diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index d68c6ff1fe33ae..dab6cbd0f8fe6b 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1,3 @@ # These are supported funding model platforms -github: [mrdoob, HumanInteractive, donmccurdy] +github: [mrdoob, HumanInteractive, donmccurdy, gkjohnson, WestLangley] diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index f7b4a905d4f25a..f184ffc7ff27de 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -28,8 +28,8 @@ Steps to reproduce the behavior: ***Live example*** -* [jsfiddle-latest-release](https://jsfiddle.net/hbfpj2wv/2/) -* [jsfiddle-dev](https://jsfiddle.net/086yzvgc/) +* [jsfiddle-latest-release](https://jsfiddle.net/g3atw6k5/) +* [jsfiddle-dev](https://jsfiddle.net/eL7gqyhd/) **Expected behavior** diff --git a/README.md b/README.md index 16a97341079e67..a032a35c7a140f 100644 --- a/README.md +++ b/README.md @@ -8,15 +8,16 @@ #### JavaScript 3D library -The aim of the project is to create an easy to use, lightweight, cross-browser, general purpose 3D library. The current builds only include a WebGL renderer but WebGPU (experimental), SVG and CSS3D renderers are also available in the examples. +The aim of the project is to create an easy to use, lightweight, cross-browser, general purpose 3D library. The current builds only include a WebGL renderer but WebGPU (experimental), SVG and CSS3D renderers are also available as addons. [Examples](https://threejs.org/examples/) — -[Documentation](https://threejs.org/docs/) — +[Docs](https://threejs.org/docs/) — +[Manual](https://threejs.org/manual/) — [Wiki](https://github.com/mrdoob/three.js/wiki) — [Migrating](https://github.com/mrdoob/three.js/wiki/Migration-Guide) — [Questions](https://stackoverflow.com/questions/tagged/three.js) — [Forum](https://discourse.threejs.org/) — -[Slack](https://join.slack.com/t/threejs/shared_invite/zt-rnuegz5e-FQpc6YboDVW~5idlp7GfDw) +[Discord](https://discord.gg/56GBJwAnUS) ### Usage diff --git a/build/three.cjs b/build/three.cjs index 6a800f99ecb69d..47dbf50f6aff18 100644 --- a/build/three.cjs +++ b/build/three.cjs @@ -7,7 +7,7 @@ Object.defineProperty(exports, '__esModule', { value: true }); -const REVISION = '143'; +const REVISION = '147'; const MOUSE = { LEFT: 0, MIDDLE: 1, @@ -33,8 +33,6 @@ const VSMShadowMap = 3; const FrontSide = 0; const BackSide = 1; const DoubleSide = 2; -const FlatShading = 1; -const SmoothShading = 2; const NoBlending = 0; const NormalBlending = 1; const AdditiveBlending = 2; @@ -105,7 +103,7 @@ const UnsignedShort4444Type = 1017; const UnsignedShort5551Type = 1018; const UnsignedInt248Type = 1020; const AlphaFormat = 1021; -const RGBFormat = 1022; +const RGBFormat = 1022; // @deprecated since r137 const RGBAFormat = 1023; const LuminanceFormat = 1024; const LuminanceAlphaFormat = 1025; @@ -161,8 +159,9 @@ const sRGBEncoding = 3001; const BasicDepthPacking = 3200; const RGBADepthPacking = 3201; const TangentSpaceNormalMap = 0; -const ObjectSpaceNormalMap = 1; // Color space string identifiers, matching CSS Color Module Level 4 and WebGPU names where available. +const ObjectSpaceNormalMap = 1; +// Color space string identifiers, matching CSS Color Module Level 4 and WebGPU names where available. const NoColorSpace = ''; const SRGBColorSpace = 'srgb'; const LinearSRGBColorSpace = 'srgb-linear'; @@ -198,179 +197,168 @@ const _SRGBAFormat = 1035; // fallback for WebGL 1 /** * https://github.com/mrdoob/eventdispatcher.js/ */ + class EventDispatcher { addEventListener(type, listener) { if (this._listeners === undefined) this._listeners = {}; const listeners = this._listeners; - if (listeners[type] === undefined) { listeners[type] = []; } - if (listeners[type].indexOf(listener) === -1) { listeners[type].push(listener); } } - hasEventListener(type, listener) { if (this._listeners === undefined) return false; const listeners = this._listeners; return listeners[type] !== undefined && listeners[type].indexOf(listener) !== -1; } - removeEventListener(type, listener) { if (this._listeners === undefined) return; const listeners = this._listeners; const listenerArray = listeners[type]; - if (listenerArray !== undefined) { const index = listenerArray.indexOf(listener); - if (index !== -1) { listenerArray.splice(index, 1); } } } - dispatchEvent(event) { if (this._listeners === undefined) return; const listeners = this._listeners; const listenerArray = listeners[event.type]; - if (listenerArray !== undefined) { - event.target = this; // Make a copy, in case listeners are removed while iterating. + event.target = this; + // Make a copy, in case listeners are removed while iterating. const array = listenerArray.slice(0); - for (let i = 0, l = array.length; i < l; i++) { array[i].call(this, event); } - event.target = null; } } - } const _lut = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '0a', '0b', '0c', '0d', '0e', '0f', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '1a', '1b', '1c', '1d', '1e', '1f', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '2a', '2b', '2c', '2d', '2e', '2f', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '3a', '3b', '3c', '3d', '3e', '3f', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '4a', '4b', '4c', '4d', '4e', '4f', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '5a', '5b', '5c', '5d', '5e', '5f', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '6a', '6b', '6c', '6d', '6e', '6f', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '7a', '7b', '7c', '7d', '7e', '7f', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '8a', '8b', '8c', '8d', '8e', '8f', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '9a', '9b', '9c', '9d', '9e', '9f', 'a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9', 'aa', 'ab', 'ac', 'ad', 'ae', 'af', 'b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'ba', 'bb', 'bc', 'bd', 'be', 'bf', 'c0', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9', 'ca', 'cb', 'cc', 'cd', 'ce', 'cf', 'd0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9', 'da', 'db', 'dc', 'dd', 'de', 'df', 'e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9', 'ea', 'eb', 'ec', 'ed', 'ee', 'ef', 'f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'fa', 'fb', 'fc', 'fd', 'fe', 'ff']; let _seed = 1234567; const DEG2RAD = Math.PI / 180; -const RAD2DEG = 180 / Math.PI; // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136 +const RAD2DEG = 180 / Math.PI; +// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136 function generateUUID() { const d0 = Math.random() * 0xffffffff | 0; const d1 = Math.random() * 0xffffffff | 0; const d2 = Math.random() * 0xffffffff | 0; const d3 = Math.random() * 0xffffffff | 0; - const uuid = _lut[d0 & 0xff] + _lut[d0 >> 8 & 0xff] + _lut[d0 >> 16 & 0xff] + _lut[d0 >> 24 & 0xff] + '-' + _lut[d1 & 0xff] + _lut[d1 >> 8 & 0xff] + '-' + _lut[d1 >> 16 & 0x0f | 0x40] + _lut[d1 >> 24 & 0xff] + '-' + _lut[d2 & 0x3f | 0x80] + _lut[d2 >> 8 & 0xff] + '-' + _lut[d2 >> 16 & 0xff] + _lut[d2 >> 24 & 0xff] + _lut[d3 & 0xff] + _lut[d3 >> 8 & 0xff] + _lut[d3 >> 16 & 0xff] + _lut[d3 >> 24 & 0xff]; // .toLowerCase() here flattens concatenated strings to save heap memory space. + const uuid = _lut[d0 & 0xff] + _lut[d0 >> 8 & 0xff] + _lut[d0 >> 16 & 0xff] + _lut[d0 >> 24 & 0xff] + '-' + _lut[d1 & 0xff] + _lut[d1 >> 8 & 0xff] + '-' + _lut[d1 >> 16 & 0x0f | 0x40] + _lut[d1 >> 24 & 0xff] + '-' + _lut[d2 & 0x3f | 0x80] + _lut[d2 >> 8 & 0xff] + '-' + _lut[d2 >> 16 & 0xff] + _lut[d2 >> 24 & 0xff] + _lut[d3 & 0xff] + _lut[d3 >> 8 & 0xff] + _lut[d3 >> 16 & 0xff] + _lut[d3 >> 24 & 0xff]; + // .toLowerCase() here flattens concatenated strings to save heap memory space. return uuid.toLowerCase(); } - function clamp(value, min, max) { return Math.max(min, Math.min(max, value)); -} // compute euclidean modulo of m % n -// https://en.wikipedia.org/wiki/Modulo_operation - +} +// compute euclidean modulo of m % n +// https://en.wikipedia.org/wiki/Modulo_operation function euclideanModulo(n, m) { return (n % m + m) % m; -} // Linear mapping from range to range - +} +// Linear mapping from range to range function mapLinear(x, a1, a2, b1, b2) { return b1 + (x - a1) * (b2 - b1) / (a2 - a1); -} // https://www.gamedev.net/tutorials/programming/general-and-gameplay-programming/inverse-lerp-a-super-useful-yet-often-overlooked-function-r5230/ - +} +// https://www.gamedev.net/tutorials/programming/general-and-gameplay-programming/inverse-lerp-a-super-useful-yet-often-overlooked-function-r5230/ function inverseLerp(x, y, value) { if (x !== y) { return (value - x) / (y - x); } else { return 0; } -} // https://en.wikipedia.org/wiki/Linear_interpolation - +} +// https://en.wikipedia.org/wiki/Linear_interpolation function lerp(x, y, t) { return (1 - t) * x + t * y; -} // http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/ - +} +// http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/ function damp(x, y, lambda, dt) { return lerp(x, y, 1 - Math.exp(-lambda * dt)); -} // https://www.desmos.com/calculator/vcsjnyz7x4 - +} +// https://www.desmos.com/calculator/vcsjnyz7x4 function pingpong(x, length = 1) { return length - Math.abs(euclideanModulo(x, length * 2) - length); -} // http://en.wikipedia.org/wiki/Smoothstep - +} +// http://en.wikipedia.org/wiki/Smoothstep function smoothstep(x, min, max) { if (x <= min) return 0; if (x >= max) return 1; x = (x - min) / (max - min); return x * x * (3 - 2 * x); } - function smootherstep(x, min, max) { if (x <= min) return 0; if (x >= max) return 1; x = (x - min) / (max - min); return x * x * x * (x * (x * 6 - 15) + 10); -} // Random integer from interval - +} +// Random integer from interval function randInt(low, high) { return low + Math.floor(Math.random() * (high - low + 1)); -} // Random float from interval - +} +// Random float from interval function randFloat(low, high) { return low + Math.random() * (high - low); -} // Random float from <-range/2, range/2> interval - +} +// Random float from <-range/2, range/2> interval function randFloatSpread(range) { return range * (0.5 - Math.random()); -} // Deterministic pseudo-random float in the interval [ 0, 1 ] - +} +// Deterministic pseudo-random float in the interval [ 0, 1 ] function seededRandom(s) { - if (s !== undefined) _seed = s; // Mulberry32 generator + if (s !== undefined) _seed = s; + + // Mulberry32 generator let t = _seed += 0x6D2B79F5; t = Math.imul(t ^ t >>> 15, t | 1); t ^= t + Math.imul(t ^ t >>> 7, t | 61); return ((t ^ t >>> 14) >>> 0) / 4294967296; } - function degToRad(degrees) { return degrees * DEG2RAD; } - function radToDeg(radians) { return radians * RAD2DEG; } - function isPowerOfTwo(value) { return (value & value - 1) === 0 && value !== 0; } - function ceilPowerOfTwo(value) { return Math.pow(2, Math.ceil(Math.log(value) / Math.LN2)); } - function floorPowerOfTwo(value) { return Math.pow(2, Math.floor(Math.log(value) / Math.LN2)); } - function setQuaternionFromProperEuler(q, a, b, c, order) { // Intrinsic Proper Euler Angles - see https://en.wikipedia.org/wiki/Euler_angles + // rotations are applied to the axes in the order specified by 'order' // rotation by angle 'a' is applied first, then by angle 'b', then by angle 'c' // angles are in radians + const cos = Math.cos; const sin = Math.sin; const c2 = cos(b / 2); @@ -381,76 +369,57 @@ function setQuaternionFromProperEuler(q, a, b, c, order) { const s1_3 = sin((a - c) / 2); const c3_1 = cos((c - a) / 2); const s3_1 = sin((c - a) / 2); - switch (order) { case 'XYX': q.set(c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13); break; - case 'YZY': q.set(s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13); break; - case 'ZXZ': q.set(s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13); break; - case 'XZX': q.set(c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13); break; - case 'YXY': q.set(s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13); break; - case 'ZYZ': q.set(s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13); break; - default: console.warn('THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order); } } - -function denormalize$1(value, array) { +function denormalize(value, array) { switch (array.constructor) { case Float32Array: return value; - case Uint16Array: return value / 65535.0; - case Uint8Array: return value / 255.0; - case Int16Array: return Math.max(value / 32767.0, -1.0); - case Int8Array: return Math.max(value / 127.0, -1.0); - default: throw new Error('Invalid component type.'); } } - function normalize(value, array) { switch (array.constructor) { case Float32Array: return value; - case Uint16Array: return Math.round(value * 65535.0); - case Uint8Array: return Math.round(value * 255.0); - case Int16Array: return Math.round(value * 32767.0); - case Int8Array: return Math.round(value * 127.0); - default: throw new Error('Invalid component type.'); } @@ -481,7 +450,7 @@ var MathUtils = /*#__PURE__*/Object.freeze({ floorPowerOfTwo: floorPowerOfTwo, setQuaternionFromProperEuler: setQuaternionFromProperEuler, normalize: normalize, - denormalize: denormalize$1 + denormalize: denormalize }); class Vector2 { @@ -490,321 +459,263 @@ class Vector2 { this.x = x; this.y = y; } - get width() { return this.x; } - set width(value) { this.x = value; } - get height() { return this.y; } - set height(value) { this.y = value; } - set(x, y) { this.x = x; this.y = y; return this; } - setScalar(scalar) { this.x = scalar; this.y = scalar; return this; } - setX(x) { this.x = x; return this; } - setY(y) { this.y = y; return this; } - setComponent(index, value) { switch (index) { case 0: this.x = value; break; - case 1: this.y = value; break; - default: throw new Error('index is out of range: ' + index); } - return this; } - getComponent(index) { switch (index) { case 0: return this.x; - case 1: return this.y; - default: throw new Error('index is out of range: ' + index); } } - clone() { return new this.constructor(this.x, this.y); } - copy(v) { this.x = v.x; this.y = v.y; return this; } - add(v) { this.x += v.x; this.y += v.y; return this; } - addScalar(s) { this.x += s; this.y += s; return this; } - addVectors(a, b) { this.x = a.x + b.x; this.y = a.y + b.y; return this; } - addScaledVector(v, s) { this.x += v.x * s; this.y += v.y * s; return this; } - sub(v) { this.x -= v.x; this.y -= v.y; return this; } - subScalar(s) { this.x -= s; this.y -= s; return this; } - subVectors(a, b) { this.x = a.x - b.x; this.y = a.y - b.y; return this; } - multiply(v) { this.x *= v.x; this.y *= v.y; return this; } - multiplyScalar(scalar) { this.x *= scalar; this.y *= scalar; return this; } - divide(v) { this.x /= v.x; this.y /= v.y; return this; } - divideScalar(scalar) { return this.multiplyScalar(1 / scalar); } - applyMatrix3(m) { const x = this.x, - y = this.y; + y = this.y; const 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; } - min(v) { this.x = Math.min(this.x, v.x); this.y = Math.min(this.y, v.y); return this; } - max(v) { this.x = Math.max(this.x, v.x); this.y = Math.max(this.y, v.y); return this; } - clamp(min, max) { // assumes min < max, componentwise + this.x = Math.max(min.x, Math.min(max.x, this.x)); this.y = Math.max(min.y, Math.min(max.y, this.y)); return this; } - clampScalar(minVal, maxVal) { this.x = Math.max(minVal, Math.min(maxVal, this.x)); this.y = Math.max(minVal, Math.min(maxVal, this.y)); return this; } - clampLength(min, max) { const length = this.length(); return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length))); } - floor() { this.x = Math.floor(this.x); this.y = Math.floor(this.y); return this; } - ceil() { this.x = Math.ceil(this.x); this.y = Math.ceil(this.y); return this; } - round() { this.x = Math.round(this.x); this.y = Math.round(this.y); return this; } - roundToZero() { this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x); this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y); return this; } - negate() { this.x = -this.x; this.y = -this.y; return this; } - dot(v) { return this.x * v.x + this.y * v.y; } - cross(v) { return this.x * v.y - this.y * v.x; } - lengthSq() { return this.x * this.x + this.y * this.y; } - length() { return Math.sqrt(this.x * this.x + this.y * this.y); } - manhattanLength() { return Math.abs(this.x) + Math.abs(this.y); } - normalize() { return this.divideScalar(this.length() || 1); } - angle() { // computes the angle in radians with respect to the positive x-axis + const angle = Math.atan2(-this.y, -this.x) + Math.PI; return angle; } - distanceTo(v) { return Math.sqrt(this.distanceToSquared(v)); } - distanceToSquared(v) { const dx = this.x - v.x, - dy = this.y - v.y; + dy = this.y - v.y; return dx * dx + dy * dy; } - manhattanDistanceTo(v) { return Math.abs(this.x - v.x) + Math.abs(this.y - v.y); } - setLength(length) { return this.normalize().multiplyScalar(length); } - lerp(v, alpha) { this.x += (v.x - this.x) * alpha; this.y += (v.y - this.y) * alpha; return this; } - lerpVectors(v1, v2, alpha) { this.x = v1.x + (v2.x - v1.x) * alpha; this.y = v1.y + (v2.y - v1.y) * alpha; return this; } - equals(v) { return v.x === this.x && v.y === this.y; } - fromArray(array, offset = 0) { this.x = array[offset]; this.y = array[offset + 1]; return this; } - toArray(array = [], offset = 0) { array[offset] = this.x; array[offset + 1] = this.y; return array; } - fromBufferAttribute(attribute, index) { this.x = attribute.getX(index); this.y = attribute.getY(index); return this; } - rotateAround(center, angle) { const c = Math.cos(angle), - s = Math.sin(angle); + s = Math.sin(angle); const x = this.x - center.x; const y = this.y - center.y; this.x = x * c - y * s + center.x; this.y = x * s + y * c + center.y; return this; } - random() { this.x = Math.random(); this.y = Math.random(); return this; } - *[Symbol.iterator]() { yield this.x; yield this.y; } - } class Matrix3 { @@ -812,7 +723,6 @@ class Matrix3 { Matrix3.prototype.isMatrix3 = true; this.elements = [1, 0, 0, 0, 1, 0, 0, 0, 1]; } - set(n11, n12, n13, n21, n22, n23, n31, n32, n33) { const te = this.elements; te[0] = n11; @@ -826,12 +736,10 @@ class Matrix3 { te[8] = n33; return this; } - identity() { this.set(1, 0, 0, 0, 1, 0, 0, 0, 1); return this; } - copy(m) { const te = this.elements; const me = m.elements; @@ -846,50 +754,45 @@ class Matrix3 { te[8] = me[8]; return this; } - extractBasis(xAxis, yAxis, zAxis) { xAxis.setFromMatrix3Column(this, 0); yAxis.setFromMatrix3Column(this, 1); zAxis.setFromMatrix3Column(this, 2); return this; } - setFromMatrix4(m) { const me = m.elements; this.set(me[0], me[4], me[8], me[1], me[5], me[9], me[2], me[6], me[10]); return this; } - multiply(m) { return this.multiplyMatrices(this, m); } - premultiply(m) { return this.multiplyMatrices(m, this); } - multiplyMatrices(a, b) { const ae = a.elements; const be = b.elements; const te = this.elements; const a11 = ae[0], - a12 = ae[3], - a13 = ae[6]; + a12 = ae[3], + a13 = ae[6]; const a21 = ae[1], - a22 = ae[4], - a23 = ae[7]; + a22 = ae[4], + a23 = ae[7]; const a31 = ae[2], - a32 = ae[5], - a33 = ae[8]; + a32 = ae[5], + a33 = ae[8]; const b11 = be[0], - b12 = be[3], - b13 = be[6]; + b12 = be[3], + b13 = be[6]; const b21 = be[1], - b22 = be[4], - b23 = be[7]; + b22 = be[4], + b23 = be[7]; const b31 = be[2], - b32 = be[5], - b33 = be[8]; + 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; @@ -901,7 +804,6 @@ class Matrix3 { te[8] = a31 * b13 + a32 * b23 + a33 * b33; return this; } - multiplyScalar(s) { const te = this.elements; te[0] *= s; @@ -915,36 +817,34 @@ class Matrix3 { te[8] *= s; return this; } - determinant() { const te = this.elements; const a = te[0], - b = te[1], - c = te[2], - d = te[3], - e = te[4], - f = te[5], - g = te[6], - h = te[7], - i = te[8]; + b = te[1], + c = te[2], + d = te[3], + e = te[4], + f = te[5], + g = te[6], + h = te[7], + i = te[8]; return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g; } - invert() { const te = this.elements, - n11 = te[0], - n21 = te[1], - n31 = te[2], - n12 = te[3], - n22 = te[4], - n32 = te[5], - n13 = te[6], - n23 = te[7], - n33 = te[8], - t11 = n33 * n22 - n32 * n23, - t12 = n32 * n13 - n33 * n12, - t13 = n23 * n12 - n22 * n13, - det = n11 * t11 + n21 * t12 + n31 * t13; + n11 = te[0], + n21 = te[1], + n31 = te[2], + n12 = te[3], + n22 = te[4], + n32 = te[5], + n13 = te[6], + n23 = te[7], + n33 = te[8], + t11 = n33 * n22 - n32 * n23, + t12 = n32 * n13 - n33 * n12, + t13 = n23 * n12 - n22 * n13, + det = n11 * t11 + n21 * t12 + n31 * t13; if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0); const detInv = 1 / det; te[0] = t11 * detInv; @@ -958,7 +858,6 @@ class Matrix3 { te[8] = (n22 * n11 - n21 * n12) * detInv; return this; } - transpose() { let tmp; const m = this.elements; @@ -973,11 +872,9 @@ class Matrix3 { m[7] = tmp; return this; } - getNormalMatrix(matrix4) { return this.setFromMatrix4(matrix4).invert().transpose(); } - transposeIntoArray(r) { const m = this.elements; r[0] = m[0]; @@ -991,7 +888,6 @@ class Matrix3 { r[8] = m[8]; return this; } - setUvTransform(tx, ty, sx, sy, rotation, cx, cy) { const c = Math.cos(rotation); const s = Math.sin(rotation); @@ -999,66 +895,56 @@ class Matrix3 { return this; } + // + scale(sx, sy) { - const te = this.elements; - te[0] *= sx; - te[3] *= sx; - te[6] *= sx; - te[1] *= sy; - te[4] *= sy; - te[7] *= sy; + this.premultiply(_m3.makeScale(sx, sy)); return this; } - rotate(theta) { + this.premultiply(_m3.makeRotation(-theta)); + return this; + } + translate(tx, ty) { + this.premultiply(_m3.makeTranslation(tx, ty)); + return this; + } + + // for 2D Transforms + + makeTranslation(x, y) { + this.set(1, 0, x, 0, 1, y, 0, 0, 1); + return this; + } + makeRotation(theta) { + // counterclockwise + const c = Math.cos(theta); const s = Math.sin(theta); - const te = this.elements; - const a11 = te[0], - a12 = te[3], - a13 = te[6]; - const a21 = te[1], - a22 = te[4], - a23 = te[7]; - te[0] = c * a11 + s * a21; - te[3] = c * a12 + s * a22; - te[6] = c * a13 + s * a23; - te[1] = -s * a11 + c * a21; - te[4] = -s * a12 + c * a22; - te[7] = -s * a13 + c * a23; + this.set(c, -s, 0, s, c, 0, 0, 0, 1); return this; } - - translate(tx, ty) { - const te = this.elements; - te[0] += tx * te[2]; - te[3] += tx * te[5]; - te[6] += tx * te[8]; - te[1] += ty * te[2]; - te[4] += ty * te[5]; - te[7] += ty * te[8]; + makeScale(x, y) { + this.set(x, 0, 0, 0, y, 0, 0, 0, 1); return this; } + // + equals(matrix) { const te = this.elements; const me = matrix.elements; - for (let i = 0; i < 9; i++) { if (te[i] !== me[i]) return false; } - return true; } - fromArray(array, offset = 0) { for (let i = 0; i < 9; i++) { this.elements[i] = array[i + offset]; } - return this; } - toArray(array = [], offset = 0) { const te = this.elements; array[offset] = te[0]; @@ -1072,22 +958,21 @@ class Matrix3 { array[offset + 8] = te[8]; return array; } - clone() { return new this.constructor().fromArray(this.elements); } - } +const _m3 = /*@__PURE__*/new Matrix3(); function arrayNeedsUint32(array) { // assumes larger values usually on last + for (let i = array.length - 1; i >= 0; --i) { - if (array[i] > 65535) return true; + if (array[i] >= 65535) return true; // account for PRIMITIVE_RESTART_FIXED_INDEX, #24565 } return false; } - const TYPED_ARRAYS = { Int8Array: Int8Array, Uint8Array: Uint8Array, @@ -1099,11 +984,9 @@ const TYPED_ARRAYS = { Float32Array: Float32Array, Float64Array: Float64Array }; - function getTypedArray(type, buffer) { return new TYPED_ARRAYS[type](buffer); } - function createElementNS(name) { return document.createElementNS('http://www.w3.org/1999/xhtml', name); } @@ -1113,9 +996,10 @@ function SRGBToLinear(c) { } function LinearToSRGB(c) { return c < 0.0031308 ? c * 12.92 : 1.055 * Math.pow(c, 0.41666) - 0.055; -} // JavaScript RGB-to-RGB transforms, defined as -// FN[InputColorSpace][OutputColorSpace] callback functions. +} +// JavaScript RGB-to-RGB transforms, defined as +// FN[InputColorSpace][OutputColorSpace] callback functions. const FN = { [SRGBColorSpace]: { [LinearSRGBColorSpace]: SRGBToLinear @@ -1126,20 +1010,16 @@ const FN = { }; const ColorManagement = { legacyMode: true, - get workingColorSpace() { return LinearSRGBColorSpace; }, - set workingColorSpace(colorSpace) { console.warn('THREE.ColorManagement: .workingColorSpace is readonly.'); }, - convert: function (color, sourceColorSpace, targetColorSpace) { if (this.legacyMode || sourceColorSpace === targetColorSpace || !sourceColorSpace || !targetColorSpace) { return color; } - if (FN[sourceColorSpace] && FN[sourceColorSpace][targetColorSpace] !== undefined) { const fn = FN[sourceColorSpace][targetColorSpace]; color.r = fn(color.r); @@ -1147,7 +1027,6 @@ const ColorManagement = { color.b = fn(color.b); return color; } - throw new Error('Unsupported color space conversion.'); }, fromWorkingColorSpace: function (color, targetColorSpace) { @@ -1308,7 +1187,7 @@ const _colorKeywords = { 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 }; -const _rgb = { +const _rgb$1 = { r: 0, g: 0, b: 0 @@ -1323,7 +1202,6 @@ const _hslB = { s: 0, l: 0 }; - function hue2rgb(p, q, t) { if (t < 0) t += 1; if (t > 1) t -= 1; @@ -1332,29 +1210,24 @@ function hue2rgb(p, q, t) { if (t < 2 / 3) return p + (q - p) * 6 * (2 / 3 - t); return p; } - function toComponents(source, target) { target.r = source.r; target.g = source.g; target.b = source.b; return target; } - class Color { constructor(r, g, b) { this.isColor = true; this.r = 1; this.g = 1; this.b = 1; - if (g === undefined && b === undefined) { // r is THREE.Color, hex or string return this.set(r); } - return this.setRGB(r, g, b); } - set(value) { if (value && value.isColor) { this.copy(value); @@ -1363,17 +1236,14 @@ class Color { } else if (typeof value === 'string') { this.setStyle(value); } - return this; } - setScalar(scalar) { this.r = scalar; this.g = scalar; this.b = scalar; return this; } - setHex(hex, colorSpace = SRGBColorSpace) { hex = Math.floor(hex); this.r = (hex >> 16 & 255) / 255; @@ -1382,21 +1252,18 @@ class Color { ColorManagement.toWorkingColorSpace(this, colorSpace); return this; } - - setRGB(r, g, b, colorSpace = LinearSRGBColorSpace) { + setRGB(r, g, b, colorSpace = ColorManagement.workingColorSpace) { this.r = r; this.g = g; this.b = b; ColorManagement.toWorkingColorSpace(this, colorSpace); return this; } - - setHSL(h, s, l, colorSpace = LinearSRGBColorSpace) { + setHSL(h, s, l, colorSpace = ColorManagement.workingColorSpace) { // h,s,l ranges are in 0.0 - 1.0 h = euclideanModulo(h, 1); s = clamp(s, 0, 1); l = clamp(l, 0, 1); - if (s === 0) { this.r = this.g = this.b = l; } else { @@ -1406,28 +1273,23 @@ class Color { this.g = hue2rgb(q, p, h); this.b = hue2rgb(q, p, h - 1 / 3); } - ColorManagement.toWorkingColorSpace(this, colorSpace); return this; } - setStyle(style, colorSpace = SRGBColorSpace) { function handleAlpha(string) { if (string === undefined) return; - if (parseFloat(string) < 1) { console.warn('THREE.Color: Alpha component of ' + style + ' will be ignored.'); } } - let m; - if (m = /^((?:rgb|hsl)a?)\(([^\)]*)\)/.exec(style)) { // rgb / hsl + let color; const name = m[1]; const components = m[2]; - switch (name) { case 'rgb': case 'rgba': @@ -1440,7 +1302,6 @@ class Color { handleAlpha(color[4]); return this; } - if (color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5) this.r = Math.min(100, parseInt(color[1], 10)) / 100; @@ -1450,27 +1311,24 @@ class Color { handleAlpha(color[4]); return this; } - break; - case 'hsl': case 'hsla': - if (color = /^\s*(\d*\.?\d+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { + if (color = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { // hsl(120,50%,50%) hsla(120,50%,50%,0.5) const h = parseFloat(color[1]) / 360; - const s = parseInt(color[2], 10) / 100; - const l = parseInt(color[3], 10) / 100; + const s = parseFloat(color[2]) / 100; + const l = parseFloat(color[3]) / 100; handleAlpha(color[4]); return this.setHSL(h, s, l, colorSpace); } - break; } } else if (m = /^\#([A-Fa-f\d]+)$/.exec(style)) { // hex color + const hex = m[1]; const size = hex.length; - if (size === 3) { // #ff0 this.r = parseInt(hex.charAt(0) + hex.charAt(0), 16) / 255; @@ -1487,18 +1345,14 @@ class Color { return this; } } - if (style && style.length > 0) { return this.setColorName(style, colorSpace); } - return this; } - setColorName(style, colorSpace = SRGBColorSpace) { // color keywords const hex = _colorKeywords[style.toLowerCase()]; - if (hex !== undefined) { // red this.setHex(hex, colorSpace); @@ -1506,114 +1360,94 @@ class Color { // unknown color console.warn('THREE.Color: Unknown color ' + style); } - return this; } - clone() { return new this.constructor(this.r, this.g, this.b); } - copy(color) { this.r = color.r; this.g = color.g; this.b = color.b; return this; } - copySRGBToLinear(color) { this.r = SRGBToLinear(color.r); this.g = SRGBToLinear(color.g); this.b = SRGBToLinear(color.b); return this; } - copyLinearToSRGB(color) { this.r = LinearToSRGB(color.r); this.g = LinearToSRGB(color.g); this.b = LinearToSRGB(color.b); return this; } - convertSRGBToLinear() { this.copySRGBToLinear(this); return this; } - convertLinearToSRGB() { this.copyLinearToSRGB(this); return this; } - getHex(colorSpace = SRGBColorSpace) { - ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb), colorSpace); - return clamp(_rgb.r * 255, 0, 255) << 16 ^ clamp(_rgb.g * 255, 0, 255) << 8 ^ clamp(_rgb.b * 255, 0, 255) << 0; + ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb$1), colorSpace); + return clamp(_rgb$1.r * 255, 0, 255) << 16 ^ clamp(_rgb$1.g * 255, 0, 255) << 8 ^ clamp(_rgb$1.b * 255, 0, 255) << 0; } - getHexString(colorSpace = SRGBColorSpace) { return ('000000' + this.getHex(colorSpace).toString(16)).slice(-6); } - - getHSL(target, colorSpace = LinearSRGBColorSpace) { + getHSL(target, colorSpace = ColorManagement.workingColorSpace) { // h,s,l ranges are in 0.0 - 1.0 - ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb), colorSpace); - const r = _rgb.r, - g = _rgb.g, - b = _rgb.b; + + ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb$1), colorSpace); + const r = _rgb$1.r, + g = _rgb$1.g, + b = _rgb$1.b; const max = Math.max(r, g, b); const min = Math.min(r, g, b); let hue, saturation; const lightness = (min + max) / 2.0; - if (min === max) { hue = 0; saturation = 0; } else { const delta = max - min; saturation = lightness <= 0.5 ? delta / (max + min) : delta / (2 - max - min); - switch (max) { 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; } - hue /= 6; } - target.h = hue; target.s = saturation; target.l = lightness; return target; } - - getRGB(target, colorSpace = LinearSRGBColorSpace) { - ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb), colorSpace); - target.r = _rgb.r; - target.g = _rgb.g; - target.b = _rgb.b; + getRGB(target, colorSpace = ColorManagement.workingColorSpace) { + ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb$1), colorSpace); + target.r = _rgb$1.r; + target.g = _rgb$1.g; + target.b = _rgb$1.b; return target; } - getStyle(colorSpace = SRGBColorSpace) { - ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb), colorSpace); - + ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb$1), colorSpace); if (colorSpace !== SRGBColorSpace) { // Requires CSS Color Module Level 4 (https://www.w3.org/TR/css-color-4/). - return `color(${colorSpace} ${_rgb.r} ${_rgb.g} ${_rgb.b})`; + return `color(${colorSpace} ${_rgb$1.r} ${_rgb$1.g} ${_rgb$1.b})`; } - - return `rgb(${_rgb.r * 255 | 0},${_rgb.g * 255 | 0},${_rgb.b * 255 | 0})`; + return `rgb(${_rgb$1.r * 255 | 0},${_rgb$1.g * 255 | 0},${_rgb$1.b * 255 | 0})`; } - offsetHSL(h, s, l) { this.getHSL(_hslA); _hslA.h += h; @@ -1622,63 +1456,54 @@ class Color { this.setHSL(_hslA.h, _hslA.s, _hslA.l); return this; } - add(color) { this.r += color.r; this.g += color.g; this.b += color.b; return this; } - addColors(color1, color2) { this.r = color1.r + color2.r; this.g = color1.g + color2.g; this.b = color1.b + color2.b; return this; } - addScalar(s) { this.r += s; this.g += s; this.b += s; return this; } - 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; } - multiply(color) { this.r *= color.r; this.g *= color.g; this.b *= color.b; return this; } - multiplyScalar(s) { this.r *= s; this.g *= s; this.b *= s; return this; } - 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; } - lerpColors(color1, color2, alpha) { this.r = color1.r + (color2.r - color1.r) * alpha; this.g = color1.g + (color2.g - color1.g) * alpha; this.b = color1.b + (color2.b - color1.b) * alpha; return this; } - lerpHSL(color, alpha) { this.getHSL(_hslA); color.getHSL(_hslB); @@ -1688,86 +1513,62 @@ class Color { this.setHSL(h, s, l); return this; } - equals(c) { return c.r === this.r && c.g === this.g && c.b === this.b; } - fromArray(array, offset = 0) { this.r = array[offset]; this.g = array[offset + 1]; this.b = array[offset + 2]; return this; } - toArray(array = [], offset = 0) { array[offset] = this.r; array[offset + 1] = this.g; array[offset + 2] = this.b; return array; } - fromBufferAttribute(attribute, index) { this.r = attribute.getX(index); this.g = attribute.getY(index); this.b = attribute.getZ(index); - - if (attribute.normalized === true) { - // assuming Uint8Array - this.r /= 255; - this.g /= 255; - this.b /= 255; - } - return this; } - toJSON() { return this.getHex(); } - *[Symbol.iterator]() { yield this.r; yield this.g; yield this.b; } - } - Color.NAMES = _colorKeywords; let _canvas; - class ImageUtils { static getDataURL(image) { if (/^data:/i.test(image.src)) { return image.src; } - if (typeof HTMLCanvasElement == 'undefined') { return image.src; } - let canvas; - if (image instanceof HTMLCanvasElement) { canvas = image; } else { if (_canvas === undefined) _canvas = createElementNS('canvas'); _canvas.width = image.width; _canvas.height = image.height; - const context = _canvas.getContext('2d'); - if (image instanceof ImageData) { context.putImageData(image, 0, 0); } else { context.drawImage(image, 0, 0, image.width, image.height); } - canvas = _canvas; } - if (canvas.width > 2048 || canvas.height > 2048) { console.warn('THREE.ImageUtils.getDataURL: Image converted to jpg for performance reasons', image); return canvas.toDataURL('image/jpeg', 0.6); @@ -1775,7 +1576,6 @@ class ImageUtils { return canvas.toDataURL('image/png'); } } - static sRGBToLinear(image) { if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) { const canvas = createElementNS('canvas'); @@ -1785,25 +1585,22 @@ class ImageUtils { context.drawImage(image, 0, 0, image.width, image.height); const imageData = context.getImageData(0, 0, image.width, image.height); const data = imageData.data; - for (let i = 0; i < data.length; i++) { data[i] = SRGBToLinear(data[i] / 255) * 255; } - context.putImageData(imageData, 0, 0); return canvas; } else if (image.data) { const data = image.data.slice(0); - for (let i = 0; i < data.length; i++) { if (data instanceof Uint8Array || data instanceof Uint8ClampedArray) { data[i] = Math.floor(SRGBToLinear(data[i] / 255) * 255); } else { // assuming float + data[i] = SRGBToLinear(data[i]); } } - return { data: data, width: image.width, @@ -1814,7 +1611,6 @@ class ImageUtils { return image; } } - } class Source { @@ -1824,31 +1620,25 @@ class Source { this.data = data; this.version = 0; } - set needsUpdate(value) { if (value === true) this.version++; } - toJSON(meta) { const isRootObject = meta === undefined || typeof meta === 'string'; - if (!isRootObject && meta.images[this.uuid] !== undefined) { return meta.images[this.uuid]; } - const output = { uuid: this.uuid, url: '' }; const data = this.data; - if (data !== null) { let url; - if (Array.isArray(data)) { // cube texture - url = []; + url = []; for (let i = 0, l = data.length; i < l; i++) { if (data[i].isDataTexture) { url.push(serializeImage(data[i].image)); @@ -1858,28 +1648,26 @@ class Source { } } else { // texture + url = serializeImage(data); } - output.url = url; } - if (!isRootObject) { meta.images[this.uuid] = output; } - return output; } - } - function serializeImage(image) { if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) { // default images + return ImageUtils.getDataURL(image); } else { if (image.data) { // images of DataTexture + return { data: Array.from(image.data), width: image.width, @@ -1894,9 +1682,8 @@ function serializeImage(image) { } let textureId = 0; - class Texture extends EventDispatcher { - constructor(image = Texture.DEFAULT_IMAGE, mapping = Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format = RGBAFormat, type = UnsignedByteType, anisotropy = 1, encoding = LinearEncoding) { + constructor(image = Texture.DEFAULT_IMAGE, mapping = Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format = RGBAFormat, type = UnsignedByteType, anisotropy = Texture.DEFAULT_ANISOTROPY, encoding = LinearEncoding) { super(); this.isTexture = true; Object.defineProperty(this, 'id', { @@ -1925,36 +1712,31 @@ class Texture extends EventDispatcher { 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; this.userData = {}; this.version = 0; this.onUpdate = null; this.isRenderTargetTexture = false; // indicates whether a texture belongs to a render target or not - this.needsPMREMUpdate = false; // indicates whether this texture should be processed by PMREMGenerator or not (only relevant for render target textures) } get image() { return this.source.data; } - set image(value) { this.source.data = value; } - 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() { return new this.constructor().copy(this); } - copy(source) { this.name = source.name; this.source = source.source; @@ -1983,14 +1765,11 @@ class Texture extends EventDispatcher { this.needsUpdate = true; return this; } - toJSON(meta) { const isRootObject = meta === undefined || typeof meta === 'string'; - if (!isRootObject && meta.textures[this.uuid] !== undefined) { return meta.textures[this.uuid]; } - const output = { metadata: { version: 4.5, @@ -2017,84 +1796,68 @@ class Texture extends EventDispatcher { unpackAlignment: this.unpackAlignment }; if (JSON.stringify(this.userData) !== '{}') output.userData = this.userData; - if (!isRootObject) { meta.textures[this.uuid] = output; } - return output; } - dispose() { this.dispatchEvent({ type: 'dispose' }); } - 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; - 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); } - break; } } - if (uv.y < 0 || uv.y > 1) { switch (this.wrapT) { case RepeatWrapping: uv.y = uv.y - Math.floor(uv.y); break; - case ClampToEdgeWrapping: uv.y = uv.y < 0 ? 0 : 1; break; - 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); } - break; } } - if (this.flipY) { uv.y = 1 - uv.y; } - return uv; } - set needsUpdate(value) { if (value === true) { this.version++; this.source.needsUpdate = true; } } - } - Texture.DEFAULT_IMAGE = null; Texture.DEFAULT_MAPPING = UVMapping; +Texture.DEFAULT_ANISOTROPY = 1; class Vector4 { constructor(x = 0, y = 0, z = 0, w = 1) { @@ -2104,23 +1867,18 @@ class Vector4 { this.z = z; this.w = w; } - get width() { return this.z; } - set width(value) { this.z = value; } - get height() { return this.w; } - set height(value) { this.w = value; } - set(x, y, z, w) { this.x = x; this.y = y; @@ -2128,7 +1886,6 @@ class Vector4 { this.w = w; return this; } - setScalar(scalar) { this.x = scalar; this.y = scalar; @@ -2136,75 +1893,58 @@ class Vector4 { this.w = scalar; return this; } - setX(x) { this.x = x; return this; } - setY(y) { this.y = y; return this; } - setZ(z) { this.z = z; return this; } - setW(w) { this.w = w; return this; } - setComponent(index, value) { switch (index) { case 0: this.x = value; break; - case 1: this.y = value; break; - case 2: this.z = value; break; - case 3: this.w = value; break; - default: throw new Error('index is out of range: ' + index); } - return this; } - getComponent(index) { switch (index) { case 0: return this.x; - case 1: return this.y; - case 2: return this.z; - case 3: return this.w; - default: throw new Error('index is out of range: ' + index); } } - clone() { return new this.constructor(this.x, this.y, this.z, this.w); } - copy(v) { this.x = v.x; this.y = v.y; @@ -2212,7 +1952,6 @@ class Vector4 { this.w = v.w !== undefined ? v.w : 1; return this; } - add(v) { this.x += v.x; this.y += v.y; @@ -2220,7 +1959,6 @@ class Vector4 { this.w += v.w; return this; } - addScalar(s) { this.x += s; this.y += s; @@ -2228,7 +1966,6 @@ class Vector4 { this.w += s; return this; } - addVectors(a, b) { this.x = a.x + b.x; this.y = a.y + b.y; @@ -2236,7 +1973,6 @@ class Vector4 { this.w = a.w + b.w; return this; } - addScaledVector(v, s) { this.x += v.x * s; this.y += v.y * s; @@ -2244,7 +1980,6 @@ class Vector4 { this.w += v.w * s; return this; } - sub(v) { this.x -= v.x; this.y -= v.y; @@ -2252,7 +1987,6 @@ class Vector4 { this.w -= v.w; return this; } - subScalar(s) { this.x -= s; this.y -= s; @@ -2260,7 +1994,6 @@ class Vector4 { this.w -= s; return this; } - subVectors(a, b) { this.x = a.x - b.x; this.y = a.y - b.y; @@ -2268,7 +2001,6 @@ class Vector4 { this.w = a.w - b.w; return this; } - multiply(v) { this.x *= v.x; this.y *= v.y; @@ -2276,7 +2008,6 @@ class Vector4 { this.w *= v.w; return this; } - multiplyScalar(scalar) { this.x *= scalar; this.y *= scalar; @@ -2284,12 +2015,11 @@ class Vector4 { this.w *= scalar; return this; } - applyMatrix4(m) { const x = this.x, - y = this.y, - z = this.z, - w = this.w; + y = this.y, + z = this.z, + w = this.w; const 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; @@ -2297,17 +2027,16 @@ class Vector4 { this.w = e[3] * x + e[7] * y + e[11] * z + e[15] * w; return this; } - divideScalar(scalar) { return this.multiplyScalar(1 / scalar); } - 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); const s = Math.sqrt(1 - q.w * q.w); - if (s < 0.0001) { this.x = 1; this.y = 0; @@ -2317,40 +2046,42 @@ class Vector4 { this.y = q.y / s; this.z = q.z / s; } - return this; } - 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) - let angle, x, y, z; // variables for result + let angle, x, y, z; // variables for result const 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]; - + // 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 + } + // otherwise this singularity is angle = 180 angle = Math.PI; const xx = (m11 + 1) / 2; @@ -2359,9 +2090,9 @@ class Vector4 { const xy = (m12 + m21) / 4; const xz = (m13 + m31) / 4; const yz = (m23 + m32) / 4; - if (xx > yy && xx > zz) { // m11 is the largest diagonal term + if (xx < epsilon) { x = 0; y = 0.707106781; @@ -2373,6 +2104,7 @@ class Vector4 { } } else if (yy > zz) { // m22 is the largest diagonal term + if (yy < epsilon) { x = 0.707106781; y = 0; @@ -2384,6 +2116,7 @@ class Vector4 { } } else { // m33 is the largest diagonal term so base result on this + if (zz < epsilon) { x = 0.707106781; y = 0.707106781; @@ -2394,15 +2127,17 @@ class Vector4 { 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 + } + // as we have reached here there are no singularities so we can handle normally let s = Math.sqrt((m32 - m23) * (m32 - m23) + (m13 - m31) * (m13 - m31) + (m21 - m12) * (m21 - m12)); // used to normalize - if (Math.abs(s) < 0.001) s = 1; // prevent divide by zero, should not happen if matrix is orthogonal and should be + 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; @@ -2411,7 +2146,6 @@ class Vector4 { this.w = Math.acos((m11 + m22 + m33 - 1) / 2); return this; } - min(v) { this.x = Math.min(this.x, v.x); this.y = Math.min(this.y, v.y); @@ -2419,7 +2153,6 @@ class Vector4 { this.w = Math.min(this.w, v.w); return this; } - max(v) { this.x = Math.max(this.x, v.x); this.y = Math.max(this.y, v.y); @@ -2427,16 +2160,15 @@ class Vector4 { this.w = Math.max(this.w, v.w); return this; } - clamp(min, max) { // assumes min < max, componentwise + this.x = Math.max(min.x, Math.min(max.x, this.x)); this.y = Math.max(min.y, Math.min(max.y, this.y)); this.z = Math.max(min.z, Math.min(max.z, this.z)); this.w = Math.max(min.w, Math.min(max.w, this.w)); return this; } - clampScalar(minVal, maxVal) { this.x = Math.max(minVal, Math.min(maxVal, this.x)); this.y = Math.max(minVal, Math.min(maxVal, this.y)); @@ -2444,12 +2176,10 @@ class Vector4 { this.w = Math.max(minVal, Math.min(maxVal, this.w)); return this; } - clampLength(min, max) { const length = this.length(); return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length))); } - floor() { this.x = Math.floor(this.x); this.y = Math.floor(this.y); @@ -2457,7 +2187,6 @@ class Vector4 { this.w = Math.floor(this.w); return this; } - ceil() { this.x = Math.ceil(this.x); this.y = Math.ceil(this.y); @@ -2465,7 +2194,6 @@ class Vector4 { this.w = Math.ceil(this.w); return this; } - round() { this.x = Math.round(this.x); this.y = Math.round(this.y); @@ -2473,7 +2201,6 @@ class Vector4 { this.w = Math.round(this.w); return this; } - roundToZero() { this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x); this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y); @@ -2481,7 +2208,6 @@ class Vector4 { this.w = this.w < 0 ? Math.ceil(this.w) : Math.floor(this.w); return this; } - negate() { this.x = -this.x; this.y = -this.y; @@ -2489,31 +2215,24 @@ class Vector4 { this.w = -this.w; return this; } - dot(v) { return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; } - lengthSq() { return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; } - length() { return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w); } - manhattanLength() { return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z) + Math.abs(this.w); } - normalize() { return this.divideScalar(this.length() || 1); } - setLength(length) { return this.normalize().multiplyScalar(length); } - lerp(v, alpha) { this.x += (v.x - this.x) * alpha; this.y += (v.y - this.y) * alpha; @@ -2521,7 +2240,6 @@ class Vector4 { this.w += (v.w - this.w) * alpha; return this; } - lerpVectors(v1, v2, alpha) { this.x = v1.x + (v2.x - v1.x) * alpha; this.y = v1.y + (v2.y - v1.y) * alpha; @@ -2529,11 +2247,9 @@ class Vector4 { this.w = v1.w + (v2.w - v1.w) * alpha; return this; } - equals(v) { return v.x === this.x && v.y === this.y && v.z === this.z && v.w === this.w; } - fromArray(array, offset = 0) { this.x = array[offset]; this.y = array[offset + 1]; @@ -2541,7 +2257,6 @@ class Vector4 { this.w = array[offset + 3]; return this; } - toArray(array = [], offset = 0) { array[offset] = this.x; array[offset + 1] = this.y; @@ -2549,7 +2264,6 @@ class Vector4 { array[offset + 3] = this.w; return array; } - fromBufferAttribute(attribute, index) { this.x = attribute.getX(index); this.y = attribute.getY(index); @@ -2557,7 +2271,6 @@ class Vector4 { this.w = attribute.getW(index); return this; } - random() { this.x = Math.random(); this.y = Math.random(); @@ -2565,14 +2278,12 @@ class Vector4 { this.w = Math.random(); return this; } - *[Symbol.iterator]() { yield this.x; yield this.y; yield this.z; yield this.w; } - } /* @@ -2580,9 +2291,8 @@ class Vector4 { * Texture parameters for an auto-generated target texture * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers */ - class WebGLRenderTarget extends EventDispatcher { - constructor(width, height, options = {}) { + constructor(width = 1, height = 1, options = {}) { super(); this.isWebGLRenderTarget = true; this.width = width; @@ -2607,7 +2317,6 @@ class WebGLRenderTarget extends EventDispatcher { this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null; this.samples = options.samples !== undefined ? options.samples : 0; } - setSize(width, height, depth = 1) { if (this.width !== width || this.height !== height || this.depth !== depth) { this.width = width; @@ -2618,22 +2327,21 @@ class WebGLRenderTarget extends EventDispatcher { this.texture.image.depth = depth; this.dispose(); } - this.viewport.set(0, 0, width, height); this.scissor.set(0, 0, width, height); } - clone() { return new this.constructor().copy(this); } - copy(source) { this.width = source.width; this.height = source.height; this.depth = source.depth; this.viewport.copy(source.viewport); this.texture = source.texture.clone(); - this.texture.isRenderTargetTexture = true; // ensure image object is not shared, see #20328 + this.texture.isRenderTargetTexture = true; + + // ensure image object is not shared, see #20328 const image = Object.assign({}, source.texture.image); this.texture.source = new Source(image); @@ -2643,13 +2351,11 @@ class WebGLRenderTarget extends EventDispatcher { this.samples = source.samples; return this; } - dispose() { this.dispatchEvent({ type: 'dispose' }); } - } class DataArrayTexture extends Texture { @@ -2669,18 +2375,16 @@ class DataArrayTexture extends Texture { this.flipY = false; this.unpackAlignment = 1; } - } class WebGLArrayRenderTarget extends WebGLRenderTarget { - constructor(width, height, depth) { + constructor(width = 1, height = 1, depth = 1) { super(width, height); this.isWebGLArrayRenderTarget = true; this.depth = depth; this.texture = new DataArrayTexture(null, width, height, depth); this.texture.isRenderTargetTexture = true; } - } class Data3DTexture extends Texture { @@ -2692,6 +2396,7 @@ class Data3DTexture extends Texture { // texture.anisotropy = 16; // // See #14839 + super(null); this.isData3DTexture = true; this.image = { @@ -2707,53 +2412,45 @@ class Data3DTexture extends Texture { this.flipY = false; this.unpackAlignment = 1; } - } class WebGL3DRenderTarget extends WebGLRenderTarget { - constructor(width, height, depth) { + constructor(width = 1, height = 1, depth = 1) { super(width, height); this.isWebGL3DRenderTarget = true; this.depth = depth; this.texture = new Data3DTexture(null, width, height, depth); this.texture.isRenderTargetTexture = true; } - } class WebGLMultipleRenderTargets extends WebGLRenderTarget { - constructor(width, height, count, options = {}) { + constructor(width = 1, height = 1, count = 1, options = {}) { super(width, height, options); this.isWebGLMultipleRenderTargets = true; const texture = this.texture; this.texture = []; - for (let i = 0; i < count; i++) { this.texture[i] = texture.clone(); this.texture[i].isRenderTargetTexture = true; } } - setSize(width, height, depth = 1) { if (this.width !== width || this.height !== height || this.depth !== depth) { this.width = width; this.height = height; this.depth = depth; - for (let i = 0, il = this.texture.length; i < il; i++) { this.texture[i].image.width = width; this.texture[i].image.height = height; this.texture[i].image.depth = depth; } - this.dispose(); } - this.viewport.set(0, 0, width, height); this.scissor.set(0, 0, width, height); return this; } - copy(source) { this.dispose(); this.width = source.width; @@ -2765,15 +2462,12 @@ class WebGLMultipleRenderTargets extends WebGLRenderTarget { this.stencilBuffer = source.stencilBuffer; if (source.depthTexture !== null) this.depthTexture = source.depthTexture.clone(); this.texture.length = 0; - for (let i = 0, il = source.texture.length; i < il; i++) { this.texture[i] = source.texture[i].clone(); this.texture[i].isRenderTargetTexture = true; } - return this; } - } class Quaternion { @@ -2784,18 +2478,17 @@ class Quaternion { this._z = z; this._w = w; } - static slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t) { // fuzz-free, array-based Quaternion SLERP operation + let x0 = src0[srcOffset0 + 0], - y0 = src0[srcOffset0 + 1], - z0 = src0[srcOffset0 + 2], - w0 = src0[srcOffset0 + 3]; + y0 = src0[srcOffset0 + 1], + z0 = src0[srcOffset0 + 2], + w0 = src0[srcOffset0 + 3]; const x1 = src1[srcOffset1 + 0], - y1 = src1[srcOffset1 + 1], - z1 = src1[srcOffset1 + 2], - w1 = src1[srcOffset1 + 3]; - + y1 = src1[srcOffset1 + 1], + z1 = src1[srcOffset1 + 2], + w1 = src1[srcOffset1 + 3]; if (t === 0) { dst[dstOffset + 0] = x0; dst[dstOffset + 1] = y0; @@ -2803,7 +2496,6 @@ class Quaternion { dst[dstOffset + 3] = w0; return; } - if (t === 1) { dst[dstOffset + 0] = x1; dst[dstOffset + 1] = y1; @@ -2811,26 +2503,26 @@ class Quaternion { dst[dstOffset + 3] = w1; return; } - if (w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1) { let s = 1 - t; const cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, - dir = cos >= 0 ? 1 : -1, - sqrSin = 1 - cos * cos; // Skip the Slerp for tiny steps to avoid numeric problems: + dir = cos >= 0 ? 1 : -1, + sqrSin = 1 - cos * cos; + // Skip the Slerp for tiny steps to avoid numeric problems: if (sqrSin > Number.EPSILON) { const sin = Math.sqrt(sqrSin), - len = Math.atan2(sin, cos * dir); + len = Math.atan2(sin, cos * dir); s = Math.sin(s * len) / sin; t = Math.sin(t * len) / sin; } - const tDir = t * dir; x0 = x0 * s + x1 * tDir; y0 = y0 * s + y1 * tDir; z0 = z0 * s + z1 * tDir; - w0 = w0 * s + w1 * tDir; // Normalize in case we just did a lerp: + w0 = w0 * s + w1 * tDir; + // Normalize in case we just did a lerp: if (s === 1 - t) { const f = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0); x0 *= f; @@ -2839,13 +2531,11 @@ class Quaternion { w0 *= f; } } - dst[dstOffset] = x0; dst[dstOffset + 1] = y0; dst[dstOffset + 2] = z0; dst[dstOffset + 3] = w0; } - static multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) { const x0 = src0[srcOffset0]; const y0 = src0[srcOffset0 + 1]; @@ -2861,82 +2551,60 @@ class Quaternion { dst[dstOffset + 3] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1; return dst; } - get x() { return this._x; } - set x(value) { this._x = value; - this._onChangeCallback(); } - get y() { return this._y; } - set y(value) { this._y = value; - this._onChangeCallback(); } - get z() { return this._z; } - set z(value) { this._z = value; - this._onChangeCallback(); } - get w() { return this._w; } - set w(value) { this._w = value; - this._onChangeCallback(); } - set(x, y, z, w) { this._x = x; this._y = y; this._z = z; this._w = w; - this._onChangeCallback(); - return this; } - clone() { return new this.constructor(this._x, this._y, this._z, this._w); } - copy(quaternion) { this._x = quaternion.x; this._y = quaternion.y; this._z = quaternion.z; this._w = quaternion.w; - this._onChangeCallback(); - return this; } - setFromEuler(euler, update) { - if (!(euler && euler.isEuler)) { - throw new Error('THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.'); - } - const x = euler._x, - y = euler._y, - z = euler._z, - order = euler._order; // http://www.mathworks.com/matlabcentral/fileexchange/ + 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 @@ -2948,7 +2616,6 @@ class Quaternion { const s1 = sin(x / 2); const s2 = sin(y / 2); const s3 = sin(z / 2); - switch (order) { case 'XYZ': this._x = s1 * c2 * c3 + c1 * s2 * s3; @@ -2956,80 +2623,72 @@ class Quaternion { this._z = c1 * c2 * s3 + s1 * s2 * c3; this._w = c1 * c2 * c3 - s1 * s2 * s3; break; - case 'YXZ': this._x = s1 * c2 * c3 + c1 * s2 * s3; this._y = c1 * s2 * c3 - s1 * c2 * s3; this._z = c1 * c2 * s3 - s1 * s2 * c3; this._w = c1 * c2 * c3 + s1 * s2 * s3; break; - case 'ZXY': this._x = s1 * c2 * c3 - c1 * s2 * s3; this._y = c1 * s2 * c3 + s1 * c2 * s3; this._z = c1 * c2 * s3 + s1 * s2 * c3; this._w = c1 * c2 * c3 - s1 * s2 * s3; break; - case 'ZYX': this._x = s1 * c2 * c3 - c1 * s2 * s3; this._y = c1 * s2 * c3 + s1 * c2 * s3; this._z = c1 * c2 * s3 - s1 * s2 * c3; this._w = c1 * c2 * c3 + s1 * s2 * s3; break; - case 'YZX': this._x = s1 * c2 * c3 + c1 * s2 * s3; this._y = c1 * s2 * c3 + s1 * c2 * s3; this._z = c1 * c2 * s3 - s1 * s2 * c3; this._w = c1 * c2 * c3 - s1 * s2 * s3; break; - case 'XZY': this._x = s1 * c2 * c3 - c1 * s2 * s3; this._y = c1 * s2 * c3 - s1 * c2 * s3; this._z = c1 * c2 * s3 + s1 * s2 * c3; this._w = c1 * c2 * c3 + s1 * s2 * s3; break; - default: console.warn('THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order); } - if (update !== false) this._onChangeCallback(); return this; } - setFromAxisAngle(axis, angle) { // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm + // assumes axis is normalized + const halfAngle = angle / 2, - s = Math.sin(halfAngle); + s = Math.sin(halfAngle); this._x = axis.x * s; this._y = axis.y * s; this._z = axis.z * s; this._w = Math.cos(halfAngle); - this._onChangeCallback(); - return this; } - setFromRotationMatrix(m) { // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - const te = m.elements, - m11 = te[0], - m12 = te[4], - m13 = te[8], - m21 = te[1], - m22 = te[5], - m23 = te[9], - m31 = te[2], - m32 = te[6], - m33 = te[10], - trace = m11 + m22 + m33; + const te = m.elements, + m11 = te[0], + m12 = te[4], + m13 = te[8], + m21 = te[1], + m22 = te[5], + m23 = te[9], + m31 = te[2], + m32 = te[6], + m33 = te[10], + trace = m11 + m22 + m33; if (trace > 0) { const s = 0.5 / Math.sqrt(trace + 1.0); this._w = 0.25 / s; @@ -3055,20 +2714,17 @@ class Quaternion { this._y = (m23 + m32) / s; this._z = 0.25 * s; } - this._onChangeCallback(); - return this; } - setFromUnitVectors(vFrom, vTo) { // assumes direction vectors vFrom and vTo are normalized - let r = vFrom.dot(vTo) + 1; + let r = vFrom.dot(vTo) + 1; if (r < Number.EPSILON) { // vFrom and vTo point in opposite directions - r = 0; + r = 0; if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) { this._x = -vFrom.y; this._y = vFrom.x; @@ -3082,19 +2738,17 @@ class Quaternion { } } else { // crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3 + this._x = vFrom.y * vTo.z - vFrom.z * vTo.y; this._y = vFrom.z * vTo.x - vFrom.x * vTo.z; this._z = vFrom.x * vTo.y - vFrom.y * vTo.x; this._w = r; } - return this.normalize(); } - angleTo(q) { return 2 * Math.acos(Math.abs(clamp(this.dot(q), -1, 1))); } - rotateTowards(q, step) { const angle = this.angleTo(q); if (angle === 0) return this; @@ -3102,41 +2756,32 @@ class Quaternion { this.slerp(q, t); return this; } - identity() { return this.set(0, 0, 0, 1); } - invert() { // quaternion is assumed to have unit length + return this.conjugate(); } - conjugate() { this._x *= -1; this._y *= -1; this._z *= -1; - this._onChangeCallback(); - return this; } - dot(v) { return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w; } - lengthSq() { return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w; } - length() { return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w); } - normalize() { let l = this.length(); - if (l === 0) { this._x = 0; this._y = 0; @@ -3149,50 +2794,44 @@ class Quaternion { this._z = this._z * l; this._w = this._w * l; } - this._onChangeCallback(); - return this; } - multiply(q) { return this.multiplyQuaternions(this, q); } - premultiply(q) { return this.multiplyQuaternions(q, this); } - multiplyQuaternions(a, b) { // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm + const qax = a._x, - qay = a._y, - qaz = a._z, - qaw = a._w; + qay = a._y, + qaz = a._z, + qaw = a._w; const qbx = b._x, - qby = b._y, - qbz = b._z, - qbw = b._w; + qby = b._y, + qbz = b._z, + qbw = b._w; this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; - this._onChangeCallback(); - return this; } - slerp(qb, t) { if (t === 0) return this; if (t === 1) return this.copy(qb); const x = this._x, - y = this._y, - z = this._z, - w = this._w; // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ + y = this._y, + z = this._z, + w = this._w; - let cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; + // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ + let cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; if (cosHalfTheta < 0) { this._w = -qb._w; this._x = -qb._x; @@ -3202,7 +2841,6 @@ class Quaternion { } else { this.copy(qb); } - if (cosHalfTheta >= 1.0) { this._w = w; this._x = x; @@ -3210,9 +2848,7 @@ class Quaternion { this._z = z; return this; } - const sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta; - if (sqrSinHalfTheta <= Number.EPSILON) { const s = 1 - t; this._w = s * w + t * this._w; @@ -3220,34 +2856,28 @@ class Quaternion { this._y = s * y + t * this._y; this._z = s * z + t * this._z; this.normalize(); - this._onChangeCallback(); - return this; } - const sinHalfTheta = Math.sqrt(sqrSinHalfTheta); const halfTheta = Math.atan2(sinHalfTheta, cosHalfTheta); const ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta, - ratioB = Math.sin(t * halfTheta) / sinHalfTheta; + ratioB = Math.sin(t * halfTheta) / sinHalfTheta; this._w = w * ratioA + this._w * ratioB; this._x = x * ratioA + this._x * ratioB; this._y = y * ratioA + this._y * ratioB; this._z = z * ratioA + this._z * ratioB; - this._onChangeCallback(); - return this; } - slerpQuaternions(qa, qb, t) { return this.copy(qa).slerp(qb, t); } - random() { // Derived from http://planning.cs.uiuc.edu/node198.html // Note, this source uses w, x, y, z ordering, // so we swap the order below. + const u1 = Math.random(); const sqrt1u1 = Math.sqrt(1 - u1); const sqrtu1 = Math.sqrt(u1); @@ -3255,22 +2885,17 @@ class Quaternion { const u3 = 2 * Math.PI * Math.random(); return this.set(sqrt1u1 * Math.cos(u2), sqrtu1 * Math.sin(u3), sqrtu1 * Math.cos(u3), sqrt1u1 * Math.sin(u2)); } - equals(quaternion) { return quaternion._x === this._x && quaternion._y === this._y && quaternion._z === this._z && quaternion._w === this._w; } - fromArray(array, offset = 0) { this._x = array[offset]; this._y = array[offset + 1]; this._z = array[offset + 2]; this._w = array[offset + 3]; - this._onChangeCallback(); - return this; } - toArray(array = [], offset = 0) { array[offset] = this._x; array[offset + 1] = this._y; @@ -3278,7 +2903,6 @@ class Quaternion { array[offset + 3] = this._w; return array; } - fromBufferAttribute(attribute, index) { this._x = attribute.getX(index); this._y = attribute.getY(index); @@ -3286,21 +2910,17 @@ class Quaternion { this._w = attribute.getW(index); return this; } - _onChange(callback) { this._onChangeCallback = callback; return this; } - _onChangeCallback() {} - *[Symbol.iterator]() { yield this._x; yield this._y; yield this._z; yield this._w; } - } class Vector3 { @@ -3310,7 +2930,6 @@ class Vector3 { this.y = y; this.z = z; } - set(x, y, z) { if (z === undefined) z = this.z; // sprite.scale.set(x,y) @@ -3319,174 +2938,144 @@ class Vector3 { this.z = z; return this; } - setScalar(scalar) { this.x = scalar; this.y = scalar; this.z = scalar; return this; } - setX(x) { this.x = x; return this; } - setY(y) { this.y = y; return this; } - setZ(z) { this.z = z; return this; } - setComponent(index, value) { switch (index) { case 0: this.x = value; break; - case 1: this.y = value; break; - case 2: this.z = value; break; - default: throw new Error('index is out of range: ' + index); } - return this; } - getComponent(index) { switch (index) { case 0: return this.x; - case 1: return this.y; - case 2: return this.z; - default: throw new Error('index is out of range: ' + index); } } - clone() { return new this.constructor(this.x, this.y, this.z); } - copy(v) { this.x = v.x; this.y = v.y; this.z = v.z; return this; } - add(v) { this.x += v.x; this.y += v.y; this.z += v.z; return this; } - addScalar(s) { this.x += s; this.y += s; this.z += s; return this; } - addVectors(a, b) { this.x = a.x + b.x; this.y = a.y + b.y; this.z = a.z + b.z; return this; } - addScaledVector(v, s) { this.x += v.x * s; this.y += v.y * s; this.z += v.z * s; return this; } - sub(v) { this.x -= v.x; this.y -= v.y; this.z -= v.z; return this; } - subScalar(s) { this.x -= s; this.y -= s; this.z -= s; return this; } - subVectors(a, b) { this.x = a.x - b.x; this.y = a.y - b.y; this.z = a.z - b.z; return this; } - multiply(v) { this.x *= v.x; this.y *= v.y; this.z *= v.z; return this; } - multiplyScalar(scalar) { this.x *= scalar; this.y *= scalar; this.z *= scalar; return this; } - multiplyVectors(a, b) { this.x = a.x * b.x; this.y = a.y * b.y; this.z = a.z * b.z; return this; } - applyEuler(euler) { return this.applyQuaternion(_quaternion$4.setFromEuler(euler)); } - applyAxisAngle(axis, angle) { return this.applyQuaternion(_quaternion$4.setFromAxisAngle(axis, angle)); } - applyMatrix3(m) { const x = this.x, - y = this.y, - z = this.z; + y = this.y, + z = this.z; const e = m.elements; this.x = e[0] * x + e[3] * y + e[6] * z; this.y = e[1] * x + e[4] * y + e[7] * z; this.z = e[2] * x + e[5] * y + e[8] * z; return this; } - applyNormalMatrix(m) { return this.applyMatrix3(m).normalize(); } - applyMatrix4(m) { const x = this.x, - y = this.y, - z = this.z; + y = this.y, + z = this.z; const e = m.elements; const w = 1 / (e[3] * x + e[7] * y + e[11] * z + e[15]); this.x = (e[0] * x + e[4] * y + e[8] * z + e[12]) * w; @@ -3494,230 +3083,205 @@ class Vector3 { this.z = (e[2] * x + e[6] * y + e[10] * z + e[14]) * w; return this; } - applyQuaternion(q) { const x = this.x, - y = this.y, - z = this.z; + y = this.y, + z = this.z; const qx = q.x, - qy = q.y, - qz = q.z, - qw = q.w; // calculate quat * vector + qy = q.y, + qz = q.z, + qw = q.w; + + // calculate quat * vector const ix = qw * x + qy * z - qz * y; const iy = qw * y + qz * x - qx * z; const iz = qw * z + qx * y - qy * x; - const iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat + const iw = -qx * x - qy * y - qz * z; + + // calculate result * inverse quat this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; return this; } - project(camera) { return this.applyMatrix4(camera.matrixWorldInverse).applyMatrix4(camera.projectionMatrix); } - unproject(camera) { return this.applyMatrix4(camera.projectionMatrixInverse).applyMatrix4(camera.matrixWorld); } - transformDirection(m) { // input: THREE.Matrix4 affine matrix // vector interpreted as a direction + const x = this.x, - y = this.y, - z = this.z; + y = this.y, + z = this.z; const e = m.elements; this.x = e[0] * x + e[4] * y + e[8] * z; this.y = e[1] * x + e[5] * y + e[9] * z; this.z = e[2] * x + e[6] * y + e[10] * z; return this.normalize(); } - divide(v) { this.x /= v.x; this.y /= v.y; this.z /= v.z; return this; } - divideScalar(scalar) { return this.multiplyScalar(1 / scalar); } - min(v) { this.x = Math.min(this.x, v.x); this.y = Math.min(this.y, v.y); this.z = Math.min(this.z, v.z); return this; } - max(v) { this.x = Math.max(this.x, v.x); this.y = Math.max(this.y, v.y); this.z = Math.max(this.z, v.z); return this; } - clamp(min, max) { // assumes min < max, componentwise + this.x = Math.max(min.x, Math.min(max.x, this.x)); this.y = Math.max(min.y, Math.min(max.y, this.y)); this.z = Math.max(min.z, Math.min(max.z, this.z)); return this; } - clampScalar(minVal, maxVal) { this.x = Math.max(minVal, Math.min(maxVal, this.x)); this.y = Math.max(minVal, Math.min(maxVal, this.y)); this.z = Math.max(minVal, Math.min(maxVal, this.z)); return this; } - clampLength(min, max) { const length = this.length(); return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length))); } - floor() { this.x = Math.floor(this.x); this.y = Math.floor(this.y); this.z = Math.floor(this.z); return this; } - ceil() { this.x = Math.ceil(this.x); this.y = Math.ceil(this.y); this.z = Math.ceil(this.z); return this; } - round() { this.x = Math.round(this.x); this.y = Math.round(this.y); this.z = Math.round(this.z); return this; } - roundToZero() { this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x); this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y); this.z = this.z < 0 ? Math.ceil(this.z) : Math.floor(this.z); return this; } - negate() { this.x = -this.x; this.y = -this.y; this.z = -this.z; return this; } - dot(v) { return this.x * v.x + this.y * v.y + this.z * v.z; - } // TODO lengthSquared? + } + // TODO lengthSquared? lengthSq() { return this.x * this.x + this.y * this.y + this.z * this.z; } - length() { return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); } - manhattanLength() { return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z); } - normalize() { return this.divideScalar(this.length() || 1); } - setLength(length) { return this.normalize().multiplyScalar(length); } - lerp(v, alpha) { this.x += (v.x - this.x) * alpha; this.y += (v.y - this.y) * alpha; this.z += (v.z - this.z) * alpha; return this; } - lerpVectors(v1, v2, alpha) { this.x = v1.x + (v2.x - v1.x) * alpha; this.y = v1.y + (v2.y - v1.y) * alpha; this.z = v1.z + (v2.z - v1.z) * alpha; return this; } - cross(v) { return this.crossVectors(this, v); } - crossVectors(a, b) { const ax = a.x, - ay = a.y, - az = a.z; + ay = a.y, + az = a.z; const bx = b.x, - by = b.y, - bz = b.z; + by = b.y, + bz = b.z; this.x = ay * bz - az * by; this.y = az * bx - ax * bz; this.z = ax * by - ay * bx; return this; } - projectOnVector(v) { const denominator = v.lengthSq(); if (denominator === 0) return this.set(0, 0, 0); const scalar = v.dot(this) / denominator; return this.copy(v).multiplyScalar(scalar); } - projectOnPlane(planeNormal) { _vector$c.copy(this).projectOnVector(planeNormal); - return this.sub(_vector$c); } - reflect(normal) { // reflect incident vector off plane orthogonal to normal // normal is assumed to have unit length + return this.sub(_vector$c.copy(normal).multiplyScalar(2 * this.dot(normal))); } - angleTo(v) { const denominator = Math.sqrt(this.lengthSq() * v.lengthSq()); if (denominator === 0) return Math.PI / 2; - const theta = this.dot(v) / denominator; // clamp, to handle numerical problems + const theta = this.dot(v) / denominator; + + // clamp, to handle numerical problems return Math.acos(clamp(theta, -1, 1)); } - distanceTo(v) { return Math.sqrt(this.distanceToSquared(v)); } - distanceToSquared(v) { const dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; + dy = this.y - v.y, + dz = this.z - v.z; return dx * dx + dy * dy + dz * dz; } - manhattanDistanceTo(v) { return Math.abs(this.x - v.x) + Math.abs(this.y - v.y) + Math.abs(this.z - v.z); } - setFromSpherical(s) { return this.setFromSphericalCoords(s.radius, s.phi, s.theta); } - setFromSphericalCoords(radius, phi, theta) { const sinPhiRadius = Math.sin(phi) * radius; this.x = sinPhiRadius * Math.sin(theta); @@ -3725,18 +3289,15 @@ class Vector3 { this.z = sinPhiRadius * Math.cos(theta); return this; } - setFromCylindrical(c) { return this.setFromCylindricalCoords(c.radius, c.theta, c.y); } - setFromCylindricalCoords(radius, theta, y) { this.x = radius * Math.sin(theta); this.y = y; this.z = radius * Math.cos(theta); return this; } - setFromMatrixPosition(m) { const e = m.elements; this.x = e[12]; @@ -3744,7 +3305,6 @@ class Vector3 { this.z = e[14]; return this; } - setFromMatrixScale(m) { const sx = this.setFromMatrixColumn(m, 0).length(); const sy = this.setFromMatrixColumn(m, 1).length(); @@ -3754,56 +3314,48 @@ class Vector3 { this.z = sz; return this; } - setFromMatrixColumn(m, index) { return this.fromArray(m.elements, index * 4); } - setFromMatrix3Column(m, index) { return this.fromArray(m.elements, index * 3); } - setFromEuler(e) { this.x = e._x; this.y = e._y; this.z = e._z; return this; } - equals(v) { return v.x === this.x && v.y === this.y && v.z === this.z; } - fromArray(array, offset = 0) { this.x = array[offset]; this.y = array[offset + 1]; this.z = array[offset + 2]; return this; } - toArray(array = [], offset = 0) { array[offset] = this.x; array[offset + 1] = this.y; array[offset + 2] = this.z; return array; } - fromBufferAttribute(attribute, index) { this.x = attribute.getX(index); this.y = attribute.getY(index); this.z = attribute.getZ(index); return this; } - random() { this.x = Math.random(); this.y = Math.random(); this.z = Math.random(); return this; } - randomDirection() { // Derived from https://mathworld.wolfram.com/SpherePointPicking.html + const u = (Math.random() - 0.5) * 2; const t = Math.random() * Math.PI * 2; const f = Math.sqrt(1 - u ** 2); @@ -3812,17 +3364,13 @@ class Vector3 { this.z = u; return this; } - *[Symbol.iterator]() { yield this.x; yield this.y; yield this.z; } - } - const _vector$c = /*@__PURE__*/new Vector3(); - const _quaternion$4 = /*@__PURE__*/new Quaternion(); class Box3 { @@ -3831,13 +3379,11 @@ class Box3 { this.min = min; this.max = max; } - set(min, max) { this.min.copy(min); this.max.copy(max); return this; } - setFromArray(array) { let minX = +Infinity; let minY = +Infinity; @@ -3845,7 +3391,6 @@ class Box3 { let maxX = -Infinity; let maxY = -Infinity; let maxZ = -Infinity; - for (let i = 0, l = array.length; i < l; i += 3) { const x = array[i]; const y = array[i + 1]; @@ -3857,12 +3402,10 @@ class Box3 { if (y > maxY) maxY = y; if (z > maxZ) maxZ = z; } - this.min.set(minX, minY, minZ); this.max.set(maxX, maxY, maxZ); return this; } - setFromBufferAttribute(attribute) { let minX = +Infinity; let minY = +Infinity; @@ -3870,7 +3413,6 @@ class Box3 { let maxX = -Infinity; let maxY = -Infinity; let maxZ = -Infinity; - for (let i = 0, l = attribute.count; i < l; i++) { const x = attribute.getX(i); const y = attribute.getY(i); @@ -3882,150 +3424,122 @@ class Box3 { if (y > maxY) maxY = y; if (z > maxZ) maxZ = z; } - this.min.set(minX, minY, minZ); this.max.set(maxX, maxY, maxZ); return this; } - setFromPoints(points) { this.makeEmpty(); - for (let i = 0, il = points.length; i < il; i++) { this.expandByPoint(points[i]); } - return this; } - setFromCenterAndSize(center, size) { const halfSize = _vector$b.copy(size).multiplyScalar(0.5); - this.min.copy(center).sub(halfSize); this.max.copy(center).add(halfSize); return this; } - setFromObject(object, precise = false) { this.makeEmpty(); return this.expandByObject(object, precise); } - clone() { return new this.constructor().copy(this); } - copy(box) { this.min.copy(box.min); this.max.copy(box.max); return this; } - makeEmpty() { this.min.x = this.min.y = this.min.z = +Infinity; this.max.x = this.max.y = this.max.z = -Infinity; return this; } - 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; } - getCenter(target) { return this.isEmpty() ? target.set(0, 0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5); } - getSize(target) { return this.isEmpty() ? target.set(0, 0, 0) : target.subVectors(this.max, this.min); } - expandByPoint(point) { this.min.min(point); this.max.max(point); return this; } - expandByVector(vector) { this.min.sub(vector); this.max.add(vector); return this; } - expandByScalar(scalar) { this.min.addScalar(-scalar); this.max.addScalar(scalar); return this; } - expandByObject(object, precise = false) { // 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); const geometry = object.geometry; - if (geometry !== undefined) { if (precise && geometry.attributes != undefined && geometry.attributes.position !== undefined) { const position = geometry.attributes.position; - for (let i = 0, l = position.count; i < l; i++) { _vector$b.fromBufferAttribute(position, i).applyMatrix4(object.matrixWorld); - this.expandByPoint(_vector$b); } } else { if (geometry.boundingBox === null) { geometry.computeBoundingBox(); } - _box$3.copy(geometry.boundingBox); - _box$3.applyMatrix4(object.matrixWorld); - this.union(_box$3); } } - const children = object.children; - for (let i = 0, l = children.length; i < l; i++) { this.expandByObject(children[i], precise); } - return this; } - 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; } - 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; } - getParameter(point, target) { // This can potentially have a divide by zero if the box // has a size dimension of 0. + 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)); } - 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; } - intersectsSphere(sphere) { // Find the point on the AABB closest to the sphere center. - this.clampPoint(sphere.center, _vector$b); // If that point is inside the sphere, the AABB and sphere intersect. + this.clampPoint(sphere.center, _vector$b); + // If that point is inside the sphere, the AABB and sphere intersect. return _vector$b.distanceToSquared(sphere.center) <= sphere.radius * sphere.radius; } - 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. - let min, max; + let min, max; if (plane.normal.x > 0) { min = plane.normal.x * this.min.x; max = plane.normal.x * this.max.x; @@ -4033,7 +3547,6 @@ class Box3 { min = plane.normal.x * this.max.x; max = plane.normal.x * this.min.x; } - if (plane.normal.y > 0) { min += plane.normal.y * this.min.y; max += plane.normal.y * this.max.y; @@ -4041,7 +3554,6 @@ class Box3 { min += plane.normal.y * this.max.y; max += plane.normal.y * this.min.y; } - if (plane.normal.z > 0) { min += plane.normal.z * this.min.z; max += plane.normal.z * this.max.z; @@ -4049,411 +3561,318 @@ class Box3 { min += plane.normal.z * this.max.z; max += plane.normal.z * this.min.z; } - return min <= -plane.constant && max >= -plane.constant; } - intersectsTriangle(triangle) { if (this.isEmpty()) { return false; - } // compute box center and extents - + } + // compute box center and extents this.getCenter(_center); + _extents.subVectors(this.max, _center); - _extents.subVectors(this.max, _center); // translate triangle to aabb origin - - + // translate triangle to aabb origin _v0$2.subVectors(triangle.a, _center); - _v1$7.subVectors(triangle.b, _center); + _v2$4.subVectors(triangle.c, _center); - _v2$3.subVectors(triangle.c, _center); // compute edge vectors for triangle - - + // compute edge vectors for triangle _f0.subVectors(_v1$7, _v0$2); + _f1.subVectors(_v2$4, _v1$7); + _f2.subVectors(_v0$2, _v2$4); - _f1.subVectors(_v2$3, _v1$7); - - _f2.subVectors(_v0$2, _v2$3); // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb + // 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) - - let 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]; - - if (!satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents)) { + if (!satForAxes(axes, _v0$2, _v1$7, _v2$4, _extents)) { return false; - } // test 3 face normals from the aabb - + } + // test 3 face normals from the aabb axes = [1, 0, 0, 0, 1, 0, 0, 0, 1]; - - if (!satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents)) { + if (!satForAxes(axes, _v0$2, _v1$7, _v2$4, _extents)) { return false; - } // finally testing the face normal of the triangle - // use already existing triangle edge vectors here - + } + // finally testing the face normal of the triangle + // use already existing triangle edge vectors here _triangleNormal.crossVectors(_f0, _f1); - axes = [_triangleNormal.x, _triangleNormal.y, _triangleNormal.z]; - return satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents); + return satForAxes(axes, _v0$2, _v1$7, _v2$4, _extents); } - clampPoint(point, target) { return target.copy(point).clamp(this.min, this.max); } - distanceToPoint(point) { const clampedPoint = _vector$b.copy(point).clamp(this.min, this.max); - return clampedPoint.sub(point).length(); } - getBoundingSphere(target) { this.getCenter(target.center); target.radius = this.getSize(_vector$b).length() * 0.5; return target; } - 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. + 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. if (this.isEmpty()) this.makeEmpty(); return this; } - union(box) { this.min.min(box.min); this.max.max(box.max); return this; } - 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 + if (this.isEmpty()) return this; + // 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 - this.setFromPoints(_points); return this; } - translate(offset) { this.min.add(offset); this.max.add(offset); return this; } - equals(box) { return box.min.equals(this.min) && box.max.equals(this.max); } - } - const _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()]; - const _vector$b = /*@__PURE__*/new Vector3(); +const _box$3 = /*@__PURE__*/new Box3(); -const _box$3 = /*@__PURE__*/new Box3(); // triangle centered vertices - +// triangle centered vertices const _v0$2 = /*@__PURE__*/new Vector3(); - const _v1$7 = /*@__PURE__*/new Vector3(); +const _v2$4 = /*@__PURE__*/new Vector3(); -const _v2$3 = /*@__PURE__*/new Vector3(); // triangle edge vectors - +// triangle edge vectors const _f0 = /*@__PURE__*/new Vector3(); - const _f1 = /*@__PURE__*/new Vector3(); - const _f2 = /*@__PURE__*/new Vector3(); - const _center = /*@__PURE__*/new Vector3(); - const _extents = /*@__PURE__*/new Vector3(); - const _triangleNormal = /*@__PURE__*/new Vector3(); - const _testAxis = /*@__PURE__*/new Vector3(); - function satForAxes(axes, v0, v1, v2, extents) { for (let i = 0, j = axes.length - 3; i <= j; i += 3) { - _testAxis.fromArray(axes, i); // project the aabb onto the separating axis - - - const 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 separating axis - + _testAxis.fromArray(axes, i); + // project the aabb onto the separating axis + const 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 separating axis const p0 = v0.dot(_testAxis); const p1 = v1.dot(_testAxis); - const p2 = v2.dot(_testAxis); // actual test, basically see if either of the most extreme of the triangle points intersects r - + const 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 separating and we can exit return false; } } - return true; } const _box$2 = /*@__PURE__*/new Box3(); - const _v1$6 = /*@__PURE__*/new Vector3(); - -const _toFarthestPoint = /*@__PURE__*/new Vector3(); - -const _toPoint = /*@__PURE__*/new Vector3(); - +const _v2$3 = /*@__PURE__*/new Vector3(); class Sphere { constructor(center = new Vector3(), radius = -1) { this.center = center; this.radius = radius; } - set(center, radius) { this.center.copy(center); this.radius = radius; return this; } - setFromPoints(points, optionalCenter) { const center = this.center; - if (optionalCenter !== undefined) { center.copy(optionalCenter); } else { _box$2.setFromPoints(points).getCenter(center); } - let maxRadiusSq = 0; - for (let i = 0, il = points.length; i < il; i++) { maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(points[i])); } - this.radius = Math.sqrt(maxRadiusSq); return this; } - copy(sphere) { this.center.copy(sphere.center); this.radius = sphere.radius; return this; } - isEmpty() { return this.radius < 0; } - makeEmpty() { this.center.set(0, 0, 0); this.radius = -1; return this; } - containsPoint(point) { return point.distanceToSquared(this.center) <= this.radius * this.radius; } - distanceToPoint(point) { return point.distanceTo(this.center) - this.radius; } - intersectsSphere(sphere) { const radiusSum = this.radius + sphere.radius; return sphere.center.distanceToSquared(this.center) <= radiusSum * radiusSum; } - intersectsBox(box) { return box.intersectsSphere(this); } - intersectsPlane(plane) { return Math.abs(plane.distanceToPoint(this.center)) <= this.radius; } - clampPoint(point, target) { const deltaLengthSq = this.center.distanceToSquared(point); target.copy(point); - if (deltaLengthSq > this.radius * this.radius) { target.sub(this.center).normalize(); target.multiplyScalar(this.radius).add(this.center); } - return target; } - getBoundingBox(target) { 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; } - applyMatrix4(matrix) { this.center.applyMatrix4(matrix); this.radius = this.radius * matrix.getMaxScaleOnAxis(); return this; } - translate(offset) { this.center.add(offset); return this; } - expandByPoint(point) { - // from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L649-L671 - _toPoint.subVectors(point, this.center); - - const lengthSq = _toPoint.lengthSq(); - + if (this.isEmpty()) { + this.center.copy(point); + this.radius = 0; + return this; + } + _v1$6.subVectors(point, this.center); + const lengthSq = _v1$6.lengthSq(); if (lengthSq > this.radius * this.radius) { - const length = Math.sqrt(lengthSq); - const missingRadiusHalf = (length - this.radius) * 0.5; // Nudge this sphere towards the target point. Add half the missing distance to radius, - // and the other half to position. This gives a tighter enclosure, instead of if - // the whole missing distance were just added to radius. + // calculate the minimal sphere - this.center.add(_toPoint.multiplyScalar(missingRadiusHalf / length)); - this.radius += missingRadiusHalf; + const length = Math.sqrt(lengthSq); + const delta = (length - this.radius) * 0.5; + this.center.addScaledVector(_v1$6, delta / length); + this.radius += delta; } - return this; } - union(sphere) { - // from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L759-L769 - // To enclose another sphere into this sphere, we only need to enclose two points: - // 1) Enclose the farthest point on the other sphere into this sphere. - // 2) Enclose the opposite point of the farthest point into this sphere. + if (sphere.isEmpty()) { + return this; + } + if (this.isEmpty()) { + this.copy(sphere); + return this; + } if (this.center.equals(sphere.center) === true) { - _toFarthestPoint.set(0, 0, 1).multiplyScalar(sphere.radius); + this.radius = Math.max(this.radius, sphere.radius); } else { - _toFarthestPoint.subVectors(sphere.center, this.center).normalize().multiplyScalar(sphere.radius); + _v2$3.subVectors(sphere.center, this.center).setLength(sphere.radius); + this.expandByPoint(_v1$6.copy(sphere.center).add(_v2$3)); + this.expandByPoint(_v1$6.copy(sphere.center).sub(_v2$3)); } - - this.expandByPoint(_v1$6.copy(sphere.center).add(_toFarthestPoint)); - this.expandByPoint(_v1$6.copy(sphere.center).sub(_toFarthestPoint)); return this; } - equals(sphere) { return sphere.center.equals(this.center) && sphere.radius === this.radius; } - clone() { return new this.constructor().copy(this); } - } const _vector$a = /*@__PURE__*/new Vector3(); - const _segCenter = /*@__PURE__*/new Vector3(); - const _segDir = /*@__PURE__*/new Vector3(); - const _diff = /*@__PURE__*/new Vector3(); - const _edge1 = /*@__PURE__*/new Vector3(); - const _edge2 = /*@__PURE__*/new Vector3(); - const _normal$1 = /*@__PURE__*/new Vector3(); - class Ray { constructor(origin = new Vector3(), direction = new Vector3(0, 0, -1)) { this.origin = origin; this.direction = direction; } - set(origin, direction) { this.origin.copy(origin); this.direction.copy(direction); return this; } - copy(ray) { this.origin.copy(ray.origin); this.direction.copy(ray.direction); return this; } - at(t, target) { return target.copy(this.direction).multiplyScalar(t).add(this.origin); } - lookAt(v) { this.direction.copy(v).sub(this.origin).normalize(); return this; } - recast(t) { this.origin.copy(this.at(t, _vector$a)); return this; } - closestPointToPoint(point, target) { target.subVectors(point, this.origin); const directionDistance = target.dot(this.direction); - if (directionDistance < 0) { return target.copy(this.origin); } - return target.copy(this.direction).multiplyScalar(directionDistance).add(this.origin); } - distanceToPoint(point) { return Math.sqrt(this.distanceSqToPoint(point)); } - distanceSqToPoint(point) { - const directionDistance = _vector$a.subVectors(point, this.origin).dot(this.direction); // point behind the ray + const directionDistance = _vector$a.subVectors(point, this.origin).dot(this.direction); + // point behind the ray if (directionDistance < 0) { return this.origin.distanceToSquared(point); } - _vector$a.copy(this.direction).multiplyScalar(directionDistance).add(this.origin); - return _vector$a.distanceToSquared(point); } - distanceSqToSegment(v0, v1, optionalPointOnRay, optionalPointOnSegment) { // from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteDistRaySegment.h // It returns the min distance between the ray and the segment @@ -4461,47 +3880,43 @@ class Ray { // 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); + _segCenter.copy(v0).add(v1).multiplyScalar(0.5); _segDir.copy(v1).sub(v0).normalize(); - _diff.copy(this.origin).sub(_segCenter); - const segExtent = v0.distanceTo(v1) * 0.5; const a01 = -this.direction.dot(_segDir); - const b0 = _diff.dot(this.direction); - const b1 = -_diff.dot(_segDir); - const c = _diff.lengthSq(); - const det = Math.abs(1 - a01 * a01); let s0, s1, sqrDist, extDet; - 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 (s1 >= -extDet) { if (s1 <= extDet) { // region 0 // Minimum at interior points of ray and segment. + const 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; @@ -4509,16 +3924,19 @@ class Ray { } 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; @@ -4526,102 +3944,94 @@ class Ray { } } 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); } - if (optionalPointOnSegment) { optionalPointOnSegment.copy(_segDir).multiplyScalar(s1).add(_segCenter); } - return sqrDist; } - intersectSphere(sphere, target) { _vector$a.subVectors(sphere.center, this.origin); - const tca = _vector$a.dot(this.direction); - const d2 = _vector$a.dot(_vector$a) - tca * tca; const radius2 = sphere.radius * sphere.radius; if (d2 > radius2) return null; - const thc = Math.sqrt(radius2 - d2); // t0 = first intersect point - entrance on front of sphere + const thc = Math.sqrt(radius2 - d2); - const t0 = tca - thc; // t1 = second intersect point - exit point on back of sphere + // t0 = first intersect point - entrance on front of sphere + const t0 = tca - thc; - const t1 = tca + thc; // test to see if both t0 and t1 are behind the ray - if so, return null + // t1 = second intersect point - exit point on back of sphere + const t1 = tca + thc; - if (t0 < 0 && t1 < 0) return null; // test to see if t0 is behind the ray: + // 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. + if (t0 < 0) return this.at(t1, target); - 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 - + // else t0 is in front of the ray, so return the first collision point scaled by t0 return this.at(t0, target); } - intersectsSphere(sphere) { return this.distanceSqToPoint(sphere.center) <= sphere.radius * sphere.radius; } - distanceToPlane(plane) { const denominator = plane.normal.dot(this.direction); - 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 + } + // Null is preferable to undefined since undefined means.... it is undefined return null; } + const t = -(this.origin.dot(plane.normal) + plane.constant) / denominator; - const t = -(this.origin.dot(plane.normal) + plane.constant) / denominator; // Return if the ray never intersects the plane + // Return if the ray never intersects the plane return t >= 0 ? t : null; } - intersectPlane(plane, target) { const t = this.distanceToPlane(plane); - if (t === null) { return null; } - return this.at(t, target); } - intersectsPlane(plane) { // check if the ray lies on the plane first - const distToPoint = plane.distanceToPoint(this.origin); + const distToPoint = plane.distanceToPoint(this.origin); if (distToPoint === 0) { return true; } - const denominator = plane.normal.dot(this.direction); - if (denominator * distToPoint < 0) { return true; - } // ray origin is behind the plane (and is pointing behind it) + } + // ray origin is behind the plane (and is pointing behind it) return false; } - intersectBox(box, target) { let tmin, tmax, tymin, tymax, tzmin, tzmax; const invdirx = 1 / this.direction.x, - invdiry = 1 / this.direction.y, - invdirz = 1 / this.direction.z; + invdiry = 1 / this.direction.y, + invdirz = 1 / this.direction.z; const origin = this.origin; - if (invdirx >= 0) { tmin = (box.min.x - origin.x) * invdirx; tmax = (box.max.x - origin.x) * invdirx; @@ -4629,7 +4039,6 @@ class Ray { tmin = (box.max.x - origin.x) * invdirx; tmax = (box.min.x - origin.x) * invdirx; } - if (invdiry >= 0) { tymin = (box.min.y - origin.y) * invdiry; tymax = (box.max.y - origin.y) * invdiry; @@ -4637,13 +4046,9 @@ class Ray { 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; - + if (tmin > tymax || tymin > tmax) return null; + if (tymin > tmin || isNaN(tmin)) tmin = tymin; + if (tymax < tmax || isNaN(tmax)) tmax = tymax; if (invdirz >= 0) { tzmin = (box.min.z - origin.z) * invdirz; tzmax = (box.max.z - origin.z) * invdirz; @@ -4651,36 +4056,34 @@ class Ray { tzmin = (box.max.z - origin.z) * invdirz; tzmax = (box.min.z - origin.z) * invdirz; } - 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) + if (tzmax < tmax || tmax !== tmax) tmax = tzmax; + + //return point closest to the ray (positive side) if (tmax < 0) return null; return this.at(tmin >= 0 ? tmin : tmax, target); } - intersectsBox(box) { return this.intersectBox(box, _vector$a) !== null; } - intersectTriangle(a, b, c, backfaceCulling, target) { // Compute the offset origin, edges, and normal. + // from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h - _edge1.subVectors(b, a); + _edge1.subVectors(b, a); _edge2.subVectors(c, a); + _normal$1.crossVectors(_edge1, _edge2); - _normal$1.crossVectors(_edge1, _edge2); // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction, + // 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) - - let DdN = this.direction.dot(_normal$1); let sign; - if (DdN > 0) { if (backfaceCulling) return null; sign = 1; @@ -4690,52 +4093,47 @@ class Ray { } else { return null; } - _diff.subVectors(this.origin, a); + const DdQxE2 = sign * this.direction.dot(_edge2.crossVectors(_diff, _edge2)); - const DdQxE2 = sign * this.direction.dot(_edge2.crossVectors(_diff, _edge2)); // b1 < 0, no intersection - + // b1 < 0, no intersection if (DdQxE2 < 0) { return null; } + const DdE1xQ = sign * this.direction.dot(_edge1.cross(_diff)); - const DdE1xQ = sign * this.direction.dot(_edge1.cross(_diff)); // b2 < 0, no intersection - + // b2 < 0, no intersection if (DdE1xQ < 0) { return null; - } // b1+b2 > 1, no intersection - + } + // b1+b2 > 1, no intersection if (DdQxE2 + DdE1xQ > DdN) { return null; - } // Line intersects triangle, check if ray does. - - - const QdN = -sign * _diff.dot(_normal$1); // t < 0, no intersection + } + // Line intersects triangle, check if ray does. + const QdN = -sign * _diff.dot(_normal$1); + // t < 0, no intersection if (QdN < 0) { return null; - } // Ray intersects triangle. - + } + // Ray intersects triangle. return this.at(QdN / DdN, target); } - applyMatrix4(matrix4) { this.origin.applyMatrix4(matrix4); this.direction.transformDirection(matrix4); return this; } - equals(ray) { return ray.origin.equals(this.origin) && ray.direction.equals(this.direction); } - clone() { return new this.constructor().copy(this); } - } class Matrix4 { @@ -4743,7 +4141,6 @@ class Matrix4 { Matrix4.prototype.isMatrix4 = true; this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; } - set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) { const te = this.elements; te[0] = n11; @@ -4764,16 +4161,13 @@ class Matrix4 { te[15] = n44; return this; } - identity() { this.set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); return this; } - clone() { return new Matrix4().fromArray(this.elements); } - copy(m) { const te = this.elements; const me = m.elements; @@ -4795,45 +4189,37 @@ class Matrix4 { te[15] = me[15]; return this; } - copyPosition(m) { const te = this.elements, - me = m.elements; + me = m.elements; te[12] = me[12]; te[13] = me[13]; te[14] = me[14]; return this; } - setFromMatrix3(m) { const me = m.elements; this.set(me[0], me[3], me[6], 0, me[1], me[4], me[7], 0, me[2], me[5], me[8], 0, 0, 0, 0, 1); return this; } - extractBasis(xAxis, yAxis, zAxis) { xAxis.setFromMatrixColumn(this, 0); yAxis.setFromMatrixColumn(this, 1); zAxis.setFromMatrixColumn(this, 2); return this; } - makeBasis(xAxis, yAxis, zAxis) { this.set(xAxis.x, yAxis.x, zAxis.x, 0, xAxis.y, yAxis.y, zAxis.y, 0, xAxis.z, yAxis.z, zAxis.z, 0, 0, 0, 0, 1); return this; } - extractRotation(m) { // this method does not support reflection matrices + const te = this.elements; const me = m.elements; - const scaleX = 1 / _v1$5.setFromMatrixColumn(m, 0).length(); - const scaleY = 1 / _v1$5.setFromMatrixColumn(m, 1).length(); - const scaleZ = 1 / _v1$5.setFromMatrixColumn(m, 2).length(); - te[0] = me[0] * scaleX; te[1] = me[1] * scaleX; te[2] = me[2] * scaleX; @@ -4852,24 +4238,22 @@ class Matrix4 { te[15] = 1; return this; } - makeRotationFromEuler(euler) { const te = this.elements; const x = euler.x, - y = euler.y, - z = euler.z; + y = euler.y, + z = euler.z; const a = Math.cos(x), - b = Math.sin(x); + b = Math.sin(x); const c = Math.cos(y), - d = Math.sin(y); + d = Math.sin(y); const e = Math.cos(z), - f = Math.sin(z); - + f = Math.sin(z); if (euler.order === 'XYZ') { const ae = a * e, - af = a * f, - be = b * e, - bf = b * f; + af = a * f, + be = b * e, + bf = b * f; te[0] = c * e; te[4] = -c * f; te[8] = d; @@ -4881,9 +4265,9 @@ class Matrix4 { te[10] = a * c; } else if (euler.order === 'YXZ') { const ce = c * e, - cf = c * f, - de = d * e, - df = d * f; + cf = c * f, + de = d * e, + df = d * f; te[0] = ce + df * b; te[4] = de * b - cf; te[8] = a * d; @@ -4895,9 +4279,9 @@ class Matrix4 { te[10] = a * c; } else if (euler.order === 'ZXY') { const ce = c * e, - cf = c * f, - de = d * e, - df = d * f; + cf = c * f, + de = d * e, + df = d * f; te[0] = ce - df * b; te[4] = -a * f; te[8] = de + cf * b; @@ -4909,9 +4293,9 @@ class Matrix4 { te[10] = a * c; } else if (euler.order === 'ZYX') { const ae = a * e, - af = a * f, - be = b * e, - bf = b * f; + af = a * f, + be = b * e, + bf = b * f; te[0] = c * e; te[4] = be * d - af; te[8] = ae * d + bf; @@ -4923,9 +4307,9 @@ class Matrix4 { te[10] = a * c; } else if (euler.order === 'YZX') { const ac = a * c, - ad = a * d, - bc = b * c, - bd = b * d; + ad = a * d, + bc = b * c, + bd = b * d; te[0] = c * e; te[4] = bd - ac * f; te[8] = bc * f + ad; @@ -4937,9 +4321,9 @@ class Matrix4 { te[10] = ac - bd * f; } else if (euler.order === 'XZY') { const ac = a * c, - ad = a * d, - bc = b * c, - bd = b * d; + ad = a * d, + bc = b * c, + bd = b * d; te[0] = c * e; te[4] = -f; te[8] = d * e; @@ -4949,55 +4333,46 @@ class Matrix4 { te[2] = bc * f - ad; te[6] = b * e; te[10] = bd * f + ac; - } // bottom row - + } + // bottom row te[3] = 0; te[7] = 0; - te[11] = 0; // last column + te[11] = 0; + // last column te[12] = 0; te[13] = 0; te[14] = 0; te[15] = 1; return this; } - makeRotationFromQuaternion(q) { return this.compose(_zero, q, _one); } - lookAt(eye, target, up) { const te = this.elements; - _z.subVectors(eye, target); - if (_z.lengthSq() === 0) { // eye and target are in the same position + _z.z = 1; } - _z.normalize(); - _x.crossVectors(up, _z); - if (_x.lengthSq() === 0) { // up and z are parallel + if (Math.abs(up.z) === 1) { _z.x += 0.0001; } else { _z.z += 0.0001; } - _z.normalize(); - _x.crossVectors(up, _z); } - _x.normalize(); - _y.crossVectors(_z, _x); - te[0] = _x.x; te[4] = _y.x; te[8] = _z.x; @@ -5009,51 +4384,48 @@ class Matrix4 { te[10] = _z.z; return this; } - multiply(m) { return this.multiplyMatrices(this, m); } - premultiply(m) { return this.multiplyMatrices(m, this); } - multiplyMatrices(a, b) { const ae = a.elements; const be = b.elements; const te = this.elements; const a11 = ae[0], - a12 = ae[4], - a13 = ae[8], - a14 = ae[12]; + a12 = ae[4], + a13 = ae[8], + a14 = ae[12]; const a21 = ae[1], - a22 = ae[5], - a23 = ae[9], - a24 = ae[13]; + a22 = ae[5], + a23 = ae[9], + a24 = ae[13]; const a31 = ae[2], - a32 = ae[6], - a33 = ae[10], - a34 = ae[14]; + a32 = ae[6], + a33 = ae[10], + a34 = ae[14]; const a41 = ae[3], - a42 = ae[7], - a43 = ae[11], - a44 = ae[15]; + a42 = ae[7], + a43 = ae[11], + a44 = ae[15]; const b11 = be[0], - b12 = be[4], - b13 = be[8], - b14 = be[12]; + b12 = be[4], + b13 = be[8], + b14 = be[12]; const b21 = be[1], - b22 = be[5], - b23 = be[9], - b24 = be[13]; + b22 = be[5], + b23 = be[9], + b24 = be[13]; const b31 = be[2], - b32 = be[6], - b33 = be[10], - b34 = be[14]; + b32 = be[6], + b33 = be[10], + b34 = be[14]; const b41 = be[3], - b42 = be[7], - b43 = be[11], - b44 = be[15]; + 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; @@ -5072,7 +4444,6 @@ class Matrix4 { te[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; return this; } - multiplyScalar(s) { const te = this.elements; te[0] *= s; @@ -5093,30 +4464,30 @@ class Matrix4 { te[15] *= s; return this; } - determinant() { const te = this.elements; const n11 = te[0], - n12 = te[4], - n13 = te[8], - n14 = te[12]; + n12 = te[4], + n13 = te[8], + n14 = te[12]; const n21 = te[1], - n22 = te[5], - n23 = te[9], - n24 = te[13]; + n22 = te[5], + n23 = te[9], + n24 = te[13]; const n31 = te[2], - n32 = te[6], - n33 = te[10], - n34 = te[14]; + n32 = te[6], + n33 = te[10], + n34 = te[14]; const n41 = te[3], - n42 = te[7], - n43 = te[11], - n44 = te[15]; //TODO: make this more efficient + n42 = te[7], + n43 = te[11], + n44 = te[15]; + + //TODO: make this more efficient //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm ) return n41 * (+n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34) + n42 * (+n11 * n23 * n34 - n11 * n24 * n33 + n14 * n21 * n33 - n13 * n21 * n34 + n13 * n24 * n31 - n14 * n23 * n31) + n43 * (+n11 * n24 * n32 - n11 * n22 * n34 - n14 * n21 * n32 + n12 * n21 * n34 + n14 * n22 * n31 - n12 * n24 * n31) + n44 * (-n13 * n22 * n31 - n11 * n23 * n32 + n11 * n22 * n33 + n13 * n21 * n32 - n12 * n21 * n33 + n12 * n23 * n31); } - transpose() { const te = this.elements; let tmp; @@ -5140,10 +4511,8 @@ class Matrix4 { te[14] = tmp; return this; } - setPosition(x, y, z) { const te = this.elements; - if (x.isVector3) { te[12] = x.x; te[13] = x.y; @@ -5153,33 +4522,31 @@ class Matrix4 { te[13] = y; te[14] = z; } - return this; } - invert() { // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm const te = this.elements, - n11 = te[0], - n21 = te[1], - n31 = te[2], - n41 = te[3], - n12 = te[4], - n22 = te[5], - n32 = te[6], - n42 = te[7], - n13 = te[8], - n23 = te[9], - n33 = te[10], - n43 = te[11], - n14 = te[12], - n24 = te[13], - n34 = te[14], - n44 = te[15], - t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44, - t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44, - t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44, - t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; + n11 = te[0], + n21 = te[1], + n31 = te[2], + n41 = te[3], + n12 = te[4], + n22 = te[5], + n32 = te[6], + n42 = te[7], + n13 = te[8], + n23 = te[9], + n33 = te[10], + n43 = te[11], + n14 = te[12], + n24 = te[13], + n34 = te[14], + n44 = te[15], + t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44, + t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44, + t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44, + t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; const det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14; if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); const detInv = 1 / det; @@ -5201,12 +4568,11 @@ class Matrix4 { te[15] = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * detInv; return this; } - scale(v) { const te = this.elements; const x = v.x, - y = v.y, - z = v.z; + y = v.y, + z = v.z; te[0] *= x; te[4] *= y; te[8] *= z; @@ -5221,7 +4587,6 @@ class Matrix4 { te[11] *= z; return this; } - getMaxScaleOnAxis() { const te = this.elements; const scaleXSq = te[0] * te[0] + te[1] * te[1] + te[2] * te[2]; @@ -5229,78 +4594,71 @@ class Matrix4 { const scaleZSq = te[8] * te[8] + te[9] * te[9] + te[10] * te[10]; return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq)); } - makeTranslation(x, y, z) { this.set(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1); return this; } - makeRotationX(theta) { const c = Math.cos(theta), - s = Math.sin(theta); + s = Math.sin(theta); this.set(1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1); return this; } - makeRotationY(theta) { const c = Math.cos(theta), - s = Math.sin(theta); + s = Math.sin(theta); this.set(c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1); return this; } - makeRotationZ(theta) { const c = Math.cos(theta), - s = Math.sin(theta); + s = Math.sin(theta); this.set(c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); return this; } - makeRotationAxis(axis, angle) { // Based on http://www.gamedev.net/reference/articles/article1199.asp + const c = Math.cos(angle); const s = Math.sin(angle); const t = 1 - c; const x = axis.x, - y = axis.y, - z = axis.z; + y = axis.y, + z = axis.z; const tx = t * x, - ty = t * y; + ty = t * y; this.set(tx * x + c, tx * y - s * z, tx * z + s * y, 0, tx * y + s * z, ty * y + c, ty * z - s * x, 0, tx * z - s * y, ty * z + s * x, t * z * z + c, 0, 0, 0, 0, 1); return this; } - makeScale(x, y, z) { this.set(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1); return this; } - makeShear(xy, xz, yx, yz, zx, zy) { this.set(1, yx, zx, 0, xy, 1, zy, 0, xz, yz, 1, 0, 0, 0, 0, 1); return this; } - compose(position, quaternion, scale) { const te = this.elements; const x = quaternion._x, - y = quaternion._y, - z = quaternion._z, - w = quaternion._w; + y = quaternion._y, + z = quaternion._z, + w = quaternion._w; const x2 = x + x, - y2 = y + y, - z2 = z + z; + y2 = y + y, + z2 = z + z; const xx = x * x2, - xy = x * y2, - xz = x * z2; + xy = x * y2, + xz = x * z2; const yy = y * y2, - yz = y * z2, - zz = z * z2; + yz = y * z2, + zz = z * z2; const wx = w * x2, - wy = w * y2, - wz = w * z2; + wy = w * y2, + wz = w * z2; const sx = scale.x, - sy = scale.y, - sz = scale.z; + sy = scale.y, + sz = scale.z; te[0] = (1 - (yy + zz)) * sx; te[1] = (xy + wz) * sx; te[2] = (xz - wy) * sx; @@ -5319,25 +4677,21 @@ class Matrix4 { te[15] = 1; return this; } - decompose(position, quaternion, scale) { const te = this.elements; - let sx = _v1$5.set(te[0], te[1], te[2]).length(); - const sy = _v1$5.set(te[4], te[5], te[6]).length(); + const sz = _v1$5.set(te[8], te[9], te[10]).length(); - const sz = _v1$5.set(te[8], te[9], te[10]).length(); // if determine is negative, we need to invert one scale - - + // if determine is negative, we need to invert one scale const det = this.determinant(); if (det < 0) sx = -sx; position.x = te[12]; position.y = te[13]; - position.z = te[14]; // scale the rotation part + position.z = te[14]; + // scale the rotation part _m1$2.copy(this); - const invSX = 1 / sx; const invSY = 1 / sy; const invSZ = 1 / sz; @@ -5356,7 +4710,6 @@ class Matrix4 { scale.z = sz; return this; } - makePerspective(left, right, top, bottom, near, far) { const te = this.elements; const x = 2 * near / (right - left); @@ -5383,7 +4736,6 @@ class Matrix4 { te[15] = 0; return this; } - makeOrthographic(left, right, top, bottom, near, far) { const te = this.elements; const w = 1.0 / (right - left); @@ -5410,26 +4762,20 @@ class Matrix4 { te[15] = 1; return this; } - equals(matrix) { const te = this.elements; const me = matrix.elements; - for (let i = 0; i < 16; i++) { if (te[i] !== me[i]) return false; } - return true; } - fromArray(array, offset = 0) { for (let i = 0; i < 16; i++) { this.elements[i] = array[i + offset]; } - return this; } - toArray(array = [], offset = 0) { const te = this.elements; array[offset] = te[0]; @@ -5450,27 +4796,17 @@ class Matrix4 { array[offset + 15] = te[15]; return array; } - } - const _v1$5 = /*@__PURE__*/new Vector3(); - const _m1$2 = /*@__PURE__*/new Matrix4(); - const _zero = /*@__PURE__*/new Vector3(0, 0, 0); - const _one = /*@__PURE__*/new Vector3(1, 1, 1); - const _x = /*@__PURE__*/new Vector3(); - const _y = /*@__PURE__*/new Vector3(); - const _z = /*@__PURE__*/new Vector3(); const _matrix$1 = /*@__PURE__*/new Matrix4(); - const _quaternion$3 = /*@__PURE__*/new Quaternion(); - class Euler { constructor(x = 0, y = 0, z = 0, order = Euler.DefaultOrder) { this.isEuler = true; @@ -5479,90 +4815,69 @@ class Euler { this._z = z; this._order = order; } - get x() { return this._x; } - set x(value) { this._x = value; - this._onChangeCallback(); } - get y() { return this._y; } - set y(value) { this._y = value; - this._onChangeCallback(); } - get z() { return this._z; } - set z(value) { this._z = value; - this._onChangeCallback(); } - get order() { return this._order; } - set order(value) { this._order = value; - this._onChangeCallback(); } - set(x, y, z, order = this._order) { this._x = x; this._y = y; this._z = z; this._order = order; - this._onChangeCallback(); - return this; } - clone() { return new this.constructor(this._x, this._y, this._z, this._order); } - copy(euler) { this._x = euler._x; this._y = euler._y; this._z = euler._z; this._order = euler._order; - this._onChangeCallback(); - return this; } - setFromRotationMatrix(m, order = this._order, update = true) { // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + const te = m.elements; const m11 = te[0], - m12 = te[4], - m13 = te[8]; + m12 = te[4], + m13 = te[8]; const m21 = te[1], - m22 = te[5], - m23 = te[9]; + m22 = te[5], + m23 = te[9]; const m31 = te[2], - m32 = te[6], - m33 = te[10]; - + m32 = te[6], + m33 = te[10]; switch (order) { case 'XYZ': this._y = Math.asin(clamp(m13, -1, 1)); - if (Math.abs(m13) < 0.9999999) { this._x = Math.atan2(-m23, m33); this._z = Math.atan2(-m12, m11); @@ -5570,12 +4885,9 @@ class Euler { this._x = Math.atan2(m32, m22); this._z = 0; } - break; - case 'YXZ': this._x = Math.asin(-clamp(m23, -1, 1)); - if (Math.abs(m23) < 0.9999999) { this._y = Math.atan2(m13, m33); this._z = Math.atan2(m21, m22); @@ -5583,12 +4895,9 @@ class Euler { this._y = Math.atan2(-m31, m11); this._z = 0; } - break; - case 'ZXY': this._x = Math.asin(clamp(m32, -1, 1)); - if (Math.abs(m32) < 0.9999999) { this._y = Math.atan2(-m31, m33); this._z = Math.atan2(-m12, m22); @@ -5596,12 +4905,9 @@ class Euler { this._y = 0; this._z = Math.atan2(m21, m11); } - break; - case 'ZYX': this._y = Math.asin(-clamp(m31, -1, 1)); - if (Math.abs(m31) < 0.9999999) { this._x = Math.atan2(m32, m33); this._z = Math.atan2(m21, m11); @@ -5609,12 +4915,9 @@ class Euler { this._x = 0; this._z = Math.atan2(-m12, m22); } - break; - case 'YZX': this._z = Math.asin(clamp(m21, -1, 1)); - if (Math.abs(m21) < 0.9999999) { this._x = Math.atan2(-m23, m22); this._y = Math.atan2(-m31, m11); @@ -5622,12 +4925,9 @@ class Euler { this._x = 0; this._y = Math.atan2(m13, m33); } - break; - case 'XZY': this._z = Math.asin(-clamp(m12, -1, 1)); - if (Math.abs(m12) < 0.9999999) { this._x = Math.atan2(m32, m22); this._y = Math.atan2(m13, m11); @@ -5635,50 +4935,38 @@ class Euler { this._x = Math.atan2(-m23, m33); this._y = 0; } - break; - default: console.warn('THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order); } - this._order = order; if (update === true) this._onChangeCallback(); return this; } - setFromQuaternion(q, order, update) { _matrix$1.makeRotationFromQuaternion(q); - return this.setFromRotationMatrix(_matrix$1, order, update); } - setFromVector3(v, order = this._order) { return this.set(v.x, v.y, v.z, order); } - reorder(newOrder) { // WARNING: this discards revolution information -bhouston - _quaternion$3.setFromEuler(this); + _quaternion$3.setFromEuler(this); return this.setFromQuaternion(_quaternion$3, newOrder); } - equals(euler) { return euler._x === this._x && euler._y === this._y && euler._z === this._z && euler._order === this._order; } - fromArray(array) { this._x = array[0]; this._y = array[1]; this._z = array[2]; if (array[3] !== undefined) this._order = array[3]; - this._onChangeCallback(); - return this; } - toArray(array = [], offset = 0) { array[offset] = this._x; array[offset + 1] = this._y; @@ -5686,28 +4974,24 @@ class Euler { array[offset + 3] = this._order; return array; } - _onChange(callback) { this._onChangeCallback = callback; return this; } - _onChangeCallback() {} - *[Symbol.iterator]() { yield this._x; yield this._y; yield this._z; yield this._order; - } // @deprecated since r138, 02cf0df1cb4575d5842fef9c85bb5a89fe020d53 + } + // @deprecated since r138, 02cf0df1cb4575d5842fef9c85bb5a89fe020d53 toVector3() { console.error('THREE.Euler: .toVector3() has been removed. Use Vector3.setFromEuler() instead'); } - } - Euler.DefaultOrder = 'XYZ'; Euler.RotationOrders = ['XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX']; @@ -5715,70 +4999,49 @@ class Layers { constructor() { this.mask = 1 | 0; } - set(channel) { this.mask = (1 << channel | 0) >>> 0; } - enable(channel) { this.mask |= 1 << channel | 0; } - enableAll() { this.mask = 0xffffffff | 0; } - toggle(channel) { this.mask ^= 1 << channel | 0; } - disable(channel) { this.mask &= ~(1 << channel | 0); } - disableAll() { this.mask = 0; } - test(layers) { return (this.mask & layers.mask) !== 0; } - isEnabled(channel) { return (this.mask & (1 << channel | 0)) !== 0; } - } let _object3DId = 0; - const _v1$4 = /*@__PURE__*/new Vector3(); - const _q1 = /*@__PURE__*/new Quaternion(); - const _m1$1 = /*@__PURE__*/new Matrix4(); - const _target = /*@__PURE__*/new Vector3(); - const _position$3 = /*@__PURE__*/new Vector3(); - const _scale$2 = /*@__PURE__*/new Vector3(); - const _quaternion$2 = /*@__PURE__*/new Quaternion(); - const _xAxis = /*@__PURE__*/new Vector3(1, 0, 0); - const _yAxis = /*@__PURE__*/new Vector3(0, 1, 0); - const _zAxis = /*@__PURE__*/new Vector3(0, 0, 1); - const _addedEvent = { type: 'added' }; const _removedEvent = { type: 'removed' }; - class Object3D extends EventDispatcher { constructor() { super(); @@ -5796,19 +5059,14 @@ class Object3D extends EventDispatcher { const rotation = new Euler(); const quaternion = new Quaternion(); const scale = new Vector3(1, 1, 1); - function onRotationChange() { quaternion.setFromEuler(rotation, false); } - function onQuaternionChange() { rotation.setFromQuaternion(quaternion, undefined, false); } - rotation._onChange(onRotationChange); - quaternion._onChange(onQuaternionChange); - Object.defineProperties(this, { position: { configurable: true, @@ -5841,6 +5099,8 @@ class Object3D extends EventDispatcher { this.matrixWorld = new Matrix4(); this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate; this.matrixWorldNeedsUpdate = false; + this.matrixWorldAutoUpdate = Object3D.DefaultMatrixWorldAutoUpdate; // checked by the renderer + this.layers = new Layers(); this.visible = true; this.castShadow = false; @@ -5850,355 +5110,294 @@ class Object3D extends EventDispatcher { this.animations = []; this.userData = {}; } - onBeforeRender() {} - onAfterRender() {} - applyMatrix4(matrix) { if (this.matrixAutoUpdate) this.updateMatrix(); this.matrix.premultiply(matrix); this.matrix.decompose(this.position, this.quaternion, this.scale); } - applyQuaternion(q) { this.quaternion.premultiply(q); return this; } - setRotationFromAxisAngle(axis, angle) { // assumes axis is normalized + this.quaternion.setFromAxisAngle(axis, angle); } - setRotationFromEuler(euler) { this.quaternion.setFromEuler(euler, true); } - setRotationFromMatrix(m) { // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + this.quaternion.setFromRotationMatrix(m); } - setRotationFromQuaternion(q) { // assumes q is normalized + this.quaternion.copy(q); } - rotateOnAxis(axis, angle) { // rotate object on axis in object space // axis is assumed to be normalized - _q1.setFromAxisAngle(axis, angle); + _q1.setFromAxisAngle(axis, angle); this.quaternion.multiply(_q1); return this; } - rotateOnWorldAxis(axis, angle) { // rotate object on axis in world space // axis is assumed to be normalized // method assumes no rotated parent - _q1.setFromAxisAngle(axis, angle); + _q1.setFromAxisAngle(axis, angle); this.quaternion.premultiply(_q1); return this; } - rotateX(angle) { return this.rotateOnAxis(_xAxis, angle); } - rotateY(angle) { return this.rotateOnAxis(_yAxis, angle); } - rotateZ(angle) { return this.rotateOnAxis(_zAxis, angle); } - translateOnAxis(axis, distance) { // translate object by distance along axis in object space // axis is assumed to be normalized - _v1$4.copy(axis).applyQuaternion(this.quaternion); + _v1$4.copy(axis).applyQuaternion(this.quaternion); this.position.add(_v1$4.multiplyScalar(distance)); return this; } - translateX(distance) { return this.translateOnAxis(_xAxis, distance); } - translateY(distance) { return this.translateOnAxis(_yAxis, distance); } - translateZ(distance) { return this.translateOnAxis(_zAxis, distance); } - localToWorld(vector) { return vector.applyMatrix4(this.matrixWorld); } - worldToLocal(vector) { return vector.applyMatrix4(_m1$1.copy(this.matrixWorld).invert()); } - lookAt(x, y, z) { // This method does not support objects having non-uniformly-scaled parent(s) + if (x.isVector3) { _target.copy(x); } else { _target.set(x, y, z); } - const parent = this.parent; this.updateWorldMatrix(true, false); - _position$3.setFromMatrixPosition(this.matrixWorld); - if (this.isCamera || this.isLight) { _m1$1.lookAt(_position$3, _target, this.up); } else { _m1$1.lookAt(_target, _position$3, this.up); } - this.quaternion.setFromRotationMatrix(_m1$1); - if (parent) { _m1$1.extractRotation(parent.matrixWorld); - _q1.setFromRotationMatrix(_m1$1); - this.quaternion.premultiply(_q1.invert()); } } - add(object) { if (arguments.length > 1) { for (let i = 0; i < arguments.length; i++) { this.add(arguments[i]); } - return this; } - if (object === this) { console.error('THREE.Object3D.add: object can\'t be added as a child of itself.', object); return this; } - if (object && object.isObject3D) { if (object.parent !== null) { object.parent.remove(object); } - object.parent = this; this.children.push(object); object.dispatchEvent(_addedEvent); } else { console.error('THREE.Object3D.add: object not an instance of THREE.Object3D.', object); } - return this; } - remove(object) { if (arguments.length > 1) { for (let i = 0; i < arguments.length; i++) { this.remove(arguments[i]); } - return this; } - const index = this.children.indexOf(object); - if (index !== -1) { object.parent = null; this.children.splice(index, 1); object.dispatchEvent(_removedEvent); } - return this; } - removeFromParent() { const parent = this.parent; - if (parent !== null) { parent.remove(this); } - return this; } - clear() { for (let i = 0; i < this.children.length; i++) { const object = this.children[i]; object.parent = null; object.dispatchEvent(_removedEvent); } - this.children.length = 0; return this; } - attach(object) { // adds object as a child of this, while maintaining the object's world transform + // Note: This method does not support scene graphs having non-uniformly-scaled nodes(s) - this.updateWorldMatrix(true, false); + this.updateWorldMatrix(true, false); _m1$1.copy(this.matrixWorld).invert(); - if (object.parent !== null) { object.parent.updateWorldMatrix(true, false); - _m1$1.multiply(object.parent.matrixWorld); } - object.applyMatrix4(_m1$1); this.add(object); object.updateWorldMatrix(false, true); return this; } - getObjectById(id) { return this.getObjectByProperty('id', id); } - getObjectByName(name) { return this.getObjectByProperty('name', name); } - getObjectByProperty(name, value) { if (this[name] === value) return this; - for (let i = 0, l = this.children.length; i < l; i++) { const child = this.children[i]; const object = child.getObjectByProperty(name, value); - if (object !== undefined) { return object; } } - return undefined; } - getWorldPosition(target) { this.updateWorldMatrix(true, false); return target.setFromMatrixPosition(this.matrixWorld); } - getWorldQuaternion(target) { this.updateWorldMatrix(true, false); this.matrixWorld.decompose(_position$3, target, _scale$2); return target; } - getWorldScale(target) { this.updateWorldMatrix(true, false); this.matrixWorld.decompose(_position$3, _quaternion$2, target); return target; } - getWorldDirection(target) { this.updateWorldMatrix(true, false); const e = this.matrixWorld.elements; return target.set(e[8], e[9], e[10]).normalize(); } - raycast() {} - traverse(callback) { callback(this); const children = this.children; - for (let i = 0, l = children.length; i < l; i++) { children[i].traverse(callback); } } - traverseVisible(callback) { if (this.visible === false) return; callback(this); const children = this.children; - for (let i = 0, l = children.length; i < l; i++) { children[i].traverseVisible(callback); } } - traverseAncestors(callback) { const parent = this.parent; - if (parent !== null) { callback(parent); parent.traverseAncestors(callback); } } - updateMatrix() { this.matrix.compose(this.position, this.quaternion, this.scale); this.matrixWorldNeedsUpdate = true; } - updateMatrixWorld(force) { if (this.matrixAutoUpdate) this.updateMatrix(); - if (this.matrixWorldNeedsUpdate || force) { if (this.parent === null) { this.matrixWorld.copy(this.matrix); } else { this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix); } - this.matrixWorldNeedsUpdate = false; force = true; - } // update children + } + // update children const children = this.children; - for (let i = 0, l = children.length; i < l; i++) { - children[i].updateMatrixWorld(force); + const child = children[i]; + if (child.matrixWorldAutoUpdate === true || force === true) { + child.updateMatrixWorld(force); + } } } - updateWorldMatrix(updateParents, updateChildren) { const parent = this.parent; - - if (updateParents === true && parent !== null) { + if (updateParents === true && parent !== null && parent.matrixWorldAutoUpdate === true) { parent.updateWorldMatrix(true, false); } - if (this.matrixAutoUpdate) this.updateMatrix(); - if (this.parent === null) { this.matrixWorld.copy(this.matrix); } else { this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix); - } // update children + } + // update children if (updateChildren === true) { const children = this.children; - for (let i = 0, l = children.length; i < l; i++) { - children[i].updateWorldMatrix(false, true); + const child = children[i]; + if (child.matrixWorldAutoUpdate === true) { + child.updateWorldMatrix(false, true); + } } } } - toJSON(meta) { // meta is a string when called from JSON.stringify const isRootObject = meta === undefined || typeof meta === 'string'; - const output = {}; // meta is a hash used to collect geometries, materials. + const output = {}; + + // meta is a hash used to collect geometries, materials. // not providing it implies that this is the root object // being serialized. - if (isRootObject) { // initialize meta obj meta = { @@ -6216,8 +5415,9 @@ class Object3D extends EventDispatcher { type: 'Object', generator: 'Object3D.toJSON' }; - } // standard Object3D serialization + } + // standard Object3D serialization const object = {}; object.uuid = this.uuid; @@ -6231,24 +5431,25 @@ class Object3D extends EventDispatcher { 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.matrixAutoUpdate === false) object.matrixAutoUpdate = false; + + // object specific properties if (this.isInstancedMesh) { object.type = 'InstancedMesh'; object.count = this.count; object.instanceMatrix = this.instanceMatrix.toJSON(); if (this.instanceColor !== null) object.instanceColor = this.instanceColor.toJSON(); - } // + } + // function serialize(library, element) { if (library[element.uuid] === undefined) { library[element.uuid] = element.toJSON(meta); } - return element.uuid; } - if (this.isScene) { if (this.background) { if (this.background.isColor) { @@ -6257,17 +5458,14 @@ class Object3D extends EventDispatcher { object.background = this.background.toJSON(meta).uuid; } } - if (this.environment && this.environment.isTexture && this.environment.isRenderTargetTexture !== true) { object.environment = this.environment.toJSON(meta).uuid; } } else if (this.isMesh || this.isLine || this.isPoints) { object.geometry = serialize(meta.geometries, this.geometry); const parameters = this.geometry.parameters; - if (parameters !== undefined && parameters.shapes !== undefined) { const shapes = parameters.shapes; - if (Array.isArray(shapes)) { for (let i = 0, l = shapes.length; i < l; i++) { const shape = shapes[i]; @@ -6278,50 +5476,44 @@ class Object3D extends EventDispatcher { } } } - if (this.isSkinnedMesh) { object.bindMode = this.bindMode; object.bindMatrix = this.bindMatrix.toArray(); - if (this.skeleton !== undefined) { serialize(meta.skeletons, this.skeleton); object.skeleton = this.skeleton.uuid; } } - if (this.material !== undefined) { if (Array.isArray(this.material)) { const uuids = []; - for (let i = 0, l = this.material.length; i < l; i++) { uuids.push(serialize(meta.materials, this.material[i])); } - object.material = uuids; } else { object.material = serialize(meta.materials, this.material); } - } // + } + // if (this.children.length > 0) { object.children = []; - for (let i = 0; i < this.children.length; i++) { object.children.push(this.children[i].toJSON(meta).object); } - } // + } + // if (this.animations.length > 0) { object.animations = []; - for (let i = 0; i < this.animations.length; i++) { const animation = this.animations[i]; object.animations.push(serialize(meta.animations, animation)); } } - if (isRootObject) { const geometries = extractFromCache(meta.geometries); const materials = extractFromCache(meta.materials); @@ -6340,29 +5532,25 @@ class Object3D extends EventDispatcher { if (animations.length > 0) output.animations = animations; if (nodes.length > 0) output.nodes = nodes; } - output.object = object; - return output; // extract data from the cache hash + return output; + + // extract data from the cache hash // remove metadata on each item // and return as array - function extractFromCache(cache) { const values = []; - for (const key in cache) { const data = cache[key]; delete data.metadata; values.push(data); } - return values; } } - clone(recursive) { return new this.constructor().copy(this, recursive); } - copy(source, recursive = true) { this.name = source.name; this.up.copy(source.up); @@ -6374,6 +5562,7 @@ class Object3D extends EventDispatcher { this.matrixWorld.copy(source.matrixWorld); this.matrixAutoUpdate = source.matrixAutoUpdate; this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; + this.matrixWorldAutoUpdate = source.matrixWorldAutoUpdate; this.layers.mask = source.layers.mask; this.visible = source.visible; this.castShadow = source.castShadow; @@ -6381,103 +5570,76 @@ class Object3D extends EventDispatcher { this.frustumCulled = source.frustumCulled; this.renderOrder = source.renderOrder; this.userData = JSON.parse(JSON.stringify(source.userData)); - if (recursive === true) { for (let i = 0; i < source.children.length; i++) { const child = source.children[i]; this.add(child.clone()); } } - return this; } - } - Object3D.DefaultUp = /*@__PURE__*/new Vector3(0, 1, 0); Object3D.DefaultMatrixAutoUpdate = true; +Object3D.DefaultMatrixWorldAutoUpdate = true; const _v0$1 = /*@__PURE__*/new Vector3(); - const _v1$3 = /*@__PURE__*/new Vector3(); - const _v2$2 = /*@__PURE__*/new Vector3(); - const _v3$1 = /*@__PURE__*/new Vector3(); - const _vab = /*@__PURE__*/new Vector3(); - const _vac = /*@__PURE__*/new Vector3(); - const _vbc = /*@__PURE__*/new Vector3(); - const _vap = /*@__PURE__*/new Vector3(); - const _vbp = /*@__PURE__*/new Vector3(); - const _vcp = /*@__PURE__*/new Vector3(); - class Triangle { constructor(a = new Vector3(), b = new Vector3(), c = new Vector3()) { this.a = a; this.b = b; this.c = c; } - static getNormal(a, b, c, target) { target.subVectors(c, b); - _v0$1.subVectors(a, b); - target.cross(_v0$1); const targetLengthSq = target.lengthSq(); - 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 - + } + // static/instance method to calculate barycentric coordinates + // based on: http://www.blackpawn.com/texts/pointinpoly/default.html static getBarycoord(point, a, b, c, target) { _v0$1.subVectors(c, a); - _v1$3.subVectors(b, a); - _v2$2.subVectors(point, a); - const dot00 = _v0$1.dot(_v0$1); - const dot01 = _v0$1.dot(_v1$3); - const dot02 = _v0$1.dot(_v2$2); - const dot11 = _v1$3.dot(_v1$3); - const dot12 = _v1$3.dot(_v2$2); + const denom = dot00 * dot11 - dot01 * dot01; - const denom = dot00 * dot11 - dot01 * dot01; // collinear or singular triangle - + // collinear 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 target.set(-2, -1, -1); } - const invDenom = 1 / denom; const u = (dot11 * dot02 - dot01 * dot12) * invDenom; - const v = (dot00 * dot12 - dot01 * dot02) * invDenom; // barycentric coordinates must always sum to 1 + const v = (dot00 * dot12 - dot01 * dot02) * invDenom; + // barycentric coordinates must always sum to 1 return target.set(1 - u - v, v, u); } - static containsPoint(point, a, b, c) { this.getBarycoord(point, a, b, c, _v3$1); return _v3$1.x >= 0 && _v3$1.y >= 0 && _v3$1.x + _v3$1.y <= 1; } - static getUV(point, p1, p2, p3, uv1, uv2, uv3, target) { this.getBarycoord(point, p1, p2, p3, _v3$1); target.set(0, 0); @@ -6486,177 +5648,137 @@ class Triangle { target.addScaledVector(uv3, _v3$1.z); return target; } - static isFrontFacing(a, b, c, direction) { _v0$1.subVectors(c, b); + _v1$3.subVectors(a, b); - _v1$3.subVectors(a, b); // strictly front facing - - + // strictly front facing return _v0$1.cross(_v1$3).dot(direction) < 0 ? true : false; } - set(a, b, c) { this.a.copy(a); this.b.copy(b); this.c.copy(c); return this; } - setFromPointsAndIndices(points, i0, i1, i2) { this.a.copy(points[i0]); this.b.copy(points[i1]); this.c.copy(points[i2]); return this; } - setFromAttributeAndIndices(attribute, i0, i1, i2) { this.a.fromBufferAttribute(attribute, i0); this.b.fromBufferAttribute(attribute, i1); this.c.fromBufferAttribute(attribute, i2); return this; } - clone() { return new this.constructor().copy(this); } - copy(triangle) { this.a.copy(triangle.a); this.b.copy(triangle.b); this.c.copy(triangle.c); return this; } - getArea() { _v0$1.subVectors(this.c, this.b); - _v1$3.subVectors(this.a, this.b); - return _v0$1.cross(_v1$3).length() * 0.5; } - getMidpoint(target) { return target.addVectors(this.a, this.b).add(this.c).multiplyScalar(1 / 3); } - getNormal(target) { return Triangle.getNormal(this.a, this.b, this.c, target); } - getPlane(target) { return target.setFromCoplanarPoints(this.a, this.b, this.c); } - getBarycoord(point, target) { return Triangle.getBarycoord(point, this.a, this.b, this.c, target); } - getUV(point, uv1, uv2, uv3, target) { return Triangle.getUV(point, this.a, this.b, this.c, uv1, uv2, uv3, target); } - containsPoint(point) { return Triangle.containsPoint(point, this.a, this.b, this.c); } - isFrontFacing(direction) { return Triangle.isFrontFacing(this.a, this.b, this.c, direction); } - intersectsBox(box) { return box.intersectsTriangle(this); } - closestPointToPoint(p, target) { const a = this.a, - b = this.b, - c = this.c; - let v, w; // algorithm thanks to Real-Time Collision Detection by Christer Ericson, + b = this.b, + c = this.c; + let 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); - _vap.subVectors(p, a); - const d1 = _vab.dot(_vap); - const d2 = _vac.dot(_vap); - if (d1 <= 0 && d2 <= 0) { // vertex region of A; barycentric coords (1, 0, 0) return target.copy(a); } - _vbp.subVectors(p, b); - const d3 = _vab.dot(_vbp); - const d4 = _vac.dot(_vbp); - if (d3 >= 0 && d4 <= d3) { // vertex region of B; barycentric coords (0, 1, 0) return target.copy(b); } - const vc = d1 * d4 - d3 * d2; - if (vc <= 0 && d1 >= 0 && d3 <= 0) { - v = d1 / (d1 - d3); // edge region of AB; barycentric coords (1-v, v, 0) - + v = d1 / (d1 - d3); + // edge region of AB; barycentric coords (1-v, v, 0) return target.copy(a).addScaledVector(_vab, v); } - _vcp.subVectors(p, c); - const d5 = _vab.dot(_vcp); - const d6 = _vac.dot(_vcp); - if (d6 >= 0 && d5 <= d6) { // vertex region of C; barycentric coords (0, 0, 1) return target.copy(c); } - const vb = d5 * d2 - d1 * d6; - if (vb <= 0 && d2 >= 0 && d6 <= 0) { - w = d2 / (d2 - d6); // edge region of AC; barycentric coords (1-w, 0, w) - + w = d2 / (d2 - d6); + // edge region of AC; barycentric coords (1-w, 0, w) return target.copy(a).addScaledVector(_vac, w); } - const va = d3 * d6 - d5 * d4; - if (va <= 0 && d4 - d3 >= 0 && d5 - d6 >= 0) { _vbc.subVectors(c, b); - - w = (d4 - d3) / (d4 - d3 + (d5 - d6)); // edge region of BC; barycentric coords (0, 1-w, w) - + w = (d4 - d3) / (d4 - d3 + (d5 - d6)); + // edge region of BC; barycentric coords (0, 1-w, w) return target.copy(b).addScaledVector(_vbc, w); // edge region of BC - } // face region - - - const denom = 1 / (va + vb + vc); // u = va * denom + } + // face region + const denom = 1 / (va + vb + vc); + // u = va * denom v = vb * denom; w = vc * denom; return target.copy(a).addScaledVector(_vab, v).addScaledVector(_vac, w); } - equals(triangle) { return triangle.a.equals(this.a) && triangle.b.equals(this.b) && triangle.c.equals(this.c); } - } let materialId = 0; - class Material extends EventDispatcher { constructor() { super(); @@ -6708,54 +5830,34 @@ class Material extends EventDispatcher { this.version = 0; this._alphaTest = 0; } - get alphaTest() { return this._alphaTest; } - set alphaTest(value) { if (this._alphaTest > 0 !== value > 0) { this.version++; } - this._alphaTest = value; } - onBuild() {} - onBeforeRender() {} - onBeforeCompile() {} - customProgramCacheKey() { return this.onBeforeCompile.toString(); } - setValues(values) { if (values === undefined) return; - for (const key in values) { const newValue = values[key]; - if (newValue === undefined) { console.warn('THREE.Material: \'' + key + '\' parameter is undefined.'); continue; - } // for backward compatibility if shading is set in the constructor - - - if (key === 'shading') { - console.warn('THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.'); - this.flatShading = newValue === FlatShading ? true : false; - continue; } - const currentValue = this[key]; - if (currentValue === undefined) { console.warn('THREE.' + this.type + ': \'' + key + '\' is not a property of this material.'); continue; } - if (currentValue && currentValue.isColor) { currentValue.set(newValue); } else if (currentValue && currentValue.isVector3 && newValue && newValue.isVector3) { @@ -6765,25 +5867,23 @@ class Material extends EventDispatcher { } } } - toJSON(meta) { const isRootObject = meta === undefined || typeof meta === 'string'; - if (isRootObject) { meta = { textures: {}, images: {} }; } - const data = { metadata: { version: 4.5, type: 'Material', generator: 'Material.toJSON' } - }; // standard Material serialization + }; + // standard Material serialization data.uuid = this.uuid; data.type = this.type; if (this.name !== '') data.name = this.name; @@ -6801,88 +5901,71 @@ class Material extends EventDispatcher { 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.iridescence !== undefined) data.iridescence = this.iridescence; if (this.iridescenceIOR !== undefined) data.iridescenceIOR = this.iridescenceIOR; if (this.iridescenceThicknessRange !== undefined) data.iridescenceThicknessRange = this.iridescenceThicknessRange; - if (this.iridescenceMap && this.iridescenceMap.isTexture) { data.iridescenceMap = this.iridescenceMap.toJSON(meta).uuid; } - if (this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture) { data.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON(meta).uuid; } - 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; data.lightMapIntensity = this.lightMapIntensity; } - 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.specularIntensityMap && this.specularIntensityMap.isTexture) data.specularIntensityMap = this.specularIntensityMap.toJSON(meta).uuid; if (this.specularColorMap && this.specularColorMap.isTexture) data.specularColorMap = this.specularColorMap.toJSON(meta).uuid; - if (this.envMap && this.envMap.isTexture) { data.envMap = this.envMap.toJSON(meta).uuid; if (this.combine !== undefined) data.combine = this.combine; } - if (this.envMapIntensity !== undefined) data.envMapIntensity = this.envMapIntensity; if (this.reflectivity !== undefined) data.reflectivity = this.reflectivity; if (this.refractionRatio !== undefined) data.refractionRatio = this.refractionRatio; - if (this.gradientMap && this.gradientMap.isTexture) { data.gradientMap = this.gradientMap.toJSON(meta).uuid; } - if (this.transmission !== undefined) data.transmission = this.transmission; if (this.transmissionMap && this.transmissionMap.isTexture) data.transmissionMap = this.transmissionMap.toJSON(meta).uuid; if (this.thickness !== undefined) data.thickness = this.thickness; if (this.thicknessMap && this.thicknessMap.isTexture) data.thicknessMap = this.thicknessMap.toJSON(meta).uuid; - if (this.attenuationDistance !== undefined) data.attenuationDistance = this.attenuationDistance; + if (this.attenuationDistance !== undefined && this.attenuationDistance !== Infinity) data.attenuationDistance = this.attenuationDistance; if (this.attenuationColor !== undefined) data.attenuationColor = this.attenuationColor.getHex(); if (this.size !== undefined) data.size = this.size; if (this.shadowSide !== null) data.shadowSide = this.shadowSide; @@ -6903,8 +5986,9 @@ class Material extends EventDispatcher { data.stencilFuncMask = this.stencilFuncMask; data.stencilFail = this.stencilFail; data.stencilZFail = this.stencilZFail; - data.stencilZPass = this.stencilZPass; // rotation (SpriteMaterial) + data.stencilZPass = this.stencilZPass; + // rotation (SpriteMaterial) if (this.rotation !== undefined && this.rotation !== 0) data.rotation = this.rotation; if (this.polygonOffset === true) data.polygonOffset = true; if (this.polygonOffsetFactor !== 0) data.polygonOffsetFactor = this.polygonOffsetFactor; @@ -6925,34 +6009,30 @@ class Material extends EventDispatcher { if (this.visible === false) data.visible = false; if (this.toneMapped === false) data.toneMapped = false; if (this.fog === false) data.fog = false; - if (JSON.stringify(this.userData) !== '{}') data.userData = this.userData; // TODO: Copied from Object3D.toJSON + if (JSON.stringify(this.userData) !== '{}') data.userData = this.userData; + + // TODO: Copied from Object3D.toJSON function extractFromCache(cache) { const values = []; - for (const key in cache) { const data = cache[key]; delete data.metadata; values.push(data); } - return values; } - if (isRootObject) { const textures = extractFromCache(meta.textures); const images = extractFromCache(meta.images); if (textures.length > 0) data.textures = textures; if (images.length > 0) data.images = images; } - return data; } - clone() { return new this.constructor().copy(this); } - copy(source) { this.name = source.name; this.blending = source.blending; @@ -6979,16 +6059,13 @@ class Material extends EventDispatcher { this.stencilWrite = source.stencilWrite; const srcPlanes = source.clippingPlanes; let dstPlanes = null; - if (srcPlanes !== null) { const n = srcPlanes.length; dstPlanes = new Array(n); - for (let i = 0; i !== n; ++i) { dstPlanes[i] = srcPlanes[i].clone(); } } - this.clippingPlanes = dstPlanes; this.clipIntersection = source.clipIntersection; this.clipShadows = source.clipShadows; @@ -7007,17 +6084,14 @@ class Material extends EventDispatcher { this.userData = JSON.parse(JSON.stringify(source.userData)); return this; } - dispose() { this.dispatchEvent({ type: 'dispose' }); } - set needsUpdate(value) { if (value === true) this.version++; } - } class MeshBasicMaterial extends Material { @@ -7045,7 +6119,6 @@ class MeshBasicMaterial extends Material { this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.color.copy(source.color); @@ -7067,19 +6140,15 @@ class MeshBasicMaterial extends Material { this.fog = source.fog; return this; } - } const _vector$9 = /*@__PURE__*/new Vector3(); - const _vector2$1 = /*@__PURE__*/new Vector2(); - class BufferAttribute { constructor(array, itemSize, normalized) { if (Array.isArray(array)) { throw new TypeError('THREE.BufferAttribute: array should be a Typed Array.'); } - this.isBufferAttribute = true; this.name = ''; this.array = array; @@ -7093,18 +6162,14 @@ class BufferAttribute { }; this.version = 0; } - onUploadCallback() {} - set needsUpdate(value) { if (value === true) this.version++; } - setUsage(value) { this.usage = value; return this; } - copy(source) { this.name = source.name; this.array = new source.array.constructor(source.array); @@ -7114,235 +6179,146 @@ class BufferAttribute { this.usage = source.usage; return this; } - copyAt(index1, attribute, index2) { index1 *= this.itemSize; index2 *= attribute.itemSize; - for (let i = 0, l = this.itemSize; i < l; i++) { this.array[index1 + i] = attribute.array[index2 + i]; } - return this; } - copyArray(array) { this.array.set(array); return this; } - - copyColorsArray(colors) { - const array = this.array; - let offset = 0; - - for (let i = 0, l = colors.length; i < l; i++) { - let color = colors[i]; - - if (color === undefined) { - console.warn('THREE.BufferAttribute.copyColorsArray(): color is undefined', i); - color = new Color(); - } - - array[offset++] = color.r; - array[offset++] = color.g; - array[offset++] = color.b; - } - - return this; - } - - copyVector2sArray(vectors) { - const array = this.array; - let offset = 0; - - for (let i = 0, l = vectors.length; i < l; i++) { - let vector = vectors[i]; - - if (vector === undefined) { - console.warn('THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i); - vector = new Vector2(); - } - - array[offset++] = vector.x; - array[offset++] = vector.y; - } - - return this; - } - - copyVector3sArray(vectors) { - const array = this.array; - let offset = 0; - - for (let i = 0, l = vectors.length; i < l; i++) { - let vector = vectors[i]; - - 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; - } - - return this; - } - - copyVector4sArray(vectors) { - const array = this.array; - let offset = 0; - - for (let i = 0, l = vectors.length; i < l; i++) { - let vector = vectors[i]; - - if (vector === undefined) { - console.warn('THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i); - vector = new Vector4(); - } - - array[offset++] = vector.x; - array[offset++] = vector.y; - array[offset++] = vector.z; - array[offset++] = vector.w; - } - - return this; - } - applyMatrix3(m) { if (this.itemSize === 2) { for (let i = 0, l = this.count; i < l; i++) { _vector2$1.fromBufferAttribute(this, i); - _vector2$1.applyMatrix3(m); - this.setXY(i, _vector2$1.x, _vector2$1.y); } } else if (this.itemSize === 3) { for (let i = 0, l = this.count; i < l; i++) { _vector$9.fromBufferAttribute(this, i); - _vector$9.applyMatrix3(m); - this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); } } - return this; } - applyMatrix4(m) { for (let i = 0, l = this.count; i < l; i++) { _vector$9.fromBufferAttribute(this, i); - _vector$9.applyMatrix4(m); - this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); } - return this; } - applyNormalMatrix(m) { for (let i = 0, l = this.count; i < l; i++) { _vector$9.fromBufferAttribute(this, i); - _vector$9.applyNormalMatrix(m); - this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); } - return this; } - transformDirection(m) { for (let i = 0, l = this.count; i < l; i++) { _vector$9.fromBufferAttribute(this, i); - _vector$9.transformDirection(m); - this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); } - return this; } - set(value, offset = 0) { + // Matching BufferAttribute constructor, do not normalize the array. this.array.set(value, offset); return this; } - getX(index) { - return this.array[index * this.itemSize]; + let x = this.array[index * this.itemSize]; + if (this.normalized) x = denormalize(x, this.array); + return x; } - setX(index, x) { + if (this.normalized) x = normalize(x, this.array); this.array[index * this.itemSize] = x; return this; } - getY(index) { - return this.array[index * this.itemSize + 1]; + let y = this.array[index * this.itemSize + 1]; + if (this.normalized) y = denormalize(y, this.array); + return y; } - setY(index, y) { + if (this.normalized) y = normalize(y, this.array); this.array[index * this.itemSize + 1] = y; return this; } - getZ(index) { - return this.array[index * this.itemSize + 2]; + let z = this.array[index * this.itemSize + 2]; + if (this.normalized) z = denormalize(z, this.array); + return z; } - setZ(index, z) { + if (this.normalized) z = normalize(z, this.array); this.array[index * this.itemSize + 2] = z; return this; } - getW(index) { - return this.array[index * this.itemSize + 3]; + let w = this.array[index * this.itemSize + 3]; + if (this.normalized) w = denormalize(w, this.array); + return w; } - setW(index, w) { + if (this.normalized) w = normalize(w, this.array); this.array[index * this.itemSize + 3] = w; return this; } - setXY(index, x, y) { index *= this.itemSize; + if (this.normalized) { + x = normalize(x, this.array); + y = normalize(y, this.array); + } this.array[index + 0] = x; this.array[index + 1] = y; return this; } - setXYZ(index, x, y, z) { index *= this.itemSize; + if (this.normalized) { + x = normalize(x, this.array); + y = normalize(y, this.array); + z = normalize(z, this.array); + } this.array[index + 0] = x; this.array[index + 1] = y; this.array[index + 2] = z; return this; } - setXYZW(index, x, y, z, w) { index *= this.itemSize; + if (this.normalized) { + x = normalize(x, this.array); + y = normalize(y, this.array); + z = normalize(z, this.array); + w = normalize(w, this.array); + } this.array[index + 0] = x; this.array[index + 1] = y; this.array[index + 2] = z; this.array[index + 3] = w; return this; } - onUpload(callback) { this.onUploadCallback = callback; return this; } - clone() { return new this.constructor(this.array, this.itemSize).copy(this); } - toJSON() { const data = { itemSize: this.itemSize, @@ -7356,94 +6332,83 @@ class BufferAttribute { return data; } -} // + // @deprecated + copyColorsArray() { + console.error('THREE.BufferAttribute: copyColorsArray() was removed in r144.'); + } + copyVector2sArray() { + console.error('THREE.BufferAttribute: copyVector2sArray() was removed in r144.'); + } + copyVector3sArray() { + console.error('THREE.BufferAttribute: copyVector3sArray() was removed in r144.'); + } + copyVector4sArray() { + console.error('THREE.BufferAttribute: copyVector4sArray() was removed in r144.'); + } +} + +// class Int8BufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Int8Array(array), itemSize, normalized); } - } - class Uint8BufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Uint8Array(array), itemSize, normalized); } - } - class Uint8ClampedBufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Uint8ClampedArray(array), itemSize, normalized); } - } - class Int16BufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Int16Array(array), itemSize, normalized); } - } - class Uint16BufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Uint16Array(array), itemSize, normalized); } - } - class Int32BufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Int32Array(array), itemSize, normalized); } - } - class Uint32BufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Uint32Array(array), itemSize, normalized); } - } - class Float16BufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Uint16Array(array), itemSize, normalized); this.isFloat16BufferAttribute = true; } - } - class Float32BufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Float32Array(array), itemSize, normalized); } - } - class Float64BufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Float64Array(array), itemSize, normalized); } - -} // +} let _id$1 = 0; - const _m1 = /*@__PURE__*/new Matrix4(); - const _obj = /*@__PURE__*/new Object3D(); - const _offset = /*@__PURE__*/new Vector3(); - const _box$1 = /*@__PURE__*/new Box3(); - const _boxMorphTargets = /*@__PURE__*/new Box3(); - const _vector$8 = /*@__PURE__*/new Vector3(); - class BufferGeometry extends EventDispatcher { constructor() { super(); @@ -7467,39 +6432,31 @@ class BufferGeometry extends EventDispatcher { }; this.userData = {}; } - getIndex() { return this.index; } - setIndex(index) { if (Array.isArray(index)) { this.index = new (arrayNeedsUint32(index) ? Uint32BufferAttribute : Uint16BufferAttribute)(index, 1); } else { this.index = index; } - return this; } - getAttribute(name) { return this.attributes[name]; } - setAttribute(name, attribute) { this.attributes[name] = attribute; return this; } - deleteAttribute(name) { delete this.attributes[name]; return this; } - hasAttribute(name) { return this.attributes[name] !== undefined; } - addGroup(start, count, materialIndex = 0) { this.groups.push({ start: start, @@ -7507,155 +6464,123 @@ class BufferGeometry extends EventDispatcher { materialIndex: materialIndex }); } - clearGroups() { this.groups = []; } - setDrawRange(start, count) { this.drawRange.start = start; this.drawRange.count = count; } - applyMatrix4(matrix) { const position = this.attributes.position; - if (position !== undefined) { position.applyMatrix4(matrix); position.needsUpdate = true; } - const normal = this.attributes.normal; - if (normal !== undefined) { const normalMatrix = new Matrix3().getNormalMatrix(matrix); normal.applyNormalMatrix(normalMatrix); normal.needsUpdate = true; } - const tangent = this.attributes.tangent; - if (tangent !== undefined) { tangent.transformDirection(matrix); tangent.needsUpdate = true; } - if (this.boundingBox !== null) { this.computeBoundingBox(); } - if (this.boundingSphere !== null) { this.computeBoundingSphere(); } - return this; } - applyQuaternion(q) { _m1.makeRotationFromQuaternion(q); - this.applyMatrix4(_m1); return this; } - rotateX(angle) { // rotate geometry around world x-axis - _m1.makeRotationX(angle); + _m1.makeRotationX(angle); this.applyMatrix4(_m1); return this; } - rotateY(angle) { // rotate geometry around world y-axis - _m1.makeRotationY(angle); + _m1.makeRotationY(angle); this.applyMatrix4(_m1); return this; } - rotateZ(angle) { // rotate geometry around world z-axis - _m1.makeRotationZ(angle); + _m1.makeRotationZ(angle); this.applyMatrix4(_m1); return this; } - translate(x, y, z) { // translate geometry - _m1.makeTranslation(x, y, z); + _m1.makeTranslation(x, y, z); this.applyMatrix4(_m1); return this; } - scale(x, y, z) { // scale geometry - _m1.makeScale(x, y, z); + _m1.makeScale(x, y, z); this.applyMatrix4(_m1); return this; } - lookAt(vector) { _obj.lookAt(vector); - _obj.updateMatrix(); - this.applyMatrix4(_obj.matrix); return this; } - center() { this.computeBoundingBox(); this.boundingBox.getCenter(_offset).negate(); this.translate(_offset.x, _offset.y, _offset.z); return this; } - setFromPoints(points) { const position = []; - for (let i = 0, l = points.length; i < l; i++) { const point = points[i]; position.push(point.x, point.y, point.z || 0); } - this.setAttribute('position', new Float32BufferAttribute(position, 3)); return this; } - computeBoundingBox() { if (this.boundingBox === null) { this.boundingBox = new Box3(); } - const position = this.attributes.position; const 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; } - if (position !== undefined) { - this.boundingBox.setFromBufferAttribute(position); // process morph attributes if present + this.boundingBox.setFromBufferAttribute(position); + + // process morph attributes if present if (morphAttributesPosition) { for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { const morphAttribute = morphAttributesPosition[i]; - _box$1.setFromBufferAttribute(morphAttribute); - if (this.morphTargetsRelative) { _vector$8.addVectors(this.boundingBox.min, _box$1.min); - this.boundingBox.expandByPoint(_vector$8); - _vector$8.addVectors(this.boundingBox.max, _box$1.max); - this.boundingBox.expandByPoint(_vector$8); } else { this.boundingBox.expandByPoint(_box$1.min); @@ -7666,133 +6591,111 @@ class BufferGeometry extends EventDispatcher { } else { this.boundingBox.makeEmpty(); } - 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() { if (this.boundingSphere === null) { this.boundingSphere = new Sphere(); } - const position = this.attributes.position; const morphAttributesPosition = this.morphAttributes.position; - 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; } - if (position) { // first, find the center of the bounding sphere - const center = this.boundingSphere.center; - _box$1.setFromBufferAttribute(position); // process morph attributes if present + const center = this.boundingSphere.center; + _box$1.setFromBufferAttribute(position); + // process morph attributes if present if (morphAttributesPosition) { for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { const morphAttribute = morphAttributesPosition[i]; - _boxMorphTargets.setFromBufferAttribute(morphAttribute); - if (this.morphTargetsRelative) { _vector$8.addVectors(_box$1.min, _boxMorphTargets.min); - _box$1.expandByPoint(_vector$8); - _vector$8.addVectors(_box$1.max, _boxMorphTargets.max); - _box$1.expandByPoint(_vector$8); } else { _box$1.expandByPoint(_boxMorphTargets.min); - _box$1.expandByPoint(_boxMorphTargets.max); } } } + _box$1.getCenter(center); - _box$1.getCenter(center); // second, try to find a boundingSphere with a radius smaller than the + // second, try to find a boundingSphere with a radius smaller than the // boundingSphere of the boundingBox: sqrt(3) smaller in the best case - let maxRadiusSq = 0; - for (let i = 0, il = position.count; i < il; i++) { _vector$8.fromBufferAttribute(position, i); - maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8)); - } // process morph attributes if present + } + // process morph attributes if present if (morphAttributesPosition) { for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { const morphAttribute = morphAttributesPosition[i]; const morphTargetsRelative = this.morphTargetsRelative; - for (let j = 0, jl = morphAttribute.count; j < jl; j++) { _vector$8.fromBufferAttribute(morphAttribute, j); - if (morphTargetsRelative) { _offset.fromBufferAttribute(position, j); - _vector$8.add(_offset); } - maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8)); } } } - this.boundingSphere.radius = Math.sqrt(maxRadiusSq); - if (isNaN(this.boundingSphere.radius)) { console.error('THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this); } } } - computeTangents() { const index = this.index; - const attributes = this.attributes; // based on http://www.terathon.com/code/tangent.html + const attributes = this.attributes; + + // based on http://www.terathon.com/code/tangent.html // (per vertex tangents) if (index === null || attributes.position === undefined || attributes.normal === undefined || attributes.uv === undefined) { console.error('THREE.BufferGeometry: .computeTangents() failed. Missing required attributes (index, position, normal or uv)'); return; } - const indices = index.array; const positions = attributes.position.array; const normals = attributes.normal.array; const uvs = attributes.uv.array; const nVertices = positions.length / 3; - if (this.hasAttribute('tangent') === false) { this.setAttribute('tangent', new BufferAttribute(new Float32Array(4 * nVertices), 4)); } - const tangents = this.getAttribute('tangent').array; const tan1 = [], - tan2 = []; - + tan2 = []; for (let i = 0; i < nVertices; i++) { tan1[i] = new Vector3(); tan2[i] = new Vector3(); } - const vA = new Vector3(), - vB = new Vector3(), - vC = new Vector3(), - uvA = new Vector2(), - uvB = new Vector2(), - uvC = new Vector2(), - sdir = new Vector3(), - tdir = new Vector3(); - + vB = new Vector3(), + vC = new Vector3(), + uvA = new Vector2(), + uvB = new Vector2(), + uvC = new Vector2(), + sdir = new Vector3(), + tdir = new Vector3(); function handleTriangle(a, b, c) { vA.fromArray(positions, a * 3); vB.fromArray(positions, b * 3); @@ -7804,7 +6707,9 @@ class BufferGeometry extends EventDispatcher { vC.sub(vA); uvB.sub(uvA); uvC.sub(uvA); - const r = 1.0 / (uvB.x * uvC.y - uvC.x * uvB.y); // silently ignore degenerate uv triangles having coincident or colinear vertices + const r = 1.0 / (uvB.x * uvC.y - uvC.x * uvB.y); + + // silently ignore degenerate uv triangles having coincident or colinear vertices if (!isFinite(r)) return; sdir.copy(vB).multiplyScalar(uvC.y).addScaledVector(vC, -uvB.y).multiplyScalar(r); @@ -7816,38 +6721,36 @@ class BufferGeometry extends EventDispatcher { tan2[b].add(tdir); tan2[c].add(tdir); } - let groups = this.groups; - if (groups.length === 0) { groups = [{ start: 0, count: indices.length }]; } - for (let i = 0, il = groups.length; i < il; ++i) { const group = groups[i]; const start = group.start; const count = group.count; - for (let j = start, jl = start + count; j < jl; j += 3) { handleTriangle(indices[j + 0], indices[j + 1], indices[j + 2]); } } - const tmp = new Vector3(), - tmp2 = new Vector3(); + tmp2 = new Vector3(); const n = new Vector3(), - n2 = new Vector3(); - + n2 = new Vector3(); function handleVertex(v) { n.fromArray(normals, v * 3); n2.copy(n); - const t = tan1[v]; // Gram-Schmidt orthogonalize + const t = tan1[v]; + + // Gram-Schmidt orthogonalize tmp.copy(t); - tmp.sub(n.multiplyScalar(n.dot(t))).normalize(); // Calculate handedness + tmp.sub(n.multiplyScalar(n.dot(t))).normalize(); + + // Calculate handedness tmp2.crossVectors(n2, t); const test = tmp2.dot(tan2[v]); @@ -7857,12 +6760,10 @@ class BufferGeometry extends EventDispatcher { tangents[v * 4 + 2] = tmp.z; tangents[v * 4 + 3] = w; } - for (let i = 0, il = groups.length; i < il; ++i) { const group = groups[i]; const start = group.start; const count = group.count; - for (let j = start, jl = start + count; j < jl; j += 3) { handleVertex(indices[j + 0]); handleVertex(indices[j + 1]); @@ -7870,32 +6771,31 @@ class BufferGeometry extends EventDispatcher { } } } - computeVertexNormals() { const index = this.index; const positionAttribute = this.getAttribute('position'); - if (positionAttribute !== undefined) { let normalAttribute = this.getAttribute('normal'); - if (normalAttribute === undefined) { normalAttribute = new BufferAttribute(new Float32Array(positionAttribute.count * 3), 3); this.setAttribute('normal', normalAttribute); } else { // reset existing normals to zero + for (let i = 0, il = normalAttribute.count; i < il; i++) { normalAttribute.setXYZ(i, 0, 0, 0); } } - const pA = new Vector3(), - pB = new Vector3(), - pC = new Vector3(); + pB = new Vector3(), + pC = new Vector3(); const nA = new Vector3(), - nB = new Vector3(), - nC = new Vector3(); + nB = new Vector3(), + nC = new Vector3(); const cb = new Vector3(), - ab = new Vector3(); // indexed elements + ab = new Vector3(); + + // indexed elements if (index) { for (let i = 0, il = index.count; i < il; i += 3) { @@ -7920,6 +6820,7 @@ class BufferGeometry extends EventDispatcher { } } else { // non-indexed elements (unconnected triangle soup) + for (let i = 0, il = positionAttribute.count; i < il; i += 3) { pA.fromBufferAttribute(positionAttribute, i + 0); pB.fromBufferAttribute(positionAttribute, i + 1); @@ -7932,54 +6833,25 @@ class BufferGeometry extends EventDispatcher { normalAttribute.setXYZ(i + 2, cb.x, cb.y, cb.z); } } - this.normalizeNormals(); normalAttribute.needsUpdate = true; } } - merge(geometry, offset) { - if (!(geometry && geometry.isBufferGeometry)) { - console.error('THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry); - return; - } - - if (offset === undefined) { - offset = 0; - console.warn('THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. ' + 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.'); - } - - const attributes = this.attributes; - - for (const key in attributes) { - if (geometry.attributes[key] === undefined) continue; - const attribute1 = attributes[key]; - const attributeArray1 = attribute1.array; - const attribute2 = geometry.attributes[key]; - const attributeArray2 = attribute2.array; - const attributeOffset = attribute2.itemSize * offset; - const length = Math.min(attributeArray2.length, attributeArray1.length - attributeOffset); - - for (let i = 0, j = attributeOffset; i < length; i++, j++) { - attributeArray1[j] = attributeArray2[i]; - } - } + // @deprecated since r144 + merge() { + console.error('THREE.BufferGeometry.merge() has been removed. Use THREE.BufferGeometryUtils.mergeBufferGeometries() instead.'); return this; } - normalizeNormals() { const normals = this.attributes.normal; - for (let i = 0, il = normals.count; i < il; i++) { _vector$8.fromBufferAttribute(normals, i); - _vector$8.normalize(); - normals.setXYZ(i, _vector$8.x, _vector$8.y, _vector$8.z); } } - toNonIndexed() { function convertBufferAttribute(attribute, indices) { const array = attribute.array; @@ -7987,42 +6859,41 @@ class BufferGeometry extends EventDispatcher { const normalized = attribute.normalized; const array2 = new array.constructor(indices.length * itemSize); let index = 0, - index2 = 0; - + index2 = 0; for (let i = 0, l = indices.length; i < l; i++) { if (attribute.isInterleavedBufferAttribute) { index = indices[i] * attribute.data.stride + attribute.offset; } else { index = indices[i] * itemSize; } - for (let j = 0; j < itemSize; j++) { array2[index2++] = array[index++]; } } - return new BufferAttribute(array2, itemSize, normalized); - } // + } + // if (this.index === null) { console.warn('THREE.BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed.'); return this; } - const geometry2 = new BufferGeometry(); const indices = this.index.array; - const attributes = this.attributes; // attributes + const attributes = this.attributes; + + // attributes for (const name in attributes) { const attribute = attributes[name]; const newAttribute = convertBufferAttribute(attribute, indices); geometry2.setAttribute(name, newAttribute); - } // morph attributes + } + // morph attributes const morphAttributes = this.morphAttributes; - for (const name in morphAttributes) { const morphArray = []; const morphAttribute = morphAttributes[name]; // morphAttribute: array of Float32BufferAttributes @@ -8032,22 +6903,19 @@ class BufferGeometry extends EventDispatcher { const newAttribute = convertBufferAttribute(attribute, indices); morphArray.push(newAttribute); } - geometry2.morphAttributes[name] = morphArray; } + geometry2.morphTargetsRelative = this.morphTargetsRelative; - geometry2.morphTargetsRelative = this.morphTargetsRelative; // groups + // groups const groups = this.groups; - for (let i = 0, l = groups.length; i < l; i++) { const group = groups[i]; geometry2.addGroup(group.start, group.count, group.materialIndex); } - return geometry2; } - toJSON() { const data = { metadata: { @@ -8055,118 +6923,109 @@ class BufferGeometry extends EventDispatcher { type: 'BufferGeometry', generator: 'BufferGeometry.toJSON' } - }; // standard BufferGeometry serialization + }; + + // 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; - if (this.parameters !== undefined) { const parameters = this.parameters; - for (const key in parameters) { if (parameters[key] !== undefined) data[key] = parameters[key]; } - return data; - } // for simplicity the code assumes attributes are not shared across geometries, see #15811 + } + // for simplicity the code assumes attributes are not shared across geometries, see #15811 data.data = { attributes: {} }; const index = this.index; - if (index !== null) { data.data.index = { type: index.array.constructor.name, array: Array.prototype.slice.call(index.array) }; } - const attributes = this.attributes; - for (const key in attributes) { const attribute = attributes[key]; data.data.attributes[key] = attribute.toJSON(data.data); } - const morphAttributes = {}; let hasMorphAttributes = false; - for (const key in this.morphAttributes) { const attributeArray = this.morphAttributes[key]; const array = []; - for (let i = 0, il = attributeArray.length; i < il; i++) { const attribute = attributeArray[i]; array.push(attribute.toJSON(data.data)); } - if (array.length > 0) { morphAttributes[key] = array; hasMorphAttributes = true; } } - if (hasMorphAttributes) { data.data.morphAttributes = morphAttributes; data.data.morphTargetsRelative = this.morphTargetsRelative; } - const groups = this.groups; - if (groups.length > 0) { data.data.groups = JSON.parse(JSON.stringify(groups)); } - const boundingSphere = this.boundingSphere; - if (boundingSphere !== null) { data.data.boundingSphere = { center: boundingSphere.center.toArray(), radius: boundingSphere.radius }; } - return data; } - clone() { return new this.constructor().copy(this); } - copy(source) { // reset + this.index = null; this.attributes = {}; this.morphAttributes = {}; this.groups = []; this.boundingBox = null; - this.boundingSphere = null; // used for storing cloned, shared data + this.boundingSphere = null; - const data = {}; // name + // used for storing cloned, shared data - this.name = source.name; // index + const data = {}; - const index = source.index; + // name + + this.name = source.name; + + // index + const index = source.index; if (index !== null) { this.setIndex(index.clone(data)); - } // attributes + } + // attributes const attributes = source.attributes; - for (const name in attributes) { const attribute = attributes[name]; this.setAttribute(name, attribute.clone(data)); - } // morph attributes + } + // morph attributes const morphAttributes = source.morphAttributes; - for (const name in morphAttributes) { const array = []; const morphAttribute = morphAttributes[name]; // morphAttribute: array of Float32BufferAttributes @@ -8174,85 +7033,70 @@ class BufferGeometry extends EventDispatcher { for (let i = 0, l = morphAttribute.length; i < l; i++) { array.push(morphAttribute[i].clone(data)); } - this.morphAttributes[name] = array; } + this.morphTargetsRelative = source.morphTargetsRelative; - this.morphTargetsRelative = source.morphTargetsRelative; // groups + // groups const groups = source.groups; - for (let i = 0, l = groups.length; i < l; i++) { const group = groups[i]; this.addGroup(group.start, group.count, group.materialIndex); - } // bounding box + } + // bounding box const boundingBox = source.boundingBox; - if (boundingBox !== null) { this.boundingBox = boundingBox.clone(); - } // bounding sphere + } + // bounding sphere const boundingSphere = source.boundingSphere; - if (boundingSphere !== null) { this.boundingSphere = boundingSphere.clone(); - } // draw range + } + // draw range this.drawRange.start = source.drawRange.start; - this.drawRange.count = source.drawRange.count; // user data + this.drawRange.count = source.drawRange.count; - this.userData = source.userData; // geometry generator parameters + // user data + + this.userData = source.userData; + + // geometry generator parameters if (source.parameters !== undefined) this.parameters = Object.assign({}, source.parameters); return this; } - dispose() { this.dispatchEvent({ type: 'dispose' }); } - } const _inverseMatrix$2 = /*@__PURE__*/new Matrix4(); - const _ray$2 = /*@__PURE__*/new Ray(); - const _sphere$3 = /*@__PURE__*/new Sphere(); - const _vA$1 = /*@__PURE__*/new Vector3(); - const _vB$1 = /*@__PURE__*/new Vector3(); - const _vC$1 = /*@__PURE__*/new Vector3(); - const _tempA = /*@__PURE__*/new Vector3(); - const _tempB = /*@__PURE__*/new Vector3(); - const _tempC = /*@__PURE__*/new Vector3(); - const _morphA = /*@__PURE__*/new Vector3(); - const _morphB = /*@__PURE__*/new Vector3(); - const _morphC = /*@__PURE__*/new Vector3(); - const _uvA$1 = /*@__PURE__*/new Vector2(); - const _uvB$1 = /*@__PURE__*/new Vector2(); - const _uvC$1 = /*@__PURE__*/new Vector2(); - const _intersectionPoint = /*@__PURE__*/new Vector3(); - const _intersectionPointWorld = /*@__PURE__*/new Vector3(); - class Mesh extends Object3D { constructor(geometry = new BufferGeometry(), material = new MeshBasicMaterial()) { super(); @@ -8262,35 +7106,27 @@ class Mesh extends Object3D { this.material = material; this.updateMorphTargets(); } - copy(source, recursive) { super.copy(source, recursive); - if (source.morphTargetInfluences !== undefined) { this.morphTargetInfluences = source.morphTargetInfluences.slice(); } - if (source.morphTargetDictionary !== undefined) { this.morphTargetDictionary = Object.assign({}, source.morphTargetDictionary); } - this.material = source.material; this.geometry = source.geometry; return this; } - updateMorphTargets() { const geometry = this.geometry; const morphAttributes = geometry.morphAttributes; const keys = Object.keys(morphAttributes); - if (keys.length > 0) { const morphAttribute = morphAttributes[keys[0]]; - if (morphAttribute !== undefined) { this.morphTargetInfluences = []; this.morphTargetDictionary = {}; - for (let m = 0, ml = morphAttribute.length; m < ml; m++) { const name = morphAttribute[m].name || String(m); this.morphTargetInfluences.push(0); @@ -8299,30 +7135,29 @@ class Mesh extends Object3D { } } } - raycast(raycaster, intersects) { const geometry = this.geometry; const material = this.material; const matrixWorld = this.matrixWorld; - if (material === undefined) return; // Checking boundingSphere distance to ray + if (material === undefined) return; - if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); + // Checking boundingSphere distance to ray + if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); _sphere$3.copy(geometry.boundingSphere); - _sphere$3.applyMatrix4(matrixWorld); + if (raycaster.ray.intersectsSphere(_sphere$3) === false) return; - if (raycaster.ray.intersectsSphere(_sphere$3) === false) return; // + // _inverseMatrix$2.copy(matrixWorld).invert(); + _ray$2.copy(raycaster.ray).applyMatrix4(_inverseMatrix$2); - _ray$2.copy(raycaster.ray).applyMatrix4(_inverseMatrix$2); // Check boundingBox before continuing - + // Check boundingBox before continuing if (geometry.boundingBox !== null) { if (_ray$2.intersectsBox(geometry.boundingBox) === false) return; } - let intersection; const index = geometry.index; const position = geometry.attributes.position; @@ -8332,25 +7167,22 @@ class Mesh extends Object3D { const uv2 = geometry.attributes.uv2; const groups = geometry.groups; const drawRange = geometry.drawRange; - if (index !== null) { // indexed buffer geometry + if (Array.isArray(material)) { for (let i = 0, il = groups.length; i < il; i++) { const group = groups[i]; const groupMaterial = material[group.materialIndex]; const start = Math.max(group.start, drawRange.start); const end = Math.min(index.count, Math.min(group.start + group.count, drawRange.start + drawRange.count)); - for (let j = start, jl = end; j < jl; j += 3) { const a = index.getX(j); const b = index.getX(j + 1); const c = index.getX(j + 2); intersection = checkBufferGeometryIntersection(this, groupMaterial, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c); - if (intersection) { intersection.faceIndex = Math.floor(j / 3); // triangle number in indexed buffer semantics - intersection.face.materialIndex = group.materialIndex; intersects.push(intersection); } @@ -8359,38 +7191,33 @@ class Mesh extends Object3D { } else { const start = Math.max(0, drawRange.start); const end = Math.min(index.count, drawRange.start + drawRange.count); - for (let i = start, il = end; i < il; i += 3) { const a = index.getX(i); const b = index.getX(i + 1); const c = index.getX(i + 2); intersection = checkBufferGeometryIntersection(this, material, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c); - if (intersection) { intersection.faceIndex = Math.floor(i / 3); // triangle number in indexed buffer semantics - intersects.push(intersection); } } } } else if (position !== undefined) { // non-indexed buffer geometry + if (Array.isArray(material)) { for (let i = 0, il = groups.length; i < il; i++) { const group = groups[i]; const groupMaterial = material[group.materialIndex]; const start = Math.max(group.start, drawRange.start); const end = Math.min(position.count, Math.min(group.start + group.count, drawRange.start + drawRange.count)); - for (let j = start, jl = end; j < jl; j += 3) { const a = j; const b = j + 1; const c = j + 2; intersection = checkBufferGeometryIntersection(this, groupMaterial, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c); - if (intersection) { intersection.faceIndex = Math.floor(j / 3); // triangle number in non-indexed buffer semantics - intersection.face.materialIndex = group.materialIndex; intersects.push(intersection); } @@ -8399,40 +7226,30 @@ class Mesh extends Object3D { } else { const start = Math.max(0, drawRange.start); const end = Math.min(position.count, drawRange.start + drawRange.count); - for (let i = start, il = end; i < il; i += 3) { const a = i; const b = i + 1; const c = i + 2; intersection = checkBufferGeometryIntersection(this, material, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c); - if (intersection) { intersection.faceIndex = Math.floor(i / 3); // triangle number in non-indexed buffer semantics - intersects.push(intersection); } } } } } - } - function checkIntersection(object, material, raycaster, ray, pA, pB, pC, point) { let intersect; - if (material.side === BackSide) { intersect = ray.intersectTriangle(pC, pB, pA, true, point); } else { intersect = ray.intersectTriangle(pA, pB, pC, material.side !== DoubleSide, point); } - if (intersect === null) return null; - _intersectionPointWorld.copy(point); - _intersectionPointWorld.applyMatrix4(object.matrixWorld); - const distance = raycaster.ray.origin.distanceTo(_intersectionPointWorld); if (distance < raycaster.near || distance > raycaster.far) return null; return { @@ -8441,85 +7258,55 @@ function checkIntersection(object, material, raycaster, ray, pA, pB, pC, point) object: object }; } - function checkBufferGeometryIntersection(object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c) { _vA$1.fromBufferAttribute(position, a); - _vB$1.fromBufferAttribute(position, b); - _vC$1.fromBufferAttribute(position, c); - const morphInfluences = object.morphTargetInfluences; - if (morphPosition && morphInfluences) { _morphA.set(0, 0, 0); - _morphB.set(0, 0, 0); - _morphC.set(0, 0, 0); - for (let i = 0, il = morphPosition.length; i < il; i++) { const influence = morphInfluences[i]; const morphAttribute = morphPosition[i]; if (influence === 0) continue; - _tempA.fromBufferAttribute(morphAttribute, a); - _tempB.fromBufferAttribute(morphAttribute, b); - _tempC.fromBufferAttribute(morphAttribute, c); - if (morphTargetsRelative) { _morphA.addScaledVector(_tempA, influence); - _morphB.addScaledVector(_tempB, influence); - _morphC.addScaledVector(_tempC, influence); } else { _morphA.addScaledVector(_tempA.sub(_vA$1), influence); - _morphB.addScaledVector(_tempB.sub(_vB$1), influence); - _morphC.addScaledVector(_tempC.sub(_vC$1), influence); } } - _vA$1.add(_morphA); - _vB$1.add(_morphB); - _vC$1.add(_morphC); } - if (object.isSkinnedMesh) { object.boneTransform(a, _vA$1); object.boneTransform(b, _vB$1); object.boneTransform(c, _vC$1); } - const intersection = checkIntersection(object, material, raycaster, ray, _vA$1, _vB$1, _vC$1, _intersectionPoint); - if (intersection) { if (uv) { _uvA$1.fromBufferAttribute(uv, a); - _uvB$1.fromBufferAttribute(uv, b); - _uvC$1.fromBufferAttribute(uv, c); - intersection.uv = Triangle.getUV(_intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2()); } - if (uv2) { _uvA$1.fromBufferAttribute(uv2, a); - _uvB$1.fromBufferAttribute(uv2, b); - _uvC$1.fromBufferAttribute(uv2, c); - intersection.uv2 = Triangle.getUV(_intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2()); } - const face = { a: a, b: b, @@ -8530,7 +7317,6 @@ function checkBufferGeometryIntersection(object, material, raycaster, ray, posit Triangle.getNormal(_vA$1, _vB$1, _vC$1, face.normal); intersection.face = face; } - return intersection; } @@ -8546,38 +7332,41 @@ class BoxGeometry extends BufferGeometry { heightSegments: heightSegments, depthSegments: depthSegments }; - const scope = this; // segments + const scope = this; + + // segments widthSegments = Math.floor(widthSegments); heightSegments = Math.floor(heightSegments); - depthSegments = Math.floor(depthSegments); // buffers + depthSegments = Math.floor(depthSegments); + + // buffers const indices = []; const vertices = []; const normals = []; - const uvs = []; // helper variables + const uvs = []; + + // helper variables let numberOfVertices = 0; - let groupStart = 0; // build each side of the box geometry + let groupStart = 0; - buildPlane('z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0); // px + // build each side of the box geometry + buildPlane('z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0); // px buildPlane('z', 'y', 'x', 1, -1, depth, height, -width, depthSegments, heightSegments, 1); // nx - buildPlane('x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2); // py - 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 - buildPlane('x', 'y', 'z', -1, -1, width, height, -depth, widthSegments, heightSegments, 5); // nz + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); - function buildPlane(u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex) { const segmentWidth = width / gridX; const segmentHeight = height / gridY; @@ -8588,78 +7377,98 @@ class BoxGeometry extends BufferGeometry { const gridY1 = gridY + 1; let vertexCounter = 0; let groupCount = 0; - const vector = new Vector3(); // generate vertices, normals and uvs + const vector = new Vector3(); + + // generate vertices, normals and uvs for (let iy = 0; iy < gridY1; iy++) { const y = iy * segmentHeight - heightHalf; - for (let ix = 0; ix < gridX1; ix++) { - const x = ix * segmentWidth - widthHalf; // set values to correct vector component + const x = ix * segmentWidth - widthHalf; + + // set values to correct vector component vector[u] = x * udir; vector[v] = y * vdir; - vector[w] = depthHalf; // now apply vector to vertex buffer + vector[w] = depthHalf; + + // now apply vector to vertex buffer - vertices.push(vector.x, vector.y, vector.z); // set values to correct vector component + 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 + vector[w] = depth > 0 ? 1 : -1; + + // now apply vector to normal buffer - normals.push(vector.x, vector.y, vector.z); // uvs + normals.push(vector.x, vector.y, vector.z); + + // uvs uvs.push(ix / gridX); - uvs.push(1 - iy / gridY); // counters + uvs.push(1 - iy / gridY); + + // counters vertexCounter += 1; } - } // indices + } + + // 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 - for (let iy = 0; iy < gridY; iy++) { for (let ix = 0; ix < gridX; ix++) { const a = numberOfVertices + ix + gridX1 * iy; const b = numberOfVertices + ix + gridX1 * (iy + 1); const c = numberOfVertices + (ix + 1) + gridX1 * (iy + 1); - const d = numberOfVertices + (ix + 1) + gridX1 * iy; // faces + const d = numberOfVertices + (ix + 1) + gridX1 * iy; + + // faces indices.push(a, b, d); - indices.push(b, c, d); // increase counter + indices.push(b, c, d); + + // increase counter groupCount += 6; } - } // add a group to the geometry. this will ensure multi material support + } + + // add a group to the geometry. this will ensure multi material support + + scope.addGroup(groupStart, groupCount, materialIndex); + // calculate new start value for groups - scope.addGroup(groupStart, groupCount, materialIndex); // calculate new start value for groups + groupStart += groupCount; - groupStart += groupCount; // update total number of vertices + // update total number of vertices numberOfVertices += vertexCounter; } } - static fromJSON(data) { return new BoxGeometry(data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments); } - } /** * Uniform Utilities */ + function cloneUniforms(src) { const dst = {}; - for (const u in src) { dst[u] = {}; - for (const p in src[u]) { const property = src[u][p]; - if (property && (property.isColor || property.isMatrix3 || property.isMatrix4 || property.isVector2 || property.isVector3 || property.isVector4 || property.isTexture || property.isQuaternion)) { dst[u][p] = property.clone(); } else if (Array.isArray(property)) { @@ -8669,31 +7478,34 @@ function cloneUniforms(src) { } } } - return dst; } function mergeUniforms(uniforms) { const merged = {}; - for (let u = 0; u < uniforms.length; u++) { const tmp = cloneUniforms(uniforms[u]); - for (const p in tmp) { merged[p] = tmp[p]; } } - return merged; } function cloneUniformsGroups(src) { const dst = []; - for (let u = 0; u < src.length; u++) { dst.push(src[u].clone()); } - return dst; -} // Legacy +} +function getUnlitUniformColorSpace(renderer) { + if (renderer.getRenderTarget() === null) { + // https://github.com/mrdoob/three.js/pull/23937#issuecomment-1111067398 + return renderer.outputEncoding === sRGBEncoding ? SRGBColorSpace : LinearSRGBColorSpace; + } + return LinearSRGBColorSpace; +} + +// Legacy const UniformsUtils = { clone: cloneUniforms, @@ -8718,9 +7530,7 @@ class ShaderMaterial extends Material { this.wireframe = false; this.wireframeLinewidth = 1; this.fog = false; // set to use scene fog - this.lights = false; // set to use scene lights - this.clipping = false; // set to use user-defined clipping planes this.extensions = { @@ -8731,10 +7541,10 @@ class ShaderMaterial extends Material { drawBuffers: false, // set to use draw buffers shaderTextureLOD: false // set to use shader texture LOD + }; - }; // When rendered geometry doesn't include these attributes but the material does, + // 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], @@ -8743,16 +7553,10 @@ class ShaderMaterial extends Material { 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); } } - copy(source) { super.copy(source); this.fragmentShader = source.fragmentShader; @@ -8769,16 +7573,13 @@ class ShaderMaterial extends Material { this.glslVersion = source.glslVersion; return this; } - toJSON(meta) { const data = super.toJSON(meta); data.glslVersion = this.glslVersion; data.uniforms = {}; - for (const name in this.uniforms) { const uniform = this.uniforms[name]; const value = uniform.value; - if (value && value.isTexture) { data.uniforms[name] = { type: 't', @@ -8817,7 +7618,9 @@ class ShaderMaterial extends Material { } else { data.uniforms[name] = { value: value - }; // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far + }; + + // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far } } @@ -8825,15 +7628,12 @@ class ShaderMaterial extends Material { data.vertexShader = this.vertexShader; data.fragmentShader = this.fragmentShader; const extensions = {}; - for (const key in this.extensions) { if (this.extensions[key] === true) extensions[key] = true; } - if (Object.keys(extensions).length > 0) data.extensions = extensions; return data; } - } class Camera extends Object3D { @@ -8845,7 +7645,6 @@ class Camera extends Object3D { this.projectionMatrix = new Matrix4(); this.projectionMatrixInverse = new Matrix4(); } - copy(source, recursive) { super.copy(source, recursive); this.matrixWorldInverse.copy(source.matrixWorldInverse); @@ -8853,27 +7652,22 @@ class Camera extends Object3D { this.projectionMatrixInverse.copy(source.projectionMatrixInverse); return this; } - getWorldDirection(target) { this.updateWorldMatrix(true, false); const e = this.matrixWorld.elements; return target.set(-e[8], -e[9], -e[10]).normalize(); } - updateMatrixWorld(force) { super.updateMatrixWorld(force); this.matrixWorldInverse.copy(this.matrixWorld).invert(); } - updateWorldMatrix(updateParents, updateChildren) { super.updateWorldMatrix(updateParents, updateChildren); this.matrixWorldInverse.copy(this.matrixWorld).invert(); } - clone() { return new this.constructor().copy(this); } - } class PerspectiveCamera extends Camera { @@ -8889,12 +7683,10 @@ class PerspectiveCamera extends Camera { this.aspect = aspect; 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(); } - copy(source, recursive) { super.copy(source, recursive); this.fov = source.fov; @@ -8908,6 +7700,7 @@ class PerspectiveCamera extends Camera { this.filmOffset = source.filmOffset; return this; } + /** * Sets the FOV by focal length in respect to the current .filmGauge. * @@ -8916,37 +7709,32 @@ class PerspectiveCamera extends Camera { * * Values for focal length and film gauge must have the same unit. */ - - setFocalLength(focalLength) { /** see {@link http://www.bobatkins.com/photography/technical/field_of_view.html} */ const vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; this.fov = RAD2DEG * 2 * Math.atan(vExtentSlope); this.updateProjectionMatrix(); } + /** * Calculates the focal length from the current .fov and .filmGauge. */ - - getFocalLength() { const vExtentSlope = Math.tan(DEG2RAD * 0.5 * this.fov); return 0.5 * this.getFilmHeight() / vExtentSlope; } - getEffectiveFOV() { return RAD2DEG * 2 * Math.atan(Math.tan(DEG2RAD * 0.5 * this.fov) / this.zoom); } - getFilmWidth() { // film not completely covered in portrait format (aspect < 1) return this.filmGauge * Math.min(this.aspect, 1); } - getFilmHeight() { // film not completely covered in landscape format (aspect > 1) return this.filmGauge / Math.max(this.aspect, 1); } + /** * Sets an offset in a larger frustum. This is useful for multi-window or * multi-monitor/multi-machine setups. @@ -8982,11 +7770,8 @@ class PerspectiveCamera extends Camera { * * Note there is no reason monitors have to be the same size or in a grid. */ - - setViewOffset(fullWidth, fullHeight, x, y, width, height) { this.aspect = fullWidth / fullHeight; - if (this.view === null) { this.view = { enabled: true, @@ -8998,7 +7783,6 @@ class PerspectiveCamera extends Camera { height: 1 }; } - this.view.enabled = true; this.view.fullWidth = fullWidth; this.view.fullHeight = fullHeight; @@ -9008,15 +7792,12 @@ class PerspectiveCamera extends Camera { this.view.height = height; this.updateProjectionMatrix(); } - clearViewOffset() { if (this.view !== null) { this.view.enabled = false; } - this.updateProjectionMatrix(); } - updateProjectionMatrix() { const near = this.near; let top = near * Math.tan(DEG2RAD * 0.5 * this.fov) / this.zoom; @@ -9024,22 +7805,19 @@ class PerspectiveCamera extends Camera { let width = this.aspect * height; let left = -0.5 * width; const view = this.view; - if (this.view !== null && this.view.enabled) { const fullWidth = view.fullWidth, - fullHeight = view.fullHeight; + fullHeight = view.fullHeight; left += view.offsetX * width / fullWidth; top -= view.offsetY * height / fullHeight; width *= view.width / fullWidth; height *= view.height / fullHeight; } - const 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.copy(this.projectionMatrix).invert(); } - toJSON(meta) { const data = super.toJSON(meta); data.object.fov = this.fov; @@ -9053,55 +7831,46 @@ class PerspectiveCamera extends Camera { data.object.filmOffset = this.filmOffset; return data; } - } -const fov = 90, - aspect = 1; - +const fov = -90; // negative fov is not an error +const aspect = 1; class CubeCamera extends Object3D { constructor(near, far, renderTarget) { super(); 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; const cameraPX = new PerspectiveCamera(fov, aspect, near, far); cameraPX.layers = this.layers; - cameraPX.up.set(0, -1, 0); - cameraPX.lookAt(new Vector3(1, 0, 0)); + cameraPX.up.set(0, 1, 0); + cameraPX.lookAt(1, 0, 0); this.add(cameraPX); const cameraNX = new PerspectiveCamera(fov, aspect, near, far); cameraNX.layers = this.layers; - cameraNX.up.set(0, -1, 0); - cameraNX.lookAt(new Vector3(-1, 0, 0)); + cameraNX.up.set(0, 1, 0); + cameraNX.lookAt(-1, 0, 0); this.add(cameraNX); const cameraPY = new PerspectiveCamera(fov, aspect, near, far); cameraPY.layers = this.layers; - cameraPY.up.set(0, 0, 1); - cameraPY.lookAt(new Vector3(0, 1, 0)); + cameraPY.up.set(0, 0, -1); + cameraPY.lookAt(0, 1, 0); this.add(cameraPY); const cameraNY = new PerspectiveCamera(fov, aspect, near, far); cameraNY.layers = this.layers; - cameraNY.up.set(0, 0, -1); - cameraNY.lookAt(new Vector3(0, -1, 0)); + cameraNY.up.set(0, 0, 1); + cameraNY.lookAt(0, -1, 0); this.add(cameraNY); const cameraPZ = new PerspectiveCamera(fov, aspect, near, far); cameraPZ.layers = this.layers; - cameraPZ.up.set(0, -1, 0); - cameraPZ.lookAt(new Vector3(0, 0, 1)); + cameraPZ.up.set(0, 1, 0); + cameraPZ.lookAt(0, 0, 1); this.add(cameraPZ); const cameraNZ = new PerspectiveCamera(fov, aspect, near, far); cameraNZ.layers = this.layers; - cameraNZ.up.set(0, -1, 0); - cameraNZ.lookAt(new Vector3(0, 0, -1)); + cameraNZ.up.set(0, 1, 0); + cameraNZ.lookAt(0, 0, -1); this.add(cameraNZ); } - update(renderer, scene) { if (this.parent === null) this.updateMatrixWorld(); const renderTarget = this.renderTarget; @@ -9131,7 +7900,6 @@ class CubeCamera extends Object3D { renderer.xr.enabled = currentXrEnabled; renderTarget.texture.needsPMREMUpdate = true; } - } class CubeTexture extends Texture { @@ -9142,19 +7910,16 @@ class CubeTexture extends Texture { this.isCubeTexture = true; this.flipY = false; } - get images() { return this.image; } - set images(value) { this.image = value; } - } class WebGLCubeRenderTarget extends WebGLRenderTarget { - constructor(size, options = {}) { + constructor(size = 1, options = {}) { super(size, size, options); this.isWebGLCubeRenderTarget = true; const image = { @@ -9163,9 +7928,12 @@ class WebGLCubeRenderTarget extends WebGLRenderTarget { depth: 1 }; const images = [image, image, image, image, image, image]; - this.texture = new CubeTexture(images, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding); // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js) + this.texture = new CubeTexture(images, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding); + + // 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 isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture // as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures). @@ -9174,7 +7942,6 @@ class WebGLCubeRenderTarget extends WebGLRenderTarget { this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false; this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter; } - fromEquirectangularTexture(renderer, texture) { this.texture.type = texture.type; this.texture.encoding = texture.encoding; @@ -9187,9 +7954,7 @@ class WebGLCubeRenderTarget extends WebGLRenderTarget { value: null } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec3 vWorldDirection; @@ -9208,9 +7973,7 @@ class WebGLCubeRenderTarget extends WebGLRenderTarget { } `, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tEquirect; @@ -9240,8 +8003,9 @@ class WebGLCubeRenderTarget extends WebGLRenderTarget { }); material.uniforms.tEquirect.value = texture; const mesh = new Mesh(geometry, material); - const currentMinFilter = texture.minFilter; // Avoid blurred poles + const currentMinFilter = texture.minFilter; + // Avoid blurred poles if (texture.minFilter === LinearMipmapLinearFilter) texture.minFilter = LinearFilter; const camera = new CubeCamera(1, 10, this); camera.update(renderer, mesh); @@ -9250,167 +8014,137 @@ class WebGLCubeRenderTarget extends WebGLRenderTarget { mesh.material.dispose(); return this; } - clear(renderer, color, depth, stencil) { const currentRenderTarget = renderer.getRenderTarget(); - for (let i = 0; i < 6; i++) { renderer.setRenderTarget(this, i); renderer.clear(color, depth, stencil); } - renderer.setRenderTarget(currentRenderTarget); } - } const _vector1 = /*@__PURE__*/new Vector3(); - const _vector2 = /*@__PURE__*/new Vector3(); - const _normalMatrix = /*@__PURE__*/new Matrix3(); - class Plane { constructor(normal = new Vector3(1, 0, 0), constant = 0) { - this.isPlane = true; // normal is assumed to be normalized + this.isPlane = true; + + // normal is assumed to be normalized this.normal = normal; this.constant = constant; } - set(normal, constant) { this.normal.copy(normal); this.constant = constant; return this; } - setComponents(x, y, z, w) { this.normal.set(x, y, z); this.constant = w; return this; } - setFromNormalAndCoplanarPoint(normal, point) { this.normal.copy(normal); this.constant = -point.dot(this.normal); return this; } - setFromCoplanarPoints(a, b, c) { - const 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)? + const 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)? this.setFromNormalAndCoplanarPoint(normal, a); return this; } - copy(plane) { this.normal.copy(plane.normal); this.constant = plane.constant; return this; } - normalize() { // Note: will lead to a divide by zero if the plane is invalid. + const inverseNormalLength = 1.0 / this.normal.length(); this.normal.multiplyScalar(inverseNormalLength); this.constant *= inverseNormalLength; return this; } - negate() { this.constant *= -1; this.normal.negate(); return this; } - distanceToPoint(point) { return this.normal.dot(point) + this.constant; } - distanceToSphere(sphere) { return this.distanceToPoint(sphere.center) - sphere.radius; } - projectPoint(point, target) { return target.copy(this.normal).multiplyScalar(-this.distanceToPoint(point)).add(point); } - intersectLine(line, target) { const direction = line.delta(_vector1); const denominator = this.normal.dot(direction); - 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. - + } + // Unsure if this is the correct method to handle this case. return null; } - const t = -(line.start.dot(this.normal) + this.constant) / denominator; - if (t < 0 || t > 1) { return null; } - return target.copy(direction).multiplyScalar(t).add(line.start); } - intersectsLine(line) { // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. + const startSign = this.distanceToPoint(line.start); const endSign = this.distanceToPoint(line.end); return startSign < 0 && endSign > 0 || endSign < 0 && startSign > 0; } - intersectsBox(box) { return box.intersectsPlane(this); } - intersectsSphere(sphere) { return sphere.intersectsPlane(this); } - coplanarPoint(target) { return target.copy(this.normal).multiplyScalar(-this.constant); } - applyMatrix4(matrix, optionalNormalMatrix) { const normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix(matrix); - const referencePoint = this.coplanarPoint(_vector1).applyMatrix4(matrix); const normal = this.normal.applyMatrix3(normalMatrix).normalize(); this.constant = -referencePoint.dot(normal); return this; } - translate(offset) { this.constant -= offset.dot(this.normal); return this; } - equals(plane) { return plane.normal.equals(this.normal) && plane.constant === this.constant; } - clone() { return new this.constructor().copy(this); } - } const _sphere$2 = /*@__PURE__*/new Sphere(); - const _vector$7 = /*@__PURE__*/new Vector3(); - class Frustum { constructor(p0 = new Plane(), p1 = new Plane(), p2 = new Plane(), p3 = new Plane(), p4 = new Plane(), p5 = new Plane()) { this.planes = [p0, p1, p2, p3, p4, p5]; } - set(p0, p1, p2, p3, p4, p5) { const planes = this.planes; planes[0].copy(p0); @@ -9421,36 +8155,32 @@ class Frustum { planes[5].copy(p5); return this; } - copy(frustum) { const planes = this.planes; - for (let i = 0; i < 6; i++) { planes[i].copy(frustum.planes[i]); } - return this; } - setFromProjectionMatrix(m) { const planes = this.planes; const me = m.elements; const me0 = me[0], - me1 = me[1], - me2 = me[2], - me3 = me[3]; + me1 = me[1], + me2 = me[2], + me3 = me[3]; const me4 = me[4], - me5 = me[5], - me6 = me[6], - me7 = me[7]; + me5 = me[5], + me6 = me[6], + me7 = me[7]; const me8 = me[8], - me9 = me[9], - me10 = me[10], - me11 = me[11]; + me9 = me[9], + me10 = me[10], + me11 = me[11]; const me12 = me[12], - me13 = me[13], - me14 = me[14], - me15 = me[15]; + 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(); @@ -9459,76 +8189,58 @@ class Frustum { planes[5].setComponents(me3 + me2, me7 + me6, me11 + me10, me15 + me14).normalize(); return this; } - intersectsObject(object) { const geometry = object.geometry; if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); - _sphere$2.copy(geometry.boundingSphere).applyMatrix4(object.matrixWorld); - return this.intersectsSphere(_sphere$2); } - intersectsSprite(sprite) { _sphere$2.center.set(0, 0, 0); - _sphere$2.radius = 0.7071067811865476; - _sphere$2.applyMatrix4(sprite.matrixWorld); - return this.intersectsSphere(_sphere$2); } - intersectsSphere(sphere) { const planes = this.planes; const center = sphere.center; const negRadius = -sphere.radius; - for (let i = 0; i < 6; i++) { const distance = planes[i].distanceToPoint(center); - if (distance < negRadius) { return false; } } - return true; } - intersectsBox(box) { const planes = this.planes; - for (let i = 0; i < 6; i++) { - const plane = planes[i]; // corner at max distance + const plane = planes[i]; + + // corner at max distance _vector$7.x = plane.normal.x > 0 ? box.max.x : box.min.x; _vector$7.y = plane.normal.y > 0 ? box.max.y : box.min.y; _vector$7.z = plane.normal.z > 0 ? box.max.z : box.min.z; - if (plane.distanceToPoint(_vector$7) < 0) { return false; } } - return true; } - containsPoint(point) { const planes = this.planes; - for (let i = 0; i < 6; i++) { if (planes[i].distanceToPoint(point) < 0) { return false; } } - return true; } - clone() { return new this.constructor().copy(this); } - } function WebGLAnimation() { @@ -9536,12 +8248,10 @@ function WebGLAnimation() { let isAnimating = false; let animationLoop = null; let requestId = null; - function onAnimationFrame(time, frame) { animationLoop(time, frame); requestId = context.requestAnimationFrame(onAnimationFrame); } - return { start: function () { if (isAnimating === true) return; @@ -9565,7 +8275,6 @@ function WebGLAnimation() { function WebGLAttributes(gl, capabilities) { const isWebGL2 = capabilities.isWebGL2; const buffers = new WeakMap(); - function createBuffer(attribute, bufferType) { const array = attribute.array; const usage = attribute.usage; @@ -9574,7 +8283,6 @@ function WebGLAttributes(gl, capabilities) { gl.bufferData(bufferType, array, usage); attribute.onUploadCallback(); let type; - if (array instanceof Float32Array) { type = gl.FLOAT; } else if (array instanceof Uint16Array) { @@ -9602,7 +8310,6 @@ function WebGLAttributes(gl, capabilities) { } else { throw new Error('THREE.WebGLAttributes: Unsupported buffer data format: ' + array); } - return { buffer: buffer, type: type, @@ -9610,14 +8317,13 @@ function WebGLAttributes(gl, capabilities) { version: attribute.version }; } - function updateBuffer(buffer, attribute, bufferType) { const array = attribute.array; const updateRange = attribute.updateRange; gl.bindBuffer(bufferType, buffer); - if (updateRange.count === -1) { // Not using update ranges + gl.bufferSubData(bufferType, 0, array); } else { if (isWebGL2) { @@ -9625,31 +8331,29 @@ function WebGLAttributes(gl, capabilities) { } else { gl.bufferSubData(bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, array.subarray(updateRange.offset, updateRange.offset + updateRange.count)); } - updateRange.count = -1; // reset range } - } // + attribute.onUploadCallback(); + } + + // function get(attribute) { if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; return buffers.get(attribute); } - function remove(attribute) { if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; const data = buffers.get(attribute); - if (data) { gl.deleteBuffer(data.buffer); buffers.delete(attribute); } } - function update(attribute, bufferType) { if (attribute.isGLBufferAttribute) { const cached = buffers.get(attribute); - if (!cached || cached.version < attribute.version) { buffers.set(attribute, { buffer: attribute.buffer, @@ -9658,13 +8362,10 @@ function WebGLAttributes(gl, capabilities) { version: attribute.version }); } - return; } - if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; const data = buffers.get(attribute); - if (data === undefined) { buffers.set(attribute, createBuffer(attribute, bufferType)); } else if (data.version < attribute.version) { @@ -9672,7 +8373,6 @@ function WebGLAttributes(gl, capabilities) { data.version = attribute.version; } } - return { get: get, remove: remove, @@ -9697,16 +8397,16 @@ class PlaneGeometry extends BufferGeometry { const gridX1 = gridX + 1; const gridY1 = gridY + 1; const segment_width = width / gridX; - const segment_height = height / gridY; // + const segment_height = height / gridY; + + // const indices = []; const vertices = []; const normals = []; const uvs = []; - for (let iy = 0; iy < gridY1; iy++) { const y = iy * segment_height - height_half; - for (let ix = 0; ix < gridX1; ix++) { const x = ix * segment_width - width_half; vertices.push(x, -y, 0); @@ -9715,7 +8415,6 @@ class PlaneGeometry extends BufferGeometry { uvs.push(1 - iy / gridY); } } - for (let iy = 0; iy < gridY; iy++) { for (let ix = 0; ix < gridX; ix++) { const a = ix + gridX1 * iy; @@ -9726,17 +8425,14 @@ class PlaneGeometry extends BufferGeometry { indices.push(b, c, d); } } - this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); } - static fromJSON(data) { return new PlaneGeometry(data.width, data.height, data.widthSegments, data.heightSegments); } - } var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif"; @@ -9779,7 +8475,7 @@ var color_vertex = "#if defined( USE_COLOR_ALPHA )\n\tvColor = vec4( 1.0 );\n#el 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; }\nvec3 pow2( const in vec3 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 max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\nfloat average( const in vec3 v ) { return dot( v, vec3( 0.3333333 ) ); }\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 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 USE_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}\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 luminance( const in vec3 rgb ) {\n\tconst vec3 weights = vec3( 0.2126729, 0.7151522, 0.0721750 );\n\treturn dot( weights, 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}"; -var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_minMipLevel 4.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\tvec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\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\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\n\t\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n\t\tuv.x *= CUBEUV_TEXEL_WIDTH;\n\t\tuv.y *= CUBEUV_TEXEL_HEIGHT;\n\t\t#ifdef texture2DGradEXT\n\t\t\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n\t\t#else\n\t\t\treturn texture2D( envMap, uv ).rgb;\n\t\t#endif\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_MAX_MIP );\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 cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_minMipLevel 4.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\tvec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\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\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\n\t\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n\t\tuv.x *= CUBEUV_TEXEL_WIDTH;\n\t\tuv.y *= CUBEUV_TEXEL_HEIGHT;\n\t\t#ifdef texture2DGradEXT\n\t\t\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n\t\t#else\n\t\t\treturn texture2D( envMap, uv ).rgb;\n\t\t#endif\n\t}\n\t#define cubeUV_r0 1.0\n\t#define cubeUV_v0 0.339\n\t#define cubeUV_m0 - 2.0\n\t#define cubeUV_r1 0.8\n\t#define cubeUV_v1 0.276\n\t#define cubeUV_m1 - 1.0\n\t#define cubeUV_r4 0.4\n\t#define cubeUV_v4 0.046\n\t#define cubeUV_m4 2.0\n\t#define cubeUV_r5 0.305\n\t#define cubeUV_v5 0.016\n\t#define cubeUV_m5 3.0\n\t#define cubeUV_r6 0.21\n\t#define cubeUV_v6 0.0038\n\t#define cubeUV_m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= cubeUV_r1 ) {\n\t\t\tmip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0;\n\t\t} else if ( roughness >= cubeUV_r4 ) {\n\t\t\tmip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1;\n\t\t} else if ( roughness >= cubeUV_r5 ) {\n\t\t\tmip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4;\n\t\t} else if ( roughness >= cubeUV_r6 ) {\n\t\t\tmip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_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 ), cubeUV_m0, CUBEUV_MAX_MIP );\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"; @@ -9795,13 +8491,13 @@ var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );"; var encodings_pars_fragment = "vec4 LinearToLinear( in vec4 value ) {\n\treturn value;\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}"; -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#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_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#else\n\t\tvec4 envColor = vec4( 0.0 );\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\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"; -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"; +var envmap_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\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"; -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"; +var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\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"; 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"; @@ -9813,13 +8509,15 @@ var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float vFogDepth;\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"; -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 vec3( texture2D( gradientMap, coord ).r );\n\t#else\n\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t#endif\n}"; +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 vec3( texture2D( gradientMap, coord ).r );\n\t#else\n\t\tvec2 fw = fwidth( coord ) * 0.5;\n\t\treturn mix( vec3( 0.7 ), vec3( 1.0 ), smoothstep( 0.7 - fw.x, 0.7 + fw.x, coord.x ) );\n\t#endif\n}"; var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\treflectedLight.indirectDiffuse += lightMapIrradiance;\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.normal );\n#ifdef DOUBLE_SIDED\n\tvIndirectBack += getAmbientLightIrradiance( ambientLightColor );\n\tvIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry.normal );\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\tgetPointLightInfo( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = 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\tgetSpotLightInfo( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = 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\tgetDirectionalLightInfo( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = 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.normal );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry.normal );\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif"; +var lights_lambert_fragment = "LambertMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularStrength = specularStrength;"; + +var lights_lambert_pars_fragment = "varying vec3 vViewPosition;\nstruct LambertMaterial {\n\tvec3 diffuseColor;\n\tfloat specularStrength;\n};\nvoid RE_Direct_Lambert( const in IncidentLight directLight, const in GeometricContext geometry, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in GeometricContext geometry, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Lambert\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Lambert"; 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 vec3 normal ) {\n\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\treturn irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\t#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\tif ( cutoffDistance > 0.0 ) {\n\t\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\t}\n\t\treturn distanceFalloff;\n\t#else\n\t\tif ( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\t\treturn pow( saturate( - lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t\t}\n\t\treturn 1.0;\n\t#endif\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n\treturn smoothstep( coneCosine, penumbraCosine, angleCosine );\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 getDirectionalLightInfo( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tlight.color = directionalLight.color;\n\t\tlight.direction = directionalLight.direction;\n\t\tlight.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 getPointLightInfo( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tlight.color = pointLight.color;\n\t\tlight.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n\t\tlight.visible = ( light.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 getSpotLightInfo( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat angleCos = dot( light.direction, spotLight.direction );\n\t\tfloat spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\tif ( spotAttenuation > 0.0 ) {\n\t\t\tfloat lightDistance = length( lVector );\n\t\t\tlight.color = spotLight.color * spotAttenuation;\n\t\t\tlight.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t\t} else {\n\t\t\tlight.color = vec3( 0.0 );\n\t\t\tlight.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 vec3 normal ) {\n\t\tfloat dotNL = dot( normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\treturn irradiance;\n\t}\n#endif"; @@ -9827,17 +8525,17 @@ var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP )\n\tvec3 getIBLIrr var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;"; -var lights_toon_pars_fragment = "varying vec3 vViewPosition;\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\treflectedLight.directDiffuse += irradiance * BRDF_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_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)"; +var lights_toon_pars_fragment = "varying vec3 vViewPosition;\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\treflectedLight.directDiffuse += irradiance * BRDF_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_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon"; 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;\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\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, 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_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)"; +var lights_phong_pars_fragment = "varying vec3 vViewPosition;\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\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, 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_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong"; -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.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\t#ifdef SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULARINTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vUv ).a;\n\t\t#endif\n\t\t#ifdef USE_SPECULARCOLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vUv ).rgb;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( ior - 1.0 ) / ( ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\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_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vUv ).a;\n\t#endif\n#endif"; +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.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\tmaterial.ior = ior;\n\t#ifdef SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULARINTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vUv ).a;\n\t\t#endif\n\t\t#ifdef USE_SPECULARCOLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vUv ).rgb;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\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_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vUv ).a;\n\t#endif\n#endif"; -var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat roughness;\n\tvec3 specularColor;\n\tfloat specularF90;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\tfloat iridescence;\n\t\tfloat iridescenceIOR;\n\t\tfloat iridescenceThickness;\n\t\tvec3 iridescenceFresnel;\n\t\tvec3 iridescenceF0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n};\nvec3 clearcoatSpecular = vec3( 0.0 );\nvec3 sheenSpecular = vec3( 0.0 );\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\n\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\n\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\n\treturn saturate( DG * RECIPROCAL_PI );\n}\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\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\tvec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\n\treturn fab;\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\treturn specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#endif\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\t#ifdef USE_IRIDESCENCE\n\t\tvec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n\t#else\n\t\tvec3 Fr = specularColor;\n\t#endif\n\tvec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\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.roughness;\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#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecular += ccIrradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.clearcoatNormal, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness );\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\treflectedLight.directSpecular += irradiance * BRDF_GGX_Iridescence( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness );\n\t#else\n\t\treflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.roughness );\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_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_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 USE_CLEARCOAT\n\t\tclearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometry.clearcoatNormal, geometry.viewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometry.normal, geometry.viewDir, material.sheenRoughness );\n\t#endif\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t#ifdef USE_IRIDESCENCE\n\t\tcomputeMultiscatteringIridescence( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );\n\t#else\n\t\tcomputeMultiscattering( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n\t#endif\n\tvec3 totalScattering = singleScattering + multiScattering;\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) );\n\treflectedLight.indirectSpecular += 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}"; +var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat roughness;\n\tvec3 specularColor;\n\tfloat specularF90;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\tfloat iridescence;\n\t\tfloat iridescenceIOR;\n\t\tfloat iridescenceThickness;\n\t\tvec3 iridescenceFresnel;\n\t\tvec3 iridescenceF0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n\t#ifdef IOR\n\t\tfloat ior;\n\t#endif\n\t#ifdef USE_TRANSMISSION\n\t\tfloat transmission;\n\t\tfloat transmissionAlpha;\n\t\tfloat thickness;\n\t\tfloat attenuationDistance;\n\t\tvec3 attenuationColor;\n\t#endif\n};\nvec3 clearcoatSpecular = vec3( 0.0 );\nvec3 sheenSpecular = vec3( 0.0 );\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\n\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\n\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\n\treturn saturate( DG * RECIPROCAL_PI );\n}\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\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\tvec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\n\treturn fab;\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\treturn specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#endif\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\t#ifdef USE_IRIDESCENCE\n\t\tvec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n\t#else\n\t\tvec3 Fr = specularColor;\n\t#endif\n\tvec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\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.roughness;\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#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecular += ccIrradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.clearcoatNormal, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness );\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\treflectedLight.directSpecular += irradiance * BRDF_GGX_Iridescence( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness );\n\t#else\n\t\treflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.roughness );\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_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_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 USE_CLEARCOAT\n\t\tclearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometry.clearcoatNormal, geometry.viewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometry.normal, geometry.viewDir, material.sheenRoughness );\n\t#endif\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t#ifdef USE_IRIDESCENCE\n\t\tcomputeMultiscatteringIridescence( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );\n\t#else\n\t\tcomputeMultiscattering( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n\t#endif\n\tvec3 totalScattering = singleScattering + multiScattering;\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) );\n\treflectedLight.indirectSpecular += 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}"; -var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef USE_CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n\tfloat dotNVi = saturate( dot( normal, geometry.viewDir ) );\n\tif ( material.iridescenceThickness == 0.0 ) {\n\t\tmaterial.iridescence = 0.0;\n\t} else {\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\t}\n\tif ( material.iridescence > 0.0 ) {\n\t\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\t}\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\tgetPointLightInfo( 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\tgetSpotLightInfo( 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\tgetDirectionalLightInfo( 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.normal );\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.normal );\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 lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef USE_CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n\tfloat dotNVi = saturate( dot( normal, geometry.viewDir ) );\n\tif ( material.iridescenceThickness == 0.0 ) {\n\t\tmaterial.iridescence = 0.0;\n\t} else {\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\t}\n\tif ( material.iridescence > 0.0 ) {\n\t\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\t}\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\tgetPointLightInfo( 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\tvec4 spotColor;\n\tvec3 spotLightCoord;\n\tbool inSpotLightMap;\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\tgetSpotLightInfo( spotLight, geometry, directLight );\n\t\t#if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n\t\t#elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t#define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n\t\t#else\n\t\t#define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#endif\n\t\t#if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n\t\t\tspotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n\t\t\tinSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n\t\t\tspotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n\t\t\tdirectLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n\t\t#endif\n\t\t#undef SPOT_LIGHT_MAP_INDEX\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, vSpotLightCoord[ 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\tgetDirectionalLightInfo( 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.normal );\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.normal );\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 lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\t\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getIBLIrradiance( geometry.normal );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getIBLRadiance( geometry.viewDir, geometry.normal, material.roughness );\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatRadiance += getIBLRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness );\n\t#endif\n#endif"; @@ -9871,7 +8569,7 @@ var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\tuniform float morphTar var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\t#ifdef MORPHTARGETS_TEXTURE\n\t\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ];\n\t\t}\n\t#else\n\t\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\n\t\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\n\t\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\n\t\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\n\t\t#ifndef USE_MORPHNORMALS\n\t\t\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\n\t\t\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\n\t\t\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\n\t\t\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\n\t\t#endif\n\t#endif\n#endif"; -var normal_fragment_begin = "float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#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 * faceDirection;\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 * faceDirection;\n\t\t\tbitangent = bitangent * faceDirection;\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_begin = "float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#ifdef FLAT_SHADED\n\tvec3 fdx = dFdx( vViewPosition );\n\tvec3 fdy = dFdy( vViewPosition );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * faceDirection;\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 * faceDirection;\n\t\t\tbitangent = bitangent * faceDirection;\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 * faceDirection;\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, faceDirection );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\n#endif"; @@ -9891,9 +8589,9 @@ var clearcoat_pars_fragment = "#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clea var iridescence_pars_fragment = "#ifdef USE_IRIDESCENCEMAP\n\tuniform sampler2D iridescenceMap;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform sampler2D iridescenceThicknessMap;\n#endif"; -var output_fragment = "#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= transmissionAlpha + 0.1;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );"; +var output_fragment = "#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= material.transmissionAlpha + 0.1;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.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 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}\nvec2 packDepthToRG( in highp float v ) {\n\treturn packDepthToRGBA( v ).yx;\n}\nfloat unpackRGToDepth( const in highp vec2 v ) {\n\treturn unpackRGBAToDepth( vec4( v.xy, 0.0, 0.0 ) );\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"; @@ -9907,13 +8605,13 @@ var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUG var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; -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"; +var shadowmap_pars_fragment = "#if NUM_SPOT_LIGHT_COORDS > 0\n varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#if NUM_SPOT_LIGHT_MAPS > 0\n uniform sampler2D spotLightMap[ NUM_SPOT_LIGHT_MAPS ];\n#endif\n#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\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"; -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"; +var shadowmap_pars_vertex = "#if NUM_SPOT_LIGHT_COORDS > 0\n uniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#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\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"; -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 shadowmap_vertex = "#if defined( USE_SHADOWMAP ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n\t#if NUM_DIR_LIGHT_SHADOWS > 0 || NUM_SPOT_LIGHT_COORDS > 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_COORDS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition;\n\t\t#if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\tshadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias;\n\t\t#endif\n\t\tvSpotLightCoord[ i ] = spotLightMatrix[ 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}"; +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, vSpotLightCoord[ 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}"; 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"; @@ -9931,9 +8629,9 @@ var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = to 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; }"; -var transmission_fragment = "#ifdef USE_TRANSMISSION\n\tfloat transmissionAlpha = 1.0;\n\tfloat transmissionFactor = transmission;\n\tfloat thicknessFactor = thickness;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\ttransmissionFactor *= texture2D( transmissionMap, vUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tthicknessFactor *= texture2D( thicknessMap, vUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmission = getIBLVolumeRefraction(\n\t\tn, v, roughnessFactor, material.diffuseColor, material.specularColor, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, ior, thicknessFactor,\n\t\tattenuationColor, attenuationDistance );\n\ttotalDiffuse = mix( totalDiffuse, transmission.rgb, transmissionFactor );\n\ttransmissionAlpha = mix( transmissionAlpha, transmission.a, transmissionFactor );\n#endif"; +var transmission_fragment = "#ifdef USE_TRANSMISSION\n\tmaterial.transmission = transmission;\n\tmaterial.transmissionAlpha = 1.0;\n\tmaterial.thickness = thickness;\n\tmaterial.attenuationDistance = attenuationDistance;\n\tmaterial.attenuationColor = attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tmaterial.transmission *= texture2D( transmissionMap, vUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tmaterial.thickness *= texture2D( thicknessMap, vUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmission = getIBLVolumeRefraction(\n\t\tn, v, material.roughness, material.diffuseColor, material.specularColor, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, material.ior, material.thickness,\n\t\tmaterial.attenuationColor, material.attenuationDistance );\n\tmaterial.transmissionAlpha = mix( material.transmissionAlpha, transmission.a, material.transmission );\n\ttotalDiffuse = mix( totalDiffuse, transmission.rgb, material.transmission );\n#endif"; -var transmission_pars_fragment = "#ifdef USE_TRANSMISSION\n\tuniform float transmission;\n\tuniform float thickness;\n\tuniform float attenuationDistance;\n\tuniform vec3 attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tuniform sampler2D transmissionMap;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tuniform sampler2D thicknessMap;\n\t#endif\n\tuniform vec2 transmissionSamplerSize;\n\tuniform sampler2D transmissionSamplerMap;\n\tuniform mat4 modelMatrix;\n\tuniform mat4 projectionMatrix;\n\tvarying vec3 vWorldPosition;\n\tvec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\n\t\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n\t\tvec3 modelScale;\n\t\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\treturn normalize( refractionVector ) * thickness * modelScale;\n\t}\n\tfloat applyIorToRoughness( const in float roughness, const in float ior ) {\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t}\n\tvec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\n\t\tfloat framebufferLod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n\t\t#ifdef texture2DLodEXT\n\t\t\treturn texture2DLodEXT( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#else\n\t\t\treturn texture2D( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#endif\n\t}\n\tvec3 applyVolumeAttenuation( const in vec3 radiance, const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tif ( attenuationDistance == 0.0 ) {\n\t\t\treturn radiance;\n\t\t} else {\n\t\t\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n\t\t\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\t\t\treturn transmittance * radiance;\n\t\t}\n\t}\n\tvec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\n\t\tconst in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\n\t\tconst in mat4 viewMatrix, const in mat4 projMatrix, const in float ior, const in float thickness,\n\t\tconst in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\trefractionCoords += 1.0;\n\t\trefractionCoords /= 2.0;\n\t\tvec4 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n\t\tvec3 attenuatedColor = applyVolumeAttenuation( transmittedLight.rgb, length( transmissionRay ), attenuationColor, attenuationDistance );\n\t\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n\t\treturn vec4( ( 1.0 - F ) * attenuatedColor * diffuseColor, transmittedLight.a );\n\t}\n#endif"; +var transmission_pars_fragment = "#ifdef USE_TRANSMISSION\n\tuniform float transmission;\n\tuniform float thickness;\n\tuniform float attenuationDistance;\n\tuniform vec3 attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tuniform sampler2D transmissionMap;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tuniform sampler2D thicknessMap;\n\t#endif\n\tuniform vec2 transmissionSamplerSize;\n\tuniform sampler2D transmissionSamplerMap;\n\tuniform mat4 modelMatrix;\n\tuniform mat4 projectionMatrix;\n\tvarying vec3 vWorldPosition;\n\tvec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\n\t\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n\t\tvec3 modelScale;\n\t\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\treturn normalize( refractionVector ) * thickness * modelScale;\n\t}\n\tfloat applyIorToRoughness( const in float roughness, const in float ior ) {\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t}\n\tvec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\n\t\tfloat framebufferLod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n\t\t#ifdef texture2DLodEXT\n\t\t\treturn texture2DLodEXT( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#else\n\t\t\treturn texture2D( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#endif\n\t}\n\tvec3 applyVolumeAttenuation( const in vec3 radiance, const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tif ( isinf( attenuationDistance ) ) {\n\t\t\treturn radiance;\n\t\t} else {\n\t\t\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n\t\t\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\t\t\treturn transmittance * radiance;\n\t\t}\n\t}\n\tvec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\n\t\tconst in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\n\t\tconst in mat4 viewMatrix, const in mat4 projMatrix, const in float ior, const in float thickness,\n\t\tconst in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\trefractionCoords += 1.0;\n\t\trefractionCoords /= 2.0;\n\t\tvec4 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n\t\tvec3 attenuatedColor = applyVolumeAttenuation( transmittedLight.rgb, length( transmissionRay ), attenuationColor, attenuationDistance );\n\t\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n\t\treturn vec4( ( 1.0 - F ) * attenuatedColor * diffuseColor, transmittedLight.a );\n\t}\n#endif"; var uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif"; @@ -9947,13 +8645,16 @@ var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tat var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif"; -var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION )\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 worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) || NUM_SPOT_LIGHT_COORDS > 0\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"; -const vertex$g = "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}"; -const fragment$g = "uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tgl_FragColor = texture2D( t2D, vUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\tgl_FragColor = vec4( mix( pow( gl_FragColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), gl_FragColor.rgb * 0.0773993808, vec3( lessThanEqual( gl_FragColor.rgb, vec3( 0.04045 ) ) ) ), gl_FragColor.w );\n\t#endif\n\t#include \n\t#include \n}"; +const vertex$h = "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}"; +const fragment$h = "uniform sampler2D t2D;\nuniform float backgroundIntensity;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\ttexColor = vec4( mix( pow( texColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), texColor.rgb * 0.0773993808, vec3( lessThanEqual( texColor.rgb, vec3( 0.04045 ) ) ) ), texColor.w );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include \n\t#include \n}"; + +const vertex$g = "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}"; +const fragment$g = "#ifdef ENVMAP_TYPE_CUBE\n\tuniform samplerCube envMap;\n#elif defined( ENVMAP_TYPE_CUBE_UV )\n\tuniform sampler2D envMap;\n#endif\nuniform float flipEnvMap;\nuniform float backgroundBlurriness;\nuniform float backgroundIntensity;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 texColor = textureCube( envMap, vec3( flipEnvMap * vWorldDirection.x, vWorldDirection.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 texColor = textureCubeUV( envMap, vWorldDirection, backgroundBlurriness );\n\t#else\n\t\tvec4 texColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include \n\t#include \n}"; const vertex$f = "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}"; -const fragment$f = "#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}"; +const fragment$f = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = texColor;\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}"; const vertex$e = "#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}"; const fragment$e = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \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}"; @@ -9968,10 +8669,10 @@ const vertex$b = "uniform float scale;\nattribute float lineDistance;\nvarying f const fragment$b = "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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; const vertex$a = "#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#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\t\t#include \n\t\t#include \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\t#include \n\t#include \n}"; -const fragment$a = "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 \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\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; +const fragment$a = "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\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; -const vertex$9 = "#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\t#include \n}"; -const fragment$9 = "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 \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_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_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; +const vertex$9 = "#define LAMBERT\nvarying vec3 vViewPosition;\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\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}"; +const fragment$9 = "#define LAMBERT\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 \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 + totalEmissiveRadiance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; const vertex$8 = "#define MATCAP\nvarying vec3 vViewPosition;\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\tvViewPosition = - mvPosition.xyz;\n}"; const fragment$8 = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\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\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#else\n\t\tvec4 matcapColor = vec4( vec3( mix( 0.2, 0.8, uv.y ) ), 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; @@ -9980,7 +8681,7 @@ const vertex$7 = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUM const fragment$7 = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\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\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n\t#ifdef OPAQUE\n\t\tgl_FragColor.a = 1.0;\n\t#endif\n}"; const vertex$6 = "#define PHONG\nvarying vec3 vViewPosition;\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\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}"; -const fragment$6 = "#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 \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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; +const fragment$6 = "#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 \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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; const vertex$5 = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n\tvarying vec3 vWorldPosition;\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\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\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n#ifdef USE_TRANSMISSION\n\tvWorldPosition = worldPosition.xyz;\n#endif\n}"; const fragment$5 = "#define STANDARD\n#ifdef PHYSICAL\n\t#define IOR\n\t#define SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n\tuniform float ior;\n#endif\n#ifdef SPECULAR\n\tuniform float specularIntensity;\n\tuniform vec3 specularColor;\n\t#ifdef USE_SPECULARINTENSITYMAP\n\t\tuniform sampler2D specularIntensityMap;\n\t#endif\n\t#ifdef USE_SPECULARCOLORMAP\n\t\tuniform sampler2D specularColorMap;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_IRIDESCENCE\n\tuniform float iridescence;\n\tuniform float iridescenceIOR;\n\tuniform float iridescenceThicknessMinimum;\n\tuniform float iridescenceThicknessMaximum;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheenColor;\n\tuniform float sheenRoughness;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tuniform sampler2D sheenColorMap;\n\t#endif\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tuniform sampler2D sheenRoughnessMap;\n\t#endif\n#endif\nvarying vec3 vViewPosition;\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 \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\t#include \n\t#include \n\t#include \n\tvec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n\tvec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n\t#include \n\tvec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n\t#ifdef USE_SHEEN\n\t\tfloat sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor );\n\t\toutgoingLight = outgoingLight * sheenEnergyComp + sheenSpecular;\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNVcc = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\tvec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n\t\toutgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + clearcoatSpecular * material.clearcoat;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; @@ -10039,7 +8740,8 @@ const ShaderChunk = { gradientmap_pars_fragment: gradientmap_pars_fragment, lightmap_fragment: lightmap_fragment, lightmap_pars_fragment: lightmap_pars_fragment, - lights_lambert_vertex: lights_lambert_vertex, + lights_lambert_fragment: lights_lambert_fragment, + lights_lambert_pars_fragment: lights_lambert_pars_fragment, lights_pars_begin: lights_pars_begin, lights_toon_fragment: lights_toon_fragment, lights_toon_pars_fragment: lights_toon_pars_fragment, @@ -10103,8 +8805,10 @@ const ShaderChunk = { uv2_pars_vertex: uv2_pars_vertex, uv2_vertex: uv2_vertex, worldpos_vertex: worldpos_vertex, - background_vert: vertex$g, - background_frag: fragment$g, + background_vert: vertex$h, + background_frag: fragment$h, + backgroundCube_vert: vertex$g, + backgroundCube_frag: fragment$g, cube_vert: vertex$f, cube_frag: fragment$f, depth_vert: vertex$e, @@ -10188,8 +8892,8 @@ const UniformsLib = { refractionRatio: { value: 0.98 } // basic, lambert, phong - }, + aomap: { aoMap: { value: null @@ -10317,10 +9021,13 @@ const UniformsLib = { shadowMapSize: {} } }, + spotLightMap: { + value: [] + }, spotShadowMap: { value: [] }, - spotShadowMatrix: { + spotLightMatrix: { value: [] }, pointLights: { @@ -10435,7 +9142,7 @@ const ShaderLib = { fragmentShader: ShaderChunk.meshbasic_frag }, lambert: { - uniforms: /*@__PURE__*/mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.fog, UniformsLib.lights, { + uniforms: /*@__PURE__*/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: /*@__PURE__*/new Color(0x000000) } @@ -10472,8 +9179,8 @@ const ShaderLib = { envMapIntensity: { value: 1 } // temporary - }]), + vertexShader: ShaderChunk.meshphysical_vert, fragmentShader: ShaderChunk.meshphysical_frag }, @@ -10541,17 +9248,44 @@ const ShaderLib = { }, t2D: { value: null + }, + backgroundIntensity: { + value: 1 } }, vertexShader: ShaderChunk.background_vert, fragmentShader: ShaderChunk.background_frag }, + backgroundCube: { + uniforms: { + envMap: { + value: null + }, + flipEnvMap: { + value: -1 + }, + backgroundBlurriness: { + value: 0 + }, + backgroundIntensity: { + value: 1 + } + }, + vertexShader: ShaderChunk.backgroundCube_vert, + fragmentShader: ShaderChunk.backgroundCube_frag + }, cube: { - uniforms: /*@__PURE__*/mergeUniforms([UniformsLib.envmap, { + uniforms: { + tCube: { + value: null + }, + tFlip: { + value: -1 + }, opacity: { value: 1.0 } - }]), + }, vertexShader: ShaderChunk.cube_vert, fragmentShader: ShaderChunk.cube_frag }, @@ -10686,7 +9420,12 @@ ShaderLib.physical = { fragmentShader: ShaderChunk.meshphysical_frag }; -function WebGLBackground(renderer, cubemaps, state, objects, alpha, premultipliedAlpha) { +const _rgb = { + r: 0, + b: 0, + g: 0 +}; +function WebGLBackground(renderer, cubemaps, cubeuvmaps, state, objects, alpha, premultipliedAlpha) { const clearColor = new Color(0x000000); let clearAlpha = alpha === true ? 0 : 1; let planeMesh; @@ -10694,42 +9433,38 @@ function WebGLBackground(renderer, cubemaps, state, objects, alpha, premultiplie let currentBackground = null; let currentBackgroundVersion = 0; let currentTonemapping = null; - function render(renderList, scene) { let forceClear = false; let background = scene.isScene === true ? scene.background : null; - if (background && background.isTexture) { - background = cubemaps.get(background); - } // Ignore background in AR - // TODO: Reconsider this. + const usePMREM = scene.backgroundBlurriness > 0; // use PMREM if the user wants to blur the background + background = (usePMREM ? cubeuvmaps : cubemaps).get(background); + } + // Ignore background in AR + // TODO: Reconsider this. const xr = renderer.xr; const session = xr.getSession && xr.getSession(); - if (session && session.environmentBlendMode === 'additive') { background = null; } - if (background === null) { setClear(clearColor, clearAlpha); } else if (background && background.isColor) { setClear(background, 1); forceClear = true; } - if (renderer.autoClear || forceClear) { renderer.clear(renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil); } - if (background && (background.isCubeTexture || background.mapping === CubeUVReflectionMapping)) { if (boxMesh === undefined) { boxMesh = new Mesh(new BoxGeometry(1, 1, 1), new ShaderMaterial({ name: 'BackgroundCubeMaterial', - uniforms: cloneUniforms(ShaderLib.cube.uniforms), - vertexShader: ShaderLib.cube.vertexShader, - fragmentShader: ShaderLib.cube.fragmentShader, + uniforms: cloneUniforms(ShaderLib.backgroundCube.uniforms), + vertexShader: ShaderLib.backgroundCube.vertexShader, + fragmentShader: ShaderLib.backgroundCube.fragmentShader, side: BackSide, depthTest: false, depthWrite: false, @@ -10737,12 +9472,11 @@ function WebGLBackground(renderer, cubemaps, state, objects, alpha, premultiplie })); boxMesh.geometry.deleteAttribute('normal'); boxMesh.geometry.deleteAttribute('uv'); - boxMesh.onBeforeRender = function (renderer, scene, camera) { this.matrixWorld.copyPosition(camera.matrixWorld); - }; // enable code injection for non-built-in material - + }; + // add "envMap" material property so the renderer can evaluate it like for built-in materials Object.defineProperty(boxMesh.material, 'envMap', { get: function () { return this.uniforms.envMap.value; @@ -10750,19 +9484,19 @@ function WebGLBackground(renderer, cubemaps, state, objects, alpha, premultiplie }); objects.update(boxMesh); } - boxMesh.material.uniforms.envMap.value = background; boxMesh.material.uniforms.flipEnvMap.value = background.isCubeTexture && background.isRenderTargetTexture === false ? -1 : 1; - + boxMesh.material.uniforms.backgroundBlurriness.value = scene.backgroundBlurriness; + boxMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity; if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) { boxMesh.material.needsUpdate = true; currentBackground = background; currentBackgroundVersion = background.version; currentTonemapping = renderer.toneMapping; } + boxMesh.layers.enableAll(); - boxMesh.layers.enableAll(); // push to the pre-sorted opaque render list - + // 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) { @@ -10776,8 +9510,9 @@ function WebGLBackground(renderer, cubemaps, state, objects, alpha, premultiplie depthWrite: false, fog: false })); - planeMesh.geometry.deleteAttribute('normal'); // enable code injection for non-built-in material + planeMesh.geometry.deleteAttribute('normal'); + // add "map" material property so the renderer can evaluate it like for built-in materials Object.defineProperty(planeMesh.material, 'map', { get: function () { return this.uniforms.t2D.value; @@ -10785,32 +9520,28 @@ function WebGLBackground(renderer, cubemaps, state, objects, alpha, premultiplie }); objects.update(planeMesh); } - planeMesh.material.uniforms.t2D.value = background; - + planeMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity; if (background.matrixAutoUpdate === true) { background.updateMatrix(); } - planeMesh.material.uniforms.uvTransform.value.copy(background.matrix); - if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) { planeMesh.material.needsUpdate = true; currentBackground = background; currentBackgroundVersion = background.version; currentTonemapping = renderer.toneMapping; } + planeMesh.layers.enableAll(); - planeMesh.layers.enableAll(); // push to the pre-sorted opaque render list - + // push to the pre-sorted opaque render list 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); + color.getRGB(_rgb, getUnlitUniformColorSpace(renderer)); + state.buffers.color.setClear(_rgb.r, _rgb.g, _rgb.b, alpha, premultipliedAlpha); } - return { getClearColor: function () { return clearColor; @@ -10839,23 +9570,18 @@ function WebGLBindingStates(gl, extensions, attributes, capabilities) { const defaultState = createBindingState(null); let currentState = defaultState; let forceUpdate = false; - function setup(object, material, program, geometry, index) { let updateBuffers = false; - if (vaoAvailable) { const state = getBindingState(geometry, program, material); - if (currentState !== state) { currentState = state; bindVertexArrayObject(currentState.object); } - updateBuffers = needsUpdate(object, geometry, program, index); if (updateBuffers) saveCache(object, geometry, program, index); } else { const wireframe = material.wireframe === true; - if (currentState.geometry !== geometry.id || currentState.program !== program.id || currentState.wireframe !== wireframe) { currentState.geometry = geometry.id; currentState.program = program.id; @@ -10863,73 +9589,57 @@ function WebGLBindingStates(gl, extensions, attributes, capabilities) { updateBuffers = true; } } - if (index !== null) { attributes.update(index, gl.ELEMENT_ARRAY_BUFFER); } - if (updateBuffers || forceUpdate) { forceUpdate = false; setupVertexAttributes(object, material, program, geometry); - if (index !== null) { gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, attributes.get(index).buffer); } } } - 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); } - function deleteVertexArrayObject(vao) { if (capabilities.isWebGL2) return gl.deleteVertexArray(vao); return extension.deleteVertexArrayOES(vao); } - function getBindingState(geometry, program, material) { const wireframe = material.wireframe === true; let programMap = bindingStates[geometry.id]; - if (programMap === undefined) { programMap = {}; bindingStates[geometry.id] = programMap; } - let stateMap = programMap[program.id]; - if (stateMap === undefined) { stateMap = {}; programMap[program.id] = stateMap; } - let state = stateMap[wireframe]; - if (state === undefined) { state = createBindingState(createVertexArrayObject()); stateMap[wireframe] = state; } - return state; } - function createBindingState(vao) { const newAttributes = []; const enabledAttributes = []; const attributeDivisors = []; - for (let i = 0; i < maxVertexAttributes; i++) { newAttributes[i] = 0; enabledAttributes[i] = 0; attributeDivisors[i] = 0; } - return { // for backward compatibility on non-VAO support browser geometry: null, @@ -10943,105 +9653,83 @@ function WebGLBindingStates(gl, extensions, attributes, capabilities) { index: null }; } - function needsUpdate(object, geometry, program, index) { const cachedAttributes = currentState.attributes; const geometryAttributes = geometry.attributes; let attributesNum = 0; const programAttributes = program.getAttributes(); - for (const name in programAttributes) { const programAttribute = programAttributes[name]; - if (programAttribute.location >= 0) { const cachedAttribute = cachedAttributes[name]; let geometryAttribute = geometryAttributes[name]; - if (geometryAttribute === undefined) { if (name === 'instanceMatrix' && object.instanceMatrix) geometryAttribute = object.instanceMatrix; if (name === 'instanceColor' && object.instanceColor) geometryAttribute = object.instanceColor; } - if (cachedAttribute === undefined) return true; if (cachedAttribute.attribute !== geometryAttribute) return true; if (geometryAttribute && cachedAttribute.data !== geometryAttribute.data) return true; attributesNum++; } } - if (currentState.attributesNum !== attributesNum) return true; if (currentState.index !== index) return true; return false; } - function saveCache(object, geometry, program, index) { const cache = {}; const attributes = geometry.attributes; let attributesNum = 0; const programAttributes = program.getAttributes(); - for (const name in programAttributes) { const programAttribute = programAttributes[name]; - if (programAttribute.location >= 0) { let attribute = attributes[name]; - if (attribute === undefined) { if (name === 'instanceMatrix' && object.instanceMatrix) attribute = object.instanceMatrix; if (name === 'instanceColor' && object.instanceColor) attribute = object.instanceColor; } - const data = {}; data.attribute = attribute; - if (attribute && attribute.data) { data.data = attribute.data; } - cache[name] = data; attributesNum++; } } - currentState.attributes = cache; currentState.attributesNum = attributesNum; currentState.index = index; } - function initAttributes() { const newAttributes = currentState.newAttributes; - for (let i = 0, il = newAttributes.length; i < il; i++) { newAttributes[i] = 0; } } - function enableAttribute(attribute) { enableAttributeAndDivisor(attribute, 0); } - function enableAttributeAndDivisor(attribute, meshPerAttribute) { const newAttributes = currentState.newAttributes; const enabledAttributes = currentState.enabledAttributes; const attributeDivisors = currentState.attributeDivisors; newAttributes[attribute] = 1; - if (enabledAttributes[attribute] === 0) { gl.enableVertexAttribArray(attribute); enabledAttributes[attribute] = 1; } - if (attributeDivisors[attribute] !== meshPerAttribute) { const extension = capabilities.isWebGL2 ? gl : extensions.get('ANGLE_instanced_arrays'); extension[capabilities.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE'](attribute, meshPerAttribute); attributeDivisors[attribute] = meshPerAttribute; } } - function disableUnusedAttributes() { const newAttributes = currentState.newAttributes; const enabledAttributes = currentState.enabledAttributes; - for (let i = 0, il = enabledAttributes.length; i < il; i++) { if (enabledAttributes[i] !== newAttributes[i]) { gl.disableVertexAttribArray(i); @@ -11049,7 +9737,6 @@ function WebGLBindingStates(gl, extensions, attributes, capabilities) { } } } - function vertexAttribPointer(index, size, type, normalized, stride, offset) { if (capabilities.isWebGL2 === true && (type === gl.INT || type === gl.UNSIGNED_INT)) { gl.vertexAttribIPointer(index, size, type, stride, offset); @@ -11057,48 +9744,41 @@ function WebGLBindingStates(gl, extensions, attributes, capabilities) { gl.vertexAttribPointer(index, size, type, normalized, stride, offset); } } - function setupVertexAttributes(object, material, program, geometry) { if (capabilities.isWebGL2 === false && (object.isInstancedMesh || geometry.isInstancedBufferGeometry)) { if (extensions.get('ANGLE_instanced_arrays') === null) return; } - initAttributes(); const geometryAttributes = geometry.attributes; const programAttributes = program.getAttributes(); const materialDefaultAttributeValues = material.defaultAttributeValues; - for (const name in programAttributes) { const programAttribute = programAttributes[name]; - if (programAttribute.location >= 0) { let geometryAttribute = geometryAttributes[name]; - if (geometryAttribute === undefined) { if (name === 'instanceMatrix' && object.instanceMatrix) geometryAttribute = object.instanceMatrix; if (name === 'instanceColor' && object.instanceColor) geometryAttribute = object.instanceColor; } - if (geometryAttribute !== undefined) { const normalized = geometryAttribute.normalized; const size = geometryAttribute.itemSize; - const attribute = attributes.get(geometryAttribute); // TODO Attribute may not be available on context restore + const attribute = attributes.get(geometryAttribute); + + // TODO Attribute may not be available on context restore if (attribute === undefined) continue; const buffer = attribute.buffer; const type = attribute.type; const bytesPerElement = attribute.bytesPerElement; - if (geometryAttribute.isInterleavedBufferAttribute) { const data = geometryAttribute.data; const stride = data.stride; const offset = geometryAttribute.offset; - if (data.isInstancedInterleavedBuffer) { for (let i = 0; i < programAttribute.locationSize; i++) { enableAttributeAndDivisor(programAttribute.location + i, data.meshPerAttribute); } - if (object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined) { geometry._maxInstanceCount = data.meshPerAttribute * data.count; } @@ -11107,9 +9787,7 @@ function WebGLBindingStates(gl, extensions, attributes, capabilities) { enableAttribute(programAttribute.location + i); } } - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - for (let i = 0; i < programAttribute.locationSize; i++) { vertexAttribPointer(programAttribute.location + i, size / programAttribute.locationSize, type, normalized, stride * bytesPerElement, (offset + size / programAttribute.locationSize * i) * bytesPerElement); } @@ -11118,7 +9796,6 @@ function WebGLBindingStates(gl, extensions, attributes, capabilities) { for (let i = 0; i < programAttribute.locationSize; i++) { enableAttributeAndDivisor(programAttribute.location + i, geometryAttribute.meshPerAttribute); } - if (object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined) { geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count; } @@ -11127,30 +9804,24 @@ function WebGLBindingStates(gl, extensions, attributes, capabilities) { enableAttribute(programAttribute.location + i); } } - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - for (let i = 0; i < programAttribute.locationSize; i++) { vertexAttribPointer(programAttribute.location + i, size / programAttribute.locationSize, type, normalized, size * bytesPerElement, size / programAttribute.locationSize * i * bytesPerElement); } } } else if (materialDefaultAttributeValues !== undefined) { const value = materialDefaultAttributeValues[name]; - if (value !== undefined) { switch (value.length) { case 2: gl.vertexAttrib2fv(programAttribute.location, value); break; - case 3: gl.vertexAttrib3fv(programAttribute.location, value); break; - case 4: gl.vertexAttrib4fv(programAttribute.location, value); break; - default: gl.vertexAttrib1fv(programAttribute.location, value); } @@ -11158,79 +9829,63 @@ function WebGLBindingStates(gl, extensions, attributes, capabilities) { } } } - disableUnusedAttributes(); } - function dispose() { reset(); - for (const geometryId in bindingStates) { const programMap = bindingStates[geometryId]; - for (const programId in programMap) { const stateMap = programMap[programId]; - for (const wireframe in stateMap) { deleteVertexArrayObject(stateMap[wireframe].object); delete stateMap[wireframe]; } - delete programMap[programId]; } - delete bindingStates[geometryId]; } } - function releaseStatesOfGeometry(geometry) { if (bindingStates[geometry.id] === undefined) return; const programMap = bindingStates[geometry.id]; - for (const programId in programMap) { const stateMap = programMap[programId]; - for (const wireframe in stateMap) { deleteVertexArrayObject(stateMap[wireframe].object); delete stateMap[wireframe]; } - delete programMap[programId]; } - delete bindingStates[geometry.id]; } - function releaseStatesOfProgram(program) { for (const geometryId in bindingStates) { const programMap = bindingStates[geometryId]; if (programMap[program.id] === undefined) continue; const stateMap = programMap[program.id]; - for (const wireframe in stateMap) { deleteVertexArrayObject(stateMap[wireframe].object); delete stateMap[wireframe]; } - delete programMap[program.id]; } } - function reset() { resetDefaultState(); forceUpdate = true; if (currentState === defaultState) return; currentState = defaultState; bindVertexArrayObject(currentState.object); - } // for backward-compatibility + } + // for backward-compatibility function resetDefaultState() { defaultState.geometry = null; defaultState.program = null; defaultState.wireframe = false; } - return { setup: setup, reset: reset, @@ -11247,37 +9902,32 @@ function WebGLBindingStates(gl, extensions, attributes, capabilities) { function WebGLBufferRenderer(gl, extensions, info, capabilities) { const isWebGL2 = capabilities.isWebGL2; let mode; - function setMode(value) { mode = value; } - function render(start, count) { gl.drawArrays(mode, start, count); info.update(count, mode, 1); } - function renderInstances(start, count, primcount) { if (primcount === 0) return; let extension, methodName; - if (isWebGL2) { extension = gl; methodName = 'drawArraysInstanced'; } else { extension = extensions.get('ANGLE_instanced_arrays'); methodName = 'drawArraysInstancedANGLE'; - 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); - } // + } + // this.setMode = setMode; this.render = render; @@ -11286,47 +9936,37 @@ function WebGLBufferRenderer(gl, extensions, info, capabilities) { function WebGLCapabilities(gl, extensions, parameters) { let maxAnisotropy; - function getMaxAnisotropy() { if (maxAnisotropy !== undefined) return maxAnisotropy; - if (extensions.has('EXT_texture_filter_anisotropic') === true) { const extension = extensions.get('EXT_texture_filter_anisotropic'); maxAnisotropy = gl.getParameter(extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT); } else { maxAnisotropy = 0; } - return maxAnisotropy; } - function getMaxPrecision(precision) { if (precision === 'highp') { if (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT).precision > 0 && gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision > 0) { return 'highp'; } - precision = 'mediump'; } - if (precision === 'mediump') { if (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_FLOAT).precision > 0 && gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT).precision > 0) { return 'mediump'; } } - return 'lowp'; } - const isWebGL2 = typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext || typeof WebGL2ComputeRenderingContext !== 'undefined' && gl instanceof WebGL2ComputeRenderingContext; let precision = parameters.precision !== undefined ? parameters.precision : 'highp'; const maxPrecision = getMaxPrecision(precision); - if (maxPrecision !== precision) { console.warn('THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.'); precision = maxPrecision; } - const drawBuffers = isWebGL2 || extensions.has('WEBGL_draw_buffers'); const logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true; const maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); @@ -11366,21 +10006,21 @@ function WebGLCapabilities(gl, extensions, parameters) { function WebGLClipping(properties) { const scope = this; let globalState = null, - numGlobalPlanes = 0, - localClippingEnabled = false, - renderingShadows = false; + numGlobalPlanes = 0, + localClippingEnabled = false, + renderingShadows = false; const plane = new Plane(), - viewNormalMatrix = new Matrix3(), - uniform = { - value: null, - needsUpdate: false - }; + viewNormalMatrix = new Matrix3(), + uniform = { + value: null, + needsUpdate: false + }; this.uniform = uniform; this.numPlanes = 0; this.numIntersection = 0; - this.init = function (planes, enableLocalClipping, camera) { - const enabled = planes.length !== 0 || enableLocalClipping || // enable state of previous frame - the clipping code has to + const 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; @@ -11388,86 +10028,73 @@ function WebGLClipping(properties) { numGlobalPlanes = planes.length; return enabled; }; - this.beginShadows = function () { renderingShadows = true; projectPlanes(null); }; - this.endShadows = function () { renderingShadows = false; resetGlobalState(); }; - this.setState = function (material, camera, useCache) { const planes = material.clippingPlanes, - clipIntersection = material.clipIntersection, - clipShadows = material.clipShadows; + clipIntersection = material.clipIntersection, + clipShadows = material.clipShadows; const 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 { const nGlobal = renderingShadows ? 0 : numGlobalPlanes, - lGlobal = nGlobal * 4; + lGlobal = nGlobal * 4; let dstArray = materialProperties.clippingState || null; uniform.value = dstArray; // ensure unique state dstArray = projectPlanes(planes, camera, lGlobal, useCache); - for (let i = 0; i !== lGlobal; ++i) { dstArray[i] = globalState[i]; } - materialProperties.clippingState = dstArray; this.numIntersection = clipIntersection ? this.numPlanes : 0; this.numPlanes += nGlobal; } }; - function resetGlobalState() { if (uniform.value !== globalState) { uniform.value = globalState; uniform.needsUpdate = numGlobalPlanes > 0; } - scope.numPlanes = numGlobalPlanes; scope.numIntersection = 0; } - function projectPlanes(planes, camera, dstOffset, skipTransform) { const nPlanes = planes !== null ? planes.length : 0; let dstArray = null; - if (nPlanes !== 0) { dstArray = uniform.value; - if (skipTransform !== true || dstArray === null) { const flatSize = dstOffset + nPlanes * 4, - viewMatrix = camera.matrixWorldInverse; + viewMatrix = camera.matrixWorldInverse; viewNormalMatrix.getNormalMatrix(viewMatrix); - if (dstArray === null || dstArray.length < flatSize) { dstArray = new Float32Array(flatSize); } - for (let 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; } } - uniform.value = dstArray; uniform.needsUpdate = true; } - scope.numPlanes = nPlanes; scope.numIntersection = 0; return dstArray; @@ -11476,28 +10103,23 @@ function WebGLClipping(properties) { function WebGLCubeMaps(renderer) { let cubemaps = new WeakMap(); - function mapTextureMapping(texture, mapping) { if (mapping === EquirectangularReflectionMapping) { texture.mapping = CubeReflectionMapping; } else if (mapping === EquirectangularRefractionMapping) { texture.mapping = CubeRefractionMapping; } - return texture; } - function get(texture) { if (texture && texture.isTexture && texture.isRenderTargetTexture === false) { const mapping = texture.mapping; - if (mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping) { if (cubemaps.has(texture)) { const cubemap = cubemaps.get(texture).texture; return mapTextureMapping(cubemap, texture.mapping); } else { const image = texture.image; - if (image && image.height > 0) { const renderTarget = new WebGLCubeRenderTarget(image.height / 2); renderTarget.fromEquirectangularTexture(renderer, texture); @@ -11506,30 +10128,26 @@ function WebGLCubeMaps(renderer) { return mapTextureMapping(renderTarget.texture, texture.mapping); } else { // image not yet ready. try the conversion next frame + return null; } } } } - return texture; } - function onTextureDispose(event) { const texture = event.target; texture.removeEventListener('dispose', onTextureDispose); const cubemap = cubemaps.get(texture); - if (cubemap !== undefined) { cubemaps.delete(texture); cubemap.dispose(); } } - function dispose() { cubemaps = new WeakMap(); } - return { get: get, dispose: dispose @@ -11551,7 +10169,6 @@ class OrthographicCamera extends Camera { this.far = far; this.updateProjectionMatrix(); } - copy(source, recursive) { super.copy(source, recursive); this.left = source.left; @@ -11564,7 +10181,6 @@ class OrthographicCamera extends Camera { this.view = source.view === null ? null : Object.assign({}, source.view); return this; } - setViewOffset(fullWidth, fullHeight, x, y, width, height) { if (this.view === null) { this.view = { @@ -11577,7 +10193,6 @@ class OrthographicCamera extends Camera { height: 1 }; } - this.view.enabled = true; this.view.fullWidth = fullWidth; this.view.fullHeight = fullHeight; @@ -11587,15 +10202,12 @@ class OrthographicCamera extends Camera { this.view.height = height; this.updateProjectionMatrix(); } - clearViewOffset() { if (this.view !== null) { this.view.enabled = false; } - this.updateProjectionMatrix(); } - updateProjectionMatrix() { const dx = (this.right - this.left) / (2 * this.zoom); const dy = (this.top - this.bottom) / (2 * this.zoom); @@ -11605,7 +10217,6 @@ class OrthographicCamera extends Camera { let right = cx + dx; let top = cy + dy; let bottom = cy - dy; - if (this.view !== null && this.view.enabled) { const scaleW = (this.right - this.left) / this.view.fullWidth / this.zoom; const scaleH = (this.top - this.bottom) / this.view.fullHeight / this.zoom; @@ -11614,11 +10225,9 @@ class OrthographicCamera extends Camera { top -= scaleH * this.view.offsetY; bottom = top - scaleH * this.view.height; } - this.projectionMatrix.makeOrthographic(left, right, top, bottom, this.near, this.far); this.projectionMatrixInverse.copy(this.projectionMatrix).invert(); } - toJSON(meta) { const data = super.toJSON(meta); data.object.zoom = this.zoom; @@ -11631,30 +10240,31 @@ class OrthographicCamera extends Camera { if (this.view !== null) data.object.view = Object.assign({}, this.view); return data; } - } -const LOD_MIN = 4; // The standard deviations (radians) associated with the extra mips. These are +const LOD_MIN = 4; + +// 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. +const EXTRA_LOD_SIGMA = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582]; -const EXTRA_LOD_SIGMA = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582]; // The maximum length of the blur for loop. Smaller sigmas will use fewer +// The maximum length of the blur for loop. Smaller sigmas will use fewer // samples and exit early, but not recompile the shader. - const MAX_SAMPLES = 20; - const _flatCamera = /*@__PURE__*/new OrthographicCamera(); - const _clearColor = /*@__PURE__*/new Color(); +let _oldTarget = null; -let _oldTarget = null; // Golden Ratio - +// Golden Ratio const PHI = (1 + Math.sqrt(5)) / 2; -const 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. +const 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. const _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 @@ -11682,9 +10292,9 @@ class PMREMGenerator { this._blurMaterial = null; this._cubemapMaterial = null; this._equirectMaterial = null; - 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 @@ -11692,133 +10302,104 @@ class PMREMGenerator { * and far planes ensure the scene is rendered in its entirety (the cubeCamera * is placed at the origin). */ - - fromScene(scene, sigma = 0, near = 0.1, far = 100) { _oldTarget = this._renderer.getRenderTarget(); - this._setSize(256); - const cubeUVRenderTarget = this._allocateTargets(); - cubeUVRenderTarget.depthBuffer = true; - this._sceneToCubeUV(scene, near, far, cubeUVRenderTarget); - if (sigma > 0) { this._blur(cubeUVRenderTarget, 0, 0, sigma); } - this._applyPMREM(cubeUVRenderTarget); - this._cleanup(cubeUVRenderTarget); - return cubeUVRenderTarget; } + /** * Generates a PMREM from an equirectangular texture, which can be either LDR * or HDR. The ideal input image size is 1k (1024 x 512), * as this matches best with the 256 x 256 cubemap output. */ - - fromEquirectangular(equirectangular, renderTarget = null) { return this._fromTexture(equirectangular, renderTarget); } + /** * Generates a PMREM from an cubemap texture, which can be either LDR * or HDR. The ideal input cube size is 256 x 256, * as this matches best with the 256 x 256 cubemap output. */ - - fromCubemap(cubemap, renderTarget = null) { return this._fromTexture(cubemap, renderTarget); } + /** * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during * your texture's network fetch for increased concurrency. */ - - compileCubemapShader() { if (this._cubemapMaterial === null) { this._cubemapMaterial = _getCubemapMaterial(); - this._compileMaterial(this._cubemapMaterial); } } + /** * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during * your texture's network fetch for increased concurrency. */ - - compileEquirectangularShader() { if (this._equirectMaterial === null) { this._equirectMaterial = _getEquirectMaterial(); - this._compileMaterial(this._equirectMaterial); } } + /** * 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. */ - - dispose() { this._dispose(); - if (this._cubemapMaterial !== null) this._cubemapMaterial.dispose(); if (this._equirectMaterial !== null) this._equirectMaterial.dispose(); - } // private interface + } + // private interface _setSize(cubeSize) { this._lodMax = Math.floor(Math.log2(cubeSize)); this._cubeSize = Math.pow(2, this._lodMax); } - _dispose() { if (this._blurMaterial !== null) this._blurMaterial.dispose(); if (this._pingPongRenderTarget !== null) this._pingPongRenderTarget.dispose(); - for (let i = 0; i < this._lodPlanes.length; i++) { this._lodPlanes[i].dispose(); } } - _cleanup(outputTarget) { this._renderer.setRenderTarget(_oldTarget); - outputTarget.scissorTest = false; - _setViewport(outputTarget, 0, 0, outputTarget.width, outputTarget.height); } - _fromTexture(texture, renderTarget) { if (texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping) { this._setSize(texture.image.length === 0 ? 16 : texture.image[0].width || texture.image[0].image.width); } else { // Equirectangular + this._setSize(texture.image.width / 4); } - _oldTarget = this._renderer.getRenderTarget(); - const cubeUVRenderTarget = renderTarget || this._allocateTargets(); - this._textureToCubeUV(texture, cubeUVRenderTarget); - this._applyPMREM(cubeUVRenderTarget); - this._cleanup(cubeUVRenderTarget); - return cubeUVRenderTarget; } - _allocateTargets() { const width = 3 * Math.max(this._cubeSize, 16 * 7); const height = 4 * this._cubeSize; @@ -11831,14 +10412,11 @@ class PMREMGenerator { encoding: LinearEncoding, depthBuffer: false }; - const cubeUVRenderTarget = _createRenderTarget(width, height, params); - if (this._pingPongRenderTarget === null || this._pingPongRenderTarget.width !== width) { if (this._pingPongRenderTarget !== null) { this._dispose(); } - this._pingPongRenderTarget = _createRenderTarget(width, height, params); const { _lodMax @@ -11850,16 +10428,12 @@ class PMREMGenerator { } = _createPlanes(_lodMax)); this._blurMaterial = _getBlurShader(_lodMax, width, height); } - return cubeUVRenderTarget; } - _compileMaterial(material) { const tmpMesh = new Mesh(this._lodPlanes[0], material); - this._renderer.compile(tmpMesh, _flatCamera); } - _sceneToCubeUV(scene, near, far, cubeUVRenderTarget) { const fov = 90; const aspect = 1; @@ -11881,7 +10455,6 @@ class PMREMGenerator { const backgroundBox = new Mesh(new BoxGeometry(), backgroundMaterial); let useSolidColor = false; const background = scene.background; - if (background) { if (background.isColor) { backgroundMaterial.color.copy(background); @@ -11892,10 +10465,8 @@ class PMREMGenerator { backgroundMaterial.color.copy(_clearColor); useSolidColor = true; } - for (let i = 0; i < 6; i++) { const col = i % 3; - if (col === 0) { cubeCamera.up.set(0, upSign[i], 0); cubeCamera.lookAt(forwardSign[i], 0, 0); @@ -11906,69 +10477,54 @@ class PMREMGenerator { cubeCamera.up.set(0, upSign[i], 0); cubeCamera.lookAt(0, 0, forwardSign[i]); } - const size = this._cubeSize; - _setViewport(cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size); - renderer.setRenderTarget(cubeUVRenderTarget); - if (useSolidColor) { renderer.render(backgroundBox, cubeCamera); } - renderer.render(scene, cubeCamera); } - backgroundBox.geometry.dispose(); backgroundBox.material.dispose(); renderer.toneMapping = toneMapping; renderer.autoClear = originalAutoClear; scene.background = background; } - _textureToCubeUV(texture, cubeUVRenderTarget) { const renderer = this._renderer; const isCubeTexture = texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping; - if (isCubeTexture) { if (this._cubemapMaterial === null) { this._cubemapMaterial = _getCubemapMaterial(); } - this._cubemapMaterial.uniforms.flipEnvMap.value = texture.isRenderTargetTexture === false ? -1 : 1; } else { if (this._equirectMaterial === null) { this._equirectMaterial = _getEquirectMaterial(); } } - const material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial; const mesh = new Mesh(this._lodPlanes[0], material); const uniforms = material.uniforms; uniforms['envMap'].value = texture; const size = this._cubeSize; - _setViewport(cubeUVRenderTarget, 0, 0, 3 * size, 2 * size); - renderer.setRenderTarget(cubeUVRenderTarget); renderer.render(mesh, _flatCamera); } - _applyPMREM(cubeUVRenderTarget) { const renderer = this._renderer; const autoClear = renderer.autoClear; renderer.autoClear = false; - for (let i = 1; i < this._lodPlanes.length; i++) { const sigma = Math.sqrt(this._sigmas[i] * this._sigmas[i] - this._sigmas[i - 1] * this._sigmas[i - 1]); const poleAxis = _axisDirections[(i - 1) % _axisDirections.length]; - 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 @@ -11976,25 +10532,19 @@ class PMREMGenerator { * the poles) to approximate the orthogonally-separable blur. It is least * accurate at the poles, but still does a decent job. */ - - _blur(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) { const pingPongRenderTarget = this._pingPongRenderTarget; - this._halfBlur(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, sigma, 'latitudinal', poleAxis); - this._halfBlur(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, sigma, 'longitudinal', poleAxis); } - _halfBlur(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis) { const renderer = this._renderer; const blurMaterial = this._blurMaterial; - 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. - + } + // Number of standard deviations at which to cut off the discrete approximation. const STANDARD_DEVIATIONS = 3; const blurMesh = new Mesh(this._lodPlanes[lodOut], blurMaterial); const blurUniforms = blurMaterial.uniforms; @@ -12002,39 +10552,31 @@ class PMREMGenerator { const radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : 2 * Math.PI / (2 * MAX_SAMPLES - 1); const sigmaPixels = sigmaRadians / radiansPerPixel; const samples = isFinite(sigmaRadians) ? 1 + Math.floor(STANDARD_DEVIATIONS * sigmaPixels) : MAX_SAMPLES; - 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}`); } - const weights = []; let sum = 0; - for (let i = 0; i < MAX_SAMPLES; ++i) { const x = i / sigmaPixels; const weight = Math.exp(-x * x / 2); weights.push(weight); - if (i === 0) { sum += weight; } else if (i < samples) { sum += 2 * weight; } } - for (let i = 0; i < weights.length; i++) { weights[i] = weights[i] / sum; } - blurUniforms['envMap'].value = targetIn.texture; blurUniforms['samples'].value = samples; blurUniforms['weights'].value = weights; blurUniforms['latitudinal'].value = direction === 'latitudinal'; - if (poleAxis) { blurUniforms['poleAxis'].value = poleAxis; } - const { _lodMax } = this; @@ -12043,33 +10585,26 @@ class PMREMGenerator { const outputSize = this._sizeLods[lodOut]; const x = 3 * outputSize * (lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0); const y = 4 * (this._cubeSize - outputSize); - _setViewport(targetOut, x, y, 3 * outputSize, 2 * outputSize); - renderer.setRenderTarget(targetOut); renderer.render(blurMesh, _flatCamera); } - } - function _createPlanes(lodMax) { const lodPlanes = []; const sizeLods = []; const sigmas = []; let lod = lodMax; const totalLods = lodMax - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; - for (let i = 0; i < totalLods; i++) { const sizeLod = Math.pow(2, lod); sizeLods.push(sizeLod); let sigma = 1.0 / sizeLod; - if (i > lodMax - LOD_MIN) { sigma = EXTRA_LOD_SIGMA[i - lodMax + LOD_MIN - 1]; } else if (i === 0) { sigma = 0; } - sigmas.push(sigma); const texelSize = 1.0 / (sizeLod - 2); const min = -texelSize; @@ -12083,7 +10618,6 @@ function _createPlanes(lodMax) { const position = new Float32Array(positionSize * vertices * cubeFaces); const uv = new Float32Array(uvSize * vertices * cubeFaces); const faceIndex = new Float32Array(faceIndexSize * vertices * cubeFaces); - for (let face = 0; face < cubeFaces; face++) { const x = face % 3 * 2 / 3 - 1; const y = face > 2 ? 0 : -1; @@ -12093,25 +10627,21 @@ function _createPlanes(lodMax) { const fill = [face, face, face, face, face, face]; faceIndex.set(fill, faceIndexSize * vertices * face); } - const planes = new BufferGeometry(); planes.setAttribute('position', new BufferAttribute(position, positionSize)); planes.setAttribute('uv', new BufferAttribute(uv, uvSize)); planes.setAttribute('faceIndex', new BufferAttribute(faceIndex, faceIndexSize)); lodPlanes.push(planes); - if (lod > LOD_MIN) { lod--; } } - return { lodPlanes, sizeLods, sigmas }; } - function _createRenderTarget(width, height, params) { const cubeUVRenderTarget = new WebGLRenderTarget(width, height, params); cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; @@ -12119,12 +10649,10 @@ function _createRenderTarget(width, height, params) { 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(lodMax, width, height) { const weights = new Float32Array(MAX_SAMPLES); const poleAxis = new Vector3(0, 1, 0); @@ -12160,9 +10688,7 @@ function _getBlurShader(lodMax, width, height) { } }, vertexShader: _getCommonVertexShader(), - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` precision mediump float; precision mediump int; @@ -12229,7 +10755,6 @@ function _getBlurShader(lodMax, width, height) { }); return shaderMaterial; } - function _getEquirectMaterial() { return new ShaderMaterial({ name: 'EquirectangularToCubeUV', @@ -12239,9 +10764,7 @@ function _getEquirectMaterial() { } }, vertexShader: _getCommonVertexShader(), - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` precision mediump float; precision mediump int; @@ -12266,7 +10789,6 @@ function _getEquirectMaterial() { depthWrite: false }); } - function _getCubemapMaterial() { return new ShaderMaterial({ name: 'CubemapToCubeUV', @@ -12279,9 +10801,7 @@ function _getCubemapMaterial() { } }, vertexShader: _getCommonVertexShader(), - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` precision mediump float; precision mediump int; @@ -12303,11 +10823,8 @@ function _getCubemapMaterial() { depthWrite: false }); } - function _getCommonVertexShader() { - return ( - /* glsl */ - ` + return (/* glsl */` precision mediump float; precision mediump int; @@ -12369,12 +10886,13 @@ function _getCommonVertexShader() { function WebGLCubeUVMaps(renderer) { let cubeUVmaps = new WeakMap(); let pmremGenerator = null; - function get(texture) { if (texture && texture.isTexture) { const mapping = texture.mapping; const isEquirectMap = mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping; - const isCubeMap = mapping === CubeReflectionMapping || mapping === CubeRefractionMapping; // equirect/cube map to cubeUV conversion + const isCubeMap = mapping === CubeReflectionMapping || mapping === CubeRefractionMapping; + + // equirect/cube map to cubeUV conversion if (isEquirectMap || isCubeMap) { if (texture.isRenderTargetTexture && texture.needsPMREMUpdate === true) { @@ -12389,7 +10907,6 @@ function WebGLCubeUVMaps(renderer) { return cubeUVmaps.get(texture).texture; } else { const image = texture.image; - if (isEquirectMap && image && image.height > 0 || isCubeMap && image && isCubeTextureComplete(image)) { if (pmremGenerator === null) pmremGenerator = new PMREMGenerator(renderer); const renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular(texture) : pmremGenerator.fromCubemap(texture); @@ -12398,47 +10915,39 @@ function WebGLCubeUVMaps(renderer) { return renderTarget.texture; } else { // image not yet ready. try the conversion next frame + return null; } } } } } - return texture; } - function isCubeTextureComplete(image) { let count = 0; const length = 6; - for (let i = 0; i < length; i++) { if (image[i] !== undefined) count++; } - return count === length; } - function onTextureDispose(event) { const texture = event.target; texture.removeEventListener('dispose', onTextureDispose); const cubemapUV = cubeUVmaps.get(texture); - if (cubemapUV !== undefined) { cubeUVmaps.delete(texture); cubemapUV.dispose(); } } - function dispose() { cubeUVmaps = new WeakMap(); - if (pmremGenerator !== null) { pmremGenerator.dispose(); pmremGenerator = null; } } - return { get: get, dispose: dispose @@ -12447,39 +10956,30 @@ function WebGLCubeUVMaps(renderer) { function WebGLExtensions(gl) { const extensions = {}; - function getExtension(name) { if (extensions[name] !== undefined) { return extensions[name]; } - let extension; - 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; - 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; - 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; - default: extension = gl.getExtension(name); } - extensions[name] = extension; return extension; } - return { has: function (name) { return getExtension(name) !== null; @@ -12497,18 +10997,15 @@ function WebGLExtensions(gl) { getExtension('OES_vertex_array_object'); getExtension('ANGLE_instanced_arrays'); } - getExtension('OES_texture_float_linear'); getExtension('EXT_color_buffer_half_float'); getExtension('WEBGL_multisampled_render_to_texture'); }, get: function (name) { const extension = getExtension(name); - if (extension === null) { console.warn('THREE.WebGLRenderer: ' + name + ' extension not supported.'); } - return extension; } }; @@ -12517,37 +11014,30 @@ function WebGLExtensions(gl) { function WebGLGeometries(gl, attributes, info, bindingStates) { const geometries = {}; const wireframeAttributes = new WeakMap(); - function onGeometryDispose(event) { const geometry = event.target; - if (geometry.index !== null) { attributes.remove(geometry.index); } - for (const name in geometry.attributes) { attributes.remove(geometry.attributes[name]); } - geometry.removeEventListener('dispose', onGeometryDispose); delete geometries[geometry.id]; const attribute = wireframeAttributes.get(geometry); - if (attribute) { attributes.remove(attribute); wireframeAttributes.delete(geometry); } - bindingStates.releaseStatesOfGeometry(geometry); - if (geometry.isInstancedBufferGeometry === true) { delete geometry._maxInstanceCount; - } // + } + // info.memory.geometries--; } - function get(object, geometry) { if (geometries[geometry.id] === true) return geometry; geometry.addEventListener('dispose', onGeometryDispose); @@ -12555,36 +11045,33 @@ function WebGLGeometries(gl, attributes, info, bindingStates) { info.memory.geometries++; return geometry; } - function update(geometry) { - const geometryAttributes = geometry.attributes; // Updating index buffer in VAO now. See WebGLBindingStates. + const geometryAttributes = geometry.attributes; + + // Updating index buffer in VAO now. See WebGLBindingStates. for (const name in geometryAttributes) { attributes.update(geometryAttributes[name], gl.ARRAY_BUFFER); - } // morph targets + } + // morph targets const morphAttributes = geometry.morphAttributes; - for (const name in morphAttributes) { const array = morphAttributes[name]; - for (let i = 0, l = array.length; i < l; i++) { attributes.update(array[i], gl.ARRAY_BUFFER); } } } - function updateWireframeAttribute(geometry) { const indices = []; const geometryIndex = geometry.index; const geometryPosition = geometry.attributes.position; let version = 0; - if (geometryIndex !== null) { const array = geometryIndex.array; version = geometryIndex.version; - for (let i = 0, l = array.length; i < l; i += 3) { const a = array[i + 0]; const b = array[i + 1]; @@ -12594,7 +11081,6 @@ function WebGLGeometries(gl, attributes, info, bindingStates) { } else { const array = geometryPosition.array; version = geometryPosition.version; - for (let i = 0, l = array.length / 3 - 1; i < l; i += 3) { const a = i + 0; const b = i + 1; @@ -12602,25 +11088,27 @@ function WebGLGeometries(gl, attributes, info, bindingStates) { indices.push(a, b, b, c, c, a); } } - const attribute = new (arrayNeedsUint32(indices) ? Uint32BufferAttribute : Uint16BufferAttribute)(indices, 1); - attribute.version = version; // Updating index buffer in VAO now. See WebGLBindingStates + attribute.version = version; + + // Updating index buffer in VAO now. See WebGLBindingStates + // const previousAttribute = wireframeAttributes.get(geometry); - if (previousAttribute) attributes.remove(previousAttribute); // + if (previousAttribute) attributes.remove(previousAttribute); + + // wireframeAttributes.set(geometry, attribute); } - function getWireframeAttribute(geometry) { const currentAttribute = wireframeAttributes.get(geometry); - if (currentAttribute) { const geometryIndex = geometry.index; - if (geometryIndex !== null) { // if the attribute is obsolete, create a new one + if (currentAttribute.version < geometryIndex.version) { updateWireframeAttribute(geometry); } @@ -12628,10 +11116,8 @@ function WebGLGeometries(gl, attributes, info, bindingStates) { } else { updateWireframeAttribute(geometry); } - return wireframeAttributes.get(geometry); } - return { get: get, update: update, @@ -12642,44 +11128,37 @@ function WebGLGeometries(gl, attributes, info, bindingStates) { function WebGLIndexedBufferRenderer(gl, extensions, info, capabilities) { const isWebGL2 = capabilities.isWebGL2; let mode; - function setMode(value) { mode = value; } - let type, bytesPerElement; - function setIndex(value) { type = value.type; bytesPerElement = value.bytesPerElement; } - function render(start, count) { gl.drawElements(mode, count, type, start * bytesPerElement); info.update(count, mode, 1); } - function renderInstances(start, count, primcount) { if (primcount === 0) return; let extension, methodName; - if (isWebGL2) { extension = gl; methodName = 'drawElementsInstanced'; } else { extension = extensions.get('ANGLE_instanced_arrays'); methodName = 'drawElementsInstancedANGLE'; - if (extension === null) { console.error('THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.'); return; } } - extension[methodName](mode, count, type, start * bytesPerElement, primcount); info.update(count, mode, primcount); - } // + } + // this.setMode = setMode; this.setIndex = setIndex; @@ -12699,37 +11178,29 @@ function WebGLInfo(gl) { points: 0, lines: 0 }; - function update(count, mode, instanceCount) { render.calls++; - switch (mode) { case gl.TRIANGLES: render.triangles += instanceCount * (count / 3); break; - case gl.LINES: render.lines += instanceCount * (count / 2); break; - case gl.LINE_STRIP: render.lines += instanceCount * (count - 1); break; - case gl.LINE_LOOP: render.lines += instanceCount * count; break; - case gl.POINTS: render.points += instanceCount * count; break; - default: console.error('THREE.WebGLInfo: Unknown draw mode:', mode); break; } } - function reset() { render.frame++; render.calls = 0; @@ -12737,7 +11208,6 @@ function WebGLInfo(gl) { render.points = 0; render.lines = 0; } - return { memory: memory, render: render, @@ -12751,39 +11221,27 @@ function WebGLInfo(gl) { function numericalSort(a, b) { return a[0] - b[0]; } - function absNumericalSort(a, b) { return Math.abs(b[1]) - Math.abs(a[1]); } - -function denormalize(morph, attribute) { - let denominator = 1; - const array = attribute.isInterleavedBufferAttribute ? attribute.data.array : attribute.array; - if (array instanceof Int8Array) denominator = 127;else if (array instanceof Uint8Array) denominator = 255;else if (array instanceof Uint16Array) denominator = 65535;else if (array instanceof Int16Array) denominator = 32767;else if (array instanceof Int32Array) denominator = 2147483647;else console.error('THREE.WebGLMorphtargets: Unsupported morph attribute data type: ', array); - morph.divideScalar(denominator); -} - function WebGLMorphtargets(gl, capabilities, textures) { const influencesList = {}; const morphInfluences = new Float32Array(8); const morphTextures = new WeakMap(); const morph = new Vector4(); const workInfluences = []; - for (let i = 0; i < 8; i++) { workInfluences[i] = [i, 0]; } - function update(object, geometry, material, program) { const objectInfluences = object.morphTargetInfluences; - if (capabilities.isWebGL2 === true) { // instead of using attributes, the WebGL 2 code path encodes morph targets // into an array of data textures. Each layer represents a single morph target. + const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color; const morphTargetsCount = morphAttribute !== undefined ? morphAttribute.length : 0; let entry = morphTextures.get(geometry); - if (entry === undefined || entry.count !== morphTargetsCount) { if (entry !== undefined) entry.texture.dispose(); const hasMorphPosition = geometry.morphAttributes.position !== undefined; @@ -12798,49 +11256,41 @@ function WebGLMorphtargets(gl, capabilities, textures) { if (hasMorphColors === true) vertexDataCount = 3; let width = geometry.attributes.position.count * vertexDataCount; let height = 1; - if (width > capabilities.maxTextureSize) { height = Math.ceil(width / capabilities.maxTextureSize); width = capabilities.maxTextureSize; } - const buffer = new Float32Array(width * height * 4 * morphTargetsCount); const texture = new DataArrayTexture(buffer, width, height, morphTargetsCount); texture.type = FloatType; - texture.needsUpdate = true; // fill buffer + texture.needsUpdate = true; - const vertexDataStride = vertexDataCount * 4; + // fill buffer + const vertexDataStride = vertexDataCount * 4; for (let i = 0; i < morphTargetsCount; i++) { const morphTarget = morphTargets[i]; const morphNormal = morphNormals[i]; const morphColor = morphColors[i]; const offset = width * height * 4 * i; - for (let j = 0; j < morphTarget.count; j++) { const stride = j * vertexDataStride; - if (hasMorphPosition === true) { morph.fromBufferAttribute(morphTarget, j); - if (morphTarget.normalized === true) denormalize(morph, morphTarget); buffer[offset + stride + 0] = morph.x; buffer[offset + stride + 1] = morph.y; buffer[offset + stride + 2] = morph.z; buffer[offset + stride + 3] = 0; } - if (hasMorphNormals === true) { morph.fromBufferAttribute(morphNormal, j); - if (morphNormal.normalized === true) denormalize(morph, morphNormal); buffer[offset + stride + 4] = morph.x; buffer[offset + stride + 5] = morph.y; buffer[offset + stride + 6] = morph.z; buffer[offset + stride + 7] = 0; } - if (hasMorphColors === true) { morph.fromBufferAttribute(morphColor, j); - if (morphColor.normalized === true) denormalize(morph, morphColor); buffer[offset + stride + 8] = morph.x; buffer[offset + stride + 9] = morph.y; buffer[offset + stride + 10] = morph.z; @@ -12848,30 +11298,26 @@ function WebGLMorphtargets(gl, capabilities, textures) { } } } - entry = { count: morphTargetsCount, texture: texture, size: new Vector2(width, height) }; morphTextures.set(geometry, entry); - function disposeTexture() { texture.dispose(); morphTextures.delete(geometry); geometry.removeEventListener('dispose', disposeTexture); } - geometry.addEventListener('dispose', disposeTexture); - } // + } + // let morphInfluencesSum = 0; - for (let i = 0; i < objectInfluences.length; i++) { morphInfluencesSum += objectInfluences[i]; } - const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; program.getUniforms().setValue(gl, 'morphTargetBaseInfluence', morphBaseInfluence); program.getUniforms().setValue(gl, 'morphTargetInfluences', objectInfluences); @@ -12880,29 +11326,27 @@ function WebGLMorphtargets(gl, capabilities, textures) { } else { // 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 + const length = objectInfluences === undefined ? 0 : objectInfluences.length; let influences = influencesList[geometry.id]; - if (influences === undefined || influences.length !== length) { // initialise list - influences = []; + influences = []; for (let i = 0; i < length; i++) { influences[i] = [i, 0]; } - influencesList[geometry.id] = influences; - } // Collect influences + } + // Collect influences for (let i = 0; i < length; i++) { const influence = influences[i]; influence[0] = i; influence[1] = objectInfluences[i]; } - influences.sort(absNumericalSort); - for (let i = 0; i < 8; i++) { if (i < length && influences[i][1]) { workInfluences[i][0] = influences[i][0]; @@ -12912,50 +11356,42 @@ function WebGLMorphtargets(gl, capabilities, textures) { workInfluences[i][1] = 0; } } - workInfluences.sort(numericalSort); const morphTargets = geometry.morphAttributes.position; const morphNormals = geometry.morphAttributes.normal; let morphInfluencesSum = 0; - for (let i = 0; i < 8; i++) { const influence = workInfluences[i]; const index = influence[0]; const value = influence[1]; - if (index !== Number.MAX_SAFE_INTEGER && value) { if (morphTargets && geometry.getAttribute('morphTarget' + i) !== morphTargets[index]) { geometry.setAttribute('morphTarget' + i, morphTargets[index]); } - if (morphNormals && geometry.getAttribute('morphNormal' + i) !== morphNormals[index]) { geometry.setAttribute('morphNormal' + i, morphNormals[index]); } - morphInfluences[i] = value; morphInfluencesSum += value; } else { if (morphTargets && geometry.hasAttribute('morphTarget' + i) === true) { geometry.deleteAttribute('morphTarget' + i); } - if (morphNormals && geometry.hasAttribute('morphNormal' + i) === true) { geometry.deleteAttribute('morphNormal' + i); } - morphInfluences[i] = 0; } - } // GLSL shader uses formula baseinfluence * base + sum(target * influence) + } + + // 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) - - const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; program.getUniforms().setValue(gl, 'morphTargetBaseInfluence', morphBaseInfluence); program.getUniforms().setValue(gl, 'morphTargetInfluences', morphInfluences); } } - return { update: update }; @@ -12963,43 +11399,37 @@ function WebGLMorphtargets(gl, capabilities, textures) { function WebGLObjects(gl, geometries, attributes, info) { let updateMap = new WeakMap(); - function update(object) { const frame = info.render.frame; const geometry = object.geometry; - const buffergeometry = geometries.get(object, geometry); // Update once per frame + const buffergeometry = geometries.get(object, geometry); + + // Update once per frame if (updateMap.get(buffergeometry) !== frame) { geometries.update(buffergeometry); updateMap.set(buffergeometry, frame); } - if (object.isInstancedMesh) { if (object.hasEventListener('dispose', onInstancedMeshDispose) === false) { object.addEventListener('dispose', onInstancedMeshDispose); } - attributes.update(object.instanceMatrix, gl.ARRAY_BUFFER); - if (object.instanceColor !== null) { attributes.update(object.instanceColor, gl.ARRAY_BUFFER); } } - return buffergeometry; } - function dispose() { updateMap = new WeakMap(); } - function onInstancedMeshDispose(event) { const instancedMesh = event.target; instancedMesh.removeEventListener('dispose', onInstancedMeshDispose); attributes.remove(instancedMesh.instanceMatrix); if (instancedMesh.instanceColor !== null) attributes.remove(instancedMesh.instanceColor); } - return { update: update, dispose: dispose @@ -13051,88 +11481,89 @@ function WebGLObjects(gl, geometries, attributes, info) { const emptyTexture = /*@__PURE__*/new Texture(); const emptyArrayTexture = /*@__PURE__*/new DataArrayTexture(); const empty3dTexture = /*@__PURE__*/new Data3DTexture(); -const emptyCubeTexture = /*@__PURE__*/new CubeTexture(); // --- Utilities --- +const emptyCubeTexture = /*@__PURE__*/new CubeTexture(); + +// --- Utilities --- + // Array Caches (provide typed arrays for temporary by size) const arrayCacheF32 = []; -const arrayCacheI32 = []; // Float32Array caches used for uploading Matrix uniforms +const arrayCacheI32 = []; + +// Float32Array caches used for uploading Matrix uniforms const mat4array = new Float32Array(16); const mat3array = new Float32Array(9); -const mat2array = new Float32Array(4); // Flattening for arrays of vectors and matrices +const mat2array = new Float32Array(4); + +// Flattening for arrays of vectors and matrices function flatten(array, nBlocks, blockSize) { const firstElem = array[0]; - if (firstElem <= 0 || firstElem > 0) return array; // unoptimized: ! isNaN( firstElem ) + if (firstElem <= 0 || firstElem > 0) return array; + // unoptimized: ! isNaN( firstElem ) // see http://jacksondunstan.com/articles/983 const n = nBlocks * blockSize; let r = arrayCacheF32[n]; - if (r === undefined) { r = new Float32Array(n); arrayCacheF32[n] = r; } - if (nBlocks !== 0) { firstElem.toArray(r, 0); - for (let i = 1, offset = 0; i !== nBlocks; ++i) { offset += blockSize; array[i].toArray(r, offset); } } - return r; } - function arraysEqual(a, b) { if (a.length !== b.length) return false; - for (let i = 0, l = a.length; i < l; i++) { if (a[i] !== b[i]) return false; } - return true; } - function copyArray(a, b) { for (let i = 0, l = b.length; i < l; i++) { a[i] = b[i]; } -} // Texture unit allocation +} +// Texture unit allocation function allocTexUnits(textures, n) { let r = arrayCacheI32[n]; - if (r === undefined) { r = new Int32Array(n); arrayCacheI32[n] = r; } - for (let i = 0; i !== n; ++i) { r[i] = textures.allocateTextureUnit(); } - return r; -} // --- Setters --- +} + +// --- Setters --- + // Note: Defining these methods externally, because they come in a bunch // and this way their names minify. -// Single scalar +// Single scalar function setValueV1f(gl, v) { const 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) +} +// Single float vector (from flat array or THREE.VectorN) function setValueV2f(gl, v) { const cache = this.cache; - if (v.x !== undefined) { if (cache[0] !== v.x || cache[1] !== v.y) { gl.uniform2f(this.addr, v.x, v.y); @@ -13145,10 +11576,8 @@ function setValueV2f(gl, v) { copyArray(cache, v); } } - function setValueV3f(gl, v) { const cache = this.cache; - 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); @@ -13169,10 +11598,8 @@ function setValueV3f(gl, v) { copyArray(cache, v); } } - function setValueV4f(gl, v) { const cache = this.cache; - 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); @@ -13186,13 +11613,13 @@ function setValueV4f(gl, v) { gl.uniform4fv(this.addr, v); copyArray(cache, v); } -} // Single matrix (from flat array or THREE.MatrixN) +} +// Single matrix (from flat array or THREE.MatrixN) function setValueM2(gl, v) { const cache = this.cache; const elements = v.elements; - if (elements === undefined) { if (arraysEqual(cache, v)) return; gl.uniformMatrix2fv(this.addr, false, v); @@ -13204,11 +11631,9 @@ function setValueM2(gl, v) { copyArray(cache, elements); } } - function setValueM3(gl, v) { const cache = this.cache; const elements = v.elements; - if (elements === undefined) { if (arraysEqual(cache, v)) return; gl.uniformMatrix3fv(this.addr, false, v); @@ -13220,11 +11645,9 @@ function setValueM3(gl, v) { copyArray(cache, elements); } } - function setValueM4(gl, v) { const cache = this.cache; const elements = v.elements; - if (elements === undefined) { if (arraysEqual(cache, v)) return; gl.uniformMatrix4fv(this.addr, false, v); @@ -13235,132 +11658,174 @@ function setValueM4(gl, v) { gl.uniformMatrix4fv(this.addr, false, mat4array); copyArray(cache, elements); } -} // Single integer / boolean +} +// Single integer / boolean function setValueV1i(gl, v) { const cache = this.cache; if (cache[0] === v) return; gl.uniform1i(this.addr, v); cache[0] = v; -} // Single integer / boolean vector (from flat array) +} +// Single integer / boolean vector (from flat array or THREE.VectorN) function setValueV2i(gl, v) { const cache = this.cache; - if (arraysEqual(cache, v)) return; - gl.uniform2iv(this.addr, v); - copyArray(cache, v); + if (v.x !== undefined) { + if (cache[0] !== v.x || cache[1] !== v.y) { + gl.uniform2i(this.addr, v.x, v.y); + cache[0] = v.x; + cache[1] = v.y; + } + } else { + if (arraysEqual(cache, v)) return; + gl.uniform2iv(this.addr, v); + copyArray(cache, v); + } } - function setValueV3i(gl, v) { const cache = this.cache; - if (arraysEqual(cache, v)) return; - gl.uniform3iv(this.addr, v); - copyArray(cache, v); + if (v.x !== undefined) { + if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z) { + gl.uniform3i(this.addr, v.x, v.y, v.z); + cache[0] = v.x; + cache[1] = v.y; + cache[2] = v.z; + } + } else { + if (arraysEqual(cache, v)) return; + gl.uniform3iv(this.addr, v); + copyArray(cache, v); + } } - function setValueV4i(gl, v) { const cache = this.cache; - if (arraysEqual(cache, v)) return; - gl.uniform4iv(this.addr, v); - copyArray(cache, v); -} // Single unsigned integer + if (v.x !== undefined) { + if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z || cache[3] !== v.w) { + gl.uniform4i(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.uniform4iv(this.addr, v); + copyArray(cache, v); + } +} +// Single unsigned integer function setValueV1ui(gl, v) { const cache = this.cache; if (cache[0] === v) return; gl.uniform1ui(this.addr, v); cache[0] = v; -} // Single unsigned integer vector (from flat array) +} +// Single unsigned integer vector (from flat array or THREE.VectorN) function setValueV2ui(gl, v) { const cache = this.cache; - if (arraysEqual(cache, v)) return; - gl.uniform2uiv(this.addr, v); - copyArray(cache, v); + if (v.x !== undefined) { + if (cache[0] !== v.x || cache[1] !== v.y) { + gl.uniform2ui(this.addr, v.x, v.y); + cache[0] = v.x; + cache[1] = v.y; + } + } else { + if (arraysEqual(cache, v)) return; + gl.uniform2uiv(this.addr, v); + copyArray(cache, v); + } } - function setValueV3ui(gl, v) { const cache = this.cache; - if (arraysEqual(cache, v)) return; - gl.uniform3uiv(this.addr, v); - copyArray(cache, v); + if (v.x !== undefined) { + if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z) { + gl.uniform3ui(this.addr, v.x, v.y, v.z); + cache[0] = v.x; + cache[1] = v.y; + cache[2] = v.z; + } + } else { + if (arraysEqual(cache, v)) return; + gl.uniform3uiv(this.addr, v); + copyArray(cache, v); + } } - function setValueV4ui(gl, v) { const cache = this.cache; - if (arraysEqual(cache, v)) return; - gl.uniform4uiv(this.addr, v); - copyArray(cache, v); -} // Single texture (2D / Cube) + if (v.x !== undefined) { + if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z || cache[3] !== v.w) { + gl.uniform4ui(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.uniform4uiv(this.addr, v); + copyArray(cache, v); + } +} +// Single texture (2D / Cube) function setValueT1(gl, v, textures) { const cache = this.cache; const unit = textures.allocateTextureUnit(); - if (cache[0] !== unit) { gl.uniform1i(this.addr, unit); cache[0] = unit; } - textures.setTexture2D(v || emptyTexture, unit); } - function setValueT3D1(gl, v, textures) { const cache = this.cache; const unit = textures.allocateTextureUnit(); - if (cache[0] !== unit) { gl.uniform1i(this.addr, unit); cache[0] = unit; } - textures.setTexture3D(v || empty3dTexture, unit); } - function setValueT6(gl, v, textures) { const cache = this.cache; const unit = textures.allocateTextureUnit(); - if (cache[0] !== unit) { gl.uniform1i(this.addr, unit); cache[0] = unit; } - textures.setTextureCube(v || emptyCubeTexture, unit); } - function setValueT2DArray1(gl, v, textures) { const cache = this.cache; const unit = textures.allocateTextureUnit(); - if (cache[0] !== unit) { gl.uniform1i(this.addr, unit); cache[0] = unit; } - textures.setTexture2DArray(v || emptyArrayTexture, unit); -} // Helper to pick the right setter for the singular case +} +// Helper to pick the right setter for the singular case function getSingularSetter(type) { switch (type) { case 0x1406: return setValueV1f; // FLOAT - case 0x8b50: return setValueV2f; // _VEC2 - case 0x8b51: return setValueV3f; // _VEC3 - case 0x8b52: return setValueV4f; // _VEC4 @@ -13368,11 +11833,9 @@ function getSingularSetter(type) { case 0x8b5a: return setValueM2; // _MAT2 - case 0x8b5b: return setValueM3; // _MAT3 - case 0x8b5c: return setValueM4; // _MAT4 @@ -13381,17 +11844,14 @@ function getSingularSetter(type) { case 0x8b56: return setValueV1i; // INT, BOOL - case 0x8b53: case 0x8b57: return setValueV2i; // _VEC2 - case 0x8b54: case 0x8b58: return setValueV3i; // _VEC3 - case 0x8b55: case 0x8b59: return setValueV4i; @@ -13400,190 +11860,179 @@ function getSingularSetter(type) { case 0x1405: return setValueV1ui; // UINT - case 0x8dc6: return setValueV2ui; // _VEC2 - case 0x8dc7: return setValueV3ui; // _VEC3 - case 0x8dc8: return setValueV4ui; // _VEC4 case 0x8b5e: // SAMPLER_2D - case 0x8d66: // SAMPLER_EXTERNAL_OES - case 0x8dca: // INT_SAMPLER_2D - case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D - case 0x8b62: // SAMPLER_2D_SHADOW return setValueT1; - case 0x8b5f: // SAMPLER_3D - case 0x8dcb: // INT_SAMPLER_3D - case 0x8dd3: // UNSIGNED_INT_SAMPLER_3D return setValueT3D1; - case 0x8b60: // SAMPLER_CUBE - case 0x8dcc: // INT_SAMPLER_CUBE - case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE - case 0x8dc5: // SAMPLER_CUBE_SHADOW return setValueT6; - case 0x8dc1: // SAMPLER_2D_ARRAY - case 0x8dcf: // INT_SAMPLER_2D_ARRAY - case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY - case 0x8dc4: // SAMPLER_2D_ARRAY_SHADOW return setValueT2DArray1; } -} // Array of scalars +} +// Array of scalars function setValueV1fArray(gl, v) { gl.uniform1fv(this.addr, v); -} // Array of vectors (from flat array or array of THREE.VectorN) +} +// Array of vectors (from flat array or array of THREE.VectorN) function setValueV2fArray(gl, v) { const data = flatten(v, this.size, 2); gl.uniform2fv(this.addr, data); } - function setValueV3fArray(gl, v) { const data = flatten(v, this.size, 3); gl.uniform3fv(this.addr, data); } - function setValueV4fArray(gl, v) { const data = flatten(v, this.size, 4); gl.uniform4fv(this.addr, data); -} // Array of matrices (from flat array or array of THREE.MatrixN) +} +// Array of matrices (from flat array or array of THREE.MatrixN) function setValueM2Array(gl, v) { const data = flatten(v, this.size, 4); gl.uniformMatrix2fv(this.addr, false, data); } - function setValueM3Array(gl, v) { const data = flatten(v, this.size, 9); gl.uniformMatrix3fv(this.addr, false, data); } - function setValueM4Array(gl, v) { const data = flatten(v, this.size, 16); gl.uniformMatrix4fv(this.addr, false, data); -} // Array of integer / boolean +} +// Array of integer / boolean function setValueV1iArray(gl, v) { gl.uniform1iv(this.addr, v); -} // Array of integer / boolean vectors (from flat array) +} +// Array of integer / boolean vectors (from flat array) function setValueV2iArray(gl, v) { gl.uniform2iv(this.addr, v); } - function setValueV3iArray(gl, v) { gl.uniform3iv(this.addr, v); } - function setValueV4iArray(gl, v) { gl.uniform4iv(this.addr, v); -} // Array of unsigned integer +} +// Array of unsigned integer function setValueV1uiArray(gl, v) { gl.uniform1uiv(this.addr, v); -} // Array of unsigned integer vectors (from flat array) +} +// Array of unsigned integer vectors (from flat array) function setValueV2uiArray(gl, v) { gl.uniform2uiv(this.addr, v); } - function setValueV3uiArray(gl, v) { gl.uniform3uiv(this.addr, v); } - function setValueV4uiArray(gl, v) { gl.uniform4uiv(this.addr, v); -} // Array of textures (2D / 3D / Cube / 2DArray) +} +// Array of textures (2D / 3D / Cube / 2DArray) function setValueT1Array(gl, v, textures) { + const cache = this.cache; const n = v.length; const units = allocTexUnits(textures, n); - gl.uniform1iv(this.addr, units); - + if (!arraysEqual(cache, units)) { + gl.uniform1iv(this.addr, units); + copyArray(cache, units); + } for (let i = 0; i !== n; ++i) { textures.setTexture2D(v[i] || emptyTexture, units[i]); } } - function setValueT3DArray(gl, v, textures) { + const cache = this.cache; const n = v.length; const units = allocTexUnits(textures, n); - gl.uniform1iv(this.addr, units); - + if (!arraysEqual(cache, units)) { + gl.uniform1iv(this.addr, units); + copyArray(cache, units); + } for (let i = 0; i !== n; ++i) { textures.setTexture3D(v[i] || empty3dTexture, units[i]); } } - function setValueT6Array(gl, v, textures) { + const cache = this.cache; const n = v.length; const units = allocTexUnits(textures, n); - gl.uniform1iv(this.addr, units); - + if (!arraysEqual(cache, units)) { + gl.uniform1iv(this.addr, units); + copyArray(cache, units); + } for (let i = 0; i !== n; ++i) { textures.setTextureCube(v[i] || emptyCubeTexture, units[i]); } } - function setValueT2DArrayArray(gl, v, textures) { + const cache = this.cache; const n = v.length; const units = allocTexUnits(textures, n); - gl.uniform1iv(this.addr, units); - + if (!arraysEqual(cache, units)) { + gl.uniform1iv(this.addr, units); + copyArray(cache, units); + } for (let i = 0; i !== n; ++i) { textures.setTexture2DArray(v[i] || emptyArrayTexture, units[i]); } -} // Helper to pick the right setter for a pure (bottom-level) array +} +// Helper to pick the right setter for a pure (bottom-level) array function getPureArraySetter(type) { switch (type) { case 0x1406: return setValueV1fArray; // FLOAT - case 0x8b50: return setValueV2fArray; // _VEC2 - case 0x8b51: return setValueV3fArray; // _VEC3 - case 0x8b52: return setValueV4fArray; // _VEC4 @@ -13591,11 +12040,9 @@ function getPureArraySetter(type) { case 0x8b5a: return setValueM2Array; // _MAT2 - case 0x8b5b: return setValueM3Array; // _MAT3 - case 0x8b5c: return setValueM4Array; // _MAT4 @@ -13604,17 +12051,14 @@ function getPureArraySetter(type) { case 0x8b56: return setValueV1iArray; // INT, BOOL - case 0x8b53: case 0x8b57: return setValueV2iArray; // _VEC2 - case 0x8b54: case 0x8b58: return setValueV3iArray; // _VEC3 - case 0x8b55: case 0x8b59: return setValueV4iArray; @@ -13623,70 +12067,54 @@ function getPureArraySetter(type) { case 0x1405: return setValueV1uiArray; // UINT - case 0x8dc6: return setValueV2uiArray; // _VEC2 - case 0x8dc7: return setValueV3uiArray; // _VEC3 - case 0x8dc8: return setValueV4uiArray; // _VEC4 case 0x8b5e: // SAMPLER_2D - case 0x8d66: // SAMPLER_EXTERNAL_OES - case 0x8dca: // INT_SAMPLER_2D - case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D - case 0x8b62: // SAMPLER_2D_SHADOW return setValueT1Array; - case 0x8b5f: // SAMPLER_3D - case 0x8dcb: // INT_SAMPLER_3D - case 0x8dd3: // UNSIGNED_INT_SAMPLER_3D return setValueT3DArray; - case 0x8b60: // SAMPLER_CUBE - case 0x8dcc: // INT_SAMPLER_CUBE - case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE - case 0x8dc5: // SAMPLER_CUBE_SHADOW return setValueT6Array; - case 0x8dc1: // SAMPLER_2D_ARRAY - case 0x8dcf: // INT_SAMPLER_2D_ARRAY - case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY - case 0x8dc4: // SAMPLER_2D_ARRAY_SHADOW return setValueT2DArrayArray; } -} // --- Uniform Classes --- +} +// --- Uniform Classes --- class SingleUniform { constructor(id, activeInfo, addr) { this.id = id; this.addr = addr; this.cache = []; - this.setValue = getSingularSetter(activeInfo.type); // this.path = activeInfo.name; // DEBUG - } + this.setValue = getSingularSetter(activeInfo.type); + // this.path = activeInfo.name; // DEBUG + } } class PureArrayUniform { @@ -13695,9 +12123,10 @@ class PureArrayUniform { this.addr = addr; this.cache = []; this.size = activeInfo.size; - this.setValue = getPureArraySetter(activeInfo.type); // this.path = activeInfo.name; // DEBUG - } + this.setValue = getPureArraySetter(activeInfo.type); + // this.path = activeInfo.name; // DEBUG + } } class StructuredUniform { @@ -13706,21 +12135,22 @@ class StructuredUniform { this.seq = []; this.map = {}; } - setValue(gl, value, textures) { const seq = this.seq; - for (let i = 0, n = seq.length; i !== n; ++i) { const u = seq[i]; u.setValue(gl, value[u.id], textures); } } +} + +// --- Top-level --- -} // --- Top-level --- // Parser - builds up the property tree from the path strings +const RePathPart = /(\w+)(\])?(\[|\.)?/g; -const RePathPart = /(\w+)(\])?(\[|\.)?/g; // extracts +// 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) @@ -13733,87 +12163,78 @@ function addUniform(container, uniformObject) { container.seq.push(uniformObject); container.map[uniformObject.id] = uniformObject; } - function parseUniform(activeInfo, addr, container) { const path = activeInfo.name, - pathLength = path.length; // reset RegExp object, because of the early exit of a previous run + pathLength = path.length; + // reset RegExp object, because of the early exit of a previous run RePathPart.lastIndex = 0; - while (true) { const match = RePathPart.exec(path), - matchEnd = RePathPart.lastIndex; + matchEnd = RePathPart.lastIndex; let id = match[1]; const idIsIndex = match[2] === ']', - subscript = match[3]; + subscript = match[3]; if (idIsIndex) id = id | 0; // convert to integer 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 + const map = container.map; let next = map[id]; - if (next === undefined) { next = new StructuredUniform(id); addUniform(container, next); } - container = next; } } -} // Root Container +} +// Root Container class WebGLUniforms { constructor(gl, program) { this.seq = []; this.map = {}; const n = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); - for (let i = 0; i < n; ++i) { const info = gl.getActiveUniform(program, i), - addr = gl.getUniformLocation(program, info.name); + addr = gl.getUniformLocation(program, info.name); parseUniform(info, addr, this); } } - setValue(gl, name, value, textures) { const u = this.map[name]; if (u !== undefined) u.setValue(gl, value, textures); } - setOptional(gl, object, name) { const v = object[name]; if (v !== undefined) this.setValue(gl, name, v); } - static upload(gl, seq, values, textures) { for (let i = 0, n = seq.length; i !== n; ++i) { const u = seq[i], - v = values[u.id]; - + v = values[u.id]; if (v.needsUpdate !== false) { // note: always updating when .needsUpdate is undefined u.setValue(gl, v.value, textures); } } } - static seqWithValue(seq, values) { const r = []; - for (let i = 0, n = seq.length; i !== n; ++i) { const u = seq[i]; if (u.id in values) r.push(u); } - return r; } - } function WebGLShader(gl, type, string) { @@ -13824,116 +12245,96 @@ function WebGLShader(gl, type, string) { } let programIdCount = 0; - function handleSource(string, errorLine) { const lines = string.split('\n'); const lines2 = []; const from = Math.max(errorLine - 6, 0); const to = Math.min(errorLine + 6, lines.length); - for (let i = from; i < to; i++) { const line = i + 1; lines2.push(`${line === errorLine ? '>' : ' '} ${line}: ${lines[i]}`); } - return lines2.join('\n'); } - function getEncodingComponents(encoding) { switch (encoding) { case LinearEncoding: return ['Linear', '( value )']; - case sRGBEncoding: return ['sRGB', '( value )']; - default: console.warn('THREE.WebGLProgram: Unsupported encoding:', encoding); return ['Linear', '( value )']; } } - function getShaderErrors(gl, shader, type) { const status = gl.getShaderParameter(shader, gl.COMPILE_STATUS); const errors = gl.getShaderInfoLog(shader).trim(); if (status && errors === '') return ''; const errorMatches = /ERROR: 0:(\d+)/.exec(errors); - if (errorMatches) { // --enable-privileged-webgl-extension // console.log( '**' + type + '**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) ); + const errorLine = parseInt(errorMatches[1]); return type.toUpperCase() + '\n\n' + errors + '\n\n' + handleSource(gl.getShaderSource(shader), errorLine); } else { return errors; } } - function getTexelEncodingFunction(functionName, encoding) { const components = getEncodingComponents(encoding); return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[0] + components[1] + '; }'; } - function getToneMappingFunction(functionName, toneMapping) { let toneMappingName; - switch (toneMapping) { case LinearToneMapping: toneMappingName = 'Linear'; break; - case ReinhardToneMapping: toneMappingName = 'Reinhard'; break; - case CineonToneMapping: toneMappingName = 'OptimizedCineon'; break; - case ACESFilmicToneMapping: toneMappingName = 'ACESFilmic'; break; - case CustomToneMapping: toneMappingName = 'Custom'; break; - default: console.warn('THREE.WebGLProgram: Unsupported toneMapping:', toneMapping); toneMappingName = 'Linear'; } - return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }'; } - function generateExtensions(parameters) { const chunks = [parameters.extensionDerivatives || !!parameters.envMapCubeUVHeight || 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.transmission) && parameters.rendererExtensionShaderTextureLod ? '#extension GL_EXT_shader_texture_lod : enable' : '']; return chunks.filter(filterEmptyLine).join('\n'); } - function generateDefines(defines) { const chunks = []; - for (const name in defines) { const value = defines[name]; if (value === false) continue; chunks.push('#define ' + name + ' ' + value); } - return chunks.join('\n'); } - function fetchAttributeLocations(gl, program) { const attributes = {}; const n = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); - for (let i = 0; i < n; i++) { const info = gl.getActiveAttrib(program, i); const name = info.name; let locationSize = 1; if (info.type === gl.FLOAT_MAT2) locationSize = 2; if (info.type === gl.FLOAT_MAT3) locationSize = 3; - if (info.type === gl.FLOAT_MAT4) locationSize = 4; // console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i ); + if (info.type === gl.FLOAT_MAT4) locationSize = 4; + + // console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i ); attributes[name] = { type: info.type, @@ -13941,66 +12342,51 @@ function fetchAttributeLocations(gl, program) { locationSize: locationSize }; } - 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); + const numSpotLightCoords = parameters.numSpotLightShadows + parameters.numSpotLightMaps - parameters.numSpotLightShadowsWithMaps; + return string.replace(/NUM_DIR_LIGHTS/g, parameters.numDirLights).replace(/NUM_SPOT_LIGHTS/g, parameters.numSpotLights).replace(/NUM_SPOT_LIGHT_MAPS/g, parameters.numSpotLightMaps).replace(/NUM_SPOT_LIGHT_COORDS/g, numSpotLightCoords).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_WITH_MAPS/g, parameters.numSpotLightShadowsWithMaps).replace(/NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows).replace(/NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows); } - function replaceClippingPlaneNums(string, parameters) { return string.replace(/NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g, parameters.numClippingPlanes - parameters.numClipIntersection); -} // Resolve Includes +} +// Resolve Includes const includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm; - function resolveIncludes(string) { return string.replace(includePattern, includeReplacer); } - function includeReplacer(match, include) { const string = ShaderChunk[include]; - if (string === undefined) { throw new Error('Can not resolve #include <' + include + '>'); } - return resolveIncludes(string); -} // Unroll Loops +} +// Unroll Loops -const deprecatedUnrollLoopPattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g; const 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; - function unrollLoops(string) { - return string.replace(unrollLoopPattern, loopReplacer).replace(deprecatedUnrollLoopPattern, deprecatedLoopReplacer); -} - -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 string.replace(unrollLoopPattern, loopReplacer); } - function loopReplacer(match, start, end, snippet) { let string = ''; - for (let i = parseInt(start); i < parseInt(end); i++) { string += snippet.replace(/\[\s*i\s*\]/g, '[ ' + i + ' ]').replace(/UNROLLED_LOOP_INDEX/g, i); } - return string; -} // +} +// function generatePrecision(parameters) { let precisionstring = 'precision ' + parameters.precision + ' float;\nprecision ' + parameters.precision + ' int;'; - if (parameters.precision === 'highp') { precisionstring += '\n#define HIGH_PRECISION'; } else if (parameters.precision === 'mediump') { @@ -14008,13 +12394,10 @@ function generatePrecision(parameters) { } else if (parameters.precision === 'lowp') { precisionstring += '\n#define LOW_PRECISION'; } - return precisionstring; } - function generateShadowMapTypeDefine(parameters) { let shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC'; - if (parameters.shadowMapType === PCFShadowMap) { shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF'; } else if (parameters.shadowMapType === PCFSoftShadowMap) { @@ -14022,32 +12405,25 @@ function generateShadowMapTypeDefine(parameters) { } else if (parameters.shadowMapType === VSMShadowMap) { shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM'; } - return shadowMapTypeDefine; } - function generateEnvMapTypeDefine(parameters) { let envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; - if (parameters.envMap) { switch (parameters.envMapMode) { case CubeReflectionMapping: case CubeRefractionMapping: envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; break; - case CubeUVReflectionMapping: envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV'; break; } } - return envMapTypeDefine; } - function generateEnvMapModeDefine(parameters) { let envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; - if (parameters.envMap) { switch (parameters.envMapMode) { case CubeRefractionMapping: @@ -14055,32 +12431,25 @@ function generateEnvMapModeDefine(parameters) { break; } } - return envMapModeDefine; } - function generateEnvMapBlendingDefine(parameters) { let envMapBlendingDefine = 'ENVMAP_BLENDING_NONE'; - if (parameters.envMap) { switch (parameters.combine) { case MultiplyOperation: envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; break; - case MixOperation: envMapBlendingDefine = 'ENVMAP_BLENDING_MIX'; break; - case AddOperation: envMapBlendingDefine = 'ENVMAP_BLENDING_ADD'; break; } } - return envMapBlendingDefine; } - function generateCubeUVSize(parameters) { const imageHeight = parameters.envMapCubeUVHeight; if (imageHeight === null) return null; @@ -14093,10 +12462,10 @@ function generateCubeUVSize(parameters) { maxMip }; } - function WebGLProgram(renderer, cacheKey, parameters, bindingStates) { // TODO Send this event to Three.js DevTools // console.log( 'WebGLProgram', cacheKey ); + const gl = renderer.getContext(); const defines = parameters.defines; let vertexShader = parameters.vertexShader; @@ -14111,26 +12480,23 @@ function WebGLProgram(renderer, cacheKey, parameters, bindingStates) { const program = gl.createProgram(); let prefixVertex, prefixFragment; let versionString = parameters.glslVersion ? '#version ' + parameters.glslVersion + '\n' : ''; - if (parameters.isRawShaderMaterial) { prefixVertex = [customDefines].filter(filterEmptyLine).join('\n'); - 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' : '', 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.iridescenceMap ? '#define USE_IRIDESCENCEMAP' : '', parameters.iridescenceThicknessMap ? '#define USE_IRIDESCENCE_THICKNESSMAP' : '', parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.specularIntensityMap ? '#define USE_SPECULARINTENSITYMAP' : '', parameters.specularColorMap ? '#define USE_SPECULARCOLORMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.transmission ? '#define USE_TRANSMISSION' : '', parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '', parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '', parameters.sheenColorMap ? '#define USE_SHEENCOLORMAP' : '', parameters.sheenRoughnessMap ? '#define USE_SHEENROUGHNESSMAP' : '', parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors ? '#define USE_COLOR' : '', parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '', parameters.vertexUvs ? '#define USE_UV' : '', parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '', parameters.flatShading ? '#define FLAT_SHADED' : '', parameters.skinning ? '#define USE_SKINNING' : '', parameters.morphTargets ? '#define USE_MORPHTARGETS' : '', parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '', parameters.morphColors && parameters.isWebGL2 ? '#define USE_MORPHCOLORS' : '', parameters.morphTargetsCount > 0 && parameters.isWebGL2 ? '#define MORPHTARGETS_TEXTURE' : '', parameters.morphTargetsCount > 0 && parameters.isWebGL2 ? '#define MORPHTARGETS_TEXTURE_STRIDE ' + parameters.morphTextureStride : '', parameters.morphTargetsCount > 0 && parameters.isWebGL2 ? '#define MORPHTARGETS_COUNT ' + parameters.morphTargetsCount : '', 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', '#if defined( USE_COLOR_ALPHA )', ' attribute vec4 color;', '#elif defined( USE_COLOR )', ' attribute vec3 color;', '#endif', '#if ( defined( USE_MORPHTARGETS ) && ! defined( MORPHTARGETS_TEXTURE ) )', ' 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.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 : '', envMapCubeUVSize ? '#define CUBEUV_TEXEL_WIDTH ' + envMapCubeUVSize.texelWidth : '', envMapCubeUVSize ? '#define CUBEUV_TEXEL_HEIGHT ' + envMapCubeUVSize.texelHeight : '', envMapCubeUVSize ? '#define CUBEUV_MAX_MIP ' + envMapCubeUVSize.maxMip + '.0' : '', 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.clearcoat ? '#define USE_CLEARCOAT' : '', parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.iridescence ? '#define USE_IRIDESCENCE' : '', parameters.iridescenceMap ? '#define USE_IRIDESCENCEMAP' : '', parameters.iridescenceThicknessMap ? '#define USE_IRIDESCENCE_THICKNESSMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.specularIntensityMap ? '#define USE_SPECULARINTENSITYMAP' : '', parameters.specularColorMap ? '#define USE_SPECULARCOLORMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.alphaTest ? '#define USE_ALPHATEST' : '', parameters.sheen ? '#define USE_SHEEN' : '', parameters.sheenColorMap ? '#define USE_SHEENCOLORMAP' : '', parameters.sheenRoughnessMap ? '#define USE_SHEENROUGHNESSMAP' : '', parameters.transmission ? '#define USE_TRANSMISSION' : '', parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '', parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '', parameters.decodeVideoTexture ? '#define DECODE_VIDEO_TEXTURE' : '', parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors || parameters.instancingColor ? '#define USE_COLOR' : '', parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '', 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' : '', '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' : '', parameters.opaque ? '#define OPAQUE' : '', ShaderChunk['encodings_pars_fragment'], // this code is required here because it is used by the various encoding/decoding function defined below + prefixFragment = [customExtensions, generatePrecision(parameters), '#define SHADER_NAME ' + parameters.shaderName, customDefines, 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 : '', envMapCubeUVSize ? '#define CUBEUV_TEXEL_WIDTH ' + envMapCubeUVSize.texelWidth : '', envMapCubeUVSize ? '#define CUBEUV_TEXEL_HEIGHT ' + envMapCubeUVSize.texelHeight : '', envMapCubeUVSize ? '#define CUBEUV_MAX_MIP ' + envMapCubeUVSize.maxMip + '.0' : '', 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.clearcoat ? '#define USE_CLEARCOAT' : '', parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.iridescence ? '#define USE_IRIDESCENCE' : '', parameters.iridescenceMap ? '#define USE_IRIDESCENCEMAP' : '', parameters.iridescenceThicknessMap ? '#define USE_IRIDESCENCE_THICKNESSMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.specularIntensityMap ? '#define USE_SPECULARINTENSITYMAP' : '', parameters.specularColorMap ? '#define USE_SPECULARCOLORMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.alphaTest ? '#define USE_ALPHATEST' : '', parameters.sheen ? '#define USE_SHEEN' : '', parameters.sheenColorMap ? '#define USE_SHEENCOLORMAP' : '', parameters.sheenRoughnessMap ? '#define USE_SHEENROUGHNESSMAP' : '', parameters.transmission ? '#define USE_TRANSMISSION' : '', parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '', parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '', parameters.decodeVideoTexture ? '#define DECODE_VIDEO_TEXTURE' : '', parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors || parameters.instancingColor ? '#define USE_COLOR' : '', parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '', 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' : '', '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' : '', parameters.opaque ? '#define OPAQUE' : '', ShaderChunk['encodings_pars_fragment'], + // this code is required here because it is used by the various encoding/decoding function defined below getTexelEncodingFunction('linearToOutputTexel', parameters.outputEncoding), parameters.useDepthPacking ? '#define DEPTH_PACKING ' + parameters.depthPacking : '', '\n'].filter(filterEmptyLine).join('\n'); } - vertexShader = resolveIncludes(vertexShader); vertexShader = replaceLightNums(vertexShader, parameters); vertexShader = replaceClippingPlaneNums(vertexShader, parameters); @@ -14139,22 +12505,25 @@ function WebGLProgram(renderer, cacheKey, parameters, bindingStates) { 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 = ['precision mediump sampler2DArray;', '#define attribute in', '#define varying out', '#define texture2D texture'].join('\n') + '\n' + prefixVertex; prefixFragment = ['#define varying in', parameters.glslVersion === GLSL3 ? '' : 'layout(location = 0) 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; } - const vertexGlsl = versionString + prefixVertex + vertexShader; - const fragmentGlsl = versionString + prefixFragment + fragmentShader; // console.log( '*VERTEX*', vertexGlsl ); + const fragmentGlsl = versionString + prefixFragment + fragmentShader; + + // console.log( '*VERTEX*', vertexGlsl ); // console.log( '*FRAGMENT*', fragmentGlsl ); const glVertexShader = WebGLShader(gl, gl.VERTEX_SHADER, vertexGlsl); const glFragmentShader = WebGLShader(gl, gl.FRAGMENT_SHADER, fragmentGlsl); gl.attachShader(program, glVertexShader); - gl.attachShader(program, glFragmentShader); // Force a particular attribute to index 0. + gl.attachShader(program, glFragmentShader); + + // Force a particular attribute to index 0. if (parameters.index0AttributeName !== undefined) { gl.bindAttribLocation(program, 0, parameters.index0AttributeName); @@ -14162,16 +12531,15 @@ function WebGLProgram(renderer, cacheKey, parameters, bindingStates) { // programs with morphTargets displace position out of attribute 0 gl.bindAttribLocation(program, 0, 'position'); } + gl.linkProgram(program); - gl.linkProgram(program); // check for link errors - + // check for link errors if (renderer.debug.checkShaderErrors) { const programLog = gl.getProgramInfoLog(program).trim(); const vertexLog = gl.getShaderInfoLog(glVertexShader).trim(); const fragmentLog = gl.getShaderInfoLog(glFragmentShader).trim(); let runnable = true; let haveDiagnostics = true; - if (gl.getProgramParameter(program, gl.LINK_STATUS) === false) { runnable = false; const vertexErrors = getShaderErrors(gl, glVertexShader, 'vertex'); @@ -14182,7 +12550,6 @@ function WebGLProgram(renderer, cacheKey, parameters, bindingStates) { } else if (vertexLog === '' || fragmentLog === '') { haveDiagnostics = false; } - if (haveDiagnostics) { this.diagnostics = { runnable: runnable, @@ -14197,43 +12564,46 @@ function WebGLProgram(renderer, cacheKey, parameters, bindingStates) { } }; } - } // Clean up + } + + // Clean up + // Crashes in iOS9 and iOS10. #18402 // gl.detachShader( program, glVertexShader ); // gl.detachShader( program, glFragmentShader ); - gl.deleteShader(glVertexShader); - gl.deleteShader(glFragmentShader); // set up caching for uniform locations + gl.deleteShader(glFragmentShader); - let cachedUniforms; + // set up caching for uniform locations + let cachedUniforms; this.getUniforms = function () { if (cachedUniforms === undefined) { cachedUniforms = new WebGLUniforms(gl, program); } - return cachedUniforms; - }; // set up caching for attribute locations + }; + // set up caching for attribute locations let cachedAttributes; - this.getAttributes = function () { if (cachedAttributes === undefined) { cachedAttributes = fetchAttributeLocations(gl, program); } - return cachedAttributes; - }; // free resource + }; + // free resource this.destroy = function () { bindingStates.releaseStatesOfProgram(this); gl.deleteProgram(program); this.program = undefined; - }; // + }; + // this.name = parameters.shaderName; this.id = programIdCount++; @@ -14246,98 +12616,76 @@ function WebGLProgram(renderer, cacheKey, parameters, bindingStates) { } let _id = 0; - class WebGLShaderCache { constructor() { this.shaderCache = new Map(); this.materialCache = new Map(); } - update(material) { const vertexShader = material.vertexShader; const fragmentShader = material.fragmentShader; - const vertexShaderStage = this._getShaderStage(vertexShader); - const fragmentShaderStage = this._getShaderStage(fragmentShader); - const materialShaders = this._getShaderCacheForMaterial(material); - if (materialShaders.has(vertexShaderStage) === false) { materialShaders.add(vertexShaderStage); vertexShaderStage.usedTimes++; } - if (materialShaders.has(fragmentShaderStage) === false) { materialShaders.add(fragmentShaderStage); fragmentShaderStage.usedTimes++; } - return this; } - remove(material) { const materialShaders = this.materialCache.get(material); - for (const shaderStage of materialShaders) { shaderStage.usedTimes--; if (shaderStage.usedTimes === 0) this.shaderCache.delete(shaderStage.code); } - this.materialCache.delete(material); return this; } - getVertexShaderID(material) { return this._getShaderStage(material.vertexShader).id; } - getFragmentShaderID(material) { return this._getShaderStage(material.fragmentShader).id; } - dispose() { this.shaderCache.clear(); this.materialCache.clear(); } - _getShaderCacheForMaterial(material) { const cache = this.materialCache; - - if (cache.has(material) === false) { - cache.set(material, new Set()); + let set = cache.get(material); + if (set === undefined) { + set = new Set(); + cache.set(material, set); } - - return cache.get(material); + return set; } - _getShaderStage(code) { const cache = this.shaderCache; - - if (cache.has(code) === false) { - const stage = new WebGLShaderStage(code); + let stage = cache.get(code); + if (stage === undefined) { + stage = new WebGLShaderStage(code); cache.set(code, stage); } - - return cache.get(code); + return stage; } - } - class WebGLShaderStage { constructor(code) { this.id = _id++; this.code = code; this.usedTimes = 0; } - } function WebGLPrograms(renderer, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping) { const _programLayers = new Layers(); - const _customShaders = new WebGLShaderCache(); - const programs = []; const isWebGL2 = capabilities.isWebGL2; const logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer; @@ -14360,35 +12708,37 @@ function WebGLPrograms(renderer, cubemaps, cubeuvmaps, extensions, capabilities, ShadowMaterial: 'shadow', SpriteMaterial: 'sprite' }; - function getParameters(material, lights, shadows, scene, object) { const fog = scene.fog; const geometry = object.geometry; const environment = material.isMeshStandardMaterial ? scene.environment : null; const envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || environment); const envMapCubeUVHeight = !!envMap && envMap.mapping === CubeUVReflectionMapping ? envMap.image.height : null; - const shaderID = shaderIDs[material.type]; // heuristics to create shader parameters according to lights in the scene + const shaderID = shaderIDs[material.type]; + + // heuristics to create shader parameters according to lights in the scene // (not to blow over maxLights budget) if (material.precision !== null) { precision = capabilities.getMaxPrecision(material.precision); - if (precision !== material.precision) { console.warn('THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.'); } - } // + } + // const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color; const morphTargetsCount = morphAttribute !== undefined ? morphAttribute.length : 0; let morphTextureStride = 0; if (geometry.morphAttributes.position !== undefined) morphTextureStride = 1; if (geometry.morphAttributes.normal !== undefined) morphTextureStride = 2; - if (geometry.morphAttributes.color !== undefined) morphTextureStride = 3; // + if (geometry.morphAttributes.color !== undefined) morphTextureStride = 3; + + // let vertexShader, fragmentShader; let customVertexShaderID, customFragmentShaderID; - if (shaderID) { const shader = ShaderLib[shaderID]; vertexShader = shader.vertexShader; @@ -14396,13 +12746,10 @@ function WebGLPrograms(renderer, cubemaps, cubeuvmaps, extensions, capabilities, } else { vertexShader = material.vertexShader; fragmentShader = material.fragmentShader; - _customShaders.update(material); - customVertexShaderID = _customShaders.getVertexShaderID(material); customFragmentShaderID = _customShaders.getFragmentShaderID(material); } - const currentRenderTarget = renderer.getRenderTarget(); const useAlphaTest = material.alphaTest > 0; const useClearcoat = material.clearcoat > 0; @@ -14480,11 +12827,13 @@ function WebGLPrograms(renderer, cubemaps, cubeuvmaps, extensions, capabilities, numDirLights: lights.directional.length, numPointLights: lights.point.length, numSpotLights: lights.spot.length, + numSpotLightMaps: lights.spotLightMap.length, numRectAreaLights: lights.rectArea.length, numHemiLights: lights.hemi.length, numDirLightShadows: lights.directionalShadowMap.length, numPointLightShadows: lights.pointShadowMap.length, numSpotLightShadows: lights.spotShadowMap.length, + numSpotLightShadowsWithMaps: lights.numSpotLightShadowsWithMaps, numClippingPlanes: clipping.numPlanes, numClipIntersection: clipping.numIntersection, dithering: material.dithering, @@ -14509,34 +12858,28 @@ function WebGLPrograms(renderer, cubemaps, cubeuvmaps, extensions, capabilities, }; return parameters; } - function getProgramCacheKey(parameters) { const array = []; - if (parameters.shaderID) { array.push(parameters.shaderID); } else { array.push(parameters.customVertexShaderID); array.push(parameters.customFragmentShaderID); } - if (parameters.defines !== undefined) { for (const name in parameters.defines) { array.push(name); array.push(parameters.defines[name]); } } - if (parameters.isRawShaderMaterial === false) { getProgramCacheKeyParameters(array, parameters); getProgramCacheKeyBooleans(array, parameters); array.push(renderer.outputEncoding); } - array.push(parameters.customProgramCacheKey); return array.join(); } - function getProgramCacheKeyParameters(array, parameters) { array.push(parameters.precision); array.push(parameters.outputEncoding); @@ -14551,21 +12894,21 @@ function WebGLPrograms(renderer, cubemaps, cubeuvmaps, extensions, capabilities, array.push(parameters.numDirLights); array.push(parameters.numPointLights); array.push(parameters.numSpotLights); + array.push(parameters.numSpotLightMaps); array.push(parameters.numHemiLights); array.push(parameters.numRectAreaLights); array.push(parameters.numDirLightShadows); array.push(parameters.numPointLightShadows); array.push(parameters.numSpotLightShadows); + array.push(parameters.numSpotLightShadowsWithMaps); array.push(parameters.shadowMapType); array.push(parameters.toneMapping); array.push(parameters.numClippingPlanes); array.push(parameters.numClipIntersection); array.push(parameters.depthPacking); } - function getProgramCacheKeyBooleans(array, parameters) { _programLayers.disableAll(); - if (parameters.isWebGL2) _programLayers.enable(0); if (parameters.supportsVertexTextures) _programLayers.enable(1); if (parameters.instancing) _programLayers.enable(2); @@ -14599,92 +12942,81 @@ function WebGLPrograms(renderer, cubemaps, cubeuvmaps, extensions, capabilities, if (parameters.vertexUvs) _programLayers.enable(30); if (parameters.vertexTangents) _programLayers.enable(31); if (parameters.uvsVertexOnly) _programLayers.enable(32); - if (parameters.fog) _programLayers.enable(33); array.push(_programLayers.mask); - _programLayers.disableAll(); - - if (parameters.useFog) _programLayers.enable(0); - if (parameters.flatShading) _programLayers.enable(1); - if (parameters.logarithmicDepthBuffer) _programLayers.enable(2); - if (parameters.skinning) _programLayers.enable(3); - if (parameters.morphTargets) _programLayers.enable(4); - if (parameters.morphNormals) _programLayers.enable(5); - if (parameters.morphColors) _programLayers.enable(6); - if (parameters.premultipliedAlpha) _programLayers.enable(7); - if (parameters.shadowMapEnabled) _programLayers.enable(8); - if (parameters.physicallyCorrectLights) _programLayers.enable(9); - if (parameters.doubleSided) _programLayers.enable(10); - if (parameters.flipSided) _programLayers.enable(11); - if (parameters.useDepthPacking) _programLayers.enable(12); - if (parameters.dithering) _programLayers.enable(13); - if (parameters.specularIntensityMap) _programLayers.enable(14); - if (parameters.specularColorMap) _programLayers.enable(15); - if (parameters.transmission) _programLayers.enable(16); - if (parameters.transmissionMap) _programLayers.enable(17); - if (parameters.thicknessMap) _programLayers.enable(18); - if (parameters.sheen) _programLayers.enable(19); - if (parameters.sheenColorMap) _programLayers.enable(20); - if (parameters.sheenRoughnessMap) _programLayers.enable(21); - if (parameters.decodeVideoTexture) _programLayers.enable(22); - if (parameters.opaque) _programLayers.enable(23); + if (parameters.fog) _programLayers.enable(0); + if (parameters.useFog) _programLayers.enable(1); + if (parameters.flatShading) _programLayers.enable(2); + if (parameters.logarithmicDepthBuffer) _programLayers.enable(3); + if (parameters.skinning) _programLayers.enable(4); + if (parameters.morphTargets) _programLayers.enable(5); + if (parameters.morphNormals) _programLayers.enable(6); + if (parameters.morphColors) _programLayers.enable(7); + if (parameters.premultipliedAlpha) _programLayers.enable(8); + if (parameters.shadowMapEnabled) _programLayers.enable(9); + if (parameters.physicallyCorrectLights) _programLayers.enable(10); + if (parameters.doubleSided) _programLayers.enable(11); + if (parameters.flipSided) _programLayers.enable(12); + if (parameters.useDepthPacking) _programLayers.enable(13); + if (parameters.dithering) _programLayers.enable(14); + if (parameters.specularIntensityMap) _programLayers.enable(15); + if (parameters.specularColorMap) _programLayers.enable(16); + if (parameters.transmission) _programLayers.enable(17); + if (parameters.transmissionMap) _programLayers.enable(18); + if (parameters.thicknessMap) _programLayers.enable(19); + if (parameters.sheen) _programLayers.enable(20); + if (parameters.sheenColorMap) _programLayers.enable(21); + if (parameters.sheenRoughnessMap) _programLayers.enable(22); + if (parameters.decodeVideoTexture) _programLayers.enable(23); + if (parameters.opaque) _programLayers.enable(24); array.push(_programLayers.mask); } - function getUniforms(material) { const shaderID = shaderIDs[material.type]; let uniforms; - if (shaderID) { const shader = ShaderLib[shaderID]; uniforms = UniformsUtils.clone(shader.uniforms); } else { uniforms = material.uniforms; } - return uniforms; } - function acquireProgram(parameters, cacheKey) { - let program; // Check if code has been already compiled + let program; + // Check if code has been already compiled for (let p = 0, pl = programs.length; p < pl; p++) { const preexistingProgram = programs[p]; - if (preexistingProgram.cacheKey === cacheKey) { program = preexistingProgram; ++program.usedTimes; break; } } - if (program === undefined) { program = new WebGLProgram(renderer, cacheKey, parameters, bindingStates); programs.push(program); } - return program; } - function releaseProgram(program) { if (--program.usedTimes === 0) { // Remove from unordered set const i = programs.indexOf(program); programs[i] = programs[programs.length - 1]; - programs.pop(); // Free WebGL resources + programs.pop(); + // Free WebGL resources program.destroy(); } } - function releaseShaderCache(material) { _customShaders.remove(material); } - function dispose() { _customShaders.dispose(); } - return { getParameters: getParameters, getProgramCacheKey: getProgramCacheKey, @@ -14700,30 +13032,23 @@ function WebGLPrograms(renderer, cubemaps, cubeuvmaps, extensions, capabilities, function WebGLProperties() { let properties = new WeakMap(); - function get(object) { let map = properties.get(object); - if (map === undefined) { map = {}; properties.set(object, map); } - return map; } - function remove(object) { properties.delete(object); } - function update(object, key, value) { properties.get(object)[key] = value; } - function dispose() { properties = new WeakMap(); } - return { get: get, remove: remove, @@ -14745,7 +13070,6 @@ function painterSortStable(a, b) { return a.id - b.id; } } - function reversePainterSortStable(a, b) { if (a.groupOrder !== b.groupOrder) { return a.groupOrder - b.groupOrder; @@ -14757,24 +13081,20 @@ function reversePainterSortStable(a, b) { return a.id - b.id; } } - function WebGLRenderList() { const renderItems = []; let renderItemsIndex = 0; const opaque = []; const transmissive = []; const transparent = []; - function init() { renderItemsIndex = 0; opaque.length = 0; transmissive.length = 0; transparent.length = 0; } - function getNextRenderItem(object, geometry, material, groupOrder, z, group) { let renderItem = renderItems[renderItemsIndex]; - if (renderItem === undefined) { renderItem = { id: object.id, @@ -14797,14 +13117,11 @@ function WebGLRenderList() { renderItem.z = z; renderItem.group = group; } - renderItemsIndex++; return renderItem; } - function push(object, geometry, material, groupOrder, z, group) { const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group); - if (material.transmission > 0.0) { transmissive.push(renderItem); } else if (material.transparent === true) { @@ -14813,10 +13130,8 @@ function WebGLRenderList() { opaque.push(renderItem); } } - function unshift(object, geometry, material, groupOrder, z, group) { const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group); - if (material.transmission > 0.0) { transmissive.unshift(renderItem); } else if (material.transparent === true) { @@ -14825,15 +13140,14 @@ function WebGLRenderList() { opaque.unshift(renderItem); } } - function sort(customOpaqueSort, customTransparentSort) { if (opaque.length > 1) opaque.sort(customOpaqueSort || painterSortStable); if (transmissive.length > 1) transmissive.sort(customTransparentSort || reversePainterSortStable); if (transparent.length > 1) transparent.sort(customTransparentSort || reversePainterSortStable); } - function finish() { // Clear references from inactive renderItems in the list + for (let i = renderItemsIndex, il = renderItems.length; i < il; i++) { const renderItem = renderItems[i]; if (renderItem.id === null) break; @@ -14844,7 +13158,6 @@ function WebGLRenderList() { renderItem.group = null; } } - return { opaque: opaque, transmissive: transmissive, @@ -14856,32 +13169,27 @@ function WebGLRenderList() { sort: sort }; } - function WebGLRenderLists() { let lists = new WeakMap(); - function get(scene, renderCallDepth) { + const listArray = lists.get(scene); let list; - - if (lists.has(scene) === false) { + if (listArray === undefined) { list = new WebGLRenderList(); lists.set(scene, [list]); } else { - if (renderCallDepth >= lists.get(scene).length) { + if (renderCallDepth >= listArray.length) { list = new WebGLRenderList(); - lists.get(scene).push(list); + listArray.push(list); } else { - list = lists.get(scene)[renderCallDepth]; + list = listArray[renderCallDepth]; } } - return list; } - function dispose() { lists = new WeakMap(); } - return { get: get, dispose: dispose @@ -14895,9 +13203,7 @@ function UniformsCache() { if (lights[light.id] !== undefined) { return lights[light.id]; } - let uniforms; - switch (light.type) { case 'DirectionalLight': uniforms = { @@ -14905,7 +13211,6 @@ function UniformsCache() { color: new Color() }; break; - case 'SpotLight': uniforms = { position: new Vector3(), @@ -14917,7 +13222,6 @@ function UniformsCache() { decay: 0 }; break; - case 'PointLight': uniforms = { position: new Vector3(), @@ -14926,7 +13230,6 @@ function UniformsCache() { decay: 0 }; break; - case 'HemisphereLight': uniforms = { direction: new Vector3(), @@ -14934,7 +13237,6 @@ function UniformsCache() { groundColor: new Color() }; break; - case 'RectAreaLight': uniforms = { color: new Color(), @@ -14944,13 +13246,11 @@ function UniformsCache() { }; break; } - lights[light.id] = uniforms; return uniforms; } }; } - function ShadowUniformsCache() { const lights = {}; return { @@ -14958,9 +13258,7 @@ function ShadowUniformsCache() { if (lights[light.id] !== undefined) { return lights[light.id]; } - let uniforms; - switch (light.type) { case 'DirectionalLight': uniforms = { @@ -14970,7 +13268,6 @@ function ShadowUniformsCache() { shadowMapSize: new Vector2() }; break; - case 'SpotLight': uniforms = { shadowBias: 0, @@ -14979,7 +13276,6 @@ function ShadowUniformsCache() { shadowMapSize: new Vector2() }; break; - case 'PointLight': uniforms = { shadowBias: 0, @@ -14990,6 +13286,7 @@ function ShadowUniformsCache() { shadowCameraFar: 1000 }; break; + // TODO (abelnation): set RectAreaLight shadow uniforms } @@ -14998,13 +13295,10 @@ function ShadowUniformsCache() { } }; } - let nextVersion = 0; - -function shadowCastingLightsFirst(lightA, lightB) { - return (lightB.castShadow ? 1 : 0) - (lightA.castShadow ? 1 : 0); +function shadowCastingAndTexturingLightsFirst(lightA, lightB) { + return (lightB.castShadow ? 2 : 0) - (lightA.castShadow ? 2 : 0) + (lightB.map ? 1 : 0) - (lightA.map ? 1 : 0); } - function WebGLLights(extensions, capabilities) { const cache = new UniformsCache(); const shadowCache = ShadowUniformsCache(); @@ -15018,7 +13312,8 @@ function WebGLLights(extensions, capabilities) { hemiLength: -1, numDirectionalShadows: -1, numPointShadows: -1, - numSpotShadows: -1 + numSpotShadows: -1, + numSpotMaps: -1 }, ambient: [0, 0, 0], probe: [], @@ -15027,9 +13322,10 @@ function WebGLLights(extensions, capabilities) { directionalShadowMap: [], directionalShadowMatrix: [], spot: [], + spotLightMap: [], spotShadow: [], spotShadowMap: [], - spotShadowMatrix: [], + spotLightMatrix: [], rectArea: [], rectAreaLTC1: null, rectAreaLTC2: null, @@ -15037,22 +13333,18 @@ function WebGLLights(extensions, capabilities) { pointShadow: [], pointShadowMap: [], pointShadowMatrix: [], - hemi: [] + hemi: [], + numSpotLightShadowsWithMaps: 0 }; - for (let i = 0; i < 9; i++) state.probe.push(new Vector3()); - const vector3 = new Vector3(); const matrix4 = new Matrix4(); const matrix42 = new Matrix4(); - function setup(lights, physicallyCorrectLights) { let r = 0, - g = 0, - b = 0; - + g = 0, + b = 0; for (let i = 0; i < 9; i++) state.probe[i].set(0, 0, 0); - let directionalLength = 0; let pointLength = 0; let spotLength = 0; @@ -15061,17 +13353,20 @@ function WebGLLights(extensions, capabilities) { let numDirectionalShadows = 0; let numPointShadows = 0; let numSpotShadows = 0; - lights.sort(shadowCastingLightsFirst); // artist-friendly light intensity scaling factor + let numSpotMaps = 0; + let numSpotShadowsWithMaps = 0; - const scaleFactor = physicallyCorrectLights !== true ? Math.PI : 1; + // ordering : [shadow casting + map texturing, map texturing, shadow casting, none ] + lights.sort(shadowCastingAndTexturingLightsFirst); + // artist-friendly light intensity scaling factor + const scaleFactor = physicallyCorrectLights !== true ? Math.PI : 1; for (let i = 0, l = lights.length; i < l; i++) { const light = lights[i]; const color = light.color; const intensity = light.intensity; const distance = light.distance; const shadowMap = light.shadow && light.shadow.map ? light.shadow.map.texture : null; - if (light.isAmbientLight) { r += color.r * intensity * scaleFactor; g += color.g * intensity * scaleFactor; @@ -15083,7 +13378,6 @@ function WebGLLights(extensions, capabilities) { } else if (light.isDirectionalLight) { const uniforms = cache.get(light); uniforms.color.copy(light.color).multiplyScalar(light.intensity * scaleFactor); - if (light.castShadow) { const shadow = light.shadow; const shadowUniforms = shadowCache.get(light); @@ -15096,7 +13390,6 @@ function WebGLLights(extensions, capabilities) { state.directionalShadowMatrix[directionalLength] = light.shadow.matrix; numDirectionalShadows++; } - state.directional[directionalLength] = uniforms; directionalLength++; } else if (light.isSpotLight) { @@ -15107,9 +13400,19 @@ function WebGLLights(extensions, capabilities) { uniforms.coneCos = Math.cos(light.angle); uniforms.penumbraCos = Math.cos(light.angle * (1 - light.penumbra)); uniforms.decay = light.decay; - + state.spot[spotLength] = uniforms; + const shadow = light.shadow; + if (light.map) { + state.spotLightMap[numSpotMaps] = light.map; + numSpotMaps++; + + // make sure the lightMatrix is up to date + // TODO : do it if required only + shadow.updateMatrices(light); + if (light.castShadow) numSpotShadowsWithMaps++; + } + state.spotLightMatrix[spotLength] = shadow.matrix; if (light.castShadow) { - const shadow = light.shadow; const shadowUniforms = shadowCache.get(light); shadowUniforms.shadowBias = shadow.bias; shadowUniforms.shadowNormalBias = shadow.normalBias; @@ -15117,17 +13420,11 @@ function WebGLLights(extensions, capabilities) { shadowUniforms.shadowMapSize = shadow.mapSize; state.spotShadow[spotLength] = shadowUniforms; state.spotShadowMap[spotLength] = shadowMap; - state.spotShadowMatrix[spotLength] = light.shadow.matrix; numSpotShadows++; } - - state.spot[spotLength] = uniforms; spotLength++; } else if (light.isRectAreaLight) { - const uniforms = 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 - + const uniforms = cache.get(light); uniforms.color.copy(color).multiplyScalar(intensity); uniforms.halfWidth.set(light.width * 0.5, 0.0, 0.0); uniforms.halfHeight.set(0.0, light.height * 0.5, 0.0); @@ -15138,7 +13435,6 @@ function WebGLLights(extensions, capabilities) { uniforms.color.copy(light.color).multiplyScalar(light.intensity * scaleFactor); uniforms.distance = light.distance; uniforms.decay = light.decay; - if (light.castShadow) { const shadow = light.shadow; const shadowUniforms = shadowCache.get(light); @@ -15153,7 +13449,6 @@ function WebGLLights(extensions, capabilities) { state.pointShadowMatrix[pointLength] = light.shadow.matrix; numPointShadows++; } - state.point[pointLength] = uniforms; pointLength++; } else if (light.isHemisphereLight) { @@ -15164,14 +13459,15 @@ function WebGLLights(extensions, capabilities) { hemiLength++; } } - 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; @@ -15183,13 +13479,11 @@ function WebGLLights(extensions, capabilities) { } } } - state.ambient[0] = r; state.ambient[1] = g; state.ambient[2] = b; const 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) { + 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 || hash.numSpotMaps !== numSpotMaps) { state.directional.length = directionalLength; state.spot.length = spotLength; state.rectArea.length = rectAreaLength; @@ -15203,7 +13497,9 @@ function WebGLLights(extensions, capabilities) { state.spotShadowMap.length = numSpotShadows; state.directionalShadowMatrix.length = numDirectionalShadows; state.pointShadowMatrix.length = numPointShadows; - state.spotShadowMatrix.length = numSpotShadows; + state.spotLightMatrix.length = numSpotShadows + numSpotMaps - numSpotShadowsWithMaps; + state.spotLightMap.length = numSpotMaps; + state.numSpotLightShadowsWithMaps = numSpotShadowsWithMaps; hash.directionalLength = directionalLength; hash.pointLength = pointLength; hash.spotLength = spotLength; @@ -15212,10 +13508,10 @@ function WebGLLights(extensions, capabilities) { hash.numDirectionalShadows = numDirectionalShadows; hash.numPointShadows = numPointShadows; hash.numSpotShadows = numSpotShadows; + hash.numSpotMaps = numSpotMaps; state.version = nextVersion++; } } - function setupView(lights, camera) { let directionalLength = 0; let pointLength = 0; @@ -15223,10 +13519,8 @@ function WebGLLights(extensions, capabilities) { let rectAreaLength = 0; let hemiLength = 0; const viewMatrix = camera.matrixWorldInverse; - for (let i = 0, l = lights.length; i < l; i++) { const light = lights[i]; - if (light.isDirectionalLight) { const uniforms = state.directional[directionalLength]; uniforms.direction.setFromMatrixPosition(light.matrixWorld); @@ -15246,8 +13540,9 @@ function WebGLLights(extensions, capabilities) { } else if (light.isRectAreaLight) { const uniforms = state.rectArea[rectAreaLength]; uniforms.position.setFromMatrixPosition(light.matrixWorld); - uniforms.position.applyMatrix4(viewMatrix); // extract local rotation of light to derive width/height half vectors + uniforms.position.applyMatrix4(viewMatrix); + // extract local rotation of light to derive width/height half vectors matrix42.identity(); matrix4.copy(light.matrixWorld); matrix4.premultiply(viewMatrix); @@ -15270,7 +13565,6 @@ function WebGLLights(extensions, capabilities) { } } } - return { setup: setup, setupView: setupView, @@ -15282,28 +13576,22 @@ function WebGLRenderState(extensions, capabilities) { const lights = new WebGLLights(extensions, capabilities); const lightsArray = []; const shadowsArray = []; - function init() { lightsArray.length = 0; shadowsArray.length = 0; } - function pushLight(light) { lightsArray.push(light); } - function pushShadow(shadowLight) { shadowsArray.push(shadowLight); } - function setupLights(physicallyCorrectLights) { lights.setup(lightsArray, physicallyCorrectLights); } - function setupLightsView(camera) { lights.setupView(lightsArray, camera); } - const state = { lightsArray: lightsArray, shadowsArray: shadowsArray, @@ -15318,32 +13606,27 @@ function WebGLRenderState(extensions, capabilities) { pushShadow: pushShadow }; } - function WebGLRenderStates(extensions, capabilities) { let renderStates = new WeakMap(); - function get(scene, renderCallDepth = 0) { + const renderStateArray = renderStates.get(scene); let renderState; - - if (renderStates.has(scene) === false) { + if (renderStateArray === undefined) { renderState = new WebGLRenderState(extensions, capabilities); renderStates.set(scene, [renderState]); } else { - if (renderCallDepth >= renderStates.get(scene).length) { + if (renderCallDepth >= renderStateArray.length) { renderState = new WebGLRenderState(extensions, capabilities); - renderStates.get(scene).push(renderState); + renderStateArray.push(renderState); } else { - renderState = renderStates.get(scene)[renderCallDepth]; + renderState = renderStateArray[renderCallDepth]; } } - return renderState; } - function dispose() { renderStates = new WeakMap(); } - return { get: get, dispose: dispose @@ -15365,7 +13648,6 @@ class MeshDepthMaterial extends Material { this.wireframeLinewidth = 1; this.setValues(parameters); } - copy(source) { super.copy(source); this.depthPacking = source.depthPacking; @@ -15378,7 +13660,6 @@ class MeshDepthMaterial extends Material { this.wireframeLinewidth = source.wireframeLinewidth; return this; } - } class MeshDistanceMaterial extends Material { @@ -15396,7 +13677,6 @@ class MeshDistanceMaterial extends Material { this.displacementBias = 0; this.setValues(parameters); } - copy(source) { super.copy(source); this.referencePosition.copy(source.referencePosition); @@ -15409,7 +13689,6 @@ class MeshDistanceMaterial extends Material { this.displacementBias = source.displacementBias; return this; } - } const vertex = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}"; @@ -15417,17 +13696,15 @@ const fragment = "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nunif function WebGLShadowMap(_renderer, _objects, _capabilities) { let _frustum = new Frustum(); - const _shadowMapSize = new Vector2(), - _viewportSize = new Vector2(), - _viewport = new Vector4(), - _depthMaterial = new MeshDepthMaterial({ - depthPacking: RGBADepthPacking - }), - _distanceMaterial = new MeshDistanceMaterial(), - _materialCache = {}, - _maxTextureSize = _capabilities.maxTextureSize; - + _viewportSize = new Vector2(), + _viewport = new Vector4(), + _depthMaterial = new MeshDepthMaterial({ + depthPacking: RGBADepthPacking + }), + _distanceMaterial = new MeshDistanceMaterial(), + _materialCache = {}, + _maxTextureSize = _capabilities.maxTextureSize; const shadowSide = { 0: BackSide, 1: FrontSide, @@ -15461,62 +13738,47 @@ function WebGLShadowMap(_renderer, _objects, _capabilities) { this.autoUpdate = true; this.needsUpdate = false; this.type = PCFShadowMap; - this.render = function (lights, scene, camera) { if (scope.enabled === false) return; if (scope.autoUpdate === false && scope.needsUpdate === false) return; if (lights.length === 0) return; - const currentRenderTarget = _renderer.getRenderTarget(); - const activeCubeFace = _renderer.getActiveCubeFace(); - const activeMipmapLevel = _renderer.getActiveMipmapLevel(); + const _state = _renderer.state; - const _state = _renderer.state; // Set GL state for depth map. - + // Set GL state for depth map. _state.setBlending(NoBlending); - _state.buffers.color.setClear(1, 1, 1, 1); - _state.buffers.depth.setTest(true); + _state.setScissorTest(false); - _state.setScissorTest(false); // render depth map - + // render depth map for (let i = 0, il = lights.length; i < il; i++) { const light = lights[i]; const shadow = light.shadow; - if (shadow === undefined) { console.warn('THREE.WebGLShadowMap:', light, 'has no shadow.'); continue; } - if (shadow.autoUpdate === false && shadow.needsUpdate === false) continue; - _shadowMapSize.copy(shadow.mapSize); - const shadowFrameExtents = shadow.getFrameExtents(); - _shadowMapSize.multiply(shadowFrameExtents); - _viewportSize.copy(shadow.mapSize); - 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 (_shadowMapSize.y > _maxTextureSize) { _viewportSize.y = Math.floor(_maxTextureSize / shadowFrameExtents.y); _shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y; shadow.mapSize.y = _viewportSize.y; } } - if (shadow.map === null) { const pars = this.type !== VSMShadowMap ? { minFilter: NearestFilter, @@ -15526,118 +13788,94 @@ function WebGLShadowMap(_renderer, _objects, _capabilities) { shadow.map.texture.name = light.name + '.shadowMap'; shadow.camera.updateProjectionMatrix(); } - _renderer.setRenderTarget(shadow.map); - _renderer.clear(); - const viewportCount = shadow.getViewportCount(); - for (let vp = 0; vp < viewportCount; vp++) { const viewport = shadow.getViewport(vp); - _viewport.set(_viewportSize.x * viewport.x, _viewportSize.y * viewport.y, _viewportSize.x * viewport.z, _viewportSize.y * viewport.w); - _state.viewport(_viewport); - shadow.updateMatrices(light, vp); _frustum = shadow.getFrustum(); renderObject(scene, camera, shadow.camera, light, this.type); - } // do blur pass for VSM + } + // do blur pass for VSM if (shadow.isPointLightShadow !== true && this.type === VSMShadowMap) { VSMPass(shadow, camera); } - shadow.needsUpdate = false; } - scope.needsUpdate = false; - _renderer.setRenderTarget(currentRenderTarget, activeCubeFace, activeMipmapLevel); }; - function VSMPass(shadow, camera) { const geometry = _objects.update(fullScreenMesh); - if (shadowMaterialVertical.defines.VSM_SAMPLES !== shadow.blurSamples) { shadowMaterialVertical.defines.VSM_SAMPLES = shadow.blurSamples; shadowMaterialHorizontal.defines.VSM_SAMPLES = shadow.blurSamples; shadowMaterialVertical.needsUpdate = true; shadowMaterialHorizontal.needsUpdate = true; } - if (shadow.mapPass === null) { shadow.mapPass = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y); - } // vertical pass + } + // vertical pass shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture; shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize; shadowMaterialVertical.uniforms.radius.value = shadow.radius; - _renderer.setRenderTarget(shadow.mapPass); - _renderer.clear(); + _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null); - _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null); // horizontal pass - + // horizontal pass shadowMaterialHorizontal.uniforms.shadow_pass.value = shadow.mapPass.texture; shadowMaterialHorizontal.uniforms.resolution.value = shadow.mapSize; shadowMaterialHorizontal.uniforms.radius.value = shadow.radius; - _renderer.setRenderTarget(shadow.map); - _renderer.clear(); - _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialHorizontal, fullScreenMesh, null); } - function getDepthMaterial(object, material, light, shadowCameraNear, shadowCameraFar, type) { let result = null; const customMaterial = light.isPointLight === true ? object.customDistanceMaterial : object.customDepthMaterial; - if (customMaterial !== undefined) { result = customMaterial; } else { result = light.isPointLight === true ? _distanceMaterial : _depthMaterial; } - - if (_renderer.localClippingEnabled && material.clipShadows === true && Array.isArray(material.clippingPlanes) && material.clippingPlanes.length !== 0 || material.displacementMap && material.displacementScale !== 0 || material.alphaMap && material.alphaTest > 0) { + if (_renderer.localClippingEnabled && material.clipShadows === true && Array.isArray(material.clippingPlanes) && material.clippingPlanes.length !== 0 || material.displacementMap && material.displacementScale !== 0 || material.alphaMap && material.alphaTest > 0 || material.map && material.alphaTest > 0) { // in this case we need a unique material instance reflecting the // appropriate state + const keyA = result.uuid, - keyB = material.uuid; + keyB = material.uuid; let materialsForVariant = _materialCache[keyA]; - if (materialsForVariant === undefined) { materialsForVariant = {}; _materialCache[keyA] = materialsForVariant; } - let cachedMaterial = materialsForVariant[keyB]; - if (cachedMaterial === undefined) { cachedMaterial = result.clone(); materialsForVariant[keyB] = cachedMaterial; } - result = cachedMaterial; } - result.visible = material.visible; result.wireframe = material.wireframe; - if (type === VSMShadowMap) { result.side = material.shadowSide !== null ? material.shadowSide : material.side; } else { result.side = material.shadowSide !== null ? material.shadowSide : shadowSide[material.side]; } - result.alphaMap = material.alphaMap; result.alphaTest = material.alphaTest; + result.map = material.map; result.clipShadows = material.clipShadows; result.clippingPlanes = material.clippingPlanes; result.clipIntersection = material.clipIntersection; @@ -15646,51 +13884,38 @@ function WebGLShadowMap(_renderer, _objects, _capabilities) { result.displacementBias = material.displacementBias; result.wireframeLinewidth = material.wireframeLinewidth; result.linewidth = material.linewidth; - if (light.isPointLight === true && result.isMeshDistanceMaterial === true) { result.referencePosition.setFromMatrixPosition(light.matrixWorld); result.nearDistance = shadowCameraNear; result.farDistance = shadowCameraFar; } - return result; } - function renderObject(object, camera, shadowCamera, light, type) { if (object.visible === false) return; const visible = object.layers.test(camera.layers); - 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); - const geometry = _objects.update(object); - const material = object.material; - if (Array.isArray(material)) { const groups = geometry.groups; - for (let k = 0, kl = groups.length; k < kl; k++) { const group = groups[k]; const groupMaterial = material[group.materialIndex]; - if (groupMaterial && groupMaterial.visible) { const depthMaterial = getDepthMaterial(object, groupMaterial, light, shadowCamera.near, shadowCamera.far, type); - _renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, group); } } } else if (material.visible) { const depthMaterial = getDepthMaterial(object, material, light, shadowCamera.near, shadowCamera.far, type); - _renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, null); } } } - const children = object.children; - for (let i = 0, l = children.length; i < l; i++) { renderObject(children[i], camera, shadowCamera, light, type); } @@ -15699,7 +13924,6 @@ function WebGLShadowMap(_renderer, _objects, _capabilities) { function WebGLState(gl, extensions, capabilities) { const isWebGL2 = capabilities.isWebGL2; - function ColorBuffer() { let locked = false; const color = new Vector4(); @@ -15721,9 +13945,7 @@ function WebGLState(gl, extensions, capabilities) { g *= a; b *= a; } - color.set(r, g, b, a); - if (currentColorClear.equals(color) === false) { gl.clearColor(r, g, b, a); currentColorClear.copy(color); @@ -15758,47 +13980,34 @@ function WebGLState(gl, extensions, capabilities) { }, setFunc: function (depthFunc) { if (currentDepthFunc !== depthFunc) { - if (depthFunc) { - switch (depthFunc) { - case NeverDepth: - gl.depthFunc(gl.NEVER); - break; - - case AlwaysDepth: - gl.depthFunc(gl.ALWAYS); - break; - - case LessDepth: - gl.depthFunc(gl.LESS); - break; - - case LessEqualDepth: - gl.depthFunc(gl.LEQUAL); - break; - - case EqualDepth: - gl.depthFunc(gl.EQUAL); - break; - - case GreaterEqualDepth: - gl.depthFunc(gl.GEQUAL); - break; - - case GreaterDepth: - gl.depthFunc(gl.GREATER); - break; - - case NotEqualDepth: - gl.depthFunc(gl.NOTEQUAL); - break; - - default: - gl.depthFunc(gl.LEQUAL); - } - } else { - gl.depthFunc(gl.LEQUAL); + switch (depthFunc) { + case NeverDepth: + gl.depthFunc(gl.NEVER); + break; + case AlwaysDepth: + gl.depthFunc(gl.ALWAYS); + break; + case LessDepth: + gl.depthFunc(gl.LESS); + break; + case LessEqualDepth: + gl.depthFunc(gl.LEQUAL); + break; + case EqualDepth: + gl.depthFunc(gl.EQUAL); + break; + case GreaterEqualDepth: + gl.depthFunc(gl.GEQUAL); + break; + case GreaterDepth: + gl.depthFunc(gl.GREATER); + break; + case NotEqualDepth: + gl.depthFunc(gl.NOTEQUAL); + break; + default: + gl.depthFunc(gl.LEQUAL); } - currentDepthFunc = depthFunc; } }, @@ -15819,7 +14028,6 @@ function WebGLState(gl, extensions, capabilities) { } }; } - function StencilBuffer() { let locked = false; let currentStencilMask = null; @@ -15883,8 +14091,9 @@ function WebGLState(gl, extensions, capabilities) { currentStencilClear = null; } }; - } // + } + // const colorBuffer = new ColorBuffer(); const depthBuffer = new DepthBuffer(); @@ -15914,7 +14123,6 @@ function WebGLState(gl, extensions, capabilities) { let lineWidthAvailable = false; let version = 0; const glVersion = gl.getParameter(gl.VERSION); - if (glVersion.indexOf('WebGL') !== -1) { version = parseFloat(/^WebGL (\d)/.exec(glVersion)[1]); lineWidthAvailable = version >= 1.0; @@ -15922,32 +14130,28 @@ function WebGLState(gl, extensions, capabilities) { version = parseFloat(/^OpenGL ES (\d)/.exec(glVersion)[1]); lineWidthAvailable = version >= 2.0; } - let currentTextureSlot = null; let currentBoundTextures = {}; const scissorParam = gl.getParameter(gl.SCISSOR_BOX); const viewportParam = gl.getParameter(gl.VIEWPORT); const currentScissor = new Vector4().fromArray(scissorParam); const currentViewport = new Vector4().fromArray(viewportParam); - function createTexture(type, target, count) { const data = new Uint8Array(4); // 4 is required to match default unpack alignment of 4. - const texture = gl.createTexture(); gl.bindTexture(type, texture); gl.texParameteri(type, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(type, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - for (let i = 0; i < count; i++) { gl.texImage2D(target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data); } - return texture; } - const emptyTextures = {}; emptyTextures[gl.TEXTURE_2D] = createTexture(gl.TEXTURE_2D, gl.TEXTURE_2D, 1); - emptyTextures[gl.TEXTURE_CUBE_MAP] = createTexture(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6); // init + emptyTextures[gl.TEXTURE_CUBE_MAP] = createTexture(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6); + + // init colorBuffer.setClear(0, 0, 0, 1); depthBuffer.setClear(1); @@ -15957,7 +14161,9 @@ function WebGLState(gl, extensions, capabilities) { setFlipSided(false); setCullFace(CullFaceBack); enable(gl.CULL_FACE); - setBlending(NoBlending); // + setBlending(NoBlending); + + // function enable(id) { if (enabledCapabilities[id] !== true) { @@ -15965,56 +14171,45 @@ function WebGLState(gl, extensions, capabilities) { enabledCapabilities[id] = true; } } - function disable(id) { if (enabledCapabilities[id] !== false) { gl.disable(id); enabledCapabilities[id] = false; } } - function bindFramebuffer(target, framebuffer) { if (currentBoundFramebuffers[target] !== framebuffer) { gl.bindFramebuffer(target, framebuffer); currentBoundFramebuffers[target] = framebuffer; - if (isWebGL2) { // gl.DRAW_FRAMEBUFFER is equivalent to gl.FRAMEBUFFER + if (target === gl.DRAW_FRAMEBUFFER) { currentBoundFramebuffers[gl.FRAMEBUFFER] = framebuffer; } - if (target === gl.FRAMEBUFFER) { currentBoundFramebuffers[gl.DRAW_FRAMEBUFFER] = framebuffer; } } - return true; } - return false; } - function drawBuffers(renderTarget, framebuffer) { let drawBuffers = defaultDrawbuffers; let needsUpdate = false; - if (renderTarget) { drawBuffers = currentDrawbuffers.get(framebuffer); - if (drawBuffers === undefined) { drawBuffers = []; currentDrawbuffers.set(framebuffer, drawBuffers); } - if (renderTarget.isWebGLMultipleRenderTargets) { const textures = renderTarget.texture; - if (drawBuffers.length !== textures.length || drawBuffers[0] !== gl.COLOR_ATTACHMENT0) { for (let i = 0, il = textures.length; i < il; i++) { drawBuffers[i] = gl.COLOR_ATTACHMENT0 + i; } - drawBuffers.length = textures.length; needsUpdate = true; } @@ -16030,7 +14225,6 @@ function WebGLState(gl, extensions, capabilities) { needsUpdate = true; } } - if (needsUpdate) { if (capabilities.isWebGL2) { gl.drawBuffers(drawBuffers); @@ -16039,35 +14233,29 @@ function WebGLState(gl, extensions, capabilities) { } } } - function useProgram(program) { if (currentProgram !== program) { gl.useProgram(program); currentProgram = program; return true; } - return false; } - const equationToGL = { [AddEquation]: gl.FUNC_ADD, [SubtractEquation]: gl.FUNC_SUBTRACT, [ReverseSubtractEquation]: gl.FUNC_REVERSE_SUBTRACT }; - if (isWebGL2) { equationToGL[MinEquation] = gl.MIN; equationToGL[MaxEquation] = gl.MAX; } else { const extension = extensions.get('EXT_blend_minmax'); - if (extension !== null) { equationToGL[MinEquation] = extension.MIN_EXT; equationToGL[MaxEquation] = extension.MAX_EXT; } } - const factorToGL = { [ZeroFactor]: gl.ZERO, [OneFactor]: gl.ONE, @@ -16081,22 +14269,18 @@ function WebGLState(gl, extensions, capabilities) { [OneMinusDstColorFactor]: gl.ONE_MINUS_DST_COLOR, [OneMinusDstAlphaFactor]: gl.ONE_MINUS_DST_ALPHA }; - function setBlending(blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha) { if (blending === NoBlending) { if (currentBlendingEnabled === true) { disable(gl.BLEND); currentBlendingEnabled = false; } - return; } - if (currentBlendingEnabled === false) { enable(gl.BLEND); currentBlendingEnabled = true; } - if (blending !== CustomBlending) { if (blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha) { if (currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation) { @@ -16104,25 +14288,20 @@ function WebGLState(gl, extensions, capabilities) { currentBlendEquation = AddEquation; currentBlendEquationAlpha = AddEquation; } - if (premultipliedAlpha) { switch (blending) { case NormalBlending: gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); break; - case AdditiveBlending: gl.blendFunc(gl.ONE, gl.ONE); break; - case SubtractiveBlending: gl.blendFuncSeparate(gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE); break; - case MultiplyBlending: gl.blendFuncSeparate(gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA); break; - default: console.error('THREE.WebGLState: Invalid blending: ', blending); break; @@ -16132,25 +14311,20 @@ function WebGLState(gl, extensions, capabilities) { case NormalBlending: gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); break; - case AdditiveBlending: gl.blendFunc(gl.SRC_ALPHA, gl.ONE); break; - case SubtractiveBlending: gl.blendFuncSeparate(gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE); break; - case MultiplyBlending: gl.blendFunc(gl.ZERO, gl.SRC_COLOR); break; - default: console.error('THREE.WebGLState: Invalid blending: ', blending); break; } } - currentBlendSrc = null; currentBlendDst = null; currentBlendSrcAlpha = null; @@ -16158,21 +14332,19 @@ function WebGLState(gl, extensions, capabilities) { currentBlending = blending; currentPremultipledAlpha = premultipliedAlpha; } - return; - } // custom blending + } + // custom blending blendEquationAlpha = blendEquationAlpha || blendEquation; blendSrcAlpha = blendSrcAlpha || blendSrc; blendDstAlpha = blendDstAlpha || blendDst; - if (blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha) { gl.blendEquationSeparate(equationToGL[blendEquation], equationToGL[blendEquationAlpha]); currentBlendEquation = blendEquation; currentBlendEquationAlpha = blendEquationAlpha; } - if (blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha) { gl.blendFuncSeparate(factorToGL[blendSrc], factorToGL[blendDst], factorToGL[blendSrcAlpha], factorToGL[blendDstAlpha]); currentBlendSrc = blendSrc; @@ -16180,11 +14352,9 @@ function WebGLState(gl, extensions, capabilities) { currentBlendSrcAlpha = blendSrcAlpha; currentBlendDstAlpha = blendDstAlpha; } - currentBlending = blending; - currentPremultipledAlpha = null; + currentPremultipledAlpha = false; } - function setMaterial(material, frontFaceCW) { material.side === DoubleSide ? disable(gl.CULL_FACE) : enable(gl.CULL_FACE); let flipSided = material.side === BackSide; @@ -16197,17 +14367,16 @@ function WebGLState(gl, extensions, capabilities) { colorBuffer.setMask(material.colorWrite); const stencilWrite = material.stencilWrite; stencilBuffer.setTest(stencilWrite); - if (stencilWrite) { stencilBuffer.setMask(material.stencilWriteMask); stencilBuffer.setFunc(material.stencilFunc, material.stencilRef, material.stencilFuncMask); stencilBuffer.setOp(material.stencilFail, material.stencilZFail, material.stencilZPass); } - setPolygonOffset(material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits); material.alphaToCoverage === true ? enable(gl.SAMPLE_ALPHA_TO_COVERAGE) : disable(gl.SAMPLE_ALPHA_TO_COVERAGE); - } // + } + // function setFlipSided(flipSided) { if (currentFlipSided !== flipSided) { @@ -16216,15 +14385,12 @@ function WebGLState(gl, extensions, capabilities) { } else { gl.frontFace(gl.CCW); } - currentFlipSided = flipSided; } } - function setCullFace(cullFace) { if (cullFace !== CullFaceNone) { enable(gl.CULL_FACE); - if (cullFace !== currentCullFace) { if (cullFace === CullFaceBack) { gl.cullFace(gl.BACK); @@ -16237,21 +14403,17 @@ function WebGLState(gl, extensions, capabilities) { } else { disable(gl.CULL_FACE); } - currentCullFace = cullFace; } - function setLineWidth(width) { if (width !== currentLineWidth) { if (lineWidthAvailable) gl.lineWidth(width); currentLineWidth = width; } } - function setPolygonOffset(polygonOffset, factor, units) { if (polygonOffset) { enable(gl.POLYGON_OFFSET_FILL); - if (currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units) { gl.polygonOffset(factor, units); currentPolygonOffsetFactor = factor; @@ -16261,57 +14423,57 @@ function WebGLState(gl, extensions, capabilities) { disable(gl.POLYGON_OFFSET_FILL); } } - function setScissorTest(scissorTest) { if (scissorTest) { enable(gl.SCISSOR_TEST); } else { disable(gl.SCISSOR_TEST); } - } // texture + } + // texture function activeTexture(webglSlot) { if (webglSlot === undefined) webglSlot = gl.TEXTURE0 + maxTextures - 1; - if (currentTextureSlot !== webglSlot) { gl.activeTexture(webglSlot); currentTextureSlot = webglSlot; } } - - function bindTexture(webglType, webglTexture) { - if (currentTextureSlot === null) { - activeTexture(); + function bindTexture(webglType, webglTexture, webglSlot) { + if (webglSlot === undefined) { + if (currentTextureSlot === null) { + webglSlot = gl.TEXTURE0 + maxTextures - 1; + } else { + webglSlot = currentTextureSlot; + } } - - let boundTexture = currentBoundTextures[currentTextureSlot]; - + let boundTexture = currentBoundTextures[webglSlot]; if (boundTexture === undefined) { boundTexture = { type: undefined, texture: undefined }; - currentBoundTextures[currentTextureSlot] = boundTexture; + currentBoundTextures[webglSlot] = boundTexture; } - if (boundTexture.type !== webglType || boundTexture.texture !== webglTexture) { + if (currentTextureSlot !== webglSlot) { + gl.activeTexture(webglSlot); + currentTextureSlot = webglSlot; + } gl.bindTexture(webglType, webglTexture || emptyTextures[webglType]); boundTexture.type = webglType; boundTexture.texture = webglTexture; } } - function unbindTexture() { const boundTexture = currentBoundTextures[currentTextureSlot]; - if (boundTexture !== undefined && boundTexture.type !== undefined) { gl.bindTexture(boundTexture.type, null); boundTexture.type = undefined; boundTexture.texture = undefined; } } - function compressedTexImage2D() { try { gl.compressedTexImage2D.apply(gl, arguments); @@ -16319,7 +14481,13 @@ function WebGLState(gl, extensions, capabilities) { console.error('THREE.WebGLState:', error); } } - + function compressedTexImage3D() { + try { + gl.compressedTexImage3D.apply(gl, arguments); + } catch (error) { + console.error('THREE.WebGLState:', error); + } + } function texSubImage2D() { try { gl.texSubImage2D.apply(gl, arguments); @@ -16327,7 +14495,6 @@ function WebGLState(gl, extensions, capabilities) { console.error('THREE.WebGLState:', error); } } - function texSubImage3D() { try { gl.texSubImage3D.apply(gl, arguments); @@ -16335,7 +14502,6 @@ function WebGLState(gl, extensions, capabilities) { console.error('THREE.WebGLState:', error); } } - function compressedTexSubImage2D() { try { gl.compressedTexSubImage2D.apply(gl, arguments); @@ -16343,7 +14509,13 @@ function WebGLState(gl, extensions, capabilities) { console.error('THREE.WebGLState:', error); } } - + function compressedTexSubImage3D() { + try { + gl.compressedTexSubImage3D.apply(gl, arguments); + } catch (error) { + console.error('THREE.WebGLState:', error); + } + } function texStorage2D() { try { gl.texStorage2D.apply(gl, arguments); @@ -16351,7 +14523,6 @@ function WebGLState(gl, extensions, capabilities) { console.error('THREE.WebGLState:', error); } } - function texStorage3D() { try { gl.texStorage3D.apply(gl, arguments); @@ -16359,7 +14530,6 @@ function WebGLState(gl, extensions, capabilities) { console.error('THREE.WebGLState:', error); } } - function texImage2D() { try { gl.texImage2D.apply(gl, arguments); @@ -16367,15 +14537,15 @@ function WebGLState(gl, extensions, capabilities) { console.error('THREE.WebGLState:', error); } } - function texImage3D() { try { gl.texImage3D.apply(gl, arguments); } catch (error) { console.error('THREE.WebGLState:', error); } - } // + } + // function scissor(scissor) { if (currentScissor.equals(scissor) === false) { @@ -16383,44 +14553,40 @@ function WebGLState(gl, extensions, capabilities) { currentScissor.copy(scissor); } } - function viewport(viewport) { if (currentViewport.equals(viewport) === false) { gl.viewport(viewport.x, viewport.y, viewport.z, viewport.w); currentViewport.copy(viewport); } } - function updateUBOMapping(uniformsGroup, program) { let mapping = uboProgamMap.get(program); - if (mapping === undefined) { mapping = new WeakMap(); uboProgamMap.set(program, mapping); } - let blockIndex = mapping.get(uniformsGroup); - if (blockIndex === undefined) { blockIndex = gl.getUniformBlockIndex(program, uniformsGroup.name); mapping.set(uniformsGroup, blockIndex); } } - function uniformBlockBinding(uniformsGroup, program) { const mapping = uboProgamMap.get(program); const blockIndex = mapping.get(uniformsGroup); - if (uboBindings.get(uniformsGroup) !== blockIndex) { // bind shader specific block index to global block point + gl.uniformBlockBinding(program, blockIndex, uniformsGroup.__bindingPointIndex); uboBindings.set(uniformsGroup, blockIndex); } - } // + } + // function reset() { // reset state + gl.disable(gl.BLEND); gl.disable(gl.CULL_FACE); gl.disable(gl.DEPTH_TEST); @@ -16445,16 +14611,16 @@ function WebGLState(gl, extensions, capabilities) { gl.polygonOffset(0, 0); gl.activeTexture(gl.TEXTURE0); gl.bindFramebuffer(gl.FRAMEBUFFER, null); - if (isWebGL2 === true) { gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null); gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null); } - gl.useProgram(null); gl.lineWidth(1); gl.scissor(0, 0, gl.canvas.width, gl.canvas.height); - gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); // reset internals + gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); + + // reset internals enabledCapabilities = {}; currentTextureSlot = null; @@ -16483,7 +14649,6 @@ function WebGLState(gl, extensions, capabilities) { depthBuffer.reset(); stencilBuffer.reset(); } - return { buffers: { color: colorBuffer, @@ -16506,6 +14671,7 @@ function WebGLState(gl, extensions, capabilities) { bindTexture: bindTexture, unbindTexture: unbindTexture, compressedTexImage2D: compressedTexImage2D, + compressedTexImage3D: compressedTexImage3D, texImage2D: texImage2D, texImage3D: texImage3D, updateUBOMapping: updateUBOMapping, @@ -16515,6 +14681,7 @@ function WebGLState(gl, extensions, capabilities) { texSubImage2D: texSubImage2D, texSubImage3D: texSubImage3D, compressedTexSubImage2D: compressedTexSubImage2D, + compressedTexSubImage3D: compressedTexSubImage3D, scissor: scissor, viewport: viewport, reset: reset @@ -16528,47 +14695,52 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, const maxTextureSize = capabilities.maxTextureSize; const maxSamples = capabilities.maxSamples; const multisampledRTTExt = extensions.has('WEBGL_multisampled_render_to_texture') ? extensions.get('WEBGL_multisampled_render_to_texture') : null; - const supportsInvalidateFramebuffer = /OculusBrowser/g.test(navigator.userAgent); - + const supportsInvalidateFramebuffer = typeof navigator === 'undefined' ? false : /OculusBrowser/g.test(navigator.userAgent); const _videoTextures = new WeakMap(); - let _canvas; - const _sources = new WeakMap(); // maps WebglTexture objects to instances of Source + // 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). - let useOffscreenCanvas = false; - try { - useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined' // eslint-disable-next-line compat/compat + useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined' + // eslint-disable-next-line compat/compat && new OffscreenCanvas(1, 1).getContext('2d') !== null; - } catch (err) {// Ignore any errors - } + } catch (err) { + // Ignore any errors + } function createCanvas(width, height) { // Use OffscreenCanvas when available. Specially needed in web workers - return useOffscreenCanvas ? // eslint-disable-next-line compat/compat + + return useOffscreenCanvas ? + // eslint-disable-next-line compat/compat new OffscreenCanvas(width, height) : createElementNS('canvas'); } - function resizeImage(image, needsPowerOfTwo, needsNewCanvas, maxSize) { - let scale = 1; // handle case if texture exceeds max size + let scale = 1; + + // handle case if texture exceeds max size if (image.width > maxSize || image.height > maxSize) { scale = maxSize / Math.max(image.width, image.height); - } // only perform resize if necessary + } + // only perform resize if necessary 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) { const floor = needsPowerOfTwo ? floorPowerOfTwo : Math.floor; const width = floor(scale * image.width); const height = floor(scale * image.height); - if (_canvas === undefined) _canvas = createCanvas(width, height); // cube textures can't reuse the same canvas + if (_canvas === undefined) _canvas = createCanvas(width, height); + + // cube textures can't reuse the same canvas const canvas = needsNewCanvas ? createCanvas(width, height) : _canvas; canvas.width = width; @@ -16581,223 +14753,190 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, if ('data' in image) { console.warn('THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').'); } - return image; } } - return image; } - function isPowerOfTwo$1(image) { return isPowerOfTwo(image.width) && isPowerOfTwo(image.height); } - function textureNeedsPowerOfTwo(texture) { if (isWebGL2) return false; return texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping || texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; } - function textureNeedsGenerateMipmaps(texture, supportsMips) { return texture.generateMipmaps && supportsMips && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; } - function generateMipmap(target) { _gl.generateMipmap(target); } - - function getInternalFormat(internalFormatName, glFormat, glType, encoding, isVideoTexture = false) { + function getInternalFormat(internalFormatName, glFormat, glType, encoding, forceLinearEncoding = false) { if (isWebGL2 === false) return glFormat; - if (internalFormatName !== null) { if (_gl[internalFormatName] !== undefined) return _gl[internalFormatName]; console.warn('THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \'' + internalFormatName + '\''); } - let internalFormat = glFormat; - if (glFormat === _gl.RED) { if (glType === _gl.FLOAT) internalFormat = _gl.R32F; if (glType === _gl.HALF_FLOAT) internalFormat = _gl.R16F; if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.R8; } - if (glFormat === _gl.RG) { if (glType === _gl.FLOAT) internalFormat = _gl.RG32F; if (glType === _gl.HALF_FLOAT) internalFormat = _gl.RG16F; if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.RG8; } - if (glFormat === _gl.RGBA) { if (glType === _gl.FLOAT) internalFormat = _gl.RGBA32F; if (glType === _gl.HALF_FLOAT) internalFormat = _gl.RGBA16F; - if (glType === _gl.UNSIGNED_BYTE) internalFormat = encoding === sRGBEncoding && isVideoTexture === false ? _gl.SRGB8_ALPHA8 : _gl.RGBA8; + if (glType === _gl.UNSIGNED_BYTE) internalFormat = encoding === sRGBEncoding && forceLinearEncoding === false ? _gl.SRGB8_ALPHA8 : _gl.RGBA8; if (glType === _gl.UNSIGNED_SHORT_4_4_4_4) internalFormat = _gl.RGBA4; if (glType === _gl.UNSIGNED_SHORT_5_5_5_1) internalFormat = _gl.RGB5_A1; } - if (internalFormat === _gl.R16F || internalFormat === _gl.R32F || internalFormat === _gl.RG16F || internalFormat === _gl.RG32F || internalFormat === _gl.RGBA16F || internalFormat === _gl.RGBA32F) { extensions.get('EXT_color_buffer_float'); } - return internalFormat; } - function getMipLevels(texture, image, supportsMips) { if (textureNeedsGenerateMipmaps(texture, supportsMips) === true || texture.isFramebufferTexture && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter) { return Math.log2(Math.max(image.width, image.height)) + 1; } else if (texture.mipmaps !== undefined && texture.mipmaps.length > 0) { // user-defined mipmaps + return texture.mipmaps.length; } else if (texture.isCompressedTexture && Array.isArray(texture.image)) { return image.mipmaps.length; } else { // texture without mipmaps (only base level) + return 1; } - } // Fallback filters for non-power-of-2 textures + } + // Fallback filters for non-power-of-2 textures function filterFallback(f) { if (f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter) { return _gl.NEAREST; } - return _gl.LINEAR; - } // + } + // function onTextureDispose(event) { const texture = event.target; texture.removeEventListener('dispose', onTextureDispose); deallocateTexture(texture); - if (texture.isVideoTexture) { _videoTextures.delete(texture); } } - function onRenderTargetDispose(event) { const renderTarget = event.target; renderTarget.removeEventListener('dispose', onRenderTargetDispose); deallocateRenderTarget(renderTarget); - } // + } + // function deallocateTexture(texture) { const textureProperties = properties.get(texture); - if (textureProperties.__webglInit === undefined) return; // check if it's necessary to remove the WebGLTexture object + if (textureProperties.__webglInit === undefined) return; - const source = texture.source; + // check if it's necessary to remove the WebGLTexture object + const source = texture.source; const webglTextures = _sources.get(source); - if (webglTextures) { const webglTexture = webglTextures[textureProperties.__cacheKey]; - webglTexture.usedTimes--; // the WebGLTexture object is not used anymore, remove it + webglTexture.usedTimes--; + + // the WebGLTexture object is not used anymore, remove it if (webglTexture.usedTimes === 0) { deleteTexture(texture); - } // remove the weak map entry if no WebGLTexture uses the source anymore + } + // remove the weak map entry if no WebGLTexture uses the source anymore if (Object.keys(webglTextures).length === 0) { _sources.delete(source); } } - properties.remove(texture); } - function deleteTexture(texture) { const textureProperties = properties.get(texture); - _gl.deleteTexture(textureProperties.__webglTexture); - const source = texture.source; - const webglTextures = _sources.get(source); - delete webglTextures[textureProperties.__cacheKey]; info.memory.textures--; } - function deallocateRenderTarget(renderTarget) { const texture = renderTarget.texture; const renderTargetProperties = properties.get(renderTarget); const textureProperties = properties.get(texture); - if (textureProperties.__webglTexture !== undefined) { _gl.deleteTexture(textureProperties.__webglTexture); - info.memory.textures--; } - if (renderTarget.depthTexture) { renderTarget.depthTexture.dispose(); } - if (renderTarget.isWebGLCubeRenderTarget) { for (let i = 0; i < 6; i++) { _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer[i]); - if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer[i]); } } else { _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer); - if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer); if (renderTargetProperties.__webglMultisampledFramebuffer) _gl.deleteFramebuffer(renderTargetProperties.__webglMultisampledFramebuffer); - if (renderTargetProperties.__webglColorRenderbuffer) { for (let i = 0; i < renderTargetProperties.__webglColorRenderbuffer.length; i++) { if (renderTargetProperties.__webglColorRenderbuffer[i]) _gl.deleteRenderbuffer(renderTargetProperties.__webglColorRenderbuffer[i]); } } - if (renderTargetProperties.__webglDepthRenderbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthRenderbuffer); } - if (renderTarget.isWebGLMultipleRenderTargets) { for (let i = 0, il = texture.length; i < il; i++) { const attachmentProperties = properties.get(texture[i]); - if (attachmentProperties.__webglTexture) { _gl.deleteTexture(attachmentProperties.__webglTexture); - info.memory.textures--; } - properties.remove(texture[i]); } } - properties.remove(texture); properties.remove(renderTarget); - } // + } + // let textureUnits = 0; - function resetTextureUnits() { textureUnits = 0; } - function allocateTextureUnit() { const textureUnit = textureUnits; - if (textureUnit >= maxTextures) { console.warn('THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + maxTextures); } - textureUnits += 1; return textureUnit; } - function getTextureCacheKey(texture) { const array = []; array.push(texture.wrapS); array.push(texture.wrapT); + array.push(texture.wrapR || 0); array.push(texture.magFilter); array.push(texture.minFilter); array.push(texture.anisotropy); @@ -16810,16 +14949,15 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, array.push(texture.unpackAlignment); array.push(texture.encoding); return array.join(); - } // + } + // function setTexture2D(texture, slot) { const textureProperties = properties.get(texture); if (texture.isVideoTexture) updateVideoTexture(texture); - if (texture.isRenderTargetTexture === false && texture.version > 0 && textureProperties.__version !== texture.version) { const image = texture.image; - if (image === null) { console.warn('THREE.WebGLRenderer: Texture marked for update but no image data found.'); } else if (image.complete === false) { @@ -16829,47 +14967,32 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, return; } } - - state.activeTexture(_gl.TEXTURE0 + slot); - state.bindTexture(_gl.TEXTURE_2D, textureProperties.__webglTexture); + state.bindTexture(_gl.TEXTURE_2D, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); } - function setTexture2DArray(texture, slot) { const textureProperties = properties.get(texture); - if (texture.version > 0 && textureProperties.__version !== texture.version) { uploadTexture(textureProperties, texture, slot); return; } - - state.activeTexture(_gl.TEXTURE0 + slot); - state.bindTexture(_gl.TEXTURE_2D_ARRAY, textureProperties.__webglTexture); + state.bindTexture(_gl.TEXTURE_2D_ARRAY, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); } - function setTexture3D(texture, slot) { const textureProperties = properties.get(texture); - if (texture.version > 0 && textureProperties.__version !== texture.version) { uploadTexture(textureProperties, texture, slot); return; } - - state.activeTexture(_gl.TEXTURE0 + slot); - state.bindTexture(_gl.TEXTURE_3D, textureProperties.__webglTexture); + state.bindTexture(_gl.TEXTURE_3D, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); } - function setTextureCube(texture, slot) { const textureProperties = properties.get(texture); - if (texture.version > 0 && textureProperties.__version !== texture.version) { uploadCubeTexture(textureProperties, texture, slot); return; } - - state.activeTexture(_gl.TEXTURE0 + slot); - state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture); + state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); } - const wrappingToGL = { [RepeatWrapping]: _gl.REPEAT, [ClampToEdgeWrapping]: _gl.CLAMP_TO_EDGE, @@ -16883,149 +15006,128 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, [LinearMipmapNearestFilter]: _gl.LINEAR_MIPMAP_NEAREST, [LinearMipmapLinearFilter]: _gl.LINEAR_MIPMAP_LINEAR }; - function setTextureParameters(textureType, texture, supportsMips) { if (supportsMips) { _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_S, wrappingToGL[texture.wrapS]); - _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_T, wrappingToGL[texture.wrapT]); - if (textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY) { _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_R, wrappingToGL[texture.wrapR]); } - _gl.texParameteri(textureType, _gl.TEXTURE_MAG_FILTER, filterToGL[texture.magFilter]); - _gl.texParameteri(textureType, _gl.TEXTURE_MIN_FILTER, filterToGL[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); - if (textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY) { _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_R, _gl.CLAMP_TO_EDGE); } - 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.'); } - _gl.texParameteri(textureType, _gl.TEXTURE_MAG_FILTER, filterFallback(texture.magFilter)); - _gl.texParameteri(textureType, _gl.TEXTURE_MIN_FILTER, filterFallback(texture.minFilter)); - 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.'); } } - if (extensions.has('EXT_texture_filter_anisotropic') === true) { const extension = extensions.get('EXT_texture_filter_anisotropic'); if (texture.type === FloatType && extensions.has('OES_texture_float_linear') === false) return; // verify extension for WebGL 1 and WebGL 2 - if (isWebGL2 === false && texture.type === HalfFloatType && extensions.has('OES_texture_half_float_linear') === false) return; // verify extension for WebGL 1 only 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) { let forceUpload = false; - if (textureProperties.__webglInit === undefined) { textureProperties.__webglInit = true; texture.addEventListener('dispose', onTextureDispose); - } // create Source <-> WebGLTextures mapping if necessary + } + // create Source <-> WebGLTextures mapping if necessary const source = texture.source; - let webglTextures = _sources.get(source); - if (webglTextures === undefined) { webglTextures = {}; - _sources.set(source, webglTextures); - } // check if there is already a WebGLTexture object for the given texture parameters + } + // check if there is already a WebGLTexture object for the given texture parameters const textureCacheKey = getTextureCacheKey(texture); - if (textureCacheKey !== textureProperties.__cacheKey) { // if not, create a new instance of WebGLTexture + if (webglTextures[textureCacheKey] === undefined) { // create new entry + webglTextures[textureCacheKey] = { texture: _gl.createTexture(), usedTimes: 0 }; - info.memory.textures++; // when a new instance of WebGLTexture was created, a texture upload is required + info.memory.textures++; + + // when a new instance of WebGLTexture was created, a texture upload is required // even if the image contents are identical forceUpload = true; } + webglTextures[textureCacheKey].usedTimes++; - webglTextures[textureCacheKey].usedTimes++; // every time the texture cache key changes, it's necessary to check if an instance of + // every time the texture cache key changes, it's necessary to check if an instance of // WebGLTexture can be deleted in order to avoid a memory leak. const webglTexture = webglTextures[textureProperties.__cacheKey]; - if (webglTexture !== undefined) { webglTextures[textureProperties.__cacheKey].usedTimes--; - if (webglTexture.usedTimes === 0) { deleteTexture(texture); } - } // store references to cache key and WebGLTexture object + } + // store references to cache key and WebGLTexture object textureProperties.__cacheKey = textureCacheKey; textureProperties.__webglTexture = webglTextures[textureCacheKey].texture; } - return forceUpload; } - function uploadTexture(textureProperties, texture, slot) { let textureType = _gl.TEXTURE_2D; - if (texture.isDataArrayTexture) textureType = _gl.TEXTURE_2D_ARRAY; + if (texture.isDataArrayTexture || texture.isCompressedArrayTexture) textureType = _gl.TEXTURE_2D_ARRAY; if (texture.isData3DTexture) textureType = _gl.TEXTURE_3D; const forceUpload = initTexture(textureProperties, texture); const source = texture.source; - state.activeTexture(_gl.TEXTURE0 + slot); - state.bindTexture(textureType, textureProperties.__webglTexture); - - if (source.version !== source.__currentVersion || forceUpload === true) { + state.bindTexture(textureType, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); + const sourceProperties = properties.get(source); + if (source.version !== sourceProperties.__version || forceUpload === true) { + state.activeTexture(_gl.TEXTURE0 + slot); _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); - _gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, _gl.NONE); - const needsPowerOfTwo = textureNeedsPowerOfTwo(texture) && isPowerOfTwo$1(texture.image) === false; let image = resizeImage(texture.image, needsPowerOfTwo, false, maxTextureSize); image = verifyColorSpace(texture, image); const supportsMips = isPowerOfTwo$1(image) || isWebGL2, - glFormat = utils.convert(texture.format, texture.encoding); + glFormat = utils.convert(texture.format, texture.encoding); let glType = utils.convert(texture.type), - glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding, texture.isVideoTexture); + glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding, texture.isVideoTexture); setTextureParameters(textureType, texture, supportsMips); let mipmap; const mipmaps = texture.mipmaps; const useTexStorage = isWebGL2 && texture.isVideoTexture !== true; - const allocateMemory = source.__currentVersion === undefined || forceUpload === true; + const allocateMemory = sourceProperties.__version === undefined || forceUpload === true; const levels = getMipLevels(texture, image, supportsMips); - if (texture.isDepthTexture) { // populate depth texture with dummy data - glInternalFormat = _gl.DEPTH_COMPONENT; + glInternalFormat = _gl.DEPTH_COMPONENT; if (isWebGL2) { if (texture.type === FloatType) { glInternalFormat = _gl.DEPTH_COMPONENT32F; @@ -17040,8 +15142,9 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, if (texture.type === FloatType) { console.error('WebGLRenderer: Floating point depth texture requires WebGL2.'); } - } // validation checks for WebGL 1 + } + // validation checks for WebGL 1 if (texture.format === DepthFormat && glInternalFormat === _gl.DEPTH_COMPONENT) { // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are @@ -17053,21 +15156,22 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, glType = utils.convert(texture.type); } } - if (texture.format === DepthStencilFormat && glInternalFormat === _gl.DEPTH_COMPONENT) { // Depth stencil textures need the DEPTH_STENCIL internal format // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) - glInternalFormat = _gl.DEPTH_STENCIL; // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are + glInternalFormat = _gl.DEPTH_STENCIL; + + // 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); } - } // + } + // if (allocateMemory) { if (useTexStorage) { @@ -17080,56 +15184,77 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, // 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) { if (useTexStorage && allocateMemory) { state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); } - for (let i = 0, il = mipmaps.length; i < il; i++) { mipmap = mipmaps[i]; - if (useTexStorage) { state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); } else { state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); } } - texture.generateMipmaps = false; } else { if (useTexStorage) { if (allocateMemory) { state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); } - state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, image.width, image.height, glFormat, glType, image.data); } else { state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data); } } } else if (texture.isCompressedTexture) { - if (useTexStorage && allocateMemory) { - state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); - } - - for (let i = 0, il = mipmaps.length; i < il; i++) { - mipmap = mipmaps[i]; - - if (texture.format !== RGBAFormat) { - if (glFormat !== null) { - if (useTexStorage) { - state.compressedTexSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data); + if (texture.isCompressedArrayTexture) { + if (useTexStorage && allocateMemory) { + state.texStorage3D(_gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height, image.depth); + } + for (let i = 0, il = mipmaps.length; i < il; i++) { + mipmap = mipmaps[i]; + if (texture.format !== RGBAFormat) { + if (glFormat !== null) { + if (useTexStorage) { + state.compressedTexSubImage3D(_gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, mipmap.data, 0, 0); + } else { + state.compressedTexImage3D(_gl.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, mipmap.data, 0, 0); + } } else { - state.compressedTexImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data); + console.warn('THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()'); } } else { - console.warn('THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()'); + if (useTexStorage) { + state.texSubImage3D(_gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, glType, mipmap.data); + } else { + state.texImage3D(_gl.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, glFormat, glType, mipmap.data); + } } - } else { - if (useTexStorage) { - state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); + } + } else { + if (useTexStorage && allocateMemory) { + state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); + } + for (let i = 0, il = mipmaps.length; i < il; i++) { + mipmap = mipmaps[i]; + if (texture.format !== RGBAFormat) { + if (glFormat !== null) { + if (useTexStorage) { + state.compressedTexSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data); + } else { + state.compressedTexImage2D(_gl.TEXTURE_2D, 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(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); + if (useTexStorage) { + state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); + } else { + state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); + } } } } @@ -17138,7 +15263,6 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, if (allocateMemory) { state.texStorage3D(_gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, image.width, image.height, image.depth); } - state.texSubImage3D(_gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data); } else { state.texImage3D(_gl.TEXTURE_2D_ARRAY, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data); @@ -17148,7 +15272,6 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, if (allocateMemory) { state.texStorage3D(_gl.TEXTURE_3D, levels, glInternalFormat, image.width, image.height, image.depth); } - state.texSubImage3D(_gl.TEXTURE_3D, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data); } else { state.texImage3D(_gl.TEXTURE_3D, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data); @@ -17159,8 +15282,7 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); } else { let width = image.width, - height = image.height; - + height = image.height; for (let i = 0; i < levels; i++) { state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, width, height, 0, glFormat, glType, null); width >>= 1; @@ -17170,101 +15292,84 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, } } 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) { if (useTexStorage && allocateMemory) { state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); } - for (let i = 0, il = mipmaps.length; i < il; i++) { mipmap = mipmaps[i]; - if (useTexStorage) { state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, glFormat, glType, mipmap); } else { state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, glFormat, glType, mipmap); } } - texture.generateMipmaps = false; } else { if (useTexStorage) { if (allocateMemory) { state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); } - state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, glFormat, glType, image); } else { state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image); } } } - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { generateMipmap(textureType); } - - source.__currentVersion = source.version; + sourceProperties.__version = source.version; if (texture.onUpdate) texture.onUpdate(texture); } - textureProperties.__version = texture.version; } - function uploadCubeTexture(textureProperties, texture, slot) { if (texture.image.length !== 6) return; const forceUpload = initTexture(textureProperties, texture); const source = texture.source; - state.activeTexture(_gl.TEXTURE0 + slot); - state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture); - - if (source.version !== source.__currentVersion || forceUpload === true) { + state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); + const sourceProperties = properties.get(source); + if (source.version !== sourceProperties.__version || forceUpload === true) { + state.activeTexture(_gl.TEXTURE0 + slot); _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); - _gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, _gl.NONE); - const isCompressed = texture.isCompressedTexture || texture.image[0].isCompressedTexture; const isDataTexture = texture.image[0] && texture.image[0].isDataTexture; const cubeImage = []; - for (let 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]; } - cubeImage[i] = verifyColorSpace(texture, cubeImage[i]); } - const image = cubeImage[0], - supportsMips = isPowerOfTwo$1(image) || isWebGL2, - glFormat = utils.convert(texture.format, texture.encoding), - glType = utils.convert(texture.type), - glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding); + supportsMips = isPowerOfTwo$1(image) || isWebGL2, + glFormat = utils.convert(texture.format, texture.encoding), + glType = utils.convert(texture.type), + glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding); const useTexStorage = isWebGL2 && texture.isVideoTexture !== true; - const allocateMemory = source.__currentVersion === undefined || forceUpload === true; + const allocateMemory = sourceProperties.__version === undefined || forceUpload === true; let levels = getMipLevels(texture, image, supportsMips); setTextureParameters(_gl.TEXTURE_CUBE_MAP, texture, supportsMips); let mipmaps; - if (isCompressed) { if (useTexStorage && allocateMemory) { state.texStorage2D(_gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, image.width, image.height); } - for (let i = 0; i < 6; i++) { mipmaps = cubeImage[i].mipmaps; - for (let j = 0; j < mipmaps.length; j++) { const mipmap = mipmaps[j]; - if (texture.format !== RGBAFormat) { if (glFormat !== null) { if (useTexStorage) { @@ -17286,15 +15391,14 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, } } else { mipmaps = texture.mipmaps; - if (useTexStorage && allocateMemory) { // TODO: Uniformly handle mipmap definitions // Normal textures and compressed cube textures define base level + mips with their mipmap array // Uncompressed cube textures use their mipmap array only for mips (no base level) + if (mipmaps.length > 0) levels++; state.texStorage2D(_gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, cubeImage[0].width, cubeImage[0].height); } - for (let i = 0; i < 6; i++) { if (isDataTexture) { if (useTexStorage) { @@ -17302,11 +15406,9 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, } else { state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, cubeImage[i].width, cubeImage[i].height, 0, glFormat, glType, cubeImage[i].data); } - for (let j = 0; j < mipmaps.length; j++) { const mipmap = mipmaps[j]; const mipmapImage = mipmap.image[i].image; - if (useTexStorage) { state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, mipmapImage.width, mipmapImage.height, glFormat, glType, mipmapImage.data); } else { @@ -17319,10 +15421,8 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, } else { state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[i]); } - for (let j = 0; j < mipmaps.length; j++) { const mipmap = mipmaps[j]; - if (useTexStorage) { state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, glFormat, glType, mipmap.image[i]); } else { @@ -17332,27 +15432,24 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, } } } - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { // We assume images for cube map have the same size. generateMipmap(_gl.TEXTURE_CUBE_MAP); } - - source.__currentVersion = source.version; + sourceProperties.__version = source.version; if (texture.onUpdate) texture.onUpdate(texture); } - textureProperties.__version = texture.version; - } // Render targets - // Setup storage for target texture and bind it to correct framebuffer + } + // Render targets + // Setup storage for target texture and bind it to correct framebuffer function setupFrameBufferTexture(framebuffer, renderTarget, texture, attachment, textureTarget) { const glFormat = utils.convert(texture.format, texture.encoding); const glType = utils.convert(texture.type); const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding); const renderTargetProperties = properties.get(renderTarget); - if (!renderTargetProperties.__hasExternalTextures) { if (textureTarget === _gl.TEXTURE_3D || textureTarget === _gl.TEXTURE_2D_ARRAY) { state.texImage3D(textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, renderTarget.depth, 0, glFormat, glType, null); @@ -17360,28 +15457,24 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, state.texImage2D(textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null); } } - state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); - if (useMultisampledRTT(renderTarget)) { multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, attachment, textureTarget, properties.get(texture).__webglTexture, 0, getRenderTargetSamples(renderTarget)); - } else { + } else if (textureTarget === _gl.TEXTURE_2D || textureTarget >= _gl.TEXTURE_CUBE_MAP_POSITIVE_X && textureTarget <= _gl.TEXTURE_CUBE_MAP_NEGATIVE_Z) { + // see #24753 + _gl.framebufferTexture2D(_gl.FRAMEBUFFER, attachment, textureTarget, properties.get(texture).__webglTexture, 0); } - state.bindFramebuffer(_gl.FRAMEBUFFER, null); - } // Setup storage for internal depth/stencil buffers and bind to correct framebuffer - + } + // Setup storage for internal depth/stencil buffers and bind to correct framebuffer function setupRenderBufferStorage(renderbuffer, renderTarget, isMultisample) { _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderbuffer); - if (renderTarget.depthBuffer && !renderTarget.stencilBuffer) { let glInternalFormat = _gl.DEPTH_COMPONENT16; - if (isMultisample || useMultisampledRTT(renderTarget)) { const depthTexture = renderTarget.depthTexture; - if (depthTexture && depthTexture.isDepthTexture) { if (depthTexture.type === FloatType) { glInternalFormat = _gl.DEPTH_COMPONENT32F; @@ -17389,9 +15482,7 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, glInternalFormat = _gl.DEPTH_COMPONENT24; } } - const samples = getRenderTargetSamples(renderTarget); - if (useMultisampledRTT(renderTarget)) { multisampledRTTExt.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); } else { @@ -17400,11 +15491,9 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, } else { _gl.renderbufferStorage(_gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height); } - _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer); } else if (renderTarget.depthBuffer && renderTarget.stencilBuffer) { const samples = getRenderTargetSamples(renderTarget); - if (isMultisample && useMultisampledRTT(renderTarget) === false) { _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, _gl.DEPTH24_STENCIL8, renderTarget.width, renderTarget.height); } else if (useMultisampledRTT(renderTarget)) { @@ -17412,18 +15501,15 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, } else { _gl.renderbufferStorage(_gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height); } - _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer); } else { const textures = renderTarget.isWebGLMultipleRenderTargets === true ? renderTarget.texture : [renderTarget.texture]; - for (let i = 0; i < textures.length; i++) { const texture = textures[i]; const glFormat = utils.convert(texture.format, texture.encoding); const glType = utils.convert(texture.type); const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding); const samples = getRenderTargetSamples(renderTarget); - if (isMultisample && useMultisampledRTT(renderTarget) === false) { _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); } else if (useMultisampledRTT(renderTarget)) { @@ -17433,33 +15519,27 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, } } } - _gl.bindRenderbuffer(_gl.RENDERBUFFER, null); - } // Setup resources for a Depth Texture for a FBO (needs an extension) - + } + // Setup resources for a Depth Texture for a FBO (needs an extension) function setupDepthTexture(framebuffer, renderTarget) { const isCube = renderTarget && renderTarget.isWebGLCubeRenderTarget; if (isCube) throw new Error('Depth Texture with cube render targets is not supported'); state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); - 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 - + } + // upload an empty depth texture with framebuffer size 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); - const webglDepthTexture = properties.get(renderTarget.depthTexture).__webglTexture; - const samples = getRenderTargetSamples(renderTarget); - if (renderTarget.depthTexture.format === DepthFormat) { if (useMultisampledRTT(renderTarget)) { multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples); @@ -17475,20 +15555,18 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, } else { throw new Error('Unknown depthTexture format'); } - } // Setup GL resources for a non-texture depth buffer - + } + // Setup GL resources for a non-texture depth buffer function setupDepthRenderbuffer(renderTarget) { const renderTargetProperties = properties.get(renderTarget); const isCube = renderTarget.isWebGLCubeRenderTarget === true; - if (renderTarget.depthTexture && !renderTargetProperties.__autoAllocateDepthBuffer) { if (isCube) throw new Error('target.depthTexture not supported in Cube render targets'); setupDepthTexture(renderTargetProperties.__webglFramebuffer, renderTarget); } else { if (isCube) { renderTargetProperties.__webglDepthbuffer = []; - for (let i = 0; i < 6; i++) { state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[i]); renderTargetProperties.__webglDepthbuffer[i] = _gl.createRenderbuffer(); @@ -17500,59 +15578,51 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer, renderTarget, false); } } - state.bindFramebuffer(_gl.FRAMEBUFFER, null); - } // rebind framebuffer with external textures - + } + // rebind framebuffer with external textures function rebindTextures(renderTarget, colorTexture, depthTexture) { const renderTargetProperties = properties.get(renderTarget); - if (colorTexture !== undefined) { setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, renderTarget.texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D); } - if (depthTexture !== undefined) { setupDepthRenderbuffer(renderTarget); } - } // Set up GL resources for the render target - + } + // Set up GL resources for the render target function setupRenderTarget(renderTarget) { const texture = renderTarget.texture; const renderTargetProperties = properties.get(renderTarget); const textureProperties = properties.get(texture); renderTarget.addEventListener('dispose', onRenderTargetDispose); - if (renderTarget.isWebGLMultipleRenderTargets !== true) { if (textureProperties.__webglTexture === undefined) { textureProperties.__webglTexture = _gl.createTexture(); } - textureProperties.__version = texture.version; info.memory.textures++; } - const isCube = renderTarget.isWebGLCubeRenderTarget === true; const isMultipleRenderTargets = renderTarget.isWebGLMultipleRenderTargets === true; - const supportsMips = isPowerOfTwo$1(renderTarget) || isWebGL2; // Setup framebuffer + const supportsMips = isPowerOfTwo$1(renderTarget) || isWebGL2; + + // Setup framebuffer if (isCube) { renderTargetProperties.__webglFramebuffer = []; - for (let i = 0; i < 6; i++) { renderTargetProperties.__webglFramebuffer[i] = _gl.createFramebuffer(); } } else { renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer(); - if (isMultipleRenderTargets) { if (capabilities.drawBuffers) { const textures = renderTarget.texture; - for (let i = 0, il = textures.length; i < il; i++) { const attachmentProperties = properties.get(textures[i]); - if (attachmentProperties.__webglTexture === undefined) { attachmentProperties.__webglTexture = _gl.createTexture(); info.memory.textures++; @@ -17562,73 +15632,58 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, console.warn('THREE.WebGLRenderer: WebGLMultipleRenderTargets can only be used with WebGL2 or WEBGL_draw_buffers extension.'); } } - if (isWebGL2 && renderTarget.samples > 0 && useMultisampledRTT(renderTarget) === false) { const textures = isMultipleRenderTargets ? texture : [texture]; renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer(); renderTargetProperties.__webglColorRenderbuffer = []; state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); - for (let i = 0; i < textures.length; i++) { const texture = textures[i]; renderTargetProperties.__webglColorRenderbuffer[i] = _gl.createRenderbuffer(); - _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); - const glFormat = utils.convert(texture.format, texture.encoding); const glType = utils.convert(texture.type); - const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding); + const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding, renderTarget.isXRRenderTarget === true); const samples = getRenderTargetSamples(renderTarget); - _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); - _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); } - _gl.bindRenderbuffer(_gl.RENDERBUFFER, null); - if (renderTarget.depthBuffer) { renderTargetProperties.__webglDepthRenderbuffer = _gl.createRenderbuffer(); setupRenderBufferStorage(renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true); } - state.bindFramebuffer(_gl.FRAMEBUFFER, null); } - } // Setup color buffer + } + // Setup color buffer if (isCube) { state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture); setTextureParameters(_gl.TEXTURE_CUBE_MAP, texture, supportsMips); - for (let i = 0; i < 6; i++) { setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer[i], renderTarget, texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i); } - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { generateMipmap(_gl.TEXTURE_CUBE_MAP); } - state.unbindTexture(); } else if (isMultipleRenderTargets) { const textures = renderTarget.texture; - for (let i = 0, il = textures.length; i < il; i++) { const attachment = textures[i]; const attachmentProperties = properties.get(attachment); state.bindTexture(_gl.TEXTURE_2D, attachmentProperties.__webglTexture); setTextureParameters(_gl.TEXTURE_2D, attachment, supportsMips); setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, attachment, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D); - if (textureNeedsGenerateMipmaps(attachment, supportsMips)) { generateMipmap(_gl.TEXTURE_2D); } } - state.unbindTexture(); } else { let glTextureType = _gl.TEXTURE_2D; - if (renderTarget.isWebGL3DRenderTarget || renderTarget.isWebGLArrayRenderTarget) { if (isWebGL2) { glTextureType = renderTarget.isWebGL3DRenderTarget ? _gl.TEXTURE_3D : _gl.TEXTURE_2D_ARRAY; @@ -17636,43 +15691,35 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, console.error('THREE.WebGLTextures: THREE.Data3DTexture and THREE.DataArrayTexture only supported with WebGL2.'); } } - state.bindTexture(glTextureType, textureProperties.__webglTexture); setTextureParameters(glTextureType, texture, supportsMips); setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, texture, _gl.COLOR_ATTACHMENT0, glTextureType); - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { generateMipmap(glTextureType); } - state.unbindTexture(); - } // Setup depth and stencil buffers + } + // Setup depth and stencil buffers if (renderTarget.depthBuffer) { setupDepthRenderbuffer(renderTarget); } } - function updateRenderTargetMipmap(renderTarget) { const supportsMips = isPowerOfTwo$1(renderTarget) || isWebGL2; const textures = renderTarget.isWebGLMultipleRenderTargets === true ? renderTarget.texture : [renderTarget.texture]; - for (let i = 0, il = textures.length; i < il; i++) { const texture = textures[i]; - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { const target = renderTarget.isWebGLCubeRenderTarget ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D; - const webglTexture = properties.get(texture).__webglTexture; - state.bindTexture(target, webglTexture); generateMipmap(target); state.unbindTexture(); } } } - function updateMultisampleRenderTarget(renderTarget) { if (isWebGL2 && renderTarget.samples > 0 && useMultisampledRTT(renderTarget) === false) { const textures = renderTarget.isWebGLMultipleRenderTargets ? renderTarget.texture : [renderTarget.texture]; @@ -17682,122 +15729,105 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, const invalidationArray = []; const depthStyle = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT; const renderTargetProperties = properties.get(renderTarget); - const isMultipleRenderTargets = renderTarget.isWebGLMultipleRenderTargets === true; // If MRT we need to remove FBO attachments + const isMultipleRenderTargets = renderTarget.isWebGLMultipleRenderTargets === true; + // If MRT we need to remove FBO attachments if (isMultipleRenderTargets) { for (let i = 0; i < textures.length; i++) { state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); - _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, null); - state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); - _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D, null, 0); } } - state.bindFramebuffer(_gl.READ_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); - for (let i = 0; i < textures.length; i++) { invalidationArray.push(_gl.COLOR_ATTACHMENT0 + i); - if (renderTarget.depthBuffer) { invalidationArray.push(depthStyle); } - const ignoreDepthValues = renderTargetProperties.__ignoreDepthValues !== undefined ? renderTargetProperties.__ignoreDepthValues : false; - if (ignoreDepthValues === false) { if (renderTarget.depthBuffer) mask |= _gl.DEPTH_BUFFER_BIT; if (renderTarget.stencilBuffer) mask |= _gl.STENCIL_BUFFER_BIT; } - if (isMultipleRenderTargets) { _gl.framebufferRenderbuffer(_gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); } - if (ignoreDepthValues === true) { _gl.invalidateFramebuffer(_gl.READ_FRAMEBUFFER, [depthStyle]); - _gl.invalidateFramebuffer(_gl.DRAW_FRAMEBUFFER, [depthStyle]); } - if (isMultipleRenderTargets) { const webglTexture = properties.get(textures[i]).__webglTexture; - _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, webglTexture, 0); } - _gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, mask, _gl.NEAREST); - if (supportsInvalidateFramebuffer) { _gl.invalidateFramebuffer(_gl.READ_FRAMEBUFFER, invalidationArray); } } - state.bindFramebuffer(_gl.READ_FRAMEBUFFER, null); - state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, null); // If MRT since pre-blit we removed the FBO we need to reconstruct the attachments + state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, null); + // If MRT since pre-blit we removed the FBO we need to reconstruct the attachments if (isMultipleRenderTargets) { for (let i = 0; i < textures.length; i++) { state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); - _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); - const webglTexture = properties.get(textures[i]).__webglTexture; - state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); - _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D, webglTexture, 0); } } - state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); } } - function getRenderTargetSamples(renderTarget) { return Math.min(maxSamples, renderTarget.samples); } - function useMultisampledRTT(renderTarget) { const renderTargetProperties = properties.get(renderTarget); return isWebGL2 && renderTarget.samples > 0 && extensions.has('WEBGL_multisampled_render_to_texture') === true && renderTargetProperties.__useRenderToTexture !== false; } - function updateVideoTexture(texture) { - const frame = info.render.frame; // Check the last frame we updated the VideoTexture + const frame = info.render.frame; + + // Check the last frame we updated the VideoTexture if (_videoTextures.get(texture) !== frame) { _videoTextures.set(texture, frame); - texture.update(); } } - function verifyColorSpace(texture, image) { const encoding = texture.encoding; const format = texture.format; const type = texture.type; if (texture.isCompressedTexture === true || texture.isVideoTexture === true || texture.format === _SRGBAFormat) return image; - if (encoding !== LinearEncoding) { // sRGB + if (encoding === sRGBEncoding) { if (isWebGL2 === false) { // in WebGL 1, try to use EXT_sRGB extension and unsized formats + if (extensions.has('EXT_sRGB') === true && format === RGBAFormat) { - texture.format = _SRGBAFormat; // it's not possible to generate mips in WebGL 1 with this extension + texture.format = _SRGBAFormat; + + // it's not possible to generate mips in WebGL 1 with this extension texture.minFilter = LinearFilter; texture.generateMipmaps = false; } else { // slow fallback (CPU decode) + image = ImageUtils.sRGBToLinear(image); } } else { // in WebGL 2 uncompressed textures can only be sRGB encoded if they have the RGBA8 format + if (format !== RGBAFormat || type !== UnsignedByteType) { console.warn('THREE.WebGLTextures: sRGB encoded textures have to use RGBAFormat and UnsignedByteType.'); } @@ -17806,10 +15836,10 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, console.error('THREE.WebGLTextures: Unsupported texture encoding:', encoding); } } - return image; - } // + } + // this.allocateTextureUnit = allocateTextureUnit; this.resetTextureUnits = resetTextureUnits; @@ -17828,7 +15858,6 @@ function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, function WebGLUtils(gl, extensions, capabilities) { const isWebGL2 = capabilities.isWebGL2; - function convert(p, encoding = null) { let extension; if (p === UnsignedByteType) return gl.UNSIGNED_BYTE; @@ -17840,52 +15869,53 @@ function WebGLUtils(gl, extensions, capabilities) { if (p === IntType) return gl.INT; if (p === UnsignedIntType) return gl.UNSIGNED_INT; if (p === FloatType) return gl.FLOAT; - if (p === HalfFloatType) { if (isWebGL2) return gl.HALF_FLOAT; extension = extensions.get('OES_texture_half_float'); - if (extension !== null) { return extension.HALF_FLOAT_OES; } else { return null; } } - if (p === AlphaFormat) return gl.ALPHA; if (p === RGBAFormat) return gl.RGBA; if (p === LuminanceFormat) return gl.LUMINANCE; if (p === LuminanceAlphaFormat) return gl.LUMINANCE_ALPHA; if (p === DepthFormat) return gl.DEPTH_COMPONENT; if (p === DepthStencilFormat) return gl.DEPTH_STENCIL; - if (p === RedFormat) return gl.RED; + + // @deprecated since r137 if (p === RGBFormat) { console.warn('THREE.WebGLRenderer: THREE.RGBFormat has been removed. Use THREE.RGBAFormat instead. https://github.com/mrdoob/three.js/pull/23228'); return gl.RGBA; - } // WebGL 1 sRGB fallback + } + // WebGL 1 sRGB fallback if (p === _SRGBAFormat) { extension = extensions.get('EXT_sRGB'); - if (extension !== null) { return extension.SRGB_ALPHA_EXT; } else { return null; } - } // WebGL2 formats. + } + // WebGL2 formats. + if (p === RedFormat) return gl.RED; if (p === RedIntegerFormat) return gl.RED_INTEGER; if (p === RGFormat) return gl.RG; if (p === RGIntegerFormat) return gl.RG_INTEGER; - if (p === RGBAIntegerFormat) return gl.RGBA_INTEGER; // S3TC + if (p === RGBAIntegerFormat) return gl.RGBA_INTEGER; + + // S3TC if (p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format) { if (encoding === sRGBEncoding) { extension = extensions.get('WEBGL_compressed_texture_s3tc_srgb'); - if (extension !== null) { if (p === RGB_S3TC_DXT1_Format) return extension.COMPRESSED_SRGB_S3TC_DXT1_EXT; if (p === RGBA_S3TC_DXT1_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; @@ -17896,7 +15926,6 @@ function WebGLUtils(gl, extensions, capabilities) { } } else { 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; @@ -17906,12 +15935,12 @@ function WebGLUtils(gl, extensions, capabilities) { return null; } } - } // PVRTC + } + // PVRTC 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; @@ -17920,35 +15949,35 @@ function WebGLUtils(gl, extensions, capabilities) { } else { return null; } - } // ETC1 + } + // ETC1 if (p === RGB_ETC1_Format) { extension = extensions.get('WEBGL_compressed_texture_etc1'); - if (extension !== null) { return extension.COMPRESSED_RGB_ETC1_WEBGL; } else { return null; } - } // ETC2 + } + // ETC2 if (p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format) { extension = extensions.get('WEBGL_compressed_texture_etc'); - if (extension !== null) { if (p === RGB_ETC2_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ETC2 : extension.COMPRESSED_RGB8_ETC2; if (p === RGBA_ETC2_EAC_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : extension.COMPRESSED_RGBA8_ETC2_EAC; } else { return null; } - } // ASTC + } + // ASTC 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) { extension = extensions.get('WEBGL_compressed_texture_astc'); - if (extension !== null) { if (p === RGBA_ASTC_4x4_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : extension.COMPRESSED_RGBA_ASTC_4x4_KHR; if (p === RGBA_ASTC_5x4_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : extension.COMPRESSED_RGBA_ASTC_5x4_KHR; @@ -17967,35 +15996,35 @@ function WebGLUtils(gl, extensions, capabilities) { } else { return null; } - } // BPTC + } + // BPTC if (p === RGBA_BPTC_Format) { extension = extensions.get('EXT_texture_compression_bptc'); - if (extension !== null) { if (p === RGBA_BPTC_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT : extension.COMPRESSED_RGBA_BPTC_UNORM_EXT; } else { return null; } - } // + } + // if (p === UnsignedInt248Type) { if (isWebGL2) return gl.UNSIGNED_INT_24_8; extension = extensions.get('WEBGL_depth_texture'); - if (extension !== null) { return extension.UNSIGNED_INT_24_8_WEBGL; } else { return null; } - } // if "p" can't be resolved, assume the user defines a WebGL constant as a string (fallback/workaround for packed RGB formats) + } + // if "p" can't be resolved, assume the user defines a WebGL constant as a string (fallback/workaround for packed RGB formats) return gl[p] !== undefined ? gl[p] : null; } - return { convert: convert }; @@ -18007,7 +16036,6 @@ class ArrayCamera extends PerspectiveCamera { this.isArrayCamera = true; this.cameras = array; } - } class Group extends Object3D { @@ -18016,20 +16044,17 @@ class Group extends Object3D { this.isGroup = true; this.type = 'Group'; } - } const _moveEvent = { type: 'move' }; - class WebXRController { constructor() { this._targetRay = null; this._grip = null; this._hand = null; } - getHandSpace() { if (this._hand === null) { this._hand = new Group(); @@ -18040,10 +16065,8 @@ class WebXRController { pinching: false }; } - return this._hand; } - getTargetRaySpace() { if (this._targetRay === null) { this._targetRay = new Group(); @@ -18054,10 +16077,8 @@ class WebXRController { this._targetRay.hasAngularVelocity = false; this._targetRay.angularVelocity = new Vector3(); } - return this._targetRay; } - getGripSpace() { if (this._grip === null) { this._grip = new Group(); @@ -18068,47 +16089,52 @@ class WebXRController { this._grip.hasAngularVelocity = false; this._grip.angularVelocity = new Vector3(); } - return this._grip; } - dispatchEvent(event) { if (this._targetRay !== null) { this._targetRay.dispatchEvent(event); } - if (this._grip !== null) { this._grip.dispatchEvent(event); } - if (this._hand !== null) { this._hand.dispatchEvent(event); } - return this; } - + connect(inputSource) { + if (inputSource && inputSource.hand) { + const hand = this._hand; + if (hand) { + for (const inputjoint of inputSource.hand.values()) { + // Initialize hand with joints when connected + this._getHandJoint(hand, inputjoint); + } + } + } + this.dispatchEvent({ + type: 'connected', + data: inputSource + }); + return this; + } disconnect(inputSource) { this.dispatchEvent({ type: 'disconnected', data: inputSource }); - if (this._targetRay !== null) { this._targetRay.visible = false; } - if (this._grip !== null) { this._grip.visible = false; } - if (this._hand !== null) { this._hand.visible = false; } - return this; } - update(inputSource, frame, referenceSpace) { let inputPose = null; let gripPose = null; @@ -18116,44 +16142,31 @@ class WebXRController { const targetRay = this._targetRay; const grip = this._grip; const hand = this._hand; - if (inputSource && frame.session.visibilityState !== 'visible-blurred') { if (hand && inputSource.hand) { handPose = true; - for (const inputjoint of inputSource.hand.values()) { // Update the joints groups with the XRJoint poses const jointPose = frame.getJointPose(inputjoint, referenceSpace); - if (hand.joints[inputjoint.jointName] === undefined) { - // The transform of this joint will be updated with the joint pose on each frame - const joint = new Group(); - joint.matrixAutoUpdate = false; - joint.visible = false; - hand.joints[inputjoint.jointName] = joint; // ?? - - hand.add(joint); - } - - const joint = hand.joints[inputjoint.jointName]; - + // The transform of this joint will be updated with the joint pose on each frame + const joint = this._getHandJoint(hand, inputjoint); if (jointPose !== null) { joint.matrix.fromArray(jointPose.transform.matrix); joint.matrix.decompose(joint.position, joint.rotation, joint.scale); joint.jointRadius = jointPose.radius; } - joint.visible = jointPose !== null; - } // Custom events - // Check pinchz + } + // Custom events + // Check pinchz const indexTip = hand.joints['index-finger-tip']; const thumbTip = hand.joints['thumb-tip']; const distance = indexTip.position.distanceTo(thumbTip.position); const distanceToPinch = 0.02; const threshold = 0.005; - if (hand.inputState.pinching && distance > distanceToPinch + threshold) { hand.inputState.pinching = false; this.dispatchEvent({ @@ -18172,18 +16185,15 @@ class WebXRController { } else { if (grip !== null && inputSource.gripSpace) { gripPose = frame.getPose(inputSource.gripSpace, referenceSpace); - if (gripPose !== null) { grip.matrix.fromArray(gripPose.transform.matrix); grip.matrix.decompose(grip.position, grip.rotation, grip.scale); - if (gripPose.linearVelocity) { grip.hasLinearVelocity = true; grip.linearVelocity.copy(gripPose.linearVelocity); } else { grip.hasLinearVelocity = false; } - if (gripPose.angularVelocity) { grip.hasAngularVelocity = true; grip.angularVelocity.copy(gripPose.angularVelocity); @@ -18193,62 +16203,64 @@ class WebXRController { } } } - if (targetRay !== null) { - inputPose = frame.getPose(inputSource.targetRaySpace, referenceSpace); // Some runtimes (namely Vive Cosmos with Vive OpenXR Runtime) have only grip space and ray space is equal to it + inputPose = frame.getPose(inputSource.targetRaySpace, referenceSpace); + // Some runtimes (namely Vive Cosmos with Vive OpenXR Runtime) have only grip space and ray space is equal to it if (inputPose === null && gripPose !== null) { inputPose = gripPose; } - if (inputPose !== null) { targetRay.matrix.fromArray(inputPose.transform.matrix); targetRay.matrix.decompose(targetRay.position, targetRay.rotation, targetRay.scale); - if (inputPose.linearVelocity) { targetRay.hasLinearVelocity = true; targetRay.linearVelocity.copy(inputPose.linearVelocity); } else { targetRay.hasLinearVelocity = false; } - if (inputPose.angularVelocity) { targetRay.hasAngularVelocity = true; targetRay.angularVelocity.copy(inputPose.angularVelocity); } else { targetRay.hasAngularVelocity = false; } - this.dispatchEvent(_moveEvent); } } } - if (targetRay !== null) { targetRay.visible = inputPose !== null; } - if (grip !== null) { grip.visible = gripPose !== null; } - if (hand !== null) { hand.visible = handPose !== null; } - return this; } + // private method + + _getHandJoint(hand, inputjoint) { + if (hand.joints[inputjoint.jointName] === undefined) { + const joint = new Group(); + joint.matrixAutoUpdate = false; + joint.visible = false; + hand.joints[inputjoint.jointName] = joint; + hand.add(joint); + } + return hand.joints[inputjoint.jointName]; + } } class DepthTexture extends Texture { constructor(width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format) { format = format !== undefined ? format : DepthFormat; - if (format !== DepthFormat && format !== DepthStencilFormat) { throw new Error('DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat'); } - if (type === undefined && format === DepthFormat) type = UnsignedIntType; if (type === undefined && format === DepthStencilFormat) type = UnsignedInt248Type; super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy); @@ -18262,7 +16274,6 @@ class DepthTexture extends Texture { this.flipY = false; this.generateMipmaps = false; } - } class WebXRManager extends EventDispatcher { @@ -18283,7 +16294,11 @@ class WebXRManager extends EventDispatcher { let initialRenderTarget = null; let newRenderTarget = null; const controllers = []; - const controllerInputSources = []; // + const controllerInputSources = []; + const planes = new Set(); + const planesLastChangedTimes = new Map(); + + // const cameraL = new PerspectiveCamera(); cameraL.layers.enable(1); @@ -18296,55 +16311,46 @@ class WebXRManager extends EventDispatcher { cameraVR.layers.enable(1); cameraVR.layers.enable(2); let _currentDepthNear = null; - let _currentDepthFar = null; // + let _currentDepthFar = null; + + // this.cameraAutoUpdate = true; this.enabled = false; this.isPresenting = false; - this.getController = function (index) { let controller = controllers[index]; - if (controller === undefined) { controller = new WebXRController(); controllers[index] = controller; } - return controller.getTargetRaySpace(); }; - this.getControllerGrip = function (index) { let controller = controllers[index]; - if (controller === undefined) { controller = new WebXRController(); controllers[index] = controller; } - return controller.getGripSpace(); }; - this.getHand = function (index) { let controller = controllers[index]; - if (controller === undefined) { controller = new WebXRController(); controllers[index] = controller; } - return controller.getHandSpace(); - }; // + }; + // function onSessionEvent(event) { const controllerIndex = controllerInputSources.indexOf(event.inputSource); - if (controllerIndex === -1) { return; } - const controller = controllers[controllerIndex]; - if (controller !== undefined) { controller.dispatchEvent({ type: event.type, @@ -18352,7 +16358,6 @@ class WebXRManager extends EventDispatcher { }); } } - function onSessionEnd() { session.removeEventListener('select', onSessionEvent); session.removeEventListener('selectstart', onSessionEvent); @@ -18362,23 +16367,25 @@ class WebXRManager extends EventDispatcher { session.removeEventListener('squeezeend', onSessionEvent); session.removeEventListener('end', onSessionEnd); session.removeEventListener('inputsourceschange', onInputSourcesChange); - for (let i = 0; i < controllers.length; i++) { const inputSource = controllerInputSources[i]; if (inputSource === null) continue; controllerInputSources[i] = null; controllers[i].disconnect(inputSource); } - _currentDepthNear = null; - _currentDepthFar = null; // restore framebuffer/rendering state + _currentDepthFar = null; + + // restore framebuffer/rendering state renderer.setRenderTarget(initialRenderTarget); glBaseLayer = null; glProjLayer = null; glBinding = null; session = null; - newRenderTarget = null; // + newRenderTarget = null; + + // animation.stop(); scope.isPresenting = false; @@ -18386,50 +16393,38 @@ class WebXRManager extends EventDispatcher { type: 'sessionend' }); } - this.setFramebufferScaleFactor = function (value) { framebufferScaleFactor = value; - if (scope.isPresenting === true) { console.warn('THREE.WebXRManager: Cannot change framebuffer scale while presenting.'); } }; - this.setReferenceSpaceType = function (value) { referenceSpaceType = value; - if (scope.isPresenting === true) { console.warn('THREE.WebXRManager: Cannot change reference space type while presenting.'); } }; - this.getReferenceSpace = function () { return customReferenceSpace || referenceSpace; }; - this.setReferenceSpace = function (space) { customReferenceSpace = space; }; - this.getBaseLayer = function () { return glProjLayer !== null ? glProjLayer : glBaseLayer; }; - this.getBinding = function () { return glBinding; }; - this.getFrame = function () { return xrFrame; }; - this.getSession = function () { return session; }; - this.setSession = async function (value) { session = value; - if (session !== null) { initialRenderTarget = renderer.getRenderTarget(); session.addEventListener('select', onSessionEvent); @@ -18440,11 +16435,9 @@ class WebXRManager extends EventDispatcher { session.addEventListener('squeezeend', onSessionEvent); session.addEventListener('end', onSessionEnd); session.addEventListener('inputsourceschange', onInputSourcesChange); - if (attributes.xrCompatible !== true) { await gl.makeXRCompatible(); } - if (session.renderState.layers === undefined || renderer.capabilities.isWebGL2 === false) { const layerInit = { antialias: session.renderState.layers === undefined ? attributes.antialias : true, @@ -18460,19 +16453,18 @@ class WebXRManager extends EventDispatcher { newRenderTarget = new WebGLRenderTarget(glBaseLayer.framebufferWidth, glBaseLayer.framebufferHeight, { format: RGBAFormat, type: UnsignedByteType, - encoding: renderer.outputEncoding + encoding: renderer.outputEncoding, + stencilBuffer: attributes.stencil }); } else { let depthFormat = null; let depthType = null; let glDepthFormat = null; - if (attributes.depth) { glDepthFormat = attributes.stencil ? gl.DEPTH24_STENCIL8 : gl.DEPTH_COMPONENT24; depthFormat = attributes.stencil ? DepthStencilFormat : DepthFormat; depthType = attributes.stencil ? UnsignedInt248Type : UnsignedIntType; } - const projectionlayerInit = { colorFormat: gl.RGBA8, depthFormat: glDepthFormat, @@ -18494,10 +16486,9 @@ class WebXRManager extends EventDispatcher { const renderTargetProperties = renderer.properties.get(newRenderTarget); renderTargetProperties.__ignoreDepthValues = glProjLayer.ignoreDepthValues; } - newRenderTarget.isXRRenderTarget = true; // TODO Remove this when possible, see #23278 - // Set foveation to maximum. + // Set foveation to maximum. this.setFoveation(1.0); customReferenceSpace = null; referenceSpace = await session.requestReferenceSpace(referenceSpaceType); @@ -18509,29 +16500,26 @@ class WebXRManager extends EventDispatcher { }); } }; - function onInputSourcesChange(event) { // Notify disconnected + for (let i = 0; i < event.removed.length; i++) { const inputSource = event.removed[i]; const index = controllerInputSources.indexOf(inputSource); - if (index >= 0) { controllerInputSources[index] = null; - controllers[index].dispatchEvent({ - type: 'disconnected', - data: inputSource - }); + controllers[index].disconnect(inputSource); } - } // Notify connected + } + // Notify connected for (let i = 0; i < event.added.length; i++) { const inputSource = event.added[i]; let controllerIndex = controllerInputSources.indexOf(inputSource); - if (controllerIndex === -1) { // Assign input source a controller that currently has no input source + for (let i = 0; i < controllers.length; i++) { if (i >= controllerInputSources.length) { controllerInputSources.push(inputSource); @@ -18542,42 +16530,40 @@ class WebXRManager extends EventDispatcher { controllerIndex = i; break; } - } // If all controllers do currently receive input we ignore new ones + } + // If all controllers do currently receive input we ignore new ones if (controllerIndex === -1) break; } - const controller = controllers[controllerIndex]; - if (controller) { - controller.dispatchEvent({ - type: 'connected', - data: inputSource - }); + controller.connect(inputSource); } } - } // + } + // const cameraLPos = new Vector3(); const 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); const ipd = cameraLPos.distanceTo(cameraRPos); const projL = cameraL.projectionMatrix.elements; - const projR = cameraR.projectionMatrix.elements; // VR systems will have identical far and near planes, and + const 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. - const near = projL[14] / (projL[10] - 1); const far = projL[14] / (projL[10] + 1); const topFov = (projL[9] + 1) / projL[5]; @@ -18585,20 +16571,23 @@ class WebXRManager extends EventDispatcher { const leftFov = (projL[8] - 1) / projL[0]; const rightFov = (projR[8] + 1) / projR[0]; const left = near * leftFov; - const right = near * rightFov; // Calculate the new camera's position offset from the - // left camera. xOffset should be roughly half `ipd`. + const right = near * rightFov; + // Calculate the new camera's position offset from the + // left camera. xOffset should be roughly half `ipd`. const zOffset = ipd / (-leftFov + rightFov); - const xOffset = zOffset * -leftFov; // TODO: Better way to apply this offset? + const 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.copy(camera.matrixWorld).invert(); // Find the union of the frustum values of the cameras and scale + camera.matrixWorldInverse.copy(camera.matrixWorld).invert(); + + // 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. - const near2 = near + zOffset; const far2 = far + zOffset; const left2 = left - xOffset; @@ -18607,24 +16596,21 @@ class WebXRManager extends EventDispatcher { const 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); } - camera.matrixWorldInverse.copy(camera.matrixWorld).invert(); } - this.updateCamera = function (camera) { if (session === null) return; cameraVR.near = cameraR.near = cameraL.near = camera.near; cameraVR.far = cameraR.far = cameraL.far = camera.far; - 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 @@ -18632,156 +16618,182 @@ class WebXRManager extends EventDispatcher { _currentDepthNear = cameraVR.near; _currentDepthFar = cameraVR.far; } - const parent = camera.parent; const cameras = cameraVR.cameras; updateCamera(cameraVR, parent); - for (let i = 0; i < cameras.length; i++) { updateCamera(cameras[i], parent); } + cameraVR.matrixWorld.decompose(cameraVR.position, cameraVR.quaternion, cameraVR.scale); - cameraVR.matrixWorld.decompose(cameraVR.position, cameraVR.quaternion, cameraVR.scale); // update user camera and its children + // update user camera and its children - camera.position.copy(cameraVR.position); - camera.quaternion.copy(cameraVR.quaternion); - camera.scale.copy(cameraVR.scale); camera.matrix.copy(cameraVR.matrix); - camera.matrixWorld.copy(cameraVR.matrixWorld); + camera.matrix.decompose(camera.position, camera.quaternion, camera.scale); const children = camera.children; - for (let i = 0, l = children.length; i < l; i++) { children[i].updateMatrixWorld(true); - } // update projection matrix for proper view frustum culling + } + // 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); } }; - this.getCamera = function () { return cameraVR; }; - this.getFoveation = function () { if (glProjLayer !== null) { return glProjLayer.fixedFoveation; } - if (glBaseLayer !== null) { return glBaseLayer.fixedFoveation; } - return undefined; }; - this.setFoveation = function (foveation) { // 0 = no foveation = full resolution // 1 = maximum foveation = the edges render at lower resolution + if (glProjLayer !== null) { glProjLayer.fixedFoveation = foveation; } - if (glBaseLayer !== null && glBaseLayer.fixedFoveation !== undefined) { glBaseLayer.fixedFoveation = foveation; } - }; // Animation Loop + }; + this.getPlanes = function () { + return planes; + }; + // Animation Loop let onAnimationFrameCallback = null; - function onAnimationFrame(time, frame) { pose = frame.getViewerPose(customReferenceSpace || referenceSpace); xrFrame = frame; - if (pose !== null) { const views = pose.views; - if (glBaseLayer !== null) { renderer.setRenderTargetFramebuffer(newRenderTarget, glBaseLayer.framebuffer); renderer.setRenderTarget(newRenderTarget); } + let cameraVRNeedsUpdate = false; - let cameraVRNeedsUpdate = false; // check if it's necessary to rebuild cameraVR's camera list + // check if it's necessary to rebuild cameraVR's camera list if (views.length !== cameraVR.cameras.length) { cameraVR.cameras.length = 0; cameraVRNeedsUpdate = true; } - for (let i = 0; i < views.length; i++) { const view = views[i]; let viewport = null; - if (glBaseLayer !== null) { viewport = glBaseLayer.getViewport(view); } else { const glSubImage = glBinding.getViewSubImage(glProjLayer, view); - viewport = glSubImage.viewport; // For side-by-side projection, we only produce a single texture for both eyes. + viewport = glSubImage.viewport; + // For side-by-side projection, we only produce a single texture for both eyes. if (i === 0) { renderer.setRenderTargetTextures(newRenderTarget, glSubImage.colorTexture, glProjLayer.ignoreDepthValues ? undefined : glSubImage.depthStencilTexture); renderer.setRenderTarget(newRenderTarget); } } - let camera = cameras[i]; - if (camera === undefined) { camera = new PerspectiveCamera(); camera.layers.enable(i); camera.viewport = new Vector4(); cameras[i] = camera; } - camera.matrix.fromArray(view.transform.matrix); camera.projectionMatrix.fromArray(view.projectionMatrix); camera.viewport.set(viewport.x, viewport.y, viewport.width, viewport.height); - if (i === 0) { cameraVR.matrix.copy(camera.matrix); } - if (cameraVRNeedsUpdate === true) { cameraVR.cameras.push(camera); } } - } // + } + // for (let i = 0; i < controllers.length; i++) { const inputSource = controllerInputSources[i]; const controller = controllers[i]; - if (inputSource !== null && controller !== undefined) { controller.update(inputSource, frame, customReferenceSpace || referenceSpace); } } - if (onAnimationFrameCallback) onAnimationFrameCallback(time, frame); + if (frame.detectedPlanes) { + scope.dispatchEvent({ + type: 'planesdetected', + data: frame.detectedPlanes + }); + let planesToRemove = null; + for (const plane of planes) { + if (!frame.detectedPlanes.has(plane)) { + if (planesToRemove === null) { + planesToRemove = []; + } + planesToRemove.push(plane); + } + } + if (planesToRemove !== null) { + for (const plane of planesToRemove) { + planes.delete(plane); + planesLastChangedTimes.delete(plane); + scope.dispatchEvent({ + type: 'planeremoved', + data: plane + }); + } + } + for (const plane of frame.detectedPlanes) { + if (!planes.has(plane)) { + planes.add(plane); + planesLastChangedTimes.set(plane, frame.lastChangedTime); + scope.dispatchEvent({ + type: 'planeadded', + data: plane + }); + } else { + const lastKnownTime = planesLastChangedTimes.get(plane); + if (plane.lastChangedTime > lastKnownTime) { + planesLastChangedTimes.set(plane, plane.lastChangedTime); + scope.dispatchEvent({ + type: 'planechanged', + data: plane + }); + } + } + } + } xrFrame = null; } - const animation = new WebGLAnimation(); animation.setAnimationLoop(onAnimationFrame); - this.setAnimationLoop = function (callback) { onAnimationFrameCallback = callback; }; - this.dispose = function () {}; } - } function WebGLMaterials(renderer, properties) { function refreshFogUniforms(uniforms, fog) { - uniforms.fogColor.value.copy(fog.color); - + fog.color.getRGB(uniforms.fogColor.value, getUnlitUniformColorSpace(renderer)); if (fog.isFog) { uniforms.fogNear.value = fog.near; uniforms.fogFar.value = fog.far; @@ -18789,7 +16801,6 @@ function WebGLMaterials(renderer, properties) { uniforms.fogDensity.value = fog.density; } } - function refreshMaterialUniforms(uniforms, material, pixelRatio, height, transmissionRenderTarget) { if (material.isMeshBasicMaterial) { refreshUniformsCommon(uniforms, material); @@ -18804,7 +16815,6 @@ function WebGLMaterials(renderer, properties) { } else if (material.isMeshStandardMaterial) { refreshUniformsCommon(uniforms, material); refreshUniformsStandard(uniforms, material); - if (material.isMeshPhysicalMaterial) { refreshUniformsPhysical(uniforms, material, transmissionRenderTarget); } @@ -18820,7 +16830,6 @@ function WebGLMaterials(renderer, properties) { refreshUniformsCommon(uniforms, material); } else if (material.isLineBasicMaterial) { refreshUniformsLine(uniforms, material); - if (material.isLineDashedMaterial) { refreshUniformsDash(uniforms, material); } @@ -18838,55 +16847,43 @@ function WebGLMaterials(renderer, properties) { function refreshUniformsCommon(uniforms, material) { uniforms.opacity.value = material.opacity; - if (material.color) { uniforms.diffuse.value.copy(material.color); } - if (material.emissive) { uniforms.emissive.value.copy(material.emissive).multiplyScalar(material.emissiveIntensity); } - if (material.map) { uniforms.map.value = material.map; } - if (material.alphaMap) { uniforms.alphaMap.value = material.alphaMap; } - if (material.bumpMap) { uniforms.bumpMap.value = material.bumpMap; uniforms.bumpScale.value = material.bumpScale; if (material.side === BackSide) uniforms.bumpScale.value *= -1; } - if (material.displacementMap) { uniforms.displacementMap.value = material.displacementMap; uniforms.displacementScale.value = material.displacementScale; uniforms.displacementBias.value = material.displacementBias; } - if (material.emissiveMap) { uniforms.emissiveMap.value = material.emissiveMap; } - if (material.normalMap) { uniforms.normalMap.value = material.normalMap; uniforms.normalScale.value.copy(material.normalScale); if (material.side === BackSide) uniforms.normalScale.value.negate(); } - if (material.specularMap) { uniforms.specularMap.value = material.specularMap; } - if (material.alphaTest > 0) { uniforms.alphaTest.value = material.alphaTest; } - const envMap = properties.get(material).envMap; - if (envMap) { uniforms.envMap.value = envMap; uniforms.flipEnvMap.value = envMap.isCubeTexture && envMap.isRenderTargetTexture === false ? -1 : 1; @@ -18894,18 +16891,19 @@ function WebGLMaterials(renderer, properties) { uniforms.ior.value = material.ior; uniforms.refractionRatio.value = material.refractionRatio; } - if (material.lightMap) { - uniforms.lightMap.value = material.lightMap; // artist-friendly light intensity scaling factor + uniforms.lightMap.value = material.lightMap; + // artist-friendly light intensity scaling factor const scaleFactor = renderer.physicallyCorrectLights !== true ? Math.PI : 1; uniforms.lightMapIntensity.value = material.lightMapIntensity * scaleFactor; } - if (material.aoMap) { uniforms.aoMap.value = material.aoMap; uniforms.aoMapIntensity.value = material.aoMapIntensity; - } // uv repeat and offset setting priorities + } + + // uv repeat and offset setting priorities // 1. color map // 2. specular map // 3. displacementMap map @@ -18925,9 +16923,7 @@ function WebGLMaterials(renderer, properties) { // 17. transmission map // 18. thickness map - let uvScaleMap; - if (material.map) { uvScaleMap = material.map; } else if (material.specularMap) { @@ -18969,131 +16965,110 @@ function WebGLMaterials(renderer, properties) { } else if (material.sheenRoughnessMap) { uvScaleMap = material.sheenRoughnessMap; } - if (uvScaleMap !== undefined) { // backwards compatibility if (uvScaleMap.isWebGLRenderTarget) { uvScaleMap = uvScaleMap.texture; } - if (uvScaleMap.matrixAutoUpdate === true) { uvScaleMap.updateMatrix(); } - uniforms.uvTransform.value.copy(uvScaleMap.matrix); - } // uv repeat and offset setting priorities for uv2 + } + + // uv repeat and offset setting priorities for uv2 // 1. ao map // 2. light map - let uv2ScaleMap; - if (material.aoMap) { uv2ScaleMap = material.aoMap; } else if (material.lightMap) { uv2ScaleMap = material.lightMap; } - if (uv2ScaleMap !== undefined) { // backwards compatibility if (uv2ScaleMap.isWebGLRenderTarget) { uv2ScaleMap = uv2ScaleMap.texture; } - if (uv2ScaleMap.matrixAutoUpdate === true) { uv2ScaleMap.updateMatrix(); } - uniforms.uv2Transform.value.copy(uv2ScaleMap.matrix); } } - function refreshUniformsLine(uniforms, material) { uniforms.diffuse.value.copy(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 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; } - if (material.alphaMap) { uniforms.alphaMap.value = material.alphaMap; } - if (material.alphaTest > 0) { uniforms.alphaTest.value = material.alphaTest; - } // uv repeat and offset setting priorities + } + + // uv repeat and offset setting priorities // 1. color map // 2. alpha map - let uvScaleMap; - 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); } } - function refreshUniformsSprites(uniforms, material) { uniforms.diffuse.value.copy(material.color); uniforms.opacity.value = material.opacity; uniforms.rotation.value = material.rotation; - if (material.map) { uniforms.map.value = material.map; } - if (material.alphaMap) { uniforms.alphaMap.value = material.alphaMap; } - if (material.alphaTest > 0) { uniforms.alphaTest.value = material.alphaTest; - } // uv repeat and offset setting priorities + } + + // uv repeat and offset setting priorities // 1. color map // 2. alpha map - let uvScaleMap; - 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); } } - 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 ) @@ -19104,123 +17079,96 @@ function WebGLMaterials(renderer, properties) { uniforms.gradientMap.value = material.gradientMap; } } - 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; } - const envMap = properties.get(material).envMap; - if (envMap) { //uniforms.envMap.value = material.envMap; // part of uniforms common uniforms.envMapIntensity.value = material.envMapIntensity; } } - function refreshUniformsPhysical(uniforms, material, transmissionRenderTarget) { uniforms.ior.value = material.ior; // also part of uniforms common if (material.sheen > 0) { uniforms.sheenColor.value.copy(material.sheenColor).multiplyScalar(material.sheen); uniforms.sheenRoughness.value = material.sheenRoughness; - if (material.sheenColorMap) { uniforms.sheenColorMap.value = material.sheenColorMap; } - if (material.sheenRoughnessMap) { uniforms.sheenRoughnessMap.value = material.sheenRoughnessMap; } } - if (material.clearcoat > 0) { uniforms.clearcoat.value = material.clearcoat; uniforms.clearcoatRoughness.value = material.clearcoatRoughness; - if (material.clearcoatMap) { uniforms.clearcoatMap.value = material.clearcoatMap; } - if (material.clearcoatRoughnessMap) { uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap; } - if (material.clearcoatNormalMap) { uniforms.clearcoatNormalScale.value.copy(material.clearcoatNormalScale); uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap; - if (material.side === BackSide) { uniforms.clearcoatNormalScale.value.negate(); } } } - if (material.iridescence > 0) { uniforms.iridescence.value = material.iridescence; uniforms.iridescenceIOR.value = material.iridescenceIOR; uniforms.iridescenceThicknessMinimum.value = material.iridescenceThicknessRange[0]; uniforms.iridescenceThicknessMaximum.value = material.iridescenceThicknessRange[1]; - if (material.iridescenceMap) { uniforms.iridescenceMap.value = material.iridescenceMap; } - if (material.iridescenceThicknessMap) { uniforms.iridescenceThicknessMap.value = material.iridescenceThicknessMap; } } - if (material.transmission > 0) { uniforms.transmission.value = material.transmission; uniforms.transmissionSamplerMap.value = transmissionRenderTarget.texture; uniforms.transmissionSamplerSize.value.set(transmissionRenderTarget.width, transmissionRenderTarget.height); - if (material.transmissionMap) { uniforms.transmissionMap.value = material.transmissionMap; } - uniforms.thickness.value = material.thickness; - if (material.thicknessMap) { uniforms.thicknessMap.value = material.thicknessMap; } - uniforms.attenuationDistance.value = material.attenuationDistance; uniforms.attenuationColor.value.copy(material.attenuationColor); } - uniforms.specularIntensity.value = material.specularIntensity; uniforms.specularColor.value.copy(material.specularColor); - if (material.specularIntensityMap) { uniforms.specularIntensityMap.value = material.specularIntensityMap; } - if (material.specularColorMap) { uniforms.specularColorMap.value = material.specularColorMap; } } - function refreshUniformsMatcap(uniforms, material) { if (material.matcap) { uniforms.matcap.value = material.matcap; } } - function refreshUniformsDistance(uniforms, material) { uniforms.referencePosition.value.copy(material.referencePosition); uniforms.nearDistance.value = material.nearDistance; uniforms.farDistance.value = material.farDistance; } - return { refreshFogUniforms: refreshFogUniforms, refreshMaterialUniforms: refreshMaterialUniforms @@ -19237,31 +17185,31 @@ function WebGLUniformsGroups(gl, info, capabilities, state) { const webglProgram = program.program; state.uniformBlockBinding(uniformsGroup, webglProgram); } - function update(uniformsGroup, program) { let buffer = buffers[uniformsGroup.id]; - if (buffer === undefined) { prepareUniformsGroup(uniformsGroup); buffer = createBuffer(uniformsGroup); buffers[uniformsGroup.id] = buffer; uniformsGroup.addEventListener('dispose', onUniformsGroupsDispose); - } // ensure to update the binding points/block indices mapping for this program + } + // ensure to update the binding points/block indices mapping for this program const webglProgram = program.program; - state.updateUBOMapping(uniformsGroup, webglProgram); // update UBO once per frame + state.updateUBOMapping(uniformsGroup, webglProgram); - const frame = info.render.frame; + // update UBO once per frame + const frame = info.render.frame; if (updateList[uniformsGroup.id] !== frame) { updateBufferData(uniformsGroup); updateList[uniformsGroup.id] = frame; } } - function createBuffer(uniformsGroup) { // the setup of an UBO is independent of a particular shader program but global + const bindingPointIndex = allocateBindingPointIndex(); uniformsGroup.__bindingPointIndex = bindingPointIndex; const buffer = gl.createBuffer(); @@ -19273,7 +17221,6 @@ function WebGLUniformsGroups(gl, info, capabilities, state) { gl.bindBufferBase(gl.UNIFORM_BUFFER, bindingPointIndex, buffer); return buffer; } - function allocateBindingPointIndex() { for (let i = 0; i < maxBindingPoints; i++) { if (allocatedBindingPoints.indexOf(i) === -1) { @@ -19281,30 +17228,29 @@ function WebGLUniformsGroups(gl, info, capabilities, state) { return i; } } - console.error('THREE.WebGLRenderer: Maximum number of simultaneously usable uniforms groups reached.'); return 0; } - function updateBufferData(uniformsGroup) { const buffer = buffers[uniformsGroup.id]; const uniforms = uniformsGroup.uniforms; const cache = uniformsGroup.__cache; gl.bindBuffer(gl.UNIFORM_BUFFER, buffer); - for (let i = 0, il = uniforms.length; i < il; i++) { - const uniform = uniforms[i]; // partly update the buffer if necessary + const uniform = uniforms[i]; + + // partly update the buffer if necessary if (hasUniformChanged(uniform, i, cache) === true) { const value = uniform.value; const offset = uniform.__offset; - if (typeof value === 'number') { uniform.__data[0] = value; gl.bufferSubData(gl.UNIFORM_BUFFER, offset, uniform.__data); } else { if (uniform.value.isMatrix3) { // manually converting 3x3 to 3x4 + uniform.__data[0] = uniform.value.elements[0]; uniform.__data[1] = uniform.value.elements[1]; uniform.__data[2] = uniform.value.elements[2]; @@ -19320,29 +17266,26 @@ function WebGLUniformsGroups(gl, info, capabilities, state) { } else { value.toArray(uniform.__data); } - gl.bufferSubData(gl.UNIFORM_BUFFER, offset, uniform.__data); } } } - gl.bindBuffer(gl.UNIFORM_BUFFER, null); } - function hasUniformChanged(uniform, index, cache) { const value = uniform.value; - if (cache[index] === undefined) { // cache entry does not exist so far + if (typeof value === 'number') { cache[index] = value; } else { cache[index] = value.clone(); } - return true; } else { // compare current value with cached entry + if (typeof value === 'number') { if (cache[index] !== value) { cache[index] = value; @@ -19350,88 +17293,99 @@ function WebGLUniformsGroups(gl, info, capabilities, state) { } } else { const cachedObject = cache[index]; - if (cachedObject.equals(value) === false) { cachedObject.copy(value); return true; } } } - return false; } - function prepareUniformsGroup(uniformsGroup) { // determine total buffer size according to the STD140 layout // Hint: STD140 is the only supported layout in WebGL 2 + const uniforms = uniformsGroup.uniforms; let offset = 0; // global buffer offset in bytes - const chunkSize = 16; // size of a chunk in bytes - let chunkOffset = 0; // offset within a single chunk in bytes for (let i = 0, l = uniforms.length; i < l; i++) { const uniform = uniforms[i]; - const info = getUniformSize(uniform); // the following two properties will be used for partial buffer updates + const info = getUniformSize(uniform); + + // the following two properties will be used for partial buffer updates uniform.__data = new Float32Array(info.storage / Float32Array.BYTES_PER_ELEMENT); - uniform.__offset = offset; // + uniform.__offset = offset; + + // if (i > 0) { chunkOffset = offset % chunkSize; - const remainingSizeInChunk = chunkSize - chunkOffset; // check for chunk overflow + const remainingSizeInChunk = chunkSize - chunkOffset; + + // check for chunk overflow if (chunkOffset !== 0 && remainingSizeInChunk - info.boundary < 0) { // add padding and adjust offset + offset += chunkSize - chunkOffset; uniform.__offset = offset; } } - offset += info.storage; - } // ensure correct final padding + } + // ensure correct final padding chunkOffset = offset % chunkSize; - if (chunkOffset > 0) offset += chunkSize - chunkOffset; // + if (chunkOffset > 0) offset += chunkSize - chunkOffset; + + // uniformsGroup.__size = offset; uniformsGroup.__cache = {}; return this; } - function getUniformSize(uniform) { const value = uniform.value; const info = { boundary: 0, // bytes storage: 0 // bytes + }; - }; // determine sizes according to STD140 + // determine sizes according to STD140 if (typeof value === 'number') { // float/int + info.boundary = 4; info.storage = 4; } else if (value.isVector2) { // vec2 + info.boundary = 8; info.storage = 8; } else if (value.isVector3 || value.isColor) { // vec3 + info.boundary = 16; info.storage = 12; // evil: vec3 must start on a 16-byte boundary but it only consumes 12 bytes } else if (value.isVector4) { // vec4 + info.boundary = 16; info.storage = 16; } else if (value.isMatrix3) { // mat3 (in STD140 a 3x3 matrix is represented as 3x4) + info.boundary = 48; info.storage = 48; } else if (value.isMatrix4) { // mat4 + info.boundary = 64; info.storage = 64; } else if (value.isTexture) { @@ -19439,10 +17393,8 @@ function WebGLUniformsGroups(gl, info, capabilities, state) { } else { console.warn('THREE.WebGLRenderer: Unsupported uniform value type.', value); } - return info; } - function onUniformsGroupsDispose(event) { const uniformsGroup = event.target; uniformsGroup.removeEventListener('dispose', onUniformsGroupsDispose); @@ -19452,17 +17404,14 @@ function WebGLUniformsGroups(gl, info, capabilities, state) { delete buffers[uniformsGroup.id]; delete updateList[uniformsGroup.id]; } - function dispose() { for (const id in buffers) { gl.deleteBuffer(buffers[id]); } - allocatedBindingPoints = []; buffers = {}; updateList = {}; } - return { bind: bind, update: update, @@ -19475,119 +17424,119 @@ function createCanvasElement() { canvas.style.display = 'block'; return canvas; } - function WebGLRenderer(parameters = {}) { this.isWebGLRenderer = true; - const _canvas = parameters.canvas !== undefined ? parameters.canvas : createCanvasElement(), - _context = parameters.context !== undefined ? parameters.context : null, - _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; - + _context = parameters.context !== undefined ? parameters.context : null, + _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; let _alpha; - if (_context !== null) { _alpha = _context.getContextAttributes().alpha; } else { _alpha = parameters.alpha !== undefined ? parameters.alpha : false; } - let currentRenderList = null; - let currentRenderState = null; // render() can be called from within a callback triggered by another render. + let currentRenderState = null; + + // render() can be called from within a callback triggered by another render. // We track this so that the nested render call gets its list and state isolated from the parent render call. const renderListStack = []; - const renderStateStack = []; // public properties + const renderStateStack = []; + + // public properties - this.domElement = _canvas; // Debug configuration container + this.domElement = _canvas; + // Debug configuration container this.debug = { /** * Enables error checking and reporting when shader programs are being compiled * @type {boolean} */ checkShaderErrors: true - }; // clearing + }; + + // clearing this.autoClear = true; this.autoClearColor = true; this.autoClearDepth = true; - this.autoClearStencil = true; // scene graph + this.autoClearStencil = true; - this.sortObjects = true; // user-defined clipping + // scene graph + + this.sortObjects = true; + + // user-defined clipping this.clippingPlanes = []; - this.localClippingEnabled = false; // physically based shading + this.localClippingEnabled = false; + + // physically based shading + + this.outputEncoding = LinearEncoding; - this.outputEncoding = LinearEncoding; // physical lights + // physical lights - this.physicallyCorrectLights = false; // tone mapping + this.physicallyCorrectLights = false; + + // tone mapping this.toneMapping = NoToneMapping; - this.toneMappingExposure = 1.0; // + this.toneMappingExposure = 1.0; - Object.defineProperties(this, { - // @deprecated since r136, 0e21088102b4de7e0a0a33140620b7a3424b9e6d - gammaFactor: { - get: function () { - console.warn('THREE.WebGLRenderer: .gammaFactor has been removed.'); - return 2; - }, - set: function () { - console.warn('THREE.WebGLRenderer: .gammaFactor has been removed.'); - } - } - }); // internal properties + // internal properties const _this = this; + let _isContextLost = false; - let _isContextLost = false; // internal state cache + // internal state cache let _currentActiveCubeFace = 0; let _currentActiveMipmapLevel = 0; let _currentRenderTarget = null; - let _currentMaterialId = -1; - let _currentCamera = null; - const _currentViewport = new Vector4(); - const _currentScissor = new Vector4(); + let _currentScissorTest = null; - let _currentScissorTest = null; // + // let _width = _canvas.width; let _height = _canvas.height; let _pixelRatio = 1; let _opaqueSort = null; let _transparentSort = null; - const _viewport = new Vector4(0, 0, _width, _height); - const _scissor = new Vector4(0, 0, _width, _height); + let _scissorTest = false; - let _scissorTest = false; // frustum + // frustum - const _frustum = new Frustum(); // clipping + const _frustum = new Frustum(); + // clipping let _clippingEnabled = false; - let _localClippingEnabled = false; // transmission + let _localClippingEnabled = false; - let _transmissionRenderTarget = null; // camera matrices cache + // transmission - const _projScreenMatrix = new Matrix4(); + let _transmissionRenderTarget = null; - const _vector2 = new Vector2(); + // camera matrices cache + const _projScreenMatrix = new Matrix4(); + const _vector2 = new Vector2(); const _vector3 = new Vector3(); - const _emptyScene = { background: null, fog: null, @@ -19595,26 +17544,21 @@ function WebGLRenderer(parameters = {}) { overrideMaterial: null, isScene: true }; - function getTargetPixelRatio() { return _currentRenderTarget === null ? _pixelRatio : 1; - } // initialize + } + // initialize let _gl = _context; - function getContext(contextNames, contextAttributes) { for (let i = 0; i < contextNames.length; i++) { const contextName = contextNames[i]; - const context = _canvas.getContext(contextName, contextAttributes); - if (context !== null) return context; } - return null; } - try { const contextAttributes = { alpha: true, @@ -19625,25 +17569,21 @@ function WebGLRenderer(parameters = {}) { preserveDrawingBuffer: _preserveDrawingBuffer, powerPreference: _powerPreference, failIfMajorPerformanceCaveat: _failIfMajorPerformanceCaveat - }; // OffscreenCanvas does not have setAttribute, see #22811 + }; - if ('setAttribute' in _canvas) _canvas.setAttribute('data-engine', `three.js r${REVISION}`); // event listeners must be registered before WebGL context is created, see #12753 + // OffscreenCanvas does not have setAttribute, see #22811 + if ('setAttribute' in _canvas) _canvas.setAttribute('data-engine', `three.js r${REVISION}`); + // event listeners must be registered before WebGL context is created, see #12753 _canvas.addEventListener('webglcontextlost', onContextLost, false); - _canvas.addEventListener('webglcontextrestored', onContextRestore, false); - _canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false); - if (_gl === null) { const contextNames = ['webgl2', 'webgl', 'experimental-webgl']; - 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.'); @@ -19651,8 +17591,9 @@ function WebGLRenderer(parameters = {}) { throw new Error('Error creating WebGL context.'); } } - } // Some experimental-webgl implementations do not have getShaderPrecisionFormat + } + // Some experimental-webgl implementations do not have getShaderPrecisionFormat if (_gl.getShaderPrecisionFormat === undefined) { _gl.getShaderPrecisionFormat = function () { @@ -19667,13 +17608,11 @@ function WebGLRenderer(parameters = {}) { console.error('THREE.WebGLRenderer: ' + error.message); throw error; } - let extensions, capabilities, state, info; let properties, textures, cubemaps, cubeuvmaps, attributes, geometries, objects; let programCache, materials, renderLists, renderStates, clipping, shadowMap; let background, morphtargets, bufferRenderer, indexedBufferRenderer; let utils, bindingStates, uniformsGroups; - function initGLContext() { extensions = new WebGLExtensions(_gl); capabilities = new WebGLCapabilities(_gl, extensions, parameters); @@ -19695,7 +17634,7 @@ function WebGLRenderer(parameters = {}) { materials = new WebGLMaterials(_this, properties); renderLists = new WebGLRenderLists(); renderStates = new WebGLRenderStates(extensions, capabilities); - background = new WebGLBackground(_this, cubemaps, state, objects, _alpha, _premultipliedAlpha); + background = new WebGLBackground(_this, cubemaps, cubeuvmaps, state, objects, _alpha, _premultipliedAlpha); shadowMap = new WebGLShadowMap(_this, objects, capabilities); uniformsGroups = new WebGLUniformsGroups(_gl, info, capabilities, state); bufferRenderer = new WebGLBufferRenderer(_gl, extensions, info, capabilities); @@ -19709,67 +17648,58 @@ function WebGLRenderer(parameters = {}) { _this.state = state; _this.info = info; } + initGLContext(); - initGLContext(); // xr + // xr const xr = new WebXRManager(_this, _gl); - this.xr = xr; // API + this.xr = xr; + + // API this.getContext = function () { return _gl; }; - this.getContextAttributes = function () { return _gl.getContextAttributes(); }; - this.forceContextLoss = function () { const extension = extensions.get('WEBGL_lose_context'); if (extension) extension.loseContext(); }; - this.forceContextRestore = function () { const extension = extensions.get('WEBGL_lose_context'); if (extension) extension.restoreContext(); }; - this.getPixelRatio = function () { return _pixelRatio; }; - this.setPixelRatio = function (value) { if (value === undefined) return; _pixelRatio = value; this.setSize(_width, _height, false); }; - this.getSize = function (target) { 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; } - _width = width; _height = height; _canvas.width = Math.floor(width * _pixelRatio); _canvas.height = Math.floor(height * _pixelRatio); - if (updateStyle !== false) { _canvas.style.width = width + 'px'; _canvas.style.height = height + 'px'; } - this.setViewport(0, 0, width, height); }; - this.getDrawingBufferSize = function (target) { return target.set(_width * _pixelRatio, _height * _pixelRatio).floor(); }; - this.setDrawingBufferSize = function (width, height, pixelRatio) { _width = width; _height = height; @@ -19778,101 +17708,81 @@ function WebGLRenderer(parameters = {}) { _canvas.height = Math.floor(height * pixelRatio); this.setViewport(0, 0, width, height); }; - this.getCurrentViewport = function (target) { return target.copy(_currentViewport); }; - this.getViewport = function (target) { return target.copy(_viewport); }; - 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); } - state.viewport(_currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor()); }; - 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); } - state.scissor(_currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor()); }; - this.getScissorTest = function () { return _scissorTest; }; - this.setScissorTest = function (boolean) { state.setScissorTest(_scissorTest = boolean); }; - this.setOpaqueSort = function (method) { _opaqueSort = method; }; - this.setTransparentSort = function (method) { _transparentSort = method; - }; // Clearing + }; + // Clearing this.getClearColor = function (target) { return target.copy(background.getClearColor()); }; - this.setClearColor = function () { background.setClearColor.apply(background, arguments); }; - this.getClearAlpha = function () { return background.getClearAlpha(); }; - this.setClearAlpha = function () { background.setClearAlpha.apply(background, arguments); }; - this.clear = function (color = true, depth = true, stencil = true) { let bits = 0; if (color) bits |= _gl.COLOR_BUFFER_BIT; if (depth) bits |= _gl.DEPTH_BUFFER_BIT; if (stencil) bits |= _gl.STENCIL_BUFFER_BIT; - _gl.clear(bits); }; - this.clearColor = function () { this.clear(true, false, false); }; - this.clearDepth = function () { this.clear(false, true, false); }; - this.clearStencil = function () { this.clear(false, false, true); - }; // + }; + // this.dispose = function () { _canvas.removeEventListener('webglcontextlost', onContextLost, false); - _canvas.removeEventListener('webglcontextrestored', onContextRestore, false); - _canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false); - renderLists.dispose(); renderStates.dispose(); properties.dispose(); @@ -19885,25 +17795,21 @@ function WebGLRenderer(parameters = {}) { xr.dispose(); xr.removeEventListener('sessionstart', onXRSessionStart); xr.removeEventListener('sessionend', onXRSessionEnd); - if (_transmissionRenderTarget) { _transmissionRenderTarget.dispose(); - _transmissionRenderTarget = null; } - animation.stop(); - }; // Events + }; + // Events function onContextLost(event) { event.preventDefault(); console.log('THREE.WebGLRenderer: Context Lost.'); _isContextLost = true; } - - function - /* event */ + function /* event */ onContextRestore() { console.log('THREE.WebGLRenderer: Context Restored.'); _isContextLost = false; @@ -19919,82 +17825,83 @@ function WebGLRenderer(parameters = {}) { shadowMap.needsUpdate = shadowMapNeedsUpdate; shadowMap.type = shadowMapType; } - function onContextCreationError(event) { console.error('THREE.WebGLRenderer: A WebGL context could not be created. Reason: ', event.statusMessage); } - function onMaterialDispose(event) { const material = event.target; material.removeEventListener('dispose', onMaterialDispose); deallocateMaterial(material); - } // Buffer deallocation + } + // Buffer deallocation function deallocateMaterial(material) { releaseMaterialProgramReferences(material); properties.remove(material); } - function releaseMaterialProgramReferences(material) { const programs = properties.get(material).programs; - if (programs !== undefined) { programs.forEach(function (program) { programCache.releaseProgram(program); }); - if (material.isShaderMaterial) { programCache.releaseShaderCache(material); } } - } // Buffer rendering + } + // Buffer rendering this.renderBufferDirect = function (camera, scene, geometry, material, object, group) { if (scene === null) scene = _emptyScene; // renderBufferDirect second parameter used to be fog (could be null) const frontFaceCW = object.isMesh && object.matrixWorld.determinant() < 0; const program = setProgram(camera, scene, geometry, material, object); - state.setMaterial(material, frontFaceCW); // - - let index = geometry.index; - const position = geometry.attributes.position; // - - if (index === null) { - if (position === undefined || position.count === 0) return; - } else if (index.count === 0) { - return; - } // + state.setMaterial(material, frontFaceCW); + // + let index = geometry.index; let rangeFactor = 1; - if (material.wireframe === true) { index = geometries.getWireframeAttribute(geometry); rangeFactor = 2; } + // + + const drawRange = geometry.drawRange; + const position = geometry.attributes.position; + let drawStart = drawRange.start * rangeFactor; + let drawEnd = (drawRange.start + drawRange.count) * rangeFactor; + if (group !== null) { + drawStart = Math.max(drawStart, group.start * rangeFactor); + drawEnd = Math.min(drawEnd, (group.start + group.count) * rangeFactor); + } + if (index !== null) { + drawStart = Math.max(drawStart, 0); + drawEnd = Math.min(drawEnd, index.count); + } else if (position !== undefined && position !== null) { + drawStart = Math.max(drawStart, 0); + drawEnd = Math.min(drawEnd, position.count); + } + const drawCount = drawEnd - drawStart; + if (drawCount < 0 || drawCount === Infinity) return; + + // + bindingStates.setup(object, material, program, geometry, index); let attribute; let renderer = bufferRenderer; - if (index !== null) { attribute = attributes.get(index); renderer = indexedBufferRenderer; renderer.setIndex(attribute); - } // - + } - const dataCount = index !== null ? index.count : position.count; - const rangeStart = geometry.drawRange.start * rangeFactor; - const rangeCount = geometry.drawRange.count * rangeFactor; - const groupStart = group !== null ? group.start * rangeFactor : 0; - const groupCount = group !== null ? group.count * rangeFactor : Infinity; - const drawStart = Math.max(rangeStart, groupStart); - const drawEnd = Math.min(dataCount, rangeStart + rangeCount, groupStart + groupCount) - 1; - const drawCount = Math.max(0, drawEnd - drawStart + 1); - if (drawCount === 0) return; // + // if (object.isMesh) { if (material.wireframe === true) { @@ -20008,7 +17915,6 @@ function WebGLRenderer(parameters = {}) { if (lineWidth === undefined) lineWidth = 1; // Not using Line*Material state.setLineWidth(lineWidth * getTargetPixelRatio()); - if (object.isLineSegments) { renderer.setMode(_gl.LINES); } else if (object.isLineLoop) { @@ -20021,26 +17927,39 @@ function WebGLRenderer(parameters = {}) { } else if (object.isSprite) { renderer.setMode(_gl.TRIANGLES); } - if (object.isInstancedMesh) { renderer.renderInstances(drawStart, drawCount, object.count); } else if (geometry.isInstancedBufferGeometry) { - const instanceCount = Math.min(geometry.instanceCount, geometry._maxInstanceCount); + const maxInstanceCount = geometry._maxInstanceCount !== undefined ? geometry._maxInstanceCount : Infinity; + const instanceCount = Math.min(geometry.instanceCount, maxInstanceCount); renderer.renderInstances(drawStart, drawCount, instanceCount); } else { renderer.render(drawStart, drawCount); } - }; // Compile + }; + // Compile this.compile = function (scene, camera) { + function prepare(material, scene, object) { + if (material.transparent === true && material.side === DoubleSide) { + material.side = BackSide; + material.needsUpdate = true; + getProgram(material, scene, object); + material.side = FrontSide; + material.needsUpdate = true; + getProgram(material, scene, object); + material.side = DoubleSide; + } else { + getProgram(material, scene, object); + } + } currentRenderState = renderStates.get(scene); currentRenderState.init(); renderStateStack.push(currentRenderState); scene.traverseVisible(function (object) { if (object.isLight && object.layers.test(camera.layers)) { currentRenderState.pushLight(object); - if (object.castShadow) { currentRenderState.pushShadow(object); } @@ -20049,77 +17968,72 @@ function WebGLRenderer(parameters = {}) { currentRenderState.setupLights(_this.physicallyCorrectLights); scene.traverse(function (object) { const material = object.material; - if (material) { if (Array.isArray(material)) { for (let i = 0; i < material.length; i++) { const material2 = material[i]; - getProgram(material2, scene, object); + prepare(material2, scene, object); } } else { - getProgram(material, scene, object); + prepare(material, scene, object); } } }); renderStateStack.pop(); currentRenderState = null; - }; // Animation Loop + }; + // Animation Loop let onAnimationFrameCallback = null; - function onAnimationFrame(time) { if (onAnimationFrameCallback) onAnimationFrameCallback(time); } - function onXRSessionStart() { animation.stop(); } - function onXRSessionEnd() { animation.start(); } - const animation = new WebGLAnimation(); animation.setAnimationLoop(onAnimationFrame); if (typeof self !== 'undefined') animation.setContext(self); - this.setAnimationLoop = function (callback) { onAnimationFrameCallback = callback; xr.setAnimationLoop(callback); callback === null ? animation.stop() : animation.start(); }; - xr.addEventListener('sessionstart', onXRSessionStart); - xr.addEventListener('sessionend', onXRSessionEnd); // Rendering + xr.addEventListener('sessionend', onXRSessionEnd); + + // Rendering this.render = function (scene, camera) { if (camera !== undefined && camera.isCamera !== true) { console.error('THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.'); return; } + if (_isContextLost === true) return; - if (_isContextLost === true) return; // update scene graph + // update scene graph - if (scene.autoUpdate === true) scene.updateMatrixWorld(); // update camera matrices and frustum + if (scene.matrixWorldAutoUpdate === true) scene.updateMatrixWorld(); - if (camera.parent === null) camera.updateMatrixWorld(); + // update camera matrices and frustum + if (camera.parent === null && camera.matrixWorldAutoUpdate === true) camera.updateMatrixWorld(); if (xr.enabled === true && xr.isPresenting === true) { if (xr.cameraAutoUpdate === true) xr.updateCamera(camera); camera = xr.getCamera(); // use XR camera for rendering - } // - + } + // if (scene.isScene === true) scene.onBeforeRender(_this, scene, camera, _currentRenderTarget); currentRenderState = renderStates.get(scene, renderStateStack.length); currentRenderState.init(); renderStateStack.push(currentRenderState); - _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); - _frustum.setFromProjectionMatrix(_projScreenMatrix); - _localClippingEnabled = this.localClippingEnabled; _clippingEnabled = clipping.init(this.clippingPlanes, _localClippingEnabled, camera); currentRenderList = renderLists.get(scene, renderListStack.length); @@ -20127,69 +18041,75 @@ function WebGLRenderer(parameters = {}) { renderListStack.push(currentRenderList); projectObject(scene, camera, 0, _this.sortObjects); currentRenderList.finish(); - if (_this.sortObjects === true) { currentRenderList.sort(_opaqueSort, _transparentSort); - } // + } + // if (_clippingEnabled === true) clipping.beginShadows(); const shadowsArray = currentRenderState.state.shadowsArray; shadowMap.render(shadowsArray, scene, camera); - if (_clippingEnabled === true) clipping.endShadows(); // + if (_clippingEnabled === true) clipping.endShadows(); - if (this.info.autoReset === true) this.info.reset(); // + // - background.render(currentRenderList, scene); // render scene + if (this.info.autoReset === true) this.info.reset(); - currentRenderState.setupLights(_this.physicallyCorrectLights); + // + + background.render(currentRenderList, scene); + // render scene + + currentRenderState.setupLights(_this.physicallyCorrectLights); if (camera.isArrayCamera) { const cameras = camera.cameras; - for (let i = 0, l = cameras.length; i < l; i++) { const camera2 = cameras[i]; renderScene(currentRenderList, scene, camera2, camera2.viewport); } } else { renderScene(currentRenderList, scene, camera); - } // + } + // if (_currentRenderTarget !== null) { // resolve multisample renderbuffers to a single-sample texture if necessary - textures.updateMultisampleRenderTarget(_currentRenderTarget); // Generate mipmap if we're using any kind of mipmap filtering + + textures.updateMultisampleRenderTarget(_currentRenderTarget); + + // Generate mipmap if we're using any kind of mipmap filtering textures.updateRenderTargetMipmap(_currentRenderTarget); - } // + } + // + + if (scene.isScene === true) scene.onAfterRender(_this, scene, camera); - if (scene.isScene === true) scene.onAfterRender(_this, scene, camera); // _gl.finish(); + // _gl.finish(); bindingStates.resetDefaultState(); _currentMaterialId = -1; _currentCamera = null; renderStateStack.pop(); - if (renderStateStack.length > 0) { currentRenderState = renderStateStack[renderStateStack.length - 1]; } else { currentRenderState = null; } - renderListStack.pop(); - if (renderListStack.length > 0) { currentRenderList = renderListStack[renderListStack.length - 1]; } else { currentRenderList = null; } }; - function projectObject(object, camera, groupOrder, sortObjects) { if (object.visible === false) return; const visible = object.layers.test(camera.layers); - if (visible) { if (object.isGroup) { groupOrder = object.renderOrder; @@ -20197,7 +18117,6 @@ function WebGLRenderer(parameters = {}) { if (object.autoUpdate === true) object.update(camera); } else if (object.isLight) { currentRenderState.pushLight(object); - if (object.castShadow) { currentRenderState.pushShadow(object); } @@ -20206,10 +18125,8 @@ function WebGLRenderer(parameters = {}) { if (sortObjects) { _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); } - const geometry = objects.update(object); const material = object.material; - if (material.visible) { currentRenderList.push(object, geometry, material, groupOrder, _vector3.z, null); } @@ -20217,27 +18134,23 @@ function WebGLRenderer(parameters = {}) { } 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; } } - if (!object.frustumCulled || _frustum.intersectsObject(object)) { if (sortObjects) { _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); } - const geometry = objects.update(object); const material = object.material; - if (Array.isArray(material)) { const groups = geometry.groups; - for (let i = 0, l = groups.length; i < l; i++) { const group = groups[i]; const groupMaterial = material[group.materialIndex]; - if (groupMaterial && groupMaterial.visible) { currentRenderList.push(object, geometry, groupMaterial, groupOrder, _vector3.z, group); } @@ -20248,14 +18161,11 @@ function WebGLRenderer(parameters = {}) { } } } - const children = object.children; - for (let i = 0, l = children.length; i < l; i++) { projectObject(children[i], camera, groupOrder, sortObjects); } } - function renderScene(currentRenderList, scene, camera, viewport) { const opaqueObjects = currentRenderList.opaque; const transmissiveObjects = currentRenderList.transmissive; @@ -20265,17 +18175,17 @@ function WebGLRenderer(parameters = {}) { if (viewport) state.viewport(_currentViewport.copy(viewport)); if (opaqueObjects.length > 0) renderObjects(opaqueObjects, scene, camera); if (transmissiveObjects.length > 0) renderObjects(transmissiveObjects, scene, camera); - if (transparentObjects.length > 0) renderObjects(transparentObjects, scene, camera); // Ensure depth buffer writing is enabled so it can be cleared on next render + if (transparentObjects.length > 0) renderObjects(transparentObjects, scene, camera); + + // Ensure depth buffer writing is enabled so it can be cleared on next render state.buffers.depth.setTest(true); state.buffers.depth.setMask(true); state.buffers.color.setMask(true); state.setPolygonOffset(false); } - function renderTransmissionPass(opaqueObjects, scene, camera) { const isWebGL2 = capabilities.isWebGL2; - if (_transmissionRenderTarget === null) { _transmissionRenderTarget = new WebGLRenderTarget(1, 1, { generateMipmaps: true, @@ -20284,75 +18194,60 @@ function WebGLRenderer(parameters = {}) { samples: isWebGL2 && _antialias === true ? 4 : 0 }); } - _this.getDrawingBufferSize(_vector2); - if (isWebGL2) { _transmissionRenderTarget.setSize(_vector2.x, _vector2.y); } else { _transmissionRenderTarget.setSize(floorPowerOfTwo(_vector2.x), floorPowerOfTwo(_vector2.y)); - } // + } + // const currentRenderTarget = _this.getRenderTarget(); - _this.setRenderTarget(_transmissionRenderTarget); + _this.clear(); - _this.clear(); // Turn off the features which can affect the frag color for opaque objects pass. + // Turn off the features which can affect the frag color for opaque objects pass. // Otherwise they are applied twice in opaque objects pass and transmission objects pass. - - const currentToneMapping = _this.toneMapping; _this.toneMapping = NoToneMapping; renderObjects(opaqueObjects, scene, camera); _this.toneMapping = currentToneMapping; textures.updateMultisampleRenderTarget(_transmissionRenderTarget); textures.updateRenderTargetMipmap(_transmissionRenderTarget); - _this.setRenderTarget(currentRenderTarget); } - function renderObjects(renderList, scene, camera) { const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null; - for (let i = 0, l = renderList.length; i < l; i++) { const renderItem = renderList[i]; const object = renderItem.object; const geometry = renderItem.geometry; const material = overrideMaterial === null ? renderItem.material : overrideMaterial; const group = renderItem.group; - if (object.layers.test(camera.layers)) { renderObject(object, scene, camera, geometry, material, group); } } } - function renderObject(object, scene, camera, geometry, material, group) { object.onBeforeRender(_this, scene, camera, geometry, material, group); object.modelViewMatrix.multiplyMatrices(camera.matrixWorldInverse, object.matrixWorld); object.normalMatrix.getNormalMatrix(object.modelViewMatrix); material.onBeforeRender(_this, scene, camera, geometry, object, group); - if (material.transparent === true && material.side === DoubleSide) { material.side = BackSide; material.needsUpdate = true; - _this.renderBufferDirect(camera, scene, geometry, material, object, group); - material.side = FrontSide; material.needsUpdate = true; - _this.renderBufferDirect(camera, scene, geometry, material, object, group); - material.side = DoubleSide; } else { _this.renderBufferDirect(camera, scene, geometry, material, object, group); } - object.onAfterRender(_this, scene, camera, geometry, material, group); } - function getProgram(material, scene, object) { if (scene.isScene !== true) scene = _emptyScene; // scene could be a Mesh, Line, Points, ... @@ -20362,23 +18257,24 @@ function WebGLRenderer(parameters = {}) { const lightsStateVersion = lights.state.version; const parameters = programCache.getParameters(material, lights.state, shadowsArray, scene, object); const programCacheKey = programCache.getProgramCacheKey(parameters); - let programs = materialProperties.programs; // always update environment and fog - changing these trigger an getProgram call, but it's possible that the program doesn't change + let programs = materialProperties.programs; + + // always update environment and fog - changing these trigger an getProgram call, but it's possible that the program doesn't change materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null; materialProperties.fog = scene.fog; materialProperties.envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || materialProperties.environment); - if (programs === undefined) { // new material + material.addEventListener('dispose', onMaterialDispose); programs = new Map(); materialProperties.programs = programs; } - let program = programs.get(programCacheKey); - if (program !== undefined) { // early out if program and light state is identical + if (materialProperties.currentProgram === program && materialProperties.lightsStateVersion === lightsStateVersion) { updateCommonMaterialProperties(material, parameters); return program; @@ -20391,20 +18287,19 @@ function WebGLRenderer(parameters = {}) { programs.set(programCacheKey, program); materialProperties.uniforms = parameters.uniforms; } - const uniforms = materialProperties.uniforms; - if (!material.isShaderMaterial && !material.isRawShaderMaterial || material.clipping === true) { uniforms.clippingPlanes = clipping.uniform; } + updateCommonMaterialProperties(material, parameters); - updateCommonMaterialProperties(material, parameters); // store the light setup it was created for + // 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; @@ -20420,9 +18315,11 @@ function WebGLRenderer(parameters = {}) { 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.spotLightMatrix.value = lights.state.spotLightMatrix; + uniforms.spotLightMap.value = lights.state.spotLightMap; uniforms.pointShadowMap.value = lights.state.pointShadowMap; - uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; // TODO (abelnation): add area lights shadow info to uniforms + uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; + // TODO (abelnation): add area lights shadow info to uniforms } const progUniforms = program.getUniforms(); @@ -20431,7 +18328,6 @@ function WebGLRenderer(parameters = {}) { materialProperties.uniformsList = uniformsList; return program; } - function updateCommonMaterialProperties(material, parameters) { const materialProperties = properties.get(material); materialProperties.outputEncoding = parameters.outputEncoding; @@ -20447,7 +18343,6 @@ function WebGLRenderer(parameters = {}) { materialProperties.vertexTangents = parameters.vertexTangents; materialProperties.toneMapping = parameters.toneMapping; } - function setProgram(camera, scene, geometry, material, object) { if (scene.isScene !== true) scene = _emptyScene; // scene could be a Mesh, Line, Points, ... @@ -20466,20 +18361,20 @@ function WebGLRenderer(parameters = {}) { const morphTargetsCount = morphAttribute !== undefined ? morphAttribute.length : 0; const materialProperties = properties.get(material); const lights = currentRenderState.state.lights; - if (_clippingEnabled === true) { if (_localClippingEnabled === true || camera !== _currentCamera) { - const useCache = camera === _currentCamera && material.id === _currentMaterialId; // we might want to call this function with some ClippingGroup + const 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); } - } // + } + // let needsProgramChange = false; - if (material.version === materialProperties.__version) { if (materialProperties.needsLights && materialProperties.lightsStateVersion !== lights.state.version) { needsProgramChange = true; @@ -20517,76 +18412,69 @@ function WebGLRenderer(parameters = {}) { } else { needsProgramChange = true; materialProperties.__version = material.version; - } // + } + // let program = materialProperties.currentProgram; - if (needsProgramChange === true) { program = getProgram(material, scene, object); } - let refreshProgram = false; let refreshMaterial = false; let refreshLights = false; const p_uniforms = program.getUniforms(), - m_uniforms = materialProperties.uniforms; - + m_uniforms = materialProperties.uniforms; if (state.useProgram(program.program)) { refreshProgram = true; refreshMaterial = true; refreshLights = true; } - if (material.id !== _currentMaterialId) { _currentMaterialId = material.id; refreshMaterial = true; } - 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 + _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: refreshMaterial = true; // set to true on material change - refreshLights = true; // remains set until update done - } // load material specific uniforms - // (shader material also gets them for the sake of genericity) + } + // load material specific uniforms + // (shader material also gets them for the sake of genericity) if (material.isShaderMaterial || material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshStandardMaterial || material.envMap) { const uCamPos = p_uniforms.map.cameraPosition; - if (uCamPos !== undefined) { uCamPos.setValue(_gl, _vector3.setFromMatrixPosition(camera.matrixWorld)); } } - if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial) { p_uniforms.setValue(_gl, 'isOrthographic', camera.isOrthographicCamera === true); } - if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial || material.isShadowMaterial || object.isSkinnedMesh) { p_uniforms.setValue(_gl, 'viewMatrix', camera.matrixWorldInverse); } - } // skinning and morph target uniforms must be set even if material didn't change + } + + // skinning and morph target uniforms must be set even if material didn't change // auto-setting of texture unit for bone and morph texture must go before other textures // otherwise textures used for skinning and morphing can take over texture units reserved for other material textures - if (object.isSkinnedMesh) { p_uniforms.setOptional(_gl, object, 'bindMatrix'); p_uniforms.setOptional(_gl, object, 'bindMatrixInverse'); const skeleton = object.skeleton; - if (skeleton) { if (capabilities.floatVertexTextures) { if (skeleton.boneTexture === null) skeleton.computeBoneTexture(); @@ -20597,58 +18485,62 @@ function WebGLRenderer(parameters = {}) { } } } - const morphAttributes = geometry.morphAttributes; - if (morphAttributes.position !== undefined || morphAttributes.normal !== undefined || morphAttributes.color !== undefined && capabilities.isWebGL2 === true) { morphtargets.update(object, geometry, material, program); } - if (refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow) { materialProperties.receiveShadow = object.receiveShadow; p_uniforms.setValue(_gl, 'receiveShadow', object.receiveShadow); } + // https://github.com/mrdoob/three.js/pull/24467#issuecomment-1209031512 + + if (material.isMeshGouraudMaterial && material.envMap !== null) { + m_uniforms.envMap.value = envMap; + m_uniforms.flipEnvMap.value = envMap.isCubeTexture && envMap.isRenderTargetTexture === false ? -1 : 1; + } if (refreshMaterial) { p_uniforms.setValue(_gl, 'toneMappingExposure', _this.toneMappingExposure); - 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 + } + // refresh uniforms common to several materials if (fog && material.fog === true) { materials.refreshFogUniforms(m_uniforms, fog); } - materials.refreshMaterialUniforms(m_uniforms, material, _pixelRatio, _height, _transmissionRenderTarget); 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 (material.isSpriteMaterial) { p_uniforms.setValue(_gl, 'center', object.center); - } // common matrices + } + // common matrices p_uniforms.setValue(_gl, 'modelViewMatrix', object.modelViewMatrix); p_uniforms.setValue(_gl, 'normalMatrix', object.normalMatrix); - p_uniforms.setValue(_gl, 'modelMatrix', object.matrixWorld); // UBOs + p_uniforms.setValue(_gl, 'modelMatrix', object.matrixWorld); + + // UBOs if (material.isShaderMaterial || material.isRawShaderMaterial) { const groups = material.uniformsGroups; - for (let i = 0, l = groups.length; i < l; i++) { if (capabilities.isWebGL2) { const group = groups[i]; @@ -20659,10 +18551,10 @@ function WebGLRenderer(parameters = {}) { } } } - return program; - } // If uniforms are marked as clean, they don't need to be loaded to the GPU. + } + // If uniforms are marked as clean, they don't need to be loaded to the GPU. function markUniformsLightsNeedsUpdate(uniforms, value) { uniforms.ambientLightColor.needsUpdate = value; @@ -20676,32 +18568,25 @@ function WebGLRenderer(parameters = {}) { 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; } - this.getActiveCubeFace = function () { return _currentActiveCubeFace; }; - this.getActiveMipmapLevel = function () { return _currentActiveMipmapLevel; }; - this.getRenderTarget = function () { return _currentRenderTarget; }; - this.setRenderTargetTextures = function (renderTarget, colorTexture, depthTexture) { properties.get(renderTarget.texture).__webglTexture = colorTexture; properties.get(renderTarget.depthTexture).__webglTexture = depthTexture; const renderTargetProperties = properties.get(renderTarget); renderTargetProperties.__hasExternalTextures = true; - if (renderTargetProperties.__hasExternalTextures) { renderTargetProperties.__autoAllocateDepthBuffer = depthTexture === undefined; - if (!renderTargetProperties.__autoAllocateDepthBuffer) { // The multisample_render_to_texture extension doesn't work properly if there // are midframe flushes and an external depth buffer. Disable use of the extension. @@ -20712,22 +18597,21 @@ function WebGLRenderer(parameters = {}) { } } }; - this.setRenderTargetFramebuffer = function (renderTarget, defaultFramebuffer) { const renderTargetProperties = properties.get(renderTarget); renderTargetProperties.__webglFramebuffer = defaultFramebuffer; renderTargetProperties.__useDefaultFramebuffer = defaultFramebuffer === undefined; }; - this.setRenderTarget = function (renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) { _currentRenderTarget = renderTarget; _currentActiveCubeFace = activeCubeFace; _currentActiveMipmapLevel = activeMipmapLevel; let useDefaultFramebuffer = true; - + let framebuffer = null; + let isCube = false; + let isRenderTarget3D = false; if (renderTarget) { const renderTargetProperties = properties.get(renderTarget); - if (renderTargetProperties.__useDefaultFramebuffer !== undefined) { // We need to make sure to rebind the framebuffer. state.bindFramebuffer(_gl.FRAMEBUFFER, null); @@ -20738,21 +18622,11 @@ function WebGLRenderer(parameters = {}) { // Color and depth texture must be rebound in order for the swapchain to update. textures.rebindTextures(renderTarget, properties.get(renderTarget.texture).__webglTexture, properties.get(renderTarget.depthTexture).__webglTexture); } - } - - let framebuffer = null; - let isCube = false; - let isRenderTarget3D = false; - - if (renderTarget) { const texture = renderTarget.texture; - - if (texture.isData3DTexture || texture.isDataArrayTexture) { + if (texture.isData3DTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture) { isRenderTarget3D = true; } - const __webglFramebuffer = properties.get(renderTarget).__webglFramebuffer; - if (renderTarget.isWebGLCubeRenderTarget) { framebuffer = __webglFramebuffer[activeCubeFace]; isCube = true; @@ -20761,41 +18635,29 @@ function WebGLRenderer(parameters = {}) { } else { framebuffer = __webglFramebuffer; } - _currentViewport.copy(renderTarget.viewport); - _currentScissor.copy(renderTarget.scissor); - _currentScissorTest = renderTarget.scissorTest; } else { _currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor(); - _currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor(); - _currentScissorTest = _scissorTest; } - const framebufferBound = state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); - if (framebufferBound && capabilities.drawBuffers && useDefaultFramebuffer) { state.drawBuffers(renderTarget, framebuffer); } - state.viewport(_currentViewport); state.scissor(_currentScissor); state.setScissorTest(_currentScissorTest); - if (isCube) { const textureProperties = properties.get(renderTarget.texture); - _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + activeCubeFace, textureProperties.__webglTexture, activeMipmapLevel); } else if (isRenderTarget3D) { const textureProperties = properties.get(renderTarget.texture); const layer = activeCubeFace || 0; - _gl.framebufferTextureLayer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureProperties.__webglTexture, activeMipmapLevel || 0, layer); } - _currentMaterialId = -1; // reset current material to ensure correct uniform bindings }; @@ -20804,72 +18666,63 @@ function WebGLRenderer(parameters = {}) { console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.'); return; } - let framebuffer = properties.get(renderTarget).__webglFramebuffer; - if (renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== undefined) { framebuffer = framebuffer[activeCubeFaceIndex]; } - if (framebuffer) { state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); - try { const texture = renderTarget.texture; const textureFormat = texture.format; const textureType = texture.type; - if (textureFormat !== RGBAFormat && utils.convert(textureFormat) !== _gl.getParameter(_gl.IMPLEMENTATION_COLOR_READ_FORMAT)) { console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.'); return; } - const halfFloatSupportedByExt = textureType === HalfFloatType && (extensions.has('EXT_color_buffer_half_float') || capabilities.isWebGL2 && extensions.has('EXT_color_buffer_float')); - - if (textureType !== UnsignedByteType && utils.convert(textureType) !== _gl.getParameter(_gl.IMPLEMENTATION_COLOR_READ_TYPE) && // Edge and Chrome Mac < 52 (#9513) - !(textureType === FloatType && (capabilities.isWebGL2 || extensions.has('OES_texture_float') || extensions.has('WEBGL_color_buffer_float'))) && // Chrome Mac >= 52 and Firefox + if (textureType !== UnsignedByteType && utils.convert(textureType) !== _gl.getParameter(_gl.IMPLEMENTATION_COLOR_READ_TYPE) && + // Edge and Chrome Mac < 52 (#9513) + !(textureType === FloatType && (capabilities.isWebGL2 || extensions.has('OES_texture_float') || extensions.has('WEBGL_color_buffer_float'))) && + // Chrome Mac >= 52 and Firefox !halfFloatSupportedByExt) { console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.'); return; - } // the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604) + } + // 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); } } finally { // restore framebuffer of current render target if necessary + const framebuffer = _currentRenderTarget !== null ? properties.get(_currentRenderTarget).__webglFramebuffer : null; state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); } } }; - this.copyFramebufferToTexture = function (position, texture, level = 0) { const levelScale = Math.pow(2, -level); const width = Math.floor(texture.image.width * levelScale); const height = Math.floor(texture.image.height * levelScale); textures.setTexture2D(texture, 0); - _gl.copyTexSubImage2D(_gl.TEXTURE_2D, level, 0, 0, position.x, position.y, width, height); - state.unbindTexture(); }; - this.copyTextureToTexture = function (position, srcTexture, dstTexture, level = 0) { const width = srcTexture.image.width; const height = srcTexture.image.height; const glFormat = utils.convert(dstTexture.format); const 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 + textures.setTexture2D(dstTexture, 0); + // As another texture upload may have changed pixelStorei + // parameters, make sure they are correct for the dstTexture _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY); - _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha); - _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment); - if (srcTexture.isDataTexture) { _gl.texSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data); } else { @@ -20878,26 +18731,23 @@ function WebGLRenderer(parameters = {}) { } else { _gl.texSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, glFormat, glType, srcTexture.image); } - } // Generate mipmaps only when copying level 0 - + } + // Generate mipmaps only when copying level 0 if (level === 0 && dstTexture.generateMipmaps) _gl.generateMipmap(_gl.TEXTURE_2D); state.unbindTexture(); }; - this.copyTextureToTexture3D = function (sourceBox, position, srcTexture, dstTexture, level = 0) { if (_this.isWebGL1Renderer) { console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: can only be used with WebGL2.'); return; } - const width = sourceBox.max.x - sourceBox.min.x + 1; const height = sourceBox.max.y - sourceBox.min.y + 1; const depth = sourceBox.max.z - sourceBox.min.z + 1; const glFormat = utils.convert(dstTexture.format); const glType = utils.convert(dstTexture.type); let glTarget; - if (dstTexture.isData3DTexture) { textures.setTexture3D(dstTexture, 0); glTarget = _gl.TEXTURE_3D; @@ -20908,76 +18758,52 @@ function WebGLRenderer(parameters = {}) { console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: only supports THREE.DataTexture3D and THREE.DataTexture2DArray.'); return; } - _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY); - _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha); - _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment); - const unpackRowLen = _gl.getParameter(_gl.UNPACK_ROW_LENGTH); - const unpackImageHeight = _gl.getParameter(_gl.UNPACK_IMAGE_HEIGHT); - const unpackSkipPixels = _gl.getParameter(_gl.UNPACK_SKIP_PIXELS); - const unpackSkipRows = _gl.getParameter(_gl.UNPACK_SKIP_ROWS); - const unpackSkipImages = _gl.getParameter(_gl.UNPACK_SKIP_IMAGES); - const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[0] : srcTexture.image; - _gl.pixelStorei(_gl.UNPACK_ROW_LENGTH, image.width); - _gl.pixelStorei(_gl.UNPACK_IMAGE_HEIGHT, image.height); - _gl.pixelStorei(_gl.UNPACK_SKIP_PIXELS, sourceBox.min.x); - _gl.pixelStorei(_gl.UNPACK_SKIP_ROWS, sourceBox.min.y); - _gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, sourceBox.min.z); - if (srcTexture.isDataTexture || srcTexture.isData3DTexture) { _gl.texSubImage3D(glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, glType, image.data); } else { - if (srcTexture.isCompressedTexture) { + if (srcTexture.isCompressedArrayTexture) { console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: untested support for compressed srcTexture.'); - _gl.compressedTexSubImage3D(glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, image.data); } else { _gl.texSubImage3D(glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, glType, image); } } - _gl.pixelStorei(_gl.UNPACK_ROW_LENGTH, unpackRowLen); - _gl.pixelStorei(_gl.UNPACK_IMAGE_HEIGHT, unpackImageHeight); - _gl.pixelStorei(_gl.UNPACK_SKIP_PIXELS, unpackSkipPixels); - _gl.pixelStorei(_gl.UNPACK_SKIP_ROWS, unpackSkipRows); + _gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, unpackSkipImages); - _gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, unpackSkipImages); // Generate mipmaps only when copying level 0 - - + // Generate mipmaps only when copying level 0 if (level === 0 && dstTexture.generateMipmaps) _gl.generateMipmap(glTarget); state.unbindTexture(); }; - this.initTexture = function (texture) { if (texture.isCubeTexture) { textures.setTextureCube(texture, 0); } else if (texture.isData3DTexture) { textures.setTexture3D(texture, 0); - } else if (texture.isDataArrayTexture) { + } else if (texture.isDataArrayTexture || texture.isCompressedArrayTexture) { textures.setTexture2DArray(texture, 0); } else { textures.setTexture2D(texture, 0); } - state.unbindTexture(); }; - this.resetState = function () { _currentActiveCubeFace = 0; _currentActiveMipmapLevel = 0; @@ -20985,7 +18811,6 @@ function WebGLRenderer(parameters = {}) { state.reset(); bindingStates.reset(); }; - if (typeof __THREE_DEVTOOLS__ !== 'undefined') { __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('observe', { detail: this @@ -20994,7 +18819,6 @@ function WebGLRenderer(parameters = {}) { } class WebGL1Renderer extends WebGLRenderer {} - WebGL1Renderer.prototype.isWebGL1Renderer = true; class FogExp2 { @@ -21004,11 +18828,9 @@ class FogExp2 { this.color = new Color(color); this.density = density; } - clone() { return new FogExp2(this.color, this.density); } - toJSON() { return { type: 'FogExp2', @@ -21016,7 +18838,6 @@ class FogExp2 { density: this.density }; } - } class Fog { @@ -21027,11 +18848,9 @@ class Fog { this.near = near; this.far = far; } - clone() { return new Fog(this.color, this.near, this.far); } - toJSON() { return { type: 'Fog', @@ -21040,7 +18859,6 @@ class Fog { far: this.far }; } - } class Scene extends Object3D { @@ -21051,33 +18869,44 @@ class Scene extends Object3D { this.background = null; this.environment = null; this.fog = null; + this.backgroundBlurriness = 0; + this.backgroundIntensity = 1; this.overrideMaterial = null; - this.autoUpdate = true; // checked by the renderer - if (typeof __THREE_DEVTOOLS__ !== 'undefined') { __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('observe', { detail: this })); } } - copy(source, recursive) { super.copy(source, recursive); 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(); + this.backgroundBlurriness = source.backgroundBlurriness; + this.backgroundIntensity = source.backgroundIntensity; if (source.overrideMaterial !== null) this.overrideMaterial = source.overrideMaterial.clone(); - this.autoUpdate = source.autoUpdate; this.matrixAutoUpdate = source.matrixAutoUpdate; return this; } - toJSON(meta) { const data = super.toJSON(meta); if (this.fog !== null) data.object.fog = this.fog.toJSON(); + if (this.backgroundBlurriness > 0) data.backgroundBlurriness = this.backgroundBlurriness; + if (this.backgroundIntensity !== 1) data.backgroundIntensity = this.backgroundIntensity; return data; } + // @deprecated + + get autoUpdate() { + console.warn('THREE.Scene: autoUpdate was renamed to matrixWorldAutoUpdate in r144.'); + return this.matrixWorldAutoUpdate; + } + set autoUpdate(value) { + console.warn('THREE.Scene: autoUpdate was renamed to matrixWorldAutoUpdate in r144.'); + this.matrixWorldAutoUpdate = value; + } } class InterleavedBuffer { @@ -21094,18 +18923,14 @@ class InterleavedBuffer { this.version = 0; this.uuid = generateUUID(); } - onUploadCallback() {} - set needsUpdate(value) { if (value === true) this.version++; } - setUsage(value) { this.usage = value; return this; } - copy(source) { this.array = new source.array.constructor(source.array); this.count = source.count; @@ -21113,61 +18938,52 @@ class InterleavedBuffer { this.usage = source.usage; return this; } - copyAt(index1, attribute, index2) { index1 *= this.stride; index2 *= attribute.stride; - for (let i = 0, l = this.stride; i < l; i++) { this.array[index1 + i] = attribute.array[index2 + i]; } - return this; } - set(value, offset = 0) { this.array.set(value, offset); return this; } - clone(data) { if (data.arrayBuffers === undefined) { data.arrayBuffers = {}; } - if (this.array.buffer._uuid === undefined) { this.array.buffer._uuid = generateUUID(); } - if (data.arrayBuffers[this.array.buffer._uuid] === undefined) { data.arrayBuffers[this.array.buffer._uuid] = this.array.slice(0).buffer; } - const array = new this.array.constructor(data.arrayBuffers[this.array.buffer._uuid]); const ib = new this.constructor(array, this.stride); ib.setUsage(this.usage); return ib; } - onUpload(callback) { this.onUploadCallback = callback; return this; } - toJSON(data) { if (data.arrayBuffers === undefined) { data.arrayBuffers = {}; - } // generate UUID for array buffer if necessary + } + // generate UUID for array buffer if necessary if (this.array.buffer._uuid === undefined) { this.array.buffer._uuid = generateUUID(); } - if (data.arrayBuffers[this.array.buffer._uuid] === undefined) { data.arrayBuffers[this.array.buffer._uuid] = Array.from(new Uint32Array(this.array.buffer)); - } // + } + // return { uuid: this.uuid, @@ -21176,11 +18992,9 @@ class InterleavedBuffer { stride: this.stride }; } - } const _vector$6 = /*@__PURE__*/new Vector3(); - class InterleavedBufferAttribute { constructor(interleavedBuffer, itemSize, offset, normalized = false) { this.isInterleavedBufferAttribute = true; @@ -21190,155 +19004,148 @@ class InterleavedBufferAttribute { this.offset = offset; this.normalized = normalized === true; } - get count() { return this.data.count; } - get array() { return this.data.array; } - set needsUpdate(value) { this.data.needsUpdate = value; } - applyMatrix4(m) { for (let i = 0, l = this.data.count; i < l; i++) { _vector$6.fromBufferAttribute(this, i); - _vector$6.applyMatrix4(m); - this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); } - return this; } - applyNormalMatrix(m) { for (let i = 0, l = this.count; i < l; i++) { _vector$6.fromBufferAttribute(this, i); - _vector$6.applyNormalMatrix(m); - this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); } - return this; } - transformDirection(m) { for (let i = 0, l = this.count; i < l; i++) { _vector$6.fromBufferAttribute(this, i); - _vector$6.transformDirection(m); - this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); } - return this; } - setX(index, x) { + if (this.normalized) x = normalize(x, this.array); this.data.array[index * this.data.stride + this.offset] = x; return this; } - setY(index, y) { + if (this.normalized) y = normalize(y, this.array); this.data.array[index * this.data.stride + this.offset + 1] = y; return this; } - setZ(index, z) { + if (this.normalized) z = normalize(z, this.array); this.data.array[index * this.data.stride + this.offset + 2] = z; return this; } - setW(index, w) { + if (this.normalized) w = normalize(w, this.array); this.data.array[index * this.data.stride + this.offset + 3] = w; return this; } - getX(index) { - return this.data.array[index * this.data.stride + this.offset]; + let x = this.data.array[index * this.data.stride + this.offset]; + if (this.normalized) x = denormalize(x, this.array); + return x; } - getY(index) { - return this.data.array[index * this.data.stride + this.offset + 1]; + let y = this.data.array[index * this.data.stride + this.offset + 1]; + if (this.normalized) y = denormalize(y, this.array); + return y; } - getZ(index) { - return this.data.array[index * this.data.stride + this.offset + 2]; + let z = this.data.array[index * this.data.stride + this.offset + 2]; + if (this.normalized) z = denormalize(z, this.array); + return z; } - getW(index) { - return this.data.array[index * this.data.stride + this.offset + 3]; + let w = this.data.array[index * this.data.stride + this.offset + 3]; + if (this.normalized) w = denormalize(w, this.array); + return w; } - setXY(index, x, y) { index = index * this.data.stride + this.offset; + if (this.normalized) { + x = normalize(x, this.array); + y = normalize(y, this.array); + } this.data.array[index + 0] = x; this.data.array[index + 1] = y; return this; } - setXYZ(index, x, y, z) { index = index * this.data.stride + this.offset; + if (this.normalized) { + x = normalize(x, this.array); + y = normalize(y, this.array); + z = normalize(z, this.array); + } this.data.array[index + 0] = x; this.data.array[index + 1] = y; this.data.array[index + 2] = z; return this; } - setXYZW(index, x, y, z, w) { index = index * this.data.stride + this.offset; + if (this.normalized) { + x = normalize(x, this.array); + y = normalize(y, this.array); + z = normalize(z, this.array); + w = normalize(w, this.array); + } 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(data) { if (data === undefined) { - console.log('THREE.InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will deinterleave buffer data.'); + console.log('THREE.InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will de-interleave buffer data.'); const array = []; - for (let i = 0; i < this.count; i++) { const index = i * this.data.stride + this.offset; - for (let j = 0; j < this.itemSize; j++) { array.push(this.data.array[index + j]); } } - return new BufferAttribute(new this.array.constructor(array), this.itemSize, this.normalized); } else { if (data.interleavedBuffers === undefined) { data.interleavedBuffers = {}; } - 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(data) { if (data === undefined) { - console.log('THREE.InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will deinterleave buffer data.'); + console.log('THREE.InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will de-interleave buffer data.'); const array = []; - for (let i = 0; i < this.count; i++) { const index = i * this.data.stride + this.offset; - for (let 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 + } + // de-interleave data and save it as an ordinary buffer attribute for now return { itemSize: this.itemSize, @@ -21347,15 +19154,14 @@ class InterleavedBufferAttribute { normalized: this.normalized }; } else { - // save as true interleaved attribtue + // save as true interleaved attribute + if (data.interleavedBuffers === undefined) { data.interleavedBuffers = {}; } - if (data.interleavedBuffers[this.data.uuid] === undefined) { data.interleavedBuffers[this.data.uuid] = this.data.toJSON(data); } - return { isInterleavedBufferAttribute: true, itemSize: this.itemSize, @@ -21365,7 +19171,6 @@ class InterleavedBufferAttribute { }; } } - } class SpriteMaterial extends Material { @@ -21382,7 +19187,6 @@ class SpriteMaterial extends Material { this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.color.copy(source.color); @@ -21393,110 +19197,74 @@ class SpriteMaterial extends Material { this.fog = source.fog; return this; } - } let _geometry; - const _intersectPoint = /*@__PURE__*/new Vector3(); - const _worldScale = /*@__PURE__*/new Vector3(); - const _mvPosition = /*@__PURE__*/new Vector3(); - const _alignedPosition = /*@__PURE__*/new Vector2(); - const _rotatedPosition = /*@__PURE__*/new Vector2(); - const _viewWorldMatrix = /*@__PURE__*/new Matrix4(); - const _vA = /*@__PURE__*/new Vector3(); - const _vB = /*@__PURE__*/new Vector3(); - const _vC = /*@__PURE__*/new Vector3(); - const _uvA = /*@__PURE__*/new Vector2(); - const _uvB = /*@__PURE__*/new Vector2(); - const _uvC = /*@__PURE__*/new Vector2(); - class Sprite extends Object3D { constructor(material) { super(); this.isSprite = true; this.type = 'Sprite'; - if (_geometry === undefined) { _geometry = new BufferGeometry(); const 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]); const interleavedBuffer = new InterleavedBuffer(float32Array, 5); - _geometry.setIndex([0, 1, 2, 0, 2, 3]); - _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); } - raycast(raycaster, intersects) { if (raycaster.camera === null) { console.error('THREE.Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.'); } - _worldScale.setFromMatrixScale(this.matrixWorld); - _viewWorldMatrix.copy(raycaster.camera.matrixWorld); - this.modelViewMatrix.multiplyMatrices(raycaster.camera.matrixWorldInverse, this.matrixWorld); - _mvPosition.setFromMatrixPosition(this.modelViewMatrix); - if (raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false) { _worldScale.multiplyScalar(-_mvPosition.z); } - const rotation = this.material.rotation; let sin, cos; - if (rotation !== 0) { cos = Math.cos(rotation); sin = Math.sin(rotation); } - const center = this.center; transformVertex(_vA.set(-0.5, -0.5, 0), _mvPosition, center, _worldScale, sin, cos); transformVertex(_vB.set(0.5, -0.5, 0), _mvPosition, center, _worldScale, sin, cos); transformVertex(_vC.set(0.5, 0.5, 0), _mvPosition, center, _worldScale, sin, cos); - _uvA.set(0, 0); - _uvB.set(1, 0); + _uvC.set(1, 1); - _uvC.set(1, 1); // check first triangle - - + // check first triangle let intersect = raycaster.ray.intersectTriangle(_vA, _vB, _vC, false, _intersectPoint); - if (intersect === null) { // check second triangle transformVertex(_vB.set(-0.5, 0.5, 0), _mvPosition, center, _worldScale, sin, cos); - _uvB.set(0, 1); - intersect = raycaster.ray.intersectTriangle(_vA, _vC, _vB, false, _intersectPoint); - if (intersect === null) { return; } } - const distance = raycaster.ray.origin.distanceTo(_intersectPoint); if (distance < raycaster.near || distance > raycaster.far) return; intersects.push({ @@ -21507,39 +19275,34 @@ class Sprite extends Object3D { object: this }); } - copy(source, recursive) { super.copy(source, recursive); if (source.center !== undefined) this.center.copy(source.center); this.material = source.material; return this; } - } - 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 - + _alignedPosition.subVectors(vertexPosition, center).addScalar(0.5).multiply(scale); + // to check if rotation is not zero 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 + vertexPosition.y += _rotatedPosition.y; + // transform to world space vertexPosition.applyMatrix4(_viewWorldMatrix); } const _v1$2 = /*@__PURE__*/new Vector3(); - const _v2$1 = /*@__PURE__*/new Vector3(); - class LOD extends Object3D { constructor() { super(); @@ -21556,130 +19319,109 @@ class LOD extends Object3D { }); this.autoUpdate = true; } - copy(source) { super.copy(source, false); const levels = source.levels; - for (let i = 0, l = levels.length; i < l; i++) { const level = levels[i]; - this.addLevel(level.object.clone(), level.distance); + this.addLevel(level.object.clone(), level.distance, level.hysteresis); } - this.autoUpdate = source.autoUpdate; return this; } - - addLevel(object, distance = 0) { + addLevel(object, distance = 0, hysteresis = 0) { distance = Math.abs(distance); const levels = this.levels; let l; - for (l = 0; l < levels.length; l++) { if (distance < levels[l].distance) { break; } } - levels.splice(l, 0, { distance: distance, + hysteresis: hysteresis, object: object }); this.add(object); return this; } - getCurrentLevel() { return this._currentLevel; } - getObjectForDistance(distance) { const levels = this.levels; - if (levels.length > 0) { let i, l; - for (i = 1, l = levels.length; i < l; i++) { - if (distance < levels[i].distance) { + let levelDistance = levels[i].distance; + if (levels[i].object.visible) { + levelDistance -= levelDistance * levels[i].hysteresis; + } + if (distance < levelDistance) { break; } } - return levels[i - 1].object; } - return null; } - raycast(raycaster, intersects) { const levels = this.levels; - if (levels.length > 0) { _v1$2.setFromMatrixPosition(this.matrixWorld); - const distance = raycaster.ray.origin.distanceTo(_v1$2); this.getObjectForDistance(distance).raycast(raycaster, intersects); } } - update(camera) { const levels = this.levels; - if (levels.length > 1) { _v1$2.setFromMatrixPosition(camera.matrixWorld); - _v2$1.setFromMatrixPosition(this.matrixWorld); - const distance = _v1$2.distanceTo(_v2$1) / camera.zoom; levels[0].object.visible = true; let i, l; - for (i = 1, l = levels.length; i < l; i++) { - if (distance >= levels[i].distance) { + let levelDistance = levels[i].distance; + if (levels[i].object.visible) { + levelDistance -= levelDistance * levels[i].hysteresis; + } + if (distance >= levelDistance) { levels[i - 1].object.visible = false; levels[i].object.visible = true; } else { break; } } - this._currentLevel = i - 1; - for (; i < l; i++) { levels[i].object.visible = false; } } } - toJSON(meta) { const data = super.toJSON(meta); if (this.autoUpdate === false) data.object.autoUpdate = false; data.object.levels = []; const levels = this.levels; - for (let i = 0, l = levels.length; i < l; i++) { const level = levels[i]; data.object.levels.push({ object: level.object.uuid, - distance: level.distance + distance: level.distance, + hysteresis: level.hysteresis }); } - return data; } - } const _basePosition = /*@__PURE__*/new Vector3(); - const _skinIndex = /*@__PURE__*/new Vector4(); - const _skinWeight = /*@__PURE__*/new Vector4(); - const _vector$5 = /*@__PURE__*/new Vector3(); - const _matrix = /*@__PURE__*/new Matrix4(); - class SkinnedMesh extends Mesh { constructor(geometry, material) { super(geometry, material); @@ -21689,7 +19431,6 @@ class SkinnedMesh extends Mesh { this.bindMatrix = new Matrix4(); this.bindMatrixInverse = new Matrix4(); } - copy(source, recursive) { super.copy(source, recursive); this.bindMode = source.bindMode; @@ -21698,32 +19439,25 @@ class SkinnedMesh extends Mesh { this.skeleton = source.skeleton; return this; } - bind(skeleton, bindMatrix) { this.skeleton = skeleton; - if (bindMatrix === undefined) { this.updateMatrixWorld(true); this.skeleton.calculateInverses(); bindMatrix = this.matrixWorld; } - this.bindMatrix.copy(bindMatrix); this.bindMatrixInverse.copy(bindMatrix).invert(); } - pose() { this.skeleton.pose(); } - normalizeSkinWeights() { const vector = new Vector4(); const skinWeight = this.geometry.attributes.skinWeight; - for (let i = 0, l = skinWeight.count; i < l; i++) { vector.fromBufferAttribute(skinWeight, i); const scale = 1.0 / vector.manhattanLength(); - if (scale !== Infinity) { vector.multiplyScalar(scale); } else { @@ -21733,10 +19467,8 @@ class SkinnedMesh extends Mesh { skinWeight.setXYZW(i, vector.x, vector.y, vector.z, vector.w); } } - updateMatrixWorld(force) { super.updateMatrixWorld(force); - if (this.bindMode === 'attached') { this.bindMatrixInverse.copy(this.matrixWorld).invert(); } else if (this.bindMode === 'detached') { @@ -21745,34 +19477,23 @@ class SkinnedMesh extends Mesh { console.warn('THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode); } } - boneTransform(index, target) { const skeleton = this.skeleton; const geometry = this.geometry; - _skinIndex.fromBufferAttribute(geometry.attributes.skinIndex, index); - _skinWeight.fromBufferAttribute(geometry.attributes.skinWeight, index); - _basePosition.copy(target).applyMatrix4(this.bindMatrix); - target.set(0, 0, 0); - for (let i = 0; i < 4; i++) { const weight = _skinWeight.getComponent(i); - if (weight !== 0) { const boneIndex = _skinIndex.getComponent(i); - _matrix.multiplyMatrices(skeleton.bones[boneIndex].matrixWorld, skeleton.boneInverses[boneIndex]); - target.addScaledVector(_vector$5.copy(_basePosition).applyMatrix4(_matrix), weight); } } - return target.applyMatrix4(this.bindMatrixInverse); } - } class Bone extends Object3D { @@ -21781,7 +19502,6 @@ class Bone extends Object3D { this.isBone = true; this.type = 'Bone'; } - } class DataTexture extends Texture { @@ -21797,13 +19517,10 @@ class DataTexture extends Texture { this.flipY = false; this.unpackAlignment = 1; } - } const _offsetMatrix = /*@__PURE__*/new Matrix4(); - const _identityMatrix = /*@__PURE__*/new Matrix4(); - class Skeleton { constructor(bones = [], boneInverses = []) { this.uuid = generateUUID(); @@ -21815,55 +19532,51 @@ class Skeleton { this.frame = -1; this.init(); } - init() { const bones = this.bones; const boneInverses = this.boneInverses; - this.boneMatrices = new Float32Array(bones.length * 16); // calculate inverse bone matrices if necessary + this.boneMatrices = new Float32Array(bones.length * 16); + + // calculate inverse bone matrices if necessary if (boneInverses.length === 0) { this.calculateInverses(); } else { // handle special case + if (bones.length !== boneInverses.length) { console.warn('THREE.Skeleton: Number of inverse bone matrices does not match amount of bones.'); this.boneInverses = []; - for (let i = 0, il = this.bones.length; i < il; i++) { this.boneInverses.push(new Matrix4()); } } } } - calculateInverses() { this.boneInverses.length = 0; - for (let i = 0, il = this.bones.length; i < il; i++) { const inverse = new Matrix4(); - if (this.bones[i]) { inverse.copy(this.bones[i].matrixWorld).invert(); } - this.boneInverses.push(inverse); } } - pose() { // recover the bind-time world matrices + for (let i = 0, il = this.bones.length; i < il; i++) { const bone = this.bones[i]; - if (bone) { bone.matrixWorld.copy(this.boneInverses[i]).invert(); } - } // compute the local matrices, positions, rotations and scales + } + // compute the local matrices, positions, rotations and scales for (let i = 0, il = this.bones.length; i < il; i++) { const bone = this.bones[i]; - if (bone) { if (bone.parent && bone.parent.isBone) { bone.matrix.copy(bone.parent.matrixWorld).invert(); @@ -21871,36 +19584,32 @@ class Skeleton { } else { bone.matrix.copy(bone.matrixWorld); } - bone.matrix.decompose(bone.position, bone.quaternion, bone.scale); } } } - update() { const bones = this.bones; const boneInverses = this.boneInverses; const boneMatrices = this.boneMatrices; - const boneTexture = this.boneTexture; // flatten bone matrices to array + const boneTexture = this.boneTexture; + + // flatten bone matrices to array for (let i = 0, il = bones.length; i < il; i++) { // compute the offset between the current and the original transform - const matrix = bones[i] ? bones[i].matrixWorld : _identityMatrix; + const matrix = bones[i] ? bones[i].matrixWorld : _identityMatrix; _offsetMatrix.multiplyMatrices(matrix, boneInverses[i]); - _offsetMatrix.toArray(boneMatrices, i * 16); } - if (boneTexture !== null) { boneTexture.needsUpdate = true; } } - clone() { return new Skeleton(this.bones, this.boneInverses); } - computeBoneTexture() { // layout (1 matrix = 4 pixels) // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4) @@ -21908,12 +19617,11 @@ class Skeleton { // 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) - let size = Math.sqrt(this.bones.length * 4); // 4 pixels needed for 1 matrix + let size = Math.sqrt(this.bones.length * 4); // 4 pixels needed for 1 matrix size = ceilPowerOfTwo(size); size = Math.max(size, 4); const boneMatrices = new Float32Array(size * size * 4); // 4 floats per RGBA pixel - boneMatrices.set(this.boneMatrices); // copy current values const boneTexture = new DataTexture(boneMatrices, size, size, RGBAFormat, FloatType); @@ -21923,46 +19631,36 @@ class Skeleton { this.boneTextureSize = size; return this; } - getBoneByName(name) { for (let i = 0, il = this.bones.length; i < il; i++) { const bone = this.bones[i]; - if (bone.name === name) { return bone; } } - return undefined; } - dispose() { if (this.boneTexture !== null) { this.boneTexture.dispose(); this.boneTexture = null; } } - fromJSON(json, bones) { this.uuid = json.uuid; - for (let i = 0, l = json.bones.length; i < l; i++) { const uuid = json.bones[i]; let bone = bones[uuid]; - if (bone === undefined) { console.warn('THREE.Skeleton: No bone found with UUID:', uuid); bone = new Bone(); } - this.bones.push(bone); this.boneInverses.push(new Matrix4().fromArray(json.boneInverses[i])); } - this.init(); return this; } - toJSON() { const data = { metadata: { @@ -21976,55 +19674,40 @@ class Skeleton { data.uuid = this.uuid; const bones = this.bones; const boneInverses = this.boneInverses; - for (let i = 0, l = bones.length; i < l; i++) { const bone = bones[i]; data.bones.push(bone.uuid); const boneInverse = boneInverses[i]; data.boneInverses.push(boneInverse.toArray()); } - return data; } - } class InstancedBufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized, meshPerAttribute = 1) { - if (typeof normalized === 'number') { - meshPerAttribute = normalized; - normalized = false; - console.error('THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument.'); - } - super(array, itemSize, normalized); this.isInstancedBufferAttribute = true; this.meshPerAttribute = meshPerAttribute; } - copy(source) { super.copy(source); this.meshPerAttribute = source.meshPerAttribute; return this; } - toJSON() { const data = super.toJSON(); data.meshPerAttribute = this.meshPerAttribute; data.isInstancedBufferAttribute = true; return data; } - } const _instanceLocalMatrix = /*@__PURE__*/new Matrix4(); - const _instanceWorldMatrix = /*@__PURE__*/new Matrix4(); - const _instanceIntersects = []; - +const _identity = /*@__PURE__*/new Matrix4(); const _mesh = /*@__PURE__*/new Mesh(); - class InstancedMesh extends Mesh { constructor(geometry, material, count) { super(geometry, material); @@ -22033,8 +19716,10 @@ class InstancedMesh extends Mesh { this.instanceColor = null; this.count = count; this.frustumCulled = false; + for (let i = 0; i < count; i++) { + this.setMatrixAt(i, _identity); + } } - copy(source, recursive) { super.copy(source, recursive); this.instanceMatrix.copy(source.instanceMatrix); @@ -22042,33 +19727,30 @@ class InstancedMesh extends Mesh { this.count = source.count; return this; } - getColorAt(index, color) { color.fromArray(this.instanceColor.array, index * 3); } - getMatrixAt(index, matrix) { matrix.fromArray(this.instanceMatrix.array, index * 16); } - raycast(raycaster, intersects) { const matrixWorld = this.matrixWorld; const raycastTimes = this.count; _mesh.geometry = this.geometry; _mesh.material = this.material; if (_mesh.material === undefined) return; - for (let instanceId = 0; instanceId < raycastTimes; instanceId++) { // calculate the world matrix for each instance - this.getMatrixAt(instanceId, _instanceLocalMatrix); - _instanceWorldMatrix.multiplyMatrices(matrixWorld, _instanceLocalMatrix); // the mesh represents this single instance + this.getMatrixAt(instanceId, _instanceLocalMatrix); + _instanceWorldMatrix.multiplyMatrices(matrixWorld, _instanceLocalMatrix); + // the mesh represents this single instance _mesh.matrixWorld = _instanceWorldMatrix; + _mesh.raycast(raycaster, _instanceIntersects); - _mesh.raycast(raycaster, _instanceIntersects); // process the result of raycast - + // process the result of raycast for (let i = 0, l = _instanceIntersects.length; i < l; i++) { const intersect = _instanceIntersects[i]; @@ -22076,31 +19758,24 @@ class InstancedMesh extends Mesh { intersect.object = this; intersects.push(intersect); } - _instanceIntersects.length = 0; } } - setColorAt(index, color) { if (this.instanceColor === null) { this.instanceColor = new InstancedBufferAttribute(new Float32Array(this.instanceMatrix.count * 3), 3); } - color.toArray(this.instanceColor.array, index * 3); } - setMatrixAt(index, matrix) { matrix.toArray(this.instanceMatrix.array, index * 16); } - updateMorphTargets() {} - dispose() { this.dispatchEvent({ type: 'dispose' }); } - } class LineBasicMaterial extends Material { @@ -22115,7 +19790,6 @@ class LineBasicMaterial extends Material { this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.color.copy(source.color); @@ -22125,19 +19799,13 @@ class LineBasicMaterial extends Material { this.fog = source.fog; return this; } - } const _start$1 = /*@__PURE__*/new Vector3(); - const _end$1 = /*@__PURE__*/new Vector3(); - const _inverseMatrix$1 = /*@__PURE__*/new Matrix4(); - const _ray$1 = /*@__PURE__*/new Ray(); - const _sphere$1 = /*@__PURE__*/new Sphere(); - class Line extends Object3D { constructor(geometry = new BufferGeometry(), material = new LineBasicMaterial()) { super(); @@ -22147,57 +19815,50 @@ class Line extends Object3D { this.material = material; this.updateMorphTargets(); } - copy(source, recursive) { super.copy(source, recursive); this.material = source.material; this.geometry = source.geometry; return this; } - computeLineDistances() { - const geometry = this.geometry; // we assume non-indexed geometry + const geometry = this.geometry; + + // we assume non-indexed geometry if (geometry.index === null) { const positionAttribute = geometry.attributes.position; const lineDistances = [0]; - for (let i = 1, l = positionAttribute.count; i < l; i++) { _start$1.fromBufferAttribute(positionAttribute, i - 1); - _end$1.fromBufferAttribute(positionAttribute, i); - lineDistances[i] = lineDistances[i - 1]; lineDistances[i] += _start$1.distanceTo(_end$1); } - geometry.setAttribute('lineDistance', new Float32BufferAttribute(lineDistances, 1)); } else { console.warn('THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.'); } - return this; } - raycast(raycaster, intersects) { const geometry = this.geometry; const matrixWorld = this.matrixWorld; const threshold = raycaster.params.Line.threshold; - const drawRange = geometry.drawRange; // Checking boundingSphere distance to ray + const drawRange = geometry.drawRange; - if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); + // Checking boundingSphere distance to ray + if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); _sphere$1.copy(geometry.boundingSphere); - _sphere$1.applyMatrix4(matrixWorld); - _sphere$1.radius += threshold; - if (raycaster.ray.intersectsSphere(_sphere$1) === false) return; // + if (raycaster.ray.intersectsSphere(_sphere$1) === false) return; - _inverseMatrix$1.copy(matrixWorld).invert(); + // + _inverseMatrix$1.copy(matrixWorld).invert(); _ray$1.copy(raycaster.ray).applyMatrix4(_inverseMatrix$1); - const localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3); const localThresholdSq = localThreshold * localThreshold; const vStart = new Vector3(); @@ -22208,19 +19869,15 @@ class Line extends Object3D { const index = geometry.index; const attributes = geometry.attributes; const positionAttribute = attributes.position; - if (index !== null) { const start = Math.max(0, drawRange.start); const end = Math.min(index.count, drawRange.start + drawRange.count); - for (let i = start, l = end - 1; i < l; i += step) { const a = index.getX(i); const b = index.getX(i + 1); vStart.fromBufferAttribute(positionAttribute, a); vEnd.fromBufferAttribute(positionAttribute, b); - const distSq = _ray$1.distanceSqToSegment(vStart, vEnd, interRay, interSegment); - if (distSq > localThresholdSq) continue; interRay.applyMatrix4(this.matrixWorld); //Move back to world space for distance calculation @@ -22240,13 +19897,10 @@ class Line extends Object3D { } else { const start = Math.max(0, drawRange.start); const end = Math.min(positionAttribute.count, drawRange.start + drawRange.count); - for (let i = start, l = end - 1; i < l; i += step) { vStart.fromBufferAttribute(positionAttribute, i); vEnd.fromBufferAttribute(positionAttribute, i + 1); - const distSq = _ray$1.distanceSqToSegment(vStart, vEnd, interRay, interSegment); - if (distSq > localThresholdSq) continue; interRay.applyMatrix4(this.matrixWorld); //Move back to world space for distance calculation @@ -22265,19 +19919,15 @@ class Line extends Object3D { } } } - updateMorphTargets() { const geometry = this.geometry; const morphAttributes = geometry.morphAttributes; const keys = Object.keys(morphAttributes); - if (keys.length > 0) { const morphAttribute = morphAttributes[keys[0]]; - if (morphAttribute !== undefined) { this.morphTargetInfluences = []; this.morphTargetDictionary = {}; - for (let m = 0, ml = morphAttribute.length; m < ml; m++) { const name = morphAttribute[m].name || String(m); this.morphTargetInfluences.push(0); @@ -22286,44 +19936,36 @@ class Line extends Object3D { } } } - } const _start = /*@__PURE__*/new Vector3(); - const _end = /*@__PURE__*/new Vector3(); - class LineSegments extends Line { constructor(geometry, material) { super(geometry, material); this.isLineSegments = true; this.type = 'LineSegments'; } - computeLineDistances() { - const geometry = this.geometry; // we assume non-indexed geometry + const geometry = this.geometry; + + // we assume non-indexed geometry if (geometry.index === null) { const positionAttribute = geometry.attributes.position; const lineDistances = []; - for (let i = 0, l = positionAttribute.count; i < l; i += 2) { _start.fromBufferAttribute(positionAttribute, i); - _end.fromBufferAttribute(positionAttribute, i + 1); - lineDistances[i] = i === 0 ? 0 : lineDistances[i - 1]; lineDistances[i + 1] = lineDistances[i] + _start.distanceTo(_end); } - geometry.setAttribute('lineDistance', new Float32BufferAttribute(lineDistances, 1)); } else { console.warn('THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.'); } - return this; } - } class LineLoop extends Line { @@ -22332,7 +19974,6 @@ class LineLoop extends Line { this.isLineLoop = true; this.type = 'LineLoop'; } - } class PointsMaterial extends Material { @@ -22348,7 +19989,6 @@ class PointsMaterial extends Material { this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.color.copy(source.color); @@ -22359,17 +19999,12 @@ class PointsMaterial extends Material { this.fog = source.fog; return this; } - } const _inverseMatrix = /*@__PURE__*/new Matrix4(); - const _ray = /*@__PURE__*/new Ray(); - const _sphere = /*@__PURE__*/new Sphere(); - const _position$2 = /*@__PURE__*/new Vector3(); - class Points extends Object3D { constructor(geometry = new BufferGeometry(), material = new PointsMaterial()) { super(); @@ -22379,74 +20014,61 @@ class Points extends Object3D { this.material = material; this.updateMorphTargets(); } - copy(source, recursive) { super.copy(source, recursive); this.material = source.material; this.geometry = source.geometry; return this; } - raycast(raycaster, intersects) { const geometry = this.geometry; const matrixWorld = this.matrixWorld; const threshold = raycaster.params.Points.threshold; - const drawRange = geometry.drawRange; // Checking boundingSphere distance to ray + const drawRange = geometry.drawRange; - if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); + // Checking boundingSphere distance to ray + if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); _sphere.copy(geometry.boundingSphere); - _sphere.applyMatrix4(matrixWorld); - _sphere.radius += threshold; - if (raycaster.ray.intersectsSphere(_sphere) === false) return; // + if (raycaster.ray.intersectsSphere(_sphere) === false) return; - _inverseMatrix.copy(matrixWorld).invert(); + // + _inverseMatrix.copy(matrixWorld).invert(); _ray.copy(raycaster.ray).applyMatrix4(_inverseMatrix); - const localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3); const localThresholdSq = localThreshold * localThreshold; const index = geometry.index; const attributes = geometry.attributes; const positionAttribute = attributes.position; - if (index !== null) { const start = Math.max(0, drawRange.start); const end = Math.min(index.count, drawRange.start + drawRange.count); - for (let i = start, il = end; i < il; i++) { const a = index.getX(i); - _position$2.fromBufferAttribute(positionAttribute, a); - testPoint(_position$2, a, localThresholdSq, matrixWorld, raycaster, intersects, this); } } else { const start = Math.max(0, drawRange.start); const end = Math.min(positionAttribute.count, drawRange.start + drawRange.count); - for (let i = start, l = end; i < l; i++) { _position$2.fromBufferAttribute(positionAttribute, i); - testPoint(_position$2, i, localThresholdSq, matrixWorld, raycaster, intersects, this); } } } - updateMorphTargets() { const geometry = this.geometry; const morphAttributes = geometry.morphAttributes; const keys = Object.keys(morphAttributes); - if (keys.length > 0) { const morphAttribute = morphAttributes[keys[0]]; - if (morphAttribute !== undefined) { this.morphTargetInfluences = []; this.morphTargetDictionary = {}; - for (let m = 0, ml = morphAttribute.length; m < ml; m++) { const name = morphAttribute[m].name || String(m); this.morphTargetInfluences.push(0); @@ -22455,17 +20077,12 @@ class Points extends Object3D { } } } - } - function testPoint(point, index, localThresholdSq, matrixWorld, raycaster, intersects, object) { const rayPointDistanceSq = _ray.distanceSqToPoint(point); - if (rayPointDistanceSq < localThresholdSq) { const intersectPoint = new Vector3(); - _ray.closestPointToPoint(point, intersectPoint); - intersectPoint.applyMatrix4(matrixWorld); const distance = raycaster.ray.origin.distanceTo(intersectPoint); if (distance < raycaster.near || distance > raycaster.far) return; @@ -22488,30 +20105,24 @@ class VideoTexture extends Texture { this.magFilter = magFilter !== undefined ? magFilter : LinearFilter; this.generateMipmaps = false; const scope = this; - function updateVideo() { scope.needsUpdate = true; video.requestVideoFrameCallback(updateVideo); } - if ('requestVideoFrameCallback' in video) { video.requestVideoFrameCallback(updateVideo); } } - clone() { return new this.constructor(this.image).copy(this); } - update() { const video = this.image; const hasVideoFrameCallback = ('requestVideoFrameCallback' in video); - if (hasVideoFrameCallback === false && video.readyState >= video.HAVE_CURRENT_DATA) { this.needsUpdate = true; } } - } class FramebufferTexture extends Texture { @@ -22527,7 +20138,6 @@ class FramebufferTexture extends Texture { this.generateMipmaps = false; this.needsUpdate = true; } - } class CompressedTexture extends Texture { @@ -22538,15 +20148,27 @@ class CompressedTexture extends Texture { width: width, height: height }; - this.mipmaps = mipmaps; // no flipping for cube textures + this.mipmaps = mipmaps; + + // no flipping for cube textures // (also flipping doesn't work for compressed textures ) - this.flipY = false; // can't generate mipmaps for compressed textures + this.flipY = false; + + // can't generate mipmaps for compressed textures // mips must be embedded in DDS files this.generateMipmaps = false; } +} +class CompressedArrayTexture extends CompressedTexture { + constructor(mipmaps, width, height, depth, format, type) { + super(mipmaps, width, height, format, type); + this.isCompressedArrayTexture = true; + this.image.depth = depth; + this.wrapR = ClampToEdgeWrapping; + } } class CanvasTexture extends Texture { @@ -22555,7 +20177,6 @@ class CanvasTexture extends Texture { this.isCanvasTexture = true; this.needsUpdate = true; } - } /** @@ -22592,70 +20213,69 @@ class Curve { constructor() { this.type = 'Curve'; this.arcLengthDivisions = 200; - } // Virtual base class method to overwrite and implement in subclasses - // - t [0 .. 1] + } + // Virtual base class method to overwrite and implement in subclasses + // - t [0 .. 1] getPoint() { console.warn('THREE.Curve: .getPoint() not implemented.'); return null; - } // Get point at relative position in curve according to arc length - // - u [0 .. 1] + } + // Get point at relative position in curve according to arc length + // - u [0 .. 1] getPointAt(u, optionalTarget) { const t = this.getUtoTmapping(u); return this.getPoint(t, optionalTarget); - } // Get sequence of points using getPoint( t ) + } + // Get sequence of points using getPoint( t ) getPoints(divisions = 5) { const points = []; - for (let d = 0; d <= divisions; d++) { points.push(this.getPoint(d / divisions)); } - return points; - } // Get sequence of points using getPointAt( u ) + } + // Get sequence of points using getPointAt( u ) getSpacedPoints(divisions = 5) { const points = []; - for (let d = 0; d <= divisions; d++) { points.push(this.getPointAt(d / divisions)); } - return points; - } // Get total curve arc length + } + // Get total curve arc length getLength() { const lengths = this.getLengths(); return lengths[lengths.length - 1]; - } // Get list of cumulative segment lengths + } + // Get list of cumulative segment lengths getLengths(divisions = this.arcLengthDivisions) { if (this.cacheArcLengths && this.cacheArcLengths.length === divisions + 1 && !this.needsUpdate) { return this.cacheArcLengths; } - this.needsUpdate = false; const cache = []; let current, - last = this.getPoint(0); + last = this.getPoint(0); let sum = 0; cache.push(0); - for (let 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. } @@ -22663,8 +20283,9 @@ class Curve { updateArcLengths() { this.needsUpdate = true; this.getLengths(); - } // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant + } + // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant getUtoTmapping(u, distance) { const arcLengths = this.getLengths(); @@ -22676,53 +20297,61 @@ class Curve { targetArcLength = distance; } else { targetArcLength = u * arcLengths[il - 1]; - } // binary search for the index with largest value smaller than target u distance + } + // binary search for the index with largest value smaller than target u distance let low = 0, - high = il - 1, - comparison; - + 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; } else if (comparison > 0) { high = i - 1; } else { high = i; - break; // DONE + break; + + // DONE } } i = high; - if (arcLengths[i] === targetArcLength) { return i / (il - 1); - } // we could get finer grain at lengths, or use simple interpolation between two points + } + // we could get finer grain at lengths, or use simple interpolation between two points const lengthBefore = arcLengths[i]; const lengthAfter = arcLengths[i + 1]; - const segmentLength = lengthAfter - lengthBefore; // determine where we are between the 'before' and 'after' points + const segmentLength = lengthAfter - lengthBefore; - const segmentFraction = (targetArcLength - lengthBefore) / segmentLength; // add that fractional amount to t + // determine where we are between the 'before' and 'after' points + + const segmentFraction = (targetArcLength - lengthBefore) / segmentLength; + + // add that fractional amount to t const t = (i + segmentFraction) / (il - 1); return t; - } // Returns a unit vector tangent at 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(t, optionalTarget) { const delta = 0.0001; let t1 = t - delta; - let t2 = t + delta; // Capping in case of danger + let t2 = t + delta; + + // Capping in case of danger if (t1 < 0) t1 = 0; if (t2 > 1) t2 = 1; @@ -22732,27 +20361,29 @@ class Curve { tangent.copy(pt2).sub(pt1).normalize(); return tangent; } - getTangentAt(u, optionalTarget) { const t = this.getUtoTmapping(u); return this.getTangent(t, optionalTarget); } - computeFrenetFrames(segments, closed) { // see http://www.cs.indiana.edu/pub/techreports/TR425.pdf + const normal = new Vector3(); const tangents = []; const normals = []; const binormals = []; const vec = new Vector3(); - const mat = new Matrix4(); // compute the tangent vectors for each segment on the curve + const mat = new Matrix4(); + + // compute the tangent vectors for each segment on the curve for (let i = 0; i <= segments; i++) { const u = i / segments; tangents[i] = this.getTangentAt(u, new Vector3()); - } // select an initial normal vector perpendicular to the first tangent vector, - // and in the direction of the minimum tangent xyz component + } + // select an initial normal vector perpendicular to the first tangent vector, + // and in the direction of the minimum tangent xyz component normals[0] = new Vector3(); binormals[0] = new Vector3(); @@ -22760,72 +20391,63 @@ class Curve { const tx = Math.abs(tangents[0].x); const ty = Math.abs(tangents[0].y); const tz = Math.abs(tangents[0].z); - if (tx <= min) { min = tx; normal.set(1, 0, 0); } - if (ty <= min) { min = ty; normal.set(0, 1, 0); } - if (tz <= min) { 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 curve + binormals[0].crossVectors(tangents[0], normals[0]); + + // compute the slowly-varying normal and binormal vectors for each segment on the curve for (let i = 1; i <= segments; i++) { normals[i] = normals[i - 1].clone(); binormals[i] = binormals[i - 1].clone(); vec.crossVectors(tangents[i - 1], tangents[i]); - if (vec.length() > Number.EPSILON) { vec.normalize(); const theta = Math.acos(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 the curve is closed, postprocess the vectors so the first and last normal vectors are the same if (closed === true) { let theta = Math.acos(clamp(normals[0].dot(normals[segments]), -1, 1)); theta /= segments; - if (tangents[0].dot(vec.crossVectors(normals[0], normals[segments])) > 0) { theta = -theta; } - for (let i = 1; i <= segments; i++) { // twist a little... normals[i].applyMatrix4(mat.makeRotationAxis(tangents[i], theta * i)); binormals[i].crossVectors(tangents[i], normals[i]); } } - return { tangents: tangents, normals: normals, binormals: binormals }; } - clone() { return new this.constructor().copy(this); } - copy(source) { this.arcLengthDivisions = source.arcLengthDivisions; return this; } - toJSON() { const data = { metadata: { @@ -22838,12 +20460,10 @@ class Curve { data.type = this.type; return data; } - fromJSON(json) { this.arcLengthDivisions = json.arcLengthDivisions; return this; } - } class EllipseCurve extends Curve { @@ -22860,17 +20480,15 @@ class EllipseCurve extends Curve { this.aClockwise = aClockwise; this.aRotation = aRotation; } - getPoint(t, optionalTarget) { const point = optionalTarget || new Vector2(); const twoPi = Math.PI * 2; let deltaAngle = this.aEndAngle - this.aStartAngle; - const samePoints = Math.abs(deltaAngle) < Number.EPSILON; // ensures that deltaAngle is 0 .. 2 PI + const samePoints = Math.abs(deltaAngle) < Number.EPSILON; + // ensures that deltaAngle is 0 .. 2 PI while (deltaAngle < 0) deltaAngle += twoPi; - while (deltaAngle > twoPi) deltaAngle -= twoPi; - if (deltaAngle < Number.EPSILON) { if (samePoints) { deltaAngle = 0; @@ -22878,7 +20496,6 @@ class EllipseCurve extends Curve { deltaAngle = twoPi; } } - if (this.aClockwise === true && !samePoints) { if (deltaAngle === twoPi) { deltaAngle = -twoPi; @@ -22886,24 +20503,21 @@ class EllipseCurve extends Curve { deltaAngle = deltaAngle - twoPi; } } - const angle = this.aStartAngle + t * deltaAngle; let x = this.aX + this.xRadius * Math.cos(angle); let y = this.aY + this.yRadius * Math.sin(angle); - if (this.aRotation !== 0) { const cos = Math.cos(this.aRotation); const sin = Math.sin(this.aRotation); const tx = x - this.aX; - const ty = y - this.aY; // Rotate the point about the center of the ellipse. + const ty = y - this.aY; + // Rotate the point about the center of the ellipse. x = tx * cos - ty * sin + this.aX; y = tx * sin + ty * cos + this.aY; } - return point.set(x, y); } - copy(source) { super.copy(source); this.aX = source.aX; @@ -22916,7 +20530,6 @@ class EllipseCurve extends Curve { this.aRotation = source.aRotation; return this; } - toJSON() { const data = super.toJSON(); data.aX = this.aX; @@ -22929,7 +20542,6 @@ class EllipseCurve extends Curve { data.aRotation = this.aRotation; return data; } - fromJSON(json) { super.fromJSON(json); this.aX = json.aX; @@ -22942,7 +20554,6 @@ class EllipseCurve extends Curve { this.aRotation = json.aRotation; return this; } - } class ArcCurve extends EllipseCurve { @@ -22951,7 +20562,6 @@ class ArcCurve extends EllipseCurve { this.isArcCurve = true; this.type = 'ArcCurve'; } - } /** @@ -22975,9 +20585,10 @@ which can be placed in CurveUtils. function CubicPoly() { let c0 = 0, - c1 = 0, - c2 = 0, - c3 = 0; + c1 = 0, + c2 = 0, + c3 = 0; + /* * Compute coefficients for a cubic polynomial * p(s) = c0 + c1*s + c2*s^2 + c3*s^3 @@ -22986,14 +20597,12 @@ function CubicPoly() { * 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 (x0, x1, x2, x3, tension) { init(x1, x2, tension * (x2 - x0), tension * (x3 - x1)); @@ -23001,8 +20610,9 @@ function CubicPoly() { initNonuniformCatmullRom: function (x0, x1, x2, x3, dt0, dt1, dt2) { // compute tangents when parameterized in [t1,t2] let t1 = (x1 - x0) / dt0 - (x2 - x0) / (dt0 + dt1) + (x2 - x1) / dt1; - let t2 = (x2 - x1) / dt1 - (x3 - x1) / (dt1 + dt2) + (x3 - x2) / dt2; // rescale tangents for parametrization in [0,1] + let 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); @@ -23013,14 +20623,14 @@ function CubicPoly() { return c0 + c1 * t + c2 * t2 + c3 * t3; } }; -} // +} +// const tmp = /*@__PURE__*/new Vector3(); const px = /*@__PURE__*/new CubicPoly(); const py = /*@__PURE__*/new CubicPoly(); const pz = /*@__PURE__*/new CubicPoly(); - class CatmullRomCurve3 extends Curve { constructor(points = [], closed = false, curveType = 'centripetal', tension = 0.5) { super(); @@ -23031,7 +20641,6 @@ class CatmullRomCurve3 extends Curve { this.curveType = curveType; this.tension = tension; } - getPoint(t, optionalTarget = new Vector3()) { const point = optionalTarget; const points = this.points; @@ -23039,14 +20648,12 @@ class CatmullRomCurve3 extends Curve { const p = (l - (this.closed ? 0 : 1)) * t; let intPoint = Math.floor(p); let weight = p - intPoint; - 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; } - let p0, p3; // 4 points (p1 & p2 defined below) if (this.closed || intPoint > 0) { @@ -23056,10 +20663,8 @@ class CatmullRomCurve3 extends Curve { tmp.subVectors(points[0], points[1]).add(points[0]); p0 = tmp; } - const p1 = points[intPoint % l]; const p2 = points[(intPoint + 1) % l]; - if (this.closed || intPoint + 2 < l) { p3 = points[(intPoint + 2) % l]; } else { @@ -23067,14 +20672,14 @@ class CatmullRomCurve3 extends Curve { 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 const pow = this.curveType === 'chordal' ? 0.5 : 0.25; let dt0 = Math.pow(p0.distanceToSquared(p1), pow); let dt1 = Math.pow(p1.distanceToSquared(p2), pow); - let dt2 = Math.pow(p2.distanceToSquared(p3), pow); // safety check for repeated points + let 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; @@ -23086,107 +20691,92 @@ class CatmullRomCurve3 extends Curve { 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; } - copy(source) { super.copy(source); this.points = []; - for (let i = 0, l = source.points.length; i < l; i++) { const point = source.points[i]; this.points.push(point.clone()); } - this.closed = source.closed; this.curveType = source.curveType; this.tension = source.tension; return this; } - toJSON() { const data = super.toJSON(); data.points = []; - for (let i = 0, l = this.points.length; i < l; i++) { const point = this.points[i]; data.points.push(point.toArray()); } - data.closed = this.closed; data.curveType = this.curveType; data.tension = this.tension; return data; } - fromJSON(json) { super.fromJSON(json); this.points = []; - for (let i = 0, l = json.points.length; i < l; i++) { const point = json.points[i]; this.points.push(new Vector3().fromArray(point)); } - this.closed = json.closed; this.curveType = json.curveType; this.tension = json.tension; return this; } - } /** * Bezier Curves formulas obtained from * https://en.wikipedia.org/wiki/B%C3%A9zier_curve */ + function CatmullRom(t, p0, p1, p2, p3) { const v0 = (p2 - p0) * 0.5; const v1 = (p3 - p1) * 0.5; const t2 = t * t; const t3 = t * t2; return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1; -} // +} +// function QuadraticBezierP0(t, p) { const k = 1 - t; return k * k * p; } - function QuadraticBezierP1(t, p) { return 2 * (1 - t) * t * p; } - function QuadraticBezierP2(t, p) { return t * t * p; } - function QuadraticBezier(t, p0, p1, p2) { return QuadraticBezierP0(t, p0) + QuadraticBezierP1(t, p1) + QuadraticBezierP2(t, p2); -} // +} +// function CubicBezierP0(t, p) { const k = 1 - t; return k * k * k * p; } - function CubicBezierP1(t, p) { const k = 1 - t; return 3 * k * k * t * p; } - function CubicBezierP2(t, p) { return 3 * (1 - t) * t * t * p; } - function CubicBezierP3(t, p) { return t * t * t * p; } - function CubicBezier(t, p0, p1, p2, p3) { return CubicBezierP0(t, p0) + CubicBezierP1(t, p1) + CubicBezierP2(t, p2) + CubicBezierP3(t, p3); } @@ -23201,17 +20791,15 @@ class CubicBezierCurve extends Curve { this.v2 = v2; this.v3 = v3; } - getPoint(t, optionalTarget = new Vector2()) { const point = optionalTarget; const v0 = this.v0, - v1 = this.v1, - v2 = this.v2, - v3 = this.v3; + 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; } - copy(source) { super.copy(source); this.v0.copy(source.v0); @@ -23220,7 +20808,6 @@ class CubicBezierCurve extends Curve { this.v3.copy(source.v3); return this; } - toJSON() { const data = super.toJSON(); data.v0 = this.v0.toArray(); @@ -23229,7 +20816,6 @@ class CubicBezierCurve extends Curve { data.v3 = this.v3.toArray(); return data; } - fromJSON(json) { super.fromJSON(json); this.v0.fromArray(json.v0); @@ -23238,7 +20824,6 @@ class CubicBezierCurve extends Curve { this.v3.fromArray(json.v3); return this; } - } class CubicBezierCurve3 extends Curve { @@ -23251,17 +20836,15 @@ class CubicBezierCurve3 extends Curve { this.v2 = v2; this.v3 = v3; } - getPoint(t, optionalTarget = new Vector3()) { const point = optionalTarget; const v0 = this.v0, - v1 = this.v1, - v2 = this.v2, - v3 = this.v3; + 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; } - copy(source) { super.copy(source); this.v0.copy(source.v0); @@ -23270,7 +20853,6 @@ class CubicBezierCurve3 extends Curve { this.v3.copy(source.v3); return this; } - toJSON() { const data = super.toJSON(); data.v0 = this.v0.toArray(); @@ -23279,7 +20861,6 @@ class CubicBezierCurve3 extends Curve { data.v3 = this.v3.toArray(); return data; } - fromJSON(json) { super.fromJSON(json); this.v0.fromArray(json.v0); @@ -23288,7 +20869,6 @@ class CubicBezierCurve3 extends Curve { this.v3.fromArray(json.v3); return this; } - } class LineCurve extends Curve { @@ -23299,52 +20879,44 @@ class LineCurve extends Curve { this.v1 = v1; this.v2 = v2; } - getPoint(t, optionalTarget = new Vector2()) { const point = optionalTarget; - if (t === 1) { point.copy(this.v2); } else { point.copy(this.v2).sub(this.v1); point.multiplyScalar(t).add(this.v1); } - return point; - } // Line curve is linear, so we can overwrite default getPointAt - + } + // Line curve is linear, so we can overwrite default getPointAt getPointAt(u, optionalTarget) { return this.getPoint(u, optionalTarget); } - getTangent(t, optionalTarget) { const tangent = optionalTarget || new Vector2(); tangent.copy(this.v2).sub(this.v1).normalize(); return tangent; } - copy(source) { super.copy(source); this.v1.copy(source.v1); this.v2.copy(source.v2); return this; } - toJSON() { const data = super.toJSON(); data.v1 = this.v1.toArray(); data.v2 = this.v2.toArray(); return data; } - fromJSON(json) { super.fromJSON(json); this.v1.fromArray(json.v1); this.v2.fromArray(json.v2); return this; } - } class LineCurve3 extends Curve { @@ -23355,46 +20927,38 @@ class LineCurve3 extends Curve { this.v1 = v1; this.v2 = v2; } - getPoint(t, optionalTarget = new Vector3()) { const point = optionalTarget; - if (t === 1) { point.copy(this.v2); } else { point.copy(this.v2).sub(this.v1); point.multiplyScalar(t).add(this.v1); } - return point; - } // Line curve is linear, so we can overwrite default getPointAt - - + } + // Line curve is linear, so we can overwrite default getPointAt getPointAt(u, optionalTarget) { return this.getPoint(u, optionalTarget); } - copy(source) { super.copy(source); this.v1.copy(source.v1); this.v2.copy(source.v2); return this; } - toJSON() { const data = super.toJSON(); data.v1 = this.v1.toArray(); data.v2 = this.v2.toArray(); return data; } - fromJSON(json) { super.fromJSON(json); this.v1.fromArray(json.v1); this.v2.fromArray(json.v2); return this; } - } class QuadraticBezierCurve extends Curve { @@ -23406,16 +20970,14 @@ class QuadraticBezierCurve extends Curve { this.v1 = v1; this.v2 = v2; } - getPoint(t, optionalTarget = new Vector2()) { const point = optionalTarget; const v0 = this.v0, - v1 = this.v1, - v2 = this.v2; + 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; } - copy(source) { super.copy(source); this.v0.copy(source.v0); @@ -23423,7 +20985,6 @@ class QuadraticBezierCurve extends Curve { this.v2.copy(source.v2); return this; } - toJSON() { const data = super.toJSON(); data.v0 = this.v0.toArray(); @@ -23431,7 +20992,6 @@ class QuadraticBezierCurve extends Curve { data.v2 = this.v2.toArray(); return data; } - fromJSON(json) { super.fromJSON(json); this.v0.fromArray(json.v0); @@ -23439,7 +20999,6 @@ class QuadraticBezierCurve extends Curve { this.v2.fromArray(json.v2); return this; } - } class QuadraticBezierCurve3 extends Curve { @@ -23451,16 +21010,14 @@ class QuadraticBezierCurve3 extends Curve { this.v1 = v1; this.v2 = v2; } - getPoint(t, optionalTarget = new Vector3()) { const point = optionalTarget; const v0 = this.v0, - v1 = this.v1, - v2 = this.v2; + 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; } - copy(source) { super.copy(source); this.v0.copy(source.v0); @@ -23468,7 +21025,6 @@ class QuadraticBezierCurve3 extends Curve { this.v2.copy(source.v2); return this; } - toJSON() { const data = super.toJSON(); data.v0 = this.v0.toArray(); @@ -23476,7 +21032,6 @@ class QuadraticBezierCurve3 extends Curve { data.v2 = this.v2.toArray(); return data; } - fromJSON(json) { super.fromJSON(json); this.v0.fromArray(json.v0); @@ -23484,7 +21039,6 @@ class QuadraticBezierCurve3 extends Curve { this.v2.fromArray(json.v2); return this; } - } class SplineCurve extends Curve { @@ -23494,7 +21048,6 @@ class SplineCurve extends Curve { this.type = 'SplineCurve'; this.points = points; } - getPoint(t, optionalTarget = new Vector2()) { const point = optionalTarget; const points = this.points; @@ -23508,43 +21061,33 @@ class SplineCurve extends Curve { point.set(CatmullRom(weight, p0.x, p1.x, p2.x, p3.x), CatmullRom(weight, p0.y, p1.y, p2.y, p3.y)); return point; } - copy(source) { super.copy(source); this.points = []; - for (let i = 0, l = source.points.length; i < l; i++) { const point = source.points[i]; this.points.push(point.clone()); } - return this; } - toJSON() { const data = super.toJSON(); data.points = []; - for (let i = 0, l = this.points.length; i < l; i++) { const point = this.points[i]; data.points.push(point.toArray()); } - return data; } - fromJSON(json) { super.fromJSON(json); this.points = []; - for (let i = 0, l = json.points.length; i < l; i++) { const point = json.points[i]; this.points.push(new Vector2().fromArray(point)); } - return this; } - } var Curves = /*#__PURE__*/Object.freeze({ @@ -23577,28 +21120,30 @@ class CurvePath extends Curve { add(curve) { this.curves.push(curve); } - closePath() { // Add a line curve if start and end of lines are not connected const startPoint = this.curves[0].getPoint(0); const 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 + } + + // 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(t, optionalTarget) { const d = t * this.getLength(); const curveLengths = this.getCurveLengths(); - let i = 0; // To think about boundaries points. + let i = 0; + + // To think about boundaries points. while (i < curveLengths.length) { if (curveLengths[i] >= d) { @@ -23608,73 +21153,68 @@ class CurvePath extends Curve { const u = segmentLength === 0 ? 0 : 1 - diff / segmentLength; return curve.getPointAt(u, optionalTarget); } - i++; } + return null; + + // loop where sum != 0, sum > d , sum+1 d , sum+1 1 && !points[points.length - 1].equals(points[0])) { points.push(points[0]); } - return points; } - copy(source) { super.copy(source); this.curves = []; - for (let i = 0, l = source.curves.length; i < l; i++) { const curve = source.curves[i]; this.curves.push(curve.clone()); } - this.autoClose = source.autoClose; return this; } - toJSON() { const data = super.toJSON(); data.autoClose = this.autoClose; data.curves = []; - for (let i = 0, l = this.curves.length; i < l; i++) { const curve = this.curves[i]; data.curves.push(curve.toJSON()); } - return data; } - fromJSON(json) { super.fromJSON(json); this.autoClose = json.autoClose; this.curves = []; - for (let i = 0, l = json.curves.length; i < l; i++) { const curve = json.curves[i]; this.curves.push(new Curves[curve.type]().fromJSON(curve)); } - return this; } - } class Path extends CurvePath { @@ -23737,114 +21265,92 @@ class Path extends CurvePath { super(); this.type = 'Path'; this.currentPoint = new Vector2(); - if (points) { this.setFromPoints(points); } } - setFromPoints(points) { this.moveTo(points[0].x, points[0].y); - for (let i = 1, l = points.length; i < l; i++) { this.lineTo(points[i].x, points[i].y); } - return this; } - moveTo(x, y) { this.currentPoint.set(x, y); // TODO consider referencing vectors instead of copying? return this; } - lineTo(x, y) { const curve = new LineCurve(this.currentPoint.clone(), new Vector2(x, y)); this.curves.push(curve); this.currentPoint.set(x, y); return this; } - quadraticCurveTo(aCPx, aCPy, aX, aY) { const 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(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY) { const 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(pts - /*Array of Vector*/ - ) { + splineThru(pts /*Array of Vector*/) { const npts = [this.currentPoint.clone()].concat(pts); const curve = new SplineCurve(npts); this.curves.push(curve); this.currentPoint.copy(pts[pts.length - 1]); return this; } - arc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { const x0 = this.currentPoint.x; const y0 = this.currentPoint.y; this.absarc(aX + x0, aY + y0, aRadius, aStartAngle, aEndAngle, aClockwise); return this; } - absarc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { this.absellipse(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise); return this; } - ellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation) { const x0 = this.currentPoint.x; const y0 = this.currentPoint.y; this.absellipse(aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation); return this; } - absellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation) { const curve = new EllipseCurve(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation); - if (this.curves.length > 0) { // if a previous curve is present, attempt to join const firstPoint = curve.getPoint(0); - if (!firstPoint.equals(this.currentPoint)) { this.lineTo(firstPoint.x, firstPoint.y); } } - this.curves.push(curve); const lastPoint = curve.getPoint(1); this.currentPoint.copy(lastPoint); return this; } - copy(source) { super.copy(source); this.currentPoint.copy(source.currentPoint); return this; } - toJSON() { const data = super.toJSON(); data.currentPoint = this.currentPoint.toArray(); return data; } - fromJSON(json) { super.fromJSON(json); this.currentPoint.fromArray(json.currentPoint); return this; } - } class LatheGeometry extends BufferGeometry { @@ -23857,15 +21363,21 @@ class LatheGeometry extends BufferGeometry { phiStart: phiStart, phiLength: phiLength }; - segments = Math.floor(segments); // clamp phiLength so it's in range of [ 0, 2PI ] + segments = Math.floor(segments); + + // clamp phiLength so it's in range of [ 0, 2PI ] + + phiLength = clamp(phiLength, 0, Math.PI * 2); - phiLength = clamp(phiLength, 0, Math.PI * 2); // buffers + // buffers const indices = []; const vertices = []; const uvs = []; const initNormals = []; - const normals = []; // helper variables + const normals = []; + + // helper variables const inverseSegments = 1.0 / segments; const vertex = new Vector3(); @@ -23874,12 +21386,15 @@ class LatheGeometry extends BufferGeometry { const curNormal = new Vector3(); const prevNormal = new Vector3(); let dx = 0; - let dy = 0; // pre-compute normals for initial "meridian" + let dy = 0; + + // pre-compute normals for initial "meridian" for (let j = 0; j <= points.length - 1; j++) { switch (j) { case 0: // special handling for 1st vertex on path + dx = points[j + 1].x - points[j].x; dy = points[j + 1].y - points[j].y; normal.x = dy * 1.0; @@ -23889,14 +21404,14 @@ class LatheGeometry extends BufferGeometry { normal.normalize(); initNormals.push(normal.x, normal.y, normal.z); break; - case points.length - 1: // special handling for last Vertex on path + initNormals.push(prevNormal.x, prevNormal.y, prevNormal.z); break; - default: // default handling for all vertices in between + dx = points[j + 1].x - points[j].x; dy = points[j + 1].y - points[j].y; normal.x = dy * 1.0; @@ -23910,32 +21425,38 @@ class LatheGeometry extends BufferGeometry { initNormals.push(normal.x, normal.y, normal.z); prevNormal.copy(curNormal); } - } // generate vertices, uvs and normals + } + // generate vertices, uvs and normals for (let i = 0; i <= segments; i++) { const phi = phiStart + i * inverseSegments * phiLength; const sin = Math.sin(phi); const cos = Math.cos(phi); - for (let 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 + 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); // normal + uvs.push(uv.x, uv.y); + + // normal const x = initNormals[3 * j + 0] * sin; const y = initNormals[3 * j + 1]; const z = initNormals[3 * j + 0] * cos; normals.push(x, y, z); } - } // indices + } + // indices for (let i = 0; i < segments; i++) { for (let j = 0; j < points.length - 1; j++) { @@ -23943,24 +21464,25 @@ class LatheGeometry extends BufferGeometry { const a = base; const b = base + points.length; const c = base + points.length + 1; - const d = base + 1; // faces + const d = base + 1; + + // faces indices.push(a, b, d); indices.push(c, d, b); } - } // build geometry + } + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); } - static fromJSON(data) { return new LatheGeometry(data.points, data.segments, data.phiStart, data.phiLength); } - } class CapsuleGeometry extends LatheGeometry { @@ -23977,11 +21499,9 @@ class CapsuleGeometry extends LatheGeometry { radialSegments: radialSegments }; } - static fromJSON(data) { return new CapsuleGeometry(data.radius, data.length, data.capSegments, data.radialSegments); } - } class CircleGeometry extends BufferGeometry { @@ -23994,50 +21514,61 @@ class CircleGeometry extends BufferGeometry { thetaStart: thetaStart, thetaLength: thetaLength }; - segments = Math.max(3, segments); // buffers + segments = Math.max(3, segments); + + // buffers const indices = []; const vertices = []; const normals = []; - const uvs = []; // helper variables + const uvs = []; + + // helper variables const vertex = new Vector3(); - const uv = new Vector2(); // center point + const uv = new Vector2(); + + // center point vertices.push(0, 0, 0); normals.push(0, 0, 1); uvs.push(0.5, 0.5); - for (let s = 0, i = 3; s <= segments; s++, i += 3) { - const segment = thetaStart + s / segments * thetaLength; // vertex + const 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 + vertices.push(vertex.x, vertex.y, vertex.z); + + // normal + + normals.push(0, 0, 1); - normals.push(0, 0, 1); // uvs + // uvs uv.x = (vertices[i] / radius + 1) / 2; uv.y = (vertices[i + 1] / radius + 1) / 2; uvs.push(uv.x, uv.y); - } // indices + } + // indices for (let i = 1; i <= segments; i++) { indices.push(i, i + 1, 0); - } // build geometry + } + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); } - static fromJSON(data) { return new CircleGeometry(data.radius, data.segments, data.thetaStart, data.thetaLength); } - } class CylinderGeometry extends BufferGeometry { @@ -24056,89 +21587,115 @@ class CylinderGeometry extends BufferGeometry { }; const scope = this; radialSegments = Math.floor(radialSegments); - heightSegments = Math.floor(heightSegments); // buffers + heightSegments = Math.floor(heightSegments); + + // buffers const indices = []; const vertices = []; const normals = []; - const uvs = []; // helper variables + const uvs = []; + + // helper variables let index = 0; const indexArray = []; const halfHeight = height / 2; - let groupStart = 0; // generate geometry + let groupStart = 0; - generateTorso(); + // generate geometry + generateTorso(); if (openEnded === false) { if (radiusTop > 0) generateCap(true); if (radiusBottom > 0) generateCap(false); - } // build geometry + } + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); - function generateTorso() { const normal = new Vector3(); const vertex = new Vector3(); - let groupCount = 0; // this will be used to calculate the normal + let groupCount = 0; - const slope = (radiusBottom - radiusTop) / height; // generate vertices, normals and uvs + // this will be used to calculate the normal + const slope = (radiusBottom - radiusTop) / height; + + // generate vertices, normals and uvs for (let y = 0; y <= heightSegments; y++) { const indexRow = []; - const v = y / heightSegments; // calculate the radius of the current row + const v = y / heightSegments; - const radius = v * (radiusBottom - radiusTop) + radiusTop; + // calculate the radius of the current row + const radius = v * (radiusBottom - radiusTop) + radiusTop; for (let x = 0; x <= radialSegments; x++) { const u = x / radialSegments; const theta = u * thetaLength + thetaStart; const sinTheta = Math.sin(theta); - const cosTheta = Math.cos(theta); // vertex + const 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 + vertices.push(vertex.x, vertex.y, vertex.z); + + // normal normal.set(sinTheta, slope, cosTheta).normalize(); - normals.push(normal.x, normal.y, normal.z); // uv + normals.push(normal.x, normal.y, normal.z); + + // uv - uvs.push(u, 1 - v); // save index of vertex in respective row + uvs.push(u, 1 - v); + + // save index of vertex in respective row indexRow.push(index++); - } // now save vertices of the row in our index array + } + // now save vertices of the row in our index array indexArray.push(indexRow); - } // generate indices + } + // generate indices for (let x = 0; x < radialSegments; x++) { for (let y = 0; y < heightSegments; y++) { // we use the index array to access the correct indices + const a = indexArray[y][x]; const b = indexArray[y + 1][x]; const c = indexArray[y + 1][x + 1]; - const d = indexArray[y][x + 1]; // faces + const d = indexArray[y][x + 1]; + + // faces indices.push(a, b, d); - indices.push(b, c, d); // update group counter + indices.push(b, c, d); + + // update group counter groupCount += 6; } - } // add a group to the geometry. this will ensure multi material support + } + // add a group to the geometry. this will ensure multi material support - scope.addGroup(groupStart, groupCount, 0); // calculate new start value for groups + scope.addGroup(groupStart, groupCount, 0); + + // calculate new start value for groups groupStart += groupCount; } - function generateCap(top) { // save the index of the first center vertex const centerIndexStart = index; @@ -24146,71 +21703,92 @@ class CylinderGeometry extends BufferGeometry { const vertex = new Vector3(); let groupCount = 0; const radius = top === true ? radiusTop : radiusBottom; - const sign = top === true ? 1 : -1; // first we generate the center vertex data of the cap. + const 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 for (let x = 1; x <= radialSegments; x++) { // vertex - vertices.push(0, halfHeight * sign, 0); // normal - normals.push(0, sign, 0); // uv + vertices.push(0, halfHeight * sign, 0); + + // normal + + normals.push(0, sign, 0); + + // uv - uvs.push(0.5, 0.5); // increase index + uvs.push(0.5, 0.5); + + // increase index index++; - } // save the index of the last center vertex + } + // save the index of the last center vertex + const centerIndexEnd = index; - const centerIndexEnd = index; // now we generate the surrounding vertices, normals and uvs + // now we generate the surrounding vertices, normals and uvs for (let x = 0; x <= radialSegments; x++) { const u = x / radialSegments; const theta = u * thetaLength + thetaStart; const cosTheta = Math.cos(theta); - const sinTheta = Math.sin(theta); // vertex + const sinTheta = Math.sin(theta); + + // vertex vertex.x = radius * sinTheta; vertex.y = halfHeight * sign; vertex.z = radius * cosTheta; - vertices.push(vertex.x, vertex.y, vertex.z); // normal + vertices.push(vertex.x, vertex.y, vertex.z); + + // normal - normals.push(0, sign, 0); // uv + normals.push(0, sign, 0); + + // uv uv.x = cosTheta * 0.5 + 0.5; uv.y = sinTheta * 0.5 * sign + 0.5; - uvs.push(uv.x, uv.y); // increase index + uvs.push(uv.x, uv.y); + + // increase index index++; - } // generate indices + } + // generate indices for (let x = 0; x < radialSegments; x++) { const c = centerIndexStart + x; const i = centerIndexEnd + x; - if (top === true) { // face top + indices.push(i, i + 1, c); } else { // face bottom + indices.push(i + 1, i, c); } - groupCount += 3; - } // add a group to the geometry. this will ensure multi material support + } + + // add a group to the geometry. this will ensure multi material support + scope.addGroup(groupStart, groupCount, top === true ? 1 : 2); - scope.addGroup(groupStart, groupCount, top === true ? 1 : 2); // calculate new start value for groups + // calculate new start value for groups groupStart += groupCount; } } - static fromJSON(data) { return new CylinderGeometry(data.radiusTop, data.radiusBottom, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength); } - } class ConeGeometry extends CylinderGeometry { @@ -24227,11 +21805,9 @@ class ConeGeometry extends CylinderGeometry { thetaLength: thetaLength }; } - static fromJSON(data) { return new ConeGeometry(data.radius, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength); } - } class PolyhedronGeometry extends BufferGeometry { @@ -24243,54 +21819,71 @@ class PolyhedronGeometry extends BufferGeometry { indices: indices, radius: radius, detail: detail - }; // default buffer data + }; + + // default buffer data const vertexBuffer = []; - const uvBuffer = []; // the subdivision creates the vertex buffer data + const uvBuffer = []; + + // the subdivision creates the vertex buffer data + + subdivide(detail); - subdivide(detail); // all vertices should lie on a conceptual sphere with a given radius + // all vertices should lie on a conceptual sphere with a given radius - applyRadius(radius); // finally, create the uv data + applyRadius(radius); - generateUVs(); // build non-indexed geometry + // finally, create the uv data + + generateUVs(); + + // build non-indexed geometry this.setAttribute('position', new Float32BufferAttribute(vertexBuffer, 3)); this.setAttribute('normal', new Float32BufferAttribute(vertexBuffer.slice(), 3)); this.setAttribute('uv', new Float32BufferAttribute(uvBuffer, 2)); - if (detail === 0) { this.computeVertexNormals(); // flat normals } else { this.normalizeNormals(); // smooth normals - } // helper functions + } + // helper functions function subdivide(detail) { const a = new Vector3(); const b = new Vector3(); - const c = new Vector3(); // iterate over all faces and apply a subdivison with the given detail value + const c = new Vector3(); + + // iterate over all faces and apply a subdivision with the given detail value for (let 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 + getVertexByIndex(indices[i + 2], c); + + // perform subdivision subdivideFace(a, b, c, detail); } } - function subdivideFace(a, b, c, detail) { - const cols = detail + 1; // we use this multidimensional array as a data structure for creating the subdivision + const cols = detail + 1; + + // we use this multidimensional array as a data structure for creating the subdivision - const v = []; // construct all of the vertices for this subdivision + const v = []; + + // construct all of the vertices for this subdivision for (let i = 0; i <= cols; i++) { v[i] = []; const aj = a.clone().lerp(c, i / cols); const bj = b.clone().lerp(c, i / cols); const rows = cols - i; - for (let j = 0; j <= rows; j++) { if (j === 0 && i === cols) { v[i][j] = aj; @@ -24298,13 +21891,13 @@ class PolyhedronGeometry extends BufferGeometry { v[i][j] = aj.clone().lerp(bj, j / rows); } } - } // construct all of the faces + } + // construct all of the faces for (let i = 0; i < cols; i++) { for (let j = 0; j < 2 * (cols - i) - 1; j++) { const k = Math.floor(j / 2); - if (j % 2 === 0) { pushVertex(v[i][k + 1]); pushVertex(v[i + 1][k]); @@ -24317,9 +21910,10 @@ class PolyhedronGeometry extends BufferGeometry { } } } - function applyRadius(radius) { - const vertex = new Vector3(); // iterate over the entire buffer and apply the radius to each vertex + const vertex = new Vector3(); + + // iterate over the entire buffer and apply the radius to each vertex for (let i = 0; i < vertexBuffer.length; i += 3) { vertex.x = vertexBuffer[i + 0]; @@ -24331,10 +21925,8 @@ class PolyhedronGeometry extends BufferGeometry { vertexBuffer[i + 2] = vertex.z; } } - function generateUVs() { const vertex = new Vector3(); - for (let i = 0; i < vertexBuffer.length; i += 3) { vertex.x = vertexBuffer[i + 0]; vertex.y = vertexBuffer[i + 1]; @@ -24343,20 +21935,22 @@ class PolyhedronGeometry extends BufferGeometry { const v = inclination(vertex) / Math.PI + 0.5; uvBuffer.push(u, 1 - v); } - correctUVs(); correctSeam(); } - function correctSeam() { // handle case when face straddles the seam, see #3269 + for (let i = 0; i < uvBuffer.length; i += 6) { // uv data of a single face + const x0 = uvBuffer[i + 0]; const x1 = uvBuffer[i + 2]; const x2 = uvBuffer[i + 4]; const max = Math.max(x0, x1, x2); - const min = Math.min(x0, x1, x2); // 0.9 is somewhat arbitrary + const min = Math.min(x0, x1, x2); + + // 0.9 is somewhat arbitrary if (max > 0.9 && min < 0.1) { if (x0 < 0.2) uvBuffer[i + 0] += 1; @@ -24365,18 +21959,15 @@ class PolyhedronGeometry extends BufferGeometry { } } } - function pushVertex(vertex) { vertexBuffer.push(vertex.x, vertex.y, vertex.z); } - function getVertexByIndex(index, vertex) { const stride = index * 3; vertex.x = vertices[stride + 0]; vertex.y = vertices[stride + 1]; vertex.z = vertices[stride + 2]; } - function correctUVs() { const a = new Vector3(); const b = new Vector3(); @@ -24385,7 +21976,6 @@ class PolyhedronGeometry extends BufferGeometry { const uvA = new Vector2(); const uvB = new Vector2(); const uvC = new Vector2(); - for (let 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]); @@ -24400,42 +21990,44 @@ class PolyhedronGeometry extends BufferGeometry { correctUV(uvC, j + 4, c, azi); } } - function correctUV(uv, stride, vector, azimuth) { if (azimuth < 0 && uv.x === 1) { uvBuffer[stride] = uv.x - 1; } - 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. + } + // 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. + } + // Angle above the XZ plane. function inclination(vector) { return Math.atan2(-vector.y, Math.sqrt(vector.x * vector.x + vector.z * vector.z)); } } - static fromJSON(data) { return new PolyhedronGeometry(data.vertices, data.indices, data.radius, data.details); } - } class DodecahedronGeometry extends PolyhedronGeometry { constructor(radius = 1, detail = 0) { const t = (1 + Math.sqrt(5)) / 2; const r = 1 / t; - const 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/φ) + const 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]; const 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]; super(vertices, indices, radius, detail); @@ -24445,21 +22037,15 @@ class DodecahedronGeometry extends PolyhedronGeometry { detail: detail }; } - static fromJSON(data) { return new DodecahedronGeometry(data.radius, data.detail); } - } const _v0 = /*@__PURE__*/new Vector3(); - const _v1$1 = /*@__PURE__*/new Vector3(); - const _normal = /*@__PURE__*/new Vector3(); - const _triangle = /*@__PURE__*/new Triangle(); - class EdgesGeometry extends BufferGeometry { constructor(geometry = null, thresholdAngle = 1) { super(); @@ -24468,7 +22054,6 @@ class EdgesGeometry extends BufferGeometry { geometry: geometry, thresholdAngle: thresholdAngle }; - if (geometry !== null) { const precisionPoints = 4; const precision = Math.pow(10, precisionPoints); @@ -24481,7 +22066,6 @@ class EdgesGeometry extends BufferGeometry { const hashes = new Array(3); const edgeData = {}; const vertices = []; - for (let i = 0; i < indexCount; i += 3) { if (indexAttr) { indexArr[0] = indexAttr.getX(i); @@ -24492,7 +22076,6 @@ class EdgesGeometry extends BufferGeometry { indexArr[1] = i + 1; indexArr[2] = i + 2; } - const { a, b, @@ -24501,19 +22084,19 @@ class EdgesGeometry extends BufferGeometry { a.fromBufferAttribute(positionAttr, indexArr[0]); b.fromBufferAttribute(positionAttr, indexArr[1]); c.fromBufferAttribute(positionAttr, indexArr[2]); + _triangle.getNormal(_normal); - _triangle.getNormal(_normal); // create hashes for the edge from the vertices - - + // create hashes for the edge from the vertices 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 + hashes[2] = `${Math.round(c.x * precision)},${Math.round(c.y * precision)},${Math.round(c.z * precision)}`; + // skip degenerate triangles if (hashes[0] === hashes[1] || hashes[1] === hashes[2] || hashes[2] === hashes[0]) { continue; - } // iterate over every edge - + } + // iterate over every edge for (let j = 0; j < 3; j++) { // get the first and next vertex making up the edge const jNext = (j + 1) % 3; @@ -24523,7 +22106,6 @@ class EdgesGeometry extends BufferGeometry { const v1 = _triangle[vertKeys[jNext]]; const hash = `${vecHash0}_${vecHash1}`; const 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. @@ -24531,7 +22113,6 @@ class EdgesGeometry extends BufferGeometry { 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 @@ -24542,29 +22123,24 @@ class EdgesGeometry extends BufferGeometry { }; } } - } // iterate over all remaining, unmatched edges and add them to the vertex array - + } + // iterate over all remaining, unmatched edges and add them to the vertex array for (const key in edgeData) { if (edgeData[key]) { const { index0, index1 } = edgeData[key]; - _v0.fromBufferAttribute(positionAttr, index0); - _v1$1.fromBufferAttribute(positionAttr, index1); - vertices.push(_v0.x, _v0.y, _v0.z); vertices.push(_v1$1.x, _v1$1.y, _v1$1.z); } } - this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); } } - } class Shape extends Path { @@ -24574,17 +22150,15 @@ class Shape extends Path { this.type = 'Shape'; this.holes = []; } - getPointsHoles(divisions) { const holesPts = []; - for (let i = 0, l = this.holes.length; i < l; i++) { holesPts[i] = this.holes[i].getPoints(divisions); } - return holesPts; - } // get points of shape and holes (keypoints based on segments parameter) + } + // get points of shape and holes (keypoints based on segments parameter) extractPoints(divisions) { return { @@ -24592,50 +22166,41 @@ class Shape extends Path { holes: this.getPointsHoles(divisions) }; } - copy(source) { super.copy(source); this.holes = []; - for (let i = 0, l = source.holes.length; i < l; i++) { const hole = source.holes[i]; this.holes.push(hole.clone()); } - return this; } - toJSON() { const data = super.toJSON(); data.uuid = this.uuid; data.holes = []; - for (let i = 0, l = this.holes.length; i < l; i++) { const hole = this.holes[i]; data.holes.push(hole.toJSON()); } - return data; } - fromJSON(json) { super.fromJSON(json); this.uuid = json.uuid; this.holes = []; - for (let i = 0, l = json.holes.length; i < l; i++) { const hole = json.holes[i]; this.holes.push(new Path().fromJSON(hole)); } - return this; } - } /** - * Port from https://github.com/mapbox/earcut (v2.2.2) + * Port from https://github.com/mapbox/earcut (v2.2.4) */ + const Earcut = { triangulate: function (data, holeIndices, dim = 2) { const hasHoles = holeIndices && holeIndices.length; @@ -24644,12 +22209,12 @@ const Earcut = { const triangles = []; if (!outerNode || outerNode.next === outerNode.prev) return triangles; let 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 + 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 if (data.length > 80 * dim) { minX = maxX = data[0]; minY = maxY = data[1]; - for (let i = dim; i < outerLen; i += dim) { x = data[i]; y = data[i + 1]; @@ -24657,45 +22222,40 @@ const Earcut = { 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 - + } + // minX, minY and invSize are later used to transform coords into integers for z-order calculation invSize = Math.max(maxX - minX, maxY - minY); - invSize = invSize !== 0 ? 1 / invSize : 0; + invSize = invSize !== 0 ? 32767 / invSize : 0; } - - earcutLinked(outerNode, triangles, dim, minX, minY, invSize); + earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0); return triangles; } -}; // create a circular doubly linked list from polygon points in the specified winding order +}; +// create a circular doubly linked list from polygon points in the specified winding order function linkedList(data, start, end, dim, clockwise) { let i, last; - 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; } - return last; -} // eliminate colinear or duplicate points - +} +// eliminate colinear or duplicate points function filterPoints(start, end) { if (!start) return start; if (!end) end = start; let p = start, - again; - + again; do { again = false; - if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) { removeNode(p); p = end = p.prev; @@ -24705,167 +22265,182 @@ function filterPoints(start, end) { p = p.next; } } while (again || p !== end); - return end; -} // main ear slicing loop which triangulates a polygon (given as a linked list) - +} +// main ear slicing loop which triangulates a polygon (given as a linked list) function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) { - if (!ear) return; // interlink polygon nodes in z-order + if (!ear) return; + // interlink polygon nodes in z-order if (!pass && invSize) indexCurve(ear, minX, minY, invSize); let stop = ear, - prev, - next; // iterate through ears, slicing them one by one + prev, + next; + // iterate through ears, slicing them one by one while (ear.prev !== ear.next) { prev = ear.prev; next = ear.next; - 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 + triangles.push(prev.i / dim | 0); + triangles.push(ear.i / dim | 0); + triangles.push(next.i / dim | 0); + removeNode(ear); + // skipping the next vertex leads to less sliver triangles ear = next.next; stop = next.next; continue; } + ear = next; - ear = next; // if we looped through the whole remaining polygon and can't find any more ears - + // if we looped through the whole remaining polygon and can't find any more ears 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 + 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 + 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); } - break; } } -} // check whether a polygon node forms a valid ear with adjacent nodes - +} +// check whether a polygon node forms a valid ear with adjacent nodes function isEar(ear) { const a = ear.prev, - b = ear, - c = ear.next; + 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 - let p = ear.next.next; + // now make sure we don't have other points inside the potential ear + const ax = a.x, + bx = b.x, + cx = c.x, + ay = a.y, + by = b.y, + cy = c.y; - 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; + // triangle bbox; min & max are calculated like this for speed + const x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx, + y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy, + x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx, + y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy; + let p = c.next; + while (p !== a) { + if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; p = p.next; } - return true; } - function isEarHashed(ear, minX, minY, invSize) { const a = ear.prev, - b = ear, - c = ear.next; + 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 - const 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; + const ax = a.x, + bx = b.x, + cx = c.x, + ay = a.y, + by = b.y, + cy = c.y; - const minZ = zOrder(minTX, minTY, minX, minY, invSize), - maxZ = zOrder(maxTX, maxTY, minX, minY, invSize); + // triangle bbox; min & max are calculated like this for speed + const x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx, + y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy, + x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx, + y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy; + + // z-order range for the current triangle bbox; + const minZ = zOrder(x0, y0, minX, minY, invSize), + maxZ = zOrder(x1, y1, minX, minY, invSize); let p = ear.prevZ, - n = ear.nextZ; // look for points inside the triangle in both directions + n = ear.nextZ; + // look for points inside the triangle in both directions 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; + if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangle(ax, ay, bx, by, cx, cy, 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; + if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; n = n.nextZ; - } // look for remaining points in decreasing z-order - + } + // 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; + if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; p = p.prevZ; - } // look for remaining points in increasing z-order - + } + // look for remaining points in increasing z-order 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; + if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; n = n.nextZ; } - return true; -} // go through all polygon nodes and cure small local self-intersections - +} +// go through all polygon nodes and cure small local self-intersections function cureLocalIntersections(start, triangles, dim) { let p = start; - do { const a = p.prev, - b = p.next.next; - + b = p.next.next; 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 + triangles.push(a.i / dim | 0); + triangles.push(p.i / dim | 0); + triangles.push(b.i / dim | 0); + // remove two nodes involved removeNode(p); removeNode(p.next); p = start = b; } - p = p.next; } while (p !== start); - return filterPoints(p); -} // try splitting polygon into two and triangulate them independently - +} +// 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 let a = start; - do { let b = a.next.next; - while (b !== a.prev) { if (a.i !== b.i && isValidDiagonal(a, b)) { // split the polygon in two by the diagonal - let c = splitPolygon(a, b); // filter colinear points around the cuts + let 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 + c = filterPoints(c, c.next); - earcutLinked(a, triangles, dim, minX, minY, invSize); - earcutLinked(c, triangles, dim, minX, minY, invSize); + // run earcut on each half + earcutLinked(a, triangles, dim, minX, minY, invSize, 0); + earcutLinked(c, triangles, dim, minX, minY, invSize, 0); return; } - b = b.next; } - a = a.next; } while (a !== start); -} // link every hole into the outer loop, producing a single-ring polygon without holes - +} +// link every hole into the outer loop, producing a single-ring polygon without holes function eliminateHoles(data, holeIndices, outerNode, dim) { const queue = []; let 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; @@ -24873,74 +22448,65 @@ function eliminateHoles(data, holeIndices, outerNode, dim) { if (list === list.next) list.steiner = true; queue.push(getLeftmost(list)); } + queue.sort(compareX); - queue.sort(compareX); // process holes from left to right - + // process holes from left to right for (i = 0; i < queue.length; i++) { - eliminateHole(queue[i], outerNode); - outerNode = filterPoints(outerNode, outerNode.next); + outerNode = eliminateHole(queue[i], outerNode); } - return outerNode; } - function compareX(a, b) { return a.x - b.x; -} // find a bridge between vertices that connects hole with an outer ring and link it - +} +// find a bridge between vertices that connects hole with an outer ring and link it function eliminateHole(hole, outerNode) { - outerNode = findHoleBridge(hole, outerNode); - - if (outerNode) { - const b = splitPolygon(outerNode, hole); // filter collinear points around the cuts - - filterPoints(outerNode, outerNode.next); - filterPoints(b, b.next); + const bridge = findHoleBridge(hole, outerNode); + if (!bridge) { + return outerNode; } -} // David Eberly's algorithm for finding a bridge between hole and outer polygon + const bridgeReverse = splitPolygon(bridge, hole); + // filter collinear points around the cuts + filterPoints(bridgeReverse, bridgeReverse.next); + return filterPoints(bridge, bridge.next); +} +// David Eberly's algorithm for finding a bridge between hole and outer polygon function findHoleBridge(hole, outerNode) { - let p = outerNode; - const hx = hole.x; - const hy = hole.y; - let 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 + let p = outerNode, + qx = -Infinity, + m; + const hx = hole.x, + hy = hole.y; + // 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 do { if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) { const x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); - if (x <= hx && x > qx) { qx = x; - - if (x === hx) { - if (hy === p.y) return p; - if (hy === p.next.y) return p.next; - } - m = p.x < p.next.x ? p : p.next; + if (x === hx) return m; // hole touches outer segment; pick leftmost endpoint } } p = p.next; } while (p !== outerNode); - 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 const stop = m, - mx = m.x, - my = m.y; + mx = m.x, + my = m.y; let tanMin = Infinity, - tan; + tan; p = m; - 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 @@ -24950,66 +22516,57 @@ function findHoleBridge(hole, outerNode) { tanMin = tan; } } - p = p.next; } while (p !== stop); - return m; -} // whether sector in vertex m contains sector in vertex p in the same coordinates - +} +// whether sector in vertex m contains sector in vertex p in the same coordinates 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 - +} +// interlink polygon nodes in z-order function indexCurve(start, minX, minY, invSize) { let p = start; - do { - if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, invSize); + if (p.z === 0) p.z = zOrder(p.x, p.y, minX, minY, invSize); p.prevZ = p.prev; p.nextZ = p.next; p = p.next; } while (p !== start); - 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 - +} +// Simon Tatham's linked list merge sort algorithm +// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html function sortLinked(list) { let i, - p, - q, - e, - tail, - numMerges, - pSize, - qSize, - inSize = 1; - + p, + q, + e, + tail, + numMerges, + pSize, + qSize, + inSize = 1; do { p = list; list = null; tail = null; numMerges = 0; - while (p) { numMerges++; q = p; pSize = 0; - for (i = 0; i < inSize; i++) { pSize++; q = q.nextZ; if (!q) break; } - qSize = inSize; - while (pSize > 0 || qSize > 0 && q) { if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) { e = p; @@ -25020,27 +22577,23 @@ function sortLinked(list) { q = q.nextZ; qSize--; } - if (tail) tail.nextZ = e;else list = e; e.prevZ = tail; tail = e; } - p = q; } - tail.nextZ = null; inSize *= 2; } while (numMerges > 1); - return list; -} // z-order of a point given coords and inverse of the longer side of data bbox - +} +// z-order of a point given coords and inverse of the longer side of data bbox 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 - minX) * invSize | 0; + y = (y - minY) * invSize | 0; x = (x | x << 8) & 0x00FF00FF; x = (x | x << 4) & 0x0F0F0F0F; x = (x | x << 2) & 0x33333333; @@ -25050,45 +22603,46 @@ function zOrder(x, y, minX, minY, invSize) { y = (y | y << 2) & 0x33333333; y = (y | y << 1) & 0x55555555; return x | y << 1; -} // find the leftmost node of a polygon ring - +} +// find the leftmost node of a polygon ring function getLeftmost(start) { let p = start, - leftmost = 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); - return leftmost; -} // check if a point lies within a convex triangle - +} +// check if a point lies within a convex triangle 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) - + return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && (ax - px) * (by - py) >= (bx - px) * (ay - py) && (bx - px) * (cy - py) >= (cx - px) * (by - py); +} +// check if a diagonal between two polygon nodes is valid (lies in polygon interior) function isValidDiagonal(a, b) { - return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && ( // doesn'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 + 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 - +} +// signed area of a triangle 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 - +} +// check if two points are equal function equals(p1, p2) { return p1.x === p2.x && p1.y === p2.y; -} // check if two segments intersect - +} +// check if two segments intersect function intersects(p1, q1, p2, q2) { const o1 = sign(area(p1, q1, p2)); const o2 = sign(area(p1, q1, q2)); @@ -25097,64 +22651,56 @@ function intersects(p1, q1, p2, q2) { if (o1 !== o2 && o3 !== o4) return true; // general case if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1 - if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1 - if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2 - if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2 return false; -} // for collinear points p, q, r, check if point q lies on segment pr - +} +// 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 - +} +// check if a polygon diagonal intersects any polygon segments function intersectsPolygon(a, b) { let p = a; - 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); - return false; -} // check if a polygon diagonal is locally inside the polygon - +} +// check if a polygon diagonal is locally inside the polygon 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 - +} +// check if the middle point of a polygon diagonal is inside the polygon function middleInside(a, b) { let p = a, - inside = false; + inside = false; const px = (a.x + b.x) / 2, - py = (a.y + b.y) / 2; - + py = (a.y + b.y) / 2; 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); - 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 - +} +// 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 function splitPolygon(a, b) { const a2 = new Node(a.i, a.x, a.y), - b2 = new Node(b.i, b.x, b.y), - an = a.next, - bp = b.prev; + b2 = new Node(b.i, b.x, b.y), + an = a.next, + bp = b.prev; a.next = b; b.prev = a; a2.next = an; @@ -25164,12 +22710,11 @@ function splitPolygon(a, b) { bp.next = b2; b2.prev = bp; return b2; -} // create a node and optionally link it with previous one (in a circular doubly linked list) - +} +// create a node and optionally link it with previous one (in a circular doubly linked list) function insertNode(i, x, y, last) { const p = new Node(i, x, y); - if (!last) { p.prev = p; p.next = p; @@ -25179,102 +22724,95 @@ function insertNode(i, x, y, last) { last.next.prev = p; last.next = p; } - 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; } - function Node(i, x, y) { // vertex index in coordinates array - this.i = i; // vertex coordinates + this.i = i; + // vertex coordinates this.x = x; - this.y = y; // previous and next vertex nodes in a polygon ring + this.y = y; + // previous and next vertex nodes in a polygon ring this.prev = null; - this.next = null; // z-order curve value + this.next = null; - this.z = null; // previous and next nodes in z-order + // z-order curve value + this.z = 0; + // previous and next nodes in z-order this.prevZ = null; - this.nextZ = null; // indicates whether this is a steiner point + this.nextZ = null; + // indicates whether this is a steiner point this.steiner = false; } - function signedArea(data, start, end, dim) { let sum = 0; - for (let i = start, j = end - dim; i < end; i += dim) { sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); j = i; } - return sum; } class ShapeUtils { // calculate area of the contour polygon + static area(contour) { const n = contour.length; let a = 0.0; - for (let 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; } - static isClockWise(pts) { return ShapeUtils.area(pts) < 0; } - static triangulateShape(contour, holes) { const vertices = []; // flat array of vertices like [ x0,y0, x1,y1, x2,y2, ... ] - const holeIndices = []; // array of hole indices - const faces = []; // final array of vertex indices like [ [ a,b,d ], [ b,c,d ] ] removeDupEndPts(contour); - addContour(vertices, contour); // + addContour(vertices, contour); + + // let holeIndex = contour.length; holes.forEach(removeDupEndPts); - for (let i = 0; i < holes.length; i++) { holeIndices.push(holeIndex); holeIndex += holes[i].length; addContour(vertices, holes[i]); - } // + } + + // + const triangles = Earcut.triangulate(vertices, holeIndices); - const triangles = Earcut.triangulate(vertices, holeIndices); // + // for (let i = 0; i < triangles.length; i += 3) { faces.push(triangles.slice(i, i + 3)); } - return faces; } - } - function removeDupEndPts(points) { const l = points.length; - if (l > 2 && points[l - 1].equals(points[0])) { points.pop(); } } - function addContour(vertices, contour) { for (let i = 0; i < contour.length; i++) { vertices.push(contour[i].x); @@ -25303,7 +22841,6 @@ function addContour(vertices, contour) { * * } */ - class ExtrudeGeometry extends BufferGeometry { constructor(shapes = new Shape([new Vector2(0.5, 0.5), new Vector2(-0.5, 0.5), new Vector2(-0.5, -0.5), new Vector2(0.5, -0.5)]), options = {}) { super(); @@ -25316,19 +22853,23 @@ class ExtrudeGeometry extends BufferGeometry { const scope = this; const verticesArray = []; const uvArray = []; - for (let i = 0, l = shapes.length; i < l; i++) { const shape = shapes[i]; addShape(shape); - } // build geometry + } + // build geometry this.setAttribute('position', new Float32BufferAttribute(verticesArray, 3)); this.setAttribute('uv', new Float32BufferAttribute(uvArray, 2)); - this.computeVertexNormals(); // functions + this.computeVertexNormals(); + + // functions function addShape(shape) { - const placeholder = []; // options + const placeholder = []; + + // options const curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12; const steps = options.steps !== undefined ? options.steps : 1; @@ -25339,53 +22880,60 @@ class ExtrudeGeometry extends BufferGeometry { let bevelOffset = options.bevelOffset !== undefined ? options.bevelOffset : 0; let bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3; const extrudePath = options.extrudePath; - const uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator; // + const uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator; + + // let extrudePts, - extrudeByPath = false; + extrudeByPath = false; let splineTube, binormal, normal, position2; - 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? - splineTube = extrudePath.computeFrenetFrames(steps, false); // console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length); + splineTube = extrudePath.computeFrenetFrames(steps, false); + + // console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length); binormal = new Vector3(); normal = new Vector3(); position2 = new Vector3(); - } // Safeguards if bevels are not enabled + } + // Safeguards if bevels are not enabled if (!bevelEnabled) { bevelSegments = 0; bevelThickness = 0; bevelSize = 0; bevelOffset = 0; - } // Variables initialization + } + // Variables initialization const shapePoints = shape.extractPoints(curveSegments); let vertices = shapePoints.shape; const holes = shapePoints.holes; const reverse = !ShapeUtils.isClockWise(vertices); - if (reverse) { - vertices = vertices.reverse(); // Maybe we should also check if holes are in the opposite direction, just to be safe ... + vertices = vertices.reverse(); + + // Maybe we should also check if holes are in the opposite direction, just to be safe ... for (let h = 0, hl = holes.length; h < hl; h++) { const ahole = holes[h]; - if (ShapeUtils.isClockWise(ahole)) { holes[h] = ahole.reverse(); } } } - const faces = ShapeUtils.triangulateShape(vertices, holes); + /* Vertices */ const contour = vertices; // vertices has all points but contour has only points of circumference @@ -25394,14 +22942,14 @@ class ExtrudeGeometry extends BufferGeometry { const ahole = holes[h]; vertices = vertices.concat(ahole); } - function scalePt2(pt, vec, size) { if (!vec) console.error('THREE.ExtrudeGeometry: vec does not exist'); return vec.clone().multiplyScalar(size).add(pt); } - const vlen = vertices.length, - flen = faces.length; // Find directions for point movement + flen = faces.length; + + // Find directions for point movement function getBevelVec(inPt, inPrev, inNext) { // computes for inPt the corresponding point inPt' on a new contour @@ -25410,37 +22958,47 @@ class ExtrudeGeometry extends BufferGeometry { // // 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. + let 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 const v_prev_x = inPt.x - inPrev.x, - v_prev_y = inPt.y - inPrev.y; + v_prev_y = inPt.y - inPrev.y; const v_next_x = inNext.x - inPt.x, - v_next_y = inNext.y - inPt.y; - const v_prev_lensq = v_prev_x * v_prev_x + v_prev_y * v_prev_y; // check for collinear edges + v_next_y = inNext.y - inPt.y; + const v_prev_lensq = v_prev_x * v_prev_x + v_prev_y * v_prev_y; + // check for collinear edges const collinear0 = v_prev_x * v_next_y - v_prev_y * v_next_x; - if (Math.abs(collinear0) > Number.EPSILON) { // not collinear + // length of vectors for normalizing + const v_prev_len = Math.sqrt(v_prev_lensq); - const 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 + const 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 const ptPrevShift_x = inPrev.x - v_prev_y / v_prev_len; const ptPrevShift_y = inPrev.y + v_prev_x / v_prev_len; const ptNextShift_x = inNext.x - v_next_y / v_next_len; - const ptNextShift_y = inNext.y + v_next_x / v_next_len; // scaling factor for v_prev to intersection point + const ptNextShift_y = inNext.y + v_next_x / v_next_len; + + // scaling factor for v_prev to intersection point + + const 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); - const 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 + // 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 + v_trans_y = ptPrevShift_y + v_prev_y * sf - inPt.y; + // Don't normalize!, otherwise sharp corners become ugly + // but prevent crazy spikes const v_trans_lensq = v_trans_x * v_trans_x + v_trans_y * v_trans_y; - if (v_trans_lensq <= 2) { return new Vector2(v_trans_x, v_trans_y); } else { @@ -25448,6 +23006,7 @@ class ExtrudeGeometry extends BufferGeometry { } } else { // handle special case of collinear edges + let direction_eq = false; // assumes: opposite if (v_prev_x > Number.EPSILON) { @@ -25465,7 +23024,6 @@ class ExtrudeGeometry extends BufferGeometry { } } } - if (direction_eq) { // console.log("Warning: lines are a straight sequence"); v_trans_x = -v_prev_y; @@ -25478,117 +23036,121 @@ class ExtrudeGeometry extends BufferGeometry { shrink_by = Math.sqrt(v_prev_lensq / 2); } } - return new Vector2(v_trans_x / shrink_by, v_trans_y / shrink_by); } - const contourMovements = []; - for (let 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) + if (k === il) k = 0; + + // (j)---(i)---(k) // console.log('i,j,k', i, j , k) contourMovements[i] = getBevelVec(contour[i], contour[j], contour[k]); } - const holesMovements = []; let oneHoleMovements, - verticesMovements = contourMovements.concat(); - + verticesMovements = contourMovements.concat(); for (let h = 0, hl = holes.length; h < hl; h++) { const ahole = holes[h]; oneHoleMovements = []; - for (let 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) + 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 + } + // Loop bevelSegments, 1 for the front, 1 for the back for (let b = 0; b < bevelSegments; b++) { //for ( b = bevelSegments; b > 0; b -- ) { + const t = b / bevelSegments; const z = bevelThickness * Math.cos(t * Math.PI / 2); - const bs = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset; // contract shape + const bs = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset; + + // contract shape for (let i = 0, il = contour.length; i < il; i++) { const vert = scalePt2(contour[i], contourMovements[i], bs); v(vert.x, vert.y, -z); - } // expand holes + } + // expand holes for (let h = 0, hl = holes.length; h < hl; h++) { const ahole = holes[h]; oneHoleMovements = holesMovements[h]; - for (let i = 0, il = ahole.length; i < il; i++) { const vert = scalePt2(ahole[i], oneHoleMovements[i], bs); v(vert.x, vert.y, -z); } } } + const bs = bevelSize + bevelOffset; - const bs = bevelSize + bevelOffset; // Back facing vertices + // Back facing vertices for (let i = 0; i < vlen; i++) { const 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 + } + // Add stepped vertices... + // Including front facing vertices for (let s = 1; s <= steps; s++) { for (let i = 0; i < vlen; i++) { const vert = bevelEnabled ? scalePt2(vertices[i], verticesMovements[i], bs) : vertices[i]; - if (!extrudeByPath) { v(vert.x, vert.y, depth / 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 ++ ) { + } + // Add bevel segments planes + //for ( b = 1; b <= bevelSegments; b ++ ) { for (let b = bevelSegments - 1; b >= 0; b--) { const t = b / bevelSegments; const z = bevelThickness * Math.cos(t * Math.PI / 2); - const bs = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset; // contract shape + const bs = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset; + + // contract shape for (let i = 0, il = contour.length; i < il; i++) { const vert = scalePt2(contour[i], contourMovements[i], bs); v(vert.x, vert.y, depth + z); - } // expand holes + } + // expand holes for (let h = 0, hl = holes.length; h < hl; h++) { const ahole = holes[h]; oneHoleMovements = holesMovements[h]; - for (let i = 0, il = ahole.length; i < il; i++) { const vert = scalePt2(ahole[i], oneHoleMovements[i], bs); - if (!extrudeByPath) { v(vert.x, vert.y, depth + z); } else { @@ -25597,29 +23159,35 @@ class ExtrudeGeometry extends BufferGeometry { } } } + /* Faces */ + // Top and bottom faces + buildLidFaces(); - buildLidFaces(); // Sides faces + // Sides faces - buildSideFaces(); ///// Internal functions + buildSideFaces(); + + ///// Internal functions function buildLidFaces() { const start = verticesArray.length / 3; - if (bevelEnabled) { let layer = 0; // steps + 1 + let offset = vlen * layer; - let offset = vlen * layer; // Bottom faces + // Bottom faces for (let i = 0; i < flen; i++) { const face = faces[i]; f3(face[2] + offset, face[1] + offset, face[0] + offset); } - layer = steps + bevelSegments * 2; - offset = vlen * layer; // Top faces + offset = vlen * layer; + + // Top faces for (let i = 0; i < flen; i++) { const face = faces[i]; @@ -25627,64 +23195,63 @@ class ExtrudeGeometry extends BufferGeometry { } } else { // Bottom faces + for (let i = 0; i < flen; i++) { const face = faces[i]; f3(face[2], face[1], face[0]); - } // Top faces + } + // Top faces for (let i = 0; i < flen; i++) { const face = faces[i]; f3(face[0] + vlen * steps, face[1] + vlen * steps, face[2] + vlen * steps); } } - scope.addGroup(start, verticesArray.length / 3 - start, 0); - } // Create faces for the z-sides of the shape + } + // Create faces for the z-sides of the shape function buildSideFaces() { const start = verticesArray.length / 3; let layeroffset = 0; sidewalls(contour, layeroffset); layeroffset += contour.length; - for (let h = 0, hl = holes.length; h < hl; h++) { const ahole = holes[h]; - sidewalls(ahole, layeroffset); //, true + sidewalls(ahole, layeroffset); + //, true layeroffset += ahole.length; } - scope.addGroup(start, verticesArray.length / 3 - start, 1); } - function sidewalls(contour, layeroffset) { let i = contour.length; - while (--i >= 0) { const j = i; let k = i - 1; - if (k < 0) k = contour.length - 1; //console.log('b', i,j, i-1, k,vertices.length); + if (k < 0) k = contour.length - 1; + + //console.log('b', i,j, i-1, k,vertices.length); for (let s = 0, sl = steps + bevelSegments * 2; s < sl; s++) { const slen1 = vlen * s; const slen2 = vlen * (s + 1); const a = layeroffset + j + slen1, - b = layeroffset + k + slen1, - c = layeroffset + k + slen2, - d = layeroffset + j + slen2; + b = layeroffset + k + slen1, + c = layeroffset + k + slen2, + d = layeroffset + j + slen2; f4(a, b, c, d); } } } - function v(x, y, z) { placeholder.push(x); placeholder.push(y); placeholder.push(z); } - function f3(a, b, c) { addVertex(a); addVertex(b); @@ -25695,7 +23262,6 @@ class ExtrudeGeometry extends BufferGeometry { addUV(uvs[1]); addUV(uvs[2]); } - function f4(a, b, c, d) { addVertex(a); addVertex(b); @@ -25712,46 +23278,36 @@ class ExtrudeGeometry extends BufferGeometry { 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); } } } - toJSON() { const data = super.toJSON(); const shapes = this.parameters.shapes; const options = this.parameters.options; return toJSON$1(shapes, options, data); } - static fromJSON(data, shapes) { const geometryShapes = []; - for (let j = 0, jl = data.shapes.length; j < jl; j++) { const shape = shapes[data.shapes[j]]; geometryShapes.push(shape); } - const extrudePath = data.options.extrudePath; - if (extrudePath !== undefined) { data.options.extrudePath = new Curves[extrudePath.type]().fromJSON(extrudePath); } - return new ExtrudeGeometry(geometryShapes, data.options); } - } - const WorldUVGenerator = { generateTopUV: function (geometry, vertices, indexA, indexB, indexC) { const a_x = vertices[indexA * 3]; @@ -25775,7 +23331,6 @@ const WorldUVGenerator = { const d_x = vertices[indexD * 3]; const d_y = vertices[indexD * 3 + 1]; const d_z = vertices[indexD * 3 + 2]; - if (Math.abs(a_y - b_y) < Math.abs(a_x - b_x)) { 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 { @@ -25783,10 +23338,8 @@ const WorldUVGenerator = { } } }; - function toJSON$1(shapes, options, data) { data.shapes = []; - if (Array.isArray(shapes)) { for (let i = 0, l = shapes.length; i < l; i++) { const shape = shapes[i]; @@ -25795,7 +23348,6 @@ function toJSON$1(shapes, options, data) { } else { data.shapes.push(shapes.uuid); } - data.options = Object.assign({}, options); if (options.extrudePath !== undefined) data.options.extrudePath = options.extrudePath.toJSON(); return data; @@ -25813,11 +23365,9 @@ class IcosahedronGeometry extends PolyhedronGeometry { detail: detail }; } - static fromJSON(data) { return new IcosahedronGeometry(data.radius, data.detail); } - } class OctahedronGeometry extends PolyhedronGeometry { @@ -25831,11 +23381,9 @@ class OctahedronGeometry extends PolyhedronGeometry { detail: detail }; } - static fromJSON(data) { return new OctahedronGeometry(data.radius, data.detail); } - } class RingGeometry extends BufferGeometry { @@ -25851,65 +23399,80 @@ class RingGeometry extends BufferGeometry { thetaLength: thetaLength }; thetaSegments = Math.max(3, thetaSegments); - phiSegments = Math.max(1, phiSegments); // buffers + phiSegments = Math.max(1, phiSegments); + + // buffers const indices = []; const vertices = []; const normals = []; - const uvs = []; // some helper variables + const uvs = []; + + // some helper variables let radius = innerRadius; const radiusStep = (outerRadius - innerRadius) / phiSegments; const vertex = new Vector3(); - const uv = new Vector2(); // generate vertices, normals and uvs + const uv = new Vector2(); + + // generate vertices, normals and uvs for (let j = 0; j <= phiSegments; j++) { for (let i = 0; i <= thetaSegments; i++) { // values are generate from the inside of the ring to the outside - const segment = thetaStart + i / thetaSegments * thetaLength; // vertex + + const segment = thetaStart + i / thetaSegments * thetaLength; + + // vertex vertex.x = radius * Math.cos(segment); vertex.y = radius * Math.sin(segment); - vertices.push(vertex.x, vertex.y, vertex.z); // normal + vertices.push(vertex.x, vertex.y, vertex.z); + + // normal + + normals.push(0, 0, 1); - normals.push(0, 0, 1); // uv + // uv 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 + } + // increase the radius for next row of vertices radius += radiusStep; - } // indices + } + // indices for (let j = 0; j < phiSegments; j++) { const thetaSegmentLevel = j * (thetaSegments + 1); - for (let i = 0; i < thetaSegments; i++) { const segment = i + thetaSegmentLevel; const a = segment; const b = segment + thetaSegments + 1; const c = segment + thetaSegments + 2; - const d = segment + 1; // faces + const d = segment + 1; + + // faces indices.push(a, b, d); indices.push(b, c, d); } - } // build geometry + } + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); } - static fromJSON(data) { return new RingGeometry(data.innerRadius, data.outerRadius, data.thetaSegments, data.phiSegments, data.thetaStart, data.thetaLength); } - } class ShapeGeometry extends BufferGeometry { @@ -25919,15 +23482,21 @@ class ShapeGeometry extends BufferGeometry { this.parameters = { shapes: shapes, curveSegments: curveSegments - }; // buffers + }; + + // buffers const indices = []; const vertices = []; const normals = []; - const uvs = []; // helper variables + const uvs = []; + + // helper variables let groupStart = 0; - let groupCount = 0; // allow single and array values for "shapes" parameter + let groupCount = 0; + + // allow single and array values for "shapes" parameter if (Array.isArray(shapes) === false) { addShape(shapes); @@ -25939,47 +23508,53 @@ class ShapeGeometry extends BufferGeometry { groupStart += groupCount; groupCount = 0; } - } // build geometry + } + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // helper functions + this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); + + // helper functions function addShape(shape) { const indexOffset = vertices.length / 3; const points = shape.extractPoints(curveSegments); let shapeVertices = points.shape; - const shapeHoles = points.holes; // check direction of vertices + const shapeHoles = points.holes; + + // check direction of vertices if (ShapeUtils.isClockWise(shapeVertices) === false) { shapeVertices = shapeVertices.reverse(); } - for (let i = 0, l = shapeHoles.length; i < l; i++) { const shapeHole = shapeHoles[i]; - if (ShapeUtils.isClockWise(shapeHole) === true) { shapeHoles[i] = shapeHole.reverse(); } } + const faces = ShapeUtils.triangulateShape(shapeVertices, shapeHoles); - const faces = ShapeUtils.triangulateShape(shapeVertices, shapeHoles); // join vertices of inner and outer paths to a single array + // join vertices of inner and outer paths to a single array for (let i = 0, l = shapeHoles.length; i < l; i++) { const shapeHole = shapeHoles[i]; shapeVertices = shapeVertices.concat(shapeHole); - } // vertices, normals, uvs + } + // vertices, normals, uvs for (let i = 0, l = shapeVertices.length; i < l; i++) { const vertex = shapeVertices[i]; vertices.push(vertex.x, vertex.y, 0); normals.push(0, 0, 1); uvs.push(vertex.x, vertex.y); // world uvs - } // incides + } + // indices for (let i = 0, l = faces.length; i < l; i++) { const face = faces[i]; @@ -25991,29 +23566,22 @@ class ShapeGeometry extends BufferGeometry { } } } - toJSON() { const data = super.toJSON(); const shapes = this.parameters.shapes; return toJSON(shapes, data); } - static fromJSON(data, shapes) { const geometryShapes = []; - for (let j = 0, jl = data.shapes.length; j < jl; j++) { const shape = shapes[data.shapes[j]]; geometryShapes.push(shape); } - return new ShapeGeometry(geometryShapes, data.curveSegments); } - } - function toJSON(shapes, data) { data.shapes = []; - if (Array.isArray(shapes)) { for (let i = 0, l = shapes.length; i < l; i++) { const shape = shapes[i]; @@ -26022,7 +23590,6 @@ function toJSON(shapes, data) { } else { data.shapes.push(shapes.uuid); } - return data; } @@ -26045,43 +23612,53 @@ class SphereGeometry extends BufferGeometry { let index = 0; const grid = []; const vertex = new Vector3(); - const normal = new Vector3(); // buffers + const normal = new Vector3(); + + // buffers const indices = []; const vertices = []; const normals = []; - const uvs = []; // generate vertices, normals and uvs + const uvs = []; + + // generate vertices, normals and uvs for (let iy = 0; iy <= heightSegments; iy++) { const verticesRow = []; - const v = iy / heightSegments; // special case for the poles + const v = iy / heightSegments; - let uOffset = 0; + // special case for the poles + let uOffset = 0; if (iy == 0 && thetaStart == 0) { uOffset = 0.5 / widthSegments; } else if (iy == heightSegments && thetaEnd == Math.PI) { uOffset = -0.5 / widthSegments; } - for (let ix = 0; ix <= widthSegments; ix++) { - const u = ix / widthSegments; // vertex + const u = ix / widthSegments; + + // vertex 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 + vertices.push(vertex.x, vertex.y, vertex.z); + + // normal normal.copy(vertex).normalize(); - normals.push(normal.x, normal.y, normal.z); // uv + normals.push(normal.x, normal.y, normal.z); + + // uv uvs.push(u + uOffset, 1 - v); verticesRow.push(index++); } - grid.push(verticesRow); - } // indices + } + // indices for (let iy = 0; iy < heightSegments; iy++) { for (let ix = 0; ix < widthSegments; ix++) { @@ -26092,19 +23669,18 @@ class SphereGeometry extends BufferGeometry { if (iy !== 0 || thetaStart > 0) indices.push(a, b, d); if (iy !== heightSegments - 1 || thetaEnd < Math.PI) indices.push(b, c, d); } - } // build geometry + } + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); } - static fromJSON(data) { return new SphereGeometry(data.radius, data.widthSegments, data.heightSegments, data.phiStart, data.phiLength, data.thetaStart, data.thetaLength); } - } class TetrahedronGeometry extends PolyhedronGeometry { @@ -26118,11 +23694,9 @@ class TetrahedronGeometry extends PolyhedronGeometry { detail: detail }; } - static fromJSON(data) { return new TetrahedronGeometry(data.radius, data.detail); } - } class TorusGeometry extends BufferGeometry { @@ -26137,62 +23711,77 @@ class TorusGeometry extends BufferGeometry { arc: arc }; radialSegments = Math.floor(radialSegments); - tubularSegments = Math.floor(tubularSegments); // buffers + tubularSegments = Math.floor(tubularSegments); + + // buffers const indices = []; const vertices = []; const normals = []; - const uvs = []; // helper variables + const uvs = []; + + // helper variables const center = new Vector3(); const vertex = new Vector3(); - const normal = new Vector3(); // generate vertices, normals and uvs + const normal = new Vector3(); + + // generate vertices, normals and uvs for (let j = 0; j <= radialSegments; j++) { for (let i = 0; i <= tubularSegments; i++) { const u = i / tubularSegments * arc; - const v = j / radialSegments * Math.PI * 2; // vertex + const 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 + 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 + normals.push(normal.x, normal.y, normal.z); + + // uv uvs.push(i / tubularSegments); uvs.push(j / radialSegments); } - } // generate indices + } + // generate indices for (let j = 1; j <= radialSegments; j++) { for (let i = 1; i <= tubularSegments; i++) { // indices + const a = (tubularSegments + 1) * j + i - 1; const b = (tubularSegments + 1) * (j - 1) + i - 1; const c = (tubularSegments + 1) * (j - 1) + i; - const d = (tubularSegments + 1) * j + i; // faces + const d = (tubularSegments + 1) * j + i; + + // faces indices.push(a, b, d); indices.push(b, c, d); } - } // build geometry + } + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); } - static fromJSON(data) { return new TorusGeometry(data.radius, data.tube, data.radialSegments, data.tubularSegments, data.arc); } - } class TorusKnotGeometry extends BufferGeometry { @@ -26208,12 +23797,16 @@ class TorusKnotGeometry extends BufferGeometry { q: q }; tubularSegments = Math.floor(tubularSegments); - radialSegments = Math.floor(radialSegments); // buffers + radialSegments = Math.floor(radialSegments); + + // buffers const indices = []; const vertices = []; const normals = []; - const uvs = []; // helper variables + const uvs = []; + + // helper variables const vertex = new Vector3(); const normal = new Vector3(); @@ -26221,64 +23814,86 @@ class TorusKnotGeometry extends BufferGeometry { const P2 = new Vector3(); const B = new Vector3(); const T = new Vector3(); - const N = new Vector3(); // generate vertices, normals and uvs + const N = new Vector3(); + + // generate vertices, normals and uvs for (let i = 0; i <= tubularSegments; ++i) { // the radian "u" is used to calculate the position on the torus curve of the current tubular segment - const 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. + + const 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 + 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 + N.crossVectors(B, T); + + // normalize B, N. T can be ignored, we don't use it B.normalize(); N.normalize(); - for (let 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. + const v = j / radialSegments * Math.PI * 2; const cx = -tube * Math.cos(v); - const cy = tube * Math.sin(v); // now calculate the final vertex position. + const cy = tube * Math.sin(v); + + // now calculate the final vertex position. // first we orient the extrusion with our basis vectors, 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) + 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 + normals.push(normal.x, normal.y, normal.z); + + // uv uvs.push(i / tubularSegments); uvs.push(j / radialSegments); } - } // generate indices + } + // generate indices for (let j = 1; j <= tubularSegments; j++) { for (let i = 1; i <= radialSegments; i++) { // indices + const a = (radialSegments + 1) * (j - 1) + (i - 1); const b = (radialSegments + 1) * j + (i - 1); const c = (radialSegments + 1) * j + i; - const d = (radialSegments + 1) * (j - 1) + i; // faces + const d = (radialSegments + 1) * (j - 1) + i; + + // faces indices.push(a, b, d); indices.push(b, c, d); } - } // build geometry + } + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // this function calculates the current position on the torus curve + this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); + + // this function calculates the current position on the torus curve function calculatePositionOnCurve(u, p, q, radius, position) { const cu = Math.cos(u); @@ -26290,11 +23905,9 @@ class TorusKnotGeometry extends BufferGeometry { position.z = radius * Math.sin(quOverP) * 0.5; } } - static fromJSON(data) { return new TorusKnotGeometry(data.radius, data.tube, data.tubularSegments, data.radialSegments, data.p, data.q); } - } class TubeGeometry extends BufferGeometry { @@ -26308,63 +23921,88 @@ class TubeGeometry extends BufferGeometry { radialSegments: radialSegments, closed: closed }; - const frames = path.computeFrenetFrames(tubularSegments, closed); // expose internals + const frames = path.computeFrenetFrames(tubularSegments, closed); + + // expose internals this.tangents = frames.tangents; this.normals = frames.normals; - this.binormals = frames.binormals; // helper variables + this.binormals = frames.binormals; + + // helper variables const vertex = new Vector3(); const normal = new Vector3(); const uv = new Vector2(); - let P = new Vector3(); // buffer + let P = new Vector3(); + + // buffer const vertices = []; const normals = []; const uvs = []; - const indices = []; // create buffer data + const indices = []; + + // create buffer data + + generateBufferData(); - generateBufferData(); // build geometry + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // functions + this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); + + // functions function generateBufferData() { for (let i = 0; i < tubularSegments; i++) { generateSegment(i); - } // if the geometry is not closed, generate the last row of vertices and normals + } + + // 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) + generateSegment(closed === false ? tubularSegments : 0); - generateSegment(closed === false ? tubularSegments : 0); // uvs are generated in a separate function. + // uvs are generated in a separate function. // this makes it easy compute correct values for closed geometries - generateUVs(); // finally create faces + generateUVs(); + + // finally create faces generateIndices(); } - 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 + + P = path.getPointAt(i / tubularSegments, P); + + // retrieve corresponding normal and binormal const N = frames.normals[i]; - const B = frames.binormals[i]; // generate normals and vertices for the current segment + const B = frames.binormals[i]; + + // generate normals and vertices for the current segment for (let j = 0; j <= radialSegments; j++) { const v = j / radialSegments * Math.PI * 2; const sin = Math.sin(v); - const cos = -Math.cos(v); // normal + const cos = -Math.cos(v); + + // normal 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 + normals.push(normal.x, normal.y, normal.z); + + // vertex vertex.x = P.x + radius * normal.x; vertex.y = P.y + radius * normal.y; @@ -26372,21 +24010,21 @@ class TubeGeometry extends BufferGeometry { vertices.push(vertex.x, vertex.y, vertex.z); } } - function generateIndices() { for (let j = 1; j <= tubularSegments; j++) { for (let i = 1; i <= radialSegments; i++) { const a = (radialSegments + 1) * (j - 1) + (i - 1); const b = (radialSegments + 1) * j + (i - 1); const c = (radialSegments + 1) * j + i; - const d = (radialSegments + 1) * (j - 1) + i; // faces + const d = (radialSegments + 1) * (j - 1) + i; + + // faces indices.push(a, b, d); indices.push(b, c, d); } } } - function generateUVs() { for (let i = 0; i <= tubularSegments; i++) { for (let j = 0; j <= radialSegments; j++) { @@ -26397,19 +24035,16 @@ class TubeGeometry extends BufferGeometry { } } } - toJSON() { const data = super.toJSON(); data.path = this.parameters.path.toJSON(); return data; } - static fromJSON(data) { // This only works for built-in curves (e.g. CatmullRomCurve3). // User defined curves or instances of CurvePath will not be deserialized. return new TubeGeometry(new Curves[data.path.type]().fromJSON(data.path), data.tubularSegments, data.radius, data.radialSegments, data.closed); } - } class WireframeGeometry extends BufferGeometry { @@ -26419,42 +24054,42 @@ class WireframeGeometry extends BufferGeometry { this.parameters = { geometry: geometry }; - if (geometry !== null) { // buffer + const vertices = []; - const edges = new Set(); // helper variables + const edges = new Set(); + + // helper variables const start = new Vector3(); const end = new Vector3(); - if (geometry.index !== null) { // indexed BufferGeometry + const position = geometry.attributes.position; const indices = geometry.index; let groups = geometry.groups; - if (groups.length === 0) { groups = [{ start: 0, count: indices.count, materialIndex: 0 }]; - } // create a data structure that contains all edges without duplicates + } + // create a data structure that contains all edges without duplicates for (let o = 0, ol = groups.length; o < ol; ++o) { const group = groups[o]; const groupStart = group.start; const groupCount = group.count; - for (let i = groupStart, l = groupStart + groupCount; i < l; i += 3) { for (let j = 0; j < 3; j++) { const index1 = indices.getX(i + j); const index2 = indices.getX(i + (j + 1) % 3); start.fromBufferAttribute(position, index1); end.fromBufferAttribute(position, index2); - if (isUniqueEdge(start, end, edges) === true) { vertices.push(start.x, start.y, start.z); vertices.push(end.x, end.y, end.z); @@ -26464,32 +24099,31 @@ class WireframeGeometry extends BufferGeometry { } } else { // non-indexed BufferGeometry - const position = geometry.attributes.position; + const position = geometry.attributes.position; for (let i = 0, l = position.count / 3; i < l; i++) { for (let j = 0; j < 3; j++) { // 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) + const index1 = 3 * i + j; const index2 = 3 * i + (j + 1) % 3; start.fromBufferAttribute(position, index1); end.fromBufferAttribute(position, index2); - if (isUniqueEdge(start, end, edges) === true) { vertices.push(start.x, start.y, start.z); vertices.push(end.x, end.y, end.z); } } } - } // build geometry + } + // build geometry this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); } } - } - function isUniqueEdge(start, end, edges) { const hash1 = `${start.x},${start.y},${start.z}-${end.x},${end.y},${end.z}`; const hash2 = `${end.x},${end.y},${end.z}-${start.x},${start.y},${start.z}`; // coincident edge @@ -26506,44 +24140,25 @@ function isUniqueEdge(start, end, edges) { var Geometries = /*#__PURE__*/Object.freeze({ __proto__: null, BoxGeometry: BoxGeometry, - BoxBufferGeometry: BoxGeometry, CapsuleGeometry: CapsuleGeometry, - CapsuleBufferGeometry: CapsuleGeometry, CircleGeometry: CircleGeometry, - CircleBufferGeometry: CircleGeometry, ConeGeometry: ConeGeometry, - ConeBufferGeometry: ConeGeometry, CylinderGeometry: CylinderGeometry, - CylinderBufferGeometry: CylinderGeometry, DodecahedronGeometry: DodecahedronGeometry, - DodecahedronBufferGeometry: DodecahedronGeometry, EdgesGeometry: EdgesGeometry, ExtrudeGeometry: ExtrudeGeometry, - ExtrudeBufferGeometry: ExtrudeGeometry, IcosahedronGeometry: IcosahedronGeometry, - IcosahedronBufferGeometry: IcosahedronGeometry, LatheGeometry: LatheGeometry, - LatheBufferGeometry: LatheGeometry, OctahedronGeometry: OctahedronGeometry, - OctahedronBufferGeometry: OctahedronGeometry, PlaneGeometry: PlaneGeometry, - PlaneBufferGeometry: PlaneGeometry, PolyhedronGeometry: PolyhedronGeometry, - PolyhedronBufferGeometry: PolyhedronGeometry, RingGeometry: RingGeometry, - RingBufferGeometry: RingGeometry, ShapeGeometry: ShapeGeometry, - ShapeBufferGeometry: ShapeGeometry, SphereGeometry: SphereGeometry, - SphereBufferGeometry: SphereGeometry, TetrahedronGeometry: TetrahedronGeometry, - TetrahedronBufferGeometry: TetrahedronGeometry, TorusGeometry: TorusGeometry, - TorusBufferGeometry: TorusGeometry, TorusKnotGeometry: TorusKnotGeometry, - TorusKnotBufferGeometry: TorusKnotGeometry, TubeGeometry: TubeGeometry, - TubeBufferGeometry: TubeGeometry, WireframeGeometry: WireframeGeometry }); @@ -26557,14 +24172,12 @@ class ShadowMaterial extends Material { this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.color.copy(source.color); this.fog = source.fog; return this; } - } class RawShaderMaterial extends ShaderMaterial { @@ -26573,7 +24186,6 @@ class RawShaderMaterial extends ShaderMaterial { this.isRawShaderMaterial = true; this.type = 'RawShaderMaterial'; } - } class MeshStandardMaterial extends Material { @@ -26585,7 +24197,6 @@ class MeshStandardMaterial extends Material { }; this.type = 'MeshStandardMaterial'; this.color = new Color(0xffffff); // diffuse - this.roughness = 1.0; this.metalness = 0.0; this.map = null; @@ -26617,7 +24228,6 @@ class MeshStandardMaterial extends Material { this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.defines = { @@ -26655,7 +24265,6 @@ class MeshStandardMaterial extends Material { this.fog = source.fog; return this; } - } class MeshPhysicalMaterial extends MeshStandardMaterial { @@ -26692,7 +24301,7 @@ class MeshPhysicalMaterial extends MeshStandardMaterial { this.transmissionMap = null; this.thickness = 0; this.thicknessMap = null; - this.attenuationDistance = 0.0; + this.attenuationDistance = Infinity; this.attenuationColor = new Color(1, 1, 1); this.specularIntensity = 1.0; this.specularIntensityMap = null; @@ -26704,55 +24313,42 @@ class MeshPhysicalMaterial extends MeshStandardMaterial { this._transmission = 0; this.setValues(parameters); } - get sheen() { return this._sheen; } - set sheen(value) { if (this._sheen > 0 !== value > 0) { this.version++; } - this._sheen = value; } - get clearcoat() { return this._clearcoat; } - set clearcoat(value) { if (this._clearcoat > 0 !== value > 0) { this.version++; } - this._clearcoat = value; } - get iridescence() { return this._iridescence; } - set iridescence(value) { if (this._iridescence > 0 !== value > 0) { this.version++; } - this._iridescence = value; } - get transmission() { return this._transmission; } - set transmission(value) { if (this._transmission > 0 !== value > 0) { this.version++; } - this._transmission = value; } - copy(source) { super.copy(source); this.defines = { @@ -26788,7 +24384,6 @@ class MeshPhysicalMaterial extends MeshStandardMaterial { this.specularColorMap = source.specularColorMap; return this; } - } class MeshPhongMaterial extends Material { @@ -26797,7 +24392,6 @@ class MeshPhongMaterial extends Material { this.isMeshPhongMaterial = true; this.type = 'MeshPhongMaterial'; this.color = new Color(0xffffff); // diffuse - this.specular = new Color(0x111111); this.shininess = 30; this.map = null; @@ -26830,7 +24424,6 @@ class MeshPhongMaterial extends Material { this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.color.copy(source.color); @@ -26866,7 +24459,6 @@ class MeshPhongMaterial extends Material { this.fog = source.fog; return this; } - } class MeshToonMaterial extends Material { @@ -26903,7 +24495,6 @@ class MeshToonMaterial extends Material { this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.color.copy(source.color); @@ -26932,7 +24523,6 @@ class MeshToonMaterial extends Material { this.fog = source.fog; return this; } - } class MeshNormalMaterial extends Material { @@ -26953,7 +24543,6 @@ class MeshNormalMaterial extends Material { this.flatShading = false; this.setValues(parameters); } - copy(source) { super.copy(source); this.bumpMap = source.bumpMap; @@ -26969,7 +24558,6 @@ class MeshNormalMaterial extends Material { this.flatShading = source.flatShading; return this; } - } class MeshLambertMaterial extends Material { @@ -26987,6 +24575,14 @@ class MeshLambertMaterial extends Material { 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; @@ -26997,10 +24593,10 @@ class MeshLambertMaterial extends Material { this.wireframeLinewidth = 1; this.wireframeLinecap = 'round'; this.wireframeLinejoin = 'round'; + this.flatShading = false; this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.color.copy(source.color); @@ -27012,6 +24608,14 @@ class MeshLambertMaterial extends Material { 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; @@ -27022,10 +24626,10 @@ class MeshLambertMaterial extends Material { this.wireframeLinewidth = source.wireframeLinewidth; this.wireframeLinecap = source.wireframeLinecap; this.wireframeLinejoin = source.wireframeLinejoin; + this.flatShading = source.flatShading; this.fog = source.fog; return this; } - } class MeshMatcapMaterial extends Material { @@ -27053,7 +24657,6 @@ class MeshMatcapMaterial extends Material { this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.defines = { @@ -27075,7 +24678,6 @@ class MeshMatcapMaterial extends Material { this.fog = source.fog; return this; } - } class LineDashedMaterial extends LineBasicMaterial { @@ -27088,7 +24690,6 @@ class LineDashedMaterial extends LineBasicMaterial { this.gapSize = 1; this.setValues(parameters); } - copy(source) { super.copy(source); this.scale = source.scale; @@ -27096,24 +24697,23 @@ class LineDashedMaterial extends LineBasicMaterial { this.gapSize = source.gapSize; return this; } - } +// same as Array.prototype.slice, but also works on typed arrays function arraySlice(array, from, to) { if (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 - +} +// converts an array to a specific type function convertArray(array, type, forceClone) { - if (!array || // let 'undefined' and 'null' pass + if (!array || + // let 'undefined' and 'null' pass !forceClone && array.constructor === type) return array; - if (typeof type.BYTES_PER_ELEMENT === 'number') { return new type(array); // create typed array } @@ -27123,48 +24723,40 @@ function convertArray(array, type, forceClone) { function isTypedArray(object) { return ArrayBuffer.isView(object) && !(object instanceof DataView); -} // returns an array by which times and values can be sorted - +} +// returns an array by which times and values can be sorted function getKeyframeOrder(times) { function compareTime(i, j) { return times[i] - times[j]; } - const n = times.length; const result = new Array(n); - for (let i = 0; i !== n; ++i) result[i] = i; - result.sort(compareTime); return result; -} // uses the array previously returned by 'getKeyframeOrder' to sort data - +} +// uses the array previously returned by 'getKeyframeOrder' to sort data function sortedArray(values, stride, order) { const nValues = values.length; const result = new values.constructor(nValues); - for (let i = 0, dstOffset = 0; dstOffset !== nValues; ++i) { const srcOffset = order[i] * stride; - for (let j = 0; j !== stride; ++j) { result[dstOffset++] = values[srcOffset + j]; } } - return result; -} // function for parsing AOS keyframe formats - +} +// function for parsing AOS keyframe formats function flattenJSON(jsonKeys, times, values, valuePropertyName) { let i = 1, - key = jsonKeys[0]; - + key = jsonKeys[0]; while (key !== undefined && key[valuePropertyName] === undefined) { key = jsonKeys[i++]; } - if (key === undefined) return; // no data let value = key[valuePropertyName]; @@ -27173,7 +24765,6 @@ function flattenJSON(jsonKeys, times, values, valuePropertyName) { if (Array.isArray(value)) { do { value = key[valuePropertyName]; - if (value !== undefined) { times.push(key.time); values.push.apply(values, value); // push all elements @@ -27183,109 +24774,101 @@ function flattenJSON(jsonKeys, times, values, valuePropertyName) { } while (key !== undefined); } else if (value.toArray !== undefined) { // ...assume THREE.Math-ish + do { value = key[valuePropertyName]; - if (value !== undefined) { times.push(key.time); value.toArray(values, values.length); } - key = jsonKeys[i++]; } while (key !== undefined); } else { // otherwise push as-is + do { value = key[valuePropertyName]; - if (value !== undefined) { times.push(key.time); values.push(value); } - key = jsonKeys[i++]; } while (key !== undefined); } } - function subclip(sourceClip, name, startFrame, endFrame, fps = 30) { const clip = sourceClip.clone(); clip.name = name; const tracks = []; - for (let i = 0; i < clip.tracks.length; ++i) { const track = clip.tracks[i]; const valueSize = track.getValueSize(); const times = []; const values = []; - for (let j = 0; j < track.times.length; ++j) { const frame = track.times[j] * fps; if (frame < startFrame || frame >= endFrame) continue; times.push(track.times[j]); - for (let k = 0; k < valueSize; ++k) { values.push(track.values[j * valueSize + k]); } } - if (times.length === 0) continue; track.times = convertArray(times, track.times.constructor); track.values = convertArray(values, track.values.constructor); tracks.push(track); } + clip.tracks = tracks; - clip.tracks = tracks; // find minimum .times value across all tracks in the trimmed clip + // find minimum .times value across all tracks in the trimmed clip let minStartTime = Infinity; - for (let 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 + } + // shift all tracks such that clip begins at t=0 for (let i = 0; i < clip.tracks.length; ++i) { clip.tracks[i].shift(-1 * minStartTime); } - clip.resetDuration(); return clip; } - function makeClipAdditive(targetClip, referenceFrame = 0, referenceClip = targetClip, fps = 30) { if (fps <= 0) fps = 30; const numTracks = referenceClip.tracks.length; - const referenceTime = referenceFrame / fps; // Make each track's values relative to the values at the reference frame + const referenceTime = referenceFrame / fps; + // Make each track's values relative to the values at the reference frame for (let i = 0; i < numTracks; ++i) { const referenceTrack = referenceClip.tracks[i]; - const referenceTrackType = referenceTrack.ValueTypeName; // Skip this track if it's non-numeric + const referenceTrackType = referenceTrack.ValueTypeName; - if (referenceTrackType === 'bool' || referenceTrackType === 'string') continue; // Find the track in the target clip whose name and type matches the reference track + // Skip this track if it's non-numeric + if (referenceTrackType === 'bool' || referenceTrackType === 'string') continue; + // Find the track in the target clip whose name and type matches the reference track const targetTrack = targetClip.tracks.find(function (track) { return track.name === referenceTrack.name && track.ValueTypeName === referenceTrackType; }); if (targetTrack === undefined) continue; let referenceOffset = 0; const referenceValueSize = referenceTrack.getValueSize(); - if (referenceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) { referenceOffset = referenceValueSize / 3; } - let targetOffset = 0; const targetValueSize = targetTrack.getValueSize(); - if (targetTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) { targetOffset = targetValueSize / 3; } - const lastIndex = referenceTrack.times.length - 1; - let referenceValue; // Find the value to subtract out of the track + let referenceValue; + // Find the value to subtract out of the track if (referenceTime <= referenceTrack.times[0]) { // Reference frame is earlier than the first keyframe, so just use the first keyframe const startIndex = referenceOffset; @@ -27303,33 +24886,32 @@ function makeClipAdditive(targetClip, referenceFrame = 0, referenceClip = target const endIndex = referenceValueSize - referenceOffset; interpolant.evaluate(referenceTime); referenceValue = arraySlice(interpolant.resultBuffer, startIndex, endIndex); - } // Conjugate the quaternion - + } + // Conjugate the quaternion if (referenceTrackType === 'quaternion') { const referenceQuat = new Quaternion().fromArray(referenceValue).normalize().conjugate(); referenceQuat.toArray(referenceValue); - } // Subtract the reference value from all of the track values + } + // Subtract the reference value from all of the track values const numTimes = targetTrack.times.length; - for (let j = 0; j < numTimes; ++j) { const valueStart = j * targetValueSize + targetOffset; - if (referenceTrackType === 'quaternion') { // Multiply the conjugate for quaternion track types Quaternion.multiplyQuaternionsFlat(targetTrack.values, valueStart, referenceValue, 0, targetTrack.values, valueStart); } else { - const valueEnd = targetValueSize - targetOffset * 2; // Subtract each value for all other numeric track types + const valueEnd = targetValueSize - targetOffset * 2; + // Subtract each value for all other numeric track types for (let k = 0; k < valueEnd; ++k) { targetTrack.values[valueStart + k] -= referenceValue[k]; } } } } - targetClip.blendMode = AdditiveAnimationBlendMode; return targetClip; } @@ -27366,6 +24948,7 @@ var AnimationUtils = /*#__PURE__*/Object.freeze({ * http://www.oodesign.com/template-method-pattern.html * */ + class Interpolant { constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { this.parameterPositions = parameterPositions; @@ -27376,17 +24959,14 @@ class Interpolant { this.settings = null; this.DefaultSettings_ = {}; } - evaluate(t) { const pp = this.parameterPositions; let i1 = this._cachedIndex, - t1 = pp[i1], - t0 = pp[i1 - 1]; - + t1 = pp[i1], + t0 = pp[i1 - 1]; validate_interval: { seek: { let right; - linear_scan: { //- See http://jsperf.com/comparison-to-undefined/3 //- slower code: @@ -27395,90 +24975,89 @@ class Interpolant { forward_scan: if (!(t < t1)) { for (let giveUpAt = i1 + 2;;) { if (t1 === undefined) { - if (t < t0) break forward_scan; // after end + if (t < t0) break forward_scan; + + // after end i1 = pp.length; this._cachedIndex = i1; return this.copySampleValue_(i1 - 1); } - if (i1 === giveUpAt) break; // this loop t0 = t1; t1 = pp[++i1]; - if (t < t1) { // we have arrived at the sought interval break seek; } - } // prepare binary search on the right side of the index - + } + // prepare binary search on the right side of the index right = pp.length; break linear_scan; - } //- slower code: - //- if ( t < t0 || t0 === undefined ) { - + } + //- slower code: + //- if ( t < t0 || t0 === undefined ) { if (!(t >= t0)) { // looping? - const t1global = pp[1]; + const t1global = pp[1]; if (t < t1global) { i1 = 2; // + 1, using the scan for the details - t0 = t1global; - } // linear reverse scan + } + // linear reverse scan for (let giveUpAt = i1 - 2;;) { if (t0 === undefined) { // before start + this._cachedIndex = 0; return this.copySampleValue_(0); } - if (i1 === giveUpAt) break; // this loop t1 = t0; t0 = pp[--i1 - 1]; - if (t >= t0) { // we have arrived at the sought interval break seek; } - } // prepare binary search on the left side of the index - + } + // prepare binary search on the left side of the index right = i1; i1 = 0; break linear_scan; - } // the interval is valid + } + // the interval is valid break validate_interval; } // linear scan - // binary search + // binary search while (i1 < right) { const mid = i1 + right >>> 1; - if (t < pp[mid]) { right = mid; } else { i1 = mid + 1; } } - t1 = pp[i1]; - t0 = pp[i1 - 1]; // check boundary cases, again + t0 = pp[i1 - 1]; + + // check boundary cases, again if (t0 === undefined) { this._cachedIndex = 0; return this.copySampleValue_(0); } - if (t1 === undefined) { i1 = pp.length; this._cachedIndex = i1; @@ -27486,41 +25065,39 @@ class Interpolant { } } // seek - this._cachedIndex = i1; this.intervalChanged_(i1, t0, t1); } // validate_interval - return this.interpolate_(i1, t0, t, t1); } - getSettings_() { return this.settings || this.DefaultSettings_; } - copySampleValue_(index) { // copies a sample value to the result buffer - const result = this.resultBuffer, - values = this.sampleValues, - stride = this.valueSize, - offset = index * stride; + const result = this.resultBuffer, + values = this.sampleValues, + stride = this.valueSize, + offset = index * stride; for (let i = 0; i !== stride; ++i) { result[i] = values[offset + i]; } - return result; - } // Template methods for derived classes: + } + // Template methods for derived classes: interpolate_() { - throw new Error('call to abstract method'); // implementations shall return this.resultBuffer + throw new Error('call to abstract method'); + // implementations shall return this.resultBuffer } - intervalChanged_() {// empty - } + intervalChanged_() { + // empty + } } /** @@ -27543,14 +25120,12 @@ class CubicInterpolant extends Interpolant { endingEnd: ZeroCurvatureEnding }; } - intervalChanged_(i1, t0, t1) { const pp = this.parameterPositions; let iPrev = i1 - 2, - iNext = i1 + 1, - tPrev = pp[iPrev], - tNext = pp[iNext]; - + iNext = i1 + 1, + tPrev = pp[iPrev], + tNext = pp[iNext]; if (tPrev === undefined) { switch (this.getSettings_().endingStart) { case ZeroSlopeEnding: @@ -27558,21 +25133,19 @@ class CubicInterpolant extends Interpolant { iPrev = i1; tPrev = 2 * t0 - t1; break; - case WrapAroundEnding: // use the other end of the curve iPrev = pp.length - 2; tPrev = t0 + pp[iPrev] - pp[iPrev + 1]; break; - default: // ZeroCurvatureEnding + // f''(t0) = 0 a.k.a. Natural Spline iPrev = i1; tPrev = t1; } } - if (tNext === undefined) { switch (this.getSettings_().endingEnd) { case ZeroSlopeEnding: @@ -27580,78 +25153,73 @@ class CubicInterpolant extends Interpolant { 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; - default: // ZeroCurvatureEnding + // f''(tN) = 0, a.k.a. Natural Spline iNext = i1 - 1; tNext = t0; } } - const halfDt = (t1 - t0) * 0.5, - stride = this.valueSize; + stride = this.valueSize; this._weightPrev = halfDt / (t0 - tPrev); this._weightNext = halfDt / (tNext - t1); this._offsetPrev = iPrev * stride; this._offsetNext = iNext * stride; } - interpolate_(i1, t0, t, t1) { const 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 + 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 const sP = -wP * ppp + 2 * wP * pp - wP * p; const s0 = (1 + wP) * ppp + (-1.5 - 2 * wP) * pp + (-0.5 + wP) * p + 1; const s1 = (-1 - wN) * ppp + (1.5 + wN) * pp + 0.5 * p; - const sN = wN * ppp - wN * pp; // combine data linearly + const sN = wN * ppp - wN * pp; + + // combine data linearly for (let i = 0; i !== stride; ++i) { result[i] = sP * values[oP + i] + s0 * values[o0 + i] + s1 * values[o1 + i] + sN * values[oN + i]; } - return result; } - } class LinearInterpolant extends Interpolant { constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { super(parameterPositions, sampleValues, sampleSize, resultBuffer); } - interpolate_(i1, t0, t, t1) { const result = this.resultBuffer, - values = this.sampleValues, - stride = this.valueSize, - offset1 = i1 * stride, - offset0 = offset1 - stride, - weight1 = (t - t0) / (t1 - t0), - weight0 = 1 - weight1; - + values = this.sampleValues, + stride = this.valueSize, + offset1 = i1 * stride, + offset0 = offset1 - stride, + weight1 = (t - t0) / (t1 - t0), + weight0 = 1 - weight1; for (let i = 0; i !== stride; ++i) { result[i] = values[offset0 + i] * weight0 + values[offset1 + i] * weight1; } - return result; } - } /** @@ -27664,13 +25232,9 @@ class DiscreteInterpolant extends Interpolant { constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { super(parameterPositions, sampleValues, sampleSize, resultBuffer); } - - interpolate_(i1 - /*, t0, t, t1 */ - ) { + interpolate_(i1 /*, t0, t, t1 */) { return this.copySampleValue_(i1 - 1); } - } class KeyframeTrack { @@ -27681,14 +25245,16 @@ class KeyframeTrack { this.times = convertArray(times, this.TimeBufferType); this.values = convertArray(values, this.ValueBufferType); this.setInterpolation(interpolation || this.DefaultInterpolation); - } // Serialization (in static context, because of constructor invocation - // and automatic invocation of .toJSON): + } + // Serialization (in static context, because of constructor invocation + // and automatic invocation of .toJSON): static toJSON(track) { const trackType = track.constructor; - let json; // derived classes can define a static toJSON method + let json; + // derived classes can define a static toJSON method if (trackType.toJSON !== this.toJSON) { json = trackType.toJSON(track); } else { @@ -27699,49 +25265,38 @@ class KeyframeTrack { 'values': convertArray(track.values, Array) }; const interpolation = track.getInterpolation(); - if (interpolation !== track.DefaultInterpolation) { json.interpolation = interpolation; } } - json.type = track.ValueTypeName; // mandatory return json; } - InterpolantFactoryMethodDiscrete(result) { return new DiscreteInterpolant(this.times, this.values, this.getValueSize(), result); } - InterpolantFactoryMethodLinear(result) { return new LinearInterpolant(this.times, this.values, this.getValueSize(), result); } - InterpolantFactoryMethodSmooth(result) { return new CubicInterpolant(this.times, this.values, this.getValueSize(), result); } - setInterpolation(interpolation) { let factoryMethod; - switch (interpolation) { case InterpolateDiscrete: factoryMethod = this.InterpolantFactoryMethodDiscrete; break; - case InterpolateLinear: factoryMethod = this.InterpolantFactoryMethodLinear; break; - case InterpolateSmooth: factoryMethod = this.InterpolantFactoryMethodSmooth; break; } - if (factoryMethod === undefined) { const message = 'unsupported interpolation for ' + this.ValueTypeName + ' keyframe track named ' + this.name; - if (this.createInterpolant === undefined) { // fall back to default, unless the default itself is messed up if (interpolation !== this.DefaultInterpolation) { @@ -27754,70 +25309,58 @@ class KeyframeTrack { console.warn('THREE.KeyframeTrack:', message); return this; } - this.createInterpolant = factoryMethod; return this; } - getInterpolation() { switch (this.createInterpolant) { case this.InterpolantFactoryMethodDiscrete: return InterpolateDiscrete; - case this.InterpolantFactoryMethodLinear: return InterpolateLinear; - case this.InterpolantFactoryMethodSmooth: return InterpolateSmooth; } } - getValueSize() { return this.values.length / this.times.length; - } // move all keyframes either forwards or backwards in time - + } + // move all keyframes either forwards or backwards in time shift(timeOffset) { if (timeOffset !== 0.0) { const times = this.times; - for (let i = 0, n = times.length; i !== n; ++i) { times[i] += timeOffset; } } - return this; - } // scale all keyframe times by a factor (useful for frame <-> seconds conversions) - + } + // scale all keyframe times by a factor (useful for frame <-> seconds conversions) scale(timeScale) { if (timeScale !== 1.0) { const times = this.times; - for (let 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 - + } + // 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(startTime, endTime) { const times = this.times, - nKeys = times.length; + nKeys = times.length; let from = 0, - to = nKeys - 1; - + to = nKeys - 1; while (from !== nKeys && times[from] < startTime) { ++from; } - while (to !== -1 && times[to] > endTime) { --to; } - ++to; // inclusive -> exclusive bound if (from !== 0 || to !== nKeys) { @@ -27826,59 +25369,47 @@ class KeyframeTrack { to = Math.max(to, 1); from = to - 1; } - const stride = this.getValueSize(); this.times = arraySlice(times, from, to); this.values = arraySlice(this.values, from * stride, to * stride); } - return this; - } // ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable - + } + // ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable validate() { let valid = true; const valueSize = this.getValueSize(); - if (valueSize - Math.floor(valueSize) !== 0) { console.error('THREE.KeyframeTrack: Invalid value size in track.', this); valid = false; } - const times = this.times, - values = this.values, - nKeys = times.length; - + values = this.values, + nKeys = times.length; if (nKeys === 0) { console.error('THREE.KeyframeTrack: Track is empty.', this); valid = false; } - let prevTime = null; - for (let i = 0; i !== nKeys; i++) { const currTime = times[i]; - 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; } - prevTime = currTime; } - if (values !== undefined) { if (isTypedArray(values)) { for (let i = 0, n = values.length; i !== n; ++i) { const value = values[i]; - if (isNaN(value)) { console.error('THREE.KeyframeTrack: Value is not a valid number.', this, i, value); valid = false; @@ -27887,36 +25418,35 @@ class KeyframeTrack { } } } - 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) - + } + // 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() { // times or values may be shared with other tracks, so overwriting is unsafe const times = arraySlice(this.times), - values = arraySlice(this.values), - stride = this.getValueSize(), - smoothInterpolation = this.getInterpolation() === InterpolateSmooth, - lastIndex = times.length - 1; + values = arraySlice(this.values), + stride = this.getValueSize(), + smoothInterpolation = this.getInterpolation() === InterpolateSmooth, + lastIndex = times.length - 1; let writeIndex = 1; - for (let i = 1; i < lastIndex; ++i) { let keep = false; const time = times[i]; - const timeNext = times[i + 1]; // remove adjacent keyframes scheduled at the same time + const timeNext = times[i + 1]; + + // remove adjacent keyframes scheduled at the same time if (time !== timeNext && (i !== 1 || time !== times[0])) { if (!smoothInterpolation) { // remove unnecessary keyframes same as their neighbors - const offset = i * stride, - offsetP = offset - stride, - offsetN = offset + stride; + const offset = i * stride, + offsetP = offset - stride, + offsetN = offset + stride; for (let j = 0; j !== stride; ++j) { const value = values[offset + j]; - if (value !== values[offsetP + j] || value !== values[offsetN + j]) { keep = true; break; @@ -27925,35 +25455,32 @@ class KeyframeTrack { } else { keep = true; } - } // in-place compaction + } + // in-place compaction if (keep) { if (i !== writeIndex) { times[writeIndex] = times[i]; const readOffset = i * stride, - writeOffset = writeIndex * stride; - + writeOffset = writeIndex * stride; for (let j = 0; j !== stride; ++j) { values[writeOffset + j] = values[readOffset + j]; } } - ++writeIndex; } - } // flush last keyframe (compaction looks ahead) + } + // flush last keyframe (compaction looks ahead) if (lastIndex > 0) { times[writeIndex] = times[lastIndex]; - for (let readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++j) { values[writeOffset + j] = values[readOffset + j]; } - ++writeIndex; } - if (writeIndex !== times.length) { this.times = arraySlice(times, 0, writeIndex); this.values = arraySlice(values, 0, writeIndex * stride); @@ -27961,22 +25488,19 @@ class KeyframeTrack { this.times = times; this.values = values; } - return this; } - clone() { const times = arraySlice(this.times, 0); const values = arraySlice(this.values, 0); const TypedKeyframeTrack = this.constructor; - const track = new TypedKeyframeTrack(this.name, times, values); // Interpolant argument to constructor is not saved, so copy the factory method directly. + const track = new TypedKeyframeTrack(this.name, times, values); + // Interpolant argument to constructor is not saved, so copy the factory method directly. track.createInterpolant = this.createInterpolant; return track; } - } - KeyframeTrack.prototype.TimeBufferType = Float32Array; KeyframeTrack.prototype.ValueBufferType = Float32Array; KeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear; @@ -27984,30 +25508,24 @@ KeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear; /** * A Track of Boolean keyframe values. */ - class BooleanKeyframeTrack extends KeyframeTrack {} - BooleanKeyframeTrack.prototype.ValueTypeName = 'bool'; BooleanKeyframeTrack.prototype.ValueBufferType = Array; BooleanKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete; BooleanKeyframeTrack.prototype.InterpolantFactoryMethodLinear = undefined; -BooleanKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined; // Note: Actually this track could have a optimized / compressed +BooleanKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined; /** * A Track of keyframe values that represent color. */ - class ColorKeyframeTrack extends KeyframeTrack {} - -ColorKeyframeTrack.prototype.ValueTypeName = 'color'; // ValueBufferType is inherited +ColorKeyframeTrack.prototype.ValueTypeName = 'color'; /** * A Track of numeric keyframe values. */ - class NumberKeyframeTrack extends KeyframeTrack {} - -NumberKeyframeTrack.prototype.ValueTypeName = 'number'; // ValueBufferType is inherited +NumberKeyframeTrack.prototype.ValueTypeName = 'number'; /** * Spherical linear unit quaternion interpolant. @@ -28017,45 +25535,36 @@ class QuaternionLinearInterpolant extends Interpolant { constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { super(parameterPositions, sampleValues, sampleSize, resultBuffer); } - interpolate_(i1, t0, t, t1) { const result = this.resultBuffer, - values = this.sampleValues, - stride = this.valueSize, - alpha = (t - t0) / (t1 - t0); + values = this.sampleValues, + stride = this.valueSize, + alpha = (t - t0) / (t1 - t0); let offset = i1 * stride; - for (let end = offset + stride; offset !== end; offset += 4) { Quaternion.slerpFlat(result, 0, values, offset - stride, values, offset, alpha); } - return result; } - } /** * A Track of quaternion keyframe values. */ - class QuaternionKeyframeTrack extends KeyframeTrack { InterpolantFactoryMethodLinear(result) { return new QuaternionLinearInterpolant(this.times, this.values, this.getValueSize(), result); } - } - -QuaternionKeyframeTrack.prototype.ValueTypeName = 'quaternion'; // ValueBufferType is inherited - +QuaternionKeyframeTrack.prototype.ValueTypeName = 'quaternion'; +// ValueBufferType is inherited QuaternionKeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear; QuaternionKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined; /** * A Track that interpolates Strings */ - class StringKeyframeTrack extends KeyframeTrack {} - StringKeyframeTrack.prototype.ValueTypeName = 'string'; StringKeyframeTrack.prototype.ValueBufferType = Array; StringKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete; @@ -28065,10 +25574,8 @@ StringKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined; /** * A Track of vectored keyframe values. */ - class VectorKeyframeTrack extends KeyframeTrack {} - -VectorKeyframeTrack.prototype.ValueTypeName = 'vector'; // ValueBufferType is inherited +VectorKeyframeTrack.prototype.ValueTypeName = 'vector'; class AnimationClip { constructor(name, duration = -1, tracks, blendMode = NormalAnimationBlendMode) { @@ -28076,30 +25583,27 @@ class AnimationClip { this.tracks = tracks; this.duration = duration; this.blendMode = blendMode; - this.uuid = generateUUID(); // this means it should figure out its duration by scanning the tracks + this.uuid = generateUUID(); + // this means it should figure out its duration by scanning the tracks if (this.duration < 0) { this.resetDuration(); } } - static parse(json) { const tracks = [], - jsonTracks = json.tracks, - frameTime = 1.0 / (json.fps || 1.0); - + jsonTracks = json.tracks, + frameTime = 1.0 / (json.fps || 1.0); for (let i = 0, n = jsonTracks.length; i !== n; ++i) { tracks.push(parseKeyframeTrack(jsonTracks[i]).scale(frameTime)); } - const clip = new this(json.name, json.duration, tracks, json.blendMode); clip.uuid = json.uuid; return clip; } - static toJSON(clip) { const tracks = [], - clipTracks = clip.tracks; + clipTracks = clip.tracks; const json = { 'name': clip.name, 'duration': clip.duration, @@ -28107,18 +25611,14 @@ class AnimationClip { 'uuid': clip.uuid, 'blendMode': clip.blendMode }; - for (let i = 0, n = clipTracks.length; i !== n; ++i) { tracks.push(KeyframeTrack.toJSON(clipTracks[i])); } - return json; } - static CreateFromMorphTargetSequence(name, morphTargetSequence, fps, noLoop) { const numMorphTargets = morphTargetSequence.length; const tracks = []; - for (let i = 0; i < numMorphTargets; i++) { let times = []; let values = []; @@ -28126,204 +25626,174 @@ class AnimationClip { values.push(0, 1, 0); const order = getKeyframeOrder(times); times = sortedArray(times, 1, order); - values = sortedArray(values, 1, order); // if there is a key at the first frame, duplicate it as the - // last frame as well for perfect loop. + values = 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]); } - tracks.push(new NumberKeyframeTrack('.morphTargetInfluences[' + morphTargetSequence[i].name + ']', times, values).scale(1.0 / fps)); } - return new this(name, -1, tracks); } - static findByName(objectOrClipArray, name) { let clipArray = objectOrClipArray; - if (!Array.isArray(objectOrClipArray)) { const o = objectOrClipArray; clipArray = o.geometry && o.geometry.animations || o.animations; } - for (let i = 0; i < clipArray.length; i++) { if (clipArray[i].name === name) { return clipArray[i]; } } - return null; } - static CreateClipsFromMorphTargetSequences(morphTargets, fps, noLoop) { - const animationToMorphTargets = {}; // tested with https://regex101.com/ on trick sequences + const animationToMorphTargets = {}; + + // tested with https://regex101.com/ on trick sequences // such flamingo_flyA_003, flamingo_run1_003, crdeath0059 + const pattern = /^([\w-]*?)([\d]+)$/; - const pattern = /^([\w-]*?)([\d]+)$/; // sort morph target names into animation groups based + // sort morph target names into animation groups based // patterns like Walk_001, Walk_002, Run_001, Run_002 - for (let i = 0, il = morphTargets.length; i < il; i++) { const morphTarget = morphTargets[i]; const parts = morphTarget.name.match(pattern); - if (parts && parts.length > 1) { const name = parts[1]; let animationMorphTargets = animationToMorphTargets[name]; - if (!animationMorphTargets) { animationToMorphTargets[name] = animationMorphTargets = []; } - animationMorphTargets.push(morphTarget); } } - const clips = []; - for (const name in animationToMorphTargets) { clips.push(this.CreateFromMorphTargetSequence(name, animationToMorphTargets[name], fps, noLoop)); } - return clips; - } // parse the animation.hierarchy format - + } + // parse the animation.hierarchy format static parseAnimation(animation, bones) { if (!animation) { console.error('THREE.AnimationClip: No animation in JSONLoader data.'); return null; } - const addNonemptyTrack = function (trackType, trackName, animationKeys, propertyName, destTracks) { // only return track if there are actually keys. if (animationKeys.length !== 0) { const times = []; const values = []; - flattenJSON(animationKeys, times, values, propertyName); // empty keys are filtered out, so check again + flattenJSON(animationKeys, times, values, propertyName); + // empty keys are filtered out, so check again if (times.length !== 0) { destTracks.push(new trackType(trackName, times, values)); } } }; - const tracks = []; const clipName = animation.name || 'default'; const fps = animation.fps || 30; - const blendMode = animation.blendMode; // automatic length determination in AnimationClip. + const blendMode = animation.blendMode; + // automatic length determination in AnimationClip. let duration = animation.length || -1; const hierarchyTracks = animation.hierarchy || []; - for (let h = 0; h < hierarchyTracks.length; h++) { - const animationKeys = hierarchyTracks[h].keys; // skip empty tracks + const animationKeys = hierarchyTracks[h].keys; - if (!animationKeys || animationKeys.length === 0) continue; // process morph targets + // skip empty tracks + if (!animationKeys || animationKeys.length === 0) continue; + // process morph targets if (animationKeys[0].morphTargets) { // figure out all morph targets used in this track const morphTargetNames = {}; let k; - for (k = 0; k < animationKeys.length; k++) { if (animationKeys[k].morphTargets) { for (let m = 0; m < animationKeys[k].morphTargets.length; m++) { morphTargetNames[animationKeys[k].morphTargets[m]] = -1; } } - } // create a track for each morph target with all zero + } + + // create a track for each morph target with all zero // morphTargetInfluences except for the keys in which // the morphTarget is named. - - for (const morphTargetName in morphTargetNames) { const times = []; const values = []; - for (let m = 0; m !== animationKeys[k].morphTargets.length; ++m) { const animationKey = animationKeys[k]; times.push(animationKey.time); values.push(animationKey.morphTarget === morphTargetName ? 1 : 0); } - tracks.push(new NumberKeyframeTrack('.morphTargetInfluence[' + morphTargetName + ']', times, values)); } - duration = morphTargetNames.length * fps; } else { // ...assume skeletal animation + const 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); } } - if (tracks.length === 0) { return null; } - const clip = new this(clipName, duration, tracks, blendMode); return clip; } - resetDuration() { const tracks = this.tracks; let duration = 0; - for (let i = 0, n = tracks.length; i !== n; ++i) { const track = this.tracks[i]; duration = Math.max(duration, track.times[track.times.length - 1]); } - this.duration = duration; return this; } - trim() { for (let i = 0; i < this.tracks.length; i++) { this.tracks[i].trim(0, this.duration); } - return this; } - validate() { let valid = true; - for (let i = 0; i < this.tracks.length; i++) { valid = valid && this.tracks[i].validate(); } - return valid; } - optimize() { for (let i = 0; i < this.tracks.length; i++) { this.tracks[i].optimize(); } - return this; } - clone() { const tracks = []; - for (let i = 0; i < this.tracks.length; i++) { tracks.push(this.tracks[i].clone()); } - return new this.constructor(this.name, this.duration, tracks, this.blendMode); } - toJSON() { return this.constructor.toJSON(this); } - } - function getTrackTypeForValueTypeName(typeName) { switch (typeName.toLowerCase()) { case 'scalar': @@ -28332,46 +25802,37 @@ function getTrackTypeForValueTypeName(typeName) { case 'number': case 'integer': return NumberKeyframeTrack; - case 'vector': case 'vector2': case 'vector3': case 'vector4': return VectorKeyframeTrack; - case 'color': return ColorKeyframeTrack; - case 'quaternion': return QuaternionKeyframeTrack; - case 'bool': case 'boolean': return BooleanKeyframeTrack; - case 'string': return StringKeyframeTrack; } - throw new Error('THREE.KeyframeTrack: Unsupported typeName: ' + typeName); } - function parseKeyframeTrack(json) { if (json.type === undefined) { throw new Error('THREE.KeyframeTrack: track type undefined, can not parse'); } - const trackType = getTrackTypeForValueTypeName(json.type); - if (json.times === undefined) { const times = [], - values = []; + values = []; flattenJSON(json.keys, times, values, 'value'); json.times = times; json.values = values; - } // derived classes can define a static parse method - + } + // derived classes can define a static parse method if (trackType.parse !== undefined) { return trackType.parse(json); } else { @@ -28384,12 +25845,16 @@ const Cache = { enabled: false, files: {}, add: function (key, file) { - if (this.enabled === false) return; // console.log( 'THREE.Cache', 'Adding key:', key ); + if (this.enabled === false) return; + + // console.log( 'THREE.Cache', 'Adding key:', key ); this.files[key] = file; }, get: function (key) { - if (this.enabled === false) return; // console.log( 'THREE.Cache', 'Checking key:', key ); + if (this.enabled === false) return; + + // console.log( 'THREE.Cache', 'Checking key:', key ); return this.files[key]; }, @@ -28408,76 +25873,62 @@ class LoadingManager { let itemsLoaded = 0; let itemsTotal = 0; let urlModifier = undefined; - const handlers = []; // Refer to #5689 for the reason why we don't set .onStart + const 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; }; - this.itemEnd = function (url) { itemsLoaded++; - if (scope.onProgress !== undefined) { scope.onProgress(url, itemsLoaded, itemsTotal); } - if (itemsLoaded === itemsTotal) { isLoading = false; - if (scope.onLoad !== undefined) { scope.onLoad(); } } }; - this.itemError = function (url) { if (scope.onError !== undefined) { scope.onError(url); } }; - this.resolveURL = function (url) { if (urlModifier) { return urlModifier(url); } - return url; }; - this.setURLModifier = function (transform) { urlModifier = transform; return this; }; - this.addHandler = function (regex, loader) { handlers.push(regex, loader); return this; }; - this.removeHandler = function (regex) { const index = handlers.indexOf(regex); - if (index !== -1) { handlers.splice(index, 2); } - return this; }; - this.getHandler = function (file) { for (let i = 0, l = handlers.length; i < l; i += 2) { const regex = handlers[i]; @@ -28488,13 +25939,10 @@ class LoadingManager { return loader; } } - return null; }; } - } - const DefaultLoadingManager = /*@__PURE__*/new LoadingManager(); class Loader { @@ -28506,66 +25954,52 @@ class Loader { this.resourcePath = ''; this.requestHeader = {}; } - load() {} - loadAsync(url, onProgress) { const scope = this; return new Promise(function (resolve, reject) { scope.load(url, resolve, onProgress, reject); }); } - parse() {} - setCrossOrigin(crossOrigin) { this.crossOrigin = crossOrigin; return this; } - setWithCredentials(value) { this.withCredentials = value; return this; } - setPath(path) { this.path = path; return this; } - setResourcePath(resourcePath) { this.resourcePath = resourcePath; return this; } - setRequestHeader(requestHeader) { this.requestHeader = requestHeader; return this; } - } const loading = {}; - class HttpError extends Error { constructor(message, response) { super(message); this.response = response; } - } - class FileLoader extends Loader { constructor(manager) { super(manager); } - load(url, onLoad, onProgress, onError) { if (url === undefined) url = ''; if (this.path !== undefined) url = this.path + url; url = this.manager.resolveURL(url); const cached = Cache.get(url); - if (cached !== undefined) { this.manager.itemStart(url); setTimeout(() => { @@ -28573,8 +26007,9 @@ class FileLoader extends Loader { this.manager.itemEnd(url); }, 0); return cached; - } // Check if request is duplicate + } + // Check if request is duplicate if (loading[url] !== undefined) { loading[url].push({ @@ -28583,49 +26018,56 @@ class FileLoader extends Loader { onError: onError }); return; - } // Initialise array for duplicate requests - + } + // Initialise array for duplicate requests loading[url] = []; loading[url].push({ onLoad: onLoad, onProgress: onProgress, onError: onError - }); // create request + }); + // create request const req = new Request(url, { headers: new Headers(this.requestHeader), - credentials: this.withCredentials ? 'include' : 'same-origin' // An abort controller could be added within a future PR - - }); // record states ( avoid data race ) + credentials: this.withCredentials ? 'include' : 'same-origin' + // An abort controller could be added within a future PR + }); + // record states ( avoid data race ) const mimeType = this.mimeType; - const responseType = this.responseType; // start the fetch + const responseType = this.responseType; + // start the fetch fetch(req).then(response => { if (response.status === 200 || response.status === 0) { // Some browsers return HTTP Status 0 when using non-http protocol // e.g. 'file://' or 'data://'. Handle as success. + if (response.status === 0) { console.warn('THREE.FileLoader: HTTP Status 0 received.'); - } // Workaround: Checking if response.body === undefined for Alipay browser #23548 + } + // Workaround: Checking if response.body === undefined for Alipay browser #23548 if (typeof ReadableStream === 'undefined' || response.body === undefined || response.body.getReader === undefined) { return response; } - const callbacks = loading[url]; const reader = response.body.getReader(); - const contentLength = response.headers.get('Content-Length'); + + // Nginx needs X-File-Size check + // https://serverfault.com/questions/482875/why-does-nginx-remove-content-length-header-for-chunked-content + const contentLength = response.headers.get('Content-Length') || response.headers.get('X-File-Size'); const total = contentLength ? parseInt(contentLength) : 0; const lengthComputable = total !== 0; - let loaded = 0; // periodically read data into the new stream tracking while download progress + let loaded = 0; + // periodically read data into the new stream tracking while download progress const stream = new ReadableStream({ start(controller) { readData(); - function readData() { reader.read().then(({ done, @@ -28640,19 +26082,16 @@ class FileLoader extends Loader { loaded, total }); - for (let i = 0, il = callbacks.length; i < il; i++) { const callback = callbacks[i]; if (callback.onProgress) callback.onProgress(event); } - controller.enqueue(value); readData(); } }); } } - }); return new Response(stream); } else { @@ -28662,19 +26101,15 @@ class FileLoader extends Loader { switch (responseType) { case 'arraybuffer': return response.arrayBuffer(); - case 'blob': return response.blob(); - case 'document': return response.text().then(text => { const parser = new DOMParser(); return parser.parseFromString(text, mimeType); }); - case 'json': return response.json(); - default: if (mimeType === undefined) { return response.text(); @@ -28686,7 +26121,6 @@ class FileLoader extends Loader { const decoder = new TextDecoder(label); return response.arrayBuffer().then(ab => decoder.decode(ab)); } - } }).then(data => { // Add to cache only on HTTP success, so that we do not cache @@ -28694,52 +26128,44 @@ class FileLoader extends Loader { Cache.add(url, data); const callbacks = loading[url]; delete loading[url]; - for (let i = 0, il = callbacks.length; i < il; i++) { const callback = callbacks[i]; if (callback.onLoad) callback.onLoad(data); } }).catch(err => { // Abort errors and other errors are handled the same - const callbacks = loading[url]; + const callbacks = loading[url]; if (callbacks === undefined) { // When onLoad was called and url was deleted in `loading` this.manager.itemError(url); throw err; } - delete loading[url]; - for (let i = 0, il = callbacks.length; i < il; i++) { const callback = callbacks[i]; if (callback.onError) callback.onError(err); } - this.manager.itemError(url); }).finally(() => { this.manager.itemEnd(url); }); this.manager.itemStart(url); } - setResponseType(value) { this.responseType = value; return this; } - setMimeType(value) { this.mimeType = value; return this; } - } class AnimationLoader extends Loader { constructor(manager) { super(manager); } - load(url, onLoad, onProgress, onError) { const scope = this; const loader = new FileLoader(this.manager); @@ -28755,23 +26181,18 @@ class AnimationLoader extends Loader { } else { console.error(e); } - scope.manager.itemError(url); } }, onProgress, onError); } - parse(json) { const animations = []; - for (let i = 0; i < json.length; i++) { const clip = AnimationClip.parse(json[i]); animations.push(clip); } - return animations; } - } /** @@ -28784,7 +26205,6 @@ class CompressedTextureLoader extends Loader { constructor(manager) { super(manager); } - load(url, onLoad, onProgress, onError) { const scope = this; const images = []; @@ -28795,7 +26215,6 @@ class CompressedTextureLoader extends Loader { loader.setRequestHeader(this.requestHeader); loader.setWithCredentials(scope.withCredentials); let loaded = 0; - function loadTexture(i) { loader.load(url[i], function (buffer) { const texDatas = scope.parse(buffer, true); @@ -28806,7 +26225,6 @@ class CompressedTextureLoader extends Loader { mipmaps: texDatas.mipmaps }; loaded += 1; - if (loaded === 6) { if (texDatas.mipmapCount === 1) texture.minFilter = LinearFilter; texture.image = images; @@ -28816,24 +26234,21 @@ class CompressedTextureLoader extends Loader { } }, onProgress, onError); } - if (Array.isArray(url)) { for (let 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) { const texDatas = scope.parse(buffer, true); - if (texDatas.isCubemap) { const faces = texDatas.mipmaps.length / texDatas.mipmapCount; - for (let f = 0; f < faces; f++) { images[f] = { mipmaps: [] }; - for (let i = 0; i < texDatas.mipmapCount; i++) { images[f].mipmaps.push(texDatas.mipmaps[f * texDatas.mipmapCount + i]); images[f].format = texDatas.format; @@ -28841,40 +26256,33 @@ class CompressedTextureLoader extends Loader { images[f].height = texDatas.height; } } - texture.image = images; } else { texture.image.width = texDatas.width; texture.image.height = texDatas.height; texture.mipmaps = texDatas.mipmaps; } - if (texDatas.mipmapCount === 1) { texture.minFilter = LinearFilter; } - texture.format = texDatas.format; texture.needsUpdate = true; if (onLoad) onLoad(texture); }, onProgress, onError); } - return texture; } - } class ImageLoader extends Loader { constructor(manager) { super(manager); } - load(url, onLoad, onProgress, onError) { if (this.path !== undefined) url = this.path + url; url = this.manager.resolveURL(url); const scope = this; const cached = Cache.get(url); - if (cached !== undefined) { scope.manager.itemStart(url); setTimeout(function () { @@ -28883,73 +26291,59 @@ class ImageLoader extends Loader { }, 0); return cached; } - const image = createElementNS('img'); - function onImageLoad() { removeEventListeners(); Cache.add(url, this); if (onLoad) onLoad(this); scope.manager.itemEnd(url); } - function onImageError(event) { removeEventListeners(); if (onError) onError(event); scope.manager.itemError(url); scope.manager.itemEnd(url); } - function removeEventListeners() { image.removeEventListener('load', onImageLoad, false); image.removeEventListener('error', onImageError, false); } - image.addEventListener('load', onImageLoad, false); image.addEventListener('error', onImageError, false); - if (url.slice(0, 5) !== 'data:') { if (this.crossOrigin !== undefined) image.crossOrigin = this.crossOrigin; } - scope.manager.itemStart(url); image.src = url; return image; } - } class CubeTextureLoader extends Loader { constructor(manager) { super(manager); } - load(urls, onLoad, onProgress, onError) { const texture = new CubeTexture(); const loader = new ImageLoader(this.manager); loader.setCrossOrigin(this.crossOrigin); loader.setPath(this.path); let loaded = 0; - function loadTexture(i) { loader.load(urls[i], function (image) { texture.images[i] = image; loaded++; - if (loaded === 6) { texture.needsUpdate = true; if (onLoad) onLoad(texture); } }, undefined, onError); } - for (let i = 0; i < urls.length; ++i) { loadTexture(i); } - return texture; } - } /** @@ -28962,7 +26356,6 @@ class DataTextureLoader extends Loader { constructor(manager) { super(manager); } - load(url, onLoad, onProgress, onError) { const scope = this; const texture = new DataTexture(); @@ -28974,7 +26367,6 @@ class DataTextureLoader extends Loader { loader.load(url, function (buffer) { const texData = scope.parse(buffer); if (!texData) return; - if (texData.image !== undefined) { texture.image = texData.image; } else if (texData.data !== undefined) { @@ -28982,29 +26374,23 @@ class DataTextureLoader extends Loader { texture.image.height = texData.height; texture.image.data = texData.data; } - 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; - if (texData.encoding !== undefined) { texture.encoding = texData.encoding; } - if (texData.flipY !== undefined) { texture.flipY = texData.flipY; } - if (texData.format !== undefined) { texture.format = texData.format; } - if (texData.type !== undefined) { texture.type = texData.type; } - if (texData.mipmaps !== undefined) { texture.mipmaps = texData.mipmaps; texture.minFilter = LinearMipmapLinearFilter; // presumably... @@ -29013,24 +26399,20 @@ class DataTextureLoader extends Loader { if (texData.mipmapCount === 1) { texture.minFilter = LinearFilter; } - if (texData.generateMipmaps !== undefined) { texture.generateMipmaps = texData.generateMipmaps; } - texture.needsUpdate = true; if (onLoad) onLoad(texture, texData); }, onProgress, onError); return texture; } - } class TextureLoader extends Loader { constructor(manager) { super(manager); } - load(url, onLoad, onProgress, onError) { const texture = new Texture(); const loader = new ImageLoader(this.manager); @@ -29039,14 +26421,12 @@ class TextureLoader extends Loader { loader.load(url, function (image) { texture.image = image; texture.needsUpdate = true; - if (onLoad !== undefined) { onLoad(texture); } }, onProgress, onError); return texture; } - } class Light extends Object3D { @@ -29057,17 +26437,16 @@ class Light extends Object3D { this.color = new Color(color); this.intensity = intensity; } + dispose() { - dispose() {// Empty here in base class; some subclasses override. + // Empty here in base class; some subclasses override. } - copy(source, recursive) { super.copy(source, recursive); this.color.copy(source.color); this.intensity = source.intensity; return this; } - toJSON(meta) { const data = super.toJSON(meta); data.object.color = this.color.getHex(); @@ -29080,7 +26459,6 @@ class Light extends Object3D { if (this.shadow !== undefined) data.object.shadow = this.shadow.toJSON(); return data; } - } class HemisphereLight extends Light { @@ -29092,21 +26470,16 @@ class HemisphereLight extends Light { this.updateMatrix(); this.groundColor = new Color(groundColor); } - copy(source, recursive) { super.copy(source, recursive); this.groundColor.copy(source.groundColor); return this; } - } const _projScreenMatrix$1 = /*@__PURE__*/new Matrix4(); - const _lightPositionWorld$1 = /*@__PURE__*/new Vector3(); - const _lookTarget$1 = /*@__PURE__*/new Vector3(); - class LightShadow { constructor(camera) { this.camera = camera; @@ -29125,55 +26498,39 @@ class LightShadow { this._viewportCount = 1; this._viewports = [new Vector4(0, 0, 1, 1)]; } - getViewportCount() { return this._viewportCount; } - getFrustum() { return this._frustum; } - updateMatrices(light) { const shadowCamera = this.camera; const shadowMatrix = this.matrix; - _lightPositionWorld$1.setFromMatrixPosition(light.matrixWorld); - shadowCamera.position.copy(_lightPositionWorld$1); - _lookTarget$1.setFromMatrixPosition(light.target.matrixWorld); - shadowCamera.lookAt(_lookTarget$1); shadowCamera.updateMatrixWorld(); - _projScreenMatrix$1.multiplyMatrices(shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse); - this._frustum.setFromProjectionMatrix(_projScreenMatrix$1); - 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); + shadowMatrix.multiply(_projScreenMatrix$1); } - getViewport(viewportIndex) { return this._viewports[viewportIndex]; } - getFrameExtents() { return this._frameExtents; } - dispose() { if (this.map) { this.map.dispose(); } - if (this.mapPass) { this.mapPass.dispose(); } } - copy(source) { this.camera = source.camera.clone(); this.bias = source.bias; @@ -29181,11 +26538,9 @@ class LightShadow { this.mapSize.copy(source.mapSize); return this; } - clone() { return new this.constructor().copy(this); } - toJSON() { const object = {}; if (this.bias !== 0) object.bias = this.bias; @@ -29196,7 +26551,6 @@ class LightShadow { delete object.camera.matrix; return object; } - } class SpotLightShadow extends LightShadow { @@ -29205,33 +26559,28 @@ class SpotLightShadow extends LightShadow { this.isSpotLightShadow = true; this.focus = 1; } - updateMatrices(light) { const camera = this.camera; const fov = RAD2DEG * 2 * light.angle * this.focus; const aspect = this.mapSize.width / this.mapSize.height; const 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(); } - super.updateMatrices(light); } - copy(source) { super.copy(source); this.focus = source.focus; return this; } - } class SpotLight extends Light { - constructor(color, intensity, distance = 0, angle = Math.PI / 3, penumbra = 0, decay = 1) { + constructor(color, intensity, distance = 0, angle = Math.PI / 3, penumbra = 0, decay = 2) { super(color, intensity); this.isSpotLight = true; this.type = 'SpotLight'; @@ -29241,26 +26590,22 @@ class SpotLight extends Light { this.distance = distance; this.angle = angle; this.penumbra = penumbra; - this.decay = decay; // for physically correct lights, should be 2. - + this.decay = decay; + this.map = null; this.shadow = new SpotLightShadow(); } - get power() { // compute the light's luminous power (in lumens) from its intensity (in candela) // by convention for a spotlight, luminous power (lm) = π * luminous intensity (cd) return this.intensity * Math.PI; } - set power(power) { // set the light's intensity (in candela) from the desired luminous power (in lumens) this.intensity = power / Math.PI; } - dispose() { this.shadow.dispose(); } - copy(source, recursive) { super.copy(source, recursive); this.distance = source.distance; @@ -29271,22 +26616,19 @@ class SpotLight extends Light { this.shadow = source.shadow.clone(); return this; } - } const _projScreenMatrix = /*@__PURE__*/new Matrix4(); - const _lightPositionWorld = /*@__PURE__*/new Vector3(); - const _lookTarget = /*@__PURE__*/new Vector3(); - class PointLightShadow extends LightShadow { constructor() { super(new PerspectiveCamera(90, 1, 0.5, 500)); this.isPointLightShadow = true; this._frameExtents = new Vector2(4, 2); this._viewportCount = 6; - this._viewports = [// These viewports map a cube-map onto a 2D texture with the + this._viewports = [ + // These viewports map a cube-map onto a 2D texture with the // following orientation: // // xzXZ @@ -29298,73 +26640,64 @@ class PointLightShadow extends LightShadow { // 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(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)]; } - updateMatrices(light, viewportIndex = 0) { const camera = this.camera; const shadowMatrix = this.matrix; const far = light.distance || camera.far; - if (far !== camera.far) { camera.far = far; camera.updateProjectionMatrix(); } - _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); } - } class PointLight extends Light { - constructor(color, intensity, distance = 0, decay = 1) { + constructor(color, intensity, distance = 0, decay = 2) { super(color, intensity); this.isPointLight = true; this.type = 'PointLight'; this.distance = distance; - this.decay = decay; // for physically correct lights, should be 2. - + this.decay = decay; this.shadow = new PointLightShadow(); } - get power() { // compute the light's luminous power (in lumens) from its intensity (in candela) // for an isotropic light source, luminous power (lm) = 4 π luminous intensity (cd) return this.intensity * 4 * Math.PI; } - set power(power) { // set the light's intensity (in candela) from the desired luminous power (in lumens) this.intensity = power / (4 * Math.PI); } - dispose() { this.shadow.dispose(); } - copy(source, recursive) { super.copy(source, recursive); this.distance = source.distance; @@ -29372,7 +26705,6 @@ class PointLight extends Light { this.shadow = source.shadow.clone(); return this; } - } class DirectionalLightShadow extends LightShadow { @@ -29380,7 +26712,6 @@ class DirectionalLightShadow extends LightShadow { super(new OrthographicCamera(-5, 5, 5, -5, 0.5, 500)); this.isDirectionalLightShadow = true; } - } class DirectionalLight extends Light { @@ -29393,18 +26724,15 @@ class DirectionalLight extends Light { this.target = new Object3D(); this.shadow = new DirectionalLightShadow(); } - dispose() { this.shadow.dispose(); } - copy(source) { super.copy(source); this.target = source.target.clone(); this.shadow = source.shadow.clone(); return this; } - } class AmbientLight extends Light { @@ -29413,7 +26741,6 @@ class AmbientLight extends Light { this.isAmbientLight = true; this.type = 'AmbientLight'; } - } class RectAreaLight extends Light { @@ -29424,31 +26751,26 @@ class RectAreaLight extends Light { this.width = width; this.height = height; } - get power() { // compute the light's luminous power (in lumens) from its intensity (in nits) return this.intensity * this.width * this.height * Math.PI; } - set power(power) { // set the light's intensity (in nits) from the desired luminous power (in lumens) this.intensity = power / (this.width * this.height * Math.PI); } - copy(source) { super.copy(source); this.width = source.width; this.height = source.height; return this; } - toJSON(meta) { const data = super.toJSON(meta); data.object.width = this.width; data.object.height = this.height; return data; } - } /** @@ -29458,177 +26780,162 @@ class RectAreaLight extends Light { * Secondary reference: * https://www.ppsloan.org/publications/StupidSH36.pdf */ + // 3-band SH defined by 9 coefficients class SphericalHarmonics3 { constructor() { this.isSphericalHarmonics3 = true; this.coefficients = []; - for (let i = 0; i < 9; i++) { this.coefficients.push(new Vector3()); } } - set(coefficients) { for (let i = 0; i < 9; i++) { this.coefficients[i].copy(coefficients[i]); } - return this; } - zero() { for (let i = 0; i < 9; i++) { this.coefficients[i].set(0, 0, 0); } - return this; - } // get the radiance in the direction of the normal - // target is a Vector3 - + } + // get the radiance in the direction of the normal + // target is a Vector3 getAt(normal, target) { // normal is assumed to be unit length + const x = normal.x, - y = normal.y, - z = normal.z; - const coeff = this.coefficients; // band 0 + y = normal.y, + z = normal.z; + const coeff = this.coefficients; - target.copy(coeff[0]).multiplyScalar(0.282095); // band 1 + // 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[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 + } + + // 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 - - getIrradianceAt(normal, target) { // normal is assumed to be unit length + const x = normal.x, - y = normal.y, - z = normal.z; - const coeff = this.coefficients; // band 0 + y = normal.y, + z = normal.z; + const coeff = this.coefficients; + // band 0 target.copy(coeff[0]).multiplyScalar(0.886227); // π * 0.282095 - // band 1 + // 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[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; } - add(sh) { for (let i = 0; i < 9; i++) { this.coefficients[i].add(sh.coefficients[i]); } - return this; } - addScaledSH(sh, s) { for (let i = 0; i < 9; i++) { this.coefficients[i].addScaledVector(sh.coefficients[i], s); } - return this; } - scale(s) { for (let i = 0; i < 9; i++) { this.coefficients[i].multiplyScalar(s); } - return this; } - lerp(sh, alpha) { for (let i = 0; i < 9; i++) { this.coefficients[i].lerp(sh.coefficients[i], alpha); } - return this; } - equals(sh) { for (let i = 0; i < 9; i++) { if (!this.coefficients[i].equals(sh.coefficients[i])) { return false; } } - return true; } - copy(sh) { return this.set(sh.coefficients); } - clone() { return new this.constructor().copy(this); } - fromArray(array, offset = 0) { const coefficients = this.coefficients; - for (let i = 0; i < 9; i++) { coefficients[i].fromArray(array, offset + i * 3); } - return this; } - toArray(array = [], offset = 0) { const coefficients = this.coefficients; - for (let i = 0; i < 9; i++) { coefficients[i].toArray(array, offset + i * 3); } - return array; - } // evaluate the basis functions - // shBasis is an Array[ 9 ] - + } + // evaluate the basis functions + // shBasis is an Array[ 9 ] static getBasisAt(normal, shBasis) { // normal is assumed to be unit length + const x = normal.x, - y = normal.y, - z = normal.z; // band 0 + y = normal.y, + z = normal.z; - shBasis[0] = 0.282095; // band 1 + // 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[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); } - } class LightProbe extends Light { @@ -29637,26 +26944,21 @@ class LightProbe extends Light { this.isLightProbe = true; this.sh = sh; } - copy(source) { super.copy(source); this.sh.copy(source.sh); return this; } - fromJSON(json) { this.intensity = json.intensity; // TODO: Move this bit to Light.fromJSON(); - this.sh.fromArray(json.sh); return this; } - toJSON(meta) { const data = super.toJSON(meta); data.object.sh = this.sh.toArray(); return data; } - } class MaterialLoader extends Loader { @@ -29664,7 +26966,6 @@ class MaterialLoader extends Loader { super(manager); this.textures = {}; } - load(url, onLoad, onProgress, onError) { const scope = this; const loader = new FileLoader(scope.manager); @@ -29680,23 +26981,18 @@ class MaterialLoader extends Loader { } else { console.error(e); } - scope.manager.itemError(url); } }, onProgress, onError); } - parse(json) { const textures = this.textures; - function getTexture(name) { if (textures[name] === undefined) { console.warn('THREE.MaterialLoader: Undefined texture', name); } - return textures[name]; } - const material = MaterialLoader.createMaterialFromType(json.type); if (json.uuid !== undefined) material.uuid = json.uuid; if (json.name !== undefined) material.name = json.name; @@ -29758,72 +27054,63 @@ class MaterialLoader extends Loader { 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 + } + // Shader Material if (json.uniforms !== undefined) { for (const name in json.uniforms) { const 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; - case 'v2': material.uniforms[name].value = new Vector2().fromArray(uniform.value); break; - case 'v3': material.uniforms[name].value = new Vector3().fromArray(uniform.value); break; - case 'v4': material.uniforms[name].value = new Vector4().fromArray(uniform.value); break; - case 'm3': material.uniforms[name].value = new Matrix3().fromArray(uniform.value); break; - case 'm4': material.uniforms[name].value = new Matrix4().fromArray(uniform.value); break; - default: material.uniforms[name].value = uniform.value; } } } - 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.glslVersion !== undefined) material.glslVersion = json.glslVersion; if (json.extensions !== undefined) { for (const key in json.extensions) { material.extensions[key] = json.extensions[key]; } - } // Deprecated - + } - if (json.shading !== undefined) material.flatShading = json.shading === 1; // THREE.FlatShading // for PointsMaterial if (json.size !== undefined) material.size = json.size; - if (json.sizeAttenuation !== undefined) material.sizeAttenuation = json.sizeAttenuation; // maps + if (json.sizeAttenuation !== undefined) material.sizeAttenuation = json.sizeAttenuation; + + // maps if (json.map !== undefined) material.map = getTexture(json.map); if (json.matcap !== undefined) material.matcap = getTexture(json.matcap); @@ -29832,18 +27119,15 @@ class MaterialLoader extends Loader { 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; - if (json.normalScale !== undefined) { let normalScale = json.normalScale; - if (Array.isArray(normalScale) === false) { // Blender exporter used to export a scalar. See #7459 + normalScale = [normalScale, normalScale]; } - 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; @@ -29875,12 +27159,10 @@ class MaterialLoader extends Loader { if (json.sheenRoughnessMap !== undefined) material.sheenRoughnessMap = getTexture(json.sheenRoughnessMap); return material; } - setTextures(value) { this.textures = value; return this; } - static createMaterialFromType(type) { const materialLib = { ShadowMaterial, @@ -29904,57 +27186,58 @@ class MaterialLoader extends Loader { }; return new materialLib[type](); } - } class LoaderUtils { static 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. + } + // Avoid the String.fromCharCode.apply(null, array) shortcut, which + // throws a "maximum call stack size exceeded" error for large arrays. let s = ''; - for (let i = 0, il = array.length; i < il; i++) { // Implicitly assumes little-endian. s += String.fromCharCode(array[i]); } - try { // merges multi-byte utf-8 characters. + return decodeURIComponent(escape(s)); } catch (e) { // see #16358 + return s; } } - static extractUrlBase(url) { const index = url.lastIndexOf('/'); if (index === -1) return './'; return url.slice(0, index + 1); } - static resolveURL(url, path) { // Invalid URL - if (typeof url !== 'string' || url === '') return ''; // Host Relative URL + if (typeof url !== 'string' || url === '') return ''; + // Host Relative URL if (/^https?:\/\//i.test(path) && /^\//.test(url)) { path = path.replace(/(^https?:\/\/[^\/]+).*/i, '$1'); - } // Absolute URL http://,https://,// - + } - if (/^(https?:)?\/\//i.test(url)) return url; // Data URI + // Absolute URL http://,https://,// + if (/^(https?:)?\/\//i.test(url)) return url; - if (/^data:.*,.*$/i.test(url)) return url; // Blob URL + // Data URI + if (/^data:.*,.*$/i.test(url)) return url; - if (/^blob:.*$/i.test(url)) return url; // Relative URL + // Blob URL + if (/^blob:.*$/i.test(url)) return url; + // Relative URL return path + url; } - } class InstancedBufferGeometry extends BufferGeometry { @@ -29964,31 +27247,23 @@ class InstancedBufferGeometry extends BufferGeometry { this.type = 'InstancedBufferGeometry'; this.instanceCount = Infinity; } - copy(source) { super.copy(source); this.instanceCount = source.instanceCount; return this; } - - clone() { - return new this.constructor().copy(this); - } - toJSON() { - const data = super.toJSON(this); + const data = super.toJSON(); data.instanceCount = this.instanceCount; data.isInstancedBufferGeometry = true; return data; } - } class BufferGeometryLoader extends Loader { constructor(manager) { super(manager); } - load(url, onLoad, onProgress, onError) { const scope = this; const loader = new FileLoader(scope.manager); @@ -30004,16 +27279,13 @@ class BufferGeometryLoader extends Loader { } else { console.error(e); } - scope.manager.itemError(url); } }, onProgress, onError); } - parse(json) { const interleavedBufferMap = {}; const arrayBufferMap = {}; - function getInterleavedBuffer(json, uuid) { if (interleavedBufferMap[uuid] !== undefined) return interleavedBufferMap[uuid]; const interleavedBuffers = json.interleavedBuffers; @@ -30025,7 +27297,6 @@ class BufferGeometryLoader extends Loader { interleavedBufferMap[uuid] = ib; return ib; } - function getArrayBuffer(json, uuid) { if (arrayBufferMap[uuid] !== undefined) return arrayBufferMap[uuid]; const arrayBuffers = json.arrayBuffers; @@ -30034,21 +27305,16 @@ class BufferGeometryLoader extends Loader { arrayBufferMap[uuid] = ab; return ab; } - const geometry = json.isInstancedBufferGeometry ? new InstancedBufferGeometry() : new BufferGeometry(); const index = json.data.index; - if (index !== undefined) { const typedArray = getTypedArray(index.type, index.array); geometry.setIndex(new BufferAttribute(typedArray, 1)); } - const attributes = json.data.attributes; - for (const key in attributes) { const attribute = attributes[key]; let bufferAttribute; - if (attribute.isInterleavedBufferAttribute) { const interleavedBuffer = getInterleavedBuffer(json.data, attribute.data); bufferAttribute = new InterleavedBufferAttribute(interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized); @@ -30057,29 +27323,22 @@ class BufferGeometryLoader extends Loader { const bufferAttributeConstr = attribute.isInstancedBufferAttribute ? InstancedBufferAttribute : BufferAttribute; bufferAttribute = new bufferAttributeConstr(typedArray, attribute.itemSize, attribute.normalized); } - if (attribute.name !== undefined) bufferAttribute.name = attribute.name; if (attribute.usage !== undefined) bufferAttribute.setUsage(attribute.usage); - if (attribute.updateRange !== undefined) { bufferAttribute.updateRange.offset = attribute.updateRange.offset; bufferAttribute.updateRange.count = attribute.updateRange.count; } - geometry.setAttribute(key, bufferAttribute); } - const morphAttributes = json.data.morphAttributes; - if (morphAttributes) { for (const key in morphAttributes) { const attributeArray = morphAttributes[key]; const array = []; - for (let i = 0, il = attributeArray.length; i < il; i++) { const attribute = attributeArray[i]; let bufferAttribute; - if (attribute.isInterleavedBufferAttribute) { const interleavedBuffer = getInterleavedBuffer(json.data, attribute.data); bufferAttribute = new InterleavedBufferAttribute(interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized); @@ -30087,54 +27346,41 @@ class BufferGeometryLoader extends Loader { const typedArray = getTypedArray(attribute.type, attribute.array); bufferAttribute = new BufferAttribute(typedArray, attribute.itemSize, attribute.normalized); } - if (attribute.name !== undefined) bufferAttribute.name = attribute.name; array.push(bufferAttribute); } - geometry.morphAttributes[key] = array; } } - const morphTargetsRelative = json.data.morphTargetsRelative; - if (morphTargetsRelative) { geometry.morphTargetsRelative = true; } - const groups = json.data.groups || json.data.drawcalls || json.data.offsets; - if (groups !== undefined) { for (let i = 0, n = groups.length; i !== n; ++i) { const group = groups[i]; geometry.addGroup(group.start, group.count, group.materialIndex); } } - const boundingSphere = json.data.boundingSphere; - if (boundingSphere !== undefined) { const center = new Vector3(); - if (boundingSphere.center !== undefined) { center.fromArray(boundingSphere.center); } - geometry.boundingSphere = new Sphere(center, boundingSphere.radius); } - if (json.name) geometry.name = json.name; if (json.userData) geometry.userData = json.userData; return geometry; } - } class ObjectLoader extends Loader { constructor(manager) { super(manager); } - load(url, onLoad, onProgress, onError) { const scope = this; const path = this.path === '' ? LoaderUtils.extractUrlBase(url) : this.path; @@ -30145,7 +27391,6 @@ class ObjectLoader extends Loader { loader.setWithCredentials(this.withCredentials); loader.load(url, function (text) { let json = null; - try { json = JSON.parse(text); } catch (error) { @@ -30153,18 +27398,15 @@ class ObjectLoader extends Loader { console.error('THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message); return; } - const metadata = json.metadata; - if (metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry') { + if (onError !== undefined) onError(new Error('THREE.ObjectLoader: Can\'t load ' + url)); console.error('THREE.ObjectLoader: Can\'t load ' + url); return; } - scope.parse(json, onLoad); }, onProgress, onError); } - async loadAsync(url, onProgress) { const scope = this; const path = this.path === '' ? LoaderUtils.extractUrlBase(url) : this.path; @@ -30176,14 +27418,11 @@ class ObjectLoader extends Loader { const text = await loader.loadAsync(url, onProgress); const json = JSON.parse(text); const metadata = json.metadata; - if (metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry') { throw new Error('THREE.ObjectLoader: Can\'t load ' + url); } - return await scope.parseAsync(json); } - parse(json, onLoad) { const animations = this.parseAnimations(json.animations); const shapes = this.parseShapes(json.shapes); @@ -30195,24 +27434,22 @@ class ObjectLoader extends Loader { const materials = this.parseMaterials(json.materials, textures); const object = this.parseObject(json.object, geometries, materials, textures, animations); const skeletons = this.parseSkeletons(json.skeletons, object); - this.bindSkeletons(object, skeletons); // + this.bindSkeletons(object, skeletons); + + // if (onLoad !== undefined) { let hasImages = false; - for (const uuid in images) { if (images[uuid].data instanceof HTMLImageElement) { hasImages = true; break; } } - if (hasImages === false) onLoad(object); } - return object; } - async parseAsync(json) { const animations = this.parseAnimations(json.animations); const shapes = this.parseShapes(json.shapes); @@ -30225,27 +27462,27 @@ class ObjectLoader extends Loader { this.bindSkeletons(object, skeletons); return object; } - parseShapes(json) { const shapes = {}; - if (json !== undefined) { for (let i = 0, l = json.length; i < l; i++) { const shape = new Shape().fromJSON(json[i]); shapes[shape.uuid] = shape; } } - return shapes; } - parseSkeletons(json, object) { const skeletons = {}; - const bones = {}; // generate bone lookup table + const bones = {}; + + // generate bone lookup table object.traverse(function (child) { if (child.isBone) bones[child.uuid] = child; - }); // create skeletons + }); + + // create skeletons if (json !== undefined) { for (let i = 0, l = json.length; i < l; i++) { @@ -30253,92 +27490,53 @@ class ObjectLoader extends Loader { skeletons[skeleton.uuid] = skeleton; } } - return skeletons; } - parseGeometries(json, shapes) { const geometries = {}; - if (json !== undefined) { const bufferGeometryLoader = new BufferGeometryLoader(); - for (let i = 0, l = json.length; i < l; i++) { let geometry; const data = json[i]; - switch (data.type) { case 'BufferGeometry': case 'InstancedBufferGeometry': geometry = bufferGeometryLoader.parse(data); break; - - case 'Geometry': - console.error('THREE.ObjectLoader: The legacy Geometry type is no longer supported.'); - break; - default: if (data.type in Geometries) { geometry = Geometries[data.type].fromJSON(data, shapes); } else { console.warn(`THREE.ObjectLoader: Unsupported geometry type "${data.type}"`); } - } - 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; } } - return geometries; } - parseMaterials(json, textures) { const cache = {}; // MultiMaterial - const materials = {}; - if (json !== undefined) { const loader = new MaterialLoader(); loader.setTextures(textures); - for (let i = 0, l = json.length; i < l; i++) { const data = json[i]; - - if (data.type === 'MultiMaterial') { - // Deprecated - const array = []; - - for (let j = 0; j < data.materials.length; j++) { - const material = data.materials[j]; - - if (cache[material.uuid] === undefined) { - cache[material.uuid] = loader.parse(material); - } - - array.push(cache[material.uuid]); - } - - materials[data.uuid] = array; - } else { - if (cache[data.uuid] === undefined) { - cache[data.uuid] = loader.parse(data); - } - - materials[data.uuid] = cache[data.uuid]; + if (cache[data.uuid] === undefined) { + cache[data.uuid] = loader.parse(data); } + materials[data.uuid] = cache[data.uuid]; } } - return materials; } - parseAnimations(json) { const animations = {}; - if (json !== undefined) { for (let i = 0; i < json.length; i++) { const data = json[i]; @@ -30346,15 +27544,12 @@ class ObjectLoader extends Loader { animations[clip.uuid] = clip; } } - return animations; } - parseImages(json, onLoad) { const scope = this; const images = {}; let loader; - function loadImage(url) { scope.manager.itemStart(url); return loader.load(url, function () { @@ -30364,7 +27559,6 @@ class ObjectLoader extends Loader { scope.manager.itemEnd(url); }); } - function deserializeImage(image) { if (typeof image === 'string') { const url = image; @@ -30382,51 +27576,45 @@ class ObjectLoader extends Loader { } } } - if (json !== undefined && json.length > 0) { const manager = new LoadingManager(onLoad); loader = new ImageLoader(manager); loader.setCrossOrigin(this.crossOrigin); - for (let i = 0, il = json.length; i < il; i++) { const image = json[i]; const url = image.url; - if (Array.isArray(url)) { // load array of images e.g CubeTexture - const imageArray = []; + const imageArray = []; for (let j = 0, jl = url.length; j < jl; j++) { const currentUrl = url[j]; const deserializedImage = deserializeImage(currentUrl); - if (deserializedImage !== null) { if (deserializedImage instanceof HTMLImageElement) { imageArray.push(deserializedImage); } else { // special case: handle array of data textures for cube textures + imageArray.push(new DataTexture(deserializedImage.data, deserializedImage.width, deserializedImage.height)); } } } - images[image.uuid] = new Source(imageArray); } else { // load single image + const deserializedImage = deserializeImage(image.url); images[image.uuid] = new Source(deserializedImage); } } } - return images; } - async parseImagesAsync(json) { const scope = this; const images = {}; let loader; - async function deserializeImage(image) { if (typeof image === 'string') { const url = image; @@ -30444,70 +27632,59 @@ class ObjectLoader extends Loader { } } } - if (json !== undefined && json.length > 0) { loader = new ImageLoader(this.manager); loader.setCrossOrigin(this.crossOrigin); - for (let i = 0, il = json.length; i < il; i++) { const image = json[i]; const url = image.url; - if (Array.isArray(url)) { // load array of images e.g CubeTexture - const imageArray = []; + const imageArray = []; for (let j = 0, jl = url.length; j < jl; j++) { const currentUrl = url[j]; const deserializedImage = await deserializeImage(currentUrl); - if (deserializedImage !== null) { if (deserializedImage instanceof HTMLImageElement) { imageArray.push(deserializedImage); } else { // special case: handle array of data textures for cube textures + imageArray.push(new DataTexture(deserializedImage.data, deserializedImage.width, deserializedImage.height)); } } } - images[image.uuid] = new Source(imageArray); } else { // load single image + const deserializedImage = await deserializeImage(image.url); images[image.uuid] = new Source(deserializedImage); } } } - return images; } - 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]; } - const textures = {}; - if (json !== undefined) { for (let i = 0, l = json.length; i < l; i++) { const data = json[i]; - if (data.image === undefined) { console.warn('THREE.ObjectLoader: No "image" specified for', data.uuid); } - if (images[data.image] === undefined) { console.warn('THREE.ObjectLoader: Undefined image', data.image); } - const source = images[data.image]; const image = source.data; let texture; - if (Array.isArray(image)) { texture = new CubeTexture(); if (image.length === 6) texture.needsUpdate = true; @@ -30517,7 +27694,6 @@ class ObjectLoader extends Loader { } else { texture = new Texture(); } - if (image) texture.needsUpdate = true; // textures can have undefined image data } @@ -30529,12 +27705,10 @@ class ObjectLoader extends Loader { 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); } - if (data.format !== undefined) texture.format = data.format; if (data.type !== undefined) texture.type = data.type; if (data.encoding !== undefined) texture.encoding = data.encoding; @@ -30548,61 +27722,44 @@ class ObjectLoader extends Loader { textures[data.uuid] = texture; } } - return textures; } - parseObject(data, geometries, materials, textures, animations) { let object; - function getGeometry(name) { if (geometries[name] === undefined) { console.warn('THREE.ObjectLoader: Undefined geometry', name); } - return geometries[name]; } - function getMaterial(name) { if (name === undefined) return undefined; - if (Array.isArray(name)) { const array = []; - for (let i = 0, l = name.length; i < l; i++) { const uuid = name[i]; - if (materials[uuid] === undefined) { console.warn('THREE.ObjectLoader: Undefined material', uuid); } - array.push(materials[uuid]); } - return array; } - if (materials[name] === undefined) { console.warn('THREE.ObjectLoader: Undefined material', name); } - return materials[name]; } - function getTexture(uuid) { if (textures[uuid] === undefined) { console.warn('THREE.ObjectLoader: Undefined texture', uuid); } - return textures[uuid]; } - let geometry, material; - switch (data.type) { case 'Scene': object = new Scene(); - if (data.background !== undefined) { if (Number.isInteger(data.background)) { object.background = new Color(data.background); @@ -30610,11 +27767,9 @@ class ObjectLoader extends Loader { object.background = getTexture(data.background); } } - if (data.environment !== undefined) { object.environment = getTexture(data.environment); } - if (data.fog !== undefined) { if (data.fog.type === 'Fog') { object.fog = new Fog(data.fog.color, data.fog.near, data.fog.far); @@ -30622,9 +27777,8 @@ class ObjectLoader extends Loader { object.fog = new FogExp2(data.fog.color, data.fog.density); } } - + if (data.backgroundBlurriness !== undefined) object.backgroundBlurriness = data.backgroundBlurriness; break; - case 'PerspectiveCamera': object = new PerspectiveCamera(data.fov, data.aspect, data.near, data.far); if (data.focus !== undefined) object.focus = data.focus; @@ -30633,41 +27787,32 @@ class ObjectLoader extends Loader { if (data.filmOffset !== undefined) object.filmOffset = data.filmOffset; if (data.view !== undefined) object.view = Object.assign({}, data.view); break; - 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; - case 'AmbientLight': object = new AmbientLight(data.color, data.intensity); break; - case 'DirectionalLight': object = new DirectionalLight(data.color, data.intensity); break; - case 'PointLight': object = new PointLight(data.color, data.intensity, data.distance, data.decay); break; - case 'RectAreaLight': object = new RectAreaLight(data.color, data.intensity, data.width, data.height); break; - case 'SpotLight': object = new SpotLight(data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay); break; - case 'HemisphereLight': object = new HemisphereLight(data.color, data.groundColor, data.intensity); break; - case 'LightProbe': object = new LightProbe().fromJSON(data); break; - case 'SkinnedMesh': geometry = getGeometry(data.geometry); material = getMaterial(data.material); @@ -30676,13 +27821,11 @@ class ObjectLoader extends Loader { if (data.bindMatrix !== undefined) object.bindMatrix.fromArray(data.bindMatrix); if (data.skeleton !== undefined) object.skeleton = data.skeleton; break; - case 'Mesh': geometry = getGeometry(data.geometry); material = getMaterial(data.material); object = new Mesh(geometry, material); break; - case 'InstancedMesh': geometry = getGeometry(data.geometry); material = getMaterial(data.material); @@ -30693,47 +27836,36 @@ class ObjectLoader extends Loader { object.instanceMatrix = new InstancedBufferAttribute(new Float32Array(instanceMatrix.array), 16); if (instanceColor !== undefined) object.instanceColor = new InstancedBufferAttribute(new Float32Array(instanceColor.array), instanceColor.itemSize); break; - case 'LOD': object = new LOD(); break; - case 'Line': object = new Line(getGeometry(data.geometry), getMaterial(data.material)); break; - case 'LineLoop': object = new LineLoop(getGeometry(data.geometry), getMaterial(data.material)); break; - case 'LineSegments': object = new LineSegments(getGeometry(data.geometry), getMaterial(data.material)); break; - case 'PointCloud': case 'Points': object = new Points(getGeometry(data.geometry), getMaterial(data.material)); break; - case 'Sprite': object = new Sprite(getMaterial(data.material)); break; - case 'Group': object = new Group(); break; - case 'Bone': object = new Bone(); break; - default: object = new Object3D(); } - object.uuid = data.uuid; if (data.name !== undefined) object.name = data.name; - if (data.matrix !== undefined) { object.matrix.fromArray(data.matrix); if (data.matrixAutoUpdate !== undefined) object.matrixAutoUpdate = data.matrixAutoUpdate; @@ -30744,10 +27876,8 @@ class ObjectLoader extends Loader { if (data.quaternion !== undefined) object.quaternion.fromArray(data.quaternion); if (data.scale !== undefined) object.scale.fromArray(data.scale); } - if (data.castShadow !== undefined) object.castShadow = data.castShadow; if (data.receiveShadow !== undefined) object.receiveShadow = data.receiveShadow; - 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; @@ -30755,53 +27885,42 @@ class ObjectLoader extends Loader { 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); } - 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; - if (data.children !== undefined) { const children = data.children; - for (let i = 0; i < children.length; i++) { object.add(this.parseObject(children[i], geometries, materials, textures, animations)); } } - if (data.animations !== undefined) { const objectAnimations = data.animations; - for (let i = 0; i < objectAnimations.length; i++) { const uuid = objectAnimations[i]; object.animations.push(animations[uuid]); } } - if (data.type === 'LOD') { if (data.autoUpdate !== undefined) object.autoUpdate = data.autoUpdate; const levels = data.levels; - for (let l = 0; l < levels.length; l++) { const level = levels[l]; const child = object.getObjectByProperty('uuid', level.object); - if (child !== undefined) { - object.addLevel(child, level.distance); + object.addLevel(child, level.distance, level.hysteresis); } } } - return object; } - bindSkeletons(object, skeletons) { if (Object.keys(skeletons).length === 0) return; object.traverse(function (child) { if (child.isSkinnedMesh === true && child.skeleton !== undefined) { const skeleton = skeletons[child.skeleton]; - if (skeleton === undefined) { console.warn('THREE.ObjectLoader: No skeleton found with UUID:', child.skeleton); } else { @@ -30810,9 +27929,7 @@ class ObjectLoader extends Loader { } }); } - } - const TEXTURE_MAPPING = { UVMapping: UVMapping, CubeReflectionMapping: CubeReflectionMapping, @@ -30839,32 +27956,26 @@ class ImageBitmapLoader extends Loader { constructor(manager) { super(manager); this.isImageBitmapLoader = true; - if (typeof createImageBitmap === 'undefined') { console.warn('THREE.ImageBitmapLoader: createImageBitmap() not supported.'); } - if (typeof fetch === 'undefined') { console.warn('THREE.ImageBitmapLoader: fetch() not supported.'); } - this.options = { premultiplyAlpha: 'none' }; } - setOptions(options) { this.options = options; return this; } - load(url, onLoad, onProgress, onError) { if (url === undefined) url = ''; if (this.path !== undefined) url = this.path + url; url = this.manager.resolveURL(url); const scope = this; const cached = Cache.get(url); - if (cached !== undefined) { scope.manager.itemStart(url); setTimeout(function () { @@ -30873,7 +27984,6 @@ class ImageBitmapLoader extends Loader { }, 0); return cached; } - const fetchOptions = {}; fetchOptions.credentials = this.crossOrigin === 'anonymous' ? 'same-origin' : 'include'; fetchOptions.headers = this.requestHeader; @@ -30894,29 +28004,25 @@ class ImageBitmapLoader extends Loader { }); scope.manager.itemStart(url); } - } let _context; - -const AudioContext = { - getContext: function () { +class AudioContext { + static getContext() { if (_context === undefined) { _context = new (window.AudioContext || window.webkitAudioContext)(); } - return _context; - }, - setContext: function (value) { + } + static setContext(value) { _context = value; } -}; +} class AudioLoader extends Loader { constructor(manager) { super(manager); } - load(url, onLoad, onProgress, onError) { const scope = this; const loader = new FileLoader(this.manager); @@ -30939,12 +28045,10 @@ class AudioLoader extends Loader { } else { console.error(e); } - scope.manager.itemError(url); } }, onProgress, onError); } - } class HemisphereLightProbe extends LightProbe { @@ -30954,33 +28058,30 @@ class HemisphereLightProbe extends LightProbe { const color1 = new Color().set(skyColor); const color2 = new Color().set(groundColor); const sky = new Vector3(color1.r, color1.g, color1.b); - const ground = new Vector3(color2.r, color2.g, color2.b); // without extra factor of PI in the shader, should = 1 / Math.sqrt( Math.PI ); + const ground = new Vector3(color2.r, color2.g, color2.b); + // without extra factor of PI in the shader, should = 1 / Math.sqrt( Math.PI ); const c0 = Math.sqrt(Math.PI); const 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); } - } class AmbientLightProbe extends LightProbe { constructor(color, intensity = 1) { super(undefined, intensity); this.isAmbientLightProbe = true; - const color1 = new Color().set(color); // without extra factor of PI in the shader, would be 2 / Math.sqrt( Math.PI ); + const 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)); } - } const _eyeRight = /*@__PURE__*/new Matrix4(); - const _eyeLeft = /*@__PURE__*/new Matrix4(); - const _projectionMatrix = /*@__PURE__*/new Matrix4(); - class StereoCamera { constructor() { this.type = 'StereoCamera'; @@ -31002,11 +28103,9 @@ class StereoCamera { eyeSep: null }; } - update(camera) { const cache = this._cache; const 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; - if (needsUpdate) { cache.focus = camera.focus; cache.fov = camera.fov; @@ -31014,24 +28113,31 @@ class StereoCamera { cache.near = camera.near; cache.far = camera.far; cache.zoom = camera.zoom; - cache.eyeSep = this.eyeSep; // Off-axis stereoscopic effect based on + cache.eyeSep = this.eyeSep; + + // Off-axis stereoscopic effect based on // http://paulbourke.net/stereographics/stereorender/ _projectionMatrix.copy(camera.projectionMatrix); - const eyeSepHalf = cache.eyeSep / 2; const eyeSepOnProjection = eyeSepHalf * cache.near / cache.focus; const ymax = cache.near * Math.tan(DEG2RAD * cache.fov * 0.5) / cache.zoom; - let xmin, xmax; // translate xOffset + let xmin, xmax; + + // translate xOffset _eyeLeft.elements[12] = -eyeSepHalf; - _eyeRight.elements[12] = eyeSepHalf; // for left eye + _eyeRight.elements[12] = eyeSepHalf; + + // for left eye 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 + this.cameraL.projectionMatrix.copy(_projectionMatrix); + + // for right eye xmin = -ymax * cache.aspect - eyeSepOnProjection; xmax = ymax * cache.aspect - eyeSepOnProjection; @@ -31039,11 +28145,9 @@ class StereoCamera { _projectionMatrix.elements[8] = (xmax + xmin) / (xmax - xmin); this.cameraR.projectionMatrix.copy(_projectionMatrix); } - this.cameraL.matrixWorld.copy(camera.matrixWorld).multiply(_eyeLeft); this.cameraR.matrixWorld.copy(camera.matrixWorld).multiply(_eyeRight); } - } class Clock { @@ -31054,57 +28158,44 @@ class Clock { this.elapsedTime = 0; this.running = false; } - start() { this.startTime = now(); this.oldTime = this.startTime; this.elapsedTime = 0; this.running = true; } - stop() { this.getElapsedTime(); this.running = false; this.autoStart = false; } - getElapsedTime() { this.getDelta(); return this.elapsedTime; } - getDelta() { let diff = 0; - if (this.autoStart && !this.running) { this.start(); return 0; } - if (this.running) { const newTime = now(); diff = (newTime - this.oldTime) / 1000; this.oldTime = newTime; this.elapsedTime += diff; } - return diff; } - } - function now() { return (typeof performance === 'undefined' ? Date : performance).now(); // see #10732 } const _position$1 = /*@__PURE__*/new Vector3(); - const _quaternion$1 = /*@__PURE__*/new Quaternion(); - const _scale$1 = /*@__PURE__*/new Vector3(); - const _orientation$1 = /*@__PURE__*/new Vector3(); - class AudioListener extends Object3D { constructor() { super(); @@ -31113,15 +28204,15 @@ class AudioListener extends Object3D { this.gain = this.context.createGain(); this.gain.connect(this.context.destination); this.filter = null; - this.timeDelta = 0; // private + this.timeDelta = 0; + + // private this._clock = new Clock(); } - getInput() { return this.gain; } - removeFilter() { if (this.filter !== null) { this.gain.disconnect(this.filter); @@ -31129,14 +28220,11 @@ class AudioListener extends Object3D { this.gain.connect(this.context.destination); this.filter = null; } - return this; } - getFilter() { return this.filter; } - setFilter(value) { if (this.filter !== null) { this.gain.disconnect(this.filter); @@ -31144,33 +28232,28 @@ class AudioListener extends Object3D { } else { this.gain.disconnect(this.context.destination); } - this.filter = value; this.gain.connect(this.filter); this.filter.connect(this.context.destination); return this; } - getMasterVolume() { return this.gain.gain.value; } - setMasterVolume(value) { this.gain.gain.setTargetAtTime(value, this.context.currentTime, 0.01); return this; } - updateMatrixWorld(force) { super.updateMatrixWorld(force); const listener = this.context.listener; const up = this.up; this.timeDelta = this._clock.getDelta(); this.matrixWorld.decompose(_position$1, _quaternion$1, _scale$1); - _orientation$1.set(0, 0, -1).applyQuaternion(_quaternion$1); - if (listener.positionX) { // code path for Chrome (see #14393) + const endTime = this.context.currentTime + this.timeDelta; listener.positionX.linearRampToValueAtTime(_position$1.x, endTime); listener.positionY.linearRampToValueAtTime(_position$1.y, endTime); @@ -31186,7 +28269,6 @@ class AudioListener extends Object3D { listener.setOrientation(_orientation$1.x, _orientation$1.y, _orientation$1.z, up.x, up.y, up.z); } } - } class Audio extends Object3D { @@ -31215,11 +28297,9 @@ class Audio extends Object3D { this._connected = false; this.filters = []; } - getOutput() { return this.gain; } - setNodeSource(audioNode) { this.hasPlaybackControl = false; this.sourceType = 'audioNode'; @@ -31227,7 +28307,6 @@ class Audio extends Object3D { this.connect(); return this; } - setMediaElementSource(mediaElement) { this.hasPlaybackControl = false; this.sourceType = 'mediaNode'; @@ -31235,7 +28314,6 @@ class Audio extends Object3D { this.connect(); return this; } - setMediaStreamSource(mediaStream) { this.hasPlaybackControl = false; this.sourceType = 'mediaStreamNode'; @@ -31243,25 +28321,21 @@ class Audio extends Object3D { this.connect(); return this; } - setBuffer(audioBuffer) { this.buffer = audioBuffer; this.sourceType = 'buffer'; if (this.autoplay) this.play(); return this; } - play(delay = 0) { 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; } - this._startedAt = this.context.currentTime + delay; const source = this.context.createBufferSource(); source.buffer = this.buffer; @@ -31276,84 +28350,68 @@ class Audio extends Object3D { this.setPlaybackRate(this.playbackRate); return this.connect(); } - pause() { if (this.hasPlaybackControl === false) { console.warn('THREE.Audio: this Audio has no playback control.'); return; } - if (this.isPlaying === true) { // update current progress - this._progress += Math.max(this.context.currentTime - this._startedAt, 0) * this.playbackRate; + this._progress += Math.max(this.context.currentTime - this._startedAt, 0) * this.playbackRate; if (this.loop === true) { // ensure _progress does not exceed duration with looped audios + this._progress = this._progress % (this.duration || this.buffer.duration); } - this.source.stop(); this.source.onended = null; this.isPlaying = false; } - return this; } - stop() { if (this.hasPlaybackControl === false) { console.warn('THREE.Audio: this Audio has no playback control.'); return; } - this._progress = 0; this.source.stop(); this.source.onended = null; this.isPlaying = false; return this; } - connect() { if (this.filters.length > 0) { this.source.connect(this.filters[0]); - for (let i = 1, l = this.filters.length; i < l; i++) { this.filters[i - 1].connect(this.filters[i]); } - this.filters[this.filters.length - 1].connect(this.getOutput()); } else { this.source.connect(this.getOutput()); } - this._connected = true; return this; } - disconnect() { if (this.filters.length > 0) { this.source.disconnect(this.filters[0]); - for (let i = 1, l = this.filters.length; i < l; i++) { this.filters[i - 1].disconnect(this.filters[i]); } - this.filters[this.filters.length - 1].disconnect(this.getOutput()); } else { this.source.disconnect(this.getOutput()); } - this._connected = false; return this; } - getFilters() { return this.filters; } - setFilters(value) { if (!value) value = []; - if (this._connected === true) { this.disconnect(); this.filters = value.slice(); @@ -31361,10 +28419,8 @@ class Audio extends Object3D { } else { this.filters = value.slice(); } - return this; } - setDetune(value) { this.detune = value; if (this.source.detune === undefined) return; // only set detune when available @@ -31372,98 +28428,73 @@ class Audio extends Object3D { if (this.isPlaying === true) { this.source.detune.setTargetAtTime(this.detune, this.context.currentTime, 0.01); } - return this; } - getDetune() { return this.detune; } - getFilter() { return this.getFilters()[0]; } - setFilter(filter) { return this.setFilters(filter ? [filter] : []); } - setPlaybackRate(value) { if (this.hasPlaybackControl === false) { console.warn('THREE.Audio: this Audio has no playback control.'); return; } - this.playbackRate = value; - if (this.isPlaying === true) { this.source.playbackRate.setTargetAtTime(this.playbackRate, this.context.currentTime, 0.01); } - return this; } - getPlaybackRate() { return this.playbackRate; } - onEnded() { this.isPlaying = false; } - getLoop() { if (this.hasPlaybackControl === false) { console.warn('THREE.Audio: this Audio has no playback control.'); return false; } - return this.loop; } - setLoop(value) { if (this.hasPlaybackControl === false) { console.warn('THREE.Audio: this Audio has no playback control.'); return; } - this.loop = value; - if (this.isPlaying === true) { this.source.loop = this.loop; } - return this; } - setLoopStart(value) { this.loopStart = value; return this; } - setLoopEnd(value) { this.loopEnd = value; return this; } - getVolume() { return this.gain.gain.value; } - setVolume(value) { this.gain.gain.setTargetAtTime(value, this.context.currentTime, 0.01); return this; } - } const _position = /*@__PURE__*/new Vector3(); - const _quaternion = /*@__PURE__*/new Quaternion(); - const _scale = /*@__PURE__*/new Vector3(); - const _orientation = /*@__PURE__*/new Vector3(); - class PositionalAudio extends Audio { constructor(listener) { super(listener); @@ -31471,70 +28502,56 @@ class PositionalAudio extends Audio { this.panner.panningModel = 'HRTF'; this.panner.connect(this.gain); } - disconnect() { super.disconnect(); this.panner.disconnect(this.gain); } - getOutput() { return this.panner; } - getRefDistance() { return this.panner.refDistance; } - setRefDistance(value) { this.panner.refDistance = value; return this; } - getRolloffFactor() { return this.panner.rolloffFactor; } - setRolloffFactor(value) { this.panner.rolloffFactor = value; return this; } - getDistanceModel() { return this.panner.distanceModel; } - setDistanceModel(value) { this.panner.distanceModel = value; return this; } - getMaxDistance() { return this.panner.maxDistance; } - setMaxDistance(value) { this.panner.maxDistance = value; return this; } - setDirectionalCone(coneInnerAngle, coneOuterAngle, coneOuterGain) { this.panner.coneInnerAngle = coneInnerAngle; this.panner.coneOuterAngle = coneOuterAngle; this.panner.coneOuterGain = coneOuterGain; return this; } - updateMatrixWorld(force) { super.updateMatrixWorld(force); if (this.hasPlaybackControl === true && this.isPlaying === false) return; this.matrixWorld.decompose(_position, _quaternion, _scale); - _orientation.set(0, 0, 1).applyQuaternion(_quaternion); - const panner = this.panner; - if (panner.positionX) { // code path for Chrome and Firefox (see #14393) + const endTime = this.context.currentTime + this.listener.timeDelta; panner.positionX.linearRampToValueAtTime(_position.x, endTime); panner.positionY.linearRampToValueAtTime(_position.y, endTime); @@ -31547,7 +28564,6 @@ class PositionalAudio extends Audio { panner.setOrientation(_orientation.x, _orientation.y, _orientation.z); } } - } class AudioAnalyser { @@ -31557,30 +28573,27 @@ class AudioAnalyser { this.data = new Uint8Array(this.analyser.frequencyBinCount); audio.getOutput().connect(this.analyser); } - getFrequencyData() { this.analyser.getByteFrequencyData(this.data); return this.data; } - getAverageFrequency() { let value = 0; const data = this.getFrequencyData(); - for (let i = 0; i < data.length; i++) { value += data[i]; } - return value / data.length; } - } class PropertyMixer { constructor(binding, typeName, valueSize) { this.binding = binding; this.valueSize = valueSize; - let mixFunction, mixFunctionAdditive, setIdentity; // buffer layout: [ incoming | accu0 | accu1 | orig | addAccu | (optional work) ] + let 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' @@ -31604,24 +28617,22 @@ class PropertyMixer { this.buffer = new Float64Array(valueSize * 6); this._workIndex = 5; break; - 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 + mixFunction = this._select; + // Use the regular mix function and for additive on these types, + // additive is not relevant for non-numeric types mixFunctionAdditive = this._select; setIdentity = this._setAdditiveIdentityOther; this.buffer = new Array(valueSize * 5); break; - 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; @@ -31631,133 +28642,126 @@ class PropertyMixer { this.cumulativeWeightAdditive = 0; this.useCount = 0; this.referenceCount = 0; - } // accumulate data in the 'incoming' region into 'accu' - + } + // accumulate data in the 'incoming' region into 'accu' 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 + const buffer = this.buffer, - stride = this.valueSize, - offset = accuIndex * stride + stride; + stride = this.valueSize, + offset = accuIndex * stride + stride; let currentWeight = this.cumulativeWeight; - if (currentWeight === 0) { // accuN := incoming * weight + for (let i = 0; i !== stride; ++i) { buffer[offset + i] = buffer[i]; } - currentWeight = weight; } else { // accuN := accuN + incoming * weight + currentWeight += weight; const mix = weight / currentWeight; - this._mixBufferRegion(buffer, offset, 0, mix, stride); } - this.cumulativeWeight = currentWeight; - } // accumulate data in the 'incoming' region into 'add' - + } + // accumulate data in the 'incoming' region into 'add' accumulateAdditive(weight) { const buffer = this.buffer, - stride = this.valueSize, - offset = stride * this._addIndex; - + stride = this.valueSize, + offset = stride * this._addIndex; if (this.cumulativeWeightAdditive === 0) { // add = identity + this._setIdentity(); - } // add := add + incoming * weight + } + // add := add + incoming * weight this._mixBufferRegionAdditive(buffer, offset, 0, weight, stride); - this.cumulativeWeightAdditive += weight; - } // apply the state of 'accu' to the binding when accus differ - + } + // apply the state of 'accu' to the binding when accus differ apply(accuIndex) { const stride = this.valueSize, - buffer = this.buffer, - offset = accuIndex * stride + stride, - weight = this.cumulativeWeight, - weightAdditive = this.cumulativeWeightAdditive, - binding = this.binding; + buffer = this.buffer, + offset = accuIndex * stride + stride, + weight = this.cumulativeWeight, + weightAdditive = this.cumulativeWeightAdditive, + binding = this.binding; this.cumulativeWeight = 0; this.cumulativeWeightAdditive = 0; - if (weight < 1) { // accuN := accuN + original * ( 1 - cumulativeWeight ) - const originalValueOffset = stride * this._origIndex; + const originalValueOffset = stride * this._origIndex; this._mixBufferRegion(buffer, offset, originalValueOffset, 1 - weight, stride); } - if (weightAdditive > 0) { // accuN := accuN + additive accuN + this._mixBufferRegionAdditive(buffer, offset, this._addIndex * stride, 1, stride); } - for (let 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 - + } + // remember the state of the bound property and copy it to both accus saveOriginalState() { const binding = this.binding; const buffer = this.buffer, - stride = this.valueSize, - originalValueOffset = stride * this._origIndex; - binding.getValue(buffer, originalValueOffset); // accu[0..1] := orig -- initially detect changes against the original + stride = this.valueSize, + originalValueOffset = stride * this._origIndex; + binding.getValue(buffer, originalValueOffset); + // accu[0..1] := orig -- initially detect changes against the original for (let i = stride, e = originalValueOffset; i !== e; ++i) { buffer[i] = buffer[originalValueOffset + i % stride]; - } // Add to identity for additive - + } + // Add to identity for additive this._setIdentity(); - this.cumulativeWeight = 0; this.cumulativeWeightAdditive = 0; - } // apply the state previously taken via 'saveOriginalState' to the binding - + } + // apply the state previously taken via 'saveOriginalState' to the binding restoreOriginalState() { const originalValueOffset = this.valueSize * 3; this.binding.setValue(this.buffer, originalValueOffset); } - _setAdditiveIdentityNumeric() { const startIndex = this._addIndex * this.valueSize; const endIndex = startIndex + this.valueSize; - for (let i = startIndex; i < endIndex; i++) { this.buffer[i] = 0; } } - _setAdditiveIdentityQuaternion() { this._setAdditiveIdentityNumeric(); - this.buffer[this._addIndex * this.valueSize + 3] = 1; } - _setAdditiveIdentityOther() { const startIndex = this._origIndex * this.valueSize; const targetIndex = this._addIndex * this.valueSize; - for (let i = 0; i < this.valueSize; i++) { this.buffer[targetIndex + i] = this.buffer[startIndex + i]; } - } // mix functions + } + // mix functions _select(buffer, dstOffset, srcOffset, t, stride) { if (t >= 0.5) { @@ -31766,126 +28770,110 @@ class PropertyMixer { } } } - _slerp(buffer, dstOffset, srcOffset, t) { Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t); } - _slerpAdditive(buffer, dstOffset, srcOffset, t, stride) { - const workOffset = this._workIndex * stride; // Store result in intermediate buffer offset + const workOffset = this._workIndex * stride; - Quaternion.multiplyQuaternionsFlat(buffer, workOffset, buffer, dstOffset, buffer, srcOffset); // Slerp to the intermediate result + // Store result in intermediate buffer offset + Quaternion.multiplyQuaternionsFlat(buffer, workOffset, buffer, dstOffset, buffer, srcOffset); + // Slerp to the intermediate result Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, workOffset, t); } - _lerp(buffer, dstOffset, srcOffset, t, stride) { const s = 1 - t; - for (let i = 0; i !== stride; ++i) { const j = dstOffset + i; buffer[j] = buffer[j] * s + buffer[srcOffset + i] * t; } } - _lerpAdditive(buffer, dstOffset, srcOffset, t, stride) { for (let i = 0; i !== stride; ++i) { const j = dstOffset + i; buffer[j] = buffer[j] + buffer[srcOffset + i] * t; } } - } // Characters [].:/ are reserved for track binding syntax. const _RESERVED_CHARS_RE = '\\[\\]\\.:\\/'; +const _reservedRe = new RegExp('[' + _RESERVED_CHARS_RE + ']', 'g'); -const _reservedRe = new RegExp('[' + _RESERVED_CHARS_RE + ']', 'g'); // Attempts to allow node names from any language. ES5's `\w` regexp matches +// 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. - - const _wordChar = '[^' + _RESERVED_CHARS_RE + ']'; +const _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace('\\.', '') + ']'; -const _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace('\\.', '') + ']'; // Parent directories, delimited by '/' or ':'. Currently unused, but must +// Parent directories, delimited by '/' or ':'. Currently unused, but must // be matched to parse the rest of the track name. +const _directoryRe = /*@__PURE__*/ /((?:WC+[\/:])*)/.source.replace('WC', _wordChar); +// Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'. +const _nodeRe = /*@__PURE__*/ /(WCOD+)?/.source.replace('WCOD', _wordCharOrDot); -const _directoryRe = /*@__PURE__*/ /((?:WC+[\/:])*)/.source.replace('WC', _wordChar); // Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'. - - -const _nodeRe = /*@__PURE__*/ /(WCOD+)?/.source.replace('WCOD', _wordCharOrDot); // Object on target node, and accessor. May not contain reserved +// Object on target node, and accessor. May not contain reserved // characters. Accessor may contain any character except closing bracket. +const _objectRe = /*@__PURE__*/ /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace('WC', _wordChar); - -const _objectRe = /*@__PURE__*/ /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace('WC', _wordChar); // Property and accessor. May not contain reserved characters. Accessor may +// Property and accessor. May not contain reserved characters. Accessor may // contain any non-bracket characters. - - const _propertyRe = /*@__PURE__*/ /\.(WC+)(?:\[(.+)\])?/.source.replace('WC', _wordChar); - const _trackRe = new RegExp('' + '^' + _directoryRe + _nodeRe + _objectRe + _propertyRe + '$'); - -const _supportedObjectNames = ['material', 'materials', 'bones']; - +const _supportedObjectNames = ['material', 'materials', 'bones', 'map']; class Composite { constructor(targetGroup, path, optionalParsedPath) { const parsedPath = optionalParsedPath || PropertyBinding.parseTrackName(path); this._targetGroup = targetGroup; this._bindings = targetGroup.subscribe_(path, parsedPath); } - getValue(array, offset) { this.bind(); // bind all binding const firstValidIndex = this._targetGroup.nCachedObjects_, - binding = this._bindings[firstValidIndex]; // and only call .getValue on the first + binding = this._bindings[firstValidIndex]; + // and only call .getValue on the first if (binding !== undefined) binding.getValue(array, offset); } - setValue(array, offset) { const bindings = this._bindings; - for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { bindings[i].setValue(array, offset); } } - bind() { const bindings = this._bindings; - for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { bindings[i].bind(); } } - unbind() { const bindings = this._bindings; - for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { bindings[i].unbind(); } } +} -} // Note: This class uses a State pattern on a per-method basis: +// 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. - - class PropertyBinding { constructor(rootNode, path, parsedPath) { this.path = path; this.parsedPath = parsedPath || PropertyBinding.parseTrackName(path); this.node = PropertyBinding.findNode(rootNode, this.parsedPath.nodeName) || rootNode; - this.rootNode = rootNode; // initial state of these methods that calls 'bind' + this.rootNode = rootNode; + // initial state of these methods that calls 'bind' this.getValue = this._getValue_unbound; this.setValue = this._setValue_unbound; } - static create(root, path, parsedPath) { if (!(root && root.isAnimationObjectGroup)) { return new PropertyBinding(root, path, parsedPath); @@ -31893,6 +28881,7 @@ class PropertyBinding { return new PropertyBinding.Composite(root, path, parsedPath); } } + /** * Replaces spaces with underscores and removes unsupported characters from * node names, to ensure compatibility with parseTrackName(). @@ -31900,19 +28889,14 @@ class PropertyBinding { * @param {string} name Node name to be sanitized. * @return {string} */ - - static sanitizeNodeName(name) { return name.replace(/\s/g, '_').replace(_reservedRe, ''); } - static parseTrackName(trackName) { const matches = _trackRe.exec(trackName); - if (matches === null) { throw new Error('PropertyBinding: Cannot parse trackName: ' + trackName); } - const results = { // directoryName: matches[ 1 ], // (tschw) currently unused nodeName: matches[2], @@ -31923,304 +28907,287 @@ class PropertyBinding { propertyIndex: matches[6] }; const lastDot = results.nodeName && results.nodeName.lastIndexOf('.'); - if (lastDot !== undefined && lastDot !== -1) { - const objectName = results.nodeName.substring(lastDot + 1); // Object names must be checked against an allowlist. Otherwise, there + const 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). - if (_supportedObjectNames.indexOf(objectName) !== -1) { results.nodeName = results.nodeName.substring(0, lastDot); results.objectName = objectName; } } - if (results.propertyName === null || results.propertyName.length === 0) { throw new Error('PropertyBinding: can not parse propertyName from trackName: ' + trackName); } - return results; } - static findNode(root, nodeName) { if (nodeName === undefined || nodeName === '' || nodeName === '.' || nodeName === -1 || nodeName === root.name || nodeName === root.uuid) { return root; - } // search into skeleton bones. - + } + // search into skeleton bones. if (root.skeleton) { const bone = root.skeleton.getBoneByName(nodeName); - if (bone !== undefined) { return bone; } - } // search into node subtree. - + } + // search into node subtree. if (root.children) { const searchNodeSubtree = function (children) { for (let i = 0; i < children.length; i++) { const childNode = children[i]; - if (childNode.name === nodeName || childNode.uuid === nodeName) { return childNode; } - const result = searchNodeSubtree(childNode.children); if (result) return result; } - return null; }; - const subTreeNode = searchNodeSubtree(root.children); - if (subTreeNode) { return subTreeNode; } } - return null; - } // these are used to "bind" a nonexistent property - + } + // these are used to "bind" a nonexistent property _getValue_unavailable() {} + _setValue_unavailable() {} - _setValue_unavailable() {} // Getters - + // Getters _getValue_direct(buffer, offset) { buffer[offset] = this.targetObject[this.propertyName]; } - _getValue_array(buffer, offset) { const source = this.resolvedProperty; - for (let i = 0, n = source.length; i !== n; ++i) { buffer[offset++] = source[i]; } } - _getValue_arrayElement(buffer, offset) { buffer[offset] = this.resolvedProperty[this.propertyIndex]; } - _getValue_toArray(buffer, offset) { this.resolvedProperty.toArray(buffer, offset); - } // Direct + } + // Direct _setValue_direct(buffer, offset) { this.targetObject[this.propertyName] = buffer[offset]; } - _setValue_direct_setNeedsUpdate(buffer, offset) { this.targetObject[this.propertyName] = buffer[offset]; this.targetObject.needsUpdate = true; } - _setValue_direct_setMatrixWorldNeedsUpdate(buffer, offset) { this.targetObject[this.propertyName] = buffer[offset]; this.targetObject.matrixWorldNeedsUpdate = true; - } // EntireArray + } + // EntireArray _setValue_array(buffer, offset) { const dest = this.resolvedProperty; - for (let i = 0, n = dest.length; i !== n; ++i) { dest[i] = buffer[offset++]; } } - _setValue_array_setNeedsUpdate(buffer, offset) { const dest = this.resolvedProperty; - for (let i = 0, n = dest.length; i !== n; ++i) { dest[i] = buffer[offset++]; } - this.targetObject.needsUpdate = true; } - _setValue_array_setMatrixWorldNeedsUpdate(buffer, offset) { const dest = this.resolvedProperty; - for (let i = 0, n = dest.length; i !== n; ++i) { dest[i] = buffer[offset++]; } - this.targetObject.matrixWorldNeedsUpdate = true; - } // ArrayElement + } + // ArrayElement _setValue_arrayElement(buffer, offset) { this.resolvedProperty[this.propertyIndex] = buffer[offset]; } - _setValue_arrayElement_setNeedsUpdate(buffer, offset) { this.resolvedProperty[this.propertyIndex] = buffer[offset]; this.targetObject.needsUpdate = true; } - _setValue_arrayElement_setMatrixWorldNeedsUpdate(buffer, offset) { this.resolvedProperty[this.propertyIndex] = buffer[offset]; this.targetObject.matrixWorldNeedsUpdate = true; - } // HasToFromArray + } + // HasToFromArray _setValue_fromArray(buffer, offset) { this.resolvedProperty.fromArray(buffer, offset); } - _setValue_fromArray_setNeedsUpdate(buffer, offset) { this.resolvedProperty.fromArray(buffer, offset); this.targetObject.needsUpdate = true; } - _setValue_fromArray_setMatrixWorldNeedsUpdate(buffer, offset) { this.resolvedProperty.fromArray(buffer, offset); this.targetObject.matrixWorldNeedsUpdate = true; } - _getValue_unbound(targetArray, offset) { this.bind(); this.getValue(targetArray, offset); } - _setValue_unbound(sourceArray, offset) { this.bind(); this.setValue(sourceArray, offset); - } // create getter / setter pair for a property in the scene graph - + } + // create getter / setter pair for a property in the scene graph bind() { let targetObject = this.node; const parsedPath = this.parsedPath; const objectName = parsedPath.objectName; const propertyName = parsedPath.propertyName; let propertyIndex = parsedPath.propertyIndex; - if (!targetObject) { targetObject = PropertyBinding.findNode(this.rootNode, parsedPath.nodeName) || this.rootNode; this.node = targetObject; - } // set fail state so we can just 'return' on error - + } + // set fail state so we can just 'return' on error this.getValue = this._getValue_unavailable; - this.setValue = this._setValue_unavailable; // ensure there is a value node + this.setValue = this._setValue_unavailable; + // ensure there is a value node if (!targetObject) { console.error('THREE.PropertyBinding: Trying to update node for track: ' + this.path + ' but it wasn\'t found.'); return; } - if (objectName) { - let objectIndex = parsedPath.objectIndex; // special cases were we need to reach deeper into the hierarchy to get the face materials.... + let 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; } - 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; } - targetObject = targetObject.material.materials; break; - 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. + } + // potential future optimization: skip this if propertyIndex is already an integer + // and convert the integer string to a true integer. - targetObject = targetObject.skeleton.bones; // support resolving morphTarget names into indices. + targetObject = targetObject.skeleton.bones; + // support resolving morphTarget names into indices. for (let i = 0; i < targetObject.length; i++) { if (targetObject[i].name === objectIndex) { objectIndex = i; break; } } - break; - + case 'map': + if ('map' in targetObject) { + targetObject = targetObject.map; + break; + } + if (!targetObject.material) { + console.error('THREE.PropertyBinding: Can not bind to material as node does not have a material.', this); + return; + } + if (!targetObject.material.map) { + console.error('THREE.PropertyBinding: Can not bind to material.map as node.material does not have a map.', this); + return; + } + targetObject = targetObject.material.map; + break; default: if (targetObject[objectName] === undefined) { console.error('THREE.PropertyBinding: Can not bind to objectName of node undefined.', this); return; } - targetObject = targetObject[objectName]; } - if (objectIndex !== undefined) { if (targetObject[objectIndex] === undefined) { console.error('THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject); return; } - targetObject = targetObject[objectIndex]; } - } // resolve property - + } + // resolve property const nodeProperty = targetObject[propertyName]; - if (nodeProperty === undefined) { const 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 - + } + // determine versioning scheme let versioning = this.Versioning.None; this.targetObject = targetObject; - 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 + versioning = this.Versioning.MatrixWorldNeedsUpdate; + } + // determine how the property gets bound let bindingType = this.BindingType.Direct; - 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; } - 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]; } } - 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)) { @@ -32228,23 +29195,21 @@ class PropertyBinding { this.resolvedProperty = nodeProperty; } else { this.propertyName = propertyName; - } // select getter / setter - + } + // select getter / setter this.getValue = this.GetterByBindingType[bindingType]; this.setValue = this.SetterByBindingTypeAndVersioning[bindingType][versioning]; } - unbind() { - this.node = null; // back to the prototype version of getValue / setValue - // note: avoiding to mutate the shape of 'this' via 'delete' + this.node = null; + // back to the prototype version of getValue / setValue + // note: avoiding to mutate the shape of 'this' via 'delete' this.getValue = this._getValue_unbound; this.setValue = this._setValue_unbound; } - } - PropertyBinding.Composite = Composite; PropertyBinding.prototype.BindingType = { Direct: 0, @@ -32258,10 +29223,15 @@ PropertyBinding.prototype.Versioning = { MatrixWorldNeedsUpdate: 2 }; PropertyBinding.prototype.GetterByBindingType = [PropertyBinding.prototype._getValue_direct, PropertyBinding.prototype._getValue_array, PropertyBinding.prototype._getValue_arrayElement, PropertyBinding.prototype._getValue_toArray]; -PropertyBinding.prototype.SetterByBindingTypeAndVersioning = [[// Direct -PropertyBinding.prototype._setValue_direct, PropertyBinding.prototype._setValue_direct_setNeedsUpdate, PropertyBinding.prototype._setValue_direct_setMatrixWorldNeedsUpdate], [// EntireArray -PropertyBinding.prototype._setValue_array, PropertyBinding.prototype._setValue_array_setNeedsUpdate, PropertyBinding.prototype._setValue_array_setMatrixWorldNeedsUpdate], [// ArrayElement -PropertyBinding.prototype._setValue_arrayElement, PropertyBinding.prototype._setValue_arrayElement_setNeedsUpdate, PropertyBinding.prototype._setValue_arrayElement_setMatrixWorldNeedsUpdate], [// HasToFromArray +PropertyBinding.prototype.SetterByBindingTypeAndVersioning = [[ +// Direct +PropertyBinding.prototype._setValue_direct, PropertyBinding.prototype._setValue_direct_setNeedsUpdate, PropertyBinding.prototype._setValue_direct_setMatrixWorldNeedsUpdate], [ +// EntireArray + +PropertyBinding.prototype._setValue_array, PropertyBinding.prototype._setValue_array_setNeedsUpdate, PropertyBinding.prototype._setValue_array_setMatrixWorldNeedsUpdate], [ +// ArrayElement +PropertyBinding.prototype._setValue_arrayElement, PropertyBinding.prototype._setValue_arrayElement_setNeedsUpdate, PropertyBinding.prototype._setValue_arrayElement_setMatrixWorldNeedsUpdate], [ +// HasToFromArray PropertyBinding.prototype._setValue_fromArray, PropertyBinding.prototype._setValue_fromArray_setNeedsUpdate, PropertyBinding.prototype._setValue_fromArray_setMatrixWorldNeedsUpdate]]; /** @@ -32296,8 +29266,9 @@ PropertyBinding.prototype._setValue_fromArray, PropertyBinding.prototype._setVal class AnimationObjectGroup { constructor() { this.isAnimationObjectGroup = true; - this.uuid = generateUUID(); // cached objects followed by the active ones + this.uuid = generateUUID(); + // cached objects followed by the active ones this._objects = Array.prototype.slice.call(arguments); this.nCachedObjects_ = 0; // threshold // note: read by PropertyBinding.Composite @@ -32308,13 +29279,9 @@ class AnimationObjectGroup { for (let i = 0, n = arguments.length; i !== n; ++i) { indices[arguments[i].uuid] = i; } - this._paths = []; // inside: string - this._parsedPaths = []; // inside: { we don't care, here } - this._bindings = []; // inside: Array< PropertyBinding > - this._bindingsIndicesByPath = {}; // inside: indices in these arrays const scope = this; @@ -32323,165 +29290,164 @@ class AnimationObjectGroup { get total() { return scope._objects.length; }, - get inUse() { return this.total - scope.nCachedObjects_; } - }, - get bindingsPerObject() { return scope._bindings.length; } - }; } - add() { const objects = this._objects, - indicesByUUID = this._indicesByUUID, - paths = this._paths, - parsedPaths = this._parsedPaths, - bindings = this._bindings, - nBindings = bindings.length; + indicesByUUID = this._indicesByUUID, + paths = this._paths, + parsedPaths = this._parsedPaths, + bindings = this._bindings, + nBindings = bindings.length; let knownObject = undefined, - nObjects = objects.length, - nCachedObjects = this.nCachedObjects_; - + nObjects = objects.length, + nCachedObjects = this.nCachedObjects_; for (let i = 0, n = arguments.length; i !== n; ++i) { const object = arguments[i], - uuid = object.uuid; + uuid = object.uuid; let 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 + objects.push(object); + + // accounting is done, now do the same for all bindings for (let 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 + knownObject = objects[index]; + + // move existing object to the ACTIVE region const firstActiveIndex = --nCachedObjects, - lastCachedObject = objects[firstActiveIndex]; + 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 + objects[firstActiveIndex] = object; + + // accounting is done, now do the same for all bindings for (let j = 0, m = nBindings; j !== m; ++j) { const bindingsForPath = bindings[j], - lastCached = bindingsForPath[firstActiveIndex]; + lastCached = bindingsForPath[firstActiveIndex]; let 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]); } - 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 - this.nCachedObjects_ = nCachedObjects; } - remove() { const objects = this._objects, - indicesByUUID = this._indicesByUUID, - bindings = this._bindings, - nBindings = bindings.length; + indicesByUUID = this._indicesByUUID, + bindings = this._bindings, + nBindings = bindings.length; let nCachedObjects = this.nCachedObjects_; - for (let i = 0, n = arguments.length; i !== n; ++i) { const object = arguments[i], - uuid = object.uuid, - index = indicesByUUID[uuid]; - + uuid = object.uuid, + index = indicesByUUID[uuid]; if (index !== undefined && index >= nCachedObjects) { // move existing object into the CACHED region + const lastCachedIndex = nCachedObjects++, - firstActiveObject = objects[lastCachedIndex]; + 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 + objects[lastCachedIndex] = object; + + // accounting is done, now do the same for all bindings for (let j = 0, m = nBindings; j !== m; ++j) { const bindingsForPath = bindings[j], - firstActive = bindingsForPath[lastCachedIndex], - binding = bindingsForPath[index]; + firstActive = bindingsForPath[lastCachedIndex], + binding = bindingsForPath[index]; bindingsForPath[index] = firstActive; bindingsForPath[lastCachedIndex] = binding; } } } // for arguments - this.nCachedObjects_ = nCachedObjects; - } // remove & forget - + } + // remove & forget uncache() { const objects = this._objects, - indicesByUUID = this._indicesByUUID, - bindings = this._bindings, - nBindings = bindings.length; + indicesByUUID = this._indicesByUUID, + bindings = this._bindings, + nBindings = bindings.length; let nCachedObjects = this.nCachedObjects_, - nObjects = objects.length; - + nObjects = objects.length; for (let i = 0, n = arguments.length; i !== n; ++i) { const object = arguments[i], - uuid = object.uuid, - index = indicesByUUID[uuid]; - + uuid = object.uuid, + index = indicesByUUID[uuid]; if (index !== undefined) { delete indicesByUUID[uuid]; - if (index < nCachedObjects) { // object is cached, shrink the CACHED region + const firstActiveIndex = --nCachedObjects, - lastCachedObject = objects[firstActiveIndex], - lastIndex = --nObjects, - lastObject = objects[lastIndex]; // last cached object takes this object's place + 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 + 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 + objects.pop(); + + // accounting is done, now do the same for all bindings for (let j = 0, m = nBindings; j !== m; ++j) { const bindingsForPath = bindings[j], - lastCached = bindingsForPath[firstActiveIndex], - last = bindingsForPath[lastIndex]; + 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 - const lastIndex = --nObjects, - lastObject = objects[lastIndex]; + const lastIndex = --nObjects, + lastObject = objects[lastIndex]; if (lastIndex > 0) { indicesByUUID[lastObject.uuid] = index; } - objects[index] = lastObject; - objects.pop(); // accounting is done, now do the same for all bindings + objects.pop(); + + // accounting is done, now do the same for all bindings for (let j = 0, m = nBindings; j !== m; ++j) { const bindingsForPath = bindings[j]; @@ -32489,56 +29455,52 @@ class AnimationObjectGroup { bindingsForPath.pop(); } } // cached or active - } // if object is known - } // for arguments - this.nCachedObjects_ = nCachedObjects; - } // Internal interface used by befriended PropertyBinding.Composite: + } + // Internal interface used by befriended PropertyBinding.Composite: subscribe_(path, parsedPath) { // returns an array of bindings for the given path that is changed // according to the contained objects in the group + const indicesByPath = this._bindingsIndicesByPath; let index = indicesByPath[path]; const bindings = this._bindings; if (index !== undefined) return bindings[index]; const paths = this._paths, - parsedPaths = this._parsedPaths, - objects = this._objects, - nObjects = objects.length, - nCachedObjects = this.nCachedObjects_, - bindingsForPath = new Array(nObjects); + 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 (let i = nCachedObjects, n = objects.length; i !== n; ++i) { const object = objects[i]; bindingsForPath[i] = new PropertyBinding(object, path, parsedPath); } - return bindingsForPath; } - unsubscribe_(path) { // tells the group to forget about a property path and no longer // update the array previously obtained with 'subscribe_' - const indicesByPath = this._bindingsIndicesByPath, - index = indicesByPath[path]; + const indicesByPath = this._bindingsIndicesByPath, + index = indicesByPath[path]; if (index !== undefined) { const paths = this._paths, - parsedPaths = this._parsedPaths, - bindings = this._bindings, - lastBindingsIndex = bindings.length - 1, - lastBindings = bindings[lastBindingsIndex], - lastBindingsPath = path[lastBindingsIndex]; + parsedPaths = this._parsedPaths, + bindings = this._bindings, + lastBindingsIndex = bindings.length - 1, + lastBindings = bindings[lastBindingsIndex], + lastBindingsPath = path[lastBindingsIndex]; indicesByPath[lastBindingsPath] = index; bindings[index] = lastBindings; bindings.pop(); @@ -32548,7 +29510,6 @@ class AnimationObjectGroup { paths.pop(); } } - } class AnimationAction { @@ -32558,37 +29519,36 @@ class AnimationAction { this._localRoot = localRoot; this.blendMode = blendMode; const tracks = clip.tracks, - nTracks = tracks.length, - interpolants = new Array(nTracks); + nTracks = tracks.length, + interpolants = new Array(nTracks); const interpolantSettings = { endingStart: ZeroCurvatureEnding, endingEnd: ZeroCurvatureEnding }; - for (let i = 0; i !== nTracks; ++i) { const interpolant = tracks[i].createInterpolant(null); interpolants[i] = interpolant; interpolant.settings = interpolantSettings; } - this._interpolantSettings = interpolantSettings; this._interpolants = interpolants; // bound by the mixer - // inside: PropertyMixer (managed by the mixer) + // inside: PropertyMixer (managed by the mixer) this._propertyBindings = new Array(nTracks); this._cacheIndex = null; // for the memory manager - this._byClipCacheIndex = null; // for the memory manager this._timeScaleInterpolant = null; this._weightInterpolant = null; this.loop = LoopRepeat; - this._loopCount = -1; // global mixer time when the action is to be started + this._loopCount = -1; + + // global mixer time when the action is to be started // it's set back to 'null' upon start of the action + this._startTime = null; - this._startTime = null; // scaled local time of the action + // scaled local time of the action // gets clamped or wrapped to 0..clip.duration according to loop - this.time = 0; this.timeScale = 1; this._effectiveTimeScale = 1; @@ -32597,265 +29557,226 @@ class AnimationAction { this.repetitions = Infinity; // no. of repetitions when looping this.paused = false; // true -> zero effective time scale - this.enabled = true; // false -> zero effective weight this.clampWhenFinished = false; // keep feeding the last frame? this.zeroSlopeAtStart = true; // for smooth interpolation w/o separate - this.zeroSlopeAtEnd = true; // clips for start, loop and end - } // State & Scheduling + } + // State & Scheduling play() { this._mixer._activateAction(this); - return this; } - stop() { this._mixer._deactivateAction(this); - return this.reset(); } - reset() { this.paused = false; this.enabled = true; this.time = 0; // restart clip - this._loopCount = -1; // forget previous loops - this._startTime = null; // forget scheduling return this.stopFading().stopWarping(); } - isRunning() { return this.enabled && !this.paused && this.timeScale !== 0 && this._startTime === null && this._mixer._isActiveAction(this); - } // return true when play has been called - + } + // return true when play has been called isScheduled() { return this._mixer._isActiveAction(this); } - startAt(time) { this._startTime = time; return this; } - setLoop(mode, repetitions) { this.loop = mode; this.repetitions = repetitions; return this; - } // Weight + } + + // 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 - - setEffectiveWeight(weight) { - this.weight = weight; // note: same logic as when updated at runtime + 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 - + } + // return the weight considering fading and .enabled getEffectiveWeight() { return this._effectiveWeight; } - fadeIn(duration) { return this._scheduleFading(duration, 0, 1); } - fadeOut(duration) { return this._scheduleFading(duration, 1, 0); } - crossFadeFrom(fadeOutAction, duration, warp) { fadeOutAction.fadeOut(duration); this.fadeIn(duration); - if (warp) { const fadeInDuration = this._clip.duration, - fadeOutDuration = fadeOutAction._clip.duration, - startEndRatio = fadeOutDuration / fadeInDuration, - endStartRatio = fadeInDuration / fadeOutDuration; + fadeOutDuration = fadeOutAction._clip.duration, + startEndRatio = fadeOutDuration / fadeInDuration, + endStartRatio = fadeInDuration / fadeOutDuration; fadeOutAction.warp(1.0, startEndRatio, duration); this.warp(endStartRatio, 1.0, duration); } - return this; } - crossFadeTo(fadeInAction, duration, warp) { return fadeInAction.crossFadeFrom(this, duration, warp); } - stopFading() { const weightInterpolant = this._weightInterpolant; - if (weightInterpolant !== null) { this._weightInterpolant = null; - this._mixer._takeBackControlInterpolant(weightInterpolant); } - return this; - } // Time Scale Control + } + + // 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 - - setEffectiveTimeScale(timeScale) { this.timeScale = timeScale; this._effectiveTimeScale = this.paused ? 0 : timeScale; return this.stopWarping(); - } // return the time scale considering warping and .paused - + } + // return the time scale considering warping and .paused getEffectiveTimeScale() { return this._effectiveTimeScale; } - setDuration(duration) { this.timeScale = this._clip.duration / duration; return this.stopWarping(); } - syncWith(action) { this.time = action.time; this.timeScale = action.timeScale; return this.stopWarping(); } - halt(duration) { return this.warp(this._effectiveTimeScale, 0, duration); } - warp(startTimeScale, endTimeScale, duration) { const mixer = this._mixer, - now = mixer.time, - timeScale = this.timeScale; + now = mixer.time, + timeScale = this.timeScale; let interpolant = this._timeScaleInterpolant; - if (interpolant === null) { interpolant = mixer._lendControlInterpolant(); this._timeScaleInterpolant = interpolant; } - const times = interpolant.parameterPositions, - values = interpolant.sampleValues; + values = interpolant.sampleValues; times[0] = now; times[1] = now + duration; values[0] = startTimeScale / timeScale; values[1] = endTimeScale / timeScale; return this; } - stopWarping() { const timeScaleInterpolant = this._timeScaleInterpolant; - if (timeScaleInterpolant !== null) { this._timeScaleInterpolant = null; - this._mixer._takeBackControlInterpolant(timeScaleInterpolant); } - return this; - } // Object Accessors + } + // Object Accessors getMixer() { return this._mixer; } - getClip() { return this._clip; } - getRoot() { return this._localRoot || this._mixer._root; - } // Interna + } + // Interna _update(time, deltaTime, timeDirection, accuIndex) { // called by the mixer + if (!this.enabled) { // call ._updateWeight() to update ._effectiveWeight - this._updateWeight(time); + this._updateWeight(time); return; } - const startTime = this._startTime; - if (startTime !== null) { // check for scheduled start of action - const timeRunning = (time - startTime) * timeDirection; + const timeRunning = (time - startTime) * timeDirection; if (timeRunning < 0 || timeDirection === 0) { - return; // yet to come / don't decide when delta = 0 - } // start - - - this._startTime = null; // unschedule - - deltaTime = timeDirection * timeRunning; - } // apply time scale and advance time + deltaTime = 0; + } else { + this._startTime = null; // unschedule + deltaTime = timeDirection * timeRunning; + } + } + // apply time scale and advance time deltaTime *= this._updateTimeScale(time); + const clipTime = this._updateTime(deltaTime); - const clipTime = this._updateTime(deltaTime); // note: _updateTime may disable the action resulting in + // note: _updateTime may disable the action resulting in // an effective weight of 0 - const weight = this._updateWeight(time); - if (weight > 0) { const interpolants = this._interpolants; const propertyMixers = this._propertyBindings; - switch (this.blendMode) { case AdditiveAnimationBlendMode: for (let j = 0, m = interpolants.length; j !== m; ++j) { interpolants[j].evaluate(clipTime); propertyMixers[j].accumulateAdditive(weight); } - break; - case NormalAnimationBlendMode: default: for (let j = 0, m = interpolants.length; j !== m; ++j) { interpolants[j].evaluate(clipTime); propertyMixers[j].accumulate(accuIndex, weight); } - } } } - _updateWeight(time) { let weight = 0; - if (this.enabled) { weight = this.weight; const interpolant = this._weightInterpolant; - if (interpolant !== null) { const interpolantValue = interpolant.evaluate(time)[0]; weight *= interpolantValue; - if (time > interpolant.parameterPositions[1]) { this.stopFading(); - if (interpolantValue === 0) { // faded out, disable this.enabled = false; @@ -32863,25 +29784,19 @@ class AnimationAction { } } } - this._effectiveWeight = weight; return weight; } - _updateTimeScale(time) { let timeScale = 0; - if (!this.paused) { timeScale = this.timeScale; const interpolant = this._timeScaleInterpolant; - if (interpolant !== null) { const interpolantValue = interpolant.evaluate(time)[0]; timeScale *= interpolantValue; - if (time > interpolant.parameterPositions[1]) { this.stopWarping(); - if (timeScale === 0) { // motion has halted, pause this.paused = true; @@ -32892,31 +29807,26 @@ class AnimationAction { } } } - this._effectiveTimeScale = timeScale; return timeScale; } - _updateTime(deltaTime) { const duration = this._clip.duration; const loop = this.loop; let time = this.time + deltaTime; let loopCount = this._loopCount; const pingPong = loop === LoopPingPong; - if (deltaTime === 0) { if (loopCount === -1) return time; return pingPong && (loopCount & 1) === 1 ? duration - time : time; } - if (loop === LoopOnce) { if (loopCount === -1) { // just started - this._loopCount = 0; + this._loopCount = 0; this._setEndings(true, true, false); } - handle_stop: { if (time >= duration) { time = duration; @@ -32926,10 +29836,8 @@ class AnimationAction { this.time = time; break handle_stop; } - if (this.clampWhenFinished) this.paused = true;else this.enabled = false; this.time = time; - this._mixer.dispatchEvent({ type: 'finished', action: this, @@ -32938,34 +29846,34 @@ class AnimationAction { } } else { // repetitive Repeat or PingPong + if (loopCount === -1) { // just started + if (deltaTime >= 0) { loopCount = 0; - 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); } } - if (time >= duration || time < 0) { // wrap around - const loopDelta = Math.floor(time / duration); // signed + const loopDelta = Math.floor(time / duration); // signed time -= duration * loopDelta; loopCount += Math.abs(loopDelta); const 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, @@ -32973,18 +29881,17 @@ class AnimationAction { }); } else { // keep running + if (pending === 1) { // entering the last round - const atStart = deltaTime < 0; + const atStart = deltaTime < 0; this._setEndings(atStart, !atStart, pingPong); } else { this._setEndings(false, false, pingPong); } - this._loopCount = loopCount; this.time = time; - this._mixer.dispatchEvent({ type: 'loop', action: this, @@ -32994,30 +29901,27 @@ class AnimationAction { } else { this.time = time; } - if (pingPong && (loopCount & 1) === 1) { // invert time for the "pong round" + return duration - time; } } - return time; } - _setEndings(atStart, atEnd, pingPong) { const settings = this._interpolantSettings; - 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; } - if (atEnd) { settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding; } else { @@ -33025,158 +29929,132 @@ class AnimationAction { } } } - _scheduleFading(duration, weightNow, weightThen) { const mixer = this._mixer, - now = mixer.time; + now = mixer.time; let interpolant = this._weightInterpolant; - if (interpolant === null) { interpolant = mixer._lendControlInterpolant(); this._weightInterpolant = interpolant; } - const times = interpolant.parameterPositions, - values = interpolant.sampleValues; + values = interpolant.sampleValues; times[0] = now; values[0] = weightNow; times[1] = now + duration; values[1] = weightThen; return this; } - } const _controlInterpolantsResultBuffer = new Float32Array(1); - class AnimationMixer extends EventDispatcher { constructor(root) { super(); this._root = root; - this._initMemoryManager(); - this._accuIndex = 0; this.time = 0; this.timeScale = 1.0; } - _bindAction(action, prototypeAction) { const root = action._localRoot || this._root, - tracks = action._clip.tracks, - nTracks = tracks.length, - bindings = action._propertyBindings, - interpolants = action._interpolants, - rootUuid = root.uuid, - bindingsByRoot = this._bindingsByRootAndName; + tracks = action._clip.tracks, + nTracks = tracks.length, + bindings = action._propertyBindings, + interpolants = action._interpolants, + rootUuid = root.uuid, + bindingsByRoot = this._bindingsByRootAndName; let bindingsByName = bindingsByRoot[rootUuid]; - if (bindingsByName === undefined) { bindingsByName = {}; bindingsByRoot[rootUuid] = bindingsByName; } - for (let i = 0; i !== nTracks; ++i) { const track = tracks[i], - trackName = track.name; + trackName = track.name; let binding = bindingsByName[trackName]; - if (binding !== undefined) { ++binding.referenceCount; bindings[i] = binding; } else { binding = bindings[i]; - if (binding !== undefined) { // existing binding, make sure the cache knows + if (binding._cacheIndex === null) { ++binding.referenceCount; - this._addInactiveBinding(binding, rootUuid, trackName); } - continue; } - const path = prototypeAction && prototypeAction._propertyBindings[i].binding.parsedPath; binding = new PropertyMixer(PropertyBinding.create(root, trackName, path), track.ValueTypeName, track.getValueSize()); ++binding.referenceCount; - this._addInactiveBinding(binding, rootUuid, trackName); - bindings[i] = binding; } - interpolants[i].resultBuffer = binding.buffer; } } - _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 - const rootUuid = (action._localRoot || this._root).uuid, - clipUuid = action._clip.uuid, - actionsForClip = this._actionsByClip[clipUuid]; + const 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); } + const bindings = action._propertyBindings; - const bindings = action._propertyBindings; // increment reference counts / sort out state - + // increment reference counts / sort out state for (let i = 0, n = bindings.length; i !== n; ++i) { const binding = bindings[i]; - if (binding.useCount++ === 0) { this._lendBinding(binding); - binding.saveOriginalState(); } } - this._lendAction(action); } } - _deactivateAction(action) { if (this._isActiveAction(action)) { - const bindings = action._propertyBindings; // decrement reference counts / sort out state + const bindings = action._propertyBindings; + // decrement reference counts / sort out state for (let i = 0, n = bindings.length; i !== n; ++i) { const binding = bindings[i]; - if (--binding.useCount === 0) { binding.restoreOriginalState(); - this._takeBackBinding(binding); } } - this._takeBackAction(action); } - } // Memory manager + } + // Memory manager _initMemoryManager() { this._actions = []; // 'nActiveActions' followed by inactive ones - this._nActiveActions = 0; - this._actionsByClip = {}; // inside: + this._actionsByClip = {}; + // inside: // { // knownActions: Array< AnimationAction > - used as prototypes // actionByRoot: AnimationAction - lookup // } this._bindings = []; // 'nActiveBindings' followed by inactive ones - this._nActiveBindings = 0; this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer > this._controlInterpolants = []; // same game as above - this._nActiveControlInterpolants = 0; const scope = this; this.stats = { @@ -33184,46 +30062,39 @@ class AnimationMixer extends EventDispatcher { get total() { return scope._actions.length; }, - get inUse() { return scope._nActiveActions; } - }, bindings: { get total() { return scope._bindings.length; }, - get inUse() { return scope._nActiveBindings; } - }, controlInterpolants: { get total() { return scope._controlInterpolants.length; }, - get inUse() { return scope._nActiveControlInterpolants; } - } }; - } // Memory management for AnimationAction objects + } + // Memory management for AnimationAction objects _isActiveAction(action) { const index = action._cacheIndex; return index !== null && index < this._nActiveActions; } - _addInactiveAction(action, clipUuid, rootUuid) { const actions = this._actions, - actionsByClip = this._actionsByClip; + actionsByClip = this._actionsByClip; let actionsForClip = actionsByClip[clipUuid]; - if (actionsForClip === undefined) { actionsForClip = { knownActions: [action], @@ -33236,179 +30107,164 @@ class AnimationMixer extends EventDispatcher { action._byClipCacheIndex = knownActions.length; knownActions.push(action); } - action._cacheIndex = actions.length; actions.push(action); actionsForClip.actionByRoot[rootUuid] = action; } - _removeInactiveAction(action) { const actions = this._actions, - lastInactiveAction = actions[actions.length - 1], - cacheIndex = action._cacheIndex; + lastInactiveAction = actions[actions.length - 1], + cacheIndex = action._cacheIndex; lastInactiveAction._cacheIndex = cacheIndex; actions[cacheIndex] = lastInactiveAction; actions.pop(); action._cacheIndex = null; const clipUuid = action._clip.uuid, - actionsByClip = this._actionsByClip, - actionsForClip = actionsByClip[clipUuid], - knownActionsForClip = actionsForClip.knownActions, - lastKnownAction = knownActionsForClip[knownActionsForClip.length - 1], - byClipCacheIndex = action._byClipCacheIndex; + 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; const actionByRoot = actionsForClip.actionByRoot, - rootUuid = (action._localRoot || this._root).uuid; + rootUuid = (action._localRoot || this._root).uuid; delete actionByRoot[rootUuid]; - if (knownActionsForClip.length === 0) { delete actionsByClip[clipUuid]; } - this._removeInactiveBindingsForAction(action); } - _removeInactiveBindingsForAction(action) { const bindings = action._propertyBindings; - for (let i = 0, n = bindings.length; i !== n; ++i) { const binding = bindings[i]; - if (--binding.referenceCount === 0) { this._removeInactiveBinding(binding); } } } - _lendAction(action) { // [ active actions | inactive actions ] // [ active actions >| inactive actions ] // s a // <-swap-> // a s + const actions = this._actions, - prevIndex = action._cacheIndex, - lastActiveIndex = this._nActiveActions++, - firstInactiveAction = actions[lastActiveIndex]; + prevIndex = action._cacheIndex, + lastActiveIndex = this._nActiveActions++, + firstInactiveAction = actions[lastActiveIndex]; action._cacheIndex = lastActiveIndex; actions[lastActiveIndex] = action; firstInactiveAction._cacheIndex = prevIndex; actions[prevIndex] = firstInactiveAction; } - _takeBackAction(action) { // [ active actions | inactive actions ] // [ active actions |< inactive actions ] // a s // <-swap-> // s a + const actions = this._actions, - prevIndex = action._cacheIndex, - firstInactiveIndex = --this._nActiveActions, - lastActiveAction = actions[firstInactiveIndex]; + 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 + } + // Memory management for PropertyMixer objects _addInactiveBinding(binding, rootUuid, trackName) { const bindingsByRoot = this._bindingsByRootAndName, - bindings = this._bindings; + bindings = this._bindings; let bindingByName = bindingsByRoot[rootUuid]; - if (bindingByName === undefined) { bindingByName = {}; bindingsByRoot[rootUuid] = bindingByName; } - bindingByName[trackName] = binding; binding._cacheIndex = bindings.length; bindings.push(binding); } - _removeInactiveBinding(binding) { const 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; + 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(binding) { const bindings = this._bindings, - prevIndex = binding._cacheIndex, - lastActiveIndex = this._nActiveBindings++, - firstInactiveBinding = bindings[lastActiveIndex]; + prevIndex = binding._cacheIndex, + lastActiveIndex = this._nActiveBindings++, + firstInactiveBinding = bindings[lastActiveIndex]; binding._cacheIndex = lastActiveIndex; bindings[lastActiveIndex] = binding; firstInactiveBinding._cacheIndex = prevIndex; bindings[prevIndex] = firstInactiveBinding; } - _takeBackBinding(binding) { const bindings = this._bindings, - prevIndex = binding._cacheIndex, - firstInactiveIndex = --this._nActiveBindings, - lastActiveBinding = bindings[firstInactiveIndex]; + 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 + } + // Memory management of Interpolants for weight and time scale _lendControlInterpolant() { const interpolants = this._controlInterpolants, - lastActiveIndex = this._nActiveControlInterpolants++; + lastActiveIndex = this._nActiveControlInterpolants++; let interpolant = interpolants[lastActiveIndex]; - if (interpolant === undefined) { interpolant = new LinearInterpolant(new Float32Array(2), new Float32Array(2), 1, _controlInterpolantsResultBuffer); interpolant.__cacheIndex = lastActiveIndex; interpolants[lastActiveIndex] = interpolant; } - return interpolant; } - _takeBackControlInterpolant(interpolant) { const interpolants = this._controlInterpolants, - prevIndex = interpolant.__cacheIndex, - firstInactiveIndex = --this._nActiveControlInterpolants, - lastActiveInterpolant = interpolants[firstInactiveIndex]; + prevIndex = interpolant.__cacheIndex, + firstInactiveIndex = --this._nActiveControlInterpolants, + lastActiveInterpolant = interpolants[firstInactiveIndex]; interpolant.__cacheIndex = firstInactiveIndex; interpolants[firstInactiveIndex] = interpolant; lastActiveInterpolant.__cacheIndex = prevIndex; interpolants[prevIndex] = lastActiveInterpolant; - } // return an action for a clip optionally using a custom root target + } + + // 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(clip, optionalRoot, blendMode) { const root = optionalRoot || this._root, - rootUuid = root.uuid; + rootUuid = root.uuid; let clipObject = typeof clip === 'string' ? AnimationClip.findByName(root, clip) : clip; const clipUuid = clipObject !== null ? clipObject.uuid : clip; const actionsForClip = this._actionsByClip[clipUuid]; let prototypeAction = null; - if (blendMode === undefined) { if (clipObject !== null) { blendMode = clipObject.blendMode; @@ -33416,196 +30272,167 @@ class AnimationMixer extends EventDispatcher { blendMode = NormalAnimationBlendMode; } } - if (actionsForClip !== undefined) { const existingAction = actionsForClip.actionByRoot[rootUuid]; - 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 - + } - prototypeAction = actionsForClip.knownActions[0]; // also, take the clip from the prototype action + // we know the clip, so we don't have to parse all + // the bindings again but can just copy + prototypeAction = actionsForClip.knownActions[0]; + // also, take the clip from the prototype action if (clipObject === null) clipObject = prototypeAction._clip; - } // clip must be known when specified via string - + } - if (clipObject === null) return null; // allocate all resources required to run it + // clip must be known when specified via string + if (clipObject === null) return null; + // allocate all resources required to run it const newAction = new AnimationAction(this, clipObject, optionalRoot, blendMode); + this._bindAction(newAction, prototypeAction); - this._bindAction(newAction, prototypeAction); // and make the action known to the memory manager - - + // and make the action known to the memory manager this._addInactiveAction(newAction, clipUuid, rootUuid); - return newAction; - } // get an existing action - + } + // get an existing action existingAction(clip, optionalRoot) { const 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]; - + rootUuid = root.uuid, + clipObject = typeof clip === 'string' ? AnimationClip.findByName(root, clip) : clip, + clipUuid = clipObject ? clipObject.uuid : clip, + actionsForClip = this._actionsByClip[clipUuid]; if (actionsForClip !== undefined) { return actionsForClip.actionByRoot[rootUuid] || null; } - return null; - } // deactivates all previously scheduled actions - + } + // deactivates all previously scheduled actions stopAllAction() { const actions = this._actions, - nActions = this._nActiveActions; - + nActions = this._nActiveActions; for (let i = nActions - 1; i >= 0; --i) { actions[i].stop(); } - return this; - } // advance the time and update apply the animation - + } + // advance the time and update apply the animation update(deltaTime) { deltaTime *= this.timeScale; const actions = this._actions, - nActions = this._nActiveActions, - time = this.time += deltaTime, - timeDirection = Math.sign(deltaTime), - accuIndex = this._accuIndex ^= 1; // run active actions + nActions = this._nActiveActions, + time = this.time += deltaTime, + timeDirection = Math.sign(deltaTime), + accuIndex = this._accuIndex ^= 1; + + // run active actions for (let i = 0; i !== nActions; ++i) { const action = actions[i]; - action._update(time, deltaTime, timeDirection, accuIndex); - } // update scene graph + } + // update scene graph const bindings = this._bindings, - nBindings = this._nActiveBindings; - + nBindings = this._nActiveBindings; for (let i = 0; i !== nBindings; ++i) { bindings[i].apply(accuIndex); } - return this; - } // Allows you to seek to a specific time in an animation. - + } + // Allows you to seek to a specific time in an animation. setTime(timeInSeconds) { this.time = 0; // Zero out time attribute for AnimationMixer object; - for (let i = 0; i < this._actions.length; i++) { this._actions[i].time = 0; // Zero out time attribute for all associated AnimationAction objects. } return this.update(timeInSeconds); // Update used to set exact time. Returns "this" AnimationMixer object. - } // return this mixer's root target object - + } + // return this mixer's root target object getRoot() { return this._root; - } // free all resources specific to a particular clip - + } + // free all resources specific to a particular clip uncacheClip(clip) { const actions = this._actions, - clipUuid = clip.uuid, - actionsByClip = this._actionsByClip, - actionsForClip = actionsByClip[clipUuid]; - + 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 - const actionsToRemove = actionsForClip.knownActions; + const actionsToRemove = actionsForClip.knownActions; for (let i = 0, n = actionsToRemove.length; i !== n; ++i) { const action = actionsToRemove[i]; - this._deactivateAction(action); - const cacheIndex = action._cacheIndex, - lastInactiveAction = actions[actions.length - 1]; + 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 - + } + // free all resources specific to a particular root target object uncacheRoot(root) { const rootUuid = root.uuid, - actionsByClip = this._actionsByClip; - + actionsByClip = this._actionsByClip; for (const clipUuid in actionsByClip) { const actionByRoot = actionsByClip[clipUuid].actionByRoot, - action = actionByRoot[rootUuid]; - + action = actionByRoot[rootUuid]; if (action !== undefined) { this._deactivateAction(action); - this._removeInactiveAction(action); } } - const bindingsByRoot = this._bindingsByRootAndName, - bindingByName = bindingsByRoot[rootUuid]; - + bindingByName = bindingsByRoot[rootUuid]; if (bindingByName !== undefined) { for (const trackName in bindingByName) { const binding = bindingByName[trackName]; binding.restoreOriginalState(); - this._removeInactiveBinding(binding); } } - } // remove a targeted clip from the cache - + } + // remove a targeted clip from the cache uncacheAction(clip, optionalRoot) { const action = this.existingAction(clip, optionalRoot); - if (action !== null) { this._deactivateAction(action); - this._removeInactiveAction(action); } } - } class Uniform { constructor(value) { - if (typeof value === 'string') { - console.warn('THREE.Uniform: Type parameter is no longer needed.'); - value = arguments[1]; - } - this.value = value; } - clone() { return new Uniform(this.value.clone === undefined ? this.value : this.value.clone()); } - } let id = 0; - class UniformsGroup extends EventDispatcher { constructor() { super(); @@ -33617,52 +30444,42 @@ class UniformsGroup extends EventDispatcher { this.usage = StaticDrawUsage; this.uniforms = []; } - add(uniform) { this.uniforms.push(uniform); return this; } - remove(uniform) { const index = this.uniforms.indexOf(uniform); if (index !== -1) this.uniforms.splice(index, 1); return this; } - setName(name) { this.name = name; return this; } - setUsage(value) { this.usage = value; return this; } - dispose() { this.dispatchEvent({ type: 'dispose' }); return this; } - copy(source) { this.name = source.name; this.usage = source.usage; const uniformsSource = source.uniforms; this.uniforms.length = 0; - for (let i = 0, l = uniformsSource.length; i < l; i++) { this.uniforms.push(uniformsSource[i].clone()); } - return this; } - clone() { return new this.constructor().copy(this); } - } class InstancedInterleavedBuffer extends InterleavedBuffer { @@ -33671,26 +30488,22 @@ class InstancedInterleavedBuffer extends InterleavedBuffer { this.isInstancedInterleavedBuffer = true; this.meshPerAttribute = meshPerAttribute; } - copy(source) { super.copy(source); this.meshPerAttribute = source.meshPerAttribute; return this; } - clone(data) { const ib = super.clone(data); ib.meshPerAttribute = this.meshPerAttribute; return ib; } - toJSON(data) { const json = super.toJSON(data); json.isInstancedInterleavedBuffer = true; json.meshPerAttribute = this.meshPerAttribute; return json; } - } class GLBufferAttribute { @@ -33703,37 +30516,32 @@ class GLBufferAttribute { this.count = count; this.version = 0; } - set needsUpdate(value) { if (value === true) this.version++; } - setBuffer(buffer) { this.buffer = buffer; return this; } - setType(type, elementSize) { this.type = type; this.elementSize = elementSize; return this; } - setItemSize(itemSize) { this.itemSize = itemSize; return this; } - setCount(count) { this.count = count; return this; } - } class Raycaster { constructor(origin, direction, near = 0, far = Infinity) { - this.ray = new Ray(origin, direction); // direction is assumed to be normalized (for accurate distance calculations) + this.ray = new Ray(origin, direction); + // direction is assumed to be normalized (for accurate distance calculations) this.near = near; this.far = far; @@ -33751,12 +30559,11 @@ class Raycaster { Sprite: {} }; } - set(origin, direction) { // direction is assumed to be normalized (for accurate distance calculations) + this.ray.set(origin, direction); } - setFromCamera(coords, camera) { if (camera.isPerspectiveCamera) { this.ray.origin.setFromMatrixPosition(camera.matrixWorld); @@ -33764,43 +30571,34 @@ class Raycaster { this.camera = camera; } else if (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: ' + camera.type); } } - intersectObject(object, recursive = true, intersects = []) { intersectObject(object, this, intersects, recursive); intersects.sort(ascSort); return intersects; } - intersectObjects(objects, recursive = true, intersects = []) { for (let i = 0, l = objects.length; i < l; i++) { intersectObject(objects[i], this, intersects, recursive); } - intersects.sort(ascSort); return intersects; } - } - 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); } - if (recursive === true) { const children = object.children; - for (let i = 0, l = children.length; i < l; i++) { intersectObject(children[i], raycaster, intersects, true); } @@ -33813,45 +30611,38 @@ function intersectObject(object, raycaster, intersects, recursive) { * 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. */ - class Spherical { constructor(radius = 1, phi = 0, theta = 0) { this.radius = radius; this.phi = phi; // polar angle - this.theta = theta; // azimuthal angle return this; } - set(radius, phi, theta) { this.radius = radius; this.phi = phi; this.theta = theta; return this; } - copy(other) { this.radius = other.radius; this.phi = other.phi; this.theta = other.theta; return this; - } // restrict phi to be between EPS and PI-EPS - + } + // restrict phi to be between EPS and PI-EPS makeSafe() { const EPS = 0.000001; this.phi = Math.max(EPS, Math.min(Math.PI - EPS, this.phi)); return this; } - setFromVector3(v) { return this.setFromCartesianCoords(v.x, v.y, v.z); } - setFromCartesianCoords(x, y, z) { this.radius = Math.sqrt(x * x + y * y + z * z); - if (this.radius === 0) { this.theta = 0; this.phi = 0; @@ -33859,294 +30650,235 @@ class Spherical { this.theta = Math.atan2(x, z); this.phi = Math.acos(clamp(y / this.radius, -1, 1)); } - return this; } - clone() { return new this.constructor().copy(this); } - } /** * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system */ + class Cylindrical { constructor(radius = 1, theta = 0, y = 0) { this.radius = radius; // distance from the origin to a point in the x-z plane - this.theta = theta; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis - this.y = y; // height above the x-z plane return this; } - set(radius, theta, y) { this.radius = radius; this.theta = theta; this.y = y; return this; } - copy(other) { this.radius = other.radius; this.theta = other.theta; this.y = other.y; return this; } - setFromVector3(v) { return this.setFromCartesianCoords(v.x, v.y, v.z); } - setFromCartesianCoords(x, y, z) { this.radius = Math.sqrt(x * x + z * z); this.theta = Math.atan2(x, z); this.y = y; return this; } - clone() { return new this.constructor().copy(this); } - } const _vector$4 = /*@__PURE__*/new Vector2(); - class Box2 { constructor(min = new Vector2(+Infinity, +Infinity), max = new Vector2(-Infinity, -Infinity)) { this.isBox2 = true; this.min = min; this.max = max; } - set(min, max) { this.min.copy(min); this.max.copy(max); return this; } - setFromPoints(points) { this.makeEmpty(); - for (let i = 0, il = points.length; i < il; i++) { this.expandByPoint(points[i]); } - return this; } - setFromCenterAndSize(center, size) { const halfSize = _vector$4.copy(size).multiplyScalar(0.5); - this.min.copy(center).sub(halfSize); this.max.copy(center).add(halfSize); return this; } - clone() { return new this.constructor().copy(this); } - copy(box) { this.min.copy(box.min); this.max.copy(box.max); return this; } - makeEmpty() { this.min.x = this.min.y = +Infinity; this.max.x = this.max.y = -Infinity; return this; } - 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; } - getCenter(target) { return this.isEmpty() ? target.set(0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5); } - getSize(target) { return this.isEmpty() ? target.set(0, 0) : target.subVectors(this.max, this.min); } - expandByPoint(point) { this.min.min(point); this.max.max(point); return this; } - expandByVector(vector) { this.min.sub(vector); this.max.add(vector); return this; } - expandByScalar(scalar) { this.min.addScalar(-scalar); this.max.addScalar(scalar); return this; } - 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; } - 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; } - getParameter(point, target) { // This can potentially have a divide by zero if the box // has a size dimension of 0. + 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)); } - 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; } - clampPoint(point, target) { return target.copy(point).clamp(this.min, this.max); } - distanceToPoint(point) { const clampedPoint = _vector$4.copy(point).clamp(this.min, this.max); - return clampedPoint.sub(point).length(); } - intersect(box) { this.min.max(box.min); this.max.min(box.max); return this; } - union(box) { this.min.min(box.min); this.max.max(box.max); return this; } - translate(offset) { this.min.add(offset); this.max.add(offset); return this; } - equals(box) { return box.min.equals(this.min) && box.max.equals(this.max); } - } const _startP = /*@__PURE__*/new Vector3(); - const _startEnd = /*@__PURE__*/new Vector3(); - class Line3 { constructor(start = new Vector3(), end = new Vector3()) { this.start = start; this.end = end; } - set(start, end) { this.start.copy(start); this.end.copy(end); return this; } - copy(line) { this.start.copy(line.start); this.end.copy(line.end); return this; } - getCenter(target) { return target.addVectors(this.start, this.end).multiplyScalar(0.5); } - delta(target) { return target.subVectors(this.end, this.start); } - distanceSq() { return this.start.distanceToSquared(this.end); } - distance() { return this.start.distanceTo(this.end); } - at(t, target) { return this.delta(target).multiplyScalar(t).add(this.start); } - closestPointToPointParameter(point, clampToLine) { _startP.subVectors(point, this.start); - _startEnd.subVectors(this.end, this.start); - const startEnd2 = _startEnd.dot(_startEnd); - const startEnd_startP = _startEnd.dot(_startP); - let t = startEnd_startP / startEnd2; - if (clampToLine) { t = clamp(t, 0, 1); } - return t; } - closestPointToPoint(point, clampToLine, target) { const t = this.closestPointToPointParameter(point, clampToLine); return this.delta(target).multiplyScalar(t).add(this.start); } - applyMatrix4(matrix) { this.start.applyMatrix4(matrix); this.end.applyMatrix4(matrix); return this; } - equals(line) { return line.start.equals(this.start) && line.end.equals(this.end); } - clone() { return new this.constructor().copy(this); } - } const _vector$3 = /*@__PURE__*/new Vector3(); - class SpotLightHelper extends Object3D { constructor(light, color) { super(); this.light = light; - this.light.updateMatrixWorld(); this.matrix = light.matrixWorld; this.matrixAutoUpdate = false; this.color = color; + this.type = 'SpotLightHelper'; const geometry = new BufferGeometry(); const 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 (let i = 0, j = 1, l = 32; i < l; i++, j++) { const p1 = i / l * Math.PI * 2; const p2 = j / l * Math.PI * 2; positions.push(Math.cos(p1), Math.sin(p1), 1, Math.cos(p2), Math.sin(p2), 1); } - geometry.setAttribute('position', new Float32BufferAttribute(positions, 3)); const material = new LineBasicMaterial({ fog: false, @@ -34156,37 +30888,29 @@ class SpotLightHelper extends Object3D { this.add(this.cone); this.update(); } - dispose() { this.cone.geometry.dispose(); this.cone.material.dispose(); } - update() { - this.light.updateMatrixWorld(); + this.light.updateWorldMatrix(true, false); + this.light.target.updateWorldMatrix(true, false); const coneLength = this.light.distance ? this.light.distance : 1000; const coneWidth = coneLength * Math.tan(this.light.angle); this.cone.scale.set(coneWidth, coneWidth, coneLength); - _vector$3.setFromMatrixPosition(this.light.target.matrixWorld); - this.cone.lookAt(_vector$3); - if (this.color !== undefined) { this.cone.material.color.set(this.color); } else { this.cone.material.color.copy(this.light.color); } } - } const _vector$2 = /*@__PURE__*/new Vector3(); - const _boneMatrix = /*@__PURE__*/new Matrix4(); - const _matrixWorldInv = /*@__PURE__*/new Matrix4(); - class SkeletonHelper extends LineSegments { constructor(object) { const bones = getBoneList(object); @@ -34195,10 +30919,8 @@ class SkeletonHelper extends LineSegments { const colors = []; const color1 = new Color(0, 0, 1); const color2 = new Color(0, 1, 0); - for (let i = 0; i < bones.length; i++) { const bone = bones[i]; - if (bone.parent && bone.parent.isBone) { vertices.push(0, 0, 0); vertices.push(0, 0, 0); @@ -34206,7 +30928,6 @@ class SkeletonHelper extends LineSegments { colors.push(color2.r, color2.g, color2.b); } } - geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); const material = new LineBasicMaterial({ @@ -34224,50 +30945,39 @@ class SkeletonHelper extends LineSegments { this.matrix = object.matrixWorld; this.matrixAutoUpdate = false; } - updateMatrixWorld(force) { const bones = this.bones; const geometry = this.geometry; const position = geometry.getAttribute('position'); - _matrixWorldInv.copy(this.root.matrixWorld).invert(); - for (let i = 0, j = 0; i < bones.length; i++) { const bone = bones[i]; - if (bone.parent && bone.parent.isBone) { _boneMatrix.multiplyMatrices(_matrixWorldInv, bone.matrixWorld); - _vector$2.setFromMatrixPosition(_boneMatrix); - position.setXYZ(j, _vector$2.x, _vector$2.y, _vector$2.z); - _boneMatrix.multiplyMatrices(_matrixWorldInv, bone.parent.matrixWorld); - _vector$2.setFromMatrixPosition(_boneMatrix); - position.setXYZ(j + 1, _vector$2.x, _vector$2.y, _vector$2.z); j += 2; } } - geometry.getAttribute('position').needsUpdate = true; super.updateMatrixWorld(force); } - + dispose() { + this.geometry.dispose(); + this.material.dispose(); + } } - function getBoneList(object) { const boneList = []; - if (object.isBone === true) { boneList.push(object); } - for (let i = 0; i < object.children.length; i++) { boneList.push.apply(boneList, getBoneList(object.children[i])); } - return boneList; } @@ -34281,12 +30991,12 @@ class PointLightHelper extends Mesh { }); super(geometry, material); 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.IcosahedronGeometry( 1, 2 ); @@ -34307,13 +31017,14 @@ class PointLightHelper extends Mesh { this.geometry.dispose(); this.material.dispose(); } - update() { + this.light.updateWorldMatrix(true, false); 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 ) { @@ -34323,25 +31034,20 @@ class PointLightHelper extends Mesh { this.lightDistance.scale.set( d, d, d ); } */ - } - } const _vector$1 = /*@__PURE__*/new Vector3(); - const _color1 = /*@__PURE__*/new Color(); - const _color2 = /*@__PURE__*/new Color(); - class HemisphereLightHelper extends Object3D { constructor(light, size, color) { super(); this.light = light; - this.light.updateMatrixWorld(); this.matrix = light.matrixWorld; this.matrixAutoUpdate = false; this.color = color; + this.type = 'HemisphereLightHelper'; const geometry = new OctahedronGeometry(size); geometry.rotateY(Math.PI * 0.5); this.material = new MeshBasicMaterial({ @@ -34356,35 +31062,27 @@ class HemisphereLightHelper extends Object3D { this.add(new Mesh(geometry, this.material)); this.update(); } - dispose() { this.children[0].geometry.dispose(); this.children[0].material.dispose(); } - update() { const mesh = this.children[0]; - if (this.color !== undefined) { this.material.color.set(this.color); } else { const colors = mesh.geometry.getAttribute('color'); - _color1.copy(this.light.color); - _color2.copy(this.light.groundColor); - for (let i = 0, l = colors.count; i < l; i++) { const color = i < l / 2 ? _color1 : _color2; colors.setXYZ(i, color.r, color.g, color.b); } - colors.needsUpdate = true; } - + this.light.updateWorldMatrix(true, false); mesh.lookAt(_vector$1.setFromMatrixPosition(this.light.matrixWorld).negate()); } - } class GridHelper extends LineSegments { @@ -34395,8 +31093,7 @@ class GridHelper extends LineSegments { const step = size / divisions; const halfSize = size / 2; const vertices = [], - colors = []; - + colors = []; for (let 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); @@ -34410,7 +31107,6 @@ class GridHelper extends LineSegments { color.toArray(colors, j); j += 3; } - const geometry = new BufferGeometry(); geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); @@ -34421,39 +31117,49 @@ class GridHelper extends LineSegments { super(geometry, material); this.type = 'GridHelper'; } - + dispose() { + this.geometry.dispose(); + this.material.dispose(); + } } class PolarGridHelper extends LineSegments { - constructor(radius = 10, radials = 16, circles = 8, divisions = 64, color1 = 0x444444, color2 = 0x888888) { + constructor(radius = 10, sectors = 16, rings = 8, divisions = 64, color1 = 0x444444, color2 = 0x888888) { color1 = new Color(color1); color2 = new Color(color2); const vertices = []; - const colors = []; // create the radials + const colors = []; - for (let i = 0; i <= radials; i++) { - const v = i / radials * (Math.PI * 2); - const x = Math.sin(v) * radius; - const z = Math.cos(v) * radius; - vertices.push(0, 0, 0); - vertices.push(x, 0, z); - const color = i & 1 ? color1 : color2; - colors.push(color.r, color.g, color.b); - colors.push(color.r, color.g, color.b); - } // create the circles + // create the sectors + + if (sectors > 1) { + for (let i = 0; i < sectors; i++) { + const v = i / sectors * (Math.PI * 2); + const x = Math.sin(v) * radius; + const z = Math.cos(v) * radius; + vertices.push(0, 0, 0); + vertices.push(x, 0, z); + const color = i & 1 ? color1 : color2; + colors.push(color.r, color.g, color.b); + colors.push(color.r, color.g, color.b); + } + } + // create the rings - for (let i = 0; i <= circles; i++) { + for (let i = 0; i < rings; i++) { const color = i & 1 ? color1 : color2; - const r = radius - radius / circles * i; - + const r = radius - radius / rings * i; for (let j = 0; j < divisions; j++) { // first vertex + let v = j / divisions * (Math.PI * 2); let x = Math.sin(v) * r; let z = Math.cos(v) * r; vertices.push(x, 0, z); - colors.push(color.r, color.g, color.b); // second vertex + colors.push(color.r, color.g, color.b); + + // second vertex v = (j + 1) / divisions * (Math.PI * 2); x = Math.sin(v) * r; @@ -34462,7 +31168,6 @@ class PolarGridHelper extends LineSegments { colors.push(color.r, color.g, color.b); } } - const geometry = new BufferGeometry(); geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); @@ -34473,23 +31178,23 @@ class PolarGridHelper extends LineSegments { super(geometry, material); this.type = 'PolarGridHelper'; } - + dispose() { + this.geometry.dispose(); + this.material.dispose(); + } } const _v1 = /*@__PURE__*/new Vector3(); - const _v2 = /*@__PURE__*/new Vector3(); - const _v3 = /*@__PURE__*/new Vector3(); - class DirectionalLightHelper extends Object3D { constructor(light, size, color) { super(); this.light = light; - this.light.updateMatrixWorld(); this.matrix = light.matrixWorld; this.matrixAutoUpdate = false; this.color = color; + this.type = 'DirectionalLightHelper'; if (size === undefined) size = 1; let geometry = new BufferGeometry(); geometry.setAttribute('position', new Float32BufferAttribute([-size, size, 0, size, size, 0, size, -size, 0, -size, -size, 0, -size, size, 0], 3)); @@ -34505,23 +31210,19 @@ class DirectionalLightHelper extends Object3D { this.add(this.targetLine); this.update(); } - dispose() { this.lightPlane.geometry.dispose(); this.lightPlane.material.dispose(); this.targetLine.geometry.dispose(); this.targetLine.material.dispose(); } - update() { + this.light.updateWorldMatrix(true, false); + this.light.target.updateWorldMatrix(true, false); _v1.setFromMatrixPosition(this.light.matrixWorld); - _v2.setFromMatrixPosition(this.light.target.matrixWorld); - _v3.subVectors(_v2, _v1); - this.lightPlane.lookAt(_v2); - if (this.color !== undefined) { this.lightPlane.material.color.set(this.color); this.targetLine.material.color.set(this.color); @@ -34529,16 +31230,14 @@ class DirectionalLightHelper extends Object3D { this.lightPlane.material.color.copy(this.light.color); this.targetLine.material.color.copy(this.light.color); } - this.targetLine.lookAt(_v2); this.targetLine.scale.z = _v3.length(); } - } const _vector = /*@__PURE__*/new Vector3(); - const _camera = /*@__PURE__*/new Camera(); + /** * - shows frustum, line of sight and up of the camera * - suitable for fast updates @@ -34546,7 +31245,6 @@ const _camera = /*@__PURE__*/new Camera(); * https://github.com/evanw/lightgl.js/blob/master/tests/shadowmap.html */ - class CameraHelper extends LineSegments { constructor(camera) { const geometry = new BufferGeometry(); @@ -34557,56 +31255,65 @@ class CameraHelper extends LineSegments { }); const vertices = []; const colors = []; - const pointMap = {}; // near + const pointMap = {}; + + // near addLine('n1', 'n2'); addLine('n2', 'n4'); addLine('n4', 'n3'); - addLine('n3', 'n1'); // far + addLine('n3', 'n1'); + + // far addLine('f1', 'f2'); addLine('f2', 'f4'); addLine('f4', 'f3'); - addLine('f3', 'f1'); // sides + addLine('f3', 'f1'); + + // sides addLine('n1', 'f1'); addLine('n2', 'f2'); addLine('n3', 'f3'); - addLine('n4', 'f4'); // cone + addLine('n4', 'f4'); + + // cone addLine('p', 'n1'); addLine('p', 'n2'); addLine('p', 'n3'); - addLine('p', 'n4'); // up + addLine('p', 'n4'); + + // up addLine('u1', 'u2'); addLine('u2', 'u3'); - addLine('u3', 'u1'); // target + addLine('u3', 'u1'); + + // target addLine('c', 't'); - addLine('p', 'c'); // cross + addLine('p', 'c'); + + // cross addLine('cn1', 'cn2'); addLine('cn3', 'cn4'); addLine('cf1', 'cf2'); addLine('cf3', 'cf4'); - function addLine(a, b) { addPoint(a); addPoint(b); } - function addPoint(id) { vertices.push(0, 0, 0); colors.push(0, 0, 0); - if (pointMap[id] === undefined) { pointMap[id] = []; } - pointMap[id].push(vertices.length / 3 - 1); } - geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); super(geometry, material); @@ -34616,7 +31323,9 @@ class CameraHelper extends LineSegments { this.matrix = camera.matrixWorld; this.matrixAutoUpdate = false; this.pointMap = pointMap; - this.update(); // colors + this.update(); + + // colors const colorFrustum = new Color(0xffaa00); const colorCone = new Color(0xff0000); @@ -34625,121 +31334,121 @@ class CameraHelper extends LineSegments { const colorCross = new Color(0x333333); this.setColors(colorFrustum, colorCone, colorUp, colorTarget, colorCross); } - setColors(frustum, cone, up, target, cross) { const geometry = this.geometry; - const colorAttribute = geometry.getAttribute('color'); // near + const colorAttribute = geometry.getAttribute('color'); + + // near colorAttribute.setXYZ(0, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(1, frustum.r, frustum.g, frustum.b); // n1, n2 - colorAttribute.setXYZ(2, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(3, frustum.r, frustum.g, frustum.b); // n2, n4 - colorAttribute.setXYZ(4, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(5, frustum.r, frustum.g, frustum.b); // n4, n3 - colorAttribute.setXYZ(6, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(7, frustum.r, frustum.g, frustum.b); // n3, n1 + // far colorAttribute.setXYZ(8, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(9, frustum.r, frustum.g, frustum.b); // f1, f2 - colorAttribute.setXYZ(10, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(11, frustum.r, frustum.g, frustum.b); // f2, f4 - colorAttribute.setXYZ(12, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(13, frustum.r, frustum.g, frustum.b); // f4, f3 - colorAttribute.setXYZ(14, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(15, frustum.r, frustum.g, frustum.b); // f3, f1 + // sides colorAttribute.setXYZ(16, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(17, frustum.r, frustum.g, frustum.b); // n1, f1 - colorAttribute.setXYZ(18, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(19, frustum.r, frustum.g, frustum.b); // n2, f2 - colorAttribute.setXYZ(20, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(21, frustum.r, frustum.g, frustum.b); // n3, f3 - colorAttribute.setXYZ(22, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(23, frustum.r, frustum.g, frustum.b); // n4, f4 + // cone colorAttribute.setXYZ(24, cone.r, cone.g, cone.b); colorAttribute.setXYZ(25, cone.r, cone.g, cone.b); // p, n1 - colorAttribute.setXYZ(26, cone.r, cone.g, cone.b); colorAttribute.setXYZ(27, cone.r, cone.g, cone.b); // p, n2 - colorAttribute.setXYZ(28, cone.r, cone.g, cone.b); colorAttribute.setXYZ(29, cone.r, cone.g, cone.b); // p, n3 - colorAttribute.setXYZ(30, cone.r, cone.g, cone.b); colorAttribute.setXYZ(31, cone.r, cone.g, cone.b); // p, n4 + // up colorAttribute.setXYZ(32, up.r, up.g, up.b); colorAttribute.setXYZ(33, up.r, up.g, up.b); // u1, u2 - colorAttribute.setXYZ(34, up.r, up.g, up.b); colorAttribute.setXYZ(35, up.r, up.g, up.b); // u2, u3 - colorAttribute.setXYZ(36, up.r, up.g, up.b); colorAttribute.setXYZ(37, up.r, up.g, up.b); // u3, u1 + // target colorAttribute.setXYZ(38, target.r, target.g, target.b); colorAttribute.setXYZ(39, target.r, target.g, target.b); // c, t - colorAttribute.setXYZ(40, cross.r, cross.g, cross.b); colorAttribute.setXYZ(41, cross.r, cross.g, cross.b); // p, c + // cross colorAttribute.setXYZ(42, cross.r, cross.g, cross.b); colorAttribute.setXYZ(43, cross.r, cross.g, cross.b); // cn1, cn2 - colorAttribute.setXYZ(44, cross.r, cross.g, cross.b); colorAttribute.setXYZ(45, cross.r, cross.g, cross.b); // cn3, cn4 colorAttribute.setXYZ(46, cross.r, cross.g, cross.b); colorAttribute.setXYZ(47, cross.r, cross.g, cross.b); // cf1, cf2 - colorAttribute.setXYZ(48, cross.r, cross.g, cross.b); colorAttribute.setXYZ(49, cross.r, cross.g, cross.b); // cf3, cf4 colorAttribute.needsUpdate = true; } - update() { const geometry = this.geometry; const pointMap = this.pointMap; const w = 1, - h = 1; // we need just camera projection matrix inverse + h = 1; + + // we need just camera projection matrix inverse // world matrix must be identity - _camera.projectionMatrixInverse.copy(this.camera.projectionMatrixInverse); // center / target + _camera.projectionMatrixInverse.copy(this.camera.projectionMatrixInverse); + // center / target setPoint('c', pointMap, geometry, _camera, 0, 0, -1); - setPoint('t', pointMap, geometry, _camera, 0, 0, 1); // near + setPoint('t', pointMap, geometry, _camera, 0, 0, 1); + + // near 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('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('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('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); @@ -34751,22 +31460,16 @@ class CameraHelper extends LineSegments { setPoint('cn4', pointMap, geometry, _camera, 0, h, -1); geometry.getAttribute('position').needsUpdate = true; } - dispose() { this.geometry.dispose(); this.material.dispose(); } - } - function setPoint(point, pointMap, geometry, camera, x, y, z) { _vector.set(x, y, z).unproject(camera); - const points = pointMap[point]; - if (points !== undefined) { const position = geometry.getAttribute('position'); - for (let i = 0, l = points.length; i < l; i++) { position.setXYZ(points[i], _vector.x, _vector.y, _vector.z); } @@ -34774,7 +31477,6 @@ function setPoint(point, pointMap, geometry, camera, x, y, z) { } const _box = /*@__PURE__*/new Box3(); - class BoxHelper extends LineSegments { constructor(object, color = 0xffff00) { const 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]); @@ -34791,19 +31493,17 @@ class BoxHelper extends LineSegments { this.matrixAutoUpdate = false; this.update(); } - update(object) { if (object !== undefined) { console.warn('THREE.BoxHelper: .update() has no longer arguments.'); } - if (this.object !== undefined) { _box.setFromObject(this.object); } - if (_box.isEmpty()) return; const min = _box.min; const max = _box.max; + /* 5____4 1/___0/| @@ -34848,19 +31548,20 @@ class BoxHelper extends LineSegments { position.needsUpdate = true; this.geometry.computeBoundingSphere(); } - setFromObject(object) { this.object = object; this.update(); return this; } - copy(source, recursive) { super.copy(source, recursive); this.object = source.object; return this; } - + dispose() { + this.geometry.dispose(); + this.material.dispose(); + } } class Box3Helper extends LineSegments { @@ -34878,7 +31579,6 @@ class Box3Helper extends LineSegments { this.type = 'Box3Helper'; this.geometry.computeBoundingSphere(); } - updateMatrixWorld(force) { const box = this.box; if (box.isEmpty()) return; @@ -34887,7 +31587,10 @@ class Box3Helper extends LineSegments { this.scale.multiplyScalar(0.5); super.updateMatrixWorld(force); } - + dispose() { + this.geometry.dispose(); + this.material.dispose(); + } } class PlaneHelper extends Line { @@ -34916,7 +31619,6 @@ class PlaneHelper extends Line { toneMapped: false }))); } - updateMatrixWorld(force) { this.position.set(0, 0, 0); this.scale.set(0.5 * this.size, 0.5 * this.size, 1); @@ -34924,29 +31626,28 @@ class PlaneHelper extends Line { this.translateZ(-this.plane.constant); super.updateMatrixWorld(force); } - + dispose() { + this.geometry.dispose(); + this.material.dispose(); + this.children[0].geometry.dispose(); + this.children[0].material.dispose(); + } } const _axis = /*@__PURE__*/new Vector3(); - let _lineGeometry, _coneGeometry; - class ArrowHelper extends Object3D { // dir is assumed to be normalized + constructor(dir = new Vector3(0, 0, 1), origin = new Vector3(0, 0, 0), length = 1, color = 0xffff00, headLength = length * 0.2, headWidth = headLength * 0.2) { super(); this.type = 'ArrowHelper'; - if (_lineGeometry === undefined) { _lineGeometry = new BufferGeometry(); - _lineGeometry.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 0, 1, 0], 3)); - _coneGeometry = new CylinderGeometry(0, 0.5, 1, 5, 1); - _coneGeometry.translate(0, -0.5, 0); } - this.position.copy(origin); this.line = new Line(_lineGeometry, new LineBasicMaterial({ color: color, @@ -34963,42 +31664,42 @@ class ArrowHelper extends Object3D { this.setDirection(dir); this.setLength(length, headLength, headWidth); } - 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(); - const radians = Math.acos(dir.y); this.quaternion.setFromAxisAngle(_axis, radians); } } - setLength(length, headLength = length * 0.2, headWidth = headLength * 0.2) { this.line.scale.set(1, Math.max(0.0001, length - headLength), 1); // see #17458 - this.line.updateMatrix(); this.cone.scale.set(headWidth, headLength, headWidth); this.cone.position.y = length; this.cone.updateMatrix(); } - setColor(color) { this.line.material.color.set(color); this.cone.material.color.set(color); } - copy(source) { super.copy(source, false); this.line.copy(source.line); this.cone.copy(source.cone); return this; } - + dispose() { + this.line.geometry.dispose(); + this.line.material.dispose(); + this.cone.geometry.dispose(); + this.cone.material.dispose(); + } } class AxesHelper extends LineSegments { @@ -35015,7 +31716,6 @@ class AxesHelper extends LineSegments { super(geometry, material); this.type = 'AxesHelper'; } - setColors(xAxisColor, yAxisColor, zAxisColor) { const color = new Color(); const array = this.geometry.attributes.color.array; @@ -35031,12 +31731,10 @@ class AxesHelper extends LineSegments { this.geometry.attributes.color.needsUpdate = true; return this; } - dispose() { this.geometry.dispose(); this.material.dispose(); } - } class ShapePath { @@ -35046,62 +31744,52 @@ class ShapePath { this.subPaths = []; this.currentPath = null; } - moveTo(x, y) { this.currentPath = new Path(); this.subPaths.push(this.currentPath); this.currentPath.moveTo(x, y); return this; } - lineTo(x, y) { this.currentPath.lineTo(x, y); return this; } - quadraticCurveTo(aCPx, aCPy, aX, aY) { this.currentPath.quadraticCurveTo(aCPx, aCPy, aX, aY); return this; } - bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY) { this.currentPath.bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY); return this; } - splineThru(pts) { this.currentPath.splineThru(pts); return this; } - - toShapes(isCCW, noHoles) { + toShapes(isCCW) { function toShapesNoHoles(inSubpaths) { const shapes = []; - for (let i = 0, l = inSubpaths.length; i < l; i++) { const tmpPath = inSubpaths[i]; const tmpShape = new Shape(); tmpShape.curves = tmpPath.curves; shapes.push(tmpShape); } - return shapes; } - function isPointInsidePolygon(inPt, inPolygon) { - const polyLen = inPolygon.length; // inPt on polygon contour => immediate success or + const 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 - let inside = false; - for (let p = polyLen - 1, q = 0; q < polyLen; p = q++) { let edgeLowPt = inPolygon[p]; let edgeHighPt = inPolygon[q]; let edgeDx = edgeHighPt.x - edgeLowPt.x; let edgeDy = edgeHighPt.y - edgeLowPt.y; - if (Math.abs(edgeDy) > Number.EPSILON) { // not parallel if (edgeDy < 0) { @@ -35110,16 +31798,13 @@ class ShapePath { 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 { const 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 } @@ -35127,7 +31812,6 @@ class ShapePath { // parallel or collinear if (inPt.y !== edgeLowPt.y) continue; // parallel // edge 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; } @@ -35135,14 +31819,11 @@ class ShapePath { return inside; } - const isClockWise = ShapeUtils.isClockWise; const subPaths = this.subPaths; if (subPaths.length === 0) return []; - if (noHoles === true) return toShapesNoHoles(subPaths); let solid, tmpPath, tmpShape; const shapes = []; - if (subPaths.length === 1) { tmpPath = subPaths[0]; tmpShape = new Shape(); @@ -35150,9 +31831,10 @@ class ShapePath { shapes.push(tmpShape); return shapes; } - let holesFirst = !isClockWise(subPaths[0].getPoints()); - holesFirst = isCCW ? !holesFirst : holesFirst; // console.log("Holes first", holesFirst); + holesFirst = isCCW ? !holesFirst : holesFirst; + + // console.log("Holes first", holesFirst); const betterShapeHoles = []; const newShapes = []; @@ -35161,13 +31843,11 @@ class ShapePath { let tmpPoints; newShapes[mainIdx] = undefined; newShapeHoles[mainIdx] = []; - for (let 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] = { @@ -35176,37 +31856,35 @@ class ShapePath { }; newShapes[mainIdx].s.curves = tmpPath.curves; if (holesFirst) mainIdx++; - newShapeHoles[mainIdx] = []; //console.log('cw', i); + 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 + }); + //console.log('ccw', i); + } + } + // only Holes? -> probably all Shapes with wrong orientation if (!newShapes[0]) return toShapesNoHoles(subPaths); - if (newShapes.length > 1) { let ambiguous = false; let toChange = 0; - for (let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++) { betterShapeHoles[sIdx] = []; } - for (let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++) { const sho = newShapeHoles[sIdx]; - for (let hIdx = 0; hIdx < sho.length; hIdx++) { const ho = sho[hIdx]; let hole_unassigned = true; - for (let s2Idx = 0; s2Idx < newShapes.length; s2Idx++) { if (isPointInsidePolygon(ho.p, newShapes[s2Idx].p)) { if (sIdx !== s2Idx) toChange++; - if (hole_unassigned) { hole_unassigned = false; betterShapeHoles[s2Idx].push(ho); @@ -35215,123 +31893,120 @@ class ShapePath { } } } - if (hole_unassigned) { betterShapeHoles[sIdx].push(ho); } } } - if (toChange > 0 && ambiguous === false) { newShapeHoles = betterShapeHoles; } } - let tmpHoles; - for (let i = 0, il = newShapes.length; i < il; i++) { tmpShape = newShapes[i].s; shapes.push(tmpShape); tmpHoles = newShapeHoles[i]; - for (let j = 0, jl = tmpHoles.length; j < jl; j++) { tmpShape.holes.push(tmpHoles[j].h); } - } //console.log("shape", shapes); + } + //console.log("shape", shapes); return shapes; } - } -const _tables = /*@__PURE__*/_generateTables(); +// Fast Half Float Conversions, http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf +const _tables = /*@__PURE__*/_generateTables(); function _generateTables() { // float32 to float16 helpers + const buffer = new ArrayBuffer(4); const floatView = new Float32Array(buffer); const uint32View = new Uint32Array(buffer); const baseTable = new Uint32Array(512); const shiftTable = new Uint32Array(512); - for (let i = 0; i < 256; ++i) { - const e = i - 127; // very small number (0, -0) + const e = i - 127; + + // very small number (0, -0) if (e < -27) { baseTable[i] = 0x0000; baseTable[i | 0x100] = 0x8000; shiftTable[i] = 24; - shiftTable[i | 0x100] = 24; // small number (denorm) + shiftTable[i | 0x100] = 24; + + // small number (denorm) } else if (e < -14) { baseTable[i] = 0x0400 >> -e - 14; baseTable[i | 0x100] = 0x0400 >> -e - 14 | 0x8000; shiftTable[i] = -e - 1; - shiftTable[i | 0x100] = -e - 1; // normal number + shiftTable[i | 0x100] = -e - 1; + + // normal number } else if (e <= 15) { baseTable[i] = e + 15 << 10; baseTable[i | 0x100] = e + 15 << 10 | 0x8000; shiftTable[i] = 13; - shiftTable[i | 0x100] = 13; // large number (Infinity, -Infinity) + shiftTable[i | 0x100] = 13; + + // large number (Infinity, -Infinity) } else if (e < 128) { baseTable[i] = 0x7c00; baseTable[i | 0x100] = 0xfc00; shiftTable[i] = 24; - shiftTable[i | 0x100] = 24; // stay (NaN, Infinity, -Infinity) + shiftTable[i | 0x100] = 24; + + // stay (NaN, Infinity, -Infinity) } else { baseTable[i] = 0x7c00; baseTable[i | 0x100] = 0xfc00; shiftTable[i] = 13; shiftTable[i | 0x100] = 13; } - } // float16 to float32 helpers + } + // float16 to float32 helpers const mantissaTable = new Uint32Array(2048); const exponentTable = new Uint32Array(64); const offsetTable = new Uint32Array(64); - for (let i = 1; i < 1024; ++i) { let m = i << 13; // zero pad mantissa bits - let e = 0; // zero exponent - // normalized + // normalized while ((m & 0x00800000) === 0) { m <<= 1; e -= 0x00800000; // decrement exponent } m &= ~0x00800000; // clear leading 1 bit - e += 0x38800000; // adjust bias mantissaTable[i] = m | e; } - for (let i = 1024; i < 2048; ++i) { mantissaTable[i] = 0x38000000 + (i - 1024 << 13); } - for (let i = 1; i < 31; ++i) { exponentTable[i] = i << 23; } - exponentTable[31] = 0x47800000; exponentTable[32] = 0x80000000; - for (let i = 33; i < 63; ++i) { exponentTable[i] = 0x80000000 + (i - 32 << 23); } - exponentTable[63] = 0xc7800000; - for (let i = 1; i < 64; ++i) { if (i !== 32) { offsetTable[i] = 1024; } } - return { floatView: floatView, uint32View: uint32View, @@ -35341,8 +32016,9 @@ function _generateTables() { exponentTable: exponentTable, offsetTable: offsetTable }; -} // float32 to float16 +} +// float32 to float16 function toHalfFloat(val) { if (Math.abs(val) > 65504) console.warn('THREE.DataUtils.toHalfFloat(): Value out of range.'); @@ -35351,8 +32027,9 @@ function toHalfFloat(val) { const f = _tables.uint32View[0]; const e = f >> 23 & 0x1ff; return _tables.baseTable[e] + ((f & 0x007fffff) >> _tables.shiftTable[e]); -} // float16 to float32 +} +// float16 to float32 function fromHalfFloat(val) { const m = val >> 10; @@ -35366,33 +32043,13 @@ var DataUtils = /*#__PURE__*/Object.freeze({ fromHalfFloat: fromHalfFloat }); -class ParametricGeometry extends BufferGeometry { - constructor() { - console.error('THREE.ParametricGeometry has been moved to /examples/jsm/geometries/ParametricGeometry.js'); - super(); - } - -} // r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 - -class TextGeometry extends BufferGeometry { - constructor() { - console.error('THREE.TextGeometry has been moved to /examples/jsm/geometries/TextGeometry.js'); - super(); - } - -} // r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 - -function FontLoader() { - console.error('THREE.FontLoader has been moved to /examples/jsm/loaders/FontLoader.js'); -} // r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 - -function Font() { - console.error('THREE.Font has been moved to /examples/jsm/loaders/FontLoader.js'); -} // r134, d65e0af06644fe5a84a6fc0e372f4318f95a04c0 +// r134, d65e0af06644fe5a84a6fc0e372f4318f95a04c0 function ImmediateRenderObject() { console.error('THREE.ImmediateRenderObject has been removed.'); -} // r138, 48b05d3500acc084df50be9b4c90781ad9b8cb17 +} + +// r138, 48b05d3500acc084df50be9b4c90781ad9b8cb17 class WebGLMultisampleRenderTarget extends WebGLRenderTarget { constructor(width, height, options) { @@ -35400,23 +32057,195 @@ class WebGLMultisampleRenderTarget extends WebGLRenderTarget { super(width, height, options); this.samples = 4; } +} -} // r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce +// r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce class DataTexture2DArray extends DataArrayTexture { constructor(data, width, height, depth) { console.warn('THREE.DataTexture2DArray has been renamed to DataArrayTexture.'); super(data, width, height, depth); } +} -} // r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce +// r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce class DataTexture3D extends Data3DTexture { constructor(data, width, height, depth) { console.warn('THREE.DataTexture3D has been renamed to Data3DTexture.'); super(data, width, height, depth); } +} + +// r144 + +class BoxBufferGeometry extends BoxGeometry { + constructor(width, height, depth, widthSegments, heightSegments, depthSegments) { + console.warn('THREE.BoxBufferGeometry has been renamed to THREE.BoxGeometry.'); + super(width, height, depth, widthSegments, heightSegments, depthSegments); + } +} + +// r144 + +class CapsuleBufferGeometry extends CapsuleGeometry { + constructor(radius, length, capSegments, radialSegments) { + console.warn('THREE.CapsuleBufferGeometry has been renamed to THREE.CapsuleGeometry.'); + super(radius, length, capSegments, radialSegments); + } +} + +// r144 + +class CircleBufferGeometry extends CircleGeometry { + constructor(radius, segments, thetaStart, thetaLength) { + console.warn('THREE.CircleBufferGeometry has been renamed to THREE.CircleGeometry.'); + super(radius, segments, thetaStart, thetaLength); + } +} + +// r144 + +class ConeBufferGeometry extends ConeGeometry { + constructor(radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) { + console.warn('THREE.ConeBufferGeometry has been renamed to THREE.ConeGeometry.'); + super(radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength); + } +} + +// r144 + +class CylinderBufferGeometry extends CylinderGeometry { + constructor(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) { + console.warn('THREE.CylinderBufferGeometry has been renamed to THREE.CylinderGeometry.'); + super(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength); + } +} + +// r144 + +class DodecahedronBufferGeometry extends DodecahedronGeometry { + constructor(radius, detail) { + console.warn('THREE.DodecahedronBufferGeometry has been renamed to THREE.DodecahedronGeometry.'); + super(radius, detail); + } +} + +// r144 + +class ExtrudeBufferGeometry extends ExtrudeGeometry { + constructor(shapes, options) { + console.warn('THREE.ExtrudeBufferGeometry has been renamed to THREE.ExtrudeGeometry.'); + super(shapes, options); + } +} + +// r144 + +class IcosahedronBufferGeometry extends IcosahedronGeometry { + constructor(radius, detail) { + console.warn('THREE.IcosahedronBufferGeometry has been renamed to THREE.IcosahedronGeometry.'); + super(radius, detail); + } +} + +// r144 + +class LatheBufferGeometry extends LatheGeometry { + constructor(points, segments, phiStart, phiLength) { + console.warn('THREE.LatheBufferGeometry has been renamed to THREE.LatheGeometry.'); + super(points, segments, phiStart, phiLength); + } +} + +// r144 + +class OctahedronBufferGeometry extends OctahedronGeometry { + constructor(radius, detail) { + console.warn('THREE.OctahedronBufferGeometry has been renamed to THREE.OctahedronGeometry.'); + super(radius, detail); + } +} + +// r144 + +class PlaneBufferGeometry extends PlaneGeometry { + constructor(width, height, widthSegments, heightSegments) { + console.warn('THREE.PlaneBufferGeometry has been renamed to THREE.PlaneGeometry.'); + super(width, height, widthSegments, heightSegments); + } +} + +// r144 + +class PolyhedronBufferGeometry extends PolyhedronGeometry { + constructor(vertices, indices, radius, detail) { + console.warn('THREE.PolyhedronBufferGeometry has been renamed to THREE.PolyhedronGeometry.'); + super(vertices, indices, radius, detail); + } +} + +// r144 + +class RingBufferGeometry extends RingGeometry { + constructor(innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength) { + console.warn('THREE.RingBufferGeometry has been renamed to THREE.RingGeometry.'); + super(innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength); + } +} + +// r144 + +class ShapeBufferGeometry extends ShapeGeometry { + constructor(shapes, curveSegments) { + console.warn('THREE.ShapeBufferGeometry has been renamed to THREE.ShapeGeometry.'); + super(shapes, curveSegments); + } +} + +// r144 + +class SphereBufferGeometry extends SphereGeometry { + constructor(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength) { + console.warn('THREE.SphereBufferGeometry has been renamed to THREE.SphereGeometry.'); + super(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength); + } +} + +// r144 + +class TetrahedronBufferGeometry extends TetrahedronGeometry { + constructor(radius, detail) { + console.warn('THREE.TetrahedronBufferGeometry has been renamed to THREE.TetrahedronGeometry.'); + super(radius, detail); + } +} + +// r144 + +class TorusBufferGeometry extends TorusGeometry { + constructor(radius, tube, radialSegments, tubularSegments, arc) { + console.warn('THREE.TorusBufferGeometry has been renamed to THREE.TorusGeometry.'); + super(radius, tube, radialSegments, tubularSegments, arc); + } +} + +// r144 + +class TorusKnotBufferGeometry extends TorusKnotGeometry { + constructor(radius, tube, tubularSegments, radialSegments, p, q) { + console.warn('THREE.TorusKnotBufferGeometry has been renamed to THREE.TorusKnotGeometry.'); + super(radius, tube, tubularSegments, radialSegments, p, q); + } +} + +// r144 +class TubeBufferGeometry extends TubeGeometry { + constructor(path, tubularSegments, radius, radialSegments, closed) { + console.warn('THREE.TubeBufferGeometry has been renamed to THREE.TubeGeometry.'); + super(path, tubularSegments, radius, radialSegments, closed); + } } if (typeof __THREE_DEVTOOLS__ !== 'undefined') { @@ -35426,7 +32255,6 @@ if (typeof __THREE_DEVTOOLS__ !== 'undefined') { } })); } - if (typeof window !== 'undefined') { if (window.__THREE__) { console.warn('WARNING: Multiple instances of Three.js being imported.'); @@ -35467,7 +32295,7 @@ exports.BooleanKeyframeTrack = BooleanKeyframeTrack; exports.Box2 = Box2; exports.Box3 = Box3; exports.Box3Helper = Box3Helper; -exports.BoxBufferGeometry = BoxGeometry; +exports.BoxBufferGeometry = BoxBufferGeometry; exports.BoxGeometry = BoxGeometry; exports.BoxHelper = BoxHelper; exports.BufferAttribute = BufferAttribute; @@ -35478,20 +32306,21 @@ exports.Cache = Cache; exports.Camera = Camera; exports.CameraHelper = CameraHelper; exports.CanvasTexture = CanvasTexture; -exports.CapsuleBufferGeometry = CapsuleGeometry; +exports.CapsuleBufferGeometry = CapsuleBufferGeometry; exports.CapsuleGeometry = CapsuleGeometry; exports.CatmullRomCurve3 = CatmullRomCurve3; exports.CineonToneMapping = CineonToneMapping; -exports.CircleBufferGeometry = CircleGeometry; +exports.CircleBufferGeometry = CircleBufferGeometry; exports.CircleGeometry = CircleGeometry; exports.ClampToEdgeWrapping = ClampToEdgeWrapping; exports.Clock = Clock; exports.Color = Color; exports.ColorKeyframeTrack = ColorKeyframeTrack; exports.ColorManagement = ColorManagement; +exports.CompressedArrayTexture = CompressedArrayTexture; exports.CompressedTexture = CompressedTexture; exports.CompressedTextureLoader = CompressedTextureLoader; -exports.ConeBufferGeometry = ConeGeometry; +exports.ConeBufferGeometry = ConeBufferGeometry; exports.ConeGeometry = ConeGeometry; exports.CubeCamera = CubeCamera; exports.CubeReflectionMapping = CubeReflectionMapping; @@ -35510,7 +32339,7 @@ exports.Curve = Curve; exports.CurvePath = CurvePath; exports.CustomBlending = CustomBlending; exports.CustomToneMapping = CustomToneMapping; -exports.CylinderBufferGeometry = CylinderGeometry; +exports.CylinderBufferGeometry = CylinderBufferGeometry; exports.CylinderGeometry = CylinderGeometry; exports.Cylindrical = Cylindrical; exports.Data3DTexture = Data3DTexture; @@ -35529,7 +32358,7 @@ exports.DepthTexture = DepthTexture; exports.DirectionalLight = DirectionalLight; exports.DirectionalLightHelper = DirectionalLightHelper; exports.DiscreteInterpolant = DiscreteInterpolant; -exports.DodecahedronBufferGeometry = DodecahedronGeometry; +exports.DodecahedronBufferGeometry = DodecahedronBufferGeometry; exports.DodecahedronGeometry = DodecahedronGeometry; exports.DoubleSide = DoubleSide; exports.DstAlphaFactor = DstAlphaFactor; @@ -35545,18 +32374,15 @@ exports.EquirectangularReflectionMapping = EquirectangularReflectionMapping; exports.EquirectangularRefractionMapping = EquirectangularRefractionMapping; exports.Euler = Euler; exports.EventDispatcher = EventDispatcher; -exports.ExtrudeBufferGeometry = ExtrudeGeometry; +exports.ExtrudeBufferGeometry = ExtrudeBufferGeometry; exports.ExtrudeGeometry = ExtrudeGeometry; exports.FileLoader = FileLoader; -exports.FlatShading = FlatShading; exports.Float16BufferAttribute = Float16BufferAttribute; exports.Float32BufferAttribute = Float32BufferAttribute; exports.Float64BufferAttribute = Float64BufferAttribute; exports.FloatType = FloatType; exports.Fog = Fog; exports.FogExp2 = FogExp2; -exports.Font = Font; -exports.FontLoader = FontLoader; exports.FramebufferTexture = FramebufferTexture; exports.FrontSide = FrontSide; exports.Frustum = Frustum; @@ -35573,7 +32399,7 @@ exports.HalfFloatType = HalfFloatType; exports.HemisphereLight = HemisphereLight; exports.HemisphereLightHelper = HemisphereLightHelper; exports.HemisphereLightProbe = HemisphereLightProbe; -exports.IcosahedronBufferGeometry = IcosahedronGeometry; +exports.IcosahedronBufferGeometry = IcosahedronBufferGeometry; exports.IcosahedronGeometry = IcosahedronGeometry; exports.ImageBitmapLoader = ImageBitmapLoader; exports.ImageLoader = ImageLoader; @@ -35599,7 +32425,7 @@ exports.InvertStencilOp = InvertStencilOp; exports.KeepStencilOp = KeepStencilOp; exports.KeyframeTrack = KeyframeTrack; exports.LOD = LOD; -exports.LatheBufferGeometry = LatheGeometry; +exports.LatheBufferGeometry = LatheBufferGeometry; exports.LatheGeometry = LatheGeometry; exports.Layers = Layers; exports.LessDepth = LessDepth; @@ -35674,7 +32500,7 @@ exports.NumberKeyframeTrack = NumberKeyframeTrack; exports.Object3D = Object3D; exports.ObjectLoader = ObjectLoader; exports.ObjectSpaceNormalMap = ObjectSpaceNormalMap; -exports.OctahedronBufferGeometry = OctahedronGeometry; +exports.OctahedronBufferGeometry = OctahedronBufferGeometry; exports.OctahedronGeometry = OctahedronGeometry; exports.OneFactor = OneFactor; exports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor; @@ -35685,11 +32511,10 @@ exports.OrthographicCamera = OrthographicCamera; exports.PCFShadowMap = PCFShadowMap; exports.PCFSoftShadowMap = PCFSoftShadowMap; exports.PMREMGenerator = PMREMGenerator; -exports.ParametricGeometry = ParametricGeometry; exports.Path = Path; exports.PerspectiveCamera = PerspectiveCamera; exports.Plane = Plane; -exports.PlaneBufferGeometry = PlaneGeometry; +exports.PlaneBufferGeometry = PlaneBufferGeometry; exports.PlaneGeometry = PlaneGeometry; exports.PlaneHelper = PlaneHelper; exports.PointLight = PointLight; @@ -35697,7 +32522,7 @@ exports.PointLightHelper = PointLightHelper; exports.Points = Points; exports.PointsMaterial = PointsMaterial; exports.PolarGridHelper = PolarGridHelper; -exports.PolyhedronBufferGeometry = PolyhedronGeometry; +exports.PolyhedronBufferGeometry = PolyhedronBufferGeometry; exports.PolyhedronGeometry = PolyhedronGeometry; exports.PositionalAudio = PositionalAudio; exports.PropertyBinding = PropertyBinding; @@ -35750,7 +32575,7 @@ exports.ReinhardToneMapping = ReinhardToneMapping; exports.RepeatWrapping = RepeatWrapping; exports.ReplaceStencilOp = ReplaceStencilOp; exports.ReverseSubtractEquation = ReverseSubtractEquation; -exports.RingBufferGeometry = RingGeometry; +exports.RingBufferGeometry = RingBufferGeometry; exports.RingGeometry = RingGeometry; exports.SRGBColorSpace = SRGBColorSpace; exports.Scene = Scene; @@ -35759,7 +32584,7 @@ exports.ShaderLib = ShaderLib; exports.ShaderMaterial = ShaderMaterial; exports.ShadowMaterial = ShadowMaterial; exports.Shape = Shape; -exports.ShapeBufferGeometry = ShapeGeometry; +exports.ShapeBufferGeometry = ShapeBufferGeometry; exports.ShapeGeometry = ShapeGeometry; exports.ShapePath = ShapePath; exports.ShapeUtils = ShapeUtils; @@ -35767,10 +32592,9 @@ exports.ShortType = ShortType; exports.Skeleton = Skeleton; exports.SkeletonHelper = SkeletonHelper; exports.SkinnedMesh = SkinnedMesh; -exports.SmoothShading = SmoothShading; exports.Source = Source; exports.Sphere = Sphere; -exports.SphereBufferGeometry = SphereGeometry; +exports.SphereBufferGeometry = SphereBufferGeometry; exports.SphereGeometry = SphereGeometry; exports.Spherical = Spherical; exports.SphericalHarmonics3 = SphericalHarmonics3; @@ -35794,20 +32618,19 @@ exports.SubtractEquation = SubtractEquation; exports.SubtractiveBlending = SubtractiveBlending; exports.TOUCH = TOUCH; exports.TangentSpaceNormalMap = TangentSpaceNormalMap; -exports.TetrahedronBufferGeometry = TetrahedronGeometry; +exports.TetrahedronBufferGeometry = TetrahedronBufferGeometry; exports.TetrahedronGeometry = TetrahedronGeometry; -exports.TextGeometry = TextGeometry; exports.Texture = Texture; exports.TextureLoader = TextureLoader; -exports.TorusBufferGeometry = TorusGeometry; +exports.TorusBufferGeometry = TorusBufferGeometry; exports.TorusGeometry = TorusGeometry; -exports.TorusKnotBufferGeometry = TorusKnotGeometry; +exports.TorusKnotBufferGeometry = TorusKnotBufferGeometry; exports.TorusKnotGeometry = TorusKnotGeometry; exports.Triangle = Triangle; exports.TriangleFanDrawMode = TriangleFanDrawMode; exports.TriangleStripDrawMode = TriangleStripDrawMode; exports.TrianglesDrawMode = TrianglesDrawMode; -exports.TubeBufferGeometry = TubeGeometry; +exports.TubeBufferGeometry = TubeBufferGeometry; exports.TubeGeometry = TubeGeometry; exports.UVMapping = UVMapping; exports.Uint16BufferAttribute = Uint16BufferAttribute; diff --git a/build/three.js b/build/three.js index 5059b392b64a3f..e709d5fcf83c8d 100644 --- a/build/three.js +++ b/build/three.js @@ -9,7 +9,7 @@ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.THREE = {})); })(this, (function (exports) { 'use strict'; - const REVISION = '143'; + const REVISION = '147'; const MOUSE = { LEFT: 0, MIDDLE: 1, @@ -35,8 +35,6 @@ const FrontSide = 0; const BackSide = 1; const DoubleSide = 2; - const FlatShading = 1; - const SmoothShading = 2; const NoBlending = 0; const NormalBlending = 1; const AdditiveBlending = 2; @@ -107,7 +105,7 @@ const UnsignedShort5551Type = 1018; const UnsignedInt248Type = 1020; const AlphaFormat = 1021; - const RGBFormat = 1022; + const RGBFormat = 1022; // @deprecated since r137 const RGBAFormat = 1023; const LuminanceFormat = 1024; const LuminanceAlphaFormat = 1025; @@ -163,8 +161,9 @@ const BasicDepthPacking = 3200; const RGBADepthPacking = 3201; const TangentSpaceNormalMap = 0; - const ObjectSpaceNormalMap = 1; // Color space string identifiers, matching CSS Color Module Level 4 and WebGPU names where available. + const ObjectSpaceNormalMap = 1; + // Color space string identifiers, matching CSS Color Module Level 4 and WebGPU names where available. const NoColorSpace = ''; const SRGBColorSpace = 'srgb'; const LinearSRGBColorSpace = 'srgb-linear'; @@ -200,179 +199,168 @@ /** * https://github.com/mrdoob/eventdispatcher.js/ */ + class EventDispatcher { addEventListener(type, listener) { if (this._listeners === undefined) this._listeners = {}; const listeners = this._listeners; - if (listeners[type] === undefined) { listeners[type] = []; } - if (listeners[type].indexOf(listener) === -1) { listeners[type].push(listener); } } - hasEventListener(type, listener) { if (this._listeners === undefined) return false; const listeners = this._listeners; return listeners[type] !== undefined && listeners[type].indexOf(listener) !== -1; } - removeEventListener(type, listener) { if (this._listeners === undefined) return; const listeners = this._listeners; const listenerArray = listeners[type]; - if (listenerArray !== undefined) { const index = listenerArray.indexOf(listener); - if (index !== -1) { listenerArray.splice(index, 1); } } } - dispatchEvent(event) { if (this._listeners === undefined) return; const listeners = this._listeners; const listenerArray = listeners[event.type]; - if (listenerArray !== undefined) { - event.target = this; // Make a copy, in case listeners are removed while iterating. + event.target = this; + // Make a copy, in case listeners are removed while iterating. const array = listenerArray.slice(0); - for (let i = 0, l = array.length; i < l; i++) { array[i].call(this, event); } - event.target = null; } } - } const _lut = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '0a', '0b', '0c', '0d', '0e', '0f', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '1a', '1b', '1c', '1d', '1e', '1f', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '2a', '2b', '2c', '2d', '2e', '2f', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '3a', '3b', '3c', '3d', '3e', '3f', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '4a', '4b', '4c', '4d', '4e', '4f', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '5a', '5b', '5c', '5d', '5e', '5f', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '6a', '6b', '6c', '6d', '6e', '6f', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '7a', '7b', '7c', '7d', '7e', '7f', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '8a', '8b', '8c', '8d', '8e', '8f', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '9a', '9b', '9c', '9d', '9e', '9f', 'a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9', 'aa', 'ab', 'ac', 'ad', 'ae', 'af', 'b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'ba', 'bb', 'bc', 'bd', 'be', 'bf', 'c0', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9', 'ca', 'cb', 'cc', 'cd', 'ce', 'cf', 'd0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9', 'da', 'db', 'dc', 'dd', 'de', 'df', 'e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9', 'ea', 'eb', 'ec', 'ed', 'ee', 'ef', 'f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'fa', 'fb', 'fc', 'fd', 'fe', 'ff']; let _seed = 1234567; const DEG2RAD = Math.PI / 180; - const RAD2DEG = 180 / Math.PI; // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136 + const RAD2DEG = 180 / Math.PI; + // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136 function generateUUID() { const d0 = Math.random() * 0xffffffff | 0; const d1 = Math.random() * 0xffffffff | 0; const d2 = Math.random() * 0xffffffff | 0; const d3 = Math.random() * 0xffffffff | 0; - const uuid = _lut[d0 & 0xff] + _lut[d0 >> 8 & 0xff] + _lut[d0 >> 16 & 0xff] + _lut[d0 >> 24 & 0xff] + '-' + _lut[d1 & 0xff] + _lut[d1 >> 8 & 0xff] + '-' + _lut[d1 >> 16 & 0x0f | 0x40] + _lut[d1 >> 24 & 0xff] + '-' + _lut[d2 & 0x3f | 0x80] + _lut[d2 >> 8 & 0xff] + '-' + _lut[d2 >> 16 & 0xff] + _lut[d2 >> 24 & 0xff] + _lut[d3 & 0xff] + _lut[d3 >> 8 & 0xff] + _lut[d3 >> 16 & 0xff] + _lut[d3 >> 24 & 0xff]; // .toLowerCase() here flattens concatenated strings to save heap memory space. + const uuid = _lut[d0 & 0xff] + _lut[d0 >> 8 & 0xff] + _lut[d0 >> 16 & 0xff] + _lut[d0 >> 24 & 0xff] + '-' + _lut[d1 & 0xff] + _lut[d1 >> 8 & 0xff] + '-' + _lut[d1 >> 16 & 0x0f | 0x40] + _lut[d1 >> 24 & 0xff] + '-' + _lut[d2 & 0x3f | 0x80] + _lut[d2 >> 8 & 0xff] + '-' + _lut[d2 >> 16 & 0xff] + _lut[d2 >> 24 & 0xff] + _lut[d3 & 0xff] + _lut[d3 >> 8 & 0xff] + _lut[d3 >> 16 & 0xff] + _lut[d3 >> 24 & 0xff]; + // .toLowerCase() here flattens concatenated strings to save heap memory space. return uuid.toLowerCase(); } - function clamp(value, min, max) { return Math.max(min, Math.min(max, value)); - } // compute euclidean modulo of m % n - // https://en.wikipedia.org/wiki/Modulo_operation - + } + // compute euclidean modulo of m % n + // https://en.wikipedia.org/wiki/Modulo_operation function euclideanModulo(n, m) { return (n % m + m) % m; - } // Linear mapping from range to range - + } + // Linear mapping from range to range function mapLinear(x, a1, a2, b1, b2) { return b1 + (x - a1) * (b2 - b1) / (a2 - a1); - } // https://www.gamedev.net/tutorials/programming/general-and-gameplay-programming/inverse-lerp-a-super-useful-yet-often-overlooked-function-r5230/ - + } + // https://www.gamedev.net/tutorials/programming/general-and-gameplay-programming/inverse-lerp-a-super-useful-yet-often-overlooked-function-r5230/ function inverseLerp(x, y, value) { if (x !== y) { return (value - x) / (y - x); } else { return 0; } - } // https://en.wikipedia.org/wiki/Linear_interpolation - + } + // https://en.wikipedia.org/wiki/Linear_interpolation function lerp(x, y, t) { return (1 - t) * x + t * y; - } // http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/ - + } + // http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/ function damp(x, y, lambda, dt) { return lerp(x, y, 1 - Math.exp(-lambda * dt)); - } // https://www.desmos.com/calculator/vcsjnyz7x4 - + } + // https://www.desmos.com/calculator/vcsjnyz7x4 function pingpong(x, length = 1) { return length - Math.abs(euclideanModulo(x, length * 2) - length); - } // http://en.wikipedia.org/wiki/Smoothstep - + } + // http://en.wikipedia.org/wiki/Smoothstep function smoothstep(x, min, max) { if (x <= min) return 0; if (x >= max) return 1; x = (x - min) / (max - min); return x * x * (3 - 2 * x); } - function smootherstep(x, min, max) { if (x <= min) return 0; if (x >= max) return 1; x = (x - min) / (max - min); return x * x * x * (x * (x * 6 - 15) + 10); - } // Random integer from interval - + } + // Random integer from interval function randInt(low, high) { return low + Math.floor(Math.random() * (high - low + 1)); - } // Random float from interval - + } + // Random float from interval function randFloat(low, high) { return low + Math.random() * (high - low); - } // Random float from <-range/2, range/2> interval - + } + // Random float from <-range/2, range/2> interval function randFloatSpread(range) { return range * (0.5 - Math.random()); - } // Deterministic pseudo-random float in the interval [ 0, 1 ] - + } + // Deterministic pseudo-random float in the interval [ 0, 1 ] function seededRandom(s) { - if (s !== undefined) _seed = s; // Mulberry32 generator + if (s !== undefined) _seed = s; + + // Mulberry32 generator let t = _seed += 0x6D2B79F5; t = Math.imul(t ^ t >>> 15, t | 1); t ^= t + Math.imul(t ^ t >>> 7, t | 61); return ((t ^ t >>> 14) >>> 0) / 4294967296; } - function degToRad(degrees) { return degrees * DEG2RAD; } - function radToDeg(radians) { return radians * RAD2DEG; } - function isPowerOfTwo(value) { return (value & value - 1) === 0 && value !== 0; } - function ceilPowerOfTwo(value) { return Math.pow(2, Math.ceil(Math.log(value) / Math.LN2)); } - function floorPowerOfTwo(value) { return Math.pow(2, Math.floor(Math.log(value) / Math.LN2)); } - function setQuaternionFromProperEuler(q, a, b, c, order) { // Intrinsic Proper Euler Angles - see https://en.wikipedia.org/wiki/Euler_angles + // rotations are applied to the axes in the order specified by 'order' // rotation by angle 'a' is applied first, then by angle 'b', then by angle 'c' // angles are in radians + const cos = Math.cos; const sin = Math.sin; const c2 = cos(b / 2); @@ -383,76 +371,57 @@ const s1_3 = sin((a - c) / 2); const c3_1 = cos((c - a) / 2); const s3_1 = sin((c - a) / 2); - switch (order) { case 'XYX': q.set(c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13); break; - case 'YZY': q.set(s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13); break; - case 'ZXZ': q.set(s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13); break; - case 'XZX': q.set(c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13); break; - case 'YXY': q.set(s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13); break; - case 'ZYZ': q.set(s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13); break; - default: console.warn('THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order); } } - - function denormalize$1(value, array) { + function denormalize(value, array) { switch (array.constructor) { case Float32Array: return value; - case Uint16Array: return value / 65535.0; - case Uint8Array: return value / 255.0; - case Int16Array: return Math.max(value / 32767.0, -1.0); - case Int8Array: return Math.max(value / 127.0, -1.0); - default: throw new Error('Invalid component type.'); } } - function normalize(value, array) { switch (array.constructor) { case Float32Array: return value; - case Uint16Array: return Math.round(value * 65535.0); - case Uint8Array: return Math.round(value * 255.0); - case Int16Array: return Math.round(value * 32767.0); - case Int8Array: return Math.round(value * 127.0); - default: throw new Error('Invalid component type.'); } @@ -483,7 +452,7 @@ floorPowerOfTwo: floorPowerOfTwo, setQuaternionFromProperEuler: setQuaternionFromProperEuler, normalize: normalize, - denormalize: denormalize$1 + denormalize: denormalize }); class Vector2 { @@ -492,321 +461,263 @@ this.x = x; this.y = y; } - get width() { return this.x; } - set width(value) { this.x = value; } - get height() { return this.y; } - set height(value) { this.y = value; } - set(x, y) { this.x = x; this.y = y; return this; } - setScalar(scalar) { this.x = scalar; this.y = scalar; return this; } - setX(x) { this.x = x; return this; } - setY(y) { this.y = y; return this; } - setComponent(index, value) { switch (index) { case 0: this.x = value; break; - case 1: this.y = value; break; - default: throw new Error('index is out of range: ' + index); } - return this; } - getComponent(index) { switch (index) { case 0: return this.x; - case 1: return this.y; - default: throw new Error('index is out of range: ' + index); } } - clone() { return new this.constructor(this.x, this.y); } - copy(v) { this.x = v.x; this.y = v.y; return this; } - add(v) { this.x += v.x; this.y += v.y; return this; } - addScalar(s) { this.x += s; this.y += s; return this; } - addVectors(a, b) { this.x = a.x + b.x; this.y = a.y + b.y; return this; } - addScaledVector(v, s) { this.x += v.x * s; this.y += v.y * s; return this; } - sub(v) { this.x -= v.x; this.y -= v.y; return this; } - subScalar(s) { this.x -= s; this.y -= s; return this; } - subVectors(a, b) { this.x = a.x - b.x; this.y = a.y - b.y; return this; } - multiply(v) { this.x *= v.x; this.y *= v.y; return this; } - multiplyScalar(scalar) { this.x *= scalar; this.y *= scalar; return this; } - divide(v) { this.x /= v.x; this.y /= v.y; return this; } - divideScalar(scalar) { return this.multiplyScalar(1 / scalar); } - applyMatrix3(m) { const x = this.x, - y = this.y; + y = this.y; const 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; } - min(v) { this.x = Math.min(this.x, v.x); this.y = Math.min(this.y, v.y); return this; } - max(v) { this.x = Math.max(this.x, v.x); this.y = Math.max(this.y, v.y); return this; } - clamp(min, max) { // assumes min < max, componentwise + this.x = Math.max(min.x, Math.min(max.x, this.x)); this.y = Math.max(min.y, Math.min(max.y, this.y)); return this; } - clampScalar(minVal, maxVal) { this.x = Math.max(minVal, Math.min(maxVal, this.x)); this.y = Math.max(minVal, Math.min(maxVal, this.y)); return this; } - clampLength(min, max) { const length = this.length(); return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length))); } - floor() { this.x = Math.floor(this.x); this.y = Math.floor(this.y); return this; } - ceil() { this.x = Math.ceil(this.x); this.y = Math.ceil(this.y); return this; } - round() { this.x = Math.round(this.x); this.y = Math.round(this.y); return this; } - roundToZero() { this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x); this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y); return this; } - negate() { this.x = -this.x; this.y = -this.y; return this; } - dot(v) { return this.x * v.x + this.y * v.y; } - cross(v) { return this.x * v.y - this.y * v.x; } - lengthSq() { return this.x * this.x + this.y * this.y; } - length() { return Math.sqrt(this.x * this.x + this.y * this.y); } - manhattanLength() { return Math.abs(this.x) + Math.abs(this.y); } - normalize() { return this.divideScalar(this.length() || 1); } - angle() { // computes the angle in radians with respect to the positive x-axis + const angle = Math.atan2(-this.y, -this.x) + Math.PI; return angle; } - distanceTo(v) { return Math.sqrt(this.distanceToSquared(v)); } - distanceToSquared(v) { const dx = this.x - v.x, - dy = this.y - v.y; + dy = this.y - v.y; return dx * dx + dy * dy; } - manhattanDistanceTo(v) { return Math.abs(this.x - v.x) + Math.abs(this.y - v.y); } - setLength(length) { return this.normalize().multiplyScalar(length); } - lerp(v, alpha) { this.x += (v.x - this.x) * alpha; this.y += (v.y - this.y) * alpha; return this; } - lerpVectors(v1, v2, alpha) { this.x = v1.x + (v2.x - v1.x) * alpha; this.y = v1.y + (v2.y - v1.y) * alpha; return this; } - equals(v) { return v.x === this.x && v.y === this.y; } - fromArray(array, offset = 0) { this.x = array[offset]; this.y = array[offset + 1]; return this; } - toArray(array = [], offset = 0) { array[offset] = this.x; array[offset + 1] = this.y; return array; } - fromBufferAttribute(attribute, index) { this.x = attribute.getX(index); this.y = attribute.getY(index); return this; } - rotateAround(center, angle) { const c = Math.cos(angle), - s = Math.sin(angle); + s = Math.sin(angle); const x = this.x - center.x; const y = this.y - center.y; this.x = x * c - y * s + center.x; this.y = x * s + y * c + center.y; return this; } - random() { this.x = Math.random(); this.y = Math.random(); return this; } - *[Symbol.iterator]() { yield this.x; yield this.y; } - } class Matrix3 { @@ -814,7 +725,6 @@ Matrix3.prototype.isMatrix3 = true; this.elements = [1, 0, 0, 0, 1, 0, 0, 0, 1]; } - set(n11, n12, n13, n21, n22, n23, n31, n32, n33) { const te = this.elements; te[0] = n11; @@ -828,12 +738,10 @@ te[8] = n33; return this; } - identity() { this.set(1, 0, 0, 0, 1, 0, 0, 0, 1); return this; } - copy(m) { const te = this.elements; const me = m.elements; @@ -848,50 +756,45 @@ te[8] = me[8]; return this; } - extractBasis(xAxis, yAxis, zAxis) { xAxis.setFromMatrix3Column(this, 0); yAxis.setFromMatrix3Column(this, 1); zAxis.setFromMatrix3Column(this, 2); return this; } - setFromMatrix4(m) { const me = m.elements; this.set(me[0], me[4], me[8], me[1], me[5], me[9], me[2], me[6], me[10]); return this; } - multiply(m) { return this.multiplyMatrices(this, m); } - premultiply(m) { return this.multiplyMatrices(m, this); } - multiplyMatrices(a, b) { const ae = a.elements; const be = b.elements; const te = this.elements; const a11 = ae[0], - a12 = ae[3], - a13 = ae[6]; + a12 = ae[3], + a13 = ae[6]; const a21 = ae[1], - a22 = ae[4], - a23 = ae[7]; + a22 = ae[4], + a23 = ae[7]; const a31 = ae[2], - a32 = ae[5], - a33 = ae[8]; + a32 = ae[5], + a33 = ae[8]; const b11 = be[0], - b12 = be[3], - b13 = be[6]; + b12 = be[3], + b13 = be[6]; const b21 = be[1], - b22 = be[4], - b23 = be[7]; + b22 = be[4], + b23 = be[7]; const b31 = be[2], - b32 = be[5], - b33 = be[8]; + 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; @@ -903,7 +806,6 @@ te[8] = a31 * b13 + a32 * b23 + a33 * b33; return this; } - multiplyScalar(s) { const te = this.elements; te[0] *= s; @@ -917,36 +819,34 @@ te[8] *= s; return this; } - determinant() { const te = this.elements; const a = te[0], - b = te[1], - c = te[2], - d = te[3], - e = te[4], - f = te[5], - g = te[6], - h = te[7], - i = te[8]; + b = te[1], + c = te[2], + d = te[3], + e = te[4], + f = te[5], + g = te[6], + h = te[7], + i = te[8]; return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g; } - invert() { const te = this.elements, - n11 = te[0], - n21 = te[1], - n31 = te[2], - n12 = te[3], - n22 = te[4], - n32 = te[5], - n13 = te[6], - n23 = te[7], - n33 = te[8], - t11 = n33 * n22 - n32 * n23, - t12 = n32 * n13 - n33 * n12, - t13 = n23 * n12 - n22 * n13, - det = n11 * t11 + n21 * t12 + n31 * t13; + n11 = te[0], + n21 = te[1], + n31 = te[2], + n12 = te[3], + n22 = te[4], + n32 = te[5], + n13 = te[6], + n23 = te[7], + n33 = te[8], + t11 = n33 * n22 - n32 * n23, + t12 = n32 * n13 - n33 * n12, + t13 = n23 * n12 - n22 * n13, + det = n11 * t11 + n21 * t12 + n31 * t13; if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0); const detInv = 1 / det; te[0] = t11 * detInv; @@ -960,7 +860,6 @@ te[8] = (n22 * n11 - n21 * n12) * detInv; return this; } - transpose() { let tmp; const m = this.elements; @@ -975,11 +874,9 @@ m[7] = tmp; return this; } - getNormalMatrix(matrix4) { return this.setFromMatrix4(matrix4).invert().transpose(); } - transposeIntoArray(r) { const m = this.elements; r[0] = m[0]; @@ -993,7 +890,6 @@ r[8] = m[8]; return this; } - setUvTransform(tx, ty, sx, sy, rotation, cx, cy) { const c = Math.cos(rotation); const s = Math.sin(rotation); @@ -1001,66 +897,56 @@ return this; } + // + scale(sx, sy) { - const te = this.elements; - te[0] *= sx; - te[3] *= sx; - te[6] *= sx; - te[1] *= sy; - te[4] *= sy; - te[7] *= sy; + this.premultiply(_m3.makeScale(sx, sy)); return this; } - rotate(theta) { + this.premultiply(_m3.makeRotation(-theta)); + return this; + } + translate(tx, ty) { + this.premultiply(_m3.makeTranslation(tx, ty)); + return this; + } + + // for 2D Transforms + + makeTranslation(x, y) { + this.set(1, 0, x, 0, 1, y, 0, 0, 1); + return this; + } + makeRotation(theta) { + // counterclockwise + const c = Math.cos(theta); const s = Math.sin(theta); - const te = this.elements; - const a11 = te[0], - a12 = te[3], - a13 = te[6]; - const a21 = te[1], - a22 = te[4], - a23 = te[7]; - te[0] = c * a11 + s * a21; - te[3] = c * a12 + s * a22; - te[6] = c * a13 + s * a23; - te[1] = -s * a11 + c * a21; - te[4] = -s * a12 + c * a22; - te[7] = -s * a13 + c * a23; + this.set(c, -s, 0, s, c, 0, 0, 0, 1); return this; } - - translate(tx, ty) { - const te = this.elements; - te[0] += tx * te[2]; - te[3] += tx * te[5]; - te[6] += tx * te[8]; - te[1] += ty * te[2]; - te[4] += ty * te[5]; - te[7] += ty * te[8]; + makeScale(x, y) { + this.set(x, 0, 0, 0, y, 0, 0, 0, 1); return this; } + // + equals(matrix) { const te = this.elements; const me = matrix.elements; - for (let i = 0; i < 9; i++) { if (te[i] !== me[i]) return false; } - return true; } - fromArray(array, offset = 0) { for (let i = 0; i < 9; i++) { this.elements[i] = array[i + offset]; } - return this; } - toArray(array = [], offset = 0) { const te = this.elements; array[offset] = te[0]; @@ -1074,22 +960,21 @@ array[offset + 8] = te[8]; return array; } - clone() { return new this.constructor().fromArray(this.elements); } - } + const _m3 = /*@__PURE__*/new Matrix3(); function arrayNeedsUint32(array) { // assumes larger values usually on last + for (let i = array.length - 1; i >= 0; --i) { - if (array[i] > 65535) return true; + if (array[i] >= 65535) return true; // account for PRIMITIVE_RESTART_FIXED_INDEX, #24565 } return false; } - const TYPED_ARRAYS = { Int8Array: Int8Array, Uint8Array: Uint8Array, @@ -1101,11 +986,9 @@ Float32Array: Float32Array, Float64Array: Float64Array }; - function getTypedArray(type, buffer) { return new TYPED_ARRAYS[type](buffer); } - function createElementNS(name) { return document.createElementNS('http://www.w3.org/1999/xhtml', name); } @@ -1115,9 +998,10 @@ } function LinearToSRGB(c) { return c < 0.0031308 ? c * 12.92 : 1.055 * Math.pow(c, 0.41666) - 0.055; - } // JavaScript RGB-to-RGB transforms, defined as - // FN[InputColorSpace][OutputColorSpace] callback functions. + } + // JavaScript RGB-to-RGB transforms, defined as + // FN[InputColorSpace][OutputColorSpace] callback functions. const FN = { [SRGBColorSpace]: { [LinearSRGBColorSpace]: SRGBToLinear @@ -1128,20 +1012,16 @@ }; const ColorManagement = { legacyMode: true, - get workingColorSpace() { return LinearSRGBColorSpace; }, - set workingColorSpace(colorSpace) { console.warn('THREE.ColorManagement: .workingColorSpace is readonly.'); }, - convert: function (color, sourceColorSpace, targetColorSpace) { if (this.legacyMode || sourceColorSpace === targetColorSpace || !sourceColorSpace || !targetColorSpace) { return color; } - if (FN[sourceColorSpace] && FN[sourceColorSpace][targetColorSpace] !== undefined) { const fn = FN[sourceColorSpace][targetColorSpace]; color.r = fn(color.r); @@ -1149,7 +1029,6 @@ color.b = fn(color.b); return color; } - throw new Error('Unsupported color space conversion.'); }, fromWorkingColorSpace: function (color, targetColorSpace) { @@ -1310,7 +1189,7 @@ 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 }; - const _rgb = { + const _rgb$1 = { r: 0, g: 0, b: 0 @@ -1325,7 +1204,6 @@ s: 0, l: 0 }; - function hue2rgb(p, q, t) { if (t < 0) t += 1; if (t > 1) t -= 1; @@ -1334,29 +1212,24 @@ if (t < 2 / 3) return p + (q - p) * 6 * (2 / 3 - t); return p; } - function toComponents(source, target) { target.r = source.r; target.g = source.g; target.b = source.b; return target; } - class Color { constructor(r, g, b) { this.isColor = true; this.r = 1; this.g = 1; this.b = 1; - if (g === undefined && b === undefined) { // r is THREE.Color, hex or string return this.set(r); } - return this.setRGB(r, g, b); } - set(value) { if (value && value.isColor) { this.copy(value); @@ -1365,17 +1238,14 @@ } else if (typeof value === 'string') { this.setStyle(value); } - return this; } - setScalar(scalar) { this.r = scalar; this.g = scalar; this.b = scalar; return this; } - setHex(hex, colorSpace = SRGBColorSpace) { hex = Math.floor(hex); this.r = (hex >> 16 & 255) / 255; @@ -1384,21 +1254,18 @@ ColorManagement.toWorkingColorSpace(this, colorSpace); return this; } - - setRGB(r, g, b, colorSpace = LinearSRGBColorSpace) { + setRGB(r, g, b, colorSpace = ColorManagement.workingColorSpace) { this.r = r; this.g = g; this.b = b; ColorManagement.toWorkingColorSpace(this, colorSpace); return this; } - - setHSL(h, s, l, colorSpace = LinearSRGBColorSpace) { + setHSL(h, s, l, colorSpace = ColorManagement.workingColorSpace) { // h,s,l ranges are in 0.0 - 1.0 h = euclideanModulo(h, 1); s = clamp(s, 0, 1); l = clamp(l, 0, 1); - if (s === 0) { this.r = this.g = this.b = l; } else { @@ -1408,28 +1275,23 @@ this.g = hue2rgb(q, p, h); this.b = hue2rgb(q, p, h - 1 / 3); } - ColorManagement.toWorkingColorSpace(this, colorSpace); return this; } - setStyle(style, colorSpace = SRGBColorSpace) { function handleAlpha(string) { if (string === undefined) return; - if (parseFloat(string) < 1) { console.warn('THREE.Color: Alpha component of ' + style + ' will be ignored.'); } } - let m; - if (m = /^((?:rgb|hsl)a?)\(([^\)]*)\)/.exec(style)) { // rgb / hsl + let color; const name = m[1]; const components = m[2]; - switch (name) { case 'rgb': case 'rgba': @@ -1442,7 +1304,6 @@ handleAlpha(color[4]); return this; } - if (color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5) this.r = Math.min(100, parseInt(color[1], 10)) / 100; @@ -1452,27 +1313,24 @@ handleAlpha(color[4]); return this; } - break; - case 'hsl': case 'hsla': - if (color = /^\s*(\d*\.?\d+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { + if (color = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { // hsl(120,50%,50%) hsla(120,50%,50%,0.5) const h = parseFloat(color[1]) / 360; - const s = parseInt(color[2], 10) / 100; - const l = parseInt(color[3], 10) / 100; + const s = parseFloat(color[2]) / 100; + const l = parseFloat(color[3]) / 100; handleAlpha(color[4]); return this.setHSL(h, s, l, colorSpace); } - break; } } else if (m = /^\#([A-Fa-f\d]+)$/.exec(style)) { // hex color + const hex = m[1]; const size = hex.length; - if (size === 3) { // #ff0 this.r = parseInt(hex.charAt(0) + hex.charAt(0), 16) / 255; @@ -1489,18 +1347,14 @@ return this; } } - if (style && style.length > 0) { return this.setColorName(style, colorSpace); } - return this; } - setColorName(style, colorSpace = SRGBColorSpace) { // color keywords const hex = _colorKeywords[style.toLowerCase()]; - if (hex !== undefined) { // red this.setHex(hex, colorSpace); @@ -1508,114 +1362,94 @@ // unknown color console.warn('THREE.Color: Unknown color ' + style); } - return this; } - clone() { return new this.constructor(this.r, this.g, this.b); } - copy(color) { this.r = color.r; this.g = color.g; this.b = color.b; return this; } - copySRGBToLinear(color) { this.r = SRGBToLinear(color.r); this.g = SRGBToLinear(color.g); this.b = SRGBToLinear(color.b); return this; } - copyLinearToSRGB(color) { this.r = LinearToSRGB(color.r); this.g = LinearToSRGB(color.g); this.b = LinearToSRGB(color.b); return this; } - convertSRGBToLinear() { this.copySRGBToLinear(this); return this; } - convertLinearToSRGB() { this.copyLinearToSRGB(this); return this; } - getHex(colorSpace = SRGBColorSpace) { - ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb), colorSpace); - return clamp(_rgb.r * 255, 0, 255) << 16 ^ clamp(_rgb.g * 255, 0, 255) << 8 ^ clamp(_rgb.b * 255, 0, 255) << 0; + ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb$1), colorSpace); + return clamp(_rgb$1.r * 255, 0, 255) << 16 ^ clamp(_rgb$1.g * 255, 0, 255) << 8 ^ clamp(_rgb$1.b * 255, 0, 255) << 0; } - getHexString(colorSpace = SRGBColorSpace) { return ('000000' + this.getHex(colorSpace).toString(16)).slice(-6); } - - getHSL(target, colorSpace = LinearSRGBColorSpace) { + getHSL(target, colorSpace = ColorManagement.workingColorSpace) { // h,s,l ranges are in 0.0 - 1.0 - ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb), colorSpace); - const r = _rgb.r, - g = _rgb.g, - b = _rgb.b; + + ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb$1), colorSpace); + const r = _rgb$1.r, + g = _rgb$1.g, + b = _rgb$1.b; const max = Math.max(r, g, b); const min = Math.min(r, g, b); let hue, saturation; const lightness = (min + max) / 2.0; - if (min === max) { hue = 0; saturation = 0; } else { const delta = max - min; saturation = lightness <= 0.5 ? delta / (max + min) : delta / (2 - max - min); - switch (max) { 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; } - hue /= 6; } - target.h = hue; target.s = saturation; target.l = lightness; return target; } - - getRGB(target, colorSpace = LinearSRGBColorSpace) { - ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb), colorSpace); - target.r = _rgb.r; - target.g = _rgb.g; - target.b = _rgb.b; + getRGB(target, colorSpace = ColorManagement.workingColorSpace) { + ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb$1), colorSpace); + target.r = _rgb$1.r; + target.g = _rgb$1.g; + target.b = _rgb$1.b; return target; } - getStyle(colorSpace = SRGBColorSpace) { - ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb), colorSpace); - + ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb$1), colorSpace); if (colorSpace !== SRGBColorSpace) { // Requires CSS Color Module Level 4 (https://www.w3.org/TR/css-color-4/). - return `color(${colorSpace} ${_rgb.r} ${_rgb.g} ${_rgb.b})`; + return `color(${colorSpace} ${_rgb$1.r} ${_rgb$1.g} ${_rgb$1.b})`; } - - return `rgb(${_rgb.r * 255 | 0},${_rgb.g * 255 | 0},${_rgb.b * 255 | 0})`; + return `rgb(${_rgb$1.r * 255 | 0},${_rgb$1.g * 255 | 0},${_rgb$1.b * 255 | 0})`; } - offsetHSL(h, s, l) { this.getHSL(_hslA); _hslA.h += h; @@ -1624,63 +1458,54 @@ this.setHSL(_hslA.h, _hslA.s, _hslA.l); return this; } - add(color) { this.r += color.r; this.g += color.g; this.b += color.b; return this; } - addColors(color1, color2) { this.r = color1.r + color2.r; this.g = color1.g + color2.g; this.b = color1.b + color2.b; return this; } - addScalar(s) { this.r += s; this.g += s; this.b += s; return this; } - 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; } - multiply(color) { this.r *= color.r; this.g *= color.g; this.b *= color.b; return this; } - multiplyScalar(s) { this.r *= s; this.g *= s; this.b *= s; return this; } - 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; } - lerpColors(color1, color2, alpha) { this.r = color1.r + (color2.r - color1.r) * alpha; this.g = color1.g + (color2.g - color1.g) * alpha; this.b = color1.b + (color2.b - color1.b) * alpha; return this; } - lerpHSL(color, alpha) { this.getHSL(_hslA); color.getHSL(_hslB); @@ -1690,86 +1515,62 @@ this.setHSL(h, s, l); return this; } - equals(c) { return c.r === this.r && c.g === this.g && c.b === this.b; } - fromArray(array, offset = 0) { this.r = array[offset]; this.g = array[offset + 1]; this.b = array[offset + 2]; return this; } - toArray(array = [], offset = 0) { array[offset] = this.r; array[offset + 1] = this.g; array[offset + 2] = this.b; return array; } - fromBufferAttribute(attribute, index) { this.r = attribute.getX(index); this.g = attribute.getY(index); this.b = attribute.getZ(index); - - if (attribute.normalized === true) { - // assuming Uint8Array - this.r /= 255; - this.g /= 255; - this.b /= 255; - } - return this; } - toJSON() { return this.getHex(); } - *[Symbol.iterator]() { yield this.r; yield this.g; yield this.b; } - } - Color.NAMES = _colorKeywords; let _canvas; - class ImageUtils { static getDataURL(image) { if (/^data:/i.test(image.src)) { return image.src; } - if (typeof HTMLCanvasElement == 'undefined') { return image.src; } - let canvas; - if (image instanceof HTMLCanvasElement) { canvas = image; } else { if (_canvas === undefined) _canvas = createElementNS('canvas'); _canvas.width = image.width; _canvas.height = image.height; - const context = _canvas.getContext('2d'); - if (image instanceof ImageData) { context.putImageData(image, 0, 0); } else { context.drawImage(image, 0, 0, image.width, image.height); } - canvas = _canvas; } - if (canvas.width > 2048 || canvas.height > 2048) { console.warn('THREE.ImageUtils.getDataURL: Image converted to jpg for performance reasons', image); return canvas.toDataURL('image/jpeg', 0.6); @@ -1777,7 +1578,6 @@ return canvas.toDataURL('image/png'); } } - static sRGBToLinear(image) { if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) { const canvas = createElementNS('canvas'); @@ -1787,25 +1587,22 @@ context.drawImage(image, 0, 0, image.width, image.height); const imageData = context.getImageData(0, 0, image.width, image.height); const data = imageData.data; - for (let i = 0; i < data.length; i++) { data[i] = SRGBToLinear(data[i] / 255) * 255; } - context.putImageData(imageData, 0, 0); return canvas; } else if (image.data) { const data = image.data.slice(0); - for (let i = 0; i < data.length; i++) { if (data instanceof Uint8Array || data instanceof Uint8ClampedArray) { data[i] = Math.floor(SRGBToLinear(data[i] / 255) * 255); } else { // assuming float + data[i] = SRGBToLinear(data[i]); } } - return { data: data, width: image.width, @@ -1816,7 +1613,6 @@ return image; } } - } class Source { @@ -1826,31 +1622,25 @@ this.data = data; this.version = 0; } - set needsUpdate(value) { if (value === true) this.version++; } - toJSON(meta) { const isRootObject = meta === undefined || typeof meta === 'string'; - if (!isRootObject && meta.images[this.uuid] !== undefined) { return meta.images[this.uuid]; } - const output = { uuid: this.uuid, url: '' }; const data = this.data; - if (data !== null) { let url; - if (Array.isArray(data)) { // cube texture - url = []; + url = []; for (let i = 0, l = data.length; i < l; i++) { if (data[i].isDataTexture) { url.push(serializeImage(data[i].image)); @@ -1860,28 +1650,26 @@ } } else { // texture + url = serializeImage(data); } - output.url = url; } - if (!isRootObject) { meta.images[this.uuid] = output; } - return output; } - } - function serializeImage(image) { if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) { // default images + return ImageUtils.getDataURL(image); } else { if (image.data) { // images of DataTexture + return { data: Array.from(image.data), width: image.width, @@ -1896,9 +1684,8 @@ } let textureId = 0; - class Texture extends EventDispatcher { - constructor(image = Texture.DEFAULT_IMAGE, mapping = Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format = RGBAFormat, type = UnsignedByteType, anisotropy = 1, encoding = LinearEncoding) { + constructor(image = Texture.DEFAULT_IMAGE, mapping = Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format = RGBAFormat, type = UnsignedByteType, anisotropy = Texture.DEFAULT_ANISOTROPY, encoding = LinearEncoding) { super(); this.isTexture = true; Object.defineProperty(this, 'id', { @@ -1927,36 +1714,31 @@ 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; this.userData = {}; this.version = 0; this.onUpdate = null; this.isRenderTargetTexture = false; // indicates whether a texture belongs to a render target or not - this.needsPMREMUpdate = false; // indicates whether this texture should be processed by PMREMGenerator or not (only relevant for render target textures) } get image() { return this.source.data; } - set image(value) { this.source.data = value; } - 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() { return new this.constructor().copy(this); } - copy(source) { this.name = source.name; this.source = source.source; @@ -1985,14 +1767,11 @@ this.needsUpdate = true; return this; } - toJSON(meta) { const isRootObject = meta === undefined || typeof meta === 'string'; - if (!isRootObject && meta.textures[this.uuid] !== undefined) { return meta.textures[this.uuid]; } - const output = { metadata: { version: 4.5, @@ -2019,84 +1798,68 @@ unpackAlignment: this.unpackAlignment }; if (JSON.stringify(this.userData) !== '{}') output.userData = this.userData; - if (!isRootObject) { meta.textures[this.uuid] = output; } - return output; } - dispose() { this.dispatchEvent({ type: 'dispose' }); } - 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; - 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); } - break; } } - if (uv.y < 0 || uv.y > 1) { switch (this.wrapT) { case RepeatWrapping: uv.y = uv.y - Math.floor(uv.y); break; - case ClampToEdgeWrapping: uv.y = uv.y < 0 ? 0 : 1; break; - 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); } - break; } } - if (this.flipY) { uv.y = 1 - uv.y; } - return uv; } - set needsUpdate(value) { if (value === true) { this.version++; this.source.needsUpdate = true; } } - } - Texture.DEFAULT_IMAGE = null; Texture.DEFAULT_MAPPING = UVMapping; + Texture.DEFAULT_ANISOTROPY = 1; class Vector4 { constructor(x = 0, y = 0, z = 0, w = 1) { @@ -2106,23 +1869,18 @@ this.z = z; this.w = w; } - get width() { return this.z; } - set width(value) { this.z = value; } - get height() { return this.w; } - set height(value) { this.w = value; } - set(x, y, z, w) { this.x = x; this.y = y; @@ -2130,7 +1888,6 @@ this.w = w; return this; } - setScalar(scalar) { this.x = scalar; this.y = scalar; @@ -2138,75 +1895,58 @@ this.w = scalar; return this; } - setX(x) { this.x = x; return this; } - setY(y) { this.y = y; return this; } - setZ(z) { this.z = z; return this; } - setW(w) { this.w = w; return this; } - setComponent(index, value) { switch (index) { case 0: this.x = value; break; - case 1: this.y = value; break; - case 2: this.z = value; break; - case 3: this.w = value; break; - default: throw new Error('index is out of range: ' + index); } - return this; } - getComponent(index) { switch (index) { case 0: return this.x; - case 1: return this.y; - case 2: return this.z; - case 3: return this.w; - default: throw new Error('index is out of range: ' + index); } } - clone() { return new this.constructor(this.x, this.y, this.z, this.w); } - copy(v) { this.x = v.x; this.y = v.y; @@ -2214,7 +1954,6 @@ this.w = v.w !== undefined ? v.w : 1; return this; } - add(v) { this.x += v.x; this.y += v.y; @@ -2222,7 +1961,6 @@ this.w += v.w; return this; } - addScalar(s) { this.x += s; this.y += s; @@ -2230,7 +1968,6 @@ this.w += s; return this; } - addVectors(a, b) { this.x = a.x + b.x; this.y = a.y + b.y; @@ -2238,7 +1975,6 @@ this.w = a.w + b.w; return this; } - addScaledVector(v, s) { this.x += v.x * s; this.y += v.y * s; @@ -2246,7 +1982,6 @@ this.w += v.w * s; return this; } - sub(v) { this.x -= v.x; this.y -= v.y; @@ -2254,7 +1989,6 @@ this.w -= v.w; return this; } - subScalar(s) { this.x -= s; this.y -= s; @@ -2262,7 +1996,6 @@ this.w -= s; return this; } - subVectors(a, b) { this.x = a.x - b.x; this.y = a.y - b.y; @@ -2270,7 +2003,6 @@ this.w = a.w - b.w; return this; } - multiply(v) { this.x *= v.x; this.y *= v.y; @@ -2278,7 +2010,6 @@ this.w *= v.w; return this; } - multiplyScalar(scalar) { this.x *= scalar; this.y *= scalar; @@ -2286,12 +2017,11 @@ this.w *= scalar; return this; } - applyMatrix4(m) { const x = this.x, - y = this.y, - z = this.z, - w = this.w; + y = this.y, + z = this.z, + w = this.w; const 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; @@ -2299,17 +2029,16 @@ this.w = e[3] * x + e[7] * y + e[11] * z + e[15] * w; return this; } - divideScalar(scalar) { return this.multiplyScalar(1 / scalar); } - 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); const s = Math.sqrt(1 - q.w * q.w); - if (s < 0.0001) { this.x = 1; this.y = 0; @@ -2319,40 +2048,42 @@ this.y = q.y / s; this.z = q.z / s; } - return this; } - 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) - let angle, x, y, z; // variables for result + let angle, x, y, z; // variables for result const 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]; - + // 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 + } + // otherwise this singularity is angle = 180 angle = Math.PI; const xx = (m11 + 1) / 2; @@ -2361,9 +2092,9 @@ const xy = (m12 + m21) / 4; const xz = (m13 + m31) / 4; const yz = (m23 + m32) / 4; - if (xx > yy && xx > zz) { // m11 is the largest diagonal term + if (xx < epsilon) { x = 0; y = 0.707106781; @@ -2375,6 +2106,7 @@ } } else if (yy > zz) { // m22 is the largest diagonal term + if (yy < epsilon) { x = 0.707106781; y = 0; @@ -2386,6 +2118,7 @@ } } else { // m33 is the largest diagonal term so base result on this + if (zz < epsilon) { x = 0.707106781; y = 0.707106781; @@ -2396,15 +2129,17 @@ 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 + } + // as we have reached here there are no singularities so we can handle normally let s = Math.sqrt((m32 - m23) * (m32 - m23) + (m13 - m31) * (m13 - m31) + (m21 - m12) * (m21 - m12)); // used to normalize - if (Math.abs(s) < 0.001) s = 1; // prevent divide by zero, should not happen if matrix is orthogonal and should be + 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; @@ -2413,7 +2148,6 @@ this.w = Math.acos((m11 + m22 + m33 - 1) / 2); return this; } - min(v) { this.x = Math.min(this.x, v.x); this.y = Math.min(this.y, v.y); @@ -2421,7 +2155,6 @@ this.w = Math.min(this.w, v.w); return this; } - max(v) { this.x = Math.max(this.x, v.x); this.y = Math.max(this.y, v.y); @@ -2429,16 +2162,15 @@ this.w = Math.max(this.w, v.w); return this; } - clamp(min, max) { // assumes min < max, componentwise + this.x = Math.max(min.x, Math.min(max.x, this.x)); this.y = Math.max(min.y, Math.min(max.y, this.y)); this.z = Math.max(min.z, Math.min(max.z, this.z)); this.w = Math.max(min.w, Math.min(max.w, this.w)); return this; } - clampScalar(minVal, maxVal) { this.x = Math.max(minVal, Math.min(maxVal, this.x)); this.y = Math.max(minVal, Math.min(maxVal, this.y)); @@ -2446,12 +2178,10 @@ this.w = Math.max(minVal, Math.min(maxVal, this.w)); return this; } - clampLength(min, max) { const length = this.length(); return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length))); } - floor() { this.x = Math.floor(this.x); this.y = Math.floor(this.y); @@ -2459,7 +2189,6 @@ this.w = Math.floor(this.w); return this; } - ceil() { this.x = Math.ceil(this.x); this.y = Math.ceil(this.y); @@ -2467,7 +2196,6 @@ this.w = Math.ceil(this.w); return this; } - round() { this.x = Math.round(this.x); this.y = Math.round(this.y); @@ -2475,7 +2203,6 @@ this.w = Math.round(this.w); return this; } - roundToZero() { this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x); this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y); @@ -2483,7 +2210,6 @@ this.w = this.w < 0 ? Math.ceil(this.w) : Math.floor(this.w); return this; } - negate() { this.x = -this.x; this.y = -this.y; @@ -2491,31 +2217,24 @@ this.w = -this.w; return this; } - dot(v) { return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; } - lengthSq() { return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; } - length() { return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w); } - manhattanLength() { return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z) + Math.abs(this.w); } - normalize() { return this.divideScalar(this.length() || 1); } - setLength(length) { return this.normalize().multiplyScalar(length); } - lerp(v, alpha) { this.x += (v.x - this.x) * alpha; this.y += (v.y - this.y) * alpha; @@ -2523,7 +2242,6 @@ this.w += (v.w - this.w) * alpha; return this; } - lerpVectors(v1, v2, alpha) { this.x = v1.x + (v2.x - v1.x) * alpha; this.y = v1.y + (v2.y - v1.y) * alpha; @@ -2531,11 +2249,9 @@ this.w = v1.w + (v2.w - v1.w) * alpha; return this; } - equals(v) { return v.x === this.x && v.y === this.y && v.z === this.z && v.w === this.w; } - fromArray(array, offset = 0) { this.x = array[offset]; this.y = array[offset + 1]; @@ -2543,7 +2259,6 @@ this.w = array[offset + 3]; return this; } - toArray(array = [], offset = 0) { array[offset] = this.x; array[offset + 1] = this.y; @@ -2551,7 +2266,6 @@ array[offset + 3] = this.w; return array; } - fromBufferAttribute(attribute, index) { this.x = attribute.getX(index); this.y = attribute.getY(index); @@ -2559,7 +2273,6 @@ this.w = attribute.getW(index); return this; } - random() { this.x = Math.random(); this.y = Math.random(); @@ -2567,14 +2280,12 @@ this.w = Math.random(); return this; } - *[Symbol.iterator]() { yield this.x; yield this.y; yield this.z; yield this.w; } - } /* @@ -2582,9 +2293,8 @@ * Texture parameters for an auto-generated target texture * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers */ - class WebGLRenderTarget extends EventDispatcher { - constructor(width, height, options = {}) { + constructor(width = 1, height = 1, options = {}) { super(); this.isWebGLRenderTarget = true; this.width = width; @@ -2609,7 +2319,6 @@ this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null; this.samples = options.samples !== undefined ? options.samples : 0; } - setSize(width, height, depth = 1) { if (this.width !== width || this.height !== height || this.depth !== depth) { this.width = width; @@ -2620,22 +2329,21 @@ this.texture.image.depth = depth; this.dispose(); } - this.viewport.set(0, 0, width, height); this.scissor.set(0, 0, width, height); } - clone() { return new this.constructor().copy(this); } - copy(source) { this.width = source.width; this.height = source.height; this.depth = source.depth; this.viewport.copy(source.viewport); this.texture = source.texture.clone(); - this.texture.isRenderTargetTexture = true; // ensure image object is not shared, see #20328 + this.texture.isRenderTargetTexture = true; + + // ensure image object is not shared, see #20328 const image = Object.assign({}, source.texture.image); this.texture.source = new Source(image); @@ -2645,13 +2353,11 @@ this.samples = source.samples; return this; } - dispose() { this.dispatchEvent({ type: 'dispose' }); } - } class DataArrayTexture extends Texture { @@ -2671,18 +2377,16 @@ this.flipY = false; this.unpackAlignment = 1; } - } class WebGLArrayRenderTarget extends WebGLRenderTarget { - constructor(width, height, depth) { + constructor(width = 1, height = 1, depth = 1) { super(width, height); this.isWebGLArrayRenderTarget = true; this.depth = depth; this.texture = new DataArrayTexture(null, width, height, depth); this.texture.isRenderTargetTexture = true; } - } class Data3DTexture extends Texture { @@ -2694,6 +2398,7 @@ // texture.anisotropy = 16; // // See #14839 + super(null); this.isData3DTexture = true; this.image = { @@ -2709,53 +2414,45 @@ this.flipY = false; this.unpackAlignment = 1; } - } class WebGL3DRenderTarget extends WebGLRenderTarget { - constructor(width, height, depth) { + constructor(width = 1, height = 1, depth = 1) { super(width, height); this.isWebGL3DRenderTarget = true; this.depth = depth; this.texture = new Data3DTexture(null, width, height, depth); this.texture.isRenderTargetTexture = true; } - } class WebGLMultipleRenderTargets extends WebGLRenderTarget { - constructor(width, height, count, options = {}) { + constructor(width = 1, height = 1, count = 1, options = {}) { super(width, height, options); this.isWebGLMultipleRenderTargets = true; const texture = this.texture; this.texture = []; - for (let i = 0; i < count; i++) { this.texture[i] = texture.clone(); this.texture[i].isRenderTargetTexture = true; } } - setSize(width, height, depth = 1) { if (this.width !== width || this.height !== height || this.depth !== depth) { this.width = width; this.height = height; this.depth = depth; - for (let i = 0, il = this.texture.length; i < il; i++) { this.texture[i].image.width = width; this.texture[i].image.height = height; this.texture[i].image.depth = depth; } - this.dispose(); } - this.viewport.set(0, 0, width, height); this.scissor.set(0, 0, width, height); return this; } - copy(source) { this.dispose(); this.width = source.width; @@ -2767,15 +2464,12 @@ this.stencilBuffer = source.stencilBuffer; if (source.depthTexture !== null) this.depthTexture = source.depthTexture.clone(); this.texture.length = 0; - for (let i = 0, il = source.texture.length; i < il; i++) { this.texture[i] = source.texture[i].clone(); this.texture[i].isRenderTargetTexture = true; } - return this; } - } class Quaternion { @@ -2786,18 +2480,17 @@ this._z = z; this._w = w; } - static slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t) { // fuzz-free, array-based Quaternion SLERP operation + let x0 = src0[srcOffset0 + 0], - y0 = src0[srcOffset0 + 1], - z0 = src0[srcOffset0 + 2], - w0 = src0[srcOffset0 + 3]; + y0 = src0[srcOffset0 + 1], + z0 = src0[srcOffset0 + 2], + w0 = src0[srcOffset0 + 3]; const x1 = src1[srcOffset1 + 0], - y1 = src1[srcOffset1 + 1], - z1 = src1[srcOffset1 + 2], - w1 = src1[srcOffset1 + 3]; - + y1 = src1[srcOffset1 + 1], + z1 = src1[srcOffset1 + 2], + w1 = src1[srcOffset1 + 3]; if (t === 0) { dst[dstOffset + 0] = x0; dst[dstOffset + 1] = y0; @@ -2805,7 +2498,6 @@ dst[dstOffset + 3] = w0; return; } - if (t === 1) { dst[dstOffset + 0] = x1; dst[dstOffset + 1] = y1; @@ -2813,26 +2505,26 @@ dst[dstOffset + 3] = w1; return; } - if (w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1) { let s = 1 - t; const cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, - dir = cos >= 0 ? 1 : -1, - sqrSin = 1 - cos * cos; // Skip the Slerp for tiny steps to avoid numeric problems: + dir = cos >= 0 ? 1 : -1, + sqrSin = 1 - cos * cos; + // Skip the Slerp for tiny steps to avoid numeric problems: if (sqrSin > Number.EPSILON) { const sin = Math.sqrt(sqrSin), - len = Math.atan2(sin, cos * dir); + len = Math.atan2(sin, cos * dir); s = Math.sin(s * len) / sin; t = Math.sin(t * len) / sin; } - const tDir = t * dir; x0 = x0 * s + x1 * tDir; y0 = y0 * s + y1 * tDir; z0 = z0 * s + z1 * tDir; - w0 = w0 * s + w1 * tDir; // Normalize in case we just did a lerp: + w0 = w0 * s + w1 * tDir; + // Normalize in case we just did a lerp: if (s === 1 - t) { const f = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0); x0 *= f; @@ -2841,13 +2533,11 @@ w0 *= f; } } - dst[dstOffset] = x0; dst[dstOffset + 1] = y0; dst[dstOffset + 2] = z0; dst[dstOffset + 3] = w0; } - static multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) { const x0 = src0[srcOffset0]; const y0 = src0[srcOffset0 + 1]; @@ -2863,82 +2553,60 @@ dst[dstOffset + 3] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1; return dst; } - get x() { return this._x; } - set x(value) { this._x = value; - this._onChangeCallback(); } - get y() { return this._y; } - set y(value) { this._y = value; - this._onChangeCallback(); } - get z() { return this._z; } - set z(value) { this._z = value; - this._onChangeCallback(); } - get w() { return this._w; } - set w(value) { this._w = value; - this._onChangeCallback(); } - set(x, y, z, w) { this._x = x; this._y = y; this._z = z; this._w = w; - this._onChangeCallback(); - return this; } - clone() { return new this.constructor(this._x, this._y, this._z, this._w); } - copy(quaternion) { this._x = quaternion.x; this._y = quaternion.y; this._z = quaternion.z; this._w = quaternion.w; - this._onChangeCallback(); - return this; } - setFromEuler(euler, update) { - if (!(euler && euler.isEuler)) { - throw new Error('THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.'); - } - const x = euler._x, - y = euler._y, - z = euler._z, - order = euler._order; // http://www.mathworks.com/matlabcentral/fileexchange/ + 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 @@ -2950,7 +2618,6 @@ const s1 = sin(x / 2); const s2 = sin(y / 2); const s3 = sin(z / 2); - switch (order) { case 'XYZ': this._x = s1 * c2 * c3 + c1 * s2 * s3; @@ -2958,80 +2625,72 @@ this._z = c1 * c2 * s3 + s1 * s2 * c3; this._w = c1 * c2 * c3 - s1 * s2 * s3; break; - case 'YXZ': this._x = s1 * c2 * c3 + c1 * s2 * s3; this._y = c1 * s2 * c3 - s1 * c2 * s3; this._z = c1 * c2 * s3 - s1 * s2 * c3; this._w = c1 * c2 * c3 + s1 * s2 * s3; break; - case 'ZXY': this._x = s1 * c2 * c3 - c1 * s2 * s3; this._y = c1 * s2 * c3 + s1 * c2 * s3; this._z = c1 * c2 * s3 + s1 * s2 * c3; this._w = c1 * c2 * c3 - s1 * s2 * s3; break; - case 'ZYX': this._x = s1 * c2 * c3 - c1 * s2 * s3; this._y = c1 * s2 * c3 + s1 * c2 * s3; this._z = c1 * c2 * s3 - s1 * s2 * c3; this._w = c1 * c2 * c3 + s1 * s2 * s3; break; - case 'YZX': this._x = s1 * c2 * c3 + c1 * s2 * s3; this._y = c1 * s2 * c3 + s1 * c2 * s3; this._z = c1 * c2 * s3 - s1 * s2 * c3; this._w = c1 * c2 * c3 - s1 * s2 * s3; break; - case 'XZY': this._x = s1 * c2 * c3 - c1 * s2 * s3; this._y = c1 * s2 * c3 - s1 * c2 * s3; this._z = c1 * c2 * s3 + s1 * s2 * c3; this._w = c1 * c2 * c3 + s1 * s2 * s3; break; - default: console.warn('THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order); } - if (update !== false) this._onChangeCallback(); return this; } - setFromAxisAngle(axis, angle) { // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm + // assumes axis is normalized + const halfAngle = angle / 2, - s = Math.sin(halfAngle); + s = Math.sin(halfAngle); this._x = axis.x * s; this._y = axis.y * s; this._z = axis.z * s; this._w = Math.cos(halfAngle); - this._onChangeCallback(); - return this; } - setFromRotationMatrix(m) { // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - const te = m.elements, - m11 = te[0], - m12 = te[4], - m13 = te[8], - m21 = te[1], - m22 = te[5], - m23 = te[9], - m31 = te[2], - m32 = te[6], - m33 = te[10], - trace = m11 + m22 + m33; + const te = m.elements, + m11 = te[0], + m12 = te[4], + m13 = te[8], + m21 = te[1], + m22 = te[5], + m23 = te[9], + m31 = te[2], + m32 = te[6], + m33 = te[10], + trace = m11 + m22 + m33; if (trace > 0) { const s = 0.5 / Math.sqrt(trace + 1.0); this._w = 0.25 / s; @@ -3057,20 +2716,17 @@ this._y = (m23 + m32) / s; this._z = 0.25 * s; } - this._onChangeCallback(); - return this; } - setFromUnitVectors(vFrom, vTo) { // assumes direction vectors vFrom and vTo are normalized - let r = vFrom.dot(vTo) + 1; + let r = vFrom.dot(vTo) + 1; if (r < Number.EPSILON) { // vFrom and vTo point in opposite directions - r = 0; + r = 0; if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) { this._x = -vFrom.y; this._y = vFrom.x; @@ -3084,19 +2740,17 @@ } } else { // crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3 + this._x = vFrom.y * vTo.z - vFrom.z * vTo.y; this._y = vFrom.z * vTo.x - vFrom.x * vTo.z; this._z = vFrom.x * vTo.y - vFrom.y * vTo.x; this._w = r; } - return this.normalize(); } - angleTo(q) { return 2 * Math.acos(Math.abs(clamp(this.dot(q), -1, 1))); } - rotateTowards(q, step) { const angle = this.angleTo(q); if (angle === 0) return this; @@ -3104,41 +2758,32 @@ this.slerp(q, t); return this; } - identity() { return this.set(0, 0, 0, 1); } - invert() { // quaternion is assumed to have unit length + return this.conjugate(); } - conjugate() { this._x *= -1; this._y *= -1; this._z *= -1; - this._onChangeCallback(); - return this; } - dot(v) { return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w; } - lengthSq() { return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w; } - length() { return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w); } - normalize() { let l = this.length(); - if (l === 0) { this._x = 0; this._y = 0; @@ -3151,50 +2796,44 @@ this._z = this._z * l; this._w = this._w * l; } - this._onChangeCallback(); - return this; } - multiply(q) { return this.multiplyQuaternions(this, q); } - premultiply(q) { return this.multiplyQuaternions(q, this); } - multiplyQuaternions(a, b) { // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm + const qax = a._x, - qay = a._y, - qaz = a._z, - qaw = a._w; + qay = a._y, + qaz = a._z, + qaw = a._w; const qbx = b._x, - qby = b._y, - qbz = b._z, - qbw = b._w; + qby = b._y, + qbz = b._z, + qbw = b._w; this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; - this._onChangeCallback(); - return this; } - slerp(qb, t) { if (t === 0) return this; if (t === 1) return this.copy(qb); const x = this._x, - y = this._y, - z = this._z, - w = this._w; // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ + y = this._y, + z = this._z, + w = this._w; - let cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; + // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ + let cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; if (cosHalfTheta < 0) { this._w = -qb._w; this._x = -qb._x; @@ -3204,7 +2843,6 @@ } else { this.copy(qb); } - if (cosHalfTheta >= 1.0) { this._w = w; this._x = x; @@ -3212,9 +2850,7 @@ this._z = z; return this; } - const sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta; - if (sqrSinHalfTheta <= Number.EPSILON) { const s = 1 - t; this._w = s * w + t * this._w; @@ -3222,34 +2858,28 @@ this._y = s * y + t * this._y; this._z = s * z + t * this._z; this.normalize(); - this._onChangeCallback(); - return this; } - const sinHalfTheta = Math.sqrt(sqrSinHalfTheta); const halfTheta = Math.atan2(sinHalfTheta, cosHalfTheta); const ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta, - ratioB = Math.sin(t * halfTheta) / sinHalfTheta; + ratioB = Math.sin(t * halfTheta) / sinHalfTheta; this._w = w * ratioA + this._w * ratioB; this._x = x * ratioA + this._x * ratioB; this._y = y * ratioA + this._y * ratioB; this._z = z * ratioA + this._z * ratioB; - this._onChangeCallback(); - return this; } - slerpQuaternions(qa, qb, t) { return this.copy(qa).slerp(qb, t); } - random() { // Derived from http://planning.cs.uiuc.edu/node198.html // Note, this source uses w, x, y, z ordering, // so we swap the order below. + const u1 = Math.random(); const sqrt1u1 = Math.sqrt(1 - u1); const sqrtu1 = Math.sqrt(u1); @@ -3257,22 +2887,17 @@ const u3 = 2 * Math.PI * Math.random(); return this.set(sqrt1u1 * Math.cos(u2), sqrtu1 * Math.sin(u3), sqrtu1 * Math.cos(u3), sqrt1u1 * Math.sin(u2)); } - equals(quaternion) { return quaternion._x === this._x && quaternion._y === this._y && quaternion._z === this._z && quaternion._w === this._w; } - fromArray(array, offset = 0) { this._x = array[offset]; this._y = array[offset + 1]; this._z = array[offset + 2]; this._w = array[offset + 3]; - this._onChangeCallback(); - return this; } - toArray(array = [], offset = 0) { array[offset] = this._x; array[offset + 1] = this._y; @@ -3280,7 +2905,6 @@ array[offset + 3] = this._w; return array; } - fromBufferAttribute(attribute, index) { this._x = attribute.getX(index); this._y = attribute.getY(index); @@ -3288,21 +2912,17 @@ this._w = attribute.getW(index); return this; } - _onChange(callback) { this._onChangeCallback = callback; return this; } - _onChangeCallback() {} - *[Symbol.iterator]() { yield this._x; yield this._y; yield this._z; yield this._w; } - } class Vector3 { @@ -3312,7 +2932,6 @@ this.y = y; this.z = z; } - set(x, y, z) { if (z === undefined) z = this.z; // sprite.scale.set(x,y) @@ -3321,174 +2940,144 @@ this.z = z; return this; } - setScalar(scalar) { this.x = scalar; this.y = scalar; this.z = scalar; return this; } - setX(x) { this.x = x; return this; } - setY(y) { this.y = y; return this; } - setZ(z) { this.z = z; return this; } - setComponent(index, value) { switch (index) { case 0: this.x = value; break; - case 1: this.y = value; break; - case 2: this.z = value; break; - default: throw new Error('index is out of range: ' + index); } - return this; } - getComponent(index) { switch (index) { case 0: return this.x; - case 1: return this.y; - case 2: return this.z; - default: throw new Error('index is out of range: ' + index); } } - clone() { return new this.constructor(this.x, this.y, this.z); } - copy(v) { this.x = v.x; this.y = v.y; this.z = v.z; return this; } - add(v) { this.x += v.x; this.y += v.y; this.z += v.z; return this; } - addScalar(s) { this.x += s; this.y += s; this.z += s; return this; } - addVectors(a, b) { this.x = a.x + b.x; this.y = a.y + b.y; this.z = a.z + b.z; return this; } - addScaledVector(v, s) { this.x += v.x * s; this.y += v.y * s; this.z += v.z * s; return this; } - sub(v) { this.x -= v.x; this.y -= v.y; this.z -= v.z; return this; } - subScalar(s) { this.x -= s; this.y -= s; this.z -= s; return this; } - subVectors(a, b) { this.x = a.x - b.x; this.y = a.y - b.y; this.z = a.z - b.z; return this; } - multiply(v) { this.x *= v.x; this.y *= v.y; this.z *= v.z; return this; } - multiplyScalar(scalar) { this.x *= scalar; this.y *= scalar; this.z *= scalar; return this; } - multiplyVectors(a, b) { this.x = a.x * b.x; this.y = a.y * b.y; this.z = a.z * b.z; return this; } - applyEuler(euler) { return this.applyQuaternion(_quaternion$4.setFromEuler(euler)); } - applyAxisAngle(axis, angle) { return this.applyQuaternion(_quaternion$4.setFromAxisAngle(axis, angle)); } - applyMatrix3(m) { const x = this.x, - y = this.y, - z = this.z; + y = this.y, + z = this.z; const e = m.elements; this.x = e[0] * x + e[3] * y + e[6] * z; this.y = e[1] * x + e[4] * y + e[7] * z; this.z = e[2] * x + e[5] * y + e[8] * z; return this; } - applyNormalMatrix(m) { return this.applyMatrix3(m).normalize(); } - applyMatrix4(m) { const x = this.x, - y = this.y, - z = this.z; + y = this.y, + z = this.z; const e = m.elements; const w = 1 / (e[3] * x + e[7] * y + e[11] * z + e[15]); this.x = (e[0] * x + e[4] * y + e[8] * z + e[12]) * w; @@ -3496,230 +3085,205 @@ this.z = (e[2] * x + e[6] * y + e[10] * z + e[14]) * w; return this; } - applyQuaternion(q) { const x = this.x, - y = this.y, - z = this.z; + y = this.y, + z = this.z; const qx = q.x, - qy = q.y, - qz = q.z, - qw = q.w; // calculate quat * vector + qy = q.y, + qz = q.z, + qw = q.w; + + // calculate quat * vector const ix = qw * x + qy * z - qz * y; const iy = qw * y + qz * x - qx * z; const iz = qw * z + qx * y - qy * x; - const iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat + const iw = -qx * x - qy * y - qz * z; + + // calculate result * inverse quat this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; return this; } - project(camera) { return this.applyMatrix4(camera.matrixWorldInverse).applyMatrix4(camera.projectionMatrix); } - unproject(camera) { return this.applyMatrix4(camera.projectionMatrixInverse).applyMatrix4(camera.matrixWorld); } - transformDirection(m) { // input: THREE.Matrix4 affine matrix // vector interpreted as a direction + const x = this.x, - y = this.y, - z = this.z; + y = this.y, + z = this.z; const e = m.elements; this.x = e[0] * x + e[4] * y + e[8] * z; this.y = e[1] * x + e[5] * y + e[9] * z; this.z = e[2] * x + e[6] * y + e[10] * z; return this.normalize(); } - divide(v) { this.x /= v.x; this.y /= v.y; this.z /= v.z; return this; } - divideScalar(scalar) { return this.multiplyScalar(1 / scalar); } - min(v) { this.x = Math.min(this.x, v.x); this.y = Math.min(this.y, v.y); this.z = Math.min(this.z, v.z); return this; } - max(v) { this.x = Math.max(this.x, v.x); this.y = Math.max(this.y, v.y); this.z = Math.max(this.z, v.z); return this; } - clamp(min, max) { // assumes min < max, componentwise + this.x = Math.max(min.x, Math.min(max.x, this.x)); this.y = Math.max(min.y, Math.min(max.y, this.y)); this.z = Math.max(min.z, Math.min(max.z, this.z)); return this; } - clampScalar(minVal, maxVal) { this.x = Math.max(minVal, Math.min(maxVal, this.x)); this.y = Math.max(minVal, Math.min(maxVal, this.y)); this.z = Math.max(minVal, Math.min(maxVal, this.z)); return this; } - clampLength(min, max) { const length = this.length(); return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length))); } - floor() { this.x = Math.floor(this.x); this.y = Math.floor(this.y); this.z = Math.floor(this.z); return this; } - ceil() { this.x = Math.ceil(this.x); this.y = Math.ceil(this.y); this.z = Math.ceil(this.z); return this; } - round() { this.x = Math.round(this.x); this.y = Math.round(this.y); this.z = Math.round(this.z); return this; } - roundToZero() { this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x); this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y); this.z = this.z < 0 ? Math.ceil(this.z) : Math.floor(this.z); return this; } - negate() { this.x = -this.x; this.y = -this.y; this.z = -this.z; return this; } - dot(v) { return this.x * v.x + this.y * v.y + this.z * v.z; - } // TODO lengthSquared? + } + // TODO lengthSquared? lengthSq() { return this.x * this.x + this.y * this.y + this.z * this.z; } - length() { return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); } - manhattanLength() { return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z); } - normalize() { return this.divideScalar(this.length() || 1); } - setLength(length) { return this.normalize().multiplyScalar(length); } - lerp(v, alpha) { this.x += (v.x - this.x) * alpha; this.y += (v.y - this.y) * alpha; this.z += (v.z - this.z) * alpha; return this; } - lerpVectors(v1, v2, alpha) { this.x = v1.x + (v2.x - v1.x) * alpha; this.y = v1.y + (v2.y - v1.y) * alpha; this.z = v1.z + (v2.z - v1.z) * alpha; return this; } - cross(v) { return this.crossVectors(this, v); } - crossVectors(a, b) { const ax = a.x, - ay = a.y, - az = a.z; + ay = a.y, + az = a.z; const bx = b.x, - by = b.y, - bz = b.z; + by = b.y, + bz = b.z; this.x = ay * bz - az * by; this.y = az * bx - ax * bz; this.z = ax * by - ay * bx; return this; } - projectOnVector(v) { const denominator = v.lengthSq(); if (denominator === 0) return this.set(0, 0, 0); const scalar = v.dot(this) / denominator; return this.copy(v).multiplyScalar(scalar); } - projectOnPlane(planeNormal) { _vector$c.copy(this).projectOnVector(planeNormal); - return this.sub(_vector$c); } - reflect(normal) { // reflect incident vector off plane orthogonal to normal // normal is assumed to have unit length + return this.sub(_vector$c.copy(normal).multiplyScalar(2 * this.dot(normal))); } - angleTo(v) { const denominator = Math.sqrt(this.lengthSq() * v.lengthSq()); if (denominator === 0) return Math.PI / 2; - const theta = this.dot(v) / denominator; // clamp, to handle numerical problems + const theta = this.dot(v) / denominator; + + // clamp, to handle numerical problems return Math.acos(clamp(theta, -1, 1)); } - distanceTo(v) { return Math.sqrt(this.distanceToSquared(v)); } - distanceToSquared(v) { const dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; + dy = this.y - v.y, + dz = this.z - v.z; return dx * dx + dy * dy + dz * dz; } - manhattanDistanceTo(v) { return Math.abs(this.x - v.x) + Math.abs(this.y - v.y) + Math.abs(this.z - v.z); } - setFromSpherical(s) { return this.setFromSphericalCoords(s.radius, s.phi, s.theta); } - setFromSphericalCoords(radius, phi, theta) { const sinPhiRadius = Math.sin(phi) * radius; this.x = sinPhiRadius * Math.sin(theta); @@ -3727,18 +3291,15 @@ this.z = sinPhiRadius * Math.cos(theta); return this; } - setFromCylindrical(c) { return this.setFromCylindricalCoords(c.radius, c.theta, c.y); } - setFromCylindricalCoords(radius, theta, y) { this.x = radius * Math.sin(theta); this.y = y; this.z = radius * Math.cos(theta); return this; } - setFromMatrixPosition(m) { const e = m.elements; this.x = e[12]; @@ -3746,7 +3307,6 @@ this.z = e[14]; return this; } - setFromMatrixScale(m) { const sx = this.setFromMatrixColumn(m, 0).length(); const sy = this.setFromMatrixColumn(m, 1).length(); @@ -3756,56 +3316,48 @@ this.z = sz; return this; } - setFromMatrixColumn(m, index) { return this.fromArray(m.elements, index * 4); } - setFromMatrix3Column(m, index) { return this.fromArray(m.elements, index * 3); } - setFromEuler(e) { this.x = e._x; this.y = e._y; this.z = e._z; return this; } - equals(v) { return v.x === this.x && v.y === this.y && v.z === this.z; } - fromArray(array, offset = 0) { this.x = array[offset]; this.y = array[offset + 1]; this.z = array[offset + 2]; return this; } - toArray(array = [], offset = 0) { array[offset] = this.x; array[offset + 1] = this.y; array[offset + 2] = this.z; return array; } - fromBufferAttribute(attribute, index) { this.x = attribute.getX(index); this.y = attribute.getY(index); this.z = attribute.getZ(index); return this; } - random() { this.x = Math.random(); this.y = Math.random(); this.z = Math.random(); return this; } - randomDirection() { // Derived from https://mathworld.wolfram.com/SpherePointPicking.html + const u = (Math.random() - 0.5) * 2; const t = Math.random() * Math.PI * 2; const f = Math.sqrt(1 - u ** 2); @@ -3814,17 +3366,13 @@ this.z = u; return this; } - *[Symbol.iterator]() { yield this.x; yield this.y; yield this.z; } - } - const _vector$c = /*@__PURE__*/new Vector3(); - const _quaternion$4 = /*@__PURE__*/new Quaternion(); class Box3 { @@ -3833,13 +3381,11 @@ this.min = min; this.max = max; } - set(min, max) { this.min.copy(min); this.max.copy(max); return this; } - setFromArray(array) { let minX = +Infinity; let minY = +Infinity; @@ -3847,7 +3393,6 @@ let maxX = -Infinity; let maxY = -Infinity; let maxZ = -Infinity; - for (let i = 0, l = array.length; i < l; i += 3) { const x = array[i]; const y = array[i + 1]; @@ -3859,12 +3404,10 @@ if (y > maxY) maxY = y; if (z > maxZ) maxZ = z; } - this.min.set(minX, minY, minZ); this.max.set(maxX, maxY, maxZ); return this; } - setFromBufferAttribute(attribute) { let minX = +Infinity; let minY = +Infinity; @@ -3872,7 +3415,6 @@ let maxX = -Infinity; let maxY = -Infinity; let maxZ = -Infinity; - for (let i = 0, l = attribute.count; i < l; i++) { const x = attribute.getX(i); const y = attribute.getY(i); @@ -3884,150 +3426,122 @@ if (y > maxY) maxY = y; if (z > maxZ) maxZ = z; } - this.min.set(minX, minY, minZ); this.max.set(maxX, maxY, maxZ); return this; } - setFromPoints(points) { this.makeEmpty(); - for (let i = 0, il = points.length; i < il; i++) { this.expandByPoint(points[i]); } - return this; } - setFromCenterAndSize(center, size) { const halfSize = _vector$b.copy(size).multiplyScalar(0.5); - this.min.copy(center).sub(halfSize); this.max.copy(center).add(halfSize); return this; } - setFromObject(object, precise = false) { this.makeEmpty(); return this.expandByObject(object, precise); } - clone() { return new this.constructor().copy(this); } - copy(box) { this.min.copy(box.min); this.max.copy(box.max); return this; } - makeEmpty() { this.min.x = this.min.y = this.min.z = +Infinity; this.max.x = this.max.y = this.max.z = -Infinity; return this; } - 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; } - getCenter(target) { return this.isEmpty() ? target.set(0, 0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5); } - getSize(target) { return this.isEmpty() ? target.set(0, 0, 0) : target.subVectors(this.max, this.min); } - expandByPoint(point) { this.min.min(point); this.max.max(point); return this; } - expandByVector(vector) { this.min.sub(vector); this.max.add(vector); return this; } - expandByScalar(scalar) { this.min.addScalar(-scalar); this.max.addScalar(scalar); return this; } - expandByObject(object, precise = false) { // 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); const geometry = object.geometry; - if (geometry !== undefined) { if (precise && geometry.attributes != undefined && geometry.attributes.position !== undefined) { const position = geometry.attributes.position; - for (let i = 0, l = position.count; i < l; i++) { _vector$b.fromBufferAttribute(position, i).applyMatrix4(object.matrixWorld); - this.expandByPoint(_vector$b); } } else { if (geometry.boundingBox === null) { geometry.computeBoundingBox(); } - _box$3.copy(geometry.boundingBox); - _box$3.applyMatrix4(object.matrixWorld); - this.union(_box$3); } } - const children = object.children; - for (let i = 0, l = children.length; i < l; i++) { this.expandByObject(children[i], precise); } - return this; } - 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; } - 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; } - getParameter(point, target) { // This can potentially have a divide by zero if the box // has a size dimension of 0. + 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)); } - 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; } - intersectsSphere(sphere) { // Find the point on the AABB closest to the sphere center. - this.clampPoint(sphere.center, _vector$b); // If that point is inside the sphere, the AABB and sphere intersect. + this.clampPoint(sphere.center, _vector$b); + // If that point is inside the sphere, the AABB and sphere intersect. return _vector$b.distanceToSquared(sphere.center) <= sphere.radius * sphere.radius; } - 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. - let min, max; + let min, max; if (plane.normal.x > 0) { min = plane.normal.x * this.min.x; max = plane.normal.x * this.max.x; @@ -4035,7 +3549,6 @@ min = plane.normal.x * this.max.x; max = plane.normal.x * this.min.x; } - if (plane.normal.y > 0) { min += plane.normal.y * this.min.y; max += plane.normal.y * this.max.y; @@ -4043,7 +3556,6 @@ min += plane.normal.y * this.max.y; max += plane.normal.y * this.min.y; } - if (plane.normal.z > 0) { min += plane.normal.z * this.min.z; max += plane.normal.z * this.max.z; @@ -4051,411 +3563,318 @@ min += plane.normal.z * this.max.z; max += plane.normal.z * this.min.z; } - return min <= -plane.constant && max >= -plane.constant; } - intersectsTriangle(triangle) { if (this.isEmpty()) { return false; - } // compute box center and extents - + } + // compute box center and extents this.getCenter(_center); + _extents.subVectors(this.max, _center); - _extents.subVectors(this.max, _center); // translate triangle to aabb origin - - + // translate triangle to aabb origin _v0$2.subVectors(triangle.a, _center); - _v1$7.subVectors(triangle.b, _center); + _v2$4.subVectors(triangle.c, _center); - _v2$3.subVectors(triangle.c, _center); // compute edge vectors for triangle - - + // compute edge vectors for triangle _f0.subVectors(_v1$7, _v0$2); + _f1.subVectors(_v2$4, _v1$7); + _f2.subVectors(_v0$2, _v2$4); - _f1.subVectors(_v2$3, _v1$7); - - _f2.subVectors(_v0$2, _v2$3); // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb + // 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) - - let 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]; - - if (!satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents)) { + if (!satForAxes(axes, _v0$2, _v1$7, _v2$4, _extents)) { return false; - } // test 3 face normals from the aabb - + } + // test 3 face normals from the aabb axes = [1, 0, 0, 0, 1, 0, 0, 0, 1]; - - if (!satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents)) { + if (!satForAxes(axes, _v0$2, _v1$7, _v2$4, _extents)) { return false; - } // finally testing the face normal of the triangle - // use already existing triangle edge vectors here - + } + // finally testing the face normal of the triangle + // use already existing triangle edge vectors here _triangleNormal.crossVectors(_f0, _f1); - axes = [_triangleNormal.x, _triangleNormal.y, _triangleNormal.z]; - return satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents); + return satForAxes(axes, _v0$2, _v1$7, _v2$4, _extents); } - clampPoint(point, target) { return target.copy(point).clamp(this.min, this.max); } - distanceToPoint(point) { const clampedPoint = _vector$b.copy(point).clamp(this.min, this.max); - return clampedPoint.sub(point).length(); } - getBoundingSphere(target) { this.getCenter(target.center); target.radius = this.getSize(_vector$b).length() * 0.5; return target; } - 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. + 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. if (this.isEmpty()) this.makeEmpty(); return this; } - union(box) { this.min.min(box.min); this.max.max(box.max); return this; } - 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 + if (this.isEmpty()) return this; + // 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 - this.setFromPoints(_points); return this; } - translate(offset) { this.min.add(offset); this.max.add(offset); return this; } - equals(box) { return box.min.equals(this.min) && box.max.equals(this.max); } - } - const _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()]; - const _vector$b = /*@__PURE__*/new Vector3(); + const _box$3 = /*@__PURE__*/new Box3(); - const _box$3 = /*@__PURE__*/new Box3(); // triangle centered vertices - + // triangle centered vertices const _v0$2 = /*@__PURE__*/new Vector3(); - const _v1$7 = /*@__PURE__*/new Vector3(); + const _v2$4 = /*@__PURE__*/new Vector3(); - const _v2$3 = /*@__PURE__*/new Vector3(); // triangle edge vectors - + // triangle edge vectors const _f0 = /*@__PURE__*/new Vector3(); - const _f1 = /*@__PURE__*/new Vector3(); - const _f2 = /*@__PURE__*/new Vector3(); - const _center = /*@__PURE__*/new Vector3(); - const _extents = /*@__PURE__*/new Vector3(); - const _triangleNormal = /*@__PURE__*/new Vector3(); - const _testAxis = /*@__PURE__*/new Vector3(); - function satForAxes(axes, v0, v1, v2, extents) { for (let i = 0, j = axes.length - 3; i <= j; i += 3) { - _testAxis.fromArray(axes, i); // project the aabb onto the separating axis - - - const 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 separating axis - + _testAxis.fromArray(axes, i); + // project the aabb onto the separating axis + const 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 separating axis const p0 = v0.dot(_testAxis); const p1 = v1.dot(_testAxis); - const p2 = v2.dot(_testAxis); // actual test, basically see if either of the most extreme of the triangle points intersects r - + const 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 separating and we can exit return false; } } - return true; } const _box$2 = /*@__PURE__*/new Box3(); - const _v1$6 = /*@__PURE__*/new Vector3(); - - const _toFarthestPoint = /*@__PURE__*/new Vector3(); - - const _toPoint = /*@__PURE__*/new Vector3(); - + const _v2$3 = /*@__PURE__*/new Vector3(); class Sphere { constructor(center = new Vector3(), radius = -1) { this.center = center; this.radius = radius; } - set(center, radius) { this.center.copy(center); this.radius = radius; return this; } - setFromPoints(points, optionalCenter) { const center = this.center; - if (optionalCenter !== undefined) { center.copy(optionalCenter); } else { _box$2.setFromPoints(points).getCenter(center); } - let maxRadiusSq = 0; - for (let i = 0, il = points.length; i < il; i++) { maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(points[i])); } - this.radius = Math.sqrt(maxRadiusSq); return this; } - copy(sphere) { this.center.copy(sphere.center); this.radius = sphere.radius; return this; } - isEmpty() { return this.radius < 0; } - makeEmpty() { this.center.set(0, 0, 0); this.radius = -1; return this; } - containsPoint(point) { return point.distanceToSquared(this.center) <= this.radius * this.radius; } - distanceToPoint(point) { return point.distanceTo(this.center) - this.radius; } - intersectsSphere(sphere) { const radiusSum = this.radius + sphere.radius; return sphere.center.distanceToSquared(this.center) <= radiusSum * radiusSum; } - intersectsBox(box) { return box.intersectsSphere(this); } - intersectsPlane(plane) { return Math.abs(plane.distanceToPoint(this.center)) <= this.radius; } - clampPoint(point, target) { const deltaLengthSq = this.center.distanceToSquared(point); target.copy(point); - if (deltaLengthSq > this.radius * this.radius) { target.sub(this.center).normalize(); target.multiplyScalar(this.radius).add(this.center); } - return target; } - getBoundingBox(target) { 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; } - applyMatrix4(matrix) { this.center.applyMatrix4(matrix); this.radius = this.radius * matrix.getMaxScaleOnAxis(); return this; } - translate(offset) { this.center.add(offset); return this; } - expandByPoint(point) { - // from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L649-L671 - _toPoint.subVectors(point, this.center); - - const lengthSq = _toPoint.lengthSq(); - + if (this.isEmpty()) { + this.center.copy(point); + this.radius = 0; + return this; + } + _v1$6.subVectors(point, this.center); + const lengthSq = _v1$6.lengthSq(); if (lengthSq > this.radius * this.radius) { - const length = Math.sqrt(lengthSq); - const missingRadiusHalf = (length - this.radius) * 0.5; // Nudge this sphere towards the target point. Add half the missing distance to radius, - // and the other half to position. This gives a tighter enclosure, instead of if - // the whole missing distance were just added to radius. + // calculate the minimal sphere - this.center.add(_toPoint.multiplyScalar(missingRadiusHalf / length)); - this.radius += missingRadiusHalf; + const length = Math.sqrt(lengthSq); + const delta = (length - this.radius) * 0.5; + this.center.addScaledVector(_v1$6, delta / length); + this.radius += delta; } - return this; } - union(sphere) { - // from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L759-L769 - // To enclose another sphere into this sphere, we only need to enclose two points: - // 1) Enclose the farthest point on the other sphere into this sphere. - // 2) Enclose the opposite point of the farthest point into this sphere. + if (sphere.isEmpty()) { + return this; + } + if (this.isEmpty()) { + this.copy(sphere); + return this; + } if (this.center.equals(sphere.center) === true) { - _toFarthestPoint.set(0, 0, 1).multiplyScalar(sphere.radius); + this.radius = Math.max(this.radius, sphere.radius); } else { - _toFarthestPoint.subVectors(sphere.center, this.center).normalize().multiplyScalar(sphere.radius); + _v2$3.subVectors(sphere.center, this.center).setLength(sphere.radius); + this.expandByPoint(_v1$6.copy(sphere.center).add(_v2$3)); + this.expandByPoint(_v1$6.copy(sphere.center).sub(_v2$3)); } - - this.expandByPoint(_v1$6.copy(sphere.center).add(_toFarthestPoint)); - this.expandByPoint(_v1$6.copy(sphere.center).sub(_toFarthestPoint)); return this; } - equals(sphere) { return sphere.center.equals(this.center) && sphere.radius === this.radius; } - clone() { return new this.constructor().copy(this); } - } const _vector$a = /*@__PURE__*/new Vector3(); - const _segCenter = /*@__PURE__*/new Vector3(); - const _segDir = /*@__PURE__*/new Vector3(); - const _diff = /*@__PURE__*/new Vector3(); - const _edge1 = /*@__PURE__*/new Vector3(); - const _edge2 = /*@__PURE__*/new Vector3(); - const _normal$1 = /*@__PURE__*/new Vector3(); - class Ray { constructor(origin = new Vector3(), direction = new Vector3(0, 0, -1)) { this.origin = origin; this.direction = direction; } - set(origin, direction) { this.origin.copy(origin); this.direction.copy(direction); return this; } - copy(ray) { this.origin.copy(ray.origin); this.direction.copy(ray.direction); return this; } - at(t, target) { return target.copy(this.direction).multiplyScalar(t).add(this.origin); } - lookAt(v) { this.direction.copy(v).sub(this.origin).normalize(); return this; } - recast(t) { this.origin.copy(this.at(t, _vector$a)); return this; } - closestPointToPoint(point, target) { target.subVectors(point, this.origin); const directionDistance = target.dot(this.direction); - if (directionDistance < 0) { return target.copy(this.origin); } - return target.copy(this.direction).multiplyScalar(directionDistance).add(this.origin); } - distanceToPoint(point) { return Math.sqrt(this.distanceSqToPoint(point)); } - distanceSqToPoint(point) { - const directionDistance = _vector$a.subVectors(point, this.origin).dot(this.direction); // point behind the ray + const directionDistance = _vector$a.subVectors(point, this.origin).dot(this.direction); + // point behind the ray if (directionDistance < 0) { return this.origin.distanceToSquared(point); } - _vector$a.copy(this.direction).multiplyScalar(directionDistance).add(this.origin); - return _vector$a.distanceToSquared(point); } - distanceSqToSegment(v0, v1, optionalPointOnRay, optionalPointOnSegment) { // from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteDistRaySegment.h // It returns the min distance between the ray and the segment @@ -4463,47 +3882,43 @@ // 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); + _segCenter.copy(v0).add(v1).multiplyScalar(0.5); _segDir.copy(v1).sub(v0).normalize(); - _diff.copy(this.origin).sub(_segCenter); - const segExtent = v0.distanceTo(v1) * 0.5; const a01 = -this.direction.dot(_segDir); - const b0 = _diff.dot(this.direction); - const b1 = -_diff.dot(_segDir); - const c = _diff.lengthSq(); - const det = Math.abs(1 - a01 * a01); let s0, s1, sqrDist, extDet; - 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 (s1 >= -extDet) { if (s1 <= extDet) { // region 0 // Minimum at interior points of ray and segment. + const 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; @@ -4511,16 +3926,19 @@ } 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; @@ -4528,102 +3946,94 @@ } } 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); } - if (optionalPointOnSegment) { optionalPointOnSegment.copy(_segDir).multiplyScalar(s1).add(_segCenter); } - return sqrDist; } - intersectSphere(sphere, target) { _vector$a.subVectors(sphere.center, this.origin); - const tca = _vector$a.dot(this.direction); - const d2 = _vector$a.dot(_vector$a) - tca * tca; const radius2 = sphere.radius * sphere.radius; if (d2 > radius2) return null; - const thc = Math.sqrt(radius2 - d2); // t0 = first intersect point - entrance on front of sphere + const thc = Math.sqrt(radius2 - d2); - const t0 = tca - thc; // t1 = second intersect point - exit point on back of sphere + // t0 = first intersect point - entrance on front of sphere + const t0 = tca - thc; - const t1 = tca + thc; // test to see if both t0 and t1 are behind the ray - if so, return null + // t1 = second intersect point - exit point on back of sphere + const t1 = tca + thc; - if (t0 < 0 && t1 < 0) return null; // test to see if t0 is behind the ray: + // 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. + if (t0 < 0) return this.at(t1, target); - 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 - + // else t0 is in front of the ray, so return the first collision point scaled by t0 return this.at(t0, target); } - intersectsSphere(sphere) { return this.distanceSqToPoint(sphere.center) <= sphere.radius * sphere.radius; } - distanceToPlane(plane) { const denominator = plane.normal.dot(this.direction); - 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 + } + // Null is preferable to undefined since undefined means.... it is undefined return null; } + const t = -(this.origin.dot(plane.normal) + plane.constant) / denominator; - const t = -(this.origin.dot(plane.normal) + plane.constant) / denominator; // Return if the ray never intersects the plane + // Return if the ray never intersects the plane return t >= 0 ? t : null; } - intersectPlane(plane, target) { const t = this.distanceToPlane(plane); - if (t === null) { return null; } - return this.at(t, target); } - intersectsPlane(plane) { // check if the ray lies on the plane first - const distToPoint = plane.distanceToPoint(this.origin); + const distToPoint = plane.distanceToPoint(this.origin); if (distToPoint === 0) { return true; } - const denominator = plane.normal.dot(this.direction); - if (denominator * distToPoint < 0) { return true; - } // ray origin is behind the plane (and is pointing behind it) + } + // ray origin is behind the plane (and is pointing behind it) return false; } - intersectBox(box, target) { let tmin, tmax, tymin, tymax, tzmin, tzmax; const invdirx = 1 / this.direction.x, - invdiry = 1 / this.direction.y, - invdirz = 1 / this.direction.z; + invdiry = 1 / this.direction.y, + invdirz = 1 / this.direction.z; const origin = this.origin; - if (invdirx >= 0) { tmin = (box.min.x - origin.x) * invdirx; tmax = (box.max.x - origin.x) * invdirx; @@ -4631,7 +4041,6 @@ tmin = (box.max.x - origin.x) * invdirx; tmax = (box.min.x - origin.x) * invdirx; } - if (invdiry >= 0) { tymin = (box.min.y - origin.y) * invdiry; tymax = (box.max.y - origin.y) * invdiry; @@ -4639,13 +4048,9 @@ 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; - + if (tmin > tymax || tymin > tmax) return null; + if (tymin > tmin || isNaN(tmin)) tmin = tymin; + if (tymax < tmax || isNaN(tmax)) tmax = tymax; if (invdirz >= 0) { tzmin = (box.min.z - origin.z) * invdirz; tzmax = (box.max.z - origin.z) * invdirz; @@ -4653,36 +4058,34 @@ tzmin = (box.max.z - origin.z) * invdirz; tzmax = (box.min.z - origin.z) * invdirz; } - 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) + if (tzmax < tmax || tmax !== tmax) tmax = tzmax; + + //return point closest to the ray (positive side) if (tmax < 0) return null; return this.at(tmin >= 0 ? tmin : tmax, target); } - intersectsBox(box) { return this.intersectBox(box, _vector$a) !== null; } - intersectTriangle(a, b, c, backfaceCulling, target) { // Compute the offset origin, edges, and normal. + // from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h - _edge1.subVectors(b, a); + _edge1.subVectors(b, a); _edge2.subVectors(c, a); + _normal$1.crossVectors(_edge1, _edge2); - _normal$1.crossVectors(_edge1, _edge2); // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction, + // 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) - - let DdN = this.direction.dot(_normal$1); let sign; - if (DdN > 0) { if (backfaceCulling) return null; sign = 1; @@ -4692,52 +4095,47 @@ } else { return null; } - _diff.subVectors(this.origin, a); + const DdQxE2 = sign * this.direction.dot(_edge2.crossVectors(_diff, _edge2)); - const DdQxE2 = sign * this.direction.dot(_edge2.crossVectors(_diff, _edge2)); // b1 < 0, no intersection - + // b1 < 0, no intersection if (DdQxE2 < 0) { return null; } + const DdE1xQ = sign * this.direction.dot(_edge1.cross(_diff)); - const DdE1xQ = sign * this.direction.dot(_edge1.cross(_diff)); // b2 < 0, no intersection - + // b2 < 0, no intersection if (DdE1xQ < 0) { return null; - } // b1+b2 > 1, no intersection - + } + // b1+b2 > 1, no intersection if (DdQxE2 + DdE1xQ > DdN) { return null; - } // Line intersects triangle, check if ray does. - - - const QdN = -sign * _diff.dot(_normal$1); // t < 0, no intersection + } + // Line intersects triangle, check if ray does. + const QdN = -sign * _diff.dot(_normal$1); + // t < 0, no intersection if (QdN < 0) { return null; - } // Ray intersects triangle. - + } + // Ray intersects triangle. return this.at(QdN / DdN, target); } - applyMatrix4(matrix4) { this.origin.applyMatrix4(matrix4); this.direction.transformDirection(matrix4); return this; } - equals(ray) { return ray.origin.equals(this.origin) && ray.direction.equals(this.direction); } - clone() { return new this.constructor().copy(this); } - } class Matrix4 { @@ -4745,7 +4143,6 @@ Matrix4.prototype.isMatrix4 = true; this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; } - set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) { const te = this.elements; te[0] = n11; @@ -4766,16 +4163,13 @@ te[15] = n44; return this; } - identity() { this.set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); return this; } - clone() { return new Matrix4().fromArray(this.elements); } - copy(m) { const te = this.elements; const me = m.elements; @@ -4797,45 +4191,37 @@ te[15] = me[15]; return this; } - copyPosition(m) { const te = this.elements, - me = m.elements; + me = m.elements; te[12] = me[12]; te[13] = me[13]; te[14] = me[14]; return this; } - setFromMatrix3(m) { const me = m.elements; this.set(me[0], me[3], me[6], 0, me[1], me[4], me[7], 0, me[2], me[5], me[8], 0, 0, 0, 0, 1); return this; } - extractBasis(xAxis, yAxis, zAxis) { xAxis.setFromMatrixColumn(this, 0); yAxis.setFromMatrixColumn(this, 1); zAxis.setFromMatrixColumn(this, 2); return this; } - makeBasis(xAxis, yAxis, zAxis) { this.set(xAxis.x, yAxis.x, zAxis.x, 0, xAxis.y, yAxis.y, zAxis.y, 0, xAxis.z, yAxis.z, zAxis.z, 0, 0, 0, 0, 1); return this; } - extractRotation(m) { // this method does not support reflection matrices + const te = this.elements; const me = m.elements; - const scaleX = 1 / _v1$5.setFromMatrixColumn(m, 0).length(); - const scaleY = 1 / _v1$5.setFromMatrixColumn(m, 1).length(); - const scaleZ = 1 / _v1$5.setFromMatrixColumn(m, 2).length(); - te[0] = me[0] * scaleX; te[1] = me[1] * scaleX; te[2] = me[2] * scaleX; @@ -4854,24 +4240,22 @@ te[15] = 1; return this; } - makeRotationFromEuler(euler) { const te = this.elements; const x = euler.x, - y = euler.y, - z = euler.z; + y = euler.y, + z = euler.z; const a = Math.cos(x), - b = Math.sin(x); + b = Math.sin(x); const c = Math.cos(y), - d = Math.sin(y); + d = Math.sin(y); const e = Math.cos(z), - f = Math.sin(z); - + f = Math.sin(z); if (euler.order === 'XYZ') { const ae = a * e, - af = a * f, - be = b * e, - bf = b * f; + af = a * f, + be = b * e, + bf = b * f; te[0] = c * e; te[4] = -c * f; te[8] = d; @@ -4883,9 +4267,9 @@ te[10] = a * c; } else if (euler.order === 'YXZ') { const ce = c * e, - cf = c * f, - de = d * e, - df = d * f; + cf = c * f, + de = d * e, + df = d * f; te[0] = ce + df * b; te[4] = de * b - cf; te[8] = a * d; @@ -4897,9 +4281,9 @@ te[10] = a * c; } else if (euler.order === 'ZXY') { const ce = c * e, - cf = c * f, - de = d * e, - df = d * f; + cf = c * f, + de = d * e, + df = d * f; te[0] = ce - df * b; te[4] = -a * f; te[8] = de + cf * b; @@ -4911,9 +4295,9 @@ te[10] = a * c; } else if (euler.order === 'ZYX') { const ae = a * e, - af = a * f, - be = b * e, - bf = b * f; + af = a * f, + be = b * e, + bf = b * f; te[0] = c * e; te[4] = be * d - af; te[8] = ae * d + bf; @@ -4925,9 +4309,9 @@ te[10] = a * c; } else if (euler.order === 'YZX') { const ac = a * c, - ad = a * d, - bc = b * c, - bd = b * d; + ad = a * d, + bc = b * c, + bd = b * d; te[0] = c * e; te[4] = bd - ac * f; te[8] = bc * f + ad; @@ -4939,9 +4323,9 @@ te[10] = ac - bd * f; } else if (euler.order === 'XZY') { const ac = a * c, - ad = a * d, - bc = b * c, - bd = b * d; + ad = a * d, + bc = b * c, + bd = b * d; te[0] = c * e; te[4] = -f; te[8] = d * e; @@ -4951,55 +4335,46 @@ te[2] = bc * f - ad; te[6] = b * e; te[10] = bd * f + ac; - } // bottom row - + } + // bottom row te[3] = 0; te[7] = 0; - te[11] = 0; // last column + te[11] = 0; + // last column te[12] = 0; te[13] = 0; te[14] = 0; te[15] = 1; return this; } - makeRotationFromQuaternion(q) { return this.compose(_zero, q, _one); } - lookAt(eye, target, up) { const te = this.elements; - _z.subVectors(eye, target); - if (_z.lengthSq() === 0) { // eye and target are in the same position + _z.z = 1; } - _z.normalize(); - _x.crossVectors(up, _z); - if (_x.lengthSq() === 0) { // up and z are parallel + if (Math.abs(up.z) === 1) { _z.x += 0.0001; } else { _z.z += 0.0001; } - _z.normalize(); - _x.crossVectors(up, _z); } - _x.normalize(); - _y.crossVectors(_z, _x); - te[0] = _x.x; te[4] = _y.x; te[8] = _z.x; @@ -5011,51 +4386,48 @@ te[10] = _z.z; return this; } - multiply(m) { return this.multiplyMatrices(this, m); } - premultiply(m) { return this.multiplyMatrices(m, this); } - multiplyMatrices(a, b) { const ae = a.elements; const be = b.elements; const te = this.elements; const a11 = ae[0], - a12 = ae[4], - a13 = ae[8], - a14 = ae[12]; + a12 = ae[4], + a13 = ae[8], + a14 = ae[12]; const a21 = ae[1], - a22 = ae[5], - a23 = ae[9], - a24 = ae[13]; + a22 = ae[5], + a23 = ae[9], + a24 = ae[13]; const a31 = ae[2], - a32 = ae[6], - a33 = ae[10], - a34 = ae[14]; + a32 = ae[6], + a33 = ae[10], + a34 = ae[14]; const a41 = ae[3], - a42 = ae[7], - a43 = ae[11], - a44 = ae[15]; + a42 = ae[7], + a43 = ae[11], + a44 = ae[15]; const b11 = be[0], - b12 = be[4], - b13 = be[8], - b14 = be[12]; + b12 = be[4], + b13 = be[8], + b14 = be[12]; const b21 = be[1], - b22 = be[5], - b23 = be[9], - b24 = be[13]; + b22 = be[5], + b23 = be[9], + b24 = be[13]; const b31 = be[2], - b32 = be[6], - b33 = be[10], - b34 = be[14]; + b32 = be[6], + b33 = be[10], + b34 = be[14]; const b41 = be[3], - b42 = be[7], - b43 = be[11], - b44 = be[15]; + 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; @@ -5074,7 +4446,6 @@ te[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; return this; } - multiplyScalar(s) { const te = this.elements; te[0] *= s; @@ -5095,30 +4466,30 @@ te[15] *= s; return this; } - determinant() { const te = this.elements; const n11 = te[0], - n12 = te[4], - n13 = te[8], - n14 = te[12]; + n12 = te[4], + n13 = te[8], + n14 = te[12]; const n21 = te[1], - n22 = te[5], - n23 = te[9], - n24 = te[13]; + n22 = te[5], + n23 = te[9], + n24 = te[13]; const n31 = te[2], - n32 = te[6], - n33 = te[10], - n34 = te[14]; + n32 = te[6], + n33 = te[10], + n34 = te[14]; const n41 = te[3], - n42 = te[7], - n43 = te[11], - n44 = te[15]; //TODO: make this more efficient + n42 = te[7], + n43 = te[11], + n44 = te[15]; + + //TODO: make this more efficient //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm ) return n41 * (+n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34) + n42 * (+n11 * n23 * n34 - n11 * n24 * n33 + n14 * n21 * n33 - n13 * n21 * n34 + n13 * n24 * n31 - n14 * n23 * n31) + n43 * (+n11 * n24 * n32 - n11 * n22 * n34 - n14 * n21 * n32 + n12 * n21 * n34 + n14 * n22 * n31 - n12 * n24 * n31) + n44 * (-n13 * n22 * n31 - n11 * n23 * n32 + n11 * n22 * n33 + n13 * n21 * n32 - n12 * n21 * n33 + n12 * n23 * n31); } - transpose() { const te = this.elements; let tmp; @@ -5142,10 +4513,8 @@ te[14] = tmp; return this; } - setPosition(x, y, z) { const te = this.elements; - if (x.isVector3) { te[12] = x.x; te[13] = x.y; @@ -5155,33 +4524,31 @@ te[13] = y; te[14] = z; } - return this; } - invert() { // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm const te = this.elements, - n11 = te[0], - n21 = te[1], - n31 = te[2], - n41 = te[3], - n12 = te[4], - n22 = te[5], - n32 = te[6], - n42 = te[7], - n13 = te[8], - n23 = te[9], - n33 = te[10], - n43 = te[11], - n14 = te[12], - n24 = te[13], - n34 = te[14], - n44 = te[15], - t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44, - t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44, - t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44, - t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; + n11 = te[0], + n21 = te[1], + n31 = te[2], + n41 = te[3], + n12 = te[4], + n22 = te[5], + n32 = te[6], + n42 = te[7], + n13 = te[8], + n23 = te[9], + n33 = te[10], + n43 = te[11], + n14 = te[12], + n24 = te[13], + n34 = te[14], + n44 = te[15], + t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44, + t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44, + t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44, + t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; const det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14; if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); const detInv = 1 / det; @@ -5203,12 +4570,11 @@ te[15] = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * detInv; return this; } - scale(v) { const te = this.elements; const x = v.x, - y = v.y, - z = v.z; + y = v.y, + z = v.z; te[0] *= x; te[4] *= y; te[8] *= z; @@ -5223,7 +4589,6 @@ te[11] *= z; return this; } - getMaxScaleOnAxis() { const te = this.elements; const scaleXSq = te[0] * te[0] + te[1] * te[1] + te[2] * te[2]; @@ -5231,78 +4596,71 @@ const scaleZSq = te[8] * te[8] + te[9] * te[9] + te[10] * te[10]; return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq)); } - makeTranslation(x, y, z) { this.set(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1); return this; } - makeRotationX(theta) { const c = Math.cos(theta), - s = Math.sin(theta); + s = Math.sin(theta); this.set(1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1); return this; } - makeRotationY(theta) { const c = Math.cos(theta), - s = Math.sin(theta); + s = Math.sin(theta); this.set(c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1); return this; } - makeRotationZ(theta) { const c = Math.cos(theta), - s = Math.sin(theta); + s = Math.sin(theta); this.set(c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); return this; } - makeRotationAxis(axis, angle) { // Based on http://www.gamedev.net/reference/articles/article1199.asp + const c = Math.cos(angle); const s = Math.sin(angle); const t = 1 - c; const x = axis.x, - y = axis.y, - z = axis.z; + y = axis.y, + z = axis.z; const tx = t * x, - ty = t * y; + ty = t * y; this.set(tx * x + c, tx * y - s * z, tx * z + s * y, 0, tx * y + s * z, ty * y + c, ty * z - s * x, 0, tx * z - s * y, ty * z + s * x, t * z * z + c, 0, 0, 0, 0, 1); return this; } - makeScale(x, y, z) { this.set(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1); return this; } - makeShear(xy, xz, yx, yz, zx, zy) { this.set(1, yx, zx, 0, xy, 1, zy, 0, xz, yz, 1, 0, 0, 0, 0, 1); return this; } - compose(position, quaternion, scale) { const te = this.elements; const x = quaternion._x, - y = quaternion._y, - z = quaternion._z, - w = quaternion._w; + y = quaternion._y, + z = quaternion._z, + w = quaternion._w; const x2 = x + x, - y2 = y + y, - z2 = z + z; + y2 = y + y, + z2 = z + z; const xx = x * x2, - xy = x * y2, - xz = x * z2; + xy = x * y2, + xz = x * z2; const yy = y * y2, - yz = y * z2, - zz = z * z2; + yz = y * z2, + zz = z * z2; const wx = w * x2, - wy = w * y2, - wz = w * z2; + wy = w * y2, + wz = w * z2; const sx = scale.x, - sy = scale.y, - sz = scale.z; + sy = scale.y, + sz = scale.z; te[0] = (1 - (yy + zz)) * sx; te[1] = (xy + wz) * sx; te[2] = (xz - wy) * sx; @@ -5321,25 +4679,21 @@ te[15] = 1; return this; } - decompose(position, quaternion, scale) { const te = this.elements; - let sx = _v1$5.set(te[0], te[1], te[2]).length(); - const sy = _v1$5.set(te[4], te[5], te[6]).length(); + const sz = _v1$5.set(te[8], te[9], te[10]).length(); - const sz = _v1$5.set(te[8], te[9], te[10]).length(); // if determine is negative, we need to invert one scale - - + // if determine is negative, we need to invert one scale const det = this.determinant(); if (det < 0) sx = -sx; position.x = te[12]; position.y = te[13]; - position.z = te[14]; // scale the rotation part + position.z = te[14]; + // scale the rotation part _m1$2.copy(this); - const invSX = 1 / sx; const invSY = 1 / sy; const invSZ = 1 / sz; @@ -5358,7 +4712,6 @@ scale.z = sz; return this; } - makePerspective(left, right, top, bottom, near, far) { const te = this.elements; const x = 2 * near / (right - left); @@ -5385,7 +4738,6 @@ te[15] = 0; return this; } - makeOrthographic(left, right, top, bottom, near, far) { const te = this.elements; const w = 1.0 / (right - left); @@ -5412,26 +4764,20 @@ te[15] = 1; return this; } - equals(matrix) { const te = this.elements; const me = matrix.elements; - for (let i = 0; i < 16; i++) { if (te[i] !== me[i]) return false; } - return true; } - fromArray(array, offset = 0) { for (let i = 0; i < 16; i++) { this.elements[i] = array[i + offset]; } - return this; } - toArray(array = [], offset = 0) { const te = this.elements; array[offset] = te[0]; @@ -5452,27 +4798,17 @@ array[offset + 15] = te[15]; return array; } - } - const _v1$5 = /*@__PURE__*/new Vector3(); - const _m1$2 = /*@__PURE__*/new Matrix4(); - const _zero = /*@__PURE__*/new Vector3(0, 0, 0); - const _one = /*@__PURE__*/new Vector3(1, 1, 1); - const _x = /*@__PURE__*/new Vector3(); - const _y = /*@__PURE__*/new Vector3(); - const _z = /*@__PURE__*/new Vector3(); const _matrix$1 = /*@__PURE__*/new Matrix4(); - const _quaternion$3 = /*@__PURE__*/new Quaternion(); - class Euler { constructor(x = 0, y = 0, z = 0, order = Euler.DefaultOrder) { this.isEuler = true; @@ -5481,90 +4817,69 @@ this._z = z; this._order = order; } - get x() { return this._x; } - set x(value) { this._x = value; - this._onChangeCallback(); } - get y() { return this._y; } - set y(value) { this._y = value; - this._onChangeCallback(); } - get z() { return this._z; } - set z(value) { this._z = value; - this._onChangeCallback(); } - get order() { return this._order; } - set order(value) { this._order = value; - this._onChangeCallback(); } - set(x, y, z, order = this._order) { this._x = x; this._y = y; this._z = z; this._order = order; - this._onChangeCallback(); - return this; } - clone() { return new this.constructor(this._x, this._y, this._z, this._order); } - copy(euler) { this._x = euler._x; this._y = euler._y; this._z = euler._z; this._order = euler._order; - this._onChangeCallback(); - return this; } - setFromRotationMatrix(m, order = this._order, update = true) { // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + const te = m.elements; const m11 = te[0], - m12 = te[4], - m13 = te[8]; + m12 = te[4], + m13 = te[8]; const m21 = te[1], - m22 = te[5], - m23 = te[9]; + m22 = te[5], + m23 = te[9]; const m31 = te[2], - m32 = te[6], - m33 = te[10]; - + m32 = te[6], + m33 = te[10]; switch (order) { case 'XYZ': this._y = Math.asin(clamp(m13, -1, 1)); - if (Math.abs(m13) < 0.9999999) { this._x = Math.atan2(-m23, m33); this._z = Math.atan2(-m12, m11); @@ -5572,12 +4887,9 @@ this._x = Math.atan2(m32, m22); this._z = 0; } - break; - case 'YXZ': this._x = Math.asin(-clamp(m23, -1, 1)); - if (Math.abs(m23) < 0.9999999) { this._y = Math.atan2(m13, m33); this._z = Math.atan2(m21, m22); @@ -5585,12 +4897,9 @@ this._y = Math.atan2(-m31, m11); this._z = 0; } - break; - case 'ZXY': this._x = Math.asin(clamp(m32, -1, 1)); - if (Math.abs(m32) < 0.9999999) { this._y = Math.atan2(-m31, m33); this._z = Math.atan2(-m12, m22); @@ -5598,12 +4907,9 @@ this._y = 0; this._z = Math.atan2(m21, m11); } - break; - case 'ZYX': this._y = Math.asin(-clamp(m31, -1, 1)); - if (Math.abs(m31) < 0.9999999) { this._x = Math.atan2(m32, m33); this._z = Math.atan2(m21, m11); @@ -5611,12 +4917,9 @@ this._x = 0; this._z = Math.atan2(-m12, m22); } - break; - case 'YZX': this._z = Math.asin(clamp(m21, -1, 1)); - if (Math.abs(m21) < 0.9999999) { this._x = Math.atan2(-m23, m22); this._y = Math.atan2(-m31, m11); @@ -5624,12 +4927,9 @@ this._x = 0; this._y = Math.atan2(m13, m33); } - break; - case 'XZY': this._z = Math.asin(-clamp(m12, -1, 1)); - if (Math.abs(m12) < 0.9999999) { this._x = Math.atan2(m32, m22); this._y = Math.atan2(m13, m11); @@ -5637,50 +4937,38 @@ this._x = Math.atan2(-m23, m33); this._y = 0; } - break; - default: console.warn('THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order); } - this._order = order; if (update === true) this._onChangeCallback(); return this; } - setFromQuaternion(q, order, update) { _matrix$1.makeRotationFromQuaternion(q); - return this.setFromRotationMatrix(_matrix$1, order, update); } - setFromVector3(v, order = this._order) { return this.set(v.x, v.y, v.z, order); } - reorder(newOrder) { // WARNING: this discards revolution information -bhouston - _quaternion$3.setFromEuler(this); + _quaternion$3.setFromEuler(this); return this.setFromQuaternion(_quaternion$3, newOrder); } - equals(euler) { return euler._x === this._x && euler._y === this._y && euler._z === this._z && euler._order === this._order; } - fromArray(array) { this._x = array[0]; this._y = array[1]; this._z = array[2]; if (array[3] !== undefined) this._order = array[3]; - this._onChangeCallback(); - return this; } - toArray(array = [], offset = 0) { array[offset] = this._x; array[offset + 1] = this._y; @@ -5688,28 +4976,24 @@ array[offset + 3] = this._order; return array; } - _onChange(callback) { this._onChangeCallback = callback; return this; } - _onChangeCallback() {} - *[Symbol.iterator]() { yield this._x; yield this._y; yield this._z; yield this._order; - } // @deprecated since r138, 02cf0df1cb4575d5842fef9c85bb5a89fe020d53 + } + // @deprecated since r138, 02cf0df1cb4575d5842fef9c85bb5a89fe020d53 toVector3() { console.error('THREE.Euler: .toVector3() has been removed. Use Vector3.setFromEuler() instead'); } - } - Euler.DefaultOrder = 'XYZ'; Euler.RotationOrders = ['XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX']; @@ -5717,70 +5001,49 @@ constructor() { this.mask = 1 | 0; } - set(channel) { this.mask = (1 << channel | 0) >>> 0; } - enable(channel) { this.mask |= 1 << channel | 0; } - enableAll() { this.mask = 0xffffffff | 0; } - toggle(channel) { this.mask ^= 1 << channel | 0; } - disable(channel) { this.mask &= ~(1 << channel | 0); } - disableAll() { this.mask = 0; } - test(layers) { return (this.mask & layers.mask) !== 0; } - isEnabled(channel) { return (this.mask & (1 << channel | 0)) !== 0; } - } let _object3DId = 0; - const _v1$4 = /*@__PURE__*/new Vector3(); - const _q1 = /*@__PURE__*/new Quaternion(); - const _m1$1 = /*@__PURE__*/new Matrix4(); - const _target = /*@__PURE__*/new Vector3(); - const _position$3 = /*@__PURE__*/new Vector3(); - const _scale$2 = /*@__PURE__*/new Vector3(); - const _quaternion$2 = /*@__PURE__*/new Quaternion(); - const _xAxis = /*@__PURE__*/new Vector3(1, 0, 0); - const _yAxis = /*@__PURE__*/new Vector3(0, 1, 0); - const _zAxis = /*@__PURE__*/new Vector3(0, 0, 1); - const _addedEvent = { type: 'added' }; const _removedEvent = { type: 'removed' }; - class Object3D extends EventDispatcher { constructor() { super(); @@ -5798,19 +5061,14 @@ const rotation = new Euler(); const quaternion = new Quaternion(); const scale = new Vector3(1, 1, 1); - function onRotationChange() { quaternion.setFromEuler(rotation, false); } - function onQuaternionChange() { rotation.setFromQuaternion(quaternion, undefined, false); } - rotation._onChange(onRotationChange); - quaternion._onChange(onQuaternionChange); - Object.defineProperties(this, { position: { configurable: true, @@ -5843,6 +5101,8 @@ this.matrixWorld = new Matrix4(); this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate; this.matrixWorldNeedsUpdate = false; + this.matrixWorldAutoUpdate = Object3D.DefaultMatrixWorldAutoUpdate; // checked by the renderer + this.layers = new Layers(); this.visible = true; this.castShadow = false; @@ -5852,355 +5112,294 @@ this.animations = []; this.userData = {}; } - onBeforeRender() {} - onAfterRender() {} - applyMatrix4(matrix) { if (this.matrixAutoUpdate) this.updateMatrix(); this.matrix.premultiply(matrix); this.matrix.decompose(this.position, this.quaternion, this.scale); } - applyQuaternion(q) { this.quaternion.premultiply(q); return this; } - setRotationFromAxisAngle(axis, angle) { // assumes axis is normalized + this.quaternion.setFromAxisAngle(axis, angle); } - setRotationFromEuler(euler) { this.quaternion.setFromEuler(euler, true); } - setRotationFromMatrix(m) { // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + this.quaternion.setFromRotationMatrix(m); } - setRotationFromQuaternion(q) { // assumes q is normalized + this.quaternion.copy(q); } - rotateOnAxis(axis, angle) { // rotate object on axis in object space // axis is assumed to be normalized - _q1.setFromAxisAngle(axis, angle); + _q1.setFromAxisAngle(axis, angle); this.quaternion.multiply(_q1); return this; } - rotateOnWorldAxis(axis, angle) { // rotate object on axis in world space // axis is assumed to be normalized // method assumes no rotated parent - _q1.setFromAxisAngle(axis, angle); + _q1.setFromAxisAngle(axis, angle); this.quaternion.premultiply(_q1); return this; } - rotateX(angle) { return this.rotateOnAxis(_xAxis, angle); } - rotateY(angle) { return this.rotateOnAxis(_yAxis, angle); } - rotateZ(angle) { return this.rotateOnAxis(_zAxis, angle); } - translateOnAxis(axis, distance) { // translate object by distance along axis in object space // axis is assumed to be normalized - _v1$4.copy(axis).applyQuaternion(this.quaternion); + _v1$4.copy(axis).applyQuaternion(this.quaternion); this.position.add(_v1$4.multiplyScalar(distance)); return this; } - translateX(distance) { return this.translateOnAxis(_xAxis, distance); } - translateY(distance) { return this.translateOnAxis(_yAxis, distance); } - translateZ(distance) { return this.translateOnAxis(_zAxis, distance); } - localToWorld(vector) { return vector.applyMatrix4(this.matrixWorld); } - worldToLocal(vector) { return vector.applyMatrix4(_m1$1.copy(this.matrixWorld).invert()); } - lookAt(x, y, z) { // This method does not support objects having non-uniformly-scaled parent(s) + if (x.isVector3) { _target.copy(x); } else { _target.set(x, y, z); } - const parent = this.parent; this.updateWorldMatrix(true, false); - _position$3.setFromMatrixPosition(this.matrixWorld); - if (this.isCamera || this.isLight) { _m1$1.lookAt(_position$3, _target, this.up); } else { _m1$1.lookAt(_target, _position$3, this.up); } - this.quaternion.setFromRotationMatrix(_m1$1); - if (parent) { _m1$1.extractRotation(parent.matrixWorld); - _q1.setFromRotationMatrix(_m1$1); - this.quaternion.premultiply(_q1.invert()); } } - add(object) { if (arguments.length > 1) { for (let i = 0; i < arguments.length; i++) { this.add(arguments[i]); } - return this; } - if (object === this) { console.error('THREE.Object3D.add: object can\'t be added as a child of itself.', object); return this; } - if (object && object.isObject3D) { if (object.parent !== null) { object.parent.remove(object); } - object.parent = this; this.children.push(object); object.dispatchEvent(_addedEvent); } else { console.error('THREE.Object3D.add: object not an instance of THREE.Object3D.', object); } - return this; } - remove(object) { if (arguments.length > 1) { for (let i = 0; i < arguments.length; i++) { this.remove(arguments[i]); } - return this; } - const index = this.children.indexOf(object); - if (index !== -1) { object.parent = null; this.children.splice(index, 1); object.dispatchEvent(_removedEvent); } - return this; } - removeFromParent() { const parent = this.parent; - if (parent !== null) { parent.remove(this); } - return this; } - clear() { for (let i = 0; i < this.children.length; i++) { const object = this.children[i]; object.parent = null; object.dispatchEvent(_removedEvent); } - this.children.length = 0; return this; } - attach(object) { // adds object as a child of this, while maintaining the object's world transform + // Note: This method does not support scene graphs having non-uniformly-scaled nodes(s) - this.updateWorldMatrix(true, false); + this.updateWorldMatrix(true, false); _m1$1.copy(this.matrixWorld).invert(); - if (object.parent !== null) { object.parent.updateWorldMatrix(true, false); - _m1$1.multiply(object.parent.matrixWorld); } - object.applyMatrix4(_m1$1); this.add(object); object.updateWorldMatrix(false, true); return this; } - getObjectById(id) { return this.getObjectByProperty('id', id); } - getObjectByName(name) { return this.getObjectByProperty('name', name); } - getObjectByProperty(name, value) { if (this[name] === value) return this; - for (let i = 0, l = this.children.length; i < l; i++) { const child = this.children[i]; const object = child.getObjectByProperty(name, value); - if (object !== undefined) { return object; } } - return undefined; } - getWorldPosition(target) { this.updateWorldMatrix(true, false); return target.setFromMatrixPosition(this.matrixWorld); } - getWorldQuaternion(target) { this.updateWorldMatrix(true, false); this.matrixWorld.decompose(_position$3, target, _scale$2); return target; } - getWorldScale(target) { this.updateWorldMatrix(true, false); this.matrixWorld.decompose(_position$3, _quaternion$2, target); return target; } - getWorldDirection(target) { this.updateWorldMatrix(true, false); const e = this.matrixWorld.elements; return target.set(e[8], e[9], e[10]).normalize(); } - raycast() {} - traverse(callback) { callback(this); const children = this.children; - for (let i = 0, l = children.length; i < l; i++) { children[i].traverse(callback); } } - traverseVisible(callback) { if (this.visible === false) return; callback(this); const children = this.children; - for (let i = 0, l = children.length; i < l; i++) { children[i].traverseVisible(callback); } } - traverseAncestors(callback) { const parent = this.parent; - if (parent !== null) { callback(parent); parent.traverseAncestors(callback); } } - updateMatrix() { this.matrix.compose(this.position, this.quaternion, this.scale); this.matrixWorldNeedsUpdate = true; } - updateMatrixWorld(force) { if (this.matrixAutoUpdate) this.updateMatrix(); - if (this.matrixWorldNeedsUpdate || force) { if (this.parent === null) { this.matrixWorld.copy(this.matrix); } else { this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix); } - this.matrixWorldNeedsUpdate = false; force = true; - } // update children + } + // update children const children = this.children; - for (let i = 0, l = children.length; i < l; i++) { - children[i].updateMatrixWorld(force); + const child = children[i]; + if (child.matrixWorldAutoUpdate === true || force === true) { + child.updateMatrixWorld(force); + } } } - updateWorldMatrix(updateParents, updateChildren) { const parent = this.parent; - - if (updateParents === true && parent !== null) { + if (updateParents === true && parent !== null && parent.matrixWorldAutoUpdate === true) { parent.updateWorldMatrix(true, false); } - if (this.matrixAutoUpdate) this.updateMatrix(); - if (this.parent === null) { this.matrixWorld.copy(this.matrix); } else { this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix); - } // update children + } + // update children if (updateChildren === true) { const children = this.children; - for (let i = 0, l = children.length; i < l; i++) { - children[i].updateWorldMatrix(false, true); + const child = children[i]; + if (child.matrixWorldAutoUpdate === true) { + child.updateWorldMatrix(false, true); + } } } } - toJSON(meta) { // meta is a string when called from JSON.stringify const isRootObject = meta === undefined || typeof meta === 'string'; - const output = {}; // meta is a hash used to collect geometries, materials. + const output = {}; + + // meta is a hash used to collect geometries, materials. // not providing it implies that this is the root object // being serialized. - if (isRootObject) { // initialize meta obj meta = { @@ -6218,8 +5417,9 @@ type: 'Object', generator: 'Object3D.toJSON' }; - } // standard Object3D serialization + } + // standard Object3D serialization const object = {}; object.uuid = this.uuid; @@ -6233,24 +5433,25 @@ 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.matrixAutoUpdate === false) object.matrixAutoUpdate = false; + + // object specific properties if (this.isInstancedMesh) { object.type = 'InstancedMesh'; object.count = this.count; object.instanceMatrix = this.instanceMatrix.toJSON(); if (this.instanceColor !== null) object.instanceColor = this.instanceColor.toJSON(); - } // + } + // function serialize(library, element) { if (library[element.uuid] === undefined) { library[element.uuid] = element.toJSON(meta); } - return element.uuid; } - if (this.isScene) { if (this.background) { if (this.background.isColor) { @@ -6259,17 +5460,14 @@ object.background = this.background.toJSON(meta).uuid; } } - if (this.environment && this.environment.isTexture && this.environment.isRenderTargetTexture !== true) { object.environment = this.environment.toJSON(meta).uuid; } } else if (this.isMesh || this.isLine || this.isPoints) { object.geometry = serialize(meta.geometries, this.geometry); const parameters = this.geometry.parameters; - if (parameters !== undefined && parameters.shapes !== undefined) { const shapes = parameters.shapes; - if (Array.isArray(shapes)) { for (let i = 0, l = shapes.length; i < l; i++) { const shape = shapes[i]; @@ -6280,50 +5478,44 @@ } } } - if (this.isSkinnedMesh) { object.bindMode = this.bindMode; object.bindMatrix = this.bindMatrix.toArray(); - if (this.skeleton !== undefined) { serialize(meta.skeletons, this.skeleton); object.skeleton = this.skeleton.uuid; } } - if (this.material !== undefined) { if (Array.isArray(this.material)) { const uuids = []; - for (let i = 0, l = this.material.length; i < l; i++) { uuids.push(serialize(meta.materials, this.material[i])); } - object.material = uuids; } else { object.material = serialize(meta.materials, this.material); } - } // + } + // if (this.children.length > 0) { object.children = []; - for (let i = 0; i < this.children.length; i++) { object.children.push(this.children[i].toJSON(meta).object); } - } // + } + // if (this.animations.length > 0) { object.animations = []; - for (let i = 0; i < this.animations.length; i++) { const animation = this.animations[i]; object.animations.push(serialize(meta.animations, animation)); } } - if (isRootObject) { const geometries = extractFromCache(meta.geometries); const materials = extractFromCache(meta.materials); @@ -6342,29 +5534,25 @@ if (animations.length > 0) output.animations = animations; if (nodes.length > 0) output.nodes = nodes; } - output.object = object; - return output; // extract data from the cache hash + return output; + + // extract data from the cache hash // remove metadata on each item // and return as array - function extractFromCache(cache) { const values = []; - for (const key in cache) { const data = cache[key]; delete data.metadata; values.push(data); } - return values; } } - clone(recursive) { return new this.constructor().copy(this, recursive); } - copy(source, recursive = true) { this.name = source.name; this.up.copy(source.up); @@ -6376,6 +5564,7 @@ this.matrixWorld.copy(source.matrixWorld); this.matrixAutoUpdate = source.matrixAutoUpdate; this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; + this.matrixWorldAutoUpdate = source.matrixWorldAutoUpdate; this.layers.mask = source.layers.mask; this.visible = source.visible; this.castShadow = source.castShadow; @@ -6383,103 +5572,76 @@ this.frustumCulled = source.frustumCulled; this.renderOrder = source.renderOrder; this.userData = JSON.parse(JSON.stringify(source.userData)); - if (recursive === true) { for (let i = 0; i < source.children.length; i++) { const child = source.children[i]; this.add(child.clone()); } } - return this; } - } - Object3D.DefaultUp = /*@__PURE__*/new Vector3(0, 1, 0); Object3D.DefaultMatrixAutoUpdate = true; + Object3D.DefaultMatrixWorldAutoUpdate = true; const _v0$1 = /*@__PURE__*/new Vector3(); - const _v1$3 = /*@__PURE__*/new Vector3(); - const _v2$2 = /*@__PURE__*/new Vector3(); - const _v3$1 = /*@__PURE__*/new Vector3(); - const _vab = /*@__PURE__*/new Vector3(); - const _vac = /*@__PURE__*/new Vector3(); - const _vbc = /*@__PURE__*/new Vector3(); - const _vap = /*@__PURE__*/new Vector3(); - const _vbp = /*@__PURE__*/new Vector3(); - const _vcp = /*@__PURE__*/new Vector3(); - class Triangle { constructor(a = new Vector3(), b = new Vector3(), c = new Vector3()) { this.a = a; this.b = b; this.c = c; } - static getNormal(a, b, c, target) { target.subVectors(c, b); - _v0$1.subVectors(a, b); - target.cross(_v0$1); const targetLengthSq = target.lengthSq(); - 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 - + } + // static/instance method to calculate barycentric coordinates + // based on: http://www.blackpawn.com/texts/pointinpoly/default.html static getBarycoord(point, a, b, c, target) { _v0$1.subVectors(c, a); - _v1$3.subVectors(b, a); - _v2$2.subVectors(point, a); - const dot00 = _v0$1.dot(_v0$1); - const dot01 = _v0$1.dot(_v1$3); - const dot02 = _v0$1.dot(_v2$2); - const dot11 = _v1$3.dot(_v1$3); - const dot12 = _v1$3.dot(_v2$2); + const denom = dot00 * dot11 - dot01 * dot01; - const denom = dot00 * dot11 - dot01 * dot01; // collinear or singular triangle - + // collinear 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 target.set(-2, -1, -1); } - const invDenom = 1 / denom; const u = (dot11 * dot02 - dot01 * dot12) * invDenom; - const v = (dot00 * dot12 - dot01 * dot02) * invDenom; // barycentric coordinates must always sum to 1 + const v = (dot00 * dot12 - dot01 * dot02) * invDenom; + // barycentric coordinates must always sum to 1 return target.set(1 - u - v, v, u); } - static containsPoint(point, a, b, c) { this.getBarycoord(point, a, b, c, _v3$1); return _v3$1.x >= 0 && _v3$1.y >= 0 && _v3$1.x + _v3$1.y <= 1; } - static getUV(point, p1, p2, p3, uv1, uv2, uv3, target) { this.getBarycoord(point, p1, p2, p3, _v3$1); target.set(0, 0); @@ -6488,177 +5650,137 @@ target.addScaledVector(uv3, _v3$1.z); return target; } - static isFrontFacing(a, b, c, direction) { _v0$1.subVectors(c, b); + _v1$3.subVectors(a, b); - _v1$3.subVectors(a, b); // strictly front facing - - + // strictly front facing return _v0$1.cross(_v1$3).dot(direction) < 0 ? true : false; } - set(a, b, c) { this.a.copy(a); this.b.copy(b); this.c.copy(c); return this; } - setFromPointsAndIndices(points, i0, i1, i2) { this.a.copy(points[i0]); this.b.copy(points[i1]); this.c.copy(points[i2]); return this; } - setFromAttributeAndIndices(attribute, i0, i1, i2) { this.a.fromBufferAttribute(attribute, i0); this.b.fromBufferAttribute(attribute, i1); this.c.fromBufferAttribute(attribute, i2); return this; } - clone() { return new this.constructor().copy(this); } - copy(triangle) { this.a.copy(triangle.a); this.b.copy(triangle.b); this.c.copy(triangle.c); return this; } - getArea() { _v0$1.subVectors(this.c, this.b); - _v1$3.subVectors(this.a, this.b); - return _v0$1.cross(_v1$3).length() * 0.5; } - getMidpoint(target) { return target.addVectors(this.a, this.b).add(this.c).multiplyScalar(1 / 3); } - getNormal(target) { return Triangle.getNormal(this.a, this.b, this.c, target); } - getPlane(target) { return target.setFromCoplanarPoints(this.a, this.b, this.c); } - getBarycoord(point, target) { return Triangle.getBarycoord(point, this.a, this.b, this.c, target); } - getUV(point, uv1, uv2, uv3, target) { return Triangle.getUV(point, this.a, this.b, this.c, uv1, uv2, uv3, target); } - containsPoint(point) { return Triangle.containsPoint(point, this.a, this.b, this.c); } - isFrontFacing(direction) { return Triangle.isFrontFacing(this.a, this.b, this.c, direction); } - intersectsBox(box) { return box.intersectsTriangle(this); } - closestPointToPoint(p, target) { const a = this.a, - b = this.b, - c = this.c; - let v, w; // algorithm thanks to Real-Time Collision Detection by Christer Ericson, + b = this.b, + c = this.c; + let 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); - _vap.subVectors(p, a); - const d1 = _vab.dot(_vap); - const d2 = _vac.dot(_vap); - if (d1 <= 0 && d2 <= 0) { // vertex region of A; barycentric coords (1, 0, 0) return target.copy(a); } - _vbp.subVectors(p, b); - const d3 = _vab.dot(_vbp); - const d4 = _vac.dot(_vbp); - if (d3 >= 0 && d4 <= d3) { // vertex region of B; barycentric coords (0, 1, 0) return target.copy(b); } - const vc = d1 * d4 - d3 * d2; - if (vc <= 0 && d1 >= 0 && d3 <= 0) { - v = d1 / (d1 - d3); // edge region of AB; barycentric coords (1-v, v, 0) - + v = d1 / (d1 - d3); + // edge region of AB; barycentric coords (1-v, v, 0) return target.copy(a).addScaledVector(_vab, v); } - _vcp.subVectors(p, c); - const d5 = _vab.dot(_vcp); - const d6 = _vac.dot(_vcp); - if (d6 >= 0 && d5 <= d6) { // vertex region of C; barycentric coords (0, 0, 1) return target.copy(c); } - const vb = d5 * d2 - d1 * d6; - if (vb <= 0 && d2 >= 0 && d6 <= 0) { - w = d2 / (d2 - d6); // edge region of AC; barycentric coords (1-w, 0, w) - + w = d2 / (d2 - d6); + // edge region of AC; barycentric coords (1-w, 0, w) return target.copy(a).addScaledVector(_vac, w); } - const va = d3 * d6 - d5 * d4; - if (va <= 0 && d4 - d3 >= 0 && d5 - d6 >= 0) { _vbc.subVectors(c, b); - - w = (d4 - d3) / (d4 - d3 + (d5 - d6)); // edge region of BC; barycentric coords (0, 1-w, w) - + w = (d4 - d3) / (d4 - d3 + (d5 - d6)); + // edge region of BC; barycentric coords (0, 1-w, w) return target.copy(b).addScaledVector(_vbc, w); // edge region of BC - } // face region - - - const denom = 1 / (va + vb + vc); // u = va * denom + } + // face region + const denom = 1 / (va + vb + vc); + // u = va * denom v = vb * denom; w = vc * denom; return target.copy(a).addScaledVector(_vab, v).addScaledVector(_vac, w); } - equals(triangle) { return triangle.a.equals(this.a) && triangle.b.equals(this.b) && triangle.c.equals(this.c); } - } let materialId = 0; - class Material extends EventDispatcher { constructor() { super(); @@ -6710,54 +5832,34 @@ this.version = 0; this._alphaTest = 0; } - get alphaTest() { return this._alphaTest; } - set alphaTest(value) { if (this._alphaTest > 0 !== value > 0) { this.version++; } - this._alphaTest = value; } - onBuild() {} - onBeforeRender() {} - onBeforeCompile() {} - customProgramCacheKey() { return this.onBeforeCompile.toString(); } - setValues(values) { if (values === undefined) return; - for (const key in values) { const newValue = values[key]; - if (newValue === undefined) { console.warn('THREE.Material: \'' + key + '\' parameter is undefined.'); continue; - } // for backward compatibility if shading is set in the constructor - - - if (key === 'shading') { - console.warn('THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.'); - this.flatShading = newValue === FlatShading ? true : false; - continue; } - const currentValue = this[key]; - if (currentValue === undefined) { console.warn('THREE.' + this.type + ': \'' + key + '\' is not a property of this material.'); continue; } - if (currentValue && currentValue.isColor) { currentValue.set(newValue); } else if (currentValue && currentValue.isVector3 && newValue && newValue.isVector3) { @@ -6767,25 +5869,23 @@ } } } - toJSON(meta) { const isRootObject = meta === undefined || typeof meta === 'string'; - if (isRootObject) { meta = { textures: {}, images: {} }; } - const data = { metadata: { version: 4.5, type: 'Material', generator: 'Material.toJSON' } - }; // standard Material serialization + }; + // standard Material serialization data.uuid = this.uuid; data.type = this.type; if (this.name !== '') data.name = this.name; @@ -6803,88 +5903,71 @@ 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.iridescence !== undefined) data.iridescence = this.iridescence; if (this.iridescenceIOR !== undefined) data.iridescenceIOR = this.iridescenceIOR; if (this.iridescenceThicknessRange !== undefined) data.iridescenceThicknessRange = this.iridescenceThicknessRange; - if (this.iridescenceMap && this.iridescenceMap.isTexture) { data.iridescenceMap = this.iridescenceMap.toJSON(meta).uuid; } - if (this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture) { data.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON(meta).uuid; } - 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; data.lightMapIntensity = this.lightMapIntensity; } - 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.specularIntensityMap && this.specularIntensityMap.isTexture) data.specularIntensityMap = this.specularIntensityMap.toJSON(meta).uuid; if (this.specularColorMap && this.specularColorMap.isTexture) data.specularColorMap = this.specularColorMap.toJSON(meta).uuid; - if (this.envMap && this.envMap.isTexture) { data.envMap = this.envMap.toJSON(meta).uuid; if (this.combine !== undefined) data.combine = this.combine; } - if (this.envMapIntensity !== undefined) data.envMapIntensity = this.envMapIntensity; if (this.reflectivity !== undefined) data.reflectivity = this.reflectivity; if (this.refractionRatio !== undefined) data.refractionRatio = this.refractionRatio; - if (this.gradientMap && this.gradientMap.isTexture) { data.gradientMap = this.gradientMap.toJSON(meta).uuid; } - if (this.transmission !== undefined) data.transmission = this.transmission; if (this.transmissionMap && this.transmissionMap.isTexture) data.transmissionMap = this.transmissionMap.toJSON(meta).uuid; if (this.thickness !== undefined) data.thickness = this.thickness; if (this.thicknessMap && this.thicknessMap.isTexture) data.thicknessMap = this.thicknessMap.toJSON(meta).uuid; - if (this.attenuationDistance !== undefined) data.attenuationDistance = this.attenuationDistance; + if (this.attenuationDistance !== undefined && this.attenuationDistance !== Infinity) data.attenuationDistance = this.attenuationDistance; if (this.attenuationColor !== undefined) data.attenuationColor = this.attenuationColor.getHex(); if (this.size !== undefined) data.size = this.size; if (this.shadowSide !== null) data.shadowSide = this.shadowSide; @@ -6905,8 +5988,9 @@ data.stencilFuncMask = this.stencilFuncMask; data.stencilFail = this.stencilFail; data.stencilZFail = this.stencilZFail; - data.stencilZPass = this.stencilZPass; // rotation (SpriteMaterial) + data.stencilZPass = this.stencilZPass; + // rotation (SpriteMaterial) if (this.rotation !== undefined && this.rotation !== 0) data.rotation = this.rotation; if (this.polygonOffset === true) data.polygonOffset = true; if (this.polygonOffsetFactor !== 0) data.polygonOffsetFactor = this.polygonOffsetFactor; @@ -6927,34 +6011,30 @@ if (this.visible === false) data.visible = false; if (this.toneMapped === false) data.toneMapped = false; if (this.fog === false) data.fog = false; - if (JSON.stringify(this.userData) !== '{}') data.userData = this.userData; // TODO: Copied from Object3D.toJSON + if (JSON.stringify(this.userData) !== '{}') data.userData = this.userData; + + // TODO: Copied from Object3D.toJSON function extractFromCache(cache) { const values = []; - for (const key in cache) { const data = cache[key]; delete data.metadata; values.push(data); } - return values; } - if (isRootObject) { const textures = extractFromCache(meta.textures); const images = extractFromCache(meta.images); if (textures.length > 0) data.textures = textures; if (images.length > 0) data.images = images; } - return data; } - clone() { return new this.constructor().copy(this); } - copy(source) { this.name = source.name; this.blending = source.blending; @@ -6981,16 +6061,13 @@ this.stencilWrite = source.stencilWrite; const srcPlanes = source.clippingPlanes; let dstPlanes = null; - if (srcPlanes !== null) { const n = srcPlanes.length; dstPlanes = new Array(n); - for (let i = 0; i !== n; ++i) { dstPlanes[i] = srcPlanes[i].clone(); } } - this.clippingPlanes = dstPlanes; this.clipIntersection = source.clipIntersection; this.clipShadows = source.clipShadows; @@ -7009,17 +6086,14 @@ this.userData = JSON.parse(JSON.stringify(source.userData)); return this; } - dispose() { this.dispatchEvent({ type: 'dispose' }); } - set needsUpdate(value) { if (value === true) this.version++; } - } class MeshBasicMaterial extends Material { @@ -7047,7 +6121,6 @@ this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.color.copy(source.color); @@ -7069,19 +6142,15 @@ this.fog = source.fog; return this; } - } const _vector$9 = /*@__PURE__*/new Vector3(); - const _vector2$1 = /*@__PURE__*/new Vector2(); - class BufferAttribute { constructor(array, itemSize, normalized) { if (Array.isArray(array)) { throw new TypeError('THREE.BufferAttribute: array should be a Typed Array.'); } - this.isBufferAttribute = true; this.name = ''; this.array = array; @@ -7095,18 +6164,14 @@ }; this.version = 0; } - onUploadCallback() {} - set needsUpdate(value) { if (value === true) this.version++; } - setUsage(value) { this.usage = value; return this; } - copy(source) { this.name = source.name; this.array = new source.array.constructor(source.array); @@ -7116,235 +6181,146 @@ this.usage = source.usage; return this; } - copyAt(index1, attribute, index2) { index1 *= this.itemSize; index2 *= attribute.itemSize; - for (let i = 0, l = this.itemSize; i < l; i++) { this.array[index1 + i] = attribute.array[index2 + i]; } - return this; } - copyArray(array) { this.array.set(array); return this; } - - copyColorsArray(colors) { - const array = this.array; - let offset = 0; - - for (let i = 0, l = colors.length; i < l; i++) { - let color = colors[i]; - - if (color === undefined) { - console.warn('THREE.BufferAttribute.copyColorsArray(): color is undefined', i); - color = new Color(); - } - - array[offset++] = color.r; - array[offset++] = color.g; - array[offset++] = color.b; - } - - return this; - } - - copyVector2sArray(vectors) { - const array = this.array; - let offset = 0; - - for (let i = 0, l = vectors.length; i < l; i++) { - let vector = vectors[i]; - - if (vector === undefined) { - console.warn('THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i); - vector = new Vector2(); - } - - array[offset++] = vector.x; - array[offset++] = vector.y; - } - - return this; - } - - copyVector3sArray(vectors) { - const array = this.array; - let offset = 0; - - for (let i = 0, l = vectors.length; i < l; i++) { - let vector = vectors[i]; - - 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; - } - - return this; - } - - copyVector4sArray(vectors) { - const array = this.array; - let offset = 0; - - for (let i = 0, l = vectors.length; i < l; i++) { - let vector = vectors[i]; - - if (vector === undefined) { - console.warn('THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i); - vector = new Vector4(); - } - - array[offset++] = vector.x; - array[offset++] = vector.y; - array[offset++] = vector.z; - array[offset++] = vector.w; - } - - return this; - } - applyMatrix3(m) { if (this.itemSize === 2) { for (let i = 0, l = this.count; i < l; i++) { _vector2$1.fromBufferAttribute(this, i); - _vector2$1.applyMatrix3(m); - this.setXY(i, _vector2$1.x, _vector2$1.y); } } else if (this.itemSize === 3) { for (let i = 0, l = this.count; i < l; i++) { _vector$9.fromBufferAttribute(this, i); - _vector$9.applyMatrix3(m); - this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); } } - return this; } - applyMatrix4(m) { for (let i = 0, l = this.count; i < l; i++) { _vector$9.fromBufferAttribute(this, i); - _vector$9.applyMatrix4(m); - this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); } - return this; } - applyNormalMatrix(m) { for (let i = 0, l = this.count; i < l; i++) { _vector$9.fromBufferAttribute(this, i); - _vector$9.applyNormalMatrix(m); - this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); } - return this; } - transformDirection(m) { for (let i = 0, l = this.count; i < l; i++) { _vector$9.fromBufferAttribute(this, i); - _vector$9.transformDirection(m); - this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); } - return this; } - set(value, offset = 0) { + // Matching BufferAttribute constructor, do not normalize the array. this.array.set(value, offset); return this; } - getX(index) { - return this.array[index * this.itemSize]; + let x = this.array[index * this.itemSize]; + if (this.normalized) x = denormalize(x, this.array); + return x; } - setX(index, x) { + if (this.normalized) x = normalize(x, this.array); this.array[index * this.itemSize] = x; return this; } - getY(index) { - return this.array[index * this.itemSize + 1]; + let y = this.array[index * this.itemSize + 1]; + if (this.normalized) y = denormalize(y, this.array); + return y; } - setY(index, y) { + if (this.normalized) y = normalize(y, this.array); this.array[index * this.itemSize + 1] = y; return this; } - getZ(index) { - return this.array[index * this.itemSize + 2]; + let z = this.array[index * this.itemSize + 2]; + if (this.normalized) z = denormalize(z, this.array); + return z; } - setZ(index, z) { + if (this.normalized) z = normalize(z, this.array); this.array[index * this.itemSize + 2] = z; return this; } - getW(index) { - return this.array[index * this.itemSize + 3]; + let w = this.array[index * this.itemSize + 3]; + if (this.normalized) w = denormalize(w, this.array); + return w; } - setW(index, w) { + if (this.normalized) w = normalize(w, this.array); this.array[index * this.itemSize + 3] = w; return this; } - setXY(index, x, y) { index *= this.itemSize; + if (this.normalized) { + x = normalize(x, this.array); + y = normalize(y, this.array); + } this.array[index + 0] = x; this.array[index + 1] = y; return this; } - setXYZ(index, x, y, z) { index *= this.itemSize; + if (this.normalized) { + x = normalize(x, this.array); + y = normalize(y, this.array); + z = normalize(z, this.array); + } this.array[index + 0] = x; this.array[index + 1] = y; this.array[index + 2] = z; return this; } - setXYZW(index, x, y, z, w) { index *= this.itemSize; + if (this.normalized) { + x = normalize(x, this.array); + y = normalize(y, this.array); + z = normalize(z, this.array); + w = normalize(w, this.array); + } this.array[index + 0] = x; this.array[index + 1] = y; this.array[index + 2] = z; this.array[index + 3] = w; return this; } - onUpload(callback) { this.onUploadCallback = callback; return this; } - clone() { return new this.constructor(this.array, this.itemSize).copy(this); } - toJSON() { const data = { itemSize: this.itemSize, @@ -7358,94 +6334,83 @@ return data; } - } // + // @deprecated + + copyColorsArray() { + console.error('THREE.BufferAttribute: copyColorsArray() was removed in r144.'); + } + copyVector2sArray() { + console.error('THREE.BufferAttribute: copyVector2sArray() was removed in r144.'); + } + copyVector3sArray() { + console.error('THREE.BufferAttribute: copyVector3sArray() was removed in r144.'); + } + copyVector4sArray() { + console.error('THREE.BufferAttribute: copyVector4sArray() was removed in r144.'); + } + } + // class Int8BufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Int8Array(array), itemSize, normalized); } - } - class Uint8BufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Uint8Array(array), itemSize, normalized); } - } - class Uint8ClampedBufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Uint8ClampedArray(array), itemSize, normalized); } - } - class Int16BufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Int16Array(array), itemSize, normalized); } - } - class Uint16BufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Uint16Array(array), itemSize, normalized); } - } - class Int32BufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Int32Array(array), itemSize, normalized); } - } - class Uint32BufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Uint32Array(array), itemSize, normalized); } - } - class Float16BufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Uint16Array(array), itemSize, normalized); this.isFloat16BufferAttribute = true; } - } - class Float32BufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Float32Array(array), itemSize, normalized); } - } - class Float64BufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Float64Array(array), itemSize, normalized); } - - } // + } let _id$1 = 0; - const _m1 = /*@__PURE__*/new Matrix4(); - const _obj = /*@__PURE__*/new Object3D(); - const _offset = /*@__PURE__*/new Vector3(); - const _box$1 = /*@__PURE__*/new Box3(); - const _boxMorphTargets = /*@__PURE__*/new Box3(); - const _vector$8 = /*@__PURE__*/new Vector3(); - class BufferGeometry extends EventDispatcher { constructor() { super(); @@ -7469,39 +6434,31 @@ }; this.userData = {}; } - getIndex() { return this.index; } - setIndex(index) { if (Array.isArray(index)) { this.index = new (arrayNeedsUint32(index) ? Uint32BufferAttribute : Uint16BufferAttribute)(index, 1); } else { this.index = index; } - return this; } - getAttribute(name) { return this.attributes[name]; } - setAttribute(name, attribute) { this.attributes[name] = attribute; return this; } - deleteAttribute(name) { delete this.attributes[name]; return this; } - hasAttribute(name) { return this.attributes[name] !== undefined; } - addGroup(start, count, materialIndex = 0) { this.groups.push({ start: start, @@ -7509,155 +6466,123 @@ materialIndex: materialIndex }); } - clearGroups() { this.groups = []; } - setDrawRange(start, count) { this.drawRange.start = start; this.drawRange.count = count; } - applyMatrix4(matrix) { const position = this.attributes.position; - if (position !== undefined) { position.applyMatrix4(matrix); position.needsUpdate = true; } - const normal = this.attributes.normal; - if (normal !== undefined) { const normalMatrix = new Matrix3().getNormalMatrix(matrix); normal.applyNormalMatrix(normalMatrix); normal.needsUpdate = true; } - const tangent = this.attributes.tangent; - if (tangent !== undefined) { tangent.transformDirection(matrix); tangent.needsUpdate = true; } - if (this.boundingBox !== null) { this.computeBoundingBox(); } - if (this.boundingSphere !== null) { this.computeBoundingSphere(); } - return this; } - applyQuaternion(q) { _m1.makeRotationFromQuaternion(q); - this.applyMatrix4(_m1); return this; } - rotateX(angle) { // rotate geometry around world x-axis - _m1.makeRotationX(angle); + _m1.makeRotationX(angle); this.applyMatrix4(_m1); return this; } - rotateY(angle) { // rotate geometry around world y-axis - _m1.makeRotationY(angle); + _m1.makeRotationY(angle); this.applyMatrix4(_m1); return this; } - rotateZ(angle) { // rotate geometry around world z-axis - _m1.makeRotationZ(angle); + _m1.makeRotationZ(angle); this.applyMatrix4(_m1); return this; } - translate(x, y, z) { // translate geometry - _m1.makeTranslation(x, y, z); + _m1.makeTranslation(x, y, z); this.applyMatrix4(_m1); return this; } - scale(x, y, z) { // scale geometry - _m1.makeScale(x, y, z); + _m1.makeScale(x, y, z); this.applyMatrix4(_m1); return this; } - lookAt(vector) { _obj.lookAt(vector); - _obj.updateMatrix(); - this.applyMatrix4(_obj.matrix); return this; } - center() { this.computeBoundingBox(); this.boundingBox.getCenter(_offset).negate(); this.translate(_offset.x, _offset.y, _offset.z); return this; } - setFromPoints(points) { const position = []; - for (let i = 0, l = points.length; i < l; i++) { const point = points[i]; position.push(point.x, point.y, point.z || 0); } - this.setAttribute('position', new Float32BufferAttribute(position, 3)); return this; } - computeBoundingBox() { if (this.boundingBox === null) { this.boundingBox = new Box3(); } - const position = this.attributes.position; const 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; } - if (position !== undefined) { - this.boundingBox.setFromBufferAttribute(position); // process morph attributes if present + this.boundingBox.setFromBufferAttribute(position); + + // process morph attributes if present if (morphAttributesPosition) { for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { const morphAttribute = morphAttributesPosition[i]; - _box$1.setFromBufferAttribute(morphAttribute); - if (this.morphTargetsRelative) { _vector$8.addVectors(this.boundingBox.min, _box$1.min); - this.boundingBox.expandByPoint(_vector$8); - _vector$8.addVectors(this.boundingBox.max, _box$1.max); - this.boundingBox.expandByPoint(_vector$8); } else { this.boundingBox.expandByPoint(_box$1.min); @@ -7668,133 +6593,111 @@ } else { this.boundingBox.makeEmpty(); } - 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() { if (this.boundingSphere === null) { this.boundingSphere = new Sphere(); } - const position = this.attributes.position; const morphAttributesPosition = this.morphAttributes.position; - 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; } - if (position) { // first, find the center of the bounding sphere - const center = this.boundingSphere.center; - _box$1.setFromBufferAttribute(position); // process morph attributes if present + const center = this.boundingSphere.center; + _box$1.setFromBufferAttribute(position); + // process morph attributes if present if (morphAttributesPosition) { for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { const morphAttribute = morphAttributesPosition[i]; - _boxMorphTargets.setFromBufferAttribute(morphAttribute); - if (this.morphTargetsRelative) { _vector$8.addVectors(_box$1.min, _boxMorphTargets.min); - _box$1.expandByPoint(_vector$8); - _vector$8.addVectors(_box$1.max, _boxMorphTargets.max); - _box$1.expandByPoint(_vector$8); } else { _box$1.expandByPoint(_boxMorphTargets.min); - _box$1.expandByPoint(_boxMorphTargets.max); } } } + _box$1.getCenter(center); - _box$1.getCenter(center); // second, try to find a boundingSphere with a radius smaller than the + // second, try to find a boundingSphere with a radius smaller than the // boundingSphere of the boundingBox: sqrt(3) smaller in the best case - let maxRadiusSq = 0; - for (let i = 0, il = position.count; i < il; i++) { _vector$8.fromBufferAttribute(position, i); - maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8)); - } // process morph attributes if present + } + // process morph attributes if present if (morphAttributesPosition) { for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { const morphAttribute = morphAttributesPosition[i]; const morphTargetsRelative = this.morphTargetsRelative; - for (let j = 0, jl = morphAttribute.count; j < jl; j++) { _vector$8.fromBufferAttribute(morphAttribute, j); - if (morphTargetsRelative) { _offset.fromBufferAttribute(position, j); - _vector$8.add(_offset); } - maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8)); } } } - this.boundingSphere.radius = Math.sqrt(maxRadiusSq); - if (isNaN(this.boundingSphere.radius)) { console.error('THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this); } } } - computeTangents() { const index = this.index; - const attributes = this.attributes; // based on http://www.terathon.com/code/tangent.html + const attributes = this.attributes; + + // based on http://www.terathon.com/code/tangent.html // (per vertex tangents) if (index === null || attributes.position === undefined || attributes.normal === undefined || attributes.uv === undefined) { console.error('THREE.BufferGeometry: .computeTangents() failed. Missing required attributes (index, position, normal or uv)'); return; } - const indices = index.array; const positions = attributes.position.array; const normals = attributes.normal.array; const uvs = attributes.uv.array; const nVertices = positions.length / 3; - if (this.hasAttribute('tangent') === false) { this.setAttribute('tangent', new BufferAttribute(new Float32Array(4 * nVertices), 4)); } - const tangents = this.getAttribute('tangent').array; const tan1 = [], - tan2 = []; - + tan2 = []; for (let i = 0; i < nVertices; i++) { tan1[i] = new Vector3(); tan2[i] = new Vector3(); } - const vA = new Vector3(), - vB = new Vector3(), - vC = new Vector3(), - uvA = new Vector2(), - uvB = new Vector2(), - uvC = new Vector2(), - sdir = new Vector3(), - tdir = new Vector3(); - + vB = new Vector3(), + vC = new Vector3(), + uvA = new Vector2(), + uvB = new Vector2(), + uvC = new Vector2(), + sdir = new Vector3(), + tdir = new Vector3(); function handleTriangle(a, b, c) { vA.fromArray(positions, a * 3); vB.fromArray(positions, b * 3); @@ -7806,7 +6709,9 @@ vC.sub(vA); uvB.sub(uvA); uvC.sub(uvA); - const r = 1.0 / (uvB.x * uvC.y - uvC.x * uvB.y); // silently ignore degenerate uv triangles having coincident or colinear vertices + const r = 1.0 / (uvB.x * uvC.y - uvC.x * uvB.y); + + // silently ignore degenerate uv triangles having coincident or colinear vertices if (!isFinite(r)) return; sdir.copy(vB).multiplyScalar(uvC.y).addScaledVector(vC, -uvB.y).multiplyScalar(r); @@ -7818,38 +6723,36 @@ tan2[b].add(tdir); tan2[c].add(tdir); } - let groups = this.groups; - if (groups.length === 0) { groups = [{ start: 0, count: indices.length }]; } - for (let i = 0, il = groups.length; i < il; ++i) { const group = groups[i]; const start = group.start; const count = group.count; - for (let j = start, jl = start + count; j < jl; j += 3) { handleTriangle(indices[j + 0], indices[j + 1], indices[j + 2]); } } - const tmp = new Vector3(), - tmp2 = new Vector3(); + tmp2 = new Vector3(); const n = new Vector3(), - n2 = new Vector3(); - + n2 = new Vector3(); function handleVertex(v) { n.fromArray(normals, v * 3); n2.copy(n); - const t = tan1[v]; // Gram-Schmidt orthogonalize + const t = tan1[v]; + + // Gram-Schmidt orthogonalize tmp.copy(t); - tmp.sub(n.multiplyScalar(n.dot(t))).normalize(); // Calculate handedness + tmp.sub(n.multiplyScalar(n.dot(t))).normalize(); + + // Calculate handedness tmp2.crossVectors(n2, t); const test = tmp2.dot(tan2[v]); @@ -7859,12 +6762,10 @@ tangents[v * 4 + 2] = tmp.z; tangents[v * 4 + 3] = w; } - for (let i = 0, il = groups.length; i < il; ++i) { const group = groups[i]; const start = group.start; const count = group.count; - for (let j = start, jl = start + count; j < jl; j += 3) { handleVertex(indices[j + 0]); handleVertex(indices[j + 1]); @@ -7872,32 +6773,31 @@ } } } - computeVertexNormals() { const index = this.index; const positionAttribute = this.getAttribute('position'); - if (positionAttribute !== undefined) { let normalAttribute = this.getAttribute('normal'); - if (normalAttribute === undefined) { normalAttribute = new BufferAttribute(new Float32Array(positionAttribute.count * 3), 3); this.setAttribute('normal', normalAttribute); } else { // reset existing normals to zero + for (let i = 0, il = normalAttribute.count; i < il; i++) { normalAttribute.setXYZ(i, 0, 0, 0); } } - const pA = new Vector3(), - pB = new Vector3(), - pC = new Vector3(); + pB = new Vector3(), + pC = new Vector3(); const nA = new Vector3(), - nB = new Vector3(), - nC = new Vector3(); + nB = new Vector3(), + nC = new Vector3(); const cb = new Vector3(), - ab = new Vector3(); // indexed elements + ab = new Vector3(); + + // indexed elements if (index) { for (let i = 0, il = index.count; i < il; i += 3) { @@ -7922,6 +6822,7 @@ } } else { // non-indexed elements (unconnected triangle soup) + for (let i = 0, il = positionAttribute.count; i < il; i += 3) { pA.fromBufferAttribute(positionAttribute, i + 0); pB.fromBufferAttribute(positionAttribute, i + 1); @@ -7934,54 +6835,25 @@ normalAttribute.setXYZ(i + 2, cb.x, cb.y, cb.z); } } - this.normalizeNormals(); normalAttribute.needsUpdate = true; } } - merge(geometry, offset) { - if (!(geometry && geometry.isBufferGeometry)) { - console.error('THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry); - return; - } - - if (offset === undefined) { - offset = 0; - console.warn('THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. ' + 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.'); - } - - const attributes = this.attributes; - - for (const key in attributes) { - if (geometry.attributes[key] === undefined) continue; - const attribute1 = attributes[key]; - const attributeArray1 = attribute1.array; - const attribute2 = geometry.attributes[key]; - const attributeArray2 = attribute2.array; - const attributeOffset = attribute2.itemSize * offset; - const length = Math.min(attributeArray2.length, attributeArray1.length - attributeOffset); - - for (let i = 0, j = attributeOffset; i < length; i++, j++) { - attributeArray1[j] = attributeArray2[i]; - } - } + // @deprecated since r144 + merge() { + console.error('THREE.BufferGeometry.merge() has been removed. Use THREE.BufferGeometryUtils.mergeBufferGeometries() instead.'); return this; } - normalizeNormals() { const normals = this.attributes.normal; - for (let i = 0, il = normals.count; i < il; i++) { _vector$8.fromBufferAttribute(normals, i); - _vector$8.normalize(); - normals.setXYZ(i, _vector$8.x, _vector$8.y, _vector$8.z); } } - toNonIndexed() { function convertBufferAttribute(attribute, indices) { const array = attribute.array; @@ -7989,42 +6861,41 @@ const normalized = attribute.normalized; const array2 = new array.constructor(indices.length * itemSize); let index = 0, - index2 = 0; - + index2 = 0; for (let i = 0, l = indices.length; i < l; i++) { if (attribute.isInterleavedBufferAttribute) { index = indices[i] * attribute.data.stride + attribute.offset; } else { index = indices[i] * itemSize; } - for (let j = 0; j < itemSize; j++) { array2[index2++] = array[index++]; } } - return new BufferAttribute(array2, itemSize, normalized); - } // + } + // if (this.index === null) { console.warn('THREE.BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed.'); return this; } - const geometry2 = new BufferGeometry(); const indices = this.index.array; - const attributes = this.attributes; // attributes + const attributes = this.attributes; + + // attributes for (const name in attributes) { const attribute = attributes[name]; const newAttribute = convertBufferAttribute(attribute, indices); geometry2.setAttribute(name, newAttribute); - } // morph attributes + } + // morph attributes const morphAttributes = this.morphAttributes; - for (const name in morphAttributes) { const morphArray = []; const morphAttribute = morphAttributes[name]; // morphAttribute: array of Float32BufferAttributes @@ -8034,22 +6905,19 @@ const newAttribute = convertBufferAttribute(attribute, indices); morphArray.push(newAttribute); } - geometry2.morphAttributes[name] = morphArray; } + geometry2.morphTargetsRelative = this.morphTargetsRelative; - geometry2.morphTargetsRelative = this.morphTargetsRelative; // groups + // groups const groups = this.groups; - for (let i = 0, l = groups.length; i < l; i++) { const group = groups[i]; geometry2.addGroup(group.start, group.count, group.materialIndex); } - return geometry2; } - toJSON() { const data = { metadata: { @@ -8057,118 +6925,109 @@ type: 'BufferGeometry', generator: 'BufferGeometry.toJSON' } - }; // standard BufferGeometry serialization + }; + + // 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; - if (this.parameters !== undefined) { const parameters = this.parameters; - for (const key in parameters) { if (parameters[key] !== undefined) data[key] = parameters[key]; } - return data; - } // for simplicity the code assumes attributes are not shared across geometries, see #15811 + } + // for simplicity the code assumes attributes are not shared across geometries, see #15811 data.data = { attributes: {} }; const index = this.index; - if (index !== null) { data.data.index = { type: index.array.constructor.name, array: Array.prototype.slice.call(index.array) }; } - const attributes = this.attributes; - for (const key in attributes) { const attribute = attributes[key]; data.data.attributes[key] = attribute.toJSON(data.data); } - const morphAttributes = {}; let hasMorphAttributes = false; - for (const key in this.morphAttributes) { const attributeArray = this.morphAttributes[key]; const array = []; - for (let i = 0, il = attributeArray.length; i < il; i++) { const attribute = attributeArray[i]; array.push(attribute.toJSON(data.data)); } - if (array.length > 0) { morphAttributes[key] = array; hasMorphAttributes = true; } } - if (hasMorphAttributes) { data.data.morphAttributes = morphAttributes; data.data.morphTargetsRelative = this.morphTargetsRelative; } - const groups = this.groups; - if (groups.length > 0) { data.data.groups = JSON.parse(JSON.stringify(groups)); } - const boundingSphere = this.boundingSphere; - if (boundingSphere !== null) { data.data.boundingSphere = { center: boundingSphere.center.toArray(), radius: boundingSphere.radius }; } - return data; } - clone() { return new this.constructor().copy(this); } - copy(source) { // reset + this.index = null; this.attributes = {}; this.morphAttributes = {}; this.groups = []; this.boundingBox = null; - this.boundingSphere = null; // used for storing cloned, shared data + this.boundingSphere = null; - const data = {}; // name + // used for storing cloned, shared data - this.name = source.name; // index + const data = {}; - const index = source.index; + // name + this.name = source.name; + + // index + + const index = source.index; if (index !== null) { this.setIndex(index.clone(data)); - } // attributes + } + // attributes const attributes = source.attributes; - for (const name in attributes) { const attribute = attributes[name]; this.setAttribute(name, attribute.clone(data)); - } // morph attributes + } + // morph attributes const morphAttributes = source.morphAttributes; - for (const name in morphAttributes) { const array = []; const morphAttribute = morphAttributes[name]; // morphAttribute: array of Float32BufferAttributes @@ -8176,85 +7035,70 @@ for (let i = 0, l = morphAttribute.length; i < l; i++) { array.push(morphAttribute[i].clone(data)); } - this.morphAttributes[name] = array; } + this.morphTargetsRelative = source.morphTargetsRelative; - this.morphTargetsRelative = source.morphTargetsRelative; // groups + // groups const groups = source.groups; - for (let i = 0, l = groups.length; i < l; i++) { const group = groups[i]; this.addGroup(group.start, group.count, group.materialIndex); - } // bounding box + } + // bounding box const boundingBox = source.boundingBox; - if (boundingBox !== null) { this.boundingBox = boundingBox.clone(); - } // bounding sphere + } + // bounding sphere const boundingSphere = source.boundingSphere; - if (boundingSphere !== null) { this.boundingSphere = boundingSphere.clone(); - } // draw range + } + // draw range this.drawRange.start = source.drawRange.start; - this.drawRange.count = source.drawRange.count; // user data + this.drawRange.count = source.drawRange.count; + + // user data - this.userData = source.userData; // geometry generator parameters + this.userData = source.userData; + + // geometry generator parameters if (source.parameters !== undefined) this.parameters = Object.assign({}, source.parameters); return this; } - dispose() { this.dispatchEvent({ type: 'dispose' }); } - } const _inverseMatrix$2 = /*@__PURE__*/new Matrix4(); - const _ray$2 = /*@__PURE__*/new Ray(); - const _sphere$3 = /*@__PURE__*/new Sphere(); - const _vA$1 = /*@__PURE__*/new Vector3(); - const _vB$1 = /*@__PURE__*/new Vector3(); - const _vC$1 = /*@__PURE__*/new Vector3(); - const _tempA = /*@__PURE__*/new Vector3(); - const _tempB = /*@__PURE__*/new Vector3(); - const _tempC = /*@__PURE__*/new Vector3(); - const _morphA = /*@__PURE__*/new Vector3(); - const _morphB = /*@__PURE__*/new Vector3(); - const _morphC = /*@__PURE__*/new Vector3(); - const _uvA$1 = /*@__PURE__*/new Vector2(); - const _uvB$1 = /*@__PURE__*/new Vector2(); - const _uvC$1 = /*@__PURE__*/new Vector2(); - const _intersectionPoint = /*@__PURE__*/new Vector3(); - const _intersectionPointWorld = /*@__PURE__*/new Vector3(); - class Mesh extends Object3D { constructor(geometry = new BufferGeometry(), material = new MeshBasicMaterial()) { super(); @@ -8264,35 +7108,27 @@ this.material = material; this.updateMorphTargets(); } - copy(source, recursive) { super.copy(source, recursive); - if (source.morphTargetInfluences !== undefined) { this.morphTargetInfluences = source.morphTargetInfluences.slice(); } - if (source.morphTargetDictionary !== undefined) { this.morphTargetDictionary = Object.assign({}, source.morphTargetDictionary); } - this.material = source.material; this.geometry = source.geometry; return this; } - updateMorphTargets() { const geometry = this.geometry; const morphAttributes = geometry.morphAttributes; const keys = Object.keys(morphAttributes); - if (keys.length > 0) { const morphAttribute = morphAttributes[keys[0]]; - if (morphAttribute !== undefined) { this.morphTargetInfluences = []; this.morphTargetDictionary = {}; - for (let m = 0, ml = morphAttribute.length; m < ml; m++) { const name = morphAttribute[m].name || String(m); this.morphTargetInfluences.push(0); @@ -8301,30 +7137,29 @@ } } } - raycast(raycaster, intersects) { const geometry = this.geometry; const material = this.material; const matrixWorld = this.matrixWorld; - if (material === undefined) return; // Checking boundingSphere distance to ray + if (material === undefined) return; - if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); + // Checking boundingSphere distance to ray + if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); _sphere$3.copy(geometry.boundingSphere); - _sphere$3.applyMatrix4(matrixWorld); + if (raycaster.ray.intersectsSphere(_sphere$3) === false) return; - if (raycaster.ray.intersectsSphere(_sphere$3) === false) return; // + // _inverseMatrix$2.copy(matrixWorld).invert(); + _ray$2.copy(raycaster.ray).applyMatrix4(_inverseMatrix$2); - _ray$2.copy(raycaster.ray).applyMatrix4(_inverseMatrix$2); // Check boundingBox before continuing - + // Check boundingBox before continuing if (geometry.boundingBox !== null) { if (_ray$2.intersectsBox(geometry.boundingBox) === false) return; } - let intersection; const index = geometry.index; const position = geometry.attributes.position; @@ -8334,25 +7169,22 @@ const uv2 = geometry.attributes.uv2; const groups = geometry.groups; const drawRange = geometry.drawRange; - if (index !== null) { // indexed buffer geometry + if (Array.isArray(material)) { for (let i = 0, il = groups.length; i < il; i++) { const group = groups[i]; const groupMaterial = material[group.materialIndex]; const start = Math.max(group.start, drawRange.start); const end = Math.min(index.count, Math.min(group.start + group.count, drawRange.start + drawRange.count)); - for (let j = start, jl = end; j < jl; j += 3) { const a = index.getX(j); const b = index.getX(j + 1); const c = index.getX(j + 2); intersection = checkBufferGeometryIntersection(this, groupMaterial, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c); - if (intersection) { intersection.faceIndex = Math.floor(j / 3); // triangle number in indexed buffer semantics - intersection.face.materialIndex = group.materialIndex; intersects.push(intersection); } @@ -8361,38 +7193,33 @@ } else { const start = Math.max(0, drawRange.start); const end = Math.min(index.count, drawRange.start + drawRange.count); - for (let i = start, il = end; i < il; i += 3) { const a = index.getX(i); const b = index.getX(i + 1); const c = index.getX(i + 2); intersection = checkBufferGeometryIntersection(this, material, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c); - if (intersection) { intersection.faceIndex = Math.floor(i / 3); // triangle number in indexed buffer semantics - intersects.push(intersection); } } } } else if (position !== undefined) { // non-indexed buffer geometry + if (Array.isArray(material)) { for (let i = 0, il = groups.length; i < il; i++) { const group = groups[i]; const groupMaterial = material[group.materialIndex]; const start = Math.max(group.start, drawRange.start); const end = Math.min(position.count, Math.min(group.start + group.count, drawRange.start + drawRange.count)); - for (let j = start, jl = end; j < jl; j += 3) { const a = j; const b = j + 1; const c = j + 2; intersection = checkBufferGeometryIntersection(this, groupMaterial, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c); - if (intersection) { intersection.faceIndex = Math.floor(j / 3); // triangle number in non-indexed buffer semantics - intersection.face.materialIndex = group.materialIndex; intersects.push(intersection); } @@ -8401,40 +7228,30 @@ } else { const start = Math.max(0, drawRange.start); const end = Math.min(position.count, drawRange.start + drawRange.count); - for (let i = start, il = end; i < il; i += 3) { const a = i; const b = i + 1; const c = i + 2; intersection = checkBufferGeometryIntersection(this, material, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c); - if (intersection) { intersection.faceIndex = Math.floor(i / 3); // triangle number in non-indexed buffer semantics - intersects.push(intersection); } } } } } - } - function checkIntersection(object, material, raycaster, ray, pA, pB, pC, point) { let intersect; - if (material.side === BackSide) { intersect = ray.intersectTriangle(pC, pB, pA, true, point); } else { intersect = ray.intersectTriangle(pA, pB, pC, material.side !== DoubleSide, point); } - if (intersect === null) return null; - _intersectionPointWorld.copy(point); - _intersectionPointWorld.applyMatrix4(object.matrixWorld); - const distance = raycaster.ray.origin.distanceTo(_intersectionPointWorld); if (distance < raycaster.near || distance > raycaster.far) return null; return { @@ -8443,85 +7260,55 @@ object: object }; } - function checkBufferGeometryIntersection(object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c) { _vA$1.fromBufferAttribute(position, a); - _vB$1.fromBufferAttribute(position, b); - _vC$1.fromBufferAttribute(position, c); - const morphInfluences = object.morphTargetInfluences; - if (morphPosition && morphInfluences) { _morphA.set(0, 0, 0); - _morphB.set(0, 0, 0); - _morphC.set(0, 0, 0); - for (let i = 0, il = morphPosition.length; i < il; i++) { const influence = morphInfluences[i]; const morphAttribute = morphPosition[i]; if (influence === 0) continue; - _tempA.fromBufferAttribute(morphAttribute, a); - _tempB.fromBufferAttribute(morphAttribute, b); - _tempC.fromBufferAttribute(morphAttribute, c); - if (morphTargetsRelative) { _morphA.addScaledVector(_tempA, influence); - _morphB.addScaledVector(_tempB, influence); - _morphC.addScaledVector(_tempC, influence); } else { _morphA.addScaledVector(_tempA.sub(_vA$1), influence); - _morphB.addScaledVector(_tempB.sub(_vB$1), influence); - _morphC.addScaledVector(_tempC.sub(_vC$1), influence); } } - _vA$1.add(_morphA); - _vB$1.add(_morphB); - _vC$1.add(_morphC); } - if (object.isSkinnedMesh) { object.boneTransform(a, _vA$1); object.boneTransform(b, _vB$1); object.boneTransform(c, _vC$1); } - const intersection = checkIntersection(object, material, raycaster, ray, _vA$1, _vB$1, _vC$1, _intersectionPoint); - if (intersection) { if (uv) { _uvA$1.fromBufferAttribute(uv, a); - _uvB$1.fromBufferAttribute(uv, b); - _uvC$1.fromBufferAttribute(uv, c); - intersection.uv = Triangle.getUV(_intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2()); } - if (uv2) { _uvA$1.fromBufferAttribute(uv2, a); - _uvB$1.fromBufferAttribute(uv2, b); - _uvC$1.fromBufferAttribute(uv2, c); - intersection.uv2 = Triangle.getUV(_intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2()); } - const face = { a: a, b: b, @@ -8532,7 +7319,6 @@ Triangle.getNormal(_vA$1, _vB$1, _vC$1, face.normal); intersection.face = face; } - return intersection; } @@ -8548,38 +7334,41 @@ heightSegments: heightSegments, depthSegments: depthSegments }; - const scope = this; // segments + const scope = this; + + // segments widthSegments = Math.floor(widthSegments); heightSegments = Math.floor(heightSegments); - depthSegments = Math.floor(depthSegments); // buffers + depthSegments = Math.floor(depthSegments); + + // buffers const indices = []; const vertices = []; const normals = []; - const uvs = []; // helper variables + const uvs = []; + + // helper variables let numberOfVertices = 0; - let groupStart = 0; // build each side of the box geometry + let groupStart = 0; - buildPlane('z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0); // px + // build each side of the box geometry + buildPlane('z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0); // px buildPlane('z', 'y', 'x', 1, -1, depth, height, -width, depthSegments, heightSegments, 1); // nx - buildPlane('x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2); // py - 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 - buildPlane('x', 'y', 'z', -1, -1, width, height, -depth, widthSegments, heightSegments, 5); // nz + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); - function buildPlane(u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex) { const segmentWidth = width / gridX; const segmentHeight = height / gridY; @@ -8590,78 +7379,98 @@ const gridY1 = gridY + 1; let vertexCounter = 0; let groupCount = 0; - const vector = new Vector3(); // generate vertices, normals and uvs + const vector = new Vector3(); + + // generate vertices, normals and uvs for (let iy = 0; iy < gridY1; iy++) { const y = iy * segmentHeight - heightHalf; - for (let ix = 0; ix < gridX1; ix++) { - const x = ix * segmentWidth - widthHalf; // set values to correct vector component + const x = ix * segmentWidth - widthHalf; + + // set values to correct vector component vector[u] = x * udir; vector[v] = y * vdir; - vector[w] = depthHalf; // now apply vector to vertex buffer + vector[w] = depthHalf; + + // now apply vector to vertex buffer - vertices.push(vector.x, vector.y, vector.z); // set values to correct vector component + 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 + vector[w] = depth > 0 ? 1 : -1; + + // now apply vector to normal buffer - normals.push(vector.x, vector.y, vector.z); // uvs + normals.push(vector.x, vector.y, vector.z); + + // uvs uvs.push(ix / gridX); - uvs.push(1 - iy / gridY); // counters + uvs.push(1 - iy / gridY); + + // counters vertexCounter += 1; } - } // indices + } + + // 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 - for (let iy = 0; iy < gridY; iy++) { for (let ix = 0; ix < gridX; ix++) { const a = numberOfVertices + ix + gridX1 * iy; const b = numberOfVertices + ix + gridX1 * (iy + 1); const c = numberOfVertices + (ix + 1) + gridX1 * (iy + 1); - const d = numberOfVertices + (ix + 1) + gridX1 * iy; // faces + const d = numberOfVertices + (ix + 1) + gridX1 * iy; + + // faces indices.push(a, b, d); - indices.push(b, c, d); // increase counter + indices.push(b, c, d); + + // increase counter groupCount += 6; } - } // add a group to the geometry. this will ensure multi material support + } + // add a group to the geometry. this will ensure multi material support - scope.addGroup(groupStart, groupCount, materialIndex); // calculate new start value for groups + scope.addGroup(groupStart, groupCount, materialIndex); - groupStart += groupCount; // update total number of vertices + // calculate new start value for groups + + groupStart += groupCount; + + // update total number of vertices numberOfVertices += vertexCounter; } } - static fromJSON(data) { return new BoxGeometry(data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments); } - } /** * Uniform Utilities */ + function cloneUniforms(src) { const dst = {}; - for (const u in src) { dst[u] = {}; - for (const p in src[u]) { const property = src[u][p]; - if (property && (property.isColor || property.isMatrix3 || property.isMatrix4 || property.isVector2 || property.isVector3 || property.isVector4 || property.isTexture || property.isQuaternion)) { dst[u][p] = property.clone(); } else if (Array.isArray(property)) { @@ -8671,31 +7480,34 @@ } } } - return dst; } function mergeUniforms(uniforms) { const merged = {}; - for (let u = 0; u < uniforms.length; u++) { const tmp = cloneUniforms(uniforms[u]); - for (const p in tmp) { merged[p] = tmp[p]; } } - return merged; } function cloneUniformsGroups(src) { const dst = []; - for (let u = 0; u < src.length; u++) { dst.push(src[u].clone()); } - return dst; - } // Legacy + } + function getUnlitUniformColorSpace(renderer) { + if (renderer.getRenderTarget() === null) { + // https://github.com/mrdoob/three.js/pull/23937#issuecomment-1111067398 + return renderer.outputEncoding === sRGBEncoding ? SRGBColorSpace : LinearSRGBColorSpace; + } + return LinearSRGBColorSpace; + } + + // Legacy const UniformsUtils = { clone: cloneUniforms, @@ -8720,9 +7532,7 @@ this.wireframe = false; this.wireframeLinewidth = 1; this.fog = false; // set to use scene fog - this.lights = false; // set to use scene lights - this.clipping = false; // set to use user-defined clipping planes this.extensions = { @@ -8733,10 +7543,10 @@ drawBuffers: false, // set to use draw buffers shaderTextureLOD: false // set to use shader texture LOD + }; - }; // When rendered geometry doesn't include these attributes but the material does, + // 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], @@ -8745,16 +7555,10 @@ 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); } } - copy(source) { super.copy(source); this.fragmentShader = source.fragmentShader; @@ -8771,16 +7575,13 @@ this.glslVersion = source.glslVersion; return this; } - toJSON(meta) { const data = super.toJSON(meta); data.glslVersion = this.glslVersion; data.uniforms = {}; - for (const name in this.uniforms) { const uniform = this.uniforms[name]; const value = uniform.value; - if (value && value.isTexture) { data.uniforms[name] = { type: 't', @@ -8819,7 +7620,9 @@ } else { data.uniforms[name] = { value: value - }; // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far + }; + + // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far } } @@ -8827,15 +7630,12 @@ data.vertexShader = this.vertexShader; data.fragmentShader = this.fragmentShader; const extensions = {}; - for (const key in this.extensions) { if (this.extensions[key] === true) extensions[key] = true; } - if (Object.keys(extensions).length > 0) data.extensions = extensions; return data; } - } class Camera extends Object3D { @@ -8847,7 +7647,6 @@ this.projectionMatrix = new Matrix4(); this.projectionMatrixInverse = new Matrix4(); } - copy(source, recursive) { super.copy(source, recursive); this.matrixWorldInverse.copy(source.matrixWorldInverse); @@ -8855,27 +7654,22 @@ this.projectionMatrixInverse.copy(source.projectionMatrixInverse); return this; } - getWorldDirection(target) { this.updateWorldMatrix(true, false); const e = this.matrixWorld.elements; return target.set(-e[8], -e[9], -e[10]).normalize(); } - updateMatrixWorld(force) { super.updateMatrixWorld(force); this.matrixWorldInverse.copy(this.matrixWorld).invert(); } - updateWorldMatrix(updateParents, updateChildren) { super.updateWorldMatrix(updateParents, updateChildren); this.matrixWorldInverse.copy(this.matrixWorld).invert(); } - clone() { return new this.constructor().copy(this); } - } class PerspectiveCamera extends Camera { @@ -8891,12 +7685,10 @@ this.aspect = aspect; 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(); } - copy(source, recursive) { super.copy(source, recursive); this.fov = source.fov; @@ -8910,6 +7702,7 @@ this.filmOffset = source.filmOffset; return this; } + /** * Sets the FOV by focal length in respect to the current .filmGauge. * @@ -8918,37 +7711,32 @@ * * Values for focal length and film gauge must have the same unit. */ - - setFocalLength(focalLength) { /** see {@link http://www.bobatkins.com/photography/technical/field_of_view.html} */ const vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; this.fov = RAD2DEG * 2 * Math.atan(vExtentSlope); this.updateProjectionMatrix(); } + /** * Calculates the focal length from the current .fov and .filmGauge. */ - - getFocalLength() { const vExtentSlope = Math.tan(DEG2RAD * 0.5 * this.fov); return 0.5 * this.getFilmHeight() / vExtentSlope; } - getEffectiveFOV() { return RAD2DEG * 2 * Math.atan(Math.tan(DEG2RAD * 0.5 * this.fov) / this.zoom); } - getFilmWidth() { // film not completely covered in portrait format (aspect < 1) return this.filmGauge * Math.min(this.aspect, 1); } - getFilmHeight() { // film not completely covered in landscape format (aspect > 1) return this.filmGauge / Math.max(this.aspect, 1); } + /** * Sets an offset in a larger frustum. This is useful for multi-window or * multi-monitor/multi-machine setups. @@ -8984,11 +7772,8 @@ * * Note there is no reason monitors have to be the same size or in a grid. */ - - setViewOffset(fullWidth, fullHeight, x, y, width, height) { this.aspect = fullWidth / fullHeight; - if (this.view === null) { this.view = { enabled: true, @@ -9000,7 +7785,6 @@ height: 1 }; } - this.view.enabled = true; this.view.fullWidth = fullWidth; this.view.fullHeight = fullHeight; @@ -9010,15 +7794,12 @@ this.view.height = height; this.updateProjectionMatrix(); } - clearViewOffset() { if (this.view !== null) { this.view.enabled = false; } - this.updateProjectionMatrix(); } - updateProjectionMatrix() { const near = this.near; let top = near * Math.tan(DEG2RAD * 0.5 * this.fov) / this.zoom; @@ -9026,22 +7807,19 @@ let width = this.aspect * height; let left = -0.5 * width; const view = this.view; - if (this.view !== null && this.view.enabled) { const fullWidth = view.fullWidth, - fullHeight = view.fullHeight; + fullHeight = view.fullHeight; left += view.offsetX * width / fullWidth; top -= view.offsetY * height / fullHeight; width *= view.width / fullWidth; height *= view.height / fullHeight; } - const 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.copy(this.projectionMatrix).invert(); } - toJSON(meta) { const data = super.toJSON(meta); data.object.fov = this.fov; @@ -9055,55 +7833,46 @@ data.object.filmOffset = this.filmOffset; return data; } - } - const fov = 90, - aspect = 1; - + const fov = -90; // negative fov is not an error + const aspect = 1; class CubeCamera extends Object3D { constructor(near, far, renderTarget) { super(); 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; const cameraPX = new PerspectiveCamera(fov, aspect, near, far); cameraPX.layers = this.layers; - cameraPX.up.set(0, -1, 0); - cameraPX.lookAt(new Vector3(1, 0, 0)); + cameraPX.up.set(0, 1, 0); + cameraPX.lookAt(1, 0, 0); this.add(cameraPX); const cameraNX = new PerspectiveCamera(fov, aspect, near, far); cameraNX.layers = this.layers; - cameraNX.up.set(0, -1, 0); - cameraNX.lookAt(new Vector3(-1, 0, 0)); + cameraNX.up.set(0, 1, 0); + cameraNX.lookAt(-1, 0, 0); this.add(cameraNX); const cameraPY = new PerspectiveCamera(fov, aspect, near, far); cameraPY.layers = this.layers; - cameraPY.up.set(0, 0, 1); - cameraPY.lookAt(new Vector3(0, 1, 0)); + cameraPY.up.set(0, 0, -1); + cameraPY.lookAt(0, 1, 0); this.add(cameraPY); const cameraNY = new PerspectiveCamera(fov, aspect, near, far); cameraNY.layers = this.layers; - cameraNY.up.set(0, 0, -1); - cameraNY.lookAt(new Vector3(0, -1, 0)); + cameraNY.up.set(0, 0, 1); + cameraNY.lookAt(0, -1, 0); this.add(cameraNY); const cameraPZ = new PerspectiveCamera(fov, aspect, near, far); cameraPZ.layers = this.layers; - cameraPZ.up.set(0, -1, 0); - cameraPZ.lookAt(new Vector3(0, 0, 1)); + cameraPZ.up.set(0, 1, 0); + cameraPZ.lookAt(0, 0, 1); this.add(cameraPZ); const cameraNZ = new PerspectiveCamera(fov, aspect, near, far); cameraNZ.layers = this.layers; - cameraNZ.up.set(0, -1, 0); - cameraNZ.lookAt(new Vector3(0, 0, -1)); + cameraNZ.up.set(0, 1, 0); + cameraNZ.lookAt(0, 0, -1); this.add(cameraNZ); } - update(renderer, scene) { if (this.parent === null) this.updateMatrixWorld(); const renderTarget = this.renderTarget; @@ -9133,7 +7902,6 @@ renderer.xr.enabled = currentXrEnabled; renderTarget.texture.needsPMREMUpdate = true; } - } class CubeTexture extends Texture { @@ -9144,19 +7912,16 @@ this.isCubeTexture = true; this.flipY = false; } - get images() { return this.image; } - set images(value) { this.image = value; } - } class WebGLCubeRenderTarget extends WebGLRenderTarget { - constructor(size, options = {}) { + constructor(size = 1, options = {}) { super(size, size, options); this.isWebGLCubeRenderTarget = true; const image = { @@ -9165,9 +7930,12 @@ depth: 1 }; const images = [image, image, image, image, image, image]; - this.texture = new CubeTexture(images, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding); // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js) + this.texture = new CubeTexture(images, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding); + + // 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 isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture // as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures). @@ -9176,7 +7944,6 @@ this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false; this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter; } - fromEquirectangularTexture(renderer, texture) { this.texture.type = texture.type; this.texture.encoding = texture.encoding; @@ -9189,9 +7956,7 @@ value: null } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec3 vWorldDirection; @@ -9210,9 +7975,7 @@ } `, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tEquirect; @@ -9242,8 +8005,9 @@ }); material.uniforms.tEquirect.value = texture; const mesh = new Mesh(geometry, material); - const currentMinFilter = texture.minFilter; // Avoid blurred poles + const currentMinFilter = texture.minFilter; + // Avoid blurred poles if (texture.minFilter === LinearMipmapLinearFilter) texture.minFilter = LinearFilter; const camera = new CubeCamera(1, 10, this); camera.update(renderer, mesh); @@ -9252,167 +8016,137 @@ mesh.material.dispose(); return this; } - clear(renderer, color, depth, stencil) { const currentRenderTarget = renderer.getRenderTarget(); - for (let i = 0; i < 6; i++) { renderer.setRenderTarget(this, i); renderer.clear(color, depth, stencil); } - renderer.setRenderTarget(currentRenderTarget); } - } const _vector1 = /*@__PURE__*/new Vector3(); - const _vector2 = /*@__PURE__*/new Vector3(); - const _normalMatrix = /*@__PURE__*/new Matrix3(); - class Plane { constructor(normal = new Vector3(1, 0, 0), constant = 0) { - this.isPlane = true; // normal is assumed to be normalized + this.isPlane = true; + + // normal is assumed to be normalized this.normal = normal; this.constant = constant; } - set(normal, constant) { this.normal.copy(normal); this.constant = constant; return this; } - setComponents(x, y, z, w) { this.normal.set(x, y, z); this.constant = w; return this; } - setFromNormalAndCoplanarPoint(normal, point) { this.normal.copy(normal); this.constant = -point.dot(this.normal); return this; } - setFromCoplanarPoints(a, b, c) { - const 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)? + const 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)? this.setFromNormalAndCoplanarPoint(normal, a); return this; } - copy(plane) { this.normal.copy(plane.normal); this.constant = plane.constant; return this; } - normalize() { // Note: will lead to a divide by zero if the plane is invalid. + const inverseNormalLength = 1.0 / this.normal.length(); this.normal.multiplyScalar(inverseNormalLength); this.constant *= inverseNormalLength; return this; } - negate() { this.constant *= -1; this.normal.negate(); return this; } - distanceToPoint(point) { return this.normal.dot(point) + this.constant; } - distanceToSphere(sphere) { return this.distanceToPoint(sphere.center) - sphere.radius; } - projectPoint(point, target) { return target.copy(this.normal).multiplyScalar(-this.distanceToPoint(point)).add(point); } - intersectLine(line, target) { const direction = line.delta(_vector1); const denominator = this.normal.dot(direction); - 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. - + } + // Unsure if this is the correct method to handle this case. return null; } - const t = -(line.start.dot(this.normal) + this.constant) / denominator; - if (t < 0 || t > 1) { return null; } - return target.copy(direction).multiplyScalar(t).add(line.start); } - intersectsLine(line) { // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. + const startSign = this.distanceToPoint(line.start); const endSign = this.distanceToPoint(line.end); return startSign < 0 && endSign > 0 || endSign < 0 && startSign > 0; } - intersectsBox(box) { return box.intersectsPlane(this); } - intersectsSphere(sphere) { return sphere.intersectsPlane(this); } - coplanarPoint(target) { return target.copy(this.normal).multiplyScalar(-this.constant); } - applyMatrix4(matrix, optionalNormalMatrix) { const normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix(matrix); - const referencePoint = this.coplanarPoint(_vector1).applyMatrix4(matrix); const normal = this.normal.applyMatrix3(normalMatrix).normalize(); this.constant = -referencePoint.dot(normal); return this; } - translate(offset) { this.constant -= offset.dot(this.normal); return this; } - equals(plane) { return plane.normal.equals(this.normal) && plane.constant === this.constant; } - clone() { return new this.constructor().copy(this); } - } const _sphere$2 = /*@__PURE__*/new Sphere(); - const _vector$7 = /*@__PURE__*/new Vector3(); - class Frustum { constructor(p0 = new Plane(), p1 = new Plane(), p2 = new Plane(), p3 = new Plane(), p4 = new Plane(), p5 = new Plane()) { this.planes = [p0, p1, p2, p3, p4, p5]; } - set(p0, p1, p2, p3, p4, p5) { const planes = this.planes; planes[0].copy(p0); @@ -9423,36 +8157,32 @@ planes[5].copy(p5); return this; } - copy(frustum) { const planes = this.planes; - for (let i = 0; i < 6; i++) { planes[i].copy(frustum.planes[i]); } - return this; } - setFromProjectionMatrix(m) { const planes = this.planes; const me = m.elements; const me0 = me[0], - me1 = me[1], - me2 = me[2], - me3 = me[3]; + me1 = me[1], + me2 = me[2], + me3 = me[3]; const me4 = me[4], - me5 = me[5], - me6 = me[6], - me7 = me[7]; + me5 = me[5], + me6 = me[6], + me7 = me[7]; const me8 = me[8], - me9 = me[9], - me10 = me[10], - me11 = me[11]; + me9 = me[9], + me10 = me[10], + me11 = me[11]; const me12 = me[12], - me13 = me[13], - me14 = me[14], - me15 = me[15]; + 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(); @@ -9461,76 +8191,58 @@ planes[5].setComponents(me3 + me2, me7 + me6, me11 + me10, me15 + me14).normalize(); return this; } - intersectsObject(object) { const geometry = object.geometry; if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); - _sphere$2.copy(geometry.boundingSphere).applyMatrix4(object.matrixWorld); - return this.intersectsSphere(_sphere$2); } - intersectsSprite(sprite) { _sphere$2.center.set(0, 0, 0); - _sphere$2.radius = 0.7071067811865476; - _sphere$2.applyMatrix4(sprite.matrixWorld); - return this.intersectsSphere(_sphere$2); } - intersectsSphere(sphere) { const planes = this.planes; const center = sphere.center; const negRadius = -sphere.radius; - for (let i = 0; i < 6; i++) { const distance = planes[i].distanceToPoint(center); - if (distance < negRadius) { return false; } } - return true; } - intersectsBox(box) { const planes = this.planes; - for (let i = 0; i < 6; i++) { - const plane = planes[i]; // corner at max distance + const plane = planes[i]; + + // corner at max distance _vector$7.x = plane.normal.x > 0 ? box.max.x : box.min.x; _vector$7.y = plane.normal.y > 0 ? box.max.y : box.min.y; _vector$7.z = plane.normal.z > 0 ? box.max.z : box.min.z; - if (plane.distanceToPoint(_vector$7) < 0) { return false; } } - return true; } - containsPoint(point) { const planes = this.planes; - for (let i = 0; i < 6; i++) { if (planes[i].distanceToPoint(point) < 0) { return false; } } - return true; } - clone() { return new this.constructor().copy(this); } - } function WebGLAnimation() { @@ -9538,12 +8250,10 @@ let isAnimating = false; let animationLoop = null; let requestId = null; - function onAnimationFrame(time, frame) { animationLoop(time, frame); requestId = context.requestAnimationFrame(onAnimationFrame); } - return { start: function () { if (isAnimating === true) return; @@ -9567,7 +8277,6 @@ function WebGLAttributes(gl, capabilities) { const isWebGL2 = capabilities.isWebGL2; const buffers = new WeakMap(); - function createBuffer(attribute, bufferType) { const array = attribute.array; const usage = attribute.usage; @@ -9576,7 +8285,6 @@ gl.bufferData(bufferType, array, usage); attribute.onUploadCallback(); let type; - if (array instanceof Float32Array) { type = gl.FLOAT; } else if (array instanceof Uint16Array) { @@ -9604,7 +8312,6 @@ } else { throw new Error('THREE.WebGLAttributes: Unsupported buffer data format: ' + array); } - return { buffer: buffer, type: type, @@ -9612,14 +8319,13 @@ version: attribute.version }; } - function updateBuffer(buffer, attribute, bufferType) { const array = attribute.array; const updateRange = attribute.updateRange; gl.bindBuffer(bufferType, buffer); - if (updateRange.count === -1) { // Not using update ranges + gl.bufferSubData(bufferType, 0, array); } else { if (isWebGL2) { @@ -9627,31 +8333,29 @@ } else { gl.bufferSubData(bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, array.subarray(updateRange.offset, updateRange.offset + updateRange.count)); } - updateRange.count = -1; // reset range } - } // + attribute.onUploadCallback(); + } + + // function get(attribute) { if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; return buffers.get(attribute); } - function remove(attribute) { if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; const data = buffers.get(attribute); - if (data) { gl.deleteBuffer(data.buffer); buffers.delete(attribute); } } - function update(attribute, bufferType) { if (attribute.isGLBufferAttribute) { const cached = buffers.get(attribute); - if (!cached || cached.version < attribute.version) { buffers.set(attribute, { buffer: attribute.buffer, @@ -9660,13 +8364,10 @@ version: attribute.version }); } - return; } - if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; const data = buffers.get(attribute); - if (data === undefined) { buffers.set(attribute, createBuffer(attribute, bufferType)); } else if (data.version < attribute.version) { @@ -9674,7 +8375,6 @@ data.version = attribute.version; } } - return { get: get, remove: remove, @@ -9699,16 +8399,16 @@ const gridX1 = gridX + 1; const gridY1 = gridY + 1; const segment_width = width / gridX; - const segment_height = height / gridY; // + const segment_height = height / gridY; + + // const indices = []; const vertices = []; const normals = []; const uvs = []; - for (let iy = 0; iy < gridY1; iy++) { const y = iy * segment_height - height_half; - for (let ix = 0; ix < gridX1; ix++) { const x = ix * segment_width - width_half; vertices.push(x, -y, 0); @@ -9717,7 +8417,6 @@ uvs.push(1 - iy / gridY); } } - for (let iy = 0; iy < gridY; iy++) { for (let ix = 0; ix < gridX; ix++) { const a = ix + gridX1 * iy; @@ -9728,17 +8427,14 @@ indices.push(b, c, d); } } - this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); } - static fromJSON(data) { return new PlaneGeometry(data.width, data.height, data.widthSegments, data.heightSegments); } - } var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif"; @@ -9781,7 +8477,7 @@ 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; }\nvec3 pow2( const in vec3 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 max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\nfloat average( const in vec3 v ) { return dot( v, vec3( 0.3333333 ) ); }\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 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 USE_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}\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 luminance( const in vec3 rgb ) {\n\tconst vec3 weights = vec3( 0.2126729, 0.7151522, 0.0721750 );\n\treturn dot( weights, 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}"; - var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_minMipLevel 4.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\tvec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\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\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\n\t\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n\t\tuv.x *= CUBEUV_TEXEL_WIDTH;\n\t\tuv.y *= CUBEUV_TEXEL_HEIGHT;\n\t\t#ifdef texture2DGradEXT\n\t\t\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n\t\t#else\n\t\t\treturn texture2D( envMap, uv ).rgb;\n\t\t#endif\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_MAX_MIP );\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 cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_minMipLevel 4.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\tvec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\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\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\n\t\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n\t\tuv.x *= CUBEUV_TEXEL_WIDTH;\n\t\tuv.y *= CUBEUV_TEXEL_HEIGHT;\n\t\t#ifdef texture2DGradEXT\n\t\t\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n\t\t#else\n\t\t\treturn texture2D( envMap, uv ).rgb;\n\t\t#endif\n\t}\n\t#define cubeUV_r0 1.0\n\t#define cubeUV_v0 0.339\n\t#define cubeUV_m0 - 2.0\n\t#define cubeUV_r1 0.8\n\t#define cubeUV_v1 0.276\n\t#define cubeUV_m1 - 1.0\n\t#define cubeUV_r4 0.4\n\t#define cubeUV_v4 0.046\n\t#define cubeUV_m4 2.0\n\t#define cubeUV_r5 0.305\n\t#define cubeUV_v5 0.016\n\t#define cubeUV_m5 3.0\n\t#define cubeUV_r6 0.21\n\t#define cubeUV_v6 0.0038\n\t#define cubeUV_m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= cubeUV_r1 ) {\n\t\t\tmip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0;\n\t\t} else if ( roughness >= cubeUV_r4 ) {\n\t\t\tmip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1;\n\t\t} else if ( roughness >= cubeUV_r5 ) {\n\t\t\tmip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4;\n\t\t} else if ( roughness >= cubeUV_r6 ) {\n\t\t\tmip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_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 ), cubeUV_m0, CUBEUV_MAX_MIP );\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"; @@ -9797,13 +8493,13 @@ var encodings_pars_fragment = "vec4 LinearToLinear( in vec4 value ) {\n\treturn value;\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}"; - 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#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_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#else\n\t\tvec4 envColor = vec4( 0.0 );\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\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"; - 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"; + var envmap_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\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"; - 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"; + var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\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"; 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"; @@ -9815,13 +8511,15 @@ var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float vFogDepth;\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"; - 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 vec3( texture2D( gradientMap, coord ).r );\n\t#else\n\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t#endif\n}"; + 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 vec3( texture2D( gradientMap, coord ).r );\n\t#else\n\t\tvec2 fw = fwidth( coord ) * 0.5;\n\t\treturn mix( vec3( 0.7 ), vec3( 1.0 ), smoothstep( 0.7 - fw.x, 0.7 + fw.x, coord.x ) );\n\t#endif\n}"; var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\treflectedLight.indirectDiffuse += lightMapIrradiance;\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.normal );\n#ifdef DOUBLE_SIDED\n\tvIndirectBack += getAmbientLightIrradiance( ambientLightColor );\n\tvIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry.normal );\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\tgetPointLightInfo( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = 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\tgetSpotLightInfo( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = 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\tgetDirectionalLightInfo( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = 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.normal );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry.normal );\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif"; + var lights_lambert_fragment = "LambertMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularStrength = specularStrength;"; + + var lights_lambert_pars_fragment = "varying vec3 vViewPosition;\nstruct LambertMaterial {\n\tvec3 diffuseColor;\n\tfloat specularStrength;\n};\nvoid RE_Direct_Lambert( const in IncidentLight directLight, const in GeometricContext geometry, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in GeometricContext geometry, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Lambert\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Lambert"; 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 vec3 normal ) {\n\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\treturn irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\t#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\tif ( cutoffDistance > 0.0 ) {\n\t\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\t}\n\t\treturn distanceFalloff;\n\t#else\n\t\tif ( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\t\treturn pow( saturate( - lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t\t}\n\t\treturn 1.0;\n\t#endif\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n\treturn smoothstep( coneCosine, penumbraCosine, angleCosine );\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 getDirectionalLightInfo( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tlight.color = directionalLight.color;\n\t\tlight.direction = directionalLight.direction;\n\t\tlight.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 getPointLightInfo( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tlight.color = pointLight.color;\n\t\tlight.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n\t\tlight.visible = ( light.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 getSpotLightInfo( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat angleCos = dot( light.direction, spotLight.direction );\n\t\tfloat spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\tif ( spotAttenuation > 0.0 ) {\n\t\t\tfloat lightDistance = length( lVector );\n\t\t\tlight.color = spotLight.color * spotAttenuation;\n\t\t\tlight.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t\t} else {\n\t\t\tlight.color = vec3( 0.0 );\n\t\t\tlight.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 vec3 normal ) {\n\t\tfloat dotNL = dot( normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\treturn irradiance;\n\t}\n#endif"; @@ -9829,17 +8527,17 @@ var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;"; - var lights_toon_pars_fragment = "varying vec3 vViewPosition;\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\treflectedLight.directDiffuse += irradiance * BRDF_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_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)"; + var lights_toon_pars_fragment = "varying vec3 vViewPosition;\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\treflectedLight.directDiffuse += irradiance * BRDF_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_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon"; 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;\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\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, 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_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)"; + var lights_phong_pars_fragment = "varying vec3 vViewPosition;\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\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, 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_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong"; - 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.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\t#ifdef SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULARINTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vUv ).a;\n\t\t#endif\n\t\t#ifdef USE_SPECULARCOLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vUv ).rgb;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( ior - 1.0 ) / ( ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\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_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vUv ).a;\n\t#endif\n#endif"; + 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.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\tmaterial.ior = ior;\n\t#ifdef SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULARINTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vUv ).a;\n\t\t#endif\n\t\t#ifdef USE_SPECULARCOLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vUv ).rgb;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\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_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vUv ).a;\n\t#endif\n#endif"; - var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat roughness;\n\tvec3 specularColor;\n\tfloat specularF90;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\tfloat iridescence;\n\t\tfloat iridescenceIOR;\n\t\tfloat iridescenceThickness;\n\t\tvec3 iridescenceFresnel;\n\t\tvec3 iridescenceF0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n};\nvec3 clearcoatSpecular = vec3( 0.0 );\nvec3 sheenSpecular = vec3( 0.0 );\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\n\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\n\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\n\treturn saturate( DG * RECIPROCAL_PI );\n}\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\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\tvec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\n\treturn fab;\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\treturn specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#endif\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\t#ifdef USE_IRIDESCENCE\n\t\tvec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n\t#else\n\t\tvec3 Fr = specularColor;\n\t#endif\n\tvec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\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.roughness;\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#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecular += ccIrradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.clearcoatNormal, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness );\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\treflectedLight.directSpecular += irradiance * BRDF_GGX_Iridescence( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness );\n\t#else\n\t\treflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.roughness );\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_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_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 USE_CLEARCOAT\n\t\tclearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometry.clearcoatNormal, geometry.viewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometry.normal, geometry.viewDir, material.sheenRoughness );\n\t#endif\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t#ifdef USE_IRIDESCENCE\n\t\tcomputeMultiscatteringIridescence( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );\n\t#else\n\t\tcomputeMultiscattering( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n\t#endif\n\tvec3 totalScattering = singleScattering + multiScattering;\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) );\n\treflectedLight.indirectSpecular += 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}"; + var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat roughness;\n\tvec3 specularColor;\n\tfloat specularF90;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\tfloat iridescence;\n\t\tfloat iridescenceIOR;\n\t\tfloat iridescenceThickness;\n\t\tvec3 iridescenceFresnel;\n\t\tvec3 iridescenceF0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n\t#ifdef IOR\n\t\tfloat ior;\n\t#endif\n\t#ifdef USE_TRANSMISSION\n\t\tfloat transmission;\n\t\tfloat transmissionAlpha;\n\t\tfloat thickness;\n\t\tfloat attenuationDistance;\n\t\tvec3 attenuationColor;\n\t#endif\n};\nvec3 clearcoatSpecular = vec3( 0.0 );\nvec3 sheenSpecular = vec3( 0.0 );\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\n\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\n\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\n\treturn saturate( DG * RECIPROCAL_PI );\n}\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\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\tvec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\n\treturn fab;\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\treturn specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#endif\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\t#ifdef USE_IRIDESCENCE\n\t\tvec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n\t#else\n\t\tvec3 Fr = specularColor;\n\t#endif\n\tvec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\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.roughness;\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#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecular += ccIrradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.clearcoatNormal, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness );\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\treflectedLight.directSpecular += irradiance * BRDF_GGX_Iridescence( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness );\n\t#else\n\t\treflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.roughness );\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_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_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 USE_CLEARCOAT\n\t\tclearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometry.clearcoatNormal, geometry.viewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometry.normal, geometry.viewDir, material.sheenRoughness );\n\t#endif\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t#ifdef USE_IRIDESCENCE\n\t\tcomputeMultiscatteringIridescence( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );\n\t#else\n\t\tcomputeMultiscattering( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n\t#endif\n\tvec3 totalScattering = singleScattering + multiScattering;\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) );\n\treflectedLight.indirectSpecular += 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}"; - var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef USE_CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n\tfloat dotNVi = saturate( dot( normal, geometry.viewDir ) );\n\tif ( material.iridescenceThickness == 0.0 ) {\n\t\tmaterial.iridescence = 0.0;\n\t} else {\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\t}\n\tif ( material.iridescence > 0.0 ) {\n\t\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\t}\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\tgetPointLightInfo( 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\tgetSpotLightInfo( 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\tgetDirectionalLightInfo( 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.normal );\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.normal );\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 lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef USE_CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n\tfloat dotNVi = saturate( dot( normal, geometry.viewDir ) );\n\tif ( material.iridescenceThickness == 0.0 ) {\n\t\tmaterial.iridescence = 0.0;\n\t} else {\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\t}\n\tif ( material.iridescence > 0.0 ) {\n\t\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\t}\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\tgetPointLightInfo( 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\tvec4 spotColor;\n\tvec3 spotLightCoord;\n\tbool inSpotLightMap;\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\tgetSpotLightInfo( spotLight, geometry, directLight );\n\t\t#if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n\t\t#elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t#define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n\t\t#else\n\t\t#define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#endif\n\t\t#if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n\t\t\tspotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n\t\t\tinSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n\t\t\tspotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n\t\t\tdirectLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n\t\t#endif\n\t\t#undef SPOT_LIGHT_MAP_INDEX\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, vSpotLightCoord[ 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\tgetDirectionalLightInfo( 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.normal );\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.normal );\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 lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\t\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getIBLIrradiance( geometry.normal );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getIBLRadiance( geometry.viewDir, geometry.normal, material.roughness );\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatRadiance += getIBLRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness );\n\t#endif\n#endif"; @@ -9873,7 +8571,7 @@ var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\t#ifdef MORPHTARGETS_TEXTURE\n\t\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ];\n\t\t}\n\t#else\n\t\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\n\t\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\n\t\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\n\t\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\n\t\t#ifndef USE_MORPHNORMALS\n\t\t\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\n\t\t\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\n\t\t\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\n\t\t\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\n\t\t#endif\n\t#endif\n#endif"; - var normal_fragment_begin = "float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#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 * faceDirection;\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 * faceDirection;\n\t\t\tbitangent = bitangent * faceDirection;\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_begin = "float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#ifdef FLAT_SHADED\n\tvec3 fdx = dFdx( vViewPosition );\n\tvec3 fdy = dFdy( vViewPosition );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * faceDirection;\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 * faceDirection;\n\t\t\tbitangent = bitangent * faceDirection;\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 * faceDirection;\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, faceDirection );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\n#endif"; @@ -9893,9 +8591,9 @@ var iridescence_pars_fragment = "#ifdef USE_IRIDESCENCEMAP\n\tuniform sampler2D iridescenceMap;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform sampler2D iridescenceThicknessMap;\n#endif"; - var output_fragment = "#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= transmissionAlpha + 0.1;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );"; + var output_fragment = "#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= material.transmissionAlpha + 0.1;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.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 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}\nvec2 packDepthToRG( in highp float v ) {\n\treturn packDepthToRGBA( v ).yx;\n}\nfloat unpackRGToDepth( const in highp vec2 v ) {\n\treturn unpackRGBAToDepth( vec4( v.xy, 0.0, 0.0 ) );\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"; @@ -9909,13 +8607,13 @@ var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; - 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"; + var shadowmap_pars_fragment = "#if NUM_SPOT_LIGHT_COORDS > 0\n varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#if NUM_SPOT_LIGHT_MAPS > 0\n uniform sampler2D spotLightMap[ NUM_SPOT_LIGHT_MAPS ];\n#endif\n#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\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"; - 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"; + var shadowmap_pars_vertex = "#if NUM_SPOT_LIGHT_COORDS > 0\n uniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#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\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"; - 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 shadowmap_vertex = "#if defined( USE_SHADOWMAP ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n\t#if NUM_DIR_LIGHT_SHADOWS > 0 || NUM_SPOT_LIGHT_COORDS > 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_COORDS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition;\n\t\t#if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\tshadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias;\n\t\t#endif\n\t\tvSpotLightCoord[ i ] = spotLightMatrix[ 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}"; + 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, vSpotLightCoord[ 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}"; 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"; @@ -9933,9 +8631,9 @@ 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; }"; - var transmission_fragment = "#ifdef USE_TRANSMISSION\n\tfloat transmissionAlpha = 1.0;\n\tfloat transmissionFactor = transmission;\n\tfloat thicknessFactor = thickness;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\ttransmissionFactor *= texture2D( transmissionMap, vUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tthicknessFactor *= texture2D( thicknessMap, vUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmission = getIBLVolumeRefraction(\n\t\tn, v, roughnessFactor, material.diffuseColor, material.specularColor, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, ior, thicknessFactor,\n\t\tattenuationColor, attenuationDistance );\n\ttotalDiffuse = mix( totalDiffuse, transmission.rgb, transmissionFactor );\n\ttransmissionAlpha = mix( transmissionAlpha, transmission.a, transmissionFactor );\n#endif"; + var transmission_fragment = "#ifdef USE_TRANSMISSION\n\tmaterial.transmission = transmission;\n\tmaterial.transmissionAlpha = 1.0;\n\tmaterial.thickness = thickness;\n\tmaterial.attenuationDistance = attenuationDistance;\n\tmaterial.attenuationColor = attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tmaterial.transmission *= texture2D( transmissionMap, vUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tmaterial.thickness *= texture2D( thicknessMap, vUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmission = getIBLVolumeRefraction(\n\t\tn, v, material.roughness, material.diffuseColor, material.specularColor, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, material.ior, material.thickness,\n\t\tmaterial.attenuationColor, material.attenuationDistance );\n\tmaterial.transmissionAlpha = mix( material.transmissionAlpha, transmission.a, material.transmission );\n\ttotalDiffuse = mix( totalDiffuse, transmission.rgb, material.transmission );\n#endif"; - var transmission_pars_fragment = "#ifdef USE_TRANSMISSION\n\tuniform float transmission;\n\tuniform float thickness;\n\tuniform float attenuationDistance;\n\tuniform vec3 attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tuniform sampler2D transmissionMap;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tuniform sampler2D thicknessMap;\n\t#endif\n\tuniform vec2 transmissionSamplerSize;\n\tuniform sampler2D transmissionSamplerMap;\n\tuniform mat4 modelMatrix;\n\tuniform mat4 projectionMatrix;\n\tvarying vec3 vWorldPosition;\n\tvec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\n\t\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n\t\tvec3 modelScale;\n\t\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\treturn normalize( refractionVector ) * thickness * modelScale;\n\t}\n\tfloat applyIorToRoughness( const in float roughness, const in float ior ) {\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t}\n\tvec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\n\t\tfloat framebufferLod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n\t\t#ifdef texture2DLodEXT\n\t\t\treturn texture2DLodEXT( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#else\n\t\t\treturn texture2D( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#endif\n\t}\n\tvec3 applyVolumeAttenuation( const in vec3 radiance, const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tif ( attenuationDistance == 0.0 ) {\n\t\t\treturn radiance;\n\t\t} else {\n\t\t\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n\t\t\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\t\t\treturn transmittance * radiance;\n\t\t}\n\t}\n\tvec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\n\t\tconst in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\n\t\tconst in mat4 viewMatrix, const in mat4 projMatrix, const in float ior, const in float thickness,\n\t\tconst in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\trefractionCoords += 1.0;\n\t\trefractionCoords /= 2.0;\n\t\tvec4 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n\t\tvec3 attenuatedColor = applyVolumeAttenuation( transmittedLight.rgb, length( transmissionRay ), attenuationColor, attenuationDistance );\n\t\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n\t\treturn vec4( ( 1.0 - F ) * attenuatedColor * diffuseColor, transmittedLight.a );\n\t}\n#endif"; + var transmission_pars_fragment = "#ifdef USE_TRANSMISSION\n\tuniform float transmission;\n\tuniform float thickness;\n\tuniform float attenuationDistance;\n\tuniform vec3 attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tuniform sampler2D transmissionMap;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tuniform sampler2D thicknessMap;\n\t#endif\n\tuniform vec2 transmissionSamplerSize;\n\tuniform sampler2D transmissionSamplerMap;\n\tuniform mat4 modelMatrix;\n\tuniform mat4 projectionMatrix;\n\tvarying vec3 vWorldPosition;\n\tvec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\n\t\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n\t\tvec3 modelScale;\n\t\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\treturn normalize( refractionVector ) * thickness * modelScale;\n\t}\n\tfloat applyIorToRoughness( const in float roughness, const in float ior ) {\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t}\n\tvec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\n\t\tfloat framebufferLod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n\t\t#ifdef texture2DLodEXT\n\t\t\treturn texture2DLodEXT( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#else\n\t\t\treturn texture2D( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#endif\n\t}\n\tvec3 applyVolumeAttenuation( const in vec3 radiance, const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tif ( isinf( attenuationDistance ) ) {\n\t\t\treturn radiance;\n\t\t} else {\n\t\t\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n\t\t\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\t\t\treturn transmittance * radiance;\n\t\t}\n\t}\n\tvec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\n\t\tconst in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\n\t\tconst in mat4 viewMatrix, const in mat4 projMatrix, const in float ior, const in float thickness,\n\t\tconst in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\trefractionCoords += 1.0;\n\t\trefractionCoords /= 2.0;\n\t\tvec4 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n\t\tvec3 attenuatedColor = applyVolumeAttenuation( transmittedLight.rgb, length( transmissionRay ), attenuationColor, attenuationDistance );\n\t\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n\t\treturn vec4( ( 1.0 - F ) * attenuatedColor * diffuseColor, transmittedLight.a );\n\t}\n#endif"; var uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif"; @@ -9949,13 +8647,16 @@ var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif"; - var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION )\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 worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) || NUM_SPOT_LIGHT_COORDS > 0\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"; - const vertex$g = "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}"; - const fragment$g = "uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tgl_FragColor = texture2D( t2D, vUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\tgl_FragColor = vec4( mix( pow( gl_FragColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), gl_FragColor.rgb * 0.0773993808, vec3( lessThanEqual( gl_FragColor.rgb, vec3( 0.04045 ) ) ) ), gl_FragColor.w );\n\t#endif\n\t#include \n\t#include \n}"; + const vertex$h = "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}"; + const fragment$h = "uniform sampler2D t2D;\nuniform float backgroundIntensity;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\ttexColor = vec4( mix( pow( texColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), texColor.rgb * 0.0773993808, vec3( lessThanEqual( texColor.rgb, vec3( 0.04045 ) ) ) ), texColor.w );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include \n\t#include \n}"; + + const vertex$g = "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}"; + const fragment$g = "#ifdef ENVMAP_TYPE_CUBE\n\tuniform samplerCube envMap;\n#elif defined( ENVMAP_TYPE_CUBE_UV )\n\tuniform sampler2D envMap;\n#endif\nuniform float flipEnvMap;\nuniform float backgroundBlurriness;\nuniform float backgroundIntensity;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 texColor = textureCube( envMap, vec3( flipEnvMap * vWorldDirection.x, vWorldDirection.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 texColor = textureCubeUV( envMap, vWorldDirection, backgroundBlurriness );\n\t#else\n\t\tvec4 texColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include \n\t#include \n}"; const vertex$f = "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}"; - const fragment$f = "#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}"; + const fragment$f = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = texColor;\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}"; const vertex$e = "#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}"; const fragment$e = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \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}"; @@ -9970,10 +8671,10 @@ const fragment$b = "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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; const vertex$a = "#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#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\t\t#include \n\t\t#include \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\t#include \n\t#include \n}"; - const fragment$a = "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 \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\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + const fragment$a = "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\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - const vertex$9 = "#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\t#include \n}"; - const fragment$9 = "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 \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_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_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + const vertex$9 = "#define LAMBERT\nvarying vec3 vViewPosition;\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\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}"; + const fragment$9 = "#define LAMBERT\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 \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 + totalEmissiveRadiance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; const vertex$8 = "#define MATCAP\nvarying vec3 vViewPosition;\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\tvViewPosition = - mvPosition.xyz;\n}"; const fragment$8 = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\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\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#else\n\t\tvec4 matcapColor = vec4( vec3( mix( 0.2, 0.8, uv.y ) ), 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; @@ -9982,7 +8683,7 @@ const fragment$7 = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\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\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n\t#ifdef OPAQUE\n\t\tgl_FragColor.a = 1.0;\n\t#endif\n}"; const vertex$6 = "#define PHONG\nvarying vec3 vViewPosition;\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\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}"; - const fragment$6 = "#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 \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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + const fragment$6 = "#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 \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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; const vertex$5 = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n\tvarying vec3 vWorldPosition;\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\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\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n#ifdef USE_TRANSMISSION\n\tvWorldPosition = worldPosition.xyz;\n#endif\n}"; const fragment$5 = "#define STANDARD\n#ifdef PHYSICAL\n\t#define IOR\n\t#define SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n\tuniform float ior;\n#endif\n#ifdef SPECULAR\n\tuniform float specularIntensity;\n\tuniform vec3 specularColor;\n\t#ifdef USE_SPECULARINTENSITYMAP\n\t\tuniform sampler2D specularIntensityMap;\n\t#endif\n\t#ifdef USE_SPECULARCOLORMAP\n\t\tuniform sampler2D specularColorMap;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_IRIDESCENCE\n\tuniform float iridescence;\n\tuniform float iridescenceIOR;\n\tuniform float iridescenceThicknessMinimum;\n\tuniform float iridescenceThicknessMaximum;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheenColor;\n\tuniform float sheenRoughness;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tuniform sampler2D sheenColorMap;\n\t#endif\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tuniform sampler2D sheenRoughnessMap;\n\t#endif\n#endif\nvarying vec3 vViewPosition;\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 \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\t#include \n\t#include \n\t#include \n\tvec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n\tvec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n\t#include \n\tvec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n\t#ifdef USE_SHEEN\n\t\tfloat sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor );\n\t\toutgoingLight = outgoingLight * sheenEnergyComp + sheenSpecular;\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNVcc = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\tvec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n\t\toutgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + clearcoatSpecular * material.clearcoat;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; @@ -10041,7 +8742,8 @@ gradientmap_pars_fragment: gradientmap_pars_fragment, lightmap_fragment: lightmap_fragment, lightmap_pars_fragment: lightmap_pars_fragment, - lights_lambert_vertex: lights_lambert_vertex, + lights_lambert_fragment: lights_lambert_fragment, + lights_lambert_pars_fragment: lights_lambert_pars_fragment, lights_pars_begin: lights_pars_begin, lights_toon_fragment: lights_toon_fragment, lights_toon_pars_fragment: lights_toon_pars_fragment, @@ -10105,8 +8807,10 @@ uv2_pars_vertex: uv2_pars_vertex, uv2_vertex: uv2_vertex, worldpos_vertex: worldpos_vertex, - background_vert: vertex$g, - background_frag: fragment$g, + background_vert: vertex$h, + background_frag: fragment$h, + backgroundCube_vert: vertex$g, + backgroundCube_frag: fragment$g, cube_vert: vertex$f, cube_frag: fragment$f, depth_vert: vertex$e, @@ -10190,8 +8894,8 @@ refractionRatio: { value: 0.98 } // basic, lambert, phong - }, + aomap: { aoMap: { value: null @@ -10319,10 +9023,13 @@ shadowMapSize: {} } }, + spotLightMap: { + value: [] + }, spotShadowMap: { value: [] }, - spotShadowMatrix: { + spotLightMatrix: { value: [] }, pointLights: { @@ -10437,7 +9144,7 @@ fragmentShader: ShaderChunk.meshbasic_frag }, lambert: { - uniforms: /*@__PURE__*/mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.fog, UniformsLib.lights, { + uniforms: /*@__PURE__*/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: /*@__PURE__*/new Color(0x000000) } @@ -10474,8 +9181,8 @@ envMapIntensity: { value: 1 } // temporary - }]), + vertexShader: ShaderChunk.meshphysical_vert, fragmentShader: ShaderChunk.meshphysical_frag }, @@ -10543,17 +9250,44 @@ }, t2D: { value: null + }, + backgroundIntensity: { + value: 1 } }, vertexShader: ShaderChunk.background_vert, fragmentShader: ShaderChunk.background_frag }, + backgroundCube: { + uniforms: { + envMap: { + value: null + }, + flipEnvMap: { + value: -1 + }, + backgroundBlurriness: { + value: 0 + }, + backgroundIntensity: { + value: 1 + } + }, + vertexShader: ShaderChunk.backgroundCube_vert, + fragmentShader: ShaderChunk.backgroundCube_frag + }, cube: { - uniforms: /*@__PURE__*/mergeUniforms([UniformsLib.envmap, { + uniforms: { + tCube: { + value: null + }, + tFlip: { + value: -1 + }, opacity: { value: 1.0 } - }]), + }, vertexShader: ShaderChunk.cube_vert, fragmentShader: ShaderChunk.cube_frag }, @@ -10688,7 +9422,12 @@ fragmentShader: ShaderChunk.meshphysical_frag }; - function WebGLBackground(renderer, cubemaps, state, objects, alpha, premultipliedAlpha) { + const _rgb = { + r: 0, + b: 0, + g: 0 + }; + function WebGLBackground(renderer, cubemaps, cubeuvmaps, state, objects, alpha, premultipliedAlpha) { const clearColor = new Color(0x000000); let clearAlpha = alpha === true ? 0 : 1; let planeMesh; @@ -10696,42 +9435,38 @@ let currentBackground = null; let currentBackgroundVersion = 0; let currentTonemapping = null; - function render(renderList, scene) { let forceClear = false; let background = scene.isScene === true ? scene.background : null; - if (background && background.isTexture) { - background = cubemaps.get(background); - } // Ignore background in AR - // TODO: Reconsider this. + const usePMREM = scene.backgroundBlurriness > 0; // use PMREM if the user wants to blur the background + background = (usePMREM ? cubeuvmaps : cubemaps).get(background); + } + // Ignore background in AR + // TODO: Reconsider this. const xr = renderer.xr; const session = xr.getSession && xr.getSession(); - if (session && session.environmentBlendMode === 'additive') { background = null; } - if (background === null) { setClear(clearColor, clearAlpha); } else if (background && background.isColor) { setClear(background, 1); forceClear = true; } - if (renderer.autoClear || forceClear) { renderer.clear(renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil); } - if (background && (background.isCubeTexture || background.mapping === CubeUVReflectionMapping)) { if (boxMesh === undefined) { boxMesh = new Mesh(new BoxGeometry(1, 1, 1), new ShaderMaterial({ name: 'BackgroundCubeMaterial', - uniforms: cloneUniforms(ShaderLib.cube.uniforms), - vertexShader: ShaderLib.cube.vertexShader, - fragmentShader: ShaderLib.cube.fragmentShader, + uniforms: cloneUniforms(ShaderLib.backgroundCube.uniforms), + vertexShader: ShaderLib.backgroundCube.vertexShader, + fragmentShader: ShaderLib.backgroundCube.fragmentShader, side: BackSide, depthTest: false, depthWrite: false, @@ -10739,12 +9474,11 @@ })); boxMesh.geometry.deleteAttribute('normal'); boxMesh.geometry.deleteAttribute('uv'); - boxMesh.onBeforeRender = function (renderer, scene, camera) { this.matrixWorld.copyPosition(camera.matrixWorld); - }; // enable code injection for non-built-in material - + }; + // add "envMap" material property so the renderer can evaluate it like for built-in materials Object.defineProperty(boxMesh.material, 'envMap', { get: function () { return this.uniforms.envMap.value; @@ -10752,19 +9486,19 @@ }); objects.update(boxMesh); } - boxMesh.material.uniforms.envMap.value = background; boxMesh.material.uniforms.flipEnvMap.value = background.isCubeTexture && background.isRenderTargetTexture === false ? -1 : 1; - + boxMesh.material.uniforms.backgroundBlurriness.value = scene.backgroundBlurriness; + boxMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity; if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) { boxMesh.material.needsUpdate = true; currentBackground = background; currentBackgroundVersion = background.version; currentTonemapping = renderer.toneMapping; } + boxMesh.layers.enableAll(); - boxMesh.layers.enableAll(); // push to the pre-sorted opaque render list - + // 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) { @@ -10778,8 +9512,9 @@ depthWrite: false, fog: false })); - planeMesh.geometry.deleteAttribute('normal'); // enable code injection for non-built-in material + planeMesh.geometry.deleteAttribute('normal'); + // add "map" material property so the renderer can evaluate it like for built-in materials Object.defineProperty(planeMesh.material, 'map', { get: function () { return this.uniforms.t2D.value; @@ -10787,32 +9522,28 @@ }); objects.update(planeMesh); } - planeMesh.material.uniforms.t2D.value = background; - + planeMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity; if (background.matrixAutoUpdate === true) { background.updateMatrix(); } - planeMesh.material.uniforms.uvTransform.value.copy(background.matrix); - if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) { planeMesh.material.needsUpdate = true; currentBackground = background; currentBackgroundVersion = background.version; currentTonemapping = renderer.toneMapping; } + planeMesh.layers.enableAll(); - planeMesh.layers.enableAll(); // push to the pre-sorted opaque render list - + // push to the pre-sorted opaque render list 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); + color.getRGB(_rgb, getUnlitUniformColorSpace(renderer)); + state.buffers.color.setClear(_rgb.r, _rgb.g, _rgb.b, alpha, premultipliedAlpha); } - return { getClearColor: function () { return clearColor; @@ -10841,23 +9572,18 @@ const defaultState = createBindingState(null); let currentState = defaultState; let forceUpdate = false; - function setup(object, material, program, geometry, index) { let updateBuffers = false; - if (vaoAvailable) { const state = getBindingState(geometry, program, material); - if (currentState !== state) { currentState = state; bindVertexArrayObject(currentState.object); } - updateBuffers = needsUpdate(object, geometry, program, index); if (updateBuffers) saveCache(object, geometry, program, index); } else { const wireframe = material.wireframe === true; - if (currentState.geometry !== geometry.id || currentState.program !== program.id || currentState.wireframe !== wireframe) { currentState.geometry = geometry.id; currentState.program = program.id; @@ -10865,73 +9591,57 @@ updateBuffers = true; } } - if (index !== null) { attributes.update(index, gl.ELEMENT_ARRAY_BUFFER); } - if (updateBuffers || forceUpdate) { forceUpdate = false; setupVertexAttributes(object, material, program, geometry); - if (index !== null) { gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, attributes.get(index).buffer); } } } - 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); } - function deleteVertexArrayObject(vao) { if (capabilities.isWebGL2) return gl.deleteVertexArray(vao); return extension.deleteVertexArrayOES(vao); } - function getBindingState(geometry, program, material) { const wireframe = material.wireframe === true; let programMap = bindingStates[geometry.id]; - if (programMap === undefined) { programMap = {}; bindingStates[geometry.id] = programMap; } - let stateMap = programMap[program.id]; - if (stateMap === undefined) { stateMap = {}; programMap[program.id] = stateMap; } - let state = stateMap[wireframe]; - if (state === undefined) { state = createBindingState(createVertexArrayObject()); stateMap[wireframe] = state; } - return state; } - function createBindingState(vao) { const newAttributes = []; const enabledAttributes = []; const attributeDivisors = []; - for (let i = 0; i < maxVertexAttributes; i++) { newAttributes[i] = 0; enabledAttributes[i] = 0; attributeDivisors[i] = 0; } - return { // for backward compatibility on non-VAO support browser geometry: null, @@ -10945,105 +9655,83 @@ index: null }; } - function needsUpdate(object, geometry, program, index) { const cachedAttributes = currentState.attributes; const geometryAttributes = geometry.attributes; let attributesNum = 0; const programAttributes = program.getAttributes(); - for (const name in programAttributes) { const programAttribute = programAttributes[name]; - if (programAttribute.location >= 0) { const cachedAttribute = cachedAttributes[name]; let geometryAttribute = geometryAttributes[name]; - if (geometryAttribute === undefined) { if (name === 'instanceMatrix' && object.instanceMatrix) geometryAttribute = object.instanceMatrix; if (name === 'instanceColor' && object.instanceColor) geometryAttribute = object.instanceColor; } - if (cachedAttribute === undefined) return true; if (cachedAttribute.attribute !== geometryAttribute) return true; if (geometryAttribute && cachedAttribute.data !== geometryAttribute.data) return true; attributesNum++; } } - if (currentState.attributesNum !== attributesNum) return true; if (currentState.index !== index) return true; return false; } - function saveCache(object, geometry, program, index) { const cache = {}; const attributes = geometry.attributes; let attributesNum = 0; const programAttributes = program.getAttributes(); - for (const name in programAttributes) { const programAttribute = programAttributes[name]; - if (programAttribute.location >= 0) { let attribute = attributes[name]; - if (attribute === undefined) { if (name === 'instanceMatrix' && object.instanceMatrix) attribute = object.instanceMatrix; if (name === 'instanceColor' && object.instanceColor) attribute = object.instanceColor; } - const data = {}; data.attribute = attribute; - if (attribute && attribute.data) { data.data = attribute.data; } - cache[name] = data; attributesNum++; } } - currentState.attributes = cache; currentState.attributesNum = attributesNum; currentState.index = index; } - function initAttributes() { const newAttributes = currentState.newAttributes; - for (let i = 0, il = newAttributes.length; i < il; i++) { newAttributes[i] = 0; } } - function enableAttribute(attribute) { enableAttributeAndDivisor(attribute, 0); } - function enableAttributeAndDivisor(attribute, meshPerAttribute) { const newAttributes = currentState.newAttributes; const enabledAttributes = currentState.enabledAttributes; const attributeDivisors = currentState.attributeDivisors; newAttributes[attribute] = 1; - if (enabledAttributes[attribute] === 0) { gl.enableVertexAttribArray(attribute); enabledAttributes[attribute] = 1; } - if (attributeDivisors[attribute] !== meshPerAttribute) { const extension = capabilities.isWebGL2 ? gl : extensions.get('ANGLE_instanced_arrays'); extension[capabilities.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE'](attribute, meshPerAttribute); attributeDivisors[attribute] = meshPerAttribute; } } - function disableUnusedAttributes() { const newAttributes = currentState.newAttributes; const enabledAttributes = currentState.enabledAttributes; - for (let i = 0, il = enabledAttributes.length; i < il; i++) { if (enabledAttributes[i] !== newAttributes[i]) { gl.disableVertexAttribArray(i); @@ -11051,7 +9739,6 @@ } } } - function vertexAttribPointer(index, size, type, normalized, stride, offset) { if (capabilities.isWebGL2 === true && (type === gl.INT || type === gl.UNSIGNED_INT)) { gl.vertexAttribIPointer(index, size, type, stride, offset); @@ -11059,48 +9746,41 @@ gl.vertexAttribPointer(index, size, type, normalized, stride, offset); } } - function setupVertexAttributes(object, material, program, geometry) { if (capabilities.isWebGL2 === false && (object.isInstancedMesh || geometry.isInstancedBufferGeometry)) { if (extensions.get('ANGLE_instanced_arrays') === null) return; } - initAttributes(); const geometryAttributes = geometry.attributes; const programAttributes = program.getAttributes(); const materialDefaultAttributeValues = material.defaultAttributeValues; - for (const name in programAttributes) { const programAttribute = programAttributes[name]; - if (programAttribute.location >= 0) { let geometryAttribute = geometryAttributes[name]; - if (geometryAttribute === undefined) { if (name === 'instanceMatrix' && object.instanceMatrix) geometryAttribute = object.instanceMatrix; if (name === 'instanceColor' && object.instanceColor) geometryAttribute = object.instanceColor; } - if (geometryAttribute !== undefined) { const normalized = geometryAttribute.normalized; const size = geometryAttribute.itemSize; - const attribute = attributes.get(geometryAttribute); // TODO Attribute may not be available on context restore + const attribute = attributes.get(geometryAttribute); + + // TODO Attribute may not be available on context restore if (attribute === undefined) continue; const buffer = attribute.buffer; const type = attribute.type; const bytesPerElement = attribute.bytesPerElement; - if (geometryAttribute.isInterleavedBufferAttribute) { const data = geometryAttribute.data; const stride = data.stride; const offset = geometryAttribute.offset; - if (data.isInstancedInterleavedBuffer) { for (let i = 0; i < programAttribute.locationSize; i++) { enableAttributeAndDivisor(programAttribute.location + i, data.meshPerAttribute); } - if (object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined) { geometry._maxInstanceCount = data.meshPerAttribute * data.count; } @@ -11109,9 +9789,7 @@ enableAttribute(programAttribute.location + i); } } - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - for (let i = 0; i < programAttribute.locationSize; i++) { vertexAttribPointer(programAttribute.location + i, size / programAttribute.locationSize, type, normalized, stride * bytesPerElement, (offset + size / programAttribute.locationSize * i) * bytesPerElement); } @@ -11120,7 +9798,6 @@ for (let i = 0; i < programAttribute.locationSize; i++) { enableAttributeAndDivisor(programAttribute.location + i, geometryAttribute.meshPerAttribute); } - if (object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined) { geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count; } @@ -11129,30 +9806,24 @@ enableAttribute(programAttribute.location + i); } } - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - for (let i = 0; i < programAttribute.locationSize; i++) { vertexAttribPointer(programAttribute.location + i, size / programAttribute.locationSize, type, normalized, size * bytesPerElement, size / programAttribute.locationSize * i * bytesPerElement); } } } else if (materialDefaultAttributeValues !== undefined) { const value = materialDefaultAttributeValues[name]; - if (value !== undefined) { switch (value.length) { case 2: gl.vertexAttrib2fv(programAttribute.location, value); break; - case 3: gl.vertexAttrib3fv(programAttribute.location, value); break; - case 4: gl.vertexAttrib4fv(programAttribute.location, value); break; - default: gl.vertexAttrib1fv(programAttribute.location, value); } @@ -11160,79 +9831,63 @@ } } } - disableUnusedAttributes(); } - function dispose() { reset(); - for (const geometryId in bindingStates) { const programMap = bindingStates[geometryId]; - for (const programId in programMap) { const stateMap = programMap[programId]; - for (const wireframe in stateMap) { deleteVertexArrayObject(stateMap[wireframe].object); delete stateMap[wireframe]; } - delete programMap[programId]; } - delete bindingStates[geometryId]; } } - function releaseStatesOfGeometry(geometry) { if (bindingStates[geometry.id] === undefined) return; const programMap = bindingStates[geometry.id]; - for (const programId in programMap) { const stateMap = programMap[programId]; - for (const wireframe in stateMap) { deleteVertexArrayObject(stateMap[wireframe].object); delete stateMap[wireframe]; } - delete programMap[programId]; } - delete bindingStates[geometry.id]; } - function releaseStatesOfProgram(program) { for (const geometryId in bindingStates) { const programMap = bindingStates[geometryId]; if (programMap[program.id] === undefined) continue; const stateMap = programMap[program.id]; - for (const wireframe in stateMap) { deleteVertexArrayObject(stateMap[wireframe].object); delete stateMap[wireframe]; } - delete programMap[program.id]; } } - function reset() { resetDefaultState(); forceUpdate = true; if (currentState === defaultState) return; currentState = defaultState; bindVertexArrayObject(currentState.object); - } // for backward-compatibility + } + // for backward-compatibility function resetDefaultState() { defaultState.geometry = null; defaultState.program = null; defaultState.wireframe = false; } - return { setup: setup, reset: reset, @@ -11249,37 +9904,32 @@ function WebGLBufferRenderer(gl, extensions, info, capabilities) { const isWebGL2 = capabilities.isWebGL2; let mode; - function setMode(value) { mode = value; } - function render(start, count) { gl.drawArrays(mode, start, count); info.update(count, mode, 1); } - function renderInstances(start, count, primcount) { if (primcount === 0) return; let extension, methodName; - if (isWebGL2) { extension = gl; methodName = 'drawArraysInstanced'; } else { extension = extensions.get('ANGLE_instanced_arrays'); methodName = 'drawArraysInstancedANGLE'; - 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); - } // + } + // this.setMode = setMode; this.render = render; @@ -11288,47 +9938,37 @@ function WebGLCapabilities(gl, extensions, parameters) { let maxAnisotropy; - function getMaxAnisotropy() { if (maxAnisotropy !== undefined) return maxAnisotropy; - if (extensions.has('EXT_texture_filter_anisotropic') === true) { const extension = extensions.get('EXT_texture_filter_anisotropic'); maxAnisotropy = gl.getParameter(extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT); } else { maxAnisotropy = 0; } - return maxAnisotropy; } - function getMaxPrecision(precision) { if (precision === 'highp') { if (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT).precision > 0 && gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision > 0) { return 'highp'; } - precision = 'mediump'; } - if (precision === 'mediump') { if (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_FLOAT).precision > 0 && gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT).precision > 0) { return 'mediump'; } } - return 'lowp'; } - const isWebGL2 = typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext || typeof WebGL2ComputeRenderingContext !== 'undefined' && gl instanceof WebGL2ComputeRenderingContext; let precision = parameters.precision !== undefined ? parameters.precision : 'highp'; const maxPrecision = getMaxPrecision(precision); - if (maxPrecision !== precision) { console.warn('THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.'); precision = maxPrecision; } - const drawBuffers = isWebGL2 || extensions.has('WEBGL_draw_buffers'); const logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true; const maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); @@ -11368,21 +10008,21 @@ function WebGLClipping(properties) { const scope = this; let globalState = null, - numGlobalPlanes = 0, - localClippingEnabled = false, - renderingShadows = false; + numGlobalPlanes = 0, + localClippingEnabled = false, + renderingShadows = false; const plane = new Plane(), - viewNormalMatrix = new Matrix3(), - uniform = { - value: null, - needsUpdate: false - }; + viewNormalMatrix = new Matrix3(), + uniform = { + value: null, + needsUpdate: false + }; this.uniform = uniform; this.numPlanes = 0; this.numIntersection = 0; - this.init = function (planes, enableLocalClipping, camera) { - const enabled = planes.length !== 0 || enableLocalClipping || // enable state of previous frame - the clipping code has to + const 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; @@ -11390,86 +10030,73 @@ numGlobalPlanes = planes.length; return enabled; }; - this.beginShadows = function () { renderingShadows = true; projectPlanes(null); }; - this.endShadows = function () { renderingShadows = false; resetGlobalState(); }; - this.setState = function (material, camera, useCache) { const planes = material.clippingPlanes, - clipIntersection = material.clipIntersection, - clipShadows = material.clipShadows; + clipIntersection = material.clipIntersection, + clipShadows = material.clipShadows; const 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 { const nGlobal = renderingShadows ? 0 : numGlobalPlanes, - lGlobal = nGlobal * 4; + lGlobal = nGlobal * 4; let dstArray = materialProperties.clippingState || null; uniform.value = dstArray; // ensure unique state dstArray = projectPlanes(planes, camera, lGlobal, useCache); - for (let i = 0; i !== lGlobal; ++i) { dstArray[i] = globalState[i]; } - materialProperties.clippingState = dstArray; this.numIntersection = clipIntersection ? this.numPlanes : 0; this.numPlanes += nGlobal; } }; - function resetGlobalState() { if (uniform.value !== globalState) { uniform.value = globalState; uniform.needsUpdate = numGlobalPlanes > 0; } - scope.numPlanes = numGlobalPlanes; scope.numIntersection = 0; } - function projectPlanes(planes, camera, dstOffset, skipTransform) { const nPlanes = planes !== null ? planes.length : 0; let dstArray = null; - if (nPlanes !== 0) { dstArray = uniform.value; - if (skipTransform !== true || dstArray === null) { const flatSize = dstOffset + nPlanes * 4, - viewMatrix = camera.matrixWorldInverse; + viewMatrix = camera.matrixWorldInverse; viewNormalMatrix.getNormalMatrix(viewMatrix); - if (dstArray === null || dstArray.length < flatSize) { dstArray = new Float32Array(flatSize); } - for (let 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; } } - uniform.value = dstArray; uniform.needsUpdate = true; } - scope.numPlanes = nPlanes; scope.numIntersection = 0; return dstArray; @@ -11478,28 +10105,23 @@ function WebGLCubeMaps(renderer) { let cubemaps = new WeakMap(); - function mapTextureMapping(texture, mapping) { if (mapping === EquirectangularReflectionMapping) { texture.mapping = CubeReflectionMapping; } else if (mapping === EquirectangularRefractionMapping) { texture.mapping = CubeRefractionMapping; } - return texture; } - function get(texture) { if (texture && texture.isTexture && texture.isRenderTargetTexture === false) { const mapping = texture.mapping; - if (mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping) { if (cubemaps.has(texture)) { const cubemap = cubemaps.get(texture).texture; return mapTextureMapping(cubemap, texture.mapping); } else { const image = texture.image; - if (image && image.height > 0) { const renderTarget = new WebGLCubeRenderTarget(image.height / 2); renderTarget.fromEquirectangularTexture(renderer, texture); @@ -11508,30 +10130,26 @@ return mapTextureMapping(renderTarget.texture, texture.mapping); } else { // image not yet ready. try the conversion next frame + return null; } } } } - return texture; } - function onTextureDispose(event) { const texture = event.target; texture.removeEventListener('dispose', onTextureDispose); const cubemap = cubemaps.get(texture); - if (cubemap !== undefined) { cubemaps.delete(texture); cubemap.dispose(); } } - function dispose() { cubemaps = new WeakMap(); } - return { get: get, dispose: dispose @@ -11553,7 +10171,6 @@ this.far = far; this.updateProjectionMatrix(); } - copy(source, recursive) { super.copy(source, recursive); this.left = source.left; @@ -11566,7 +10183,6 @@ this.view = source.view === null ? null : Object.assign({}, source.view); return this; } - setViewOffset(fullWidth, fullHeight, x, y, width, height) { if (this.view === null) { this.view = { @@ -11579,7 +10195,6 @@ height: 1 }; } - this.view.enabled = true; this.view.fullWidth = fullWidth; this.view.fullHeight = fullHeight; @@ -11589,15 +10204,12 @@ this.view.height = height; this.updateProjectionMatrix(); } - clearViewOffset() { if (this.view !== null) { this.view.enabled = false; } - this.updateProjectionMatrix(); } - updateProjectionMatrix() { const dx = (this.right - this.left) / (2 * this.zoom); const dy = (this.top - this.bottom) / (2 * this.zoom); @@ -11607,7 +10219,6 @@ let right = cx + dx; let top = cy + dy; let bottom = cy - dy; - if (this.view !== null && this.view.enabled) { const scaleW = (this.right - this.left) / this.view.fullWidth / this.zoom; const scaleH = (this.top - this.bottom) / this.view.fullHeight / this.zoom; @@ -11616,11 +10227,9 @@ top -= scaleH * this.view.offsetY; bottom = top - scaleH * this.view.height; } - this.projectionMatrix.makeOrthographic(left, right, top, bottom, this.near, this.far); this.projectionMatrixInverse.copy(this.projectionMatrix).invert(); } - toJSON(meta) { const data = super.toJSON(meta); data.object.zoom = this.zoom; @@ -11633,30 +10242,31 @@ if (this.view !== null) data.object.view = Object.assign({}, this.view); return data; } - } - const LOD_MIN = 4; // The standard deviations (radians) associated with the extra mips. These are + const LOD_MIN = 4; + + // 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. + const EXTRA_LOD_SIGMA = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582]; - const EXTRA_LOD_SIGMA = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582]; // The maximum length of the blur for loop. Smaller sigmas will use fewer + // The maximum length of the blur for loop. Smaller sigmas will use fewer // samples and exit early, but not recompile the shader. - const MAX_SAMPLES = 20; - const _flatCamera = /*@__PURE__*/new OrthographicCamera(); - const _clearColor = /*@__PURE__*/new Color(); + let _oldTarget = null; - let _oldTarget = null; // Golden Ratio - + // Golden Ratio const PHI = (1 + Math.sqrt(5)) / 2; - const 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. + const 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. const _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 @@ -11684,9 +10294,9 @@ this._blurMaterial = null; this._cubemapMaterial = null; this._equirectMaterial = null; - 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 @@ -11694,133 +10304,104 @@ * and far planes ensure the scene is rendered in its entirety (the cubeCamera * is placed at the origin). */ - - fromScene(scene, sigma = 0, near = 0.1, far = 100) { _oldTarget = this._renderer.getRenderTarget(); - this._setSize(256); - const cubeUVRenderTarget = this._allocateTargets(); - cubeUVRenderTarget.depthBuffer = true; - this._sceneToCubeUV(scene, near, far, cubeUVRenderTarget); - if (sigma > 0) { this._blur(cubeUVRenderTarget, 0, 0, sigma); } - this._applyPMREM(cubeUVRenderTarget); - this._cleanup(cubeUVRenderTarget); - return cubeUVRenderTarget; } + /** * Generates a PMREM from an equirectangular texture, which can be either LDR * or HDR. The ideal input image size is 1k (1024 x 512), * as this matches best with the 256 x 256 cubemap output. */ - - fromEquirectangular(equirectangular, renderTarget = null) { return this._fromTexture(equirectangular, renderTarget); } + /** * Generates a PMREM from an cubemap texture, which can be either LDR * or HDR. The ideal input cube size is 256 x 256, * as this matches best with the 256 x 256 cubemap output. */ - - fromCubemap(cubemap, renderTarget = null) { return this._fromTexture(cubemap, renderTarget); } + /** * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during * your texture's network fetch for increased concurrency. */ - - compileCubemapShader() { if (this._cubemapMaterial === null) { this._cubemapMaterial = _getCubemapMaterial(); - this._compileMaterial(this._cubemapMaterial); } } + /** * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during * your texture's network fetch for increased concurrency. */ - - compileEquirectangularShader() { if (this._equirectMaterial === null) { this._equirectMaterial = _getEquirectMaterial(); - this._compileMaterial(this._equirectMaterial); } } + /** * 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. */ - - dispose() { this._dispose(); - if (this._cubemapMaterial !== null) this._cubemapMaterial.dispose(); if (this._equirectMaterial !== null) this._equirectMaterial.dispose(); - } // private interface + } + // private interface _setSize(cubeSize) { this._lodMax = Math.floor(Math.log2(cubeSize)); this._cubeSize = Math.pow(2, this._lodMax); } - _dispose() { if (this._blurMaterial !== null) this._blurMaterial.dispose(); if (this._pingPongRenderTarget !== null) this._pingPongRenderTarget.dispose(); - for (let i = 0; i < this._lodPlanes.length; i++) { this._lodPlanes[i].dispose(); } } - _cleanup(outputTarget) { this._renderer.setRenderTarget(_oldTarget); - outputTarget.scissorTest = false; - _setViewport(outputTarget, 0, 0, outputTarget.width, outputTarget.height); } - _fromTexture(texture, renderTarget) { if (texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping) { this._setSize(texture.image.length === 0 ? 16 : texture.image[0].width || texture.image[0].image.width); } else { // Equirectangular + this._setSize(texture.image.width / 4); } - _oldTarget = this._renderer.getRenderTarget(); - const cubeUVRenderTarget = renderTarget || this._allocateTargets(); - this._textureToCubeUV(texture, cubeUVRenderTarget); - this._applyPMREM(cubeUVRenderTarget); - this._cleanup(cubeUVRenderTarget); - return cubeUVRenderTarget; } - _allocateTargets() { const width = 3 * Math.max(this._cubeSize, 16 * 7); const height = 4 * this._cubeSize; @@ -11833,14 +10414,11 @@ encoding: LinearEncoding, depthBuffer: false }; - const cubeUVRenderTarget = _createRenderTarget(width, height, params); - if (this._pingPongRenderTarget === null || this._pingPongRenderTarget.width !== width) { if (this._pingPongRenderTarget !== null) { this._dispose(); } - this._pingPongRenderTarget = _createRenderTarget(width, height, params); const { _lodMax @@ -11852,16 +10430,12 @@ } = _createPlanes(_lodMax)); this._blurMaterial = _getBlurShader(_lodMax, width, height); } - return cubeUVRenderTarget; } - _compileMaterial(material) { const tmpMesh = new Mesh(this._lodPlanes[0], material); - this._renderer.compile(tmpMesh, _flatCamera); } - _sceneToCubeUV(scene, near, far, cubeUVRenderTarget) { const fov = 90; const aspect = 1; @@ -11883,7 +10457,6 @@ const backgroundBox = new Mesh(new BoxGeometry(), backgroundMaterial); let useSolidColor = false; const background = scene.background; - if (background) { if (background.isColor) { backgroundMaterial.color.copy(background); @@ -11894,10 +10467,8 @@ backgroundMaterial.color.copy(_clearColor); useSolidColor = true; } - for (let i = 0; i < 6; i++) { const col = i % 3; - if (col === 0) { cubeCamera.up.set(0, upSign[i], 0); cubeCamera.lookAt(forwardSign[i], 0, 0); @@ -11908,69 +10479,54 @@ cubeCamera.up.set(0, upSign[i], 0); cubeCamera.lookAt(0, 0, forwardSign[i]); } - const size = this._cubeSize; - _setViewport(cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size); - renderer.setRenderTarget(cubeUVRenderTarget); - if (useSolidColor) { renderer.render(backgroundBox, cubeCamera); } - renderer.render(scene, cubeCamera); } - backgroundBox.geometry.dispose(); backgroundBox.material.dispose(); renderer.toneMapping = toneMapping; renderer.autoClear = originalAutoClear; scene.background = background; } - _textureToCubeUV(texture, cubeUVRenderTarget) { const renderer = this._renderer; const isCubeTexture = texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping; - if (isCubeTexture) { if (this._cubemapMaterial === null) { this._cubemapMaterial = _getCubemapMaterial(); } - this._cubemapMaterial.uniforms.flipEnvMap.value = texture.isRenderTargetTexture === false ? -1 : 1; } else { if (this._equirectMaterial === null) { this._equirectMaterial = _getEquirectMaterial(); } } - const material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial; const mesh = new Mesh(this._lodPlanes[0], material); const uniforms = material.uniforms; uniforms['envMap'].value = texture; const size = this._cubeSize; - _setViewport(cubeUVRenderTarget, 0, 0, 3 * size, 2 * size); - renderer.setRenderTarget(cubeUVRenderTarget); renderer.render(mesh, _flatCamera); } - _applyPMREM(cubeUVRenderTarget) { const renderer = this._renderer; const autoClear = renderer.autoClear; renderer.autoClear = false; - for (let i = 1; i < this._lodPlanes.length; i++) { const sigma = Math.sqrt(this._sigmas[i] * this._sigmas[i] - this._sigmas[i - 1] * this._sigmas[i - 1]); const poleAxis = _axisDirections[(i - 1) % _axisDirections.length]; - 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 @@ -11978,25 +10534,19 @@ * the poles) to approximate the orthogonally-separable blur. It is least * accurate at the poles, but still does a decent job. */ - - _blur(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) { const pingPongRenderTarget = this._pingPongRenderTarget; - this._halfBlur(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, sigma, 'latitudinal', poleAxis); - this._halfBlur(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, sigma, 'longitudinal', poleAxis); } - _halfBlur(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis) { const renderer = this._renderer; const blurMaterial = this._blurMaterial; - 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. - + } + // Number of standard deviations at which to cut off the discrete approximation. const STANDARD_DEVIATIONS = 3; const blurMesh = new Mesh(this._lodPlanes[lodOut], blurMaterial); const blurUniforms = blurMaterial.uniforms; @@ -12004,39 +10554,31 @@ const radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : 2 * Math.PI / (2 * MAX_SAMPLES - 1); const sigmaPixels = sigmaRadians / radiansPerPixel; const samples = isFinite(sigmaRadians) ? 1 + Math.floor(STANDARD_DEVIATIONS * sigmaPixels) : MAX_SAMPLES; - 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}`); } - const weights = []; let sum = 0; - for (let i = 0; i < MAX_SAMPLES; ++i) { const x = i / sigmaPixels; const weight = Math.exp(-x * x / 2); weights.push(weight); - if (i === 0) { sum += weight; } else if (i < samples) { sum += 2 * weight; } } - for (let i = 0; i < weights.length; i++) { weights[i] = weights[i] / sum; } - blurUniforms['envMap'].value = targetIn.texture; blurUniforms['samples'].value = samples; blurUniforms['weights'].value = weights; blurUniforms['latitudinal'].value = direction === 'latitudinal'; - if (poleAxis) { blurUniforms['poleAxis'].value = poleAxis; } - const { _lodMax } = this; @@ -12045,33 +10587,26 @@ const outputSize = this._sizeLods[lodOut]; const x = 3 * outputSize * (lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0); const y = 4 * (this._cubeSize - outputSize); - _setViewport(targetOut, x, y, 3 * outputSize, 2 * outputSize); - renderer.setRenderTarget(targetOut); renderer.render(blurMesh, _flatCamera); } - } - function _createPlanes(lodMax) { const lodPlanes = []; const sizeLods = []; const sigmas = []; let lod = lodMax; const totalLods = lodMax - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; - for (let i = 0; i < totalLods; i++) { const sizeLod = Math.pow(2, lod); sizeLods.push(sizeLod); let sigma = 1.0 / sizeLod; - if (i > lodMax - LOD_MIN) { sigma = EXTRA_LOD_SIGMA[i - lodMax + LOD_MIN - 1]; } else if (i === 0) { sigma = 0; } - sigmas.push(sigma); const texelSize = 1.0 / (sizeLod - 2); const min = -texelSize; @@ -12085,7 +10620,6 @@ const position = new Float32Array(positionSize * vertices * cubeFaces); const uv = new Float32Array(uvSize * vertices * cubeFaces); const faceIndex = new Float32Array(faceIndexSize * vertices * cubeFaces); - for (let face = 0; face < cubeFaces; face++) { const x = face % 3 * 2 / 3 - 1; const y = face > 2 ? 0 : -1; @@ -12095,25 +10629,21 @@ const fill = [face, face, face, face, face, face]; faceIndex.set(fill, faceIndexSize * vertices * face); } - const planes = new BufferGeometry(); planes.setAttribute('position', new BufferAttribute(position, positionSize)); planes.setAttribute('uv', new BufferAttribute(uv, uvSize)); planes.setAttribute('faceIndex', new BufferAttribute(faceIndex, faceIndexSize)); lodPlanes.push(planes); - if (lod > LOD_MIN) { lod--; } } - return { lodPlanes, sizeLods, sigmas }; } - function _createRenderTarget(width, height, params) { const cubeUVRenderTarget = new WebGLRenderTarget(width, height, params); cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; @@ -12121,12 +10651,10 @@ 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(lodMax, width, height) { const weights = new Float32Array(MAX_SAMPLES); const poleAxis = new Vector3(0, 1, 0); @@ -12162,9 +10690,7 @@ } }, vertexShader: _getCommonVertexShader(), - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` precision mediump float; precision mediump int; @@ -12231,7 +10757,6 @@ }); return shaderMaterial; } - function _getEquirectMaterial() { return new ShaderMaterial({ name: 'EquirectangularToCubeUV', @@ -12241,9 +10766,7 @@ } }, vertexShader: _getCommonVertexShader(), - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` precision mediump float; precision mediump int; @@ -12268,7 +10791,6 @@ depthWrite: false }); } - function _getCubemapMaterial() { return new ShaderMaterial({ name: 'CubemapToCubeUV', @@ -12281,9 +10803,7 @@ } }, vertexShader: _getCommonVertexShader(), - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` precision mediump float; precision mediump int; @@ -12305,11 +10825,8 @@ depthWrite: false }); } - function _getCommonVertexShader() { - return ( - /* glsl */ - ` + return (/* glsl */` precision mediump float; precision mediump int; @@ -12371,12 +10888,13 @@ function WebGLCubeUVMaps(renderer) { let cubeUVmaps = new WeakMap(); let pmremGenerator = null; - function get(texture) { if (texture && texture.isTexture) { const mapping = texture.mapping; const isEquirectMap = mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping; - const isCubeMap = mapping === CubeReflectionMapping || mapping === CubeRefractionMapping; // equirect/cube map to cubeUV conversion + const isCubeMap = mapping === CubeReflectionMapping || mapping === CubeRefractionMapping; + + // equirect/cube map to cubeUV conversion if (isEquirectMap || isCubeMap) { if (texture.isRenderTargetTexture && texture.needsPMREMUpdate === true) { @@ -12391,7 +10909,6 @@ return cubeUVmaps.get(texture).texture; } else { const image = texture.image; - if (isEquirectMap && image && image.height > 0 || isCubeMap && image && isCubeTextureComplete(image)) { if (pmremGenerator === null) pmremGenerator = new PMREMGenerator(renderer); const renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular(texture) : pmremGenerator.fromCubemap(texture); @@ -12400,47 +10917,39 @@ return renderTarget.texture; } else { // image not yet ready. try the conversion next frame + return null; } } } } } - return texture; } - function isCubeTextureComplete(image) { let count = 0; const length = 6; - for (let i = 0; i < length; i++) { if (image[i] !== undefined) count++; } - return count === length; } - function onTextureDispose(event) { const texture = event.target; texture.removeEventListener('dispose', onTextureDispose); const cubemapUV = cubeUVmaps.get(texture); - if (cubemapUV !== undefined) { cubeUVmaps.delete(texture); cubemapUV.dispose(); } } - function dispose() { cubeUVmaps = new WeakMap(); - if (pmremGenerator !== null) { pmremGenerator.dispose(); pmremGenerator = null; } } - return { get: get, dispose: dispose @@ -12449,39 +10958,30 @@ function WebGLExtensions(gl) { const extensions = {}; - function getExtension(name) { if (extensions[name] !== undefined) { return extensions[name]; } - let extension; - 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; - 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; - 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; - default: extension = gl.getExtension(name); } - extensions[name] = extension; return extension; } - return { has: function (name) { return getExtension(name) !== null; @@ -12499,18 +10999,15 @@ getExtension('OES_vertex_array_object'); getExtension('ANGLE_instanced_arrays'); } - getExtension('OES_texture_float_linear'); getExtension('EXT_color_buffer_half_float'); getExtension('WEBGL_multisampled_render_to_texture'); }, get: function (name) { const extension = getExtension(name); - if (extension === null) { console.warn('THREE.WebGLRenderer: ' + name + ' extension not supported.'); } - return extension; } }; @@ -12519,37 +11016,30 @@ function WebGLGeometries(gl, attributes, info, bindingStates) { const geometries = {}; const wireframeAttributes = new WeakMap(); - function onGeometryDispose(event) { const geometry = event.target; - if (geometry.index !== null) { attributes.remove(geometry.index); } - for (const name in geometry.attributes) { attributes.remove(geometry.attributes[name]); } - geometry.removeEventListener('dispose', onGeometryDispose); delete geometries[geometry.id]; const attribute = wireframeAttributes.get(geometry); - if (attribute) { attributes.remove(attribute); wireframeAttributes.delete(geometry); } - bindingStates.releaseStatesOfGeometry(geometry); - if (geometry.isInstancedBufferGeometry === true) { delete geometry._maxInstanceCount; - } // + } + // info.memory.geometries--; } - function get(object, geometry) { if (geometries[geometry.id] === true) return geometry; geometry.addEventListener('dispose', onGeometryDispose); @@ -12557,36 +11047,33 @@ info.memory.geometries++; return geometry; } - function update(geometry) { - const geometryAttributes = geometry.attributes; // Updating index buffer in VAO now. See WebGLBindingStates. + const geometryAttributes = geometry.attributes; + + // Updating index buffer in VAO now. See WebGLBindingStates. for (const name in geometryAttributes) { attributes.update(geometryAttributes[name], gl.ARRAY_BUFFER); - } // morph targets + } + // morph targets const morphAttributes = geometry.morphAttributes; - for (const name in morphAttributes) { const array = morphAttributes[name]; - for (let i = 0, l = array.length; i < l; i++) { attributes.update(array[i], gl.ARRAY_BUFFER); } } } - function updateWireframeAttribute(geometry) { const indices = []; const geometryIndex = geometry.index; const geometryPosition = geometry.attributes.position; let version = 0; - if (geometryIndex !== null) { const array = geometryIndex.array; version = geometryIndex.version; - for (let i = 0, l = array.length; i < l; i += 3) { const a = array[i + 0]; const b = array[i + 1]; @@ -12596,7 +11083,6 @@ } else { const array = geometryPosition.array; version = geometryPosition.version; - for (let i = 0, l = array.length / 3 - 1; i < l; i += 3) { const a = i + 0; const b = i + 1; @@ -12604,25 +11090,27 @@ indices.push(a, b, b, c, c, a); } } - const attribute = new (arrayNeedsUint32(indices) ? Uint32BufferAttribute : Uint16BufferAttribute)(indices, 1); - attribute.version = version; // Updating index buffer in VAO now. See WebGLBindingStates + attribute.version = version; + + // Updating index buffer in VAO now. See WebGLBindingStates + // const previousAttribute = wireframeAttributes.get(geometry); - if (previousAttribute) attributes.remove(previousAttribute); // + if (previousAttribute) attributes.remove(previousAttribute); + + // wireframeAttributes.set(geometry, attribute); } - function getWireframeAttribute(geometry) { const currentAttribute = wireframeAttributes.get(geometry); - if (currentAttribute) { const geometryIndex = geometry.index; - if (geometryIndex !== null) { // if the attribute is obsolete, create a new one + if (currentAttribute.version < geometryIndex.version) { updateWireframeAttribute(geometry); } @@ -12630,10 +11118,8 @@ } else { updateWireframeAttribute(geometry); } - return wireframeAttributes.get(geometry); } - return { get: get, update: update, @@ -12644,44 +11130,37 @@ function WebGLIndexedBufferRenderer(gl, extensions, info, capabilities) { const isWebGL2 = capabilities.isWebGL2; let mode; - function setMode(value) { mode = value; } - let type, bytesPerElement; - function setIndex(value) { type = value.type; bytesPerElement = value.bytesPerElement; } - function render(start, count) { gl.drawElements(mode, count, type, start * bytesPerElement); info.update(count, mode, 1); } - function renderInstances(start, count, primcount) { if (primcount === 0) return; let extension, methodName; - if (isWebGL2) { extension = gl; methodName = 'drawElementsInstanced'; } else { extension = extensions.get('ANGLE_instanced_arrays'); methodName = 'drawElementsInstancedANGLE'; - if (extension === null) { console.error('THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.'); return; } } - extension[methodName](mode, count, type, start * bytesPerElement, primcount); info.update(count, mode, primcount); - } // + } + // this.setMode = setMode; this.setIndex = setIndex; @@ -12701,37 +11180,29 @@ points: 0, lines: 0 }; - function update(count, mode, instanceCount) { render.calls++; - switch (mode) { case gl.TRIANGLES: render.triangles += instanceCount * (count / 3); break; - case gl.LINES: render.lines += instanceCount * (count / 2); break; - case gl.LINE_STRIP: render.lines += instanceCount * (count - 1); break; - case gl.LINE_LOOP: render.lines += instanceCount * count; break; - case gl.POINTS: render.points += instanceCount * count; break; - default: console.error('THREE.WebGLInfo: Unknown draw mode:', mode); break; } } - function reset() { render.frame++; render.calls = 0; @@ -12739,7 +11210,6 @@ render.points = 0; render.lines = 0; } - return { memory: memory, render: render, @@ -12753,39 +11223,27 @@ function numericalSort(a, b) { return a[0] - b[0]; } - function absNumericalSort(a, b) { return Math.abs(b[1]) - Math.abs(a[1]); } - - function denormalize(morph, attribute) { - let denominator = 1; - const array = attribute.isInterleavedBufferAttribute ? attribute.data.array : attribute.array; - if (array instanceof Int8Array) denominator = 127;else if (array instanceof Uint8Array) denominator = 255;else if (array instanceof Uint16Array) denominator = 65535;else if (array instanceof Int16Array) denominator = 32767;else if (array instanceof Int32Array) denominator = 2147483647;else console.error('THREE.WebGLMorphtargets: Unsupported morph attribute data type: ', array); - morph.divideScalar(denominator); - } - function WebGLMorphtargets(gl, capabilities, textures) { const influencesList = {}; const morphInfluences = new Float32Array(8); const morphTextures = new WeakMap(); const morph = new Vector4(); const workInfluences = []; - for (let i = 0; i < 8; i++) { workInfluences[i] = [i, 0]; } - function update(object, geometry, material, program) { const objectInfluences = object.morphTargetInfluences; - if (capabilities.isWebGL2 === true) { // instead of using attributes, the WebGL 2 code path encodes morph targets // into an array of data textures. Each layer represents a single morph target. + const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color; const morphTargetsCount = morphAttribute !== undefined ? morphAttribute.length : 0; let entry = morphTextures.get(geometry); - if (entry === undefined || entry.count !== morphTargetsCount) { if (entry !== undefined) entry.texture.dispose(); const hasMorphPosition = geometry.morphAttributes.position !== undefined; @@ -12800,49 +11258,41 @@ if (hasMorphColors === true) vertexDataCount = 3; let width = geometry.attributes.position.count * vertexDataCount; let height = 1; - if (width > capabilities.maxTextureSize) { height = Math.ceil(width / capabilities.maxTextureSize); width = capabilities.maxTextureSize; } - const buffer = new Float32Array(width * height * 4 * morphTargetsCount); const texture = new DataArrayTexture(buffer, width, height, morphTargetsCount); texture.type = FloatType; - texture.needsUpdate = true; // fill buffer + texture.needsUpdate = true; - const vertexDataStride = vertexDataCount * 4; + // fill buffer + const vertexDataStride = vertexDataCount * 4; for (let i = 0; i < morphTargetsCount; i++) { const morphTarget = morphTargets[i]; const morphNormal = morphNormals[i]; const morphColor = morphColors[i]; const offset = width * height * 4 * i; - for (let j = 0; j < morphTarget.count; j++) { const stride = j * vertexDataStride; - if (hasMorphPosition === true) { morph.fromBufferAttribute(morphTarget, j); - if (morphTarget.normalized === true) denormalize(morph, morphTarget); buffer[offset + stride + 0] = morph.x; buffer[offset + stride + 1] = morph.y; buffer[offset + stride + 2] = morph.z; buffer[offset + stride + 3] = 0; } - if (hasMorphNormals === true) { morph.fromBufferAttribute(morphNormal, j); - if (morphNormal.normalized === true) denormalize(morph, morphNormal); buffer[offset + stride + 4] = morph.x; buffer[offset + stride + 5] = morph.y; buffer[offset + stride + 6] = morph.z; buffer[offset + stride + 7] = 0; } - if (hasMorphColors === true) { morph.fromBufferAttribute(morphColor, j); - if (morphColor.normalized === true) denormalize(morph, morphColor); buffer[offset + stride + 8] = morph.x; buffer[offset + stride + 9] = morph.y; buffer[offset + stride + 10] = morph.z; @@ -12850,30 +11300,26 @@ } } } - entry = { count: morphTargetsCount, texture: texture, size: new Vector2(width, height) }; morphTextures.set(geometry, entry); - function disposeTexture() { texture.dispose(); morphTextures.delete(geometry); geometry.removeEventListener('dispose', disposeTexture); } - geometry.addEventListener('dispose', disposeTexture); - } // + } + // let morphInfluencesSum = 0; - for (let i = 0; i < objectInfluences.length; i++) { morphInfluencesSum += objectInfluences[i]; } - const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; program.getUniforms().setValue(gl, 'morphTargetBaseInfluence', morphBaseInfluence); program.getUniforms().setValue(gl, 'morphTargetInfluences', objectInfluences); @@ -12882,29 +11328,27 @@ } else { // 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 + const length = objectInfluences === undefined ? 0 : objectInfluences.length; let influences = influencesList[geometry.id]; - if (influences === undefined || influences.length !== length) { // initialise list - influences = []; + influences = []; for (let i = 0; i < length; i++) { influences[i] = [i, 0]; } - influencesList[geometry.id] = influences; - } // Collect influences + } + // Collect influences for (let i = 0; i < length; i++) { const influence = influences[i]; influence[0] = i; influence[1] = objectInfluences[i]; } - influences.sort(absNumericalSort); - for (let i = 0; i < 8; i++) { if (i < length && influences[i][1]) { workInfluences[i][0] = influences[i][0]; @@ -12914,50 +11358,42 @@ workInfluences[i][1] = 0; } } - workInfluences.sort(numericalSort); const morphTargets = geometry.morphAttributes.position; const morphNormals = geometry.morphAttributes.normal; let morphInfluencesSum = 0; - for (let i = 0; i < 8; i++) { const influence = workInfluences[i]; const index = influence[0]; const value = influence[1]; - if (index !== Number.MAX_SAFE_INTEGER && value) { if (morphTargets && geometry.getAttribute('morphTarget' + i) !== morphTargets[index]) { geometry.setAttribute('morphTarget' + i, morphTargets[index]); } - if (morphNormals && geometry.getAttribute('morphNormal' + i) !== morphNormals[index]) { geometry.setAttribute('morphNormal' + i, morphNormals[index]); } - morphInfluences[i] = value; morphInfluencesSum += value; } else { if (morphTargets && geometry.hasAttribute('morphTarget' + i) === true) { geometry.deleteAttribute('morphTarget' + i); } - if (morphNormals && geometry.hasAttribute('morphNormal' + i) === true) { geometry.deleteAttribute('morphNormal' + i); } - morphInfluences[i] = 0; } - } // GLSL shader uses formula baseinfluence * base + sum(target * influence) + } + + // 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) - - const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; program.getUniforms().setValue(gl, 'morphTargetBaseInfluence', morphBaseInfluence); program.getUniforms().setValue(gl, 'morphTargetInfluences', morphInfluences); } } - return { update: update }; @@ -12965,43 +11401,37 @@ function WebGLObjects(gl, geometries, attributes, info) { let updateMap = new WeakMap(); - function update(object) { const frame = info.render.frame; const geometry = object.geometry; - const buffergeometry = geometries.get(object, geometry); // Update once per frame + const buffergeometry = geometries.get(object, geometry); + + // Update once per frame if (updateMap.get(buffergeometry) !== frame) { geometries.update(buffergeometry); updateMap.set(buffergeometry, frame); } - if (object.isInstancedMesh) { if (object.hasEventListener('dispose', onInstancedMeshDispose) === false) { object.addEventListener('dispose', onInstancedMeshDispose); } - attributes.update(object.instanceMatrix, gl.ARRAY_BUFFER); - if (object.instanceColor !== null) { attributes.update(object.instanceColor, gl.ARRAY_BUFFER); } } - return buffergeometry; } - function dispose() { updateMap = new WeakMap(); } - function onInstancedMeshDispose(event) { const instancedMesh = event.target; instancedMesh.removeEventListener('dispose', onInstancedMeshDispose); attributes.remove(instancedMesh.instanceMatrix); if (instancedMesh.instanceColor !== null) attributes.remove(instancedMesh.instanceColor); } - return { update: update, dispose: dispose @@ -13053,88 +11483,89 @@ const emptyTexture = /*@__PURE__*/new Texture(); const emptyArrayTexture = /*@__PURE__*/new DataArrayTexture(); const empty3dTexture = /*@__PURE__*/new Data3DTexture(); - const emptyCubeTexture = /*@__PURE__*/new CubeTexture(); // --- Utilities --- + const emptyCubeTexture = /*@__PURE__*/new CubeTexture(); + + // --- Utilities --- + // Array Caches (provide typed arrays for temporary by size) const arrayCacheF32 = []; - const arrayCacheI32 = []; // Float32Array caches used for uploading Matrix uniforms + const arrayCacheI32 = []; + + // Float32Array caches used for uploading Matrix uniforms const mat4array = new Float32Array(16); const mat3array = new Float32Array(9); - const mat2array = new Float32Array(4); // Flattening for arrays of vectors and matrices + const mat2array = new Float32Array(4); + + // Flattening for arrays of vectors and matrices function flatten(array, nBlocks, blockSize) { const firstElem = array[0]; - if (firstElem <= 0 || firstElem > 0) return array; // unoptimized: ! isNaN( firstElem ) + if (firstElem <= 0 || firstElem > 0) return array; + // unoptimized: ! isNaN( firstElem ) // see http://jacksondunstan.com/articles/983 const n = nBlocks * blockSize; let r = arrayCacheF32[n]; - if (r === undefined) { r = new Float32Array(n); arrayCacheF32[n] = r; } - if (nBlocks !== 0) { firstElem.toArray(r, 0); - for (let i = 1, offset = 0; i !== nBlocks; ++i) { offset += blockSize; array[i].toArray(r, offset); } } - return r; } - function arraysEqual(a, b) { if (a.length !== b.length) return false; - for (let i = 0, l = a.length; i < l; i++) { if (a[i] !== b[i]) return false; } - return true; } - function copyArray(a, b) { for (let i = 0, l = b.length; i < l; i++) { a[i] = b[i]; } - } // Texture unit allocation + } + // Texture unit allocation function allocTexUnits(textures, n) { let r = arrayCacheI32[n]; - if (r === undefined) { r = new Int32Array(n); arrayCacheI32[n] = r; } - for (let i = 0; i !== n; ++i) { r[i] = textures.allocateTextureUnit(); } - return r; - } // --- Setters --- + } + + // --- Setters --- + // Note: Defining these methods externally, because they come in a bunch // and this way their names minify. - // Single scalar + // Single scalar function setValueV1f(gl, v) { const 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) + } + // Single float vector (from flat array or THREE.VectorN) function setValueV2f(gl, v) { const cache = this.cache; - if (v.x !== undefined) { if (cache[0] !== v.x || cache[1] !== v.y) { gl.uniform2f(this.addr, v.x, v.y); @@ -13147,10 +11578,8 @@ copyArray(cache, v); } } - function setValueV3f(gl, v) { const cache = this.cache; - 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); @@ -13171,10 +11600,8 @@ copyArray(cache, v); } } - function setValueV4f(gl, v) { const cache = this.cache; - 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); @@ -13188,13 +11615,13 @@ gl.uniform4fv(this.addr, v); copyArray(cache, v); } - } // Single matrix (from flat array or THREE.MatrixN) + } + // Single matrix (from flat array or THREE.MatrixN) function setValueM2(gl, v) { const cache = this.cache; const elements = v.elements; - if (elements === undefined) { if (arraysEqual(cache, v)) return; gl.uniformMatrix2fv(this.addr, false, v); @@ -13206,11 +11633,9 @@ copyArray(cache, elements); } } - function setValueM3(gl, v) { const cache = this.cache; const elements = v.elements; - if (elements === undefined) { if (arraysEqual(cache, v)) return; gl.uniformMatrix3fv(this.addr, false, v); @@ -13222,11 +11647,9 @@ copyArray(cache, elements); } } - function setValueM4(gl, v) { const cache = this.cache; const elements = v.elements; - if (elements === undefined) { if (arraysEqual(cache, v)) return; gl.uniformMatrix4fv(this.addr, false, v); @@ -13237,132 +11660,174 @@ gl.uniformMatrix4fv(this.addr, false, mat4array); copyArray(cache, elements); } - } // Single integer / boolean + } + // Single integer / boolean function setValueV1i(gl, v) { const cache = this.cache; if (cache[0] === v) return; gl.uniform1i(this.addr, v); cache[0] = v; - } // Single integer / boolean vector (from flat array) + } + // Single integer / boolean vector (from flat array or THREE.VectorN) function setValueV2i(gl, v) { const cache = this.cache; - if (arraysEqual(cache, v)) return; - gl.uniform2iv(this.addr, v); - copyArray(cache, v); + if (v.x !== undefined) { + if (cache[0] !== v.x || cache[1] !== v.y) { + gl.uniform2i(this.addr, v.x, v.y); + cache[0] = v.x; + cache[1] = v.y; + } + } else { + if (arraysEqual(cache, v)) return; + gl.uniform2iv(this.addr, v); + copyArray(cache, v); + } } - function setValueV3i(gl, v) { const cache = this.cache; - if (arraysEqual(cache, v)) return; - gl.uniform3iv(this.addr, v); - copyArray(cache, v); + if (v.x !== undefined) { + if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z) { + gl.uniform3i(this.addr, v.x, v.y, v.z); + cache[0] = v.x; + cache[1] = v.y; + cache[2] = v.z; + } + } else { + if (arraysEqual(cache, v)) return; + gl.uniform3iv(this.addr, v); + copyArray(cache, v); + } } - function setValueV4i(gl, v) { const cache = this.cache; - if (arraysEqual(cache, v)) return; - gl.uniform4iv(this.addr, v); - copyArray(cache, v); - } // Single unsigned integer + if (v.x !== undefined) { + if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z || cache[3] !== v.w) { + gl.uniform4i(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.uniform4iv(this.addr, v); + copyArray(cache, v); + } + } + // Single unsigned integer function setValueV1ui(gl, v) { const cache = this.cache; if (cache[0] === v) return; gl.uniform1ui(this.addr, v); cache[0] = v; - } // Single unsigned integer vector (from flat array) + } + // Single unsigned integer vector (from flat array or THREE.VectorN) function setValueV2ui(gl, v) { const cache = this.cache; - if (arraysEqual(cache, v)) return; - gl.uniform2uiv(this.addr, v); - copyArray(cache, v); + if (v.x !== undefined) { + if (cache[0] !== v.x || cache[1] !== v.y) { + gl.uniform2ui(this.addr, v.x, v.y); + cache[0] = v.x; + cache[1] = v.y; + } + } else { + if (arraysEqual(cache, v)) return; + gl.uniform2uiv(this.addr, v); + copyArray(cache, v); + } } - function setValueV3ui(gl, v) { const cache = this.cache; - if (arraysEqual(cache, v)) return; - gl.uniform3uiv(this.addr, v); - copyArray(cache, v); + if (v.x !== undefined) { + if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z) { + gl.uniform3ui(this.addr, v.x, v.y, v.z); + cache[0] = v.x; + cache[1] = v.y; + cache[2] = v.z; + } + } else { + if (arraysEqual(cache, v)) return; + gl.uniform3uiv(this.addr, v); + copyArray(cache, v); + } } - function setValueV4ui(gl, v) { const cache = this.cache; - if (arraysEqual(cache, v)) return; - gl.uniform4uiv(this.addr, v); - copyArray(cache, v); - } // Single texture (2D / Cube) + if (v.x !== undefined) { + if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z || cache[3] !== v.w) { + gl.uniform4ui(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.uniform4uiv(this.addr, v); + copyArray(cache, v); + } + } + // Single texture (2D / Cube) function setValueT1(gl, v, textures) { const cache = this.cache; const unit = textures.allocateTextureUnit(); - if (cache[0] !== unit) { gl.uniform1i(this.addr, unit); cache[0] = unit; } - textures.setTexture2D(v || emptyTexture, unit); } - function setValueT3D1(gl, v, textures) { const cache = this.cache; const unit = textures.allocateTextureUnit(); - if (cache[0] !== unit) { gl.uniform1i(this.addr, unit); cache[0] = unit; } - textures.setTexture3D(v || empty3dTexture, unit); } - function setValueT6(gl, v, textures) { const cache = this.cache; const unit = textures.allocateTextureUnit(); - if (cache[0] !== unit) { gl.uniform1i(this.addr, unit); cache[0] = unit; } - textures.setTextureCube(v || emptyCubeTexture, unit); } - function setValueT2DArray1(gl, v, textures) { const cache = this.cache; const unit = textures.allocateTextureUnit(); - if (cache[0] !== unit) { gl.uniform1i(this.addr, unit); cache[0] = unit; } - textures.setTexture2DArray(v || emptyArrayTexture, unit); - } // Helper to pick the right setter for the singular case + } + // Helper to pick the right setter for the singular case function getSingularSetter(type) { switch (type) { case 0x1406: return setValueV1f; // FLOAT - case 0x8b50: return setValueV2f; // _VEC2 - case 0x8b51: return setValueV3f; // _VEC3 - case 0x8b52: return setValueV4f; // _VEC4 @@ -13370,11 +11835,9 @@ case 0x8b5a: return setValueM2; // _MAT2 - case 0x8b5b: return setValueM3; // _MAT3 - case 0x8b5c: return setValueM4; // _MAT4 @@ -13383,17 +11846,14 @@ case 0x8b56: return setValueV1i; // INT, BOOL - case 0x8b53: case 0x8b57: return setValueV2i; // _VEC2 - case 0x8b54: case 0x8b58: return setValueV3i; // _VEC3 - case 0x8b55: case 0x8b59: return setValueV4i; @@ -13402,190 +11862,179 @@ case 0x1405: return setValueV1ui; // UINT - case 0x8dc6: return setValueV2ui; // _VEC2 - case 0x8dc7: return setValueV3ui; // _VEC3 - case 0x8dc8: return setValueV4ui; // _VEC4 case 0x8b5e: // SAMPLER_2D - case 0x8d66: // SAMPLER_EXTERNAL_OES - case 0x8dca: // INT_SAMPLER_2D - case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D - case 0x8b62: // SAMPLER_2D_SHADOW return setValueT1; - case 0x8b5f: // SAMPLER_3D - case 0x8dcb: // INT_SAMPLER_3D - case 0x8dd3: // UNSIGNED_INT_SAMPLER_3D return setValueT3D1; - case 0x8b60: // SAMPLER_CUBE - case 0x8dcc: // INT_SAMPLER_CUBE - case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE - case 0x8dc5: // SAMPLER_CUBE_SHADOW return setValueT6; - case 0x8dc1: // SAMPLER_2D_ARRAY - case 0x8dcf: // INT_SAMPLER_2D_ARRAY - case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY - case 0x8dc4: // SAMPLER_2D_ARRAY_SHADOW return setValueT2DArray1; } - } // Array of scalars + } + // Array of scalars function setValueV1fArray(gl, v) { gl.uniform1fv(this.addr, v); - } // Array of vectors (from flat array or array of THREE.VectorN) + } + // Array of vectors (from flat array or array of THREE.VectorN) function setValueV2fArray(gl, v) { const data = flatten(v, this.size, 2); gl.uniform2fv(this.addr, data); } - function setValueV3fArray(gl, v) { const data = flatten(v, this.size, 3); gl.uniform3fv(this.addr, data); } - function setValueV4fArray(gl, v) { const data = flatten(v, this.size, 4); gl.uniform4fv(this.addr, data); - } // Array of matrices (from flat array or array of THREE.MatrixN) + } + // Array of matrices (from flat array or array of THREE.MatrixN) function setValueM2Array(gl, v) { const data = flatten(v, this.size, 4); gl.uniformMatrix2fv(this.addr, false, data); } - function setValueM3Array(gl, v) { const data = flatten(v, this.size, 9); gl.uniformMatrix3fv(this.addr, false, data); } - function setValueM4Array(gl, v) { const data = flatten(v, this.size, 16); gl.uniformMatrix4fv(this.addr, false, data); - } // Array of integer / boolean + } + // Array of integer / boolean function setValueV1iArray(gl, v) { gl.uniform1iv(this.addr, v); - } // Array of integer / boolean vectors (from flat array) + } + // Array of integer / boolean vectors (from flat array) function setValueV2iArray(gl, v) { gl.uniform2iv(this.addr, v); } - function setValueV3iArray(gl, v) { gl.uniform3iv(this.addr, v); } - function setValueV4iArray(gl, v) { gl.uniform4iv(this.addr, v); - } // Array of unsigned integer + } + // Array of unsigned integer function setValueV1uiArray(gl, v) { gl.uniform1uiv(this.addr, v); - } // Array of unsigned integer vectors (from flat array) + } + // Array of unsigned integer vectors (from flat array) function setValueV2uiArray(gl, v) { gl.uniform2uiv(this.addr, v); } - function setValueV3uiArray(gl, v) { gl.uniform3uiv(this.addr, v); } - function setValueV4uiArray(gl, v) { gl.uniform4uiv(this.addr, v); - } // Array of textures (2D / 3D / Cube / 2DArray) + } + // Array of textures (2D / 3D / Cube / 2DArray) function setValueT1Array(gl, v, textures) { + const cache = this.cache; const n = v.length; const units = allocTexUnits(textures, n); - gl.uniform1iv(this.addr, units); - + if (!arraysEqual(cache, units)) { + gl.uniform1iv(this.addr, units); + copyArray(cache, units); + } for (let i = 0; i !== n; ++i) { textures.setTexture2D(v[i] || emptyTexture, units[i]); } } - function setValueT3DArray(gl, v, textures) { + const cache = this.cache; const n = v.length; const units = allocTexUnits(textures, n); - gl.uniform1iv(this.addr, units); - + if (!arraysEqual(cache, units)) { + gl.uniform1iv(this.addr, units); + copyArray(cache, units); + } for (let i = 0; i !== n; ++i) { textures.setTexture3D(v[i] || empty3dTexture, units[i]); } } - function setValueT6Array(gl, v, textures) { + const cache = this.cache; const n = v.length; const units = allocTexUnits(textures, n); - gl.uniform1iv(this.addr, units); - + if (!arraysEqual(cache, units)) { + gl.uniform1iv(this.addr, units); + copyArray(cache, units); + } for (let i = 0; i !== n; ++i) { textures.setTextureCube(v[i] || emptyCubeTexture, units[i]); } } - function setValueT2DArrayArray(gl, v, textures) { + const cache = this.cache; const n = v.length; const units = allocTexUnits(textures, n); - gl.uniform1iv(this.addr, units); - + if (!arraysEqual(cache, units)) { + gl.uniform1iv(this.addr, units); + copyArray(cache, units); + } for (let i = 0; i !== n; ++i) { textures.setTexture2DArray(v[i] || emptyArrayTexture, units[i]); } - } // Helper to pick the right setter for a pure (bottom-level) array + } + // Helper to pick the right setter for a pure (bottom-level) array function getPureArraySetter(type) { switch (type) { case 0x1406: return setValueV1fArray; // FLOAT - case 0x8b50: return setValueV2fArray; // _VEC2 - case 0x8b51: return setValueV3fArray; // _VEC3 - case 0x8b52: return setValueV4fArray; // _VEC4 @@ -13593,11 +12042,9 @@ case 0x8b5a: return setValueM2Array; // _MAT2 - case 0x8b5b: return setValueM3Array; // _MAT3 - case 0x8b5c: return setValueM4Array; // _MAT4 @@ -13606,17 +12053,14 @@ case 0x8b56: return setValueV1iArray; // INT, BOOL - case 0x8b53: case 0x8b57: return setValueV2iArray; // _VEC2 - case 0x8b54: case 0x8b58: return setValueV3iArray; // _VEC3 - case 0x8b55: case 0x8b59: return setValueV4iArray; @@ -13625,70 +12069,54 @@ case 0x1405: return setValueV1uiArray; // UINT - case 0x8dc6: return setValueV2uiArray; // _VEC2 - case 0x8dc7: return setValueV3uiArray; // _VEC3 - case 0x8dc8: return setValueV4uiArray; // _VEC4 case 0x8b5e: // SAMPLER_2D - case 0x8d66: // SAMPLER_EXTERNAL_OES - case 0x8dca: // INT_SAMPLER_2D - case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D - case 0x8b62: // SAMPLER_2D_SHADOW return setValueT1Array; - case 0x8b5f: // SAMPLER_3D - case 0x8dcb: // INT_SAMPLER_3D - case 0x8dd3: // UNSIGNED_INT_SAMPLER_3D return setValueT3DArray; - case 0x8b60: // SAMPLER_CUBE - case 0x8dcc: // INT_SAMPLER_CUBE - case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE - case 0x8dc5: // SAMPLER_CUBE_SHADOW return setValueT6Array; - case 0x8dc1: // SAMPLER_2D_ARRAY - case 0x8dcf: // INT_SAMPLER_2D_ARRAY - case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY - case 0x8dc4: // SAMPLER_2D_ARRAY_SHADOW return setValueT2DArrayArray; } - } // --- Uniform Classes --- + } + // --- Uniform Classes --- class SingleUniform { constructor(id, activeInfo, addr) { this.id = id; this.addr = addr; this.cache = []; - this.setValue = getSingularSetter(activeInfo.type); // this.path = activeInfo.name; // DEBUG - } + this.setValue = getSingularSetter(activeInfo.type); + // this.path = activeInfo.name; // DEBUG + } } class PureArrayUniform { @@ -13697,9 +12125,10 @@ this.addr = addr; this.cache = []; this.size = activeInfo.size; - this.setValue = getPureArraySetter(activeInfo.type); // this.path = activeInfo.name; // DEBUG - } + this.setValue = getPureArraySetter(activeInfo.type); + // this.path = activeInfo.name; // DEBUG + } } class StructuredUniform { @@ -13708,21 +12137,22 @@ this.seq = []; this.map = {}; } - setValue(gl, value, textures) { const seq = this.seq; - for (let i = 0, n = seq.length; i !== n; ++i) { const u = seq[i]; u.setValue(gl, value[u.id], textures); } } + } + + // --- Top-level --- - } // --- Top-level --- // Parser - builds up the property tree from the path strings + const RePathPart = /(\w+)(\])?(\[|\.)?/g; - const RePathPart = /(\w+)(\])?(\[|\.)?/g; // extracts + // 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) @@ -13735,87 +12165,78 @@ container.seq.push(uniformObject); container.map[uniformObject.id] = uniformObject; } - function parseUniform(activeInfo, addr, container) { const path = activeInfo.name, - pathLength = path.length; // reset RegExp object, because of the early exit of a previous run + pathLength = path.length; + // reset RegExp object, because of the early exit of a previous run RePathPart.lastIndex = 0; - while (true) { const match = RePathPart.exec(path), - matchEnd = RePathPart.lastIndex; + matchEnd = RePathPart.lastIndex; let id = match[1]; const idIsIndex = match[2] === ']', - subscript = match[3]; + subscript = match[3]; if (idIsIndex) id = id | 0; // convert to integer 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 + const map = container.map; let next = map[id]; - if (next === undefined) { next = new StructuredUniform(id); addUniform(container, next); } - container = next; } } - } // Root Container + } + // Root Container class WebGLUniforms { constructor(gl, program) { this.seq = []; this.map = {}; const n = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); - for (let i = 0; i < n; ++i) { const info = gl.getActiveUniform(program, i), - addr = gl.getUniformLocation(program, info.name); + addr = gl.getUniformLocation(program, info.name); parseUniform(info, addr, this); } } - setValue(gl, name, value, textures) { const u = this.map[name]; if (u !== undefined) u.setValue(gl, value, textures); } - setOptional(gl, object, name) { const v = object[name]; if (v !== undefined) this.setValue(gl, name, v); } - static upload(gl, seq, values, textures) { for (let i = 0, n = seq.length; i !== n; ++i) { const u = seq[i], - v = values[u.id]; - + v = values[u.id]; if (v.needsUpdate !== false) { // note: always updating when .needsUpdate is undefined u.setValue(gl, v.value, textures); } } } - static seqWithValue(seq, values) { const r = []; - for (let i = 0, n = seq.length; i !== n; ++i) { const u = seq[i]; if (u.id in values) r.push(u); } - return r; } - } function WebGLShader(gl, type, string) { @@ -13826,116 +12247,96 @@ } let programIdCount = 0; - function handleSource(string, errorLine) { const lines = string.split('\n'); const lines2 = []; const from = Math.max(errorLine - 6, 0); const to = Math.min(errorLine + 6, lines.length); - for (let i = from; i < to; i++) { const line = i + 1; lines2.push(`${line === errorLine ? '>' : ' '} ${line}: ${lines[i]}`); } - return lines2.join('\n'); } - function getEncodingComponents(encoding) { switch (encoding) { case LinearEncoding: return ['Linear', '( value )']; - case sRGBEncoding: return ['sRGB', '( value )']; - default: console.warn('THREE.WebGLProgram: Unsupported encoding:', encoding); return ['Linear', '( value )']; } } - function getShaderErrors(gl, shader, type) { const status = gl.getShaderParameter(shader, gl.COMPILE_STATUS); const errors = gl.getShaderInfoLog(shader).trim(); if (status && errors === '') return ''; const errorMatches = /ERROR: 0:(\d+)/.exec(errors); - if (errorMatches) { // --enable-privileged-webgl-extension // console.log( '**' + type + '**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) ); + const errorLine = parseInt(errorMatches[1]); return type.toUpperCase() + '\n\n' + errors + '\n\n' + handleSource(gl.getShaderSource(shader), errorLine); } else { return errors; } } - function getTexelEncodingFunction(functionName, encoding) { const components = getEncodingComponents(encoding); return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[0] + components[1] + '; }'; } - function getToneMappingFunction(functionName, toneMapping) { let toneMappingName; - switch (toneMapping) { case LinearToneMapping: toneMappingName = 'Linear'; break; - case ReinhardToneMapping: toneMappingName = 'Reinhard'; break; - case CineonToneMapping: toneMappingName = 'OptimizedCineon'; break; - case ACESFilmicToneMapping: toneMappingName = 'ACESFilmic'; break; - case CustomToneMapping: toneMappingName = 'Custom'; break; - default: console.warn('THREE.WebGLProgram: Unsupported toneMapping:', toneMapping); toneMappingName = 'Linear'; } - return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }'; } - function generateExtensions(parameters) { const chunks = [parameters.extensionDerivatives || !!parameters.envMapCubeUVHeight || 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.transmission) && parameters.rendererExtensionShaderTextureLod ? '#extension GL_EXT_shader_texture_lod : enable' : '']; return chunks.filter(filterEmptyLine).join('\n'); } - function generateDefines(defines) { const chunks = []; - for (const name in defines) { const value = defines[name]; if (value === false) continue; chunks.push('#define ' + name + ' ' + value); } - return chunks.join('\n'); } - function fetchAttributeLocations(gl, program) { const attributes = {}; const n = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); - for (let i = 0; i < n; i++) { const info = gl.getActiveAttrib(program, i); const name = info.name; let locationSize = 1; if (info.type === gl.FLOAT_MAT2) locationSize = 2; if (info.type === gl.FLOAT_MAT3) locationSize = 3; - if (info.type === gl.FLOAT_MAT4) locationSize = 4; // console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i ); + if (info.type === gl.FLOAT_MAT4) locationSize = 4; + + // console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i ); attributes[name] = { type: info.type, @@ -13943,66 +12344,51 @@ locationSize: locationSize }; } - 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); + const numSpotLightCoords = parameters.numSpotLightShadows + parameters.numSpotLightMaps - parameters.numSpotLightShadowsWithMaps; + return string.replace(/NUM_DIR_LIGHTS/g, parameters.numDirLights).replace(/NUM_SPOT_LIGHTS/g, parameters.numSpotLights).replace(/NUM_SPOT_LIGHT_MAPS/g, parameters.numSpotLightMaps).replace(/NUM_SPOT_LIGHT_COORDS/g, numSpotLightCoords).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_WITH_MAPS/g, parameters.numSpotLightShadowsWithMaps).replace(/NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows).replace(/NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows); } - function replaceClippingPlaneNums(string, parameters) { return string.replace(/NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g, parameters.numClippingPlanes - parameters.numClipIntersection); - } // Resolve Includes + } + // Resolve Includes const includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm; - function resolveIncludes(string) { return string.replace(includePattern, includeReplacer); } - function includeReplacer(match, include) { const string = ShaderChunk[include]; - if (string === undefined) { throw new Error('Can not resolve #include <' + include + '>'); } - return resolveIncludes(string); - } // Unroll Loops + } + // Unroll Loops - const deprecatedUnrollLoopPattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g; const 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; - function unrollLoops(string) { - return string.replace(unrollLoopPattern, loopReplacer).replace(deprecatedUnrollLoopPattern, deprecatedLoopReplacer); - } - - 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 string.replace(unrollLoopPattern, loopReplacer); } - function loopReplacer(match, start, end, snippet) { let string = ''; - for (let i = parseInt(start); i < parseInt(end); i++) { string += snippet.replace(/\[\s*i\s*\]/g, '[ ' + i + ' ]').replace(/UNROLLED_LOOP_INDEX/g, i); } - return string; - } // + } + // function generatePrecision(parameters) { let precisionstring = 'precision ' + parameters.precision + ' float;\nprecision ' + parameters.precision + ' int;'; - if (parameters.precision === 'highp') { precisionstring += '\n#define HIGH_PRECISION'; } else if (parameters.precision === 'mediump') { @@ -14010,13 +12396,10 @@ } else if (parameters.precision === 'lowp') { precisionstring += '\n#define LOW_PRECISION'; } - return precisionstring; } - function generateShadowMapTypeDefine(parameters) { let shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC'; - if (parameters.shadowMapType === PCFShadowMap) { shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF'; } else if (parameters.shadowMapType === PCFSoftShadowMap) { @@ -14024,32 +12407,25 @@ } else if (parameters.shadowMapType === VSMShadowMap) { shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM'; } - return shadowMapTypeDefine; } - function generateEnvMapTypeDefine(parameters) { let envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; - if (parameters.envMap) { switch (parameters.envMapMode) { case CubeReflectionMapping: case CubeRefractionMapping: envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; break; - case CubeUVReflectionMapping: envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV'; break; } } - return envMapTypeDefine; } - function generateEnvMapModeDefine(parameters) { let envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; - if (parameters.envMap) { switch (parameters.envMapMode) { case CubeRefractionMapping: @@ -14057,32 +12433,25 @@ break; } } - return envMapModeDefine; } - function generateEnvMapBlendingDefine(parameters) { let envMapBlendingDefine = 'ENVMAP_BLENDING_NONE'; - if (parameters.envMap) { switch (parameters.combine) { case MultiplyOperation: envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; break; - case MixOperation: envMapBlendingDefine = 'ENVMAP_BLENDING_MIX'; break; - case AddOperation: envMapBlendingDefine = 'ENVMAP_BLENDING_ADD'; break; } } - return envMapBlendingDefine; } - function generateCubeUVSize(parameters) { const imageHeight = parameters.envMapCubeUVHeight; if (imageHeight === null) return null; @@ -14095,10 +12464,10 @@ maxMip }; } - function WebGLProgram(renderer, cacheKey, parameters, bindingStates) { // TODO Send this event to Three.js DevTools // console.log( 'WebGLProgram', cacheKey ); + const gl = renderer.getContext(); const defines = parameters.defines; let vertexShader = parameters.vertexShader; @@ -14113,26 +12482,23 @@ const program = gl.createProgram(); let prefixVertex, prefixFragment; let versionString = parameters.glslVersion ? '#version ' + parameters.glslVersion + '\n' : ''; - if (parameters.isRawShaderMaterial) { prefixVertex = [customDefines].filter(filterEmptyLine).join('\n'); - 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' : '', 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.iridescenceMap ? '#define USE_IRIDESCENCEMAP' : '', parameters.iridescenceThicknessMap ? '#define USE_IRIDESCENCE_THICKNESSMAP' : '', parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.specularIntensityMap ? '#define USE_SPECULARINTENSITYMAP' : '', parameters.specularColorMap ? '#define USE_SPECULARCOLORMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.transmission ? '#define USE_TRANSMISSION' : '', parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '', parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '', parameters.sheenColorMap ? '#define USE_SHEENCOLORMAP' : '', parameters.sheenRoughnessMap ? '#define USE_SHEENROUGHNESSMAP' : '', parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors ? '#define USE_COLOR' : '', parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '', parameters.vertexUvs ? '#define USE_UV' : '', parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '', parameters.flatShading ? '#define FLAT_SHADED' : '', parameters.skinning ? '#define USE_SKINNING' : '', parameters.morphTargets ? '#define USE_MORPHTARGETS' : '', parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '', parameters.morphColors && parameters.isWebGL2 ? '#define USE_MORPHCOLORS' : '', parameters.morphTargetsCount > 0 && parameters.isWebGL2 ? '#define MORPHTARGETS_TEXTURE' : '', parameters.morphTargetsCount > 0 && parameters.isWebGL2 ? '#define MORPHTARGETS_TEXTURE_STRIDE ' + parameters.morphTextureStride : '', parameters.morphTargetsCount > 0 && parameters.isWebGL2 ? '#define MORPHTARGETS_COUNT ' + parameters.morphTargetsCount : '', 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', '#if defined( USE_COLOR_ALPHA )', ' attribute vec4 color;', '#elif defined( USE_COLOR )', ' attribute vec3 color;', '#endif', '#if ( defined( USE_MORPHTARGETS ) && ! defined( MORPHTARGETS_TEXTURE ) )', ' 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.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 : '', envMapCubeUVSize ? '#define CUBEUV_TEXEL_WIDTH ' + envMapCubeUVSize.texelWidth : '', envMapCubeUVSize ? '#define CUBEUV_TEXEL_HEIGHT ' + envMapCubeUVSize.texelHeight : '', envMapCubeUVSize ? '#define CUBEUV_MAX_MIP ' + envMapCubeUVSize.maxMip + '.0' : '', 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.clearcoat ? '#define USE_CLEARCOAT' : '', parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.iridescence ? '#define USE_IRIDESCENCE' : '', parameters.iridescenceMap ? '#define USE_IRIDESCENCEMAP' : '', parameters.iridescenceThicknessMap ? '#define USE_IRIDESCENCE_THICKNESSMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.specularIntensityMap ? '#define USE_SPECULARINTENSITYMAP' : '', parameters.specularColorMap ? '#define USE_SPECULARCOLORMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.alphaTest ? '#define USE_ALPHATEST' : '', parameters.sheen ? '#define USE_SHEEN' : '', parameters.sheenColorMap ? '#define USE_SHEENCOLORMAP' : '', parameters.sheenRoughnessMap ? '#define USE_SHEENROUGHNESSMAP' : '', parameters.transmission ? '#define USE_TRANSMISSION' : '', parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '', parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '', parameters.decodeVideoTexture ? '#define DECODE_VIDEO_TEXTURE' : '', parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors || parameters.instancingColor ? '#define USE_COLOR' : '', parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '', 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' : '', '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' : '', parameters.opaque ? '#define OPAQUE' : '', ShaderChunk['encodings_pars_fragment'], // this code is required here because it is used by the various encoding/decoding function defined below + prefixFragment = [customExtensions, generatePrecision(parameters), '#define SHADER_NAME ' + parameters.shaderName, customDefines, 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 : '', envMapCubeUVSize ? '#define CUBEUV_TEXEL_WIDTH ' + envMapCubeUVSize.texelWidth : '', envMapCubeUVSize ? '#define CUBEUV_TEXEL_HEIGHT ' + envMapCubeUVSize.texelHeight : '', envMapCubeUVSize ? '#define CUBEUV_MAX_MIP ' + envMapCubeUVSize.maxMip + '.0' : '', 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.clearcoat ? '#define USE_CLEARCOAT' : '', parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.iridescence ? '#define USE_IRIDESCENCE' : '', parameters.iridescenceMap ? '#define USE_IRIDESCENCEMAP' : '', parameters.iridescenceThicknessMap ? '#define USE_IRIDESCENCE_THICKNESSMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.specularIntensityMap ? '#define USE_SPECULARINTENSITYMAP' : '', parameters.specularColorMap ? '#define USE_SPECULARCOLORMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.alphaTest ? '#define USE_ALPHATEST' : '', parameters.sheen ? '#define USE_SHEEN' : '', parameters.sheenColorMap ? '#define USE_SHEENCOLORMAP' : '', parameters.sheenRoughnessMap ? '#define USE_SHEENROUGHNESSMAP' : '', parameters.transmission ? '#define USE_TRANSMISSION' : '', parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '', parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '', parameters.decodeVideoTexture ? '#define DECODE_VIDEO_TEXTURE' : '', parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors || parameters.instancingColor ? '#define USE_COLOR' : '', parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '', 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' : '', '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' : '', parameters.opaque ? '#define OPAQUE' : '', ShaderChunk['encodings_pars_fragment'], + // this code is required here because it is used by the various encoding/decoding function defined below getTexelEncodingFunction('linearToOutputTexel', parameters.outputEncoding), parameters.useDepthPacking ? '#define DEPTH_PACKING ' + parameters.depthPacking : '', '\n'].filter(filterEmptyLine).join('\n'); } - vertexShader = resolveIncludes(vertexShader); vertexShader = replaceLightNums(vertexShader, parameters); vertexShader = replaceClippingPlaneNums(vertexShader, parameters); @@ -14141,22 +12507,25 @@ 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 = ['precision mediump sampler2DArray;', '#define attribute in', '#define varying out', '#define texture2D texture'].join('\n') + '\n' + prefixVertex; prefixFragment = ['#define varying in', parameters.glslVersion === GLSL3 ? '' : 'layout(location = 0) 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; } - const vertexGlsl = versionString + prefixVertex + vertexShader; - const fragmentGlsl = versionString + prefixFragment + fragmentShader; // console.log( '*VERTEX*', vertexGlsl ); + const fragmentGlsl = versionString + prefixFragment + fragmentShader; + + // console.log( '*VERTEX*', vertexGlsl ); // console.log( '*FRAGMENT*', fragmentGlsl ); const glVertexShader = WebGLShader(gl, gl.VERTEX_SHADER, vertexGlsl); const glFragmentShader = WebGLShader(gl, gl.FRAGMENT_SHADER, fragmentGlsl); gl.attachShader(program, glVertexShader); - gl.attachShader(program, glFragmentShader); // Force a particular attribute to index 0. + gl.attachShader(program, glFragmentShader); + + // Force a particular attribute to index 0. if (parameters.index0AttributeName !== undefined) { gl.bindAttribLocation(program, 0, parameters.index0AttributeName); @@ -14164,16 +12533,15 @@ // programs with morphTargets displace position out of attribute 0 gl.bindAttribLocation(program, 0, 'position'); } + gl.linkProgram(program); - gl.linkProgram(program); // check for link errors - + // check for link errors if (renderer.debug.checkShaderErrors) { const programLog = gl.getProgramInfoLog(program).trim(); const vertexLog = gl.getShaderInfoLog(glVertexShader).trim(); const fragmentLog = gl.getShaderInfoLog(glFragmentShader).trim(); let runnable = true; let haveDiagnostics = true; - if (gl.getProgramParameter(program, gl.LINK_STATUS) === false) { runnable = false; const vertexErrors = getShaderErrors(gl, glVertexShader, 'vertex'); @@ -14184,7 +12552,6 @@ } else if (vertexLog === '' || fragmentLog === '') { haveDiagnostics = false; } - if (haveDiagnostics) { this.diagnostics = { runnable: runnable, @@ -14199,43 +12566,46 @@ } }; } - } // Clean up + } + + // Clean up + // Crashes in iOS9 and iOS10. #18402 // gl.detachShader( program, glVertexShader ); // gl.detachShader( program, glFragmentShader ); - gl.deleteShader(glVertexShader); - gl.deleteShader(glFragmentShader); // set up caching for uniform locations + gl.deleteShader(glFragmentShader); - let cachedUniforms; + // set up caching for uniform locations + let cachedUniforms; this.getUniforms = function () { if (cachedUniforms === undefined) { cachedUniforms = new WebGLUniforms(gl, program); } - return cachedUniforms; - }; // set up caching for attribute locations + }; + // set up caching for attribute locations let cachedAttributes; - this.getAttributes = function () { if (cachedAttributes === undefined) { cachedAttributes = fetchAttributeLocations(gl, program); } - return cachedAttributes; - }; // free resource + }; + // free resource this.destroy = function () { bindingStates.releaseStatesOfProgram(this); gl.deleteProgram(program); this.program = undefined; - }; // + }; + // this.name = parameters.shaderName; this.id = programIdCount++; @@ -14248,98 +12618,76 @@ } let _id = 0; - class WebGLShaderCache { constructor() { this.shaderCache = new Map(); this.materialCache = new Map(); } - update(material) { const vertexShader = material.vertexShader; const fragmentShader = material.fragmentShader; - const vertexShaderStage = this._getShaderStage(vertexShader); - const fragmentShaderStage = this._getShaderStage(fragmentShader); - const materialShaders = this._getShaderCacheForMaterial(material); - if (materialShaders.has(vertexShaderStage) === false) { materialShaders.add(vertexShaderStage); vertexShaderStage.usedTimes++; } - if (materialShaders.has(fragmentShaderStage) === false) { materialShaders.add(fragmentShaderStage); fragmentShaderStage.usedTimes++; } - return this; } - remove(material) { const materialShaders = this.materialCache.get(material); - for (const shaderStage of materialShaders) { shaderStage.usedTimes--; if (shaderStage.usedTimes === 0) this.shaderCache.delete(shaderStage.code); } - this.materialCache.delete(material); return this; } - getVertexShaderID(material) { return this._getShaderStage(material.vertexShader).id; } - getFragmentShaderID(material) { return this._getShaderStage(material.fragmentShader).id; } - dispose() { this.shaderCache.clear(); this.materialCache.clear(); } - _getShaderCacheForMaterial(material) { const cache = this.materialCache; - - if (cache.has(material) === false) { - cache.set(material, new Set()); + let set = cache.get(material); + if (set === undefined) { + set = new Set(); + cache.set(material, set); } - - return cache.get(material); + return set; } - _getShaderStage(code) { const cache = this.shaderCache; - - if (cache.has(code) === false) { - const stage = new WebGLShaderStage(code); + let stage = cache.get(code); + if (stage === undefined) { + stage = new WebGLShaderStage(code); cache.set(code, stage); } - - return cache.get(code); + return stage; } - } - class WebGLShaderStage { constructor(code) { this.id = _id++; this.code = code; this.usedTimes = 0; } - } function WebGLPrograms(renderer, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping) { const _programLayers = new Layers(); - const _customShaders = new WebGLShaderCache(); - const programs = []; const isWebGL2 = capabilities.isWebGL2; const logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer; @@ -14362,35 +12710,37 @@ ShadowMaterial: 'shadow', SpriteMaterial: 'sprite' }; - function getParameters(material, lights, shadows, scene, object) { const fog = scene.fog; const geometry = object.geometry; const environment = material.isMeshStandardMaterial ? scene.environment : null; const envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || environment); const envMapCubeUVHeight = !!envMap && envMap.mapping === CubeUVReflectionMapping ? envMap.image.height : null; - const shaderID = shaderIDs[material.type]; // heuristics to create shader parameters according to lights in the scene + const shaderID = shaderIDs[material.type]; + + // heuristics to create shader parameters according to lights in the scene // (not to blow over maxLights budget) if (material.precision !== null) { precision = capabilities.getMaxPrecision(material.precision); - if (precision !== material.precision) { console.warn('THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.'); } - } // + } + // const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color; const morphTargetsCount = morphAttribute !== undefined ? morphAttribute.length : 0; let morphTextureStride = 0; if (geometry.morphAttributes.position !== undefined) morphTextureStride = 1; if (geometry.morphAttributes.normal !== undefined) morphTextureStride = 2; - if (geometry.morphAttributes.color !== undefined) morphTextureStride = 3; // + if (geometry.morphAttributes.color !== undefined) morphTextureStride = 3; + + // let vertexShader, fragmentShader; let customVertexShaderID, customFragmentShaderID; - if (shaderID) { const shader = ShaderLib[shaderID]; vertexShader = shader.vertexShader; @@ -14398,13 +12748,10 @@ } else { vertexShader = material.vertexShader; fragmentShader = material.fragmentShader; - _customShaders.update(material); - customVertexShaderID = _customShaders.getVertexShaderID(material); customFragmentShaderID = _customShaders.getFragmentShaderID(material); } - const currentRenderTarget = renderer.getRenderTarget(); const useAlphaTest = material.alphaTest > 0; const useClearcoat = material.clearcoat > 0; @@ -14482,11 +12829,13 @@ numDirLights: lights.directional.length, numPointLights: lights.point.length, numSpotLights: lights.spot.length, + numSpotLightMaps: lights.spotLightMap.length, numRectAreaLights: lights.rectArea.length, numHemiLights: lights.hemi.length, numDirLightShadows: lights.directionalShadowMap.length, numPointLightShadows: lights.pointShadowMap.length, numSpotLightShadows: lights.spotShadowMap.length, + numSpotLightShadowsWithMaps: lights.numSpotLightShadowsWithMaps, numClippingPlanes: clipping.numPlanes, numClipIntersection: clipping.numIntersection, dithering: material.dithering, @@ -14511,34 +12860,28 @@ }; return parameters; } - function getProgramCacheKey(parameters) { const array = []; - if (parameters.shaderID) { array.push(parameters.shaderID); } else { array.push(parameters.customVertexShaderID); array.push(parameters.customFragmentShaderID); } - if (parameters.defines !== undefined) { for (const name in parameters.defines) { array.push(name); array.push(parameters.defines[name]); } } - if (parameters.isRawShaderMaterial === false) { getProgramCacheKeyParameters(array, parameters); getProgramCacheKeyBooleans(array, parameters); array.push(renderer.outputEncoding); } - array.push(parameters.customProgramCacheKey); return array.join(); } - function getProgramCacheKeyParameters(array, parameters) { array.push(parameters.precision); array.push(parameters.outputEncoding); @@ -14553,21 +12896,21 @@ array.push(parameters.numDirLights); array.push(parameters.numPointLights); array.push(parameters.numSpotLights); + array.push(parameters.numSpotLightMaps); array.push(parameters.numHemiLights); array.push(parameters.numRectAreaLights); array.push(parameters.numDirLightShadows); array.push(parameters.numPointLightShadows); array.push(parameters.numSpotLightShadows); + array.push(parameters.numSpotLightShadowsWithMaps); array.push(parameters.shadowMapType); array.push(parameters.toneMapping); array.push(parameters.numClippingPlanes); array.push(parameters.numClipIntersection); array.push(parameters.depthPacking); } - function getProgramCacheKeyBooleans(array, parameters) { _programLayers.disableAll(); - if (parameters.isWebGL2) _programLayers.enable(0); if (parameters.supportsVertexTextures) _programLayers.enable(1); if (parameters.instancing) _programLayers.enable(2); @@ -14601,92 +12944,81 @@ if (parameters.vertexUvs) _programLayers.enable(30); if (parameters.vertexTangents) _programLayers.enable(31); if (parameters.uvsVertexOnly) _programLayers.enable(32); - if (parameters.fog) _programLayers.enable(33); array.push(_programLayers.mask); - _programLayers.disableAll(); - - if (parameters.useFog) _programLayers.enable(0); - if (parameters.flatShading) _programLayers.enable(1); - if (parameters.logarithmicDepthBuffer) _programLayers.enable(2); - if (parameters.skinning) _programLayers.enable(3); - if (parameters.morphTargets) _programLayers.enable(4); - if (parameters.morphNormals) _programLayers.enable(5); - if (parameters.morphColors) _programLayers.enable(6); - if (parameters.premultipliedAlpha) _programLayers.enable(7); - if (parameters.shadowMapEnabled) _programLayers.enable(8); - if (parameters.physicallyCorrectLights) _programLayers.enable(9); - if (parameters.doubleSided) _programLayers.enable(10); - if (parameters.flipSided) _programLayers.enable(11); - if (parameters.useDepthPacking) _programLayers.enable(12); - if (parameters.dithering) _programLayers.enable(13); - if (parameters.specularIntensityMap) _programLayers.enable(14); - if (parameters.specularColorMap) _programLayers.enable(15); - if (parameters.transmission) _programLayers.enable(16); - if (parameters.transmissionMap) _programLayers.enable(17); - if (parameters.thicknessMap) _programLayers.enable(18); - if (parameters.sheen) _programLayers.enable(19); - if (parameters.sheenColorMap) _programLayers.enable(20); - if (parameters.sheenRoughnessMap) _programLayers.enable(21); - if (parameters.decodeVideoTexture) _programLayers.enable(22); - if (parameters.opaque) _programLayers.enable(23); + if (parameters.fog) _programLayers.enable(0); + if (parameters.useFog) _programLayers.enable(1); + if (parameters.flatShading) _programLayers.enable(2); + if (parameters.logarithmicDepthBuffer) _programLayers.enable(3); + if (parameters.skinning) _programLayers.enable(4); + if (parameters.morphTargets) _programLayers.enable(5); + if (parameters.morphNormals) _programLayers.enable(6); + if (parameters.morphColors) _programLayers.enable(7); + if (parameters.premultipliedAlpha) _programLayers.enable(8); + if (parameters.shadowMapEnabled) _programLayers.enable(9); + if (parameters.physicallyCorrectLights) _programLayers.enable(10); + if (parameters.doubleSided) _programLayers.enable(11); + if (parameters.flipSided) _programLayers.enable(12); + if (parameters.useDepthPacking) _programLayers.enable(13); + if (parameters.dithering) _programLayers.enable(14); + if (parameters.specularIntensityMap) _programLayers.enable(15); + if (parameters.specularColorMap) _programLayers.enable(16); + if (parameters.transmission) _programLayers.enable(17); + if (parameters.transmissionMap) _programLayers.enable(18); + if (parameters.thicknessMap) _programLayers.enable(19); + if (parameters.sheen) _programLayers.enable(20); + if (parameters.sheenColorMap) _programLayers.enable(21); + if (parameters.sheenRoughnessMap) _programLayers.enable(22); + if (parameters.decodeVideoTexture) _programLayers.enable(23); + if (parameters.opaque) _programLayers.enable(24); array.push(_programLayers.mask); } - function getUniforms(material) { const shaderID = shaderIDs[material.type]; let uniforms; - if (shaderID) { const shader = ShaderLib[shaderID]; uniforms = UniformsUtils.clone(shader.uniforms); } else { uniforms = material.uniforms; } - return uniforms; } - function acquireProgram(parameters, cacheKey) { - let program; // Check if code has been already compiled + let program; + // Check if code has been already compiled for (let p = 0, pl = programs.length; p < pl; p++) { const preexistingProgram = programs[p]; - if (preexistingProgram.cacheKey === cacheKey) { program = preexistingProgram; ++program.usedTimes; break; } } - if (program === undefined) { program = new WebGLProgram(renderer, cacheKey, parameters, bindingStates); programs.push(program); } - return program; } - function releaseProgram(program) { if (--program.usedTimes === 0) { // Remove from unordered set const i = programs.indexOf(program); programs[i] = programs[programs.length - 1]; - programs.pop(); // Free WebGL resources + programs.pop(); + // Free WebGL resources program.destroy(); } } - function releaseShaderCache(material) { _customShaders.remove(material); } - function dispose() { _customShaders.dispose(); } - return { getParameters: getParameters, getProgramCacheKey: getProgramCacheKey, @@ -14702,30 +13034,23 @@ function WebGLProperties() { let properties = new WeakMap(); - function get(object) { let map = properties.get(object); - if (map === undefined) { map = {}; properties.set(object, map); } - return map; } - function remove(object) { properties.delete(object); } - function update(object, key, value) { properties.get(object)[key] = value; } - function dispose() { properties = new WeakMap(); } - return { get: get, remove: remove, @@ -14747,7 +13072,6 @@ return a.id - b.id; } } - function reversePainterSortStable(a, b) { if (a.groupOrder !== b.groupOrder) { return a.groupOrder - b.groupOrder; @@ -14759,24 +13083,20 @@ return a.id - b.id; } } - function WebGLRenderList() { const renderItems = []; let renderItemsIndex = 0; const opaque = []; const transmissive = []; const transparent = []; - function init() { renderItemsIndex = 0; opaque.length = 0; transmissive.length = 0; transparent.length = 0; } - function getNextRenderItem(object, geometry, material, groupOrder, z, group) { let renderItem = renderItems[renderItemsIndex]; - if (renderItem === undefined) { renderItem = { id: object.id, @@ -14799,14 +13119,11 @@ renderItem.z = z; renderItem.group = group; } - renderItemsIndex++; return renderItem; } - function push(object, geometry, material, groupOrder, z, group) { const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group); - if (material.transmission > 0.0) { transmissive.push(renderItem); } else if (material.transparent === true) { @@ -14815,10 +13132,8 @@ opaque.push(renderItem); } } - function unshift(object, geometry, material, groupOrder, z, group) { const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group); - if (material.transmission > 0.0) { transmissive.unshift(renderItem); } else if (material.transparent === true) { @@ -14827,15 +13142,14 @@ opaque.unshift(renderItem); } } - function sort(customOpaqueSort, customTransparentSort) { if (opaque.length > 1) opaque.sort(customOpaqueSort || painterSortStable); if (transmissive.length > 1) transmissive.sort(customTransparentSort || reversePainterSortStable); if (transparent.length > 1) transparent.sort(customTransparentSort || reversePainterSortStable); } - function finish() { // Clear references from inactive renderItems in the list + for (let i = renderItemsIndex, il = renderItems.length; i < il; i++) { const renderItem = renderItems[i]; if (renderItem.id === null) break; @@ -14846,7 +13160,6 @@ renderItem.group = null; } } - return { opaque: opaque, transmissive: transmissive, @@ -14858,32 +13171,27 @@ sort: sort }; } - function WebGLRenderLists() { let lists = new WeakMap(); - function get(scene, renderCallDepth) { + const listArray = lists.get(scene); let list; - - if (lists.has(scene) === false) { + if (listArray === undefined) { list = new WebGLRenderList(); lists.set(scene, [list]); } else { - if (renderCallDepth >= lists.get(scene).length) { + if (renderCallDepth >= listArray.length) { list = new WebGLRenderList(); - lists.get(scene).push(list); + listArray.push(list); } else { - list = lists.get(scene)[renderCallDepth]; + list = listArray[renderCallDepth]; } } - return list; } - function dispose() { lists = new WeakMap(); } - return { get: get, dispose: dispose @@ -14897,9 +13205,7 @@ if (lights[light.id] !== undefined) { return lights[light.id]; } - let uniforms; - switch (light.type) { case 'DirectionalLight': uniforms = { @@ -14907,7 +13213,6 @@ color: new Color() }; break; - case 'SpotLight': uniforms = { position: new Vector3(), @@ -14919,7 +13224,6 @@ decay: 0 }; break; - case 'PointLight': uniforms = { position: new Vector3(), @@ -14928,7 +13232,6 @@ decay: 0 }; break; - case 'HemisphereLight': uniforms = { direction: new Vector3(), @@ -14936,7 +13239,6 @@ groundColor: new Color() }; break; - case 'RectAreaLight': uniforms = { color: new Color(), @@ -14946,13 +13248,11 @@ }; break; } - lights[light.id] = uniforms; return uniforms; } }; } - function ShadowUniformsCache() { const lights = {}; return { @@ -14960,9 +13260,7 @@ if (lights[light.id] !== undefined) { return lights[light.id]; } - let uniforms; - switch (light.type) { case 'DirectionalLight': uniforms = { @@ -14972,7 +13270,6 @@ shadowMapSize: new Vector2() }; break; - case 'SpotLight': uniforms = { shadowBias: 0, @@ -14981,7 +13278,6 @@ shadowMapSize: new Vector2() }; break; - case 'PointLight': uniforms = { shadowBias: 0, @@ -14992,6 +13288,7 @@ shadowCameraFar: 1000 }; break; + // TODO (abelnation): set RectAreaLight shadow uniforms } @@ -15000,13 +13297,10 @@ } }; } - let nextVersion = 0; - - function shadowCastingLightsFirst(lightA, lightB) { - return (lightB.castShadow ? 1 : 0) - (lightA.castShadow ? 1 : 0); + function shadowCastingAndTexturingLightsFirst(lightA, lightB) { + return (lightB.castShadow ? 2 : 0) - (lightA.castShadow ? 2 : 0) + (lightB.map ? 1 : 0) - (lightA.map ? 1 : 0); } - function WebGLLights(extensions, capabilities) { const cache = new UniformsCache(); const shadowCache = ShadowUniformsCache(); @@ -15020,7 +13314,8 @@ hemiLength: -1, numDirectionalShadows: -1, numPointShadows: -1, - numSpotShadows: -1 + numSpotShadows: -1, + numSpotMaps: -1 }, ambient: [0, 0, 0], probe: [], @@ -15029,9 +13324,10 @@ directionalShadowMap: [], directionalShadowMatrix: [], spot: [], + spotLightMap: [], spotShadow: [], spotShadowMap: [], - spotShadowMatrix: [], + spotLightMatrix: [], rectArea: [], rectAreaLTC1: null, rectAreaLTC2: null, @@ -15039,22 +13335,18 @@ pointShadow: [], pointShadowMap: [], pointShadowMatrix: [], - hemi: [] + hemi: [], + numSpotLightShadowsWithMaps: 0 }; - for (let i = 0; i < 9; i++) state.probe.push(new Vector3()); - const vector3 = new Vector3(); const matrix4 = new Matrix4(); const matrix42 = new Matrix4(); - function setup(lights, physicallyCorrectLights) { let r = 0, - g = 0, - b = 0; - + g = 0, + b = 0; for (let i = 0; i < 9; i++) state.probe[i].set(0, 0, 0); - let directionalLength = 0; let pointLength = 0; let spotLength = 0; @@ -15063,17 +13355,20 @@ let numDirectionalShadows = 0; let numPointShadows = 0; let numSpotShadows = 0; - lights.sort(shadowCastingLightsFirst); // artist-friendly light intensity scaling factor + let numSpotMaps = 0; + let numSpotShadowsWithMaps = 0; - const scaleFactor = physicallyCorrectLights !== true ? Math.PI : 1; + // ordering : [shadow casting + map texturing, map texturing, shadow casting, none ] + lights.sort(shadowCastingAndTexturingLightsFirst); + // artist-friendly light intensity scaling factor + const scaleFactor = physicallyCorrectLights !== true ? Math.PI : 1; for (let i = 0, l = lights.length; i < l; i++) { const light = lights[i]; const color = light.color; const intensity = light.intensity; const distance = light.distance; const shadowMap = light.shadow && light.shadow.map ? light.shadow.map.texture : null; - if (light.isAmbientLight) { r += color.r * intensity * scaleFactor; g += color.g * intensity * scaleFactor; @@ -15085,7 +13380,6 @@ } else if (light.isDirectionalLight) { const uniforms = cache.get(light); uniforms.color.copy(light.color).multiplyScalar(light.intensity * scaleFactor); - if (light.castShadow) { const shadow = light.shadow; const shadowUniforms = shadowCache.get(light); @@ -15098,7 +13392,6 @@ state.directionalShadowMatrix[directionalLength] = light.shadow.matrix; numDirectionalShadows++; } - state.directional[directionalLength] = uniforms; directionalLength++; } else if (light.isSpotLight) { @@ -15109,9 +13402,19 @@ uniforms.coneCos = Math.cos(light.angle); uniforms.penumbraCos = Math.cos(light.angle * (1 - light.penumbra)); uniforms.decay = light.decay; - + state.spot[spotLength] = uniforms; + const shadow = light.shadow; + if (light.map) { + state.spotLightMap[numSpotMaps] = light.map; + numSpotMaps++; + + // make sure the lightMatrix is up to date + // TODO : do it if required only + shadow.updateMatrices(light); + if (light.castShadow) numSpotShadowsWithMaps++; + } + state.spotLightMatrix[spotLength] = shadow.matrix; if (light.castShadow) { - const shadow = light.shadow; const shadowUniforms = shadowCache.get(light); shadowUniforms.shadowBias = shadow.bias; shadowUniforms.shadowNormalBias = shadow.normalBias; @@ -15119,17 +13422,11 @@ shadowUniforms.shadowMapSize = shadow.mapSize; state.spotShadow[spotLength] = shadowUniforms; state.spotShadowMap[spotLength] = shadowMap; - state.spotShadowMatrix[spotLength] = light.shadow.matrix; numSpotShadows++; } - - state.spot[spotLength] = uniforms; spotLength++; } else if (light.isRectAreaLight) { - const uniforms = 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 - + const uniforms = cache.get(light); uniforms.color.copy(color).multiplyScalar(intensity); uniforms.halfWidth.set(light.width * 0.5, 0.0, 0.0); uniforms.halfHeight.set(0.0, light.height * 0.5, 0.0); @@ -15140,7 +13437,6 @@ uniforms.color.copy(light.color).multiplyScalar(light.intensity * scaleFactor); uniforms.distance = light.distance; uniforms.decay = light.decay; - if (light.castShadow) { const shadow = light.shadow; const shadowUniforms = shadowCache.get(light); @@ -15155,7 +13451,6 @@ state.pointShadowMatrix[pointLength] = light.shadow.matrix; numPointShadows++; } - state.point[pointLength] = uniforms; pointLength++; } else if (light.isHemisphereLight) { @@ -15166,14 +13461,15 @@ hemiLength++; } } - 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; @@ -15185,13 +13481,11 @@ } } } - state.ambient[0] = r; state.ambient[1] = g; state.ambient[2] = b; const 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) { + 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 || hash.numSpotMaps !== numSpotMaps) { state.directional.length = directionalLength; state.spot.length = spotLength; state.rectArea.length = rectAreaLength; @@ -15205,7 +13499,9 @@ state.spotShadowMap.length = numSpotShadows; state.directionalShadowMatrix.length = numDirectionalShadows; state.pointShadowMatrix.length = numPointShadows; - state.spotShadowMatrix.length = numSpotShadows; + state.spotLightMatrix.length = numSpotShadows + numSpotMaps - numSpotShadowsWithMaps; + state.spotLightMap.length = numSpotMaps; + state.numSpotLightShadowsWithMaps = numSpotShadowsWithMaps; hash.directionalLength = directionalLength; hash.pointLength = pointLength; hash.spotLength = spotLength; @@ -15214,10 +13510,10 @@ hash.numDirectionalShadows = numDirectionalShadows; hash.numPointShadows = numPointShadows; hash.numSpotShadows = numSpotShadows; + hash.numSpotMaps = numSpotMaps; state.version = nextVersion++; } } - function setupView(lights, camera) { let directionalLength = 0; let pointLength = 0; @@ -15225,10 +13521,8 @@ let rectAreaLength = 0; let hemiLength = 0; const viewMatrix = camera.matrixWorldInverse; - for (let i = 0, l = lights.length; i < l; i++) { const light = lights[i]; - if (light.isDirectionalLight) { const uniforms = state.directional[directionalLength]; uniforms.direction.setFromMatrixPosition(light.matrixWorld); @@ -15248,8 +13542,9 @@ } else if (light.isRectAreaLight) { const uniforms = state.rectArea[rectAreaLength]; uniforms.position.setFromMatrixPosition(light.matrixWorld); - uniforms.position.applyMatrix4(viewMatrix); // extract local rotation of light to derive width/height half vectors + uniforms.position.applyMatrix4(viewMatrix); + // extract local rotation of light to derive width/height half vectors matrix42.identity(); matrix4.copy(light.matrixWorld); matrix4.premultiply(viewMatrix); @@ -15272,7 +13567,6 @@ } } } - return { setup: setup, setupView: setupView, @@ -15284,28 +13578,22 @@ const lights = new WebGLLights(extensions, capabilities); const lightsArray = []; const shadowsArray = []; - function init() { lightsArray.length = 0; shadowsArray.length = 0; } - function pushLight(light) { lightsArray.push(light); } - function pushShadow(shadowLight) { shadowsArray.push(shadowLight); } - function setupLights(physicallyCorrectLights) { lights.setup(lightsArray, physicallyCorrectLights); } - function setupLightsView(camera) { lights.setupView(lightsArray, camera); } - const state = { lightsArray: lightsArray, shadowsArray: shadowsArray, @@ -15320,32 +13608,27 @@ pushShadow: pushShadow }; } - function WebGLRenderStates(extensions, capabilities) { let renderStates = new WeakMap(); - function get(scene, renderCallDepth = 0) { + const renderStateArray = renderStates.get(scene); let renderState; - - if (renderStates.has(scene) === false) { + if (renderStateArray === undefined) { renderState = new WebGLRenderState(extensions, capabilities); renderStates.set(scene, [renderState]); } else { - if (renderCallDepth >= renderStates.get(scene).length) { + if (renderCallDepth >= renderStateArray.length) { renderState = new WebGLRenderState(extensions, capabilities); - renderStates.get(scene).push(renderState); + renderStateArray.push(renderState); } else { - renderState = renderStates.get(scene)[renderCallDepth]; + renderState = renderStateArray[renderCallDepth]; } } - return renderState; } - function dispose() { renderStates = new WeakMap(); } - return { get: get, dispose: dispose @@ -15367,7 +13650,6 @@ this.wireframeLinewidth = 1; this.setValues(parameters); } - copy(source) { super.copy(source); this.depthPacking = source.depthPacking; @@ -15380,7 +13662,6 @@ this.wireframeLinewidth = source.wireframeLinewidth; return this; } - } class MeshDistanceMaterial extends Material { @@ -15398,7 +13679,6 @@ this.displacementBias = 0; this.setValues(parameters); } - copy(source) { super.copy(source); this.referencePosition.copy(source.referencePosition); @@ -15411,7 +13691,6 @@ this.displacementBias = source.displacementBias; return this; } - } const vertex = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}"; @@ -15419,17 +13698,15 @@ function WebGLShadowMap(_renderer, _objects, _capabilities) { let _frustum = new Frustum(); - const _shadowMapSize = new Vector2(), - _viewportSize = new Vector2(), - _viewport = new Vector4(), - _depthMaterial = new MeshDepthMaterial({ - depthPacking: RGBADepthPacking - }), - _distanceMaterial = new MeshDistanceMaterial(), - _materialCache = {}, - _maxTextureSize = _capabilities.maxTextureSize; - + _viewportSize = new Vector2(), + _viewport = new Vector4(), + _depthMaterial = new MeshDepthMaterial({ + depthPacking: RGBADepthPacking + }), + _distanceMaterial = new MeshDistanceMaterial(), + _materialCache = {}, + _maxTextureSize = _capabilities.maxTextureSize; const shadowSide = { 0: BackSide, 1: FrontSide, @@ -15463,62 +13740,47 @@ this.autoUpdate = true; this.needsUpdate = false; this.type = PCFShadowMap; - this.render = function (lights, scene, camera) { if (scope.enabled === false) return; if (scope.autoUpdate === false && scope.needsUpdate === false) return; if (lights.length === 0) return; - const currentRenderTarget = _renderer.getRenderTarget(); - const activeCubeFace = _renderer.getActiveCubeFace(); - const activeMipmapLevel = _renderer.getActiveMipmapLevel(); + const _state = _renderer.state; - const _state = _renderer.state; // Set GL state for depth map. - + // Set GL state for depth map. _state.setBlending(NoBlending); - _state.buffers.color.setClear(1, 1, 1, 1); - _state.buffers.depth.setTest(true); + _state.setScissorTest(false); - _state.setScissorTest(false); // render depth map - + // render depth map for (let i = 0, il = lights.length; i < il; i++) { const light = lights[i]; const shadow = light.shadow; - if (shadow === undefined) { console.warn('THREE.WebGLShadowMap:', light, 'has no shadow.'); continue; } - if (shadow.autoUpdate === false && shadow.needsUpdate === false) continue; - _shadowMapSize.copy(shadow.mapSize); - const shadowFrameExtents = shadow.getFrameExtents(); - _shadowMapSize.multiply(shadowFrameExtents); - _viewportSize.copy(shadow.mapSize); - 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 (_shadowMapSize.y > _maxTextureSize) { _viewportSize.y = Math.floor(_maxTextureSize / shadowFrameExtents.y); _shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y; shadow.mapSize.y = _viewportSize.y; } } - if (shadow.map === null) { const pars = this.type !== VSMShadowMap ? { minFilter: NearestFilter, @@ -15528,118 +13790,94 @@ shadow.map.texture.name = light.name + '.shadowMap'; shadow.camera.updateProjectionMatrix(); } - _renderer.setRenderTarget(shadow.map); - _renderer.clear(); - const viewportCount = shadow.getViewportCount(); - for (let vp = 0; vp < viewportCount; vp++) { const viewport = shadow.getViewport(vp); - _viewport.set(_viewportSize.x * viewport.x, _viewportSize.y * viewport.y, _viewportSize.x * viewport.z, _viewportSize.y * viewport.w); - _state.viewport(_viewport); - shadow.updateMatrices(light, vp); _frustum = shadow.getFrustum(); renderObject(scene, camera, shadow.camera, light, this.type); - } // do blur pass for VSM + } + // do blur pass for VSM if (shadow.isPointLightShadow !== true && this.type === VSMShadowMap) { VSMPass(shadow, camera); } - shadow.needsUpdate = false; } - scope.needsUpdate = false; - _renderer.setRenderTarget(currentRenderTarget, activeCubeFace, activeMipmapLevel); }; - function VSMPass(shadow, camera) { const geometry = _objects.update(fullScreenMesh); - if (shadowMaterialVertical.defines.VSM_SAMPLES !== shadow.blurSamples) { shadowMaterialVertical.defines.VSM_SAMPLES = shadow.blurSamples; shadowMaterialHorizontal.defines.VSM_SAMPLES = shadow.blurSamples; shadowMaterialVertical.needsUpdate = true; shadowMaterialHorizontal.needsUpdate = true; } - if (shadow.mapPass === null) { shadow.mapPass = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y); - } // vertical pass + } + // vertical pass shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture; shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize; shadowMaterialVertical.uniforms.radius.value = shadow.radius; - _renderer.setRenderTarget(shadow.mapPass); - _renderer.clear(); + _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null); - _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null); // horizontal pass - + // horizontal pass shadowMaterialHorizontal.uniforms.shadow_pass.value = shadow.mapPass.texture; shadowMaterialHorizontal.uniforms.resolution.value = shadow.mapSize; shadowMaterialHorizontal.uniforms.radius.value = shadow.radius; - _renderer.setRenderTarget(shadow.map); - _renderer.clear(); - _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialHorizontal, fullScreenMesh, null); } - function getDepthMaterial(object, material, light, shadowCameraNear, shadowCameraFar, type) { let result = null; const customMaterial = light.isPointLight === true ? object.customDistanceMaterial : object.customDepthMaterial; - if (customMaterial !== undefined) { result = customMaterial; } else { result = light.isPointLight === true ? _distanceMaterial : _depthMaterial; } - - if (_renderer.localClippingEnabled && material.clipShadows === true && Array.isArray(material.clippingPlanes) && material.clippingPlanes.length !== 0 || material.displacementMap && material.displacementScale !== 0 || material.alphaMap && material.alphaTest > 0) { + if (_renderer.localClippingEnabled && material.clipShadows === true && Array.isArray(material.clippingPlanes) && material.clippingPlanes.length !== 0 || material.displacementMap && material.displacementScale !== 0 || material.alphaMap && material.alphaTest > 0 || material.map && material.alphaTest > 0) { // in this case we need a unique material instance reflecting the // appropriate state + const keyA = result.uuid, - keyB = material.uuid; + keyB = material.uuid; let materialsForVariant = _materialCache[keyA]; - if (materialsForVariant === undefined) { materialsForVariant = {}; _materialCache[keyA] = materialsForVariant; } - let cachedMaterial = materialsForVariant[keyB]; - if (cachedMaterial === undefined) { cachedMaterial = result.clone(); materialsForVariant[keyB] = cachedMaterial; } - result = cachedMaterial; } - result.visible = material.visible; result.wireframe = material.wireframe; - if (type === VSMShadowMap) { result.side = material.shadowSide !== null ? material.shadowSide : material.side; } else { result.side = material.shadowSide !== null ? material.shadowSide : shadowSide[material.side]; } - result.alphaMap = material.alphaMap; result.alphaTest = material.alphaTest; + result.map = material.map; result.clipShadows = material.clipShadows; result.clippingPlanes = material.clippingPlanes; result.clipIntersection = material.clipIntersection; @@ -15648,51 +13886,38 @@ result.displacementBias = material.displacementBias; result.wireframeLinewidth = material.wireframeLinewidth; result.linewidth = material.linewidth; - if (light.isPointLight === true && result.isMeshDistanceMaterial === true) { result.referencePosition.setFromMatrixPosition(light.matrixWorld); result.nearDistance = shadowCameraNear; result.farDistance = shadowCameraFar; } - return result; } - function renderObject(object, camera, shadowCamera, light, type) { if (object.visible === false) return; const visible = object.layers.test(camera.layers); - 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); - const geometry = _objects.update(object); - const material = object.material; - if (Array.isArray(material)) { const groups = geometry.groups; - for (let k = 0, kl = groups.length; k < kl; k++) { const group = groups[k]; const groupMaterial = material[group.materialIndex]; - if (groupMaterial && groupMaterial.visible) { const depthMaterial = getDepthMaterial(object, groupMaterial, light, shadowCamera.near, shadowCamera.far, type); - _renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, group); } } } else if (material.visible) { const depthMaterial = getDepthMaterial(object, material, light, shadowCamera.near, shadowCamera.far, type); - _renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, null); } } } - const children = object.children; - for (let i = 0, l = children.length; i < l; i++) { renderObject(children[i], camera, shadowCamera, light, type); } @@ -15701,7 +13926,6 @@ function WebGLState(gl, extensions, capabilities) { const isWebGL2 = capabilities.isWebGL2; - function ColorBuffer() { let locked = false; const color = new Vector4(); @@ -15723,9 +13947,7 @@ g *= a; b *= a; } - color.set(r, g, b, a); - if (currentColorClear.equals(color) === false) { gl.clearColor(r, g, b, a); currentColorClear.copy(color); @@ -15760,47 +13982,34 @@ }, setFunc: function (depthFunc) { if (currentDepthFunc !== depthFunc) { - if (depthFunc) { - switch (depthFunc) { - case NeverDepth: - gl.depthFunc(gl.NEVER); - break; - - case AlwaysDepth: - gl.depthFunc(gl.ALWAYS); - break; - - case LessDepth: - gl.depthFunc(gl.LESS); - break; - - case LessEqualDepth: - gl.depthFunc(gl.LEQUAL); - break; - - case EqualDepth: - gl.depthFunc(gl.EQUAL); - break; - - case GreaterEqualDepth: - gl.depthFunc(gl.GEQUAL); - break; - - case GreaterDepth: - gl.depthFunc(gl.GREATER); - break; - - case NotEqualDepth: - gl.depthFunc(gl.NOTEQUAL); - break; - - default: - gl.depthFunc(gl.LEQUAL); - } - } else { - gl.depthFunc(gl.LEQUAL); + switch (depthFunc) { + case NeverDepth: + gl.depthFunc(gl.NEVER); + break; + case AlwaysDepth: + gl.depthFunc(gl.ALWAYS); + break; + case LessDepth: + gl.depthFunc(gl.LESS); + break; + case LessEqualDepth: + gl.depthFunc(gl.LEQUAL); + break; + case EqualDepth: + gl.depthFunc(gl.EQUAL); + break; + case GreaterEqualDepth: + gl.depthFunc(gl.GEQUAL); + break; + case GreaterDepth: + gl.depthFunc(gl.GREATER); + break; + case NotEqualDepth: + gl.depthFunc(gl.NOTEQUAL); + break; + default: + gl.depthFunc(gl.LEQUAL); } - currentDepthFunc = depthFunc; } }, @@ -15821,7 +14030,6 @@ } }; } - function StencilBuffer() { let locked = false; let currentStencilMask = null; @@ -15885,8 +14093,9 @@ currentStencilClear = null; } }; - } // + } + // const colorBuffer = new ColorBuffer(); const depthBuffer = new DepthBuffer(); @@ -15916,7 +14125,6 @@ let lineWidthAvailable = false; let version = 0; const glVersion = gl.getParameter(gl.VERSION); - if (glVersion.indexOf('WebGL') !== -1) { version = parseFloat(/^WebGL (\d)/.exec(glVersion)[1]); lineWidthAvailable = version >= 1.0; @@ -15924,32 +14132,28 @@ version = parseFloat(/^OpenGL ES (\d)/.exec(glVersion)[1]); lineWidthAvailable = version >= 2.0; } - let currentTextureSlot = null; let currentBoundTextures = {}; const scissorParam = gl.getParameter(gl.SCISSOR_BOX); const viewportParam = gl.getParameter(gl.VIEWPORT); const currentScissor = new Vector4().fromArray(scissorParam); const currentViewport = new Vector4().fromArray(viewportParam); - function createTexture(type, target, count) { const data = new Uint8Array(4); // 4 is required to match default unpack alignment of 4. - const texture = gl.createTexture(); gl.bindTexture(type, texture); gl.texParameteri(type, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(type, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - for (let i = 0; i < count; i++) { gl.texImage2D(target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data); } - return texture; } - const emptyTextures = {}; emptyTextures[gl.TEXTURE_2D] = createTexture(gl.TEXTURE_2D, gl.TEXTURE_2D, 1); - emptyTextures[gl.TEXTURE_CUBE_MAP] = createTexture(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6); // init + emptyTextures[gl.TEXTURE_CUBE_MAP] = createTexture(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6); + + // init colorBuffer.setClear(0, 0, 0, 1); depthBuffer.setClear(1); @@ -15959,7 +14163,9 @@ setFlipSided(false); setCullFace(CullFaceBack); enable(gl.CULL_FACE); - setBlending(NoBlending); // + setBlending(NoBlending); + + // function enable(id) { if (enabledCapabilities[id] !== true) { @@ -15967,56 +14173,45 @@ enabledCapabilities[id] = true; } } - function disable(id) { if (enabledCapabilities[id] !== false) { gl.disable(id); enabledCapabilities[id] = false; } } - function bindFramebuffer(target, framebuffer) { if (currentBoundFramebuffers[target] !== framebuffer) { gl.bindFramebuffer(target, framebuffer); currentBoundFramebuffers[target] = framebuffer; - if (isWebGL2) { // gl.DRAW_FRAMEBUFFER is equivalent to gl.FRAMEBUFFER + if (target === gl.DRAW_FRAMEBUFFER) { currentBoundFramebuffers[gl.FRAMEBUFFER] = framebuffer; } - if (target === gl.FRAMEBUFFER) { currentBoundFramebuffers[gl.DRAW_FRAMEBUFFER] = framebuffer; } } - return true; } - return false; } - function drawBuffers(renderTarget, framebuffer) { let drawBuffers = defaultDrawbuffers; let needsUpdate = false; - if (renderTarget) { drawBuffers = currentDrawbuffers.get(framebuffer); - if (drawBuffers === undefined) { drawBuffers = []; currentDrawbuffers.set(framebuffer, drawBuffers); } - if (renderTarget.isWebGLMultipleRenderTargets) { const textures = renderTarget.texture; - if (drawBuffers.length !== textures.length || drawBuffers[0] !== gl.COLOR_ATTACHMENT0) { for (let i = 0, il = textures.length; i < il; i++) { drawBuffers[i] = gl.COLOR_ATTACHMENT0 + i; } - drawBuffers.length = textures.length; needsUpdate = true; } @@ -16032,7 +14227,6 @@ needsUpdate = true; } } - if (needsUpdate) { if (capabilities.isWebGL2) { gl.drawBuffers(drawBuffers); @@ -16041,35 +14235,29 @@ } } } - function useProgram(program) { if (currentProgram !== program) { gl.useProgram(program); currentProgram = program; return true; } - return false; } - const equationToGL = { [AddEquation]: gl.FUNC_ADD, [SubtractEquation]: gl.FUNC_SUBTRACT, [ReverseSubtractEquation]: gl.FUNC_REVERSE_SUBTRACT }; - if (isWebGL2) { equationToGL[MinEquation] = gl.MIN; equationToGL[MaxEquation] = gl.MAX; } else { const extension = extensions.get('EXT_blend_minmax'); - if (extension !== null) { equationToGL[MinEquation] = extension.MIN_EXT; equationToGL[MaxEquation] = extension.MAX_EXT; } } - const factorToGL = { [ZeroFactor]: gl.ZERO, [OneFactor]: gl.ONE, @@ -16083,22 +14271,18 @@ [OneMinusDstColorFactor]: gl.ONE_MINUS_DST_COLOR, [OneMinusDstAlphaFactor]: gl.ONE_MINUS_DST_ALPHA }; - function setBlending(blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha) { if (blending === NoBlending) { if (currentBlendingEnabled === true) { disable(gl.BLEND); currentBlendingEnabled = false; } - return; } - if (currentBlendingEnabled === false) { enable(gl.BLEND); currentBlendingEnabled = true; } - if (blending !== CustomBlending) { if (blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha) { if (currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation) { @@ -16106,25 +14290,20 @@ currentBlendEquation = AddEquation; currentBlendEquationAlpha = AddEquation; } - if (premultipliedAlpha) { switch (blending) { case NormalBlending: gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); break; - case AdditiveBlending: gl.blendFunc(gl.ONE, gl.ONE); break; - case SubtractiveBlending: gl.blendFuncSeparate(gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE); break; - case MultiplyBlending: gl.blendFuncSeparate(gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA); break; - default: console.error('THREE.WebGLState: Invalid blending: ', blending); break; @@ -16134,25 +14313,20 @@ case NormalBlending: gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); break; - case AdditiveBlending: gl.blendFunc(gl.SRC_ALPHA, gl.ONE); break; - case SubtractiveBlending: gl.blendFuncSeparate(gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE); break; - case MultiplyBlending: gl.blendFunc(gl.ZERO, gl.SRC_COLOR); break; - default: console.error('THREE.WebGLState: Invalid blending: ', blending); break; } } - currentBlendSrc = null; currentBlendDst = null; currentBlendSrcAlpha = null; @@ -16160,21 +14334,19 @@ currentBlending = blending; currentPremultipledAlpha = premultipliedAlpha; } - return; - } // custom blending + } + // custom blending blendEquationAlpha = blendEquationAlpha || blendEquation; blendSrcAlpha = blendSrcAlpha || blendSrc; blendDstAlpha = blendDstAlpha || blendDst; - if (blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha) { gl.blendEquationSeparate(equationToGL[blendEquation], equationToGL[blendEquationAlpha]); currentBlendEquation = blendEquation; currentBlendEquationAlpha = blendEquationAlpha; } - if (blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha) { gl.blendFuncSeparate(factorToGL[blendSrc], factorToGL[blendDst], factorToGL[blendSrcAlpha], factorToGL[blendDstAlpha]); currentBlendSrc = blendSrc; @@ -16182,11 +14354,9 @@ currentBlendSrcAlpha = blendSrcAlpha; currentBlendDstAlpha = blendDstAlpha; } - currentBlending = blending; - currentPremultipledAlpha = null; + currentPremultipledAlpha = false; } - function setMaterial(material, frontFaceCW) { material.side === DoubleSide ? disable(gl.CULL_FACE) : enable(gl.CULL_FACE); let flipSided = material.side === BackSide; @@ -16199,17 +14369,16 @@ colorBuffer.setMask(material.colorWrite); const stencilWrite = material.stencilWrite; stencilBuffer.setTest(stencilWrite); - if (stencilWrite) { stencilBuffer.setMask(material.stencilWriteMask); stencilBuffer.setFunc(material.stencilFunc, material.stencilRef, material.stencilFuncMask); stencilBuffer.setOp(material.stencilFail, material.stencilZFail, material.stencilZPass); } - setPolygonOffset(material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits); material.alphaToCoverage === true ? enable(gl.SAMPLE_ALPHA_TO_COVERAGE) : disable(gl.SAMPLE_ALPHA_TO_COVERAGE); - } // + } + // function setFlipSided(flipSided) { if (currentFlipSided !== flipSided) { @@ -16218,15 +14387,12 @@ } else { gl.frontFace(gl.CCW); } - currentFlipSided = flipSided; } } - function setCullFace(cullFace) { if (cullFace !== CullFaceNone) { enable(gl.CULL_FACE); - if (cullFace !== currentCullFace) { if (cullFace === CullFaceBack) { gl.cullFace(gl.BACK); @@ -16239,21 +14405,17 @@ } else { disable(gl.CULL_FACE); } - currentCullFace = cullFace; } - function setLineWidth(width) { if (width !== currentLineWidth) { if (lineWidthAvailable) gl.lineWidth(width); currentLineWidth = width; } } - function setPolygonOffset(polygonOffset, factor, units) { if (polygonOffset) { enable(gl.POLYGON_OFFSET_FILL); - if (currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units) { gl.polygonOffset(factor, units); currentPolygonOffsetFactor = factor; @@ -16263,57 +14425,57 @@ disable(gl.POLYGON_OFFSET_FILL); } } - function setScissorTest(scissorTest) { if (scissorTest) { enable(gl.SCISSOR_TEST); } else { disable(gl.SCISSOR_TEST); } - } // texture + } + // texture function activeTexture(webglSlot) { if (webglSlot === undefined) webglSlot = gl.TEXTURE0 + maxTextures - 1; - if (currentTextureSlot !== webglSlot) { gl.activeTexture(webglSlot); currentTextureSlot = webglSlot; } } - - function bindTexture(webglType, webglTexture) { - if (currentTextureSlot === null) { - activeTexture(); + function bindTexture(webglType, webglTexture, webglSlot) { + if (webglSlot === undefined) { + if (currentTextureSlot === null) { + webglSlot = gl.TEXTURE0 + maxTextures - 1; + } else { + webglSlot = currentTextureSlot; + } } - - let boundTexture = currentBoundTextures[currentTextureSlot]; - + let boundTexture = currentBoundTextures[webglSlot]; if (boundTexture === undefined) { boundTexture = { type: undefined, texture: undefined }; - currentBoundTextures[currentTextureSlot] = boundTexture; + currentBoundTextures[webglSlot] = boundTexture; } - if (boundTexture.type !== webglType || boundTexture.texture !== webglTexture) { + if (currentTextureSlot !== webglSlot) { + gl.activeTexture(webglSlot); + currentTextureSlot = webglSlot; + } gl.bindTexture(webglType, webglTexture || emptyTextures[webglType]); boundTexture.type = webglType; boundTexture.texture = webglTexture; } } - function unbindTexture() { const boundTexture = currentBoundTextures[currentTextureSlot]; - if (boundTexture !== undefined && boundTexture.type !== undefined) { gl.bindTexture(boundTexture.type, null); boundTexture.type = undefined; boundTexture.texture = undefined; } } - function compressedTexImage2D() { try { gl.compressedTexImage2D.apply(gl, arguments); @@ -16321,7 +14483,13 @@ console.error('THREE.WebGLState:', error); } } - + function compressedTexImage3D() { + try { + gl.compressedTexImage3D.apply(gl, arguments); + } catch (error) { + console.error('THREE.WebGLState:', error); + } + } function texSubImage2D() { try { gl.texSubImage2D.apply(gl, arguments); @@ -16329,7 +14497,6 @@ console.error('THREE.WebGLState:', error); } } - function texSubImage3D() { try { gl.texSubImage3D.apply(gl, arguments); @@ -16337,7 +14504,6 @@ console.error('THREE.WebGLState:', error); } } - function compressedTexSubImage2D() { try { gl.compressedTexSubImage2D.apply(gl, arguments); @@ -16345,7 +14511,13 @@ console.error('THREE.WebGLState:', error); } } - + function compressedTexSubImage3D() { + try { + gl.compressedTexSubImage3D.apply(gl, arguments); + } catch (error) { + console.error('THREE.WebGLState:', error); + } + } function texStorage2D() { try { gl.texStorage2D.apply(gl, arguments); @@ -16353,7 +14525,6 @@ console.error('THREE.WebGLState:', error); } } - function texStorage3D() { try { gl.texStorage3D.apply(gl, arguments); @@ -16361,7 +14532,6 @@ console.error('THREE.WebGLState:', error); } } - function texImage2D() { try { gl.texImage2D.apply(gl, arguments); @@ -16369,15 +14539,15 @@ console.error('THREE.WebGLState:', error); } } - function texImage3D() { try { gl.texImage3D.apply(gl, arguments); } catch (error) { console.error('THREE.WebGLState:', error); } - } // + } + // function scissor(scissor) { if (currentScissor.equals(scissor) === false) { @@ -16385,44 +14555,40 @@ currentScissor.copy(scissor); } } - function viewport(viewport) { if (currentViewport.equals(viewport) === false) { gl.viewport(viewport.x, viewport.y, viewport.z, viewport.w); currentViewport.copy(viewport); } } - function updateUBOMapping(uniformsGroup, program) { let mapping = uboProgamMap.get(program); - if (mapping === undefined) { mapping = new WeakMap(); uboProgamMap.set(program, mapping); } - let blockIndex = mapping.get(uniformsGroup); - if (blockIndex === undefined) { blockIndex = gl.getUniformBlockIndex(program, uniformsGroup.name); mapping.set(uniformsGroup, blockIndex); } } - function uniformBlockBinding(uniformsGroup, program) { const mapping = uboProgamMap.get(program); const blockIndex = mapping.get(uniformsGroup); - if (uboBindings.get(uniformsGroup) !== blockIndex) { // bind shader specific block index to global block point + gl.uniformBlockBinding(program, blockIndex, uniformsGroup.__bindingPointIndex); uboBindings.set(uniformsGroup, blockIndex); } - } // + } + // function reset() { // reset state + gl.disable(gl.BLEND); gl.disable(gl.CULL_FACE); gl.disable(gl.DEPTH_TEST); @@ -16447,16 +14613,16 @@ gl.polygonOffset(0, 0); gl.activeTexture(gl.TEXTURE0); gl.bindFramebuffer(gl.FRAMEBUFFER, null); - if (isWebGL2 === true) { gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null); gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null); } - gl.useProgram(null); gl.lineWidth(1); gl.scissor(0, 0, gl.canvas.width, gl.canvas.height); - gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); // reset internals + gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); + + // reset internals enabledCapabilities = {}; currentTextureSlot = null; @@ -16485,7 +14651,6 @@ depthBuffer.reset(); stencilBuffer.reset(); } - return { buffers: { color: colorBuffer, @@ -16508,6 +14673,7 @@ bindTexture: bindTexture, unbindTexture: unbindTexture, compressedTexImage2D: compressedTexImage2D, + compressedTexImage3D: compressedTexImage3D, texImage2D: texImage2D, texImage3D: texImage3D, updateUBOMapping: updateUBOMapping, @@ -16517,6 +14683,7 @@ texSubImage2D: texSubImage2D, texSubImage3D: texSubImage3D, compressedTexSubImage2D: compressedTexSubImage2D, + compressedTexSubImage3D: compressedTexSubImage3D, scissor: scissor, viewport: viewport, reset: reset @@ -16530,47 +14697,52 @@ const maxTextureSize = capabilities.maxTextureSize; const maxSamples = capabilities.maxSamples; const multisampledRTTExt = extensions.has('WEBGL_multisampled_render_to_texture') ? extensions.get('WEBGL_multisampled_render_to_texture') : null; - const supportsInvalidateFramebuffer = /OculusBrowser/g.test(navigator.userAgent); - + const supportsInvalidateFramebuffer = typeof navigator === 'undefined' ? false : /OculusBrowser/g.test(navigator.userAgent); const _videoTextures = new WeakMap(); - let _canvas; - const _sources = new WeakMap(); // maps WebglTexture objects to instances of Source + // 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). - let useOffscreenCanvas = false; - try { - useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined' // eslint-disable-next-line compat/compat + useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined' + // eslint-disable-next-line compat/compat && new OffscreenCanvas(1, 1).getContext('2d') !== null; - } catch (err) {// Ignore any errors - } + } catch (err) { + // Ignore any errors + } function createCanvas(width, height) { // Use OffscreenCanvas when available. Specially needed in web workers - return useOffscreenCanvas ? // eslint-disable-next-line compat/compat + + return useOffscreenCanvas ? + // eslint-disable-next-line compat/compat new OffscreenCanvas(width, height) : createElementNS('canvas'); } - function resizeImage(image, needsPowerOfTwo, needsNewCanvas, maxSize) { - let scale = 1; // handle case if texture exceeds max size + let scale = 1; + + // handle case if texture exceeds max size if (image.width > maxSize || image.height > maxSize) { scale = maxSize / Math.max(image.width, image.height); - } // only perform resize if necessary + } + // only perform resize if necessary 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) { const floor = needsPowerOfTwo ? floorPowerOfTwo : Math.floor; const width = floor(scale * image.width); const height = floor(scale * image.height); - if (_canvas === undefined) _canvas = createCanvas(width, height); // cube textures can't reuse the same canvas + if (_canvas === undefined) _canvas = createCanvas(width, height); + + // cube textures can't reuse the same canvas const canvas = needsNewCanvas ? createCanvas(width, height) : _canvas; canvas.width = width; @@ -16583,223 +14755,190 @@ if ('data' in image) { console.warn('THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').'); } - return image; } } - return image; } - function isPowerOfTwo$1(image) { return isPowerOfTwo(image.width) && isPowerOfTwo(image.height); } - function textureNeedsPowerOfTwo(texture) { if (isWebGL2) return false; return texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping || texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; } - function textureNeedsGenerateMipmaps(texture, supportsMips) { return texture.generateMipmaps && supportsMips && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; } - function generateMipmap(target) { _gl.generateMipmap(target); } - - function getInternalFormat(internalFormatName, glFormat, glType, encoding, isVideoTexture = false) { + function getInternalFormat(internalFormatName, glFormat, glType, encoding, forceLinearEncoding = false) { if (isWebGL2 === false) return glFormat; - if (internalFormatName !== null) { if (_gl[internalFormatName] !== undefined) return _gl[internalFormatName]; console.warn('THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \'' + internalFormatName + '\''); } - let internalFormat = glFormat; - if (glFormat === _gl.RED) { if (glType === _gl.FLOAT) internalFormat = _gl.R32F; if (glType === _gl.HALF_FLOAT) internalFormat = _gl.R16F; if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.R8; } - if (glFormat === _gl.RG) { if (glType === _gl.FLOAT) internalFormat = _gl.RG32F; if (glType === _gl.HALF_FLOAT) internalFormat = _gl.RG16F; if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.RG8; } - if (glFormat === _gl.RGBA) { if (glType === _gl.FLOAT) internalFormat = _gl.RGBA32F; if (glType === _gl.HALF_FLOAT) internalFormat = _gl.RGBA16F; - if (glType === _gl.UNSIGNED_BYTE) internalFormat = encoding === sRGBEncoding && isVideoTexture === false ? _gl.SRGB8_ALPHA8 : _gl.RGBA8; + if (glType === _gl.UNSIGNED_BYTE) internalFormat = encoding === sRGBEncoding && forceLinearEncoding === false ? _gl.SRGB8_ALPHA8 : _gl.RGBA8; if (glType === _gl.UNSIGNED_SHORT_4_4_4_4) internalFormat = _gl.RGBA4; if (glType === _gl.UNSIGNED_SHORT_5_5_5_1) internalFormat = _gl.RGB5_A1; } - if (internalFormat === _gl.R16F || internalFormat === _gl.R32F || internalFormat === _gl.RG16F || internalFormat === _gl.RG32F || internalFormat === _gl.RGBA16F || internalFormat === _gl.RGBA32F) { extensions.get('EXT_color_buffer_float'); } - return internalFormat; } - function getMipLevels(texture, image, supportsMips) { if (textureNeedsGenerateMipmaps(texture, supportsMips) === true || texture.isFramebufferTexture && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter) { return Math.log2(Math.max(image.width, image.height)) + 1; } else if (texture.mipmaps !== undefined && texture.mipmaps.length > 0) { // user-defined mipmaps + return texture.mipmaps.length; } else if (texture.isCompressedTexture && Array.isArray(texture.image)) { return image.mipmaps.length; } else { // texture without mipmaps (only base level) + return 1; } - } // Fallback filters for non-power-of-2 textures + } + // Fallback filters for non-power-of-2 textures function filterFallback(f) { if (f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter) { return _gl.NEAREST; } - return _gl.LINEAR; - } // + } + // function onTextureDispose(event) { const texture = event.target; texture.removeEventListener('dispose', onTextureDispose); deallocateTexture(texture); - if (texture.isVideoTexture) { _videoTextures.delete(texture); } } - function onRenderTargetDispose(event) { const renderTarget = event.target; renderTarget.removeEventListener('dispose', onRenderTargetDispose); deallocateRenderTarget(renderTarget); - } // + } + // function deallocateTexture(texture) { const textureProperties = properties.get(texture); - if (textureProperties.__webglInit === undefined) return; // check if it's necessary to remove the WebGLTexture object + if (textureProperties.__webglInit === undefined) return; - const source = texture.source; + // check if it's necessary to remove the WebGLTexture object + const source = texture.source; const webglTextures = _sources.get(source); - if (webglTextures) { const webglTexture = webglTextures[textureProperties.__cacheKey]; - webglTexture.usedTimes--; // the WebGLTexture object is not used anymore, remove it + webglTexture.usedTimes--; + + // the WebGLTexture object is not used anymore, remove it if (webglTexture.usedTimes === 0) { deleteTexture(texture); - } // remove the weak map entry if no WebGLTexture uses the source anymore + } + // remove the weak map entry if no WebGLTexture uses the source anymore if (Object.keys(webglTextures).length === 0) { _sources.delete(source); } } - properties.remove(texture); } - function deleteTexture(texture) { const textureProperties = properties.get(texture); - _gl.deleteTexture(textureProperties.__webglTexture); - const source = texture.source; - const webglTextures = _sources.get(source); - delete webglTextures[textureProperties.__cacheKey]; info.memory.textures--; } - function deallocateRenderTarget(renderTarget) { const texture = renderTarget.texture; const renderTargetProperties = properties.get(renderTarget); const textureProperties = properties.get(texture); - if (textureProperties.__webglTexture !== undefined) { _gl.deleteTexture(textureProperties.__webglTexture); - info.memory.textures--; } - if (renderTarget.depthTexture) { renderTarget.depthTexture.dispose(); } - if (renderTarget.isWebGLCubeRenderTarget) { for (let i = 0; i < 6; i++) { _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer[i]); - if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer[i]); } } else { _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer); - if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer); if (renderTargetProperties.__webglMultisampledFramebuffer) _gl.deleteFramebuffer(renderTargetProperties.__webglMultisampledFramebuffer); - if (renderTargetProperties.__webglColorRenderbuffer) { for (let i = 0; i < renderTargetProperties.__webglColorRenderbuffer.length; i++) { if (renderTargetProperties.__webglColorRenderbuffer[i]) _gl.deleteRenderbuffer(renderTargetProperties.__webglColorRenderbuffer[i]); } } - if (renderTargetProperties.__webglDepthRenderbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthRenderbuffer); } - if (renderTarget.isWebGLMultipleRenderTargets) { for (let i = 0, il = texture.length; i < il; i++) { const attachmentProperties = properties.get(texture[i]); - if (attachmentProperties.__webglTexture) { _gl.deleteTexture(attachmentProperties.__webglTexture); - info.memory.textures--; } - properties.remove(texture[i]); } } - properties.remove(texture); properties.remove(renderTarget); - } // + } + // let textureUnits = 0; - function resetTextureUnits() { textureUnits = 0; } - function allocateTextureUnit() { const textureUnit = textureUnits; - if (textureUnit >= maxTextures) { console.warn('THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + maxTextures); } - textureUnits += 1; return textureUnit; } - function getTextureCacheKey(texture) { const array = []; array.push(texture.wrapS); array.push(texture.wrapT); + array.push(texture.wrapR || 0); array.push(texture.magFilter); array.push(texture.minFilter); array.push(texture.anisotropy); @@ -16812,16 +14951,15 @@ array.push(texture.unpackAlignment); array.push(texture.encoding); return array.join(); - } // + } + // function setTexture2D(texture, slot) { const textureProperties = properties.get(texture); if (texture.isVideoTexture) updateVideoTexture(texture); - if (texture.isRenderTargetTexture === false && texture.version > 0 && textureProperties.__version !== texture.version) { const image = texture.image; - if (image === null) { console.warn('THREE.WebGLRenderer: Texture marked for update but no image data found.'); } else if (image.complete === false) { @@ -16831,47 +14969,32 @@ return; } } - - state.activeTexture(_gl.TEXTURE0 + slot); - state.bindTexture(_gl.TEXTURE_2D, textureProperties.__webglTexture); + state.bindTexture(_gl.TEXTURE_2D, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); } - function setTexture2DArray(texture, slot) { const textureProperties = properties.get(texture); - if (texture.version > 0 && textureProperties.__version !== texture.version) { uploadTexture(textureProperties, texture, slot); return; } - - state.activeTexture(_gl.TEXTURE0 + slot); - state.bindTexture(_gl.TEXTURE_2D_ARRAY, textureProperties.__webglTexture); + state.bindTexture(_gl.TEXTURE_2D_ARRAY, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); } - function setTexture3D(texture, slot) { const textureProperties = properties.get(texture); - if (texture.version > 0 && textureProperties.__version !== texture.version) { uploadTexture(textureProperties, texture, slot); return; } - - state.activeTexture(_gl.TEXTURE0 + slot); - state.bindTexture(_gl.TEXTURE_3D, textureProperties.__webglTexture); + state.bindTexture(_gl.TEXTURE_3D, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); } - function setTextureCube(texture, slot) { const textureProperties = properties.get(texture); - if (texture.version > 0 && textureProperties.__version !== texture.version) { uploadCubeTexture(textureProperties, texture, slot); return; } - - state.activeTexture(_gl.TEXTURE0 + slot); - state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture); + state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); } - const wrappingToGL = { [RepeatWrapping]: _gl.REPEAT, [ClampToEdgeWrapping]: _gl.CLAMP_TO_EDGE, @@ -16885,149 +15008,128 @@ [LinearMipmapNearestFilter]: _gl.LINEAR_MIPMAP_NEAREST, [LinearMipmapLinearFilter]: _gl.LINEAR_MIPMAP_LINEAR }; - function setTextureParameters(textureType, texture, supportsMips) { if (supportsMips) { _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_S, wrappingToGL[texture.wrapS]); - _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_T, wrappingToGL[texture.wrapT]); - if (textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY) { _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_R, wrappingToGL[texture.wrapR]); } - _gl.texParameteri(textureType, _gl.TEXTURE_MAG_FILTER, filterToGL[texture.magFilter]); - _gl.texParameteri(textureType, _gl.TEXTURE_MIN_FILTER, filterToGL[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); - if (textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY) { _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_R, _gl.CLAMP_TO_EDGE); } - 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.'); } - _gl.texParameteri(textureType, _gl.TEXTURE_MAG_FILTER, filterFallback(texture.magFilter)); - _gl.texParameteri(textureType, _gl.TEXTURE_MIN_FILTER, filterFallback(texture.minFilter)); - 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.'); } } - if (extensions.has('EXT_texture_filter_anisotropic') === true) { const extension = extensions.get('EXT_texture_filter_anisotropic'); if (texture.type === FloatType && extensions.has('OES_texture_float_linear') === false) return; // verify extension for WebGL 1 and WebGL 2 - if (isWebGL2 === false && texture.type === HalfFloatType && extensions.has('OES_texture_half_float_linear') === false) return; // verify extension for WebGL 1 only 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) { let forceUpload = false; - if (textureProperties.__webglInit === undefined) { textureProperties.__webglInit = true; texture.addEventListener('dispose', onTextureDispose); - } // create Source <-> WebGLTextures mapping if necessary + } + // create Source <-> WebGLTextures mapping if necessary const source = texture.source; - let webglTextures = _sources.get(source); - if (webglTextures === undefined) { webglTextures = {}; - _sources.set(source, webglTextures); - } // check if there is already a WebGLTexture object for the given texture parameters + } + // check if there is already a WebGLTexture object for the given texture parameters const textureCacheKey = getTextureCacheKey(texture); - if (textureCacheKey !== textureProperties.__cacheKey) { // if not, create a new instance of WebGLTexture + if (webglTextures[textureCacheKey] === undefined) { // create new entry + webglTextures[textureCacheKey] = { texture: _gl.createTexture(), usedTimes: 0 }; - info.memory.textures++; // when a new instance of WebGLTexture was created, a texture upload is required + info.memory.textures++; + + // when a new instance of WebGLTexture was created, a texture upload is required // even if the image contents are identical forceUpload = true; } + webglTextures[textureCacheKey].usedTimes++; - webglTextures[textureCacheKey].usedTimes++; // every time the texture cache key changes, it's necessary to check if an instance of + // every time the texture cache key changes, it's necessary to check if an instance of // WebGLTexture can be deleted in order to avoid a memory leak. const webglTexture = webglTextures[textureProperties.__cacheKey]; - if (webglTexture !== undefined) { webglTextures[textureProperties.__cacheKey].usedTimes--; - if (webglTexture.usedTimes === 0) { deleteTexture(texture); } - } // store references to cache key and WebGLTexture object + } + // store references to cache key and WebGLTexture object textureProperties.__cacheKey = textureCacheKey; textureProperties.__webglTexture = webglTextures[textureCacheKey].texture; } - return forceUpload; } - function uploadTexture(textureProperties, texture, slot) { let textureType = _gl.TEXTURE_2D; - if (texture.isDataArrayTexture) textureType = _gl.TEXTURE_2D_ARRAY; + if (texture.isDataArrayTexture || texture.isCompressedArrayTexture) textureType = _gl.TEXTURE_2D_ARRAY; if (texture.isData3DTexture) textureType = _gl.TEXTURE_3D; const forceUpload = initTexture(textureProperties, texture); const source = texture.source; - state.activeTexture(_gl.TEXTURE0 + slot); - state.bindTexture(textureType, textureProperties.__webglTexture); - - if (source.version !== source.__currentVersion || forceUpload === true) { + state.bindTexture(textureType, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); + const sourceProperties = properties.get(source); + if (source.version !== sourceProperties.__version || forceUpload === true) { + state.activeTexture(_gl.TEXTURE0 + slot); _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); - _gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, _gl.NONE); - const needsPowerOfTwo = textureNeedsPowerOfTwo(texture) && isPowerOfTwo$1(texture.image) === false; let image = resizeImage(texture.image, needsPowerOfTwo, false, maxTextureSize); image = verifyColorSpace(texture, image); const supportsMips = isPowerOfTwo$1(image) || isWebGL2, - glFormat = utils.convert(texture.format, texture.encoding); + glFormat = utils.convert(texture.format, texture.encoding); let glType = utils.convert(texture.type), - glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding, texture.isVideoTexture); + glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding, texture.isVideoTexture); setTextureParameters(textureType, texture, supportsMips); let mipmap; const mipmaps = texture.mipmaps; const useTexStorage = isWebGL2 && texture.isVideoTexture !== true; - const allocateMemory = source.__currentVersion === undefined || forceUpload === true; + const allocateMemory = sourceProperties.__version === undefined || forceUpload === true; const levels = getMipLevels(texture, image, supportsMips); - if (texture.isDepthTexture) { // populate depth texture with dummy data - glInternalFormat = _gl.DEPTH_COMPONENT; + glInternalFormat = _gl.DEPTH_COMPONENT; if (isWebGL2) { if (texture.type === FloatType) { glInternalFormat = _gl.DEPTH_COMPONENT32F; @@ -17042,8 +15144,9 @@ if (texture.type === FloatType) { console.error('WebGLRenderer: Floating point depth texture requires WebGL2.'); } - } // validation checks for WebGL 1 + } + // validation checks for WebGL 1 if (texture.format === DepthFormat && glInternalFormat === _gl.DEPTH_COMPONENT) { // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are @@ -17055,21 +15158,22 @@ glType = utils.convert(texture.type); } } - if (texture.format === DepthStencilFormat && glInternalFormat === _gl.DEPTH_COMPONENT) { // Depth stencil textures need the DEPTH_STENCIL internal format // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) - glInternalFormat = _gl.DEPTH_STENCIL; // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are + glInternalFormat = _gl.DEPTH_STENCIL; + + // 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); } - } // + } + // if (allocateMemory) { if (useTexStorage) { @@ -17082,56 +15186,77 @@ // 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) { if (useTexStorage && allocateMemory) { state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); } - for (let i = 0, il = mipmaps.length; i < il; i++) { mipmap = mipmaps[i]; - if (useTexStorage) { state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); } else { state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); } } - texture.generateMipmaps = false; } else { if (useTexStorage) { if (allocateMemory) { state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); } - state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, image.width, image.height, glFormat, glType, image.data); } else { state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data); } } } else if (texture.isCompressedTexture) { - if (useTexStorage && allocateMemory) { - state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); - } - - for (let i = 0, il = mipmaps.length; i < il; i++) { - mipmap = mipmaps[i]; - - if (texture.format !== RGBAFormat) { - if (glFormat !== null) { - if (useTexStorage) { - state.compressedTexSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data); + if (texture.isCompressedArrayTexture) { + if (useTexStorage && allocateMemory) { + state.texStorage3D(_gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height, image.depth); + } + for (let i = 0, il = mipmaps.length; i < il; i++) { + mipmap = mipmaps[i]; + if (texture.format !== RGBAFormat) { + if (glFormat !== null) { + if (useTexStorage) { + state.compressedTexSubImage3D(_gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, mipmap.data, 0, 0); + } else { + state.compressedTexImage3D(_gl.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, mipmap.data, 0, 0); + } } else { - state.compressedTexImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data); + console.warn('THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()'); } } else { - console.warn('THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()'); + if (useTexStorage) { + state.texSubImage3D(_gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, glType, mipmap.data); + } else { + state.texImage3D(_gl.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, glFormat, glType, mipmap.data); + } } - } else { - if (useTexStorage) { - state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); + } + } else { + if (useTexStorage && allocateMemory) { + state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); + } + for (let i = 0, il = mipmaps.length; i < il; i++) { + mipmap = mipmaps[i]; + if (texture.format !== RGBAFormat) { + if (glFormat !== null) { + if (useTexStorage) { + state.compressedTexSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data); + } else { + state.compressedTexImage2D(_gl.TEXTURE_2D, 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(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); + if (useTexStorage) { + state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); + } else { + state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); + } } } } @@ -17140,7 +15265,6 @@ if (allocateMemory) { state.texStorage3D(_gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, image.width, image.height, image.depth); } - state.texSubImage3D(_gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data); } else { state.texImage3D(_gl.TEXTURE_2D_ARRAY, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data); @@ -17150,7 +15274,6 @@ if (allocateMemory) { state.texStorage3D(_gl.TEXTURE_3D, levels, glInternalFormat, image.width, image.height, image.depth); } - state.texSubImage3D(_gl.TEXTURE_3D, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data); } else { state.texImage3D(_gl.TEXTURE_3D, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data); @@ -17161,8 +15284,7 @@ state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); } else { let width = image.width, - height = image.height; - + height = image.height; for (let i = 0; i < levels; i++) { state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, width, height, 0, glFormat, glType, null); width >>= 1; @@ -17172,101 +15294,84 @@ } } 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) { if (useTexStorage && allocateMemory) { state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); } - for (let i = 0, il = mipmaps.length; i < il; i++) { mipmap = mipmaps[i]; - if (useTexStorage) { state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, glFormat, glType, mipmap); } else { state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, glFormat, glType, mipmap); } } - texture.generateMipmaps = false; } else { if (useTexStorage) { if (allocateMemory) { state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); } - state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, glFormat, glType, image); } else { state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image); } } } - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { generateMipmap(textureType); } - - source.__currentVersion = source.version; + sourceProperties.__version = source.version; if (texture.onUpdate) texture.onUpdate(texture); } - textureProperties.__version = texture.version; } - function uploadCubeTexture(textureProperties, texture, slot) { if (texture.image.length !== 6) return; const forceUpload = initTexture(textureProperties, texture); const source = texture.source; - state.activeTexture(_gl.TEXTURE0 + slot); - state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture); - - if (source.version !== source.__currentVersion || forceUpload === true) { + state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); + const sourceProperties = properties.get(source); + if (source.version !== sourceProperties.__version || forceUpload === true) { + state.activeTexture(_gl.TEXTURE0 + slot); _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); - _gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, _gl.NONE); - const isCompressed = texture.isCompressedTexture || texture.image[0].isCompressedTexture; const isDataTexture = texture.image[0] && texture.image[0].isDataTexture; const cubeImage = []; - for (let 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]; } - cubeImage[i] = verifyColorSpace(texture, cubeImage[i]); } - const image = cubeImage[0], - supportsMips = isPowerOfTwo$1(image) || isWebGL2, - glFormat = utils.convert(texture.format, texture.encoding), - glType = utils.convert(texture.type), - glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding); + supportsMips = isPowerOfTwo$1(image) || isWebGL2, + glFormat = utils.convert(texture.format, texture.encoding), + glType = utils.convert(texture.type), + glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding); const useTexStorage = isWebGL2 && texture.isVideoTexture !== true; - const allocateMemory = source.__currentVersion === undefined || forceUpload === true; + const allocateMemory = sourceProperties.__version === undefined || forceUpload === true; let levels = getMipLevels(texture, image, supportsMips); setTextureParameters(_gl.TEXTURE_CUBE_MAP, texture, supportsMips); let mipmaps; - if (isCompressed) { if (useTexStorage && allocateMemory) { state.texStorage2D(_gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, image.width, image.height); } - for (let i = 0; i < 6; i++) { mipmaps = cubeImage[i].mipmaps; - for (let j = 0; j < mipmaps.length; j++) { const mipmap = mipmaps[j]; - if (texture.format !== RGBAFormat) { if (glFormat !== null) { if (useTexStorage) { @@ -17288,15 +15393,14 @@ } } else { mipmaps = texture.mipmaps; - if (useTexStorage && allocateMemory) { // TODO: Uniformly handle mipmap definitions // Normal textures and compressed cube textures define base level + mips with their mipmap array // Uncompressed cube textures use their mipmap array only for mips (no base level) + if (mipmaps.length > 0) levels++; state.texStorage2D(_gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, cubeImage[0].width, cubeImage[0].height); } - for (let i = 0; i < 6; i++) { if (isDataTexture) { if (useTexStorage) { @@ -17304,11 +15408,9 @@ } else { state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, cubeImage[i].width, cubeImage[i].height, 0, glFormat, glType, cubeImage[i].data); } - for (let j = 0; j < mipmaps.length; j++) { const mipmap = mipmaps[j]; const mipmapImage = mipmap.image[i].image; - if (useTexStorage) { state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, mipmapImage.width, mipmapImage.height, glFormat, glType, mipmapImage.data); } else { @@ -17321,10 +15423,8 @@ } else { state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[i]); } - for (let j = 0; j < mipmaps.length; j++) { const mipmap = mipmaps[j]; - if (useTexStorage) { state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, glFormat, glType, mipmap.image[i]); } else { @@ -17334,27 +15434,24 @@ } } } - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { // We assume images for cube map have the same size. generateMipmap(_gl.TEXTURE_CUBE_MAP); } - - source.__currentVersion = source.version; + sourceProperties.__version = source.version; if (texture.onUpdate) texture.onUpdate(texture); } - textureProperties.__version = texture.version; - } // Render targets - // Setup storage for target texture and bind it to correct framebuffer + } + // Render targets + // Setup storage for target texture and bind it to correct framebuffer function setupFrameBufferTexture(framebuffer, renderTarget, texture, attachment, textureTarget) { const glFormat = utils.convert(texture.format, texture.encoding); const glType = utils.convert(texture.type); const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding); const renderTargetProperties = properties.get(renderTarget); - if (!renderTargetProperties.__hasExternalTextures) { if (textureTarget === _gl.TEXTURE_3D || textureTarget === _gl.TEXTURE_2D_ARRAY) { state.texImage3D(textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, renderTarget.depth, 0, glFormat, glType, null); @@ -17362,28 +15459,24 @@ state.texImage2D(textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null); } } - state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); - if (useMultisampledRTT(renderTarget)) { multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, attachment, textureTarget, properties.get(texture).__webglTexture, 0, getRenderTargetSamples(renderTarget)); - } else { + } else if (textureTarget === _gl.TEXTURE_2D || textureTarget >= _gl.TEXTURE_CUBE_MAP_POSITIVE_X && textureTarget <= _gl.TEXTURE_CUBE_MAP_NEGATIVE_Z) { + // see #24753 + _gl.framebufferTexture2D(_gl.FRAMEBUFFER, attachment, textureTarget, properties.get(texture).__webglTexture, 0); } - state.bindFramebuffer(_gl.FRAMEBUFFER, null); - } // Setup storage for internal depth/stencil buffers and bind to correct framebuffer - + } + // Setup storage for internal depth/stencil buffers and bind to correct framebuffer function setupRenderBufferStorage(renderbuffer, renderTarget, isMultisample) { _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderbuffer); - if (renderTarget.depthBuffer && !renderTarget.stencilBuffer) { let glInternalFormat = _gl.DEPTH_COMPONENT16; - if (isMultisample || useMultisampledRTT(renderTarget)) { const depthTexture = renderTarget.depthTexture; - if (depthTexture && depthTexture.isDepthTexture) { if (depthTexture.type === FloatType) { glInternalFormat = _gl.DEPTH_COMPONENT32F; @@ -17391,9 +15484,7 @@ glInternalFormat = _gl.DEPTH_COMPONENT24; } } - const samples = getRenderTargetSamples(renderTarget); - if (useMultisampledRTT(renderTarget)) { multisampledRTTExt.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); } else { @@ -17402,11 +15493,9 @@ } else { _gl.renderbufferStorage(_gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height); } - _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer); } else if (renderTarget.depthBuffer && renderTarget.stencilBuffer) { const samples = getRenderTargetSamples(renderTarget); - if (isMultisample && useMultisampledRTT(renderTarget) === false) { _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, _gl.DEPTH24_STENCIL8, renderTarget.width, renderTarget.height); } else if (useMultisampledRTT(renderTarget)) { @@ -17414,18 +15503,15 @@ } else { _gl.renderbufferStorage(_gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height); } - _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer); } else { const textures = renderTarget.isWebGLMultipleRenderTargets === true ? renderTarget.texture : [renderTarget.texture]; - for (let i = 0; i < textures.length; i++) { const texture = textures[i]; const glFormat = utils.convert(texture.format, texture.encoding); const glType = utils.convert(texture.type); const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding); const samples = getRenderTargetSamples(renderTarget); - if (isMultisample && useMultisampledRTT(renderTarget) === false) { _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); } else if (useMultisampledRTT(renderTarget)) { @@ -17435,33 +15521,27 @@ } } } - _gl.bindRenderbuffer(_gl.RENDERBUFFER, null); - } // Setup resources for a Depth Texture for a FBO (needs an extension) - + } + // Setup resources for a Depth Texture for a FBO (needs an extension) function setupDepthTexture(framebuffer, renderTarget) { const isCube = renderTarget && renderTarget.isWebGLCubeRenderTarget; if (isCube) throw new Error('Depth Texture with cube render targets is not supported'); state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); - 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 - + } + // upload an empty depth texture with framebuffer size 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); - const webglDepthTexture = properties.get(renderTarget.depthTexture).__webglTexture; - const samples = getRenderTargetSamples(renderTarget); - if (renderTarget.depthTexture.format === DepthFormat) { if (useMultisampledRTT(renderTarget)) { multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples); @@ -17477,20 +15557,18 @@ } else { throw new Error('Unknown depthTexture format'); } - } // Setup GL resources for a non-texture depth buffer - + } + // Setup GL resources for a non-texture depth buffer function setupDepthRenderbuffer(renderTarget) { const renderTargetProperties = properties.get(renderTarget); const isCube = renderTarget.isWebGLCubeRenderTarget === true; - if (renderTarget.depthTexture && !renderTargetProperties.__autoAllocateDepthBuffer) { if (isCube) throw new Error('target.depthTexture not supported in Cube render targets'); setupDepthTexture(renderTargetProperties.__webglFramebuffer, renderTarget); } else { if (isCube) { renderTargetProperties.__webglDepthbuffer = []; - for (let i = 0; i < 6; i++) { state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[i]); renderTargetProperties.__webglDepthbuffer[i] = _gl.createRenderbuffer(); @@ -17502,59 +15580,51 @@ setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer, renderTarget, false); } } - state.bindFramebuffer(_gl.FRAMEBUFFER, null); - } // rebind framebuffer with external textures - + } + // rebind framebuffer with external textures function rebindTextures(renderTarget, colorTexture, depthTexture) { const renderTargetProperties = properties.get(renderTarget); - if (colorTexture !== undefined) { setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, renderTarget.texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D); } - if (depthTexture !== undefined) { setupDepthRenderbuffer(renderTarget); } - } // Set up GL resources for the render target - + } + // Set up GL resources for the render target function setupRenderTarget(renderTarget) { const texture = renderTarget.texture; const renderTargetProperties = properties.get(renderTarget); const textureProperties = properties.get(texture); renderTarget.addEventListener('dispose', onRenderTargetDispose); - if (renderTarget.isWebGLMultipleRenderTargets !== true) { if (textureProperties.__webglTexture === undefined) { textureProperties.__webglTexture = _gl.createTexture(); } - textureProperties.__version = texture.version; info.memory.textures++; } - const isCube = renderTarget.isWebGLCubeRenderTarget === true; const isMultipleRenderTargets = renderTarget.isWebGLMultipleRenderTargets === true; - const supportsMips = isPowerOfTwo$1(renderTarget) || isWebGL2; // Setup framebuffer + const supportsMips = isPowerOfTwo$1(renderTarget) || isWebGL2; + + // Setup framebuffer if (isCube) { renderTargetProperties.__webglFramebuffer = []; - for (let i = 0; i < 6; i++) { renderTargetProperties.__webglFramebuffer[i] = _gl.createFramebuffer(); } } else { renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer(); - if (isMultipleRenderTargets) { if (capabilities.drawBuffers) { const textures = renderTarget.texture; - for (let i = 0, il = textures.length; i < il; i++) { const attachmentProperties = properties.get(textures[i]); - if (attachmentProperties.__webglTexture === undefined) { attachmentProperties.__webglTexture = _gl.createTexture(); info.memory.textures++; @@ -17564,73 +15634,58 @@ console.warn('THREE.WebGLRenderer: WebGLMultipleRenderTargets can only be used with WebGL2 or WEBGL_draw_buffers extension.'); } } - if (isWebGL2 && renderTarget.samples > 0 && useMultisampledRTT(renderTarget) === false) { const textures = isMultipleRenderTargets ? texture : [texture]; renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer(); renderTargetProperties.__webglColorRenderbuffer = []; state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); - for (let i = 0; i < textures.length; i++) { const texture = textures[i]; renderTargetProperties.__webglColorRenderbuffer[i] = _gl.createRenderbuffer(); - _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); - const glFormat = utils.convert(texture.format, texture.encoding); const glType = utils.convert(texture.type); - const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding); + const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding, renderTarget.isXRRenderTarget === true); const samples = getRenderTargetSamples(renderTarget); - _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); - _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); } - _gl.bindRenderbuffer(_gl.RENDERBUFFER, null); - if (renderTarget.depthBuffer) { renderTargetProperties.__webglDepthRenderbuffer = _gl.createRenderbuffer(); setupRenderBufferStorage(renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true); } - state.bindFramebuffer(_gl.FRAMEBUFFER, null); } - } // Setup color buffer + } + // Setup color buffer if (isCube) { state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture); setTextureParameters(_gl.TEXTURE_CUBE_MAP, texture, supportsMips); - for (let i = 0; i < 6; i++) { setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer[i], renderTarget, texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i); } - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { generateMipmap(_gl.TEXTURE_CUBE_MAP); } - state.unbindTexture(); } else if (isMultipleRenderTargets) { const textures = renderTarget.texture; - for (let i = 0, il = textures.length; i < il; i++) { const attachment = textures[i]; const attachmentProperties = properties.get(attachment); state.bindTexture(_gl.TEXTURE_2D, attachmentProperties.__webglTexture); setTextureParameters(_gl.TEXTURE_2D, attachment, supportsMips); setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, attachment, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D); - if (textureNeedsGenerateMipmaps(attachment, supportsMips)) { generateMipmap(_gl.TEXTURE_2D); } } - state.unbindTexture(); } else { let glTextureType = _gl.TEXTURE_2D; - if (renderTarget.isWebGL3DRenderTarget || renderTarget.isWebGLArrayRenderTarget) { if (isWebGL2) { glTextureType = renderTarget.isWebGL3DRenderTarget ? _gl.TEXTURE_3D : _gl.TEXTURE_2D_ARRAY; @@ -17638,43 +15693,35 @@ console.error('THREE.WebGLTextures: THREE.Data3DTexture and THREE.DataArrayTexture only supported with WebGL2.'); } } - state.bindTexture(glTextureType, textureProperties.__webglTexture); setTextureParameters(glTextureType, texture, supportsMips); setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, texture, _gl.COLOR_ATTACHMENT0, glTextureType); - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { generateMipmap(glTextureType); } - state.unbindTexture(); - } // Setup depth and stencil buffers + } + // Setup depth and stencil buffers if (renderTarget.depthBuffer) { setupDepthRenderbuffer(renderTarget); } } - function updateRenderTargetMipmap(renderTarget) { const supportsMips = isPowerOfTwo$1(renderTarget) || isWebGL2; const textures = renderTarget.isWebGLMultipleRenderTargets === true ? renderTarget.texture : [renderTarget.texture]; - for (let i = 0, il = textures.length; i < il; i++) { const texture = textures[i]; - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { const target = renderTarget.isWebGLCubeRenderTarget ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D; - const webglTexture = properties.get(texture).__webglTexture; - state.bindTexture(target, webglTexture); generateMipmap(target); state.unbindTexture(); } } } - function updateMultisampleRenderTarget(renderTarget) { if (isWebGL2 && renderTarget.samples > 0 && useMultisampledRTT(renderTarget) === false) { const textures = renderTarget.isWebGLMultipleRenderTargets ? renderTarget.texture : [renderTarget.texture]; @@ -17684,122 +15731,105 @@ const invalidationArray = []; const depthStyle = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT; const renderTargetProperties = properties.get(renderTarget); - const isMultipleRenderTargets = renderTarget.isWebGLMultipleRenderTargets === true; // If MRT we need to remove FBO attachments + const isMultipleRenderTargets = renderTarget.isWebGLMultipleRenderTargets === true; + // If MRT we need to remove FBO attachments if (isMultipleRenderTargets) { for (let i = 0; i < textures.length; i++) { state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); - _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, null); - state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); - _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D, null, 0); } } - state.bindFramebuffer(_gl.READ_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); - for (let i = 0; i < textures.length; i++) { invalidationArray.push(_gl.COLOR_ATTACHMENT0 + i); - if (renderTarget.depthBuffer) { invalidationArray.push(depthStyle); } - const ignoreDepthValues = renderTargetProperties.__ignoreDepthValues !== undefined ? renderTargetProperties.__ignoreDepthValues : false; - if (ignoreDepthValues === false) { if (renderTarget.depthBuffer) mask |= _gl.DEPTH_BUFFER_BIT; if (renderTarget.stencilBuffer) mask |= _gl.STENCIL_BUFFER_BIT; } - if (isMultipleRenderTargets) { _gl.framebufferRenderbuffer(_gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); } - if (ignoreDepthValues === true) { _gl.invalidateFramebuffer(_gl.READ_FRAMEBUFFER, [depthStyle]); - _gl.invalidateFramebuffer(_gl.DRAW_FRAMEBUFFER, [depthStyle]); } - if (isMultipleRenderTargets) { const webglTexture = properties.get(textures[i]).__webglTexture; - _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, webglTexture, 0); } - _gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, mask, _gl.NEAREST); - if (supportsInvalidateFramebuffer) { _gl.invalidateFramebuffer(_gl.READ_FRAMEBUFFER, invalidationArray); } } - state.bindFramebuffer(_gl.READ_FRAMEBUFFER, null); - state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, null); // If MRT since pre-blit we removed the FBO we need to reconstruct the attachments + state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, null); + // If MRT since pre-blit we removed the FBO we need to reconstruct the attachments if (isMultipleRenderTargets) { for (let i = 0; i < textures.length; i++) { state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); - _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); - const webglTexture = properties.get(textures[i]).__webglTexture; - state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); - _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D, webglTexture, 0); } } - state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); } } - function getRenderTargetSamples(renderTarget) { return Math.min(maxSamples, renderTarget.samples); } - function useMultisampledRTT(renderTarget) { const renderTargetProperties = properties.get(renderTarget); return isWebGL2 && renderTarget.samples > 0 && extensions.has('WEBGL_multisampled_render_to_texture') === true && renderTargetProperties.__useRenderToTexture !== false; } - function updateVideoTexture(texture) { - const frame = info.render.frame; // Check the last frame we updated the VideoTexture + const frame = info.render.frame; + + // Check the last frame we updated the VideoTexture if (_videoTextures.get(texture) !== frame) { _videoTextures.set(texture, frame); - texture.update(); } } - function verifyColorSpace(texture, image) { const encoding = texture.encoding; const format = texture.format; const type = texture.type; if (texture.isCompressedTexture === true || texture.isVideoTexture === true || texture.format === _SRGBAFormat) return image; - if (encoding !== LinearEncoding) { // sRGB + if (encoding === sRGBEncoding) { if (isWebGL2 === false) { // in WebGL 1, try to use EXT_sRGB extension and unsized formats + if (extensions.has('EXT_sRGB') === true && format === RGBAFormat) { - texture.format = _SRGBAFormat; // it's not possible to generate mips in WebGL 1 with this extension + texture.format = _SRGBAFormat; + + // it's not possible to generate mips in WebGL 1 with this extension texture.minFilter = LinearFilter; texture.generateMipmaps = false; } else { // slow fallback (CPU decode) + image = ImageUtils.sRGBToLinear(image); } } else { // in WebGL 2 uncompressed textures can only be sRGB encoded if they have the RGBA8 format + if (format !== RGBAFormat || type !== UnsignedByteType) { console.warn('THREE.WebGLTextures: sRGB encoded textures have to use RGBAFormat and UnsignedByteType.'); } @@ -17808,10 +15838,10 @@ console.error('THREE.WebGLTextures: Unsupported texture encoding:', encoding); } } - return image; - } // + } + // this.allocateTextureUnit = allocateTextureUnit; this.resetTextureUnits = resetTextureUnits; @@ -17830,7 +15860,6 @@ function WebGLUtils(gl, extensions, capabilities) { const isWebGL2 = capabilities.isWebGL2; - function convert(p, encoding = null) { let extension; if (p === UnsignedByteType) return gl.UNSIGNED_BYTE; @@ -17842,52 +15871,53 @@ if (p === IntType) return gl.INT; if (p === UnsignedIntType) return gl.UNSIGNED_INT; if (p === FloatType) return gl.FLOAT; - if (p === HalfFloatType) { if (isWebGL2) return gl.HALF_FLOAT; extension = extensions.get('OES_texture_half_float'); - if (extension !== null) { return extension.HALF_FLOAT_OES; } else { return null; } } - if (p === AlphaFormat) return gl.ALPHA; if (p === RGBAFormat) return gl.RGBA; if (p === LuminanceFormat) return gl.LUMINANCE; if (p === LuminanceAlphaFormat) return gl.LUMINANCE_ALPHA; if (p === DepthFormat) return gl.DEPTH_COMPONENT; if (p === DepthStencilFormat) return gl.DEPTH_STENCIL; - if (p === RedFormat) return gl.RED; + + // @deprecated since r137 if (p === RGBFormat) { console.warn('THREE.WebGLRenderer: THREE.RGBFormat has been removed. Use THREE.RGBAFormat instead. https://github.com/mrdoob/three.js/pull/23228'); return gl.RGBA; - } // WebGL 1 sRGB fallback + } + // WebGL 1 sRGB fallback if (p === _SRGBAFormat) { extension = extensions.get('EXT_sRGB'); - if (extension !== null) { return extension.SRGB_ALPHA_EXT; } else { return null; } - } // WebGL2 formats. + } + // WebGL2 formats. + if (p === RedFormat) return gl.RED; if (p === RedIntegerFormat) return gl.RED_INTEGER; if (p === RGFormat) return gl.RG; if (p === RGIntegerFormat) return gl.RG_INTEGER; - if (p === RGBAIntegerFormat) return gl.RGBA_INTEGER; // S3TC + if (p === RGBAIntegerFormat) return gl.RGBA_INTEGER; + + // S3TC if (p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format) { if (encoding === sRGBEncoding) { extension = extensions.get('WEBGL_compressed_texture_s3tc_srgb'); - if (extension !== null) { if (p === RGB_S3TC_DXT1_Format) return extension.COMPRESSED_SRGB_S3TC_DXT1_EXT; if (p === RGBA_S3TC_DXT1_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; @@ -17898,7 +15928,6 @@ } } else { 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; @@ -17908,12 +15937,12 @@ return null; } } - } // PVRTC + } + // PVRTC 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; @@ -17922,35 +15951,35 @@ } else { return null; } - } // ETC1 + } + // ETC1 if (p === RGB_ETC1_Format) { extension = extensions.get('WEBGL_compressed_texture_etc1'); - if (extension !== null) { return extension.COMPRESSED_RGB_ETC1_WEBGL; } else { return null; } - } // ETC2 + } + // ETC2 if (p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format) { extension = extensions.get('WEBGL_compressed_texture_etc'); - if (extension !== null) { if (p === RGB_ETC2_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ETC2 : extension.COMPRESSED_RGB8_ETC2; if (p === RGBA_ETC2_EAC_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : extension.COMPRESSED_RGBA8_ETC2_EAC; } else { return null; } - } // ASTC + } + // ASTC 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) { extension = extensions.get('WEBGL_compressed_texture_astc'); - if (extension !== null) { if (p === RGBA_ASTC_4x4_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : extension.COMPRESSED_RGBA_ASTC_4x4_KHR; if (p === RGBA_ASTC_5x4_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : extension.COMPRESSED_RGBA_ASTC_5x4_KHR; @@ -17969,35 +15998,35 @@ } else { return null; } - } // BPTC + } + // BPTC if (p === RGBA_BPTC_Format) { extension = extensions.get('EXT_texture_compression_bptc'); - if (extension !== null) { if (p === RGBA_BPTC_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT : extension.COMPRESSED_RGBA_BPTC_UNORM_EXT; } else { return null; } - } // + } + // if (p === UnsignedInt248Type) { if (isWebGL2) return gl.UNSIGNED_INT_24_8; extension = extensions.get('WEBGL_depth_texture'); - if (extension !== null) { return extension.UNSIGNED_INT_24_8_WEBGL; } else { return null; } - } // if "p" can't be resolved, assume the user defines a WebGL constant as a string (fallback/workaround for packed RGB formats) + } + // if "p" can't be resolved, assume the user defines a WebGL constant as a string (fallback/workaround for packed RGB formats) return gl[p] !== undefined ? gl[p] : null; } - return { convert: convert }; @@ -18009,7 +16038,6 @@ this.isArrayCamera = true; this.cameras = array; } - } class Group extends Object3D { @@ -18018,20 +16046,17 @@ this.isGroup = true; this.type = 'Group'; } - } const _moveEvent = { type: 'move' }; - class WebXRController { constructor() { this._targetRay = null; this._grip = null; this._hand = null; } - getHandSpace() { if (this._hand === null) { this._hand = new Group(); @@ -18042,10 +16067,8 @@ pinching: false }; } - return this._hand; } - getTargetRaySpace() { if (this._targetRay === null) { this._targetRay = new Group(); @@ -18056,10 +16079,8 @@ this._targetRay.hasAngularVelocity = false; this._targetRay.angularVelocity = new Vector3(); } - return this._targetRay; } - getGripSpace() { if (this._grip === null) { this._grip = new Group(); @@ -18070,47 +16091,52 @@ this._grip.hasAngularVelocity = false; this._grip.angularVelocity = new Vector3(); } - return this._grip; } - dispatchEvent(event) { if (this._targetRay !== null) { this._targetRay.dispatchEvent(event); } - if (this._grip !== null) { this._grip.dispatchEvent(event); } - if (this._hand !== null) { this._hand.dispatchEvent(event); } - return this; } - + connect(inputSource) { + if (inputSource && inputSource.hand) { + const hand = this._hand; + if (hand) { + for (const inputjoint of inputSource.hand.values()) { + // Initialize hand with joints when connected + this._getHandJoint(hand, inputjoint); + } + } + } + this.dispatchEvent({ + type: 'connected', + data: inputSource + }); + return this; + } disconnect(inputSource) { this.dispatchEvent({ type: 'disconnected', data: inputSource }); - if (this._targetRay !== null) { this._targetRay.visible = false; } - if (this._grip !== null) { this._grip.visible = false; } - if (this._hand !== null) { this._hand.visible = false; } - return this; } - update(inputSource, frame, referenceSpace) { let inputPose = null; let gripPose = null; @@ -18118,44 +16144,31 @@ const targetRay = this._targetRay; const grip = this._grip; const hand = this._hand; - if (inputSource && frame.session.visibilityState !== 'visible-blurred') { if (hand && inputSource.hand) { handPose = true; - for (const inputjoint of inputSource.hand.values()) { // Update the joints groups with the XRJoint poses const jointPose = frame.getJointPose(inputjoint, referenceSpace); - if (hand.joints[inputjoint.jointName] === undefined) { - // The transform of this joint will be updated with the joint pose on each frame - const joint = new Group(); - joint.matrixAutoUpdate = false; - joint.visible = false; - hand.joints[inputjoint.jointName] = joint; // ?? - - hand.add(joint); - } - - const joint = hand.joints[inputjoint.jointName]; - + // The transform of this joint will be updated with the joint pose on each frame + const joint = this._getHandJoint(hand, inputjoint); if (jointPose !== null) { joint.matrix.fromArray(jointPose.transform.matrix); joint.matrix.decompose(joint.position, joint.rotation, joint.scale); joint.jointRadius = jointPose.radius; } - joint.visible = jointPose !== null; - } // Custom events - // Check pinchz + } + // Custom events + // Check pinchz const indexTip = hand.joints['index-finger-tip']; const thumbTip = hand.joints['thumb-tip']; const distance = indexTip.position.distanceTo(thumbTip.position); const distanceToPinch = 0.02; const threshold = 0.005; - if (hand.inputState.pinching && distance > distanceToPinch + threshold) { hand.inputState.pinching = false; this.dispatchEvent({ @@ -18174,18 +16187,15 @@ } else { if (grip !== null && inputSource.gripSpace) { gripPose = frame.getPose(inputSource.gripSpace, referenceSpace); - if (gripPose !== null) { grip.matrix.fromArray(gripPose.transform.matrix); grip.matrix.decompose(grip.position, grip.rotation, grip.scale); - if (gripPose.linearVelocity) { grip.hasLinearVelocity = true; grip.linearVelocity.copy(gripPose.linearVelocity); } else { grip.hasLinearVelocity = false; } - if (gripPose.angularVelocity) { grip.hasAngularVelocity = true; grip.angularVelocity.copy(gripPose.angularVelocity); @@ -18195,62 +16205,64 @@ } } } - if (targetRay !== null) { - inputPose = frame.getPose(inputSource.targetRaySpace, referenceSpace); // Some runtimes (namely Vive Cosmos with Vive OpenXR Runtime) have only grip space and ray space is equal to it + inputPose = frame.getPose(inputSource.targetRaySpace, referenceSpace); + // Some runtimes (namely Vive Cosmos with Vive OpenXR Runtime) have only grip space and ray space is equal to it if (inputPose === null && gripPose !== null) { inputPose = gripPose; } - if (inputPose !== null) { targetRay.matrix.fromArray(inputPose.transform.matrix); targetRay.matrix.decompose(targetRay.position, targetRay.rotation, targetRay.scale); - if (inputPose.linearVelocity) { targetRay.hasLinearVelocity = true; targetRay.linearVelocity.copy(inputPose.linearVelocity); } else { targetRay.hasLinearVelocity = false; } - if (inputPose.angularVelocity) { targetRay.hasAngularVelocity = true; targetRay.angularVelocity.copy(inputPose.angularVelocity); } else { targetRay.hasAngularVelocity = false; } - this.dispatchEvent(_moveEvent); } } } - if (targetRay !== null) { targetRay.visible = inputPose !== null; } - if (grip !== null) { grip.visible = gripPose !== null; } - if (hand !== null) { hand.visible = handPose !== null; } - return this; } + // private method + + _getHandJoint(hand, inputjoint) { + if (hand.joints[inputjoint.jointName] === undefined) { + const joint = new Group(); + joint.matrixAutoUpdate = false; + joint.visible = false; + hand.joints[inputjoint.jointName] = joint; + hand.add(joint); + } + return hand.joints[inputjoint.jointName]; + } } class DepthTexture extends Texture { constructor(width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format) { format = format !== undefined ? format : DepthFormat; - if (format !== DepthFormat && format !== DepthStencilFormat) { throw new Error('DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat'); } - if (type === undefined && format === DepthFormat) type = UnsignedIntType; if (type === undefined && format === DepthStencilFormat) type = UnsignedInt248Type; super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy); @@ -18264,7 +16276,6 @@ this.flipY = false; this.generateMipmaps = false; } - } class WebXRManager extends EventDispatcher { @@ -18285,7 +16296,11 @@ let initialRenderTarget = null; let newRenderTarget = null; const controllers = []; - const controllerInputSources = []; // + const controllerInputSources = []; + const planes = new Set(); + const planesLastChangedTimes = new Map(); + + // const cameraL = new PerspectiveCamera(); cameraL.layers.enable(1); @@ -18298,55 +16313,46 @@ cameraVR.layers.enable(1); cameraVR.layers.enable(2); let _currentDepthNear = null; - let _currentDepthFar = null; // + let _currentDepthFar = null; + + // this.cameraAutoUpdate = true; this.enabled = false; this.isPresenting = false; - this.getController = function (index) { let controller = controllers[index]; - if (controller === undefined) { controller = new WebXRController(); controllers[index] = controller; } - return controller.getTargetRaySpace(); }; - this.getControllerGrip = function (index) { let controller = controllers[index]; - if (controller === undefined) { controller = new WebXRController(); controllers[index] = controller; } - return controller.getGripSpace(); }; - this.getHand = function (index) { let controller = controllers[index]; - if (controller === undefined) { controller = new WebXRController(); controllers[index] = controller; } - return controller.getHandSpace(); - }; // + }; + // function onSessionEvent(event) { const controllerIndex = controllerInputSources.indexOf(event.inputSource); - if (controllerIndex === -1) { return; } - const controller = controllers[controllerIndex]; - if (controller !== undefined) { controller.dispatchEvent({ type: event.type, @@ -18354,7 +16360,6 @@ }); } } - function onSessionEnd() { session.removeEventListener('select', onSessionEvent); session.removeEventListener('selectstart', onSessionEvent); @@ -18364,23 +16369,25 @@ session.removeEventListener('squeezeend', onSessionEvent); session.removeEventListener('end', onSessionEnd); session.removeEventListener('inputsourceschange', onInputSourcesChange); - for (let i = 0; i < controllers.length; i++) { const inputSource = controllerInputSources[i]; if (inputSource === null) continue; controllerInputSources[i] = null; controllers[i].disconnect(inputSource); } - _currentDepthNear = null; - _currentDepthFar = null; // restore framebuffer/rendering state + _currentDepthFar = null; + + // restore framebuffer/rendering state renderer.setRenderTarget(initialRenderTarget); glBaseLayer = null; glProjLayer = null; glBinding = null; session = null; - newRenderTarget = null; // + newRenderTarget = null; + + // animation.stop(); scope.isPresenting = false; @@ -18388,50 +16395,38 @@ type: 'sessionend' }); } - this.setFramebufferScaleFactor = function (value) { framebufferScaleFactor = value; - if (scope.isPresenting === true) { console.warn('THREE.WebXRManager: Cannot change framebuffer scale while presenting.'); } }; - this.setReferenceSpaceType = function (value) { referenceSpaceType = value; - if (scope.isPresenting === true) { console.warn('THREE.WebXRManager: Cannot change reference space type while presenting.'); } }; - this.getReferenceSpace = function () { return customReferenceSpace || referenceSpace; }; - this.setReferenceSpace = function (space) { customReferenceSpace = space; }; - this.getBaseLayer = function () { return glProjLayer !== null ? glProjLayer : glBaseLayer; }; - this.getBinding = function () { return glBinding; }; - this.getFrame = function () { return xrFrame; }; - this.getSession = function () { return session; }; - this.setSession = async function (value) { session = value; - if (session !== null) { initialRenderTarget = renderer.getRenderTarget(); session.addEventListener('select', onSessionEvent); @@ -18442,11 +16437,9 @@ session.addEventListener('squeezeend', onSessionEvent); session.addEventListener('end', onSessionEnd); session.addEventListener('inputsourceschange', onInputSourcesChange); - if (attributes.xrCompatible !== true) { await gl.makeXRCompatible(); } - if (session.renderState.layers === undefined || renderer.capabilities.isWebGL2 === false) { const layerInit = { antialias: session.renderState.layers === undefined ? attributes.antialias : true, @@ -18462,19 +16455,18 @@ newRenderTarget = new WebGLRenderTarget(glBaseLayer.framebufferWidth, glBaseLayer.framebufferHeight, { format: RGBAFormat, type: UnsignedByteType, - encoding: renderer.outputEncoding + encoding: renderer.outputEncoding, + stencilBuffer: attributes.stencil }); } else { let depthFormat = null; let depthType = null; let glDepthFormat = null; - if (attributes.depth) { glDepthFormat = attributes.stencil ? gl.DEPTH24_STENCIL8 : gl.DEPTH_COMPONENT24; depthFormat = attributes.stencil ? DepthStencilFormat : DepthFormat; depthType = attributes.stencil ? UnsignedInt248Type : UnsignedIntType; } - const projectionlayerInit = { colorFormat: gl.RGBA8, depthFormat: glDepthFormat, @@ -18496,10 +16488,9 @@ const renderTargetProperties = renderer.properties.get(newRenderTarget); renderTargetProperties.__ignoreDepthValues = glProjLayer.ignoreDepthValues; } - newRenderTarget.isXRRenderTarget = true; // TODO Remove this when possible, see #23278 - // Set foveation to maximum. + // Set foveation to maximum. this.setFoveation(1.0); customReferenceSpace = null; referenceSpace = await session.requestReferenceSpace(referenceSpaceType); @@ -18511,29 +16502,26 @@ }); } }; - function onInputSourcesChange(event) { // Notify disconnected + for (let i = 0; i < event.removed.length; i++) { const inputSource = event.removed[i]; const index = controllerInputSources.indexOf(inputSource); - if (index >= 0) { controllerInputSources[index] = null; - controllers[index].dispatchEvent({ - type: 'disconnected', - data: inputSource - }); + controllers[index].disconnect(inputSource); } - } // Notify connected + } + // Notify connected for (let i = 0; i < event.added.length; i++) { const inputSource = event.added[i]; let controllerIndex = controllerInputSources.indexOf(inputSource); - if (controllerIndex === -1) { // Assign input source a controller that currently has no input source + for (let i = 0; i < controllers.length; i++) { if (i >= controllerInputSources.length) { controllerInputSources.push(inputSource); @@ -18544,42 +16532,40 @@ controllerIndex = i; break; } - } // If all controllers do currently receive input we ignore new ones + } + // If all controllers do currently receive input we ignore new ones if (controllerIndex === -1) break; } - const controller = controllers[controllerIndex]; - if (controller) { - controller.dispatchEvent({ - type: 'connected', - data: inputSource - }); + controller.connect(inputSource); } } - } // + } + // const cameraLPos = new Vector3(); const 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); const ipd = cameraLPos.distanceTo(cameraRPos); const projL = cameraL.projectionMatrix.elements; - const projR = cameraR.projectionMatrix.elements; // VR systems will have identical far and near planes, and + const 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. - const near = projL[14] / (projL[10] - 1); const far = projL[14] / (projL[10] + 1); const topFov = (projL[9] + 1) / projL[5]; @@ -18587,20 +16573,23 @@ const leftFov = (projL[8] - 1) / projL[0]; const rightFov = (projR[8] + 1) / projR[0]; const left = near * leftFov; - const right = near * rightFov; // Calculate the new camera's position offset from the - // left camera. xOffset should be roughly half `ipd`. + const right = near * rightFov; + // Calculate the new camera's position offset from the + // left camera. xOffset should be roughly half `ipd`. const zOffset = ipd / (-leftFov + rightFov); - const xOffset = zOffset * -leftFov; // TODO: Better way to apply this offset? + const 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.copy(camera.matrixWorld).invert(); // Find the union of the frustum values of the cameras and scale + camera.matrixWorldInverse.copy(camera.matrixWorld).invert(); + + // 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. - const near2 = near + zOffset; const far2 = far + zOffset; const left2 = left - xOffset; @@ -18609,24 +16598,21 @@ const 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); } - camera.matrixWorldInverse.copy(camera.matrixWorld).invert(); } - this.updateCamera = function (camera) { if (session === null) return; cameraVR.near = cameraR.near = cameraL.near = camera.near; cameraVR.far = cameraR.far = cameraL.far = camera.far; - 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 @@ -18634,156 +16620,182 @@ _currentDepthNear = cameraVR.near; _currentDepthFar = cameraVR.far; } - const parent = camera.parent; const cameras = cameraVR.cameras; updateCamera(cameraVR, parent); - for (let i = 0; i < cameras.length; i++) { updateCamera(cameras[i], parent); } + cameraVR.matrixWorld.decompose(cameraVR.position, cameraVR.quaternion, cameraVR.scale); - cameraVR.matrixWorld.decompose(cameraVR.position, cameraVR.quaternion, cameraVR.scale); // update user camera and its children + // update user camera and its children - camera.position.copy(cameraVR.position); - camera.quaternion.copy(cameraVR.quaternion); - camera.scale.copy(cameraVR.scale); camera.matrix.copy(cameraVR.matrix); - camera.matrixWorld.copy(cameraVR.matrixWorld); + camera.matrix.decompose(camera.position, camera.quaternion, camera.scale); const children = camera.children; - for (let i = 0, l = children.length; i < l; i++) { children[i].updateMatrixWorld(true); - } // update projection matrix for proper view frustum culling + } + // 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); } }; - this.getCamera = function () { return cameraVR; }; - this.getFoveation = function () { if (glProjLayer !== null) { return glProjLayer.fixedFoveation; } - if (glBaseLayer !== null) { return glBaseLayer.fixedFoveation; } - return undefined; }; - this.setFoveation = function (foveation) { // 0 = no foveation = full resolution // 1 = maximum foveation = the edges render at lower resolution + if (glProjLayer !== null) { glProjLayer.fixedFoveation = foveation; } - if (glBaseLayer !== null && glBaseLayer.fixedFoveation !== undefined) { glBaseLayer.fixedFoveation = foveation; } - }; // Animation Loop + }; + this.getPlanes = function () { + return planes; + }; + // Animation Loop let onAnimationFrameCallback = null; - function onAnimationFrame(time, frame) { pose = frame.getViewerPose(customReferenceSpace || referenceSpace); xrFrame = frame; - if (pose !== null) { const views = pose.views; - if (glBaseLayer !== null) { renderer.setRenderTargetFramebuffer(newRenderTarget, glBaseLayer.framebuffer); renderer.setRenderTarget(newRenderTarget); } + let cameraVRNeedsUpdate = false; - let cameraVRNeedsUpdate = false; // check if it's necessary to rebuild cameraVR's camera list + // check if it's necessary to rebuild cameraVR's camera list if (views.length !== cameraVR.cameras.length) { cameraVR.cameras.length = 0; cameraVRNeedsUpdate = true; } - for (let i = 0; i < views.length; i++) { const view = views[i]; let viewport = null; - if (glBaseLayer !== null) { viewport = glBaseLayer.getViewport(view); } else { const glSubImage = glBinding.getViewSubImage(glProjLayer, view); - viewport = glSubImage.viewport; // For side-by-side projection, we only produce a single texture for both eyes. + viewport = glSubImage.viewport; + // For side-by-side projection, we only produce a single texture for both eyes. if (i === 0) { renderer.setRenderTargetTextures(newRenderTarget, glSubImage.colorTexture, glProjLayer.ignoreDepthValues ? undefined : glSubImage.depthStencilTexture); renderer.setRenderTarget(newRenderTarget); } } - let camera = cameras[i]; - if (camera === undefined) { camera = new PerspectiveCamera(); camera.layers.enable(i); camera.viewport = new Vector4(); cameras[i] = camera; } - camera.matrix.fromArray(view.transform.matrix); camera.projectionMatrix.fromArray(view.projectionMatrix); camera.viewport.set(viewport.x, viewport.y, viewport.width, viewport.height); - if (i === 0) { cameraVR.matrix.copy(camera.matrix); } - if (cameraVRNeedsUpdate === true) { cameraVR.cameras.push(camera); } } - } // + } + // for (let i = 0; i < controllers.length; i++) { const inputSource = controllerInputSources[i]; const controller = controllers[i]; - if (inputSource !== null && controller !== undefined) { controller.update(inputSource, frame, customReferenceSpace || referenceSpace); } } - if (onAnimationFrameCallback) onAnimationFrameCallback(time, frame); + if (frame.detectedPlanes) { + scope.dispatchEvent({ + type: 'planesdetected', + data: frame.detectedPlanes + }); + let planesToRemove = null; + for (const plane of planes) { + if (!frame.detectedPlanes.has(plane)) { + if (planesToRemove === null) { + planesToRemove = []; + } + planesToRemove.push(plane); + } + } + if (planesToRemove !== null) { + for (const plane of planesToRemove) { + planes.delete(plane); + planesLastChangedTimes.delete(plane); + scope.dispatchEvent({ + type: 'planeremoved', + data: plane + }); + } + } + for (const plane of frame.detectedPlanes) { + if (!planes.has(plane)) { + planes.add(plane); + planesLastChangedTimes.set(plane, frame.lastChangedTime); + scope.dispatchEvent({ + type: 'planeadded', + data: plane + }); + } else { + const lastKnownTime = planesLastChangedTimes.get(plane); + if (plane.lastChangedTime > lastKnownTime) { + planesLastChangedTimes.set(plane, plane.lastChangedTime); + scope.dispatchEvent({ + type: 'planechanged', + data: plane + }); + } + } + } + } xrFrame = null; } - const animation = new WebGLAnimation(); animation.setAnimationLoop(onAnimationFrame); - this.setAnimationLoop = function (callback) { onAnimationFrameCallback = callback; }; - this.dispose = function () {}; } - } function WebGLMaterials(renderer, properties) { function refreshFogUniforms(uniforms, fog) { - uniforms.fogColor.value.copy(fog.color); - + fog.color.getRGB(uniforms.fogColor.value, getUnlitUniformColorSpace(renderer)); if (fog.isFog) { uniforms.fogNear.value = fog.near; uniforms.fogFar.value = fog.far; @@ -18791,7 +16803,6 @@ uniforms.fogDensity.value = fog.density; } } - function refreshMaterialUniforms(uniforms, material, pixelRatio, height, transmissionRenderTarget) { if (material.isMeshBasicMaterial) { refreshUniformsCommon(uniforms, material); @@ -18806,7 +16817,6 @@ } else if (material.isMeshStandardMaterial) { refreshUniformsCommon(uniforms, material); refreshUniformsStandard(uniforms, material); - if (material.isMeshPhysicalMaterial) { refreshUniformsPhysical(uniforms, material, transmissionRenderTarget); } @@ -18822,7 +16832,6 @@ refreshUniformsCommon(uniforms, material); } else if (material.isLineBasicMaterial) { refreshUniformsLine(uniforms, material); - if (material.isLineDashedMaterial) { refreshUniformsDash(uniforms, material); } @@ -18840,55 +16849,43 @@ function refreshUniformsCommon(uniforms, material) { uniforms.opacity.value = material.opacity; - if (material.color) { uniforms.diffuse.value.copy(material.color); } - if (material.emissive) { uniforms.emissive.value.copy(material.emissive).multiplyScalar(material.emissiveIntensity); } - if (material.map) { uniforms.map.value = material.map; } - if (material.alphaMap) { uniforms.alphaMap.value = material.alphaMap; } - if (material.bumpMap) { uniforms.bumpMap.value = material.bumpMap; uniforms.bumpScale.value = material.bumpScale; if (material.side === BackSide) uniforms.bumpScale.value *= -1; } - if (material.displacementMap) { uniforms.displacementMap.value = material.displacementMap; uniforms.displacementScale.value = material.displacementScale; uniforms.displacementBias.value = material.displacementBias; } - if (material.emissiveMap) { uniforms.emissiveMap.value = material.emissiveMap; } - if (material.normalMap) { uniforms.normalMap.value = material.normalMap; uniforms.normalScale.value.copy(material.normalScale); if (material.side === BackSide) uniforms.normalScale.value.negate(); } - if (material.specularMap) { uniforms.specularMap.value = material.specularMap; } - if (material.alphaTest > 0) { uniforms.alphaTest.value = material.alphaTest; } - const envMap = properties.get(material).envMap; - if (envMap) { uniforms.envMap.value = envMap; uniforms.flipEnvMap.value = envMap.isCubeTexture && envMap.isRenderTargetTexture === false ? -1 : 1; @@ -18896,18 +16893,19 @@ uniforms.ior.value = material.ior; uniforms.refractionRatio.value = material.refractionRatio; } - if (material.lightMap) { - uniforms.lightMap.value = material.lightMap; // artist-friendly light intensity scaling factor + uniforms.lightMap.value = material.lightMap; + // artist-friendly light intensity scaling factor const scaleFactor = renderer.physicallyCorrectLights !== true ? Math.PI : 1; uniforms.lightMapIntensity.value = material.lightMapIntensity * scaleFactor; } - if (material.aoMap) { uniforms.aoMap.value = material.aoMap; uniforms.aoMapIntensity.value = material.aoMapIntensity; - } // uv repeat and offset setting priorities + } + + // uv repeat and offset setting priorities // 1. color map // 2. specular map // 3. displacementMap map @@ -18927,9 +16925,7 @@ // 17. transmission map // 18. thickness map - let uvScaleMap; - if (material.map) { uvScaleMap = material.map; } else if (material.specularMap) { @@ -18971,131 +16967,110 @@ } else if (material.sheenRoughnessMap) { uvScaleMap = material.sheenRoughnessMap; } - if (uvScaleMap !== undefined) { // backwards compatibility if (uvScaleMap.isWebGLRenderTarget) { uvScaleMap = uvScaleMap.texture; } - if (uvScaleMap.matrixAutoUpdate === true) { uvScaleMap.updateMatrix(); } - uniforms.uvTransform.value.copy(uvScaleMap.matrix); - } // uv repeat and offset setting priorities for uv2 + } + + // uv repeat and offset setting priorities for uv2 // 1. ao map // 2. light map - let uv2ScaleMap; - if (material.aoMap) { uv2ScaleMap = material.aoMap; } else if (material.lightMap) { uv2ScaleMap = material.lightMap; } - if (uv2ScaleMap !== undefined) { // backwards compatibility if (uv2ScaleMap.isWebGLRenderTarget) { uv2ScaleMap = uv2ScaleMap.texture; } - if (uv2ScaleMap.matrixAutoUpdate === true) { uv2ScaleMap.updateMatrix(); } - uniforms.uv2Transform.value.copy(uv2ScaleMap.matrix); } } - function refreshUniformsLine(uniforms, material) { uniforms.diffuse.value.copy(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 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; } - if (material.alphaMap) { uniforms.alphaMap.value = material.alphaMap; } - if (material.alphaTest > 0) { uniforms.alphaTest.value = material.alphaTest; - } // uv repeat and offset setting priorities + } + + // uv repeat and offset setting priorities // 1. color map // 2. alpha map - let uvScaleMap; - 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); } } - function refreshUniformsSprites(uniforms, material) { uniforms.diffuse.value.copy(material.color); uniforms.opacity.value = material.opacity; uniforms.rotation.value = material.rotation; - if (material.map) { uniforms.map.value = material.map; } - if (material.alphaMap) { uniforms.alphaMap.value = material.alphaMap; } - if (material.alphaTest > 0) { uniforms.alphaTest.value = material.alphaTest; - } // uv repeat and offset setting priorities + } + + // uv repeat and offset setting priorities // 1. color map // 2. alpha map - let uvScaleMap; - 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); } } - 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 ) @@ -19106,123 +17081,96 @@ uniforms.gradientMap.value = material.gradientMap; } } - 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; } - const envMap = properties.get(material).envMap; - if (envMap) { //uniforms.envMap.value = material.envMap; // part of uniforms common uniforms.envMapIntensity.value = material.envMapIntensity; } } - function refreshUniformsPhysical(uniforms, material, transmissionRenderTarget) { uniforms.ior.value = material.ior; // also part of uniforms common if (material.sheen > 0) { uniforms.sheenColor.value.copy(material.sheenColor).multiplyScalar(material.sheen); uniforms.sheenRoughness.value = material.sheenRoughness; - if (material.sheenColorMap) { uniforms.sheenColorMap.value = material.sheenColorMap; } - if (material.sheenRoughnessMap) { uniforms.sheenRoughnessMap.value = material.sheenRoughnessMap; } } - if (material.clearcoat > 0) { uniforms.clearcoat.value = material.clearcoat; uniforms.clearcoatRoughness.value = material.clearcoatRoughness; - if (material.clearcoatMap) { uniforms.clearcoatMap.value = material.clearcoatMap; } - if (material.clearcoatRoughnessMap) { uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap; } - if (material.clearcoatNormalMap) { uniforms.clearcoatNormalScale.value.copy(material.clearcoatNormalScale); uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap; - if (material.side === BackSide) { uniforms.clearcoatNormalScale.value.negate(); } } } - if (material.iridescence > 0) { uniforms.iridescence.value = material.iridescence; uniforms.iridescenceIOR.value = material.iridescenceIOR; uniforms.iridescenceThicknessMinimum.value = material.iridescenceThicknessRange[0]; uniforms.iridescenceThicknessMaximum.value = material.iridescenceThicknessRange[1]; - if (material.iridescenceMap) { uniforms.iridescenceMap.value = material.iridescenceMap; } - if (material.iridescenceThicknessMap) { uniforms.iridescenceThicknessMap.value = material.iridescenceThicknessMap; } } - if (material.transmission > 0) { uniforms.transmission.value = material.transmission; uniforms.transmissionSamplerMap.value = transmissionRenderTarget.texture; uniforms.transmissionSamplerSize.value.set(transmissionRenderTarget.width, transmissionRenderTarget.height); - if (material.transmissionMap) { uniforms.transmissionMap.value = material.transmissionMap; } - uniforms.thickness.value = material.thickness; - if (material.thicknessMap) { uniforms.thicknessMap.value = material.thicknessMap; } - uniforms.attenuationDistance.value = material.attenuationDistance; uniforms.attenuationColor.value.copy(material.attenuationColor); } - uniforms.specularIntensity.value = material.specularIntensity; uniforms.specularColor.value.copy(material.specularColor); - if (material.specularIntensityMap) { uniforms.specularIntensityMap.value = material.specularIntensityMap; } - if (material.specularColorMap) { uniforms.specularColorMap.value = material.specularColorMap; } } - function refreshUniformsMatcap(uniforms, material) { if (material.matcap) { uniforms.matcap.value = material.matcap; } } - function refreshUniformsDistance(uniforms, material) { uniforms.referencePosition.value.copy(material.referencePosition); uniforms.nearDistance.value = material.nearDistance; uniforms.farDistance.value = material.farDistance; } - return { refreshFogUniforms: refreshFogUniforms, refreshMaterialUniforms: refreshMaterialUniforms @@ -19239,31 +17187,31 @@ const webglProgram = program.program; state.uniformBlockBinding(uniformsGroup, webglProgram); } - function update(uniformsGroup, program) { let buffer = buffers[uniformsGroup.id]; - if (buffer === undefined) { prepareUniformsGroup(uniformsGroup); buffer = createBuffer(uniformsGroup); buffers[uniformsGroup.id] = buffer; uniformsGroup.addEventListener('dispose', onUniformsGroupsDispose); - } // ensure to update the binding points/block indices mapping for this program + } + // ensure to update the binding points/block indices mapping for this program const webglProgram = program.program; - state.updateUBOMapping(uniformsGroup, webglProgram); // update UBO once per frame + state.updateUBOMapping(uniformsGroup, webglProgram); - const frame = info.render.frame; + // update UBO once per frame + const frame = info.render.frame; if (updateList[uniformsGroup.id] !== frame) { updateBufferData(uniformsGroup); updateList[uniformsGroup.id] = frame; } } - function createBuffer(uniformsGroup) { // the setup of an UBO is independent of a particular shader program but global + const bindingPointIndex = allocateBindingPointIndex(); uniformsGroup.__bindingPointIndex = bindingPointIndex; const buffer = gl.createBuffer(); @@ -19275,7 +17223,6 @@ gl.bindBufferBase(gl.UNIFORM_BUFFER, bindingPointIndex, buffer); return buffer; } - function allocateBindingPointIndex() { for (let i = 0; i < maxBindingPoints; i++) { if (allocatedBindingPoints.indexOf(i) === -1) { @@ -19283,30 +17230,29 @@ return i; } } - console.error('THREE.WebGLRenderer: Maximum number of simultaneously usable uniforms groups reached.'); return 0; } - function updateBufferData(uniformsGroup) { const buffer = buffers[uniformsGroup.id]; const uniforms = uniformsGroup.uniforms; const cache = uniformsGroup.__cache; gl.bindBuffer(gl.UNIFORM_BUFFER, buffer); - for (let i = 0, il = uniforms.length; i < il; i++) { - const uniform = uniforms[i]; // partly update the buffer if necessary + const uniform = uniforms[i]; + + // partly update the buffer if necessary if (hasUniformChanged(uniform, i, cache) === true) { const value = uniform.value; const offset = uniform.__offset; - if (typeof value === 'number') { uniform.__data[0] = value; gl.bufferSubData(gl.UNIFORM_BUFFER, offset, uniform.__data); } else { if (uniform.value.isMatrix3) { // manually converting 3x3 to 3x4 + uniform.__data[0] = uniform.value.elements[0]; uniform.__data[1] = uniform.value.elements[1]; uniform.__data[2] = uniform.value.elements[2]; @@ -19322,29 +17268,26 @@ } else { value.toArray(uniform.__data); } - gl.bufferSubData(gl.UNIFORM_BUFFER, offset, uniform.__data); } } } - gl.bindBuffer(gl.UNIFORM_BUFFER, null); } - function hasUniformChanged(uniform, index, cache) { const value = uniform.value; - if (cache[index] === undefined) { // cache entry does not exist so far + if (typeof value === 'number') { cache[index] = value; } else { cache[index] = value.clone(); } - return true; } else { // compare current value with cached entry + if (typeof value === 'number') { if (cache[index] !== value) { cache[index] = value; @@ -19352,88 +17295,99 @@ } } else { const cachedObject = cache[index]; - if (cachedObject.equals(value) === false) { cachedObject.copy(value); return true; } } } - return false; } - function prepareUniformsGroup(uniformsGroup) { // determine total buffer size according to the STD140 layout // Hint: STD140 is the only supported layout in WebGL 2 + const uniforms = uniformsGroup.uniforms; let offset = 0; // global buffer offset in bytes - const chunkSize = 16; // size of a chunk in bytes - let chunkOffset = 0; // offset within a single chunk in bytes for (let i = 0, l = uniforms.length; i < l; i++) { const uniform = uniforms[i]; - const info = getUniformSize(uniform); // the following two properties will be used for partial buffer updates + const info = getUniformSize(uniform); + + // the following two properties will be used for partial buffer updates uniform.__data = new Float32Array(info.storage / Float32Array.BYTES_PER_ELEMENT); - uniform.__offset = offset; // + uniform.__offset = offset; + + // if (i > 0) { chunkOffset = offset % chunkSize; - const remainingSizeInChunk = chunkSize - chunkOffset; // check for chunk overflow + const remainingSizeInChunk = chunkSize - chunkOffset; + + // check for chunk overflow if (chunkOffset !== 0 && remainingSizeInChunk - info.boundary < 0) { // add padding and adjust offset + offset += chunkSize - chunkOffset; uniform.__offset = offset; } } - offset += info.storage; - } // ensure correct final padding + } + // ensure correct final padding chunkOffset = offset % chunkSize; - if (chunkOffset > 0) offset += chunkSize - chunkOffset; // + if (chunkOffset > 0) offset += chunkSize - chunkOffset; + + // uniformsGroup.__size = offset; uniformsGroup.__cache = {}; return this; } - function getUniformSize(uniform) { const value = uniform.value; const info = { boundary: 0, // bytes storage: 0 // bytes + }; - }; // determine sizes according to STD140 + // determine sizes according to STD140 if (typeof value === 'number') { // float/int + info.boundary = 4; info.storage = 4; } else if (value.isVector2) { // vec2 + info.boundary = 8; info.storage = 8; } else if (value.isVector3 || value.isColor) { // vec3 + info.boundary = 16; info.storage = 12; // evil: vec3 must start on a 16-byte boundary but it only consumes 12 bytes } else if (value.isVector4) { // vec4 + info.boundary = 16; info.storage = 16; } else if (value.isMatrix3) { // mat3 (in STD140 a 3x3 matrix is represented as 3x4) + info.boundary = 48; info.storage = 48; } else if (value.isMatrix4) { // mat4 + info.boundary = 64; info.storage = 64; } else if (value.isTexture) { @@ -19441,10 +17395,8 @@ } else { console.warn('THREE.WebGLRenderer: Unsupported uniform value type.', value); } - return info; } - function onUniformsGroupsDispose(event) { const uniformsGroup = event.target; uniformsGroup.removeEventListener('dispose', onUniformsGroupsDispose); @@ -19454,17 +17406,14 @@ delete buffers[uniformsGroup.id]; delete updateList[uniformsGroup.id]; } - function dispose() { for (const id in buffers) { gl.deleteBuffer(buffers[id]); } - allocatedBindingPoints = []; buffers = {}; updateList = {}; } - return { bind: bind, update: update, @@ -19477,119 +17426,119 @@ canvas.style.display = 'block'; return canvas; } - function WebGLRenderer(parameters = {}) { this.isWebGLRenderer = true; - const _canvas = parameters.canvas !== undefined ? parameters.canvas : createCanvasElement(), - _context = parameters.context !== undefined ? parameters.context : null, - _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; - + _context = parameters.context !== undefined ? parameters.context : null, + _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; let _alpha; - if (_context !== null) { _alpha = _context.getContextAttributes().alpha; } else { _alpha = parameters.alpha !== undefined ? parameters.alpha : false; } - let currentRenderList = null; - let currentRenderState = null; // render() can be called from within a callback triggered by another render. + let currentRenderState = null; + + // render() can be called from within a callback triggered by another render. // We track this so that the nested render call gets its list and state isolated from the parent render call. const renderListStack = []; - const renderStateStack = []; // public properties + const renderStateStack = []; + + // public properties - this.domElement = _canvas; // Debug configuration container + this.domElement = _canvas; + // Debug configuration container this.debug = { /** * Enables error checking and reporting when shader programs are being compiled * @type {boolean} */ checkShaderErrors: true - }; // clearing + }; + + // clearing this.autoClear = true; this.autoClearColor = true; this.autoClearDepth = true; - this.autoClearStencil = true; // scene graph + this.autoClearStencil = true; - this.sortObjects = true; // user-defined clipping + // scene graph + + this.sortObjects = true; + + // user-defined clipping this.clippingPlanes = []; - this.localClippingEnabled = false; // physically based shading + this.localClippingEnabled = false; + + // physically based shading + + this.outputEncoding = LinearEncoding; - this.outputEncoding = LinearEncoding; // physical lights + // physical lights - this.physicallyCorrectLights = false; // tone mapping + this.physicallyCorrectLights = false; + + // tone mapping this.toneMapping = NoToneMapping; - this.toneMappingExposure = 1.0; // + this.toneMappingExposure = 1.0; - Object.defineProperties(this, { - // @deprecated since r136, 0e21088102b4de7e0a0a33140620b7a3424b9e6d - gammaFactor: { - get: function () { - console.warn('THREE.WebGLRenderer: .gammaFactor has been removed.'); - return 2; - }, - set: function () { - console.warn('THREE.WebGLRenderer: .gammaFactor has been removed.'); - } - } - }); // internal properties + // internal properties const _this = this; + let _isContextLost = false; - let _isContextLost = false; // internal state cache + // internal state cache let _currentActiveCubeFace = 0; let _currentActiveMipmapLevel = 0; let _currentRenderTarget = null; - let _currentMaterialId = -1; - let _currentCamera = null; - const _currentViewport = new Vector4(); - const _currentScissor = new Vector4(); + let _currentScissorTest = null; - let _currentScissorTest = null; // + // let _width = _canvas.width; let _height = _canvas.height; let _pixelRatio = 1; let _opaqueSort = null; let _transparentSort = null; - const _viewport = new Vector4(0, 0, _width, _height); - const _scissor = new Vector4(0, 0, _width, _height); + let _scissorTest = false; - let _scissorTest = false; // frustum + // frustum - const _frustum = new Frustum(); // clipping + const _frustum = new Frustum(); + // clipping let _clippingEnabled = false; - let _localClippingEnabled = false; // transmission + let _localClippingEnabled = false; - let _transmissionRenderTarget = null; // camera matrices cache + // transmission - const _projScreenMatrix = new Matrix4(); + let _transmissionRenderTarget = null; - const _vector2 = new Vector2(); + // camera matrices cache + const _projScreenMatrix = new Matrix4(); + const _vector2 = new Vector2(); const _vector3 = new Vector3(); - const _emptyScene = { background: null, fog: null, @@ -19597,26 +17546,21 @@ overrideMaterial: null, isScene: true }; - function getTargetPixelRatio() { return _currentRenderTarget === null ? _pixelRatio : 1; - } // initialize + } + // initialize let _gl = _context; - function getContext(contextNames, contextAttributes) { for (let i = 0; i < contextNames.length; i++) { const contextName = contextNames[i]; - const context = _canvas.getContext(contextName, contextAttributes); - if (context !== null) return context; } - return null; } - try { const contextAttributes = { alpha: true, @@ -19627,25 +17571,21 @@ preserveDrawingBuffer: _preserveDrawingBuffer, powerPreference: _powerPreference, failIfMajorPerformanceCaveat: _failIfMajorPerformanceCaveat - }; // OffscreenCanvas does not have setAttribute, see #22811 + }; - if ('setAttribute' in _canvas) _canvas.setAttribute('data-engine', `three.js r${REVISION}`); // event listeners must be registered before WebGL context is created, see #12753 + // OffscreenCanvas does not have setAttribute, see #22811 + if ('setAttribute' in _canvas) _canvas.setAttribute('data-engine', `three.js r${REVISION}`); + // event listeners must be registered before WebGL context is created, see #12753 _canvas.addEventListener('webglcontextlost', onContextLost, false); - _canvas.addEventListener('webglcontextrestored', onContextRestore, false); - _canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false); - if (_gl === null) { const contextNames = ['webgl2', 'webgl', 'experimental-webgl']; - 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.'); @@ -19653,8 +17593,9 @@ throw new Error('Error creating WebGL context.'); } } - } // Some experimental-webgl implementations do not have getShaderPrecisionFormat + } + // Some experimental-webgl implementations do not have getShaderPrecisionFormat if (_gl.getShaderPrecisionFormat === undefined) { _gl.getShaderPrecisionFormat = function () { @@ -19669,13 +17610,11 @@ console.error('THREE.WebGLRenderer: ' + error.message); throw error; } - let extensions, capabilities, state, info; let properties, textures, cubemaps, cubeuvmaps, attributes, geometries, objects; let programCache, materials, renderLists, renderStates, clipping, shadowMap; let background, morphtargets, bufferRenderer, indexedBufferRenderer; let utils, bindingStates, uniformsGroups; - function initGLContext() { extensions = new WebGLExtensions(_gl); capabilities = new WebGLCapabilities(_gl, extensions, parameters); @@ -19697,7 +17636,7 @@ materials = new WebGLMaterials(_this, properties); renderLists = new WebGLRenderLists(); renderStates = new WebGLRenderStates(extensions, capabilities); - background = new WebGLBackground(_this, cubemaps, state, objects, _alpha, _premultipliedAlpha); + background = new WebGLBackground(_this, cubemaps, cubeuvmaps, state, objects, _alpha, _premultipliedAlpha); shadowMap = new WebGLShadowMap(_this, objects, capabilities); uniformsGroups = new WebGLUniformsGroups(_gl, info, capabilities, state); bufferRenderer = new WebGLBufferRenderer(_gl, extensions, info, capabilities); @@ -19711,67 +17650,58 @@ _this.state = state; _this.info = info; } + initGLContext(); - initGLContext(); // xr + // xr const xr = new WebXRManager(_this, _gl); - this.xr = xr; // API + this.xr = xr; + + // API this.getContext = function () { return _gl; }; - this.getContextAttributes = function () { return _gl.getContextAttributes(); }; - this.forceContextLoss = function () { const extension = extensions.get('WEBGL_lose_context'); if (extension) extension.loseContext(); }; - this.forceContextRestore = function () { const extension = extensions.get('WEBGL_lose_context'); if (extension) extension.restoreContext(); }; - this.getPixelRatio = function () { return _pixelRatio; }; - this.setPixelRatio = function (value) { if (value === undefined) return; _pixelRatio = value; this.setSize(_width, _height, false); }; - this.getSize = function (target) { 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; } - _width = width; _height = height; _canvas.width = Math.floor(width * _pixelRatio); _canvas.height = Math.floor(height * _pixelRatio); - if (updateStyle !== false) { _canvas.style.width = width + 'px'; _canvas.style.height = height + 'px'; } - this.setViewport(0, 0, width, height); }; - this.getDrawingBufferSize = function (target) { return target.set(_width * _pixelRatio, _height * _pixelRatio).floor(); }; - this.setDrawingBufferSize = function (width, height, pixelRatio) { _width = width; _height = height; @@ -19780,101 +17710,81 @@ _canvas.height = Math.floor(height * pixelRatio); this.setViewport(0, 0, width, height); }; - this.getCurrentViewport = function (target) { return target.copy(_currentViewport); }; - this.getViewport = function (target) { return target.copy(_viewport); }; - 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); } - state.viewport(_currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor()); }; - 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); } - state.scissor(_currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor()); }; - this.getScissorTest = function () { return _scissorTest; }; - this.setScissorTest = function (boolean) { state.setScissorTest(_scissorTest = boolean); }; - this.setOpaqueSort = function (method) { _opaqueSort = method; }; - this.setTransparentSort = function (method) { _transparentSort = method; - }; // Clearing + }; + // Clearing this.getClearColor = function (target) { return target.copy(background.getClearColor()); }; - this.setClearColor = function () { background.setClearColor.apply(background, arguments); }; - this.getClearAlpha = function () { return background.getClearAlpha(); }; - this.setClearAlpha = function () { background.setClearAlpha.apply(background, arguments); }; - this.clear = function (color = true, depth = true, stencil = true) { let bits = 0; if (color) bits |= _gl.COLOR_BUFFER_BIT; if (depth) bits |= _gl.DEPTH_BUFFER_BIT; if (stencil) bits |= _gl.STENCIL_BUFFER_BIT; - _gl.clear(bits); }; - this.clearColor = function () { this.clear(true, false, false); }; - this.clearDepth = function () { this.clear(false, true, false); }; - this.clearStencil = function () { this.clear(false, false, true); - }; // + }; + // this.dispose = function () { _canvas.removeEventListener('webglcontextlost', onContextLost, false); - _canvas.removeEventListener('webglcontextrestored', onContextRestore, false); - _canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false); - renderLists.dispose(); renderStates.dispose(); properties.dispose(); @@ -19887,25 +17797,21 @@ xr.dispose(); xr.removeEventListener('sessionstart', onXRSessionStart); xr.removeEventListener('sessionend', onXRSessionEnd); - if (_transmissionRenderTarget) { _transmissionRenderTarget.dispose(); - _transmissionRenderTarget = null; } - animation.stop(); - }; // Events + }; + // Events function onContextLost(event) { event.preventDefault(); console.log('THREE.WebGLRenderer: Context Lost.'); _isContextLost = true; } - - function - /* event */ + function /* event */ onContextRestore() { console.log('THREE.WebGLRenderer: Context Restored.'); _isContextLost = false; @@ -19921,82 +17827,83 @@ shadowMap.needsUpdate = shadowMapNeedsUpdate; shadowMap.type = shadowMapType; } - function onContextCreationError(event) { console.error('THREE.WebGLRenderer: A WebGL context could not be created. Reason: ', event.statusMessage); } - function onMaterialDispose(event) { const material = event.target; material.removeEventListener('dispose', onMaterialDispose); deallocateMaterial(material); - } // Buffer deallocation + } + // Buffer deallocation function deallocateMaterial(material) { releaseMaterialProgramReferences(material); properties.remove(material); } - function releaseMaterialProgramReferences(material) { const programs = properties.get(material).programs; - if (programs !== undefined) { programs.forEach(function (program) { programCache.releaseProgram(program); }); - if (material.isShaderMaterial) { programCache.releaseShaderCache(material); } } - } // Buffer rendering + } + // Buffer rendering this.renderBufferDirect = function (camera, scene, geometry, material, object, group) { if (scene === null) scene = _emptyScene; // renderBufferDirect second parameter used to be fog (could be null) const frontFaceCW = object.isMesh && object.matrixWorld.determinant() < 0; const program = setProgram(camera, scene, geometry, material, object); - state.setMaterial(material, frontFaceCW); // - - let index = geometry.index; - const position = geometry.attributes.position; // - - if (index === null) { - if (position === undefined || position.count === 0) return; - } else if (index.count === 0) { - return; - } // + state.setMaterial(material, frontFaceCW); + // + let index = geometry.index; let rangeFactor = 1; - if (material.wireframe === true) { index = geometries.getWireframeAttribute(geometry); rangeFactor = 2; } + // + + const drawRange = geometry.drawRange; + const position = geometry.attributes.position; + let drawStart = drawRange.start * rangeFactor; + let drawEnd = (drawRange.start + drawRange.count) * rangeFactor; + if (group !== null) { + drawStart = Math.max(drawStart, group.start * rangeFactor); + drawEnd = Math.min(drawEnd, (group.start + group.count) * rangeFactor); + } + if (index !== null) { + drawStart = Math.max(drawStart, 0); + drawEnd = Math.min(drawEnd, index.count); + } else if (position !== undefined && position !== null) { + drawStart = Math.max(drawStart, 0); + drawEnd = Math.min(drawEnd, position.count); + } + const drawCount = drawEnd - drawStart; + if (drawCount < 0 || drawCount === Infinity) return; + + // + bindingStates.setup(object, material, program, geometry, index); let attribute; let renderer = bufferRenderer; - if (index !== null) { attribute = attributes.get(index); renderer = indexedBufferRenderer; renderer.setIndex(attribute); - } // - + } - const dataCount = index !== null ? index.count : position.count; - const rangeStart = geometry.drawRange.start * rangeFactor; - const rangeCount = geometry.drawRange.count * rangeFactor; - const groupStart = group !== null ? group.start * rangeFactor : 0; - const groupCount = group !== null ? group.count * rangeFactor : Infinity; - const drawStart = Math.max(rangeStart, groupStart); - const drawEnd = Math.min(dataCount, rangeStart + rangeCount, groupStart + groupCount) - 1; - const drawCount = Math.max(0, drawEnd - drawStart + 1); - if (drawCount === 0) return; // + // if (object.isMesh) { if (material.wireframe === true) { @@ -20010,7 +17917,6 @@ if (lineWidth === undefined) lineWidth = 1; // Not using Line*Material state.setLineWidth(lineWidth * getTargetPixelRatio()); - if (object.isLineSegments) { renderer.setMode(_gl.LINES); } else if (object.isLineLoop) { @@ -20023,26 +17929,39 @@ } else if (object.isSprite) { renderer.setMode(_gl.TRIANGLES); } - if (object.isInstancedMesh) { renderer.renderInstances(drawStart, drawCount, object.count); } else if (geometry.isInstancedBufferGeometry) { - const instanceCount = Math.min(geometry.instanceCount, geometry._maxInstanceCount); + const maxInstanceCount = geometry._maxInstanceCount !== undefined ? geometry._maxInstanceCount : Infinity; + const instanceCount = Math.min(geometry.instanceCount, maxInstanceCount); renderer.renderInstances(drawStart, drawCount, instanceCount); } else { renderer.render(drawStart, drawCount); } - }; // Compile + }; + // Compile this.compile = function (scene, camera) { + function prepare(material, scene, object) { + if (material.transparent === true && material.side === DoubleSide) { + material.side = BackSide; + material.needsUpdate = true; + getProgram(material, scene, object); + material.side = FrontSide; + material.needsUpdate = true; + getProgram(material, scene, object); + material.side = DoubleSide; + } else { + getProgram(material, scene, object); + } + } currentRenderState = renderStates.get(scene); currentRenderState.init(); renderStateStack.push(currentRenderState); scene.traverseVisible(function (object) { if (object.isLight && object.layers.test(camera.layers)) { currentRenderState.pushLight(object); - if (object.castShadow) { currentRenderState.pushShadow(object); } @@ -20051,77 +17970,72 @@ currentRenderState.setupLights(_this.physicallyCorrectLights); scene.traverse(function (object) { const material = object.material; - if (material) { if (Array.isArray(material)) { for (let i = 0; i < material.length; i++) { const material2 = material[i]; - getProgram(material2, scene, object); + prepare(material2, scene, object); } } else { - getProgram(material, scene, object); + prepare(material, scene, object); } } }); renderStateStack.pop(); currentRenderState = null; - }; // Animation Loop + }; + // Animation Loop let onAnimationFrameCallback = null; - function onAnimationFrame(time) { if (onAnimationFrameCallback) onAnimationFrameCallback(time); } - function onXRSessionStart() { animation.stop(); } - function onXRSessionEnd() { animation.start(); } - const animation = new WebGLAnimation(); animation.setAnimationLoop(onAnimationFrame); if (typeof self !== 'undefined') animation.setContext(self); - this.setAnimationLoop = function (callback) { onAnimationFrameCallback = callback; xr.setAnimationLoop(callback); callback === null ? animation.stop() : animation.start(); }; - xr.addEventListener('sessionstart', onXRSessionStart); - xr.addEventListener('sessionend', onXRSessionEnd); // Rendering + xr.addEventListener('sessionend', onXRSessionEnd); + + // Rendering this.render = function (scene, camera) { if (camera !== undefined && camera.isCamera !== true) { console.error('THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.'); return; } + if (_isContextLost === true) return; - if (_isContextLost === true) return; // update scene graph + // update scene graph - if (scene.autoUpdate === true) scene.updateMatrixWorld(); // update camera matrices and frustum + if (scene.matrixWorldAutoUpdate === true) scene.updateMatrixWorld(); - if (camera.parent === null) camera.updateMatrixWorld(); + // update camera matrices and frustum + if (camera.parent === null && camera.matrixWorldAutoUpdate === true) camera.updateMatrixWorld(); if (xr.enabled === true && xr.isPresenting === true) { if (xr.cameraAutoUpdate === true) xr.updateCamera(camera); camera = xr.getCamera(); // use XR camera for rendering - } // - + } + // if (scene.isScene === true) scene.onBeforeRender(_this, scene, camera, _currentRenderTarget); currentRenderState = renderStates.get(scene, renderStateStack.length); currentRenderState.init(); renderStateStack.push(currentRenderState); - _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); - _frustum.setFromProjectionMatrix(_projScreenMatrix); - _localClippingEnabled = this.localClippingEnabled; _clippingEnabled = clipping.init(this.clippingPlanes, _localClippingEnabled, camera); currentRenderList = renderLists.get(scene, renderListStack.length); @@ -20129,69 +18043,75 @@ renderListStack.push(currentRenderList); projectObject(scene, camera, 0, _this.sortObjects); currentRenderList.finish(); - if (_this.sortObjects === true) { currentRenderList.sort(_opaqueSort, _transparentSort); - } // + } + // if (_clippingEnabled === true) clipping.beginShadows(); const shadowsArray = currentRenderState.state.shadowsArray; shadowMap.render(shadowsArray, scene, camera); - if (_clippingEnabled === true) clipping.endShadows(); // + if (_clippingEnabled === true) clipping.endShadows(); - if (this.info.autoReset === true) this.info.reset(); // + // - background.render(currentRenderList, scene); // render scene + if (this.info.autoReset === true) this.info.reset(); - currentRenderState.setupLights(_this.physicallyCorrectLights); + // + + background.render(currentRenderList, scene); + // render scene + + currentRenderState.setupLights(_this.physicallyCorrectLights); if (camera.isArrayCamera) { const cameras = camera.cameras; - for (let i = 0, l = cameras.length; i < l; i++) { const camera2 = cameras[i]; renderScene(currentRenderList, scene, camera2, camera2.viewport); } } else { renderScene(currentRenderList, scene, camera); - } // + } + // if (_currentRenderTarget !== null) { // resolve multisample renderbuffers to a single-sample texture if necessary - textures.updateMultisampleRenderTarget(_currentRenderTarget); // Generate mipmap if we're using any kind of mipmap filtering + + textures.updateMultisampleRenderTarget(_currentRenderTarget); + + // Generate mipmap if we're using any kind of mipmap filtering textures.updateRenderTargetMipmap(_currentRenderTarget); - } // + } + // + + if (scene.isScene === true) scene.onAfterRender(_this, scene, camera); - if (scene.isScene === true) scene.onAfterRender(_this, scene, camera); // _gl.finish(); + // _gl.finish(); bindingStates.resetDefaultState(); _currentMaterialId = -1; _currentCamera = null; renderStateStack.pop(); - if (renderStateStack.length > 0) { currentRenderState = renderStateStack[renderStateStack.length - 1]; } else { currentRenderState = null; } - renderListStack.pop(); - if (renderListStack.length > 0) { currentRenderList = renderListStack[renderListStack.length - 1]; } else { currentRenderList = null; } }; - function projectObject(object, camera, groupOrder, sortObjects) { if (object.visible === false) return; const visible = object.layers.test(camera.layers); - if (visible) { if (object.isGroup) { groupOrder = object.renderOrder; @@ -20199,7 +18119,6 @@ if (object.autoUpdate === true) object.update(camera); } else if (object.isLight) { currentRenderState.pushLight(object); - if (object.castShadow) { currentRenderState.pushShadow(object); } @@ -20208,10 +18127,8 @@ if (sortObjects) { _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); } - const geometry = objects.update(object); const material = object.material; - if (material.visible) { currentRenderList.push(object, geometry, material, groupOrder, _vector3.z, null); } @@ -20219,27 +18136,23 @@ } 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; } } - if (!object.frustumCulled || _frustum.intersectsObject(object)) { if (sortObjects) { _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); } - const geometry = objects.update(object); const material = object.material; - if (Array.isArray(material)) { const groups = geometry.groups; - for (let i = 0, l = groups.length; i < l; i++) { const group = groups[i]; const groupMaterial = material[group.materialIndex]; - if (groupMaterial && groupMaterial.visible) { currentRenderList.push(object, geometry, groupMaterial, groupOrder, _vector3.z, group); } @@ -20250,14 +18163,11 @@ } } } - const children = object.children; - for (let i = 0, l = children.length; i < l; i++) { projectObject(children[i], camera, groupOrder, sortObjects); } } - function renderScene(currentRenderList, scene, camera, viewport) { const opaqueObjects = currentRenderList.opaque; const transmissiveObjects = currentRenderList.transmissive; @@ -20267,17 +18177,17 @@ if (viewport) state.viewport(_currentViewport.copy(viewport)); if (opaqueObjects.length > 0) renderObjects(opaqueObjects, scene, camera); if (transmissiveObjects.length > 0) renderObjects(transmissiveObjects, scene, camera); - if (transparentObjects.length > 0) renderObjects(transparentObjects, scene, camera); // Ensure depth buffer writing is enabled so it can be cleared on next render + if (transparentObjects.length > 0) renderObjects(transparentObjects, scene, camera); + + // Ensure depth buffer writing is enabled so it can be cleared on next render state.buffers.depth.setTest(true); state.buffers.depth.setMask(true); state.buffers.color.setMask(true); state.setPolygonOffset(false); } - function renderTransmissionPass(opaqueObjects, scene, camera) { const isWebGL2 = capabilities.isWebGL2; - if (_transmissionRenderTarget === null) { _transmissionRenderTarget = new WebGLRenderTarget(1, 1, { generateMipmaps: true, @@ -20286,75 +18196,60 @@ samples: isWebGL2 && _antialias === true ? 4 : 0 }); } - _this.getDrawingBufferSize(_vector2); - if (isWebGL2) { _transmissionRenderTarget.setSize(_vector2.x, _vector2.y); } else { _transmissionRenderTarget.setSize(floorPowerOfTwo(_vector2.x), floorPowerOfTwo(_vector2.y)); - } // + } + // const currentRenderTarget = _this.getRenderTarget(); - _this.setRenderTarget(_transmissionRenderTarget); + _this.clear(); - _this.clear(); // Turn off the features which can affect the frag color for opaque objects pass. + // Turn off the features which can affect the frag color for opaque objects pass. // Otherwise they are applied twice in opaque objects pass and transmission objects pass. - - const currentToneMapping = _this.toneMapping; _this.toneMapping = NoToneMapping; renderObjects(opaqueObjects, scene, camera); _this.toneMapping = currentToneMapping; textures.updateMultisampleRenderTarget(_transmissionRenderTarget); textures.updateRenderTargetMipmap(_transmissionRenderTarget); - _this.setRenderTarget(currentRenderTarget); } - function renderObjects(renderList, scene, camera) { const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null; - for (let i = 0, l = renderList.length; i < l; i++) { const renderItem = renderList[i]; const object = renderItem.object; const geometry = renderItem.geometry; const material = overrideMaterial === null ? renderItem.material : overrideMaterial; const group = renderItem.group; - if (object.layers.test(camera.layers)) { renderObject(object, scene, camera, geometry, material, group); } } } - function renderObject(object, scene, camera, geometry, material, group) { object.onBeforeRender(_this, scene, camera, geometry, material, group); object.modelViewMatrix.multiplyMatrices(camera.matrixWorldInverse, object.matrixWorld); object.normalMatrix.getNormalMatrix(object.modelViewMatrix); material.onBeforeRender(_this, scene, camera, geometry, object, group); - if (material.transparent === true && material.side === DoubleSide) { material.side = BackSide; material.needsUpdate = true; - _this.renderBufferDirect(camera, scene, geometry, material, object, group); - material.side = FrontSide; material.needsUpdate = true; - _this.renderBufferDirect(camera, scene, geometry, material, object, group); - material.side = DoubleSide; } else { _this.renderBufferDirect(camera, scene, geometry, material, object, group); } - object.onAfterRender(_this, scene, camera, geometry, material, group); } - function getProgram(material, scene, object) { if (scene.isScene !== true) scene = _emptyScene; // scene could be a Mesh, Line, Points, ... @@ -20364,23 +18259,24 @@ const lightsStateVersion = lights.state.version; const parameters = programCache.getParameters(material, lights.state, shadowsArray, scene, object); const programCacheKey = programCache.getProgramCacheKey(parameters); - let programs = materialProperties.programs; // always update environment and fog - changing these trigger an getProgram call, but it's possible that the program doesn't change + let programs = materialProperties.programs; + + // always update environment and fog - changing these trigger an getProgram call, but it's possible that the program doesn't change materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null; materialProperties.fog = scene.fog; materialProperties.envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || materialProperties.environment); - if (programs === undefined) { // new material + material.addEventListener('dispose', onMaterialDispose); programs = new Map(); materialProperties.programs = programs; } - let program = programs.get(programCacheKey); - if (program !== undefined) { // early out if program and light state is identical + if (materialProperties.currentProgram === program && materialProperties.lightsStateVersion === lightsStateVersion) { updateCommonMaterialProperties(material, parameters); return program; @@ -20393,20 +18289,19 @@ programs.set(programCacheKey, program); materialProperties.uniforms = parameters.uniforms; } - const uniforms = materialProperties.uniforms; - if (!material.isShaderMaterial && !material.isRawShaderMaterial || material.clipping === true) { uniforms.clippingPlanes = clipping.uniform; } + updateCommonMaterialProperties(material, parameters); - updateCommonMaterialProperties(material, parameters); // store the light setup it was created for + // 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; @@ -20422,9 +18317,11 @@ 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.spotLightMatrix.value = lights.state.spotLightMatrix; + uniforms.spotLightMap.value = lights.state.spotLightMap; uniforms.pointShadowMap.value = lights.state.pointShadowMap; - uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; // TODO (abelnation): add area lights shadow info to uniforms + uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; + // TODO (abelnation): add area lights shadow info to uniforms } const progUniforms = program.getUniforms(); @@ -20433,7 +18330,6 @@ materialProperties.uniformsList = uniformsList; return program; } - function updateCommonMaterialProperties(material, parameters) { const materialProperties = properties.get(material); materialProperties.outputEncoding = parameters.outputEncoding; @@ -20449,7 +18345,6 @@ materialProperties.vertexTangents = parameters.vertexTangents; materialProperties.toneMapping = parameters.toneMapping; } - function setProgram(camera, scene, geometry, material, object) { if (scene.isScene !== true) scene = _emptyScene; // scene could be a Mesh, Line, Points, ... @@ -20468,20 +18363,20 @@ const morphTargetsCount = morphAttribute !== undefined ? morphAttribute.length : 0; const materialProperties = properties.get(material); const lights = currentRenderState.state.lights; - if (_clippingEnabled === true) { if (_localClippingEnabled === true || camera !== _currentCamera) { - const useCache = camera === _currentCamera && material.id === _currentMaterialId; // we might want to call this function with some ClippingGroup + const 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); } - } // + } + // let needsProgramChange = false; - if (material.version === materialProperties.__version) { if (materialProperties.needsLights && materialProperties.lightsStateVersion !== lights.state.version) { needsProgramChange = true; @@ -20519,76 +18414,69 @@ } else { needsProgramChange = true; materialProperties.__version = material.version; - } // + } + // let program = materialProperties.currentProgram; - if (needsProgramChange === true) { program = getProgram(material, scene, object); } - let refreshProgram = false; let refreshMaterial = false; let refreshLights = false; const p_uniforms = program.getUniforms(), - m_uniforms = materialProperties.uniforms; - + m_uniforms = materialProperties.uniforms; if (state.useProgram(program.program)) { refreshProgram = true; refreshMaterial = true; refreshLights = true; } - if (material.id !== _currentMaterialId) { _currentMaterialId = material.id; refreshMaterial = true; } - 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 + _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: refreshMaterial = true; // set to true on material change - refreshLights = true; // remains set until update done - } // load material specific uniforms - // (shader material also gets them for the sake of genericity) + } + // load material specific uniforms + // (shader material also gets them for the sake of genericity) if (material.isShaderMaterial || material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshStandardMaterial || material.envMap) { const uCamPos = p_uniforms.map.cameraPosition; - if (uCamPos !== undefined) { uCamPos.setValue(_gl, _vector3.setFromMatrixPosition(camera.matrixWorld)); } } - if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial) { p_uniforms.setValue(_gl, 'isOrthographic', camera.isOrthographicCamera === true); } - if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial || material.isShadowMaterial || object.isSkinnedMesh) { p_uniforms.setValue(_gl, 'viewMatrix', camera.matrixWorldInverse); } - } // skinning and morph target uniforms must be set even if material didn't change + } + + // skinning and morph target uniforms must be set even if material didn't change // auto-setting of texture unit for bone and morph texture must go before other textures // otherwise textures used for skinning and morphing can take over texture units reserved for other material textures - if (object.isSkinnedMesh) { p_uniforms.setOptional(_gl, object, 'bindMatrix'); p_uniforms.setOptional(_gl, object, 'bindMatrixInverse'); const skeleton = object.skeleton; - if (skeleton) { if (capabilities.floatVertexTextures) { if (skeleton.boneTexture === null) skeleton.computeBoneTexture(); @@ -20599,58 +18487,62 @@ } } } - const morphAttributes = geometry.morphAttributes; - if (morphAttributes.position !== undefined || morphAttributes.normal !== undefined || morphAttributes.color !== undefined && capabilities.isWebGL2 === true) { morphtargets.update(object, geometry, material, program); } - if (refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow) { materialProperties.receiveShadow = object.receiveShadow; p_uniforms.setValue(_gl, 'receiveShadow', object.receiveShadow); } + // https://github.com/mrdoob/three.js/pull/24467#issuecomment-1209031512 + + if (material.isMeshGouraudMaterial && material.envMap !== null) { + m_uniforms.envMap.value = envMap; + m_uniforms.flipEnvMap.value = envMap.isCubeTexture && envMap.isRenderTargetTexture === false ? -1 : 1; + } if (refreshMaterial) { p_uniforms.setValue(_gl, 'toneMappingExposure', _this.toneMappingExposure); - 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 + } + // refresh uniforms common to several materials if (fog && material.fog === true) { materials.refreshFogUniforms(m_uniforms, fog); } - materials.refreshMaterialUniforms(m_uniforms, material, _pixelRatio, _height, _transmissionRenderTarget); 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 (material.isSpriteMaterial) { p_uniforms.setValue(_gl, 'center', object.center); - } // common matrices + } + // common matrices p_uniforms.setValue(_gl, 'modelViewMatrix', object.modelViewMatrix); p_uniforms.setValue(_gl, 'normalMatrix', object.normalMatrix); - p_uniforms.setValue(_gl, 'modelMatrix', object.matrixWorld); // UBOs + p_uniforms.setValue(_gl, 'modelMatrix', object.matrixWorld); + + // UBOs if (material.isShaderMaterial || material.isRawShaderMaterial) { const groups = material.uniformsGroups; - for (let i = 0, l = groups.length; i < l; i++) { if (capabilities.isWebGL2) { const group = groups[i]; @@ -20661,10 +18553,10 @@ } } } - return program; - } // If uniforms are marked as clean, they don't need to be loaded to the GPU. + } + // If uniforms are marked as clean, they don't need to be loaded to the GPU. function markUniformsLightsNeedsUpdate(uniforms, value) { uniforms.ambientLightColor.needsUpdate = value; @@ -20678,32 +18570,25 @@ 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; } - this.getActiveCubeFace = function () { return _currentActiveCubeFace; }; - this.getActiveMipmapLevel = function () { return _currentActiveMipmapLevel; }; - this.getRenderTarget = function () { return _currentRenderTarget; }; - this.setRenderTargetTextures = function (renderTarget, colorTexture, depthTexture) { properties.get(renderTarget.texture).__webglTexture = colorTexture; properties.get(renderTarget.depthTexture).__webglTexture = depthTexture; const renderTargetProperties = properties.get(renderTarget); renderTargetProperties.__hasExternalTextures = true; - if (renderTargetProperties.__hasExternalTextures) { renderTargetProperties.__autoAllocateDepthBuffer = depthTexture === undefined; - if (!renderTargetProperties.__autoAllocateDepthBuffer) { // The multisample_render_to_texture extension doesn't work properly if there // are midframe flushes and an external depth buffer. Disable use of the extension. @@ -20714,22 +18599,21 @@ } } }; - this.setRenderTargetFramebuffer = function (renderTarget, defaultFramebuffer) { const renderTargetProperties = properties.get(renderTarget); renderTargetProperties.__webglFramebuffer = defaultFramebuffer; renderTargetProperties.__useDefaultFramebuffer = defaultFramebuffer === undefined; }; - this.setRenderTarget = function (renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) { _currentRenderTarget = renderTarget; _currentActiveCubeFace = activeCubeFace; _currentActiveMipmapLevel = activeMipmapLevel; let useDefaultFramebuffer = true; - + let framebuffer = null; + let isCube = false; + let isRenderTarget3D = false; if (renderTarget) { const renderTargetProperties = properties.get(renderTarget); - if (renderTargetProperties.__useDefaultFramebuffer !== undefined) { // We need to make sure to rebind the framebuffer. state.bindFramebuffer(_gl.FRAMEBUFFER, null); @@ -20740,21 +18624,11 @@ // Color and depth texture must be rebound in order for the swapchain to update. textures.rebindTextures(renderTarget, properties.get(renderTarget.texture).__webglTexture, properties.get(renderTarget.depthTexture).__webglTexture); } - } - - let framebuffer = null; - let isCube = false; - let isRenderTarget3D = false; - - if (renderTarget) { const texture = renderTarget.texture; - - if (texture.isData3DTexture || texture.isDataArrayTexture) { + if (texture.isData3DTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture) { isRenderTarget3D = true; } - const __webglFramebuffer = properties.get(renderTarget).__webglFramebuffer; - if (renderTarget.isWebGLCubeRenderTarget) { framebuffer = __webglFramebuffer[activeCubeFace]; isCube = true; @@ -20763,41 +18637,29 @@ } else { framebuffer = __webglFramebuffer; } - _currentViewport.copy(renderTarget.viewport); - _currentScissor.copy(renderTarget.scissor); - _currentScissorTest = renderTarget.scissorTest; } else { _currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor(); - _currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor(); - _currentScissorTest = _scissorTest; } - const framebufferBound = state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); - if (framebufferBound && capabilities.drawBuffers && useDefaultFramebuffer) { state.drawBuffers(renderTarget, framebuffer); } - state.viewport(_currentViewport); state.scissor(_currentScissor); state.setScissorTest(_currentScissorTest); - if (isCube) { const textureProperties = properties.get(renderTarget.texture); - _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + activeCubeFace, textureProperties.__webglTexture, activeMipmapLevel); } else if (isRenderTarget3D) { const textureProperties = properties.get(renderTarget.texture); const layer = activeCubeFace || 0; - _gl.framebufferTextureLayer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureProperties.__webglTexture, activeMipmapLevel || 0, layer); } - _currentMaterialId = -1; // reset current material to ensure correct uniform bindings }; @@ -20806,72 +18668,63 @@ console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.'); return; } - let framebuffer = properties.get(renderTarget).__webglFramebuffer; - if (renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== undefined) { framebuffer = framebuffer[activeCubeFaceIndex]; } - if (framebuffer) { state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); - try { const texture = renderTarget.texture; const textureFormat = texture.format; const textureType = texture.type; - if (textureFormat !== RGBAFormat && utils.convert(textureFormat) !== _gl.getParameter(_gl.IMPLEMENTATION_COLOR_READ_FORMAT)) { console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.'); return; } - const halfFloatSupportedByExt = textureType === HalfFloatType && (extensions.has('EXT_color_buffer_half_float') || capabilities.isWebGL2 && extensions.has('EXT_color_buffer_float')); - - if (textureType !== UnsignedByteType && utils.convert(textureType) !== _gl.getParameter(_gl.IMPLEMENTATION_COLOR_READ_TYPE) && // Edge and Chrome Mac < 52 (#9513) - !(textureType === FloatType && (capabilities.isWebGL2 || extensions.has('OES_texture_float') || extensions.has('WEBGL_color_buffer_float'))) && // Chrome Mac >= 52 and Firefox + if (textureType !== UnsignedByteType && utils.convert(textureType) !== _gl.getParameter(_gl.IMPLEMENTATION_COLOR_READ_TYPE) && + // Edge and Chrome Mac < 52 (#9513) + !(textureType === FloatType && (capabilities.isWebGL2 || extensions.has('OES_texture_float') || extensions.has('WEBGL_color_buffer_float'))) && + // Chrome Mac >= 52 and Firefox !halfFloatSupportedByExt) { console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.'); return; - } // the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604) + } + // 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); } } finally { // restore framebuffer of current render target if necessary + const framebuffer = _currentRenderTarget !== null ? properties.get(_currentRenderTarget).__webglFramebuffer : null; state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); } } }; - this.copyFramebufferToTexture = function (position, texture, level = 0) { const levelScale = Math.pow(2, -level); const width = Math.floor(texture.image.width * levelScale); const height = Math.floor(texture.image.height * levelScale); textures.setTexture2D(texture, 0); - _gl.copyTexSubImage2D(_gl.TEXTURE_2D, level, 0, 0, position.x, position.y, width, height); - state.unbindTexture(); }; - this.copyTextureToTexture = function (position, srcTexture, dstTexture, level = 0) { const width = srcTexture.image.width; const height = srcTexture.image.height; const glFormat = utils.convert(dstTexture.format); const 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 + textures.setTexture2D(dstTexture, 0); + // As another texture upload may have changed pixelStorei + // parameters, make sure they are correct for the dstTexture _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY); - _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha); - _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment); - if (srcTexture.isDataTexture) { _gl.texSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data); } else { @@ -20880,26 +18733,23 @@ } else { _gl.texSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, glFormat, glType, srcTexture.image); } - } // Generate mipmaps only when copying level 0 - + } + // Generate mipmaps only when copying level 0 if (level === 0 && dstTexture.generateMipmaps) _gl.generateMipmap(_gl.TEXTURE_2D); state.unbindTexture(); }; - this.copyTextureToTexture3D = function (sourceBox, position, srcTexture, dstTexture, level = 0) { if (_this.isWebGL1Renderer) { console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: can only be used with WebGL2.'); return; } - const width = sourceBox.max.x - sourceBox.min.x + 1; const height = sourceBox.max.y - sourceBox.min.y + 1; const depth = sourceBox.max.z - sourceBox.min.z + 1; const glFormat = utils.convert(dstTexture.format); const glType = utils.convert(dstTexture.type); let glTarget; - if (dstTexture.isData3DTexture) { textures.setTexture3D(dstTexture, 0); glTarget = _gl.TEXTURE_3D; @@ -20910,76 +18760,52 @@ console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: only supports THREE.DataTexture3D and THREE.DataTexture2DArray.'); return; } - _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY); - _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha); - _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment); - const unpackRowLen = _gl.getParameter(_gl.UNPACK_ROW_LENGTH); - const unpackImageHeight = _gl.getParameter(_gl.UNPACK_IMAGE_HEIGHT); - const unpackSkipPixels = _gl.getParameter(_gl.UNPACK_SKIP_PIXELS); - const unpackSkipRows = _gl.getParameter(_gl.UNPACK_SKIP_ROWS); - const unpackSkipImages = _gl.getParameter(_gl.UNPACK_SKIP_IMAGES); - const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[0] : srcTexture.image; - _gl.pixelStorei(_gl.UNPACK_ROW_LENGTH, image.width); - _gl.pixelStorei(_gl.UNPACK_IMAGE_HEIGHT, image.height); - _gl.pixelStorei(_gl.UNPACK_SKIP_PIXELS, sourceBox.min.x); - _gl.pixelStorei(_gl.UNPACK_SKIP_ROWS, sourceBox.min.y); - _gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, sourceBox.min.z); - if (srcTexture.isDataTexture || srcTexture.isData3DTexture) { _gl.texSubImage3D(glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, glType, image.data); } else { - if (srcTexture.isCompressedTexture) { + if (srcTexture.isCompressedArrayTexture) { console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: untested support for compressed srcTexture.'); - _gl.compressedTexSubImage3D(glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, image.data); } else { _gl.texSubImage3D(glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, glType, image); } } - _gl.pixelStorei(_gl.UNPACK_ROW_LENGTH, unpackRowLen); - _gl.pixelStorei(_gl.UNPACK_IMAGE_HEIGHT, unpackImageHeight); - _gl.pixelStorei(_gl.UNPACK_SKIP_PIXELS, unpackSkipPixels); - _gl.pixelStorei(_gl.UNPACK_SKIP_ROWS, unpackSkipRows); + _gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, unpackSkipImages); - _gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, unpackSkipImages); // Generate mipmaps only when copying level 0 - - + // Generate mipmaps only when copying level 0 if (level === 0 && dstTexture.generateMipmaps) _gl.generateMipmap(glTarget); state.unbindTexture(); }; - this.initTexture = function (texture) { if (texture.isCubeTexture) { textures.setTextureCube(texture, 0); } else if (texture.isData3DTexture) { textures.setTexture3D(texture, 0); - } else if (texture.isDataArrayTexture) { + } else if (texture.isDataArrayTexture || texture.isCompressedArrayTexture) { textures.setTexture2DArray(texture, 0); } else { textures.setTexture2D(texture, 0); } - state.unbindTexture(); }; - this.resetState = function () { _currentActiveCubeFace = 0; _currentActiveMipmapLevel = 0; @@ -20987,7 +18813,6 @@ state.reset(); bindingStates.reset(); }; - if (typeof __THREE_DEVTOOLS__ !== 'undefined') { __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('observe', { detail: this @@ -20996,7 +18821,6 @@ } class WebGL1Renderer extends WebGLRenderer {} - WebGL1Renderer.prototype.isWebGL1Renderer = true; class FogExp2 { @@ -21006,11 +18830,9 @@ this.color = new Color(color); this.density = density; } - clone() { return new FogExp2(this.color, this.density); } - toJSON() { return { type: 'FogExp2', @@ -21018,7 +18840,6 @@ density: this.density }; } - } class Fog { @@ -21029,11 +18850,9 @@ this.near = near; this.far = far; } - clone() { return new Fog(this.color, this.near, this.far); } - toJSON() { return { type: 'Fog', @@ -21042,7 +18861,6 @@ far: this.far }; } - } class Scene extends Object3D { @@ -21053,33 +18871,44 @@ this.background = null; this.environment = null; this.fog = null; + this.backgroundBlurriness = 0; + this.backgroundIntensity = 1; this.overrideMaterial = null; - this.autoUpdate = true; // checked by the renderer - if (typeof __THREE_DEVTOOLS__ !== 'undefined') { __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('observe', { detail: this })); } } - copy(source, recursive) { super.copy(source, recursive); 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(); + this.backgroundBlurriness = source.backgroundBlurriness; + this.backgroundIntensity = source.backgroundIntensity; if (source.overrideMaterial !== null) this.overrideMaterial = source.overrideMaterial.clone(); - this.autoUpdate = source.autoUpdate; this.matrixAutoUpdate = source.matrixAutoUpdate; return this; } - toJSON(meta) { const data = super.toJSON(meta); if (this.fog !== null) data.object.fog = this.fog.toJSON(); + if (this.backgroundBlurriness > 0) data.backgroundBlurriness = this.backgroundBlurriness; + if (this.backgroundIntensity !== 1) data.backgroundIntensity = this.backgroundIntensity; return data; } + // @deprecated + + get autoUpdate() { + console.warn('THREE.Scene: autoUpdate was renamed to matrixWorldAutoUpdate in r144.'); + return this.matrixWorldAutoUpdate; + } + set autoUpdate(value) { + console.warn('THREE.Scene: autoUpdate was renamed to matrixWorldAutoUpdate in r144.'); + this.matrixWorldAutoUpdate = value; + } } class InterleavedBuffer { @@ -21096,18 +18925,14 @@ this.version = 0; this.uuid = generateUUID(); } - onUploadCallback() {} - set needsUpdate(value) { if (value === true) this.version++; } - setUsage(value) { this.usage = value; return this; } - copy(source) { this.array = new source.array.constructor(source.array); this.count = source.count; @@ -21115,61 +18940,52 @@ this.usage = source.usage; return this; } - copyAt(index1, attribute, index2) { index1 *= this.stride; index2 *= attribute.stride; - for (let i = 0, l = this.stride; i < l; i++) { this.array[index1 + i] = attribute.array[index2 + i]; } - return this; } - set(value, offset = 0) { this.array.set(value, offset); return this; } - clone(data) { if (data.arrayBuffers === undefined) { data.arrayBuffers = {}; } - if (this.array.buffer._uuid === undefined) { this.array.buffer._uuid = generateUUID(); } - if (data.arrayBuffers[this.array.buffer._uuid] === undefined) { data.arrayBuffers[this.array.buffer._uuid] = this.array.slice(0).buffer; } - const array = new this.array.constructor(data.arrayBuffers[this.array.buffer._uuid]); const ib = new this.constructor(array, this.stride); ib.setUsage(this.usage); return ib; } - onUpload(callback) { this.onUploadCallback = callback; return this; } - toJSON(data) { if (data.arrayBuffers === undefined) { data.arrayBuffers = {}; - } // generate UUID for array buffer if necessary + } + // generate UUID for array buffer if necessary if (this.array.buffer._uuid === undefined) { this.array.buffer._uuid = generateUUID(); } - if (data.arrayBuffers[this.array.buffer._uuid] === undefined) { data.arrayBuffers[this.array.buffer._uuid] = Array.from(new Uint32Array(this.array.buffer)); - } // + } + // return { uuid: this.uuid, @@ -21178,11 +18994,9 @@ stride: this.stride }; } - } const _vector$6 = /*@__PURE__*/new Vector3(); - class InterleavedBufferAttribute { constructor(interleavedBuffer, itemSize, offset, normalized = false) { this.isInterleavedBufferAttribute = true; @@ -21192,155 +19006,148 @@ this.offset = offset; this.normalized = normalized === true; } - get count() { return this.data.count; } - get array() { return this.data.array; } - set needsUpdate(value) { this.data.needsUpdate = value; } - applyMatrix4(m) { for (let i = 0, l = this.data.count; i < l; i++) { _vector$6.fromBufferAttribute(this, i); - _vector$6.applyMatrix4(m); - this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); } - return this; } - applyNormalMatrix(m) { for (let i = 0, l = this.count; i < l; i++) { _vector$6.fromBufferAttribute(this, i); - _vector$6.applyNormalMatrix(m); - this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); } - return this; } - transformDirection(m) { for (let i = 0, l = this.count; i < l; i++) { _vector$6.fromBufferAttribute(this, i); - _vector$6.transformDirection(m); - this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); } - return this; } - setX(index, x) { + if (this.normalized) x = normalize(x, this.array); this.data.array[index * this.data.stride + this.offset] = x; return this; } - setY(index, y) { + if (this.normalized) y = normalize(y, this.array); this.data.array[index * this.data.stride + this.offset + 1] = y; return this; } - setZ(index, z) { + if (this.normalized) z = normalize(z, this.array); this.data.array[index * this.data.stride + this.offset + 2] = z; return this; } - setW(index, w) { + if (this.normalized) w = normalize(w, this.array); this.data.array[index * this.data.stride + this.offset + 3] = w; return this; } - getX(index) { - return this.data.array[index * this.data.stride + this.offset]; + let x = this.data.array[index * this.data.stride + this.offset]; + if (this.normalized) x = denormalize(x, this.array); + return x; } - getY(index) { - return this.data.array[index * this.data.stride + this.offset + 1]; + let y = this.data.array[index * this.data.stride + this.offset + 1]; + if (this.normalized) y = denormalize(y, this.array); + return y; } - getZ(index) { - return this.data.array[index * this.data.stride + this.offset + 2]; + let z = this.data.array[index * this.data.stride + this.offset + 2]; + if (this.normalized) z = denormalize(z, this.array); + return z; } - getW(index) { - return this.data.array[index * this.data.stride + this.offset + 3]; + let w = this.data.array[index * this.data.stride + this.offset + 3]; + if (this.normalized) w = denormalize(w, this.array); + return w; } - setXY(index, x, y) { index = index * this.data.stride + this.offset; + if (this.normalized) { + x = normalize(x, this.array); + y = normalize(y, this.array); + } this.data.array[index + 0] = x; this.data.array[index + 1] = y; return this; } - setXYZ(index, x, y, z) { index = index * this.data.stride + this.offset; + if (this.normalized) { + x = normalize(x, this.array); + y = normalize(y, this.array); + z = normalize(z, this.array); + } this.data.array[index + 0] = x; this.data.array[index + 1] = y; this.data.array[index + 2] = z; return this; } - setXYZW(index, x, y, z, w) { index = index * this.data.stride + this.offset; + if (this.normalized) { + x = normalize(x, this.array); + y = normalize(y, this.array); + z = normalize(z, this.array); + w = normalize(w, this.array); + } 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(data) { if (data === undefined) { - console.log('THREE.InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will deinterleave buffer data.'); + console.log('THREE.InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will de-interleave buffer data.'); const array = []; - for (let i = 0; i < this.count; i++) { const index = i * this.data.stride + this.offset; - for (let j = 0; j < this.itemSize; j++) { array.push(this.data.array[index + j]); } } - return new BufferAttribute(new this.array.constructor(array), this.itemSize, this.normalized); } else { if (data.interleavedBuffers === undefined) { data.interleavedBuffers = {}; } - 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(data) { if (data === undefined) { - console.log('THREE.InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will deinterleave buffer data.'); + console.log('THREE.InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will de-interleave buffer data.'); const array = []; - for (let i = 0; i < this.count; i++) { const index = i * this.data.stride + this.offset; - for (let 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 + } + // de-interleave data and save it as an ordinary buffer attribute for now return { itemSize: this.itemSize, @@ -21349,15 +19156,14 @@ normalized: this.normalized }; } else { - // save as true interleaved attribtue + // save as true interleaved attribute + if (data.interleavedBuffers === undefined) { data.interleavedBuffers = {}; } - if (data.interleavedBuffers[this.data.uuid] === undefined) { data.interleavedBuffers[this.data.uuid] = this.data.toJSON(data); } - return { isInterleavedBufferAttribute: true, itemSize: this.itemSize, @@ -21367,7 +19173,6 @@ }; } } - } class SpriteMaterial extends Material { @@ -21384,7 +19189,6 @@ this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.color.copy(source.color); @@ -21395,110 +19199,74 @@ this.fog = source.fog; return this; } - } let _geometry; - const _intersectPoint = /*@__PURE__*/new Vector3(); - const _worldScale = /*@__PURE__*/new Vector3(); - const _mvPosition = /*@__PURE__*/new Vector3(); - const _alignedPosition = /*@__PURE__*/new Vector2(); - const _rotatedPosition = /*@__PURE__*/new Vector2(); - const _viewWorldMatrix = /*@__PURE__*/new Matrix4(); - const _vA = /*@__PURE__*/new Vector3(); - const _vB = /*@__PURE__*/new Vector3(); - const _vC = /*@__PURE__*/new Vector3(); - const _uvA = /*@__PURE__*/new Vector2(); - const _uvB = /*@__PURE__*/new Vector2(); - const _uvC = /*@__PURE__*/new Vector2(); - class Sprite extends Object3D { constructor(material) { super(); this.isSprite = true; this.type = 'Sprite'; - if (_geometry === undefined) { _geometry = new BufferGeometry(); const 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]); const interleavedBuffer = new InterleavedBuffer(float32Array, 5); - _geometry.setIndex([0, 1, 2, 0, 2, 3]); - _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); } - raycast(raycaster, intersects) { if (raycaster.camera === null) { console.error('THREE.Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.'); } - _worldScale.setFromMatrixScale(this.matrixWorld); - _viewWorldMatrix.copy(raycaster.camera.matrixWorld); - this.modelViewMatrix.multiplyMatrices(raycaster.camera.matrixWorldInverse, this.matrixWorld); - _mvPosition.setFromMatrixPosition(this.modelViewMatrix); - if (raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false) { _worldScale.multiplyScalar(-_mvPosition.z); } - const rotation = this.material.rotation; let sin, cos; - if (rotation !== 0) { cos = Math.cos(rotation); sin = Math.sin(rotation); } - const center = this.center; transformVertex(_vA.set(-0.5, -0.5, 0), _mvPosition, center, _worldScale, sin, cos); transformVertex(_vB.set(0.5, -0.5, 0), _mvPosition, center, _worldScale, sin, cos); transformVertex(_vC.set(0.5, 0.5, 0), _mvPosition, center, _worldScale, sin, cos); - _uvA.set(0, 0); - _uvB.set(1, 0); + _uvC.set(1, 1); - _uvC.set(1, 1); // check first triangle - - + // check first triangle let intersect = raycaster.ray.intersectTriangle(_vA, _vB, _vC, false, _intersectPoint); - if (intersect === null) { // check second triangle transformVertex(_vB.set(-0.5, 0.5, 0), _mvPosition, center, _worldScale, sin, cos); - _uvB.set(0, 1); - intersect = raycaster.ray.intersectTriangle(_vA, _vC, _vB, false, _intersectPoint); - if (intersect === null) { return; } } - const distance = raycaster.ray.origin.distanceTo(_intersectPoint); if (distance < raycaster.near || distance > raycaster.far) return; intersects.push({ @@ -21509,39 +19277,34 @@ object: this }); } - copy(source, recursive) { super.copy(source, recursive); if (source.center !== undefined) this.center.copy(source.center); this.material = source.material; return this; } - } - 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 - + _alignedPosition.subVectors(vertexPosition, center).addScalar(0.5).multiply(scale); + // to check if rotation is not zero 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 + vertexPosition.y += _rotatedPosition.y; + // transform to world space vertexPosition.applyMatrix4(_viewWorldMatrix); } const _v1$2 = /*@__PURE__*/new Vector3(); - const _v2$1 = /*@__PURE__*/new Vector3(); - class LOD extends Object3D { constructor() { super(); @@ -21558,130 +19321,109 @@ }); this.autoUpdate = true; } - copy(source) { super.copy(source, false); const levels = source.levels; - for (let i = 0, l = levels.length; i < l; i++) { const level = levels[i]; - this.addLevel(level.object.clone(), level.distance); + this.addLevel(level.object.clone(), level.distance, level.hysteresis); } - this.autoUpdate = source.autoUpdate; return this; } - - addLevel(object, distance = 0) { + addLevel(object, distance = 0, hysteresis = 0) { distance = Math.abs(distance); const levels = this.levels; let l; - for (l = 0; l < levels.length; l++) { if (distance < levels[l].distance) { break; } } - levels.splice(l, 0, { distance: distance, + hysteresis: hysteresis, object: object }); this.add(object); return this; } - getCurrentLevel() { return this._currentLevel; } - getObjectForDistance(distance) { const levels = this.levels; - if (levels.length > 0) { let i, l; - for (i = 1, l = levels.length; i < l; i++) { - if (distance < levels[i].distance) { + let levelDistance = levels[i].distance; + if (levels[i].object.visible) { + levelDistance -= levelDistance * levels[i].hysteresis; + } + if (distance < levelDistance) { break; } } - return levels[i - 1].object; } - return null; } - raycast(raycaster, intersects) { const levels = this.levels; - if (levels.length > 0) { _v1$2.setFromMatrixPosition(this.matrixWorld); - const distance = raycaster.ray.origin.distanceTo(_v1$2); this.getObjectForDistance(distance).raycast(raycaster, intersects); } } - update(camera) { const levels = this.levels; - if (levels.length > 1) { _v1$2.setFromMatrixPosition(camera.matrixWorld); - _v2$1.setFromMatrixPosition(this.matrixWorld); - const distance = _v1$2.distanceTo(_v2$1) / camera.zoom; levels[0].object.visible = true; let i, l; - for (i = 1, l = levels.length; i < l; i++) { - if (distance >= levels[i].distance) { + let levelDistance = levels[i].distance; + if (levels[i].object.visible) { + levelDistance -= levelDistance * levels[i].hysteresis; + } + if (distance >= levelDistance) { levels[i - 1].object.visible = false; levels[i].object.visible = true; } else { break; } } - this._currentLevel = i - 1; - for (; i < l; i++) { levels[i].object.visible = false; } } } - toJSON(meta) { const data = super.toJSON(meta); if (this.autoUpdate === false) data.object.autoUpdate = false; data.object.levels = []; const levels = this.levels; - for (let i = 0, l = levels.length; i < l; i++) { const level = levels[i]; data.object.levels.push({ object: level.object.uuid, - distance: level.distance + distance: level.distance, + hysteresis: level.hysteresis }); } - return data; } - } const _basePosition = /*@__PURE__*/new Vector3(); - const _skinIndex = /*@__PURE__*/new Vector4(); - const _skinWeight = /*@__PURE__*/new Vector4(); - const _vector$5 = /*@__PURE__*/new Vector3(); - const _matrix = /*@__PURE__*/new Matrix4(); - class SkinnedMesh extends Mesh { constructor(geometry, material) { super(geometry, material); @@ -21691,7 +19433,6 @@ this.bindMatrix = new Matrix4(); this.bindMatrixInverse = new Matrix4(); } - copy(source, recursive) { super.copy(source, recursive); this.bindMode = source.bindMode; @@ -21700,32 +19441,25 @@ this.skeleton = source.skeleton; return this; } - bind(skeleton, bindMatrix) { this.skeleton = skeleton; - if (bindMatrix === undefined) { this.updateMatrixWorld(true); this.skeleton.calculateInverses(); bindMatrix = this.matrixWorld; } - this.bindMatrix.copy(bindMatrix); this.bindMatrixInverse.copy(bindMatrix).invert(); } - pose() { this.skeleton.pose(); } - normalizeSkinWeights() { const vector = new Vector4(); const skinWeight = this.geometry.attributes.skinWeight; - for (let i = 0, l = skinWeight.count; i < l; i++) { vector.fromBufferAttribute(skinWeight, i); const scale = 1.0 / vector.manhattanLength(); - if (scale !== Infinity) { vector.multiplyScalar(scale); } else { @@ -21735,10 +19469,8 @@ skinWeight.setXYZW(i, vector.x, vector.y, vector.z, vector.w); } } - updateMatrixWorld(force) { super.updateMatrixWorld(force); - if (this.bindMode === 'attached') { this.bindMatrixInverse.copy(this.matrixWorld).invert(); } else if (this.bindMode === 'detached') { @@ -21747,34 +19479,23 @@ console.warn('THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode); } } - boneTransform(index, target) { const skeleton = this.skeleton; const geometry = this.geometry; - _skinIndex.fromBufferAttribute(geometry.attributes.skinIndex, index); - _skinWeight.fromBufferAttribute(geometry.attributes.skinWeight, index); - _basePosition.copy(target).applyMatrix4(this.bindMatrix); - target.set(0, 0, 0); - for (let i = 0; i < 4; i++) { const weight = _skinWeight.getComponent(i); - if (weight !== 0) { const boneIndex = _skinIndex.getComponent(i); - _matrix.multiplyMatrices(skeleton.bones[boneIndex].matrixWorld, skeleton.boneInverses[boneIndex]); - target.addScaledVector(_vector$5.copy(_basePosition).applyMatrix4(_matrix), weight); } } - return target.applyMatrix4(this.bindMatrixInverse); } - } class Bone extends Object3D { @@ -21783,7 +19504,6 @@ this.isBone = true; this.type = 'Bone'; } - } class DataTexture extends Texture { @@ -21799,13 +19519,10 @@ this.flipY = false; this.unpackAlignment = 1; } - } const _offsetMatrix = /*@__PURE__*/new Matrix4(); - const _identityMatrix = /*@__PURE__*/new Matrix4(); - class Skeleton { constructor(bones = [], boneInverses = []) { this.uuid = generateUUID(); @@ -21817,55 +19534,51 @@ this.frame = -1; this.init(); } - init() { const bones = this.bones; const boneInverses = this.boneInverses; - this.boneMatrices = new Float32Array(bones.length * 16); // calculate inverse bone matrices if necessary + this.boneMatrices = new Float32Array(bones.length * 16); + + // calculate inverse bone matrices if necessary if (boneInverses.length === 0) { this.calculateInverses(); } else { // handle special case + if (bones.length !== boneInverses.length) { console.warn('THREE.Skeleton: Number of inverse bone matrices does not match amount of bones.'); this.boneInverses = []; - for (let i = 0, il = this.bones.length; i < il; i++) { this.boneInverses.push(new Matrix4()); } } } } - calculateInverses() { this.boneInverses.length = 0; - for (let i = 0, il = this.bones.length; i < il; i++) { const inverse = new Matrix4(); - if (this.bones[i]) { inverse.copy(this.bones[i].matrixWorld).invert(); } - this.boneInverses.push(inverse); } } - pose() { // recover the bind-time world matrices + for (let i = 0, il = this.bones.length; i < il; i++) { const bone = this.bones[i]; - if (bone) { bone.matrixWorld.copy(this.boneInverses[i]).invert(); } - } // compute the local matrices, positions, rotations and scales + } + // compute the local matrices, positions, rotations and scales for (let i = 0, il = this.bones.length; i < il; i++) { const bone = this.bones[i]; - if (bone) { if (bone.parent && bone.parent.isBone) { bone.matrix.copy(bone.parent.matrixWorld).invert(); @@ -21873,36 +19586,32 @@ } else { bone.matrix.copy(bone.matrixWorld); } - bone.matrix.decompose(bone.position, bone.quaternion, bone.scale); } } } - update() { const bones = this.bones; const boneInverses = this.boneInverses; const boneMatrices = this.boneMatrices; - const boneTexture = this.boneTexture; // flatten bone matrices to array + const boneTexture = this.boneTexture; + + // flatten bone matrices to array for (let i = 0, il = bones.length; i < il; i++) { // compute the offset between the current and the original transform - const matrix = bones[i] ? bones[i].matrixWorld : _identityMatrix; + const matrix = bones[i] ? bones[i].matrixWorld : _identityMatrix; _offsetMatrix.multiplyMatrices(matrix, boneInverses[i]); - _offsetMatrix.toArray(boneMatrices, i * 16); } - if (boneTexture !== null) { boneTexture.needsUpdate = true; } } - clone() { return new Skeleton(this.bones, this.boneInverses); } - computeBoneTexture() { // layout (1 matrix = 4 pixels) // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4) @@ -21910,12 +19619,11 @@ // 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) - let size = Math.sqrt(this.bones.length * 4); // 4 pixels needed for 1 matrix + let size = Math.sqrt(this.bones.length * 4); // 4 pixels needed for 1 matrix size = ceilPowerOfTwo(size); size = Math.max(size, 4); const boneMatrices = new Float32Array(size * size * 4); // 4 floats per RGBA pixel - boneMatrices.set(this.boneMatrices); // copy current values const boneTexture = new DataTexture(boneMatrices, size, size, RGBAFormat, FloatType); @@ -21925,46 +19633,36 @@ this.boneTextureSize = size; return this; } - getBoneByName(name) { for (let i = 0, il = this.bones.length; i < il; i++) { const bone = this.bones[i]; - if (bone.name === name) { return bone; } } - return undefined; } - dispose() { if (this.boneTexture !== null) { this.boneTexture.dispose(); this.boneTexture = null; } } - fromJSON(json, bones) { this.uuid = json.uuid; - for (let i = 0, l = json.bones.length; i < l; i++) { const uuid = json.bones[i]; let bone = bones[uuid]; - if (bone === undefined) { console.warn('THREE.Skeleton: No bone found with UUID:', uuid); bone = new Bone(); } - this.bones.push(bone); this.boneInverses.push(new Matrix4().fromArray(json.boneInverses[i])); } - this.init(); return this; } - toJSON() { const data = { metadata: { @@ -21978,55 +19676,40 @@ data.uuid = this.uuid; const bones = this.bones; const boneInverses = this.boneInverses; - for (let i = 0, l = bones.length; i < l; i++) { const bone = bones[i]; data.bones.push(bone.uuid); const boneInverse = boneInverses[i]; data.boneInverses.push(boneInverse.toArray()); } - return data; } - } class InstancedBufferAttribute extends BufferAttribute { constructor(array, itemSize, normalized, meshPerAttribute = 1) { - if (typeof normalized === 'number') { - meshPerAttribute = normalized; - normalized = false; - console.error('THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument.'); - } - super(array, itemSize, normalized); this.isInstancedBufferAttribute = true; this.meshPerAttribute = meshPerAttribute; } - copy(source) { super.copy(source); this.meshPerAttribute = source.meshPerAttribute; return this; } - toJSON() { const data = super.toJSON(); data.meshPerAttribute = this.meshPerAttribute; data.isInstancedBufferAttribute = true; return data; } - } const _instanceLocalMatrix = /*@__PURE__*/new Matrix4(); - const _instanceWorldMatrix = /*@__PURE__*/new Matrix4(); - const _instanceIntersects = []; - + const _identity = /*@__PURE__*/new Matrix4(); const _mesh = /*@__PURE__*/new Mesh(); - class InstancedMesh extends Mesh { constructor(geometry, material, count) { super(geometry, material); @@ -22035,8 +19718,10 @@ this.instanceColor = null; this.count = count; this.frustumCulled = false; + for (let i = 0; i < count; i++) { + this.setMatrixAt(i, _identity); + } } - copy(source, recursive) { super.copy(source, recursive); this.instanceMatrix.copy(source.instanceMatrix); @@ -22044,33 +19729,30 @@ this.count = source.count; return this; } - getColorAt(index, color) { color.fromArray(this.instanceColor.array, index * 3); } - getMatrixAt(index, matrix) { matrix.fromArray(this.instanceMatrix.array, index * 16); } - raycast(raycaster, intersects) { const matrixWorld = this.matrixWorld; const raycastTimes = this.count; _mesh.geometry = this.geometry; _mesh.material = this.material; if (_mesh.material === undefined) return; - for (let instanceId = 0; instanceId < raycastTimes; instanceId++) { // calculate the world matrix for each instance - this.getMatrixAt(instanceId, _instanceLocalMatrix); - _instanceWorldMatrix.multiplyMatrices(matrixWorld, _instanceLocalMatrix); // the mesh represents this single instance + this.getMatrixAt(instanceId, _instanceLocalMatrix); + _instanceWorldMatrix.multiplyMatrices(matrixWorld, _instanceLocalMatrix); + // the mesh represents this single instance _mesh.matrixWorld = _instanceWorldMatrix; + _mesh.raycast(raycaster, _instanceIntersects); - _mesh.raycast(raycaster, _instanceIntersects); // process the result of raycast - + // process the result of raycast for (let i = 0, l = _instanceIntersects.length; i < l; i++) { const intersect = _instanceIntersects[i]; @@ -22078,31 +19760,24 @@ intersect.object = this; intersects.push(intersect); } - _instanceIntersects.length = 0; } } - setColorAt(index, color) { if (this.instanceColor === null) { this.instanceColor = new InstancedBufferAttribute(new Float32Array(this.instanceMatrix.count * 3), 3); } - color.toArray(this.instanceColor.array, index * 3); } - setMatrixAt(index, matrix) { matrix.toArray(this.instanceMatrix.array, index * 16); } - updateMorphTargets() {} - dispose() { this.dispatchEvent({ type: 'dispose' }); } - } class LineBasicMaterial extends Material { @@ -22117,7 +19792,6 @@ this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.color.copy(source.color); @@ -22127,19 +19801,13 @@ this.fog = source.fog; return this; } - } const _start$1 = /*@__PURE__*/new Vector3(); - const _end$1 = /*@__PURE__*/new Vector3(); - const _inverseMatrix$1 = /*@__PURE__*/new Matrix4(); - const _ray$1 = /*@__PURE__*/new Ray(); - const _sphere$1 = /*@__PURE__*/new Sphere(); - class Line extends Object3D { constructor(geometry = new BufferGeometry(), material = new LineBasicMaterial()) { super(); @@ -22149,57 +19817,50 @@ this.material = material; this.updateMorphTargets(); } - copy(source, recursive) { super.copy(source, recursive); this.material = source.material; this.geometry = source.geometry; return this; } - computeLineDistances() { - const geometry = this.geometry; // we assume non-indexed geometry + const geometry = this.geometry; + + // we assume non-indexed geometry if (geometry.index === null) { const positionAttribute = geometry.attributes.position; const lineDistances = [0]; - for (let i = 1, l = positionAttribute.count; i < l; i++) { _start$1.fromBufferAttribute(positionAttribute, i - 1); - _end$1.fromBufferAttribute(positionAttribute, i); - lineDistances[i] = lineDistances[i - 1]; lineDistances[i] += _start$1.distanceTo(_end$1); } - geometry.setAttribute('lineDistance', new Float32BufferAttribute(lineDistances, 1)); } else { console.warn('THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.'); } - return this; } - raycast(raycaster, intersects) { const geometry = this.geometry; const matrixWorld = this.matrixWorld; const threshold = raycaster.params.Line.threshold; - const drawRange = geometry.drawRange; // Checking boundingSphere distance to ray + const drawRange = geometry.drawRange; - if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); + // Checking boundingSphere distance to ray + if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); _sphere$1.copy(geometry.boundingSphere); - _sphere$1.applyMatrix4(matrixWorld); - _sphere$1.radius += threshold; - if (raycaster.ray.intersectsSphere(_sphere$1) === false) return; // + if (raycaster.ray.intersectsSphere(_sphere$1) === false) return; - _inverseMatrix$1.copy(matrixWorld).invert(); + // + _inverseMatrix$1.copy(matrixWorld).invert(); _ray$1.copy(raycaster.ray).applyMatrix4(_inverseMatrix$1); - const localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3); const localThresholdSq = localThreshold * localThreshold; const vStart = new Vector3(); @@ -22210,19 +19871,15 @@ const index = geometry.index; const attributes = geometry.attributes; const positionAttribute = attributes.position; - if (index !== null) { const start = Math.max(0, drawRange.start); const end = Math.min(index.count, drawRange.start + drawRange.count); - for (let i = start, l = end - 1; i < l; i += step) { const a = index.getX(i); const b = index.getX(i + 1); vStart.fromBufferAttribute(positionAttribute, a); vEnd.fromBufferAttribute(positionAttribute, b); - const distSq = _ray$1.distanceSqToSegment(vStart, vEnd, interRay, interSegment); - if (distSq > localThresholdSq) continue; interRay.applyMatrix4(this.matrixWorld); //Move back to world space for distance calculation @@ -22242,13 +19899,10 @@ } else { const start = Math.max(0, drawRange.start); const end = Math.min(positionAttribute.count, drawRange.start + drawRange.count); - for (let i = start, l = end - 1; i < l; i += step) { vStart.fromBufferAttribute(positionAttribute, i); vEnd.fromBufferAttribute(positionAttribute, i + 1); - const distSq = _ray$1.distanceSqToSegment(vStart, vEnd, interRay, interSegment); - if (distSq > localThresholdSq) continue; interRay.applyMatrix4(this.matrixWorld); //Move back to world space for distance calculation @@ -22267,19 +19921,15 @@ } } } - updateMorphTargets() { const geometry = this.geometry; const morphAttributes = geometry.morphAttributes; const keys = Object.keys(morphAttributes); - if (keys.length > 0) { const morphAttribute = morphAttributes[keys[0]]; - if (morphAttribute !== undefined) { this.morphTargetInfluences = []; this.morphTargetDictionary = {}; - for (let m = 0, ml = morphAttribute.length; m < ml; m++) { const name = morphAttribute[m].name || String(m); this.morphTargetInfluences.push(0); @@ -22288,44 +19938,36 @@ } } } - } const _start = /*@__PURE__*/new Vector3(); - const _end = /*@__PURE__*/new Vector3(); - class LineSegments extends Line { constructor(geometry, material) { super(geometry, material); this.isLineSegments = true; this.type = 'LineSegments'; } - computeLineDistances() { - const geometry = this.geometry; // we assume non-indexed geometry + const geometry = this.geometry; + + // we assume non-indexed geometry if (geometry.index === null) { const positionAttribute = geometry.attributes.position; const lineDistances = []; - for (let i = 0, l = positionAttribute.count; i < l; i += 2) { _start.fromBufferAttribute(positionAttribute, i); - _end.fromBufferAttribute(positionAttribute, i + 1); - lineDistances[i] = i === 0 ? 0 : lineDistances[i - 1]; lineDistances[i + 1] = lineDistances[i] + _start.distanceTo(_end); } - geometry.setAttribute('lineDistance', new Float32BufferAttribute(lineDistances, 1)); } else { console.warn('THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.'); } - return this; } - } class LineLoop extends Line { @@ -22334,7 +19976,6 @@ this.isLineLoop = true; this.type = 'LineLoop'; } - } class PointsMaterial extends Material { @@ -22350,7 +19991,6 @@ this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.color.copy(source.color); @@ -22361,17 +20001,12 @@ this.fog = source.fog; return this; } - } const _inverseMatrix = /*@__PURE__*/new Matrix4(); - const _ray = /*@__PURE__*/new Ray(); - const _sphere = /*@__PURE__*/new Sphere(); - const _position$2 = /*@__PURE__*/new Vector3(); - class Points extends Object3D { constructor(geometry = new BufferGeometry(), material = new PointsMaterial()) { super(); @@ -22381,74 +20016,61 @@ this.material = material; this.updateMorphTargets(); } - copy(source, recursive) { super.copy(source, recursive); this.material = source.material; this.geometry = source.geometry; return this; } - raycast(raycaster, intersects) { const geometry = this.geometry; const matrixWorld = this.matrixWorld; const threshold = raycaster.params.Points.threshold; - const drawRange = geometry.drawRange; // Checking boundingSphere distance to ray + const drawRange = geometry.drawRange; - if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); + // Checking boundingSphere distance to ray + if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); _sphere.copy(geometry.boundingSphere); - _sphere.applyMatrix4(matrixWorld); - _sphere.radius += threshold; - if (raycaster.ray.intersectsSphere(_sphere) === false) return; // + if (raycaster.ray.intersectsSphere(_sphere) === false) return; - _inverseMatrix.copy(matrixWorld).invert(); + // + _inverseMatrix.copy(matrixWorld).invert(); _ray.copy(raycaster.ray).applyMatrix4(_inverseMatrix); - const localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3); const localThresholdSq = localThreshold * localThreshold; const index = geometry.index; const attributes = geometry.attributes; const positionAttribute = attributes.position; - if (index !== null) { const start = Math.max(0, drawRange.start); const end = Math.min(index.count, drawRange.start + drawRange.count); - for (let i = start, il = end; i < il; i++) { const a = index.getX(i); - _position$2.fromBufferAttribute(positionAttribute, a); - testPoint(_position$2, a, localThresholdSq, matrixWorld, raycaster, intersects, this); } } else { const start = Math.max(0, drawRange.start); const end = Math.min(positionAttribute.count, drawRange.start + drawRange.count); - for (let i = start, l = end; i < l; i++) { _position$2.fromBufferAttribute(positionAttribute, i); - testPoint(_position$2, i, localThresholdSq, matrixWorld, raycaster, intersects, this); } } } - updateMorphTargets() { const geometry = this.geometry; const morphAttributes = geometry.morphAttributes; const keys = Object.keys(morphAttributes); - if (keys.length > 0) { const morphAttribute = morphAttributes[keys[0]]; - if (morphAttribute !== undefined) { this.morphTargetInfluences = []; this.morphTargetDictionary = {}; - for (let m = 0, ml = morphAttribute.length; m < ml; m++) { const name = morphAttribute[m].name || String(m); this.morphTargetInfluences.push(0); @@ -22457,17 +20079,12 @@ } } } - } - function testPoint(point, index, localThresholdSq, matrixWorld, raycaster, intersects, object) { const rayPointDistanceSq = _ray.distanceSqToPoint(point); - if (rayPointDistanceSq < localThresholdSq) { const intersectPoint = new Vector3(); - _ray.closestPointToPoint(point, intersectPoint); - intersectPoint.applyMatrix4(matrixWorld); const distance = raycaster.ray.origin.distanceTo(intersectPoint); if (distance < raycaster.near || distance > raycaster.far) return; @@ -22490,30 +20107,24 @@ this.magFilter = magFilter !== undefined ? magFilter : LinearFilter; this.generateMipmaps = false; const scope = this; - function updateVideo() { scope.needsUpdate = true; video.requestVideoFrameCallback(updateVideo); } - if ('requestVideoFrameCallback' in video) { video.requestVideoFrameCallback(updateVideo); } } - clone() { return new this.constructor(this.image).copy(this); } - update() { const video = this.image; const hasVideoFrameCallback = ('requestVideoFrameCallback' in video); - if (hasVideoFrameCallback === false && video.readyState >= video.HAVE_CURRENT_DATA) { this.needsUpdate = true; } } - } class FramebufferTexture extends Texture { @@ -22529,7 +20140,6 @@ this.generateMipmaps = false; this.needsUpdate = true; } - } class CompressedTexture extends Texture { @@ -22540,15 +20150,27 @@ width: width, height: height }; - this.mipmaps = mipmaps; // no flipping for cube textures + this.mipmaps = mipmaps; + + // no flipping for cube textures // (also flipping doesn't work for compressed textures ) - this.flipY = false; // can't generate mipmaps for compressed textures + this.flipY = false; + + // can't generate mipmaps for compressed textures // mips must be embedded in DDS files this.generateMipmaps = false; } + } + class CompressedArrayTexture extends CompressedTexture { + constructor(mipmaps, width, height, depth, format, type) { + super(mipmaps, width, height, format, type); + this.isCompressedArrayTexture = true; + this.image.depth = depth; + this.wrapR = ClampToEdgeWrapping; + } } class CanvasTexture extends Texture { @@ -22557,7 +20179,6 @@ this.isCanvasTexture = true; this.needsUpdate = true; } - } /** @@ -22594,70 +20215,69 @@ constructor() { this.type = 'Curve'; this.arcLengthDivisions = 200; - } // Virtual base class method to overwrite and implement in subclasses - // - t [0 .. 1] + } + // Virtual base class method to overwrite and implement in subclasses + // - t [0 .. 1] getPoint() { console.warn('THREE.Curve: .getPoint() not implemented.'); return null; - } // Get point at relative position in curve according to arc length - // - u [0 .. 1] + } + // Get point at relative position in curve according to arc length + // - u [0 .. 1] getPointAt(u, optionalTarget) { const t = this.getUtoTmapping(u); return this.getPoint(t, optionalTarget); - } // Get sequence of points using getPoint( t ) + } + // Get sequence of points using getPoint( t ) getPoints(divisions = 5) { const points = []; - for (let d = 0; d <= divisions; d++) { points.push(this.getPoint(d / divisions)); } - return points; - } // Get sequence of points using getPointAt( u ) + } + // Get sequence of points using getPointAt( u ) getSpacedPoints(divisions = 5) { const points = []; - for (let d = 0; d <= divisions; d++) { points.push(this.getPointAt(d / divisions)); } - return points; - } // Get total curve arc length + } + // Get total curve arc length getLength() { const lengths = this.getLengths(); return lengths[lengths.length - 1]; - } // Get list of cumulative segment lengths + } + // Get list of cumulative segment lengths getLengths(divisions = this.arcLengthDivisions) { if (this.cacheArcLengths && this.cacheArcLengths.length === divisions + 1 && !this.needsUpdate) { return this.cacheArcLengths; } - this.needsUpdate = false; const cache = []; let current, - last = this.getPoint(0); + last = this.getPoint(0); let sum = 0; cache.push(0); - for (let 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. } @@ -22665,8 +20285,9 @@ updateArcLengths() { this.needsUpdate = true; this.getLengths(); - } // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant + } + // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant getUtoTmapping(u, distance) { const arcLengths = this.getLengths(); @@ -22678,53 +20299,61 @@ targetArcLength = distance; } else { targetArcLength = u * arcLengths[il - 1]; - } // binary search for the index with largest value smaller than target u distance + } + // binary search for the index with largest value smaller than target u distance let low = 0, - high = il - 1, - comparison; - + 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; } else if (comparison > 0) { high = i - 1; } else { high = i; - break; // DONE + break; + + // DONE } } i = high; - if (arcLengths[i] === targetArcLength) { return i / (il - 1); - } // we could get finer grain at lengths, or use simple interpolation between two points + } + // we could get finer grain at lengths, or use simple interpolation between two points const lengthBefore = arcLengths[i]; const lengthAfter = arcLengths[i + 1]; - const segmentLength = lengthAfter - lengthBefore; // determine where we are between the 'before' and 'after' points + const segmentLength = lengthAfter - lengthBefore; - const segmentFraction = (targetArcLength - lengthBefore) / segmentLength; // add that fractional amount to t + // determine where we are between the 'before' and 'after' points + + const segmentFraction = (targetArcLength - lengthBefore) / segmentLength; + + // add that fractional amount to t const t = (i + segmentFraction) / (il - 1); return t; - } // Returns a unit vector tangent at 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(t, optionalTarget) { const delta = 0.0001; let t1 = t - delta; - let t2 = t + delta; // Capping in case of danger + let t2 = t + delta; + + // Capping in case of danger if (t1 < 0) t1 = 0; if (t2 > 1) t2 = 1; @@ -22734,27 +20363,29 @@ tangent.copy(pt2).sub(pt1).normalize(); return tangent; } - getTangentAt(u, optionalTarget) { const t = this.getUtoTmapping(u); return this.getTangent(t, optionalTarget); } - computeFrenetFrames(segments, closed) { // see http://www.cs.indiana.edu/pub/techreports/TR425.pdf + const normal = new Vector3(); const tangents = []; const normals = []; const binormals = []; const vec = new Vector3(); - const mat = new Matrix4(); // compute the tangent vectors for each segment on the curve + const mat = new Matrix4(); + + // compute the tangent vectors for each segment on the curve for (let i = 0; i <= segments; i++) { const u = i / segments; tangents[i] = this.getTangentAt(u, new Vector3()); - } // select an initial normal vector perpendicular to the first tangent vector, - // and in the direction of the minimum tangent xyz component + } + // select an initial normal vector perpendicular to the first tangent vector, + // and in the direction of the minimum tangent xyz component normals[0] = new Vector3(); binormals[0] = new Vector3(); @@ -22762,72 +20393,63 @@ const tx = Math.abs(tangents[0].x); const ty = Math.abs(tangents[0].y); const tz = Math.abs(tangents[0].z); - if (tx <= min) { min = tx; normal.set(1, 0, 0); } - if (ty <= min) { min = ty; normal.set(0, 1, 0); } - if (tz <= min) { 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 curve + binormals[0].crossVectors(tangents[0], normals[0]); + + // compute the slowly-varying normal and binormal vectors for each segment on the curve for (let i = 1; i <= segments; i++) { normals[i] = normals[i - 1].clone(); binormals[i] = binormals[i - 1].clone(); vec.crossVectors(tangents[i - 1], tangents[i]); - if (vec.length() > Number.EPSILON) { vec.normalize(); const theta = Math.acos(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 the curve is closed, postprocess the vectors so the first and last normal vectors are the same if (closed === true) { let theta = Math.acos(clamp(normals[0].dot(normals[segments]), -1, 1)); theta /= segments; - if (tangents[0].dot(vec.crossVectors(normals[0], normals[segments])) > 0) { theta = -theta; } - for (let i = 1; i <= segments; i++) { // twist a little... normals[i].applyMatrix4(mat.makeRotationAxis(tangents[i], theta * i)); binormals[i].crossVectors(tangents[i], normals[i]); } } - return { tangents: tangents, normals: normals, binormals: binormals }; } - clone() { return new this.constructor().copy(this); } - copy(source) { this.arcLengthDivisions = source.arcLengthDivisions; return this; } - toJSON() { const data = { metadata: { @@ -22840,12 +20462,10 @@ data.type = this.type; return data; } - fromJSON(json) { this.arcLengthDivisions = json.arcLengthDivisions; return this; } - } class EllipseCurve extends Curve { @@ -22862,17 +20482,15 @@ this.aClockwise = aClockwise; this.aRotation = aRotation; } - getPoint(t, optionalTarget) { const point = optionalTarget || new Vector2(); const twoPi = Math.PI * 2; let deltaAngle = this.aEndAngle - this.aStartAngle; - const samePoints = Math.abs(deltaAngle) < Number.EPSILON; // ensures that deltaAngle is 0 .. 2 PI + const samePoints = Math.abs(deltaAngle) < Number.EPSILON; + // ensures that deltaAngle is 0 .. 2 PI while (deltaAngle < 0) deltaAngle += twoPi; - while (deltaAngle > twoPi) deltaAngle -= twoPi; - if (deltaAngle < Number.EPSILON) { if (samePoints) { deltaAngle = 0; @@ -22880,7 +20498,6 @@ deltaAngle = twoPi; } } - if (this.aClockwise === true && !samePoints) { if (deltaAngle === twoPi) { deltaAngle = -twoPi; @@ -22888,24 +20505,21 @@ deltaAngle = deltaAngle - twoPi; } } - const angle = this.aStartAngle + t * deltaAngle; let x = this.aX + this.xRadius * Math.cos(angle); let y = this.aY + this.yRadius * Math.sin(angle); - if (this.aRotation !== 0) { const cos = Math.cos(this.aRotation); const sin = Math.sin(this.aRotation); const tx = x - this.aX; - const ty = y - this.aY; // Rotate the point about the center of the ellipse. + const ty = y - this.aY; + // Rotate the point about the center of the ellipse. x = tx * cos - ty * sin + this.aX; y = tx * sin + ty * cos + this.aY; } - return point.set(x, y); } - copy(source) { super.copy(source); this.aX = source.aX; @@ -22918,7 +20532,6 @@ this.aRotation = source.aRotation; return this; } - toJSON() { const data = super.toJSON(); data.aX = this.aX; @@ -22931,7 +20544,6 @@ data.aRotation = this.aRotation; return data; } - fromJSON(json) { super.fromJSON(json); this.aX = json.aX; @@ -22944,7 +20556,6 @@ this.aRotation = json.aRotation; return this; } - } class ArcCurve extends EllipseCurve { @@ -22953,7 +20564,6 @@ this.isArcCurve = true; this.type = 'ArcCurve'; } - } /** @@ -22977,9 +20587,10 @@ function CubicPoly() { let c0 = 0, - c1 = 0, - c2 = 0, - c3 = 0; + c1 = 0, + c2 = 0, + c3 = 0; + /* * Compute coefficients for a cubic polynomial * p(s) = c0 + c1*s + c2*s^2 + c3*s^3 @@ -22988,14 +20599,12 @@ * 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 (x0, x1, x2, x3, tension) { init(x1, x2, tension * (x2 - x0), tension * (x3 - x1)); @@ -23003,8 +20612,9 @@ initNonuniformCatmullRom: function (x0, x1, x2, x3, dt0, dt1, dt2) { // compute tangents when parameterized in [t1,t2] let t1 = (x1 - x0) / dt0 - (x2 - x0) / (dt0 + dt1) + (x2 - x1) / dt1; - let t2 = (x2 - x1) / dt1 - (x3 - x1) / (dt1 + dt2) + (x3 - x2) / dt2; // rescale tangents for parametrization in [0,1] + let 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); @@ -23015,14 +20625,14 @@ return c0 + c1 * t + c2 * t2 + c3 * t3; } }; - } // + } + // const tmp = /*@__PURE__*/new Vector3(); const px = /*@__PURE__*/new CubicPoly(); const py = /*@__PURE__*/new CubicPoly(); const pz = /*@__PURE__*/new CubicPoly(); - class CatmullRomCurve3 extends Curve { constructor(points = [], closed = false, curveType = 'centripetal', tension = 0.5) { super(); @@ -23033,7 +20643,6 @@ this.curveType = curveType; this.tension = tension; } - getPoint(t, optionalTarget = new Vector3()) { const point = optionalTarget; const points = this.points; @@ -23041,14 +20650,12 @@ const p = (l - (this.closed ? 0 : 1)) * t; let intPoint = Math.floor(p); let weight = p - intPoint; - 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; } - let p0, p3; // 4 points (p1 & p2 defined below) if (this.closed || intPoint > 0) { @@ -23058,10 +20665,8 @@ tmp.subVectors(points[0], points[1]).add(points[0]); p0 = tmp; } - const p1 = points[intPoint % l]; const p2 = points[(intPoint + 1) % l]; - if (this.closed || intPoint + 2 < l) { p3 = points[(intPoint + 2) % l]; } else { @@ -23069,14 +20674,14 @@ 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 const pow = this.curveType === 'chordal' ? 0.5 : 0.25; let dt0 = Math.pow(p0.distanceToSquared(p1), pow); let dt1 = Math.pow(p1.distanceToSquared(p2), pow); - let dt2 = Math.pow(p2.distanceToSquared(p3), pow); // safety check for repeated points + let 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; @@ -23088,107 +20693,92 @@ 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; } - copy(source) { super.copy(source); this.points = []; - for (let i = 0, l = source.points.length; i < l; i++) { const point = source.points[i]; this.points.push(point.clone()); } - this.closed = source.closed; this.curveType = source.curveType; this.tension = source.tension; return this; } - toJSON() { const data = super.toJSON(); data.points = []; - for (let i = 0, l = this.points.length; i < l; i++) { const point = this.points[i]; data.points.push(point.toArray()); } - data.closed = this.closed; data.curveType = this.curveType; data.tension = this.tension; return data; } - fromJSON(json) { super.fromJSON(json); this.points = []; - for (let i = 0, l = json.points.length; i < l; i++) { const point = json.points[i]; this.points.push(new Vector3().fromArray(point)); } - this.closed = json.closed; this.curveType = json.curveType; this.tension = json.tension; return this; } - } /** * Bezier Curves formulas obtained from * https://en.wikipedia.org/wiki/B%C3%A9zier_curve */ + function CatmullRom(t, p0, p1, p2, p3) { const v0 = (p2 - p0) * 0.5; const v1 = (p3 - p1) * 0.5; const t2 = t * t; const t3 = t * t2; return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1; - } // + } + // function QuadraticBezierP0(t, p) { const k = 1 - t; return k * k * p; } - function QuadraticBezierP1(t, p) { return 2 * (1 - t) * t * p; } - function QuadraticBezierP2(t, p) { return t * t * p; } - function QuadraticBezier(t, p0, p1, p2) { return QuadraticBezierP0(t, p0) + QuadraticBezierP1(t, p1) + QuadraticBezierP2(t, p2); - } // + } + // function CubicBezierP0(t, p) { const k = 1 - t; return k * k * k * p; } - function CubicBezierP1(t, p) { const k = 1 - t; return 3 * k * k * t * p; } - function CubicBezierP2(t, p) { return 3 * (1 - t) * t * t * p; } - function CubicBezierP3(t, p) { return t * t * t * p; } - function CubicBezier(t, p0, p1, p2, p3) { return CubicBezierP0(t, p0) + CubicBezierP1(t, p1) + CubicBezierP2(t, p2) + CubicBezierP3(t, p3); } @@ -23203,17 +20793,15 @@ this.v2 = v2; this.v3 = v3; } - getPoint(t, optionalTarget = new Vector2()) { const point = optionalTarget; const v0 = this.v0, - v1 = this.v1, - v2 = this.v2, - v3 = this.v3; + 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; } - copy(source) { super.copy(source); this.v0.copy(source.v0); @@ -23222,7 +20810,6 @@ this.v3.copy(source.v3); return this; } - toJSON() { const data = super.toJSON(); data.v0 = this.v0.toArray(); @@ -23231,7 +20818,6 @@ data.v3 = this.v3.toArray(); return data; } - fromJSON(json) { super.fromJSON(json); this.v0.fromArray(json.v0); @@ -23240,7 +20826,6 @@ this.v3.fromArray(json.v3); return this; } - } class CubicBezierCurve3 extends Curve { @@ -23253,17 +20838,15 @@ this.v2 = v2; this.v3 = v3; } - getPoint(t, optionalTarget = new Vector3()) { const point = optionalTarget; const v0 = this.v0, - v1 = this.v1, - v2 = this.v2, - v3 = this.v3; + 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; } - copy(source) { super.copy(source); this.v0.copy(source.v0); @@ -23272,7 +20855,6 @@ this.v3.copy(source.v3); return this; } - toJSON() { const data = super.toJSON(); data.v0 = this.v0.toArray(); @@ -23281,7 +20863,6 @@ data.v3 = this.v3.toArray(); return data; } - fromJSON(json) { super.fromJSON(json); this.v0.fromArray(json.v0); @@ -23290,7 +20871,6 @@ this.v3.fromArray(json.v3); return this; } - } class LineCurve extends Curve { @@ -23301,52 +20881,44 @@ this.v1 = v1; this.v2 = v2; } - getPoint(t, optionalTarget = new Vector2()) { const point = optionalTarget; - if (t === 1) { point.copy(this.v2); } else { point.copy(this.v2).sub(this.v1); point.multiplyScalar(t).add(this.v1); } - return point; - } // Line curve is linear, so we can overwrite default getPointAt - + } + // Line curve is linear, so we can overwrite default getPointAt getPointAt(u, optionalTarget) { return this.getPoint(u, optionalTarget); } - getTangent(t, optionalTarget) { const tangent = optionalTarget || new Vector2(); tangent.copy(this.v2).sub(this.v1).normalize(); return tangent; } - copy(source) { super.copy(source); this.v1.copy(source.v1); this.v2.copy(source.v2); return this; } - toJSON() { const data = super.toJSON(); data.v1 = this.v1.toArray(); data.v2 = this.v2.toArray(); return data; } - fromJSON(json) { super.fromJSON(json); this.v1.fromArray(json.v1); this.v2.fromArray(json.v2); return this; } - } class LineCurve3 extends Curve { @@ -23357,46 +20929,38 @@ this.v1 = v1; this.v2 = v2; } - getPoint(t, optionalTarget = new Vector3()) { const point = optionalTarget; - if (t === 1) { point.copy(this.v2); } else { point.copy(this.v2).sub(this.v1); point.multiplyScalar(t).add(this.v1); } - return point; - } // Line curve is linear, so we can overwrite default getPointAt - - + } + // Line curve is linear, so we can overwrite default getPointAt getPointAt(u, optionalTarget) { return this.getPoint(u, optionalTarget); } - copy(source) { super.copy(source); this.v1.copy(source.v1); this.v2.copy(source.v2); return this; } - toJSON() { const data = super.toJSON(); data.v1 = this.v1.toArray(); data.v2 = this.v2.toArray(); return data; } - fromJSON(json) { super.fromJSON(json); this.v1.fromArray(json.v1); this.v2.fromArray(json.v2); return this; } - } class QuadraticBezierCurve extends Curve { @@ -23408,16 +20972,14 @@ this.v1 = v1; this.v2 = v2; } - getPoint(t, optionalTarget = new Vector2()) { const point = optionalTarget; const v0 = this.v0, - v1 = this.v1, - v2 = this.v2; + 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; } - copy(source) { super.copy(source); this.v0.copy(source.v0); @@ -23425,7 +20987,6 @@ this.v2.copy(source.v2); return this; } - toJSON() { const data = super.toJSON(); data.v0 = this.v0.toArray(); @@ -23433,7 +20994,6 @@ data.v2 = this.v2.toArray(); return data; } - fromJSON(json) { super.fromJSON(json); this.v0.fromArray(json.v0); @@ -23441,7 +21001,6 @@ this.v2.fromArray(json.v2); return this; } - } class QuadraticBezierCurve3 extends Curve { @@ -23453,16 +21012,14 @@ this.v1 = v1; this.v2 = v2; } - getPoint(t, optionalTarget = new Vector3()) { const point = optionalTarget; const v0 = this.v0, - v1 = this.v1, - v2 = this.v2; + 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; } - copy(source) { super.copy(source); this.v0.copy(source.v0); @@ -23470,7 +21027,6 @@ this.v2.copy(source.v2); return this; } - toJSON() { const data = super.toJSON(); data.v0 = this.v0.toArray(); @@ -23478,7 +21034,6 @@ data.v2 = this.v2.toArray(); return data; } - fromJSON(json) { super.fromJSON(json); this.v0.fromArray(json.v0); @@ -23486,7 +21041,6 @@ this.v2.fromArray(json.v2); return this; } - } class SplineCurve extends Curve { @@ -23496,7 +21050,6 @@ this.type = 'SplineCurve'; this.points = points; } - getPoint(t, optionalTarget = new Vector2()) { const point = optionalTarget; const points = this.points; @@ -23510,43 +21063,33 @@ point.set(CatmullRom(weight, p0.x, p1.x, p2.x, p3.x), CatmullRom(weight, p0.y, p1.y, p2.y, p3.y)); return point; } - copy(source) { super.copy(source); this.points = []; - for (let i = 0, l = source.points.length; i < l; i++) { const point = source.points[i]; this.points.push(point.clone()); } - return this; } - toJSON() { const data = super.toJSON(); data.points = []; - for (let i = 0, l = this.points.length; i < l; i++) { const point = this.points[i]; data.points.push(point.toArray()); } - return data; } - fromJSON(json) { super.fromJSON(json); this.points = []; - for (let i = 0, l = json.points.length; i < l; i++) { const point = json.points[i]; this.points.push(new Vector2().fromArray(point)); } - return this; } - } var Curves = /*#__PURE__*/Object.freeze({ @@ -23579,28 +21122,30 @@ add(curve) { this.curves.push(curve); } - closePath() { // Add a line curve if start and end of lines are not connected const startPoint = this.curves[0].getPoint(0); const 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 + } + + // 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(t, optionalTarget) { const d = t * this.getLength(); const curveLengths = this.getCurveLengths(); - let i = 0; // To think about boundaries points. + let i = 0; + + // To think about boundaries points. while (i < curveLengths.length) { if (curveLengths[i] >= d) { @@ -23610,73 +21155,68 @@ const u = segmentLength === 0 ? 0 : 1 - diff / segmentLength; return curve.getPointAt(u, optionalTarget); } - i++; } + return null; + + // loop where sum != 0, sum > d , sum+1 d , sum+1 1 && !points[points.length - 1].equals(points[0])) { points.push(points[0]); } - return points; } - copy(source) { super.copy(source); this.curves = []; - for (let i = 0, l = source.curves.length; i < l; i++) { const curve = source.curves[i]; this.curves.push(curve.clone()); } - this.autoClose = source.autoClose; return this; } - toJSON() { const data = super.toJSON(); data.autoClose = this.autoClose; data.curves = []; - for (let i = 0, l = this.curves.length; i < l; i++) { const curve = this.curves[i]; data.curves.push(curve.toJSON()); } - return data; } - fromJSON(json) { super.fromJSON(json); this.autoClose = json.autoClose; this.curves = []; - for (let i = 0, l = json.curves.length; i < l; i++) { const curve = json.curves[i]; this.curves.push(new Curves[curve.type]().fromJSON(curve)); } - return this; } - } class Path extends CurvePath { @@ -23739,114 +21267,92 @@ super(); this.type = 'Path'; this.currentPoint = new Vector2(); - if (points) { this.setFromPoints(points); } } - setFromPoints(points) { this.moveTo(points[0].x, points[0].y); - for (let i = 1, l = points.length; i < l; i++) { this.lineTo(points[i].x, points[i].y); } - return this; } - moveTo(x, y) { this.currentPoint.set(x, y); // TODO consider referencing vectors instead of copying? return this; } - lineTo(x, y) { const curve = new LineCurve(this.currentPoint.clone(), new Vector2(x, y)); this.curves.push(curve); this.currentPoint.set(x, y); return this; } - quadraticCurveTo(aCPx, aCPy, aX, aY) { const 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(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY) { const 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(pts - /*Array of Vector*/ - ) { + splineThru(pts /*Array of Vector*/) { const npts = [this.currentPoint.clone()].concat(pts); const curve = new SplineCurve(npts); this.curves.push(curve); this.currentPoint.copy(pts[pts.length - 1]); return this; } - arc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { const x0 = this.currentPoint.x; const y0 = this.currentPoint.y; this.absarc(aX + x0, aY + y0, aRadius, aStartAngle, aEndAngle, aClockwise); return this; } - absarc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { this.absellipse(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise); return this; } - ellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation) { const x0 = this.currentPoint.x; const y0 = this.currentPoint.y; this.absellipse(aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation); return this; } - absellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation) { const curve = new EllipseCurve(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation); - if (this.curves.length > 0) { // if a previous curve is present, attempt to join const firstPoint = curve.getPoint(0); - if (!firstPoint.equals(this.currentPoint)) { this.lineTo(firstPoint.x, firstPoint.y); } } - this.curves.push(curve); const lastPoint = curve.getPoint(1); this.currentPoint.copy(lastPoint); return this; } - copy(source) { super.copy(source); this.currentPoint.copy(source.currentPoint); return this; } - toJSON() { const data = super.toJSON(); data.currentPoint = this.currentPoint.toArray(); return data; } - fromJSON(json) { super.fromJSON(json); this.currentPoint.fromArray(json.currentPoint); return this; } - } class LatheGeometry extends BufferGeometry { @@ -23859,15 +21365,21 @@ phiStart: phiStart, phiLength: phiLength }; - segments = Math.floor(segments); // clamp phiLength so it's in range of [ 0, 2PI ] + segments = Math.floor(segments); + + // clamp phiLength so it's in range of [ 0, 2PI ] + + phiLength = clamp(phiLength, 0, Math.PI * 2); - phiLength = clamp(phiLength, 0, Math.PI * 2); // buffers + // buffers const indices = []; const vertices = []; const uvs = []; const initNormals = []; - const normals = []; // helper variables + const normals = []; + + // helper variables const inverseSegments = 1.0 / segments; const vertex = new Vector3(); @@ -23876,12 +21388,15 @@ const curNormal = new Vector3(); const prevNormal = new Vector3(); let dx = 0; - let dy = 0; // pre-compute normals for initial "meridian" + let dy = 0; + + // pre-compute normals for initial "meridian" for (let j = 0; j <= points.length - 1; j++) { switch (j) { case 0: // special handling for 1st vertex on path + dx = points[j + 1].x - points[j].x; dy = points[j + 1].y - points[j].y; normal.x = dy * 1.0; @@ -23891,14 +21406,14 @@ normal.normalize(); initNormals.push(normal.x, normal.y, normal.z); break; - case points.length - 1: // special handling for last Vertex on path + initNormals.push(prevNormal.x, prevNormal.y, prevNormal.z); break; - default: // default handling for all vertices in between + dx = points[j + 1].x - points[j].x; dy = points[j + 1].y - points[j].y; normal.x = dy * 1.0; @@ -23912,32 +21427,38 @@ initNormals.push(normal.x, normal.y, normal.z); prevNormal.copy(curNormal); } - } // generate vertices, uvs and normals + } + // generate vertices, uvs and normals for (let i = 0; i <= segments; i++) { const phi = phiStart + i * inverseSegments * phiLength; const sin = Math.sin(phi); const cos = Math.cos(phi); - for (let 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 + 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); // normal + uvs.push(uv.x, uv.y); + + // normal const x = initNormals[3 * j + 0] * sin; const y = initNormals[3 * j + 1]; const z = initNormals[3 * j + 0] * cos; normals.push(x, y, z); } - } // indices + } + // indices for (let i = 0; i < segments; i++) { for (let j = 0; j < points.length - 1; j++) { @@ -23945,24 +21466,25 @@ const a = base; const b = base + points.length; const c = base + points.length + 1; - const d = base + 1; // faces + const d = base + 1; + + // faces indices.push(a, b, d); indices.push(c, d, b); } - } // build geometry + } + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); } - static fromJSON(data) { return new LatheGeometry(data.points, data.segments, data.phiStart, data.phiLength); } - } class CapsuleGeometry extends LatheGeometry { @@ -23979,11 +21501,9 @@ radialSegments: radialSegments }; } - static fromJSON(data) { return new CapsuleGeometry(data.radius, data.length, data.capSegments, data.radialSegments); } - } class CircleGeometry extends BufferGeometry { @@ -23996,50 +21516,61 @@ thetaStart: thetaStart, thetaLength: thetaLength }; - segments = Math.max(3, segments); // buffers + segments = Math.max(3, segments); + + // buffers const indices = []; const vertices = []; const normals = []; - const uvs = []; // helper variables + const uvs = []; + + // helper variables const vertex = new Vector3(); - const uv = new Vector2(); // center point + const uv = new Vector2(); + + // center point vertices.push(0, 0, 0); normals.push(0, 0, 1); uvs.push(0.5, 0.5); - for (let s = 0, i = 3; s <= segments; s++, i += 3) { - const segment = thetaStart + s / segments * thetaLength; // vertex + const 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 + vertices.push(vertex.x, vertex.y, vertex.z); + + // normal + + normals.push(0, 0, 1); - normals.push(0, 0, 1); // uvs + // uvs uv.x = (vertices[i] / radius + 1) / 2; uv.y = (vertices[i + 1] / radius + 1) / 2; uvs.push(uv.x, uv.y); - } // indices + } + // indices for (let i = 1; i <= segments; i++) { indices.push(i, i + 1, 0); - } // build geometry + } + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); } - static fromJSON(data) { return new CircleGeometry(data.radius, data.segments, data.thetaStart, data.thetaLength); } - } class CylinderGeometry extends BufferGeometry { @@ -24058,89 +21589,115 @@ }; const scope = this; radialSegments = Math.floor(radialSegments); - heightSegments = Math.floor(heightSegments); // buffers + heightSegments = Math.floor(heightSegments); + + // buffers const indices = []; const vertices = []; const normals = []; - const uvs = []; // helper variables + const uvs = []; + + // helper variables let index = 0; const indexArray = []; const halfHeight = height / 2; - let groupStart = 0; // generate geometry + let groupStart = 0; - generateTorso(); + // generate geometry + generateTorso(); if (openEnded === false) { if (radiusTop > 0) generateCap(true); if (radiusBottom > 0) generateCap(false); - } // build geometry + } + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); - function generateTorso() { const normal = new Vector3(); const vertex = new Vector3(); - let groupCount = 0; // this will be used to calculate the normal + let groupCount = 0; - const slope = (radiusBottom - radiusTop) / height; // generate vertices, normals and uvs + // this will be used to calculate the normal + const slope = (radiusBottom - radiusTop) / height; + + // generate vertices, normals and uvs for (let y = 0; y <= heightSegments; y++) { const indexRow = []; - const v = y / heightSegments; // calculate the radius of the current row + const v = y / heightSegments; - const radius = v * (radiusBottom - radiusTop) + radiusTop; + // calculate the radius of the current row + const radius = v * (radiusBottom - radiusTop) + radiusTop; for (let x = 0; x <= radialSegments; x++) { const u = x / radialSegments; const theta = u * thetaLength + thetaStart; const sinTheta = Math.sin(theta); - const cosTheta = Math.cos(theta); // vertex + const 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 + vertices.push(vertex.x, vertex.y, vertex.z); + + // normal normal.set(sinTheta, slope, cosTheta).normalize(); - normals.push(normal.x, normal.y, normal.z); // uv + normals.push(normal.x, normal.y, normal.z); + + // uv - uvs.push(u, 1 - v); // save index of vertex in respective row + uvs.push(u, 1 - v); + + // save index of vertex in respective row indexRow.push(index++); - } // now save vertices of the row in our index array + } + // now save vertices of the row in our index array indexArray.push(indexRow); - } // generate indices + } + // generate indices for (let x = 0; x < radialSegments; x++) { for (let y = 0; y < heightSegments; y++) { // we use the index array to access the correct indices + const a = indexArray[y][x]; const b = indexArray[y + 1][x]; const c = indexArray[y + 1][x + 1]; - const d = indexArray[y][x + 1]; // faces + const d = indexArray[y][x + 1]; + + // faces indices.push(a, b, d); - indices.push(b, c, d); // update group counter + indices.push(b, c, d); + + // update group counter groupCount += 6; } - } // add a group to the geometry. this will ensure multi material support + } + // add a group to the geometry. this will ensure multi material support - scope.addGroup(groupStart, groupCount, 0); // calculate new start value for groups + scope.addGroup(groupStart, groupCount, 0); + + // calculate new start value for groups groupStart += groupCount; } - function generateCap(top) { // save the index of the first center vertex const centerIndexStart = index; @@ -24148,71 +21705,92 @@ const vertex = new Vector3(); let groupCount = 0; const radius = top === true ? radiusTop : radiusBottom; - const sign = top === true ? 1 : -1; // first we generate the center vertex data of the cap. + const 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 for (let x = 1; x <= radialSegments; x++) { // vertex - vertices.push(0, halfHeight * sign, 0); // normal - normals.push(0, sign, 0); // uv + vertices.push(0, halfHeight * sign, 0); + + // normal + + normals.push(0, sign, 0); + + // uv - uvs.push(0.5, 0.5); // increase index + uvs.push(0.5, 0.5); + + // increase index index++; - } // save the index of the last center vertex + } + // save the index of the last center vertex + const centerIndexEnd = index; - const centerIndexEnd = index; // now we generate the surrounding vertices, normals and uvs + // now we generate the surrounding vertices, normals and uvs for (let x = 0; x <= radialSegments; x++) { const u = x / radialSegments; const theta = u * thetaLength + thetaStart; const cosTheta = Math.cos(theta); - const sinTheta = Math.sin(theta); // vertex + const sinTheta = Math.sin(theta); + + // vertex vertex.x = radius * sinTheta; vertex.y = halfHeight * sign; vertex.z = radius * cosTheta; - vertices.push(vertex.x, vertex.y, vertex.z); // normal + vertices.push(vertex.x, vertex.y, vertex.z); + + // normal - normals.push(0, sign, 0); // uv + normals.push(0, sign, 0); + + // uv uv.x = cosTheta * 0.5 + 0.5; uv.y = sinTheta * 0.5 * sign + 0.5; - uvs.push(uv.x, uv.y); // increase index + uvs.push(uv.x, uv.y); + + // increase index index++; - } // generate indices + } + // generate indices for (let x = 0; x < radialSegments; x++) { const c = centerIndexStart + x; const i = centerIndexEnd + x; - if (top === true) { // face top + indices.push(i, i + 1, c); } else { // face bottom + indices.push(i + 1, i, c); } - groupCount += 3; - } // add a group to the geometry. this will ensure multi material support + } + + // add a group to the geometry. this will ensure multi material support + scope.addGroup(groupStart, groupCount, top === true ? 1 : 2); - scope.addGroup(groupStart, groupCount, top === true ? 1 : 2); // calculate new start value for groups + // calculate new start value for groups groupStart += groupCount; } } - static fromJSON(data) { return new CylinderGeometry(data.radiusTop, data.radiusBottom, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength); } - } class ConeGeometry extends CylinderGeometry { @@ -24229,11 +21807,9 @@ thetaLength: thetaLength }; } - static fromJSON(data) { return new ConeGeometry(data.radius, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength); } - } class PolyhedronGeometry extends BufferGeometry { @@ -24245,54 +21821,71 @@ indices: indices, radius: radius, detail: detail - }; // default buffer data + }; + + // default buffer data const vertexBuffer = []; - const uvBuffer = []; // the subdivision creates the vertex buffer data + const uvBuffer = []; + + // the subdivision creates the vertex buffer data + + subdivide(detail); - subdivide(detail); // all vertices should lie on a conceptual sphere with a given radius + // all vertices should lie on a conceptual sphere with a given radius - applyRadius(radius); // finally, create the uv data + applyRadius(radius); - generateUVs(); // build non-indexed geometry + // finally, create the uv data + + generateUVs(); + + // build non-indexed geometry this.setAttribute('position', new Float32BufferAttribute(vertexBuffer, 3)); this.setAttribute('normal', new Float32BufferAttribute(vertexBuffer.slice(), 3)); this.setAttribute('uv', new Float32BufferAttribute(uvBuffer, 2)); - if (detail === 0) { this.computeVertexNormals(); // flat normals } else { this.normalizeNormals(); // smooth normals - } // helper functions + } + // helper functions function subdivide(detail) { const a = new Vector3(); const b = new Vector3(); - const c = new Vector3(); // iterate over all faces and apply a subdivison with the given detail value + const c = new Vector3(); + + // iterate over all faces and apply a subdivision with the given detail value for (let 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 + getVertexByIndex(indices[i + 2], c); + + // perform subdivision subdivideFace(a, b, c, detail); } } - function subdivideFace(a, b, c, detail) { - const cols = detail + 1; // we use this multidimensional array as a data structure for creating the subdivision + const cols = detail + 1; + + // we use this multidimensional array as a data structure for creating the subdivision - const v = []; // construct all of the vertices for this subdivision + const v = []; + + // construct all of the vertices for this subdivision for (let i = 0; i <= cols; i++) { v[i] = []; const aj = a.clone().lerp(c, i / cols); const bj = b.clone().lerp(c, i / cols); const rows = cols - i; - for (let j = 0; j <= rows; j++) { if (j === 0 && i === cols) { v[i][j] = aj; @@ -24300,13 +21893,13 @@ v[i][j] = aj.clone().lerp(bj, j / rows); } } - } // construct all of the faces + } + // construct all of the faces for (let i = 0; i < cols; i++) { for (let j = 0; j < 2 * (cols - i) - 1; j++) { const k = Math.floor(j / 2); - if (j % 2 === 0) { pushVertex(v[i][k + 1]); pushVertex(v[i + 1][k]); @@ -24319,9 +21912,10 @@ } } } - function applyRadius(radius) { - const vertex = new Vector3(); // iterate over the entire buffer and apply the radius to each vertex + const vertex = new Vector3(); + + // iterate over the entire buffer and apply the radius to each vertex for (let i = 0; i < vertexBuffer.length; i += 3) { vertex.x = vertexBuffer[i + 0]; @@ -24333,10 +21927,8 @@ vertexBuffer[i + 2] = vertex.z; } } - function generateUVs() { const vertex = new Vector3(); - for (let i = 0; i < vertexBuffer.length; i += 3) { vertex.x = vertexBuffer[i + 0]; vertex.y = vertexBuffer[i + 1]; @@ -24345,20 +21937,22 @@ const v = inclination(vertex) / Math.PI + 0.5; uvBuffer.push(u, 1 - v); } - correctUVs(); correctSeam(); } - function correctSeam() { // handle case when face straddles the seam, see #3269 + for (let i = 0; i < uvBuffer.length; i += 6) { // uv data of a single face + const x0 = uvBuffer[i + 0]; const x1 = uvBuffer[i + 2]; const x2 = uvBuffer[i + 4]; const max = Math.max(x0, x1, x2); - const min = Math.min(x0, x1, x2); // 0.9 is somewhat arbitrary + const min = Math.min(x0, x1, x2); + + // 0.9 is somewhat arbitrary if (max > 0.9 && min < 0.1) { if (x0 < 0.2) uvBuffer[i + 0] += 1; @@ -24367,18 +21961,15 @@ } } } - function pushVertex(vertex) { vertexBuffer.push(vertex.x, vertex.y, vertex.z); } - function getVertexByIndex(index, vertex) { const stride = index * 3; vertex.x = vertices[stride + 0]; vertex.y = vertices[stride + 1]; vertex.z = vertices[stride + 2]; } - function correctUVs() { const a = new Vector3(); const b = new Vector3(); @@ -24387,7 +21978,6 @@ const uvA = new Vector2(); const uvB = new Vector2(); const uvC = new Vector2(); - for (let 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]); @@ -24402,42 +21992,44 @@ correctUV(uvC, j + 4, c, azi); } } - function correctUV(uv, stride, vector, azimuth) { if (azimuth < 0 && uv.x === 1) { uvBuffer[stride] = uv.x - 1; } - 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. + } + // 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. + } + // Angle above the XZ plane. function inclination(vector) { return Math.atan2(-vector.y, Math.sqrt(vector.x * vector.x + vector.z * vector.z)); } } - static fromJSON(data) { return new PolyhedronGeometry(data.vertices, data.indices, data.radius, data.details); } - } class DodecahedronGeometry extends PolyhedronGeometry { constructor(radius = 1, detail = 0) { const t = (1 + Math.sqrt(5)) / 2; const r = 1 / t; - const 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/φ) + const 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]; const 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]; super(vertices, indices, radius, detail); @@ -24447,21 +22039,15 @@ detail: detail }; } - static fromJSON(data) { return new DodecahedronGeometry(data.radius, data.detail); } - } const _v0 = /*@__PURE__*/new Vector3(); - const _v1$1 = /*@__PURE__*/new Vector3(); - const _normal = /*@__PURE__*/new Vector3(); - const _triangle = /*@__PURE__*/new Triangle(); - class EdgesGeometry extends BufferGeometry { constructor(geometry = null, thresholdAngle = 1) { super(); @@ -24470,7 +22056,6 @@ geometry: geometry, thresholdAngle: thresholdAngle }; - if (geometry !== null) { const precisionPoints = 4; const precision = Math.pow(10, precisionPoints); @@ -24483,7 +22068,6 @@ const hashes = new Array(3); const edgeData = {}; const vertices = []; - for (let i = 0; i < indexCount; i += 3) { if (indexAttr) { indexArr[0] = indexAttr.getX(i); @@ -24494,7 +22078,6 @@ indexArr[1] = i + 1; indexArr[2] = i + 2; } - const { a, b, @@ -24503,19 +22086,19 @@ a.fromBufferAttribute(positionAttr, indexArr[0]); b.fromBufferAttribute(positionAttr, indexArr[1]); c.fromBufferAttribute(positionAttr, indexArr[2]); + _triangle.getNormal(_normal); - _triangle.getNormal(_normal); // create hashes for the edge from the vertices - - + // create hashes for the edge from the vertices 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 + hashes[2] = `${Math.round(c.x * precision)},${Math.round(c.y * precision)},${Math.round(c.z * precision)}`; + // skip degenerate triangles if (hashes[0] === hashes[1] || hashes[1] === hashes[2] || hashes[2] === hashes[0]) { continue; - } // iterate over every edge - + } + // iterate over every edge for (let j = 0; j < 3; j++) { // get the first and next vertex making up the edge const jNext = (j + 1) % 3; @@ -24525,7 +22108,6 @@ const v1 = _triangle[vertKeys[jNext]]; const hash = `${vecHash0}_${vecHash1}`; const 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. @@ -24533,7 +22115,6 @@ 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 @@ -24544,29 +22125,24 @@ }; } } - } // iterate over all remaining, unmatched edges and add them to the vertex array - + } + // iterate over all remaining, unmatched edges and add them to the vertex array for (const key in edgeData) { if (edgeData[key]) { const { index0, index1 } = edgeData[key]; - _v0.fromBufferAttribute(positionAttr, index0); - _v1$1.fromBufferAttribute(positionAttr, index1); - vertices.push(_v0.x, _v0.y, _v0.z); vertices.push(_v1$1.x, _v1$1.y, _v1$1.z); } } - this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); } } - } class Shape extends Path { @@ -24576,17 +22152,15 @@ this.type = 'Shape'; this.holes = []; } - getPointsHoles(divisions) { const holesPts = []; - for (let i = 0, l = this.holes.length; i < l; i++) { holesPts[i] = this.holes[i].getPoints(divisions); } - return holesPts; - } // get points of shape and holes (keypoints based on segments parameter) + } + // get points of shape and holes (keypoints based on segments parameter) extractPoints(divisions) { return { @@ -24594,50 +22168,41 @@ holes: this.getPointsHoles(divisions) }; } - copy(source) { super.copy(source); this.holes = []; - for (let i = 0, l = source.holes.length; i < l; i++) { const hole = source.holes[i]; this.holes.push(hole.clone()); } - return this; } - toJSON() { const data = super.toJSON(); data.uuid = this.uuid; data.holes = []; - for (let i = 0, l = this.holes.length; i < l; i++) { const hole = this.holes[i]; data.holes.push(hole.toJSON()); } - return data; } - fromJSON(json) { super.fromJSON(json); this.uuid = json.uuid; this.holes = []; - for (let i = 0, l = json.holes.length; i < l; i++) { const hole = json.holes[i]; this.holes.push(new Path().fromJSON(hole)); } - return this; } - } /** - * Port from https://github.com/mapbox/earcut (v2.2.2) + * Port from https://github.com/mapbox/earcut (v2.2.4) */ + const Earcut = { triangulate: function (data, holeIndices, dim = 2) { const hasHoles = holeIndices && holeIndices.length; @@ -24646,12 +22211,12 @@ const triangles = []; if (!outerNode || outerNode.next === outerNode.prev) return triangles; let 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 + 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 if (data.length > 80 * dim) { minX = maxX = data[0]; minY = maxY = data[1]; - for (let i = dim; i < outerLen; i += dim) { x = data[i]; y = data[i + 1]; @@ -24659,45 +22224,40 @@ 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 - + } + // minX, minY and invSize are later used to transform coords into integers for z-order calculation invSize = Math.max(maxX - minX, maxY - minY); - invSize = invSize !== 0 ? 1 / invSize : 0; + invSize = invSize !== 0 ? 32767 / invSize : 0; } - - earcutLinked(outerNode, triangles, dim, minX, minY, invSize); + earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0); return triangles; } - }; // create a circular doubly linked list from polygon points in the specified winding order + }; + // create a circular doubly linked list from polygon points in the specified winding order function linkedList(data, start, end, dim, clockwise) { let i, last; - 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; } - return last; - } // eliminate colinear or duplicate points - + } + // eliminate colinear or duplicate points function filterPoints(start, end) { if (!start) return start; if (!end) end = start; let p = start, - again; - + again; do { again = false; - if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) { removeNode(p); p = end = p.prev; @@ -24707,167 +22267,182 @@ p = p.next; } } while (again || p !== end); - return end; - } // main ear slicing loop which triangulates a polygon (given as a linked list) - + } + // main ear slicing loop which triangulates a polygon (given as a linked list) function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) { - if (!ear) return; // interlink polygon nodes in z-order + if (!ear) return; + // interlink polygon nodes in z-order if (!pass && invSize) indexCurve(ear, minX, minY, invSize); let stop = ear, - prev, - next; // iterate through ears, slicing them one by one + prev, + next; + // iterate through ears, slicing them one by one while (ear.prev !== ear.next) { prev = ear.prev; next = ear.next; - 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 + triangles.push(prev.i / dim | 0); + triangles.push(ear.i / dim | 0); + triangles.push(next.i / dim | 0); + removeNode(ear); + // skipping the next vertex leads to less sliver triangles ear = next.next; stop = next.next; continue; } + ear = next; - ear = next; // if we looped through the whole remaining polygon and can't find any more ears - + // if we looped through the whole remaining polygon and can't find any more ears 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 + 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 + 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); } - break; } } - } // check whether a polygon node forms a valid ear with adjacent nodes - + } + // check whether a polygon node forms a valid ear with adjacent nodes function isEar(ear) { const a = ear.prev, - b = ear, - c = ear.next; + 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 - let p = ear.next.next; + // now make sure we don't have other points inside the potential ear + const ax = a.x, + bx = b.x, + cx = c.x, + ay = a.y, + by = b.y, + cy = c.y; - 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; + // triangle bbox; min & max are calculated like this for speed + const x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx, + y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy, + x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx, + y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy; + let p = c.next; + while (p !== a) { + if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; p = p.next; } - return true; } - function isEarHashed(ear, minX, minY, invSize) { const a = ear.prev, - b = ear, - c = ear.next; + 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 - const 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; + const ax = a.x, + bx = b.x, + cx = c.x, + ay = a.y, + by = b.y, + cy = c.y; - const minZ = zOrder(minTX, minTY, minX, minY, invSize), - maxZ = zOrder(maxTX, maxTY, minX, minY, invSize); + // triangle bbox; min & max are calculated like this for speed + const x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx, + y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy, + x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx, + y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy; + + // z-order range for the current triangle bbox; + const minZ = zOrder(x0, y0, minX, minY, invSize), + maxZ = zOrder(x1, y1, minX, minY, invSize); let p = ear.prevZ, - n = ear.nextZ; // look for points inside the triangle in both directions + n = ear.nextZ; + // look for points inside the triangle in both directions 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; + if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangle(ax, ay, bx, by, cx, cy, 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; + if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; n = n.nextZ; - } // look for remaining points in decreasing z-order - + } + // 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; + if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; p = p.prevZ; - } // look for remaining points in increasing z-order - + } + // look for remaining points in increasing z-order 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; + if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; n = n.nextZ; } - return true; - } // go through all polygon nodes and cure small local self-intersections - + } + // go through all polygon nodes and cure small local self-intersections function cureLocalIntersections(start, triangles, dim) { let p = start; - do { const a = p.prev, - b = p.next.next; - + b = p.next.next; 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 + triangles.push(a.i / dim | 0); + triangles.push(p.i / dim | 0); + triangles.push(b.i / dim | 0); + // remove two nodes involved removeNode(p); removeNode(p.next); p = start = b; } - p = p.next; } while (p !== start); - return filterPoints(p); - } // try splitting polygon into two and triangulate them independently - + } + // 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 let a = start; - do { let b = a.next.next; - while (b !== a.prev) { if (a.i !== b.i && isValidDiagonal(a, b)) { // split the polygon in two by the diagonal - let c = splitPolygon(a, b); // filter colinear points around the cuts + let 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 + c = filterPoints(c, c.next); - earcutLinked(a, triangles, dim, minX, minY, invSize); - earcutLinked(c, triangles, dim, minX, minY, invSize); + // run earcut on each half + earcutLinked(a, triangles, dim, minX, minY, invSize, 0); + earcutLinked(c, triangles, dim, minX, minY, invSize, 0); return; } - b = b.next; } - a = a.next; } while (a !== start); - } // link every hole into the outer loop, producing a single-ring polygon without holes - + } + // link every hole into the outer loop, producing a single-ring polygon without holes function eliminateHoles(data, holeIndices, outerNode, dim) { const queue = []; let 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; @@ -24875,74 +22450,65 @@ if (list === list.next) list.steiner = true; queue.push(getLeftmost(list)); } + queue.sort(compareX); - queue.sort(compareX); // process holes from left to right - + // process holes from left to right for (i = 0; i < queue.length; i++) { - eliminateHole(queue[i], outerNode); - outerNode = filterPoints(outerNode, outerNode.next); + outerNode = eliminateHole(queue[i], outerNode); } - return outerNode; } - function compareX(a, b) { return a.x - b.x; - } // find a bridge between vertices that connects hole with an outer ring and link it - + } + // find a bridge between vertices that connects hole with an outer ring and link it function eliminateHole(hole, outerNode) { - outerNode = findHoleBridge(hole, outerNode); - - if (outerNode) { - const b = splitPolygon(outerNode, hole); // filter collinear points around the cuts - - filterPoints(outerNode, outerNode.next); - filterPoints(b, b.next); + const bridge = findHoleBridge(hole, outerNode); + if (!bridge) { + return outerNode; } - } // David Eberly's algorithm for finding a bridge between hole and outer polygon + const bridgeReverse = splitPolygon(bridge, hole); + // filter collinear points around the cuts + filterPoints(bridgeReverse, bridgeReverse.next); + return filterPoints(bridge, bridge.next); + } + // David Eberly's algorithm for finding a bridge between hole and outer polygon function findHoleBridge(hole, outerNode) { - let p = outerNode; - const hx = hole.x; - const hy = hole.y; - let 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 + let p = outerNode, + qx = -Infinity, + m; + const hx = hole.x, + hy = hole.y; + // 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 do { if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) { const x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); - if (x <= hx && x > qx) { qx = x; - - if (x === hx) { - if (hy === p.y) return p; - if (hy === p.next.y) return p.next; - } - m = p.x < p.next.x ? p : p.next; + if (x === hx) return m; // hole touches outer segment; pick leftmost endpoint } } p = p.next; } while (p !== outerNode); - 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 const stop = m, - mx = m.x, - my = m.y; + mx = m.x, + my = m.y; let tanMin = Infinity, - tan; + tan; p = m; - 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 @@ -24952,66 +22518,57 @@ tanMin = tan; } } - p = p.next; } while (p !== stop); - return m; - } // whether sector in vertex m contains sector in vertex p in the same coordinates - + } + // whether sector in vertex m contains sector in vertex p in the same coordinates 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 - + } + // interlink polygon nodes in z-order function indexCurve(start, minX, minY, invSize) { let p = start; - do { - if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, invSize); + if (p.z === 0) p.z = zOrder(p.x, p.y, minX, minY, invSize); p.prevZ = p.prev; p.nextZ = p.next; p = p.next; } while (p !== start); - 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 - + } + // Simon Tatham's linked list merge sort algorithm + // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html function sortLinked(list) { let i, - p, - q, - e, - tail, - numMerges, - pSize, - qSize, - inSize = 1; - + p, + q, + e, + tail, + numMerges, + pSize, + qSize, + inSize = 1; do { p = list; list = null; tail = null; numMerges = 0; - while (p) { numMerges++; q = p; pSize = 0; - for (i = 0; i < inSize; i++) { pSize++; q = q.nextZ; if (!q) break; } - qSize = inSize; - while (pSize > 0 || qSize > 0 && q) { if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) { e = p; @@ -25022,27 +22579,23 @@ q = q.nextZ; qSize--; } - if (tail) tail.nextZ = e;else list = e; e.prevZ = tail; tail = e; } - p = q; } - tail.nextZ = null; inSize *= 2; } while (numMerges > 1); - return list; - } // z-order of a point given coords and inverse of the longer side of data bbox - + } + // z-order of a point given coords and inverse of the longer side of data bbox 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 - minX) * invSize | 0; + y = (y - minY) * invSize | 0; x = (x | x << 8) & 0x00FF00FF; x = (x | x << 4) & 0x0F0F0F0F; x = (x | x << 2) & 0x33333333; @@ -25052,45 +22605,46 @@ y = (y | y << 2) & 0x33333333; y = (y | y << 1) & 0x55555555; return x | y << 1; - } // find the leftmost node of a polygon ring - + } + // find the leftmost node of a polygon ring function getLeftmost(start) { let p = start, - leftmost = 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); - return leftmost; - } // check if a point lies within a convex triangle - + } + // check if a point lies within a convex triangle 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) - + return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && (ax - px) * (by - py) >= (bx - px) * (ay - py) && (bx - px) * (cy - py) >= (cx - px) * (by - py); + } + // check if a diagonal between two polygon nodes is valid (lies in polygon interior) function isValidDiagonal(a, b) { - return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && ( // doesn'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 + 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 - + } + // signed area of a triangle 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 - + } + // check if two points are equal function equals(p1, p2) { return p1.x === p2.x && p1.y === p2.y; - } // check if two segments intersect - + } + // check if two segments intersect function intersects(p1, q1, p2, q2) { const o1 = sign(area(p1, q1, p2)); const o2 = sign(area(p1, q1, q2)); @@ -25099,64 +22653,56 @@ if (o1 !== o2 && o3 !== o4) return true; // general case if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1 - if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1 - if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2 - if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2 return false; - } // for collinear points p, q, r, check if point q lies on segment pr - + } + // 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 - + } + // check if a polygon diagonal intersects any polygon segments function intersectsPolygon(a, b) { let p = a; - 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); - return false; - } // check if a polygon diagonal is locally inside the polygon - + } + // check if a polygon diagonal is locally inside the polygon 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 - + } + // check if the middle point of a polygon diagonal is inside the polygon function middleInside(a, b) { let p = a, - inside = false; + inside = false; const px = (a.x + b.x) / 2, - py = (a.y + b.y) / 2; - + py = (a.y + b.y) / 2; 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); - 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 - + } + // 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 function splitPolygon(a, b) { const a2 = new Node(a.i, a.x, a.y), - b2 = new Node(b.i, b.x, b.y), - an = a.next, - bp = b.prev; + b2 = new Node(b.i, b.x, b.y), + an = a.next, + bp = b.prev; a.next = b; b.prev = a; a2.next = an; @@ -25166,12 +22712,11 @@ bp.next = b2; b2.prev = bp; return b2; - } // create a node and optionally link it with previous one (in a circular doubly linked list) - + } + // create a node and optionally link it with previous one (in a circular doubly linked list) function insertNode(i, x, y, last) { const p = new Node(i, x, y); - if (!last) { p.prev = p; p.next = p; @@ -25181,102 +22726,95 @@ last.next.prev = p; last.next = p; } - 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; } - function Node(i, x, y) { // vertex index in coordinates array - this.i = i; // vertex coordinates + this.i = i; + // vertex coordinates this.x = x; - this.y = y; // previous and next vertex nodes in a polygon ring + this.y = y; + // previous and next vertex nodes in a polygon ring this.prev = null; - this.next = null; // z-order curve value + this.next = null; - this.z = null; // previous and next nodes in z-order + // z-order curve value + this.z = 0; + // previous and next nodes in z-order this.prevZ = null; - this.nextZ = null; // indicates whether this is a steiner point + this.nextZ = null; + // indicates whether this is a steiner point this.steiner = false; } - function signedArea(data, start, end, dim) { let sum = 0; - for (let i = start, j = end - dim; i < end; i += dim) { sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); j = i; } - return sum; } class ShapeUtils { // calculate area of the contour polygon + static area(contour) { const n = contour.length; let a = 0.0; - for (let 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; } - static isClockWise(pts) { return ShapeUtils.area(pts) < 0; } - static triangulateShape(contour, holes) { const vertices = []; // flat array of vertices like [ x0,y0, x1,y1, x2,y2, ... ] - const holeIndices = []; // array of hole indices - const faces = []; // final array of vertex indices like [ [ a,b,d ], [ b,c,d ] ] removeDupEndPts(contour); - addContour(vertices, contour); // + addContour(vertices, contour); + + // let holeIndex = contour.length; holes.forEach(removeDupEndPts); - for (let i = 0; i < holes.length; i++) { holeIndices.push(holeIndex); holeIndex += holes[i].length; addContour(vertices, holes[i]); - } // + } + + // + const triangles = Earcut.triangulate(vertices, holeIndices); - const triangles = Earcut.triangulate(vertices, holeIndices); // + // for (let i = 0; i < triangles.length; i += 3) { faces.push(triangles.slice(i, i + 3)); } - return faces; } - } - function removeDupEndPts(points) { const l = points.length; - if (l > 2 && points[l - 1].equals(points[0])) { points.pop(); } } - function addContour(vertices, contour) { for (let i = 0; i < contour.length; i++) { vertices.push(contour[i].x); @@ -25305,7 +22843,6 @@ * * } */ - class ExtrudeGeometry extends BufferGeometry { constructor(shapes = new Shape([new Vector2(0.5, 0.5), new Vector2(-0.5, 0.5), new Vector2(-0.5, -0.5), new Vector2(0.5, -0.5)]), options = {}) { super(); @@ -25318,19 +22855,23 @@ const scope = this; const verticesArray = []; const uvArray = []; - for (let i = 0, l = shapes.length; i < l; i++) { const shape = shapes[i]; addShape(shape); - } // build geometry + } + // build geometry this.setAttribute('position', new Float32BufferAttribute(verticesArray, 3)); this.setAttribute('uv', new Float32BufferAttribute(uvArray, 2)); - this.computeVertexNormals(); // functions + this.computeVertexNormals(); + + // functions function addShape(shape) { - const placeholder = []; // options + const placeholder = []; + + // options const curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12; const steps = options.steps !== undefined ? options.steps : 1; @@ -25341,53 +22882,60 @@ let bevelOffset = options.bevelOffset !== undefined ? options.bevelOffset : 0; let bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3; const extrudePath = options.extrudePath; - const uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator; // + const uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator; + + // let extrudePts, - extrudeByPath = false; + extrudeByPath = false; let splineTube, binormal, normal, position2; - 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? - splineTube = extrudePath.computeFrenetFrames(steps, false); // console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length); + splineTube = extrudePath.computeFrenetFrames(steps, false); + + // console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length); binormal = new Vector3(); normal = new Vector3(); position2 = new Vector3(); - } // Safeguards if bevels are not enabled + } + // Safeguards if bevels are not enabled if (!bevelEnabled) { bevelSegments = 0; bevelThickness = 0; bevelSize = 0; bevelOffset = 0; - } // Variables initialization + } + // Variables initialization const shapePoints = shape.extractPoints(curveSegments); let vertices = shapePoints.shape; const holes = shapePoints.holes; const reverse = !ShapeUtils.isClockWise(vertices); - if (reverse) { - vertices = vertices.reverse(); // Maybe we should also check if holes are in the opposite direction, just to be safe ... + vertices = vertices.reverse(); + + // Maybe we should also check if holes are in the opposite direction, just to be safe ... for (let h = 0, hl = holes.length; h < hl; h++) { const ahole = holes[h]; - if (ShapeUtils.isClockWise(ahole)) { holes[h] = ahole.reverse(); } } } - const faces = ShapeUtils.triangulateShape(vertices, holes); + /* Vertices */ const contour = vertices; // vertices has all points but contour has only points of circumference @@ -25396,14 +22944,14 @@ const ahole = holes[h]; vertices = vertices.concat(ahole); } - function scalePt2(pt, vec, size) { if (!vec) console.error('THREE.ExtrudeGeometry: vec does not exist'); return vec.clone().multiplyScalar(size).add(pt); } - const vlen = vertices.length, - flen = faces.length; // Find directions for point movement + flen = faces.length; + + // Find directions for point movement function getBevelVec(inPt, inPrev, inNext) { // computes for inPt the corresponding point inPt' on a new contour @@ -25412,37 +22960,47 @@ // // 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. + let 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 const v_prev_x = inPt.x - inPrev.x, - v_prev_y = inPt.y - inPrev.y; + v_prev_y = inPt.y - inPrev.y; const v_next_x = inNext.x - inPt.x, - v_next_y = inNext.y - inPt.y; - const v_prev_lensq = v_prev_x * v_prev_x + v_prev_y * v_prev_y; // check for collinear edges + v_next_y = inNext.y - inPt.y; + const v_prev_lensq = v_prev_x * v_prev_x + v_prev_y * v_prev_y; + // check for collinear edges const collinear0 = v_prev_x * v_next_y - v_prev_y * v_next_x; - if (Math.abs(collinear0) > Number.EPSILON) { // not collinear + // length of vectors for normalizing + const v_prev_len = Math.sqrt(v_prev_lensq); - const 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 + const 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 const ptPrevShift_x = inPrev.x - v_prev_y / v_prev_len; const ptPrevShift_y = inPrev.y + v_prev_x / v_prev_len; const ptNextShift_x = inNext.x - v_next_y / v_next_len; - const ptNextShift_y = inNext.y + v_next_x / v_next_len; // scaling factor for v_prev to intersection point + const ptNextShift_y = inNext.y + v_next_x / v_next_len; + + // scaling factor for v_prev to intersection point + + const 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); - const 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 + // 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 + v_trans_y = ptPrevShift_y + v_prev_y * sf - inPt.y; + // Don't normalize!, otherwise sharp corners become ugly + // but prevent crazy spikes const v_trans_lensq = v_trans_x * v_trans_x + v_trans_y * v_trans_y; - if (v_trans_lensq <= 2) { return new Vector2(v_trans_x, v_trans_y); } else { @@ -25450,6 +23008,7 @@ } } else { // handle special case of collinear edges + let direction_eq = false; // assumes: opposite if (v_prev_x > Number.EPSILON) { @@ -25467,7 +23026,6 @@ } } } - if (direction_eq) { // console.log("Warning: lines are a straight sequence"); v_trans_x = -v_prev_y; @@ -25480,117 +23038,121 @@ shrink_by = Math.sqrt(v_prev_lensq / 2); } } - return new Vector2(v_trans_x / shrink_by, v_trans_y / shrink_by); } - const contourMovements = []; - for (let 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) + if (k === il) k = 0; + + // (j)---(i)---(k) // console.log('i,j,k', i, j , k) contourMovements[i] = getBevelVec(contour[i], contour[j], contour[k]); } - const holesMovements = []; let oneHoleMovements, - verticesMovements = contourMovements.concat(); - + verticesMovements = contourMovements.concat(); for (let h = 0, hl = holes.length; h < hl; h++) { const ahole = holes[h]; oneHoleMovements = []; - for (let 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) + 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 + } + // Loop bevelSegments, 1 for the front, 1 for the back for (let b = 0; b < bevelSegments; b++) { //for ( b = bevelSegments; b > 0; b -- ) { + const t = b / bevelSegments; const z = bevelThickness * Math.cos(t * Math.PI / 2); - const bs = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset; // contract shape + const bs = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset; + + // contract shape for (let i = 0, il = contour.length; i < il; i++) { const vert = scalePt2(contour[i], contourMovements[i], bs); v(vert.x, vert.y, -z); - } // expand holes + } + // expand holes for (let h = 0, hl = holes.length; h < hl; h++) { const ahole = holes[h]; oneHoleMovements = holesMovements[h]; - for (let i = 0, il = ahole.length; i < il; i++) { const vert = scalePt2(ahole[i], oneHoleMovements[i], bs); v(vert.x, vert.y, -z); } } } + const bs = bevelSize + bevelOffset; - const bs = bevelSize + bevelOffset; // Back facing vertices + // Back facing vertices for (let i = 0; i < vlen; i++) { const 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 + } + // Add stepped vertices... + // Including front facing vertices for (let s = 1; s <= steps; s++) { for (let i = 0; i < vlen; i++) { const vert = bevelEnabled ? scalePt2(vertices[i], verticesMovements[i], bs) : vertices[i]; - if (!extrudeByPath) { v(vert.x, vert.y, depth / 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 ++ ) { + } + // Add bevel segments planes + //for ( b = 1; b <= bevelSegments; b ++ ) { for (let b = bevelSegments - 1; b >= 0; b--) { const t = b / bevelSegments; const z = bevelThickness * Math.cos(t * Math.PI / 2); - const bs = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset; // contract shape + const bs = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset; + + // contract shape for (let i = 0, il = contour.length; i < il; i++) { const vert = scalePt2(contour[i], contourMovements[i], bs); v(vert.x, vert.y, depth + z); - } // expand holes + } + // expand holes for (let h = 0, hl = holes.length; h < hl; h++) { const ahole = holes[h]; oneHoleMovements = holesMovements[h]; - for (let i = 0, il = ahole.length; i < il; i++) { const vert = scalePt2(ahole[i], oneHoleMovements[i], bs); - if (!extrudeByPath) { v(vert.x, vert.y, depth + z); } else { @@ -25599,29 +23161,35 @@ } } } + /* Faces */ + // Top and bottom faces + buildLidFaces(); - buildLidFaces(); // Sides faces + // Sides faces - buildSideFaces(); ///// Internal functions + buildSideFaces(); + + ///// Internal functions function buildLidFaces() { const start = verticesArray.length / 3; - if (bevelEnabled) { let layer = 0; // steps + 1 + let offset = vlen * layer; - let offset = vlen * layer; // Bottom faces + // Bottom faces for (let i = 0; i < flen; i++) { const face = faces[i]; f3(face[2] + offset, face[1] + offset, face[0] + offset); } - layer = steps + bevelSegments * 2; - offset = vlen * layer; // Top faces + offset = vlen * layer; + + // Top faces for (let i = 0; i < flen; i++) { const face = faces[i]; @@ -25629,64 +23197,63 @@ } } else { // Bottom faces + for (let i = 0; i < flen; i++) { const face = faces[i]; f3(face[2], face[1], face[0]); - } // Top faces + } + // Top faces for (let i = 0; i < flen; i++) { const face = faces[i]; f3(face[0] + vlen * steps, face[1] + vlen * steps, face[2] + vlen * steps); } } - scope.addGroup(start, verticesArray.length / 3 - start, 0); - } // Create faces for the z-sides of the shape + } + // Create faces for the z-sides of the shape function buildSideFaces() { const start = verticesArray.length / 3; let layeroffset = 0; sidewalls(contour, layeroffset); layeroffset += contour.length; - for (let h = 0, hl = holes.length; h < hl; h++) { const ahole = holes[h]; - sidewalls(ahole, layeroffset); //, true + sidewalls(ahole, layeroffset); + //, true layeroffset += ahole.length; } - scope.addGroup(start, verticesArray.length / 3 - start, 1); } - function sidewalls(contour, layeroffset) { let i = contour.length; - while (--i >= 0) { const j = i; let k = i - 1; - if (k < 0) k = contour.length - 1; //console.log('b', i,j, i-1, k,vertices.length); + if (k < 0) k = contour.length - 1; + + //console.log('b', i,j, i-1, k,vertices.length); for (let s = 0, sl = steps + bevelSegments * 2; s < sl; s++) { const slen1 = vlen * s; const slen2 = vlen * (s + 1); const a = layeroffset + j + slen1, - b = layeroffset + k + slen1, - c = layeroffset + k + slen2, - d = layeroffset + j + slen2; + b = layeroffset + k + slen1, + c = layeroffset + k + slen2, + d = layeroffset + j + slen2; f4(a, b, c, d); } } } - function v(x, y, z) { placeholder.push(x); placeholder.push(y); placeholder.push(z); } - function f3(a, b, c) { addVertex(a); addVertex(b); @@ -25697,7 +23264,6 @@ addUV(uvs[1]); addUV(uvs[2]); } - function f4(a, b, c, d) { addVertex(a); addVertex(b); @@ -25714,46 +23280,36 @@ 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); } } } - toJSON() { const data = super.toJSON(); const shapes = this.parameters.shapes; const options = this.parameters.options; return toJSON$1(shapes, options, data); } - static fromJSON(data, shapes) { const geometryShapes = []; - for (let j = 0, jl = data.shapes.length; j < jl; j++) { const shape = shapes[data.shapes[j]]; geometryShapes.push(shape); } - const extrudePath = data.options.extrudePath; - if (extrudePath !== undefined) { data.options.extrudePath = new Curves[extrudePath.type]().fromJSON(extrudePath); } - return new ExtrudeGeometry(geometryShapes, data.options); } - } - const WorldUVGenerator = { generateTopUV: function (geometry, vertices, indexA, indexB, indexC) { const a_x = vertices[indexA * 3]; @@ -25777,7 +23333,6 @@ const d_x = vertices[indexD * 3]; const d_y = vertices[indexD * 3 + 1]; const d_z = vertices[indexD * 3 + 2]; - if (Math.abs(a_y - b_y) < Math.abs(a_x - b_x)) { 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 { @@ -25785,10 +23340,8 @@ } } }; - function toJSON$1(shapes, options, data) { data.shapes = []; - if (Array.isArray(shapes)) { for (let i = 0, l = shapes.length; i < l; i++) { const shape = shapes[i]; @@ -25797,7 +23350,6 @@ } else { data.shapes.push(shapes.uuid); } - data.options = Object.assign({}, options); if (options.extrudePath !== undefined) data.options.extrudePath = options.extrudePath.toJSON(); return data; @@ -25815,11 +23367,9 @@ detail: detail }; } - static fromJSON(data) { return new IcosahedronGeometry(data.radius, data.detail); } - } class OctahedronGeometry extends PolyhedronGeometry { @@ -25833,11 +23383,9 @@ detail: detail }; } - static fromJSON(data) { return new OctahedronGeometry(data.radius, data.detail); } - } class RingGeometry extends BufferGeometry { @@ -25853,65 +23401,80 @@ thetaLength: thetaLength }; thetaSegments = Math.max(3, thetaSegments); - phiSegments = Math.max(1, phiSegments); // buffers + phiSegments = Math.max(1, phiSegments); + + // buffers const indices = []; const vertices = []; const normals = []; - const uvs = []; // some helper variables + const uvs = []; + + // some helper variables let radius = innerRadius; const radiusStep = (outerRadius - innerRadius) / phiSegments; const vertex = new Vector3(); - const uv = new Vector2(); // generate vertices, normals and uvs + const uv = new Vector2(); + + // generate vertices, normals and uvs for (let j = 0; j <= phiSegments; j++) { for (let i = 0; i <= thetaSegments; i++) { // values are generate from the inside of the ring to the outside - const segment = thetaStart + i / thetaSegments * thetaLength; // vertex + + const segment = thetaStart + i / thetaSegments * thetaLength; + + // vertex vertex.x = radius * Math.cos(segment); vertex.y = radius * Math.sin(segment); - vertices.push(vertex.x, vertex.y, vertex.z); // normal + vertices.push(vertex.x, vertex.y, vertex.z); + + // normal + + normals.push(0, 0, 1); - normals.push(0, 0, 1); // uv + // uv 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 + } + // increase the radius for next row of vertices radius += radiusStep; - } // indices + } + // indices for (let j = 0; j < phiSegments; j++) { const thetaSegmentLevel = j * (thetaSegments + 1); - for (let i = 0; i < thetaSegments; i++) { const segment = i + thetaSegmentLevel; const a = segment; const b = segment + thetaSegments + 1; const c = segment + thetaSegments + 2; - const d = segment + 1; // faces + const d = segment + 1; + + // faces indices.push(a, b, d); indices.push(b, c, d); } - } // build geometry + } + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); } - static fromJSON(data) { return new RingGeometry(data.innerRadius, data.outerRadius, data.thetaSegments, data.phiSegments, data.thetaStart, data.thetaLength); } - } class ShapeGeometry extends BufferGeometry { @@ -25921,15 +23484,21 @@ this.parameters = { shapes: shapes, curveSegments: curveSegments - }; // buffers + }; + + // buffers const indices = []; const vertices = []; const normals = []; - const uvs = []; // helper variables + const uvs = []; + + // helper variables let groupStart = 0; - let groupCount = 0; // allow single and array values for "shapes" parameter + let groupCount = 0; + + // allow single and array values for "shapes" parameter if (Array.isArray(shapes) === false) { addShape(shapes); @@ -25941,47 +23510,53 @@ groupStart += groupCount; groupCount = 0; } - } // build geometry + } + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // helper functions + this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); + + // helper functions function addShape(shape) { const indexOffset = vertices.length / 3; const points = shape.extractPoints(curveSegments); let shapeVertices = points.shape; - const shapeHoles = points.holes; // check direction of vertices + const shapeHoles = points.holes; + + // check direction of vertices if (ShapeUtils.isClockWise(shapeVertices) === false) { shapeVertices = shapeVertices.reverse(); } - for (let i = 0, l = shapeHoles.length; i < l; i++) { const shapeHole = shapeHoles[i]; - if (ShapeUtils.isClockWise(shapeHole) === true) { shapeHoles[i] = shapeHole.reverse(); } } + const faces = ShapeUtils.triangulateShape(shapeVertices, shapeHoles); - const faces = ShapeUtils.triangulateShape(shapeVertices, shapeHoles); // join vertices of inner and outer paths to a single array + // join vertices of inner and outer paths to a single array for (let i = 0, l = shapeHoles.length; i < l; i++) { const shapeHole = shapeHoles[i]; shapeVertices = shapeVertices.concat(shapeHole); - } // vertices, normals, uvs + } + // vertices, normals, uvs for (let i = 0, l = shapeVertices.length; i < l; i++) { const vertex = shapeVertices[i]; vertices.push(vertex.x, vertex.y, 0); normals.push(0, 0, 1); uvs.push(vertex.x, vertex.y); // world uvs - } // incides + } + // indices for (let i = 0, l = faces.length; i < l; i++) { const face = faces[i]; @@ -25993,29 +23568,22 @@ } } } - toJSON() { const data = super.toJSON(); const shapes = this.parameters.shapes; return toJSON(shapes, data); } - static fromJSON(data, shapes) { const geometryShapes = []; - for (let j = 0, jl = data.shapes.length; j < jl; j++) { const shape = shapes[data.shapes[j]]; geometryShapes.push(shape); } - return new ShapeGeometry(geometryShapes, data.curveSegments); } - } - function toJSON(shapes, data) { data.shapes = []; - if (Array.isArray(shapes)) { for (let i = 0, l = shapes.length; i < l; i++) { const shape = shapes[i]; @@ -26024,7 +23592,6 @@ } else { data.shapes.push(shapes.uuid); } - return data; } @@ -26047,43 +23614,53 @@ let index = 0; const grid = []; const vertex = new Vector3(); - const normal = new Vector3(); // buffers + const normal = new Vector3(); + + // buffers const indices = []; const vertices = []; const normals = []; - const uvs = []; // generate vertices, normals and uvs + const uvs = []; + + // generate vertices, normals and uvs for (let iy = 0; iy <= heightSegments; iy++) { const verticesRow = []; - const v = iy / heightSegments; // special case for the poles + const v = iy / heightSegments; - let uOffset = 0; + // special case for the poles + let uOffset = 0; if (iy == 0 && thetaStart == 0) { uOffset = 0.5 / widthSegments; } else if (iy == heightSegments && thetaEnd == Math.PI) { uOffset = -0.5 / widthSegments; } - for (let ix = 0; ix <= widthSegments; ix++) { - const u = ix / widthSegments; // vertex + const u = ix / widthSegments; + + // vertex 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 + vertices.push(vertex.x, vertex.y, vertex.z); + + // normal normal.copy(vertex).normalize(); - normals.push(normal.x, normal.y, normal.z); // uv + normals.push(normal.x, normal.y, normal.z); + + // uv uvs.push(u + uOffset, 1 - v); verticesRow.push(index++); } - grid.push(verticesRow); - } // indices + } + // indices for (let iy = 0; iy < heightSegments; iy++) { for (let ix = 0; ix < widthSegments; ix++) { @@ -26094,19 +23671,18 @@ if (iy !== 0 || thetaStart > 0) indices.push(a, b, d); if (iy !== heightSegments - 1 || thetaEnd < Math.PI) indices.push(b, c, d); } - } // build geometry + } + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); } - static fromJSON(data) { return new SphereGeometry(data.radius, data.widthSegments, data.heightSegments, data.phiStart, data.phiLength, data.thetaStart, data.thetaLength); } - } class TetrahedronGeometry extends PolyhedronGeometry { @@ -26120,11 +23696,9 @@ detail: detail }; } - static fromJSON(data) { return new TetrahedronGeometry(data.radius, data.detail); } - } class TorusGeometry extends BufferGeometry { @@ -26139,62 +23713,77 @@ arc: arc }; radialSegments = Math.floor(radialSegments); - tubularSegments = Math.floor(tubularSegments); // buffers + tubularSegments = Math.floor(tubularSegments); + + // buffers const indices = []; const vertices = []; const normals = []; - const uvs = []; // helper variables + const uvs = []; + + // helper variables const center = new Vector3(); const vertex = new Vector3(); - const normal = new Vector3(); // generate vertices, normals and uvs + const normal = new Vector3(); + + // generate vertices, normals and uvs for (let j = 0; j <= radialSegments; j++) { for (let i = 0; i <= tubularSegments; i++) { const u = i / tubularSegments * arc; - const v = j / radialSegments * Math.PI * 2; // vertex + const 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 + 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 + normals.push(normal.x, normal.y, normal.z); + + // uv uvs.push(i / tubularSegments); uvs.push(j / radialSegments); } - } // generate indices + } + // generate indices for (let j = 1; j <= radialSegments; j++) { for (let i = 1; i <= tubularSegments; i++) { // indices + const a = (tubularSegments + 1) * j + i - 1; const b = (tubularSegments + 1) * (j - 1) + i - 1; const c = (tubularSegments + 1) * (j - 1) + i; - const d = (tubularSegments + 1) * j + i; // faces + const d = (tubularSegments + 1) * j + i; + + // faces indices.push(a, b, d); indices.push(b, c, d); } - } // build geometry + } + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); } - static fromJSON(data) { return new TorusGeometry(data.radius, data.tube, data.radialSegments, data.tubularSegments, data.arc); } - } class TorusKnotGeometry extends BufferGeometry { @@ -26210,12 +23799,16 @@ q: q }; tubularSegments = Math.floor(tubularSegments); - radialSegments = Math.floor(radialSegments); // buffers + radialSegments = Math.floor(radialSegments); + + // buffers const indices = []; const vertices = []; const normals = []; - const uvs = []; // helper variables + const uvs = []; + + // helper variables const vertex = new Vector3(); const normal = new Vector3(); @@ -26223,64 +23816,86 @@ const P2 = new Vector3(); const B = new Vector3(); const T = new Vector3(); - const N = new Vector3(); // generate vertices, normals and uvs + const N = new Vector3(); + + // generate vertices, normals and uvs for (let i = 0; i <= tubularSegments; ++i) { // the radian "u" is used to calculate the position on the torus curve of the current tubular segment - const 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. + + const 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 + 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 + N.crossVectors(B, T); + + // normalize B, N. T can be ignored, we don't use it B.normalize(); N.normalize(); - for (let 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. + const v = j / radialSegments * Math.PI * 2; const cx = -tube * Math.cos(v); - const cy = tube * Math.sin(v); // now calculate the final vertex position. + const cy = tube * Math.sin(v); + + // now calculate the final vertex position. // first we orient the extrusion with our basis vectors, 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) + 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 + normals.push(normal.x, normal.y, normal.z); + + // uv uvs.push(i / tubularSegments); uvs.push(j / radialSegments); } - } // generate indices + } + // generate indices for (let j = 1; j <= tubularSegments; j++) { for (let i = 1; i <= radialSegments; i++) { // indices + const a = (radialSegments + 1) * (j - 1) + (i - 1); const b = (radialSegments + 1) * j + (i - 1); const c = (radialSegments + 1) * j + i; - const d = (radialSegments + 1) * (j - 1) + i; // faces + const d = (radialSegments + 1) * (j - 1) + i; + + // faces indices.push(a, b, d); indices.push(b, c, d); } - } // build geometry + } + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // this function calculates the current position on the torus curve + this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); + + // this function calculates the current position on the torus curve function calculatePositionOnCurve(u, p, q, radius, position) { const cu = Math.cos(u); @@ -26292,11 +23907,9 @@ position.z = radius * Math.sin(quOverP) * 0.5; } } - static fromJSON(data) { return new TorusKnotGeometry(data.radius, data.tube, data.tubularSegments, data.radialSegments, data.p, data.q); } - } class TubeGeometry extends BufferGeometry { @@ -26310,63 +23923,88 @@ radialSegments: radialSegments, closed: closed }; - const frames = path.computeFrenetFrames(tubularSegments, closed); // expose internals + const frames = path.computeFrenetFrames(tubularSegments, closed); + + // expose internals this.tangents = frames.tangents; this.normals = frames.normals; - this.binormals = frames.binormals; // helper variables + this.binormals = frames.binormals; + + // helper variables const vertex = new Vector3(); const normal = new Vector3(); const uv = new Vector2(); - let P = new Vector3(); // buffer + let P = new Vector3(); + + // buffer const vertices = []; const normals = []; const uvs = []; - const indices = []; // create buffer data + const indices = []; + + // create buffer data + + generateBufferData(); - generateBufferData(); // build geometry + // build geometry this.setIndex(indices); this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // functions + this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); + + // functions function generateBufferData() { for (let i = 0; i < tubularSegments; i++) { generateSegment(i); - } // if the geometry is not closed, generate the last row of vertices and normals + } + + // 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) + generateSegment(closed === false ? tubularSegments : 0); - generateSegment(closed === false ? tubularSegments : 0); // uvs are generated in a separate function. + // uvs are generated in a separate function. // this makes it easy compute correct values for closed geometries - generateUVs(); // finally create faces + generateUVs(); + + // finally create faces generateIndices(); } - 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 + + P = path.getPointAt(i / tubularSegments, P); + + // retrieve corresponding normal and binormal const N = frames.normals[i]; - const B = frames.binormals[i]; // generate normals and vertices for the current segment + const B = frames.binormals[i]; + + // generate normals and vertices for the current segment for (let j = 0; j <= radialSegments; j++) { const v = j / radialSegments * Math.PI * 2; const sin = Math.sin(v); - const cos = -Math.cos(v); // normal + const cos = -Math.cos(v); + + // normal 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 + normals.push(normal.x, normal.y, normal.z); + + // vertex vertex.x = P.x + radius * normal.x; vertex.y = P.y + radius * normal.y; @@ -26374,21 +24012,21 @@ vertices.push(vertex.x, vertex.y, vertex.z); } } - function generateIndices() { for (let j = 1; j <= tubularSegments; j++) { for (let i = 1; i <= radialSegments; i++) { const a = (radialSegments + 1) * (j - 1) + (i - 1); const b = (radialSegments + 1) * j + (i - 1); const c = (radialSegments + 1) * j + i; - const d = (radialSegments + 1) * (j - 1) + i; // faces + const d = (radialSegments + 1) * (j - 1) + i; + + // faces indices.push(a, b, d); indices.push(b, c, d); } } } - function generateUVs() { for (let i = 0; i <= tubularSegments; i++) { for (let j = 0; j <= radialSegments; j++) { @@ -26399,19 +24037,16 @@ } } } - toJSON() { const data = super.toJSON(); data.path = this.parameters.path.toJSON(); return data; } - static fromJSON(data) { // This only works for built-in curves (e.g. CatmullRomCurve3). // User defined curves or instances of CurvePath will not be deserialized. return new TubeGeometry(new Curves[data.path.type]().fromJSON(data.path), data.tubularSegments, data.radius, data.radialSegments, data.closed); } - } class WireframeGeometry extends BufferGeometry { @@ -26421,42 +24056,42 @@ this.parameters = { geometry: geometry }; - if (geometry !== null) { // buffer + const vertices = []; - const edges = new Set(); // helper variables + const edges = new Set(); + + // helper variables const start = new Vector3(); const end = new Vector3(); - if (geometry.index !== null) { // indexed BufferGeometry + const position = geometry.attributes.position; const indices = geometry.index; let groups = geometry.groups; - if (groups.length === 0) { groups = [{ start: 0, count: indices.count, materialIndex: 0 }]; - } // create a data structure that contains all edges without duplicates + } + // create a data structure that contains all edges without duplicates for (let o = 0, ol = groups.length; o < ol; ++o) { const group = groups[o]; const groupStart = group.start; const groupCount = group.count; - for (let i = groupStart, l = groupStart + groupCount; i < l; i += 3) { for (let j = 0; j < 3; j++) { const index1 = indices.getX(i + j); const index2 = indices.getX(i + (j + 1) % 3); start.fromBufferAttribute(position, index1); end.fromBufferAttribute(position, index2); - if (isUniqueEdge(start, end, edges) === true) { vertices.push(start.x, start.y, start.z); vertices.push(end.x, end.y, end.z); @@ -26466,32 +24101,31 @@ } } else { // non-indexed BufferGeometry - const position = geometry.attributes.position; + const position = geometry.attributes.position; for (let i = 0, l = position.count / 3; i < l; i++) { for (let j = 0; j < 3; j++) { // 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) + const index1 = 3 * i + j; const index2 = 3 * i + (j + 1) % 3; start.fromBufferAttribute(position, index1); end.fromBufferAttribute(position, index2); - if (isUniqueEdge(start, end, edges) === true) { vertices.push(start.x, start.y, start.z); vertices.push(end.x, end.y, end.z); } } } - } // build geometry + } + // build geometry this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); } } - } - function isUniqueEdge(start, end, edges) { const hash1 = `${start.x},${start.y},${start.z}-${end.x},${end.y},${end.z}`; const hash2 = `${end.x},${end.y},${end.z}-${start.x},${start.y},${start.z}`; // coincident edge @@ -26508,44 +24142,25 @@ var Geometries = /*#__PURE__*/Object.freeze({ __proto__: null, BoxGeometry: BoxGeometry, - BoxBufferGeometry: BoxGeometry, CapsuleGeometry: CapsuleGeometry, - CapsuleBufferGeometry: CapsuleGeometry, CircleGeometry: CircleGeometry, - CircleBufferGeometry: CircleGeometry, ConeGeometry: ConeGeometry, - ConeBufferGeometry: ConeGeometry, CylinderGeometry: CylinderGeometry, - CylinderBufferGeometry: CylinderGeometry, DodecahedronGeometry: DodecahedronGeometry, - DodecahedronBufferGeometry: DodecahedronGeometry, EdgesGeometry: EdgesGeometry, ExtrudeGeometry: ExtrudeGeometry, - ExtrudeBufferGeometry: ExtrudeGeometry, IcosahedronGeometry: IcosahedronGeometry, - IcosahedronBufferGeometry: IcosahedronGeometry, LatheGeometry: LatheGeometry, - LatheBufferGeometry: LatheGeometry, OctahedronGeometry: OctahedronGeometry, - OctahedronBufferGeometry: OctahedronGeometry, PlaneGeometry: PlaneGeometry, - PlaneBufferGeometry: PlaneGeometry, PolyhedronGeometry: PolyhedronGeometry, - PolyhedronBufferGeometry: PolyhedronGeometry, RingGeometry: RingGeometry, - RingBufferGeometry: RingGeometry, ShapeGeometry: ShapeGeometry, - ShapeBufferGeometry: ShapeGeometry, SphereGeometry: SphereGeometry, - SphereBufferGeometry: SphereGeometry, TetrahedronGeometry: TetrahedronGeometry, - TetrahedronBufferGeometry: TetrahedronGeometry, TorusGeometry: TorusGeometry, - TorusBufferGeometry: TorusGeometry, TorusKnotGeometry: TorusKnotGeometry, - TorusKnotBufferGeometry: TorusKnotGeometry, TubeGeometry: TubeGeometry, - TubeBufferGeometry: TubeGeometry, WireframeGeometry: WireframeGeometry }); @@ -26559,14 +24174,12 @@ this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.color.copy(source.color); this.fog = source.fog; return this; } - } class RawShaderMaterial extends ShaderMaterial { @@ -26575,7 +24188,6 @@ this.isRawShaderMaterial = true; this.type = 'RawShaderMaterial'; } - } class MeshStandardMaterial extends Material { @@ -26587,7 +24199,6 @@ }; this.type = 'MeshStandardMaterial'; this.color = new Color(0xffffff); // diffuse - this.roughness = 1.0; this.metalness = 0.0; this.map = null; @@ -26619,7 +24230,6 @@ this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.defines = { @@ -26657,7 +24267,6 @@ this.fog = source.fog; return this; } - } class MeshPhysicalMaterial extends MeshStandardMaterial { @@ -26694,7 +24303,7 @@ this.transmissionMap = null; this.thickness = 0; this.thicknessMap = null; - this.attenuationDistance = 0.0; + this.attenuationDistance = Infinity; this.attenuationColor = new Color(1, 1, 1); this.specularIntensity = 1.0; this.specularIntensityMap = null; @@ -26706,55 +24315,42 @@ this._transmission = 0; this.setValues(parameters); } - get sheen() { return this._sheen; } - set sheen(value) { if (this._sheen > 0 !== value > 0) { this.version++; } - this._sheen = value; } - get clearcoat() { return this._clearcoat; } - set clearcoat(value) { if (this._clearcoat > 0 !== value > 0) { this.version++; } - this._clearcoat = value; } - get iridescence() { return this._iridescence; } - set iridescence(value) { if (this._iridescence > 0 !== value > 0) { this.version++; } - this._iridescence = value; } - get transmission() { return this._transmission; } - set transmission(value) { if (this._transmission > 0 !== value > 0) { this.version++; } - this._transmission = value; } - copy(source) { super.copy(source); this.defines = { @@ -26790,7 +24386,6 @@ this.specularColorMap = source.specularColorMap; return this; } - } class MeshPhongMaterial extends Material { @@ -26799,7 +24394,6 @@ this.isMeshPhongMaterial = true; this.type = 'MeshPhongMaterial'; this.color = new Color(0xffffff); // diffuse - this.specular = new Color(0x111111); this.shininess = 30; this.map = null; @@ -26832,7 +24426,6 @@ this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.color.copy(source.color); @@ -26868,7 +24461,6 @@ this.fog = source.fog; return this; } - } class MeshToonMaterial extends Material { @@ -26905,7 +24497,6 @@ this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.color.copy(source.color); @@ -26934,7 +24525,6 @@ this.fog = source.fog; return this; } - } class MeshNormalMaterial extends Material { @@ -26955,7 +24545,6 @@ this.flatShading = false; this.setValues(parameters); } - copy(source) { super.copy(source); this.bumpMap = source.bumpMap; @@ -26971,7 +24560,6 @@ this.flatShading = source.flatShading; return this; } - } class MeshLambertMaterial extends Material { @@ -26989,6 +24577,14 @@ 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; @@ -26999,10 +24595,10 @@ this.wireframeLinewidth = 1; this.wireframeLinecap = 'round'; this.wireframeLinejoin = 'round'; + this.flatShading = false; this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.color.copy(source.color); @@ -27014,6 +24610,14 @@ 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; @@ -27024,10 +24628,10 @@ this.wireframeLinewidth = source.wireframeLinewidth; this.wireframeLinecap = source.wireframeLinecap; this.wireframeLinejoin = source.wireframeLinejoin; + this.flatShading = source.flatShading; this.fog = source.fog; return this; } - } class MeshMatcapMaterial extends Material { @@ -27055,7 +24659,6 @@ this.fog = true; this.setValues(parameters); } - copy(source) { super.copy(source); this.defines = { @@ -27077,7 +24680,6 @@ this.fog = source.fog; return this; } - } class LineDashedMaterial extends LineBasicMaterial { @@ -27090,7 +24692,6 @@ this.gapSize = 1; this.setValues(parameters); } - copy(source) { super.copy(source); this.scale = source.scale; @@ -27098,24 +24699,23 @@ this.gapSize = source.gapSize; return this; } - } + // same as Array.prototype.slice, but also works on typed arrays function arraySlice(array, from, to) { if (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 - + } + // converts an array to a specific type function convertArray(array, type, forceClone) { - if (!array || // let 'undefined' and 'null' pass + if (!array || + // let 'undefined' and 'null' pass !forceClone && array.constructor === type) return array; - if (typeof type.BYTES_PER_ELEMENT === 'number') { return new type(array); // create typed array } @@ -27125,48 +24725,40 @@ function isTypedArray(object) { return ArrayBuffer.isView(object) && !(object instanceof DataView); - } // returns an array by which times and values can be sorted - + } + // returns an array by which times and values can be sorted function getKeyframeOrder(times) { function compareTime(i, j) { return times[i] - times[j]; } - const n = times.length; const result = new Array(n); - for (let i = 0; i !== n; ++i) result[i] = i; - result.sort(compareTime); return result; - } // uses the array previously returned by 'getKeyframeOrder' to sort data - + } + // uses the array previously returned by 'getKeyframeOrder' to sort data function sortedArray(values, stride, order) { const nValues = values.length; const result = new values.constructor(nValues); - for (let i = 0, dstOffset = 0; dstOffset !== nValues; ++i) { const srcOffset = order[i] * stride; - for (let j = 0; j !== stride; ++j) { result[dstOffset++] = values[srcOffset + j]; } } - return result; - } // function for parsing AOS keyframe formats - + } + // function for parsing AOS keyframe formats function flattenJSON(jsonKeys, times, values, valuePropertyName) { let i = 1, - key = jsonKeys[0]; - + key = jsonKeys[0]; while (key !== undefined && key[valuePropertyName] === undefined) { key = jsonKeys[i++]; } - if (key === undefined) return; // no data let value = key[valuePropertyName]; @@ -27175,7 +24767,6 @@ if (Array.isArray(value)) { do { value = key[valuePropertyName]; - if (value !== undefined) { times.push(key.time); values.push.apply(values, value); // push all elements @@ -27185,109 +24776,101 @@ } while (key !== undefined); } else if (value.toArray !== undefined) { // ...assume THREE.Math-ish + do { value = key[valuePropertyName]; - if (value !== undefined) { times.push(key.time); value.toArray(values, values.length); } - key = jsonKeys[i++]; } while (key !== undefined); } else { // otherwise push as-is + do { value = key[valuePropertyName]; - if (value !== undefined) { times.push(key.time); values.push(value); } - key = jsonKeys[i++]; } while (key !== undefined); } } - function subclip(sourceClip, name, startFrame, endFrame, fps = 30) { const clip = sourceClip.clone(); clip.name = name; const tracks = []; - for (let i = 0; i < clip.tracks.length; ++i) { const track = clip.tracks[i]; const valueSize = track.getValueSize(); const times = []; const values = []; - for (let j = 0; j < track.times.length; ++j) { const frame = track.times[j] * fps; if (frame < startFrame || frame >= endFrame) continue; times.push(track.times[j]); - for (let k = 0; k < valueSize; ++k) { values.push(track.values[j * valueSize + k]); } } - if (times.length === 0) continue; track.times = convertArray(times, track.times.constructor); track.values = convertArray(values, track.values.constructor); tracks.push(track); } + clip.tracks = tracks; - clip.tracks = tracks; // find minimum .times value across all tracks in the trimmed clip + // find minimum .times value across all tracks in the trimmed clip let minStartTime = Infinity; - for (let 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 + } + // shift all tracks such that clip begins at t=0 for (let i = 0; i < clip.tracks.length; ++i) { clip.tracks[i].shift(-1 * minStartTime); } - clip.resetDuration(); return clip; } - function makeClipAdditive(targetClip, referenceFrame = 0, referenceClip = targetClip, fps = 30) { if (fps <= 0) fps = 30; const numTracks = referenceClip.tracks.length; - const referenceTime = referenceFrame / fps; // Make each track's values relative to the values at the reference frame + const referenceTime = referenceFrame / fps; + // Make each track's values relative to the values at the reference frame for (let i = 0; i < numTracks; ++i) { const referenceTrack = referenceClip.tracks[i]; - const referenceTrackType = referenceTrack.ValueTypeName; // Skip this track if it's non-numeric + const referenceTrackType = referenceTrack.ValueTypeName; - if (referenceTrackType === 'bool' || referenceTrackType === 'string') continue; // Find the track in the target clip whose name and type matches the reference track + // Skip this track if it's non-numeric + if (referenceTrackType === 'bool' || referenceTrackType === 'string') continue; + // Find the track in the target clip whose name and type matches the reference track const targetTrack = targetClip.tracks.find(function (track) { return track.name === referenceTrack.name && track.ValueTypeName === referenceTrackType; }); if (targetTrack === undefined) continue; let referenceOffset = 0; const referenceValueSize = referenceTrack.getValueSize(); - if (referenceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) { referenceOffset = referenceValueSize / 3; } - let targetOffset = 0; const targetValueSize = targetTrack.getValueSize(); - if (targetTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) { targetOffset = targetValueSize / 3; } - const lastIndex = referenceTrack.times.length - 1; - let referenceValue; // Find the value to subtract out of the track + let referenceValue; + // Find the value to subtract out of the track if (referenceTime <= referenceTrack.times[0]) { // Reference frame is earlier than the first keyframe, so just use the first keyframe const startIndex = referenceOffset; @@ -27305,33 +24888,32 @@ const endIndex = referenceValueSize - referenceOffset; interpolant.evaluate(referenceTime); referenceValue = arraySlice(interpolant.resultBuffer, startIndex, endIndex); - } // Conjugate the quaternion - + } + // Conjugate the quaternion if (referenceTrackType === 'quaternion') { const referenceQuat = new Quaternion().fromArray(referenceValue).normalize().conjugate(); referenceQuat.toArray(referenceValue); - } // Subtract the reference value from all of the track values + } + // Subtract the reference value from all of the track values const numTimes = targetTrack.times.length; - for (let j = 0; j < numTimes; ++j) { const valueStart = j * targetValueSize + targetOffset; - if (referenceTrackType === 'quaternion') { // Multiply the conjugate for quaternion track types Quaternion.multiplyQuaternionsFlat(targetTrack.values, valueStart, referenceValue, 0, targetTrack.values, valueStart); } else { - const valueEnd = targetValueSize - targetOffset * 2; // Subtract each value for all other numeric track types + const valueEnd = targetValueSize - targetOffset * 2; + // Subtract each value for all other numeric track types for (let k = 0; k < valueEnd; ++k) { targetTrack.values[valueStart + k] -= referenceValue[k]; } } } } - targetClip.blendMode = AdditiveAnimationBlendMode; return targetClip; } @@ -27368,6 +24950,7 @@ * http://www.oodesign.com/template-method-pattern.html * */ + class Interpolant { constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { this.parameterPositions = parameterPositions; @@ -27378,17 +24961,14 @@ this.settings = null; this.DefaultSettings_ = {}; } - evaluate(t) { const pp = this.parameterPositions; let i1 = this._cachedIndex, - t1 = pp[i1], - t0 = pp[i1 - 1]; - + t1 = pp[i1], + t0 = pp[i1 - 1]; validate_interval: { seek: { let right; - linear_scan: { //- See http://jsperf.com/comparison-to-undefined/3 //- slower code: @@ -27397,90 +24977,89 @@ forward_scan: if (!(t < t1)) { for (let giveUpAt = i1 + 2;;) { if (t1 === undefined) { - if (t < t0) break forward_scan; // after end + if (t < t0) break forward_scan; + + // after end i1 = pp.length; this._cachedIndex = i1; return this.copySampleValue_(i1 - 1); } - if (i1 === giveUpAt) break; // this loop t0 = t1; t1 = pp[++i1]; - if (t < t1) { // we have arrived at the sought interval break seek; } - } // prepare binary search on the right side of the index - + } + // prepare binary search on the right side of the index right = pp.length; break linear_scan; - } //- slower code: - //- if ( t < t0 || t0 === undefined ) { - + } + //- slower code: + //- if ( t < t0 || t0 === undefined ) { if (!(t >= t0)) { // looping? - const t1global = pp[1]; + const t1global = pp[1]; if (t < t1global) { i1 = 2; // + 1, using the scan for the details - t0 = t1global; - } // linear reverse scan + } + // linear reverse scan for (let giveUpAt = i1 - 2;;) { if (t0 === undefined) { // before start + this._cachedIndex = 0; return this.copySampleValue_(0); } - if (i1 === giveUpAt) break; // this loop t1 = t0; t0 = pp[--i1 - 1]; - if (t >= t0) { // we have arrived at the sought interval break seek; } - } // prepare binary search on the left side of the index - + } + // prepare binary search on the left side of the index right = i1; i1 = 0; break linear_scan; - } // the interval is valid + } + // the interval is valid break validate_interval; } // linear scan - // binary search + // binary search while (i1 < right) { const mid = i1 + right >>> 1; - if (t < pp[mid]) { right = mid; } else { i1 = mid + 1; } } - t1 = pp[i1]; - t0 = pp[i1 - 1]; // check boundary cases, again + t0 = pp[i1 - 1]; + + // check boundary cases, again if (t0 === undefined) { this._cachedIndex = 0; return this.copySampleValue_(0); } - if (t1 === undefined) { i1 = pp.length; this._cachedIndex = i1; @@ -27488,41 +25067,39 @@ } } // seek - this._cachedIndex = i1; this.intervalChanged_(i1, t0, t1); } // validate_interval - return this.interpolate_(i1, t0, t, t1); } - getSettings_() { return this.settings || this.DefaultSettings_; } - copySampleValue_(index) { // copies a sample value to the result buffer - const result = this.resultBuffer, - values = this.sampleValues, - stride = this.valueSize, - offset = index * stride; + const result = this.resultBuffer, + values = this.sampleValues, + stride = this.valueSize, + offset = index * stride; for (let i = 0; i !== stride; ++i) { result[i] = values[offset + i]; } - return result; - } // Template methods for derived classes: + } + // Template methods for derived classes: interpolate_() { - throw new Error('call to abstract method'); // implementations shall return this.resultBuffer + throw new Error('call to abstract method'); + // implementations shall return this.resultBuffer } - intervalChanged_() {// empty - } + intervalChanged_() { + // empty + } } /** @@ -27545,14 +25122,12 @@ endingEnd: ZeroCurvatureEnding }; } - intervalChanged_(i1, t0, t1) { const pp = this.parameterPositions; let iPrev = i1 - 2, - iNext = i1 + 1, - tPrev = pp[iPrev], - tNext = pp[iNext]; - + iNext = i1 + 1, + tPrev = pp[iPrev], + tNext = pp[iNext]; if (tPrev === undefined) { switch (this.getSettings_().endingStart) { case ZeroSlopeEnding: @@ -27560,21 +25135,19 @@ iPrev = i1; tPrev = 2 * t0 - t1; break; - case WrapAroundEnding: // use the other end of the curve iPrev = pp.length - 2; tPrev = t0 + pp[iPrev] - pp[iPrev + 1]; break; - default: // ZeroCurvatureEnding + // f''(t0) = 0 a.k.a. Natural Spline iPrev = i1; tPrev = t1; } } - if (tNext === undefined) { switch (this.getSettings_().endingEnd) { case ZeroSlopeEnding: @@ -27582,78 +25155,73 @@ 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; - default: // ZeroCurvatureEnding + // f''(tN) = 0, a.k.a. Natural Spline iNext = i1 - 1; tNext = t0; } } - const halfDt = (t1 - t0) * 0.5, - stride = this.valueSize; + stride = this.valueSize; this._weightPrev = halfDt / (t0 - tPrev); this._weightNext = halfDt / (tNext - t1); this._offsetPrev = iPrev * stride; this._offsetNext = iNext * stride; } - interpolate_(i1, t0, t, t1) { const 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 + 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 const sP = -wP * ppp + 2 * wP * pp - wP * p; const s0 = (1 + wP) * ppp + (-1.5 - 2 * wP) * pp + (-0.5 + wP) * p + 1; const s1 = (-1 - wN) * ppp + (1.5 + wN) * pp + 0.5 * p; - const sN = wN * ppp - wN * pp; // combine data linearly + const sN = wN * ppp - wN * pp; + + // combine data linearly for (let i = 0; i !== stride; ++i) { result[i] = sP * values[oP + i] + s0 * values[o0 + i] + s1 * values[o1 + i] + sN * values[oN + i]; } - return result; } - } class LinearInterpolant extends Interpolant { constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { super(parameterPositions, sampleValues, sampleSize, resultBuffer); } - interpolate_(i1, t0, t, t1) { const result = this.resultBuffer, - values = this.sampleValues, - stride = this.valueSize, - offset1 = i1 * stride, - offset0 = offset1 - stride, - weight1 = (t - t0) / (t1 - t0), - weight0 = 1 - weight1; - + values = this.sampleValues, + stride = this.valueSize, + offset1 = i1 * stride, + offset0 = offset1 - stride, + weight1 = (t - t0) / (t1 - t0), + weight0 = 1 - weight1; for (let i = 0; i !== stride; ++i) { result[i] = values[offset0 + i] * weight0 + values[offset1 + i] * weight1; } - return result; } - } /** @@ -27666,13 +25234,9 @@ constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { super(parameterPositions, sampleValues, sampleSize, resultBuffer); } - - interpolate_(i1 - /*, t0, t, t1 */ - ) { + interpolate_(i1 /*, t0, t, t1 */) { return this.copySampleValue_(i1 - 1); } - } class KeyframeTrack { @@ -27683,14 +25247,16 @@ this.times = convertArray(times, this.TimeBufferType); this.values = convertArray(values, this.ValueBufferType); this.setInterpolation(interpolation || this.DefaultInterpolation); - } // Serialization (in static context, because of constructor invocation - // and automatic invocation of .toJSON): + } + // Serialization (in static context, because of constructor invocation + // and automatic invocation of .toJSON): static toJSON(track) { const trackType = track.constructor; - let json; // derived classes can define a static toJSON method + let json; + // derived classes can define a static toJSON method if (trackType.toJSON !== this.toJSON) { json = trackType.toJSON(track); } else { @@ -27701,49 +25267,38 @@ 'values': convertArray(track.values, Array) }; const interpolation = track.getInterpolation(); - if (interpolation !== track.DefaultInterpolation) { json.interpolation = interpolation; } } - json.type = track.ValueTypeName; // mandatory return json; } - InterpolantFactoryMethodDiscrete(result) { return new DiscreteInterpolant(this.times, this.values, this.getValueSize(), result); } - InterpolantFactoryMethodLinear(result) { return new LinearInterpolant(this.times, this.values, this.getValueSize(), result); } - InterpolantFactoryMethodSmooth(result) { return new CubicInterpolant(this.times, this.values, this.getValueSize(), result); } - setInterpolation(interpolation) { let factoryMethod; - switch (interpolation) { case InterpolateDiscrete: factoryMethod = this.InterpolantFactoryMethodDiscrete; break; - case InterpolateLinear: factoryMethod = this.InterpolantFactoryMethodLinear; break; - case InterpolateSmooth: factoryMethod = this.InterpolantFactoryMethodSmooth; break; } - if (factoryMethod === undefined) { const message = 'unsupported interpolation for ' + this.ValueTypeName + ' keyframe track named ' + this.name; - if (this.createInterpolant === undefined) { // fall back to default, unless the default itself is messed up if (interpolation !== this.DefaultInterpolation) { @@ -27756,70 +25311,58 @@ console.warn('THREE.KeyframeTrack:', message); return this; } - this.createInterpolant = factoryMethod; return this; } - getInterpolation() { switch (this.createInterpolant) { case this.InterpolantFactoryMethodDiscrete: return InterpolateDiscrete; - case this.InterpolantFactoryMethodLinear: return InterpolateLinear; - case this.InterpolantFactoryMethodSmooth: return InterpolateSmooth; } } - getValueSize() { return this.values.length / this.times.length; - } // move all keyframes either forwards or backwards in time - + } + // move all keyframes either forwards or backwards in time shift(timeOffset) { if (timeOffset !== 0.0) { const times = this.times; - for (let i = 0, n = times.length; i !== n; ++i) { times[i] += timeOffset; } } - return this; - } // scale all keyframe times by a factor (useful for frame <-> seconds conversions) - + } + // scale all keyframe times by a factor (useful for frame <-> seconds conversions) scale(timeScale) { if (timeScale !== 1.0) { const times = this.times; - for (let 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 - + } + // 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(startTime, endTime) { const times = this.times, - nKeys = times.length; + nKeys = times.length; let from = 0, - to = nKeys - 1; - + to = nKeys - 1; while (from !== nKeys && times[from] < startTime) { ++from; } - while (to !== -1 && times[to] > endTime) { --to; } - ++to; // inclusive -> exclusive bound if (from !== 0 || to !== nKeys) { @@ -27828,59 +25371,47 @@ to = Math.max(to, 1); from = to - 1; } - const stride = this.getValueSize(); this.times = arraySlice(times, from, to); this.values = arraySlice(this.values, from * stride, to * stride); } - return this; - } // ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable - + } + // ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable validate() { let valid = true; const valueSize = this.getValueSize(); - if (valueSize - Math.floor(valueSize) !== 0) { console.error('THREE.KeyframeTrack: Invalid value size in track.', this); valid = false; } - const times = this.times, - values = this.values, - nKeys = times.length; - + values = this.values, + nKeys = times.length; if (nKeys === 0) { console.error('THREE.KeyframeTrack: Track is empty.', this); valid = false; } - let prevTime = null; - for (let i = 0; i !== nKeys; i++) { const currTime = times[i]; - 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; } - prevTime = currTime; } - if (values !== undefined) { if (isTypedArray(values)) { for (let i = 0, n = values.length; i !== n; ++i) { const value = values[i]; - if (isNaN(value)) { console.error('THREE.KeyframeTrack: Value is not a valid number.', this, i, value); valid = false; @@ -27889,36 +25420,35 @@ } } } - 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) - + } + // 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() { // times or values may be shared with other tracks, so overwriting is unsafe const times = arraySlice(this.times), - values = arraySlice(this.values), - stride = this.getValueSize(), - smoothInterpolation = this.getInterpolation() === InterpolateSmooth, - lastIndex = times.length - 1; + values = arraySlice(this.values), + stride = this.getValueSize(), + smoothInterpolation = this.getInterpolation() === InterpolateSmooth, + lastIndex = times.length - 1; let writeIndex = 1; - for (let i = 1; i < lastIndex; ++i) { let keep = false; const time = times[i]; - const timeNext = times[i + 1]; // remove adjacent keyframes scheduled at the same time + const timeNext = times[i + 1]; + + // remove adjacent keyframes scheduled at the same time if (time !== timeNext && (i !== 1 || time !== times[0])) { if (!smoothInterpolation) { // remove unnecessary keyframes same as their neighbors - const offset = i * stride, - offsetP = offset - stride, - offsetN = offset + stride; + const offset = i * stride, + offsetP = offset - stride, + offsetN = offset + stride; for (let j = 0; j !== stride; ++j) { const value = values[offset + j]; - if (value !== values[offsetP + j] || value !== values[offsetN + j]) { keep = true; break; @@ -27927,35 +25457,32 @@ } else { keep = true; } - } // in-place compaction + } + // in-place compaction if (keep) { if (i !== writeIndex) { times[writeIndex] = times[i]; const readOffset = i * stride, - writeOffset = writeIndex * stride; - + writeOffset = writeIndex * stride; for (let j = 0; j !== stride; ++j) { values[writeOffset + j] = values[readOffset + j]; } } - ++writeIndex; } - } // flush last keyframe (compaction looks ahead) + } + // flush last keyframe (compaction looks ahead) if (lastIndex > 0) { times[writeIndex] = times[lastIndex]; - for (let readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++j) { values[writeOffset + j] = values[readOffset + j]; } - ++writeIndex; } - if (writeIndex !== times.length) { this.times = arraySlice(times, 0, writeIndex); this.values = arraySlice(values, 0, writeIndex * stride); @@ -27963,22 +25490,19 @@ this.times = times; this.values = values; } - return this; } - clone() { const times = arraySlice(this.times, 0); const values = arraySlice(this.values, 0); const TypedKeyframeTrack = this.constructor; - const track = new TypedKeyframeTrack(this.name, times, values); // Interpolant argument to constructor is not saved, so copy the factory method directly. + const track = new TypedKeyframeTrack(this.name, times, values); + // Interpolant argument to constructor is not saved, so copy the factory method directly. track.createInterpolant = this.createInterpolant; return track; } - } - KeyframeTrack.prototype.TimeBufferType = Float32Array; KeyframeTrack.prototype.ValueBufferType = Float32Array; KeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear; @@ -27986,30 +25510,24 @@ /** * A Track of Boolean keyframe values. */ - class BooleanKeyframeTrack extends KeyframeTrack {} - BooleanKeyframeTrack.prototype.ValueTypeName = 'bool'; BooleanKeyframeTrack.prototype.ValueBufferType = Array; BooleanKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete; BooleanKeyframeTrack.prototype.InterpolantFactoryMethodLinear = undefined; - BooleanKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined; // Note: Actually this track could have a optimized / compressed + BooleanKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined; /** * A Track of keyframe values that represent color. */ - class ColorKeyframeTrack extends KeyframeTrack {} - - ColorKeyframeTrack.prototype.ValueTypeName = 'color'; // ValueBufferType is inherited + ColorKeyframeTrack.prototype.ValueTypeName = 'color'; /** * A Track of numeric keyframe values. */ - class NumberKeyframeTrack extends KeyframeTrack {} - - NumberKeyframeTrack.prototype.ValueTypeName = 'number'; // ValueBufferType is inherited + NumberKeyframeTrack.prototype.ValueTypeName = 'number'; /** * Spherical linear unit quaternion interpolant. @@ -28019,45 +25537,36 @@ constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { super(parameterPositions, sampleValues, sampleSize, resultBuffer); } - interpolate_(i1, t0, t, t1) { const result = this.resultBuffer, - values = this.sampleValues, - stride = this.valueSize, - alpha = (t - t0) / (t1 - t0); + values = this.sampleValues, + stride = this.valueSize, + alpha = (t - t0) / (t1 - t0); let offset = i1 * stride; - for (let end = offset + stride; offset !== end; offset += 4) { Quaternion.slerpFlat(result, 0, values, offset - stride, values, offset, alpha); } - return result; } - } /** * A Track of quaternion keyframe values. */ - class QuaternionKeyframeTrack extends KeyframeTrack { InterpolantFactoryMethodLinear(result) { return new QuaternionLinearInterpolant(this.times, this.values, this.getValueSize(), result); } - } - - QuaternionKeyframeTrack.prototype.ValueTypeName = 'quaternion'; // ValueBufferType is inherited - + QuaternionKeyframeTrack.prototype.ValueTypeName = 'quaternion'; + // ValueBufferType is inherited QuaternionKeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear; QuaternionKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined; /** * A Track that interpolates Strings */ - class StringKeyframeTrack extends KeyframeTrack {} - StringKeyframeTrack.prototype.ValueTypeName = 'string'; StringKeyframeTrack.prototype.ValueBufferType = Array; StringKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete; @@ -28067,10 +25576,8 @@ /** * A Track of vectored keyframe values. */ - class VectorKeyframeTrack extends KeyframeTrack {} - - VectorKeyframeTrack.prototype.ValueTypeName = 'vector'; // ValueBufferType is inherited + VectorKeyframeTrack.prototype.ValueTypeName = 'vector'; class AnimationClip { constructor(name, duration = -1, tracks, blendMode = NormalAnimationBlendMode) { @@ -28078,30 +25585,27 @@ this.tracks = tracks; this.duration = duration; this.blendMode = blendMode; - this.uuid = generateUUID(); // this means it should figure out its duration by scanning the tracks + this.uuid = generateUUID(); + // this means it should figure out its duration by scanning the tracks if (this.duration < 0) { this.resetDuration(); } } - static parse(json) { const tracks = [], - jsonTracks = json.tracks, - frameTime = 1.0 / (json.fps || 1.0); - + jsonTracks = json.tracks, + frameTime = 1.0 / (json.fps || 1.0); for (let i = 0, n = jsonTracks.length; i !== n; ++i) { tracks.push(parseKeyframeTrack(jsonTracks[i]).scale(frameTime)); } - const clip = new this(json.name, json.duration, tracks, json.blendMode); clip.uuid = json.uuid; return clip; } - static toJSON(clip) { const tracks = [], - clipTracks = clip.tracks; + clipTracks = clip.tracks; const json = { 'name': clip.name, 'duration': clip.duration, @@ -28109,18 +25613,14 @@ 'uuid': clip.uuid, 'blendMode': clip.blendMode }; - for (let i = 0, n = clipTracks.length; i !== n; ++i) { tracks.push(KeyframeTrack.toJSON(clipTracks[i])); } - return json; } - static CreateFromMorphTargetSequence(name, morphTargetSequence, fps, noLoop) { const numMorphTargets = morphTargetSequence.length; const tracks = []; - for (let i = 0; i < numMorphTargets; i++) { let times = []; let values = []; @@ -28128,204 +25628,174 @@ values.push(0, 1, 0); const order = getKeyframeOrder(times); times = sortedArray(times, 1, order); - values = sortedArray(values, 1, order); // if there is a key at the first frame, duplicate it as the - // last frame as well for perfect loop. + values = 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]); } - tracks.push(new NumberKeyframeTrack('.morphTargetInfluences[' + morphTargetSequence[i].name + ']', times, values).scale(1.0 / fps)); } - return new this(name, -1, tracks); } - static findByName(objectOrClipArray, name) { let clipArray = objectOrClipArray; - if (!Array.isArray(objectOrClipArray)) { const o = objectOrClipArray; clipArray = o.geometry && o.geometry.animations || o.animations; } - for (let i = 0; i < clipArray.length; i++) { if (clipArray[i].name === name) { return clipArray[i]; } } - return null; } - static CreateClipsFromMorphTargetSequences(morphTargets, fps, noLoop) { - const animationToMorphTargets = {}; // tested with https://regex101.com/ on trick sequences + const animationToMorphTargets = {}; + + // tested with https://regex101.com/ on trick sequences // such flamingo_flyA_003, flamingo_run1_003, crdeath0059 + const pattern = /^([\w-]*?)([\d]+)$/; - const pattern = /^([\w-]*?)([\d]+)$/; // sort morph target names into animation groups based + // sort morph target names into animation groups based // patterns like Walk_001, Walk_002, Run_001, Run_002 - for (let i = 0, il = morphTargets.length; i < il; i++) { const morphTarget = morphTargets[i]; const parts = morphTarget.name.match(pattern); - if (parts && parts.length > 1) { const name = parts[1]; let animationMorphTargets = animationToMorphTargets[name]; - if (!animationMorphTargets) { animationToMorphTargets[name] = animationMorphTargets = []; } - animationMorphTargets.push(morphTarget); } } - const clips = []; - for (const name in animationToMorphTargets) { clips.push(this.CreateFromMorphTargetSequence(name, animationToMorphTargets[name], fps, noLoop)); } - return clips; - } // parse the animation.hierarchy format - + } + // parse the animation.hierarchy format static parseAnimation(animation, bones) { if (!animation) { console.error('THREE.AnimationClip: No animation in JSONLoader data.'); return null; } - const addNonemptyTrack = function (trackType, trackName, animationKeys, propertyName, destTracks) { // only return track if there are actually keys. if (animationKeys.length !== 0) { const times = []; const values = []; - flattenJSON(animationKeys, times, values, propertyName); // empty keys are filtered out, so check again + flattenJSON(animationKeys, times, values, propertyName); + // empty keys are filtered out, so check again if (times.length !== 0) { destTracks.push(new trackType(trackName, times, values)); } } }; - const tracks = []; const clipName = animation.name || 'default'; const fps = animation.fps || 30; - const blendMode = animation.blendMode; // automatic length determination in AnimationClip. + const blendMode = animation.blendMode; + // automatic length determination in AnimationClip. let duration = animation.length || -1; const hierarchyTracks = animation.hierarchy || []; - for (let h = 0; h < hierarchyTracks.length; h++) { - const animationKeys = hierarchyTracks[h].keys; // skip empty tracks + const animationKeys = hierarchyTracks[h].keys; - if (!animationKeys || animationKeys.length === 0) continue; // process morph targets + // skip empty tracks + if (!animationKeys || animationKeys.length === 0) continue; + // process morph targets if (animationKeys[0].morphTargets) { // figure out all morph targets used in this track const morphTargetNames = {}; let k; - for (k = 0; k < animationKeys.length; k++) { if (animationKeys[k].morphTargets) { for (let m = 0; m < animationKeys[k].morphTargets.length; m++) { morphTargetNames[animationKeys[k].morphTargets[m]] = -1; } } - } // create a track for each morph target with all zero + } + + // create a track for each morph target with all zero // morphTargetInfluences except for the keys in which // the morphTarget is named. - - for (const morphTargetName in morphTargetNames) { const times = []; const values = []; - for (let m = 0; m !== animationKeys[k].morphTargets.length; ++m) { const animationKey = animationKeys[k]; times.push(animationKey.time); values.push(animationKey.morphTarget === morphTargetName ? 1 : 0); } - tracks.push(new NumberKeyframeTrack('.morphTargetInfluence[' + morphTargetName + ']', times, values)); } - duration = morphTargetNames.length * fps; } else { // ...assume skeletal animation + const 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); } } - if (tracks.length === 0) { return null; } - const clip = new this(clipName, duration, tracks, blendMode); return clip; } - resetDuration() { const tracks = this.tracks; let duration = 0; - for (let i = 0, n = tracks.length; i !== n; ++i) { const track = this.tracks[i]; duration = Math.max(duration, track.times[track.times.length - 1]); } - this.duration = duration; return this; } - trim() { for (let i = 0; i < this.tracks.length; i++) { this.tracks[i].trim(0, this.duration); } - return this; } - validate() { let valid = true; - for (let i = 0; i < this.tracks.length; i++) { valid = valid && this.tracks[i].validate(); } - return valid; } - optimize() { for (let i = 0; i < this.tracks.length; i++) { this.tracks[i].optimize(); } - return this; } - clone() { const tracks = []; - for (let i = 0; i < this.tracks.length; i++) { tracks.push(this.tracks[i].clone()); } - return new this.constructor(this.name, this.duration, tracks, this.blendMode); } - toJSON() { return this.constructor.toJSON(this); } - } - function getTrackTypeForValueTypeName(typeName) { switch (typeName.toLowerCase()) { case 'scalar': @@ -28334,46 +25804,37 @@ case 'number': case 'integer': return NumberKeyframeTrack; - case 'vector': case 'vector2': case 'vector3': case 'vector4': return VectorKeyframeTrack; - case 'color': return ColorKeyframeTrack; - case 'quaternion': return QuaternionKeyframeTrack; - case 'bool': case 'boolean': return BooleanKeyframeTrack; - case 'string': return StringKeyframeTrack; } - throw new Error('THREE.KeyframeTrack: Unsupported typeName: ' + typeName); } - function parseKeyframeTrack(json) { if (json.type === undefined) { throw new Error('THREE.KeyframeTrack: track type undefined, can not parse'); } - const trackType = getTrackTypeForValueTypeName(json.type); - if (json.times === undefined) { const times = [], - values = []; + values = []; flattenJSON(json.keys, times, values, 'value'); json.times = times; json.values = values; - } // derived classes can define a static parse method - + } + // derived classes can define a static parse method if (trackType.parse !== undefined) { return trackType.parse(json); } else { @@ -28386,12 +25847,16 @@ enabled: false, files: {}, add: function (key, file) { - if (this.enabled === false) return; // console.log( 'THREE.Cache', 'Adding key:', key ); + if (this.enabled === false) return; + + // console.log( 'THREE.Cache', 'Adding key:', key ); this.files[key] = file; }, get: function (key) { - if (this.enabled === false) return; // console.log( 'THREE.Cache', 'Checking key:', key ); + if (this.enabled === false) return; + + // console.log( 'THREE.Cache', 'Checking key:', key ); return this.files[key]; }, @@ -28410,76 +25875,62 @@ let itemsLoaded = 0; let itemsTotal = 0; let urlModifier = undefined; - const handlers = []; // Refer to #5689 for the reason why we don't set .onStart + const 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; }; - this.itemEnd = function (url) { itemsLoaded++; - if (scope.onProgress !== undefined) { scope.onProgress(url, itemsLoaded, itemsTotal); } - if (itemsLoaded === itemsTotal) { isLoading = false; - if (scope.onLoad !== undefined) { scope.onLoad(); } } }; - this.itemError = function (url) { if (scope.onError !== undefined) { scope.onError(url); } }; - this.resolveURL = function (url) { if (urlModifier) { return urlModifier(url); } - return url; }; - this.setURLModifier = function (transform) { urlModifier = transform; return this; }; - this.addHandler = function (regex, loader) { handlers.push(regex, loader); return this; }; - this.removeHandler = function (regex) { const index = handlers.indexOf(regex); - if (index !== -1) { handlers.splice(index, 2); } - return this; }; - this.getHandler = function (file) { for (let i = 0, l = handlers.length; i < l; i += 2) { const regex = handlers[i]; @@ -28490,13 +25941,10 @@ return loader; } } - return null; }; } - } - const DefaultLoadingManager = /*@__PURE__*/new LoadingManager(); class Loader { @@ -28508,66 +25956,52 @@ this.resourcePath = ''; this.requestHeader = {}; } - load() {} - loadAsync(url, onProgress) { const scope = this; return new Promise(function (resolve, reject) { scope.load(url, resolve, onProgress, reject); }); } - parse() {} - setCrossOrigin(crossOrigin) { this.crossOrigin = crossOrigin; return this; } - setWithCredentials(value) { this.withCredentials = value; return this; } - setPath(path) { this.path = path; return this; } - setResourcePath(resourcePath) { this.resourcePath = resourcePath; return this; } - setRequestHeader(requestHeader) { this.requestHeader = requestHeader; return this; } - } const loading = {}; - class HttpError extends Error { constructor(message, response) { super(message); this.response = response; } - } - class FileLoader extends Loader { constructor(manager) { super(manager); } - load(url, onLoad, onProgress, onError) { if (url === undefined) url = ''; if (this.path !== undefined) url = this.path + url; url = this.manager.resolveURL(url); const cached = Cache.get(url); - if (cached !== undefined) { this.manager.itemStart(url); setTimeout(() => { @@ -28575,8 +26009,9 @@ this.manager.itemEnd(url); }, 0); return cached; - } // Check if request is duplicate + } + // Check if request is duplicate if (loading[url] !== undefined) { loading[url].push({ @@ -28585,49 +26020,56 @@ onError: onError }); return; - } // Initialise array for duplicate requests - + } + // Initialise array for duplicate requests loading[url] = []; loading[url].push({ onLoad: onLoad, onProgress: onProgress, onError: onError - }); // create request + }); + // create request const req = new Request(url, { headers: new Headers(this.requestHeader), - credentials: this.withCredentials ? 'include' : 'same-origin' // An abort controller could be added within a future PR - - }); // record states ( avoid data race ) + credentials: this.withCredentials ? 'include' : 'same-origin' + // An abort controller could be added within a future PR + }); + // record states ( avoid data race ) const mimeType = this.mimeType; - const responseType = this.responseType; // start the fetch + const responseType = this.responseType; + // start the fetch fetch(req).then(response => { if (response.status === 200 || response.status === 0) { // Some browsers return HTTP Status 0 when using non-http protocol // e.g. 'file://' or 'data://'. Handle as success. + if (response.status === 0) { console.warn('THREE.FileLoader: HTTP Status 0 received.'); - } // Workaround: Checking if response.body === undefined for Alipay browser #23548 + } + // Workaround: Checking if response.body === undefined for Alipay browser #23548 if (typeof ReadableStream === 'undefined' || response.body === undefined || response.body.getReader === undefined) { return response; } - const callbacks = loading[url]; const reader = response.body.getReader(); - const contentLength = response.headers.get('Content-Length'); + + // Nginx needs X-File-Size check + // https://serverfault.com/questions/482875/why-does-nginx-remove-content-length-header-for-chunked-content + const contentLength = response.headers.get('Content-Length') || response.headers.get('X-File-Size'); const total = contentLength ? parseInt(contentLength) : 0; const lengthComputable = total !== 0; - let loaded = 0; // periodically read data into the new stream tracking while download progress + let loaded = 0; + // periodically read data into the new stream tracking while download progress const stream = new ReadableStream({ start(controller) { readData(); - function readData() { reader.read().then(({ done, @@ -28642,19 +26084,16 @@ loaded, total }); - for (let i = 0, il = callbacks.length; i < il; i++) { const callback = callbacks[i]; if (callback.onProgress) callback.onProgress(event); } - controller.enqueue(value); readData(); } }); } } - }); return new Response(stream); } else { @@ -28664,19 +26103,15 @@ switch (responseType) { case 'arraybuffer': return response.arrayBuffer(); - case 'blob': return response.blob(); - case 'document': return response.text().then(text => { const parser = new DOMParser(); return parser.parseFromString(text, mimeType); }); - case 'json': return response.json(); - default: if (mimeType === undefined) { return response.text(); @@ -28688,7 +26123,6 @@ const decoder = new TextDecoder(label); return response.arrayBuffer().then(ab => decoder.decode(ab)); } - } }).then(data => { // Add to cache only on HTTP success, so that we do not cache @@ -28696,52 +26130,44 @@ Cache.add(url, data); const callbacks = loading[url]; delete loading[url]; - for (let i = 0, il = callbacks.length; i < il; i++) { const callback = callbacks[i]; if (callback.onLoad) callback.onLoad(data); } }).catch(err => { // Abort errors and other errors are handled the same - const callbacks = loading[url]; + const callbacks = loading[url]; if (callbacks === undefined) { // When onLoad was called and url was deleted in `loading` this.manager.itemError(url); throw err; } - delete loading[url]; - for (let i = 0, il = callbacks.length; i < il; i++) { const callback = callbacks[i]; if (callback.onError) callback.onError(err); } - this.manager.itemError(url); }).finally(() => { this.manager.itemEnd(url); }); this.manager.itemStart(url); } - setResponseType(value) { this.responseType = value; return this; } - setMimeType(value) { this.mimeType = value; return this; } - } class AnimationLoader extends Loader { constructor(manager) { super(manager); } - load(url, onLoad, onProgress, onError) { const scope = this; const loader = new FileLoader(this.manager); @@ -28757,23 +26183,18 @@ } else { console.error(e); } - scope.manager.itemError(url); } }, onProgress, onError); } - parse(json) { const animations = []; - for (let i = 0; i < json.length; i++) { const clip = AnimationClip.parse(json[i]); animations.push(clip); } - return animations; } - } /** @@ -28786,7 +26207,6 @@ constructor(manager) { super(manager); } - load(url, onLoad, onProgress, onError) { const scope = this; const images = []; @@ -28797,7 +26217,6 @@ loader.setRequestHeader(this.requestHeader); loader.setWithCredentials(scope.withCredentials); let loaded = 0; - function loadTexture(i) { loader.load(url[i], function (buffer) { const texDatas = scope.parse(buffer, true); @@ -28808,7 +26227,6 @@ mipmaps: texDatas.mipmaps }; loaded += 1; - if (loaded === 6) { if (texDatas.mipmapCount === 1) texture.minFilter = LinearFilter; texture.image = images; @@ -28818,24 +26236,21 @@ } }, onProgress, onError); } - if (Array.isArray(url)) { for (let 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) { const texDatas = scope.parse(buffer, true); - if (texDatas.isCubemap) { const faces = texDatas.mipmaps.length / texDatas.mipmapCount; - for (let f = 0; f < faces; f++) { images[f] = { mipmaps: [] }; - for (let i = 0; i < texDatas.mipmapCount; i++) { images[f].mipmaps.push(texDatas.mipmaps[f * texDatas.mipmapCount + i]); images[f].format = texDatas.format; @@ -28843,40 +26258,33 @@ images[f].height = texDatas.height; } } - texture.image = images; } else { texture.image.width = texDatas.width; texture.image.height = texDatas.height; texture.mipmaps = texDatas.mipmaps; } - if (texDatas.mipmapCount === 1) { texture.minFilter = LinearFilter; } - texture.format = texDatas.format; texture.needsUpdate = true; if (onLoad) onLoad(texture); }, onProgress, onError); } - return texture; } - } class ImageLoader extends Loader { constructor(manager) { super(manager); } - load(url, onLoad, onProgress, onError) { if (this.path !== undefined) url = this.path + url; url = this.manager.resolveURL(url); const scope = this; const cached = Cache.get(url); - if (cached !== undefined) { scope.manager.itemStart(url); setTimeout(function () { @@ -28885,73 +26293,59 @@ }, 0); return cached; } - const image = createElementNS('img'); - function onImageLoad() { removeEventListeners(); Cache.add(url, this); if (onLoad) onLoad(this); scope.manager.itemEnd(url); } - function onImageError(event) { removeEventListeners(); if (onError) onError(event); scope.manager.itemError(url); scope.manager.itemEnd(url); } - function removeEventListeners() { image.removeEventListener('load', onImageLoad, false); image.removeEventListener('error', onImageError, false); } - image.addEventListener('load', onImageLoad, false); image.addEventListener('error', onImageError, false); - if (url.slice(0, 5) !== 'data:') { if (this.crossOrigin !== undefined) image.crossOrigin = this.crossOrigin; } - scope.manager.itemStart(url); image.src = url; return image; } - } class CubeTextureLoader extends Loader { constructor(manager) { super(manager); } - load(urls, onLoad, onProgress, onError) { const texture = new CubeTexture(); const loader = new ImageLoader(this.manager); loader.setCrossOrigin(this.crossOrigin); loader.setPath(this.path); let loaded = 0; - function loadTexture(i) { loader.load(urls[i], function (image) { texture.images[i] = image; loaded++; - if (loaded === 6) { texture.needsUpdate = true; if (onLoad) onLoad(texture); } }, undefined, onError); } - for (let i = 0; i < urls.length; ++i) { loadTexture(i); } - return texture; } - } /** @@ -28964,7 +26358,6 @@ constructor(manager) { super(manager); } - load(url, onLoad, onProgress, onError) { const scope = this; const texture = new DataTexture(); @@ -28976,7 +26369,6 @@ loader.load(url, function (buffer) { const texData = scope.parse(buffer); if (!texData) return; - if (texData.image !== undefined) { texture.image = texData.image; } else if (texData.data !== undefined) { @@ -28984,29 +26376,23 @@ texture.image.height = texData.height; texture.image.data = texData.data; } - 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; - if (texData.encoding !== undefined) { texture.encoding = texData.encoding; } - if (texData.flipY !== undefined) { texture.flipY = texData.flipY; } - if (texData.format !== undefined) { texture.format = texData.format; } - if (texData.type !== undefined) { texture.type = texData.type; } - if (texData.mipmaps !== undefined) { texture.mipmaps = texData.mipmaps; texture.minFilter = LinearMipmapLinearFilter; // presumably... @@ -29015,24 +26401,20 @@ if (texData.mipmapCount === 1) { texture.minFilter = LinearFilter; } - if (texData.generateMipmaps !== undefined) { texture.generateMipmaps = texData.generateMipmaps; } - texture.needsUpdate = true; if (onLoad) onLoad(texture, texData); }, onProgress, onError); return texture; } - } class TextureLoader extends Loader { constructor(manager) { super(manager); } - load(url, onLoad, onProgress, onError) { const texture = new Texture(); const loader = new ImageLoader(this.manager); @@ -29041,14 +26423,12 @@ loader.load(url, function (image) { texture.image = image; texture.needsUpdate = true; - if (onLoad !== undefined) { onLoad(texture); } }, onProgress, onError); return texture; } - } class Light extends Object3D { @@ -29059,17 +26439,16 @@ this.color = new Color(color); this.intensity = intensity; } + dispose() { - dispose() {// Empty here in base class; some subclasses override. + // Empty here in base class; some subclasses override. } - copy(source, recursive) { super.copy(source, recursive); this.color.copy(source.color); this.intensity = source.intensity; return this; } - toJSON(meta) { const data = super.toJSON(meta); data.object.color = this.color.getHex(); @@ -29082,7 +26461,6 @@ if (this.shadow !== undefined) data.object.shadow = this.shadow.toJSON(); return data; } - } class HemisphereLight extends Light { @@ -29094,21 +26472,16 @@ this.updateMatrix(); this.groundColor = new Color(groundColor); } - copy(source, recursive) { super.copy(source, recursive); this.groundColor.copy(source.groundColor); return this; } - } const _projScreenMatrix$1 = /*@__PURE__*/new Matrix4(); - const _lightPositionWorld$1 = /*@__PURE__*/new Vector3(); - const _lookTarget$1 = /*@__PURE__*/new Vector3(); - class LightShadow { constructor(camera) { this.camera = camera; @@ -29127,55 +26500,39 @@ this._viewportCount = 1; this._viewports = [new Vector4(0, 0, 1, 1)]; } - getViewportCount() { return this._viewportCount; } - getFrustum() { return this._frustum; } - updateMatrices(light) { const shadowCamera = this.camera; const shadowMatrix = this.matrix; - _lightPositionWorld$1.setFromMatrixPosition(light.matrixWorld); - shadowCamera.position.copy(_lightPositionWorld$1); - _lookTarget$1.setFromMatrixPosition(light.target.matrixWorld); - shadowCamera.lookAt(_lookTarget$1); shadowCamera.updateMatrixWorld(); - _projScreenMatrix$1.multiplyMatrices(shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse); - this._frustum.setFromProjectionMatrix(_projScreenMatrix$1); - 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); + shadowMatrix.multiply(_projScreenMatrix$1); } - getViewport(viewportIndex) { return this._viewports[viewportIndex]; } - getFrameExtents() { return this._frameExtents; } - dispose() { if (this.map) { this.map.dispose(); } - if (this.mapPass) { this.mapPass.dispose(); } } - copy(source) { this.camera = source.camera.clone(); this.bias = source.bias; @@ -29183,11 +26540,9 @@ this.mapSize.copy(source.mapSize); return this; } - clone() { return new this.constructor().copy(this); } - toJSON() { const object = {}; if (this.bias !== 0) object.bias = this.bias; @@ -29198,7 +26553,6 @@ delete object.camera.matrix; return object; } - } class SpotLightShadow extends LightShadow { @@ -29207,33 +26561,28 @@ this.isSpotLightShadow = true; this.focus = 1; } - updateMatrices(light) { const camera = this.camera; const fov = RAD2DEG * 2 * light.angle * this.focus; const aspect = this.mapSize.width / this.mapSize.height; const 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(); } - super.updateMatrices(light); } - copy(source) { super.copy(source); this.focus = source.focus; return this; } - } class SpotLight extends Light { - constructor(color, intensity, distance = 0, angle = Math.PI / 3, penumbra = 0, decay = 1) { + constructor(color, intensity, distance = 0, angle = Math.PI / 3, penumbra = 0, decay = 2) { super(color, intensity); this.isSpotLight = true; this.type = 'SpotLight'; @@ -29243,26 +26592,22 @@ this.distance = distance; this.angle = angle; this.penumbra = penumbra; - this.decay = decay; // for physically correct lights, should be 2. - + this.decay = decay; + this.map = null; this.shadow = new SpotLightShadow(); } - get power() { // compute the light's luminous power (in lumens) from its intensity (in candela) // by convention for a spotlight, luminous power (lm) = π * luminous intensity (cd) return this.intensity * Math.PI; } - set power(power) { // set the light's intensity (in candela) from the desired luminous power (in lumens) this.intensity = power / Math.PI; } - dispose() { this.shadow.dispose(); } - copy(source, recursive) { super.copy(source, recursive); this.distance = source.distance; @@ -29273,22 +26618,19 @@ this.shadow = source.shadow.clone(); return this; } - } const _projScreenMatrix = /*@__PURE__*/new Matrix4(); - const _lightPositionWorld = /*@__PURE__*/new Vector3(); - const _lookTarget = /*@__PURE__*/new Vector3(); - class PointLightShadow extends LightShadow { constructor() { super(new PerspectiveCamera(90, 1, 0.5, 500)); this.isPointLightShadow = true; this._frameExtents = new Vector2(4, 2); this._viewportCount = 6; - this._viewports = [// These viewports map a cube-map onto a 2D texture with the + this._viewports = [ + // These viewports map a cube-map onto a 2D texture with the // following orientation: // // xzXZ @@ -29300,73 +26642,64 @@ // 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(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)]; } - updateMatrices(light, viewportIndex = 0) { const camera = this.camera; const shadowMatrix = this.matrix; const far = light.distance || camera.far; - if (far !== camera.far) { camera.far = far; camera.updateProjectionMatrix(); } - _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); } - } class PointLight extends Light { - constructor(color, intensity, distance = 0, decay = 1) { + constructor(color, intensity, distance = 0, decay = 2) { super(color, intensity); this.isPointLight = true; this.type = 'PointLight'; this.distance = distance; - this.decay = decay; // for physically correct lights, should be 2. - + this.decay = decay; this.shadow = new PointLightShadow(); } - get power() { // compute the light's luminous power (in lumens) from its intensity (in candela) // for an isotropic light source, luminous power (lm) = 4 π luminous intensity (cd) return this.intensity * 4 * Math.PI; } - set power(power) { // set the light's intensity (in candela) from the desired luminous power (in lumens) this.intensity = power / (4 * Math.PI); } - dispose() { this.shadow.dispose(); } - copy(source, recursive) { super.copy(source, recursive); this.distance = source.distance; @@ -29374,7 +26707,6 @@ this.shadow = source.shadow.clone(); return this; } - } class DirectionalLightShadow extends LightShadow { @@ -29382,7 +26714,6 @@ super(new OrthographicCamera(-5, 5, 5, -5, 0.5, 500)); this.isDirectionalLightShadow = true; } - } class DirectionalLight extends Light { @@ -29395,18 +26726,15 @@ this.target = new Object3D(); this.shadow = new DirectionalLightShadow(); } - dispose() { this.shadow.dispose(); } - copy(source) { super.copy(source); this.target = source.target.clone(); this.shadow = source.shadow.clone(); return this; } - } class AmbientLight extends Light { @@ -29415,7 +26743,6 @@ this.isAmbientLight = true; this.type = 'AmbientLight'; } - } class RectAreaLight extends Light { @@ -29426,31 +26753,26 @@ this.width = width; this.height = height; } - get power() { // compute the light's luminous power (in lumens) from its intensity (in nits) return this.intensity * this.width * this.height * Math.PI; } - set power(power) { // set the light's intensity (in nits) from the desired luminous power (in lumens) this.intensity = power / (this.width * this.height * Math.PI); } - copy(source) { super.copy(source); this.width = source.width; this.height = source.height; return this; } - toJSON(meta) { const data = super.toJSON(meta); data.object.width = this.width; data.object.height = this.height; return data; } - } /** @@ -29460,177 +26782,162 @@ * Secondary reference: * https://www.ppsloan.org/publications/StupidSH36.pdf */ + // 3-band SH defined by 9 coefficients class SphericalHarmonics3 { constructor() { this.isSphericalHarmonics3 = true; this.coefficients = []; - for (let i = 0; i < 9; i++) { this.coefficients.push(new Vector3()); } } - set(coefficients) { for (let i = 0; i < 9; i++) { this.coefficients[i].copy(coefficients[i]); } - return this; } - zero() { for (let i = 0; i < 9; i++) { this.coefficients[i].set(0, 0, 0); } - return this; - } // get the radiance in the direction of the normal - // target is a Vector3 - + } + // get the radiance in the direction of the normal + // target is a Vector3 getAt(normal, target) { // normal is assumed to be unit length + const x = normal.x, - y = normal.y, - z = normal.z; - const coeff = this.coefficients; // band 0 + y = normal.y, + z = normal.z; + const coeff = this.coefficients; - target.copy(coeff[0]).multiplyScalar(0.282095); // band 1 + // 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[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 + } + + // 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 - - getIrradianceAt(normal, target) { // normal is assumed to be unit length + const x = normal.x, - y = normal.y, - z = normal.z; - const coeff = this.coefficients; // band 0 + y = normal.y, + z = normal.z; + const coeff = this.coefficients; + // band 0 target.copy(coeff[0]).multiplyScalar(0.886227); // π * 0.282095 - // band 1 + // 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[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; } - add(sh) { for (let i = 0; i < 9; i++) { this.coefficients[i].add(sh.coefficients[i]); } - return this; } - addScaledSH(sh, s) { for (let i = 0; i < 9; i++) { this.coefficients[i].addScaledVector(sh.coefficients[i], s); } - return this; } - scale(s) { for (let i = 0; i < 9; i++) { this.coefficients[i].multiplyScalar(s); } - return this; } - lerp(sh, alpha) { for (let i = 0; i < 9; i++) { this.coefficients[i].lerp(sh.coefficients[i], alpha); } - return this; } - equals(sh) { for (let i = 0; i < 9; i++) { if (!this.coefficients[i].equals(sh.coefficients[i])) { return false; } } - return true; } - copy(sh) { return this.set(sh.coefficients); } - clone() { return new this.constructor().copy(this); } - fromArray(array, offset = 0) { const coefficients = this.coefficients; - for (let i = 0; i < 9; i++) { coefficients[i].fromArray(array, offset + i * 3); } - return this; } - toArray(array = [], offset = 0) { const coefficients = this.coefficients; - for (let i = 0; i < 9; i++) { coefficients[i].toArray(array, offset + i * 3); } - return array; - } // evaluate the basis functions - // shBasis is an Array[ 9 ] - + } + // evaluate the basis functions + // shBasis is an Array[ 9 ] static getBasisAt(normal, shBasis) { // normal is assumed to be unit length + const x = normal.x, - y = normal.y, - z = normal.z; // band 0 + y = normal.y, + z = normal.z; - shBasis[0] = 0.282095; // band 1 + // 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[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); } - } class LightProbe extends Light { @@ -29639,26 +26946,21 @@ this.isLightProbe = true; this.sh = sh; } - copy(source) { super.copy(source); this.sh.copy(source.sh); return this; } - fromJSON(json) { this.intensity = json.intensity; // TODO: Move this bit to Light.fromJSON(); - this.sh.fromArray(json.sh); return this; } - toJSON(meta) { const data = super.toJSON(meta); data.object.sh = this.sh.toArray(); return data; } - } class MaterialLoader extends Loader { @@ -29666,7 +26968,6 @@ super(manager); this.textures = {}; } - load(url, onLoad, onProgress, onError) { const scope = this; const loader = new FileLoader(scope.manager); @@ -29682,23 +26983,18 @@ } else { console.error(e); } - scope.manager.itemError(url); } }, onProgress, onError); } - parse(json) { const textures = this.textures; - function getTexture(name) { if (textures[name] === undefined) { console.warn('THREE.MaterialLoader: Undefined texture', name); } - return textures[name]; } - const material = MaterialLoader.createMaterialFromType(json.type); if (json.uuid !== undefined) material.uuid = json.uuid; if (json.name !== undefined) material.name = json.name; @@ -29760,72 +27056,63 @@ 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 + } + // Shader Material if (json.uniforms !== undefined) { for (const name in json.uniforms) { const 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; - case 'v2': material.uniforms[name].value = new Vector2().fromArray(uniform.value); break; - case 'v3': material.uniforms[name].value = new Vector3().fromArray(uniform.value); break; - case 'v4': material.uniforms[name].value = new Vector4().fromArray(uniform.value); break; - case 'm3': material.uniforms[name].value = new Matrix3().fromArray(uniform.value); break; - case 'm4': material.uniforms[name].value = new Matrix4().fromArray(uniform.value); break; - default: material.uniforms[name].value = uniform.value; } } } - 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.glslVersion !== undefined) material.glslVersion = json.glslVersion; if (json.extensions !== undefined) { for (const key in json.extensions) { material.extensions[key] = json.extensions[key]; } - } // Deprecated - + } - if (json.shading !== undefined) material.flatShading = json.shading === 1; // THREE.FlatShading // for PointsMaterial if (json.size !== undefined) material.size = json.size; - if (json.sizeAttenuation !== undefined) material.sizeAttenuation = json.sizeAttenuation; // maps + if (json.sizeAttenuation !== undefined) material.sizeAttenuation = json.sizeAttenuation; + + // maps if (json.map !== undefined) material.map = getTexture(json.map); if (json.matcap !== undefined) material.matcap = getTexture(json.matcap); @@ -29834,18 +27121,15 @@ 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; - if (json.normalScale !== undefined) { let normalScale = json.normalScale; - if (Array.isArray(normalScale) === false) { // Blender exporter used to export a scalar. See #7459 + normalScale = [normalScale, normalScale]; } - 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; @@ -29877,12 +27161,10 @@ if (json.sheenRoughnessMap !== undefined) material.sheenRoughnessMap = getTexture(json.sheenRoughnessMap); return material; } - setTextures(value) { this.textures = value; return this; } - static createMaterialFromType(type) { const materialLib = { ShadowMaterial, @@ -29906,57 +27188,58 @@ }; return new materialLib[type](); } - } class LoaderUtils { static 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. + } + // Avoid the String.fromCharCode.apply(null, array) shortcut, which + // throws a "maximum call stack size exceeded" error for large arrays. let s = ''; - for (let i = 0, il = array.length; i < il; i++) { // Implicitly assumes little-endian. s += String.fromCharCode(array[i]); } - try { // merges multi-byte utf-8 characters. + return decodeURIComponent(escape(s)); } catch (e) { // see #16358 + return s; } } - static extractUrlBase(url) { const index = url.lastIndexOf('/'); if (index === -1) return './'; return url.slice(0, index + 1); } - static resolveURL(url, path) { // Invalid URL - if (typeof url !== 'string' || url === '') return ''; // Host Relative URL + if (typeof url !== 'string' || url === '') return ''; + // Host Relative URL if (/^https?:\/\//i.test(path) && /^\//.test(url)) { path = path.replace(/(^https?:\/\/[^\/]+).*/i, '$1'); - } // Absolute URL http://,https://,// - + } - if (/^(https?:)?\/\//i.test(url)) return url; // Data URI + // Absolute URL http://,https://,// + if (/^(https?:)?\/\//i.test(url)) return url; - if (/^data:.*,.*$/i.test(url)) return url; // Blob URL + // Data URI + if (/^data:.*,.*$/i.test(url)) return url; - if (/^blob:.*$/i.test(url)) return url; // Relative URL + // Blob URL + if (/^blob:.*$/i.test(url)) return url; + // Relative URL return path + url; } - } class InstancedBufferGeometry extends BufferGeometry { @@ -29966,31 +27249,23 @@ this.type = 'InstancedBufferGeometry'; this.instanceCount = Infinity; } - copy(source) { super.copy(source); this.instanceCount = source.instanceCount; return this; } - - clone() { - return new this.constructor().copy(this); - } - toJSON() { - const data = super.toJSON(this); + const data = super.toJSON(); data.instanceCount = this.instanceCount; data.isInstancedBufferGeometry = true; return data; } - } class BufferGeometryLoader extends Loader { constructor(manager) { super(manager); } - load(url, onLoad, onProgress, onError) { const scope = this; const loader = new FileLoader(scope.manager); @@ -30006,16 +27281,13 @@ } else { console.error(e); } - scope.manager.itemError(url); } }, onProgress, onError); } - parse(json) { const interleavedBufferMap = {}; const arrayBufferMap = {}; - function getInterleavedBuffer(json, uuid) { if (interleavedBufferMap[uuid] !== undefined) return interleavedBufferMap[uuid]; const interleavedBuffers = json.interleavedBuffers; @@ -30027,7 +27299,6 @@ interleavedBufferMap[uuid] = ib; return ib; } - function getArrayBuffer(json, uuid) { if (arrayBufferMap[uuid] !== undefined) return arrayBufferMap[uuid]; const arrayBuffers = json.arrayBuffers; @@ -30036,21 +27307,16 @@ arrayBufferMap[uuid] = ab; return ab; } - const geometry = json.isInstancedBufferGeometry ? new InstancedBufferGeometry() : new BufferGeometry(); const index = json.data.index; - if (index !== undefined) { const typedArray = getTypedArray(index.type, index.array); geometry.setIndex(new BufferAttribute(typedArray, 1)); } - const attributes = json.data.attributes; - for (const key in attributes) { const attribute = attributes[key]; let bufferAttribute; - if (attribute.isInterleavedBufferAttribute) { const interleavedBuffer = getInterleavedBuffer(json.data, attribute.data); bufferAttribute = new InterleavedBufferAttribute(interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized); @@ -30059,29 +27325,22 @@ const bufferAttributeConstr = attribute.isInstancedBufferAttribute ? InstancedBufferAttribute : BufferAttribute; bufferAttribute = new bufferAttributeConstr(typedArray, attribute.itemSize, attribute.normalized); } - if (attribute.name !== undefined) bufferAttribute.name = attribute.name; if (attribute.usage !== undefined) bufferAttribute.setUsage(attribute.usage); - if (attribute.updateRange !== undefined) { bufferAttribute.updateRange.offset = attribute.updateRange.offset; bufferAttribute.updateRange.count = attribute.updateRange.count; } - geometry.setAttribute(key, bufferAttribute); } - const morphAttributes = json.data.morphAttributes; - if (morphAttributes) { for (const key in morphAttributes) { const attributeArray = morphAttributes[key]; const array = []; - for (let i = 0, il = attributeArray.length; i < il; i++) { const attribute = attributeArray[i]; let bufferAttribute; - if (attribute.isInterleavedBufferAttribute) { const interleavedBuffer = getInterleavedBuffer(json.data, attribute.data); bufferAttribute = new InterleavedBufferAttribute(interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized); @@ -30089,54 +27348,41 @@ const typedArray = getTypedArray(attribute.type, attribute.array); bufferAttribute = new BufferAttribute(typedArray, attribute.itemSize, attribute.normalized); } - if (attribute.name !== undefined) bufferAttribute.name = attribute.name; array.push(bufferAttribute); } - geometry.morphAttributes[key] = array; } } - const morphTargetsRelative = json.data.morphTargetsRelative; - if (morphTargetsRelative) { geometry.morphTargetsRelative = true; } - const groups = json.data.groups || json.data.drawcalls || json.data.offsets; - if (groups !== undefined) { for (let i = 0, n = groups.length; i !== n; ++i) { const group = groups[i]; geometry.addGroup(group.start, group.count, group.materialIndex); } } - const boundingSphere = json.data.boundingSphere; - if (boundingSphere !== undefined) { const center = new Vector3(); - if (boundingSphere.center !== undefined) { center.fromArray(boundingSphere.center); } - geometry.boundingSphere = new Sphere(center, boundingSphere.radius); } - if (json.name) geometry.name = json.name; if (json.userData) geometry.userData = json.userData; return geometry; } - } class ObjectLoader extends Loader { constructor(manager) { super(manager); } - load(url, onLoad, onProgress, onError) { const scope = this; const path = this.path === '' ? LoaderUtils.extractUrlBase(url) : this.path; @@ -30147,7 +27393,6 @@ loader.setWithCredentials(this.withCredentials); loader.load(url, function (text) { let json = null; - try { json = JSON.parse(text); } catch (error) { @@ -30155,18 +27400,15 @@ console.error('THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message); return; } - const metadata = json.metadata; - if (metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry') { + if (onError !== undefined) onError(new Error('THREE.ObjectLoader: Can\'t load ' + url)); console.error('THREE.ObjectLoader: Can\'t load ' + url); return; } - scope.parse(json, onLoad); }, onProgress, onError); } - async loadAsync(url, onProgress) { const scope = this; const path = this.path === '' ? LoaderUtils.extractUrlBase(url) : this.path; @@ -30178,14 +27420,11 @@ const text = await loader.loadAsync(url, onProgress); const json = JSON.parse(text); const metadata = json.metadata; - if (metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry') { throw new Error('THREE.ObjectLoader: Can\'t load ' + url); } - return await scope.parseAsync(json); } - parse(json, onLoad) { const animations = this.parseAnimations(json.animations); const shapes = this.parseShapes(json.shapes); @@ -30197,24 +27436,22 @@ const materials = this.parseMaterials(json.materials, textures); const object = this.parseObject(json.object, geometries, materials, textures, animations); const skeletons = this.parseSkeletons(json.skeletons, object); - this.bindSkeletons(object, skeletons); // + this.bindSkeletons(object, skeletons); + + // if (onLoad !== undefined) { let hasImages = false; - for (const uuid in images) { if (images[uuid].data instanceof HTMLImageElement) { hasImages = true; break; } } - if (hasImages === false) onLoad(object); } - return object; } - async parseAsync(json) { const animations = this.parseAnimations(json.animations); const shapes = this.parseShapes(json.shapes); @@ -30227,27 +27464,27 @@ this.bindSkeletons(object, skeletons); return object; } - parseShapes(json) { const shapes = {}; - if (json !== undefined) { for (let i = 0, l = json.length; i < l; i++) { const shape = new Shape().fromJSON(json[i]); shapes[shape.uuid] = shape; } } - return shapes; } - parseSkeletons(json, object) { const skeletons = {}; - const bones = {}; // generate bone lookup table + const bones = {}; + + // generate bone lookup table object.traverse(function (child) { if (child.isBone) bones[child.uuid] = child; - }); // create skeletons + }); + + // create skeletons if (json !== undefined) { for (let i = 0, l = json.length; i < l; i++) { @@ -30255,92 +27492,53 @@ skeletons[skeleton.uuid] = skeleton; } } - return skeletons; } - parseGeometries(json, shapes) { const geometries = {}; - if (json !== undefined) { const bufferGeometryLoader = new BufferGeometryLoader(); - for (let i = 0, l = json.length; i < l; i++) { let geometry; const data = json[i]; - switch (data.type) { case 'BufferGeometry': case 'InstancedBufferGeometry': geometry = bufferGeometryLoader.parse(data); break; - - case 'Geometry': - console.error('THREE.ObjectLoader: The legacy Geometry type is no longer supported.'); - break; - default: if (data.type in Geometries) { geometry = Geometries[data.type].fromJSON(data, shapes); } else { console.warn(`THREE.ObjectLoader: Unsupported geometry type "${data.type}"`); } - } - 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; } } - return geometries; } - parseMaterials(json, textures) { const cache = {}; // MultiMaterial - const materials = {}; - if (json !== undefined) { const loader = new MaterialLoader(); loader.setTextures(textures); - for (let i = 0, l = json.length; i < l; i++) { const data = json[i]; - - if (data.type === 'MultiMaterial') { - // Deprecated - const array = []; - - for (let j = 0; j < data.materials.length; j++) { - const material = data.materials[j]; - - if (cache[material.uuid] === undefined) { - cache[material.uuid] = loader.parse(material); - } - - array.push(cache[material.uuid]); - } - - materials[data.uuid] = array; - } else { - if (cache[data.uuid] === undefined) { - cache[data.uuid] = loader.parse(data); - } - - materials[data.uuid] = cache[data.uuid]; + if (cache[data.uuid] === undefined) { + cache[data.uuid] = loader.parse(data); } + materials[data.uuid] = cache[data.uuid]; } } - return materials; } - parseAnimations(json) { const animations = {}; - if (json !== undefined) { for (let i = 0; i < json.length; i++) { const data = json[i]; @@ -30348,15 +27546,12 @@ animations[clip.uuid] = clip; } } - return animations; } - parseImages(json, onLoad) { const scope = this; const images = {}; let loader; - function loadImage(url) { scope.manager.itemStart(url); return loader.load(url, function () { @@ -30366,7 +27561,6 @@ scope.manager.itemEnd(url); }); } - function deserializeImage(image) { if (typeof image === 'string') { const url = image; @@ -30384,51 +27578,45 @@ } } } - if (json !== undefined && json.length > 0) { const manager = new LoadingManager(onLoad); loader = new ImageLoader(manager); loader.setCrossOrigin(this.crossOrigin); - for (let i = 0, il = json.length; i < il; i++) { const image = json[i]; const url = image.url; - if (Array.isArray(url)) { // load array of images e.g CubeTexture - const imageArray = []; + const imageArray = []; for (let j = 0, jl = url.length; j < jl; j++) { const currentUrl = url[j]; const deserializedImage = deserializeImage(currentUrl); - if (deserializedImage !== null) { if (deserializedImage instanceof HTMLImageElement) { imageArray.push(deserializedImage); } else { // special case: handle array of data textures for cube textures + imageArray.push(new DataTexture(deserializedImage.data, deserializedImage.width, deserializedImage.height)); } } } - images[image.uuid] = new Source(imageArray); } else { // load single image + const deserializedImage = deserializeImage(image.url); images[image.uuid] = new Source(deserializedImage); } } } - return images; } - async parseImagesAsync(json) { const scope = this; const images = {}; let loader; - async function deserializeImage(image) { if (typeof image === 'string') { const url = image; @@ -30446,70 +27634,59 @@ } } } - if (json !== undefined && json.length > 0) { loader = new ImageLoader(this.manager); loader.setCrossOrigin(this.crossOrigin); - for (let i = 0, il = json.length; i < il; i++) { const image = json[i]; const url = image.url; - if (Array.isArray(url)) { // load array of images e.g CubeTexture - const imageArray = []; + const imageArray = []; for (let j = 0, jl = url.length; j < jl; j++) { const currentUrl = url[j]; const deserializedImage = await deserializeImage(currentUrl); - if (deserializedImage !== null) { if (deserializedImage instanceof HTMLImageElement) { imageArray.push(deserializedImage); } else { // special case: handle array of data textures for cube textures + imageArray.push(new DataTexture(deserializedImage.data, deserializedImage.width, deserializedImage.height)); } } } - images[image.uuid] = new Source(imageArray); } else { // load single image + const deserializedImage = await deserializeImage(image.url); images[image.uuid] = new Source(deserializedImage); } } } - return images; } - 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]; } - const textures = {}; - if (json !== undefined) { for (let i = 0, l = json.length; i < l; i++) { const data = json[i]; - if (data.image === undefined) { console.warn('THREE.ObjectLoader: No "image" specified for', data.uuid); } - if (images[data.image] === undefined) { console.warn('THREE.ObjectLoader: Undefined image', data.image); } - const source = images[data.image]; const image = source.data; let texture; - if (Array.isArray(image)) { texture = new CubeTexture(); if (image.length === 6) texture.needsUpdate = true; @@ -30519,7 +27696,6 @@ } else { texture = new Texture(); } - if (image) texture.needsUpdate = true; // textures can have undefined image data } @@ -30531,12 +27707,10 @@ 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); } - if (data.format !== undefined) texture.format = data.format; if (data.type !== undefined) texture.type = data.type; if (data.encoding !== undefined) texture.encoding = data.encoding; @@ -30550,61 +27724,44 @@ textures[data.uuid] = texture; } } - return textures; } - parseObject(data, geometries, materials, textures, animations) { let object; - function getGeometry(name) { if (geometries[name] === undefined) { console.warn('THREE.ObjectLoader: Undefined geometry', name); } - return geometries[name]; } - function getMaterial(name) { if (name === undefined) return undefined; - if (Array.isArray(name)) { const array = []; - for (let i = 0, l = name.length; i < l; i++) { const uuid = name[i]; - if (materials[uuid] === undefined) { console.warn('THREE.ObjectLoader: Undefined material', uuid); } - array.push(materials[uuid]); } - return array; } - if (materials[name] === undefined) { console.warn('THREE.ObjectLoader: Undefined material', name); } - return materials[name]; } - function getTexture(uuid) { if (textures[uuid] === undefined) { console.warn('THREE.ObjectLoader: Undefined texture', uuid); } - return textures[uuid]; } - let geometry, material; - switch (data.type) { case 'Scene': object = new Scene(); - if (data.background !== undefined) { if (Number.isInteger(data.background)) { object.background = new Color(data.background); @@ -30612,11 +27769,9 @@ object.background = getTexture(data.background); } } - if (data.environment !== undefined) { object.environment = getTexture(data.environment); } - if (data.fog !== undefined) { if (data.fog.type === 'Fog') { object.fog = new Fog(data.fog.color, data.fog.near, data.fog.far); @@ -30624,9 +27779,8 @@ object.fog = new FogExp2(data.fog.color, data.fog.density); } } - + if (data.backgroundBlurriness !== undefined) object.backgroundBlurriness = data.backgroundBlurriness; break; - case 'PerspectiveCamera': object = new PerspectiveCamera(data.fov, data.aspect, data.near, data.far); if (data.focus !== undefined) object.focus = data.focus; @@ -30635,41 +27789,32 @@ if (data.filmOffset !== undefined) object.filmOffset = data.filmOffset; if (data.view !== undefined) object.view = Object.assign({}, data.view); break; - 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; - case 'AmbientLight': object = new AmbientLight(data.color, data.intensity); break; - case 'DirectionalLight': object = new DirectionalLight(data.color, data.intensity); break; - case 'PointLight': object = new PointLight(data.color, data.intensity, data.distance, data.decay); break; - case 'RectAreaLight': object = new RectAreaLight(data.color, data.intensity, data.width, data.height); break; - case 'SpotLight': object = new SpotLight(data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay); break; - case 'HemisphereLight': object = new HemisphereLight(data.color, data.groundColor, data.intensity); break; - case 'LightProbe': object = new LightProbe().fromJSON(data); break; - case 'SkinnedMesh': geometry = getGeometry(data.geometry); material = getMaterial(data.material); @@ -30678,13 +27823,11 @@ if (data.bindMatrix !== undefined) object.bindMatrix.fromArray(data.bindMatrix); if (data.skeleton !== undefined) object.skeleton = data.skeleton; break; - case 'Mesh': geometry = getGeometry(data.geometry); material = getMaterial(data.material); object = new Mesh(geometry, material); break; - case 'InstancedMesh': geometry = getGeometry(data.geometry); material = getMaterial(data.material); @@ -30695,47 +27838,36 @@ object.instanceMatrix = new InstancedBufferAttribute(new Float32Array(instanceMatrix.array), 16); if (instanceColor !== undefined) object.instanceColor = new InstancedBufferAttribute(new Float32Array(instanceColor.array), instanceColor.itemSize); break; - case 'LOD': object = new LOD(); break; - case 'Line': object = new Line(getGeometry(data.geometry), getMaterial(data.material)); break; - case 'LineLoop': object = new LineLoop(getGeometry(data.geometry), getMaterial(data.material)); break; - case 'LineSegments': object = new LineSegments(getGeometry(data.geometry), getMaterial(data.material)); break; - case 'PointCloud': case 'Points': object = new Points(getGeometry(data.geometry), getMaterial(data.material)); break; - case 'Sprite': object = new Sprite(getMaterial(data.material)); break; - case 'Group': object = new Group(); break; - case 'Bone': object = new Bone(); break; - default: object = new Object3D(); } - object.uuid = data.uuid; if (data.name !== undefined) object.name = data.name; - if (data.matrix !== undefined) { object.matrix.fromArray(data.matrix); if (data.matrixAutoUpdate !== undefined) object.matrixAutoUpdate = data.matrixAutoUpdate; @@ -30746,10 +27878,8 @@ if (data.quaternion !== undefined) object.quaternion.fromArray(data.quaternion); if (data.scale !== undefined) object.scale.fromArray(data.scale); } - if (data.castShadow !== undefined) object.castShadow = data.castShadow; if (data.receiveShadow !== undefined) object.receiveShadow = data.receiveShadow; - 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; @@ -30757,53 +27887,42 @@ 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); } - 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; - if (data.children !== undefined) { const children = data.children; - for (let i = 0; i < children.length; i++) { object.add(this.parseObject(children[i], geometries, materials, textures, animations)); } } - if (data.animations !== undefined) { const objectAnimations = data.animations; - for (let i = 0; i < objectAnimations.length; i++) { const uuid = objectAnimations[i]; object.animations.push(animations[uuid]); } } - if (data.type === 'LOD') { if (data.autoUpdate !== undefined) object.autoUpdate = data.autoUpdate; const levels = data.levels; - for (let l = 0; l < levels.length; l++) { const level = levels[l]; const child = object.getObjectByProperty('uuid', level.object); - if (child !== undefined) { - object.addLevel(child, level.distance); + object.addLevel(child, level.distance, level.hysteresis); } } } - return object; } - bindSkeletons(object, skeletons) { if (Object.keys(skeletons).length === 0) return; object.traverse(function (child) { if (child.isSkinnedMesh === true && child.skeleton !== undefined) { const skeleton = skeletons[child.skeleton]; - if (skeleton === undefined) { console.warn('THREE.ObjectLoader: No skeleton found with UUID:', child.skeleton); } else { @@ -30812,9 +27931,7 @@ } }); } - } - const TEXTURE_MAPPING = { UVMapping: UVMapping, CubeReflectionMapping: CubeReflectionMapping, @@ -30841,32 +27958,26 @@ constructor(manager) { super(manager); this.isImageBitmapLoader = true; - if (typeof createImageBitmap === 'undefined') { console.warn('THREE.ImageBitmapLoader: createImageBitmap() not supported.'); } - if (typeof fetch === 'undefined') { console.warn('THREE.ImageBitmapLoader: fetch() not supported.'); } - this.options = { premultiplyAlpha: 'none' }; } - setOptions(options) { this.options = options; return this; } - load(url, onLoad, onProgress, onError) { if (url === undefined) url = ''; if (this.path !== undefined) url = this.path + url; url = this.manager.resolveURL(url); const scope = this; const cached = Cache.get(url); - if (cached !== undefined) { scope.manager.itemStart(url); setTimeout(function () { @@ -30875,7 +27986,6 @@ }, 0); return cached; } - const fetchOptions = {}; fetchOptions.credentials = this.crossOrigin === 'anonymous' ? 'same-origin' : 'include'; fetchOptions.headers = this.requestHeader; @@ -30896,29 +28006,25 @@ }); scope.manager.itemStart(url); } - } let _context; - - const AudioContext = { - getContext: function () { + class AudioContext { + static getContext() { if (_context === undefined) { _context = new (window.AudioContext || window.webkitAudioContext)(); } - return _context; - }, - setContext: function (value) { + } + static setContext(value) { _context = value; } - }; + } class AudioLoader extends Loader { constructor(manager) { super(manager); } - load(url, onLoad, onProgress, onError) { const scope = this; const loader = new FileLoader(this.manager); @@ -30941,12 +28047,10 @@ } else { console.error(e); } - scope.manager.itemError(url); } }, onProgress, onError); } - } class HemisphereLightProbe extends LightProbe { @@ -30956,33 +28060,30 @@ const color1 = new Color().set(skyColor); const color2 = new Color().set(groundColor); const sky = new Vector3(color1.r, color1.g, color1.b); - const ground = new Vector3(color2.r, color2.g, color2.b); // without extra factor of PI in the shader, should = 1 / Math.sqrt( Math.PI ); + const ground = new Vector3(color2.r, color2.g, color2.b); + // without extra factor of PI in the shader, should = 1 / Math.sqrt( Math.PI ); const c0 = Math.sqrt(Math.PI); const 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); } - } class AmbientLightProbe extends LightProbe { constructor(color, intensity = 1) { super(undefined, intensity); this.isAmbientLightProbe = true; - const color1 = new Color().set(color); // without extra factor of PI in the shader, would be 2 / Math.sqrt( Math.PI ); + const 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)); } - } const _eyeRight = /*@__PURE__*/new Matrix4(); - const _eyeLeft = /*@__PURE__*/new Matrix4(); - const _projectionMatrix = /*@__PURE__*/new Matrix4(); - class StereoCamera { constructor() { this.type = 'StereoCamera'; @@ -31004,11 +28105,9 @@ eyeSep: null }; } - update(camera) { const cache = this._cache; const 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; - if (needsUpdate) { cache.focus = camera.focus; cache.fov = camera.fov; @@ -31016,24 +28115,31 @@ cache.near = camera.near; cache.far = camera.far; cache.zoom = camera.zoom; - cache.eyeSep = this.eyeSep; // Off-axis stereoscopic effect based on + cache.eyeSep = this.eyeSep; + + // Off-axis stereoscopic effect based on // http://paulbourke.net/stereographics/stereorender/ _projectionMatrix.copy(camera.projectionMatrix); - const eyeSepHalf = cache.eyeSep / 2; const eyeSepOnProjection = eyeSepHalf * cache.near / cache.focus; const ymax = cache.near * Math.tan(DEG2RAD * cache.fov * 0.5) / cache.zoom; - let xmin, xmax; // translate xOffset + let xmin, xmax; + + // translate xOffset _eyeLeft.elements[12] = -eyeSepHalf; - _eyeRight.elements[12] = eyeSepHalf; // for left eye + _eyeRight.elements[12] = eyeSepHalf; + + // for left eye 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 + this.cameraL.projectionMatrix.copy(_projectionMatrix); + + // for right eye xmin = -ymax * cache.aspect - eyeSepOnProjection; xmax = ymax * cache.aspect - eyeSepOnProjection; @@ -31041,11 +28147,9 @@ _projectionMatrix.elements[8] = (xmax + xmin) / (xmax - xmin); this.cameraR.projectionMatrix.copy(_projectionMatrix); } - this.cameraL.matrixWorld.copy(camera.matrixWorld).multiply(_eyeLeft); this.cameraR.matrixWorld.copy(camera.matrixWorld).multiply(_eyeRight); } - } class Clock { @@ -31056,57 +28160,44 @@ this.elapsedTime = 0; this.running = false; } - start() { this.startTime = now(); this.oldTime = this.startTime; this.elapsedTime = 0; this.running = true; } - stop() { this.getElapsedTime(); this.running = false; this.autoStart = false; } - getElapsedTime() { this.getDelta(); return this.elapsedTime; } - getDelta() { let diff = 0; - if (this.autoStart && !this.running) { this.start(); return 0; } - if (this.running) { const newTime = now(); diff = (newTime - this.oldTime) / 1000; this.oldTime = newTime; this.elapsedTime += diff; } - return diff; } - } - function now() { return (typeof performance === 'undefined' ? Date : performance).now(); // see #10732 } const _position$1 = /*@__PURE__*/new Vector3(); - const _quaternion$1 = /*@__PURE__*/new Quaternion(); - const _scale$1 = /*@__PURE__*/new Vector3(); - const _orientation$1 = /*@__PURE__*/new Vector3(); - class AudioListener extends Object3D { constructor() { super(); @@ -31115,15 +28206,15 @@ this.gain = this.context.createGain(); this.gain.connect(this.context.destination); this.filter = null; - this.timeDelta = 0; // private + this.timeDelta = 0; + + // private this._clock = new Clock(); } - getInput() { return this.gain; } - removeFilter() { if (this.filter !== null) { this.gain.disconnect(this.filter); @@ -31131,14 +28222,11 @@ this.gain.connect(this.context.destination); this.filter = null; } - return this; } - getFilter() { return this.filter; } - setFilter(value) { if (this.filter !== null) { this.gain.disconnect(this.filter); @@ -31146,33 +28234,28 @@ } else { this.gain.disconnect(this.context.destination); } - this.filter = value; this.gain.connect(this.filter); this.filter.connect(this.context.destination); return this; } - getMasterVolume() { return this.gain.gain.value; } - setMasterVolume(value) { this.gain.gain.setTargetAtTime(value, this.context.currentTime, 0.01); return this; } - updateMatrixWorld(force) { super.updateMatrixWorld(force); const listener = this.context.listener; const up = this.up; this.timeDelta = this._clock.getDelta(); this.matrixWorld.decompose(_position$1, _quaternion$1, _scale$1); - _orientation$1.set(0, 0, -1).applyQuaternion(_quaternion$1); - if (listener.positionX) { // code path for Chrome (see #14393) + const endTime = this.context.currentTime + this.timeDelta; listener.positionX.linearRampToValueAtTime(_position$1.x, endTime); listener.positionY.linearRampToValueAtTime(_position$1.y, endTime); @@ -31188,7 +28271,6 @@ listener.setOrientation(_orientation$1.x, _orientation$1.y, _orientation$1.z, up.x, up.y, up.z); } } - } class Audio extends Object3D { @@ -31217,11 +28299,9 @@ this._connected = false; this.filters = []; } - getOutput() { return this.gain; } - setNodeSource(audioNode) { this.hasPlaybackControl = false; this.sourceType = 'audioNode'; @@ -31229,7 +28309,6 @@ this.connect(); return this; } - setMediaElementSource(mediaElement) { this.hasPlaybackControl = false; this.sourceType = 'mediaNode'; @@ -31237,7 +28316,6 @@ this.connect(); return this; } - setMediaStreamSource(mediaStream) { this.hasPlaybackControl = false; this.sourceType = 'mediaStreamNode'; @@ -31245,25 +28323,21 @@ this.connect(); return this; } - setBuffer(audioBuffer) { this.buffer = audioBuffer; this.sourceType = 'buffer'; if (this.autoplay) this.play(); return this; } - play(delay = 0) { 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; } - this._startedAt = this.context.currentTime + delay; const source = this.context.createBufferSource(); source.buffer = this.buffer; @@ -31278,84 +28352,68 @@ this.setPlaybackRate(this.playbackRate); return this.connect(); } - pause() { if (this.hasPlaybackControl === false) { console.warn('THREE.Audio: this Audio has no playback control.'); return; } - if (this.isPlaying === true) { // update current progress - this._progress += Math.max(this.context.currentTime - this._startedAt, 0) * this.playbackRate; + this._progress += Math.max(this.context.currentTime - this._startedAt, 0) * this.playbackRate; if (this.loop === true) { // ensure _progress does not exceed duration with looped audios + this._progress = this._progress % (this.duration || this.buffer.duration); } - this.source.stop(); this.source.onended = null; this.isPlaying = false; } - return this; } - stop() { if (this.hasPlaybackControl === false) { console.warn('THREE.Audio: this Audio has no playback control.'); return; } - this._progress = 0; this.source.stop(); this.source.onended = null; this.isPlaying = false; return this; } - connect() { if (this.filters.length > 0) { this.source.connect(this.filters[0]); - for (let i = 1, l = this.filters.length; i < l; i++) { this.filters[i - 1].connect(this.filters[i]); } - this.filters[this.filters.length - 1].connect(this.getOutput()); } else { this.source.connect(this.getOutput()); } - this._connected = true; return this; } - disconnect() { if (this.filters.length > 0) { this.source.disconnect(this.filters[0]); - for (let i = 1, l = this.filters.length; i < l; i++) { this.filters[i - 1].disconnect(this.filters[i]); } - this.filters[this.filters.length - 1].disconnect(this.getOutput()); } else { this.source.disconnect(this.getOutput()); } - this._connected = false; return this; } - getFilters() { return this.filters; } - setFilters(value) { if (!value) value = []; - if (this._connected === true) { this.disconnect(); this.filters = value.slice(); @@ -31363,10 +28421,8 @@ } else { this.filters = value.slice(); } - return this; } - setDetune(value) { this.detune = value; if (this.source.detune === undefined) return; // only set detune when available @@ -31374,98 +28430,73 @@ if (this.isPlaying === true) { this.source.detune.setTargetAtTime(this.detune, this.context.currentTime, 0.01); } - return this; } - getDetune() { return this.detune; } - getFilter() { return this.getFilters()[0]; } - setFilter(filter) { return this.setFilters(filter ? [filter] : []); } - setPlaybackRate(value) { if (this.hasPlaybackControl === false) { console.warn('THREE.Audio: this Audio has no playback control.'); return; } - this.playbackRate = value; - if (this.isPlaying === true) { this.source.playbackRate.setTargetAtTime(this.playbackRate, this.context.currentTime, 0.01); } - return this; } - getPlaybackRate() { return this.playbackRate; } - onEnded() { this.isPlaying = false; } - getLoop() { if (this.hasPlaybackControl === false) { console.warn('THREE.Audio: this Audio has no playback control.'); return false; } - return this.loop; } - setLoop(value) { if (this.hasPlaybackControl === false) { console.warn('THREE.Audio: this Audio has no playback control.'); return; } - this.loop = value; - if (this.isPlaying === true) { this.source.loop = this.loop; } - return this; } - setLoopStart(value) { this.loopStart = value; return this; } - setLoopEnd(value) { this.loopEnd = value; return this; } - getVolume() { return this.gain.gain.value; } - setVolume(value) { this.gain.gain.setTargetAtTime(value, this.context.currentTime, 0.01); return this; } - } const _position = /*@__PURE__*/new Vector3(); - const _quaternion = /*@__PURE__*/new Quaternion(); - const _scale = /*@__PURE__*/new Vector3(); - const _orientation = /*@__PURE__*/new Vector3(); - class PositionalAudio extends Audio { constructor(listener) { super(listener); @@ -31473,70 +28504,56 @@ this.panner.panningModel = 'HRTF'; this.panner.connect(this.gain); } - disconnect() { super.disconnect(); this.panner.disconnect(this.gain); } - getOutput() { return this.panner; } - getRefDistance() { return this.panner.refDistance; } - setRefDistance(value) { this.panner.refDistance = value; return this; } - getRolloffFactor() { return this.panner.rolloffFactor; } - setRolloffFactor(value) { this.panner.rolloffFactor = value; return this; } - getDistanceModel() { return this.panner.distanceModel; } - setDistanceModel(value) { this.panner.distanceModel = value; return this; } - getMaxDistance() { return this.panner.maxDistance; } - setMaxDistance(value) { this.panner.maxDistance = value; return this; } - setDirectionalCone(coneInnerAngle, coneOuterAngle, coneOuterGain) { this.panner.coneInnerAngle = coneInnerAngle; this.panner.coneOuterAngle = coneOuterAngle; this.panner.coneOuterGain = coneOuterGain; return this; } - updateMatrixWorld(force) { super.updateMatrixWorld(force); if (this.hasPlaybackControl === true && this.isPlaying === false) return; this.matrixWorld.decompose(_position, _quaternion, _scale); - _orientation.set(0, 0, 1).applyQuaternion(_quaternion); - const panner = this.panner; - if (panner.positionX) { // code path for Chrome and Firefox (see #14393) + const endTime = this.context.currentTime + this.listener.timeDelta; panner.positionX.linearRampToValueAtTime(_position.x, endTime); panner.positionY.linearRampToValueAtTime(_position.y, endTime); @@ -31549,7 +28566,6 @@ panner.setOrientation(_orientation.x, _orientation.y, _orientation.z); } } - } class AudioAnalyser { @@ -31559,30 +28575,27 @@ this.data = new Uint8Array(this.analyser.frequencyBinCount); audio.getOutput().connect(this.analyser); } - getFrequencyData() { this.analyser.getByteFrequencyData(this.data); return this.data; } - getAverageFrequency() { let value = 0; const data = this.getFrequencyData(); - for (let i = 0; i < data.length; i++) { value += data[i]; } - return value / data.length; } - } class PropertyMixer { constructor(binding, typeName, valueSize) { this.binding = binding; this.valueSize = valueSize; - let mixFunction, mixFunctionAdditive, setIdentity; // buffer layout: [ incoming | accu0 | accu1 | orig | addAccu | (optional work) ] + let 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' @@ -31606,24 +28619,22 @@ this.buffer = new Float64Array(valueSize * 6); this._workIndex = 5; break; - 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 + mixFunction = this._select; + // Use the regular mix function and for additive on these types, + // additive is not relevant for non-numeric types mixFunctionAdditive = this._select; setIdentity = this._setAdditiveIdentityOther; this.buffer = new Array(valueSize * 5); break; - 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; @@ -31633,133 +28644,126 @@ this.cumulativeWeightAdditive = 0; this.useCount = 0; this.referenceCount = 0; - } // accumulate data in the 'incoming' region into 'accu' - + } + // accumulate data in the 'incoming' region into 'accu' 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 + const buffer = this.buffer, - stride = this.valueSize, - offset = accuIndex * stride + stride; + stride = this.valueSize, + offset = accuIndex * stride + stride; let currentWeight = this.cumulativeWeight; - if (currentWeight === 0) { // accuN := incoming * weight + for (let i = 0; i !== stride; ++i) { buffer[offset + i] = buffer[i]; } - currentWeight = weight; } else { // accuN := accuN + incoming * weight + currentWeight += weight; const mix = weight / currentWeight; - this._mixBufferRegion(buffer, offset, 0, mix, stride); } - this.cumulativeWeight = currentWeight; - } // accumulate data in the 'incoming' region into 'add' - + } + // accumulate data in the 'incoming' region into 'add' accumulateAdditive(weight) { const buffer = this.buffer, - stride = this.valueSize, - offset = stride * this._addIndex; - + stride = this.valueSize, + offset = stride * this._addIndex; if (this.cumulativeWeightAdditive === 0) { // add = identity + this._setIdentity(); - } // add := add + incoming * weight + } + // add := add + incoming * weight this._mixBufferRegionAdditive(buffer, offset, 0, weight, stride); - this.cumulativeWeightAdditive += weight; - } // apply the state of 'accu' to the binding when accus differ - + } + // apply the state of 'accu' to the binding when accus differ apply(accuIndex) { const stride = this.valueSize, - buffer = this.buffer, - offset = accuIndex * stride + stride, - weight = this.cumulativeWeight, - weightAdditive = this.cumulativeWeightAdditive, - binding = this.binding; + buffer = this.buffer, + offset = accuIndex * stride + stride, + weight = this.cumulativeWeight, + weightAdditive = this.cumulativeWeightAdditive, + binding = this.binding; this.cumulativeWeight = 0; this.cumulativeWeightAdditive = 0; - if (weight < 1) { // accuN := accuN + original * ( 1 - cumulativeWeight ) - const originalValueOffset = stride * this._origIndex; + const originalValueOffset = stride * this._origIndex; this._mixBufferRegion(buffer, offset, originalValueOffset, 1 - weight, stride); } - if (weightAdditive > 0) { // accuN := accuN + additive accuN + this._mixBufferRegionAdditive(buffer, offset, this._addIndex * stride, 1, stride); } - for (let 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 - + } + // remember the state of the bound property and copy it to both accus saveOriginalState() { const binding = this.binding; const buffer = this.buffer, - stride = this.valueSize, - originalValueOffset = stride * this._origIndex; - binding.getValue(buffer, originalValueOffset); // accu[0..1] := orig -- initially detect changes against the original + stride = this.valueSize, + originalValueOffset = stride * this._origIndex; + binding.getValue(buffer, originalValueOffset); + // accu[0..1] := orig -- initially detect changes against the original for (let i = stride, e = originalValueOffset; i !== e; ++i) { buffer[i] = buffer[originalValueOffset + i % stride]; - } // Add to identity for additive - + } + // Add to identity for additive this._setIdentity(); - this.cumulativeWeight = 0; this.cumulativeWeightAdditive = 0; - } // apply the state previously taken via 'saveOriginalState' to the binding - + } + // apply the state previously taken via 'saveOriginalState' to the binding restoreOriginalState() { const originalValueOffset = this.valueSize * 3; this.binding.setValue(this.buffer, originalValueOffset); } - _setAdditiveIdentityNumeric() { const startIndex = this._addIndex * this.valueSize; const endIndex = startIndex + this.valueSize; - for (let i = startIndex; i < endIndex; i++) { this.buffer[i] = 0; } } - _setAdditiveIdentityQuaternion() { this._setAdditiveIdentityNumeric(); - this.buffer[this._addIndex * this.valueSize + 3] = 1; } - _setAdditiveIdentityOther() { const startIndex = this._origIndex * this.valueSize; const targetIndex = this._addIndex * this.valueSize; - for (let i = 0; i < this.valueSize; i++) { this.buffer[targetIndex + i] = this.buffer[startIndex + i]; } - } // mix functions + } + // mix functions _select(buffer, dstOffset, srcOffset, t, stride) { if (t >= 0.5) { @@ -31768,126 +28772,110 @@ } } } - _slerp(buffer, dstOffset, srcOffset, t) { Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t); } - _slerpAdditive(buffer, dstOffset, srcOffset, t, stride) { - const workOffset = this._workIndex * stride; // Store result in intermediate buffer offset + const workOffset = this._workIndex * stride; - Quaternion.multiplyQuaternionsFlat(buffer, workOffset, buffer, dstOffset, buffer, srcOffset); // Slerp to the intermediate result + // Store result in intermediate buffer offset + Quaternion.multiplyQuaternionsFlat(buffer, workOffset, buffer, dstOffset, buffer, srcOffset); + // Slerp to the intermediate result Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, workOffset, t); } - _lerp(buffer, dstOffset, srcOffset, t, stride) { const s = 1 - t; - for (let i = 0; i !== stride; ++i) { const j = dstOffset + i; buffer[j] = buffer[j] * s + buffer[srcOffset + i] * t; } } - _lerpAdditive(buffer, dstOffset, srcOffset, t, stride) { for (let i = 0; i !== stride; ++i) { const j = dstOffset + i; buffer[j] = buffer[j] + buffer[srcOffset + i] * t; } } - } // Characters [].:/ are reserved for track binding syntax. const _RESERVED_CHARS_RE = '\\[\\]\\.:\\/'; + const _reservedRe = new RegExp('[' + _RESERVED_CHARS_RE + ']', 'g'); - const _reservedRe = new RegExp('[' + _RESERVED_CHARS_RE + ']', 'g'); // Attempts to allow node names from any language. ES5's `\w` regexp matches + // 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. - - const _wordChar = '[^' + _RESERVED_CHARS_RE + ']'; + const _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace('\\.', '') + ']'; - const _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace('\\.', '') + ']'; // Parent directories, delimited by '/' or ':'. Currently unused, but must + // Parent directories, delimited by '/' or ':'. Currently unused, but must // be matched to parse the rest of the track name. + const _directoryRe = /*@__PURE__*/ /((?:WC+[\/:])*)/.source.replace('WC', _wordChar); + // Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'. + const _nodeRe = /*@__PURE__*/ /(WCOD+)?/.source.replace('WCOD', _wordCharOrDot); - const _directoryRe = /*@__PURE__*/ /((?:WC+[\/:])*)/.source.replace('WC', _wordChar); // Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'. - - - const _nodeRe = /*@__PURE__*/ /(WCOD+)?/.source.replace('WCOD', _wordCharOrDot); // Object on target node, and accessor. May not contain reserved + // Object on target node, and accessor. May not contain reserved // characters. Accessor may contain any character except closing bracket. + const _objectRe = /*@__PURE__*/ /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace('WC', _wordChar); - - const _objectRe = /*@__PURE__*/ /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace('WC', _wordChar); // Property and accessor. May not contain reserved characters. Accessor may + // Property and accessor. May not contain reserved characters. Accessor may // contain any non-bracket characters. - - const _propertyRe = /*@__PURE__*/ /\.(WC+)(?:\[(.+)\])?/.source.replace('WC', _wordChar); - const _trackRe = new RegExp('' + '^' + _directoryRe + _nodeRe + _objectRe + _propertyRe + '$'); - - const _supportedObjectNames = ['material', 'materials', 'bones']; - + const _supportedObjectNames = ['material', 'materials', 'bones', 'map']; class Composite { constructor(targetGroup, path, optionalParsedPath) { const parsedPath = optionalParsedPath || PropertyBinding.parseTrackName(path); this._targetGroup = targetGroup; this._bindings = targetGroup.subscribe_(path, parsedPath); } - getValue(array, offset) { this.bind(); // bind all binding const firstValidIndex = this._targetGroup.nCachedObjects_, - binding = this._bindings[firstValidIndex]; // and only call .getValue on the first + binding = this._bindings[firstValidIndex]; + // and only call .getValue on the first if (binding !== undefined) binding.getValue(array, offset); } - setValue(array, offset) { const bindings = this._bindings; - for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { bindings[i].setValue(array, offset); } } - bind() { const bindings = this._bindings; - for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { bindings[i].bind(); } } - unbind() { const bindings = this._bindings; - for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { bindings[i].unbind(); } } + } - } // Note: This class uses a State pattern on a per-method basis: + // 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. - - class PropertyBinding { constructor(rootNode, path, parsedPath) { this.path = path; this.parsedPath = parsedPath || PropertyBinding.parseTrackName(path); this.node = PropertyBinding.findNode(rootNode, this.parsedPath.nodeName) || rootNode; - this.rootNode = rootNode; // initial state of these methods that calls 'bind' + this.rootNode = rootNode; + // initial state of these methods that calls 'bind' this.getValue = this._getValue_unbound; this.setValue = this._setValue_unbound; } - static create(root, path, parsedPath) { if (!(root && root.isAnimationObjectGroup)) { return new PropertyBinding(root, path, parsedPath); @@ -31895,6 +28883,7 @@ return new PropertyBinding.Composite(root, path, parsedPath); } } + /** * Replaces spaces with underscores and removes unsupported characters from * node names, to ensure compatibility with parseTrackName(). @@ -31902,19 +28891,14 @@ * @param {string} name Node name to be sanitized. * @return {string} */ - - static sanitizeNodeName(name) { return name.replace(/\s/g, '_').replace(_reservedRe, ''); } - static parseTrackName(trackName) { const matches = _trackRe.exec(trackName); - if (matches === null) { throw new Error('PropertyBinding: Cannot parse trackName: ' + trackName); } - const results = { // directoryName: matches[ 1 ], // (tschw) currently unused nodeName: matches[2], @@ -31925,304 +28909,287 @@ propertyIndex: matches[6] }; const lastDot = results.nodeName && results.nodeName.lastIndexOf('.'); - if (lastDot !== undefined && lastDot !== -1) { - const objectName = results.nodeName.substring(lastDot + 1); // Object names must be checked against an allowlist. Otherwise, there + const 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). - if (_supportedObjectNames.indexOf(objectName) !== -1) { results.nodeName = results.nodeName.substring(0, lastDot); results.objectName = objectName; } } - if (results.propertyName === null || results.propertyName.length === 0) { throw new Error('PropertyBinding: can not parse propertyName from trackName: ' + trackName); } - return results; } - static findNode(root, nodeName) { if (nodeName === undefined || nodeName === '' || nodeName === '.' || nodeName === -1 || nodeName === root.name || nodeName === root.uuid) { return root; - } // search into skeleton bones. - + } + // search into skeleton bones. if (root.skeleton) { const bone = root.skeleton.getBoneByName(nodeName); - if (bone !== undefined) { return bone; } - } // search into node subtree. - + } + // search into node subtree. if (root.children) { const searchNodeSubtree = function (children) { for (let i = 0; i < children.length; i++) { const childNode = children[i]; - if (childNode.name === nodeName || childNode.uuid === nodeName) { return childNode; } - const result = searchNodeSubtree(childNode.children); if (result) return result; } - return null; }; - const subTreeNode = searchNodeSubtree(root.children); - if (subTreeNode) { return subTreeNode; } } - return null; - } // these are used to "bind" a nonexistent property - + } + // these are used to "bind" a nonexistent property _getValue_unavailable() {} + _setValue_unavailable() {} - _setValue_unavailable() {} // Getters - + // Getters _getValue_direct(buffer, offset) { buffer[offset] = this.targetObject[this.propertyName]; } - _getValue_array(buffer, offset) { const source = this.resolvedProperty; - for (let i = 0, n = source.length; i !== n; ++i) { buffer[offset++] = source[i]; } } - _getValue_arrayElement(buffer, offset) { buffer[offset] = this.resolvedProperty[this.propertyIndex]; } - _getValue_toArray(buffer, offset) { this.resolvedProperty.toArray(buffer, offset); - } // Direct + } + // Direct _setValue_direct(buffer, offset) { this.targetObject[this.propertyName] = buffer[offset]; } - _setValue_direct_setNeedsUpdate(buffer, offset) { this.targetObject[this.propertyName] = buffer[offset]; this.targetObject.needsUpdate = true; } - _setValue_direct_setMatrixWorldNeedsUpdate(buffer, offset) { this.targetObject[this.propertyName] = buffer[offset]; this.targetObject.matrixWorldNeedsUpdate = true; - } // EntireArray + } + // EntireArray _setValue_array(buffer, offset) { const dest = this.resolvedProperty; - for (let i = 0, n = dest.length; i !== n; ++i) { dest[i] = buffer[offset++]; } } - _setValue_array_setNeedsUpdate(buffer, offset) { const dest = this.resolvedProperty; - for (let i = 0, n = dest.length; i !== n; ++i) { dest[i] = buffer[offset++]; } - this.targetObject.needsUpdate = true; } - _setValue_array_setMatrixWorldNeedsUpdate(buffer, offset) { const dest = this.resolvedProperty; - for (let i = 0, n = dest.length; i !== n; ++i) { dest[i] = buffer[offset++]; } - this.targetObject.matrixWorldNeedsUpdate = true; - } // ArrayElement + } + // ArrayElement _setValue_arrayElement(buffer, offset) { this.resolvedProperty[this.propertyIndex] = buffer[offset]; } - _setValue_arrayElement_setNeedsUpdate(buffer, offset) { this.resolvedProperty[this.propertyIndex] = buffer[offset]; this.targetObject.needsUpdate = true; } - _setValue_arrayElement_setMatrixWorldNeedsUpdate(buffer, offset) { this.resolvedProperty[this.propertyIndex] = buffer[offset]; this.targetObject.matrixWorldNeedsUpdate = true; - } // HasToFromArray + } + // HasToFromArray _setValue_fromArray(buffer, offset) { this.resolvedProperty.fromArray(buffer, offset); } - _setValue_fromArray_setNeedsUpdate(buffer, offset) { this.resolvedProperty.fromArray(buffer, offset); this.targetObject.needsUpdate = true; } - _setValue_fromArray_setMatrixWorldNeedsUpdate(buffer, offset) { this.resolvedProperty.fromArray(buffer, offset); this.targetObject.matrixWorldNeedsUpdate = true; } - _getValue_unbound(targetArray, offset) { this.bind(); this.getValue(targetArray, offset); } - _setValue_unbound(sourceArray, offset) { this.bind(); this.setValue(sourceArray, offset); - } // create getter / setter pair for a property in the scene graph - + } + // create getter / setter pair for a property in the scene graph bind() { let targetObject = this.node; const parsedPath = this.parsedPath; const objectName = parsedPath.objectName; const propertyName = parsedPath.propertyName; let propertyIndex = parsedPath.propertyIndex; - if (!targetObject) { targetObject = PropertyBinding.findNode(this.rootNode, parsedPath.nodeName) || this.rootNode; this.node = targetObject; - } // set fail state so we can just 'return' on error - + } + // set fail state so we can just 'return' on error this.getValue = this._getValue_unavailable; - this.setValue = this._setValue_unavailable; // ensure there is a value node + this.setValue = this._setValue_unavailable; + // ensure there is a value node if (!targetObject) { console.error('THREE.PropertyBinding: Trying to update node for track: ' + this.path + ' but it wasn\'t found.'); return; } - if (objectName) { - let objectIndex = parsedPath.objectIndex; // special cases were we need to reach deeper into the hierarchy to get the face materials.... + let 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; } - 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; } - targetObject = targetObject.material.materials; break; - 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. + } + // potential future optimization: skip this if propertyIndex is already an integer + // and convert the integer string to a true integer. - targetObject = targetObject.skeleton.bones; // support resolving morphTarget names into indices. + targetObject = targetObject.skeleton.bones; + // support resolving morphTarget names into indices. for (let i = 0; i < targetObject.length; i++) { if (targetObject[i].name === objectIndex) { objectIndex = i; break; } } - break; - + case 'map': + if ('map' in targetObject) { + targetObject = targetObject.map; + break; + } + if (!targetObject.material) { + console.error('THREE.PropertyBinding: Can not bind to material as node does not have a material.', this); + return; + } + if (!targetObject.material.map) { + console.error('THREE.PropertyBinding: Can not bind to material.map as node.material does not have a map.', this); + return; + } + targetObject = targetObject.material.map; + break; default: if (targetObject[objectName] === undefined) { console.error('THREE.PropertyBinding: Can not bind to objectName of node undefined.', this); return; } - targetObject = targetObject[objectName]; } - if (objectIndex !== undefined) { if (targetObject[objectIndex] === undefined) { console.error('THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject); return; } - targetObject = targetObject[objectIndex]; } - } // resolve property - + } + // resolve property const nodeProperty = targetObject[propertyName]; - if (nodeProperty === undefined) { const 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 - + } + // determine versioning scheme let versioning = this.Versioning.None; this.targetObject = targetObject; - 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 + versioning = this.Versioning.MatrixWorldNeedsUpdate; + } + // determine how the property gets bound let bindingType = this.BindingType.Direct; - 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; } - 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]; } } - 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)) { @@ -32230,23 +29197,21 @@ this.resolvedProperty = nodeProperty; } else { this.propertyName = propertyName; - } // select getter / setter - + } + // select getter / setter this.getValue = this.GetterByBindingType[bindingType]; this.setValue = this.SetterByBindingTypeAndVersioning[bindingType][versioning]; } - unbind() { - this.node = null; // back to the prototype version of getValue / setValue - // note: avoiding to mutate the shape of 'this' via 'delete' + this.node = null; + // back to the prototype version of getValue / setValue + // note: avoiding to mutate the shape of 'this' via 'delete' this.getValue = this._getValue_unbound; this.setValue = this._setValue_unbound; } - } - PropertyBinding.Composite = Composite; PropertyBinding.prototype.BindingType = { Direct: 0, @@ -32260,10 +29225,15 @@ MatrixWorldNeedsUpdate: 2 }; PropertyBinding.prototype.GetterByBindingType = [PropertyBinding.prototype._getValue_direct, PropertyBinding.prototype._getValue_array, PropertyBinding.prototype._getValue_arrayElement, PropertyBinding.prototype._getValue_toArray]; - PropertyBinding.prototype.SetterByBindingTypeAndVersioning = [[// Direct - PropertyBinding.prototype._setValue_direct, PropertyBinding.prototype._setValue_direct_setNeedsUpdate, PropertyBinding.prototype._setValue_direct_setMatrixWorldNeedsUpdate], [// EntireArray - PropertyBinding.prototype._setValue_array, PropertyBinding.prototype._setValue_array_setNeedsUpdate, PropertyBinding.prototype._setValue_array_setMatrixWorldNeedsUpdate], [// ArrayElement - PropertyBinding.prototype._setValue_arrayElement, PropertyBinding.prototype._setValue_arrayElement_setNeedsUpdate, PropertyBinding.prototype._setValue_arrayElement_setMatrixWorldNeedsUpdate], [// HasToFromArray + PropertyBinding.prototype.SetterByBindingTypeAndVersioning = [[ + // Direct + PropertyBinding.prototype._setValue_direct, PropertyBinding.prototype._setValue_direct_setNeedsUpdate, PropertyBinding.prototype._setValue_direct_setMatrixWorldNeedsUpdate], [ + // EntireArray + + PropertyBinding.prototype._setValue_array, PropertyBinding.prototype._setValue_array_setNeedsUpdate, PropertyBinding.prototype._setValue_array_setMatrixWorldNeedsUpdate], [ + // ArrayElement + PropertyBinding.prototype._setValue_arrayElement, PropertyBinding.prototype._setValue_arrayElement_setNeedsUpdate, PropertyBinding.prototype._setValue_arrayElement_setMatrixWorldNeedsUpdate], [ + // HasToFromArray PropertyBinding.prototype._setValue_fromArray, PropertyBinding.prototype._setValue_fromArray_setNeedsUpdate, PropertyBinding.prototype._setValue_fromArray_setMatrixWorldNeedsUpdate]]; /** @@ -32298,8 +29268,9 @@ class AnimationObjectGroup { constructor() { this.isAnimationObjectGroup = true; - this.uuid = generateUUID(); // cached objects followed by the active ones + this.uuid = generateUUID(); + // cached objects followed by the active ones this._objects = Array.prototype.slice.call(arguments); this.nCachedObjects_ = 0; // threshold // note: read by PropertyBinding.Composite @@ -32310,13 +29281,9 @@ for (let i = 0, n = arguments.length; i !== n; ++i) { indices[arguments[i].uuid] = i; } - this._paths = []; // inside: string - this._parsedPaths = []; // inside: { we don't care, here } - this._bindings = []; // inside: Array< PropertyBinding > - this._bindingsIndicesByPath = {}; // inside: indices in these arrays const scope = this; @@ -32325,165 +29292,164 @@ get total() { return scope._objects.length; }, - get inUse() { return this.total - scope.nCachedObjects_; } - }, - get bindingsPerObject() { return scope._bindings.length; } - }; } - add() { const objects = this._objects, - indicesByUUID = this._indicesByUUID, - paths = this._paths, - parsedPaths = this._parsedPaths, - bindings = this._bindings, - nBindings = bindings.length; + indicesByUUID = this._indicesByUUID, + paths = this._paths, + parsedPaths = this._parsedPaths, + bindings = this._bindings, + nBindings = bindings.length; let knownObject = undefined, - nObjects = objects.length, - nCachedObjects = this.nCachedObjects_; - + nObjects = objects.length, + nCachedObjects = this.nCachedObjects_; for (let i = 0, n = arguments.length; i !== n; ++i) { const object = arguments[i], - uuid = object.uuid; + uuid = object.uuid; let 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 + objects.push(object); + + // accounting is done, now do the same for all bindings for (let 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 + knownObject = objects[index]; + + // move existing object to the ACTIVE region const firstActiveIndex = --nCachedObjects, - lastCachedObject = objects[firstActiveIndex]; + 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 + objects[firstActiveIndex] = object; + + // accounting is done, now do the same for all bindings for (let j = 0, m = nBindings; j !== m; ++j) { const bindingsForPath = bindings[j], - lastCached = bindingsForPath[firstActiveIndex]; + lastCached = bindingsForPath[firstActiveIndex]; let 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]); } - 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 - this.nCachedObjects_ = nCachedObjects; } - remove() { const objects = this._objects, - indicesByUUID = this._indicesByUUID, - bindings = this._bindings, - nBindings = bindings.length; + indicesByUUID = this._indicesByUUID, + bindings = this._bindings, + nBindings = bindings.length; let nCachedObjects = this.nCachedObjects_; - for (let i = 0, n = arguments.length; i !== n; ++i) { const object = arguments[i], - uuid = object.uuid, - index = indicesByUUID[uuid]; - + uuid = object.uuid, + index = indicesByUUID[uuid]; if (index !== undefined && index >= nCachedObjects) { // move existing object into the CACHED region + const lastCachedIndex = nCachedObjects++, - firstActiveObject = objects[lastCachedIndex]; + 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 + objects[lastCachedIndex] = object; + + // accounting is done, now do the same for all bindings for (let j = 0, m = nBindings; j !== m; ++j) { const bindingsForPath = bindings[j], - firstActive = bindingsForPath[lastCachedIndex], - binding = bindingsForPath[index]; + firstActive = bindingsForPath[lastCachedIndex], + binding = bindingsForPath[index]; bindingsForPath[index] = firstActive; bindingsForPath[lastCachedIndex] = binding; } } } // for arguments - this.nCachedObjects_ = nCachedObjects; - } // remove & forget - + } + // remove & forget uncache() { const objects = this._objects, - indicesByUUID = this._indicesByUUID, - bindings = this._bindings, - nBindings = bindings.length; + indicesByUUID = this._indicesByUUID, + bindings = this._bindings, + nBindings = bindings.length; let nCachedObjects = this.nCachedObjects_, - nObjects = objects.length; - + nObjects = objects.length; for (let i = 0, n = arguments.length; i !== n; ++i) { const object = arguments[i], - uuid = object.uuid, - index = indicesByUUID[uuid]; - + uuid = object.uuid, + index = indicesByUUID[uuid]; if (index !== undefined) { delete indicesByUUID[uuid]; - if (index < nCachedObjects) { // object is cached, shrink the CACHED region + const firstActiveIndex = --nCachedObjects, - lastCachedObject = objects[firstActiveIndex], - lastIndex = --nObjects, - lastObject = objects[lastIndex]; // last cached object takes this object's place + 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 + 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 + objects.pop(); + + // accounting is done, now do the same for all bindings for (let j = 0, m = nBindings; j !== m; ++j) { const bindingsForPath = bindings[j], - lastCached = bindingsForPath[firstActiveIndex], - last = bindingsForPath[lastIndex]; + 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 - const lastIndex = --nObjects, - lastObject = objects[lastIndex]; + const lastIndex = --nObjects, + lastObject = objects[lastIndex]; if (lastIndex > 0) { indicesByUUID[lastObject.uuid] = index; } - objects[index] = lastObject; - objects.pop(); // accounting is done, now do the same for all bindings + objects.pop(); + + // accounting is done, now do the same for all bindings for (let j = 0, m = nBindings; j !== m; ++j) { const bindingsForPath = bindings[j]; @@ -32491,56 +29457,52 @@ bindingsForPath.pop(); } } // cached or active - } // if object is known - } // for arguments - this.nCachedObjects_ = nCachedObjects; - } // Internal interface used by befriended PropertyBinding.Composite: + } + // Internal interface used by befriended PropertyBinding.Composite: subscribe_(path, parsedPath) { // returns an array of bindings for the given path that is changed // according to the contained objects in the group + const indicesByPath = this._bindingsIndicesByPath; let index = indicesByPath[path]; const bindings = this._bindings; if (index !== undefined) return bindings[index]; const paths = this._paths, - parsedPaths = this._parsedPaths, - objects = this._objects, - nObjects = objects.length, - nCachedObjects = this.nCachedObjects_, - bindingsForPath = new Array(nObjects); + 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 (let i = nCachedObjects, n = objects.length; i !== n; ++i) { const object = objects[i]; bindingsForPath[i] = new PropertyBinding(object, path, parsedPath); } - return bindingsForPath; } - unsubscribe_(path) { // tells the group to forget about a property path and no longer // update the array previously obtained with 'subscribe_' - const indicesByPath = this._bindingsIndicesByPath, - index = indicesByPath[path]; + const indicesByPath = this._bindingsIndicesByPath, + index = indicesByPath[path]; if (index !== undefined) { const paths = this._paths, - parsedPaths = this._parsedPaths, - bindings = this._bindings, - lastBindingsIndex = bindings.length - 1, - lastBindings = bindings[lastBindingsIndex], - lastBindingsPath = path[lastBindingsIndex]; + parsedPaths = this._parsedPaths, + bindings = this._bindings, + lastBindingsIndex = bindings.length - 1, + lastBindings = bindings[lastBindingsIndex], + lastBindingsPath = path[lastBindingsIndex]; indicesByPath[lastBindingsPath] = index; bindings[index] = lastBindings; bindings.pop(); @@ -32550,7 +29512,6 @@ paths.pop(); } } - } class AnimationAction { @@ -32560,37 +29521,36 @@ this._localRoot = localRoot; this.blendMode = blendMode; const tracks = clip.tracks, - nTracks = tracks.length, - interpolants = new Array(nTracks); + nTracks = tracks.length, + interpolants = new Array(nTracks); const interpolantSettings = { endingStart: ZeroCurvatureEnding, endingEnd: ZeroCurvatureEnding }; - for (let i = 0; i !== nTracks; ++i) { const interpolant = tracks[i].createInterpolant(null); interpolants[i] = interpolant; interpolant.settings = interpolantSettings; } - this._interpolantSettings = interpolantSettings; this._interpolants = interpolants; // bound by the mixer - // inside: PropertyMixer (managed by the mixer) + // inside: PropertyMixer (managed by the mixer) this._propertyBindings = new Array(nTracks); this._cacheIndex = null; // for the memory manager - this._byClipCacheIndex = null; // for the memory manager this._timeScaleInterpolant = null; this._weightInterpolant = null; this.loop = LoopRepeat; - this._loopCount = -1; // global mixer time when the action is to be started + this._loopCount = -1; + + // global mixer time when the action is to be started // it's set back to 'null' upon start of the action + this._startTime = null; - this._startTime = null; // scaled local time of the action + // scaled local time of the action // gets clamped or wrapped to 0..clip.duration according to loop - this.time = 0; this.timeScale = 1; this._effectiveTimeScale = 1; @@ -32599,265 +29559,226 @@ this.repetitions = Infinity; // no. of repetitions when looping this.paused = false; // true -> zero effective time scale - this.enabled = true; // false -> zero effective weight this.clampWhenFinished = false; // keep feeding the last frame? this.zeroSlopeAtStart = true; // for smooth interpolation w/o separate - this.zeroSlopeAtEnd = true; // clips for start, loop and end - } // State & Scheduling + } + // State & Scheduling play() { this._mixer._activateAction(this); - return this; } - stop() { this._mixer._deactivateAction(this); - return this.reset(); } - reset() { this.paused = false; this.enabled = true; this.time = 0; // restart clip - this._loopCount = -1; // forget previous loops - this._startTime = null; // forget scheduling return this.stopFading().stopWarping(); } - isRunning() { return this.enabled && !this.paused && this.timeScale !== 0 && this._startTime === null && this._mixer._isActiveAction(this); - } // return true when play has been called - + } + // return true when play has been called isScheduled() { return this._mixer._isActiveAction(this); } - startAt(time) { this._startTime = time; return this; } - setLoop(mode, repetitions) { this.loop = mode; this.repetitions = repetitions; return this; - } // Weight + } + + // 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 - - setEffectiveWeight(weight) { - this.weight = weight; // note: same logic as when updated at runtime + 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 - + } + // return the weight considering fading and .enabled getEffectiveWeight() { return this._effectiveWeight; } - fadeIn(duration) { return this._scheduleFading(duration, 0, 1); } - fadeOut(duration) { return this._scheduleFading(duration, 1, 0); } - crossFadeFrom(fadeOutAction, duration, warp) { fadeOutAction.fadeOut(duration); this.fadeIn(duration); - if (warp) { const fadeInDuration = this._clip.duration, - fadeOutDuration = fadeOutAction._clip.duration, - startEndRatio = fadeOutDuration / fadeInDuration, - endStartRatio = fadeInDuration / fadeOutDuration; + fadeOutDuration = fadeOutAction._clip.duration, + startEndRatio = fadeOutDuration / fadeInDuration, + endStartRatio = fadeInDuration / fadeOutDuration; fadeOutAction.warp(1.0, startEndRatio, duration); this.warp(endStartRatio, 1.0, duration); } - return this; } - crossFadeTo(fadeInAction, duration, warp) { return fadeInAction.crossFadeFrom(this, duration, warp); } - stopFading() { const weightInterpolant = this._weightInterpolant; - if (weightInterpolant !== null) { this._weightInterpolant = null; - this._mixer._takeBackControlInterpolant(weightInterpolant); } - return this; - } // Time Scale Control + } + + // 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 - - setEffectiveTimeScale(timeScale) { this.timeScale = timeScale; this._effectiveTimeScale = this.paused ? 0 : timeScale; return this.stopWarping(); - } // return the time scale considering warping and .paused - + } + // return the time scale considering warping and .paused getEffectiveTimeScale() { return this._effectiveTimeScale; } - setDuration(duration) { this.timeScale = this._clip.duration / duration; return this.stopWarping(); } - syncWith(action) { this.time = action.time; this.timeScale = action.timeScale; return this.stopWarping(); } - halt(duration) { return this.warp(this._effectiveTimeScale, 0, duration); } - warp(startTimeScale, endTimeScale, duration) { const mixer = this._mixer, - now = mixer.time, - timeScale = this.timeScale; + now = mixer.time, + timeScale = this.timeScale; let interpolant = this._timeScaleInterpolant; - if (interpolant === null) { interpolant = mixer._lendControlInterpolant(); this._timeScaleInterpolant = interpolant; } - const times = interpolant.parameterPositions, - values = interpolant.sampleValues; + values = interpolant.sampleValues; times[0] = now; times[1] = now + duration; values[0] = startTimeScale / timeScale; values[1] = endTimeScale / timeScale; return this; } - stopWarping() { const timeScaleInterpolant = this._timeScaleInterpolant; - if (timeScaleInterpolant !== null) { this._timeScaleInterpolant = null; - this._mixer._takeBackControlInterpolant(timeScaleInterpolant); } - return this; - } // Object Accessors + } + // Object Accessors getMixer() { return this._mixer; } - getClip() { return this._clip; } - getRoot() { return this._localRoot || this._mixer._root; - } // Interna + } + // Interna _update(time, deltaTime, timeDirection, accuIndex) { // called by the mixer + if (!this.enabled) { // call ._updateWeight() to update ._effectiveWeight - this._updateWeight(time); + this._updateWeight(time); return; } - const startTime = this._startTime; - if (startTime !== null) { // check for scheduled start of action - const timeRunning = (time - startTime) * timeDirection; + const timeRunning = (time - startTime) * timeDirection; if (timeRunning < 0 || timeDirection === 0) { - return; // yet to come / don't decide when delta = 0 - } // start - - - this._startTime = null; // unschedule - - deltaTime = timeDirection * timeRunning; - } // apply time scale and advance time + deltaTime = 0; + } else { + this._startTime = null; // unschedule + deltaTime = timeDirection * timeRunning; + } + } + // apply time scale and advance time deltaTime *= this._updateTimeScale(time); + const clipTime = this._updateTime(deltaTime); - const clipTime = this._updateTime(deltaTime); // note: _updateTime may disable the action resulting in + // note: _updateTime may disable the action resulting in // an effective weight of 0 - const weight = this._updateWeight(time); - if (weight > 0) { const interpolants = this._interpolants; const propertyMixers = this._propertyBindings; - switch (this.blendMode) { case AdditiveAnimationBlendMode: for (let j = 0, m = interpolants.length; j !== m; ++j) { interpolants[j].evaluate(clipTime); propertyMixers[j].accumulateAdditive(weight); } - break; - case NormalAnimationBlendMode: default: for (let j = 0, m = interpolants.length; j !== m; ++j) { interpolants[j].evaluate(clipTime); propertyMixers[j].accumulate(accuIndex, weight); } - } } } - _updateWeight(time) { let weight = 0; - if (this.enabled) { weight = this.weight; const interpolant = this._weightInterpolant; - if (interpolant !== null) { const interpolantValue = interpolant.evaluate(time)[0]; weight *= interpolantValue; - if (time > interpolant.parameterPositions[1]) { this.stopFading(); - if (interpolantValue === 0) { // faded out, disable this.enabled = false; @@ -32865,25 +29786,19 @@ } } } - this._effectiveWeight = weight; return weight; } - _updateTimeScale(time) { let timeScale = 0; - if (!this.paused) { timeScale = this.timeScale; const interpolant = this._timeScaleInterpolant; - if (interpolant !== null) { const interpolantValue = interpolant.evaluate(time)[0]; timeScale *= interpolantValue; - if (time > interpolant.parameterPositions[1]) { this.stopWarping(); - if (timeScale === 0) { // motion has halted, pause this.paused = true; @@ -32894,31 +29809,26 @@ } } } - this._effectiveTimeScale = timeScale; return timeScale; } - _updateTime(deltaTime) { const duration = this._clip.duration; const loop = this.loop; let time = this.time + deltaTime; let loopCount = this._loopCount; const pingPong = loop === LoopPingPong; - if (deltaTime === 0) { if (loopCount === -1) return time; return pingPong && (loopCount & 1) === 1 ? duration - time : time; } - if (loop === LoopOnce) { if (loopCount === -1) { // just started - this._loopCount = 0; + this._loopCount = 0; this._setEndings(true, true, false); } - handle_stop: { if (time >= duration) { time = duration; @@ -32928,10 +29838,8 @@ this.time = time; break handle_stop; } - if (this.clampWhenFinished) this.paused = true;else this.enabled = false; this.time = time; - this._mixer.dispatchEvent({ type: 'finished', action: this, @@ -32940,34 +29848,34 @@ } } else { // repetitive Repeat or PingPong + if (loopCount === -1) { // just started + if (deltaTime >= 0) { loopCount = 0; - 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); } } - if (time >= duration || time < 0) { // wrap around - const loopDelta = Math.floor(time / duration); // signed + const loopDelta = Math.floor(time / duration); // signed time -= duration * loopDelta; loopCount += Math.abs(loopDelta); const 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, @@ -32975,18 +29883,17 @@ }); } else { // keep running + if (pending === 1) { // entering the last round - const atStart = deltaTime < 0; + const atStart = deltaTime < 0; this._setEndings(atStart, !atStart, pingPong); } else { this._setEndings(false, false, pingPong); } - this._loopCount = loopCount; this.time = time; - this._mixer.dispatchEvent({ type: 'loop', action: this, @@ -32996,30 +29903,27 @@ } else { this.time = time; } - if (pingPong && (loopCount & 1) === 1) { // invert time for the "pong round" + return duration - time; } } - return time; } - _setEndings(atStart, atEnd, pingPong) { const settings = this._interpolantSettings; - 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; } - if (atEnd) { settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding; } else { @@ -33027,158 +29931,132 @@ } } } - _scheduleFading(duration, weightNow, weightThen) { const mixer = this._mixer, - now = mixer.time; + now = mixer.time; let interpolant = this._weightInterpolant; - if (interpolant === null) { interpolant = mixer._lendControlInterpolant(); this._weightInterpolant = interpolant; } - const times = interpolant.parameterPositions, - values = interpolant.sampleValues; + values = interpolant.sampleValues; times[0] = now; values[0] = weightNow; times[1] = now + duration; values[1] = weightThen; return this; } - } const _controlInterpolantsResultBuffer = new Float32Array(1); - class AnimationMixer extends EventDispatcher { constructor(root) { super(); this._root = root; - this._initMemoryManager(); - this._accuIndex = 0; this.time = 0; this.timeScale = 1.0; } - _bindAction(action, prototypeAction) { const root = action._localRoot || this._root, - tracks = action._clip.tracks, - nTracks = tracks.length, - bindings = action._propertyBindings, - interpolants = action._interpolants, - rootUuid = root.uuid, - bindingsByRoot = this._bindingsByRootAndName; + tracks = action._clip.tracks, + nTracks = tracks.length, + bindings = action._propertyBindings, + interpolants = action._interpolants, + rootUuid = root.uuid, + bindingsByRoot = this._bindingsByRootAndName; let bindingsByName = bindingsByRoot[rootUuid]; - if (bindingsByName === undefined) { bindingsByName = {}; bindingsByRoot[rootUuid] = bindingsByName; } - for (let i = 0; i !== nTracks; ++i) { const track = tracks[i], - trackName = track.name; + trackName = track.name; let binding = bindingsByName[trackName]; - if (binding !== undefined) { ++binding.referenceCount; bindings[i] = binding; } else { binding = bindings[i]; - if (binding !== undefined) { // existing binding, make sure the cache knows + if (binding._cacheIndex === null) { ++binding.referenceCount; - this._addInactiveBinding(binding, rootUuid, trackName); } - continue; } - const path = prototypeAction && prototypeAction._propertyBindings[i].binding.parsedPath; binding = new PropertyMixer(PropertyBinding.create(root, trackName, path), track.ValueTypeName, track.getValueSize()); ++binding.referenceCount; - this._addInactiveBinding(binding, rootUuid, trackName); - bindings[i] = binding; } - interpolants[i].resultBuffer = binding.buffer; } } - _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 - const rootUuid = (action._localRoot || this._root).uuid, - clipUuid = action._clip.uuid, - actionsForClip = this._actionsByClip[clipUuid]; + const 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); } + const bindings = action._propertyBindings; - const bindings = action._propertyBindings; // increment reference counts / sort out state - + // increment reference counts / sort out state for (let i = 0, n = bindings.length; i !== n; ++i) { const binding = bindings[i]; - if (binding.useCount++ === 0) { this._lendBinding(binding); - binding.saveOriginalState(); } } - this._lendAction(action); } } - _deactivateAction(action) { if (this._isActiveAction(action)) { - const bindings = action._propertyBindings; // decrement reference counts / sort out state + const bindings = action._propertyBindings; + // decrement reference counts / sort out state for (let i = 0, n = bindings.length; i !== n; ++i) { const binding = bindings[i]; - if (--binding.useCount === 0) { binding.restoreOriginalState(); - this._takeBackBinding(binding); } } - this._takeBackAction(action); } - } // Memory manager + } + // Memory manager _initMemoryManager() { this._actions = []; // 'nActiveActions' followed by inactive ones - this._nActiveActions = 0; - this._actionsByClip = {}; // inside: + this._actionsByClip = {}; + // inside: // { // knownActions: Array< AnimationAction > - used as prototypes // actionByRoot: AnimationAction - lookup // } this._bindings = []; // 'nActiveBindings' followed by inactive ones - this._nActiveBindings = 0; this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer > this._controlInterpolants = []; // same game as above - this._nActiveControlInterpolants = 0; const scope = this; this.stats = { @@ -33186,46 +30064,39 @@ get total() { return scope._actions.length; }, - get inUse() { return scope._nActiveActions; } - }, bindings: { get total() { return scope._bindings.length; }, - get inUse() { return scope._nActiveBindings; } - }, controlInterpolants: { get total() { return scope._controlInterpolants.length; }, - get inUse() { return scope._nActiveControlInterpolants; } - } }; - } // Memory management for AnimationAction objects + } + // Memory management for AnimationAction objects _isActiveAction(action) { const index = action._cacheIndex; return index !== null && index < this._nActiveActions; } - _addInactiveAction(action, clipUuid, rootUuid) { const actions = this._actions, - actionsByClip = this._actionsByClip; + actionsByClip = this._actionsByClip; let actionsForClip = actionsByClip[clipUuid]; - if (actionsForClip === undefined) { actionsForClip = { knownActions: [action], @@ -33238,179 +30109,164 @@ action._byClipCacheIndex = knownActions.length; knownActions.push(action); } - action._cacheIndex = actions.length; actions.push(action); actionsForClip.actionByRoot[rootUuid] = action; } - _removeInactiveAction(action) { const actions = this._actions, - lastInactiveAction = actions[actions.length - 1], - cacheIndex = action._cacheIndex; + lastInactiveAction = actions[actions.length - 1], + cacheIndex = action._cacheIndex; lastInactiveAction._cacheIndex = cacheIndex; actions[cacheIndex] = lastInactiveAction; actions.pop(); action._cacheIndex = null; const clipUuid = action._clip.uuid, - actionsByClip = this._actionsByClip, - actionsForClip = actionsByClip[clipUuid], - knownActionsForClip = actionsForClip.knownActions, - lastKnownAction = knownActionsForClip[knownActionsForClip.length - 1], - byClipCacheIndex = action._byClipCacheIndex; + 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; const actionByRoot = actionsForClip.actionByRoot, - rootUuid = (action._localRoot || this._root).uuid; + rootUuid = (action._localRoot || this._root).uuid; delete actionByRoot[rootUuid]; - if (knownActionsForClip.length === 0) { delete actionsByClip[clipUuid]; } - this._removeInactiveBindingsForAction(action); } - _removeInactiveBindingsForAction(action) { const bindings = action._propertyBindings; - for (let i = 0, n = bindings.length; i !== n; ++i) { const binding = bindings[i]; - if (--binding.referenceCount === 0) { this._removeInactiveBinding(binding); } } } - _lendAction(action) { // [ active actions | inactive actions ] // [ active actions >| inactive actions ] // s a // <-swap-> // a s + const actions = this._actions, - prevIndex = action._cacheIndex, - lastActiveIndex = this._nActiveActions++, - firstInactiveAction = actions[lastActiveIndex]; + prevIndex = action._cacheIndex, + lastActiveIndex = this._nActiveActions++, + firstInactiveAction = actions[lastActiveIndex]; action._cacheIndex = lastActiveIndex; actions[lastActiveIndex] = action; firstInactiveAction._cacheIndex = prevIndex; actions[prevIndex] = firstInactiveAction; } - _takeBackAction(action) { // [ active actions | inactive actions ] // [ active actions |< inactive actions ] // a s // <-swap-> // s a + const actions = this._actions, - prevIndex = action._cacheIndex, - firstInactiveIndex = --this._nActiveActions, - lastActiveAction = actions[firstInactiveIndex]; + 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 + } + // Memory management for PropertyMixer objects _addInactiveBinding(binding, rootUuid, trackName) { const bindingsByRoot = this._bindingsByRootAndName, - bindings = this._bindings; + bindings = this._bindings; let bindingByName = bindingsByRoot[rootUuid]; - if (bindingByName === undefined) { bindingByName = {}; bindingsByRoot[rootUuid] = bindingByName; } - bindingByName[trackName] = binding; binding._cacheIndex = bindings.length; bindings.push(binding); } - _removeInactiveBinding(binding) { const 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; + 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(binding) { const bindings = this._bindings, - prevIndex = binding._cacheIndex, - lastActiveIndex = this._nActiveBindings++, - firstInactiveBinding = bindings[lastActiveIndex]; + prevIndex = binding._cacheIndex, + lastActiveIndex = this._nActiveBindings++, + firstInactiveBinding = bindings[lastActiveIndex]; binding._cacheIndex = lastActiveIndex; bindings[lastActiveIndex] = binding; firstInactiveBinding._cacheIndex = prevIndex; bindings[prevIndex] = firstInactiveBinding; } - _takeBackBinding(binding) { const bindings = this._bindings, - prevIndex = binding._cacheIndex, - firstInactiveIndex = --this._nActiveBindings, - lastActiveBinding = bindings[firstInactiveIndex]; + 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 + } + // Memory management of Interpolants for weight and time scale _lendControlInterpolant() { const interpolants = this._controlInterpolants, - lastActiveIndex = this._nActiveControlInterpolants++; + lastActiveIndex = this._nActiveControlInterpolants++; let interpolant = interpolants[lastActiveIndex]; - if (interpolant === undefined) { interpolant = new LinearInterpolant(new Float32Array(2), new Float32Array(2), 1, _controlInterpolantsResultBuffer); interpolant.__cacheIndex = lastActiveIndex; interpolants[lastActiveIndex] = interpolant; } - return interpolant; } - _takeBackControlInterpolant(interpolant) { const interpolants = this._controlInterpolants, - prevIndex = interpolant.__cacheIndex, - firstInactiveIndex = --this._nActiveControlInterpolants, - lastActiveInterpolant = interpolants[firstInactiveIndex]; + prevIndex = interpolant.__cacheIndex, + firstInactiveIndex = --this._nActiveControlInterpolants, + lastActiveInterpolant = interpolants[firstInactiveIndex]; interpolant.__cacheIndex = firstInactiveIndex; interpolants[firstInactiveIndex] = interpolant; lastActiveInterpolant.__cacheIndex = prevIndex; interpolants[prevIndex] = lastActiveInterpolant; - } // return an action for a clip optionally using a custom root target + } + + // 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(clip, optionalRoot, blendMode) { const root = optionalRoot || this._root, - rootUuid = root.uuid; + rootUuid = root.uuid; let clipObject = typeof clip === 'string' ? AnimationClip.findByName(root, clip) : clip; const clipUuid = clipObject !== null ? clipObject.uuid : clip; const actionsForClip = this._actionsByClip[clipUuid]; let prototypeAction = null; - if (blendMode === undefined) { if (clipObject !== null) { blendMode = clipObject.blendMode; @@ -33418,196 +30274,167 @@ blendMode = NormalAnimationBlendMode; } } - if (actionsForClip !== undefined) { const existingAction = actionsForClip.actionByRoot[rootUuid]; - 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 - + } - prototypeAction = actionsForClip.knownActions[0]; // also, take the clip from the prototype action + // we know the clip, so we don't have to parse all + // the bindings again but can just copy + prototypeAction = actionsForClip.knownActions[0]; + // also, take the clip from the prototype action if (clipObject === null) clipObject = prototypeAction._clip; - } // clip must be known when specified via string - + } - if (clipObject === null) return null; // allocate all resources required to run it + // clip must be known when specified via string + if (clipObject === null) return null; + // allocate all resources required to run it const newAction = new AnimationAction(this, clipObject, optionalRoot, blendMode); + this._bindAction(newAction, prototypeAction); - this._bindAction(newAction, prototypeAction); // and make the action known to the memory manager - - + // and make the action known to the memory manager this._addInactiveAction(newAction, clipUuid, rootUuid); - return newAction; - } // get an existing action - + } + // get an existing action existingAction(clip, optionalRoot) { const 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]; - + rootUuid = root.uuid, + clipObject = typeof clip === 'string' ? AnimationClip.findByName(root, clip) : clip, + clipUuid = clipObject ? clipObject.uuid : clip, + actionsForClip = this._actionsByClip[clipUuid]; if (actionsForClip !== undefined) { return actionsForClip.actionByRoot[rootUuid] || null; } - return null; - } // deactivates all previously scheduled actions - + } + // deactivates all previously scheduled actions stopAllAction() { const actions = this._actions, - nActions = this._nActiveActions; - + nActions = this._nActiveActions; for (let i = nActions - 1; i >= 0; --i) { actions[i].stop(); } - return this; - } // advance the time and update apply the animation - + } + // advance the time and update apply the animation update(deltaTime) { deltaTime *= this.timeScale; const actions = this._actions, - nActions = this._nActiveActions, - time = this.time += deltaTime, - timeDirection = Math.sign(deltaTime), - accuIndex = this._accuIndex ^= 1; // run active actions + nActions = this._nActiveActions, + time = this.time += deltaTime, + timeDirection = Math.sign(deltaTime), + accuIndex = this._accuIndex ^= 1; + + // run active actions for (let i = 0; i !== nActions; ++i) { const action = actions[i]; - action._update(time, deltaTime, timeDirection, accuIndex); - } // update scene graph + } + // update scene graph const bindings = this._bindings, - nBindings = this._nActiveBindings; - + nBindings = this._nActiveBindings; for (let i = 0; i !== nBindings; ++i) { bindings[i].apply(accuIndex); } - return this; - } // Allows you to seek to a specific time in an animation. - + } + // Allows you to seek to a specific time in an animation. setTime(timeInSeconds) { this.time = 0; // Zero out time attribute for AnimationMixer object; - for (let i = 0; i < this._actions.length; i++) { this._actions[i].time = 0; // Zero out time attribute for all associated AnimationAction objects. } return this.update(timeInSeconds); // Update used to set exact time. Returns "this" AnimationMixer object. - } // return this mixer's root target object - + } + // return this mixer's root target object getRoot() { return this._root; - } // free all resources specific to a particular clip - + } + // free all resources specific to a particular clip uncacheClip(clip) { const actions = this._actions, - clipUuid = clip.uuid, - actionsByClip = this._actionsByClip, - actionsForClip = actionsByClip[clipUuid]; - + 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 - const actionsToRemove = actionsForClip.knownActions; + const actionsToRemove = actionsForClip.knownActions; for (let i = 0, n = actionsToRemove.length; i !== n; ++i) { const action = actionsToRemove[i]; - this._deactivateAction(action); - const cacheIndex = action._cacheIndex, - lastInactiveAction = actions[actions.length - 1]; + 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 - + } + // free all resources specific to a particular root target object uncacheRoot(root) { const rootUuid = root.uuid, - actionsByClip = this._actionsByClip; - + actionsByClip = this._actionsByClip; for (const clipUuid in actionsByClip) { const actionByRoot = actionsByClip[clipUuid].actionByRoot, - action = actionByRoot[rootUuid]; - + action = actionByRoot[rootUuid]; if (action !== undefined) { this._deactivateAction(action); - this._removeInactiveAction(action); } } - const bindingsByRoot = this._bindingsByRootAndName, - bindingByName = bindingsByRoot[rootUuid]; - + bindingByName = bindingsByRoot[rootUuid]; if (bindingByName !== undefined) { for (const trackName in bindingByName) { const binding = bindingByName[trackName]; binding.restoreOriginalState(); - this._removeInactiveBinding(binding); } } - } // remove a targeted clip from the cache - + } + // remove a targeted clip from the cache uncacheAction(clip, optionalRoot) { const action = this.existingAction(clip, optionalRoot); - if (action !== null) { this._deactivateAction(action); - this._removeInactiveAction(action); } } - } class Uniform { constructor(value) { - if (typeof value === 'string') { - console.warn('THREE.Uniform: Type parameter is no longer needed.'); - value = arguments[1]; - } - this.value = value; } - clone() { return new Uniform(this.value.clone === undefined ? this.value : this.value.clone()); } - } let id = 0; - class UniformsGroup extends EventDispatcher { constructor() { super(); @@ -33619,52 +30446,42 @@ this.usage = StaticDrawUsage; this.uniforms = []; } - add(uniform) { this.uniforms.push(uniform); return this; } - remove(uniform) { const index = this.uniforms.indexOf(uniform); if (index !== -1) this.uniforms.splice(index, 1); return this; } - setName(name) { this.name = name; return this; } - setUsage(value) { this.usage = value; return this; } - dispose() { this.dispatchEvent({ type: 'dispose' }); return this; } - copy(source) { this.name = source.name; this.usage = source.usage; const uniformsSource = source.uniforms; this.uniforms.length = 0; - for (let i = 0, l = uniformsSource.length; i < l; i++) { this.uniforms.push(uniformsSource[i].clone()); } - return this; } - clone() { return new this.constructor().copy(this); } - } class InstancedInterleavedBuffer extends InterleavedBuffer { @@ -33673,26 +30490,22 @@ this.isInstancedInterleavedBuffer = true; this.meshPerAttribute = meshPerAttribute; } - copy(source) { super.copy(source); this.meshPerAttribute = source.meshPerAttribute; return this; } - clone(data) { const ib = super.clone(data); ib.meshPerAttribute = this.meshPerAttribute; return ib; } - toJSON(data) { const json = super.toJSON(data); json.isInstancedInterleavedBuffer = true; json.meshPerAttribute = this.meshPerAttribute; return json; } - } class GLBufferAttribute { @@ -33705,37 +30518,32 @@ this.count = count; this.version = 0; } - set needsUpdate(value) { if (value === true) this.version++; } - setBuffer(buffer) { this.buffer = buffer; return this; } - setType(type, elementSize) { this.type = type; this.elementSize = elementSize; return this; } - setItemSize(itemSize) { this.itemSize = itemSize; return this; } - setCount(count) { this.count = count; return this; } - } class Raycaster { constructor(origin, direction, near = 0, far = Infinity) { - this.ray = new Ray(origin, direction); // direction is assumed to be normalized (for accurate distance calculations) + this.ray = new Ray(origin, direction); + // direction is assumed to be normalized (for accurate distance calculations) this.near = near; this.far = far; @@ -33753,12 +30561,11 @@ Sprite: {} }; } - set(origin, direction) { // direction is assumed to be normalized (for accurate distance calculations) + this.ray.set(origin, direction); } - setFromCamera(coords, camera) { if (camera.isPerspectiveCamera) { this.ray.origin.setFromMatrixPosition(camera.matrixWorld); @@ -33766,43 +30573,34 @@ this.camera = camera; } else if (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: ' + camera.type); } } - intersectObject(object, recursive = true, intersects = []) { intersectObject(object, this, intersects, recursive); intersects.sort(ascSort); return intersects; } - intersectObjects(objects, recursive = true, intersects = []) { for (let i = 0, l = objects.length; i < l; i++) { intersectObject(objects[i], this, intersects, recursive); } - intersects.sort(ascSort); return intersects; } - } - 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); } - if (recursive === true) { const children = object.children; - for (let i = 0, l = children.length; i < l; i++) { intersectObject(children[i], raycaster, intersects, true); } @@ -33815,45 +30613,38 @@ * 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. */ - class Spherical { constructor(radius = 1, phi = 0, theta = 0) { this.radius = radius; this.phi = phi; // polar angle - this.theta = theta; // azimuthal angle return this; } - set(radius, phi, theta) { this.radius = radius; this.phi = phi; this.theta = theta; return this; } - copy(other) { this.radius = other.radius; this.phi = other.phi; this.theta = other.theta; return this; - } // restrict phi to be between EPS and PI-EPS - + } + // restrict phi to be between EPS and PI-EPS makeSafe() { const EPS = 0.000001; this.phi = Math.max(EPS, Math.min(Math.PI - EPS, this.phi)); return this; } - setFromVector3(v) { return this.setFromCartesianCoords(v.x, v.y, v.z); } - setFromCartesianCoords(x, y, z) { this.radius = Math.sqrt(x * x + y * y + z * z); - if (this.radius === 0) { this.theta = 0; this.phi = 0; @@ -33861,294 +30652,235 @@ this.theta = Math.atan2(x, z); this.phi = Math.acos(clamp(y / this.radius, -1, 1)); } - return this; } - clone() { return new this.constructor().copy(this); } - } /** * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system */ + class Cylindrical { constructor(radius = 1, theta = 0, y = 0) { this.radius = radius; // distance from the origin to a point in the x-z plane - this.theta = theta; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis - this.y = y; // height above the x-z plane return this; } - set(radius, theta, y) { this.radius = radius; this.theta = theta; this.y = y; return this; } - copy(other) { this.radius = other.radius; this.theta = other.theta; this.y = other.y; return this; } - setFromVector3(v) { return this.setFromCartesianCoords(v.x, v.y, v.z); } - setFromCartesianCoords(x, y, z) { this.radius = Math.sqrt(x * x + z * z); this.theta = Math.atan2(x, z); this.y = y; return this; } - clone() { return new this.constructor().copy(this); } - } const _vector$4 = /*@__PURE__*/new Vector2(); - class Box2 { constructor(min = new Vector2(+Infinity, +Infinity), max = new Vector2(-Infinity, -Infinity)) { this.isBox2 = true; this.min = min; this.max = max; } - set(min, max) { this.min.copy(min); this.max.copy(max); return this; } - setFromPoints(points) { this.makeEmpty(); - for (let i = 0, il = points.length; i < il; i++) { this.expandByPoint(points[i]); } - return this; } - setFromCenterAndSize(center, size) { const halfSize = _vector$4.copy(size).multiplyScalar(0.5); - this.min.copy(center).sub(halfSize); this.max.copy(center).add(halfSize); return this; } - clone() { return new this.constructor().copy(this); } - copy(box) { this.min.copy(box.min); this.max.copy(box.max); return this; } - makeEmpty() { this.min.x = this.min.y = +Infinity; this.max.x = this.max.y = -Infinity; return this; } - 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; } - getCenter(target) { return this.isEmpty() ? target.set(0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5); } - getSize(target) { return this.isEmpty() ? target.set(0, 0) : target.subVectors(this.max, this.min); } - expandByPoint(point) { this.min.min(point); this.max.max(point); return this; } - expandByVector(vector) { this.min.sub(vector); this.max.add(vector); return this; } - expandByScalar(scalar) { this.min.addScalar(-scalar); this.max.addScalar(scalar); return this; } - 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; } - 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; } - getParameter(point, target) { // This can potentially have a divide by zero if the box // has a size dimension of 0. + 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)); } - 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; } - clampPoint(point, target) { return target.copy(point).clamp(this.min, this.max); } - distanceToPoint(point) { const clampedPoint = _vector$4.copy(point).clamp(this.min, this.max); - return clampedPoint.sub(point).length(); } - intersect(box) { this.min.max(box.min); this.max.min(box.max); return this; } - union(box) { this.min.min(box.min); this.max.max(box.max); return this; } - translate(offset) { this.min.add(offset); this.max.add(offset); return this; } - equals(box) { return box.min.equals(this.min) && box.max.equals(this.max); } - } const _startP = /*@__PURE__*/new Vector3(); - const _startEnd = /*@__PURE__*/new Vector3(); - class Line3 { constructor(start = new Vector3(), end = new Vector3()) { this.start = start; this.end = end; } - set(start, end) { this.start.copy(start); this.end.copy(end); return this; } - copy(line) { this.start.copy(line.start); this.end.copy(line.end); return this; } - getCenter(target) { return target.addVectors(this.start, this.end).multiplyScalar(0.5); } - delta(target) { return target.subVectors(this.end, this.start); } - distanceSq() { return this.start.distanceToSquared(this.end); } - distance() { return this.start.distanceTo(this.end); } - at(t, target) { return this.delta(target).multiplyScalar(t).add(this.start); } - closestPointToPointParameter(point, clampToLine) { _startP.subVectors(point, this.start); - _startEnd.subVectors(this.end, this.start); - const startEnd2 = _startEnd.dot(_startEnd); - const startEnd_startP = _startEnd.dot(_startP); - let t = startEnd_startP / startEnd2; - if (clampToLine) { t = clamp(t, 0, 1); } - return t; } - closestPointToPoint(point, clampToLine, target) { const t = this.closestPointToPointParameter(point, clampToLine); return this.delta(target).multiplyScalar(t).add(this.start); } - applyMatrix4(matrix) { this.start.applyMatrix4(matrix); this.end.applyMatrix4(matrix); return this; } - equals(line) { return line.start.equals(this.start) && line.end.equals(this.end); } - clone() { return new this.constructor().copy(this); } - } const _vector$3 = /*@__PURE__*/new Vector3(); - class SpotLightHelper extends Object3D { constructor(light, color) { super(); this.light = light; - this.light.updateMatrixWorld(); this.matrix = light.matrixWorld; this.matrixAutoUpdate = false; this.color = color; + this.type = 'SpotLightHelper'; const geometry = new BufferGeometry(); const 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 (let i = 0, j = 1, l = 32; i < l; i++, j++) { const p1 = i / l * Math.PI * 2; const p2 = j / l * Math.PI * 2; positions.push(Math.cos(p1), Math.sin(p1), 1, Math.cos(p2), Math.sin(p2), 1); } - geometry.setAttribute('position', new Float32BufferAttribute(positions, 3)); const material = new LineBasicMaterial({ fog: false, @@ -34158,37 +30890,29 @@ this.add(this.cone); this.update(); } - dispose() { this.cone.geometry.dispose(); this.cone.material.dispose(); } - update() { - this.light.updateMatrixWorld(); + this.light.updateWorldMatrix(true, false); + this.light.target.updateWorldMatrix(true, false); const coneLength = this.light.distance ? this.light.distance : 1000; const coneWidth = coneLength * Math.tan(this.light.angle); this.cone.scale.set(coneWidth, coneWidth, coneLength); - _vector$3.setFromMatrixPosition(this.light.target.matrixWorld); - this.cone.lookAt(_vector$3); - if (this.color !== undefined) { this.cone.material.color.set(this.color); } else { this.cone.material.color.copy(this.light.color); } } - } const _vector$2 = /*@__PURE__*/new Vector3(); - const _boneMatrix = /*@__PURE__*/new Matrix4(); - const _matrixWorldInv = /*@__PURE__*/new Matrix4(); - class SkeletonHelper extends LineSegments { constructor(object) { const bones = getBoneList(object); @@ -34197,10 +30921,8 @@ const colors = []; const color1 = new Color(0, 0, 1); const color2 = new Color(0, 1, 0); - for (let i = 0; i < bones.length; i++) { const bone = bones[i]; - if (bone.parent && bone.parent.isBone) { vertices.push(0, 0, 0); vertices.push(0, 0, 0); @@ -34208,7 +30930,6 @@ colors.push(color2.r, color2.g, color2.b); } } - geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); const material = new LineBasicMaterial({ @@ -34226,50 +30947,39 @@ this.matrix = object.matrixWorld; this.matrixAutoUpdate = false; } - updateMatrixWorld(force) { const bones = this.bones; const geometry = this.geometry; const position = geometry.getAttribute('position'); - _matrixWorldInv.copy(this.root.matrixWorld).invert(); - for (let i = 0, j = 0; i < bones.length; i++) { const bone = bones[i]; - if (bone.parent && bone.parent.isBone) { _boneMatrix.multiplyMatrices(_matrixWorldInv, bone.matrixWorld); - _vector$2.setFromMatrixPosition(_boneMatrix); - position.setXYZ(j, _vector$2.x, _vector$2.y, _vector$2.z); - _boneMatrix.multiplyMatrices(_matrixWorldInv, bone.parent.matrixWorld); - _vector$2.setFromMatrixPosition(_boneMatrix); - position.setXYZ(j + 1, _vector$2.x, _vector$2.y, _vector$2.z); j += 2; } } - geometry.getAttribute('position').needsUpdate = true; super.updateMatrixWorld(force); } - + dispose() { + this.geometry.dispose(); + this.material.dispose(); + } } - function getBoneList(object) { const boneList = []; - if (object.isBone === true) { boneList.push(object); } - for (let i = 0; i < object.children.length; i++) { boneList.push.apply(boneList, getBoneList(object.children[i])); } - return boneList; } @@ -34283,12 +30993,12 @@ }); super(geometry, material); 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.IcosahedronGeometry( 1, 2 ); @@ -34309,13 +31019,14 @@ this.geometry.dispose(); this.material.dispose(); } - update() { + this.light.updateWorldMatrix(true, false); 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 ) { @@ -34325,25 +31036,20 @@ this.lightDistance.scale.set( d, d, d ); } */ - } - } const _vector$1 = /*@__PURE__*/new Vector3(); - const _color1 = /*@__PURE__*/new Color(); - const _color2 = /*@__PURE__*/new Color(); - class HemisphereLightHelper extends Object3D { constructor(light, size, color) { super(); this.light = light; - this.light.updateMatrixWorld(); this.matrix = light.matrixWorld; this.matrixAutoUpdate = false; this.color = color; + this.type = 'HemisphereLightHelper'; const geometry = new OctahedronGeometry(size); geometry.rotateY(Math.PI * 0.5); this.material = new MeshBasicMaterial({ @@ -34358,35 +31064,27 @@ this.add(new Mesh(geometry, this.material)); this.update(); } - dispose() { this.children[0].geometry.dispose(); this.children[0].material.dispose(); } - update() { const mesh = this.children[0]; - if (this.color !== undefined) { this.material.color.set(this.color); } else { const colors = mesh.geometry.getAttribute('color'); - _color1.copy(this.light.color); - _color2.copy(this.light.groundColor); - for (let i = 0, l = colors.count; i < l; i++) { const color = i < l / 2 ? _color1 : _color2; colors.setXYZ(i, color.r, color.g, color.b); } - colors.needsUpdate = true; } - + this.light.updateWorldMatrix(true, false); mesh.lookAt(_vector$1.setFromMatrixPosition(this.light.matrixWorld).negate()); } - } class GridHelper extends LineSegments { @@ -34397,8 +31095,7 @@ const step = size / divisions; const halfSize = size / 2; const vertices = [], - colors = []; - + colors = []; for (let 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); @@ -34412,7 +31109,6 @@ color.toArray(colors, j); j += 3; } - const geometry = new BufferGeometry(); geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); @@ -34423,39 +31119,49 @@ super(geometry, material); this.type = 'GridHelper'; } - + dispose() { + this.geometry.dispose(); + this.material.dispose(); + } } class PolarGridHelper extends LineSegments { - constructor(radius = 10, radials = 16, circles = 8, divisions = 64, color1 = 0x444444, color2 = 0x888888) { + constructor(radius = 10, sectors = 16, rings = 8, divisions = 64, color1 = 0x444444, color2 = 0x888888) { color1 = new Color(color1); color2 = new Color(color2); const vertices = []; - const colors = []; // create the radials + const colors = []; - for (let i = 0; i <= radials; i++) { - const v = i / radials * (Math.PI * 2); - const x = Math.sin(v) * radius; - const z = Math.cos(v) * radius; - vertices.push(0, 0, 0); - vertices.push(x, 0, z); - const color = i & 1 ? color1 : color2; - colors.push(color.r, color.g, color.b); - colors.push(color.r, color.g, color.b); - } // create the circles + // create the sectors + + if (sectors > 1) { + for (let i = 0; i < sectors; i++) { + const v = i / sectors * (Math.PI * 2); + const x = Math.sin(v) * radius; + const z = Math.cos(v) * radius; + vertices.push(0, 0, 0); + vertices.push(x, 0, z); + const color = i & 1 ? color1 : color2; + colors.push(color.r, color.g, color.b); + colors.push(color.r, color.g, color.b); + } + } + // create the rings - for (let i = 0; i <= circles; i++) { + for (let i = 0; i < rings; i++) { const color = i & 1 ? color1 : color2; - const r = radius - radius / circles * i; - + const r = radius - radius / rings * i; for (let j = 0; j < divisions; j++) { // first vertex + let v = j / divisions * (Math.PI * 2); let x = Math.sin(v) * r; let z = Math.cos(v) * r; vertices.push(x, 0, z); - colors.push(color.r, color.g, color.b); // second vertex + colors.push(color.r, color.g, color.b); + + // second vertex v = (j + 1) / divisions * (Math.PI * 2); x = Math.sin(v) * r; @@ -34464,7 +31170,6 @@ colors.push(color.r, color.g, color.b); } } - const geometry = new BufferGeometry(); geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); @@ -34475,23 +31180,23 @@ super(geometry, material); this.type = 'PolarGridHelper'; } - + dispose() { + this.geometry.dispose(); + this.material.dispose(); + } } const _v1 = /*@__PURE__*/new Vector3(); - const _v2 = /*@__PURE__*/new Vector3(); - const _v3 = /*@__PURE__*/new Vector3(); - class DirectionalLightHelper extends Object3D { constructor(light, size, color) { super(); this.light = light; - this.light.updateMatrixWorld(); this.matrix = light.matrixWorld; this.matrixAutoUpdate = false; this.color = color; + this.type = 'DirectionalLightHelper'; if (size === undefined) size = 1; let geometry = new BufferGeometry(); geometry.setAttribute('position', new Float32BufferAttribute([-size, size, 0, size, size, 0, size, -size, 0, -size, -size, 0, -size, size, 0], 3)); @@ -34507,23 +31212,19 @@ this.add(this.targetLine); this.update(); } - dispose() { this.lightPlane.geometry.dispose(); this.lightPlane.material.dispose(); this.targetLine.geometry.dispose(); this.targetLine.material.dispose(); } - update() { + this.light.updateWorldMatrix(true, false); + this.light.target.updateWorldMatrix(true, false); _v1.setFromMatrixPosition(this.light.matrixWorld); - _v2.setFromMatrixPosition(this.light.target.matrixWorld); - _v3.subVectors(_v2, _v1); - this.lightPlane.lookAt(_v2); - if (this.color !== undefined) { this.lightPlane.material.color.set(this.color); this.targetLine.material.color.set(this.color); @@ -34531,16 +31232,14 @@ this.lightPlane.material.color.copy(this.light.color); this.targetLine.material.color.copy(this.light.color); } - this.targetLine.lookAt(_v2); this.targetLine.scale.z = _v3.length(); } - } const _vector = /*@__PURE__*/new Vector3(); - const _camera = /*@__PURE__*/new Camera(); + /** * - shows frustum, line of sight and up of the camera * - suitable for fast updates @@ -34548,7 +31247,6 @@ * https://github.com/evanw/lightgl.js/blob/master/tests/shadowmap.html */ - class CameraHelper extends LineSegments { constructor(camera) { const geometry = new BufferGeometry(); @@ -34559,56 +31257,65 @@ }); const vertices = []; const colors = []; - const pointMap = {}; // near + const pointMap = {}; + + // near addLine('n1', 'n2'); addLine('n2', 'n4'); addLine('n4', 'n3'); - addLine('n3', 'n1'); // far + addLine('n3', 'n1'); + + // far addLine('f1', 'f2'); addLine('f2', 'f4'); addLine('f4', 'f3'); - addLine('f3', 'f1'); // sides + addLine('f3', 'f1'); + + // sides addLine('n1', 'f1'); addLine('n2', 'f2'); addLine('n3', 'f3'); - addLine('n4', 'f4'); // cone + addLine('n4', 'f4'); + + // cone addLine('p', 'n1'); addLine('p', 'n2'); addLine('p', 'n3'); - addLine('p', 'n4'); // up + addLine('p', 'n4'); + + // up addLine('u1', 'u2'); addLine('u2', 'u3'); - addLine('u3', 'u1'); // target + addLine('u3', 'u1'); + + // target addLine('c', 't'); - addLine('p', 'c'); // cross + addLine('p', 'c'); + + // cross addLine('cn1', 'cn2'); addLine('cn3', 'cn4'); addLine('cf1', 'cf2'); addLine('cf3', 'cf4'); - function addLine(a, b) { addPoint(a); addPoint(b); } - function addPoint(id) { vertices.push(0, 0, 0); colors.push(0, 0, 0); - if (pointMap[id] === undefined) { pointMap[id] = []; } - pointMap[id].push(vertices.length / 3 - 1); } - geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); super(geometry, material); @@ -34618,7 +31325,9 @@ this.matrix = camera.matrixWorld; this.matrixAutoUpdate = false; this.pointMap = pointMap; - this.update(); // colors + this.update(); + + // colors const colorFrustum = new Color(0xffaa00); const colorCone = new Color(0xff0000); @@ -34627,121 +31336,121 @@ const colorCross = new Color(0x333333); this.setColors(colorFrustum, colorCone, colorUp, colorTarget, colorCross); } - setColors(frustum, cone, up, target, cross) { const geometry = this.geometry; - const colorAttribute = geometry.getAttribute('color'); // near + const colorAttribute = geometry.getAttribute('color'); + + // near colorAttribute.setXYZ(0, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(1, frustum.r, frustum.g, frustum.b); // n1, n2 - colorAttribute.setXYZ(2, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(3, frustum.r, frustum.g, frustum.b); // n2, n4 - colorAttribute.setXYZ(4, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(5, frustum.r, frustum.g, frustum.b); // n4, n3 - colorAttribute.setXYZ(6, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(7, frustum.r, frustum.g, frustum.b); // n3, n1 + // far colorAttribute.setXYZ(8, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(9, frustum.r, frustum.g, frustum.b); // f1, f2 - colorAttribute.setXYZ(10, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(11, frustum.r, frustum.g, frustum.b); // f2, f4 - colorAttribute.setXYZ(12, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(13, frustum.r, frustum.g, frustum.b); // f4, f3 - colorAttribute.setXYZ(14, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(15, frustum.r, frustum.g, frustum.b); // f3, f1 + // sides colorAttribute.setXYZ(16, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(17, frustum.r, frustum.g, frustum.b); // n1, f1 - colorAttribute.setXYZ(18, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(19, frustum.r, frustum.g, frustum.b); // n2, f2 - colorAttribute.setXYZ(20, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(21, frustum.r, frustum.g, frustum.b); // n3, f3 - colorAttribute.setXYZ(22, frustum.r, frustum.g, frustum.b); colorAttribute.setXYZ(23, frustum.r, frustum.g, frustum.b); // n4, f4 + // cone colorAttribute.setXYZ(24, cone.r, cone.g, cone.b); colorAttribute.setXYZ(25, cone.r, cone.g, cone.b); // p, n1 - colorAttribute.setXYZ(26, cone.r, cone.g, cone.b); colorAttribute.setXYZ(27, cone.r, cone.g, cone.b); // p, n2 - colorAttribute.setXYZ(28, cone.r, cone.g, cone.b); colorAttribute.setXYZ(29, cone.r, cone.g, cone.b); // p, n3 - colorAttribute.setXYZ(30, cone.r, cone.g, cone.b); colorAttribute.setXYZ(31, cone.r, cone.g, cone.b); // p, n4 + // up colorAttribute.setXYZ(32, up.r, up.g, up.b); colorAttribute.setXYZ(33, up.r, up.g, up.b); // u1, u2 - colorAttribute.setXYZ(34, up.r, up.g, up.b); colorAttribute.setXYZ(35, up.r, up.g, up.b); // u2, u3 - colorAttribute.setXYZ(36, up.r, up.g, up.b); colorAttribute.setXYZ(37, up.r, up.g, up.b); // u3, u1 + // target colorAttribute.setXYZ(38, target.r, target.g, target.b); colorAttribute.setXYZ(39, target.r, target.g, target.b); // c, t - colorAttribute.setXYZ(40, cross.r, cross.g, cross.b); colorAttribute.setXYZ(41, cross.r, cross.g, cross.b); // p, c + // cross colorAttribute.setXYZ(42, cross.r, cross.g, cross.b); colorAttribute.setXYZ(43, cross.r, cross.g, cross.b); // cn1, cn2 - colorAttribute.setXYZ(44, cross.r, cross.g, cross.b); colorAttribute.setXYZ(45, cross.r, cross.g, cross.b); // cn3, cn4 colorAttribute.setXYZ(46, cross.r, cross.g, cross.b); colorAttribute.setXYZ(47, cross.r, cross.g, cross.b); // cf1, cf2 - colorAttribute.setXYZ(48, cross.r, cross.g, cross.b); colorAttribute.setXYZ(49, cross.r, cross.g, cross.b); // cf3, cf4 colorAttribute.needsUpdate = true; } - update() { const geometry = this.geometry; const pointMap = this.pointMap; const w = 1, - h = 1; // we need just camera projection matrix inverse + h = 1; + + // we need just camera projection matrix inverse // world matrix must be identity - _camera.projectionMatrixInverse.copy(this.camera.projectionMatrixInverse); // center / target + _camera.projectionMatrixInverse.copy(this.camera.projectionMatrixInverse); + // center / target setPoint('c', pointMap, geometry, _camera, 0, 0, -1); - setPoint('t', pointMap, geometry, _camera, 0, 0, 1); // near + setPoint('t', pointMap, geometry, _camera, 0, 0, 1); + + // near 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('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('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('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); @@ -34753,22 +31462,16 @@ setPoint('cn4', pointMap, geometry, _camera, 0, h, -1); geometry.getAttribute('position').needsUpdate = true; } - dispose() { this.geometry.dispose(); this.material.dispose(); } - } - function setPoint(point, pointMap, geometry, camera, x, y, z) { _vector.set(x, y, z).unproject(camera); - const points = pointMap[point]; - if (points !== undefined) { const position = geometry.getAttribute('position'); - for (let i = 0, l = points.length; i < l; i++) { position.setXYZ(points[i], _vector.x, _vector.y, _vector.z); } @@ -34776,7 +31479,6 @@ } const _box = /*@__PURE__*/new Box3(); - class BoxHelper extends LineSegments { constructor(object, color = 0xffff00) { const 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]); @@ -34793,19 +31495,17 @@ this.matrixAutoUpdate = false; this.update(); } - update(object) { if (object !== undefined) { console.warn('THREE.BoxHelper: .update() has no longer arguments.'); } - if (this.object !== undefined) { _box.setFromObject(this.object); } - if (_box.isEmpty()) return; const min = _box.min; const max = _box.max; + /* 5____4 1/___0/| @@ -34850,19 +31550,20 @@ position.needsUpdate = true; this.geometry.computeBoundingSphere(); } - setFromObject(object) { this.object = object; this.update(); return this; } - copy(source, recursive) { super.copy(source, recursive); this.object = source.object; return this; } - + dispose() { + this.geometry.dispose(); + this.material.dispose(); + } } class Box3Helper extends LineSegments { @@ -34880,7 +31581,6 @@ this.type = 'Box3Helper'; this.geometry.computeBoundingSphere(); } - updateMatrixWorld(force) { const box = this.box; if (box.isEmpty()) return; @@ -34889,7 +31589,10 @@ this.scale.multiplyScalar(0.5); super.updateMatrixWorld(force); } - + dispose() { + this.geometry.dispose(); + this.material.dispose(); + } } class PlaneHelper extends Line { @@ -34918,7 +31621,6 @@ toneMapped: false }))); } - updateMatrixWorld(force) { this.position.set(0, 0, 0); this.scale.set(0.5 * this.size, 0.5 * this.size, 1); @@ -34926,29 +31628,28 @@ this.translateZ(-this.plane.constant); super.updateMatrixWorld(force); } - + dispose() { + this.geometry.dispose(); + this.material.dispose(); + this.children[0].geometry.dispose(); + this.children[0].material.dispose(); + } } const _axis = /*@__PURE__*/new Vector3(); - let _lineGeometry, _coneGeometry; - class ArrowHelper extends Object3D { // dir is assumed to be normalized + constructor(dir = new Vector3(0, 0, 1), origin = new Vector3(0, 0, 0), length = 1, color = 0xffff00, headLength = length * 0.2, headWidth = headLength * 0.2) { super(); this.type = 'ArrowHelper'; - if (_lineGeometry === undefined) { _lineGeometry = new BufferGeometry(); - _lineGeometry.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 0, 1, 0], 3)); - _coneGeometry = new CylinderGeometry(0, 0.5, 1, 5, 1); - _coneGeometry.translate(0, -0.5, 0); } - this.position.copy(origin); this.line = new Line(_lineGeometry, new LineBasicMaterial({ color: color, @@ -34965,42 +31666,42 @@ this.setDirection(dir); this.setLength(length, headLength, headWidth); } - 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(); - const radians = Math.acos(dir.y); this.quaternion.setFromAxisAngle(_axis, radians); } } - setLength(length, headLength = length * 0.2, headWidth = headLength * 0.2) { this.line.scale.set(1, Math.max(0.0001, length - headLength), 1); // see #17458 - this.line.updateMatrix(); this.cone.scale.set(headWidth, headLength, headWidth); this.cone.position.y = length; this.cone.updateMatrix(); } - setColor(color) { this.line.material.color.set(color); this.cone.material.color.set(color); } - copy(source) { super.copy(source, false); this.line.copy(source.line); this.cone.copy(source.cone); return this; } - + dispose() { + this.line.geometry.dispose(); + this.line.material.dispose(); + this.cone.geometry.dispose(); + this.cone.material.dispose(); + } } class AxesHelper extends LineSegments { @@ -35017,7 +31718,6 @@ super(geometry, material); this.type = 'AxesHelper'; } - setColors(xAxisColor, yAxisColor, zAxisColor) { const color = new Color(); const array = this.geometry.attributes.color.array; @@ -35033,12 +31733,10 @@ this.geometry.attributes.color.needsUpdate = true; return this; } - dispose() { this.geometry.dispose(); this.material.dispose(); } - } class ShapePath { @@ -35048,62 +31746,52 @@ this.subPaths = []; this.currentPath = null; } - moveTo(x, y) { this.currentPath = new Path(); this.subPaths.push(this.currentPath); this.currentPath.moveTo(x, y); return this; } - lineTo(x, y) { this.currentPath.lineTo(x, y); return this; } - quadraticCurveTo(aCPx, aCPy, aX, aY) { this.currentPath.quadraticCurveTo(aCPx, aCPy, aX, aY); return this; } - bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY) { this.currentPath.bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY); return this; } - splineThru(pts) { this.currentPath.splineThru(pts); return this; } - - toShapes(isCCW, noHoles) { + toShapes(isCCW) { function toShapesNoHoles(inSubpaths) { const shapes = []; - for (let i = 0, l = inSubpaths.length; i < l; i++) { const tmpPath = inSubpaths[i]; const tmpShape = new Shape(); tmpShape.curves = tmpPath.curves; shapes.push(tmpShape); } - return shapes; } - function isPointInsidePolygon(inPt, inPolygon) { - const polyLen = inPolygon.length; // inPt on polygon contour => immediate success or + const 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 - let inside = false; - for (let p = polyLen - 1, q = 0; q < polyLen; p = q++) { let edgeLowPt = inPolygon[p]; let edgeHighPt = inPolygon[q]; let edgeDx = edgeHighPt.x - edgeLowPt.x; let edgeDy = edgeHighPt.y - edgeLowPt.y; - if (Math.abs(edgeDy) > Number.EPSILON) { // not parallel if (edgeDy < 0) { @@ -35112,16 +31800,13 @@ 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 { const 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 } @@ -35129,7 +31814,6 @@ // parallel or collinear if (inPt.y !== edgeLowPt.y) continue; // parallel // edge 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; } @@ -35137,14 +31821,11 @@ return inside; } - const isClockWise = ShapeUtils.isClockWise; const subPaths = this.subPaths; if (subPaths.length === 0) return []; - if (noHoles === true) return toShapesNoHoles(subPaths); let solid, tmpPath, tmpShape; const shapes = []; - if (subPaths.length === 1) { tmpPath = subPaths[0]; tmpShape = new Shape(); @@ -35152,9 +31833,10 @@ shapes.push(tmpShape); return shapes; } - let holesFirst = !isClockWise(subPaths[0].getPoints()); - holesFirst = isCCW ? !holesFirst : holesFirst; // console.log("Holes first", holesFirst); + holesFirst = isCCW ? !holesFirst : holesFirst; + + // console.log("Holes first", holesFirst); const betterShapeHoles = []; const newShapes = []; @@ -35163,13 +31845,11 @@ let tmpPoints; newShapes[mainIdx] = undefined; newShapeHoles[mainIdx] = []; - for (let 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] = { @@ -35178,37 +31858,35 @@ }; newShapes[mainIdx].s.curves = tmpPath.curves; if (holesFirst) mainIdx++; - newShapeHoles[mainIdx] = []; //console.log('cw', i); + 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 + }); + //console.log('ccw', i); + } + } + // only Holes? -> probably all Shapes with wrong orientation if (!newShapes[0]) return toShapesNoHoles(subPaths); - if (newShapes.length > 1) { let ambiguous = false; let toChange = 0; - for (let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++) { betterShapeHoles[sIdx] = []; } - for (let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++) { const sho = newShapeHoles[sIdx]; - for (let hIdx = 0; hIdx < sho.length; hIdx++) { const ho = sho[hIdx]; let hole_unassigned = true; - for (let s2Idx = 0; s2Idx < newShapes.length; s2Idx++) { if (isPointInsidePolygon(ho.p, newShapes[s2Idx].p)) { if (sIdx !== s2Idx) toChange++; - if (hole_unassigned) { hole_unassigned = false; betterShapeHoles[s2Idx].push(ho); @@ -35217,123 +31895,120 @@ } } } - if (hole_unassigned) { betterShapeHoles[sIdx].push(ho); } } } - if (toChange > 0 && ambiguous === false) { newShapeHoles = betterShapeHoles; } } - let tmpHoles; - for (let i = 0, il = newShapes.length; i < il; i++) { tmpShape = newShapes[i].s; shapes.push(tmpShape); tmpHoles = newShapeHoles[i]; - for (let j = 0, jl = tmpHoles.length; j < jl; j++) { tmpShape.holes.push(tmpHoles[j].h); } - } //console.log("shape", shapes); + } + //console.log("shape", shapes); return shapes; } - } - const _tables = /*@__PURE__*/_generateTables(); + // Fast Half Float Conversions, http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf + const _tables = /*@__PURE__*/_generateTables(); function _generateTables() { // float32 to float16 helpers + const buffer = new ArrayBuffer(4); const floatView = new Float32Array(buffer); const uint32View = new Uint32Array(buffer); const baseTable = new Uint32Array(512); const shiftTable = new Uint32Array(512); - for (let i = 0; i < 256; ++i) { - const e = i - 127; // very small number (0, -0) + const e = i - 127; + + // very small number (0, -0) if (e < -27) { baseTable[i] = 0x0000; baseTable[i | 0x100] = 0x8000; shiftTable[i] = 24; - shiftTable[i | 0x100] = 24; // small number (denorm) + shiftTable[i | 0x100] = 24; + + // small number (denorm) } else if (e < -14) { baseTable[i] = 0x0400 >> -e - 14; baseTable[i | 0x100] = 0x0400 >> -e - 14 | 0x8000; shiftTable[i] = -e - 1; - shiftTable[i | 0x100] = -e - 1; // normal number + shiftTable[i | 0x100] = -e - 1; + + // normal number } else if (e <= 15) { baseTable[i] = e + 15 << 10; baseTable[i | 0x100] = e + 15 << 10 | 0x8000; shiftTable[i] = 13; - shiftTable[i | 0x100] = 13; // large number (Infinity, -Infinity) + shiftTable[i | 0x100] = 13; + + // large number (Infinity, -Infinity) } else if (e < 128) { baseTable[i] = 0x7c00; baseTable[i | 0x100] = 0xfc00; shiftTable[i] = 24; - shiftTable[i | 0x100] = 24; // stay (NaN, Infinity, -Infinity) + shiftTable[i | 0x100] = 24; + + // stay (NaN, Infinity, -Infinity) } else { baseTable[i] = 0x7c00; baseTable[i | 0x100] = 0xfc00; shiftTable[i] = 13; shiftTable[i | 0x100] = 13; } - } // float16 to float32 helpers + } + // float16 to float32 helpers const mantissaTable = new Uint32Array(2048); const exponentTable = new Uint32Array(64); const offsetTable = new Uint32Array(64); - for (let i = 1; i < 1024; ++i) { let m = i << 13; // zero pad mantissa bits - let e = 0; // zero exponent - // normalized + // normalized while ((m & 0x00800000) === 0) { m <<= 1; e -= 0x00800000; // decrement exponent } m &= ~0x00800000; // clear leading 1 bit - e += 0x38800000; // adjust bias mantissaTable[i] = m | e; } - for (let i = 1024; i < 2048; ++i) { mantissaTable[i] = 0x38000000 + (i - 1024 << 13); } - for (let i = 1; i < 31; ++i) { exponentTable[i] = i << 23; } - exponentTable[31] = 0x47800000; exponentTable[32] = 0x80000000; - for (let i = 33; i < 63; ++i) { exponentTable[i] = 0x80000000 + (i - 32 << 23); } - exponentTable[63] = 0xc7800000; - for (let i = 1; i < 64; ++i) { if (i !== 32) { offsetTable[i] = 1024; } } - return { floatView: floatView, uint32View: uint32View, @@ -35343,8 +32018,9 @@ exponentTable: exponentTable, offsetTable: offsetTable }; - } // float32 to float16 + } + // float32 to float16 function toHalfFloat(val) { if (Math.abs(val) > 65504) console.warn('THREE.DataUtils.toHalfFloat(): Value out of range.'); @@ -35353,8 +32029,9 @@ const f = _tables.uint32View[0]; const e = f >> 23 & 0x1ff; return _tables.baseTable[e] + ((f & 0x007fffff) >> _tables.shiftTable[e]); - } // float16 to float32 + } + // float16 to float32 function fromHalfFloat(val) { const m = val >> 10; @@ -35368,33 +32045,13 @@ fromHalfFloat: fromHalfFloat }); - class ParametricGeometry extends BufferGeometry { - constructor() { - console.error('THREE.ParametricGeometry has been moved to /examples/jsm/geometries/ParametricGeometry.js'); - super(); - } - - } // r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 - - class TextGeometry extends BufferGeometry { - constructor() { - console.error('THREE.TextGeometry has been moved to /examples/jsm/geometries/TextGeometry.js'); - super(); - } - - } // r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 - - function FontLoader() { - console.error('THREE.FontLoader has been moved to /examples/jsm/loaders/FontLoader.js'); - } // r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 - - function Font() { - console.error('THREE.Font has been moved to /examples/jsm/loaders/FontLoader.js'); - } // r134, d65e0af06644fe5a84a6fc0e372f4318f95a04c0 + // r134, d65e0af06644fe5a84a6fc0e372f4318f95a04c0 function ImmediateRenderObject() { console.error('THREE.ImmediateRenderObject has been removed.'); - } // r138, 48b05d3500acc084df50be9b4c90781ad9b8cb17 + } + + // r138, 48b05d3500acc084df50be9b4c90781ad9b8cb17 class WebGLMultisampleRenderTarget extends WebGLRenderTarget { constructor(width, height, options) { @@ -35402,23 +32059,195 @@ super(width, height, options); this.samples = 4; } + } - } // r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce + // r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce class DataTexture2DArray extends DataArrayTexture { constructor(data, width, height, depth) { console.warn('THREE.DataTexture2DArray has been renamed to DataArrayTexture.'); super(data, width, height, depth); } + } - } // r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce + // r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce class DataTexture3D extends Data3DTexture { constructor(data, width, height, depth) { console.warn('THREE.DataTexture3D has been renamed to Data3DTexture.'); super(data, width, height, depth); } + } + + // r144 + + class BoxBufferGeometry extends BoxGeometry { + constructor(width, height, depth, widthSegments, heightSegments, depthSegments) { + console.warn('THREE.BoxBufferGeometry has been renamed to THREE.BoxGeometry.'); + super(width, height, depth, widthSegments, heightSegments, depthSegments); + } + } + + // r144 + + class CapsuleBufferGeometry extends CapsuleGeometry { + constructor(radius, length, capSegments, radialSegments) { + console.warn('THREE.CapsuleBufferGeometry has been renamed to THREE.CapsuleGeometry.'); + super(radius, length, capSegments, radialSegments); + } + } + + // r144 + + class CircleBufferGeometry extends CircleGeometry { + constructor(radius, segments, thetaStart, thetaLength) { + console.warn('THREE.CircleBufferGeometry has been renamed to THREE.CircleGeometry.'); + super(radius, segments, thetaStart, thetaLength); + } + } + + // r144 + + class ConeBufferGeometry extends ConeGeometry { + constructor(radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) { + console.warn('THREE.ConeBufferGeometry has been renamed to THREE.ConeGeometry.'); + super(radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength); + } + } + + // r144 + + class CylinderBufferGeometry extends CylinderGeometry { + constructor(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) { + console.warn('THREE.CylinderBufferGeometry has been renamed to THREE.CylinderGeometry.'); + super(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength); + } + } + + // r144 + + class DodecahedronBufferGeometry extends DodecahedronGeometry { + constructor(radius, detail) { + console.warn('THREE.DodecahedronBufferGeometry has been renamed to THREE.DodecahedronGeometry.'); + super(radius, detail); + } + } + + // r144 + + class ExtrudeBufferGeometry extends ExtrudeGeometry { + constructor(shapes, options) { + console.warn('THREE.ExtrudeBufferGeometry has been renamed to THREE.ExtrudeGeometry.'); + super(shapes, options); + } + } + + // r144 + + class IcosahedronBufferGeometry extends IcosahedronGeometry { + constructor(radius, detail) { + console.warn('THREE.IcosahedronBufferGeometry has been renamed to THREE.IcosahedronGeometry.'); + super(radius, detail); + } + } + + // r144 + + class LatheBufferGeometry extends LatheGeometry { + constructor(points, segments, phiStart, phiLength) { + console.warn('THREE.LatheBufferGeometry has been renamed to THREE.LatheGeometry.'); + super(points, segments, phiStart, phiLength); + } + } + + // r144 + + class OctahedronBufferGeometry extends OctahedronGeometry { + constructor(radius, detail) { + console.warn('THREE.OctahedronBufferGeometry has been renamed to THREE.OctahedronGeometry.'); + super(radius, detail); + } + } + + // r144 + + class PlaneBufferGeometry extends PlaneGeometry { + constructor(width, height, widthSegments, heightSegments) { + console.warn('THREE.PlaneBufferGeometry has been renamed to THREE.PlaneGeometry.'); + super(width, height, widthSegments, heightSegments); + } + } + + // r144 + + class PolyhedronBufferGeometry extends PolyhedronGeometry { + constructor(vertices, indices, radius, detail) { + console.warn('THREE.PolyhedronBufferGeometry has been renamed to THREE.PolyhedronGeometry.'); + super(vertices, indices, radius, detail); + } + } + + // r144 + + class RingBufferGeometry extends RingGeometry { + constructor(innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength) { + console.warn('THREE.RingBufferGeometry has been renamed to THREE.RingGeometry.'); + super(innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength); + } + } + + // r144 + + class ShapeBufferGeometry extends ShapeGeometry { + constructor(shapes, curveSegments) { + console.warn('THREE.ShapeBufferGeometry has been renamed to THREE.ShapeGeometry.'); + super(shapes, curveSegments); + } + } + + // r144 + + class SphereBufferGeometry extends SphereGeometry { + constructor(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength) { + console.warn('THREE.SphereBufferGeometry has been renamed to THREE.SphereGeometry.'); + super(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength); + } + } + + // r144 + + class TetrahedronBufferGeometry extends TetrahedronGeometry { + constructor(radius, detail) { + console.warn('THREE.TetrahedronBufferGeometry has been renamed to THREE.TetrahedronGeometry.'); + super(radius, detail); + } + } + + // r144 + + class TorusBufferGeometry extends TorusGeometry { + constructor(radius, tube, radialSegments, tubularSegments, arc) { + console.warn('THREE.TorusBufferGeometry has been renamed to THREE.TorusGeometry.'); + super(radius, tube, radialSegments, tubularSegments, arc); + } + } + + // r144 + + class TorusKnotBufferGeometry extends TorusKnotGeometry { + constructor(radius, tube, tubularSegments, radialSegments, p, q) { + console.warn('THREE.TorusKnotBufferGeometry has been renamed to THREE.TorusKnotGeometry.'); + super(radius, tube, tubularSegments, radialSegments, p, q); + } + } + + // r144 + class TubeBufferGeometry extends TubeGeometry { + constructor(path, tubularSegments, radius, radialSegments, closed) { + console.warn('THREE.TubeBufferGeometry has been renamed to THREE.TubeGeometry.'); + super(path, tubularSegments, radius, radialSegments, closed); + } } if (typeof __THREE_DEVTOOLS__ !== 'undefined') { @@ -35428,7 +32257,6 @@ } })); } - if (typeof window !== 'undefined') { if (window.__THREE__) { console.warn('WARNING: Multiple instances of Three.js being imported.'); @@ -35469,7 +32297,7 @@ exports.Box2 = Box2; exports.Box3 = Box3; exports.Box3Helper = Box3Helper; - exports.BoxBufferGeometry = BoxGeometry; + exports.BoxBufferGeometry = BoxBufferGeometry; exports.BoxGeometry = BoxGeometry; exports.BoxHelper = BoxHelper; exports.BufferAttribute = BufferAttribute; @@ -35480,20 +32308,21 @@ exports.Camera = Camera; exports.CameraHelper = CameraHelper; exports.CanvasTexture = CanvasTexture; - exports.CapsuleBufferGeometry = CapsuleGeometry; + exports.CapsuleBufferGeometry = CapsuleBufferGeometry; exports.CapsuleGeometry = CapsuleGeometry; exports.CatmullRomCurve3 = CatmullRomCurve3; exports.CineonToneMapping = CineonToneMapping; - exports.CircleBufferGeometry = CircleGeometry; + exports.CircleBufferGeometry = CircleBufferGeometry; exports.CircleGeometry = CircleGeometry; exports.ClampToEdgeWrapping = ClampToEdgeWrapping; exports.Clock = Clock; exports.Color = Color; exports.ColorKeyframeTrack = ColorKeyframeTrack; exports.ColorManagement = ColorManagement; + exports.CompressedArrayTexture = CompressedArrayTexture; exports.CompressedTexture = CompressedTexture; exports.CompressedTextureLoader = CompressedTextureLoader; - exports.ConeBufferGeometry = ConeGeometry; + exports.ConeBufferGeometry = ConeBufferGeometry; exports.ConeGeometry = ConeGeometry; exports.CubeCamera = CubeCamera; exports.CubeReflectionMapping = CubeReflectionMapping; @@ -35512,7 +32341,7 @@ exports.CurvePath = CurvePath; exports.CustomBlending = CustomBlending; exports.CustomToneMapping = CustomToneMapping; - exports.CylinderBufferGeometry = CylinderGeometry; + exports.CylinderBufferGeometry = CylinderBufferGeometry; exports.CylinderGeometry = CylinderGeometry; exports.Cylindrical = Cylindrical; exports.Data3DTexture = Data3DTexture; @@ -35531,7 +32360,7 @@ exports.DirectionalLight = DirectionalLight; exports.DirectionalLightHelper = DirectionalLightHelper; exports.DiscreteInterpolant = DiscreteInterpolant; - exports.DodecahedronBufferGeometry = DodecahedronGeometry; + exports.DodecahedronBufferGeometry = DodecahedronBufferGeometry; exports.DodecahedronGeometry = DodecahedronGeometry; exports.DoubleSide = DoubleSide; exports.DstAlphaFactor = DstAlphaFactor; @@ -35547,18 +32376,15 @@ exports.EquirectangularRefractionMapping = EquirectangularRefractionMapping; exports.Euler = Euler; exports.EventDispatcher = EventDispatcher; - exports.ExtrudeBufferGeometry = ExtrudeGeometry; + exports.ExtrudeBufferGeometry = ExtrudeBufferGeometry; exports.ExtrudeGeometry = ExtrudeGeometry; exports.FileLoader = FileLoader; - exports.FlatShading = FlatShading; exports.Float16BufferAttribute = Float16BufferAttribute; exports.Float32BufferAttribute = Float32BufferAttribute; exports.Float64BufferAttribute = Float64BufferAttribute; exports.FloatType = FloatType; exports.Fog = Fog; exports.FogExp2 = FogExp2; - exports.Font = Font; - exports.FontLoader = FontLoader; exports.FramebufferTexture = FramebufferTexture; exports.FrontSide = FrontSide; exports.Frustum = Frustum; @@ -35575,7 +32401,7 @@ exports.HemisphereLight = HemisphereLight; exports.HemisphereLightHelper = HemisphereLightHelper; exports.HemisphereLightProbe = HemisphereLightProbe; - exports.IcosahedronBufferGeometry = IcosahedronGeometry; + exports.IcosahedronBufferGeometry = IcosahedronBufferGeometry; exports.IcosahedronGeometry = IcosahedronGeometry; exports.ImageBitmapLoader = ImageBitmapLoader; exports.ImageLoader = ImageLoader; @@ -35601,7 +32427,7 @@ exports.KeepStencilOp = KeepStencilOp; exports.KeyframeTrack = KeyframeTrack; exports.LOD = LOD; - exports.LatheBufferGeometry = LatheGeometry; + exports.LatheBufferGeometry = LatheBufferGeometry; exports.LatheGeometry = LatheGeometry; exports.Layers = Layers; exports.LessDepth = LessDepth; @@ -35676,7 +32502,7 @@ exports.Object3D = Object3D; exports.ObjectLoader = ObjectLoader; exports.ObjectSpaceNormalMap = ObjectSpaceNormalMap; - exports.OctahedronBufferGeometry = OctahedronGeometry; + exports.OctahedronBufferGeometry = OctahedronBufferGeometry; exports.OctahedronGeometry = OctahedronGeometry; exports.OneFactor = OneFactor; exports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor; @@ -35687,11 +32513,10 @@ exports.PCFShadowMap = PCFShadowMap; exports.PCFSoftShadowMap = PCFSoftShadowMap; exports.PMREMGenerator = PMREMGenerator; - exports.ParametricGeometry = ParametricGeometry; exports.Path = Path; exports.PerspectiveCamera = PerspectiveCamera; exports.Plane = Plane; - exports.PlaneBufferGeometry = PlaneGeometry; + exports.PlaneBufferGeometry = PlaneBufferGeometry; exports.PlaneGeometry = PlaneGeometry; exports.PlaneHelper = PlaneHelper; exports.PointLight = PointLight; @@ -35699,7 +32524,7 @@ exports.Points = Points; exports.PointsMaterial = PointsMaterial; exports.PolarGridHelper = PolarGridHelper; - exports.PolyhedronBufferGeometry = PolyhedronGeometry; + exports.PolyhedronBufferGeometry = PolyhedronBufferGeometry; exports.PolyhedronGeometry = PolyhedronGeometry; exports.PositionalAudio = PositionalAudio; exports.PropertyBinding = PropertyBinding; @@ -35752,7 +32577,7 @@ exports.RepeatWrapping = RepeatWrapping; exports.ReplaceStencilOp = ReplaceStencilOp; exports.ReverseSubtractEquation = ReverseSubtractEquation; - exports.RingBufferGeometry = RingGeometry; + exports.RingBufferGeometry = RingBufferGeometry; exports.RingGeometry = RingGeometry; exports.SRGBColorSpace = SRGBColorSpace; exports.Scene = Scene; @@ -35761,7 +32586,7 @@ exports.ShaderMaterial = ShaderMaterial; exports.ShadowMaterial = ShadowMaterial; exports.Shape = Shape; - exports.ShapeBufferGeometry = ShapeGeometry; + exports.ShapeBufferGeometry = ShapeBufferGeometry; exports.ShapeGeometry = ShapeGeometry; exports.ShapePath = ShapePath; exports.ShapeUtils = ShapeUtils; @@ -35769,10 +32594,9 @@ exports.Skeleton = Skeleton; exports.SkeletonHelper = SkeletonHelper; exports.SkinnedMesh = SkinnedMesh; - exports.SmoothShading = SmoothShading; exports.Source = Source; exports.Sphere = Sphere; - exports.SphereBufferGeometry = SphereGeometry; + exports.SphereBufferGeometry = SphereBufferGeometry; exports.SphereGeometry = SphereGeometry; exports.Spherical = Spherical; exports.SphericalHarmonics3 = SphericalHarmonics3; @@ -35796,20 +32620,19 @@ exports.SubtractiveBlending = SubtractiveBlending; exports.TOUCH = TOUCH; exports.TangentSpaceNormalMap = TangentSpaceNormalMap; - exports.TetrahedronBufferGeometry = TetrahedronGeometry; + exports.TetrahedronBufferGeometry = TetrahedronBufferGeometry; exports.TetrahedronGeometry = TetrahedronGeometry; - exports.TextGeometry = TextGeometry; exports.Texture = Texture; exports.TextureLoader = TextureLoader; - exports.TorusBufferGeometry = TorusGeometry; + exports.TorusBufferGeometry = TorusBufferGeometry; exports.TorusGeometry = TorusGeometry; - exports.TorusKnotBufferGeometry = TorusKnotGeometry; + exports.TorusKnotBufferGeometry = TorusKnotBufferGeometry; exports.TorusKnotGeometry = TorusKnotGeometry; exports.Triangle = Triangle; exports.TriangleFanDrawMode = TriangleFanDrawMode; exports.TriangleStripDrawMode = TriangleStripDrawMode; exports.TrianglesDrawMode = TrianglesDrawMode; - exports.TubeBufferGeometry = TubeGeometry; + exports.TubeBufferGeometry = TubeBufferGeometry; exports.TubeGeometry = TubeGeometry; exports.UVMapping = UVMapping; exports.Uint16BufferAttribute = Uint16BufferAttribute; diff --git a/build/three.min.js b/build/three.min.js index 02ec66f6ed0590..8dc08f72d829a1 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -3,4 +3,4 @@ * Copyright 2010-2022 Three.js Authors * SPDX-License-Identifier: MIT */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).THREE={})}(this,(function(t){"use strict";const e="143",i=100,n=300,r=301,s=302,a=303,o=304,l=306,c=1e3,h=1001,u=1002,d=1003,p=1004,f=1005,m=1006,g=1007,v=1008,x=1009,_=1012,y=1014,M=1015,b=1016,w=1020,S=1023,T=1026,A=1027,E=33776,C=33777,L=33778,R=33779,P=35840,I=35841,D=35842,N=35843,O=37492,z=37496,F=37808,B=37809,U=37810,k=37811,G=37812,V=37813,H=37814,W=37815,j=37816,q=37817,X=37818,Y=37819,Z=37820,J=37821,K=36492,$=2300,Q=2301,tt=2302,et=2400,it=2401,nt=2402,rt=2500,st=2501,at=3e3,ot=3001,lt="srgb",ct="srgb-linear",ht=7680,ut=35044,dt="300 es",pt=1035;class ft{addEventListener(t,e){void 0===this._listeners&&(this._listeners={});const i=this._listeners;void 0===i[t]&&(i[t]=[]),-1===i[t].indexOf(e)&&i[t].push(e)}hasEventListener(t,e){if(void 0===this._listeners)return!1;const i=this._listeners;return void 0!==i[t]&&-1!==i[t].indexOf(e)}removeEventListener(t,e){if(void 0===this._listeners)return;const i=this._listeners[t];if(void 0!==i){const t=i.indexOf(e);-1!==t&&i.splice(t,1)}}dispatchEvent(t){if(void 0===this._listeners)return;const e=this._listeners[t.type];if(void 0!==e){t.target=this;const i=e.slice(0);for(let e=0,n=i.length;e>8&255]+mt[t>>16&255]+mt[t>>24&255]+"-"+mt[255&e]+mt[e>>8&255]+"-"+mt[e>>16&15|64]+mt[e>>24&255]+"-"+mt[63&i|128]+mt[i>>8&255]+"-"+mt[i>>16&255]+mt[i>>24&255]+mt[255&n]+mt[n>>8&255]+mt[n>>16&255]+mt[n>>24&255]).toLowerCase()}function yt(t,e,i){return Math.max(e,Math.min(i,t))}function Mt(t,e){return(t%e+e)%e}function bt(t,e,i){return(1-i)*t+i*e}function wt(t){return 0==(t&t-1)&&0!==t}function St(t){return Math.pow(2,Math.ceil(Math.log(t)/Math.LN2))}function Tt(t){return Math.pow(2,Math.floor(Math.log(t)/Math.LN2))}var At=Object.freeze({__proto__:null,DEG2RAD:vt,RAD2DEG:xt,generateUUID:_t,clamp:yt,euclideanModulo:Mt,mapLinear:function(t,e,i,n,r){return n+(t-e)*(r-n)/(i-e)},inverseLerp:function(t,e,i){return t!==e?(i-t)/(e-t):0},lerp:bt,damp:function(t,e,i,n){return bt(t,e,1-Math.exp(-i*n))},pingpong:function(t,e=1){return e-Math.abs(Mt(t,2*e)-e)},smoothstep:function(t,e,i){return t<=e?0:t>=i?1:(t=(t-e)/(i-e))*t*(3-2*t)},smootherstep:function(t,e,i){return t<=e?0:t>=i?1:(t=(t-e)/(i-e))*t*t*(t*(6*t-15)+10)},randInt:function(t,e){return t+Math.floor(Math.random()*(e-t+1))},randFloat:function(t,e){return t+Math.random()*(e-t)},randFloatSpread:function(t){return t*(.5-Math.random())},seededRandom:function(t){void 0!==t&&(gt=t);let e=gt+=1831565813;return e=Math.imul(e^e>>>15,1|e),e^=e+Math.imul(e^e>>>7,61|e),((e^e>>>14)>>>0)/4294967296},degToRad:function(t){return t*vt},radToDeg:function(t){return t*xt},isPowerOfTwo:wt,ceilPowerOfTwo:St,floorPowerOfTwo:Tt,setQuaternionFromProperEuler:function(t,e,i,n,r){const s=Math.cos,a=Math.sin,o=s(i/2),l=a(i/2),c=s((e+n)/2),h=a((e+n)/2),u=s((e-n)/2),d=a((e-n)/2),p=s((n-e)/2),f=a((n-e)/2);switch(r){case"XYX":t.set(o*h,l*u,l*d,o*c);break;case"YZY":t.set(l*d,o*h,l*u,o*c);break;case"ZXZ":t.set(l*u,l*d,o*h,o*c);break;case"XZX":t.set(o*h,l*f,l*p,o*c);break;case"YXY":t.set(l*p,o*h,l*f,o*c);break;case"ZYZ":t.set(l*f,l*p,o*h,o*c);break;default:console.warn("THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: "+r)}},normalize:function(t,e){switch(e.constructor){case Float32Array:return t;case Uint16Array:return Math.round(65535*t);case Uint8Array:return Math.round(255*t);case Int16Array:return Math.round(32767*t);case Int8Array:return Math.round(127*t);default:throw new Error("Invalid component type.")}},denormalize:function(t,e){switch(e.constructor){case Float32Array:return t;case Uint16Array:return t/65535;case Uint8Array:return t/255;case Int16Array:return Math.max(t/32767,-1);case Int8Array:return Math.max(t/127,-1);default:throw new Error("Invalid component type.")}}});class Et{constructor(t=0,e=0){Et.prototype.isVector2=!0,this.x=t,this.y=e}get width(){return this.x}set width(t){this.x=t}get height(){return this.y}set height(t){this.y=t}set(t,e){return this.x=t,this.y=e,this}setScalar(t){return this.x=t,this.y=t,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setComponent(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;default:throw new Error("index is out of range: "+t)}return this}getComponent(t){switch(t){case 0:return this.x;case 1:return this.y;default:throw new Error("index is out of range: "+t)}}clone(){return new this.constructor(this.x,this.y)}copy(t){return this.x=t.x,this.y=t.y,this}add(t){return this.x+=t.x,this.y+=t.y,this}addScalar(t){return this.x+=t,this.y+=t,this}addVectors(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this}addScaledVector(t,e){return this.x+=t.x*e,this.y+=t.y*e,this}sub(t){return this.x-=t.x,this.y-=t.y,this}subScalar(t){return this.x-=t,this.y-=t,this}subVectors(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this}multiply(t){return this.x*=t.x,this.y*=t.y,this}multiplyScalar(t){return this.x*=t,this.y*=t,this}divide(t){return this.x/=t.x,this.y/=t.y,this}divideScalar(t){return this.multiplyScalar(1/t)}applyMatrix3(t){const e=this.x,i=this.y,n=t.elements;return this.x=n[0]*e+n[3]*i+n[6],this.y=n[1]*e+n[4]*i+n[7],this}min(t){return this.x=Math.min(this.x,t.x),this.y=Math.min(this.y,t.y),this}max(t){return this.x=Math.max(this.x,t.x),this.y=Math.max(this.y,t.y),this}clamp(t,e){return this.x=Math.max(t.x,Math.min(e.x,this.x)),this.y=Math.max(t.y,Math.min(e.y,this.y)),this}clampScalar(t,e){return this.x=Math.max(t,Math.min(e,this.x)),this.y=Math.max(t,Math.min(e,this.y)),this}clampLength(t,e){const i=this.length();return this.divideScalar(i||1).multiplyScalar(Math.max(t,Math.min(e,i)))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this}roundToZero(){return this.x=this.x<0?Math.ceil(this.x):Math.floor(this.x),this.y=this.y<0?Math.ceil(this.y):Math.floor(this.y),this}negate(){return this.x=-this.x,this.y=-this.y,this}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}lengthSq(){return this.x*this.x+this.y*this.y}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)}normalize(){return this.divideScalar(this.length()||1)}angle(){return Math.atan2(-this.y,-this.x)+Math.PI}distanceTo(t){return Math.sqrt(this.distanceToSquared(t))}distanceToSquared(t){const e=this.x-t.x,i=this.y-t.y;return e*e+i*i}manhattanDistanceTo(t){return Math.abs(this.x-t.x)+Math.abs(this.y-t.y)}setLength(t){return this.normalize().multiplyScalar(t)}lerp(t,e){return this.x+=(t.x-this.x)*e,this.y+=(t.y-this.y)*e,this}lerpVectors(t,e,i){return this.x=t.x+(e.x-t.x)*i,this.y=t.y+(e.y-t.y)*i,this}equals(t){return t.x===this.x&&t.y===this.y}fromArray(t,e=0){return this.x=t[e],this.y=t[e+1],this}toArray(t=[],e=0){return t[e]=this.x,t[e+1]=this.y,t}fromBufferAttribute(t,e){return this.x=t.getX(e),this.y=t.getY(e),this}rotateAround(t,e){const i=Math.cos(e),n=Math.sin(e),r=this.x-t.x,s=this.y-t.y;return this.x=r*i-s*n+t.x,this.y=r*n+s*i+t.y,this}random(){return this.x=Math.random(),this.y=Math.random(),this}*[Symbol.iterator](){yield this.x,yield this.y}}class Ct{constructor(){Ct.prototype.isMatrix3=!0,this.elements=[1,0,0,0,1,0,0,0,1]}set(t,e,i,n,r,s,a,o,l){const c=this.elements;return c[0]=t,c[1]=n,c[2]=a,c[3]=e,c[4]=r,c[5]=o,c[6]=i,c[7]=s,c[8]=l,this}identity(){return this.set(1,0,0,0,1,0,0,0,1),this}copy(t){const e=this.elements,i=t.elements;return e[0]=i[0],e[1]=i[1],e[2]=i[2],e[3]=i[3],e[4]=i[4],e[5]=i[5],e[6]=i[6],e[7]=i[7],e[8]=i[8],this}extractBasis(t,e,i){return t.setFromMatrix3Column(this,0),e.setFromMatrix3Column(this,1),i.setFromMatrix3Column(this,2),this}setFromMatrix4(t){const e=t.elements;return this.set(e[0],e[4],e[8],e[1],e[5],e[9],e[2],e[6],e[10]),this}multiply(t){return this.multiplyMatrices(this,t)}premultiply(t){return this.multiplyMatrices(t,this)}multiplyMatrices(t,e){const i=t.elements,n=e.elements,r=this.elements,s=i[0],a=i[3],o=i[6],l=i[1],c=i[4],h=i[7],u=i[2],d=i[5],p=i[8],f=n[0],m=n[3],g=n[6],v=n[1],x=n[4],_=n[7],y=n[2],M=n[5],b=n[8];return r[0]=s*f+a*v+o*y,r[3]=s*m+a*x+o*M,r[6]=s*g+a*_+o*b,r[1]=l*f+c*v+h*y,r[4]=l*m+c*x+h*M,r[7]=l*g+c*_+h*b,r[2]=u*f+d*v+p*y,r[5]=u*m+d*x+p*M,r[8]=u*g+d*_+p*b,this}multiplyScalar(t){const e=this.elements;return e[0]*=t,e[3]*=t,e[6]*=t,e[1]*=t,e[4]*=t,e[7]*=t,e[2]*=t,e[5]*=t,e[8]*=t,this}determinant(){const t=this.elements,e=t[0],i=t[1],n=t[2],r=t[3],s=t[4],a=t[5],o=t[6],l=t[7],c=t[8];return e*s*c-e*a*l-i*r*c+i*a*o+n*r*l-n*s*o}invert(){const t=this.elements,e=t[0],i=t[1],n=t[2],r=t[3],s=t[4],a=t[5],o=t[6],l=t[7],c=t[8],h=c*s-a*l,u=a*o-c*r,d=l*r-s*o,p=e*h+i*u+n*d;if(0===p)return this.set(0,0,0,0,0,0,0,0,0);const f=1/p;return t[0]=h*f,t[1]=(n*l-c*i)*f,t[2]=(a*i-n*s)*f,t[3]=u*f,t[4]=(c*e-n*o)*f,t[5]=(n*r-a*e)*f,t[6]=d*f,t[7]=(i*o-l*e)*f,t[8]=(s*e-i*r)*f,this}transpose(){let t;const e=this.elements;return t=e[1],e[1]=e[3],e[3]=t,t=e[2],e[2]=e[6],e[6]=t,t=e[5],e[5]=e[7],e[7]=t,this}getNormalMatrix(t){return this.setFromMatrix4(t).invert().transpose()}transposeIntoArray(t){const e=this.elements;return t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],this}setUvTransform(t,e,i,n,r,s,a){const o=Math.cos(r),l=Math.sin(r);return this.set(i*o,i*l,-i*(o*s+l*a)+s+t,-n*l,n*o,-n*(-l*s+o*a)+a+e,0,0,1),this}scale(t,e){const i=this.elements;return i[0]*=t,i[3]*=t,i[6]*=t,i[1]*=e,i[4]*=e,i[7]*=e,this}rotate(t){const e=Math.cos(t),i=Math.sin(t),n=this.elements,r=n[0],s=n[3],a=n[6],o=n[1],l=n[4],c=n[7];return n[0]=e*r+i*o,n[3]=e*s+i*l,n[6]=e*a+i*c,n[1]=-i*r+e*o,n[4]=-i*s+e*l,n[7]=-i*a+e*c,this}translate(t,e){const i=this.elements;return i[0]+=t*i[2],i[3]+=t*i[5],i[6]+=t*i[8],i[1]+=e*i[2],i[4]+=e*i[5],i[7]+=e*i[8],this}equals(t){const e=this.elements,i=t.elements;for(let t=0;t<9;t++)if(e[t]!==i[t])return!1;return!0}fromArray(t,e=0){for(let i=0;i<9;i++)this.elements[i]=t[i+e];return this}toArray(t=[],e=0){const i=this.elements;return t[e]=i[0],t[e+1]=i[1],t[e+2]=i[2],t[e+3]=i[3],t[e+4]=i[4],t[e+5]=i[5],t[e+6]=i[6],t[e+7]=i[7],t[e+8]=i[8],t}clone(){return(new this.constructor).fromArray(this.elements)}}function Lt(t){for(let e=t.length-1;e>=0;--e)if(t[e]>65535)return!0;return!1}const Rt={Int8Array:Int8Array,Uint8Array:Uint8Array,Uint8ClampedArray:Uint8ClampedArray,Int16Array:Int16Array,Uint16Array:Uint16Array,Int32Array:Int32Array,Uint32Array:Uint32Array,Float32Array:Float32Array,Float64Array:Float64Array};function Pt(t,e){return new Rt[t](e)}function It(t){return document.createElementNS("http://www.w3.org/1999/xhtml",t)}function Dt(t){return t<.04045?.0773993808*t:Math.pow(.9478672986*t+.0521327014,2.4)}function Nt(t){return t<.0031308?12.92*t:1.055*Math.pow(t,.41666)-.055}const Ot={[lt]:{[ct]:Dt},[ct]:{[lt]:Nt}},zt={legacyMode:!0,get workingColorSpace(){return ct},set workingColorSpace(t){console.warn("THREE.ColorManagement: .workingColorSpace is readonly.")},convert:function(t,e,i){if(this.legacyMode||e===i||!e||!i)return t;if(Ot[e]&&void 0!==Ot[e][i]){const n=Ot[e][i];return t.r=n(t.r),t.g=n(t.g),t.b=n(t.b),t}throw new Error("Unsupported color space conversion.")},fromWorkingColorSpace:function(t,e){return this.convert(t,this.workingColorSpace,e)},toWorkingColorSpace:function(t,e){return this.convert(t,e,this.workingColorSpace)}},Ft={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074},Bt={r:0,g:0,b:0},Ut={h:0,s:0,l:0},kt={h:0,s:0,l:0};function Gt(t,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+6*(e-t)*(2/3-i):t}function Vt(t,e){return e.r=t.r,e.g=t.g,e.b=t.b,e}class Ht{constructor(t,e,i){return this.isColor=!0,this.r=1,this.g=1,this.b=1,void 0===e&&void 0===i?this.set(t):this.setRGB(t,e,i)}set(t){return t&&t.isColor?this.copy(t):"number"==typeof t?this.setHex(t):"string"==typeof t&&this.setStyle(t),this}setScalar(t){return this.r=t,this.g=t,this.b=t,this}setHex(t,e="srgb"){return t=Math.floor(t),this.r=(t>>16&255)/255,this.g=(t>>8&255)/255,this.b=(255&t)/255,zt.toWorkingColorSpace(this,e),this}setRGB(t,e,i,n="srgb-linear"){return this.r=t,this.g=e,this.b=i,zt.toWorkingColorSpace(this,n),this}setHSL(t,e,i,n="srgb-linear"){if(t=Mt(t,1),e=yt(e,0,1),i=yt(i,0,1),0===e)this.r=this.g=this.b=i;else{const n=i<=.5?i*(1+e):i+e-i*e,r=2*i-n;this.r=Gt(r,n,t+1/3),this.g=Gt(r,n,t),this.b=Gt(r,n,t-1/3)}return zt.toWorkingColorSpace(this,n),this}setStyle(t,e="srgb"){function i(e){void 0!==e&&parseFloat(e)<1&&console.warn("THREE.Color: Alpha component of "+t+" will be ignored.")}let n;if(n=/^((?:rgb|hsl)a?)\(([^\)]*)\)/.exec(t)){let t;const r=n[1],s=n[2];switch(r){case"rgb":case"rgba":if(t=/^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(s))return this.r=Math.min(255,parseInt(t[1],10))/255,this.g=Math.min(255,parseInt(t[2],10))/255,this.b=Math.min(255,parseInt(t[3],10))/255,zt.toWorkingColorSpace(this,e),i(t[4]),this;if(t=/^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(s))return this.r=Math.min(100,parseInt(t[1],10))/100,this.g=Math.min(100,parseInt(t[2],10))/100,this.b=Math.min(100,parseInt(t[3],10))/100,zt.toWorkingColorSpace(this,e),i(t[4]),this;break;case"hsl":case"hsla":if(t=/^\s*(\d*\.?\d+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(s)){const n=parseFloat(t[1])/360,r=parseInt(t[2],10)/100,s=parseInt(t[3],10)/100;return i(t[4]),this.setHSL(n,r,s,e)}}}else if(n=/^\#([A-Fa-f\d]+)$/.exec(t)){const t=n[1],i=t.length;if(3===i)return this.r=parseInt(t.charAt(0)+t.charAt(0),16)/255,this.g=parseInt(t.charAt(1)+t.charAt(1),16)/255,this.b=parseInt(t.charAt(2)+t.charAt(2),16)/255,zt.toWorkingColorSpace(this,e),this;if(6===i)return this.r=parseInt(t.charAt(0)+t.charAt(1),16)/255,this.g=parseInt(t.charAt(2)+t.charAt(3),16)/255,this.b=parseInt(t.charAt(4)+t.charAt(5),16)/255,zt.toWorkingColorSpace(this,e),this}return t&&t.length>0?this.setColorName(t,e):this}setColorName(t,e="srgb"){const i=Ft[t.toLowerCase()];return void 0!==i?this.setHex(i,e):console.warn("THREE.Color: Unknown color "+t),this}clone(){return new this.constructor(this.r,this.g,this.b)}copy(t){return this.r=t.r,this.g=t.g,this.b=t.b,this}copySRGBToLinear(t){return this.r=Dt(t.r),this.g=Dt(t.g),this.b=Dt(t.b),this}copyLinearToSRGB(t){return this.r=Nt(t.r),this.g=Nt(t.g),this.b=Nt(t.b),this}convertSRGBToLinear(){return this.copySRGBToLinear(this),this}convertLinearToSRGB(){return this.copyLinearToSRGB(this),this}getHex(t="srgb"){return zt.fromWorkingColorSpace(Vt(this,Bt),t),yt(255*Bt.r,0,255)<<16^yt(255*Bt.g,0,255)<<8^yt(255*Bt.b,0,255)<<0}getHexString(t="srgb"){return("000000"+this.getHex(t).toString(16)).slice(-6)}getHSL(t,e="srgb-linear"){zt.fromWorkingColorSpace(Vt(this,Bt),e);const i=Bt.r,n=Bt.g,r=Bt.b,s=Math.max(i,n,r),a=Math.min(i,n,r);let o,l;const c=(a+s)/2;if(a===s)o=0,l=0;else{const t=s-a;switch(l=c<=.5?t/(s+a):t/(2-s-a),s){case i:o=(n-r)/t+(n2048||e.height>2048?(console.warn("THREE.ImageUtils.getDataURL: Image converted to jpg for performance reasons",t),e.toDataURL("image/jpeg",.6)):e.toDataURL("image/png")}static sRGBToLinear(t){if("undefined"!=typeof HTMLImageElement&&t instanceof HTMLImageElement||"undefined"!=typeof HTMLCanvasElement&&t instanceof HTMLCanvasElement||"undefined"!=typeof ImageBitmap&&t instanceof ImageBitmap){const e=It("canvas");e.width=t.width,e.height=t.height;const i=e.getContext("2d");i.drawImage(t,0,0,t.width,t.height);const n=i.getImageData(0,0,t.width,t.height),r=n.data;for(let t=0;t1)switch(this.wrapS){case c:t.x=t.x-Math.floor(t.x);break;case h:t.x=t.x<0?0:1;break;case u:1===Math.abs(Math.floor(t.x)%2)?t.x=Math.ceil(t.x)-t.x:t.x=t.x-Math.floor(t.x)}if(t.y<0||t.y>1)switch(this.wrapT){case c:t.y=t.y-Math.floor(t.y);break;case h:t.y=t.y<0?0:1;break;case u:1===Math.abs(Math.floor(t.y)%2)?t.y=Math.ceil(t.y)-t.y:t.y=t.y-Math.floor(t.y)}return this.flipY&&(t.y=1-t.y),t}set needsUpdate(t){!0===t&&(this.version++,this.source.needsUpdate=!0)}}Zt.DEFAULT_IMAGE=null,Zt.DEFAULT_MAPPING=n;class Jt{constructor(t=0,e=0,i=0,n=1){Jt.prototype.isVector4=!0,this.x=t,this.y=e,this.z=i,this.w=n}get width(){return this.z}set width(t){this.z=t}get height(){return this.w}set height(t){this.w=t}set(t,e,i,n){return this.x=t,this.y=e,this.z=i,this.w=n,this}setScalar(t){return this.x=t,this.y=t,this.z=t,this.w=t,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setZ(t){return this.z=t,this}setW(t){return this.w=t,this}setComponent(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;case 2:this.z=e;break;case 3:this.w=e;break;default:throw new Error("index is out of range: "+t)}return this}getComponent(t){switch(t){case 0:return this.x;case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw new Error("index is out of range: "+t)}}clone(){return new this.constructor(this.x,this.y,this.z,this.w)}copy(t){return this.x=t.x,this.y=t.y,this.z=t.z,this.w=void 0!==t.w?t.w:1,this}add(t){return this.x+=t.x,this.y+=t.y,this.z+=t.z,this.w+=t.w,this}addScalar(t){return this.x+=t,this.y+=t,this.z+=t,this.w+=t,this}addVectors(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this.z=t.z+e.z,this.w=t.w+e.w,this}addScaledVector(t,e){return this.x+=t.x*e,this.y+=t.y*e,this.z+=t.z*e,this.w+=t.w*e,this}sub(t){return this.x-=t.x,this.y-=t.y,this.z-=t.z,this.w-=t.w,this}subScalar(t){return this.x-=t,this.y-=t,this.z-=t,this.w-=t,this}subVectors(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this.z=t.z-e.z,this.w=t.w-e.w,this}multiply(t){return this.x*=t.x,this.y*=t.y,this.z*=t.z,this.w*=t.w,this}multiplyScalar(t){return this.x*=t,this.y*=t,this.z*=t,this.w*=t,this}applyMatrix4(t){const e=this.x,i=this.y,n=this.z,r=this.w,s=t.elements;return this.x=s[0]*e+s[4]*i+s[8]*n+s[12]*r,this.y=s[1]*e+s[5]*i+s[9]*n+s[13]*r,this.z=s[2]*e+s[6]*i+s[10]*n+s[14]*r,this.w=s[3]*e+s[7]*i+s[11]*n+s[15]*r,this}divideScalar(t){return this.multiplyScalar(1/t)}setAxisAngleFromQuaternion(t){this.w=2*Math.acos(t.w);const e=Math.sqrt(1-t.w*t.w);return e<1e-4?(this.x=1,this.y=0,this.z=0):(this.x=t.x/e,this.y=t.y/e,this.z=t.z/e),this}setAxisAngleFromRotationMatrix(t){let e,i,n,r;const s=.01,a=.1,o=t.elements,l=o[0],c=o[4],h=o[8],u=o[1],d=o[5],p=o[9],f=o[2],m=o[6],g=o[10];if(Math.abs(c-u)o&&t>v?tv?o=0?1:-1,n=1-e*e;if(n>Number.EPSILON){const r=Math.sqrt(n),s=Math.atan2(r,e*i);t=Math.sin(t*s)/r,a=Math.sin(a*s)/r}const r=a*i;if(o=o*t+u*r,l=l*t+d*r,c=c*t+p*r,h=h*t+f*r,t===1-a){const t=1/Math.sqrt(o*o+l*l+c*c+h*h);o*=t,l*=t,c*=t,h*=t}}t[e]=o,t[e+1]=l,t[e+2]=c,t[e+3]=h}static multiplyQuaternionsFlat(t,e,i,n,r,s){const a=i[n],o=i[n+1],l=i[n+2],c=i[n+3],h=r[s],u=r[s+1],d=r[s+2],p=r[s+3];return t[e]=a*p+c*h+o*d-l*u,t[e+1]=o*p+c*u+l*h-a*d,t[e+2]=l*p+c*d+a*u-o*h,t[e+3]=c*p-a*h-o*u-l*d,t}get x(){return this._x}set x(t){this._x=t,this._onChangeCallback()}get y(){return this._y}set y(t){this._y=t,this._onChangeCallback()}get z(){return this._z}set z(t){this._z=t,this._onChangeCallback()}get w(){return this._w}set w(t){this._w=t,this._onChangeCallback()}set(t,e,i,n){return this._x=t,this._y=e,this._z=i,this._w=n,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._w)}copy(t){return this._x=t.x,this._y=t.y,this._z=t.z,this._w=t.w,this._onChangeCallback(),this}setFromEuler(t,e){if(!t||!t.isEuler)throw new Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.");const i=t._x,n=t._y,r=t._z,s=t._order,a=Math.cos,o=Math.sin,l=a(i/2),c=a(n/2),h=a(r/2),u=o(i/2),d=o(n/2),p=o(r/2);switch(s){case"XYZ":this._x=u*c*h+l*d*p,this._y=l*d*h-u*c*p,this._z=l*c*p+u*d*h,this._w=l*c*h-u*d*p;break;case"YXZ":this._x=u*c*h+l*d*p,this._y=l*d*h-u*c*p,this._z=l*c*p-u*d*h,this._w=l*c*h+u*d*p;break;case"ZXY":this._x=u*c*h-l*d*p,this._y=l*d*h+u*c*p,this._z=l*c*p+u*d*h,this._w=l*c*h-u*d*p;break;case"ZYX":this._x=u*c*h-l*d*p,this._y=l*d*h+u*c*p,this._z=l*c*p-u*d*h,this._w=l*c*h+u*d*p;break;case"YZX":this._x=u*c*h+l*d*p,this._y=l*d*h+u*c*p,this._z=l*c*p-u*d*h,this._w=l*c*h-u*d*p;break;case"XZY":this._x=u*c*h-l*d*p,this._y=l*d*h-u*c*p,this._z=l*c*p+u*d*h,this._w=l*c*h+u*d*p;break;default:console.warn("THREE.Quaternion: .setFromEuler() encountered an unknown order: "+s)}return!1!==e&&this._onChangeCallback(),this}setFromAxisAngle(t,e){const i=e/2,n=Math.sin(i);return this._x=t.x*n,this._y=t.y*n,this._z=t.z*n,this._w=Math.cos(i),this._onChangeCallback(),this}setFromRotationMatrix(t){const e=t.elements,i=e[0],n=e[4],r=e[8],s=e[1],a=e[5],o=e[9],l=e[2],c=e[6],h=e[10],u=i+a+h;if(u>0){const t=.5/Math.sqrt(u+1);this._w=.25/t,this._x=(c-o)*t,this._y=(r-l)*t,this._z=(s-n)*t}else if(i>a&&i>h){const t=2*Math.sqrt(1+i-a-h);this._w=(c-o)/t,this._x=.25*t,this._y=(n+s)/t,this._z=(r+l)/t}else if(a>h){const t=2*Math.sqrt(1+a-i-h);this._w=(r-l)/t,this._x=(n+s)/t,this._y=.25*t,this._z=(o+c)/t}else{const t=2*Math.sqrt(1+h-i-a);this._w=(s-n)/t,this._x=(r+l)/t,this._y=(o+c)/t,this._z=.25*t}return this._onChangeCallback(),this}setFromUnitVectors(t,e){let i=t.dot(e)+1;return iMath.abs(t.z)?(this._x=-t.y,this._y=t.x,this._z=0,this._w=i):(this._x=0,this._y=-t.z,this._z=t.y,this._w=i)):(this._x=t.y*e.z-t.z*e.y,this._y=t.z*e.x-t.x*e.z,this._z=t.x*e.y-t.y*e.x,this._w=i),this.normalize()}angleTo(t){return 2*Math.acos(Math.abs(yt(this.dot(t),-1,1)))}rotateTowards(t,e){const i=this.angleTo(t);if(0===i)return this;const n=Math.min(1,e/i);return this.slerp(t,n),this}identity(){return this.set(0,0,0,1)}invert(){return this.conjugate()}conjugate(){return this._x*=-1,this._y*=-1,this._z*=-1,this._onChangeCallback(),this}dot(t){return this._x*t._x+this._y*t._y+this._z*t._z+this._w*t._w}lengthSq(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w}length(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)}normalize(){let t=this.length();return 0===t?(this._x=0,this._y=0,this._z=0,this._w=1):(t=1/t,this._x=this._x*t,this._y=this._y*t,this._z=this._z*t,this._w=this._w*t),this._onChangeCallback(),this}multiply(t){return this.multiplyQuaternions(this,t)}premultiply(t){return this.multiplyQuaternions(t,this)}multiplyQuaternions(t,e){const i=t._x,n=t._y,r=t._z,s=t._w,a=e._x,o=e._y,l=e._z,c=e._w;return this._x=i*c+s*a+n*l-r*o,this._y=n*c+s*o+r*a-i*l,this._z=r*c+s*l+i*o-n*a,this._w=s*c-i*a-n*o-r*l,this._onChangeCallback(),this}slerp(t,e){if(0===e)return this;if(1===e)return this.copy(t);const i=this._x,n=this._y,r=this._z,s=this._w;let a=s*t._w+i*t._x+n*t._y+r*t._z;if(a<0?(this._w=-t._w,this._x=-t._x,this._y=-t._y,this._z=-t._z,a=-a):this.copy(t),a>=1)return this._w=s,this._x=i,this._y=n,this._z=r,this;const o=1-a*a;if(o<=Number.EPSILON){const t=1-e;return this._w=t*s+e*this._w,this._x=t*i+e*this._x,this._y=t*n+e*this._y,this._z=t*r+e*this._z,this.normalize(),this._onChangeCallback(),this}const l=Math.sqrt(o),c=Math.atan2(l,a),h=Math.sin((1-e)*c)/l,u=Math.sin(e*c)/l;return this._w=s*h+this._w*u,this._x=i*h+this._x*u,this._y=n*h+this._y*u,this._z=r*h+this._z*u,this._onChangeCallback(),this}slerpQuaternions(t,e,i){return this.copy(t).slerp(e,i)}random(){const t=Math.random(),e=Math.sqrt(1-t),i=Math.sqrt(t),n=2*Math.PI*Math.random(),r=2*Math.PI*Math.random();return this.set(e*Math.cos(n),i*Math.sin(r),i*Math.cos(r),e*Math.sin(n))}equals(t){return t._x===this._x&&t._y===this._y&&t._z===this._z&&t._w===this._w}fromArray(t,e=0){return this._x=t[e],this._y=t[e+1],this._z=t[e+2],this._w=t[e+3],this._onChangeCallback(),this}toArray(t=[],e=0){return t[e]=this._x,t[e+1]=this._y,t[e+2]=this._z,t[e+3]=this._w,t}fromBufferAttribute(t,e){return this._x=t.getX(e),this._y=t.getY(e),this._z=t.getZ(e),this._w=t.getW(e),this}_onChange(t){return this._onChangeCallback=t,this}_onChangeCallback(){}*[Symbol.iterator](){yield this._x,yield this._y,yield this._z,yield this._w}}class ee{constructor(t=0,e=0,i=0){ee.prototype.isVector3=!0,this.x=t,this.y=e,this.z=i}set(t,e,i){return void 0===i&&(i=this.z),this.x=t,this.y=e,this.z=i,this}setScalar(t){return this.x=t,this.y=t,this.z=t,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setZ(t){return this.z=t,this}setComponent(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;case 2:this.z=e;break;default:throw new Error("index is out of range: "+t)}return this}getComponent(t){switch(t){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw new Error("index is out of range: "+t)}}clone(){return new this.constructor(this.x,this.y,this.z)}copy(t){return this.x=t.x,this.y=t.y,this.z=t.z,this}add(t){return this.x+=t.x,this.y+=t.y,this.z+=t.z,this}addScalar(t){return this.x+=t,this.y+=t,this.z+=t,this}addVectors(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this.z=t.z+e.z,this}addScaledVector(t,e){return this.x+=t.x*e,this.y+=t.y*e,this.z+=t.z*e,this}sub(t){return this.x-=t.x,this.y-=t.y,this.z-=t.z,this}subScalar(t){return this.x-=t,this.y-=t,this.z-=t,this}subVectors(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this.z=t.z-e.z,this}multiply(t){return this.x*=t.x,this.y*=t.y,this.z*=t.z,this}multiplyScalar(t){return this.x*=t,this.y*=t,this.z*=t,this}multiplyVectors(t,e){return this.x=t.x*e.x,this.y=t.y*e.y,this.z=t.z*e.z,this}applyEuler(t){return this.applyQuaternion(ne.setFromEuler(t))}applyAxisAngle(t,e){return this.applyQuaternion(ne.setFromAxisAngle(t,e))}applyMatrix3(t){const e=this.x,i=this.y,n=this.z,r=t.elements;return this.x=r[0]*e+r[3]*i+r[6]*n,this.y=r[1]*e+r[4]*i+r[7]*n,this.z=r[2]*e+r[5]*i+r[8]*n,this}applyNormalMatrix(t){return this.applyMatrix3(t).normalize()}applyMatrix4(t){const e=this.x,i=this.y,n=this.z,r=t.elements,s=1/(r[3]*e+r[7]*i+r[11]*n+r[15]);return this.x=(r[0]*e+r[4]*i+r[8]*n+r[12])*s,this.y=(r[1]*e+r[5]*i+r[9]*n+r[13])*s,this.z=(r[2]*e+r[6]*i+r[10]*n+r[14])*s,this}applyQuaternion(t){const e=this.x,i=this.y,n=this.z,r=t.x,s=t.y,a=t.z,o=t.w,l=o*e+s*n-a*i,c=o*i+a*e-r*n,h=o*n+r*i-s*e,u=-r*e-s*i-a*n;return this.x=l*o+u*-r+c*-a-h*-s,this.y=c*o+u*-s+h*-r-l*-a,this.z=h*o+u*-a+l*-s-c*-r,this}project(t){return this.applyMatrix4(t.matrixWorldInverse).applyMatrix4(t.projectionMatrix)}unproject(t){return this.applyMatrix4(t.projectionMatrixInverse).applyMatrix4(t.matrixWorld)}transformDirection(t){const e=this.x,i=this.y,n=this.z,r=t.elements;return this.x=r[0]*e+r[4]*i+r[8]*n,this.y=r[1]*e+r[5]*i+r[9]*n,this.z=r[2]*e+r[6]*i+r[10]*n,this.normalize()}divide(t){return this.x/=t.x,this.y/=t.y,this.z/=t.z,this}divideScalar(t){return this.multiplyScalar(1/t)}min(t){return this.x=Math.min(this.x,t.x),this.y=Math.min(this.y,t.y),this.z=Math.min(this.z,t.z),this}max(t){return this.x=Math.max(this.x,t.x),this.y=Math.max(this.y,t.y),this.z=Math.max(this.z,t.z),this}clamp(t,e){return this.x=Math.max(t.x,Math.min(e.x,this.x)),this.y=Math.max(t.y,Math.min(e.y,this.y)),this.z=Math.max(t.z,Math.min(e.z,this.z)),this}clampScalar(t,e){return this.x=Math.max(t,Math.min(e,this.x)),this.y=Math.max(t,Math.min(e,this.y)),this.z=Math.max(t,Math.min(e,this.z)),this}clampLength(t,e){const i=this.length();return this.divideScalar(i||1).multiplyScalar(Math.max(t,Math.min(e,i)))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.z=Math.floor(this.z),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=Math.ceil(this.z),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.z=Math.round(this.z),this}roundToZero(){return this.x=this.x<0?Math.ceil(this.x):Math.floor(this.x),this.y=this.y<0?Math.ceil(this.y):Math.floor(this.y),this.z=this.z<0?Math.ceil(this.z):Math.floor(this.z),this}negate(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this}dot(t){return this.x*t.x+this.y*t.y+this.z*t.z}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)}normalize(){return this.divideScalar(this.length()||1)}setLength(t){return this.normalize().multiplyScalar(t)}lerp(t,e){return this.x+=(t.x-this.x)*e,this.y+=(t.y-this.y)*e,this.z+=(t.z-this.z)*e,this}lerpVectors(t,e,i){return this.x=t.x+(e.x-t.x)*i,this.y=t.y+(e.y-t.y)*i,this.z=t.z+(e.z-t.z)*i,this}cross(t){return this.crossVectors(this,t)}crossVectors(t,e){const i=t.x,n=t.y,r=t.z,s=e.x,a=e.y,o=e.z;return this.x=n*o-r*a,this.y=r*s-i*o,this.z=i*a-n*s,this}projectOnVector(t){const e=t.lengthSq();if(0===e)return this.set(0,0,0);const i=t.dot(this)/e;return this.copy(t).multiplyScalar(i)}projectOnPlane(t){return ie.copy(this).projectOnVector(t),this.sub(ie)}reflect(t){return this.sub(ie.copy(t).multiplyScalar(2*this.dot(t)))}angleTo(t){const e=Math.sqrt(this.lengthSq()*t.lengthSq());if(0===e)return Math.PI/2;const i=this.dot(t)/e;return Math.acos(yt(i,-1,1))}distanceTo(t){return Math.sqrt(this.distanceToSquared(t))}distanceToSquared(t){const e=this.x-t.x,i=this.y-t.y,n=this.z-t.z;return e*e+i*i+n*n}manhattanDistanceTo(t){return Math.abs(this.x-t.x)+Math.abs(this.y-t.y)+Math.abs(this.z-t.z)}setFromSpherical(t){return this.setFromSphericalCoords(t.radius,t.phi,t.theta)}setFromSphericalCoords(t,e,i){const n=Math.sin(e)*t;return this.x=n*Math.sin(i),this.y=Math.cos(e)*t,this.z=n*Math.cos(i),this}setFromCylindrical(t){return this.setFromCylindricalCoords(t.radius,t.theta,t.y)}setFromCylindricalCoords(t,e,i){return this.x=t*Math.sin(e),this.y=i,this.z=t*Math.cos(e),this}setFromMatrixPosition(t){const e=t.elements;return this.x=e[12],this.y=e[13],this.z=e[14],this}setFromMatrixScale(t){const e=this.setFromMatrixColumn(t,0).length(),i=this.setFromMatrixColumn(t,1).length(),n=this.setFromMatrixColumn(t,2).length();return this.x=e,this.y=i,this.z=n,this}setFromMatrixColumn(t,e){return this.fromArray(t.elements,4*e)}setFromMatrix3Column(t,e){return this.fromArray(t.elements,3*e)}setFromEuler(t){return this.x=t._x,this.y=t._y,this.z=t._z,this}equals(t){return t.x===this.x&&t.y===this.y&&t.z===this.z}fromArray(t,e=0){return this.x=t[e],this.y=t[e+1],this.z=t[e+2],this}toArray(t=[],e=0){return t[e]=this.x,t[e+1]=this.y,t[e+2]=this.z,t}fromBufferAttribute(t,e){return this.x=t.getX(e),this.y=t.getY(e),this.z=t.getZ(e),this}random(){return this.x=Math.random(),this.y=Math.random(),this.z=Math.random(),this}randomDirection(){const t=2*(Math.random()-.5),e=Math.random()*Math.PI*2,i=Math.sqrt(1-t**2);return this.x=i*Math.cos(e),this.y=i*Math.sin(e),this.z=t,this}*[Symbol.iterator](){yield this.x,yield this.y,yield this.z}}const ie=new ee,ne=new te;class re{constructor(t=new ee(1/0,1/0,1/0),e=new ee(-1/0,-1/0,-1/0)){this.isBox3=!0,this.min=t,this.max=e}set(t,e){return this.min.copy(t),this.max.copy(e),this}setFromArray(t){let e=1/0,i=1/0,n=1/0,r=-1/0,s=-1/0,a=-1/0;for(let o=0,l=t.length;or&&(r=l),c>s&&(s=c),h>a&&(a=h)}return this.min.set(e,i,n),this.max.set(r,s,a),this}setFromBufferAttribute(t){let e=1/0,i=1/0,n=1/0,r=-1/0,s=-1/0,a=-1/0;for(let o=0,l=t.count;or&&(r=l),c>s&&(s=c),h>a&&(a=h)}return this.min.set(e,i,n),this.max.set(r,s,a),this}setFromPoints(t){this.makeEmpty();for(let e=0,i=t.length;ethis.max.x||t.ythis.max.y||t.zthis.max.z)}containsBox(t){return this.min.x<=t.min.x&&t.max.x<=this.max.x&&this.min.y<=t.min.y&&t.max.y<=this.max.y&&this.min.z<=t.min.z&&t.max.z<=this.max.z}getParameter(t,e){return e.set((t.x-this.min.x)/(this.max.x-this.min.x),(t.y-this.min.y)/(this.max.y-this.min.y),(t.z-this.min.z)/(this.max.z-this.min.z))}intersectsBox(t){return!(t.max.xthis.max.x||t.max.ythis.max.y||t.max.zthis.max.z)}intersectsSphere(t){return this.clampPoint(t.center,ae),ae.distanceToSquared(t.center)<=t.radius*t.radius}intersectsPlane(t){let e,i;return t.normal.x>0?(e=t.normal.x*this.min.x,i=t.normal.x*this.max.x):(e=t.normal.x*this.max.x,i=t.normal.x*this.min.x),t.normal.y>0?(e+=t.normal.y*this.min.y,i+=t.normal.y*this.max.y):(e+=t.normal.y*this.max.y,i+=t.normal.y*this.min.y),t.normal.z>0?(e+=t.normal.z*this.min.z,i+=t.normal.z*this.max.z):(e+=t.normal.z*this.max.z,i+=t.normal.z*this.min.z),e<=-t.constant&&i>=-t.constant}intersectsTriangle(t){if(this.isEmpty())return!1;this.getCenter(fe),me.subVectors(this.max,fe),le.subVectors(t.a,fe),ce.subVectors(t.b,fe),he.subVectors(t.c,fe),ue.subVectors(ce,le),de.subVectors(he,ce),pe.subVectors(le,he);let e=[0,-ue.z,ue.y,0,-de.z,de.y,0,-pe.z,pe.y,ue.z,0,-ue.x,de.z,0,-de.x,pe.z,0,-pe.x,-ue.y,ue.x,0,-de.y,de.x,0,-pe.y,pe.x,0];return!!xe(e,le,ce,he,me)&&(e=[1,0,0,0,1,0,0,0,1],!!xe(e,le,ce,he,me)&&(ge.crossVectors(ue,de),e=[ge.x,ge.y,ge.z],xe(e,le,ce,he,me)))}clampPoint(t,e){return e.copy(t).clamp(this.min,this.max)}distanceToPoint(t){return ae.copy(t).clamp(this.min,this.max).sub(t).length()}getBoundingSphere(t){return this.getCenter(t.center),t.radius=.5*this.getSize(ae).length(),t}intersect(t){return this.min.max(t.min),this.max.min(t.max),this.isEmpty()&&this.makeEmpty(),this}union(t){return this.min.min(t.min),this.max.max(t.max),this}applyMatrix4(t){return this.isEmpty()||(se[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(t),se[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(t),se[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(t),se[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(t),se[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(t),se[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(t),se[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(t),se[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(t),this.setFromPoints(se)),this}translate(t){return this.min.add(t),this.max.add(t),this}equals(t){return t.min.equals(this.min)&&t.max.equals(this.max)}}const se=[new ee,new ee,new ee,new ee,new ee,new ee,new ee,new ee],ae=new ee,oe=new re,le=new ee,ce=new ee,he=new ee,ue=new ee,de=new ee,pe=new ee,fe=new ee,me=new ee,ge=new ee,ve=new ee;function xe(t,e,i,n,r){for(let s=0,a=t.length-3;s<=a;s+=3){ve.fromArray(t,s);const a=r.x*Math.abs(ve.x)+r.y*Math.abs(ve.y)+r.z*Math.abs(ve.z),o=e.dot(ve),l=i.dot(ve),c=n.dot(ve);if(Math.max(-Math.max(o,l,c),Math.min(o,l,c))>a)return!1}return!0}const _e=new re,ye=new ee,Me=new ee,be=new ee;class we{constructor(t=new ee,e=-1){this.center=t,this.radius=e}set(t,e){return this.center.copy(t),this.radius=e,this}setFromPoints(t,e){const i=this.center;void 0!==e?i.copy(e):_e.setFromPoints(t).getCenter(i);let n=0;for(let e=0,r=t.length;ethis.radius*this.radius&&(e.sub(this.center).normalize(),e.multiplyScalar(this.radius).add(this.center)),e}getBoundingBox(t){return this.isEmpty()?(t.makeEmpty(),t):(t.set(this.center,this.center),t.expandByScalar(this.radius),t)}applyMatrix4(t){return this.center.applyMatrix4(t),this.radius=this.radius*t.getMaxScaleOnAxis(),this}translate(t){return this.center.add(t),this}expandByPoint(t){be.subVectors(t,this.center);const e=be.lengthSq();if(e>this.radius*this.radius){const t=Math.sqrt(e),i=.5*(t-this.radius);this.center.add(be.multiplyScalar(i/t)),this.radius+=i}return this}union(t){return!0===this.center.equals(t.center)?Me.set(0,0,1).multiplyScalar(t.radius):Me.subVectors(t.center,this.center).normalize().multiplyScalar(t.radius),this.expandByPoint(ye.copy(t.center).add(Me)),this.expandByPoint(ye.copy(t.center).sub(Me)),this}equals(t){return t.center.equals(this.center)&&t.radius===this.radius}clone(){return(new this.constructor).copy(this)}}const Se=new ee,Te=new ee,Ae=new ee,Ee=new ee,Ce=new ee,Le=new ee,Re=new ee;class Pe{constructor(t=new ee,e=new ee(0,0,-1)){this.origin=t,this.direction=e}set(t,e){return this.origin.copy(t),this.direction.copy(e),this}copy(t){return this.origin.copy(t.origin),this.direction.copy(t.direction),this}at(t,e){return e.copy(this.direction).multiplyScalar(t).add(this.origin)}lookAt(t){return this.direction.copy(t).sub(this.origin).normalize(),this}recast(t){return this.origin.copy(this.at(t,Se)),this}closestPointToPoint(t,e){e.subVectors(t,this.origin);const i=e.dot(this.direction);return i<0?e.copy(this.origin):e.copy(this.direction).multiplyScalar(i).add(this.origin)}distanceToPoint(t){return Math.sqrt(this.distanceSqToPoint(t))}distanceSqToPoint(t){const e=Se.subVectors(t,this.origin).dot(this.direction);return e<0?this.origin.distanceToSquared(t):(Se.copy(this.direction).multiplyScalar(e).add(this.origin),Se.distanceToSquared(t))}distanceSqToSegment(t,e,i,n){Te.copy(t).add(e).multiplyScalar(.5),Ae.copy(e).sub(t).normalize(),Ee.copy(this.origin).sub(Te);const r=.5*t.distanceTo(e),s=-this.direction.dot(Ae),a=Ee.dot(this.direction),o=-Ee.dot(Ae),l=Ee.lengthSq(),c=Math.abs(1-s*s);let h,u,d,p;if(c>0)if(h=s*o-a,u=s*a-o,p=r*c,h>=0)if(u>=-p)if(u<=p){const t=1/c;h*=t,u*=t,d=h*(h+s*u+2*a)+u*(s*h+u+2*o)+l}else u=r,h=Math.max(0,-(s*u+a)),d=-h*h+u*(u+2*o)+l;else u=-r,h=Math.max(0,-(s*u+a)),d=-h*h+u*(u+2*o)+l;else u<=-p?(h=Math.max(0,-(-s*r+a)),u=h>0?-r:Math.min(Math.max(-r,-o),r),d=-h*h+u*(u+2*o)+l):u<=p?(h=0,u=Math.min(Math.max(-r,-o),r),d=u*(u+2*o)+l):(h=Math.max(0,-(s*r+a)),u=h>0?r:Math.min(Math.max(-r,-o),r),d=-h*h+u*(u+2*o)+l);else u=s>0?-r:r,h=Math.max(0,-(s*u+a)),d=-h*h+u*(u+2*o)+l;return i&&i.copy(this.direction).multiplyScalar(h).add(this.origin),n&&n.copy(Ae).multiplyScalar(u).add(Te),d}intersectSphere(t,e){Se.subVectors(t.center,this.origin);const i=Se.dot(this.direction),n=Se.dot(Se)-i*i,r=t.radius*t.radius;if(n>r)return null;const s=Math.sqrt(r-n),a=i-s,o=i+s;return a<0&&o<0?null:a<0?this.at(o,e):this.at(a,e)}intersectsSphere(t){return this.distanceSqToPoint(t.center)<=t.radius*t.radius}distanceToPlane(t){const e=t.normal.dot(this.direction);if(0===e)return 0===t.distanceToPoint(this.origin)?0:null;const i=-(this.origin.dot(t.normal)+t.constant)/e;return i>=0?i:null}intersectPlane(t,e){const i=this.distanceToPlane(t);return null===i?null:this.at(i,e)}intersectsPlane(t){const e=t.distanceToPoint(this.origin);if(0===e)return!0;return t.normal.dot(this.direction)*e<0}intersectBox(t,e){let i,n,r,s,a,o;const l=1/this.direction.x,c=1/this.direction.y,h=1/this.direction.z,u=this.origin;return l>=0?(i=(t.min.x-u.x)*l,n=(t.max.x-u.x)*l):(i=(t.max.x-u.x)*l,n=(t.min.x-u.x)*l),c>=0?(r=(t.min.y-u.y)*c,s=(t.max.y-u.y)*c):(r=(t.max.y-u.y)*c,s=(t.min.y-u.y)*c),i>s||r>n?null:((r>i||i!=i)&&(i=r),(s=0?(a=(t.min.z-u.z)*h,o=(t.max.z-u.z)*h):(a=(t.max.z-u.z)*h,o=(t.min.z-u.z)*h),i>o||a>n?null:((a>i||i!=i)&&(i=a),(o=0?i:n,e)))}intersectsBox(t){return null!==this.intersectBox(t,Se)}intersectTriangle(t,e,i,n,r){Ce.subVectors(e,t),Le.subVectors(i,t),Re.crossVectors(Ce,Le);let s,a=this.direction.dot(Re);if(a>0){if(n)return null;s=1}else{if(!(a<0))return null;s=-1,a=-a}Ee.subVectors(this.origin,t);const o=s*this.direction.dot(Le.crossVectors(Ee,Le));if(o<0)return null;const l=s*this.direction.dot(Ce.cross(Ee));if(l<0)return null;if(o+l>a)return null;const c=-s*Ee.dot(Re);return c<0?null:this.at(c/a,r)}applyMatrix4(t){return this.origin.applyMatrix4(t),this.direction.transformDirection(t),this}equals(t){return t.origin.equals(this.origin)&&t.direction.equals(this.direction)}clone(){return(new this.constructor).copy(this)}}class Ie{constructor(){Ie.prototype.isMatrix4=!0,this.elements=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]}set(t,e,i,n,r,s,a,o,l,c,h,u,d,p,f,m){const g=this.elements;return g[0]=t,g[4]=e,g[8]=i,g[12]=n,g[1]=r,g[5]=s,g[9]=a,g[13]=o,g[2]=l,g[6]=c,g[10]=h,g[14]=u,g[3]=d,g[7]=p,g[11]=f,g[15]=m,this}identity(){return this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1),this}clone(){return(new Ie).fromArray(this.elements)}copy(t){const e=this.elements,i=t.elements;return e[0]=i[0],e[1]=i[1],e[2]=i[2],e[3]=i[3],e[4]=i[4],e[5]=i[5],e[6]=i[6],e[7]=i[7],e[8]=i[8],e[9]=i[9],e[10]=i[10],e[11]=i[11],e[12]=i[12],e[13]=i[13],e[14]=i[14],e[15]=i[15],this}copyPosition(t){const e=this.elements,i=t.elements;return e[12]=i[12],e[13]=i[13],e[14]=i[14],this}setFromMatrix3(t){const e=t.elements;return this.set(e[0],e[3],e[6],0,e[1],e[4],e[7],0,e[2],e[5],e[8],0,0,0,0,1),this}extractBasis(t,e,i){return t.setFromMatrixColumn(this,0),e.setFromMatrixColumn(this,1),i.setFromMatrixColumn(this,2),this}makeBasis(t,e,i){return this.set(t.x,e.x,i.x,0,t.y,e.y,i.y,0,t.z,e.z,i.z,0,0,0,0,1),this}extractRotation(t){const e=this.elements,i=t.elements,n=1/De.setFromMatrixColumn(t,0).length(),r=1/De.setFromMatrixColumn(t,1).length(),s=1/De.setFromMatrixColumn(t,2).length();return e[0]=i[0]*n,e[1]=i[1]*n,e[2]=i[2]*n,e[3]=0,e[4]=i[4]*r,e[5]=i[5]*r,e[6]=i[6]*r,e[7]=0,e[8]=i[8]*s,e[9]=i[9]*s,e[10]=i[10]*s,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,this}makeRotationFromEuler(t){const e=this.elements,i=t.x,n=t.y,r=t.z,s=Math.cos(i),a=Math.sin(i),o=Math.cos(n),l=Math.sin(n),c=Math.cos(r),h=Math.sin(r);if("XYZ"===t.order){const t=s*c,i=s*h,n=a*c,r=a*h;e[0]=o*c,e[4]=-o*h,e[8]=l,e[1]=i+n*l,e[5]=t-r*l,e[9]=-a*o,e[2]=r-t*l,e[6]=n+i*l,e[10]=s*o}else if("YXZ"===t.order){const t=o*c,i=o*h,n=l*c,r=l*h;e[0]=t+r*a,e[4]=n*a-i,e[8]=s*l,e[1]=s*h,e[5]=s*c,e[9]=-a,e[2]=i*a-n,e[6]=r+t*a,e[10]=s*o}else if("ZXY"===t.order){const t=o*c,i=o*h,n=l*c,r=l*h;e[0]=t-r*a,e[4]=-s*h,e[8]=n+i*a,e[1]=i+n*a,e[5]=s*c,e[9]=r-t*a,e[2]=-s*l,e[6]=a,e[10]=s*o}else if("ZYX"===t.order){const t=s*c,i=s*h,n=a*c,r=a*h;e[0]=o*c,e[4]=n*l-i,e[8]=t*l+r,e[1]=o*h,e[5]=r*l+t,e[9]=i*l-n,e[2]=-l,e[6]=a*o,e[10]=s*o}else if("YZX"===t.order){const t=s*o,i=s*l,n=a*o,r=a*l;e[0]=o*c,e[4]=r-t*h,e[8]=n*h+i,e[1]=h,e[5]=s*c,e[9]=-a*c,e[2]=-l*c,e[6]=i*h+n,e[10]=t-r*h}else if("XZY"===t.order){const t=s*o,i=s*l,n=a*o,r=a*l;e[0]=o*c,e[4]=-h,e[8]=l*c,e[1]=t*h+r,e[5]=s*c,e[9]=i*h-n,e[2]=n*h-i,e[6]=a*c,e[10]=r*h+t}return e[3]=0,e[7]=0,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,this}makeRotationFromQuaternion(t){return this.compose(Oe,t,ze)}lookAt(t,e,i){const n=this.elements;return Ue.subVectors(t,e),0===Ue.lengthSq()&&(Ue.z=1),Ue.normalize(),Fe.crossVectors(i,Ue),0===Fe.lengthSq()&&(1===Math.abs(i.z)?Ue.x+=1e-4:Ue.z+=1e-4,Ue.normalize(),Fe.crossVectors(i,Ue)),Fe.normalize(),Be.crossVectors(Ue,Fe),n[0]=Fe.x,n[4]=Be.x,n[8]=Ue.x,n[1]=Fe.y,n[5]=Be.y,n[9]=Ue.y,n[2]=Fe.z,n[6]=Be.z,n[10]=Ue.z,this}multiply(t){return this.multiplyMatrices(this,t)}premultiply(t){return this.multiplyMatrices(t,this)}multiplyMatrices(t,e){const i=t.elements,n=e.elements,r=this.elements,s=i[0],a=i[4],o=i[8],l=i[12],c=i[1],h=i[5],u=i[9],d=i[13],p=i[2],f=i[6],m=i[10],g=i[14],v=i[3],x=i[7],_=i[11],y=i[15],M=n[0],b=n[4],w=n[8],S=n[12],T=n[1],A=n[5],E=n[9],C=n[13],L=n[2],R=n[6],P=n[10],I=n[14],D=n[3],N=n[7],O=n[11],z=n[15];return r[0]=s*M+a*T+o*L+l*D,r[4]=s*b+a*A+o*R+l*N,r[8]=s*w+a*E+o*P+l*O,r[12]=s*S+a*C+o*I+l*z,r[1]=c*M+h*T+u*L+d*D,r[5]=c*b+h*A+u*R+d*N,r[9]=c*w+h*E+u*P+d*O,r[13]=c*S+h*C+u*I+d*z,r[2]=p*M+f*T+m*L+g*D,r[6]=p*b+f*A+m*R+g*N,r[10]=p*w+f*E+m*P+g*O,r[14]=p*S+f*C+m*I+g*z,r[3]=v*M+x*T+_*L+y*D,r[7]=v*b+x*A+_*R+y*N,r[11]=v*w+x*E+_*P+y*O,r[15]=v*S+x*C+_*I+y*z,this}multiplyScalar(t){const e=this.elements;return e[0]*=t,e[4]*=t,e[8]*=t,e[12]*=t,e[1]*=t,e[5]*=t,e[9]*=t,e[13]*=t,e[2]*=t,e[6]*=t,e[10]*=t,e[14]*=t,e[3]*=t,e[7]*=t,e[11]*=t,e[15]*=t,this}determinant(){const t=this.elements,e=t[0],i=t[4],n=t[8],r=t[12],s=t[1],a=t[5],o=t[9],l=t[13],c=t[2],h=t[6],u=t[10],d=t[14];return t[3]*(+r*o*h-n*l*h-r*a*u+i*l*u+n*a*d-i*o*d)+t[7]*(+e*o*d-e*l*u+r*s*u-n*s*d+n*l*c-r*o*c)+t[11]*(+e*l*h-e*a*d-r*s*h+i*s*d+r*a*c-i*l*c)+t[15]*(-n*a*c-e*o*h+e*a*u+n*s*h-i*s*u+i*o*c)}transpose(){const t=this.elements;let e;return e=t[1],t[1]=t[4],t[4]=e,e=t[2],t[2]=t[8],t[8]=e,e=t[6],t[6]=t[9],t[9]=e,e=t[3],t[3]=t[12],t[12]=e,e=t[7],t[7]=t[13],t[13]=e,e=t[11],t[11]=t[14],t[14]=e,this}setPosition(t,e,i){const n=this.elements;return t.isVector3?(n[12]=t.x,n[13]=t.y,n[14]=t.z):(n[12]=t,n[13]=e,n[14]=i),this}invert(){const t=this.elements,e=t[0],i=t[1],n=t[2],r=t[3],s=t[4],a=t[5],o=t[6],l=t[7],c=t[8],h=t[9],u=t[10],d=t[11],p=t[12],f=t[13],m=t[14],g=t[15],v=h*m*l-f*u*l+f*o*d-a*m*d-h*o*g+a*u*g,x=p*u*l-c*m*l-p*o*d+s*m*d+c*o*g-s*u*g,_=c*f*l-p*h*l+p*a*d-s*f*d-c*a*g+s*h*g,y=p*h*o-c*f*o-p*a*u+s*f*u+c*a*m-s*h*m,M=e*v+i*x+n*_+r*y;if(0===M)return this.set(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);const b=1/M;return t[0]=v*b,t[1]=(f*u*r-h*m*r-f*n*d+i*m*d+h*n*g-i*u*g)*b,t[2]=(a*m*r-f*o*r+f*n*l-i*m*l-a*n*g+i*o*g)*b,t[3]=(h*o*r-a*u*r-h*n*l+i*u*l+a*n*d-i*o*d)*b,t[4]=x*b,t[5]=(c*m*r-p*u*r+p*n*d-e*m*d-c*n*g+e*u*g)*b,t[6]=(p*o*r-s*m*r-p*n*l+e*m*l+s*n*g-e*o*g)*b,t[7]=(s*u*r-c*o*r+c*n*l-e*u*l-s*n*d+e*o*d)*b,t[8]=_*b,t[9]=(p*h*r-c*f*r-p*i*d+e*f*d+c*i*g-e*h*g)*b,t[10]=(s*f*r-p*a*r+p*i*l-e*f*l-s*i*g+e*a*g)*b,t[11]=(c*a*r-s*h*r-c*i*l+e*h*l+s*i*d-e*a*d)*b,t[12]=y*b,t[13]=(c*f*n-p*h*n+p*i*u-e*f*u-c*i*m+e*h*m)*b,t[14]=(p*a*n-s*f*n-p*i*o+e*f*o+s*i*m-e*a*m)*b,t[15]=(s*h*n-c*a*n+c*i*o-e*h*o-s*i*u+e*a*u)*b,this}scale(t){const e=this.elements,i=t.x,n=t.y,r=t.z;return e[0]*=i,e[4]*=n,e[8]*=r,e[1]*=i,e[5]*=n,e[9]*=r,e[2]*=i,e[6]*=n,e[10]*=r,e[3]*=i,e[7]*=n,e[11]*=r,this}getMaxScaleOnAxis(){const t=this.elements,e=t[0]*t[0]+t[1]*t[1]+t[2]*t[2],i=t[4]*t[4]+t[5]*t[5]+t[6]*t[6],n=t[8]*t[8]+t[9]*t[9]+t[10]*t[10];return Math.sqrt(Math.max(e,i,n))}makeTranslation(t,e,i){return this.set(1,0,0,t,0,1,0,e,0,0,1,i,0,0,0,1),this}makeRotationX(t){const e=Math.cos(t),i=Math.sin(t);return this.set(1,0,0,0,0,e,-i,0,0,i,e,0,0,0,0,1),this}makeRotationY(t){const e=Math.cos(t),i=Math.sin(t);return this.set(e,0,i,0,0,1,0,0,-i,0,e,0,0,0,0,1),this}makeRotationZ(t){const e=Math.cos(t),i=Math.sin(t);return this.set(e,-i,0,0,i,e,0,0,0,0,1,0,0,0,0,1),this}makeRotationAxis(t,e){const i=Math.cos(e),n=Math.sin(e),r=1-i,s=t.x,a=t.y,o=t.z,l=r*s,c=r*a;return this.set(l*s+i,l*a-n*o,l*o+n*a,0,l*a+n*o,c*a+i,c*o-n*s,0,l*o-n*a,c*o+n*s,r*o*o+i,0,0,0,0,1),this}makeScale(t,e,i){return this.set(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1),this}makeShear(t,e,i,n,r,s){return this.set(1,i,r,0,t,1,s,0,e,n,1,0,0,0,0,1),this}compose(t,e,i){const n=this.elements,r=e._x,s=e._y,a=e._z,o=e._w,l=r+r,c=s+s,h=a+a,u=r*l,d=r*c,p=r*h,f=s*c,m=s*h,g=a*h,v=o*l,x=o*c,_=o*h,y=i.x,M=i.y,b=i.z;return n[0]=(1-(f+g))*y,n[1]=(d+_)*y,n[2]=(p-x)*y,n[3]=0,n[4]=(d-_)*M,n[5]=(1-(u+g))*M,n[6]=(m+v)*M,n[7]=0,n[8]=(p+x)*b,n[9]=(m-v)*b,n[10]=(1-(u+f))*b,n[11]=0,n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=1,this}decompose(t,e,i){const n=this.elements;let r=De.set(n[0],n[1],n[2]).length();const s=De.set(n[4],n[5],n[6]).length(),a=De.set(n[8],n[9],n[10]).length();this.determinant()<0&&(r=-r),t.x=n[12],t.y=n[13],t.z=n[14],Ne.copy(this);const o=1/r,l=1/s,c=1/a;return Ne.elements[0]*=o,Ne.elements[1]*=o,Ne.elements[2]*=o,Ne.elements[4]*=l,Ne.elements[5]*=l,Ne.elements[6]*=l,Ne.elements[8]*=c,Ne.elements[9]*=c,Ne.elements[10]*=c,e.setFromRotationMatrix(Ne),i.x=r,i.y=s,i.z=a,this}makePerspective(t,e,i,n,r,s){const a=this.elements,o=2*r/(e-t),l=2*r/(i-n),c=(e+t)/(e-t),h=(i+n)/(i-n),u=-(s+r)/(s-r),d=-2*s*r/(s-r);return a[0]=o,a[4]=0,a[8]=c,a[12]=0,a[1]=0,a[5]=l,a[9]=h,a[13]=0,a[2]=0,a[6]=0,a[10]=u,a[14]=d,a[3]=0,a[7]=0,a[11]=-1,a[15]=0,this}makeOrthographic(t,e,i,n,r,s){const a=this.elements,o=1/(e-t),l=1/(i-n),c=1/(s-r),h=(e+t)*o,u=(i+n)*l,d=(s+r)*c;return a[0]=2*o,a[4]=0,a[8]=0,a[12]=-h,a[1]=0,a[5]=2*l,a[9]=0,a[13]=-u,a[2]=0,a[6]=0,a[10]=-2*c,a[14]=-d,a[3]=0,a[7]=0,a[11]=0,a[15]=1,this}equals(t){const e=this.elements,i=t.elements;for(let t=0;t<16;t++)if(e[t]!==i[t])return!1;return!0}fromArray(t,e=0){for(let i=0;i<16;i++)this.elements[i]=t[i+e];return this}toArray(t=[],e=0){const i=this.elements;return t[e]=i[0],t[e+1]=i[1],t[e+2]=i[2],t[e+3]=i[3],t[e+4]=i[4],t[e+5]=i[5],t[e+6]=i[6],t[e+7]=i[7],t[e+8]=i[8],t[e+9]=i[9],t[e+10]=i[10],t[e+11]=i[11],t[e+12]=i[12],t[e+13]=i[13],t[e+14]=i[14],t[e+15]=i[15],t}}const De=new ee,Ne=new Ie,Oe=new ee(0,0,0),ze=new ee(1,1,1),Fe=new ee,Be=new ee,Ue=new ee,ke=new Ie,Ge=new te;class Ve{constructor(t=0,e=0,i=0,n=Ve.DefaultOrder){this.isEuler=!0,this._x=t,this._y=e,this._z=i,this._order=n}get x(){return this._x}set x(t){this._x=t,this._onChangeCallback()}get y(){return this._y}set y(t){this._y=t,this._onChangeCallback()}get z(){return this._z}set z(t){this._z=t,this._onChangeCallback()}get order(){return this._order}set order(t){this._order=t,this._onChangeCallback()}set(t,e,i,n=this._order){return this._x=t,this._y=e,this._z=i,this._order=n,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._order)}copy(t){return this._x=t._x,this._y=t._y,this._z=t._z,this._order=t._order,this._onChangeCallback(),this}setFromRotationMatrix(t,e=this._order,i=!0){const n=t.elements,r=n[0],s=n[4],a=n[8],o=n[1],l=n[5],c=n[9],h=n[2],u=n[6],d=n[10];switch(e){case"XYZ":this._y=Math.asin(yt(a,-1,1)),Math.abs(a)<.9999999?(this._x=Math.atan2(-c,d),this._z=Math.atan2(-s,r)):(this._x=Math.atan2(u,l),this._z=0);break;case"YXZ":this._x=Math.asin(-yt(c,-1,1)),Math.abs(c)<.9999999?(this._y=Math.atan2(a,d),this._z=Math.atan2(o,l)):(this._y=Math.atan2(-h,r),this._z=0);break;case"ZXY":this._x=Math.asin(yt(u,-1,1)),Math.abs(u)<.9999999?(this._y=Math.atan2(-h,d),this._z=Math.atan2(-s,l)):(this._y=0,this._z=Math.atan2(o,r));break;case"ZYX":this._y=Math.asin(-yt(h,-1,1)),Math.abs(h)<.9999999?(this._x=Math.atan2(u,d),this._z=Math.atan2(o,r)):(this._x=0,this._z=Math.atan2(-s,l));break;case"YZX":this._z=Math.asin(yt(o,-1,1)),Math.abs(o)<.9999999?(this._x=Math.atan2(-c,l),this._y=Math.atan2(-h,r)):(this._x=0,this._y=Math.atan2(a,d));break;case"XZY":this._z=Math.asin(-yt(s,-1,1)),Math.abs(s)<.9999999?(this._x=Math.atan2(u,l),this._y=Math.atan2(a,r)):(this._x=Math.atan2(-c,d),this._y=0);break;default:console.warn("THREE.Euler: .setFromRotationMatrix() encountered an unknown order: "+e)}return this._order=e,!0===i&&this._onChangeCallback(),this}setFromQuaternion(t,e,i){return ke.makeRotationFromQuaternion(t),this.setFromRotationMatrix(ke,e,i)}setFromVector3(t,e=this._order){return this.set(t.x,t.y,t.z,e)}reorder(t){return Ge.setFromEuler(this),this.setFromQuaternion(Ge,t)}equals(t){return t._x===this._x&&t._y===this._y&&t._z===this._z&&t._order===this._order}fromArray(t){return this._x=t[0],this._y=t[1],this._z=t[2],void 0!==t[3]&&(this._order=t[3]),this._onChangeCallback(),this}toArray(t=[],e=0){return t[e]=this._x,t[e+1]=this._y,t[e+2]=this._z,t[e+3]=this._order,t}_onChange(t){return this._onChangeCallback=t,this}_onChangeCallback(){}*[Symbol.iterator](){yield this._x,yield this._y,yield this._z,yield this._order}toVector3(){console.error("THREE.Euler: .toVector3() has been removed. Use Vector3.setFromEuler() instead")}}Ve.DefaultOrder="XYZ",Ve.RotationOrders=["XYZ","YZX","ZXY","XZY","YXZ","ZYX"];class He{constructor(){this.mask=1}set(t){this.mask=(1<>>0}enable(t){this.mask|=1<1){for(let t=0;t1){for(let t=0;t0){n.children=[];for(let e=0;e0){n.animations=[];for(let e=0;e0&&(i.geometries=e),n.length>0&&(i.materials=n),r.length>0&&(i.textures=r),a.length>0&&(i.images=a),o.length>0&&(i.shapes=o),l.length>0&&(i.skeletons=l),c.length>0&&(i.animations=c),h.length>0&&(i.nodes=h)}return i.object=n,i;function s(t){const e=[];for(const i in t){const n=t[i];delete n.metadata,e.push(n)}return e}}clone(t){return(new this.constructor).copy(this,t)}copy(t,e=!0){if(this.name=t.name,this.up.copy(t.up),this.position.copy(t.position),this.rotation.order=t.rotation.order,this.quaternion.copy(t.quaternion),this.scale.copy(t.scale),this.matrix.copy(t.matrix),this.matrixWorld.copy(t.matrixWorld),this.matrixAutoUpdate=t.matrixAutoUpdate,this.matrixWorldNeedsUpdate=t.matrixWorldNeedsUpdate,this.layers.mask=t.layers.mask,this.visible=t.visible,this.castShadow=t.castShadow,this.receiveShadow=t.receiveShadow,this.frustumCulled=t.frustumCulled,this.renderOrder=t.renderOrder,this.userData=JSON.parse(JSON.stringify(t.userData)),!0===e)for(let e=0;e0?n.multiplyScalar(1/Math.sqrt(r)):n.set(0,0,0)}static getBarycoord(t,e,i,n,r){ri.subVectors(n,e),si.subVectors(i,e),ai.subVectors(t,e);const s=ri.dot(ri),a=ri.dot(si),o=ri.dot(ai),l=si.dot(si),c=si.dot(ai),h=s*l-a*a;if(0===h)return r.set(-2,-1,-1);const u=1/h,d=(l*o-a*c)*u,p=(s*c-a*o)*u;return r.set(1-d-p,p,d)}static containsPoint(t,e,i,n){return this.getBarycoord(t,e,i,n,oi),oi.x>=0&&oi.y>=0&&oi.x+oi.y<=1}static getUV(t,e,i,n,r,s,a,o){return this.getBarycoord(t,e,i,n,oi),o.set(0,0),o.addScaledVector(r,oi.x),o.addScaledVector(s,oi.y),o.addScaledVector(a,oi.z),o}static isFrontFacing(t,e,i,n){return ri.subVectors(i,e),si.subVectors(t,e),ri.cross(si).dot(n)<0}set(t,e,i){return this.a.copy(t),this.b.copy(e),this.c.copy(i),this}setFromPointsAndIndices(t,e,i,n){return this.a.copy(t[e]),this.b.copy(t[i]),this.c.copy(t[n]),this}setFromAttributeAndIndices(t,e,i,n){return this.a.fromBufferAttribute(t,e),this.b.fromBufferAttribute(t,i),this.c.fromBufferAttribute(t,n),this}clone(){return(new this.constructor).copy(this)}copy(t){return this.a.copy(t.a),this.b.copy(t.b),this.c.copy(t.c),this}getArea(){return ri.subVectors(this.c,this.b),si.subVectors(this.a,this.b),.5*ri.cross(si).length()}getMidpoint(t){return t.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)}getNormal(t){return fi.getNormal(this.a,this.b,this.c,t)}getPlane(t){return t.setFromCoplanarPoints(this.a,this.b,this.c)}getBarycoord(t,e){return fi.getBarycoord(t,this.a,this.b,this.c,e)}getUV(t,e,i,n,r){return fi.getUV(t,this.a,this.b,this.c,e,i,n,r)}containsPoint(t){return fi.containsPoint(t,this.a,this.b,this.c)}isFrontFacing(t){return fi.isFrontFacing(this.a,this.b,this.c,t)}intersectsBox(t){return t.intersectsTriangle(this)}closestPointToPoint(t,e){const i=this.a,n=this.b,r=this.c;let s,a;li.subVectors(n,i),ci.subVectors(r,i),ui.subVectors(t,i);const o=li.dot(ui),l=ci.dot(ui);if(o<=0&&l<=0)return e.copy(i);di.subVectors(t,n);const c=li.dot(di),h=ci.dot(di);if(c>=0&&h<=c)return e.copy(n);const u=o*h-c*l;if(u<=0&&o>=0&&c<=0)return s=o/(o-c),e.copy(i).addScaledVector(li,s);pi.subVectors(t,r);const d=li.dot(pi),p=ci.dot(pi);if(p>=0&&d<=p)return e.copy(r);const f=d*l-o*p;if(f<=0&&l>=0&&p<=0)return a=l/(l-p),e.copy(i).addScaledVector(ci,a);const m=c*p-d*h;if(m<=0&&h-c>=0&&d-p>=0)return hi.subVectors(r,n),a=(h-c)/(h-c+(d-p)),e.copy(n).addScaledVector(hi,a);const g=1/(m+f+u);return s=f*g,a=u*g,e.copy(i).addScaledVector(li,s).addScaledVector(ci,a)}equals(t){return t.a.equals(this.a)&&t.b.equals(this.b)&&t.c.equals(this.c)}}let mi=0;class gi extends ft{constructor(){super(),this.isMaterial=!0,Object.defineProperty(this,"id",{value:mi++}),this.uuid=_t(),this.name="",this.type="Material",this.blending=1,this.side=0,this.vertexColors=!1,this.opacity=1,this.transparent=!1,this.blendSrc=204,this.blendDst=205,this.blendEquation=i,this.blendSrcAlpha=null,this.blendDstAlpha=null,this.blendEquationAlpha=null,this.depthFunc=3,this.depthTest=!0,this.depthWrite=!0,this.stencilWriteMask=255,this.stencilFunc=519,this.stencilRef=0,this.stencilFuncMask=255,this.stencilFail=ht,this.stencilZFail=ht,this.stencilZPass=ht,this.stencilWrite=!1,this.clippingPlanes=null,this.clipIntersection=!1,this.clipShadows=!1,this.shadowSide=null,this.colorWrite=!0,this.precision=null,this.polygonOffset=!1,this.polygonOffsetFactor=0,this.polygonOffsetUnits=0,this.dithering=!1,this.alphaToCoverage=!1,this.premultipliedAlpha=!1,this.visible=!0,this.toneMapped=!0,this.userData={},this.version=0,this._alphaTest=0}get alphaTest(){return this._alphaTest}set alphaTest(t){this._alphaTest>0!=t>0&&this.version++,this._alphaTest=t}onBuild(){}onBeforeRender(){}onBeforeCompile(){}customProgramCacheKey(){return this.onBeforeCompile.toString()}setValues(t){if(void 0!==t)for(const e in t){const i=t[e];if(void 0===i){console.warn("THREE.Material: '"+e+"' parameter is undefined.");continue}if("shading"===e){console.warn("THREE."+this.type+": .shading has been removed. Use the boolean .flatShading instead."),this.flatShading=1===i;continue}const n=this[e];void 0!==n?n&&n.isColor?n.set(i):n&&n.isVector3&&i&&i.isVector3?n.copy(i):this[e]=i:console.warn("THREE."+this.type+": '"+e+"' is not a property of this material.")}}toJSON(t){const e=void 0===t||"string"==typeof t;e&&(t={textures:{},images:{}});const i={metadata:{version:4.5,type:"Material",generator:"Material.toJSON"}};function n(t){const e=[];for(const i in t){const n=t[i];delete n.metadata,e.push(n)}return e}if(i.uuid=this.uuid,i.type=this.type,""!==this.name&&(i.name=this.name),this.color&&this.color.isColor&&(i.color=this.color.getHex()),void 0!==this.roughness&&(i.roughness=this.roughness),void 0!==this.metalness&&(i.metalness=this.metalness),void 0!==this.sheen&&(i.sheen=this.sheen),this.sheenColor&&this.sheenColor.isColor&&(i.sheenColor=this.sheenColor.getHex()),void 0!==this.sheenRoughness&&(i.sheenRoughness=this.sheenRoughness),this.emissive&&this.emissive.isColor&&(i.emissive=this.emissive.getHex()),this.emissiveIntensity&&1!==this.emissiveIntensity&&(i.emissiveIntensity=this.emissiveIntensity),this.specular&&this.specular.isColor&&(i.specular=this.specular.getHex()),void 0!==this.specularIntensity&&(i.specularIntensity=this.specularIntensity),this.specularColor&&this.specularColor.isColor&&(i.specularColor=this.specularColor.getHex()),void 0!==this.shininess&&(i.shininess=this.shininess),void 0!==this.clearcoat&&(i.clearcoat=this.clearcoat),void 0!==this.clearcoatRoughness&&(i.clearcoatRoughness=this.clearcoatRoughness),this.clearcoatMap&&this.clearcoatMap.isTexture&&(i.clearcoatMap=this.clearcoatMap.toJSON(t).uuid),this.clearcoatRoughnessMap&&this.clearcoatRoughnessMap.isTexture&&(i.clearcoatRoughnessMap=this.clearcoatRoughnessMap.toJSON(t).uuid),this.clearcoatNormalMap&&this.clearcoatNormalMap.isTexture&&(i.clearcoatNormalMap=this.clearcoatNormalMap.toJSON(t).uuid,i.clearcoatNormalScale=this.clearcoatNormalScale.toArray()),void 0!==this.iridescence&&(i.iridescence=this.iridescence),void 0!==this.iridescenceIOR&&(i.iridescenceIOR=this.iridescenceIOR),void 0!==this.iridescenceThicknessRange&&(i.iridescenceThicknessRange=this.iridescenceThicknessRange),this.iridescenceMap&&this.iridescenceMap.isTexture&&(i.iridescenceMap=this.iridescenceMap.toJSON(t).uuid),this.iridescenceThicknessMap&&this.iridescenceThicknessMap.isTexture&&(i.iridescenceThicknessMap=this.iridescenceThicknessMap.toJSON(t).uuid),this.map&&this.map.isTexture&&(i.map=this.map.toJSON(t).uuid),this.matcap&&this.matcap.isTexture&&(i.matcap=this.matcap.toJSON(t).uuid),this.alphaMap&&this.alphaMap.isTexture&&(i.alphaMap=this.alphaMap.toJSON(t).uuid),this.lightMap&&this.lightMap.isTexture&&(i.lightMap=this.lightMap.toJSON(t).uuid,i.lightMapIntensity=this.lightMapIntensity),this.aoMap&&this.aoMap.isTexture&&(i.aoMap=this.aoMap.toJSON(t).uuid,i.aoMapIntensity=this.aoMapIntensity),this.bumpMap&&this.bumpMap.isTexture&&(i.bumpMap=this.bumpMap.toJSON(t).uuid,i.bumpScale=this.bumpScale),this.normalMap&&this.normalMap.isTexture&&(i.normalMap=this.normalMap.toJSON(t).uuid,i.normalMapType=this.normalMapType,i.normalScale=this.normalScale.toArray()),this.displacementMap&&this.displacementMap.isTexture&&(i.displacementMap=this.displacementMap.toJSON(t).uuid,i.displacementScale=this.displacementScale,i.displacementBias=this.displacementBias),this.roughnessMap&&this.roughnessMap.isTexture&&(i.roughnessMap=this.roughnessMap.toJSON(t).uuid),this.metalnessMap&&this.metalnessMap.isTexture&&(i.metalnessMap=this.metalnessMap.toJSON(t).uuid),this.emissiveMap&&this.emissiveMap.isTexture&&(i.emissiveMap=this.emissiveMap.toJSON(t).uuid),this.specularMap&&this.specularMap.isTexture&&(i.specularMap=this.specularMap.toJSON(t).uuid),this.specularIntensityMap&&this.specularIntensityMap.isTexture&&(i.specularIntensityMap=this.specularIntensityMap.toJSON(t).uuid),this.specularColorMap&&this.specularColorMap.isTexture&&(i.specularColorMap=this.specularColorMap.toJSON(t).uuid),this.envMap&&this.envMap.isTexture&&(i.envMap=this.envMap.toJSON(t).uuid,void 0!==this.combine&&(i.combine=this.combine)),void 0!==this.envMapIntensity&&(i.envMapIntensity=this.envMapIntensity),void 0!==this.reflectivity&&(i.reflectivity=this.reflectivity),void 0!==this.refractionRatio&&(i.refractionRatio=this.refractionRatio),this.gradientMap&&this.gradientMap.isTexture&&(i.gradientMap=this.gradientMap.toJSON(t).uuid),void 0!==this.transmission&&(i.transmission=this.transmission),this.transmissionMap&&this.transmissionMap.isTexture&&(i.transmissionMap=this.transmissionMap.toJSON(t).uuid),void 0!==this.thickness&&(i.thickness=this.thickness),this.thicknessMap&&this.thicknessMap.isTexture&&(i.thicknessMap=this.thicknessMap.toJSON(t).uuid),void 0!==this.attenuationDistance&&(i.attenuationDistance=this.attenuationDistance),void 0!==this.attenuationColor&&(i.attenuationColor=this.attenuationColor.getHex()),void 0!==this.size&&(i.size=this.size),null!==this.shadowSide&&(i.shadowSide=this.shadowSide),void 0!==this.sizeAttenuation&&(i.sizeAttenuation=this.sizeAttenuation),1!==this.blending&&(i.blending=this.blending),0!==this.side&&(i.side=this.side),this.vertexColors&&(i.vertexColors=!0),this.opacity<1&&(i.opacity=this.opacity),!0===this.transparent&&(i.transparent=this.transparent),i.depthFunc=this.depthFunc,i.depthTest=this.depthTest,i.depthWrite=this.depthWrite,i.colorWrite=this.colorWrite,i.stencilWrite=this.stencilWrite,i.stencilWriteMask=this.stencilWriteMask,i.stencilFunc=this.stencilFunc,i.stencilRef=this.stencilRef,i.stencilFuncMask=this.stencilFuncMask,i.stencilFail=this.stencilFail,i.stencilZFail=this.stencilZFail,i.stencilZPass=this.stencilZPass,void 0!==this.rotation&&0!==this.rotation&&(i.rotation=this.rotation),!0===this.polygonOffset&&(i.polygonOffset=!0),0!==this.polygonOffsetFactor&&(i.polygonOffsetFactor=this.polygonOffsetFactor),0!==this.polygonOffsetUnits&&(i.polygonOffsetUnits=this.polygonOffsetUnits),void 0!==this.linewidth&&1!==this.linewidth&&(i.linewidth=this.linewidth),void 0!==this.dashSize&&(i.dashSize=this.dashSize),void 0!==this.gapSize&&(i.gapSize=this.gapSize),void 0!==this.scale&&(i.scale=this.scale),!0===this.dithering&&(i.dithering=!0),this.alphaTest>0&&(i.alphaTest=this.alphaTest),!0===this.alphaToCoverage&&(i.alphaToCoverage=this.alphaToCoverage),!0===this.premultipliedAlpha&&(i.premultipliedAlpha=this.premultipliedAlpha),!0===this.wireframe&&(i.wireframe=this.wireframe),this.wireframeLinewidth>1&&(i.wireframeLinewidth=this.wireframeLinewidth),"round"!==this.wireframeLinecap&&(i.wireframeLinecap=this.wireframeLinecap),"round"!==this.wireframeLinejoin&&(i.wireframeLinejoin=this.wireframeLinejoin),!0===this.flatShading&&(i.flatShading=this.flatShading),!1===this.visible&&(i.visible=!1),!1===this.toneMapped&&(i.toneMapped=!1),!1===this.fog&&(i.fog=!1),"{}"!==JSON.stringify(this.userData)&&(i.userData=this.userData),e){const e=n(t.textures),r=n(t.images);e.length>0&&(i.textures=e),r.length>0&&(i.images=r)}return i}clone(){return(new this.constructor).copy(this)}copy(t){this.name=t.name,this.blending=t.blending,this.side=t.side,this.vertexColors=t.vertexColors,this.opacity=t.opacity,this.transparent=t.transparent,this.blendSrc=t.blendSrc,this.blendDst=t.blendDst,this.blendEquation=t.blendEquation,this.blendSrcAlpha=t.blendSrcAlpha,this.blendDstAlpha=t.blendDstAlpha,this.blendEquationAlpha=t.blendEquationAlpha,this.depthFunc=t.depthFunc,this.depthTest=t.depthTest,this.depthWrite=t.depthWrite,this.stencilWriteMask=t.stencilWriteMask,this.stencilFunc=t.stencilFunc,this.stencilRef=t.stencilRef,this.stencilFuncMask=t.stencilFuncMask,this.stencilFail=t.stencilFail,this.stencilZFail=t.stencilZFail,this.stencilZPass=t.stencilZPass,this.stencilWrite=t.stencilWrite;const e=t.clippingPlanes;let i=null;if(null!==e){const t=e.length;i=new Array(t);for(let n=0;n!==t;++n)i[n]=e[n].clone()}return this.clippingPlanes=i,this.clipIntersection=t.clipIntersection,this.clipShadows=t.clipShadows,this.shadowSide=t.shadowSide,this.colorWrite=t.colorWrite,this.precision=t.precision,this.polygonOffset=t.polygonOffset,this.polygonOffsetFactor=t.polygonOffsetFactor,this.polygonOffsetUnits=t.polygonOffsetUnits,this.dithering=t.dithering,this.alphaTest=t.alphaTest,this.alphaToCoverage=t.alphaToCoverage,this.premultipliedAlpha=t.premultipliedAlpha,this.visible=t.visible,this.toneMapped=t.toneMapped,this.userData=JSON.parse(JSON.stringify(t.userData)),this}dispose(){this.dispatchEvent({type:"dispose"})}set needsUpdate(t){!0===t&&this.version++}}class vi extends gi{constructor(t){super(),this.isMeshBasicMaterial=!0,this.type="MeshBasicMaterial",this.color=new Ht(16777215),this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.combine=0,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.specularMap=t.specularMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.combine=t.combine,this.reflectivity=t.reflectivity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.fog=t.fog,this}}const xi=new ee,_i=new Et;class yi{constructor(t,e,i){if(Array.isArray(t))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.isBufferAttribute=!0,this.name="",this.array=t,this.itemSize=e,this.count=void 0!==t?t.length/e:0,this.normalized=!0===i,this.usage=ut,this.updateRange={offset:0,count:-1},this.version=0}onUploadCallback(){}set needsUpdate(t){!0===t&&this.version++}setUsage(t){return this.usage=t,this}copy(t){return this.name=t.name,this.array=new t.array.constructor(t.array),this.itemSize=t.itemSize,this.count=t.count,this.normalized=t.normalized,this.usage=t.usage,this}copyAt(t,e,i){t*=this.itemSize,i*=e.itemSize;for(let n=0,r=this.itemSize;n0&&(t.userData=this.userData),void 0!==this.parameters){const e=this.parameters;for(const i in e)void 0!==e[i]&&(t[i]=e[i]);return t}t.data={attributes:{}};const e=this.index;null!==e&&(t.data.index={type:e.array.constructor.name,array:Array.prototype.slice.call(e.array)});const i=this.attributes;for(const e in i){const n=i[e];t.data.attributes[e]=n.toJSON(t.data)}const n={};let r=!1;for(const e in this.morphAttributes){const i=this.morphAttributes[e],s=[];for(let e=0,n=i.length;e0&&(n[e]=s,r=!0)}r&&(t.data.morphAttributes=n,t.data.morphTargetsRelative=this.morphTargetsRelative);const s=this.groups;s.length>0&&(t.data.groups=JSON.parse(JSON.stringify(s)));const a=this.boundingSphere;return null!==a&&(t.data.boundingSphere={center:a.center.toArray(),radius:a.radius}),t}clone(){return(new this.constructor).copy(this)}copy(t){this.index=null,this.attributes={},this.morphAttributes={},this.groups=[],this.boundingBox=null,this.boundingSphere=null;const e={};this.name=t.name;const i=t.index;null!==i&&this.setIndex(i.clone(e));const n=t.attributes;for(const t in n){const i=n[t];this.setAttribute(t,i.clone(e))}const r=t.morphAttributes;for(const t in r){const i=[],n=r[t];for(let t=0,r=n.length;t0){const i=t[e[0]];if(void 0!==i){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let t=0,e=i.length;ti.far?null:{distance:c,point:Yi.clone(),object:t}}(t,e,i,n,Oi,zi,Fi,Xi);if(p){o&&(Wi.fromBufferAttribute(o,c),ji.fromBufferAttribute(o,h),qi.fromBufferAttribute(o,u),p.uv=fi.getUV(Xi,Oi,zi,Fi,Wi,ji,qi,new Et)),l&&(Wi.fromBufferAttribute(l,c),ji.fromBufferAttribute(l,h),qi.fromBufferAttribute(l,u),p.uv2=fi.getUV(Xi,Oi,zi,Fi,Wi,ji,qi,new Et));const t={a:c,b:h,c:u,normal:new ee,materialIndex:0};fi.getNormal(Oi,zi,Fi,t.normal),p.face=t}return p}class Ki extends Pi{constructor(t=1,e=1,i=1,n=1,r=1,s=1){super(),this.type="BoxGeometry",this.parameters={width:t,height:e,depth:i,widthSegments:n,heightSegments:r,depthSegments:s};const a=this;n=Math.floor(n),r=Math.floor(r),s=Math.floor(s);const o=[],l=[],c=[],h=[];let u=0,d=0;function p(t,e,i,n,r,s,p,f,m,g,v){const x=s/m,_=p/g,y=s/2,M=p/2,b=f/2,w=m+1,S=g+1;let T=0,A=0;const E=new ee;for(let s=0;s0?1:-1,c.push(E.x,E.y,E.z),h.push(o/m),h.push(1-s/g),T+=1}}for(let t=0;t0&&(e.defines=this.defines),e.vertexShader=this.vertexShader,e.fragmentShader=this.fragmentShader;const i={};for(const t in this.extensions)!0===this.extensions[t]&&(i[t]=!0);return Object.keys(i).length>0&&(e.extensions=i),e}}class nn extends ni{constructor(){super(),this.isCamera=!0,this.type="Camera",this.matrixWorldInverse=new Ie,this.projectionMatrix=new Ie,this.projectionMatrixInverse=new Ie}copy(t,e){return super.copy(t,e),this.matrixWorldInverse.copy(t.matrixWorldInverse),this.projectionMatrix.copy(t.projectionMatrix),this.projectionMatrixInverse.copy(t.projectionMatrixInverse),this}getWorldDirection(t){this.updateWorldMatrix(!0,!1);const e=this.matrixWorld.elements;return t.set(-e[8],-e[9],-e[10]).normalize()}updateMatrixWorld(t){super.updateMatrixWorld(t),this.matrixWorldInverse.copy(this.matrixWorld).invert()}updateWorldMatrix(t,e){super.updateWorldMatrix(t,e),this.matrixWorldInverse.copy(this.matrixWorld).invert()}clone(){return(new this.constructor).copy(this)}}class rn extends nn{constructor(t=50,e=1,i=.1,n=2e3){super(),this.isPerspectiveCamera=!0,this.type="PerspectiveCamera",this.fov=t,this.zoom=1,this.near=i,this.far=n,this.focus=10,this.aspect=e,this.view=null,this.filmGauge=35,this.filmOffset=0,this.updateProjectionMatrix()}copy(t,e){return super.copy(t,e),this.fov=t.fov,this.zoom=t.zoom,this.near=t.near,this.far=t.far,this.focus=t.focus,this.aspect=t.aspect,this.view=null===t.view?null:Object.assign({},t.view),this.filmGauge=t.filmGauge,this.filmOffset=t.filmOffset,this}setFocalLength(t){const e=.5*this.getFilmHeight()/t;this.fov=2*xt*Math.atan(e),this.updateProjectionMatrix()}getFocalLength(){const t=Math.tan(.5*vt*this.fov);return.5*this.getFilmHeight()/t}getEffectiveFOV(){return 2*xt*Math.atan(Math.tan(.5*vt*this.fov)/this.zoom)}getFilmWidth(){return this.filmGauge*Math.min(this.aspect,1)}getFilmHeight(){return this.filmGauge/Math.max(this.aspect,1)}setViewOffset(t,e,i,n,r,s){this.aspect=t/e,null===this.view&&(this.view={enabled:!0,fullWidth:1,fullHeight:1,offsetX:0,offsetY:0,width:1,height:1}),this.view.enabled=!0,this.view.fullWidth=t,this.view.fullHeight=e,this.view.offsetX=i,this.view.offsetY=n,this.view.width=r,this.view.height=s,this.updateProjectionMatrix()}clearViewOffset(){null!==this.view&&(this.view.enabled=!1),this.updateProjectionMatrix()}updateProjectionMatrix(){const t=this.near;let e=t*Math.tan(.5*vt*this.fov)/this.zoom,i=2*e,n=this.aspect*i,r=-.5*n;const s=this.view;if(null!==this.view&&this.view.enabled){const t=s.fullWidth,a=s.fullHeight;r+=s.offsetX*n/t,e-=s.offsetY*i/a,n*=s.width/t,i*=s.height/a}const a=this.filmOffset;0!==a&&(r+=t*a/this.getFilmWidth()),this.projectionMatrix.makePerspective(r,r+n,e,e-i,t,this.far),this.projectionMatrixInverse.copy(this.projectionMatrix).invert()}toJSON(t){const e=super.toJSON(t);return e.object.fov=this.fov,e.object.zoom=this.zoom,e.object.near=this.near,e.object.far=this.far,e.object.focus=this.focus,e.object.aspect=this.aspect,null!==this.view&&(e.object.view=Object.assign({},this.view)),e.object.filmGauge=this.filmGauge,e.object.filmOffset=this.filmOffset,e}}const sn=90;class an extends ni{constructor(t,e,i){if(super(),this.type="CubeCamera",!0!==i.isWebGLCubeRenderTarget)return void console.error("THREE.CubeCamera: The constructor now expects an instance of WebGLCubeRenderTarget as third parameter.");this.renderTarget=i;const n=new rn(sn,1,t,e);n.layers=this.layers,n.up.set(0,-1,0),n.lookAt(new ee(1,0,0)),this.add(n);const r=new rn(sn,1,t,e);r.layers=this.layers,r.up.set(0,-1,0),r.lookAt(new ee(-1,0,0)),this.add(r);const s=new rn(sn,1,t,e);s.layers=this.layers,s.up.set(0,0,1),s.lookAt(new ee(0,1,0)),this.add(s);const a=new rn(sn,1,t,e);a.layers=this.layers,a.up.set(0,0,-1),a.lookAt(new ee(0,-1,0)),this.add(a);const o=new rn(sn,1,t,e);o.layers=this.layers,o.up.set(0,-1,0),o.lookAt(new ee(0,0,1)),this.add(o);const l=new rn(sn,1,t,e);l.layers=this.layers,l.up.set(0,-1,0),l.lookAt(new ee(0,0,-1)),this.add(l)}update(t,e){null===this.parent&&this.updateMatrixWorld();const i=this.renderTarget,[n,r,s,a,o,l]=this.children,c=t.getRenderTarget(),h=t.toneMapping,u=t.xr.enabled;t.toneMapping=0,t.xr.enabled=!1;const d=i.texture.generateMipmaps;i.texture.generateMipmaps=!1,t.setRenderTarget(i,0),t.render(e,n),t.setRenderTarget(i,1),t.render(e,r),t.setRenderTarget(i,2),t.render(e,s),t.setRenderTarget(i,3),t.render(e,a),t.setRenderTarget(i,4),t.render(e,o),i.texture.generateMipmaps=d,t.setRenderTarget(i,5),t.render(e,l),t.setRenderTarget(c),t.toneMapping=h,t.xr.enabled=u,i.texture.needsPMREMUpdate=!0}}class on extends Zt{constructor(t,e,i,n,s,a,o,l,c,h){super(t=void 0!==t?t:[],e=void 0!==e?e:r,i,n,s,a,o,l,c,h),this.isCubeTexture=!0,this.flipY=!1}get images(){return this.image}set images(t){this.image=t}}class ln extends Kt{constructor(t,e={}){super(t,t,e),this.isWebGLCubeRenderTarget=!0;const i={width:t,height:t,depth:1},n=[i,i,i,i,i,i];this.texture=new on(n,e.mapping,e.wrapS,e.wrapT,e.magFilter,e.minFilter,e.format,e.type,e.anisotropy,e.encoding),this.texture.isRenderTargetTexture=!0,this.texture.generateMipmaps=void 0!==e.generateMipmaps&&e.generateMipmaps,this.texture.minFilter=void 0!==e.minFilter?e.minFilter:m}fromEquirectangularTexture(t,e){this.texture.type=e.type,this.texture.encoding=e.encoding,this.texture.generateMipmaps=e.generateMipmaps,this.texture.minFilter=e.minFilter,this.texture.magFilter=e.magFilter;const i={uniforms:{tEquirect:{value:null}},vertexShader:"\n\n\t\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t\tvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\n\t\t\t\t\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvWorldDirection = transformDirection( position, modelMatrix );\n\n\t\t\t\t\t#include \n\t\t\t\t\t#include \n\n\t\t\t\t}\n\t\t\t",fragmentShader:"\n\n\t\t\t\tuniform sampler2D tEquirect;\n\n\t\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t\t#include \n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvec3 direction = normalize( vWorldDirection );\n\n\t\t\t\t\tvec2 sampleUV = equirectUv( direction );\n\n\t\t\t\t\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\n\t\t\t\t}\n\t\t\t"},n=new Ki(5,5,5),r=new en({name:"CubemapFromEquirect",uniforms:$i(i.uniforms),vertexShader:i.vertexShader,fragmentShader:i.fragmentShader,side:1,blending:0});r.uniforms.tEquirect.value=e;const s=new Zi(n,r),a=e.minFilter;e.minFilter===v&&(e.minFilter=m);return new an(1,10,this).update(t,s),e.minFilter=a,s.geometry.dispose(),s.material.dispose(),this}clear(t,e,i,n){const r=t.getRenderTarget();for(let r=0;r<6;r++)t.setRenderTarget(this,r),t.clear(e,i,n);t.setRenderTarget(r)}}const cn=new ee,hn=new ee,un=new Ct;class dn{constructor(t=new ee(1,0,0),e=0){this.isPlane=!0,this.normal=t,this.constant=e}set(t,e){return this.normal.copy(t),this.constant=e,this}setComponents(t,e,i,n){return this.normal.set(t,e,i),this.constant=n,this}setFromNormalAndCoplanarPoint(t,e){return this.normal.copy(t),this.constant=-e.dot(this.normal),this}setFromCoplanarPoints(t,e,i){const n=cn.subVectors(i,e).cross(hn.subVectors(t,e)).normalize();return this.setFromNormalAndCoplanarPoint(n,t),this}copy(t){return this.normal.copy(t.normal),this.constant=t.constant,this}normalize(){const t=1/this.normal.length();return this.normal.multiplyScalar(t),this.constant*=t,this}negate(){return this.constant*=-1,this.normal.negate(),this}distanceToPoint(t){return this.normal.dot(t)+this.constant}distanceToSphere(t){return this.distanceToPoint(t.center)-t.radius}projectPoint(t,e){return e.copy(this.normal).multiplyScalar(-this.distanceToPoint(t)).add(t)}intersectLine(t,e){const i=t.delta(cn),n=this.normal.dot(i);if(0===n)return 0===this.distanceToPoint(t.start)?e.copy(t.start):null;const r=-(t.start.dot(this.normal)+this.constant)/n;return r<0||r>1?null:e.copy(i).multiplyScalar(r).add(t.start)}intersectsLine(t){const e=this.distanceToPoint(t.start),i=this.distanceToPoint(t.end);return e<0&&i>0||i<0&&e>0}intersectsBox(t){return t.intersectsPlane(this)}intersectsSphere(t){return t.intersectsPlane(this)}coplanarPoint(t){return t.copy(this.normal).multiplyScalar(-this.constant)}applyMatrix4(t,e){const i=e||un.getNormalMatrix(t),n=this.coplanarPoint(cn).applyMatrix4(t),r=this.normal.applyMatrix3(i).normalize();return this.constant=-n.dot(r),this}translate(t){return this.constant-=t.dot(this.normal),this}equals(t){return t.normal.equals(this.normal)&&t.constant===this.constant}clone(){return(new this.constructor).copy(this)}}const pn=new we,fn=new ee;class mn{constructor(t=new dn,e=new dn,i=new dn,n=new dn,r=new dn,s=new dn){this.planes=[t,e,i,n,r,s]}set(t,e,i,n,r,s){const a=this.planes;return a[0].copy(t),a[1].copy(e),a[2].copy(i),a[3].copy(n),a[4].copy(r),a[5].copy(s),this}copy(t){const e=this.planes;for(let i=0;i<6;i++)e[i].copy(t.planes[i]);return this}setFromProjectionMatrix(t){const e=this.planes,i=t.elements,n=i[0],r=i[1],s=i[2],a=i[3],o=i[4],l=i[5],c=i[6],h=i[7],u=i[8],d=i[9],p=i[10],f=i[11],m=i[12],g=i[13],v=i[14],x=i[15];return e[0].setComponents(a-n,h-o,f-u,x-m).normalize(),e[1].setComponents(a+n,h+o,f+u,x+m).normalize(),e[2].setComponents(a+r,h+l,f+d,x+g).normalize(),e[3].setComponents(a-r,h-l,f-d,x-g).normalize(),e[4].setComponents(a-s,h-c,f-p,x-v).normalize(),e[5].setComponents(a+s,h+c,f+p,x+v).normalize(),this}intersectsObject(t){const e=t.geometry;return null===e.boundingSphere&&e.computeBoundingSphere(),pn.copy(e.boundingSphere).applyMatrix4(t.matrixWorld),this.intersectsSphere(pn)}intersectsSprite(t){return pn.center.set(0,0,0),pn.radius=.7071067811865476,pn.applyMatrix4(t.matrixWorld),this.intersectsSphere(pn)}intersectsSphere(t){const e=this.planes,i=t.center,n=-t.radius;for(let t=0;t<6;t++){if(e[t].distanceToPoint(i)0?t.max.x:t.min.x,fn.y=n.normal.y>0?t.max.y:t.min.y,fn.z=n.normal.z>0?t.max.z:t.min.z,n.distanceToPoint(fn)<0)return!1}return!0}containsPoint(t){const e=this.planes;for(let i=0;i<6;i++)if(e[i].distanceToPoint(t)<0)return!1;return!0}clone(){return(new this.constructor).copy(this)}}function gn(){let t=null,e=!1,i=null,n=null;function r(e,s){i(e,s),n=t.requestAnimationFrame(r)}return{start:function(){!0!==e&&null!==i&&(n=t.requestAnimationFrame(r),e=!0)},stop:function(){t.cancelAnimationFrame(n),e=!1},setAnimationLoop:function(t){i=t},setContext:function(e){t=e}}}function vn(t,e){const i=e.isWebGL2,n=new WeakMap;return{get:function(t){return t.isInterleavedBufferAttribute&&(t=t.data),n.get(t)},remove:function(e){e.isInterleavedBufferAttribute&&(e=e.data);const i=n.get(e);i&&(t.deleteBuffer(i.buffer),n.delete(e))},update:function(e,r){if(e.isGLBufferAttribute){const t=n.get(e);return void((!t||t.version 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}\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_BlinnPhong( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, 1.0, dotVH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie( float roughness, float dotNH ) {\n\tfloat alpha = pow2( roughness );\n\tfloat invAlpha = 1.0 / alpha;\n\tfloat cos2h = dotNH * dotNH;\n\tfloat sin2h = max( 1.0 - cos2h, 0.0078125 );\n\treturn ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\n}\nfloat V_Neubelt( float dotNV, float dotNL ) {\n\treturn saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );\n}\nvec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat D = D_Charlie( sheenRoughness, dotNH );\n\tfloat V = V_Neubelt( dotNV, dotNL );\n\treturn sheenColor * ( D * V );\n}\n#endif",iridescence_fragment:"#ifdef USE_IRIDESCENCE\n\tconst mat3 XYZ_TO_REC709 = mat3(\n\t\t 3.2404542, -0.9692660,\t0.0556434,\n\t\t-1.5371385,\t1.8760108, -0.2040259,\n\t\t-0.4985314,\t0.0415560,\t1.0572252\n\t);\n\tvec3 Fresnel0ToIor( vec3 fresnel0 ) {\n\t\tvec3 sqrtF0 = sqrt( fresnel0 );\n\t\treturn ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 );\n\t}\n\tvec3 IorToFresnel0( vec3 transmittedIor, float incidentIor ) {\n\t\treturn pow2( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) );\n\t}\n\tfloat IorToFresnel0( float transmittedIor, float incidentIor ) {\n\t\treturn pow2( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ));\n\t}\n\tvec3 evalSensitivity( float OPD, vec3 shift ) {\n\t\tfloat phase = 2.0 * PI * OPD * 1.0e-9;\n\t\tvec3 val = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 );\n\t\tvec3 pos = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 );\n\t\tvec3 var = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 );\n\t\tvec3 xyz = val * sqrt( 2.0 * PI * var ) * cos( pos * phase + shift ) * exp( - pow2( phase ) * var );\n\t\txyz.x += 9.7470e-14 * sqrt( 2.0 * PI * 4.5282e+09 ) * cos( 2.2399e+06 * phase + shift[ 0 ] ) * exp( - 4.5282e+09 * pow2( phase ) );\n\t\txyz /= 1.0685e-7;\n\t\tvec3 rgb = XYZ_TO_REC709 * xyz;\n\t\treturn rgb;\n\t}\n\tvec3 evalIridescence( float outsideIOR, float eta2, float cosTheta1, float thinFilmThickness, vec3 baseF0 ) {\n\t\tvec3 I;\n\t\tfloat iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );\n\t\tfloat sinTheta2Sq = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) );\n\t\tfloat cosTheta2Sq = 1.0 - sinTheta2Sq;\n\t\tif ( cosTheta2Sq < 0.0 ) {\n\t\t\t return vec3( 1.0 );\n\t\t}\n\t\tfloat cosTheta2 = sqrt( cosTheta2Sq );\n\t\tfloat R0 = IorToFresnel0( iridescenceIOR, outsideIOR );\n\t\tfloat R12 = F_Schlick( R0, 1.0, cosTheta1 );\n\t\tfloat R21 = R12;\n\t\tfloat T121 = 1.0 - R12;\n\t\tfloat phi12 = 0.0;\n\t\tif ( iridescenceIOR < outsideIOR ) phi12 = PI;\n\t\tfloat phi21 = PI - phi12;\n\t\tvec3 baseIOR = Fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) );\t\tvec3 R1 = IorToFresnel0( baseIOR, iridescenceIOR );\n\t\tvec3 R23 = F_Schlick( R1, 1.0, cosTheta2 );\n\t\tvec3 phi23 = vec3( 0.0 );\n\t\tif ( baseIOR[ 0 ] < iridescenceIOR ) phi23[ 0 ] = PI;\n\t\tif ( baseIOR[ 1 ] < iridescenceIOR ) phi23[ 1 ] = PI;\n\t\tif ( baseIOR[ 2 ] < iridescenceIOR ) phi23[ 2 ] = PI;\n\t\tfloat OPD = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2;\n\t\tvec3 phi = vec3( phi21 ) + phi23;\n\t\tvec3 R123 = clamp( R12 * R23, 1e-5, 0.9999 );\n\t\tvec3 r123 = sqrt( R123 );\n\t\tvec3 Rs = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 );\n\t\tvec3 C0 = R12 + Rs;\n\t\tI = C0;\n\t\tvec3 Cm = Rs - T121;\n\t\tfor ( int m = 1; m <= 2; ++ m ) {\n\t\t\tCm *= r123;\n\t\t\tvec3 Sm = 2.0 * evalSensitivity( float( m ) * OPD, float( m ) * phi );\n\t\t\tI += Cm * Sm;\n\t\t}\n\t\treturn max( I, vec3( 0.0 ) );\n\t}\n#endif",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, float faceDirection ) {\n\t\tvec3 vSigmaX = dFdx( surf_pos.xyz );\n\t\tvec3 vSigmaY = dFdy( surf_pos.xyz );\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 ) * faceDirection;\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",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",clipping_planes_pars_fragment:"#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif",clipping_planes_pars_vertex:"#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif",clipping_planes_vertex:"#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif",color_fragment:"#if defined( USE_COLOR_ALPHA )\n\tdiffuseColor *= vColor;\n#elif defined( USE_COLOR )\n\tdiffuseColor.rgb *= vColor;\n#endif",color_pars_fragment:"#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR )\n\tvarying vec3 vColor;\n#endif",color_pars_vertex:"#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\n\tvarying vec3 vColor;\n#endif",color_vertex:"#if defined( USE_COLOR_ALPHA )\n\tvColor = vec4( 1.0 );\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\n\tvColor = vec3( 1.0 );\n#endif\n#ifdef USE_COLOR\n\tvColor *= color;\n#endif\n#ifdef USE_INSTANCING_COLOR\n\tvColor.xyz *= instanceColor.xyz;\n#endif",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; }\nvec3 pow2( const in vec3 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 max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\nfloat average( const in vec3 v ) { return dot( v, vec3( 0.3333333 ) ); }\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 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 USE_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}\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 luminance( const in vec3 rgb ) {\n\tconst vec3 weights = vec3( 0.2126729, 0.7151522, 0.0721750 );\n\treturn dot( weights, 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}",cube_uv_reflection_fragment:"#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_minMipLevel 4.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\tvec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\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\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\n\t\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n\t\tuv.x *= CUBEUV_TEXEL_WIDTH;\n\t\tuv.y *= CUBEUV_TEXEL_HEIGHT;\n\t\t#ifdef texture2DGradEXT\n\t\t\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n\t\t#else\n\t\t\treturn texture2D( envMap, uv ).rgb;\n\t\t#endif\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_MAX_MIP );\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",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",displacementmap_pars_vertex:"#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif",displacementmap_vertex:"#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif",emissivemap_fragment:"#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif",emissivemap_pars_fragment:"#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif",encodings_fragment:"gl_FragColor = linearToOutputTexel( gl_FragColor );",encodings_pars_fragment:"vec4 LinearToLinear( in vec4 value ) {\n\treturn value;\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}",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#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",envmap_common_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\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",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",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",envmap_physical_pars_fragment:"#if defined( USE_ENVMAP )\n\tvec3 getIBLIrradiance( const in vec3 normal ) {\n\t\t#if defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 );\n\t\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\tvec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\n\t\t#if defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 reflectVec = reflect( - viewDir, normal );\n\t\t\treflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );\n\t\t\treturn envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n#endif",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",fog_vertex:"#ifdef USE_FOG\n\tvFogDepth = - mvPosition.z;\n#endif",fog_pars_vertex:"#ifdef USE_FOG\n\tvarying float vFogDepth;\n#endif",fog_fragment:"#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif",fog_pars_fragment:"#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float vFogDepth;\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",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 vec3( texture2D( gradientMap, coord ).r );\n\t#else\n\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t#endif\n}",lightmap_fragment:"#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\treflectedLight.indirectDiffuse += lightMapIrradiance;\n#endif",lightmap_pars_fragment:"#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif",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.normal );\n#ifdef DOUBLE_SIDED\n\tvIndirectBack += getAmbientLightIrradiance( ambientLightColor );\n\tvIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry.normal );\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\tgetPointLightInfo( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = 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\tgetSpotLightInfo( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = 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\tgetDirectionalLightInfo( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = 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.normal );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry.normal );\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif",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 vec3 normal ) {\n\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\treturn irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\t#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\tif ( cutoffDistance > 0.0 ) {\n\t\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\t}\n\t\treturn distanceFalloff;\n\t#else\n\t\tif ( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\t\treturn pow( saturate( - lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t\t}\n\t\treturn 1.0;\n\t#endif\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n\treturn smoothstep( coneCosine, penumbraCosine, angleCosine );\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 getDirectionalLightInfo( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tlight.color = directionalLight.color;\n\t\tlight.direction = directionalLight.direction;\n\t\tlight.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 getPointLightInfo( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tlight.color = pointLight.color;\n\t\tlight.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n\t\tlight.visible = ( light.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 getSpotLightInfo( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat angleCos = dot( light.direction, spotLight.direction );\n\t\tfloat spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\tif ( spotAttenuation > 0.0 ) {\n\t\t\tfloat lightDistance = length( lVector );\n\t\t\tlight.color = spotLight.color * spotAttenuation;\n\t\t\tlight.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t\t} else {\n\t\t\tlight.color = vec3( 0.0 );\n\t\t\tlight.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 vec3 normal ) {\n\t\tfloat dotNL = dot( normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\treturn irradiance;\n\t}\n#endif",lights_toon_fragment:"ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;",lights_toon_pars_fragment:"varying vec3 vViewPosition;\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\treflectedLight.directDiffuse += irradiance * BRDF_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_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)",lights_phong_fragment:"BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;",lights_phong_pars_fragment:"varying vec3 vViewPosition;\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\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, 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_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)",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.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\t#ifdef SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULARINTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vUv ).a;\n\t\t#endif\n\t\t#ifdef USE_SPECULARCOLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vUv ).rgb;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( ior - 1.0 ) / ( ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\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_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vUv ).a;\n\t#endif\n#endif",lights_physical_pars_fragment:"struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat roughness;\n\tvec3 specularColor;\n\tfloat specularF90;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\tfloat iridescence;\n\t\tfloat iridescenceIOR;\n\t\tfloat iridescenceThickness;\n\t\tvec3 iridescenceFresnel;\n\t\tvec3 iridescenceF0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n};\nvec3 clearcoatSpecular = vec3( 0.0 );\nvec3 sheenSpecular = vec3( 0.0 );\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\n\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\n\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\n\treturn saturate( DG * RECIPROCAL_PI );\n}\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\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\tvec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\n\treturn fab;\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\treturn specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#endif\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\t#ifdef USE_IRIDESCENCE\n\t\tvec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n\t#else\n\t\tvec3 Fr = specularColor;\n\t#endif\n\tvec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\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.roughness;\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(\t\t0, 1,\t\t0 ),\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#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecular += ccIrradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.clearcoatNormal, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness );\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\treflectedLight.directSpecular += irradiance * BRDF_GGX_Iridescence( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness );\n\t#else\n\t\treflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.roughness );\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_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_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 USE_CLEARCOAT\n\t\tclearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometry.clearcoatNormal, geometry.viewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometry.normal, geometry.viewDir, material.sheenRoughness );\n\t#endif\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t#ifdef USE_IRIDESCENCE\n\t\tcomputeMultiscatteringIridescence( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );\n\t#else\n\t\tcomputeMultiscattering( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n\t#endif\n\tvec3 totalScattering = singleScattering + multiScattering;\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) );\n\treflectedLight.indirectSpecular += 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}",lights_fragment_begin:"\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef USE_CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n\tfloat dotNVi = saturate( dot( normal, geometry.viewDir ) );\n\tif ( material.iridescenceThickness == 0.0 ) {\n\t\tmaterial.iridescence = 0.0;\n\t} else {\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\t}\n\tif ( material.iridescence > 0.0 ) {\n\t\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\t}\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\tgetPointLightInfo( 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\tgetSpotLightInfo( 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\tgetDirectionalLightInfo( 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.normal );\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.normal );\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",lights_fragment_maps:"#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\t\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getIBLIrradiance( geometry.normal );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getIBLRadiance( geometry.viewDir, geometry.normal, material.roughness );\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatRadiance += getIBLRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness );\n\t#endif\n#endif",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",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",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",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",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",map_fragment:"#ifdef USE_MAP\n\tvec4 sampledDiffuseColor = texture2D( map, vUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\tsampledDiffuseColor = vec4( mix( pow( sampledDiffuseColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), sampledDiffuseColor.rgb * 0.0773993808, vec3( lessThanEqual( sampledDiffuseColor.rgb, vec3( 0.04045 ) ) ) ), sampledDiffuseColor.w );\n\t#endif\n\tdiffuseColor *= sampledDiffuseColor;\n#endif",map_pars_fragment:"#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif",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\tdiffuseColor *= texture2D( map, uv );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif",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",metalnessmap_fragment:"float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif",metalnessmap_pars_fragment:"#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif",morphcolor_vertex:"#if defined( USE_MORPHCOLORS ) && defined( MORPHTARGETS_TEXTURE )\n\tvColor *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t#if defined( USE_COLOR_ALPHA )\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ) * morphTargetInfluences[ i ];\n\t\t#elif defined( USE_COLOR )\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ).rgb * morphTargetInfluences[ i ];\n\t\t#endif\n\t}\n#endif",morphnormal_vertex:"#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\t#ifdef MORPHTARGETS_TEXTURE\n\t\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1 ).xyz * morphTargetInfluences[ i ];\n\t\t}\n\t#else\n\t\tobjectNormal += morphNormal0 * morphTargetInfluences[ 0 ];\n\t\tobjectNormal += morphNormal1 * morphTargetInfluences[ 1 ];\n\t\tobjectNormal += morphNormal2 * morphTargetInfluences[ 2 ];\n\t\tobjectNormal += morphNormal3 * morphTargetInfluences[ 3 ];\n\t#endif\n#endif",morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n\tuniform float morphTargetBaseInfluence;\n\t#ifdef MORPHTARGETS_TEXTURE\n\t\tuniform float morphTargetInfluences[ MORPHTARGETS_COUNT ];\n\t\tuniform sampler2DArray morphTargetsTexture;\n\t\tuniform ivec2 morphTargetsTextureSize;\n\t\tvec4 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset ) {\n\t\t\tint texelIndex = vertexIndex * MORPHTARGETS_TEXTURE_STRIDE + offset;\n\t\t\tint y = texelIndex / morphTargetsTextureSize.x;\n\t\t\tint x = texelIndex - y * morphTargetsTextureSize.x;\n\t\t\tivec3 morphUV = ivec3( x, y, morphTargetIndex );\n\t\t\treturn texelFetch( morphTargetsTexture, morphUV, 0 );\n\t\t}\n\t#else\n\t\t#ifndef USE_MORPHNORMALS\n\t\t\tuniform float morphTargetInfluences[ 8 ];\n\t\t#else\n\t\t\tuniform float morphTargetInfluences[ 4 ];\n\t\t#endif\n\t#endif\n#endif",morphtarget_vertex:"#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\t#ifdef MORPHTARGETS_TEXTURE\n\t\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ];\n\t\t}\n\t#else\n\t\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\n\t\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\n\t\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\n\t\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\n\t\t#ifndef USE_MORPHNORMALS\n\t\t\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\n\t\t\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\n\t\t\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\n\t\t\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\n\t\t#endif\n\t#endif\n#endif",normal_fragment_begin:"float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#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 * faceDirection;\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 * faceDirection;\n\t\t\tbitangent = bitangent * faceDirection;\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;",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 * faceDirection;\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, faceDirection );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\n#endif",normal_pars_fragment:"#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",normal_pars_vertex:"#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",normal_vertex:"#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",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, float faceDirection ) {\n\t\tvec3 q0 = dFdx( eye_pos.xyz );\n\t\tvec3 q1 = dFdy( eye_pos.xyz );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tvec3 N = surf_norm;\n\t\tvec3 q1perp = cross( q1, N );\n\t\tvec3 q0perp = cross( N, q0 );\n\t\tvec3 T = q1perp * st0.x + q0perp * st1.x;\n\t\tvec3 B = q1perp * st0.y + q0perp * st1.y;\n\t\tfloat det = max( dot( T, T ), dot( B, B ) );\n\t\tfloat scale = ( det == 0.0 ) ? 0.0 : faceDirection * inversesqrt( det );\n\t\treturn normalize( T * ( mapN.x * scale ) + B * ( mapN.y * scale ) + N * mapN.z );\n\t}\n#endif",clearcoat_normal_fragment_begin:"#ifdef USE_CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif",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, faceDirection );\n\t#endif\n#endif",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",iridescence_pars_fragment:"#ifdef USE_IRIDESCENCEMAP\n\tuniform sampler2D iridescenceMap;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform sampler2D iridescenceThicknessMap;\n#endif",output_fragment:"#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= transmissionAlpha + 0.1;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );",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}",premultiplied_alpha_fragment:"#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif",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;",dithering_fragment:"#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif",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",roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif",roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",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\ttexture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t\tf.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\ttexture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t\tf.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",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",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",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}",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",skinning_pars_vertex:"#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\tuniform highp sampler2D boneTexture;\n\tuniform int boneTextureSize;\n\tmat4 getBoneMatrix( const in float i ) {\n\t\tfloat j = i * 4.0;\n\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\ty = dy * ( y + 0.5 );\n\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\treturn bone;\n\t}\n#endif",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",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",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",specularmap_pars_fragment:"#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif",tonemapping_fragment:"#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif",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(\t1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108,\t1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605,\t1.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; }",transmission_fragment:"#ifdef USE_TRANSMISSION\n\tfloat transmissionAlpha = 1.0;\n\tfloat transmissionFactor = transmission;\n\tfloat thicknessFactor = thickness;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\ttransmissionFactor *= texture2D( transmissionMap, vUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tthicknessFactor *= texture2D( thicknessMap, vUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmission = getIBLVolumeRefraction(\n\t\tn, v, roughnessFactor, material.diffuseColor, material.specularColor, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, ior, thicknessFactor,\n\t\tattenuationColor, attenuationDistance );\n\ttotalDiffuse = mix( totalDiffuse, transmission.rgb, transmissionFactor );\n\ttransmissionAlpha = mix( transmissionAlpha, transmission.a, transmissionFactor );\n#endif",transmission_pars_fragment:"#ifdef USE_TRANSMISSION\n\tuniform float transmission;\n\tuniform float thickness;\n\tuniform float attenuationDistance;\n\tuniform vec3 attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tuniform sampler2D transmissionMap;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tuniform sampler2D thicknessMap;\n\t#endif\n\tuniform vec2 transmissionSamplerSize;\n\tuniform sampler2D transmissionSamplerMap;\n\tuniform mat4 modelMatrix;\n\tuniform mat4 projectionMatrix;\n\tvarying vec3 vWorldPosition;\n\tvec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\n\t\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n\t\tvec3 modelScale;\n\t\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\treturn normalize( refractionVector ) * thickness * modelScale;\n\t}\n\tfloat applyIorToRoughness( const in float roughness, const in float ior ) {\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t}\n\tvec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\n\t\tfloat framebufferLod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n\t\t#ifdef texture2DLodEXT\n\t\t\treturn texture2DLodEXT( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#else\n\t\t\treturn texture2D( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#endif\n\t}\n\tvec3 applyVolumeAttenuation( const in vec3 radiance, const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tif ( attenuationDistance == 0.0 ) {\n\t\t\treturn radiance;\n\t\t} else {\n\t\t\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n\t\t\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\t\t\treturn transmittance * radiance;\n\t\t}\n\t}\n\tvec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\n\t\tconst in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\n\t\tconst in mat4 viewMatrix, const in mat4 projMatrix, const in float ior, const in float thickness,\n\t\tconst in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\trefractionCoords += 1.0;\n\t\trefractionCoords /= 2.0;\n\t\tvec4 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n\t\tvec3 attenuatedColor = applyVolumeAttenuation( transmittedLight.rgb, length( transmissionRay ), attenuationColor, attenuationDistance );\n\t\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n\t\treturn vec4( ( 1.0 - F ) * attenuatedColor * diffuseColor, transmittedLight.a );\n\t}\n#endif",uv_pars_fragment:"#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif",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",uv_vertex:"#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif",uv2_pars_fragment:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif",uv2_pars_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n\tuniform mat3 uv2Transform;\n#endif",uv2_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif",worldpos_vertex:"#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION )\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",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}",background_frag:"uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tgl_FragColor = texture2D( t2D, vUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\tgl_FragColor = vec4( mix( pow( gl_FragColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), gl_FragColor.rgb * 0.0773993808, vec3( lessThanEqual( gl_FragColor.rgb, vec3( 0.04045 ) ) ) ), gl_FragColor.w );\n\t#endif\n\t#include \n\t#include \n}",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}",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}",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}",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 \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}",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}",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 \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}",equirect_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}",equirect_frag:"uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV = equirectUv( direction );\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\t#include \n\t#include \n}",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\t#include \n}",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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",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#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\t\t#include \n\t\t#include \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\t#include \n\t#include \n}",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 \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\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",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\t#include \n}",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 \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_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_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshmatcap_vert:"#define MATCAP\nvarying vec3 vViewPosition;\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\tvViewPosition = - mvPosition.xyz;\n}",meshmatcap_frag:"#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\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\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#else\n\t\tvec4 matcapColor = vec4( vec3( mix( 0.2, 0.8, uv.y ) ), 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshnormal_vert:"#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\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#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}",meshnormal_frag:"#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\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\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n\t#ifdef OPAQUE\n\t\tgl_FragColor.a = 1.0;\n\t#endif\n}",meshphong_vert:"#define PHONG\nvarying vec3 vViewPosition;\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\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}",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 \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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshphysical_vert:"#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n\tvarying vec3 vWorldPosition;\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\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\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n#ifdef USE_TRANSMISSION\n\tvWorldPosition = worldPosition.xyz;\n#endif\n}",meshphysical_frag:"#define STANDARD\n#ifdef PHYSICAL\n\t#define IOR\n\t#define SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n\tuniform float ior;\n#endif\n#ifdef SPECULAR\n\tuniform float specularIntensity;\n\tuniform vec3 specularColor;\n\t#ifdef USE_SPECULARINTENSITYMAP\n\t\tuniform sampler2D specularIntensityMap;\n\t#endif\n\t#ifdef USE_SPECULARCOLORMAP\n\t\tuniform sampler2D specularColorMap;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_IRIDESCENCE\n\tuniform float iridescence;\n\tuniform float iridescenceIOR;\n\tuniform float iridescenceThicknessMinimum;\n\tuniform float iridescenceThicknessMaximum;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheenColor;\n\tuniform float sheenRoughness;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tuniform sampler2D sheenColorMap;\n\t#endif\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tuniform sampler2D sheenRoughnessMap;\n\t#endif\n#endif\nvarying vec3 vViewPosition;\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 \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\t#include \n\t#include \n\t#include \n\tvec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n\tvec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n\t#include \n\tvec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n\t#ifdef USE_SHEEN\n\t\tfloat sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor );\n\t\toutgoingLight = outgoingLight * sheenEnergyComp + sheenSpecular;\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNVcc = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\tvec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n\t\toutgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + clearcoatSpecular * material.clearcoat;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshtoon_vert:"#define TOON\nvarying vec3 vViewPosition;\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\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}",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 \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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",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\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}",points_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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",shadow_vert:"#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}",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}",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}",sprite_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \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\t#include \n\t#include \n\t#include \n\t#include \n}"},yn={common:{diffuse:{value:new Ht(16777215)},opacity:{value:1},map:{value:null},uvTransform:{value:new Ct},uv2Transform:{value:new Ct},alphaMap:{value:null},alphaTest:{value:0}},specularmap:{specularMap:{value:null}},envmap:{envMap:{value:null},flipEnvMap:{value:-1},reflectivity:{value:1},ior:{value:1.5},refractionRatio:{value:.98}},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 Et(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:25e-5},fogNear:{value:1},fogFar:{value:2e3},fogColor:{value:new Ht(16777215)}},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:{}}},rectAreaLights:{value:[],properties:{color:{},position:{},width:{},height:{}}},ltc_1:{value:null},ltc_2:{value:null}},points:{diffuse:{value:new Ht(16777215)},opacity:{value:1},size:{value:1},scale:{value:1},map:{value:null},alphaMap:{value:null},alphaTest:{value:0},uvTransform:{value:new Ct}},sprite:{diffuse:{value:new Ht(16777215)},opacity:{value:1},center:{value:new Et(.5,.5)},rotation:{value:0},map:{value:null},alphaMap:{value:null},alphaTest:{value:0},uvTransform:{value:new Ct}}},Mn={basic:{uniforms:Qi([yn.common,yn.specularmap,yn.envmap,yn.aomap,yn.lightmap,yn.fog]),vertexShader:_n.meshbasic_vert,fragmentShader:_n.meshbasic_frag},lambert:{uniforms:Qi([yn.common,yn.specularmap,yn.envmap,yn.aomap,yn.lightmap,yn.emissivemap,yn.fog,yn.lights,{emissive:{value:new Ht(0)}}]),vertexShader:_n.meshlambert_vert,fragmentShader:_n.meshlambert_frag},phong:{uniforms:Qi([yn.common,yn.specularmap,yn.envmap,yn.aomap,yn.lightmap,yn.emissivemap,yn.bumpmap,yn.normalmap,yn.displacementmap,yn.fog,yn.lights,{emissive:{value:new Ht(0)},specular:{value:new Ht(1118481)},shininess:{value:30}}]),vertexShader:_n.meshphong_vert,fragmentShader:_n.meshphong_frag},standard:{uniforms:Qi([yn.common,yn.envmap,yn.aomap,yn.lightmap,yn.emissivemap,yn.bumpmap,yn.normalmap,yn.displacementmap,yn.roughnessmap,yn.metalnessmap,yn.fog,yn.lights,{emissive:{value:new Ht(0)},roughness:{value:1},metalness:{value:0},envMapIntensity:{value:1}}]),vertexShader:_n.meshphysical_vert,fragmentShader:_n.meshphysical_frag},toon:{uniforms:Qi([yn.common,yn.aomap,yn.lightmap,yn.emissivemap,yn.bumpmap,yn.normalmap,yn.displacementmap,yn.gradientmap,yn.fog,yn.lights,{emissive:{value:new Ht(0)}}]),vertexShader:_n.meshtoon_vert,fragmentShader:_n.meshtoon_frag},matcap:{uniforms:Qi([yn.common,yn.bumpmap,yn.normalmap,yn.displacementmap,yn.fog,{matcap:{value:null}}]),vertexShader:_n.meshmatcap_vert,fragmentShader:_n.meshmatcap_frag},points:{uniforms:Qi([yn.points,yn.fog]),vertexShader:_n.points_vert,fragmentShader:_n.points_frag},dashed:{uniforms:Qi([yn.common,yn.fog,{scale:{value:1},dashSize:{value:1},totalSize:{value:2}}]),vertexShader:_n.linedashed_vert,fragmentShader:_n.linedashed_frag},depth:{uniforms:Qi([yn.common,yn.displacementmap]),vertexShader:_n.depth_vert,fragmentShader:_n.depth_frag},normal:{uniforms:Qi([yn.common,yn.bumpmap,yn.normalmap,yn.displacementmap,{opacity:{value:1}}]),vertexShader:_n.meshnormal_vert,fragmentShader:_n.meshnormal_frag},sprite:{uniforms:Qi([yn.sprite,yn.fog]),vertexShader:_n.sprite_vert,fragmentShader:_n.sprite_frag},background:{uniforms:{uvTransform:{value:new Ct},t2D:{value:null}},vertexShader:_n.background_vert,fragmentShader:_n.background_frag},cube:{uniforms:Qi([yn.envmap,{opacity:{value:1}}]),vertexShader:_n.cube_vert,fragmentShader:_n.cube_frag},equirect:{uniforms:{tEquirect:{value:null}},vertexShader:_n.equirect_vert,fragmentShader:_n.equirect_frag},distanceRGBA:{uniforms:Qi([yn.common,yn.displacementmap,{referencePosition:{value:new ee},nearDistance:{value:1},farDistance:{value:1e3}}]),vertexShader:_n.distanceRGBA_vert,fragmentShader:_n.distanceRGBA_frag},shadow:{uniforms:Qi([yn.lights,yn.fog,{color:{value:new Ht(0)},opacity:{value:1}}]),vertexShader:_n.shadow_vert,fragmentShader:_n.shadow_frag}};function bn(t,e,i,n,r,s){const a=new Ht(0);let o,c,h=!0===r?0:1,u=null,d=0,p=null;function f(t,e){i.buffers.color.setClear(t.r,t.g,t.b,e,s)}return{getClearColor:function(){return a},setClearColor:function(t,e=1){a.set(t),h=e,f(a,h)},getClearAlpha:function(){return h},setClearAlpha:function(t){h=t,f(a,h)},render:function(i,r){let s=!1,m=!0===r.isScene?r.background:null;m&&m.isTexture&&(m=e.get(m));const g=t.xr,v=g.getSession&&g.getSession();v&&"additive"===v.environmentBlendMode&&(m=null),null===m?f(a,h):m&&m.isColor&&(f(m,1),s=!0),(t.autoClear||s)&&t.clear(t.autoClearColor,t.autoClearDepth,t.autoClearStencil),m&&(m.isCubeTexture||m.mapping===l)?(void 0===c&&(c=new Zi(new Ki(1,1,1),new en({name:"BackgroundCubeMaterial",uniforms:$i(Mn.cube.uniforms),vertexShader:Mn.cube.vertexShader,fragmentShader:Mn.cube.fragmentShader,side:1,depthTest:!1,depthWrite:!1,fog:!1})),c.geometry.deleteAttribute("normal"),c.geometry.deleteAttribute("uv"),c.onBeforeRender=function(t,e,i){this.matrixWorld.copyPosition(i.matrixWorld)},Object.defineProperty(c.material,"envMap",{get:function(){return this.uniforms.envMap.value}}),n.update(c)),c.material.uniforms.envMap.value=m,c.material.uniforms.flipEnvMap.value=m.isCubeTexture&&!1===m.isRenderTargetTexture?-1:1,u===m&&d===m.version&&p===t.toneMapping||(c.material.needsUpdate=!0,u=m,d=m.version,p=t.toneMapping),c.layers.enableAll(),i.unshift(c,c.geometry,c.material,0,0,null)):m&&m.isTexture&&(void 0===o&&(o=new Zi(new xn(2,2),new en({name:"BackgroundMaterial",uniforms:$i(Mn.background.uniforms),vertexShader:Mn.background.vertexShader,fragmentShader:Mn.background.fragmentShader,side:0,depthTest:!1,depthWrite:!1,fog:!1})),o.geometry.deleteAttribute("normal"),Object.defineProperty(o.material,"map",{get:function(){return this.uniforms.t2D.value}}),n.update(o)),o.material.uniforms.t2D.value=m,!0===m.matrixAutoUpdate&&m.updateMatrix(),o.material.uniforms.uvTransform.value.copy(m.matrix),u===m&&d===m.version&&p===t.toneMapping||(o.material.needsUpdate=!0,u=m,d=m.version,p=t.toneMapping),o.layers.enableAll(),i.unshift(o,o.geometry,o.material,0,0,null))}}}function wn(t,e,i,n){const r=t.getParameter(34921),s=n.isWebGL2?null:e.get("OES_vertex_array_object"),a=n.isWebGL2||null!==s,o={},l=p(null);let c=l,h=!1;function u(e){return n.isWebGL2?t.bindVertexArray(e):s.bindVertexArrayOES(e)}function d(e){return n.isWebGL2?t.deleteVertexArray(e):s.deleteVertexArrayOES(e)}function p(t){const e=[],i=[],n=[];for(let t=0;t=0){const i=r[e];let n=s[e];if(void 0===n&&("instanceMatrix"===e&&t.instanceMatrix&&(n=t.instanceMatrix),"instanceColor"===e&&t.instanceColor&&(n=t.instanceColor)),void 0===i)return!0;if(i.attribute!==n)return!0;if(n&&i.data!==n.data)return!0;a++}}return c.attributesNum!==a||c.index!==n}(r,_,d,y),M&&function(t,e,i,n){const r={},s=e.attributes;let a=0;const o=i.getAttributes();for(const e in o){if(o[e].location>=0){let i=s[e];void 0===i&&("instanceMatrix"===e&&t.instanceMatrix&&(i=t.instanceMatrix),"instanceColor"===e&&t.instanceColor&&(i=t.instanceColor));const n={};n.attribute=i,i&&i.data&&(n.data=i.data),r[e]=n,a++}}c.attributes=r,c.attributesNum=a,c.index=n}(r,_,d,y)}else{const t=!0===l.wireframe;c.geometry===_.id&&c.program===d.id&&c.wireframe===t||(c.geometry=_.id,c.program=d.id,c.wireframe=t,M=!0)}null!==y&&i.update(y,34963),(M||h)&&(h=!1,function(r,s,a,o){if(!1===n.isWebGL2&&(r.isInstancedMesh||o.isInstancedBufferGeometry)&&null===e.get("ANGLE_instanced_arrays"))return;f();const l=o.attributes,c=a.getAttributes(),h=s.defaultAttributeValues;for(const e in c){const n=c[e];if(n.location>=0){let s=l[e];if(void 0===s&&("instanceMatrix"===e&&r.instanceMatrix&&(s=r.instanceMatrix),"instanceColor"===e&&r.instanceColor&&(s=r.instanceColor)),void 0!==s){const e=s.normalized,a=s.itemSize,l=i.get(s);if(void 0===l)continue;const c=l.buffer,h=l.type,u=l.bytesPerElement;if(s.isInterleavedBufferAttribute){const i=s.data,l=i.stride,d=s.offset;if(i.isInstancedInterleavedBuffer){for(let t=0;t0&&t.getShaderPrecisionFormat(35632,36338).precision>0)return"highp";e="mediump"}return"mediump"===e&&t.getShaderPrecisionFormat(35633,36337).precision>0&&t.getShaderPrecisionFormat(35632,36337).precision>0?"mediump":"lowp"}const s="undefined"!=typeof WebGL2RenderingContext&&t instanceof WebGL2RenderingContext||"undefined"!=typeof WebGL2ComputeRenderingContext&&t instanceof WebGL2ComputeRenderingContext;let a=void 0!==i.precision?i.precision:"highp";const o=r(a);o!==a&&(console.warn("THREE.WebGLRenderer:",a,"not supported, using",o,"instead."),a=o);const l=s||e.has("WEBGL_draw_buffers"),c=!0===i.logarithmicDepthBuffer,h=t.getParameter(34930),u=t.getParameter(35660),d=t.getParameter(3379),p=t.getParameter(34076),f=t.getParameter(34921),m=t.getParameter(36347),g=t.getParameter(36348),v=t.getParameter(36349),x=u>0,_=s||e.has("OES_texture_float");return{isWebGL2:s,drawBuffers:l,getMaxAnisotropy:function(){if(void 0!==n)return n;if(!0===e.has("EXT_texture_filter_anisotropic")){const i=e.get("EXT_texture_filter_anisotropic");n=t.getParameter(i.MAX_TEXTURE_MAX_ANISOTROPY_EXT)}else n=0;return n},getMaxPrecision:r,precision:a,logarithmicDepthBuffer:c,maxTextures:h,maxVertexTextures:u,maxTextureSize:d,maxCubemapSize:p,maxAttributes:f,maxVertexUniforms:m,maxVaryings:g,maxFragmentUniforms:v,vertexTextures:x,floatFragmentTextures:_,floatVertexTextures:x&&_,maxSamples:s?t.getParameter(36183):0}}function An(t){const e=this;let i=null,n=0,r=!1,s=!1;const a=new dn,o=new Ct,l={value:null,needsUpdate:!1};function c(){l.value!==i&&(l.value=i,l.needsUpdate=n>0),e.numPlanes=n,e.numIntersection=0}function h(t,i,n,r){const s=null!==t?t.length:0;let c=null;if(0!==s){if(c=l.value,!0!==r||null===c){const e=n+4*s,r=i.matrixWorldInverse;o.getNormalMatrix(r),(null===c||c.length0){const a=new ln(s.height/2);return a.fromEquirectangularTexture(t,r),e.set(r,a),r.addEventListener("dispose",n),i(a.texture,r.mapping)}return null}}}return r},dispose:function(){e=new WeakMap}}}Mn.physical={uniforms:Qi([Mn.standard.uniforms,{clearcoat:{value:0},clearcoatMap:{value:null},clearcoatRoughness:{value:0},clearcoatRoughnessMap:{value:null},clearcoatNormalScale:{value:new Et(1,1)},clearcoatNormalMap:{value:null},iridescence:{value:0},iridescenceMap:{value:null},iridescenceIOR:{value:1.3},iridescenceThicknessMinimum:{value:100},iridescenceThicknessMaximum:{value:400},iridescenceThicknessMap:{value:null},sheen:{value:0},sheenColor:{value:new Ht(0)},sheenColorMap:{value:null},sheenRoughness:{value:1},sheenRoughnessMap:{value:null},transmission:{value:0},transmissionMap:{value:null},transmissionSamplerSize:{value:new Et},transmissionSamplerMap:{value:null},thickness:{value:0},thicknessMap:{value:null},attenuationDistance:{value:0},attenuationColor:{value:new Ht(0)},specularIntensity:{value:1},specularIntensityMap:{value:null},specularColor:{value:new Ht(1,1,1)},specularColorMap:{value:null}}]),vertexShader:_n.meshphysical_vert,fragmentShader:_n.meshphysical_frag};class Cn extends nn{constructor(t=-1,e=1,i=1,n=-1,r=.1,s=2e3){super(),this.isOrthographicCamera=!0,this.type="OrthographicCamera",this.zoom=1,this.view=null,this.left=t,this.right=e,this.top=i,this.bottom=n,this.near=r,this.far=s,this.updateProjectionMatrix()}copy(t,e){return super.copy(t,e),this.left=t.left,this.right=t.right,this.top=t.top,this.bottom=t.bottom,this.near=t.near,this.far=t.far,this.zoom=t.zoom,this.view=null===t.view?null:Object.assign({},t.view),this}setViewOffset(t,e,i,n,r,s){null===this.view&&(this.view={enabled:!0,fullWidth:1,fullHeight:1,offsetX:0,offsetY:0,width:1,height:1}),this.view.enabled=!0,this.view.fullWidth=t,this.view.fullHeight=e,this.view.offsetX=i,this.view.offsetY=n,this.view.width=r,this.view.height=s,this.updateProjectionMatrix()}clearViewOffset(){null!==this.view&&(this.view.enabled=!1),this.updateProjectionMatrix()}updateProjectionMatrix(){const t=(this.right-this.left)/(2*this.zoom),e=(this.top-this.bottom)/(2*this.zoom),i=(this.right+this.left)/2,n=(this.top+this.bottom)/2;let r=i-t,s=i+t,a=n+e,o=n-e;if(null!==this.view&&this.view.enabled){const t=(this.right-this.left)/this.view.fullWidth/this.zoom,e=(this.top-this.bottom)/this.view.fullHeight/this.zoom;r+=t*this.view.offsetX,s=r+t*this.view.width,a-=e*this.view.offsetY,o=a-e*this.view.height}this.projectionMatrix.makeOrthographic(r,s,a,o,this.near,this.far),this.projectionMatrixInverse.copy(this.projectionMatrix).invert()}toJSON(t){const e=super.toJSON(t);return e.object.zoom=this.zoom,e.object.left=this.left,e.object.right=this.right,e.object.top=this.top,e.object.bottom=this.bottom,e.object.near=this.near,e.object.far=this.far,null!==this.view&&(e.object.view=Object.assign({},this.view)),e}}const Ln=[.125,.215,.35,.446,.526,.582],Rn=20,Pn=new Cn,In=new Ht;let Dn=null;const Nn=(1+Math.sqrt(5))/2,On=1/Nn,zn=[new ee(1,1,1),new ee(-1,1,1),new ee(1,1,-1),new ee(-1,1,-1),new ee(0,Nn,On),new ee(0,Nn,-On),new ee(On,0,Nn),new ee(-On,0,Nn),new ee(Nn,On,0),new ee(-Nn,On,0)];class Fn{constructor(t){this._renderer=t,this._pingPongRenderTarget=null,this._lodMax=0,this._cubeSize=0,this._lodPlanes=[],this._sizeLods=[],this._sigmas=[],this._blurMaterial=null,this._cubemapMaterial=null,this._equirectMaterial=null,this._compileMaterial(this._blurMaterial)}fromScene(t,e=0,i=.1,n=100){Dn=this._renderer.getRenderTarget(),this._setSize(256);const r=this._allocateTargets();return r.depthBuffer=!0,this._sceneToCubeUV(t,i,n,r),e>0&&this._blur(r,0,0,e),this._applyPMREM(r),this._cleanup(r),r}fromEquirectangular(t,e=null){return this._fromTexture(t,e)}fromCubemap(t,e=null){return this._fromTexture(t,e)}compileCubemapShader(){null===this._cubemapMaterial&&(this._cubemapMaterial=Gn(),this._compileMaterial(this._cubemapMaterial))}compileEquirectangularShader(){null===this._equirectMaterial&&(this._equirectMaterial=kn(),this._compileMaterial(this._equirectMaterial))}dispose(){this._dispose(),null!==this._cubemapMaterial&&this._cubemapMaterial.dispose(),null!==this._equirectMaterial&&this._equirectMaterial.dispose()}_setSize(t){this._lodMax=Math.floor(Math.log2(t)),this._cubeSize=Math.pow(2,this._lodMax)}_dispose(){null!==this._blurMaterial&&this._blurMaterial.dispose(),null!==this._pingPongRenderTarget&&this._pingPongRenderTarget.dispose();for(let t=0;tt-4?o=Ln[a-t+4-1]:0===a&&(o=0),n.push(o);const l=1/(s-2),c=-l,h=1+l,u=[c,c,h,c,h,h,c,c,h,h,c,h],d=6,p=6,f=3,m=2,g=1,v=new Float32Array(f*p*d),x=new Float32Array(m*p*d),_=new Float32Array(g*p*d);for(let t=0;t2?0:-1,n=[e,i,0,e+2/3,i,0,e+2/3,i+1,0,e,i,0,e+2/3,i+1,0,e,i+1,0];v.set(n,f*p*t),x.set(u,m*p*t);const r=[t,t,t,t,t,t];_.set(r,g*p*t)}const y=new Pi;y.setAttribute("position",new yi(v,f)),y.setAttribute("uv",new yi(x,m)),y.setAttribute("faceIndex",new yi(_,g)),e.push(y),r>4&&r--}return{lodPlanes:e,sizeLods:i,sigmas:n}}(n)),this._blurMaterial=function(t,e,i){const n=new Float32Array(Rn),r=new ee(0,1,0);return new en({name:"SphericalGaussianBlur",defines:{n:Rn,CUBEUV_TEXEL_WIDTH:1/e,CUBEUV_TEXEL_HEIGHT:1/i,CUBEUV_MAX_MIP:`${t}.0`},uniforms:{envMap:{value:null},samples:{value:1},weights:{value:n},latitudinal:{value:!1},dTheta:{value:0},mipInt:{value:0},poleAxis:{value:r}},vertexShader:Vn(),fragmentShader:"\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#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}\n\t\t",blending:0,depthTest:!1,depthWrite:!1})}(n,t,e)}return n}_compileMaterial(t){const e=new Zi(this._lodPlanes[0],t);this._renderer.compile(e,Pn)}_sceneToCubeUV(t,e,i,n){const r=new rn(90,1,e,i),s=[1,-1,1,1,1,1],a=[1,1,1,-1,-1,-1],o=this._renderer,l=o.autoClear,c=o.toneMapping;o.getClearColor(In),o.toneMapping=0,o.autoClear=!1;const h=new vi({name:"PMREM.Background",side:1,depthWrite:!1,depthTest:!1}),u=new Zi(new Ki,h);let d=!1;const p=t.background;p?p.isColor&&(h.color.copy(p),t.background=null,d=!0):(h.color.copy(In),d=!0);for(let e=0;e<6;e++){const i=e%3;0===i?(r.up.set(0,s[e],0),r.lookAt(a[e],0,0)):1===i?(r.up.set(0,0,s[e]),r.lookAt(0,a[e],0)):(r.up.set(0,s[e],0),r.lookAt(0,0,a[e]));const l=this._cubeSize;Un(n,i*l,e>2?l:0,l,l),o.setRenderTarget(n),d&&o.render(u,r),o.render(t,r)}u.geometry.dispose(),u.material.dispose(),o.toneMapping=c,o.autoClear=l,t.background=p}_textureToCubeUV(t,e){const i=this._renderer,n=t.mapping===r||t.mapping===s;n?(null===this._cubemapMaterial&&(this._cubemapMaterial=Gn()),this._cubemapMaterial.uniforms.flipEnvMap.value=!1===t.isRenderTargetTexture?-1:1):null===this._equirectMaterial&&(this._equirectMaterial=kn());const a=n?this._cubemapMaterial:this._equirectMaterial,o=new Zi(this._lodPlanes[0],a);a.uniforms.envMap.value=t;const l=this._cubeSize;Un(e,0,0,3*l,2*l),i.setRenderTarget(e),i.render(o,Pn)}_applyPMREM(t){const e=this._renderer,i=e.autoClear;e.autoClear=!1;for(let e=1;eRn&&console.warn(`sigmaRadians, ${r}, is too large and will clip, as it requested ${f} samples when the maximum is set to 20`);const m=[];let g=0;for(let t=0;tv-4?n-v+4:0),4*(this._cubeSize-x),3*x,2*x),o.setRenderTarget(e),o.render(c,Pn)}}function Bn(t,e,i){const n=new Kt(t,e,i);return n.texture.mapping=l,n.texture.name="PMREM.cubeUv",n.scissorTest=!0,n}function Un(t,e,i,n,r){t.viewport.set(e,i,n,r),t.scissor.set(e,i,n,r)}function kn(){return new en({name:"EquirectangularToCubeUV",uniforms:{envMap:{value:null}},vertexShader:Vn(),fragmentShader:"\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\n\t\t\t#include \n\n\t\t\tvoid main() {\n\n\t\t\t\tvec3 outputDirection = normalize( vOutputDirection );\n\t\t\t\tvec2 uv = equirectUv( outputDirection );\n\n\t\t\t\tgl_FragColor = vec4( texture2D ( envMap, uv ).rgb, 1.0 );\n\n\t\t\t}\n\t\t",blending:0,depthTest:!1,depthWrite:!1})}function Gn(){return new en({name:"CubemapToCubeUV",uniforms:{envMap:{value:null},flipEnvMap:{value:-1}},vertexShader:Vn(),fragmentShader:"\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tuniform float flipEnvMap;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform samplerCube envMap;\n\n\t\t\tvoid main() {\n\n\t\t\t\tgl_FragColor = textureCube( envMap, vec3( flipEnvMap * vOutputDirection.x, vOutputDirection.yz ) );\n\n\t\t\t}\n\t\t",blending:0,depthTest:!1,depthWrite:!1})}function Vn(){return"\n\n\t\tprecision mediump float;\n\t\tprecision mediump int;\n\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 Hn(t){let e=new WeakMap,i=null;function n(t){const i=t.target;i.removeEventListener("dispose",n);const r=e.get(i);void 0!==r&&(e.delete(i),r.dispose())}return{get:function(l){if(l&&l.isTexture){const c=l.mapping,h=c===a||c===o,u=c===r||c===s;if(h||u){if(l.isRenderTargetTexture&&!0===l.needsPMREMUpdate){l.needsPMREMUpdate=!1;let n=e.get(l);return null===i&&(i=new Fn(t)),n=h?i.fromEquirectangular(l,n):i.fromCubemap(l,n),e.set(l,n),n.texture}if(e.has(l))return e.get(l).texture;{const r=l.image;if(h&&r&&r.height>0||u&&r&&function(t){let e=0;const i=6;for(let n=0;ne.maxTextureSize&&(E=Math.ceil(A/e.maxTextureSize),A=e.maxTextureSize);const C=new Float32Array(A*E*4*f),L=new $t(C,A,E,f);L.type=M,L.needsUpdate=!0;const R=4*T;for(let I=0;I0)return t;const r=e*i;let s=nr[r];if(void 0===s&&(s=new Float32Array(r),nr[r]=s),0!==e){n.toArray(s,0);for(let n=1,r=0;n!==e;++n)r+=i,t[n].toArray(s,r)}return s}function cr(t,e){if(t.length!==e.length)return!1;for(let i=0,n=t.length;i":" "} ${r}: ${i[t]}`)}return n.join("\n")}(t.getShaderSource(e),n)}return r}function as(t,e){const i=function(t){switch(t){case at:return["Linear","( value )"];case ot:return["sRGB","( value )"];default:return console.warn("THREE.WebGLProgram: Unsupported encoding:",t),["Linear","( value )"]}}(e);return"vec4 "+t+"( vec4 value ) { return LinearTo"+i[0]+i[1]+"; }"}function os(t,e){let i;switch(e){case 1:i="Linear";break;case 2:i="Reinhard";break;case 3:i="OptimizedCineon";break;case 4:i="ACESFilmic";break;case 5:i="Custom";break;default:console.warn("THREE.WebGLProgram: Unsupported toneMapping:",e),i="Linear"}return"vec3 "+t+"( vec3 color ) { return "+i+"ToneMapping( color ); }"}function ls(t){return""!==t}function cs(t,e){return t.replace(/NUM_DIR_LIGHTS/g,e.numDirLights).replace(/NUM_SPOT_LIGHTS/g,e.numSpotLights).replace(/NUM_RECT_AREA_LIGHTS/g,e.numRectAreaLights).replace(/NUM_POINT_LIGHTS/g,e.numPointLights).replace(/NUM_HEMI_LIGHTS/g,e.numHemiLights).replace(/NUM_DIR_LIGHT_SHADOWS/g,e.numDirLightShadows).replace(/NUM_SPOT_LIGHT_SHADOWS/g,e.numSpotLightShadows).replace(/NUM_POINT_LIGHT_SHADOWS/g,e.numPointLightShadows)}function hs(t,e){return t.replace(/NUM_CLIPPING_PLANES/g,e.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g,e.numClippingPlanes-e.numClipIntersection)}const us=/^[ \t]*#include +<([\w\d./]+)>/gm;function ds(t){return t.replace(us,ps)}function ps(t,e){const i=_n[e];if(void 0===i)throw new Error("Can not resolve #include <"+e+">");return ds(i)}const fs=/#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g,ms=/#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;function gs(t){return t.replace(ms,xs).replace(fs,vs)}function vs(t,e,i,n){return console.warn("WebGLProgram: #pragma unroll_loop shader syntax is deprecated. Please use #pragma unroll_loop_start syntax instead."),xs(t,e,i,n)}function xs(t,e,i,n){let r="";for(let t=parseInt(e);t0&&(_+="\n"),y=[g,v].filter(ls).join("\n"),y.length>0&&(y+="\n")):(_=[_s(i),"#define SHADER_NAME "+i.shaderName,v,i.instancing?"#define USE_INSTANCING":"",i.instancingColor?"#define USE_INSTANCING_COLOR":"",i.supportsVertexTextures?"#define VERTEX_TEXTURES":"",i.useFog&&i.fog?"#define USE_FOG":"",i.useFog&&i.fogExp2?"#define FOG_EXP2":"",i.map?"#define USE_MAP":"",i.envMap?"#define USE_ENVMAP":"",i.envMap?"#define "+p:"",i.lightMap?"#define USE_LIGHTMAP":"",i.aoMap?"#define USE_AOMAP":"",i.emissiveMap?"#define USE_EMISSIVEMAP":"",i.bumpMap?"#define USE_BUMPMAP":"",i.normalMap?"#define USE_NORMALMAP":"",i.normalMap&&i.objectSpaceNormalMap?"#define OBJECTSPACE_NORMALMAP":"",i.normalMap&&i.tangentSpaceNormalMap?"#define TANGENTSPACE_NORMALMAP":"",i.clearcoatMap?"#define USE_CLEARCOATMAP":"",i.clearcoatRoughnessMap?"#define USE_CLEARCOAT_ROUGHNESSMAP":"",i.clearcoatNormalMap?"#define USE_CLEARCOAT_NORMALMAP":"",i.iridescenceMap?"#define USE_IRIDESCENCEMAP":"",i.iridescenceThicknessMap?"#define USE_IRIDESCENCE_THICKNESSMAP":"",i.displacementMap&&i.supportsVertexTextures?"#define USE_DISPLACEMENTMAP":"",i.specularMap?"#define USE_SPECULARMAP":"",i.specularIntensityMap?"#define USE_SPECULARINTENSITYMAP":"",i.specularColorMap?"#define USE_SPECULARCOLORMAP":"",i.roughnessMap?"#define USE_ROUGHNESSMAP":"",i.metalnessMap?"#define USE_METALNESSMAP":"",i.alphaMap?"#define USE_ALPHAMAP":"",i.transmission?"#define USE_TRANSMISSION":"",i.transmissionMap?"#define USE_TRANSMISSIONMAP":"",i.thicknessMap?"#define USE_THICKNESSMAP":"",i.sheenColorMap?"#define USE_SHEENCOLORMAP":"",i.sheenRoughnessMap?"#define USE_SHEENROUGHNESSMAP":"",i.vertexTangents?"#define USE_TANGENT":"",i.vertexColors?"#define USE_COLOR":"",i.vertexAlphas?"#define USE_COLOR_ALPHA":"",i.vertexUvs?"#define USE_UV":"",i.uvsVertexOnly?"#define UVS_VERTEX_ONLY":"",i.flatShading?"#define FLAT_SHADED":"",i.skinning?"#define USE_SKINNING":"",i.morphTargets?"#define USE_MORPHTARGETS":"",i.morphNormals&&!1===i.flatShading?"#define USE_MORPHNORMALS":"",i.morphColors&&i.isWebGL2?"#define USE_MORPHCOLORS":"",i.morphTargetsCount>0&&i.isWebGL2?"#define MORPHTARGETS_TEXTURE":"",i.morphTargetsCount>0&&i.isWebGL2?"#define MORPHTARGETS_TEXTURE_STRIDE "+i.morphTextureStride:"",i.morphTargetsCount>0&&i.isWebGL2?"#define MORPHTARGETS_COUNT "+i.morphTargetsCount:"",i.doubleSided?"#define DOUBLE_SIDED":"",i.flipSided?"#define FLIP_SIDED":"",i.shadowMapEnabled?"#define USE_SHADOWMAP":"",i.shadowMapEnabled?"#define "+u:"",i.sizeAttenuation?"#define USE_SIZEATTENUATION":"",i.logarithmicDepthBuffer?"#define USE_LOGDEPTHBUF":"",i.logarithmicDepthBuffer&&i.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","\tattribute mat4 instanceMatrix;","#endif","#ifdef USE_INSTANCING_COLOR","\tattribute vec3 instanceColor;","#endif","attribute vec3 position;","attribute vec3 normal;","attribute vec2 uv;","#ifdef USE_TANGENT","\tattribute vec4 tangent;","#endif","#if defined( USE_COLOR_ALPHA )","\tattribute vec4 color;","#elif defined( USE_COLOR )","\tattribute vec3 color;","#endif","#if ( defined( USE_MORPHTARGETS ) && ! defined( MORPHTARGETS_TEXTURE ) )","\tattribute vec3 morphTarget0;","\tattribute vec3 morphTarget1;","\tattribute vec3 morphTarget2;","\tattribute vec3 morphTarget3;","\t#ifdef USE_MORPHNORMALS","\t\tattribute vec3 morphNormal0;","\t\tattribute vec3 morphNormal1;","\t\tattribute vec3 morphNormal2;","\t\tattribute vec3 morphNormal3;","\t#else","\t\tattribute vec3 morphTarget4;","\t\tattribute vec3 morphTarget5;","\t\tattribute vec3 morphTarget6;","\t\tattribute vec3 morphTarget7;","\t#endif","#endif","#ifdef USE_SKINNING","\tattribute vec4 skinIndex;","\tattribute vec4 skinWeight;","#endif","\n"].filter(ls).join("\n"),y=[g,_s(i),"#define SHADER_NAME "+i.shaderName,v,i.useFog&&i.fog?"#define USE_FOG":"",i.useFog&&i.fogExp2?"#define FOG_EXP2":"",i.map?"#define USE_MAP":"",i.matcap?"#define USE_MATCAP":"",i.envMap?"#define USE_ENVMAP":"",i.envMap?"#define "+d:"",i.envMap?"#define "+p:"",i.envMap?"#define "+f:"",m?"#define CUBEUV_TEXEL_WIDTH "+m.texelWidth:"",m?"#define CUBEUV_TEXEL_HEIGHT "+m.texelHeight:"",m?"#define CUBEUV_MAX_MIP "+m.maxMip+".0":"",i.lightMap?"#define USE_LIGHTMAP":"",i.aoMap?"#define USE_AOMAP":"",i.emissiveMap?"#define USE_EMISSIVEMAP":"",i.bumpMap?"#define USE_BUMPMAP":"",i.normalMap?"#define USE_NORMALMAP":"",i.normalMap&&i.objectSpaceNormalMap?"#define OBJECTSPACE_NORMALMAP":"",i.normalMap&&i.tangentSpaceNormalMap?"#define TANGENTSPACE_NORMALMAP":"",i.clearcoat?"#define USE_CLEARCOAT":"",i.clearcoatMap?"#define USE_CLEARCOATMAP":"",i.clearcoatRoughnessMap?"#define USE_CLEARCOAT_ROUGHNESSMAP":"",i.clearcoatNormalMap?"#define USE_CLEARCOAT_NORMALMAP":"",i.iridescence?"#define USE_IRIDESCENCE":"",i.iridescenceMap?"#define USE_IRIDESCENCEMAP":"",i.iridescenceThicknessMap?"#define USE_IRIDESCENCE_THICKNESSMAP":"",i.specularMap?"#define USE_SPECULARMAP":"",i.specularIntensityMap?"#define USE_SPECULARINTENSITYMAP":"",i.specularColorMap?"#define USE_SPECULARCOLORMAP":"",i.roughnessMap?"#define USE_ROUGHNESSMAP":"",i.metalnessMap?"#define USE_METALNESSMAP":"",i.alphaMap?"#define USE_ALPHAMAP":"",i.alphaTest?"#define USE_ALPHATEST":"",i.sheen?"#define USE_SHEEN":"",i.sheenColorMap?"#define USE_SHEENCOLORMAP":"",i.sheenRoughnessMap?"#define USE_SHEENROUGHNESSMAP":"",i.transmission?"#define USE_TRANSMISSION":"",i.transmissionMap?"#define USE_TRANSMISSIONMAP":"",i.thicknessMap?"#define USE_THICKNESSMAP":"",i.decodeVideoTexture?"#define DECODE_VIDEO_TEXTURE":"",i.vertexTangents?"#define USE_TANGENT":"",i.vertexColors||i.instancingColor?"#define USE_COLOR":"",i.vertexAlphas?"#define USE_COLOR_ALPHA":"",i.vertexUvs?"#define USE_UV":"",i.uvsVertexOnly?"#define UVS_VERTEX_ONLY":"",i.gradientMap?"#define USE_GRADIENTMAP":"",i.flatShading?"#define FLAT_SHADED":"",i.doubleSided?"#define DOUBLE_SIDED":"",i.flipSided?"#define FLIP_SIDED":"",i.shadowMapEnabled?"#define USE_SHADOWMAP":"",i.shadowMapEnabled?"#define "+u:"",i.premultipliedAlpha?"#define PREMULTIPLIED_ALPHA":"",i.physicallyCorrectLights?"#define PHYSICALLY_CORRECT_LIGHTS":"",i.logarithmicDepthBuffer?"#define USE_LOGDEPTHBUF":"",i.logarithmicDepthBuffer&&i.rendererExtensionFragDepth?"#define USE_LOGDEPTHBUF_EXT":"","uniform mat4 viewMatrix;","uniform vec3 cameraPosition;","uniform bool isOrthographic;",0!==i.toneMapping?"#define TONE_MAPPING":"",0!==i.toneMapping?_n.tonemapping_pars_fragment:"",0!==i.toneMapping?os("toneMapping",i.toneMapping):"",i.dithering?"#define DITHERING":"",i.opaque?"#define OPAQUE":"",_n.encodings_pars_fragment,as("linearToOutputTexel",i.outputEncoding),i.useDepthPacking?"#define DEPTH_PACKING "+i.depthPacking:"","\n"].filter(ls).join("\n")),c=ds(c),c=cs(c,i),c=hs(c,i),h=ds(h),h=cs(h,i),h=hs(h,i),c=gs(c),h=gs(h),i.isWebGL2&&!0!==i.isRawShaderMaterial&&(M="#version 300 es\n",_=["precision mediump sampler2DArray;","#define attribute in","#define varying out","#define texture2D texture"].join("\n")+"\n"+_,y=["#define varying in",i.glslVersion===dt?"":"layout(location = 0) out highp vec4 pc_fragColor;",i.glslVersion===dt?"":"#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"+y);const b=M+y+h,w=ns(a,35633,M+_+c),S=ns(a,35632,b);if(a.attachShader(x,w),a.attachShader(x,S),void 0!==i.index0AttributeName?a.bindAttribLocation(x,0,i.index0AttributeName):!0===i.morphTargets&&a.bindAttribLocation(x,0,"position"),a.linkProgram(x),t.debug.checkShaderErrors){const t=a.getProgramInfoLog(x).trim(),e=a.getShaderInfoLog(w).trim(),i=a.getShaderInfoLog(S).trim();let n=!0,r=!0;if(!1===a.getProgramParameter(x,35714)){n=!1;const e=ss(a,w,"vertex"),i=ss(a,S,"fragment");console.error("THREE.WebGLProgram: Shader Error "+a.getError()+" - VALIDATE_STATUS "+a.getProgramParameter(x,35715)+"\n\nProgram Info Log: "+t+"\n"+e+"\n"+i)}else""!==t?console.warn("THREE.WebGLProgram: Program Info Log:",t):""!==e&&""!==i||(r=!1);r&&(this.diagnostics={runnable:n,programLog:t,vertexShader:{log:e,prefix:_},fragmentShader:{log:i,prefix:y}})}let T,A;return a.deleteShader(w),a.deleteShader(S),this.getUniforms=function(){return void 0===T&&(T=new is(a,x)),T},this.getAttributes=function(){return void 0===A&&(A=function(t,e){const i={},n=t.getProgramParameter(e,35721);for(let r=0;r0,D=s.clearcoat>0,N=s.iridescence>0;return{isWebGL2:u,shaderID:w,shaderName:s.type,vertexShader:A,fragmentShader:E,defines:s.defines,customVertexShaderID:C,customFragmentShaderID:L,isRawShaderMaterial:!0===s.isRawShaderMaterial,glslVersion:s.glslVersion,precision:f,instancing:!0===v.isInstancedMesh,instancingColor:!0===v.isInstancedMesh&&null!==v.instanceColor,supportsVertexTextures:p,outputEncoding:null===P?t.outputEncoding:!0===P.isXRRenderTarget?P.texture.encoding:at,map:!!s.map,matcap:!!s.matcap,envMap:!!M,envMapMode:M&&M.mapping,envMapCubeUVHeight:b,lightMap:!!s.lightMap,aoMap:!!s.aoMap,emissiveMap:!!s.emissiveMap,bumpMap:!!s.bumpMap,normalMap:!!s.normalMap,objectSpaceNormalMap:1===s.normalMapType,tangentSpaceNormalMap:0===s.normalMapType,decodeVideoTexture:!!s.map&&!0===s.map.isVideoTexture&&s.map.encoding===ot,clearcoat:D,clearcoatMap:D&&!!s.clearcoatMap,clearcoatRoughnessMap:D&&!!s.clearcoatRoughnessMap,clearcoatNormalMap:D&&!!s.clearcoatNormalMap,iridescence:N,iridescenceMap:N&&!!s.iridescenceMap,iridescenceThicknessMap:N&&!!s.iridescenceThicknessMap,displacementMap:!!s.displacementMap,roughnessMap:!!s.roughnessMap,metalnessMap:!!s.metalnessMap,specularMap:!!s.specularMap,specularIntensityMap:!!s.specularIntensityMap,specularColorMap:!!s.specularColorMap,opaque:!1===s.transparent&&1===s.blending,alphaMap:!!s.alphaMap,alphaTest:I,gradientMap:!!s.gradientMap,sheen:s.sheen>0,sheenColorMap:!!s.sheenColorMap,sheenRoughnessMap:!!s.sheenRoughnessMap,transmission:s.transmission>0,transmissionMap:!!s.transmissionMap,thicknessMap:!!s.thicknessMap,combine:s.combine,vertexTangents:!!s.normalMap&&!!_.attributes.tangent,vertexColors:s.vertexColors,vertexAlphas:!0===s.vertexColors&&!!_.attributes.color&&4===_.attributes.color.itemSize,vertexUvs:!!(s.map||s.bumpMap||s.normalMap||s.specularMap||s.alphaMap||s.emissiveMap||s.roughnessMap||s.metalnessMap||s.clearcoatMap||s.clearcoatRoughnessMap||s.clearcoatNormalMap||s.iridescenceMap||s.iridescenceThicknessMap||s.displacementMap||s.transmissionMap||s.thicknessMap||s.specularIntensityMap||s.specularColorMap||s.sheenColorMap||s.sheenRoughnessMap),uvsVertexOnly:!(s.map||s.bumpMap||s.normalMap||s.specularMap||s.alphaMap||s.emissiveMap||s.roughnessMap||s.metalnessMap||s.clearcoatNormalMap||s.iridescenceMap||s.iridescenceThicknessMap||s.transmission>0||s.transmissionMap||s.thicknessMap||s.specularIntensityMap||s.specularColorMap||s.sheen>0||s.sheenColorMap||s.sheenRoughnessMap||!s.displacementMap),fog:!!x,useFog:!0===s.fog,fogExp2:x&&x.isFogExp2,flatShading:!!s.flatShading,sizeAttenuation:s.sizeAttenuation,logarithmicDepthBuffer:d,skinning:!0===v.isSkinnedMesh,morphTargets:void 0!==_.morphAttributes.position,morphNormals:void 0!==_.morphAttributes.normal,morphColors:void 0!==_.morphAttributes.color,morphTargetsCount:T,morphTextureStride:R,numDirLights:o.directional.length,numPointLights:o.point.length,numSpotLights:o.spot.length,numRectAreaLights:o.rectArea.length,numHemiLights:o.hemi.length,numDirLightShadows:o.directionalShadowMap.length,numPointLightShadows:o.pointShadowMap.length,numSpotLightShadows:o.spotShadowMap.length,numClippingPlanes:a.numPlanes,numClipIntersection:a.numIntersection,dithering:s.dithering,shadowMapEnabled:t.shadowMap.enabled&&h.length>0,shadowMapType:t.shadowMap.type,toneMapping:s.toneMapped?t.toneMapping:0,physicallyCorrectLights:t.physicallyCorrectLights,premultipliedAlpha:s.premultipliedAlpha,doubleSided:2===s.side,flipSided:1===s.side,useDepthPacking:!!s.depthPacking,depthPacking:s.depthPacking||0,index0AttributeName:s.index0AttributeName,extensionDerivatives:s.extensions&&s.extensions.derivatives,extensionFragDepth:s.extensions&&s.extensions.fragDepth,extensionDrawBuffers:s.extensions&&s.extensions.drawBuffers,extensionShaderTextureLOD:s.extensions&&s.extensions.shaderTextureLOD,rendererExtensionFragDepth:u||n.has("EXT_frag_depth"),rendererExtensionDrawBuffers:u||n.has("WEBGL_draw_buffers"),rendererExtensionShaderTextureLod:u||n.has("EXT_shader_texture_lod"),customProgramCacheKey:s.customProgramCacheKey()}},getProgramCacheKey:function(e){const i=[];if(e.shaderID?i.push(e.shaderID):(i.push(e.customVertexShaderID),i.push(e.customFragmentShaderID)),void 0!==e.defines)for(const t in e.defines)i.push(t),i.push(e.defines[t]);return!1===e.isRawShaderMaterial&&(!function(t,e){t.push(e.precision),t.push(e.outputEncoding),t.push(e.envMapMode),t.push(e.envMapCubeUVHeight),t.push(e.combine),t.push(e.vertexUvs),t.push(e.fogExp2),t.push(e.sizeAttenuation),t.push(e.morphTargetsCount),t.push(e.morphAttributeCount),t.push(e.numDirLights),t.push(e.numPointLights),t.push(e.numSpotLights),t.push(e.numHemiLights),t.push(e.numRectAreaLights),t.push(e.numDirLightShadows),t.push(e.numPointLightShadows),t.push(e.numSpotLightShadows),t.push(e.shadowMapType),t.push(e.toneMapping),t.push(e.numClippingPlanes),t.push(e.numClipIntersection),t.push(e.depthPacking)}(i,e),function(t,e){o.disableAll(),e.isWebGL2&&o.enable(0);e.supportsVertexTextures&&o.enable(1);e.instancing&&o.enable(2);e.instancingColor&&o.enable(3);e.map&&o.enable(4);e.matcap&&o.enable(5);e.envMap&&o.enable(6);e.lightMap&&o.enable(7);e.aoMap&&o.enable(8);e.emissiveMap&&o.enable(9);e.bumpMap&&o.enable(10);e.normalMap&&o.enable(11);e.objectSpaceNormalMap&&o.enable(12);e.tangentSpaceNormalMap&&o.enable(13);e.clearcoat&&o.enable(14);e.clearcoatMap&&o.enable(15);e.clearcoatRoughnessMap&&o.enable(16);e.clearcoatNormalMap&&o.enable(17);e.iridescence&&o.enable(18);e.iridescenceMap&&o.enable(19);e.iridescenceThicknessMap&&o.enable(20);e.displacementMap&&o.enable(21);e.specularMap&&o.enable(22);e.roughnessMap&&o.enable(23);e.metalnessMap&&o.enable(24);e.gradientMap&&o.enable(25);e.alphaMap&&o.enable(26);e.alphaTest&&o.enable(27);e.vertexColors&&o.enable(28);e.vertexAlphas&&o.enable(29);e.vertexUvs&&o.enable(30);e.vertexTangents&&o.enable(31);e.uvsVertexOnly&&o.enable(32);e.fog&&o.enable(33);t.push(o.mask),o.disableAll(),e.useFog&&o.enable(0);e.flatShading&&o.enable(1);e.logarithmicDepthBuffer&&o.enable(2);e.skinning&&o.enable(3);e.morphTargets&&o.enable(4);e.morphNormals&&o.enable(5);e.morphColors&&o.enable(6);e.premultipliedAlpha&&o.enable(7);e.shadowMapEnabled&&o.enable(8);e.physicallyCorrectLights&&o.enable(9);e.doubleSided&&o.enable(10);e.flipSided&&o.enable(11);e.useDepthPacking&&o.enable(12);e.dithering&&o.enable(13);e.specularIntensityMap&&o.enable(14);e.specularColorMap&&o.enable(15);e.transmission&&o.enable(16);e.transmissionMap&&o.enable(17);e.thicknessMap&&o.enable(18);e.sheen&&o.enable(19);e.sheenColorMap&&o.enable(20);e.sheenRoughnessMap&&o.enable(21);e.decodeVideoTexture&&o.enable(22);e.opaque&&o.enable(23);t.push(o.mask)}(i,e),i.push(t.outputEncoding)),i.push(e.customProgramCacheKey),i.join()},getUniforms:function(t){const e=m[t.type];let i;if(e){const t=Mn[e];i=tn.clone(t.uniforms)}else i=t.uniforms;return i},acquireProgram:function(e,i){let n;for(let t=0,e=h.length;t0?n.push(h):!0===a.transparent?r.push(h):i.push(h)},unshift:function(t,e,a,o,l,c){const h=s(t,e,a,o,l,c);a.transmission>0?n.unshift(h):!0===a.transparent?r.unshift(h):i.unshift(h)},finish:function(){for(let i=e,n=t.length;i1&&i.sort(t||As),n.length>1&&n.sort(e||Es),r.length>1&&r.sort(e||Es)}}}function Ls(){let t=new WeakMap;return{get:function(e,i){let n;return!1===t.has(e)?(n=new Cs,t.set(e,[n])):i>=t.get(e).length?(n=new Cs,t.get(e).push(n)):n=t.get(e)[i],n},dispose:function(){t=new WeakMap}}}function Rs(){const t={};return{get:function(e){if(void 0!==t[e.id])return t[e.id];let i;switch(e.type){case"DirectionalLight":i={direction:new ee,color:new Ht};break;case"SpotLight":i={position:new ee,direction:new ee,color:new Ht,distance:0,coneCos:0,penumbraCos:0,decay:0};break;case"PointLight":i={position:new ee,color:new Ht,distance:0,decay:0};break;case"HemisphereLight":i={direction:new ee,skyColor:new Ht,groundColor:new Ht};break;case"RectAreaLight":i={color:new Ht,position:new ee,halfWidth:new ee,halfHeight:new ee}}return t[e.id]=i,i}}}let Ps=0;function Is(t,e){return(e.castShadow?1:0)-(t.castShadow?1:0)}function Ds(t,e){const i=new Rs,n=function(){const t={};return{get:function(e){if(void 0!==t[e.id])return t[e.id];let i;switch(e.type){case"DirectionalLight":case"SpotLight":i={shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowMapSize:new Et};break;case"PointLight":i={shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowMapSize:new Et,shadowCameraNear:1,shadowCameraFar:1e3}}return t[e.id]=i,i}}}(),r={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:[]};for(let t=0;t<9;t++)r.probe.push(new ee);const s=new ee,a=new Ie,o=new Ie;return{setup:function(s,a){let o=0,l=0,c=0;for(let t=0;t<9;t++)r.probe[t].set(0,0,0);let h=0,u=0,d=0,p=0,f=0,m=0,g=0,v=0;s.sort(Is);const x=!0!==a?Math.PI:1;for(let t=0,e=s.length;t0&&(e.isWebGL2||!0===t.has("OES_texture_float_linear")?(r.rectAreaLTC1=yn.LTC_FLOAT_1,r.rectAreaLTC2=yn.LTC_FLOAT_2):!0===t.has("OES_texture_half_float_linear")?(r.rectAreaLTC1=yn.LTC_HALF_1,r.rectAreaLTC2=yn.LTC_HALF_2):console.error("THREE.WebGLRenderer: Unable to use RectAreaLight. Missing WebGL extensions.")),r.ambient[0]=o,r.ambient[1]=l,r.ambient[2]=c;const _=r.hash;_.directionalLength===h&&_.pointLength===u&&_.spotLength===d&&_.rectAreaLength===p&&_.hemiLength===f&&_.numDirectionalShadows===m&&_.numPointShadows===g&&_.numSpotShadows===v||(r.directional.length=h,r.spot.length=d,r.rectArea.length=p,r.point.length=u,r.hemi.length=f,r.directionalShadow.length=m,r.directionalShadowMap.length=m,r.pointShadow.length=g,r.pointShadowMap.length=g,r.spotShadow.length=v,r.spotShadowMap.length=v,r.directionalShadowMatrix.length=m,r.pointShadowMatrix.length=g,r.spotShadowMatrix.length=v,_.directionalLength=h,_.pointLength=u,_.spotLength=d,_.rectAreaLength=p,_.hemiLength=f,_.numDirectionalShadows=m,_.numPointShadows=g,_.numSpotShadows=v,r.version=Ps++)},setupView:function(t,e){let i=0,n=0,l=0,c=0,h=0;const u=e.matrixWorldInverse;for(let e=0,d=t.length;e=i.get(n).length?(s=new Ns(t,e),i.get(n).push(s)):s=i.get(n)[r],s},dispose:function(){i=new WeakMap}}}class zs extends gi{constructor(t){super(),this.isMeshDepthMaterial=!0,this.type="MeshDepthMaterial",this.depthPacking=3200,this.map=null,this.alphaMap=null,this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.wireframe=!1,this.wireframeLinewidth=1,this.setValues(t)}copy(t){return super.copy(t),this.depthPacking=t.depthPacking,this.map=t.map,this.alphaMap=t.alphaMap,this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this}}class Fs extends gi{constructor(t){super(),this.isMeshDistanceMaterial=!0,this.type="MeshDistanceMaterial",this.referencePosition=new ee,this.nearDistance=1,this.farDistance=1e3,this.map=null,this.alphaMap=null,this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.setValues(t)}copy(t){return super.copy(t),this.referencePosition.copy(t.referencePosition),this.nearDistance=t.nearDistance,this.farDistance=t.farDistance,this.map=t.map,this.alphaMap=t.alphaMap,this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this}}function Bs(t,e,i){let n=new mn;const r=new Et,s=new Et,a=new Jt,o=new zs({depthPacking:3201}),l=new Fs,c={},h=i.maxTextureSize,u={0:1,1:0,2:2},p=new en({defines:{VSM_SAMPLES:8},uniforms:{shadow_pass:{value:null},resolution:{value:new Et},radius:{value:4}},vertexShader:"void main() {\n\tgl_Position = vec4( position, 1.0 );\n}",fragmentShader:"uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include \nvoid main() {\n\tconst float samples = float( VSM_SAMPLES );\n\tfloat mean = 0.0;\n\tfloat squared_mean = 0.0;\n\tfloat uvStride = samples <= 1.0 ? 0.0 : 2.0 / ( samples - 1.0 );\n\tfloat uvStart = samples <= 1.0 ? 0.0 : - 1.0;\n\tfor ( float i = 0.0; i < samples; i ++ ) {\n\t\tfloat uvOffset = uvStart + i * uvStride;\n\t\t#ifdef HORIZONTAL_PASS\n\t\t\tvec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( uvOffset, 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, uvOffset ) * radius ) / resolution ) );\n\t\t\tmean += depth;\n\t\t\tsquared_mean += depth * depth;\n\t\t#endif\n\t}\n\tmean = mean / samples;\n\tsquared_mean = squared_mean / samples;\n\tfloat std_dev = sqrt( squared_mean - mean * mean );\n\tgl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}"}),f=p.clone();f.defines.HORIZONTAL_PASS=1;const m=new Pi;m.setAttribute("position",new yi(new Float32Array([-1,-1,.5,3,-1,.5,-1,3,.5]),3));const g=new Zi(m,p),v=this;function x(i,n){const s=e.update(g);p.defines.VSM_SAMPLES!==i.blurSamples&&(p.defines.VSM_SAMPLES=i.blurSamples,f.defines.VSM_SAMPLES=i.blurSamples,p.needsUpdate=!0,f.needsUpdate=!0),null===i.mapPass&&(i.mapPass=new Kt(r.x,r.y)),p.uniforms.shadow_pass.value=i.map.texture,p.uniforms.resolution.value=i.mapSize,p.uniforms.radius.value=i.radius,t.setRenderTarget(i.mapPass),t.clear(),t.renderBufferDirect(n,null,s,p,g,null),f.uniforms.shadow_pass.value=i.mapPass.texture,f.uniforms.resolution.value=i.mapSize,f.uniforms.radius.value=i.radius,t.setRenderTarget(i.map),t.clear(),t.renderBufferDirect(n,null,s,f,g,null)}function _(e,i,n,r,s,a){let h=null;const d=!0===n.isPointLight?e.customDistanceMaterial:e.customDepthMaterial;if(h=void 0!==d?d:!0===n.isPointLight?l:o,t.localClippingEnabled&&!0===i.clipShadows&&Array.isArray(i.clippingPlanes)&&0!==i.clippingPlanes.length||i.displacementMap&&0!==i.displacementScale||i.alphaMap&&i.alphaTest>0){const t=h.uuid,e=i.uuid;let n=c[t];void 0===n&&(n={},c[t]=n);let r=n[e];void 0===r&&(r=h.clone(),n[e]=r),h=r}return h.visible=i.visible,h.wireframe=i.wireframe,h.side=3===a?null!==i.shadowSide?i.shadowSide:i.side:null!==i.shadowSide?i.shadowSide:u[i.side],h.alphaMap=i.alphaMap,h.alphaTest=i.alphaTest,h.clipShadows=i.clipShadows,h.clippingPlanes=i.clippingPlanes,h.clipIntersection=i.clipIntersection,h.displacementMap=i.displacementMap,h.displacementScale=i.displacementScale,h.displacementBias=i.displacementBias,h.wireframeLinewidth=i.wireframeLinewidth,h.linewidth=i.linewidth,!0===n.isPointLight&&!0===h.isMeshDistanceMaterial&&(h.referencePosition.setFromMatrixPosition(n.matrixWorld),h.nearDistance=r,h.farDistance=s),h}function y(i,r,s,a,o){if(!1===i.visible)return;if(i.layers.test(r.layers)&&(i.isMesh||i.isLine||i.isPoints)&&(i.castShadow||i.receiveShadow&&3===o)&&(!i.frustumCulled||n.intersectsObject(i))){i.modelViewMatrix.multiplyMatrices(s.matrixWorldInverse,i.matrixWorld);const n=e.update(i),r=i.material;if(Array.isArray(r)){const e=n.groups;for(let l=0,c=e.length;lh||r.y>h)&&(r.x>h&&(s.x=Math.floor(h/f.x),r.x=s.x*f.x,u.mapSize.x=s.x),r.y>h&&(s.y=Math.floor(h/f.y),r.y=s.y*f.y,u.mapSize.y=s.y)),null===u.map){const t=3!==this.type?{minFilter:d,magFilter:d}:{};u.map=new Kt(r.x,r.y,t),u.map.texture.name=c.name+".shadowMap",u.camera.updateProjectionMatrix()}t.setRenderTarget(u.map),t.clear();const m=u.getViewportCount();for(let t=0;t=1):-1!==I.indexOf("OpenGL ES")&&(P=parseFloat(/^OpenGL ES (\d)/.exec(I)[1]),R=P>=2);let D=null,N={};const O=t.getParameter(3088),z=t.getParameter(2978),F=(new Jt).fromArray(O),B=(new Jt).fromArray(z);function U(e,i,n){const r=new Uint8Array(4),s=t.createTexture();t.bindTexture(e,s),t.texParameteri(e,10241,9728),t.texParameteri(e,10240,9728);for(let e=0;en||t.height>n)&&(r=n/Math.max(t.width,t.height)),r<1||!0===e){if("undefined"!=typeof HTMLImageElement&&t instanceof HTMLImageElement||"undefined"!=typeof HTMLCanvasElement&&t instanceof HTMLCanvasElement||"undefined"!=typeof ImageBitmap&&t instanceof ImageBitmap){const n=e?Tt:Math.floor,s=n(r*t.width),a=n(r*t.height);void 0===D&&(D=z(s,a));const o=i?z(s,a):D;o.width=s,o.height=a;return o.getContext("2d").drawImage(t,0,0,s,a),console.warn("THREE.WebGLRenderer: Texture has been resized from ("+t.width+"x"+t.height+") to ("+s+"x"+a+")."),o}return"data"in t&&console.warn("THREE.WebGLRenderer: Image in DataTexture is too big ("+t.width+"x"+t.height+")."),t}return t}function B(t){return wt(t.width)&&wt(t.height)}function U(t,e){return t.generateMipmaps&&e&&t.minFilter!==d&&t.minFilter!==m}function k(e){t.generateMipmap(e)}function G(i,n,r,s,a=!1){if(!1===o)return n;if(null!==i){if(void 0!==t[i])return t[i];console.warn("THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format '"+i+"'")}let l=n;return 6403===n&&(5126===r&&(l=33326),5131===r&&(l=33325),5121===r&&(l=33321)),33319===n&&(5126===r&&(l=33328),5131===r&&(l=33327),5121===r&&(l=33323)),6408===n&&(5126===r&&(l=34836),5131===r&&(l=34842),5121===r&&(l=s===ot&&!1===a?35907:32856),32819===r&&(l=32854),32820===r&&(l=32855)),33325!==l&&33326!==l&&33327!==l&&33328!==l&&34842!==l&&34836!==l||e.get("EXT_color_buffer_float"),l}function V(t,e,i){return!0===U(t,i)||t.isFramebufferTexture&&t.minFilter!==d&&t.minFilter!==m?Math.log2(Math.max(e.width,e.height))+1:void 0!==t.mipmaps&&t.mipmaps.length>0?t.mipmaps.length:t.isCompressedTexture&&Array.isArray(t.image)?e.mipmaps.length:1}function H(t){return t===d||t===p||t===f?9728:9729}function W(t){const e=t.target;e.removeEventListener("dispose",W),function(t){const e=n.get(t);if(void 0===e.__webglInit)return;const i=t.source,r=N.get(i);if(r){const n=r[e.__cacheKey];n.usedTimes--,0===n.usedTimes&&q(t),0===Object.keys(r).length&&N.delete(i)}n.remove(t)}(e),e.isVideoTexture&&I.delete(e)}function j(e){const i=e.target;i.removeEventListener("dispose",j),function(e){const i=e.texture,r=n.get(e),s=n.get(i);void 0!==s.__webglTexture&&(t.deleteTexture(s.__webglTexture),a.memory.textures--);e.depthTexture&&e.depthTexture.dispose();if(e.isWebGLCubeRenderTarget)for(let e=0;e<6;e++)t.deleteFramebuffer(r.__webglFramebuffer[e]),r.__webglDepthbuffer&&t.deleteRenderbuffer(r.__webglDepthbuffer[e]);else{if(t.deleteFramebuffer(r.__webglFramebuffer),r.__webglDepthbuffer&&t.deleteRenderbuffer(r.__webglDepthbuffer),r.__webglMultisampledFramebuffer&&t.deleteFramebuffer(r.__webglMultisampledFramebuffer),r.__webglColorRenderbuffer)for(let e=0;e0&&r.__version!==t.version){const i=t.image;if(null===i)console.warn("THREE.WebGLRenderer: Texture marked for update but no image data found.");else{if(!1!==i.complete)return void Q(r,t,e);console.warn("THREE.WebGLRenderer: Texture marked for update but image is incomplete")}}i.activeTexture(33984+e),i.bindTexture(3553,r.__webglTexture)}const Z={[c]:10497,[h]:33071,[u]:33648},J={[d]:9728,[p]:9984,[f]:9986,[m]:9729,[g]:9985,[v]:9987};function K(i,s,a){if(a?(t.texParameteri(i,10242,Z[s.wrapS]),t.texParameteri(i,10243,Z[s.wrapT]),32879!==i&&35866!==i||t.texParameteri(i,32882,Z[s.wrapR]),t.texParameteri(i,10240,J[s.magFilter]),t.texParameteri(i,10241,J[s.minFilter])):(t.texParameteri(i,10242,33071),t.texParameteri(i,10243,33071),32879!==i&&35866!==i||t.texParameteri(i,32882,33071),s.wrapS===h&&s.wrapT===h||console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping."),t.texParameteri(i,10240,H(s.magFilter)),t.texParameteri(i,10241,H(s.minFilter)),s.minFilter!==d&&s.minFilter!==m&&console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.")),!0===e.has("EXT_texture_filter_anisotropic")){const a=e.get("EXT_texture_filter_anisotropic");if(s.type===M&&!1===e.has("OES_texture_float_linear"))return;if(!1===o&&s.type===b&&!1===e.has("OES_texture_half_float_linear"))return;(s.anisotropy>1||n.get(s).__currentAnisotropy)&&(t.texParameterf(i,a.TEXTURE_MAX_ANISOTROPY_EXT,Math.min(s.anisotropy,r.getMaxAnisotropy())),n.get(s).__currentAnisotropy=s.anisotropy)}}function $(e,i){let n=!1;void 0===e.__webglInit&&(e.__webglInit=!0,i.addEventListener("dispose",W));const r=i.source;let s=N.get(r);void 0===s&&(s={},N.set(r,s));const o=function(t){const e=[];return e.push(t.wrapS),e.push(t.wrapT),e.push(t.magFilter),e.push(t.minFilter),e.push(t.anisotropy),e.push(t.internalFormat),e.push(t.format),e.push(t.type),e.push(t.generateMipmaps),e.push(t.premultiplyAlpha),e.push(t.flipY),e.push(t.unpackAlignment),e.push(t.encoding),e.join()}(i);if(o!==e.__cacheKey){void 0===s[o]&&(s[o]={texture:t.createTexture(),usedTimes:0},a.memory.textures++,n=!0),s[o].usedTimes++;const r=s[e.__cacheKey];void 0!==r&&(s[e.__cacheKey].usedTimes--,0===r.usedTimes&&q(i)),e.__cacheKey=o,e.__webglTexture=s[o].texture}return n}function Q(e,n,r){let a=3553;n.isDataArrayTexture&&(a=35866),n.isData3DTexture&&(a=32879);const l=$(e,n),c=n.source;if(i.activeTexture(33984+r),i.bindTexture(a,e.__webglTexture),c.version!==c.__currentVersion||!0===l){t.pixelStorei(37440,n.flipY),t.pixelStorei(37441,n.premultiplyAlpha),t.pixelStorei(3317,n.unpackAlignment),t.pixelStorei(37443,0);const e=function(t){return!o&&(t.wrapS!==h||t.wrapT!==h||t.minFilter!==d&&t.minFilter!==m)}(n)&&!1===B(n.image);let r=F(n.image,e,!1,C);r=st(n,r);const u=B(r)||o,p=s.convert(n.format,n.encoding);let f,g=s.convert(n.type),v=G(n.internalFormat,p,g,n.encoding,n.isVideoTexture);K(a,n,u);const x=n.mipmaps,b=o&&!0!==n.isVideoTexture,E=void 0===c.__currentVersion||!0===l,L=V(n,r,u);if(n.isDepthTexture)v=6402,o?v=n.type===M?36012:n.type===y?33190:n.type===w?35056:33189:n.type===M&&console.error("WebGLRenderer: Floating point depth texture requires WebGL2."),n.format===T&&6402===v&&n.type!==_&&n.type!==y&&(console.warn("THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture."),n.type=y,g=s.convert(n.type)),n.format===A&&6402===v&&(v=34041,n.type!==w&&(console.warn("THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture."),n.type=w,g=s.convert(n.type))),E&&(b?i.texStorage2D(3553,1,v,r.width,r.height):i.texImage2D(3553,0,v,r.width,r.height,0,p,g,null));else if(n.isDataTexture)if(x.length>0&&u){b&&E&&i.texStorage2D(3553,L,v,x[0].width,x[0].height);for(let t=0,e=x.length;t>=1,e>>=1}}else if(x.length>0&&u){b&&E&&i.texStorage2D(3553,L,v,x[0].width,x[0].height);for(let t=0,e=x.length;t0&&!0===e.has("WEBGL_multisampled_render_to_texture")&&!1!==i.__useRenderToTexture}function st(t,i){const n=t.encoding,r=t.format,s=t.type;return!0===t.isCompressedTexture||!0===t.isVideoTexture||t.format===pt||n!==at&&(n===ot?!1===o?!0===e.has("EXT_sRGB")&&r===S?(t.format=pt,t.minFilter=m,t.generateMipmaps=!1):i=jt.sRGBToLinear(i):r===S&&s===x||console.warn("THREE.WebGLTextures: sRGB encoded textures have to use RGBAFormat and UnsignedByteType."):console.error("THREE.WebGLTextures: Unsupported texture encoding:",n)),i}this.allocateTextureUnit=function(){const t=X;return t>=l&&console.warn("THREE.WebGLTextures: Trying to use "+t+" texture units while this GPU supports only "+l),X+=1,t},this.resetTextureUnits=function(){X=0},this.setTexture2D=Y,this.setTexture2DArray=function(t,e){const r=n.get(t);t.version>0&&r.__version!==t.version?Q(r,t,e):(i.activeTexture(33984+e),i.bindTexture(35866,r.__webglTexture))},this.setTexture3D=function(t,e){const r=n.get(t);t.version>0&&r.__version!==t.version?Q(r,t,e):(i.activeTexture(33984+e),i.bindTexture(32879,r.__webglTexture))},this.setTextureCube=function(e,r){const a=n.get(e);e.version>0&&a.__version!==e.version?function(e,n,r){if(6!==n.image.length)return;const a=$(e,n),l=n.source;if(i.activeTexture(33984+r),i.bindTexture(34067,e.__webglTexture),l.version!==l.__currentVersion||!0===a){t.pixelStorei(37440,n.flipY),t.pixelStorei(37441,n.premultiplyAlpha),t.pixelStorei(3317,n.unpackAlignment),t.pixelStorei(37443,0);const e=n.isCompressedTexture||n.image[0].isCompressedTexture,r=n.image[0]&&n.image[0].isDataTexture,c=[];for(let t=0;t<6;t++)c[t]=e||r?r?n.image[t].image:n.image[t]:F(n.image[t],!1,!0,E),c[t]=st(n,c[t]);const h=c[0],u=B(h)||o,d=s.convert(n.format,n.encoding),p=s.convert(n.type),f=G(n.internalFormat,d,p,n.encoding),m=o&&!0!==n.isVideoTexture,g=void 0===l.__currentVersion||!0===a;let v,x=V(n,h,u);if(K(34067,n,u),e){m&&g&&i.texStorage2D(34067,x,f,h.width,h.height);for(let t=0;t<6;t++){v=c[t].mipmaps;for(let e=0;e0&&x++,i.texStorage2D(34067,x,f,c[0].width,c[0].height));for(let t=0;t<6;t++)if(r){m?i.texSubImage2D(34069+t,0,0,0,c[t].width,c[t].height,d,p,c[t].data):i.texImage2D(34069+t,0,f,c[t].width,c[t].height,0,d,p,c[t].data);for(let e=0;e0&&!1===rt(e)){const n=d?l:[l];c.__webglMultisampledFramebuffer=t.createFramebuffer(),c.__webglColorRenderbuffer=[],i.bindFramebuffer(36160,c.__webglMultisampledFramebuffer);for(let i=0;i0&&!1===rt(e)){const r=e.isWebGLMultipleRenderTargets?e.texture:[e.texture],s=e.width,a=e.height;let o=16384;const l=[],c=e.stencilBuffer?33306:36096,h=n.get(e),u=!0===e.isWebGLMultipleRenderTargets;if(u)for(let e=0;eo+c?(l.inputState.pinching=!1,this.dispatchEvent({type:"pinchend",handedness:t.handedness,target:this})):!l.inputState.pinching&&a<=o-c&&(l.inputState.pinching=!0,this.dispatchEvent({type:"pinchstart",handedness:t.handedness,target:this}))}else null!==o&&t.gripSpace&&(r=e.getPose(t.gripSpace,i),null!==r&&(o.matrix.fromArray(r.transform.matrix),o.matrix.decompose(o.position,o.rotation,o.scale),r.linearVelocity?(o.hasLinearVelocity=!0,o.linearVelocity.copy(r.linearVelocity)):o.hasLinearVelocity=!1,r.angularVelocity?(o.hasAngularVelocity=!0,o.angularVelocity.copy(r.angularVelocity)):o.hasAngularVelocity=!1));null!==a&&(n=e.getPose(t.targetRaySpace,i),null===n&&null!==r&&(n=r),null!==n&&(a.matrix.fromArray(n.transform.matrix),a.matrix.decompose(a.position,a.rotation,a.scale),n.linearVelocity?(a.hasLinearVelocity=!0,a.linearVelocity.copy(n.linearVelocity)):a.hasLinearVelocity=!1,n.angularVelocity?(a.hasAngularVelocity=!0,a.angularVelocity.copy(n.angularVelocity)):a.hasAngularVelocity=!1,this.dispatchEvent(Ws)))}return null!==a&&(a.visible=null!==n),null!==o&&(o.visible=null!==r),null!==l&&(l.visible=null!==s),this}}class qs extends Zt{constructor(t,e,i,n,r,s,a,o,l,c){if((c=void 0!==c?c:T)!==T&&c!==A)throw new Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat");void 0===i&&c===T&&(i=y),void 0===i&&c===A&&(i=w),super(null,n,r,s,a,o,c,i,l),this.isDepthTexture=!0,this.image={width:t,height:e},this.magFilter=void 0!==a?a:d,this.minFilter=void 0!==o?o:d,this.flipY=!1,this.generateMipmaps=!1}}class Xs extends ft{constructor(t,e){super();const i=this;let n=null,r=1,s=null,a="local-floor",o=null,l=null,c=null,h=null,u=null,d=null;const p=e.getContextAttributes();let f=null,m=null;const g=[],v=[],_=new rn;_.layers.enable(1),_.viewport=new Jt;const M=new rn;M.layers.enable(2),M.viewport=new Jt;const b=[_,M],E=new Vs;E.layers.enable(1),E.layers.enable(2);let C=null,L=null;function R(t){const e=v.indexOf(t.inputSource);if(-1===e)return;const i=g[e];void 0!==i&&i.dispatchEvent({type:t.type,data:t.inputSource})}function P(){n.removeEventListener("select",R),n.removeEventListener("selectstart",R),n.removeEventListener("selectend",R),n.removeEventListener("squeeze",R),n.removeEventListener("squeezestart",R),n.removeEventListener("squeezeend",R),n.removeEventListener("end",P),n.removeEventListener("inputsourceschange",I);for(let t=0;t=0&&(v[n]=null,g[n].dispatchEvent({type:"disconnected",data:i}))}for(let e=0;e=v.length){v.push(i),n=t;break}if(null===v[t]){v[t]=i,n=t;break}}if(-1===n)break}const r=g[n];r&&r.dispatchEvent({type:"connected",data:i})}}this.cameraAutoUpdate=!0,this.enabled=!1,this.isPresenting=!1,this.getController=function(t){let e=g[t];return void 0===e&&(e=new js,g[t]=e),e.getTargetRaySpace()},this.getControllerGrip=function(t){let e=g[t];return void 0===e&&(e=new js,g[t]=e),e.getGripSpace()},this.getHand=function(t){let e=g[t];return void 0===e&&(e=new js,g[t]=e),e.getHandSpace()},this.setFramebufferScaleFactor=function(t){r=t,!0===i.isPresenting&&console.warn("THREE.WebXRManager: Cannot change framebuffer scale while presenting.")},this.setReferenceSpaceType=function(t){a=t,!0===i.isPresenting&&console.warn("THREE.WebXRManager: Cannot change reference space type while presenting.")},this.getReferenceSpace=function(){return o||s},this.setReferenceSpace=function(t){o=t},this.getBaseLayer=function(){return null!==h?h:u},this.getBinding=function(){return c},this.getFrame=function(){return d},this.getSession=function(){return n},this.setSession=async function(l){if(n=l,null!==n){if(f=t.getRenderTarget(),n.addEventListener("select",R),n.addEventListener("selectstart",R),n.addEventListener("selectend",R),n.addEventListener("squeeze",R),n.addEventListener("squeezestart",R),n.addEventListener("squeezeend",R),n.addEventListener("end",P),n.addEventListener("inputsourceschange",I),!0!==p.xrCompatible&&await e.makeXRCompatible(),void 0===n.renderState.layers||!1===t.capabilities.isWebGL2){const i={antialias:void 0!==n.renderState.layers||p.antialias,alpha:p.alpha,depth:p.depth,stencil:p.stencil,framebufferScaleFactor:r};u=new XRWebGLLayer(n,e,i),n.updateRenderState({baseLayer:u}),m=new Kt(u.framebufferWidth,u.framebufferHeight,{format:S,type:x,encoding:t.outputEncoding})}else{let i=null,s=null,a=null;p.depth&&(a=p.stencil?35056:33190,i=p.stencil?A:T,s=p.stencil?w:y);const o={colorFormat:32856,depthFormat:a,scaleFactor:r};c=new XRWebGLBinding(n,e),h=c.createProjectionLayer(o),n.updateRenderState({layers:[h]}),m=new Kt(h.textureWidth,h.textureHeight,{format:S,type:x,depthTexture:new qs(h.textureWidth,h.textureHeight,s,void 0,void 0,void 0,void 0,void 0,void 0,i),stencilBuffer:p.stencil,encoding:t.outputEncoding,samples:p.antialias?4:0});t.properties.get(m).__ignoreDepthValues=h.ignoreDepthValues}m.isXRRenderTarget=!0,this.setFoveation(1),o=null,s=await n.requestReferenceSpace(a),F.setContext(n),F.start(),i.isPresenting=!0,i.dispatchEvent({type:"sessionstart"})}};const D=new ee,N=new ee;function O(t,e){null===e?t.matrixWorld.copy(t.matrix):t.matrixWorld.multiplyMatrices(e.matrixWorld,t.matrix),t.matrixWorldInverse.copy(t.matrixWorld).invert()}this.updateCamera=function(t){if(null===n)return;E.near=M.near=_.near=t.near,E.far=M.far=_.far=t.far,C===E.near&&L===E.far||(n.updateRenderState({depthNear:E.near,depthFar:E.far}),C=E.near,L=E.far);const e=t.parent,i=E.cameras;O(E,e);for(let t=0;t0&&(i.alphaTest.value=n.alphaTest);const r=e.get(n).envMap;if(r&&(i.envMap.value=r,i.flipEnvMap.value=r.isCubeTexture&&!1===r.isRenderTargetTexture?-1:1,i.reflectivity.value=n.reflectivity,i.ior.value=n.ior,i.refractionRatio.value=n.refractionRatio),n.lightMap){i.lightMap.value=n.lightMap;const e=!0!==t.physicallyCorrectLights?Math.PI:1;i.lightMapIntensity.value=n.lightMapIntensity*e}let s,a;n.aoMap&&(i.aoMap.value=n.aoMap,i.aoMapIntensity.value=n.aoMapIntensity),n.map?s=n.map:n.specularMap?s=n.specularMap:n.displacementMap?s=n.displacementMap:n.normalMap?s=n.normalMap:n.bumpMap?s=n.bumpMap:n.roughnessMap?s=n.roughnessMap:n.metalnessMap?s=n.metalnessMap:n.alphaMap?s=n.alphaMap:n.emissiveMap?s=n.emissiveMap:n.clearcoatMap?s=n.clearcoatMap:n.clearcoatNormalMap?s=n.clearcoatNormalMap:n.clearcoatRoughnessMap?s=n.clearcoatRoughnessMap:n.iridescenceMap?s=n.iridescenceMap:n.iridescenceThicknessMap?s=n.iridescenceThicknessMap:n.specularIntensityMap?s=n.specularIntensityMap:n.specularColorMap?s=n.specularColorMap:n.transmissionMap?s=n.transmissionMap:n.thicknessMap?s=n.thicknessMap:n.sheenColorMap?s=n.sheenColorMap:n.sheenRoughnessMap&&(s=n.sheenRoughnessMap),void 0!==s&&(s.isWebGLRenderTarget&&(s=s.texture),!0===s.matrixAutoUpdate&&s.updateMatrix(),i.uvTransform.value.copy(s.matrix)),n.aoMap?a=n.aoMap:n.lightMap&&(a=n.lightMap),void 0!==a&&(a.isWebGLRenderTarget&&(a=a.texture),!0===a.matrixAutoUpdate&&a.updateMatrix(),i.uv2Transform.value.copy(a.matrix))}return{refreshFogUniforms:function(t,e){t.fogColor.value.copy(e.color),e.isFog?(t.fogNear.value=e.near,t.fogFar.value=e.far):e.isFogExp2&&(t.fogDensity.value=e.density)},refreshMaterialUniforms:function(t,n,r,s,a){n.isMeshBasicMaterial||n.isMeshLambertMaterial?i(t,n):n.isMeshToonMaterial?(i(t,n),function(t,e){e.gradientMap&&(t.gradientMap.value=e.gradientMap)}(t,n)):n.isMeshPhongMaterial?(i(t,n),function(t,e){t.specular.value.copy(e.specular),t.shininess.value=Math.max(e.shininess,1e-4)}(t,n)):n.isMeshStandardMaterial?(i(t,n),function(t,i){t.roughness.value=i.roughness,t.metalness.value=i.metalness,i.roughnessMap&&(t.roughnessMap.value=i.roughnessMap);i.metalnessMap&&(t.metalnessMap.value=i.metalnessMap);e.get(i).envMap&&(t.envMapIntensity.value=i.envMapIntensity)}(t,n),n.isMeshPhysicalMaterial&&function(t,e,i){t.ior.value=e.ior,e.sheen>0&&(t.sheenColor.value.copy(e.sheenColor).multiplyScalar(e.sheen),t.sheenRoughness.value=e.sheenRoughness,e.sheenColorMap&&(t.sheenColorMap.value=e.sheenColorMap),e.sheenRoughnessMap&&(t.sheenRoughnessMap.value=e.sheenRoughnessMap));e.clearcoat>0&&(t.clearcoat.value=e.clearcoat,t.clearcoatRoughness.value=e.clearcoatRoughness,e.clearcoatMap&&(t.clearcoatMap.value=e.clearcoatMap),e.clearcoatRoughnessMap&&(t.clearcoatRoughnessMap.value=e.clearcoatRoughnessMap),e.clearcoatNormalMap&&(t.clearcoatNormalScale.value.copy(e.clearcoatNormalScale),t.clearcoatNormalMap.value=e.clearcoatNormalMap,1===e.side&&t.clearcoatNormalScale.value.negate()));e.iridescence>0&&(t.iridescence.value=e.iridescence,t.iridescenceIOR.value=e.iridescenceIOR,t.iridescenceThicknessMinimum.value=e.iridescenceThicknessRange[0],t.iridescenceThicknessMaximum.value=e.iridescenceThicknessRange[1],e.iridescenceMap&&(t.iridescenceMap.value=e.iridescenceMap),e.iridescenceThicknessMap&&(t.iridescenceThicknessMap.value=e.iridescenceThicknessMap));e.transmission>0&&(t.transmission.value=e.transmission,t.transmissionSamplerMap.value=i.texture,t.transmissionSamplerSize.value.set(i.width,i.height),e.transmissionMap&&(t.transmissionMap.value=e.transmissionMap),t.thickness.value=e.thickness,e.thicknessMap&&(t.thicknessMap.value=e.thicknessMap),t.attenuationDistance.value=e.attenuationDistance,t.attenuationColor.value.copy(e.attenuationColor));t.specularIntensity.value=e.specularIntensity,t.specularColor.value.copy(e.specularColor),e.specularIntensityMap&&(t.specularIntensityMap.value=e.specularIntensityMap);e.specularColorMap&&(t.specularColorMap.value=e.specularColorMap)}(t,n,a)):n.isMeshMatcapMaterial?(i(t,n),function(t,e){e.matcap&&(t.matcap.value=e.matcap)}(t,n)):n.isMeshDepthMaterial?i(t,n):n.isMeshDistanceMaterial?(i(t,n),function(t,e){t.referencePosition.value.copy(e.referencePosition),t.nearDistance.value=e.nearDistance,t.farDistance.value=e.farDistance}(t,n)):n.isMeshNormalMaterial?i(t,n):n.isLineBasicMaterial?(function(t,e){t.diffuse.value.copy(e.color),t.opacity.value=e.opacity}(t,n),n.isLineDashedMaterial&&function(t,e){t.dashSize.value=e.dashSize,t.totalSize.value=e.dashSize+e.gapSize,t.scale.value=e.scale}(t,n)):n.isPointsMaterial?function(t,e,i,n){t.diffuse.value.copy(e.color),t.opacity.value=e.opacity,t.size.value=e.size*i,t.scale.value=.5*n,e.map&&(t.map.value=e.map);e.alphaMap&&(t.alphaMap.value=e.alphaMap);e.alphaTest>0&&(t.alphaTest.value=e.alphaTest);let r;e.map?r=e.map:e.alphaMap&&(r=e.alphaMap);void 0!==r&&(!0===r.matrixAutoUpdate&&r.updateMatrix(),t.uvTransform.value.copy(r.matrix))}(t,n,r,s):n.isSpriteMaterial?function(t,e){t.diffuse.value.copy(e.color),t.opacity.value=e.opacity,t.rotation.value=e.rotation,e.map&&(t.map.value=e.map);e.alphaMap&&(t.alphaMap.value=e.alphaMap);e.alphaTest>0&&(t.alphaTest.value=e.alphaTest);let i;e.map?i=e.map:e.alphaMap&&(i=e.alphaMap);void 0!==i&&(!0===i.matrixAutoUpdate&&i.updateMatrix(),t.uvTransform.value.copy(i.matrix))}(t,n):n.isShadowMaterial?(t.color.value.copy(n.color),t.opacity.value=n.opacity):n.isShaderMaterial&&(n.uniformsNeedUpdate=!1)}}}function Zs(t,e,i,n){let r={},s={},a=[];const o=i.isWebGL2?t.getParameter(35375):0;function l(t,e,i){const n=t.value;if(void 0===i[e])return i[e]="number"==typeof n?n:n.clone(),!0;if("number"==typeof n){if(i[e]!==n)return i[e]=n,!0}else{const t=i[e];if(!1===t.equals(n))return t.copy(n),!0}return!1}function c(t){const e=t.value,i={boundary:0,storage:0};return"number"==typeof e?(i.boundary=4,i.storage=4):e.isVector2?(i.boundary=8,i.storage=8):e.isVector3||e.isColor?(i.boundary=16,i.storage=12):e.isVector4?(i.boundary=16,i.storage=16):e.isMatrix3?(i.boundary=48,i.storage=48):e.isMatrix4?(i.boundary=64,i.storage=64):e.isTexture?console.warn("THREE.WebGLRenderer: Texture samplers can not be part of an uniforms group."):console.warn("THREE.WebGLRenderer: Unsupported uniform value type.",e),i}function h(e){const i=e.target;i.removeEventListener("dispose",h);const n=a.indexOf(i.__bindingPointIndex);a.splice(n,1),t.deleteBuffer(r[i.id]),delete r[i.id],delete s[i.id]}return{bind:function(t,e){const i=e.program;n.uniformBlockBinding(t,i)},update:function(i,u){let d=r[i.id];void 0===d&&(!function(t){const e=t.uniforms;let i=0;const n=16;let r=0;for(let t=0,s=e.length;t0){r=i%n;const t=n-r;0!==r&&t-a.boundary<0&&(i+=n-r,s.__offset=i)}i+=a.storage}r=i%n,r>0&&(i+=n-r);t.__size=i,t.__cache={}}(i),d=function(e){const i=function(){for(let t=0;t0&&function(t,e,i){const n=Y.isWebGL2;null===G&&(G=new Kt(1,1,{generateMipmaps:!0,type:X.has("EXT_color_buffer_half_float")?b:x,minFilter:v,samples:n&&!0===s?4:0}));m.getDrawingBufferSize(H),n?G.setSize(H.x,H.y):G.setSize(Tt(H.x),Tt(H.y));const r=m.getRenderTarget();m.setRenderTarget(G),m.clear();const a=m.toneMapping;m.toneMapping=0,Ot(t,e,i),m.toneMapping=a,$.updateMultisampleRenderTarget(G),$.updateRenderTargetMipmap(G),m.setRenderTarget(r)}(r,e,i),n&&Z.viewport(E.copy(n)),r.length>0&&Ot(r,e,i),a.length>0&&Ot(a,e,i),o.length>0&&Ot(o,e,i),Z.buffers.depth.setTest(!0),Z.buffers.depth.setMask(!0),Z.buffers.color.setMask(!0),Z.setPolygonOffset(!1)}function Ot(t,e,i){const n=!0===e.isScene?e.overrideMaterial:null;for(let r=0,s=t.length;r0?f[f.length-1]:null,p.pop(),u=p.length>0?p[p.length-1]:null},this.getActiveCubeFace=function(){return _},this.getActiveMipmapLevel=function(){return y},this.getRenderTarget=function(){return w},this.setRenderTargetTextures=function(t,e,i){K.get(t.texture).__webglTexture=e,K.get(t.depthTexture).__webglTexture=i;const n=K.get(t);n.__hasExternalTextures=!0,n.__hasExternalTextures&&(n.__autoAllocateDepthBuffer=void 0===i,n.__autoAllocateDepthBuffer||!0===X.has("WEBGL_multisampled_render_to_texture")&&(console.warn("THREE.WebGLRenderer: Render-to-texture extension was disabled because an external texture was provided"),n.__useRenderToTexture=!1))},this.setRenderTargetFramebuffer=function(t,e){const i=K.get(t);i.__webglFramebuffer=e,i.__useDefaultFramebuffer=void 0===e},this.setRenderTarget=function(t,e=0,i=0){w=t,_=e,y=i;let n=!0;if(t){const e=K.get(t);void 0!==e.__useDefaultFramebuffer?(Z.bindFramebuffer(36160,null),n=!1):void 0===e.__webglFramebuffer?$.setupRenderTarget(t):e.__hasExternalTextures&&$.rebindTextures(t,K.get(t.texture).__webglTexture,K.get(t.depthTexture).__webglTexture)}let r=null,s=!1,a=!1;if(t){const i=t.texture;(i.isData3DTexture||i.isDataArrayTexture)&&(a=!0);const n=K.get(t).__webglFramebuffer;t.isWebGLCubeRenderTarget?(r=n[e],s=!0):r=Y.isWebGL2&&t.samples>0&&!1===$.useMultisampledRTT(t)?K.get(t).__webglMultisampledFramebuffer:n,E.copy(t.viewport),C.copy(t.scissor),L=t.scissorTest}else E.copy(O).multiplyScalar(I).floor(),C.copy(z).multiplyScalar(I).floor(),L=F;if(Z.bindFramebuffer(36160,r)&&Y.drawBuffers&&n&&Z.drawBuffers(t,r),Z.viewport(E),Z.scissor(C),Z.setScissorTest(L),s){const n=K.get(t.texture);xt.framebufferTexture2D(36160,36064,34069+e,n.__webglTexture,i)}else if(a){const n=K.get(t.texture),r=e||0;xt.framebufferTextureLayer(36160,36064,n.__webglTexture,i||0,r)}T=-1},this.readRenderTargetPixels=function(t,e,i,n,r,s,a){if(!t||!t.isWebGLRenderTarget)return void console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");let o=K.get(t).__webglFramebuffer;if(t.isWebGLCubeRenderTarget&&void 0!==a&&(o=o[a]),o){Z.bindFramebuffer(36160,o);try{const a=t.texture,o=a.format,l=a.type;if(o!==S&&mt.convert(o)!==xt.getParameter(35739))return void console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.");const c=l===b&&(X.has("EXT_color_buffer_half_float")||Y.isWebGL2&&X.has("EXT_color_buffer_float"));if(!(l===x||mt.convert(l)===xt.getParameter(35738)||l===M&&(Y.isWebGL2||X.has("OES_texture_float")||X.has("WEBGL_color_buffer_float"))||c))return void console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.");e>=0&&e<=t.width-n&&i>=0&&i<=t.height-r&&xt.readPixels(e,i,n,r,mt.convert(o),mt.convert(l),s)}finally{const t=null!==w?K.get(w).__webglFramebuffer:null;Z.bindFramebuffer(36160,t)}}},this.copyFramebufferToTexture=function(t,e,i=0){const n=Math.pow(2,-i),r=Math.floor(e.image.width*n),s=Math.floor(e.image.height*n);$.setTexture2D(e,0),xt.copyTexSubImage2D(3553,i,0,0,t.x,t.y,r,s),Z.unbindTexture()},this.copyTextureToTexture=function(t,e,i,n=0){const r=e.image.width,s=e.image.height,a=mt.convert(i.format),o=mt.convert(i.type);$.setTexture2D(i,0),xt.pixelStorei(37440,i.flipY),xt.pixelStorei(37441,i.premultiplyAlpha),xt.pixelStorei(3317,i.unpackAlignment),e.isDataTexture?xt.texSubImage2D(3553,n,t.x,t.y,r,s,a,o,e.image.data):e.isCompressedTexture?xt.compressedTexSubImage2D(3553,n,t.x,t.y,e.mipmaps[0].width,e.mipmaps[0].height,a,e.mipmaps[0].data):xt.texSubImage2D(3553,n,t.x,t.y,a,o,e.image),0===n&&i.generateMipmaps&&xt.generateMipmap(3553),Z.unbindTexture()},this.copyTextureToTexture3D=function(t,e,i,n,r=0){if(m.isWebGL1Renderer)return void console.warn("THREE.WebGLRenderer.copyTextureToTexture3D: can only be used with WebGL2.");const s=t.max.x-t.min.x+1,a=t.max.y-t.min.y+1,o=t.max.z-t.min.z+1,l=mt.convert(n.format),c=mt.convert(n.type);let h;if(n.isData3DTexture)$.setTexture3D(n,0),h=32879;else{if(!n.isDataArrayTexture)return void console.warn("THREE.WebGLRenderer.copyTextureToTexture3D: only supports THREE.DataTexture3D and THREE.DataTexture2DArray.");$.setTexture2DArray(n,0),h=35866}xt.pixelStorei(37440,n.flipY),xt.pixelStorei(37441,n.premultiplyAlpha),xt.pixelStorei(3317,n.unpackAlignment);const u=xt.getParameter(3314),d=xt.getParameter(32878),p=xt.getParameter(3316),f=xt.getParameter(3315),g=xt.getParameter(32877),v=i.isCompressedTexture?i.mipmaps[0]:i.image;xt.pixelStorei(3314,v.width),xt.pixelStorei(32878,v.height),xt.pixelStorei(3316,t.min.x),xt.pixelStorei(3315,t.min.y),xt.pixelStorei(32877,t.min.z),i.isDataTexture||i.isData3DTexture?xt.texSubImage3D(h,r,e.x,e.y,e.z,s,a,o,l,c,v.data):i.isCompressedTexture?(console.warn("THREE.WebGLRenderer.copyTextureToTexture3D: untested support for compressed srcTexture."),xt.compressedTexSubImage3D(h,r,e.x,e.y,e.z,s,a,o,l,v.data)):xt.texSubImage3D(h,r,e.x,e.y,e.z,s,a,o,l,c,v),xt.pixelStorei(3314,u),xt.pixelStorei(32878,d),xt.pixelStorei(3316,p),xt.pixelStorei(3315,f),xt.pixelStorei(32877,g),0===r&&n.generateMipmaps&&xt.generateMipmap(h),Z.unbindTexture()},this.initTexture=function(t){t.isCubeTexture?$.setTextureCube(t,0):t.isData3DTexture?$.setTexture3D(t,0):t.isDataArrayTexture?$.setTexture2DArray(t,0):$.setTexture2D(t,0),Z.unbindTexture()},this.resetState=function(){_=0,y=0,w=null,Z.reset(),gt.reset()},"undefined"!=typeof __THREE_DEVTOOLS__&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe",{detail:this}))}class Ks extends Js{}Ks.prototype.isWebGL1Renderer=!0;class $s{constructor(t,e=25e-5){this.isFogExp2=!0,this.name="",this.color=new Ht(t),this.density=e}clone(){return new $s(this.color,this.density)}toJSON(){return{type:"FogExp2",color:this.color.getHex(),density:this.density}}}class Qs{constructor(t,e=1,i=1e3){this.isFog=!0,this.name="",this.color=new Ht(t),this.near=e,this.far=i}clone(){return new Qs(this.color,this.near,this.far)}toJSON(){return{type:"Fog",color:this.color.getHex(),near:this.near,far:this.far}}}class ta extends ni{constructor(){super(),this.isScene=!0,this.type="Scene",this.background=null,this.environment=null,this.fog=null,this.overrideMaterial=null,this.autoUpdate=!0,"undefined"!=typeof __THREE_DEVTOOLS__&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe",{detail:this}))}copy(t,e){return super.copy(t,e),null!==t.background&&(this.background=t.background.clone()),null!==t.environment&&(this.environment=t.environment.clone()),null!==t.fog&&(this.fog=t.fog.clone()),null!==t.overrideMaterial&&(this.overrideMaterial=t.overrideMaterial.clone()),this.autoUpdate=t.autoUpdate,this.matrixAutoUpdate=t.matrixAutoUpdate,this}toJSON(t){const e=super.toJSON(t);return null!==this.fog&&(e.object.fog=this.fog.toJSON()),e}}class ea{constructor(t,e){this.isInterleavedBuffer=!0,this.array=t,this.stride=e,this.count=void 0!==t?t.length/e:0,this.usage=ut,this.updateRange={offset:0,count:-1},this.version=0,this.uuid=_t()}onUploadCallback(){}set needsUpdate(t){!0===t&&this.version++}setUsage(t){return this.usage=t,this}copy(t){return this.array=new t.array.constructor(t.array),this.count=t.count,this.stride=t.stride,this.usage=t.usage,this}copyAt(t,e,i){t*=this.stride,i*=e.stride;for(let n=0,r=this.stride;nt.far||e.push({distance:o,point:aa.clone(),uv:fi.getUV(aa,da,pa,fa,ma,ga,va,new Et),face:null,object:this})}copy(t,e){return super.copy(t,e),void 0!==t.center&&this.center.copy(t.center),this.material=t.material,this}}function _a(t,e,i,n,r,s){ca.subVectors(t,i).addScalar(.5).multiply(n),void 0!==r?(ha.x=s*ca.x-r*ca.y,ha.y=r*ca.x+s*ca.y):ha.copy(ca),t.copy(e),t.x+=ha.x,t.y+=ha.y,t.applyMatrix4(ua)}const ya=new ee,Ma=new ee;class ba extends ni{constructor(){super(),this._currentLevel=0,this.type="LOD",Object.defineProperties(this,{levels:{enumerable:!0,value:[]},isLOD:{value:!0}}),this.autoUpdate=!0}copy(t){super.copy(t,!1);const e=t.levels;for(let t=0,i=e.length;t0){let i,n;for(i=1,n=e.length;i0){ya.setFromMatrixPosition(this.matrixWorld);const i=t.ray.origin.distanceTo(ya);this.getObjectForDistance(i).raycast(t,e)}}update(t){const e=this.levels;if(e.length>1){ya.setFromMatrixPosition(t.matrixWorld),Ma.setFromMatrixPosition(this.matrixWorld);const i=ya.distanceTo(Ma)/t.zoom;let n,r;for(e[0].object.visible=!0,n=1,r=e.length;n=e[n].distance;n++)e[n-1].object.visible=!1,e[n].object.visible=!0;for(this._currentLevel=n-1;no)continue;u.applyMatrix4(this.matrixWorld);const s=t.ray.origin.distanceTo(u);st.far||e.push({distance:s,point:h.clone().applyMatrix4(this.matrixWorld),index:i,face:null,faceIndex:null,object:this})}}else{for(let i=Math.max(0,s.start),n=Math.min(f.count,s.start+s.count)-1;io)continue;u.applyMatrix4(this.matrixWorld);const n=t.ray.origin.distanceTo(u);nt.far||e.push({distance:n,point:h.clone().applyMatrix4(this.matrixWorld),index:i,face:null,faceIndex:null,object:this})}}}updateMorphTargets(){const t=this.geometry.morphAttributes,e=Object.keys(t);if(e.length>0){const i=t[e[0]];if(void 0!==i){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let t=0,e=i.length;t0){const i=t[e[0]];if(void 0!==i){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let t=0,e=i.length;tr.far)return;s.push({distance:l,distanceToRay:Math.sqrt(o),point:i,index:e,face:null,object:a})}}class ro extends Zt{constructor(t,e,i,n,r,s,a,o,l,c,h,u){super(null,s,a,o,l,c,n,r,h,u),this.isCompressedTexture=!0,this.image={width:e,height:i},this.mipmaps=t,this.flipY=!1,this.generateMipmaps=!1}}class so{constructor(){this.type="Curve",this.arcLengthDivisions=200}getPoint(){return console.warn("THREE.Curve: .getPoint() not implemented."),null}getPointAt(t,e){const i=this.getUtoTmapping(t);return this.getPoint(i,e)}getPoints(t=5){const e=[];for(let i=0;i<=t;i++)e.push(this.getPoint(i/t));return e}getSpacedPoints(t=5){const e=[];for(let i=0;i<=t;i++)e.push(this.getPointAt(i/t));return e}getLength(){const t=this.getLengths();return t[t.length-1]}getLengths(t=this.arcLengthDivisions){if(this.cacheArcLengths&&this.cacheArcLengths.length===t+1&&!this.needsUpdate)return this.cacheArcLengths;this.needsUpdate=!1;const e=[];let i,n=this.getPoint(0),r=0;e.push(0);for(let s=1;s<=t;s++)i=this.getPoint(s/t),r+=i.distanceTo(n),e.push(r),n=i;return this.cacheArcLengths=e,e}updateArcLengths(){this.needsUpdate=!0,this.getLengths()}getUtoTmapping(t,e){const i=this.getLengths();let n=0;const r=i.length;let s;s=e||t*i[r-1];let a,o=0,l=r-1;for(;o<=l;)if(n=Math.floor(o+(l-o)/2),a=i[n]-s,a<0)o=n+1;else{if(!(a>0)){l=n;break}l=n-1}if(n=l,i[n]===s)return n/(r-1);const c=i[n];return(n+(s-c)/(i[n+1]-c))/(r-1)}getTangent(t,e){const i=1e-4;let n=t-i,r=t+i;n<0&&(n=0),r>1&&(r=1);const s=this.getPoint(n),a=this.getPoint(r),o=e||(s.isVector2?new Et:new ee);return o.copy(a).sub(s).normalize(),o}getTangentAt(t,e){const i=this.getUtoTmapping(t);return this.getTangent(i,e)}computeFrenetFrames(t,e){const i=new ee,n=[],r=[],s=[],a=new ee,o=new Ie;for(let e=0;e<=t;e++){const i=e/t;n[e]=this.getTangentAt(i,new ee)}r[0]=new ee,s[0]=new ee;let l=Number.MAX_VALUE;const c=Math.abs(n[0].x),h=Math.abs(n[0].y),u=Math.abs(n[0].z);c<=l&&(l=c,i.set(1,0,0)),h<=l&&(l=h,i.set(0,1,0)),u<=l&&i.set(0,0,1),a.crossVectors(n[0],i).normalize(),r[0].crossVectors(n[0],a),s[0].crossVectors(n[0],r[0]);for(let e=1;e<=t;e++){if(r[e]=r[e-1].clone(),s[e]=s[e-1].clone(),a.crossVectors(n[e-1],n[e]),a.length()>Number.EPSILON){a.normalize();const t=Math.acos(yt(n[e-1].dot(n[e]),-1,1));r[e].applyMatrix4(o.makeRotationAxis(a,t))}s[e].crossVectors(n[e],r[e])}if(!0===e){let e=Math.acos(yt(r[0].dot(r[t]),-1,1));e/=t,n[0].dot(a.crossVectors(r[0],r[t]))>0&&(e=-e);for(let i=1;i<=t;i++)r[i].applyMatrix4(o.makeRotationAxis(n[i],e*i)),s[i].crossVectors(n[i],r[i])}return{tangents:n,normals:r,binormals:s}}clone(){return(new this.constructor).copy(this)}copy(t){return this.arcLengthDivisions=t.arcLengthDivisions,this}toJSON(){const t={metadata:{version:4.5,type:"Curve",generator:"Curve.toJSON"}};return t.arcLengthDivisions=this.arcLengthDivisions,t.type=this.type,t}fromJSON(t){return this.arcLengthDivisions=t.arcLengthDivisions,this}}class ao extends so{constructor(t=0,e=0,i=1,n=1,r=0,s=2*Math.PI,a=!1,o=0){super(),this.isEllipseCurve=!0,this.type="EllipseCurve",this.aX=t,this.aY=e,this.xRadius=i,this.yRadius=n,this.aStartAngle=r,this.aEndAngle=s,this.aClockwise=a,this.aRotation=o}getPoint(t,e){const i=e||new Et,n=2*Math.PI;let r=this.aEndAngle-this.aStartAngle;const s=Math.abs(r)n;)r-=n;r0?0:(Math.floor(Math.abs(l)/r)+1)*r:0===c&&l===r-1&&(l=r-2,c=1),this.closed||l>0?a=n[(l-1)%r]:(co.subVectors(n[0],n[1]).add(n[0]),a=co);const h=n[l%r],u=n[(l+1)%r];if(this.closed||l+2n.length-2?n.length-1:s+1],h=n[s>n.length-3?n.length-1:s+2];return i.set(mo(a,o.x,l.x,c.x,h.x),mo(a,o.y,l.y,c.y,h.y)),i}copy(t){super.copy(t),this.points=[];for(let e=0,i=t.points.length;e=i){const t=n[r]-i,s=this.curves[r],a=s.getLength(),o=0===a?0:1-t/a;return s.getPointAt(o,e)}r++}return null}getLength(){const t=this.getCurveLengths();return t[t.length-1]}updateArcLengths(){this.needsUpdate=!0,this.cacheLengths=null,this.getCurveLengths()}getCurveLengths(){if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths;const t=[];let e=0;for(let i=0,n=this.curves.length;i1&&!e[e.length-1].equals(e[0])&&e.push(e[0]),e}copy(t){super.copy(t),this.curves=[];for(let e=0,i=t.curves.length;e0){const t=l.getPoint(0);t.equals(this.currentPoint)||this.lineTo(t.x,t.y)}this.curves.push(l);const c=l.getPoint(1);return this.currentPoint.copy(c),this}copy(t){return super.copy(t),this.currentPoint.copy(t.currentPoint),this}toJSON(){const t=super.toJSON();return t.currentPoint=this.currentPoint.toArray(),t}fromJSON(t){return super.fromJSON(t),this.currentPoint.fromArray(t.currentPoint),this}}class Co extends Pi{constructor(t=[new Et(0,-.5),new Et(.5,0),new Et(0,.5)],e=12,i=0,n=2*Math.PI){super(),this.type="LatheGeometry",this.parameters={points:t,segments:e,phiStart:i,phiLength:n},e=Math.floor(e),n=yt(n,0,2*Math.PI);const r=[],s=[],a=[],o=[],l=[],c=1/e,h=new ee,u=new Et,d=new ee,p=new ee,f=new ee;let m=0,g=0;for(let e=0;e<=t.length-1;e++)switch(e){case 0:m=t[e+1].x-t[e].x,g=t[e+1].y-t[e].y,d.x=1*g,d.y=-m,d.z=0*g,f.copy(d),d.normalize(),o.push(d.x,d.y,d.z);break;case t.length-1:o.push(f.x,f.y,f.z);break;default:m=t[e+1].x-t[e].x,g=t[e+1].y-t[e].y,d.x=1*g,d.y=-m,d.z=0*g,p.copy(d),d.x+=f.x,d.y+=f.y,d.z+=f.z,d.normalize(),o.push(d.x,d.y,d.z),f.copy(p)}for(let r=0;r<=e;r++){const d=i+r*c*n,p=Math.sin(d),f=Math.cos(d);for(let i=0;i<=t.length-1;i++){h.x=t[i].x*p,h.y=t[i].y,h.z=t[i].x*f,s.push(h.x,h.y,h.z),u.x=r/e,u.y=i/(t.length-1),a.push(u.x,u.y);const n=o[3*i+0]*p,c=o[3*i+1],d=o[3*i+0]*f;l.push(n,c,d)}}for(let i=0;i0&&v(!0),e>0&&v(!1)),this.setIndex(c),this.setAttribute("position",new wi(h,3)),this.setAttribute("normal",new wi(u,3)),this.setAttribute("uv",new wi(d,2))}static fromJSON(t){return new Po(t.radiusTop,t.radiusBottom,t.height,t.radialSegments,t.heightSegments,t.openEnded,t.thetaStart,t.thetaLength)}}class Io extends Po{constructor(t=1,e=1,i=8,n=1,r=!1,s=0,a=2*Math.PI){super(0,t,e,i,n,r,s,a),this.type="ConeGeometry",this.parameters={radius:t,height:e,radialSegments:i,heightSegments:n,openEnded:r,thetaStart:s,thetaLength:a}}static fromJSON(t){return new Io(t.radius,t.height,t.radialSegments,t.heightSegments,t.openEnded,t.thetaStart,t.thetaLength)}}class Do extends Pi{constructor(t=[],e=[],i=1,n=0){super(),this.type="PolyhedronGeometry",this.parameters={vertices:t,indices:e,radius:i,detail:n};const r=[],s=[];function a(t,e,i,n){const r=n+1,s=[];for(let n=0;n<=r;n++){s[n]=[];const a=t.clone().lerp(i,n/r),o=e.clone().lerp(i,n/r),l=r-n;for(let t=0;t<=l;t++)s[n][t]=0===t&&n===r?a:a.clone().lerp(o,t/l)}for(let t=0;t.9&&a<.1&&(e<.2&&(s[t+0]+=1),i<.2&&(s[t+2]+=1),n<.2&&(s[t+4]+=1))}}()}(),this.setAttribute("position",new wi(r,3)),this.setAttribute("normal",new wi(r.slice(),3)),this.setAttribute("uv",new wi(s,2)),0===n?this.computeVertexNormals():this.normalizeNormals()}static fromJSON(t){return new Do(t.vertices,t.indices,t.radius,t.details)}}class No extends Do{constructor(t=1,e=0){const i=(1+Math.sqrt(5))/2,n=1/i;super([-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,-n,-i,0,-n,i,0,n,-i,0,n,i,-n,-i,0,-n,i,0,n,-i,0,n,i,0,-i,0,-n,i,0,-n,-i,0,n,i,0,n],[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],t,e),this.type="DodecahedronGeometry",this.parameters={radius:t,detail:e}}static fromJSON(t){return new No(t.radius,t.detail)}}const Oo=new ee,zo=new ee,Fo=new ee,Bo=new fi;class Uo extends Pi{constructor(t=null,e=1){if(super(),this.type="EdgesGeometry",this.parameters={geometry:t,thresholdAngle:e},null!==t){const i=4,n=Math.pow(10,i),r=Math.cos(vt*e),s=t.getIndex(),a=t.getAttribute("position"),o=s?s.count:a.count,l=[0,0,0],c=["a","b","c"],h=new Array(3),u={},d=[];for(let t=0;t80*i){o=c=t[0],l=h=t[1];for(let e=i;ec&&(c=u),d>h&&(h=d);p=Math.max(c-o,h-l),p=0!==p?1/p:0}return Wo(s,a,i,o,l,p),a};function Vo(t,e,i,n,r){let s,a;if(r===function(t,e,i,n){let r=0;for(let s=e,a=i-n;s0)for(s=e;s=e;s-=n)a=cl(s,t[s],t[s+1],a);return a&&nl(a,a.next)&&(hl(a),a=a.next),a}function Ho(t,e){if(!t)return t;e||(e=t);let i,n=t;do{if(i=!1,n.steiner||!nl(n,n.next)&&0!==il(n.prev,n,n.next))n=n.next;else{if(hl(n),n=e=n.prev,n===n.next)break;i=!0}}while(i||n!==e);return e}function Wo(t,e,i,n,r,s,a){if(!t)return;!a&&s&&function(t,e,i,n){let r=t;do{null===r.z&&(r.z=$o(r.x,r.y,e,i,n)),r.prevZ=r.prev,r.nextZ=r.next,r=r.next}while(r!==t);r.prevZ.nextZ=null,r.prevZ=null,function(t){let e,i,n,r,s,a,o,l,c=1;do{for(i=t,t=null,s=null,a=0;i;){for(a++,n=i,o=0,e=0;e0||l>0&&n;)0!==o&&(0===l||!n||i.z<=n.z)?(r=i,i=i.nextZ,o--):(r=n,n=n.nextZ,l--),s?s.nextZ=r:t=r,r.prevZ=s,s=r;i=n}s.nextZ=null,c*=2}while(a>1)}(r)}(t,n,r,s);let o,l,c=t;for(;t.prev!==t.next;)if(o=t.prev,l=t.next,s?qo(t,n,r,s):jo(t))e.push(o.i/i),e.push(t.i/i),e.push(l.i/i),hl(t),t=l.next,c=l.next;else if((t=l)===c){a?1===a?Wo(t=Xo(Ho(t),e,i),e,i,n,r,s,2):2===a&&Yo(t,e,i,n,r,s):Wo(Ho(t),e,i,n,r,s,1);break}}function jo(t){const e=t.prev,i=t,n=t.next;if(il(e,i,n)>=0)return!1;let r=t.next.next;for(;r!==t.prev;){if(tl(e.x,e.y,i.x,i.y,n.x,n.y,r.x,r.y)&&il(r.prev,r,r.next)>=0)return!1;r=r.next}return!0}function qo(t,e,i,n){const r=t.prev,s=t,a=t.next;if(il(r,s,a)>=0)return!1;const o=r.xs.x?r.x>a.x?r.x:a.x:s.x>a.x?s.x:a.x,h=r.y>s.y?r.y>a.y?r.y:a.y:s.y>a.y?s.y:a.y,u=$o(o,l,e,i,n),d=$o(c,h,e,i,n);let p=t.prevZ,f=t.nextZ;for(;p&&p.z>=u&&f&&f.z<=d;){if(p!==t.prev&&p!==t.next&&tl(r.x,r.y,s.x,s.y,a.x,a.y,p.x,p.y)&&il(p.prev,p,p.next)>=0)return!1;if(p=p.prevZ,f!==t.prev&&f!==t.next&&tl(r.x,r.y,s.x,s.y,a.x,a.y,f.x,f.y)&&il(f.prev,f,f.next)>=0)return!1;f=f.nextZ}for(;p&&p.z>=u;){if(p!==t.prev&&p!==t.next&&tl(r.x,r.y,s.x,s.y,a.x,a.y,p.x,p.y)&&il(p.prev,p,p.next)>=0)return!1;p=p.prevZ}for(;f&&f.z<=d;){if(f!==t.prev&&f!==t.next&&tl(r.x,r.y,s.x,s.y,a.x,a.y,f.x,f.y)&&il(f.prev,f,f.next)>=0)return!1;f=f.nextZ}return!0}function Xo(t,e,i){let n=t;do{const r=n.prev,s=n.next.next;!nl(r,s)&&rl(r,n,n.next,s)&&ol(r,s)&&ol(s,r)&&(e.push(r.i/i),e.push(n.i/i),e.push(s.i/i),hl(n),hl(n.next),n=t=s),n=n.next}while(n!==t);return Ho(n)}function Yo(t,e,i,n,r,s){let a=t;do{let t=a.next.next;for(;t!==a.prev;){if(a.i!==t.i&&el(a,t)){let o=ll(a,t);return a=Ho(a,a.next),o=Ho(o,o.next),Wo(a,e,i,n,r,s),void Wo(o,e,i,n,r,s)}t=t.next}a=a.next}while(a!==t)}function Zo(t,e){return t.x-e.x}function Jo(t,e){if(e=function(t,e){let i=e;const n=t.x,r=t.y;let s,a=-1/0;do{if(r<=i.y&&r>=i.next.y&&i.next.y!==i.y){const t=i.x+(r-i.y)*(i.next.x-i.x)/(i.next.y-i.y);if(t<=n&&t>a){if(a=t,t===n){if(r===i.y)return i;if(r===i.next.y)return i.next}s=i.x=i.x&&i.x>=l&&n!==i.x&&tl(rs.x||i.x===s.x&&Ko(s,i)))&&(s=i,u=h)),i=i.next}while(i!==o);return s}(t,e),e){const i=ll(e,t);Ho(e,e.next),Ho(i,i.next)}}function Ko(t,e){return il(t.prev,t,e.prev)<0&&il(e.next,t,t.next)<0}function $o(t,e,i,n,r){return(t=1431655765&((t=858993459&((t=252645135&((t=16711935&((t=32767*(t-i)*r)|t<<8))|t<<4))|t<<2))|t<<1))|(e=1431655765&((e=858993459&((e=252645135&((e=16711935&((e=32767*(e-n)*r)|e<<8))|e<<4))|e<<2))|e<<1))<<1}function Qo(t){let e=t,i=t;do{(e.x=0&&(t-a)*(n-o)-(i-a)*(e-o)>=0&&(i-a)*(s-o)-(r-a)*(n-o)>=0}function el(t,e){return t.next.i!==e.i&&t.prev.i!==e.i&&!function(t,e){let i=t;do{if(i.i!==t.i&&i.next.i!==t.i&&i.i!==e.i&&i.next.i!==e.i&&rl(i,i.next,t,e))return!0;i=i.next}while(i!==t);return!1}(t,e)&&(ol(t,e)&&ol(e,t)&&function(t,e){let i=t,n=!1;const r=(t.x+e.x)/2,s=(t.y+e.y)/2;do{i.y>s!=i.next.y>s&&i.next.y!==i.y&&r<(i.next.x-i.x)*(s-i.y)/(i.next.y-i.y)+i.x&&(n=!n),i=i.next}while(i!==t);return n}(t,e)&&(il(t.prev,t,e.prev)||il(t,e.prev,e))||nl(t,e)&&il(t.prev,t,t.next)>0&&il(e.prev,e,e.next)>0)}function il(t,e,i){return(e.y-t.y)*(i.x-e.x)-(e.x-t.x)*(i.y-e.y)}function nl(t,e){return t.x===e.x&&t.y===e.y}function rl(t,e,i,n){const r=al(il(t,e,i)),s=al(il(t,e,n)),a=al(il(i,n,t)),o=al(il(i,n,e));return r!==s&&a!==o||(!(0!==r||!sl(t,i,e))||(!(0!==s||!sl(t,n,e))||(!(0!==a||!sl(i,t,n))||!(0!==o||!sl(i,e,n)))))}function sl(t,e,i){return e.x<=Math.max(t.x,i.x)&&e.x>=Math.min(t.x,i.x)&&e.y<=Math.max(t.y,i.y)&&e.y>=Math.min(t.y,i.y)}function al(t){return t>0?1:t<0?-1:0}function ol(t,e){return il(t.prev,t,t.next)<0?il(t,e,t.next)>=0&&il(t,t.prev,e)>=0:il(t,e,t.prev)<0||il(t,t.next,e)<0}function ll(t,e){const i=new ul(t.i,t.x,t.y),n=new ul(e.i,e.x,e.y),r=t.next,s=e.prev;return t.next=e,e.prev=t,i.next=r,r.prev=i,n.next=i,i.prev=n,s.next=n,n.prev=s,n}function cl(t,e,i,n){const r=new ul(t,e,i);return n?(r.next=n.next,r.prev=n,n.next.prev=r,n.next=r):(r.prev=r,r.next=r),r}function hl(t){t.next.prev=t.prev,t.prev.next=t.next,t.prevZ&&(t.prevZ.nextZ=t.nextZ),t.nextZ&&(t.nextZ.prevZ=t.prevZ)}function ul(t,e,i){this.i=t,this.x=e,this.y=i,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}class dl{static area(t){const e=t.length;let i=0;for(let n=e-1,r=0;r2&&t[e-1].equals(t[0])&&t.pop()}function fl(t,e){for(let i=0;iNumber.EPSILON){const u=Math.sqrt(h),d=Math.sqrt(l*l+c*c),p=e.x-o/u,f=e.y+a/u,m=((i.x-c/d-p)*c-(i.y+l/d-f)*l)/(a*c-o*l);n=p+a*m-t.x,r=f+o*m-t.y;const g=n*n+r*r;if(g<=2)return new Et(n,r);s=Math.sqrt(g/2)}else{let t=!1;a>Number.EPSILON?l>Number.EPSILON&&(t=!0):a<-Number.EPSILON?l<-Number.EPSILON&&(t=!0):Math.sign(o)===Math.sign(c)&&(t=!0),t?(n=-o,r=a,s=Math.sqrt(h)):(n=a,r=o,s=Math.sqrt(h/2))}return new Et(n/s,r/s)}const P=[];for(let t=0,e=A.length,i=e-1,n=t+1;t=0;t--){const e=t/p,i=h*Math.cos(e*Math.PI/2),n=u*Math.sin(e*Math.PI/2)+d;for(let t=0,e=A.length;t=0;){const n=i;let r=i-1;r<0&&(r=t.length-1);for(let t=0,i=o+2*p;t0)&&d.push(e,r,l),(t!==i-1||o0!=t>0&&this.version++,this._sheen=t}get clearcoat(){return this._clearcoat}set clearcoat(t){this._clearcoat>0!=t>0&&this.version++,this._clearcoat=t}get iridescence(){return this._iridescence}set iridescence(t){this._iridescence>0!=t>0&&this.version++,this._iridescence=t}get transmission(){return this._transmission}set transmission(t){this._transmission>0!=t>0&&this.version++,this._transmission=t}copy(t){return super.copy(t),this.defines={STANDARD:"",PHYSICAL:""},this.clearcoat=t.clearcoat,this.clearcoatMap=t.clearcoatMap,this.clearcoatRoughness=t.clearcoatRoughness,this.clearcoatRoughnessMap=t.clearcoatRoughnessMap,this.clearcoatNormalMap=t.clearcoatNormalMap,this.clearcoatNormalScale.copy(t.clearcoatNormalScale),this.ior=t.ior,this.iridescence=t.iridescence,this.iridescenceMap=t.iridescenceMap,this.iridescenceIOR=t.iridescenceIOR,this.iridescenceThicknessRange=[...t.iridescenceThicknessRange],this.iridescenceThicknessMap=t.iridescenceThicknessMap,this.sheen=t.sheen,this.sheenColor.copy(t.sheenColor),this.sheenColorMap=t.sheenColorMap,this.sheenRoughness=t.sheenRoughness,this.sheenRoughnessMap=t.sheenRoughnessMap,this.transmission=t.transmission,this.transmissionMap=t.transmissionMap,this.thickness=t.thickness,this.thicknessMap=t.thicknessMap,this.attenuationDistance=t.attenuationDistance,this.attenuationColor.copy(t.attenuationColor),this.specularIntensity=t.specularIntensity,this.specularIntensityMap=t.specularIntensityMap,this.specularColor.copy(t.specularColor),this.specularColorMap=t.specularColorMap,this}}class Dl extends gi{constructor(t){super(),this.isMeshPhongMaterial=!0,this.type="MeshPhongMaterial",this.color=new Ht(16777215),this.specular=new Ht(1118481),this.shininess=30,this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new Ht(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Et(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.combine=0,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.flatShading=!1,this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.specular.copy(t.specular),this.shininess=t.shininess,this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.emissive.copy(t.emissive),this.emissiveMap=t.emissiveMap,this.emissiveIntensity=t.emissiveIntensity,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.specularMap=t.specularMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.combine=t.combine,this.reflectivity=t.reflectivity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.flatShading=t.flatShading,this.fog=t.fog,this}}class Nl extends gi{constructor(t){super(),this.isMeshToonMaterial=!0,this.defines={TOON:""},this.type="MeshToonMaterial",this.color=new Ht(16777215),this.map=null,this.gradientMap=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new Ht(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Et(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.alphaMap=null,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.map=t.map,this.gradientMap=t.gradientMap,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.emissive.copy(t.emissive),this.emissiveMap=t.emissiveMap,this.emissiveIntensity=t.emissiveIntensity,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.alphaMap=t.alphaMap,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.fog=t.fog,this}}class Ol extends gi{constructor(t){super(),this.isMeshNormalMaterial=!0,this.type="MeshNormalMaterial",this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Et(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.wireframe=!1,this.wireframeLinewidth=1,this.flatShading=!1,this.setValues(t)}copy(t){return super.copy(t),this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.flatShading=t.flatShading,this}}class zl extends gi{constructor(t){super(),this.isMeshLambertMaterial=!0,this.type="MeshLambertMaterial",this.color=new Ht(16777215),this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new Ht(0),this.emissiveIntensity=1,this.emissiveMap=null,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.combine=0,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.emissive.copy(t.emissive),this.emissiveMap=t.emissiveMap,this.emissiveIntensity=t.emissiveIntensity,this.specularMap=t.specularMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.combine=t.combine,this.reflectivity=t.reflectivity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.fog=t.fog,this}}class Fl extends gi{constructor(t){super(),this.isMeshMatcapMaterial=!0,this.defines={MATCAP:""},this.type="MeshMatcapMaterial",this.color=new Ht(16777215),this.matcap=null,this.map=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Et(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.alphaMap=null,this.flatShading=!1,this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.defines={MATCAP:""},this.color.copy(t.color),this.matcap=t.matcap,this.map=t.map,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.alphaMap=t.alphaMap,this.flatShading=t.flatShading,this.fog=t.fog,this}}class Bl extends ka{constructor(t){super(),this.isLineDashedMaterial=!0,this.type="LineDashedMaterial",this.scale=1,this.dashSize=3,this.gapSize=1,this.setValues(t)}copy(t){return super.copy(t),this.scale=t.scale,this.dashSize=t.dashSize,this.gapSize=t.gapSize,this}}function Ul(t,e,i){return Gl(t)?new t.constructor(t.subarray(e,void 0!==i?i:t.length)):t.slice(e,i)}function kl(t,e,i){return!t||!i&&t.constructor===e?t:"number"==typeof e.BYTES_PER_ELEMENT?new e(t):Array.prototype.slice.call(t)}function Gl(t){return ArrayBuffer.isView(t)&&!(t instanceof DataView)}function Vl(t){const e=t.length,i=new Array(e);for(let t=0;t!==e;++t)i[t]=t;return i.sort((function(e,i){return t[e]-t[i]})),i}function Hl(t,e,i){const n=t.length,r=new t.constructor(n);for(let s=0,a=0;a!==n;++s){const n=i[s]*e;for(let i=0;i!==e;++i)r[a++]=t[n+i]}return r}function Wl(t,e,i,n){let r=1,s=t[0];for(;void 0!==s&&void 0===s[n];)s=t[r++];if(void 0===s)return;let a=s[n];if(void 0!==a)if(Array.isArray(a))do{a=s[n],void 0!==a&&(e.push(s.time),i.push.apply(i,a)),s=t[r++]}while(void 0!==s);else if(void 0!==a.toArray)do{a=s[n],void 0!==a&&(e.push(s.time),a.toArray(i,i.length)),s=t[r++]}while(void 0!==s);else do{a=s[n],void 0!==a&&(e.push(s.time),i.push(a)),s=t[r++]}while(void 0!==s)}var jl=Object.freeze({__proto__:null,arraySlice:Ul,convertArray:kl,isTypedArray:Gl,getKeyframeOrder:Vl,sortedArray:Hl,flattenJSON:Wl,subclip:function(t,e,i,n,r=30){const s=t.clone();s.name=e;const a=[];for(let t=0;t=n)){l.push(e.times[t]);for(let i=0;is.tracks[t].times[0]&&(o=s.tracks[t].times[0]);for(let t=0;t=n.times[u]){const t=u*l+o,e=t+l-o;d=Ul(n.values,t,e)}else{const t=n.createInterpolant(),e=o,i=l-o;t.evaluate(s),d=Ul(t.resultBuffer,e,i)}if("quaternion"===r){(new te).fromArray(d).normalize().conjugate().toArray(d)}const p=a.times.length;for(let t=0;t=r)break t;{const a=e[1];t=r)break e}s=i,i=0}}for(;i>>1;te;)--s;if(++s,0!==r||s!==n){r>=s&&(s=Math.max(s,1),r=s-1);const t=this.getValueSize();this.times=Ul(i,r,s),this.values=Ul(this.values,r*t,s*t)}return this}validate(){let t=!0;const e=this.getValueSize();e-Math.floor(e)!=0&&(console.error("THREE.KeyframeTrack: Invalid value size in track.",this),t=!1);const i=this.times,n=this.values,r=i.length;0===r&&(console.error("THREE.KeyframeTrack: Track is empty.",this),t=!1);let s=null;for(let e=0;e!==r;e++){const n=i[e];if("number"==typeof n&&isNaN(n)){console.error("THREE.KeyframeTrack: Time is not a valid number.",this,e,n),t=!1;break}if(null!==s&&s>n){console.error("THREE.KeyframeTrack: Out of order keys.",this,e,n,s),t=!1;break}s=n}if(void 0!==n&&Gl(n))for(let e=0,i=n.length;e!==i;++e){const i=n[e];if(isNaN(i)){console.error("THREE.KeyframeTrack: Value is not a valid number.",this,e,i),t=!1;break}}return t}optimize(){const t=Ul(this.times),e=Ul(this.values),i=this.getValueSize(),n=this.getInterpolation()===tt,r=t.length-1;let s=1;for(let a=1;a0){t[s]=t[r];for(let t=r*i,n=s*i,a=0;a!==i;++a)e[n+a]=e[t+a];++s}return s!==t.length?(this.times=Ul(t,0,s),this.values=Ul(e,0,s*i)):(this.times=t,this.values=e),this}clone(){const t=Ul(this.times,0),e=Ul(this.values,0),i=new(0,this.constructor)(this.name,t,e);return i.createInterpolant=this.createInterpolant,i}}Jl.prototype.TimeBufferType=Float32Array,Jl.prototype.ValueBufferType=Float32Array,Jl.prototype.DefaultInterpolation=Q;class Kl extends Jl{}Kl.prototype.ValueTypeName="bool",Kl.prototype.ValueBufferType=Array,Kl.prototype.DefaultInterpolation=$,Kl.prototype.InterpolantFactoryMethodLinear=void 0,Kl.prototype.InterpolantFactoryMethodSmooth=void 0;class $l extends Jl{}$l.prototype.ValueTypeName="color";class Ql extends Jl{}Ql.prototype.ValueTypeName="number";class tc extends ql{constructor(t,e,i,n){super(t,e,i,n)}interpolate_(t,e,i,n){const r=this.resultBuffer,s=this.sampleValues,a=this.valueSize,o=(i-e)/(n-e);let l=t*a;for(let t=l+a;l!==t;l+=4)te.slerpFlat(r,0,s,l-a,s,l,o);return r}}class ec extends Jl{InterpolantFactoryMethodLinear(t){return new tc(this.times,this.values,this.getValueSize(),t)}}ec.prototype.ValueTypeName="quaternion",ec.prototype.DefaultInterpolation=Q,ec.prototype.InterpolantFactoryMethodSmooth=void 0;class ic extends Jl{}ic.prototype.ValueTypeName="string",ic.prototype.ValueBufferType=Array,ic.prototype.DefaultInterpolation=$,ic.prototype.InterpolantFactoryMethodLinear=void 0,ic.prototype.InterpolantFactoryMethodSmooth=void 0;class nc extends Jl{}nc.prototype.ValueTypeName="vector";class rc{constructor(t,e=-1,i,n=2500){this.name=t,this.tracks=i,this.duration=e,this.blendMode=n,this.uuid=_t(),this.duration<0&&this.resetDuration()}static parse(t){const e=[],i=t.tracks,n=1/(t.fps||1);for(let t=0,r=i.length;t!==r;++t)e.push(sc(i[t]).scale(n));const r=new this(t.name,t.duration,e,t.blendMode);return r.uuid=t.uuid,r}static toJSON(t){const e=[],i=t.tracks,n={name:t.name,duration:t.duration,tracks:e,uuid:t.uuid,blendMode:t.blendMode};for(let t=0,n=i.length;t!==n;++t)e.push(Jl.toJSON(i[t]));return n}static CreateFromMorphTargetSequence(t,e,i,n){const r=e.length,s=[];for(let t=0;t1){const t=s[1];let e=n[t];e||(n[t]=e=[]),e.push(i)}}const s=[];for(const t in n)s.push(this.CreateFromMorphTargetSequence(t,n[t],e,i));return s}static parseAnimation(t,e){if(!t)return console.error("THREE.AnimationClip: No animation in JSONLoader data."),null;const i=function(t,e,i,n,r){if(0!==i.length){const s=[],a=[];Wl(i,s,a,n),0!==s.length&&r.push(new t(e,s,a))}},n=[],r=t.name||"default",s=t.fps||30,a=t.blendMode;let o=t.length||-1;const l=t.hierarchy||[];for(let t=0;t{e&&e(r),this.manager.itemEnd(t)}),0),r;if(void 0!==hc[t])return void hc[t].push({onLoad:e,onProgress:i,onError:n});hc[t]=[],hc[t].push({onLoad:e,onProgress:i,onError:n});const s=new Request(t,{headers:new Headers(this.requestHeader),credentials:this.withCredentials?"include":"same-origin"}),a=this.mimeType,o=this.responseType;fetch(s).then((e=>{if(200===e.status||0===e.status){if(0===e.status&&console.warn("THREE.FileLoader: HTTP Status 0 received."),"undefined"==typeof ReadableStream||void 0===e.body||void 0===e.body.getReader)return e;const i=hc[t],n=e.body.getReader(),r=e.headers.get("Content-Length"),s=r?parseInt(r):0,a=0!==s;let o=0;const l=new ReadableStream({start(t){!function e(){n.read().then((({done:n,value:r})=>{if(n)t.close();else{o+=r.byteLength;const n=new ProgressEvent("progress",{lengthComputable:a,loaded:o,total:s});for(let t=0,e=i.length;t{switch(o){case"arraybuffer":return t.arrayBuffer();case"blob":return t.blob();case"document":return t.text().then((t=>(new DOMParser).parseFromString(t,a)));case"json":return t.json();default:if(void 0===a)return t.text();{const e=/charset="?([^;"\s]*)"?/i.exec(a),i=e&&e[1]?e[1].toLowerCase():void 0,n=new TextDecoder(i);return t.arrayBuffer().then((t=>n.decode(t)))}}})).then((e=>{ac.add(t,e);const i=hc[t];delete hc[t];for(let t=0,n=i.length;t{const i=hc[t];if(void 0===i)throw this.manager.itemError(t),e;delete hc[t];for(let t=0,n=i.length;t{this.manager.itemEnd(t)})),this.manager.itemStart(t)}setResponseType(t){return this.responseType=t,this}setMimeType(t){return this.mimeType=t,this}}class pc extends cc{constructor(t){super(t)}load(t,e,i,n){void 0!==this.path&&(t=this.path+t),t=this.manager.resolveURL(t);const r=this,s=ac.get(t);if(void 0!==s)return r.manager.itemStart(t),setTimeout((function(){e&&e(s),r.manager.itemEnd(t)}),0),s;const a=It("img");function o(){c(),ac.add(t,this),e&&e(this),r.manager.itemEnd(t)}function l(e){c(),n&&n(e),r.manager.itemError(t),r.manager.itemEnd(t)}function c(){a.removeEventListener("load",o,!1),a.removeEventListener("error",l,!1)}return a.addEventListener("load",o,!1),a.addEventListener("error",l,!1),"data:"!==t.slice(0,5)&&void 0!==this.crossOrigin&&(a.crossOrigin=this.crossOrigin),r.manager.itemStart(t),a.src=t,a}}class fc extends ni{constructor(t,e=1){super(),this.isLight=!0,this.type="Light",this.color=new Ht(t),this.intensity=e}dispose(){}copy(t,e){return super.copy(t,e),this.color.copy(t.color),this.intensity=t.intensity,this}toJSON(t){const e=super.toJSON(t);return e.object.color=this.color.getHex(),e.object.intensity=this.intensity,void 0!==this.groundColor&&(e.object.groundColor=this.groundColor.getHex()),void 0!==this.distance&&(e.object.distance=this.distance),void 0!==this.angle&&(e.object.angle=this.angle),void 0!==this.decay&&(e.object.decay=this.decay),void 0!==this.penumbra&&(e.object.penumbra=this.penumbra),void 0!==this.shadow&&(e.object.shadow=this.shadow.toJSON()),e}}class mc extends fc{constructor(t,e,i){super(t,i),this.isHemisphereLight=!0,this.type="HemisphereLight",this.position.copy(ni.DefaultUp),this.updateMatrix(),this.groundColor=new Ht(e)}copy(t,e){return super.copy(t,e),this.groundColor.copy(t.groundColor),this}}const gc=new Ie,vc=new ee,xc=new ee;class _c{constructor(t){this.camera=t,this.bias=0,this.normalBias=0,this.radius=1,this.blurSamples=8,this.mapSize=new Et(512,512),this.map=null,this.mapPass=null,this.matrix=new Ie,this.autoUpdate=!0,this.needsUpdate=!1,this._frustum=new mn,this._frameExtents=new Et(1,1),this._viewportCount=1,this._viewports=[new Jt(0,0,1,1)]}getViewportCount(){return this._viewportCount}getFrustum(){return this._frustum}updateMatrices(t){const e=this.camera,i=this.matrix;vc.setFromMatrixPosition(t.matrixWorld),e.position.copy(vc),xc.setFromMatrixPosition(t.target.matrixWorld),e.lookAt(xc),e.updateMatrixWorld(),gc.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),this._frustum.setFromProjectionMatrix(gc),i.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1),i.multiply(e.projectionMatrix),i.multiply(e.matrixWorldInverse)}getViewport(t){return this._viewports[t]}getFrameExtents(){return this._frameExtents}dispose(){this.map&&this.map.dispose(),this.mapPass&&this.mapPass.dispose()}copy(t){return this.camera=t.camera.clone(),this.bias=t.bias,this.radius=t.radius,this.mapSize.copy(t.mapSize),this}clone(){return(new this.constructor).copy(this)}toJSON(){const t={};return 0!==this.bias&&(t.bias=this.bias),0!==this.normalBias&&(t.normalBias=this.normalBias),1!==this.radius&&(t.radius=this.radius),512===this.mapSize.x&&512===this.mapSize.y||(t.mapSize=this.mapSize.toArray()),t.camera=this.camera.toJSON(!1).object,delete t.camera.matrix,t}}class yc extends _c{constructor(){super(new rn(50,1,.5,500)),this.isSpotLightShadow=!0,this.focus=1}updateMatrices(t){const e=this.camera,i=2*xt*t.angle*this.focus,n=this.mapSize.width/this.mapSize.height,r=t.distance||e.far;i===e.fov&&n===e.aspect&&r===e.far||(e.fov=i,e.aspect=n,e.far=r,e.updateProjectionMatrix()),super.updateMatrices(t)}copy(t){return super.copy(t),this.focus=t.focus,this}}class Mc extends fc{constructor(t,e,i=0,n=Math.PI/3,r=0,s=1){super(t,e),this.isSpotLight=!0,this.type="SpotLight",this.position.copy(ni.DefaultUp),this.updateMatrix(),this.target=new ni,this.distance=i,this.angle=n,this.penumbra=r,this.decay=s,this.shadow=new yc}get power(){return this.intensity*Math.PI}set power(t){this.intensity=t/Math.PI}dispose(){this.shadow.dispose()}copy(t,e){return super.copy(t,e),this.distance=t.distance,this.angle=t.angle,this.penumbra=t.penumbra,this.decay=t.decay,this.target=t.target.clone(),this.shadow=t.shadow.clone(),this}}const bc=new Ie,wc=new ee,Sc=new ee;class Tc extends _c{constructor(){super(new rn(90,1,.5,500)),this.isPointLightShadow=!0,this._frameExtents=new Et(4,2),this._viewportCount=6,this._viewports=[new Jt(2,1,1,1),new Jt(0,1,1,1),new Jt(3,1,1,1),new Jt(1,1,1,1),new Jt(3,0,1,1),new Jt(1,0,1,1)],this._cubeDirections=[new ee(1,0,0),new ee(-1,0,0),new ee(0,0,1),new ee(0,0,-1),new ee(0,1,0),new ee(0,-1,0)],this._cubeUps=[new ee(0,1,0),new ee(0,1,0),new ee(0,1,0),new ee(0,1,0),new ee(0,0,1),new ee(0,0,-1)]}updateMatrices(t,e=0){const i=this.camera,n=this.matrix,r=t.distance||i.far;r!==i.far&&(i.far=r,i.updateProjectionMatrix()),wc.setFromMatrixPosition(t.matrixWorld),i.position.copy(wc),Sc.copy(i.position),Sc.add(this._cubeDirections[e]),i.up.copy(this._cubeUps[e]),i.lookAt(Sc),i.updateMatrixWorld(),n.makeTranslation(-wc.x,-wc.y,-wc.z),bc.multiplyMatrices(i.projectionMatrix,i.matrixWorldInverse),this._frustum.setFromProjectionMatrix(bc)}}class Ac extends fc{constructor(t,e,i=0,n=1){super(t,e),this.isPointLight=!0,this.type="PointLight",this.distance=i,this.decay=n,this.shadow=new Tc}get power(){return 4*this.intensity*Math.PI}set power(t){this.intensity=t/(4*Math.PI)}dispose(){this.shadow.dispose()}copy(t,e){return super.copy(t,e),this.distance=t.distance,this.decay=t.decay,this.shadow=t.shadow.clone(),this}}class Ec extends _c{constructor(){super(new Cn(-5,5,5,-5,.5,500)),this.isDirectionalLightShadow=!0}}class Cc extends fc{constructor(t,e){super(t,e),this.isDirectionalLight=!0,this.type="DirectionalLight",this.position.copy(ni.DefaultUp),this.updateMatrix(),this.target=new ni,this.shadow=new Ec}dispose(){this.shadow.dispose()}copy(t){return super.copy(t),this.target=t.target.clone(),this.shadow=t.shadow.clone(),this}}class Lc extends fc{constructor(t,e){super(t,e),this.isAmbientLight=!0,this.type="AmbientLight"}}class Rc extends fc{constructor(t,e,i=10,n=10){super(t,e),this.isRectAreaLight=!0,this.type="RectAreaLight",this.width=i,this.height=n}get power(){return this.intensity*this.width*this.height*Math.PI}set power(t){this.intensity=t/(this.width*this.height*Math.PI)}copy(t){return super.copy(t),this.width=t.width,this.height=t.height,this}toJSON(t){const e=super.toJSON(t);return e.object.width=this.width,e.object.height=this.height,e}}class Pc{constructor(){this.isSphericalHarmonics3=!0,this.coefficients=[];for(let t=0;t<9;t++)this.coefficients.push(new ee)}set(t){for(let e=0;e<9;e++)this.coefficients[e].copy(t[e]);return this}zero(){for(let t=0;t<9;t++)this.coefficients[t].set(0,0,0);return this}getAt(t,e){const i=t.x,n=t.y,r=t.z,s=this.coefficients;return e.copy(s[0]).multiplyScalar(.282095),e.addScaledVector(s[1],.488603*n),e.addScaledVector(s[2],.488603*r),e.addScaledVector(s[3],.488603*i),e.addScaledVector(s[4],i*n*1.092548),e.addScaledVector(s[5],n*r*1.092548),e.addScaledVector(s[6],.315392*(3*r*r-1)),e.addScaledVector(s[7],i*r*1.092548),e.addScaledVector(s[8],.546274*(i*i-n*n)),e}getIrradianceAt(t,e){const i=t.x,n=t.y,r=t.z,s=this.coefficients;return e.copy(s[0]).multiplyScalar(.886227),e.addScaledVector(s[1],1.023328*n),e.addScaledVector(s[2],1.023328*r),e.addScaledVector(s[3],1.023328*i),e.addScaledVector(s[4],.858086*i*n),e.addScaledVector(s[5],.858086*n*r),e.addScaledVector(s[6],.743125*r*r-.247708),e.addScaledVector(s[7],.858086*i*r),e.addScaledVector(s[8],.429043*(i*i-n*n)),e}add(t){for(let e=0;e<9;e++)this.coefficients[e].add(t.coefficients[e]);return this}addScaledSH(t,e){for(let i=0;i<9;i++)this.coefficients[i].addScaledVector(t.coefficients[i],e);return this}scale(t){for(let e=0;e<9;e++)this.coefficients[e].multiplyScalar(t);return this}lerp(t,e){for(let i=0;i<9;i++)this.coefficients[i].lerp(t.coefficients[i],e);return this}equals(t){for(let e=0;e<9;e++)if(!this.coefficients[e].equals(t.coefficients[e]))return!1;return!0}copy(t){return this.set(t.coefficients)}clone(){return(new this.constructor).copy(this)}fromArray(t,e=0){const i=this.coefficients;for(let n=0;n<9;n++)i[n].fromArray(t,e+3*n);return this}toArray(t=[],e=0){const i=this.coefficients;for(let n=0;n<9;n++)i[n].toArray(t,e+3*n);return t}static getBasisAt(t,e){const i=t.x,n=t.y,r=t.z;e[0]=.282095,e[1]=.488603*n,e[2]=.488603*r,e[3]=.488603*i,e[4]=1.092548*i*n,e[5]=1.092548*n*r,e[6]=.315392*(3*r*r-1),e[7]=1.092548*i*r,e[8]=.546274*(i*i-n*n)}}class Ic extends fc{constructor(t=new Pc,e=1){super(void 0,e),this.isLightProbe=!0,this.sh=t}copy(t){return super.copy(t),this.sh.copy(t.sh),this}fromJSON(t){return this.intensity=t.intensity,this.sh.fromArray(t.sh),this}toJSON(t){const e=super.toJSON(t);return e.object.sh=this.sh.toArray(),e}}class Dc extends cc{constructor(t){super(t),this.textures={}}load(t,e,i,n){const r=this,s=new dc(r.manager);s.setPath(r.path),s.setRequestHeader(r.requestHeader),s.setWithCredentials(r.withCredentials),s.load(t,(function(i){try{e(r.parse(JSON.parse(i)))}catch(e){n?n(e):console.error(e),r.manager.itemError(t)}}),i,n)}parse(t){const e=this.textures;function i(t){return void 0===e[t]&&console.warn("THREE.MaterialLoader: Undefined texture",t),e[t]}const n=Dc.createMaterialFromType(t.type);if(void 0!==t.uuid&&(n.uuid=t.uuid),void 0!==t.name&&(n.name=t.name),void 0!==t.color&&void 0!==n.color&&n.color.setHex(t.color),void 0!==t.roughness&&(n.roughness=t.roughness),void 0!==t.metalness&&(n.metalness=t.metalness),void 0!==t.sheen&&(n.sheen=t.sheen),void 0!==t.sheenColor&&(n.sheenColor=(new Ht).setHex(t.sheenColor)),void 0!==t.sheenRoughness&&(n.sheenRoughness=t.sheenRoughness),void 0!==t.emissive&&void 0!==n.emissive&&n.emissive.setHex(t.emissive),void 0!==t.specular&&void 0!==n.specular&&n.specular.setHex(t.specular),void 0!==t.specularIntensity&&(n.specularIntensity=t.specularIntensity),void 0!==t.specularColor&&void 0!==n.specularColor&&n.specularColor.setHex(t.specularColor),void 0!==t.shininess&&(n.shininess=t.shininess),void 0!==t.clearcoat&&(n.clearcoat=t.clearcoat),void 0!==t.clearcoatRoughness&&(n.clearcoatRoughness=t.clearcoatRoughness),void 0!==t.iridescence&&(n.iridescence=t.iridescence),void 0!==t.iridescenceIOR&&(n.iridescenceIOR=t.iridescenceIOR),void 0!==t.iridescenceThicknessRange&&(n.iridescenceThicknessRange=t.iridescenceThicknessRange),void 0!==t.transmission&&(n.transmission=t.transmission),void 0!==t.thickness&&(n.thickness=t.thickness),void 0!==t.attenuationDistance&&(n.attenuationDistance=t.attenuationDistance),void 0!==t.attenuationColor&&void 0!==n.attenuationColor&&n.attenuationColor.setHex(t.attenuationColor),void 0!==t.fog&&(n.fog=t.fog),void 0!==t.flatShading&&(n.flatShading=t.flatShading),void 0!==t.blending&&(n.blending=t.blending),void 0!==t.combine&&(n.combine=t.combine),void 0!==t.side&&(n.side=t.side),void 0!==t.shadowSide&&(n.shadowSide=t.shadowSide),void 0!==t.opacity&&(n.opacity=t.opacity),void 0!==t.transparent&&(n.transparent=t.transparent),void 0!==t.alphaTest&&(n.alphaTest=t.alphaTest),void 0!==t.depthTest&&(n.depthTest=t.depthTest),void 0!==t.depthWrite&&(n.depthWrite=t.depthWrite),void 0!==t.colorWrite&&(n.colorWrite=t.colorWrite),void 0!==t.stencilWrite&&(n.stencilWrite=t.stencilWrite),void 0!==t.stencilWriteMask&&(n.stencilWriteMask=t.stencilWriteMask),void 0!==t.stencilFunc&&(n.stencilFunc=t.stencilFunc),void 0!==t.stencilRef&&(n.stencilRef=t.stencilRef),void 0!==t.stencilFuncMask&&(n.stencilFuncMask=t.stencilFuncMask),void 0!==t.stencilFail&&(n.stencilFail=t.stencilFail),void 0!==t.stencilZFail&&(n.stencilZFail=t.stencilZFail),void 0!==t.stencilZPass&&(n.stencilZPass=t.stencilZPass),void 0!==t.wireframe&&(n.wireframe=t.wireframe),void 0!==t.wireframeLinewidth&&(n.wireframeLinewidth=t.wireframeLinewidth),void 0!==t.wireframeLinecap&&(n.wireframeLinecap=t.wireframeLinecap),void 0!==t.wireframeLinejoin&&(n.wireframeLinejoin=t.wireframeLinejoin),void 0!==t.rotation&&(n.rotation=t.rotation),1!==t.linewidth&&(n.linewidth=t.linewidth),void 0!==t.dashSize&&(n.dashSize=t.dashSize),void 0!==t.gapSize&&(n.gapSize=t.gapSize),void 0!==t.scale&&(n.scale=t.scale),void 0!==t.polygonOffset&&(n.polygonOffset=t.polygonOffset),void 0!==t.polygonOffsetFactor&&(n.polygonOffsetFactor=t.polygonOffsetFactor),void 0!==t.polygonOffsetUnits&&(n.polygonOffsetUnits=t.polygonOffsetUnits),void 0!==t.dithering&&(n.dithering=t.dithering),void 0!==t.alphaToCoverage&&(n.alphaToCoverage=t.alphaToCoverage),void 0!==t.premultipliedAlpha&&(n.premultipliedAlpha=t.premultipliedAlpha),void 0!==t.visible&&(n.visible=t.visible),void 0!==t.toneMapped&&(n.toneMapped=t.toneMapped),void 0!==t.userData&&(n.userData=t.userData),void 0!==t.vertexColors&&("number"==typeof t.vertexColors?n.vertexColors=t.vertexColors>0:n.vertexColors=t.vertexColors),void 0!==t.uniforms)for(const e in t.uniforms){const r=t.uniforms[e];switch(n.uniforms[e]={},r.type){case"t":n.uniforms[e].value=i(r.value);break;case"c":n.uniforms[e].value=(new Ht).setHex(r.value);break;case"v2":n.uniforms[e].value=(new Et).fromArray(r.value);break;case"v3":n.uniforms[e].value=(new ee).fromArray(r.value);break;case"v4":n.uniforms[e].value=(new Jt).fromArray(r.value);break;case"m3":n.uniforms[e].value=(new Ct).fromArray(r.value);break;case"m4":n.uniforms[e].value=(new Ie).fromArray(r.value);break;default:n.uniforms[e].value=r.value}}if(void 0!==t.defines&&(n.defines=t.defines),void 0!==t.vertexShader&&(n.vertexShader=t.vertexShader),void 0!==t.fragmentShader&&(n.fragmentShader=t.fragmentShader),void 0!==t.extensions)for(const e in t.extensions)n.extensions[e]=t.extensions[e];if(void 0!==t.shading&&(n.flatShading=1===t.shading),void 0!==t.size&&(n.size=t.size),void 0!==t.sizeAttenuation&&(n.sizeAttenuation=t.sizeAttenuation),void 0!==t.map&&(n.map=i(t.map)),void 0!==t.matcap&&(n.matcap=i(t.matcap)),void 0!==t.alphaMap&&(n.alphaMap=i(t.alphaMap)),void 0!==t.bumpMap&&(n.bumpMap=i(t.bumpMap)),void 0!==t.bumpScale&&(n.bumpScale=t.bumpScale),void 0!==t.normalMap&&(n.normalMap=i(t.normalMap)),void 0!==t.normalMapType&&(n.normalMapType=t.normalMapType),void 0!==t.normalScale){let e=t.normalScale;!1===Array.isArray(e)&&(e=[e,e]),n.normalScale=(new Et).fromArray(e)}return void 0!==t.displacementMap&&(n.displacementMap=i(t.displacementMap)),void 0!==t.displacementScale&&(n.displacementScale=t.displacementScale),void 0!==t.displacementBias&&(n.displacementBias=t.displacementBias),void 0!==t.roughnessMap&&(n.roughnessMap=i(t.roughnessMap)),void 0!==t.metalnessMap&&(n.metalnessMap=i(t.metalnessMap)),void 0!==t.emissiveMap&&(n.emissiveMap=i(t.emissiveMap)),void 0!==t.emissiveIntensity&&(n.emissiveIntensity=t.emissiveIntensity),void 0!==t.specularMap&&(n.specularMap=i(t.specularMap)),void 0!==t.specularIntensityMap&&(n.specularIntensityMap=i(t.specularIntensityMap)),void 0!==t.specularColorMap&&(n.specularColorMap=i(t.specularColorMap)),void 0!==t.envMap&&(n.envMap=i(t.envMap)),void 0!==t.envMapIntensity&&(n.envMapIntensity=t.envMapIntensity),void 0!==t.reflectivity&&(n.reflectivity=t.reflectivity),void 0!==t.refractionRatio&&(n.refractionRatio=t.refractionRatio),void 0!==t.lightMap&&(n.lightMap=i(t.lightMap)),void 0!==t.lightMapIntensity&&(n.lightMapIntensity=t.lightMapIntensity),void 0!==t.aoMap&&(n.aoMap=i(t.aoMap)),void 0!==t.aoMapIntensity&&(n.aoMapIntensity=t.aoMapIntensity),void 0!==t.gradientMap&&(n.gradientMap=i(t.gradientMap)),void 0!==t.clearcoatMap&&(n.clearcoatMap=i(t.clearcoatMap)),void 0!==t.clearcoatRoughnessMap&&(n.clearcoatRoughnessMap=i(t.clearcoatRoughnessMap)),void 0!==t.clearcoatNormalMap&&(n.clearcoatNormalMap=i(t.clearcoatNormalMap)),void 0!==t.clearcoatNormalScale&&(n.clearcoatNormalScale=(new Et).fromArray(t.clearcoatNormalScale)),void 0!==t.iridescenceMap&&(n.iridescenceMap=i(t.iridescenceMap)),void 0!==t.iridescenceThicknessMap&&(n.iridescenceThicknessMap=i(t.iridescenceThicknessMap)),void 0!==t.transmissionMap&&(n.transmissionMap=i(t.transmissionMap)),void 0!==t.thicknessMap&&(n.thicknessMap=i(t.thicknessMap)),void 0!==t.sheenColorMap&&(n.sheenColorMap=i(t.sheenColorMap)),void 0!==t.sheenRoughnessMap&&(n.sheenRoughnessMap=i(t.sheenRoughnessMap)),n}setTextures(t){return this.textures=t,this}static createMaterialFromType(t){return new{ShadowMaterial:Ll,SpriteMaterial:ra,RawShaderMaterial:Rl,ShaderMaterial:en,PointsMaterial:Ka,MeshPhysicalMaterial:Il,MeshStandardMaterial:Pl,MeshPhongMaterial:Dl,MeshToonMaterial:Nl,MeshNormalMaterial:Ol,MeshLambertMaterial:zl,MeshDepthMaterial:zs,MeshDistanceMaterial:Fs,MeshBasicMaterial:vi,MeshMatcapMaterial:Fl,LineDashedMaterial:Bl,LineBasicMaterial:ka,Material:gi}[t]}}class Nc{static decodeText(t){if("undefined"!=typeof TextDecoder)return(new TextDecoder).decode(t);let e="";for(let i=0,n=t.length;i0){this.source.connect(this.filters[0]);for(let t=1,e=this.filters.length;t0){this.source.disconnect(this.filters[0]);for(let t=1,e=this.filters.length;t0&&this._mixBufferRegionAdditive(i,n,this._addIndex*e,1,e);for(let t=e,r=e+e;t!==r;++t)if(i[t]!==i[t+e]){a.setValue(i,n);break}}saveOriginalState(){const t=this.binding,e=this.buffer,i=this.valueSize,n=i*this._origIndex;t.getValue(e,n);for(let t=i,r=n;t!==r;++t)e[t]=e[n+t%i];this._setIdentity(),this.cumulativeWeight=0,this.cumulativeWeightAdditive=0}restoreOriginalState(){const t=3*this.valueSize;this.binding.setValue(this.buffer,t)}_setAdditiveIdentityNumeric(){const t=this._addIndex*this.valueSize,e=t+this.valueSize;for(let i=t;i=.5)for(let n=0;n!==r;++n)t[e+n]=t[i+n]}_slerp(t,e,i,n){te.slerpFlat(t,e,t,e,t,i,n)}_slerpAdditive(t,e,i,n,r){const s=this._workIndex*r;te.multiplyQuaternionsFlat(t,s,t,e,t,i),te.slerpFlat(t,e,t,e,t,s,n)}_lerp(t,e,i,n,r){const s=1-n;for(let a=0;a!==r;++a){const r=e+a;t[r]=t[r]*s+t[i+a]*n}}_lerpAdditive(t,e,i,n,r){for(let s=0;s!==r;++s){const r=e+s;t[r]=t[r]+t[i+s]*n}}}const nh="\\[\\]\\.:\\/",rh=new RegExp("[\\[\\]\\.:\\/]","g"),sh="[^\\[\\]\\.:\\/]",ah="[^"+nh.replace("\\.","")+"]",oh=new RegExp("^"+/((?:WC+[\/:])*)/.source.replace("WC",sh)+/(WCOD+)?/.source.replace("WCOD",ah)+/(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC",sh)+/\.(WC+)(?:\[(.+)\])?/.source.replace("WC",sh)+"$"),lh=["material","materials","bones"];class ch{constructor(t,e,i){this.path=e,this.parsedPath=i||ch.parseTrackName(e),this.node=ch.findNode(t,this.parsedPath.nodeName)||t,this.rootNode=t,this.getValue=this._getValue_unbound,this.setValue=this._setValue_unbound}static create(t,e,i){return t&&t.isAnimationObjectGroup?new ch.Composite(t,e,i):new ch(t,e,i)}static sanitizeNodeName(t){return t.replace(/\s/g,"_").replace(rh,"")}static parseTrackName(t){const e=oh.exec(t);if(null===e)throw new Error("PropertyBinding: Cannot parse trackName: "+t);const i={nodeName:e[2],objectName:e[3],objectIndex:e[4],propertyName:e[5],propertyIndex:e[6]},n=i.nodeName&&i.nodeName.lastIndexOf(".");if(void 0!==n&&-1!==n){const t=i.nodeName.substring(n+1);-1!==lh.indexOf(t)&&(i.nodeName=i.nodeName.substring(0,n),i.objectName=t)}if(null===i.propertyName||0===i.propertyName.length)throw new Error("PropertyBinding: can not parse propertyName from trackName: "+t);return i}static findNode(t,e){if(void 0===e||""===e||"."===e||-1===e||e===t.name||e===t.uuid)return t;if(t.skeleton){const i=t.skeleton.getBoneByName(e);if(void 0!==i)return i}if(t.children){const i=function(t){for(let n=0;n0){const t=this._interpolants,e=this._propertyBindings;if(this.blendMode===st)for(let i=0,n=t.length;i!==n;++i)t[i].evaluate(s),e[i].accumulateAdditive(a);else for(let i=0,r=t.length;i!==r;++i)t[i].evaluate(s),e[i].accumulate(n,a)}}_updateWeight(t){let e=0;if(this.enabled){e=this.weight;const i=this._weightInterpolant;if(null!==i){const n=i.evaluate(t)[0];e*=n,t>i.parameterPositions[1]&&(this.stopFading(),0===n&&(this.enabled=!1))}}return this._effectiveWeight=e,e}_updateTimeScale(t){let e=0;if(!this.paused){e=this.timeScale;const i=this._timeScaleInterpolant;if(null!==i){e*=i.evaluate(t)[0],t>i.parameterPositions[1]&&(this.stopWarping(),0===e?this.paused=!0:this.timeScale=e)}}return this._effectiveTimeScale=e,e}_updateTime(t){const e=this._clip.duration,i=this.loop;let n=this.time+t,r=this._loopCount;const s=2202===i;if(0===t)return-1===r?n:s&&1==(1&r)?e-n:n;if(2200===i){-1===r&&(this._loopCount=0,this._setEndings(!0,!0,!1));t:{if(n>=e)n=e;else{if(!(n<0)){this.time=n;break t}n=0}this.clampWhenFinished?this.paused=!0:this.enabled=!1,this.time=n,this._mixer.dispatchEvent({type:"finished",action:this,direction:t<0?-1:1})}}else{if(-1===r&&(t>=0?(r=0,this._setEndings(!0,0===this.repetitions,s)):this._setEndings(0===this.repetitions,!0,s)),n>=e||n<0){const i=Math.floor(n/e);n-=e*i,r+=Math.abs(i);const a=this.repetitions-r;if(a<=0)this.clampWhenFinished?this.paused=!0:this.enabled=!1,n=t>0?e:0,this.time=n,this._mixer.dispatchEvent({type:"finished",action:this,direction:t>0?1:-1});else{if(1===a){const e=t<0;this._setEndings(e,!e,s)}else this._setEndings(!1,!1,s);this._loopCount=r,this.time=n,this._mixer.dispatchEvent({type:"loop",action:this,loopDelta:i})}}else this.time=n;if(s&&1==(1&r))return e-n}return n}_setEndings(t,e,i){const n=this._interpolantSettings;i?(n.endingStart=it,n.endingEnd=it):(n.endingStart=t?this.zeroSlopeAtStart?it:et:nt,n.endingEnd=e?this.zeroSlopeAtEnd?it:et:nt)}_scheduleFading(t,e,i){const n=this._mixer,r=n.time;let s=this._weightInterpolant;null===s&&(s=n._lendControlInterpolant(),this._weightInterpolant=s);const a=s.parameterPositions,o=s.sampleValues;return a[0]=r,o[0]=e,a[1]=r+t,o[1]=i,this}}const uh=new Float32Array(1);class dh{constructor(t){"string"==typeof t&&(console.warn("THREE.Uniform: Type parameter is no longer needed."),t=arguments[1]),this.value=t}clone(){return new dh(void 0===this.value.clone?this.value:this.value.clone())}}let ph=0;function fh(t,e){return t.distance-e.distance}function mh(t,e,i,n){if(t.layers.test(e.layers)&&t.raycast(e,i),!0===n){const n=t.children;for(let t=0,r=n.length;t>-e-14,n[256|t]=1024>>-e-14|32768,r[t]=-e-1,r[256|t]=-e-1):e<=15?(n[t]=e+15<<10,n[256|t]=e+15<<10|32768,r[t]=13,r[256|t]=13):e<128?(n[t]=31744,n[256|t]=64512,r[t]=24,r[256|t]=24):(n[t]=31744,n[256|t]=64512,r[t]=13,r[256|t]=13)}const s=new Uint32Array(2048),a=new Uint32Array(64),o=new Uint32Array(64);for(let t=1;t<1024;++t){let e=t<<13,i=0;for(;0==(8388608&e);)e<<=1,i-=8388608;e&=-8388609,i+=947912704,s[t]=e|i}for(let t=1024;t<2048;++t)s[t]=939524096+(t-1024<<13);for(let t=1;t<31;++t)a[t]=t<<23;a[31]=1199570944,a[32]=2147483648;for(let t=33;t<63;++t)a[t]=2147483648+(t-32<<23);a[63]=3347054592;for(let t=1;t<64;++t)32!==t&&(o[t]=1024);return{floatView:e,uint32View:i,baseTable:n,shiftTable:r,mantissaTable:s,exponentTable:a,offsetTable:o}}var Uh=Object.freeze({__proto__:null,toHalfFloat:function(t){Math.abs(t)>65504&&console.warn("THREE.DataUtils.toHalfFloat(): Value out of range."),t=yt(t,-65504,65504),Fh.floatView[0]=t;const e=Fh.uint32View[0],i=e>>23&511;return Fh.baseTable[i]+((8388607&e)>>Fh.shiftTable[i])},fromHalfFloat:function(t){const e=t>>10;return Fh.uint32View[0]=Fh.mantissaTable[Fh.offsetTable[e]+(1023&t)]+Fh.exponentTable[e],Fh.floatView[0]}});"undefined"!=typeof __THREE_DEVTOOLS__&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("register",{detail:{revision:e}})),"undefined"!=typeof window&&(window.__THREE__?console.warn("WARNING: Multiple instances of Three.js being imported."):window.__THREE__=e),t.ACESFilmicToneMapping=4,t.AddEquation=i,t.AddOperation=2,t.AdditiveAnimationBlendMode=st,t.AdditiveBlending=2,t.AlphaFormat=1021,t.AlwaysDepth=1,t.AlwaysStencilFunc=519,t.AmbientLight=Lc,t.AmbientLightProbe=class extends Ic{constructor(t,e=1){super(void 0,e),this.isAmbientLightProbe=!0;const i=(new Ht).set(t);this.sh.coefficients[0].set(i.r,i.g,i.b).multiplyScalar(2*Math.sqrt(Math.PI))}},t.AnimationClip=rc,t.AnimationLoader=class extends cc{constructor(t){super(t)}load(t,e,i,n){const r=this,s=new dc(this.manager);s.setPath(this.path),s.setRequestHeader(this.requestHeader),s.setWithCredentials(this.withCredentials),s.load(t,(function(i){try{e(r.parse(JSON.parse(i)))}catch(e){n?n(e):console.error(e),r.manager.itemError(t)}}),i,n)}parse(t){const e=[];for(let i=0;i=0;--e)t[e].stop();return this}update(t){t*=this.timeScale;const e=this._actions,i=this._nActiveActions,n=this.time+=t,r=Math.sign(t),s=this._accuIndex^=1;for(let a=0;a!==i;++a){e[a]._update(n,t,r,s)}const a=this._bindings,o=this._nActiveBindings;for(let t=0;t!==o;++t)a[t].apply(s);return this}setTime(t){this.time=0;for(let t=0;t=r){const s=r++,c=t[s];e[c.uuid]=l,t[l]=c,e[o]=s,t[s]=a;for(let t=0,e=n;t!==e;++t){const e=i[t],n=e[s],r=e[l];e[l]=n,e[s]=r}}}this.nCachedObjects_=r}uncache(){const t=this._objects,e=this._indicesByUUID,i=this._bindings,n=i.length;let r=this.nCachedObjects_,s=t.length;for(let a=0,o=arguments.length;a!==o;++a){const o=arguments[a].uuid,l=e[o];if(void 0!==l)if(delete e[o],l0&&(e[a.uuid]=l),t[l]=a,t.pop();for(let t=0,e=n;t!==e;++t){const e=i[t];e[l]=e[r],e.pop()}}}this.nCachedObjects_=r}subscribe_(t,e){const i=this._bindingsIndicesByPath;let n=i[t];const r=this._bindings;if(void 0!==n)return r[n];const s=this._paths,a=this._parsedPaths,o=this._objects,l=o.length,c=this.nCachedObjects_,h=new Array(l);n=r.length,i[t]=n,s.push(t),a.push(e),r.push(h);for(let i=c,n=o.length;i!==n;++i){const n=o[i];h[i]=new ch(n,t,e)}return h}unsubscribe_(t){const e=this._bindingsIndicesByPath,i=e[t];if(void 0!==i){const n=this._paths,r=this._parsedPaths,s=this._bindings,a=s.length-1,o=s[a];e[t[a]]=i,s[i]=o,s.pop(),r[i]=r[a],r.pop(),n[i]=n[a],n.pop()}}},t.AnimationUtils=jl,t.ArcCurve=oo,t.ArrayCamera=Vs,t.ArrowHelper=class extends ni{constructor(t=new ee(0,0,1),e=new ee(0,0,0),i=1,n=16776960,r=.2*i,s=.2*r){super(),this.type="ArrowHelper",void 0===Oh&&(Oh=new Pi,Oh.setAttribute("position",new wi([0,0,0,0,1,0],3)),zh=new Po(0,.5,1,5,1),zh.translate(0,-.5,0)),this.position.copy(e),this.line=new qa(Oh,new ka({color:n,toneMapped:!1})),this.line.matrixAutoUpdate=!1,this.add(this.line),this.cone=new Zi(zh,new vi({color:n,toneMapped:!1})),this.cone.matrixAutoUpdate=!1,this.add(this.cone),this.setDirection(t),this.setLength(i,r,s)}setDirection(t){if(t.y>.99999)this.quaternion.set(0,0,0,1);else if(t.y<-.99999)this.quaternion.set(1,0,0,0);else{Nh.set(t.z,0,-t.x).normalize();const e=Math.acos(t.y);this.quaternion.setFromAxisAngle(Nh,e)}}setLength(t,e=.2*t,i=.2*e){this.line.scale.set(1,Math.max(1e-4,t-e),1),this.line.updateMatrix(),this.cone.scale.set(i,e,i),this.cone.position.y=t,this.cone.updateMatrix()}setColor(t){this.line.material.color.set(t),this.cone.material.color.set(t)}copy(t){return super.copy(t,!1),this.line.copy(t.line),this.cone.copy(t.cone),this}},t.Audio=Kc,t.AudioAnalyser=class{constructor(t,e=2048){this.analyser=t.context.createAnalyser(),this.analyser.fftSize=e,this.data=new Uint8Array(this.analyser.frequencyBinCount),t.getOutput().connect(this.analyser)}getFrequencyData(){return this.analyser.getByteFrequencyData(this.data),this.data}getAverageFrequency(){let t=0;const e=this.getFrequencyData();for(let i=0;ithis.max.x||t.ythis.max.y)}containsBox(t){return this.min.x<=t.min.x&&t.max.x<=this.max.x&&this.min.y<=t.min.y&&t.max.y<=this.max.y}getParameter(t,e){return e.set((t.x-this.min.x)/(this.max.x-this.min.x),(t.y-this.min.y)/(this.max.y-this.min.y))}intersectsBox(t){return!(t.max.xthis.max.x||t.max.ythis.max.y)}clampPoint(t,e){return e.copy(t).clamp(this.min,this.max)}distanceToPoint(t){return gh.copy(t).clamp(this.min,this.max).sub(t).length()}intersect(t){return this.min.max(t.min),this.max.min(t.max),this}union(t){return this.min.min(t.min),this.max.max(t.max),this}translate(t){return this.min.add(t),this.max.add(t),this}equals(t){return t.min.equals(this.min)&&t.max.equals(this.max)}},t.Box3=re,t.Box3Helper=class extends Za{constructor(t,e=16776960){const i=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]),n=new Pi;n.setIndex(new yi(i,1)),n.setAttribute("position",new wi([1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1],3)),super(n,new ka({color:e,toneMapped:!1})),this.box=t,this.type="Box3Helper",this.geometry.computeBoundingSphere()}updateMatrixWorld(t){const e=this.box;e.isEmpty()||(e.getCenter(this.position),e.getSize(this.scale),this.scale.multiplyScalar(.5),super.updateMatrixWorld(t))}},t.BoxBufferGeometry=Ki,t.BoxGeometry=Ki,t.BoxHelper=class extends Za{constructor(t,e=16776960){const i=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]),n=new Float32Array(24),r=new Pi;r.setIndex(new yi(i,1)),r.setAttribute("position",new yi(n,3)),super(r,new ka({color:e,toneMapped:!1})),this.object=t,this.type="BoxHelper",this.matrixAutoUpdate=!1,this.update()}update(t){if(void 0!==t&&console.warn("THREE.BoxHelper: .update() has no longer arguments."),void 0!==this.object&&Dh.setFromObject(this.object),Dh.isEmpty())return;const e=Dh.min,i=Dh.max,n=this.geometry.attributes.position,r=n.array;r[0]=i.x,r[1]=i.y,r[2]=i.z,r[3]=e.x,r[4]=i.y,r[5]=i.z,r[6]=e.x,r[7]=e.y,r[8]=i.z,r[9]=i.x,r[10]=e.y,r[11]=i.z,r[12]=i.x,r[13]=i.y,r[14]=e.z,r[15]=e.x,r[16]=i.y,r[17]=e.z,r[18]=e.x,r[19]=e.y,r[20]=e.z,r[21]=i.x,r[22]=e.y,r[23]=e.z,n.needsUpdate=!0,this.geometry.computeBoundingSphere()}setFromObject(t){return this.object=t,this.update(),this}copy(t,e){return super.copy(t,e),this.object=t.object,this}},t.BufferAttribute=yi,t.BufferGeometry=Pi,t.BufferGeometryLoader=zc,t.ByteType=1010,t.Cache=ac,t.Camera=nn,t.CameraHelper=class extends Za{constructor(t){const e=new Pi,i=new ka({color:16777215,vertexColors:!0,toneMapped:!1}),n=[],r=[],s={};function a(t,e){o(t),o(e)}function o(t){n.push(0,0,0),r.push(0,0,0),void 0===s[t]&&(s[t]=[]),s[t].push(n.length/3-1)}a("n1","n2"),a("n2","n4"),a("n4","n3"),a("n3","n1"),a("f1","f2"),a("f2","f4"),a("f4","f3"),a("f3","f1"),a("n1","f1"),a("n2","f2"),a("n3","f3"),a("n4","f4"),a("p","n1"),a("p","n2"),a("p","n3"),a("p","n4"),a("u1","u2"),a("u2","u3"),a("u3","u1"),a("c","t"),a("p","c"),a("cn1","cn2"),a("cn3","cn4"),a("cf1","cf2"),a("cf3","cf4"),e.setAttribute("position",new wi(n,3)),e.setAttribute("color",new wi(r,3)),super(e,i),this.type="CameraHelper",this.camera=t,this.camera.updateProjectionMatrix&&this.camera.updateProjectionMatrix(),this.matrix=t.matrixWorld,this.matrixAutoUpdate=!1,this.pointMap=s,this.update();const l=new Ht(16755200),c=new Ht(16711680),h=new Ht(43775),u=new Ht(16777215),d=new Ht(3355443);this.setColors(l,c,h,u,d)}setColors(t,e,i,n,r){const s=this.geometry.getAttribute("color");s.setXYZ(0,t.r,t.g,t.b),s.setXYZ(1,t.r,t.g,t.b),s.setXYZ(2,t.r,t.g,t.b),s.setXYZ(3,t.r,t.g,t.b),s.setXYZ(4,t.r,t.g,t.b),s.setXYZ(5,t.r,t.g,t.b),s.setXYZ(6,t.r,t.g,t.b),s.setXYZ(7,t.r,t.g,t.b),s.setXYZ(8,t.r,t.g,t.b),s.setXYZ(9,t.r,t.g,t.b),s.setXYZ(10,t.r,t.g,t.b),s.setXYZ(11,t.r,t.g,t.b),s.setXYZ(12,t.r,t.g,t.b),s.setXYZ(13,t.r,t.g,t.b),s.setXYZ(14,t.r,t.g,t.b),s.setXYZ(15,t.r,t.g,t.b),s.setXYZ(16,t.r,t.g,t.b),s.setXYZ(17,t.r,t.g,t.b),s.setXYZ(18,t.r,t.g,t.b),s.setXYZ(19,t.r,t.g,t.b),s.setXYZ(20,t.r,t.g,t.b),s.setXYZ(21,t.r,t.g,t.b),s.setXYZ(22,t.r,t.g,t.b),s.setXYZ(23,t.r,t.g,t.b),s.setXYZ(24,e.r,e.g,e.b),s.setXYZ(25,e.r,e.g,e.b),s.setXYZ(26,e.r,e.g,e.b),s.setXYZ(27,e.r,e.g,e.b),s.setXYZ(28,e.r,e.g,e.b),s.setXYZ(29,e.r,e.g,e.b),s.setXYZ(30,e.r,e.g,e.b),s.setXYZ(31,e.r,e.g,e.b),s.setXYZ(32,i.r,i.g,i.b),s.setXYZ(33,i.r,i.g,i.b),s.setXYZ(34,i.r,i.g,i.b),s.setXYZ(35,i.r,i.g,i.b),s.setXYZ(36,i.r,i.g,i.b),s.setXYZ(37,i.r,i.g,i.b),s.setXYZ(38,n.r,n.g,n.b),s.setXYZ(39,n.r,n.g,n.b),s.setXYZ(40,r.r,r.g,r.b),s.setXYZ(41,r.r,r.g,r.b),s.setXYZ(42,r.r,r.g,r.b),s.setXYZ(43,r.r,r.g,r.b),s.setXYZ(44,r.r,r.g,r.b),s.setXYZ(45,r.r,r.g,r.b),s.setXYZ(46,r.r,r.g,r.b),s.setXYZ(47,r.r,r.g,r.b),s.setXYZ(48,r.r,r.g,r.b),s.setXYZ(49,r.r,r.g,r.b),s.needsUpdate=!0}update(){const t=this.geometry,e=this.pointMap;Ph.projectionMatrixInverse.copy(this.camera.projectionMatrixInverse),Ih("c",e,t,Ph,0,0,-1),Ih("t",e,t,Ph,0,0,1),Ih("n1",e,t,Ph,-1,-1,-1),Ih("n2",e,t,Ph,1,-1,-1),Ih("n3",e,t,Ph,-1,1,-1),Ih("n4",e,t,Ph,1,1,-1),Ih("f1",e,t,Ph,-1,-1,1),Ih("f2",e,t,Ph,1,-1,1),Ih("f3",e,t,Ph,-1,1,1),Ih("f4",e,t,Ph,1,1,1),Ih("u1",e,t,Ph,.7,1.1,-1),Ih("u2",e,t,Ph,-.7,1.1,-1),Ih("u3",e,t,Ph,0,2,-1),Ih("cf1",e,t,Ph,-1,0,1),Ih("cf2",e,t,Ph,1,0,1),Ih("cf3",e,t,Ph,0,-1,1),Ih("cf4",e,t,Ph,0,1,1),Ih("cn1",e,t,Ph,-1,0,-1),Ih("cn2",e,t,Ph,1,0,-1),Ih("cn3",e,t,Ph,0,-1,-1),Ih("cn4",e,t,Ph,0,1,-1),t.getAttribute("position").needsUpdate=!0}dispose(){this.geometry.dispose(),this.material.dispose()}},t.CanvasTexture=class extends Zt{constructor(t,e,i,n,r,s,a,o,l){super(t,e,i,n,r,s,a,o,l),this.isCanvasTexture=!0,this.needsUpdate=!0}},t.CapsuleBufferGeometry=Lo,t.CapsuleGeometry=Lo,t.CatmullRomCurve3=fo,t.CineonToneMapping=3,t.CircleBufferGeometry=Ro,t.CircleGeometry=Ro,t.ClampToEdgeWrapping=h,t.Clock=jc,t.Color=Ht,t.ColorKeyframeTrack=$l,t.ColorManagement=zt,t.CompressedTexture=ro,t.CompressedTextureLoader=class extends cc{constructor(t){super(t)}load(t,e,i,n){const r=this,s=[],a=new ro,o=new dc(this.manager);o.setPath(this.path),o.setResponseType("arraybuffer"),o.setRequestHeader(this.requestHeader),o.setWithCredentials(r.withCredentials);let l=0;function c(c){o.load(t[c],(function(t){const i=r.parse(t,!0);s[c]={width:i.width,height:i.height,format:i.format,mipmaps:i.mipmaps},l+=1,6===l&&(1===i.mipmapCount&&(a.minFilter=m),a.image=s,a.format=i.format,a.needsUpdate=!0,e&&e(a))}),i,n)}if(Array.isArray(t))for(let e=0,i=t.length;e0){const i=new oc(e);r=new pc(i),r.setCrossOrigin(this.crossOrigin);for(let e=0,i=t.length;e0){n=new pc(this.manager),n.setCrossOrigin(this.crossOrigin);for(let e=0,n=t.length;eNumber.EPSILON){if(l<0&&(i=e[s],o=-o,a=e[r],l=-l),t.ya.y)continue;if(t.y===i.y){if(t.x===i.x)return!0}else{const e=l*(t.x-i.x)-o*(t.y-i.y);if(0===e)return!0;if(e<0)continue;n=!n}}else{if(t.y!==i.y)continue;if(a.x<=t.x&&t.x<=i.x||i.x<=t.x&&t.x<=a.x)return!0}}return n}const r=dl.isClockWise,s=this.subPaths;if(0===s.length)return[];if(!0===e)return i(s);let a,o,l;const c=[];if(1===s.length)return o=s[0],l=new ko,l.curves=o.curves,c.push(l),c;let h=!r(s[0].getPoints());h=t?!h:h;const u=[],d=[];let p,f,m=[],g=0;d[g]=void 0,m[g]=[];for(let e=0,i=s.length;e1){let t=!1,e=0;for(let t=0,e=d.length;t0&&!1===t&&(m=u)}for(let t=0,e=d.length;t=t.HAVE_CURRENT_DATA&&(this.needsUpdate=!0)}},t.WebGL1Renderer=Ks,t.WebGL3DRenderTarget=class extends Kt{constructor(t,e,i){super(t,e),this.isWebGL3DRenderTarget=!0,this.depth=i,this.texture=new Qt(null,t,e,i),this.texture.isRenderTargetTexture=!0}},t.WebGLArrayRenderTarget=class extends Kt{constructor(t,e,i){super(t,e),this.isWebGLArrayRenderTarget=!0,this.depth=i,this.texture=new $t(null,t,e,i),this.texture.isRenderTargetTexture=!0}},t.WebGLCubeRenderTarget=ln,t.WebGLMultipleRenderTargets=class extends Kt{constructor(t,e,i,n={}){super(t,e,n),this.isWebGLMultipleRenderTargets=!0;const r=this.texture;this.texture=[];for(let t=0;t>8&255]+ft[t>>16&255]+ft[t>>24&255]+"-"+ft[255&e]+ft[e>>8&255]+"-"+ft[e>>16&15|64]+ft[e>>24&255]+"-"+ft[63&i|128]+ft[i>>8&255]+"-"+ft[i>>16&255]+ft[i>>24&255]+ft[255&n]+ft[n>>8&255]+ft[n>>16&255]+ft[n>>24&255]).toLowerCase()}function yt(t,e,i){return Math.max(e,Math.min(i,t))}function Mt(t,e){return(t%e+e)%e}function bt(t,e,i){return(1-i)*t+i*e}function St(t){return 0==(t&t-1)&&0!==t}function wt(t){return Math.pow(2,Math.ceil(Math.log(t)/Math.LN2))}function Tt(t){return Math.pow(2,Math.floor(Math.log(t)/Math.LN2))}function At(t,e){switch(e.constructor){case Float32Array:return t;case Uint16Array:return t/65535;case Uint8Array:return t/255;case Int16Array:return Math.max(t/32767,-1);case Int8Array:return Math.max(t/127,-1);default:throw new Error("Invalid component type.")}}function Et(t,e){switch(e.constructor){case Float32Array:return t;case Uint16Array:return Math.round(65535*t);case Uint8Array:return Math.round(255*t);case Int16Array:return Math.round(32767*t);case Int8Array:return Math.round(127*t);default:throw new Error("Invalid component type.")}}var Ct=Object.freeze({__proto__:null,DEG2RAD:vt,RAD2DEG:xt,generateUUID:_t,clamp:yt,euclideanModulo:Mt,mapLinear:function(t,e,i,n,r){return n+(t-e)*(r-n)/(i-e)},inverseLerp:function(t,e,i){return t!==e?(i-t)/(e-t):0},lerp:bt,damp:function(t,e,i,n){return bt(t,e,1-Math.exp(-i*n))},pingpong:function(t,e=1){return e-Math.abs(Mt(t,2*e)-e)},smoothstep:function(t,e,i){return t<=e?0:t>=i?1:(t=(t-e)/(i-e))*t*(3-2*t)},smootherstep:function(t,e,i){return t<=e?0:t>=i?1:(t=(t-e)/(i-e))*t*t*(t*(6*t-15)+10)},randInt:function(t,e){return t+Math.floor(Math.random()*(e-t+1))},randFloat:function(t,e){return t+Math.random()*(e-t)},randFloatSpread:function(t){return t*(.5-Math.random())},seededRandom:function(t){void 0!==t&&(gt=t);let e=gt+=1831565813;return e=Math.imul(e^e>>>15,1|e),e^=e+Math.imul(e^e>>>7,61|e),((e^e>>>14)>>>0)/4294967296},degToRad:function(t){return t*vt},radToDeg:function(t){return t*xt},isPowerOfTwo:St,ceilPowerOfTwo:wt,floorPowerOfTwo:Tt,setQuaternionFromProperEuler:function(t,e,i,n,r){const s=Math.cos,a=Math.sin,o=s(i/2),l=a(i/2),c=s((e+n)/2),h=a((e+n)/2),u=s((e-n)/2),d=a((e-n)/2),p=s((n-e)/2),m=a((n-e)/2);switch(r){case"XYX":t.set(o*h,l*u,l*d,o*c);break;case"YZY":t.set(l*d,o*h,l*u,o*c);break;case"ZXZ":t.set(l*u,l*d,o*h,o*c);break;case"XZX":t.set(o*h,l*m,l*p,o*c);break;case"YXY":t.set(l*p,o*h,l*m,o*c);break;case"ZYZ":t.set(l*m,l*p,o*h,o*c);break;default:console.warn("THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: "+r)}},normalize:Et,denormalize:At});class Lt{constructor(t=0,e=0){Lt.prototype.isVector2=!0,this.x=t,this.y=e}get width(){return this.x}set width(t){this.x=t}get height(){return this.y}set height(t){this.y=t}set(t,e){return this.x=t,this.y=e,this}setScalar(t){return this.x=t,this.y=t,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setComponent(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;default:throw new Error("index is out of range: "+t)}return this}getComponent(t){switch(t){case 0:return this.x;case 1:return this.y;default:throw new Error("index is out of range: "+t)}}clone(){return new this.constructor(this.x,this.y)}copy(t){return this.x=t.x,this.y=t.y,this}add(t){return this.x+=t.x,this.y+=t.y,this}addScalar(t){return this.x+=t,this.y+=t,this}addVectors(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this}addScaledVector(t,e){return this.x+=t.x*e,this.y+=t.y*e,this}sub(t){return this.x-=t.x,this.y-=t.y,this}subScalar(t){return this.x-=t,this.y-=t,this}subVectors(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this}multiply(t){return this.x*=t.x,this.y*=t.y,this}multiplyScalar(t){return this.x*=t,this.y*=t,this}divide(t){return this.x/=t.x,this.y/=t.y,this}divideScalar(t){return this.multiplyScalar(1/t)}applyMatrix3(t){const e=this.x,i=this.y,n=t.elements;return this.x=n[0]*e+n[3]*i+n[6],this.y=n[1]*e+n[4]*i+n[7],this}min(t){return this.x=Math.min(this.x,t.x),this.y=Math.min(this.y,t.y),this}max(t){return this.x=Math.max(this.x,t.x),this.y=Math.max(this.y,t.y),this}clamp(t,e){return this.x=Math.max(t.x,Math.min(e.x,this.x)),this.y=Math.max(t.y,Math.min(e.y,this.y)),this}clampScalar(t,e){return this.x=Math.max(t,Math.min(e,this.x)),this.y=Math.max(t,Math.min(e,this.y)),this}clampLength(t,e){const i=this.length();return this.divideScalar(i||1).multiplyScalar(Math.max(t,Math.min(e,i)))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this}roundToZero(){return this.x=this.x<0?Math.ceil(this.x):Math.floor(this.x),this.y=this.y<0?Math.ceil(this.y):Math.floor(this.y),this}negate(){return this.x=-this.x,this.y=-this.y,this}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}lengthSq(){return this.x*this.x+this.y*this.y}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)}normalize(){return this.divideScalar(this.length()||1)}angle(){return Math.atan2(-this.y,-this.x)+Math.PI}distanceTo(t){return Math.sqrt(this.distanceToSquared(t))}distanceToSquared(t){const e=this.x-t.x,i=this.y-t.y;return e*e+i*i}manhattanDistanceTo(t){return Math.abs(this.x-t.x)+Math.abs(this.y-t.y)}setLength(t){return this.normalize().multiplyScalar(t)}lerp(t,e){return this.x+=(t.x-this.x)*e,this.y+=(t.y-this.y)*e,this}lerpVectors(t,e,i){return this.x=t.x+(e.x-t.x)*i,this.y=t.y+(e.y-t.y)*i,this}equals(t){return t.x===this.x&&t.y===this.y}fromArray(t,e=0){return this.x=t[e],this.y=t[e+1],this}toArray(t=[],e=0){return t[e]=this.x,t[e+1]=this.y,t}fromBufferAttribute(t,e){return this.x=t.getX(e),this.y=t.getY(e),this}rotateAround(t,e){const i=Math.cos(e),n=Math.sin(e),r=this.x-t.x,s=this.y-t.y;return this.x=r*i-s*n+t.x,this.y=r*n+s*i+t.y,this}random(){return this.x=Math.random(),this.y=Math.random(),this}*[Symbol.iterator](){yield this.x,yield this.y}}class Rt{constructor(){Rt.prototype.isMatrix3=!0,this.elements=[1,0,0,0,1,0,0,0,1]}set(t,e,i,n,r,s,a,o,l){const c=this.elements;return c[0]=t,c[1]=n,c[2]=a,c[3]=e,c[4]=r,c[5]=o,c[6]=i,c[7]=s,c[8]=l,this}identity(){return this.set(1,0,0,0,1,0,0,0,1),this}copy(t){const e=this.elements,i=t.elements;return e[0]=i[0],e[1]=i[1],e[2]=i[2],e[3]=i[3],e[4]=i[4],e[5]=i[5],e[6]=i[6],e[7]=i[7],e[8]=i[8],this}extractBasis(t,e,i){return t.setFromMatrix3Column(this,0),e.setFromMatrix3Column(this,1),i.setFromMatrix3Column(this,2),this}setFromMatrix4(t){const e=t.elements;return this.set(e[0],e[4],e[8],e[1],e[5],e[9],e[2],e[6],e[10]),this}multiply(t){return this.multiplyMatrices(this,t)}premultiply(t){return this.multiplyMatrices(t,this)}multiplyMatrices(t,e){const i=t.elements,n=e.elements,r=this.elements,s=i[0],a=i[3],o=i[6],l=i[1],c=i[4],h=i[7],u=i[2],d=i[5],p=i[8],m=n[0],f=n[3],g=n[6],v=n[1],x=n[4],_=n[7],y=n[2],M=n[5],b=n[8];return r[0]=s*m+a*v+o*y,r[3]=s*f+a*x+o*M,r[6]=s*g+a*_+o*b,r[1]=l*m+c*v+h*y,r[4]=l*f+c*x+h*M,r[7]=l*g+c*_+h*b,r[2]=u*m+d*v+p*y,r[5]=u*f+d*x+p*M,r[8]=u*g+d*_+p*b,this}multiplyScalar(t){const e=this.elements;return e[0]*=t,e[3]*=t,e[6]*=t,e[1]*=t,e[4]*=t,e[7]*=t,e[2]*=t,e[5]*=t,e[8]*=t,this}determinant(){const t=this.elements,e=t[0],i=t[1],n=t[2],r=t[3],s=t[4],a=t[5],o=t[6],l=t[7],c=t[8];return e*s*c-e*a*l-i*r*c+i*a*o+n*r*l-n*s*o}invert(){const t=this.elements,e=t[0],i=t[1],n=t[2],r=t[3],s=t[4],a=t[5],o=t[6],l=t[7],c=t[8],h=c*s-a*l,u=a*o-c*r,d=l*r-s*o,p=e*h+i*u+n*d;if(0===p)return this.set(0,0,0,0,0,0,0,0,0);const m=1/p;return t[0]=h*m,t[1]=(n*l-c*i)*m,t[2]=(a*i-n*s)*m,t[3]=u*m,t[4]=(c*e-n*o)*m,t[5]=(n*r-a*e)*m,t[6]=d*m,t[7]=(i*o-l*e)*m,t[8]=(s*e-i*r)*m,this}transpose(){let t;const e=this.elements;return t=e[1],e[1]=e[3],e[3]=t,t=e[2],e[2]=e[6],e[6]=t,t=e[5],e[5]=e[7],e[7]=t,this}getNormalMatrix(t){return this.setFromMatrix4(t).invert().transpose()}transposeIntoArray(t){const e=this.elements;return t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],this}setUvTransform(t,e,i,n,r,s,a){const o=Math.cos(r),l=Math.sin(r);return this.set(i*o,i*l,-i*(o*s+l*a)+s+t,-n*l,n*o,-n*(-l*s+o*a)+a+e,0,0,1),this}scale(t,e){return this.premultiply(Pt.makeScale(t,e)),this}rotate(t){return this.premultiply(Pt.makeRotation(-t)),this}translate(t,e){return this.premultiply(Pt.makeTranslation(t,e)),this}makeTranslation(t,e){return this.set(1,0,t,0,1,e,0,0,1),this}makeRotation(t){const e=Math.cos(t),i=Math.sin(t);return this.set(e,-i,0,i,e,0,0,0,1),this}makeScale(t,e){return this.set(t,0,0,0,e,0,0,0,1),this}equals(t){const e=this.elements,i=t.elements;for(let t=0;t<9;t++)if(e[t]!==i[t])return!1;return!0}fromArray(t,e=0){for(let i=0;i<9;i++)this.elements[i]=t[i+e];return this}toArray(t=[],e=0){const i=this.elements;return t[e]=i[0],t[e+1]=i[1],t[e+2]=i[2],t[e+3]=i[3],t[e+4]=i[4],t[e+5]=i[5],t[e+6]=i[6],t[e+7]=i[7],t[e+8]=i[8],t}clone(){return(new this.constructor).fromArray(this.elements)}}const Pt=new Rt;function It(t){for(let e=t.length-1;e>=0;--e)if(t[e]>=65535)return!0;return!1}const Dt={Int8Array:Int8Array,Uint8Array:Uint8Array,Uint8ClampedArray:Uint8ClampedArray,Int16Array:Int16Array,Uint16Array:Uint16Array,Int32Array:Int32Array,Uint32Array:Uint32Array,Float32Array:Float32Array,Float64Array:Float64Array};function Nt(t,e){return new Dt[t](e)}function Ot(t){return document.createElementNS("http://www.w3.org/1999/xhtml",t)}function zt(t){return t<.04045?.0773993808*t:Math.pow(.9478672986*t+.0521327014,2.4)}function Ut(t){return t<.0031308?12.92*t:1.055*Math.pow(t,.41666)-.055}const Bt={[lt]:{[ct]:zt},[ct]:{[lt]:Ut}},Ft={legacyMode:!0,get workingColorSpace(){return ct},set workingColorSpace(t){console.warn("THREE.ColorManagement: .workingColorSpace is readonly.")},convert:function(t,e,i){if(this.legacyMode||e===i||!e||!i)return t;if(Bt[e]&&void 0!==Bt[e][i]){const n=Bt[e][i];return t.r=n(t.r),t.g=n(t.g),t.b=n(t.b),t}throw new Error("Unsupported color space conversion.")},fromWorkingColorSpace:function(t,e){return this.convert(t,this.workingColorSpace,e)},toWorkingColorSpace:function(t,e){return this.convert(t,e,this.workingColorSpace)}},kt={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074},Gt={r:0,g:0,b:0},Vt={h:0,s:0,l:0},Ht={h:0,s:0,l:0};function Wt(t,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+6*(e-t)*(2/3-i):t}function jt(t,e){return e.r=t.r,e.g=t.g,e.b=t.b,e}class qt{constructor(t,e,i){return this.isColor=!0,this.r=1,this.g=1,this.b=1,void 0===e&&void 0===i?this.set(t):this.setRGB(t,e,i)}set(t){return t&&t.isColor?this.copy(t):"number"==typeof t?this.setHex(t):"string"==typeof t&&this.setStyle(t),this}setScalar(t){return this.r=t,this.g=t,this.b=t,this}setHex(t,e="srgb"){return t=Math.floor(t),this.r=(t>>16&255)/255,this.g=(t>>8&255)/255,this.b=(255&t)/255,Ft.toWorkingColorSpace(this,e),this}setRGB(t,e,i,n=Ft.workingColorSpace){return this.r=t,this.g=e,this.b=i,Ft.toWorkingColorSpace(this,n),this}setHSL(t,e,i,n=Ft.workingColorSpace){if(t=Mt(t,1),e=yt(e,0,1),i=yt(i,0,1),0===e)this.r=this.g=this.b=i;else{const n=i<=.5?i*(1+e):i+e-i*e,r=2*i-n;this.r=Wt(r,n,t+1/3),this.g=Wt(r,n,t),this.b=Wt(r,n,t-1/3)}return Ft.toWorkingColorSpace(this,n),this}setStyle(t,e="srgb"){function i(e){void 0!==e&&parseFloat(e)<1&&console.warn("THREE.Color: Alpha component of "+t+" will be ignored.")}let n;if(n=/^((?:rgb|hsl)a?)\(([^\)]*)\)/.exec(t)){let t;const r=n[1],s=n[2];switch(r){case"rgb":case"rgba":if(t=/^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(s))return this.r=Math.min(255,parseInt(t[1],10))/255,this.g=Math.min(255,parseInt(t[2],10))/255,this.b=Math.min(255,parseInt(t[3],10))/255,Ft.toWorkingColorSpace(this,e),i(t[4]),this;if(t=/^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(s))return this.r=Math.min(100,parseInt(t[1],10))/100,this.g=Math.min(100,parseInt(t[2],10))/100,this.b=Math.min(100,parseInt(t[3],10))/100,Ft.toWorkingColorSpace(this,e),i(t[4]),this;break;case"hsl":case"hsla":if(t=/^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(s)){const n=parseFloat(t[1])/360,r=parseFloat(t[2])/100,s=parseFloat(t[3])/100;return i(t[4]),this.setHSL(n,r,s,e)}}}else if(n=/^\#([A-Fa-f\d]+)$/.exec(t)){const t=n[1],i=t.length;if(3===i)return this.r=parseInt(t.charAt(0)+t.charAt(0),16)/255,this.g=parseInt(t.charAt(1)+t.charAt(1),16)/255,this.b=parseInt(t.charAt(2)+t.charAt(2),16)/255,Ft.toWorkingColorSpace(this,e),this;if(6===i)return this.r=parseInt(t.charAt(0)+t.charAt(1),16)/255,this.g=parseInt(t.charAt(2)+t.charAt(3),16)/255,this.b=parseInt(t.charAt(4)+t.charAt(5),16)/255,Ft.toWorkingColorSpace(this,e),this}return t&&t.length>0?this.setColorName(t,e):this}setColorName(t,e="srgb"){const i=kt[t.toLowerCase()];return void 0!==i?this.setHex(i,e):console.warn("THREE.Color: Unknown color "+t),this}clone(){return new this.constructor(this.r,this.g,this.b)}copy(t){return this.r=t.r,this.g=t.g,this.b=t.b,this}copySRGBToLinear(t){return this.r=zt(t.r),this.g=zt(t.g),this.b=zt(t.b),this}copyLinearToSRGB(t){return this.r=Ut(t.r),this.g=Ut(t.g),this.b=Ut(t.b),this}convertSRGBToLinear(){return this.copySRGBToLinear(this),this}convertLinearToSRGB(){return this.copyLinearToSRGB(this),this}getHex(t="srgb"){return Ft.fromWorkingColorSpace(jt(this,Gt),t),yt(255*Gt.r,0,255)<<16^yt(255*Gt.g,0,255)<<8^yt(255*Gt.b,0,255)<<0}getHexString(t="srgb"){return("000000"+this.getHex(t).toString(16)).slice(-6)}getHSL(t,e=Ft.workingColorSpace){Ft.fromWorkingColorSpace(jt(this,Gt),e);const i=Gt.r,n=Gt.g,r=Gt.b,s=Math.max(i,n,r),a=Math.min(i,n,r);let o,l;const c=(a+s)/2;if(a===s)o=0,l=0;else{const t=s-a;switch(l=c<=.5?t/(s+a):t/(2-s-a),s){case i:o=(n-r)/t+(n2048||e.height>2048?(console.warn("THREE.ImageUtils.getDataURL: Image converted to jpg for performance reasons",t),e.toDataURL("image/jpeg",.6)):e.toDataURL("image/png")}static sRGBToLinear(t){if("undefined"!=typeof HTMLImageElement&&t instanceof HTMLImageElement||"undefined"!=typeof HTMLCanvasElement&&t instanceof HTMLCanvasElement||"undefined"!=typeof ImageBitmap&&t instanceof ImageBitmap){const e=Ot("canvas");e.width=t.width,e.height=t.height;const i=e.getContext("2d");i.drawImage(t,0,0,t.width,t.height);const n=i.getImageData(0,0,t.width,t.height),r=n.data;for(let t=0;t1)switch(this.wrapS){case c:t.x=t.x-Math.floor(t.x);break;case h:t.x=t.x<0?0:1;break;case u:1===Math.abs(Math.floor(t.x)%2)?t.x=Math.ceil(t.x)-t.x:t.x=t.x-Math.floor(t.x)}if(t.y<0||t.y>1)switch(this.wrapT){case c:t.y=t.y-Math.floor(t.y);break;case h:t.y=t.y<0?0:1;break;case u:1===Math.abs(Math.floor(t.y)%2)?t.y=Math.ceil(t.y)-t.y:t.y=t.y-Math.floor(t.y)}return this.flipY&&(t.y=1-t.y),t}set needsUpdate(t){!0===t&&(this.version++,this.source.needsUpdate=!0)}}$t.DEFAULT_IMAGE=null,$t.DEFAULT_MAPPING=n,$t.DEFAULT_ANISOTROPY=1;class Qt{constructor(t=0,e=0,i=0,n=1){Qt.prototype.isVector4=!0,this.x=t,this.y=e,this.z=i,this.w=n}get width(){return this.z}set width(t){this.z=t}get height(){return this.w}set height(t){this.w=t}set(t,e,i,n){return this.x=t,this.y=e,this.z=i,this.w=n,this}setScalar(t){return this.x=t,this.y=t,this.z=t,this.w=t,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setZ(t){return this.z=t,this}setW(t){return this.w=t,this}setComponent(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;case 2:this.z=e;break;case 3:this.w=e;break;default:throw new Error("index is out of range: "+t)}return this}getComponent(t){switch(t){case 0:return this.x;case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw new Error("index is out of range: "+t)}}clone(){return new this.constructor(this.x,this.y,this.z,this.w)}copy(t){return this.x=t.x,this.y=t.y,this.z=t.z,this.w=void 0!==t.w?t.w:1,this}add(t){return this.x+=t.x,this.y+=t.y,this.z+=t.z,this.w+=t.w,this}addScalar(t){return this.x+=t,this.y+=t,this.z+=t,this.w+=t,this}addVectors(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this.z=t.z+e.z,this.w=t.w+e.w,this}addScaledVector(t,e){return this.x+=t.x*e,this.y+=t.y*e,this.z+=t.z*e,this.w+=t.w*e,this}sub(t){return this.x-=t.x,this.y-=t.y,this.z-=t.z,this.w-=t.w,this}subScalar(t){return this.x-=t,this.y-=t,this.z-=t,this.w-=t,this}subVectors(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this.z=t.z-e.z,this.w=t.w-e.w,this}multiply(t){return this.x*=t.x,this.y*=t.y,this.z*=t.z,this.w*=t.w,this}multiplyScalar(t){return this.x*=t,this.y*=t,this.z*=t,this.w*=t,this}applyMatrix4(t){const e=this.x,i=this.y,n=this.z,r=this.w,s=t.elements;return this.x=s[0]*e+s[4]*i+s[8]*n+s[12]*r,this.y=s[1]*e+s[5]*i+s[9]*n+s[13]*r,this.z=s[2]*e+s[6]*i+s[10]*n+s[14]*r,this.w=s[3]*e+s[7]*i+s[11]*n+s[15]*r,this}divideScalar(t){return this.multiplyScalar(1/t)}setAxisAngleFromQuaternion(t){this.w=2*Math.acos(t.w);const e=Math.sqrt(1-t.w*t.w);return e<1e-4?(this.x=1,this.y=0,this.z=0):(this.x=t.x/e,this.y=t.y/e,this.z=t.z/e),this}setAxisAngleFromRotationMatrix(t){let e,i,n,r;const s=.01,a=.1,o=t.elements,l=o[0],c=o[4],h=o[8],u=o[1],d=o[5],p=o[9],m=o[2],f=o[6],g=o[10];if(Math.abs(c-u)o&&t>v?tv?o=0?1:-1,n=1-e*e;if(n>Number.EPSILON){const r=Math.sqrt(n),s=Math.atan2(r,e*i);t=Math.sin(t*s)/r,a=Math.sin(a*s)/r}const r=a*i;if(o=o*t+u*r,l=l*t+d*r,c=c*t+p*r,h=h*t+m*r,t===1-a){const t=1/Math.sqrt(o*o+l*l+c*c+h*h);o*=t,l*=t,c*=t,h*=t}}t[e]=o,t[e+1]=l,t[e+2]=c,t[e+3]=h}static multiplyQuaternionsFlat(t,e,i,n,r,s){const a=i[n],o=i[n+1],l=i[n+2],c=i[n+3],h=r[s],u=r[s+1],d=r[s+2],p=r[s+3];return t[e]=a*p+c*h+o*d-l*u,t[e+1]=o*p+c*u+l*h-a*d,t[e+2]=l*p+c*d+a*u-o*h,t[e+3]=c*p-a*h-o*u-l*d,t}get x(){return this._x}set x(t){this._x=t,this._onChangeCallback()}get y(){return this._y}set y(t){this._y=t,this._onChangeCallback()}get z(){return this._z}set z(t){this._z=t,this._onChangeCallback()}get w(){return this._w}set w(t){this._w=t,this._onChangeCallback()}set(t,e,i,n){return this._x=t,this._y=e,this._z=i,this._w=n,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._w)}copy(t){return this._x=t.x,this._y=t.y,this._z=t.z,this._w=t.w,this._onChangeCallback(),this}setFromEuler(t,e){const i=t._x,n=t._y,r=t._z,s=t._order,a=Math.cos,o=Math.sin,l=a(i/2),c=a(n/2),h=a(r/2),u=o(i/2),d=o(n/2),p=o(r/2);switch(s){case"XYZ":this._x=u*c*h+l*d*p,this._y=l*d*h-u*c*p,this._z=l*c*p+u*d*h,this._w=l*c*h-u*d*p;break;case"YXZ":this._x=u*c*h+l*d*p,this._y=l*d*h-u*c*p,this._z=l*c*p-u*d*h,this._w=l*c*h+u*d*p;break;case"ZXY":this._x=u*c*h-l*d*p,this._y=l*d*h+u*c*p,this._z=l*c*p+u*d*h,this._w=l*c*h-u*d*p;break;case"ZYX":this._x=u*c*h-l*d*p,this._y=l*d*h+u*c*p,this._z=l*c*p-u*d*h,this._w=l*c*h+u*d*p;break;case"YZX":this._x=u*c*h+l*d*p,this._y=l*d*h+u*c*p,this._z=l*c*p-u*d*h,this._w=l*c*h-u*d*p;break;case"XZY":this._x=u*c*h-l*d*p,this._y=l*d*h-u*c*p,this._z=l*c*p+u*d*h,this._w=l*c*h+u*d*p;break;default:console.warn("THREE.Quaternion: .setFromEuler() encountered an unknown order: "+s)}return!1!==e&&this._onChangeCallback(),this}setFromAxisAngle(t,e){const i=e/2,n=Math.sin(i);return this._x=t.x*n,this._y=t.y*n,this._z=t.z*n,this._w=Math.cos(i),this._onChangeCallback(),this}setFromRotationMatrix(t){const e=t.elements,i=e[0],n=e[4],r=e[8],s=e[1],a=e[5],o=e[9],l=e[2],c=e[6],h=e[10],u=i+a+h;if(u>0){const t=.5/Math.sqrt(u+1);this._w=.25/t,this._x=(c-o)*t,this._y=(r-l)*t,this._z=(s-n)*t}else if(i>a&&i>h){const t=2*Math.sqrt(1+i-a-h);this._w=(c-o)/t,this._x=.25*t,this._y=(n+s)/t,this._z=(r+l)/t}else if(a>h){const t=2*Math.sqrt(1+a-i-h);this._w=(r-l)/t,this._x=(n+s)/t,this._y=.25*t,this._z=(o+c)/t}else{const t=2*Math.sqrt(1+h-i-a);this._w=(s-n)/t,this._x=(r+l)/t,this._y=(o+c)/t,this._z=.25*t}return this._onChangeCallback(),this}setFromUnitVectors(t,e){let i=t.dot(e)+1;return iMath.abs(t.z)?(this._x=-t.y,this._y=t.x,this._z=0,this._w=i):(this._x=0,this._y=-t.z,this._z=t.y,this._w=i)):(this._x=t.y*e.z-t.z*e.y,this._y=t.z*e.x-t.x*e.z,this._z=t.x*e.y-t.y*e.x,this._w=i),this.normalize()}angleTo(t){return 2*Math.acos(Math.abs(yt(this.dot(t),-1,1)))}rotateTowards(t,e){const i=this.angleTo(t);if(0===i)return this;const n=Math.min(1,e/i);return this.slerp(t,n),this}identity(){return this.set(0,0,0,1)}invert(){return this.conjugate()}conjugate(){return this._x*=-1,this._y*=-1,this._z*=-1,this._onChangeCallback(),this}dot(t){return this._x*t._x+this._y*t._y+this._z*t._z+this._w*t._w}lengthSq(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w}length(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)}normalize(){let t=this.length();return 0===t?(this._x=0,this._y=0,this._z=0,this._w=1):(t=1/t,this._x=this._x*t,this._y=this._y*t,this._z=this._z*t,this._w=this._w*t),this._onChangeCallback(),this}multiply(t){return this.multiplyQuaternions(this,t)}premultiply(t){return this.multiplyQuaternions(t,this)}multiplyQuaternions(t,e){const i=t._x,n=t._y,r=t._z,s=t._w,a=e._x,o=e._y,l=e._z,c=e._w;return this._x=i*c+s*a+n*l-r*o,this._y=n*c+s*o+r*a-i*l,this._z=r*c+s*l+i*o-n*a,this._w=s*c-i*a-n*o-r*l,this._onChangeCallback(),this}slerp(t,e){if(0===e)return this;if(1===e)return this.copy(t);const i=this._x,n=this._y,r=this._z,s=this._w;let a=s*t._w+i*t._x+n*t._y+r*t._z;if(a<0?(this._w=-t._w,this._x=-t._x,this._y=-t._y,this._z=-t._z,a=-a):this.copy(t),a>=1)return this._w=s,this._x=i,this._y=n,this._z=r,this;const o=1-a*a;if(o<=Number.EPSILON){const t=1-e;return this._w=t*s+e*this._w,this._x=t*i+e*this._x,this._y=t*n+e*this._y,this._z=t*r+e*this._z,this.normalize(),this._onChangeCallback(),this}const l=Math.sqrt(o),c=Math.atan2(l,a),h=Math.sin((1-e)*c)/l,u=Math.sin(e*c)/l;return this._w=s*h+this._w*u,this._x=i*h+this._x*u,this._y=n*h+this._y*u,this._z=r*h+this._z*u,this._onChangeCallback(),this}slerpQuaternions(t,e,i){return this.copy(t).slerp(e,i)}random(){const t=Math.random(),e=Math.sqrt(1-t),i=Math.sqrt(t),n=2*Math.PI*Math.random(),r=2*Math.PI*Math.random();return this.set(e*Math.cos(n),i*Math.sin(r),i*Math.cos(r),e*Math.sin(n))}equals(t){return t._x===this._x&&t._y===this._y&&t._z===this._z&&t._w===this._w}fromArray(t,e=0){return this._x=t[e],this._y=t[e+1],this._z=t[e+2],this._w=t[e+3],this._onChangeCallback(),this}toArray(t=[],e=0){return t[e]=this._x,t[e+1]=this._y,t[e+2]=this._z,t[e+3]=this._w,t}fromBufferAttribute(t,e){return this._x=t.getX(e),this._y=t.getY(e),this._z=t.getZ(e),this._w=t.getW(e),this}_onChange(t){return this._onChangeCallback=t,this}_onChangeCallback(){}*[Symbol.iterator](){yield this._x,yield this._y,yield this._z,yield this._w}}class re{constructor(t=0,e=0,i=0){re.prototype.isVector3=!0,this.x=t,this.y=e,this.z=i}set(t,e,i){return void 0===i&&(i=this.z),this.x=t,this.y=e,this.z=i,this}setScalar(t){return this.x=t,this.y=t,this.z=t,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setZ(t){return this.z=t,this}setComponent(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;case 2:this.z=e;break;default:throw new Error("index is out of range: "+t)}return this}getComponent(t){switch(t){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw new Error("index is out of range: "+t)}}clone(){return new this.constructor(this.x,this.y,this.z)}copy(t){return this.x=t.x,this.y=t.y,this.z=t.z,this}add(t){return this.x+=t.x,this.y+=t.y,this.z+=t.z,this}addScalar(t){return this.x+=t,this.y+=t,this.z+=t,this}addVectors(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this.z=t.z+e.z,this}addScaledVector(t,e){return this.x+=t.x*e,this.y+=t.y*e,this.z+=t.z*e,this}sub(t){return this.x-=t.x,this.y-=t.y,this.z-=t.z,this}subScalar(t){return this.x-=t,this.y-=t,this.z-=t,this}subVectors(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this.z=t.z-e.z,this}multiply(t){return this.x*=t.x,this.y*=t.y,this.z*=t.z,this}multiplyScalar(t){return this.x*=t,this.y*=t,this.z*=t,this}multiplyVectors(t,e){return this.x=t.x*e.x,this.y=t.y*e.y,this.z=t.z*e.z,this}applyEuler(t){return this.applyQuaternion(ae.setFromEuler(t))}applyAxisAngle(t,e){return this.applyQuaternion(ae.setFromAxisAngle(t,e))}applyMatrix3(t){const e=this.x,i=this.y,n=this.z,r=t.elements;return this.x=r[0]*e+r[3]*i+r[6]*n,this.y=r[1]*e+r[4]*i+r[7]*n,this.z=r[2]*e+r[5]*i+r[8]*n,this}applyNormalMatrix(t){return this.applyMatrix3(t).normalize()}applyMatrix4(t){const e=this.x,i=this.y,n=this.z,r=t.elements,s=1/(r[3]*e+r[7]*i+r[11]*n+r[15]);return this.x=(r[0]*e+r[4]*i+r[8]*n+r[12])*s,this.y=(r[1]*e+r[5]*i+r[9]*n+r[13])*s,this.z=(r[2]*e+r[6]*i+r[10]*n+r[14])*s,this}applyQuaternion(t){const e=this.x,i=this.y,n=this.z,r=t.x,s=t.y,a=t.z,o=t.w,l=o*e+s*n-a*i,c=o*i+a*e-r*n,h=o*n+r*i-s*e,u=-r*e-s*i-a*n;return this.x=l*o+u*-r+c*-a-h*-s,this.y=c*o+u*-s+h*-r-l*-a,this.z=h*o+u*-a+l*-s-c*-r,this}project(t){return this.applyMatrix4(t.matrixWorldInverse).applyMatrix4(t.projectionMatrix)}unproject(t){return this.applyMatrix4(t.projectionMatrixInverse).applyMatrix4(t.matrixWorld)}transformDirection(t){const e=this.x,i=this.y,n=this.z,r=t.elements;return this.x=r[0]*e+r[4]*i+r[8]*n,this.y=r[1]*e+r[5]*i+r[9]*n,this.z=r[2]*e+r[6]*i+r[10]*n,this.normalize()}divide(t){return this.x/=t.x,this.y/=t.y,this.z/=t.z,this}divideScalar(t){return this.multiplyScalar(1/t)}min(t){return this.x=Math.min(this.x,t.x),this.y=Math.min(this.y,t.y),this.z=Math.min(this.z,t.z),this}max(t){return this.x=Math.max(this.x,t.x),this.y=Math.max(this.y,t.y),this.z=Math.max(this.z,t.z),this}clamp(t,e){return this.x=Math.max(t.x,Math.min(e.x,this.x)),this.y=Math.max(t.y,Math.min(e.y,this.y)),this.z=Math.max(t.z,Math.min(e.z,this.z)),this}clampScalar(t,e){return this.x=Math.max(t,Math.min(e,this.x)),this.y=Math.max(t,Math.min(e,this.y)),this.z=Math.max(t,Math.min(e,this.z)),this}clampLength(t,e){const i=this.length();return this.divideScalar(i||1).multiplyScalar(Math.max(t,Math.min(e,i)))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.z=Math.floor(this.z),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=Math.ceil(this.z),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.z=Math.round(this.z),this}roundToZero(){return this.x=this.x<0?Math.ceil(this.x):Math.floor(this.x),this.y=this.y<0?Math.ceil(this.y):Math.floor(this.y),this.z=this.z<0?Math.ceil(this.z):Math.floor(this.z),this}negate(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this}dot(t){return this.x*t.x+this.y*t.y+this.z*t.z}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)}normalize(){return this.divideScalar(this.length()||1)}setLength(t){return this.normalize().multiplyScalar(t)}lerp(t,e){return this.x+=(t.x-this.x)*e,this.y+=(t.y-this.y)*e,this.z+=(t.z-this.z)*e,this}lerpVectors(t,e,i){return this.x=t.x+(e.x-t.x)*i,this.y=t.y+(e.y-t.y)*i,this.z=t.z+(e.z-t.z)*i,this}cross(t){return this.crossVectors(this,t)}crossVectors(t,e){const i=t.x,n=t.y,r=t.z,s=e.x,a=e.y,o=e.z;return this.x=n*o-r*a,this.y=r*s-i*o,this.z=i*a-n*s,this}projectOnVector(t){const e=t.lengthSq();if(0===e)return this.set(0,0,0);const i=t.dot(this)/e;return this.copy(t).multiplyScalar(i)}projectOnPlane(t){return se.copy(this).projectOnVector(t),this.sub(se)}reflect(t){return this.sub(se.copy(t).multiplyScalar(2*this.dot(t)))}angleTo(t){const e=Math.sqrt(this.lengthSq()*t.lengthSq());if(0===e)return Math.PI/2;const i=this.dot(t)/e;return Math.acos(yt(i,-1,1))}distanceTo(t){return Math.sqrt(this.distanceToSquared(t))}distanceToSquared(t){const e=this.x-t.x,i=this.y-t.y,n=this.z-t.z;return e*e+i*i+n*n}manhattanDistanceTo(t){return Math.abs(this.x-t.x)+Math.abs(this.y-t.y)+Math.abs(this.z-t.z)}setFromSpherical(t){return this.setFromSphericalCoords(t.radius,t.phi,t.theta)}setFromSphericalCoords(t,e,i){const n=Math.sin(e)*t;return this.x=n*Math.sin(i),this.y=Math.cos(e)*t,this.z=n*Math.cos(i),this}setFromCylindrical(t){return this.setFromCylindricalCoords(t.radius,t.theta,t.y)}setFromCylindricalCoords(t,e,i){return this.x=t*Math.sin(e),this.y=i,this.z=t*Math.cos(e),this}setFromMatrixPosition(t){const e=t.elements;return this.x=e[12],this.y=e[13],this.z=e[14],this}setFromMatrixScale(t){const e=this.setFromMatrixColumn(t,0).length(),i=this.setFromMatrixColumn(t,1).length(),n=this.setFromMatrixColumn(t,2).length();return this.x=e,this.y=i,this.z=n,this}setFromMatrixColumn(t,e){return this.fromArray(t.elements,4*e)}setFromMatrix3Column(t,e){return this.fromArray(t.elements,3*e)}setFromEuler(t){return this.x=t._x,this.y=t._y,this.z=t._z,this}equals(t){return t.x===this.x&&t.y===this.y&&t.z===this.z}fromArray(t,e=0){return this.x=t[e],this.y=t[e+1],this.z=t[e+2],this}toArray(t=[],e=0){return t[e]=this.x,t[e+1]=this.y,t[e+2]=this.z,t}fromBufferAttribute(t,e){return this.x=t.getX(e),this.y=t.getY(e),this.z=t.getZ(e),this}random(){return this.x=Math.random(),this.y=Math.random(),this.z=Math.random(),this}randomDirection(){const t=2*(Math.random()-.5),e=Math.random()*Math.PI*2,i=Math.sqrt(1-t**2);return this.x=i*Math.cos(e),this.y=i*Math.sin(e),this.z=t,this}*[Symbol.iterator](){yield this.x,yield this.y,yield this.z}}const se=new re,ae=new ne;class oe{constructor(t=new re(1/0,1/0,1/0),e=new re(-1/0,-1/0,-1/0)){this.isBox3=!0,this.min=t,this.max=e}set(t,e){return this.min.copy(t),this.max.copy(e),this}setFromArray(t){let e=1/0,i=1/0,n=1/0,r=-1/0,s=-1/0,a=-1/0;for(let o=0,l=t.length;or&&(r=l),c>s&&(s=c),h>a&&(a=h)}return this.min.set(e,i,n),this.max.set(r,s,a),this}setFromBufferAttribute(t){let e=1/0,i=1/0,n=1/0,r=-1/0,s=-1/0,a=-1/0;for(let o=0,l=t.count;or&&(r=l),c>s&&(s=c),h>a&&(a=h)}return this.min.set(e,i,n),this.max.set(r,s,a),this}setFromPoints(t){this.makeEmpty();for(let e=0,i=t.length;ethis.max.x||t.ythis.max.y||t.zthis.max.z)}containsBox(t){return this.min.x<=t.min.x&&t.max.x<=this.max.x&&this.min.y<=t.min.y&&t.max.y<=this.max.y&&this.min.z<=t.min.z&&t.max.z<=this.max.z}getParameter(t,e){return e.set((t.x-this.min.x)/(this.max.x-this.min.x),(t.y-this.min.y)/(this.max.y-this.min.y),(t.z-this.min.z)/(this.max.z-this.min.z))}intersectsBox(t){return!(t.max.xthis.max.x||t.max.ythis.max.y||t.max.zthis.max.z)}intersectsSphere(t){return this.clampPoint(t.center,ce),ce.distanceToSquared(t.center)<=t.radius*t.radius}intersectsPlane(t){let e,i;return t.normal.x>0?(e=t.normal.x*this.min.x,i=t.normal.x*this.max.x):(e=t.normal.x*this.max.x,i=t.normal.x*this.min.x),t.normal.y>0?(e+=t.normal.y*this.min.y,i+=t.normal.y*this.max.y):(e+=t.normal.y*this.max.y,i+=t.normal.y*this.min.y),t.normal.z>0?(e+=t.normal.z*this.min.z,i+=t.normal.z*this.max.z):(e+=t.normal.z*this.max.z,i+=t.normal.z*this.min.z),e<=-t.constant&&i>=-t.constant}intersectsTriangle(t){if(this.isEmpty())return!1;this.getCenter(ve),xe.subVectors(this.max,ve),ue.subVectors(t.a,ve),de.subVectors(t.b,ve),pe.subVectors(t.c,ve),me.subVectors(de,ue),fe.subVectors(pe,de),ge.subVectors(ue,pe);let e=[0,-me.z,me.y,0,-fe.z,fe.y,0,-ge.z,ge.y,me.z,0,-me.x,fe.z,0,-fe.x,ge.z,0,-ge.x,-me.y,me.x,0,-fe.y,fe.x,0,-ge.y,ge.x,0];return!!Me(e,ue,de,pe,xe)&&(e=[1,0,0,0,1,0,0,0,1],!!Me(e,ue,de,pe,xe)&&(_e.crossVectors(me,fe),e=[_e.x,_e.y,_e.z],Me(e,ue,de,pe,xe)))}clampPoint(t,e){return e.copy(t).clamp(this.min,this.max)}distanceToPoint(t){return ce.copy(t).clamp(this.min,this.max).sub(t).length()}getBoundingSphere(t){return this.getCenter(t.center),t.radius=.5*this.getSize(ce).length(),t}intersect(t){return this.min.max(t.min),this.max.min(t.max),this.isEmpty()&&this.makeEmpty(),this}union(t){return this.min.min(t.min),this.max.max(t.max),this}applyMatrix4(t){return this.isEmpty()||(le[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(t),le[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(t),le[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(t),le[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(t),le[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(t),le[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(t),le[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(t),le[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(t),this.setFromPoints(le)),this}translate(t){return this.min.add(t),this.max.add(t),this}equals(t){return t.min.equals(this.min)&&t.max.equals(this.max)}}const le=[new re,new re,new re,new re,new re,new re,new re,new re],ce=new re,he=new oe,ue=new re,de=new re,pe=new re,me=new re,fe=new re,ge=new re,ve=new re,xe=new re,_e=new re,ye=new re;function Me(t,e,i,n,r){for(let s=0,a=t.length-3;s<=a;s+=3){ye.fromArray(t,s);const a=r.x*Math.abs(ye.x)+r.y*Math.abs(ye.y)+r.z*Math.abs(ye.z),o=e.dot(ye),l=i.dot(ye),c=n.dot(ye);if(Math.max(-Math.max(o,l,c),Math.min(o,l,c))>a)return!1}return!0}const be=new oe,Se=new re,we=new re;class Te{constructor(t=new re,e=-1){this.center=t,this.radius=e}set(t,e){return this.center.copy(t),this.radius=e,this}setFromPoints(t,e){const i=this.center;void 0!==e?i.copy(e):be.setFromPoints(t).getCenter(i);let n=0;for(let e=0,r=t.length;ethis.radius*this.radius&&(e.sub(this.center).normalize(),e.multiplyScalar(this.radius).add(this.center)),e}getBoundingBox(t){return this.isEmpty()?(t.makeEmpty(),t):(t.set(this.center,this.center),t.expandByScalar(this.radius),t)}applyMatrix4(t){return this.center.applyMatrix4(t),this.radius=this.radius*t.getMaxScaleOnAxis(),this}translate(t){return this.center.add(t),this}expandByPoint(t){if(this.isEmpty())return this.center.copy(t),this.radius=0,this;Se.subVectors(t,this.center);const e=Se.lengthSq();if(e>this.radius*this.radius){const t=Math.sqrt(e),i=.5*(t-this.radius);this.center.addScaledVector(Se,i/t),this.radius+=i}return this}union(t){return t.isEmpty()?this:this.isEmpty()?(this.copy(t),this):(!0===this.center.equals(t.center)?this.radius=Math.max(this.radius,t.radius):(we.subVectors(t.center,this.center).setLength(t.radius),this.expandByPoint(Se.copy(t.center).add(we)),this.expandByPoint(Se.copy(t.center).sub(we))),this)}equals(t){return t.center.equals(this.center)&&t.radius===this.radius}clone(){return(new this.constructor).copy(this)}}const Ae=new re,Ee=new re,Ce=new re,Le=new re,Re=new re,Pe=new re,Ie=new re;class De{constructor(t=new re,e=new re(0,0,-1)){this.origin=t,this.direction=e}set(t,e){return this.origin.copy(t),this.direction.copy(e),this}copy(t){return this.origin.copy(t.origin),this.direction.copy(t.direction),this}at(t,e){return e.copy(this.direction).multiplyScalar(t).add(this.origin)}lookAt(t){return this.direction.copy(t).sub(this.origin).normalize(),this}recast(t){return this.origin.copy(this.at(t,Ae)),this}closestPointToPoint(t,e){e.subVectors(t,this.origin);const i=e.dot(this.direction);return i<0?e.copy(this.origin):e.copy(this.direction).multiplyScalar(i).add(this.origin)}distanceToPoint(t){return Math.sqrt(this.distanceSqToPoint(t))}distanceSqToPoint(t){const e=Ae.subVectors(t,this.origin).dot(this.direction);return e<0?this.origin.distanceToSquared(t):(Ae.copy(this.direction).multiplyScalar(e).add(this.origin),Ae.distanceToSquared(t))}distanceSqToSegment(t,e,i,n){Ee.copy(t).add(e).multiplyScalar(.5),Ce.copy(e).sub(t).normalize(),Le.copy(this.origin).sub(Ee);const r=.5*t.distanceTo(e),s=-this.direction.dot(Ce),a=Le.dot(this.direction),o=-Le.dot(Ce),l=Le.lengthSq(),c=Math.abs(1-s*s);let h,u,d,p;if(c>0)if(h=s*o-a,u=s*a-o,p=r*c,h>=0)if(u>=-p)if(u<=p){const t=1/c;h*=t,u*=t,d=h*(h+s*u+2*a)+u*(s*h+u+2*o)+l}else u=r,h=Math.max(0,-(s*u+a)),d=-h*h+u*(u+2*o)+l;else u=-r,h=Math.max(0,-(s*u+a)),d=-h*h+u*(u+2*o)+l;else u<=-p?(h=Math.max(0,-(-s*r+a)),u=h>0?-r:Math.min(Math.max(-r,-o),r),d=-h*h+u*(u+2*o)+l):u<=p?(h=0,u=Math.min(Math.max(-r,-o),r),d=u*(u+2*o)+l):(h=Math.max(0,-(s*r+a)),u=h>0?r:Math.min(Math.max(-r,-o),r),d=-h*h+u*(u+2*o)+l);else u=s>0?-r:r,h=Math.max(0,-(s*u+a)),d=-h*h+u*(u+2*o)+l;return i&&i.copy(this.direction).multiplyScalar(h).add(this.origin),n&&n.copy(Ce).multiplyScalar(u).add(Ee),d}intersectSphere(t,e){Ae.subVectors(t.center,this.origin);const i=Ae.dot(this.direction),n=Ae.dot(Ae)-i*i,r=t.radius*t.radius;if(n>r)return null;const s=Math.sqrt(r-n),a=i-s,o=i+s;return a<0&&o<0?null:a<0?this.at(o,e):this.at(a,e)}intersectsSphere(t){return this.distanceSqToPoint(t.center)<=t.radius*t.radius}distanceToPlane(t){const e=t.normal.dot(this.direction);if(0===e)return 0===t.distanceToPoint(this.origin)?0:null;const i=-(this.origin.dot(t.normal)+t.constant)/e;return i>=0?i:null}intersectPlane(t,e){const i=this.distanceToPlane(t);return null===i?null:this.at(i,e)}intersectsPlane(t){const e=t.distanceToPoint(this.origin);if(0===e)return!0;return t.normal.dot(this.direction)*e<0}intersectBox(t,e){let i,n,r,s,a,o;const l=1/this.direction.x,c=1/this.direction.y,h=1/this.direction.z,u=this.origin;return l>=0?(i=(t.min.x-u.x)*l,n=(t.max.x-u.x)*l):(i=(t.max.x-u.x)*l,n=(t.min.x-u.x)*l),c>=0?(r=(t.min.y-u.y)*c,s=(t.max.y-u.y)*c):(r=(t.max.y-u.y)*c,s=(t.min.y-u.y)*c),i>s||r>n?null:((r>i||isNaN(i))&&(i=r),(s=0?(a=(t.min.z-u.z)*h,o=(t.max.z-u.z)*h):(a=(t.max.z-u.z)*h,o=(t.min.z-u.z)*h),i>o||a>n?null:((a>i||i!=i)&&(i=a),(o=0?i:n,e)))}intersectsBox(t){return null!==this.intersectBox(t,Ae)}intersectTriangle(t,e,i,n,r){Re.subVectors(e,t),Pe.subVectors(i,t),Ie.crossVectors(Re,Pe);let s,a=this.direction.dot(Ie);if(a>0){if(n)return null;s=1}else{if(!(a<0))return null;s=-1,a=-a}Le.subVectors(this.origin,t);const o=s*this.direction.dot(Pe.crossVectors(Le,Pe));if(o<0)return null;const l=s*this.direction.dot(Re.cross(Le));if(l<0)return null;if(o+l>a)return null;const c=-s*Le.dot(Ie);return c<0?null:this.at(c/a,r)}applyMatrix4(t){return this.origin.applyMatrix4(t),this.direction.transformDirection(t),this}equals(t){return t.origin.equals(this.origin)&&t.direction.equals(this.direction)}clone(){return(new this.constructor).copy(this)}}class Ne{constructor(){Ne.prototype.isMatrix4=!0,this.elements=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]}set(t,e,i,n,r,s,a,o,l,c,h,u,d,p,m,f){const g=this.elements;return g[0]=t,g[4]=e,g[8]=i,g[12]=n,g[1]=r,g[5]=s,g[9]=a,g[13]=o,g[2]=l,g[6]=c,g[10]=h,g[14]=u,g[3]=d,g[7]=p,g[11]=m,g[15]=f,this}identity(){return this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1),this}clone(){return(new Ne).fromArray(this.elements)}copy(t){const e=this.elements,i=t.elements;return e[0]=i[0],e[1]=i[1],e[2]=i[2],e[3]=i[3],e[4]=i[4],e[5]=i[5],e[6]=i[6],e[7]=i[7],e[8]=i[8],e[9]=i[9],e[10]=i[10],e[11]=i[11],e[12]=i[12],e[13]=i[13],e[14]=i[14],e[15]=i[15],this}copyPosition(t){const e=this.elements,i=t.elements;return e[12]=i[12],e[13]=i[13],e[14]=i[14],this}setFromMatrix3(t){const e=t.elements;return this.set(e[0],e[3],e[6],0,e[1],e[4],e[7],0,e[2],e[5],e[8],0,0,0,0,1),this}extractBasis(t,e,i){return t.setFromMatrixColumn(this,0),e.setFromMatrixColumn(this,1),i.setFromMatrixColumn(this,2),this}makeBasis(t,e,i){return this.set(t.x,e.x,i.x,0,t.y,e.y,i.y,0,t.z,e.z,i.z,0,0,0,0,1),this}extractRotation(t){const e=this.elements,i=t.elements,n=1/Oe.setFromMatrixColumn(t,0).length(),r=1/Oe.setFromMatrixColumn(t,1).length(),s=1/Oe.setFromMatrixColumn(t,2).length();return e[0]=i[0]*n,e[1]=i[1]*n,e[2]=i[2]*n,e[3]=0,e[4]=i[4]*r,e[5]=i[5]*r,e[6]=i[6]*r,e[7]=0,e[8]=i[8]*s,e[9]=i[9]*s,e[10]=i[10]*s,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,this}makeRotationFromEuler(t){const e=this.elements,i=t.x,n=t.y,r=t.z,s=Math.cos(i),a=Math.sin(i),o=Math.cos(n),l=Math.sin(n),c=Math.cos(r),h=Math.sin(r);if("XYZ"===t.order){const t=s*c,i=s*h,n=a*c,r=a*h;e[0]=o*c,e[4]=-o*h,e[8]=l,e[1]=i+n*l,e[5]=t-r*l,e[9]=-a*o,e[2]=r-t*l,e[6]=n+i*l,e[10]=s*o}else if("YXZ"===t.order){const t=o*c,i=o*h,n=l*c,r=l*h;e[0]=t+r*a,e[4]=n*a-i,e[8]=s*l,e[1]=s*h,e[5]=s*c,e[9]=-a,e[2]=i*a-n,e[6]=r+t*a,e[10]=s*o}else if("ZXY"===t.order){const t=o*c,i=o*h,n=l*c,r=l*h;e[0]=t-r*a,e[4]=-s*h,e[8]=n+i*a,e[1]=i+n*a,e[5]=s*c,e[9]=r-t*a,e[2]=-s*l,e[6]=a,e[10]=s*o}else if("ZYX"===t.order){const t=s*c,i=s*h,n=a*c,r=a*h;e[0]=o*c,e[4]=n*l-i,e[8]=t*l+r,e[1]=o*h,e[5]=r*l+t,e[9]=i*l-n,e[2]=-l,e[6]=a*o,e[10]=s*o}else if("YZX"===t.order){const t=s*o,i=s*l,n=a*o,r=a*l;e[0]=o*c,e[4]=r-t*h,e[8]=n*h+i,e[1]=h,e[5]=s*c,e[9]=-a*c,e[2]=-l*c,e[6]=i*h+n,e[10]=t-r*h}else if("XZY"===t.order){const t=s*o,i=s*l,n=a*o,r=a*l;e[0]=o*c,e[4]=-h,e[8]=l*c,e[1]=t*h+r,e[5]=s*c,e[9]=i*h-n,e[2]=n*h-i,e[6]=a*c,e[10]=r*h+t}return e[3]=0,e[7]=0,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,this}makeRotationFromQuaternion(t){return this.compose(Ue,t,Be)}lookAt(t,e,i){const n=this.elements;return Ge.subVectors(t,e),0===Ge.lengthSq()&&(Ge.z=1),Ge.normalize(),Fe.crossVectors(i,Ge),0===Fe.lengthSq()&&(1===Math.abs(i.z)?Ge.x+=1e-4:Ge.z+=1e-4,Ge.normalize(),Fe.crossVectors(i,Ge)),Fe.normalize(),ke.crossVectors(Ge,Fe),n[0]=Fe.x,n[4]=ke.x,n[8]=Ge.x,n[1]=Fe.y,n[5]=ke.y,n[9]=Ge.y,n[2]=Fe.z,n[6]=ke.z,n[10]=Ge.z,this}multiply(t){return this.multiplyMatrices(this,t)}premultiply(t){return this.multiplyMatrices(t,this)}multiplyMatrices(t,e){const i=t.elements,n=e.elements,r=this.elements,s=i[0],a=i[4],o=i[8],l=i[12],c=i[1],h=i[5],u=i[9],d=i[13],p=i[2],m=i[6],f=i[10],g=i[14],v=i[3],x=i[7],_=i[11],y=i[15],M=n[0],b=n[4],S=n[8],w=n[12],T=n[1],A=n[5],E=n[9],C=n[13],L=n[2],R=n[6],P=n[10],I=n[14],D=n[3],N=n[7],O=n[11],z=n[15];return r[0]=s*M+a*T+o*L+l*D,r[4]=s*b+a*A+o*R+l*N,r[8]=s*S+a*E+o*P+l*O,r[12]=s*w+a*C+o*I+l*z,r[1]=c*M+h*T+u*L+d*D,r[5]=c*b+h*A+u*R+d*N,r[9]=c*S+h*E+u*P+d*O,r[13]=c*w+h*C+u*I+d*z,r[2]=p*M+m*T+f*L+g*D,r[6]=p*b+m*A+f*R+g*N,r[10]=p*S+m*E+f*P+g*O,r[14]=p*w+m*C+f*I+g*z,r[3]=v*M+x*T+_*L+y*D,r[7]=v*b+x*A+_*R+y*N,r[11]=v*S+x*E+_*P+y*O,r[15]=v*w+x*C+_*I+y*z,this}multiplyScalar(t){const e=this.elements;return e[0]*=t,e[4]*=t,e[8]*=t,e[12]*=t,e[1]*=t,e[5]*=t,e[9]*=t,e[13]*=t,e[2]*=t,e[6]*=t,e[10]*=t,e[14]*=t,e[3]*=t,e[7]*=t,e[11]*=t,e[15]*=t,this}determinant(){const t=this.elements,e=t[0],i=t[4],n=t[8],r=t[12],s=t[1],a=t[5],o=t[9],l=t[13],c=t[2],h=t[6],u=t[10],d=t[14];return t[3]*(+r*o*h-n*l*h-r*a*u+i*l*u+n*a*d-i*o*d)+t[7]*(+e*o*d-e*l*u+r*s*u-n*s*d+n*l*c-r*o*c)+t[11]*(+e*l*h-e*a*d-r*s*h+i*s*d+r*a*c-i*l*c)+t[15]*(-n*a*c-e*o*h+e*a*u+n*s*h-i*s*u+i*o*c)}transpose(){const t=this.elements;let e;return e=t[1],t[1]=t[4],t[4]=e,e=t[2],t[2]=t[8],t[8]=e,e=t[6],t[6]=t[9],t[9]=e,e=t[3],t[3]=t[12],t[12]=e,e=t[7],t[7]=t[13],t[13]=e,e=t[11],t[11]=t[14],t[14]=e,this}setPosition(t,e,i){const n=this.elements;return t.isVector3?(n[12]=t.x,n[13]=t.y,n[14]=t.z):(n[12]=t,n[13]=e,n[14]=i),this}invert(){const t=this.elements,e=t[0],i=t[1],n=t[2],r=t[3],s=t[4],a=t[5],o=t[6],l=t[7],c=t[8],h=t[9],u=t[10],d=t[11],p=t[12],m=t[13],f=t[14],g=t[15],v=h*f*l-m*u*l+m*o*d-a*f*d-h*o*g+a*u*g,x=p*u*l-c*f*l-p*o*d+s*f*d+c*o*g-s*u*g,_=c*m*l-p*h*l+p*a*d-s*m*d-c*a*g+s*h*g,y=p*h*o-c*m*o-p*a*u+s*m*u+c*a*f-s*h*f,M=e*v+i*x+n*_+r*y;if(0===M)return this.set(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);const b=1/M;return t[0]=v*b,t[1]=(m*u*r-h*f*r-m*n*d+i*f*d+h*n*g-i*u*g)*b,t[2]=(a*f*r-m*o*r+m*n*l-i*f*l-a*n*g+i*o*g)*b,t[3]=(h*o*r-a*u*r-h*n*l+i*u*l+a*n*d-i*o*d)*b,t[4]=x*b,t[5]=(c*f*r-p*u*r+p*n*d-e*f*d-c*n*g+e*u*g)*b,t[6]=(p*o*r-s*f*r-p*n*l+e*f*l+s*n*g-e*o*g)*b,t[7]=(s*u*r-c*o*r+c*n*l-e*u*l-s*n*d+e*o*d)*b,t[8]=_*b,t[9]=(p*h*r-c*m*r-p*i*d+e*m*d+c*i*g-e*h*g)*b,t[10]=(s*m*r-p*a*r+p*i*l-e*m*l-s*i*g+e*a*g)*b,t[11]=(c*a*r-s*h*r-c*i*l+e*h*l+s*i*d-e*a*d)*b,t[12]=y*b,t[13]=(c*m*n-p*h*n+p*i*u-e*m*u-c*i*f+e*h*f)*b,t[14]=(p*a*n-s*m*n-p*i*o+e*m*o+s*i*f-e*a*f)*b,t[15]=(s*h*n-c*a*n+c*i*o-e*h*o-s*i*u+e*a*u)*b,this}scale(t){const e=this.elements,i=t.x,n=t.y,r=t.z;return e[0]*=i,e[4]*=n,e[8]*=r,e[1]*=i,e[5]*=n,e[9]*=r,e[2]*=i,e[6]*=n,e[10]*=r,e[3]*=i,e[7]*=n,e[11]*=r,this}getMaxScaleOnAxis(){const t=this.elements,e=t[0]*t[0]+t[1]*t[1]+t[2]*t[2],i=t[4]*t[4]+t[5]*t[5]+t[6]*t[6],n=t[8]*t[8]+t[9]*t[9]+t[10]*t[10];return Math.sqrt(Math.max(e,i,n))}makeTranslation(t,e,i){return this.set(1,0,0,t,0,1,0,e,0,0,1,i,0,0,0,1),this}makeRotationX(t){const e=Math.cos(t),i=Math.sin(t);return this.set(1,0,0,0,0,e,-i,0,0,i,e,0,0,0,0,1),this}makeRotationY(t){const e=Math.cos(t),i=Math.sin(t);return this.set(e,0,i,0,0,1,0,0,-i,0,e,0,0,0,0,1),this}makeRotationZ(t){const e=Math.cos(t),i=Math.sin(t);return this.set(e,-i,0,0,i,e,0,0,0,0,1,0,0,0,0,1),this}makeRotationAxis(t,e){const i=Math.cos(e),n=Math.sin(e),r=1-i,s=t.x,a=t.y,o=t.z,l=r*s,c=r*a;return this.set(l*s+i,l*a-n*o,l*o+n*a,0,l*a+n*o,c*a+i,c*o-n*s,0,l*o-n*a,c*o+n*s,r*o*o+i,0,0,0,0,1),this}makeScale(t,e,i){return this.set(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1),this}makeShear(t,e,i,n,r,s){return this.set(1,i,r,0,t,1,s,0,e,n,1,0,0,0,0,1),this}compose(t,e,i){const n=this.elements,r=e._x,s=e._y,a=e._z,o=e._w,l=r+r,c=s+s,h=a+a,u=r*l,d=r*c,p=r*h,m=s*c,f=s*h,g=a*h,v=o*l,x=o*c,_=o*h,y=i.x,M=i.y,b=i.z;return n[0]=(1-(m+g))*y,n[1]=(d+_)*y,n[2]=(p-x)*y,n[3]=0,n[4]=(d-_)*M,n[5]=(1-(u+g))*M,n[6]=(f+v)*M,n[7]=0,n[8]=(p+x)*b,n[9]=(f-v)*b,n[10]=(1-(u+m))*b,n[11]=0,n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=1,this}decompose(t,e,i){const n=this.elements;let r=Oe.set(n[0],n[1],n[2]).length();const s=Oe.set(n[4],n[5],n[6]).length(),a=Oe.set(n[8],n[9],n[10]).length();this.determinant()<0&&(r=-r),t.x=n[12],t.y=n[13],t.z=n[14],ze.copy(this);const o=1/r,l=1/s,c=1/a;return ze.elements[0]*=o,ze.elements[1]*=o,ze.elements[2]*=o,ze.elements[4]*=l,ze.elements[5]*=l,ze.elements[6]*=l,ze.elements[8]*=c,ze.elements[9]*=c,ze.elements[10]*=c,e.setFromRotationMatrix(ze),i.x=r,i.y=s,i.z=a,this}makePerspective(t,e,i,n,r,s){const a=this.elements,o=2*r/(e-t),l=2*r/(i-n),c=(e+t)/(e-t),h=(i+n)/(i-n),u=-(s+r)/(s-r),d=-2*s*r/(s-r);return a[0]=o,a[4]=0,a[8]=c,a[12]=0,a[1]=0,a[5]=l,a[9]=h,a[13]=0,a[2]=0,a[6]=0,a[10]=u,a[14]=d,a[3]=0,a[7]=0,a[11]=-1,a[15]=0,this}makeOrthographic(t,e,i,n,r,s){const a=this.elements,o=1/(e-t),l=1/(i-n),c=1/(s-r),h=(e+t)*o,u=(i+n)*l,d=(s+r)*c;return a[0]=2*o,a[4]=0,a[8]=0,a[12]=-h,a[1]=0,a[5]=2*l,a[9]=0,a[13]=-u,a[2]=0,a[6]=0,a[10]=-2*c,a[14]=-d,a[3]=0,a[7]=0,a[11]=0,a[15]=1,this}equals(t){const e=this.elements,i=t.elements;for(let t=0;t<16;t++)if(e[t]!==i[t])return!1;return!0}fromArray(t,e=0){for(let i=0;i<16;i++)this.elements[i]=t[i+e];return this}toArray(t=[],e=0){const i=this.elements;return t[e]=i[0],t[e+1]=i[1],t[e+2]=i[2],t[e+3]=i[3],t[e+4]=i[4],t[e+5]=i[5],t[e+6]=i[6],t[e+7]=i[7],t[e+8]=i[8],t[e+9]=i[9],t[e+10]=i[10],t[e+11]=i[11],t[e+12]=i[12],t[e+13]=i[13],t[e+14]=i[14],t[e+15]=i[15],t}}const Oe=new re,ze=new Ne,Ue=new re(0,0,0),Be=new re(1,1,1),Fe=new re,ke=new re,Ge=new re,Ve=new Ne,He=new ne;class We{constructor(t=0,e=0,i=0,n=We.DefaultOrder){this.isEuler=!0,this._x=t,this._y=e,this._z=i,this._order=n}get x(){return this._x}set x(t){this._x=t,this._onChangeCallback()}get y(){return this._y}set y(t){this._y=t,this._onChangeCallback()}get z(){return this._z}set z(t){this._z=t,this._onChangeCallback()}get order(){return this._order}set order(t){this._order=t,this._onChangeCallback()}set(t,e,i,n=this._order){return this._x=t,this._y=e,this._z=i,this._order=n,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._order)}copy(t){return this._x=t._x,this._y=t._y,this._z=t._z,this._order=t._order,this._onChangeCallback(),this}setFromRotationMatrix(t,e=this._order,i=!0){const n=t.elements,r=n[0],s=n[4],a=n[8],o=n[1],l=n[5],c=n[9],h=n[2],u=n[6],d=n[10];switch(e){case"XYZ":this._y=Math.asin(yt(a,-1,1)),Math.abs(a)<.9999999?(this._x=Math.atan2(-c,d),this._z=Math.atan2(-s,r)):(this._x=Math.atan2(u,l),this._z=0);break;case"YXZ":this._x=Math.asin(-yt(c,-1,1)),Math.abs(c)<.9999999?(this._y=Math.atan2(a,d),this._z=Math.atan2(o,l)):(this._y=Math.atan2(-h,r),this._z=0);break;case"ZXY":this._x=Math.asin(yt(u,-1,1)),Math.abs(u)<.9999999?(this._y=Math.atan2(-h,d),this._z=Math.atan2(-s,l)):(this._y=0,this._z=Math.atan2(o,r));break;case"ZYX":this._y=Math.asin(-yt(h,-1,1)),Math.abs(h)<.9999999?(this._x=Math.atan2(u,d),this._z=Math.atan2(o,r)):(this._x=0,this._z=Math.atan2(-s,l));break;case"YZX":this._z=Math.asin(yt(o,-1,1)),Math.abs(o)<.9999999?(this._x=Math.atan2(-c,l),this._y=Math.atan2(-h,r)):(this._x=0,this._y=Math.atan2(a,d));break;case"XZY":this._z=Math.asin(-yt(s,-1,1)),Math.abs(s)<.9999999?(this._x=Math.atan2(u,l),this._y=Math.atan2(a,r)):(this._x=Math.atan2(-c,d),this._y=0);break;default:console.warn("THREE.Euler: .setFromRotationMatrix() encountered an unknown order: "+e)}return this._order=e,!0===i&&this._onChangeCallback(),this}setFromQuaternion(t,e,i){return Ve.makeRotationFromQuaternion(t),this.setFromRotationMatrix(Ve,e,i)}setFromVector3(t,e=this._order){return this.set(t.x,t.y,t.z,e)}reorder(t){return He.setFromEuler(this),this.setFromQuaternion(He,t)}equals(t){return t._x===this._x&&t._y===this._y&&t._z===this._z&&t._order===this._order}fromArray(t){return this._x=t[0],this._y=t[1],this._z=t[2],void 0!==t[3]&&(this._order=t[3]),this._onChangeCallback(),this}toArray(t=[],e=0){return t[e]=this._x,t[e+1]=this._y,t[e+2]=this._z,t[e+3]=this._order,t}_onChange(t){return this._onChangeCallback=t,this}_onChangeCallback(){}*[Symbol.iterator](){yield this._x,yield this._y,yield this._z,yield this._order}toVector3(){console.error("THREE.Euler: .toVector3() has been removed. Use Vector3.setFromEuler() instead")}}We.DefaultOrder="XYZ",We.RotationOrders=["XYZ","YZX","ZXY","XZY","YXZ","ZYX"];class je{constructor(){this.mask=1}set(t){this.mask=(1<>>0}enable(t){this.mask|=1<1){for(let t=0;t1){for(let t=0;t0){n.children=[];for(let e=0;e0){n.animations=[];for(let e=0;e0&&(i.geometries=e),n.length>0&&(i.materials=n),r.length>0&&(i.textures=r),a.length>0&&(i.images=a),o.length>0&&(i.shapes=o),l.length>0&&(i.skeletons=l),c.length>0&&(i.animations=c),h.length>0&&(i.nodes=h)}return i.object=n,i;function s(t){const e=[];for(const i in t){const n=t[i];delete n.metadata,e.push(n)}return e}}clone(t){return(new this.constructor).copy(this,t)}copy(t,e=!0){if(this.name=t.name,this.up.copy(t.up),this.position.copy(t.position),this.rotation.order=t.rotation.order,this.quaternion.copy(t.quaternion),this.scale.copy(t.scale),this.matrix.copy(t.matrix),this.matrixWorld.copy(t.matrixWorld),this.matrixAutoUpdate=t.matrixAutoUpdate,this.matrixWorldNeedsUpdate=t.matrixWorldNeedsUpdate,this.matrixWorldAutoUpdate=t.matrixWorldAutoUpdate,this.layers.mask=t.layers.mask,this.visible=t.visible,this.castShadow=t.castShadow,this.receiveShadow=t.receiveShadow,this.frustumCulled=t.frustumCulled,this.renderOrder=t.renderOrder,this.userData=JSON.parse(JSON.stringify(t.userData)),!0===e)for(let e=0;e0?n.multiplyScalar(1/Math.sqrt(r)):n.set(0,0,0)}static getBarycoord(t,e,i,n,r){ai.subVectors(n,e),oi.subVectors(i,e),li.subVectors(t,e);const s=ai.dot(ai),a=ai.dot(oi),o=ai.dot(li),l=oi.dot(oi),c=oi.dot(li),h=s*l-a*a;if(0===h)return r.set(-2,-1,-1);const u=1/h,d=(l*o-a*c)*u,p=(s*c-a*o)*u;return r.set(1-d-p,p,d)}static containsPoint(t,e,i,n){return this.getBarycoord(t,e,i,n,ci),ci.x>=0&&ci.y>=0&&ci.x+ci.y<=1}static getUV(t,e,i,n,r,s,a,o){return this.getBarycoord(t,e,i,n,ci),o.set(0,0),o.addScaledVector(r,ci.x),o.addScaledVector(s,ci.y),o.addScaledVector(a,ci.z),o}static isFrontFacing(t,e,i,n){return ai.subVectors(i,e),oi.subVectors(t,e),ai.cross(oi).dot(n)<0}set(t,e,i){return this.a.copy(t),this.b.copy(e),this.c.copy(i),this}setFromPointsAndIndices(t,e,i,n){return this.a.copy(t[e]),this.b.copy(t[i]),this.c.copy(t[n]),this}setFromAttributeAndIndices(t,e,i,n){return this.a.fromBufferAttribute(t,e),this.b.fromBufferAttribute(t,i),this.c.fromBufferAttribute(t,n),this}clone(){return(new this.constructor).copy(this)}copy(t){return this.a.copy(t.a),this.b.copy(t.b),this.c.copy(t.c),this}getArea(){return ai.subVectors(this.c,this.b),oi.subVectors(this.a,this.b),.5*ai.cross(oi).length()}getMidpoint(t){return t.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)}getNormal(t){return gi.getNormal(this.a,this.b,this.c,t)}getPlane(t){return t.setFromCoplanarPoints(this.a,this.b,this.c)}getBarycoord(t,e){return gi.getBarycoord(t,this.a,this.b,this.c,e)}getUV(t,e,i,n,r){return gi.getUV(t,this.a,this.b,this.c,e,i,n,r)}containsPoint(t){return gi.containsPoint(t,this.a,this.b,this.c)}isFrontFacing(t){return gi.isFrontFacing(this.a,this.b,this.c,t)}intersectsBox(t){return t.intersectsTriangle(this)}closestPointToPoint(t,e){const i=this.a,n=this.b,r=this.c;let s,a;hi.subVectors(n,i),ui.subVectors(r,i),pi.subVectors(t,i);const o=hi.dot(pi),l=ui.dot(pi);if(o<=0&&l<=0)return e.copy(i);mi.subVectors(t,n);const c=hi.dot(mi),h=ui.dot(mi);if(c>=0&&h<=c)return e.copy(n);const u=o*h-c*l;if(u<=0&&o>=0&&c<=0)return s=o/(o-c),e.copy(i).addScaledVector(hi,s);fi.subVectors(t,r);const d=hi.dot(fi),p=ui.dot(fi);if(p>=0&&d<=p)return e.copy(r);const m=d*l-o*p;if(m<=0&&l>=0&&p<=0)return a=l/(l-p),e.copy(i).addScaledVector(ui,a);const f=c*p-d*h;if(f<=0&&h-c>=0&&d-p>=0)return di.subVectors(r,n),a=(h-c)/(h-c+(d-p)),e.copy(n).addScaledVector(di,a);const g=1/(f+m+u);return s=m*g,a=u*g,e.copy(i).addScaledVector(hi,s).addScaledVector(ui,a)}equals(t){return t.a.equals(this.a)&&t.b.equals(this.b)&&t.c.equals(this.c)}}let vi=0;class xi extends mt{constructor(){super(),this.isMaterial=!0,Object.defineProperty(this,"id",{value:vi++}),this.uuid=_t(),this.name="",this.type="Material",this.blending=1,this.side=0,this.vertexColors=!1,this.opacity=1,this.transparent=!1,this.blendSrc=204,this.blendDst=205,this.blendEquation=i,this.blendSrcAlpha=null,this.blendDstAlpha=null,this.blendEquationAlpha=null,this.depthFunc=3,this.depthTest=!0,this.depthWrite=!0,this.stencilWriteMask=255,this.stencilFunc=519,this.stencilRef=0,this.stencilFuncMask=255,this.stencilFail=ht,this.stencilZFail=ht,this.stencilZPass=ht,this.stencilWrite=!1,this.clippingPlanes=null,this.clipIntersection=!1,this.clipShadows=!1,this.shadowSide=null,this.colorWrite=!0,this.precision=null,this.polygonOffset=!1,this.polygonOffsetFactor=0,this.polygonOffsetUnits=0,this.dithering=!1,this.alphaToCoverage=!1,this.premultipliedAlpha=!1,this.visible=!0,this.toneMapped=!0,this.userData={},this.version=0,this._alphaTest=0}get alphaTest(){return this._alphaTest}set alphaTest(t){this._alphaTest>0!=t>0&&this.version++,this._alphaTest=t}onBuild(){}onBeforeRender(){}onBeforeCompile(){}customProgramCacheKey(){return this.onBeforeCompile.toString()}setValues(t){if(void 0!==t)for(const e in t){const i=t[e];if(void 0===i){console.warn("THREE.Material: '"+e+"' parameter is undefined.");continue}const n=this[e];void 0!==n?n&&n.isColor?n.set(i):n&&n.isVector3&&i&&i.isVector3?n.copy(i):this[e]=i:console.warn("THREE."+this.type+": '"+e+"' is not a property of this material.")}}toJSON(t){const e=void 0===t||"string"==typeof t;e&&(t={textures:{},images:{}});const i={metadata:{version:4.5,type:"Material",generator:"Material.toJSON"}};function n(t){const e=[];for(const i in t){const n=t[i];delete n.metadata,e.push(n)}return e}if(i.uuid=this.uuid,i.type=this.type,""!==this.name&&(i.name=this.name),this.color&&this.color.isColor&&(i.color=this.color.getHex()),void 0!==this.roughness&&(i.roughness=this.roughness),void 0!==this.metalness&&(i.metalness=this.metalness),void 0!==this.sheen&&(i.sheen=this.sheen),this.sheenColor&&this.sheenColor.isColor&&(i.sheenColor=this.sheenColor.getHex()),void 0!==this.sheenRoughness&&(i.sheenRoughness=this.sheenRoughness),this.emissive&&this.emissive.isColor&&(i.emissive=this.emissive.getHex()),this.emissiveIntensity&&1!==this.emissiveIntensity&&(i.emissiveIntensity=this.emissiveIntensity),this.specular&&this.specular.isColor&&(i.specular=this.specular.getHex()),void 0!==this.specularIntensity&&(i.specularIntensity=this.specularIntensity),this.specularColor&&this.specularColor.isColor&&(i.specularColor=this.specularColor.getHex()),void 0!==this.shininess&&(i.shininess=this.shininess),void 0!==this.clearcoat&&(i.clearcoat=this.clearcoat),void 0!==this.clearcoatRoughness&&(i.clearcoatRoughness=this.clearcoatRoughness),this.clearcoatMap&&this.clearcoatMap.isTexture&&(i.clearcoatMap=this.clearcoatMap.toJSON(t).uuid),this.clearcoatRoughnessMap&&this.clearcoatRoughnessMap.isTexture&&(i.clearcoatRoughnessMap=this.clearcoatRoughnessMap.toJSON(t).uuid),this.clearcoatNormalMap&&this.clearcoatNormalMap.isTexture&&(i.clearcoatNormalMap=this.clearcoatNormalMap.toJSON(t).uuid,i.clearcoatNormalScale=this.clearcoatNormalScale.toArray()),void 0!==this.iridescence&&(i.iridescence=this.iridescence),void 0!==this.iridescenceIOR&&(i.iridescenceIOR=this.iridescenceIOR),void 0!==this.iridescenceThicknessRange&&(i.iridescenceThicknessRange=this.iridescenceThicknessRange),this.iridescenceMap&&this.iridescenceMap.isTexture&&(i.iridescenceMap=this.iridescenceMap.toJSON(t).uuid),this.iridescenceThicknessMap&&this.iridescenceThicknessMap.isTexture&&(i.iridescenceThicknessMap=this.iridescenceThicknessMap.toJSON(t).uuid),this.map&&this.map.isTexture&&(i.map=this.map.toJSON(t).uuid),this.matcap&&this.matcap.isTexture&&(i.matcap=this.matcap.toJSON(t).uuid),this.alphaMap&&this.alphaMap.isTexture&&(i.alphaMap=this.alphaMap.toJSON(t).uuid),this.lightMap&&this.lightMap.isTexture&&(i.lightMap=this.lightMap.toJSON(t).uuid,i.lightMapIntensity=this.lightMapIntensity),this.aoMap&&this.aoMap.isTexture&&(i.aoMap=this.aoMap.toJSON(t).uuid,i.aoMapIntensity=this.aoMapIntensity),this.bumpMap&&this.bumpMap.isTexture&&(i.bumpMap=this.bumpMap.toJSON(t).uuid,i.bumpScale=this.bumpScale),this.normalMap&&this.normalMap.isTexture&&(i.normalMap=this.normalMap.toJSON(t).uuid,i.normalMapType=this.normalMapType,i.normalScale=this.normalScale.toArray()),this.displacementMap&&this.displacementMap.isTexture&&(i.displacementMap=this.displacementMap.toJSON(t).uuid,i.displacementScale=this.displacementScale,i.displacementBias=this.displacementBias),this.roughnessMap&&this.roughnessMap.isTexture&&(i.roughnessMap=this.roughnessMap.toJSON(t).uuid),this.metalnessMap&&this.metalnessMap.isTexture&&(i.metalnessMap=this.metalnessMap.toJSON(t).uuid),this.emissiveMap&&this.emissiveMap.isTexture&&(i.emissiveMap=this.emissiveMap.toJSON(t).uuid),this.specularMap&&this.specularMap.isTexture&&(i.specularMap=this.specularMap.toJSON(t).uuid),this.specularIntensityMap&&this.specularIntensityMap.isTexture&&(i.specularIntensityMap=this.specularIntensityMap.toJSON(t).uuid),this.specularColorMap&&this.specularColorMap.isTexture&&(i.specularColorMap=this.specularColorMap.toJSON(t).uuid),this.envMap&&this.envMap.isTexture&&(i.envMap=this.envMap.toJSON(t).uuid,void 0!==this.combine&&(i.combine=this.combine)),void 0!==this.envMapIntensity&&(i.envMapIntensity=this.envMapIntensity),void 0!==this.reflectivity&&(i.reflectivity=this.reflectivity),void 0!==this.refractionRatio&&(i.refractionRatio=this.refractionRatio),this.gradientMap&&this.gradientMap.isTexture&&(i.gradientMap=this.gradientMap.toJSON(t).uuid),void 0!==this.transmission&&(i.transmission=this.transmission),this.transmissionMap&&this.transmissionMap.isTexture&&(i.transmissionMap=this.transmissionMap.toJSON(t).uuid),void 0!==this.thickness&&(i.thickness=this.thickness),this.thicknessMap&&this.thicknessMap.isTexture&&(i.thicknessMap=this.thicknessMap.toJSON(t).uuid),void 0!==this.attenuationDistance&&this.attenuationDistance!==1/0&&(i.attenuationDistance=this.attenuationDistance),void 0!==this.attenuationColor&&(i.attenuationColor=this.attenuationColor.getHex()),void 0!==this.size&&(i.size=this.size),null!==this.shadowSide&&(i.shadowSide=this.shadowSide),void 0!==this.sizeAttenuation&&(i.sizeAttenuation=this.sizeAttenuation),1!==this.blending&&(i.blending=this.blending),0!==this.side&&(i.side=this.side),this.vertexColors&&(i.vertexColors=!0),this.opacity<1&&(i.opacity=this.opacity),!0===this.transparent&&(i.transparent=this.transparent),i.depthFunc=this.depthFunc,i.depthTest=this.depthTest,i.depthWrite=this.depthWrite,i.colorWrite=this.colorWrite,i.stencilWrite=this.stencilWrite,i.stencilWriteMask=this.stencilWriteMask,i.stencilFunc=this.stencilFunc,i.stencilRef=this.stencilRef,i.stencilFuncMask=this.stencilFuncMask,i.stencilFail=this.stencilFail,i.stencilZFail=this.stencilZFail,i.stencilZPass=this.stencilZPass,void 0!==this.rotation&&0!==this.rotation&&(i.rotation=this.rotation),!0===this.polygonOffset&&(i.polygonOffset=!0),0!==this.polygonOffsetFactor&&(i.polygonOffsetFactor=this.polygonOffsetFactor),0!==this.polygonOffsetUnits&&(i.polygonOffsetUnits=this.polygonOffsetUnits),void 0!==this.linewidth&&1!==this.linewidth&&(i.linewidth=this.linewidth),void 0!==this.dashSize&&(i.dashSize=this.dashSize),void 0!==this.gapSize&&(i.gapSize=this.gapSize),void 0!==this.scale&&(i.scale=this.scale),!0===this.dithering&&(i.dithering=!0),this.alphaTest>0&&(i.alphaTest=this.alphaTest),!0===this.alphaToCoverage&&(i.alphaToCoverage=this.alphaToCoverage),!0===this.premultipliedAlpha&&(i.premultipliedAlpha=this.premultipliedAlpha),!0===this.wireframe&&(i.wireframe=this.wireframe),this.wireframeLinewidth>1&&(i.wireframeLinewidth=this.wireframeLinewidth),"round"!==this.wireframeLinecap&&(i.wireframeLinecap=this.wireframeLinecap),"round"!==this.wireframeLinejoin&&(i.wireframeLinejoin=this.wireframeLinejoin),!0===this.flatShading&&(i.flatShading=this.flatShading),!1===this.visible&&(i.visible=!1),!1===this.toneMapped&&(i.toneMapped=!1),!1===this.fog&&(i.fog=!1),"{}"!==JSON.stringify(this.userData)&&(i.userData=this.userData),e){const e=n(t.textures),r=n(t.images);e.length>0&&(i.textures=e),r.length>0&&(i.images=r)}return i}clone(){return(new this.constructor).copy(this)}copy(t){this.name=t.name,this.blending=t.blending,this.side=t.side,this.vertexColors=t.vertexColors,this.opacity=t.opacity,this.transparent=t.transparent,this.blendSrc=t.blendSrc,this.blendDst=t.blendDst,this.blendEquation=t.blendEquation,this.blendSrcAlpha=t.blendSrcAlpha,this.blendDstAlpha=t.blendDstAlpha,this.blendEquationAlpha=t.blendEquationAlpha,this.depthFunc=t.depthFunc,this.depthTest=t.depthTest,this.depthWrite=t.depthWrite,this.stencilWriteMask=t.stencilWriteMask,this.stencilFunc=t.stencilFunc,this.stencilRef=t.stencilRef,this.stencilFuncMask=t.stencilFuncMask,this.stencilFail=t.stencilFail,this.stencilZFail=t.stencilZFail,this.stencilZPass=t.stencilZPass,this.stencilWrite=t.stencilWrite;const e=t.clippingPlanes;let i=null;if(null!==e){const t=e.length;i=new Array(t);for(let n=0;n!==t;++n)i[n]=e[n].clone()}return this.clippingPlanes=i,this.clipIntersection=t.clipIntersection,this.clipShadows=t.clipShadows,this.shadowSide=t.shadowSide,this.colorWrite=t.colorWrite,this.precision=t.precision,this.polygonOffset=t.polygonOffset,this.polygonOffsetFactor=t.polygonOffsetFactor,this.polygonOffsetUnits=t.polygonOffsetUnits,this.dithering=t.dithering,this.alphaTest=t.alphaTest,this.alphaToCoverage=t.alphaToCoverage,this.premultipliedAlpha=t.premultipliedAlpha,this.visible=t.visible,this.toneMapped=t.toneMapped,this.userData=JSON.parse(JSON.stringify(t.userData)),this}dispose(){this.dispatchEvent({type:"dispose"})}set needsUpdate(t){!0===t&&this.version++}}class _i extends xi{constructor(t){super(),this.isMeshBasicMaterial=!0,this.type="MeshBasicMaterial",this.color=new qt(16777215),this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.combine=0,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.specularMap=t.specularMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.combine=t.combine,this.reflectivity=t.reflectivity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.fog=t.fog,this}}const yi=new re,Mi=new Lt;class bi{constructor(t,e,i){if(Array.isArray(t))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.isBufferAttribute=!0,this.name="",this.array=t,this.itemSize=e,this.count=void 0!==t?t.length/e:0,this.normalized=!0===i,this.usage=ut,this.updateRange={offset:0,count:-1},this.version=0}onUploadCallback(){}set needsUpdate(t){!0===t&&this.version++}setUsage(t){return this.usage=t,this}copy(t){return this.name=t.name,this.array=new t.array.constructor(t.array),this.itemSize=t.itemSize,this.count=t.count,this.normalized=t.normalized,this.usage=t.usage,this}copyAt(t,e,i){t*=this.itemSize,i*=e.itemSize;for(let n=0,r=this.itemSize;n0&&(t.userData=this.userData),void 0!==this.parameters){const e=this.parameters;for(const i in e)void 0!==e[i]&&(t[i]=e[i]);return t}t.data={attributes:{}};const e=this.index;null!==e&&(t.data.index={type:e.array.constructor.name,array:Array.prototype.slice.call(e.array)});const i=this.attributes;for(const e in i){const n=i[e];t.data.attributes[e]=n.toJSON(t.data)}const n={};let r=!1;for(const e in this.morphAttributes){const i=this.morphAttributes[e],s=[];for(let e=0,n=i.length;e0&&(n[e]=s,r=!0)}r&&(t.data.morphAttributes=n,t.data.morphTargetsRelative=this.morphTargetsRelative);const s=this.groups;s.length>0&&(t.data.groups=JSON.parse(JSON.stringify(s)));const a=this.boundingSphere;return null!==a&&(t.data.boundingSphere={center:a.center.toArray(),radius:a.radius}),t}clone(){return(new this.constructor).copy(this)}copy(t){this.index=null,this.attributes={},this.morphAttributes={},this.groups=[],this.boundingBox=null,this.boundingSphere=null;const e={};this.name=t.name;const i=t.index;null!==i&&this.setIndex(i.clone(e));const n=t.attributes;for(const t in n){const i=n[t];this.setAttribute(t,i.clone(e))}const r=t.morphAttributes;for(const t in r){const i=[],n=r[t];for(let t=0,r=n.length;t0){const i=t[e[0]];if(void 0!==i){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let t=0,e=i.length;ti.far?null:{distance:c,point:Ji.clone(),object:t}}(t,e,i,n,Ui,Bi,Fi,Zi);if(p){o&&(qi.fromBufferAttribute(o,c),Xi.fromBufferAttribute(o,h),Yi.fromBufferAttribute(o,u),p.uv=gi.getUV(Zi,Ui,Bi,Fi,qi,Xi,Yi,new Lt)),l&&(qi.fromBufferAttribute(l,c),Xi.fromBufferAttribute(l,h),Yi.fromBufferAttribute(l,u),p.uv2=gi.getUV(Zi,Ui,Bi,Fi,qi,Xi,Yi,new Lt));const t={a:c,b:h,c:u,normal:new re,materialIndex:0};gi.getNormal(Ui,Bi,Fi,t.normal),p.face=t}return p}class Qi extends Di{constructor(t=1,e=1,i=1,n=1,r=1,s=1){super(),this.type="BoxGeometry",this.parameters={width:t,height:e,depth:i,widthSegments:n,heightSegments:r,depthSegments:s};const a=this;n=Math.floor(n),r=Math.floor(r),s=Math.floor(s);const o=[],l=[],c=[],h=[];let u=0,d=0;function p(t,e,i,n,r,s,p,m,f,g,v){const x=s/f,_=p/g,y=s/2,M=p/2,b=m/2,S=f+1,w=g+1;let T=0,A=0;const E=new re;for(let s=0;s0?1:-1,c.push(E.x,E.y,E.z),h.push(o/f),h.push(1-s/g),T+=1}}for(let t=0;t0&&(e.defines=this.defines),e.vertexShader=this.vertexShader,e.fragmentShader=this.fragmentShader;const i={};for(const t in this.extensions)!0===this.extensions[t]&&(i[t]=!0);return Object.keys(i).length>0&&(e.extensions=i),e}}class an extends si{constructor(){super(),this.isCamera=!0,this.type="Camera",this.matrixWorldInverse=new Ne,this.projectionMatrix=new Ne,this.projectionMatrixInverse=new Ne}copy(t,e){return super.copy(t,e),this.matrixWorldInverse.copy(t.matrixWorldInverse),this.projectionMatrix.copy(t.projectionMatrix),this.projectionMatrixInverse.copy(t.projectionMatrixInverse),this}getWorldDirection(t){this.updateWorldMatrix(!0,!1);const e=this.matrixWorld.elements;return t.set(-e[8],-e[9],-e[10]).normalize()}updateMatrixWorld(t){super.updateMatrixWorld(t),this.matrixWorldInverse.copy(this.matrixWorld).invert()}updateWorldMatrix(t,e){super.updateWorldMatrix(t,e),this.matrixWorldInverse.copy(this.matrixWorld).invert()}clone(){return(new this.constructor).copy(this)}}class on extends an{constructor(t=50,e=1,i=.1,n=2e3){super(),this.isPerspectiveCamera=!0,this.type="PerspectiveCamera",this.fov=t,this.zoom=1,this.near=i,this.far=n,this.focus=10,this.aspect=e,this.view=null,this.filmGauge=35,this.filmOffset=0,this.updateProjectionMatrix()}copy(t,e){return super.copy(t,e),this.fov=t.fov,this.zoom=t.zoom,this.near=t.near,this.far=t.far,this.focus=t.focus,this.aspect=t.aspect,this.view=null===t.view?null:Object.assign({},t.view),this.filmGauge=t.filmGauge,this.filmOffset=t.filmOffset,this}setFocalLength(t){const e=.5*this.getFilmHeight()/t;this.fov=2*xt*Math.atan(e),this.updateProjectionMatrix()}getFocalLength(){const t=Math.tan(.5*vt*this.fov);return.5*this.getFilmHeight()/t}getEffectiveFOV(){return 2*xt*Math.atan(Math.tan(.5*vt*this.fov)/this.zoom)}getFilmWidth(){return this.filmGauge*Math.min(this.aspect,1)}getFilmHeight(){return this.filmGauge/Math.max(this.aspect,1)}setViewOffset(t,e,i,n,r,s){this.aspect=t/e,null===this.view&&(this.view={enabled:!0,fullWidth:1,fullHeight:1,offsetX:0,offsetY:0,width:1,height:1}),this.view.enabled=!0,this.view.fullWidth=t,this.view.fullHeight=e,this.view.offsetX=i,this.view.offsetY=n,this.view.width=r,this.view.height=s,this.updateProjectionMatrix()}clearViewOffset(){null!==this.view&&(this.view.enabled=!1),this.updateProjectionMatrix()}updateProjectionMatrix(){const t=this.near;let e=t*Math.tan(.5*vt*this.fov)/this.zoom,i=2*e,n=this.aspect*i,r=-.5*n;const s=this.view;if(null!==this.view&&this.view.enabled){const t=s.fullWidth,a=s.fullHeight;r+=s.offsetX*n/t,e-=s.offsetY*i/a,n*=s.width/t,i*=s.height/a}const a=this.filmOffset;0!==a&&(r+=t*a/this.getFilmWidth()),this.projectionMatrix.makePerspective(r,r+n,e,e-i,t,this.far),this.projectionMatrixInverse.copy(this.projectionMatrix).invert()}toJSON(t){const e=super.toJSON(t);return e.object.fov=this.fov,e.object.zoom=this.zoom,e.object.near=this.near,e.object.far=this.far,e.object.focus=this.focus,e.object.aspect=this.aspect,null!==this.view&&(e.object.view=Object.assign({},this.view)),e.object.filmGauge=this.filmGauge,e.object.filmOffset=this.filmOffset,e}}const ln=-90;class cn extends si{constructor(t,e,i){super(),this.type="CubeCamera",this.renderTarget=i;const n=new on(ln,1,t,e);n.layers=this.layers,n.up.set(0,1,0),n.lookAt(1,0,0),this.add(n);const r=new on(ln,1,t,e);r.layers=this.layers,r.up.set(0,1,0),r.lookAt(-1,0,0),this.add(r);const s=new on(ln,1,t,e);s.layers=this.layers,s.up.set(0,0,-1),s.lookAt(0,1,0),this.add(s);const a=new on(ln,1,t,e);a.layers=this.layers,a.up.set(0,0,1),a.lookAt(0,-1,0),this.add(a);const o=new on(ln,1,t,e);o.layers=this.layers,o.up.set(0,1,0),o.lookAt(0,0,1),this.add(o);const l=new on(ln,1,t,e);l.layers=this.layers,l.up.set(0,1,0),l.lookAt(0,0,-1),this.add(l)}update(t,e){null===this.parent&&this.updateMatrixWorld();const i=this.renderTarget,[n,r,s,a,o,l]=this.children,c=t.getRenderTarget(),h=t.toneMapping,u=t.xr.enabled;t.toneMapping=0,t.xr.enabled=!1;const d=i.texture.generateMipmaps;i.texture.generateMipmaps=!1,t.setRenderTarget(i,0),t.render(e,n),t.setRenderTarget(i,1),t.render(e,r),t.setRenderTarget(i,2),t.render(e,s),t.setRenderTarget(i,3),t.render(e,a),t.setRenderTarget(i,4),t.render(e,o),i.texture.generateMipmaps=d,t.setRenderTarget(i,5),t.render(e,l),t.setRenderTarget(c),t.toneMapping=h,t.xr.enabled=u,i.texture.needsPMREMUpdate=!0}}class hn extends $t{constructor(t,e,i,n,s,a,o,l,c,h){super(t=void 0!==t?t:[],e=void 0!==e?e:r,i,n,s,a,o,l,c,h),this.isCubeTexture=!0,this.flipY=!1}get images(){return this.image}set images(t){this.image=t}}class un extends te{constructor(t=1,e={}){super(t,t,e),this.isWebGLCubeRenderTarget=!0;const i={width:t,height:t,depth:1},n=[i,i,i,i,i,i];this.texture=new hn(n,e.mapping,e.wrapS,e.wrapT,e.magFilter,e.minFilter,e.format,e.type,e.anisotropy,e.encoding),this.texture.isRenderTargetTexture=!0,this.texture.generateMipmaps=void 0!==e.generateMipmaps&&e.generateMipmaps,this.texture.minFilter=void 0!==e.minFilter?e.minFilter:f}fromEquirectangularTexture(t,e){this.texture.type=e.type,this.texture.encoding=e.encoding,this.texture.generateMipmaps=e.generateMipmaps,this.texture.minFilter=e.minFilter,this.texture.magFilter=e.magFilter;const i={uniforms:{tEquirect:{value:null}},vertexShader:"\n\n\t\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t\tvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\n\t\t\t\t\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvWorldDirection = transformDirection( position, modelMatrix );\n\n\t\t\t\t\t#include \n\t\t\t\t\t#include \n\n\t\t\t\t}\n\t\t\t",fragmentShader:"\n\n\t\t\t\tuniform sampler2D tEquirect;\n\n\t\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t\t#include \n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvec3 direction = normalize( vWorldDirection );\n\n\t\t\t\t\tvec2 sampleUV = equirectUv( direction );\n\n\t\t\t\t\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\n\t\t\t\t}\n\t\t\t"},n=new Qi(5,5,5),r=new sn({name:"CubemapFromEquirect",uniforms:tn(i.uniforms),vertexShader:i.vertexShader,fragmentShader:i.fragmentShader,side:1,blending:0});r.uniforms.tEquirect.value=e;const s=new Ki(n,r),a=e.minFilter;e.minFilter===v&&(e.minFilter=f);return new cn(1,10,this).update(t,s),e.minFilter=a,s.geometry.dispose(),s.material.dispose(),this}clear(t,e,i,n){const r=t.getRenderTarget();for(let r=0;r<6;r++)t.setRenderTarget(this,r),t.clear(e,i,n);t.setRenderTarget(r)}}const dn=new re,pn=new re,mn=new Rt;class fn{constructor(t=new re(1,0,0),e=0){this.isPlane=!0,this.normal=t,this.constant=e}set(t,e){return this.normal.copy(t),this.constant=e,this}setComponents(t,e,i,n){return this.normal.set(t,e,i),this.constant=n,this}setFromNormalAndCoplanarPoint(t,e){return this.normal.copy(t),this.constant=-e.dot(this.normal),this}setFromCoplanarPoints(t,e,i){const n=dn.subVectors(i,e).cross(pn.subVectors(t,e)).normalize();return this.setFromNormalAndCoplanarPoint(n,t),this}copy(t){return this.normal.copy(t.normal),this.constant=t.constant,this}normalize(){const t=1/this.normal.length();return this.normal.multiplyScalar(t),this.constant*=t,this}negate(){return this.constant*=-1,this.normal.negate(),this}distanceToPoint(t){return this.normal.dot(t)+this.constant}distanceToSphere(t){return this.distanceToPoint(t.center)-t.radius}projectPoint(t,e){return e.copy(this.normal).multiplyScalar(-this.distanceToPoint(t)).add(t)}intersectLine(t,e){const i=t.delta(dn),n=this.normal.dot(i);if(0===n)return 0===this.distanceToPoint(t.start)?e.copy(t.start):null;const r=-(t.start.dot(this.normal)+this.constant)/n;return r<0||r>1?null:e.copy(i).multiplyScalar(r).add(t.start)}intersectsLine(t){const e=this.distanceToPoint(t.start),i=this.distanceToPoint(t.end);return e<0&&i>0||i<0&&e>0}intersectsBox(t){return t.intersectsPlane(this)}intersectsSphere(t){return t.intersectsPlane(this)}coplanarPoint(t){return t.copy(this.normal).multiplyScalar(-this.constant)}applyMatrix4(t,e){const i=e||mn.getNormalMatrix(t),n=this.coplanarPoint(dn).applyMatrix4(t),r=this.normal.applyMatrix3(i).normalize();return this.constant=-n.dot(r),this}translate(t){return this.constant-=t.dot(this.normal),this}equals(t){return t.normal.equals(this.normal)&&t.constant===this.constant}clone(){return(new this.constructor).copy(this)}}const gn=new Te,vn=new re;class xn{constructor(t=new fn,e=new fn,i=new fn,n=new fn,r=new fn,s=new fn){this.planes=[t,e,i,n,r,s]}set(t,e,i,n,r,s){const a=this.planes;return a[0].copy(t),a[1].copy(e),a[2].copy(i),a[3].copy(n),a[4].copy(r),a[5].copy(s),this}copy(t){const e=this.planes;for(let i=0;i<6;i++)e[i].copy(t.planes[i]);return this}setFromProjectionMatrix(t){const e=this.planes,i=t.elements,n=i[0],r=i[1],s=i[2],a=i[3],o=i[4],l=i[5],c=i[6],h=i[7],u=i[8],d=i[9],p=i[10],m=i[11],f=i[12],g=i[13],v=i[14],x=i[15];return e[0].setComponents(a-n,h-o,m-u,x-f).normalize(),e[1].setComponents(a+n,h+o,m+u,x+f).normalize(),e[2].setComponents(a+r,h+l,m+d,x+g).normalize(),e[3].setComponents(a-r,h-l,m-d,x-g).normalize(),e[4].setComponents(a-s,h-c,m-p,x-v).normalize(),e[5].setComponents(a+s,h+c,m+p,x+v).normalize(),this}intersectsObject(t){const e=t.geometry;return null===e.boundingSphere&&e.computeBoundingSphere(),gn.copy(e.boundingSphere).applyMatrix4(t.matrixWorld),this.intersectsSphere(gn)}intersectsSprite(t){return gn.center.set(0,0,0),gn.radius=.7071067811865476,gn.applyMatrix4(t.matrixWorld),this.intersectsSphere(gn)}intersectsSphere(t){const e=this.planes,i=t.center,n=-t.radius;for(let t=0;t<6;t++){if(e[t].distanceToPoint(i)0?t.max.x:t.min.x,vn.y=n.normal.y>0?t.max.y:t.min.y,vn.z=n.normal.z>0?t.max.z:t.min.z,n.distanceToPoint(vn)<0)return!1}return!0}containsPoint(t){const e=this.planes;for(let i=0;i<6;i++)if(e[i].distanceToPoint(t)<0)return!1;return!0}clone(){return(new this.constructor).copy(this)}}function _n(){let t=null,e=!1,i=null,n=null;function r(e,s){i(e,s),n=t.requestAnimationFrame(r)}return{start:function(){!0!==e&&null!==i&&(n=t.requestAnimationFrame(r),e=!0)},stop:function(){t.cancelAnimationFrame(n),e=!1},setAnimationLoop:function(t){i=t},setContext:function(e){t=e}}}function yn(t,e){const i=e.isWebGL2,n=new WeakMap;return{get:function(t){return t.isInterleavedBufferAttribute&&(t=t.data),n.get(t)},remove:function(e){e.isInterleavedBufferAttribute&&(e=e.data);const i=n.get(e);i&&(t.deleteBuffer(i.buffer),n.delete(e))},update:function(e,r){if(e.isGLBufferAttribute){const t=n.get(e);return void((!t||t.version 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}\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_BlinnPhong( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, 1.0, dotVH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie( float roughness, float dotNH ) {\n\tfloat alpha = pow2( roughness );\n\tfloat invAlpha = 1.0 / alpha;\n\tfloat cos2h = dotNH * dotNH;\n\tfloat sin2h = max( 1.0 - cos2h, 0.0078125 );\n\treturn ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\n}\nfloat V_Neubelt( float dotNV, float dotNL ) {\n\treturn saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );\n}\nvec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat D = D_Charlie( sheenRoughness, dotNH );\n\tfloat V = V_Neubelt( dotNV, dotNL );\n\treturn sheenColor * ( D * V );\n}\n#endif",iridescence_fragment:"#ifdef USE_IRIDESCENCE\n\tconst mat3 XYZ_TO_REC709 = mat3(\n\t\t 3.2404542, -0.9692660,\t0.0556434,\n\t\t-1.5371385,\t1.8760108, -0.2040259,\n\t\t-0.4985314,\t0.0415560,\t1.0572252\n\t);\n\tvec3 Fresnel0ToIor( vec3 fresnel0 ) {\n\t\tvec3 sqrtF0 = sqrt( fresnel0 );\n\t\treturn ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 );\n\t}\n\tvec3 IorToFresnel0( vec3 transmittedIor, float incidentIor ) {\n\t\treturn pow2( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) );\n\t}\n\tfloat IorToFresnel0( float transmittedIor, float incidentIor ) {\n\t\treturn pow2( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ));\n\t}\n\tvec3 evalSensitivity( float OPD, vec3 shift ) {\n\t\tfloat phase = 2.0 * PI * OPD * 1.0e-9;\n\t\tvec3 val = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 );\n\t\tvec3 pos = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 );\n\t\tvec3 var = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 );\n\t\tvec3 xyz = val * sqrt( 2.0 * PI * var ) * cos( pos * phase + shift ) * exp( - pow2( phase ) * var );\n\t\txyz.x += 9.7470e-14 * sqrt( 2.0 * PI * 4.5282e+09 ) * cos( 2.2399e+06 * phase + shift[ 0 ] ) * exp( - 4.5282e+09 * pow2( phase ) );\n\t\txyz /= 1.0685e-7;\n\t\tvec3 rgb = XYZ_TO_REC709 * xyz;\n\t\treturn rgb;\n\t}\n\tvec3 evalIridescence( float outsideIOR, float eta2, float cosTheta1, float thinFilmThickness, vec3 baseF0 ) {\n\t\tvec3 I;\n\t\tfloat iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );\n\t\tfloat sinTheta2Sq = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) );\n\t\tfloat cosTheta2Sq = 1.0 - sinTheta2Sq;\n\t\tif ( cosTheta2Sq < 0.0 ) {\n\t\t\t return vec3( 1.0 );\n\t\t}\n\t\tfloat cosTheta2 = sqrt( cosTheta2Sq );\n\t\tfloat R0 = IorToFresnel0( iridescenceIOR, outsideIOR );\n\t\tfloat R12 = F_Schlick( R0, 1.0, cosTheta1 );\n\t\tfloat R21 = R12;\n\t\tfloat T121 = 1.0 - R12;\n\t\tfloat phi12 = 0.0;\n\t\tif ( iridescenceIOR < outsideIOR ) phi12 = PI;\n\t\tfloat phi21 = PI - phi12;\n\t\tvec3 baseIOR = Fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) );\t\tvec3 R1 = IorToFresnel0( baseIOR, iridescenceIOR );\n\t\tvec3 R23 = F_Schlick( R1, 1.0, cosTheta2 );\n\t\tvec3 phi23 = vec3( 0.0 );\n\t\tif ( baseIOR[ 0 ] < iridescenceIOR ) phi23[ 0 ] = PI;\n\t\tif ( baseIOR[ 1 ] < iridescenceIOR ) phi23[ 1 ] = PI;\n\t\tif ( baseIOR[ 2 ] < iridescenceIOR ) phi23[ 2 ] = PI;\n\t\tfloat OPD = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2;\n\t\tvec3 phi = vec3( phi21 ) + phi23;\n\t\tvec3 R123 = clamp( R12 * R23, 1e-5, 0.9999 );\n\t\tvec3 r123 = sqrt( R123 );\n\t\tvec3 Rs = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 );\n\t\tvec3 C0 = R12 + Rs;\n\t\tI = C0;\n\t\tvec3 Cm = Rs - T121;\n\t\tfor ( int m = 1; m <= 2; ++ m ) {\n\t\t\tCm *= r123;\n\t\t\tvec3 Sm = 2.0 * evalSensitivity( float( m ) * OPD, float( m ) * phi );\n\t\t\tI += Cm * Sm;\n\t\t}\n\t\treturn max( I, vec3( 0.0 ) );\n\t}\n#endif",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, float faceDirection ) {\n\t\tvec3 vSigmaX = dFdx( surf_pos.xyz );\n\t\tvec3 vSigmaY = dFdy( surf_pos.xyz );\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 ) * faceDirection;\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",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",clipping_planes_pars_fragment:"#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif",clipping_planes_pars_vertex:"#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif",clipping_planes_vertex:"#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif",color_fragment:"#if defined( USE_COLOR_ALPHA )\n\tdiffuseColor *= vColor;\n#elif defined( USE_COLOR )\n\tdiffuseColor.rgb *= vColor;\n#endif",color_pars_fragment:"#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR )\n\tvarying vec3 vColor;\n#endif",color_pars_vertex:"#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\n\tvarying vec3 vColor;\n#endif",color_vertex:"#if defined( USE_COLOR_ALPHA )\n\tvColor = vec4( 1.0 );\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\n\tvColor = vec3( 1.0 );\n#endif\n#ifdef USE_COLOR\n\tvColor *= color;\n#endif\n#ifdef USE_INSTANCING_COLOR\n\tvColor.xyz *= instanceColor.xyz;\n#endif",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; }\nvec3 pow2( const in vec3 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 max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\nfloat average( const in vec3 v ) { return dot( v, vec3( 0.3333333 ) ); }\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 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 USE_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}\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 luminance( const in vec3 rgb ) {\n\tconst vec3 weights = vec3( 0.2126729, 0.7151522, 0.0721750 );\n\treturn dot( weights, 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}",cube_uv_reflection_fragment:"#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_minMipLevel 4.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\tvec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\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\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\n\t\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n\t\tuv.x *= CUBEUV_TEXEL_WIDTH;\n\t\tuv.y *= CUBEUV_TEXEL_HEIGHT;\n\t\t#ifdef texture2DGradEXT\n\t\t\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n\t\t#else\n\t\t\treturn texture2D( envMap, uv ).rgb;\n\t\t#endif\n\t}\n\t#define cubeUV_r0 1.0\n\t#define cubeUV_v0 0.339\n\t#define cubeUV_m0 - 2.0\n\t#define cubeUV_r1 0.8\n\t#define cubeUV_v1 0.276\n\t#define cubeUV_m1 - 1.0\n\t#define cubeUV_r4 0.4\n\t#define cubeUV_v4 0.046\n\t#define cubeUV_m4 2.0\n\t#define cubeUV_r5 0.305\n\t#define cubeUV_v5 0.016\n\t#define cubeUV_m5 3.0\n\t#define cubeUV_r6 0.21\n\t#define cubeUV_v6 0.0038\n\t#define cubeUV_m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= cubeUV_r1 ) {\n\t\t\tmip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0;\n\t\t} else if ( roughness >= cubeUV_r4 ) {\n\t\t\tmip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1;\n\t\t} else if ( roughness >= cubeUV_r5 ) {\n\t\t\tmip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4;\n\t\t} else if ( roughness >= cubeUV_r6 ) {\n\t\t\tmip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_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 ), cubeUV_m0, CUBEUV_MAX_MIP );\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",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",displacementmap_pars_vertex:"#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif",displacementmap_vertex:"#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif",emissivemap_fragment:"#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif",emissivemap_pars_fragment:"#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif",encodings_fragment:"gl_FragColor = linearToOutputTexel( gl_FragColor );",encodings_pars_fragment:"vec4 LinearToLinear( in vec4 value ) {\n\treturn value;\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}",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#else\n\t\tvec4 envColor = vec4( 0.0 );\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",envmap_common_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\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",envmap_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\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",envmap_pars_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\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",envmap_physical_pars_fragment:"#if defined( USE_ENVMAP )\n\tvec3 getIBLIrradiance( const in vec3 normal ) {\n\t\t#if defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 );\n\t\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\tvec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\n\t\t#if defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 reflectVec = reflect( - viewDir, normal );\n\t\t\treflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );\n\t\t\treturn envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n#endif",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",fog_vertex:"#ifdef USE_FOG\n\tvFogDepth = - mvPosition.z;\n#endif",fog_pars_vertex:"#ifdef USE_FOG\n\tvarying float vFogDepth;\n#endif",fog_fragment:"#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif",fog_pars_fragment:"#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float vFogDepth;\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",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 vec3( texture2D( gradientMap, coord ).r );\n\t#else\n\t\tvec2 fw = fwidth( coord ) * 0.5;\n\t\treturn mix( vec3( 0.7 ), vec3( 1.0 ), smoothstep( 0.7 - fw.x, 0.7 + fw.x, coord.x ) );\n\t#endif\n}",lightmap_fragment:"#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\treflectedLight.indirectDiffuse += lightMapIrradiance;\n#endif",lightmap_pars_fragment:"#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif",lights_lambert_fragment:"LambertMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularStrength = specularStrength;",lights_lambert_pars_fragment:"varying vec3 vViewPosition;\nstruct LambertMaterial {\n\tvec3 diffuseColor;\n\tfloat specularStrength;\n};\nvoid RE_Direct_Lambert( const in IncidentLight directLight, const in GeometricContext geometry, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in GeometricContext geometry, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Lambert\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Lambert",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 vec3 normal ) {\n\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\treturn irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\t#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\tif ( cutoffDistance > 0.0 ) {\n\t\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\t}\n\t\treturn distanceFalloff;\n\t#else\n\t\tif ( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\t\treturn pow( saturate( - lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t\t}\n\t\treturn 1.0;\n\t#endif\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n\treturn smoothstep( coneCosine, penumbraCosine, angleCosine );\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 getDirectionalLightInfo( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tlight.color = directionalLight.color;\n\t\tlight.direction = directionalLight.direction;\n\t\tlight.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 getPointLightInfo( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tlight.color = pointLight.color;\n\t\tlight.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n\t\tlight.visible = ( light.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 getSpotLightInfo( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat angleCos = dot( light.direction, spotLight.direction );\n\t\tfloat spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\tif ( spotAttenuation > 0.0 ) {\n\t\t\tfloat lightDistance = length( lVector );\n\t\t\tlight.color = spotLight.color * spotAttenuation;\n\t\t\tlight.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t\t} else {\n\t\t\tlight.color = vec3( 0.0 );\n\t\t\tlight.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 vec3 normal ) {\n\t\tfloat dotNL = dot( normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\treturn irradiance;\n\t}\n#endif",lights_toon_fragment:"ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;",lights_toon_pars_fragment:"varying vec3 vViewPosition;\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\treflectedLight.directDiffuse += irradiance * BRDF_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_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon",lights_phong_fragment:"BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;",lights_phong_pars_fragment:"varying vec3 vViewPosition;\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\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, 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_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong",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.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\tmaterial.ior = ior;\n\t#ifdef SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULARINTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vUv ).a;\n\t\t#endif\n\t\t#ifdef USE_SPECULARCOLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vUv ).rgb;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\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_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vUv ).a;\n\t#endif\n#endif",lights_physical_pars_fragment:"struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat roughness;\n\tvec3 specularColor;\n\tfloat specularF90;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\tfloat iridescence;\n\t\tfloat iridescenceIOR;\n\t\tfloat iridescenceThickness;\n\t\tvec3 iridescenceFresnel;\n\t\tvec3 iridescenceF0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n\t#ifdef IOR\n\t\tfloat ior;\n\t#endif\n\t#ifdef USE_TRANSMISSION\n\t\tfloat transmission;\n\t\tfloat transmissionAlpha;\n\t\tfloat thickness;\n\t\tfloat attenuationDistance;\n\t\tvec3 attenuationColor;\n\t#endif\n};\nvec3 clearcoatSpecular = vec3( 0.0 );\nvec3 sheenSpecular = vec3( 0.0 );\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\n\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\n\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\n\treturn saturate( DG * RECIPROCAL_PI );\n}\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\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\tvec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\n\treturn fab;\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\treturn specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#endif\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\t#ifdef USE_IRIDESCENCE\n\t\tvec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n\t#else\n\t\tvec3 Fr = specularColor;\n\t#endif\n\tvec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\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.roughness;\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(\t\t0, 1,\t\t0 ),\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#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecular += ccIrradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.clearcoatNormal, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness );\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\treflectedLight.directSpecular += irradiance * BRDF_GGX_Iridescence( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness );\n\t#else\n\t\treflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.roughness );\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_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_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 USE_CLEARCOAT\n\t\tclearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometry.clearcoatNormal, geometry.viewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometry.normal, geometry.viewDir, material.sheenRoughness );\n\t#endif\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t#ifdef USE_IRIDESCENCE\n\t\tcomputeMultiscatteringIridescence( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );\n\t#else\n\t\tcomputeMultiscattering( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n\t#endif\n\tvec3 totalScattering = singleScattering + multiScattering;\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) );\n\treflectedLight.indirectSpecular += 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}",lights_fragment_begin:"\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef USE_CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n\tfloat dotNVi = saturate( dot( normal, geometry.viewDir ) );\n\tif ( material.iridescenceThickness == 0.0 ) {\n\t\tmaterial.iridescence = 0.0;\n\t} else {\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\t}\n\tif ( material.iridescence > 0.0 ) {\n\t\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\t}\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\tgetPointLightInfo( 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\tvec4 spotColor;\n\tvec3 spotLightCoord;\n\tbool inSpotLightMap;\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\tgetSpotLightInfo( spotLight, geometry, directLight );\n\t\t#if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n\t\t#elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t#define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n\t\t#else\n\t\t#define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#endif\n\t\t#if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n\t\t\tspotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n\t\t\tinSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n\t\t\tspotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n\t\t\tdirectLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n\t\t#endif\n\t\t#undef SPOT_LIGHT_MAP_INDEX\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, vSpotLightCoord[ 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\tgetDirectionalLightInfo( 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.normal );\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.normal );\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",lights_fragment_maps:"#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\t\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getIBLIrradiance( geometry.normal );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getIBLRadiance( geometry.viewDir, geometry.normal, material.roughness );\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatRadiance += getIBLRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness );\n\t#endif\n#endif",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",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",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",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",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",map_fragment:"#ifdef USE_MAP\n\tvec4 sampledDiffuseColor = texture2D( map, vUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\tsampledDiffuseColor = vec4( mix( pow( sampledDiffuseColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), sampledDiffuseColor.rgb * 0.0773993808, vec3( lessThanEqual( sampledDiffuseColor.rgb, vec3( 0.04045 ) ) ) ), sampledDiffuseColor.w );\n\t#endif\n\tdiffuseColor *= sampledDiffuseColor;\n#endif",map_pars_fragment:"#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif",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\tdiffuseColor *= texture2D( map, uv );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif",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",metalnessmap_fragment:"float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif",metalnessmap_pars_fragment:"#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif",morphcolor_vertex:"#if defined( USE_MORPHCOLORS ) && defined( MORPHTARGETS_TEXTURE )\n\tvColor *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t#if defined( USE_COLOR_ALPHA )\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ) * morphTargetInfluences[ i ];\n\t\t#elif defined( USE_COLOR )\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ).rgb * morphTargetInfluences[ i ];\n\t\t#endif\n\t}\n#endif",morphnormal_vertex:"#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\t#ifdef MORPHTARGETS_TEXTURE\n\t\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1 ).xyz * morphTargetInfluences[ i ];\n\t\t}\n\t#else\n\t\tobjectNormal += morphNormal0 * morphTargetInfluences[ 0 ];\n\t\tobjectNormal += morphNormal1 * morphTargetInfluences[ 1 ];\n\t\tobjectNormal += morphNormal2 * morphTargetInfluences[ 2 ];\n\t\tobjectNormal += morphNormal3 * morphTargetInfluences[ 3 ];\n\t#endif\n#endif",morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n\tuniform float morphTargetBaseInfluence;\n\t#ifdef MORPHTARGETS_TEXTURE\n\t\tuniform float morphTargetInfluences[ MORPHTARGETS_COUNT ];\n\t\tuniform sampler2DArray morphTargetsTexture;\n\t\tuniform ivec2 morphTargetsTextureSize;\n\t\tvec4 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset ) {\n\t\t\tint texelIndex = vertexIndex * MORPHTARGETS_TEXTURE_STRIDE + offset;\n\t\t\tint y = texelIndex / morphTargetsTextureSize.x;\n\t\t\tint x = texelIndex - y * morphTargetsTextureSize.x;\n\t\t\tivec3 morphUV = ivec3( x, y, morphTargetIndex );\n\t\t\treturn texelFetch( morphTargetsTexture, morphUV, 0 );\n\t\t}\n\t#else\n\t\t#ifndef USE_MORPHNORMALS\n\t\t\tuniform float morphTargetInfluences[ 8 ];\n\t\t#else\n\t\t\tuniform float morphTargetInfluences[ 4 ];\n\t\t#endif\n\t#endif\n#endif",morphtarget_vertex:"#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\t#ifdef MORPHTARGETS_TEXTURE\n\t\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ];\n\t\t}\n\t#else\n\t\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\n\t\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\n\t\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\n\t\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\n\t\t#ifndef USE_MORPHNORMALS\n\t\t\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\n\t\t\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\n\t\t\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\n\t\t\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\n\t\t#endif\n\t#endif\n#endif",normal_fragment_begin:"float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#ifdef FLAT_SHADED\n\tvec3 fdx = dFdx( vViewPosition );\n\tvec3 fdy = dFdy( vViewPosition );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * faceDirection;\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 * faceDirection;\n\t\t\tbitangent = bitangent * faceDirection;\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;",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 * faceDirection;\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, faceDirection );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\n#endif",normal_pars_fragment:"#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",normal_pars_vertex:"#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",normal_vertex:"#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",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, float faceDirection ) {\n\t\tvec3 q0 = dFdx( eye_pos.xyz );\n\t\tvec3 q1 = dFdy( eye_pos.xyz );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tvec3 N = surf_norm;\n\t\tvec3 q1perp = cross( q1, N );\n\t\tvec3 q0perp = cross( N, q0 );\n\t\tvec3 T = q1perp * st0.x + q0perp * st1.x;\n\t\tvec3 B = q1perp * st0.y + q0perp * st1.y;\n\t\tfloat det = max( dot( T, T ), dot( B, B ) );\n\t\tfloat scale = ( det == 0.0 ) ? 0.0 : faceDirection * inversesqrt( det );\n\t\treturn normalize( T * ( mapN.x * scale ) + B * ( mapN.y * scale ) + N * mapN.z );\n\t}\n#endif",clearcoat_normal_fragment_begin:"#ifdef USE_CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif",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, faceDirection );\n\t#endif\n#endif",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",iridescence_pars_fragment:"#ifdef USE_IRIDESCENCEMAP\n\tuniform sampler2D iridescenceMap;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform sampler2D iridescenceThicknessMap;\n#endif",output_fragment:"#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= material.transmissionAlpha + 0.1;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );",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}\nvec2 packDepthToRG( in highp float v ) {\n\treturn packDepthToRGBA( v ).yx;\n}\nfloat unpackRGToDepth( const in highp vec2 v ) {\n\treturn unpackRGBAToDepth( vec4( v.xy, 0.0, 0.0 ) );\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}",premultiplied_alpha_fragment:"#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif",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;",dithering_fragment:"#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif",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",roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif",roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",shadowmap_pars_fragment:"#if NUM_SPOT_LIGHT_COORDS > 0\n\tvarying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#if NUM_SPOT_LIGHT_MAPS > 0\n\tuniform sampler2D spotLightMap[ NUM_SPOT_LIGHT_MAPS ];\n#endif\n#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\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\ttexture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t\tf.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\ttexture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t\tf.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",shadowmap_pars_vertex:"#if NUM_SPOT_LIGHT_COORDS > 0\n\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\tvarying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#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\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",shadowmap_vertex:"#if defined( USE_SHADOWMAP ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n\t#if NUM_DIR_LIGHT_SHADOWS > 0 || NUM_SPOT_LIGHT_COORDS > 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_COORDS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition;\n\t\t#if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\tshadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias;\n\t\t#endif\n\t\tvSpotLightCoord[ i ] = spotLightMatrix[ 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",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, vSpotLightCoord[ 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}",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",skinning_pars_vertex:"#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\tuniform highp sampler2D boneTexture;\n\tuniform int boneTextureSize;\n\tmat4 getBoneMatrix( const in float i ) {\n\t\tfloat j = i * 4.0;\n\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\ty = dy * ( y + 0.5 );\n\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\treturn bone;\n\t}\n#endif",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",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",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",specularmap_pars_fragment:"#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif",tonemapping_fragment:"#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif",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(\t1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108,\t1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605,\t1.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; }",transmission_fragment:"#ifdef USE_TRANSMISSION\n\tmaterial.transmission = transmission;\n\tmaterial.transmissionAlpha = 1.0;\n\tmaterial.thickness = thickness;\n\tmaterial.attenuationDistance = attenuationDistance;\n\tmaterial.attenuationColor = attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tmaterial.transmission *= texture2D( transmissionMap, vUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tmaterial.thickness *= texture2D( thicknessMap, vUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmission = getIBLVolumeRefraction(\n\t\tn, v, material.roughness, material.diffuseColor, material.specularColor, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, material.ior, material.thickness,\n\t\tmaterial.attenuationColor, material.attenuationDistance );\n\tmaterial.transmissionAlpha = mix( material.transmissionAlpha, transmission.a, material.transmission );\n\ttotalDiffuse = mix( totalDiffuse, transmission.rgb, material.transmission );\n#endif",transmission_pars_fragment:"#ifdef USE_TRANSMISSION\n\tuniform float transmission;\n\tuniform float thickness;\n\tuniform float attenuationDistance;\n\tuniform vec3 attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tuniform sampler2D transmissionMap;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tuniform sampler2D thicknessMap;\n\t#endif\n\tuniform vec2 transmissionSamplerSize;\n\tuniform sampler2D transmissionSamplerMap;\n\tuniform mat4 modelMatrix;\n\tuniform mat4 projectionMatrix;\n\tvarying vec3 vWorldPosition;\n\tvec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\n\t\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n\t\tvec3 modelScale;\n\t\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\treturn normalize( refractionVector ) * thickness * modelScale;\n\t}\n\tfloat applyIorToRoughness( const in float roughness, const in float ior ) {\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t}\n\tvec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\n\t\tfloat framebufferLod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n\t\t#ifdef texture2DLodEXT\n\t\t\treturn texture2DLodEXT( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#else\n\t\t\treturn texture2D( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#endif\n\t}\n\tvec3 applyVolumeAttenuation( const in vec3 radiance, const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tif ( isinf( attenuationDistance ) ) {\n\t\t\treturn radiance;\n\t\t} else {\n\t\t\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n\t\t\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\t\t\treturn transmittance * radiance;\n\t\t}\n\t}\n\tvec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\n\t\tconst in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\n\t\tconst in mat4 viewMatrix, const in mat4 projMatrix, const in float ior, const in float thickness,\n\t\tconst in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\trefractionCoords += 1.0;\n\t\trefractionCoords /= 2.0;\n\t\tvec4 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n\t\tvec3 attenuatedColor = applyVolumeAttenuation( transmittedLight.rgb, length( transmissionRay ), attenuationColor, attenuationDistance );\n\t\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n\t\treturn vec4( ( 1.0 - F ) * attenuatedColor * diffuseColor, transmittedLight.a );\n\t}\n#endif",uv_pars_fragment:"#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif",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",uv_vertex:"#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif",uv2_pars_fragment:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif",uv2_pars_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n\tuniform mat3 uv2Transform;\n#endif",uv2_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif",worldpos_vertex:"#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) || NUM_SPOT_LIGHT_COORDS > 0\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",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}",background_frag:"uniform sampler2D t2D;\nuniform float backgroundIntensity;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\ttexColor = vec4( mix( pow( texColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), texColor.rgb * 0.0773993808, vec3( lessThanEqual( texColor.rgb, vec3( 0.04045 ) ) ) ), texColor.w );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include \n\t#include \n}",backgroundCube_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}",backgroundCube_frag:"#ifdef ENVMAP_TYPE_CUBE\n\tuniform samplerCube envMap;\n#elif defined( ENVMAP_TYPE_CUBE_UV )\n\tuniform sampler2D envMap;\n#endif\nuniform float flipEnvMap;\nuniform float backgroundBlurriness;\nuniform float backgroundIntensity;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 texColor = textureCube( envMap, vec3( flipEnvMap * vWorldDirection.x, vWorldDirection.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 texColor = textureCubeUV( envMap, vWorldDirection, backgroundBlurriness );\n\t#else\n\t\tvec4 texColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include \n\t#include \n}",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}",cube_frag:"uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = texColor;\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}",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}",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 \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}",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}",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 \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}",equirect_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}",equirect_frag:"uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV = equirectUv( direction );\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\t#include \n\t#include \n}",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\t#include \n}",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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",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#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\t\t#include \n\t\t#include \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\t#include \n\t#include \n}",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\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshlambert_vert:"#define LAMBERT\nvarying vec3 vViewPosition;\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\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}",meshlambert_frag:"#define LAMBERT\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 \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 + totalEmissiveRadiance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshmatcap_vert:"#define MATCAP\nvarying vec3 vViewPosition;\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\tvViewPosition = - mvPosition.xyz;\n}",meshmatcap_frag:"#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\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\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#else\n\t\tvec4 matcapColor = vec4( vec3( mix( 0.2, 0.8, uv.y ) ), 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshnormal_vert:"#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\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#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}",meshnormal_frag:"#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\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\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n\t#ifdef OPAQUE\n\t\tgl_FragColor.a = 1.0;\n\t#endif\n}",meshphong_vert:"#define PHONG\nvarying vec3 vViewPosition;\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\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}",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 \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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshphysical_vert:"#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n\tvarying vec3 vWorldPosition;\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\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\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n#ifdef USE_TRANSMISSION\n\tvWorldPosition = worldPosition.xyz;\n#endif\n}",meshphysical_frag:"#define STANDARD\n#ifdef PHYSICAL\n\t#define IOR\n\t#define SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n\tuniform float ior;\n#endif\n#ifdef SPECULAR\n\tuniform float specularIntensity;\n\tuniform vec3 specularColor;\n\t#ifdef USE_SPECULARINTENSITYMAP\n\t\tuniform sampler2D specularIntensityMap;\n\t#endif\n\t#ifdef USE_SPECULARCOLORMAP\n\t\tuniform sampler2D specularColorMap;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_IRIDESCENCE\n\tuniform float iridescence;\n\tuniform float iridescenceIOR;\n\tuniform float iridescenceThicknessMinimum;\n\tuniform float iridescenceThicknessMaximum;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheenColor;\n\tuniform float sheenRoughness;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tuniform sampler2D sheenColorMap;\n\t#endif\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tuniform sampler2D sheenRoughnessMap;\n\t#endif\n#endif\nvarying vec3 vViewPosition;\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 \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\t#include \n\t#include \n\t#include \n\tvec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n\tvec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n\t#include \n\tvec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n\t#ifdef USE_SHEEN\n\t\tfloat sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor );\n\t\toutgoingLight = outgoingLight * sheenEnergyComp + sheenSpecular;\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNVcc = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\tvec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n\t\toutgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + clearcoatSpecular * material.clearcoat;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshtoon_vert:"#define TOON\nvarying vec3 vViewPosition;\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\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}",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 \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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",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\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}",points_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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",shadow_vert:"#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}",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}",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}",sprite_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \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\t#include \n\t#include \n\t#include \n\t#include \n}"},Sn={common:{diffuse:{value:new qt(16777215)},opacity:{value:1},map:{value:null},uvTransform:{value:new Rt},uv2Transform:{value:new Rt},alphaMap:{value:null},alphaTest:{value:0}},specularmap:{specularMap:{value:null}},envmap:{envMap:{value:null},flipEnvMap:{value:-1},reflectivity:{value:1},ior:{value:1.5},refractionRatio:{value:.98}},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 Lt(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:25e-5},fogNear:{value:1},fogFar:{value:2e3},fogColor:{value:new qt(16777215)}},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:{}}},spotLightMap:{value:[]},spotShadowMap:{value:[]},spotLightMatrix:{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:{}}},rectAreaLights:{value:[],properties:{color:{},position:{},width:{},height:{}}},ltc_1:{value:null},ltc_2:{value:null}},points:{diffuse:{value:new qt(16777215)},opacity:{value:1},size:{value:1},scale:{value:1},map:{value:null},alphaMap:{value:null},alphaTest:{value:0},uvTransform:{value:new Rt}},sprite:{diffuse:{value:new qt(16777215)},opacity:{value:1},center:{value:new Lt(.5,.5)},rotation:{value:0},map:{value:null},alphaMap:{value:null},alphaTest:{value:0},uvTransform:{value:new Rt}}},wn={basic:{uniforms:en([Sn.common,Sn.specularmap,Sn.envmap,Sn.aomap,Sn.lightmap,Sn.fog]),vertexShader:bn.meshbasic_vert,fragmentShader:bn.meshbasic_frag},lambert:{uniforms:en([Sn.common,Sn.specularmap,Sn.envmap,Sn.aomap,Sn.lightmap,Sn.emissivemap,Sn.bumpmap,Sn.normalmap,Sn.displacementmap,Sn.fog,Sn.lights,{emissive:{value:new qt(0)}}]),vertexShader:bn.meshlambert_vert,fragmentShader:bn.meshlambert_frag},phong:{uniforms:en([Sn.common,Sn.specularmap,Sn.envmap,Sn.aomap,Sn.lightmap,Sn.emissivemap,Sn.bumpmap,Sn.normalmap,Sn.displacementmap,Sn.fog,Sn.lights,{emissive:{value:new qt(0)},specular:{value:new qt(1118481)},shininess:{value:30}}]),vertexShader:bn.meshphong_vert,fragmentShader:bn.meshphong_frag},standard:{uniforms:en([Sn.common,Sn.envmap,Sn.aomap,Sn.lightmap,Sn.emissivemap,Sn.bumpmap,Sn.normalmap,Sn.displacementmap,Sn.roughnessmap,Sn.metalnessmap,Sn.fog,Sn.lights,{emissive:{value:new qt(0)},roughness:{value:1},metalness:{value:0},envMapIntensity:{value:1}}]),vertexShader:bn.meshphysical_vert,fragmentShader:bn.meshphysical_frag},toon:{uniforms:en([Sn.common,Sn.aomap,Sn.lightmap,Sn.emissivemap,Sn.bumpmap,Sn.normalmap,Sn.displacementmap,Sn.gradientmap,Sn.fog,Sn.lights,{emissive:{value:new qt(0)}}]),vertexShader:bn.meshtoon_vert,fragmentShader:bn.meshtoon_frag},matcap:{uniforms:en([Sn.common,Sn.bumpmap,Sn.normalmap,Sn.displacementmap,Sn.fog,{matcap:{value:null}}]),vertexShader:bn.meshmatcap_vert,fragmentShader:bn.meshmatcap_frag},points:{uniforms:en([Sn.points,Sn.fog]),vertexShader:bn.points_vert,fragmentShader:bn.points_frag},dashed:{uniforms:en([Sn.common,Sn.fog,{scale:{value:1},dashSize:{value:1},totalSize:{value:2}}]),vertexShader:bn.linedashed_vert,fragmentShader:bn.linedashed_frag},depth:{uniforms:en([Sn.common,Sn.displacementmap]),vertexShader:bn.depth_vert,fragmentShader:bn.depth_frag},normal:{uniforms:en([Sn.common,Sn.bumpmap,Sn.normalmap,Sn.displacementmap,{opacity:{value:1}}]),vertexShader:bn.meshnormal_vert,fragmentShader:bn.meshnormal_frag},sprite:{uniforms:en([Sn.sprite,Sn.fog]),vertexShader:bn.sprite_vert,fragmentShader:bn.sprite_frag},background:{uniforms:{uvTransform:{value:new Rt},t2D:{value:null},backgroundIntensity:{value:1}},vertexShader:bn.background_vert,fragmentShader:bn.background_frag},backgroundCube:{uniforms:{envMap:{value:null},flipEnvMap:{value:-1},backgroundBlurriness:{value:0},backgroundIntensity:{value:1}},vertexShader:bn.backgroundCube_vert,fragmentShader:bn.backgroundCube_frag},cube:{uniforms:{tCube:{value:null},tFlip:{value:-1},opacity:{value:1}},vertexShader:bn.cube_vert,fragmentShader:bn.cube_frag},equirect:{uniforms:{tEquirect:{value:null}},vertexShader:bn.equirect_vert,fragmentShader:bn.equirect_frag},distanceRGBA:{uniforms:en([Sn.common,Sn.displacementmap,{referencePosition:{value:new re},nearDistance:{value:1},farDistance:{value:1e3}}]),vertexShader:bn.distanceRGBA_vert,fragmentShader:bn.distanceRGBA_frag},shadow:{uniforms:en([Sn.lights,Sn.fog,{color:{value:new qt(0)},opacity:{value:1}}]),vertexShader:bn.shadow_vert,fragmentShader:bn.shadow_frag}};wn.physical={uniforms:en([wn.standard.uniforms,{clearcoat:{value:0},clearcoatMap:{value:null},clearcoatRoughness:{value:0},clearcoatRoughnessMap:{value:null},clearcoatNormalScale:{value:new Lt(1,1)},clearcoatNormalMap:{value:null},iridescence:{value:0},iridescenceMap:{value:null},iridescenceIOR:{value:1.3},iridescenceThicknessMinimum:{value:100},iridescenceThicknessMaximum:{value:400},iridescenceThicknessMap:{value:null},sheen:{value:0},sheenColor:{value:new qt(0)},sheenColorMap:{value:null},sheenRoughness:{value:1},sheenRoughnessMap:{value:null},transmission:{value:0},transmissionMap:{value:null},transmissionSamplerSize:{value:new Lt},transmissionSamplerMap:{value:null},thickness:{value:0},thicknessMap:{value:null},attenuationDistance:{value:0},attenuationColor:{value:new qt(0)},specularIntensity:{value:1},specularIntensityMap:{value:null},specularColor:{value:new qt(1,1,1)},specularColorMap:{value:null}}]),vertexShader:bn.meshphysical_vert,fragmentShader:bn.meshphysical_frag};const Tn={r:0,b:0,g:0};function An(t,e,i,n,r,s,a){const o=new qt(0);let c,h,u=!0===s?0:1,d=null,p=0,m=null;function f(e,i){e.getRGB(Tn,nn(t)),n.buffers.color.setClear(Tn.r,Tn.g,Tn.b,i,a)}return{getClearColor:function(){return o},setClearColor:function(t,e=1){o.set(t),u=e,f(o,u)},getClearAlpha:function(){return u},setClearAlpha:function(t){u=t,f(o,u)},render:function(n,s){let a=!1,g=!0===s.isScene?s.background:null;if(g&&g.isTexture){g=(s.backgroundBlurriness>0?i:e).get(g)}const v=t.xr,x=v.getSession&&v.getSession();x&&"additive"===x.environmentBlendMode&&(g=null),null===g?f(o,u):g&&g.isColor&&(f(g,1),a=!0),(t.autoClear||a)&&t.clear(t.autoClearColor,t.autoClearDepth,t.autoClearStencil),g&&(g.isCubeTexture||g.mapping===l)?(void 0===h&&(h=new Ki(new Qi(1,1,1),new sn({name:"BackgroundCubeMaterial",uniforms:tn(wn.backgroundCube.uniforms),vertexShader:wn.backgroundCube.vertexShader,fragmentShader:wn.backgroundCube.fragmentShader,side:1,depthTest:!1,depthWrite:!1,fog:!1})),h.geometry.deleteAttribute("normal"),h.geometry.deleteAttribute("uv"),h.onBeforeRender=function(t,e,i){this.matrixWorld.copyPosition(i.matrixWorld)},Object.defineProperty(h.material,"envMap",{get:function(){return this.uniforms.envMap.value}}),r.update(h)),h.material.uniforms.envMap.value=g,h.material.uniforms.flipEnvMap.value=g.isCubeTexture&&!1===g.isRenderTargetTexture?-1:1,h.material.uniforms.backgroundBlurriness.value=s.backgroundBlurriness,h.material.uniforms.backgroundIntensity.value=s.backgroundIntensity,d===g&&p===g.version&&m===t.toneMapping||(h.material.needsUpdate=!0,d=g,p=g.version,m=t.toneMapping),h.layers.enableAll(),n.unshift(h,h.geometry,h.material,0,0,null)):g&&g.isTexture&&(void 0===c&&(c=new Ki(new Mn(2,2),new sn({name:"BackgroundMaterial",uniforms:tn(wn.background.uniforms),vertexShader:wn.background.vertexShader,fragmentShader:wn.background.fragmentShader,side:0,depthTest:!1,depthWrite:!1,fog:!1})),c.geometry.deleteAttribute("normal"),Object.defineProperty(c.material,"map",{get:function(){return this.uniforms.t2D.value}}),r.update(c)),c.material.uniforms.t2D.value=g,c.material.uniforms.backgroundIntensity.value=s.backgroundIntensity,!0===g.matrixAutoUpdate&&g.updateMatrix(),c.material.uniforms.uvTransform.value.copy(g.matrix),d===g&&p===g.version&&m===t.toneMapping||(c.material.needsUpdate=!0,d=g,p=g.version,m=t.toneMapping),c.layers.enableAll(),n.unshift(c,c.geometry,c.material,0,0,null))}}}function En(t,e,i,n){const r=t.getParameter(34921),s=n.isWebGL2?null:e.get("OES_vertex_array_object"),a=n.isWebGL2||null!==s,o={},l=p(null);let c=l,h=!1;function u(e){return n.isWebGL2?t.bindVertexArray(e):s.bindVertexArrayOES(e)}function d(e){return n.isWebGL2?t.deleteVertexArray(e):s.deleteVertexArrayOES(e)}function p(t){const e=[],i=[],n=[];for(let t=0;t=0){const i=r[e];let n=s[e];if(void 0===n&&("instanceMatrix"===e&&t.instanceMatrix&&(n=t.instanceMatrix),"instanceColor"===e&&t.instanceColor&&(n=t.instanceColor)),void 0===i)return!0;if(i.attribute!==n)return!0;if(n&&i.data!==n.data)return!0;a++}}return c.attributesNum!==a||c.index!==n}(r,_,d,y),M&&function(t,e,i,n){const r={},s=e.attributes;let a=0;const o=i.getAttributes();for(const e in o){if(o[e].location>=0){let i=s[e];void 0===i&&("instanceMatrix"===e&&t.instanceMatrix&&(i=t.instanceMatrix),"instanceColor"===e&&t.instanceColor&&(i=t.instanceColor));const n={};n.attribute=i,i&&i.data&&(n.data=i.data),r[e]=n,a++}}c.attributes=r,c.attributesNum=a,c.index=n}(r,_,d,y)}else{const t=!0===l.wireframe;c.geometry===_.id&&c.program===d.id&&c.wireframe===t||(c.geometry=_.id,c.program=d.id,c.wireframe=t,M=!0)}null!==y&&i.update(y,34963),(M||h)&&(h=!1,function(r,s,a,o){if(!1===n.isWebGL2&&(r.isInstancedMesh||o.isInstancedBufferGeometry)&&null===e.get("ANGLE_instanced_arrays"))return;m();const l=o.attributes,c=a.getAttributes(),h=s.defaultAttributeValues;for(const e in c){const n=c[e];if(n.location>=0){let s=l[e];if(void 0===s&&("instanceMatrix"===e&&r.instanceMatrix&&(s=r.instanceMatrix),"instanceColor"===e&&r.instanceColor&&(s=r.instanceColor)),void 0!==s){const e=s.normalized,a=s.itemSize,l=i.get(s);if(void 0===l)continue;const c=l.buffer,h=l.type,u=l.bytesPerElement;if(s.isInterleavedBufferAttribute){const i=s.data,l=i.stride,d=s.offset;if(i.isInstancedInterleavedBuffer){for(let t=0;t0&&t.getShaderPrecisionFormat(35632,36338).precision>0)return"highp";e="mediump"}return"mediump"===e&&t.getShaderPrecisionFormat(35633,36337).precision>0&&t.getShaderPrecisionFormat(35632,36337).precision>0?"mediump":"lowp"}const s="undefined"!=typeof WebGL2RenderingContext&&t instanceof WebGL2RenderingContext||"undefined"!=typeof WebGL2ComputeRenderingContext&&t instanceof WebGL2ComputeRenderingContext;let a=void 0!==i.precision?i.precision:"highp";const o=r(a);o!==a&&(console.warn("THREE.WebGLRenderer:",a,"not supported, using",o,"instead."),a=o);const l=s||e.has("WEBGL_draw_buffers"),c=!0===i.logarithmicDepthBuffer,h=t.getParameter(34930),u=t.getParameter(35660),d=t.getParameter(3379),p=t.getParameter(34076),m=t.getParameter(34921),f=t.getParameter(36347),g=t.getParameter(36348),v=t.getParameter(36349),x=u>0,_=s||e.has("OES_texture_float");return{isWebGL2:s,drawBuffers:l,getMaxAnisotropy:function(){if(void 0!==n)return n;if(!0===e.has("EXT_texture_filter_anisotropic")){const i=e.get("EXT_texture_filter_anisotropic");n=t.getParameter(i.MAX_TEXTURE_MAX_ANISOTROPY_EXT)}else n=0;return n},getMaxPrecision:r,precision:a,logarithmicDepthBuffer:c,maxTextures:h,maxVertexTextures:u,maxTextureSize:d,maxCubemapSize:p,maxAttributes:m,maxVertexUniforms:f,maxVaryings:g,maxFragmentUniforms:v,vertexTextures:x,floatFragmentTextures:_,floatVertexTextures:x&&_,maxSamples:s?t.getParameter(36183):0}}function Rn(t){const e=this;let i=null,n=0,r=!1,s=!1;const a=new fn,o=new Rt,l={value:null,needsUpdate:!1};function c(){l.value!==i&&(l.value=i,l.needsUpdate=n>0),e.numPlanes=n,e.numIntersection=0}function h(t,i,n,r){const s=null!==t?t.length:0;let c=null;if(0!==s){if(c=l.value,!0!==r||null===c){const e=n+4*s,r=i.matrixWorldInverse;o.getNormalMatrix(r),(null===c||c.length0){const a=new un(s.height/2);return a.fromEquirectangularTexture(t,r),e.set(r,a),r.addEventListener("dispose",n),i(a.texture,r.mapping)}return null}}}return r},dispose:function(){e=new WeakMap}}}class In extends an{constructor(t=-1,e=1,i=1,n=-1,r=.1,s=2e3){super(),this.isOrthographicCamera=!0,this.type="OrthographicCamera",this.zoom=1,this.view=null,this.left=t,this.right=e,this.top=i,this.bottom=n,this.near=r,this.far=s,this.updateProjectionMatrix()}copy(t,e){return super.copy(t,e),this.left=t.left,this.right=t.right,this.top=t.top,this.bottom=t.bottom,this.near=t.near,this.far=t.far,this.zoom=t.zoom,this.view=null===t.view?null:Object.assign({},t.view),this}setViewOffset(t,e,i,n,r,s){null===this.view&&(this.view={enabled:!0,fullWidth:1,fullHeight:1,offsetX:0,offsetY:0,width:1,height:1}),this.view.enabled=!0,this.view.fullWidth=t,this.view.fullHeight=e,this.view.offsetX=i,this.view.offsetY=n,this.view.width=r,this.view.height=s,this.updateProjectionMatrix()}clearViewOffset(){null!==this.view&&(this.view.enabled=!1),this.updateProjectionMatrix()}updateProjectionMatrix(){const t=(this.right-this.left)/(2*this.zoom),e=(this.top-this.bottom)/(2*this.zoom),i=(this.right+this.left)/2,n=(this.top+this.bottom)/2;let r=i-t,s=i+t,a=n+e,o=n-e;if(null!==this.view&&this.view.enabled){const t=(this.right-this.left)/this.view.fullWidth/this.zoom,e=(this.top-this.bottom)/this.view.fullHeight/this.zoom;r+=t*this.view.offsetX,s=r+t*this.view.width,a-=e*this.view.offsetY,o=a-e*this.view.height}this.projectionMatrix.makeOrthographic(r,s,a,o,this.near,this.far),this.projectionMatrixInverse.copy(this.projectionMatrix).invert()}toJSON(t){const e=super.toJSON(t);return e.object.zoom=this.zoom,e.object.left=this.left,e.object.right=this.right,e.object.top=this.top,e.object.bottom=this.bottom,e.object.near=this.near,e.object.far=this.far,null!==this.view&&(e.object.view=Object.assign({},this.view)),e}}const Dn=[.125,.215,.35,.446,.526,.582],Nn=20,On=new In,zn=new qt;let Un=null;const Bn=(1+Math.sqrt(5))/2,Fn=1/Bn,kn=[new re(1,1,1),new re(-1,1,1),new re(1,1,-1),new re(-1,1,-1),new re(0,Bn,Fn),new re(0,Bn,-Fn),new re(Fn,0,Bn),new re(-Fn,0,Bn),new re(Bn,Fn,0),new re(-Bn,Fn,0)];class Gn{constructor(t){this._renderer=t,this._pingPongRenderTarget=null,this._lodMax=0,this._cubeSize=0,this._lodPlanes=[],this._sizeLods=[],this._sigmas=[],this._blurMaterial=null,this._cubemapMaterial=null,this._equirectMaterial=null,this._compileMaterial(this._blurMaterial)}fromScene(t,e=0,i=.1,n=100){Un=this._renderer.getRenderTarget(),this._setSize(256);const r=this._allocateTargets();return r.depthBuffer=!0,this._sceneToCubeUV(t,i,n,r),e>0&&this._blur(r,0,0,e),this._applyPMREM(r),this._cleanup(r),r}fromEquirectangular(t,e=null){return this._fromTexture(t,e)}fromCubemap(t,e=null){return this._fromTexture(t,e)}compileCubemapShader(){null===this._cubemapMaterial&&(this._cubemapMaterial=jn(),this._compileMaterial(this._cubemapMaterial))}compileEquirectangularShader(){null===this._equirectMaterial&&(this._equirectMaterial=Wn(),this._compileMaterial(this._equirectMaterial))}dispose(){this._dispose(),null!==this._cubemapMaterial&&this._cubemapMaterial.dispose(),null!==this._equirectMaterial&&this._equirectMaterial.dispose()}_setSize(t){this._lodMax=Math.floor(Math.log2(t)),this._cubeSize=Math.pow(2,this._lodMax)}_dispose(){null!==this._blurMaterial&&this._blurMaterial.dispose(),null!==this._pingPongRenderTarget&&this._pingPongRenderTarget.dispose();for(let t=0;tt-4?o=Dn[a-t+4-1]:0===a&&(o=0),n.push(o);const l=1/(s-2),c=-l,h=1+l,u=[c,c,h,c,h,h,c,c,h,h,c,h],d=6,p=6,m=3,f=2,g=1,v=new Float32Array(m*p*d),x=new Float32Array(f*p*d),_=new Float32Array(g*p*d);for(let t=0;t2?0:-1,n=[e,i,0,e+2/3,i,0,e+2/3,i+1,0,e,i,0,e+2/3,i+1,0,e,i+1,0];v.set(n,m*p*t),x.set(u,f*p*t);const r=[t,t,t,t,t,t];_.set(r,g*p*t)}const y=new Di;y.setAttribute("position",new bi(v,m)),y.setAttribute("uv",new bi(x,f)),y.setAttribute("faceIndex",new bi(_,g)),e.push(y),r>4&&r--}return{lodPlanes:e,sizeLods:i,sigmas:n}}(n)),this._blurMaterial=function(t,e,i){const n=new Float32Array(Nn),r=new re(0,1,0);return new sn({name:"SphericalGaussianBlur",defines:{n:Nn,CUBEUV_TEXEL_WIDTH:1/e,CUBEUV_TEXEL_HEIGHT:1/i,CUBEUV_MAX_MIP:`${t}.0`},uniforms:{envMap:{value:null},samples:{value:1},weights:{value:n},latitudinal:{value:!1},dTheta:{value:0},mipInt:{value:0},poleAxis:{value:r}},vertexShader:qn(),fragmentShader:"\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#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}\n\t\t",blending:0,depthTest:!1,depthWrite:!1})}(n,t,e)}return n}_compileMaterial(t){const e=new Ki(this._lodPlanes[0],t);this._renderer.compile(e,On)}_sceneToCubeUV(t,e,i,n){const r=new on(90,1,e,i),s=[1,-1,1,1,1,1],a=[1,1,1,-1,-1,-1],o=this._renderer,l=o.autoClear,c=o.toneMapping;o.getClearColor(zn),o.toneMapping=0,o.autoClear=!1;const h=new _i({name:"PMREM.Background",side:1,depthWrite:!1,depthTest:!1}),u=new Ki(new Qi,h);let d=!1;const p=t.background;p?p.isColor&&(h.color.copy(p),t.background=null,d=!0):(h.color.copy(zn),d=!0);for(let e=0;e<6;e++){const i=e%3;0===i?(r.up.set(0,s[e],0),r.lookAt(a[e],0,0)):1===i?(r.up.set(0,0,s[e]),r.lookAt(0,a[e],0)):(r.up.set(0,s[e],0),r.lookAt(0,0,a[e]));const l=this._cubeSize;Hn(n,i*l,e>2?l:0,l,l),o.setRenderTarget(n),d&&o.render(u,r),o.render(t,r)}u.geometry.dispose(),u.material.dispose(),o.toneMapping=c,o.autoClear=l,t.background=p}_textureToCubeUV(t,e){const i=this._renderer,n=t.mapping===r||t.mapping===s;n?(null===this._cubemapMaterial&&(this._cubemapMaterial=jn()),this._cubemapMaterial.uniforms.flipEnvMap.value=!1===t.isRenderTargetTexture?-1:1):null===this._equirectMaterial&&(this._equirectMaterial=Wn());const a=n?this._cubemapMaterial:this._equirectMaterial,o=new Ki(this._lodPlanes[0],a);a.uniforms.envMap.value=t;const l=this._cubeSize;Hn(e,0,0,3*l,2*l),i.setRenderTarget(e),i.render(o,On)}_applyPMREM(t){const e=this._renderer,i=e.autoClear;e.autoClear=!1;for(let e=1;eNn&&console.warn(`sigmaRadians, ${r}, is too large and will clip, as it requested ${m} samples when the maximum is set to 20`);const f=[];let g=0;for(let t=0;tv-4?n-v+4:0),4*(this._cubeSize-x),3*x,2*x),o.setRenderTarget(e),o.render(c,On)}}function Vn(t,e,i){const n=new te(t,e,i);return n.texture.mapping=l,n.texture.name="PMREM.cubeUv",n.scissorTest=!0,n}function Hn(t,e,i,n,r){t.viewport.set(e,i,n,r),t.scissor.set(e,i,n,r)}function Wn(){return new sn({name:"EquirectangularToCubeUV",uniforms:{envMap:{value:null}},vertexShader:qn(),fragmentShader:"\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\n\t\t\t#include \n\n\t\t\tvoid main() {\n\n\t\t\t\tvec3 outputDirection = normalize( vOutputDirection );\n\t\t\t\tvec2 uv = equirectUv( outputDirection );\n\n\t\t\t\tgl_FragColor = vec4( texture2D ( envMap, uv ).rgb, 1.0 );\n\n\t\t\t}\n\t\t",blending:0,depthTest:!1,depthWrite:!1})}function jn(){return new sn({name:"CubemapToCubeUV",uniforms:{envMap:{value:null},flipEnvMap:{value:-1}},vertexShader:qn(),fragmentShader:"\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tuniform float flipEnvMap;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform samplerCube envMap;\n\n\t\t\tvoid main() {\n\n\t\t\t\tgl_FragColor = textureCube( envMap, vec3( flipEnvMap * vOutputDirection.x, vOutputDirection.yz ) );\n\n\t\t\t}\n\t\t",blending:0,depthTest:!1,depthWrite:!1})}function qn(){return"\n\n\t\tprecision mediump float;\n\t\tprecision mediump int;\n\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 Xn(t){let e=new WeakMap,i=null;function n(t){const i=t.target;i.removeEventListener("dispose",n);const r=e.get(i);void 0!==r&&(e.delete(i),r.dispose())}return{get:function(l){if(l&&l.isTexture){const c=l.mapping,h=c===a||c===o,u=c===r||c===s;if(h||u){if(l.isRenderTargetTexture&&!0===l.needsPMREMUpdate){l.needsPMREMUpdate=!1;let n=e.get(l);return null===i&&(i=new Gn(t)),n=h?i.fromEquirectangular(l,n):i.fromCubemap(l,n),e.set(l,n),n.texture}if(e.has(l))return e.get(l).texture;{const r=l.image;if(h&&r&&r.height>0||u&&r&&function(t){let e=0;const i=6;for(let n=0;ne.maxTextureSize&&(E=Math.ceil(A/e.maxTextureSize),A=e.maxTextureSize);const C=new Float32Array(A*E*4*m),L=new ee(C,A,E,m);L.type=M,L.needsUpdate=!0;const R=4*T;for(let I=0;I0)return t;const r=e*i;let s=ar[r];if(void 0===s&&(s=new Float32Array(r),ar[r]=s),0!==e){n.toArray(s,0);for(let n=1,r=0;n!==e;++n)r+=i,t[n].toArray(s,r)}return s}function dr(t,e){if(t.length!==e.length)return!1;for(let i=0,n=t.length;i":" "} ${r}: ${i[t]}`)}return n.join("\n")}(t.getShaderSource(e),n)}return r}function cs(t,e){const i=function(t){switch(t){case at:return["Linear","( value )"];case ot:return["sRGB","( value )"];default:return console.warn("THREE.WebGLProgram: Unsupported encoding:",t),["Linear","( value )"]}}(e);return"vec4 "+t+"( vec4 value ) { return LinearTo"+i[0]+i[1]+"; }"}function hs(t,e){let i;switch(e){case 1:i="Linear";break;case 2:i="Reinhard";break;case 3:i="OptimizedCineon";break;case 4:i="ACESFilmic";break;case 5:i="Custom";break;default:console.warn("THREE.WebGLProgram: Unsupported toneMapping:",e),i="Linear"}return"vec3 "+t+"( vec3 color ) { return "+i+"ToneMapping( color ); }"}function us(t){return""!==t}function ds(t,e){const i=e.numSpotLightShadows+e.numSpotLightMaps-e.numSpotLightShadowsWithMaps;return t.replace(/NUM_DIR_LIGHTS/g,e.numDirLights).replace(/NUM_SPOT_LIGHTS/g,e.numSpotLights).replace(/NUM_SPOT_LIGHT_MAPS/g,e.numSpotLightMaps).replace(/NUM_SPOT_LIGHT_COORDS/g,i).replace(/NUM_RECT_AREA_LIGHTS/g,e.numRectAreaLights).replace(/NUM_POINT_LIGHTS/g,e.numPointLights).replace(/NUM_HEMI_LIGHTS/g,e.numHemiLights).replace(/NUM_DIR_LIGHT_SHADOWS/g,e.numDirLightShadows).replace(/NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS/g,e.numSpotLightShadowsWithMaps).replace(/NUM_SPOT_LIGHT_SHADOWS/g,e.numSpotLightShadows).replace(/NUM_POINT_LIGHT_SHADOWS/g,e.numPointLightShadows)}function ps(t,e){return t.replace(/NUM_CLIPPING_PLANES/g,e.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g,e.numClippingPlanes-e.numClipIntersection)}const ms=/^[ \t]*#include +<([\w\d./]+)>/gm;function fs(t){return t.replace(ms,gs)}function gs(t,e){const i=bn[e];if(void 0===i)throw new Error("Can not resolve #include <"+e+">");return fs(i)}const vs=/#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;function xs(t){return t.replace(vs,_s)}function _s(t,e,i,n){let r="";for(let t=parseInt(e);t0&&(_+="\n"),y=[g,v].filter(us).join("\n"),y.length>0&&(y+="\n")):(_=[ys(i),"#define SHADER_NAME "+i.shaderName,v,i.instancing?"#define USE_INSTANCING":"",i.instancingColor?"#define USE_INSTANCING_COLOR":"",i.supportsVertexTextures?"#define VERTEX_TEXTURES":"",i.useFog&&i.fog?"#define USE_FOG":"",i.useFog&&i.fogExp2?"#define FOG_EXP2":"",i.map?"#define USE_MAP":"",i.envMap?"#define USE_ENVMAP":"",i.envMap?"#define "+p:"",i.lightMap?"#define USE_LIGHTMAP":"",i.aoMap?"#define USE_AOMAP":"",i.emissiveMap?"#define USE_EMISSIVEMAP":"",i.bumpMap?"#define USE_BUMPMAP":"",i.normalMap?"#define USE_NORMALMAP":"",i.normalMap&&i.objectSpaceNormalMap?"#define OBJECTSPACE_NORMALMAP":"",i.normalMap&&i.tangentSpaceNormalMap?"#define TANGENTSPACE_NORMALMAP":"",i.clearcoatMap?"#define USE_CLEARCOATMAP":"",i.clearcoatRoughnessMap?"#define USE_CLEARCOAT_ROUGHNESSMAP":"",i.clearcoatNormalMap?"#define USE_CLEARCOAT_NORMALMAP":"",i.iridescenceMap?"#define USE_IRIDESCENCEMAP":"",i.iridescenceThicknessMap?"#define USE_IRIDESCENCE_THICKNESSMAP":"",i.displacementMap&&i.supportsVertexTextures?"#define USE_DISPLACEMENTMAP":"",i.specularMap?"#define USE_SPECULARMAP":"",i.specularIntensityMap?"#define USE_SPECULARINTENSITYMAP":"",i.specularColorMap?"#define USE_SPECULARCOLORMAP":"",i.roughnessMap?"#define USE_ROUGHNESSMAP":"",i.metalnessMap?"#define USE_METALNESSMAP":"",i.alphaMap?"#define USE_ALPHAMAP":"",i.transmission?"#define USE_TRANSMISSION":"",i.transmissionMap?"#define USE_TRANSMISSIONMAP":"",i.thicknessMap?"#define USE_THICKNESSMAP":"",i.sheenColorMap?"#define USE_SHEENCOLORMAP":"",i.sheenRoughnessMap?"#define USE_SHEENROUGHNESSMAP":"",i.vertexTangents?"#define USE_TANGENT":"",i.vertexColors?"#define USE_COLOR":"",i.vertexAlphas?"#define USE_COLOR_ALPHA":"",i.vertexUvs?"#define USE_UV":"",i.uvsVertexOnly?"#define UVS_VERTEX_ONLY":"",i.flatShading?"#define FLAT_SHADED":"",i.skinning?"#define USE_SKINNING":"",i.morphTargets?"#define USE_MORPHTARGETS":"",i.morphNormals&&!1===i.flatShading?"#define USE_MORPHNORMALS":"",i.morphColors&&i.isWebGL2?"#define USE_MORPHCOLORS":"",i.morphTargetsCount>0&&i.isWebGL2?"#define MORPHTARGETS_TEXTURE":"",i.morphTargetsCount>0&&i.isWebGL2?"#define MORPHTARGETS_TEXTURE_STRIDE "+i.morphTextureStride:"",i.morphTargetsCount>0&&i.isWebGL2?"#define MORPHTARGETS_COUNT "+i.morphTargetsCount:"",i.doubleSided?"#define DOUBLE_SIDED":"",i.flipSided?"#define FLIP_SIDED":"",i.shadowMapEnabled?"#define USE_SHADOWMAP":"",i.shadowMapEnabled?"#define "+u:"",i.sizeAttenuation?"#define USE_SIZEATTENUATION":"",i.logarithmicDepthBuffer?"#define USE_LOGDEPTHBUF":"",i.logarithmicDepthBuffer&&i.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","\tattribute mat4 instanceMatrix;","#endif","#ifdef USE_INSTANCING_COLOR","\tattribute vec3 instanceColor;","#endif","attribute vec3 position;","attribute vec3 normal;","attribute vec2 uv;","#ifdef USE_TANGENT","\tattribute vec4 tangent;","#endif","#if defined( USE_COLOR_ALPHA )","\tattribute vec4 color;","#elif defined( USE_COLOR )","\tattribute vec3 color;","#endif","#if ( defined( USE_MORPHTARGETS ) && ! defined( MORPHTARGETS_TEXTURE ) )","\tattribute vec3 morphTarget0;","\tattribute vec3 morphTarget1;","\tattribute vec3 morphTarget2;","\tattribute vec3 morphTarget3;","\t#ifdef USE_MORPHNORMALS","\t\tattribute vec3 morphNormal0;","\t\tattribute vec3 morphNormal1;","\t\tattribute vec3 morphNormal2;","\t\tattribute vec3 morphNormal3;","\t#else","\t\tattribute vec3 morphTarget4;","\t\tattribute vec3 morphTarget5;","\t\tattribute vec3 morphTarget6;","\t\tattribute vec3 morphTarget7;","\t#endif","#endif","#ifdef USE_SKINNING","\tattribute vec4 skinIndex;","\tattribute vec4 skinWeight;","#endif","\n"].filter(us).join("\n"),y=[g,ys(i),"#define SHADER_NAME "+i.shaderName,v,i.useFog&&i.fog?"#define USE_FOG":"",i.useFog&&i.fogExp2?"#define FOG_EXP2":"",i.map?"#define USE_MAP":"",i.matcap?"#define USE_MATCAP":"",i.envMap?"#define USE_ENVMAP":"",i.envMap?"#define "+d:"",i.envMap?"#define "+p:"",i.envMap?"#define "+m:"",f?"#define CUBEUV_TEXEL_WIDTH "+f.texelWidth:"",f?"#define CUBEUV_TEXEL_HEIGHT "+f.texelHeight:"",f?"#define CUBEUV_MAX_MIP "+f.maxMip+".0":"",i.lightMap?"#define USE_LIGHTMAP":"",i.aoMap?"#define USE_AOMAP":"",i.emissiveMap?"#define USE_EMISSIVEMAP":"",i.bumpMap?"#define USE_BUMPMAP":"",i.normalMap?"#define USE_NORMALMAP":"",i.normalMap&&i.objectSpaceNormalMap?"#define OBJECTSPACE_NORMALMAP":"",i.normalMap&&i.tangentSpaceNormalMap?"#define TANGENTSPACE_NORMALMAP":"",i.clearcoat?"#define USE_CLEARCOAT":"",i.clearcoatMap?"#define USE_CLEARCOATMAP":"",i.clearcoatRoughnessMap?"#define USE_CLEARCOAT_ROUGHNESSMAP":"",i.clearcoatNormalMap?"#define USE_CLEARCOAT_NORMALMAP":"",i.iridescence?"#define USE_IRIDESCENCE":"",i.iridescenceMap?"#define USE_IRIDESCENCEMAP":"",i.iridescenceThicknessMap?"#define USE_IRIDESCENCE_THICKNESSMAP":"",i.specularMap?"#define USE_SPECULARMAP":"",i.specularIntensityMap?"#define USE_SPECULARINTENSITYMAP":"",i.specularColorMap?"#define USE_SPECULARCOLORMAP":"",i.roughnessMap?"#define USE_ROUGHNESSMAP":"",i.metalnessMap?"#define USE_METALNESSMAP":"",i.alphaMap?"#define USE_ALPHAMAP":"",i.alphaTest?"#define USE_ALPHATEST":"",i.sheen?"#define USE_SHEEN":"",i.sheenColorMap?"#define USE_SHEENCOLORMAP":"",i.sheenRoughnessMap?"#define USE_SHEENROUGHNESSMAP":"",i.transmission?"#define USE_TRANSMISSION":"",i.transmissionMap?"#define USE_TRANSMISSIONMAP":"",i.thicknessMap?"#define USE_THICKNESSMAP":"",i.decodeVideoTexture?"#define DECODE_VIDEO_TEXTURE":"",i.vertexTangents?"#define USE_TANGENT":"",i.vertexColors||i.instancingColor?"#define USE_COLOR":"",i.vertexAlphas?"#define USE_COLOR_ALPHA":"",i.vertexUvs?"#define USE_UV":"",i.uvsVertexOnly?"#define UVS_VERTEX_ONLY":"",i.gradientMap?"#define USE_GRADIENTMAP":"",i.flatShading?"#define FLAT_SHADED":"",i.doubleSided?"#define DOUBLE_SIDED":"",i.flipSided?"#define FLIP_SIDED":"",i.shadowMapEnabled?"#define USE_SHADOWMAP":"",i.shadowMapEnabled?"#define "+u:"",i.premultipliedAlpha?"#define PREMULTIPLIED_ALPHA":"",i.physicallyCorrectLights?"#define PHYSICALLY_CORRECT_LIGHTS":"",i.logarithmicDepthBuffer?"#define USE_LOGDEPTHBUF":"",i.logarithmicDepthBuffer&&i.rendererExtensionFragDepth?"#define USE_LOGDEPTHBUF_EXT":"","uniform mat4 viewMatrix;","uniform vec3 cameraPosition;","uniform bool isOrthographic;",0!==i.toneMapping?"#define TONE_MAPPING":"",0!==i.toneMapping?bn.tonemapping_pars_fragment:"",0!==i.toneMapping?hs("toneMapping",i.toneMapping):"",i.dithering?"#define DITHERING":"",i.opaque?"#define OPAQUE":"",bn.encodings_pars_fragment,cs("linearToOutputTexel",i.outputEncoding),i.useDepthPacking?"#define DEPTH_PACKING "+i.depthPacking:"","\n"].filter(us).join("\n")),c=fs(c),c=ds(c,i),c=ps(c,i),h=fs(h),h=ds(h,i),h=ps(h,i),c=xs(c),h=xs(h),i.isWebGL2&&!0!==i.isRawShaderMaterial&&(M="#version 300 es\n",_=["precision mediump sampler2DArray;","#define attribute in","#define varying out","#define texture2D texture"].join("\n")+"\n"+_,y=["#define varying in",i.glslVersion===dt?"":"layout(location = 0) out highp vec4 pc_fragColor;",i.glslVersion===dt?"":"#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"+y);const b=M+y+h,S=as(a,35633,M+_+c),w=as(a,35632,b);if(a.attachShader(x,S),a.attachShader(x,w),void 0!==i.index0AttributeName?a.bindAttribLocation(x,0,i.index0AttributeName):!0===i.morphTargets&&a.bindAttribLocation(x,0,"position"),a.linkProgram(x),t.debug.checkShaderErrors){const t=a.getProgramInfoLog(x).trim(),e=a.getShaderInfoLog(S).trim(),i=a.getShaderInfoLog(w).trim();let n=!0,r=!0;if(!1===a.getProgramParameter(x,35714)){n=!1;const e=ls(a,S,"vertex"),i=ls(a,w,"fragment");console.error("THREE.WebGLProgram: Shader Error "+a.getError()+" - VALIDATE_STATUS "+a.getProgramParameter(x,35715)+"\n\nProgram Info Log: "+t+"\n"+e+"\n"+i)}else""!==t?console.warn("THREE.WebGLProgram: Program Info Log:",t):""!==e&&""!==i||(r=!1);r&&(this.diagnostics={runnable:n,programLog:t,vertexShader:{log:e,prefix:_},fragmentShader:{log:i,prefix:y}})}let T,A;return a.deleteShader(S),a.deleteShader(w),this.getUniforms=function(){return void 0===T&&(T=new ss(a,x)),T},this.getAttributes=function(){return void 0===A&&(A=function(t,e){const i={},n=t.getProgramParameter(e,35721);for(let r=0;r0,D=s.clearcoat>0,N=s.iridescence>0;return{isWebGL2:u,shaderID:S,shaderName:s.type,vertexShader:A,fragmentShader:E,defines:s.defines,customVertexShaderID:C,customFragmentShaderID:L,isRawShaderMaterial:!0===s.isRawShaderMaterial,glslVersion:s.glslVersion,precision:m,instancing:!0===v.isInstancedMesh,instancingColor:!0===v.isInstancedMesh&&null!==v.instanceColor,supportsVertexTextures:p,outputEncoding:null===P?t.outputEncoding:!0===P.isXRRenderTarget?P.texture.encoding:at,map:!!s.map,matcap:!!s.matcap,envMap:!!M,envMapMode:M&&M.mapping,envMapCubeUVHeight:b,lightMap:!!s.lightMap,aoMap:!!s.aoMap,emissiveMap:!!s.emissiveMap,bumpMap:!!s.bumpMap,normalMap:!!s.normalMap,objectSpaceNormalMap:1===s.normalMapType,tangentSpaceNormalMap:0===s.normalMapType,decodeVideoTexture:!!s.map&&!0===s.map.isVideoTexture&&s.map.encoding===ot,clearcoat:D,clearcoatMap:D&&!!s.clearcoatMap,clearcoatRoughnessMap:D&&!!s.clearcoatRoughnessMap,clearcoatNormalMap:D&&!!s.clearcoatNormalMap,iridescence:N,iridescenceMap:N&&!!s.iridescenceMap,iridescenceThicknessMap:N&&!!s.iridescenceThicknessMap,displacementMap:!!s.displacementMap,roughnessMap:!!s.roughnessMap,metalnessMap:!!s.metalnessMap,specularMap:!!s.specularMap,specularIntensityMap:!!s.specularIntensityMap,specularColorMap:!!s.specularColorMap,opaque:!1===s.transparent&&1===s.blending,alphaMap:!!s.alphaMap,alphaTest:I,gradientMap:!!s.gradientMap,sheen:s.sheen>0,sheenColorMap:!!s.sheenColorMap,sheenRoughnessMap:!!s.sheenRoughnessMap,transmission:s.transmission>0,transmissionMap:!!s.transmissionMap,thicknessMap:!!s.thicknessMap,combine:s.combine,vertexTangents:!!s.normalMap&&!!_.attributes.tangent,vertexColors:s.vertexColors,vertexAlphas:!0===s.vertexColors&&!!_.attributes.color&&4===_.attributes.color.itemSize,vertexUvs:!!(s.map||s.bumpMap||s.normalMap||s.specularMap||s.alphaMap||s.emissiveMap||s.roughnessMap||s.metalnessMap||s.clearcoatMap||s.clearcoatRoughnessMap||s.clearcoatNormalMap||s.iridescenceMap||s.iridescenceThicknessMap||s.displacementMap||s.transmissionMap||s.thicknessMap||s.specularIntensityMap||s.specularColorMap||s.sheenColorMap||s.sheenRoughnessMap),uvsVertexOnly:!(s.map||s.bumpMap||s.normalMap||s.specularMap||s.alphaMap||s.emissiveMap||s.roughnessMap||s.metalnessMap||s.clearcoatNormalMap||s.iridescenceMap||s.iridescenceThicknessMap||s.transmission>0||s.transmissionMap||s.thicknessMap||s.specularIntensityMap||s.specularColorMap||s.sheen>0||s.sheenColorMap||s.sheenRoughnessMap||!s.displacementMap),fog:!!x,useFog:!0===s.fog,fogExp2:x&&x.isFogExp2,flatShading:!!s.flatShading,sizeAttenuation:s.sizeAttenuation,logarithmicDepthBuffer:d,skinning:!0===v.isSkinnedMesh,morphTargets:void 0!==_.morphAttributes.position,morphNormals:void 0!==_.morphAttributes.normal,morphColors:void 0!==_.morphAttributes.color,morphTargetsCount:T,morphTextureStride:R,numDirLights:o.directional.length,numPointLights:o.point.length,numSpotLights:o.spot.length,numSpotLightMaps:o.spotLightMap.length,numRectAreaLights:o.rectArea.length,numHemiLights:o.hemi.length,numDirLightShadows:o.directionalShadowMap.length,numPointLightShadows:o.pointShadowMap.length,numSpotLightShadows:o.spotShadowMap.length,numSpotLightShadowsWithMaps:o.numSpotLightShadowsWithMaps,numClippingPlanes:a.numPlanes,numClipIntersection:a.numIntersection,dithering:s.dithering,shadowMapEnabled:t.shadowMap.enabled&&h.length>0,shadowMapType:t.shadowMap.type,toneMapping:s.toneMapped?t.toneMapping:0,physicallyCorrectLights:t.physicallyCorrectLights,premultipliedAlpha:s.premultipliedAlpha,doubleSided:2===s.side,flipSided:1===s.side,useDepthPacking:!!s.depthPacking,depthPacking:s.depthPacking||0,index0AttributeName:s.index0AttributeName,extensionDerivatives:s.extensions&&s.extensions.derivatives,extensionFragDepth:s.extensions&&s.extensions.fragDepth,extensionDrawBuffers:s.extensions&&s.extensions.drawBuffers,extensionShaderTextureLOD:s.extensions&&s.extensions.shaderTextureLOD,rendererExtensionFragDepth:u||n.has("EXT_frag_depth"),rendererExtensionDrawBuffers:u||n.has("WEBGL_draw_buffers"),rendererExtensionShaderTextureLod:u||n.has("EXT_shader_texture_lod"),customProgramCacheKey:s.customProgramCacheKey()}},getProgramCacheKey:function(e){const i=[];if(e.shaderID?i.push(e.shaderID):(i.push(e.customVertexShaderID),i.push(e.customFragmentShaderID)),void 0!==e.defines)for(const t in e.defines)i.push(t),i.push(e.defines[t]);return!1===e.isRawShaderMaterial&&(!function(t,e){t.push(e.precision),t.push(e.outputEncoding),t.push(e.envMapMode),t.push(e.envMapCubeUVHeight),t.push(e.combine),t.push(e.vertexUvs),t.push(e.fogExp2),t.push(e.sizeAttenuation),t.push(e.morphTargetsCount),t.push(e.morphAttributeCount),t.push(e.numDirLights),t.push(e.numPointLights),t.push(e.numSpotLights),t.push(e.numSpotLightMaps),t.push(e.numHemiLights),t.push(e.numRectAreaLights),t.push(e.numDirLightShadows),t.push(e.numPointLightShadows),t.push(e.numSpotLightShadows),t.push(e.numSpotLightShadowsWithMaps),t.push(e.shadowMapType),t.push(e.toneMapping),t.push(e.numClippingPlanes),t.push(e.numClipIntersection),t.push(e.depthPacking)}(i,e),function(t,e){o.disableAll(),e.isWebGL2&&o.enable(0);e.supportsVertexTextures&&o.enable(1);e.instancing&&o.enable(2);e.instancingColor&&o.enable(3);e.map&&o.enable(4);e.matcap&&o.enable(5);e.envMap&&o.enable(6);e.lightMap&&o.enable(7);e.aoMap&&o.enable(8);e.emissiveMap&&o.enable(9);e.bumpMap&&o.enable(10);e.normalMap&&o.enable(11);e.objectSpaceNormalMap&&o.enable(12);e.tangentSpaceNormalMap&&o.enable(13);e.clearcoat&&o.enable(14);e.clearcoatMap&&o.enable(15);e.clearcoatRoughnessMap&&o.enable(16);e.clearcoatNormalMap&&o.enable(17);e.iridescence&&o.enable(18);e.iridescenceMap&&o.enable(19);e.iridescenceThicknessMap&&o.enable(20);e.displacementMap&&o.enable(21);e.specularMap&&o.enable(22);e.roughnessMap&&o.enable(23);e.metalnessMap&&o.enable(24);e.gradientMap&&o.enable(25);e.alphaMap&&o.enable(26);e.alphaTest&&o.enable(27);e.vertexColors&&o.enable(28);e.vertexAlphas&&o.enable(29);e.vertexUvs&&o.enable(30);e.vertexTangents&&o.enable(31);e.uvsVertexOnly&&o.enable(32);t.push(o.mask),o.disableAll(),e.fog&&o.enable(0);e.useFog&&o.enable(1);e.flatShading&&o.enable(2);e.logarithmicDepthBuffer&&o.enable(3);e.skinning&&o.enable(4);e.morphTargets&&o.enable(5);e.morphNormals&&o.enable(6);e.morphColors&&o.enable(7);e.premultipliedAlpha&&o.enable(8);e.shadowMapEnabled&&o.enable(9);e.physicallyCorrectLights&&o.enable(10);e.doubleSided&&o.enable(11);e.flipSided&&o.enable(12);e.useDepthPacking&&o.enable(13);e.dithering&&o.enable(14);e.specularIntensityMap&&o.enable(15);e.specularColorMap&&o.enable(16);e.transmission&&o.enable(17);e.transmissionMap&&o.enable(18);e.thicknessMap&&o.enable(19);e.sheen&&o.enable(20);e.sheenColorMap&&o.enable(21);e.sheenRoughnessMap&&o.enable(22);e.decodeVideoTexture&&o.enable(23);e.opaque&&o.enable(24);t.push(o.mask)}(i,e),i.push(t.outputEncoding)),i.push(e.customProgramCacheKey),i.join()},getUniforms:function(t){const e=f[t.type];let i;if(e){const t=wn[e];i=rn.clone(t.uniforms)}else i=t.uniforms;return i},acquireProgram:function(e,i){let n;for(let t=0,e=h.length;t0?n.push(h):!0===a.transparent?r.push(h):i.push(h)},unshift:function(t,e,a,o,l,c){const h=s(t,e,a,o,l,c);a.transmission>0?n.unshift(h):!0===a.transparent?r.unshift(h):i.unshift(h)},finish:function(){for(let i=e,n=t.length;i1&&i.sort(t||Es),n.length>1&&n.sort(e||Cs),r.length>1&&r.sort(e||Cs)}}}function Rs(){let t=new WeakMap;return{get:function(e,i){const n=t.get(e);let r;return void 0===n?(r=new Ls,t.set(e,[r])):i>=n.length?(r=new Ls,n.push(r)):r=n[i],r},dispose:function(){t=new WeakMap}}}function Ps(){const t={};return{get:function(e){if(void 0!==t[e.id])return t[e.id];let i;switch(e.type){case"DirectionalLight":i={direction:new re,color:new qt};break;case"SpotLight":i={position:new re,direction:new re,color:new qt,distance:0,coneCos:0,penumbraCos:0,decay:0};break;case"PointLight":i={position:new re,color:new qt,distance:0,decay:0};break;case"HemisphereLight":i={direction:new re,skyColor:new qt,groundColor:new qt};break;case"RectAreaLight":i={color:new qt,position:new re,halfWidth:new re,halfHeight:new re}}return t[e.id]=i,i}}}let Is=0;function Ds(t,e){return(e.castShadow?2:0)-(t.castShadow?2:0)+(e.map?1:0)-(t.map?1:0)}function Ns(t,e){const i=new Ps,n=function(){const t={};return{get:function(e){if(void 0!==t[e.id])return t[e.id];let i;switch(e.type){case"DirectionalLight":case"SpotLight":i={shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowMapSize:new Lt};break;case"PointLight":i={shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowMapSize:new Lt,shadowCameraNear:1,shadowCameraFar:1e3}}return t[e.id]=i,i}}}(),r={version:0,hash:{directionalLength:-1,pointLength:-1,spotLength:-1,rectAreaLength:-1,hemiLength:-1,numDirectionalShadows:-1,numPointShadows:-1,numSpotShadows:-1,numSpotMaps:-1},ambient:[0,0,0],probe:[],directional:[],directionalShadow:[],directionalShadowMap:[],directionalShadowMatrix:[],spot:[],spotLightMap:[],spotShadow:[],spotShadowMap:[],spotLightMatrix:[],rectArea:[],rectAreaLTC1:null,rectAreaLTC2:null,point:[],pointShadow:[],pointShadowMap:[],pointShadowMatrix:[],hemi:[],numSpotLightShadowsWithMaps:0};for(let t=0;t<9;t++)r.probe.push(new re);const s=new re,a=new Ne,o=new Ne;return{setup:function(s,a){let o=0,l=0,c=0;for(let t=0;t<9;t++)r.probe[t].set(0,0,0);let h=0,u=0,d=0,p=0,m=0,f=0,g=0,v=0,x=0,_=0;s.sort(Ds);const y=!0!==a?Math.PI:1;for(let t=0,e=s.length;t0&&(e.isWebGL2||!0===t.has("OES_texture_float_linear")?(r.rectAreaLTC1=Sn.LTC_FLOAT_1,r.rectAreaLTC2=Sn.LTC_FLOAT_2):!0===t.has("OES_texture_half_float_linear")?(r.rectAreaLTC1=Sn.LTC_HALF_1,r.rectAreaLTC2=Sn.LTC_HALF_2):console.error("THREE.WebGLRenderer: Unable to use RectAreaLight. Missing WebGL extensions.")),r.ambient[0]=o,r.ambient[1]=l,r.ambient[2]=c;const M=r.hash;M.directionalLength===h&&M.pointLength===u&&M.spotLength===d&&M.rectAreaLength===p&&M.hemiLength===m&&M.numDirectionalShadows===f&&M.numPointShadows===g&&M.numSpotShadows===v&&M.numSpotMaps===x||(r.directional.length=h,r.spot.length=d,r.rectArea.length=p,r.point.length=u,r.hemi.length=m,r.directionalShadow.length=f,r.directionalShadowMap.length=f,r.pointShadow.length=g,r.pointShadowMap.length=g,r.spotShadow.length=v,r.spotShadowMap.length=v,r.directionalShadowMatrix.length=f,r.pointShadowMatrix.length=g,r.spotLightMatrix.length=v+x-_,r.spotLightMap.length=x,r.numSpotLightShadowsWithMaps=_,M.directionalLength=h,M.pointLength=u,M.spotLength=d,M.rectAreaLength=p,M.hemiLength=m,M.numDirectionalShadows=f,M.numPointShadows=g,M.numSpotShadows=v,M.numSpotMaps=x,r.version=Is++)},setupView:function(t,e){let i=0,n=0,l=0,c=0,h=0;const u=e.matrixWorldInverse;for(let e=0,d=t.length;e=s.length?(a=new Os(t,e),s.push(a)):a=s[r],a},dispose:function(){i=new WeakMap}}}class Us extends xi{constructor(t){super(),this.isMeshDepthMaterial=!0,this.type="MeshDepthMaterial",this.depthPacking=3200,this.map=null,this.alphaMap=null,this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.wireframe=!1,this.wireframeLinewidth=1,this.setValues(t)}copy(t){return super.copy(t),this.depthPacking=t.depthPacking,this.map=t.map,this.alphaMap=t.alphaMap,this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this}}class Bs extends xi{constructor(t){super(),this.isMeshDistanceMaterial=!0,this.type="MeshDistanceMaterial",this.referencePosition=new re,this.nearDistance=1,this.farDistance=1e3,this.map=null,this.alphaMap=null,this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.setValues(t)}copy(t){return super.copy(t),this.referencePosition.copy(t.referencePosition),this.nearDistance=t.nearDistance,this.farDistance=t.farDistance,this.map=t.map,this.alphaMap=t.alphaMap,this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this}}function Fs(t,e,i){let n=new xn;const r=new Lt,s=new Lt,a=new Qt,o=new Us({depthPacking:3201}),l=new Bs,c={},h=i.maxTextureSize,u={0:1,1:0,2:2},p=new sn({defines:{VSM_SAMPLES:8},uniforms:{shadow_pass:{value:null},resolution:{value:new Lt},radius:{value:4}},vertexShader:"void main() {\n\tgl_Position = vec4( position, 1.0 );\n}",fragmentShader:"uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include \nvoid main() {\n\tconst float samples = float( VSM_SAMPLES );\n\tfloat mean = 0.0;\n\tfloat squared_mean = 0.0;\n\tfloat uvStride = samples <= 1.0 ? 0.0 : 2.0 / ( samples - 1.0 );\n\tfloat uvStart = samples <= 1.0 ? 0.0 : - 1.0;\n\tfor ( float i = 0.0; i < samples; i ++ ) {\n\t\tfloat uvOffset = uvStart + i * uvStride;\n\t\t#ifdef HORIZONTAL_PASS\n\t\t\tvec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( uvOffset, 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, uvOffset ) * radius ) / resolution ) );\n\t\t\tmean += depth;\n\t\t\tsquared_mean += depth * depth;\n\t\t#endif\n\t}\n\tmean = mean / samples;\n\tsquared_mean = squared_mean / samples;\n\tfloat std_dev = sqrt( squared_mean - mean * mean );\n\tgl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}"}),m=p.clone();m.defines.HORIZONTAL_PASS=1;const f=new Di;f.setAttribute("position",new bi(new Float32Array([-1,-1,.5,3,-1,.5,-1,3,.5]),3));const g=new Ki(f,p),v=this;function x(i,n){const s=e.update(g);p.defines.VSM_SAMPLES!==i.blurSamples&&(p.defines.VSM_SAMPLES=i.blurSamples,m.defines.VSM_SAMPLES=i.blurSamples,p.needsUpdate=!0,m.needsUpdate=!0),null===i.mapPass&&(i.mapPass=new te(r.x,r.y)),p.uniforms.shadow_pass.value=i.map.texture,p.uniforms.resolution.value=i.mapSize,p.uniforms.radius.value=i.radius,t.setRenderTarget(i.mapPass),t.clear(),t.renderBufferDirect(n,null,s,p,g,null),m.uniforms.shadow_pass.value=i.mapPass.texture,m.uniforms.resolution.value=i.mapSize,m.uniforms.radius.value=i.radius,t.setRenderTarget(i.map),t.clear(),t.renderBufferDirect(n,null,s,m,g,null)}function _(e,i,n,r,s,a){let h=null;const d=!0===n.isPointLight?e.customDistanceMaterial:e.customDepthMaterial;if(h=void 0!==d?d:!0===n.isPointLight?l:o,t.localClippingEnabled&&!0===i.clipShadows&&Array.isArray(i.clippingPlanes)&&0!==i.clippingPlanes.length||i.displacementMap&&0!==i.displacementScale||i.alphaMap&&i.alphaTest>0||i.map&&i.alphaTest>0){const t=h.uuid,e=i.uuid;let n=c[t];void 0===n&&(n={},c[t]=n);let r=n[e];void 0===r&&(r=h.clone(),n[e]=r),h=r}return h.visible=i.visible,h.wireframe=i.wireframe,h.side=3===a?null!==i.shadowSide?i.shadowSide:i.side:null!==i.shadowSide?i.shadowSide:u[i.side],h.alphaMap=i.alphaMap,h.alphaTest=i.alphaTest,h.map=i.map,h.clipShadows=i.clipShadows,h.clippingPlanes=i.clippingPlanes,h.clipIntersection=i.clipIntersection,h.displacementMap=i.displacementMap,h.displacementScale=i.displacementScale,h.displacementBias=i.displacementBias,h.wireframeLinewidth=i.wireframeLinewidth,h.linewidth=i.linewidth,!0===n.isPointLight&&!0===h.isMeshDistanceMaterial&&(h.referencePosition.setFromMatrixPosition(n.matrixWorld),h.nearDistance=r,h.farDistance=s),h}function y(i,r,s,a,o){if(!1===i.visible)return;if(i.layers.test(r.layers)&&(i.isMesh||i.isLine||i.isPoints)&&(i.castShadow||i.receiveShadow&&3===o)&&(!i.frustumCulled||n.intersectsObject(i))){i.modelViewMatrix.multiplyMatrices(s.matrixWorldInverse,i.matrixWorld);const n=e.update(i),r=i.material;if(Array.isArray(r)){const e=n.groups;for(let l=0,c=e.length;lh||r.y>h)&&(r.x>h&&(s.x=Math.floor(h/m.x),r.x=s.x*m.x,u.mapSize.x=s.x),r.y>h&&(s.y=Math.floor(h/m.y),r.y=s.y*m.y,u.mapSize.y=s.y)),null===u.map){const t=3!==this.type?{minFilter:d,magFilter:d}:{};u.map=new te(r.x,r.y,t),u.map.texture.name=c.name+".shadowMap",u.camera.updateProjectionMatrix()}t.setRenderTarget(u.map),t.clear();const f=u.getViewportCount();for(let t=0;t=1):-1!==I.indexOf("OpenGL ES")&&(P=parseFloat(/^OpenGL ES (\d)/.exec(I)[1]),R=P>=2);let D=null,N={};const O=t.getParameter(3088),z=t.getParameter(2978),U=(new Qt).fromArray(O),B=(new Qt).fromArray(z);function F(e,i,n){const r=new Uint8Array(4),s=t.createTexture();t.bindTexture(e,s),t.texParameteri(e,10241,9728),t.texParameteri(e,10240,9728);for(let e=0;en||t.height>n)&&(r=n/Math.max(t.width,t.height)),r<1||!0===e){if("undefined"!=typeof HTMLImageElement&&t instanceof HTMLImageElement||"undefined"!=typeof HTMLCanvasElement&&t instanceof HTMLCanvasElement||"undefined"!=typeof ImageBitmap&&t instanceof ImageBitmap){const n=e?Tt:Math.floor,s=n(r*t.width),a=n(r*t.height);void 0===D&&(D=z(s,a));const o=i?z(s,a):D;o.width=s,o.height=a;return o.getContext("2d").drawImage(t,0,0,s,a),console.warn("THREE.WebGLRenderer: Texture has been resized from ("+t.width+"x"+t.height+") to ("+s+"x"+a+")."),o}return"data"in t&&console.warn("THREE.WebGLRenderer: Image in DataTexture is too big ("+t.width+"x"+t.height+")."),t}return t}function B(t){return St(t.width)&&St(t.height)}function F(t,e){return t.generateMipmaps&&e&&t.minFilter!==d&&t.minFilter!==f}function k(e){t.generateMipmap(e)}function G(i,n,r,s,a=!1){if(!1===o)return n;if(null!==i){if(void 0!==t[i])return t[i];console.warn("THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format '"+i+"'")}let l=n;return 6403===n&&(5126===r&&(l=33326),5131===r&&(l=33325),5121===r&&(l=33321)),33319===n&&(5126===r&&(l=33328),5131===r&&(l=33327),5121===r&&(l=33323)),6408===n&&(5126===r&&(l=34836),5131===r&&(l=34842),5121===r&&(l=s===ot&&!1===a?35907:32856),32819===r&&(l=32854),32820===r&&(l=32855)),33325!==l&&33326!==l&&33327!==l&&33328!==l&&34842!==l&&34836!==l||e.get("EXT_color_buffer_float"),l}function V(t,e,i){return!0===F(t,i)||t.isFramebufferTexture&&t.minFilter!==d&&t.minFilter!==f?Math.log2(Math.max(e.width,e.height))+1:void 0!==t.mipmaps&&t.mipmaps.length>0?t.mipmaps.length:t.isCompressedTexture&&Array.isArray(t.image)?e.mipmaps.length:1}function H(t){return t===d||t===p||t===m?9728:9729}function W(t){const e=t.target;e.removeEventListener("dispose",W),function(t){const e=n.get(t);if(void 0===e.__webglInit)return;const i=t.source,r=N.get(i);if(r){const n=r[e.__cacheKey];n.usedTimes--,0===n.usedTimes&&q(t),0===Object.keys(r).length&&N.delete(i)}n.remove(t)}(e),e.isVideoTexture&&I.delete(e)}function j(e){const i=e.target;i.removeEventListener("dispose",j),function(e){const i=e.texture,r=n.get(e),s=n.get(i);void 0!==s.__webglTexture&&(t.deleteTexture(s.__webglTexture),a.memory.textures--);e.depthTexture&&e.depthTexture.dispose();if(e.isWebGLCubeRenderTarget)for(let e=0;e<6;e++)t.deleteFramebuffer(r.__webglFramebuffer[e]),r.__webglDepthbuffer&&t.deleteRenderbuffer(r.__webglDepthbuffer[e]);else{if(t.deleteFramebuffer(r.__webglFramebuffer),r.__webglDepthbuffer&&t.deleteRenderbuffer(r.__webglDepthbuffer),r.__webglMultisampledFramebuffer&&t.deleteFramebuffer(r.__webglMultisampledFramebuffer),r.__webglColorRenderbuffer)for(let e=0;e0&&r.__version!==t.version){const i=t.image;if(null===i)console.warn("THREE.WebGLRenderer: Texture marked for update but no image data found.");else{if(!1!==i.complete)return void Q(r,t,e);console.warn("THREE.WebGLRenderer: Texture marked for update but image is incomplete")}}i.bindTexture(3553,r.__webglTexture,33984+e)}const Z={[c]:10497,[h]:33071,[u]:33648},J={[d]:9728,[p]:9984,[m]:9986,[f]:9729,[g]:9985,[v]:9987};function K(i,s,a){if(a?(t.texParameteri(i,10242,Z[s.wrapS]),t.texParameteri(i,10243,Z[s.wrapT]),32879!==i&&35866!==i||t.texParameteri(i,32882,Z[s.wrapR]),t.texParameteri(i,10240,J[s.magFilter]),t.texParameteri(i,10241,J[s.minFilter])):(t.texParameteri(i,10242,33071),t.texParameteri(i,10243,33071),32879!==i&&35866!==i||t.texParameteri(i,32882,33071),s.wrapS===h&&s.wrapT===h||console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping."),t.texParameteri(i,10240,H(s.magFilter)),t.texParameteri(i,10241,H(s.minFilter)),s.minFilter!==d&&s.minFilter!==f&&console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.")),!0===e.has("EXT_texture_filter_anisotropic")){const a=e.get("EXT_texture_filter_anisotropic");if(s.type===M&&!1===e.has("OES_texture_float_linear"))return;if(!1===o&&s.type===b&&!1===e.has("OES_texture_half_float_linear"))return;(s.anisotropy>1||n.get(s).__currentAnisotropy)&&(t.texParameterf(i,a.TEXTURE_MAX_ANISOTROPY_EXT,Math.min(s.anisotropy,r.getMaxAnisotropy())),n.get(s).__currentAnisotropy=s.anisotropy)}}function $(e,i){let n=!1;void 0===e.__webglInit&&(e.__webglInit=!0,i.addEventListener("dispose",W));const r=i.source;let s=N.get(r);void 0===s&&(s={},N.set(r,s));const o=function(t){const e=[];return e.push(t.wrapS),e.push(t.wrapT),e.push(t.wrapR||0),e.push(t.magFilter),e.push(t.minFilter),e.push(t.anisotropy),e.push(t.internalFormat),e.push(t.format),e.push(t.type),e.push(t.generateMipmaps),e.push(t.premultiplyAlpha),e.push(t.flipY),e.push(t.unpackAlignment),e.push(t.encoding),e.join()}(i);if(o!==e.__cacheKey){void 0===s[o]&&(s[o]={texture:t.createTexture(),usedTimes:0},a.memory.textures++,n=!0),s[o].usedTimes++;const r=s[e.__cacheKey];void 0!==r&&(s[e.__cacheKey].usedTimes--,0===r.usedTimes&&q(i)),e.__cacheKey=o,e.__webglTexture=s[o].texture}return n}function Q(e,r,a){let l=3553;(r.isDataArrayTexture||r.isCompressedArrayTexture)&&(l=35866),r.isData3DTexture&&(l=32879);const c=$(e,r),u=r.source;i.bindTexture(l,e.__webglTexture,33984+a);const p=n.get(u);if(u.version!==p.__version||!0===c){i.activeTexture(33984+a),t.pixelStorei(37440,r.flipY),t.pixelStorei(37441,r.premultiplyAlpha),t.pixelStorei(3317,r.unpackAlignment),t.pixelStorei(37443,0);const e=function(t){return!o&&(t.wrapS!==h||t.wrapT!==h||t.minFilter!==d&&t.minFilter!==f)}(r)&&!1===B(r.image);let n=U(r.image,e,!1,C);n=st(r,n);const m=B(n)||o,g=s.convert(r.format,r.encoding);let v,x=s.convert(r.type),b=G(r.internalFormat,g,x,r.encoding,r.isVideoTexture);K(l,r,m);const E=r.mipmaps,L=o&&!0!==r.isVideoTexture,R=void 0===p.__version||!0===c,P=V(r,n,m);if(r.isDepthTexture)b=6402,o?b=r.type===M?36012:r.type===y?33190:r.type===S?35056:33189:r.type===M&&console.error("WebGLRenderer: Floating point depth texture requires WebGL2."),r.format===T&&6402===b&&r.type!==_&&r.type!==y&&(console.warn("THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture."),r.type=y,x=s.convert(r.type)),r.format===A&&6402===b&&(b=34041,r.type!==S&&(console.warn("THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture."),r.type=S,x=s.convert(r.type))),R&&(L?i.texStorage2D(3553,1,b,n.width,n.height):i.texImage2D(3553,0,b,n.width,n.height,0,g,x,null));else if(r.isDataTexture)if(E.length>0&&m){L&&R&&i.texStorage2D(3553,P,b,E[0].width,E[0].height);for(let t=0,e=E.length;t>=1,e>>=1}}else if(E.length>0&&m){L&&R&&i.texStorage2D(3553,P,b,E[0].width,E[0].height);for(let t=0,e=E.length;t=34069&&l<=34074)&&t.framebufferTexture2D(36160,o,l,n.get(a).__webglTexture,0),i.bindFramebuffer(36160,null)}function et(e,i,n){if(t.bindRenderbuffer(36161,e),i.depthBuffer&&!i.stencilBuffer){let r=33189;if(n||rt(i)){const e=i.depthTexture;e&&e.isDepthTexture&&(e.type===M?r=36012:e.type===y&&(r=33190));const n=nt(i);rt(i)?R.renderbufferStorageMultisampleEXT(36161,n,r,i.width,i.height):t.renderbufferStorageMultisample(36161,n,r,i.width,i.height)}else t.renderbufferStorage(36161,r,i.width,i.height);t.framebufferRenderbuffer(36160,36096,36161,e)}else if(i.depthBuffer&&i.stencilBuffer){const r=nt(i);n&&!1===rt(i)?t.renderbufferStorageMultisample(36161,r,35056,i.width,i.height):rt(i)?R.renderbufferStorageMultisampleEXT(36161,r,35056,i.width,i.height):t.renderbufferStorage(36161,34041,i.width,i.height),t.framebufferRenderbuffer(36160,33306,36161,e)}else{const e=!0===i.isWebGLMultipleRenderTargets?i.texture:[i.texture];for(let r=0;r0&&!0===e.has("WEBGL_multisampled_render_to_texture")&&!1!==i.__useRenderToTexture}function st(t,i){const n=t.encoding,r=t.format,s=t.type;return!0===t.isCompressedTexture||!0===t.isVideoTexture||t.format===pt||n!==at&&(n===ot?!1===o?!0===e.has("EXT_sRGB")&&r===w?(t.format=pt,t.minFilter=f,t.generateMipmaps=!1):i=Yt.sRGBToLinear(i):r===w&&s===x||console.warn("THREE.WebGLTextures: sRGB encoded textures have to use RGBAFormat and UnsignedByteType."):console.error("THREE.WebGLTextures: Unsupported texture encoding:",n)),i}this.allocateTextureUnit=function(){const t=X;return t>=l&&console.warn("THREE.WebGLTextures: Trying to use "+t+" texture units while this GPU supports only "+l),X+=1,t},this.resetTextureUnits=function(){X=0},this.setTexture2D=Y,this.setTexture2DArray=function(t,e){const r=n.get(t);t.version>0&&r.__version!==t.version?Q(r,t,e):i.bindTexture(35866,r.__webglTexture,33984+e)},this.setTexture3D=function(t,e){const r=n.get(t);t.version>0&&r.__version!==t.version?Q(r,t,e):i.bindTexture(32879,r.__webglTexture,33984+e)},this.setTextureCube=function(e,r){const a=n.get(e);e.version>0&&a.__version!==e.version?function(e,r,a){if(6!==r.image.length)return;const l=$(e,r),c=r.source;i.bindTexture(34067,e.__webglTexture,33984+a);const h=n.get(c);if(c.version!==h.__version||!0===l){i.activeTexture(33984+a),t.pixelStorei(37440,r.flipY),t.pixelStorei(37441,r.premultiplyAlpha),t.pixelStorei(3317,r.unpackAlignment),t.pixelStorei(37443,0);const e=r.isCompressedTexture||r.image[0].isCompressedTexture,n=r.image[0]&&r.image[0].isDataTexture,u=[];for(let t=0;t<6;t++)u[t]=e||n?n?r.image[t].image:r.image[t]:U(r.image[t],!1,!0,E),u[t]=st(r,u[t]);const d=u[0],p=B(d)||o,m=s.convert(r.format,r.encoding),f=s.convert(r.type),g=G(r.internalFormat,m,f,r.encoding),v=o&&!0!==r.isVideoTexture,x=void 0===h.__version||!0===l;let _,y=V(r,d,p);if(K(34067,r,p),e){v&&x&&i.texStorage2D(34067,y,g,d.width,d.height);for(let t=0;t<6;t++){_=u[t].mipmaps;for(let e=0;e<_.length;e++){const n=_[e];r.format!==w?null!==m?v?i.compressedTexSubImage2D(34069+t,e,0,0,n.width,n.height,m,n.data):i.compressedTexImage2D(34069+t,e,g,n.width,n.height,0,n.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()"):v?i.texSubImage2D(34069+t,e,0,0,n.width,n.height,m,f,n.data):i.texImage2D(34069+t,e,g,n.width,n.height,0,m,f,n.data)}}}else{_=r.mipmaps,v&&x&&(_.length>0&&y++,i.texStorage2D(34067,y,g,u[0].width,u[0].height));for(let t=0;t<6;t++)if(n){v?i.texSubImage2D(34069+t,0,0,0,u[t].width,u[t].height,m,f,u[t].data):i.texImage2D(34069+t,0,g,u[t].width,u[t].height,0,m,f,u[t].data);for(let e=0;e<_.length;e++){const n=_[e].image[t].image;v?i.texSubImage2D(34069+t,e+1,0,0,n.width,n.height,m,f,n.data):i.texImage2D(34069+t,e+1,g,n.width,n.height,0,m,f,n.data)}}else{v?i.texSubImage2D(34069+t,0,0,0,m,f,u[t]):i.texImage2D(34069+t,0,g,m,f,u[t]);for(let e=0;e<_.length;e++){const n=_[e];v?i.texSubImage2D(34069+t,e+1,0,0,m,f,n.image[t]):i.texImage2D(34069+t,e+1,g,m,f,n.image[t])}}}F(r,p)&&k(34067),h.__version=c.version,r.onUpdate&&r.onUpdate(r)}e.__version=r.version}(a,e,r):i.bindTexture(34067,a.__webglTexture,33984+r)},this.rebindTextures=function(t,e,i){const r=n.get(t);void 0!==e&&tt(r.__webglFramebuffer,t,t.texture,36064,3553),void 0!==i&&it(t)},this.setupRenderTarget=function(e){const l=e.texture,c=n.get(e),h=n.get(l);e.addEventListener("dispose",j),!0!==e.isWebGLMultipleRenderTargets&&(void 0===h.__webglTexture&&(h.__webglTexture=t.createTexture()),h.__version=l.version,a.memory.textures++);const u=!0===e.isWebGLCubeRenderTarget,d=!0===e.isWebGLMultipleRenderTargets,p=B(e)||o;if(u){c.__webglFramebuffer=[];for(let e=0;e<6;e++)c.__webglFramebuffer[e]=t.createFramebuffer()}else{if(c.__webglFramebuffer=t.createFramebuffer(),d)if(r.drawBuffers){const i=e.texture;for(let e=0,r=i.length;e0&&!1===rt(e)){const n=d?l:[l];c.__webglMultisampledFramebuffer=t.createFramebuffer(),c.__webglColorRenderbuffer=[],i.bindFramebuffer(36160,c.__webglMultisampledFramebuffer);for(let i=0;i0&&!1===rt(e)){const r=e.isWebGLMultipleRenderTargets?e.texture:[e.texture],s=e.width,a=e.height;let o=16384;const l=[],c=e.stencilBuffer?33306:36096,h=n.get(e),u=!0===e.isWebGLMultipleRenderTargets;if(u)for(let e=0;eo+c?(l.inputState.pinching=!1,this.dispatchEvent({type:"pinchend",handedness:t.handedness,target:this})):!l.inputState.pinching&&a<=o-c&&(l.inputState.pinching=!0,this.dispatchEvent({type:"pinchstart",handedness:t.handedness,target:this}))}else null!==o&&t.gripSpace&&(r=e.getPose(t.gripSpace,i),null!==r&&(o.matrix.fromArray(r.transform.matrix),o.matrix.decompose(o.position,o.rotation,o.scale),r.linearVelocity?(o.hasLinearVelocity=!0,o.linearVelocity.copy(r.linearVelocity)):o.hasLinearVelocity=!1,r.angularVelocity?(o.hasAngularVelocity=!0,o.angularVelocity.copy(r.angularVelocity)):o.hasAngularVelocity=!1));null!==a&&(n=e.getPose(t.targetRaySpace,i),null===n&&null!==r&&(n=r),null!==n&&(a.matrix.fromArray(n.transform.matrix),a.matrix.decompose(a.position,a.rotation,a.scale),n.linearVelocity?(a.hasLinearVelocity=!0,a.linearVelocity.copy(n.linearVelocity)):a.hasLinearVelocity=!1,n.angularVelocity?(a.hasAngularVelocity=!0,a.angularVelocity.copy(n.angularVelocity)):a.hasAngularVelocity=!1,this.dispatchEvent(js)))}return null!==a&&(a.visible=null!==n),null!==o&&(o.visible=null!==r),null!==l&&(l.visible=null!==s),this}_getHandJoint(t,e){if(void 0===t.joints[e.jointName]){const i=new Ws;i.matrixAutoUpdate=!1,i.visible=!1,t.joints[e.jointName]=i,t.add(i)}return t.joints[e.jointName]}}class Xs extends $t{constructor(t,e,i,n,r,s,a,o,l,c){if((c=void 0!==c?c:T)!==T&&c!==A)throw new Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat");void 0===i&&c===T&&(i=y),void 0===i&&c===A&&(i=S),super(null,n,r,s,a,o,c,i,l),this.isDepthTexture=!0,this.image={width:t,height:e},this.magFilter=void 0!==a?a:d,this.minFilter=void 0!==o?o:d,this.flipY=!1,this.generateMipmaps=!1}}class Ys extends mt{constructor(t,e){super();const i=this;let n=null,r=1,s=null,a="local-floor",o=null,l=null,c=null,h=null,u=null,d=null;const p=e.getContextAttributes();let m=null,f=null;const g=[],v=[],_=new Set,M=new Map,b=new on;b.layers.enable(1),b.viewport=new Qt;const E=new on;E.layers.enable(2),E.viewport=new Qt;const C=[b,E],L=new Hs;L.layers.enable(1),L.layers.enable(2);let R=null,P=null;function I(t){const e=v.indexOf(t.inputSource);if(-1===e)return;const i=g[e];void 0!==i&&i.dispatchEvent({type:t.type,data:t.inputSource})}function D(){n.removeEventListener("select",I),n.removeEventListener("selectstart",I),n.removeEventListener("selectend",I),n.removeEventListener("squeeze",I),n.removeEventListener("squeezestart",I),n.removeEventListener("squeezeend",I),n.removeEventListener("end",D),n.removeEventListener("inputsourceschange",N);for(let t=0;t=0&&(v[n]=null,g[n].disconnect(i))}for(let e=0;e=v.length){v.push(i),n=t;break}if(null===v[t]){v[t]=i,n=t;break}}if(-1===n)break}const r=g[n];r&&r.connect(i)}}this.cameraAutoUpdate=!0,this.enabled=!1,this.isPresenting=!1,this.getController=function(t){let e=g[t];return void 0===e&&(e=new qs,g[t]=e),e.getTargetRaySpace()},this.getControllerGrip=function(t){let e=g[t];return void 0===e&&(e=new qs,g[t]=e),e.getGripSpace()},this.getHand=function(t){let e=g[t];return void 0===e&&(e=new qs,g[t]=e),e.getHandSpace()},this.setFramebufferScaleFactor=function(t){r=t,!0===i.isPresenting&&console.warn("THREE.WebXRManager: Cannot change framebuffer scale while presenting.")},this.setReferenceSpaceType=function(t){a=t,!0===i.isPresenting&&console.warn("THREE.WebXRManager: Cannot change reference space type while presenting.")},this.getReferenceSpace=function(){return o||s},this.setReferenceSpace=function(t){o=t},this.getBaseLayer=function(){return null!==h?h:u},this.getBinding=function(){return c},this.getFrame=function(){return d},this.getSession=function(){return n},this.setSession=async function(l){if(n=l,null!==n){if(m=t.getRenderTarget(),n.addEventListener("select",I),n.addEventListener("selectstart",I),n.addEventListener("selectend",I),n.addEventListener("squeeze",I),n.addEventListener("squeezestart",I),n.addEventListener("squeezeend",I),n.addEventListener("end",D),n.addEventListener("inputsourceschange",N),!0!==p.xrCompatible&&await e.makeXRCompatible(),void 0===n.renderState.layers||!1===t.capabilities.isWebGL2){const i={antialias:void 0!==n.renderState.layers||p.antialias,alpha:p.alpha,depth:p.depth,stencil:p.stencil,framebufferScaleFactor:r};u=new XRWebGLLayer(n,e,i),n.updateRenderState({baseLayer:u}),f=new te(u.framebufferWidth,u.framebufferHeight,{format:w,type:x,encoding:t.outputEncoding,stencilBuffer:p.stencil})}else{let i=null,s=null,a=null;p.depth&&(a=p.stencil?35056:33190,i=p.stencil?A:T,s=p.stencil?S:y);const o={colorFormat:32856,depthFormat:a,scaleFactor:r};c=new XRWebGLBinding(n,e),h=c.createProjectionLayer(o),n.updateRenderState({layers:[h]}),f=new te(h.textureWidth,h.textureHeight,{format:w,type:x,depthTexture:new Xs(h.textureWidth,h.textureHeight,s,void 0,void 0,void 0,void 0,void 0,void 0,i),stencilBuffer:p.stencil,encoding:t.outputEncoding,samples:p.antialias?4:0});t.properties.get(f).__ignoreDepthValues=h.ignoreDepthValues}f.isXRRenderTarget=!0,this.setFoveation(1),o=null,s=await n.requestReferenceSpace(a),F.setContext(n),F.start(),i.isPresenting=!0,i.dispatchEvent({type:"sessionstart"})}};const O=new re,z=new re;function U(t,e){null===e?t.matrixWorld.copy(t.matrix):t.matrixWorld.multiplyMatrices(e.matrixWorld,t.matrix),t.matrixWorldInverse.copy(t.matrixWorld).invert()}this.updateCamera=function(t){if(null===n)return;L.near=E.near=b.near=t.near,L.far=E.far=b.far=t.far,R===L.near&&P===L.far||(n.updateRenderState({depthNear:L.near,depthFar:L.far}),R=L.near,P=L.far);const e=t.parent,i=L.cameras;U(L,e);for(let t=0;te&&(M.set(t,t.lastChangedTime),i.dispatchEvent({type:"planechanged",data:t}))}else _.add(t),M.set(t,n.lastChangedTime),i.dispatchEvent({type:"planeadded",data:t})}d=null})),this.setAnimationLoop=function(t){B=t},this.dispose=function(){}}}function Zs(t,e){function i(i,n){i.opacity.value=n.opacity,n.color&&i.diffuse.value.copy(n.color),n.emissive&&i.emissive.value.copy(n.emissive).multiplyScalar(n.emissiveIntensity),n.map&&(i.map.value=n.map),n.alphaMap&&(i.alphaMap.value=n.alphaMap),n.bumpMap&&(i.bumpMap.value=n.bumpMap,i.bumpScale.value=n.bumpScale,1===n.side&&(i.bumpScale.value*=-1)),n.displacementMap&&(i.displacementMap.value=n.displacementMap,i.displacementScale.value=n.displacementScale,i.displacementBias.value=n.displacementBias),n.emissiveMap&&(i.emissiveMap.value=n.emissiveMap),n.normalMap&&(i.normalMap.value=n.normalMap,i.normalScale.value.copy(n.normalScale),1===n.side&&i.normalScale.value.negate()),n.specularMap&&(i.specularMap.value=n.specularMap),n.alphaTest>0&&(i.alphaTest.value=n.alphaTest);const r=e.get(n).envMap;if(r&&(i.envMap.value=r,i.flipEnvMap.value=r.isCubeTexture&&!1===r.isRenderTargetTexture?-1:1,i.reflectivity.value=n.reflectivity,i.ior.value=n.ior,i.refractionRatio.value=n.refractionRatio),n.lightMap){i.lightMap.value=n.lightMap;const e=!0!==t.physicallyCorrectLights?Math.PI:1;i.lightMapIntensity.value=n.lightMapIntensity*e}let s,a;n.aoMap&&(i.aoMap.value=n.aoMap,i.aoMapIntensity.value=n.aoMapIntensity),n.map?s=n.map:n.specularMap?s=n.specularMap:n.displacementMap?s=n.displacementMap:n.normalMap?s=n.normalMap:n.bumpMap?s=n.bumpMap:n.roughnessMap?s=n.roughnessMap:n.metalnessMap?s=n.metalnessMap:n.alphaMap?s=n.alphaMap:n.emissiveMap?s=n.emissiveMap:n.clearcoatMap?s=n.clearcoatMap:n.clearcoatNormalMap?s=n.clearcoatNormalMap:n.clearcoatRoughnessMap?s=n.clearcoatRoughnessMap:n.iridescenceMap?s=n.iridescenceMap:n.iridescenceThicknessMap?s=n.iridescenceThicknessMap:n.specularIntensityMap?s=n.specularIntensityMap:n.specularColorMap?s=n.specularColorMap:n.transmissionMap?s=n.transmissionMap:n.thicknessMap?s=n.thicknessMap:n.sheenColorMap?s=n.sheenColorMap:n.sheenRoughnessMap&&(s=n.sheenRoughnessMap),void 0!==s&&(s.isWebGLRenderTarget&&(s=s.texture),!0===s.matrixAutoUpdate&&s.updateMatrix(),i.uvTransform.value.copy(s.matrix)),n.aoMap?a=n.aoMap:n.lightMap&&(a=n.lightMap),void 0!==a&&(a.isWebGLRenderTarget&&(a=a.texture),!0===a.matrixAutoUpdate&&a.updateMatrix(),i.uv2Transform.value.copy(a.matrix))}return{refreshFogUniforms:function(e,i){i.color.getRGB(e.fogColor.value,nn(t)),i.isFog?(e.fogNear.value=i.near,e.fogFar.value=i.far):i.isFogExp2&&(e.fogDensity.value=i.density)},refreshMaterialUniforms:function(t,n,r,s,a){n.isMeshBasicMaterial||n.isMeshLambertMaterial?i(t,n):n.isMeshToonMaterial?(i(t,n),function(t,e){e.gradientMap&&(t.gradientMap.value=e.gradientMap)}(t,n)):n.isMeshPhongMaterial?(i(t,n),function(t,e){t.specular.value.copy(e.specular),t.shininess.value=Math.max(e.shininess,1e-4)}(t,n)):n.isMeshStandardMaterial?(i(t,n),function(t,i){t.roughness.value=i.roughness,t.metalness.value=i.metalness,i.roughnessMap&&(t.roughnessMap.value=i.roughnessMap);i.metalnessMap&&(t.metalnessMap.value=i.metalnessMap);e.get(i).envMap&&(t.envMapIntensity.value=i.envMapIntensity)}(t,n),n.isMeshPhysicalMaterial&&function(t,e,i){t.ior.value=e.ior,e.sheen>0&&(t.sheenColor.value.copy(e.sheenColor).multiplyScalar(e.sheen),t.sheenRoughness.value=e.sheenRoughness,e.sheenColorMap&&(t.sheenColorMap.value=e.sheenColorMap),e.sheenRoughnessMap&&(t.sheenRoughnessMap.value=e.sheenRoughnessMap));e.clearcoat>0&&(t.clearcoat.value=e.clearcoat,t.clearcoatRoughness.value=e.clearcoatRoughness,e.clearcoatMap&&(t.clearcoatMap.value=e.clearcoatMap),e.clearcoatRoughnessMap&&(t.clearcoatRoughnessMap.value=e.clearcoatRoughnessMap),e.clearcoatNormalMap&&(t.clearcoatNormalScale.value.copy(e.clearcoatNormalScale),t.clearcoatNormalMap.value=e.clearcoatNormalMap,1===e.side&&t.clearcoatNormalScale.value.negate()));e.iridescence>0&&(t.iridescence.value=e.iridescence,t.iridescenceIOR.value=e.iridescenceIOR,t.iridescenceThicknessMinimum.value=e.iridescenceThicknessRange[0],t.iridescenceThicknessMaximum.value=e.iridescenceThicknessRange[1],e.iridescenceMap&&(t.iridescenceMap.value=e.iridescenceMap),e.iridescenceThicknessMap&&(t.iridescenceThicknessMap.value=e.iridescenceThicknessMap));e.transmission>0&&(t.transmission.value=e.transmission,t.transmissionSamplerMap.value=i.texture,t.transmissionSamplerSize.value.set(i.width,i.height),e.transmissionMap&&(t.transmissionMap.value=e.transmissionMap),t.thickness.value=e.thickness,e.thicknessMap&&(t.thicknessMap.value=e.thicknessMap),t.attenuationDistance.value=e.attenuationDistance,t.attenuationColor.value.copy(e.attenuationColor));t.specularIntensity.value=e.specularIntensity,t.specularColor.value.copy(e.specularColor),e.specularIntensityMap&&(t.specularIntensityMap.value=e.specularIntensityMap);e.specularColorMap&&(t.specularColorMap.value=e.specularColorMap)}(t,n,a)):n.isMeshMatcapMaterial?(i(t,n),function(t,e){e.matcap&&(t.matcap.value=e.matcap)}(t,n)):n.isMeshDepthMaterial?i(t,n):n.isMeshDistanceMaterial?(i(t,n),function(t,e){t.referencePosition.value.copy(e.referencePosition),t.nearDistance.value=e.nearDistance,t.farDistance.value=e.farDistance}(t,n)):n.isMeshNormalMaterial?i(t,n):n.isLineBasicMaterial?(function(t,e){t.diffuse.value.copy(e.color),t.opacity.value=e.opacity}(t,n),n.isLineDashedMaterial&&function(t,e){t.dashSize.value=e.dashSize,t.totalSize.value=e.dashSize+e.gapSize,t.scale.value=e.scale}(t,n)):n.isPointsMaterial?function(t,e,i,n){t.diffuse.value.copy(e.color),t.opacity.value=e.opacity,t.size.value=e.size*i,t.scale.value=.5*n,e.map&&(t.map.value=e.map);e.alphaMap&&(t.alphaMap.value=e.alphaMap);e.alphaTest>0&&(t.alphaTest.value=e.alphaTest);let r;e.map?r=e.map:e.alphaMap&&(r=e.alphaMap);void 0!==r&&(!0===r.matrixAutoUpdate&&r.updateMatrix(),t.uvTransform.value.copy(r.matrix))}(t,n,r,s):n.isSpriteMaterial?function(t,e){t.diffuse.value.copy(e.color),t.opacity.value=e.opacity,t.rotation.value=e.rotation,e.map&&(t.map.value=e.map);e.alphaMap&&(t.alphaMap.value=e.alphaMap);e.alphaTest>0&&(t.alphaTest.value=e.alphaTest);let i;e.map?i=e.map:e.alphaMap&&(i=e.alphaMap);void 0!==i&&(!0===i.matrixAutoUpdate&&i.updateMatrix(),t.uvTransform.value.copy(i.matrix))}(t,n):n.isShadowMaterial?(t.color.value.copy(n.color),t.opacity.value=n.opacity):n.isShaderMaterial&&(n.uniformsNeedUpdate=!1)}}}function Js(t,e,i,n){let r={},s={},a=[];const o=i.isWebGL2?t.getParameter(35375):0;function l(t,e,i){const n=t.value;if(void 0===i[e])return i[e]="number"==typeof n?n:n.clone(),!0;if("number"==typeof n){if(i[e]!==n)return i[e]=n,!0}else{const t=i[e];if(!1===t.equals(n))return t.copy(n),!0}return!1}function c(t){const e=t.value,i={boundary:0,storage:0};return"number"==typeof e?(i.boundary=4,i.storage=4):e.isVector2?(i.boundary=8,i.storage=8):e.isVector3||e.isColor?(i.boundary=16,i.storage=12):e.isVector4?(i.boundary=16,i.storage=16):e.isMatrix3?(i.boundary=48,i.storage=48):e.isMatrix4?(i.boundary=64,i.storage=64):e.isTexture?console.warn("THREE.WebGLRenderer: Texture samplers can not be part of an uniforms group."):console.warn("THREE.WebGLRenderer: Unsupported uniform value type.",e),i}function h(e){const i=e.target;i.removeEventListener("dispose",h);const n=a.indexOf(i.__bindingPointIndex);a.splice(n,1),t.deleteBuffer(r[i.id]),delete r[i.id],delete s[i.id]}return{bind:function(t,e){const i=e.program;n.uniformBlockBinding(t,i)},update:function(i,u){let d=r[i.id];void 0===d&&(!function(t){const e=t.uniforms;let i=0;const n=16;let r=0;for(let t=0,s=e.length;t0){r=i%n;const t=n-r;0!==r&&t-a.boundary<0&&(i+=n-r,s.__offset=i)}i+=a.storage}r=i%n,r>0&&(i+=n-r);t.__size=i,t.__cache={}}(i),d=function(e){const i=function(){for(let t=0;t0&&function(t,e,i){const n=Y.isWebGL2;null===G&&(G=new te(1,1,{generateMipmaps:!0,type:X.has("EXT_color_buffer_half_float")?b:x,minFilter:v,samples:n&&!0===s?4:0}));f.getDrawingBufferSize(H),n?G.setSize(H.x,H.y):G.setSize(Tt(H.x),Tt(H.y));const r=f.getRenderTarget();f.setRenderTarget(G),f.clear();const a=f.toneMapping;f.toneMapping=0,Nt(t,e,i),f.toneMapping=a,$.updateMultisampleRenderTarget(G),$.updateRenderTargetMipmap(G),f.setRenderTarget(r)}(r,e,i),n&&Z.viewport(E.copy(n)),r.length>0&&Nt(r,e,i),a.length>0&&Nt(a,e,i),o.length>0&&Nt(o,e,i),Z.buffers.depth.setTest(!0),Z.buffers.depth.setMask(!0),Z.buffers.color.setMask(!0),Z.setPolygonOffset(!1)}function Nt(t,e,i){const n=!0===e.isScene?e.overrideMaterial:null;for(let r=0,s=t.length;r0?m[m.length-1]:null,p.pop(),u=p.length>0?p[p.length-1]:null},this.getActiveCubeFace=function(){return _},this.getActiveMipmapLevel=function(){return y},this.getRenderTarget=function(){return S},this.setRenderTargetTextures=function(t,e,i){K.get(t.texture).__webglTexture=e,K.get(t.depthTexture).__webglTexture=i;const n=K.get(t);n.__hasExternalTextures=!0,n.__hasExternalTextures&&(n.__autoAllocateDepthBuffer=void 0===i,n.__autoAllocateDepthBuffer||!0===X.has("WEBGL_multisampled_render_to_texture")&&(console.warn("THREE.WebGLRenderer: Render-to-texture extension was disabled because an external texture was provided"),n.__useRenderToTexture=!1))},this.setRenderTargetFramebuffer=function(t,e){const i=K.get(t);i.__webglFramebuffer=e,i.__useDefaultFramebuffer=void 0===e},this.setRenderTarget=function(t,e=0,i=0){S=t,_=e,y=i;let n=!0,r=null,s=!1,a=!1;if(t){const i=K.get(t);void 0!==i.__useDefaultFramebuffer?(Z.bindFramebuffer(36160,null),n=!1):void 0===i.__webglFramebuffer?$.setupRenderTarget(t):i.__hasExternalTextures&&$.rebindTextures(t,K.get(t.texture).__webglTexture,K.get(t.depthTexture).__webglTexture);const o=t.texture;(o.isData3DTexture||o.isDataArrayTexture||o.isCompressedArrayTexture)&&(a=!0);const l=K.get(t).__webglFramebuffer;t.isWebGLCubeRenderTarget?(r=l[e],s=!0):r=Y.isWebGL2&&t.samples>0&&!1===$.useMultisampledRTT(t)?K.get(t).__webglMultisampledFramebuffer:l,E.copy(t.viewport),C.copy(t.scissor),L=t.scissorTest}else E.copy(O).multiplyScalar(I).floor(),C.copy(z).multiplyScalar(I).floor(),L=U;if(Z.bindFramebuffer(36160,r)&&Y.drawBuffers&&n&&Z.drawBuffers(t,r),Z.viewport(E),Z.scissor(C),Z.setScissorTest(L),s){const n=K.get(t.texture);xt.framebufferTexture2D(36160,36064,34069+e,n.__webglTexture,i)}else if(a){const n=K.get(t.texture),r=e||0;xt.framebufferTextureLayer(36160,36064,n.__webglTexture,i||0,r)}T=-1},this.readRenderTargetPixels=function(t,e,i,n,r,s,a){if(!t||!t.isWebGLRenderTarget)return void console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");let o=K.get(t).__webglFramebuffer;if(t.isWebGLCubeRenderTarget&&void 0!==a&&(o=o[a]),o){Z.bindFramebuffer(36160,o);try{const a=t.texture,o=a.format,l=a.type;if(o!==w&&ft.convert(o)!==xt.getParameter(35739))return void console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.");const c=l===b&&(X.has("EXT_color_buffer_half_float")||Y.isWebGL2&&X.has("EXT_color_buffer_float"));if(!(l===x||ft.convert(l)===xt.getParameter(35738)||l===M&&(Y.isWebGL2||X.has("OES_texture_float")||X.has("WEBGL_color_buffer_float"))||c))return void console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.");e>=0&&e<=t.width-n&&i>=0&&i<=t.height-r&&xt.readPixels(e,i,n,r,ft.convert(o),ft.convert(l),s)}finally{const t=null!==S?K.get(S).__webglFramebuffer:null;Z.bindFramebuffer(36160,t)}}},this.copyFramebufferToTexture=function(t,e,i=0){const n=Math.pow(2,-i),r=Math.floor(e.image.width*n),s=Math.floor(e.image.height*n);$.setTexture2D(e,0),xt.copyTexSubImage2D(3553,i,0,0,t.x,t.y,r,s),Z.unbindTexture()},this.copyTextureToTexture=function(t,e,i,n=0){const r=e.image.width,s=e.image.height,a=ft.convert(i.format),o=ft.convert(i.type);$.setTexture2D(i,0),xt.pixelStorei(37440,i.flipY),xt.pixelStorei(37441,i.premultiplyAlpha),xt.pixelStorei(3317,i.unpackAlignment),e.isDataTexture?xt.texSubImage2D(3553,n,t.x,t.y,r,s,a,o,e.image.data):e.isCompressedTexture?xt.compressedTexSubImage2D(3553,n,t.x,t.y,e.mipmaps[0].width,e.mipmaps[0].height,a,e.mipmaps[0].data):xt.texSubImage2D(3553,n,t.x,t.y,a,o,e.image),0===n&&i.generateMipmaps&&xt.generateMipmap(3553),Z.unbindTexture()},this.copyTextureToTexture3D=function(t,e,i,n,r=0){if(f.isWebGL1Renderer)return void console.warn("THREE.WebGLRenderer.copyTextureToTexture3D: can only be used with WebGL2.");const s=t.max.x-t.min.x+1,a=t.max.y-t.min.y+1,o=t.max.z-t.min.z+1,l=ft.convert(n.format),c=ft.convert(n.type);let h;if(n.isData3DTexture)$.setTexture3D(n,0),h=32879;else{if(!n.isDataArrayTexture)return void console.warn("THREE.WebGLRenderer.copyTextureToTexture3D: only supports THREE.DataTexture3D and THREE.DataTexture2DArray.");$.setTexture2DArray(n,0),h=35866}xt.pixelStorei(37440,n.flipY),xt.pixelStorei(37441,n.premultiplyAlpha),xt.pixelStorei(3317,n.unpackAlignment);const u=xt.getParameter(3314),d=xt.getParameter(32878),p=xt.getParameter(3316),m=xt.getParameter(3315),g=xt.getParameter(32877),v=i.isCompressedTexture?i.mipmaps[0]:i.image;xt.pixelStorei(3314,v.width),xt.pixelStorei(32878,v.height),xt.pixelStorei(3316,t.min.x),xt.pixelStorei(3315,t.min.y),xt.pixelStorei(32877,t.min.z),i.isDataTexture||i.isData3DTexture?xt.texSubImage3D(h,r,e.x,e.y,e.z,s,a,o,l,c,v.data):i.isCompressedArrayTexture?(console.warn("THREE.WebGLRenderer.copyTextureToTexture3D: untested support for compressed srcTexture."),xt.compressedTexSubImage3D(h,r,e.x,e.y,e.z,s,a,o,l,v.data)):xt.texSubImage3D(h,r,e.x,e.y,e.z,s,a,o,l,c,v),xt.pixelStorei(3314,u),xt.pixelStorei(32878,d),xt.pixelStorei(3316,p),xt.pixelStorei(3315,m),xt.pixelStorei(32877,g),0===r&&n.generateMipmaps&&xt.generateMipmap(h),Z.unbindTexture()},this.initTexture=function(t){t.isCubeTexture?$.setTextureCube(t,0):t.isData3DTexture?$.setTexture3D(t,0):t.isDataArrayTexture||t.isCompressedArrayTexture?$.setTexture2DArray(t,0):$.setTexture2D(t,0),Z.unbindTexture()},this.resetState=function(){_=0,y=0,S=null,Z.reset(),gt.reset()},"undefined"!=typeof __THREE_DEVTOOLS__&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe",{detail:this}))}class $s extends Ks{}$s.prototype.isWebGL1Renderer=!0;class Qs{constructor(t,e=25e-5){this.isFogExp2=!0,this.name="",this.color=new qt(t),this.density=e}clone(){return new Qs(this.color,this.density)}toJSON(){return{type:"FogExp2",color:this.color.getHex(),density:this.density}}}class ta{constructor(t,e=1,i=1e3){this.isFog=!0,this.name="",this.color=new qt(t),this.near=e,this.far=i}clone(){return new ta(this.color,this.near,this.far)}toJSON(){return{type:"Fog",color:this.color.getHex(),near:this.near,far:this.far}}}class ea extends si{constructor(){super(),this.isScene=!0,this.type="Scene",this.background=null,this.environment=null,this.fog=null,this.backgroundBlurriness=0,this.backgroundIntensity=1,this.overrideMaterial=null,"undefined"!=typeof __THREE_DEVTOOLS__&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe",{detail:this}))}copy(t,e){return super.copy(t,e),null!==t.background&&(this.background=t.background.clone()),null!==t.environment&&(this.environment=t.environment.clone()),null!==t.fog&&(this.fog=t.fog.clone()),this.backgroundBlurriness=t.backgroundBlurriness,this.backgroundIntensity=t.backgroundIntensity,null!==t.overrideMaterial&&(this.overrideMaterial=t.overrideMaterial.clone()),this.matrixAutoUpdate=t.matrixAutoUpdate,this}toJSON(t){const e=super.toJSON(t);return null!==this.fog&&(e.object.fog=this.fog.toJSON()),this.backgroundBlurriness>0&&(e.backgroundBlurriness=this.backgroundBlurriness),1!==this.backgroundIntensity&&(e.backgroundIntensity=this.backgroundIntensity),e}get autoUpdate(){return console.warn("THREE.Scene: autoUpdate was renamed to matrixWorldAutoUpdate in r144."),this.matrixWorldAutoUpdate}set autoUpdate(t){console.warn("THREE.Scene: autoUpdate was renamed to matrixWorldAutoUpdate in r144."),this.matrixWorldAutoUpdate=t}}class ia{constructor(t,e){this.isInterleavedBuffer=!0,this.array=t,this.stride=e,this.count=void 0!==t?t.length/e:0,this.usage=ut,this.updateRange={offset:0,count:-1},this.version=0,this.uuid=_t()}onUploadCallback(){}set needsUpdate(t){!0===t&&this.version++}setUsage(t){return this.usage=t,this}copy(t){return this.array=new t.array.constructor(t.array),this.count=t.count,this.stride=t.stride,this.usage=t.usage,this}copyAt(t,e,i){t*=this.stride,i*=e.stride;for(let n=0,r=this.stride;nt.far||e.push({distance:o,point:oa.clone(),uv:gi.getUV(oa,pa,ma,fa,ga,va,xa,new Lt),face:null,object:this})}copy(t,e){return super.copy(t,e),void 0!==t.center&&this.center.copy(t.center),this.material=t.material,this}}function ya(t,e,i,n,r,s){ha.subVectors(t,i).addScalar(.5).multiply(n),void 0!==r?(ua.x=s*ha.x-r*ha.y,ua.y=r*ha.x+s*ha.y):ua.copy(ha),t.copy(e),t.x+=ua.x,t.y+=ua.y,t.applyMatrix4(da)}const Ma=new re,ba=new re;class Sa extends si{constructor(){super(),this._currentLevel=0,this.type="LOD",Object.defineProperties(this,{levels:{enumerable:!0,value:[]},isLOD:{value:!0}}),this.autoUpdate=!0}copy(t){super.copy(t,!1);const e=t.levels;for(let t=0,i=e.length;t0){let i,n;for(i=1,n=e.length;i0){Ma.setFromMatrixPosition(this.matrixWorld);const i=t.ray.origin.distanceTo(Ma);this.getObjectForDistance(i).raycast(t,e)}}update(t){const e=this.levels;if(e.length>1){Ma.setFromMatrixPosition(t.matrixWorld),ba.setFromMatrixPosition(this.matrixWorld);const i=Ma.distanceTo(ba)/t.zoom;let n,r;for(e[0].object.visible=!0,n=1,r=e.length;n=t))break;e[n-1].object.visible=!1,e[n].object.visible=!0}for(this._currentLevel=n-1;no)continue;u.applyMatrix4(this.matrixWorld);const s=t.ray.origin.distanceTo(u);st.far||e.push({distance:s,point:h.clone().applyMatrix4(this.matrixWorld),index:i,face:null,faceIndex:null,object:this})}}else{for(let i=Math.max(0,s.start),n=Math.min(m.count,s.start+s.count)-1;io)continue;u.applyMatrix4(this.matrixWorld);const n=t.ray.origin.distanceTo(u);nt.far||e.push({distance:n,point:h.clone().applyMatrix4(this.matrixWorld),index:i,face:null,faceIndex:null,object:this})}}}updateMorphTargets(){const t=this.geometry.morphAttributes,e=Object.keys(t);if(e.length>0){const i=t[e[0]];if(void 0!==i){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let t=0,e=i.length;t0){const i=t[e[0]];if(void 0!==i){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let t=0,e=i.length;tr.far)return;s.push({distance:l,distanceToRay:Math.sqrt(o),point:i,index:e,face:null,object:a})}}class ao extends $t{constructor(t,e,i,n,r,s,a,o,l,c,h,u){super(null,s,a,o,l,c,n,r,h,u),this.isCompressedTexture=!0,this.image={width:e,height:i},this.mipmaps=t,this.flipY=!1,this.generateMipmaps=!1}}class oo{constructor(){this.type="Curve",this.arcLengthDivisions=200}getPoint(){return console.warn("THREE.Curve: .getPoint() not implemented."),null}getPointAt(t,e){const i=this.getUtoTmapping(t);return this.getPoint(i,e)}getPoints(t=5){const e=[];for(let i=0;i<=t;i++)e.push(this.getPoint(i/t));return e}getSpacedPoints(t=5){const e=[];for(let i=0;i<=t;i++)e.push(this.getPointAt(i/t));return e}getLength(){const t=this.getLengths();return t[t.length-1]}getLengths(t=this.arcLengthDivisions){if(this.cacheArcLengths&&this.cacheArcLengths.length===t+1&&!this.needsUpdate)return this.cacheArcLengths;this.needsUpdate=!1;const e=[];let i,n=this.getPoint(0),r=0;e.push(0);for(let s=1;s<=t;s++)i=this.getPoint(s/t),r+=i.distanceTo(n),e.push(r),n=i;return this.cacheArcLengths=e,e}updateArcLengths(){this.needsUpdate=!0,this.getLengths()}getUtoTmapping(t,e){const i=this.getLengths();let n=0;const r=i.length;let s;s=e||t*i[r-1];let a,o=0,l=r-1;for(;o<=l;)if(n=Math.floor(o+(l-o)/2),a=i[n]-s,a<0)o=n+1;else{if(!(a>0)){l=n;break}l=n-1}if(n=l,i[n]===s)return n/(r-1);const c=i[n];return(n+(s-c)/(i[n+1]-c))/(r-1)}getTangent(t,e){const i=1e-4;let n=t-i,r=t+i;n<0&&(n=0),r>1&&(r=1);const s=this.getPoint(n),a=this.getPoint(r),o=e||(s.isVector2?new Lt:new re);return o.copy(a).sub(s).normalize(),o}getTangentAt(t,e){const i=this.getUtoTmapping(t);return this.getTangent(i,e)}computeFrenetFrames(t,e){const i=new re,n=[],r=[],s=[],a=new re,o=new Ne;for(let e=0;e<=t;e++){const i=e/t;n[e]=this.getTangentAt(i,new re)}r[0]=new re,s[0]=new re;let l=Number.MAX_VALUE;const c=Math.abs(n[0].x),h=Math.abs(n[0].y),u=Math.abs(n[0].z);c<=l&&(l=c,i.set(1,0,0)),h<=l&&(l=h,i.set(0,1,0)),u<=l&&i.set(0,0,1),a.crossVectors(n[0],i).normalize(),r[0].crossVectors(n[0],a),s[0].crossVectors(n[0],r[0]);for(let e=1;e<=t;e++){if(r[e]=r[e-1].clone(),s[e]=s[e-1].clone(),a.crossVectors(n[e-1],n[e]),a.length()>Number.EPSILON){a.normalize();const t=Math.acos(yt(n[e-1].dot(n[e]),-1,1));r[e].applyMatrix4(o.makeRotationAxis(a,t))}s[e].crossVectors(n[e],r[e])}if(!0===e){let e=Math.acos(yt(r[0].dot(r[t]),-1,1));e/=t,n[0].dot(a.crossVectors(r[0],r[t]))>0&&(e=-e);for(let i=1;i<=t;i++)r[i].applyMatrix4(o.makeRotationAxis(n[i],e*i)),s[i].crossVectors(n[i],r[i])}return{tangents:n,normals:r,binormals:s}}clone(){return(new this.constructor).copy(this)}copy(t){return this.arcLengthDivisions=t.arcLengthDivisions,this}toJSON(){const t={metadata:{version:4.5,type:"Curve",generator:"Curve.toJSON"}};return t.arcLengthDivisions=this.arcLengthDivisions,t.type=this.type,t}fromJSON(t){return this.arcLengthDivisions=t.arcLengthDivisions,this}}class lo extends oo{constructor(t=0,e=0,i=1,n=1,r=0,s=2*Math.PI,a=!1,o=0){super(),this.isEllipseCurve=!0,this.type="EllipseCurve",this.aX=t,this.aY=e,this.xRadius=i,this.yRadius=n,this.aStartAngle=r,this.aEndAngle=s,this.aClockwise=a,this.aRotation=o}getPoint(t,e){const i=e||new Lt,n=2*Math.PI;let r=this.aEndAngle-this.aStartAngle;const s=Math.abs(r)n;)r-=n;r0?0:(Math.floor(Math.abs(l)/r)+1)*r:0===c&&l===r-1&&(l=r-2,c=1),this.closed||l>0?a=n[(l-1)%r]:(uo.subVectors(n[0],n[1]).add(n[0]),a=uo);const h=n[l%r],u=n[(l+1)%r];if(this.closed||l+2n.length-2?n.length-1:s+1],h=n[s>n.length-3?n.length-1:s+2];return i.set(vo(a,o.x,l.x,c.x,h.x),vo(a,o.y,l.y,c.y,h.y)),i}copy(t){super.copy(t),this.points=[];for(let e=0,i=t.points.length;e=i){const t=n[r]-i,s=this.curves[r],a=s.getLength(),o=0===a?0:1-t/a;return s.getPointAt(o,e)}r++}return null}getLength(){const t=this.getCurveLengths();return t[t.length-1]}updateArcLengths(){this.needsUpdate=!0,this.cacheLengths=null,this.getCurveLengths()}getCurveLengths(){if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths;const t=[];let e=0;for(let i=0,n=this.curves.length;i1&&!e[e.length-1].equals(e[0])&&e.push(e[0]),e}copy(t){super.copy(t),this.curves=[];for(let e=0,i=t.curves.length;e0){const t=l.getPoint(0);t.equals(this.currentPoint)||this.lineTo(t.x,t.y)}this.curves.push(l);const c=l.getPoint(1);return this.currentPoint.copy(c),this}copy(t){return super.copy(t),this.currentPoint.copy(t.currentPoint),this}toJSON(){const t=super.toJSON();return t.currentPoint=this.currentPoint.toArray(),t}fromJSON(t){return super.fromJSON(t),this.currentPoint.fromArray(t.currentPoint),this}}class Ro extends Di{constructor(t=[new Lt(0,-.5),new Lt(.5,0),new Lt(0,.5)],e=12,i=0,n=2*Math.PI){super(),this.type="LatheGeometry",this.parameters={points:t,segments:e,phiStart:i,phiLength:n},e=Math.floor(e),n=yt(n,0,2*Math.PI);const r=[],s=[],a=[],o=[],l=[],c=1/e,h=new re,u=new Lt,d=new re,p=new re,m=new re;let f=0,g=0;for(let e=0;e<=t.length-1;e++)switch(e){case 0:f=t[e+1].x-t[e].x,g=t[e+1].y-t[e].y,d.x=1*g,d.y=-f,d.z=0*g,m.copy(d),d.normalize(),o.push(d.x,d.y,d.z);break;case t.length-1:o.push(m.x,m.y,m.z);break;default:f=t[e+1].x-t[e].x,g=t[e+1].y-t[e].y,d.x=1*g,d.y=-f,d.z=0*g,p.copy(d),d.x+=m.x,d.y+=m.y,d.z+=m.z,d.normalize(),o.push(d.x,d.y,d.z),m.copy(p)}for(let r=0;r<=e;r++){const d=i+r*c*n,p=Math.sin(d),m=Math.cos(d);for(let i=0;i<=t.length-1;i++){h.x=t[i].x*p,h.y=t[i].y,h.z=t[i].x*m,s.push(h.x,h.y,h.z),u.x=r/e,u.y=i/(t.length-1),a.push(u.x,u.y);const n=o[3*i+0]*p,c=o[3*i+1],d=o[3*i+0]*m;l.push(n,c,d)}}for(let i=0;i0&&v(!0),e>0&&v(!1)),this.setIndex(c),this.setAttribute("position",new Ti(h,3)),this.setAttribute("normal",new Ti(u,3)),this.setAttribute("uv",new Ti(d,2))}static fromJSON(t){return new Do(t.radiusTop,t.radiusBottom,t.height,t.radialSegments,t.heightSegments,t.openEnded,t.thetaStart,t.thetaLength)}}class No extends Do{constructor(t=1,e=1,i=8,n=1,r=!1,s=0,a=2*Math.PI){super(0,t,e,i,n,r,s,a),this.type="ConeGeometry",this.parameters={radius:t,height:e,radialSegments:i,heightSegments:n,openEnded:r,thetaStart:s,thetaLength:a}}static fromJSON(t){return new No(t.radius,t.height,t.radialSegments,t.heightSegments,t.openEnded,t.thetaStart,t.thetaLength)}}class Oo extends Di{constructor(t=[],e=[],i=1,n=0){super(),this.type="PolyhedronGeometry",this.parameters={vertices:t,indices:e,radius:i,detail:n};const r=[],s=[];function a(t,e,i,n){const r=n+1,s=[];for(let n=0;n<=r;n++){s[n]=[];const a=t.clone().lerp(i,n/r),o=e.clone().lerp(i,n/r),l=r-n;for(let t=0;t<=l;t++)s[n][t]=0===t&&n===r?a:a.clone().lerp(o,t/l)}for(let t=0;t.9&&a<.1&&(e<.2&&(s[t+0]+=1),i<.2&&(s[t+2]+=1),n<.2&&(s[t+4]+=1))}}()}(),this.setAttribute("position",new Ti(r,3)),this.setAttribute("normal",new Ti(r.slice(),3)),this.setAttribute("uv",new Ti(s,2)),0===n?this.computeVertexNormals():this.normalizeNormals()}static fromJSON(t){return new Oo(t.vertices,t.indices,t.radius,t.details)}}class zo extends Oo{constructor(t=1,e=0){const i=(1+Math.sqrt(5))/2,n=1/i;super([-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,-n,-i,0,-n,i,0,n,-i,0,n,i,-n,-i,0,-n,i,0,n,-i,0,n,i,0,-i,0,-n,i,0,-n,-i,0,n,i,0,n],[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],t,e),this.type="DodecahedronGeometry",this.parameters={radius:t,detail:e}}static fromJSON(t){return new zo(t.radius,t.detail)}}const Uo=new re,Bo=new re,Fo=new re,ko=new gi;class Go extends Di{constructor(t=null,e=1){if(super(),this.type="EdgesGeometry",this.parameters={geometry:t,thresholdAngle:e},null!==t){const i=4,n=Math.pow(10,i),r=Math.cos(vt*e),s=t.getIndex(),a=t.getAttribute("position"),o=s?s.count:a.count,l=[0,0,0],c=["a","b","c"],h=new Array(3),u={},d=[];for(let t=0;t80*i){o=c=t[0],l=h=t[1];for(let e=i;ec&&(c=u),d>h&&(h=d);p=Math.max(c-o,h-l),p=0!==p?32767/p:0}return qo(s,a,i,o,l,p,0),a};function Wo(t,e,i,n,r){let s,a;if(r===function(t,e,i,n){let r=0;for(let s=e,a=i-n;s0)for(s=e;s=e;s-=n)a=ul(s,t[s],t[s+1],a);return a&&sl(a,a.next)&&(dl(a),a=a.next),a}function jo(t,e){if(!t)return t;e||(e=t);let i,n=t;do{if(i=!1,n.steiner||!sl(n,n.next)&&0!==rl(n.prev,n,n.next))n=n.next;else{if(dl(n),n=e=n.prev,n===n.next)break;i=!0}}while(i||n!==e);return e}function qo(t,e,i,n,r,s,a){if(!t)return;!a&&s&&function(t,e,i,n){let r=t;do{0===r.z&&(r.z=tl(r.x,r.y,e,i,n)),r.prevZ=r.prev,r.nextZ=r.next,r=r.next}while(r!==t);r.prevZ.nextZ=null,r.prevZ=null,function(t){let e,i,n,r,s,a,o,l,c=1;do{for(i=t,t=null,s=null,a=0;i;){for(a++,n=i,o=0,e=0;e0||l>0&&n;)0!==o&&(0===l||!n||i.z<=n.z)?(r=i,i=i.nextZ,o--):(r=n,n=n.nextZ,l--),s?s.nextZ=r:t=r,r.prevZ=s,s=r;i=n}s.nextZ=null,c*=2}while(a>1)}(r)}(t,n,r,s);let o,l,c=t;for(;t.prev!==t.next;)if(o=t.prev,l=t.next,s?Yo(t,n,r,s):Xo(t))e.push(o.i/i|0),e.push(t.i/i|0),e.push(l.i/i|0),dl(t),t=l.next,c=l.next;else if((t=l)===c){a?1===a?qo(t=Zo(jo(t),e,i),e,i,n,r,s,2):2===a&&Jo(t,e,i,n,r,s):qo(jo(t),e,i,n,r,s,1);break}}function Xo(t){const e=t.prev,i=t,n=t.next;if(rl(e,i,n)>=0)return!1;const r=e.x,s=i.x,a=n.x,o=e.y,l=i.y,c=n.y,h=rs?r>a?r:a:s>a?s:a,p=o>l?o>c?o:c:l>c?l:c;let m=n.next;for(;m!==e;){if(m.x>=h&&m.x<=d&&m.y>=u&&m.y<=p&&il(r,o,s,l,a,c,m.x,m.y)&&rl(m.prev,m,m.next)>=0)return!1;m=m.next}return!0}function Yo(t,e,i,n){const r=t.prev,s=t,a=t.next;if(rl(r,s,a)>=0)return!1;const o=r.x,l=s.x,c=a.x,h=r.y,u=s.y,d=a.y,p=ol?o>c?o:c:l>c?l:c,g=h>u?h>d?h:d:u>d?u:d,v=tl(p,m,e,i,n),x=tl(f,g,e,i,n);let _=t.prevZ,y=t.nextZ;for(;_&&_.z>=v&&y&&y.z<=x;){if(_.x>=p&&_.x<=f&&_.y>=m&&_.y<=g&&_!==r&&_!==a&&il(o,h,l,u,c,d,_.x,_.y)&&rl(_.prev,_,_.next)>=0)return!1;if(_=_.prevZ,y.x>=p&&y.x<=f&&y.y>=m&&y.y<=g&&y!==r&&y!==a&&il(o,h,l,u,c,d,y.x,y.y)&&rl(y.prev,y,y.next)>=0)return!1;y=y.nextZ}for(;_&&_.z>=v;){if(_.x>=p&&_.x<=f&&_.y>=m&&_.y<=g&&_!==r&&_!==a&&il(o,h,l,u,c,d,_.x,_.y)&&rl(_.prev,_,_.next)>=0)return!1;_=_.prevZ}for(;y&&y.z<=x;){if(y.x>=p&&y.x<=f&&y.y>=m&&y.y<=g&&y!==r&&y!==a&&il(o,h,l,u,c,d,y.x,y.y)&&rl(y.prev,y,y.next)>=0)return!1;y=y.nextZ}return!0}function Zo(t,e,i){let n=t;do{const r=n.prev,s=n.next.next;!sl(r,s)&&al(r,n,n.next,s)&&cl(r,s)&&cl(s,r)&&(e.push(r.i/i|0),e.push(n.i/i|0),e.push(s.i/i|0),dl(n),dl(n.next),n=t=s),n=n.next}while(n!==t);return jo(n)}function Jo(t,e,i,n,r,s){let a=t;do{let t=a.next.next;for(;t!==a.prev;){if(a.i!==t.i&&nl(a,t)){let o=hl(a,t);return a=jo(a,a.next),o=jo(o,o.next),qo(a,e,i,n,r,s,0),void qo(o,e,i,n,r,s,0)}t=t.next}a=a.next}while(a!==t)}function Ko(t,e){return t.x-e.x}function $o(t,e){const i=function(t,e){let i,n=e,r=-1/0;const s=t.x,a=t.y;do{if(a<=n.y&&a>=n.next.y&&n.next.y!==n.y){const t=n.x+(a-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(t<=s&&t>r&&(r=t,i=n.x=n.x&&n.x>=l&&s!==n.x&&il(ai.x||n.x===i.x&&Qo(i,n)))&&(i=n,u=h)),n=n.next}while(n!==o);return i}(t,e);if(!i)return e;const n=hl(i,t);return jo(n,n.next),jo(i,i.next)}function Qo(t,e){return rl(t.prev,t,e.prev)<0&&rl(e.next,t,t.next)<0}function tl(t,e,i,n,r){return(t=1431655765&((t=858993459&((t=252645135&((t=16711935&((t=(t-i)*r|0)|t<<8))|t<<4))|t<<2))|t<<1))|(e=1431655765&((e=858993459&((e=252645135&((e=16711935&((e=(e-n)*r|0)|e<<8))|e<<4))|e<<2))|e<<1))<<1}function el(t){let e=t,i=t;do{(e.x=(t-a)*(s-o)&&(t-a)*(n-o)>=(i-a)*(e-o)&&(i-a)*(s-o)>=(r-a)*(n-o)}function nl(t,e){return t.next.i!==e.i&&t.prev.i!==e.i&&!function(t,e){let i=t;do{if(i.i!==t.i&&i.next.i!==t.i&&i.i!==e.i&&i.next.i!==e.i&&al(i,i.next,t,e))return!0;i=i.next}while(i!==t);return!1}(t,e)&&(cl(t,e)&&cl(e,t)&&function(t,e){let i=t,n=!1;const r=(t.x+e.x)/2,s=(t.y+e.y)/2;do{i.y>s!=i.next.y>s&&i.next.y!==i.y&&r<(i.next.x-i.x)*(s-i.y)/(i.next.y-i.y)+i.x&&(n=!n),i=i.next}while(i!==t);return n}(t,e)&&(rl(t.prev,t,e.prev)||rl(t,e.prev,e))||sl(t,e)&&rl(t.prev,t,t.next)>0&&rl(e.prev,e,e.next)>0)}function rl(t,e,i){return(e.y-t.y)*(i.x-e.x)-(e.x-t.x)*(i.y-e.y)}function sl(t,e){return t.x===e.x&&t.y===e.y}function al(t,e,i,n){const r=ll(rl(t,e,i)),s=ll(rl(t,e,n)),a=ll(rl(i,n,t)),o=ll(rl(i,n,e));return r!==s&&a!==o||(!(0!==r||!ol(t,i,e))||(!(0!==s||!ol(t,n,e))||(!(0!==a||!ol(i,t,n))||!(0!==o||!ol(i,e,n)))))}function ol(t,e,i){return e.x<=Math.max(t.x,i.x)&&e.x>=Math.min(t.x,i.x)&&e.y<=Math.max(t.y,i.y)&&e.y>=Math.min(t.y,i.y)}function ll(t){return t>0?1:t<0?-1:0}function cl(t,e){return rl(t.prev,t,t.next)<0?rl(t,e,t.next)>=0&&rl(t,t.prev,e)>=0:rl(t,e,t.prev)<0||rl(t,t.next,e)<0}function hl(t,e){const i=new pl(t.i,t.x,t.y),n=new pl(e.i,e.x,e.y),r=t.next,s=e.prev;return t.next=e,e.prev=t,i.next=r,r.prev=i,n.next=i,i.prev=n,s.next=n,n.prev=s,n}function ul(t,e,i,n){const r=new pl(t,e,i);return n?(r.next=n.next,r.prev=n,n.next.prev=r,n.next=r):(r.prev=r,r.next=r),r}function dl(t){t.next.prev=t.prev,t.prev.next=t.next,t.prevZ&&(t.prevZ.nextZ=t.nextZ),t.nextZ&&(t.nextZ.prevZ=t.prevZ)}function pl(t,e,i){this.i=t,this.x=e,this.y=i,this.prev=null,this.next=null,this.z=0,this.prevZ=null,this.nextZ=null,this.steiner=!1}class ml{static area(t){const e=t.length;let i=0;for(let n=e-1,r=0;r2&&t[e-1].equals(t[0])&&t.pop()}function gl(t,e){for(let i=0;iNumber.EPSILON){const u=Math.sqrt(h),d=Math.sqrt(l*l+c*c),p=e.x-o/u,m=e.y+a/u,f=((i.x-c/d-p)*c-(i.y+l/d-m)*l)/(a*c-o*l);n=p+a*f-t.x,r=m+o*f-t.y;const g=n*n+r*r;if(g<=2)return new Lt(n,r);s=Math.sqrt(g/2)}else{let t=!1;a>Number.EPSILON?l>Number.EPSILON&&(t=!0):a<-Number.EPSILON?l<-Number.EPSILON&&(t=!0):Math.sign(o)===Math.sign(c)&&(t=!0),t?(n=-o,r=a,s=Math.sqrt(h)):(n=a,r=o,s=Math.sqrt(h/2))}return new Lt(n/s,r/s)}const P=[];for(let t=0,e=A.length,i=e-1,n=t+1;t=0;t--){const e=t/p,i=h*Math.cos(e*Math.PI/2),n=u*Math.sin(e*Math.PI/2)+d;for(let t=0,e=A.length;t=0;){const n=i;let r=i-1;r<0&&(r=t.length-1);for(let t=0,i=o+2*p;t0)&&d.push(e,r,l),(t!==i-1||o0!=t>0&&this.version++,this._sheen=t}get clearcoat(){return this._clearcoat}set clearcoat(t){this._clearcoat>0!=t>0&&this.version++,this._clearcoat=t}get iridescence(){return this._iridescence}set iridescence(t){this._iridescence>0!=t>0&&this.version++,this._iridescence=t}get transmission(){return this._transmission}set transmission(t){this._transmission>0!=t>0&&this.version++,this._transmission=t}copy(t){return super.copy(t),this.defines={STANDARD:"",PHYSICAL:""},this.clearcoat=t.clearcoat,this.clearcoatMap=t.clearcoatMap,this.clearcoatRoughness=t.clearcoatRoughness,this.clearcoatRoughnessMap=t.clearcoatRoughnessMap,this.clearcoatNormalMap=t.clearcoatNormalMap,this.clearcoatNormalScale.copy(t.clearcoatNormalScale),this.ior=t.ior,this.iridescence=t.iridescence,this.iridescenceMap=t.iridescenceMap,this.iridescenceIOR=t.iridescenceIOR,this.iridescenceThicknessRange=[...t.iridescenceThicknessRange],this.iridescenceThicknessMap=t.iridescenceThicknessMap,this.sheen=t.sheen,this.sheenColor.copy(t.sheenColor),this.sheenColorMap=t.sheenColorMap,this.sheenRoughness=t.sheenRoughness,this.sheenRoughnessMap=t.sheenRoughnessMap,this.transmission=t.transmission,this.transmissionMap=t.transmissionMap,this.thickness=t.thickness,this.thicknessMap=t.thicknessMap,this.attenuationDistance=t.attenuationDistance,this.attenuationColor.copy(t.attenuationColor),this.specularIntensity=t.specularIntensity,this.specularIntensityMap=t.specularIntensityMap,this.specularColor.copy(t.specularColor),this.specularColorMap=t.specularColorMap,this}}class Ol extends xi{constructor(t){super(),this.isMeshPhongMaterial=!0,this.type="MeshPhongMaterial",this.color=new qt(16777215),this.specular=new qt(1118481),this.shininess=30,this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new qt(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Lt(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.combine=0,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.flatShading=!1,this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.specular.copy(t.specular),this.shininess=t.shininess,this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.emissive.copy(t.emissive),this.emissiveMap=t.emissiveMap,this.emissiveIntensity=t.emissiveIntensity,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.specularMap=t.specularMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.combine=t.combine,this.reflectivity=t.reflectivity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.flatShading=t.flatShading,this.fog=t.fog,this}}class zl extends xi{constructor(t){super(),this.isMeshToonMaterial=!0,this.defines={TOON:""},this.type="MeshToonMaterial",this.color=new qt(16777215),this.map=null,this.gradientMap=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new qt(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Lt(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.alphaMap=null,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.map=t.map,this.gradientMap=t.gradientMap,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.emissive.copy(t.emissive),this.emissiveMap=t.emissiveMap,this.emissiveIntensity=t.emissiveIntensity,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.alphaMap=t.alphaMap,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.fog=t.fog,this}}class Ul extends xi{constructor(t){super(),this.isMeshNormalMaterial=!0,this.type="MeshNormalMaterial",this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Lt(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.wireframe=!1,this.wireframeLinewidth=1,this.flatShading=!1,this.setValues(t)}copy(t){return super.copy(t),this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.flatShading=t.flatShading,this}}class Bl extends xi{constructor(t){super(),this.isMeshLambertMaterial=!0,this.type="MeshLambertMaterial",this.color=new qt(16777215),this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new qt(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Lt(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.combine=0,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.flatShading=!1,this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.emissive.copy(t.emissive),this.emissiveMap=t.emissiveMap,this.emissiveIntensity=t.emissiveIntensity,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.specularMap=t.specularMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.combine=t.combine,this.reflectivity=t.reflectivity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.flatShading=t.flatShading,this.fog=t.fog,this}}class Fl extends xi{constructor(t){super(),this.isMeshMatcapMaterial=!0,this.defines={MATCAP:""},this.type="MeshMatcapMaterial",this.color=new qt(16777215),this.matcap=null,this.map=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Lt(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.alphaMap=null,this.flatShading=!1,this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.defines={MATCAP:""},this.color.copy(t.color),this.matcap=t.matcap,this.map=t.map,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.alphaMap=t.alphaMap,this.flatShading=t.flatShading,this.fog=t.fog,this}}class kl extends Va{constructor(t){super(),this.isLineDashedMaterial=!0,this.type="LineDashedMaterial",this.scale=1,this.dashSize=3,this.gapSize=1,this.setValues(t)}copy(t){return super.copy(t),this.scale=t.scale,this.dashSize=t.dashSize,this.gapSize=t.gapSize,this}}function Gl(t,e,i){return Hl(t)?new t.constructor(t.subarray(e,void 0!==i?i:t.length)):t.slice(e,i)}function Vl(t,e,i){return!t||!i&&t.constructor===e?t:"number"==typeof e.BYTES_PER_ELEMENT?new e(t):Array.prototype.slice.call(t)}function Hl(t){return ArrayBuffer.isView(t)&&!(t instanceof DataView)}function Wl(t){const e=t.length,i=new Array(e);for(let t=0;t!==e;++t)i[t]=t;return i.sort((function(e,i){return t[e]-t[i]})),i}function jl(t,e,i){const n=t.length,r=new t.constructor(n);for(let s=0,a=0;a!==n;++s){const n=i[s]*e;for(let i=0;i!==e;++i)r[a++]=t[n+i]}return r}function ql(t,e,i,n){let r=1,s=t[0];for(;void 0!==s&&void 0===s[n];)s=t[r++];if(void 0===s)return;let a=s[n];if(void 0!==a)if(Array.isArray(a))do{a=s[n],void 0!==a&&(e.push(s.time),i.push.apply(i,a)),s=t[r++]}while(void 0!==s);else if(void 0!==a.toArray)do{a=s[n],void 0!==a&&(e.push(s.time),a.toArray(i,i.length)),s=t[r++]}while(void 0!==s);else do{a=s[n],void 0!==a&&(e.push(s.time),i.push(a)),s=t[r++]}while(void 0!==s)}var Xl=Object.freeze({__proto__:null,arraySlice:Gl,convertArray:Vl,isTypedArray:Hl,getKeyframeOrder:Wl,sortedArray:jl,flattenJSON:ql,subclip:function(t,e,i,n,r=30){const s=t.clone();s.name=e;const a=[];for(let t=0;t=n)){l.push(e.times[t]);for(let i=0;is.tracks[t].times[0]&&(o=s.tracks[t].times[0]);for(let t=0;t=n.times[u]){const t=u*l+o,e=t+l-o;d=Gl(n.values,t,e)}else{const t=n.createInterpolant(),e=o,i=l-o;t.evaluate(s),d=Gl(t.resultBuffer,e,i)}if("quaternion"===r){(new ne).fromArray(d).normalize().conjugate().toArray(d)}const p=a.times.length;for(let t=0;t=r)break t;{const a=e[1];t=r)break e}s=i,i=0}}for(;i>>1;te;)--s;if(++s,0!==r||s!==n){r>=s&&(s=Math.max(s,1),r=s-1);const t=this.getValueSize();this.times=Gl(i,r,s),this.values=Gl(this.values,r*t,s*t)}return this}validate(){let t=!0;const e=this.getValueSize();e-Math.floor(e)!=0&&(console.error("THREE.KeyframeTrack: Invalid value size in track.",this),t=!1);const i=this.times,n=this.values,r=i.length;0===r&&(console.error("THREE.KeyframeTrack: Track is empty.",this),t=!1);let s=null;for(let e=0;e!==r;e++){const n=i[e];if("number"==typeof n&&isNaN(n)){console.error("THREE.KeyframeTrack: Time is not a valid number.",this,e,n),t=!1;break}if(null!==s&&s>n){console.error("THREE.KeyframeTrack: Out of order keys.",this,e,n,s),t=!1;break}s=n}if(void 0!==n&&Hl(n))for(let e=0,i=n.length;e!==i;++e){const i=n[e];if(isNaN(i)){console.error("THREE.KeyframeTrack: Value is not a valid number.",this,e,i),t=!1;break}}return t}optimize(){const t=Gl(this.times),e=Gl(this.values),i=this.getValueSize(),n=this.getInterpolation()===tt,r=t.length-1;let s=1;for(let a=1;a0){t[s]=t[r];for(let t=r*i,n=s*i,a=0;a!==i;++a)e[n+a]=e[t+a];++s}return s!==t.length?(this.times=Gl(t,0,s),this.values=Gl(e,0,s*i)):(this.times=t,this.values=e),this}clone(){const t=Gl(this.times,0),e=Gl(this.values,0),i=new(0,this.constructor)(this.name,t,e);return i.createInterpolant=this.createInterpolant,i}}$l.prototype.TimeBufferType=Float32Array,$l.prototype.ValueBufferType=Float32Array,$l.prototype.DefaultInterpolation=Q;class Ql extends $l{}Ql.prototype.ValueTypeName="bool",Ql.prototype.ValueBufferType=Array,Ql.prototype.DefaultInterpolation=$,Ql.prototype.InterpolantFactoryMethodLinear=void 0,Ql.prototype.InterpolantFactoryMethodSmooth=void 0;class tc extends $l{}tc.prototype.ValueTypeName="color";class ec extends $l{}ec.prototype.ValueTypeName="number";class ic extends Yl{constructor(t,e,i,n){super(t,e,i,n)}interpolate_(t,e,i,n){const r=this.resultBuffer,s=this.sampleValues,a=this.valueSize,o=(i-e)/(n-e);let l=t*a;for(let t=l+a;l!==t;l+=4)ne.slerpFlat(r,0,s,l-a,s,l,o);return r}}class nc extends $l{InterpolantFactoryMethodLinear(t){return new ic(this.times,this.values,this.getValueSize(),t)}}nc.prototype.ValueTypeName="quaternion",nc.prototype.DefaultInterpolation=Q,nc.prototype.InterpolantFactoryMethodSmooth=void 0;class rc extends $l{}rc.prototype.ValueTypeName="string",rc.prototype.ValueBufferType=Array,rc.prototype.DefaultInterpolation=$,rc.prototype.InterpolantFactoryMethodLinear=void 0,rc.prototype.InterpolantFactoryMethodSmooth=void 0;class sc extends $l{}sc.prototype.ValueTypeName="vector";class ac{constructor(t,e=-1,i,n=2500){this.name=t,this.tracks=i,this.duration=e,this.blendMode=n,this.uuid=_t(),this.duration<0&&this.resetDuration()}static parse(t){const e=[],i=t.tracks,n=1/(t.fps||1);for(let t=0,r=i.length;t!==r;++t)e.push(oc(i[t]).scale(n));const r=new this(t.name,t.duration,e,t.blendMode);return r.uuid=t.uuid,r}static toJSON(t){const e=[],i=t.tracks,n={name:t.name,duration:t.duration,tracks:e,uuid:t.uuid,blendMode:t.blendMode};for(let t=0,n=i.length;t!==n;++t)e.push($l.toJSON(i[t]));return n}static CreateFromMorphTargetSequence(t,e,i,n){const r=e.length,s=[];for(let t=0;t1){const t=s[1];let e=n[t];e||(n[t]=e=[]),e.push(i)}}const s=[];for(const t in n)s.push(this.CreateFromMorphTargetSequence(t,n[t],e,i));return s}static parseAnimation(t,e){if(!t)return console.error("THREE.AnimationClip: No animation in JSONLoader data."),null;const i=function(t,e,i,n,r){if(0!==i.length){const s=[],a=[];ql(i,s,a,n),0!==s.length&&r.push(new t(e,s,a))}},n=[],r=t.name||"default",s=t.fps||30,a=t.blendMode;let o=t.length||-1;const l=t.hierarchy||[];for(let t=0;t{e&&e(r),this.manager.itemEnd(t)}),0),r;if(void 0!==dc[t])return void dc[t].push({onLoad:e,onProgress:i,onError:n});dc[t]=[],dc[t].push({onLoad:e,onProgress:i,onError:n});const s=new Request(t,{headers:new Headers(this.requestHeader),credentials:this.withCredentials?"include":"same-origin"}),a=this.mimeType,o=this.responseType;fetch(s).then((e=>{if(200===e.status||0===e.status){if(0===e.status&&console.warn("THREE.FileLoader: HTTP Status 0 received."),"undefined"==typeof ReadableStream||void 0===e.body||void 0===e.body.getReader)return e;const i=dc[t],n=e.body.getReader(),r=e.headers.get("Content-Length")||e.headers.get("X-File-Size"),s=r?parseInt(r):0,a=0!==s;let o=0;const l=new ReadableStream({start(t){!function e(){n.read().then((({done:n,value:r})=>{if(n)t.close();else{o+=r.byteLength;const n=new ProgressEvent("progress",{lengthComputable:a,loaded:o,total:s});for(let t=0,e=i.length;t{switch(o){case"arraybuffer":return t.arrayBuffer();case"blob":return t.blob();case"document":return t.text().then((t=>(new DOMParser).parseFromString(t,a)));case"json":return t.json();default:if(void 0===a)return t.text();{const e=/charset="?([^;"\s]*)"?/i.exec(a),i=e&&e[1]?e[1].toLowerCase():void 0,n=new TextDecoder(i);return t.arrayBuffer().then((t=>n.decode(t)))}}})).then((e=>{lc.add(t,e);const i=dc[t];delete dc[t];for(let t=0,n=i.length;t{const i=dc[t];if(void 0===i)throw this.manager.itemError(t),e;delete dc[t];for(let t=0,n=i.length;t{this.manager.itemEnd(t)})),this.manager.itemStart(t)}setResponseType(t){return this.responseType=t,this}setMimeType(t){return this.mimeType=t,this}}class fc extends uc{constructor(t){super(t)}load(t,e,i,n){void 0!==this.path&&(t=this.path+t),t=this.manager.resolveURL(t);const r=this,s=lc.get(t);if(void 0!==s)return r.manager.itemStart(t),setTimeout((function(){e&&e(s),r.manager.itemEnd(t)}),0),s;const a=Ot("img");function o(){c(),lc.add(t,this),e&&e(this),r.manager.itemEnd(t)}function l(e){c(),n&&n(e),r.manager.itemError(t),r.manager.itemEnd(t)}function c(){a.removeEventListener("load",o,!1),a.removeEventListener("error",l,!1)}return a.addEventListener("load",o,!1),a.addEventListener("error",l,!1),"data:"!==t.slice(0,5)&&void 0!==this.crossOrigin&&(a.crossOrigin=this.crossOrigin),r.manager.itemStart(t),a.src=t,a}}class gc extends si{constructor(t,e=1){super(),this.isLight=!0,this.type="Light",this.color=new qt(t),this.intensity=e}dispose(){}copy(t,e){return super.copy(t,e),this.color.copy(t.color),this.intensity=t.intensity,this}toJSON(t){const e=super.toJSON(t);return e.object.color=this.color.getHex(),e.object.intensity=this.intensity,void 0!==this.groundColor&&(e.object.groundColor=this.groundColor.getHex()),void 0!==this.distance&&(e.object.distance=this.distance),void 0!==this.angle&&(e.object.angle=this.angle),void 0!==this.decay&&(e.object.decay=this.decay),void 0!==this.penumbra&&(e.object.penumbra=this.penumbra),void 0!==this.shadow&&(e.object.shadow=this.shadow.toJSON()),e}}class vc extends gc{constructor(t,e,i){super(t,i),this.isHemisphereLight=!0,this.type="HemisphereLight",this.position.copy(si.DefaultUp),this.updateMatrix(),this.groundColor=new qt(e)}copy(t,e){return super.copy(t,e),this.groundColor.copy(t.groundColor),this}}const xc=new Ne,_c=new re,yc=new re;class Mc{constructor(t){this.camera=t,this.bias=0,this.normalBias=0,this.radius=1,this.blurSamples=8,this.mapSize=new Lt(512,512),this.map=null,this.mapPass=null,this.matrix=new Ne,this.autoUpdate=!0,this.needsUpdate=!1,this._frustum=new xn,this._frameExtents=new Lt(1,1),this._viewportCount=1,this._viewports=[new Qt(0,0,1,1)]}getViewportCount(){return this._viewportCount}getFrustum(){return this._frustum}updateMatrices(t){const e=this.camera,i=this.matrix;_c.setFromMatrixPosition(t.matrixWorld),e.position.copy(_c),yc.setFromMatrixPosition(t.target.matrixWorld),e.lookAt(yc),e.updateMatrixWorld(),xc.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),this._frustum.setFromProjectionMatrix(xc),i.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1),i.multiply(xc)}getViewport(t){return this._viewports[t]}getFrameExtents(){return this._frameExtents}dispose(){this.map&&this.map.dispose(),this.mapPass&&this.mapPass.dispose()}copy(t){return this.camera=t.camera.clone(),this.bias=t.bias,this.radius=t.radius,this.mapSize.copy(t.mapSize),this}clone(){return(new this.constructor).copy(this)}toJSON(){const t={};return 0!==this.bias&&(t.bias=this.bias),0!==this.normalBias&&(t.normalBias=this.normalBias),1!==this.radius&&(t.radius=this.radius),512===this.mapSize.x&&512===this.mapSize.y||(t.mapSize=this.mapSize.toArray()),t.camera=this.camera.toJSON(!1).object,delete t.camera.matrix,t}}class bc extends Mc{constructor(){super(new on(50,1,.5,500)),this.isSpotLightShadow=!0,this.focus=1}updateMatrices(t){const e=this.camera,i=2*xt*t.angle*this.focus,n=this.mapSize.width/this.mapSize.height,r=t.distance||e.far;i===e.fov&&n===e.aspect&&r===e.far||(e.fov=i,e.aspect=n,e.far=r,e.updateProjectionMatrix()),super.updateMatrices(t)}copy(t){return super.copy(t),this.focus=t.focus,this}}class Sc extends gc{constructor(t,e,i=0,n=Math.PI/3,r=0,s=2){super(t,e),this.isSpotLight=!0,this.type="SpotLight",this.position.copy(si.DefaultUp),this.updateMatrix(),this.target=new si,this.distance=i,this.angle=n,this.penumbra=r,this.decay=s,this.map=null,this.shadow=new bc}get power(){return this.intensity*Math.PI}set power(t){this.intensity=t/Math.PI}dispose(){this.shadow.dispose()}copy(t,e){return super.copy(t,e),this.distance=t.distance,this.angle=t.angle,this.penumbra=t.penumbra,this.decay=t.decay,this.target=t.target.clone(),this.shadow=t.shadow.clone(),this}}const wc=new Ne,Tc=new re,Ac=new re;class Ec extends Mc{constructor(){super(new on(90,1,.5,500)),this.isPointLightShadow=!0,this._frameExtents=new Lt(4,2),this._viewportCount=6,this._viewports=[new Qt(2,1,1,1),new Qt(0,1,1,1),new Qt(3,1,1,1),new Qt(1,1,1,1),new Qt(3,0,1,1),new Qt(1,0,1,1)],this._cubeDirections=[new re(1,0,0),new re(-1,0,0),new re(0,0,1),new re(0,0,-1),new re(0,1,0),new re(0,-1,0)],this._cubeUps=[new re(0,1,0),new re(0,1,0),new re(0,1,0),new re(0,1,0),new re(0,0,1),new re(0,0,-1)]}updateMatrices(t,e=0){const i=this.camera,n=this.matrix,r=t.distance||i.far;r!==i.far&&(i.far=r,i.updateProjectionMatrix()),Tc.setFromMatrixPosition(t.matrixWorld),i.position.copy(Tc),Ac.copy(i.position),Ac.add(this._cubeDirections[e]),i.up.copy(this._cubeUps[e]),i.lookAt(Ac),i.updateMatrixWorld(),n.makeTranslation(-Tc.x,-Tc.y,-Tc.z),wc.multiplyMatrices(i.projectionMatrix,i.matrixWorldInverse),this._frustum.setFromProjectionMatrix(wc)}}class Cc extends gc{constructor(t,e,i=0,n=2){super(t,e),this.isPointLight=!0,this.type="PointLight",this.distance=i,this.decay=n,this.shadow=new Ec}get power(){return 4*this.intensity*Math.PI}set power(t){this.intensity=t/(4*Math.PI)}dispose(){this.shadow.dispose()}copy(t,e){return super.copy(t,e),this.distance=t.distance,this.decay=t.decay,this.shadow=t.shadow.clone(),this}}class Lc extends Mc{constructor(){super(new In(-5,5,5,-5,.5,500)),this.isDirectionalLightShadow=!0}}class Rc extends gc{constructor(t,e){super(t,e),this.isDirectionalLight=!0,this.type="DirectionalLight",this.position.copy(si.DefaultUp),this.updateMatrix(),this.target=new si,this.shadow=new Lc}dispose(){this.shadow.dispose()}copy(t){return super.copy(t),this.target=t.target.clone(),this.shadow=t.shadow.clone(),this}}class Pc extends gc{constructor(t,e){super(t,e),this.isAmbientLight=!0,this.type="AmbientLight"}}class Ic extends gc{constructor(t,e,i=10,n=10){super(t,e),this.isRectAreaLight=!0,this.type="RectAreaLight",this.width=i,this.height=n}get power(){return this.intensity*this.width*this.height*Math.PI}set power(t){this.intensity=t/(this.width*this.height*Math.PI)}copy(t){return super.copy(t),this.width=t.width,this.height=t.height,this}toJSON(t){const e=super.toJSON(t);return e.object.width=this.width,e.object.height=this.height,e}}class Dc{constructor(){this.isSphericalHarmonics3=!0,this.coefficients=[];for(let t=0;t<9;t++)this.coefficients.push(new re)}set(t){for(let e=0;e<9;e++)this.coefficients[e].copy(t[e]);return this}zero(){for(let t=0;t<9;t++)this.coefficients[t].set(0,0,0);return this}getAt(t,e){const i=t.x,n=t.y,r=t.z,s=this.coefficients;return e.copy(s[0]).multiplyScalar(.282095),e.addScaledVector(s[1],.488603*n),e.addScaledVector(s[2],.488603*r),e.addScaledVector(s[3],.488603*i),e.addScaledVector(s[4],i*n*1.092548),e.addScaledVector(s[5],n*r*1.092548),e.addScaledVector(s[6],.315392*(3*r*r-1)),e.addScaledVector(s[7],i*r*1.092548),e.addScaledVector(s[8],.546274*(i*i-n*n)),e}getIrradianceAt(t,e){const i=t.x,n=t.y,r=t.z,s=this.coefficients;return e.copy(s[0]).multiplyScalar(.886227),e.addScaledVector(s[1],1.023328*n),e.addScaledVector(s[2],1.023328*r),e.addScaledVector(s[3],1.023328*i),e.addScaledVector(s[4],.858086*i*n),e.addScaledVector(s[5],.858086*n*r),e.addScaledVector(s[6],.743125*r*r-.247708),e.addScaledVector(s[7],.858086*i*r),e.addScaledVector(s[8],.429043*(i*i-n*n)),e}add(t){for(let e=0;e<9;e++)this.coefficients[e].add(t.coefficients[e]);return this}addScaledSH(t,e){for(let i=0;i<9;i++)this.coefficients[i].addScaledVector(t.coefficients[i],e);return this}scale(t){for(let e=0;e<9;e++)this.coefficients[e].multiplyScalar(t);return this}lerp(t,e){for(let i=0;i<9;i++)this.coefficients[i].lerp(t.coefficients[i],e);return this}equals(t){for(let e=0;e<9;e++)if(!this.coefficients[e].equals(t.coefficients[e]))return!1;return!0}copy(t){return this.set(t.coefficients)}clone(){return(new this.constructor).copy(this)}fromArray(t,e=0){const i=this.coefficients;for(let n=0;n<9;n++)i[n].fromArray(t,e+3*n);return this}toArray(t=[],e=0){const i=this.coefficients;for(let n=0;n<9;n++)i[n].toArray(t,e+3*n);return t}static getBasisAt(t,e){const i=t.x,n=t.y,r=t.z;e[0]=.282095,e[1]=.488603*n,e[2]=.488603*r,e[3]=.488603*i,e[4]=1.092548*i*n,e[5]=1.092548*n*r,e[6]=.315392*(3*r*r-1),e[7]=1.092548*i*r,e[8]=.546274*(i*i-n*n)}}class Nc extends gc{constructor(t=new Dc,e=1){super(void 0,e),this.isLightProbe=!0,this.sh=t}copy(t){return super.copy(t),this.sh.copy(t.sh),this}fromJSON(t){return this.intensity=t.intensity,this.sh.fromArray(t.sh),this}toJSON(t){const e=super.toJSON(t);return e.object.sh=this.sh.toArray(),e}}class Oc extends uc{constructor(t){super(t),this.textures={}}load(t,e,i,n){const r=this,s=new mc(r.manager);s.setPath(r.path),s.setRequestHeader(r.requestHeader),s.setWithCredentials(r.withCredentials),s.load(t,(function(i){try{e(r.parse(JSON.parse(i)))}catch(e){n?n(e):console.error(e),r.manager.itemError(t)}}),i,n)}parse(t){const e=this.textures;function i(t){return void 0===e[t]&&console.warn("THREE.MaterialLoader: Undefined texture",t),e[t]}const n=Oc.createMaterialFromType(t.type);if(void 0!==t.uuid&&(n.uuid=t.uuid),void 0!==t.name&&(n.name=t.name),void 0!==t.color&&void 0!==n.color&&n.color.setHex(t.color),void 0!==t.roughness&&(n.roughness=t.roughness),void 0!==t.metalness&&(n.metalness=t.metalness),void 0!==t.sheen&&(n.sheen=t.sheen),void 0!==t.sheenColor&&(n.sheenColor=(new qt).setHex(t.sheenColor)),void 0!==t.sheenRoughness&&(n.sheenRoughness=t.sheenRoughness),void 0!==t.emissive&&void 0!==n.emissive&&n.emissive.setHex(t.emissive),void 0!==t.specular&&void 0!==n.specular&&n.specular.setHex(t.specular),void 0!==t.specularIntensity&&(n.specularIntensity=t.specularIntensity),void 0!==t.specularColor&&void 0!==n.specularColor&&n.specularColor.setHex(t.specularColor),void 0!==t.shininess&&(n.shininess=t.shininess),void 0!==t.clearcoat&&(n.clearcoat=t.clearcoat),void 0!==t.clearcoatRoughness&&(n.clearcoatRoughness=t.clearcoatRoughness),void 0!==t.iridescence&&(n.iridescence=t.iridescence),void 0!==t.iridescenceIOR&&(n.iridescenceIOR=t.iridescenceIOR),void 0!==t.iridescenceThicknessRange&&(n.iridescenceThicknessRange=t.iridescenceThicknessRange),void 0!==t.transmission&&(n.transmission=t.transmission),void 0!==t.thickness&&(n.thickness=t.thickness),void 0!==t.attenuationDistance&&(n.attenuationDistance=t.attenuationDistance),void 0!==t.attenuationColor&&void 0!==n.attenuationColor&&n.attenuationColor.setHex(t.attenuationColor),void 0!==t.fog&&(n.fog=t.fog),void 0!==t.flatShading&&(n.flatShading=t.flatShading),void 0!==t.blending&&(n.blending=t.blending),void 0!==t.combine&&(n.combine=t.combine),void 0!==t.side&&(n.side=t.side),void 0!==t.shadowSide&&(n.shadowSide=t.shadowSide),void 0!==t.opacity&&(n.opacity=t.opacity),void 0!==t.transparent&&(n.transparent=t.transparent),void 0!==t.alphaTest&&(n.alphaTest=t.alphaTest),void 0!==t.depthTest&&(n.depthTest=t.depthTest),void 0!==t.depthWrite&&(n.depthWrite=t.depthWrite),void 0!==t.colorWrite&&(n.colorWrite=t.colorWrite),void 0!==t.stencilWrite&&(n.stencilWrite=t.stencilWrite),void 0!==t.stencilWriteMask&&(n.stencilWriteMask=t.stencilWriteMask),void 0!==t.stencilFunc&&(n.stencilFunc=t.stencilFunc),void 0!==t.stencilRef&&(n.stencilRef=t.stencilRef),void 0!==t.stencilFuncMask&&(n.stencilFuncMask=t.stencilFuncMask),void 0!==t.stencilFail&&(n.stencilFail=t.stencilFail),void 0!==t.stencilZFail&&(n.stencilZFail=t.stencilZFail),void 0!==t.stencilZPass&&(n.stencilZPass=t.stencilZPass),void 0!==t.wireframe&&(n.wireframe=t.wireframe),void 0!==t.wireframeLinewidth&&(n.wireframeLinewidth=t.wireframeLinewidth),void 0!==t.wireframeLinecap&&(n.wireframeLinecap=t.wireframeLinecap),void 0!==t.wireframeLinejoin&&(n.wireframeLinejoin=t.wireframeLinejoin),void 0!==t.rotation&&(n.rotation=t.rotation),1!==t.linewidth&&(n.linewidth=t.linewidth),void 0!==t.dashSize&&(n.dashSize=t.dashSize),void 0!==t.gapSize&&(n.gapSize=t.gapSize),void 0!==t.scale&&(n.scale=t.scale),void 0!==t.polygonOffset&&(n.polygonOffset=t.polygonOffset),void 0!==t.polygonOffsetFactor&&(n.polygonOffsetFactor=t.polygonOffsetFactor),void 0!==t.polygonOffsetUnits&&(n.polygonOffsetUnits=t.polygonOffsetUnits),void 0!==t.dithering&&(n.dithering=t.dithering),void 0!==t.alphaToCoverage&&(n.alphaToCoverage=t.alphaToCoverage),void 0!==t.premultipliedAlpha&&(n.premultipliedAlpha=t.premultipliedAlpha),void 0!==t.visible&&(n.visible=t.visible),void 0!==t.toneMapped&&(n.toneMapped=t.toneMapped),void 0!==t.userData&&(n.userData=t.userData),void 0!==t.vertexColors&&("number"==typeof t.vertexColors?n.vertexColors=t.vertexColors>0:n.vertexColors=t.vertexColors),void 0!==t.uniforms)for(const e in t.uniforms){const r=t.uniforms[e];switch(n.uniforms[e]={},r.type){case"t":n.uniforms[e].value=i(r.value);break;case"c":n.uniforms[e].value=(new qt).setHex(r.value);break;case"v2":n.uniforms[e].value=(new Lt).fromArray(r.value);break;case"v3":n.uniforms[e].value=(new re).fromArray(r.value);break;case"v4":n.uniforms[e].value=(new Qt).fromArray(r.value);break;case"m3":n.uniforms[e].value=(new Rt).fromArray(r.value);break;case"m4":n.uniforms[e].value=(new Ne).fromArray(r.value);break;default:n.uniforms[e].value=r.value}}if(void 0!==t.defines&&(n.defines=t.defines),void 0!==t.vertexShader&&(n.vertexShader=t.vertexShader),void 0!==t.fragmentShader&&(n.fragmentShader=t.fragmentShader),void 0!==t.glslVersion&&(n.glslVersion=t.glslVersion),void 0!==t.extensions)for(const e in t.extensions)n.extensions[e]=t.extensions[e];if(void 0!==t.size&&(n.size=t.size),void 0!==t.sizeAttenuation&&(n.sizeAttenuation=t.sizeAttenuation),void 0!==t.map&&(n.map=i(t.map)),void 0!==t.matcap&&(n.matcap=i(t.matcap)),void 0!==t.alphaMap&&(n.alphaMap=i(t.alphaMap)),void 0!==t.bumpMap&&(n.bumpMap=i(t.bumpMap)),void 0!==t.bumpScale&&(n.bumpScale=t.bumpScale),void 0!==t.normalMap&&(n.normalMap=i(t.normalMap)),void 0!==t.normalMapType&&(n.normalMapType=t.normalMapType),void 0!==t.normalScale){let e=t.normalScale;!1===Array.isArray(e)&&(e=[e,e]),n.normalScale=(new Lt).fromArray(e)}return void 0!==t.displacementMap&&(n.displacementMap=i(t.displacementMap)),void 0!==t.displacementScale&&(n.displacementScale=t.displacementScale),void 0!==t.displacementBias&&(n.displacementBias=t.displacementBias),void 0!==t.roughnessMap&&(n.roughnessMap=i(t.roughnessMap)),void 0!==t.metalnessMap&&(n.metalnessMap=i(t.metalnessMap)),void 0!==t.emissiveMap&&(n.emissiveMap=i(t.emissiveMap)),void 0!==t.emissiveIntensity&&(n.emissiveIntensity=t.emissiveIntensity),void 0!==t.specularMap&&(n.specularMap=i(t.specularMap)),void 0!==t.specularIntensityMap&&(n.specularIntensityMap=i(t.specularIntensityMap)),void 0!==t.specularColorMap&&(n.specularColorMap=i(t.specularColorMap)),void 0!==t.envMap&&(n.envMap=i(t.envMap)),void 0!==t.envMapIntensity&&(n.envMapIntensity=t.envMapIntensity),void 0!==t.reflectivity&&(n.reflectivity=t.reflectivity),void 0!==t.refractionRatio&&(n.refractionRatio=t.refractionRatio),void 0!==t.lightMap&&(n.lightMap=i(t.lightMap)),void 0!==t.lightMapIntensity&&(n.lightMapIntensity=t.lightMapIntensity),void 0!==t.aoMap&&(n.aoMap=i(t.aoMap)),void 0!==t.aoMapIntensity&&(n.aoMapIntensity=t.aoMapIntensity),void 0!==t.gradientMap&&(n.gradientMap=i(t.gradientMap)),void 0!==t.clearcoatMap&&(n.clearcoatMap=i(t.clearcoatMap)),void 0!==t.clearcoatRoughnessMap&&(n.clearcoatRoughnessMap=i(t.clearcoatRoughnessMap)),void 0!==t.clearcoatNormalMap&&(n.clearcoatNormalMap=i(t.clearcoatNormalMap)),void 0!==t.clearcoatNormalScale&&(n.clearcoatNormalScale=(new Lt).fromArray(t.clearcoatNormalScale)),void 0!==t.iridescenceMap&&(n.iridescenceMap=i(t.iridescenceMap)),void 0!==t.iridescenceThicknessMap&&(n.iridescenceThicknessMap=i(t.iridescenceThicknessMap)),void 0!==t.transmissionMap&&(n.transmissionMap=i(t.transmissionMap)),void 0!==t.thicknessMap&&(n.thicknessMap=i(t.thicknessMap)),void 0!==t.sheenColorMap&&(n.sheenColorMap=i(t.sheenColorMap)),void 0!==t.sheenRoughnessMap&&(n.sheenRoughnessMap=i(t.sheenRoughnessMap)),n}setTextures(t){return this.textures=t,this}static createMaterialFromType(t){return new{ShadowMaterial:Pl,SpriteMaterial:sa,RawShaderMaterial:Il,ShaderMaterial:sn,PointsMaterial:Qa,MeshPhysicalMaterial:Nl,MeshStandardMaterial:Dl,MeshPhongMaterial:Ol,MeshToonMaterial:zl,MeshNormalMaterial:Ul,MeshLambertMaterial:Bl,MeshDepthMaterial:Us,MeshDistanceMaterial:Bs,MeshBasicMaterial:_i,MeshMatcapMaterial:Fl,LineDashedMaterial:kl,LineBasicMaterial:Va,Material:xi}[t]}}class zc{static decodeText(t){if("undefined"!=typeof TextDecoder)return(new TextDecoder).decode(t);let e="";for(let i=0,n=t.length;i0){this.source.connect(this.filters[0]);for(let t=1,e=this.filters.length;t0){this.source.disconnect(this.filters[0]);for(let t=1,e=this.filters.length;t0&&this._mixBufferRegionAdditive(i,n,this._addIndex*e,1,e);for(let t=e,r=e+e;t!==r;++t)if(i[t]!==i[t+e]){a.setValue(i,n);break}}saveOriginalState(){const t=this.binding,e=this.buffer,i=this.valueSize,n=i*this._origIndex;t.getValue(e,n);for(let t=i,r=n;t!==r;++t)e[t]=e[n+t%i];this._setIdentity(),this.cumulativeWeight=0,this.cumulativeWeightAdditive=0}restoreOriginalState(){const t=3*this.valueSize;this.binding.setValue(this.buffer,t)}_setAdditiveIdentityNumeric(){const t=this._addIndex*this.valueSize,e=t+this.valueSize;for(let i=t;i=.5)for(let n=0;n!==r;++n)t[e+n]=t[i+n]}_slerp(t,e,i,n){ne.slerpFlat(t,e,t,e,t,i,n)}_slerpAdditive(t,e,i,n,r){const s=this._workIndex*r;ne.multiplyQuaternionsFlat(t,s,t,e,t,i),ne.slerpFlat(t,e,t,e,t,s,n)}_lerp(t,e,i,n,r){const s=1-n;for(let a=0;a!==r;++a){const r=e+a;t[r]=t[r]*s+t[i+a]*n}}_lerpAdditive(t,e,i,n,r){for(let s=0;s!==r;++s){const r=e+s;t[r]=t[r]+t[i+s]*n}}}const sh="\\[\\]\\.:\\/",ah=new RegExp("[\\[\\]\\.:\\/]","g"),oh="[^\\[\\]\\.:\\/]",lh="[^"+sh.replace("\\.","")+"]",ch=new RegExp("^"+/((?:WC+[\/:])*)/.source.replace("WC",oh)+/(WCOD+)?/.source.replace("WCOD",lh)+/(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC",oh)+/\.(WC+)(?:\[(.+)\])?/.source.replace("WC",oh)+"$"),hh=["material","materials","bones","map"];class uh{constructor(t,e,i){this.path=e,this.parsedPath=i||uh.parseTrackName(e),this.node=uh.findNode(t,this.parsedPath.nodeName)||t,this.rootNode=t,this.getValue=this._getValue_unbound,this.setValue=this._setValue_unbound}static create(t,e,i){return t&&t.isAnimationObjectGroup?new uh.Composite(t,e,i):new uh(t,e,i)}static sanitizeNodeName(t){return t.replace(/\s/g,"_").replace(ah,"")}static parseTrackName(t){const e=ch.exec(t);if(null===e)throw new Error("PropertyBinding: Cannot parse trackName: "+t);const i={nodeName:e[2],objectName:e[3],objectIndex:e[4],propertyName:e[5],propertyIndex:e[6]},n=i.nodeName&&i.nodeName.lastIndexOf(".");if(void 0!==n&&-1!==n){const t=i.nodeName.substring(n+1);-1!==hh.indexOf(t)&&(i.nodeName=i.nodeName.substring(0,n),i.objectName=t)}if(null===i.propertyName||0===i.propertyName.length)throw new Error("PropertyBinding: can not parse propertyName from trackName: "+t);return i}static findNode(t,e){if(void 0===e||""===e||"."===e||-1===e||e===t.name||e===t.uuid)return t;if(t.skeleton){const i=t.skeleton.getBoneByName(e);if(void 0!==i)return i}if(t.children){const i=function(t){for(let n=0;n0){const t=this._interpolants,e=this._propertyBindings;if(this.blendMode===st)for(let i=0,n=t.length;i!==n;++i)t[i].evaluate(s),e[i].accumulateAdditive(a);else for(let i=0,r=t.length;i!==r;++i)t[i].evaluate(s),e[i].accumulate(n,a)}}_updateWeight(t){let e=0;if(this.enabled){e=this.weight;const i=this._weightInterpolant;if(null!==i){const n=i.evaluate(t)[0];e*=n,t>i.parameterPositions[1]&&(this.stopFading(),0===n&&(this.enabled=!1))}}return this._effectiveWeight=e,e}_updateTimeScale(t){let e=0;if(!this.paused){e=this.timeScale;const i=this._timeScaleInterpolant;if(null!==i){e*=i.evaluate(t)[0],t>i.parameterPositions[1]&&(this.stopWarping(),0===e?this.paused=!0:this.timeScale=e)}}return this._effectiveTimeScale=e,e}_updateTime(t){const e=this._clip.duration,i=this.loop;let n=this.time+t,r=this._loopCount;const s=2202===i;if(0===t)return-1===r?n:s&&1==(1&r)?e-n:n;if(2200===i){-1===r&&(this._loopCount=0,this._setEndings(!0,!0,!1));t:{if(n>=e)n=e;else{if(!(n<0)){this.time=n;break t}n=0}this.clampWhenFinished?this.paused=!0:this.enabled=!1,this.time=n,this._mixer.dispatchEvent({type:"finished",action:this,direction:t<0?-1:1})}}else{if(-1===r&&(t>=0?(r=0,this._setEndings(!0,0===this.repetitions,s)):this._setEndings(0===this.repetitions,!0,s)),n>=e||n<0){const i=Math.floor(n/e);n-=e*i,r+=Math.abs(i);const a=this.repetitions-r;if(a<=0)this.clampWhenFinished?this.paused=!0:this.enabled=!1,n=t>0?e:0,this.time=n,this._mixer.dispatchEvent({type:"finished",action:this,direction:t>0?1:-1});else{if(1===a){const e=t<0;this._setEndings(e,!e,s)}else this._setEndings(!1,!1,s);this._loopCount=r,this.time=n,this._mixer.dispatchEvent({type:"loop",action:this,loopDelta:i})}}else this.time=n;if(s&&1==(1&r))return e-n}return n}_setEndings(t,e,i){const n=this._interpolantSettings;i?(n.endingStart=it,n.endingEnd=it):(n.endingStart=t?this.zeroSlopeAtStart?it:et:nt,n.endingEnd=e?this.zeroSlopeAtEnd?it:et:nt)}_scheduleFading(t,e,i){const n=this._mixer,r=n.time;let s=this._weightInterpolant;null===s&&(s=n._lendControlInterpolant(),this._weightInterpolant=s);const a=s.parameterPositions,o=s.sampleValues;return a[0]=r,o[0]=e,a[1]=r+t,o[1]=i,this}}const ph=new Float32Array(1);class mh{constructor(t){this.value=t}clone(){return new mh(void 0===this.value.clone?this.value:this.value.clone())}}let fh=0;function gh(t,e){return t.distance-e.distance}function vh(t,e,i,n){if(t.layers.test(e.layers)&&t.raycast(e,i),!0===n){const n=t.children;for(let t=0,r=n.length;t>-e-14,n[256|t]=1024>>-e-14|32768,r[t]=-e-1,r[256|t]=-e-1):e<=15?(n[t]=e+15<<10,n[256|t]=e+15<<10|32768,r[t]=13,r[256|t]=13):e<128?(n[t]=31744,n[256|t]=64512,r[t]=24,r[256|t]=24):(n[t]=31744,n[256|t]=64512,r[t]=13,r[256|t]=13)}const s=new Uint32Array(2048),a=new Uint32Array(64),o=new Uint32Array(64);for(let t=1;t<1024;++t){let e=t<<13,i=0;for(;0==(8388608&e);)e<<=1,i-=8388608;e&=-8388609,i+=947912704,s[t]=e|i}for(let t=1024;t<2048;++t)s[t]=939524096+(t-1024<<13);for(let t=1;t<31;++t)a[t]=t<<23;a[31]=1199570944,a[32]=2147483648;for(let t=33;t<63;++t)a[t]=2147483648+(t-32<<23);a[63]=3347054592;for(let t=1;t<64;++t)32!==t&&(o[t]=1024);return{floatView:e,uint32View:i,baseTable:n,shiftTable:r,mantissaTable:s,exponentTable:a,offsetTable:o}}var Gh=Object.freeze({__proto__:null,toHalfFloat:function(t){Math.abs(t)>65504&&console.warn("THREE.DataUtils.toHalfFloat(): Value out of range."),t=yt(t,-65504,65504),Fh.floatView[0]=t;const e=Fh.uint32View[0],i=e>>23&511;return Fh.baseTable[i]+((8388607&e)>>Fh.shiftTable[i])},fromHalfFloat:function(t){const e=t>>10;return Fh.uint32View[0]=Fh.mantissaTable[Fh.offsetTable[e]+(1023&t)]+Fh.exponentTable[e],Fh.floatView[0]}});"undefined"!=typeof __THREE_DEVTOOLS__&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("register",{detail:{revision:e}})),"undefined"!=typeof window&&(window.__THREE__?console.warn("WARNING: Multiple instances of Three.js being imported."):window.__THREE__=e),t.ACESFilmicToneMapping=4,t.AddEquation=i,t.AddOperation=2,t.AdditiveAnimationBlendMode=st,t.AdditiveBlending=2,t.AlphaFormat=1021,t.AlwaysDepth=1,t.AlwaysStencilFunc=519,t.AmbientLight=Pc,t.AmbientLightProbe=class extends Nc{constructor(t,e=1){super(void 0,e),this.isAmbientLightProbe=!0;const i=(new qt).set(t);this.sh.coefficients[0].set(i.r,i.g,i.b).multiplyScalar(2*Math.sqrt(Math.PI))}},t.AnimationClip=ac,t.AnimationLoader=class extends uc{constructor(t){super(t)}load(t,e,i,n){const r=this,s=new mc(this.manager);s.setPath(this.path),s.setRequestHeader(this.requestHeader),s.setWithCredentials(this.withCredentials),s.load(t,(function(i){try{e(r.parse(JSON.parse(i)))}catch(e){n?n(e):console.error(e),r.manager.itemError(t)}}),i,n)}parse(t){const e=[];for(let i=0;i=0;--e)t[e].stop();return this}update(t){t*=this.timeScale;const e=this._actions,i=this._nActiveActions,n=this.time+=t,r=Math.sign(t),s=this._accuIndex^=1;for(let a=0;a!==i;++a){e[a]._update(n,t,r,s)}const a=this._bindings,o=this._nActiveBindings;for(let t=0;t!==o;++t)a[t].apply(s);return this}setTime(t){this.time=0;for(let t=0;t=r){const s=r++,c=t[s];e[c.uuid]=l,t[l]=c,e[o]=s,t[s]=a;for(let t=0,e=n;t!==e;++t){const e=i[t],n=e[s],r=e[l];e[l]=n,e[s]=r}}}this.nCachedObjects_=r}uncache(){const t=this._objects,e=this._indicesByUUID,i=this._bindings,n=i.length;let r=this.nCachedObjects_,s=t.length;for(let a=0,o=arguments.length;a!==o;++a){const o=arguments[a].uuid,l=e[o];if(void 0!==l)if(delete e[o],l0&&(e[a.uuid]=l),t[l]=a,t.pop();for(let t=0,e=n;t!==e;++t){const e=i[t];e[l]=e[r],e.pop()}}}this.nCachedObjects_=r}subscribe_(t,e){const i=this._bindingsIndicesByPath;let n=i[t];const r=this._bindings;if(void 0!==n)return r[n];const s=this._paths,a=this._parsedPaths,o=this._objects,l=o.length,c=this.nCachedObjects_,h=new Array(l);n=r.length,i[t]=n,s.push(t),a.push(e),r.push(h);for(let i=c,n=o.length;i!==n;++i){const n=o[i];h[i]=new uh(n,t,e)}return h}unsubscribe_(t){const e=this._bindingsIndicesByPath,i=e[t];if(void 0!==i){const n=this._paths,r=this._parsedPaths,s=this._bindings,a=s.length-1,o=s[a];e[t[a]]=i,s[i]=o,s.pop(),r[i]=r[a],r.pop(),n[i]=n[a],n.pop()}}},t.AnimationUtils=Xl,t.ArcCurve=co,t.ArrayCamera=Hs,t.ArrowHelper=class extends si{constructor(t=new re(0,0,1),e=new re(0,0,0),i=1,n=16776960,r=.2*i,s=.2*r){super(),this.type="ArrowHelper",void 0===Uh&&(Uh=new Di,Uh.setAttribute("position",new Ti([0,0,0,0,1,0],3)),Bh=new Do(0,.5,1,5,1),Bh.translate(0,-.5,0)),this.position.copy(e),this.line=new Ya(Uh,new Va({color:n,toneMapped:!1})),this.line.matrixAutoUpdate=!1,this.add(this.line),this.cone=new Ki(Bh,new _i({color:n,toneMapped:!1})),this.cone.matrixAutoUpdate=!1,this.add(this.cone),this.setDirection(t),this.setLength(i,r,s)}setDirection(t){if(t.y>.99999)this.quaternion.set(0,0,0,1);else if(t.y<-.99999)this.quaternion.set(1,0,0,0);else{zh.set(t.z,0,-t.x).normalize();const e=Math.acos(t.y);this.quaternion.setFromAxisAngle(zh,e)}}setLength(t,e=.2*t,i=.2*e){this.line.scale.set(1,Math.max(1e-4,t-e),1),this.line.updateMatrix(),this.cone.scale.set(i,e,i),this.cone.position.y=t,this.cone.updateMatrix()}setColor(t){this.line.material.color.set(t),this.cone.material.color.set(t)}copy(t){return super.copy(t,!1),this.line.copy(t.line),this.cone.copy(t.cone),this}dispose(){this.line.geometry.dispose(),this.line.material.dispose(),this.cone.geometry.dispose(),this.cone.material.dispose()}},t.Audio=Qc,t.AudioAnalyser=class{constructor(t,e=2048){this.analyser=t.context.createAnalyser(),this.analyser.fftSize=e,this.data=new Uint8Array(this.analyser.frequencyBinCount),t.getOutput().connect(this.analyser)}getFrequencyData(){return this.analyser.getByteFrequencyData(this.data),this.data}getAverageFrequency(){let t=0;const e=this.getFrequencyData();for(let i=0;ithis.max.x||t.ythis.max.y)}containsBox(t){return this.min.x<=t.min.x&&t.max.x<=this.max.x&&this.min.y<=t.min.y&&t.max.y<=this.max.y}getParameter(t,e){return e.set((t.x-this.min.x)/(this.max.x-this.min.x),(t.y-this.min.y)/(this.max.y-this.min.y))}intersectsBox(t){return!(t.max.xthis.max.x||t.max.ythis.max.y)}clampPoint(t,e){return e.copy(t).clamp(this.min,this.max)}distanceToPoint(t){return xh.copy(t).clamp(this.min,this.max).sub(t).length()}intersect(t){return this.min.max(t.min),this.max.min(t.max),this}union(t){return this.min.min(t.min),this.max.max(t.max),this}translate(t){return this.min.add(t),this.max.add(t),this}equals(t){return t.min.equals(this.min)&&t.max.equals(this.max)}},t.Box3=oe,t.Box3Helper=class extends Ka{constructor(t,e=16776960){const i=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]),n=new Di;n.setIndex(new bi(i,1)),n.setAttribute("position",new Ti([1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1],3)),super(n,new Va({color:e,toneMapped:!1})),this.box=t,this.type="Box3Helper",this.geometry.computeBoundingSphere()}updateMatrixWorld(t){const e=this.box;e.isEmpty()||(e.getCenter(this.position),e.getSize(this.scale),this.scale.multiplyScalar(.5),super.updateMatrixWorld(t))}dispose(){this.geometry.dispose(),this.material.dispose()}},t.BoxBufferGeometry=class extends Qi{constructor(t,e,i,n,r,s){console.warn("THREE.BoxBufferGeometry has been renamed to THREE.BoxGeometry."),super(t,e,i,n,r,s)}},t.BoxGeometry=Qi,t.BoxHelper=class extends Ka{constructor(t,e=16776960){const i=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]),n=new Float32Array(24),r=new Di;r.setIndex(new bi(i,1)),r.setAttribute("position",new bi(n,3)),super(r,new Va({color:e,toneMapped:!1})),this.object=t,this.type="BoxHelper",this.matrixAutoUpdate=!1,this.update()}update(t){if(void 0!==t&&console.warn("THREE.BoxHelper: .update() has no longer arguments."),void 0!==this.object&&Oh.setFromObject(this.object),Oh.isEmpty())return;const e=Oh.min,i=Oh.max,n=this.geometry.attributes.position,r=n.array;r[0]=i.x,r[1]=i.y,r[2]=i.z,r[3]=e.x,r[4]=i.y,r[5]=i.z,r[6]=e.x,r[7]=e.y,r[8]=i.z,r[9]=i.x,r[10]=e.y,r[11]=i.z,r[12]=i.x,r[13]=i.y,r[14]=e.z,r[15]=e.x,r[16]=i.y,r[17]=e.z,r[18]=e.x,r[19]=e.y,r[20]=e.z,r[21]=i.x,r[22]=e.y,r[23]=e.z,n.needsUpdate=!0,this.geometry.computeBoundingSphere()}setFromObject(t){return this.object=t,this.update(),this}copy(t,e){return super.copy(t,e),this.object=t.object,this}dispose(){this.geometry.dispose(),this.material.dispose()}},t.BufferAttribute=bi,t.BufferGeometry=Di,t.BufferGeometryLoader=Bc,t.ByteType=1010,t.Cache=lc,t.Camera=an,t.CameraHelper=class extends Ka{constructor(t){const e=new Di,i=new Va({color:16777215,vertexColors:!0,toneMapped:!1}),n=[],r=[],s={};function a(t,e){o(t),o(e)}function o(t){n.push(0,0,0),r.push(0,0,0),void 0===s[t]&&(s[t]=[]),s[t].push(n.length/3-1)}a("n1","n2"),a("n2","n4"),a("n4","n3"),a("n3","n1"),a("f1","f2"),a("f2","f4"),a("f4","f3"),a("f3","f1"),a("n1","f1"),a("n2","f2"),a("n3","f3"),a("n4","f4"),a("p","n1"),a("p","n2"),a("p","n3"),a("p","n4"),a("u1","u2"),a("u2","u3"),a("u3","u1"),a("c","t"),a("p","c"),a("cn1","cn2"),a("cn3","cn4"),a("cf1","cf2"),a("cf3","cf4"),e.setAttribute("position",new Ti(n,3)),e.setAttribute("color",new Ti(r,3)),super(e,i),this.type="CameraHelper",this.camera=t,this.camera.updateProjectionMatrix&&this.camera.updateProjectionMatrix(),this.matrix=t.matrixWorld,this.matrixAutoUpdate=!1,this.pointMap=s,this.update();const l=new qt(16755200),c=new qt(16711680),h=new qt(43775),u=new qt(16777215),d=new qt(3355443);this.setColors(l,c,h,u,d)}setColors(t,e,i,n,r){const s=this.geometry.getAttribute("color");s.setXYZ(0,t.r,t.g,t.b),s.setXYZ(1,t.r,t.g,t.b),s.setXYZ(2,t.r,t.g,t.b),s.setXYZ(3,t.r,t.g,t.b),s.setXYZ(4,t.r,t.g,t.b),s.setXYZ(5,t.r,t.g,t.b),s.setXYZ(6,t.r,t.g,t.b),s.setXYZ(7,t.r,t.g,t.b),s.setXYZ(8,t.r,t.g,t.b),s.setXYZ(9,t.r,t.g,t.b),s.setXYZ(10,t.r,t.g,t.b),s.setXYZ(11,t.r,t.g,t.b),s.setXYZ(12,t.r,t.g,t.b),s.setXYZ(13,t.r,t.g,t.b),s.setXYZ(14,t.r,t.g,t.b),s.setXYZ(15,t.r,t.g,t.b),s.setXYZ(16,t.r,t.g,t.b),s.setXYZ(17,t.r,t.g,t.b),s.setXYZ(18,t.r,t.g,t.b),s.setXYZ(19,t.r,t.g,t.b),s.setXYZ(20,t.r,t.g,t.b),s.setXYZ(21,t.r,t.g,t.b),s.setXYZ(22,t.r,t.g,t.b),s.setXYZ(23,t.r,t.g,t.b),s.setXYZ(24,e.r,e.g,e.b),s.setXYZ(25,e.r,e.g,e.b),s.setXYZ(26,e.r,e.g,e.b),s.setXYZ(27,e.r,e.g,e.b),s.setXYZ(28,e.r,e.g,e.b),s.setXYZ(29,e.r,e.g,e.b),s.setXYZ(30,e.r,e.g,e.b),s.setXYZ(31,e.r,e.g,e.b),s.setXYZ(32,i.r,i.g,i.b),s.setXYZ(33,i.r,i.g,i.b),s.setXYZ(34,i.r,i.g,i.b),s.setXYZ(35,i.r,i.g,i.b),s.setXYZ(36,i.r,i.g,i.b),s.setXYZ(37,i.r,i.g,i.b),s.setXYZ(38,n.r,n.g,n.b),s.setXYZ(39,n.r,n.g,n.b),s.setXYZ(40,r.r,r.g,r.b),s.setXYZ(41,r.r,r.g,r.b),s.setXYZ(42,r.r,r.g,r.b),s.setXYZ(43,r.r,r.g,r.b),s.setXYZ(44,r.r,r.g,r.b),s.setXYZ(45,r.r,r.g,r.b),s.setXYZ(46,r.r,r.g,r.b),s.setXYZ(47,r.r,r.g,r.b),s.setXYZ(48,r.r,r.g,r.b),s.setXYZ(49,r.r,r.g,r.b),s.needsUpdate=!0}update(){const t=this.geometry,e=this.pointMap;Dh.projectionMatrixInverse.copy(this.camera.projectionMatrixInverse),Nh("c",e,t,Dh,0,0,-1),Nh("t",e,t,Dh,0,0,1),Nh("n1",e,t,Dh,-1,-1,-1),Nh("n2",e,t,Dh,1,-1,-1),Nh("n3",e,t,Dh,-1,1,-1),Nh("n4",e,t,Dh,1,1,-1),Nh("f1",e,t,Dh,-1,-1,1),Nh("f2",e,t,Dh,1,-1,1),Nh("f3",e,t,Dh,-1,1,1),Nh("f4",e,t,Dh,1,1,1),Nh("u1",e,t,Dh,.7,1.1,-1),Nh("u2",e,t,Dh,-.7,1.1,-1),Nh("u3",e,t,Dh,0,2,-1),Nh("cf1",e,t,Dh,-1,0,1),Nh("cf2",e,t,Dh,1,0,1),Nh("cf3",e,t,Dh,0,-1,1),Nh("cf4",e,t,Dh,0,1,1),Nh("cn1",e,t,Dh,-1,0,-1),Nh("cn2",e,t,Dh,1,0,-1),Nh("cn3",e,t,Dh,0,-1,-1),Nh("cn4",e,t,Dh,0,1,-1),t.getAttribute("position").needsUpdate=!0}dispose(){this.geometry.dispose(),this.material.dispose()}},t.CanvasTexture=class extends $t{constructor(t,e,i,n,r,s,a,o,l){super(t,e,i,n,r,s,a,o,l),this.isCanvasTexture=!0,this.needsUpdate=!0}},t.CapsuleBufferGeometry=class extends Po{constructor(t,e,i,n){console.warn("THREE.CapsuleBufferGeometry has been renamed to THREE.CapsuleGeometry."),super(t,e,i,n)}},t.CapsuleGeometry=Po,t.CatmullRomCurve3=go,t.CineonToneMapping=3,t.CircleBufferGeometry=class extends Io{constructor(t,e,i,n){console.warn("THREE.CircleBufferGeometry has been renamed to THREE.CircleGeometry."),super(t,e,i,n)}},t.CircleGeometry=Io,t.ClampToEdgeWrapping=h,t.Clock=Xc,t.Color=qt,t.ColorKeyframeTrack=tc,t.ColorManagement=Ft,t.CompressedArrayTexture=class extends ao{constructor(t,e,i,n,r,s){super(t,e,i,r,s),this.isCompressedArrayTexture=!0,this.image.depth=n,this.wrapR=h}},t.CompressedTexture=ao,t.CompressedTextureLoader=class extends uc{constructor(t){super(t)}load(t,e,i,n){const r=this,s=[],a=new ao,o=new mc(this.manager);o.setPath(this.path),o.setResponseType("arraybuffer"),o.setRequestHeader(this.requestHeader),o.setWithCredentials(r.withCredentials);let l=0;function c(c){o.load(t[c],(function(t){const i=r.parse(t,!0);s[c]={width:i.width,height:i.height,format:i.format,mipmaps:i.mipmaps},l+=1,6===l&&(1===i.mipmapCount&&(a.minFilter=f),a.image=s,a.format=i.format,a.needsUpdate=!0,e&&e(a))}),i,n)}if(Array.isArray(t))for(let e=0,i=t.length;e0){const i=new cc(e);r=new fc(i),r.setCrossOrigin(this.crossOrigin);for(let e=0,i=t.length;e0){n=new fc(this.manager),n.setCrossOrigin(this.crossOrigin);for(let e=0,n=t.length;e1)for(let i=0;iNumber.EPSILON){if(l<0&&(i=e[s],o=-o,a=e[r],l=-l),t.ya.y)continue;if(t.y===i.y){if(t.x===i.x)return!0}else{const e=l*(t.x-i.x)-o*(t.y-i.y);if(0===e)return!0;if(e<0)continue;n=!n}}else{if(t.y!==i.y)continue;if(a.x<=t.x&&t.x<=i.x||i.x<=t.x&&t.x<=a.x)return!0}}return n}const i=ml.isClockWise,n=this.subPaths;if(0===n.length)return[];let r,s,a;const o=[];if(1===n.length)return s=n[0],a=new Vo,a.curves=s.curves,o.push(a),o;let l=!i(n[0].getPoints());l=t?!l:l;const c=[],h=[];let u,d,p=[],m=0;h[m]=void 0,p[m]=[];for(let e=0,a=n.length;e1){let t=!1,i=0;for(let t=0,e=h.length;t0&&!1===t&&(p=c)}for(let t=0,e=h.length;t=t.HAVE_CURRENT_DATA&&(this.needsUpdate=!0)}},t.WebGL1Renderer=$s,t.WebGL3DRenderTarget=class extends te{constructor(t=1,e=1,i=1){super(t,e),this.isWebGL3DRenderTarget=!0,this.depth=i,this.texture=new ie(null,t,e,i),this.texture.isRenderTargetTexture=!0}},t.WebGLArrayRenderTarget=class extends te{constructor(t=1,e=1,i=1){super(t,e),this.isWebGLArrayRenderTarget=!0,this.depth=i,this.texture=new ee(null,t,e,i),this.texture.isRenderTargetTexture=!0}},t.WebGLCubeRenderTarget=un,t.WebGLMultipleRenderTargets=class extends te{constructor(t=1,e=1,i=1,n={}){super(t,e,n),this.isWebGLMultipleRenderTargets=!0;const r=this.texture;this.texture=[];for(let t=0;t= 0; -- i ) { - if ( array[ i ] > 65535 ) return true; + if ( array[ i ] >= 65535 ) return true; // account for PRIMITIVE_RESTART_FIXED_INDEX, #24565 } @@ -1524,7 +1557,7 @@ const _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua' '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 }; -const _rgb = { r: 0, g: 0, b: 0 }; +const _rgb$1 = { r: 0, g: 0, b: 0 }; const _hslA = { h: 0, s: 0, l: 0 }; const _hslB = { h: 0, s: 0, l: 0 }; @@ -1614,7 +1647,7 @@ class Color { } - setRGB( r, g, b, colorSpace = LinearSRGBColorSpace ) { + setRGB( r, g, b, colorSpace = ColorManagement.workingColorSpace ) { this.r = r; this.g = g; @@ -1626,7 +1659,7 @@ class Color { } - setHSL( h, s, l, colorSpace = LinearSRGBColorSpace ) { + setHSL( h, s, l, colorSpace = ColorManagement.workingColorSpace ) { // h,s,l ranges are in 0.0 - 1.0 h = euclideanModulo( h, 1 ); @@ -1719,12 +1752,12 @@ class Color { case 'hsl': case 'hsla': - if ( color = /^\s*(\d*\.?\d+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) { + if ( color = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) { // hsl(120,50%,50%) hsla(120,50%,50%,0.5) const h = parseFloat( color[ 1 ] ) / 360; - const s = parseInt( color[ 2 ], 10 ) / 100; - const l = parseInt( color[ 3 ], 10 ) / 100; + const s = parseFloat( color[ 2 ] ) / 100; + const l = parseFloat( color[ 3 ] ) / 100; handleAlpha( color[ 4 ] ); @@ -1854,9 +1887,9 @@ class Color { getHex( colorSpace = SRGBColorSpace ) { - ColorManagement.fromWorkingColorSpace( toComponents( this, _rgb ), colorSpace ); + ColorManagement.fromWorkingColorSpace( toComponents( this, _rgb$1 ), colorSpace ); - return clamp( _rgb.r * 255, 0, 255 ) << 16 ^ clamp( _rgb.g * 255, 0, 255 ) << 8 ^ clamp( _rgb.b * 255, 0, 255 ) << 0; + return clamp( _rgb$1.r * 255, 0, 255 ) << 16 ^ clamp( _rgb$1.g * 255, 0, 255 ) << 8 ^ clamp( _rgb$1.b * 255, 0, 255 ) << 0; } @@ -1866,13 +1899,13 @@ class Color { } - getHSL( target, colorSpace = LinearSRGBColorSpace ) { + getHSL( target, colorSpace = ColorManagement.workingColorSpace ) { // h,s,l ranges are in 0.0 - 1.0 - ColorManagement.fromWorkingColorSpace( toComponents( this, _rgb ), colorSpace ); + ColorManagement.fromWorkingColorSpace( toComponents( this, _rgb$1 ), colorSpace ); - const r = _rgb.r, g = _rgb.g, b = _rgb.b; + const r = _rgb$1.r, g = _rgb$1.g, b = _rgb$1.b; const max = Math.max( r, g, b ); const min = Math.min( r, g, b ); @@ -1911,13 +1944,13 @@ class Color { } - getRGB( target, colorSpace = LinearSRGBColorSpace ) { + getRGB( target, colorSpace = ColorManagement.workingColorSpace ) { - ColorManagement.fromWorkingColorSpace( toComponents( this, _rgb ), colorSpace ); + ColorManagement.fromWorkingColorSpace( toComponents( this, _rgb$1 ), colorSpace ); - target.r = _rgb.r; - target.g = _rgb.g; - target.b = _rgb.b; + target.r = _rgb$1.r; + target.g = _rgb$1.g; + target.b = _rgb$1.b; return target; @@ -1925,16 +1958,16 @@ class Color { getStyle( colorSpace = SRGBColorSpace ) { - ColorManagement.fromWorkingColorSpace( toComponents( this, _rgb ), colorSpace ); + ColorManagement.fromWorkingColorSpace( toComponents( this, _rgb$1 ), colorSpace ); if ( colorSpace !== SRGBColorSpace ) { // Requires CSS Color Module Level 4 (https://www.w3.org/TR/css-color-4/). - return `color(${ colorSpace } ${ _rgb.r } ${ _rgb.g } ${ _rgb.b })`; + return `color(${ colorSpace } ${ _rgb$1.r } ${ _rgb$1.g } ${ _rgb$1.b })`; } - return `rgb(${( _rgb.r * 255 ) | 0},${( _rgb.g * 255 ) | 0},${( _rgb.b * 255 ) | 0})`; + return `rgb(${( _rgb$1.r * 255 ) | 0},${( _rgb$1.g * 255 ) | 0},${( _rgb$1.b * 255 ) | 0})`; } @@ -2077,16 +2110,6 @@ class Color { this.g = attribute.getY( index ); this.b = attribute.getZ( index ); - if ( attribute.normalized === true ) { - - // assuming Uint8Array - - this.r /= 255; - this.g /= 255; - this.b /= 255; - - } - return this; } @@ -2357,7 +2380,7 @@ let textureId = 0; class Texture extends EventDispatcher { - constructor( image = Texture.DEFAULT_IMAGE, mapping = Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format = RGBAFormat, type = UnsignedByteType, anisotropy = 1, encoding = LinearEncoding ) { + constructor( image = Texture.DEFAULT_IMAGE, mapping = Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format = RGBAFormat, type = UnsignedByteType, anisotropy = Texture.DEFAULT_ANISOTROPY, encoding = LinearEncoding ) { super(); @@ -2642,6 +2665,7 @@ class Texture extends EventDispatcher { Texture.DEFAULT_IMAGE = null; Texture.DEFAULT_MAPPING = UVMapping; +Texture.DEFAULT_ANISOTROPY = 1; class Vector4 { @@ -3293,7 +3317,7 @@ class Vector4 { */ class WebGLRenderTarget extends EventDispatcher { - constructor( width, height, options = {} ) { + constructor( width = 1, height = 1, options = {} ) { super(); @@ -3414,7 +3438,7 @@ class DataArrayTexture extends Texture { class WebGLArrayRenderTarget extends WebGLRenderTarget { - constructor( width, height, depth ) { + constructor( width = 1, height = 1, depth = 1 ) { super( width, height ); @@ -3463,7 +3487,7 @@ class Data3DTexture extends Texture { class WebGL3DRenderTarget extends WebGLRenderTarget { - constructor( width, height, depth ) { + constructor( width = 1, height = 1, depth = 1 ) { super( width, height ); @@ -3481,7 +3505,7 @@ class WebGL3DRenderTarget extends WebGLRenderTarget { class WebGLMultipleRenderTargets extends WebGLRenderTarget { - constructor( width, height, count, options = {} ) { + constructor( width = 1, height = 1, count = 1, options = {} ) { super( width, height, options ); @@ -3758,12 +3782,6 @@ class Quaternion { setFromEuler( euler, update ) { - if ( ! ( euler && euler.isEuler ) ) { - - throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' ); - - } - const x = euler._x, y = euler._y, z = euler._z, order = euler._order; // http://www.mathworks.com/matlabcentral/fileexchange/ @@ -5300,12 +5318,12 @@ class Box3 { // translate triangle to aabb origin _v0$2.subVectors( triangle.a, _center ); _v1$7.subVectors( triangle.b, _center ); - _v2$3.subVectors( triangle.c, _center ); + _v2$4.subVectors( triangle.c, _center ); // compute edge vectors for triangle _f0.subVectors( _v1$7, _v0$2 ); - _f1.subVectors( _v2$3, _v1$7 ); - _f2.subVectors( _v0$2, _v2$3 ); + _f1.subVectors( _v2$4, _v1$7 ); + _f2.subVectors( _v0$2, _v2$4 ); // 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 @@ -5315,7 +5333,7 @@ class Box3 { _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 ]; - if ( ! satForAxes( axes, _v0$2, _v1$7, _v2$3, _extents ) ) { + if ( ! satForAxes( axes, _v0$2, _v1$7, _v2$4, _extents ) ) { return false; @@ -5323,7 +5341,7 @@ class Box3 { // test 3 face normals from the aabb axes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; - if ( ! satForAxes( axes, _v0$2, _v1$7, _v2$3, _extents ) ) { + if ( ! satForAxes( axes, _v0$2, _v1$7, _v2$4, _extents ) ) { return false; @@ -5334,7 +5352,7 @@ class Box3 { _triangleNormal.crossVectors( _f0, _f1 ); axes = [ _triangleNormal.x, _triangleNormal.y, _triangleNormal.z ]; - return satForAxes( axes, _v0$2, _v1$7, _v2$3, _extents ); + return satForAxes( axes, _v0$2, _v1$7, _v2$4, _extents ); } @@ -5440,7 +5458,7 @@ const _box$3 = /*@__PURE__*/ new Box3(); const _v0$2 = /*@__PURE__*/ new Vector3(); const _v1$7 = /*@__PURE__*/ new Vector3(); -const _v2$3 = /*@__PURE__*/ new Vector3(); +const _v2$4 = /*@__PURE__*/ new Vector3(); // triangle edge vectors @@ -5481,8 +5499,7 @@ function satForAxes( axes, v0, v1, v2, extents ) { const _box$2 = /*@__PURE__*/ new Box3(); const _v1$6 = /*@__PURE__*/ new Vector3(); -const _toFarthestPoint = /*@__PURE__*/ new Vector3(); -const _toPoint = /*@__PURE__*/ new Vector3(); +const _v2$3 = /*@__PURE__*/ new Vector3(); class Sphere { @@ -5639,23 +5656,31 @@ class Sphere { expandByPoint( point ) { - // from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L649-L671 + if ( this.isEmpty() ) { + + this.center.copy( point ); - _toPoint.subVectors( point, this.center ); + this.radius = 0; - const lengthSq = _toPoint.lengthSq(); + return this; + + } + + _v1$6.subVectors( point, this.center ); + + const lengthSq = _v1$6.lengthSq(); if ( lengthSq > ( this.radius * this.radius ) ) { + // calculate the minimal sphere + const length = Math.sqrt( lengthSq ); - const missingRadiusHalf = ( length - this.radius ) * 0.5; - // Nudge this sphere towards the target point. Add half the missing distance to radius, - // and the other half to position. This gives a tighter enclosure, instead of if - // the whole missing distance were just added to radius. + const delta = ( length - this.radius ) * 0.5; - this.center.add( _toPoint.multiplyScalar( missingRadiusHalf / length ) ); - this.radius += missingRadiusHalf; + this.center.addScaledVector( _v1$6, delta / length ); + + this.radius += delta; } @@ -5665,25 +5690,33 @@ class Sphere { union( sphere ) { - // from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L759-L769 + if ( sphere.isEmpty() ) { - // To enclose another sphere into this sphere, we only need to enclose two points: - // 1) Enclose the farthest point on the other sphere into this sphere. - // 2) Enclose the opposite point of the farthest point into this sphere. + return this; - if ( this.center.equals( sphere.center ) === true ) { + } + + if ( this.isEmpty() ) { + + this.copy( sphere ); + + return this; + + } - _toFarthestPoint.set( 0, 0, 1 ).multiplyScalar( sphere.radius ); + if ( this.center.equals( sphere.center ) === true ) { + this.radius = Math.max( this.radius, sphere.radius ); } else { - _toFarthestPoint.subVectors( sphere.center, this.center ).normalize().multiplyScalar( sphere.radius ); + _v2$3.subVectors( sphere.center, this.center ).setLength( sphere.radius ); - } + this.expandByPoint( _v1$6.copy( sphere.center ).add( _v2$3 ) ); + + this.expandByPoint( _v1$6.copy( sphere.center ).sub( _v2$3 ) ); - this.expandByPoint( _v1$6.copy( sphere.center ).add( _toFarthestPoint ) ); - this.expandByPoint( _v1$6.copy( sphere.center ).sub( _toFarthestPoint ) ); + } return this; @@ -6059,12 +6092,9 @@ class Ray { 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 ( tymin > tmin || isNaN( tmin ) ) tmin = tymin; - if ( tymax < tmax || tmax !== tmax ) tmax = tymax; + if ( tymax < tmax || isNaN( tmax ) ) tmax = tymax; if ( invdirz >= 0 ) { @@ -7523,6 +7553,8 @@ class Object3D extends EventDispatcher { this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate; this.matrixWorldNeedsUpdate = false; + this.matrixWorldAutoUpdate = Object3D.DefaultMatrixWorldAutoUpdate; // checked by the renderer + this.layers = new Layers(); this.visible = true; @@ -8007,7 +8039,13 @@ class Object3D extends EventDispatcher { for ( let i = 0, l = children.length; i < l; i ++ ) { - children[ i ].updateMatrixWorld( force ); + const child = children[ i ]; + + if ( child.matrixWorldAutoUpdate === true || force === true ) { + + child.updateMatrixWorld( force ); + + } } @@ -8017,7 +8055,7 @@ class Object3D extends EventDispatcher { const parent = this.parent; - if ( updateParents === true && parent !== null ) { + if ( updateParents === true && parent !== null && parent.matrixWorldAutoUpdate === true ) { parent.updateWorldMatrix( true, false ); @@ -8043,7 +8081,13 @@ class Object3D extends EventDispatcher { for ( let i = 0, l = children.length; i < l; i ++ ) { - children[ i ].updateWorldMatrix( false, true ); + const child = children[ i ]; + + if ( child.matrixWorldAutoUpdate === true ) { + + child.updateWorldMatrix( false, true ); + + } } @@ -8316,6 +8360,8 @@ class Object3D extends EventDispatcher { this.matrixAutoUpdate = source.matrixAutoUpdate; this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; + this.matrixWorldAutoUpdate = source.matrixWorldAutoUpdate; + this.layers.mask = source.layers.mask; this.visible = source.visible; @@ -8346,6 +8392,7 @@ class Object3D extends EventDispatcher { Object3D.DefaultUp = /*@__PURE__*/ new Vector3( 0, 1, 0 ); Object3D.DefaultMatrixAutoUpdate = true; +Object3D.DefaultMatrixWorldAutoUpdate = true; const _v0$1 = /*@__PURE__*/ new Vector3(); const _v1$3 = /*@__PURE__*/ new Vector3(); @@ -8763,15 +8810,6 @@ class Material extends EventDispatcher { } - // for backward compatibility if shading is set in the constructor - if ( key === 'shading' ) { - - console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); - this.flatShading = ( newValue === FlatShading ) ? true : false; - continue; - - } - const currentValue = this[ key ]; if ( currentValue === undefined ) { @@ -8950,7 +8988,7 @@ class Material extends EventDispatcher { if ( this.transmissionMap && this.transmissionMap.isTexture ) data.transmissionMap = this.transmissionMap.toJSON( meta ).uuid; if ( this.thickness !== undefined ) data.thickness = this.thickness; if ( this.thicknessMap && this.thicknessMap.isTexture ) data.thicknessMap = this.thicknessMap.toJSON( meta ).uuid; - if ( this.attenuationDistance !== undefined ) data.attenuationDistance = this.attenuationDistance; + if ( this.attenuationDistance !== undefined && this.attenuationDistance !== Infinity ) data.attenuationDistance = this.attenuationDistance; if ( this.attenuationColor !== undefined ) data.attenuationColor = this.attenuationColor.getHex(); if ( this.size !== undefined ) data.size = this.size; @@ -9298,110 +9336,6 @@ class BufferAttribute { } - copyColorsArray( colors ) { - - const array = this.array; - let offset = 0; - - for ( let i = 0, l = colors.length; i < l; i ++ ) { - - let color = colors[ i ]; - - if ( color === undefined ) { - - console.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i ); - color = new Color(); - - } - - array[ offset ++ ] = color.r; - array[ offset ++ ] = color.g; - array[ offset ++ ] = color.b; - - } - - return this; - - } - - copyVector2sArray( vectors ) { - - const array = this.array; - let offset = 0; - - for ( let i = 0, l = vectors.length; i < l; i ++ ) { - - let vector = vectors[ i ]; - - if ( vector === undefined ) { - - console.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i ); - vector = new Vector2(); - - } - - array[ offset ++ ] = vector.x; - array[ offset ++ ] = vector.y; - - } - - return this; - - } - - copyVector3sArray( vectors ) { - - const array = this.array; - let offset = 0; - - for ( let i = 0, l = vectors.length; i < l; i ++ ) { - - let vector = vectors[ i ]; - - 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; - - } - - return this; - - } - - copyVector4sArray( vectors ) { - - const array = this.array; - let offset = 0; - - for ( let i = 0, l = vectors.length; i < l; i ++ ) { - - let vector = vectors[ i ]; - - if ( vector === undefined ) { - - console.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i ); - vector = new Vector4(); - - } - - array[ offset ++ ] = vector.x; - array[ offset ++ ] = vector.y; - array[ offset ++ ] = vector.z; - array[ offset ++ ] = vector.w; - - } - - return this; - - } - applyMatrix3( m ) { if ( this.itemSize === 2 ) { @@ -9482,6 +9416,7 @@ class BufferAttribute { set( value, offset = 0 ) { + // Matching BufferAttribute constructor, do not normalize the array. this.array.set( value, offset ); return this; @@ -9490,12 +9425,18 @@ class BufferAttribute { getX( index ) { - return this.array[ index * this.itemSize ]; + let x = this.array[ index * this.itemSize ]; + + if ( this.normalized ) x = denormalize( x, this.array ); + + return x; } setX( index, x ) { + if ( this.normalized ) x = normalize( x, this.array ); + this.array[ index * this.itemSize ] = x; return this; @@ -9504,12 +9445,18 @@ class BufferAttribute { getY( index ) { - return this.array[ index * this.itemSize + 1 ]; + let y = this.array[ index * this.itemSize + 1 ]; + + if ( this.normalized ) y = denormalize( y, this.array ); + + return y; } setY( index, y ) { + if ( this.normalized ) y = normalize( y, this.array ); + this.array[ index * this.itemSize + 1 ] = y; return this; @@ -9518,12 +9465,18 @@ class BufferAttribute { getZ( index ) { - return this.array[ index * this.itemSize + 2 ]; + let z = this.array[ index * this.itemSize + 2 ]; + + if ( this.normalized ) z = denormalize( z, this.array ); + + return z; } setZ( index, z ) { + if ( this.normalized ) z = normalize( z, this.array ); + this.array[ index * this.itemSize + 2 ] = z; return this; @@ -9532,12 +9485,18 @@ class BufferAttribute { getW( index ) { - return this.array[ index * this.itemSize + 3 ]; + let w = this.array[ index * this.itemSize + 3 ]; + + if ( this.normalized ) w = denormalize( w, this.array ); + + return w; } setW( index, w ) { + if ( this.normalized ) w = normalize( w, this.array ); + this.array[ index * this.itemSize + 3 ] = w; return this; @@ -9548,6 +9507,13 @@ class BufferAttribute { index *= this.itemSize; + if ( this.normalized ) { + + x = normalize( x, this.array ); + y = normalize( y, this.array ); + + } + this.array[ index + 0 ] = x; this.array[ index + 1 ] = y; @@ -9559,6 +9525,14 @@ class BufferAttribute { index *= this.itemSize; + if ( this.normalized ) { + + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); + + } + this.array[ index + 0 ] = x; this.array[ index + 1 ] = y; this.array[ index + 2 ] = z; @@ -9571,6 +9545,15 @@ class BufferAttribute { index *= this.itemSize; + if ( this.normalized ) { + + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); + w = normalize( w, this.array ); + + } + this.array[ index + 0 ] = x; this.array[ index + 1 ] = y; this.array[ index + 2 ] = z; @@ -9611,6 +9594,32 @@ class BufferAttribute { } + // @deprecated + + copyColorsArray() { + + console.error( 'THREE.BufferAttribute: copyColorsArray() was removed in r144.' ); + + } + + copyVector2sArray() { + + console.error( 'THREE.BufferAttribute: copyVector2sArray() was removed in r144.' ); + + } + + copyVector3sArray() { + + console.error( 'THREE.BufferAttribute: copyVector3sArray() was removed in r144.' ); + + } + + copyVector4sArray() { + + console.error( 'THREE.BufferAttribute: copyVector4sArray() was removed in r144.' ); + + } + } // @@ -10434,49 +10443,11 @@ class BufferGeometry extends EventDispatcher { } - merge( geometry, offset ) { + // @deprecated since r144 - if ( ! ( geometry && geometry.isBufferGeometry ) ) { - - console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry ); - return; - - } - - if ( offset === undefined ) { - - offset = 0; - - console.warn( - 'THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. ' - + 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.' - ); - - } - - const attributes = this.attributes; - - for ( const key in attributes ) { - - if ( geometry.attributes[ key ] === undefined ) continue; - - const attribute1 = attributes[ key ]; - const attributeArray1 = attribute1.array; - - const attribute2 = geometry.attributes[ key ]; - const attributeArray2 = attribute2.array; - - const attributeOffset = attribute2.itemSize * offset; - const length = Math.min( attributeArray2.length, attributeArray1.length - attributeOffset ); - - for ( let i = 0, j = attributeOffset; i < length; i ++, j ++ ) { - - attributeArray1[ j ] = attributeArray2[ i ]; - - } - - } + merge() { + console.error( 'THREE.BufferGeometry.merge() has been removed. Use THREE.BufferGeometryUtils.mergeBufferGeometries() instead.' ); return this; } @@ -11460,6 +11431,19 @@ function cloneUniformsGroups( src ) { } +function getUnlitUniformColorSpace( renderer ) { + + if ( renderer.getRenderTarget() === null ) { + + // https://github.com/mrdoob/three.js/pull/23937#issuecomment-1111067398 + return renderer.outputEncoding === sRGBEncoding ? SRGBColorSpace : LinearSRGBColorSpace; + + } + + return LinearSRGBColorSpace; + +} + // Legacy const UniformsUtils = { clone: cloneUniforms, merge: mergeUniforms }; @@ -11516,12 +11500,6 @@ class ShaderMaterial extends Material { if ( parameters !== undefined ) { - if ( parameters.attributes !== undefined ) { - - console.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' ); - - } - this.setValues( parameters ); } @@ -11942,7 +11920,8 @@ class PerspectiveCamera extends Camera { } -const fov = 90, aspect = 1; +const fov = - 90; // negative fov is not an error +const aspect = 1; class CubeCamera extends Object3D { @@ -11952,49 +11931,42 @@ class CubeCamera extends Object3D { 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; const cameraPX = new PerspectiveCamera( fov, aspect, near, far ); cameraPX.layers = this.layers; - cameraPX.up.set( 0, - 1, 0 ); - cameraPX.lookAt( new Vector3( 1, 0, 0 ) ); + cameraPX.up.set( 0, 1, 0 ); + cameraPX.lookAt( 1, 0, 0 ); this.add( cameraPX ); const cameraNX = new PerspectiveCamera( fov, aspect, near, far ); cameraNX.layers = this.layers; - cameraNX.up.set( 0, - 1, 0 ); - cameraNX.lookAt( new Vector3( - 1, 0, 0 ) ); + cameraNX.up.set( 0, 1, 0 ); + cameraNX.lookAt( - 1, 0, 0 ); this.add( cameraNX ); const cameraPY = new PerspectiveCamera( fov, aspect, near, far ); cameraPY.layers = this.layers; - cameraPY.up.set( 0, 0, 1 ); - cameraPY.lookAt( new Vector3( 0, 1, 0 ) ); + cameraPY.up.set( 0, 0, - 1 ); + cameraPY.lookAt( 0, 1, 0 ); this.add( cameraPY ); const cameraNY = new PerspectiveCamera( fov, aspect, near, far ); cameraNY.layers = this.layers; - cameraNY.up.set( 0, 0, - 1 ); - cameraNY.lookAt( new Vector3( 0, - 1, 0 ) ); + cameraNY.up.set( 0, 0, 1 ); + cameraNY.lookAt( 0, - 1, 0 ); this.add( cameraNY ); const cameraPZ = new PerspectiveCamera( fov, aspect, near, far ); cameraPZ.layers = this.layers; - cameraPZ.up.set( 0, - 1, 0 ); - cameraPZ.lookAt( new Vector3( 0, 0, 1 ) ); + cameraPZ.up.set( 0, 1, 0 ); + cameraPZ.lookAt( 0, 0, 1 ); this.add( cameraPZ ); const cameraNZ = new PerspectiveCamera( fov, aspect, near, far ); cameraNZ.layers = this.layers; - cameraNZ.up.set( 0, - 1, 0 ); - cameraNZ.lookAt( new Vector3( 0, 0, - 1 ) ); + cameraNZ.up.set( 0, 1, 0 ); + cameraNZ.lookAt( 0, 0, - 1 ); this.add( cameraNZ ); } @@ -12081,7 +12053,7 @@ class CubeTexture extends Texture { class WebGLCubeRenderTarget extends WebGLRenderTarget { - constructor( size, options = {} ) { + constructor( size = 1, options = {} ) { super( size, size, options ); @@ -12738,6 +12710,8 @@ function WebGLAttributes( gl, capabilities ) { } + attribute.onUploadCallback(); + } // @@ -12939,7 +12913,7 @@ var color_vertex = "#if defined( USE_COLOR_ALPHA )\n\tvColor = vec4( 1.0 );\n#el 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; }\nvec3 pow2( const in vec3 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 max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\nfloat average( const in vec3 v ) { return dot( v, vec3( 0.3333333 ) ); }\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 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 USE_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}\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 luminance( const in vec3 rgb ) {\n\tconst vec3 weights = vec3( 0.2126729, 0.7151522, 0.0721750 );\n\treturn dot( weights, 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}"; -var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_minMipLevel 4.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\tvec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\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\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\n\t\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n\t\tuv.x *= CUBEUV_TEXEL_WIDTH;\n\t\tuv.y *= CUBEUV_TEXEL_HEIGHT;\n\t\t#ifdef texture2DGradEXT\n\t\t\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n\t\t#else\n\t\t\treturn texture2D( envMap, uv ).rgb;\n\t\t#endif\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_MAX_MIP );\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 cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_minMipLevel 4.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\tvec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\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\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\n\t\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n\t\tuv.x *= CUBEUV_TEXEL_WIDTH;\n\t\tuv.y *= CUBEUV_TEXEL_HEIGHT;\n\t\t#ifdef texture2DGradEXT\n\t\t\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n\t\t#else\n\t\t\treturn texture2D( envMap, uv ).rgb;\n\t\t#endif\n\t}\n\t#define cubeUV_r0 1.0\n\t#define cubeUV_v0 0.339\n\t#define cubeUV_m0 - 2.0\n\t#define cubeUV_r1 0.8\n\t#define cubeUV_v1 0.276\n\t#define cubeUV_m1 - 1.0\n\t#define cubeUV_r4 0.4\n\t#define cubeUV_v4 0.046\n\t#define cubeUV_m4 2.0\n\t#define cubeUV_r5 0.305\n\t#define cubeUV_v5 0.016\n\t#define cubeUV_m5 3.0\n\t#define cubeUV_r6 0.21\n\t#define cubeUV_v6 0.0038\n\t#define cubeUV_m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= cubeUV_r1 ) {\n\t\t\tmip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0;\n\t\t} else if ( roughness >= cubeUV_r4 ) {\n\t\t\tmip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1;\n\t\t} else if ( roughness >= cubeUV_r5 ) {\n\t\t\tmip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4;\n\t\t} else if ( roughness >= cubeUV_r6 ) {\n\t\t\tmip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_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 ), cubeUV_m0, CUBEUV_MAX_MIP );\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"; @@ -12955,13 +12929,13 @@ var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );"; var encodings_pars_fragment = "vec4 LinearToLinear( in vec4 value ) {\n\treturn value;\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}"; -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#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_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#else\n\t\tvec4 envColor = vec4( 0.0 );\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\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"; -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"; +var envmap_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\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"; -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"; +var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\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"; 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"; @@ -12973,13 +12947,15 @@ var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float vFogDepth;\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"; -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 vec3( texture2D( gradientMap, coord ).r );\n\t#else\n\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t#endif\n}"; +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 vec3( texture2D( gradientMap, coord ).r );\n\t#else\n\t\tvec2 fw = fwidth( coord ) * 0.5;\n\t\treturn mix( vec3( 0.7 ), vec3( 1.0 ), smoothstep( 0.7 - fw.x, 0.7 + fw.x, coord.x ) );\n\t#endif\n}"; var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\treflectedLight.indirectDiffuse += lightMapIrradiance;\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.normal );\n#ifdef DOUBLE_SIDED\n\tvIndirectBack += getAmbientLightIrradiance( ambientLightColor );\n\tvIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry.normal );\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\tgetPointLightInfo( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = 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\tgetSpotLightInfo( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = 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\tgetDirectionalLightInfo( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = 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.normal );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry.normal );\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif"; +var lights_lambert_fragment = "LambertMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularStrength = specularStrength;"; + +var lights_lambert_pars_fragment = "varying vec3 vViewPosition;\nstruct LambertMaterial {\n\tvec3 diffuseColor;\n\tfloat specularStrength;\n};\nvoid RE_Direct_Lambert( const in IncidentLight directLight, const in GeometricContext geometry, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in GeometricContext geometry, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Lambert\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Lambert"; 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 vec3 normal ) {\n\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\treturn irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\t#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\tif ( cutoffDistance > 0.0 ) {\n\t\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\t}\n\t\treturn distanceFalloff;\n\t#else\n\t\tif ( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\t\treturn pow( saturate( - lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t\t}\n\t\treturn 1.0;\n\t#endif\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n\treturn smoothstep( coneCosine, penumbraCosine, angleCosine );\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 getDirectionalLightInfo( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tlight.color = directionalLight.color;\n\t\tlight.direction = directionalLight.direction;\n\t\tlight.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 getPointLightInfo( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tlight.color = pointLight.color;\n\t\tlight.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n\t\tlight.visible = ( light.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 getSpotLightInfo( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat angleCos = dot( light.direction, spotLight.direction );\n\t\tfloat spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\tif ( spotAttenuation > 0.0 ) {\n\t\t\tfloat lightDistance = length( lVector );\n\t\t\tlight.color = spotLight.color * spotAttenuation;\n\t\t\tlight.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t\t} else {\n\t\t\tlight.color = vec3( 0.0 );\n\t\t\tlight.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 vec3 normal ) {\n\t\tfloat dotNL = dot( normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\treturn irradiance;\n\t}\n#endif"; @@ -12987,17 +12963,17 @@ var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP )\n\tvec3 getIBLIrr var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;"; -var lights_toon_pars_fragment = "varying vec3 vViewPosition;\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\treflectedLight.directDiffuse += irradiance * BRDF_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_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)"; +var lights_toon_pars_fragment = "varying vec3 vViewPosition;\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\treflectedLight.directDiffuse += irradiance * BRDF_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_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon"; 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;\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\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, 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_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)"; +var lights_phong_pars_fragment = "varying vec3 vViewPosition;\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\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, 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_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong"; -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.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\t#ifdef SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULARINTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vUv ).a;\n\t\t#endif\n\t\t#ifdef USE_SPECULARCOLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vUv ).rgb;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( ior - 1.0 ) / ( ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\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_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vUv ).a;\n\t#endif\n#endif"; +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.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\tmaterial.ior = ior;\n\t#ifdef SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULARINTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vUv ).a;\n\t\t#endif\n\t\t#ifdef USE_SPECULARCOLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vUv ).rgb;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\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_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vUv ).a;\n\t#endif\n#endif"; -var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat roughness;\n\tvec3 specularColor;\n\tfloat specularF90;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\tfloat iridescence;\n\t\tfloat iridescenceIOR;\n\t\tfloat iridescenceThickness;\n\t\tvec3 iridescenceFresnel;\n\t\tvec3 iridescenceF0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n};\nvec3 clearcoatSpecular = vec3( 0.0 );\nvec3 sheenSpecular = vec3( 0.0 );\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\n\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\n\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\n\treturn saturate( DG * RECIPROCAL_PI );\n}\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\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\tvec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\n\treturn fab;\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\treturn specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#endif\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\t#ifdef USE_IRIDESCENCE\n\t\tvec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n\t#else\n\t\tvec3 Fr = specularColor;\n\t#endif\n\tvec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\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.roughness;\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#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecular += ccIrradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.clearcoatNormal, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness );\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\treflectedLight.directSpecular += irradiance * BRDF_GGX_Iridescence( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness );\n\t#else\n\t\treflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.roughness );\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_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_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 USE_CLEARCOAT\n\t\tclearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometry.clearcoatNormal, geometry.viewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometry.normal, geometry.viewDir, material.sheenRoughness );\n\t#endif\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t#ifdef USE_IRIDESCENCE\n\t\tcomputeMultiscatteringIridescence( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );\n\t#else\n\t\tcomputeMultiscattering( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n\t#endif\n\tvec3 totalScattering = singleScattering + multiScattering;\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) );\n\treflectedLight.indirectSpecular += 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}"; +var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat roughness;\n\tvec3 specularColor;\n\tfloat specularF90;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\tfloat iridescence;\n\t\tfloat iridescenceIOR;\n\t\tfloat iridescenceThickness;\n\t\tvec3 iridescenceFresnel;\n\t\tvec3 iridescenceF0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n\t#ifdef IOR\n\t\tfloat ior;\n\t#endif\n\t#ifdef USE_TRANSMISSION\n\t\tfloat transmission;\n\t\tfloat transmissionAlpha;\n\t\tfloat thickness;\n\t\tfloat attenuationDistance;\n\t\tvec3 attenuationColor;\n\t#endif\n};\nvec3 clearcoatSpecular = vec3( 0.0 );\nvec3 sheenSpecular = vec3( 0.0 );\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\n\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\n\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\n\treturn saturate( DG * RECIPROCAL_PI );\n}\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\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\tvec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\n\treturn fab;\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\treturn specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#endif\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\t#ifdef USE_IRIDESCENCE\n\t\tvec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n\t#else\n\t\tvec3 Fr = specularColor;\n\t#endif\n\tvec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\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.roughness;\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#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecular += ccIrradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.clearcoatNormal, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness );\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\treflectedLight.directSpecular += irradiance * BRDF_GGX_Iridescence( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness );\n\t#else\n\t\treflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.roughness );\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_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_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 USE_CLEARCOAT\n\t\tclearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometry.clearcoatNormal, geometry.viewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometry.normal, geometry.viewDir, material.sheenRoughness );\n\t#endif\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t#ifdef USE_IRIDESCENCE\n\t\tcomputeMultiscatteringIridescence( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );\n\t#else\n\t\tcomputeMultiscattering( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n\t#endif\n\tvec3 totalScattering = singleScattering + multiScattering;\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) );\n\treflectedLight.indirectSpecular += 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}"; -var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef USE_CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n\tfloat dotNVi = saturate( dot( normal, geometry.viewDir ) );\n\tif ( material.iridescenceThickness == 0.0 ) {\n\t\tmaterial.iridescence = 0.0;\n\t} else {\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\t}\n\tif ( material.iridescence > 0.0 ) {\n\t\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\t}\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\tgetPointLightInfo( 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\tgetSpotLightInfo( 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\tgetDirectionalLightInfo( 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.normal );\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.normal );\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 lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef USE_CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n\tfloat dotNVi = saturate( dot( normal, geometry.viewDir ) );\n\tif ( material.iridescenceThickness == 0.0 ) {\n\t\tmaterial.iridescence = 0.0;\n\t} else {\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\t}\n\tif ( material.iridescence > 0.0 ) {\n\t\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\t}\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\tgetPointLightInfo( 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\tvec4 spotColor;\n\tvec3 spotLightCoord;\n\tbool inSpotLightMap;\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\tgetSpotLightInfo( spotLight, geometry, directLight );\n\t\t#if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n\t\t#elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t#define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n\t\t#else\n\t\t#define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#endif\n\t\t#if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n\t\t\tspotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n\t\t\tinSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n\t\t\tspotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n\t\t\tdirectLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n\t\t#endif\n\t\t#undef SPOT_LIGHT_MAP_INDEX\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, vSpotLightCoord[ 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\tgetDirectionalLightInfo( 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.normal );\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.normal );\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 lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\t\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getIBLIrradiance( geometry.normal );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getIBLRadiance( geometry.viewDir, geometry.normal, material.roughness );\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatRadiance += getIBLRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness );\n\t#endif\n#endif"; @@ -13031,7 +13007,7 @@ var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\tuniform float morphTar var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\t#ifdef MORPHTARGETS_TEXTURE\n\t\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ];\n\t\t}\n\t#else\n\t\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\n\t\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\n\t\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\n\t\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\n\t\t#ifndef USE_MORPHNORMALS\n\t\t\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\n\t\t\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\n\t\t\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\n\t\t\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\n\t\t#endif\n\t#endif\n#endif"; -var normal_fragment_begin = "float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#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 * faceDirection;\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 * faceDirection;\n\t\t\tbitangent = bitangent * faceDirection;\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_begin = "float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#ifdef FLAT_SHADED\n\tvec3 fdx = dFdx( vViewPosition );\n\tvec3 fdy = dFdy( vViewPosition );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * faceDirection;\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 * faceDirection;\n\t\t\tbitangent = bitangent * faceDirection;\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 * faceDirection;\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, faceDirection );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\n#endif"; @@ -13051,9 +13027,9 @@ var clearcoat_pars_fragment = "#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clea var iridescence_pars_fragment = "#ifdef USE_IRIDESCENCEMAP\n\tuniform sampler2D iridescenceMap;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform sampler2D iridescenceThicknessMap;\n#endif"; -var output_fragment = "#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= transmissionAlpha + 0.1;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );"; +var output_fragment = "#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= material.transmissionAlpha + 0.1;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.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 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}\nvec2 packDepthToRG( in highp float v ) {\n\treturn packDepthToRGBA( v ).yx;\n}\nfloat unpackRGToDepth( const in highp vec2 v ) {\n\treturn unpackRGBAToDepth( vec4( v.xy, 0.0, 0.0 ) );\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"; @@ -13067,13 +13043,13 @@ var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUG var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; -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"; +var shadowmap_pars_fragment = "#if NUM_SPOT_LIGHT_COORDS > 0\n varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#if NUM_SPOT_LIGHT_MAPS > 0\n uniform sampler2D spotLightMap[ NUM_SPOT_LIGHT_MAPS ];\n#endif\n#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\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"; -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"; +var shadowmap_pars_vertex = "#if NUM_SPOT_LIGHT_COORDS > 0\n uniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#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\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"; -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 shadowmap_vertex = "#if defined( USE_SHADOWMAP ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n\t#if NUM_DIR_LIGHT_SHADOWS > 0 || NUM_SPOT_LIGHT_COORDS > 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_COORDS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition;\n\t\t#if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\tshadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias;\n\t\t#endif\n\t\tvSpotLightCoord[ i ] = spotLightMatrix[ 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}"; +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, vSpotLightCoord[ 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}"; 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"; @@ -13091,9 +13067,9 @@ var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = to 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; }"; -var transmission_fragment = "#ifdef USE_TRANSMISSION\n\tfloat transmissionAlpha = 1.0;\n\tfloat transmissionFactor = transmission;\n\tfloat thicknessFactor = thickness;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\ttransmissionFactor *= texture2D( transmissionMap, vUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tthicknessFactor *= texture2D( thicknessMap, vUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmission = getIBLVolumeRefraction(\n\t\tn, v, roughnessFactor, material.diffuseColor, material.specularColor, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, ior, thicknessFactor,\n\t\tattenuationColor, attenuationDistance );\n\ttotalDiffuse = mix( totalDiffuse, transmission.rgb, transmissionFactor );\n\ttransmissionAlpha = mix( transmissionAlpha, transmission.a, transmissionFactor );\n#endif"; +var transmission_fragment = "#ifdef USE_TRANSMISSION\n\tmaterial.transmission = transmission;\n\tmaterial.transmissionAlpha = 1.0;\n\tmaterial.thickness = thickness;\n\tmaterial.attenuationDistance = attenuationDistance;\n\tmaterial.attenuationColor = attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tmaterial.transmission *= texture2D( transmissionMap, vUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tmaterial.thickness *= texture2D( thicknessMap, vUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmission = getIBLVolumeRefraction(\n\t\tn, v, material.roughness, material.diffuseColor, material.specularColor, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, material.ior, material.thickness,\n\t\tmaterial.attenuationColor, material.attenuationDistance );\n\tmaterial.transmissionAlpha = mix( material.transmissionAlpha, transmission.a, material.transmission );\n\ttotalDiffuse = mix( totalDiffuse, transmission.rgb, material.transmission );\n#endif"; -var transmission_pars_fragment = "#ifdef USE_TRANSMISSION\n\tuniform float transmission;\n\tuniform float thickness;\n\tuniform float attenuationDistance;\n\tuniform vec3 attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tuniform sampler2D transmissionMap;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tuniform sampler2D thicknessMap;\n\t#endif\n\tuniform vec2 transmissionSamplerSize;\n\tuniform sampler2D transmissionSamplerMap;\n\tuniform mat4 modelMatrix;\n\tuniform mat4 projectionMatrix;\n\tvarying vec3 vWorldPosition;\n\tvec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\n\t\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n\t\tvec3 modelScale;\n\t\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\treturn normalize( refractionVector ) * thickness * modelScale;\n\t}\n\tfloat applyIorToRoughness( const in float roughness, const in float ior ) {\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t}\n\tvec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\n\t\tfloat framebufferLod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n\t\t#ifdef texture2DLodEXT\n\t\t\treturn texture2DLodEXT( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#else\n\t\t\treturn texture2D( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#endif\n\t}\n\tvec3 applyVolumeAttenuation( const in vec3 radiance, const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tif ( attenuationDistance == 0.0 ) {\n\t\t\treturn radiance;\n\t\t} else {\n\t\t\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n\t\t\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\t\t\treturn transmittance * radiance;\n\t\t}\n\t}\n\tvec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\n\t\tconst in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\n\t\tconst in mat4 viewMatrix, const in mat4 projMatrix, const in float ior, const in float thickness,\n\t\tconst in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\trefractionCoords += 1.0;\n\t\trefractionCoords /= 2.0;\n\t\tvec4 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n\t\tvec3 attenuatedColor = applyVolumeAttenuation( transmittedLight.rgb, length( transmissionRay ), attenuationColor, attenuationDistance );\n\t\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n\t\treturn vec4( ( 1.0 - F ) * attenuatedColor * diffuseColor, transmittedLight.a );\n\t}\n#endif"; +var transmission_pars_fragment = "#ifdef USE_TRANSMISSION\n\tuniform float transmission;\n\tuniform float thickness;\n\tuniform float attenuationDistance;\n\tuniform vec3 attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tuniform sampler2D transmissionMap;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tuniform sampler2D thicknessMap;\n\t#endif\n\tuniform vec2 transmissionSamplerSize;\n\tuniform sampler2D transmissionSamplerMap;\n\tuniform mat4 modelMatrix;\n\tuniform mat4 projectionMatrix;\n\tvarying vec3 vWorldPosition;\n\tvec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\n\t\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n\t\tvec3 modelScale;\n\t\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\treturn normalize( refractionVector ) * thickness * modelScale;\n\t}\n\tfloat applyIorToRoughness( const in float roughness, const in float ior ) {\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t}\n\tvec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\n\t\tfloat framebufferLod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n\t\t#ifdef texture2DLodEXT\n\t\t\treturn texture2DLodEXT( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#else\n\t\t\treturn texture2D( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#endif\n\t}\n\tvec3 applyVolumeAttenuation( const in vec3 radiance, const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tif ( isinf( attenuationDistance ) ) {\n\t\t\treturn radiance;\n\t\t} else {\n\t\t\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n\t\t\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\t\t\treturn transmittance * radiance;\n\t\t}\n\t}\n\tvec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\n\t\tconst in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\n\t\tconst in mat4 viewMatrix, const in mat4 projMatrix, const in float ior, const in float thickness,\n\t\tconst in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\trefractionCoords += 1.0;\n\t\trefractionCoords /= 2.0;\n\t\tvec4 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n\t\tvec3 attenuatedColor = applyVolumeAttenuation( transmittedLight.rgb, length( transmissionRay ), attenuationColor, attenuationDistance );\n\t\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n\t\treturn vec4( ( 1.0 - F ) * attenuatedColor * diffuseColor, transmittedLight.a );\n\t}\n#endif"; var uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif"; @@ -13107,15 +13083,19 @@ var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tat var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif"; -var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION )\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 worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) || NUM_SPOT_LIGHT_COORDS > 0\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"; -const vertex$g = "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}"; +const vertex$h = "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}"; -const fragment$g = "uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tgl_FragColor = texture2D( t2D, vUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\tgl_FragColor = vec4( mix( pow( gl_FragColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), gl_FragColor.rgb * 0.0773993808, vec3( lessThanEqual( gl_FragColor.rgb, vec3( 0.04045 ) ) ) ), gl_FragColor.w );\n\t#endif\n\t#include \n\t#include \n}"; +const fragment$h = "uniform sampler2D t2D;\nuniform float backgroundIntensity;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\ttexColor = vec4( mix( pow( texColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), texColor.rgb * 0.0773993808, vec3( lessThanEqual( texColor.rgb, vec3( 0.04045 ) ) ) ), texColor.w );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include \n\t#include \n}"; + +const vertex$g = "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}"; + +const fragment$g = "#ifdef ENVMAP_TYPE_CUBE\n\tuniform samplerCube envMap;\n#elif defined( ENVMAP_TYPE_CUBE_UV )\n\tuniform sampler2D envMap;\n#endif\nuniform float flipEnvMap;\nuniform float backgroundBlurriness;\nuniform float backgroundIntensity;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 texColor = textureCube( envMap, vec3( flipEnvMap * vWorldDirection.x, vWorldDirection.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 texColor = textureCubeUV( envMap, vWorldDirection, backgroundBlurriness );\n\t#else\n\t\tvec4 texColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include \n\t#include \n}"; const vertex$f = "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}"; -const fragment$f = "#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}"; +const fragment$f = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = texColor;\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}"; const vertex$e = "#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}"; @@ -13135,11 +13115,11 @@ const fragment$b = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float const vertex$a = "#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#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\t\t#include \n\t\t#include \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\t#include \n\t#include \n}"; -const fragment$a = "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 \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\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; +const fragment$a = "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\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; -const vertex$9 = "#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\t#include \n}"; +const vertex$9 = "#define LAMBERT\nvarying vec3 vViewPosition;\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\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}"; -const fragment$9 = "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 \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_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_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; +const fragment$9 = "#define LAMBERT\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 \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 + totalEmissiveRadiance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; const vertex$8 = "#define MATCAP\nvarying vec3 vViewPosition;\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\tvViewPosition = - mvPosition.xyz;\n}"; @@ -13151,7 +13131,7 @@ const fragment$7 = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SH const vertex$6 = "#define PHONG\nvarying vec3 vViewPosition;\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\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}"; -const fragment$6 = "#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 \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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; +const fragment$6 = "#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 \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\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; const vertex$5 = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n\tvarying vec3 vWorldPosition;\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\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\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n#ifdef USE_TRANSMISSION\n\tvWorldPosition = worldPosition.xyz;\n#endif\n}"; @@ -13215,7 +13195,8 @@ const ShaderChunk = { gradientmap_pars_fragment: gradientmap_pars_fragment, lightmap_fragment: lightmap_fragment, lightmap_pars_fragment: lightmap_pars_fragment, - lights_lambert_vertex: lights_lambert_vertex, + lights_lambert_fragment: lights_lambert_fragment, + lights_lambert_pars_fragment: lights_lambert_pars_fragment, lights_pars_begin: lights_pars_begin, lights_toon_fragment: lights_toon_fragment, lights_toon_pars_fragment: lights_toon_pars_fragment, @@ -13280,8 +13261,10 @@ const ShaderChunk = { uv2_vertex: uv2_vertex, worldpos_vertex: worldpos_vertex, - background_vert: vertex$g, - background_frag: fragment$g, + background_vert: vertex$h, + background_frag: fragment$h, + backgroundCube_vert: vertex$g, + backgroundCube_frag: fragment$g, cube_vert: vertex$f, cube_frag: fragment$f, depth_vert: vertex$e, @@ -13346,7 +13329,7 @@ const UniformsLib = { flipEnvMap: { value: - 1 }, reflectivity: { value: 1.0 }, // basic, lambert, phong ior: { value: 1.5 }, // physical - refractionRatio: { value: 0.98 } // basic, lambert, phong + refractionRatio: { value: 0.98 }, // basic, lambert, phong }, @@ -13457,8 +13440,9 @@ const UniformsLib = { shadowMapSize: {} } }, + spotLightMap: { value: [] }, spotShadowMap: { value: [] }, - spotShadowMatrix: { value: [] }, + spotLightMatrix: { value: [] }, pointLights: { value: [], properties: { color: {}, @@ -13553,6 +13537,9 @@ const ShaderLib = { UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, UniformsLib.fog, UniformsLib.lights, { @@ -13735,6 +13722,7 @@ const ShaderLib = { uniforms: { uvTransform: { value: /*@__PURE__*/ new Matrix3() }, t2D: { value: null }, + backgroundIntensity: { value: 1 } }, vertexShader: ShaderChunk.background_vert, @@ -13742,14 +13730,27 @@ const ShaderLib = { }, + backgroundCube: { + + uniforms: { + envMap: { value: null }, + flipEnvMap: { value: - 1 }, + backgroundBlurriness: { value: 0 }, + backgroundIntensity: { value: 1 } + }, + + vertexShader: ShaderChunk.backgroundCube_vert, + fragmentShader: ShaderChunk.backgroundCube_frag + + }, + cube: { - uniforms: /*@__PURE__*/ mergeUniforms( [ - UniformsLib.envmap, - { - opacity: { value: 1.0 } - } - ] ), + uniforms: { + tCube: { value: null }, + tFlip: { value: - 1 }, + opacity: { value: 1.0 } + }, vertexShader: ShaderChunk.cube_vert, fragmentShader: ShaderChunk.cube_frag @@ -13844,7 +13845,9 @@ ShaderLib.physical = { }; -function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipliedAlpha ) { +const _rgb = { r: 0, b: 0, g: 0 }; + +function WebGLBackground( renderer, cubemaps, cubeuvmaps, state, objects, alpha, premultipliedAlpha ) { const clearColor = new Color( 0x000000 ); let clearAlpha = alpha === true ? 0 : 1; @@ -13863,7 +13866,8 @@ function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipli if ( background && background.isTexture ) { - background = cubemaps.get( background ); + const usePMREM = scene.backgroundBlurriness > 0; // use PMREM if the user wants to blur the background + background = ( usePMREM ? cubeuvmaps : cubemaps ).get( background ); } @@ -13904,9 +13908,9 @@ function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipli new BoxGeometry( 1, 1, 1 ), new ShaderMaterial( { name: 'BackgroundCubeMaterial', - uniforms: cloneUniforms( ShaderLib.cube.uniforms ), - vertexShader: ShaderLib.cube.vertexShader, - fragmentShader: ShaderLib.cube.fragmentShader, + uniforms: cloneUniforms( ShaderLib.backgroundCube.uniforms ), + vertexShader: ShaderLib.backgroundCube.vertexShader, + fragmentShader: ShaderLib.backgroundCube.fragmentShader, side: BackSide, depthTest: false, depthWrite: false, @@ -13923,7 +13927,7 @@ function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipli }; - // enable code injection for non-built-in material + // add "envMap" material property so the renderer can evaluate it like for built-in materials Object.defineProperty( boxMesh.material, 'envMap', { get: function () { @@ -13940,6 +13944,8 @@ function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipli boxMesh.material.uniforms.envMap.value = background; boxMesh.material.uniforms.flipEnvMap.value = ( background.isCubeTexture && background.isRenderTargetTexture === false ) ? - 1 : 1; + boxMesh.material.uniforms.backgroundBlurriness.value = scene.backgroundBlurriness; + boxMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity; if ( currentBackground !== background || currentBackgroundVersion !== background.version || @@ -13978,7 +13984,7 @@ function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipli planeMesh.geometry.deleteAttribute( 'normal' ); - // enable code injection for non-built-in material + // add "map" material property so the renderer can evaluate it like for built-in materials Object.defineProperty( planeMesh.material, 'map', { get: function () { @@ -13994,6 +14000,7 @@ function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipli } planeMesh.material.uniforms.t2D.value = background; + planeMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity; if ( background.matrixAutoUpdate === true ) { @@ -14026,7 +14033,9 @@ function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipli function setClear( color, alpha ) { - state.buffers.color.setClear( color.r, color.g, color.b, alpha, premultipliedAlpha ); + color.getRGB( _rgb, getUnlitUniformColorSpace( renderer ) ); + + state.buffers.color.setClear( _rgb.r, _rgb.g, _rgb.b, alpha, premultipliedAlpha ); } @@ -16685,22 +16694,6 @@ function absNumericalSort( a, b ) { } -function denormalize( morph, attribute ) { - - let denominator = 1; - const array = attribute.isInterleavedBufferAttribute ? attribute.data.array : attribute.array; - - if ( array instanceof Int8Array ) denominator = 127; - else if ( array instanceof Uint8Array ) denominator = 255; - else if ( array instanceof Uint16Array ) denominator = 65535; - else if ( array instanceof Int16Array ) denominator = 32767; - else if ( array instanceof Int32Array ) denominator = 2147483647; - else console.error( 'THREE.WebGLMorphtargets: Unsupported morph attribute data type: ', array ); - - morph.divideScalar( denominator ); - -} - function WebGLMorphtargets( gl, capabilities, textures ) { const influencesList = {}; @@ -16784,8 +16777,6 @@ function WebGLMorphtargets( gl, capabilities, textures ) { morph.fromBufferAttribute( morphTarget, j ); - if ( morphTarget.normalized === true ) denormalize( morph, morphTarget ); - buffer[ offset + stride + 0 ] = morph.x; buffer[ offset + stride + 1 ] = morph.y; buffer[ offset + stride + 2 ] = morph.z; @@ -16797,8 +16788,6 @@ function WebGLMorphtargets( gl, capabilities, textures ) { morph.fromBufferAttribute( morphNormal, j ); - if ( morphNormal.normalized === true ) denormalize( morph, morphNormal ); - buffer[ offset + stride + 4 ] = morph.x; buffer[ offset + stride + 5 ] = morph.y; buffer[ offset + stride + 6 ] = morph.z; @@ -16810,8 +16799,6 @@ function WebGLMorphtargets( gl, capabilities, textures ) { morph.fromBufferAttribute( morphColor, j ); - if ( morphColor.normalized === true ) denormalize( morph, morphColor ); - buffer[ offset + stride + 8 ] = morph.x; buffer[ offset + stride + 9 ] = morph.y; buffer[ offset + stride + 10 ] = morph.z; @@ -17417,17 +17404,32 @@ function setValueV1i( gl, v ) { } -// Single integer / boolean vector (from flat array) +// Single integer / boolean vector (from flat array or THREE.VectorN) function setValueV2i( gl, v ) { const cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( v.x !== undefined ) { - gl.uniform2iv( this.addr, v ); + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y ) { + + gl.uniform2i( this.addr, v.x, v.y ); - copyArray( cache, v ); + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; + + } + + } else { + + if ( arraysEqual( cache, v ) ) return; + + gl.uniform2iv( this.addr, v ); + + copyArray( cache, v ); + + } } @@ -17435,11 +17437,27 @@ function setValueV3i( gl, v ) { const cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( v.x !== undefined ) { + + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z ) { + + gl.uniform3i( this.addr, v.x, v.y, v.z ); - gl.uniform3iv( this.addr, v ); + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; + cache[ 2 ] = v.z; + + } + + } else { + + if ( arraysEqual( cache, v ) ) return; - copyArray( cache, v ); + gl.uniform3iv( this.addr, v ); + + copyArray( cache, v ); + + } } @@ -17447,11 +17465,28 @@ function setValueV4i( gl, v ) { const cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( v.x !== undefined ) { - gl.uniform4iv( this.addr, v ); + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z || cache[ 3 ] !== v.w ) { - copyArray( cache, v ); + gl.uniform4i( 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.uniform4iv( this.addr, v ); + + copyArray( cache, v ); + + } } @@ -17469,17 +17504,32 @@ function setValueV1ui( gl, v ) { } -// Single unsigned integer vector (from flat array) +// Single unsigned integer vector (from flat array or THREE.VectorN) function setValueV2ui( gl, v ) { const cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( v.x !== undefined ) { - gl.uniform2uiv( this.addr, v ); + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y ) { + + gl.uniform2ui( this.addr, v.x, v.y ); - copyArray( cache, v ); + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; + + } + + } else { + + if ( arraysEqual( cache, v ) ) return; + + gl.uniform2uiv( this.addr, v ); + + copyArray( cache, v ); + + } } @@ -17487,11 +17537,27 @@ function setValueV3ui( gl, v ) { const cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( v.x !== undefined ) { - gl.uniform3uiv( this.addr, v ); + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z ) { + + gl.uniform3ui( this.addr, v.x, v.y, v.z ); + + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; + cache[ 2 ] = v.z; + + } + + } else { + + if ( arraysEqual( cache, v ) ) return; + + gl.uniform3uiv( this.addr, v ); - copyArray( cache, v ); + copyArray( cache, v ); + + } } @@ -17499,11 +17565,28 @@ function setValueV4ui( gl, v ) { const cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( v.x !== undefined ) { - gl.uniform4uiv( this.addr, v ); + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z || cache[ 3 ] !== v.w ) { + + gl.uniform4ui( 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; - copyArray( cache, v ); + gl.uniform4uiv( this.addr, v ); + + copyArray( cache, v ); + + } } @@ -17749,11 +17832,19 @@ function setValueV4uiArray( gl, v ) { function setValueT1Array( gl, v, textures ) { + const cache = this.cache; + const n = v.length; const units = allocTexUnits( textures, n ); - gl.uniform1iv( this.addr, units ); + if ( ! arraysEqual( cache, units ) ) { + + gl.uniform1iv( this.addr, units ); + + copyArray( cache, units ); + + } for ( let i = 0; i !== n; ++ i ) { @@ -17765,11 +17856,19 @@ function setValueT1Array( gl, v, textures ) { function setValueT3DArray( gl, v, textures ) { + const cache = this.cache; + const n = v.length; const units = allocTexUnits( textures, n ); - gl.uniform1iv( this.addr, units ); + if ( ! arraysEqual( cache, units ) ) { + + gl.uniform1iv( this.addr, units ); + + copyArray( cache, units ); + + } for ( let i = 0; i !== n; ++ i ) { @@ -17781,11 +17880,19 @@ function setValueT3DArray( gl, v, textures ) { function setValueT6Array( gl, v, textures ) { + const cache = this.cache; + const n = v.length; const units = allocTexUnits( textures, n ); - gl.uniform1iv( this.addr, units ); + if ( ! arraysEqual( cache, units ) ) { + + gl.uniform1iv( this.addr, units ); + + copyArray( cache, units ); + + } for ( let i = 0; i !== n; ++ i ) { @@ -17797,11 +17904,19 @@ function setValueT6Array( gl, v, textures ) { function setValueT2DArrayArray( gl, v, textures ) { + const cache = this.cache; + const n = v.length; const units = allocTexUnits( textures, n ); - gl.uniform1iv( this.addr, units ); + if ( ! arraysEqual( cache, units ) ) { + + gl.uniform1iv( this.addr, units ); + + copyArray( cache, units ); + + } for ( let i = 0; i !== n; ++ i ) { @@ -18254,13 +18369,18 @@ function filterEmptyLine( string ) { function replaceLightNums( string, parameters ) { + const numSpotLightCoords = parameters.numSpotLightShadows + parameters.numSpotLightMaps - parameters.numSpotLightShadowsWithMaps; + return string .replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights ) .replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights ) + .replace( /NUM_SPOT_LIGHT_MAPS/g, parameters.numSpotLightMaps ) + .replace( /NUM_SPOT_LIGHT_COORDS/g, numSpotLightCoords ) .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_WITH_MAPS/g, parameters.numSpotLightShadowsWithMaps ) .replace( /NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows ) .replace( /NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows ); @@ -18300,21 +18420,11 @@ function includeReplacer( match, include ) { // Unroll Loops -const deprecatedUnrollLoopPattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g; const 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; function unrollLoops( string ) { - return string - .replace( unrollLoopPattern, loopReplacer ) - .replace( deprecatedUnrollLoopPattern, deprecatedLoopReplacer ); - -} - -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 string.replace( unrollLoopPattern, loopReplacer ); } @@ -19060,29 +19170,32 @@ class WebGLShaderCache { _getShaderCacheForMaterial( material ) { const cache = this.materialCache; + let set = cache.get( material ); - if ( cache.has( material ) === false ) { + if ( set === undefined ) { - cache.set( material, new Set() ); + set = new Set(); + cache.set( material, set ); } - return cache.get( material ); + return set; } _getShaderStage( code ) { const cache = this.shaderCache; + let stage = cache.get( code ); - if ( cache.has( code ) === false ) { + if ( stage === undefined ) { - const stage = new WebGLShaderStage( code ); + stage = new WebGLShaderStage( code ); cache.set( code, stage ); } - return cache.get( code ); + return stage; } @@ -19295,12 +19408,14 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities numDirLights: lights.directional.length, numPointLights: lights.point.length, numSpotLights: lights.spot.length, + numSpotLightMaps: lights.spotLightMap.length, numRectAreaLights: lights.rectArea.length, numHemiLights: lights.hemi.length, numDirLightShadows: lights.directionalShadowMap.length, numPointLightShadows: lights.pointShadowMap.length, numSpotLightShadows: lights.spotShadowMap.length, + numSpotLightShadowsWithMaps: lights.numSpotLightShadowsWithMaps, numClippingPlanes: clipping.numPlanes, numClipIntersection: clipping.numIntersection, @@ -19395,11 +19510,13 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities array.push( parameters.numDirLights ); array.push( parameters.numPointLights ); array.push( parameters.numSpotLights ); + array.push( parameters.numSpotLightMaps ); array.push( parameters.numHemiLights ); array.push( parameters.numRectAreaLights ); array.push( parameters.numDirLightShadows ); array.push( parameters.numPointLightShadows ); array.push( parameters.numSpotLightShadows ); + array.push( parameters.numSpotLightShadowsWithMaps ); array.push( parameters.shadowMapType ); array.push( parameters.toneMapping ); array.push( parameters.numClippingPlanes ); @@ -19478,60 +19595,60 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities _programLayers.enable( 31 ); if ( parameters.uvsVertexOnly ) _programLayers.enable( 32 ); - if ( parameters.fog ) - _programLayers.enable( 33 ); array.push( _programLayers.mask ); _programLayers.disableAll(); - if ( parameters.useFog ) + if ( parameters.fog ) _programLayers.enable( 0 ); - if ( parameters.flatShading ) + if ( parameters.useFog ) _programLayers.enable( 1 ); - if ( parameters.logarithmicDepthBuffer ) + if ( parameters.flatShading ) _programLayers.enable( 2 ); - if ( parameters.skinning ) + if ( parameters.logarithmicDepthBuffer ) _programLayers.enable( 3 ); - if ( parameters.morphTargets ) + if ( parameters.skinning ) _programLayers.enable( 4 ); - if ( parameters.morphNormals ) + if ( parameters.morphTargets ) _programLayers.enable( 5 ); - if ( parameters.morphColors ) + if ( parameters.morphNormals ) _programLayers.enable( 6 ); - if ( parameters.premultipliedAlpha ) + if ( parameters.morphColors ) _programLayers.enable( 7 ); - if ( parameters.shadowMapEnabled ) + if ( parameters.premultipliedAlpha ) _programLayers.enable( 8 ); - if ( parameters.physicallyCorrectLights ) + if ( parameters.shadowMapEnabled ) _programLayers.enable( 9 ); - if ( parameters.doubleSided ) + if ( parameters.physicallyCorrectLights ) _programLayers.enable( 10 ); - if ( parameters.flipSided ) + if ( parameters.doubleSided ) _programLayers.enable( 11 ); - if ( parameters.useDepthPacking ) + if ( parameters.flipSided ) _programLayers.enable( 12 ); - if ( parameters.dithering ) + if ( parameters.useDepthPacking ) _programLayers.enable( 13 ); - if ( parameters.specularIntensityMap ) + if ( parameters.dithering ) _programLayers.enable( 14 ); - if ( parameters.specularColorMap ) + if ( parameters.specularIntensityMap ) _programLayers.enable( 15 ); - if ( parameters.transmission ) + if ( parameters.specularColorMap ) _programLayers.enable( 16 ); - if ( parameters.transmissionMap ) + if ( parameters.transmission ) _programLayers.enable( 17 ); - if ( parameters.thicknessMap ) + if ( parameters.transmissionMap ) _programLayers.enable( 18 ); - if ( parameters.sheen ) + if ( parameters.thicknessMap ) _programLayers.enable( 19 ); - if ( parameters.sheenColorMap ) + if ( parameters.sheen ) _programLayers.enable( 20 ); - if ( parameters.sheenRoughnessMap ) + if ( parameters.sheenColorMap ) _programLayers.enable( 21 ); - if ( parameters.decodeVideoTexture ) + if ( parameters.sheenRoughnessMap ) _programLayers.enable( 22 ); - if ( parameters.opaque ) + if ( parameters.decodeVideoTexture ) _programLayers.enable( 23 ); + if ( parameters.opaque ) + _programLayers.enable( 24 ); array.push( _programLayers.mask ); @@ -19872,23 +19989,24 @@ function WebGLRenderLists() { function get( scene, renderCallDepth ) { + const listArray = lists.get( scene ); let list; - if ( lists.has( scene ) === false ) { + if ( listArray === undefined ) { list = new WebGLRenderList(); lists.set( scene, [ list ] ); } else { - if ( renderCallDepth >= lists.get( scene ).length ) { + if ( renderCallDepth >= listArray.length ) { list = new WebGLRenderList(); - lists.get( scene ).push( list ); + listArray.push( list ); } else { - list = lists.get( scene )[ renderCallDepth ]; + list = listArray[ renderCallDepth ]; } @@ -20051,9 +20169,9 @@ function ShadowUniformsCache() { let nextVersion = 0; -function shadowCastingLightsFirst( lightA, lightB ) { +function shadowCastingAndTexturingLightsFirst( lightA, lightB ) { - return ( lightB.castShadow ? 1 : 0 ) - ( lightA.castShadow ? 1 : 0 ); + return ( lightB.castShadow ? 2 : 0 ) - ( lightA.castShadow ? 2 : 0 ) + ( lightB.map ? 1 : 0 ) - ( lightA.map ? 1 : 0 ); } @@ -20076,7 +20194,8 @@ function WebGLLights( extensions, capabilities ) { numDirectionalShadows: - 1, numPointShadows: - 1, - numSpotShadows: - 1 + numSpotShadows: - 1, + numSpotMaps: - 1 }, ambient: [ 0, 0, 0 ], @@ -20086,9 +20205,10 @@ function WebGLLights( extensions, capabilities ) { directionalShadowMap: [], directionalShadowMatrix: [], spot: [], + spotLightMap: [], spotShadow: [], spotShadowMap: [], - spotShadowMatrix: [], + spotLightMatrix: [], rectArea: [], rectAreaLTC1: null, rectAreaLTC2: null, @@ -20096,7 +20216,8 @@ function WebGLLights( extensions, capabilities ) { pointShadow: [], pointShadowMap: [], pointShadowMatrix: [], - hemi: [] + hemi: [], + numSpotLightShadowsWithMaps: 0 }; @@ -20121,8 +20242,11 @@ function WebGLLights( extensions, capabilities ) { let numDirectionalShadows = 0; let numPointShadows = 0; let numSpotShadows = 0; + let numSpotMaps = 0; + let numSpotShadowsWithMaps = 0; - lights.sort( shadowCastingLightsFirst ); + // ordering : [shadow casting + map texturing, map texturing, shadow casting, none ] + lights.sort( shadowCastingAndTexturingLightsFirst ); // artist-friendly light intensity scaling factor const scaleFactor = ( physicallyCorrectLights !== true ) ? Math.PI : 1; @@ -20193,9 +20317,26 @@ function WebGLLights( extensions, capabilities ) { uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) ); uniforms.decay = light.decay; - if ( light.castShadow ) { + state.spot[ spotLength ] = uniforms; - const shadow = light.shadow; + const shadow = light.shadow; + + if ( light.map ) { + + state.spotLightMap[ numSpotMaps ] = light.map; + numSpotMaps ++; + + // make sure the lightMatrix is up to date + // TODO : do it if required only + shadow.updateMatrices( light ); + + if ( light.castShadow ) numSpotShadowsWithMaps ++; + + } + + state.spotLightMatrix[ spotLength ] = shadow.matrix; + + if ( light.castShadow ) { const shadowUniforms = shadowCache.get( light ); @@ -20206,24 +20347,17 @@ function WebGLLights( extensions, capabilities ) { state.spotShadow[ spotLength ] = shadowUniforms; state.spotShadowMap[ spotLength ] = shadowMap; - state.spotShadowMatrix[ spotLength ] = light.shadow.matrix; numSpotShadows ++; } - state.spot[ spotLength ] = uniforms; - spotLength ++; } else if ( light.isRectAreaLight ) { const uniforms = 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 uniforms.color.copy( color ).multiplyScalar( intensity ); uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 ); @@ -20327,7 +20461,8 @@ function WebGLLights( extensions, capabilities ) { hash.hemiLength !== hemiLength || hash.numDirectionalShadows !== numDirectionalShadows || hash.numPointShadows !== numPointShadows || - hash.numSpotShadows !== numSpotShadows ) { + hash.numSpotShadows !== numSpotShadows || + hash.numSpotMaps !== numSpotMaps ) { state.directional.length = directionalLength; state.spot.length = spotLength; @@ -20343,7 +20478,9 @@ function WebGLLights( extensions, capabilities ) { state.spotShadowMap.length = numSpotShadows; state.directionalShadowMatrix.length = numDirectionalShadows; state.pointShadowMatrix.length = numPointShadows; - state.spotShadowMatrix.length = numSpotShadows; + state.spotLightMatrix.length = numSpotShadows + numSpotMaps - numSpotShadowsWithMaps; + state.spotLightMap.length = numSpotMaps; + state.numSpotLightShadowsWithMaps = numSpotShadowsWithMaps; hash.directionalLength = directionalLength; hash.pointLength = pointLength; @@ -20354,6 +20491,7 @@ function WebGLLights( extensions, capabilities ) { hash.numDirectionalShadows = numDirectionalShadows; hash.numPointShadows = numPointShadows; hash.numSpotShadows = numSpotShadows; + hash.numSpotMaps = numSpotMaps; state.version = nextVersion ++; @@ -20516,23 +20654,24 @@ function WebGLRenderStates( extensions, capabilities ) { function get( scene, renderCallDepth = 0 ) { + const renderStateArray = renderStates.get( scene ); let renderState; - if ( renderStates.has( scene ) === false ) { + if ( renderStateArray === undefined ) { renderState = new WebGLRenderState( extensions, capabilities ); renderStates.set( scene, [ renderState ] ); } else { - if ( renderCallDepth >= renderStates.get( scene ).length ) { + if ( renderCallDepth >= renderStateArray.length ) { renderState = new WebGLRenderState( extensions, capabilities ); - renderStates.get( scene ).push( renderState ); + renderStateArray.push( renderState ); } else { - renderState = renderStates.get( scene )[ renderCallDepth ]; + renderState = renderStateArray[ renderCallDepth ]; } @@ -20889,7 +21028,8 @@ function WebGLShadowMap( _renderer, _objects, _capabilities ) { if ( ( _renderer.localClippingEnabled && material.clipShadows === true && Array.isArray( material.clippingPlanes ) && material.clippingPlanes.length !== 0 ) || ( material.displacementMap && material.displacementScale !== 0 ) || - ( material.alphaMap && material.alphaTest > 0 ) ) { + ( material.alphaMap && material.alphaTest > 0 ) || + ( material.map && material.alphaTest > 0 ) ) { // in this case we need a unique material instance reflecting the // appropriate state @@ -20933,6 +21073,7 @@ function WebGLShadowMap( _renderer, _objects, _capabilities ) { result.alphaMap = material.alphaMap; result.alphaTest = material.alphaTest; + result.map = material.map; result.clipShadows = material.clipShadows; result.clippingPlanes = material.clippingPlanes; @@ -21117,59 +21258,51 @@ function WebGLState( gl, extensions, capabilities ) { if ( currentDepthFunc !== depthFunc ) { - if ( depthFunc ) { - - switch ( depthFunc ) { - - case NeverDepth: - - gl.depthFunc( 512 ); - break; + switch ( depthFunc ) { - case AlwaysDepth: + case NeverDepth: - gl.depthFunc( 519 ); - break; + gl.depthFunc( 512 ); + break; - case LessDepth: + case AlwaysDepth: - gl.depthFunc( 513 ); - break; + gl.depthFunc( 519 ); + break; - case LessEqualDepth: + case LessDepth: - gl.depthFunc( 515 ); - break; + gl.depthFunc( 513 ); + break; - case EqualDepth: + case LessEqualDepth: - gl.depthFunc( 514 ); - break; + gl.depthFunc( 515 ); + break; - case GreaterEqualDepth: + case EqualDepth: - gl.depthFunc( 518 ); - break; + gl.depthFunc( 514 ); + break; - case GreaterDepth: + case GreaterEqualDepth: - gl.depthFunc( 516 ); - break; - - case NotEqualDepth: + gl.depthFunc( 518 ); + break; - gl.depthFunc( 517 ); - break; + case GreaterDepth: - default: + gl.depthFunc( 516 ); + break; - gl.depthFunc( 515 ); + case NotEqualDepth: - } + gl.depthFunc( 517 ); + break; - } else { + default: - gl.depthFunc( 515 ); + gl.depthFunc( 515 ); } @@ -21740,7 +21873,7 @@ function WebGLState( gl, extensions, capabilities ) { } currentBlending = blending; - currentPremultipledAlpha = null; + currentPremultipledAlpha = false; } @@ -21902,25 +22035,40 @@ function WebGLState( gl, extensions, capabilities ) { } - function bindTexture( webglType, webglTexture ) { + function bindTexture( webglType, webglTexture, webglSlot ) { + + if ( webglSlot === undefined ) { + + if ( currentTextureSlot === null ) { - if ( currentTextureSlot === null ) { + webglSlot = 33984 + maxTextures - 1; - activeTexture(); + } else { + + webglSlot = currentTextureSlot; + + } } - let boundTexture = currentBoundTextures[ currentTextureSlot ]; + let boundTexture = currentBoundTextures[ webglSlot ]; if ( boundTexture === undefined ) { boundTexture = { type: undefined, texture: undefined }; - currentBoundTextures[ currentTextureSlot ] = boundTexture; + currentBoundTextures[ webglSlot ] = boundTexture; } if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) { + if ( currentTextureSlot !== webglSlot ) { + + gl.activeTexture( webglSlot ); + currentTextureSlot = webglSlot; + + } + gl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] ); boundTexture.type = webglType; @@ -21959,6 +22107,20 @@ function WebGLState( gl, extensions, capabilities ) { } + function compressedTexImage3D() { + + try { + + gl.compressedTexImage3D.apply( gl, arguments ); + + } catch ( error ) { + + console.error( 'THREE.WebGLState:', error ); + + } + + } + function texSubImage2D() { try { @@ -22001,6 +22163,20 @@ function WebGLState( gl, extensions, capabilities ) { } + function compressedTexSubImage3D() { + + try { + + gl.compressedTexSubImage3D.apply( gl, arguments ); + + } catch ( error ) { + + console.error( 'THREE.WebGLState:', error ); + + } + + } + function texStorage2D() { try { @@ -22246,6 +22422,7 @@ function WebGLState( gl, extensions, capabilities ) { bindTexture: bindTexture, unbindTexture: unbindTexture, compressedTexImage2D: compressedTexImage2D, + compressedTexImage3D: compressedTexImage3D, texImage2D: texImage2D, texImage3D: texImage3D, @@ -22257,6 +22434,7 @@ function WebGLState( gl, extensions, capabilities ) { texSubImage2D: texSubImage2D, texSubImage3D: texSubImage3D, compressedTexSubImage2D: compressedTexSubImage2D, + compressedTexSubImage3D: compressedTexSubImage3D, scissor: scissor, viewport: viewport, @@ -22275,7 +22453,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, const maxTextureSize = capabilities.maxTextureSize; const maxSamples = capabilities.maxSamples; const multisampledRTTExt = extensions.has( 'WEBGL_multisampled_render_to_texture' ) ? extensions.get( 'WEBGL_multisampled_render_to_texture' ) : null; - const supportsInvalidateFramebuffer = /OculusBrowser/g.test( navigator.userAgent ); + const supportsInvalidateFramebuffer = typeof navigator === 'undefined' ? false : /OculusBrowser/g.test( navigator.userAgent ); const _videoTextures = new WeakMap(); let _canvas; @@ -22399,7 +22577,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - function getInternalFormat( internalFormatName, glFormat, glType, encoding, isVideoTexture = false ) { + function getInternalFormat( internalFormatName, glFormat, glType, encoding, forceLinearEncoding = false ) { if ( isWebGL2 === false ) return glFormat; @@ -22433,7 +22611,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, if ( glType === 5126 ) internalFormat = 34836; if ( glType === 5131 ) internalFormat = 34842; - if ( glType === 5121 ) internalFormat = ( encoding === sRGBEncoding && isVideoTexture === false ) ? 35907 : 32856; + if ( glType === 5121 ) internalFormat = ( encoding === sRGBEncoding && forceLinearEncoding === false ) ? 35907 : 32856; if ( glType === 32819 ) internalFormat = 32854; if ( glType === 32820 ) internalFormat = 32855; @@ -22679,6 +22857,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, array.push( texture.wrapS ); array.push( texture.wrapT ); + array.push( texture.wrapR || 0 ); array.push( texture.magFilter ); array.push( texture.minFilter ); array.push( texture.anisotropy ); @@ -22724,8 +22903,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - state.activeTexture( 33984 + slot ); - state.bindTexture( 3553, textureProperties.__webglTexture ); + state.bindTexture( 3553, textureProperties.__webglTexture, 33984 + slot ); } @@ -22740,8 +22918,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - state.activeTexture( 33984 + slot ); - state.bindTexture( 35866, textureProperties.__webglTexture ); + state.bindTexture( 35866, textureProperties.__webglTexture, 33984 + slot ); } @@ -22756,8 +22933,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - state.activeTexture( 33984 + slot ); - state.bindTexture( 32879, textureProperties.__webglTexture ); + state.bindTexture( 32879, textureProperties.__webglTexture, 33984 + slot ); } @@ -22772,8 +22948,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - state.activeTexture( 33984 + slot ); - state.bindTexture( 34067, textureProperties.__webglTexture ); + state.bindTexture( 34067, textureProperties.__webglTexture, 33984 + slot ); } @@ -22939,16 +23114,19 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, let textureType = 3553; - if ( texture.isDataArrayTexture ) textureType = 35866; + if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) textureType = 35866; if ( texture.isData3DTexture ) textureType = 32879; const forceUpload = initTexture( textureProperties, texture ); const source = texture.source; - state.activeTexture( 33984 + slot ); - state.bindTexture( textureType, textureProperties.__webglTexture ); + state.bindTexture( textureType, textureProperties.__webglTexture, 33984 + slot ); + + const sourceProperties = properties.get( source ); - if ( source.version !== source.__currentVersion || forceUpload === true ) { + if ( source.version !== sourceProperties.__version || forceUpload === true ) { + + state.activeTexture( 33984 + slot ); _gl.pixelStorei( 37440, texture.flipY ); _gl.pixelStorei( 37441, texture.premultiplyAlpha ); @@ -22971,7 +23149,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, const mipmaps = texture.mipmaps; const useTexStorage = ( isWebGL2 && texture.isVideoTexture !== true ); - const allocateMemory = ( source.__currentVersion === undefined ) || ( forceUpload === true ); + const allocateMemory = ( sourceProperties.__version === undefined ) || ( forceUpload === true ); const levels = getMipLevels( texture, image, supportsMips ); if ( texture.isDepthTexture ) { @@ -23118,45 +23296,97 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } else if ( texture.isCompressedTexture ) { - if ( useTexStorage && allocateMemory ) { + if ( texture.isCompressedArrayTexture ) { + + if ( useTexStorage && allocateMemory ) { - state.texStorage2D( 3553, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height ); + state.texStorage3D( 35866, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height, image.depth ); - } + } - for ( let i = 0, il = mipmaps.length; i < il; i ++ ) { + for ( let i = 0, il = mipmaps.length; i < il; i ++ ) { - mipmap = mipmaps[ i ]; + mipmap = mipmaps[ i ]; - if ( texture.format !== RGBAFormat ) { + if ( texture.format !== RGBAFormat ) { - if ( glFormat !== null ) { + if ( glFormat !== null ) { - if ( useTexStorage ) { + if ( useTexStorage ) { - state.compressedTexSubImage2D( 3553, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data ); + state.compressedTexSubImage3D( 35866, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, mipmap.data, 0, 0 ); + + } else { + + state.compressedTexImage3D( 35866, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, mipmap.data, 0, 0 ); + + } } else { - state.compressedTexImage2D( 3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); + console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' ); } } else { - console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' ); + if ( useTexStorage ) { + + state.texSubImage3D( 35866, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, glType, mipmap.data ); + + } else { + + state.texImage3D( 35866, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, glFormat, glType, mipmap.data ); + + } } - } else { + } - if ( useTexStorage ) { + } else { - state.texSubImage2D( 3553, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data ); + if ( useTexStorage && allocateMemory ) { + + state.texStorage2D( 3553, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height ); + + } + + for ( let i = 0, il = mipmaps.length; i < il; i ++ ) { + + mipmap = mipmaps[ i ]; + + if ( texture.format !== RGBAFormat ) { + + if ( glFormat !== null ) { + + if ( useTexStorage ) { + + state.compressedTexSubImage2D( 3553, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data ); + + } else { + + 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 ); + if ( useTexStorage ) { + + state.texSubImage2D( 3553, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data ); + + } else { + + state.texImage2D( 3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); + + } } @@ -23287,7 +23517,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - source.__currentVersion = source.version; + sourceProperties.__version = source.version; if ( texture.onUpdate ) texture.onUpdate( texture ); @@ -23304,10 +23534,13 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, const forceUpload = initTexture( textureProperties, texture ); const source = texture.source; - state.activeTexture( 33984 + slot ); - state.bindTexture( 34067, textureProperties.__webglTexture ); + state.bindTexture( 34067, textureProperties.__webglTexture, 33984 + slot ); - if ( source.version !== source.__currentVersion || forceUpload === true ) { + const sourceProperties = properties.get( source ); + + if ( source.version !== sourceProperties.__version || forceUpload === true ) { + + state.activeTexture( 33984 + slot ); _gl.pixelStorei( 37440, texture.flipY ); _gl.pixelStorei( 37441, texture.premultiplyAlpha ); @@ -23342,7 +23575,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding ); const useTexStorage = ( isWebGL2 && texture.isVideoTexture !== true ); - const allocateMemory = ( source.__currentVersion === undefined ) || ( forceUpload === true ); + const allocateMemory = ( sourceProperties.__version === undefined ) || ( forceUpload === true ); let levels = getMipLevels( texture, image, supportsMips ); setTextureParameters( 34067, texture, supportsMips ); @@ -23491,7 +23724,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - source.__currentVersion = source.version; + sourceProperties.__version = source.version; if ( texture.onUpdate ) texture.onUpdate( texture ); @@ -23531,7 +23764,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, multisampledRTTExt.framebufferTexture2DMultisampleEXT( 36160, attachment, textureTarget, properties.get( texture ).__webglTexture, 0, getRenderTargetSamples( renderTarget ) ); - } else { + } else if ( textureTarget === 3553 || ( textureTarget >= 34069 && textureTarget <= 34074 ) ) { // see #24753 _gl.framebufferTexture2D( 36160, attachment, textureTarget, properties.get( texture ).__webglTexture, 0 ); @@ -23855,7 +24088,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, const glFormat = utils.convert( texture.format, texture.encoding ); const glType = utils.convert( texture.type ); - const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding ); + const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding, renderTarget.isXRRenderTarget === true ); const samples = getRenderTargetSamples( renderTarget ); _gl.renderbufferStorageMultisample( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height ); @@ -24246,7 +24479,8 @@ function WebGLUtils( gl, extensions, capabilities ) { if ( p === LuminanceAlphaFormat ) return 6410; if ( p === DepthFormat ) return 6402; if ( p === DepthStencilFormat ) return 34041; - if ( p === RedFormat ) return 6403; + + // @deprecated since r137 if ( p === RGBFormat ) { @@ -24275,6 +24509,7 @@ function WebGLUtils( gl, extensions, capabilities ) { // WebGL2 formats. + if ( p === RedFormat ) return 6403; if ( p === RedIntegerFormat ) return 36244; if ( p === RGFormat ) return 33319; if ( p === RGIntegerFormat ) return 33320; @@ -24580,6 +24815,31 @@ class WebXRController { } + connect( inputSource ) { + + if ( inputSource && inputSource.hand ) { + + const hand = this._hand; + + if ( hand ) { + + for ( const inputjoint of inputSource.hand.values() ) { + + // Initialize hand with joints when connected + this._getHandJoint( hand, inputjoint ); + + } + + } + + } + + this.dispatchEvent( { type: 'connected', data: inputSource } ); + + return this; + + } + disconnect( inputSource ) { this.dispatchEvent( { type: 'disconnected', data: inputSource } ); @@ -24627,19 +24887,8 @@ class WebXRController { // Update the joints groups with the XRJoint poses const jointPose = frame.getJointPose( inputjoint, referenceSpace ); - if ( hand.joints[ inputjoint.jointName ] === undefined ) { - - // The transform of this joint will be updated with the joint pose on each frame - const joint = new Group(); - joint.matrixAutoUpdate = false; - joint.visible = false; - hand.joints[ inputjoint.jointName ] = joint; - // ?? - hand.add( joint ); - - } - - const joint = hand.joints[ inputjoint.jointName ]; + // The transform of this joint will be updated with the joint pose on each frame + const joint = this._getHandJoint( hand, inputjoint ); if ( jointPose !== null ) { @@ -24791,6 +25040,25 @@ class WebXRController { } + // private method + + _getHandJoint( hand, inputjoint ) { + + if ( hand.joints[ inputjoint.jointName ] === undefined ) { + + const joint = new Group(); + joint.matrixAutoUpdate = false; + joint.visible = false; + hand.joints[ inputjoint.jointName ] = joint; + + hand.add( joint ); + + } + + return hand.joints[ inputjoint.jointName ]; + + } + } class DepthTexture extends Texture { @@ -24852,6 +25120,9 @@ class WebXRManager extends EventDispatcher { const controllers = []; const controllerInputSources = []; + const planes = new Set(); + const planesLastChangedTimes = new Map(); + // const cameraL = new PerspectiveCamera(); @@ -25094,7 +25365,8 @@ class WebXRManager extends EventDispatcher { { format: RGBAFormat, type: UnsignedByteType, - encoding: renderer.outputEncoding + encoding: renderer.outputEncoding, + stencilBuffer: attributes.stencil } ); @@ -25172,7 +25444,7 @@ class WebXRManager extends EventDispatcher { if ( index >= 0 ) { controllerInputSources[ index ] = null; - controllers[ index ].dispatchEvent( { type: 'disconnected', data: inputSource } ); + controllers[ index ].disconnect( inputSource ); } @@ -25218,7 +25490,7 @@ class WebXRManager extends EventDispatcher { if ( controller ) { - controller.dispatchEvent( { type: 'connected', data: inputSource } ); + controller.connect( inputSource ); } @@ -25338,11 +25610,8 @@ class WebXRManager extends EventDispatcher { // update user camera and its children - camera.position.copy( cameraVR.position ); - camera.quaternion.copy( cameraVR.quaternion ); - camera.scale.copy( cameraVR.scale ); camera.matrix.copy( cameraVR.matrix ); - camera.matrixWorld.copy( cameraVR.matrixWorld ); + camera.matrix.decompose( camera.position, camera.quaternion, camera.scale ); const children = camera.children; @@ -25411,6 +25680,12 @@ class WebXRManager extends EventDispatcher { }; + this.getPlanes = function () { + + return planes; + + }; + // Animation Loop let onAnimationFrameCallback = null; @@ -25519,6 +25794,65 @@ class WebXRManager extends EventDispatcher { if ( onAnimationFrameCallback ) onAnimationFrameCallback( time, frame ); + if ( frame.detectedPlanes ) { + + scope.dispatchEvent( { type: 'planesdetected', data: frame.detectedPlanes } ); + + let planesToRemove = null; + + for ( const plane of planes ) { + + if ( ! frame.detectedPlanes.has( plane ) ) { + + if ( planesToRemove === null ) { + + planesToRemove = []; + + } + + planesToRemove.push( plane ); + + } + + } + + if ( planesToRemove !== null ) { + + for ( const plane of planesToRemove ) { + + planes.delete( plane ); + planesLastChangedTimes.delete( plane ); + scope.dispatchEvent( { type: 'planeremoved', data: plane } ); + + } + + } + + for ( const plane of frame.detectedPlanes ) { + + if ( ! planes.has( plane ) ) { + + planes.add( plane ); + planesLastChangedTimes.set( plane, frame.lastChangedTime ); + scope.dispatchEvent( { type: 'planeadded', data: plane } ); + + } else { + + const lastKnownTime = planesLastChangedTimes.get( plane ); + + if ( plane.lastChangedTime > lastKnownTime ) { + + planesLastChangedTimes.set( plane, plane.lastChangedTime ); + scope.dispatchEvent( { type: 'planechanged', data: plane } ); + + } + + } + + } + + } + xrFrame = null; } @@ -25543,7 +25877,7 @@ function WebGLMaterials( renderer, properties ) { function refreshFogUniforms( uniforms, fog ) { - uniforms.fogColor.value.copy( fog.color ); + fog.color.getRGB( uniforms.fogColor.value, getUnlitUniformColorSpace( renderer ) ); if ( fog.isFog ) { @@ -26670,28 +27004,6 @@ function WebGLRenderer( parameters = {} ) { this.toneMapping = NoToneMapping; this.toneMappingExposure = 1.0; - // - - Object.defineProperties( this, { - - // @deprecated since r136, 0e21088102b4de7e0a0a33140620b7a3424b9e6d - - gammaFactor: { - get: function () { - - console.warn( 'THREE.WebGLRenderer: .gammaFactor has been removed.' ); - return 2; - - }, - set: function () { - - console.warn( 'THREE.WebGLRenderer: .gammaFactor has been removed.' ); - - } - } - - } ); - // internal properties const _this = this; @@ -26873,7 +27185,7 @@ function WebGLRenderer( parameters = {} ) { materials = new WebGLMaterials( _this, properties ); renderLists = new WebGLRenderLists(); renderStates = new WebGLRenderStates( extensions, capabilities ); - background = new WebGLBackground( _this, cubemaps, state, objects, _alpha, _premultipliedAlpha ); + background = new WebGLBackground( _this, cubemaps, cubeuvmaps, state, objects, _alpha, _premultipliedAlpha ); shadowMap = new WebGLShadowMap( _this, objects, capabilities ); uniformsGroups = new WebGLUniformsGroups( _gl, info, capabilities, state ); @@ -27258,31 +27570,48 @@ function WebGLRenderer( parameters = {} ) { // let index = geometry.index; - const position = geometry.attributes.position; + let rangeFactor = 1; + + if ( material.wireframe === true ) { + + index = geometries.getWireframeAttribute( geometry ); + rangeFactor = 2; + + } // - if ( index === null ) { + const drawRange = geometry.drawRange; + const position = geometry.attributes.position; - if ( position === undefined || position.count === 0 ) return; + let drawStart = drawRange.start * rangeFactor; + let drawEnd = ( drawRange.start + drawRange.count ) * rangeFactor; - } else if ( index.count === 0 ) { + if ( group !== null ) { - return; + drawStart = Math.max( drawStart, group.start * rangeFactor ); + drawEnd = Math.min( drawEnd, ( group.start + group.count ) * rangeFactor ); } - // + if ( index !== null ) { - let rangeFactor = 1; + drawStart = Math.max( drawStart, 0 ); + drawEnd = Math.min( drawEnd, index.count ); - if ( material.wireframe === true ) { + } else if ( position !== undefined && position !== null ) { - index = geometries.getWireframeAttribute( geometry ); - rangeFactor = 2; + drawStart = Math.max( drawStart, 0 ); + drawEnd = Math.min( drawEnd, position.count ); } + const drawCount = drawEnd - drawStart; + + if ( drawCount < 0 || drawCount === Infinity ) return; + + // + bindingStates.setup( object, material, program, geometry, index ); let attribute; @@ -27299,23 +27628,6 @@ function WebGLRenderer( parameters = {} ) { // - const dataCount = ( index !== null ) ? index.count : position.count; - - const rangeStart = geometry.drawRange.start * rangeFactor; - const rangeCount = geometry.drawRange.count * rangeFactor; - - const groupStart = group !== null ? group.start * rangeFactor : 0; - const groupCount = group !== null ? group.count * rangeFactor : Infinity; - - const drawStart = Math.max( rangeStart, groupStart ); - const drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1; - - const drawCount = Math.max( 0, drawEnd - drawStart + 1 ); - - if ( drawCount === 0 ) return; - - // - if ( object.isMesh ) { if ( material.wireframe === true ) { @@ -27367,7 +27679,8 @@ function WebGLRenderer( parameters = {} ) { } else if ( geometry.isInstancedBufferGeometry ) { - const instanceCount = Math.min( geometry.instanceCount, geometry._maxInstanceCount ); + const maxInstanceCount = geometry._maxInstanceCount !== undefined ? geometry._maxInstanceCount : Infinity; + const instanceCount = Math.min( geometry.instanceCount, maxInstanceCount ); renderer.renderInstances( drawStart, drawCount, instanceCount ); @@ -27383,6 +27696,28 @@ function WebGLRenderer( parameters = {} ) { this.compile = function ( scene, camera ) { + function prepare( material, scene, object ) { + + if ( material.transparent === true && material.side === DoubleSide ) { + + material.side = BackSide; + material.needsUpdate = true; + getProgram( material, scene, object ); + + material.side = FrontSide; + material.needsUpdate = true; + getProgram( material, scene, object ); + + material.side = DoubleSide; + + } else { + + getProgram( material, scene, object ); + + } + + } + currentRenderState = renderStates.get( scene ); currentRenderState.init(); @@ -27418,13 +27753,13 @@ function WebGLRenderer( parameters = {} ) { const material2 = material[ i ]; - getProgram( material2, scene, object ); + prepare( material2, scene, object ); } } else { - getProgram( material, scene, object ); + prepare( material, scene, object ); } @@ -27491,11 +27826,11 @@ function WebGLRenderer( parameters = {} ) { // update scene graph - if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); + if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld(); // update camera matrices and frustum - if ( camera.parent === null ) camera.updateMatrixWorld(); + if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld(); if ( xr.enabled === true && xr.isPresenting === true ) { @@ -27964,7 +28299,8 @@ function WebGLRenderer( parameters = {} ) { 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.spotLightMatrix.value = lights.state.spotLightMatrix; + uniforms.spotLightMap.value = lights.state.spotLightMap; uniforms.pointShadowMap.value = lights.state.pointShadowMap; uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; // TODO (abelnation): add area lights shadow info to uniforms @@ -28262,7 +28598,6 @@ function WebGLRenderer( parameters = {} ) { } - if ( refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow ) { materialProperties.receiveShadow = object.receiveShadow; @@ -28270,6 +28605,16 @@ function WebGLRenderer( parameters = {} ) { } + // https://github.com/mrdoob/three.js/pull/24467#issuecomment-1209031512 + + if ( material.isMeshGouraudMaterial && material.envMap !== null ) { + + m_uniforms.envMap.value = envMap; + + m_uniforms.flipEnvMap.value = ( envMap.isCubeTexture && envMap.isRenderTargetTexture === false ) ? - 1 : 1; + + } + if ( refreshMaterial ) { p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure ); @@ -28439,6 +28784,9 @@ function WebGLRenderer( parameters = {} ) { _currentActiveMipmapLevel = activeMipmapLevel; let useDefaultFramebuffer = true; + let framebuffer = null; + let isCube = false; + let isRenderTarget3D = false; if ( renderTarget ) { @@ -28461,17 +28809,9 @@ function WebGLRenderer( parameters = {} ) { } - } - - let framebuffer = null; - let isCube = false; - let isRenderTarget3D = false; - - if ( renderTarget ) { - const texture = renderTarget.texture; - if ( texture.isData3DTexture || texture.isDataArrayTexture ) { + if ( texture.isData3DTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture ) { isRenderTarget3D = true; @@ -28712,7 +29052,7 @@ function WebGLRenderer( parameters = {} ) { } else { - if ( srcTexture.isCompressedTexture ) { + if ( srcTexture.isCompressedArrayTexture ) { console.warn( 'THREE.WebGLRenderer.copyTextureToTexture3D: untested support for compressed srcTexture.' ); _gl.compressedTexSubImage3D( glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, image.data ); @@ -28748,7 +29088,7 @@ function WebGLRenderer( parameters = {} ) { textures.setTexture3D( texture, 0 ); - } else if ( texture.isDataArrayTexture ) { + } else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) { textures.setTexture2DArray( texture, 0 ); @@ -28864,9 +29204,10 @@ class Scene extends Object3D { this.environment = null; this.fog = null; - this.overrideMaterial = null; + this.backgroundBlurriness = 0; + this.backgroundIntensity = 1; - this.autoUpdate = true; // checked by the renderer + this.overrideMaterial = null; if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { @@ -28884,9 +29225,11 @@ class Scene extends Object3D { if ( source.environment !== null ) this.environment = source.environment.clone(); if ( source.fog !== null ) this.fog = source.fog.clone(); + this.backgroundBlurriness = source.backgroundBlurriness; + this.backgroundIntensity = source.backgroundIntensity; + if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone(); - this.autoUpdate = source.autoUpdate; this.matrixAutoUpdate = source.matrixAutoUpdate; return this; @@ -28898,11 +29241,29 @@ class Scene extends Object3D { const data = super.toJSON( meta ); if ( this.fog !== null ) data.object.fog = this.fog.toJSON(); + if ( this.backgroundBlurriness > 0 ) data.backgroundBlurriness = this.backgroundBlurriness; + if ( this.backgroundIntensity !== 1 ) data.backgroundIntensity = this.backgroundIntensity; return data; } + // @deprecated + + get autoUpdate() { + + console.warn( 'THREE.Scene: autoUpdate was renamed to matrixWorldAutoUpdate in r144.' ); + return this.matrixWorldAutoUpdate; + + } + + set autoUpdate( value ) { + + console.warn( 'THREE.Scene: autoUpdate was renamed to matrixWorldAutoUpdate in r144.' ); + this.matrixWorldAutoUpdate = value; + + } + } class InterleavedBuffer { @@ -29132,6 +29493,8 @@ class InterleavedBufferAttribute { setX( index, x ) { + if ( this.normalized ) x = normalize( x, this.array ); + this.data.array[ index * this.data.stride + this.offset ] = x; return this; @@ -29140,6 +29503,8 @@ class InterleavedBufferAttribute { setY( index, y ) { + if ( this.normalized ) y = normalize( y, this.array ); + this.data.array[ index * this.data.stride + this.offset + 1 ] = y; return this; @@ -29148,6 +29513,8 @@ class InterleavedBufferAttribute { setZ( index, z ) { + if ( this.normalized ) z = normalize( z, this.array ); + this.data.array[ index * this.data.stride + this.offset + 2 ] = z; return this; @@ -29156,6 +29523,8 @@ class InterleavedBufferAttribute { setW( index, w ) { + if ( this.normalized ) w = normalize( w, this.array ); + this.data.array[ index * this.data.stride + this.offset + 3 ] = w; return this; @@ -29164,25 +29533,41 @@ class InterleavedBufferAttribute { getX( index ) { - return this.data.array[ index * this.data.stride + this.offset ]; + let x = this.data.array[ index * this.data.stride + this.offset ]; + + if ( this.normalized ) x = denormalize( x, this.array ); + + return x; } getY( index ) { - return this.data.array[ index * this.data.stride + this.offset + 1 ]; + let y = this.data.array[ index * this.data.stride + this.offset + 1 ]; + + if ( this.normalized ) y = denormalize( y, this.array ); + + return y; } getZ( index ) { - return this.data.array[ index * this.data.stride + this.offset + 2 ]; + let z = this.data.array[ index * this.data.stride + this.offset + 2 ]; + + if ( this.normalized ) z = denormalize( z, this.array ); + + return z; } getW( index ) { - return this.data.array[ index * this.data.stride + this.offset + 3 ]; + let w = this.data.array[ index * this.data.stride + this.offset + 3 ]; + + if ( this.normalized ) w = denormalize( w, this.array ); + + return w; } @@ -29190,6 +29575,13 @@ class InterleavedBufferAttribute { index = index * this.data.stride + this.offset; + if ( this.normalized ) { + + x = normalize( x, this.array ); + y = normalize( y, this.array ); + + } + this.data.array[ index + 0 ] = x; this.data.array[ index + 1 ] = y; @@ -29201,6 +29593,14 @@ class InterleavedBufferAttribute { index = index * this.data.stride + this.offset; + if ( this.normalized ) { + + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); + + } + this.data.array[ index + 0 ] = x; this.data.array[ index + 1 ] = y; this.data.array[ index + 2 ] = z; @@ -29213,6 +29613,15 @@ class InterleavedBufferAttribute { index = index * this.data.stride + this.offset; + if ( this.normalized ) { + + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); + w = normalize( w, this.array ); + + } + this.data.array[ index + 0 ] = x; this.data.array[ index + 1 ] = y; this.data.array[ index + 2 ] = z; @@ -29226,7 +29635,7 @@ class InterleavedBufferAttribute { if ( data === undefined ) { - console.log( 'THREE.InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will deinterleave buffer data.' ); + console.log( 'THREE.InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will de-interleave buffer data.' ); const array = []; @@ -29268,7 +29677,7 @@ class InterleavedBufferAttribute { if ( data === undefined ) { - console.log( 'THREE.InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will deinterleave buffer data.' ); + console.log( 'THREE.InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will de-interleave buffer data.' ); const array = []; @@ -29284,7 +29693,7 @@ class InterleavedBufferAttribute { } - // deinterleave data and save it as an ordinary buffer attribute for now + // de-interleave data and save it as an ordinary buffer attribute for now return { itemSize: this.itemSize, @@ -29295,7 +29704,7 @@ class InterleavedBufferAttribute { } else { - // save as true interleaved attribtue + // save as true interleaved attribute if ( data.interleavedBuffers === undefined ) { @@ -29580,7 +29989,7 @@ class LOD extends Object3D { const level = levels[ i ]; - this.addLevel( level.object.clone(), level.distance ); + this.addLevel( level.object.clone(), level.distance, level.hysteresis ); } @@ -29590,7 +29999,7 @@ class LOD extends Object3D { } - addLevel( object, distance = 0 ) { + addLevel( object, distance = 0, hysteresis = 0 ) { distance = Math.abs( distance ); @@ -29608,7 +30017,7 @@ class LOD extends Object3D { } - levels.splice( l, 0, { distance: distance, object: object } ); + levels.splice( l, 0, { distance: distance, hysteresis: hysteresis, object: object } ); this.add( object ); @@ -29622,6 +30031,8 @@ class LOD extends Object3D { } + + getObjectForDistance( distance ) { const levels = this.levels; @@ -29632,7 +30043,15 @@ class LOD extends Object3D { for ( i = 1, l = levels.length; i < l; i ++ ) { - if ( distance < levels[ i ].distance ) { + let levelDistance = levels[ i ].distance; + + if ( levels[ i ].object.visible ) { + + levelDistance -= levelDistance * levels[ i ].hysteresis; + + } + + if ( distance < levelDistance ) { break; @@ -29681,7 +30100,15 @@ class LOD extends Object3D { for ( i = 1, l = levels.length; i < l; i ++ ) { - if ( distance >= levels[ i ].distance ) { + let levelDistance = levels[ i ].distance; + + if ( levels[ i ].object.visible ) { + + levelDistance -= levelDistance * levels[ i ].hysteresis; + + } + + if ( distance >= levelDistance ) { levels[ i - 1 ].object.visible = false; levels[ i ].object.visible = true; @@ -29722,7 +30149,8 @@ class LOD extends Object3D { data.object.levels.push( { object: level.object.uuid, - distance: level.distance + distance: level.distance, + hysteresis: level.hysteresis } ); } @@ -30185,16 +30613,6 @@ class InstancedBufferAttribute extends BufferAttribute { constructor( array, itemSize, normalized, meshPerAttribute = 1 ) { - if ( typeof normalized === 'number' ) { - - meshPerAttribute = normalized; - - normalized = false; - - console.error( 'THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument.' ); - - } - super( array, itemSize, normalized ); this.isInstancedBufferAttribute = true; @@ -30232,6 +30650,7 @@ const _instanceWorldMatrix = /*@__PURE__*/ new Matrix4(); const _instanceIntersects = []; +const _identity = /*@__PURE__*/ new Matrix4(); const _mesh = /*@__PURE__*/ new Mesh(); class InstancedMesh extends Mesh { @@ -30249,6 +30668,12 @@ class InstancedMesh extends Mesh { this.frustumCulled = false; + for ( let i = 0; i < count; i ++ ) { + + this.setMatrixAt( i, _identity ); + + } + } copy( source, recursive ) { @@ -30965,6 +31390,20 @@ class CompressedTexture extends Texture { } +class CompressedArrayTexture extends CompressedTexture { + + constructor( mipmaps, width, height, depth, format, type ) { + + super( mipmaps, width, height, format, type ); + + this.isCompressedArrayTexture = true; + this.image.depth = depth; + this.wrapR = ClampToEdgeWrapping; + + } + +} + class CanvasTexture extends Texture { constructor( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) { @@ -33502,7 +33941,7 @@ class PolyhedronGeometry extends BufferGeometry { const b = new Vector3(); const c = new Vector3(); - // iterate over all faces and apply a subdivison with the given detail value + // iterate over all faces and apply a subdivision with the given detail value for ( let i = 0; i < indices.length; i += 3 ) { @@ -34044,7 +34483,7 @@ class Shape extends Path { } /** - * Port from https://github.com/mapbox/earcut (v2.2.2) + * Port from https://github.com/mapbox/earcut (v2.2.4) */ const Earcut = { @@ -34081,11 +34520,11 @@ const Earcut = { // minX, minY and invSize are later used to transform coords into integers for z-order calculation invSize = Math.max( maxX - minX, maxY - minY ); - invSize = invSize !== 0 ? 1 / invSize : 0; + invSize = invSize !== 0 ? 32767 / invSize : 0; } - earcutLinked( outerNode, triangles, dim, minX, minY, invSize ); + earcutLinked( outerNode, triangles, dim, minX, minY, invSize, 0 ); return triangles; @@ -34170,9 +34609,9 @@ function earcutLinked( ear, triangles, dim, minX, minY, invSize, pass ) { 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 ); + triangles.push( prev.i / dim | 0 ); + triangles.push( ear.i / dim | 0 ); + triangles.push( next.i / dim | 0 ); removeNode( ear ); @@ -34227,11 +34666,19 @@ function isEar( ear ) { 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 - let p = ear.next.next; + const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y; + + // triangle bbox; min & max are calculated like this for speed + const x0 = ax < bx ? ( ax < cx ? ax : cx ) : ( bx < cx ? bx : cx ), + y0 = ay < by ? ( ay < cy ? ay : cy ) : ( by < cy ? by : cy ), + x1 = ax > bx ? ( ax > cx ? ax : cx ) : ( bx > cx ? bx : cx ), + y1 = ay > by ? ( ay > cy ? ay : cy ) : ( by > cy ? by : cy ); - while ( p !== ear.prev ) { + let p = c.next; + while ( p !== a ) { - if ( pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && + if ( p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && + pointInTriangle( ax, ay, bx, by, cx, cy, p.x, p.y ) && area( p.prev, p, p.next ) >= 0 ) return false; p = p.next; @@ -34249,15 +34696,17 @@ function isEarHashed( ear, minX, minY, invSize ) { if ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear + const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y; + // triangle bbox; min & max are calculated like this for speed - const 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 ); + const x0 = ax < bx ? ( ax < cx ? ax : cx ) : ( bx < cx ? bx : cx ), + y0 = ay < by ? ( ay < cy ? ay : cy ) : ( by < cy ? by : cy ), + x1 = ax > bx ? ( ax > cx ? ax : cx ) : ( bx > cx ? bx : cx ), + y1 = ay > by ? ( ay > cy ? ay : cy ) : ( by > cy ? by : cy ); // z-order range for the current triangle bbox; - const minZ = zOrder( minTX, minTY, minX, minY, invSize ), - maxZ = zOrder( maxTX, maxTY, minX, minY, invSize ); + const minZ = zOrder( x0, y0, minX, minY, invSize ), + maxZ = zOrder( x1, y1, minX, minY, invSize ); let p = ear.prevZ, n = ear.nextZ; @@ -34265,14 +34714,12 @@ function isEarHashed( ear, minX, minY, invSize ) { // look for points inside the triangle in both directions 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; + if ( p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && + pointInTriangle( ax, ay, bx, by, cx, cy, 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; + if ( n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && + pointInTriangle( ax, ay, bx, by, cx, cy, n.x, n.y ) && area( n.prev, n, n.next ) >= 0 ) return false; n = n.nextZ; } @@ -34280,9 +34727,8 @@ function isEarHashed( ear, minX, minY, invSize ) { // 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; + if ( p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && + pointInTriangle( ax, ay, bx, by, cx, cy, p.x, p.y ) && area( p.prev, p, p.next ) >= 0 ) return false; p = p.prevZ; } @@ -34290,9 +34736,8 @@ function isEarHashed( ear, minX, minY, invSize ) { // look for remaining points in increasing z-order 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; + if ( n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && + pointInTriangle( ax, ay, bx, by, cx, cy, n.x, n.y ) && area( n.prev, n, n.next ) >= 0 ) return false; n = n.nextZ; } @@ -34312,9 +34757,9 @@ function cureLocalIntersections( start, triangles, dim ) { 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 ); + triangles.push( a.i / dim | 0 ); + triangles.push( p.i / dim | 0 ); + triangles.push( b.i / dim | 0 ); // remove two nodes involved removeNode( p ); @@ -34352,8 +34797,8 @@ function splitEarcut( start, triangles, dim, minX, minY, invSize ) { c = filterPoints( c, c.next ); // run earcut on each half - earcutLinked( a, triangles, dim, minX, minY, invSize ); - earcutLinked( c, triangles, dim, minX, minY, invSize ); + earcutLinked( a, triangles, dim, minX, minY, invSize, 0 ); + earcutLinked( c, triangles, dim, minX, minY, invSize, 0 ); return; } @@ -34389,8 +34834,7 @@ function eliminateHoles( data, holeIndices, outerNode, dim ) { // process holes from left to right for ( i = 0; i < queue.length; i ++ ) { - eliminateHole( queue[ i ], outerNode ); - outerNode = filterPoints( outerNode, outerNode.next ); + outerNode = eliminateHole( queue[ i ], outerNode ); } @@ -34407,26 +34851,29 @@ function compareX( a, b ) { // find a bridge between vertices that connects hole with an outer ring and link it function eliminateHole( hole, outerNode ) { - outerNode = findHoleBridge( hole, outerNode ); - if ( outerNode ) { + const bridge = findHoleBridge( hole, outerNode ); + if ( ! bridge ) { - const b = splitPolygon( outerNode, hole ); - - // filter collinear points around the cuts - filterPoints( outerNode, outerNode.next ); - filterPoints( b, b.next ); + return outerNode; } + const bridgeReverse = splitPolygon( bridge, hole ); + + // filter collinear points around the cuts + filterPoints( bridgeReverse, bridgeReverse.next ); + return filterPoints( bridge, bridge.next ); + } // David Eberly's algorithm for finding a bridge between hole and outer polygon function findHoleBridge( hole, outerNode ) { - let p = outerNode; - const hx = hole.x; - const hy = hole.y; - let qx = - Infinity, m; + let p = outerNode, + qx = - Infinity, + m; + + const hx = hole.x, hy = hole.y; // 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 @@ -34438,14 +34885,8 @@ function findHoleBridge( hole, outerNode ) { if ( x <= hx && x > qx ) { qx = x; - if ( x === hx ) { - - if ( hy === p.y ) return p; - if ( hy === p.next.y ) return p.next; - - } - m = p.x < p.next.x ? p : p.next; + if ( x === hx ) return m; // hole touches outer segment; pick leftmost endpoint } @@ -34457,8 +34898,6 @@ function findHoleBridge( hole, outerNode ) { 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 @@ -34507,7 +34946,7 @@ function indexCurve( start, minX, minY, invSize ) { let p = start; do { - if ( p.z === null ) p.z = zOrder( p.x, p.y, minX, minY, invSize ); + if ( p.z === 0 ) p.z = zOrder( p.x, p.y, minX, minY, invSize ); p.prevZ = p.prev; p.nextZ = p.next; p = p.next; @@ -34591,8 +35030,8 @@ function sortLinked( list ) { 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 - minX ) * invSize | 0; + y = ( y - minY ) * invSize | 0; x = ( x | ( x << 8 ) ) & 0x00FF00FF; x = ( x | ( x << 4 ) ) & 0x0F0F0F0F; @@ -34627,19 +35066,19 @@ function getLeftmost( start ) { // check if a point lies within a convex triangle 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; + return ( cx - px ) * ( ay - py ) >= ( ax - px ) * ( cy - py ) && + ( ax - px ) * ( by - py ) >= ( bx - px ) * ( ay - py ) && + ( bx - px ) * ( cy - py ) >= ( cx - px ) * ( by - py ); } // check if a diagonal between two polygon nodes is valid (lies in polygon interior) function isValidDiagonal( a, b ) { - return a.next.i !== b.i && a.prev.i !== b.i && ! intersectsPolygon( a, b ) && // doesn'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 + 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 } @@ -34696,7 +35135,7 @@ function intersectsPolygon( a, b ) { 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; + intersects( p, p.next, a, b ) ) return true; p = p.next; } while ( p !== a ); @@ -34724,7 +35163,7 @@ function middleInside( a, b ) { 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 ) ) + ( px < ( p.next.x - p.x ) * ( py - p.y ) / ( p.next.y - p.y ) + p.x ) ) inside = ! inside; p = p.next; @@ -34806,7 +35245,7 @@ function Node( i, x, y ) { this.next = null; // z-order curve value - this.z = null; + this.z = 0; // previous and next nodes in z-order this.prevZ = null; @@ -36004,7 +36443,7 @@ class ShapeGeometry extends BufferGeometry { } - // incides + // indices for ( let i = 0, l = faces.length; i < l; i ++ ) { @@ -36804,44 +37243,25 @@ function isUniqueEdge( start, end, edges ) { var Geometries = /*#__PURE__*/Object.freeze({ __proto__: null, BoxGeometry: BoxGeometry, - BoxBufferGeometry: BoxGeometry, CapsuleGeometry: CapsuleGeometry, - CapsuleBufferGeometry: CapsuleGeometry, CircleGeometry: CircleGeometry, - CircleBufferGeometry: CircleGeometry, ConeGeometry: ConeGeometry, - ConeBufferGeometry: ConeGeometry, CylinderGeometry: CylinderGeometry, - CylinderBufferGeometry: CylinderGeometry, DodecahedronGeometry: DodecahedronGeometry, - DodecahedronBufferGeometry: DodecahedronGeometry, EdgesGeometry: EdgesGeometry, ExtrudeGeometry: ExtrudeGeometry, - ExtrudeBufferGeometry: ExtrudeGeometry, IcosahedronGeometry: IcosahedronGeometry, - IcosahedronBufferGeometry: IcosahedronGeometry, LatheGeometry: LatheGeometry, - LatheBufferGeometry: LatheGeometry, OctahedronGeometry: OctahedronGeometry, - OctahedronBufferGeometry: OctahedronGeometry, PlaneGeometry: PlaneGeometry, - PlaneBufferGeometry: PlaneGeometry, PolyhedronGeometry: PolyhedronGeometry, - PolyhedronBufferGeometry: PolyhedronGeometry, RingGeometry: RingGeometry, - RingBufferGeometry: RingGeometry, ShapeGeometry: ShapeGeometry, - ShapeBufferGeometry: ShapeGeometry, SphereGeometry: SphereGeometry, - SphereBufferGeometry: SphereGeometry, TetrahedronGeometry: TetrahedronGeometry, - TetrahedronBufferGeometry: TetrahedronGeometry, TorusGeometry: TorusGeometry, - TorusBufferGeometry: TorusGeometry, TorusKnotGeometry: TorusKnotGeometry, - TorusKnotBufferGeometry: TorusKnotGeometry, TubeGeometry: TubeGeometry, - TubeBufferGeometry: TubeGeometry, WireframeGeometry: WireframeGeometry }); @@ -37062,7 +37482,7 @@ class MeshPhysicalMaterial extends MeshStandardMaterial { this.thickness = 0; this.thicknessMap = null; - this.attenuationDistance = 0.0; + this.attenuationDistance = Infinity; this.attenuationColor = new Color( 1, 1, 1 ); this.specularIntensity = 1.0; @@ -37492,6 +37912,17 @@ class MeshLambertMaterial extends Material { 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; @@ -37506,6 +37937,8 @@ class MeshLambertMaterial extends Material { this.wireframeLinecap = 'round'; this.wireframeLinejoin = 'round'; + this.flatShading = false; + this.fog = true; this.setValues( parameters ); @@ -37530,6 +37963,17 @@ class MeshLambertMaterial extends Material { 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; @@ -37544,6 +37988,8 @@ class MeshLambertMaterial extends Material { this.wireframeLinecap = source.wireframeLinecap; this.wireframeLinejoin = source.wireframeLinejoin; + this.flatShading = source.flatShading; + this.fog = source.fog; return this; @@ -39824,7 +40270,10 @@ class FileLoader extends Loader { const callbacks = loading[ url ]; const reader = response.body.getReader(); - const contentLength = response.headers.get( 'Content-Length' ); + + // Nginx needs X-File-Size check + // https://serverfault.com/questions/482875/why-does-nginx-remove-content-length-header-for-chunked-content + const contentLength = response.headers.get( 'Content-Length' ) || response.headers.get( 'X-File-Size' ); const total = contentLength ? parseInt( contentLength ) : 0; const lengthComputable = total !== 0; let loaded = 0; @@ -40610,8 +41059,7 @@ class LightShadow { 0.0, 0.0, 0.0, 1.0 ); - shadowMatrix.multiply( shadowCamera.projectionMatrix ); - shadowMatrix.multiply( shadowCamera.matrixWorldInverse ); + shadowMatrix.multiply( _projScreenMatrix$1 ); } @@ -40727,7 +41175,7 @@ class SpotLightShadow extends LightShadow { class SpotLight extends Light { - constructor( color, intensity, distance = 0, angle = Math.PI / 3, penumbra = 0, decay = 1 ) { + constructor( color, intensity, distance = 0, angle = Math.PI / 3, penumbra = 0, decay = 2 ) { super( color, intensity ); @@ -40743,7 +41191,9 @@ class SpotLight extends Light { this.distance = distance; this.angle = angle; this.penumbra = penumbra; - this.decay = decay; // for physically correct lights, should be 2. + this.decay = decay; + + this.map = null; this.shadow = new SpotLightShadow(); @@ -40879,7 +41329,7 @@ class PointLightShadow extends LightShadow { class PointLight extends Light { - constructor( color, intensity, distance = 0, decay = 1 ) { + constructor( color, intensity, distance = 0, decay = 2 ) { super( color, intensity ); @@ -40888,7 +41338,7 @@ class PointLight extends Light { this.type = 'PointLight'; this.distance = distance; - this.decay = decay; // for physically correct lights, should be 2. + this.decay = decay; this.shadow = new PointLightShadow(); @@ -41528,6 +41978,7 @@ class MaterialLoader extends Loader { 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.glslVersion !== undefined ) material.glslVersion = json.glslVersion; if ( json.extensions !== undefined ) { @@ -41539,10 +41990,6 @@ class MaterialLoader extends Loader { } - // Deprecated - - if ( json.shading !== undefined ) material.flatShading = json.shading === 1; // THREE.FlatShading - // for PointsMaterial if ( json.size !== undefined ) material.size = json.size; @@ -41755,15 +42202,9 @@ class InstancedBufferGeometry extends BufferGeometry { } - clone() { - - return new this.constructor().copy( this ); - - } - toJSON() { - const data = super.toJSON( this ); + const data = super.toJSON(); data.instanceCount = this.instanceCount; @@ -42027,6 +42468,8 @@ class ObjectLoader extends Loader { if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) { + if ( onError !== undefined ) onError( new Error( 'THREE.ObjectLoader: Can\'t load ' + url ) ); + console.error( 'THREE.ObjectLoader: Can\'t load ' + url ); return; @@ -42201,13 +42644,6 @@ class ObjectLoader extends Loader { case 'InstancedBufferGeometry': geometry = bufferGeometryLoader.parse( data ); - - break; - - case 'Geometry': - - console.error( 'THREE.ObjectLoader: The legacy Geometry type is no longer supported.' ); - break; default: @@ -42253,40 +42689,14 @@ class ObjectLoader extends Loader { const data = json[ i ]; - if ( data.type === 'MultiMaterial' ) { + if ( cache[ data.uuid ] === undefined ) { - // Deprecated - - const array = []; - - for ( let j = 0; j < data.materials.length; j ++ ) { - - const material = data.materials[ j ]; - - if ( cache[ material.uuid ] === undefined ) { - - cache[ material.uuid ] = loader.parse( material ); - - } - - array.push( cache[ material.uuid ] ); - - } - - materials[ data.uuid ] = array; - - } else { - - if ( cache[ data.uuid ] === undefined ) { - - cache[ data.uuid ] = loader.parse( data ); - - } - - materials[ data.uuid ] = cache[ data.uuid ]; + cache[ data.uuid ] = loader.parse( data ); } + materials[ data.uuid ] = cache[ data.uuid ]; + } } @@ -42739,6 +43149,8 @@ class ObjectLoader extends Loader { } + if ( data.backgroundBlurriness !== undefined ) object.backgroundBlurriness = data.backgroundBlurriness; + break; case 'PerspectiveCamera': @@ -42973,7 +43385,7 @@ class ObjectLoader extends Loader { if ( child !== undefined ) { - object.addLevel( child, level.distance ); + object.addLevel( child, level.distance, level.hysteresis ); } @@ -43134,9 +43546,9 @@ class ImageBitmapLoader extends Loader { let _context; -const AudioContext = { +class AudioContext { - getContext: function () { + static getContext() { if ( _context === undefined ) { @@ -43146,15 +43558,15 @@ const AudioContext = { return _context; - }, + } - setContext: function ( value ) { + static setContext( value ) { _context = value; } -}; +} class AudioLoader extends Loader { @@ -44458,7 +44870,7 @@ const _trackRe = new RegExp( '' + '$' ); -const _supportedObjectNames = [ 'material', 'materials', 'bones' ]; +const _supportedObjectNames = [ 'material', 'materials', 'bones', 'map' ]; class Composite { @@ -44922,6 +45334,32 @@ class PropertyBinding { break; + case 'map': + + if ( 'map' in targetObject ) { + + targetObject = targetObject.map; + break; + + } + + if ( ! targetObject.material ) { + + console.error( 'THREE.PropertyBinding: Can not bind to material as node does not have a material.', this ); + return; + + } + + if ( ! targetObject.material.map ) { + + console.error( 'THREE.PropertyBinding: Can not bind to material.map as node.material does not have a map.', this ); + return; + + } + + targetObject = targetObject.material.map; + break; + default: if ( targetObject[ objectName ] === undefined ) { @@ -45837,14 +46275,15 @@ class AnimationAction { const timeRunning = ( time - startTime ) * timeDirection; if ( timeRunning < 0 || timeDirection === 0 ) { - return; // yet to come / don't decide when delta = 0 + deltaTime = 0; - } + } else { - // start - this._startTime = null; // unschedule - deltaTime = timeDirection * timeRunning; + this._startTime = null; // unschedule + deltaTime = timeDirection * timeRunning; + + } } @@ -46956,13 +47395,6 @@ class Uniform { constructor( value ) { - if ( typeof value === 'string' ) { - - console.warn( 'THREE.Uniform: Type parameter is no longer needed.' ); - value = arguments[ 1 ]; - - } - this.value = value; } @@ -47734,13 +48166,14 @@ class SpotLightHelper extends Object3D { super(); this.light = light; - this.light.updateMatrixWorld(); this.matrix = light.matrixWorld; this.matrixAutoUpdate = false; this.color = color; + this.type = 'SpotLightHelper'; + const geometry = new BufferGeometry(); const positions = [ @@ -47783,7 +48216,8 @@ class SpotLightHelper extends Object3D { update() { - this.light.updateMatrixWorld(); + this.light.updateWorldMatrix( true, false ); + this.light.target.updateWorldMatrix( true, false ); const coneLength = this.light.distance ? this.light.distance : 1000; const coneWidth = coneLength * Math.tan( this.light.angle ); @@ -47896,6 +48330,13 @@ class SkeletonHelper extends LineSegments { } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + + } + } @@ -47929,7 +48370,6 @@ class PointLightHelper extends Mesh { super( geometry, material ); this.light = light; - this.light.updateMatrixWorld(); this.color = color; @@ -47975,6 +48415,8 @@ class PointLightHelper extends Mesh { update() { + this.light.updateWorldMatrix( true, false ); + if ( this.color !== undefined ) { this.material.color.set( this.color ); @@ -48015,13 +48457,14 @@ class HemisphereLightHelper extends Object3D { super(); this.light = light; - this.light.updateMatrixWorld(); this.matrix = light.matrixWorld; this.matrixAutoUpdate = false; this.color = color; + this.type = 'HemisphereLightHelper'; + const geometry = new OctahedronGeometry( size ); geometry.rotateY( Math.PI * 0.5 ); @@ -48073,6 +48516,8 @@ class HemisphereLightHelper extends Object3D { } + this.light.updateWorldMatrix( true, false ); + mesh.lookAt( _vector$1.setFromMatrixPosition( this.light.matrixWorld ).negate() ); } @@ -48118,11 +48563,18 @@ class GridHelper extends LineSegments { } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + + } + } class PolarGridHelper extends LineSegments { - constructor( radius = 10, radials = 16, circles = 8, divisions = 64, color1 = 0x444444, color2 = 0x888888 ) { + constructor( radius = 10, sectors = 16, rings = 8, divisions = 64, color1 = 0x444444, color2 = 0x888888 ) { color1 = new Color( color1 ); color2 = new Color( color2 ); @@ -48130,32 +48582,36 @@ class PolarGridHelper extends LineSegments { const vertices = []; const colors = []; - // create the radials + // create the sectors - for ( let i = 0; i <= radials; i ++ ) { + if ( sectors > 1 ) { - const v = ( i / radials ) * ( Math.PI * 2 ); + for ( let i = 0; i < sectors; i ++ ) { - const x = Math.sin( v ) * radius; - const z = Math.cos( v ) * radius; + const v = ( i / sectors ) * ( Math.PI * 2 ); - vertices.push( 0, 0, 0 ); - vertices.push( x, 0, z ); + const x = Math.sin( v ) * radius; + const z = Math.cos( v ) * radius; - const color = ( i & 1 ) ? color1 : color2; + vertices.push( 0, 0, 0 ); + vertices.push( x, 0, z ); - colors.push( color.r, color.g, color.b ); - colors.push( color.r, color.g, color.b ); + const color = ( i & 1 ) ? color1 : color2; + + colors.push( color.r, color.g, color.b ); + colors.push( color.r, color.g, color.b ); + + } } - // create the circles + // create the rings - for ( let i = 0; i <= circles; i ++ ) { + for ( let i = 0; i < rings; i ++ ) { const color = ( i & 1 ) ? color1 : color2; - const r = radius - ( radius / circles * i ); + const r = radius - ( radius / rings * i ); for ( let j = 0; j < divisions; j ++ ) { @@ -48195,6 +48651,13 @@ class PolarGridHelper extends LineSegments { } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + + } + } const _v1 = /*@__PURE__*/ new Vector3(); @@ -48208,13 +48671,14 @@ class DirectionalLightHelper extends Object3D { super(); this.light = light; - this.light.updateMatrixWorld(); this.matrix = light.matrixWorld; this.matrixAutoUpdate = false; this.color = color; + this.type = 'DirectionalLightHelper'; + if ( size === undefined ) size = 1; let geometry = new BufferGeometry(); @@ -48252,6 +48716,9 @@ class DirectionalLightHelper extends Object3D { update() { + this.light.updateWorldMatrix( true, false ); + this.light.target.updateWorldMatrix( true, false ); + _v1.setFromMatrixPosition( this.light.matrixWorld ); _v2.setFromMatrixPosition( this.light.target.matrixWorld ); _v3.subVectors( _v2, _v1 ); @@ -48612,7 +49079,6 @@ class BoxHelper extends LineSegments { this.geometry.computeBoundingSphere(); - } setFromObject( object ) { @@ -48634,6 +49100,13 @@ class BoxHelper extends LineSegments { } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + + } + } class Box3Helper extends LineSegments { @@ -48676,6 +49149,13 @@ class Box3Helper extends LineSegments { } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + + } + } class PlaneHelper extends Line { @@ -48722,6 +49202,15 @@ class PlaneHelper extends Line { } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + this.children[ 0 ].geometry.dispose(); + this.children[ 0 ].material.dispose(); + + } + } const _axis = /*@__PURE__*/ new Vector3(); @@ -48815,6 +49304,15 @@ class ArrowHelper extends Object3D { } + dispose() { + + this.line.geometry.dispose(); + this.line.material.dispose(); + this.cone.geometry.dispose(); + this.cone.material.dispose(); + + } + } class AxesHelper extends LineSegments { @@ -48932,7 +49430,7 @@ class ShapePath { } - toShapes( isCCW, noHoles ) { + toShapes( isCCW ) { function toShapesNoHoles( inSubpaths ) { @@ -49018,9 +49516,6 @@ class ShapePath { const subPaths = this.subPaths; if ( subPaths.length === 0 ) return []; - if ( noHoles === true ) return toShapesNoHoles( subPaths ); - - let solid, tmpPath, tmpShape; const shapes = []; @@ -49334,91 +49829,297 @@ var DataUtils = /*#__PURE__*/Object.freeze({ fromHalfFloat: fromHalfFloat }); -// r133, c5bb5434555a3c3ddd784944a0a124f996fc721b +// r134, d65e0af06644fe5a84a6fc0e372f4318f95a04c0 -class ParametricGeometry extends BufferGeometry { +function ImmediateRenderObject() { - constructor() { + console.error( 'THREE.ImmediateRenderObject has been removed.' ); - console.error( 'THREE.ParametricGeometry has been moved to /examples/jsm/geometries/ParametricGeometry.js' ); - super(); +} + +// r138, 48b05d3500acc084df50be9b4c90781ad9b8cb17 + +class WebGLMultisampleRenderTarget extends WebGLRenderTarget { + + constructor( width, height, options ) { + + console.error( 'THREE.WebGLMultisampleRenderTarget has been removed. Use a normal render target and set the "samples" property to greater 0 to enable multisampling.' ); + super( width, height, options ); + this.samples = 4; } } -// r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 +// r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce -class TextGeometry extends BufferGeometry { +class DataTexture2DArray extends DataArrayTexture { - constructor() { + constructor( data, width, height, depth ) { - console.error( 'THREE.TextGeometry has been moved to /examples/jsm/geometries/TextGeometry.js' ); - super(); + console.warn( 'THREE.DataTexture2DArray has been renamed to DataArrayTexture.' ); + super( data, width, height, depth ); } } -// r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 +// r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce + +class DataTexture3D extends Data3DTexture { + + constructor( data, width, height, depth ) { -function FontLoader() { + console.warn( 'THREE.DataTexture3D has been renamed to Data3DTexture.' ); + super( data, width, height, depth ); - console.error( 'THREE.FontLoader has been moved to /examples/jsm/loaders/FontLoader.js' ); + } } -// r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 +// r144 + +class BoxBufferGeometry extends BoxGeometry { + + constructor( width, height, depth, widthSegments, heightSegments, depthSegments ) { -function Font() { + console.warn( 'THREE.BoxBufferGeometry has been renamed to THREE.BoxGeometry.' ); + super( width, height, depth, widthSegments, heightSegments, depthSegments ); - console.error( 'THREE.Font has been moved to /examples/jsm/loaders/FontLoader.js' ); + + } } -// r134, d65e0af06644fe5a84a6fc0e372f4318f95a04c0 +// r144 -function ImmediateRenderObject() { +class CapsuleBufferGeometry extends CapsuleGeometry { - console.error( 'THREE.ImmediateRenderObject has been removed.' ); + constructor( radius, length, capSegments, radialSegments ) { + + console.warn( 'THREE.CapsuleBufferGeometry has been renamed to THREE.CapsuleGeometry.' ); + super( radius, length, capSegments, radialSegments ); + + } } -// r138, 48b05d3500acc084df50be9b4c90781ad9b8cb17 +// r144 -class WebGLMultisampleRenderTarget extends WebGLRenderTarget { +class CircleBufferGeometry extends CircleGeometry { - constructor( width, height, options ) { + constructor( radius, segments, thetaStart, thetaLength ) { - console.error( 'THREE.WebGLMultisampleRenderTarget has been removed. Use a normal render target and set the "samples" property to greater 0 to enable multisampling.' ); - super( width, height, options ); - this.samples = 4; + console.warn( 'THREE.CircleBufferGeometry has been renamed to THREE.CircleGeometry.' ); + super( radius, segments, thetaStart, thetaLength ); } } -// r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce +// r144 -class DataTexture2DArray extends DataArrayTexture { +class ConeBufferGeometry extends ConeGeometry { - constructor( data, width, height, depth ) { + constructor( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { - console.warn( 'THREE.DataTexture2DArray has been renamed to DataArrayTexture.' ); - super( data, width, height, depth ); + console.warn( 'THREE.ConeBufferGeometry has been renamed to THREE.ConeGeometry.' ); + super( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ); } } -// r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce +// r144 -class DataTexture3D extends Data3DTexture { +class CylinderBufferGeometry extends CylinderGeometry { - constructor( data, width, height, depth ) { + constructor( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { - console.warn( 'THREE.DataTexture3D has been renamed to Data3DTexture.' ); - super( data, width, height, depth ); + console.warn( 'THREE.CylinderBufferGeometry has been renamed to THREE.CylinderGeometry.' ); + super( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ); + + } + +} + +// r144 + +class DodecahedronBufferGeometry extends DodecahedronGeometry { + + constructor( radius, detail ) { + + console.warn( 'THREE.DodecahedronBufferGeometry has been renamed to THREE.DodecahedronGeometry.' ); + super( radius, detail ); + + } + +} + +// r144 + +class ExtrudeBufferGeometry extends ExtrudeGeometry { + + constructor( shapes, options ) { + + console.warn( 'THREE.ExtrudeBufferGeometry has been renamed to THREE.ExtrudeGeometry.' ); + super( shapes, options ); + + } + +} + +// r144 + +class IcosahedronBufferGeometry extends IcosahedronGeometry { + + constructor( radius, detail ) { + + console.warn( 'THREE.IcosahedronBufferGeometry has been renamed to THREE.IcosahedronGeometry.' ); + super( radius, detail ); + + } + +} + +// r144 + +class LatheBufferGeometry extends LatheGeometry { + + constructor( points, segments, phiStart, phiLength ) { + + console.warn( 'THREE.LatheBufferGeometry has been renamed to THREE.LatheGeometry.' ); + super( points, segments, phiStart, phiLength ); + + } + +} + +// r144 + +class OctahedronBufferGeometry extends OctahedronGeometry { + + constructor( radius, detail ) { + + console.warn( 'THREE.OctahedronBufferGeometry has been renamed to THREE.OctahedronGeometry.' ); + super( radius, detail ); + + } + +} + +// r144 + +class PlaneBufferGeometry extends PlaneGeometry { + + constructor( width, height, widthSegments, heightSegments ) { + + console.warn( 'THREE.PlaneBufferGeometry has been renamed to THREE.PlaneGeometry.' ); + super( width, height, widthSegments, heightSegments ); + + } + +} + +// r144 + +class PolyhedronBufferGeometry extends PolyhedronGeometry { + + constructor( vertices, indices, radius, detail ) { + + console.warn( 'THREE.PolyhedronBufferGeometry has been renamed to THREE.PolyhedronGeometry.' ); + super( vertices, indices, radius, detail ); + + } + +} + +// r144 + +class RingBufferGeometry extends RingGeometry { + + constructor( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) { + + console.warn( 'THREE.RingBufferGeometry has been renamed to THREE.RingGeometry.' ); + super( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ); + + } + +} + +// r144 + +class ShapeBufferGeometry extends ShapeGeometry { + + constructor( shapes, curveSegments ) { + + console.warn( 'THREE.ShapeBufferGeometry has been renamed to THREE.ShapeGeometry.' ); + super( shapes, curveSegments ); + + } + +} + +// r144 + +class SphereBufferGeometry extends SphereGeometry { + + constructor( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) { + + console.warn( 'THREE.SphereBufferGeometry has been renamed to THREE.SphereGeometry.' ); + super( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ); + + } + +} + +// r144 + +class TetrahedronBufferGeometry extends TetrahedronGeometry { + + constructor( radius, detail ) { + + console.warn( 'THREE.TetrahedronBufferGeometry has been renamed to THREE.TetrahedronGeometry.' ); + super( radius, detail ); + + } + +} + +// r144 + +class TorusBufferGeometry extends TorusGeometry { + + constructor( radius, tube, radialSegments, tubularSegments, arc ) { + + console.warn( 'THREE.TorusBufferGeometry has been renamed to THREE.TorusGeometry.' ); + super( radius, tube, radialSegments, tubularSegments, arc ); + + } + +} + +// r144 + +class TorusKnotBufferGeometry extends TorusKnotGeometry { + + constructor( radius, tube, tubularSegments, radialSegments, p, q ) { + + console.warn( 'THREE.TorusKnotBufferGeometry has been renamed to THREE.TorusKnotGeometry.' ); + super( radius, tube, tubularSegments, radialSegments, p, q ); + + } + +} + +// r144 + +class TubeBufferGeometry extends TubeGeometry { + + constructor( path, tubularSegments, radius, radialSegments, closed ) { + + console.warn( 'THREE.TubeBufferGeometry has been renamed to THREE.TubeGeometry.' ); + super( path, tubularSegments, radius, radialSegments, closed ); } @@ -49446,4 +50147,4 @@ if ( typeof window !== 'undefined' ) { } -export { ACESFilmicToneMapping, AddEquation, AddOperation, AdditiveAnimationBlendMode, AdditiveBlending, AlphaFormat, AlwaysDepth, AlwaysStencilFunc, AmbientLight, AmbientLightProbe, AnimationClip, AnimationLoader, AnimationMixer, AnimationObjectGroup, AnimationUtils, ArcCurve, ArrayCamera, ArrowHelper, Audio, AudioAnalyser, AudioContext, AudioListener, AudioLoader, AxesHelper, BackSide, BasicDepthPacking, BasicShadowMap, Bone, BooleanKeyframeTrack, Box2, Box3, Box3Helper, BoxGeometry as BoxBufferGeometry, BoxGeometry, BoxHelper, BufferAttribute, BufferGeometry, BufferGeometryLoader, ByteType, Cache, Camera, CameraHelper, CanvasTexture, CapsuleGeometry as CapsuleBufferGeometry, CapsuleGeometry, CatmullRomCurve3, CineonToneMapping, CircleGeometry as CircleBufferGeometry, CircleGeometry, ClampToEdgeWrapping, Clock, Color, ColorKeyframeTrack, ColorManagement, CompressedTexture, CompressedTextureLoader, ConeGeometry as ConeBufferGeometry, ConeGeometry, CubeCamera, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeTextureLoader, CubeUVReflectionMapping, CubicBezierCurve, CubicBezierCurve3, CubicInterpolant, CullFaceBack, CullFaceFront, CullFaceFrontBack, CullFaceNone, Curve, CurvePath, CustomBlending, CustomToneMapping, CylinderGeometry as CylinderBufferGeometry, CylinderGeometry, Cylindrical, Data3DTexture, DataArrayTexture, DataTexture, DataTexture2DArray, DataTexture3D, DataTextureLoader, DataUtils, DecrementStencilOp, DecrementWrapStencilOp, DefaultLoadingManager, DepthFormat, DepthStencilFormat, DepthTexture, DirectionalLight, DirectionalLightHelper, DiscreteInterpolant, DodecahedronGeometry as DodecahedronBufferGeometry, DodecahedronGeometry, DoubleSide, DstAlphaFactor, DstColorFactor, DynamicCopyUsage, DynamicDrawUsage, DynamicReadUsage, EdgesGeometry, EllipseCurve, EqualDepth, EqualStencilFunc, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, ExtrudeGeometry as ExtrudeBufferGeometry, ExtrudeGeometry, FileLoader, FlatShading, Float16BufferAttribute, Float32BufferAttribute, Float64BufferAttribute, FloatType, Fog, FogExp2, Font, FontLoader, FramebufferTexture, FrontSide, Frustum, GLBufferAttribute, GLSL1, GLSL3, GreaterDepth, GreaterEqualDepth, GreaterEqualStencilFunc, GreaterStencilFunc, GridHelper, Group, HalfFloatType, HemisphereLight, HemisphereLightHelper, HemisphereLightProbe, IcosahedronGeometry as IcosahedronBufferGeometry, IcosahedronGeometry, ImageBitmapLoader, ImageLoader, ImageUtils, ImmediateRenderObject, IncrementStencilOp, IncrementWrapStencilOp, InstancedBufferAttribute, InstancedBufferGeometry, InstancedInterleavedBuffer, InstancedMesh, Int16BufferAttribute, Int32BufferAttribute, Int8BufferAttribute, IntType, InterleavedBuffer, InterleavedBufferAttribute, Interpolant, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, InvertStencilOp, KeepStencilOp, KeyframeTrack, LOD, LatheGeometry as LatheBufferGeometry, LatheGeometry, Layers, LessDepth, LessEqualDepth, LessEqualStencilFunc, LessStencilFunc, Light, LightProbe, Line, Line3, LineBasicMaterial, LineCurve, LineCurve3, LineDashedMaterial, LineLoop, LineSegments, LinearEncoding, LinearFilter, LinearInterpolant, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearSRGBColorSpace, LinearToneMapping, Loader, LoaderUtils, LoadingManager, LoopOnce, LoopPingPong, LoopRepeat, LuminanceAlphaFormat, LuminanceFormat, MOUSE, Material, MaterialLoader, MathUtils, Matrix3, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshDistanceMaterial, MeshLambertMaterial, MeshMatcapMaterial, MeshNormalMaterial, MeshPhongMaterial, MeshPhysicalMaterial, MeshStandardMaterial, MeshToonMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeverDepth, NeverStencilFunc, NoBlending, NoColorSpace, NoToneMapping, NormalAnimationBlendMode, NormalBlending, NotEqualDepth, NotEqualStencilFunc, NumberKeyframeTrack, Object3D, ObjectLoader, ObjectSpaceNormalMap, OctahedronGeometry as OctahedronBufferGeometry, OctahedronGeometry, OneFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OrthographicCamera, PCFShadowMap, PCFSoftShadowMap, PMREMGenerator, ParametricGeometry, Path, PerspectiveCamera, Plane, PlaneGeometry as PlaneBufferGeometry, PlaneGeometry, PlaneHelper, PointLight, PointLightHelper, Points, PointsMaterial, PolarGridHelper, PolyhedronGeometry as PolyhedronBufferGeometry, PolyhedronGeometry, PositionalAudio, PropertyBinding, PropertyMixer, QuadraticBezierCurve, QuadraticBezierCurve3, Quaternion, QuaternionKeyframeTrack, QuaternionLinearInterpolant, REVISION, RGBADepthPacking, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBFormat, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, RawShaderMaterial, Ray, Raycaster, RectAreaLight, RedFormat, RedIntegerFormat, ReinhardToneMapping, RepeatWrapping, ReplaceStencilOp, ReverseSubtractEquation, RingGeometry as RingBufferGeometry, RingGeometry, SRGBColorSpace, Scene, ShaderChunk, ShaderLib, ShaderMaterial, ShadowMaterial, Shape, ShapeGeometry as ShapeBufferGeometry, ShapeGeometry, ShapePath, ShapeUtils, ShortType, Skeleton, SkeletonHelper, SkinnedMesh, SmoothShading, Source, Sphere, SphereGeometry as SphereBufferGeometry, SphereGeometry, Spherical, SphericalHarmonics3, SplineCurve, SpotLight, SpotLightHelper, Sprite, SpriteMaterial, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, StaticCopyUsage, StaticDrawUsage, StaticReadUsage, StereoCamera, StreamCopyUsage, StreamDrawUsage, StreamReadUsage, StringKeyframeTrack, SubtractEquation, SubtractiveBlending, TOUCH, TangentSpaceNormalMap, TetrahedronGeometry as TetrahedronBufferGeometry, TetrahedronGeometry, TextGeometry, Texture, TextureLoader, TorusGeometry as TorusBufferGeometry, TorusGeometry, TorusKnotGeometry as TorusKnotBufferGeometry, TorusKnotGeometry, Triangle, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, TubeGeometry as TubeBufferGeometry, TubeGeometry, UVMapping, Uint16BufferAttribute, Uint32BufferAttribute, Uint8BufferAttribute, Uint8ClampedBufferAttribute, Uniform, UniformsGroup, UniformsLib, UniformsUtils, UnsignedByteType, UnsignedInt248Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShortType, VSMShadowMap, Vector2, Vector3, Vector4, VectorKeyframeTrack, VideoTexture, WebGL1Renderer, WebGL3DRenderTarget, WebGLArrayRenderTarget, WebGLCubeRenderTarget, WebGLMultipleRenderTargets, WebGLMultisampleRenderTarget, WebGLRenderTarget, WebGLRenderer, WebGLUtils, WireframeGeometry, WrapAroundEnding, ZeroCurvatureEnding, ZeroFactor, ZeroSlopeEnding, ZeroStencilOp, _SRGBAFormat, sRGBEncoding }; +export { ACESFilmicToneMapping, AddEquation, AddOperation, AdditiveAnimationBlendMode, AdditiveBlending, AlphaFormat, AlwaysDepth, AlwaysStencilFunc, AmbientLight, AmbientLightProbe, AnimationClip, AnimationLoader, AnimationMixer, AnimationObjectGroup, AnimationUtils, ArcCurve, ArrayCamera, ArrowHelper, Audio, AudioAnalyser, AudioContext, AudioListener, AudioLoader, AxesHelper, BackSide, BasicDepthPacking, BasicShadowMap, Bone, BooleanKeyframeTrack, Box2, Box3, Box3Helper, BoxBufferGeometry, BoxGeometry, BoxHelper, BufferAttribute, BufferGeometry, BufferGeometryLoader, ByteType, Cache, Camera, CameraHelper, CanvasTexture, CapsuleBufferGeometry, CapsuleGeometry, CatmullRomCurve3, CineonToneMapping, CircleBufferGeometry, CircleGeometry, ClampToEdgeWrapping, Clock, Color, ColorKeyframeTrack, ColorManagement, CompressedArrayTexture, CompressedTexture, CompressedTextureLoader, ConeBufferGeometry, ConeGeometry, CubeCamera, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeTextureLoader, CubeUVReflectionMapping, CubicBezierCurve, CubicBezierCurve3, CubicInterpolant, CullFaceBack, CullFaceFront, CullFaceFrontBack, CullFaceNone, Curve, CurvePath, CustomBlending, CustomToneMapping, CylinderBufferGeometry, CylinderGeometry, Cylindrical, Data3DTexture, DataArrayTexture, DataTexture, DataTexture2DArray, DataTexture3D, DataTextureLoader, DataUtils, DecrementStencilOp, DecrementWrapStencilOp, DefaultLoadingManager, DepthFormat, DepthStencilFormat, DepthTexture, DirectionalLight, DirectionalLightHelper, DiscreteInterpolant, DodecahedronBufferGeometry, DodecahedronGeometry, DoubleSide, DstAlphaFactor, DstColorFactor, DynamicCopyUsage, DynamicDrawUsage, DynamicReadUsage, EdgesGeometry, EllipseCurve, EqualDepth, EqualStencilFunc, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, ExtrudeBufferGeometry, ExtrudeGeometry, FileLoader, Float16BufferAttribute, Float32BufferAttribute, Float64BufferAttribute, FloatType, Fog, FogExp2, FramebufferTexture, FrontSide, Frustum, GLBufferAttribute, GLSL1, GLSL3, GreaterDepth, GreaterEqualDepth, GreaterEqualStencilFunc, GreaterStencilFunc, GridHelper, Group, HalfFloatType, HemisphereLight, HemisphereLightHelper, HemisphereLightProbe, IcosahedronBufferGeometry, IcosahedronGeometry, ImageBitmapLoader, ImageLoader, ImageUtils, ImmediateRenderObject, IncrementStencilOp, IncrementWrapStencilOp, InstancedBufferAttribute, InstancedBufferGeometry, InstancedInterleavedBuffer, InstancedMesh, Int16BufferAttribute, Int32BufferAttribute, Int8BufferAttribute, IntType, InterleavedBuffer, InterleavedBufferAttribute, Interpolant, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, InvertStencilOp, KeepStencilOp, KeyframeTrack, LOD, LatheBufferGeometry, LatheGeometry, Layers, LessDepth, LessEqualDepth, LessEqualStencilFunc, LessStencilFunc, Light, LightProbe, Line, Line3, LineBasicMaterial, LineCurve, LineCurve3, LineDashedMaterial, LineLoop, LineSegments, LinearEncoding, LinearFilter, LinearInterpolant, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearSRGBColorSpace, LinearToneMapping, Loader, LoaderUtils, LoadingManager, LoopOnce, LoopPingPong, LoopRepeat, LuminanceAlphaFormat, LuminanceFormat, MOUSE, Material, MaterialLoader, MathUtils, Matrix3, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshDistanceMaterial, MeshLambertMaterial, MeshMatcapMaterial, MeshNormalMaterial, MeshPhongMaterial, MeshPhysicalMaterial, MeshStandardMaterial, MeshToonMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeverDepth, NeverStencilFunc, NoBlending, NoColorSpace, NoToneMapping, NormalAnimationBlendMode, NormalBlending, NotEqualDepth, NotEqualStencilFunc, NumberKeyframeTrack, Object3D, ObjectLoader, ObjectSpaceNormalMap, OctahedronBufferGeometry, OctahedronGeometry, OneFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OrthographicCamera, PCFShadowMap, PCFSoftShadowMap, PMREMGenerator, Path, PerspectiveCamera, Plane, PlaneBufferGeometry, PlaneGeometry, PlaneHelper, PointLight, PointLightHelper, Points, PointsMaterial, PolarGridHelper, PolyhedronBufferGeometry, PolyhedronGeometry, PositionalAudio, PropertyBinding, PropertyMixer, QuadraticBezierCurve, QuadraticBezierCurve3, Quaternion, QuaternionKeyframeTrack, QuaternionLinearInterpolant, REVISION, RGBADepthPacking, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBFormat, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, RawShaderMaterial, Ray, Raycaster, RectAreaLight, RedFormat, RedIntegerFormat, ReinhardToneMapping, RepeatWrapping, ReplaceStencilOp, ReverseSubtractEquation, RingBufferGeometry, RingGeometry, SRGBColorSpace, Scene, ShaderChunk, ShaderLib, ShaderMaterial, ShadowMaterial, Shape, ShapeBufferGeometry, ShapeGeometry, ShapePath, ShapeUtils, ShortType, Skeleton, SkeletonHelper, SkinnedMesh, Source, Sphere, SphereBufferGeometry, SphereGeometry, Spherical, SphericalHarmonics3, SplineCurve, SpotLight, SpotLightHelper, Sprite, SpriteMaterial, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, StaticCopyUsage, StaticDrawUsage, StaticReadUsage, StereoCamera, StreamCopyUsage, StreamDrawUsage, StreamReadUsage, StringKeyframeTrack, SubtractEquation, SubtractiveBlending, TOUCH, TangentSpaceNormalMap, TetrahedronBufferGeometry, TetrahedronGeometry, Texture, TextureLoader, TorusBufferGeometry, TorusGeometry, TorusKnotBufferGeometry, TorusKnotGeometry, Triangle, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, TubeBufferGeometry, TubeGeometry, UVMapping, Uint16BufferAttribute, Uint32BufferAttribute, Uint8BufferAttribute, Uint8ClampedBufferAttribute, Uniform, UniformsGroup, UniformsLib, UniformsUtils, UnsignedByteType, UnsignedInt248Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShortType, VSMShadowMap, Vector2, Vector3, Vector4, VectorKeyframeTrack, VideoTexture, WebGL1Renderer, WebGL3DRenderTarget, WebGLArrayRenderTarget, WebGLCubeRenderTarget, WebGLMultipleRenderTargets, WebGLMultisampleRenderTarget, WebGLRenderTarget, WebGLRenderer, WebGLUtils, WireframeGeometry, WrapAroundEnding, ZeroCurvatureEnding, ZeroFactor, ZeroSlopeEnding, ZeroStencilOp, _SRGBAFormat, sRGBEncoding }; diff --git a/docs/api/en/animation/AnimationAction.html b/docs/api/en/animation/AnimationAction.html index 8cb9337800f57b..006065b733d81e 100644 --- a/docs/api/en/animation/AnimationAction.html +++ b/docs/api/en/animation/AnimationAction.html @@ -27,7 +27,8 @@

[name]( [param:AnimationMixer mixer], [param:AnimationClip clip], [param:Obj

[page:AnimationMixer mixer] - the `AnimationMixer` that is controlled by this action.
[page:AnimationClip clip] - the `AnimationClip` that holds the animation data for this action.
- [page:Object3D localRoot] - the root object on which this action is performed.

+ [page:Object3D localRoot] - the root object on which this action is performed.
+ [page:Number blendMode] - defines how the animation is blended/combined when two or more animations are simultaneously played.

Note: Instead of calling this constructor directly you should instantiate an AnimationAction with [page:AnimationMixer.clipAction] since this method provides caching for better performance. @@ -36,6 +37,11 @@

[name]( [param:AnimationMixer mixer], [param:AnimationClip clip], [param:Obj

Properties

+

[property:Number blendMode]

+

+ Defines how the animation is blended/combined when two or more animations are simultaneously played. + Valid values are *NormalAnimationBlendMode* (default) and *AdditiveAnimationBlendMode*. +

[property:Boolean clampWhenFinished]

diff --git a/docs/api/en/animation/AnimationClip.html b/docs/api/en/animation/AnimationClip.html index f2d2ca45d549dd..389eeb4dcbdaa3 100644 --- a/docs/api/en/animation/AnimationClip.html +++ b/docs/api/en/animation/AnimationClip.html @@ -10,7 +10,7 @@

[name]

- An AnimationClip is a reusable set of keyframe tracks which represent an animation.

+ An [name] is a reusable set of keyframe tracks which represent an animation.

For an overview of the different elements of the three.js animation system see the "Animation System" article in the "Next Steps" section of the manual. @@ -25,7 +25,9 @@

[name]( [param:String name], [param:Number duration], [param:Array tracks] ) [page:String name] - a name for this clip.
[page:Number duration] - the duration of this clip (in seconds). If a negative value is passed, the duration will be calculated from the passed `tracks` array.
- [page:Array tracks] - an array of [page:KeyframeTrack KeyframeTracks].

+ [page:Array tracks] - an array of [page:KeyframeTrack KeyframeTracks].
+ [page:Number blendMode] - defines how the animation is blended/combined when two or more animations are simultaneously played.

+ Note: Instead of instantiating an AnimationClip directly with the constructor, you can use one of its static methods to create AnimationClips: from JSON ([page:.parse parse]), from morph @@ -35,9 +37,13 @@

[name]( [param:String name], [param:Number duration], [param:Array tracks] ) hold AnimationClips in its geometry's animations array.

-

Properties

+

[property:Number blendMode]

+

+ Defines how the animation is blended/combined when two or more animations are simultaneously played. + Valid values are *NormalAnimationBlendMode* (default) and *AdditiveAnimationBlendMode*. +

[property:Number duration]

diff --git a/docs/api/en/animation/AnimationMixer.html b/docs/api/en/animation/AnimationMixer.html index 8716de37ce42dd..8a2405830b4004 100644 --- a/docs/api/en/animation/AnimationMixer.html +++ b/docs/api/en/animation/AnimationMixer.html @@ -81,7 +81,7 @@

[method:this update]([param:Number deltaTimeInSeconds])

Advances the global mixer time and updates the animation.

- This is usually done in the render loop, passing [page:Clock.getDelta clock.getDelta] scaled by the mixer's [page:.timeScale timeScale]). + This is usually done in the render loop, passing [page:Clock.getDelta clock.getDelta] scaled by the mixer's [page:.timeScale timeScale].

[method:this setTime]([param:Number timeInSeconds])

diff --git a/docs/api/en/constants/Animation.html b/docs/api/en/constants/Animation.html index ef778724b467a1..bdb0a6b7be2df4 100644 --- a/docs/api/en/constants/Animation.html +++ b/docs/api/en/constants/Animation.html @@ -29,6 +29,12 @@

Ending Modes

THREE.ZeroCurvatureEnding THREE.ZeroSlopeEnding THREE.WrapAroundEnding + + +

Animation Blend Modes

+ +THREE.NormalAnimationBlendMode +THREE.AdditiveAnimationBlendMode

Source

diff --git a/docs/api/en/constants/Core.html b/docs/api/en/constants/Core.html index 0efef361d04cac..a2e74b73091bc8 100644 --- a/docs/api/en/constants/Core.html +++ b/docs/api/en/constants/Core.html @@ -21,10 +21,13 @@

Revision Number

Color Spaces

+THREE.NoColorSpace THREE.SRGBColorSpace THREE.LinearSRGBColorSpace - +

+ [page:NoColorSpace] defines no specific color space. +

[page:SRGBColorSpace] (“sRGB”) refers to the color space defined by the Rec. 709 primaries, D65 white point, and nonlinear sRGB transfer functions. sRGB is the default color space in @@ -37,7 +40,7 @@

Color Spaces

linear transfer functions. Linear-sRGB is the working color space in three.js, used throughout most of the rendering process. RGB components found in three.js materials and shaders are in the Linear-sRGB color space. - D

+

For further background and usage, see Color management. @@ -48,6 +51,22 @@

Mouse Buttons

THREE.MOUSE.LEFT THREE.MOUSE.MIDDLE THREE.MOUSE.RIGHT +THREE.MOUSE.ROTATE +THREE.MOUSE.DOLLY +THREE.MOUSE.PAN + +

+ The constants LEFT and ROTATE have the same underlying value. + The constants MIDDLE and DOLLY have the same underlying value. + The constants RIGHT and PAN have the same underlying value. +

+ +

Touch Actions

+ +THREE.TOUCH.ROTATE +THREE.TOUCH.PAN +THREE.TOUCH.DOLLY_PAN +THREE.TOUCH.DOLLY_ROTATE

Source

diff --git a/docs/api/en/constants/Materials.html b/docs/api/en/constants/Materials.html index d03aa20bff3f63..3653d57cc0c9fe 100644 --- a/docs/api/en/constants/Materials.html +++ b/docs/api/en/constants/Materials.html @@ -126,6 +126,24 @@

Stencil Operations

[page:Materials InvertStencilOp] will perform a bitwise inversion of the current stencil value.

+

Normal map type

+ + THREE.TangentSpaceNormalMap + THREE.ObjectSpaceNormalMap + +

+ Defines the type of the normal map. + For TangentSpaceNormalMap, the information is relative to the underlying surface. + For ObjectSpaceNormalMap, the information is relative to the object orientation. + Default is [page:Constant TangentSpaceNormalMap]. +

+ +

GLSL Version

+ + THREE.GLSL1 + THREE.GLSL3 + +

Source

diff --git a/docs/api/en/constants/Renderer.html b/docs/api/en/constants/Renderer.html index db6fc5ce78447a..20a31b4e215c96 100644 --- a/docs/api/en/constants/Renderer.html +++ b/docs/api/en/constants/Renderer.html @@ -46,14 +46,17 @@

Tone Mapping

THREE.ReinhardToneMapping THREE.CineonToneMapping THREE.ACESFilmicToneMapping + THREE.CustomToneMapping

These define the WebGLRenderer's [page:WebGLRenderer.toneMapping toneMapping] property. This is used to approximate the appearance of high dynamic range (HDR) on the - low dynamic range medium of a standard computer monitor or mobile device's screen.

- + low dynamic range medium of a standard computer monitor or mobile device's screen. +

+

+ THREE.LinearToneMapping, THREE.ReinhardToneMapping, THREE.CineonToneMapping and THREE.ACESFilmicToneMapping are built-in implementations of tone mapping. + THREE.CustomToneMapping expects a custom implementation by modyfing GLSL code of the material's fragment shader. See the [example:webgl_tonemapping WebGL / tonemapping] example. -

diff --git a/docs/api/en/constants/Textures.html b/docs/api/en/constants/Textures.html index e1ea7fde21e04b..b511e25f252b52 100644 --- a/docs/api/en/constants/Textures.html +++ b/docs/api/en/constants/Textures.html @@ -156,7 +156,9 @@

Formats

[page:constant AlphaFormat] discards the red, green and blue components and reads just the alpha component.

- [page:constant RedFormat] discards the green and blue components and reads just the red component.

+ [page:constant RedFormat] discards the green and blue components and reads just the red component. + (can only be used with a WebGL 2 rendering context). +

[page:constant RedIntegerFormat] discards the green and blue components and reads just the red component. The texels are read as integers instead of floating point. @@ -271,10 +273,19 @@

ASTC Compressed Texture Format

THREE.RGBA_ASTC_12x12_Format

- For use with a [page:CompressedTexture CompressedTexture]'s [page:Texture.format format] property, + For use with a [page:CompressedTexture CompressedTexture]'s [page:Texture.format format] property, these require support for the [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_astc/ WEBGL_compressed_texture_astc] extension.

+

BPTC Compressed Texture Format

+ + THREE.RGBA_BPTC_Format + +

+ For use with a [page:CompressedTexture CompressedTexture]'s [page:Texture.format format] property, + these require support for the [link:https://www.khronos.org/registry/webgl/extensions/EXT_texture_compression_bptc/ EXT_texture_compression_bptc] extension.

+

+

Internal Formats

'ALPHA' diff --git a/docs/api/en/core/BufferAttribute.html b/docs/api/en/core/BufferAttribute.html index a4349cf9645db1..02b3832453f566 100644 --- a/docs/api/en/core/BufferAttribute.html +++ b/docs/api/en/core/BufferAttribute.html @@ -142,18 +142,6 @@

[method:this copyArray]( array )

[method:this copyAt] ( [param:Integer index1], [param:BufferAttribute bufferAttribute], [param:Integer index2] )

Copy a vector from bufferAttribute[index2] to [page:BufferAttribute.array array][index1].

-

[method:this copyColorsArray]( [param:Array colors] )

-

Copy an array representing RGB color values into [page:BufferAttribute.array array].

- -

[method:this copyVector2sArray]( [param:Array vectors] )

-

Copy an array representing [page:Vector2]s into [page:BufferAttribute.array array].

- -

[method:this copyVector3sArray]( [param:Array vectors] )

-

Copy an array representing [page:Vector3]s into [page:BufferAttribute.array array].

- -

[method:this copyVector4sArray]( [param:Array vectors] )

-

Copy an array representing [page:Vector4]s into [page:BufferAttribute.array array].

-

[method:Number getX]( [param:Integer index] )

Returns the x component of the vector at the given index.

diff --git a/docs/api/en/core/BufferGeometry.html b/docs/api/en/core/BufferGeometry.html index eab77948f2d5b9..c9d6d95eb32b50 100644 --- a/docs/api/en/core/BufferGeometry.html +++ b/docs/api/en/core/BufferGeometry.html @@ -170,20 +170,12 @@

Methods

[page:EventDispatcher EventDispatcher] methods are available on this class.

-

[method:this setAttribute]( [param:String name], [param:BufferAttribute attribute] )

-

- Sets an attribute to this geometry. Use this rather than the attributes property, - because an internal hashmap of [page:.attributes] is maintained to speed up iterating over - attributes. -

-

[method:undefined addGroup]( [param:Integer start], [param:Integer count], [param:Integer materialIndex] )

Adds a group to this geometry; see the [page:BufferGeometry.groups groups] property for details.

-

[method:this applyMatrix4]( [param:Matrix4 matrix] )

Applies the matrix transform to the geometry.

@@ -193,15 +185,12 @@

[method:this applyQuaternion]( [param:Quaternion quaternion] )

[method:this center] ()

Center the geometry based on the bounding box.

-

[method:BufferGeometry clone]()

-

Creates a clone of this BufferGeometry.

- -

[method:this copy]( [param:BufferGeometry bufferGeometry] )

-

Copies another BufferGeometry to this BufferGeometry.

-

[method:undefined clearGroups]( )

Clears all groups.

+

[method:BufferGeometry clone]()

+

Creates a clone of this BufferGeometry.

+

[method:undefined computeBoundingBox]()

Computes bounding box of the geometry, updating [page:.boundingBox] attribute.
@@ -224,10 +213,15 @@

[method:undefined computeTangents]()

[method:undefined computeVertexNormals]()

Computes vertex normals by averaging face normals.

+

[method:this copy]( [param:BufferGeometry bufferGeometry] )

+

Copies another BufferGeometry to this BufferGeometry.

+ +

[method:BufferAttribute deleteAttribute]( [param:String name] )

+

Deletes the [page:BufferAttribute attribute] with the specified name.

+

[method:undefined dispose]()

- Disposes the object from memory.
- You need to call this when you want the BufferGeometry removed while the application is running. + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.

[method:BufferAttribute getAttribute]( [param:String name] )

@@ -247,18 +241,12 @@

[method:this lookAt] ( [param:Vector3 vector] )

Use [page:Object3D.lookAt] for typical real-time mesh usage.

-

[method:this merge]( [param:BufferGeometry bufferGeometry], [param:Integer offset] )

-

Merge in another BufferGeometry with an optional offset of where to start merging in.

-

[method:undefined normalizeNormals]()

Every normal vector in a geometry will have a magnitude of 1. This will correct lighting on the geometry surfaces.

-

[method:BufferAttribute deleteAttribute]( [param:String name] )

-

Deletes the [page:BufferAttribute attribute] with the specified name.

-

[method:this rotateX] ( [param:Float radians] )

Rotate the geometry about the X axis. This is typically done as a one time operation, and not during a loop. @@ -283,8 +271,12 @@

[method:this scale] ( [param:Float x], [param:Float y], [param:Float z] ) -

[method:this setIndex] ( [param:BufferAttribute index] )

-

Set the [page:.index] buffer.

+

[method:this setAttribute]( [param:String name], [param:BufferAttribute attribute] )

+

+ Sets an attribute to this geometry. Use this rather than the attributes property, + because an internal hashmap of [page:.attributes] is maintained to speed up iterating over + attributes. +

[method:undefined setDrawRange] ( [param:Integer start], [param:Integer count] )

Set the [page:.drawRange] property. For non-indexed BufferGeometry, count is the number of vertices to render. @@ -293,6 +285,9 @@

[method:undefined setDrawRange] ( [param:Integer start], [param:Integer coun

[method:this setFromPoints] ( [param:Array points] )

Sets the attributes for this BufferGeometry from an array of points.

+

[method:this setIndex] ( [param:BufferAttribute index] )

+

Set the [page:.index] buffer.

+

[method:Object toJSON]()

Convert the buffer geometry to three.js [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format].

diff --git a/docs/api/en/core/InterleavedBuffer.html b/docs/api/en/core/InterleavedBuffer.html index 3f20313cf537b0..4f9fb0b0137f1d 100644 --- a/docs/api/en/core/InterleavedBuffer.html +++ b/docs/api/en/core/InterleavedBuffer.html @@ -84,7 +84,7 @@

[method:this copyAt]( [param:Integer index1], [param:InterleavedBuffer attri

[method:this set]( [param:TypedArray value], [param:Integer offset] )

value - The source (typed) array.
- offset - The offset into the target array at which to begin writing values from the source array. Default is .

+ offset - The offset into the target array at which to begin writing values from the source array. Default is `0`.

Stores multiple values in the buffer, reading input values from a specified array.

diff --git a/docs/api/en/core/Object3D.html b/docs/api/en/core/Object3D.html index 43f98b226dbd67..c2b91134e7889f 100644 --- a/docs/api/en/core/Object3D.html +++ b/docs/api/en/core/Object3D.html @@ -84,6 +84,12 @@

[property:Matrix4 matrixWorld]

the local transform [page:.matrix].

+

[property:Boolean matrixWorldAutoUpdate]

+

+ Default is true. If set, then the renderer checks every frame if the object and its children need matrix updates. + When it isn't, then you have to maintain all matrices in the object and its children yourself. +

+

[property:Boolean matrixWorldNeedsUpdate]

When this is set, it calculates the matrixWorld in that frame and resets this property @@ -318,7 +324,7 @@

[method:undefined lookAt]( [param:Vector3 vector] )
This method does not support objects having non-uniformly-scaled parent(s).

-

[method:Array raycast]( [param:Raycaster raycaster], [param:Array intersects] )

+

[method:undefined raycast]( [param:Raycaster raycaster], [param:Array intersects] )

Abstract (empty) method to get intersections between a casted ray and this object. Subclasses such as [page:Mesh], [page:Line], and [page:Points] implement this method in order @@ -464,7 +470,13 @@

[method:undefined updateMatrix]()

Updates the local transform.

[method:undefined updateMatrixWorld]( [param:Boolean force] )

-

Updates the global transform of the object and its descendants.

+

+ force - A boolean that can be used to bypass [page:.matrixWorldAutoUpdate], + to recalculate the world matrix of the object and descendants on the current frame. + Useful if you cannot wait for the renderer to update it on the next frame (assuming [page:.matrixWorldAutoUpdate] set to `true`).

+ + Updates the global transform of the object and its descendants if the world matrix needs update ([page:.matrixWorldNeedsUpdate] set to true) or if the `force` parameter is set to `true`. +

[method:undefined updateWorldMatrix]( [param:Boolean updateParents], [param:Boolean updateChildren] )

diff --git a/docs/api/en/extras/PMREMGenerator.html b/docs/api/en/extras/PMREMGenerator.html index 56b048b06f44de..879f68046fdea2 100644 --- a/docs/api/en/extras/PMREMGenerator.html +++ b/docs/api/en/extras/PMREMGenerator.html @@ -94,7 +94,7 @@

[method:undefined compileEquirectangularShader]()

[method:undefined dispose]()

- Disposes of the PMREMGenerator's internal memory. + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.

Source

diff --git a/docs/api/en/extras/core/ShapePath.html b/docs/api/en/extras/core/ShapePath.html index 607271e98873df..b22f87f586b868 100644 --- a/docs/api/en/extras/core/ShapePath.html +++ b/docs/api/en/extras/core/ShapePath.html @@ -71,14 +71,13 @@

[method:this splineThru] ( [param:Array points] )

Connects a new [page:SplineCurve] onto the [page:ShapePath.currentPath currentPath].

-

[method:Array toShapes]( [param:Boolean isCCW], [param:Boolean noHoles] )

+

[method:Array toShapes]( [param:Boolean isCCW] )

- isCCW -- Changes how solids and holes are generated
- noHoles -- Whether or not to generate holes + isCCW -- Changes how solids and holes are generated

Converts the [page:ShapePath.subPaths subPaths] array into an array of Shapes. By default solid shapes are defined clockwise (CW) and holes are defined counterclockwise (CCW). If isCCW is set to true, - then those are flipped. If the parameter noHoles is set to true then all paths are set as solid shapes and isCCW is ignored. + then those are flipped.

diff --git a/docs/api/en/helpers/ArrowHelper.html b/docs/api/en/helpers/ArrowHelper.html index 1716b44830426b..c4456435c9ba75 100644 --- a/docs/api/en/helpers/ArrowHelper.html +++ b/docs/api/en/helpers/ArrowHelper.html @@ -82,6 +82,11 @@

[method:undefined setDirection]([param:Vector3 dir])

Sets the direction of the arrowhelper.

+

[method:undefined dispose]()

+

+ Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

+

Source

diff --git a/docs/api/en/helpers/AxesHelper.html b/docs/api/en/helpers/AxesHelper.html index 80da24120f0d9a..befb1a6ce0c9fc 100644 --- a/docs/api/en/helpers/AxesHelper.html +++ b/docs/api/en/helpers/AxesHelper.html @@ -51,7 +51,7 @@

[method:this setColors]( [param:Color xAxisColor], [param:Color yAxisColor],

[method:undefined dispose]()

- Disposes of the internally-created [page:Line.material material] and [page:Line.geometry geometry] used by this helper. + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.

Source

diff --git a/docs/api/en/helpers/Box3Helper.html b/docs/api/en/helpers/Box3Helper.html index 0ad38738c0b3f4..38fcaf46048cc0 100644 --- a/docs/api/en/helpers/Box3Helper.html +++ b/docs/api/en/helpers/Box3Helper.html @@ -56,6 +56,11 @@

[method:undefined updateMatrixWorld]( [param:Boolean force] )

property.

+

[method:undefined dispose]()

+

+ Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

+

Source

diff --git a/docs/api/en/helpers/BoxHelper.html b/docs/api/en/helpers/BoxHelper.html index f041a6a4182505..dd860844beacfa 100644 --- a/docs/api/en/helpers/BoxHelper.html +++ b/docs/api/en/helpers/BoxHelper.html @@ -67,6 +67,11 @@

[method:this setFromObject]( [param:Object3D object] )

Updates the wireframe box for the passed object.

+

[method:undefined dispose]()

+

+ Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

+

Source

diff --git a/docs/api/en/helpers/CameraHelper.html b/docs/api/en/helpers/CameraHelper.html index 8c7a4308a08ea4..587871d379fff7 100644 --- a/docs/api/en/helpers/CameraHelper.html +++ b/docs/api/en/helpers/CameraHelper.html @@ -61,7 +61,7 @@

Methods

[method:undefined dispose]()

- Disposes of the internally-created [page:Line.material material] and [page:Line.geometry geometry] used by this helper. + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.

[method:this setColors]( [param:Color frustum], [param:Color cone], [param:Color up], [param:Color target], [param:Color cross] )

diff --git a/docs/api/en/helpers/DirectionalLightHelper.html b/docs/api/en/helpers/DirectionalLightHelper.html index bed79fd2fa707d..ba90af7d3ee0bc 100644 --- a/docs/api/en/helpers/DirectionalLightHelper.html +++ b/docs/api/en/helpers/DirectionalLightHelper.html @@ -68,7 +68,9 @@

Methods

See the base [page:Object3D] class for common properties.

[method:undefined dispose]()

-

Dispose of the directionalLightHelper.

+

+ Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

[method:undefined update]()

diff --git a/docs/api/en/helpers/GridHelper.html b/docs/api/en/helpers/GridHelper.html index 4d347692d3e9c3..aac2bbe69cdd70 100644 --- a/docs/api/en/helpers/GridHelper.html +++ b/docs/api/en/helpers/GridHelper.html @@ -41,6 +41,14 @@

[name]( [param:number size], [param:Number divisions], [param:Color colorCen Creates a new [name] of size 'size' and divided into 'divisions' segments per side. Colors are optional.

+

Methods

+

See the base [page:LineSegments] class for common methods.

+ +

[method:undefined dispose]()

+

+ Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

+

Source

diff --git a/docs/api/en/helpers/HemisphereLightHelper.html b/docs/api/en/helpers/HemisphereLightHelper.html index 1d7d50ccaf956f..e24cbc09e7969d 100644 --- a/docs/api/en/helpers/HemisphereLightHelper.html +++ b/docs/api/en/helpers/HemisphereLightHelper.html @@ -62,7 +62,9 @@

Methods

See the base [page:Object3D] class for common methods.

[method:undefined dispose]()

-

Dispose of the hemisphereLightHelper.

+

+ Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

[method:undefined update]()

Updates the helper to match the position and direction of the [page:.light].

diff --git a/docs/api/en/helpers/PlaneHelper.html b/docs/api/en/helpers/PlaneHelper.html index 3ea736c9eee634..4a0b00551e1928 100644 --- a/docs/api/en/helpers/PlaneHelper.html +++ b/docs/api/en/helpers/PlaneHelper.html @@ -38,7 +38,7 @@

[name]( [param:Plane plane], [param:Float size], [param:Color hex] )

Properties

-

See the base [page:LineSegments] class for common properties.

+

See the base [page:Line] class for common properties.

[property:Plane plane]

The [page:Plane plane] being visualized.

@@ -57,6 +57,11 @@

[method:undefined updateMatrixWorld]( [param:Boolean force] )

[page:PlaneHelper.size .size] properties.

+

[method:undefined dispose]()

+

+ Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

+

Source

diff --git a/docs/api/en/helpers/PointLightHelper.html b/docs/api/en/helpers/PointLightHelper.html index dd64fd02eb01ba..add4a5e3d65494 100644 --- a/docs/api/en/helpers/PointLightHelper.html +++ b/docs/api/en/helpers/PointLightHelper.html @@ -70,7 +70,9 @@

Methods

See the base [page:Mesh] class for common methods.

[method:undefined dispose]()

-

Dispose of the pointLightHelper.

+

+ Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

[method:undefined update]()

diff --git a/docs/api/en/helpers/PolarGridHelper.html b/docs/api/en/helpers/PolarGridHelper.html index 3e8c7f30c3cd64..7c1959eb69ce7f 100644 --- a/docs/api/en/helpers/PolarGridHelper.html +++ b/docs/api/en/helpers/PolarGridHelper.html @@ -17,11 +17,11 @@

Code Example

const radius = 10; - const radials = 16; - const circles = 8; + const sectors = 16; + const rings = 8; const divisions = 64; - const helper = new THREE.PolarGridHelper( radius, radials, circles, divisions ); + const helper = new THREE.PolarGridHelper( radius, sectors, rings, divisions ); scene.add( helper ); @@ -33,17 +33,25 @@

Examples

Constructor

-

[name]( [param:Number radius], [param:Number radials], [param:Number circles], [param:Number divisions], [param:Color color1], [param:Color color2] )

+

[name]( [param:Number radius], [param:Number sectors], [param:Number rings], [param:Number divisions], [param:Color color1], [param:Color color2] )

radius -- The radius of the polar grid. This can be any positive number. Default is 10.
- radials -- The number of radial lines. This can be any positive integer. Default is 16.
- circles -- The number of circles. This can be any positive integer. Default is 8.
+ sectors -- The number of sectors the grid will be divided into. This can be any positive integer. Default is 16.
+ rings -- The number of rings. This can be any positive integer. Default is 8.
divisions -- The number of line segments used for each circle. This can be any positive integer that is 3 or greater. Default is 64.
color1 -- The first color used for grid elements. This can be a [page:Color], a hexadecimal value and an CSS-Color name. Default is 0x444444
color2 -- The second color used for grid elements. This can be a [page:Color], a hexadecimal value and an CSS-Color name. Default is 0x888888

- Creates a new [name] of radius 'radius' with 'radials' number of radials and 'circles' number of circles, where each circle is smoothed into 'divisions' number of line segments. Colors are optional. + Creates a new [name] of radius 'radius' with 'sectors' number of sectors and 'rings' number of rings, where each circle is smoothed into 'divisions' number of line segments. Colors are optional. +

+ +

Methods

+

See the base [page:LineSegments] class for common methods.

+ +

[method:undefined dispose]()

+

+ Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.

Source

diff --git a/docs/api/en/helpers/SkeletonHelper.html b/docs/api/en/helpers/SkeletonHelper.html index e42cc2cd3a25d6..d8d119383a538d 100644 --- a/docs/api/en/helpers/SkeletonHelper.html +++ b/docs/api/en/helpers/SkeletonHelper.html @@ -57,6 +57,13 @@

[property:Object3D root]

The object passed in the constructor.

+

Methods

+

See the base [page:LineSegments] class for common methods.

+ +

[method:undefined dispose]()

+

+ Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

Source

diff --git a/docs/api/en/helpers/SpotLightHelper.html b/docs/api/en/helpers/SpotLightHelper.html index f78f05f5e0da9f..91538424e26a4a 100644 --- a/docs/api/en/helpers/SpotLightHelper.html +++ b/docs/api/en/helpers/SpotLightHelper.html @@ -66,7 +66,9 @@

Methods

See the base [page:Object3D] class for common methods.

[method:undefined dispose]()

-

Disposes of the light helper.

+

+ Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

[method:undefined update]()

Updates the light helper.

diff --git a/docs/api/en/lights/DirectionalLight.html b/docs/api/en/lights/DirectionalLight.html index f2f309bd7d01da..3abf6627806d0a 100644 --- a/docs/api/en/lights/DirectionalLight.html +++ b/docs/api/en/lights/DirectionalLight.html @@ -124,8 +124,7 @@

Methods

[method:undefined dispose]()

- Override of base class's [page:Light.dispose dispose]. - Disposes of this light's [page:DirectionalLightShadow shadow]. + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.

[method:this copy]( [param:DirectionalLight source] )

diff --git a/docs/api/en/lights/Light.html b/docs/api/en/lights/Light.html index 81195c123a9077..a20df24b31797b 100644 --- a/docs/api/en/lights/Light.html +++ b/docs/api/en/lights/Light.html @@ -58,7 +58,7 @@

Methods

[method:undefined dispose]()

- Abstract dispose method for lights; implemented by subclasses that have disposable resources. + Abstract dispose method for classes that extend this class; implemented by subclasses that have disposable GPU-related resources.

[method:this copy]( [param:Light source] )

diff --git a/docs/api/en/lights/PointLight.html b/docs/api/en/lights/PointLight.html index a100bec1b30b80..f8f7d9cc487fc0 100644 --- a/docs/api/en/lights/PointLight.html +++ b/docs/api/en/lights/PointLight.html @@ -40,10 +40,9 @@

Constructor

[name]( [param:Integer color], [param:Float intensity], [param:Number distance], [param:Float decay] )

[page:Integer color] - (optional) hexadecimal color of the light. Default is 0xffffff (white).
- [page:Float intensity] - (optional) numeric value of the light's strength/intensity. Default is 1.

+ [page:Float intensity] - (optional) numeric value of the light's strength/intensity. Default is 1.
[page:Number distance] - Maximum range of the light. Default is 0 (no limit).
- [page:Float decay] - The amount the light dims along the distance of the light. Default is 1. - For [page:WebGLRenderer.physicallyCorrectLights physically correct] lighting, set this to 2.

+ [page:Float decay] - The amount the light dims along the distance of the light. Default is 2.

Creates a new [name].

@@ -55,9 +54,8 @@

Properties

[property:Float decay]

- The amount the light dims along the distance of the light
- In [page:WebGLRenderer.physicallyCorrectLights physically correct] mode, decay = 2 leads to physically realistic light falloff.
- Default is `1`. + The amount the light dims along the distance of the light. Default is `2`.
+ In context of physically-correct rendering the default value should not be changed.

[property:Float distance]

@@ -113,8 +111,7 @@

Methods

[method:undefined dispose]()

- Override of base class's [page:Light.dispose dispose]. - Disposes of this light's [page:PointLightShadow shadow]. + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.

[method:this copy]( [param:PointLight source] )

diff --git a/docs/api/en/lights/SpotLight.html b/docs/api/en/lights/SpotLight.html index 477883f79502cb..bc3932bcc26c27 100644 --- a/docs/api/en/lights/SpotLight.html +++ b/docs/api/en/lights/SpotLight.html @@ -20,10 +20,11 @@

[name]

Code Example

- // white spotlight shining from the side, casting a shadow + // white spotlight shining from the side, modulated by a texture, casting a shadow const spotLight = new THREE.SpotLight( 0xffffff ); spotLight.position.set( 100, 1000, 100 ); + spotLight.map = new THREE.TextureLoader().load( url ); spotLight.castShadow = true; @@ -50,7 +51,7 @@

Constructor

[name]( [param:Integer color], [param:Float intensity], [param:Float distance], [param:Radians angle], [param:Float penumbra], [param:Float decay] )

[page:Integer color] - (optional) hexadecimal color of the light. Default is 0xffffff (white).
- [page:Float intensity] - (optional) numeric value of the light's strength/intensity. Default is 1.

+ [page:Float intensity] - (optional) numeric value of the light's strength/intensity. Default is 1.
[page:Float distance] - Maximum range of the light. Default is 0 (no limit).
[page:Radians angle] - Maximum angle of light dispersion from its direction whose upper bound is Math.PI/2.
@@ -81,9 +82,8 @@

[property:Boolean castShadow]

[property:Float decay]

- The amount the light dims along the distance of the light.
- In [page:WebGLRenderer.physicallyCorrectLights physically correct] mode, decay = 2 leads to - physically realistic light falloff. The default is `1`. + The amount the light dims along the distance of the light. Default is `2`.
+ In context of physically-correct rendering the default value should not be changed.

[property:Float distance]

@@ -109,7 +109,7 @@

[property:Float intensity]

In [page:WebGLRenderer.physicallyCorrectLights physically correct] mode, intensity is the luminous intensity of the light measured in candela (cd).

- Changing the power will also change the light's intensity. + Changing the intensity will also change the light's power.

@@ -135,7 +135,7 @@

[property:Float power]

In [page:WebGLRenderer.physicallyCorrectLights physically correct] mode, power is the luminous power of the light measured in lumens (lm).

- Changing this will also change the light's intensity. + Changing the power will also change the light's intensity.

@@ -170,6 +170,13 @@

[property:Object3D target]

The spotlight will now track the target object.

+

[property:Texture map]

+

+ A [page:Texture] used to modulate the color of the light. The spot light color is mixed + with the RGB value of this texture, with a ratio corresponding to its + alpha value. The cookie-like masking effect is reproduced using pixel values (0, 0, 0, 1-cookie_value). + *Warning*: [param:SpotLight map] is disabled if [param:SpotLight castShadow] is *false*. +

Methods

@@ -177,8 +184,7 @@

Methods

[method:undefined dispose]()

- Override of base class's [page:Light.dispose dispose]. - Disposes of this light's [page:SpotLightShadow shadow]. + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.

[method:this copy]( [param:SpotLight source] )

diff --git a/docs/api/en/lights/shadows/LightShadow.html b/docs/api/en/lights/shadows/LightShadow.html index 9698915fd1a0f4..1ca49fb872e064 100644 --- a/docs/api/en/lights/shadows/LightShadow.html +++ b/docs/api/en/lights/shadows/LightShadow.html @@ -129,7 +129,7 @@

[method:number getViewportCount]()

[method:undefined dispose]()

- Disposes of this shadow's textures ([page:LightShadow.map map] and [page:LightShadow.mapPass mapPass]). + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.

[method:this copy]( [param:LightShadow source] )

diff --git a/docs/api/en/lights/shadows/PointLightShadow.html b/docs/api/en/lights/shadows/PointLightShadow.html index 1871cd6ad5d4d2..42a030a2ef95d1 100644 --- a/docs/api/en/lights/shadows/PointLightShadow.html +++ b/docs/api/en/lights/shadows/PointLightShadow.html @@ -7,6 +7,7 @@ + [page:LightShadow] →

[name]

diff --git a/docs/api/en/materials/Material.html b/docs/api/en/materials/Material.html index 9271f490c0750e..2164ed882b5361 100644 --- a/docs/api/en/materials/Material.html +++ b/docs/api/en/materials/Material.html @@ -36,7 +36,7 @@

[property:Float alphaTest]

Default is `0`.

-

[property:Float alphaToCoverage]

+

[property:Boolean alphaToCoverage]

Enables alpha to coverage. Can only be used with MSAA-enabled contexts (meaning when the renderer was created with `antialias` parameter set to `true`). Default is `false`. @@ -292,7 +292,7 @@

[property:String uuid]

[property:Integer version]

- This starts at `0` and counts how many times [property:Boolean needsUpdate] is set to `true`. + This starts at `0` and counts how many times [page:Material.needsUpdate .needsUpdate] is set to `true`.

[property:Boolean vertexColors]

@@ -323,8 +323,10 @@

[method:this copy]( [param:material material] )

[method:undefined dispose]()

- This disposes the material. Textures of a material don't get disposed. - These needs to be disposed by [page:Texture Texture]. + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

+

+ Material textures must be be disposed of by the dispose() method of [page:Texture Texture].

[method:undefined onBeforeCompile]( [param:Shader shader], [param:WebGLRenderer renderer] )

diff --git a/docs/api/en/materials/MeshLambertMaterial.html b/docs/api/en/materials/MeshLambertMaterial.html index ec615b0f2a5ba6..6a9040e464b4db 100644 --- a/docs/api/en/materials/MeshLambertMaterial.html +++ b/docs/api/en/materials/MeshLambertMaterial.html @@ -16,13 +16,7 @@

[name]

The material uses a non-physically based [link:https://en.wikipedia.org/wiki/Lambertian_reflectance Lambertian] model for calculating reflectance. This can simulate some surfaces (such as untreated wood or stone) well, - but cannot simulate shiny surfaces with specular highlights (such as varnished wood).

- - - - Shading is calculated using a [link:https://en.wikipedia.org/wiki/Gouraud_shading Gouraud] shading model. - This calculates shading per vertex (i.e. in the [link:https://en.wikipedia.org/wiki/Shader#Vertex_shaders vertex shader]) - and interpolates the results over the polygon's faces.

+ but cannot simulate shiny surfaces with specular highlights (such as varnished wood). [name] uses per-fragment shading.

Due to the simplicity of the reflectance and illumination models, performance will be greater when using this material over the [page:MeshPhongMaterial], [page:MeshStandardMaterial] or [page:MeshPhysicalMaterial], @@ -79,6 +73,16 @@

[property:Texture aoMap]

[property:Float aoMapIntensity]

Intensity of the ambient occlusion effect. Default is 1. Zero is no occlusion effect.

+

[property:Texture bumpMap]

+

+ The texture to create a bump map. The black and white values map to the perceived depth in relation to the lights. + Bump doesn't actually affect the geometry of the object, only the lighting. If a normal map is defined this will + be ignored. +

+ +

[property:Float bumpScale]

+

How much the bump map affects the material. Typical ranges are 0-1. Default is 1.

+

[property:Color color]

[page:Color] of the material, by default set to white (0xffffff).

@@ -91,6 +95,28 @@

[property:Integer combine]

blend between the two colors.

+

[property:Texture displacementMap]

+

+ The displacement map affects the position of the mesh's vertices. Unlike other maps + which only affect the light and shade of the material the displaced vertices can cast shadows, + block other objects, and otherwise act as real geometry. The displacement texture is + an image where the value of each pixel (white being the highest) is mapped against, + and repositions, the vertices of the mesh. +

+ +

[property:Float displacementScale]

+

+ How much the displacement map affects the mesh (where black is no displacement, + and white is maximum displacement). Without a displacement map set, this value is not applied. + Default is 1. +

+ +

[property:Float displacementBias]

+

+ The offset of the displacement map's values on the mesh's vertices. + Without a displacement map set, this value is not applied. Default is 0. +

+

[property:Color emissive]

Emissive (light) color of the material, essentially a solid color unaffected by other lighting. @@ -110,6 +136,11 @@

[property:Float emissiveIntensity]

[property:Texture envMap]

The environment map. Default is null.

+

[property:Boolean flatShading]

+

+ Define whether the material is rendered with flat shading. Default is false. +

+

[property:Boolean fog]

Whether the material is affected by fog. Default is `true`.

@@ -125,6 +156,27 @@

[property:Texture map]

[page:Material.transparent .transparent] or [page:Material.alphaTest .alphaTest]. Default is null.

+

[property:Texture normalMap]

+

+ The texture to create a normal map. The RGB values affect the surface normal for each pixel fragment and change + the way the color is lit. Normal maps do not change the actual shape of the surface, only the lighting. + In case the material has a normal map authored using the left handed convention, the y component of normalScale + should be negated to compensate for the different handedness. +

+ +

[property:Integer normalMapType]

+

+ The type of normal map.

+ + Options are [page:constant THREE.TangentSpaceNormalMap] (default), and [page:constant THREE.ObjectSpaceNormalMap]. +

+ +

[property:Vector2 normalScale]

+

+ How much the normal map affects the material. Typical ranges are 0-1. + Default is a [page:Vector2] set to (1,1). +

+

[property:Float reflectivity]

How much the environment map affects the surface; also see [page:.combine].

diff --git a/docs/api/en/materials/MeshPhongMaterial.html b/docs/api/en/materials/MeshPhongMaterial.html index b7d42da511ddf3..ab9e235bc7f805 100644 --- a/docs/api/en/materials/MeshPhongMaterial.html +++ b/docs/api/en/materials/MeshPhongMaterial.html @@ -16,13 +16,7 @@

[name]

The material uses a non-physically based [link:https://en.wikipedia.org/wiki/Blinn-Phong_shading_model Blinn-Phong] model for calculating reflectance. Unlike the Lambertian model used in the [page:MeshLambertMaterial] - this can simulate shiny surfaces with specular highlights (such as varnished wood).

- - Shading is calculated using a [link:https://en.wikipedia.org/wiki/Phong_shading Phong] shading model. - This calculates shading per pixel (i.e. in the [link:https://en.wikipedia.org/wiki/Shader#Pixel_shaders fragment shader], - AKA pixel shader) which gives more accurate results than the Gouraud model used by [page:MeshLambertMaterial], - at the cost of some performance. The [page:MeshStandardMaterial] and [page:MeshPhysicalMaterial] - also use this shading model.

+ this can simulate shiny surfaces with specular highlights (such as varnished wood). [name] uses per-fragment shading.

Performance will generally be greater when using this material over the [page:MeshStandardMaterial] or [page:MeshPhysicalMaterial], at the cost of some graphical accuracy. diff --git a/docs/api/en/materials/MeshPhysicalMaterial.html b/docs/api/en/materials/MeshPhysicalMaterial.html index 097130e329aaf4..c35844d0d85561 100644 --- a/docs/api/en/materials/MeshPhysicalMaterial.html +++ b/docs/api/en/materials/MeshPhysicalMaterial.html @@ -29,6 +29,9 @@

[name]

  • Advanced reflectivity: More flexible reflectivity for non-metallic materials.
  • +
  • + Sheen: Can be used for representing cloth and fabric materials. +
  • @@ -61,6 +64,7 @@

    Examples

    [example:webgl_materials_variations_physical materials / variations / physical]
    [example:webgl_materials_physical_clearcoat materials / physical / clearcoat]
    [example:webgl_materials_physical_reflectivity materials / physical / reflectivity]
    + [example:webgl_loader_gltf_sheen loader / gltf / sheen]
    [example:webgl_materials_physical_transmission materials / physical / transmission]

    @@ -86,7 +90,7 @@

    [property:Color attenuationColor]

    [property:Float attenuationDistance]

    - Density of the medium given as the average distance that light travels in the medium before interacting with a particle. The value is given in world space. Default is `0`. + Density of the medium given as the average distance that light travels in the medium before interacting with a particle. The value is given in world space units, and must be greater than zero. Default is `Infinity`.

    [property:Float clearcoat]

    diff --git a/docs/api/en/materials/MeshStandardMaterial.html b/docs/api/en/materials/MeshStandardMaterial.html index 2e0d0953f0e39c..c46f0c6a90d221 100644 --- a/docs/api/en/materials/MeshStandardMaterial.html +++ b/docs/api/en/materials/MeshStandardMaterial.html @@ -20,18 +20,12 @@

    [name]

    [link:http://area.autodesk.com/blogs/the-3ds-max-blog/what039s-new-for-rendering-in-3ds-max-2017 3D Studio Max].

    This approach differs from older approaches in that instead of using approximations for the way in which - light interacts with a surface, a physically correct model is used. The idea is that, instead of + light interacts with a surface, a physically correct model is used. The idea is that, instead of tweaking materials to look good under specific lighting, a material can be created that will react 'correctly' under all lighting scenarios.

    - In practice this gives a more accurate and realistic looking result than the [page:MeshLambertMaterial] - or [page:MeshPhongMaterial], at the cost of being somewhat more computationally expensive.

    - - Shading is calculated in the same way as for the [page:MeshPhongMaterial], using a - [link:https://en.wikipedia.org/wiki/Phong_shading Phong] shading model. This calculates shading - per pixel (i.e. in the [link:https://en.wikipedia.org/wiki/Shader#Pixel_shaders fragment shader], - AKA pixel shader) which gives more accurate results than the Gouraud model used by - [page:MeshLambertMaterial], at the cost of some performance.

    + In practice this gives a more accurate and realistic looking result than the [page:MeshLambertMaterial] + or [page:MeshPhongMaterial], at the cost of being somewhat more computationally expensive. [name] uses per-fragment shading.

    Note that for best results you should always specify an [page:.envMap environment map] when using this material.

    diff --git a/docs/api/en/materials/PointsMaterial.html b/docs/api/en/materials/PointsMaterial.html index 186621a5dad665..b2fb947e3befce 100644 --- a/docs/api/en/materials/PointsMaterial.html +++ b/docs/api/en/materials/PointsMaterial.html @@ -100,6 +100,7 @@

    [property:Boolean sizeAttenuation]

    Methods

    +

    See the base [page:Material] class for common methods.

    Source

    diff --git a/docs/api/en/math/Interpolant.html b/docs/api/en/math/Interpolant.html index a77b9c01b0edea..c7b043ae470c39 100644 --- a/docs/api/en/math/Interpolant.html +++ b/docs/api/en/math/Interpolant.html @@ -24,10 +24,6 @@

    [name]

    References: [link:http://www.oodesign.com/template-method-pattern.html http://www.oodesign.com/template-method-pattern.html]

    - -

    Constructor

    - -

    Constructor

    [name]( parameterPositions, sampleValues, sampleSize, resultBuffer )

    diff --git a/docs/api/en/math/Matrix3.html b/docs/api/en/math/Matrix3.html index 91c06d52924ab5..603590a43bb816 100644 --- a/docs/api/en/math/Matrix3.html +++ b/docs/api/en/math/Matrix3.html @@ -129,7 +129,45 @@

    [method:this identity]()

    0, 1, 0 0, 0, 1
    +

    + +

    [method:this makeRotation]( [param:Float theta] )

    +

    + [page:Float theta] — Rotation angle in radians. Positive values rotate counterclockwise.

    + + Sets this matrix as a 2D rotational transformation by [page:Float theta] radians. + The resulting matrix will be: + +cos(θ) -sin(θ) 0 +sin(θ) cos(θ) 0 +0 0 1 + +

    +

    [method:this makeScale]( [param:Float x], [param:Float y] )

    +

    + [page:Float x] - the amount to scale in the X axis.
    + [page:Float y] - the amount to scale in the Y axis.
    + + Sets this matrix as a 2D scale transform: + +x, 0, 0, +0, y, 0, +0, 0, 1 + +

    + +

    [method:this makeTranslation]( [param:Float x], [param:Float y] )

    +

    + [page:Float x] - the amount to translate in the X axis.
    + [page:Float y] - the amount to translate in the Y axis.
    + + Sets this matrix as a 2D translation transform: + +1, 0, x, +0, 1, y, +0, 0, 1 +

    [method:this multiply]( [param:Matrix3 m] )

    @@ -173,7 +211,7 @@

    [method:this setUvTransform]( [param:Float tx], [param:Float ty], [param:Flo [page:Float ty] - offset y
    [page:Float sx] - repeat x
    [page:Float sy] - repeat y
    - [page:Float rotation] - rotation (in radians)
    + [page:Float rotation] - rotation, in radians. Positive values rotate counterclockwise
    [page:Float cx] - center x of rotation
    [page:Float cy] - center y of rotation

    diff --git a/docs/api/en/math/Triangle.html b/docs/api/en/math/Triangle.html index f2f0550630cc04..5d5c1a8fbc595b 100644 --- a/docs/api/en/math/Triangle.html +++ b/docs/api/en/math/Triangle.html @@ -118,7 +118,7 @@

    [method:Vector2 getUV]( [param:Vector3 point], [param:Vector2 uv1], [param:V [page:Vector3 point] - The point on the triangle.
    [page:Vector2 uv1] - The uv coordinate of the triangle's first vertex.
    [page:Vector2 uv2] - The uv coordinate of the triangle's second vertex.
    - [page:Vector2 uv2] - The uv coordinate of the triangle's third vertex.
    + [page:Vector2 uv3] - The uv coordinate of the triangle's third vertex.
    [page:Vector2 target] — the result will be copied into this Vector2.

    Returns the uv coordinates for the given point on the triangle. diff --git a/docs/api/en/objects/InstancedMesh.html b/docs/api/en/objects/InstancedMesh.html index 44a92275e8cb35..044b2cc7dc090b 100644 --- a/docs/api/en/objects/InstancedMesh.html +++ b/docs/api/en/objects/InstancedMesh.html @@ -69,7 +69,7 @@

    Methods

    [method:undefined dispose]()

    - Frees the internal resources of this instance. + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.

    [method:undefined getColorAt]( [param:Integer index], [param:Color color] )

    diff --git a/docs/api/en/objects/LOD.html b/docs/api/en/objects/LOD.html index 712e485f84372b..e3c3aed5139b4c 100644 --- a/docs/api/en/objects/LOD.html +++ b/docs/api/en/objects/LOD.html @@ -70,18 +70,20 @@

    [property:Array levels]

    An array of [page:Object level] objects

    - Each level is an object with two properties:
    + Each level is an object with the following properties:
    [page:Object3D object] - The [page:Object3D] to display at this level.
    - [page:Float distance] - The distance at which to display this level of detail. + [page:Float distance] - The distance at which to display this level of detail.
    + [page:Float hysteresis] - Threshold used to avoid flickering at LOD boundaries, as a fraction of distance.

    Methods

    See the base [page:Object3D] class for common methods.

    -

    [method:this addLevel]( [param:Object3D object], [param:Float distance] )

    +

    [method:this addLevel]( [param:Object3D object], [param:Float distance], [param:Float hysteresis] )

    [page:Object3D object] - The [page:Object3D] to display at this level.
    - [page:Float distance] - The distance at which to display this level of detail.

    + [page:Float distance] - The distance at which to display this level of detail. Default 0.0.
    + [page:Float hysteresis] - Threshold used to avoid flickering at LOD boundaries, as a fraction of distance. Default 0.0.

    Adds a mesh that will display at a certain distance and greater. Typically the further away the distance, the lower the detail on the mesh. @@ -89,7 +91,7 @@

    [method:this addLevel]( [param:Object3D object], [param:Float distance] )[method:LOD clone]()

    - Returns a clone of this LOD object and its associated distance specific objects. + Returns a clone of this LOD object with its associated levels.

    @@ -105,7 +107,7 @@

    [method:Object3D getObjectForDistance]( [param:Float distance] )

    Get a reference to the first [page:Object3D] (mesh) that is greater than [page:Float distance].

    -

    [method:Array raycast]( [param:Raycaster raycaster], [param:Array intersects] )

    +

    [method:undefined raycast]( [param:Raycaster raycaster], [param:Array intersects] )

    Get intersections between a casted [page:Ray] and this LOD. [page:Raycaster.intersectObject] will call this method. diff --git a/docs/api/en/objects/Skeleton.html b/docs/api/en/objects/Skeleton.html index 0e8b8c92705820..b55d6b4bff7a41 100644 --- a/docs/api/en/objects/Skeleton.html +++ b/docs/api/en/objects/Skeleton.html @@ -115,7 +115,7 @@

    [method:Bone getBoneByName]( [param:String name] )

    [method:undefined dispose]()

    - Can be used if an instance of [name] becomes obsolete in an application. The method will free internal resources. + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.

    Source

    diff --git a/docs/api/en/renderers/WebGL3DRenderTarget.html b/docs/api/en/renderers/WebGL3DRenderTarget.html index 94842b2ecb67a3..8b7d5431147cef 100644 --- a/docs/api/en/renderers/WebGL3DRenderTarget.html +++ b/docs/api/en/renderers/WebGL3DRenderTarget.html @@ -19,9 +19,9 @@

    Constructor

    [name]( [param:Number width], [param:Number height], [param:Number depth] )

    - [page:Number width] - the width of the render target, in pixels.
    - [page:Number height] - the height of the render target, in pixels.
    - [page:Number depth] - the depth of the render target.

    + [page:Number width] - the width of the render target, in pixels. Default is `1`.
    + [page:Number height] - the height of the render target, in pixels. Default is `1`.
    + [page:Number depth] - the depth of the render target. Default is `1`.

    Creates a new [name].

    diff --git a/docs/api/en/renderers/WebGLArrayRenderTarget.html b/docs/api/en/renderers/WebGLArrayRenderTarget.html index 563f436b64fb28..72df3faaf6344e 100644 --- a/docs/api/en/renderers/WebGLArrayRenderTarget.html +++ b/docs/api/en/renderers/WebGLArrayRenderTarget.html @@ -25,9 +25,9 @@

    Constructor

    [name]( [param:Number width], [param:Number height], [param:Number depth] )

    - [page:Number width] - the width of the render target, in pixels.
    - [page:Number height] - the height of the render target, in pixels.
    - [page:Number depth] - the depth/layer count of the render target.

    + [page:Number width] - the width of the render target, in pixels. Default is `1`.
    + [page:Number height] - the height of the render target, in pixels. Default is `1`.
    + [page:Number depth] - the depth/layer count of the render target. Default is `1`.

    Creates a new [name].

    diff --git a/docs/api/en/renderers/WebGLCubeRenderTarget.html b/docs/api/en/renderers/WebGLCubeRenderTarget.html index ed64b899157630..81f97168c3e00a 100644 --- a/docs/api/en/renderers/WebGLCubeRenderTarget.html +++ b/docs/api/en/renderers/WebGLCubeRenderTarget.html @@ -25,7 +25,7 @@

    Constructor

    [name]([param:Number size], [param:Object options])

    - [page:Float size] - the size, in pixels.
    + [page:Float size] - the size, in pixels. Default is `1`.
    options - (optional) object that holds texture parameters for an auto-generated target texture and depthBuffer/stencilBuffer booleans. diff --git a/docs/api/en/renderers/WebGLMultipleRenderTargets.html b/docs/api/en/renderers/WebGLMultipleRenderTargets.html index 32b5ac28cc56a7..8789c44eea5301 100644 --- a/docs/api/en/renderers/WebGLMultipleRenderTargets.html +++ b/docs/api/en/renderers/WebGLMultipleRenderTargets.html @@ -30,9 +30,9 @@

    Constructor

    [name]([param:Number width], [param:Number height], [param:Number count], [param:Object options])

    - [page:Number width] - The width of the render target.
    - [page:Number height] - The height of the render target.
    - [page:Number count] - The number of render targets.
    + [page:Number width] - The width of the render target. Default is `1`.
    + [page:Number height] - The height of the render target. Default is `1`.
    + [page:Number count] - The number of render targets. Default is `1`.
    options - (optional object that holds texture parameters for an auto-generated target texture and depthBuffer/stencilBuffer booleans. diff --git a/docs/api/en/renderers/WebGLRenderTarget.html b/docs/api/en/renderers/WebGLRenderTarget.html index 03f4ad8f123be3..ee359f7ab1aee3 100644 --- a/docs/api/en/renderers/WebGLRenderTarget.html +++ b/docs/api/en/renderers/WebGLRenderTarget.html @@ -23,8 +23,8 @@

    Constructor

    [name]([param:Number width], [param:Number height], [param:Object options])

    - [page:Float width] - The width of the renderTarget.
    - [page:Float height] - The height of the renderTarget.
    + [page:Float width] - The width of the renderTarget. Default is `1`.
    + [page:Float height] - The height of the renderTarget. Default is `1`.
    options - optional object that holds texture parameters for an auto-generated target texture and depthBuffer/stencilBuffer booleans. @@ -123,13 +123,9 @@

    [method:this copy]( [param:WebGLRenderTarget source] )

    [method:undefined dispose]()

    - Dispatches a dispose event. + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.

    - - - -

    [page:EventDispatcher EventDispatcher] methods are available on this class.

    Source

    diff --git a/docs/api/en/renderers/WebGLRenderer.html b/docs/api/en/renderers/WebGLRenderer.html index 18711105836027..2ba3ee452b921e 100644 --- a/docs/api/en/renderers/WebGLRenderer.html +++ b/docs/api/en/renderers/WebGLRenderer.html @@ -310,7 +310,9 @@

    [method:undefined copyTextureToTexture3D]( [param:Box3 sourceBox], [param:Ve

    Copies the pixels of a texture in the bounds '[page:Box3 sourceBox]' in the destination texture starting from the given position. Enables access to [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/texSubImage3D WebGL2RenderingContext.texSubImage3D].

    [method:undefined dispose]( )

    -

    Dispose of the current rendering context.

    +

    + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

    [method:undefined forceContextLoss]()

    @@ -407,7 +409,7 @@

    [method:undefined render]( [param:Object3D scene], [param:Camera camera] )

    [method:undefined resetState]()

    diff --git a/docs/api/en/renderers/webgl/WebGLProgram.html b/docs/api/en/renderers/webgl/WebGLProgram.html index fd7ab94df4a790..1d0c6ed7d66f97 100644 --- a/docs/api/en/renderers/webgl/WebGLProgram.html +++ b/docs/api/en/renderers/webgl/WebGLProgram.html @@ -35,7 +35,7 @@

    Vertex shader (unconditional):

    uniform vec3 cameraPosition;
    - // default vertex attributes provided by Geometry and BufferGeometry + // default vertex attributes provided by BufferGeometry attribute vec3 position; attribute vec3 normal; attribute vec2 uv; @@ -55,6 +55,9 @@

    Vertex shader (unconditional):

    Vertex shader (conditional):

    + #ifdef USE_TANGENT + attribute vec4 tangent; + #endif #if defined( USE_COLOR_ALPHA ) // vertex color attribute with alpha attribute vec4 color; diff --git a/docs/api/en/renderers/webxr/WebXRManager.html b/docs/api/en/renderers/webxr/WebXRManager.html index 3cfc098271dd44..98497b8b350f90 100644 --- a/docs/api/en/renderers/webxr/WebXRManager.html +++ b/docs/api/en/renderers/webxr/WebXRManager.html @@ -82,6 +82,11 @@

    [method:Group getHand]( [param:Integer index] )

    Use this space for visualizing the user's hands when no physical controllers are used.

    +

    [method:Set getPlanes]()

    +

    + Returns the set of planes detected by WebXR's plane detection API. +

    +

    [method:String getReferenceSpace]()

    Returns the reference space. diff --git a/docs/api/en/scenes/Scene.html b/docs/api/en/scenes/Scene.html index 2c281b5fe27b42..5aa00c5061aa61 100644 --- a/docs/api/en/scenes/Scene.html +++ b/docs/api/en/scenes/Scene.html @@ -24,27 +24,36 @@

    [name]()

    Properties

    -

    [property:Boolean autoUpdate]

    +

    [property:Object background]

    - Default is true. If set, then the renderer checks every frame if the scene and its objects needs matrix updates. - When it isn't, then you have to maintain all matrices in the scene yourself. + Defines the background of the scene. Default is `null`. Valid inputs are: +

      +
    • A [page:Color] for defining a uniform colored background.
    • +
    • A [page:Texture] for defining a (flat) textured background.
    • +
    • Texture cubes ([page:CubeTexture]) or equirectangular textures for defining a skybox.
    • +
    + Note: Any camera related configurations like `zoom` or `view` are ignored.

    -

    [property:Object background]

    +

    [property:Float backgroundBlurriness]

    +

    + Sets the blurriness of the background. Only influences environment maps assigned to [page:Scene.background]. Valid input is a float between *0* and *1*. Default is *0*. +

    + +

    [property:Float backgroundIntensity]

    - If not null, sets the background used when rendering the scene, and is always rendered first. - Can be set to a [page:Color] which sets the clear color, a [page:Texture] covering the canvas, a cubemap as a [page:CubeTexture] or an equirectangular as a [page:Texture] . Default is null. + Attenuates the color of the background. Only applies to background textures. Default is *1*.

    [property:Texture environment]

    - If not null, this texture is set as the environment map for all physical materials in the scene. - However, it's not possible to overwrite an existing texture assigned to [page:MeshStandardMaterial.envMap]. Default is null. + Sets the environment map for all physical materials in the scene. + However, it's not possible to overwrite an existing texture assigned to [page:MeshStandardMaterial.envMap]. Default is `null`.

    [property:Fog fog]

    -

    A [page:Fog fog] instance defining the type of fog that affects everything rendered in the scene. Default is null.

    +

    A [page:Fog fog] instance defining the type of fog that affects everything rendered in the scene. Default is `null`.

    [property:Boolean isScene]

    @@ -53,7 +62,7 @@

    [property:Boolean isScene]

    [property:Material overrideMaterial]

    -

    If not null, it will force everything in the scene to be rendered with that material. Default is null.

    +

    Forces everything in the scene to be rendered with the defined material. Default is `null`.

    Methods

    diff --git a/docs/api/en/textures/CompressedArrayTexture.html b/docs/api/en/textures/CompressedArrayTexture.html new file mode 100644 index 00000000000000..8383f04f18c6e8 --- /dev/null +++ b/docs/api/en/textures/CompressedArrayTexture.html @@ -0,0 +1,75 @@ + + + + + + + + + + [page:CompressedTexture] → + +

    [name]

    + +

    + Creates an texture 2D array based on data in compressed form, for example from a [link:https://en.wikipedia.org/wiki/DirectDraw_Surface DDS] file.

    + + + For use with the [page:CompressedTextureLoader CompressedTextureLoader]. +

    + + +

    Constructor

    + + +

    [name]( [param:Array mipmaps], [param:Number width], [param:Number height], [param:Constant format], [param:Constant type] )

    +

    + [page:Array mipmaps] -- The mipmaps array should contain objects with data, width and height. The mipmaps should be of the correct format and type.
    + + [page:Number width] -- The width of the biggest mipmap.
    + + [page:Number height] -- The height of the biggest mipmap.
    + + [page:Number depth] -- The number of layers of the 2D array texture.
    + + [page:Constant format] -- The format used in the mipmaps. + See [page:Textures ST3C Compressed Texture Formats], + [page:Textures PVRTC Compressed Texture Formats] and + [page:Textures ETC Compressed Texture Format] for other choices.
    + + [page:Constant type] -- Default is [page:Textures THREE.UnsignedByteType]. + See [page:Textures type constants] for other choices.
    + +

    + + +

    Properties

    + + See the base [page:CompressedTexture CompressedTexture] class for common properties. + +

    [property:number wrapR]

    +

    + This defines how the texture is wrapped in the depth direction.
    + The default is [page:Textures THREE.ClampToEdgeWrapping], where the edge is clamped to the outer edge texels. + The other two choices are [page:Textures THREE.RepeatWrapping] and [page:Textures THREE.MirroredRepeatWrapping]. + See the [page:Textures texture constants] page for details. +

    + +

    [property:Boolean isCompressedArrayTexture]

    +

    + Read-only flag to check if a given object is of type [name]. +

    + +

    Methods

    + +

    + See the base [page:CompressedTexture CompressedTexture] class for common methods. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/en/textures/Source.html b/docs/api/en/textures/Source.html index 51fa8f5c5b956e..17b530d43f75ce 100644 --- a/docs/api/en/textures/Source.html +++ b/docs/api/en/textures/Source.html @@ -40,7 +40,7 @@

    [property:String uuid]

    [property:Integer version]

    - This starts at `0` and counts how many times [property:Boolean needsUpdate] is set to `true`. + This starts at `0` and counts how many times [page:Source.needsUpdate .needsUpdate] is set to `true`.

    Methods

    diff --git a/docs/api/en/textures/Texture.html b/docs/api/en/textures/Texture.html index 79c2120c14cbfb..a2744ff723b4eb 100644 --- a/docs/api/en/textures/Texture.html +++ b/docs/api/en/textures/Texture.html @@ -253,7 +253,7 @@

    [property:number encoding]

    [property:Integer version]

    - This starts at `0` and counts how many times [property:Boolean needsUpdate] is set to `true`. + This starts at `0` and counts how many times [page:Texture.needsUpdate .needsUpdate] is set to `true`.

    [property:Function onUpdate]

    @@ -292,7 +292,7 @@

    [method:undefined updateMatrix]()

    [method:Texture clone]()

    Make copy of the texture. Note this is not a "deep copy", the image is shared. - Besides, cloning a texture does not automatically mark it for a texture upload. You have to set [page:Texture.needsUpdate] to true as soon as its image property (the data source) is fully loaded or ready. + Besides, cloning a texture does not automatically mark it for a texture upload. You have to set [page:Texture.needsUpdate .needsUpdate] to true as soon as its image property (the data source) is fully loaded or ready.

    [method:Object toJSON]( [param:Object meta] )

    @@ -303,7 +303,7 @@

    [method:Object toJSON]( [param:Object meta] )

    [method:undefined dispose]()

    - Frees the GPU related resources allocated by a texture. Call this method whenever a texture is no longer used in your app. + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.

    [method:Vector2 transformUv]( [param:Vector2 uv] )

    diff --git a/docs/api/en/textures/VideoTexture.html b/docs/api/en/textures/VideoTexture.html index 89e200115e132a..3e91c3b0ad7443 100644 --- a/docs/api/en/textures/VideoTexture.html +++ b/docs/api/en/textures/VideoTexture.html @@ -12,9 +12,11 @@

    [name]

    - Creates a texture for use with a video texture.

    + Creates a texture for use with a video. +

    - This is almost the same as the base [page:Texture Texture] class, except that it continuously sets [page:Texture.needsUpdate needsUpdate] to `true` so that the texture is updated as the video plays. Automatic creation of [page:Texture.mipmaps mipmaps] is also disabled. +

    + Note: After the initial use of a texture, the video cannot be changed. Instead, call [page:.dispose]() on the texture and instantiate a new one.

    Code Example

    @@ -27,7 +29,13 @@

    Code Example

    Examples

    -

    [example:webgl_materials_video materials / video ]

    +

    + [example:webgl_materials_video materials / video]
    + [example:webgl_materials_video_webcam materials / video / webcam]
    + [example:webgl_video_kinect video / kinect]
    + [example:webgl_video_panorama_equirectangular video / panorama / equirectangular]
    + [example:webxr_vr_video vr / video] +

    Constructor

    [name]( [param:Video video], [param:Constant mapping], [param:Constant wrapS], [param:Constant wrapT], [param:Constant magFilter], [param:Constant minFilter], [param:Constant format], [param:Constant type], [param:Number anisotropy] )

    @@ -47,7 +55,7 @@

    [name]( [param:Video video], [param:Constant mapping], [param:Constant wrapS The default is [page:Textures THREE.LinearFilter]. See [page:Textures magnification filter constants] for other choices.
    [page:Constant minFilter] -- How the texture is sampled when a texel covers less than one pixel. - The default is [page:Textures THREE.LinearMipmapLinearFilter]. See [page:Textures minification filter constants] for other choices.
    + The default is [page:Textures THREE.LinearFilter]. See [page:Textures minification filter constants] for other choices.
    [page:Constant format] -- The default is [page:Textures THREE.RGBAFormat]. See [page:Textures format constants] for other choices.
    @@ -69,7 +77,7 @@

    Properties

    [property:Boolean generateMipmaps]

    - Whether to generate mipmaps. False by default. + Whether to generate mipmaps. `false` by default.

    [property:Boolean isVideoTexture]

    @@ -79,7 +87,7 @@

    [property:Boolean isVideoTexture]

    [property:Boolean needsUpdate]

    - You will not need to set this manually here as it is handled by the [page:VideoTexture.update update] method. + You will not need to set this manually here as it is handled by the [page:VideoTexture.update update]() method.

    Methods

    @@ -90,7 +98,7 @@

    Methods

    [method:undefined update]()

    - This is called automatically and sets [property:Boolean needsUpdate] to `true` every time + This is called automatically and sets [page:VideoTexture.needsUpdate .needsUpdate] to `true` every time a new frame is available.

    diff --git a/docs/api/fr/animation/AnimationAction.html b/docs/api/fr/animation/AnimationAction.html new file mode 100644 index 00000000000000..83b50a1966ac0e --- /dev/null +++ b/docs/api/fr/animation/AnimationAction.html @@ -0,0 +1,363 @@ + + + + + + + + + +

    [name]

    + +

    + Les AnimationActions programment la performance des animations qui sont stockées dans + [page:AnimationClip AnimationClips].

    + + Note: La plupart des méthodes d'AnimationAction peuvent être chainées.

    + + Pour avoir un aperçu des différents éléments du système d'animation de three.js, consultez + l'article "Système d'Animation" dans la section "Étapes Suivantes" du manuel. +

    + + +

    Constructeur

    + + +

    [name]( [param:AnimationMixer mixer], [param:AnimationClip clip], [param:Object3D localRoot] )

    +

    + [page:AnimationMixer mixer] - l'`AnimationMixer` contrôlé par cette action.
    + [page:AnimationClip clip] - l`AnimationClip` qui contient les données d'animation pour cette action.
    + [page:Object3D localRoot] - l'objet racine sur lequel est appliqué l'action.

    + + Note: Au lieu d'appeler ce constructeur directement, vous devriez instantier un AnimationAction avec + [page:AnimationMixer.clipAction] étant donné que cette méthode applique une mise en cache pour obtenir de meilleures performances. +

    + + +

    Propriétés

    + + +

    [property:Boolean clampWhenFinished]

    +

    + Si `clampWhenFinished` est mis à true l'animation sera automatiquement [page:.paused mise en pause] + à son dernier frame.

    + + Si `clampWhenFinished` est mis à false, [page:.enabled enabled] sera automatiquement reglé sur + false quand la dernière boucle de l'action sera terminée, afin que cette action n'ai pas plus + d'impact.

    + + La valeur par défaut est false.

    + + Note: `clampWhenFinished` n'a pas d'impact si l'action est interrompue (il n'a d'impact que si + la dernière boucle de l'action s'est réellement terminée). +

    + +

    [property:Boolean enabled]

    +

    + Régler `enabled` sur `false` désactive cette action, afin qu'elle n'ai aucun impact. La valeur par défaut est `true`.

    + + Quand l'action est réactivée, l'animation continue depuis son [page:.time time] actuel + (Régler `enabled` sur `false` ne relance pas l'action).

    + + Note: Régler `enabled` sur `true` ne redémarre pas automatiquement l'action. Régler `enabled` + sur `true` ne redémarrera l'action immédiatement que si les conditions suivantes sont remplies: + [page:.paused paused] est à `false`, l'action n'a pas été désactivée (en + exécutant un [page:.stop stop] ou un [page:.reset reset]), et ni [page:.weight weight] + ni [page:.timeScale timeScale] ne sont à `0`. +

    + +

    [property:Number loop]

    +

    + Le mode répeter (peut-être changé avec [page:.setLoop setLoop]). Sa valeur par défaut est + [page:Animation THREE.LoopRepeat] (avec un nombre infini de répétitions [page:.repetitions repetitions])

    + + Doit être une de ces constantes:

    + [page:Animation THREE.LoopOnce] - joue le clip une fois,
    + [page:Animation THREE.LoopRepeat] - joue le clip le nombre choisi de `répetitions`, + en sautant à chaque fois de la fin du clip à son début,
    + [page:Animation THREE.LoopPingPong] - joue le clip le nombre choisi de `répetitions`, + alternant entre lecture du début vers la fin et lecture de la fin vers le début. +

    + +

    [property:Boolean paused]

    +

    + Régler `paused` sur `true` met l'exécution de l'action en pause en mettant l'échelle temporelle effective + à `0`. La valeur par défaut est `false`.

    +

    + +

    [property:Number repetitions]

    +

    + Le nombre de répétitions de l'[page:AnimationClip] actuel réalisées durant cette action. + Peut-être paramétré depuis [page:.setLoop setLoop]. La valeur par défaut est `Infinity`.

    + Changer ce nombre n'a aucun effet, si le [page:.loop loop mode] est réglé sur + [page:Animation THREE.LoopOnce]. +

    + +

    [property:Number time]

    +

    + Le temps local de cette action (en secondes, en commençant par `0`).

    + + La valeur peut-être restreinte à `0...clip.duration` (selon l'état de la boucle). Il peut être + mis à l'échelle relativement à celui du mixer global en changeant [page:.timeScale timeScale] (en utilisant + [page:.setEffectiveTimeScale setEffectiveTimeScale] ou [page:.setDuration setDuration]).
    +

    + +

    [property:Number timeScale]

    +

    + Facteur de mise à l'échelle pour le [page:.time time]. Une valeur de `0` cause la mise en pause de l'animation. Une valeur + négative fera jouer l'animation à l'envers . La valeur par défaut est `1`.

    + Les propriétés/méthodes concernant `timeScale` (respectivement `time`) sont: + [page:.getEffectiveTimeScale getEffectiveTimeScale], + [page:.halt halt], + [page:.paused paused], + [page:.setDuration setDuration], + [page:.setEffectiveTimeScale setEffectiveTimeScale], + [page:.stopWarping stopWarping], + [page:.syncWith syncWith], + [page:.warp warp]. +

    + +

    [property:Number weight]

    +

    + Le degré d'importance d'une action (compris dans l'intervalle `[0, 1]`). Les valeurs entre `0` (aucun impact) + et 1 (impact total) peuvent être utilisées pour mélanger plusieurs actions. La valeur par défaut est `1`.

    + Les propriétés/méthodes concernant `weight` sont: + [page:.crossFadeFrom crossFadeFrom], + [page:.crossFadeTo crossFadeTo], + [page:.enabled enabled], + [page:.fadeIn fadeIn], + [page:.fadeOut fadeOut], + [page:.getEffectiveWeight getEffectiveWeight], + [page:.setEffectiveWeight setEffectiveWeight], + [page:.stopFading stopFading]. +

    + +

    [property:Boolean zeroSlopeAtEnd]

    +

    + Permet une interpolation fluide sans avoir de clips séparés pour le début, les répétitions et la fin. La valeur par défaut est `true`. +

    + +

    [property:Boolean zeroSlopeAtStart]

    +

    + Permet une interpolation fluide sans avoir de clips séparés pour le début, les répétitions et la fin. La valeur par défaut est `true`. +

    + + +

    Méthodes

    + + +

    [method:this crossFadeFrom]( [param:AnimationAction fadeOutAction], [param:Number durationInSeconds], [param:Boolean warpBoolean] )

    +

    + Provoque l'[page:.fadeIn apparition] de cette action, en faisant disparaître une autre action simultanément, durant + l'intervalle de temps passée en paramètre. Cette méthode peut être chaînée.

    + + Si warpBoolean est à true, un [page:.warp warping] additionnel (changement graduel de l'échelle temporelle) + sera appliqué.

    + + Note: Comme avec `fadeIn`/`fadeOut`, le fading commence/termine avec un weight à 1. + +

    + +

    [method:this crossFadeTo]( [param:AnimationAction fadeInAction], [param:Number durationInSeconds], [param:Boolean warpBoolean] )

    +

    + Provoque la [page:.fadeIn disparition] de cette action, en faisant apparaître une autre action simultanément, durant + l'intervalle de temps passée en paramètre. Cette méthode peut être chaînée.

    + Si warpBoolean est à true, un [page:.warp warping] additionnel (changement graduel de l'échelle temporelle) + sera appliqué.

    + + Note: Comme avec `fadeIn`/`fadeOut`, le fading commence/termine avec un weight à 1. +

    + +

    [method:this fadeIn]( [param:Number durationInSeconds] )

    +

    + Augmente graduellement le [page:.weight weight] de cette action de `0` à `1`, durant + l'intervalle de temps passée en paramètre. Cette méthode peut être chaînée. +

    + +

    [method:this fadeOut]( [param:Number durationInSeconds] )

    +

    + Diminue graduellement le [page:.weight weight] de cette de `1` à `0`, durant + l'intervalle de temps passée en paramètre. Cette méthode peut être chaînée. +

    + +

    [method:Number getEffectiveTimeScale]()

    +

    + Renvoie l'échelle temporelle effective (en prenant en compte l'état actuel du warping et de + [page:.paused paused]). +

    + +

    [method:Number getEffectiveWeight]()

    +

    + Renvoie le weight effectif (en prenant en compte l'état actuel du fondu et de + [page:.enabled enabled]). +

    + +

    [method:AnimationClip getClip]()

    +

    + Renvoie le clip qui contient les données d'animation pour cette action. +

    + +

    [method:AnimationMixer getMixer]()

    +

    + Renvoie le mixer qui est responsable de jouer cette action. +

    + +

    [method:Object3D getRoot]()

    +

    + Renvoie l'objet racine sur lequel l'action est appliquée. +

    + +

    [method:this halt]( [param:Number durationInSeconds] )

    +

    + Diminue la vitesse de l'animation jusqu'à `0` en diminuant le [page:.timeScale timeScale] graduellement + (en commençant depuis sa valeur actuelle), durant l'intervalle de temps passée en paramètre. Cette méthode peut être chaînée. +

    + +

    [method:Boolean isRunning]()

    +

    + Renvoie true si le [page:.time time] de l'action est en cours.

    + + En plus d'être activé dans le mixer (see [page:.isScheduled isScheduled]) les conditions suivantes doivent être remplies: + [page:.paused paused] est à faux, [page:.enabled enabled] est à true, + [page:.timeScale timeScale] est différent de `0`, et un départ différé n'est pas programmé + ([page:.startAt startAt]).

    + + Note: le fait que `isRunning` soit à true n'indique pas nécessairement que l'action est visible. + C'est seulement le cas si le [page:.weight weight] est reglé sur une valeur non-nulle. +

    + +

    [method:Boolean isScheduled]()

    +

    + Renvoie true, si cette action est activée dans le mixer.

    + Note: Cela n'indique pas nécessairement que l'action est en cours d'éxécution (voir les conditions additionnelles + pour [page:.isRunning isRunning]). +

    + +

    [method:this play]()

    +

    + Indique au mixer d'activer cette action. Cette méthode peut être chaînée.

    + + Note: Activer cette action ne signifie pas nécessairement que l'animation démarrera directement: + Si l'action s'était déjà terminée avant (en atteignant la fin de sa dernière boucle), ou si une durée + pour un départ différé a été renseignée (via [page:.startAt startAt]), un [page:.reset reset] doit être + éxécuté avant. Quelques autres paramètres ([page:.paused paused]=true, [page:.enabled enabled]=false, + [page:.weight weight]=0, [page:.timeScale timeScale]=0) peuvent empêcher cette animation d'être jouée, + également. +

    + +

    [method:this reset]()

    +

    + Réinitialise l'action. Cette méthode peut être chaînée.

    + + Cette méthode passe [page:.paused paused] à false, [page:.enabled enabled] à true, + [page:.time time] à `0`, annule tous les fondus et warping programmés, retire le compteur + de boucles interne et les départs différés programmés.

    + + Note: .`reset` est toujours appelé par [page:.stop stop], mais .`reset` n'appelle pas .`stop` de lui-même. + Cela signifie que: Si vous voulez à la fois, réinitialiser et stopper, n'appellez pas .`reset`; mais .`stop`. +

    + +

    [method:this setDuration]( [param:Number durationInSeconds] )

    +

    + Renseigne la durée pour une seule boucle de cette action (en modifiant [page:.timeScale timeScale] + et en stoppant tous les warpings programmés). Cette méthode peut être chaînée. +

    + +

    [method:this setEffectiveTimeScale]( [param:Number timeScale] )

    +

    + Renseigne le [page:.timeScale timeScale] et stoppe tous les warpings programmés. Cette méthode peut être chaînée.

    + + Si [page:.paused paused] est à false, l'échelle temporelle effective (propriété interne) sera également + mise à cette valeur; par ailleurs l'échelle temporelle effective (affectant directement l'animation à + cet instant) sera mis à `0`.

    + + Note: .`paused` ne sera pas automatiquement mis à `true`, si le .`timeScale` est mis à `0` par + cette méthode. +

    + +

    [method:this setEffectiveWeight]( [param:Number weight] )

    +

    + Renseigne le [page:.weight weight] et stop tous les fondus programmés. Cette méthode peut être chaînée.

    + + Si [page:.enabled enabled] est à true, le weight effectif (propriété interne) sera également mis + à cette valeur; Par ailleurs le weight effectif (affectant directement l'action à cet instant) + sera mis à `0`.

    + + Note: .`enabled` ne sera pas automatiquement mis à `false`, si le .`weight` est mis à `0` par + cette méthode. +

    + +

    [method:this setLoop]( [param:Number loopMode], [param:Number repetitions] )

    +

    + Renseigne le [page:.loop loop mode] et le nombre de [page:.repetitions répétitions]. Cette méthode + peut être chaînée. +

    + +

    [method:this startAt]( [param:Number startTimeInSeconds] )

    +

    + Définis le temps pour un départ différé (généralement [page:AnimationMixer.time] + + deltaTimeInSeconds). Cette méthode peut être chaînée.

    + + Note: Cette action ne commencera qu'à un temps donné, si .`startAt` est chaîné avec + [page:.play play], ou si l'action a déjà été activée dans le mixer (par un appel précédent + de .`play`, sans l'avoir stoppée ou réinitialisée entre temps). +

    + +

    [method:this stop]()

    +

    + Indique au mixer de désactiver cette action. Cette méthode peut être chaînée.

    + + L'action sera immédiatement stoppée et complètement [page:.reset reset].

    + + Note: Vous pouvez stopper simultanément toutes les actions actives d'un même mixer via + [page:AnimationMixer.stopAllAction mixer.stopAllAction]. +

    + +

    [method:this stopFading]()

    +

    + Stoppe tous les [page:.fadeIn fondus] programmés qui sont appliqués à cette action. Cette méthode peut être + chaînée. +

    + +

    [method:this stopWarping]()

    +

    + Stoppe tous les [page:.warp warping] programmés qui sont appliqués à cette action. Cette méthode peut être + chaînée. +

    + +

    [method:this syncWith]( [param:AnimationAction otherAction] )

    +

    + Synchronise cette action avec l'action passée en paramètre. Cette méthode peut être chaînée.

    + + La synchronisation est faite en dupliquant les valeurs du [page:.time time] et du [page:.timeScale timeScale] de l'autre action + (stoppant tous les warpings programmés).

    + + Note: Les changements futurs du `time` et du `timeScale` de l'autre action ne seront pas détéctés. +

    + +

    [method:this warp]( [param:Number startTimeScale], [param:Number endTimeScale], [param:Number durationInSeconds] )

    +

    + Change la vitesse de lecture, durant l'intervalle temporelle passée en paramètre, en modifiant le + [page:.timeScale timeScale] graduellement depuis `startTimeScale` jusqu'à `endTimeScale`. Cette méthode + peut être chaînée. +

    + + +

    Évènements

    + + +

    + Il y a deux évènements indiquant quand une boucle de l'animation ou l'animation elle-même s'est terminée. Vous pouvez y réagir avec: +

    + + mixer.addEventListener( 'loop', function( e ) { …} ); // properties of e: type, action and loopDelta + mixer.addEventListener( 'finished', function( e ) { …} ); // properties of e: type, action and direction + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/animation/AnimationClip.html b/docs/api/fr/animation/AnimationClip.html new file mode 100644 index 00000000000000..5adf329c74dad2 --- /dev/null +++ b/docs/api/fr/animation/AnimationClip.html @@ -0,0 +1,148 @@ + + + + + + + + + +

    [name]

    + +

    + Un AnimationClip est un ensemble réutilisable de pistes de keyframes qui représentent une animation.

    + + Pour un aperçu des différents éléments du système d'animation de three.js consultez + l'article "Système d'Animation" dans le section "Étapes Suivantes" du manuel. +

    + + +

    Constructeur

    + + +

    [name]( [param:String name], [param:Number duration], [param:Array tracks] )

    +

    + [page:String name] - un nom pour ce clip.
    + [page:Number duration] - la durée du clip (en secondes). Si une valeur négative est renseignée, + la durée sera calculée depuis le tableau `tracks` passé en paramètres.
    + [page:Array tracks] - un tableau de [page:KeyframeTrack KeyframeTracks].

    + + Note: Au lieu d'instantier un AnimationClip directement avec le constructeur, vous pouvez utiliser une de + ses méthodes statiques pour créer des AnimationClips: depuis un JSON ([page:.parse parse]), depuis une séquence de + morph target ([page:.CreateFromMorphTargetSequence CreateFromMorphTargetSequence], + [page:.CreateClipsFromMorphTargetSequences CreateClipsFromMorphTargetSequences]) ou depuis + une hiérarchie d'animations ([page:.parseAnimation parseAnimation]) - si votre modèle n'a pas encore + d'AnimationClips dans le tableau d'animations de sa forme. +

    + + +

    Propriétés

    + + +

    [property:Number duration]

    +

    + La durée de ce clip (en secondes). Elle peut être calculée depuis le tableau [page:.tracks tracks] + via [page:.resetDuration resetDuration]. +

    + +

    [property:String name]

    +

    + Un nom pour ce clip. Un clip peut être recherché via [page:.findByName findByName]. +

    + +

    [property:Array tracks]

    +

    + Un tableau contenant un [page:KeyframeTrack] pour chaque propriété qui est animée par ce clip. +

    + +

    [property:String uuid]

    +

    + Le [link:http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] de cette instance du clip. + Elle est assignée automatiquement et ne doit pas être modifiée. +

    + + +

    Méthodes

    + + +

    [method:AnimationClip clone]()

    +

    + Renvoie une copie de ce clip. +

    + +

    [method:this optimize]()

    +

    + Optimise chaque track en retirant les clés séquentielles équivalentes (qui sont communes dans les séquences + de morph target). +

    + +

    [method:this resetDuration]()

    +

    + Fixe la [page:.duration durée] de ce clip à la durée de son plus long + [page:KeyframeTrack]. +

    + +

    [method:Object toJSON]()

    +

    + Renvoie un objet JSON représentant le clip d'animation serialisé. +

    + +

    [method:this trim]()

    +

    + Réduit la durée de chaque track à celle du clip. +

    + +

    [method:Boolean validate]()

    +

    + Performe une validation minimale de chaque track du clip. Renvoie true si toutes les tracks sont valides. +

    + + +

    Méthodes Statiques

    + + +

    [method:Array CreateClipsFromMorphTargetSequences]( [param:String name], [param:Array morphTargetSequence], [param:Number fps], [param:Boolean noLoop] )

    +

    + Renvoie un tableau de nouveaux AnimationClips créés depuis les séquences de morph + target d'une forme, essayant de trier les noms des morph targets en un pattern basé sur le groupe d'animation + comme "Walk_001, Walk_002, Run_001, Run_002 ...". +

    + +

    [method:AnimationClip CreateFromMorphTargetSequence]( [param:String name], [param:Array morphTargetSequence], [param:Number fps], [param:Boolean noLoop] )

    +

    + Renvoie un nouvel AnimationClip depuis le tableau de morph targets d'une forme, prenant un nom et un nombre de frames par secondes.

    + + Note: Le paramètre fps est requis, mais la vitesse d'animation peut être écrasée dans un + `AnimationAction` via [page:AnimationAction.setDuration animationAction.setDuration]. +

    + +

    [method:AnimationClip findByName]( [param:Object objectOrClipArray], [param:String name] )

    +

    + Cherche un AnimationClip grâce à son nom, prenant en premier paramètre un tableau + d'AnimationClips, un mesh ou une forme qui contient un tableau nommé "animations". +

    + +

    [method:AnimationClip parse]( [param:Object json] )

    +

    + Analyse une représentation JSON d'un clip et renvoie un AnimationClip. +

    + +

    [method:AnimationClip parseAnimation]( [param:Object animation], [param:Array bones] )

    +

    + Analyse le format de l'animation.hierarchy et retourne un AnimationClip. +

    + +

    [method:Object toJSON]( [param:AnimationClip clip] )

    +

    + Prends un AnimationClip et renvoie un objet JSON. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/animation/AnimationMixer.html b/docs/api/fr/animation/AnimationMixer.html new file mode 100644 index 00000000000000..badb2513e7b9a5 --- /dev/null +++ b/docs/api/fr/animation/AnimationMixer.html @@ -0,0 +1,118 @@ + + + + + + + + + +

    [name]

    + +

    + L'AnimationMixer et un lecteur d'animations pour un objet ciblé dans la scène. Quand + plusieurs objets sont animés indépendamment, un AnimationMixer peut être utilisé pour + chaque objet.

    + + Pour un aperçu des différents éléments du système d'animation de three.js consultez + l'article "Système d'Animation" dans le section "Étapes Suivantes" du manuel. +

    + + +

    Constructeur

    + + +

    [name]( [param:Object3D rootObject] )

    +

    + [page:Object3D rootObject] - l'objet duquel les animations doivent être jouées par ce mixer.
    +

    + + +

    Propriétés

    + + +

    [property:Number time]

    +

    + La durée du mixer global (en secondes; commençant à `0` à la création du mixer). +

    + +

    [property:Number timeScale]

    +

    + Un facteur de mise à l'échelle pour le [page:.time mixer time].

    + + Note: Mettre le timeScale du mixer à `0` puis le remettre à après `1` et un moyen de mettre en pause/reprendre + toutes les actions contrôlées par ce mixer. +

    + + +

    Méthodes

    + + +

    [method:AnimationAction clipAction]([param:AnimationClip clip], [param:Object3D optionalRoot])

    +

    + Renvoie une [page:AnimationAction] pour le clip passé en paramètre, utilisant optionnellement un objet racine + différent de celui du mixer. Le premier paramètre peut être un objet [page:AnimationClip] + ou le nom d'un AnimationClip.

    + + Si une action correspondant au clip et aux paramètres racine n'existe pas encore, elle sera créée + par cette méthode. Appeler cette méthode plusieurs fois avec le même clip est les mêmes paramètres racine retournera + toujours la même instance du clip. +

    + +

    [method:AnimationAction existingAction]([param:AnimationClip clip], [param:Object3D optionalRoot])

    +

    + Renvoie un [page:AnimationAction] existant pour le clip passé en paramètre, utilisant optionnellement un objet racine + différent de celui du mixer.

    + + Le premier paramètre peut être un objet de l'[page:AnimationClip] ou le nom d'un AnimationClip. +

    + +

    [method:Object3D getRoot]()

    +

    + Renvoie l'objet racine de ce mixer. +

    + +

    [method:this stopAllAction]()

    +

    + Désactive toutes les actions précedemment programmées pour ce mixer. +

    + +

    [method:this update]([param:Number deltaTimeInSeconds])

    +

    + Augmente la durée du mixer global et met à jour les animations en fonction de cette durée.

    + + Cela est généralement fait dans la boucle de rendu, en utilisant [page:Clock.getDelta clock.getDelta] mis à l'échelle par le [page:.timeScale timeScale] du mixer. +

    + +

    [method:this setTime]([param:Number timeInSeconds])

    +

    + Fixe le mixer global à une durée spécifique et met à jour les animations en fonction de cette durée.

    + + C'est utile quand vous avez besoin de vous rendre à un moment précis d'une animation. Le paramètre d'entrée sera mis à l'échelle par le [page:.timeScale timeScale] du mixer. +

    + +

    [method:undefined uncacheClip]([param:AnimationClip clip])

    + +

    + Désalloue toutes les ressources mémoires d'un clip. Appelez [page:AnimationAction.stop]() pour toutes les actions concernées avant d'utiliser cette méthode. +

    + +

    [method:undefined uncacheRoot]([param:Object3D root])

    +

    + Désalloue toutes les ressources mémoires d'un objet racine. Appelez [page:AnimationAction.stop]() pour toutes les actions concernées avant d'utiliser cette méthode. +

    + +

    [method:undefined uncacheAction]([param:AnimationClip clip], [param:Object3D optionalRoot])

    +

    + Désalloue toutes les ressources mémoires d'une action. Appelez [page:AnimationAction.stop]() pour désactiver l'action avant d'utiliser cette méthode. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/animation/AnimationObjectGroup.html b/docs/api/fr/animation/AnimationObjectGroup.html new file mode 100644 index 00000000000000..dcbe0f7c569324 --- /dev/null +++ b/docs/api/fr/animation/AnimationObjectGroup.html @@ -0,0 +1,91 @@ + + + + + + + + + +

    [name]

    + +

    Un groupe d'objets qui reçoivent un état d'animation partagé.

    + + Pour un aperçu des différents éléments du système d'animation de three.js consultez + l'article "Système d'Animation" dans le section "Étapes Suivantes" du manuel. +

    + +

    Utilisation:

    + +

    + Ajoutez les objets que vous auriez passés comme 'root' au constructeur ou à la méthode [page:AnimationMixer.clipAction clipAction] + de l'[page:AnimationMixer AnimationMixer] et passez à la place cet objet en tant que 'root'.

    + + Notez que les objets de cette classe apparaissent comme n'étant qu'un seul objet pour le mixer, + donc les contrôles concernant les objets individuels doivent être réalisés sur le groupe. +

    + + +

    Limitations

    +

    + Les propriétés animées doivent être compatibles avec tous les objets du groupe.

    + + Une propriété peut être controlée soit directement, soit à travers un groupe cible, mais pas les deux. +

    + + +

    Constructeur

    + +

    [name]( [param:Object obj1], [param:Object obj2], [param:Object obj3], ... )

    +

    + [page:Object obj] - un nombre arbitraire de meshes qui partagent le même état d'animation. +

    + +

    Propriétés

    + +

    [property:Boolean isAnimationObjectGroup]

    +

    + Flag en lecture seule pour vérifier si un objet donné est du type [name]. +

    + + +

    [property:Object stats]

    +

    + Un objet qui contient certaines informations concernant cet `AnimationObjectGroup` (nombre total, nombre + utilisé, nombre d'affectations par objets) +

    + +

    [property:String uuid]

    +

    + Le [link:http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] de cet + `AnimationObjectGroup`. Il est assigné automatiquement et ne doit pas être modifié. +

    + + +

    Methods

    + + +

    [method:undefined add]( [param:Object obj1], [param:Object obj2], [param:Object obj3], ... )

    +

    + Ajoute un nombre arbitraire d'objets à cet `AnimationObjectGroup`. +

    + +

    [method:undefined remove]( [param:Object obj1], [param:Object obj2], [param:Object obj3], ... )

    +

    + Retire un nombre arbitraire d'objets de cet `AnimationObjectGroup`. +

    + +

    [method:undefined uncache]( [param:Object obj1], [param:Object obj2], [param:Object obj3], ... )

    +

    + Désalloue toutes les ressources mémoires des objets de cet `AnimationObjectGroup` passés en paramètres. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/animation/AnimationUtils.html b/docs/api/fr/animation/AnimationUtils.html new file mode 100644 index 00000000000000..562e08b04fa4b4 --- /dev/null +++ b/docs/api/fr/animation/AnimationUtils.html @@ -0,0 +1,67 @@ + + + + + + + + + +

    [name]

    + +

    + Un objet avec de nombreuses fonctions qui peuvent aider à manipuler les animations, utilisé en interne. +

    + + +

    Méthodes

    + + +

    [method:Array arraySlice]( array, from, to )

    +

    + Cette méthode est la même que Array.prototype.slice, mais fonctionne également sur les tableaux typés. +

    + +

    [method:Array convertArray]( array, type, forceClone )

    +

    + Convertis un tableau en un type spécifique. +

    + +

    [method:Array flattenJSON]( jsonKeys, times, values, valuePropertyName )

    +

    + Utilisé pour l'analyse des formats de keyframes AOS. +

    + +

    [method:Array getKeyframeOrder]( times )

    +

    + Retourne un tableau dans lequel les durées et les valeurs peuvent-être triées. +

    + +

    [method:Boolean isTypedArray]( object )

    +

    + Renvoie `true` si l'objet est un tableau typé. +

    + +

    [method:AnimationClip makeClipAdditive]( [param:AnimationClip targetClip], [param:Number referenceFrame], [param:AnimationClip referenceClip], [param:Number fps] )

    +

    + Convertis les keyframes de l'animation passée en paramètre en un format additif. +

    + +

    [method:Array sortedArray]( values, stride, order )

    +

    + Trie le tableau précedemment renvoyé par [page:AnimationUtils.getKeyframeOrder getKeyframeOrder]. +

    + +

    [method:AnimationClip subclip]( [param:AnimationClip clip], [param:String name], [param:Number startFrame], [param:Number endFrame], [param:Number fps] )

    +

    + Crée un nouveau clip, ne contenant que les segments du clip original compris dans l'intervalle de frames passée en paramètre. +

    + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/animation/KeyframeTrack.html b/docs/api/fr/animation/KeyframeTrack.html new file mode 100644 index 00000000000000..6226ef14192d6d --- /dev/null +++ b/docs/api/fr/animation/KeyframeTrack.html @@ -0,0 +1,262 @@ + + + + + + + + + + +

    [name]

    + +

    + Un KeyframeTrack est une séquence chronométrée de [link:https://en.wikipedia.org/wiki/Key_frame keyframes], + qui est composée de listes de durées et de valeurs connexes, qui sont utilisées pour animer + une propriété spécifique d'un objet. +

    + +

    + Pour avoir un aperçu des différents éléments du système d'animation de three.js, consultez + l'article "Système d'Animation" dans la section "Étapes Suivantes" du manuel. +

    + +

    + Contrairement à la hiérarchie d'animation du + [link:https://github.com/mrdoob/three.js/wiki/JSON-Model-format-3 JSON model format] un + `KeyframeTrack` ne stocke pas ses keyframes comme étant des objets dans un tableau à "clés" (stockant + les durées et les valeurs pour chaque frame ensemble à un même endroit). +

    + +

    + A la place, il y a toujours deux tableaux dans un `KeyframeTrack`: le tableau [page:.times times] + stocke les durées pour chaque keyframes de ce track dans un ordre séquentiel, et le tableau + [page:.values values] array contient les valeurs modifiées correspondantes de la propriété animée. +

    + +

    + Une simple valeur, appartenant à un certain point temporel, ne peut pas simplement être un nombre, mais (par + exemple) un vecteur (si c'est une position qui est animée) ou un quaternion (si c'est une rotation qui est animée). Pour + cette raison, le tableau de valeurs (qui est également un tableau à une dimension) peut être de trois ou quatre fois la taille du + tableau de durées. +

    + +

    + Il existe plusieurs sous-classes de `KeyframeTrack` correspondant aux différents + types possibles de valeurs animées, héritant de la plupart des propriétés et méthodes: +

    + +
      +
    • [page:BooleanKeyframeTrack]
    • +
    • [page:ColorKeyframeTrack]
    • +
    • [page:NumberKeyframeTrack]
    • +
    • [page:QuaternionKeyframeTrack]
    • +
    • [page:StringKeyframeTrack]
    • +
    • [page:VectorKeyframeTrack]
    • +
    + +

    + Quelques exemples qui montrent comment créer manuellement un [page:AnimationClip AnimationClips] avec différentes sortes + de KeyframeTracks peuvent être trouvés dans le fichier [link:https://threejs.org/examples/jsm/animation/AnimationClipCreator.js AnimationClipCreator]. +

    + +

    + Étant donné que les valeurs explicites ne sont spécifiées que pour les points temporels discrets stocké dans le tableau de durées, + toutes les valeurs du milieu doivent être interpolées. +

    + +

    + Le nom du track est important pour la connexion de ce track avec une propriété spécifique du + node animé (fait par [page:PropertyBinding]). +

    + + +

    Constructeur

    + + +

    [name]( [param:String name], [param:Array times], [param:Array values], [param:Constant interpolation] )

    +

    + [page:String name] - l'identifiant du `KeyframeTrack`.
    + [page:Array times] - un tableau des durées des keyframes, convertis en interne en un + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array].
    + [page:Array values] - un tableau avec les valeurs concernant le tableau de durées, convertis en interne en un + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array].
    + [page:Constant interpolation] - le type d'interpolation à utiliser. Voir + [page:Animation Animation Constants] pour les valeurs possibles. La valeur par défaut est [page:Animation InterpolateLinear]. +

    + + +

    Propriétés

    + + +

    [property:String name]

    +

    + Le nom du track peut faire référence à des morph targets ou à des [page:SkinnedMesh bones] ou possiblement d'autres valeurs de l'objet animé. Voir + [page:PropertyBinding.parseTrackName] pour les types de strings qui peuvent être assemblés: +

    + +

    + Le nom peut spécifier le noeud en utilisant son nom ou son uuid (bien qu'il doive être dans le + sous-arbre du noeud du graphe de scène passé dans le mixer). Ou, si le nom du track commence par un point, + le track s'applique au noeud racine qui a été passé en paramètre du mixer. +

    + +

    + Généralement après le noeud une propriété est spécifiée directement. Mais vous pouvez également spécifier une + sous-propriété, comme .rotation[x], si vous voulez seulement contrôler X composants de la rotation + via une float track. +

    + +

    + Vous pouvez également spécifier des bones ou des multimatériaux en utilisant un nom d'objet, par exemple: + .bones[R_hand].scale; le canal rouge de la couleur diffuse du quatrième matériau dans un + tableau de matériaux - comme autre exemple - peut être accédé avec .materials[3].diffuse[r]. +

    + +

    + PropertyBinding résoudra également les noms de morph target, par exemple: .morphTargetInfluences[run]. +

    + +

    + Note: Le nom de track ne doit pas nécessairement être unique. Plusieurs tracks peuvent gérer la même + propriété. Le résultat doit être basé sur un mélange pondéré entre les mutiples tracks selon + le poids de leurs actions respectives. +

    + +

    [property:Float32Array times]

    +

    + Un [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array], + convertis depuis le tableau de durées qui est passé en paramètre au constructeur. +

    + +

    [property:Float32Array values]

    +

    + Un [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array], + convertis depuis le tableau de valeurs qui est passé en paramètre au constructeur. +

    + +

    [property:Constant DefaultInterpolation]

    +

    + Le type d'interpolation par défaut: [page:Animation InterpolateLinear]. +

    + +

    [property:Constant TimeBufferType ]

    +

    + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array], + le type de buffer utilisé en interne pour les durées. +

    + +

    [property:Constant ValueBufferType ]

    +

    + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array], + le type de buffer utilisé en interne pour les valeurs. +

    + + +

    Méthodes

    + + +

    [method:KeyframeTrack clone]()

    +

    + Renvoie une copie de ce track. +

    + +

    [method:Interpolant createInterpolant]()

    +

    + Crée un [page:LinearInterpolant LinearInterpolant], un [page:CubicInterpolant CubicInterpolant] + ou un [page:DiscreteInterpolant DiscreteInterpolant], selon la valeur du paramètre d'interpolation + passé au constructeur. +

    + +

    [method:Interpolant getInterpolation]()

    +

    + Renvoie le type d'interpolation. +

    + +

    [method:Number getValueSize]()

    +

    + Retourne la taille de chaque valeur (qui est la taille du tableau de [page:.values valeurs] divisé + par la longueur du tableau [page:.times times]). +

    + +

    [method:DiscreteInterpolant InterpolantFactoryMethodDiscrete]( [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array result] )

    +

    + Crée un nouveau [page:DiscreteInterpolant DiscreteInterpolant] depuis le + [page:KeyframeTrack.times times] et [page:KeyframeTrack.times values]. Un Float32Array peut être + passé en paramètre, il recevra les résultats. Autrement, un nouveau tableau avec la taille appropriée sera + créé automatiquement. +

    + +

    [method:LinearInterpolant InterpolantFactoryMethodLinear]( [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array result] )

    +

    + Crée un nouveau [page:LinearInterpolant LinearInterpolant] depuis le + [page:KeyframeTrack.times times] et [page:KeyframeTrack.times values]. Un Float32Array peut être + passé en paramètre, il recevra les résultats. Autrement, un nouveau tableau avec la taille appropriée sera + créé automatiquement. +

    + +

    [method:CubicInterpolant InterpolantFactoryMethodSmooth]( [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array result] )

    +

    + Crée un nouveau [page:CubicInterpolant CubicInterpolant] depuis le + [page:KeyframeTrack.times times] et [page:KeyframeTrack.times values]. Un Float32Array peut être + passé en paramètre, il recevra les résultats. Autrement, un nouveau tableau avec la taille appropriée sera + créé automatiquement. +

    + +

    [method:this optimize]()

    +

    + Retire les clés séquentielles équivalentse, qui sont communes dans les séquences de morph target. +

    + +

    [method:this scale]()

    +

    + Met à l'échelle chaque vecteur grâce à un facteur.

    + + Note: C'est utile, par exemple, pour convertir à un certain taux de frames par secondes (comme + réalisé en interne par + [page:AnimationClip.CreateFromMorphTargetSequence animationClip.CreateFromMorphTargetSequence]). +

    + +

    [method:this setInterpolation]( [param:Constant interpolationType] )

    +

    + Renseigne le type d'interpolation. Voir [page:Animation Animation Constants] pour les choix. +

    + +

    [method:this shift]( [param:Number timeOffsetInSeconds] )

    +

    + Déplace tous les keyframes avant ou après dans le temps. +

    + + +

    [method:this trim]( [param:Number startTimeInSeconds], [param:Number endTimeInSeconds] )

    +

    + Retire les keyframes avant `startTime` et après `endTime`, + sans changer de valeurs entre [`startTime`, `endTime`]. +

    + +

    [method:Boolean validate]()

    +

    + Performe une validation minimale de chaque track du clip. Renvoie true si toutes les tracks sont valides. +

    + +

    + Cette méthode envoie des erreurs à la console, si un track est vide, si la [page:.valueSize value taille] n'est pas valide, si un élémént + dans le tableau [page:.times times] ou [page:.values values] n'est pas un nombre valide ou si les éléménts du tableau `times` sont désorganisés. +

    + +

    Méthodes Statiques

    + +

    [method:JSON toJSON]( [param:KeyframeTrack track] )

    +

    + Convertis le track en JSON. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/animation/PropertyBinding.html b/docs/api/fr/animation/PropertyBinding.html new file mode 100644 index 00000000000000..8bcd357f50edad --- /dev/null +++ b/docs/api/fr/animation/PropertyBinding.html @@ -0,0 +1,132 @@ + + + + + + + + + +

    [name]

    + +

    + Sert de référence à une propriété réelle dans le graphe de scène; utilisé en interne. +

    + + +

    Constructeur

    + + +

    [name]( [param:Object3D rootNode], path, parsedPath )

    +

    + -- [page:Object3D rootNode]: + -- path + -- parsedPath (optionnel) + +

    + +

    Propriétés

    + +

    [property:Number path]

    +

    + +

    + +

    [property:Number parsedPath]

    +

    + +

    + +

    [property:Number node]

    +

    + +

    + +

    [property:Number rootNode]

    +

    + +

    + +

    [property:Object BindingType]

    +

    + +

    + +

    [property:Object Versioning]

    +

    + +

    + +

    [property:Array GetterByBindingType]

    +

    + +

    + +

    [property:Array SetterByBindingTypeAndVersioning]

    +

    + +

    + + + +

    Méthodes

    + +

    [method:undefined getValue]( [param:Array targetArray], [param:Number offset] )

    +

    +

    + +

    [method:undefined setValue]( [param:Array sourceArray], [param:Number offset] )

    +

    +

    + +

    [method:undefined bind]( )

    +

    + Crée une paire getter / setter pour une propriété du graphe de scène. Utilisée en interne par + [page:PropertyBinding.getValue getValue] et [page:PropertyBinding.setValue setValue]. +

    + +

    [method:undefined unbind]( )

    +

    + Détruit la paire getter / setter pour une propriété du graphe de scène. +

    + +

    [method:Constructor Composite]( targetGroup, path, optionalParsedPath )

    +

    + Crée un nouveau composite PropertyBinding. +

    + +

    [method:Constructor create]( root, path, parsedPath )

    +

    + Crée un nouveau composite PropertyBinding (si la source est un [page:AnimationObjectGroup]) ou un PropertyBinding. +

    + +

    [method:Constructor parseTrackName]( trackName )

    +

    + Correspond aux strings dans les formes suivantes:
    + -- nodeName.property
    + -- nodeName.property[accessor]
    + -- nodeName.material.property[accessor]
    + -- uuid.property[accessor]
    + -- uuid.objectName[objectIndex].propertyName[propertyIndex]
    + -- parentName/nodeName.property
    + -- parentName/parentName/nodeName.property[index]
    + -- .bone[Armature.DEF_cog].position
    + -- scene:helium_balloon_model:helium_balloon_model.position +

    + +

    [method:Constructor findNode]( root, nodeName )

    +

    + Trouve un node dans un node tree ou dans un [page:Skeleton Skeleton]. +

    + + + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/animation/PropertyMixer.html b/docs/api/fr/animation/PropertyMixer.html new file mode 100644 index 00000000000000..f4a2a58a1a3f70 --- /dev/null +++ b/docs/api/fr/animation/PropertyMixer.html @@ -0,0 +1,112 @@ + + + + + + + + + +

    [name]

    + +

    + Propriété de graphe de scène stockée en mémoire tampon qui permet une accumulation pondérée; utilisée en interne. +

    + + +

    Constructeur

    + + +

    [name]( [param:PropertyBinding binding], [param:String typeName], [param:Number valueSize] )

    +

    + -- binding
    + -- typeName
    + -- valueSize
    +

    + + +

    Propriétés

    + + +

    [property:PropertyBinding binding]

    +

    + +

    + +

    [property:TypedArray buffer]

    +

    + Tampon de la taille [page:PropertyMixer valueSize] * 4.

    + Disposition: [ incoming | accu0 | accu1 | orig ]

    + Les interpolateurs peuvent utiliser .buffer comme .result, les données vont dans 'incoming'. + Les frames de 'accu0' et 'accu1' sont entrelacés afin d'obtenir le résultat intermédiaire et + sont ensuite comparés pour détecter des changements. 'orig' stocke l'état original de la propriété. +

    + +

    [property:Number cumulativeWeight]

    +

    + La valeur par défaut est `0`. +

    + +

    [property:Number cumulativeWeightAdditive]

    +

    + La valeur par défaut est `0`. +

    + +

    [property:Number valueSize]

    +

    + +

    + +

    [property:Number referenceCount]

    +

    + La valeur par défaut est `0`. +

    + +

    [property:Number useCount]

    +

    + La valeur par défaut est `0`. +

    + + +

    Méthodes

    + + +

    [method:undefined accumulate]( [param:Number accuIndex], [param:Number weight] )

    +

    + Accumule les données de la région 'incoming' du tampon [page:PropertyMixer.buffer buffer][accuIndex] dans 'accu[i]'.
    + + Si le weight est de `0` cela ne fera rien. +

    + +

    [method:undefined accumulateAdditive]( [param:Number weight] )

    +

    + Accumule les données de la région 'incoming' dans 'add'.
    + + Si le weight est de `0` cela ne fera rien. +

    + + +

    [method:undefined apply]( [param:Number accuIndex] )

    +

    + Applique l'état de [page:PropertyMixer.buffer buffer] 'accu[i]' quand les accus diffèrent. +

    + +

    [method:undefined saveOriginalState]( )

    +

    + Récupère l'état de la propriété concernée et l'applique aux deux accus. +

    + +

    [method:undefined restoreOriginalState]( )

    +

    + Applique l'état antérieur via 'saveOriginalState'. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/animation/tracks/BooleanKeyframeTrack.html b/docs/api/fr/animation/tracks/BooleanKeyframeTrack.html new file mode 100644 index 00000000000000..cd6d6c8ff10589 --- /dev/null +++ b/docs/api/fr/animation/tracks/BooleanKeyframeTrack.html @@ -0,0 +1,79 @@ + + + + + + + + + + + [page:KeyframeTrack] → + +

    [name]

    + +

    + Un suivi des valeurs booléennes des keyframes. +

    + + +

    Constructeur

    + + +

    [name]( [param:String name], [param:Array times], [param:Array values] )

    +

    + [page:String name] - (requis) indentifiant du KeyframeTrack.
    + [page:Array times] - (requis) tableau de durée des keyframes.
    + [page:Array values] - valeurs des keyframes aux temps spécifiés.
    +

    + + +

    Propriétés

    + + +

    + Voir [page:KeyframeTrack] pour les propriétés héritées. +

    + +

    [property:Constant DefaultInterpolation]

    +

    + Le type d'interpolation à utiliser par défaut, [page:Animation InterpolateDiscrete]. +

    + +

    [property:Array ValueBufferType]

    +

    + Un tableau classique (pas de Float32Array dans ce cas, contrairement à `ValueBufferType` de [page:KeyframeTrack]). +

    + +

    [property:String ValueTypeName]

    +

    + String 'bool'. +

    + + +

    Méthodes

    + + +

    + Voir [page:KeyframeTrack] pour les propriétés héritées. +

    + +

    [method:undefined InterpolantFactoryMethodLinear ]()

    +

    + La valeur de cette méthode ici est 'undefined', étant donné que cela n'a pas de sens pour les propriétés discrètes. +

    + +

    [method:undefined InterpolantFactoryMethodSmooth ]()

    +

    + La valeur de cette méthode ici est 'undefined', étant donné que cela n'a pas de sens pour les propriétés discrètes. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/animation/tracks/ColorKeyframeTrack.html b/docs/api/fr/animation/tracks/ColorKeyframeTrack.html new file mode 100644 index 00000000000000..7e4312100f9b44 --- /dev/null +++ b/docs/api/fr/animation/tracks/ColorKeyframeTrack.html @@ -0,0 +1,63 @@ + + + + + + + + + + + [page:KeyframeTrack] → + +

    [name]

    + +

    + Un suivi des valeurs représentant les changements de couleur des keyframes.

    + L'implémentation basique de ces sous-classes n'a rien de spécial pour l'instant. Toutefois, c'est ici + qu'à lieu le paramétrage des espaces colorimétriques. +

    + + +

    Constructeur

    + + +

    [name]( [param:String name], [param:Array times], [param:Array values] )

    +

    + [page:String name] - (requis) indentifiant du KeyframeTrack.
    + [page:Array times] - (requis) tableau de durée des keyframes.
    + [page:Array values] - valeurs des keyframes aux temps spécifiés, un tableau à une dimension de composants de couleur entre 0 et 1.
    + [page:Constant interpolation] - le type d'interpolation à utiliser. Voir + [page:Animation Animation Constants] pour les valeurs possibles. La valeur par défaut est + [page:Animation InterpolateLinear]. +

    + + +

    Propriétés

    + + +

    + Voir [page:KeyframeTrack] pour les propriétés héritées. +

    + +

    [property:String ValueTypeName]

    +

    + String 'color'. +

    + + +

    Méthodes

    + + +

    + Voir [page:KeyframeTrack] pour les propriétés héritées. +

    + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/animation/tracks/NumberKeyframeTrack.html b/docs/api/fr/animation/tracks/NumberKeyframeTrack.html new file mode 100644 index 00000000000000..6f34e54f3319dd --- /dev/null +++ b/docs/api/fr/animation/tracks/NumberKeyframeTrack.html @@ -0,0 +1,63 @@ + + + + + + + + + + + [page:KeyframeTrack] → + +

    [name]

    + +

    + Un suivi des valeurs numériques des keyframes. +

    + + +

    Constructeur

    + + +

    [name]( [param:String name], [param:Array times], [param:Array values] )

    +

    + [page:String name] - (requis) indentifiant du KeyframeTrack.
    + [page:Array times] - (requis) tableau de durée des keyframes.
    + [page:Array values] - valeurs des keyframes aux temps spécifiés.
    + [page:Constant interpolation] - le type d'interpolation à utiliser. Voir + [page:Animation Animation Constants] pour les valeurs possibles. La valeur par défaut est + [page:Animation InterpolateLinear]. +

    + + +

    Propriétés

    + + +

    + Voir [page:KeyframeTrack] pour les propriétés héritées. +

    + + +

    [property:String ValueTypeName]

    +

    + String 'number'. +

    + + +

    Méthodes

    + + +

    + Voir [page:KeyframeTrack] pour les propriétés héritées. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/animation/tracks/QuaternionKeyframeTrack.html b/docs/api/fr/animation/tracks/QuaternionKeyframeTrack.html new file mode 100644 index 00000000000000..4af13884b08de5 --- /dev/null +++ b/docs/api/fr/animation/tracks/QuaternionKeyframeTrack.html @@ -0,0 +1,74 @@ + + + + + + + + + + + [page:KeyframeTrack] → + +

    [name]

    + +

    + Un suivi des valeurs quaternaires des keyframes. +

    + + +

    Constructeur

    + + +

    [name]( [param:String name], [param:Array times], [param:Array values] )

    +

    + [page:String name] - (requis) indentifiant du KeyframeTrack.
    + [page:Array times] - (requis) tableau de durée des keyframes.
    + [page:Array values] - valeurs des keyframes aux temps spécifiés, un tableau à une dimension de composants quaternaires.
    + [page:Constant interpolation] - le type d'interpolation à utiliser. Voir + [page:Animation Animation Constants] pour les valeurs possibles. La valeur par défaut est + [page:Animation InterpolateLinear]. +

    + + +

    Propriétés

    + + +

    + Voir [page:KeyframeTrack] pour les propriétés héritées. +

    + +

    [property:Constant DefaultInterpolation]

    +

    + Le type d'interpolation à utiliser par défaut, [page:Animation InterpolateLinear]. +

    + +

    [property:String ValueTypeName]

    +

    + String 'quaternion'. +

    + + +

    Méthodes

    + + +

    + Voir [page:KeyframeTrack] pour les propriétés héritées. +

    + +

    [method:QuaternionLinearInterpolant InterpolantFactoryMethodLinear]()

    +

    + Renvoie un nouveau [page:QuaternionLinearInterpolant QuaternionLinearInterpolant] basé sur les valeurs + [page:KeyframeTrack.values values], [page:KeyframeTrack.times times] et + [page:KeyframeTrack.valueSize valueSize] des keyframes. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/animation/tracks/StringKeyframeTrack.html b/docs/api/fr/animation/tracks/StringKeyframeTrack.html new file mode 100644 index 00000000000000..210f28dd4183f3 --- /dev/null +++ b/docs/api/fr/animation/tracks/StringKeyframeTrack.html @@ -0,0 +1,82 @@ + + + + + + + + + + + [page:KeyframeTrack] → + +

    [name]

    + +

    + Un suivi des valeurs strings des keyframes. +

    + + +

    Constructeur

    + + +

    [name]( [param:String name], [param:Array times], [param:Array values] )

    +

    + [page:String name] - (requis) indentifiant du KeyframeTrack.
    + [page:Array times] - (requis) tableau de durée de keyframes.
    + [page:Array values] - valeurs des keyframes aux temps spécifiés.
    + [page:Constant interpolation] - le type d'interpolation à utiliser. Voir + [page:Animation Animation Constants] pour les valeurs possibles. La valeur par défaut est + [page:Animation InterpolateDiscrete]. +

    + + +

    Propriétés

    + + +

    + Voir [page:KeyframeTrack] pour les propriétés héritées. +

    + +

    [property:Constant DefaultInterpolation]

    +

    + Le type d'interpolation à utiliser par défaut, [page:Animation InterpolateDiscrete]. +

    + +

    [property:Array ValueBufferType]

    +

    + Un tableau classique (pas de Float32Array dans ce cas, contrairement à `ValueBufferType` de [page:KeyframeTrack]). +

    + +

    [property:String ValueTypeName]

    +

    + String 'string'. +

    + + +

    Méthodes

    + + +

    + Voir [page:KeyframeTrack] pour les propriétés héritées. +

    + +

    [method:undefined InterpolantFactoryMethodLinear]()

    +

    + La valeur de cette méthode ici est 'undefined', étant donné que cela n'a pas de sens pour les propriétés discrètes. +

    + +

    [method:undefined InterpolantFactoryMethodSmooth]()

    +

    + La valeur de cette méthode ici est 'undefined', étant donné que cela n'a pas de sens pour les propriétés discrètes. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/animation/tracks/VectorKeyframeTrack.html b/docs/api/fr/animation/tracks/VectorKeyframeTrack.html new file mode 100644 index 00000000000000..64dd6ac16ec11b --- /dev/null +++ b/docs/api/fr/animation/tracks/VectorKeyframeTrack.html @@ -0,0 +1,62 @@ + + + + + + + + + + + [page:KeyframeTrack] → + +

    [name]

    + +

    + Un suivi des valeurs vectorielles des keyframes. +

    + + +

    Constructeur

    + + +

    [name]( [param:String name], [param:Array times], [param:Array values] )

    +

    + [page:String name] - (requis) indentifiant du KeyframeTrack.
    + [page:Array times] - (requis) tableau de durée des keyframes.
    + [page:Array values] - valeurs des keyframes aux temps spécifiés, un tableau à une dimension de composants de vecteurs.
    + [page:Constant interpolation] - le type d'interpolation à utiliser. Voir + [page:Animation Animation Constants] pour les valeurs possibles. La valeur par défaut est + [page:Animation InterpolateLinear]. +

    + + +

    Propriétés

    + + +

    + Voir [page:KeyframeTrack] pour les propriétés héritées. +

    + +

    [property:String ValueTypeName]

    +

    + String 'vector'. +

    + + +

    Méthodes

    + + +

    + Voir [page:KeyframeTrack] pour les propriétés héritées. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/audio/Audio.html b/docs/api/fr/audio/Audio.html new file mode 100644 index 00000000000000..7fd8a665b7c604 --- /dev/null +++ b/docs/api/fr/audio/Audio.html @@ -0,0 +1,248 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + Crée un objet audio non-positionnel ( global ).

    + + La [link:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API Web Audio API] est utilisée. +

    + +

    Exemple de Code

    + + + // create an AudioListener and add it to the camera + const listener = new THREE.AudioListener(); + camera.add( listener ); + + // create a global audio source + const sound = new THREE.Audio( listener ); + + // load a sound and set it as the Audio object's buffer + const audioLoader = new THREE.AudioLoader(); + audioLoader.load( 'sounds/ambient.ogg', function( buffer ) { + sound.setBuffer( buffer ); + sound.setLoop( true ); + sound.setVolume( 0.5 ); + sound.play(); + }); + + +

    Exemples

    + +

    + [example:webaudio_sandbox webaudio / sandbox ]
    + [example:webaudio_visualizer webaudio / visualizer ] +

    + +

    Constructeur

    + + +

    [name]( [param:AudioListener listener] )

    +

    + listener — (requis) instance d'[page:AudioListener AudioListener]. +

    + + +

    Propriétés

    + +

    [property:Boolean autoplay]

    +

    Démarrage automatique de la lecture. La valeur par défaut est `false`.

    + +

    [property:AudioContext context]

    +

    L'[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext] du [page:AudioListener listener] passé au constructeur.

    + +

    [property:Number detune]

    +

    Modifie le ton, mesuré en centaines. +/- 100 est un demi-ton. +/- 1200 est un octave. La valeur par défaut est `0`.

    + +

    [property:Array filters]

    +

    Représente un tableau d'[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNodes]. Peut être utilisé pour appliquer une variété de filtres d'ordres inférieurs pour créer des effets sonores complexes. + Dans la plupart des cas, le tableau contient des instances de [link:https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode BiquadFilterNodes]. Les filtres sont appliqués via [page:Audio.setFilter] ou [page:Audio.setFilters].

    + +

    [property:GainNode gain]

    +

    Un [link:https://developer.mozilla.org/en-US/docs/Web/API/GainNode GainNode] créé + en utilisant [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createGain AudioContext.createGain]().

    + +

    [property:Boolean hasPlaybackControl]

    +

    Définit si la lecture peut-être contrôlée en utilisant les méthodes [page:Audio.play play](), + [page:Audio.pause pause]() etc. La valeur par défaut est `true`.

    + +

    [property:Boolean isPlaying]

    +

    Indique si l'audio est en cours de lecture.

    + +

    [property:AudioListener listener]

    +

    Une reference à l'objet listener de cet audio.

    + +

    [property:Number playbackRate]

    +

    Vitesse de lecture. La valeur par défaut est `1`.

    + +

    [property:Number offset]

    +

    Un décalage temporel après lequel la lecture doit commencer. Équivalent au paramètre `offset` de [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start](). La valeur par défaut est `0`.

    + +

    [property:Number duration]

    +

    Écrase la durée de l'audio. Équivalent au paramètre `duration` de [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start](). La valeur par défaut est `undefined` afin de jour le buffer entier.

    + +

    [property:String source]

    +

    Un [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode AudioBufferSourceNode] créé + en utilisant [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createBufferSource AudioContext.createBufferSource]().

    + +

    [property:String sourceType]

    +

    Type de source audio. La valeur par défaut est 'empty'.

    + +

    [property:String type]

    +

    String indiquant le type, contenant 'Audio'.

    + + +

    Méthodes

    + +

    [method:this connect]()

    +

    + Connecte à la [page:Audio.source] audio. Ceci est utilisé en interne à l'initialisation et lors + de l'ajout/retrait de filtres. +

    + +

    [method:this disconnect]()

    +

    + Déconnecte de la [page:Audio.source]. Ceci est utilisé en interne lors + de l'ajout/retrait de filtres. +

    + +

    [method:Float getDetune]()

    +

    + Renvoie le detuning de l'oscillation en centaines. +

    + +

    [method:BiquadFilterNode getFilter]()

    +

    + Renvoie le premier élément du tableau [page:Audio.filters filters]. +

    + +

    [method:Array getFilters]()

    +

    + Renvoie le tableau [page:Audio.filters filters]. +

    + +

    [method:Boolean getLoop]()

    +

    + Renvoie la valeur de [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loop source.loop] + (Indique si la lecture doit boucler). +

    + +

    [method:GainNode getOutput]()

    +

    + Renvoie le [page:Audio.gain gainNode]. +

    + +

    [method:Float getPlaybackRate]()

    +

    + Renvoie la valeur de [page:Audio.playbackRate playbackRate]. +

    + +

    [method:Float getVolume]( value )

    +

    + Renvoie le volume actuel. +

    + +

    [method:this play]( delay )

    +

    + Si [page:Audio.hasPlaybackControl hasPlaybackControl] est à true, la lecture se lance. +

    + +

    [method:this pause]()

    +

    + Si [page:Audio.hasPlaybackControl hasPlaybackControl] est à true, la lecture se met en pause. +

    + +

    [method:undefined onEnded]()

    +

    + Appelée automatiquement quand la lecture est terminée. +

    + +

    [method:this setBuffer]( audioBuffer )

    +

    + Met la [page:Audio.source source] à audioBuffer, et met le [page:Audio.sourceType sourceType] à 'buffer'.
    + Si [page:Audio.autoplay autoplay] est activé, la méthode démarrera également la lecture. +

    + +

    [method:this setDetune]( [param:Float value] )

    +

    + Définit le detuning de l'oscillation en centaines. +

    + +

    [method:this setFilter]( filter )

    +

    + Applique un noeud à filtre unique à l'audio. +

    + +

    [method:this setFilters]( [param:Array value] )

    +

    + value - tableau de filtres.
    + Applique un tableau de noeuds de filtres à l'audio. +

    + +

    [method:this setLoop]( [param:Boolean value] )

    +

    + Met [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loop source.loop] à `value` + (Indique si la lecture doit boucler). +

    + +

    [method:this setLoopStart]( [param:Float value] )

    +

    + Met [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopStart source.loopStart] à `value`. +

    + +

    [method:this setLoopEnd]( [param:Float value] )

    +

    + Met [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopEnd source.loopEnd] à `value`. +

    + +

    [method:this setMediaElementSource]( mediaElement )

    +

    + Définit le type d'objet passé en paramètre [link:https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement HTMLMediaElement] comme source de l'audio.
    + Met également [page:Audio.hasPlaybackControl hasPlaybackControl] à false. +

    + +

    [method:this setMediaStreamSource]( mediaStream )

    +

    + Définit le type d'objet passé en paramètre [link:https://developer.mozilla.org/en-US/docs/Web/API/MediaStream MediaStream] comme source de l'audio.
    + Met également [page:Audio.hasPlaybackControl hasPlaybackControl] à false. +

    + +

    [method:this setNodeSource]( audioNode )

    +

    + Met la [page:Audio.source source] à audioBuffer, et met le [page:Audio.sourceType sourceType] à 'audioNode'.
    + Met également [page:Audio.hasPlaybackControl hasPlaybackControl] à false. + +

    + +

    [method:this setPlaybackRate]( [param:Float value] )

    +

    + Si [page:Audio.hasPlaybackControl hasPlaybackControl] est activé, mets le [page:Audio.playbackRate playbackRate] à `value`. +

    + +

    [method:this setVolume]( [param:Float value] )

    +

    + Modifie le volume. +

    + +

    [method:this stop]()

    +

    + Si [page:Audio.hasPlaybackControl hasPlaybackControl] est activé, la lecture est stoppée. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/audio/AudioAnalyser.html b/docs/api/fr/audio/AudioAnalyser.html new file mode 100644 index 00000000000000..1ff06e15e62238 --- /dev/null +++ b/docs/api/fr/audio/AudioAnalyser.html @@ -0,0 +1,100 @@ + + + + + + + + + +

    [name]

    + +

    + Crée un objet AudioAnalyser, qui utilise un [link:https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode AnalyserNode] + afin d'analyser les données audio.

    + + La [link:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API Web Audio API] est utilisée. + +

    + +

    Exemple de Code

    + + + // create an AudioListener and add it to the camera + const listener = new THREE.AudioListener(); + camera.add( listener ); + + // create an Audio source + const sound = new THREE.Audio( listener ); + + // load a sound and set it as the Audio object's buffer + const audioLoader = new THREE.AudioLoader(); + audioLoader.load( 'sounds/ambient.ogg', function( buffer ) { + sound.setBuffer( buffer ); + sound.setLoop(true); + sound.setVolume(0.5); + sound.play(); + }); + + // create an AudioAnalyser, passing in the sound and desired fftSize + const analyser = new THREE.AudioAnalyser( sound, 32 ); + + // get the average frequency of the sound + const data = analyser.getAverageFrequency(); + + +

    Exemples

    + +

    + [example:webaudio_sandbox webaudio / sandbox ]
    + [example:webaudio_visualizer webaudio / visualizer ] +

    + +

    Constructeur

    + + +

    [name]( audio, [link:https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/fftSize fftSize] )

    +

    + Crée un nouvel [page:AudioAnalyser AudioAnalyser]. +

    + + +

    Propriétés

    + +

    [property:AnalyserNode analyser]

    +

    Un [link:https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode AnalyserNode] utilisé pour analyser l'audio.

    + +

    [property:Integer fftSize]

    +

    + Une puissance de deux non-nulle inférieure ou égale à 2048, représentant la taille de la FFT (Fast Fourier Transform - Transformation de Fourier Rapide) à utiliser pour déterminer le domaine de fréquence. + Consulter [link:https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/fftSize cette page] pour obtenir plus de détails. +

    + +

    [property:Uint8Array data]

    +

    + Un Uint8Array avec une taille determinée par [link:https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/frequencyBinCount analyser.frequencyBinCount] + utilisé pour stocker les données d'analyse. +

    + + +

    Méthodes

    + + +

    [method:Uint8Array getFrequencyData]()

    +

    + Utilise la méthode [link:https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getByteFrequencyData getByteFrequencyData] de l'API Web Audio. + Voir cette page. +

    + +

    [method:Number getAverageFrequency]()

    +

    + Recupère la moyenne des fréquences retournées par la méthode [page:AudioAnalyser.getFrequencyData getFrequencyData]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/audio/AudioContext.html b/docs/api/fr/audio/AudioContext.html new file mode 100644 index 00000000000000..c136d204277618 --- /dev/null +++ b/docs/api/fr/audio/AudioContext.html @@ -0,0 +1,43 @@ + + + + + + + + + + +

    [name]

    + +

    + Contient des méthodes afin de configurer un [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext].

    + + Utilisé en interne par les classes [page:AudioListener AudioListener] et [page:AudioLoader AudioLoader] classes.

    + + La [link:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API Web Audio API] est utilisée. +

    + + + +

    Méthodes

    + +

    [method:AudioContext getContext]()

    +

    + Renvoie la valeur de la variable `context` dans la portée extérieure, si elle est définie, + sinon lui assigne un nouvel [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext]. +

    + +

    [method:AudioContext setContext]( [param:AudioContext value] )

    +

    + Met la variable `context` dans la portée extérieure à `value`. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/audio/AudioListener.html b/docs/api/fr/audio/AudioListener.html new file mode 100644 index 00000000000000..e4d8526a0a77cc --- /dev/null +++ b/docs/api/fr/audio/AudioListener.html @@ -0,0 +1,112 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + Le [name] représente un [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioListener listener] virtuel de tous les effets audio positionnels et non-positionnels dans la scène.
    + Une application three.js crée généralement une instance unique de [name]. C'est un paramètre de constructeur obligatoire pour les entités audio comme [page:Audio Audio] et [page:PositionalAudio PositionalAudio].
    + Dans la plupart des cas, l'objet listener est un enfant de la caméra. Donc la transformation 3D de la caméra représente la transformation 3D du listener. +

    + +

    Exemple de Code

    + + + // create an AudioListener and add it to the camera + const listener = new THREE.AudioListener(); + camera.add( listener ); + + // create a global audio source + const sound = new THREE.Audio( listener ); + + // load a sound and set it as the Audio object's buffer + const audioLoader = new THREE.AudioLoader(); + audioLoader.load( 'sounds/ambient.ogg', function( buffer ) { + sound.setBuffer( buffer ); + sound.setLoop(true); + sound.setVolume(0.5); + sound.play(); + }); + + +

    Exemples

    + +

    + [example:webaudio_sandbox webaudio / sandbox ]
    + [example:webaudio_timing webaudio / timing ]
    + [example:webaudio_visualizer webaudio / visualizer ] +

    + +

    Constructeur

    + + +

    [name]( )

    +

    + Crée un nouvel AudioListener. +

    + + +

    Propriétés

    + +

    [property:AudioContext context]

    +

    L'[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext] du [page:AudioListener listener] passé au constructeur.

    + +

    [property:GainNode gain]

    +

    Un [link:https://developer.mozilla.org/en-US/docs/Web/API/GainNode GainNode] créé + en utilisant [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createGain AudioContext.createGain]().

    + +

    [property:AudioNode filter]

    +

    La valeur par défaut est `null`.

    + +

    [property:Number timeDelta]

    +

    La valeur du delta temporel pour les entités audio. Utilisé dans le contexte [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/linearRampToValueAtTime AudioParam.linearRampToValueAtTimeDefault](). La valeur par défaut est `0`.

    + +

    Méthodes

    + + +

    [method:GainNode getInput]()

    +

    + Renvoie le [page:AudioListener.gain gainNode]. +

    + +

    [method:this removeFilter]()

    +

    + Assigne la propriété [page:AudioListener.filter filter] à `null`. +

    + +

    [method:AudioNode getFilter]()

    +

    + Renvoie la valeur de la propriété [page:AudioListener.filter filter]. +

    + +

    [method:this setFilter]( [param:AudioNode value] )

    +

    + Assigne la propriété [page:AudioListener.filter filter] à `value`. +

    + +

    [method:Float getMasterVolume]()

    +

    + Renvoie le volume. +

    + +

    [method:this setMasterVolume]( [param:Number value] )

    +

    + Modifie le volume. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/audio/PositionalAudio.html b/docs/api/fr/audio/PositionalAudio.html new file mode 100644 index 00000000000000..a3b3bbd12d720c --- /dev/null +++ b/docs/api/fr/audio/PositionalAudio.html @@ -0,0 +1,136 @@ + + + + + + + + + + [page:Object3D] → [page:Audio] → + +

    [name]

    + +

    + Crée un objet audio positionnel.

    + + La [link:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API Web Audio API] est utilisée. +

    + +

    Exemple de Code

    + + + // create an AudioListener and add it to the camera + const listener = new THREE.AudioListener(); + camera.add( listener ); + + // create the PositionalAudio object (passing in the listener) + const sound = new THREE.PositionalAudio( listener ); + + // load a sound and set it as the PositionalAudio object's buffer + const audioLoader = new THREE.AudioLoader(); + audioLoader.load( 'sounds/song.ogg', function( buffer ) { + sound.setBuffer( buffer ); + sound.setRefDistance( 20 ); + sound.play(); + }); + + // create an object for the sound to play from + const sphere = new THREE.SphereGeometry( 20, 32, 16 ); + const material = new THREE.MeshPhongMaterial( { color: 0xff2200 } ); + const mesh = new THREE.Mesh( sphere, material ); + scene.add( mesh ); + + // finally add the sound to the mesh + mesh.add( sound ); + + +

    Exemples

    + +

    + [example:webaudio_orientation webaudio / orientation ]
    + [example:webaudio_sandbox webaudio / sandbox ]
    + [example:webaudio_timing webaudio / timing ] +

    + +

    Constructeur

    + +

    [name]( [param:AudioListener listener] )

    +

    + listener — (requis) instance d'[page:AudioListener AudioListener]. +

    + + +

    Propriétés

    + +

    + Voir la classe [page:Audio Audio] pour les propriétés héritées. +

    + +

    [property:PannerNode panner]

    +

    Le [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode PannerNode] du PositionalAudio.

    + + +

    Méthodes

    + +

    + Voir la classe [page:Audio Audio] pour les propriétés héritées. +

    + +

    [method:PannerNode getOutput]()

    +

    + Renvoie le [page:PositionalAudio.panner panner]. +

    + +

    [method:Float getRefDistance]()

    +

    + Renvoie la valeur de [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/refDistance panner.refDistance]. +

    + +

    [method:this setRefDistance]( [param:Float value] )

    +

    + Assigne une valeur à [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/refDistance panner.refDistance]. +

    + +

    [method:Float getRolloffFactor]()

    +

    + Renvoie la valeur de [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/rolloffFactor panner.rolloffFactor]. +

    + +

    [method:this setRolloffFactor]( [param:Float value] )

    +

    + Assigne une valeur à [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/rolloffFactor panner.rolloffFactor]. +

    + +

    [method:String getDistanceModel]()

    +

    + Renvoie la valeur de [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/distanceModel panner.distanceModel]. +

    + +

    [method:this setDistanceModel]( [param:String value] )

    +

    + Assigne une valeur à [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/distanceModel panner.distanceModel]. +

    + +

    [method:Float getMaxDistance]()

    +

    + Renvoie la valeur de [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/maxDistance panner.maxDistance]. +

    + +

    [method:this setMaxDistance]( [param:Float value] )

    +

    + Assigne une valeur à [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/maxDistance panner.maxDistance]. +

    + +

    [method:this setDirectionalCone]( [param:Float coneInnerAngle], [param:Float coneOuterAngle], [param:Float coneOuterGain] )

    +

    + Cette méthode peut être utilisée pour transformer un son omnidirectionnel en un [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode son directionnel]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/cameras/ArrayCamera.html b/docs/api/fr/cameras/ArrayCamera.html new file mode 100644 index 00000000000000..d4076b0af243fe --- /dev/null +++ b/docs/api/fr/cameras/ArrayCamera.html @@ -0,0 +1,53 @@ + + + + + + + + + + [page:Object3D] → [page:Camera] → [page:PerspectiveCamera] → + +

    [name]

    + +

    + [name] peut être utilisé afin d'effectuer efficacement le rendu d'une scène avec un ensemble prédéfini de caméras. C'est un aspect important concernant les performances de rendu d'une scène VR.
    + Une instance de [name] a toujours un tableau de sous-caméras. Il est obligatoire de définir la propriété `viewport` pour chaque sous-caméra, cette propriété détermine la partie du viewport qui est rendue par cette caméra. +

    + +

    Exemples

    + +

    [example:webgl_camera_array camera / array ]

    + +

    Constructeur

    + +

    [name]( [param:Array array] )

    +

    + Un tableau de caméras. +

    + + +

    Propriétés

    +

    Voir la classe [page:PerspectiveCamera] pour connaître les propriétés communes.

    + +

    [property:Array cameras]

    +

    + Un tableau de caméras. +

    + +

    [property:Boolean isArrayCamera]

    +

    + Flag en lecture seul qui pemet de vérifier si un objet donné est de type [name]. +

    + +

    Méthodes

    +

    Voir la classe [page:PerspectiveCamera] pour connaître les propriétés communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/cameras/Camera.html b/docs/api/fr/cameras/Camera.html new file mode 100644 index 00000000000000..ccec2a0c45184a --- /dev/null +++ b/docs/api/fr/cameras/Camera.html @@ -0,0 +1,86 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + Classe abstraite pour les caméras. Cette classe doit toujours être héritée lorsque vous créez une nouvelle caméra. +

    + + +

    Constructeur

    + + +

    [name]()

    +

    + Crée une nouvelle [name]. Notez que cette classe n'est pas censée être appellée directement; + vous aurez sans doute besoin d'une [page:PerspectiveCamera] ou d'une [page:OrthographicCamera] à la place. +

    + + +

    Propriétés

    +

    Voir la classe [page:Object3D] pour connaître les propriétés communes.

    + +

    [property:Boolean isCamera]

    +

    + Flag en lecture seul qui pemet de vérifier si un objet donné est de type [name]. +

    + +

    [property:Layers layers]

    +

    + Les [page:Layers layers] dont la caméra font partie. C'est une propriété héritée + de [page:Object3D].

    + + Les objets doivent partager au moins une layer avec la caméra pour être visibles + quand le point de vue de la caméra est rendu. +

    + +

    [property:Matrix4 matrixWorldInverse]

    +

    + C'est l'inverse de matrixWorld. MatrixWorld contient la matrice qui contient + les transformations de cette Caméra. +

    + +

    [property:Matrix4 projectionMatrix]

    +

    C'est la matrice qui contient la projection.

    + +

    [property:Matrix4 projectionMatrixInverse]

    +

    L'inverse de projectionMatrix.

    + + +

    Méthodes

    +

    Voir la classe [page:Object3D] pour connaître les propriétés communes.

    + +

    [method:Camera clone]( )

    +

    + Retourne une nouvelle caméra avec les mêmes propriétés que celle-ci. +

    + +

    [method:this copy]( [param:Camera source], [param:Boolean recursive] )

    +

    + Copie les propriétés de la caméra source dans celle-ci. +

    + +

    [method:Vector3 getWorldDirection]( [param:Vector3 target] )

    +

    + [page:Vector3 target] — le résultat sera copié dans ce Vector3.

    + + Retourne un [page:Vector3] représentant la direction du monde vers laquelle la caméra pointe. + (Note: Une caméra regarde l'inverse de son axe-Z local ).

    +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/cameras/CubeCamera.html b/docs/api/fr/cameras/CubeCamera.html new file mode 100644 index 00000000000000..08df9e3f049b86 --- /dev/null +++ b/docs/api/fr/cameras/CubeCamera.html @@ -0,0 +1,88 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    Crée 6 caméras qui effectuent le rendu d'un [page:WebGLCubeRenderTarget].

    + +

    Exemple de Code

    + + + // Create cube render target + const cubeRenderTarget = new THREE.WebGLCubeRenderTarget( 128, { generateMipmaps: true, minFilter: THREE.LinearMipmapLinearFilter } ); + + // Create cube camera + const cubeCamera = new THREE.CubeCamera( 1, 100000, cubeRenderTarget ); + scene.add( cubeCamera ); + + // Create car + const chromeMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: cubeRenderTarget.texture } ); + const car = new THREE.Mesh( carGeometry, chromeMaterial ); + scene.add( car ); + + // Update the render target cube + car.visible = false; + cubeCamera.position.copy( car.position ); + cubeCamera.update( renderer, scene ); + + // Render the scene + car.visible = true; + renderer.render( scene, camera ); + + +

    Exemples

    + +

    + [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ] +

    + +

    Constructeur

    + + +

    [name]( [param:Number near], [param:Number far], [param:WebGLCubeRenderTarget renderTarget] )

    +

    + near -- La distance near de clipping.
    + far -- La distance far de clipping.
    + renderTarget -- Le CubeRenderTarget de destination. +

    + +

    + Construis une CubeCamera contenant 6 [page:PerspectiveCamera PerspectiveCameras] qui + effectuent le rendu d'un [page:WebGLCubeRenderTarget]. +

    + +

    Propriétés

    +

    Voir la classe [page:Object3D] pour connaître les propriétés communes.

    + +

    [property:WebGLCubeRenderTarget renderTarget]

    +

    + Le CubeRenderTarget de destination. +

    + +

    Méthodes

    +

    Voir la classe [page:Object3D] pour connaître les propriétés communes.

    + +

    [method:undefined update]( [param:WebGLRenderer renderer], [param:Scene scene] )

    +

    + renderer -- Le moteur de rendu WebGL actuel
    + scene -- La scène actuelle +

    +

    + Appellez cette méthode pour mettre à jour le [page:CubeCamera.renderTarget renderTarget]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/cameras/OrthographicCamera.html b/docs/api/fr/cameras/OrthographicCamera.html new file mode 100644 index 00000000000000..70391321f2ce55 --- /dev/null +++ b/docs/api/fr/cameras/OrthographicCamera.html @@ -0,0 +1,145 @@ + + + + + + + + + + [page:Object3D] → [page:Camera] → + +

    [name]

    + +

    + Caméra utilisant la [link:https://en.wikipedia.org/wiki/Orthographic_projection projection orthographique].

    + + Dans ce mode de projection, la taille d'un objet dans l'image rendue reste constante + peu importe sa distance à la caméra.

    + + Cela peut être utile pour effectuer le rendu de scènes 2D et d'éléments UI, entre autres. +

    + +

    Exemple de Code

    + + + const camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 ); + scene.add( camera ); + + +

    Exemples

    + +

    + [example:webgl_camera camera ]
    + [example:webgl_interactive_cubes_ortho interactive / cubes / ortho ]
    + [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]
    + [example:webgl_postprocessing_advanced postprocessing / advanced ]
    + [example:webgl_postprocessing_dof2 postprocessing / dof2 ]
    + [example:webgl_postprocessing_godrays postprocessing / godrays ]
    + [example:webgl_rtt rtt ]
    + [example:webgl_shaders_tonemapping shaders / tonemapping ]
    + [example:webgl_shadowmap shadowmap ] +

    + +

    Constructeur

    + + +

    [name]( [param:Number left], [param:Number right], [param:Number top], [param:Number bottom], [param:Number near], [param:Number far] )

    +

    + left — Plan gauche du frustum de la caméra.
    + right — Plan droit du frustum de la caméra.
    + top — Plan supérieur du frustum de la caméra.
    + bottom — Plan inférieur du frustum de la caméra.
    + near — Plan near du frustum de la caméra.
    + far — Plan far du frustum de la caméra.

    + + Ensemble ces propriétés définissent le [link:https://en.wikipedia.org/wiki/Viewing_frustum viewing frustum] de la caméra. +

    + + +

    Properties

    +

    + Voir la classe [page:Camera] pour connaître les propriétés communes.
    + Notez qu'après avoir changé la grande majorité de ces propriétés vous devrez appeler + [page:OrthographicCamera.updateProjectionMatrix .updateProjectionMatrix] afin que les changements prennent effet. +

    + +

    [property:Float bottom]

    +

    Plan inférieur du frustum de la caméra.

    + +

    [property:Float far]

    +

    + Plan far du frustum de la caméra. La valeur par défaut est `2000`.

    + + Doit être supérieur à la valeur actuelle du plan [page:.near near]. +

    + +

    [property:Boolean isOrthographicCamera]

    +

    + Flag en lecture seul qui pemet de vérifier si un objet donné est de type [name]. +

    + +

    [property:Float left]

    +

    Plan gauche du frustum de la caméra.

    + +

    [property:Float near]

    +

    + Plan near du frustum de la caméra. La valeur par défaut est `0.1`.

    + + L'intervalle valide est comprise entre `0` et la valeur actuelle du plan [page:.far far]. + Notez que, à l'inverse de la [page:PerspectiveCamera], `0` est une valeur valide pour + le plan near de l'OrthographicCamera. +

    + +

    [property:Float right]

    +

    Plan droit du frustum de la caméra.

    + +

    [property:Float top]

    +

    Plan supérieur du frustum de la caméra.

    + +

    [property:Object view]

    +

    Renseigné par [page:OrthographicCamera.setViewOffset setViewOffset]. La valeur par défaut est `null`.

    + +

    [property:number zoom]

    +

    Récupère ou renseigne le facteur de zoom de la caméra. La valeur par défaut est `1`.

    + +

    Methods

    +

    Voir la classe [page:Camera] pour connaître les propriétés communes.

    + +

    [method:undefined setViewOffset]( [param:Float fullWidth], [param:Float fullHeight], [param:Float x], [param:Float y], [param:Float width], [param:Float height] )

    +

    + fullWidth — largeur totale du setup multi-écrans
    + fullHeight — hauteur totale du setup multi-écrans
    + x — décalage horizontal de la sous-caméra
    + y — décalage vertical de la sous-caméra
    + width — largeur de la sous-caméra
    + height — hauteur de la sous-caméra

    + + Définis un décalage dans un frustum plus grand [link:https://en.wikipedia.org/wiki/Viewing_frustum viewing frustum]. + C'est utile pour un setup multi-écrans ou multi-machines. + Pour avoir un exemple d'utilisation voir [page:PerspectiveCamera.setViewOffset PerspectiveCamera]. +

    + +

    [method:undefined clearViewOffset]()

    +

    + Retire tout décalage mis en place par la méthode .setViewOffset. +

    + +

    [method:undefined updateProjectionMatrix]()

    +

    + Met à jour la matrice de projection de la caméra. Doit être appelé après chaque changement de paramètres. +

    + +

    [method:Object toJSON]([param:Object meta])

    +

    + meta -- objet contenant des metadatas comme des objets ou des textures dans des descendants des objets.
    + Convertis la caméra en [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format] three.js. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/cameras/PerspectiveCamera.html b/docs/api/fr/cameras/PerspectiveCamera.html new file mode 100644 index 00000000000000..2d4d749a2f85be --- /dev/null +++ b/docs/api/fr/cameras/PerspectiveCamera.html @@ -0,0 +1,206 @@ + + + + + + + + + + [page:Object3D] → [page:Camera] → + +

    [name]

    + +

    + Caméra qui utilise [link:https://en.wikipedia.org/wiki/Perspective_(graphical) perspective projection].

    + + Ce mode de projection est fait afin d'imiter la vision humaine. C'est le mode de + projection le plus communément utilisé afin d'effectuer le rendu d'une scène 3D. +

    + +

    Exemple de Code

    + + + const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 ); + scene.add( camera ); + + +

    Exemples

    + +

    + [example:webgl_animation_skinning_blending animation / skinning / blending ]
    + [example:webgl_animation_skinning_morph animation / skinning / morph ]
    + [example:webgl_effects_stereo effects / stereo ]
    + [example:webgl_interactive_cubes interactive / cubes ]
    + [example:webgl_loader_collada_skinning loader / collada / skinning ] +

    + +

    Constructeur

    + +

    [name]( [param:Number fov], [param:Number aspect], [param:Number near], [param:Number far] )

    +

    + fov — Champ de vision vertical du frustum de la caméra.
    + aspect — Ratio d'aspect du frustum de la caméra.
    + near — Plan near du frustum de la caméra.
    + far — Plan far du frustum de la caméra.

    + + Ensemble, ces valeurs définissent le [link:https://en.wikipedia.org/wiki/Viewing_frustum viewing frustum] de la caméra. +

    + + +

    Propriétés

    +

    + Voir la classe [page:Camera] pour connaître les propriétés communes.
    + Notez qu'après avoir changé la grande majorité de ces propriétés vous devrez appeller + [page:PerspectiveCamera.updateProjectionMatrix .updateProjectionMatrix] afin que les changements prennent effet. +

    + +

    [property:Float aspect]

    +

    Ratio d'aspect du frustum de la caméra, en général la largeur du canvas / sa hauteur. La valeur par défaut est `1` (canvas carré).

    + +

    [property:Float far]

    +

    + Plan far du frustum de la caméra. La valeur par défaut est `2000`.

    + + Doit être supérieur à la valeur actuelle du plan [page:.near near]. +

    + +

    [property:Float filmGauge]

    +

    Taille de la pellicule utilisée pour l'axe le plus grand. La valeur par défaut est 35 (millimètres). Ce paramètre n'influe pas sur la matrice de projection sauf si .filmOffset est à une valeur non-nulle

    + +

    [property:Float filmOffset]

    +

    Décalage horizontal dans la même unité que `.filmGauge`. La valeur par défaut est `0`.

    + +

    [property:Float focus]

    +

    Distance de l'objet utilisé pour les effets de stéréoscopie et de profondeur de champ. + Ce paramètre n'influe pas sur la matrice de projection sauf si une [page:StereoCamera] est utilisée. + La valeur par défaut est `10`. +

    + +

    [property:Float fov]

    +

    Champ de vision vertical du frustum de la caméra, du bas vers le haut de l'écran, en degrés. La valeur par défaut est `50`.

    + +

    [property:Boolean isPerspectiveCamera]

    +

    + Flag en lecture seul qui pemet de vérifier si un objet donné est de type [name]. +

    + + +

    [property:Float near]

    +

    + Plan near du frustum de la caméra. La valeur par défaut est `0.1`.

    + + L'intervalle valide est supérieure à 0 et inférieure à la valeur actuelle du plan [page:.far far]. + Notez que, à l'inverse de l'[page:OrthographicCamera], `0` n'est pas une valeur valide + pour le plan near d'une PerspectiveCamera. +

    + +

    [property:Object view]

    +

    + Spécification du frustum ou nul. + La valeur est fixée par la méthode [page:PerspectiveCamera.setViewOffset .setViewOffset] + et supprimée par la méthode [page:PerspectiveCamera.clearViewOffset .clearViewOffset]. +

    + +

    [property:number zoom]

    +

    Récupère ou renseigne le facteur de zoom de la caméra. La valeur par défaut est `1`.

    + + +

    Methods

    +

    Voir la classe [page:Camera] pour connaître les propriétés communes.

    + +

    [method:undefined clearViewOffset]()

    +

    Retire tout décalage mis en place par la méthode [page:PerspectiveCamera.setViewOffset .setViewOffset].

    + +

    [method:Float getEffectiveFOV]()

    +

    Retourne l'angle du champ de vision verticalen degrés en prenant en compte le .zoom.

    + +

    [method:Float getFilmHeight]()

    +

    + Retourne la hauteur de l'image dans la pellicule. Si .aspect est plus petit ou égal à un + (format portrait), le résultat est égal à .filmGauge. +

    + +

    [method:Float getFilmWidth]()

    +

    + Retourne la largeur de l'image dans la pellicule. Si .aspect est plus grand ou égal à un + (format paysage), le résultat est égal à .filmGauge. +

    + +

    [method:Float getFocalLength]()

    +

    Retourne la distance focale du .fov actuel par rapport au .filmGauge.

    + +

    [method:undefined setFocalLength]( [param:Float focalLength] )

    +

    + Définis une valeur pour le champ de vision en fonction de la distance focale par rapport à la [page:PerspectiveCamera.filmGauge .filmGauge] actuelle.

    + + Par défaut, la distance focale est spécifiée pour une caméra de 35mm (plein cadre). +

    + +

    [method:undefined setViewOffset]( [param:Float fullWidth], [param:Float fullHeight], [param:Float x], [param:Float y], [param:Float width], [param:Float height] )

    +

    + fullWidth — largeur totale du setup multi-écrans
    + fullHeight — hauteur totale du setup multi-écrans
    + x — décalage horizontal de la sous-caméra
    + y — décalage vertical de la sous-caméra
    + width — largeur de la sous-caméra
    + height — hauteur de la sous-caméra +

    + +

    + Définis un décalage dans un frustum plus grand. C'est utile pour un setup multi-écrans ou multi-machines. +

    + +

    + Par exemple, si vous avez 3x2 écrans, que chaque écran est un 1920x1080 et les écrans sont dans une grille comme suit:
    + +

    ++---+---+---+
    +| A | B | C |
    ++---+---+---+
    +| D | E | F |
    ++---+---+---+
    +		
    + + puis pour chaque écran vous l'appelleriez ainsi:
    + + 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 ); + + + Notez qu'il n'y a aucune raison que les écrans aient la même taille ou qu'ils soient dans une grille. +

    + +

    [method:undefined updateProjectionMatrix]()

    +

    + Met à jour la matrice de projection de la caméra. Doit être appelé après chaque changement de paramètres. +

    + +

    [method:Object toJSON]([param:Object meta])

    +

    + meta -- objet contenant des metadatas comme des objets ou des textures dans des descendants des objets.
    + Convertis la caméra en [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format] three.js. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/cameras/StereoCamera.html b/docs/api/fr/cameras/StereoCamera.html new file mode 100644 index 00000000000000..8a6d31ee726e35 --- /dev/null +++ b/docs/api/fr/cameras/StereoCamera.html @@ -0,0 +1,60 @@ + + + + + + + + + + +

    [name]

    + +

    + Double [page:PerspectiveCamera PerspectiveCamera]s utilisées pour réaliser des effets tels que + [link:https://en.wikipedia.org/wiki/Anaglyph_3D 3D Anaglyph] ou [link:https://en.wikipedia.org/wiki/parallax_barrier Parallax Barrier]. +

    + +

    Exemples

    + +

    + [example:webgl_effects_anaglyph effects / anaglyph ]
    + [example:webgl_effects_parallaxbarrier effects / parallaxbarrier ]
    + [example:webgl_effects_stereo effects / stereo ] +

    + +

    Constructeur

    + +

    [name]( )

    + +

    Propriétés

    + +

    [property:Float aspect]

    +

    La valeur par défaut est `1`.

    + +

    [property:Float eyeSep]

    +

    La valeur par défaut est `0.064`.

    + +

    [property:PerspectiveCamera cameraL]

    +

    Caméra gauche. Elle est ajoutée à [page:Layers layer 1] - les objets devant être rendus par + la caméra gauche doivent aussi être ajoutés à ce layer.

    + +

    [property:PerspectiveCamera cameraR]

    +

    Caméra droite.Elle est ajoutée à [page:Layers layer 2] - les objets devant être rendus par + la caméra droite doivent aussi être ajoutés à ce layer.

    + + +

    Méthodes

    + +

    [method:undefined update]( [param:PerspectiveCamera camera] )

    +

    + Met à jour les caméras stéréos selon la caméra passée en paramètre. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/constants/Animation.html b/docs/api/fr/constants/Animation.html new file mode 100644 index 00000000000000..62a750c50e52f5 --- /dev/null +++ b/docs/api/fr/constants/Animation.html @@ -0,0 +1,46 @@ + + + + + + + + + +

    Constantes d'animation

    + +

    Modes de boucle

    + + +THREE.LoopOnce +THREE.LoopRepeat +THREE.LoopPingPong + + +

    Modes d'interpolation

    + +THREE.InterpolateDiscrete +THREE.InterpolateLinear +THREE.InterpolateSmooth + + +

    Modes de fin

    + +THREE.ZeroCurvatureEnding +THREE.ZeroSlopeEnding +THREE.WrapAroundEnding + + +

    Modes de fusion d'animation

    + +THREE.NormalAnimationBlendMode +THREE.AdditiveAnimationBlendMode + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + diff --git a/docs/api/fr/constants/BufferAttributeUsage.html b/docs/api/fr/constants/BufferAttributeUsage.html new file mode 100644 index 00000000000000..d5e36bbb745699 --- /dev/null +++ b/docs/api/fr/constants/BufferAttributeUsage.html @@ -0,0 +1,51 @@ + + + + + + + + + +

    Constantes d'utilisation des attributs de buffer

    + +

    + Les constantes d'utilisation peuvent être utilisées pour fournir une indication à l'API concernant la manière dont l'attribut de mémoire tampon (buffer attribute) de géométrie sera utilisé afin d'optimiser les performances. +

    + +

    Exemple de code

    + + + const geometry = new THREE.BufferGeometry(); + const positionAttribute = new THREE.BufferAttribute( array, 3 , false ); + positionAttribute.setUsage( THREE.DynamicDrawUsage ); + geometry.setAttribute( 'position', positionAttribute ); + + +

    Exemples

    +

    [example:webgl_buffergeometry_drawrange materials / buffergeometry / drawrange ]

    + +

    Utilisation de la géométrie

    + + THREE.StaticDrawUsage + THREE.DynamicDrawUsage + THREE.StreamDrawUsage + + THREE.StaticReadUsage + THREE.DynamicReadUsage + THREE.StreamReadUsage + + THREE.StaticCopyUsage + THREE.DynamicCopyUsage + THREE.StreamCopyUsage + + + Pour plus d'informations sur chacune de ces constantes, voir [link:https://www.khronos.org/opengl/wiki/Buffer_Object#Buffer_Object_Usage this OpenGL documentation]. + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + diff --git a/docs/api/fr/constants/Core.html b/docs/api/fr/constants/Core.html new file mode 100644 index 00000000000000..1f6bc2203bc63a --- /dev/null +++ b/docs/api/fr/constants/Core.html @@ -0,0 +1,80 @@ + + + + + + + + + +

    Constantes de base

    + +

    Numéro de révision

    + + +THREE.REVISION + + +
    + Le [link:https://github.com/mrdoob/three.js/releases revision number] courant de three.js. +
    + +

    Espaces colorimétriques

    + +THREE.NoColorSpace +THREE.SRGBColorSpace +THREE.LinearSRGBColorSpace + +

    + [page:NoColorSpace] ne définit aucun espace colorimétrique spécifique. +

    +

    + [page:SRGBColorSpace] (“sRGB”) fait référence à l'espace colorimétrique défini par la Rec. 709 primaires, D65 + point blanc et fonctions de transfert sRGB non linéaires. sRGB est l'espace colorimétrique par défaut dans + CSS, et se trouve souvent dans les palettes de couleurs et les sélecteurs de couleurs. Les couleurs exprimées en + notation hexadécimale ou en CSS sont généralement dans l'espace colorimétrique sRGB. +

    + +

    + [page:LinearSRGBColorSpace] (“Linear-sRGB”) fait référence à l'espace colorimétrique sRGB (ci-dessus) avec + fonctions de transfert linéaires. Linear-sRGB est l'espace colorimétrique de travail dans three.js, utilisé + pendant la majeure partie du processus de rendu. Les composants RVB trouvés dans les matériaux three.js + et dans les shaders sont dans l'espace colorimétrique Linear-sRGB. +

    + +

    + Pour plus d'informations d'utilisation, voir Color management. +

    + +

    Boutons de la souris

    + +THREE.MOUSE.LEFT +THREE.MOUSE.MIDDLE +THREE.MOUSE.RIGHT +THREE.MOUSE.ROTATE +THREE.MOUSE.DOLLY +THREE.MOUSE.PAN + +

    + Les constantes LEFT et ROTATE ont la même valeur sous-jacente. + Les constantes MIDDLE et DOLLY ont la même valeur sous-jacente. + Les constantes RIGHT et PAN ont la même valeur sous-jacente. +

    + +

    Actions tactiles

    + +THREE.TOUCH.ROTATE +THREE.TOUCH.PAN +THREE.TOUCH.DOLLY_PAN +THREE.TOUCH.DOLLY_ROTATE + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + + + diff --git a/docs/api/fr/constants/CustomBlendingEquations.html b/docs/api/fr/constants/CustomBlendingEquations.html new file mode 100644 index 00000000000000..d3267a0c24b516 --- /dev/null +++ b/docs/api/fr/constants/CustomBlendingEquations.html @@ -0,0 +1,64 @@ + + + + + + + + + +

    Constantes d'équations de mélange personnalisées

    + +

    + Elles fonctionnent avec tous les types de matériaux. Définissez d'abord le mode de fusion du matériau sur THREE.CustomBlending, définissez ensuite l'équation de fusion, le facteur source et le facteur de destination souhaités. +

    + +

    Exemple de code

    + + + const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); + material.blending = THREE.CustomBlending; + material.blendEquation = THREE.AddEquation; //default + material.blendSrc = THREE.SrcAlphaFactor; //default + material.blendDst = THREE.OneMinusSrcAlphaFactor; //default + + +

    Exemples

    +

    [example:webgl_materials_blending_custom materials / blending / custom ]

    + +

    Équations de mélange

    + + THREE.AddEquation + THREE.SubtractEquation + THREE.ReverseSubtractEquation + THREE.MinEquation + THREE.MaxEquation + + +

    Facteurs sources

    + + THREE.ZeroFactor + THREE.OneFactor + THREE.SrcColorFactor + THREE.OneMinusSrcColorFactor + THREE.SrcAlphaFactor + THREE.OneMinusSrcAlphaFactor + THREE.DstAlphaFactor + THREE.OneMinusDstAlphaFactor + THREE.DstColorFactor + THREE.OneMinusDstColorFactor + THREE.SrcAlphaSaturateFactor + + +

    Facteur de déstination

    +

    + Tous les facteurs source sont valides comme facteurs de destination, à l'exception de THREE.SrcAlphaSaturateFactor +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + diff --git a/docs/api/fr/constants/Materials.html b/docs/api/fr/constants/Materials.html new file mode 100644 index 00000000000000..bff834df896bea --- /dev/null +++ b/docs/api/fr/constants/Materials.html @@ -0,0 +1,153 @@ + + + + + + + + + +

    Constantes de matériau

    + +

    + Ces constantes définissent des propriétés communes à tous les métériaux, + à l'exception de Texture Combine Operations qui s'applique uniquement à [page:MeshBasicMaterial.combine MeshBasicMaterial], [page:MeshLambertMaterial.combine MeshLambertMaterial] et [page:MeshPhongMaterial.combine MeshPhongMaterial].
    +

    + + +

    Côté

    + + THREE.FrontSide + THREE.BackSide + THREE.DoubleSide + +

    + Définit quel côté des faces sera rendu - avant, arrière ou les deux. + La valeur par défaut est [page:Constant FrontSide]. +

    + +

    Mode de fusion

    + + THREE.NoBlending + THREE.NormalBlending + THREE.AdditiveBlending + THREE.SubtractiveBlending + THREE.MultiplyBlending + THREE.CustomBlending + + + +

    + Ces constantes contrôlent les équations de mélange source et destination pour le RVB et l'Alpha du matériau envoyés au WebGLRenderer pour être utilisés par WebGL.
    + [page:Constant NormalBlending] est la valeur par défaut.
    + Remarque : [page:Constant CustomBlending] doit être définit pour utiliser [page:CustomBlendingEquation Custom Blending Equations].
    + Voir l'exemple [example:webgl_materials_blending materials / blending].
    +

    + +

    Mode de profondeur

    + + THREE.NeverDepth + THREE.AlwaysDepth + THREE.EqualDepth + THREE.LessDepth + THREE.LessEqualDepth + THREE.GreaterEqualDepth + THREE.GreaterDepth + THREE.NotEqualDepth + +

    + Quelle fonction de profondeur le matériau utilise pour comparer la profondeur Z des pixels entrants à la valeur actuelle du tampon de profondeur Z. Si le résultat de la comparaison est `true`(vrai), le pixel sera dessiné.
    + [page:Materials NeverDepth] ne renvoie jamais `true`.
    + [page:Materials AlwaysDepth] renvoie toujours `true`.
    + [page:Materials EqualDepth] renvoie `true` si la profondeur Z du pixel entrant est égale à la profondeur Z du tampon actuel.
    + [page:Materials LessDepth] renvoie `true` si la profondeur Z du pixel entrant est inférieure à la profondeur Z du tampon actuel.
    + [page:Materials LessEqualDepth] si la profondeur Z du pixel entrant est inférieure ou égale à la profondeur Z du tampon actuel.
    + [page:Materials GreaterEqualDepth] renvoie `true` si la profondeur Z du pixel entrant est supérieure ou égale à la profondeur Z du tampon actuel.
    + [page:Materials GreaterDepth] renvoie `true` si la profondeur Z du pixel entrant est supérieure à la profondeur Z du tampon actuel.
    + [page:Materials NotEqualDepth] renvoie `true` si la profondeur Z du pixel entrant est différente de la profondeur Z du tampon actuel.
    +

    + +

    Opérations de combinaison de textures

    + + THREE.MultiplyOperation + THREE.MixOperation + THREE.AddOperation + +

    + Ces constantes définissent comment le résultat de la couleur de la surface est combiné avec la carte d'environnement (environnement map) (si présente), pour [page:MeshBasicMaterial.combine MeshBasicMaterial], [page:MeshLambertMaterial.combine MeshLambertMaterial] et [page:MeshPhongMaterial.combine MeshPhongMaterial].
    + [page:Constant MultiplyOperation] est la valeur par défaut qui multiplie la carte d'environnement et la couleur de la surface.
    + [page:Constant MixOperation] utilise la réflectivité pour mélanger les deux couleurs.
    + [page:Constant AddOperation] ajoute les deux couleurs. +

    + +

    Fonctions de gabarit

    + + THREE.NeverStencilFunc + THREE.LessStencilFunc + THREE.EqualStencilFunc + THREE.LessEqualStencilFunc + THREE.GreaterStencilFunc + THREE.NotEqualStencilFunc + THREE.GreaterEqualStencilFunc + THREE.AlwaysStencilFunc + +

    + Quelle fonction de gabarit le matériau utilise pour déterminer s'il faut ou non effectuer une opération de gabarit.
    + [page:Materials NeverStencilFunc] ne renvoie jamais `true`.
    + [page:Materials LessStencilFunc] renvoie `true` si la valeur de référence du gabarit est inférieure à la valeur courante du gabarit.
    + [page:Materials EqualStencilFunc] renvoie `true` si la valeur de référence du gabarit est égale à la valeur courante du gabarit.
    + [page:Materials LessEqualStencilFunc] renvoie `true` si la valeur de référence du gabarit est inférieure ou égale à la valeur courante du gabarit.
    + [page:Materials GreaterStencilFunc] renvoie `true` si la valeur de référence du gabarit est supérieure à la valeur courante du gabarit.
    + [page:Materials NotEqualStencilFunc] renvoie `true` si la valeur de référence du gabarit est différente de la valeur courante du gabarit.
    + [page:Materials GreaterEqualStencilFunc] renvoie `true` si la valeur de référence du gabarit est supérieure ou égale à la valeur courante du gabarit.
    + [page:Materials AlwaysStencilFunc] renvoie toujours `true`.
    +

    + +

    Opérations de gabarit

    + + THREE.ZeroStencilOp + THREE.KeepStencilOp + THREE.ReplaceStencilOp + THREE.IncrementStencilOp + THREE.DecrementStencilOp + THREE.IncrementWrapStencilOp + THREE.DecrementWrapStencilOp + THREE.InvertStencilOp + +

    + Quelle opération de gabarit le matériau effectuera sur le pixel du tampon de gabarit si la fonction de gabarit fournie réussit.
    + [page:Materials ZeroStencilOp] définie la valeur du gabarit sur 0.
    + [page:Materials KeepStencilOp] ne change pas la valeur courante du gabarit.
    + [page:Materials ReplaceStencilOp] remplace la valeur du pochoir par la valeur de référence du pochoir spécifiée.
    + [page:Materials IncrementStencilOp] incrémente la valeur courante du gabarit de `1`.
    + [page:Materials DecrementStencilOp] décrémente la valeur courante du gabarit de `1`.
    + [page:Materials IncrementWrapStencilOp] incrémente la valeur courante du gabarit de `1`. Si la valeur incrémentée dépasse `255` elle sera définie à `0`.
    + [page:Materials DecrementWrapStencilOp] décrémente la valeur courante du gabarit de `1`. Si la valeur décrémentée dépasse `0` elle sera définie à `255`.
    + [page:Materials InvertStencilOp] Effectuera une inversion bit à bit de la valeur actuelle du pochoir.
    +

    + +

    Type de carte normale (normal map)

    + + THREE.TangentSpaceNormalMap + THREE.ObjectSpaceNormalMap + +

    + Ces constantes définissent les types de carte normale. + Pour TangentSpaceNormalMap, l'information est relative à la surface sous-jacente. + For ObjectSpaceNormalMap, l'information est relative à la rotation de l'objet. + La valeur par défaut est [page:Constant TangentSpaceNormalMap]. +

    + +

    Version GLSL

    + + THREE.GLSL1 + THREE.GLSL3 + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + diff --git a/docs/api/fr/constants/Renderer.html b/docs/api/fr/constants/Renderer.html new file mode 100644 index 00000000000000..99e06448d9d0d1 --- /dev/null +++ b/docs/api/fr/constants/Renderer.html @@ -0,0 +1,69 @@ + + + + + + + + + +

    Constantes du moteur de rendu WebGL

    + +

    Modes d'élimination de faces

    + + THREE.CullFaceNone + THREE.CullFaceBack + THREE.CullFaceFront + THREE.CullFaceFrontBack + +

    + [page:constant CullFaceNone] désactive l'élimination de face.
    + [page:constant CullFaceBack] élimine les faces arrières (par défaut).
    + [page:constant CullFaceFront] élimine les faces avant.
    + [page:constant CullFaceFrontBack] élimine les faces avant et arrière. +

    + +

    Types d'ombres

    + + THREE.BasicShadowMap + THREE.PCFShadowMap + THREE.PCFSoftShadowMap + THREE.VSMShadowMap + +

    + Ces constantes définissent les propriétés [page:WebGLRenderer.shadowMap.type shadowMap.type] du moteur de rendu WebGL.

    + + [page:constant BasicShadowMap] donne des textures d'ombres (shadow maps) non filtrées - plus rapide, mais de moins bonne qualité.
    + [page:constant PCFShadowMap] filtre les textures d'ombre à l'aide de l'algorithme PCF (percentage-closer filtering) (par défaut).
    + [page:constant PCFSoftShadowMap] filtre les textures d'ombre à l'aide de l'algorithme de filtrage en pourcentage plus proche (PCF) avec de meilleures ombres douces, en particulier lors de l'utilisation de cartes d'ombre à faible résolution.
    + [page:constant VSMShadowMap] filtre les textures d'ombres à l'aide de l'algorithme Variance Shadow Map (VSM). Lors de l'utilisation de VSMShadowMap, tous les récepteurs d'ombre projetteront également des ombres. +

    + +

    Cartographie des tons

    + + THREE.NoToneMapping + THREE.LinearToneMapping + THREE.ReinhardToneMapping + THREE.CineonToneMapping + THREE.ACESFilmicToneMapping + THREE.CustomToneMapping + +

    + Ces constantes définissent les propriétés [page:WebGLRenderer.toneMapping toneMapping] du moteur de rendu webGL. + Elles sont utilisées pour se rapprocher de l'apparence de la plage dynamique élevée (HDR) sur le + milieu de plage dynamique faible d'un écran d'ordinateur standard ou d'un écran d'appareil mobile. +

    +

    + THREE.LinearToneMapping, THREE.ReinhardToneMapping, THREE.CineonToneMapping et THREE.ACESFilmicToneMapping sont des implémentations intégrées à la cartographie des tons. + THREE.CustomToneMapping attend une implémentation personnalisée en modifiant le code GLSL du fragment shader du matériau. + Voir l'exemple [example:webgl_tonemapping WebGL / tonemapping]. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + diff --git a/docs/api/fr/constants/Textures.html b/docs/api/fr/constants/Textures.html new file mode 100644 index 00000000000000..8318f04598a352 --- /dev/null +++ b/docs/api/fr/constants/Textures.html @@ -0,0 +1,560 @@ + + + + + + + + + +

    Constantes de texture

    + +

    Modes de mappage

    + + THREE.UVMapping + THREE.CubeReflectionMapping + THREE.CubeRefractionMapping + THREE.EquirectangularReflectionMapping + THREE.EquirectangularRefractionMapping + THREE.CubeUVReflectionMapping + + +

    + Ces constantes définissent le mode de mappage des textures.
    + [page:Constant UVMapping] est la valeur par défaut et mappe la texture en utilisant les coordonnées UV du maillage.

    + + Les autres définissent les types de mappage d'environnement.

    + + [page:Constant CubeReflectionMapping] et [page:Constant CubeRefractionMapping] sont à utiliser avec + une [page:CubeTexture CubeTexture], qui est composée de six textures, une pour chaque face du cube. + [page:Constant CubeReflectionMapping] est la valeur par défaut pour une [page:CubeTexture CubeTexture].

    + + [page:Constant EquirectangularReflectionMapping] et [page:Constant EquirectangularRefractionMapping] + sont à utiliser avec une carte d'environnement équirectangulaire. Aussi appelée carte lat-long, une texture équirectangulaire représente une vue à 360 degrés le long de la ligne médiane horizontale et une vue à 180 degrés le long de la + axe vertical, avec les bords supérieur et inférieur de l'image correspondant aux pôles nord et sud + d'une sphère cartographiée.

    + + Voir l'exemple [example:webgl_materials_envmaps materials / envmaps]. +

    + + +

    Modes d'emballage

    + + THREE.RepeatWrapping + THREE.ClampToEdgeWrapping + THREE.MirroredRepeatWrapping + +

    + Ces constantes définissent les propriétés des textures [page:Texture.wrapS wrapS] et [page:Texture.wrapT wrapT], + qui définissent l'emballage de texture horizontal et vertical.

    + + Avec [page:constant RepeatWrapping] la texure se répetera simplement à l'infini.

    + + [page:constant ClampToEdgeWrapping] est la valeur par défaut. + Le dernier pixel de la texture s'étend jusqu'au bord du maillage.

    + + Avec [page:constant MirroredRepeatWrapping] la texure se répetera à l'infini avec un effet mirroir à chaque répétition. +

    + +

    Filtres de grossissement

    + + THREE.NearestFilter + THREE.LinearFilter + + +

    + À utiliser avec une propriété de texture [page:Texture.magFilter magFilter], + Ces constantes définissent la fonction de grossissement de texture à utiliser lorsque le pixel texturé correspond à une + surface inférieure ou égale à un élément de texture (texel).

    + + [page:constant NearestFilter] renvoie la valeur de l'élément de texture le plus proche + (en distance de Manhattan) aux coordonnées de texture spécifiées.

    + + [page:constant LinearFilter] est la valeur par défaut et renvoie la moyenne pondérée + des quatre éléments de texture les plus proches des coordonnées de texture spécifiées, + et peut inclure des éléments enveloppés ou répétés à partir d'autres parties d'une texture, + en fonction des valeurs de [page:Texture.wrapS wrapS], [page:Texture.wrapT wrapT], et de la cartographie exacte. +

    + +

    Filtres de réduction

    + + THREE.NearestFilter + THREE.NearestMipmapNearestFilter + THREE.NearestMipmapLinearFilter + THREE.LinearFilter + THREE.LinearMipmapNearestFilter + THREE.LinearMipmapLinearFilter + + +

    + Pour une utilisation avec la propriété [page:Texture.minFilter minFilter] d'une texture, ces constantes définissent + la fonction de minimisation de texture qui est utilisée chaque fois que le pixel texturé est mappé + à une zone supérieure à un élément de texture (texel). +

    + + En plus de [page:constant NearestFilter] et [page:constant LinearFilter], + les quatre fonctions suivantes peuvent être utilisées pour la minification :

    + + [page:constant NearestMipmapNearestFilter] choisit le mipmap le plus proche qui + correspond à la taille du pixel texturé + et utilise le critère [page:constant NearestFilter] (le texel le plus proche du + centre du pixel) pour produire une valeur de texture.

    + + [page:constant NearestMipmapLinearFilter] choisit les deux mipmaps les plus proches + qui correspondent à la taille du pixel texturé et utilise le critère [page:constant NearestFilter] pour produire + une valeur de texture pour chaque mipmap. La valeur de texture finale est une moyenne pondérée de ces deux valeurs.

    + + [page:constant LinearMipmapNearestFilter] choisit le mipmap qui correspond le mieux + la taille du pixel texturé et utilise le critère [page:constant LinearFilter] + (une moyenne pondérée des quatre texels les plus proches du centre du pixel) + pour produire une valeur de texture.

    + + [page:constant LinearMipmapLinearFilter] est la valeur par défaut et choisit les deux mipmaps + qui correspondent le mieux à la taille du pixel texturé et utilise le critère [page:constant LinearFilter] + pour produire une valeur de texture à partir de chaque mipmap. La valeur de texture finale est une moyenne pondérée de ces deux valeurs.

    + + Voir l'exemple [example:webgl_materials_texture_filters materials / texture / filters]. +

    + +

    Types

    + + THREE.UnsignedByteType + THREE.ByteType + THREE.ShortType + THREE.UnsignedShortType + THREE.IntType + THREE.UnsignedIntType + THREE.FloatType + THREE.HalfFloatType + THREE.UnsignedShort4444Type + THREE.UnsignedShort5551Type + THREE.UnsignedInt248Type + +

    + À utiliser avec la propriété [page:Texture.type type] d'une texture, qui doit correspondre au format correct. Voir ci-dessous pour plus de détails.

    + + [page:constant UnsignedByteType] est la valeur par défaut. +

    + +

    Formats

    + + THREE.AlphaFormat + THREE.RedFormat + THREE.RedIntegerFormat + THREE.RGFormat + THREE.RGIntegerFormat + THREE.RGBAFormat + THREE.RGBAIntegerFormat + THREE.LuminanceFormat + THREE.LuminanceAlphaFormat + THREE.DepthFormat + THREE.DepthStencilFormat + +

    + À utiliser avec la propriété [page:Texture.format format] d'une texture, ceux-ci définissent + comment les éléments d'une texture 2d, ou `texels`, sont lus par les shaders.

    + + [page:constant AlphaFormat] supprime les composants rouge, vert et bleu et lit uniquement le composant alpha.

    + + [page:constant RedFormat] supprime les composants vert et bleu et lit uniquement le composant rouge.

    + + [page:constant RedIntegerFormat] supprime les composants vert et bleu et lit uniquement le composant rouge. + Les texels sont lus comme des entiers au lieu de points flottants. + (ne peut être utilisé qu'avec un contexte de rendu WebGL 2). +

    + + [page:constant RGFormat] supprime les composants alpha et bleu et lit les composants rouge et vert. + (ne peut être utilisé qu'avec un contexte de rendu WebGL 2). +

    + + [page:constant RGIntegerFormat] supprime les composants alpha et bleu et lit les composants rouge et vert. + Les texels sont lus comme des entiers au lieu de points flottants. + (ne peut être utilisé qu'avec un contexte de rendu WebGL 2). +

    + + [page:constant RGBAFormat] est la valeur par défaut et lit les composants rouge, vert, bleu et alpha.

    + + [page:constant RGBAIntegerFormat] est la valeur par défaut et lit les composants rouge, vert, bleu et alpha. + Les texels sont lus comme des entiers au lieu de points flottants. + (ne peut être utilisé qu'avec un contexte de rendu WebGL 2). +

    + + [page:constant LuminanceFormat] lit chaque élément comme une seule composante de luminance. + Celui-ci est ensuite converti en point flottant, fixé dans l'intervalle [0,1], puis assemblé + dans un élément RGBA en plaçant la valeur de luminance dans les canaux rouge, vert et bleu, + et en assignant 1.0 au canal alpha.

    + + [page:constant LuminanceAlphaFormat] lit chaque élément comme une composante de luminance/double alpha. + Il s'agit du même procédé que pour [page:constant LuminanceFormat], sauf que le canal alpha peut avoir une autre valeur que `1.0`.

    + + [page:constant DepthFormat] lit chaque élément comme une seule valeur de profondeur, les converti en point flottant, fixé dans l'intervalle [0,1]. + C'est la valeur par défaut pour [page:DepthTexture DepthTexture].

    + + [page:constant DepthStencilFormat] lit chaque élément comme une paire de valeurs de profondeur et de gabarit. + Le composant de profondeur de la paire est interprété comme dans [page:constant DepthFormat]. + Le composant de gabarit est interprété en fonction du format interne profondeur + gabarit. +

    + + Notez que la texture doit avoir le bon [page:Texture.type type] défini, comme décrit ci-dessus. + Voir [link:https://developer.mozilla.org/en/docs/Web/API/WebGLRenderingContext/texImage2D WebGLRenderingContext.texImage2D] pour plus de détails. +

    + +

    Formats de Textures Compressées DDS et ST3C

    + + THREE.RGB_S3TC_DXT1_Format + THREE.RGBA_S3TC_DXT1_Format + THREE.RGBA_S3TC_DXT3_Format + THREE.RGBA_S3TC_DXT5_Format + +

    + À utiliser avec la propriété [page:Texture.format format] d'une [page:CompressedTexture CompressedTexture], + ceux-ci doivent supporter l'extension + [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/ WEBGL_compressed_texture_s3tc]

    + + Il existe 4 formats [link:https://en.wikipedia.org/wiki/S3_Texture_Compression S3TC] disponibles avec cette extension. Ce sont :
    + [page:constant RGB_S3TC_DXT1_Format] : une image compressée DXT1 dans un format d'image RVB.
    + [page:constant RGBA_S3TC_DXT1_Format] : une image compressée DXT1 dans un format d'image RVB avec une simple valeur alpha activée/désactivée.
    + [page:constant RGBA_S3TC_DXT3_Format] : une image compressée DXT3 dans un format d'image RGBA. Comparé à une texture RGBA 32 bits, il offre une compression 4:1.
    + [page:constant RGBA_S3TC_DXT5_Format] : une image compressée DXT5 dans un format d'image RGBA. Il fournit également une compression 4:1, mais diffère de la compression DXT3 dans la façon dont la compression alpha est effectuée.
    +

    + +

    Formats de Textures Compressées PVRTC

    + + THREE.RGB_PVRTC_4BPPV1_Format + THREE.RGB_PVRTC_2BPPV1_Format + THREE.RGBA_PVRTC_4BPPV1_Format + THREE.RGBA_PVRTC_2BPPV1_Format + +

    + À utiliser avec la propriété [page:Texture.format format] d'une [page:CompressedTexture CompressedTexture], + ceux-ci doivent supporter l'extension [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/ WEBGL_compressed_texture_pvrtc].
    + Le PVRTC n'est généralement disponible que sur les appareils mobiles équipés de chipsets PowerVR, qui sont principalement des appareils Apple.

    + + Il existe 4 formats [link:https://en.wikipedia.org/wiki/PVRTC PVRTC] disponibles avec cette extension. Ce sont :
    + [page:constant RGB_PVRTC_4BPPV1_Format] : Compression RVB en mode 4 bits. Un bloc pour chaque 4×4 pixels.
    + [page:constant RGB_PVRTC_2BPPV1_Format] : Compression RVB en mode 2 bits. Un bloc pour chaque 8×4 pixels.
    + [page:constant RGBA_PVRTC_4BPPV1_Format] : Compression RGBA en mode 4 bits. Un bloc pour chaque 4×4 pixels.
    + [page:constant RGBA_PVRTC_2BPPV1_Format] : Compression RGBA en mode 2 bits. Un bloc pour chaque 8×4 pixels.
    +

    + +

    Formats de Textures Compressées PVRTC

    + + THREE.RGB_ETC1_Format + THREE.RGB_ETC2_Format + THREE.RGBA_ETC2_EAC_Format + +

    + À utiliser avec la propriété [page:Texture.format format] d'une [page:CompressedTexture CompressedTexture], + ceux-ci doivent supporter les extensions [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc1/ WEBGL_compressed_texture_etc1] + (ETC1) ou [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc/ WEBGL_compressed_texture_etc] + (ETC2).

    +

    + +

    Formats de Textures Compressées ASTC

    + + THREE.RGBA_ASTC_4x4_Format + THREE.RGBA_ASTC_5x4_Format + THREE.RGBA_ASTC_5x5_Format + THREE.RGBA_ASTC_6x5_Format + THREE.RGBA_ASTC_6x6_Format + THREE.RGBA_ASTC_8x5_Format + THREE.RGBA_ASTC_8x6_Format + THREE.RGBA_ASTC_8x8_Format + THREE.RGBA_ASTC_10x5_Format + THREE.RGBA_ASTC_10x6_Format + THREE.RGBA_ASTC_10x8_Format + THREE.RGBA_ASTC_10x10_Format + THREE.RGBA_ASTC_12x10_Format + THREE.RGBA_ASTC_12x12_Format + +

    + À utiliser avec la propriété [page:Texture.format format] d'une [page:CompressedTexture CompressedTexture], + ceux-ci doivent supporter les extensions [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_astc/ WEBGL_compressed_texture_astc].

    +

    + +

    Formats de Textures Compressées BPTC

    + + THREE.RGBA_BPTC_Format + +

    + À utiliser avec la propriété [page:Texture.format format] d'une [page:CompressedTexture CompressedTexture], + ceux-ci doivent supporter les extensions [link:https://www.khronos.org/registry/webgl/extensions/EXT_texture_compression_bptc/ EXT_texture_compression_bptc].

    +

    + +

    Formats Internes

    + + 'ALPHA' + 'RGB' + 'RGBA' + 'LUMINANCE' + 'LUMINANCE_ALPHA' + 'RED_INTEGER' + 'R8' + 'R8_SNORM' + 'R8I' + 'R8UI' + 'R16I' + 'R16UI' + 'R16F' + 'R32I' + 'R32UI' + 'R32F' + 'RG8' + 'RG8_SNORM' + 'RG8I' + 'RG8UI' + 'RG16I' + 'RG16UI' + 'RG16F' + 'RG32I' + 'RG32UI' + 'RG32F' + 'RGB565' + 'RGB8' + 'RGB8_SNORM' + 'RGB8I' + 'RGB8UI' + 'RGB16I' + 'RGB16UI' + 'RGB16F' + 'RGB32I' + 'RGB32UI' + 'RGB32F' + 'RGB9_E5' + 'SRGB8' + 'R11F_G11F_B10F' + 'RGBA4' + 'RGBA8' + 'RGBA8_SNORM' + 'RGBA8I' + 'RGBA8UI' + 'RGBA16I' + 'RGBA16UI' + 'RGBA16F' + 'RGBA32I' + 'RGBA32UI' + 'RGBA32F' + 'RGB5_A1' + 'RGB10_A2' + 'RGB10_A2UI' + 'SRGB8_ALPHA8' + 'DEPTH_COMPONENT16' + 'DEPTH_COMPONENT24' + 'DEPTH_COMPONENT32F' + 'DEPTH24_STENCIL8' + 'DEPTH32F_STENCIL8' + + +

    + + Attention : changer le format interne d'une texture n'affectera que le + texture lors de l'utilisation d'un contexte de rendu WebGL 2.

    + + À utiliser avec la propriété de texture [page:Texture.internalFormat internalFormat], + ceux-ci définissent comment les éléments d'une texture, ou "texels", sont stockés sur le GPU.

    + + [page:constante R8] stocke la composante rouge sur 8 bits.

    + + [page:constant R8_SNORM] stocke la composante rouge sur 8 bits. Le composant est stocké comme normalisé.

    + + [page:constant R8I] stocke la composante rouge sur 8 bits. Le composant est stocké sous la forme d'un entier.

    + + [page:constant R8UI] stocke la composante rouge sur 8 bits. Le composant est stocké sous la forme d'un entier non signé.

    + + [page:constant R16I] stocke la composante rouge sur 16 bits. Le composant est stocké sous la forme d'un entier.

    + + [page:constant R16UI] stocke la composante rouge sur 16 bits. Le composant est stocké sous la forme d'un entier non signé.

    + + [page:constant R16F] stocke la composante rouge sur 16 bits. Le composant est stocké en point flottant.

    + + [page:constant R32I] stocke la composante rouge sur 32 bits. Le composant est stocké sous la forme d'un entier.

    + + [page:constant R32UI] stocke la composante rouge sur 32 bits. Le composant est stocké sous la forme d'un entier non signé.

    + + [page:constant R32F] stocke la composante rouge sur 32 bits. Le composant est stocké en point flottant.

    + + [page:constante RG8] stocke les composantes rouge et verte sur 8 bits chacune.

    + + [page:constant RG8_SNORM] stocke les composantes rouge et verte sur 8 bits chacune. + Chaque composant est stocké comme normalisé. +

    + + [page:constant RG8I] stocke les composantes rouge et verte sur 8 bits chacune. + Chaque composant est stocké sous la forme d'un entier. +

    + + [page:constant RG8UI] stocke les composantes rouge et verte sur 8 bits chacune. + Chaque composant est stocké sous la forme d'un entier non signé. +

    + + [page:constant RG16I] stocke les composantes rouge et verte sur 16 bits chacune. + Chaque composant est stocké sous la forme d'un entier. +

    + + [page:constant RG16UI] stocke les composantes rouge et verte sur 16 bits chacune. + Chaque composant est stocké sous la forme d'un entier non signé. +

    + + [page:constant RG16F] stocke les composantes rouge et verte sur 16 bits chacune. + Chaque composant est stocké en point flottant. +

    + + [page:constant RG32I] stocke les composantes rouge et verte sur 32 bits chacune. + Chaque composant est stocké sous la forme d'un entier. +

    + + [page:constant RG32UI] stocke les composantes rouge et verte sur 32 bits. + Chaque composant est stocké sous la forme d'un entier non signé. +

    + + [page:constante RG32F] stocke les composantes rouge et verte sur 32 bits. + Chaque composant est stocké en point flottant. +

    + + [page:constant RGB8] stocke les composants rouge, vert et bleu sur 8 bits chacun. + + [page:constant RGB8_SNORM] stocke les composants rouge, vert et bleu sur 8 bits chacun. + Chaque composant est stocké comme normalisé. +

    + + [page:constant RGB8I] stocke les composants rouge, vert et bleu sur 8 bits chacun. + Chaque composant est stocké sous la forme d'un entier. +

    + + [page:constant RGB8UI] stocke les composants rouge, vert et bleu sur 8 bits chacun. + Chaque composant est stocké sous la forme d'un entier non signé. +

    + + [page:constant RGB16I] stocke les composants rouge, vert et bleu sur 16 bits chacun. + Chaque composant est stocké sous la forme d'un entier. +

    + + [page:constant RGB16UI] stocke les composants rouge, vert et bleu sur 16 bits chacun. + Chaque composant est stocké sous la forme d'un entier non signé. +

    + + [page:constant RGB16F] stocke les composants rouge, vert et bleu sur 16 bits chacun. + Chaque composant est stocké en point flottant +

    + + [page:constant RGB32I] stocke les composants rouge, vert et bleu sur 32 bits chacun. + Chaque composant est stocké sous la forme d'un entier. +

    + + [page:constant RGB32UI] stocke les composants rouge, vert et bleu sur 32 bits chacun. + Chaque composant est stocké sous la forme d'un entier non signé. +

    + + [page:constant RGB32F] stocke les composants rouge, vert et bleu sur 32 bits chacun. + Chaque composant est stocké en point flottant +

    + + [page:constante R11F_G11F_B10F] stocke les composantes rouge, verte et bleue respectivement sur 11 bits, 11 bits et 10 bits. + Chaque composant est stocké en point flottant. +

    + + [page:constant RGB565] stocke les composantes rouge, verte et bleue respectivement sur 5 bits, 6 bits et 5 bits.

    + + [page:constant RGB9_E5] stocke les composantes rouge, verte et bleue sur 9 bits chacune.

    + + [page:constant RGBA8] stocke les composants rouge, vert, bleu et alpha sur 8 bits chacun.

    + + [page:constant RGBA8_SNORM] stocke les composantes rouge, verte, bleue et alpha sur 8 bits. + Chaque composant est stocké comme normalisé. +

    + + [page:constant RGBA8I] stocke les composants rouge, vert, bleu et alpha sur 8 bits chacun. + Chaque composant est stocké sous la forme d'un entier. +

    + + [page:constant RGBA8UI] stocke les composants rouge, vert, bleu et alpha sur 8 bits. + Chaque composant est stocké sous la forme d'un entier non signé. +

    + + [page:constant RGBA16I] stocke les composantes rouge, verte, bleue et alpha sur 16 bits. + Chaque composant est stocké sous la forme d'un entier. +

    + + [page:constant RGBA16UI] stocke les composants rouge, vert, bleu et alpha sur 16 bits. + Chaque composant est stocké sous la forme d'un entier non signé. +

    + + [page:constant RGBA16F] stocke les composantes rouge, verte, bleue et alpha sur 16 bits. + Chaque composant est stocké en point flottant. +

    + + [page:constant RGBA32I] stocke les composantes rouge, verte, bleue et alpha sur 32 bits. + Chaque composant est stocké sous la forme d'un entier. +

    + + [page:constant RGBA32UI] stocke les composants rouge, vert, bleu et alpha sur 32 bits. + Chaque composant est stocké sous la forme d'un entier non signé. +

    + + [page:constant RGBA32F] stocke les composantes rouge, verte, bleue et alpha sur 32 bits. + Chaque composant est stocké en point flottant. +

    + + [page:constant RGB5_A1] stocke les composantes rouge, verte, bleue et alpha respectivement sur 5 bits, 5 bits, 5 bits et 1 bit.

    + + [page:constant RGB10_A2] stocke les composantes rouge, verte, bleue et alpha respectivement sur 10 bits, 10 bits, 10 bits et 2 bits.

    + + [page:constant RGB10_A2UI] stocke les composantes rouge, verte, bleue et alpha respectivement sur 10 bits, 10 bits, 10 bits et 2 bits. + Chaque composant est stocké sous la forme d'un entier non signé. +

    + + [page:constant SRGB8] stocke les composants rouge, vert et bleu sur 8 bits chacun.

    + + [page:constant SRGB8_ALPHA8] stocke les composants rouge, vert, bleu et alpha sur 8 bits chacun.

    + + [page : constante DEPTH_COMPONENT16] stocke la composante de profondeur sur 16 bits.

    + + [page : constante DEPTH_COMPONENT24] stocke la composante de profondeur sur 24 bits.

    + + [page:constant DEPTH_COMPONENT32F] stocke la composante de profondeur sur 32 bits. Le composant est stocké en point flottant.

    + + [page:constant DEPTH24_STENCIL8] stocke les composants profondeur et stencil respectivement sur 24 bits et 8 bits. + Le composant de gabarit est stocké sous la forme d'un entier non signé. +

    + + [page:constant DEPTH32F_STENCIL8] stocke les composants profondeur et stencil respectivement sur 32 bits et 8 bits. + Le composant de profondeur est stocké sous forme de point flottant et le composant de gabarit sous forme d'entier non signé. +

    + + Notez que la texture doit avoir le bon [page:Texture.type type] défini, + ainsi que le bon format [page:Texture.format]. + + Voir [link:https://developer.mozilla.org/en/docs/Web/API/WebGLRenderingContext/texImage2D WebGLRenderingContext.texImage2D], et + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/texImage3D WebGL2RenderingContext.texImage3D], + pour plus de détails sur une combinaison possible de [page:Texture.format format], [page:Texture.internalFormat internalFormat], + et [page:Texture.type type].

    + + Pour plus d'informations sur les formats internes, vous pouvez également vous référer directement à la + [link:https://www.khronos.org/registry/webgl/specs/latest/2.0/ WebGL2 Specification] et + à la [link:https://www.khronos.org/registry/OpenGL/specs/es/3.0/es_spec_3.0.pdf OpenGL ES 3.0 Specification]. +

    + +

    Encodage

    + + THREE.LinearEncoding + THREE.sRGBEncoding + THREE.BasicDepthPacking + THREE.RGBADepthPacking + +

    + À utiliser avec une propriété de texture [page:Texture.encoding encoding].

    + + Si le type d'encodage est modifié après que la texture ait été utilisée par un matériau, + vous devrez définir [page:Material.needsUpdate Material.needsUpdate] sur "true" pour que le matériau soit recompilé.

    + + La valeur par défaut est [page:constant LinearEncoding]. + Les valeurs autres que celle-ci ne sont valides que pour la carte, envMap et emissiveMap d'un matériau. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + diff --git a/docs/api/fr/core/BufferAttribute.html b/docs/api/fr/core/BufferAttribute.html new file mode 100644 index 00000000000000..c2edb4ea915bb3 --- /dev/null +++ b/docs/api/fr/core/BufferAttribute.html @@ -0,0 +1,210 @@ + + + + + + + + + +

    [name]

    + +

    + Cette classe stocke les données d'un attribut (telles que les positions des sommets, les indices de face, les normales, + couleurs, UV et tout attribut personnalisé) associé à une [page:BufferGeometry], qui permet + une transmission plus efficace des données au GPU. Voir cette page pour plus de détails et un exemple d'utilisation. + Lorsque vous travaillez avec des données de type vecteur, les méthodes d'assistance .fromBufferAttribute( attribute, index ) + des classes [page:Vector2.fromBufferAttribute Vector2], + [page:Vector3.fromBufferAttribute Vector3], + [page:Vector4.fromBufferAttribute Vector4], et + [page:Color.fromBufferAttribute Color] peuvent être utiles. +

    + +

    Constructeur

    +

    [name]( [param:TypedArray array], [param:Integer itemSize], [param:Boolean normalized] )

    +

    + [page:TypedArray array] -- Doit être un [link:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/TypedArray TypedArray]. + Utilisé pour instancier un tampon (buffer).
    + Ce tableau devrait avoir + itemSize * numVertices + éléments, où numVertices est le nombre de sommets dans le [page:BufferGeometry BufferGeometry].

    + [page:Integer itemSize] -- Le nombre de valeurs du tableau qui doivent être associées à + un sommet particulier. Par exemple, si l'attribut stocke un vecteur à 3 composants (tel qu'une position, une normale ou une couleur), alors itemSize doit être 3. +

    + + [page:Boolean normalized] -- (optionnel) S'applique uniquement aux données entières. Indique comment les données sous-jacentes + dans le tampon correspond aux valeurs du code GLSL. Par exemple, si [page:TypedArray array] est une instance de + UInt16Array, et [page:Boolean normalized] est `true`, les valeurs `0 - +65535` dans le tableau + de données seront mappées à 0.0f - +1.0f dans l'attribut GLSL. Un Int16Array (signé) mapperait + de -32768 - +32767 à -1.0f - +1.0f. Si [page:Boolean normalized] est faux, les valeurs + sera converti en flottants non modifiés, c'est-à-dire que 32767 devient 32767.0f. +

    + +

    Propriétés

    + +

    [property:TypedArray array]

    +

    + Le tableau [page:TypedArray array] contenant les données stockées dans le tampon. +

    + +

    [property:Integer count]

    +

    + Stocke la longueur du tableau [page:BufferAttribute.array array] divisée par [page:BufferAttribute.itemSize itemSize].

    + + Si le tampon stocke un vecteur à 3 composants (tel qu'une position, une normale ou une couleur), + cela comptera alors le nombre de ces vecteurs stockés. +

    + +

    [property:Boolean isBufferAttribute]

    +

    + Booléen en lecture seule pour vérifier si un objet donné est de type[name]. +

    + +

    [property:Integer itemSize]

    +

    La longueur des vecteurs qui sont stockés dans le [page:BufferAttribute.array array].

    + +

    [property:String name]

    +

    + Nom optionnel pour cette instance d'attribut. La valeur par défaut est une chaîne vide. +

    + +

    [property:Boolean needsUpdate]

    +

    + Booléen indiquant que cet attribut a changé et doit être renvoyé au GPU. + Définissez-le sur true lorsque vous modifiez la valeur du tableau.

    + + Le définir sur 'true' revient à incrémenter la [page:BufferAttribute.version version]. +

    + +

    [property:Boolean normalized]

    +

    + Indique comment les données sous-jacentes dans la mémoire tampon sont mappées aux valeurs du code de nuanceur GLSL. + Voir le constructeur ci-dessus pour plus de détails. +

    + +

    [property:Function onUploadCallback]

    +

    + Une fonction de rappel qui est exécutée après que le Renderer a transféré les données du tableau d'attributs au GPU. +

    + +

    [property:Object updateRange]

    +

    Object contenant:
    + [page:Integer offset]: La valeur par défaut est `0`. Position à laquelle commencer la mise à jour.
    + [page:Integer count]: La valeur par défaut est `-1`, ce qui signifie ne pas utiliser les plages de mise à jour.

    + + Cela peut être utilisé pour mettre à jour uniquement certains composants de vecteurs stockés (par exemple, seul le composant + lié à la couleur). +

    + +

    [property:Usage usage]

    +

    + Définit le modèle d'utilisation prévu du magasin de données à des fins d'optimisation. Correspond au paramètre `usage` de + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData WebGLRenderingContext.bufferData](). + La valeur par défaut est [page:BufferAttributeUsage StaticDrawUsage]. Voir les [page:BufferAttributeUsage constants] d'utilisation pour toutes les valeurs possibles.

    + + Remarque : Après la première utilisation d'un tampon, son utilisation ne peut pas être modifiée. Au lieu de cela, instanciez-en un nouveau et définissez l'utilisation souhaitée avant le prochain rendu. +

    + +

    [property:Integer version]

    +

    Un numéro de version incrémenté à chaque fois que la propriété [page:BufferAttribute.needsUpdate needsUpdate] est définie sur `true`.

    + +

    Méthodes

    + +

    [method:this applyMatrix3]( [param:Matrix3 m] )

    +

    Applique la matrice [page:Matrix3 m] à chaque élément Vector3 de ce BufferAttribute.

    + +

    [method:this applyMatrix4]( [param:Matrix4 m] )

    +

    Applique la matrice [page:Matrix4 m] à chaque élément Vector3 de ce BufferAttribute.

    + +

    [method:this applyNormalMatrix]( [param:Matrix3 m] )

    +

    Applique la matrice de normales [page:Matrix3 m] à chaque élément Vector3 de ce BufferAttribute.

    + +

    [method:this transformDirection]( [param:Matrix4 m] )

    +

    Applique la matrice [page:Matrix4 m] à chaque élément Vector3 de ce BufferAttribute, en interprétant les éléments comme des vecteurs directionnels.

    + +

    [method:BufferAttribute clone]()

    +

    Renvoie une copie de ce bufferAttribute.

    + +

    [method:this copy]( [param:BufferAttribute bufferAttribute] )

    +

    Copie un autre BufferAttribute à ce BufferAttribute.

    + +

    [method:this copyArray]( array )

    +

    Copie le tableau donné ici (qui peut être un tableau classique ou un TypedArray) vers un + [page:BufferAttribute.array array].

    + + Consulter [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set TypedArray.set] + pour lire les exigences en cas de copie d'un TypedArray. +

    + +

    [method:this copyAt] ( [param:Integer index1], [param:BufferAttribute bufferAttribute], [param:Integer index2] )

    +

    Copie un vecteur de bufferAttribute[index2] à [page:BufferAttribute.array array][index1].

    + +

    [method:Number getX]( [param:Integer index] )

    +

    Renvoie le composant x d'un vecteur à l'index donné.

    + +

    [method:Number getY]( [param:Integer index] )

    +

    Renvoie le composant y d'un vecteur à l'index donné.

    + +

    [method:Number getZ]( [param:Integer index] )

    +

    Renvoie le composant z d'un vecteur à l'index donné.

    + +

    [method:Number getW]( [param:Integer index] )

    +

    Renvoie le composant w d'un vecteur à l'index donné.

    + +

    [method:this onUpload]( [param:Function callback] )

    +

    + Définit la valeur d'une propriété onUploadCallback.

    + + Dans l'exemple [example:webgl_buffergeometry WebGL / Buffergeometry] ceci est utilisé pour libérer de la mémoire + après le transfert du tampon vers le GPU. +

    + +

    [method:this set] ( [param:Array value], [param:Integer offset] )

    +

    + value -- un [page:Array] ou [page:TypedArray] depuis lequel copier les valeurs
    + offset -- (optionnel) index du [page:BufferAttribute.array array] depuis lequel commencer la copie.

    + + Appelle [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set TypedArray.set]( [page:Array value], [page:Integer offset] ) + sur le [page:BufferAttribute.array array].

    + + En particulier, consultez cette page pour les exigences relatives à la valeur [page:Array value] + en tant que [page:TypedArray]. +

    + +

    [method:this setUsage] ( [param:Usage value] )

    +

    + Définit [page:BufferAttribute.usage usage] sur la valeur. Voir les [page:BufferAttributeUsage constants] pour toutes les valeurs d'entrée possibles.

    + + Remarque : Après la première utilisation d'un tampon, son utilisation ne peut pas être modifiée. Au lieu de cela, instanciez-en un nouveau et définissez l'utilisation souhaitée avant le prochain rendu. +

    + +

    [method:this setX]( [param:Integer index], [param:Float x] )

    +

    Définit la composante x du vecteur à l'indice donné.

    + +

    [method:this setY]( [param:Integer index], [param:Float y] )

    +

    Définit la composante y du vecteur à l'indice donné.

    + +

    [method:this setZ]( [param:Integer index], [param:Float z] )

    +

    Définit la composante z du vecteur à l'indice donné.

    + +

    [method:this setW]( [param:Integer index], [param:Float w] )

    +

    Définit la composante w du vecteur à l'indice donné.

    + +

    [method:this setXY]( [param:Integer index], [param:Float x], [param:Float y] )

    +

    Définit les composantes x et y du vecteur à l'indice donné.

    + +

    [method:this setXYZ]( [param:Integer index], [param:Float x], [param:Float y], [param:Float z] )

    +

    Définit les composantes x, y et z du vecteur à l'indice donné.

    + +

    [method:this setXYZW]( [param:Integer index], [param:Float x], [param:Float y], [param:Float z], [param:Float w] )

    +

    Définit les composantes x, y, z et w du vecteur à l'indice donné.

    + + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/core/BufferGeometry.html b/docs/api/fr/core/BufferGeometry.html new file mode 100644 index 00000000000000..a4d014b0ca2f1f --- /dev/null +++ b/docs/api/fr/core/BufferGeometry.html @@ -0,0 +1,309 @@ + + + + + + + + + +

    [name]

    + +

    + Représentation d'une géométrie de maillage, de ligne ou de point. Comprend les positions des sommets, les indices de faces, + normales, couleurs, UV et attributs personnalisés dans les tampons, réduisant ainsi le coût de + transmettre toutes ces données au GPU. +

    +

    + Pour lire et modifier des données dans les attributs BufferGeometry, consultez la documentation [page:BufferAttribute]. +

    + +

    Exemple de code :

    + + const geometry = new THREE.BufferGeometry(); + // créer une forme carrée simple. Nous dupliquons le haut à gauche et le bas à droite + // sommets car chaque sommet doit apparaître une fois par triangle. + const vertices = new Float32Array( [ + -1.0, -1.0, 1.0, + 1.0, -1.0, 1.0, + 1.0, 1.0, 1.0, + + 1.0, 1.0, 1.0, + -1.0, 1.0, 1.0, + -1.0, -1.0, 1.0 + ] ); + + // itemSize = 3 parce qu'il y a 3 valeurs (comoosants) par sommet + geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); + const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); + const mesh = new THREE.Mesh( geometry, material ); + + +

    Exemples

    +

    + [example:webgl_buffergeometry Mesh with non-indexed faces]
    + [example:webgl_buffergeometry_indexed Mesh with indexed faces]
    + [example:webgl_buffergeometry_lines Lines]
    + [example:webgl_buffergeometry_lines_indexed Indexed Lines]
    + [example:webgl_buffergeometry_custom_attributes_particles Particles]
    + [example:webgl_buffergeometry_rawshader Raw Shaders] +

    + +

    Constructeur

    + + +

    [name]()

    +
    + Cela crée un nouveau [name]. Il définit également plusieurs propriétés sur une valeur par défaut. +
    + + +

    Propriétés

    + +

    [property:Object attributes]

    +

    + Ce hashmap a comme identifiant le nom de l'attribut à définir et comme valeur le [page:BufferAttribute buffer] à lui attribuer. + Plutôt que d'accéder directement à cette propriété, utilisez [page:.setAttribute] et [page:.getAttribute] pour accéder aux attributs de cette géométrie. +

    + +

    [property:Box3 boundingBox]

    +

    + Boîte englobante pour le bufferGeometry, qui peut être calculée avec + [page:.computeBoundingBox](). La valeur par défaut est `null`. +

    + +

    [property:Sphere boundingSphere]

    +

    + Sphère englobante pour le bufferGeometry, qui peut être calculée avec + [page:.computeBoundingSphere](). La valeur par défaut est `null`. +

    + +

    [property:Object drawRange]

    +

    + Détermine la partie de la géométrie à rendre. Cela ne devrait pas + être défini directement, utilisez à la place[page:.setDrawRange]. La valeur par défaut est + + { start: 0, count: Infinity } + + Pour BufferGeometry non indexé, count est le nombre de sommets à rendre. + Pour BufferGeometry indexé, count est le nombre d'indices à rendre. +

    + +

    [property:Array groups]

    +

    + Divise la géométrie en groupes, dont chacun sera rendu dans un appel de dessin WebGL distinct. + Cela permet d'utiliser un éventail de matériaux avec la géométrie.

    + + Chaque groupe est un objet de la forme : + { start: Integer, count: Integer, materialIndex: Integer } + où start spécifie le premier élément de cet appel de dessin - le premier sommet de la géométrie non indexée, + sinon le premier indice triangulaire. Count spécifie combien de sommets (ou indices) sont inclus, et + materialIndex spécifie l'index de tableau de matériaux à utiliser.

    + + Utilisez [page:.addGroup] pour ajouter des groupes au lieu de modifier le tableau directement.

    + + Chaque sommet et index doit appartenir à exactement un groupe — les groupes ne doivent pas partager de sommets ou d'indices, et ne doivent pas laisser de sommets ou d'indices inutilisés. +

    + + + + + +

    [property:Integer id]

    +

    Numéro unique pour cette instance de bufferGeometry.

    + +

    [property:BufferAttribute index]

    +

    + Permet de réutiliser les sommets sur plusieurs triangles ; c'est ce qu'on appelle utiliser des "triangles indexés". + Chaque triangle est associé aux indices de trois sommets. Cet attribut stocke donc l'indice de chaque sommet pour chaque face triangulaire. + + Si cet attribut n'est pas défini, le [page: WebGLRenderer renderer] suppose que chacun des trois éléments contigus + les positions représentent un seul triangle. + + La valeur par défaut est `null`. +

    + +

    [property:Boolean isBufferGeometry]

    +

    + Booléen en lecture seule pour vérifier si un objet donné est de type [name]. +

    + +

    [property:Object morphAttributes]

    +

    + Hashmap de [page:BufferAttribute] contenant les détails des cibles de morphing de la géométrie.
    + Remarque : Une fois la géométrie rendue, les données d'attribut de morphing ne peuvent pas être modifiées. Vous devrez appeler [page:.dispose]() et créer une nouvelle instance de [nom]. +

    + +

    [property:Boolean morphTargetsRelative]

    +

    + Utilisé pour contrôler le comportement de la cible de morphing ; lorsqu'il est défini sur true, les données cibles de morphing sont traitées comme des décalages relatifs, plutôt que comme des positions/normales absolues. + + La valeur par défaut est "faux". +

    + +

    [property:String name]

    +

    + Nom facultatif pour cette instance de bufferGeometry. La valeur par défaut est une chaîne vide. +

    + +

    [property:Object userData]

    +

    + Un objet qui peut être utilisé pour stocker des données personnalisées sur le BufferGeometry. Il ne doit pas contenir + de références aux fonctions car celles-ci ne seront pas clonées. +

    + +

    [property:String uuid]

    +

    + [link:http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] de l'instance de l'objet. + Celui-ci est automatiquement attribué et ne doit pas être modifié. +

    + +

    Méthodes

    + +

    Les méthodes [page:EventDispatcher EventDispatcher] sont accessibles depuis cette classe.

    + +

    [method:undefined addGroup]( [param:Integer start], [param:Integer count], [param:Integer materialIndex] )

    +

    + Ajoute un groupe à cette géométrie; voir les propriétés des [page:BufferGeometry.groups groups] + pour plus de détails. +

    + +

    [method:this applyMatrix4]( [param:Matrix4 matrix] )

    +

    Applique la transformation matricielle à la géométrie.

    + +

    [method:this applyQuaternion]( [param:Quaternion quaternion] )

    +

    Applique la rotation représentée par le quaternion à la géométrie.

    + +

    [method:this center] ()

    +

    Centre la géométrie en fonction de la boîte englobante.

    + +

    [method:undefined clearGroups]( )

    +

    Efface tous les groupes.

    + +

    [method:BufferGeometry clone]()

    +

    Crée un clone de ce BufferGeometry.

    + +

    [method:undefined computeBoundingBox]()

    +

    + Calcule la boîte englobante de la géométrie, met à jour l'attribut [page:.boundingBox].
    + Les boîtes englobantes ne sont pas calculées par défaut. Ils doivent être calculés explicitement, sinon elles sont `null`. +

    + +

    [method:undefined computeBoundingSphere]()

    +

    + Calcule la boîte englobante de la géométrie, met à jour l'attribut [page:.boundingSphere].
    + Les sphères englobantes ne sont pas calculées par défaut. Ils doivent être calculés explicitement, sinon elles sont `null`. +

    + +

    [method:undefined computeTangents]()

    +

    + Calcule et ajoute un attribut de tangente à cette géométrie.
    + Le calcul n'est pris en charge que pour les géométries indexées et si les attributs position, normal et uv sont définis. Lorsque vous utilisez une carte normale d'espace tangent, favorisez l'algorithme MikkTSpace fourni par + [page:BufferGeometryUtils.computeMikkTSpaceTangents]. +

    + +

    [method:undefined computeVertexNormals]()

    +

    Calcule les normales des sommets en faisant la moyenne des normales des faces.

    + +

    [method:this copy]( [param:BufferGeometry bufferGeometry] )

    +

    Copie un autre BufferGeometry dans ce BufferGeometry.

    + +

    [method:BufferAttribute deleteAttribute]( [param:String name] )

    +

    Efface un [page:BufferAttribute attribute] avec le nom spécifié.

    + +

    [method:undefined dispose]()

    +

    + Libère les ressources liées au GPU allouées par cette instance. Appelez cette méthode chaque fois que cette instance n'est plus utilisée dans votre application. +

    + +

    [method:BufferAttribute getAttribute]( [param:String name] )

    +

    Renvoie un [page:BufferAttribute attribute] avec le nom spécifié.

    + +

    [method:BufferAttribute getIndex] ()

    +

    Retourne le tampon [page:.index].

    + +

    [method:Boolean hasAttribute]( [param:String name] )

    +

    Renvoie `true` si l'attribut avec le nom spécifié existe.

    + +

    [method:this lookAt] ( [param:Vector3 vector] )

    +

    + vector - Un vecteur monde à regarder.

    + + Fait pivoter la géométrie pour faire face à un point dans l'espace. Cela se fait généralement en une seule opération et non pendant une boucle. + Utilisez [page:Object3D.lookAt] pour une utilisation typique du maillage en temps réel. +

    + +

    [method:undefined normalizeNormals]()

    +

    + Chaque vecteur normal dans une géométrie aura une magnitude de 1. + Cela corrigera l'éclairage sur les surfaces géométriques. +

    + +

    [method:this rotateX] ( [param:Float radians] )

    +

    + Fait pivoter la géométrie autour de l'axe X. Cela se fait généralement en une seule opération et non pendant une boucle. + Utilisez [page:Object3D.rotation] pour une utilisation typique du maillage en temps réel. +

    + +

    [method:this rotateY] ( [param:Float radians] )

    +

    + Fait pivoter la géométrie autour de l'axe Y. Cela se fait généralement en une seule opération et non pendant une boucle. + Utilisez [page:Object3D.rotation] pour une utilisation typique du maillage en temps réel. +

    + +

    [method:this rotateZ] ( [param:Float radians] )

    +

    + Fait pivoter la géométrie autour de l'axe Z. Cela se fait généralement en une seule opération et non pendant une boucle. + Utilisez [page:Object3D.rotation] pour une utilisation typique du maillage en temps réel. +

    + +

    [method:this scale] ( [param:Float x], [param:Float y], [param:Float z] )

    +

    + Mettre à l'échelle les données géométriques. Cela se fait généralement en une seule opération et non pendant une boucle. + Utilisez [page:Object3D.scale] pour une utilisation typique du maillage en temps réel. +

    + +

    [method:this setAttribute]( [param:String name], [param:BufferAttribute attribute] )

    +

    + Définit un attribut pour cette géométrie. Utilisez ceci plutôt que la propriété attributs, + parce qu'un hashmap interne de [page:.attributes] est maintenu pour accélérer l'itération sur + les attributs. +

    + +

    [method:undefined setDrawRange] ( [param:Integer start], [param:Integer count] )

    +

    Définissez la propriété [page:.drawRange]. Pour un BufferGeometry non indexé, count est le nombre de sommets à rendre. + Pour un BufferGeometry indexé, count est le nombre d'indices à rendre.

    + +

    [method:this setFromPoints] ( [param:Array points] )

    +

    Définit les attributs de ce BufferGeometry à partir d'un tableau de points.

    + +

    [method:this setIndex] ( [param:BufferAttribute index] )

    +

    Définit le buffer [page:.index].

    + +

    [method:Object toJSON]()

    +

    Convertit la BufferGeometry en three.js [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format].

    + +

    [method:BufferGeometry toNonIndexed]()

    +

    Renvoie une version non indexée d'une BufferGeometry indexée.

    + +

    [method:this translate] ( [param:Float x], [param:Float y], [param:Float z] )

    +

    + Déplace la géométrie. Cela se fait généralement en une seule opération et non pendant une boucle. + Utilisez [page:Object3D.position] pour un déplacement de maillage en temps réel typique. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/BoxGeometry.html b/docs/api/fr/geometries/BoxGeometry.html new file mode 100644 index 00000000000000..27719eff69964a --- /dev/null +++ b/docs/api/fr/geometries/BoxGeometry.html @@ -0,0 +1,74 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    + [name] est une classe de géométrie pour un cuboïde rectangulaire avec une largeur 'width', une hauteur 'height', et une profondeur 'depth' données. + À la création, le cuboïde est centré sur l'origine, chaque arrête est parallèle à l'un des axes. +

    + + + + + +

    Exemple de code :

    + + const geometry = new THREE.BoxGeometry( 1, 1, 1 ); + const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); + const cube = new THREE.Mesh( geometry, material ); + scene.add( cube ); + + +

    Contructeur

    + +

    [name]([param:Float width], [param:Float height], [param:Float depth], [param:Integer widthSegments], [param:Integer heightSegments], [param:Integer depthSegments])

    +

    + width — Largeur; c'est-à-dire la longueur des arêtes parallèles à l'axe X. Optionnel; par défaut à 1.
    + height — Hauteur; c'est-à-dire la longueur des arêtes parallèles à l'axe Y. Optionnel; par défaut à 1.
    + depth — Profondeur; c'est-à-dire la longueur des arêtes parallèles à l'axe Z. Optionnel; par défaut à 1.
    + widthSegments — Nombre de faces rectangulaires segmentées sur la largeur des côtés. Optionnel; par défaut à 1.
    + heightSegments — Nombre de faces rectangulaires segmentées sur la hauteur des côtés. Optionnel; par défaut à 1.
    + depthSegments — Nombre de faces rectangulaires segmentées le long de la profondeur des côtés. Optionnel; par défaut à 1.
    +

    + +

    Propriétés

    +

    Voir la classe de base [page:BufferGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:BufferGeometry] Pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/CapsuleGeometry.html b/docs/api/fr/geometries/CapsuleGeometry.html new file mode 100644 index 00000000000000..da9d9c38b37725 --- /dev/null +++ b/docs/api/fr/geometries/CapsuleGeometry.html @@ -0,0 +1,73 @@ + + + + + + + + + + [page:BufferGeometry] → [page:LatheGeometry] → + +

    [name]

    + +

    + [name] est une classe de géométrie pour une capsule avec des rayons et une hauteur donnés. + Elle est construite à l'aide de demi-shpères. +

    + + + + + +

    Exemple de code :

    + + const geometry = new THREE.CapsuleGeometry( 1, 1, 4, 8 ); + const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); + const capsule = new THREE.Mesh( geometry, material ); + scene.add( capsule ); + + +

    Constructeur

    + +

    [name]([param:Float radius], [param:Float length], [param:Integer capSubdivisions], [param:Integer radialSegments])

    +

    + + radius — Rayon de la capsule. Optionnel; par défaut à 1.
    + length — Longueur de la section médiane. Optionnel; par défaut à 1.
    + capSegments — Nombre de segments de courbe utilisés pour construire les demi-sphères. Optionnel; par défaut à 4.
    + radialSegments — Nombre de faces segmentées autour de la circonférence de la capsule. Optionnel; par défaut à 8.
    +

    + +

    Propriétés

    +

    Voir la classe de base [page:BufferGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:BufferGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/CircleGeometry.html b/docs/api/fr/geometries/CircleGeometry.html new file mode 100644 index 00000000000000..8800fd46c795a7 --- /dev/null +++ b/docs/api/fr/geometries/CircleGeometry.html @@ -0,0 +1,75 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    + [name] est une forme simple de la géométrie euclidienne. + Elle est construite à partir d'un certain nombre de segments triangulaires orientés autour d'un point central et s'étendant jusqu'à un rayon donné. + Elle est construite dans le sens inverse des aiguilles d'une montre à partir d'un angle de départ et d'un angle central donné. + Elle peut également être utilisée pour créer des polygones réguliers, où le nombre de segments détermine le nombre de côtés. +

    + + + + + +

    Exemple de code :

    + + + const geometry = new THREE.CircleGeometry( 5, 32 ); + const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); + const circle = new THREE.Mesh( geometry, material ); + scene.add( circle ); + + +

    Constructeur

    + +

    [name]([param:Float radius], [param:Integer segments], [param:Float thetaStart], [param:Float thetaLength])

    +

    + radius — Rayon du cercle, par défaut = 1.
    + segments — Nombre de segments (triangles), minimum = 3, défaut = 8.
    + thetaStart — Angle de départ pour le premier segment, par défaut = 0 (position trois heures).
    + thetaLength — L'angle central, souvent appelé thêta, du secteur circulaire. La valeur par défaut est 2*Pi, ce qui fait un cercle complet. +

    + +

    Propriétés

    +

    Voir la classe de base [page:BufferGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:BufferGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/ConeGeometry.html b/docs/api/fr/geometries/ConeGeometry.html new file mode 100644 index 00000000000000..0f218a54118d25 --- /dev/null +++ b/docs/api/fr/geometries/ConeGeometry.html @@ -0,0 +1,72 @@ + + + + + + + + + + [page:BufferGeometry] → [page:CylinderGeometry] → + +

    [name]

    + +

    Une classe pour générer des géométries de cône.

    + + + + + +

    Exemple de code :

    + + const geometry = new THREE.ConeGeometry( 5, 20, 32 ); + const material = new THREE.MeshBasicMaterial( {color: 0xffff00} ); + const cone = new THREE.Mesh( geometry, material ); + scene.add( cone ); + + +

    Constructeur

    + +

    [name]([param:Float radius], [param:Float height], [param:Integer radialSegments], [param:Integer heightSegments], [param:Boolean openEnded], [param:Float thetaStart], [param:Float thetaLength])

    +

    + radius — Rayon de la base du cône. La valeur par défaut est 1.
    + height — Hauteur du cône. La valeur par défaut est 1.
    + radialSegments — Nombre de faces segmentées autour de la circonférence du cône. La valeur par défaut est 8.
    + heightSegments — Nombre de rangées de faces sur la hauteur du cône. La valeur par défaut est 1.
    + openEnded — Un booléen indiquant si la base du cône est ouverte ou fermée. La valeur par défaut est false, ce qui signifie fermée.
    + thetaStart — Angle de départ pour le premier segment, par défaut = 0 (position trois heures).
    + thetaLength — L'angle central, souvent appelé thêta, du secteur circulaire. La valeur par défaut est 2*Pi, ce qui donne un cône complet. +

    + +

    Propriétés

    +

    Voir la classe de base [page:CylinderGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:CylinderGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/CylinderGeometry.html b/docs/api/fr/geometries/CylinderGeometry.html new file mode 100644 index 00000000000000..22022acac69345 --- /dev/null +++ b/docs/api/fr/geometries/CylinderGeometry.html @@ -0,0 +1,73 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Une classe pour générer des géométries de cylindre.

    + + + + + +

    Exemple de code :

    + + const geometry = new THREE.CylinderGeometry( 5, 5, 20, 32 ); + const material = new THREE.MeshBasicMaterial( {color: 0xffff00} ); + const cylinder = new THREE.Mesh( geometry, material ); + scene.add( cylinder ); + + +

    Constructeur

    + +

    [name]([param:Float radiusTop], [param:Float radiusBottom], [param:Float height], [param:Integer radialSegments], [param:Integer heightSegments], [param:Boolean openEnded], [param:Float thetaStart], [param:Float thetaLength])

    +

    + radiusTop — Rayon du cylindre supérieur. La valeur par défaut est 1.
    + radiusBottom — Rayon du cylindre inférieur. La valeur par défaut est 1.
    + height — Hauteur du cylindre. La valeur par défaut est 1.
    + radialSegments — Nombre de faces segmentées autour de la circonférence du cylindre. La valeur par défaut est 8.
    + heightSegments — Nombre de rangées de faces sur la hauteur du cylindre. La valeur par défaut est 1.
    + openEnded — Un booléen indiquant si les extrémités du cylindre sont ouvertes ou fermées. La valeur par défaut est false, ce qui signifie fermées.
    + thetaStart — Angle de départ pour le premier segment, par défaut = 0 (position trois heures).
    + thetaLength — L'angle central, souvent appelé thêta, du secteur circulaire. La valeur par défaut est 2*Pi, ce qui donne un cylindre complet. +

    + +

    Propriétés

    +

    Voir la classe de base [page:BufferGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:BufferGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/DodecahedronGeometry.html b/docs/api/fr/geometries/DodecahedronGeometry.html new file mode 100644 index 00000000000000..0f4d261e64d439 --- /dev/null +++ b/docs/api/fr/geometries/DodecahedronGeometry.html @@ -0,0 +1,59 @@ + + + + + + + + + + [page:BufferGeometry] → [page:PolyhedronGeometry] → + +

    [name]

    + +

    Une classe pour générer des géométries de dodécaèdre.

    + + + + + +

    Constructeur

    + +

    [name]([param:Float radius], [param:Integer detail])

    +

    + radius — Rayon du dodécaèdre. La valeur par défaut est 1.
    + detail — La valeur par défaut est 0. Définir une valeur supérieure à 0 ajoute des sommets, la géométrie n'est donc plus un dodécaèdre. +

    + +

    Propriétés

    +

    Voir la classe de base [page:PolyhedronGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:PolyhedronGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/EdgesGeometry.html b/docs/api/fr/geometries/EdgesGeometry.html new file mode 100644 index 00000000000000..12ddc4dffe864b --- /dev/null +++ b/docs/api/fr/geometries/EdgesGeometry.html @@ -0,0 +1,55 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Cela peut être utilisé comme objet d'assistance pour afficher les bords d'un [page:BufferGeometry geometry].

    + +

    Exemple de code :

    + + +const geometry = new THREE.BoxGeometry( 100, 100, 100 ); +const edges = new THREE.EdgesGeometry( geometry ); +const line = new THREE.LineSegments( edges, new THREE.LineBasicMaterial( { color: 0xffffff } ) ); +scene.add( line ); + + +

    Exemples

    +

    + [example:webgl_helpers helpers] +

    + +

    Constructeur

    + +

    [name]( [param:BufferGeometry geometry], [param:Integer thresholdAngle] )

    +

    + geometry — Tout objet géométrique.
    + thresholdAngle — Une arête n'est rendue que si l'angle (en degrés) entre les normales des faces adjacentes dépasse cette valeur. par défaut = 1 degré. +

    + +

    Propriétés

    +

    Voir la classe de base [page:BufferGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:BufferGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/ExtrudeGeometry.html b/docs/api/fr/geometries/ExtrudeGeometry.html new file mode 100644 index 00000000000000..c99c1742bec7f4 --- /dev/null +++ b/docs/api/fr/geometries/ExtrudeGeometry.html @@ -0,0 +1,113 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Crée une géométrie extrudée à partir d'une forme de chemin.

    + + + + + +

    Exemple de code :

    + + + + const length = 12, width = 8; + + const shape = new THREE.Shape(); + shape.moveTo( 0,0 ); + shape.lineTo( 0, width ); + shape.lineTo( length, width ); + shape.lineTo( length, 0 ); + shape.lineTo( 0, 0 ); + + const extrudeSettings = { + steps: 2, + depth: 16, + bevelEnabled: true, + bevelThickness: 1, + bevelSize: 1, + bevelOffset: 0, + bevelSegments: 1 + }; + + const geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings ); + const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); + const mesh = new THREE.Mesh( geometry, material ) ; + scene.add( mesh ); + + + +

    Constructeur

    + + +

    [name]([param:Array shapes], [param:Object options])

    +

    + shapes — Forme ou tableau de formes.
    + options — Objet pouvant contenir les paramètres suivants. + +

      +
    • curveSegments — int. Nombre de points sur les courbes. La valeur par défaut est 12.
    • +
    • steps — int. Nombre de points utilisés pour subdiviser les segments le long de la profondeur de la courbe extrudée. La valeur par défaut est 1.
    • +
    • depth — float. Profondeur pour extruder la forme. La valeur par défaut est 1.
    • +
    • bevelEnabled — bool. Appliquer un biseau à la forme. La valeur par défaut est true.
    • +
    • bevelThickness — float. Profondeur du biseau dans la forme d'origine. La valeur par défaut est 0,2.
    • +
    • bevelSize — float. Distance du contour de la forme à laquelle s'étend le biseau. La valeur par défaut est bevelThickness - 0.1.
    • +
    • bevelOffset — float. Distance du contour de la forme à laquelle commence le biseau. La valeur par défaut est 0.
    • +
    • bevelSegments — int. Nombre de couches de biseau. La valeur par défaut est 3.
    • +
    • extrudePath — THREE.Curve. Chemin de courbe 3D le long duquel la forme doit être extrudée. Biseaux non pris en charge pour l'extrusion de chemin.
    • +
    • UVGenerator — Object. Objet qui fournit des fonctions de générateur d'UV
    • +
    + +

    +

    + Cet objet extrude une forme 2D en une géométrie 3D. +

    + +

    + Lors de la création d'un maillage avec cette géométrie, si vous souhaitez utiliser un matériau distinct pour sa face + et ses côtés extrudés, vous pouvez utiliser un éventail de matériaux. Le premier matériau sera + appliqué sur la face, le deuxième sera appliqué sur les côtés. +

    + +

    Propriétés

    +

    Voir la classe de base [page:BufferGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:BufferGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/IcosahedronGeometry.html b/docs/api/fr/geometries/IcosahedronGeometry.html new file mode 100644 index 00000000000000..0cbdf6b7f0691f --- /dev/null +++ b/docs/api/fr/geometries/IcosahedronGeometry.html @@ -0,0 +1,58 @@ + + + + + + + + + + [page:BufferGeometry] → [page:PolyhedronGeometry] → +

    [name]

    + +

    Une classe pour générer une géométrie d'icosaèdre.

    + + + + + +

    Constructeur

    + +

    [name]([param:Float radius], [param:Integer detail])

    +

    + radius — La valeur par défaut est 1.
    + detail — La valeur par défaut est 0. Le définir sur une valeur supérieure à 0 ajoute plus de sommets, la géométrie n'est donc plus un icosaèdre. Lorsque le détail est supérieur à 1, la géométrie est une sphère. +

    + +

    Propriétés

    +

    Voir la classe de base [page:PolyhedronGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:PolyhedronGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/LatheGeometry.html b/docs/api/fr/geometries/LatheGeometry.html new file mode 100644 index 00000000000000..8f66cddb2d4117 --- /dev/null +++ b/docs/api/fr/geometries/LatheGeometry.html @@ -0,0 +1,77 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Crée des maillages à symétrie axiale comme des vases. Le tour tourne autour de l'axe Y.

    + + + + + +

    Exemple de code :

    + + + const points = []; + for ( let i = 0; i < 10; i ++ ) { + points.push( new THREE.Vector2( Math.sin( i * 0.2 ) * 10 + 5, ( i - 5 ) * 2 ) ); + } + const geometry = new THREE.LatheGeometry( points ); + const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); + const lathe = new THREE.Mesh( geometry, material ); + scene.add( lathe ); + + +

    Constructeur

    + +

    [name]([param:Array points], [param:Integer segments], [param:Float phiStart], [param:Float phiLength])

    +

    + points — Tableau de Vector2s. La coordonnée x de chaque point doit être supérieure à zéro. La valeur par défaut est un tableau avec (0,-0.5), (0.5,0) et (0,0.5) qui crée une forme de losange simple.
    + segments — Le nombre de segments de circonférence à générer. La valeur par défaut est 12.
    + phiStart — L'angle de départ en radians. La valeur par défaut est 0.
    + phiLength — La plage de radian (0 à 2PI) de la section du vase. 2PI est un vase fermé, moins de 2PI en est une portion. La valeur par défaut est 2PI. +

    +

    + Cela crée une [name] basée sur les paramètres. +

    + +

    Propriétés

    +

    Voir la classe de base [page:BufferGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:BufferGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/OctahedronGeometry.html b/docs/api/fr/geometries/OctahedronGeometry.html new file mode 100644 index 00000000000000..e630b5ab3f86f0 --- /dev/null +++ b/docs/api/fr/geometries/OctahedronGeometry.html @@ -0,0 +1,58 @@ + + + + + + + + + + [page:BufferGeometry] → [page:PolyhedronGeometry] → +

    [name]

    + +

    Une classe pour générer une géométrie d'octaèdre.

    + + + + + +

    Constructeur

    + +

    [name]([param:Float radius], [param:Integer detail])

    +

    + radius — Rayon de l'octaèdre. La valeur par défaut est 1.
    + detail — La valeur par défaut est 0. Définir une valeur supérieure à zéro ajoute des sommets, la géométrie n'est donc plus un octaèdre. +

    + +

    Propriétés

    +

    Voir la classe de base [page:PolyhedronGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:PolyhedronGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/PlaneGeometry.html b/docs/api/fr/geometries/PlaneGeometry.html new file mode 100644 index 00000000000000..f4c2c8438ad167 --- /dev/null +++ b/docs/api/fr/geometries/PlaneGeometry.html @@ -0,0 +1,69 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Une classe pour générer des géométries planes.

    + + + + + +

    Exemple de code :

    + + const geometry = new THREE.PlaneGeometry( 1, 1 ); + const material = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} ); + const plane = new THREE.Mesh( geometry, material ); + scene.add( plane ); + + +

    Constructeur

    + +

    [name]([param:Float width], [param:Float height], [param:Integer widthSegments], [param:Integer heightSegments])

    +

    + width — Largeur le long de l'axe X. La valeur par défaut est 1.
    + height — Hauteur le long de l'axe Y. La valeur par défaut est 1.
    + widthSegments — Optional. Default is 1.
    + heightSegments — Optional. Default is 1. +

    + +

    Propriétés

    +

    Voir la classe de base [page:BufferGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:BufferGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/PolyhedronGeometry.html b/docs/api/fr/geometries/PolyhedronGeometry.html new file mode 100644 index 00000000000000..f75d13057bdbc0 --- /dev/null +++ b/docs/api/fr/geometries/PolyhedronGeometry.html @@ -0,0 +1,68 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    + Un polyèdre est un solide en trois dimensions à faces planes. Cette classe prendra un tableau de sommets, + projetez-les sur une sphère, puis divisez-les jusqu'au niveau de détail souhaité. Cette classe est utilisée + par [page:DodecahedronGeometry], [page:IcosahedronGeometry], [page:OctahedronGeometry], + et [page:TetrahedronGeometry] pour générer leurs géométries respectives. +

    + +

    Exemple de code :

    + +const verticesOfCube = [ + -1,-1,-1, 1,-1,-1, 1, 1,-1, -1, 1,-1, + -1,-1, 1, 1,-1, 1, 1, 1, 1, -1, 1, 1, +]; + +const indicesOfFaces = [ + 2,1,0, 0,3,2, + 0,4,7, 7,3,0, + 0,1,5, 5,4,0, + 1,2,6, 6,5,1, + 2,3,7, 7,6,2, + 4,5,6, 6,7,4 +]; + +const geometry = new THREE.PolyhedronGeometry( verticesOfCube, indicesOfFaces, 6, 2 ); + + +

    Constructeur

    + + +

    [name]([param:Array vertices], [param:Array indices], [param:Float radius], [param:Integer detail])

    +

    + vertices — [page:Array] de points de forme [1,1,1, -1,-1,-1, ... ]
    + indices — [page:Array] d'indices qui composent les faces de forme [0,1,2, 2,3,0, ... ]
    + radius — [page:Float] - Rayon de la forme finale
    + detail — [page:Integer] - Combien de niveaux pour subdiviser la géométrie. Plus il y a de détails, plus la forme est lisse. +

    + +

    Propriétés

    +

    Voir la classe de base [page:BufferGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:BufferGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/RingGeometry.html b/docs/api/fr/geometries/RingGeometry.html new file mode 100644 index 00000000000000..cd4b3ae7eb866e --- /dev/null +++ b/docs/api/fr/geometries/RingGeometry.html @@ -0,0 +1,72 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Une classe pour générer une géométrie d'anneau bidimensionnelle.

    + + + + + +

    Exemple de code :

    + + const geometry = new THREE.RingGeometry( 1, 5, 32 ); + const material = new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } ); + const mesh = new THREE.Mesh( geometry, material ); + scene.add( mesh ); + + +

    Constructeur

    + +

    [name]([param:Float innerRadius], [param:Float outerRadius], [param:Integer thetaSegments], [param:Integer phiSegments], [param:Float thetaStart], [param:Float thetaLength])

    +

    + innerRadius — La valeur par défaut est 0.5.
    + outerRadius — La valeur par défaut est 1.
    + thetaSegments — Nombre de segments. Un nombre plus élevé signifie que l'anneau sera plus rond. Le minimum est 3. La valeur par défaut est 8.
    + phiSegments — Le minimum est 1. La valeur par défaut est 1.
    + thetaStart — Angle de départ. La valeur par défaut est 0.
    + thetaLength — Angle central. La valeur par défaut est Math.PI * 2. +

    + + +

    Propriétés

    +

    Voir la classe de base [page:BufferGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:BufferGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/ShapeGeometry.html b/docs/api/fr/geometries/ShapeGeometry.html new file mode 100644 index 00000000000000..fd1f9ac26db041 --- /dev/null +++ b/docs/api/fr/geometries/ShapeGeometry.html @@ -0,0 +1,83 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Crée une géométrie polygonale unilatérale à partir d'une ou plusieurs formes de chemin.

    + + + + + + +

    Exemple de code :

    + + + + const x = 0, y = 0; + + const heartShape = new THREE.Shape(); + + heartShape.moveTo( x + 5, y + 5 ); + heartShape.bezierCurveTo( x + 5, y + 5, x + 4, y, x, y ); + heartShape.bezierCurveTo( x - 6, y, x - 6, y + 7,x - 6, y + 7 ); + heartShape.bezierCurveTo( x - 6, y + 11, x - 3, y + 15.4, x + 5, y + 19 ); + heartShape.bezierCurveTo( x + 12, y + 15.4, x + 16, y + 11, x + 16, y + 7 ); + heartShape.bezierCurveTo( x + 16, y + 7, x + 16, y, x + 10, y ); + heartShape.bezierCurveTo( x + 7, y, x + 5, y + 5, x + 5, y + 5 ); + + const geometry = new THREE.ShapeGeometry( heartShape ); + const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); + const mesh = new THREE.Mesh( geometry, material ) ; + scene.add( mesh ); + + +

    Constructeur

    + + +

    [name]([param:Array shapes], [param:Integer curveSegments])

    +

    + shapes — [page:Array] de formes ou une seule [page:Shape shape]. La valeur par défaut est un triangle.
    + curveSegments - [page:Integer] - Nombre de segments par forme. La valeur par défaut est 12. +

    + +

    Propriétés

    +

    Voir la classe de base [page:BufferGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:BufferGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/SphereGeometry.html b/docs/api/fr/geometries/SphereGeometry.html new file mode 100644 index 00000000000000..3d9cde664d3fec --- /dev/null +++ b/docs/api/fr/geometries/SphereGeometry.html @@ -0,0 +1,77 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Une classe pour générer des géométries de sphère.

    + + + + + +

    Exemple de code :

    + + const geometry = new THREE.SphereGeometry( 15, 32, 16 ); + const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); + const sphere = new THREE.Mesh( geometry, material ); + scene.add( sphere ); + + +

    Constructeur

    + +

    [name]([param:Float radius], [param:Integer widthSegments], [param:Integer heightSegments], [param:Float phiStart], [param:Float phiLength], [param:Float thetaStart], [param:Float thetaLength])

    + +

    + radius — Rayon de la sphère. La valeur par défaut est 1.
    + widthSegments — Nombre de segments horizontaux. La valeur minimale est 3 et la valeur par défaut est 32.
    + heightSegments — Nombre de segments verticaux. La valeur minimale est 2 et la valeur par défaut est 16.
    + phiStart — Spécifie l'angle de départ horizontal. La valeur par défaut est 0.
    + phiLength — Spécifie la taille de l'angle de balayage horizontal. La valeur par défaut est Math.PI * 2.
    + thetaStart — Spécifie l'angle de départ vertical. La valeur par défaut est 0.
    + thetaLength — Spécifie la taille de l'angle de balayage vertical. La valeur par défaut est Math.PI.
    +

    + +

    + La géométrie est créée en balayant et en calculant les sommets autour de l'axe Y (balayage horizontal) et de l'axe Z (balayage vertical). Ainsi, des sphères incomplètes (semblables à des `'tranches de sphère'`) peuvent être créées en utilisant différentes valeurs de phiStart, phiLength, thetaStart et thetaLength, afin de définir les points auxquels nous commençons (ou terminons) le calcul de ces sommets. +

    + +

    Propriétés

    +

    Voir la classe de base [page:BufferGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:BufferGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/TetrahedronGeometry.html b/docs/api/fr/geometries/TetrahedronGeometry.html new file mode 100644 index 00000000000000..642205cee5ee65 --- /dev/null +++ b/docs/api/fr/geometries/TetrahedronGeometry.html @@ -0,0 +1,59 @@ + + + + + + + + + + [page:BufferGeometry] → [page:PolyhedronGeometry] → + +

    [name]

    + +

    Une classe pour générer une géométrie de tétraèdre.

    + + + + + +

    Constructeur

    + +

    [name]([param:Float radius], [param:Integer detail])

    +

    + radius — Rayon du tétraèdre. La valeur par défaut est 1.
    + detail — La valeur par défaut est 0. Définir une valeur supérieure à 0 ajoute des sommets, la géométrie n'est donc plus un tétraèdre. +

    + +

    Propriétés

    +

    Voir la classe de base [page:PolyhedronGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:PolyhedronGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/TorusGeometry.html b/docs/api/fr/geometries/TorusGeometry.html new file mode 100644 index 00000000000000..e5ac0723e3b670 --- /dev/null +++ b/docs/api/fr/geometries/TorusGeometry.html @@ -0,0 +1,70 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Une classe pour générer des géométries de tore.

    + + + + + +

    Exemple de code :

    + + const geometry = new THREE.TorusGeometry( 10, 3, 16, 100 ); + const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); + const torus = new THREE.Mesh( geometry, material ); + scene.add( torus ); + + +

    Constructeur

    + +

    [name]([param:Float radius], [param:Float tube], [param:Integer radialSegments], [param:Integer tubularSegments], [param:Float arc])

    +

    + radius - Rayon du tore, du centre du tore au centre du tube. La valeur par défaut est 1.
    + tube — Rayon du tube. La valeur par défaut est 0,4.
    + radialSegments — La valeur par défaut est 8
    + tubularSegments — La valeur par défaut est 6.
    + arc — Angle central. La valeur par défaut est Math.PI * 2. +

    + +

    Propriétés

    +

    Voir la classe de base [page:BufferGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:BufferGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/TorusKnotGeometry.html b/docs/api/fr/geometries/TorusKnotGeometry.html new file mode 100644 index 00000000000000..f81e8465be50fa --- /dev/null +++ b/docs/api/fr/geometries/TorusKnotGeometry.html @@ -0,0 +1,73 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Crée un nœud de tore, dont la forme particulière est définie par une paire d'entiers premiers entre eux, p et q. Si p et q ne sont pas premiers entre eux, le résultat sera un lien tore.

    + + + + + +

    Exemple de code :

    + + const geometry = new THREE.TorusKnotGeometry( 10, 3, 100, 16 ); + const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); + const torusKnot = new THREE.Mesh( geometry, material ); + scene.add( torusKnot ); + + +

    Constructeur

    + +

    [name]([param:Float radius], [param:Float tube], [param:Integer tubularSegments], [param:Integer radialSegments], [param:Integer p], [param:Integer q])

    +

    +

      +
    • radius - Rayon du tore. La valeur par défaut est 1.
    • +
    • tube — Rayon du tube. La valeur par défaut est 0,4.
    • +
    • tubularSegments — La valeur par défaut est 64.
    • +
    • radialSegments — La valeur par défaut est 8.
    • +
    • p — Cette valeur détermine combien de fois la géométrie s'enroule autour de son axe de symétrie de rotation. La valeur par défaut est 2.
    • +
    • q — Cette valeur détermine combien de fois la géométrie s'enroule autour d'un cercle à l'intérieur du tore. La valeur par défaut est 3.
    • +
    +

    + +

    Propriétés

    +

    Voir la classe de base [page:BufferGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    Méthodes

    +

    Voir la classe de base [page:BufferGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/TubeGeometry.html b/docs/api/fr/geometries/TubeGeometry.html new file mode 100644 index 00000000000000..e5469bdfa2e548 --- /dev/null +++ b/docs/api/fr/geometries/TubeGeometry.html @@ -0,0 +1,111 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Crée un tube qui s'extrude le long d'une courbe 3D.

    + + + + + +

    Exemple de code :

    + + + class CustomSinCurve extends THREE.Curve { + + constructor( scale = 1 ) { + + super(); + + this.scale = scale; + + } + + getPoint( t, optionalTarget = new THREE.Vector3() ) { + + const tx = t * 3 - 1.5; + const ty = Math.sin( 2 * Math.PI * t ); + const tz = 0; + + return optionalTarget.set( tx, ty, tz ).multiplyScalar( this.scale ); + + } + + } + + const path = new CustomSinCurve( 10 ); + const geometry = new THREE.TubeGeometry( path, 20, 2, 8, false ); + const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); + const mesh = new THREE.Mesh( geometry, material ); + scene.add( mesh ); + + +

    Constructeur

    + + +

    [name]([param:Curve path], [param:Integer tubularSegments], [param:Float radius], [param:Integer radialSegments], [param:Boolean closed])

    +

    + path — [page:Curve] - Un chemin 3D qui hérite de la classe de base [page:Curve]. La valeur par défaut est une courbe de Bézier quadratique.
    + tubularSegments — [page:Integer] - Le nombre de segments qui composent le tube. La valeur par défaut est '64'.
    + radius — [page:Float] - Le rayon du tube. La valeur par défaut est '1'.
    + radialSegments — [page:Integer] - Le nombre de segments qui composent la section. La valeur par défaut est '8'.
    + closed — [page:Boolean] Spécifie si le tube est ouvert ou fermé. La valeur par défaut est `false`.
    +

    + + +

    Propriétés

    +

    Voir la classe de base [page:BufferGeometry] pour les propriétés communes.

    + +

    [property:Object parameters]

    +

    + Un objet avec une propriété pour chacun des paramètres du constructeur. Toute modification après instanciation ne change pas la géométrie. +

    + +

    [property:Array tangents]

    +

    + Un tableau de tangentes [page:Vector3]. +

    + +

    [property:Array normals]

    +

    + Un tableau de normales [page:Vector3]. +

    + +

    [property:Array binormals]

    +

    + Un tableau de binormaux [page:Vector3]. +

    + +

    Méthodes

    +

    Voir la classe de base [page:BufferGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/fr/geometries/WireframeGeometry.html b/docs/api/fr/geometries/WireframeGeometry.html new file mode 100644 index 00000000000000..7069042ae2e417 --- /dev/null +++ b/docs/api/fr/geometries/WireframeGeometry.html @@ -0,0 +1,56 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Cela peut être utilisé comme objet d'assistance pour afficher une [page:BufferGeometry geometry] sous forme filaire.

    + +

    Exemple de code :

    + + + const geometry = new THREE.SphereGeometry( 100, 100, 100 ); + + const wireframe = new THREE.WireframeGeometry( geometry ); + + const line = new THREE.LineSegments( wireframe ); + line.material.depthTest = false; + line.material.opacity = 0.25; + line.material.transparent = true; + + scene.add( line ); + + +

    Exemples

    + +

    + [example:webgl_helpers helpers] +

    + +

    Constructeur

    + +

    [name]( [param:BufferGeometry geometry] )

    +

    + geometry — Tout objet de géométrie. +

    + +

    Propriétés

    +

    Voir la classe de base [page:BufferGeometry] pour les propriétés communes.

    + +

    Méthodes

    +

    Voir la classe de base [page:BufferGeometry] pour les méthodes communes.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/animation/AnimationAction.html b/docs/api/it/animation/AnimationAction.html new file mode 100644 index 00000000000000..ea63fda9eacee0 --- /dev/null +++ b/docs/api/it/animation/AnimationAction.html @@ -0,0 +1,348 @@ + + + + + + + + + +

    [name]

    + +

    + AnimationAction pianifica l'esecuzione delle animazioni archiviate in + [page:AnimationClip AnimationClips].

    + + Nota: La maggior parte dei metodi di AnimationAction può essere concatenata. + + Per una paronamica dei diversi elementi del sistema di animazione di three.js consultare + l'articolo "Sistema di animazione" nella sezione "Prossimi Passi" del manuale. +

    + + +

    Costruttore

    + + +

    [name]( [param:AnimationMixer mixer], [param:AnimationClip clip], [param:Object3D localRoot] )

    +

    + [page:AnimationMixer mixer] - l'`AnimationMixer` controllato da questa azione.
    + [page:AnimationClip clip] - l'`AnimationClip` che contiene i dati di animazione per questa azione.
    + [page:Object3D localRoot] - l'oggetto root su cui viene eseguita questa azione.

    + + Nota: Invece di chiamare questo costruttore direttamente, dovresti creare un'istanza AnimationAction con + [page:AnimationMixer.clipAction] poiché questo metodo fornisce la memorizzazione nella cache per migliorare + le prestazioni. +

    + + +

    Proprietà

    + + +

    [property:Boolean clampWhenFinished]

    +

    + Se `clampWhenFinished` è impostato a true l'animazione verrà automaticamente messa in [page:.paused pausa] + sull'ultimo frame.

    + + Se `clampWhenFinished` è impostato a false, [page:.enabled enabled] verrà automaticamente impostato a false + al termine dell'ultimo ciclo di animazione, in modo che questa azione non abbia più alcun impatto.

    + + Il valore di default è false.

    + + Nota: `clampWhenFinished` non ha impatto se l'azione viene interrotta (ha effetto solo se il suo ultimo ciclo + è effettivamente terminato). +

    + +

    [property:Boolean enabled]

    +

    + Impostare `enabled` a `false` disabilita questa azione, in modo che non abbia più alcun impatto. Il valore di default è `true`.

    + + Quando l'azione viene riattivata (re-enabled), l'animazione continua dal [page:.time tempo] corrente + (impostare `enabled` a `false` non resetta l'azione).

    + + Nota: Impostare `enabled` a `true` non riavvia automaticamente l'azione. Impostare `enabled` a `true` + farà riavviare l'animazione immediatamente solo se è soddisfatta la seguente condizione: + [page:.paused paused] è `false`, l'azione non è stata disattivata nel frattempo + (eseguendo un comando di [page:.stop stop] o [page:.reset reset]) e né [page:.weight weight] né + [page:.timeScale timeScale] sono pari a `0`. +

    + +

    [property:Number loop]

    +

    + La modalità di looping può essere modificata con [page:.setLoop setLoop]. L'impostazione predefinita è + [page:Animation THREE.LoopRepeat] (con un numero infinito di [page:.repetitions ripetizioni])

    + + Il valore deve essere una di queste costanti:

    + [page:Animation THREE.LoopOnce] - riproduce il clip una volta,
    + [page:Animation THREE.LoopRepeat] - riproduce il clip con il numero di `ripetizioni` prescelto, + ogni volta saltando dalla fine della clip direttamente al suo inizio,
    + [page:Animation THREE.LoopPingPong] - riproduce il clip con il numero di `ripetizioni` prescelto, + alternativamente in avanti e in indietro. +

    + +

    [property:Boolean paused]

    +

    + Impostando `paused` a `true` l'azione verrà sospesa impostando il time scale effettivo a `0`. Il valore di default è `false`. +

    + +

    [property:Number repetitions]

    +

    + Il numero di ripetizioni dell'[page:AnimationClip] eseguite nel corso di questa azione. + Può essere settato tramite [page:.setLoop setLoop]. Il valore di default è `Infinity`.

    + Se la modalità di [page:loop looping] è impostata a [page:Animation THREE.LoopOnce], impostare questo valore non ha effetti. +

    + +

    [property:Number time]

    +

    + L'ora locale di questa azione (in secondi, partendo da `0`).

    + + Il valore viene bloccato a `0...clip.duration` (in base allo stato del ciclo). Può essere scalato + rispetto al tempo globale del mixer modificando [page:.timeScale timeScale] (utilizzando + [page:.setEffectiveTimeScale setEffectiveTimeScale] o [page:.setDuration setDuration]).
    +

    + +

    [property:Number timeScale]

    +

    + Fattore di scala per il [page:.time tempo]. Un valore uguale a `0` mette in pausa l'azione. Valori + negativi fanno sì che l'animazione venga riprodotta all'indietro. Il valore di default è `1`.

    + Le proprietà/metodi relativi a `timeScale` (rispettivamente `time`) sono: + [page:.getEffectiveTimeScale getEffectiveTimeScale], + [page:.halt halt], + [page:.paused paused], + [page:.setDuration setDuration], + [page:.setEffectiveTimeScale setEffectiveTimeScale], + [page:.stopWarping stopWarping], + [page:.syncWith syncWith], + [page:.warp warp]. +

    + +

    [property:Number weight]

    +

    + Il grado di influenza di questa azione (nell'intervallo `[0, 1]`). I valori tra `0` (nessun impatto) + e 1 (impatto totale) possono essere usati per combinare più azioni. Il valore di default è `1`.

    + Le proprietà/metodi relativi a `weight` sono: + [page:.crossFadeFrom crossFadeFrom], + [page:.crossFadeTo crossFadeTo], + [page:.enabled enabled], + [page:.fadeIn fadeIn], + [page:.fadeOut fadeOut], + [page:.getEffectiveWeight getEffectiveWeight], + [page:.setEffectiveWeight setEffectiveWeight], + [page:.stopFading stopFading]. +

    + +

    [property:Boolean zeroSlopeAtEnd]

    +

    + Abilita l'interpolazione uniforme senza clip separati per inizio, loop e fine. Il valore di default è `true`. +

    + +

    [property:Boolean zeroSlopeAtStart]

    +

    + Abilita l'interpolazione uniforme senza clip separati per inizio, loop e fine. Il valore di default è `true`. +

    + + +

    Metodi

    + + +

    [method:this crossFadeFrom]( [param:AnimationAction fadeOutAction], [param:Number durationInSeconds], [param:Boolean warpBoolean] )

    +

    + Provoca il [page:.fadeIn fade in] (la dissolvenza in entrata) di questa azione, e la dissolvenza in uscita di un'altra azione + simultaneamente, entro l'intervallo passato. Questo metodo può essere concatenato.

    + + Se warpBoolean è true, verranno applicati ulteriori [page:.warp warping] (modifiche graduali delle scale temporali).

    + + Nota: Come con `fadeIn`/`fadeOut`, la dissolvenza inizia/termina con un weight di 1. +

    + +

    [method:this crossFadeTo]( [param:AnimationAction fadeInAction], [param:Number durationInSeconds], [param:Boolean warpBoolean] )

    +

    + Provoca il [page:.fadeOut fade out] (la dissolvenza in uscita) di questa azione, e la dissolvenza in entrata di un'altra azione + simultaneamente, entro l'intervallo passato. Questo metodo può essere concatenato.

    + + Se warpBoolean è true, verranno applicati ulteriori [page:.warp warping] (modifiche graduali delle scale temporali).

    + + Nota: Come con `fadeIn`/`fadeOut`, la dissolvenza inizia/termina con un weight di 1. +

    + +

    [method:this fadeIn]( [param:Number durationInSeconds] )

    +

    + Aumenta il [page:.weight weight] di questa azione gradualmente da `0` a `1`, entro l'intervallo passato. + Questo metodo può essere concatenato. +

    + +

    [method:this fadeOut]( [param:Number durationInSeconds] )

    +

    + Diminuisce il [page:.weight weight] di questa azione gradualmente da `1` a `0`, entro l'intervallo passato. + Questo metodo può essere concatenato. +

    + +

    [method:Number getEffectiveTimeScale]()

    +

    + Restituisce l'effettivo time scale (considerando lo stato attuale di [page:.warp warping] e di [page:.paused paused]). +

    + +

    [method:Number getEffectiveWeight]()

    +

    + Restituisce l'effettivo weight (considerando lo stato attuale di fading e di [page:.enabled enabled]). +

    + +

    [method:AnimationClip getClip]()

    +

    + Restituisce la clip che contiene i dati di animazione di questa azione. +

    + +

    [method:AnimationMixer getMixer]()

    +

    + Restituisce il mixer responsabile dell'esecuzione di questa azione. +

    + +

    [method:Object3D getRoot]()

    +

    + Restituisce l'oggetto root sul quale questa animazione è eseguita. +

    + +

    [method:this halt]( [param:Number durationInSeconds] )

    +

    + Decelera la velocità di questa animazione a `0` diminuendo gradualmente il [page:.timeScale timeScale] + (a partire dal valore corrente), entro l'intervallo passato. Questo metodo può essere concatenato. +

    + +

    [method:Boolean isRunning]()

    +

    + Restituisce true se il [page:.time time] dell'azione è attualmente in esecuzione.

    + + Oltre ad essere attivato nel mixer (vedi [page:.isScheduled isScheduled]) le seguenti condizioni devono essere soddisfatte: + [page:.paused paused] deve essere uguale a false, [page:.enabled enabled] deve essere uguale a true, + [page:.timeScale timeScale] deve essere diversa da `0`, e non deve essere prevista nessuna programmazione + per un avvio ritardato ([page:.startAt startAt]).

    + + Nota: il fatto che `isRunning` sia true non significa necessariamente che l'animazione sia effettivamente visibile. + Ciò avviene solo se [page:.weight weight] è impostato su un valore diverso da zero. +

    + +

    [method:Boolean isScheduled]()

    +

    + Restituisce true se questa azione è attivata nel mixer.

    + Nota: Questo non significa necessariamente che l'animazione sia effettivamente in esecuzione (confronta + le condizioni aggiuntive per [page:.isRunning isRunning]). +

    + +

    [method:this play]()

    +

    + Dice al mixer di attivare l'azione. Questo metodo può essere concatenato.

    + + Nota: Attivare questa azione non significa necessatiamente che l'animazione verrà avviata immediatamente: + Se l'azione era già terminata prima (raggiungendo la fine del suo ultimo loop), o se è stato impostato un tempo + per un inizio ritardato (tramite [page:.startAt startAt]), prima deve essere eseguito un [page:.reset reset]. + Anche altre impostazioni, (come [page:.paused paused]=true, [page:.enabled enabled]=false, + [page:.weight weight]=0, [page:.timeScale timeScale]=0) possono impedire la riproduzione dell'animazione. +

    + +

    [method:this reset]()

    +

    + Reimposta l'azione. Questo metodo può essere concatenato.

    + + Questo metodo imposta [page:.paused paused] a false, [page:.enabled enabled] a true, + [page:.time time] a `0`, interrompe ogni fading e wraping programmati, e rimuove il conteggio del loop + interno per l'avvio ritardato.

    + + Nota: .`reset` è sempre chiamato da [page:.stop stop], ma .`reset` non chiama .`stop`. + Questo significa che se vuoi chiamare entrambi i metodi, non chiamare .`reset`, chiama invece .`stop`. +

    + +

    [method:this setDuration]( [param:Number durationInSeconds] )

    +

    + Imposta la durata per un singolo loop dell'azione (regolando il [page:.timeScale timeScale] e + interrompendo qualsiasi warping programmato). Questo metodo può essere concatenato. +

    + +

    [method:this setEffectiveTimeScale]( [param:Number timeScale] )

    +

    + Imposta il [page:.timeScale timeScale] e interrompe qualsiasi warping programmato. Questo metodo può essere concatenato.

    + + Se [page:.paused paused] è false, l'effettivo time scale (una proprietà interna) sarà impostato a questo valore, + altrimenti il time scale effettivo (che influenza direttamente l'animazione in questo momento) verrà impostato a `0`.

    + + Nota: Se .`timeScale` è impostato `0` da questo metodo, .`paused` non verrà impostato automaticamente a `true`. +

    + +

    [method:this setEffectiveWeight]( [param:Number weight] )

    +

    + Imposta il [page:.weight weight] e interrompe qualsiasi fading programmato. Questo metodo può essere concatenato.

    + + Se [page:.enabled enabled] è true, l'effettivo weight (una proprietà interna) sarà impostato a questo valore, + altrimenti il weight effettivo (che influenza direttamente l'animazione in questo momento) verrà impostata a `0`.

    + + Nota: Se .`weight` è impostato `0` da questo metodo, .`enabled` non passerà automaticamente a `false`. +

    + +

    [method:this setLoop]( [param:Number loopMode], [param:Number repetitions] )

    +

    + Imposta la modalità di [page:.loop looping] e il numero di [page:.repetitions ripetizioni]. Questo metodo può essere concatenato. +

    + +

    [method:this startAt]( [param:Number startTimeInSeconds] )

    +

    + Definisce il tempo per un avvio ritardato (solitamente passato come [page:AnimationMixer.time] + + deltaTimeInSeconds). Questo metodo può essere concatenato.

    + + Nota: L'animazione inizierà solo all'ora indicata se .`startAt` è concatenato con + [page:.play play], o se l'azione è già stata attivata nel mixer (da una precedente chiamata di .`play`, + senza che nel frattempo sia stata fermata o resettata). +

    + +

    [method:this stop]()

    +

    + Dice al mixer di disattivare questa azione. Questo metodo può essere concatenato.

    + + L'azione verrà immediatamente interrotta e completamente [page:.reset resettata].

    + + Nota: puoi interrompere tutte le azioni attive sullo stesso mixer in una volta sola tramite + [page:AnimationMixer.stopAllAction mixer.stopAllAction]. +

    + +

    [method:this stopFading]()

    +

    + Interrompe qualsiasi [page:.fadeIn fading] programmato applicato a questa azione. Questo metodo può essere concatenato. +

    + +

    [method:this stopWarping]()

    +

    + Interrompe qualsiasi [page:.warp warping] programmato applicato a questa azione. Questo metodo può essere concatenato. +

    + +

    [method:this syncWith]( [param:AnimationAction otherAction] )

    +

    + Sincronizza questa azione con l'altra azione passata. Questo metodo può essere concatenato.

    + + La sincronizzazione viene fatta impostando i valori [page:.time time] e [page:.timeScale timeScale] + di questa azione ai corrispondenti valori dell'altra azione (interrompendo qualsiasi warping programmato).

    + + Nota: Le modifiche future di `time` e `timeScale` dell'altra azione non verranno rilevate. +

    + +

    [method:this warp]( [param:Number startTimeScale], [param:Number endTimeScale], [param:Number durationInSeconds] )

    +

    + Modifica la velocità di riproduzione, entro l'intervallo di tempo passato, modificando + gradualmente il [page:.timeScale timeScale] da `startTimeScale` a `endTimeScale`. Questo metodo può essere concatenato. +

    + + +

    Eventi

    + + +

    + Ci sono due eventi che indicano quando un singolo ciclo dell'azione o l'intera azione è terminata. Si può rispondere ad essi con: +

    + + mixer.addEventListener( 'loop', function( e ) { …} ); // properties of e: type, action and loopDelta + mixer.addEventListener( 'finished', function( e ) { …} ); // properties of e: type, action and direction + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/animation/AnimationClip.html b/docs/api/it/animation/AnimationClip.html new file mode 100644 index 00000000000000..b7a28a63b331e4 --- /dev/null +++ b/docs/api/it/animation/AnimationClip.html @@ -0,0 +1,149 @@ + + + + + + + + + +

    [name]

    + +

    + Un AnimationClip è un insieme riutilizzabile di tracce di keyframe che rappresentano un'animazione.

    + + Per una paronamica dei diversi elementi del sistema di animazione di three.js consultare l'articolo + "Sistema di animazione" nella sezione "Prossimi Passi" del manuale. +

    + + +

    Costruttore

    + + +

    [name]( [param:String name], [param:Number duration], [param:Array tracks] )

    +

    + [page:String name] - il nome di questa clip.
    + [page:Number duration] - la durata di questa clip (in secondi). Se viene passato un valore negativo, + la durata verrà calcolata dall'array delle `tracks` passate.
    + [page:Array tracks] - un array di [page:KeyframeTrack KeyframeTrack].

    + + Nota: Invece di creare direttamente un'istanza di AnimationClip usando il costruttore, è possibile usare uno + dei suoi metodi statici per creare le AnimationClip: da JSON ([page:.parse parse]), da sequenze + morph target ([page:.CreateFromMorphTargetSequence CreateFromMorphTargetSequence], + [page:.CreateClipsFromMorphTargetSequences CreateClipsFromMorphTargetSequences]) o da gerarchie + di animazione ([page:.parseAnimation parseAnimation]) - se il tuo modello non contiene già una + AnimationClip nell'array di animazioni della sua geometria. +

    + + +

    Proprietà

    + + +

    [property:Number duration]

    +

    + La durata di questa clip (in secondi). Può essere calcolata dall'array delle [page:.tracks tracks] + tramite [page:.resetDuration resetDuration]. +

    + +

    [property:String name]

    +

    + Il nome di questa clip. Una specifica clip può essere cercata tramite [page:.findByName findByName]. +

    + +

    [property:Array tracks]

    +

    + Un array contenente un [page:KeyframeTrack] per ciascuna proprietà animata da questa clip. +

    + +

    [property:String uuid]

    +

    + L'[link:http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] di questa istanza di clip. + Viene assegnato automaticamente e non deve essere modificato. +

    + + +

    Metodi

    + + +

    [method:AnimationClip clone]()

    +

    + Restituisce una copia di questa clip. +

    + +

    [method:this optimize]()

    +

    + Ottimizza ogni track rimuovendo le chiavi sequenziali equivalenti (le quali sono comuni nelle + sequenze morph target). +

    + +

    [method:this resetDuration]()

    +

    + Imposta la [page:.duration durata] della clip sulla durata del suo [page:KeyframeTrack] + più lungo. +

    + +

    [method:Object toJSON]()

    +

    + Restituisce un oggetto JSON che descrive la clip di animazione serializzata. +

    + +

    [method:this trim]()

    +

    + Taglia tutte le tracce alla durata della clip. +

    + +

    [method:Boolean validate]()

    +

    + Esegue una minima validazione di ogni track nella clip. Restituisce true se tutte le track sono valide. +

    + + +

    Metodi Statici

    + + +

    [method:Array CreateClipsFromMorphTargetSequences]( [param:String name], [param:Array morphTargetSequence], [param:Number fps], [param:Boolean noLoop] )

    +

    + Restituisce un array di nuove AnimationClip creato dalle sequenze morph target di una geometria, + cercando di ordinare i nomi di morph target in pattern basati su gruppi di animazione come + "Walk_001, Walk_002, Run_001, Run_002 ...". +

    + +

    [method:AnimationClip CreateFromMorphTargetSequence]( [param:String name], [param:Array morphTargetSequence], [param:Number fps], [param:Boolean noLoop] )

    +

    + Restituisce una nuova AnimationClip dall'array morph target, passato come parametro, di una geometria, + prendendo un nome e il numero di frame per secondo.

    + + Nota: Il parametro fps è obbligatorio, ma la velocità dell'animazione può essere sovrascritta in + una `AnimationAction` tramite [page:AnimationAction.setDuration animationAction.setDuration]. +

    + +

    [method:AnimationClip findByName]( [param:Object objectOrClipArray], [param:String name] )

    +

    + Cerca una AnimationClip tramite nome, prendendo come primo parametro un array di AnimationClip o una mesh + o una geometria contenente un array chiamato "animations". +

    + +

    [method:AnimationClip parse]( [param:Object json] )

    +

    + Parsa una rappresentazione JSON di una clip e restituisce una AnimationClip. +

    + +

    [method:AnimationClip parseAnimation]( [param:Object animation], [param:Array bones] )

    +

    + Parsa il formato animation.hierarchy e restituisce una AnimationClip. +

    + +

    [method:Object toJSON]( [param:AnimationClip clip] )

    +

    + Prende una AnimationClip e restituisce un oggetto JSON. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/animation/AnimationMixer.html b/docs/api/it/animation/AnimationMixer.html new file mode 100644 index 00000000000000..fada757d5ba59d --- /dev/null +++ b/docs/api/it/animation/AnimationMixer.html @@ -0,0 +1,121 @@ + + + + + + + + + +

    [name]

    + +

    + L'AnimationMixer è un player per animazioni su un particolare oggetto della scena. Quando + più oggetti nella scena sono animati indipendentemente, un AnimationMixer può essere utilizzato + per ogni oggetto.

    + + Per una paronamica dei diversi elementi del sistema di animazione di three.js consultare + l'articolo "Sistema di animazione" nella sezione "Prossimi Passi" del manuale. +

    + + +

    Costruttore

    + + +

    [name]( [param:Object3D rootObject] )

    +

    + [page:Object3D rootObject] - l'oggetto le cui animazioni devono essere riprodotte da questo mixer.
    +

    + + +

    Proprietà

    + + +

    [property:Number time]

    +

    + Il tempo globale del mixer (in secondi; inizia con `0` dalla creazione del mixer). +

    + +

    [property:Number timeScale]

    +

    + Un fattore di scala per il [page:.time mixer time] globale.

    + + Nota: Impostando il timeScale del mixer a `0` e successivamente di nuovo a `1` è possibile + mettere in pause/unpause tutte le animazioni controllate da questo mixer. +

    + + +

    Metodi

    + + +

    [method:AnimationAction clipAction]([param:AnimationClip clip], [param:Object3D optionalRoot])

    +

    + Restituisce una AnimationAction per la clip passata come parametro, eventualmente utilizzando + un oggetto root diverso dalla root predefinita del mixer. Il primo parametro può essere sia un + oggetto [page:AnimationClip] sia il nome di una AnimationClip.

    + + Se non esiste ancora un'azione che corrisponda ai parametri della clip e della radice, questa verrà creata + da questo metodo. Chiamando questo metodo più volte con gli stessi parametri clip e + radice, si ottiene sempre la stessa istanza di clip. +

    + +

    [method:AnimationAction existingAction]([param:AnimationClip clip], [param:Object3D optionalRoot])

    +

    + Restituisce una [page:AnimationAction] esistente per la clip passata come parametro, + eventualmente utilizzando un oggetto root diverso dalla root predefinita del mixer.

    + + Il primo parametro può essere sia un oggetto [page:AnimationClip] sia il nome di una AnimationClip. +

    + +

    [method:Object3D getRoot]()

    +

    + Restituisce l'oggetto root del mixer. +

    + +

    [method:this stopAllAction]()

    +

    + Disattiva tutte le azioni precedentemente programmate su questo mixer. +

    + +

    [method:this update]([param:Number deltaTimeInSeconds])

    +

    + Anticipa il tempo del mixer globale e aggiorna l'animazione.

    + + Solitamente viene fatto nel render loop, passando [page:Clock.getDelta clock.getDelta] scalato dal [page:.timeScale timeScale] del mixer. +

    + +

    [method:this setTime]([param:Number timeInSeconds])

    +

    + Imposta il mixer globale a un tempo specifico e aggiorna l'animazione di conseguenza.

    + + È utile quando si vuole saltare ad un tempo specifico dell'animazione. Il parametro in input verrà scalato dal [page:.timeScale timeScale] del mixer. +

    + +

    [method:undefined uncacheClip]([param:AnimationClip clip])

    + +

    + Dealloca tutte le risorse di memoria per una clip. Prima di usare questo metodo assicurati di chiamare [page:AnimationAction.stop]() per + tutte le azioni correlate. +

    + +

    [method:undefined uncacheRoot]([param:Object3D root])

    +

    + Dealloca tutte le risorse di memoria per un oggetto root. Prima di usare questo metodo assicurati di chiamare [page:AnimationAction.stop]() per + tutte le azioni correlate. +

    + +

    [method:undefined uncacheAction]([param:AnimationClip clip], [param:Object3D optionalRoot])

    +

    + Dealloca tutte le risorse di memoria per un'azione. Prima di usare questo metodo assicurati di chiamare [page:AnimationAction.stop]() per + disattivare l'azione. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/animation/AnimationObjectGroup.html b/docs/api/it/animation/AnimationObjectGroup.html new file mode 100644 index 00000000000000..5c7539995f14a5 --- /dev/null +++ b/docs/api/it/animation/AnimationObjectGroup.html @@ -0,0 +1,92 @@ + + + + + + + + + +

    [name]

    + +

    Un gruppo di oggetti che riceve uno stato di animazione condiviso.

    + + Per una paronamica dei diversi elementi del sistema di animazione di three.js consultare l'articolo + "Sistema di animazione" nella sezione "Prossimi Passi" del manuale. +

    + +

    Utilizzo:

    + +

    + Aggiungi gli oggetti che altrimenti passeresti come root al costruttore o come parametro al metodo + [page:AnimationMixer.clipAction clipAction] della classe [page:AnimationMixer AnimationMixer] + e passa invece questo oggetto come 'root' della classe [page:AnimationMixer AnimationMixer].

    + + Si noti che gli oggetti di questa classe appaiono al mixer come unico oggetto, + quindi il controllo della cache dei singoli oggetti deve essere effettuato sul gruppo. +

    + + +

    Limitazioni

    +

    + Le proprietà di animazione devono essere compatibili tra tutti gli oggetti del gruppo.

    + + Una singola proprietà può essere controllata tramite un groppo target o direttamente, ma non entrambi. +

    + + +

    Costruttore

    + +

    [name]( [param:Object obj1], [param:Object obj2], [param:Object obj3], ... )

    +

    + [page:Object obj] - un numero arbitrario di mesh che condividono lo stesso stato di animazione. +

    + +

    Proprietà

    + +

    [property:Boolean isAnimationObjectGroup]

    +

    + Flag di sola lettura per controllare se un determinato oggetto è di tipo [name]. +

    + + +

    [property:Object stats]

    +

    + Un oggetto che contiene alcune informazioni di questo `AnimationObjectGroup` (numero totale, + numero in uso, numero di binding per oggetto) +

    + +

    [property:String uuid]

    +

    + L'[link:http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] di questo + `AnimationObjectGroup`. Viene automaticamente assegnato e non deve essere modificato. +

    + + +

    Metodi

    + + +

    [method:undefined add]( [param:Object obj1], [param:Object obj2], [param:Object obj3], ... )

    +

    + Agginge un numero arbitrario di oggetti a questo `AnimationObjectGroup`. +

    + +

    [method:undefined remove]( [param:Object obj1], [param:Object obj2], [param:Object obj3], ... )

    +

    + Rimuove un numero arbitrario di oggetti da questo `AnimationObjectGroup`. +

    + +

    [method:undefined uncache]( [param:Object obj1], [param:Object obj2], [param:Object obj3], ... )

    +

    + Dealloca tutte le risorse di memoria per gli oggetti passati come parametri di questo `AnimationObjectGroup`. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/animation/AnimationUtils.html b/docs/api/it/animation/AnimationUtils.html new file mode 100644 index 00000000000000..69afca9f9e87f7 --- /dev/null +++ b/docs/api/it/animation/AnimationUtils.html @@ -0,0 +1,67 @@ + + + + + + + + + +

    [name]

    + +

    + Un oggetto con varie funzioni di assistenza alle animazioni, usato internamente. +

    + + +

    Metodi

    + + +

    [method:Array arraySlice]( array, from, to )

    +

    + È lo stesso di Array.prototype.slice, ma funziona anche su array tipizzati. +

    + +

    [method:Array convertArray]( array, type, forceClone )

    +

    + Converte un array in un tipo specifico. +

    + +

    [method:Array flattenJSON]( jsonKeys, times, values, valuePropertyName )

    +

    + Utilizzato per parsare i formati keyframe AOS. +

    + +

    [method:Array getKeyframeOrder]( times )

    +

    + Restituisce un array in base al quale è possibile ordinare tempi e valori. +

    + +

    [method:Boolean isTypedArray]( object )

    +

    + Restituisce `true` se l'oggetto è un array tipizzato. +

    + +

    [method:AnimationClip makeClipAdditive]( [param:AnimationClip targetClip], [param:Number referenceFrame], [param:AnimationClip referenceClip], [param:Number fps] )

    +

    + Converte il keyframe di una data clip di animazione in un formato additivo. +

    + +

    [method:Array sortedArray]( values, stride, order )

    +

    + Ordina l'array precedentemente restituito da [page:AnimationUtils.getKeyframeOrder getKeyframeOrder]. +

    + +

    [method:AnimationClip subclip]( [param:AnimationClip clip], [param:String name], [param:Number startFrame], [param:Number endFrame], [param:Number fps] )

    +

    + Create una nuova clip, contenente solo il segmento della clip originale tra i frame indicati. +

    + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/animation/KeyframeTrack.html b/docs/api/it/animation/KeyframeTrack.html new file mode 100644 index 00000000000000..f8839f2ce306f2 --- /dev/null +++ b/docs/api/it/animation/KeyframeTrack.html @@ -0,0 +1,259 @@ + + + + + + + + + + +

    [name]

    + +

    + Un KeyframeTrack è una sequenza temporizzata di [link:https://en.wikipedia.org/wiki/Key_frame keyframe], + composti da una lista di tempi e valori correlati, utilizzati per animare una proprietà specifica di un oggetto. +

    + +

    + Per una paronamica dei diversi elementi del sistema di animazione di three.js consultare l'articolo + "Sistema di animazione" nella sezione "Prossimi Passi" del manuale. +

    + +

    + A differenza della gerarchia di animazione del [link:https://github.com/mrdoob/three.js/wiki/JSON-Model-format-3 modello JSON], + `KeyframeTrack` non memorizza i suoi singoli keyframe come oggetti in un array "keys" (che contiene i tempi + e i valori di ciascun frame in un unico posto). +

    + +

    + Invece ci sono sempre due array in un `KeyframeTrack`: l'array [page:.times times] + memorizza i valori temporali per tutti i keyframe di questa traccia in ordine sequenziale e l'array + [page:.values values] contiene i corrispondenti valori di modifica della proprietà animata. +

    + +

    + Un singolo valore, appartenente ad un determinato momento, non può essere solo un semplice numero, ma + (per esempio) un vettore (se una posizione è animata) o un quaternione (se una rotazione è animata). + Per questo motivo l'array values (che è anche un array flat) potrebbe essere tre o quattro volte + più lungo dell'array times. +

    + +

    + In corrispondenza dei diversi tipi possibili di valori animati esistono diverse sottoclassi di `KeyframeTrack`, + che ereditano la maggior parte delle proprietà e dei metodi: +

    + +
      +
    • [page:BooleanKeyframeTrack]
    • +
    • [page:ColorKeyframeTrack]
    • +
    • [page:NumberKeyframeTrack]
    • +
    • [page:QuaternionKeyframeTrack]
    • +
    • [page:StringKeyframeTrack]
    • +
    • [page:VectorKeyframeTrack]
    • +
    + +

    + Alcuni esempi di come creare manualmente [page:AnimationClip AnimationClip] con diversi tipi di + KeyframeTrack possono essere trovati nel file [link:https://threejs.org/examples/jsm/animation/AnimationClipCreator.js AnimationClipCreator]. +

    + +

    + Poiché i valori espliciti sono solo specifici per i punti temporali discreti memorizzati nell'array times + tutti i valori itermedi devono essere interpolati. +

    + +

    + Il nome della track è importante per il collegamento di questa track con una proprietà specifica + del nodo animato (creato da [page:PropertyBinding]). +

    + + +

    Costruttore

    + + +

    [name]( [param:String name], [param:Array times], [param:Array values], [param:Constant interpolation] )

    +

    + [page:String name] - l'identificativo per `KeyframeTrack`.
    + [page:Array times] - un array di times di keyframe, convertito internamente a + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array].
    + [page:Array values] - un array con i valori relativi all'array times, convertito internamente a + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array].
    + [page:Constant interpolation] - il tipo di interpolazione da usare. Vedi + [page:Animation Animation Constants] per i possibili valori. L'impostazione predefinita è [page:Animation InterpolateLinear]. +

    + + +

    Proprietà

    + + +

    [property:String name]

    +

    + Il nome della track può riferirsi a morph targets o [page:SkinnedMesh bones] o possibilmente ad altri valori all'interno dell'oggetto animato. + Vedi [page:PropertyBinding.parseTrackName] per le forme di stringhe che possono essere parsate per il property + binding: +

    + +

    + Il nome può specificare il nodo utilizzando il suo nome o il suo uuid (anche se deve trovarsi + nel sottoalbero del nodo del grafo della scena passato al mixer). Oppure, se il nome della track inizia con un punto, + la track si applica al nodo root che è stato passato nel mixer. +

    + +

    + Solitamente dopo il nodo una proprietà viene specificata direttamente. Ma si può anche specificare + una sottoproprietà, come .rotation[x], se si vuole guidare il componente X della rotazione tramite + una traccia float. +

    + +

    + Si possono anche specificare ossa (bones) o multimateriali usando il nome di un oggetto, per esempio: + .bones[R_hand].scale; il canale rosso del colore diffuso del quarto materiale in un array di materiali + - come ulteriore esempio - è accessibile con .materials[3].diffuse[r]. +

    + +

    + Il PropertyBinding risolverà anche i nomi dei morph target, per esempio: .morphTargetInfluences[run]. +

    + +

    + Nota: Il nome della traccia non deve essere per forza univoco. Più tracce possono guidare la stessa proprietà. + Il risultato deve essere basato su una miscela ponderata tra le tracce multiple in base ai pesi delle rispettive + azioni. +

    + +

    [property:Float32Array times]

    +

    + Un [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array], + convertito dall'array times passato nel costruttore. +

    + +

    [property:Float32Array values]

    +

    + Un [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array], + convertito dall'array values passato nel costruttore. +

    + +

    [property:Constant DefaultInterpolation]

    +

    + Il tipo predefinito di interpolazione: [page:Animation InterpolateLinear]. +

    + +

    [property:Constant TimeBufferType ]

    +

    + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array], + il tipo di buffer internamente utilizzato per i tempi. +

    + +

    [property:Constant ValueBufferType ]

    +

    + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array], + il tipo di buffer internamente utilizzato per i valori. +

    + + +

    Metodi

    + + +

    [method:KeyframeTrack clone]()

    +

    + Restituisce una copia di questa traccia. +

    + +

    [method:Interpolant createInterpolant]()

    +

    + Crea una [page:LinearInterpolant LinearInterpolant], [page:CubicInterpolant CubicInterpolant] + o [page:DiscreteInterpolant DiscreteInterpolant], a seconda del valore del parametro di interpolazione + passato nel costruttore. +

    + +

    [method:Interpolant getInterpolation]()

    +

    + Restituisce il tipo di interpolazione. +

    + +

    [method:Number getValueSize]()

    +

    + Restituisce la dimensione di ongi value (ovvero la lunghezza dell'array [page:.values values] diviso + la lunghezza dell'array [page:.times times]). +

    + +

    [method:DiscreteInterpolant InterpolantFactoryMethodDiscrete]( [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array result] )

    +

    + Crea un nuovo [page:DiscreteInterpolant DiscreteInterpolant] dai [page:KeyframeTrack.times tempi] e + dai [page:KeyframeTrack.times valori]. È possibile passare un Float32Array che riceverà i risultati. + Altrimenti, verrà creato automaticamente un nuovo array di dimensioni appropriate. +

    + +

    [method:LinearInterpolant InterpolantFactoryMethodLinear]( [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array result] )

    +

    + Crea un nuovo [page:LinearInterpolant LinearInterpolant] dai [page:KeyframeTrack.times tempi] e + dai [page:KeyframeTrack.times valori].È possibile passare un Float32Array che riceverà i risultati. + Altrimenti, verrà creato automaticamente un nuovo array di dimensioni appropriate. +

    + +

    [method:CubicInterpolant InterpolantFactoryMethodSmooth]( [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array result] )

    +

    + Crea un nuovo [page:CubicInterpolant CubicInterpolant] dai [page:KeyframeTrack.times tempi] e + dai [page:KeyframeTrack.times valori].È possibile passare un Float32Array che riceverà i risultati. + Altrimenti, verrà creato automaticamente un nuovo array di dimensioni appropriate. +

    + +

    [method:this optimize]()

    +

    + Rimuove le chiavi sequenziali equivalenti, che sono comuni nelle sequenze morph target. +

    + +

    [method:this scale]()

    +

    + Scala tutti i tempi del keyframe di un fattore.

    + + Nota: Questo metodo è utile, per esempio, per le conversioni ad un determinato rate di frame per secondo (come + avviene internamente da + [page:AnimationClip.CreateFromMorphTargetSequence animationClip.CreateFromMorphTargetSequence]). +

    + +

    [method:this setInterpolation]( [param:Constant interpolationType] )

    +

    + Imposta il tipo di interpolazione. Vedi [page:Animation Animation Constants] per le opzioni. +

    + +

    [method:this shift]( [param:Number timeOffsetInSeconds] )

    +

    + Sposta tutti i keyframe avanti o indietro nel tempo. +

    + + +

    [method:this trim]( [param:Number startTimeInSeconds], [param:Number endTimeInSeconds] )

    +

    + Rimuove tutti i keyframe prima di `startTime` e dopo `endTime`, + senza modificare alcun valore nell'intervallo [`startTime`, `endTime`]. +

    + +

    [method:Boolean validate]()

    +

    + Esegue una convalida minima delle tracce. Restituisce true se è valido. +

    + +

    + Questo metodo registra gli errori nella console, se una traccia è vuota, se la dimensione del valore non è valida, + se un elemento nell'array [page:.times times] o nell'array [page:.values values] non è un numero valido o se + gli elementi nell'array times non sono ordinati. +

    + +

    Metodi statici

    + +

    [method:JSON toJSON]( [param:KeyframeTrack track] )

    +

    + Converte la traccia in JSON. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/animation/PropertyBinding.html b/docs/api/it/animation/PropertyBinding.html new file mode 100644 index 00000000000000..77aa84da0f3245 --- /dev/null +++ b/docs/api/it/animation/PropertyBinding.html @@ -0,0 +1,132 @@ + + + + + + + + + +

    [name]

    + +

    + Questa classe contiene un riferimento ad una proprietà reale nel grafo della scena; usata internamente. +

    + + +

    Costruttore

    + + +

    [name]( [param:Object3D rootNode], path, parsedPath )

    +

    + -- [page:Object3D rootNode]: + -- path + -- parsedPath (optional) + +

    + +

    Proprietà

    + +

    [property:Number path]

    +

    + +

    + +

    [property:Number parsedPath]

    +

    + +

    + +

    [property:Number node]

    +

    + +

    + +

    [property:Number rootNode]

    +

    + +

    + +

    [property:Object BindingType]

    +

    + +

    + +

    [property:Object Versioning]

    +

    + +

    + +

    [property:Array GetterByBindingType]

    +

    + +

    + +

    [property:Array SetterByBindingTypeAndVersioning]

    +

    + +

    + + + +

    Metodi

    + +

    [method:undefined getValue]( [param:Array targetArray], [param:Number offset] )

    +

    +

    + +

    [method:undefined setValue]( [param:Array sourceArray], [param:Number offset] )

    +

    +

    + +

    [method:undefined bind]( )

    +

    + Crea una coppia getter e setter per la proprietà nel grafo della scena. Usata internamente + da [page:PropertyBinding.getValue getValue] e [page:PropertyBinding.setValue setValue]. +

    + +

    [method:undefined unbind]( )

    +

    + Unbind della coppia getter e setter per la proprietà nel grafo della scena. +

    + +

    [method:Constructor Composite]( targetGroup, path, optionalParsedPath )

    +

    + Crea un nuovo Composite PropertyBinding. +

    + +

    [method:Constructor create]( root, path, parsedPath )

    +

    + Crea un nuovo Composite PropertyBinding (se la root è una [page:AnimationObjectGroup] o PropertyBinding). +

    + +

    [method:Constructor parseTrackName]( trackName )

    +

    + Corrisponde a stringhe nelle seguenti forme:
    + -- nodeName.property
    + -- nodeName.property[accessor]
    + -- nodeName.material.property[accessor]
    + -- uuid.property[accessor]
    + -- uuid.objectName[objectIndex].propertyName[propertyIndex]
    + -- parentName/nodeName.property
    + -- parentName/parentName/nodeName.property[index]
    + -- .bone[Armature.DEF_cog].position
    + -- scene:helium_balloon_model:helium_balloon_model.position +

    + +

    [method:Constructor findNode]( root, nodeName )

    +

    + Trova il nodo in un albero di nodi o in uno [page:Skeleton Skeleton]. +

    + + + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/animation/PropertyMixer.html b/docs/api/it/animation/PropertyMixer.html new file mode 100644 index 00000000000000..e5516b26395c68 --- /dev/null +++ b/docs/api/it/animation/PropertyMixer.html @@ -0,0 +1,113 @@ + + + + + + + + + +

    [name]

    + +

    + Proprietà del grafo della scena bufferizzata che consente l'accumulo ponderato (weighted); utilizzata internamente. +

    + + +

    Costruttore

    + + +

    [name]( [param:PropertyBinding binding], [param:String typeName], [param:Number valueSize] )

    +

    + -- binding
    + -- typeName
    + -- valueSize
    +

    + + +

    Proprietà

    + + +

    [property:PropertyBinding binding]

    +

    + +

    + +

    [property:TypedArray buffer]

    +

    + Buffer con dimensione [page:PropertyMixer valueSize] * 4.

    + Ha il seguente layout: [ incoming | accu0 | accu1 | orig ]

    + Gli interpolatori possono usare .buffer come loro .result e i dati vanno quindi in 'incoming'. + 'accu0' e 'accu1' sono usati come frame-interleaved per il risultato cumulativo e + vengono confrontati per rilevare le modifiche. 'orig' memorizza lo stato originale + della proprietà. +

    + +

    [property:Number cumulativeWeight]

    +

    + Il valore di default è `0`. +

    + +

    [property:Number cumulativeWeightAdditive]

    +

    + Il valore di default è `0`. +

    + +

    [property:Number valueSize]

    +

    + +

    + +

    [property:Number referenceCount]

    +

    + Il valore di default è `0`. +

    + +

    [property:Number useCount]

    +

    + Il valore di default è `0`. +

    + + +

    Metodi

    + + +

    [method:undefined accumulate]( [param:Number accuIndex], [param:Number weight] )

    +

    + Accumula i dati nella regione 'incoming' del [page:PropertyMixer.buffer buffer][accuIndex] in 'accu[i]'.
    + + Se weight è `0` non fa nulla. +

    + +

    [method:undefined accumulateAdditive]( [param:Number weight] )

    +

    + Accumula i dati nella regione 'incoming' in 'add'.
    + + Se weight è `0` non fa nulla. +

    + + +

    [method:undefined apply]( [param:Number accuIndex] )

    +

    + Applica lo stato del [page:PropertyMixer.buffer buffer] 'accu[i]' al binding quando gli 'accus' differiscono. +

    + +

    [method:undefined saveOriginalState]( )

    +

    + Ricorda lo stato della proprietà vincolata e lo copia in entrambi gli 'accus'. +

    + +

    [method:undefined restoreOriginalState]( )

    +

    + Applica lo stato preso precedentemente tramite 'saveOriginalState' al binding. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/animation/tracks/BooleanKeyframeTrack.html b/docs/api/it/animation/tracks/BooleanKeyframeTrack.html new file mode 100644 index 00000000000000..ce3978dbbe3f09 --- /dev/null +++ b/docs/api/it/animation/tracks/BooleanKeyframeTrack.html @@ -0,0 +1,79 @@ + + + + + + + + + + + [page:KeyframeTrack] → + +

    [name]

    + +

    + Una traccia di valori booleani dei keyframe. +

    + + +

    Costruttore

    + + +

    [name]( [param:String name], [param:Array times], [param:Array values] )

    +

    + [page:String name] - (obbligatorio) identificativo per il KeyframeTrack.
    + [page:Array times] - (obbligatorio) array di tempi del keyframe.
    + [page:Array values] - valori per i keyframe ai tempi specificati.
    +

    + + +

    Proprietà

    + + +

    + Vedi [page:KeyframeTrack] per le proprietà ereditate. +

    + +

    [property:Constant DefaultInterpolation]

    +

    + Il tipo di interpolazione predefinito da utilizzare, [page:Animation InterpolateDiscrete]. +

    + +

    [property:Array ValueBufferType]

    +

    + Un Array normale (non un Float32Array in questo caso, diversamente da `ValueBufferType` di [page:KeyframeTrack]). +

    + +

    [property:String ValueTypeName]

    +

    + String 'bool'. +

    + + +

    Metodi

    + + +

    + Vedi [page:KeyframeTrack] per i metodi ereditati. +

    + +

    [method:undefined InterpolantFactoryMethodLinear ]()

    +

    + Il valore di questo metodo è 'undefined', poiché non ha senso per le proprietà discrete. +

    + +

    [method:undefined InterpolantFactoryMethodSmooth ]()

    +

    + Il valore di questo metodo è 'undefined', poiché non ha senso per le proprietà discrete. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/animation/tracks/ColorKeyframeTrack.html b/docs/api/it/animation/tracks/ColorKeyframeTrack.html new file mode 100644 index 00000000000000..4f07c674c9e234 --- /dev/null +++ b/docs/api/it/animation/tracks/ColorKeyframeTrack.html @@ -0,0 +1,63 @@ + + + + + + + + + + + [page:KeyframeTrack] → + +

    [name]

    + +

    + Una traccia di valori keyframe che rappresentano i cambiamenti dei colori.

    + L'implementazione base di questa sottoclasse non ha ancora nulla di speciale. + Tuttavia questo è il posto per la parametrizzazione dello spazio colore. +

    + + +

    Costruttore

    + + +

    [name]( [param:String name], [param:Array times], [param:Array values] )

    +

    + [page:String name] - (obbligatorio) identificativo per il KeyframeTrack.
    + [page:Array times] - (obbligatorio) array di tempi del keyframe.
    + [page:Array values] - valori per i keyframe ai tempi specificati, un array flat di componenti colore tra 0 e 1.
    + [page:Constant interpolation] - il tipo di interpolazione da usare. Vedi + [page:Animation Animation Constants] per i possibili valori. Il valore di default è + [page:Animation InterpolateLinear]. +

    + + +

    Proprietà

    + + +

    + Vedi [page:KeyframeTrack] per le proprietà ereditate. +

    + +

    [property:String ValueTypeName]

    +

    + String 'color'. +

    + + +

    Metodi

    + + +

    + Vedi [page:KeyframeTrack] per i metodi ereditati. +

    + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/animation/tracks/NumberKeyframeTrack.html b/docs/api/it/animation/tracks/NumberKeyframeTrack.html new file mode 100644 index 00000000000000..0c37fc6bdabaea --- /dev/null +++ b/docs/api/it/animation/tracks/NumberKeyframeTrack.html @@ -0,0 +1,63 @@ + + + + + + + + + + + [page:KeyframeTrack] → + +

    [name]

    + +

    + Una traccia di valori numerici di keyframe. +

    + + +

    Costruttore

    + + +

    [name]( [param:String name], [param:Array times], [param:Array values] )

    +

    + [page:String name] - (obbligatorio) identificativo per il KeyframeTrack.
    + [page:Array times] - (obbligatorio) array di tempi del keyframe.
    + [page:Array values] - valori per i keyframe ai tempi specificati.
    + [page:Constant interpolation] - il tipo di interpolazione da usare. Vedi + [page:Animation Animation Constants] per i valori possibili. Il valore di default è + [page:Animation InterpolateLinear]. +

    + + +

    Proprietà

    + + +

    + Vedi [page:KeyframeTrack] per le proprietà ereditate. +

    + + +

    [property:String ValueTypeName]

    +

    + String 'number'. +

    + + +

    Metodi

    + + +

    + Vedi [page:KeyframeTrack] per i metodi ereditati. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/animation/tracks/QuaternionKeyframeTrack.html b/docs/api/it/animation/tracks/QuaternionKeyframeTrack.html new file mode 100644 index 00000000000000..52590c4d670076 --- /dev/null +++ b/docs/api/it/animation/tracks/QuaternionKeyframeTrack.html @@ -0,0 +1,74 @@ + + + + + + + + + + + [page:KeyframeTrack] → + +

    [name]

    + +

    + Una traccia di valori di quaternioni di keyframe. +

    + + +

    Costruttore

    + + +

    [name]( [param:String name], [param:Array times], [param:Array values] )

    +

    + [page:String name] - (obbligatorio) identificativo per il KeyframeTrack.
    + [page:Array times] - (obbligatorio) array di tempi del keyframe.
    + [page:Array values] - valori per i keyframe ai tempi specificati, un array flat di componenti di quaternioni.
    + [page:Constant interpolation] - il tipo di interpolazione da usare. Vedi + [page:Animation Animation Constants] per i valori possibili. Il valore di default è + [page:Animation InterpolateLinear]. +

    + + +

    Proprietà

    + + +

    + Vedi [page:KeyframeTrack] per le proprietà ereditate. +

    + +

    [property:Constant DefaultInterpolation]

    +

    + Il tipo di interpolazione di default da utilizzare, [page:Animation InterpolateLinear]. +

    + +

    [property:String ValueTypeName]

    +

    + String 'quaternion'. +

    + + +

    Metodi

    + + +

    + Vedi [page:KeyframeTrack] per i metodi ereditati. +

    + +

    [method:QuaternionLinearInterpolant InterpolantFactoryMethodLinear]()

    +

    + Restituisce un nuovo [page:QuaternionLinearInterpolant QuaternionLinearInterpolant] basato sui + [page:KeyframeTrack.values values], sui [page:KeyframeTrack.times times] e sul + [page:KeyframeTrack.valueSize valueSize] dei keyframe. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/animation/tracks/StringKeyframeTrack.html b/docs/api/it/animation/tracks/StringKeyframeTrack.html new file mode 100644 index 00000000000000..5764f568d0de11 --- /dev/null +++ b/docs/api/it/animation/tracks/StringKeyframeTrack.html @@ -0,0 +1,82 @@ + + + + + + + + + + + [page:KeyframeTrack] → + +

    [name]

    + +

    + Una traccia di valori di string di keyframe. +

    + + +

    Costruttore

    + + +

    [name]( [param:String name], [param:Array times], [param:Array values] )

    +

    + [page:String name] - (obbligatorio) identificativo per il KeyframeTrack.
    + [page:Array times] - (obbligatorio) array di tempi del keyframe.
    + [page:Array values] - valori per i keyframe ai tempi specificati.
    + [page:Constant interpolation] - il tipo di interpolazione da usare. Vedi + [page:Animation Animation Constants] per i valori possibili. Il valore di default è + [page:Animation InterpolateDiscrete]. +

    + + +

    Proprietà

    + + +

    + Vedi [page:KeyframeTrack] per le proprietà ereditate. +

    + +

    [property:Constant DefaultInterpolation]

    +

    + Il tipo di interpolazione di default da utilizzare, [page:Animation InterpolateDiscrete]. +

    + +

    [property:Array ValueBufferType]

    +

    + Un Array normale (non un Float32Array in questo caso, diversamente da ValueBufferType di [page:KeyframeTrack]). +

    + +

    [property:String ValueTypeName]

    +

    + String 'string'. +

    + + +

    Metodi

    + + +

    + Vedi [page:KeyframeTrack] per i metodi ereditati. +

    + +

    [method:undefined InterpolantFactoryMethodLinear]()

    +

    + Il valore di questo metodo è 'undefined', poiché non ha senso per le proprietà discrete. +

    + +

    [method:undefined InterpolantFactoryMethodSmooth]()

    +

    + Il valore di questo metodo è 'undefined', poiché non ha senso per le proprietà discrete. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/animation/tracks/VectorKeyframeTrack.html b/docs/api/it/animation/tracks/VectorKeyframeTrack.html new file mode 100644 index 00000000000000..837948bccfe452 --- /dev/null +++ b/docs/api/it/animation/tracks/VectorKeyframeTrack.html @@ -0,0 +1,62 @@ + + + + + + + + + + + [page:KeyframeTrack] → + +

    [name]

    + +

    + Una traccia di valori vettoriali di keyframe. +

    + + +

    Costruttore

    + + +

    [name]( [param:String name], [param:Array times], [param:Array values] )

    +

    + [page:String name] - (obbligatorio) identificativo per il KeyframeTrack.
    + [page:Array times] - (obbligatorio) array di tempi del keyframe.
    + [page:Array values] - valori per i keyframe ai tempi specificati, un array flat di componenti di vettori.
    + [page:Constant interpolation] - il tipo di interpolazione da usare. Vedi + [page:Animation Animation Constants] per i valori possibili. Il valore di default è + [page:Animation InterpolateLinear]. +

    + + +

    Proprietà

    + + +

    + Vedi [page:KeyframeTrack] per le proprietà ereditate. +

    + +

    [property:String ValueTypeName]

    +

    + String 'vector'. +

    + + +

    Metodi

    + + +

    + Vedi [page:KeyframeTrack] per i metodi ereditati. +

    + + +

    Source

    + + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/audio/Audio.html b/docs/api/it/audio/Audio.html new file mode 100644 index 00000000000000..883ad06d819b66 --- /dev/null +++ b/docs/api/it/audio/Audio.html @@ -0,0 +1,267 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + Crea un oggetto audio non posizionale (globale).

    + + Utilizza le [link:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API API Web Audio]. +

    + +

    Codice di Esempio

    + + + // crea un AudioListener e aggiungilo alla camera + const listener = new THREE.AudioListener(); + camera.add( listener ); + + // crea una sorgente audio globale + const sound = new THREE.Audio( listener ); + + // carica un suono e impostalo come buffer dell'oggetto audio + const audioLoader = new THREE.AudioLoader(); + audioLoader.load( 'sounds/ambient.ogg', function( buffer ) { + sound.setBuffer( buffer ); + sound.setLoop( true ); + sound.setVolume( 0.5 ); + sound.play(); + }); + + +

    Esempi

    + +

    + [example:webaudio_sandbox webaudio / sandbox ]
    + [example:webaudio_visualizer webaudio / visualizer ] +

    + +

    Costruttore

    + + +

    [name]( [param:AudioListener listener] )

    +

    + listener — (obbligatorio) istanza [page:AudioListener AudioListener]. +

    + + +

    Proprietà

    + +

    [property:Boolean autoplay]

    +

    Indica se avviare la riproduzione automaticamente. Il valore predefinito è `false`.

    + +

    [property:AudioContext context]

    +

    L'[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext] del [page:AudioListener listener] passato nel costruttore.

    + +

    [property:Number detune]

    +

    Modifica l'intonazione, misurata in centesimi. +/- 100 è un semitono. +/- 1200 è un'ottava. Il valore predefinito è `0`.

    + +

    [property:Array filters]

    +

    + Rappresenta un'array di [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode]. Può essere usato per applicare una varietà di + filtri low-order per creare effetti sonori più complessi. In molti casi, l'array contiene istanze di + [link:https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode BiquadFilterNode]. I filtri sono impostati tramite + [page:Audio.setFilter] o [page:Audio.setFilters]. +

    + +

    [property:GainNode gain]

    +

    + Un [link:https://developer.mozilla.org/en-US/docs/Web/API/GainNode GainNode] creato usando + [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createGain AudioContext.createGain](). +

    + +

    [property:Boolean hasPlaybackControl]

    +

    + Indica se la riproduzione può essere controllata usando i metodi [page:Audio.play play](), + [page:Audio.pause pause]() etc. Il valore di default è `true`. +

    + +

    [property:Boolean isPlaying]

    +

    Indica se l'audio è attualmente in riproduzione.

    + +

    [property:AudioListener listener]

    +

    Un riferimento all'oggetto listener di questo audio.

    + +

    [property:Number playbackRate]

    +

    Velocità di riproduzione. Il valore predefinito è `1`.

    + +

    [property:Number offset]

    +

    + Un offset al momento in cui deve iniziare la riproduzione all'interno del buffer audio. + È uguale al parametro audio di [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start](). + Il valore predefinito è `0`. +

    + +

    [property:Number duration]

    +

    + Sovrascrive la durata dell'audio. È uguale al parametro `duration` di + [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start](). + Il valore predefinito è `undefined` per riprodurre l'intero buffer. +

    + +

    [property:String source]

    +

    + Un [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode AudioBufferSourceNode] creato + usando [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createBufferSource AudioContext.createBufferSource](). +

    + +

    [property:String sourceType]

    +

    Il tipo di sorgente audio. Il valore predefinito è la stringa 'empty'.

    + +

    [property:String type]

    +

    Stringa che denota il tipo, impostato ad 'Audio'.

    + + +

    Metodi

    + +

    [method:this connect]()

    +

    + Permette di collegarsi all'[page:Audio.source]. Questo metodo viene utilizzato internamente + durante l'inizializzazione e durante l'impostazione/eliminazione dei filtri. +

    + +

    [method:this disconnect]()

    +

    + Permette di scollegarsi dall'[page:Audio.source]. Questo metodo viene utilizzato internamente + durante l'impostazione/eliminazione dei filtri. +

    + +

    [method:Float getDetune]()

    +

    + Restituisce il detuning dell'oscillazione in centesimi. +

    + +

    [method:BiquadFilterNode getFilter]()

    +

    + Restituisce il primo elemento dell'array [page:Audio.filters filters]. +

    + +

    [method:Array getFilters]()

    +

    + Restituisce l'array [page:Audio.filters filters]. +

    + +

    [method:Boolean getLoop]()

    +

    + Restituisce il valore di [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loop source.loop] + (se la riproduzione deve essere ripetuta). +

    + +

    [method:GainNode getOutput]()

    +

    + Restituisce il [page:Audio.gain gainNode]. +

    + +

    [method:Float getPlaybackRate]()

    +

    + Restituisce il valore di [page:Audio.playbackRate playbackRate]. +

    + +

    [method:Float getVolume]( value )

    +

    + Restituisce il volume corrente. +

    + +

    [method:this play]( delay )

    +

    + Se [page:Audio.hasPlaybackControl hasPlaybackControl] è impostato a true, inizia la riproduzione. +

    + +

    [method:this pause]()

    +

    + Se [page:Audio.hasPlaybackControl hasPlaybackControl] è impostato a true, mette in pausa la riproduzione. +

    + +

    [method:undefined onEnded]()

    +

    + Viene chiamato automaticamente quando la riproduzione termina. +

    + +

    [method:this setBuffer]( audioBuffer )

    +

    + Imposta la [page:Audio.source sorgente] su audioBuffer, e imposta il [page:Audio.sourceType sourceType] a 'buffer'.
    + Se la riproduzione è in [page:Audio.autoplay autoplay], avvia anche la riproduzione. +

    + +

    [method:this setDetune]( [param:Float value] )

    +

    + Definisce il detuning dell'oscillazione in centesimi. +

    + +

    [method:this setFilter]( filter )

    +

    + Applica un singolo filtro all'audio. +

    + +

    [method:this setFilters]( [param:Array value] )

    +

    + value - array di filtri.
    + Applica un array di filtri all'audio. +

    + +

    [method:this setLoop]( [param:Boolean value] )

    +

    + Imposta [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loop source.loop] a `value` + (se la riproduzione deve andare in loop). +

    + +

    [method:this setLoopStart]( [param:Float value] )

    +

    + Imposta [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopStart source.loopStart] a `value`. +

    + +

    [method:this setLoopEnd]( [param:Float value] )

    +

    + Imposta [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopEnd source.loopEnd] a `value`. +

    + +

    [method:this setMediaElementSource]( mediaElement )

    +

    + Applica l'oggetto passato come parametro, di tipo [link:https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement HTMLMediaElement], + come sorgente di questo audio.
    + Inoltre imposta [page:Audio.hasPlaybackControl hasPlaybackControl] a false. +

    + +

    [method:this setMediaStreamSource]( mediaStream )

    +

    + Applica l'oggetto passato come parametro, di tipo [link:https://developer.mozilla.org/en-US/docs/Web/API/MediaStream MediaStream], + come sorgente di questo audio.
    + Inoltre imposta [page:Audio.hasPlaybackControl hasPlaybackControl] a false. +

    + +

    [method:this setNodeSource]( audioNode )

    +

    + Imposta la [page:Audio.source sorgente] dell'audioBuffer, e imposta [page:Audio.sourceType sourceType] a 'audioNode'.
    + Inoltre imposta [page:Audio.hasPlaybackControl hasPlaybackControl] a false. +

    + +

    [method:this setPlaybackRate]( [param:Float value] )

    +

    + Se [page:Audio.hasPlaybackControl hasPlaybackControl] è abilitato, imposta il [page:Audio.playbackRate playbackRate] a `value`. +

    + +

    [method:this setVolume]( [param:Float value] )

    +

    + Imposta il volume. +

    + +

    [method:this stop]()

    +

    + Se [page:Audio.hasPlaybackControl hasPlaybackControl] è abilitato, ferma la riproduzione. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/audio/AudioAnalyser.html b/docs/api/it/audio/AudioAnalyser.html new file mode 100644 index 00000000000000..908c0b0e799e36 --- /dev/null +++ b/docs/api/it/audio/AudioAnalyser.html @@ -0,0 +1,98 @@ + + + + + + + + + +

    [name]

    + +

    + Crea un oggetto AudioAnalyser, che utilizza un [link:https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode AnalyserNode] + per analizzare l'audio.

    + + Utilizza le [link:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API API Web Audio]. +

    + +

    Codice di Esempio

    + + + // crea un AudioListener e aggiungilo alla camera + const listener = new THREE.AudioListener(); + camera.add( listener ); + + // crea una sorgente Audio + const sound = new THREE.Audio( listener ); + + // carica un suono e impostalo come buffer dell'oggetto Audio + const audioLoader = new THREE.AudioLoader(); + audioLoader.load( 'sounds/ambient.ogg', function( buffer ) { + sound.setBuffer( buffer ); + sound.setLoop(true); + sound.setVolume(0.5); + sound.play(); + }); + + // crea un AudioAnalyser, passando il suono e la fftSize desiderata + const analyser = new THREE.AudioAnalyser( sound, 32 ); + + // ottieni la frequenza media del suono + const data = analyser.getAverageFrequency(); + + +

    Esempi

    + +

    + [example:webaudio_sandbox webaudio / sandbox ]
    + [example:webaudio_visualizer webaudio / visualizer ] +

    + +

    Costruttore

    + + +

    [name]( audio, [link:https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/fftSize fftSize] )

    +

    + Crea un nuovo [page:AudioAnalyser AudioAnalyser]. +

    + + +

    Proprietà

    + +

    [property:AnalyserNode analyser]

    +

    Un [link:https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode AnalyserNode] usato per analizzare l'audio.

    + +

    [property:Integer fftSize]

    +

    + Una potenza di due, non nulla, fino a 2048, che rappresenta la dimensione della FFT (Fast Fourier Transform) da utilizzare per determinare + il dominio della frequenza. Vedi [link:https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/fftSize questa pagina] per maggiori dettagli. +

    + +

    [property:Uint8Array data]

    +

    + Un Uint8Array con dimensione determinata da [link:https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/frequencyBinCount analyser.frequencyBinCount], + usata per contenere i dati di analisi. +

    + + +

    Metodi

    + + +

    [method:Uint8Array getFrequencyData]()

    +

    + Utilizza il metodo [link:https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getByteFrequencyData getByteFrequencyData] delle API Web Audio. +

    + +

    [method:Number getAverageFrequency]()

    +

    + Ottieni la media della frequenza restituita dal metodo [page:AudioAnalyser.getFrequencyData getFrequencyData]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/audio/AudioContext.html b/docs/api/it/audio/AudioContext.html new file mode 100644 index 00000000000000..8aafbdee21b1a9 --- /dev/null +++ b/docs/api/it/audio/AudioContext.html @@ -0,0 +1,43 @@ + + + + + + + + + + +

    [name]

    + +

    + Contiene i metodi per impostare un [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext].

    + + Usato internamente dalle classi [page:AudioListener AudioListener] e [page:AudioLoader AudioLoader].

    + + Utilizza le [link:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API API Web Audio]. +

    + + + +

    Metodi

    + +

    [method:AudioContext getContext]()

    +

    + Restituisce il valore della variabile `context` nell'ambito esterno, se definito, + altrimenti lo imposta in un nuovo [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext]. +

    + +

    [method:AudioContext setContext]( [param:AudioContext value] )

    +

    + Imposta la varibile `context` nell'ambito esterno su `value`. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/audio/AudioListener.html b/docs/api/it/audio/AudioListener.html new file mode 100644 index 00000000000000..04edb204bec0d2 --- /dev/null +++ b/docs/api/it/audio/AudioListener.html @@ -0,0 +1,123 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + L'[name] rappresenta un [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioListener listener] virtuale di tutti + gli effetti audio posizionli e non posizionali nella scena.
    + Un'applicazione three.js di solito crea una singola istanza di [name]. È un parametro obbligatorio nel costruttore di + entità audio come [page:Audio Audio] e [page:PositionalAudio PositionalAudio].
    + In molti casi, l'oggetto listener è un figlio della camera. Quindi la trasformazione 3D della camera rappresenta + la trasformazione 3D del listener. +

    + +

    Codice di Esempio

    + + + // crea un AudioListener e aggiungilo alla camera + const listener = new THREE.AudioListener(); + camera.add( listener ); + + // crea una sorgente audio globale + const sound = new THREE.Audio( listener ); + + // carica un suono e impostalo come buffer dell'oggetto Audio + const audioLoader = new THREE.AudioLoader(); + audioLoader.load( 'sounds/ambient.ogg', function( buffer ) { + sound.setBuffer( buffer ); + sound.setLoop(true); + sound.setVolume(0.5); + sound.play(); + }); + + +

    Esempi

    + +

    + [example:webaudio_sandbox webaudio / sandbox ]
    + [example:webaudio_timing webaudio / timing ]
    + [example:webaudio_visualizer webaudio / visualizer ] +

    + +

    Costruttore

    + + +

    [name]( )

    +

    + Crea un nuovo AudioListener. +

    + + +

    Proprietà

    + +

    [property:AudioContext context]

    +

    + L'[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext] del [page:AudioListener listener] passato nel costruttore. +

    + +

    [property:GainNode gain]

    +

    + Un [link:https://developer.mozilla.org/en-US/docs/Web/API/GainNode GainNode] creato + usando [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createGain AudioContext.createGain](). +

    + +

    [property:AudioNode filter]

    +

    Il valore predefinito è `null`.

    + +

    [property:Number timeDelta]

    +

    + Valore delta temporale delle entità audio. Usato nel contesto di + [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/linearRampToValueAtTime AudioParam.linearRampToValueAtTimeDefault](). + Il valore di default è `0`. +

    + +

    Metodi

    + + +

    [method:GainNode getInput]()

    +

    + Restituisce il [page:AudioListener.gain gainNode]. +

    + +

    [method:this removeFilter]()

    +

    + Imposta la proprietà [page:AudioListener.filter filter] a `null`. +

    + +

    [method:AudioNode getFilter]()

    +

    + Restituisce il valore della proprietà [page:AudioListener.filter filter]. +

    + +

    [method:this setFilter]( [param:AudioNode value] )

    +

    + Imposta la proprietà [page:AudioListener.filter filter] a `value`. +

    + +

    [method:Float getMasterVolume]()

    +

    + Restituisce il volume. +

    + +

    [method:this setMasterVolume]( [param:Number value] )

    +

    + Imposta il volume. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/audio/PositionalAudio.html b/docs/api/it/audio/PositionalAudio.html new file mode 100644 index 00000000000000..0839f488eba8a6 --- /dev/null +++ b/docs/api/it/audio/PositionalAudio.html @@ -0,0 +1,138 @@ + + + + + + + + + + [page:Object3D] → [page:Audio] → + +

    [name]

    + +

    + Crea un oggetto audio posizionale.

    + + Utilizza le [link:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API API Web Audio]. +

    + +

    Codice di Esempio

    + + + // crea un AudioListener e lo aggiunge alla camera + const listener = new THREE.AudioListener(); + camera.add( listener ); + + // crea l'oggetto PositionalAudio (passandogli il listener) + const sound = new THREE.PositionalAudio( listener ); + + // carica un suono e lo imposta come buffer dell'oggetto PositionalAudio + const audioLoader = new THREE.AudioLoader(); + audioLoader.load( 'sounds/song.ogg', function( buffer ) { + sound.setBuffer( buffer ); + sound.setRefDistance( 20 ); + sound.play(); + }); + + // crea un oggetto da cui riprodurre il suono + const sphere = new THREE.SphereGeometry( 20, 32, 16 ); + const material = new THREE.MeshPhongMaterial( { color: 0xff2200 } ); + const mesh = new THREE.Mesh( sphere, material ); + scene.add( mesh ); + + // infine aggiunge il suono alla mesh + mesh.add( sound ); + + +

    Esempi

    + +

    + [example:webaudio_orientation webaudio / orientation ]
    + [example:webaudio_sandbox webaudio / sandbox ]
    + [example:webaudio_timing webaudio / timing ] +

    + +

    Costruttore

    + +

    [name]( [param:AudioListener listener] )

    +

    + listener — (obbligatorio) istanza di [page:AudioListener AudioListener]. +

    + + +

    Proprietà

    + +

    + Vedi la classe [page:Audio Audio] per le proprietà ereditate. +

    + +

    [property:PannerNode panner]

    +

    + Il [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode PannerNode] di PositionalAudio. +

    + + +

    Metodi

    + +

    + Vedi la classe [page:Audio Audio] per i metodi ereditati. +

    + +

    [method:PannerNode getOutput]()

    +

    + Restituisce il [page:PositionalAudio.panner panner]. +

    + +

    [method:Float getRefDistance]()

    +

    + Restisuice il valore di [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/refDistance panner.refDistance]. +

    + +

    [method:this setRefDistance]( [param:Float value] )

    +

    + Imposta il valore di [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/refDistance panner.refDistance]. +

    + +

    [method:Float getRolloffFactor]()

    +

    + Restisuice il valore di [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/rolloffFactor panner.rolloffFactor]. +

    + +

    [method:this setRolloffFactor]( [param:Float value] )

    +

    + Imposta il valore di [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/rolloffFactor panner.rolloffFactor]. +

    + +

    [method:String getDistanceModel]()

    +

    + Restisuice il valore di [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/distanceModel panner.distanceModel]. +

    + +

    [method:this setDistanceModel]( [param:String value] )

    +

    + Imposta il valore di [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/distanceModel panner.distanceModel]. +

    + +

    [method:Float getMaxDistance]()

    +

    + Restisuice il valore di [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/maxDistance panner.maxDistance]. +

    + +

    [method:this setMaxDistance]( [param:Float value] )

    +

    + Imposta il valore di [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/maxDistance panner.maxDistance]. +

    + +

    [method:this setDirectionalCone]( [param:Float coneInnerAngle], [param:Float coneOuterAngle], [param:Float coneOuterGain] )

    +

    + Questo metodo può essere usato per trasformare un suono omnidirezionale in un [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode suono direzionale]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/cameras/ArrayCamera.html b/docs/api/it/cameras/ArrayCamera.html new file mode 100644 index 00000000000000..8d8af654e99964 --- /dev/null +++ b/docs/api/it/cameras/ArrayCamera.html @@ -0,0 +1,55 @@ + + + + + + + + + + [page:Object3D] → [page:Camera] → [page:PerspectiveCamera] → + +

    [name]

    + +

    + [name] può essere usato per renderizzare in modo efficiente una scena con un set predefinito di telecamere. + Questo è un aspetto importante delle prestazioni per il rendering delle scene VR.
    + Un'istanza di [name] ha sempre un array di telecamere secondarie. È obbligatorio definire per ogni telecamera secondaria la + proprietà `viewport` la quale determina la parte della finestra (viewport) che viene renderizzata con questa telecamera. +

    + +

    Esempi

    + +

    [example:webgl_camera_array camera / array ]

    + +

    Costruttore

    + +

    [name]( [param:Array array] )

    +

    + Un array di telecamere. +

    + + +

    Proprietà

    +

    Vedi la classe base [page:PerspectiveCamera] per le proprietà comuni.

    + +

    [property:Array cameras]

    +

    + Un array di telecamere. +

    + +

    [property:Boolean isArrayCamera]

    +

    + Flag di sola lettura per verificare se un dato oggetto è di tipo [name]. +

    + +

    Metodi

    +

    Vedi la classe base [page:PerspectiveCamera] per i metodi comuni

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/cameras/Camera.html b/docs/api/it/cameras/Camera.html new file mode 100644 index 00000000000000..47a912e245b75f --- /dev/null +++ b/docs/api/it/cameras/Camera.html @@ -0,0 +1,86 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + Classe base astratta per telecamere. Questa classe dovrebbe essere sempre ereditata quando costruisci una nuova telecamera. +

    + + +

    Costruttore

    + + +

    [name]()

    +

    + Crea una nuova [name]. Si noti che questa classe non intende essere chiamata direttamente; + invece, probabilmente vuoi utilizzare una [page:PerspectiveCamera] o una [page:OrthographicCamera]. +

    + + +

    Proprietà

    +

    Vedi la classe base [page:Object3D] per le proprietà comuni.

    + +

    [property:Boolean isCamera]

    +

    + Flag di sola lettura per verificare se un dato oggetto è di tipo [name]. +

    + +

    [property:Layers layers]

    +

    + I [page:Layers layers] di cui la telecamera è parte. Questa è una proprietà ereditata da + [page:Object3D].

    + + Gli oggetti devono condividere almeno un layer con la telecamera per essere visualizzati + quando il viewport della telecamera viene renderizzato. +

    + +

    [property:Matrix4 matrixWorldInverse]

    +

    + Questo è l'inverso di matrixWorld. MatrixWorld contiene la Matrix che contiene + la trasformazione del mondo della telecamera. +

    + +

    [property:Matrix4 projectionMatrix]

    +

    Questa è la matrice che contiene la proiezione (projection).

    + +

    [property:Matrix4 projectionMatrixInverse]

    +

    L'inverso di projectionMatrix.

    + + +

    Metodi

    +

    Vedi la classe base [page:Object3D] per i metodi comuni.

    + +

    [method:Camera clone]( )

    +

    + Restituisce una nuova telecamera con le stesse proprietà di questa. +

    + +

    [method:this copy]( [param:Camera source], [param:Boolean recursive] )

    +

    + Copia le proprietà della telecamera source in questa. +

    + +

    [method:Vector3 getWorldDirection]( [param:Vector3 target] )

    +

    + [page:Vector3 target] — il risultato sarà copiato in questo Vector3.

    + + Restituisce un [page:Vector3] che rappresenta la direzione dello spazio del world in + cui la telecamera sta guardando. (Nota: Una telecamera guarda verso il basso sul suo asse z locale, negativo).

    +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/cameras/CubeCamera.html b/docs/api/it/cameras/CubeCamera.html new file mode 100644 index 00000000000000..02cda37cbcd50c --- /dev/null +++ b/docs/api/it/cameras/CubeCamera.html @@ -0,0 +1,88 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    Crea 6 telecamere che eseguono il rendering su un [page:WebGLCubeRenderTarget].

    + +

    Codice di Esempio

    + + + // Crea una destinazione di rendering del cubo + const cubeRenderTarget = new THREE.WebGLCubeRenderTarget( 128, { generateMipmaps: true, minFilter: THREE.LinearMipmapLinearFilter } ); + + // Crea una cube camera + const cubeCamera = new THREE.CubeCamera( 1, 100000, cubeRenderTarget ); + scene.add( cubeCamera ); + + // Crea una macchina + const chromeMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: cubeRenderTarget.texture } ); + const car = new THREE.Mesh( carGeometry, chromeMaterial ); + scene.add( car ); + + // Aggiorna il cube di destinazione del rendering + car.visible = false; + cubeCamera.position.copy( car.position ); + cubeCamera.update( renderer, scene ); + + // Renderizza la scena + car.visible = true; + renderer.render( scene, camera ); + + +

    Esempi

    + +

    + [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ] +

    + +

    Costruttore

    + + +

    [name]( [param:Number near], [param:Number far], [param:WebGLCubeRenderTarget renderTarget] )

    +

    + near - La distanza vicina (near) di ritaglio.
    + far - La distanza lontana (far) di ritaglio.
    + renderTarget - La destinazione di rendering del target cube. +

    + +

    + Costruisce una CubeCamera che contiene 6 [page:PerspectiveCamera PerspectiveCamera] che eseguono + il rendering su un [page:WebGLCubeRenderTarget]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Object3D] per le proprietà comuni.

    + +

    [property:WebGLCubeRenderTarget renderTarget]

    +

    + La destinazione di rendering del target cube. +

    + +

    Metodi

    +

    Vedi la classe base [page:Object3D] per i metodi comuni.

    + +

    [method:undefined update]( [param:WebGLRenderer renderer], [param:Scene scene] )

    +

    + renderer - L'attuale renderer WebGL
    + scene - La scena attuale +

    +

    + Chiama questo metodo per aggiornare il [page:CubeCamera.renderTarget renderTarget]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/cameras/OrthographicCamera.html b/docs/api/it/cameras/OrthographicCamera.html new file mode 100644 index 00000000000000..c57542a7b7e104 --- /dev/null +++ b/docs/api/it/cameras/OrthographicCamera.html @@ -0,0 +1,146 @@ + + + + + + + + + + [page:Object3D] → [page:Camera] → + +

    [name]

    + +

    + Telecamera che utilizza la [link:https://en.wikipedia.org/wiki/Orthographic_projection proiezione ortografica].

    + + In questa modalità di proiezione, la dimensione di un oggetto nell'immagine visualizzata rimane costante indipendentemente + dalla sua distanza dalla telecamera.

    + + Questa telecamera, tra le altre cose, può essere utile per il rendering di scene 2D ed elementi della UI. +

    + +

    Codice di Esempio

    + + + const camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 ); + scene.add( camera ); + + +

    Esempi

    + +

    + [example:webgl_camera camera ]
    + [example:webgl_interactive_cubes_ortho interactive / cubes / ortho ]
    + [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]
    + [example:webgl_postprocessing_advanced postprocessing / advanced ]
    + [example:webgl_postprocessing_dof2 postprocessing / dof2 ]
    + [example:webgl_postprocessing_godrays postprocessing / godrays ]
    + [example:webgl_rtt rtt ]
    + [example:webgl_shaders_tonemapping shaders / tonemapping ]
    + [example:webgl_shadowmap shadowmap ] +

    + +

    Costruttore

    + + +

    [name]( [param:Number left], [param:Number right], [param:Number top], [param:Number bottom], [param:Number near], [param:Number far] )

    +

    + left — Piano sinistro del frustum della telecamera.
    + right — Piano destro del frustum della telecamera.
    + top — Piano superiore del frustum della telecamera.
    + bottom — Piano inferiore del frustum della telecamera.
    + near — Piano near del frustum della telecamera.
    + far — Piano far del frustum della telecamera.

    + + Queste proprietà insieme definiscono il [link:https://en.wikipedia.org/wiki/Viewing_frustum frustum visivo] della telecamera. +

    + + +

    Proprietà

    +

    + Vedi la classe base [page:Camera] per le proprietà comuni.
    + Si noti che dopo aver apportato modifiche alla maggior parte di queste proprietà + sarà necessario chiamare il metodo [page:OrthographicCamera.updateProjectionMatrix .updateProjectionMatrix] + affinché le modifiche abbiano effetto. +

    + +

    [property:Float bottom]

    +

    Piano inferiore del frustum della telecamera.

    + +

    [property:Float far]

    +

    + Piano far del frustum della telecamera. Il valore predefinito è `2000`.

    + + Deve essere maggiore del valore corrente del piano [page:.near near]. +

    + +

    [property:Boolean isOrthographicCamera]

    +

    + Flag di sola lettura per verificare se un dato oggetto è di tipo [name]. +

    + +

    [property:Float left]

    +

    Piano sinistro del frustum della telecamera.

    + +

    [property:Float near]

    +

    + Piano near del frustum della telecamera. Il valore predefinito è `0.1`.

    + + L'intervallo valido è tra `0` e il valore corrente del piano [page:.far far]. + Si noti che, diversamente dalla [page:PerspectiveCamera], `0` è un valore valido + per il piano near della OrthographicCamera. +

    + +

    [property:Float right]

    +

    Piano destro del frustum della telecamera.

    + +

    [property:Float top]

    +

    Piano superiore del frustum della telecamera.

    + +

    [property:Object view]

    +

    Impostato da [page:OrthographicCamera.setViewOffset setViewOffset]. Il valore predefinito è `null`.

    + +

    [property:number zoom]

    +

    Ottiene o imposta il fattore zoom della telecamera. Il valore predefinito è `1`.

    + +

    Metodi

    +

    Vedi la classe base [page:Camera] per i metodi comuni.

    + +

    [method:undefined setViewOffset]( [param:Float fullWidth], [param:Float fullHeight], [param:Float x], [param:Float y], [param:Float width], [param:Float height] )

    +

    + fullWidth — Larghezza totale dell'impostazione multiview
    + fullHeight — Altezza totale dell'impostazione multiview
    + x — Offset orizzontale della telecamera secondaria
    + y — Offset verticale della telecamera secondaria
    + width — Larghezza della telecamera secondaria
    + height — Altezza della telecamera secondaria

    + + Imposta un offset in un [link:https://en.wikipedia.org/wiki/Viewing_frustum frustum visivo] più ampio. + È utile per le configurazioni multi-window o multi-monitor/multi-machine. + Per un esempio di utilizzo, consultare [page:PerspectiveCamera.setViewOffset PerspectiveCamera]. +

    + +

    [method:undefined clearViewOffset]()

    +

    + Rimuove qualsiasi offset impostato dal metodo .setViewOffset. +

    + +

    [method:undefined updateProjectionMatrix]()

    +

    + Aggiorna la matrice di proiezione della telecamera. Deve essere chiamato dopo ogni modifica dei parametri. +

    + +

    [method:Object toJSON]([param:Object meta])

    +

    + meta -- oggetto contenente metadati come texture o immagini nei discendenti degli oggetti.
    + Converte la fotocamera nel [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 formato JSON Object/Scene] di three.js. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/cameras/PerspectiveCamera.html b/docs/api/it/cameras/PerspectiveCamera.html new file mode 100644 index 00000000000000..fa241221f11fe2 --- /dev/null +++ b/docs/api/it/cameras/PerspectiveCamera.html @@ -0,0 +1,214 @@ + + + + + + + + + + [page:Object3D] → [page:Camera] → + +

    [name]

    + +

    + Telecamera che utilizza la [link:https://en.wikipedia.org/wiki/Perspective_(graphical) proiezione prospettica].

    + + Questa modalità di proiezione è progettata per imitare il modo in cui l'occhio umano vede. È la proiezione + più comunemente utilizzata per il rendering di una scena 3D. +

    + +

    Codice di Esempio

    + + + const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 ); + scene.add( camera ); + + +

    Esempi

    + +

    + [example:webgl_animation_skinning_blending animation / skinning / blending ]
    + [example:webgl_animation_skinning_morph animation / skinning / morph ]
    + [example:webgl_effects_stereo effects / stereo ]
    + [example:webgl_interactive_cubes interactive / cubes ]
    + [example:webgl_loader_collada_skinning loader / collada / skinning ] +

    + +

    Costruttore

    + +

    [name]( [param:Number fov], [param:Number aspect], [param:Number near], [param:Number far] )

    +

    + fov — Campo visivo verticale del frustum della telecamera.
    + aspect — Aspect ratio del frustum della telecamera.
    + near — Piano near del frustum della telecamera.
    + far — Piano far del frustum della telecamera.

    + + Queste proprietà insieme definiscono il [link:https://en.wikipedia.org/wiki/Viewing_frustum frustum visivo] della telecamera. +

    + + +

    Proprietà

    +

    + Vedi la classe base [page:Camera] per le proprietà comuni.
    + Si noti che dopo aver apportato modifiche alla maggior parte di queste proprietà + sarà necessario chiamare il metodo [page:PerspectiveCamera.updateProjectionMatrix .updateProjectionMatrix] + affinché le modifiche abbiano effetto. +

    + +

    [property:Float aspect]

    +

    + Aspect ratio del frustum della telecamera, di solito calcolato con la larghezza del canvas / l'altezza del canvas. + Il valore predefinito è `1` (canvas quadrato). +

    + +

    [property:Float far]

    +

    + Piano far del frustum della telecamera. Il valore predefinito è `2000`.

    + + Deve essere maggiore del valore corrente del piano [page:.near near]. +

    + +

    [property:Float filmGauge]

    +

    + Dimensioni della pellicola utilizzata per l'asse maggiore. Il valore predefinito è 35 (millimetri). + Questo parametro non influenza la matrice di proiezione a meno che .filmOffset non sia impostato su un valore diverso da zero. +

    + +

    [property:Float filmOffset]

    +

    Offset orizzontale decentrato nella stessa unità di `.filmGauge`. Il valore predefinito è `0`.

    + +

    [property:Float focus]

    +

    + Distanza dell'oggetto utilizzata per la stereoscopia e gli effetti di profondità di campo. + Questo parametro non influenza la matrice di proiezione a meno che non venga utilizzata una [page:StereoCamera]. + Il valore predefinito è `10`. +

    + +

    [property:Float fov]

    +

    Campo visivo verticale del frustum della telecamera, dal basso all'alto della vista, in gradi. Il valore predefinito è `50`.

    + +

    [property:Boolean isPerspectiveCamera]

    +

    + Flag di sola lettura che verifica se la telecamera è di tipo [name]. +

    + + +

    [property:Float near]

    +

    + Piano near del frustum della telecamera. Il valore predefinito è `0.1`.

    + + L'intervallo valido è tra `0` e il valore corrente del piano [page:.far far]. + Si noti che, diversamente dalla [page:OrthographicCamera], `0` non è un valore valido + per il piano near della PerspectiveCamera. +

    + +

    [property:Object view]

    +

    + Specifica la window del frustum o null. + Questo valore viene impostato utilizzando il metodo [page:PerspectiveCamera.setViewOffset .setViewOffset] + e cancellato utilizzando il metodo [page:PerspectiveCamera.clearViewOffset .clearViewOffset]. +

    + +

    [property:number zoom]

    +

    Ottiene o imposta il fattore zoom della telecamera. Il valore predefinito è `1`.

    + + +

    Metodi

    +

    Vedi la classe base [page:Camera] per i metodi comuni.

    + +

    [method:undefined clearViewOffset]()

    +

    Rimuove qualsiasi offset impostato dal metodo [page:PerspectiveCamera.setViewOffset .setViewOffset].

    + +

    [method:Float getEffectiveFOV]()

    +

    Restituisce l'angolo verticale del campo visivo corrente in gradi considerando .zoom.

    + +

    [method:Float getFilmHeight]()

    +

    + Restituisce l'altezza dell'immagine sulla pellicola. Se .aspect è minore o uguale a uno + (formato verticale), il risultato è uguale a .filmGauge. +

    + +

    [method:Float getFilmWidth]()

    +

    + Restituisce la larghezza dell'immagine sulla pellicola. Se .aspect è maggiore o uguale ad uno (formato orizzontale), + il risultato è uguale a .filmGauge. +

    + +

    [method:Float getFocalLength]()

    +

    Restituisce la lunghezza focale del .fov corrente rispetto a .filmGauge.

    + +

    [method:undefined setFocalLength]( [param:Float focalLength] )

    +

    + Imposta il valore FOV in base alla lunghezza focale rispetto al [page:PerspectiveCamera.filmGauge .filmGauge] corrente.

    + + Per impostazione predefinita, la lunghezza focale è specificata per una telecamera da 35mm (full frame). +

    + +

    [method:undefined setViewOffset]( [param:Float fullWidth], [param:Float fullHeight], [param:Float x], [param:Float y], [param:Float width], [param:Float height] )

    +

    + fullWidth — larghezza totale dell'impostazione multiview
    + fullHeight — altezza totale dell'impostazione multiview
    + x — offset orizzontale della telecamera secondaria
    + y — offset verticale della telecamera secondaria
    + width — larghezza della telecamera secondaria
    + height — altezza della telecamera secondaria

    +

    + +

    + Imposta un offset in un frustum più ampio. È utile per le configurazioni multi-window o multi-monitor/multi-machine. +

    + +

    + Per esempio, se si dispone di 3x2 monitor e ogni monitor è un 1920x1080 e i monitor sono disposti in una griglia come questa:
    + +

    ++---+---+---+
    +| A | B | C |
    ++---+---+---+
    +| D | E | F |
    ++---+---+---+
    +		
    + + allora per ogni monitor il metodo verrebbe chiamato in questo modo:
    + + 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 ); + + + Si noti che non c'è motivo per cui i monitor debbano essere della stessa dimensione o in una griglia. +

    + +

    [method:undefined updateProjectionMatrix]()

    +

    + Aggiorna la matrice di proiezione della telecamera. Deve essere chiamato dopo ogni modifica dei parametri. +

    + +

    [method:Object toJSON]([param:Object meta])

    +

    + meta -- oggetto contenente metadati come texture o immagini nei discendenti degli oggetti.
    + Converte la fotocamera nel [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 formato JSON Object/Scene] di three.js. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/cameras/StereoCamera.html b/docs/api/it/cameras/StereoCamera.html new file mode 100644 index 00000000000000..08675101a1b98b --- /dev/null +++ b/docs/api/it/cameras/StereoCamera.html @@ -0,0 +1,64 @@ + + + + + + + + + + +

    [name]

    + +

    + Doppia telecamera [page:PerspectiveCamera PerspectiveCamera] utilizzata per effetti come + [link:https://en.wikipedia.org/wiki/Anaglyph_3D 3D Anaglyph] o [link:https://en.wikipedia.org/wiki/parallax_barrier Parallax Barrier]. +

    + +

    Esempi

    + +

    + [example:webgl_effects_anaglyph effects / anaglyph ]
    + [example:webgl_effects_parallaxbarrier effects / parallaxbarrier ]
    + [example:webgl_effects_stereo effects / stereo ] +

    + +

    Costruttore

    + +

    [name]( )

    + +

    Proprietà

    + +

    [property:Float aspect]

    +

    Il valore predefinito è `1`.

    + +

    [property:Float eyeSep]

    +

    Il valore predefinito è `0.064`.

    + +

    [property:PerspectiveCamera cameraL]

    +

    + Telecamera sinistra. È aggiunta al [page:Layers layer 1] - + anche gli oggetti che devono essere renderizzati dalla telecamera di sinistra devono + essere aggiunti a questo layer. +

    + +

    [property:PerspectiveCamera cameraR]

    +

    + Telecamera destra. È aggiunta al [page:Layers layer 2] - + anche gli oggetti che devono essere renderizzati dalla telecamera di destra devono + essere aggiunti a questo layer. + +

    Metodi

    + +

    [method:undefined update]( [param:PerspectiveCamera camera] )

    +

    + Aggiorna le telecamere Stereo in base alla telecamera passata come parametro. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/constants/Animation.html b/docs/api/it/constants/Animation.html new file mode 100644 index 00000000000000..72471849748ce5 --- /dev/null +++ b/docs/api/it/constants/Animation.html @@ -0,0 +1,46 @@ + + + + + + + + + +

    Costanti di Animazione

    + +

    Modalità Loop

    + + +THREE.LoopOnce +THREE.LoopRepeat +THREE.LoopPingPong + + +

    Modalità di Interpolazione

    + +THREE.InterpolateDiscrete +THREE.InterpolateLinear +THREE.InterpolateSmooth + + +

    Modalità Ending

    + +THREE.ZeroCurvatureEnding +THREE.ZeroSlopeEnding +THREE.WrapAroundEnding + + +

    Modalità di Animation Blend

    + +THREE.NormalAnimationBlendMode +THREE.AdditiveAnimationBlendMode + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + diff --git a/docs/api/it/constants/BufferAttributeUsage.html b/docs/api/it/constants/BufferAttributeUsage.html new file mode 100644 index 00000000000000..54974effba443e --- /dev/null +++ b/docs/api/it/constants/BufferAttributeUsage.html @@ -0,0 +1,53 @@ + + + + + + + + + +

    Costanti di utilizzo degli attributi del buffer

    + +

    + Le costanti di utilizzo possono essere utilizzate per fornire un suggerimento all'API su come verrà utilizzato l'attributo + del buffer della geometria per ottimizzare le prestazioni. +

    + +

    Codice di Esempio

    + + + const geometry = new THREE.BufferGeometry(); + const positionAttribute = new THREE.BufferAttribute( array, 3 , false ); + positionAttribute.setUsage( THREE.DynamicDrawUsage ); + geometry.setAttribute( 'position', positionAttribute ); + + +

    Esempi

    +

    [example:webgl_buffergeometry_drawrange materials / buffergeometry / drawrange ]

    + +

    Utilizzo della Geometria

    + + THREE.StaticDrawUsage + THREE.DynamicDrawUsage + THREE.StreamDrawUsage + + THREE.StaticReadUsage + THREE.DynamicReadUsage + THREE.StreamReadUsage + + THREE.StaticCopyUsage + THREE.DynamicCopyUsage + THREE.StreamCopyUsage + + + Per informazioni più dettagliate su ciascuna di queste costanti consultare + [link:https://www.khronos.org/opengl/wiki/Buffer_Object#Buffer_Object_Usage questa documentazione di OpenGL]. + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + diff --git a/docs/api/it/constants/Core.html b/docs/api/it/constants/Core.html new file mode 100644 index 00000000000000..41e9da8d67930b --- /dev/null +++ b/docs/api/it/constants/Core.html @@ -0,0 +1,80 @@ + + + + + + + + + +

    Costanti del Core

    + +

    Numero di Revisione

    + + +THREE.REVISION + + +
    + L'attuale [link:https://github.com/mrdoob/three.js/releases numero di revisione] di three.js. +
    + +

    Spazi Colore

    + +THREE.NoColorSpace +THREE.SRGBColorSpace +THREE.LinearSRGBColorSpace + +

    + [page:NoColorSpace] non definisce uno spazio colore specifico. +

    +

    + [page:SRGBColorSpace] (“sRGB”) si riferisce allo spazio colore definito dal Rec. 709 + primari, punto di bianco D65 e funzioni di trasferimento sRGB non lineare. sRGB è lo spazio + colore predefinito nei CSS, e si trova spesso nelle palette dei colori e nei selettori di colore. + I colori espressi in esadecimale o in notazione CSS sono tipicamente nello spazio colore sRGB. +

    + +

    + [page:LinearSRGBColorSpace] (“Linear-sRGB”) si riferisce allo spazio colore sRGB (sopra) con + funzioni di trasferimento lineare. Linear-sRGB è lo spazio colore di lavoro in three.js, utilizzato + durante la maggior parte del processo di rendering. I componenti RGB presenti nei materiali, negli + shader in three.js si trovano nello spazio colore Linear-sRGB. +

    + +

    + Per ulteriori informazioni sul background e sull'utilizzo, consultare Gestione del colore. +

    + +

    Pulsanti del Mouse

    + +THREE.MOUSE.LEFT +THREE.MOUSE.MIDDLE +THREE.MOUSE.RIGHT +THREE.MOUSE.ROTATE +THREE.MOUSE.DOLLY +THREE.MOUSE.PAN + +

    + Le costanti LEFT e ROTATE hanno lo stesso valore di base. + Le costanti MIDDLE e DOLLY hanno lo stesso valore di base. + Le costanti RIGHT e PAN hanno lo stesso valore di base. +

    + +

    Azioni Touch

    + +THREE.TOUCH.ROTATE +THREE.TOUCH.PAN +THREE.TOUCH.DOLLY_PAN +THREE.TOUCH.DOLLY_ROTATE + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + + + diff --git a/docs/api/it/constants/CustomBlendingEquations.html b/docs/api/it/constants/CustomBlendingEquations.html new file mode 100644 index 00000000000000..1d4eac7b6c338f --- /dev/null +++ b/docs/api/it/constants/CustomBlendingEquations.html @@ -0,0 +1,66 @@ + + + + + + + + + +

    Costanti di equazioni di blending personalizzate

    + +

    + Funzionano con tutti i tipi di materiale. Impostare prima la modalità blending del materiale + su THREE.CustomBlending, poi impostare l'equazione di blending desiderata, il fattore sorgente + (Source Factor) e quello di destinazione (Destination Factor). +

    + +

    Codice di Esempio

    + + + const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); + material.blending = THREE.CustomBlending; + material.blendEquation = THREE.AddEquation; //default + material.blendSrc = THREE.SrcAlphaFactor; //default + material.blendDst = THREE.OneMinusSrcAlphaFactor; //default + + +

    Esempi

    +

    [example:webgl_materials_blending_custom materials / blending / custom ]

    + +

    Equazioni di Blending

    + + THREE.AddEquation + THREE.SubtractEquation + THREE.ReverseSubtractEquation + THREE.MinEquation + THREE.MaxEquation + + +

    Fattori di Origine (Source Factors)

    + + THREE.ZeroFactor + THREE.OneFactor + THREE.SrcColorFactor + THREE.OneMinusSrcColorFactor + THREE.SrcAlphaFactor + THREE.OneMinusSrcAlphaFactor + THREE.DstAlphaFactor + THREE.OneMinusDstAlphaFactor + THREE.DstColorFactor + THREE.OneMinusDstColorFactor + THREE.SrcAlphaSaturateFactor + + +

    Fattori di Destinazione (Destination Factors)

    +

    + Tutti questi fattori di origine sono validi come fattori di destinazione ad eccezione di THREE.SrcAlphaSaturateFactor +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + diff --git a/docs/api/it/constants/Materials.html b/docs/api/it/constants/Materials.html new file mode 100644 index 00000000000000..61133718e03214 --- /dev/null +++ b/docs/api/it/constants/Materials.html @@ -0,0 +1,159 @@ + + + + + + + + + +

    Costanti dei Materiali

    + +

    + Queste costanti definiscono proprietà comuni per tutti i tipi di materiali, + ad eccezione di Texture Combine Operations che si applicano + solo ai materiali [page:MeshBasicMaterial.combine MeshBasicMaterial], + [page:MeshLambertMaterial.combine MeshLambertMaterial] e [page:MeshPhongMaterial.combine MeshPhongMaterial].
    +

    + + +

    Lato (Side)

    + + THREE.FrontSide + THREE.BackSide + THREE.DoubleSide + +

    + Definisce quale lato delle facce sarà visualizzato - frontale, retro o entrambi. + Il valore predefinito è [page:Constant FrontSide]. +

    + +

    Modalità Blending

    + + THREE.NoBlending + THREE.NormalBlending + THREE.AdditiveBlending + THREE.SubtractiveBlending + THREE.MultiplyBlending + THREE.CustomBlending + + + +

    + Controllano le equazioni di blending di origine e di destinazione per RGB e Alpha del materiale, inviate a WebGLRenderer + per l'uso da parte di WebGL.
    + [page:Constant NormalBlending] è l'impostazione predefinita.
    + Si noti che [page:Constant CustomBlending] deve essere impostato per utilizzare le equazioni di blending personalizzate.
    + Vedi l'esempio [example:webgl_materials_blending materials / blending].
    +

    + +

    Modalità Depth

    + + THREE.NeverDepth + THREE.AlwaysDepth + THREE.EqualDepth + THREE.LessDepth + THREE.LessEqualDepth + THREE.GreaterEqualDepth + THREE.GreaterDepth + THREE.NotEqualDepth + +

    + La funzione di profondità (depth) utilizza il materiale per confrontare la Z-depth dei pixel in arrivo + con il valore del buffer della Z-depth. Se il risultato del confronto è vero, il pixel viene disegnato. + [page:Materials NeverDepth] non tornerà mai vero.
    + [page:Materials AlwaysDepth] tornerà sempre vero.
    + [page:Materials EqualDepth] tornerà vero se lo Z-depth dei pixel in ingresso è uguale all'attuale buffer Z-depth.
    + [page:Materials LessDepth] tornerà vero se lo Z-depth dei pixel in ingresso è minore dell'attuale buffer Z-depth.
    + [page:Materials LessEqualDepth] è il valore predefinito e ritornerà vero se lo Z-depth dei pixel in ingresso è minore o uguale dell'attuale buffer Z-depth.
    + [page:Materials GreaterEqualDepth] tornerà vero se lo Z-depth dei pixel in ingresso è maggiore o uguale dell'attuale buffer Z-depth.
    + [page:Materials GreaterDepth] tornerà vero se lo Z-depth dei pixel in ingresso è maggiore dell'attuale buffer Z-depth.
    + [page:Materials NotEqualDepth]tornerà vero se lo Z-depth dei pixel in ingresso è maggiore non è uguale all'attuale buffer Z-depth.
    +

    + +

    Texture Combine Operations

    + + THREE.MultiplyOperation + THREE.MixOperation + THREE.AddOperation + +

    + Definiscono come il risultato del colore della supercificie viene combinato con la mappa ambientale (se presente), + per i materiali [page:MeshBasicMaterial.combine MeshBasicMaterial], [page:MeshLambertMaterial.combine MeshLambertMaterial] + e [page:MeshPhongMaterial.combine MeshPhongMaterial].
    + [page:Constant MultiplyOperation] è l'impostazione predefinita e moltiplica la mappa di colore dell'ambiente con il colore della superficie.
    + [page:Constant MixOperation] utilizza la riflettività per miscelare i due colori.
    + [page:Constant AddOperation] aggiunge i due colori. +

    + +

    Funzioni di Stencil

    + + THREE.NeverStencilFunc + THREE.LessStencilFunc + THREE.EqualStencilFunc + THREE.LessEqualStencilFunc + THREE.GreaterStencilFunc + THREE.NotEqualStencilFunc + THREE.GreaterEqualStencilFunc + THREE.AlwaysStencilFunc + +

    + Quale funzione di stencil utilizza il meteriale per determinare se eseguire o meno un'operazione di stencil.
    + [page:Materials NeverStencilFunc] non tornerà mai vero.
    + [page:Materials LessStencilFunc] tornerà vero se il valore di riferimento dello stencil è inferiore al valore dello stencil corrente.
    + [page:Materials EqualStencilFunc] tornerà vero se il valore di riferimento dello stencil è ugale al valore dello stencil corrente.
    + [page:Materials LessEqualStencilFunc] tornerà vero se il valore di riferimento dello stencil è minore o uguale al valore dello stencil corrente.
    + [page:Materials GreaterStencilFunc] tornerà vero se il valore di riferimento dello stencil è maggiore al valore dello stencil corrente.
    + [page:Materials NotEqualStencilFunc] tornerà vero se il valore di riferimento dello stencil non è uguale al valore dello stencil corrente.
    + [page:Materials GreaterEqualStencilFunc] tornerà vero se il valore di riferimento dello stencil è maggiore o uguale al valore dello stencil corrente.
    + [page:Materials AlwaysStencilFunc] tornerà sempre vero.
    +

    + +

    Operazioni di Stencil

    + + THREE.ZeroStencilOp + THREE.KeepStencilOp + THREE.ReplaceStencilOp + THREE.IncrementStencilOp + THREE.DecrementStencilOp + THREE.IncrementWrapStencilOp + THREE.DecrementWrapStencilOp + THREE.InvertStencilOp + +

    + Quale operazione di stencil eseguirà il materiale sul pixel del buffer di stencil se la funzione stencil fornita passa.
    + [page:Materials ZeroStencilOp] imposterà il valore dello stencil a 0.
    + [page:Materials KeepStencilOp] non cambierà il valore corrente dello stencil.
    + [page:Materials ReplaceStencilOp] sostituirà il valore dello stencil con il valore di riferimento dello stencil specificato.
    + [page:Materials IncrementStencilOp] incrementerà il valore corrente dello stencil di `1`.
    + [page:Materials DecrementStencilOp] decrementerà il valore corrente dello stencil di `1`.
    + [page:Materials IncrementWrapStencilOp] incrementerà il valore corrente dello stencil di `1`. Se il valore aumenta oltre 255, verrà impostato su `0`.
    + [page:Materials DecrementWrapStencilOp] incrementerà il valore corrente dello stencil di `1`. Se il valore diminusice al di sotto di `0` verrà impostato a `255`.
    + [page:Materials InvertStencilOp] eseguirà un'inversione di bit del valore dello stencil corrente.
    +

    + +

    Tipo Normal map

    + + THREE.TangentSpaceNormalMap + THREE.ObjectSpaceNormalMap + +

    + Definisce il tipo di mappa normale. + Per TangentSpaceNormalMap, le informazioni sono relative alla superficie sottostante. + Per ObjectSpaceNormalMap, le informazioni sono relative all'oggetto sottostante. + Il valore di default è [page:Constant TangentSpaceNormalMap]. +

    + +

    GLSL Version

    + + THREE.GLSL1 + THREE.GLSL3 + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + diff --git a/docs/api/it/constants/Renderer.html b/docs/api/it/constants/Renderer.html new file mode 100644 index 00000000000000..4a10d4391cad85 --- /dev/null +++ b/docs/api/it/constants/Renderer.html @@ -0,0 +1,72 @@ + + + + + + + + + +

    Costanti WebGLRenderer

    + +

    Modalità Cull Face

    + + THREE.CullFaceNone + THREE.CullFaceBack + THREE.CullFaceFront + THREE.CullFaceFrontBack + +

    + [page:constant CullFaceNone] disabilita il face culling.
    + [page:constant CullFaceBack] elimina le facce posteriori (predefinito).
    + [page:constant CullFaceFront] elimina le facce anteriori.
    + [page:constant CullFaceFrontBack] elimina entrambe le facce posteriori e anteriori. +

    + +

    Tipi Shadow

    + + THREE.BasicShadowMap + THREE.PCFShadowMap + THREE.PCFSoftShadowMap + THREE.VSMShadowMap + +

    + Definiscono la proprietà [page:WebGLRenderer.shadowMap.type shadowMap.type] di WebGLRenderer.

    + + [page:constant BasicShadowMap] fornisce mappe shadow non filtrate - la più veloce, ma con qualità minore.
    + [page:constant PCFShadowMap] filtra le mappe shadow utilizzando l'algoritmo Percentage-Closer Filtering (PFC) (predefinito).
    + [page:constant PCFSoftShadowMap] filtra le mappe shadow utilizzando l'algoritmo Percentage-Closer Filtering (PFC) + con migliori soft shadow soprattutto quando si utilizzano mappe shadow a bassa risoluzione.
    + [page:constant VSMShadowMap] filtra le mappe shadow utilizzando l'algoritmo Variance Shadow Map (VSM). Quando si utilizza VSMShadowMap, + anche tutti i ricevitori shadow proiettano shadow.
    +

    + +

    Mappatura dei Toni

    + + THREE.NoToneMapping + THREE.LinearToneMapping + THREE.ReinhardToneMapping + THREE.CineonToneMapping + THREE.ACESFilmicToneMapping + THREE.CustomToneMapping + +

    + Definiscono la proprietà [page:WebGLRenderer.toneMapping toneMapping] di WebGLRenderer. + Viene utilizzato per approssimare l'aspetto della gamma dinamica (HDR) sul medio della + gamma dinamica bassa del monitor di un computer o dello schermo di un dispositivo mobile. +

    +

    + THREE.LinearToneMapping, THREE.ReinhardToneMapping, THREE.CineonToneMapping e THREE.ACESFilmicToneMapping sono implementazioni + integrate della mappatura dei toni. + THREE.CustomToneMapping prevede un'implementazione personalizzata modificando il codice GLSL dello shader di frammenti del materiale. + Vedi l'esempio [example:webgl_tonemapping WebGL / tonemapping]. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + diff --git a/docs/api/it/constants/Textures.html b/docs/api/it/constants/Textures.html new file mode 100644 index 00000000000000..092d89d9a5840c --- /dev/null +++ b/docs/api/it/constants/Textures.html @@ -0,0 +1,561 @@ + + + + + + + + + +

    Constanti delle Texture

    + +

    Modalità Mapping

    + + THREE.UVMapping + THREE.CubeReflectionMapping + THREE.CubeRefractionMapping + THREE.EquirectangularReflectionMapping + THREE.EquirectangularRefractionMapping + THREE.CubeUVReflectionMapping + + +

    + Definiscono la modalità di mapping della texture.
    + [page:Constant UVMapping] è la costante predefinita, e mappa la texture usando le coordinate UV della mesh.

    + + Il resto definisce i tipi di mappatura dell'ambiente.

    + + [page:Constant CubeReflectionMapping] e [page:Constant CubeRefractionMapping] sono da utilizzare con una [page:CubeTexture CubeTexture], + la quale è composta da sei texture, una per ciascuna faccia del cubo. + [page:Constant CubeReflectionMapping] è la predefinita per una [page:CubeTexture CubeTexture].

    + + [page:Constant EquirectangularReflectionMapping] e [page:Constant EquirectangularRefractionMapping] + sono da utilizzare con una equirectangular environment map. Anche chiamata lat-long map, una texture equirectangular + rappresenta una vista a 360 gradi lungo la linea centrale orizzontale e una vista a 180 lungo l'asse verticale, con i bordi + superiore e inferiore dell'immagine corrispondenti ai poli nord e sud di una sfera mappata.

    + + Vedi l'esempio [example:webgl_materials_envmaps materials / envmaps]. +

    + + +

    Modalità Wrapping

    + + THREE.RepeatWrapping + THREE.ClampToEdgeWrapping + THREE.MirroredRepeatWrapping + +

    + Definiscono le proprietà [page:Texture.wrapS wrapS] e [page:Texture.wrapT wrapT] della texture, le quali + definiscono il wrapping orizzontale e verticale della texture.

    + + Con [page:constant RepeatWrapping] la texture sarà semplicemente ripetuta all'infinito.

    + + [page:constant ClampToEdgeWrapping] è la costante predefinita. + L'ultimo pixel della texture si estende fino al bordo della mesh.

    + + Con [page:constant MirroredRepeatWrapping] la texture sarà ripetuta all'infinito, rispecchiando ad ogni ripetizione. +

    + +

    Filtri di Ingradimento

    + + THREE.NearestFilter + THREE.LinearFilter + + +

    + Da usare con la proprietà [page:Texture.magFilter magFilter] della texture, + definiscono la funzione di ingrandimento della texture da usare quando il pixel + da texturizzare mappa un'area inferiore o uguale a un elemento della texture (texel).

    + + [page:constant NearestFilter] restituisce il valore dell'elemento della texture che è più vicino + (nella distanza di Manhattan) alle coordinate della texture specificate.

    + + [page:constant LinearFilter] è l'impostazione predefinita e restituisce la media pesata dei quattro elementi della texture + più vicini alle coordinate della texture specificate e può includere elementi wrappati o ripetuti da altre parti della texture, + a seconda dei valori di [page:Texture.wrapS wrapS] e [page:Texture.wrapT wrapT], e dall'esatta mappatura. +

    + +

    Filtri di Minificazione

    + + THREE.NearestFilter + THREE.NearestMipmapNearestFilter + THREE.NearestMipmapLinearFilter + THREE.LinearFilter + THREE.LinearMipmapNearestFilter + THREE.LinearMipmapLinearFilter + + +

    + Da usare con la proprietà [page:Texture.minFilter minFilter] della texture, + definiscono la funzione di minificazione della texture che viene usata ogni volta che il + pixel da texturizzare mappa un'area superiore di un elemento della texture (texel).

    + + Oltre a [page:constant NearestFilter] e [page:constant LinearFilter], + le seguenti quattro funzioni possono essere usate per la minificazione:

    + + [page:constant NearestMipmapNearestFilter] sceglie il mipmap che più si avvicina alle dimensioni del pixel da texturizzare + e utilizza il criterio [page:constant NearestFilter] (il texel più vicino al centro del pixel) per produrre + un valore di texture.

    + + [page:constant NearestMipmapLinearFilter] sceglie i due mipmap che più si avvicinano alle dimensioni del pixel da texturizzare + e utilizza il criterio [page:constant NearestFilter] per produrre un valore di texture per ogni mipmap. Il valore della texture finale + è una media pesata di questi due valori.

    + + [page:constant LinearMipmapNearestFilter] sceglie il mipmap che più si avvicina alle dimensioni del pixel da texturizzare + e utilizza il criterio [page:constant LinearFilter] ( una media pesata dei quattro texels che più si avvicinano al centro del pixel) per produrre + un valore di texture.

    + + [page:constant LinearMipmapLinearFilter] è l'impostazione predefinita e sceglie i due mipmap che più si avvicinano alle dimensioni del pixel da texturizzare + e utilizza il criterio [page:constant LinearFilter] per produrre un valore di texture per ogni mipmap. Il valore della texture finale è una + media pesata di questi due valori.

    + + Vedi l'esempio [example:webgl_materials_texture_filters materials / texture / filters] +

    + +

    Tipi

    + + THREE.UnsignedByteType + THREE.ByteType + THREE.ShortType + THREE.UnsignedShortType + THREE.IntType + THREE.UnsignedIntType + THREE.FloatType + THREE.HalfFloatType + THREE.UnsignedShort4444Type + THREE.UnsignedShort5551Type + THREE.UnsignedInt248Type + +

    + Da usare con la proprietà [page:Texture.type type] della texture, la quale deve corrispondere al formato corretto. Vedi sotto per i dettagli.

    + + [page:constant UnsignedByteType] è l'impostazione predefinita. +

    + +

    Formati

    + + THREE.AlphaFormat + THREE.RedFormat + THREE.RedIntegerFormat + THREE.RGFormat + THREE.RGIntegerFormat + THREE.RGBAFormat + THREE.RGBAIntegerFormat + THREE.LuminanceFormat + THREE.LuminanceAlphaFormat + THREE.DepthFormat + THREE.DepthStencilFormat + +

    + Da usare con la proprietà [page:Texture.format format] della texture, + definiscono come gli elementi di una texture 2d, o `texel`, vengono letti dagli shader.

    + + [page:constant AlphaFormat] elimina i componenti rosso, verde e blu e legge solo il componente alfa.

    + + [page:constant RedFormat] elimina i componenti verde e blu e legge solo il componente rosso.

    + + [page:constant RedIntegerFormat] elimina i componenti verde e blu e legge solo il componente rosso. + I texel sono letti come interi invece che come floating point. + (può essere utilizzato solo in un contesto di rendering WebGL 2).

    + + [page:constant RGFormat] elimina i componenti alfa e blu e legge i componenti rosso e verde. + (può essere utilizzato solo in un contesto di rendering WebGL 2).

    + + [page:constant RGIntegerFormat] elimina i componenti alfa e blu e legge i componenti rosso e verde. + I texel sono letti come numeri interi invece che come floating point. + (può essere utilizzato solo in un contesto di rendering WebGL 2).

    + + [page:constant RGBAFormat] è l'impostazione predefinita e legge i componenti rosso, verde, blu e alfa.

    + + [page:constant RGBAIntegerFormat] è l'impostazione di default e legge i componenti rosso, verde, blu e alfa. + I texel sono letti come numeri interi invece che come floating point. + (può essere utilizzato solo in un contesto di rendering WebGL 2).

    + + [page:constant LuminanceFormat] legge ogni elemento come un singolo componente di luminanza. + Questo viene quindi convertito in floating point, fissato all'intervallo [0,1], e quindi assemblato + in un elemento RGBA posizionando il valore di luminanza nei canali rosso, verde e blu, e allegando + 1.0 al canale alfa.

    + + [page:constant LuminanceAlphaFormat] legge ogni elemento come un doppio luminanza/alfa. Lo stesso processo si verifica + come per [page:constant LuminanceFormat], tranne per il fatto che il canale alfa può avere valori diversi da `1.0`.

    + + [page:constant DepthFormat] legge ogni elemento come un singolo valore depth, lo converte in floating point e si blocca + nell'intervallo [0,1]. Questa è l'impostazione predefinita per [page:DepthTexture DepthTexture].

    + + [page:constant DepthStencilFormat] legge ogni elemento come una coppia di valori depth e stencil. + Il componente depth della coppia viene interpretato come in [page:constant DepthFormat]. + Il componente stencil viene interpretato in base al formato interno depth + stencil.

    + + Si noti che la texture deve avere impostato il [page:Texture.type tipo] corretto, come descritto sopra. + Vedi [link:https://developer.mozilla.org/en/docs/Web/API/WebGLRenderingContext/texImage2D WebGLRenderingContext.texImage2D] + per maggiori dettagli. +

    + +

    Formati Texture Compressi DDS / ST3C

    + + THREE.RGB_S3TC_DXT1_Format + THREE.RGBA_S3TC_DXT1_Format + THREE.RGBA_S3TC_DXT3_Format + THREE.RGBA_S3TC_DXT5_Format + +

    + Da usare con la prorietà [page:Texture.format formato] della [page:CompressedTexture CompressedTexture], + questi richiedono il supporto per l'estensione + [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/ WEBGL_compressed_texture_s3tc].

    + + Questi sono quattro formati [link:https://en.wikipedia.org/wiki/S3_Texture_Compression S3TC] disponibili tramite questa estensione. Questi sono:
    + + [page:constant RGB_S3TC_DXT1_Format]: Un'immagine compressa DXT1 in un formato immagine RGB.
    + [page:constant RGBA_S3TC_DXT1_Format]: Un'immagine compressa DXT1 in un formato immagine RGBA con un semplice valore alfa on/off.
    + [page:constant RGBA_S3TC_DXT3_Format]: Un'immagine compressa DXT3 in un formato immagine RGBA. Comparato con una texture 32-bit, offre una compressione 4:1.
    + [page:constant RGBA_S3TC_DXT5_Format]: Un'immagine compressa DXT5 in un formato immagine RGBA. Anche questa costante permette una compressione 4:1, + ma differisce dalla compressione DXT3 nel modo in cui viene eseguita la compressione alfa.
    +

    + +

    Formati Texture Compressi PVRTC

    + + THREE.RGB_PVRTC_4BPPV1_Format + THREE.RGB_PVRTC_2BPPV1_Format + THREE.RGBA_PVRTC_4BPPV1_Format + THREE.RGBA_PVRTC_2BPPV1_Format + +

    + Da usare con la prorietà del [page:Texture.format formato] della [page:CompressedTexture CompressedTexture], + questi richiedono il supporto per l'estensione + [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/ WEBGL_compressed_texture_pvrtc].
    + + PVRTC è in genere disponibile solo su dispositivi mobili con chipset PowerVR, che sono principalmente dispositivi Apple.

    + + Questi sono quattro formati [link:https://en.wikipedia.org/wiki/PVRTC PVRTC] disponibili tramite questa estensione. Questi sono:
    + + [page:constant RGB_PVRTC_4BPPV1_Format]: compressione RGB in modalità 4-bit. un blocco per ogni pixel 4×4.
    + [page:constant RGB_PVRTC_2BPPV1_Format]: compressione RGB in modalità 2-bit. un blocco per ogni pixel 8×4.
    + [page:constant RGBA_PVRTC_4BPPV1_Format]: compressione RGBA in modalità 4-bit. un blocco per ogni pixel 4×4.
    + [page:constant RGBA_PVRTC_2BPPV1_Format]: compressione RGBA in modalità 2-bit. un blocco per ogni pixel 8×4.
    +

    + +

    Formati Texture Compressi ETC

    + + THREE.RGB_ETC1_Format + THREE.RGB_ETC2_Format + THREE.RGBA_ETC2_EAC_Format + +

    + Da usare con la prorietà del [page:Texture.format formato] della [page:CompressedTexture CompressedTexture], + questi richiedono il supporto per le estensioni + [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc1/ WEBGL_compressed_texture_etc1] (ETC1) o + [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc/ WEBGL_compressed_texture_etc] + (ETC2).

    +

    + +

    Formati Texture Compressi ASTC

    + + THREE.RGBA_ASTC_4x4_Format + THREE.RGBA_ASTC_5x4_Format + THREE.RGBA_ASTC_5x5_Format + THREE.RGBA_ASTC_6x5_Format + THREE.RGBA_ASTC_6x6_Format + THREE.RGBA_ASTC_8x5_Format + THREE.RGBA_ASTC_8x6_Format + THREE.RGBA_ASTC_8x8_Format + THREE.RGBA_ASTC_10x5_Format + THREE.RGBA_ASTC_10x6_Format + THREE.RGBA_ASTC_10x8_Format + THREE.RGBA_ASTC_10x10_Format + THREE.RGBA_ASTC_12x10_Format + THREE.RGBA_ASTC_12x12_Format + +

    + Da usare con la prorietà del [page:Texture.format formato] della [page:CompressedTexture CompressedTexture], + questi richiedono il supporto per l'estensione + [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_astc/ WEBGL_compressed_texture_astc].
    +

    + +

    Formato Texture Compresso BPTCt

    + + THREE.RGBA_BPTC_Format + +

    + Da usare con la prorietà del [page:Texture.format formato] della [page:CompressedTexture CompressedTexture], + questi richiedono il supporto per l'estensione + [link:https://www.khronos.org/registry/webgl/extensions/EXT_texture_compression_bptc/ EXT_texture_compression_bptc].
    +

    + +

    Formati Interni

    + + 'ALPHA' + 'RGB' + 'RGBA' + 'LUMINANCE' + 'LUMINANCE_ALPHA' + 'RED_INTEGER' + 'R8' + 'R8_SNORM' + 'R8I' + 'R8UI' + 'R16I' + 'R16UI' + 'R16F' + 'R32I' + 'R32UI' + 'R32F' + 'RG8' + 'RG8_SNORM' + 'RG8I' + 'RG8UI' + 'RG16I' + 'RG16UI' + 'RG16F' + 'RG32I' + 'RG32UI' + 'RG32F' + 'RGB565' + 'RGB8' + 'RGB8_SNORM' + 'RGB8I' + 'RGB8UI' + 'RGB16I' + 'RGB16UI' + 'RGB16F' + 'RGB32I' + 'RGB32UI' + 'RGB32F' + 'RGB9_E5' + 'SRGB8' + 'R11F_G11F_B10F' + 'RGBA4' + 'RGBA8' + 'RGBA8_SNORM' + 'RGBA8I' + 'RGBA8UI' + 'RGBA16I' + 'RGBA16UI' + 'RGBA16F' + 'RGBA32I' + 'RGBA32UI' + 'RGBA32F' + 'RGB5_A1' + 'RGB10_A2' + 'RGB10_A2UI' + 'SRGB8_ALPHA8' + 'DEPTH_COMPONENT16' + 'DEPTH_COMPONENT24' + 'DEPTH_COMPONENT32F' + 'DEPTH24_STENCIL8' + 'DEPTH32F_STENCIL8' + + +

    + Attenzione: la modifica di un formato interno di una texture avrà effetto solo + quando si utilizza un contesto di rendering WebGL 2.

    + + Da usare con la proprietà [page:Texture.internalFormat internalFormat] della texture, + definiscono come gli elementi della texture, o `toxel`, sono memorizzati nella GPU.

    + + [page:constant R8] memorizza il componente rosso su 8 bit.

    + + [page:constant R8_SNORM] memorizza il componente rosso su 8 bit. Il componenete viene archiviato come normalizzato.

    + + [page:constant R8I] memorizza il componente rosso su 8 bit. Il componenete viene archiviato come un intero.

    + + [page:constant R8UI] memorizza il componente rosso su 8 bit. Il componenete viene archiviato come un intero senza segno.

    + + [page:constant R16I] memorizza il componente rosso su 16 bit. Il componenete viene archiviato come un intero.

    + + [page:constant R16UI] memorizza il componente rosso su 16 bit. Il componenete viene archiviato come un intero senza segno.

    + + [page:constant R16F] memorizza il componente rosso su 16 bit. Il componenete viene archiviato come un floating point.

    + + [page:constant R32I] memorizza il componente rosso su 32 bit. Il componenete viene archiviato come un intero.

    + + [page:constant R32UI] memorizza il componente rosso su 32 bit.Il componenete viene archiviato come un intero senza segno.

    + + [page:constant R32F] memorizza il componente rosso su 32 bit. Il componenete viene archiviato come un floating point.

    + + [page:constant RG8] memorizza i componenti rosso e verde su 8 bit ciascuno.

    + + [page:constant RG8_SNORM] memorizza i componenti rosso e verde su 8 bit ciascuno. + Ogni componente viene archiviato come normalizzato. +

    + + [page:constant RG8I] memorizza i componenti rosso e verde su 8 bit ciascuno. + Ogni componente viene archiviato come un intero. +

    + + [page:constant RG8UI] memorizza i componenti rosso e verde su 8 bit ciascuno. + Ogni componente viene archiviato come un intero senza segno. +

    + + [page:constant RG16I] memorizza i componenti rosso e verde su 16 bit ciascuno. + Ogni componente viene archiviato come un intero. +

    + + [page:constant RG16UI] memorizza i componenti rosso e verde su 16 bit ciascuno. + Ogni componente viene archiviato come un intero senza segno. +

    + + [page:constant RG16F] memorizza i componenti rosso e verde su 16 bit ciascuno. + Ogni componente viene archiviato come un floating point. +

    + + [page:constant RG32I] memorizza i componenti rosso e verde su 32 bit ciascuno. + Ogni componente viene archiviato come un intero. +

    + + [page:constant RG32UI] memorizza i componenti rosso e verde su 32 bit ciascuno. + Ogni componente viene archiviato come un intero senza segno. +

    + + [page:constant RG32F] memorizza i componenti rosso e verde su 32 bit ciascuno. + Ogni componente viene archiviato come un floating point. +

    + + [page:constant RGB8] memorizza i componenti rosso, verde e blu su 8 bit ciascuno. +

    + + [page:constant RGB8_SNORM] memorizza i componenti rosso, verde e blu su 8 bit ciascuno. + Ogni componente viene archiviato come normalizzato. +

    + + [page:constant RGB8I] memorizza i componenti rosso, verde e blu su 8 bit ciascuno. + Ogni componente viene archiviato come un intero. +

    + + [page:constant RGB8UI] memorizza i componenti rosso, verde e blu su 8 bit ciascuno. + Ogni componente viene archiviato come un intero senza segno. +

    + + [page:constant RGB16I] memorizza i componenti rosso, verde e blu su 16 bit ciascuno. + Ogni componente viene archiviato come un intero. +

    + + [page:constant RGB16UI] memorizza i componenti rosso, verde e blu su 16 bit ciascuno. + Ogni componente viene archiviato come un intero senza segno. +

    + + [page:constant RGB16F] memorizza i componenti rosso, verde e blu su 16 bit ciascuno. + Ogni componente viene archiviato come un floating point +

    + + [page:constant RGB32I] memorizza i componenti rosso, verde e blu su 32 bit ciascuno. + Ogni componente viene archiviato come un intero. +

    + + [page:constant RGB32UI] memorizza i componenti rosso, verde e blu su 32 bit ciascuno. + Ogni componente viene archiviato come un intero senza segno. +

    + + [page:constant RGB32F] memorizza i componenti rosso, verde e blu su 32 bit ciascuno. + Ogni componente viene archiviato come un floating point +

    + + [page:constant R11F_G11F_B10F] memorizza i componenti rosso, verde e blu rispettivamente 11 bit, 11 bit, e 10bit. + Ogni componente viene archiviato come un floating point. +

    + + [page:constant RGB565] memorizza i componenti rosso, verde e blu rispettivamente su 5 bit, 6 bit, e 5 bit.

    + + [page:constant RGB9_E5] memorizza i componenti rosso, verde e blu su 9 bit ciascuno.

    + + [page:constant RGBA8] memorizza i componenti rosso, verde, blu e alfa su 8 bit ciascuno.

    + + [page:constant RGBA8_SNORM] memorizza i componenti rosso, verde, blu e alfa su 8 bit ciascuno. + Ogni componente viene archiviato come normalizzato. +

    + + [page:constant RGBA8I] memorizza i componenti rosso, verde, blu e alfa su 8 bit ciascuno. + Ogni componente viene archiviato come un intero. +

    + + [page:constant RGBA8UI] memorizza i componenti rosso, verde, blu e alfa su 8 bit ciascuno. + Ogni componente viene archiviato come un intero senza segno. +

    + + [page:constant RGBA16I] memorizza i componenti rosso, verde, blu e alfa su 16 bit ciascuno. + Ogni componente viene archiviato come un intero. +

    + + [page:constant RGBA16UI] memorizza i componenti rosso, verde, blu e alfa su 16 bit ciascuno. + Ogni componente viene archiviato come un intero senza segno. +

    + + [page:constant RGBA16F] memorizza i componenti rosso, verde, blu e alfa su 16 bit ciascuno. + Ogni componente viene archiviato come un floating point. +

    + + [page:constant RGBA32I] memorizza i componenti rosso, verde, blu e alfa su 32 bit ciascuno. + Ogni componente viene archiviato come un intero. +

    + + [page:constant RGBA32UI] memorizza i componenti rosso, verde, blu e alfa su 32 bit ciascuno. + Ogni componente viene archiviato come un intero senza segno. +

    + + [page:constant RGBA32F] memorizza i componenti rosso, verde, blu e alfa su 32 bit ciascuno. + Ogni componente viene archiviato come un floating point. +

    + + [page:constant RGB5_A1] memorizza i componenti rosso, verde, blu e alfa rispettivamente su 5 bit, 5 bit, 5 bit e 1 bit.

    + + [page:constant RGB10_A2] memorizza i componenti rosso, verde, blu e alfa rispettivamente su 10 bit, 10 bit, 10 bit e 2 bit.

    + + [page:constant RGB10_A2UI] memorizza i componenti rosso, verde, blu e alfa rispettivamente su 10 bit, 10 bit, 10 bit e 2 bit. + Ogni componente viene archiviato come un intero senza segno. +

    + + [page:constant SRGB8] memorizza i componenti rosso, verde e blu su 8 bit ciascuno.

    + + [page:constant SRGB8_ALPHA8] memorizza i componenti rosso, verde, blu e alfa su 8 bit ciascuno.

    + + [page:constant DEPTH_COMPONENT16] memorizza il componente depth su 16 bit.

    + + [page:constant DEPTH_COMPONENT24] memorizza il componente depth su 24 bit.

    + + [page:constant DEPTH_COMPONENT32F] memorizza il componente depth su 32 bit. Il componente viene archiviato come un floating point.

    + + [page:constant DEPTH24_STENCIL8] memorizza i componenti depth e stencil rispettivamente su 24 bit e 8 bit. + Il componente stencil viene archiviato come un intero senza segno. +

    + + [page:constant DEPTH32F_STENCIL8] memorizza i componenti depth e stencil rispettivamente su 32 bit e 8 bit. + Il componente depth viene archiviato come un floating point, il componente stencil viene archiviato come un intero senza segno. +

    + + Si noti che la texture deve avere impostato il corretto [page:Texture.type tipo], + come anche il [page:Texture.format formato] corretto. + + Vedi [link:https://developer.mozilla.org/en/docs/Web/API/WebGLRenderingContext/texImage2D WebGLRenderingContext.texImage2D], e + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/texImage3D WebGL2RenderingContext.texImage3D], + per maggiori informazioni relativamente alle possibili combinazioni del [page:Texture.format formato], dell'[page:Texture.internalFormat internalFormat], + e del [page:Texture.type tipo].

    + + Per informazioni più approfondite sui formati interni, puoi anche fare riferimento direttamente alla + [link:https://www.khronos.org/registry/webgl/specs/latest/2.0/ Specifica WebGL2] e alla + [link:https://www.khronos.org/registry/OpenGL/specs/es/3.0/es_spec_3.0.pdf Specifica OpenGL ES 3.0]. +

    + +

    Encoding

    + + THREE.LinearEncoding + THREE.sRGBEncoding + THREE.BasicDepthPacking + THREE.RGBADepthPacking + +

    + Da usare con la proprietà [page:Texture.encoding encoding] della Texture.

    + + Se il tipo di encoding viene modificato dopo che la texture è già stata utilizzata dal materiale, + sarà necessario impostare il valore [page:Material.needsUpdate Material.needsUpdate] a `true` per fare in modo + che il materiale venga ricompilato.

    + + [page:constant LinearEncoding] è l'impostazione predefinita. + Valori diversi da questo sono validi solo per la mappa di un materiale, envMap ed emissiveMap. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + diff --git a/docs/api/it/core/BufferAttribute.html b/docs/api/it/core/BufferAttribute.html new file mode 100644 index 00000000000000..c8d97887dc11ed --- /dev/null +++ b/docs/api/it/core/BufferAttribute.html @@ -0,0 +1,224 @@ + + + + + + + + + +

    [name]

    + +

    + Questa classe memorizza i dati per un attributo (come le posizioni dei vertici, gli indici delle facce, le normali, + i colori, le coordinate UV e alcuni attributi personalizzati) associato ad una [page:BufferGeometry], + che consente un passaggio più efficiente dei dati alla GPU. Consulta questa pagina per i dettagli ed un esempo di + utilizzo. Quando si lavora con dati di tipo vettoriale, i metodi helper .fromBufferAttribute( attribute, index ) + sulle classi [page:Vector2.fromBufferAttribute Vector2], + [page:Vector3.fromBufferAttribute Vector3], + [page:Vector4.fromBufferAttribute Vector4] e [page:Color.fromBufferAttribute Color] possono essere utili. +

    + +

    Costruttore

    +

    [name]( [param:TypedArray array], [param:Integer itemSize], [param:Boolean normalized] )

    +

    + [page:TypedArray array] -- Deve essere un [link:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/TypedArray TypedArray]. + Utilizzato per istanziare il buffer.
    + Questo array dovrebbe avere gli elementi itemSize * numVertices + dove numVertices è il numero di vertici della [page:BufferGeometry BufferGeometry] associata.

    + + [page:Integer itemSize] -- il numero di valori dell'array che deve essere associato ad un particolare vertice. + Per esempio, se questo atttibuto memorizza un vettore a 3 componenti (come posizione, normale o colore), + itemSize dovrebbe essere 3.

    + + [page:Boolean normalized] -- (opzionale) Si applica solo ai dati interi. Indica il modo in cui i dati sottostanti + del buffer si adattano ai valori del codice GLSL. Ad esempio, se l'[page:TypedArray array] è un'istanza di UInt16Array, + e [page:Boolean normalized] è a true, i valori `0 - +65535` nei dati dell'array saranno mappati su 0.0f - +1.0f nell'attributo GLSL. + Un Int16Array (con segno) sarà mappato da -32768 - +32767 a -1.0f - +1.0f. Se [page:Boolean normalized] è a false, i valori + verranno convertiti in float non modificati, p.e. 32767 diventa 32767.0f. +

    + +

    Proprietà

    + +

    [property:TypedArray array]

    +

    + L'[page:TypedArray array] contente i dati memorizzati nel buffer. +

    + +

    [property:Integer count]

    +

    + Memorizza la lunghezza dell'[page:BufferAttribute.array array] divisa per [page:BufferAttribute.itemSize itemSize].

    + + Se il buffer memorizza un vettore a 3 componenti (come una posizione, una normale o un colore), + questo conterà il numero dei vettori memorizzati. +

    + +

    [property:Boolean isBufferAttribute]

    +

    + Flag di sola lettura per verificare se un dato oggetto è di tipo [name]. +

    + +

    [property:Integer itemSize]

    +

    + La lunghezza dei vettori che vengono memorizzati nell'[page:BufferAttribute.array array]. +

    + +

    [property:String name]

    +

    + Un nome opzionale per questa istanza dell'attributo. Il valore predefinito è una stringa vuota. +

    + +

    [property:Boolean needsUpdate]

    +

    + Flag che indica che questo attributo è stato modificato e deve essere rinviato alla GPU. + Impostalo a true quando modifichi il valore dell'array.

    + + Impostando questa proprietà a true incrementa, inoltre, la [page:BufferAttribute.version versione]. +

    + +

    [property:Boolean normalized]

    +

    + Indica il modo in cui i dati sottostanti del buffer si adattano ai valori del codice shader GLSL. + Vedi il costruttore sopra per i dettagli. +

    + +

    [property:Function onUploadCallback]

    +

    + Una funzione di callback che viene eseguita dopo che il Renderer ha trasferito i dati dell'array dell'attributo + alla GPU. +

    + +

    [property:Object updateRange]

    +

    Oggetto contenente:
    + [page:Integer offset]: Il valore predefinito è `0`. Posizione da cui inizia l'aggiornamento.
    + [page:Integer count]: Il valore predefinito è `-1`, il che significa non utilizzare intervalli di aggiornamento.

    + + Può essere utilizzato solo per aggiornare alcuni componenti dei vettori memorizzati (per esempio, solo + il componente relativo al colore). +

    + +

    [property:Usage usage]

    +

    + Definisce il modello di utilizzo previsto per l'archivio dati a fini di ottimizzazione. Corrisponde al paramentro `usage` + di [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData WebGLRenderingContext.bufferData](). + Il valore predefinito è [page:BufferAttributeUsage StaticDrawUsage]. Vedi le [page:BufferAttributeUsage costanti] di utilizzo + per tutti i valori possibili.

    + + Nota: Dopo l'utilizzo iniziale di un buffer, il suo utilizzo non può essere modificato. Invece, istanziane uno nuovo e imposta + l'utilizzo desiderato prima del rendering successivo. +

    + +

    [property:Integer version]

    +

    + Un numero di versione, incrementato ogni volta che la proprietà [page:BufferAttribute.needsUpdate needsUpdate] viene impostata a true. +

    + +

    Metodi

    + +

    [method:this applyMatrix3]( [param:Matrix3 m] )

    +

    + Applica la matrice [page:Matrix3 m] ad ogni elemento Vector3 di questo BufferAttribute. +

    + +

    [method:this applyMatrix4]( [param:Matrix4 m] )

    +

    + Applica la matrice [page:Matrix4 m] ad ogni elemento Vector3 di questo BufferAttribute. +

    + +

    [method:this applyNormalMatrix]( [param:Matrix3 m] )

    +

    + Applica la matrice normale [page:Matrix3 m] ad ogni elemento Vector3 di questo BufferAttribute. +

    + +

    [method:this transformDirection]( [param:Matrix4 m] )

    +

    + Applica la matrice [page:Matrix4 m] ad ogni elemento Vector3 di questo BufferAttribute, interpretando gli elementi come vettori direzionali. +

    + +

    [method:BufferAttribute clone]()

    +

    Restituisce una copia di questo bufferAttribute.

    + +

    [method:this copy]( [param:BufferAttribute bufferAttribute] )

    +

    Copia un altro BufferAttribute in questo BufferAttribute.

    + +

    [method:this copyArray]( array )

    +

    + Copia l'array fornito qui (il quale può essere un normale array o un array tipizzato) + nell'[page:BufferAttribute.array array].

    + + Vedi [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set TypedArray.set] + per le note sui requisiti se si copia un TypedArray. +

    + +

    [method:this copyAt] ( [param:Integer index1], [param:BufferAttribute bufferAttribute], [param:Integer index2] )

    +

    Copia un vettore da bufferAttribute[index2] a [page:BufferAttribute.array array][index1].

    + +

    [method:Number getX]( [param:Integer index] )

    +

    Restituisce il componente x del vettore in corrispondenza dell'indice specificato.

    + +

    [method:Number getY]( [param:Integer index] )

    +

    Restituisce il componente y del vettore in corrispondenza dell'indice specificato.

    + +

    [method:Number getZ]( [param:Integer index] )

    +

    Restituisce il componente z del vettore in corrispondenza dell'indice specificato.

    + +

    [method:Number getW]( [param:Integer index] )

    +

    Restituisce il componente w del vettore in corrispondenza dell'indice specificato.

    + +

    [method:this onUpload]( [param:Function callback] )

    +

    + Imposta il valore della proprietà onUploadCallback.

    + Nel [example:webgl_buffergeometry WebGL / Buffergeometry] questo metodo viene utilizzato per + liberare memoria dopo che il buffer è stato trasferito alla GPU. +

    + +

    [method:this set] ( [param:Array value], [param:Integer offset] )

    +

    + value -- un [page:Array] o [page:TypedArray] dal quale copiare i valori.
    + offset -- (opzionale) indice dell'[page:BufferAttribute.array array] da cui iniziare la copia.

    + + Chiama [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set TypedArray.set]( [page:Array value], [page:Integer offset] ) + sull'[page:BufferAttribute.array array].

    + + In particolare, si veda questa pagina per i requisiti sul [page:Array value] + che deve essere un [page:TypedArray]. +

    + +

    [method:this setUsage] ( [param:Usage value] )

    +

    + Imposta [page:BufferAttribute.usage usage] a value. Vedi le [page:BufferAttributeUsage costanti] di utilizzo per tutti i possibili valori di input.

    + + Nota: Dopo l'utilizzo iniziale di un buffer, il suo utilizzo non può cambiare. Invece, istanziane uno nuovo e + imposta l'utilizzo desiderato prima del rendering successivo. +

    + +

    [method:this setX]( [param:Integer index], [param:Float x] )

    +

    Imposta il componente x del vettore in corrispondenza dell'indice specificato.

    + +

    [method:this setY]( [param:Integer index], [param:Float y] )

    +

    Imposta il componente y del vettore in corrispondenza dell'indice specificato.

    + +

    [method:this setZ]( [param:Integer index], [param:Float z] )

    +

    Imposta il componente z del vettore in corrispondenza dell'indice specificato.

    + +

    [method:this setW]( [param:Integer index], [param:Float w] )

    +

    Imposta il componente w del vettore in corrispondenza dell'indice specificato.

    + +

    [method:this setXY]( [param:Integer index], [param:Float x], [param:Float y] )

    +

    Imposta i componenti x e y del vettore in corrispondenza dell'indice specificato.

    + +

    [method:this setXYZ]( [param:Integer index], [param:Float x], [param:Float y], [param:Float z] )

    +

    Imposta i componenti x, y e z del vettore in corrispondenza dell'indice specificato.

    + +

    [method:this setXYZW]( [param:Integer index], [param:Float x], [param:Float y], [param:Float z], [param:Float w] )

    +

    Imposta i componenti x, y, z e w del vettore in corrispondenza dell'indice specificato.

    + + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/core/BufferGeometry.html b/docs/api/it/core/BufferGeometry.html new file mode 100644 index 00000000000000..afbff71ae75de7 --- /dev/null +++ b/docs/api/it/core/BufferGeometry.html @@ -0,0 +1,319 @@ + + + + + + + + + +

    [name]

    + +

    + Una rappresentazione della geometria di mesh, di linee o di punti. Include posizioni di vertici, indici della faccia, + normali, colori, coordinate UV, e attributi personalizzati all'interno dei buffer, riducendo il costo del passaggio + di tutti questi dati alla GPU. +

    +

    + Per leggere e modificare dati negli attributi della BufferGeometry, vedi la documentazione di [page:BufferAttribute]. +

    + +

    Codice di Esempio

    + + const geometry = new THREE.BufferGeometry(); + // crea una semplice figura quadrata. Duplichiamo i vertici top left e bottom right + // perché ogni vertice ha bisogno di apparire una volta per triangolo. + const vertices = new Float32Array( [ + -1.0, -1.0, 1.0, + 1.0, -1.0, 1.0, + 1.0, 1.0, 1.0, + + 1.0, 1.0, 1.0, + -1.0, 1.0, 1.0, + -1.0, -1.0, 1.0 + ] ); + + // itemSize = 3 perché ci osno 3 valori (componenti) per vertice + geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); + const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); + const mesh = new THREE.Mesh( geometry, material ); + + +

    Esempi

    +

    + [example:webgl_buffergeometry Mesh with non-indexed faces]
    + [example:webgl_buffergeometry_indexed Mesh with indexed faces]
    + [example:webgl_buffergeometry_lines Lines]
    + [example:webgl_buffergeometry_lines_indexed Indexed Lines]
    + [example:webgl_buffergeometry_custom_attributes_particles Particles]
    + [example:webgl_buffergeometry_rawshader Raw Shaders] +

    + +

    Costruttore

    + + +

    [name]()

    +
    + Crea un nuovo [name]. Inoltre imposta alcune proprietà al valore predefinito. +
    + + +

    Proprietà

    + +

    [property:Object attributes]

    +

    + Questo hashmap ha come id il nome dell'attributo da impostare e come valore il [page:BufferAttribute buffer] su cui impostarlo. + Piuttosto che accedere a questa proprietà direttamente, usa [page:.setAttribute] e [page:.getAttribute] per accedere agli attributi + della geometria. +

    + +

    [property:Box3 boundingBox]

    +

    + Bounding box per la bufferGeometry, che può essere calcolato con + [page:.computeBoundingBox](). Il valore predefinito è `null`. +

    + +

    [property:Sphere boundingSphere]

    +

    + Bounding sphere per la bufferGeometry, che può essere calcolato con + [page:.computeBoundingSphere](). Il valore predefinito è `null`. +

    + +

    [property:Object drawRange]

    +

    + Determina la parte della geometria da visualizzare. Non dovrebbe essere impostato + direttamente, usa invece [page:.setDrawRange]. Il valore predefinito è + + { start: 0, count: Infinity } + + Per la BufferGeometry non indicizzata, count è il numero di vertici da visualizzare. + Per la BufferGeometry indicizzata, count è il numero di indici da visualizzare. +

    + +

    [property:Array groups]

    +

    + Divide la geometria in gruppi, ognuno dei quali verrà renderizzato in una chimata draw WebGL separata. + Ci permette che un array di materiali venga usato con una geometria.

    + + Ogni gruppo è un oggetto della forma: + { start: Integer, count: Integer, materialIndex: Integer } + dove start specifica il primo elemento nella chiamata draw - il primo vertice per la geometria non + indicizzata, altrimenti il primo indice del triangolo. Count specifica quanti vertici (o indici) sono + inclusi, e materialIndex specifica l'indice dell'array del materiale da utilizzare.

    + + Usa [page:.addGroup] per aggiungere gruppi, piuttosto che modificare questo array direttamente.

    + + Ogni vertice e indice deve appartenere esattamente ad un gruppo - i gruppi non devono condividere vertici o + indici, e non devono lasciare vertici o indici inutilizzati. +

    + + + + + +

    [property:Integer id]

    +

    Numero univoco per questa istanza della bufferGeometry.

    + +

    [property:BufferAttribute index]

    +

    + Consente di riutilizzare i vertici su più triangoli; viene chiamato "indexed triangles". + Ogni triangolo è associato con gli indici di tre vertici. Questo attributo quindi memorizza + l'indice di ogni vertice per ogni faccia del triangolo. + + Se questo attributo non è impostato, il [page:WebGLRenderer renderer] assume che ogni 3 posizioni contigue + rappresentano un singolo triangolo. + + Il valore predefinito è `null`. +

    + +

    [property:Boolean isBufferGeometry]

    +

    + Flag di sola lettura per verificare se un dato oggetto è di tipo [name]. +

    + +

    [property:Object morphAttributes]

    +

    + Hashmap di BufferAttribute contenente i dettagli dei target morph delle geometrie.
    + Nota: Una volta che la geometria è stata renderizzata, i dati dell'attributo morph non possono essere modificati. + Dovrai chiamare [page:.dispose](), e creare una nuova istanza della [name]. +

    + +

    [property:Boolean morphTargetsRelative]

    +

    + Usato per controllare il comportamento del target morph: quando è impostato a true, i dati del target morph vengono + trattati come offset relativi, anziché come posizioni/normali assoluti. + + L'impostazione predefinita è `false`. +

    + +

    [property:String name]

    +

    + Nome opzionale per questa istanza di bufferGeometry. Il valore predefinito è una stringa vuota. +

    + +

    [property:Object userData]

    +

    + Un oggetto che può essere utilizzato per memorizzare i dati relativi alla BufferGeometry. + Non dovrebbe contenere i riferimenti alle funzioni poiché queste non verranno clonate. +

    + +

    [property:String uuid]

    +

    + [link:http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] di questa istanza. + Viene assegnato automaticamente e non deve essere modificato. +

    + +

    Metodi

    + +

    [page:EventDispatcher EventDispatcher] i metodi sono disponibili in questa classe.

    + +

    [method:undefined addGroup]( [param:Integer start], [param:Integer count], [param:Integer materialIndex] )

    +

    + Aggiunge un gruppo a questa geometria; vedi la proprietà [page:BufferGeometry.groups groups] + per maggiori dettagli. +

    + +

    [method:this applyMatrix4]( [param:Matrix4 matrix] )

    +

    Applica la matrice di trasformazione alla geometria.

    + +

    [method:this applyQuaternion]( [param:Quaternion quaternion] )

    +

    Applica la rotazione rappresentata dal quaternione alla geometria.

    + +

    [method:this center] ()

    +

    Centra la geometria basandosi sul bounding box.

    + +

    [method:undefined clearGroups]( )

    +

    Cancella tutti i gruppi.

    + +

    [method:BufferGeometry clone]()

    +

    Crea un clone di questa BufferGeometry.

    + +

    [method:undefined computeBoundingBox]()

    +

    + Calcola il bounding box della geometria, aggiornando l'attributo [page:.boundingBox].
    + I Bounding box non sono calcolati per impostazione predefinita. Devono essere calcolati esplicitamente, + altrimenti sono `null`. +

    + +

    [method:undefined computeBoundingSphere]()

    +

    + Calcola il bounding sphere della geometria, aggiornando l'attributo [page:.boundingSphere].
    + I Bounding sphere non sono calcolati per impostazione predefinita. Devono essere calcolati esplicitamente, + altrimenti sono `null`. +

    + +

    [method:undefined computeTangents]()

    +

    + Calcola e aggiunge un attributo tangent a questa geometria.
    + Il calcolo è supportato solo per geometrie indicizzate e se la posizione, la normale e gli attributi uv sono definiti. + Quando si usa una mappa normale dello spazio tangente, meglio usare l'algoritmo MikkTSpace fornito da [page:BufferGeometryUtils.computeMikkTSpaceTangents]. +

    + +

    [method:undefined computeVertexNormals]()

    +

    Calcola la normale dei vertici calcolando la media delle normali delle facce.

    + +

    [method:this copy]( [param:BufferGeometry bufferGeometry] )

    +

    Copia un'altra BufferGeometry in questa BufferGeometry.

    + +

    [method:BufferAttribute deleteAttribute]( [param:String name] )

    +

    Cancella l'[page:BufferAttribute attributo] con il nome specificato.

    + +

    [method:undefined dispose]()

    +

    + Elimina l'oggetto dalla memoria.
    + È necessario chiamarlo quando si desidera rimuovere BufferGeometry mentre l'applicazione è in esecuzione. +

    + +

    [method:BufferAttribute getAttribute]( [param:String name] )

    +

    Restituisce l'[page:BufferAttribute attributo] con il nome specificato.

    + +

    [method:BufferAttribute getIndex] ()

    +

    Restituisce il buffer di [page:.index].

    + +

    [method:Boolean hasAttribute]( [param:String name] )

    +

    Restituisce `true` se l'attributo con il nome specificato esiste.

    + +

    [method:this lookAt] ( [param:Vector3 vector] )

    +

    + vector - Un vettore world da guardare.

    + + Ruota la geometria in modo che sia rivolta verso un punto dello spazio. In genere, questa operazione viene + eseguita una sola volta e non durante un ciclo. + Usare [page:Object3D.lookAt] per l'uso tipico della mesh in tempo reale. +

    + +

    [method:undefined normalizeNormals]()

    +

    + Ogni vettore normale, in una geometria, deve avere magnitudine 1. + Ciò correggerà l'illuminazione sulle superfici geometriche. +

    + +

    [method:this rotateX] ( [param:Float radians] )

    +

    + Ruota la geometria attorno all'asse X. In genere, questa operazione viene eseguita una sola volta e non durante un ciclo. + Usare [page:Object3D.rotation] per la tipica rotazione della mesh in tempo reale. +

    + +

    [method:this rotateY] ( [param:Float radians] )

    +

    + Ruota la geometria attorno all'asse Y. In genere, questa operazione viene eseguita una sola volta e non durante un ciclo. + Usare [page:Object3D.rotation] per la tipica rotazione della mesh in tempo reale. +

    + +

    [method:this rotateZ] ( [param:Float radians] )

    +

    + Ruota la geometria attorno all'asse Z. In genere, questa operazione viene eseguita una sola volta e non durante un ciclo. + Usare [page:Object3D.rotation] per la tipica rotazione della mesh in tempo reale. +

    + +

    [method:this scale] ( [param:Float x], [param:Float y], [param:Float z] )

    +

    + Scala i dati della geometria. In genere, questa operazione viene eseguita una sola volta e non durante un ciclo. + Usare [page:Object3D.scale] per il tipico ridimensionamento della mesh in tempo reale. +

    + +

    [method:this setAttribute]( [param:String name], [param:BufferAttribute attribute] )

    +

    + Imposta un attributo per questa geometria. Utilizzare questo metodo piuttosto che la proprietà attributes, + perché viene mantenuta una hashmap interna di .attributes per accelerare l'iterazione sugli attributi. +

    + +

    [method:undefined setDrawRange] ( [param:Integer start], [param:Integer count] )

    +

    + Imposta la proprietà [page:.drawRange]. Per BufferGeometry non indicizzate, count è il numero di vertici da visualizzare. + Per BufferGeometry indicizzate, count è il numero di indici da visualizzare. +

    + +

    [method:this setFromPoints] ( [param:Array points] )

    +

    Imposta gli attributi per questa BufferGeometry da un array di punti.

    + +

    [method:this setIndex] ( [param:BufferAttribute index] )

    +

    Imposta il buffer [page:.index].

    + +

    [method:Object toJSON]()

    +

    Converte la buffer geometry al formato three.js [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene].

    + +

    [method:BufferGeometry toNonIndexed]()

    +

    Restituisce una versione non indicizzata di una BufferGeometry indicizzata.

    + +

    [method:this translate] ( [param:Float x], [param:Float y], [param:Float z] )

    +

    + Trasla la geometria. In genere, questa operazione viene eseguita una sola volta e non durante un ciclo. + Usare [page:Object3D.position] per la tipica traslazione della mesh in tempo reale. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/core/Clock.html b/docs/api/it/core/Clock.html new file mode 100644 index 00000000000000..3d3aec55a15501 --- /dev/null +++ b/docs/api/it/core/Clock.html @@ -0,0 +1,82 @@ + + + + + + + + + +

    [name]

    + +

    + Oggetto per tenere traccia del tempo. Questa classe utilizza [link:https://developer.mozilla.org/en-US/docs/Web/API/Performance/now performance.now] + se disponibile, altrimenti utilizza il meno accurato [link:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/now Date.now]. +

    + +

    Costruttore

    + +

    [name]( [param:Boolean autoStart] )

    +

    + autoStart — (opzionale) indica se avviare automaticamente l'orologio quando .getDelta() viene chiamato per la prima volta. L'impostazione predefinita è `true`. +

    + +

    Proprietà

    + +

    [property:Boolean autoStart]

    +

    + Se impostato, avvia l'orologio automaticamente quando [page:.getDelta]() viene chiamato per la prima volta. Il valore predefinito è `true`. +

    + +

    [property:Float startTime]

    +

    + Contiene il tempo al quale è stato chiamato l'ultima volta il metodo [page:Clock.start start] dell'orologio. Il valore predefinito è `0`. +

    + +

    [property:Float oldTime]

    +

    + Contiene il tempo in cui i metodi [page:Clock.start start], [page:.getElapsedTime]() o [page:.getDelta]() dell'orologio sono stati chiamati per l'ultima volta. + Il valore predefinito è `0`. +

    + +

    [property:Float elapsedTime]

    +

    + Tiene traccia del tempo totale di esecuzione dell'orologio. Il valore predefinito è `0`. +

    + +

    [property:Boolean running]

    +

    + Indica se l'orologio è in esecuzione o meno. Il valore predefinito è `false`. +

    + +

    Metodi

    + +

    [method:undefined start]()

    +

    + Avvia l'orologio. Inoltre imposta [page:.startTime] e [page:.oldTime] sull'ora corrente, imposta [page:.elapsedTime] a `0` e [page:.running] a `true`. +

    + +

    [method:undefined stop]()

    +

    + Ferma l'orologio e imposta [page:Clock.oldTime oldTime] sull'ora corrente. +

    + +

    [method:Float getElapsedTime]()

    +

    + Ottiene i secondi trascorsi da quando l'orologio è stato avviato e imposta [page:.oldTime] sull'ora corrente.
    + Se [page:.autoStart] è `true` e l'orologio non è in esecuzione, avvia anche l'orologio. +

    + +

    [method:Float getDelta]()

    +

    + Ottiene i secondi trascorsi dall'ora in cui è stato impostato [page:.oldTime] e imposta [page:.oldTime] sull'ora corrente.
    + Se [page:.autoStart] è `true` e l'orologio non è in esecuzione, avvia anche l'orologio. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/core/EventDispatcher.html b/docs/api/it/core/EventDispatcher.html new file mode 100644 index 00000000000000..a02b85be31e267 --- /dev/null +++ b/docs/api/it/core/EventDispatcher.html @@ -0,0 +1,97 @@ + + + + + + + + + +

    [name]

    + +

    + Eventi JavaScript per oggetti personalizzati.
    + [link:https://github.com/mrdoob/eventdispatcher.js EventDispatcher on GitHub] +

    + +

    Codice di Esempio

    + + + // Aggiungere eventi ad un oggetto custom + + class Car extends EventDispatcher { + + start() { + + this.dispatchEvent( { type: 'start', message: 'vroom vroom!' } ); + + } + + }; + + // Usare gli eventi con l'oggetto custom + + const car = new Car(); + + car.addEventListener( 'start', function ( event ) { + + alert( event.message ); + + } ); + + car.start(); + + +

    Costruttore

    + +

    [name]()

    +

    + Crea un oggetto EventDispatcher. +

    + + +

    Metodi

    + +

    [method:undefined addEventListener]( [param:String type], [param:Function listener] )

    +

    + type - Il tipo di evento da ascoltare.
    + listener - La funzione che viene chiamata quando viene generato l'evento. +

    +

    + Aggiunge un listener ad un tipo di evento. +

    + +

    [method:Boolean hasEventListener]( [param:String type], [param:Function listener] )

    +

    + type - Il tipo di evento da ascoltare.
    + listener - La funzione che viene chiamata quando viene generato l'evento. +

    +

    + Verifica se il listener è aggiunto ad un tipo di evento. +

    + +

    [method:undefined removeEventListener]( [param:String type], [param:Function listener] )

    +

    + type - Il tipo di listener che viene rimosso.
    + listener - La funzione listener che viene rimossa. +

    +

    + Rimuove un listener da un tipo di evento. +

    + +

    [method:undefined dispatchEvent]( [param:Object event] )

    +

    + event - L'evento che viene lanciato. +

    +

    + Lancia un tipo di evento. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/core/GLBufferAttribute.html b/docs/api/it/core/GLBufferAttribute.html new file mode 100644 index 00000000000000..31ab9aae12b144 --- /dev/null +++ b/docs/api/it/core/GLBufferAttribute.html @@ -0,0 +1,115 @@ + + + + + + + + + +

    [name]

    + +

    + Questa classe di attributi del buffer non costruisce un VBO. Invece, + utilizza qualsiasi VBO che gli viene passato nel costruttore e può essere + successivamente alterato tramite la proprietà `buffer`.

    + È necessario passare parametri aggiuntivi insieme a VBO. I quali sono: + il contesto GL, il tipo di dati GL, il numero di componenti per vertice, + il numero di byte per componente, e il numero di vertici.

    + Il caso d'uso più comune per questa classe è quando un qualche tipo di + calcolo GPGPU interferisce o addirittura produce i VBO in questione. +

    + +

    Costruttore

    +

    [name]( [param:WebGLBuffer buffer], [param:GLenum type], [param:Integer itemSize], [param:Integer elementSize], [param:Integer count] )

    +

    + `buffer` — Deve essere un WebGLBuffer. +
    + `type` — Uno dei Tipi di dati WebGL. +
    + `itemSize` — Il numero dei valori dell'array che devono essere associati con un particolare vertice. Ad esempio, + se questo attributo memorizza un vettore a 3 componenti (come una posizione, una normale, un colore), allora itemSize dovrebbe essere 3. +
    + `elementSize` — 1, 2 o 4. La dimensione corrispondente (in byte) per il parametro "type" passato. +

      +
    • gl.FLOAT: 4
    • +
    • gl.UNSIGNED_SHORT: 2
    • +
    • gl.SHORT: 2
    • +
    • gl.UNSIGNED_INT: 4
    • +
    • gl.INT: 4
    • +
    • gl.BYTE: 1
    • +
    • gl.UNSIGNED_BYTE: 1
    • +
    + `count` — Il numero previsto di vertici in VBO. +

    + +

    Proprietà

    + +

    [property:WebGLBuffer buffer]

    +

    + L'istanza corrente di WebGLBuffer. +

    + +

    [property:Integer count]

    +

    + Il numero previsto di vertici in VBO. +

    + +

    [property:Integer itemSize]

    +

    + Quanti valori compongono ogni elemento (vertice). +

    + +

    [property:Integer elementSize]

    +

    + Memorizza la dimensione corrispondente in byte per il valore della proprietà del `type` corrente. +

    +

    + Vedi sopra (costruttore) per un elenco di dimensioni di type conosciute. +

    + +

    [property:GLenum type]

    +

    + Un WebGL Data Type + che descrive i contenuti VBO. +

    +

    + Imposta questa proprietà insieme a `elementSize`. Il modo consigliato è + di usare il metodo `setType`. +

    + +

    [property:Boolean isGLBufferAttribute]

    +

    + Solo lettura. Sempre `true`. +

    + +

    Metodi

    + +

    [method:this setBuffer]( buffer )

    +

    Imposta la proprietà `buffer`.

    + +

    [method:this setType]( type, elementSize )

    +

    Imposta entrambe le proprietà `type` e `elementSize`.

    + +

    [method:this setItemSize]( itemSize )

    +

    Imposta la proprietà `itemSize`.

    + +

    [method:this setCount]( count )

    +

    Imposta la proprietà `count`.

    + +

    [property:Integer version]

    +

    + Un numero di versione, incrementato ogni volta che la proprietà needsUpdate è impostata a true. +

    + +

    [property:Boolean needsUpdate]

    +

    + Il valore predefinito è `false`. Impostando questo metodo a true incrementa la [page:GLBufferAttribute.version versione]. +

    + +

    Source

    +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/core/InstancedBufferAttribute.html b/docs/api/it/core/InstancedBufferAttribute.html new file mode 100644 index 00000000000000..a260e610d23250 --- /dev/null +++ b/docs/api/it/core/InstancedBufferAttribute.html @@ -0,0 +1,43 @@ + + + + + + + + + + [page:BufferAttribute] → + +

    [name]

    + +

    + Una versione istanziata di [page:BufferAttribute]. +

    + +

    Costruttore

    +

    [name]( [param:TypedArray array], [param:Integer itemSize], [param:Boolean normalized], [param:Number meshPerAttribute] )

    +

    +

    + +

    Proprietà

    +

    Vedi [page:BufferAttribute] per le prorietà ereditate.

    + +

    [property:Number meshPerAttribute]

    +

    + Definisce la frequenza con cui un valore di questo attributo del buffer deve essere ripetuto. + Un valore di uno significa che ogni valore dell'attributo istanziato è usato per una singola istanza. + Un valore di due significa che ogni valore è utilizzato per due istanze consecutive (e così via). + Il valore predefinito è `1`. +

    + +

    Metodi

    +

    Vedi [page:BufferAttribute] per i metodi ereditati.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/core/InstancedBufferGeometry.html b/docs/api/it/core/InstancedBufferGeometry.html new file mode 100644 index 00000000000000..c8a64285a9f5a5 --- /dev/null +++ b/docs/api/it/core/InstancedBufferGeometry.html @@ -0,0 +1,48 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    + Una versione istanziata di [page:BufferGeometry]. +

    + +

    Costruttore

    +

    [name]( )

    +

    +

    + +

    Properties

    +

    Vedi [page:BufferGeometry] per le prorietà ereditate.

    + +

    [property:Number instanceCount]

    +

    + Il valore predefinito è `Infinity`. +

    + +

    [property:Boolean isInstancedBufferGeometry]

    +

    + Flag di sola lettura per verificare se un dato oggetto è di tipo [name]. +

    + +

    Metodi

    +

    Vedi [page:BufferGeometry] per i metodi ereditati.

    + +

    [method:this copy]( [param:InstancedBufferGeometry source] )

    +

    Copia l'oggetto [name] specificato in questa istanza.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/core/InstancedInterleavedBuffer.html b/docs/api/it/core/InstancedInterleavedBuffer.html new file mode 100644 index 00000000000000..2fbab00c79a990 --- /dev/null +++ b/docs/api/it/core/InstancedInterleavedBuffer.html @@ -0,0 +1,44 @@ + + + + + + + + + + [page:InterleavedBuffer] → + +

    [name]

    + +

    + Una versione istanziata di [page:InterleavedBuffer]. +

    + +

    Costruttore

    +

    [name]( [param:TypedArray array], [param:Integer itemSize], [param:Number meshPerAttribute] )

    +

    +

    + +

    Proprietà

    +

    + Vedi [page:InterleavedBuffer] per le prorietà ereditate. +

    + +

    [property:Number meshPerAttribute]

    +

    + Il valore predefinito è `1`. +

    + +

    Metodi

    +

    + Vedi [page:InterleavedBuffer] per i metodi ereditati. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/core/InterleavedBuffer.html b/docs/api/it/core/InterleavedBuffer.html new file mode 100644 index 00000000000000..0985f458868b16 --- /dev/null +++ b/docs/api/it/core/InterleavedBuffer.html @@ -0,0 +1,116 @@ + + + + + + + + + +

    [name]

    + +

    + "Interleaved" significa che più attributi, possibilmente di tipo differente, (ad esempio, posizione, normale, uv, colore) + sono impacchettati in un unico array buffer. +

    + Qui trovi un'introduzione agli array interleaved: [link:https://blog.tojicode.com/2011/05/interleaved-array-basics.html Interleaved array basics] +

    + +

    Esempi

    + +

    [example:webgl_buffergeometry_points_interleaved webgl / buffergeometry / points / interleaved]

    + +

    Costruttore

    +

    [name]( [param:TypedArray array], [param:Integer stride] )

    +

    + [page:TypedArray array] -- Un array tipizzato con un buffer condiviso. Memorizza i dati della geometria.
    + [page:Integer stride] -- Il numero di elementi typed-array per vertice. +

    + +

    Proprietà

    + +

    [property:Array array]

    +

    + Un array tipizzato con un buffer condiviso. Memorizza i dati della geometria. +

    + +

    [property:Integer stride]

    +

    + Il numero di elementi typed-array per vertice. +

    + +

    [property:Integer count]

    +

    + Fornisce il numero totale di elementi in un array. +

    + +

    [property:Object updateRange]

    +

    + Oggetto contente offset e count.
    + - [page:Number offset]: Il valore predefinito è `0`.
    + - [page:Number count]: Il valore predefinito è `-1`.
    +

    + +

    [property:String uuid]

    +

    + [link:http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] di questa istanza. Viene automaticamente assegnato, non deve essere modificato. +

    + +

    [property:Integer version]

    +

    + Un numero di versione, incrementato ogni volta che la proprietà needsUpdate è impostata a true. +

    + +

    [property:Boolean needsUpdate]

    +

    + Il valore predefinito è `false`.Impostando questo valore a true incrementa la [page:InterleavedBuffer.version versione]. +

    + +

    [property:Usage usage]

    +

    + Definisce il modello di utilizzo previsto dell'archivio dati a fini di ottimizzazione. Corrisponde al parametro di utilizzo di + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData WebGLRenderingContext.bufferData](). +

    + +

    Metodi

    + +

    [method:this copy]( [param:InterleavedBuffer source] )

    +

    + Copia un altro [name] in questo [name]. +

    + +

    [method:this copyAt]( [param:Integer index1], [param:InterleavedBuffer attribute], [param:Integer index2] )

    +

    Copia i dati da `attribute[index2]` a [page:InterleavedBuffer.array array][index1].

    + +

    [method:this set]( [param:TypedArray value], [param:Integer offset] )

    +

    + value - L'array (tipizzato) di origine.
    + offset - L'offset nell'array di destinazione in corrrispondenza del quale iniziare a scrivere i valori dall'array di origine. L'impostazione predefinita è `0`.

    + + Memorizza più valori nel buffer, leggendo valori di input dall'array specificato. +

    + +

    [method:InterleavedBuffer clone]( [param:Object data] )

    +

    + data - Questo oggetto contiene buffer di array condivisi necessari per clonare correttamente le geometrie con attributi interleaved.

    + + Crea un clone di questo [name]. +

    + +

    [method:this setUsage] ( [param:Usage value] )

    +

    Imposta [page:InterleavedBuffer.usage usage] a value.

    + +

    [method:Object toJSON]( [param:Object data] )

    +

    + data - Questo oggetto contiene buffer di array condivisi necessari per serializzare correttamente le geometrie con attributi interleaved.

    + + Serializza questo [name]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/core/InterleavedBufferAttribute.html b/docs/api/it/core/InterleavedBufferAttribute.html new file mode 100644 index 00000000000000..94b9d580b76f9c --- /dev/null +++ b/docs/api/it/core/InterleavedBufferAttribute.html @@ -0,0 +1,125 @@ + + + + + + + + + + +

    [name]

    + +

    + +

    + +

    Costruttore

    +

    [name]( [param:InterleavedBuffer interleavedBuffer], [param:Integer itemSize], [param:Integer offset], [param:Boolean normalized] )

    +

    +

    + +

    Proprietà

    + +

    [property:InterleavedBuffer data]

    +

    + L'istanza [page:InterleavedBuffer InterleavedBuffer] passata nel costruttore. +

    + +

    [property:TypedArray array]

    +

    + Il valore di [page:InterleavedBufferAttribute.data data].array. +

    + +

    [property:Integer count]

    +

    + Il valore di [page:InterleavedBufferAttribute.data data].count. + + Se il buffer memorizza un elemento a 3 componenti (come una posizione, una normale, o un colore), + allora questo conterà il numero di ogni elemento memorizzato. +

    + +

    [property:Boolean isInterleavedBufferAttribute]

    +

    + Flag di sola lettura per verificare se un dato oggetto è di tipo [name]. +

    + +

    [property:Integer itemSize]

    +

    + Quanti valori compongono ogni elemento (vertice). +

    + +

    [property:String name]

    +

    + Nome opzionale per questa istanza dell'attributo. Il valore di default è una stringa vuota. +

    + +

    [property:Boolean needsUpdate]

    +

    + Il valore predefinito è `false`. Impostando questa proprietà a `true` invierà di nuovo l'intero + buffer interleaved (non solo i dati dello specifico attributo) alla GPU. +

    + +

    [property:Boolean normalized]

    +

    + Il valore predefinito è `false`. +

    + +

    [property:Integer offset]

    +

    + L'offset nel buffer dell'array sottostante in cui inizia un elemento. +

    + +

    Metodi

    + +

    [method:this applyMatrix4]( [param:Matrix4 m] )

    +

    Applica la matrice [page:Matrix4 m] ad ogni elemento Vector3 di questo InterleavedBufferAttribute.

    + +

    [method:this applyNormalMatrix]( [param:Matrix3 m] )

    +

    Applica la matrice [page:Matrix3 m] ad ogni elemento Vector3 di questo InterleavedBufferAttribute.

    + +

    [method:this transformDirection]( [param:Matrix4 m] )

    +

    Applica la matrice [page:Matrix4 m] ad ogni elemento Vector3 di questo InterleavedBufferAttribute, interpretando gli elementi come vettori direzionali.

    + +

    [method:Number getX]( [param:Integer index] )

    +

    Restituisce il componente x dell'elemento in corrispondenza dell'indice specificato.

    + +

    [method:Number getY]( [param:Integer index] )

    +

    Restituisce il componente y dell'elemento in corrispondenza dell'indice specificato.

    + +

    [method:Number getZ]( [param:Integer index] )

    +

    Restituisce il componente z dell'elemento in corrispondenza dell'indice specificato.

    + +

    [method:Number getW]( [param:Integer index] )

    +

    Restituisce il componente w dell'elemento in corrispondenza dell'indice specificato.

    + +

    [method:this setX]( [param:Integer index], [param:Float x] )

    +

    Imposta il componente x dell'elemento in corrispondenza dell'indice specificato.

    + +

    [method:this setY]( [param:Integer index], [param:Float y] )

    +

    Imposta il componente y dell'elemento in corrispondenza dell'indice specificato.

    + +

    [method:this setZ]( [param:Integer index], [param:Float z] )

    +

    Imposta il componente z dell'elemento in corrispondenza dell'indice specificato.

    + +

    [method:this setW]( [param:Integer index], [param:Float w] )

    +

    Imposta il componente w dell'elemento in corrispondenza dell'indice specificato.

    + +

    [method:this setXY]( [param:Integer index], [param:Float x], [param:Float y] )

    +

    Imposta i componenti x e y dell'elemento in corrispondenza dell'indice specificato.

    + +

    [method:this setXYZ]( [param:Integer index], [param:Float x], [param:Float y], [param:Float z] )

    +

    Imposta i componenti x, y e z dell'elemento in corrispondenza dell'indice specificato.

    + +

    [method:this setXYZW]( [param:Integer index], [param:Float x], [param:Float y], [param:Float z], [param:Float w] )

    +

    Imposta i componenti x, y, z e w dell'elemento in corrispondenza dell'indice specificato.

    + + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/core/Layers.html b/docs/api/it/core/Layers.html new file mode 100644 index 00000000000000..bcb501e6238515 --- /dev/null +++ b/docs/api/it/core/Layers.html @@ -0,0 +1,105 @@ + + + + + + + + + +

    [name]

    + +

    + Un oggetto [page:Layers] assegna un [page:Object3D] a 1 o più di 32 layer numerati da `0` a `31` + - internamente i layer sono memorizzati come una [link:https://en.wikipedia.org/wiki/Mask_(computing) maschera di bit], + e, per impostazione predefinita, tutti gli Object3D sono membri del leyer 0.

    + + Può essere utilizzato per controllare la visibilità - un oggetto deve condividere un layer con una [page:Camera telecamera] per + essere visibile quando la vista della telecamera viene renderizzata.

    + + Tutte le classi che ereditano da [page:Object3D] hanno una proprietà [page:Object3D.layers] che è un'istanza della classe. +

    + +

    Esempi

    + +

    + [example:webgl_layers WebGL / layers] +

    + +

    Costruttore

    + + +

    [name]()

    +

    + Crea un nuovo oggetto Layers, con l'appartenenza inizialmente impostata al layer 0. +

    + +

    Proprietà

    + +

    [property:Integer mask]

    +

    + Una maschera di bit che memorizza a quale dei 32 layer questo oggetto layer è attualmente membro. +

    + + +

    Metodi

    + +

    [method:undefined disable]( [param:Integer layer] )

    +

    + layer - un intero da 0 a 31.

    + + Elimina l'appartenenza a questo `layer`. +

    + +

    [method:undefined enable]( [param:Integer layer] )

    +

    + layer - un intero da 0 a 31.

    + + Aggiunge l'appartenenza a questo `layer`. +

    + +

    [method:undefined set]( [param:Integer layer] )

    +

    + layer - un intero da 0 a 31.

    + + Imposta l'appartenza a `layer`, e rimuove l'appartenza a tutti gli altri layer. +

    + +

    [method:Boolean test]( [param:Layers layers] )

    +

    + layers - un oggetto Layers

    + + Restituisce true se questo e l'oggetto `layers` passato hanno al più un layer in comune. +

    + +

    [method:Boolean isEnabled]( [param:Integer layer] )

    +

    + layer - un intero da 0 a 31.

    + + Restituisce true se il dato layer è abilitato. +

    + +

    [method:undefined toggle]( [param:Integer layer] )

    +

    + layer - un intero da 0 a 31.

    + + Attiva/disattiva l'appartenenza al `layer`. +

    + +

    [method:undefined enableAll]()

    +

    + Aggiunge l'appartenza a tutti i layer. +

    + +

    [method:undefined disableAll]()

    +

    + Rimuove l'appartenenza da tutti i layer. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/core/Object3D.html b/docs/api/it/core/Object3D.html new file mode 100644 index 00000000000000..aecef5d3f4241b --- /dev/null +++ b/docs/api/it/core/Object3D.html @@ -0,0 +1,500 @@ + + + + + + + + + +

    [name]

    + +

    + Questa è la classe base di molti oggetti in three.js e fornisce un insieme di proprietà e metodi + per manipolare gli oggetti 3D nello spazio.

    + + Si noti che questa classe può essere utilizzata per raggruppare gli oggetti tramite il metodo + [page:.add]( object ) il quale aggiunge l'oggetto come figlio, tuttavia è meglio usare [page:Group] per questo. +

    + + +

    Costruttore

    + + +

    [name]()

    +

    + Il cotruttore non prende argomenti. +

    + + +

    Proprietà

    + +

    [property:AnimationClip animations]

    +

    Array con clip di animazione dell'oggetto.

    + +

    [property:Boolean castShadow]

    +

    Se l'oggetto viene renderizzato nella mappa delle ombre. Il valore predefinito è `false`.

    + +

    [property:Array children]

    +

    Array con i children dell'oggetto. Vedi [page:Group] per informazioni su come raggrupare manualmente gli oggetti.

    + +

    [property:Material customDepthMaterial]

    +

    + Materiale depth personalizzato da utilizzare durante il rendering della mappa di depth. Può essere utilizzato solo nel contesto delle mesh. + Quando si proietta un'ombra con [page:DirectionalLight] o [page:SpotLight], se si modificano le posizioni dei vertici nello shader dei vertici + è necessario specificare un customDepthMaterial per le shadow corrette. Il valore predefinito è `undefined`. +

    + +

    [property:Material customDistanceMaterial]

    +

    + Lo stesso di [page:.customDepthMaterial customDepthMaterial], ma viene utilizzato con [page:PointLight]. + Il valore predefinito è `undefined`. +

    + +

    [property:Boolean frustumCulled]

    +

    + Quando questo è impostato, controlla ogni fotogramma, se l'oggetto è nel frustrum della telecamera prima renderizzare l'oggetto. + Se è impostato a `false` l'oggetto viene renderizzato ad ogni fotogramma anche se non si trova nel frustrum della telecamera. + Il valore predefinito è `true`. +

    + +

    [property:Integer id]

    +

    sola lettura – Numero univoco per questa istanza.

    + +

    [property:Boolean isObject3D]

    +

    + Flag di sola lettura per controllare se un dato oggetto è di tipo [name]. +

    + +

    [property:Layers layers]

    +

    + Il layer di appartenenza dell'oggetto. L'oggetto è visibile solo se ha al più un layer in comune + con la [page:Camera telecamera] utilizzata. Questa proprietà può anche essere utilizata per filtrare + gli oggetti non voluti nell'intersezione di test del reycasting quando si usa il [page:Raycaster]. +

    + +

    [property:Matrix4 matrix]

    +

    La matrice di trasformazione locale.

    + +

    [property:Boolean matrixAutoUpdate]

    +

    + Quando viene settato calcola la matrice di posizione, (rotazione o quaternione) e + ridimensiona ogni fotogramma ed inoltre ricalcola la proprietà matrixWorld. L'impostazione predefinita è [page:Object3D.DefaultMatrixAutoUpdate] (true). +

    + +

    [property:Matrix4 matrixWorld]

    +

    + La trasformazione globale dell'oggetto. Se l'Object3D non ha un genitore, è identico al [page:.matrix] della trasformazione locale. +

    + +

    [property:Boolean matrixWorldAutoUpdate]

    +

    + Il valore predefinito è true. Se impostato, il renderer controlla ogni frame se l'oggetto e i suo figli + necessitano di aggiornare la matrice. + Quando non lo è, devi mantenere tu stesso tutte le matrici nell'oggetto e i suoi figli. +

    + +

    [property:Boolean matrixWorldNeedsUpdate]

    +

    + Quando viene settato calcola la matrixWorld in quel frame e reimposta questa proprietà a false. Il valore + predefinito è `false`. +

    + +

    [property:Matrix4 modelViewMatrix]

    +

    Questo viene passato allo shader e utilizzato per calcolare la posizione dell'oggetto.

    + +

    [property:String name]

    +

    Nome opzionale dell'oggetto (non è necessario che sia univoco). Il valore predefinito è una stringa vuota.

    + +

    [property:Matrix3 normalMatrix]

    +

    + Questo viene passato allo shader e utilizzato per calcolare l'illuminazione per l'oggetto. + È la trasposizione dell'inverso della sottomatrice 3x3 in alto a sinistra di modelViewMatrix di questo oggetto.

    + + Il motivo di questa matrice speciale è che il semplice utilizzo della matrice modelViewMatrix potrebbe causare una lunghezza non unitaria delle normali + (in caso di scalatura) o una direzione non perpendicolare (in caso di scalatura non uniforme).

    + + Dall'altra parte, la parte di traslazione della matrice modelViewMatrix non è rilevante per il calcolo delle normali. Quindi una Matrix3 è sufficiente. +

    + +

    [property:Function onAfterRender]

    +

    + Una callback opzionale che viene eseguita immediatamente dopo che un oggetto 3D è stato renderizzato. + Questa funzione è chiamata con i seguenti parametri: renderer, scene, camera, geometry, material, group. +

    +

    + Si noti che questa funzione di callback viene eseguita per oggi 3D `renderizzabili` (renderable). Ovvero oggetti 3D che definiscono + il loro aspetto visivo con geometrie e materiali come istanze di [page:Mesh], [page:Line], [page:Points] o [page:Sprite]. + Invece, le istanze di [page:Object3D], [page:Group] o [page:Bone] non sono renderizzabili e quindi questa callback non viene eseguita su questi oggetti. +

    + +

    [property:Function onBeforeRender]

    +

    + Una callback opzionale che viene eseguita immediatamente prima che un oggetto 3D è stato renderizzato. + Questa funzione è chiamata con i seguenti parametri: renderer, scene, camera, geometry, material, group. +

    +

    + Si noti che questa funzione di callback viene eseguita per oggi 3D `renderizzabili` (renderable). Ovvero oggetti 3D che definiscono + il loro aspetto visivo con geometrie e materiali come istanze di [page:Mesh], [page:Line], [page:Points] o [page:Sprite]. + Invece, le istanze di [page:Object3D], [page:Group] o [page:Bone] non sono renderizzabili e quindi questa callback non viene eseguita su questi oggetti. +

    + +

    [property:Object3D parent]

    +

    Genitore dell'oggetto nel [link:https://en.wikipedia.org/wiki/Scene_graph grafo della scena]. Un oggetto può avere più + di un genitore.

    + +

    [property:Vector3 position]

    +

    Un [page:Vector3] che rappresenta la posizione locale dell'oggetto. Il valore predefinito è `(0, 0, 0)`.

    + +

    [property:Quaternion quaternion]

    +

    Rotazione locale dell'oggetto come un [page:Quaternion Quaternion].

    + +

    [property:Boolean receiveShadow]

    +

    Se il materiale riceve ombre. Il valore predefinito è `false`.

    + +

    [property:Number renderOrder]

    +

    + Questo valore consente di sovrascrivere l'ordine di rendering predefinito degli oggetti del [link:https://en.wikipedia.org/wiki/Scene_graph grafico di scena] + sebbene gli oggetti opachi e trasparenti rimangano ordinati in modo indipendente. Quando questa proprietà viene impostata per un'istanza di [page:Group Group], + tutti gli oggetti discendenti saranno ordinati e renderizzati insieme. + L'ordinamento è dal più piccolo al più grande renderOrder. Il valore predefinito è `0`. +

    + +

    [property:Euler rotation]

    +

    + La rotazione locale dell'oggetto (vedi [link:https://en.wikipedia.org/wiki/Euler_angles gli angoli di Eulero]), in radianti. +

    + +

    [property:Vector3 scale]

    +

    + La scala locale dell'oggetto. Il valore predefinito è [page:Vector3]( 1, 1, 1 ). +

    + +

    [property:Vector3 up]

    +

    + Questa proprietà viene utilizzata dal metodo [page:.lookAt lookAt], per esempio, per determinare l'orientamento del risultato.
    + L'impostazione predefinita è [page:Object3D.DefaultUp] - che è, `( 0, 1, 0 )`. +

    + +

    [property:Object userData]

    +

    + Un oggetto che può essere utilizzato per memorizzare i dati personalizzati di un Object3D. + Non dovrebbe contenere riferimenti a funzioni poiché queste non verranno clonate. +

    + +

    [property:String uuid]

    +

    + [link:http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] dell'istanza dell'oggetto. + Viene assegnato automaticamente, non dovrebbe essere modificato. +

    + +

    [property:Boolean visible]

    +

    L'oggetto viene visualizzato se `true`. Il valore predefinito è `true`.

    + + + + +

    Proprietà Statiche

    +

    + Le proprietà statiche e i metodi sono definiti per classe piuttosto che per istanza della classe. + Questo significa che modificando [page:Object3D.DefaultUp] o [page:Object3D.DefaultMatrixAutoUpdate] + verranno modificati i valori di [page:.up up] e [page:.matrixAutoUpdate matrixAutoUpdate] per `ogni` + istanza di Object3D (o classi derivate) creata dopo che la modifica è stata fatta + (gli Object3D già creati non saranno interessati). +

    + +

    [property:Vector3 DefaultUp]

    +

    + La direzione predefinita di [page:.up up] per gli oggetti, utilizzata anche come posizione predefinita per [page:DirectionalLight], + [page:HemisphereLight] e [page:Spotlight] (che crea luci che brillano dall'alto verso il basso).
    + Impostare su ( 0, 1, 0 ) per impostazione predefinita. +

    + +

    [property:Boolean DefaultMatrixAutoUpdate]

    +

    + L'impostazione predefinita per [page:.matrixAutoUpdate matrixAutoUpdate] per Object3D appena creati.
    +

    + + +

    Metodi

    + +

    I metodi [page:EventDispatcher EventDispatcher] sono disponibili in questa classe.

    + +

    [method:this add]( [param:Object3D object], ... )

    +

    + Aggiunge l'`object` come figlio di questo oggetto. È possibile aggiungere un numero arbitrario di oggetti. + Qualsiasi genitore corrente su un oggetto passato qui verrà rimosso, poiché un oggetto può avere al più un genitore.

    + + Vedi [page:Group] per avere informazioni per raggruppare manualmente gli oggetti. +

    + +

    [method:undefined applyMatrix4]( [param:Matrix4 matrix] )

    +

    Applica la matrice di trasformazione all'oggetto e aggiorna la posizione, la rotazione e la scala dell'oggetto.

    + +

    [method:this applyQuaternion]( [param:Quaternion quaternion] )

    +

    Applica la rotazione rappresentata dal quaternione dell'oggetto.

    + +

    [method:this attach]( [param:Object3D object] )

    +

    + Aggiunge l'`object` come figlio di questo oggetto, mantenendo la trasformazione world dell'oggetto.

    + Nota: Questo metodo non supporta i grafici della scena con nodi con scalatura non uniforme. +

    + +

    [method:Object3D clone]( [param:Boolean recursive] )

    +

    + recursive -- se true, anche i discendenti dell'oggetto vengono clonati. Il valore predefinito è true.

    + + Restituisce un clone di questo oggetto e opzionalmente tutti i discendenti. +

    + +

    [method:this copy]( [param:Object3D object], [param:Boolean recursive] )

    +

    + recursive -- se true, anche i discendenti dell'oggetto vengono copiati. Il valore predefinito è true.

    + + Copia l'oggetto passato in questo oggetto. + + Nota: Gli event listener e le callback definite dall'utente ([page:.onAfterRender] e [page:.onBeforeRender]) non vengono copiate. +

    + +

    [method:Object3D getObjectById]( [param:Integer id] )

    +

    + id -- Numero univoco dell'istanza dell'oggetto

    + + Cerca in un oggetto e nei suoi figli, partendo dall'oggetto stesso, e restituisce il primo con l'id corrispondente.
    + Si noti che gli id sono assegnati in ordine cronologico: 1, 2, 3, ..., incrementando di uno per ogni nuovo oggetto. +

    + +

    [method:Object3D getObjectByName]( [param:String name] )

    +

    + name -- Stringa da abbinare alla proprietà Object3D.name dei figli.

    + + Cerca in un oggetto e nei suoi figli, partendo dall'oggetto stesso, e restituisce il primo con il nome corrispondente.
    + Si noti che per molti oggetti il nome è una stringa vuota da impostazione predefinita. Dovrai impostarlo manualmente per + utilizzare questo metodo. +

    + +

    [method:Object3D getObjectByProperty]( [param:String name], [param:Any value] )

    +

    + name -- il nome della proprietà da cercare.
    + value -- il valore della proprietà data.

    + + Cerca in un oggetto e nei suoi figli, partendo dall'oggetto stesso, e restituisce il primo con la proprietà che corrisponde al valore passato. +

    + +

    [method:Vector3 getWorldPosition]( [param:Vector3 target] )

    +

    + [page:Vector3 target] — il risultato verrà copiato in questo Vector3.

    + + Restituisce un vettore che rappresenta la posizione dell'oggetto nello spazio world. +

    + +

    [method:Quaternion getWorldQuaternion]( [param:Quaternion target] )

    +

    + [page:Quaternion target] — il risultato sarà copiato in questo Quaternione.

    + + Restituisce un quaternione che rappreseta la rotazione dell'oggetto nello spazio world. +

    + +

    [method:Vector3 getWorldScale]( [param:Vector3 target] )

    +

    + [page:Vector3 target] — il risultato sarà copiato in questo Vector3.

    + + Restituisce un vettore dei fattori di scala applicati all'oggetto per ciascun asse nello spazio world. +

    + +

    [method:Vector3 getWorldDirection]( [param:Vector3 target] )

    +

    + [page:Vector3 target] — il risultato sarà copiato in questo Vector3.

    + + Restituisce un vettore che rappresenta la direzione dell'asse z positivo dell'oggetto nello spazio world. +

    + + +

    [method:Vector3 localToWorld]( [param:Vector3 vector] )

    +

    + vector - Un vettore che rappresenta la posizione nello spazio locale di questo oggetto.

    + + Converte il vettore dallo spazio locale dell'oggetto allo spazio world. +

    + +

    [method:undefined lookAt]( [param:Vector3 vector] )
    + [method:undefined lookAt]( [param:Float x], [param:Float y], [param:Float z] )

    +

    + vector - Un vettore che rappresenta la posizione nello spazio world.

    + Facoltativamente, le componenti [page:.x x], [page:.y y] e [page:.z z] della posizione nello spazio world.

    + + Ruota l'oggetto in modo che sia rivolto verso un punto nello spazio world.

    + + Questo metodo non supporta oggetti con genitore/i con scalabilità non uniforme. +

    + +

    [method:undefined raycast]( [param:Raycaster raycaster], [param:Array intersects] )

    +

    + Metodo astratto (vuoto) per ottenere le intersezioni tra un raggio casted e questo oggetto. + Sottoclassi come [page:Mesh], [page:Line], e [page:Points] implementano questo metodo per + utilizzare il raycasting. +

    + +

    [method:this remove]( [param:Object3D object], ... )

    +

    + Rimuove `object` come figlio di questo oggetto. Può essere rimosso un numero arbitrario di oggetti. +

    + +

    [method:this removeFromParent]()

    +

    + Rimuove questo oggetto dal suo attuale genitore. +

    + +

    [method:this clear]()

    +

    + Rimuove tutti i figli dall'oggetto. +

    + +

    [method:this rotateOnAxis]( [param:Vector3 axis], [param:Float angle] )

    +

    + axis -- Un vettore normalizzato nello spazio dell'oggetto.
    + angle -- L'angolo in radianti.

    + + Ruota un oggetto lungo l'asse nello spazio dell'oggetto. Si presume che l'asse sia normalizzato. +

    + +

    [method:this rotateOnWorldAxis]( [param:Vector3 axis], [param:Float angle] )

    +

    + axis -- Un vettore normalizzato nello spazio world.
    + angle -- L'angolo in radianti.

    + + Ruota un oggetto lungo l'asse nello spazio world. Si presume che l'asse sia normalizzato. + Presuppone che nessun genitore sia ruotato. +

    + +

    [method:this rotateX]( [param:Float rad] )

    +

    + rad - l'angolo di rotazione in radianti.

    + + Ruota l'oggetto attorno all'asse x nello spazio locale. +

    + +

    [method:this rotateY]( [param:Float rad] )

    +

    + rad - l'angolo di rotazione in radianti.

    + + Ruota l'oggetto attorno all'asse y nello spazio locale. +

    + +

    [method:this rotateZ]( [param:Float rad] )

    +

    + rad - l'angolo di rotazione in radianti.

    + + Ruota l'oggetto attorno all'asse z nello spazio locale. +

    + +

    [method:undefined setRotationFromAxisAngle]( [param:Vector3 axis], [param:Float angle] )

    +

    + axis -- Un vettore normalizzato nello spazio dell'oggetto.
    + angle -- l'angolo in radianti

    + + Chiama [page:Quaternion.setFromAxisAngle setFromAxisAngle]( [page:Float axis], [page:Float angle] ) + sul [page:.quaternion quaternione]. +

    + +

    [method:undefined setRotationFromEuler]( [param:Euler euler] )

    +

    + euler -- L'angolo di Eulero che specifica la quantità di rotazione.
    + + Chiama [page:Quaternion.setRotationFromEuler setRotationFromEuler]( [page:Euler euler] ) + sul [page:.quaternion quaternione]. +

    + +

    [method:undefined setRotationFromMatrix]( [param:Matrix4 m] )

    +

    + m -- ruota il quaternione della componente rotazione della matrice.
    + + Chiama [page:Quaternion.setFromRotationMatrix setFromRotationMatrix]( [page:Matrix4 m] ) + sul [page:.quaternion quaternione].

    + + Si noti che questo presuppone che il 3x3 superiore di m è una matrice di rotazione pura (cioè non ridimnsionata). +

    + +

    [method:undefined setRotationFromQuaternion]( [param:Quaternion q] )

    +

    + q -- Quaternione normalizzato.

    + + Copia il quaternione passato nel [page:.quaternion quaternione]. +

    + +

    [method:Object toJSON]( [param:Object meta] )

    +

    + meta -- oggetto contentene metadati come i materiali, le texture o le immagini per l'oggetto.
    + Converte l'oggetto al formato three.js [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene]. +

    + +

    [method:this translateOnAxis]( [param:Vector3 axis], [param:Float distance] )

    +

    + axis -- Un vettore normalizzato nello spazio dell'oggetto.
    + distance -- La distanza da traslare.

    + + Trasla un oggetto in base alla distanza lungo un asse nello spazio dell'oggetto. Questo asse si presuppone sia normalizzato. +

    + +

    [method:this translateX]( [param:Float distance] )

    +

    Trasla l'oggetto lungo l'asse x nello spazio dell'ogetto per unità di `distance`.

    + +

    [method:this translateY]( [param:Float distance] )

    +

    Trasla l'oggetto lungo l'asse y nello spazio dell'ogetto per unità di `distance`.

    + +

    [method:this translateZ]( [param:Float distance] )

    +

    Trasla l'oggetto lungo l'asse z nello spazio dell'ogetto per unità di `distance`.

    + +

    [method:undefined traverse]( [param:Function callback] )

    +

    + callback - Una funzione con primo argomento un oggetto Object3D.

    + + Esegue la callback su questo oggetto e tutti i discendenti.
    + Nota: È sconsigliato modificare il grafico della scena all'interno della callback. +

    + +

    [method:undefined traverseVisible]( [param:Function callback] )

    +

    + callback - Una funzione con primo argomento un oggetto Object3D.

    + + Simile a traverse, ma la callback viene eseguita solo su oggetti visibili. + I discendenti di oggetti invisibili non vengono attraversati.
    + Nota: È sconsigliato modificare il grafico della scena all'interno della callback. +

    + +

    [method:undefined traverseAncestors]( [param:Function callback] )

    +

    + callback - Una funzione con primo argomento un oggetto Object3D..

    + + Esegue la callback su tutti i predecessori.
    + Nota: È sconsigliato modificare il grafico della scena all'interno della callback. +

    + +

    [method:undefined updateMatrix]()

    +

    Aggiorna la trasformazione locale.

    + +

    [method:undefined updateMatrixWorld]( [param:Boolean force] )

    +

    Aggiorna la trasformazione globale di un oggetto e i suoi discendenti.

    + +

    [method:undefined updateWorldMatrix]( [param:Boolean updateParents], [param:Boolean updateChildren] )

    +

    + updateParents - aggiorna ricorsivamente la trasformazione globale dei predecessori.
    + updateChildren - aggiorna ricorsivamente la trasformazione globale dei discendenti.

    + + Aggiorna la trasformazione globale dell'oggetto. +

    + +

    [method:Vector3 worldToLocal]( [param:Vector3 vector] )

    +

    + vector - Un vettore che rappresenta una posizione nello spazio world.

    + + Converte il vettore dallo spazio world allo spazio locale di questo oggetto. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/core/Raycaster.html b/docs/api/it/core/Raycaster.html new file mode 100644 index 00000000000000..9097b5271fab50 --- /dev/null +++ b/docs/api/it/core/Raycaster.html @@ -0,0 +1,217 @@ + + + + + + + + + +

    [name]

    + +

    + Questa classe è progettata per aiutare il [link:https://en.wikipedia.org/wiki/Ray_casting raycasting]. + Il raycasting viene utilizzato, tra le altre cose, per il mouse picking (per capire su quali oggetti dello spazio 3d si trova il mouse). +

    + +

    Codice di Esempio

    + + const raycaster = new THREE.Raycaster(); + const pointer = new THREE.Vector2(); + + function onPointerMove( event ) { + + // calcolare la posizione del puntatore nelle coordinate del dispositivo normalizzate + // (-1 to +1) per entrambi i componenti + + pointer.x = ( event.clientX / window.innerWidth ) * 2 - 1; + pointer.y = - ( event.clientY / window.innerHeight ) * 2 + 1; + + } + + function render() { + + // aggiornare il raggio di picking con la telecamera e la posizione del puntatore + raycaster.setFromCamera( pointer, camera ); + + // calcolare gli oggetti intersecati dal raggio di picking + const intersects = raycaster.intersectObjects( scene.children ); + + for ( let i = 0; i < intersects.length; i ++ ) { + + intersects[ i ].object.material.color.set( 0xff0000 ); + + } + + renderer.render( scene, camera ); + + } + + window.addEventListener( 'pointermove', onPointerMove ); + + window.requestAnimationFrame(render); + + + +

    Esempi

    + +

    + [example:webgl_interactive_cubes Raycasting to a Mesh]
    + [example:webgl_interactive_cubes_ortho Raycasting to a Mesh in using an OrthographicCamera]
    + [example:webgl_interactive_buffergeometry Raycasting to a Mesh with BufferGeometry]
    + [example:webgl_instancing_raycast Raycasting to a InstancedMesh]
    + [example:webgl_interactive_lines Raycasting to a Line]
    + [example:webgl_interactive_raycasting_points Raycasting to Points]
    + [example:webgl_geometry_terrain_raycast Terrain raycasting]
    + [example:webgl_interactive_voxelpainter Raycasting to paint voxels]
    + [example:webgl_raycaster_texture Raycast to a Texture] +

    + +

    Costruttore

    + +

    [name]( [param:Vector3 origin], [param:Vector3 direction], [param:Float near], [param:Float far] )

    +

    + [page:Vector3 origin] — Il vettore di origine da cui viene proiettato il raggio.
    + [page:Vector3 direction] — Il vettore direzione che fornisce la direzione del raggio. Deve essere normalizzato.
    + [page:Float near] — Tutti i risultati restituiti sono più lontani che vicini. Near non può essere negativo. Il valore predefinito è 0.
    + [page:Float far] — Tutti i risultati ottenuti sono più vicini che lontani. Far non può essere minore di near. Il valore predefinito è Infinity. +

    +

    + Crea un nuovo oggetto raycaster.
    +

    + + +

    Proprietà

    + +

    [property:Float far]

    +

    + Il fattore `far` del raycaster. Questo valore indica quali oggetti possono essere scartati in base alla distanza. + Questo valore non dovrebbe essere negativo e deve essere maggiore del valore della proprietà `near`. +

    + +

    [property:Float near]

    +

    + Il fattore `near` del raycaster. Questo valore indica quali oggetti possono essere scartati in base alla distanza. + Questo valore non dovrebbe essere negativo e deve essere minore del valore della proprietà `far`. +

    + +

    [property:Camera camera]

    +

    + La telecamera da utilizzare durante il raycast contro oggetti dipendenti dalla vista, come oggetti su cartelloni pubblicitari + come [page:Sprites]. Questo campo può essere settato manualmente o viene impostato quando si chiama il metodo "setFromCamera". + + L'impostazione predefinita è null. +

    + +

    [property:Layers layers]

    +

    + Utilizzato da [name] per ignorare selettivamente oggetti 3D durante l'esecuzione di test di intersezione. Il seguente codice di esempio + assicura che solo gli oggetti 3D sul layer `1` vengano rispettati dall'istanza di [name]. + + + raycaster.layers.set( 1 ); + object.layers.enable( 1 ); + + +

    + +

    [property:Object params]

    +

    + Un oggetto con le seguenti proprietà: + + +{ + Mesh: {}, + Line: { threshold: 1 }, + LOD: {}, + Points: { threshold: 1 }, + Sprite: {} +} + + + Dove threshold è la precisione del raycaster quando intercetta gli oggetti, in unità di world. +

    + +

    [property:Ray ray]

    +

    Il [Page:Ray raggio] usato per il raycasting.

    + + +

    Metodi

    + +

    [method:undefined set]( [param:Vector3 origin], [param:Vector3 direction] )

    +

    + [page:Vector3 origin] — Il vettore di origine da cui viene proiettato il raggio.
    + [page:Vector3 direction] — Il vettore di direzione normalizzato che fornisce la direzione al raggio. +

    +

    + Aggiorna il raggio con una nuova origine e direzione. Si noti che questo metodo copia solamente i valori dagli argomenti. +

    + +

    [method:undefined setFromCamera]( [param:Vector2 coords], [param:Camera camera] )

    +

    + [page:Vector2 coords] — coordinate 2D del mouse, in coordinate normalizzate del dispositivo (NDC)---i componenti X e Y dovrebbero essere tra -1 e 1.
    + [page:Camera camera] — telecamera da cui dovrebbe provenire il raggio. +

    +

    + Aggiorna il raggio con una nuova origine e direzione. +

    + +

    [method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )

    +

    + [page:Object3D object] — L'oggetto da verificare per l'intersezione con il raggio.
    + [page:Boolean recursive] — Se true, controlla anche tutti i discendenti. Altrimenti controlla soltanto + l'intersezione con l'oggetto. Il valore predefinito è true.
    + [page:Array optionalTarget] — (opzionale) obiettivo per impostare il risultato. + Altrimenti viene istanziato un nuovo [page:Array]. Se impostato, è necessario cancellare questo array prima di ogni chiamata (ad esempio, array.length = 0;). +

    +

    + Controlla tutte le intersezioni tra il raggio e l'oggetto con o senza i discendenti. + Le intersezioni sono restituite ordinate per distanza, le più vicine prima. Viene restituito un array di intersezioni... +

    + + [ { distance, point, face, faceIndex, object }, ... ] + +

    + [page:Float distance] – distanza tra l'origine del raggio e l'intersezione
    + [page:Vector3 point] – punto di intersezione, nelle coordinate world
    + [page:Object face] – faccia intersecata
    + [page:Integer faceIndex] – indice della faccia intersecata
    + [page:Object3D object] – l'oggetto intersecato
    + [page:Vector2 uv] - le coordinate U,V nel punto di intersezione
    + [page:Vector2 uv2] - Secondo insieme delle coordinate U,V nel punto di intersezione
    + [page:Integer instanceId] – Il numero di indice dell'istanza in cui il raggio interseca la InstancedMesh. +

    +

    + `Raycaster` delega al metodo [page:Object3D.raycast raycast] dell'oggetto passato, + quando valuta se il raggio interseca l'oggetto o no. Ciò permette alle mesh di rispondere + in modo diverso al raycasting rispetto alle linee e alle nuvole di punti. +

    +

    + *Nota* per le mesh, le facce devono essere puntate verso l'origine del [page:.ray raggio] per essere rilevate; + le intersezioni del raggio passato attraverso il retro della faccia non saranno rilevate. Per eseguire il raycast + su entrambe le facce dell'oggetto, ti consigliamo di impostare la proprietà [page:Material.side side] del [page:Mesh.material materiale] + a `THREE.DoubleSide`. +

    + +

    [method:Array intersectObjects]( [param:Array objects], [param:Boolean recursive], [param:Array optionalTarget] )

    +

    + [page:Array objects] — Gli oggetti da controllare per l'intersezione con il raggio.
    + [page:Boolean recursive] — Se true, controlla anche i discendenti degli oggetti. Altrimenti controlla soltanto + l'intersezione con gli oggetti. Il valore predefinito è true.
    + [page:Array optionalTarget] — (opzionale) obiettivo per impostare il risultato. + Altrimenti viene istanziato un nuovo [page:Array]. Se impostato, è necessario cancellare questo array prima di ogni chiamata (ad esempio, array.length = 0;). +

    +

    + Controlla tutte le intersezioni tra il raggio e gli oggetti con o senza i discendenti. + Le intersezioni sono restituite ordinate per distanza, prima le più vicine. Le intersezioni + hanno la stessa forma di quelle restituite da [page:.intersectObject]. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/core/Uniform.html b/docs/api/it/core/Uniform.html new file mode 100644 index 00000000000000..997e0fd3f15412 --- /dev/null +++ b/docs/api/it/core/Uniform.html @@ -0,0 +1,274 @@ + + + + + + + + + +

    [name]

    + +

    Le uniform sono delle variabili GLSL globali. Vengono passate ai programmi shader. +

    + +

    Codice di Esempio

    +

    + Quando si dichiara una uniform di uno [page:ShaderMaterial], viene dichiarata per valore o per oggetto. +

    + + uniforms: { + time: { value: 1.0 }, + resolution: new Uniform( new Vector2() ) + }; + + +

    Tipi Uniform

    + +

    + Ogni uniform deve avere una proprietà `value`. Il tipo di value deve corrispondere al tipo + della variabile uniform nel codice GLSL come specificato per i tipi primitivi GLSL nella tabella + sotto. Anche le strutture uniform e gli array sono supportati. Gli array GLSL di tipo primitivo + devono essere specificati come un array del corrispondente oggetto THREE o come un array flat + contenente i dati di tutti gli oggetti. In altre parole; le primitive GLSL negli array + non devono essere rappresentate dagli array. Questa regola non si applica in modo transitivo. + Un array di array `vec2`, ciascuno con una lunghezza di cinque vettori, deve essere un array di array, + di cinque oggetti [page:Vector2] o di dieci `numeri`. +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Tipi Uniform
    GLSL typeJavaScript type
    int[page:Number]
    uint (WebGL 2)[page:Number]
    float[page:Number]
    bool[page:Boolean]
    bool[page:Number]
    vec2[page:Vector2 THREE.Vector2]
    vec2[page:Float32Array Float32Array] (*)
    vec2[page:Array Array] (*)
    vec3[page:Vector3 THREE.Vector3]
    vec3[page:Color THREE.Color]
    vec3[page:Float32Array Float32Array] (*)
    vec3[page:Array Array] (*)
    vec4[page:Vector4 THREE.Vector4]
    vec4[page:Quaternion THREE.Quaternion]
    vec4[page:Float32Array Float32Array] (*)
    vec4[page:Array Array] (*)
    mat2[page:Float32Array Float32Array] (*)
    mat2[page:Array Array] (*)
    mat3[page:Matrix3 THREE.Matrix3]
    mat3[page:Float32Array Float32Array] (*)
    mat3[page:Array Array] (*)
    mat4[page:Matrix4 THREE.Matrix4]
    mat4[page:Float32Array Float32Array] (*)
    mat4[page:Array Array] (*)
    ivec2, bvec2[page:Float32Array Float32Array] (*)
    ivec2, bvec2[page:Array Array] (*)
    ivec3, bvec3[page:Int32Array Int32Array] (*)
    ivec3, bvec3[page:Array Array] (*)
    ivec4, bvec4[page:Int32Array Int32Array] (*)
    ivec4, bvec4[page:Array Array] (*)
    sampler2D[page:Texture THREE.Texture]
    samplerCube[page:CubeTexture THREE.CubeTexture]
    + +

    + (*) Lo stesso per un array (dimensione) (più interno) dello stesso tipo GLSL, contenente i componenti di tutti i vettori o le matrici nell'array. +

    + +

    Uniform Strutturate

    + +

    + A volte vuoi organizzare le uniform come `structs` nel tuo codice shader. + È necessario utilizzare lo stile seguente in modo che three.js sia in grado di elaborare dati strutturati uniform. +

    + + uniforms = { + data: { + value: { + position: new Vector3(), + direction: new Vector3( 0, 0, 1 ) + } + } + }; + + Questa definizione può essere mappata con il seguente codice GLSL: + + struct Data { + vec3 position; + vec3 direction; + }; + + uniform Data data; + + +

    Uniforms Strutturate con Array

    + +

    + È anche possibile gestire `structs` negli array. La sintassi per questo caso d'uso appare così: +

    + + const entry1 = { + position: new Vector3(), + direction: new Vector3( 0, 0, 1 ) + }; + const entry2 = { + position: new Vector3( 1, 1, 1 ), + direction: new Vector3( 0, 1, 0 ) + }; + + uniforms = { + data: { + value: [ entry1, entry2 ] + } + }; + + Questa definizione può essere mappata con il seguente codice GLSL: + + struct Data { + vec3 position; + vec3 direction; + }; + + uniform Data data[ 2 ]; + + +

    Costruttore

    + +

    [name]( [param:Object value] )

    +

    + value -- Un oggetto contenente il valore per impostare la uniform. Il suo tipo deve essere uno dei tipi uniform descritti sopra. +

    + +

    Proprietà

    + +

    [property:Object value]

    +

    + Il valore corrente della uniform. +

    + +

    Metodi

    + +

    [method:Uniform clone]()

    +

    + Restituisce un clone della uniform.
    + Se il valore della proprietà uniform è un [page:Object] con un metodo clone(), viene utilizzato, altrimenti il valore è copiato per assegnazione. + I valori dell'array sono condivisi tra le [page:Uniform] clonate. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/core/bufferAttributeTypes/BufferAttributeTypes.html b/docs/api/it/core/bufferAttributeTypes/BufferAttributeTypes.html new file mode 100644 index 00000000000000..21be170adc4d61 --- /dev/null +++ b/docs/api/it/core/bufferAttributeTypes/BufferAttributeTypes.html @@ -0,0 +1,65 @@ + + + + + + + + + + [page:BufferAttribute] → + +

    Tipi di BufferAttribute

    + +

    + Ci sono nove tipi di [page:BufferAttribute] disponibili in three.js. Questi corrispondono ai + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#Syntax Typed Array] JavaScript. +

    + + + THREE.Float64BufferAttribute + THREE.Float32BufferAttribute + THREE.Float16BufferAttribute + THREE.Uint32BufferAttribute + THREE.Int32BufferAttribute + THREE.Uint16BufferAttribute + THREE.Int16BufferAttribute + THREE.Uint8ClampedBufferAttribute + THREE.Uint8BufferAttribute + THREE.Int8BufferAttribute + + +

    Costruttore

    + +

    Tutti i precedenti sono chiamati allo stesso modo.

    + +

    TypedBufferAttribute( [param:Array_or_Integer array], [param:Integer itemSize], [param:Boolean normalized] )

    +

    + array -- può essere un array tipizzato o non tipizzato (normale) o una lunghezza intera. + Un valore dell'array sarà convertito nel Tipo specificato. + Se viene data una lunghezza sarà creato un nuovo TypedArray, inizializzato con tutti gli elementi impostati a zero.

    + + itemSize -- il numero di valori dell'array che dovrebbe essere associato ad un particolare vertice.

    + + normalized -- (opzionale) indica come i dati sottostanti nel buffer vengono mappati ai valori nel codice GLSL. +

    + +

    Proprietà

    + +

    + Vedi [page:BufferAttribute] per le prorietà ereditate. +

    + +

    Metodi

    + +

    + Vedi [page:BufferAttribute] per i metodi ereditati. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js src/core/BufferAttribute.js] +

    + + diff --git a/docs/api/it/extras/DataUtils.html b/docs/api/it/extras/DataUtils.html new file mode 100644 index 00000000000000..b6c5b58e41c7a0 --- /dev/null +++ b/docs/api/it/extras/DataUtils.html @@ -0,0 +1,38 @@ + + + + + + + + + +

    [name]

    + +

    + Una classe che contiene funzioni di utilità per i dati. +

    + +

    Metodi

    + +

    [method:Number toHalfFloat]( [param:Number val] )

    +

    + val -- Un valore in virgola mobile a precisione singola.

    + + Restituisce un valore in virgola mobile a mezza precisione dal valore in virgola mobile a singola precisione passato. +

    + +

    [method:Number fromHalfFloat]( [param:Number val] )

    +

    + val -- Un valore in virgola mobile a mezza precisione.

    + + Restituisce un valore in virgola mobile a singola precisione dal valore in virgola mobile a mezza precisione passato. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/Earcut.html b/docs/api/it/extras/Earcut.html new file mode 100644 index 00000000000000..2268bd10be8605 --- /dev/null +++ b/docs/api/it/extras/Earcut.html @@ -0,0 +1,34 @@ + + + + + + + + + +

    [name]

    + +

    + Un'implementazione dell'algoritmo di triangolazione dei poligoni earcut. Il codice è un porting di [link:https://github.com/mapbox/earcut mapbox/earcut]. +

    + +

    Metodi

    + +

    [method:Array triangulate]( data, holeIndices, dim )

    +

    + data -- Un array flat di coordinate dei vertici.
    + holeIndices -- Un array di indici di hole, se presenti.
    + dim -- Il numero di coordinate per vertice nell'array di input.

    + + Triangola la definizione di forma data restituendo un array di triangoli. + Un triangolo è definito da tre numeri interi consecutivi che rappresentano gli indici dei vertici. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/ImageUtils.html b/docs/api/it/extras/ImageUtils.html new file mode 100644 index 00000000000000..cbe847f74dced5 --- /dev/null +++ b/docs/api/it/extras/ImageUtils.html @@ -0,0 +1,38 @@ + + + + + + + + + +

    [name]

    + +

    + Una classe contente funzioni di utilità per le immagini. +

    + +

    Metodi

    + +

    [method:String getDataURL]( [param:HTMLCanvasElement image] | [param:HTMLImageElement image] | [param:ImageBitmap image] )

    +

    + image -- L'oggetto immagine.

    + + Restituisce un URI di dati contenente una rappresentazione dell'immagine data. +

    + +

    [method:Object sRGBToLinear]( [param:HTMLCanvasElement image] | [param:HTMLImageElement image] | [param:ImageBitmap image] )

    +

    + image -- L'oggetto immagine.

    + + Converte i dati dell'immagine sRGB passata in uno spazio colore lineare. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/PMREMGenerator.html b/docs/api/it/extras/PMREMGenerator.html new file mode 100644 index 00000000000000..1d73d4e595fd67 --- /dev/null +++ b/docs/api/it/extras/PMREMGenerator.html @@ -0,0 +1,111 @@ + + + + + + + + + +

    [name]

    + +

    + Questa classe genera un Prefiltered Mipmapped Radiance Environment Map (PMREM) da una texture di ambiente cubeMap. + Ciò consente di accedere rapidamente a diversi livelli di sfocatura (blur) in base alla rugosità (roughness) del materiale. + A differenza di una catena mipmap tradizionale, scende solo al livello LOD_MIN (sopra) e quindi crea 'mips' aggiuntivi + ancora più filtrati alla stessa risoluzione LOD_MIN, associati a livelli di rugosità più elevati. + In questo modo manteniamo la risoluzione per interpolare uniformemente l'illuminazione diffusa, limitando al contempo + il calcolo del campionamento.

    + + Nota: La rugosità minima di [page:MeshStandardMaterial] dipende dalla dimensione della texture fornita. + Se il tuo render è di piccole dimensioni o le parti lucide hanno molte curvature, potresti comunque + riuscire ad ottenere una texture di dimensioni inferiori. + + + + + + + + + + + + + + + + + + + + + + + + + +
    texture sizeminimum roughness +
    160.21
    320.15
    640.11
    1280.076
    2560.054
    5120.038
    10240.027
    +

    + +

    Costruttore

    + +

    [name]( [param:WebGLRenderer renderer] )

    +

    + Questo costruttore crea una nuova [name]. +

    + +

    Metodi

    + +

    [method:WebGLRenderTarget fromScene]( [param:Scene scene], [param:Number sigma], [param:Number near], [param:Number far] )

    +

    + [page:Scene scene] - La scena data.
    + [page:Number sigma] - (opzionale) Specifica un raggio di blur in radianti da applicare alla scena prima della generazione PMREM. + Il valore predefinito è `0`.
    + [page:Number near] - (opzionale) Il valore del piano near. Il valore predefinito è `0.1`.
    + [page:Number far] - (opzionale) Il valore del piano far. Il valore predefinito è `100`.

    + + Genera un PMREM da una scena fornita, che può essere più veloce rispetto all'utilizzo di un'immagine se + la larghezza di banda della rete è bassa. I piani near e far opzionali garantiscono che la scena sia renderizzata completamente + (la cubeCamera è posizionata nell'origine). +

    + +

    [method:WebGLRenderTarget fromEquirectangular]( [param:Texture equirectangular] )

    +

    + [page:Texture equirectangular] - La texture equirettangolare.

    + + Genera una PMREM da una texture equirettangolare. +

    + +

    [method:WebGLRenderTarget fromCubemap]( [param:CubeTexture cubemap] )

    +

    + [page:CubeTexture cubemap] - La texture cubemap.

    + + Genera una PMREM da una texture cubemap. +

    + +

    [method:undefined compileCubemapShader]()

    +

    + Pre-compila lo shader cubemap. Puoi ottenere un avvio più rapido invocando questo metodo durante il recupero di rete della texture per una + maggiore concorrenza. +

    + +

    [method:undefined compileEquirectangularShader]()

    +

    + Pre-compila lo shader equirettangolare. Puoi ottenere un avvio più rapido invocando questo metodo durante il recupero di rete della texture per una + maggiore concorrenza. +

    + +

    [method:undefined dispose]()

    +

    + Elimina la memoria interna del PMREMGenerator. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/ShapeUtils.html b/docs/api/it/extras/ShapeUtils.html new file mode 100644 index 00000000000000..38d819c6e6072a --- /dev/null +++ b/docs/api/it/extras/ShapeUtils.html @@ -0,0 +1,52 @@ + + + + + + + + + +

    [name]

    + +

    + Una classe contenente funzioni di utilità per le forme (shape).

    + + Si noti che queste sono tutte funzioni lineari quindi è necessario calcolare separatamente i componenti + x, y (e z, w se presenti) di un vettore. +

    + + +

    Metodi

    + +

    [method:Number area]( contour )

    +

    + contour -- poligono 2D. Un array di THREE.Vector2().

    + + Calcola l'area di un poligono di contorno (2D). +

    + +

    [method:Boolean isClockWise]( pts )

    +

    + pts -- punti che definiscono un poligono 2D.

    + + Si noti che questa è una funzione lineare quindi è necessario calcolare separatamente i componenti + x,y di un poligono.

    + + Utilizzato internamente da [page:Path Path], + [page:ExtrudeGeometry ExtrudeGeometry] e [page:ShapeGeometry ShapeGeometry]. +

    + +

    [method:Array triangulateShape]( contour, holes )

    +

    + contour -- poligono 2D. Un array di [page:Vector2].
    + holes -- Un array che contiene array di [page:Vector2]. Ogni array rappresenta una singola definizione di hole.

    +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/core/Curve.html b/docs/api/it/extras/core/Curve.html new file mode 100644 index 00000000000000..96e4679ee87986 --- /dev/null +++ b/docs/api/it/extras/core/Curve.html @@ -0,0 +1,132 @@ + + + + + + + + + +

    [name]

    + +

    + Una classe base astratta per la creazione di un oggetto [name] che contiene i metodi di interpolazione. + Per un array di [name] vedere [page:CurvePath]. +

    + +

    Costruttore

    + + +

    [name]()

    +

    + Questo costruttore crea una nuova [name]. +

    + +

    Proprietà

    + +

    [property:Integer arcLengthDivisions]

    +

    + Questo valore determina la quatità di divisioni quando vengono calcolate le lunghezze cumulative dei segmenti tramite [page:.getLengths]. + Per garantire la precisione quando vengono utilizzati metodi come [page:.getSpacedPoints], si consiglia di aumentare la proprietà + [page:.arcLengthDivisions] se la curva è molto grande. Il valore predefinito è 200. +

    + +

    Metodi

    + +

    [method:Vector getPoint]( [param:Float t], [param:Vector optionalTarget] )

    +

    + [page:Float t] - Una posizione sulla curva. Deve essere compreso nell'intervallo [ 0, 1 ].
    + [page:Vector optionalTarget] — (opzionale) Se specificato, il risultato verrà copiato in questo vettore, + altrimenti verrà creato un nuovo vettore.

    + + Restituisce un vettore per una data posizione sulla curva. +

    + +

    [method:Vector getPointAt]( [param:Float u], [param:Vector optionalTarget] )

    +

    + [page:Float u] - Una posizione sulla curva in base alla lunghezza dell'arco. Deve essere compreso nell'intervallo [ 0, 1 ].
    + [page:Vector optionalTarget] — (opzionale) Se specificato, il risultato verrà copiato in questo vettore, + altrimenti verrà creato un nuovo vettore.

    + + Restituisce un vettore per una data posizione sulla curva in base alla lunghezza dell'arco. +

    + +

    [method:Array getPoints]( [param:Integer divisions] )

    +

    + divisions -- numero di pezzi in cui dividere la curva. Il valore predefinito è `5`.

    + + Restituisce un insieme di divisioni + 1 punto usando getPoint( t ). +

    + +

    [method:Array getSpacedPoints]( [param:Integer divisions] )

    +

    + divisions -- numero di pezzi in cui dividere la curva. Il valore predefinito è `5`.

    + + Restituisce un insieme di divisioni + 1 punto equispaziato usando getPointAt( u ). +

    + +

    [method:Float getLength]()

    +

    Restituisce la lunghezza totale dell'arco della curva.

    + +

    [method:Array getLengths]( [param:Integer divisions] )

    +

    Restituisce la lista delle lunghezze cumulative del segmento.

    + +

    [method:undefined updateArcLengths]()

    +

    + Aggiorna la cache della distanza cumulativa del segmento. Il metodo deve essere chiamato ogni volta + che i parametri della curva vengono modificati. Se una curva aggiornata fa parte di una curva composta come + [page:CurvePath], [page:.updateArcLengths]() deve essere chiamato anche sulla curva composta. +

    + +

    [method:Float getUtoTmapping]( [param:Float u], [param:Float distance] )

    +

    + Dato u nell'intervallo ( 0 .. 1 ), restituisce [page:Float t] anche nell'intervallo ( 0 .. 1 ). + u e t possono quindi essere utilizzati per fornire punti equidistanti dalle estremità della curva, utilizzando + [page:.getPoint]. +

    + +

    [method:Vector getTangent]( [param:Float t], [param:Vector optionalTarget] )

    +

    + [page:Float t] - Una posizione sulla curva. Deve essere compreso nell'intervallo [ 0, 1 ].
    + [page:Vector optionalTarget] — (opzionale) Se specificato, il risultato sarà copiato in questo vettore, + altrimenti sarà creato un nuovo vettore.

    + + Restituisce un vettore unitario tangente a t. Se la curva derivata non implementa la sua derivazione tangente, + per trovare la sua pendenza verranno utilizzati due punti distanti un piccolo delta, che sembrano fornire + un'approssimazione ragionevole. +

    + +

    [method:Vector getTangentAt]( [param:Float u], [param:Vector optionalTarget] )

    +

    + [page:Float u] - Una posizione sulla curva in base alla lunghezza dell'arco. Deve essere compreso nell'intervallo [ 0, 1 ].
    + [page:Vector optionalTarget] — (opzionale) Se specificato, il risultato sarà copiato in questo vettore, + altrimenti sarà creato un nuovo vettore.

    + + Restituisce la tangente in un punto equidistante dalle estremità della curva dal punto indicato + in [page:.getTangent]. +

    + +

    [method:Object computeFrenetFrames]( [param:Integer segments], [param:Boolean closed] )

    +

    + Genera i Frame Franet. Richiede una definizione della curva nello spazio 3D. Utilizzata nelle geometrie come [page:TubeGeometry] o [page:ExtrudeGeometry]. +

    + +

    [method:Curve clone]()

    +

    Crea un clone di questa istanza.

    + +

    [method:this copy]( [param:Curve source] )

    +

    Copia un altro oggetto [name] in questa istanza.

    + +

    [method:Object toJSON]()

    +

    Restituisce un oggetto JSON rappresentazione di questa istanza.

    + +

    [method:this fromJSON]( [param:Object json] )

    +

    Copia i dati dell'oggetto JSON dato in questa istanza.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/core/CurvePath.html b/docs/api/it/extras/core/CurvePath.html new file mode 100644 index 00000000000000..0a8a011d3bc885 --- /dev/null +++ b/docs/api/it/extras/core/CurvePath.html @@ -0,0 +1,70 @@ + + + + + + + + + + [page:Curve] → + +

    [name]

    + +

    + Una classe base atratta che estende [page:Curve]. Una CurvePath è semplicemente un array di curve collegate, + ma mantiene le API di una curva. +

    + +

    Costruttore

    + +

    [name]()

    +

    + Il costruttore non prende parametri. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Curve] per le proprietà comuni.

    + +

    [property:Array curves]

    +

    L'array di [page:Curve Curve].

    + +

    [property:Boolean autoClose]

    +

    Se chiudere automaticamente o meno il percorso.

    + +

    Metodi

    +

    Vedi la classe base [page:Curve] per i metodi comuni.

    + +

    [method:undefined add]( [param:Curve curve] )

    +

    Aggiunge una curva all'array [page:.curves].

    + +

    [method:undefined closePath]()

    +

    Aggiunge una [page:LineCurve lineCurve] per chiudere il percorso.

    + +

    [method:Array getCurveLengths]()

    +

    Ottieni l'elenco delle lunghezze delle curve cumulative nell'array [page:.curves].

    + +

    [method:Array getPoints]( [param:Integer divisions] )

    +

    + divisions -- il numero di pezzi in cui dividere la curva. Il valore predefinito è `12`.

    + + Restituisce un array di punti che rappresentano una sequenza di curve. Il paramentro `division` + definisce il numero di pezzi in cui è suddivisa ciascuna curva. Tuttavia, ai fini dell'ottimizzazione + e della qualità, la risoluzione di campionamento per ogni curva dipende dal suo tipo. Ad esempio, per una + [page:LineCurve], il numero restituito di punti è sempre solo 2. +

    + +

    [method:Array getSpacedPoints]( [param:Integer divisions] )

    +

    + divisions -- il numero di pezzi in cui dividere la curva. Il valore predefinito è `40`.

    + + Restituisce un insieme di divisioni + 1 punto equispaziato usando getPointAt( u ). +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/core/Interpolations.html b/docs/api/it/extras/core/Interpolations.html new file mode 100644 index 00000000000000..a58b4047436a93 --- /dev/null +++ b/docs/api/it/extras/core/Interpolations.html @@ -0,0 +1,48 @@ + + + + + + + + + +

    [name]

    + +

    + Le [name] contengono funzioni spline e Bézier utilizzate internamente dalle classi di curve concrete. +

    + +

    Metodi

    + +

    [method:Float CatmullRom]( [param:Float t], [param:Float p0], [param:Float p1], [param:Float p2], [param:Float p3] )

    +

    + t -- peso di interpolazione.
    + p0, p1, p2, p3 -- i punti che definiscono la curva spline.

    + + Usato internamente da [page:SplineCurve SplineCurve]. +

    + +

    [method:Float QuadraticBezier]( [param:Float t], [param:Float p0], [param:Float p1], [param:Float p2] )

    +

    + t -- peso di interpolazione.
    + p0, p1, p2 -- i punti di inizio, controllo e fine che definiscono la curva.

    + + Usato internamente da [page:QuadraticBezierCurve3 QuadraticBezierCurve3] e [page:QuadraticBezierCurve QuadraticBezierCurve]. +

    + +

    [method:Float CubicBezier]( [param:Float t], [param:Float p0], [param:Float p1], [param:Float p2], [param:Float p3] )

    +

    + t -- peso di interpolazione.
    + p0, p1, p2, p3 -- i punti di inizio, controllo (doppio) e fine che definiscono la curva.

    + + Usato internamente da [page:CubicBezierCurve3 CubicBezierCurve3] e [page:CubicBezierCurve CubicBezierCurve]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/core/Path.html b/docs/api/it/extras/core/Path.html new file mode 100644 index 00000000000000..dbf4734b7a6480 --- /dev/null +++ b/docs/api/it/extras/core/Path.html @@ -0,0 +1,150 @@ + + + + + + + + + + [page:Curve] → [page:CurvePath] → + +

    [name]

    + +

    + Una rappresentazione del percorso 2D. La classe mette a dispozione metodi per la + creazione di tracciati e contorni di forme 2D simili all'API Canvas 2D. +

    + +

    Codice di Esempio

    + + + const path = new THREE.Path(); + + path.lineTo( 0, 0.8 ); + path.quadraticCurveTo( 0, 1, 0.2, 1 ); + path.lineTo( 1, 1 ); + + const points = path.getPoints(); + + const geometry = new THREE.BufferGeometry().setFromPoints( points ); + const material = new THREE.LineBasicMaterial( { color: 0xffffff } ); + + const line = new THREE.Line( geometry, material ); + scene.add( line ); + + + +

    Costruttore

    + + +

    [name]( [param:Array points] )

    +

    + points -- (opzionale) array di [page:Vector2 Vector2].

    + + Crea un Path dai punti. Il primo punto definisce l'offset, quindi i punti successivi sono + aggiunti all'array [page:CurvePath.curves curves] come [page:LineCurve LineCurves].

    + + Se non ci sono punti specificati, viene creato un path vuoto e il [page:.currentPoint] viene impostato + nell'origine. +

    + + +

    Proprietà

    +

    Vedi la classe base [page:CurvePath] per le proprietà comuni.

    + +

    [property:Vector2 currentPoint]

    +

    L'offset corrente del path. Qualsiasi nuova [page:Curve] aggiunta inizierà da qui.

    + + +

    Metodi

    +

    Vedi la classe base [page:CurvePath] per i metodi comuni.

    + +

    [method:this absarc]( [param:Float x], [param:Float y], [param:Float radius], [param:Float startAngle], [param:Float endAngle], [param:Boolean clockwise] )

    +

    + x, y -- Il centro assoluto dell'arco.
    + radius -- Il raggio dell'arco.
    + startAngle -- L'angolo iniziale in radianti.
    + endAngle -- L'angolo finale in radianti.
    + clockwise -- Scorre l'arco in senso orario. Il valore predefinito è `false`.

    + + Aggiunge al path un'[page:EllipseCurve EllipseCurve] posizionata in modo assoluto. +

    + +

    [method:this absellipse]( [param:Float x], [param:Float y], [param:Float xRadius], [param:Float yRadius], [param:Float startAngle], [param:Float endAngle], [param:Boolean clockwise], [param:Float rotation] )

    +

    + x, y -- Il centro assoluto dell'ellisse.
    + xRadius -- Il raggio dell'ellisse nell'asse x.
    + yRadius -- Il raggio dell'ellisse nell'asse y.
    + startAngle -- L'angolo iniziale in radianti.
    + endAngle -- L'angolo finale in radianti.
    + clockwise -- Scorre l'ellisse in senso orario. Il valore predefinito è `false`.
    + rotation -- L'angolo di rotazione dell'ellisse in radianti, in senso antiorario dall'asse X. Opzionale, il valore predefinito è 0.

    + + Aggiunge al path un'[page:EllipseCurve EllipseCurve] posizionata in modo assoluto. +

    + +

    [method:this arc]( [param:Float x], [param:Float y], [param:Float radius], [param:Float startAngle], [param:Float endAngle], [param:Boolean clockwise] )

    +

    + x, y -- Il centro dell'arco offsettato dall'ultima chiamata.
    + radius -- Il raggio dell'arco.
    + startAngle -- L'angolo iniziale in radianti.
    + endAngle -- L'angolo finale in radianti.
    + clockwise -- Scorre l'arco in senso orario. Il valore predefinito è `false`.

    + + Aggiunge al path un'[page:EllipseCurve EllipseCurve] posizionata in modo relativo al [page:.currentPoint]. +

    + + +

    [method:this bezierCurveTo]( [param:Float cp1X], [param:Float cp1Y], [param:Float cp2X], [param:Float cp2Y], [param:Float x], [param:Float y] )

    +

    + Crea una curva bezier da [page:.currentPoint] con (cp1X, cp1Y) e (cp2X, cp2Y) come punti di controllo e aggiorna [page:.currentPoint] a x e y. +

    + +

    [method:this ellipse]( [param:Float x], [param:Float y], [param:Float xRadius], [param:Float yRadius], [param:Float startAngle], [param:Float endAngle], [param:Boolean clockwise], [param:Float rotation] )

    +

    + x, y -- Il centro dell'arco offsettato dall'ultima chiamata.
    + xRadius -- Il raggio dell'ellisse nell'asse x.
    + yRadius -- Il raggio dell'ellisse nell'asse y.
    + startAngle -- L'angolo iniziale in radianti.
    + endAngle -- L'angolo finale in radianti.
    + clockwise -- Scorre l'arco in senso orario. Il valore predefinito è `false`.

    + rotation -- L'angolo di rotazione dell'ellisse in radianti, in senso antiorario dall'asse X. Opzionale, il valore predefinito è 0.

    + + Aggiunge al path un'[page:EllipseCurve EllipseCurve] posizionata in modo relativo al [page:.currentPoint]. +

    + +

    [method:this lineTo]( [param:Float x], [param:Float y] )

    +

    Collega una [page:LineCurve] da il [page:.currentPoint] a x, y sul percorso.

    + + +

    [method:this moveTo]( [param:Float x], [param:Float y] )

    +

    Muove il [page:.currentPoint] a x, y.

    + + +

    [method:this quadraticCurveTo]( [param:Float cpX], [param:Float cpY], [param:Float x], [param:Float y] )

    +

    + Crea una curva quadratica da [page:.currentPoint] con cpX e cpY come punto di controllo e aggiorna [page:.currentPoint] a x e y. +

    + +

    [method:this setFromPoints]( [param:Array vector2s] )

    +

    + points -- array di [page:Vector2 Vector2].

    + + I punti vengono aggiunti all'array [page:CurvePath.curves curves] come [page:LineCurve LineCurves]. +

    + +

    [method:this splineThru] ( [param:Array points] )

    +

    + points - array di [page:Vector2 Vector2].

    + + Collega un nuovo [page:SplineCurve] al percorso. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/core/Shape.html b/docs/api/it/extras/core/Shape.html new file mode 100644 index 00000000000000..09390a5d5f9d33 --- /dev/null +++ b/docs/api/it/extras/core/Shape.html @@ -0,0 +1,104 @@ + + + + + + + + + + [page:Curve] → [page:CurvePath] → [page:Path] → + +

    [name]

    + +

    + Definisce un piano di forma 2D arbitrario usando percorsi con hole opzionali. Può essere usato con [page:ExtrudeGeometry], + [page:ShapeGeometry], per ottenere punti, o per ottenere facce triangolate. +

    + +

    Codice di Esempio

    + + + const heartShape = new THREE.Shape(); + + heartShape.moveTo( 25, 25 ); + heartShape.bezierCurveTo( 25, 25, 20, 0, 0, 0 ); + heartShape.bezierCurveTo( - 30, 0, - 30, 35, - 30, 35 ); + heartShape.bezierCurveTo( - 30, 55, - 10, 77, 25, 95 ); + heartShape.bezierCurveTo( 60, 77, 80, 55, 80, 35 ); + heartShape.bezierCurveTo( 80, 35, 80, 0, 50, 0 ); + heartShape.bezierCurveTo( 35, 0, 25, 25, 25, 25 ); + + const extrudeSettings = { depth: 8, bevelEnabled: true, bevelSegments: 2, steps: 2, bevelSize: 1, bevelThickness: 1 }; + + const geometry = new THREE.ExtrudeGeometry( heartShape, extrudeSettings ); + + const mesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial() ); + + +

    Esempi

    + +

    + [example:webgl_geometry_shapes geometry / shapes ]
    + [example:webgl_geometry_extrude_shapes geometry / extrude / shapes ]
    + [example:webgl_geometry_extrude_shapes2 geometry / extrude / shapes2 ]
    +

    + + +

    Costruttore

    + + +

    [name]( [param:Array points] )

    +

    + points -- (opzionale) un array di [page:Vector2 Vector2].

    + + Crea una Shape dai punti. Il primo punto defisce l'offset, quindi i punti successivi vengono aggiunti + all'array [page:CurvePath.curves curves] come [page:LineCurve LineCurves].

    + + Se i punti non vengono specificati, viene creata una shape vuota e il [page:.currentPoint] viene impostato nell'origine. +

    + + +

    Proprietà

    +

    Vedi la classe base [page:Path] per le proprietà comuni.

    + +

    [property:String uuid]

    +

    + L'[link:http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] di questa istanza. Viene assegnato + automaticamente, quindi non dovrebbe essere modificato. +

    + +

    [property:Array holes]

    +

    Un array di [page:Path path] che definisce gli hole nella forma.

    + +

    Metodi

    +

    Vedi la classe base [page:Path] per i metodi comuni.

    + +

    [method:Array extractPoints]( [param:Integer divisions] )

    +

    + divisions -- La finezza del risultato.

    + + Chiama [page:Curve.getPoints getPoints] sulla forma e l'array [page:.holes], e restituisce un oggetto della forma: + +{ + shape + holes +} + + dove shape e holes sono array di tipo [page:Vector2 Vector2]. +

    + +

    [method:Array getPointsHoles]( [param:Integer divisions] )

    +

    + divisions -- La finezza del risultato.

    + + Ottiene un array di [page:Vector2 Vector2] che rapprensenta gli hole nella forma. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/core/ShapePath.html b/docs/api/it/extras/core/ShapePath.html new file mode 100644 index 00000000000000..541f766361a61a --- /dev/null +++ b/docs/api/it/extras/core/ShapePath.html @@ -0,0 +1,95 @@ + + + + + + + + + +

    [name]

    + +

    + Questa classe viene utilizzata per convertire una serie di forme in un array di [page:Path], ad esempio una + forma SVG in un path (vedere l'esempio seguente). +

    + +

    Esempi

    +

    + [example:webgl_geometry_extrude_shapes2 geometry / extrude / shapes2] +

    + +

    Costruttore

    + + +

    [name]( )

    +

    + Crea un nuovo ShapePath. Diversamente da un [page:Path], non vengono passati punti poiché lo ShapePath + è progettato per essere generato dopo la creazione. +

    + + +

    Proprietà

    + +

    [property:Array subPaths]

    +

    + Un array di [page:Path]. +

    + +

    [property:Array currentPath]

    +

    + Il [page:Path] corrente che viene generato. +

    + +

    [property:Color color]

    +

    Il [page:Color Colore] della shape, da impostazione predefinita impostato su bianco (0xffffff).

    + +

    Metodi

    + +

    [method:this moveTo]( [param:Float x], [param:Float y] )

    +

    + Inizia un nuovo [page:Path] e chiama [page:Path.moveTo]( x, y ) su questo [page:Path]. + Punta anche [page:ShapePath.currentPath currentPath] a quel [page:Path]. +

    + +

    [method:this lineTo]( [param:Float x], [param:Float y] )

    +

    + Crea una linea dall'offset del [page:ShapePath.currentPath currentPath] + a X e Y e aggiorna l'offset di X e Y. +

    + +

    [method:this quadraticCurveTo]( [param:Float cpX], [param:Float cpY], [param:Float x], [param:Float y] )

    +

    + Crea una curva quadratica dall'offset del [page:ShapePath.currentPath currentPath] a x e y con cpX e cpY + come punto di controllo e aggiorna l'offset del [page:ShapePath.currentPath currentPath] di x e y. +

    + +

    [method:this bezierCurveTo]( [param:Float cp1X], [param:Float cp1Y], [param:Float cp2X], [param:Float cp2Y], [param:Float x], [param:Float y] )

    +

    + Crea una curva bazier dall'offset del [page:ShapePath.currentPath currentPath] a x e y con + cp1X, cp1Y e cp2X, cp2Y come punti di controllo e aggiorna l'offset del [page:ShapePath.currentPath currentPath] a x e y. +

    + +

    [method:this splineThru] ( [param:Array points] )

    +

    points - Un array di [page:Vector2]

    +

    Collega una nuova [page:SplineCurve] al [page:ShapePath.currentPath currentPath].

    + + +

    [method:Array toShapes]( [param:Boolean isCCW] )

    +

    + isCCW -- Modifica la modalità di generazione degli hole e dei solidi
    +

    +

    + Converte l'array [page:ShapePath.subPaths subPaths] in un array di Shape. Per impostazione predefinita + le forme solide sono definite in senso orario (CW) e i fori sono definiti in senso antiorario (CCW). + Se isCCW è impostato su `true`, le forme sono capovolte. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/extras/core/ShapePath.js src/extras/core/ShapePath.js] +

    + + diff --git a/docs/api/it/extras/curves/ArcCurve.html b/docs/api/it/extras/curves/ArcCurve.html new file mode 100644 index 00000000000000..440f354303fab2 --- /dev/null +++ b/docs/api/it/extras/curves/ArcCurve.html @@ -0,0 +1,26 @@ + + + + + + + + + + [page:Curve] → [page:EllipseCurve] → + +

    [name]

    + +

    Alias per [page:EllipseCurve].

    + +

    Properties

    +

    Vedi la classe [page:EllipseCurve] per le proprietà comuni.

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/curves/CatmullRomCurve3.html b/docs/api/it/extras/curves/CatmullRomCurve3.html new file mode 100644 index 00000000000000..bd8ca9c41bd53e --- /dev/null +++ b/docs/api/it/extras/curves/CatmullRomCurve3.html @@ -0,0 +1,80 @@ + + + + + + + + + + [page:Curve] → + +

    [name]

    + +

    Crea una curva spline 3D smooth (uniforme) da una serie di punti utilizzando l'algoritmo + [link:https://en.wikipedia.org/wiki/Centripetal_Catmull-Rom_spline Catmull-Rom].

    + +

    Codice di Esempio

    + + + // Crea un circuito ondulato chiuso + const curve = new THREE.CatmullRomCurve3( [ + new THREE.Vector3( -10, 0, 10 ), + new THREE.Vector3( -5, 5, 5 ), + new THREE.Vector3( 0, 0, 0 ), + new THREE.Vector3( 5, -5, 5 ), + new THREE.Vector3( 10, 0, 10 ) + ] ); + + const points = curve.getPoints( 50 ); + const geometry = new THREE.BufferGeometry().setFromPoints( points ); + + const material = new THREE.LineBasicMaterial( { color: 0xff0000 } ); + + // Crea l'oggetto finale da aggiungere alla scena + const curveObject = new THREE.Line( geometry, material ); + + +

    Esempi

    + +

    + [example:webgl_geometry_extrude_splines WebGL / geometry / extrude / splines] +

    + +

    Costruttore

    + +

    [name]( [param:Array points], [param:Boolean closed], [param:String curveType], [param:Float tension] )

    +

    + points – Un array di punti [page:Vector3]
    + closed – Se la curva è chiusa. Il valore predefinito è `false`.
    + curveType – Tipo di curva. Il valore predefinito è `centripetal`.
    + tension – Tensione della curva. Il valore predefinito è `0.5`. +

    + + +

    Proprietà

    +

    Vedi la classe [page:Curve] per le proprità comuni.

    + +

    [property:Array points]

    +

    L'array di punti [page:Vector3] che definisce la curva. Ha bisogno di almeno due entries.

    + +

    [property:Boolean closed]

    +

    Quando questa proprietà viene impostata su `true` la curva ritornerà su se stessa.

    + +

    [property:String curveType]

    +

    I valori possibili sono `centripetal`, `chordal` e `catmullrom`.

    + +

    [property:Float tension]

    +

    Quando [page:.curveType] è `catmullrom`, definisce la tensione di catmullrom.

    + + +

    Metodi

    +

    Vedi la classe [page:Curve] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/curves/CubicBezierCurve.html b/docs/api/it/extras/curves/CubicBezierCurve.html new file mode 100644 index 00000000000000..4e4d42c90c4459 --- /dev/null +++ b/docs/api/it/extras/curves/CubicBezierCurve.html @@ -0,0 +1,75 @@ + + + + + + + + + + [page:Curve] → + +

    [name]

    + +

    + Crea una + curva di Bezier cubica 2D smooth, + definita da un punto di inizio, di fine e due punti di controllo. +

    + +

    Codice di Esempio

    + + + const curve = new THREE.CubicBezierCurve( + new THREE.Vector2( -10, 0 ), + new THREE.Vector2( -5, 15 ), + new THREE.Vector2( 20, 15 ), + new THREE.Vector2( 10, 0 ) + ); + + const points = curve.getPoints( 50 ); + const geometry = new THREE.BufferGeometry().setFromPoints( points ); + + const material = new THREE.LineBasicMaterial( { color: 0xff0000 } ); + + // Crea l'oggetto finale da aggiungere alla scena + const curveObject = new THREE.Line( geometry, material ); + + +

    Costruttore

    + + +

    [name] ( [param:Vector2 v0], [param:Vector2 v1], [param:Vector2 v2], [param:Vector2 v3] )

    +

    + [page:Vector2 v0] – Il punto di inizio.
    + [page:Vector2 v1] – Il primo punto di controllo.
    + [page:Vector2 v2] – Il secondo punto di controllo.
    + [page:Vector2 v3] – Il punto di fine. +

    + +

    Proprietà

    +

    Vedi la classe [page:Curve] per le proprità comuni.

    + +

    [property:Vector2 v0]

    +

    Il punto di inizio.

    + +

    [property:Vector2 v1]

    +

    Il primo punto di controllo.

    + +

    [property:Vector2 v2]

    +

    Il secondo punto di controllo.

    + +

    [property:Vector2 v3]

    +

    Il punto di fine.

    + + +

    Metodi

    +

    Vedi la classe [page:Curve] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/curves/CubicBezierCurve3.html b/docs/api/it/extras/curves/CubicBezierCurve3.html new file mode 100644 index 00000000000000..b54f331f0a53a0 --- /dev/null +++ b/docs/api/it/extras/curves/CubicBezierCurve3.html @@ -0,0 +1,76 @@ + + + + + + + + + + [page:Curve] → + +

    [name]

    + +

    + Crea una + curva di Bezier cubica 3D smooth, + definita da un punto di inizio, di fine e due punti di controllo. +

    + +

    Codice di Esempio

    + + + const curve = new THREE.CubicBezierCurve3( + new THREE.Vector3( -10, 0, 0 ), + new THREE.Vector3( -5, 15, 0 ), + new THREE.Vector3( 20, 15, 0 ), + new THREE.Vector3( 10, 0, 0 ) + ); + + const points = curve.getPoints( 50 ); + const geometry = new THREE.BufferGeometry().setFromPoints( points ); + + const material = new THREE.LineBasicMaterial( { color: 0xff0000 } ); + + // Crea l'oggetto finale da aggiungere alla scena + const curveObject = new THREE.Line( geometry, material ); + + + +

    Costruttore

    + + +

    [name]( [param:Vector3 v0], [param:Vector3 v1], [param:Vector3 v2], [param:Vector3 v3] )

    +

    + [page:Vector3 v0] – Il punto di inizio.
    + [page:Vector3 v1] – Il primo punto di controllo.
    + [page:Vector3 v2] – Il secondo punto di controllo.
    + [page:Vector3 v3] – Il punto di fine. +

    + +

    Proprietà

    +

    Vedi la classe [page:Curve] per le proprità comuni.

    + +

    [property:Vector3 v0]

    +

    Il punto di inizio.

    + +

    [property:Vector3 v1]

    +

    Il primo punto di controllo.

    + +

    [property:Vector3 v2]

    +

    Il secondo punto di controllo.

    + +

    [property:Vector3 v3]

    +

    Il punto di fine.

    + + +

    Metodi

    +

    Vedi la classe [page:Curve] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/curves/EllipseCurve.html b/docs/api/it/extras/curves/EllipseCurve.html new file mode 100644 index 00000000000000..2dac41472cdee9 --- /dev/null +++ b/docs/api/it/extras/curves/EllipseCurve.html @@ -0,0 +1,91 @@ + + + + + + + + + + [page:Curve] → + +

    [name]

    + +

    + Crea una curva 2D a forma di ellisse. Impostando [page:Number xRadius] + uguale a [page:Number yRadius] risulterà in un cerchio. +

    + +

    Codice di Esempio

    + + + const curve = new THREE.EllipseCurve( + 0, 0, // ax, aY + 10, 10, // xRadius, yRadius + 0, 2 * Math.PI, // aStartAngle, aEndAngle + false, // aClockwise + 0 // aRotation + ); + + const points = curve.getPoints( 50 ); + const geometry = new THREE.BufferGeometry().setFromPoints( points ); + + const material = new THREE.LineBasicMaterial( { color: 0xff0000 } ); + + // Crea l'oggetto finale da aggiungere alla scena + const ellipse = new THREE.Line( geometry, material ); + + +

    Costruttore

    + + +

    [name]( [param:Float aX], [param:Float aY], [param:Float xRadius], [param:Float yRadius], [param:Radians aStartAngle], [param:Radians aEndAngle], [param:Boolean aClockwise], [param:Radians aRotation] )

    +

    + [page:Float aX] – L'X centro dell'ellipse. Il valore predefinito è `0`.
    + [page:Float aY] – L'Y centro dell'ellipse. Il valore predefinito è `0`.
    + [page:Float xRadius] – Il raggio dell'ellisse nella direzione x. Il valore predefinito è `1`.
    + [page:Float yRadius] – Il raggio dell'ellisse nella direzione y. Il valore predefinito è `1`.
    + [page:Radians aStartAngle] – L'angolo iniziale della curva in radianti a partire dall'asse X positivo. Il valore predefinito è `0`.
    + [page:Radians aEndAngle] – L'angolo finale della curva in radianti a partire dall'asse X positivo. Il valore predefinito è `2 x Math.PI`.
    + [page:Boolean aClockwise] – Se l'ellisse è disegnata in senso orario. Il valore predefinito è `false`.
    + [page:Radians aRotation] – L'angolo di rotazione dell'ellisse in radianti, in senso antiorario dall'asse X positivo (opzionale). Il valore predefinito è `0`.

    +

    + +

    Proprietà

    +

    Vedi la classe [page:Curve] per le proprità comuni.

    + +

    [property:Float aX]

    +

    Il centro X dell'ellisse.

    + +

    [property:Float aY]

    +

    Il centro Y dell'ellisse.

    + +

    [property:Radians xRadius]

    +

    Il raggio dell'ellisse nella direzione x.

    + +

    [property:Radians yRadius]

    +

    Il raggio dell'ellisse nella direzione y.

    + +

    [property:Float aStartAngle]

    +

    L'angolo iniziale della curva in radianti a partire dal lato centrale destro.

    + +

    [property:Float aEndAngle]

    +

    L'angolo finale della curva in radianti a partire dal lato centrale destro.

    + +

    [property:Boolean aClockwise]

    +

    Se l'ellisse è disegnata in senso orario.

    + +

    [property:Float aRotation]

    +

    L'angolo di rotazione dell'ellisse in radianti, in senso antiorario dall'asse X positivo (opzionale). Il valore predefinito è `0`.

    + + +

    Metodi

    +

    Vedi la classe [page:Curve] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/curves/LineCurve.html b/docs/api/it/extras/curves/LineCurve.html new file mode 100644 index 00000000000000..6c528542713fb9 --- /dev/null +++ b/docs/api/it/extras/curves/LineCurve.html @@ -0,0 +1,45 @@ + + + + + + + + + + [page:Curve] → + +

    [name]

    + +

    Una curva che rappresenta un segmento di linea 2D.

    + +

    Costruttore

    + + +

    [name]( [param:Vector2 v1], [param:Vector2 v2] )

    +

    + [page:Vector2 v1] – Il punto di inizio.
    + [page:Vector2 v2] - Il punto di fine. +

    + + +

    Proprietà

    +

    Vedi la classe [page:Curve] per le proprità comuni.

    + +

    [property:Vector2 v1]

    +

    Il punto di inizio.

    + +

    [property:Vector2 v2]

    +

    Il punto di fine.

    + +

    Metodi

    +

    Vedi la classe [page:Curve] per i metodi comuni.

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/curves/LineCurve3.html b/docs/api/it/extras/curves/LineCurve3.html new file mode 100644 index 00000000000000..6fdeb818f947cf --- /dev/null +++ b/docs/api/it/extras/curves/LineCurve3.html @@ -0,0 +1,44 @@ + + + + + + + + + + [page:Curve] → + +

    [name]

    + +

    Una curva che rappresenta un segmento di linea 3D.

    + +

    Costruttore

    + + +

    [name]( [param:Vector3 v1], [param:Vector3 v2] )

    +

    + [page:Vector3 v1] – Il punto di inizio.
    + [page:Vector3 v2] - Il punto di fine. +

    + + +

    Proprietà

    +

    Vedi la classe [page:Curve] per le proprità comuni.

    + +

    [property:Vector3 v1]

    +

    Il punto di inizio.

    + +

    [property:Vector3 v2]

    +

    Il punto di fine.

    + +

    Metodi

    +

    Vedi la classe [page:Curve] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/curves/QuadraticBezierCurve.html b/docs/api/it/extras/curves/QuadraticBezierCurve.html new file mode 100644 index 00000000000000..6f4c6b19a21978 --- /dev/null +++ b/docs/api/it/extras/curves/QuadraticBezierCurve.html @@ -0,0 +1,70 @@ + + + + + + + + + + [page:Curve] → + +

    [name]

    + +

    + Crea una + curva di Bezier quadratica 2D smooth, + definita da un punto di inizio, di fine e un punto di controllo. +

    + +

    Codice di Esempio

    + + + const curve = new THREE.QuadraticBezierCurve( + new THREE.Vector2( -10, 0 ), + new THREE.Vector2( 20, 15 ), + new THREE.Vector2( 10, 0 ) + ); + + const points = curve.getPoints( 50 ); + const geometry = new THREE.BufferGeometry().setFromPoints( points ); + + const material = new THREE.LineBasicMaterial( { color: 0xff0000 } ); + + // Crea l'oggetto finale da aggiungere alla scena + const curveObject = new THREE.Line( geometry, material ); + + +

    Costruttore

    + + +

    [name]( [param:Vector2 v0], [param:Vector2 v1], [param:Vector2 v2] )

    +

    + [page:Vector2 v0] – Il punto di inizio.
    + [page:Vector2 v1] – Il punto di controllo.
    + [page:Vector2 v2] – Il punto di fine. +

    + + +

    Proprietà

    +

    Vedi la classe [page:Curve] per le proprità comuni.

    + +

    [property:Vector2 v0]

    +

    Il punto di inizio.

    + +

    [property:Vector2 v1]

    +

    Il punto di controllo.

    + +

    [property:Vector2 v2]

    +

    Il punto di fine.

    + +

    Metodi

    +

    Vedi la classe [page:Curve] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/curves/QuadraticBezierCurve3.html b/docs/api/it/extras/curves/QuadraticBezierCurve3.html new file mode 100644 index 00000000000000..d56568f92b730d --- /dev/null +++ b/docs/api/it/extras/curves/QuadraticBezierCurve3.html @@ -0,0 +1,71 @@ + + + + + + + + + + [page:Curve] → + +

    [name]

    + +

    + Crea una + curva di Bezier quadratica 3D smooth, + definita da un punto di inizio, di fine e un punto di controllo. +

    + +

    Codice di Esempio

    + + + const curve = new THREE.QuadraticBezierCurve3( + new THREE.Vector3( -10, 0, 0 ), + new THREE.Vector3( 20, 15, 0 ), + new THREE.Vector3( 10, 0, 0 ) + ); + + const points = curve.getPoints( 50 ); + const geometry = new THREE.BufferGeometry().setFromPoints( points ); + + const material = new THREE.LineBasicMaterial( { color: 0xff0000 } ); + + // Crea l'oggetto finale da aggiungere alla scena + const curveObject = new THREE.Line( geometry, material ); + + +

    Costruttore

    + + +

    [name]( [param:Vector3 v0], [param:Vector3 v1], [param:Vector3 v2] )

    +

    + [page:Vector3 v0] – Il punto di inizio.
    + [page:Vector3 v1] – Il punto di controllo.
    + [page:Vector3 v2] – Il punto di fine. +

    + + + +

    Proprietà

    +

    Vedi la classe [page:Curve] per le proprità comuni.

    + +

    [property:Vector3 v0]

    +

    Il punto di inizio.

    + +

    [property:Vector3 v1]

    +

    Il punto di controllo.

    + +

    [property:Vector3 v2]

    +

    Il punto di fine.

    + +

    Metodi

    +

    Vedi la classe [page:Curve] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/extras/curves/SplineCurve.html b/docs/api/it/extras/curves/SplineCurve.html new file mode 100644 index 00000000000000..dcd7303f4ca221 --- /dev/null +++ b/docs/api/it/extras/curves/SplineCurve.html @@ -0,0 +1,62 @@ + + + + + + + + + + [page:Curve] → + +

    [name]

    + +

    + Crea una curva spline 2D smooth da una serie di punti. Internamente + utilizza [page:Interpolations.CatmullRom] per creare la curva. +

    + +

    Codice di Esempio

    + + + // Crea un onda sinusoidale + const curve = new THREE.SplineCurve( [ + new THREE.Vector2( -10, 0 ), + new THREE.Vector2( -5, 5 ), + new THREE.Vector2( 0, 0 ), + new THREE.Vector2( 5, -5 ), + new THREE.Vector2( 10, 0 ) + ] ); + + const points = curve.getPoints( 50 ); + const geometry = new THREE.BufferGeometry().setFromPoints( points ); + + const material = new THREE.LineBasicMaterial( { color: 0xff0000 } ); + + // Crea l'oggetto finale da aggiungere alla scena + const splineObject = new THREE.Line( geometry, material ); + + +

    Costruttore

    + + +

    [name]( [param:Array points] )

    +

    points – Un array di punti [page:Vector2] che definisce la curva.

    + + +

    Proprietà

    +

    Vedi la classe [page:Curve] per le proprità comuni.

    + +

    [property:Array points]

    +

    L'array di punti [page:Vector2] che definisce la curva.

    + +

    Metodi

    +

    Vedi la classe [page:Curve] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/BoxGeometry.html b/docs/api/it/geometries/BoxGeometry.html new file mode 100644 index 00000000000000..45c7f5501e4c94 --- /dev/null +++ b/docs/api/it/geometries/BoxGeometry.html @@ -0,0 +1,74 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    + [name] è una classe di geometria per un cuboide rettangolare con una determinata 'larghezza' (width), 'altezza' (height) e 'profondità' (depth). + Al momento della creazione, il cuboide è centrato nell'origine, con ciascun bordo parallelo ad uno degli assi. +

    + + + + + +

    Codice di Esempio

    + + const geometry = new THREE.BoxGeometry( 1, 1, 1 ); + const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); + const cube = new THREE.Mesh( geometry, material ); + scene.add( cube ); + + +

    Costruttore

    + +

    [name]([param:Float width], [param:Float height], [param:Float depth], [param:Integer widthSegments], [param:Integer heightSegments], [param:Integer depthSegments])

    +

    + width — Larghezza; cioè la lunghezza dei bordi paralleli all'asse X. Opzionale; il valore predefinito è 1.
    + height — Altezza; cioè la lunghezza dei bordi paralleli all'asse Y. Opzionale; il valore predefinito è 1.
    + depth — Profondità; cioè la lunghezza dei bordi paralleli all'asse Z. Opzionale; il valore predefinito è 1.
    + widthSegments — Numero di facce rettangolari segmentate lungo la larghezza dei lati. Opzionale; il valore predefinito è 1.
    + heightSegments — Numero di facce rettangolari segmentate lungo l'altezza dei lati. Opzionale; il valore predefinito è 1.
    + depthSegments — Numero di facce rettangolari segmentate lungo la profondità dei lati. Opzionale; il valore predefinito è 1.
    +

    + +

    Proprietà

    +

    Vedi la classe base [page:BufferGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:BufferGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/CapsuleGeometry.html b/docs/api/it/geometries/CapsuleGeometry.html new file mode 100644 index 00000000000000..944b9008df5f0b --- /dev/null +++ b/docs/api/it/geometries/CapsuleGeometry.html @@ -0,0 +1,73 @@ + + + + + + + + + + [page:BufferGeometry] → [page:LatheGeometry] → + +

    [name]

    + +

    + [name] è una classe di geometria per una capsula con raggi e altezza dati. + Viene costruita utilizzando un tornio. +

    + + + + + +

    Codice di Esempio

    + + const geometry = new THREE.CapsuleGeometry( 1, 1, 4, 8 ); + const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); + const capsule = new THREE.Mesh( geometry, material ); + scene.add( capsule ); + + +

    Costruttore

    + +

    [name]([param:Float radius], [param:Float length], [param:Integer capSubdivisions], [param:Integer radialSegments])

    +

    + + radius — Raggio della capsula. Opzionale; il valore predefinito è 1.
    + length — Lunghezza della sezione centrale. Opzionale; il valore predefinito è 1.
    + capSegments — Numero di segmenti curvi utilizzato per costruire i tappi della capsula. Opzionale; il valore predefinito è 4.
    + radialSegments — Numero di facce segmentate attorno alla circonferenza della capsula. Opzionale; il valore predefinito è 8.
    +

    + +

    Proprietà

    +

    Vedi la classe base [page:BufferGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:BufferGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/CircleGeometry.html b/docs/api/it/geometries/CircleGeometry.html new file mode 100644 index 00000000000000..92b4a896733139 --- /dev/null +++ b/docs/api/it/geometries/CircleGeometry.html @@ -0,0 +1,75 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    + [name] è una forma semplice della geometria Euclidea. + È costruita a partire da una serie di segmenti triangolari orientati intorno ad un punto centrale, che si estendono fino ad un determinato raggio. + È costruita in senso antiorario a partire da un angolo iniziale e da un angolo centrale dato. + Può essere utilizzata anche per creare poligoni regolari, dove il numero di segmenti determina il numero di lati. +

    + + + + + +

    Codice di Esempio

    + + + const geometry = new THREE.CircleGeometry( 5, 32 ); + const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); + const circle = new THREE.Mesh( geometry, material ); + scene.add( circle ); + + +

    Costruttore

    + +

    [name]([param:Float radius], [param:Integer segments], [param:Float thetaStart], [param:Float thetaLength])

    +

    + radius — Raggio del cerchio. Il valore predefinito è 1.
    + segments — Numero di segmenti (triangoli). Il valore minimo è 3. Il valore predefinito è 8.
    + thetaStart — Angolo iniziale per il primo segmento. Il valore predefinito è 0 (posizione ore tre).
    + thetaLength — L'angolo centrale, spesso chiamato theta, del settore circolare. Il valore predefinito è 2*Pi, che crea un cerchio completo. +

    + +

    Proprietà

    +

    Vedi la classe base [page:BufferGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:BufferGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/ConeGeometry.html b/docs/api/it/geometries/ConeGeometry.html new file mode 100644 index 00000000000000..e5b049ec16b0a1 --- /dev/null +++ b/docs/api/it/geometries/ConeGeometry.html @@ -0,0 +1,72 @@ + + + + + + + + + + [page:BufferGeometry] → [page:CylinderGeometry] → + +

    [name]

    + +

    Una classe per la generazione di geometrie di coni.

    + + + + + +

    Codice di Esempio

    + + const geometry = new THREE.ConeGeometry( 5, 20, 32 ); + const material = new THREE.MeshBasicMaterial( {color: 0xffff00} ); + const cone = new THREE.Mesh( geometry, material ); + scene.add( cone ); + + +

    Costruttore

    + +

    [name]([param:Float radius], [param:Float height], [param:Integer radialSegments], [param:Integer heightSegments], [param:Boolean openEnded], [param:Float thetaStart], [param:Float thetaLength])

    +

    + radius — Raggio della base del cono. Il valore predefinito è 1.
    + height — Altezza del cono. Il valore predefinito è 1.
    + radialSegments — Numero di facce segmentate intorno alla circonferenza del cono. Il valore predefinito è 8.
    + heightSegments — Numero di file di facce lungo l'altezza del cono. Il valore predefinito è 1.
    + openEnded — Un booleano che indica se la base del cono è aperta o chiusa. Il valore predefinito è false, significa chiusa.
    + thetaStart — Angolo iniziale per il primo segmento. Il valore predefinito è 0 (posizione ore tre).
    + thetaLength — L'angolo centrale, spesso chiamato theta, del settore circolare. Il valore predefinito è 2*Pi, che crea un cono completo. +

    + +

    Proprietà

    +

    Vedi la classe base [page:CylinderGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:CylinderGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/CylinderGeometry.html b/docs/api/it/geometries/CylinderGeometry.html new file mode 100644 index 00000000000000..7ecf7cfac597db --- /dev/null +++ b/docs/api/it/geometries/CylinderGeometry.html @@ -0,0 +1,73 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Una classe per la generazione di geometrie di cilindri.

    + + + + + +

    Codice di Esempio

    + + const geometry = new THREE.CylinderGeometry( 5, 5, 20, 32 ); + const material = new THREE.MeshBasicMaterial( {color: 0xffff00} ); + const cylinder = new THREE.Mesh( geometry, material ); + scene.add( cylinder ); + + +

    Costruttore

    + +

    [name]([param:Float radiusTop], [param:Float radiusBottom], [param:Float height], [param:Integer radialSegments], [param:Integer heightSegments], [param:Boolean openEnded], [param:Float thetaStart], [param:Float thetaLength])

    +

    + radiusTop — Raggio del cilindro nella parte superiore. Il valore predefinito è 1.
    + radiusBottom — Raggio del cilindro nella parte inferiore. Il valore predefinito è 1.
    + height — Altezza del cilindro. Il valore predefinito è 1.
    + radialSegments — Numero di facce segmentate intorno alla circonferenza del cilindro. Il valore predefinito è 8
    + heightSegments — Numero di file delle facce lungo l'altezza del cilindro. Il valore predefinito è 1.
    + openEnded — Un booleano che indica se le estremità del cilindro sono aperte o chiuse. Il valore predefinito è false, significa chiuse.
    + thetaStart — L'angolo di partenza del primo segmento. Il valore predefinito è 0 (posizione ore tre).
    + thetaLength — L'angolo centrale, spesso chiamato theta, del settore circolare. Il valore predefinito è 2*Pi, che crea un cilindro completo. +

    + +

    Proprietà

    +

    Vedi la classe base [page:BufferGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:BufferGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/DodecahedronGeometry.html b/docs/api/it/geometries/DodecahedronGeometry.html new file mode 100644 index 00000000000000..89ff5ac5e47e00 --- /dev/null +++ b/docs/api/it/geometries/DodecahedronGeometry.html @@ -0,0 +1,59 @@ + + + + + + + + + + [page:BufferGeometry] → [page:PolyhedronGeometry] → + +

    [name]

    + +

    Una classe per la generazione di geometrie di un dodecaedro.

    + + + + + +

    Costruttore

    + +

    [name]([param:Float radius], [param:Integer detail])

    +

    + radius — Raggio del dodecaedro. Il valore predefinito è 1.
    + detail — Il valore predefinito è 0. Impostandolo ad un valore maggiore di 0 si aggiungono vertici rendendolo non più un dodecaedro. +

    + +

    Proprietà

    +

    Vedi la classe base [page:PolyhedronGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:PolyhedronGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/EdgesGeometry.html b/docs/api/it/geometries/EdgesGeometry.html new file mode 100644 index 00000000000000..0541fd1a6ca374 --- /dev/null +++ b/docs/api/it/geometries/EdgesGeometry.html @@ -0,0 +1,56 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Questa classe può essere utilizzata come oggetto di supporto per visualizzare i bordi di una [page:BufferGeometry geometria].

    + +

    Codice di Esempio

    + + +const geometry = new THREE.BoxGeometry( 100, 100, 100 ); +const edges = new THREE.EdgesGeometry( geometry ); +const line = new THREE.LineSegments( edges, new THREE.LineBasicMaterial( { color: 0xffffff } ) ); +scene.add( line ); + + +

    Esempi

    +

    + [example:webgl_helpers helpers] +

    + +

    Costruttore

    + +

    [name]( [param:BufferGeometry geometry], [param:Integer thresholdAngle] )

    +

    + geometry — Qualsiasi oggetto geometria.
    + thresholdAngle — Un bordo viene renderizzato solo se l'angolo (in gradi) tra le normali delle facce adiacenti supera questo valore. + Il valore predefinito è 1 grado. +

    + +

    Proprietà

    +

    Vedi la classe base [page:BufferGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:BufferGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/ExtrudeGeometry.html b/docs/api/it/geometries/ExtrudeGeometry.html new file mode 100644 index 00000000000000..8ea08a3fdfc251 --- /dev/null +++ b/docs/api/it/geometries/ExtrudeGeometry.html @@ -0,0 +1,113 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Crea una geometria estrusa da una forma di tracciato (path shape).

    + + + + + +

    Codice di Esempio

    + + + + const length = 12, width = 8; + + const shape = new THREE.Shape(); + shape.moveTo( 0,0 ); + shape.lineTo( 0, width ); + shape.lineTo( length, width ); + shape.lineTo( length, 0 ); + shape.lineTo( 0, 0 ); + + const extrudeSettings = { + steps: 2, + depth: 16, + bevelEnabled: true, + bevelThickness: 1, + bevelSize: 1, + bevelOffset: 0, + bevelSegments: 1 + }; + + const geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings ); + const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); + const mesh = new THREE.Mesh( geometry, material ) ; + scene.add( mesh ); + + + +

    Costruttore

    + + +

    [name]([param:Array shapes], [param:Object options])

    +

    + shapes — Shape o un array di shape.
    + options — Oggetto che può contenere i seguenti parametri. + +

      +
    • curveSegments — int. Numero di punti sulle curve. Il valore predefinito è 12.
    • +
    • steps — int. Numero di punti utilizzati per suddividere i segmenti lungo la profondità della spline estrusa. Il valore predefinito è 1.
    • +
    • depth — float. Profondità per estrudere la forma. Il valore predefinito è 1.
    • +
    • bevelEnabled — bool. Applica la smussatura alla forma. Il valore predefinito è true.
    • +
    • bevelThickness — float. Quanto in profondità nella forma originale va la smussatura. Il valore predefinito è 0.2.
    • +
    • bevelSize — float. Distanza dal contorno della forma a cui si estende lo smusso. Il valore predefinito è bevelThickness - 0.1.
    • +
    • bevelOffset — float. Distanza dal contorno della forma a cui inizia lo smusso. Il valore predefinito è 0.
    • +
    • bevelSegments — int. Numero di strati di smusso. Il valore predefinito è 3.
    • +
    • extrudePath — THREE.Curve. Un path spline 3D lungo il quale deve essere eatrusa la forma. Smussi non supportati per l'estrusione del percorso.
    • +
    • UVGenerator — Object. Oggetto che fornisce le funzioni di generatore UV
    • +
    + +

    +

    + Questo oggetto estrude una forma 2D in una geometria 3D. +

    + +

    + Quando viene creata una Mesh con questa geometria, se desideri utilizzare un materiale separato per + la sua faccia e i suoi lati estrusi, puoi utilizzare l'array dei materiali. Il primo materiale + sarà applicato alla faccia; il secondo materiale sarà applicato ai lati. +

    + +

    Proprietà

    +

    Vedi la classe base [page:BufferGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:BufferGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/IcosahedronGeometry.html b/docs/api/it/geometries/IcosahedronGeometry.html new file mode 100644 index 00000000000000..983949f59258f8 --- /dev/null +++ b/docs/api/it/geometries/IcosahedronGeometry.html @@ -0,0 +1,59 @@ + + + + + + + + + + [page:BufferGeometry] → [page:PolyhedronGeometry] → +

    [name]

    + +

    Una classe per generare una geometria icosaedrica.

    + + + + + +

    Costruttore

    + +

    [name]([param:Float radius], [param:Integer detail])

    +

    + radius — Il valore predefinito è 1.
    + detail — Il valore predefinito è 0. Impostandolo ad un valore maggiore di 0 si aggiungono più vertici, rendendo il modello non più un icosaedro. + Quando il dettaglio (detail) è maggiore di 1, è effettivamente una sfera. +

    + +

    Proprietà

    +

    Vedi la classe base [page:PolyhedronGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:PolyhedronGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/LatheGeometry.html b/docs/api/it/geometries/LatheGeometry.html new file mode 100644 index 00000000000000..55226d98ecdf08 --- /dev/null +++ b/docs/api/it/geometries/LatheGeometry.html @@ -0,0 +1,78 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Crea mesh con simmetria assiale come vasi. Il tornio ruota attorno all'asse Y.

    + + + + + +

    Codice di Esempio

    + + + const points = []; + for ( let i = 0; i < 10; i ++ ) { + points.push( new THREE.Vector2( Math.sin( i * 0.2 ) * 10 + 5, ( i - 5 ) * 2 ) ); + } + const geometry = new THREE.LatheGeometry( points ); + const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); + const lathe = new THREE.Mesh( geometry, material ); + scene.add( lathe ); + + +

    Costruttore

    + +

    [name]([param:Array points], [param:Integer segments], [param:Float phiStart], [param:Float phiLength])

    +

    + points — Array di Vector2. La coordinata x di ogni punto deve essere maggiore di zero. + Il valore predefinito è un array con (0,-0.5), (0.5,0) e (0,0.5) il quale crea una semplice forma a diamante.
    + segments — il numero di segmenti di circonferenza da generare. Il valore predefinito è 12.
    + phiStart — l'angolo di partenza in radianti. Il valore predefinito è 0.
    + phiLength — l'intervallo in radianti (da 0 ta 2PI) della sezione tornita 2PI è un tornio chiuso, meno di 2PI è una porzione. Il valore predefinito è 2PI. +

    +

    + Questo crea una [name] basata sui parametri. +

    + +

    Proprietà

    +

    Vedi la classe base [page:BufferGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:BufferGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/OctahedronGeometry.html b/docs/api/it/geometries/OctahedronGeometry.html new file mode 100644 index 00000000000000..8b406740aecdb3 --- /dev/null +++ b/docs/api/it/geometries/OctahedronGeometry.html @@ -0,0 +1,58 @@ + + + + + + + + + + [page:BufferGeometry] → [page:PolyhedronGeometry] → +

    [name]

    + +

    Una classe per generare la geometria di un ottaedro.

    + + + + + +

    Costruttore

    + +

    [name]([param:Float radius], [param:Integer detail])

    +

    + radius — Raggio di un ottaedro. Il valore predefinito è 1.
    + detail — Il valore predefinito è 0. Impostandolo ad un valore maggiore di zero si aggiungono vertici, rendendo l'ottaedro non più tale. +

    + +

    Proprietà

    +

    Vedi la classe base [page:PolyhedronGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:PolyhedronGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/PlaneGeometry.html b/docs/api/it/geometries/PlaneGeometry.html new file mode 100644 index 00000000000000..e1fc65871a1203 --- /dev/null +++ b/docs/api/it/geometries/PlaneGeometry.html @@ -0,0 +1,69 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Una classe per generare la geometria di un piano.

    + + + + + +

    Codice di Esempio

    + + const geometry = new THREE.PlaneGeometry( 1, 1 ); + const material = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} ); + const plane = new THREE.Mesh( geometry, material ); + scene.add( plane ); + + +

    Costruttore

    + +

    [name]([param:Float width], [param:Float height], [param:Integer widthSegments], [param:Integer heightSegments])

    +

    + width — Larghezza lungo l'asse X. Il valore predefinito è 1.
    + height — Altezza lungo l'asse Y. Il valore predefinito è 1.
    + widthSegments — Opzionale. Il valore predefinito è 1.
    + heightSegments — Opzionale. Il valore predefinito è 1. +

    + +

    Proprietà

    +

    Vedi la classe base [page:BufferGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:BufferGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/PolyhedronGeometry.html b/docs/api/it/geometries/PolyhedronGeometry.html new file mode 100644 index 00000000000000..2b1cceee9267b1 --- /dev/null +++ b/docs/api/it/geometries/PolyhedronGeometry.html @@ -0,0 +1,68 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    + Un poliedro è un solido in tre dimensioni con le facce piatte. Questa classe prende un array di vertici, + li proietta su una sfera, e li dividerà fino al livello di dettaglio desiderato. Questa classe è utilizzata + da [page:DodecahedronGeometry], [page:IcosahedronGeometry], [page:OctahedronGeometry], + e [page:TetrahedronGeometry] per generare queste rispettive geometrie. +

    + +

    Codice id Esempio

    + +const verticesOfCube = [ + -1,-1,-1, 1,-1,-1, 1, 1,-1, -1, 1,-1, + -1,-1, 1, 1,-1, 1, 1, 1, 1, -1, 1, 1, +]; + +const indicesOfFaces = [ + 2,1,0, 0,3,2, + 0,4,7, 7,3,0, + 0,1,5, 5,4,0, + 1,2,6, 6,5,1, + 2,3,7, 7,6,2, + 4,5,6, 6,7,4 +]; + +const geometry = new THREE.PolyhedronGeometry( verticesOfCube, indicesOfFaces, 6, 2 ); + + +

    Costruttore

    + + +

    [name]([param:Array vertices], [param:Array indices], [param:Float radius], [param:Integer detail])

    +

    + vertices — [page:Array] di punti della forma [1,1,1, -1,-1,-1, ... ]
    + indices — [page:Array] di indici che compongono le facce della forma [0,1,2, 2,3,0, ... ]
    + radius — [page:Float] - Il raggio della forma finale
    + detail — [page:Integer] - In quanti livelli suddividere la geometria. Più dettagli, più liscia è la forma. +

    + +

    Proprietà

    +

    Vedi la classe base [page:BufferGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:BufferGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/RingGeometry.html b/docs/api/it/geometries/RingGeometry.html new file mode 100644 index 00000000000000..406cb67830922d --- /dev/null +++ b/docs/api/it/geometries/RingGeometry.html @@ -0,0 +1,72 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Una classe per la generazione di una geometria ad anello bidimensionale.

    + + + + + +

    Codice di Esempio

    + + const geometry = new THREE.RingGeometry( 1, 5, 32 ); + const material = new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } ); + const mesh = new THREE.Mesh( geometry, material ); + scene.add( mesh ); + + +

    Costruttore

    + +

    [name]([param:Float innerRadius], [param:Float outerRadius], [param:Integer thetaSegments], [param:Integer phiSegments], [param:Float thetaStart], [param:Float thetaLength])

    +

    + innerRadius — Il valore predefinito è 0.5.
    + outerRadius — Il valore predefinito è 1.
    + thetaSegments — Numero di segmenti. Un numero alto significa che l'anello sarà più rotondo. Il valore minimo è 3. Il valore predefinito è 8.
    + phiSegments — Il valore minimo è 1. Il valore predefinito è 1.
    + thetaStart — Angolo di partenza. Il valore predefinito è 0.
    + thetaLength — Angolo centrale. Il valore predefinito è Math.PI * 2. +

    + + +

    Proprietà

    +

    Vedi la classe base [page:BufferGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:BufferGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/ShapeGeometry.html b/docs/api/it/geometries/ShapeGeometry.html new file mode 100644 index 00000000000000..9d41f036d135ac --- /dev/null +++ b/docs/api/it/geometries/ShapeGeometry.html @@ -0,0 +1,83 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Crea una geometria poligonale unilaterale da una o più forme di tracciato.

    + + + + + + +

    Codice di Esempio

    + + + + const x = 0, y = 0; + + const heartShape = new THREE.Shape(); + + heartShape.moveTo( x + 5, y + 5 ); + heartShape.bezierCurveTo( x + 5, y + 5, x + 4, y, x, y ); + heartShape.bezierCurveTo( x - 6, y, x - 6, y + 7,x - 6, y + 7 ); + heartShape.bezierCurveTo( x - 6, y + 11, x - 3, y + 15.4, x + 5, y + 19 ); + heartShape.bezierCurveTo( x + 12, y + 15.4, x + 16, y + 11, x + 16, y + 7 ); + heartShape.bezierCurveTo( x + 16, y + 7, x + 16, y, x + 10, y ); + heartShape.bezierCurveTo( x + 7, y, x + 5, y + 5, x + 5, y + 5 ); + + const geometry = new THREE.ShapeGeometry( heartShape ); + const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); + const mesh = new THREE.Mesh( geometry, material ) ; + scene.add( mesh ); + + +

    Costruttore

    + + +

    [name]([param:Array shapes], [param:Integer curveSegments])

    +

    + shapes — [page:Array] di forme o di una singola [page:Shape forma]. L'impostazione predefinita è una singola forma triangolare.
    + curveSegments - [page:Integer] - Numero di segmenti per forma. Il valore predefinito è 12. +

    + +

    Proprietà

    +

    Vedi la classe base [page:BufferGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:BufferGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/SphereGeometry.html b/docs/api/it/geometries/SphereGeometry.html new file mode 100644 index 00000000000000..565717f4c23063 --- /dev/null +++ b/docs/api/it/geometries/SphereGeometry.html @@ -0,0 +1,79 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Una classe per generare geometrie di sfere.

    + + + + + +

    Codice di Esempio

    + + const geometry = new THREE.SphereGeometry( 15, 32, 16 ); + const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); + const sphere = new THREE.Mesh( geometry, material ); + scene.add( sphere ); + + +

    Costruttore

    + +

    [name]([param:Float radius], [param:Integer widthSegments], [param:Integer heightSegments], [param:Float phiStart], [param:Float phiLength], [param:Float thetaStart], [param:Float thetaLength])

    + +

    + radius — raggio della sfera. Il valore predefinito è 1.
    + widthSegments — numero di segmenti orizzontali. Il valore minimo è 3 e il valore predefinito è 32.
    + heightSegments — numero di segmenti verticali. Il valore minimo è 2 e il valore predefinito è 16.
    + phiStart — specifica l'angolo di partenza orizzontale. Il valore predefinito è 0.
    + phiLength — specifica la dimensione dell'angolo di ampiezza orizzontale. Il valore predefinito è Math.PI * 2.
    + thetaStart — specifica l'angolo di partenza verticale. Il valore predefinito è 0.
    + thetaLength — specifica la dimensione dell'angolo di ampiezza verticale. Il valore predefinito è Math.PI.
    +

    + +

    + La geometria viene creata eseguendo lo sweep e il calcolo dei vertici attorno all'asse Y (sweep orizzontale) e all'asse Z (sweep verticale). + Pertanto, le sfere incomplete (simili a `'fette di sfere'`) possono essere create attraverso l'utilizzo dei diversi valori di + phiStart, phiLength, thetaStart e thetaLength, al fine di definire i punti in cui iniziamo (o finiamo) il calcolo di quei vertici. +

    + +

    Proprietà

    +

    Vedi la classe base [page:BufferGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:BufferGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/TetrahedronGeometry.html b/docs/api/it/geometries/TetrahedronGeometry.html new file mode 100644 index 00000000000000..18bb32881a6f44 --- /dev/null +++ b/docs/api/it/geometries/TetrahedronGeometry.html @@ -0,0 +1,59 @@ + + + + + + + + + + [page:BufferGeometry] → [page:PolyhedronGeometry] → + +

    [name]

    + +

    Una classe per la generazione di geometrie di tetraedri.

    + + + + + +

    Costruttore

    + +

    [name]([param:Float radius], [param:Integer detail])

    +

    + radius — Raggio del tetraedro. Il valore predefinito è 1.
    + detail — Il valore predefinito è 0. Impostandolo ad un valore maggiore di 0 si aggiungono più vertici, rendendo il modello non più un tetraedro. +

    + +

    Proprietà

    +

    Vedi la classe base [page:PolyhedronGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:PolyhedronGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/TorusGeometry.html b/docs/api/it/geometries/TorusGeometry.html new file mode 100644 index 00000000000000..f2f638b4f7be83 --- /dev/null +++ b/docs/api/it/geometries/TorusGeometry.html @@ -0,0 +1,70 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Una classe per la generazione di geometrie toroidali.

    + + + + + +

    Codice di Esempio

    + + const geometry = new THREE.TorusGeometry( 10, 3, 16, 100 ); + const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); + const torus = new THREE.Mesh( geometry, material ); + scene.add( torus ); + + +

    Costruttore

    + +

    [name]([param:Float radius], [param:Float tube], [param:Integer radialSegments], [param:Integer tubularSegments], [param:Float arc])

    +

    + radius - Raggio del toro, dal centro del toro al centro del tubo. Il valore predefinito è 1.
    + tube — Raggio del tubo. Il valore predefinito è 0.4.
    + radialSegments — Il valore predefinito è 8
    + tubularSegments — Il valore predefinito è 6.
    + arc — Angolo centrale. Il valore predefinito è Math.PI * 2. +

    + +

    Proprietà

    +

    Vedi la classe base [page:BufferGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:BufferGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/TorusKnotGeometry.html b/docs/api/it/geometries/TorusKnotGeometry.html new file mode 100644 index 00000000000000..2aea69daf8e5e6 --- /dev/null +++ b/docs/api/it/geometries/TorusKnotGeometry.html @@ -0,0 +1,74 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Crea un nodo toroidale, la cui forma particolare è definita da una coppia di interi coprimi, p e q. + Se p e q non sono coprimi, il risultato sarà un collegamento toroidale.

    + + + + + +

    Codice di Esempio

    + + const geometry = new THREE.TorusKnotGeometry( 10, 3, 100, 16 ); + const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); + const torusKnot = new THREE.Mesh( geometry, material ); + scene.add( torusKnot ); + + +

    Costruttrore

    + +

    [name]([param:Float radius], [param:Float tube], [param:Integer tubularSegments], [param:Integer radialSegments], [param:Integer p], [param:Integer q])

    +

    +

      +
    • radius - Raggio del toro. Il valore predefinito è 1.
    • +
    • tube — Raggio del tubo. Il valore predefinito è 0.4.
    • +
    • tubularSegments — Il valore predefinito è 64.
    • +
    • radialSegments — Il valore predefinito è 8.
    • +
    • p — Questo valore determina, quante volte la geometria si avvolge attorno al suo asse di simmetria rotazionale. Il valore predefinito è 2.
    • +
    • q — Questo valore determina, quante volte la geometria si avvolge attorno ad un cerchio all'interno del toro. Il valore predefinito è 3.
    • +
    +

    + +

    Proprietà

    +

    Vedi la classe base [page:BufferGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    Metodi

    +

    Vedi la classe base [page:BufferGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/TubeGeometry.html b/docs/api/it/geometries/TubeGeometry.html new file mode 100644 index 00000000000000..705876b0250d9e --- /dev/null +++ b/docs/api/it/geometries/TubeGeometry.html @@ -0,0 +1,111 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Crea un tubo che si estrude lungo una curva 3d.

    + + + + + +

    Codice di Esempio

    + + + class CustomSinCurve extends THREE.Curve { + + constructor( scale = 1 ) { + + super(); + + this.scale = scale; + + } + + getPoint( t, optionalTarget = new THREE.Vector3() ) { + + const tx = t * 3 - 1.5; + const ty = Math.sin( 2 * Math.PI * t ); + const tz = 0; + + return optionalTarget.set( tx, ty, tz ).multiplyScalar( this.scale ); + + } + + } + + const path = new CustomSinCurve( 10 ); + const geometry = new THREE.TubeGeometry( path, 20, 2, 8, false ); + const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); + const mesh = new THREE.Mesh( geometry, material ); + scene.add( mesh ); + + +

    Costruttore

    + + +

    [name]([param:Curve path], [param:Integer tubularSegments], [param:Float radius], [param:Integer radialSegments], [param:Boolean closed])

    +

    + path — [page:Curve] - Un path 3D che eredita dalla classe base [page:Curve]. Il valore predefinito è una curva quadratica di Bézier.
    + tubularSegments — [page:Integer] - Il numero di segmenti che compongono il tubo. Il valore predefinito è `64`.
    + radius — [page:Float] - Il raggio del tubo. Il valore predefinito è `1`.
    + radialSegments — [page:Integer] - Il numero dei segmenti che compongono la sezione trasversale. Il valore predefinito è `8`.
    + closed — [page:Boolean] Indica se il tubo è aperto o chiuso. Il valore predefinito è `false`.
    +

    + + +

    Proprietà

    +

    Vedi la classe base [page:BufferGeometry] per le proprietà comuni.

    + +

    [property:Object parameters]

    +

    + Un oggetto con una proprietà per ognuno dei parametri del costruttore. Qualsiasi modifica dopo l'istanziazione non cambia la geometria. +

    + +

    [property:Array tangents]

    +

    + Un array [page:Vector3] di tangenti +

    + +

    [property:Array normals]

    +

    + Un array [page:Vector3] di normali +

    + +

    [property:Array binormals]

    +

    + Un array [page:Vector3] di binormali +

    + +

    Metodi

    +

    Vedi la classe base [page:BufferGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/geometries/WireframeGeometry.html b/docs/api/it/geometries/WireframeGeometry.html new file mode 100644 index 00000000000000..96a87401c9c512 --- /dev/null +++ b/docs/api/it/geometries/WireframeGeometry.html @@ -0,0 +1,56 @@ + + + + + + + + + + [page:BufferGeometry] → + +

    [name]

    + +

    Questa classe può essere utilizzata come oggetto di supporto per la visualizzazione di una [page:BufferGeometry geometria] come wireframe.

    + +

    Codice di Esempio

    + + + const geometry = new THREE.SphereGeometry( 100, 100, 100 ); + + const wireframe = new THREE.WireframeGeometry( geometry ); + + const line = new THREE.LineSegments( wireframe ); + line.material.depthTest = false; + line.material.opacity = 0.25; + line.material.transparent = true; + + scene.add( line ); + + +

    Esempi

    + +

    + [example:webgl_helpers helpers] +

    + +

    Costruttore

    + +

    [name]( [param:BufferGeometry geometry] )

    +

    + geometry — qualsiasi oggetto geometria. +

    + +

    Proprietà

    +

    Vedi la classe base [page:BufferGeometry] per le proprietà comuni.

    + +

    Metodi

    +

    Vedi la classe base [page:BufferGeometry] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/helpers/ArrowHelper.html b/docs/api/it/helpers/ArrowHelper.html new file mode 100644 index 00000000000000..e938c1e3fe6357 --- /dev/null +++ b/docs/api/it/helpers/ArrowHelper.html @@ -0,0 +1,91 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    Un oggetto freccia 3D per visualizzare le direzioni.

    + +

    Codice di Esempio

    + + + const dir = new THREE.Vector3( 1, 2, 0 ); + + // normalizza il vettore direzione (converte il vettore di lunghezza 1) + dir.normalize(); + + const origin = new THREE.Vector3( 0, 0, 0 ); + const length = 1; + const hex = 0xffff00; + + const arrowHelper = new THREE.ArrowHelper( dir, origin, length, hex ); + scene.add( arrowHelper ); + + +

    Esempi

    + +

    + [example:webgl_shadowmesh WebGL / shadowmesh] +

    + +

    Costruttore

    + +

    [name]([param:Vector3 dir], [param:Vector3 origin], [param:Number length], [param:Number hex], [param:Number headLength], [param:Number headWidth] )

    +

    + [page:Vector3 dir] -- Direzione dall'origine. Deve essere un vettore unitario.
    + [page:Vector3 origin] -- Punto in cui inizia la freccia.
    + [page:Number length] -- Lunghezza della freccia. Il valore predefinito è `1`.
    + [page:Number hex] -- Valore esadecimale per definire il colore. Il valore predefinito è 0xffff00.
    + [page:Number headLength] -- Lunghezza della punta della freccia. Il valore predefinito è 0.2 * length.
    + [page:Number headWidth] -- Larghezza della punta della fraccia. Il valore predefinito è 0.2 * headLength.
    +

    + +

    Proprietà

    +

    Vedi la classe base [page:Object3D] per le proprietà in comune.

    + +

    [property:Line line]

    +

    Contiene la parte della linea di arrowHelper.

    + +

    [property:Mesh cone]

    +

    Contiene la prte conica dell'arrowHelper.

    + +

    Metodi

    +

    Vedi la classe base [page:Object3D] per i metodi comuni.

    + +

    [method:undefined setColor]([param:Color color])

    +

    + color -- Il colore desiderato.

    + + Imposta il colore dell'arrowHelper. +

    + +

    [method:undefined setLength]([param:Number length], [param:Number headLength], [param:Number headWidth])

    +

    + length -- La lunghezza desiderata.
    + headLength -- La lunghezza della punta della freccia.
    + headWidth -- La larghezza della punta della freccia.

    + + Imposta la lunghezza dell'arrowHelper +

    + +

    [method:undefined setDirection]([param:Vector3 dir])

    +

    + dir -- La direzione desiderata. Deve essere un vettore unitario.

    + + Imposta la direzione dell'arrowHelper. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/helpers/AxesHelper.html b/docs/api/it/helpers/AxesHelper.html new file mode 100644 index 00000000000000..2185a813a05562 --- /dev/null +++ b/docs/api/it/helpers/AxesHelper.html @@ -0,0 +1,63 @@ + + + + + + + + + + [page:Object3D] → [page:Line] → [page:LineSegments] → + +

    [name]

    + +

    Un oggetto asse per visualizzare i 3 assi in modo semplice.
    + L'asse X è rossa. L'asse Y è verde. L'asse Z è blu. +

    + +

    Codice di Esempio

    + + +const axesHelper = new THREE.AxesHelper( 5 ); +scene.add( axesHelper ); + + +

    Esempi

    + +

    + [example:webgl_buffergeometry_compression WebGL / buffergeometry / compression]
    + [example:webgl_geometry_convex WebGL / geometry / convex]
    + [example:webgl_loader_nrrd WebGL / loader / nrrd] +

    + +

    Costruttore

    + + +

    [name]( [param:Number size] )

    +

    + [page:Number size] -- (opzionale) dimensione delle linee che rappresentano gli assi. Il valore predefinito è `1`. +

    + +

    Proprietà

    +

    Vedi la classe base [page:LineSegments] per le proprietà in comune.

    + +

    Metodi

    +

    Vedi la classe base [page:LineSegments] per i metodi comuni.

    + +

    [method:this setColors]( [param:Color xAxisColor], [param:Color yAxisColor], [param:Color zAxisColor] )

    +

    + Imposta il colore degli assi a [page:Color xAxisColor], [page:Color yAxisColor], [page:Color zAxisColor]. +

    + +

    [method:undefined dispose]()

    +

    + Elimina il [page:Line.material materiale] e la [page:Line.geometry geometria] creati internamente utilizzati da questo helper. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/helpers/Box3Helper.html b/docs/api/it/helpers/Box3Helper.html new file mode 100644 index 00000000000000..44df7c7f25533c --- /dev/null +++ b/docs/api/it/helpers/Box3Helper.html @@ -0,0 +1,61 @@ + + + + + + + + + + [page:Object3D] → [page:Line] → [page:LineSegments] → + +

    [name]

    + +

    + Oggetto per visualizzare una [page:Box3]. +

    + +

    Codice di Esempio

    + + + const box = new THREE.Box3(); + box.setFromCenterAndSize( new THREE.Vector3( 1, 1, 1 ), new THREE.Vector3( 2, 1, 3 ) ); + + const helper = new THREE.Box3Helper( box, 0xffff00 ); + scene.add( helper ); + + + +

    Costruttore

    + + +

    [name]( [param:Box3 box], [param:Color color] )

    +

    + [page:Box3 box] -- il Box3 da mostrare.
    + [page:Color color] -- (opzionale) il colore del box. Il valore predefinito è 0xffff00.

    + + Crea un nuovo wireframe box che rappresenta il Box3 passato. +

    + +

    Proprietà

    +

    Vedi la classe base [page:LineSegments] per le proprietà in comune.

    + +

    [property:Box3 box]

    +

    Il Box3 visualizzato.

    + +

    Metodi

    +

    Vedi la classe base [page:LineSegments] per i metodi comuni.

    + +

    [method:undefined updateMatrixWorld]( [param:Boolean force] )

    +

    + Questo sovrascrive il metodo nella classe base [page:Object3D] così che + aggiorni anche il wireframe box nell'ambito della proprietà [page:Box3Helper.box .box] +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/helpers/BoxHelper.html b/docs/api/it/helpers/BoxHelper.html new file mode 100644 index 00000000000000..d0641aa7ed5589 --- /dev/null +++ b/docs/api/it/helpers/BoxHelper.html @@ -0,0 +1,76 @@ + + + + + + + + + + [page:Object3D] → [page:Line] → [page:LineSegments] → + +

    [name]

    + +

    + Oggetto di aiuto per mostrare graficamente il bounding box allineato all'asse world intorno ad un oggetto. + Il bounding box vero e proprio è gestito da [page:Box3], questo è solo un aiuto visivo per il debug. + Può essere ridimensionato automaticamente tramite il metodo [page:BoxHelper.update] quando l'oggetto + da cui è stato creato viene trasformato. Si noti che l'oggetto deve avere una [page:BufferGeometry] + per funzionare, quindi non funziona con gli [page:Sprite Sprite]. +

    + +

    Codice di Esempio

    + + + const sphere = new THREE.SphereGeometry(); + const object = new THREE.Mesh( sphere, new THREE.MeshBasicMaterial( 0xff0000 ) ); + const box = new THREE.BoxHelper( object, 0xffff00 ); + scene.add( box ); + + +

    Esempi

    + +

    + [example:webgl_helpers WebGL / helpers]
    + [example:webgl_loader_nrrd WebGL / loader / nrrd]
    + [example:webgl_buffergeometry_drawrange WebGL / buffergeometry / drawrange] +

    + +

    Costruttore

    + + +

    [name]( [param:Object3D object], [param:Color color] )

    +

    + [page:Object3D object] -- (opzionale) l'object3D su cui mostrare il bounding box allineato all'asse del world.
    + [page:Color color] -- (opzionale) valore esadecimale che definisce il colore del box. Il valore predefinito è 0xffff00.

    + + Crea un nuovo wireframe box che delimita l'oggetto passato. Internamento utilizza il metodo [page:Box3.setFromObject] + per calcolare le dimansioni. Si noti che include qualsiasi figlio dell'oggetto. +

    + +

    Proprietà

    +

    Vedi la classe base [page:LineSegments] per le proprietà in comune.

    + +

    Metodi

    +

    Vedi la classe base [page:LineSegments] per i metodi comuni.

    + +

    [method:undefined update]()

    +

    + Aggiorna la geometria dell'helper in modo che corrisponda alle dimensioni dell'oggetto, + inclusi eventuali figli. Vedi [page:Box3.setFromObject]. +

    + +

    [method:this setFromObject]( [param:Object3D object] )

    +

    + [page:Object3D object] - [page:Object3D] su cui creare l'helper.

    + + Aggiorna il wireframe box per l'oggetto passato. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/helpers/CameraHelper.html b/docs/api/it/helpers/CameraHelper.html new file mode 100644 index 00000000000000..6c3523a1d60e5e --- /dev/null +++ b/docs/api/it/helpers/CameraHelper.html @@ -0,0 +1,81 @@ + + + + + + + + + + [page:Object3D] → [page:Line] → [page:LineSegments] → + +

    [name]

    + +

    + Questa classe aiuta a visualizzare ciò che una telecamera contiene nel suo frustum.
    + Visualizza il frustum di una telecamera utilizzando un [page:LineSegments]. +

    + +

    Codice di Esempio

    + +const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); +const helper = new THREE.CameraHelper( camera ); +scene.add( helper ); + + +

    Esempi

    +

    + [example:webgl_camera WebGL / camera]
    + [example:webgl_geometry_extrude_splines WebGL / extrude / splines] +

    + +

    Costruttore

    + +

    [name]( [param:Camera camera] )

    +

    + [page:Camera camera] -- La telecamera da visualizzare.

    + + Crea un nuovo [name] per la telecamera specificata. +

    + +

    Proprietà

    +

    Vedi la classe base [page:LineSegments] per le proprietà in comune.

    + +

    [property:Camera camera]

    +

    La telecamera visualizzata.

    + +

    [property:Object pointMap]

    +

    Contiene i punti utilizzati per visualizzare la telecamera.

    + +

    [property:Object matrix]

    +

    Riferimento a [page:Object3D.matrixWorld camera.matrixWorld].

    + +

    [property:Object matrixAutoUpdate]

    +

    + Vedi [page:Object3D.matrixAutoUpdate]. In questo caso è impostato su `false`, poiché l'helper sta usando + [page:Object3D.matrixWorld matrixWorld] della telecamera. +

    + +

    Metodi

    +

    Vedi la classe base [page:LineSegments] per i metodi comuni.

    + +

    [method:undefined dispose]()

    +

    + Elimina il [page:Line.material materiale] e la [page:Line.geometry geometria] utilizzati da questo helper. +

    + +

    [method:this setColors]( [param:Color frustum], [param:Color cone], [param:Color up], [param:Color target], [param:Color cross] )

    +

    + Definisce i colori dell'helper. +

    + +

    [method:undefined update]()

    +

    Aggiorna l'helper in base alla projectionMatrix della telecamera.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/helpers/DirectionalLightHelper.html b/docs/api/it/helpers/DirectionalLightHelper.html new file mode 100644 index 00000000000000..328ecac81845b4 --- /dev/null +++ b/docs/api/it/helpers/DirectionalLightHelper.html @@ -0,0 +1,82 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + Oggetto di supporto per aiutare a visualizzare l'effetto di una [page:DirectionalLight] nella scena. + Consiste in un piano e una linea che rappresentano la posizione e la direzione della luce. +

    + +

    Codice di Esempio

    + + + const light = new THREE.DirectionalLight( 0xFFFFFF ); + const helper = new THREE.DirectionalLightHelper( light, 5 ); + scene.add( helper ); + + +

    Costruttore

    + + +

    [name]( [param:DirectionalLight light], [param:Number size], [param:Hex color] )

    +

    + [page:DirectionalLight light]-- La luce da visualizzare.

    + + [page:Number size] -- (opzionale) le dimensioni del piano. Il valore predefinito è `1`.

    + + [page:Hex color] -- (opzionale) se non è impostato l'helper prenderà il colore della luce. +

    + + +

    Proprietà

    +

    Vedi la classe base [page:Object3D] per le proprietà in comune.

    + + +

    [property:Line lightPlane]

    +

    Contiene la mesh della linea che mostra la posizione della luce direzionale.

    + +

    [property:DirectionalLight light]

    +

    Riferimento alla [page:DirectionalLight directionalLight] da visualizzare.

    + +

    [property:Object matrix]

    +

    Riferimento alla [page:Object3D.matrixWorld matrixWorld] della luce.

    + +

    [property:Object matrixAutoUpdate]

    +

    + Vedi [page:Object3D.matrixAutoUpdate]. In questo caso è impostato su `false`, poiché l'helper sta usando + [page:Object3D.matrixWorld matrixWorld] della telecamera. +

    + +

    [property:hex color]

    +

    + Il parametro colore passato nel costruttore. Il valore predefinito è `undefined`. Se viene modificato, + il colore dell'helper sarà aggiornato la prossima volta che il metodo [page:.update update] venga chiamato. +

    + + +

    Metodi

    +

    Vedi la classe base [page:Object3D] per i metodi comuni.

    + +

    [method:undefined dispose]()

    +

    Elimina il directionalLightHelper.

    + + +

    [method:undefined update]()

    +

    Aggiorna l'helper in modo che corrisponda alla posizione e alla direzione della [page:.light directionalLight] visualizzata.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/helpers/GridHelper.html b/docs/api/it/helpers/GridHelper.html new file mode 100644 index 00000000000000..8cbff06639f347 --- /dev/null +++ b/docs/api/it/helpers/GridHelper.html @@ -0,0 +1,50 @@ + + + + + + + + + + [page:Object3D] → [page:Line] → + +

    [name]

    + +

    Il [name] è un oggetto utilizzato per definire le griglie (grid). Le grigle sono array bidimensionali di linee.

    + +

    Codice di Esempio

    + + const size = 10; + const divisions = 10; + + const gridHelper = new THREE.GridHelper( size, divisions ); + scene.add( gridHelper ); + + +

    Esempi

    + +

    + [example:webgl_helpers WebGL / helpers] +

    + +

    Costruttore

    + +

    [name]( [param:number size], [param:Number divisions], [param:Color colorCenterLine], [param:Color colorGrid] )

    +

    + size -- La dimensione della griglia. Il valore predefinito è 10.
    + divisions -- Il numero di divisioni nella griglia. Il valore predefinito è 10.
    + colorCenterLine -- (optional) Il colore della linea centrale. Può essere un [page:Color], un valore esadecimale e un nome CSS-Color. Il valore predefinito è 0x444444
    + colorGrid -- (optional) Il colore delle linee della griglia. Può essere un [page:Color], un valore esadecimale e un nome CSS-Color. Il valore predefinito è 0x888888 +

    +

    + Crea un nuovo [name] di dimensioni 'size' e suddiso in 'divisions' segmenti per lato. I colori sono opzionali. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/helpers/HemisphereLightHelper.html b/docs/api/it/helpers/HemisphereLightHelper.html new file mode 100644 index 00000000000000..c4345a79304812 --- /dev/null +++ b/docs/api/it/helpers/HemisphereLightHelper.html @@ -0,0 +1,77 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + Crea un aiuto visivo costituito da una [page:Mesh] sferica per un [page:HemisphereLight HemisphereLight]. +

    + +

    Codice di Esempio

    + + + const light = new THREE.HemisphereLight( 0xffffbb, 0x080820, 1 ); + const helper = new THREE.HemisphereLightHelper( light, 5 ); + scene.add( helper ); + + + +

    Costruttore

    + +

    [name]( [param:HemisphereLight light], [param:Number sphereSize], [param:Hex color] )

    +

    + [page:HemisphereLight light] -- La luce da visualizzare.

    + + [page:Number size] -- La dimensione della mesh utilizzata per visualizzare la luce.

    + + [page:Hex color] -- (opzionale) se questo non è impostato l'helper avrà il colore della luce. +

    + + +

    Proprietà

    +

    Vedi la classe base [page:Object3D] per le proprietà in comune.

    + +

    [property:HemisphereLight light]

    +

    Riferimento alla HemisphereLight da visualizzare.

    + +

    [property:Object matrix]

    +

    Riferimento alla [page:Object3D.matrixWorld matrixWorld] della hemisphereLight.

    + +

    [property:Object matrixAutoUpdate]

    +

    + Vedi [page:Object3D.matrixAutoUpdate]. In questo caso è impostato su `false`, poiché l'helper sta usando + [page:Object3D.matrixWorld matrixWorld] della telecamera. +

    + +

    [property:hex color]

    +

    + Il parametro colore passato nel costruttore. Il valore predefinito è `undefined`. + Se viene modificato, il colore dell'helper sarà aggiornato la prossima volta che il metodo [page:.update update] venga chiamato. +

    + + +

    Metodi

    +

    Vedi la classe base [page:Object3D] per i metodi comuni.

    + +

    [method:undefined dispose]()

    +

    Elimina l'hemisphereLightHelper.

    + +

    [method:undefined update]()

    +

    Aggiorna l'helper in modo che corrisponda alla posizione e alla direzione della [page:.light luce].

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/helpers/PlaneHelper.html b/docs/api/it/helpers/PlaneHelper.html new file mode 100644 index 00000000000000..fa0fdda9e734d4 --- /dev/null +++ b/docs/api/it/helpers/PlaneHelper.html @@ -0,0 +1,66 @@ + + + + + + + + + + [page:Object3D] → [page:Line] → [page:LineSegments] → + +

    [name]

    + +

    + Oggetto per visualizzare un [page:Plane Piano]. +

    + + +

    Codice di Esempio

    + + + const plane = new THREE.Plane( new THREE.Vector3( 1, 1, 0.2 ), 3 ); + const helper = new THREE.PlaneHelper( plane, 1, 0xffff00 ); + scene.add( helper ); + + + +

    Costruttore

    + + +

    [name]( [param:Plane plane], [param:Float size], [param:Color hex] )

    +

    + [page:Plane plane] -- il piano da visualizzare.
    + [page:Float size] -- (opzionale) lunghezza laterale dell'helper del piano. Il valore predefinito è 1.
    + [page:Color color] -- (opzionale) il colore dell'helper. Il valore predefinito è 0xffff00.

    + + Crea un nuovo wireframe che rappresenta il piano passato. +

    + +

    Proprietà

    +

    Vedi la classe base [page:LineSegments] per le proprietà in comune.

    + +

    [property:Plane plane]

    +

    Il [page:Plane plane] da visualizzare.

    + +

    [property:Float size]

    +

    Le lunghezze laterali dell'helper del piano.

    + + +

    Metodi

    +

    Vedi la classe base [page:LineSegments] per i metodi comuni.

    + +

    [method:undefined updateMatrixWorld]( [param:Boolean force] )

    +

    + Sovrascrive il metodo in base alla classe [page:Object3D]. + Questo sovrascrive il metodo nella classe base [page:Object3D] così che aggiorni anche l'oggetto helper in base alle proprietà + [page:PlaneHelper.plane .plane] e [page:PlaneHelper.size .size]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/helpers/PointLightHelper.html b/docs/api/it/helpers/PointLightHelper.html new file mode 100644 index 00000000000000..9013db03481680 --- /dev/null +++ b/docs/api/it/helpers/PointLightHelper.html @@ -0,0 +1,85 @@ + + + + + + + + + + [page:Object3D] → [page:Mesh] → + +

    [name]

    + +

    + Questo mostra un oggetto helper costituito da una [page:Mesh] sferica per la visualizzazione di + un [page:PointLight]. +

    + +

    Codice di Esempio

    + + + const pointLight = new THREE.PointLight( 0xff0000, 1, 100 ); + pointLight.position.set( 10, 10, 10 ); + scene.add( pointLight ); + + const sphereSize = 1; + const pointLightHelper = new THREE.PointLightHelper( pointLight, sphereSize ); + scene.add( pointLightHelper ); + + +

    Esempi

    + +

    + [example:webgl_helpers WebGL / helpers] +

    + +

    Costruttore

    + +

    [name]( [param:PointLight light], [param:Float sphereSize], [param:Hex color] )

    +

    + [page:PointLight light] -- La luce da visualizzare.

    + + [page:Float sphereSize] -- (opzionale) La dimensione della sfera. Il valore predefinito è `1`.

    + + [page:Hex color] -- (opzionale) Se non è impostato l'helper prenderà il colore della luce. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Mesh] per le proprietà in comune.

    + +

    [property:PointLight light]

    +

    La [page:PointLight] che viene visualizzata.

    + +

    [property:Object matrix]

    +

    Riferimento alla [page:Object3D.matrixWorld matrixWorld] del pointLight.

    + +

    [property:Object matrixAutoUpdate]

    +

    + Vedi [page:Object3D.matrixAutoUpdate]. In questo caso è impostato su `false`, poiché l'helper sta usando + [page:Object3D.matrixWorld matrixWorld] della telecamera. +

    + +

    [property:hex color]

    +

    + Il parametro colore passato nel costruttore. Il valore predefinito è `undefined`. Se viene modificato, + il colore dell'helper sarà aggiornato la prossima volta che il metodo [page:.update update] venga chiamato. +

    + +

    Metodi

    +

    Vedi la classe base [page:Mesh] per i metodi comuni.

    + +

    [method:undefined dispose]()

    +

    Elimina il pointLightHelper.

    + + +

    [method:undefined update]()

    +

    Aggiorna l'helper in modo che corrisponda alla posizione della [page:.light luce].

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/helpers/PolarGridHelper.html b/docs/api/it/helpers/PolarGridHelper.html new file mode 100644 index 00000000000000..9ad435bdc0b329 --- /dev/null +++ b/docs/api/it/helpers/PolarGridHelper.html @@ -0,0 +1,56 @@ + + + + + + + + + + [page:Object3D] → [page:Line] → + +

    [name]

    + +

    Il PolarGridHelper è un oggetto utilizzato per definire le griglie polari. Le griglie sono array bidimensionli di linee.

    + +

    Codice di Esempio

    + + + const radius = 10; + const sectors = 16; + const rings = 8; + const divisions = 64; + + const helper = new THREE.PolarGridHelper( radius, sectors, rings, divisions ); + scene.add( helper ); + + +

    Esempi

    + +

    + [example:webgl_helpers WebGL / helpers] +

    + +

    Costruttore

    + +

    [name]( [param:Number radius], [param:Number sectors], [param:Number rings], [param:Number divisions], [param:Color color1], [param:Color color2] )

    +

    + radius -- Il raggio della griglia polare. Può essere qualsiasi numero positivo. Il valore predefinito è 10.
    + sectors -- Il numero di settori in cui deve essere divisa la griglia. Può essere qualsiasi numero intero positivo. Il valore predefinito è 16.
    + rings -- Il numero di anelli. Può essere qualsiasi numero intero positivo. Il valore predefinito è 8.
    + divisions -- Il numero di segmenti linea utilizzato per ogni cerchio. Può essere qualsiasi numero intero positivo pari o superiore a 3. Il valore predefinito è 64.
    + color1 -- Il primo colore utilizzato per gli elementi della griglia. Può essere un [page:Color], un valore esadecimale e un nome CSS-Color. Il valore predefinito è 0x444444
    + color2 -- Il secondo colore utilizzato per gli elementi della griglia. Può essere un [page:Color], un valore esadecimale e un nome CSS-Color. Il valore predefinito è 0x888888 +

    +

    + Crea un nuovo [name] di raggio 'radius' con 'sectors' numero di settori e 'rings' numero di anelli, in cui ogni cerchio + viene smussato in 'divisions' numero di segmenti di linea. I colori sono opzionali. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/helpers/SkeletonHelper.html b/docs/api/it/helpers/SkeletonHelper.html new file mode 100644 index 00000000000000..1ff94cc98901b9 --- /dev/null +++ b/docs/api/it/helpers/SkeletonHelper.html @@ -0,0 +1,66 @@ + + + + + + + + + + [page:Object3D] → [page:Line] → [page:LineSegments] → + +

    [name]

    + +

    + Un oggetto helper per aiutare a visualizzare uno [page:Skeleton Skeleton]. + L'helper viene visualizzato utilizzando un [page:LineBasicMaterial LineBasicMaterial]. +

    + +

    Codice di Esempio

    + + + const helper = new THREE.SkeletonHelper( skinnedMesh ); + scene.add( helper ); + + +

    Esempi

    + +

    + [example:webgl_animation_skinning_blending WebGL / animation / skinning / blending]
    + [example:webgl_animation_skinning_morph WebGL / animation / skinning / morph]
    + [example:webgl_loader_bvh WebGL / loader / bvh ] +

    + +

    Costruttore

    + + +

    [name]( [param:Object3D object] )

    +

    + object -- Solitamente un'istanza di [page:SkinnedMesh]. Tuttavia, può essere utilizzata qualsiasi istanza di [page:Object3D] + se rappresenta una gerarchia di [page:Bone Bone] (tramite [page:Object3D.children]). +

    + +

    Proprietà

    + +

    [property:Array bones]

    +

    + L'elenco delle ossa che l'helper visualizza come [page:Line Lines]. +

    + +

    [property:Boolean isSkeletonHelper]

    +

    + Flag di sola lettura per controllare se un dato oggetto è di tipo [name]. +

    + +

    [property:Object3D root]

    +

    + L'oggetto passato nel costruttore. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/helpers/SpotLightHelper.html b/docs/api/it/helpers/SpotLightHelper.html new file mode 100644 index 00000000000000..17301123b974b6 --- /dev/null +++ b/docs/api/it/helpers/SpotLightHelper.html @@ -0,0 +1,80 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    Visualizza un oggetto helper a forma di cono per una [page:SpotLight].

    + +

    Codice di Esempio

    + + const spotLight = new THREE.SpotLight( 0xffffff ); + spotLight.position.set( 10, 10, 10 ); + scene.add( spotLight ); + + const spotLightHelper = new THREE.SpotLightHelper( spotLight ); + scene.add( spotLightHelper ); + + +

    Esempi

    +

    + [example:webgl_lights_spotlights WebGL/ lights / spotlights ] +

    + +

    Costruttore

    + +

    [name]( [param:SpotLight light], [param:Hex color] )

    +

    + [page:SpotLight light] -- La [page:SpotLight] da visualizzare.

    + + [page:Hex color] -- (opzionale) Se non è impostato l'helper prenderà il colore della luce. +

    + + +

    Proprietà

    +

    Vedi la classe base [page:Object3D] per le proprietà in comune.

    + +

    [property:LineSegments cone]

    +

    [page:LineSegments] usati per visualizzare la luce.

    + +

    [property:SpotLight light]

    +

    Riferimento alla [page:SpotLight] visualizzata.

    + +

    [property:Object matrix]

    +

    Riferimento alla [page:Object3D.matrixWorld matrixWorld] della spotLight.

    + +

    [property:Object matrixAutoUpdate]

    +

    + Vedi [page:Object3D.matrixAutoUpdate]. In questo caso è impostato su `false`, poiché l'helper sta usando + [page:Object3D.matrixWorld matrixWorld] della telecamera. +

    + +

    [property:hex color]

    +

    + Il parametro colore passato nel costruttore. Il valore predefinito è `undefined`. Se viene modificato, + il colore dell'helper sarà aggiornato la prossima volta che il metodo [page:.update update] venga chiamato. +

    + +

    Metodi

    +

    Vedi la classe base [page:Object3D] per i metodi comuni.

    + +

    [method:undefined dispose]()

    +

    Elimina l'helper della luce.

    + +

    [method:undefined update]()

    +

    Aggiorna l'helper della luce.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/lights/AmbientLight.html b/docs/api/it/lights/AmbientLight.html new file mode 100644 index 00000000000000..51875cd0096e44 --- /dev/null +++ b/docs/api/it/lights/AmbientLight.html @@ -0,0 +1,59 @@ + + + + + + + + + + [page:Object3D] → [page:Light] → + +

    [name]

    + +

    + Questa luce illumina globalmente tutti gli oggetti nella scena allo stesso modo.

    + + Questa luce non può essere utilizzata per proiettare ombre in quanto non ha una direzione. +

    + +

    Codice di Esempio

    + + + const light = new THREE.AmbientLight( 0x404040 ); // soft white light + scene.add( light ); + + +

    Costruttore

    + +

    [name]( [param:Integer color], [param:Float intensity] )

    +

    + [page:Integer color] - (opzionale) Valore numerico della componente RGB del colore. Il valore predefinito è 0xffffff.
    + [page:Float intensity] - (opzionale) Valore numerico della forza/intensità della luce. Il valore predefinito è 1.

    + + Crea una nuova [name]. +

    + +

    Proprietà

    +

    + Vedi la classe base [page:Light Light] per le proprietà comuni. +

    + +

    [property:Boolean isAmbientLight]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è del tipo [name]. +

    + + +

    Metodi

    +

    + Vedi la classe base [page:Light Light] per i metodi comuni. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/lights/AmbientLightProbe.html b/docs/api/it/lights/AmbientLightProbe.html new file mode 100644 index 00000000000000..dfd9de3fc13c3e --- /dev/null +++ b/docs/api/it/lights/AmbientLightProbe.html @@ -0,0 +1,51 @@ + + + + + + + + + + [page:Object3D] → [page:Light] → [page:LightProbe] + +

    [name]

    + +

    + Le sonde luminose sono un modo alternativo per aggiungere luce a una scena 3D. AmbientLightProbe è il dato + di stima della luce di una singola luce ambientale nella scena. Per ulteriori informazioni sulle sonde luminose, + consultare [page:LightProbe]. +

    + +

    Costruttore

    + +

    [name]( [param:Color color], [param:Float intensity] )

    +

    + [page:Color color] - (opzionale) Un'istanza di Color, una stringa che rappresenta un colore o un numero che rappresenta un colore.
    + [page:Float intensity] - (opzionale) Valore numerico dell'intensità della sonda luminosa. Il valore predefinito è 1.

    + + Crea una nuova [name]. +

    + +

    Proprietà

    +

    + Vedi la classe base [page:LightProbe LightProbe] per le proprietà comuni. +

    + +

    [property:Boolean isAmbientLightProbe]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è del tipo [name]. +

    + +

    Metodi

    +

    + Vedi la classe base [page:LightProbe LightProbe] per i metodi comuni. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/lights/DirectionalLight.html b/docs/api/it/lights/DirectionalLight.html new file mode 100644 index 00000000000000..2c34ed026f392d --- /dev/null +++ b/docs/api/it/lights/DirectionalLight.html @@ -0,0 +1,146 @@ + + + + + + + + + + [page:Object3D] → [page:Light] → + +

    [name]

    + +

    + Una luce che viene emessa in una direzione specifica. Questa luce si comporterà come se + fosse infinitamente lontana e i raggi da essa prodotti fossero tutti paralleli. Il + caso d'uso comune di questa luce è simulare la luce del giorno; il sole è abbastanza lontano + che la sua posizione può essere considerata infinita, e tutti i raggi di luce + che ne provengono sono paralleli.

    + + Questa luce può proiettare le ombre - vedi la pagina [page:DirectionalLightShadow] per i dettagli. +

    + +

    Una nota riguardo la posione, il target e la rotazione

    +

    + Un punto di confusione comune per le luci direzionali è che l'impostazione della rotazione non ha alcun effetto. + Questo succede perché la DirectionalLight di three.js è l'equivalente di ciò che viene spesso chiamato + 'Target Direct Light' in altre applicazioni.

    + + Questo significa che la sua direzione viene calcolata puntando dalla [page:Object3D.position posizione] della luce + alla posizione del [page:.target target] (al contrario di una 'Free Direct Light' che ha solo una componente di rotazione).

    + + La ragione di ciò è consentire alla luce di proiettare ombre - la telecamera delle [page:.shadow ombre] + ha bisogno di una posizione da cui calcolare le ombre.

    + + Vedi la proprietà [page:.target target] di seguito per i dettagli sull'aggiornamento del target. +

    + +

    Codice di Esempio

    + + + // Luce bianca direzionale a metà intensità che brilla dall'alto. + const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 ); + scene.add( directionalLight ); + + +

    Esempi

    +

    + [example:misc_controls_fly controls / fly ]
    + [example:webgl_effects_parallaxbarrier effects / parallaxbarrier ]
    + [example:webgl_effects_stereo effects / stereo ]
    + [example:webgl_geometry_extrude_splines geometry / extrude / splines ]
    + [example:webgl_materials_bumpmap materials / bumpmap ] +

    + +

    Costruttore

    + +

    [name]( [param:Integer color], [param:Float intensity] )

    +

    + [page:Integer color] - (opzionale) colore esadecimale della luce. Il valore predefinito è 0xffffff (bianco).
    + [page:Float intensity] - (opzionale) valore numerico della forza/intensità della luce. Il valore predefinito è 1.

    + + Crea una nuova [name]. +

    + +

    Proprietà

    +

    + Vedi la classe base [page:Light Light] per le proprietà comuni. +

    + +

    [property:Boolean castShadow]

    +

    + Se impostato a `true` la luce proietterà ombre dinamiche. *Attenzione*: Questo è costoso + e richiede una messa a punto per ottenere le ombre giuste. Si veda [page:DirectionalLightShadow] + per i dettagli. + Il valore predefinito è `false`. +

    + +

    [property:Boolean isDirectionalLight]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è del tipo [name]. +

    + +

    [property:Vector3 position]

    +

    + Questo è impostato uguale a [page:Object3D.DefaultUp] (0, 1, 0), in modo che la luce brilli dall'alto verso il basso. +

    + +

    [property:DirectionalLightShadow shadow]

    +

    + Una [page:DirectionalLightShadow] utilizzata per calcolare le ombre per questa luce. +

    + +

    [property:Object3D target]

    +

    + DirectionalLight punta dalla sua [page:.position posizione] alla target.position. La posizione + predefinita del target è `(0, 0, 0)`.
    + + *Nota*: Affinchè la posizione del target possa essere modificata in qualcosa di diverso + da quella predefinita, è necessario aggiungerlo alla [page:Scene scena] utilizzando +

    + + scene.add( light.target ); + +

    + In questo modo il [page:Object3D.matrixWorld matrixWorld] del target viene aggiornato + automaticamente a ogni frame.

    + + È anche possibile impostare il target in modo che sia un altro oggetto nella scena (qualsiasi + cosa con una proprietà [page:Object3D.position position]), in questo modo: +

    + + const targetObject = new THREE.Object3D(); + scene.add(targetObject); + + light.target = targetObject; + +

    + La directionalLight ora seguirà l'oggetto target. +

    + + +

    Metodi

    +

    + Vedi la classe base [page:Light Light] per i metodi comuni. +

    + +

    [method:undefined dispose]()

    +

    + Sovrascrive il metodo [page:Light.dispose dispose] della classe base. + Elimina l'[page:DirectionalLightShadow ombra] di questa luce. +

    + +

    [method:this copy]( [param:DirectionalLight source] )

    +

    + Copia il valore di tutte le proprietà dalla [page:DirectionalLight sorgente] (source) a questa + DirectionalLight. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/lights/HemisphereLight.html b/docs/api/it/lights/HemisphereLight.html new file mode 100644 index 00000000000000..cfb9308f4d7267 --- /dev/null +++ b/docs/api/it/lights/HemisphereLight.html @@ -0,0 +1,93 @@ + + + + + + + + + + [page:Object3D] → [page:Light] → + +

    [name]

    + +

    + Una sorgente di luce posizionata direttamente sopra la scena, con il colore che sfuma dal + colore del cielo al colore del suolo.

    + + Questa luce non può essere usata per proiettare le ombre. +

    + +

    Codice di Esempio

    + + + const light = new THREE.HemisphereLight( 0xffffbb, 0x080820, 1 ); + scene.add( light ); + + +

    Esempi

    + +

    + [example:webgl_animation_skinning_blending animation / skinning / blending ]
    + [example:webgl_lights_hemisphere lights / hemisphere ]
    + [example:misc_controls_pointerlock controls / pointerlock ]
    + [example:webgl_loader_collada_kinematics loader / collada / kinematics ]
    + [example:webgl_loader_stl loader / stl ] +

    + +

    Costruttore

    +

    [name]( [param:Integer skyColor], [param:Integer groundColor], [param:Float intensity] )

    +

    + [page:Integer skyColor] - (opzionale) colore esadecimale del cielo. Il valore predefinito è 0xffffff.
    + [page:Integer groundColor] - (opzionale) colore esadecimale del suolo. Il valore predefinito è 0xffffff.
    + [page:Float intensity] - (opzionale) valore numerico della forza/intensità della luce. Il valore predefinito è 1.

    + + Crea un nuova [name]. +

    + +

    Proprietà

    +

    + Vedi la classe base [page:Light Light] per le proprietà comuni. +

    + +

    [property:Float color]

    +

    + Il colore del cielo della luce, come passato nel costruttore. + Il valore predefinito è un nuovo [page:Color] impostato a bianco (0xffffff). +

    + +

    [property:Float groundColor]

    +

    + Il colore del suolo della luce, come passato nel costruttore. + Il valore predefinito è un nuovo [page:Color] impostato a bianco (0xffffff). +

    + +

    [property:Boolean isHemisphereLight]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è del tipo [name]. +

    + +

    [property:Vector3 position]

    +

    + Questo è impostato uguale a [page:Object3D.DefaultUp] (0, 1, 0), in modo che la luce risplenda + dall'alto verso il basso. +

    + +

    Metodi

    +

    + Vedi la classe base [page:Light Light] per i metodi comuni. +

    + +

    [method:this copy]( [param:HemisphereLight source] )

    +

    + Copia i valori di [page:.color color], [page:.intensity intensity] e + [page:.groundColor groundColor] dalla luce della [page:Light sorgente] (source) in questa luce. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/lights/HemisphereLightProbe.html b/docs/api/it/lights/HemisphereLightProbe.html new file mode 100644 index 00000000000000..934a95e2daca4b --- /dev/null +++ b/docs/api/it/lights/HemisphereLightProbe.html @@ -0,0 +1,52 @@ + + + + + + + + + + [page:Object3D] → [page:Light] → [page:LightProbe] + +

    [name]

    + +

    + Le sonde luminose sono un modo alternativo di aggiungere luce alla scena 3D. HemisphereLightProbe è i dati di stima della + luce di un singolo emisfero luminoso nella scena. Per ulteriori informazioni sulle sonde di luce, consultare [page:LightProbe]. +

    + +

    Costruttore

    + +

    [name]( [param:Color skyColor], [param:Color groundColor], [param:Float intensity] )

    +

    + [page:Color skyColor] - (opzionale) Un'istanza di Color, stringa che rappresenta un colore o un numero che rappresenta un colore.
    + [page:Color groundColor] - (opzionale) Un'istanza di Color, stringa che rappresenta un colore o un numero che rappresenta un colore.
    + [page:Float intensity] - (opzionale) Valore numerico dell'intesità della sonda di luce. Il valore predefinito è 1.

    + + Crea una nuova [name]. +

    + +

    Proprietà

    +

    + Vedi la classe base [page:LightProbe LightProbe] per le proprietà comuni. +

    + + +

    [property:Boolean isHemisphereLightProbe]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è del tipo [name]. +

    + +

    Metodi

    +

    + Vedi la classe base [page:LightProbe LightProbe] per i metodi comuni. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/lights/Light.html b/docs/api/it/lights/Light.html new file mode 100644 index 00000000000000..5721ea71134dd4 --- /dev/null +++ b/docs/api/it/lights/Light.html @@ -0,0 +1,80 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + Una classe astratta per le luci - tutti gli altri tipi di luce ereditano le proprietà e + i metodi descritti qui. +

    + +

    Costruttore

    + +

    [name]( [param:Integer color], [param:Float intensity] )

    +

    + [page:Integer color] - (opzionale) Colore esadecimale della luce. Il valore predefinito è 0xffffff (white).
    + [page:Float intensity] - (opzionale) Il valore numerico della forza/intensità della luce. Il valore predefinito è 1.

    + + Crea una nuova [name]. Si noti che questa classe non è intesa per essere chiamata direttamente (utilizzare invece una delle classi derivate). +

    + +

    Proprietà

    +

    + Vedi la classe base [page:Object3D Object3D] per le proprietà comuni. +

    + +

    [property:Color color]

    +

    + Colore della luce. Il valore predefinito è un nuovo [page:Color] impostato su bianco, + se non viene passato nel costruttore.
    +

    + +

    [property:Float intensity]

    +

    + L'intensità o la forza della luce.
    + In modalità [page:WebGLRenderer.physicallyCorrectLights fisicamente corretta], le unità di intensità dipendono dal tipo di luce.
    + Il valore predefinito è `1.0`. +

    + +

    [property:Boolean isLight]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è del tipo [name]. +

    + + +

    Metodi

    +

    + Vedi la classe base [page:Object3D Object3D] per i metodi comuni. +

    + +

    [method:undefined dispose]()

    +

    + Metodo dispose astratto per le luci; implementato dalle sottoclassi che hanno risorse disponibili. +

    + +

    [method:this copy]( [param:Light source] )

    +

    + Copia il valore di [page:.color color] e [page:.intensity intensity] dalla luce [page:Light sorgente] (source) in questa luce. +

    + +

    [method:Object toJSON]( [param:Object meta] )

    +

    + meta -- oggetto contenente matedati come i metariali e le texture per gli oggetti.
    + Converte la luce nel [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 formato Oggetto/Scena JSON] di three.js. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/lights/LightProbe.html b/docs/api/it/lights/LightProbe.html new file mode 100644 index 00000000000000..54927ccab39a0f --- /dev/null +++ b/docs/api/it/lights/LightProbe.html @@ -0,0 +1,76 @@ + + + + + + + + + + [page:Object3D] → [page:Light] → + +

    [name]

    + +

    + Le sonde luminose sono un metodo alternativo di aggiungere luce in una scena 3D. Diversamente dalle classiche sorgenti + di luce (ad esempio, direzionali, puntiformi o luci spot), le sonde luminose non emettono luce. Invece memorizzano + informazioni sulla luce che passa attraverso lo spazio 3D. Durante il rendering, la luce che colpisce un + oggetto 3D viene approssimata utilizzando i dati della sonda di luce. +

    + +

    + Le sonde luminose vengono solitamente create da mappe ambientali (di radianza). La classe [page:LightProbeGenerator] + può essere utilizzata per create le sonde luminose dalle istanze di [page:CubeTexture] o [page:WebGLCubeRenderTarget]. + Tuttavia, i dati di stima della luce potrebbero essere forniti in altre forme, ad es. di WebXR. Ciò consente il + rendering di realtà aumentata che reagiscono all'illuminazione del mondo reale. +

    + +

    + L'attuale implementazione della sonda in three.js supporta le cosidette sonde a luce diffusa. Questo tipo + di sonda luminosa è funzionalmente equivalente a una mappa ambientale di irradianza. +

    + +

    Esempi

    +

    + [example:webgl_lightprobe WebGL / light probe ]
    + [example:webgl_lightprobe_cubecamera WebGL / light probe / cube camera ] +

    + +

    Costruttore

    + +

    [name]( [param:SphericalHarmonics3 sh], [param:Float intensity] )

    +

    + [page:SphericalHarmonics3 sh] - (opzionale) Un'istanza di [page:SphericalHarmonics3].
    + [page:Float intensity] - (opzionale) Il valore numerico dell'intensità della sonda luminosa. Il valore predefinito è 1.

    + + Crea una nuova [name]. +

    + +

    Proprietà

    +

    + Vedi la classe base [page:Light Light] per le proprietà comuni. La proprietà [page:Light.color color] al momento non è valutata e + quindi non ha alcun effetto. +

    + +

    [property:Boolean isLightProbe]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è del tipo [name]. +

    + +

    [property:SphericalHarmonics3 sh]

    +

    + Una sonda luminosa utilizza le armoniche sferiche per codificare le informazioni sull'illuminazione. +

    + +

    Metodi

    +

    + Vedi la classe base [page:Light Light] per i metodi comuni. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/lights/PointLight.html b/docs/api/it/lights/PointLight.html new file mode 100644 index 00000000000000..2027fe3b6544b1 --- /dev/null +++ b/docs/api/it/lights/PointLight.html @@ -0,0 +1,128 @@ + + + + + + + + + + [page:Object3D] → [page:Light] → + +

    [name]

    + +

    + Una luce che viene emessa da un unico punto in tutte le direzioni. Un caso d'uso comune per + questo è replicare la luce emessa da una lampadina nuda.

    + + Questa luce può proiettare le ombre - vedi la pagina [page:PointLightShadow] per i dettagli. +

    + +

    Codice di Esempio

    + + +const light = new THREE.PointLight( 0xff0000, 1, 100 ); +light.position.set( 50, 50, 50 ); +scene.add( light ); + + +

    Esempi

    + +

    + [example:webgl_lights_pointlights lights / pointlights ]
    + [example:webgl_effects_anaglyph effects / anaglyph ]
    + [example:webgl_geometry_text geometry / text ]
    + [example:webgl_lensflares lensflares ] +

    + +

    Costruttore

    + +

    [name]( [param:Integer color], [param:Float intensity], [param:Number distance], [param:Float decay] )

    +

    + [page:Integer color] - (opzionale) Il colore esadecimale della luce. Il valore predefinito è 0xffffff (bianco).
    + [page:Float intensity] - (opzionale) Il valore numerico della forza/intensità della luce. Il valore predefinito è 1.
    + [page:Number distance] - Portata massima della luce. Il valore predefinito è 0 (nessun limite).
    + [page:Float decay] - La quantità di attenuazione della luce lungo la distanza della luce. Il valore predefinito è 2.

    + + Crea una nuova [name]. +

    + +

    Proprietà

    +

    + Vedi la classe base [page:Light Light] per le proprietà comuni. +

    + +

    [property:Float decay]

    +

    + The amount the light dims along the distance of the light. Default is `2`.
    + In context of physically-correct rendering the default value should not be changed. +

    + +

    [property:Float distance]

    +

    + `Modalità predefinita` — Quando la distanza è zero, la luce non si attenua. Quando la distanza è diversa da zero, + la luce si attenuerà linearmente dalla massima intensità nella posizione della luce fino a zero a questa distanza + dalla luce. +

    +

    + `Modalità [page:WebGLRenderer.physicallyCorrectLights fisicamente corretta]` — Quando la distanza è + zero, la luce si attenuerà secondo la legge dell'inverso del quadrato alla distanza infinita. + Quando la distanza è diversa da zero, la luce si attenuerà secondo la legge dell'inverso del quadrato + fino in prossimità del limite di distanza, dove si attenuerà quindi rapidamente e senza intoppi fino a 0. + Intrinsecamente, i limiti non sono fisicamente corretti. +

    +

    + Il valore predefinito è `0.0`. +

    + +

    [property:Float intensity]

    +

    + L'intensità della luce. Il valore predefinito è `1`.
    + Nella modalità [page:WebGLRenderer.physicallyCorrectLights fisicamente corretta], l'intensità + è l'intensità luminosa della luce misurata in candela (cd).

    + + Modificando l'intensità si modificherà anche la potenza della luce. +

    + +

    [property:Float power]

    +

    + La potenza della luce.
    + Nella modalità [page:WebGLRenderer.physicallyCorrectLights fisicamente corretta], la potenza è la potenza + della luminosità della luce misurata in lumen (lm).

    + + Modificando la potenza si modificherà anche l'intensità della luce. +

    + +

    [property:PointLightShadow shadow]

    +

    + Una [page:PointLightShadow] utilizzata per calcolare le ombre per questa luce.

    + + La [page:LightShadow.camera telecamera] di lightShadow è impostata su una [page:PerspectiveCamera] + con un [page:PerspectiveCamera.fov fov] di 90, [page:PerspectiveCamera.aspect aspect] di 1, + il piano [page:PerspectiveCamera.near near] a 0.5 e il piano [page:PerspectiveCamera.far far] a 500. +

    + +

    Metodi

    +

    + Vedi la classe base [page:Light Light] per i metodi comuni. +

    + +

    [method:undefined dispose]()

    +

    + Sovrascrive il metodo [page:Light.dispose dispose] della classe base. + Elimina l'[page:PointLightShadow ombra] di questa luce. +

    + +

    [method:this copy]( [param:PointLight source] )

    +

    + Copia il valore di tutte le proprietà dalla [page:PointLight sorgente] della + PointLight. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/lights/RectAreaLight.html b/docs/api/it/lights/RectAreaLight.html new file mode 100644 index 00000000000000..2607c2cd8a7ef8 --- /dev/null +++ b/docs/api/it/lights/RectAreaLight.html @@ -0,0 +1,114 @@ + + + + + + + + + + [page:Object3D] → [page:Light] → + +

    [name]

    + +

    + RectAreaLight emette luce uniformemente sulla faccia di un piano rettangolare. Questo tipo di luce + può essere utilizzato per simulare le sorgenti di luce come finestre luminose o strisce luminose.

    + + Note importanti: +

      +
    • Non c'è il supporto per le ombre.
    • +
    • Solo [page:MeshStandardMaterial MeshStandardMaterial] e [page:MeshPhysicalMaterial MeshPhysicalMaterial] sono supportati.
    • +
    • Devi includere [link:https://threejs.org/examples/jsm/lights/RectAreaLightUniformsLib.js RectAreaLightUniformsLib] nella tua scena e chiamare `init()`.
    • +
    +

    + +

    Codice di Esempio

    + + +const width = 10; +const height = 10; +const intensity = 1; +const rectLight = new THREE.RectAreaLight( 0xffffff, intensity, width, height ); +rectLight.position.set( 5, 5, 0 ); +rectLight.lookAt( 0, 0, 0 ); +scene.add( rectLight ) + +const rectLightHelper = new RectAreaLightHelper( rectLight ); +rectLight.add( rectLightHelper ); + + +

    Esempi

    + +

    + [example:webgl_lights_rectarealight WebGL / rectarealight ] +

    + +

    Costruttore

    + + +

    [name]( [param:Integer color], [param:Float intensity], [param:Float width], [param:Float height] )

    +

    + [page:Integer color] - (opzionale) colore esadecimale della luce. Il valore predefinito è 0xffffff (bianco).
    + [page:Float intensity] - (opzionale) l'intensità della luce, o luminosità. Il valore predefinito è 1.
    + [page:Float width] - (opzionale) larghezza della luce. Il valore predefinito è 10.
    + [page:Float height] - (opzionale) altezza della luce. Il valore predefinito è 10.

    + + Crea una nuova [name]. +

    + +

    Proprietà

    +

    + Vedi la classe base [page:Light Light] per le proprietà comuni. +

    + +

    [property:Float height]

    +

    + L'altezza della luce. +

    + +

    [property:Float intensity]

    +

    + L'intensità della luce. Il valore predefinito è `1`.
    + Nella modalità [page:WebGLRenderer.physicallyCorrectLights fisicamente corretta], l'intesità è la luminanza + (luminosità) della luce misurata in nits (cd/m^2).

    + + Modificando l'intensità si modificherà anche la potenza della luce. +

    + +

    [property:Boolean isRectAreaLight]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è del tipo [name]. +

    + +

    [property:Float power]

    +

    + La potenza della luce.
    + Nella modalità [page:WebGLRenderer.physicallyCorrectLights fisicamente corretta], la potenza è la potenza + della luminosità della luce misurata in lumen (lm).

    + + Modificando la potenza si modificherà anche l'intensità della luce. +

    + +

    [property:Float width]

    +

    + La larghezza della luce. +

    + +

    Metodi

    +

    + Vedi la classe base [page:Light Light] per i metodi comuni. +

    + + +

    [method:this copy]( [param:RectAreaLight source] )

    +

    + Copia il valore di tutte le proprietà dalla [page:RectAreaLight sorgente] a questa + RectAreaLight. +

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/lights/SpotLight.html b/docs/api/it/lights/SpotLight.html new file mode 100644 index 00000000000000..6d1ffe1ac76426 --- /dev/null +++ b/docs/api/it/lights/SpotLight.html @@ -0,0 +1,201 @@ + + + + + + + + + + [page:Object3D] → [page:Light] → + +

    [name]

    + +

    + Questa luce viene emessa da un unico punto in una direzione, lungo un cono che aumenta di dimensioni + man mano che si allontana dalla luce.

    + + Questa luce può proiettare le ombre - vedi la pagina [page:SpotLightShadow] per i dettagli. +

    + +

    Codice di Esempio

    + + // faretto bianco che brilla di lato, modulato da una texture, che proietta un'ombra + + const spotLight = new THREE.SpotLight( 0xffffff ); + spotLight.position.set( 100, 1000, 100 ); + spotLight.map = new THREE.TextureLoader().load( url ); + + spotLight.castShadow = true; + + spotLight.shadow.mapSize.width = 1024; + spotLight.shadow.mapSize.height = 1024; + + spotLight.shadow.camera.near = 500; + spotLight.shadow.camera.far = 4000; + spotLight.shadow.camera.fov = 30; + + scene.add( spotLight ); + + +

    Esempi

    + +

    + [example:webgl_lights_spotlight lights / spotlight ]
    + [example:webgl_lights_spotlights lights / spotlights ] +

    + +

    Costruttore

    + + +

    [name]( [param:Integer color], [param:Float intensity], [param:Float distance], [param:Radians angle], [param:Float penumbra], [param:Float decay] )

    +

    + [page:Integer color] - (opzionale) colore esadecimale della luce. Il valore predefinito è 0xffffff (bianco).
    + [page:Float intensity] - (opzionale) il valore numerico della forza/intensità della luce. Il valore predefinito è 1.
    + [page:Float distance] - Portata massima della luce. Il valore predefinito è 0 (nessun limite).
    + [page:Radians angle] - Angolo massimo di dispersione della luce dalla sua direzione in cui il limite superiore è Math.PI/2.
    + [page:Float penumbra] - Percentuale del cono del riflettore che viene attenuata a causa della penombra. + Accetta valori compresi tra zero e 1. Il valore predefinito è zero.
    + [page:Float decay] - La quantità di attenuazione della luce lungo la distanza della luce.

    + + Crea una nuova [name]. +

    + +

    Proprietà

    +

    + Vedi la classe base [page:Light Light] per le proprietà comuni. +

    + +

    [property:Float angle]

    +

    + Massima estensione del riflettore, in radianti, dalla sua direzione. Non dovrebbe essere più di + `Math.PI/2`. Il valore predefinito è `Math.PI/3`. +

    + + +

    [property:Boolean castShadow]

    +

    + Se impostato a `true` la luce proietterà ombre dinamiche. *Attenzione*: Questo è costoso e richiede + modifiche per ottenere l'aspetto corretto delle ombre. Vedi [page:SpotLightShadow] per i dettagli. + Il valore predefinito è `false`. +

    + +

    [property:Float decay]

    +

    + The amount the light dims along the distance of the light. Default is `2`.
    + In context of physically-correct rendering the default value should not be changed. +

    + +

    [property:Float distance]

    +

    + `Modalità predefinita` — Quando la distanza è zero, la luce non si attenua. Quando la distanza è diversa da zero, + la luce si attenuerà linearmente dalla massima intensità nella posizione della luce fino a zero a questa distanza + dalla luce. +

    +

    + `Modalità [page:WebGLRenderer.physicallyCorrectLights fisicamente corretta]` — Quando la distanza è + zero, la luce si attenuerà secondo la legge dell'inverso del quadrato alla distanza infinita. + Quando la distanza è diversa da zero, la luce si attenuerà secondo la legge dell'inverso del quadrato + fino in prossimità del limite di distanza, dove si attenuerà quindi rapidamente e uniformemente fino a `0`. + Intrinsecamente, i limiti non sono fisicamente corretti. +

    +

    + Il valore predefinito è `0.0`. +

    + +

    [property:Float intensity]

    +

    + L'intensità della luce. Il valore predefinito è `1`.
    + Nella modalità [page:WebGLRenderer.physicallyCorrectLights fisicamente corretta], l'intensità + è l'intensità luminosa della luce misurata in candela (cd).

    + + Modificando l'intensità si modificherà anche la potenza della luce. +

    + +

    [property:Boolean isSpotLight]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è del tipo [name]. +

    + +

    [property:Float penumbra]

    +

    + Percentuale del cono del riflettore che viene attenuata a causa della penombra. Prende valori tra + 0 e 1. Il valore predefinito è `0.0`. +

    + +

    [property:Vector3 position]

    +

    + Questo è impostato uguale a [page:Object3D.DefaultUp] (0, 1, 0), così che la luce brilli dall'alto veso il basso. +

    + +

    [property:Float power]

    +

    + La potenza della luce.
    + + Nella modalità [page:WebGLRenderer.physicallyCorrectLights fisicamente corretta], la potenza è la potenza + della luminosità della luce misurata in lumen (lm).

    + + Modificando la potenza si modificherà anche l'intensità della luce. +

    + + +

    [property:SpotLightShadow shadow]

    +

    + Una [page:SpotLightShadow] utilizzata per calcolare le ombre per questa luce. +

    + + +

    [property:Object3D target]

    +

    + Spotlight punta dalla sua [page:.position posizione] alla target.position. La posizione predefinita del target + è *(0, 0, 0)*.
    + + *Nota*: Affinchè la posizione del target possa essere modificata in qualcosa di diverso da quella predefinita, + è necessario aggiungerlo alla [page:Scene scena] utilizzando + + scene.add( light.target ); + + + In questo modo il [page:Object3D.matrixWorld matrixWorld] del target viene aggiornato automaticamente ad ogni frame.

    + + È anche possibile impostare il target in modo che sia un altro oggetto nella scena (qualsiasi cosa con + una proprietà [page:Object3D.position position]), in questo modo: + +const targetObject = new THREE.Object3D(); +scene.add(targetObject); + +light.target = targetObject; + + La spotlight ora seguirà l'oggetto target. +

    + +

    [property:Texture map]

    +

    + Una [page:Texture] utilizzata per modulare il colore della luce. Il colore della luce spot viene mescolato con il valore + RGB di questa texture, con un rapporto corrispondente al suo valore alfa. L'effetto di mascheramento simile a quello dei cookie + viene riprodotto utilizzando i valori (0, 0, 0, 1-cookie_value). + *Attenzione*: [param:SpotLight map] è disabilitata se [param:SpotLight castShadow] è *false*. +

    + +

    Metodi

    +

    + Vedi la classe base [page:Light Light] per i metodi comuni. +

    + +

    [method:undefined dispose]()

    +

    + Sovrascrive il metodo [page:Light.dispose dispose] della classe base. + Elimina l'[page:SpotLightShadow ombra] di questa luce. +

    + +

    [method:this copy]( [param:SpotLight source] )

    +

    + Copia il valore di tutte le proprietà dalla [page:SpotLight sorgente] della + SpotLight. +

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/lights/shadows/DirectionalLightShadow.html b/docs/api/it/lights/shadows/DirectionalLightShadow.html new file mode 100644 index 00000000000000..b25a6df34857db --- /dev/null +++ b/docs/api/it/lights/shadows/DirectionalLightShadow.html @@ -0,0 +1,101 @@ + + + + + + + + + + [page:LightShadow] → + +

    [name]

    + +

    + Questa classe viene utilizzata internamente da [page:DirectionalLight DirectionalLights] per calcolare le ombre.

    + + A differenza delle altre classi Ombra, questa utilizza una [page:OrthographicCamera] per calcolare le ombre, + piuttosto che una [page:PerspectiveCamera]. Questo è perché i raggi della luce da una [page:DirectionalLight] sono + paralleli. +

    + +

    Codice di Esempio

    + + + // Crea un WebGLRenderer e attiva le ombre nel renderer + const renderer = new THREE.WebGLRenderer(); + renderer.shadowMap.enabled = true; + renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap + + // Crea una DirectionalLight e attiva le ombre per la luce + const light = new THREE.DirectionalLight( 0xffffff, 1 ); + light.position.set( 0, 1, 0 ); //default; light shining from top + light.castShadow = true; // default false + scene.add( light ); + + // Imposta le proprietà dell'ombra per la luce + light.shadow.mapSize.width = 512; // default + light.shadow.mapSize.height = 512; // default + light.shadow.camera.near = 0.5; // default + light.shadow.camera.far = 500; // default + + // Crea una sfera che proietta le ombre (ma non le riceve) + const sphereGeometry = new THREE.SphereGeometry( 5, 32, 32 ); + const sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff0000 } ); + const sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); + sphere.castShadow = true; //default is false + sphere.receiveShadow = false; //default + scene.add( sphere ); + + // Crea un piano che riceve le ombre (ma non le proietta) + const planeGeometry = new THREE.PlaneGeometry( 20, 20, 32, 32 ); + const planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } ) + const plane = new THREE.Mesh( planeGeometry, planeMaterial ); + plane.receiveShadow = true; + scene.add( plane ); + + // Crea un helper per la telecamera ombra (opzionale) + const helper = new THREE.CameraHelper( light.shadow.camera ); + scene.add( helper ); + + +

    Costruttore

    +

    [name]( )

    +

    + Crea una nuova [name]. Questa classe non deve essere chiamata direttamente - viene + chiamata internamente da [page:DirectionalLight]. +

    + +

    Proprietà

    +

    + Vedi la classe base [page:LightShadow LightShadow] per le proprietà comuni. +

    + +

    [property:Camera camera]

    +

    + La visione del mondo della luce. Questo viene utilizzato per generare una mappa di profondità della scena; + gli oggetti dietro altri oggetti dalla prospettiva della luce saranno in ombra.

    + + L'impostazione predefinita è una [page:OrthographicCamera] con [page:OrthographicCamera.left left] e + [page:OrthographicCamera.bottom bottom] impostati a -5, [page:OrthographicCamera.right right] + e [page:OrthographicCamera.top top] impostati a 5, il piano [page:OrthographicCamera.near near] + imopstato a 0.5 e il piano [page:OrthographicCamera.far far] impostato a 500. +

    + +

    [property:Boolean isDirectionalLightShadow]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è del tipo [name]. +

    + +

    Metodi

    +

    + Vedi la classe base [page:LightShadow LightShadow] per i metodi comuni. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js] +

    + + diff --git a/docs/api/it/lights/shadows/LightShadow.html b/docs/api/it/lights/shadows/LightShadow.html new file mode 100644 index 00000000000000..0f8111c47b28a4 --- /dev/null +++ b/docs/api/it/lights/shadows/LightShadow.html @@ -0,0 +1,160 @@ + + + + + + + + + + +

    [name]

    + +

    + Serve come classe base per le altri classi shadow (ombra). +

    + + +

    Costruttore

    + +

    [name]( [param:Camera camera] )

    +

    + [page:Camera camera] - la visione del mondo da parte della luce.

    + + Crea una nuova [name]. Questa classe non deve essere chiamata direttamente - viene usata come classe base + da altre ombre di luce. +

    + +

    Proprietà

    + +

    [property:Boolean autoUpdate]

    +

    + Abilita gli aggiornamenti automatici dell'ombra della luce. Il valore predefinito è `true`. + Se non hai bisogno di luci/ombre, puoi impostarlo su `false`. +

    + +

    [property:Camera camera]

    +

    + La visione del mondo da parte della luce. Viene utilizzata per generare un mappa di profondità della scena; + gli oggetti dietro ad altri oggetti dalla prospettiva della luce saranno in ombra. +

    + +

    [property:Float bias]

    +

    + Bias della mappa delle ombre, quanto aggiungere o sottrarre dalla profondità normalizzata quando si decide se una superficie è in ombra.
    + Il valore predefinito è 0. Piccole regolazioni qui (nell'ordine di 0,0001) possono aiutare a ridurre gli artefatti nelle ombre. +

    + +

    [property:Integer blurSamples]

    +

    + La quantità di campioni da utilizzare durante la sfocatura di una mappa ombra VSM. +

    + +

    [property:WebGLRenderTarget map]

    +

    + La mappa di profondità generata usando la telecamera interna; una posizione oltre la profondità di un pixel è in ombra. + Calcolato internamente durante il rendering. +

    + +

    [property:WebGLRenderTarget mapPass]

    +

    + La mappa di distribuzione generata usando la telecamera interna; un'occlusione viene calcolata in base alla distribuzione + della profondità. Calcolato internamente durante il rendering. +

    + +

    [property:Vector2 mapSize]

    +

    + Un [Page:Vector2] che definisce la larghezza e l'altezza della mappa dell'ombra.

    + + Valori più alti danno una maggior qualità alle ombre a scapito del tempo di calcolo. I valori + devono essere potenze di 2, fino a [page:WebGLRenderer.capabilities].maxTextureSize per un determinato + dispositivo, sebbene la larghezza e l'altezza non debbano essere le stesse (quindi, per esempio (512, 1024) + è valido). Il valore predefinito è *( 512, 512 )*. +

    + +

    [property:Matrix4 matrix]

    +

    + Modello per lo spazio delle ombre della telecamera, per calcolare la posizione e la profondità nella mappa delle ombre. + Memorizzato in una [page:Matrix4 Matrix4]. Questa viene calcolata internamente durante il rendering. +

    + +

    [property:Boolean needsUpdate]

    +

    + Quando viene impostato a `true`, le mappe d'ombra saranno aggiornate nella successiva chiamata del `render`. + L'impostazione predefinita è `false`. + Se si è impostato [page:.autoUpdate] a `false`, sarà necessario impostare questa proprietà su `true` e quindi + eseguire una chiamata di rendering per aggiornare l'ombra della luce. +

    + +

    [property:Float normalBias]

    +

    + Definisce di quanto la posizione utilizzata per interrogare la mappa delle ombre è sfalsata rispetto + alla normale dell'oggetto. Il valore predefinito è 0. Aumentando questo valore si può ridurre l'acne dell'ombra, + soprattutto nelle scene di grandi dimensioni in cui la luce illumina la geometria con un angolo poco profondo. + Il costo è che le ombre possono apparire distorte. +

    + +

    [property:Float radius]

    +

    + Impostando questo valore maggiore di 1 si sfocheranno i bordi dell'ombra.
    + + Valori alti causeranno degli effetti di banding indesiderati nelle ombre - un [page:.mapSize mapSize] + maggiore consentirà di utilizzare un valore più elevato qui prima che questi effetti diventino visibili.
    + Se [page:WebGLRenderer.shadowMap.type] è impostato a [page:Renderer PCFSoftShadowMap], il raggio non ha effetto e + si consiglia di aumentare la morbidezza diminuendo invece [page:.mapSize mapSize].

    + + Si noti che questo non ha effetto se [page:WebGLRenderer.shadowMap.type] è impostato a [page:Renderer BasicShadowMap]. +

    + + +

    Metodi

    + +

    [method:Vector2 getFrameExtents]()

    +

    + Utilizzato internamente dal renderer per estendere la mappa d'ombra in modo da contenere tutti i viewport. +

    + +

    [method:undefined updateMatrices]( [param:Light light] )

    +

    + Aggiorna le matrici per la telecamera e l'ombra, utilizzato internamente dal renderer.

    + + light -- la luce per la quale viene renderizzata l'ombra. +

    + +

    [method:Frustum getFrustum]()

    +

    + Ottiene il frustum delle telecamere ombra. Utilizzato internamente dal renderer per tagliare gli oggetti. +

    + +

    [method:number getViewportCount]()

    +

    + Utilizzato internamente dal renderer per ottenere il numero di viewport che devono essere renderizzate per questa ombra. +

    + +

    [method:undefined dispose]()

    +

    + Elimina le texture di questa ombra ([page:LightShadow.map map] e [page:LightShadow.mapPass mapPass]). +

    + +

    [method:this copy]( [param:LightShadow source] )

    +

    + Copia il valore di tutte le proprietà dalla [page:LightShadow sorgente] della Light. +

    + +

    [method:LightShadow clone]()

    +

    + Crea una nuova LightShadow con le stesse proprietà di questa. +

    + +

    [method:Object toJSON]()

    +

    + Serializza questa LightShadow. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js] +

    + + diff --git a/docs/api/it/lights/shadows/PointLightShadow.html b/docs/api/it/lights/shadows/PointLightShadow.html new file mode 100644 index 00000000000000..1abab5fc926cb4 --- /dev/null +++ b/docs/api/it/lights/shadows/PointLightShadow.html @@ -0,0 +1,94 @@ + + + + + + + + + + [page:LightShadow] → + +

    [name]

    + +

    + Questa classe viene utilizzata internamente da [page:PointLight PointLights] per calcolare le ombre. +

    + + +

    Codice di Esempio

    + + // Crea un WebGLRenderer e attiva le ombre nel renderer + const renderer = new THREE.WebGLRenderer(); + renderer.shadowMap.enabled = true; + renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap + + // Crea una PointLight e attiva le ombre per la luce + const light = new THREE.PointLight( 0xffffff, 1, 100 ); + light.position.set( 0, 10, 4 ); + light.castShadow = true; // default false + scene.add( light ); + + // Imposta le proprietà dell'ombra per la luce + light.shadow.mapSize.width = 512; // default + light.shadow.mapSize.height = 512; // default + light.shadow.camera.near = 0.5; // default + light.shadow.camera.far = 500; // default + + // Crea una sfera che proietta le ombre (ma non le riceve) + const sphereGeometry = new THREE.SphereGeometry( 5, 32, 32 ); + const sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff0000 } ); + const sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); + sphere.castShadow = true; //default is false + sphere.receiveShadow = false; //default + scene.add( sphere ); + + // Crea un piano che riceve le ombre (ma non le proietta) + const planeGeometry = new THREE.PlaneGeometry( 20, 20, 32, 32 ); + const planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } ) + const plane = new THREE.Mesh( planeGeometry, planeMaterial ); + plane.receiveShadow = true; + scene.add( plane ); + + // Crea un helper per la telecamera ombra (opzionale) + const helper = new THREE.CameraHelper( light.shadow.camera ); + scene.add( helper ); + + +

    Costruttore

    +

    [name]( )

    +

    + Crea una nuova [name]. Questa classe non deve essere chiamata direttamente - viene + chiamata internamente da [page:PointLight]. +

    + +

    Proprietà

    +

    + Vedi la classe base [page:LightShadow LightShadow] per le proprietà comuni. +

    + +

    [property:Boolean isPointLightShadow]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è del tipo [name]. +

    + +

    Metodi

    +

    + Vedi la classe base [page:LightShadow LightShadow] per i metodi comuni. +

    + +

    [method:undefined updateMatrices]( [param:Light light], [param:number viewportIndex])

    +

    + Aggiorna le matrici per la telecamera e l'ombra, utilizzato internamente dal renderer.

    + + light -- la luce per la quale si sta renderizzando l'ombra.
    + viewportIndex -- calcola la matrice per questo viewport. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js] +

    + + diff --git a/docs/api/it/lights/shadows/SpotLightShadow.html b/docs/api/it/lights/shadows/SpotLightShadow.html new file mode 100644 index 00000000000000..26e45c88b5d7a8 --- /dev/null +++ b/docs/api/it/lights/shadows/SpotLightShadow.html @@ -0,0 +1,102 @@ + + + + + + + + + + [page:LightShadow] → + +

    [name]

    + +

    + Viene utilizzata internamente da [page:SpotLight SpotLights] per calcolare le ombre. +

    + +

    Codice di Esempio

    + + // Crea un WebGLRenderer e attiva le ombre nel renderer + const renderer = new THREE.WebGLRenderer(); + renderer.shadowMap.enabled = true; + renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap + + // Crea una SpotLight e attiva le ombre per la luce + const light = new THREE.SpotLight( 0xffffff ); + light.castShadow = true; // default false + scene.add( light ); + + // Imposta le proprietà dell'ombra per la luce + light.shadow.mapSize.width = 512; // default + light.shadow.mapSize.height = 512; // default + light.shadow.camera.near = 0.5; // default + light.shadow.camera.far = 500; // default + light.shadow.focus = 1; // default + + // Crea una sfera che proietta le ombre (ma non le riceve) + const sphereGeometry = new THREE.SphereGeometry( 5, 32, 32 ); + const sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff0000 } ); + const sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); + sphere.castShadow = true; //default is false + sphere.receiveShadow = false; //default + scene.add( sphere ); + + // Crea un piano che riceve le ombre (ma non le proietta) + const planeGeometry = new THREE.PlaneGeometry( 20, 20, 32, 32 ); + const planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } ) + const plane = new THREE.Mesh( planeGeometry, planeMaterial ); + plane.receiveShadow = true; + scene.add( plane ); + + // Crea un helper per la telecamera ombra (opzionale) + const helper = new THREE.CameraHelper( light.shadow.camera ); + scene.add( helper ); + + +

    Costruttore

    + +

    Il costruttore crea una [param:PerspectiveCamera PerspectiveCamera] per gestire la visione del mondo dell'ombra.

    + +

    Proprietà

    +

    + Vedi la classe base [page:LightShadow LightShadow] per le proprietà comuni. +

    + + +

    [property:Camera camera]

    +

    + La visione del mondo della luce. Questo viene utilizzato per generare una mappa di profondità della scena; + gli oggetti dietro altri oggetti dalla prospettiva della luce saranno in ombra.

    + + L'impostazione predefinita è una [page:PerspectiveCamera] con il piano [page:PerspectiveCamera.near near] impostato a `0.5`. + Il [page:PerspectiveCamera.fov fov] traccerà la proprietà dell'[page:SpotLight.angle angolo] del proprietario + [page:SpotLight SpotLight] tramite il metodo [page:SpotLightShadow.update update]. Allo stesso modo, la proprietà + [page:PerspectiveCamera.aspect aspect] terrà traccia dell'aspetto della [page:LightShadow.mapSize mapSize]. + Se la proprietà [page:SpotLight.distance distance] della luce è impostata, il piano [page:PerspectiveCamera.far far] + la seguirà, altrimenti il valore predefinito è `500`. +

    + +

    [property:Number focus]

    +

    + Utilizzato per mettere a fuoco la telecamera. Il campo visivo della telecamera è impostato come percentuale + del campo visivo del riflettore. L'intervallo è `[0, 1]`. Il valore predefinito è `1.0`.
    +

    + +

    [property:Boolean isSpotLightShadow]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è del tipo [name]. +

    + +

    Metodi

    +

    + Vedi la classe base [page:LightShadow LightShadow] per i metodi comuni. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js] +

    + + diff --git a/docs/api/it/loaders/AnimationLoader.html b/docs/api/it/loaders/AnimationLoader.html new file mode 100644 index 00000000000000..167ebb03c107c7 --- /dev/null +++ b/docs/api/it/loaders/AnimationLoader.html @@ -0,0 +1,88 @@ + + + + + + + + + + [page:Loader] → + +

    [name]

    + +

    + Classe per il caricamento di [page:AnimationClip AnimationClip] in formato JSON. + Utilizza internamente il [page:FileLoader] per caricare i file. +

    + +

    Codice di Esempio

    + + + // istanzia un loader + const loader = new THREE.AnimationLoader(); + + // carica una risorsa + loader.load( + // URL della risorsa + 'animations/animation.js', + + // onLoad callback + function ( animations ) { + // animations è un array di AnimationClips + }, + + // onProgress callback + function ( xhr ) { + console.log( (xhr.loaded / xhr.total * 100) + '% loaded' ); + }, + + // onError callback + function ( err ) { + console.log( 'An error happened' ); + } + ); + + +

    Costruttore

    + +

    [name]( [param:LoadingManager manager] )

    +

    + [page:LoadingManager manager] — Il [page:LoadingManager loadingManager] del loader da utilizzare. Il valore predefinito è [page:LoadingManager THREE.DefaultLoadingManager].

    + + Crea un nuovo [name]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Loader] per le proprietà comuni.

    + +

    Metodi

    +

    Vedi la classe base [page:Loader] per i metodi comuni.

    + +

    [method:undefined load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    +

    + [page:String url] — Il path o URL del file. Questo può anche essere un + [link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].
    + [page:Function onLoad] — Verrà chiamato quando il caricamento sarà completato. L'argomento saranno le [page:AnimationClip animation clip] caricate.
    + [page:Function onProgress] (opzionale) — Verrà chiamato durante il caricamento. L'argomento sarà l'istanza ProgressEvent, la quale contiene .[page:Boolean lengthComputable], + .[page:Integer total] e .[page:Integer loaded]. Se il server non imposta l'header Content-Length; .[page:Integer total] sarà 0.
    + [page:Function onError] (opzionale) — Verrà chiamato in caso di errori di caricamento.

    + + Inizia il caricamento dall'url e passa l'animazione caricata a onLoad. +

    + +

    [method:Array parse]( [param:JSON json] )

    +

    + [page:JSON json] — obbligatorio

    + + Parsa l'oggetto JSON e restituisce un array di animation clip. Le singole clip nell'oggetto verranno + parsate con [page:AnimationClip.parse]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/loaders/AudioLoader.html b/docs/api/it/loaders/AudioLoader.html new file mode 100644 index 00000000000000..b4538223a4c7eb --- /dev/null +++ b/docs/api/it/loaders/AudioLoader.html @@ -0,0 +1,97 @@ + + + + + + + + + + [page:Loader] → + +

    [name]

    + +

    + Classe per il caricamento di un [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBuffer AudioBuffer]. + Utilizza internamente il [page:FileLoader] per caricare i file. +

    + +

    Codice di Esempio

    + + + // istanzia il listener + const audioListener = new THREE.AudioListener(); + + // aggiunge il listener alla telecamera + camera.add( audioListener ); + + // istanzia un oggetto audio + const oceanAmbientSound = new THREE.Audio( audioListener ); + + // aggiunge l'oggetto audio alla scena + scene.add( oceanAmbientSound ); + + // istanzia un loader + const loader = new THREE.AudioLoader(); + + // carica una risorsa + loader.load( + // URL della risorsa + 'audio/ambient_ocean.ogg', + + // onLoad callback + function ( audioBuffer ) { + // imposta il buffer dell'oggetto audio nell'oggetto caricato + oceanAmbientSound.setBuffer( audioBuffer ); + + // avvia l'audio + oceanAmbientSound.play(); + }, + + // onProgress callback + function ( xhr ) { + console.log( (xhr.loaded / xhr.total * 100) + '% loaded' ); + }, + + // onError callback + function ( err ) { + console.log( 'An error happened' ); + } + ); + + +

    Costruttore

    + +

    [name]( [param:LoadingManager manager] )

    +

    + [page:LoadingManager manager] — Il [page:LoadingManager loadingManager] del loader da utilizzare. Il valore predefinito è [page:LoadingManager THREE.DefaultLoadingManager].

    + + Crea un nuovo [name]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Loader] per le proprietà comuni.

    + +

    Metodi

    +

    Vedi la classe base [page:Loader] per i metodi comuni.

    + +

    [method:undefined load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    +

    + [page:String url] — Il path o URL del file. Questo può anche essere un + [link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].
    + [page:Function onLoad] — Verrà chiamato quando il caricamento sarà completato. L'argomento sarà la risposta del testo caricato.
    + [page:Function onProgress] (opzionale) — Verrà chiamato durante il caricamento. L'argomento sarà l'istanza ProgressEvent, la quale contiene + .[page:Boolean lengthComputable], .[page:Integer total] e .[page:Integer loaded]. Se il server non imposta l'header Content-Length; .[page:Integer total] sarà 0.
    + [page:Function onError] (opzionale) — Verrà chiamato in caso di errori di caricamento.
    +

    +

    + Inizia il caricamento dall'url e passa l'[page:String AudioBuffer] caricato a onLoad. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/loaders/BufferGeometryLoader.html b/docs/api/it/loaders/BufferGeometryLoader.html new file mode 100644 index 00000000000000..dcaff410ab02f3 --- /dev/null +++ b/docs/api/it/loaders/BufferGeometryLoader.html @@ -0,0 +1,96 @@ + + + + + + + + + + [page:Loader] → + +

    [name]

    + +

    + Classe per il caricamento di una [page:BufferGeometry]. + Utilizza internamente il [page:FileLoader] per caricare i file. +

    + +

    Codice di Esempio

    + + + // istanzia un loader + const loader = new THREE.BufferGeometryLoader(); + + // carica una risorsa + loader.load( + // URL della risorsa + 'models/json/pressure.json', + + // onLoad callback + function ( geometry ) { + const material = new THREE.MeshLambertMaterial( { color: 0xF5F5F5 } ); + const object = new THREE.Mesh( geometry, material ); + scene.add( object ); + }, + + // onProgress callback + function ( xhr ) { + console.log( (xhr.loaded / xhr.total * 100) + '% loaded' ); + }, + + // onError callback + function ( err ) { + console.log( 'An error happened' ); + } + ); + + +

    Esempi

    + +

    + [example:webgl_performance WebGL / performance] +

    + +

    Costruttore

    + +

    [name]( [param:LoadingManager manager] )

    +

    + [page:LoadingManager manager] — Il [page:LoadingManager loadingManager] del loader da utilizzare. Il valore predefinito è [page:LoadingManager THREE.DefaultLoadingManager]. +

    +

    + Crea un nuovo [name]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Loader] per le proprietà comuni.

    + +

    Metodi

    +

    Vedi la classe base [page:Loader] per i metodi comuni.

    + +

    [method:undefined load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    +

    + [page:String url] — Il path o URL del file. Questo può anche essere un + [link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].
    + [page:Function onLoad] — Verrà chiamato quando il caricamento sarà completato. L'argomento sarà la [page:BufferGeometry] caricata.
    + [page:Function onProgress] (opzionale) — Verrà chiamato durante il caricamento. L'argomento sarà l'istanza ProgressEvent, la quale contiene + .[page:Boolean lengthComputable], .[page:Integer total] e .[page:Integer loaded]. Se il server non imposta l'header Content-Length; .[page:Integer total] sarà 0.
    + [page:Function onError] (opzionale) — Verrà chiamato in caso di errori di caricamento.
    +

    +

    + Inizia il caricamento dall'url e passa il contenuto della risposta parsato a onLoad. +

    + +

    [method:BufferGeometry parse]( [param:Object json] )

    +

    + [page:Object json] — La struttura `JSON` da parsare.

    + Parsa una struttura `JSON` e restituisce una [page:BufferGeometry]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/loaders/Cache.html b/docs/api/it/loaders/Cache.html new file mode 100644 index 00000000000000..ff17dfe115b6da --- /dev/null +++ b/docs/api/it/loaders/Cache.html @@ -0,0 +1,76 @@ + + + + + + + + + +

    [name]

    + +

    + Un semplice sistema di memorizzazione nella cache, utilizzato internamente dal [page:FileLoader]. +

    + +

    Codice di Esempio

    + +

    Per abilitare la memorizzazione nella cache su tutti i loader che utilizzano il [page:FileLoader], impostare

    + + THREE.Cache.enabled = true. + + + +

    Esempi

    + +

    + [example:webgl_geometry_text WebGL / geometry / text ]
    + [example:webgl_interactive_instances_gpu WebGL / interactive / instances / gpu]
    + [example:webgl_loader_ttf WebGL / loader / ttf] +

    + +

    Proprietà

    + +

    [property:Boolean enabled]

    +

    Indica se il caching è abilitato. Il valore predefinito è `false`.

    + +

    [property:Object files]

    +

    Un [page:Object oggetto] che contiene file memorizzati nella cache.

    + + +

    Metodi

    + +

    [method:undefined add]( [param:String key], [param:Object file] )

    +

    + [page:String key] — La [page:String chiave] (key) con cui fare riferimento al file memorizzato nella cache.
    + [page:Object file] — Il file da memorizzare nella cache.

    + + Aggiunge una voce della cache con una chiave che fa riferimento al file. Se questa chiave contiene + già un file, sarà sovrascritta. +

    + +

    [method:Any get]( [param:String key] )

    +

    + [page:String key] — Una chiave stringa.

    + + Ottiene il valore di [page:String key]. Se la chiave non esiste restituirà `undefined`. +

    + +

    [method:undefined remove]( [param:String key] )

    +

    + [page:String key] — Una chiave stringa che fa riferimento ad un file memorizzato nella cache.

    + + Rimuove il file memorizzato nella cache associato alla chiave. +

    + +

    [method:undefined clear]()

    +

    Rimuove tutti i valori dalla cache.

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/loaders/CompressedTextureLoader.html b/docs/api/it/loaders/CompressedTextureLoader.html new file mode 100644 index 00000000000000..638e65126b397a --- /dev/null +++ b/docs/api/it/loaders/CompressedTextureLoader.html @@ -0,0 +1,63 @@ + + + + + + + + + + [page:Loader] → + +

    [name]

    + +

    + Classe base astratta per il loader di texture basato su blocchi (dds, pvr, ...). + Utilizza internamente il [page:FileLoader] per caricare i file. +

    + +

    Esempi

    + +

    + Vedi il [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/DDSLoader.js DDSLoader] + e il [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/PVRLoader.js PVRLoader] + per esempi di classe derivate. +

    + +

    Costruttore

    + +

    [name]( [param:LoadingManager manager] )

    +

    + [page:LoadingManager manager] — Il [page:LoadingManager loadingManager] del loader da utilizzare. + Il valore predefinito è [page:LoadingManager THREE.DefaultLoadingManager].

    + + Crea un nuovo [name]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Loader] per le proprietà comuni.

    + +

    Metodi

    +

    Vedi la classe base [page:Loader] per i metodi comuni.

    + +

    [method:CompressedTexture load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    +

    + [page:String url] — Il path o URL del file. Questo può anche essere un + [link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].
    + [page:Function onLoad] (opzionale) — Verrà chiamato quando il caricamento sarà completato. L'argomento sarà la texture caricata.
    + [page:Function onProgress] (opzionale) — Verrà chiamato durante il caricamento. L'argomento sarà l'istanza ProgressEvent, la quale contiene + .[page:Boolean lengthComputable], .[page:Integer total] e .[page:Integer loaded]. Se il server non imposta l'header Content-Length; .[page:Integer total] sarà 0.
    + [page:Function onError] (opzionale) — Verrà chiamato in caso di errori di caricamento.
    +

    +

    + Inizia il caricamento dall'url e passa la texture caricata a onLoad. + Il metodo restituisce anche un nuovo oggetto texture che può essere direttamente utilizzato per la creazione di materiale. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/loaders/CubeTextureLoader.html b/docs/api/it/loaders/CubeTextureLoader.html new file mode 100644 index 00000000000000..21cacfd5b94f63 --- /dev/null +++ b/docs/api/it/loaders/CubeTextureLoader.html @@ -0,0 +1,80 @@ + + + + + + + + + + [page:Loader] → + +

    [name]

    + +

    + Classe per il caricamento di una [page:CubeTexture CubeTexture]. + Utilizza internamente l'[page:ImageLoader] per caricare i file. +

    + +

    Codice di Esempio

    + + +const scene = new THREE.Scene(); +scene.background = new THREE.CubeTextureLoader() + .setPath( 'textures/cubeMaps/' ) + .load( [ + 'px.png', + 'nx.png', + 'py.png', + 'ny.png', + 'pz.png', + 'nz.png' + ] ); + + +

    Esempi

    + +

    + [example:webgl_materials_cubemap materials / cubemap]
    + [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic]
    + [example:webgl_materials_cubemap_refraction materials / cubemap / refraction] +

    + +

    Costruttore

    + +

    [name]( [param:LoadingManager manager] )

    +

    + [page:LoadingManager manager] — Il [page:LoadingManager loadingManager] del loader da utilizzare. Il valore predefinito è [page:LoadingManager THREE.DefaultLoadingManager].

    + Crea un nuovo [name]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Loader] per le proprietà comuni.

    + +

    Metodi

    +

    Vedi la classe base [page:Loader] per i metodi comuni.

    + +

    [method:CubeTexture load]( [param:String urls], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    +

    + [page:String urls] — array di 6 url di immagini, una per ogni lato della CubeTexture. + Le url devono essere specificate nel seguente ordine: pos-x, neg-x, pos-y, neg-y, pos-z, neg-z. + Possono anche essere [link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URIs].
    + Si noti che, per convenzione, le mappe cubiche sono specificate in un sistema di coordinate in cui la x positiva è + a destra quando si guarda l'asse z positivo -- in altre parole, utilizza un sistema di coordinate sinistrorso. + Poiché Three.js utilizza un sistema di coordinate destrorso, le mappe d'ambiente utilizzate in three.js avranno pos-x e neg-x invertiti.
    + [page:Function onLoad] (opzionale) — Verrà chiamato quando il caricamento sarà completato. L'argomento sarà la [page:CubeTexture texture] caricata.
    + [page:Function onProgress] (opzionale) — Questa funzione di callback non è al momento supportata.
    + [page:Function onError] (opzionale) — Verrà chiamato in caso di errori di caricamento.
    +

    +

    + Inizia il caricamento dall'url e passa la [page:CubeTexture texture] caricata a onLoad. + Il metodo inoltre restituisce un nuovo oggetto texture che può essere direttamente utilizzato per la creazione di materiale. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/loaders/DataTextureLoader.html b/docs/api/it/loaders/DataTextureLoader.html new file mode 100644 index 00000000000000..cb3ad8af7afd57 --- /dev/null +++ b/docs/api/it/loaders/DataTextureLoader.html @@ -0,0 +1,62 @@ + + + + + + + + + + [page:Loader] → + +

    [name]

    + +

    + Classe base astratta per il caricamento di formati generici di texture binare (rgbe, hdr, ...). + Utilizza internamente il [page:FileLoader] per caricare i file, e crea una nuova [page:DataTexture]. +

    + +

    Esempi

    + +

    + Vedi l'[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/RGBELoader.js RGBELoader] + per un esempio di una classe derivata. +

    + +

    Costruttore

    + +

    [name]( [param:LoadingManager manager] )

    +

    + [page:LoadingManager manager] — Il [page:LoadingManager loadingManager] del loader da utilizzare. + Il valore predefinito è [page:LoadingManager THREE.DefaultLoadingManager].

    + + Crea un nuovo [name]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Loader] per le proprietà comuni.

    + +

    Metodi

    +

    Vedi la classe base [page:Loader] per i metodi comuni.

    + +

    [method:DataTexture load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    +

    + [page:String url] — Il path o URL del file. Questo può anche essere un + [link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].
    + [page:Function onLoad] (opzionale) — Verrà chiamato quando il caricamento sarà completato. L'argomento sarà la texture caricata.
    + [page:Function onProgress] (opzionale) — Verrà chiamato durante il caricamento. L'argomento sarà l'istanza ProgressEvent, la quale contiene + .[page:Boolean lengthComputable], .[page:Integer total] e .[page:Integer loaded]. Se il server non imposta l'header Content-Length; .[page:Integer total] sarà 0.
    + [page:Function onError] (opzionale) — Verrà chiamato in caso di errori di caricamento.
    +

    +

    + Inizia il caricamento dall'url e passa la texture caricata a onLoad. + Questo metodo restituisce anche un nuovo oggetto texture che può essere direttamente utilizzato per la creazione di materiale. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/loaders/FileLoader.html b/docs/api/it/loaders/FileLoader.html new file mode 100644 index 00000000000000..370956d7f00433 --- /dev/null +++ b/docs/api/it/loaders/FileLoader.html @@ -0,0 +1,113 @@ + + + + + + + + + + [page:Loader] → + +

    [name]

    + +

    + Una classe di basso livello per il caricamento delle risorse tramite la Fetch, utilizzata + internamente dalla maggior parte dei loader. + Può anche essere utilizzata direttamente per caricare qualsiasi tipo di file che non ha un loader. +

    + +

    Codice di Esempio

    + + const loader = new THREE.FileLoader(); + + // carica un file di testo e invia il risultato alla console + loader.load( + // URL della risorsa + 'example.txt', + + // onLoad callback + function ( data ) { + // invia il testo alla console + console.log( data ) + }, + + // onProgress callback + function ( xhr ) { + console.log( (xhr.loaded / xhr.total * 100) + '% loaded' ); + }, + + // onError callback + function ( err ) { + console.error( 'An error happened' ); + } + ); + + +

    + Nota: La cache deve essere abilitata usando + THREE.Cache.enabled = true; + Questa è una proprietà globale e deve essere impostata una volta per essere utilizzata da tutti i loader che usano il FileLoader internamente. + [page:Cache Cache] è un modulo della cache che contiene la risposta di ogni richiesta fatta attraverso questo loader, quindi ogni file viene richiesto una sola volta. +

    + + +

    Costruttore

    + +

    [name] ( [param:LoadingManager manager] )

    +

    + [page:LoadingManager manager] — Il [page:LoadingManager loadingManager] del loader da utilizzare. + Il valore predefinito è [page:LoadingManager THREE.DefaultLoadingManager]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Loader] per le proprietà comuni.

    + +

    [property:String mimeType]

    +

    + Il [link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types mimeType] previsto. + Vedi [page:.setMimeType]. Il valore predefinito è `undefined`. +

    + +

    [property:String responseType]

    +

    Il tipo di risposta previsto. Vedi [page:.setResponseType]. Il valore predefinito è `undefined`.

    + +

    Metodi

    +

    Vedi la classe base [page:Loader] per i metodi comuni.

    + +

    [method:undefined load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    +

    + [page:String url] — Il path o URL del file. Questo può anche essere un + [link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].
    + [page:Function onLoad] (opzionale) — Verrà chiamato quando il caricamento sarà completato. L'argomento sarà la risposta caricata.
    + [page:Function onProgress] (opzionale) — Verrà chiamato durante il caricamento. L'argomento sarà l'istanza ProgressEvent, che contiene + .[page:Boolean lengthComputable], .[page:Integer total] e .[page:Integer loaded]. Se il server non imposta l'header Content-Length; .[page:Integer total] sarà 0.
    + [page:Function onError] (opzionale) — Verrà chiamato in caso di errori di caricamento.

    + + Inizia il caricamento dall'url e passa la risposta alla funzione onLoad. +

    + +

    [method:this setMimeType]( [param:String mimeType] )

    +

    + Imposta il [link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types mimeType] previsto + per il file in fase di caricamento. Si noti che in molti casi questo verrà determinato automaticamente, quindi il valore predefinito è `undefined`. +

    + +

    [method:this setResponseType]( [param:String responseType] )

    +

    + Cambia il type della risposta. I valori validi sono:
    + [page:String text] o una stringa vuota (valore predefinito) - restituisce i dati come [page:String String].
    + [page:String arraybuffer] - carica i dati in un [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer ArrayBuffer] e lo restituisce.
    + [page:String blob] - restituisce i dati come un [link:https://developer.mozilla.org/en/docs/Web/API/Blob Blob].
    + [page:String document] - parsa il file utilizzando un [link:https://developer.mozilla.org/en-US/docs/Web/API/DOMParser DOMParser].
    + [page:String json] - parsa il file utilizzando un [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse JSON.parse].
    +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/loaders/ImageBitmapLoader.html b/docs/api/it/loaders/ImageBitmapLoader.html new file mode 100644 index 00000000000000..1e0af5c28b7ace --- /dev/null +++ b/docs/api/it/loaders/ImageBitmapLoader.html @@ -0,0 +1,115 @@ + + + + + + + + + + [page:Loader] → + +

    [name]

    + +

    + Un loader per caricare un'[page:Image] come un'[link:https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap ImageBitmap]. + Un'ImageBitmap fornisce un percorso asincrono ed efficiente in termini di risorse per preparare le texture per la + visualizzazione in WebGL.
    + A differenza del [page:FileLoader], [name] non permette richieste multiple concorrenti per lo stesso URL. +

    + +

    + Si noti che [page:Texture.flipY] e [page:Texture.premultiplyAlpha] con [link:https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap ImageBitmap] + vengono ignorati. [link:https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap ImageBitmap] necessita di queste configurazioni per la creazione + di bitmap a differenza delle immagini regolari per il caricamento su GPU. È invece necessario impostare le opzioni equivalenti tramite + [page:ImageBitmapLoader.setOptions]. Fare riferimento alle [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.10 specifiche WebGL] + per i dettagli. +

    + +

    Codice di Esempio

    + + + // istanzia un loader + const loader = new THREE.ImageBitmapLoader(); + + // imposta le opzioni se necessario + loader.setOptions( { imageOrientation: 'flipY' } ); + + // carica un'immagine + loader.load( + // URL della risorsa + 'textures/skyboxsun25degtest.png', + + // onLoad callback + function ( imageBitmap ) { + const texture = new THREE.CanvasTexture( imageBitmap ); + const material = new THREE.MeshBasicMaterial( { map: texture } ); + }, + + // la callback onProgress non è al momento supportata + undefined, + + // onError callback + function ( err ) { + console.log( 'An error happened' ); + } + ); + + +

    Esempi

    + +

    + [example:webgl_loader_imagebitmap WebGL / loader / ImageBitmap] +

    + +

    Costruttore

    + +

    [name]( [param:LoadingManager manager] )

    +

    + [page:LoadingManager manager] — Il [page:LoadingManager loadingManager] del loader da utilizzare. Il valore predefinito è [page:LoadingManager THREE.DefaultLoadingManager].

    + + Crea un nuovo [name]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Loader] per le proprietà comuni.

    + +

    [property:Boolean isImageBitmapLoader]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:String options]

    +

    + Un oggetto opzionale che imposta le opzioni per il metodo factory + [link:https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/createImageBitmap createImageBitmap] utilizzato + internamente. Il valore predefinito è `undefined`. +

    + +

    Metodi

    +

    Vedi la classe base [page:Loader] per i metodi comuni.

    + +

    [method:undefined load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    +

    + [page:String url] — Il path o URL del file. Questo può anche essere un + [link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].
    + [page:Function onLoad] — Verrà chiamato quando il caricamento sarà completato. L'argomento sarà l'[page:Image immagine] caricata.
    + [page:Function onProgress] (opzionale) — Questa funzione di callback non è al momento supportata.
    + [page:Function onError] (opzionale) — Verrà chiamato in caso di errori di caricamento.
    +

    +

    + Inizia il caricamento dall'url e restituisce l'oggetto [page:ImageBitmap immagine] che conterrà i dati. +

    + +

    [method:this setOptions]( [param:Object options] )

    +

    + Imposta l'oggetto opzioni per [link:https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/createImageBitmap createImageBitmap]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/loaders/ImageLoader.html b/docs/api/it/loaders/ImageLoader.html new file mode 100644 index 00000000000000..e944c4f6d3fb96 --- /dev/null +++ b/docs/api/it/loaders/ImageLoader.html @@ -0,0 +1,94 @@ + + + + + + + + + + [page:Loader] → + +

    [name]

    + +

    + Un loader per il caricamento di un'[page:Image]. + Questa classe viene utilizzata internamente dalle classi + [page:CubeTextureLoader], [page:ObjectLoader] e [page:TextureLoader]. +

    + +

    Codice di Esempio

    + + + // istanzia un loader + const loader = new THREE.ImageLoader(); + + // carica un'immagine + loader.load( + // URL della risorsa + 'textures/skyboxsun25degtest.png', + + // onLoad callback + function ( image ) { + // utilizza l'immagine, per esempio disegna una parte di essa nel canvas + const canvas = document.createElement( 'canvas' ); + const context = canvas.getContext( '2d' ); + context.drawImage( image, 100, 100 ); + }, + + // la callback onProgress non è al momento supportata + undefined, + + // onError callback + function () { + console.error( 'An error happened.' ); + } + ); + + +

    + Si noti che la versione r84 di three.js ha eliminato il supporto per gli eventi di avanzamento di ImageLoader. + Per un ImageLoader che supporti gli eventi di avanzamento, vedi [link:https://github.com/mrdoob/three.js/issues/10439#issuecomment-275785639 questo thread]. +

    + +

    Esempi

    + +

    + [example:webgl_loader_obj WebGL / loader / obj]
    + [example:webgl_shaders_ocean WebGL / shaders / ocean] +

    + +

    Costruttore

    + +

    [name]( [param:LoadingManager manager] )

    +

    + [page:LoadingManager manager] — Il [page:LoadingManager loadingManager] del loader da utilizzare. Il valore predefinito è [page:LoadingManager THREE.DefaultLoadingManager].

    + + Crea un nuovo [name]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Loader] per le proprietà comuni.

    + +

    Metodi

    +

    Vedi la classe base [page:Loader] per i metodi comuni.

    + +

    [method:HTMLImageElement load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    +

    + [page:String url] — Il path o URL del file. Questo può anche essere un + [link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].
    + [page:Function onLoad] — Verrà chiamato quando il caricamento sarà completato. L'argomento sarà l'[page:Image immagine] caricata.
    + [page:Function onProgress] (opzionale) — Questa funzione di callback non è al momento supportata.
    + [page:Function onError] (opzionale) — Verrà chiamato in caso di errori di caricamento.
    +

    +

    + Inizia il caricamento dall'url e restituisce l'oggetto [page:ImageBitmap immagine] che conterrà i dati. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/loaders/Loader.html b/docs/api/it/loaders/Loader.html new file mode 100644 index 00000000000000..3fc4a8a1197f97 --- /dev/null +++ b/docs/api/it/loaders/Loader.html @@ -0,0 +1,125 @@ + + + + + + + + + +

    [name]

    + +

    Classe base per l'implementazione dei loader.

    + + +

    Costruttore

    + + +

    [name]( [param:LoadingManager manager] )

    +

    + [page:LoadingManager manager] — Il [page:LoadingManager loadingManager] del loader da utilizzare. Il valore predefinito è [page:LoadingManager THREE.DefaultLoadingManager]. +

    +

    + Crea un nuovo [name]. +

    + + +

    Proprietà

    + +

    [property:String crossOrigin]

    +

    + La stringa crossOrigin per implementare il CORS per caricare la url da un dominio diverso che permette il CORS. + Il valore predefinito è `anonymous`. +

    + +

    [property:Boolean withCredentials]

    +

    + Indica se XMLHttpRequest utilizza le credenziali. Vedi [page:.setWithCredentials]. + Il valore predefinito è `false`. +

    + +

    [property:LoadingManager manager]

    +

    + Il [page:LoadingManager loadingManager] utilizzato dal loader. Il valore predefinito è [page:DefaultLoadingManager]. +

    + +

    [property:String path]

    +

    + Il percorso di base da cui l'asset sarà caricato. + Il valore predefinito è una stringa vuota. +

    + +

    [property:String resourcePath]

    +

    + Il percorso di base da cui risorse addizionali come le texture saranno caricate. + Il valore predefinito è una stringa vuota. +

    + +

    [property:Object requestHeader]

    +

    + L'[link:https://developer.mozilla.org/en-US/docs/Glossary/Request_header header della richiesta] utilizzato nella richiesta HTTP. + Vedi [page:.setRequestHeader]. Il valore predefinito è un oggetto vuoto. +

    + +

    Metodi

    + +

    [method:undefined load]()

    +

    + Questo metodo deve essere implementato da tutti i loader concreti. Contiene la logica per il caricamento della risorsa dal backend. +

    + +

    [method:Promise loadAsync]( [param:String url], [param:Function onProgress] )

    +

    + [page:String url] — Una stringa contenente il percorso/URL del file che deve essere caricato.
    + [page:Function onProgress] (opzionale) — Una funzione da chiamare mentre il caricamento è in corso. L'argomento sarà l'istanza ProgressEvent, la quale contiene + .[page:Boolean lengthComputable], .[page:Integer total] e .[page:Integer loaded]. Se il server non imposta l'header Content-Length; .[page:Integer total] sarà 0.
    +

    +

    + Questo metodo è equivalente a [page:.load], ma restituisce una [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise Promise]. +

    +

    + [page:Function onLoad] è gestito da [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve Promise.resolve] + e [page:Function onError] è gestito da [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject Promise.reject]. +

    + +

    [method:undefined parse]()

    +

    + Questo metodo deve essere implementato da tutti i loader concreti. Contiene la logica per il parsing della risorsa nelle entità di three.js. +

    + +

    [method:this setCrossOrigin]( [param:String crossOrigin] )

    +

    + [page:String crossOrigin] — La stringa crossOrigin per implementare il CORS per caricare la url da un dominio diverso che permette il CORS. +

    + +

    [method:this setWithCredentials]( [param:Boolean value] )

    +

    + Indica se XMLHttpRequest utilizza le credenziali come cookie, header di autorizzazione o + certificati client TLS. Vedi [link:https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials XMLHttpRequest.withCredentials].
    + Si noti che non ha effetti se stai caricando file localmente o dallo stesso dominio. +

    + +

    [method:this setPath]( [param:String path] )

    +

    + [page:String path] — Imposta il percorso base per la risorsa. +

    + +

    [method:this setResourcePath]( [param:String resourcePath] )

    +

    + [page:String resourcePath] — Imposta il percorso base per le risorse dipendenti come le texture. +

    + +

    [method:this setRequestHeader]( [param:Object requestHeader] )

    +

    + [page:Object requestHeader] - key: Il nome dell'header il cui valore deve essere impostato; value: Il valore da impostare come corpo dell'header.

    + + Imposta l'[link:https://developer.mozilla.org/en-US/docs/Glossary/Request_header header della richiesta] utilizzato nella richiesta HTTP. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/loaders/LoaderUtils.html b/docs/api/it/loaders/LoaderUtils.html new file mode 100644 index 00000000000000..9280d9071e8b0e --- /dev/null +++ b/docs/api/it/loaders/LoaderUtils.html @@ -0,0 +1,50 @@ + + + + + + + + + +

    [name]

    + +

    Un oggetto con diverse funzioni di utilità del loader.

    + +

    Funzioni

    + +

    [method:String decodeText]( [param:TypedArray array] )

    +

    + [page:TypedArray array] — Uno stream di byte come array tipizzato. +

    +

    + La funzione prende uno stream di byte in input e restituisce una rappresentazione di stringa. +

    + +

    [method:String extractUrlBase]( [param:String url] )

    +

    + [page:String url] — La url da cui estrarre la url di base. +

    +

    + Estrae la base dalla URL. +

    + + +

    [method:String resolveURL]( [param:String url], [param:String path] )

    +

    + [page:String url] — La risoluzione dell'url assoluto o relativo.
    + [page:String path] — Il percorso base per le url relative da risolvere. +

    +

    + Risolve gli url relativi rispetto al percorso dato. Percorsi assoluti, url di dati e url di blob verranno restituiti così come sono. + Le url invalide verranno restituite come stringhe vuote. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/loaders/MaterialLoader.html b/docs/api/it/loaders/MaterialLoader.html new file mode 100644 index 00000000000000..5fb401f4f3ed58 --- /dev/null +++ b/docs/api/it/loaders/MaterialLoader.html @@ -0,0 +1,96 @@ + + + + + + + + + + [page:Loader] → + +

    [name]

    + +

    + Un loader per il caricamento di un [page:Material Materiale] in formato JSON. + Utilizza internamente il [page:FileLoader] per caricare i file. +

    + +

    Codice di Esempio

    + + + // istanzia un loader + const loader = new THREE.MaterialLoader(); + + // carica una risorsa + loader.load( + // URL della risorsa + 'path/to/material.json', + + // onLoad callback + function ( material ) { + object.material = material; + }, + + // onProgress callback + function ( xhr ) { + console.log( (xhr.loaded / xhr.total * 100) + '% loaded' ); + }, + + // onError callback + function ( err ) { + console.log( 'An error happened' ); + } + ); + + + +

    Costruttore

    + +

    [name]( [param:LoadingManager manager] )

    +

    + [page:LoadingManager manager] — Il [page:LoadingManager loadingManager] del loader da utilizzare. Il valore predefinito è [page:LoadingManager THREE.DefaultLoadingManager].

    + Crea un nuovo [name]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Loader] per le proprietà comuni.

    + +

    [property:Object textures]

    +

    Oggetto contente qualsiasi texture utilizzata dal materiale. Vedi [page:.setTextures].

    + +

    Metodi

    +

    Vedi la classe base [page:Loader] per i metodi comuni.

    + +

    [method:undefined load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    +

    + [page:String url] — Il path o URL del file. Questo può anche essere un + [link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].
    + [page:Function onLoad] — Verrà chiamato quando il caricamento sarà completato. L'argomento sarà il [page:Material Materiale] caricato.
    + [page:Function onProgress] (opzionale) — Verrà chiamato durante il caricamento. L'argomento sarà l'istanza ProgressEvent, la quale contiene + .[page:Boolean lengthComputable], .[page:Integer total] e .[page:Integer loaded]. + Se il server non imposta l'header Content-Length; .[page:Integer total] sarà 0.
    + [page:Function onError] (opzionale) — Verrà chiamato in caso di errori di caricamento.

    + + Inizia il caricamento dall'url. +

    + +

    [method:Material parse]( [param:Object json] )

    +

    + [page:Object json] — L'oggetto json contente i parametri del materiale.

    + + Parsa una struttura `JSON` e crea un nuovo [page:Material Materiale] del tipo [page:String json.type] con i parametri definiti nell'oggetto json. +

    + +

    [method:this setTextures]( [param:Object textures] )

    +

    + [page:Object textures] — oggetto contenente qualsiasi texture utilizzata dal materiale. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/loaders/ObjectLoader.html b/docs/api/it/loaders/ObjectLoader.html new file mode 100644 index 00000000000000..57ceb13f45337b --- /dev/null +++ b/docs/api/it/loaders/ObjectLoader.html @@ -0,0 +1,152 @@ + + + + + + + + + + [page:Loader] → + +

    [name]

    + +

    + Un loader per il caricamento di una risorsa JSON nel [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 formato JSON Object/Scene].

    + + Utilizza internamente il [page:FileLoader] per caricare i file. +

    + +

    Codice di Esempio

    + + + // istanzia un loader + const loader = new THREE.ObjectLoader(); + + // carica una risorsa + loader.load( + // URL della risorsa + "models/json/example.json", + + // onLoad callback + // Qui si presume che i dati caricati siano un oggetto + function ( obj ) { + // Aggiunge l'oggetto caricato alla scena + scene.add( obj ); + }, + + // onProgress callback + function ( xhr ) { + console.log( (xhr.loaded / xhr.total * 100) + '% loaded' ); + }, + + // onError callback + function ( err ) { + console.error( 'An error happened' ); + } + ); + + + // Alternativamente, per parsare una struttura JSON precedentemente caricata + const object = loader.parse( a_json_object ); + + scene.add( object ); + + +

    Esempi

    + +

    + [example:webgl_materials_lightmap WebGL / materials / lightmap] +

    + +

    Costruttore

    + +

    [name]( [param:LoadingManager manager] )

    +

    + [page:LoadingManager manager] — Il [page:LoadingManager loadingManager] del loader da utilizzare. Il valore predefinito è [page:LoadingManager THREE.DefaultLoadingManager].

    + + Crea un nuovo [name]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Loader] per le proprietà comuni.

    + +

    Metodi

    +

    Vedi la classe base [page:Loader] per i metodi comuni.

    + +

    [method:undefined load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    +

    + [page:String url] — Il path o URL del file. Questo può anche essere un + [link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].
    + [page:Function onLoad] — Verrà chiamato quando il caricamento sarà completato. L'argomento sarà l'[page:Object3D oggetto] caricato.
    + [page:Function onProgress] (opzionale) — Verrà chiamato durante il caricamento. L'argomento sarà l'istanza ProgressEvent, la quale contiene + .[page:Boolean lengthComputable], .[page:Integer total] e .[page:Integer loaded]. + Se il server non imposta l'header Content-Length; .[page:Integer total] sarà 0.
    + [page:Function onError] (opzionale) — Verrà chiamato in caso di errori di caricamento.
    +

    +

    + Inizia il caricamento dall'url e passa il contenuto della risposta parsato a onLoad. +

    + + +

    [method:Object3D parse]( [param:Object json], [param:Function onLoad] )

    +

    + [page:Object json] — obbligatorio. La sorgente JSON da parsare.

    + [page:Function onLoad] — Verrà chiamato quando il parsing sarà completato. L'argomento sarà l'[page:Object3D oggetto] parsato.

    + + Parsa una struttura `JSON` e restituisce un oggetto three.js. + Utilizzato internamente dal metodo [page:.load](), può anche essere utilizzato direttamente per parsare una struttura JSON caricata precedentemente. +

    + +

    [method:Object parseGeometries]( [param:Object json] )

    +

    + [page:Object json] — obbligatorio. La sorgente JSON da parsare.

    + + Viene utilizzato dal metodo [page:.parse]() per analizzare le [page:BufferGeometry geometrie] nella struttura JSON. +

    + +

    [method:Object parseMaterials]( [param:Object json] )

    +

    + [page:Object json] — obbligatorio. La sorgente JSON da parsare.

    + + Viene utilizzato dal metodo [page:.parse]() per analizzare i materiali nella struttura JSON utilizzando [page:MaterialLoader]. +

    + +

    [method:Object parseAnimations]( [param:Object json] )

    +

    + [page:Object json] — obbligatorio. La sorgente JSON da parsare.

    + + Viene utilizzato dal metodo [page:.parse]() per analizzare le animazioni nella struttura JSON, utilizzando [page:AnimationClip.parse](). +

    + +

    [method:Object parseImages]( [param:Object json] )

    +

    + [page:Object json] — obbligatorio. La sorgente JSON da parsare.

    + + Viene utilizzato dal metodo [page:.parse]() per analizzare le immagini nella struttura JSON, utilizzando [page:ImageLoader]. +

    + +

    [method:Object parseTextures]( [param:Object json] )

    +

    + [page:Object json] — obbligatorio. La sorgente JSON da parsare.

    + + Viene utilizzato dal metodo [page:.parse]() per analizzare le texture nella struttura JSON. +

    + +

    [method:Object3D parseObject]( [param:Object json], [param:BufferGeometry geometries], [param:Material materials], [param:AnimationClip animations] )

    +

    + [page:Object json] — obbligatorio. La sorgente JSON da parsare.
    + [page:BufferGeometry geometries] — obbligatorio. Le geometrie del JSON.
    + [page:Material materials] — obbligatorio. I materiali del JSON.
    + [page:AnimationClip animations] — obbligatorio. Le animazioni del JSON.

    + + Viene utilizzato dal metodo [page:.parse]() per analizzare gli oggetti 3D nella struttura JSON. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/loaders/TextureLoader.html b/docs/api/it/loaders/TextureLoader.html new file mode 100644 index 00000000000000..bce3b5e36cd929 --- /dev/null +++ b/docs/api/it/loaders/TextureLoader.html @@ -0,0 +1,103 @@ + + + + + + + + + + [page:Loader] → + +

    [name]

    + +

    + Una classe per il caricamento di una [page:Texture texture]. + Utilizza internamente l'[page:ImageLoader] per caricare i file. +

    + +

    Codice di Esempio

    + + + const texture = new THREE.TextureLoader().load( 'textures/land_ocean_ice_cloud_2048.jpg' ); + + // utilizza immediatamente la texture per la creazione del materiale + const material = new THREE.MeshBasicMaterial( { map: texture } ); + + +

    Codice di Esempio con le Callback

    + + + // istanzia un loader + const loader = new THREE.TextureLoader(); + + // carica una risorsa + loader.load( + // URL della risorsa + 'textures/land_ocean_ice_cloud_2048.jpg', + + // onLoad callback + function ( texture ) { + // nell'esempio viene creato il materiale quando la texture è caricata + const material = new THREE.MeshBasicMaterial( { + map: texture + } ); + }, + + // la callback onProgress al momento non è supportata + undefined, + + // onError callback + function ( err ) { + console.error( 'An error happened.' ); + } + ); + + +

    + Si noti che la versione r84 di three.js ha eliminato il supporto per gli eventi di avanzamento di TextureLoader. + Per un TextureLoader che supporti gli eventi di avanzamento, vedi [link:https://github.com/mrdoob/three.js/issues/10439#issuecomment-293260145 questo thread]. +

    + +

    Esempi

    + +

    + [example:webgl_geometry_cube geometry / cube] +

    + +

    Costruttore

    + +

    [name]( [param:LoadingManager manager] )

    +

    + [page:LoadingManager manager] — Il [page:LoadingManager loadingManager] del loader da utilizzare. Il valore predefinito è [page:LoadingManager THREE.DefaultLoadingManager].

    + + Crea un nuovo [name]. +

    + + +

    Proprietà

    +

    Vedi la classe base [page:Loader] per le proprietà comuni.

    + +

    Metodi

    +

    Vedi la classe base [page:Loader] per i metodi comuni.

    + +

    [method:Texture load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    +

    + [page:String url] — Il path o URL del file. Questo può anche essere un + [link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].
    + [page:Function onLoad] (opzionale) — Verrà chiamato quando il caricamento sarà completato. L'argomento sarà la [page:Texture texture] caricata.
    + [page:Function onProgress] (opzionale) — Questa callback al momento non è supportata.
    + [page:Function onError] (opzionale) — Verrà chiamato in caso di errori di caricamento.

    + + Inizia il caricamento dall'url e passa la [page:Texture texture] completamente caricata al metodo onLoad. + Il metodo, inoltre, restituisce un nuovo oggetto texture che può essere direttamente utilizzato per la creazione del materiale. + Se lo fai in questo modo, la texture potrebbe apparire nella scena una volta che il processo di caricamento è terminato. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/loaders/managers/DefaultLoadingManager.html b/docs/api/it/loaders/managers/DefaultLoadingManager.html new file mode 100644 index 00000000000000..eaed7d59fbbf9e --- /dev/null +++ b/docs/api/it/loaders/managers/DefaultLoadingManager.html @@ -0,0 +1,71 @@ + + + + + + + + + +

    [name]

    + +

    + Un'istanza globale del [page:LoadingManager LoadingManager], utilizzata dalla maggior parte dei loader + quando nessun manager personalizzato viene specificato.

    + + Questo sarà sufficiente per la maggior parte degli scopi, tuttavia ci possono essere momenti in cui + si desiderano manager di caricamento separati per, ad esempio, texture e modelli. +

    + +

    Codice di Esempio

    + +

    + È possibile impostare facoltativamente le funzioni [page:LoadingManager.onStart onStart], [page:LoadingManager.onLoad onLoad], + [page:LoadingManager.onProgress onProgress], [page:LoadingManager.onStart onError] per il manager. Questi verranno applicati + a tutti i loader che utilizzano DefaultLoadingManager.

    + + Si noti che questi metodi non devono essere confusi con le funzioni con nomi simili dei singoli loader, + poiché sono intese per visulizzare le informazioni sullo stato generale del caricamento, + piuttosto che gestire i dati che sono stati caricati. +

    + +THREE.DefaultLoadingManager.onStart = function ( url, itemsLoaded, itemsTotal ) { + + console.log( 'Started loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.' ); + +}; + +THREE.DefaultLoadingManager.onLoad = function ( ) { + + console.log( 'Loading Complete!'); + +}; + + +THREE.DefaultLoadingManager.onProgress = function ( url, itemsLoaded, itemsTotal ) { + + console.log( 'Loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.' ); + +}; + +THREE.DefaultLoadingManager.onError = function ( url ) { + + console.log( 'There was an error loading ' + url ); + +}; + + + +

    Proprietà

    +

    Vedi la pagina [page:LoadingManager LoadingManager] per i dettagli delle proprietà.

    + +

    Metodi

    +

    Vedi la pagina [page:LoadingManager LoadingManager] per i dettagli dei metodi.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/loaders/LoadingManager.js src/loaders/LoadingManager.js] +

    + + diff --git a/docs/api/it/loaders/managers/LoadingManager.html b/docs/api/it/loaders/managers/LoadingManager.html new file mode 100644 index 00000000000000..0f750dd83382d3 --- /dev/null +++ b/docs/api/it/loaders/managers/LoadingManager.html @@ -0,0 +1,240 @@ + + + + + + + + + +

    [name]

    + +

    + Gestisce e tiene traccia dei dati caricati e pendenti. Un'istanza globale predefinita di questa classe + viene creata e utilizzata dai loader, se non viene fornita manualmente - vedi [page:DefaultLoadingManager].

    + + In generale questo dovrebbe essere sufficiente, tuttavia ci sono volte in cui è utile che i loader siano separti - + per esempio se si vuole mostrare barre di caricamento separate per gli oggetti e le texture. +

    + +

    Codice di Esempio

    + +

    + Questo esempio mostra come utilizzare il LoadingManager per tracciare i progressi + dell'[page:OBJLoader]. +

    + + + const manager = new THREE.LoadingManager(); + manager.onStart = function ( url, itemsLoaded, itemsTotal ) { + + console.log( 'Started loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.' ); + + }; + + manager.onLoad = function ( ) { + + console.log( 'Loading complete!'); + + }; + + + manager.onProgress = function ( url, itemsLoaded, itemsTotal ) { + + console.log( 'Loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.' ); + + }; + + manager.onError = function ( url ) { + + console.log( 'There was an error loading ' + url ); + + }; + + const loader = new THREE.OBJLoader( manager ); + loader.load( 'file.obj', function ( object ) { + + // + + } ); + + +

    + Oltre ad osservare i progressi, un LoadingManager può essere utilizzato + per sovrascrivere le URL della risorsa durante il caricamento. Questo può + essere utile per le risorse che derivano dagli eventi di drag-and-drop, + WebSockets, WebRTC, o altre API. L'esempio qui sotto mostra come caricare un modello + in memoria utilizzando le URL del Blob. +

    + + + // Oggetti Blob o File creati quando i file vengono trascinati nella pagina web + const blobs = {'fish.gltf': blob1, 'diffuse.png': blob2, 'normal.png': blob3}; + + const manager = new THREE.LoadingManager(); + + // Inizializza il manager di caricamento con la callback della URL + const objectURLs = []; + manager.setURLModifier( ( url ) => { + + url = URL.createObjectURL( blobs[ url ] ); + + objectURLs.push( url ); + + return url; + + } ); + + // Carica come di solito, quindi revoca gli URL dei Blob + const loader = new THREE.GLTFLoader( manager ); + loader.load( 'fish.gltf', (gltf) => { + + scene.add( gltf.scene ); + + objectURLs.forEach( ( url ) => URL.revokeObjectURL( url ) ); + + }); + + +

    Esempi

    + +

    + [example:webgl_loader_obj WebGL / loader / obj]
    + [example:webgl_materials_physical_reflectivity WebGL / materials / physical / reflectivity]
    + [example:webgl_postprocessing_outline WebGL / postprocesing / outline] +

    + +

    Costruttore

    + +

    [name]( [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    +

    + [page:Function onLoad] — (opzionale) Questa funzione sarà chiamata quando tutti i caricamenti saranno terminati.
    + [page:Function onProgress] — (opzionale) Questa funzione sarà chiamata quando un elemento è completato.
    + [page:Function onError] — (opzionale) Questa funzione sarà chiamata quando un loader incontra degli errori.

    + + Crea un nuovo [name]. +

    + + +

    Proprietà

    + +

    [property:Function onStart]

    +

    + Questa funzione verrà chiamata all'avvio del caricamento. + Gli argomenti sono:
    + [page:String url] — La url dell'elemento appena caricato.
    + [page:Integer itemsLoaded] — Il numero di elementi già caricati finora.
    + [page:Integer itemsTotal] — La quantità totale di elementi da caricare.

    + + Il valore predefinito è `undefined`. +

    + +

    [property:Function onLoad]

    +

    + Questa funzione sarà chiamata quando tutti i caricamenti saranno terminati. Il valore predefinito è `undefined` + a meno che non venga passata nel costruttore. +

    + +

    [property:Function onProgress]

    +

    + Questa funzione sarà chiamata quando un elemento è completato. + Gli argomenti sono:
    + [page:String url] — La url dell'elemento appena caricato.
    + [page:Integer itemsLoaded] — Il numero di elementi già caricati finora.
    + [page:Integer itemsTotal] — La quantità totale di elementi da caricare.

    + + Il valore predefinito è `undefined` a meno che non venga passata nel costruttore. +

    + +

    [property:Function onError]

    +

    + Questa funzione sarà chiamata quando un loader incontra degli errori, con l'argomento:
    + [page:String url] — La url dell'elemento andato in errore.

    + + Il valore predefinito è `undefined` a meno che non venga passata nel costruttore. +

    + + +

    Metodi

    + +

    [method:this addHandler]( [param:Object regex], [param:Loader loader] )

    +

    + [page:Object regex] — Un'espressione regolare.
    + [page:Loader loader] — Il loader. +

    + Registra un loader con l'espressione regolare passata. Può essere utilizzato per definire quale loader + deve essere utilizzato per caricare file specifici. Un caso d'uso tipico è sovrascrivere il loader + predefinito per le texture. +

    + +// aggiunge un handler per le texture TGA +manager.addHandler( /\.tga$/i, new TGALoader() ); + + +

    [method:Loader getHandler]( [param:String file] )

    +

    + [page:String file] — Il percorso del file. +

    + Può essere utilizzato per recuperare il loader registrato per il dato percorso del file. +

    + +

    [method:this removeHandler]( [param:Object regex] )

    +

    + [page:Object regex] — Un'espressione regolare. +

    + Rimuove il loader per l'espressione regolare passata. +

    + +

    [method:String resolveURL]( [param:String url] )

    +

    + [page:String url] — La url da caricare.

    + + Data una URL, utilizza la callback del modificatore di URL (se presente) e restituisce + un URL risolto. Se non è impostato alcun modificatore di URL, restituisce l'URL originale. +

    + +

    [method:this setURLModifier]( [param:Function callback] )

    +

    + [page:Function callback] — La callback del modificatore di URL. Chiamata con l'argomento [page:String url], e + deve restituisce una [page:String resolvedURL].

    + + Se fornito, la callback verrà passata ad ogni risorsa URL prima che la richiesta venga inviata. + La callback deve restituire la URL originale, o una nuova URL per sovrascrivere il comportamento del caricamento. + Questo comportamento può essere utilizzato per caricare le risorse dai file .ZIP, dalle API di drag-and-drop e dai Data URI. +

    + +
    + +

    + Nota: I metodi seguenti sono progettati per essere chiamati internamente dai loader. Non possono essere + chiamati direttamente. +

    + +

    [method:undefined itemStart]( [param:String url] )

    +

    + [page:String url] — La url da caricare.

    + + Questo metodo dovrebbe essere chiamato da qualsiasi loader che utilizza il manager quando il loader inizia a caricare una url. +

    + +

    [method:undefined itemEnd]( [param:String url] )

    +

    + [page:String url] — La url caricata.

    + + Questo metodo dovrebbe essere chiamato da qualsiasi loader che utilizza il manager quando il loader finisce di caricare una url. +

    + +

    [method:undefined itemError]( [param:String url] )

    +

    + [page:String url] — La url caricata.

    + + Questo metodo dovrebbe essere chiamato da qualsiasi loader che utilizza il manager quando il loader va in errore caricando una url. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/loaders/LoadingManager.js src/loaders/LoadingManager.js] +

    + + diff --git a/docs/api/it/materials/LineBasicMaterial.html b/docs/api/it/materials/LineBasicMaterial.html new file mode 100644 index 00000000000000..89e18a9932d776 --- /dev/null +++ b/docs/api/it/materials/LineBasicMaterial.html @@ -0,0 +1,102 @@ + + + + + + + + + + [page:Material] → + +

    [name]

    + +

    Un materiale per disegnare geometrie in stile wireframe.

    + +

    Codice di Esempio

    + + + const material = new THREE.LineBasicMaterial( { + color: 0xffffff, + linewidth: 1, + linecap: 'round', // ignorato da WebGLRenderer + linejoin: 'round' // ignorato da WebGLRenderer + } ); + + +

    Esempi

    + +

    + [example:webgl_buffergeometry_drawrange WebGL / buffergeometry / drawrange]
    + [example:webgl_buffergeometry_lines WebGL / buffergeometry / lines]
    + [example:webgl_buffergeometry_lines_indexed WebGL / buffergeometry / lines / indexed]
    + [example:webgl_decals WebGL / decals]
    + [example:webgl_geometry_nurbs WebGL / geometry / nurbs]
    + [example:webgl_geometry_shapes WebGL / geometry / shapes]
    + [example:webgl_geometry_spline_editor WebGL / geometry / spline / editor]
    + [example:webgl_interactive_buffergeometry WebGL / interactive / buffergeometry]
    + [example:webgl_interactive_voxelpainter WebGL / interactive / voxelpainter]
    + [example:webgl_lines_colors WebGL / lines / colors]
    + [example:webgl_lines_dashed WebGL / lines / dashed]
    + [example:webgl_lines_sphere WebGL / lines / sphere]
    + [example:webgl_materials WebGL / materials]
    + [example:physics_ammo_rope physics / ammo / rope] +

    + +

    Costruttore

    + +

    [name]( [param:Object parameters] )

    + +

    + [page:Object parameters] - (opzionale) un oggetto con una o più proprietà che definiscono l'aspetto del materiale. + Qualsiasi proprietà del materiale (inclusa qualsiasi proprietà ereditata dal [page:Material Materiale]) può essere passata qui.

    + + L'eccezione è la proprietà [page:Hexadecimal color], che può essere passata come una stringa esadecimale ed il suo valore predefinito è `0xffffff` (bianco). + Il metodo [page:Color.set]( color ) è chiamato internamente. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Material] per le proprietà comuni.

    + +

    [property:Color color]

    +

    [page:Color Colore] del materiale, da impostazione predefinita impostato a bianco (0xffffff).

    + +

    [property:Boolean fog]

    +

    Indica se il materiale è influenzato dalla nebbia. Il valore predefinito è `true`.

    + +

    [property:Float linewidth]

    +

    + Controlla lo spessore della linea. Il valore predefinito è `1`.

    + + A causa delle limitazioni del [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf profilo OpenGL Core] + con il renderer [page:WebGLRenderer WebGL] sulla maggior parte delle piattaforme, la larghezza della linea sarà sempre 1 + indipendentemente dal valore impostato. +

    + +

    [property:String linecap]

    +

    + Definisce l'aspetto della fine della linea. I valori possibili sono 'butt', 'round' e 'square'. + Il valore predefinito è 'round'.

    + + Questa corrisponde alla proprietà [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineCap 2D Canvas lineCap] + e viene ignorata dal renderer [page:WebGLRenderer WebGL]. +

    + +

    [property:String linejoin]

    +

    + Definisce l'aspetto dei punti di unione della linea. I valori possibili sono 'round', 'bevel' e 'miter'. Il valore predefinito è 'round'.

    + + Questa corrisponde alla proprietà [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineCap 2D Canvas lineCap] + e viene ignorata dal renderer [page:WebGLRenderer WebGL]. +

    + +

    Metodi

    +

    Vedi la classe base [page:Material] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/materials/LineDashedMaterial.html b/docs/api/it/materials/LineDashedMaterial.html new file mode 100644 index 00000000000000..5cf26ee88bac76 --- /dev/null +++ b/docs/api/it/materials/LineDashedMaterial.html @@ -0,0 +1,70 @@ + + + + + + + + + + [page:Material] → [page:LineBasicMaterial] → + +

    [name]

    + +

    Un materiale per disegnare geometrie in stile wireframe con linee tratteggiate.

    + +

    Codice di Esempio

    + + + const material = new THREE.LineDashedMaterial( { + color: 0xffffff, + linewidth: 1, + scale: 1, + dashSize: 3, + gapSize: 1, + } ); + + +

    Esempi

    + +

    + [example:webgl_lines_dashed WebGL / lines / dashed]
    +

    + +

    Costruttore

    + + +

    [name]( [param:Object parameters] )

    +

    + [page:Object parameters] - (opzionale) un oggetto con una o più proprietà che definiscono l'aspetto del materiale. + Qualsiasi proprietà del materiale (inclusa qualsiasi proprietà ereditata da [page:LineBasicMaterial LineBasicMaterial]) può essere passata qui. +

    + +

    Proprietà

    +

    Vedi la classe base [page:LineBasicMaterial] per le proprietà comuni.

    + +

    [property:number dashSize]

    +

    La dimensione del trattino. Si tratta sia dello spazio che del tratto. Il valore predefinito è `3`.

    + +

    [property:number gapSize]

    +

    La dimensione dello spazio tra i trattini. Il valore predefinito è `1`.

    + +

    [property:Boolean isLineDashedMaterial]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + + +

    [property:number scale]

    +

    La scala della parte tratteggiata di una linea. Il valore predefinito è `1`.

    + +

    Metodi

    +

    Vedi la classe base [page:LineBasicMaterial] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/materials/Material.html b/docs/api/it/materials/Material.html new file mode 100644 index 00000000000000..3215a79edfbe4d --- /dev/null +++ b/docs/api/it/materials/Material.html @@ -0,0 +1,409 @@ + + + + + + + + + +

    [name]

    + +

    + Classe base astratta per i materiali.

    + + I materiali descrivono l'aspetto degli [page:Object oggetti]. + Sono definiti in modo (spesso) indipendente dal renderer, quindi non devi + riscrivere i materiali se decidi di usare un renderer diverso.

    + + Le proprietà e i metodi seguenti vengono ereditati da tutti gli altri tipi di materiale + (sebbene possano avere impostazioni predefinite diverse). +

    + +

    Costruttore

    + + +

    [name]()

    +

    Questo crea un materiale generico.

    + + +

    Proprietà

    + +

    [property:Float alphaTest]

    +

    + Imposta il valore alfa per essere usato quando vengono eseguiti i test alfa. + Il materiale non sarà renderizzato se l'opacità è inferiore a questo valore. + Il valore predefinito è `0`. +

    + +

    [property:Boolean alphaToCoverage]

    +

    + Abilita l'alfa alla copertura. Può essere utilizzato solo con contesti abilitati per MSAA (ovvero quando il renderer è stato creato con + il parametro `antialias` impostato a `true`). + Il valore predefinito è `false`. +

    + +

    [property:Integer blendDst]

    +

    + Destinazione di fusione. Il valore predefinito è [page:CustomBlendingEquation OneMinusSrcAlphaFactor]. + Vedi le [page:CustomBlendingEquation costanti] dei fattori di destinazione per tutti i valori possibili.
    + La [page:Constant fusione] del materiale deve essere impostata a [page:Materials CustomBlending] affinché + ciò abbia effetto. +

    + +

    [property:Integer blendDstAlpha]

    +

    La trasparenza del [page:.blendDst]. Usa [page:.blendDst] se il valore è null. Il valore predefinito è `null`.

    + +

    [property:Integer blendEquation]

    +

    + Equazione di fusione da utilizzare quando si applica la fusione. Il valore predefinito è [page:CustomBlendingEquation AddEquation]. + Vedi le [page:CustomBlendingEquation costanti] dell'equazione di fusione per tutti i valori possibili.
    + La [page:Constant fusione] del materiale deve essere impostata a [page:Materials CustomBlending] affinché + ciò abbia effetto. +

    + +

    [property:Integer blendEquationAlpha]

    +

    La trasparenza del [page:.blendEquation]. Usa [page:.blendEquation] se il valore è null. Il valore predefinito è `null`.

    + +

    [property:Blending blending]

    +

    + Indica quale fusione utilizzare quando gli oggetti vengono mostrati con questo materiale.
    + Questa proprietà deve essere impostata a [page:Materials CustomBlending] per usare + [page:Constant blendSrc], [page:Constant blendDst] o [page:Constant blendEquation] personalizzati.
    + Vedi le [page:Materials costanti] del metodo di fusione per tutti i valori possibili. Il valore predefinito è [page:Materials NormalBlending]. +

    + +

    [property:Integer blendSrc]

    +

    + Sorgente di fusione. Il valore predefinito è [page:CustomBlendingEquation SrcAlphaFactor]. + Vedi le [page:CustomBlendingEquation costanti] dei fattori della sorgente per tutti i valori possibili.
    + La [page:Constant fusione] del materiale deve essere impostata a [page:Materials CustomBlending] affinché ciò abbia effetto. +

    + +

    [property:Integer blendSrcAlpha]

    +

    La trasparenza del [page:.blendSrc]. Usa [page:.blendSrc] se il valore è null. Il valore predefinito è `null`.

    + +

    [property:Boolean clipIntersection]

    +

    + Modifica il comportamento dei piani di taglio così che solo la loro intersezione sia ritagliata, piuttosto che la loro unione. + Il valore predefinito è `false`. +

    + +

    [property:Array clippingPlanes]

    +

    + Piani di taglio definiti dall'utente e specificati come ogetti THREE.Plane nello spazio world. + Questi piani si applicano agli oggetti ai quali è attaccato questo materiale. + I punti nello spazio la cui distanza con segno dal piano è negativa vengono ritagliati (non renderizzati). + Questo richiede che [page:WebGLRenderer.localClippingEnabled] sia impostato a `true`. + Vedi l'esempio [example:webgl_clipping_intersection WebGL / clipping /intersection]. + Il valore predefinito è `null`. +

    + +

    [property:Boolean clipShadows]

    +

    + Definisce se ritagliare le ombre in base ai piani di ritaglio specificati su questo materiale. L'impostazione predefinita è `false`. +

    + +

    [property:Boolean colorWrite]

    +

    + Indica se visualizzare il colore del materiale. + Può essere utilizzato insieme alla proprietà [page:Integer renderOrder] di una mesh per creare oggetti invisibili che occludono altri oggetti. + Il valore predefinito è `true`. +

    + +

    [property:Object defines]

    +

    + Definizioni personalizzate da iniettare nello shader. Questi vengono passati nella forma di un oggetto letterale, + con la coppia chiave/valore. `{ MY_CUSTOM_DEFINE: '' , PI2: Math.PI * 2 }`. + Le coppie sono definite in entrambi gli shader, vertex e fragment. Il valore predefinito è `undefined`. +

    + +

    [property:Integer depthFunc]

    +

    + Indica quale funzione di profondità utilizzare. Il valore predefinito è [page:Materials LessEqualDepth]. Vedi + le [page:Materials costanti] del metodo di profondità per tutti i valori possibili. +

    + +

    [property:Boolean depthTest]

    +

    + Indica se abilitare il test di profondità durante la visualizzazione di questo materiale. Il valore predefinito è `true`. +

    + +

    [property:Boolean depthWrite]

    +

    + Indica se il rendering di questo materiale ha qualche effetto sul buffer di profondità. Il valore predefinito è `true`.

    + + Quando si disegnano sovrapposizioni 2D può essere utile disabilitare la scrittura di profondità per sovrapporre più + cose insieme senza creare artefatti z.index. +

    + +

    [property:Boolean isMaterial]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:Boolean stencilWrite]

    +

    + Indica se le operazioni di stencil vengono eseguite sul buffer di stencil. Per seguire scritture o confronti con il buffer dello stencil, + questo valore deve essere `true`. Il valore predefinito è `false`. +

    + +

    [property:Integer stencilWriteMask]

    +

    + La maschera bit da utilizzare durante la scrittura nel buffer dello stencil. Il valore predefinito è `0xFF`. +

    + +

    [property:Integer stencilFunc]

    +

    + La funzione di confronto dello stencil da utilizzare. + Il valore predefinito è [page:Materials AlwaysStencilFunc]. + Vedi le [page:Materials costanti] della funzione stencil per tutti i possibili valori. +

    + +

    [property:Integer stencilRef]

    +

    + Il valore da utilizzare quando si eseguono confronti di stencil o operazioni di stencil. Il valore predefinito è `0`. +

    + +

    [property:Integer stencilFuncMask]

    +

    + La maschera bit da utilizzare durante il confronto con il buffer dello stencil. Il valore predefinito è `0xFF`. +

    + +

    [property:Integer stencilFail]

    +

    + Quale operazione stencil eseguire quando la funzione di confronto ritorna false. + Il valore predefinito è [page:Materials KeepStencilOp]. Vedi le [page:Materials costanti] delle operazioni stencil per tutti i possbili valori. +

    + +

    [property:Integer stencilZFail]

    +

    + Quale operazione stencil eseguire quando la funzione di confronto ritorna true ma il test di profondità fallisce. + Il valore predefinito è [page:Materials KeepStencilOp]. Vedi le [page:Materials costanti] delle operazioni stencil per tutti i possbili valori. +

    + +

    [property:Integer stencilZPass]

    +

    + Quale operazione stencil eseguire quando la funzione di confronto ritorna true ma il test di profondità termina con successo. + Il valore predefinito è [page:Materials KeepStencilOp]. Vedi le [page:Materials costanti] delle operazioni stencil per tutti i possbili valori. +

    + +

    [property:Integer id]

    +

    Numero univoco per questa istanza di materiale.

    + +

    [property:String name]

    +

    Nome opzionale dell'oggetto (non è necessario che sia univoco). Il valore predefinito è una stringa vuota.

    + +

    [property:Boolean needsUpdate]

    +

    + Specifica che il materiale ha bisogno di essere ricompilato. +

    + +

    [property:Float opacity]

    +

    + Float nell'intervallo `0.0` - `1.0` indicando quanto è trasparente il materiale. + Un valore di `0.0` indica che il materiale è completamente trasparente, `1.0` è completamente opaco.
    + Se la proprietà [page:Boolean transparent] del materiale non è impostato a `true`, il materiale rimarrà + completamente opaco e questo valore influirà solo sul suo colore.
    + Il valore predefinito è `1.0`. +

    + +

    [property:Boolean polygonOffset]

    +

    + Indica se utilizzare l'offset dei poligoni. Il valore predefinito è `false`. Corrisponde alla funzione WebGL `GL_POLYGON_OFFSET_FILL`. +

    + +

    [property:Integer polygonOffsetFactor]

    +

    Imposta il fattore di offset del poligono. Il valore predefinito è `0`.

    + +

    [property:Integer polygonOffsetUnits]

    +

    Imposta le unità di offset del poligono. Il valore predefinito è `0`.

    + +

    [property:String precision]

    +

    + Sovrascrive la precisione predefinita del renderer per questo materiale. Può essere `"highp"`, `"mediump"` or `"lowp"`. + Il valore predefinito è `null`. +

    + +

    [property:Boolean premultipliedAlpha]

    +

    + Indica se moltiplicare il valore alfa (trasparenza). + Vedi [Example:webgl_materials_physical_transmission WebGL / Materials / Physical / Transmission] per un esempio della differenza. + Il valore predefinito è `false`. +

    + +

    [property:Boolean dithering]

    +

    + Indica se applicare il dithering al colore per rimuovere l'aspetto delle bande. + Il valore predefinito è `false`. +

    + +

    [property:Integer shadowSide]

    +

    + Definisce quale lato delle facce proietta le ombre. + Quando impostato, può essere [page:Materials THREE.FrontSide], [page:Materials THREE.BackSide], o [page:Materials THREE.DoubleSide]. + Il valore predefinito è `null`.
    + Se `null`, le ombre di proiezione lateriali sono determinate come segue:
    + + + + + + + + + + + + + + + + + + + + + + + +
    [page:Material.side]Ombre proiettate lateralmente
    THREE.FrontSidelato posteriore
    THREE.BackSidelato frontale
    THREE.DoubleSideentrambi i lati
    + + +

    + +

    [property:Integer side]

    +

    + Definisce quale lato delle facce sarà visualizzato - frontale, posteriore o entrambi. + Il valore predefinito è [page:Materials THREE.FrontSide]. + Altre opzioni sono [page:Materials THREE.BackSide] e [page:Materials THREE.DoubleSide]. +

    + +

    [property:Boolean toneMapped]

    +

    + Definisce se questo materiale è mappato sui toni secondo l'impostazione [page:WebGLRenderer.toneMapping toneMapping] del renderer. + L'impostazione predefinita è `true`. +

    + +

    [property:Boolean transparent]

    +

    + Definisce se questo materiale è trasparente. Ciò a effetto sul rendering + poiché gli oggetti trasparenti richiedono un trattamento speciale e vengono + visualizzati dopo gli oggetti non trasparenti.
    + Quando impostato a true, la misura in cui il materiale è trasparente è controllata impostando + la sua proprietà di [page:Float opacity].
    + Il valore predefinito è `false`. +

    + +

    [property:String type]

    +

    + Il valore è la stringa 'Material'. Non può essere cambiato, e può essere utilizzato + per trovare tutti gli oggetti di questo tipo nella scena. +

    + +

    [property:String uuid]

    +

    + [link:http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] di questa istanza di materiale. + Questo viene assegnato automaticamente, quindi non dovrebbe essere modificato. +

    + +

    [property:Integer version]

    +

    + Parte da `0` e conta quante volte [page:Material.needsUpdate .needsUpdate] è impostato a `true`. +

    + +

    [property:Boolean vertexColors]

    +

    + Definisce se viene utilizzata la colorazione dei vertici. Il valore predefinito è `false`. +

    + +

    [property:Boolean visible]

    +

    + Definisce se questo materiale è visibile. Il valore predefinito è `true`. +

    + +

    [property:Object userData]

    +

    + Un oggetto che può essere utilizzato per memorizzare dati personalizzati sul materiale. Non dovrebbe + contenere riferimenti a funzioni poiché queste non verranno clonate. +

    + +

    Metodi

    + +

    I metodi [page:EventDispatcher EventDispatcher] sono disponibili in questa classe.

    + +

    [method:Material clone]( )

    +

    Restituisce un nuovo materiale con gli stessi parametri di questo materiale.

    + +

    [method:this copy]( [param:material material] )

    +

    Copia i parametri dal materiale passato in questo materiale.

    + +

    [method:undefined dispose]()

    +

    + Libera le risorse relative alla GPU allocate da questa istanza. + Chiama questo metodo ogni volta che questa istanza non è più utilizzata nella tua app.

    + + Le texture del materiale devono essere liberate dal metodo dispose() della [page:Texture Texture]. +

    + +

    [method:undefined onBeforeCompile]( [param:Shader shader], [param:WebGLRenderer renderer] )

    +

    + Una callback opzionale che viene eseguita immediatamente prima che il programma shader sia compilato. + Questa funzione viene chiamata con il codice sorgente dello shader come parametro. + Utile per la modifica di materiali build-in. +

    +

    + A differenza delle proprietà, la callback non è supportata da [page:Material.clone .clone](), [page:Material.copy .copy]() e [page:Material.toJSON .toJSON](). +

    + +

    [method:String customProgramCacheKey]()

    +

    + Nel caso in cui onBeforeCompile sia utilizzato, questa callback può essere utilizzata per identificare i valori delle impostazioni utilizzati + nel onBeforeCompile, quindi three.js può riutilizzare uno shader memorizzato nella cache o ricompilare lo shader per questo materiale secondo + necessità. +

    + +

    + Per esempio, se onBeforeCompile contiene un'istruzione condizionale come:
    + + if ( black ) { + + shader.fragmentShader = shader.fragmentShader.replace('gl_FragColor = vec4(1)', 'gl_FragColor = vec4(0)') + + } + + + allora customProgramCacheKey deve essere impostato come questo:
    + + material.customProgramCacheKey = function() { + + return black ? '1' : '0'; + + } + + +

    + +

    + A differenza delle proprietà, la callback non è supportata da [page:Material.clone .clone](), [page:Material.copy .copy]() e [page:Material.toJSON .toJSON](). +

    + +

    [method:undefined setValues]( [param:Object values] )

    +

    + values -- un contenitore con i parametri.
    + Imposta le proprietà in base ai `values`. +

    + +

    [method:Object toJSON]( [param:Object meta] )

    +

    + meta -- oggetto contenente metadati come texture o immagini per il materiale.
    + Converte il materiale nel [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 formato JSON Object/Scene] di three.js. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/materials/MeshBasicMaterial.html b/docs/api/it/materials/MeshBasicMaterial.html new file mode 100644 index 00000000000000..3cf256b127b62d --- /dev/null +++ b/docs/api/it/materials/MeshBasicMaterial.html @@ -0,0 +1,155 @@ + + + + + + + + + + [page:Material] → + +

    [name]

    + +

    + Un materiale per disegnare geometrie in un modo semplice e ombreggiato (piatto o wireframe).

    + + Questo materiale non è influenzato dalle luci. +

    + + + + + + +

    Costruttore

    + +

    [name]( [param:Object parameters] )

    +

    + [page:Object parameters] - (opzionale) un oggetto con una o più proprietà che definiscono l'aspetto del materiale. + Qualsiasi proprietà del materiale (inclusa qualsiasi proprietà ereditata da [page:Material]) può essere passata qui.

    + + La proprietà [page:Hexadecimal color] è un'eccezione, che può essere passata come una stringa esadecimale con valore predefinito + `0xffffff` (bianco). [page:Color.set]( color ) viene chiamato internamente. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Material] per le proprietà comuni.

    + +

    [property:Texture alphaMap]

    +

    La mappa alfa è una texture in scala di grigi che controlla l'opacità sulla superficie + (nero: completamente trasparente; bianco: completamente opaco). Il valore predefinito è `null`.

    + + Solo il colore della texture è utilizzato, ignorando il canale alfa, se questo esiste. + Per le texture RGB e RGBA, il renderer [page:WebGLRenderer WebGL] utilizzarà il canale + verde durante il campionamento di questa texture a causa del bit extra di precisione fornito + per il verde nei formati RGB 565 compressi e non compressi DXT. Anche le texture solo luminanza e + luminanza/alfa continueranno a funzionare come previsto. +

    + +

    [property:Texture aoMap]

    +

    Il canale rosso di questa texture viene utilizzato come mappa di occlusione ambientale. + Il valore predefinito è `null`. The aoMap richiede un secondo set di UV.

    + +

    [property:Float aoMapIntensity]

    +

    Intensità dell'effetto di occlusione ambientale. Il valore predefinito è `1`. Zero non è un effetto di occlusione.

    + +

    [property:Color color]

    +

    [page:Color Colore] del materiale, da impostazione predefinita impostato a bianco (0xffffff).

    + +

    [property:Integer combine]

    +

    + Come combinare il risultato del colore della superficie con l'eventuale mappa ambientale.

    + + Le opzioni sono [page:Materials THREE.MultiplyOperation] (predefinita), [page:Materials THREE.MixOperation], + [page:Materials THREE.AddOperation]. Se viene scelto MixOperation, la riflettività viene utilizzata per sfumare tra + i due colori. +

    + +

    [property:Texture envMap]

    +

    La mappa ambientale. Il valore predefinito è `null`.

    + +

    [property:Boolean fog]

    +

    Indica se il materiale è influenzato dalla nebbia. Il valore predefinito è `true`.

    + +

    [property:Texture lightMap]

    +

    La mappa della luce. Il valore predefinito è `null`. La lightMap richiede un secondo set di UV.

    + +

    [property:Float lightMapIntensity]

    +

    Intensità della luce. Il valore predefinito è `1`.

    + +

    [property:Texture map]

    +

    + La mappa del colore. Può includere facoltativamente un canale alfa, tipicamente combinato con + [page:Material.transparent .transparent] o [page:Material.alphaTest .alphaTest]. Il valore predefinito è `null`. +

    + +

    [property:Float reflectivity]

    +

    + Quanto la mappa ambientale influenza la superficie; vedi anche [page:.combine]. + Il valore predefinito è 1 e l'intervallo valido è tra 0 (senza riflessi) e 1 (riflessione completa). +

    + +

    [property:Float refractionRatio]

    +

    + L'indice di rifrazione (IOR) dell'aria (approssimativamente 1) diviso per l'indice di rifrazione del materiale. + Viene utilizzato con il metodo di mappatura ambientale + [page:Textures THREE.CubeRefractionMapping] e [page:Textures THREE.EquirectangularRefractionMapping]. + Il raggio di rifrazione non deve superare 1. Il valore predefinito è `0.98`. +

    + +

    [property:Texture specularMap]

    +

    Mappa speculare utilizzata dal materiale. Il valore predefinito è `null`.

    + +

    [property:Boolean wireframe]

    +

    Rendering della geometria come wireframe. L'impostazione predefinita è `false` + (cioè renderizza come poligoni piatti).

    + +

    [property:String wireframeLinecap]

    +

    + Definisce l'aspetto delle estremità della linea. I valori possibili sono "butt", "round" e "square". Il valore predefinito è 'round'.

    + + Corrisponde alla proprietà [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineCap 2D Canvas lineCap] + e viene ignorata dal renderer [page:WebGLRenderer WebGL]. +

    + +

    [property:String wireframeLinejoin]

    +

    + Definisce l'aspetto dei punti di unione della linea. I valori possibili sono "round", "bevel" e "miter". Il valore predefinito è 'round'.

    + + Corrisponde alla proprietà [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineJoin 2D Canvas lineJoin] + e viene ignorata dal renderer [page:WebGLRenderer WebGL]. +

    + +

    [property:Float wireframeLinewidth]

    +

    Controlla lo spesso del wireframe. Il valore predefinito è 1.

    + + A causa delle limitazioni del [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf profilo OpenGL Core] + con il renderer [page:WebGLRenderer WebGL] sulla maggior parte delle piattaforme, la larghezza di riga sarà sempre 1 indipendentemente + dal valore impostato. +

    + +

    Metodi

    +

    Vedi la classe base [page:Material] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/materials/MeshDepthMaterial.html b/docs/api/it/materials/MeshDepthMaterial.html new file mode 100644 index 00000000000000..6007e4a419e242 --- /dev/null +++ b/docs/api/it/materials/MeshDepthMaterial.html @@ -0,0 +1,117 @@ + + + + + + + + + + [page:Material] → + +

    [name]

    + +

    + Un materiale per disegnare la geometria in base alla profondità. La profondità si basa sul piano vicino (near) e il piano + lontano (far) della telecamera. Il bianco è più vicino, il nero è più lontano. +

    + + + + + +

    Costruttore

    + +

    [name]( [param:Object parameters] )

    +

    + [page:Object parameters] - (opzionale) un oggetto con una o più proprietà che definiscono l'aspetto del materiale. + Qualsiasi proprietà del materiale (inclusa qualsiasi proprietà ereditata da [page:Material]) può essere passata qui. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Material] per le proprietà comuni.

    + +

    [property:Texture alphaMap]

    +

    + La mappa alfa è una texture in scala di grigi che controlla l'opacità sulla superficie + (nero: completamente trasparente; bianco: completamente opaco). Il valore predefinito è `null`.

    + + Viene utilizzato solo il colore della texture, ignorando il canale alfa, se esiste. + Per le texuture RGB e RGBA, il renderer [page:WebGLRenderer WebGL] utilizzarà il canale del verde + durante il campionamento di questa texture a causa del bit extra di precisione fornito per il verde + nei formati RGB 565 compressi e non compressi DXT. Anche le texture solo luminanza e luminanza/alfa continueranno + a funzionare come previsto. +

    + +

    [property:Constant depthPacking]

    +

    Codifica per il confezionamento in profondità. Il valore predefinito è [page:Textures BasicDepthPacking].

    + +

    [property:Texture displacementMap]

    +

    + La mappa di spostamento influisce sulla posizione dei vertici della mesh. + A differenza di altre mappe che influenzano solo la luce e l'ombra del materiale, i vertici + spostati possono proiettare ombre, bloccare altri oggetti, e altrimenti agire come una vera + geometria. La texture di spostamento è un'immagine in cui il valore di ciascun pixel (il bianco è + il più alto) viene mappato e riposizionato rispetto ai vertici della mesh. +

    + +

    [property:Float displacementScale]

    +

    + Quando la mappa di spostamento influenza la mesh (dove il nero non è lo spostamento, + e il bianco è lo spostamento massimo). Senza una mappa di spostamento impostata, questo valore + non viene applicato. + Il valore predefinito è 1. +

    + +

    [property:Float displacementBias]

    +

    + L'offset dei valori della mappa di spostamento sui vertici della mesh. + Senza una mappa di spostamento impostata, questo valore + non viene applicato. Il valore predefinito è 0. +

    + +

    [property:Boolean fog]

    +

    Indica se il materiale è influenzato dalla nebbia. Il valore predefinito è `false`.

    + +

    [property:Texture map]

    +

    + La mappa colore. Può includere facoltativamente un canale alfa, tipicamente combinato con + [page:Material.transparent .transparent] o [page:Material.alphaTest .alphaTest]. Il valore predefinito è `null`. +

    + +

    [property:Boolean wireframe]

    +

    Rendering della geometria come wireframe. Il valore predefinito è `false` (cioè renderizzazione come sfumato liscio).

    + +

    [property:Float wireframeLinewidth]

    +

    Controlla lo spessore del wireframe. Il valore predefinito è `1`.

    + + A causa delle limitazioni del [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf profilo OpenGL Core] + con il renderer [page:WebGLRenderer WebGL] sulla maggior parte delle piattaforme, la larghezza di riga sarà sempre 1 indipendentemente + dal valore impostato. +

    + +

    Metodi

    +

    Vedi la classe base [page:Material] per i metodi comuni.

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/materials/MeshDistanceMaterial.html b/docs/api/it/materials/MeshDistanceMaterial.html new file mode 100644 index 00000000000000..cfe7e08491c2f5 --- /dev/null +++ b/docs/api/it/materials/MeshDistanceMaterial.html @@ -0,0 +1,124 @@ + + + + + + + + + + [page:Material] → + +

    [name]

    + +

    + [name] viene utilizzata internamente per implementare la mappatura delle ombre con [page:PointLight].

    + + Può anche essere utilizzato per personalizzare la proiezione dell'ombra di un oggetto assegnando un'istanza di [name] a [page:Object3D.customDistanceMaterial]. + L'esempio seguente dimostra questo approccio per garantire che le parti trasparenti degli oggetti non proiettano ombre. +

    + +

    Esempi

    + +

    + [example:webgl_shadowmap_pointlight WebGL / shadowmap / pointlight] +

    + + + +

    Costruttore

    + +

    [name]( [param:Object parameters] )

    +

    + [page:Object parameters] - (opzionale) un oggetto con una o più proprietà che definiscono l'aspetto del materiale. + Qualsiasi proprietà del materiale (inclusa qualsiasi proprietà ereditata da [page:Material]) può essere passata qui. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Material] per le proprietà comuni.

    + +

    [property:Texture alphaMap]

    +

    + La mappa alfa è una texture in scala di grigi che controlla l'opacità sulla superficie + (nero: completamente trasparente; bianco: completamente opaco). Il valore predefinito è `null`.

    + + Viene utilizzato solo il colore della texture, ignorando il canale alfa, se esiste. + Per le texuture RGB e RGBA, il renderer [page:WebGLRenderer WebGL] utilizzarà il canale del verde + durante il campionamento di questa texture a causa del bit extra di precisione fornito per il verde + nei formati RGB 565 compressi e non compressi DXT. Anche le texture solo luminanza e luminanza/alfa continueranno + a funzionare come previsto. +

    + +

    [property:Texture displacementMap]

    +

    + La mappa di spostamento influisce sulla posizione dei vertici della mesh. + A differenza di altre mappe che influenzano solo la luce e l'ombra del materiale, i vertici + spostati possono proiettare ombre, bloccare altri oggetti, e altrimenti agire come una vera + geometria. La texture di spostamento è un'immagine in cui il valore di ciascun pixel (il bianco è + il più alto) viene mappato e riposizionato rispetto ai vertici della mesh. +

    + +

    [property:Float displacementScale]

    +

    + Quando la mappa di spostamento influenza la mesh (dove il nero non è lo spostamento, + e il bianco è lo spostamento massimo). Senza una mappa di spostamento impostata, questo valore + non viene applicato. + Il valore predefinito è 1. +

    + +

    [property:Float displacementBias]

    +

    + L'offset dei valori della mappa di spostamento sui vertici della mesh. + Senza una mappa di spostamento impostata, questo valore + non viene applicato. Il valore predefinito è 0. +

    + +

    [property:Float farDistance]

    +

    + Il valore far della telecamera d'ombra interna della luce puntiforme. +

    + +

    [property:Boolean fog]

    +

    Indica se il materiale è influenzato dalla nebbia. Il valore predefinito è `false`.

    + +

    [property:Texture map]

    +

    + La mappa colore. Può includere facoltativamente un canale alfa, tipicamente combinato con + [page:Material.transparent .transparent] o [page:Material.alphaTest .alphaTest]. Il valore predefinito è `null`. +

    + +

    [property:Float nearDistance]

    +

    + Il valore near della telecamera d'obra interna della luce puntiforme. +

    + +

    [property:Vector3 referencePosition]

    +

    + La posizione della luce puntiforme nello spazio world. +

    + +

    Metodi

    +

    Vedi la classe base [page:Material] per i metodi comuni.

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/materials/MeshLambertMaterial.html b/docs/api/it/materials/MeshLambertMaterial.html new file mode 100644 index 00000000000000..3347222474c7f2 --- /dev/null +++ b/docs/api/it/materials/MeshLambertMaterial.html @@ -0,0 +1,236 @@ + + + + + + + + + + [page:Material] → + +

    [name]

    + +

    + Un materiale per superfici non lucide, senza riflessi speculari.

    + + Il materiale utilizza un modello [link:https://en.wikipedia.org/wiki/Lambertian_reflectance Lambertiano] non fisico + per calcolare la riflettanza. Questo può simulare bene alcune superfici (come legno o pietra non trattati), + ma non può simulare superfici lucide con riflessi speculari (come il legno verniciato). [name] utilizza + l'ombreggiatura per-fragment.

    + + A causa della semplicità dei modelli della riflettanza e illuminazione, le prestazioni saranno maggiori + quando si utilizza questo materiale su [page:MeshPhongMaterial], [page:MeshStandardMaterial] o [page:MeshPhysicalMaterial], + a scapito di una certa precisione grafica. +

    + + + + + +

    Costruttore

    + +

    [name]( [param:Object parameters] )

    +

    + [page:Object parameters] - (opzionale) un oggetto con una o più proprietà che definiscono l'aspetto del materiale. + Qualsiasi proprietà del materiale (inclusa qualsiasi proprietà ereditata da [page:Material]) può essere passata qui.

    + + L'eccezione è la proprietà [page:Hexadecimal colore], la quale può essere passata come stringa + esadecimale e per impostazione predefinita è `0xffffff` (bianco). [page:Color.set]( color ) viene chiamato internamente. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Material] per le proprietà comuni.

    + +

    [property:Texture alphaMap]

    +

    + La mappa alfa è una texture in scala di grigi che controlla l'opacità sulla superficie + (nero: completamente trasparente; bianco: completamente opaco). Il valore predefinito è `null`.

    + + Viene utilizzato solo il colore della texture, ignorando il canale alfa, se esiste. + Per le texuture RGB e RGBA, il renderer [page:WebGLRenderer WebGL] utilizzarà il canale del verde + durante il campionamento di questa texture a causa del bit extra di precisione fornito per il verde + nei formati RGB 565 compressi e non compressi DXT. Anche le texture solo luminanza e luminanza/alfa continueranno + a funzionare come previsto. +

    + +

    [property:Texture aoMap]

    +

    + Il canale rosso di questa texture viene utilizzato come la mappa di occlusione ambientale. Il valore + predefinito è `null`. AoMap richiede un secondo set di UV. +

    + +

    [property:Float aoMapIntensity]

    +

    L'intensità dell'effetto di occlusione ambientale. Il valore + predefinito è `1`. Zero non è un effetto di occlusione.

    + +

    [property:Texture bumpMap]

    +

    + La texture per creare una mappa di rilievo. I valori nero e bianco si associano alla profondità percepita in relazione + alle luci. Bump in realtà non influisce sulla geometria dell'oggetto, solo sull'illuminazione. Se viene definita una mappa + normale questa verrà ignorata. +

    + +

    [property:Float bumpScale]

    +

    Quanto la mappa di rilievo influisce sul materiale. Gli intervalli tipici sono 0-1. Il valore predefinito è 1.

    + +

    [property:Color color]

    +

    [page:Color Colore] del materiale, il valore predefinito è impostato a bianco (0xffffff).

    + +

    [property:Integer combine]

    +

    + Come combinare il risultato del colore della superficie con l'eventuale mappa ambientale.

    + + Le opzioni sono [page:Materials THREE.MultiplyOperation] (impostazione predefinita), [page:Materials THREE.MixOperation], + [page:Materials THREE.AddOperation]. Se viene scelto il mix, la [page:.reflectivity] viene utilizzata per + sfumare tra i due colori. +

    + +

    [property:Texture displacementMap]

    +

    + La mappa di spostamento influisce sulla posizione dei vertici della mesh. + A differenza di altre mappe che influenzano solo la luce e l'ombra del materiale, i vertici + spostati possono proiettare ombre, bloccare altri oggetti, e altrimenti agire come una vera + geometria. La texture di spostamento è un'immagine in cui il valore di ciascun pixel (il bianco è + il più alto) viene mappato e riposizionato rispetto ai vertici della mesh. +

    + +

    [property:Float displacementScale]

    +

    + Quando la mappa di spostamento influenza la mesh (dove il nero non è lo spostamento, + e il bianco è lo spostamento massimo). Senza una mappa di spostamento impostata, questo valore + non viene applicato. + Il valore predefinito è 1. +

    + +

    [property:Float displacementBias]

    +

    + L'offset dei valori della mappa di spostamento sui vertici della mesh. + Senza una mappa di spostamento impostata, questo valore + non viene applicato. Il valore predefinito è 0. +

    + +

    [property:Color emissive]

    +

    + Colore emissivo (chiaro) per il materiale, essenzialmente un colore solido non influenzato + da altre luci. L'impostazione predefinita è nero. +

    + +

    [property:Texture emissiveMap]

    +

    + Imposta la mappa emissiva (bagliore). Il valore predefinito è `null`. Il colore della mappa emissiva + è modulato dal colore emissivo e dall'intensità emissiva. Se si dispone di una mappa emissiva, + assicurarsi di impostare il colore emissivo su qualcosa di diverso dal nero. +

    + +

    [property:Float emissiveIntensity]

    +

    Intensità della luce emissiva. Modula il colore emissivo. Il valore predefinito è `1`.

    + +

    [property:Texture envMap]

    +

    La mappa ambientale. Il valore predefinito è `null`.

    + +

    [property:Boolean flatShading]

    +

    + Definisce se il materiale viene renderizzato con un'ombreggiatura piatta. Il valore predefinito è `false`. +

    + +

    [property:Boolean fog]

    +

    Indica se il materiale è influenzato dalla nebbia. Il valore predefinito è `true`.

    + +

    [property:Texture lightMap]

    +

    La mappa della luce. Il valore predefinito è `null`. La lightMap richiede un secondo set di UV.

    + +

    [property:Float lightMapIntensity]

    +

    Intensità della luce. Il valore predefinito è `1`.

    + +

    [property:Texture map]

    +

    + La mappa colore. Può includere facoltativamente un canale alfa, in genere combinato + con [page:Material.transparent .transparent] o [page:Material.alphaTest .alphaTest]. Il valore predefinito è `null`. +

    + +

    [property:Texture normalMap]

    +

    + La texture per creare una mappa normale. I valori RGB influenzano la normale della superficie per ogni frammento di pixel + e cambiano il modo in cui il colore è illuminato. Le mappe normali non modificano la figura effettiva della superficie, + ma solo l'illuminazione. Nel caso in cui il materiale abbia una mappa normale creata utilizzando la convezione della mano + sinistra, la componente y di normalScale deve essere negata per compensare la diversa mano. +

    + +

    [property:Integer normalMapType]

    +

    + Il tipo di mappa normale.

    + + Le opzioni sono [page:constant THREE.TangentSpaceNormalMap] (impostazione predefinita), e [page:constant THREE.ObjectSpaceNormalMap]. +

    + +

    [property:Vector2 normalScale]

    +

    + Quanto la mappa normale influenza il materiale. Gli intervalli tipici sono 0-1. + Il valore predefinito è un [page:Vector2] impostato a (1,1). +

    + +

    [property:Float reflectivity]

    +

    Quanto la mappa ambientale influisce sulla superficie; vedi anche [page:.combine].

    + +

    [property:Float refractionRatio]

    +

    + L'indice di rifrazione (IOR) dell'aria (circa 1) diviso per l'indice di rifrazione del materiale. + Viene utilizzato con le modalità di mappatura ambientale [page:Textures THREE.CubeRefractionMapping] e [page:Textures THREE.EquirectangularRefractionMapping]. + Il rapporto di rifrazione non deve essere superiore a 1. Il valore predefinito è `0.98`. +

    + +

    [property:Texture specularMap]

    +

    Mappa speculare utilizzata dal materiale. Il valore predefinito è `null`.

    + +

    [property:Boolean wireframe]

    +

    Rendering della geometria come wireframe. Il valore predefinito è `false` (cioè renderizzazione come poligoni piatti).

    + +

    [property:String wireframeLinecap]

    +

    + Definisce l'aspetto delle estremità della linea. I valori possibili sono "butt", "round" e "square". Il valore predefinito è 'round'.

    + + Questa corrisponde alla proprietà [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineCap 2D Canvas lineCap] + e viene ignorata dal renderer [page:WebGLRenderer WebGL]. +

    + +

    [property:String wireframeLinejoin]

    +

    + Definisce l'aspetto dei punti di unione della linea. I valori possibili sono "round", "bevel" e "miter". Il valore predefinito è 'round'.

    + + Questa corrisponde alla proprietà [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineJoin 2D Canvas lineJoin] + e viene ignorata dal renderer [page:WebGLRenderer WebGL]. +

    + +

    [property:Float wireframeLinewidth]

    +

    Controlla lo spessore del wireframe. Il valore predefinito è `1`.

    + + A causa delle limitazioni del [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf profilo OpenGL Core] + con il renderer [page:WebGLRenderer WebGL] sulla maggior parte delle piattaforme, + la larghezza di riga sarà sempre 1 indipendentemente dal valore impostato. +

    + +

    Metodi

    +

    Vedi la classe base [page:Material] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/materials/MeshMatcapMaterial.html b/docs/api/it/materials/MeshMatcapMaterial.html new file mode 100644 index 00000000000000..7ed0b92525ec94 --- /dev/null +++ b/docs/api/it/materials/MeshMatcapMaterial.html @@ -0,0 +1,149 @@ + + + + + + + + + + [page:Material] → + +

    [name]

    + +

    + [name] è definita da una texture MatCap (o Lit Sphere), la quale codifica il colore del materiale e le ombreggiature.

    + [name] non risponde alle luci poiché il file immagine matcap codifica l'illuminazione cotta. + Proietterà un'ombra su un oggetto che riceve le ombre (e il ritaglio delle ombre funziona), ma non si auto-ombrerà ne riceverà le ombre. +

    + + + + + +

    Costruttore

    + +

    [name]( [param:Object parameters] )

    +

    + [page:Object parameters] - (opzionale) un oggetto con una o più proprietà che definiscono l'aspetto del materiale. + Qualsiasi proprietà del materiale (inclusa qualsiasi proprietà ereditata da [page:Material]) può essere passata qui.

    + + L'eccezione è la proprietà [page:Hexadecimal colore], la quale può essere passata come stringa + esadecimale e per impostazione predefinita è `0xffffff` (bianco). [page:Color.set]( color ) viene chiamato internamente. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Material] per le proprietà comuni.

    + +

    [property:Texture alphaMap]

    +

    + La mappa alfa è una texture in scala di grigi che controlla l'opacità sulla superficie + (nero: completamente trasparente; bianco: completamente opaco). Il valore predefinito è `null`.

    + + Viene utilizzato solo il colore della texture, ignorando il canale alfa, se esiste. + Per le texuture RGB e RGBA, il renderer [page:WebGLRenderer WebGL] utilizzarà il canale del verde + durante il campionamento di questa texture a causa del bit extra di precisione fornito per il verde + nei formati RGB 565 compressi e non compressi DXT. Anche le texture solo luminanza e luminanza/alfa continueranno + a funzionare come previsto. +

    + +

    [property:Texture bumpMap]

    +

    + La texture per creare una mappa di rilievo. I valori nero e bianco si associano alla profondità percepita in relazione + alle luci. Bump in realtà non influisce sulla geometria dell'oggetto, solo sull'illuminazione. Se viene definita una mappa + normale questa verrà ignorata. +

    + +

    [property:Float bumpScale]

    +

    Quanto la mappa di rilievo influisce sul materiale. Gli intervalli tipici sono 0-1. Il valore predefinito è 1.

    + +

    [property:Color color]

    +

    [page:Color] del materiale, il valore predefinito è bianco (0xffffff).

    + +

    [property:Texture displacementMap]

    +

    + La mappa di spostamento influisce sulla posizione dei vertici della mesh. + A differenza di altre mappe che influenzano solo la luce e l'ombra del materiale, i vertici + spostati possono proiettare ombre, bloccare altri oggetti, e altrimenti agire come una vera + geometria. La texture di spostamento è un'immagine in cui il valore di ciascun pixel (il bianco è + il più alto) viene mappato e riposizionato rispetto ai vertici della mesh. +

    + +

    [property:Float displacementScale]

    +

    + Quando la mappa di spostamento influenza la mesh (dove il nero non è lo spostamento, + e il bianco è lo spostamento massimo). Senza una mappa di spostamento impostata, questo valore + non viene applicato. + Il valore predefinito è 1. +

    + +

    [property:Float displacementBias]

    +

    + L'offset dei valori della mappa di spostamento sui vertici della mesh. + Senza una mappa di spostamento impostata, questo valore + non viene applicato. Il valore predefinito è 0. +

    + +

    [property:Boolean flatShading]

    +

    + Definisce se il materiale viene renderizzato con un'ombreggiatura piatta. Il valore predefinito è `false`. +

    + +

    [property:Boolean fog]

    +

    Indica se il materiale è influenzato dalla nebbia. Il valore predefinito è `true`.

    + +

    [property:Texture map]

    +

    + La mappa colore. Può includere facoltativamente un canale alfa, in genere combinato + con [page:Material.transparent .transparent] or[page:Material.alphaTest .alphaTest]. Il valore predefinito è `null`. + Il colore della mappa texture è modulato dal [page:.color] diffuso. +

    + +

    [property:Texture matcap]

    +

    La mappa matcap. Il valore predefinito è `null`.

    + +

    [property:Texture normalMap]

    +

    + La texture per creare una mappa normale. I valori RGB influenzano la normale della superficie per ogni frammento di pixel + e cambiano il modo in cui il colore è illuminato. Le mappe normali non modificano la figura effettiva della superficie, + ma solo l'illuminazione. Nel caso in cui il materiale abbia una mappa normale creata utilizzando la convezione della mano + sinistra, la componente y di normalScale deve essere negata per compensare la diversa mano. +

    + +

    [property:Integer normalMapType]

    +

    + Il tipo di mappa normale.

    + + Le opzioni sono [page:constant THREE.TangentSpaceNormalMap] (impostazione predefinita), e [page:constant THREE.ObjectSpaceNormalMap]. +

    + +

    [property:Vector2 normalScale]

    +

    + Quanto la mappa normale influenza il materiale. Gli intervalli tipici sono 0-1. + Il valore predefinito è un [page:Vector2] impostato a (1,1). +

    + +

    Metodi

    +

    Vedi la classe base [page:Material] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/materials/MeshNormalMaterial.html b/docs/api/it/materials/MeshNormalMaterial.html new file mode 100644 index 00000000000000..abcecf3bcb3673 --- /dev/null +++ b/docs/api/it/materials/MeshNormalMaterial.html @@ -0,0 +1,132 @@ + + + + + + + + + + [page:Material] → + +

    [name]

    + +

    Un materiale che mappa i vettori normale sui colori RGB.

    + + + + + +

    Costruttore

    + +

    [name]( [param:Object parameters] )

    +

    + [page:Object parameters] - (opzionale) un oggetto con una o più proprietà che definiscono l'aspetto del materiale. + Qualsiasi proprietà del materiale (inclusa qualsiasi proprietà ereditata da [page:Material]) può essere passata qui.

    +

    + + +

    Proprietà

    +

    Vedi la classe base [page:Material] per le proprietà comuni.

    + +

    [property:Texture bumpMap]

    +

    + La texture per creare una mappa di rilievo. I valori nero e bianco si associano alla profondità percepita in relazione + alle luci. Bump in realtà non influisce sulla geometria dell'oggetto, solo sull'illuminazione. Se viene definita una mappa + normale questa verrà ignorata. +

    + +

    [property:Float bumpScale]

    +

    Quanto la mappa di rilievo influisce sul materiale. Gli intervalli tipici sono 0-1. Il valore predefinito è 1.

    + +

    [property:Texture displacementMap]

    +

    + La mappa di spostamento influisce sulla posizione dei vertici della mesh. + A differenza di altre mappe che influenzano solo la luce e l'ombra del materiale, i vertici + spostati possono proiettare ombre, bloccare altri oggetti, e altrimenti agire come una vera + geometria. La texture di spostamento è un'immagine in cui il valore di ciascun pixel (il bianco è + il più alto) viene mappato e riposizionato rispetto ai vertici della mesh. +

    + +

    [property:Float displacementScale]

    +

    + Quando la mappa di spostamento influenza la mesh (dove il nero non è lo spostamento, + e il bianco è lo spostamento massimo). Senza una mappa di spostamento impostata, questo valore + non viene applicato. + Il valore predefinito è 1. +

    + +

    [property:Float displacementBias]

    +

    + L'offset dei valori della mappa di spostamento sui vertici della mesh. + Senza una mappa di spostamento impostata, questo valore + non viene applicato. Il valore predefinito è 0. +

    + +

    [property:Boolean flatShading]

    +

    + Definisce se il materiale viene renderizzato con un'ombreggiatura piatta. Il valore predefinito è `false`. +

    + +

    [property:Boolean fog]

    +

    Indica se il materiale è influenzato dalla nebbia. Il valore predefinito è `false`.

    + +

    [property:Texture normalMap]

    +

    + La texture per creare una mappa normale. I valori RGB influenzano la normale della superficie per ogni frammento di pixel + e cambiano il modo in cui il colore è illuminato. Le mappe normali non modificano la figura effettiva della superficie, + ma solo l'illuminazione. Nel caso in cui il materiale abbia una mappa normale creata utilizzando la convezione della mano + sinistra, la componente y di normalScale deve essere negata per compensare la diversa mano. +

    + +

    [property:Integer normalMapType]

    +

    + Il tipo di mappa normale.

    + + Le opzioni sono [page:constant THREE.TangentSpaceNormalMap] (impostazione predefinita), e [page:constant THREE.ObjectSpaceNormalMap]. +

    + +

    [property:Vector2 normalScale]

    +

    + Quanto la mappa normale influenza il materiale. Gli intervalli tipici sono 0-1. + Il valore predefinito è un [page:Vector2] impostato a (1,1). +

    + +

    [property:Boolean wireframe]

    +

    + Rendering della geometria come wireframe. Il valore predefinito è `false` (cioè renderizzazione come poligoni piatti).

    +

    + +

    [property:Float wireframeLinewidth]

    +

    Controlla lo spessore del wireframe. Il valore predefinito è `1`.

    + + A causa delle limitazioni del [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf profilo OpenGL Core] + con il renderer [page:WebGLRenderer WebGL] sulla maggior parte delle piattaforme, + la larghezza di riga sarà sempre 1 indipendentemente dal valore impostato. +

    + +

    Metodi

    +

    Vedi la classe base [page:Material] per i metodi comuni.

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/materials/MeshPhongMaterial.html b/docs/api/it/materials/MeshPhongMaterial.html new file mode 100644 index 00000000000000..556738a99f15f6 --- /dev/null +++ b/docs/api/it/materials/MeshPhongMaterial.html @@ -0,0 +1,252 @@ + + + + + + + + + + [page:Material] → + +

    [name]

    + +

    + Un materiale per superfici lucide, senza riflessi speculari.

    + + Il materiale utilizza un modello [link:https://en.wikipedia.org/wiki/Blinn-Phong_shading_model Blinn-Phong] non fisico + per calcolare la riflettanza. A differenza dal modello Lambertiano utilizzato nel [page:MeshLambertMaterial] + questo può simulare superfici lucide con riflessi speculari (come il legno verniciato). [name] utilizza + l'ombreggiatura per-fragment.

    + + Le prestazioni saranno maggiori quando si utilizza questo materiale su [page:MeshStandardMaterial] o [page:MeshPhysicalMaterial], + a scapito di una certa precisione grafica. +

    + + + + + +

    Costruttore

    + +

    [name]( [param:Object parameters] )

    +

    + [page:Object parameters] - (opzionale) un oggetto con una o più proprietà che definiscono l'aspetto del materiale. + Qualsiasi proprietà del materiale (inclusa qualsiasi proprietà ereditata da [page:Material]) può essere passata qui.

    + + L'eccezione è la proprietà [page:Hexadecimal colore], la quale può essere passata come stringa + esadecimale e per impostazione predefinita è `0xffffff` (bianco). [page:Color.set]( color ) viene chiamato internamente. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Material] per le proprietà comuni.

    + +

    [property:Texture alphaMap]

    +

    + La mappa alfa è una texture in scala di grigi che controlla l'opacità sulla superficie + (nero: completamente trasparente; bianco: completamente opaco). Il valore predefinito è `null`.

    + + Viene utilizzato solo il colore della texture, ignorando il canale alfa, se esiste. + Per le texuture RGB e RGBA, il renderer [page:WebGLRenderer WebGL] utilizzarà il canale del verde + durante il campionamento di questa texture a causa del bit extra di precisione fornito per il verde + nei formati RGB 565 compressi e non compressi DXT. Anche le texture solo luminanza e luminanza/alfa continueranno + a funzionare come previsto. +

    + +

    [property:Texture aoMap]

    +

    Il canale rosso di questa texture viene utilizzato come la mappa di occlusione ambientale. Il valore + predefinito è `null`. AoMap richiede un secondo set di UV.

    + +

    [property:Float aoMapIntensity]

    +

    L'intensità dell'effetto di occlusione ambientale. Il valore + predefinito è `1`. Zero non è un effetto di occlusione.

    + +

    [property:Texture bumpMap]

    +

    + La texture per creare una mappa di rilievo. I valori nero e bianco si associano alla profondità percepita in relazione + alle luci. Bump in realtà non influisce sulla geometria dell'oggetto, solo sull'illuminazione. Se viene definita una mappa + normale questa verrà ignorata. +

    + +

    [property:Float bumpScale]

    +

    Quanto la mappa di rilievo influisce sul materiale. Gli intervalli tipici sono 0-1. Il valore predefinito è 1.

    + + +

    [property:Color color]

    +

    [page:Color Colore] del materiale, il valore predefinito è impostato a bianco (0xffffff).

    + +

    [property:Integer combine]

    +

    + Come combinare il risultato del colore della superficie con l'eventuale mappa ambientale.

    + + Le opzioni sono [page:Materials THREE.MultiplyOperation] (impostazione predefinita), [page:Materials THREE.MixOperation], + [page:Materials THREE.AddOperation]. Se viene scelto il mix, la [page:.reflectivity] viene utilizzata per + sfumare tra i due colori. +

    + +

    [property:Texture displacementMap]

    +

    + La mappa di spostamento influisce sulla posizione dei vertici della mesh. + A differenza di altre mappe che influenzano solo la luce e l'ombra del materiale, i vertici + spostati possono proiettare ombre, bloccare altri oggetti, e altrimenti agire come una vera + geometria. La texture di spostamento è un'immagine in cui il valore di ciascun pixel (il bianco è + il più alto) viene mappato e riposizionato rispetto ai vertici della mesh. +

    + +

    [property:Float displacementScale]

    +

    + Quando la mappa di spostamento influenza la mesh (dove il nero non è lo spostamento, + e il bianco è lo spostamento massimo). Senza una mappa di spostamento impostata, questo valore + non viene applicato. + Il valore predefinito è 1. +

    + +

    [property:Float displacementBias]

    +

    + L'offset dei valori della mappa di spostamento sui vertici della mesh. + Senza una mappa di spostamento impostata, questo valore + non viene applicato. Il valore predefinito è 0. +

    + +

    [property:Color emissive]

    +

    + Colore emissivo (chiaro) per il materiale, essenzialmente un colore solido non influenzato + da altre luci. L'impostazione predefinita è nero. +

    + +

    [property:Texture emissiveMap]

    +

    + Imposta la mappa emissiva (bagliore). Il valore predefinito è `null`. Il colore della mappa emissiva + è modulato dal colore emissivo e dall'intensità emissiva. Se si dispone di una mappa emissiva, + assicurarsi di impostare il colore emissivo su qualcosa di diverso dal nero. +

    + +

    [property:Float emissiveIntensity]

    +

    Intensità della luce emissiva. Modula il colore emissivo. Il valore predefinito è `1`.

    + +

    [property:Texture envMap]

    +

    La mappa ambientale. Il valore predefinito è `null`.

    + +

    [property:Boolean flatShading]

    +

    + Definisce se il materiale viene renderizzato con un'ombreggiatura piatta. Il valore predefinito è `false`. +

    + +

    [property:Boolean fog]

    +

    Indica se il materiale è influenzato dalla nebbia. Il valore predefinito è `true`.

    + +

    [property:Texture lightMap]

    +

    La mappa della luce. Il valore predefinito è `null`. La lightMap richiede un secondo set di UV.

    + +

    [property:Float lightMapIntensity]

    +

    Intensità della luce. Il valore predefinito è `1`.

    + +

    [property:Texture map]

    +

    + La mappa colore. Può includere facoltativamente un canale alfa, in genere combinato + con [page:Material.transparent .transparent] or[page:Material.alphaTest .alphaTest]. Il valore predefinito è `null`. + Il colore della mappa texture è modulato dal [page:.color] diffuso. +

    + +

    [property:Texture normalMap]

    +

    + La texture per creare una mappa normale. I valori RGB influenzano la normale della superficie per ogni frammento di pixel + e cambiano il modo in cui il colore è illuminato. Le mappe normali non modificano la figura effettiva della superficie, + ma solo l'illuminazione. Nel caso in cui il materiale abbia una mappa normale creata utilizzando la convezione della mano + sinistra, la componente y di normalScale deve essere negata per compensare la diversa mano. +

    + +

    [property:Integer normalMapType]

    +

    + Il tipo di mappa normale.

    + + Le opzioni sono [page:constant THREE.TangentSpaceNormalMap] (impostazione predefinita), e [page:constant THREE.ObjectSpaceNormalMap]. +

    + +

    [property:Vector2 normalScale]

    +

    + Quanto la mappa normale influenza il materiale. Gli intervalli tipici sono 0-1. + Il valore predefinito è un [page:Vector2] impostato a (1,1). +

    + +

    [property:Float reflectivity]

    +

    + Quanto la mappa ambientale influisce sulla superficie; vedi anche [page:.combine]. + Il valore predefinito è 1 e l'intervallo valido è tra 0 (nessun riflesso) e 1 (pieno riflesso). +

    + +

    [property:Float refractionRatio]

    +

    + L'indice di rifrazione (IOR) dell'aria (circa 1) diviso per l'indice di rifrazione del materiale. + Viene utilizzato con le modalità di mappatura ambientale [page:Textures THREE.CubeRefractionMapping] e [page:Textures THREE.EquirectangularRefractionMapping]. + Il rapporto di rifrazione non deve essere superiore a 1. Il valore predefinito è `0.98`. +

    + +

    [property:Float shininess]

    +

    Quanto è brillante l'evidenziazione [page:.specular speculare]; un valore più alto dà un'evidenziazione più nitida. Il valore predefinito è `30`.

    + +

    [property:Color specular]

    +

    + Colore speculare del materiale. Il valore predefinito è [page:Color] impostato a `0x111111` (grigio molto scuro).

    + + Questo definisce la lucentezza del materiale e il colore della sua lucentezza. +

    + +

    [property:Texture specularMap]

    +

    + Il valore della mappa speculare influenza sia quanto contribuisce l'evidenziazione + della superficie speculare sia quanto la mappa ambientale influisce sulla superficie. + Il valore predefinito è `null`. +

    + +

    [property:Boolean wireframe]

    +

    Rendering della geometria come wireframe. Il valore predefinito è `false` (cioè renderizzazione come poligoni piatti).

    + +

    [property:String wireframeLinecap]

    +

    + Definisce l'aspetto delle estremità della linea. I valori possibili sono "butt", "round" e "square". Il valore predefinito è 'round'.

    + + Questa corrisponde alla proprietà [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineCap 2D Canvas lineCap] + e viene ignorata dal renderer [page:WebGLRenderer WebGL]. +

    + +

    [property:String wireframeLinejoin]

    +

    + Definisce l'aspetto dei punti di unione della linea. I valori possibili sono "round", "bevel" e "miter". Il valore predefinito è 'round'.

    + + Questa corrisponde alla proprietà [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineJoin 2D Canvas lineJoin] + e viene ignorata dal renderer [page:WebGLRenderer WebGL]. +

    + +

    [property:Float wireframeLinewidth]

    +

    Controlla lo spessore del wireframe. Il valore predefinito è `1`.

    + + A causa delle limitazioni del [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf profilo OpenGL Core] + con il renderer [page:WebGLRenderer WebGL] sulla maggior parte delle piattaforme, + la larghezza di riga sarà sempre 1 indipendentemente dal valore impostato. +

    + +

    Metodi

    +

    Vedi la classe base [page:Material] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/materials/MeshPhysicalMaterial.html b/docs/api/it/materials/MeshPhysicalMaterial.html new file mode 100644 index 00000000000000..e38648f3d1542e --- /dev/null +++ b/docs/api/it/materials/MeshPhysicalMaterial.html @@ -0,0 +1,242 @@ + + + + + + + + + + [page:Material] → [page:MeshStandardMaterial] → + +

    [name]

    + +

    + Un'estenzione della classe [page:MeshStandardMaterial], che fornisce proprietà di rendering basate sulla fisica più avanzate: +

    + +
      +
    • + Clearcoat (rivestimento trasparente): Alcuni materiali - come vernici per auto, fibra di carbonio + e superfici bagnate - richiedono uno strato trasparente e riflettente sopra un altro strato che può essere irregolare + o ruvido. Il rivestimento trasparente approssima questo effetto, senza la necessità di una superficie + trasparente separata. +
    • +
    • + Physically-based transparency (trasparenza fisica): Una limitazione di [page:Material.opacity .opacity] + è che materiali molto trasparenti sono meno riflettenti. La [page:.transmission] fisica + fornisce una opzione più realistica per superfici sottili e trasparenti come il vetro. +
    • +
    • + Advanced reflectivity (riflettività avanzata): Riflettività più flessibile per materiali non metallici. +
    • +
    • + Sheen: Can be used for representing cloth and fabric materials. +
    • +
    + +

    + Come risultato di queste complesse caratteristiche di ombreggiatura, MeshPhysicalMaterial + ha un elevato costo di prestazioni, per pixel, rispetto ad altri materiali utilizzati in three.js. + Molti effetti sono disabilitati per impostazione predefinita, e viene aggiunto un costo quando questi + vengono abilitati. Per ottenere risultati ottimali, specificare sempre una [page:.envMap mappa ambientale] + quando si usa questo materiale. +

    + + + + + +

    Esempi

    +

    + [example:webgl_materials_variations_physical materials / variations / physical]
    + [example:webgl_materials_physical_clearcoat materials / physical / clearcoat]
    + [example:webgl_materials_physical_reflectivity materials / physical / reflectivity]
    + [example:webgl_loader_gltf_sheen loader / gltf / sheen]
    + [example:webgl_materials_physical_transmission materials / physical / transmission] +

    + +

    Costruttore

    + +

    [name]( [param:Object parameters] )

    +

    + [page:Object parameters] - (opzionale) un oggetto con una o più proprietà che definiscono l'aspetto del materiale. + Qualsiasi proprietà del materiale (inclusa qualsiasi proprietà ereditata da [page:Material] e [page:MeshStandardMaterial]) può essere passata qui.

    + + L'eccezione è la proprietà [page:Hexadecimal colore], la quale può essere passata come stringa + esadecimale e per impostazione predefinita è `0xffffff` (bianco). [page:Color.set]( color ) viene chiamato internamente. +

    + +

    Proprietà

    +

    Vedi le classi base [page:Material] e [page:MeshStandardMaterial] per le proprietà comuni.

    + +

    [property:Color attenuationColor]

    +

    + Il colore in cui la luce bianca si trasforma a causa dell'assorbimento quando raggiunge la distanza di attenuazione. + Il valore predefinito è `bianco` (0xffffff). +

    + +

    [property:Float attenuationDistance]

    +

    + Densità del mezzo, data come distanza media percorsa dalla luce nel mezzo prima di interagire con una particella. + Il valore è indicato nello spazio del mondo. Il valore predefinito è `0`. + Density of the medium given as the average distance that light travels in the medium before interacting with a particle. The value is given in world space units, and must be greater than zero. Default is `Infinity`. +

    + +

    [property:Float clearcoat]

    +

    + Rappresenta l'intensità dello strato di vernice trasparente, da `0.0` a `1.0`. Usare le proprietà relative al trasparente per + abilitare i materiali multistrato. Il valore predefinito è `0.0`. +

    + +

    [property:Texture clearcoatMap]

    +

    + Il canale rosso di questa texture è moltiplicato per [page:.clearcoat], + per controllare l'intensità del rivestimento per pixel. Il valore predefinito è `null`. +

    + +

    [property:Texture clearcoatNormalMap]

    +

    Può essere utilizzato per abilitare le normali indipendenti per lo strato di rivestimento trasparente. Il valore predefinito è `null`.

    + +

    [property:Vector2 clearcoatNormalScale]

    +

    Quanto [page:.clearcoatNormalMap] influisce sullo strato di rivestimento trasparente, da `(0,0)` a `(1,1)`. Il valore predefinito è `(1,1)`.

    + +

    [property:Float clearcoatRoughness]

    +

    Rugosità dello strato di rivestimento trasparente, da `0.0` a `1.0`. Il valore predefinito è `0.0`.

    + +

    [property:Texture clearcoatRoughnessMap]

    +

    + Il canale verde di questa texture è moltiplicato per [page:.clearcoatRoughness], + per controllare la rugosità del rivestimento per pixel. Il valore predefinito è `null`. +

    + +

    [property:Object defines]

    +

    Un oggetto della forma: + +{ + + 'STANDARD': '' + 'PHYSICAL': '', + +}; + + + Questo viene utilizzato dal [page:WebGLRenderer] per selezionare gli shader. +

    + +

    [property:Float ior]

    +

    + Indice di rifrazione per materiali non metallici, da `1.0` a `2.333`. Il valore predefinito è `1.5`.
    +

    + +

    [property:Float reflectivity]

    +

    + Grado di riflettività, da `0.0` a `1.0`. Il valore predefinito è `0.5`, il quale corrisponde all'indice di rifrazione di 1.5.
    + + Questo modella la riflettività dei materiali non metallici. Non ha alcun effetto quando [page:MeshStandardMaterial.metalness metalness] è `1.0`. +

    + +

    [property:Float sheen]

    +

    + L'intensità dello strato di lucentezza, da `0.0` a `1.0`. Il valore predefinito è `0.0`. +

    + +

    [property:Float sheenRoughness]

    +

    + Rugosità dello strato di lucentezza, da `0.0` a `1.0`. Il valore predefinito è `1.0`. +

    + +

    [property:Texture sheenRoughnessMap]

    +

    + Il canale alfa di questa texture è moltiplicato per [page:.sheenRoughness], + per controllare la rugosità della lucentezza per pixel. Il valore predefinito è `null`. +

    + +

    [property:Color sheenColor]

    +

    + La tinta brillante. Il valore predefinito è `0xffffff`, bianco. +

    + +

    [property:Texture sheenColorMap]

    +

    + I canali RGB della texture sono moltiplicati per [page:.sheenColor], + per controllare sulla tinta per pixel. Il valore predefinito è `null`. +

    + +

    [property:Float specularIntensity]

    +

    + Un float che ridimensiona la quantità di riflessione speculare solo per i non metalli. Quando è impostato su zero, il modello + è effettivamente Lambertiano. Da `0.0` a `1.0`. Il valore predefinito è `0.0`. +

    + +

    [property:Texture specularIntensityMap]

    +

    + Il canale alfa di questa texture è moltiplicato per [page:.specularIntensity], + per controllare l'intensità speculare per pixel. Il valore predefinito è `null`. +

    + +

    [property:Color specularColor]

    +

    + Un [page:Color] che tinge la riflessione speculare ad incidenza normale solo per i non metalli. + Il valore predefinito è `0xffffff`, bianco. +

    + +

    [property:Texture specularColorMap]

    +

    + I canali RGB di questa texture sono moltiplicati per [page:.specularColor], + per controllare il colore speculare per pixel. Il valore predefinito è `null`. +

    + +

    [property:Float thickness]

    +

    + Lo spessore del volume sotto la superficie. Il valore è dato nello spazio delle coordinate della mesh. + Se il valore è 0 il materiale è a parete sottile. Altrimenti il materiale è un limite di volume. Il valore predefinito è `0`. +

    + +

    [property:Texture thicknessMap]

    +

    + Una texture che definisce lo spessore, memorizzata nel canale G. Questo sarà moltiplicato per [page:.thickness]. + Il valore predefinito è `null`. +

    + +

    [property:Float transmission]

    +

    + Grado di trasmissione (o trasparenza ottica), da `0.0` a `1.0`. Il valore predefinito è `0.0`.
    + + I materiali sottili, trasparenti o semitrasparenti, in plastica o in vetro rimangono ampiamente + riflettenti anche se sono completamente trasmissivi. La proprietà di trasmissione può + essere utilizzata per modellare questi materiali.
    + + Quando la trasmissione è diversa da zero, l'[page:Material.opacity] deve essere impostata a `0`. +

    + +

    [property:Texture transmissionMap]

    +

    + Il canale rosso di questa texture è moltiplicato per [page:.transmission], + per controllare la trasparenza ottica per pixel. Il valore predefinito è `null`. +

    + +

    Metodi

    +

    Vedi le classi base [page:Material] e [page:MeshStandardMaterial] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/materials/MeshStandardMaterial.html b/docs/api/it/materials/MeshStandardMaterial.html new file mode 100644 index 00000000000000..3d7a5bb155260a --- /dev/null +++ b/docs/api/it/materials/MeshStandardMaterial.html @@ -0,0 +1,279 @@ + + + + + + + + + + [page:Material] → + +

    [name]

    + +

    + Un materiale standard a base fisica, che utilizza il flusso di lavoro Metallic-Roughness.

    + + Physically based rendering (PBR) è recentemente diventato uno standard in molte applicazioni 3D, come + [link:https://blogs.unity3d.com/2014/10/29/physically-based-shading-in-unity-5-a-primer/ Unity], + [link:https://docs.unrealengine.com/latest/INT/Engine/Rendering/Materials/PhysicallyBased/ Unreal] e + [link:http://area.autodesk.com/blogs/the-3ds-max-blog/what039s-new-for-rendering-in-3ds-max-2017 3D Studio Max].

    + + Questo approccio differisce da quelli precedenti per il fatto che, invece di utilizzare le approssimazioni + per il modo in cui la luce interagisce con una superficie, viene utilizzato un modello fisicamente corretto. + L'idea è che, invece di modificare i materiali per ottenere un buon risultato con un'illuminazione + specifica, è possibile creare un materiale che reagisca "correttamente" in tutti gli scenari di illuminazione.

    + + In pratica questo fornisce un risultato dall'aspetto più accurato e realistico rispetto a [page:MeshLambertMaterial] + o [page:MeshPhongMaterial], a costo di essere un po' più costoso dal punto di vista computazionale. + [name] utilizza l'ombreggiatura per-fragment.

    + + Si noti che per ottenere risultati migliori si deve sempre specificare una [page:.envMap mappa ambientale] + quando si utilizza questo materiale.

    + + Per un'introduzione non tecnica al concetto di PBR e come impostare il materiale PBR, + consulta questi articoli delle persone di [link:https://www.marmoset.co marmoset]: + +

      +
    • + [link:https://www.marmoset.co/posts/basic-theory-of-physically-based-rendering/ Basic Theory of Physically Based Rendering] +
    • +
    • + [link:https://www.marmoset.co/posts/physically-based-rendering-and-you-can-too/ Physically Based Rendering and You Can Too] +
    • +
    +

    +

    + Dettagli tecnici dell'approccio utilizzato in three.js (e altri sistemi PBR) possono essere trovati in questo + [link:https://media.disneyanimation.com/uploads/production/publication_asset/48/asset/s2012_pbs_disney_brdf_notes_v3.pdf articolo di Disney] (pdf), + di Brent Burley. +

    + + + + + +

    Costruttore

    + +

    [name]( [param:Object parameters] )

    +

    + [page:Object parameters] - (opzionale) un oggetto con una o più proprietà che definiscono l'aspetto del materiale. + Qualsiasi proprietà del materiale (inclusa qualsiasi proprietà ereditata da [page:Material]) può essere passata qui.

    + + L'eccezione è la proprietà [page:Hexadecimal colore], la quale può essere passata come stringa + esadecimale e per impostazione predefinita è `0xffffff` (bianco). [page:Color.set]( color ) viene chiamato internamente. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Material] per le proprietà comuni.

    + +

    [property:Texture alphaMap]

    +

    La mappa alfa è una texture in scala di grigi che controlla l'opacità sulla superficie + (nero: completamente trasparente; bianco: completamente opaco). Il valore predefinito è `null`.

    + + Viene utilizzato solo il colore della texture, ignorando il canale alfa, se esiste. + Per le texuture RGB e RGBA, il renderer [page:WebGLRenderer WebGL] utilizzarà il canale del verde + durante il campionamento di questa texture a causa del bit extra di precisione fornito per il verde + nei formati RGB 565 compressi e non compressi DXT. Anche le texture solo luminanza e luminanza/alfa continueranno + a funzionare come previsto. +

    + +

    [property:Texture aoMap]

    +

    Il canale rosso di questa texture viene utilizzato come la mappa di occlusione ambientale. Il valore + predefinito è `null`. AoMap richiede un secondo set di UV. +

    + +

    [property:Float aoMapIntensity]

    +

    L'intensità dell'effetto di occlusione ambientale. Il valore + predefinito è `1`. Zero non è un effetto di occlusione.

    + +

    [property:Texture bumpMap]

    +

    + La texture per creare una mappa di rilievo. I valori nero e bianco si associano alla profondità percepita in relazione + alle luci. Bump in realtà non influisce sulla geometria dell'oggetto, solo sull'illuminazione. Se viene definita una mappa + normale questa verrà ignorata. +

    + +

    [property:Float bumpScale]

    +

    Quanto la mappa di rilievo influisce sul materiale. Gli intervalli tipici sono 0-1. Il valore predefinito è 1.

    + + +

    [property:Color color]

    +

    [page:Color Colore] del materiale, il valore predefinito è impostato a bianco (0xffffff).

    + +

    [property:Object defines]

    +

    Un oggetto della forma: + + { 'STANDARD': '' }; + + + Questo viene utilizzato dal [page:WebGLRenderer] per selezionare gli shader. +

    + +

    [property:Texture displacementMap]

    +

    + La mappa di spostamento influisce sulla posizione dei vertici della mesh. + A differenza di altre mappe che influenzano solo la luce e l'ombra del materiale, i vertici + spostati possono proiettare ombre, bloccare altri oggetti, e altrimenti agire come una vera + geometria. La texture di spostamento è un'immagine in cui il valore di ciascun pixel (il bianco è + il più alto) viene mappato e riposizionato rispetto ai vertici della mesh. +

    + +

    [property:Float displacementScale]

    +

    + Quando la mappa di spostamento influenza la mesh (dove il nero non è lo spostamento, + e il bianco è lo spostamento massimo). Senza una mappa di spostamento impostata, questo valore + non viene applicato. + Il valore predefinito è 1. +

    + +

    [property:Float displacementBias]

    +

    + L'offset dei valori della mappa di spostamento sui vertici della mesh. + Senza una mappa di spostamento impostata, questo valore + non viene applicato. Il valore predefinito è 0. +

    + +

    [property:Color emissive]

    +

    + Colore emissivo (chiaro) per il materiale, essenzialmente un colore solido non influenzato + da altre luci. L'impostazione predefinita è nero. +

    + +

    [property:Texture emissiveMap]

    +

    + Imposta la mappa emissiva (bagliore). Il valore predefinito è `null`. Il colore della mappa emissiva + è modulato dal colore emissivo e dall'intensità emissiva. Se si dispone di una mappa emissiva, + assicurarsi di impostare il colore emissivo su qualcosa di diverso dal nero. +

    + +

    [property:Float emissiveIntensity]

    +

    Intensità della luce emissiva. Modula il colore emissivo. Il valore predefinito è `1`.

    + +

    [property:Texture envMap]

    +

    La mappa ambientale. Per assicurare un rendering fisicamente corretto, è necessario + aggiungere solo le mappe ambientali che sono state processate da [page:PMREMGenerator]. + Il valore predefinito è `null`.

    +

    + +

    [property:Float envMapIntensity]

    +

    Ridimensiona l'effetto della mappa ambientale moltiplicando il suo colore.

    + +

    [property:Boolean flatShading]

    +

    + Definisce se il materiale viene renderizzato con un'ombreggiatura piatta. Il valore predefinito è `false`. +

    + +

    [property:Boolean fog]

    +

    Indica se il materiale è influenzato dalla nebbia. Il valore predefinito è `true`.

    + +

    [property:Boolean isMeshStandardMaterial]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:Texture lightMap]

    +

    La mappa della luce. Il valore predefinito è `null`. La lightMap richiede un secondo set di UV.

    + +

    [property:Float lightMapIntensity]

    +

    Intensità della luce. Il valore predefinito è `1`.

    + +

    [property:Texture map]

    +

    + La mappa colore. Può includere facoltativamente un canale alfa, in genere combinato + con [page:Material.transparent .transparent] o [page:Material.alphaTest .alphaTest]. Il valore predefinito è `null`. + Il colore della mappa della texture è modulato dal [page:.color] diffuso. +

    + +

    [property:Float metalness]

    +

    + Quanto un materiale è come un metallo. I materiali non metallici come il legno o la pietra utilizzano il valore 0.0, quelli + metallici utilizzano il valore 1.0, senza (di solito) nulla nel mezzo. Il valore predefinito è 0.0. Un valore tra 0.0 e 1.0 potrebbe + essere utilizzato per un aspetto di metallo arrugginito. Se viene fornito anche metalnessMap, entrambi i valori vengono + moltiplicati. +

    + +

    [property:Texture metalnessMap]

    +

    Il canale blu di questa texture viene utilizzato per alterare la metallizzazione del materiale.

    + +

    [property:Texture normalMap]

    +

    + La texture per creare una mappa normale. I valori RGB influenzano la normale della superficie per ogni frammento di pixel + e cambiano il modo in cui il colore è illuminato. Le mappe normali non modificano la figura effettiva della superficie, + ma solo l'illuminazione. Nel caso in cui il materiale abbia una mappa normale creata utilizzando la convezione della mano + sinistra, la componente y di normalScale deve essere negata per compensare la diversa mano. +

    + +

    [property:Integer normalMapType]

    +

    + Il tipo di mappa normale.

    + + Le opzioni sono [page:constant THREE.TangentSpaceNormalMap] (impostazione predefinita), e [page:constant THREE.ObjectSpaceNormalMap]. +

    + +

    [property:Vector2 normalScale]

    +

    + Quanto la mappa normale influenza il materiale. Gli intervalli tipi sono 0-1. + Il valore predefinito è un [page:Vector2] impostato a (1,1). +

    + +

    [property:Float roughness]

    +

    + Quanto ruvido appare il materiale. 0.0 un riflesso speculare uniforme, 1.0 significa completamente diffuso. + Il valore predefinito è 1.0. Se viene fornita anche roughnessMap, entrambi i valori vengono moltiplicati. +

    + +

    [property:Texture roughnessMap]

    +

    Il canale verde di questa texture viene utilizzato per alterare la ruvidezza del materiale.

    + +

    [property:Boolean wireframe]

    +

    Rendering della geometria come wireframe. Il valore predefinito è `false` (cioè renderizzazione come poligoni piatti).

    + +

    [property:String wireframeLinecap]

    +

    + Definisce l'aspetto delle estremità della linea. I valori possibili sono "butt", "round" e "square". Il valore predefinito è 'round'.

    + + Questa corrisponde alla proprietà [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineCap 2D Canvas lineCap] + e viene ignorata dal renderer [page:WebGLRenderer WebGL]. +

    + +

    [property:String wireframeLinejoin]

    +

    + Definisce l'aspetto dei punti di unione della linea. I valori possibili sono "round", "bevel" e "miter". Il valore predefinito è 'round'.

    + + Questa corrisponde alla proprietà [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineJoin 2D Canvas lineJoin] + e viene ignorata dal renderer [page:WebGLRenderer WebGL]. +

    + +

    [property:Float wireframeLinewidth]

    +

    Controlla lo spessore del wireframe. Il valore predefinito è `1`.

    + + A causa delle limitazioni del [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf profilo OpenGL Core] + con il renderer [page:WebGLRenderer WebGL] sulla maggior parte delle piattaforme, + la larghezza di riga sarà sempre 1 indipendentemente dal valore impostato. +

    + +

    Metodi

    +

    Vedi la classe base [page:Material] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/materials/MeshToonMaterial.html b/docs/api/it/materials/MeshToonMaterial.html new file mode 100644 index 00000000000000..7c398a58411976 --- /dev/null +++ b/docs/api/it/materials/MeshToonMaterial.html @@ -0,0 +1,210 @@ + + + + + + + + + + [page:Material] → + +

    [name]

    + +
    Un materiale che implementa l'ombreggiatura dei cartoni animati (toon).
    + + + + + +

    Esempi

    +

    + [example:webgl_materials_variations_toon materials / variations / toon] +

    + +

    Costruttore

    + +

    [name]( [param:Object parameters] )

    +

    + [page:Object parameters] - (opzionale) un oggetto con una o più proprietà che definiscono l'aspetto del materiale. + Qualsiasi proprietà del materiale (inclusa qualsiasi proprietà ereditata da [page:Material]) può essere passata qui.

    + + L'eccezione è la proprietà [page:Hexadecimal colore], la quale può essere passata come stringa + esadecimale e per impostazione predefinita è `0xffffff` (bianco). [page:Color.set]( color ) viene chiamato internamente. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Material] per le proprietà comuni.

    + +

    [property:Texture alphaMap]

    +

    + La mappa alfa è una texture in scala di grigi che controlla l'opacità sulla superficie + (nero: completamente trasparente; bianco: completamente opaco). Il valore predefinito è `null`.

    + + Viene utilizzato solo il colore della texture, ignorando il canale alfa, se esiste. + Per le texuture RGB e RGBA, il renderer [page:WebGLRenderer WebGL] utilizzarà il canale del verde + durante il campionamento di questa texture a causa del bit extra di precisione fornito per il verde + nei formati RGB 565 compressi e non compressi DXT. Anche le texture solo luminanza e luminanza/alfa continueranno + a funzionare come previsto. +

    + +

    [property:Texture aoMap]

    +

    + Il canale rosso di questa texture viene utilizzato come la mappa di occlusione ambientale. Il valore + predefinito è `null`. AoMap richiede un secondo set di UV. +

    + +

    [property:Float aoMapIntensity]

    +

    L'intensità dell'effetto di occlusione ambientale. Il valore + predefinito è `1`. Zero non è un effetto di occlusione. +

    + +

    [property:Texture bumpMap]

    +

    + La texture per creare una mappa di rilievo. I valori nero e bianco si associano alla profondità percepita in relazione + alle luci. Bump in realtà non influisce sulla geometria dell'oggetto, solo sull'illuminazione. Se viene definita una mappa + normale questa verrà ignorata. +

    + +

    [property:Float bumpScale]

    +

    Quanto la mappa di rilievo influisce sul materiale. Gli intervalli tipici sono 0-1. Il valore predefinito è 1.

    + + +

    [property:Color color]

    +

    [page:Color Colore] del materiale, il valore predefinito è impostato a bianco (0xffffff).

    + +

    [property:Texture displacementMap]

    +

    + La mappa di spostamento influisce sulla posizione dei vertici della mesh. + A differenza di altre mappe che influenzano solo la luce e l'ombra del materiale, i vertici + spostati possono proiettare ombre, bloccare altri oggetti, e altrimenti agire come una vera + geometria. La texture di spostamento è un'immagine in cui il valore di ciascun pixel (il bianco è + il più alto) viene mappato e riposizionato rispetto ai vertici della mesh. +

    + +

    [property:Float displacementScale]

    +

    + Quando la mappa di spostamento influenza la mesh (dove il nero non è lo spostamento, + e il bianco è lo spostamento massimo). Senza una mappa di spostamento impostata, questo valore + non viene applicato. + Il valore predefinito è 1. +

    + +

    [property:Float displacementBias]

    +

    + L'offset dei valori della mappa di spostamento sui vertici della mesh. + Senza una mappa di spostamento impostata, questo valore + non viene applicato. Il valore predefinito è 0. +

    + +

    [property:Color emissive]

    +

    + Colore emissivo (chiaro) per il materiale, essenzialmente un colore solido non influenzato + da altre luci. L'impostazione predefinita è nero. +

    + +

    [property:Texture emissiveMap]

    +

    + Imposta la mappa emissiva (bagliore). Il valore predefinito è `null`. Il colore della mappa emissiva + è modulato dal colore emissivo e dall'intensità emissiva. Se si dispone di una mappa emissiva, + assicurarsi di impostare il colore emissivo su qualcosa di diverso dal nero. +

    + +

    [property:Float emissiveIntensity]

    +

    Intensità della luce emissiva. Modula il colore emissivo. Il valore predefinito è `1`.

    + +

    [property:Boolean fog]

    +

    Indica se il materiale è influenzato dalla nebbia. Il valore predefinito è `true`.

    + +

    [property:Texture gradientMap]

    +

    + Mappa del gradiente per l'ombreggiatura dei cartoni animati. + È necessario impostare [page:Texture.minFilter] e [page:Texture.magFilter] a [page:Textures THREE.NearestFilter] + quando si utilizza quest tipo di texture. + Il valore predefinito è `null`.

    + +

    [property:Texture lightMap]

    +

    La mappa della luce. Il valore predefinito è `null`. La lightMap richiede un secondo set di UV.

    + +

    [property:Float lightMapIntensity]

    +

    Intensità della luce. Il valore predefinito è `1`.

    + +

    [property:Texture map]

    +

    + La mappa colore. Può includere facoltativamente un canale alfa, in genere combinato + con [page:Material.transparent .transparent] o [page:Material.alphaTest .alphaTest]. Il valore predefinito è `null`. + La mappa colore della texture è mudulata dal [page:.color colore] diffuso. +

    + +

    [property:Texture normalMap]

    +

    + La texture per creare una mappa normale. I valori RGB influenzano la normale della superficie per ogni frammento di pixel + e cambiano il modo in cui il colore è illuminato. Le mappe normali non modificano la figura effettiva della superficie, + ma solo l'illuminazione. Nel caso in cui il materiale abbia una mappa normale creata utilizzando la convezione della mano + sinistra, la componente y di normalScale deve essere negata per compensare la diversa mano. +

    + +

    [property:Integer normalMapType]

    +

    + Il tipo di mappa normale.

    + + Le opzioni sono [page:constant THREE.TangentSpaceNormalMap] (impostazione predefinita), e [page:constant THREE.ObjectSpaceNormalMap]. +

    + +

    [property:Vector2 normalScale]

    +

    + Quanto la mappa normale influenza il materiale. Gli intervalli tipici sono 0-1. + Il valore predefinito è un [page:Vector2] impostato a (1,1). +

    + +

    [property:Boolean wireframe]

    +

    Rendering della geometria come wireframe. Il valore predefinito è `false` (cioè renderizzazione come poligoni piatti).

    + +

    [property:String wireframeLinecap]

    +

    + Definisce l'aspetto delle estremità della linea. I valori possibili sono "butt", "round" e "square". Il valore predefinito è 'round'.

    + + Questa corrisponde alla proprietà [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineCap 2D Canvas lineCap] + e viene ignorata dal renderer [page:WebGLRenderer WebGL]. +

    + +

    [property:String wireframeLinejoin]

    +

    + Definisce l'aspetto dei punti di unione della linea. I valori possibili sono "round", "bevel" e "miter". Il valore predefinito è 'round'.

    + + Questa corrisponde alla proprietà [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineJoin 2D Canvas lineJoin] + e viene ignorata dal renderer [page:WebGLRenderer WebGL]. +

    + +

    [property:Float wireframeLinewidth]

    +

    Controlla lo spessore del wireframe. Il valore predefinito è `1`.

    + + A causa delle limitazioni del [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf profilo OpenGL Core] + con il renderer [page:WebGLRenderer WebGL] sulla maggior parte delle piattaforme, + la larghezza di riga sarà sempre 1 indipendentemente dal valore impostato. +

    + +

    Metodi

    +

    Vedi la classe base [page:Material] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/materials/PointsMaterial.html b/docs/api/it/materials/PointsMaterial.html new file mode 100644 index 00000000000000..3abe4d6d07e492 --- /dev/null +++ b/docs/api/it/materials/PointsMaterial.html @@ -0,0 +1,116 @@ + + + + + + + + + + [page:Material] → + +

    [name]

    + +

    Il materiale predefinito utilizzato da [page:Points].

    + +

    Codice di Esempio

    + + const vertices = []; + + for ( let i = 0; i < 10000; i ++ ) { + + const x = THREE.MathUtils.randFloatSpread( 2000 ); + const y = THREE.MathUtils.randFloatSpread( 2000 ); + const z = THREE.MathUtils.randFloatSpread( 2000 ); + + vertices.push( x, y, z ); + + } + + const geometry = new THREE.BufferGeometry(); + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); + + const material = new THREE.PointsMaterial( { color: 0x888888 } ); + + const points = new THREE.Points( geometry, material ); + + scene.add( points ); + + +

    Esempi

    +

    + [example:misc_controls_fly misc / controls / fly]
    + [example:webgl_buffergeometry_drawrange WebGL / BufferGeometry / drawrange]
    + [example:webgl_buffergeometry_points WebGL / BufferGeometry / points]
    + [example:webgl_buffergeometry_points_interleaved WebGL / BufferGeometry / points / interleaved]
    + [example:webgl_camera WebGL / camera ]
    + [example:webgl_geometry_convex WebGL / geometry / convex]
    + [example:webgl_geometry_shapes WebGL / geometry / shapes]
    + [example:webgl_interactive_raycasting_points WebGL / interactive / raycasting / points]
    + [example:webgl_multiple_elements_text WebGL / multiple / elements / text]
    + [example:webgl_points_billboards WebGL / points / billboards]
    + [example:webgl_points_dynamic WebGL / points / dynamic]
    + [example:webgl_points_sprites WebGL / points / sprites]
    + [example:webgl_trails WebGL / trails] +

    + +

    Costruttore

    +

    [name]( [param:Object parameters] )

    +

    + [page:Object parameters] - (opzionale) un oggetto con una o più proprietà che definiscono l'aspetto del materiale. + Qualsiasi proprietà del materiale (inclusa qualsiasi proprietà ereditata da [page:Material]) può essere passata qui.

    + + L'eccezione è la proprietà [page:Hexadecimal colore], la quale può essere passata come stringa + esadecimale e per impostazione predefinita è `0xffffff` (bianco). [page:Color.set]( color ) viene chiamato internamente. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Material] per le proprietà comuni.

    + +

    [property:Texture alphaMap]

    +

    + La mappa alfa è una texture in scala di grigi che controlla l'opacità sulla superficie + (nero: completamente trasparente; bianco: completamente opaco). Il valore predefinito è `null`.

    + + Viene utilizzato solo il colore della texture, ignorando il canale alfa, se esiste. + Per le texuture RGB e RGBA, il renderer [page:WebGLRenderer WebGL] utilizzarà il canale del verde + durante il campionamento di questa texture a causa del bit extra di precisione fornito per il verde + nei formati RGB 565 compressi e non compressi DXT. Anche le texture solo luminanza e luminanza/alfa continueranno + a funzionare come previsto. +

    + +

    [property:Color color]

    +

    Il [page:Color Colore] del materiale, da impostazione predefinita impostato su bianco (0xffffff).

    + +

    [property:Boolean fog]

    +

    Indica se il materiale è influenzato dalla nebbia. Il valore predefinito è `true`.

    + +

    [property:Texture map]

    +

    + Imposta il colore dei punti utilizzando i dati da una [page:Texture]. + Può includere facoltativamente un canale alfa, in genere combinato con + [page:Material.transparent .transparent] o [page:Material.alphaTest .alphaTest]. +

    + +

    [property:Number size]

    +

    + Definisce la dimensione dei punti in pixel. Il valore predefinito è 1.0.
    + Verrà limitato se supera il parametro dipendetente dall'hardware [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/getParameter gl.ALIASED_POINT_SIZE_RANGE]. +

    + +

    [property:Boolean sizeAttenuation]

    +

    + Specifica se la dimensione dei punti viene attenuata dalla profondità della telecamera. (Solo telecamera prospettica). + Il valore predefinito è `true`. +

    + +

    Metodi

    +

    Vedi la classe base [page:Material] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/materials/RawShaderMaterial.html b/docs/api/it/materials/RawShaderMaterial.html new file mode 100644 index 00000000000000..32f3aa69f20613 --- /dev/null +++ b/docs/api/it/materials/RawShaderMaterial.html @@ -0,0 +1,64 @@ + + + + + + + + + + [page:Material] → [page:ShaderMaterial] → + +

    [name]

    + +

    + Questa classe lavora in maniera simile a [page:ShaderMaterial], tranne per il fatto che + le definizioni delle uniformi e degli attributi incorporati non vengono automaticamente + anteposte al codice dello shader GLSL. +

    + +

    Codice di Esempio

    + + const material = new THREE.RawShaderMaterial( { + + uniforms: { + time: { value: 1.0 } + }, + vertexShader: document.getElementById( 'vertexShader' ).textContent, + fragmentShader: document.getElementById( 'fragmentShader' ).textContent, + + } ); + + +

    Esempi

    +

    + [example:webgl_buffergeometry_rawshader WebGL / buffergeometry / rawshader]
    + [example:webgl_buffergeometry_instancing_billboards WebGL / buffergeometry / instancing / billboards]
    + [example:webgl_buffergeometry_instancing WebGL / buffergeometry / instancing]
    + [example:webgl_raymarching_reflect WebGL / raymarching / reflect]
    + [example:webgl2_volume_cloud WebGL 2 / volume / cloud]
    + [example:webgl2_volume_instancing WebGL 2 / volume / instancing]
    + [example:webgl2_volume_perlin WebGL 2 / volume / perlin] +

    + +

    Costruttore

    + +

    [name]( [param:Object parameters] )

    +

    + [page:Object parameters] - (opzionale) un oggetto con una o più proprietà che definiscono l'aspetto del materiale. + Qualsiasi proprietà del materiale (inclusa qualsiasi proprietà ereditata da [page:Material] e [page:ShaderMaterial]) può essere passata qui.

    +

    + +

    Proprietà

    +

    Vedi le classi base [page:Material] e [page:ShaderMaterial] per le proprietà comuni.

    + +

    Metodi

    +

    Vedi le classi base [page:Material] e [page:ShaderMaterial] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/materials/ShaderMaterial.html b/docs/api/it/materials/ShaderMaterial.html new file mode 100644 index 00000000000000..94663209c4c0ad --- /dev/null +++ b/docs/api/it/materials/ShaderMaterial.html @@ -0,0 +1,446 @@ + + + + + + + + + + [page:Material] → + +

    [name]

    + +

    + Un materiale renderizzato con shader personalizzati. Uno shader è un piccolo programma scritto in + [link:https://www.khronos.org/files/opengles_shading_language.pdf GLSL] + che viene eseguito sulla GPU. + Potresti voler utilizzare uno shader personalizzato se hai bisogno di: +

      +
    • implementare un effetto non incluso in nessuno dei [page:Material materiali] incorporati
    • +
    • combinare più oggetti in una singola [page:BufferGeometry] per migliorare le prestazioni
    • +
    + Di seguito ci sono delle informazioni da tenere a mente quando si utilizza uno `ShaderMaterial`: + +
      +
    • + Uno `ShaderMaterial` sarà renderizzato corretamente solo da [page:WebGLRenderer], + poiché il codice GLSL nelle proprietà [link:https://en.wikipedia.org/wiki/Shader#Vertex_shaders vertexShader] + e [link:https://en.wikipedia.org/wiki/Shader#Pixel_shaders fragmentShader] deve essere compilato ed eseguito + sulla GPU utilizzando WebGL. +
    • +
    • + A partire da THREE r72, l'assegnazione diretta di attributi in uno ShaderMaterial non è più supportata. + È invece necessario utilizzare un'istanza di [page:BufferGeometry], utilizzando le istanze [page:BufferAttribute] + per definire gli attributi personalizzati. +
    • +
    • + A partire da THREE r77, le istanze [page:WebGLRenderTarget] o [page:WebGLCubeRenderTarget] + non devono essere più utilizzate come uniformi. Al loro posto è necessario utilizzare la loro proprietà [page:Texture texture]. +
    • +
    • + Gli attributi e le uniformi integrati vengono passati agli shader insieme al codice. + Se non vuoi che [page:WebGLProgram] aggiunga nulla al tuo codice shader, puoi usare [page:RawShaderMaterial] invece di questa classe. +
    • +
    • + È possibile utilizzare la direttiva #pragma unroll_loop_start e #pragma unroll_loop_end per srotolare un ciclo `for` in GLSL dal preprocessore dello shader. + La direttiva deve essere posizionata proprio sopra il cilo. + La formattazione del ciclo deve corrispondere a uno standard definito. +
        +
      • + Il loop deve essere [link:https://en.wikipedia.org/wiki/Normalized_loop normalizzato]. +
      • +
      • + La variabile del loop deve essere *i*. +
      • +
      • + Il valore `UNROLLED_LOOP_INDEX` sarà sostituito con il valore esplicito di *i* per l'iterazione data e può essere + utilizzato nelle istruzioni del preprocessore. +
      • +
      + + #pragma unroll_loop_start + for ( int i = 0; i < 10; i ++ ) { + + // ... + + } + #pragma unroll_loop_end + +
    • +
    +

    + +

    Codice di Esempio

    + + + const material = new THREE.ShaderMaterial( { + + uniforms: { + + time: { value: 1.0 }, + resolution: { value: new THREE.Vector2() } + + }, + + vertexShader: document.getElementById( 'vertexShader' ).textContent, + + fragmentShader: document.getElementById( 'fragmentShader' ).textContent + + } ); + + +

    Esempi

    + +

    + [example:webgl_buffergeometry_custom_attributes_particles webgl / buffergeometry / custom / attributes / particles]
    + [example:webgl_buffergeometry_selective_draw webgl / buffergeometry / selective / draw]
    + [example:webgl_custom_attributes webgl / custom / attributes]
    + [example:webgl_custom_attributes_lines webgl / custom / attributes / lines]
    + [example:webgl_custom_attributes_points webgl / custom / attributes / points]
    + [example:webgl_custom_attributes_points2 webgl / custom / attributes / points2]
    + [example:webgl_custom_attributes_points3 webgl / custom / attributes / points3]
    + [example:webgl_depth_texture webgl / depth / texture]
    + [example:webgl_gpgpu_birds webgl / gpgpu / birds]
    + [example:webgl_gpgpu_protoplanet webgl / gpgpu / protoplanet]
    + [example:webgl_gpgpu_water webgl / gpgpu / water]
    + [example:webgl_interactive_points webgl / interactive / points]
    + [example:webgl_video_kinect webgl / video / kinect]
    + [example:webgl_lights_hemisphere webgl / lights / hemisphere]
    + [example:webgl_marchingcubes webgl / marchingcubes]
    + [example:webgl_materials_envmaps webgl / materials / envmaps]
    + [example:webgl_materials_lightmap webgl / materials / lightmap]
    + [example:webgl_materials_wireframe webgl / materials / wireframe]
    + [example:webgl_modifier_tessellation webgl / modifier / tessellation]
    + [example:webgl_postprocessing_dof2 webgl / postprocessing / dof2]
    + [example:webgl_postprocessing_godrays webgl / postprocessing / godrays] +

    + +

    Vertex shader e fragment shader

    + +
    +

    Si possono specificare due differenti tipi di shader per ogni materiale:

    +
      +
    • + Il vertex shader viene eseguito per primo; riceve gli `attributes` (attributi), calcola / manipola + la posizione di ogni singolo vertice, e passa valori aggiuntivi (`varying`) al fragment shader. +
    • +
    • + Il fragment (o pixel) shader viene eseguito per secondo; imposta il colore di ogni singolo "fragment" (pixel) + visualizzato nello schermo. +
    • +
    +

    Ci sono tre tipi di variabili negli shader: uniforms (uniformi), attributes (attributi), e varyings (variazioni):

    +
      +
    • + `Uniforms` sono variabili che hanno lo stesso valore per tutti i vertici - mappe di illuminazione, nebbia, + e mappe di ombreggiatura sono esempi di dati che verrebbero memorizzati nelle variabili uniformi. + È possibile accedere a queste varibili sia dal vertex shader sia dal fragment shader. +
    • +
    • + `Attributes` sono variabili associate ad ogni vertice; ad esempio, la posizione del vertice, + la normale della faccia e il colore del vertice sono tutti esempi di dati che dovrebbero essere + memorizzati negli attributi. Si può accedere a queste variabili `solo` dal vertex shader. +
    • +
    • + `Varyings` sono variabili che vengono passate da il vertex shader al fragment shader. + Per ogni fragment, il valore di ogni variazione sarà interpolato senza problemi dai valori dei vertici adiacenti. +
    • +
    +

    + Si noti che `all'interno` dello shader stesso, uniforms e attributes agiscono come costanti; + si può solo modificare i loro valori passando valori diversi ai buffer dal codice JavaScript. +

    +
    + + +

    Attributi e uniformi incorporati

    + +
    +

    + Il [page:WebGLRenderer] fornisce da impostazione predefinita molti attributi e uniformi agli shader; + le definizioni di queste variabili vengono anteposte al codice `fragmentShader` e `vertexShader` dal + [page:WebGLProgram] quando lo shader viene compilato; non è necessario che li dichiari tu stesso. + Vedi [page:WebGLProgram] per il dettaglio di queste variabili. +

    +

    + Alcune di queste uniformi o attributi (per esempio quelli relativi all'illuminazione, alla nebbia, etc.) + richiedono l'impostazione delle proprietà sul materiale affinché [page:WebGLRenderer] possa + copiare i valori appropriati alla GPU - assicurati di impostare questi flag se vuoi utilizzare + queste funzionalità nel tuo shader. +

    +

    + Se non vuoi che [page:WebGLProgram] aggiungera niente al tuo codice shader, puoi usare + [page:RawShaderMaterial] invece di questa classe. +

    +
    + + +

    Attributi e uniformi personalizzate

    + +
    +

    + Sia gli attributi personalizzati che le uniformi personalizzate devono essere dichiarate nel + tuo codice shader GLSL (all'interno di `vertexShader` e/o `fragmentShader`). + Le uniformi personalizzate devono essere definite in `entrambe` le proprietà `uniforms` del tuo `ShaderMaterial`, + mentre qualsiasi attributo personalizzato deve essere definito tramite le istanze di [page:BufferAttribute]. + Si noti che è necessario dichiarare le variazioni solo all'interno del codice shader (non all'iterno del materiale). +

    +

    + Per dichiarare un attributo personalizzato, fare riferimento alla pagina [page:BufferGeometry] per una panoramica, + e la pagina [page:BufferAttribute] per uno sguardo dettagliato alle API `BufferAttribute`. +

    +

    + Quando crei i tuoi attributi, ogni array tipizzato che crei per contenere i + dati del tuo attributo deve essere multiplo della dimensione del tuo tipo di dati. + Per esempio, se il tuo attributo è di tipo [page:Vector3 THREE.Vector3], e hai 3000 vertici + nel tuo [page:BufferGeometry], il valore del tuo array tipizzato deve essere creato con una + lunghezza di 3000 * 3, o 9000 (un valore per componente). + Di seguito viene mostrata una tabella delle dimensioni di ciascun tipo di dati come riferimento: +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Dimensioni attributi
    Tipo GLSLTipo JavaScriptDimensione
    float[page:Number]1
    vec2[page:Vector2 THREE.Vector2]2
    vec3[page:Vector3 THREE.Vector3]3
    vec3[page:Color THREE.Color]3
    vec4[page:Vector4 THREE.Vector4]4
    + +

    + Si noti che i buffer degli attributi `non` vengono aggiornati automaticamente quando i loro valori cambiano. + Per aggiornare gli attributi personalizzati, imposta il flag `needsUpdate` a true sul [page:BufferAttribute] + della geometria (vedi [page:BufferGeometry] per maggiori dettagli). +

    + +

    + Per dichiarare una [page:Uniform] personalizzata, utilizzare la proprietà `uniforms`: + +uniforms: { + time: { value: 1.0 }, + resolution: { value: new THREE.Vector2() } +} + +

    + +

    + Si consiglia di aggiornare i valori di [page:Uniform] personalizzati in base all'[page:Object3D object] e alla [page:Camera telecamera] + in [page:Object3D.onBeforeRender] poiché il [page:Material Materiale] può essere condiviso tra le [page:Mesh mesh], + la [page:Matrix4 matrixWorld] della [page:Scene scena] e la [page:Camera telecamera] viene aggiornata in [page:WebGLRenderer.render], + e alcuni effetti eseguono il rendering di una scena con le proprie [page:Camera telecamere] private. +

    + +
    + +

    Costruttore

    + +

    [name]( [param:Object parameters] )

    +

    + [page:Object parameters] - (opzionale) un oggetto con una o più proprietà che definiscono l'aspetto del materiale. + Qualsiasi proprietà del materiale (inclusa qualsiasi proprietà ereditata da [page:Material]) può essere passata qui. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Material] per le proprietà comuni.

    + +

    [property:Boolean clipping]

    +

    + Definisce se questo materiale supporta il clipping; true per consetire al renderer di passare l'uniforme di clippingPlanes. + L'impostazione predefinita è `false`. +

    + +

    [property:Object defaultAttributeValues]

    +

    + Quando la geometria renderizzata non include questi attributi ma il materiale sì, + questi valori predefiniti verranno passati agli shader. Ciò evita errori quando mancano i dati del buffer. + + +this.defaultAttributeValues = { + 'color': [ 1, 1, 1 ], + 'uv': [ 0, 0 ], + 'uv2': [ 0, 0 ] +}; + + +

    + + +

    [property:Object defines]

    +

    + Definisce le costanti personalizzate utilizzando le direttive `#define` nel codice GLSL sia per + il vertex shader che il fragment shader; ogni coppia chiave/valore produce un'altra direttiva: + + defines: { + FOO: 15, + BAR: true + } + + restituisce le linee + + #define FOO 15 + #define BAR true + + nel codice GLSL. +

    + +

    [property:Object extensions]

    +

    + Un oggetto con le seguenti proprietà: + +this.extensions = { + derivatives: false, // impostato per utilizzare le direttive + fragDepth: false, // impostato per utilizzare i valori di profondità del frammento + drawBuffers: false, // impostato per utilizzare i buffer di disegno + shaderTextureLOD: false // impostato per utilizzare la texture dello shader LOD +}; + +

    + + +

    [property:Boolean fog]

    +

    + Definisce se il colore del materiale è influenzato dalle impostazioni globali della nebbia. + true per passare le uniformi allo shader. + Il valore predefinito è `false`. +

    + +

    [property:String fragmentShader]

    +

    + Codice GLSL del fragment shader. Questo è il codice effettivo per lo shader. + Nell'esempio sopra, il codice `vertexShader` e `fragmentShader` viene estratto dal DOM; + potrebbe essere passato come stringa direttamente o caricato tramite AJAX. +

    + +

    [property:String glslVersion]

    +

    + Definisce la versione GLSL del codice dello shader personalizzato. Rilevante solo per WebGL 2 per definire se + specificare o meno GLSL 3.0. I valori validi sono `THREE.GLSL1` o `THREE.GLSL3`. Il valore predefinito è `null`. +

    + +

    [property:String index0AttributeName]

    +

    + Se impostato, questo chiama [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindAttribLocation gl.bindAttribLocation] + per associare un indice di vertice generico a una variabile di attributo. + Il valore predefinito è `undefined`. +

    + +

    [property:Boolean isShaderMaterial]

    +

    + Flag di sola lettura per verificare se l'oggetto passato è di tipo [name]. +

    + +

    [property:Boolean lights]

    +

    + Definisce se questo materiale utilizza l'illuminazione; true per trasmettere dati uniformi relativi all'illuminazione + a questo shader. L'impostazione predefinita è `false`. +

    + +

    [property:Float linewidth]

    +

    Controlla lo spessore del wireframe. Il valore predefinito è `1`.

    + + A causa delle limitazioni del [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf profilo OpenGL Core] + con il renderer [page:WebGLRenderer WebGL] sulla maggior parte delle piattaforme, + la larghezza di riga sarà sempre 1 indipendentemente dal valore impostato. +

    + +

    [property:Boolean flatShading]

    +

    + Definisce se il materiale viene renderizzato con un'ombreggiatura piatta. Il valore predefinito è `false`. +

    + +

    [property:Object uniforms]

    +

    + Un oggetto della forma: + +{ "uniform1": { value: 1.0 }, "uniform2": { value: 2 } } + + specificando le uniformi da passare al codice dello shader; la chiave è il nome della uniform, il valore è la definizione del modulo + + { value: 1.0 } + + dove `value` è il valore della uniforme. I nomi devono corrispondere al nome della uniforme, + come definito nel codice GLSL. Si noti che le uniformi vengono aggiornate su ogni frame, + quindi l'aggiornamento del valore della uniforme aggiornerà immediatamente il valore disponinbile per il codice GLSL. +

    + +

    [property:Boolean uniformsNeedUpdate]

    +

    + Può essere utilizzata per forzare un aggiornamento della uniform durante la modifica delle uniformi in + [page:Object3D.onBeforeRender](). Il valore predefinito è `false`. +

    + +

    [property:Boolean vertexColors]

    +

    + Definisce se viene utilizzata la colorazione dei vertici. Il valore predefinito è `false`. +

    + +

    [property:String vertexShader]

    +

    + Il codice GLSL del vertex shader. Questo è il codice effettivo per lo shader. + Nell'esempio sopra, il codice `vertexShader` e `fragmentShader` viene estratto dal DOM; + potrebbe essere passato come stringa direttamente o caricato tramite AJAX. +

    + +

    [property:Boolean wireframe]

    +

    + Rendering della geometria come wireframe (utilizzando GL_LINES instead of GL_TRIANGLES). + Il valore predefinito è `false` (cioè renderizzazione come poligoni piatti). +

    + +

    [property:Float wireframeLinewidth]

    +

    Controlla lo spessore del wireframe. Il valore predefinito è `1`.

    + + A causa delle limitazioni del [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf profilo OpenGL Core] + con il renderer [page:WebGLRenderer WebGL] sulla maggior parte delle piattaforme, + la larghezza di riga sarà sempre 1 indipendentemente dal valore impostato. +

    + +

    Metodi

    +

    Vedi la classe base [page:Material] per i metodi comuni.

    + +

    [method:ShaderMaterial clone]() [param:ShaderMaterial this]

    +

    + Genera una copia superficiale di questo materiale. Si noti che il vertexShader e il fragmentShader + sono copiati `per riferimento`, così come le definizioni degli `attributi`; questo significa + che i cloni del materiale condivideranno lo stesso [page:WebGLProgram] compilato. + Tuttavia, le uniform vengono copiate in base al `valore`, il che consente di avere diversi set + di uniformi per diverse copie del materiale. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/materials/ShadowMaterial.html b/docs/api/it/materials/ShadowMaterial.html new file mode 100644 index 00000000000000..e43037f2a8c371 --- /dev/null +++ b/docs/api/it/materials/ShadowMaterial.html @@ -0,0 +1,68 @@ + + + + + + + + + + [page:Material] → + +

    [name]

    + +

    + Questo materiale può ricevere le ombre, ma per il resto è completamente trasparente. +

    + +

    Codice di Esempio

    + + + const geometry = new THREE.PlaneGeometry( 2000, 2000 ); + geometry.rotateX( - Math.PI / 2 ); + + const material = new THREE.ShadowMaterial(); + material.opacity = 0.2; + + const plane = new THREE.Mesh( geometry, material ); + plane.position.y = -200; + plane.receiveShadow = true; + scene.add( plane ); + + +

    Esempi

    + +

    + [example:webgl_geometry_spline_editor geometry / spline / editor] +

    + +

    Costruttore

    + +

    [name]( [param:Object parameters] )

    +

    + [page:Object parameters] - (opzionale) un oggetto con una o più proprietà che definiscono l'aspetto del materiale. + Qualsiasi proprietà del materiale (inclusa qualsiasi proprietà ereditata da [page:Material]) può essere passata qui.

    +

    + +

    Proprietà

    +

    Vedi la classe base [page:Material] per le proprietà comuni.

    + +

    [property:Color color]

    +

    [page:Color Colore] del materiale, il valore predefinito è impostato a nero (0x000000).

    + +

    [property:Boolean fog]

    +

    Indica se il materiale è influenzato dalla nebbia. Il valore predefinito è `true`.

    + +

    [property:Boolean transparent]

    +

    Definisce se questo materiale è trasparente. Il valore predefinito è `true`.

    + +

    Metodi

    +

    Vedi la classe base [page:Material] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/materials/SpriteMaterial.html b/docs/api/it/materials/SpriteMaterial.html new file mode 100644 index 00000000000000..95471dd6150689 --- /dev/null +++ b/docs/api/it/materials/SpriteMaterial.html @@ -0,0 +1,100 @@ + + + + + + + + + + [page:Material] → + +

    [name]

    + +

    Un materiale da utilizzare con una [page:Sprite].

    + +

    Codice di Esempio

    + + + const map = new THREE.TextureLoader().load( 'textures/sprite.png' ); + const material = new THREE.SpriteMaterial( { map: map, color: 0xffffff } ); + + const sprite = new THREE.Sprite( material ); + sprite.scale.set(200, 200, 1) + scene.add( sprite ); + + +

    Esempi

    +

    + [example:webgl_raycaster_sprite WebGL / raycast / sprite]
    + [example:webgl_sprites WebGL / sprites]
    + [example:svg_sandbox SVG / sandbox] +

    + +

    Costruttore

    + +

    [name]( [param:Object parameters] )

    +

    + [page:Object parameters] - (opzionale) un oggetto con una o più proprietà che definiscono l'aspetto del materiale. + Qualsiasi proprietà del materiale (inclusa qualsiasi proprietà ereditata da [page:Material]) può essere passata qui.

    + + L'eccezione è la proprietà [page:Hexadecimal colore], la quale può essere passata come stringa + esadecimale e per impostazione predefinita è `0xffffff` (bianco). [page:Color.set]( color ) viene chiamato internamente. + + Gli SpriteMaterials non vengono ritagliati utilizzando [page:Material.clippingPlanes]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Material] per le proprietà comuni.

    + +

    [property:Texture alphaMap]

    +

    + La mappa alfa è una texture in scala di grigi che controlla l'opacità sulla superficie + (nero: completamente trasparente; bianco: completamente opaco). Il valore predefinito è `null`.

    + + Viene utilizzato solo il colore della texture, ignorando il canale alfa, se esiste. + Per le texuture RGB e RGBA, il renderer [page:WebGLRenderer WebGL] utilizzarà il canale del verde + durante il campionamento di questa texture a causa del bit extra di precisione fornito per il verde + nei formati RGB 565 compressi e non compressi DXT. Anche le texture solo luminanza e luminanza/alfa continueranno + a funzionare come previsto. +

    + +

    [property:Color color]

    +

    [page:Color Colore] del materiale, il valore predefinito è impostato a bianco (0xffffff). La [page:.map] viene moltiplicata per il colore.

    + +

    [property:Boolean fog]

    +

    Indica se il materiale è influenzato dalla nebbia. Il valore predefinito è `true`.

    + +

    [property:Boolean isSpriteMaterial]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:Texture map]

    +

    + La mappa colore. Può includere facoltativamente un canale alfa, in genere combinato + con [page:Material.transparent .transparent] o [page:Material.alphaTest .alphaTest]. Il valore predefinito è `null`. +

    + +

    [property:Radians rotation]

    +

    La rotazione della Sprite in radianti. Il valore predefinito è `0`.

    + +

    [property:Boolean sizeAttenuation]

    +

    + Indica se la dimensione della sprite viene attenuata dalla profondità della telecamera. (Solo telecamera prosepettica). + Il valore predefinito è `true`. +

    + +

    [property:Boolean transparent]

    +

    Definisce se il materiale è trasparente. Il valore predefinto è `true`.

    + +

    Metodi

    +

    Vedi la classe base [page:Material] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Box2.html b/docs/api/it/math/Box2.html new file mode 100644 index 00000000000000..9fa9989737fd58 --- /dev/null +++ b/docs/api/it/math/Box2.html @@ -0,0 +1,211 @@ + + + + + + + + + +

    [name]

    + +

    + Rappresenta un bounding box (rettangolo di selezione) allineato all'asse (AABB) nello spazio 2D. +

    + + +

    Costruttore

    + + +

    [name]( [param:Vector2 min], [param:Vector2 max] )

    +

    + [page:Vector2 min] - (opzionale) [page:Vector2] che rappresenta il limite inferiore (x, y) del box. + Il valore predefinito è ( + Infinito, + Infinito ).
    + + [page:Vector2 max] - (opzionale) [page:Vector2] che rappresenta il limite superiore (x, y) del box. + Il valore predefinito è ( - Infinito, - Infinito ).

    + + Crea un [name] delimitato da min e max. +

    + +

    Proprietà

    + +

    [property:Vector2 min]

    +

    + [page:Vector2] che rappresenta il limite inferiore (x, y) del box.
    + Il valore predefinito è ( + Infinito, + Infinito ). +

    + +

    [property:Vector2 max]

    +

    + [page:Vector2] che rappresenta il limite superiore (x, y) del box.
    + Il valore predefinito è ( - Infinito, - Infinito ). +

    + +

    Metodi

    + +

    [method:Vector2 clampPoint]( [param:Vector2 point], [param:Vector2 target] )

    +

    + [page:Vector2 point] - [page:Vector2] da bloccare.
    + [page:Vector2 target] - il risultato sarà copiato in questo Vector2.

    + + [link:https://en.wikipedia.org/wiki/Clamping_(graphics) Blocca] il [page:Vector2 punto] entro i limiti di questo box.
    +

    + +

    [method:Box2 clone]()

    +

    Restituisce un nuovo [page:Box2] con lo stesso [page:.min min] e [page:.max max] di questo.

    + +

    [method:Boolean containsBox]( [param:Box2 box] )

    +

    + [page:Box2 box] - [page:Box2 Box2] per testare l'inclusione.

    + + Restituisce true se questo box include la totalità del [page:Box2 box]. Se questo e il [page:Box2 box] sono identici, + questa funzione tornerà comunque true. +

    + +

    [method:Boolean containsPoint]( [param:Vector2 point] )

    +

    + [page:Vector2 point] - [page:Vector2] per verificare l'inclusione.

    + + Restituisce true se il [page:Vector2 punto] specificato si trova all'interno o sui limiti di questo box. +

    + +

    [method:this copy]( [param:Box2 box] )

    +

    + Copia il [page:.min min] e il [page:.max max] da [page:Box2 box] a questo box. +

    + +

    [method:Float distanceToPoint]( [param:Vector2 point] )

    +

    + [page:Vector2 point] - [page:Vector2] per misurare la distanza.

    + + Restituisce la distanza da qualsiasi arco di questo box al punto specificato. + Se il [page:Vector2 punto] si trova all'interno di questo box, la distanza sarà 0. +

    + +

    [method:Boolean equals]( [param:Box2 box] )

    +

    + [page:Box2 box] - Box da confrontare con questo.

    + + Restituisce true se questo box e il [page:Box2 box] condividono gli stessi limiti inferiori e superiori. +

    + +

    [method:this expandByPoint]( [param:Vector2 point] )

    +

    + [page:Vector2 point] - [page:Vector2] che dovrebbe essere incluso nel box.

    + + Espande i limiti di questo box in modo da includere il [page:Vector2 punto]. +

    + +

    [method:this expandByScalar]( [param:Float scalar] )

    +

    + [page:Float scalar] - Distanza di cui espandere il box.

    + + Espande ogni dimensione del box per lo [page:Float scalare]. Se negativo, le dimensioni del box saranno contratte. +

    + +

    [method:this expandByVector]( [param:Vector2 vector] )

    +

    + [page:Vector2 vector] - [page:Vector2] per il quale espandere il box.

    + + Espande questo box in modo equilatero per [page:Vector2 vettore]. La larghezza di questo box sarà estesa + dal componente x del [page:Vector2 vettore] in entrambe le direzioni. L'altezza di questo box + sarà estesa dal componente y del [page:Vector2 vettore] in entrambe le direzioni. +

    + +

    [method:Vector2 getCenter]( [param:Vector2 target] )

    +

    + [page:Vector2 target] — il risultato sarà copiato in questo Vector2.

    + + Restituisce il punto centrale del box come [page:Vector2]. +

    + +

    [method:Vector2 getParameter]( [param:Vector2 point], [param:Vector2 target] )

    +

    + [page:Vector2 point] - [page:Vector2].
    + [page:Vector2 target] - il risultato sarà copiato in questo Vector2.

    + + Restituisce un punto come proporzione della larghezza e dell'altezza di questo box. +

    + +

    [method:Vector2 getSize]( [param:Vector2 target] )

    +

    + [page:Vector2 target] - il risultato sarà copiato in questo Vector2.

    + + Restituisce la larghezza e l'altezza di questo box. +

    + +

    [method:this intersect]( [param:Box2 box] )

    +

    + [page:Box2 box] - Box con cui intersecare.

    + + Restituisce l'intersezione di questo box e [page:Box2 box], impostando il limite superiore di questo box al minore + dei limiti superiori dei due box e il limite inferiore di questo box al maggiore dei limiti inferiori dei due box. +

    + +

    [method:Boolean intersectsBox]( [param:Box2 box] )

    +

    + [page:Box2 box] - Box per il controllo dell'intersezione.

    + + Determina se questo box interseca [page:Box2 box] oppure no. +

    + +

    [method:Boolean isEmpty]()

    +

    + Restituisce true se questo box include zero punti entro i suoi limiti.
    + Si noti che un box con i limiti superiore e inferiore uguali include ancora un punto, + quello condiviso da entrambi i limiti. +

    + +

    [method:this makeEmpty]()

    +

    Rende questo box vuoto.

    + + +

    [method:this set]( [param:Vector2 min], [param:Vector2 max] )

    +

    + [page:Vector2 min] - (obbligatorio) [page:Vector2] che rappresenta il limite inferiore (x, y) del box.
    + [page:Vector2 max] - (obbligatorio) [page:Vector2] che rappresenta il limite superiore (x, y) del box.

    + + Imposta i limiti inferiore e superiore (x, y) di questo box.
    + Si noti che questo metodo copia solo i valori dagli oggetti dati. +

    + +

    [method:this setFromCenterAndSize]( [param:Vector2 center], [param:Vector2 size] )

    +

    + [page:Vector2 center] - Posizione centrale desiderata del box ([page:Vector2]).
    + [page:Vector2 size] - Dimensioni x e y desiderati per il box ([page:Vector2]).

    + + Centra questo box nel [page:Vector2 centro] e imposta la larghezza e l'altezza di questo box ai valori + specificati in [page:Vector2 size]. +

    + +

    [method:this setFromPoints]( [param:Array points] )

    +

    + [page:Array points] - Array di [page:Vector2 Vector2] che conterrà il box risultante.

    + + Imposta i limiti inferiore e superiore di questo box per includere tutti i punti in [page:Array points]. +

    + +

    [method:this translate]( [param:Vector2 offset] )

    +

    + [page:Vector2 offset] - Direzione e distanza dell'offset.

    + + Aggiunge l'[page:Vector2 offset] ad entrambi i limiti inferiore e superiore di questo box, spostando efficacemente + le unità di [page:Vector2 offset] di questo box nello spazio 2D. +

    + +

    [method:this union]( [param:Box2 box] )

    +

    + [page:Box2 box] - Box che verrà unito con questo box.

    + + Unisce questo box con [page:Box2 box], impostando il limite superiore di questo box al maggiore dei limiti superiori + di entrambi i box e il limite inferiore di questo box al minore dei limiti inferiori di entrambi i box. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Box3.html b/docs/api/it/math/Box3.html new file mode 100644 index 00000000000000..b2f45d5c7defe4 --- /dev/null +++ b/docs/api/it/math/Box3.html @@ -0,0 +1,310 @@ + + + + + + + + + +

    [name]

    + +

    + Rappresenta un bounding box (rettangolo di selezione) allineato all'asse (AABB) nello spazio 3D. +

    + +

    Codice di Esempio

    + + + const box = new THREE.Box3(); + + const mesh = new THREE.Mesh( + new THREE.SphereGeometry(), + new THREE.MeshBasicMaterial() + ); + + // assicurarsi che il bounding box sia calcolato per la sua geometria + // questo dovrebbe essere fatto una sola volta (supponendo geometrie statiche) + mesh.geometry.computeBoundingBox(); + + // ... + + // nel ciclo di animazione, calcola il bounding box corrente con la matrice world + box.copy( mesh.geometry.boundingBox ).applyMatrix4( mesh.matrixWorld ); + + +

    Costruttore

    + + +

    [name]( [param:Vector3 min], [param:Vector3 max] )

    +

    + [page:Vector3 min] - (opzionale) [page:Vector3] che rappresenta il limite inferiore (x, y, z) del box. + Il valore predefinito è ( + Infinito, + Infinito, + Infinito ).
    + + [page:Vector3 max] - (opzionale) [page:Vector3] che rappresenta il limite superiore (x, y, z) del box. + Il valore predefinito è ( - Infinito, - Infinito, - Infinito ).

    + + Crea un [name] delimitato da min e max. +

    + +

    Proprietà

    + +

    [property:Boolean isBox3]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:Vector3 min]

    +

    + [page:Vector3] rappresenta il limite inferiore (x, y, z) del box.
    + Il valore predefinito è ( + Infinito, + Infinito, + Infinito ). +

    + +

    [property:Vector3 max]

    +

    + [page:Vector3] che rappresenta il limite superiore (x, y, z) del box.
    + Il valore predefinito è ( - Infinito, - Infinito, - Infinito ). +

    + + + +

    Metodi

    + +

    [method:this applyMatrix4]( [param:Matrix4 matrix] )

    +

    + [page:Matrix4 matrix] - La [page:Matrix4] da applicare

    + + Trasforma questo Box3 con la matrice fornita. +

    + +

    [method:Vector3 clampPoint]( [param:Vector3 point], [param:Vector3 target] )

    +

    + [page:Vector3 point] - [page:Vector3] da bloccare.
    + [page:Vector3 target] - il risultato sarà copiato in questo Vector3.

    + + [link:https://en.wikipedia.org/wiki/Clamping_(graphics) Blocca] il [page:Vector3 punto] entro i limiti di questo box.
    +

    + +

    [method:Box3 clone]()

    +

    Restituisce un nuovo [page:Box3] con lo stesso [page:.min min] e [page:.max max] di questo.

    + +

    [method:Boolean containsBox]( [param:Box3 box] )

    +

    + [page:Box3 box] - [page:Box3 Box3] per testare l'inclusione.

    + + Restituisce true se questo box include la totalità del [page:Box3 box]. Se questo e il [page:Box3 box] sono identici, + questa fuonzione tornerà comunque true. +

    + +

    [method:Boolean containsPoint]( [param:Vector3 point] )

    +

    + [page:Vector3 point] - [page:Vector3] per verificare l'inclusione.

    + + Restituisce true se il [page:Vector3 punto] specificato si trova all'interno o sui limiti di questo box. +

    + +

    [method:this copy]( [param:Box3 box] )

    +

    + [page:Box3 box] - [page:Box3] da copiare.

    + + Copia il [page:.min min] e il [page:.max max] da [page:Box3 box] a questo box. +

    + +

    [method:Float distanceToPoint]( [param:Vector3 point] )

    +

    + [page:Vector3 point] - [page:Vector3] per misurare la distanza.

    + + Restituisce la distanza da qualsiasi arco di questo box al punto specificato. + Se il [page:Vector3 punto] si trova all'interno di questo box, la distanza sarà 0. +

    + + +

    [method:Boolean equals]( [param:Box3 box] )

    +

    + [page:Box3 box] - Box da confrontare con questo.

    + + Restituisce true se questo box e il [page:Box3 box] condividono gli stessi limiti inferiore e superiore. +

    + +

    [method:this expandByObject]( [param:Object3D object], [param:Boolean precise] )

    +

    + [page:Object3D object] - [page:Object3D] per espandere il box.
    + precise - (opzionale) espande il bounding box il meno possibile a scapito di ulteriori calcoli. L'impostazione predefinita è `false`.

    + + Espande i limiti di questo box per includere l'[page:Object3D oggetto] e i suoi figli, + tenendo conto delle trasformazioni del mondo dell'oggetto e dei figli. + La funzione può risultare in un box più grande del necessario (a meno che il parametro non sia impostato su true). +

    + +

    [method:this expandByPoint]( [param:Vector3 point] )

    +

    + [page:Vector3 point] - [page:Vector3] che dovrebbe essere incluso nel box.

    + + Espande i limiti di questo box in modo da includere il [page:Vector3 punto]. +

    + +

    [method:this expandByScalar]( [param:Float scalar] )

    +

    + [page:Float scalar] - Distanza di cui espandere il box.

    + + Espande ogni dimensione del box per lo [page:Float scalare]. Se negativo, le dimensioni del box saranno contratte. +

    + +

    [method:this expandByVector]( [param:Vector3 vector] )

    +

    + [page:Vector3 vector] - [page:Vector3] per il quale espandere il box.

    + + Espande questo box in modo equilatero per [page:Vector3 vettore]. La larghezza di questo box sarà estesa + dal componente x del [page:Vector3 vettore] in entrambe le direzioni. L'altezza di questo box + sarà estesa dal componente y del [page:Vector3 vettore] in entrambe le direzioni. + La profondità di questo box sarà estesa dal componente z del [page:Vector3 vettore] in entrambe le direzioni. +

    + +

    [method:Sphere getBoundingSphere]( [param:Sphere target] )

    +

    + [page:Sphere target] - il risultato sarà copiato in questa sfera.

    + + Ottiene una [page:Sphere Sfera] che delimita il box. +

    + +

    [method:Vector3 getCenter]( [param:Vector3 target] )

    +

    + [page:Vector3 target] - il risultato sarà copiato in questo Vector3.

    + + Restituisce il punto centrale del box come un [page:Vector3]. +

    + +

    [method:Vector3 getParameter]( [param:Vector3 point], [param:Vector3 target] )

    +

    + [page:Vector3 point] - [page:Vector3].
    + [page:Vector3 target] - il risultato sarà copiato in questo Vector3.

    + + Restituisce un punto come proporzione della larghezza, dell'altezza e della profondità di questo box. +

    + +

    [method:Vector3 getSize]( [param:Vector3 target] )

    +

    + [page:Vector3 target] - il risultato sarà copiato in questo Vector3.

    + + Restituisce la larghezza, l'altezza e la profondità di questo box. +

    + +

    [method:this intersect]( [param:Box3 box] )

    +

    + [page:Box3 box] - Box con cui intersecare.

    + + Restituisce l'intersezione di questo box e [page:Box3 box], impostando il limite superiore di questo box al minore + dei limiti superiori dei due box e il limite inferiore di questo box al maggiore dei limiti inferiori dei due box. + Se non ci sono sovrapposizioni, rende il box vuoto. +

    + +

    [method:Boolean intersectsBox]( [param:Box3 box] )

    +

    + [page:Box3 box] - Box per il controllo dell'intersezione.

    + + Determina se questo box interseca [page:Box3 box] oppure no. +

    + +

    [method:Boolean intersectsPlane]( [param:Plane plane] )

    +

    + [page:Plane plane] - [page:Plane] per il controllo dell'intersezione.

    + + Determina se questo box interseca il [page:Plane plane] oppure no. +

    + +

    [method:Boolean intersectsSphere]( [param:Sphere sphere] )

    +

    + [page:Sphere sphere] - [page:Sphere] per il controllo dell'intersezione.

    + + Determina se questo box interseca la [page:Sphere sphere] oppure no. +

    + +

    [method:Boolean intersectsTriangle]( [param:Triangle triangle] )

    +

    + [page:Triangle triangle] - [page:Triangle] per il controllo dell'intersezione.

    + + Determina se questo box interseca il [page:Triangle triangle] oppure no. +

    + +

    [method:Boolean isEmpty]()

    +

    + Restituisce true se questo box include zero punti entro i suoi limiti.
    + Si noti che un box con i limiti superiore e inferiore uguali include ancora un punto, + quello condiviso da entrambi i limiti. +

    + +

    [method:this makeEmpty]()

    +

    Rende questo box vuoto.

    + +

    [method:this set]( [param:Vector3 min], [param:Vector3 max] )

    +

    + [page:Vector3 min] - [page:Vector3] rappresenta il limite inferiore (x, y, z) del box.
    + [page:Vector3 max] - [page:Vector3] rappresenta il limite superiore (x, y, z) del box.

    + + Imposta i limiti inferiore e superiore (x, y, z) di questo box.
    + Si noti che questo metodo copia solo i valori dagli oggetti dati. +

    + +

    [method:this setFromArray]( [param:Array array] )

    +

    + array -- Un array di dati di posizione che il box risultante avvolgerà.

    + + Imposta i limiti inferiore e superiore di questo box per includere tutti i dati nell'`array`. +

    + +

    [method:this setFromBufferAttribute]( [param:BufferAttribute attribute] )

    +

    + [page:BufferAttribute attribute] - Un attributo buffer di dati di posizione che il box risultante avvolgerà.

    + + Imposta i limiti inferiore e superiore di questo box per includere tutti i dati nell'[page:BufferAttribute attribute]. +

    + +

    [method:this setFromCenterAndSize]( [param:Vector3 center], [param:Vector3 size] )

    +

    + [page:Vector3 center] - Posizione centrale desiderata del box.
    + [page:Vector3 size] - Dimensioni x, y e z desiderati per il box.

    + + Centra questo box nel [page:Vector3 centro] e imposta la larghezza e l'altezza di questo box ai valori + specificati in [page:Vector3 size]. +

    + +

    [method:this setFromObject]( [param:Object3D object], [param:Boolean precise] )

    +

    + [page:Object3D object] - [page:Object3D] di cui calcolare il bounding box.
    + precise - (opzionale) calcola il più piccolo bounding box all'asse world a scapito di più calcoli. L'impostazione predefinita è `false`.

    + + Calcola il bounding box allineato all'asse world di un [page:Object3D] (inclusi i suoi figli), + tenendo conto delle trasformazioni del mondo dell'oggetto e dei bambini. La funzione + può comportare un box più grande del necessario. +

    + +

    [method:this setFromPoints]( [param:Array points] )

    +

    + [page:Array points] - Array di [page:Vector3 Vector3] che conterrà il box risultante.

    + + Imposta i limiti inferiore e superiore di questo box per includere tutti i punti in [page:Array points]. +

    + +

    [method:this translate]( [param:Vector3 offset] )

    +

    + [page:Vector3 offset] - Direzione e distanza dell'offset.

    + + Aggiunge l'[page:Vector3 offset] ad entrambi i limiti inferiore e superiore di questo box, spostando efficacemente + le unità di page:Vector3 offset] di questo box nello spazio 3D. +

    + +

    [method:this union]( [param:Box3 box] )

    +

    + [page:Box3 box] - Box che verrà unito con questo box.

    + + Calcola l'unione di questo box con [page:Box3 box], impostando il limite superiore di questo box al maggiore dei limiti superiori + di entrambi i box e il limite inferiore di questo box al minore dei limiti inferiori di entrambi i box. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Color.html b/docs/api/it/math/Color.html new file mode 100644 index 00000000000000..1ed186632686b2 --- /dev/null +++ b/docs/api/it/math/Color.html @@ -0,0 +1,321 @@ + + + + + + + + + +

    [name]

    + +

    + Classe che rappresenta un colore. +

    + +

    + L'iterazione di un'istanza [name] produrrà i suoi componenti (r, g, b) nell'ordine corrispondente. +

    + +

    Codice di Esempio

    + +

    + Un colore può essere inizializzato in qualsiasi dei seguenti modi: +

    + +// Un costruttore vuoto - per impostazione predefinita sarà bianco +const color1 = new THREE.Color(); + +// Colore esadecimale (raccomandato) +const color2 = new THREE.Color( 0xff0000 ); + +// Una stringa RGB +const color3 = new THREE.Color("rgb(255, 0, 0)"); +const color4 = new THREE.Color("rgb(100%, 0%, 0%)"); + +// Nome del colore X11 - tutti i 140 nomi dei colori sono supportati. +// Si noti la mancanza del CamelCase nel nome +const color5 = new THREE.Color( 'skyblue' ); + +// Una stringa HSL +const color6 = new THREE.Color("hsl(0, 100%, 50%)"); + +// Separa i valori RGB tra 0 e 1 +const color7 = new THREE.Color( 1, 0, 0 ); + + +

    Costruttore

    + + +

    [name]( [param:Color_Hex_or_String r], [param:Float g], [param:Float b] )

    +

    + [page:Color_Hex_or_String r] - (opzionale) Se gli argomenti [page:Float g] e [page:Float b] sono definiti, indica il componente rosso del colore. + Se non sono definiti, questo può essere una [link:https://en.wikipedia.org/wiki/Web_colors#Hex_triplet tripletta esadecimale] (consigliato), + una stringa CSS-style, o un'altra istanza Color.
    + [page:Float g] - (opzionale) Se è definito, indica la componente verde del colore.
    + [page:Float b] - (opzionale) Se è definito, indica la componente blu del colore.

    + + Si noti che il metodo standard per definire il colore in three.js è con una [link:https://en.wikipedia.org/wiki/Web_colors#Hex_triplet tripletta esadecimale], + questo metodo viene utilizzato nel resto della documentazione.

    + + Quando tutti gli argomenti sono definiti allora [page:Color_Hex_or_String r] è il componente rosso, + [page:Float g] è il componente verde e [page:Float b] è il componente blue del colore.
    + Quando solo [page:Color_Hex_or_String r] è definito:
    +

      +
    • Può essere una [link:https://en.wikipedia.org/wiki/Web_colors#Hex_triplet tripletta esadecimale] che rappresenta il colore (consigliato).
    • +
    • Può essere un'altra istanza di Color.
    • +
    • Può essere una stringa CSS-style. Per esempio: +
        +
      • 'rgb(250, 0,0)'
      • +
      • 'rgb(100%,0%,0%)'
      • +
      • 'hsl(0, 100%, 50%)'
      • +
      • '#ff0000'
      • +
      • '#f00'
      • +
      • 'red'
      • +
      + +
    • +
    +

    + +

    Proprietà

    + +

    [property:Boolean isColor]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:Float r]

    +

    + Valore del canale rosso tra 0 e 1. Il valore predefinito è 1. +

    + +

    [property:Float g]

    +

    + Valore del canale verde tra 0 e 1. Il valore predefinito è 1. +

    + +

    [property:Float b]

    +

    + Valore del canale blu tra 0 e 1. Il valore predefinito è 1. +

    + +

    Metodi

    + +

    [method:this add]( [param:Color color] )

    +

    Aggiunge i valori RGB del [page:Color colore] ai valori RGB di questo colore.

    + +

    [method:this addColors]( [param:Color color1], [param:Color color2] )

    +

    Imposta questi valori RGB del colore alla somma dei valori RGB di [page:Color color1] e [page:Color color2].

    + +

    [method:this addScalar]( [param:Number s] )

    +

    Aggiunge [page:Number s] ai valori RGB di questo colore.

    + +

    [method:Color clone]()

    +

    Restituisce un nuovo Color con gli stessi valori [page:.r r], [page:.g g] e [page:.b b] di questo.

    + +

    [method:this copy]( [param:Color color] )

    +

    + Copia i parametri [page:.r r], [page:.g g] e [page:.b b] dal [page:Color colore] in questo colore. +

    + +

    [method:this convertLinearToSRGB]()

    +

    + Converte questo colore dallo spazio lineare allo spazio sRGB. +

    + +

    [method:this convertSRGBToLinear]()

    +

    + Converte questo colore dallo spazio sRGB allo spazio lineare. +

    + +

    [method:this copyLinearToSRGB]( [param:Color color] )

    +

    + [page:Color color] - Colore da copiare.

    + + Copia il colore passato in questo colore, e poi converte questo colore dallo spazio lineare allo spazio sRGB. +

    + +

    [method:this copySRGBToLinear]( [param:Color color] )

    +

    + [page:Color color] - Colore da copiare.

    + + Copia il colore passato in questo colore, e poi converte questo colore dallo spazio sRGB allo spazio lineare. +

    + +

    [method:Boolean equals]( [param:Color color] )

    +

    Compara i valori RGB del [page:Color colore] con quelli di questo oggetto. Restituisce true se sono gli stessi, false altrimenti.

    + +

    [method:this fromArray]( [param:Array array], [param:Integer offset] )

    +

    + [page:Array array] - [page:Array] di float nella forma [ [page:Float r], [page:Float g], [page:Float b] ].
    + [page:Integer offset] - Un offset opzionale nell'array.

    + + Imposta i componenti di questo colore in base a un array formattato come [ [page:Float r], [page:Float g], [page:Float b] ]. +

    + +

    [method:this fromBufferAttribute]( [param:BufferAttribute attribute], [param:Integer index] )

    +

    + [page:BufferAttribute attribute] - l'attributo sorgente.
    + [page:Integer index] - l'indice dell'attributo.

    + + Imposta i componenti del colore dall'[page:BufferAttribute attributo]. +

    + +

    [method:Integer getHex]( [param:string colorSpace] = SRGBColorSpace )

    +

    Restituisce il valore esadecimale di questo colore.

    + +

    [method:String getHexString]( [param:string colorSpace] = SRGBColorSpace )

    +

    Restituisce il valore esadecimale di questo colore come una stringa (per esempio, 'FFFFFF').

    + +

    [method:Object getHSL]( [param:Object target], [param:string colorSpace] = LinearSRGBColorSpace )

    +

    + [page:Object target] - questo risultato sarà copiato in questo Oggetto. Aggiunge le chiavi h, s e l all'oggetto (se non è già presente).

    + + Converte i valori [page:.r r], [page:.g g] e [page:.b b] del Color al formato [link:https://en.wikipedia.org/wiki/HSL_and_HSV HSL] + e restituisce un oggetto della forma: + + + { h: 0, s: 0, l: 0 } + + +

    + +

    [method:String getStyle]( [param:string colorSpace] = SRGBColorSpace )

    +

    Restituisce il valore di questo colore come una stringa CSS style. Esempio: `rgb(255,0,0)`.

    + +

    [method:this lerp]( [param:Color color], [param:Float alpha] )

    +

    + [page:Color color] - colore su cui convergere.
    + [page:Float alpha] - fattore di interpolazione nell'intervallo chiuso `[0, 1]`.

    + + Interpola linearmente i valori RGB di questo colore verso i valori RGB dell'argomento passato. + L'argomento alfa può essere considerato come il rapporto tra i due colori, dove `0.0` è + questo colore e `1.0` è il primo argomento. +

    + +

    [method:this lerpColors]( [param:Color color1], [param:Color color2], [param:Float alpha] )

    +

    + [page:Color color1] - [page:Color colore] iniziale.
    + [page:Color color2] - [page:Color colore] verso cui interpolare.
    + [page:Float alpha] - fattore interpolazione, tipicamente nell'intervallo chiuso `[0, 1]`.

    + + Imposta questo colore per essere il colore interpolato linearmente tra [page:Color color1] e + [page:Color color2] dove alfa è la distanza percentuale lungo la linea che collega i due colori + - alfa = 0 sarà [page:Color color1], e alpha = 1 sarà [page:Color color2]. +

    + +

    [method:this lerpHSL]( [param:Color color], [param:Float alpha] )

    +

    + [page:Color color] - colore su cui convergere.
    + [page:Float alpha] - fattore di interpolazione nell'intervallo chiuso`[0, 1]`.

    + + Interpola linearmente i valori HSL di questo colore verso i valori HSL dell'argomento passato. + Si differenzia dal classico [page:.lerp] non interpolando direttamente da un colore all'altro, + ma passando invece attraverso tutte le sfumature tra questi due colori. + L'argomento alfa può essere considerato come il rapporto tra i due colori, dove `0.0` è + questo colore e `1.0` è il primo argomento. +

    + +

    [method:this multiply]( [param:Color color] )

    +

    Moltiplica i valori RGB di questo colore per i valori RGB del colore passato.

    + +

    [method:this multiplyScalar]( [param:Number s] )

    +

    Moltiplica i valori RGB di questo colore per [page:Number s].

    + +

    [method:this offsetHSL]( [param:Float h], [param:Float s], [param:Float l] )

    +

    + Aggiunge [page:Float h], [page:Float s] e [page:Float l] passati ai valori di questo colore. + Internamente, converte i valori [page:.r r], [page:.g g] e [page:.b b] del colore a HSL, + aggiunge [page:Float h], [page:Float s], e [page:Float l] e poi converte il colore nero a RGB. +

    + +

    [method:this set]( [param:Color_Hex_or_String value] )

    +

    + [page:Color_Hex_or_String value] - Valore a cui impostare il valore.

    + + Vedi il costruttore sopra per i dettagli completi di quale [page:Color_Hex_or_String valore] può assumere. + Delega a [page:.copy], [page:.setStyle], o [page:.setHex] a seconda del tipo di input. +

    + +

    [method:this setHex]( [param:Integer hex], [param:string colorSpace] = SRGBColorSpace )

    +

    + [page:Integer hex] - formato [link:https://en.wikipedia.org/wiki/Web_colors#Hex_triplet tripletta esadecimale].

    + + Imposta questo colore da un valore esadecimale. +

    + +

    [method:this setHSL]( [param:Float h], [param:Float s], [param:Float l], [param:string colorSpace] = LinearSRGBColorSpace )

    +

    + [page:Float h] - Valore di tonalità compreso tra 0.0 e 1.0
    + [page:Float s] - Valore di saturazione compreso tra 0.0 e 1.0
    + [page:Float l] - Valore di luminosità compreso tra 0.0 e 1.0

    + + Imposta il colore dai valori HSL. +

    + +

    [method:this setRGB]( [param:Float r], [param:Float g], [param:Float b], [param:string colorSpace] = LinearSRGBColorSpace )

    +

    + [page:Float r] - Valore del canale rosso tra 0.0 e 1.0.
    + [page:Float g] - Valore del canale verde tra 0.0 e 1.0.
    + [page:Float b] - Valore del canale blu tra 0.0 e 1.0.

    + + Imposta questo colore dai valori RGB. +

    + +

    [method:this setScalar]( [param:Float scalar] )

    +

    + [page:Float scalar] - un valore tra 0.0 e 1.0.

    + + Imposta tutti e tre i componenti del colore al valore [page:Float scalare]. +

    + +

    [method:this setStyle]( [param:String style], [param:string colorSpace] = SRGBColorSpace )

    +

    + [page:String style] - colore come una stringa CSS-style.

    + + Imposta questo colore da una stringa CSS. Per esempio, + "rgb(250, 0,0)", + "rgb(100%, 0%, 0%)", + "hsl(0, 100%, 50%)", + "#ff0000", + "#f00", o + "red" ( o qualsiasi [link:https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart nome dei colori X11] + - tutti i 140 nomi dei colori sono supportati ).
    + + Sono accettati anche colori traslucidi come "rgba(255, 0, 0, 0.5)" e "hsla(0, 100%, 50%, 0.5)", + ma le coordinate del canale alfa verranno eliminate.

    + + Si noti che per i nomi dei colori X11, più parole come Dark Orange diventano la stringa 'darkorange'. +

    + +

    [method:this setColorName]( [param:String style], [param:string colorSpace] = SRGBColorSpace )

    +

    + [page:String style] - nome del colore ( dai [link:https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart nomi dei colori X11] ).

    + + Imposta questo colore dal nome del colore. Più veloce del metodo [page:.setStyle] se non hai bisogno di altri formati in stile CSS.

    + + Per convenienza, la lista dei nomi è esposta in Color.NAMES come un hash: Color.NAMES.aliceblue // returns 0xF0F8FF +

    + +

    [method:this sub]( [param:Color color] )

    +

    + Sottrae i componenti RGB del colore dato dai componenti RGB di questo colore. + Se questo ritorna un componente negativo, tale componente viene impostato a zero. +

    + +

    [method:Array toArray]( [param:Array array], [param:Integer offset] )

    +

    + [page:Array array] - Un array opzionale in cui memorizzare il colore.
    + [page:Integer offset] - Un offset opzionale nell'array.

    + + Restituisce un array della forma [ r, g, b ]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Cylindrical.html b/docs/api/it/math/Cylindrical.html new file mode 100644 index 00000000000000..2a74e938327e0f --- /dev/null +++ b/docs/api/it/math/Cylindrical.html @@ -0,0 +1,76 @@ + + + + + + + + + +

    [name]

    + +

    + [link:https://en.wikipedia.org/wiki/Cylindrical_coordinate_system Coordinate cilindriche] di un punto. +

    + + +

    Costruttore

    + +

    [name]( [param:Float radius], [param:Float theta], [param:Float y] )

    +

    + [page:Float radius] - distanza dall'origine a un punto nel piano x-z. + Il valore predefinito è `1.0`.
    + [page:Float theta] - angolo in senso antiorario nel piano x-z misurato in radianti dall'asse z positivo. + Il valore predefinito è `0`.
    + [page:Float y] - altezza sopra il piano x-z. Il valore predefinito è `0`. +

    + + +

    Proprietà

    + +

    [property:Float radius]

    + +

    [property:Float theta]

    + +

    [property:Float y]

    + + +

    Metodi

    + +

    [method:Cylindrical clone]()

    +

    + Restituisce un nuovo cilindro con le stesse proprietà [page:.radius radius], [page:.theta theta] + e [page:.y y] di questo. +

    + +

    [method:this copy]( [param:Cylindrical other] )

    +

    + Copia i valori delle proprietà [page:.radius radius], [page:.theta theta] + e [page:.y y] del cilindro passato in questo cilindro. +

    + +

    [method:this set]( [param:Float radius], [param:Float theta], [param:Float y] )

    +

    + Imposta i valori delle proprietà [page:.radius radius], [page:.theta theta] + e [page:.y y] di questo cilindro. +

    + +

    [method:this setFromVector3]( [param:Vector3 vec3] )

    +

    + Imposta i valori delle proprietà [page:.radius radius], [page:.theta theta] + e [page:.y y] di questo cilindro dal [page:Vector3 Vector3]. +

    + +

    [method:this setFromCartesianCoords]( [param:Float x], [param:Float y], [param:Float z] )

    +

    + Imposta i valori delle proprietà [page:.radius radius], [page:.theta theta] + e [page:.y y] di questo cilindro dalle coordinate cartesiane. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Euler.html b/docs/api/it/math/Euler.html new file mode 100644 index 00000000000000..973c35d36c359d --- /dev/null +++ b/docs/api/it/math/Euler.html @@ -0,0 +1,161 @@ + + + + + + + + + +

    [name]

    + +

    + Una classe che rappresenta gli [link:http://en.wikipedia.org/wiki/Euler_angles angoli di Eulero].

    + + Gli angoli di eulero descrivono una trasformazione rotazionale ruotando un oggetto sui suoi vari assi + in quantità specifiche per asse, e in un ordine specificato per asse. +

    + +

    + L'iterazione di un'istanza di [name] produce le sue componenti (x, y, z, order) nell'ordine corrispondente. +

    + +

    Codice di Esempio

    + + const a = new THREE.Euler( 0, 1, 1.57, 'XYZ' ); + const b = new THREE.Vector3( 1, 0, 1 ); + b.applyEuler(a); + + + +

    Costruttore

    + + +

    [name]( [param:Float x], [param:Float y], [param:Float z], [param:String order] )

    +

    + [page:Float x] - (opzionale) l'angolo dell'asse x in radianti. Il valore predefinito è `0`.
    + [page:Float y] - (opzionale) l'angolo dell'asse y in radianti. Il valore predefinito è `0`.
    + [page:Float z] - (opzionale) l'angolo dell'asse z in radianti. Il valore predefinito è `0`.
    + [page:String order] - (opzionale) una stringa che rappresenta l'ordine in cui vengono applicate le rotazioni, + il valore predefinito è 'XYZ' (deve essere in maiuscolo).

    + +

    + + +

    Proprietà

    + +

    [property:Boolean isEuler]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:String order]

    +

    + L'ordine in cui applicare le rotazioni. Il valore predefinito è 'XYZ', questo significa che l'oggetto + verrà ruotato prima intorno all'asse X, poi intorno all'asse Y e infine intorno all'asse Z. Altre possibilità sono: + 'YZX', 'ZXY', 'XZY', 'YXZ' e 'ZYX'. Queste devono essere in maiuscolo.

    + + Three.js utilizza gli angoli Tait-Bryan `intrinseci`. Questo significa che le rotazioni vengono eseguite + rispettando il sistema di coordinate `locale`. Cioè per l'ordine 'XYZ', la rotazione verrà prima eseguita + intorno all'asse locale X (il che è lo stesso dell'asse world X), poi intorno all'asse locale Y (che può essere diversa dall'asse + world Y), ed infine intorno all'asse Z (che può essere diversa dall'asse world Z). +

    + +

    [property:Float x]

    +

    + Il valore corrente del componente x. +

    + +

    [property:Float y]

    +

    + Il valore corrente del componente y. +

    + +

    [property:Float z]

    +

    + Il valore corrente del componente z. +

    + +

    Metodi

    + +

    [method:this copy]( [param:Euler euler] )

    +

    Copia il valore di [page:Euler Eulero] in questo Eulero.

    + +

    [method:Euler clone]()

    +

    Restituisce un nuovo Eulero con gli stessi parametri di questo.

    + +

    [method:Boolean equals]( [param:Euler euler] )

    +

    Verifica la stretta uguaglianza di questo Eulero ed [page:Euler Eulero].

    + +

    [method:this fromArray]( [param:Array array] )

    +

    + [page:Array array] di lunghezza 3 o 4. Il quarto argomento, opzionale, corrisponde all'[page:.order order].

    + + Assegna l'angolo [page:.x x] di questo Eulero a `array[0]`.
    + Assegna l'angolo [page:.y y] di questo Eulero a `array[1]`.
    + Assegna l'angolo [page:.z z] di questo Eulero a `array[2]`.
    + Facoltativamente, assegna [page:.order order] di questo Eulero a `array[3]`. +

    + +

    [method:this reorder]( [param:String newOrder] )

    +

    + Reimposta l'angolo di eulero con un nuovo ordine creando un quaternione da questo angolo di Eulero + e quindi impostando questo angolo di Eulero con il quaternione ed il nuovo ordine.

    + + *Attenzione*: questo scarta le informazioni sulla rivoluzione. +

    + +

    [method:this set]( [param:Float x], [param:Float y], [param:Float z], [param:String order] )

    +

    + [page:.x x] - l'angolo dell'asse x in radianti.
    + [page:.y y] - l'angolo dell'asse y in radianti.
    + [page:.z z] - l'angolo dell'asse z in radianti.
    + [page:.order order] - (opzionale) una stringa che rappresenta l'ordine in cui vengono applicate le rotazioni.

    + + Imposta gli angoli di questa trasformazione di Eulero e, facoltativamente, l'[page:.order ordine]. +

    + +

    [method:this setFromRotationMatrix]( [param:Matrix4 m], [param:String order] )

    +

    + [page:Matrix4 m] - una [page:Matrix4] di cui la parte superiore 3x3 della matrice è una + [link:https://en.wikipedia.org/wiki/Rotation_matrix matrice di rotazione] pura (cioè non scalata).
    + [page:.order order] - (opzionale) una stringa che rappresenta l'ordine in cui vengono applicate le rotazioni.
    + + Imposta gli angoli di questa trasformazione di Eulero da una matrice di rotazione pura in base + all'orientamento specificato dall'[page:.order ordine]. +

    + +

    [method:this setFromQuaternion]( [param:Quaternion q], [param:String order] )

    +

    + [page:Quaternion q] - un quaternione normalizzato.
    + [page:.order order] - (opzionale) una stringa che rappresenta l'ordine in cui vengono applicate le rotazioni.
    + + Imposta gli angoli di questa trasformazione di Eulero da un quaternione normalizzato in base all'orientamento + specificato dall'[page:.order ordine]. +

    + + +

    [method:this setFromVector3]( [param:Vector3 vector], [param:String order] )

    +

    + [page:Vector3 vector] - [page:Vector3].
    + [page:.order order] - (opzionale) una stringa che rappresenta l'ordine in cui vengono applicate le rotazioni.
    + + Imposta [page:.x x], [page:.y y] e [page:.z z], e facoltativamente aggiorna l'[page:.order ordine]. +

    + + +

    [method:Array toArray]( [param:Array array], [param:Integer offset] )

    +

    + [page:Array array] - (opzionale) un array per memorizzare l'Eulero.
    + [page:Integer offset] - (opzionale) offset nell'array.
    + + Restituisce un array della forma [[page:.x x], [page:.y y], [page:.z z], [page:.order order]]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Frustum.html b/docs/api/it/math/Frustum.html new file mode 100644 index 00000000000000..12370f53440ef6 --- /dev/null +++ b/docs/api/it/math/Frustum.html @@ -0,0 +1,111 @@ + + + + + + + + + +

    [name]

    + +

    + Il [link:http://en.wikipedia.org/wiki/Frustum Frustum] viene utilizzato per determinare cosa c'è + all'interno del campo visivo della telecamera. Aiuta ad accellerare il processo di rendering - + gli oggetti che si trovano al di fuori del frustum della telecamera possono essere tranquillamente + esclusi dal rendering.

    + + Questa classe è principalmente pensata per l'uso interno da parte di un renderer per il calcolo + di una [page:Camera telecamera] o dal frustum della [page:LightShadow.camera shadowCamera]. +

    + + +

    Costruttore

    + + +

    [name]([param:Plane p0], [param:Plane p1], [param:Plane p2], [param:Plane p3], [param:Plane p4], [param:Plane p5])

    +

    + [page:Plane p0] - (opzionale) impostato su un nuovo [page:Plane].
    + [page:Plane p1] - (opzionale) impostato su un nuovo [page:Plane].
    + [page:Plane p2] - (opzionale) impostato su un nuovo [page:Plane].
    + [page:Plane p3] - (opzionale) impostato su un nuovo [page:Plane].
    + [page:Plane p4] - (opzionale) impostato su un nuovo [page:Plane].
    + [page:Plane p5] - (opzionale) impostato su un nuovo [page:Plane].

    + + Crea un nuovo [name]. +

    + + +

    Proprietà

    + +

    [property:Array planes]

    +

    Array di 6 [page:Plane piani].

    + + +

    Metodi

    + +

    [method:Frustum clone]()

    +

    Restituisce un nuovo Frustum con gli stessi parametri di questo.

    + + +

    [method:Boolean containsPoint]( [param:Vector3 point] )

    +

    + [page:Vector3 point] - [page:Vector3] di test.

    + + Verifica se il frustum contiene il [page:Vector3 punto]. +

    + +

    [method:this copy]( [param:Frustum frustum] )

    +

    + [page:Frustum frustum] - Il frustum da copiare

    + + Copia le proprietà del [page:Frustum frustum] passato in questo. +

    + +

    [method:Boolean intersectsBox]( [param:Box3 box] )

    +

    + [page:Box3 box] - [page:Box3] per verificare l'intersezione.

    + + Restituisce true se il [page:Box3 box] si interseca con questo frustum. +

    + +

    [method:Boolean intersectsObject]( [param:Object3D object] )

    +

    + Verifica se la [page:BufferGeometry.boundingSphere bounding sphere] dell'[page:Object3D oggetto] sta intersecando il frustum.

    + + Si noti che l'oggetto deve avere una [page:BufferGeometry geometria] così che la bounding sphere possa essere calcolata. +

    + +

    [method:Boolean intersectsSphere]( [param:Sphere sphere] )

    +

    + [page:Sphere sphere] - [page:Sphere] per verificare l'intersezione.

    + + Restituisce true se la [page:Sphere sfera] si interseca con questo frustum. +

    + +

    [method:Boolean intersectsSprite]( [param:Sprite sprite] )

    +

    + Verifica se la [page:Sprite sprite] si interseca con il frustum. +

    + +

    [method:this set]( [param:Plane p0], [param:Plane p1], [param:Plane p2], [param:Plane p3], [param:Plane p4], [param:Plane p5] )

    +

    + Imposta il frustum dai piani passati. Nessun ordine dei piani è implicito.
    + Si noti che questo metodo copia solo i valori degli oggetti dati. +

    + +

    [method:this setFromProjectionMatrix]( [param:Matrix4 matrix] )

    +

    + [page:Matrix4 matrix] - La [page:Matrix4] di proiezione utilizzata per impostare i [page:.planes planes]

    + + Imposta i piani del frustum dalla matrice di proiezione. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Interpolant.html b/docs/api/it/math/Interpolant.html new file mode 100644 index 00000000000000..eae2ce16588614 --- /dev/null +++ b/docs/api/it/math/Interpolant.html @@ -0,0 +1,80 @@ + + + + + + + + + +

    [name]

    + +

    + Classe base astratta di interpolanti su campioni parametrici.

    + + Il dominio del parametro è unidimensionale, tipicamente il tempo o un path lungo una curva definita dai dati.

    + + I valori campione possono avere qualsiasi dimensionalità e le classi derivate possono applicare interpolazioni ai dati.

    + + Questa classe fornisce l'intervallo di ricerca in un Metodo Modello, rinviando l'interpolazione effettiva alle classi derivate.

    + + La complessità del tempo è `O(1)` per l'accesso lineare che attraversa al massimo due punti e `O(log N)` per l'accesso casuale, + dove *N* è il numero di posizioni.

    + + Riferimenti: [link:http://www.oodesign.com/template-method-pattern.html http://www.oodesign.com/template-method-pattern.html] +

    + + +

    Costruttore

    + +

    [name]( parameterPositions, sampleValues, sampleSize, resultBuffer )

    +

    + parameterPositions -- array di posizioni
    + sampleValues -- array di campioni
    + sampleSize -- numero di campioni
    + resultBuffer -- buffer in cui memorizzare i risultati dell'interpolazione.

    + + Nota: Questa classe non è pensata per essere chiamata direttamente. +

    + +

    Proprietà

    + +

    [property:null parameterPositions]

    +

    + +

    + +

    [property:null resultBuffer]

    +

    + +

    + +

    [property:null sampleValues]

    +

    + +

    + +

    [property:Object settings]

    +

    + Opzionale, struttura delle impostazioni e specifica della sottoclasse. +

    + +

    [property:null valueSize]

    +

    + +

    + +

    Metodi

    + +

    [method:Array evaluate]( [param:Number t] )

    +

    + Valuta l'interpolazione in posizione *t*. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Line3.html b/docs/api/it/math/Line3.html new file mode 100644 index 00000000000000..abfaa39682fab9 --- /dev/null +++ b/docs/api/it/math/Line3.html @@ -0,0 +1,118 @@ + + + + + + + + + +

    [name]

    + +

    Un segmento di linea geometrico rappresentato da un punto iniziale e uno finale.

    + + +

    Costruttore

    + + +

    [name]( [param:Vector3 start], [param:Vector3 end] )

    +

    + [page:Vector3 start] - Inizio del segmento. Il valore predefinito è `(0, 0, 0)`.
    + [page:Vector3 end] - Fine del segmento. Il valore predefinito è `(0, 0, 0)`.

    + + Crea un nuovo [name]. +

    + + +

    Proprietà

    + +

    [property:Vector3 start]

    +

    [page:Vector3] che rappresenta il punto di inizio della linea.

    + +

    [property:Vector3 end]

    +

    [page:Vector3] che rappresenta il punto di fine della linea.

    + +

    Metodi

    + +

    [method:this applyMatrix4]( [param:Matrix4 matrix] )

    +

    Applica una matrice di trasformazione al segmento.

    + +

    [method:Vector3 at]( [param:Float t], [param:Vector3 target] )

    +

    + [page:Float t] - Utilizza i valori 0-1 per restituire una posizione lungo il segmento.
    + [page:Vector3 target] — il risultato verrà copiato in questo Vector3.

    + + Restituisce un vettore in una determinata posizione lungo la linea. Quando [page:Float t] = 0, restituisce il vettore iniziale, + e quando [page:Float t] = 1 restituisce il vettore finale.
    +

    + +

    [method:Line3 clone]()

    +

    Restituisce un nuovo [page:Line3] con gli stessi vettori [page:.start start] e [page:.end end] di questo.

    + +

    [method:Vector3 closestPointToPoint]( [param:Vector3 point], [param:Boolean clampToLine], [param:Vector3 target] )

    +

    + [page:Vector3 point] - restituisce il punto più vicino alla linea a questo punto.
    + [page:Boolean clampToLine] - indica se bloccare o meno il valore restituito al segmento.
    + [page:Vector3 target] - il risultato verrà copiato in questo Vector3.

    + + Restituisce il punto più vicino alla linea. Se [page:Boolean clampToLine] è true, allora il valore restituito verrà bloccato alla linea. +

    + +

    [method:Float closestPointToPointParameter]( [param:Vector3 point], [param:Boolean clampToLine] )

    +

    + [page:Vector3 point] - il punto per il quale restituire un parametro punto.
    + [page:Boolean clampToLine] - indica se bloccare o meno il risultato nell'intervallo `[0, 1]`.

    + + Restituisce un parametro punto basato sul punto più vicino come proiettato sul segmento. + Se [page:Boolean clampToLine] è true, allora il valore restituito sarà tra 0 e 1. +

    + +

    [method:this copy]( [param:Line3 line] )

    +

    Copia i vettori [page:.start start] e [page:.end end] della linea passati in questa linea.

    + +

    [method:Vector3 delta]( [param:Vector3 target] )

    +

    + [page:Vector3 target] - il risultato verrà copiato in questo Vector3.

    + + Restituisce il vettore delta del segmento (vettore [page:.end end] meno il vettore [page:.start start]). +

    + +

    [method:Float distance]()

    +

    Restituisce la [link:https://en.wikipedia.org/wiki/Euclidean_distance distanza Euclidea] + (distanza in linea retta) tra i punti [page:.start start] e [page:.end end] della linea.

    + +

    [method:Float distanceSq]()

    +

    + Restituisce il quadrato della [link:https://en.wikipedia.org/wiki/Euclidean_distance distanza Euclidea] + (distanza in linea retta) tra i vettori [page:.start start] e [page:.end end] della linea. +

    + +

    [method:Boolean equals]( [param:Line3 line] )

    +

    + [page:Line3 line] - [page:Line3] da confrontare con questo.

    + + Restituisce true se entrambi i punti [page:.start start] e [page:.end end] della linea sono uguali. +

    + +

    [method:Vector3 getCenter]( [param:Vector3 target] )

    +

    + [page:Vector3 target] — il risultato verrà copiato in questo Vector3.

    + + Restituisce il centro del segmento. +

    + +

    [method:this set]( [param:Vector3 start], [param:Vector3 end] )

    +

    + [page:Vector3 start] - imposta il punto [page:.start start] della linea.
    + [page:Vector3 end] - imposta il punto [page:.end end] della linea.

    + + Imposta i valori start ed end copiando i vettori forniti. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/MathUtils.html b/docs/api/it/math/MathUtils.html new file mode 100644 index 00000000000000..bf6a29e43b2e45 --- /dev/null +++ b/docs/api/it/math/MathUtils.html @@ -0,0 +1,161 @@ + + + + + + + + + +

    [name]

    + +

    Un oggetto con molte funzioni matematiche di utilità.

    + +

    Funzioni

    + +

    [method:Float clamp]( [param:Float value], [param:Float min], [param:Float max] )

    +

    + [page:Float value] — Valore che deve essere fissato.
    + [page:Float min] — Valore minimo.
    + [page:Float max] — Valore massimo.

    + + Fissa il [page:Float value] tra il [page:Float min] e il [page:Float max]. +

    + +

    [method:Float degToRad]( [param:Float degrees] )

    +

    Converte i gradi in radianti.

    + +

    [method:Integer euclideanModulo]( [param:Integer n], [param:Integer m] )

    +

    + [page:Integer n], [page:Integer m] - Interi

    + + Calcola il modulo Euclideo di [page:Integer m] % [page:Integer n], che è: + ( ( n % m ) + m ) % m +

    + +

    [method:UUID generateUUID]( )

    +

    + Genera un'[link:https://en.wikipedia.org/wiki/Universally_unique_identifier UUID] + (universally unique identifier). +

    + +

    [method:Boolean isPowerOfTwo]( [param:Number n] )

    +

    Restituisce `true` se [page:Number n] è una potenza di 2.

    + +

    [method:Float inverseLerp]( [param:Float x], [param:Float y], [param:Float value] )

    +

    + [page:Float x] - Punto di inizio.
    + [page:Float y] - Punto di fine.
    + [page:Float value] - Un valore tra l'inizio e la fine.

    + + Restituisce la percentuale nell'intervallo chiuso `[0, 1]` del valore dato tra il punto di inizio e di fine. +

    + +

    [method:Float lerp]( [param:Float x], [param:Float y], [param:Float t] )

    +

    + [page:Float x] - Punto di inizio.
    + [page:Float y] - Punto di fine.
    + [page:Float t] - Fattore di interpolazione nell'intervallo chiuso `[0, 1]`.

    + + Restituisce un valore [link:https://en.wikipedia.org/wiki/Linear_interpolation interpolato linearmente] + da due punti noti in base all'intervallo dato - [page:Float t] = 0 restituirà [page:Float x] + e [page:Float t] = 1 restituirà [page:Float y]. +

    + +

    [method:Float damp]( [param:Float x], [param:Float y], [param:Float lambda], [param:Float dt] )

    +

    + [page:Float x] - Punto corrente.
    + [page:Float y] - Punto target.
    + [page:Float lambda] - Un valore lambda più alto renderà il movimento più improvviso, e un valore più basso renderà il movimento più graduale.
    + [page:Float dt] - Il tempo delta in secondi.

    + + Interpola in modo fluido un numero da [page:Float x] a [page:Float y] in modo simile ad una molla usando [page:Float dt] + per mantenere il movimento indipendente dalla frequenza dei fotogrammi. Per i dettagli, vedere + [link:http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/ Smorzamento indipendente dalla frequenza dei fotogrammi mediante lerp]. +

    + +

    [method:Float mapLinear]( [param:Float x], [param:Float a1], [param:Float a2], [param:Float b1], [param:Float b2] )

    +

    + [page:Float x] — Valore da mappare.
    + [page:Float a1] — Minimo valore per il range A.
    + [page:Float a2] — Massimo valore per il range A.
    + [page:Float b1] — Minimo valore per il range B.
    + [page:Float b2] — Massimo valore per il range B.

    + + Mappa lineare di [page:Float x] dall'intervallo [[page:Float a1], [page:Float a2]] all'intervallo [[page:Float b1], [page:Float b2]]. +

    + +

    [method:Float pingpong]( [param:Float x], [param:Float length] )

    +

    + [page:Float x] — Il valore del pingpong.
    + [page:Float length] — Il valore positivo a cui la funzione farà pingpong. Il valore predefinito è 1.

    + + Restituisce un valore che alterna tra 0 e [param:Float length]. +

    + +

    [method:Integer ceilPowerOfTwo]( [param:Number n] )

    +

    Restituisce la potenza di 2 più piccola, maggiore o uguale a [page:Number n].

    + +

    [method:Integer floorPowerOfTwo]( [param:Number n] )

    +

    Restituisce la massima potenza di 2, minore o uguale a [page:Number n].

    + +

    [method:Float radToDeg]( [param:Float radians] )

    +

    Coverte i radianti in gradi.

    + +

    [method:Float randFloat]( [param:Float low], [param:Float high] )

    +

    Float casuale nell'intervallo [[page:Float low], [page:Float high]].

    + +

    [method:Float randFloatSpread]( [param:Float range] )

    +

    Float casuale nell'intervallo [- [page:Float range] / 2, [page:Float range] / 2].

    + +

    [method:Integer randInt]( [param:Integer low], [param:Integer high] )

    +

    Intero casuale nell'intervallo [[page:Float low], [page:Float high]].

    + +

    [method:Float seededRandom]( [param:Integer seed] )

    +

    Float pseudocasuale deterministico nell'intervallo `[0, 1]`. L'intero [page:Integer seed] è opzionale.

    + +

    [method:Float smoothstep]( [param:Float x], [param:Float min], [param:Float max] )

    +

    + [page:Float x] - Il valore da valutare in base alla sua posizione tra il min e il max.
    + [page:Float min] - Qualsiasi valore di x sotto il min sarà 0.
    + [page:Float max] - Qualsiasi valore di x sopra il max sarà 1.

    + + Restituisce un valore compreso tra 0-1 che rappresenta la percentuale di spostamento di x tra il min e il max, + ma attenuata o rallentata quanto più X si avvicina al minimo e al massimo.

    + + Vedi [link:http://en.wikipedia.org/wiki/Smoothstep Smoothstep] per i dettagli. +

    + +

    [method:Float smootherstep]( [param:Float x], [param:Float min], [param:Float max] )

    +

    + [page:Float x] - Il valore da valutare in base alla sua posizione tra il min e il max.
    + [page:Float min] - Qualsiasi valore di x sotto il min sarà 0.
    + [page:Float max] - Qualsiasi valore di x sopra il max sarà 1.

    + + Restituisce un valore compreso tra 0-1. Una [link:https://en.wikipedia.org/wiki/Smoothstep#Variations variazione su smoothstep] + che ha zero derivare di primo e secondo ordine a x=0 e x=1. +

    + +

    [method:undefined setQuaternionFromProperEuler]( [param:Quaternion q], [param:Float a], [param:Float b], [param:Float c], [param:String order] )

    +

    + [page:Quaternion q] - Il quaternione da impostare.
    + [page:Float a] - La rotazione applicata al primo asse, in radianti.
    + [page:Float b] - La rotazione applicata al secondo asse, in radianti.
    + [page:Float c] - La rotazione applicata al terzo asse, in radianti.
    + [page:String order] - una stringa che specifica l'ordine degli assi: 'XYX', 'XZX', 'YXY', 'YZY', 'ZXZ', o 'ZYZ'

    + + Imposta il quaternione [page:Quaternion q] dagli [link:http://en.wikipedia.org/wiki/Euler_angles angoli di Eulero propri intrinseci] definiti + dagli angoli [page:Float a], [page:Float b], e [page:Float c], e dall'ordine [page:String order].
    + + Le rotazioni vengono applicate agli assi nell'ordine specificato da [page:String order]: + la rotazione per l'angolo [page:Float a] viene applicata per prima, poi l'angolo [page:Float b], infine l'angolo [page:Float c]. + Gli angoli sono in radianti. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Matrix3.html b/docs/api/it/math/Matrix3.html new file mode 100644 index 00000000000000..f2dc8d20e4d3e6 --- /dev/null +++ b/docs/api/it/math/Matrix3.html @@ -0,0 +1,247 @@ + + + + + + + + + +

    [name]

    + +

    + Una classe che rappresenta una [link:https://en.wikipedia.org/wiki/Matrix_(mathematics) matrice] 3x3. +

    + +

    Codice di Esempio

    + +const m = new Matrix3(); + + +

    Una nota sull'ordine delle Row-Major (righe principali) e delle Column-Major (colonne principali)

    +

    + Il metodo [page:set]() accetta gli argomenti in ordine + [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order row-major], mentre internamente + vengono memorizzati nell'array [page:.elements elements] nell'ordine column-major.

    + + Ciò significa che la chiamata a + +m.set( 11, 12, 13, + 21, 22, 23, + 31, 32, 33 ); + + risulterà nell'array [page:.elements elements] contenente: + +m.elements = [ 11, 21, 31, + 12, 22, 32, + 13, 23, 33 ]; + + e internamente tutti i calcoli vengono eseguiti utilizzando l'ordine column-major. Tuttavia, poiché l'ordine + effettivo non fa alcune differenza matematicamente e la maggior parte delle persone è abituata a pensare alle + matrici nell'ordine row-major, la documentazione di three.js mostra le matrici in ordine di row-major. + Tieni solo a mente che se stai leggendo il codice sorgente, dovrai prendere la [link:https://en.wikipedia.org/wiki/Transpose trasposizione] + di tutte le matrici qui descritte per dare un senso ai calcoli. +

    + +

    Costruttore

    + + +

    [name]()

    +

    + Crea e inizializza [name] nella + [link:https://en.wikipedia.org/wiki/Identity_matrix matrice] identità 3x3. +

    + +

    Proprietà

    + +

    [property:Array elements]

    +

    + Una lista di [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order column-major] + di valori della matrice. +

    + +

    Metodi

    + +

    [method:Matrix3 clone]()

    +

    Crea una Matrix3 con elementi identici a questa.

    + +

    [method:this copy]( [param:Matrix3 m] )

    +

    Copia gli elementi della matrice [page:Matrix3 m] in questa matrice.

    + +

    [method:Float determinant]()

    +

    + Calcola e restituisce il [link:https://en.wikipedia.org/wiki/Determinant determinante] di questa matrice. +

    + +

    [method:Boolean equals]( [param:Matrix3 m] )

    +

    Restituisce true se questa matrice e [page:Matrix3 m] sono uguali.

    + +

    [method:this extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )

    +

    + Estrae la [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) base] di questa matrice + nei tre vettori asse forniti. Se questa matrice è: + +a, b, c, +d, e, f, +g, h, i + + allora [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] saranno impostate a: + +xAxis = (a, d, g) +yAxis = (b, e, h) +zAxis = (c, f, i) + +

    + +

    [method:this fromArray]( [param:Array array], [param:Integer offset] )

    +

    + [page:Array array] - l'array da cui leggere gli elementi.
    + [page:Integer offset] - (opzionale) indice del primo elemento nell'array. Il valore predefinito è 0.

    + + Imposta gli elementi di questa matrice in base ad un array nel formato + [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major]. +

    + +

    [method:this invert]()

    +

    + Inverte questa matrice, utilizzando il [link:https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution metodo analitico]. + + Non puoi invertire con un determinante zero. Se si tenta questo, il metodo produce invece una matrice zero. +

    + +

    [method:this getNormalMatrix]( [param:Matrix4 m] )

    +

    + [page:Matrix4 m] - [page:Matrix4]

    + + Imposta questa matrice come 3x3 in alto a sinistra della [link:https://en.wikipedia.org/wiki/Normal_matrix matrice normale] + della [page:Matrix4 matrix4] passata. La matrice normale è la [link:https://en.wikipedia.org/wiki/Transpose trasposta] + [link:https://en.wikipedia.org/wiki/Invertible_matrix inversa] della matrice [page:Matrix4 m]. +

    + +

    [method:this identity]()

    +

    + Reimposta questa matrice alla matrice identità 3x3: + +1, 0, 0 +0, 1, 0 +0, 0, 1 + + +

    + +

    [method:this makeRotation]( [param:Float theta] )

    +

    + [page:Float theta] — Rotation angle in radians. Positive values rotate counterclockwise.

    + + Sets this matrix as a 2D rotational transformation by [page:Float theta] radians. + The resulting matrix will be: + +cos(θ) -sin(θ) 0 +sin(θ) cos(θ) 0 +0 0 1 + +

    + +

    [method:this makeScale]( [param:Float x], [param:Float y] )

    +

    + [page:Float x] - the amount to scale in the X axis.
    + [page:Float y] - the amount to scale in the Y axis.
    + + Sets this matrix as a 2D scale transform: + +x, 0, 0, +0, y, 0, +0, 0, 1 + +

    + +

    [method:this makeTranslation]( [param:Float x], [param:Float y] )

    +

    + [page:Float x] - the amount to translate in the X axis.
    + [page:Float y] - the amount to translate in the Y axis.
    + + Sets this matrix as a 2D translation transform: + +1, 0, x, +0, 1, y, +0, 0, 1 + +

    + +

    [method:this multiply]( [param:Matrix3 m] )

    +

    Post-moltiplica questa matrice per [page:Matrix3 m].

    + +

    [method:this multiplyMatrices]( [param:Matrix3 a], [param:Matrix3 b] )

    +

    Imposta questa matrice ad [page:Matrix3 a] x [page:Matrix3 b].

    + +

    [method:this multiplyScalar]( [param:Float s] )

    +

    Moltiplica ogni componente della matrice per il valore scalare *s*.

    + +

    [method:this rotate]( [param:Float theta] )

    +

    Ruota questa matrice dell'angolo dato (in radianti).

    + +

    [method:this scale]( [param:Float sx], [param:Float sy] )

    +

    Ridimensiona questa matrice dei valori scalari passati.

    + +

    [method:this set]( [param:Float n11], [param:Float n12], [param:Float n13], [param:Float n21], [param:Float n22], [param:Float n23], [param:Float n31], [param:Float n32], [param:Float n33] )

    +

    + [page:Float n11] - valore da inserire nella riga 1, colonna 1.
    + [page:Float n12] - valore da inserire nella riga 1, colonna 2.
    + ...
    + ...
    + [page:Float n32] - valore da inserire nella riga 3, colonna 2.
    + [page:Float n33] - valore da inserire nella riga 3, colonna 3.

    + + Imposta i valori della matrice 3x3 sulla sequenza di valori della + [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order row-major] specificata. +

    + +

    [method:this premultiply]( [param:Matrix3 m] )

    +

    Pre-moltiplica questa matrice per [page:Matrix3 m].

    + +

    [method:this setFromMatrix4]( [param:Matrix4 m] )

    +

    Imposta questa matrice sulla matrice 3x3 superiore di Matrix4 [page:Matrix4 m].

    + +

    [method:this setUvTransform]( [param:Float tx], [param:Float ty], [param:Float sx], [param:Float sy], [param:Float rotation], [param:Float cx], [param:Float cy] )

    +

    + [page:Float tx] - offset x
    + [page:Float ty] - offset y
    + [page:Float sx] - repeat x
    + [page:Float sy] - repeat y
    + [page:Float rotation] - rotazione, in radianti. Positive values rotate counterclockwise
    + [page:Float cx] - centro x di rotazione
    + [page:Float cy] - centro y di rotazione

    + + Imposta la matrice di trasformazione UV da offset, ripetizione, rotazione e centro. +

    + +

    [method:Array toArray]( [param:Array array], [param:Integer offset] )

    +

    + [page:Array array] - (opzionale) array per memorizzare il vettore risultante. In caso contrario, verrà creato un nuovo array.
    + [page:Integer offset] - (opzionale) offset nell'array in cui inserire il risultato.

    + + Scrive gli elementi di questa matrice in una matrice in formato + [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major]. +

    + +

    [method:this translate]( [param:Float tx], [param:Float ty] )

    +

    Trasla questa matrice dei valori scalari dati.

    + +

    [method:this transpose]()

    +

    [link:https://en.wikipedia.org/wiki/Transpose Traspone] questa matrice al suo posto.

    + +

    [method:this transposeIntoArray]( [param:Array array] )

    +

    + [page:Array array] - array per memorizzare il vettore risultante.

    + + [link:https://en.wikipedia.org/wiki/Transpose Traspone] questa matrice nell'array fornito, + e ritorna immutato. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Matrix4.html b/docs/api/it/math/Matrix4.html new file mode 100644 index 00000000000000..9c794001f03026 --- /dev/null +++ b/docs/api/it/math/Matrix4.html @@ -0,0 +1,418 @@ + + + + + + + + + +

    [name]

    + +

    + Una classe che rappresenta una [link:https://en.wikipedia.org/wiki/Matrix_(mathematics) matrice] 4x4.

    + + L'uso più comune di una matrice 4x4 nella grafica 3D è come una + [link:https://en.wikipedia.org/wiki/Transformation_matrix matrice di trasformazione]. + + Per un'introduzione alle matrici di trasformazione utilizzate in WebGL, + dai un'occhiata a [link:http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices questo tutorial].

    + + Ciò consente ad un [page:Vector3] che rappresenta un punto nello spazio 3D di subire trasformazioni come traslazione, rotazione + taglio, scala, riflessione, proiezione ortogonale o prospettica e così via, moltiplicandosi per la matrice. + Questo è noto come `applicare` la matrice al vettore.

    + + Ogni [page:Object3D] ha tre Matrix4 associate: +

      +
    • + [page:Object3D.matrix]: Questo memorizza la trasfomazione locale dell'oggetto. Questa è la trasformazione dell'oggetto rispetto al suo genitore. +
    • +
    • + [page:Object3D.matrixWorld]: La trasformazione globale o world dell'oggetto. Se l'oggetto non ha un genitore, allora questo è identico + alla trasformazione locale memorizzata nella [page:Object3D.matrix matrix]. +
    • +
    • + [page:Object3D.modelViewMatrix]: Questo rappresenta la trasformazione dell'oggetto rispetto al sistema di coordinate della telecamera. + Il modelViewMatrix dell'oggetto è il matrixWorld dell'oggetto pre-moltiplicato per il matrixWorldInverse della telecamera. +
    • +
    + + Le [page:Camera Telecamere] hanno tre Matrix4 addizionali: +
      +
    • + [page:Camera.matrixWorldInverse]: La matrice di visualizzazione - l'inversa della [page:Object3D.matrixWorld matrixWorld] della telecamera. +
    • +
    • + [page:Camera.projectionMatrix]: Rappresenta le informazioni su come proiettare la scena nello spazio di ritaglio. +
    • +
    • + [page:Camera.projectionMatrixInverse]: L'inverso della projectionMatrix. +
    • +
    + Nota: [page:Object3D.normalMatrix] non è una Matrix4, ma una [page:Matrix3]. +

    + +

    Una nota sull'ordine delle Row-Major (righe principali) e delle Column-Major (colonne principali)

    +

    + Il metodo [page:set]() accetta gli argomenti in ordine + [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order row-major], mentre internamente + vengono memorizzati nell'array [page:.elements elements] nell'ordine column-major.

    + + Ciò significa che la chiamata a + +const m = new THREE.Matrix4(); + +m.set( 11, 12, 13, 14, + 21, 22, 23, 24, + 31, 32, 33, 34, + 41, 42, 43, 44 ); + + + risulterà nell'array [page:.elements elements] contenente: + +m.elements = [ 11, 21, 31, 41, + 12, 22, 32, 42, + 13, 23, 33, 43, + 14, 24, 34, 44 ]; + + e internamente tutti i calcoli vengono eseguiti utilizzando l'ordine column-major. Tuttavia, poiché l'ordine + effettivo non fa alcune differenza matematicamente e la maggior parte delle persone è abituata a pensare alle + matrici nell'ordine row-major, la documentazione di three.js mostra le matrici in ordine di row-major. + Tieni solo a mente che se stai leggendo il codice sorgente, dovrai prendere la [link:https://en.wikipedia.org/wiki/Transpose trasposizione] + di tutte le matrici qui descritte per dare un senso ai calcoli. +

    + +

    Estrazione della posizione, della rotazione e del ridimensionamento

    +

    + Ci sono molte opzioni disponibili per l'estrazione della posizione, della rotazione e del ridimensionamento da una Matrix4. +

      +
    • + [page:Vector3.setFromMatrixPosition]: può essere utilizzato per estrarre il componente traslazione. +
    • +
    • + [page:Vector3.setFromMatrixScale]: può essere utilizzato per estrarre il componente ridimensionamento. +
    • +
    • + [page:Quaternion.setFromRotationMatrix], [page:Euler.setFromRotationMatrix] o [page:.extractRotation extractRotation] + può essere utilizzato per estrarre il componente rotazione da una matrice pura (non ridimensionata). +
    • +
    • + [page:.decompose decompose] può essere utilizzato per estrarre la posizione, la rotazione e il ridemsionamento tutti in uno. +
    • +
    +

    + +

    Costruttore

    + + +

    [name]()

    + +

    + Crea e inizializza [name] nella [link:https://en.wikipedia.org/wiki/Identity_matrix matrice] identità 4x4. +

    + +

    Proprietà

    + +

    [property:Array elements]

    +

    + Una lista di [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order column-major] + di valori della matrice. +

    + +

    Metodi

    + +

    [method:Matrix4 clone]()

    +

    Crea una nuova Matrix4 con gli [page:.elements elementi] identici a questa.

    + +

    [method:this compose]( [param:Vector3 position], [param:Quaternion quaternion], [param:Vector3 scale] )

    +

    + Imposta questa matrice sulla trasformazione composta da [page:Vector3 posizione], + [page:Quaternion quaternione] e [page:Vector3 ridimensionamento]. +

    + +

    [method:this copy]( [param:Matrix4 m] )

    +

    Copia gli [page:.elements elementi] della matrice [page:Matrix4 m] in questa matrice.

    + +

    [method:this copyPosition]( [param:Matrix4 m] )

    +

    + Copia il componente traslazione della matrice [page:Matrix4 m] fornita nel componente + trasformazione di questa matrice. +

    + +

    [method:this decompose]( [param:Vector3 position], [param:Quaternion quaternion], [param:Vector3 scale] )

    +

    + Decompone questa matrice nei suoi componenti [page:Vector3 posizione], [page:Quaternion quaternione] e [page:Vector3 ridimensionamento].

    + Nota: Non tutte le matrici si possono scomporre in questo modo. Per esempio, se un oggetto ha un genitore ridimensionato non uniformemente, + allora la matrice del mondo dell'oggetto potrebbe non essere scomponibile e questo metodo potrebbe non essere appropriato. +

    + +

    [method:Float determinant]()

    +

    + Calcola e restituisce il + [link:https://en.wikipedia.org/wiki/Determinant determinante] di questa matrice.

    + + Sulla base del metodo [link:http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm qui] descritto. +

    + +

    [method:Boolean equals]( [param:Matrix4 m] )

    +

    Restituisce true se questa matrice e [page:Matrix4 m] sono uguali.

    + +

    [method:this extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )

    +

    + Estrae la [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) base] di questa matrice + nei tre vettori asse forniti. Se questa matrice è: + +a, b, c, d, +e, f, g, h, +i, j, k, l, +m, n, o, p + + allora [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] saranno impostate a: + +xAxis = (a, e, i) +yAxis = (b, f, j) +zAxis = (c, g, k) + +

    + +

    [method:this extractRotation]( [param:Matrix4 m] )

    +

    + Estrae il componente rotazione della matrice [page:Matrix4 m] fornita nel componente rotazione di questa matrice. +

    + +

    [method:this fromArray]( [param:Array array], [param:Integer offset] )

    +

    + [page:Array array] - l'array da cui leggere gli elementi.
    + [page:Integer offset] - (opzionale) indice del primo elemento nell'array. Il valore predefinito è 0.

    + + Imposta gli elementi di questa matrice in base ad un array nel formato + [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major]. +

    + +

    [method:this invert]()

    +

    + Inverte questa matrice, utilizzando il [link:https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution metodo analitico]. + + Non puoi invertire con un determinante zero. Se si tenta questo, il metodo produce invece una matrice zero. +

    + +

    [method:Float getMaxScaleOnAxis]()

    +

    Ottiene il valore di ridimensionamento massimo dei 3 assi.

    + +

    [method:this identity]()

    +

    Reimposta questa matrice alla [link:https://en.wikipedia.org/wiki/Identity_matrix matrice] identità.

    + +

    [method:this lookAt]( [param:Vector3 eye], [param:Vector3 target], [param:Vector3 up] )

    +

    + Costruisce una matrice di rotazione, guardando dall'[page:Vector3 occhio] verso il [page:Vector3 target] orientato dal + vettore verso l'[page:Vector3 alto]. +

    + +

    [method:this makeRotationAxis]( [param:Vector3 axis], [param:Float theta] )

    +

    + [page:Vector3 axis] — Asse di rotazione, deve essere normalizzata.
    + [page:Float theta] — Angolo di rotazione in radianti.

    + + Imposta questa matrice come trasformazione di rotazione attorno all'[page:Vector3 asse] di [page:Float theta] radianti.
    + + Questa è un'alternativa alquanto controversa ma matematicamente valida alla rotazione tramite [page:Quaternion Quaternions]. + Vedi la discussione [link:https://www.gamedev.net/articles/programming/math-and-physics/do-we-really-need-quaternions-r1199 qui]. +

    + +

    [method:this makeBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )

    +

    + Imposta questo sulla matrice di [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) base] composta dai tre + vettori di base forniti: + +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 + +

    + +

    [method:this makePerspective]( [param:Float left], [param:Float right], [param:Float top], [param:Float bottom], [param:Float near], [param:Float far] )

    +

    + Crea una matrice di [link:https://en.wikipedia.org/wiki/3D_projection#Perspective_projection proiezione prospettica]. + Questa è utilizzata internamente da [page:PerspectiveCamera.updateProjectionMatrix](). +

    + +

    [method:this makeOrthographic]( [param:Float left], [param:Float right], [param:Float top], [param:Float bottom], [param:Float near], [param:Float far] )

    +

    + Crea una matrice di [link:https://en.wikipedia.org/wiki/Orthographic_projection proiezione ortografica]. + Questa è utilizzata internamente da [page:OrthographicCamera.updateProjectionMatrix](). +

    + +

    [method:this makeRotationFromEuler]( [param:Euler euler] )

    +

    + Imposta il componente rotazione (la matrice 3x3 in alto a sinistra) di questa matrice sulla rotazione specificata dal dato [page:Euler Angolo di Eulero]. + Il resto della matrice è impostato sull'identità. A seconda dell'[page:Euler.order ordine] di [page:Euler Eulero], ci sono sei possibili esisti. + Vedi [link:https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix questa pagina] per una lista completa. +

    + +

    [method:this makeRotationFromQuaternion]( [param:Quaternion q] )

    +

    + Imposta il componente rotazinoe di questa matrice alla rotazione specificata da [page:Quaternion q], come + descritto [link:https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion qui]. + Il resto della matrice è impostato all'identità. Quindi, dato [page:Quaternion q] = w + xi + yj + zk, la matrice risultante sarà: + +1-2y²-2z² 2xy-2zw 2xz+2yw 0 +2xy+2zw 1-2x²-2z² 2yz-2xw 0 +2xz-2yw 2yz+2xw 1-2x²-2y² 0 +0 0 0 1 + +

    + +

    [method:this makeRotationX]( [param:Float theta] )

    +

    + [page:Float theta] — Angolo rotazione in radianti.

    + + Imposta questa matrice come una trasformazione rotazionale attorno all'asse X in radianti theta [page:Float theta] (θ). + La matrice risultante sarà: + +1 0 0 0 +0 cos(θ) -sin(θ) 0 +0 sin(θ) cos(θ) 0 +0 0 0 1 + +

    + +

    [method:this makeRotationY]( [param:Float theta] )

    +

    + [page:Float theta] — Angolo rotazione in radianti.

    + + Imposta questa matrice come una trasformazione rotazionale attorno all'asse Y in radianti theta [page:Float theta] (θ). + La matrice risultante sarà: + +cos(θ) 0 sin(θ) 0 +0 1 0 0 +-sin(θ) 0 cos(θ) 0 +0 0 0 1 + +

    + +

    [method:this makeRotationZ]( [param:Float theta] )

    +

    + [page:Float theta] — Angolo rotazione in radianti.

    + + Imposta questa matrice come una trasformazione rotazionale attorno all'asse Z in radianti theta [page:Float theta] (θ). + La matrice risultante sarà: + +cos(θ) -sin(θ) 0 0 +sin(θ) cos(θ) 0 0 +0 0 1 0 +0 0 0 1 + +

    + +

    [method:this makeScale]( [param:Float x], [param:Float y], [param:Float z] )

    +

    + [page:Float x] - la quantità da scalare sull'asse X.
    + [page:Float y] - la quantità da scalare sull'asse Y.
    + [page:Float z] - la quantità da scalare sull'asse Z.

    + + Imposta questa matrice come trasformazione di scala: + +x, 0, 0, 0, +0, y, 0, 0, +0, 0, z, 0, +0, 0, 0, 1 + +

    + +

    [method:this makeShear]( [param:Float xy], [param:Float xz], [param:Float yx], [param:Float yz], [param:Float zx], [param:Float zy] )

    +

    + [page:Float xy] - la quantità di taglio di X per Y.
    + [page:Float xz] - la quantità di taglio di X per Z.
    + [page:Float yx] - la quantità di taglio di Y per X.
    + [page:Float yz] - la quantità di taglio di Y per Z.
    + [page:Float zx] - la quantità di taglio di Z per X.
    + [page:Float zy] - la quantità di taglio di Z per Y.

    + + Imposta questa matrice come trasformata di taglio: + +1, yx, zx, 0, +xy, 1, zy, 0, +xz, yz, 1, 0, +0, 0, 0, 1 + +

    + +

    [method:this makeTranslation]( [param:Float x], [param:Float y], [param:Float z] )

    +

    + [page:Float x] - la quantità da translare sull'asse X.
    + [page:Float y] - la quantità da translare sull'asse Y.
    + [page:Float z] - la quantità da translare sull'asse Z.

    + + Imposta questa matrice come una trasformata di traslazione: + +1, 0, 0, x, +0, 1, 0, y, +0, 0, 1, z, +0, 0, 0, 1 + +

    + +

    [method:this multiply]( [param:Matrix4 m] )

    +

    Post-moltiplica questa matrice per [page:Matrix4 m].

    + +

    [method:this multiplyMatrices]( [param:Matrix4 a], [param:Matrix4 b] )

    +

    Imposta questa matrice a [page:Matrix4 a] x [page:Matrix4 b].

    + +

    [method:this multiplyScalar]( [param:Float s] )

    +

    Moltiplica ogni componente della matrice per il valore scalare [page:Float s].

    + +

    [method:this premultiply]( [param:Matrix4 m] )

    +

    Pre-moltiplica questa matrice per [page:Matrix4 m].

    + +

    [method:this scale]( [param:Vector3 v] )

    +

    Moltiplica le colonne di questa matrice per il vettore [page:Vector3 v].

    + +

    [method:this set]( [param:Float n11], [param:Float n12], [param:Float n13], [param:Float n14], [param:Float n21], [param:Float n22], [param:Float n23], [param:Float n24], [param:Float n31], [param:Float n32], [param:Float n33], [param:Float n34], [param:Float n41], [param:Float n42], [param:Float n43], [param:Float n44] )

    +

    + Imposta gli [page:.elements elementi] di questa matrice ai valori principali di row-major forniti [page:Float n11], + [page:Float n12], ... [page:Float n44]. +

    + +

    [method:this setFromMatrix3]( [param:Matrix3 m] )

    +

    Imposta gli elementi 3x3 superiori di questa matrice sui valori di Matrix3 [page:Matrix3 m].

    + +

    [method:this setPosition]( [param:Vector3 v] )

    +

    [method:this setPosition]( [param:Float x], [param:Float y], [param:Float z] ) // optional API

    +

    + Imposta la componente posizione per questa matrice dal vettore [page:Vector3 v], senza influenzare + il resto della matrice - ovvero se la matrice è attulmente: + +a, b, c, d, +e, f, g, h, +i, j, k, l, +m, n, o, p + +Questa diventa: + +a, b, c, v.x, +e, f, g, v.y, +i, j, k, v.z, +m, n, o, p + +

    + +

    [method:Array toArray]( [param:Array array], [param:Integer offset] )

    +

    + [page:Array array] - (opzionale) array per memorizzare il vettore risultante.
    + [page:Integer offset] - (opzionale) offset nell'array in cui inserire il risultato.

    + + Scrive gli elementi di questa matrice in una matrice in formato + [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major]. +

    + +

    [method:this transpose]()

    +

    [link:https://en.wikipedia.org/wiki/Transpose Traspone] questa matrice.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Plane.html b/docs/api/it/math/Plane.html new file mode 100644 index 00000000000000..b2a405140ea098 --- /dev/null +++ b/docs/api/it/math/Plane.html @@ -0,0 +1,181 @@ + + + + + + + + + +

    [name]

    + +

    + Una superficie bidimensionale che si estende all'infinito nello spazio 3D, + rappresentata in [link:http://mathworld.wolfram.com/HessianNormalForm.html forma normale Hessiana] + da un vettore normale di lunghezza unitaria e una costante. +

    + + +

    Costruttore

    + + +

    [name]( [param:Vector3 normal], [param:Float constant] )

    +

    + [page:Vector3 normal] - (opzionale) un [page:Vector3] di lunghezza unitaria che definisce la normale del piano. Il valore predefinito è *(1, 0, 0)*.
    + [page:Float constant] - (opzionale) la distanza con segno dall'origine al piano. Il valore predefinito è `0`. +

    + + +

    Proprietà

    + +

    [property:Boolean isPlane]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:Vector3 normal]

    + +

    [property:Float constant]

    + +

    Metodi

    + +

    [method:this applyMatrix4]( [param:Matrix4 matrix], [param:Matrix3 optionalNormalMatrix] )

    +

    + [page:Matrix4 matrix] - la [Page:Matrix4] da applicare.
    + [page:Matrix3 optionalNormalMatrix] - (opzionale) [Page:Matrix3] normale pre-calcolata della Matrix4 da applicare.

    + + Applica una Matrix4 al piano. La matrice deve essere una trasformata affine e omogenea.
    + Se si fornisce una [page:Matrix3 optionalNormalMatrix], può essere creata in questo modo: + + const optionalNormalMatrix = new THREE.Matrix3().getNormalMatrix( matrix ); + +

    + +

    [method:Plane clone]()

    +

    Restituisce un nuovo piano con la stessa [page:.normal normal] e [page:.constant constant] di questo piano.

    + +

    [method:Vector3 coplanarPoint]( [param:Vector3 target] )

    +

    + [page:Vector3 target] — il risultato verrà copiato in questo Vector3.

    + + Restituisce un [page:Vector3] complanare al piano, calcolando la proiezione del vettore normale all'origine sul piano. +

    + +

    [method:this copy]( [param:Plane plane] )

    +

    + Copia i valori delle proprietà [page:.normal normal] e [page:.constant constant] del piano passato in questo piano. +

    + +

    [method:Float distanceToPoint]( [param:Vector3 point] )

    +

    Restituisce la distanza con segno dal [page:Vector3 point] al piano.

    + +

    [method:Float distanceToSphere]( [param:Sphere sphere] )

    +

    Restituisce la distanza con segno dalla [page:Sphere sphere] al piano.

    + +

    [method:Boolean equals]( [param:Plane plane] )

    +

    + Controlla se due piani sono uguali (le loro proprietà [page:.normal normal] e + [page:.constant constant] coincidono). +

    + +

    [method:Vector3 intersectLine]( [param:Line3 line], [param:Vector3 target] )

    +

    + [page:Line3 line] - [page:Line3] per verificare l'intersezione.
    + [page:Vector3 target] — il risultato verrà copiato in questo Vector3.

    + + Restituisce il punto di intersezione tra la linea passata e il piano. Restituisce `null` + se la linea non interseca il piano. Restituisce il punto di partenza della linea se la + linea è complanare al piano. +

    + +

    [method:Boolean intersectsBox]( [param:Box3 box] )

    +

    + [page:Box3 box] - il [page:Box3] per verificare l'intersezione.

    + + Determina se questo piano interseca il [page:Box3 box] o no. +

    + +

    [method:Boolean intersectsLine]( [param:Line3 line] )

    +

    + [page:Line3 line] - la [page:Line3] per verificare l'intersezione.

    + + Verifica se un segmento di linea si interseca (passa attraverso) il piano o no. +

    + +

    [method:Boolean intersectsSphere]( [param:Sphere sphere] )

    +

    + [page:Sphere sphere] - la [page:Sphere] per verificare l'intersezione.

    + + Determina se questo piano interseca la [page:Sphere sphere] o no. +

    + +

    [method:this negate]()

    +

    + Nega sia la normale che la costante. +

    + +

    [method:this normalize]()

    +

    + Normalizza il vettore [page:.normal normal], e aggiusta di conseguenza il valore della + [page:.constant constant]. +

    + +

    [method:Vector3 projectPoint]( [param:Vector3 point], [param:Vector3 target] )

    +

    + [page:Vector3 point] - il [page:Vector3] da proiettare sul piano.
    + [page:Vector3 target] — il risultato verrà copiato in questo Vector3.

    + + Proietta un [page:Vector3 point] sul piano. +

    + +

    [method:this set]( [param:Vector3 normal], [param:Float constant] )

    +

    + [page:Vector3 normal] - un [page:Vector3] di lunghezza unitaria che definisce la normale del piano.
    + [page:Float constant] - la distanza con segno dall'origine al piano. Il valore predefinito è `0`.

    + + Imposta le proprietà [page:.normal normal] e [page:.constant constant] del piano copiando i valori dalla normale data. +

    + +

    [method:this setComponents]( [param:Float x], [param:Float y], [param:Float z], [param:Float w] )

    +

    + [page:Float x] - x valore del vettore normale di lunghezza unitaria.
    + [page:Float y] - y valore del vettore normale di lunghezza unitaria.
    + [page:Float z] - z valore del vettore normale di lunghezza unitaria.
    + [page:Float w] - il valore della proprieà [page:.constant constant] del piano.

    + + Imposta i singoli componenti che definiscono il piano. +

    + +

    [method:this setFromCoplanarPoints]( [param:Vector3 a], [param:Vector3 b], [param:Vector3 c] )

    +

    + [page:Vector3 a] - primo punto sul piano.
    + [page:Vector3 b] - secondo punto sul piano.
    + [page:Vector3 c] - terzo punto sul piano.

    + + Definisce il piano in base ai 3 punti forniti. Si presume che l'ordine di avvolgimento sia in senso antiorario, + e determina la direzione della [page:.normal normale]. +

    + +

    [method:this setFromNormalAndCoplanarPoint]( [param:Vector3 normal], [param:Vector3 point] )

    +

    + [page:Vector3 normal] - un [page:Vector3] di lunghezza unitaria che definisce la normale del piano.
    + [page:Vector3 point] - [page:Vector3]

    + + Imposta le proprietà del piano definite da una [page:Vector3 normale] e un [page:Vector3 punto] complanare arbitrario. +

    + +

    [method:this translate]( [param:Vector3 offset] )

    +

    + [page:Vector3 offset] - la quantità di cui muovere il piano.

    + + Trasla il piano della distanza definita dal vettore [page:Vector3 offset]. + Si noti che questo influisce solo la costante del piano e non influenzerà il vettore normale. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Quaternion.html b/docs/api/it/math/Quaternion.html new file mode 100644 index 00000000000000..129ce9cb8949e4 --- /dev/null +++ b/docs/api/it/math/Quaternion.html @@ -0,0 +1,264 @@ + + + + + + + + + +

    [name]

    + +

    + Implementazione di un [link:http://en.wikipedia.org/wiki/Quaternion quaternione].
    + I quaternioni sono utilizzati in three.js per rappresentare le [link:https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation rotazioni]. +

    + +

    + L'iterazione di un'istanza di [name] produrrà le sue componenti (x, y, z, w) nell'ordine corrispondente. +

    + +

    Codice di Esempio

    + + + const quaternion = new THREE.Quaternion(); + quaternion.setFromAxisAngle( new THREE.Vector3( 0, 1, 0 ), Math.PI / 2 ); + + const vector = new THREE.Vector3( 1, 0, 0 ); + vector.applyQuaternion( quaternion ); + + + +

    Costruttore

    + + +

    [name]( [param:Float x], [param:Float y], [param:Float z], [param:Float w] )

    +

    + [page:Float x] - coordinata x.
    + [page:Float y] - coordinata y.
    + [page:Float z] - coordinata z.
    + [page:Float w] - coordinata w. +

    + + +

    Proprietà

    + +

    [property:Boolean isQuaternion]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:Float x]

    + +

    [property:Float y]

    + +

    [property:Float z]

    + +

    [property:Float w]

    + + +

    Metodi

    + +

    [method:Float angleTo]( [param:Quaternion q] )

    +

    + Restituisce l'angolo tra questo quaternione e il quaternione [page:Quaternion q] in radianti. +

    + +

    [method:Quaternion clone]()

    +

    + Crea un nuovo [name] con le proprietà [page:.x x], [page:.y y], + [page:.z z] e [page:.w w] identiche a questo. +

    + +

    [method:this conjugate]()

    +

    + Restituisce il coniugato rotazionale di questo quaternione. Il coniugato di un quaternione + rappresenta la stessa rotazione nella direzione opposta rispetto all'asse di rotazione. +

    + +

    [method:this copy]( [param:Quaternion q] )

    +

    + Copia le proprietà [page:.x x], [page:.y y], [page:.z z] e [page:.w w] di + [page:Quaternion q] in questo quaterione. +

    + +

    [method:Boolean equals]( [param:Quaternion v] )

    +

    + [page:Quaternion v] - Quaterione a cui verrà paragonato questo quaternione.

    + + Compara le proprietà [page:.x x], [page:.y y], [page:.z z] and [page:.w w] di + [page:Quaternion v] alle proprietà equivalenti di questo quaternione per determinare + se rappresentano la stessa rotazione. +

    + +

    [method:Float dot]( [param:Quaternion v] )

    +

    + Calcola il [link:https://en.wikipedia.org/wiki/Dot_product prodotto scalare] dei + quaternioni [page:Quaternion v] e questo. +

    + +

    [method:this fromArray]( [param:Array array], [param:Integer offset] )

    +

    + [page:Array array] - array di formato (x, y, z, w) utilizzato per costruire il quaternione.
    + [page:Integer offset] - (opzionale) un offset nell'array.

    + + Imposta le proprietà [page:.x x], [page:.y y], [page:.z z] e [page:.w w] di questo quaternione + da un array. +

    + +

    [method:this identity]()

    +

    + Imposta questo quaternione al quaterione identità; cioè al quaternione che rappresenta "nessuna rotazione". +

    + +

    [method:this invert]()

    +

    + Inverte questo quaternione - calcola il [page:.conjugate coniugato]. Si presume che il quaternione abbia lunghezza unitaria. +

    + +

    [method:Float length]()

    +

    Calcola la [link:https://en.wikipedia.org/wiki/Euclidean_distance lunghezza Euclidea] + (lunghezza in linea retta) di questo quaternione, considerato come un vettore a quattro dimensioni. +

    + +

    [method:Float lengthSq]()

    +

    + Calcola la radice della [link:https://en.wikipedia.org/wiki/Euclidean_distance lunghezza Euclidea] + (lunghezza in linea retta) di questo quaternione, considerato come un vettore a quattro dimensioni. + Questo può essere utile se stai confrontando le lunghezze di due quaternioni, + poiché questo è un calcolo leggermente più efficiente di [page:.length length](). +

    + +

    [method:this normalize]()

    +

    + [link:https://en.wikipedia.org/wiki/Normalized_vector Normalizza] questo quaternione - cioè, + calcolato il quaternione che esegue la stessa rotazione di questo, ma con [page:.length lunghezza] + uguale a `1`. +

    + +

    [method:this multiply]( [param:Quaternion q] )

    +

    Moltiplica questo quaternione per [page:Quaternion q].

    + +

    [method:this multiplyQuaternions]( [param:Quaternion a], [param:Quaternion b] )

    +

    + Imposta questo quaternione a [page:Quaternion a] x [page:Quaternion b].
    + Adattato dal metodo descritto [link:http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm qui]. +

    + +

    [method:this premultiply]( [param:Quaternion q] )

    +

    Pre-moltiplica questo quaternione per [page:Quaternion q].

    + +

    [method:this random]()

    +

    + Imposta questo quaternione ad un quaternione normalizzato uniformemente casuale. +

    + +

    [method:this rotateTowards]( [param:Quaternion q], [param:Float step] )

    +

    + [page:Quaternion q] - Il target quaternione.
    + [page:Float step] - Il passo angolare in radianti.

    + + Ruota questo quaternione di un dato passo angolare al quaternione definito *q*. + Il metodo assicura che il quaternione finale non superi *q*. +

    + +

    [method:this slerp]( [param:Quaternion qb], [param:Float t] )

    +

    + [page:Quaternion qb] - L'altra rotazione del quaternione.
    + [page:Float t] - Fattore di interpolazione nell'intervallo chiuso `[0, 1]`.

    + + Gestisce l'interpolazione lineare tra i quaternioni. [page:Float t] rappresenta la quantità di rotazione + tra questo quaternione (dove [page:Float t] è 0) e [page:Quaternion qb] (dove + [page:Float t] è 1). Questo quaternione è impostato sul risultato. Vedi, anche, la versione + statica dello `slerp` qui sotto. + + + // ruota una mesh verso un quaternione target + mesh.quaternion.slerp( endQuaternion, 0.01 ); + +

    + +

    [method:this slerpQuaternions]( [param:Quaternion qa], [param:Quaternion qb], [param:Float t] )

    +

    Esegue un'interpolazione sferica lineare tra i quaternioni dati e memorizza il risultato in questo quaternione.

    + +

    [method:this set]( [param:Float x], [param:Float y], [param:Float z], [param:Float w] )

    +

    Imposta le proprietà [page:.x x], [page:.y y], [page:.z z], [page:.w w] di questo quaternione.

    + +

    [method:this setFromAxisAngle]( [param:Vector3 axis], [param:Float angle] )

    +

    + Imposta questo quaternione dalla rotazione specificata dall'[page:Vector3 asse] e dall'[page:Float angolo].
    + Adattato dal metodo [link:http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm qui].
    + Si presume che l'`asse` sia normalizzato e l'`angolo` sia in radianti. +

    + +

    [method:this setFromEuler]( [param:Euler euler] )

    +

    Imposta questo quaternione dalla rotazione specificata dall'angolo di [page:Eulero].

    + +

    [method:this setFromRotationMatrix]( [param:Matrix4 m] )

    +

    + [page:Matrix4 m] - una [page:Matrix4] di cui il 3x3 superiore della matrice è una + [link:https://en.wikipedia.org/wiki/Rotation_matrix matrice di rotazione] pura (cioè non ridimensionata).
    + Imposta questo quaternione dalla componente di rotazione di [page:Matrix4 m].
    + Adattato dal metodo [link:http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm qui]. +

    + +

    [method:this setFromUnitVectors]( [param:Vector3 vFrom], [param:Vector3 vTo] )

    +

    + Imposta questo quaterione alla rotazinoe richiesta per ruotare il vettore di direzione [page:Vector3 vFrom] a + [page:Vector3 vTo].
    + Adattato dal metodo [link:http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors qui].
    + Si presume che [page:Vector3 vFrom] e [page:Vector3 vTo] siano normalizzati. +

    + +

    [method:Array toArray]( [param:Array array], [param:Integer offset] )

    +

    + [page:Array array] - Un array facoltativo per memorizzare il quaternione. Se non specificato, verrà creato un nuovo array.
    + [page:Integer offset] - (opzionale) se specificato, il risultato verrà copiato in questo [page:Array].

    + + Restituisce gli elementi numerici di questo quaternione in un array del formato [x, y, z, w]. +

    + +

    [method:this fromBufferAttribute]( [param:BufferAttribute attribute], [param:Integer index] )

    +

    + [page:BufferAttribute attribute] - l'attributo sorgente.
    + [page:Integer index] - l'indice dell'attributo.

    + + Imposta le proprietà [page:.x x], [page:.y y], [page:.z z], [page:.w w] di questo quaternione dall'[page:BufferAttribute attributo]. +

    + +

    Metodi Statici

    + +

    [method:undefined slerpFlat]( [param:Array dst], [param:Integer dstOffset], [param:Array src0], [param:Integer srcOffset0], [param:Array src1], [param:Integer srcOffset1], [param:Float t] )

    +

    + [page:Array dst] - L'array di output.
    + [page:Integer dstOffset] - Un offset nell'array di output.
    + [page:Array src0] - L'array sorgente del quaternione iniziale.
    + [page:Integer srcOffset0] - Un offset nell'array `src0`.
    + [page:Array src1] - L'array sorgente del quaternione target.
    + [page:Integer srcOffset1] - Un offset nell'array `src1`.
    + [page:Float t] - Fattore di interpolazione normalizzato (tra 0 e 1).

    + + Questa implementazione SLERP presuppone che i dati del quaternione siano gestiti in array flat. +

    + +

    [method:Array multiplyQuaternionsFlat]( [param:Array dst], [param:Integer dstOffset], [param:Array src0], [param:Integer srcOffset0], [param:Array src1], [param:Integer srcOffset1] )

    +

    + [page:Array dst] - L'array di output.
    + [page:Integer dstOffset] - Un offset nell'array di output.
    + [page:Array src0] - L'array sorgente del quaternione iniziale.
    + [page:Integer srcOffset0] - Un offset nell'array `src0`.
    + [page:Array src1] - L'array sorgente del quaternione target.
    + [page:Integer srcOffset1] - Un offset nell'array `src1`.

    + + Questa implementazione della moltiplicazione presuppone che i dati del quaterione siano gestiti in array flat. +

    + + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Ray.html b/docs/api/it/math/Ray.html new file mode 100644 index 00000000000000..468207b2eef1e9 --- /dev/null +++ b/docs/api/it/math/Ray.html @@ -0,0 +1,210 @@ + + + + + + + + + +

    [name]

    + +

    + Un raggio che parte da un'origine e si dirige in una determinata direzione. Questo viene utilizzato + dal [page:Raycaster] per assistere il raycasting. Il raycasting viene utilizzato per selezionare + con il mouse (elaborare su quali oggetti nello spazio 3D si trova il mouse) tra le altre cose. +

    + + +

    Costruttore

    + + +

    [name]( [param:Vector3 origin], [param:Vector3 direction] )

    +

    + [page:Vector3 origin] - (opzionale) l'origine del [page:Ray raggio]. Il valore predefinito è un [page:Vector3] a (0, 0, 0).
    + [page:Vector3 direction] - [page:Vector3] La direzione del [page:Ray raggio]. Deve essere normalizzato + (con [page:Vector3.normalize]) affinchè i metodi funzionino correttamente. Il valore predefinito è [page:Vector3] a (0, 0, -1).

    + + Crea un nuovo [name]. +

    + +

    Proprietà

    + +

    [property:Vector3 origin]

    +

    L'origine del [page:Ray raggio]. Il valore predefinito è un [page:Vector3] a `(0, 0, 0)`.

    + +

    [property:Vector3 direction]

    +

    + La direzione del [page:Ray raggio]. Deve essere normalizzato (con [page:Vector3.normalize]) + affinchè i metodi funzionino correttamente. Il valore predefinito è un [page:Vector3] a (0, 0, -1). +

    + + +

    Metodi

    + +

    [method:this applyMatrix4]( [param:Matrix4 matrix4] )

    +

    + [page:Matrix4 matrix4] - la [page:Matrix4] da applicare a questo [page:Ray raggio].

    + + Trasforma questo [page:Ray raggio] con [page:Matrix4]. +

    + +

    [method:Vector3 at]( [param:Float t], [param:Vector3 target] )

    +

    + [page:Float t] - la distanza lungo il [page:Ray raggio] per la quale recuperare una posizione.
    + [page:Vector3 target] — il risultato sarà copiato in questo Vector3.

    + + Ottiene un [page:Vector3] che corrisponde a una determinata distanza lungo questo [page:Ray raggio]. +

    + +

    [method:Ray clone]()

    +

    + Crea un nuovo raggio con [page:.origin origine] e [page:.direction direzione] identiche a questo. +

    + +

    [method:Vector3 closestPointToPoint]( [param:Vector3 point], [param:Vector3 target] )

    +

    + [page:Vector3 point] - il punto a cui avvicinarsi di più.
    + [page:Vector3 target] — il risultato verrà copiato in questo Vector3.

    + + Ottiene il punto lungo questo [page:Ray raggio] che è il più vicino al [page:Vector3] fornito. +

    + +

    [method:this copy]( [param:Ray ray] )

    +

    + Copia le proprietà [page:.origin origine] e [page:.direction direzione] + del [page:Ray raggio] in questo raggio. +

    + +

    [method:Float distanceSqToPoint]( [param:Vector3 point] )

    +

    + [page:Vector3 point] - il [page:Vector3] per calcolare una distanza.

    + + Ottiene la distanza al quadrato dell'avvicinamento più vicino tra il [page:Ray raggio] e il [page:Vector3]. +

    + +

    [method:Float distanceSqToSegment]( [param:Vector3 v0], [param:Vector3 v1], [param:Vector3 optionalPointOnRay], [param:Vector3 optionalPointOnSegment] )

    +

    + [page:Vector3 v0] - l'inizio del segmento.
    + [page:Vector3 v1] - la fine del segmento.
    + optionalPointOnRay - (opzionale) se viene fornito, riceve il punto su questo + [page:Ray raggio] più vicino al segmento.
    + optionalPointOnSegment - (opzionale) se viene fornito, riceve il punto + sul segmento più vicino al [page:Ray raggio].

    + + Ottiene la distanza al quadrato tra questo [page:Ray raggio] e un segmento. +

    + +

    [method:Float distanceToPlane]( [param:Plane plane] )

    +

    + [page:Plane plane] - il [page:Plane] per ottenere la distanza.

    + + Ottiene la distanza tra l'[page:.origin origine] e il [page:Plane piano], o `null` se il [page:Ray raggio] non interseca il [page:Plane piano]. +

    + +

    [method:Float distanceToPoint]( [param:Vector3 point] )

    +

    + [page:Vector3 point] - Il [page:Vector3] su cui calcolare la distanza.

    + + Ottiene la distanza dell'avvicinamento più vicino tra il [page:Ray raggio] e il [page:Vector3 punto]. +

    + + +

    [method:Boolean equals]( [param:Ray ray] )

    +

    + [page:Ray ray] - il [page:Ray raggio] su cui confrontare.

    + + Restituisce true se questo e l'altro [page:Ray raggio] hanno [page:.origin origine] + e [page:.direction direzione] uguali. +

    + +

    [method:Vector3 intersectBox]( [param:Box3 box], [param:Vector3 target] )

    +

    + [page:Box3 box] - il [page:Box3] con cui intersecare.
    + [page:Vector3 target] — il risultato verrà copiato in questo Vector3.

    + + Interseca questo [page:Ray raggio] con un [page:Box3], restituendo il punto di intersezione o + `null` se non ci sono intersezioni. +

    + +

    [method:Vector3 intersectPlane]( [param:Plane plane], [param:Vector3 target] )

    +

    + [page:Plane plane] - il [page:Plane] con cui intersecare.
    + [page:Vector3 target] — il risultato verrà copiato in questo Vector3.

    + + Interseca questo [page:Ray raggio] con un [page:Plane], restituendo il punto di intersezione o + `null` se non ci sono intersezioni. +

    + +

    [method:Vector3 intersectSphere]( [param:Sphere sphere], [param:Vector3 target] )

    +

    + [page:Sphere sphere] - la [page:Sphere] con cui intersecare.
    + [page:Vector3 target] — il risultato verrà copiato in questo Vector3.

    + + Interseca questo [page:Ray raggio] con una [page:Sphere], restituendo il punto di intersezione o + `null` se non ci sono intersezioni. +

    + +

    [method:Vector3 intersectTriangle]( [param:Vector3 a], [param:Vector3 b], [param:Vector3 c], [param:Boolean backfaceCulling], [param:Vector3 target] )

    +

    + [page:Vector3 a], [page:Vector3 b], [page:Vector3 c] - I punti [page:Vector3] che compongono il triangolo.
    + [page:Boolean backfaceCulling] - se utilizzare backface culling o meno.
    + [page:Vector3 target] — il risultato verrà copiato in questo Vector3.

    + + Interseca questo [page:Ray raggio] con un triangolo, restituendo il punto di intersezione o + `null` se non ci sono intersezioni. +

    + +

    [method:Boolean intersectsBox]( [param:Box3 box] )

    +

    + [page:Box3 box] - il [page:Box3] con cui intersecare.

    + + Restituisce true se questo [page:Ray raggio] si interseca con il [page:Box3]. +

    + +

    [method:Boolean intersectsPlane]( [param:Plane plane] )

    +

    + [page:Plane plane] - il [page:Plane] con cui intersecare.

    + + Restituisce true se questo [page:Ray raggio] si interseca con il [page:Plane]. +

    + +

    [method:Boolean intersectsSphere]( [param:Sphere sphere] )

    +

    + [page:Sphere sphere] - la [page:Sphere] con cui intersecare.

    + + Restituisce true se questo [page:Ray raggio] si interseca con la [page:Sphere]. +

    + +

    [method:this lookAt]( [param:Vector3 v] )

    +

    + [page:Vector3 v] - Il [page:Vector3] da guardare.

    + + Regola la direzione del raggio in modo che punti al vettore nelle coordinate world. +

    + +

    [method:this recast]( [param:Float t] )

    +

    + [page:Float t] - La distanza lungo il [page:Ray raggio] da interpolare.

    + + Sposta l'origine di questo [page:Ray raggio] lungo le sue direzione per la distanza data. +

    + +

    [method:this set]( [param:Vector3 origin], [param:Vector3 direction] )

    +

    + [page:Vector3 origin] - l'[page:.origin origine] del [page:Ray raggio].
    + [page:Vector3 origin] - la [page:.direction direzione] del [page:Ray raggio]. + Deve essere normalizzato (con [page:Vector3.normalize]) affinchè i metodi funzionino correttamente.

    + + Imposta le proprietà [page:.origin origine] e [page:.direction direzione] di questo raggio copiando i valori dagli oggetti dati. +

    + + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Sphere.html b/docs/api/it/math/Sphere.html new file mode 100644 index 00000000000000..a1e4be8375bb98 --- /dev/null +++ b/docs/api/it/math/Sphere.html @@ -0,0 +1,160 @@ + + + + + + + + + +

    [name]

    + +

    Una sfera definita da un centro e un raggio.

    + +

    Costruttore

    +

    [name]( [param:Vector3 center], [param:Float radius] )

    +

    + [page:Vector3 center] - centro della sfera. Il valore predefinito è un [page:Vector3] a `(0, 0, 0)`.
    + [page:Float radius] - raggio della sfera. Il valore predefinito è -1.

    + + Crea una nuova [name]. + +

    + + +

    Proprietà

    + + +

    [property:Vector3 center]

    +

    Un [page:Vector3] che definisce il centro della sfera. Il valore predefinito è `(0, 0, 0)`.

    + +

    [property:Float radius]

    +

    Il raggio della sfera. Il valore predefinito è -1.

    + +

    Metodi

    + +

    [method:this applyMatrix4]( [param:Matrix4 matrix] )

    +

    + [page:Matrix4 matrix] - [Page:Matrix4] da applicare.

    + + Trasforma questa sfera con la [page:Matrix4] fornita. +

    + +

    [method:Vector3 clampPoint]( [param:Vector3 point], [param:Vector3 target] )

    +

    + [page:Vector3 point] - [page:Vector3] Il punto da bloccare.
    + [page:Vector3 target] — Il risultato verrà copiato in questo Vector3.

    + + Blocca un punto all'interno della sfera. Se il punto è fuori dalla sfera, lo bloccherà al punto + più vicino sul bordo della sfera. I punti già all'interno della sfera non saranno influenzati. +

    + +

    [method:Sphere clone]()

    +

    Restituisce un nuova sfera con lo stesso [page:.center centro] e [page:.radius raggio] di questa.

    + +

    [method:Boolean containsPoint]( [param:Vector3 point] )

    +

    + [page:Vector3 point] - il [page:Vector3] da controllare.

    + + Controlla se la sfera contiene il [page:Vector3 punto] fornito comprensivo della superficie della sfera. +

    + +

    [method:this copy]( [param:Sphere sphere] )

    +

    + Copia i valori delle proprietà [page:.center centro] e [page:.radius raggio] della sfera passata + in questa sfera. +

    + +

    [method:Float distanceToPoint]( [param:Vector3 point] )

    +

    + Restituisce la distanza più vicina dal confine della sfera al [page:Vector3 punto]. Se la sfera contiene il punto, + la distanza sarà negativa. +

    + +

    [method:this expandByPoint]( [param:Vector3 point] )

    +

    + [page:Vector3 point] - [page:Vector3] che da includere nella sfera.

    + + Espande i confini della sfera per includere il [page:Vector3 punto]. +

    + +

    [method:Boolean isEmpty]()

    +

    + Controlla se la sfera è vuota (il raggio impostato ad un numero negativo).
    + Le sfere con un raggio di 0 contengono solo il loro punto centrale e non sono considerate vuote. +

    + +

    [method:this makeEmpty]()

    +

    Rende la sfera vuota impostando il [page:.center centro] a (0, 0, 0) e il [page:.radius raggio] a -1.

    + +

    [method:Boolean equals]( [param:Sphere sphere] )

    +

    + Controlla se i due centri e i due raggi sono uguali. +

    + +

    [method:Box3 getBoundingBox]( [param:Box3 target] )

    +

    + [page:Box3 target] — Il risultato verrà copiato in questo Box3.

    + + Restituisce un [link:https://en.wikipedia.org/wiki/Minimum_bounding_box Minimum Bounding Box] per la sfera. +

    + +

    [method:Boolean intersectsBox]( [param:Box3 box] )

    +

    + [page:Box3 box] - [page:Box3] per verificare la presenza di intersezioni.

    + + Determina se questa sfera interseca il [page:Box3 box] dato oppure no. +

    + +

    [method:Boolean intersectsPlane]( [param:Plane plane] )

    +

    + [page:Plane plane] - Plane per verificare la presenza di intersezioni.

    + + Determina se questa sfera interseca il [page:Plane plane] dato oppure no. +

    + +

    [method:Boolean intersectsSphere]( [param:Sphere sphere] )

    +

    + [page:Sphere sphere] - Sphere per verificare la presenza di intersezioni.

    + + Verifica se le due sfere si intersecano. +

    + +

    [method:this set]( [param:Vector3 center], [param:Float radius] )

    +

    + [page:Vector3 center] - centro della sfera.
    + [page:Float radius] - raggio della sfera.

    + + Imposta le proprietà [page:.center centro] e [page:.radius raggio] di questa sfera.
    + Si noti che questo metodo copia solo i valori per il centro dato. +

    + +

    [method:this setFromPoints]( [param:Array points], [param:Vector3 optionalCenter] )

    +

    + [page:Array points] - un [page:Array] di posizioni [page:Vector3].
    + [page:Vector3 optionalCenter] - Posizione [page:Vector3] opzionale per il centro della sfera.

    + + Calcola la sfera di delimitazione minima per un array di [page:Array punti]. Se viene fornito l'[page:Vector3 optionalCenter], + viene utilizzato con il centro della sfera. Altrimenti, viene calcolato il centro del rettangolo di selezione allineato + agli assi che comprende i [page:Array punti]. +

    + +

    [method:this translate]( [param:Vector3 offset] )

    +

    + Trasla il centro della sfera dell'offset [page:Vector3] fornito. +

    + +

    [method:this union]( [param:Sphere sphere] )

    +

    + [page:Sphere sphere] - Sfera di delimitazione che sarà unita a questa sfera.

    + + Espande questa sfera per racchiudere sia la sfera originale che quella data. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Spherical.html b/docs/api/it/math/Spherical.html new file mode 100644 index 00000000000000..ce7eb0b78bfa84 --- /dev/null +++ b/docs/api/it/math/Spherical.html @@ -0,0 +1,79 @@ + + + + + + + + + +

    [name]

    + +

    Le [link:https://en.wikipedia.org/wiki/Spherical_coordinate_system coordinate sferiche] di un punto.

    + + +

    Costruttore

    + + +

    [name]( [param:Float radius], [param:Float phi], [param:Float theta] )

    +

    + [page:Float radius] - il raggio, o la [link:https://en.wikipedia.org/wiki/Euclidean_distance distanza Euclidea] + (distanza in linea retta) dal punto all'origine. Il valore predefinito è `1.0`.
    + [page:Float phi] - angolo polare in radianti dall'asse y (su). Il valore predefinito è `0`.
    + [page:Float theta] - angolo dell'equatore in radianti attorno l'asse y (su). Il valore predefinito è `0`.

    + + I poli (phi) sono sull'asse positivo e negativo. L'equatore (theta) inizia con z positivo. +

    + + +

    Proprietà

    + +

    [property:Float radius]

    + +

    [property:Float phi]

    + +

    [property:Float theta]

    + + +

    Metodi

    + +

    [method:Spherical clone]()

    +

    + Restituisce una nuova [name] con le stesse proprietà [page:.radius radius], [page:.phi phi] + e [page:.theta theta] di questo. +

    + +

    [method:this copy]( [param:Spherical s] )

    +

    + Copia i valori delle proprietà [page:.radius radius], [page:.phi phi] + e [page:.theta theta] della sferica a questa sferica. +

    + +

    [method:this makeSafe]()

    +

    + Limita l'angolo polare [page:.phi phi] per essere tra 0.000001 e pi - 0.000001. +

    + +

    [method:this set]( [param:Float radius], [param:Float phi], [param:Float theta] )

    +

    Imposta i valori delle proprietà [page:.radius radius], [page:.phi phi] + e [page:.theta theta] di questa sferica.

    + +

    [method:this setFromVector3]( [param:Vector3 vec3] )

    +

    + Imposta i valori delle proprietà [page:.radius radius], [page:.phi phi] + e [page:.theta theta] di questa sferica dal [page:Vector3 Vector3]. +

    + +

    [method:this setFromCartesianCoords]( [param:Float x], [param:Float y], [param:Float z] )

    +

    + Imposta i valori delle proprietà [page:.radius radius], [page:.phi phi] + e [page:.theta theta] di questa sferica dalle coordinate cartesiane. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/SphericalHarmonics3.html b/docs/api/it/math/SphericalHarmonics3.html new file mode 100644 index 00000000000000..9cd2cde1bf8631 --- /dev/null +++ b/docs/api/it/math/SphericalHarmonics3.html @@ -0,0 +1,145 @@ + + + + + + + + + +

    [name]

    + +

    + Rappresenta un'armonica sferica del terzo ordine (SH). Le sonde luminose utilizzano questa classe per codificare le + informazioni sull'illuminazione. +

    + +

    Costruttore

    +

    [name]()

    +

    + Crea una nuova istanza di [name]. +

    + +

    Proprietà

    + +

    [property:Array coefficients]

    +

    Un array contenente i (9) coefficienti SH. Un singolo coefficiente è rappresentato come un'istanza di [page:Vector3].

    + +

    [property:Boolean isSphericalHarmonics3]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    Metodi

    + +

    [method:this add]( [param:SphericalHarmonics3 sh] )

    +

    + [page:SphericalHarmonics3 sh] - L'SH da aggiungere.

    + + Aggiunge l'SH dato a questa istanza. +

    + +

    [method:this addScaledSH]( [param:SphericalHarmonics3 sh], [param:Number scale] )

    +

    + [page:SphericalHarmonics3 sh] - L'SH da aggiungere.
    + [page:Number scale] - Il fattore scale.

    + + Un metodo pratico per eseguire [page:.add]() e [page:.scale]() contemporaneamente. +

    + +

    [method:SphericalHarmonics3 clone]()

    +

    + Restituisce una nuova istanza di [name] con i coefficienti uguali. +

    + +

    [method:this copy]( [param:SphericalHarmonics3 sh] )

    +

    + [page:SphericalHarmonics3 sh] - L'SH da copiare.

    + + Copia l'SH dato per questa istanza. +

    + +

    [method:Boolean equals]( [param:SphericalHarmonics3 sh] )

    +

    + [page:SphericalHarmonics3 sh] - L'SH con cui fare la comparazione.

    + + Restituisce true se l'SH dato e questa istanza hanno coefficienti uguali. +

    + +

    [method:this fromArray]( [param:Array array], [param:Number offset] )

    +

    + [page:Array array] - L'array contiene i numeri dei coefficienti SH.
    + [page:Number offset] - (opzionale) L'offset dell'array.

    + + Imposta i coefficienti di questa istanza dall'array passato. +

    + +

    [method:Vector3 getAt]( [param:Vector3 normal], [param:Vector3 target] )

    +

    + [page:Vector3 normal] - Il vettore normale (si assume che abbia lunghezza unitaria).
    + [page:Vector3 target] - Il vettore risultato.

    + + Restituisce la radianza nella direzione della normale data. +

    + +

    [method:Vector3 getIrradianceAt]( [param:Vector3 normal], [param:Vector3 target] )

    +

    + [page:Vector3 normal] - Il vettore normale (si assume che abbia lunghezza unitaria).
    + [page:Vector3 target] - Il vettore risultato.

    + + Restituisce l'irradianza (radianza convoluta con il lobo del coseno) nella direzione della normale data. +

    + +

    [method:this lerp]( [param:SphericalHarmonics3 sh], [param:Number alpha] )

    +

    + [page:SphericalHarmonics3 sh] - L'SH con cui interpolare.
    + [page:Number alpha] - Il fattore alfa.

    + + Interpolazioni lineari tra l'SH dato e questa istanza dal fattore alfa dato. +

    + +

    [method:this scale]( [param:Number scale] )

    +

    + [page:Number scale] - Il fattore scale.

    + + Ridimensiona questo SH in base al fattore scale passato. +

    + +

    [method:this set]( [param:Array coefficients] )

    +

    + [page:Array coefficients] - Un array di coefficienti SH.

    + + Imposta i coefficienti SH passati in questa istanza. +

    + +

    [method:Array toArray]( [param:Array array], [param:Number offset] )

    +

    + [page:Array array] - (opzionale) L'array target.
    + [page:Number offset] - (opzionale) L'array offset.

    + + Restituisce un array con i coefficienti, o li copia nell'array fornito. I coefficienti + sono rappresentati come numeri. +

    + +

    [method:this zero]()

    +

    + Imposta tutti i coefficienti a 0. +

    + +

    Metodi Statici

    + +

    [method:undefined getBasisAt]( [param:Vector3 normal], [param:Array shBasis] )

    +

    + [page:Vector3 normal] - Il vettore normale (si presume che abbia lunghezza unitaria).
    + [page:Array shBasis] - La base SH risultante.

    + + Calcola la base SH per il vettore normale passato. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Triangle.html b/docs/api/it/math/Triangle.html new file mode 100644 index 00000000000000..a15cdd46041564 --- /dev/null +++ b/docs/api/it/math/Triangle.html @@ -0,0 +1,171 @@ + + + + + + + + + +

    [name]

    + +

    + Un triangolo geometrico definito da tre [page:Vector3 Vector3] che rappresentano i suoi tre angoli. +

    + + +

    Costruttore

    + + +

    [name]( [param:Vector3 a], [param:Vector3 b], [param:Vector3 c] )

    +

    + [page:Vector3 a] - il primo angolo del triangolo. Il valore predefinito è un [page:Vector3] a `(0, 0, 0)`.
    + [page:Vector3 b] - il secondo angolo del triangolo. Il valore predefinito è un [page:Vector3] a `(0, 0, 0)`.
    + [page:Vector3 c] - il terzo angolo del triangolo. Il valore predefinito è un [page:Vector3] a `(0, 0, 0)`.

    + + Crea un nuovo [name]. +

    + + +

    Proprietà

    + +

    [property:Vector3 a]

    +

    + Il primo angolo del triangolo. Il valore predefinito è un [page:Vector3] a `(0, 0, 0)`. +

    + +

    [property:Vector3 b]

    +

    + Il secondo angolo del triangolo. Il valore predefinito è un [page:Vector3] a `(0, 0, 0)`. +

    + +

    [property:Vector3 c]

    +

    + Il terzo angolo del triangolo. Il valore predefinito è un [page:Vector3] a `(0, 0, 0)`. +

    + +

    Metodi

    + +

    [method:Triangle clone]()

    +

    + Restituisce un nuovo triangolo con le stesse proprietà [page:.a a], [page:.b b] e [page:.c c] di questo. +

    + +

    [method:Vector3 closestPointToPoint]( [param:Vector3 point], [param:Vector3 target] )

    +

    + [page:Vector3 point] - [page:Vector3]
    + [page:Vector3 target] — il risultato sarà copiato in questo Vector3.

    + + Restituisce il punto più vicino del triangolo al [page:Vector3 punto]. +

    + +

    [method:Boolean containsPoint]( [param:Vector3 point] )

    +

    + [page:Vector3 point] - [page:Vector3] da controllare.

    + + Restituisce true se il punto passato, quando proiettato sul piano del triangolo, si trova all'interno del triangolo. +

    + +

    [method:this copy]( [param:Triangle triangle] )

    +

    + Copia i valori delle proprietà [page:.a a], [page:.b b] e [page:.c c] del triangolo passato in questo triangolo. +

    + +

    [method:Boolean equals]( [param:Triangle triangle] )

    +

    + Restituisce true se i due triangoli hanno le proprietà [page:.a a], [page:.b b] e [page:.c c] identiche. +

    + +

    [method:Float getArea]()

    +

    Restituisce l'area del triangolo.

    + +

    [method:Vector3 getBarycoord]( [param:Vector3 point], [param:Vector3 target] )

    +

    + [page:Vector3 point] - [page:Vector3]
    + [page:Vector3 target] — il risultato sarà copiato in questo Vector3.

    + + Restituisce una [link:https://en.wikipedia.org/wiki/Barycentric_coordinate_system coordinata baricentrica] + dal vettore dato.

    + + [link:http://commons.wikimedia.org/wiki/File:Barycentric_coordinates_1.png Figura delle coordinate baricentriche] +

    + +

    [method:Vector3 getMidpoint]( [param:Vector3 target] )

    +

    + [page:Vector3 target] — il risultato sarà copiato in questo Vector3.

    + + Calcola il punto medio del triangolo. +

    + +

    [method:Vector3 getNormal]( [param:Vector3 target] )

    +

    + [page:Vector3 target] — il risultato sarà copiato in questo Vector3.

    + + Calcola il [link:https://en.wikipedia.org/wiki/Normal_(geometry) vettore normale] del triangolo. +

    + +

    [method:Plane getPlane]( [param:Plane target] )

    +

    + [page:Plane target] — il risultato sarà copiato in questo Plane.

    + + Calcola il [page:Plane piano] in base al triangolo. +

    + +

    [method:Vector2 getUV]( [param:Vector3 point], [param:Vector2 uv1], [param:Vector2 uv2], [param:Vector2 uv3], [param:Vector2 target] )

    +

    + [page:Vector3 point] - Il punto sul triangolo.
    + [page:Vector2 uv1] - La coordinata uv del primo vertice del triangolo.
    + [page:Vector2 uv2] - La coordinata uv del secondo vertice del triangolo.
    + [page:Vector2 uv3] - La coordinata uv del terzo vertice del triangolo.
    + [page:Vector2 target] — il risultato sarà copiato in questo Vector2.

    + + Restituisce le coordinate uv per il punto specificato sul triangolo. +

    + +

    [method:Boolean intersectsBox]( [param:Box3 box] )

    +

    + [page:Box3 box] - Box per il controllo dell'intersezione.

    + + Determina se il triangolo interseca [page:Box3 box] oppure no. +

    + +

    [method:Boolean isFrontFacing]( [param:Vector3 direction] )

    +

    + [page:Vector3 direction] - La distanza da testare.

    + + Determina se il triangolo è orientato verso la direzione data o no. +

    + +

    [method:this set]( [param:Vector3 a], [param:Vector3 b], [param:Vector3 c] ) [param:Triangle this]

    +

    + Imposta le proprietà [page:.a a], [page:.b b] e [page:.c c] del triangolo ai [page:Vector3 vector3] passati.
    + Si noti che questo metodo copia solamente i valori da un dato oggetto. +

    + +

    [method:this setFromAttributeAndIndices]( [param:BufferAttribute attribute], [param:Integer i0], [param:Integer i1], [param:Integer i2] ) [param:Triangle this]

    +

    + attribute - [page:BufferAttribute] dei dati del vertice
    + i0 - [page:Integer] indice
    + i1 - [page:Integer] indice
    + i2 - [page:Integer] indice

    + + Imposta i vertici del triangolo dai dati dei vertici dell'attributo buffer. +

    + +

    [method:this setFromPointsAndIndices]( [param:Array points], [param:Integer i0], [param:Integer i1], [param:Integer i2] ) [param:Triangle this]

    +

    + points - [page:Array] di [page:Vector3]
    + i0 - [page:Integer] indice
    + i1 - [page:Integer] indice
    + i2 - [page:Integer] indice

    + + Imposta i vettori del triangolo ai vettori nell'array. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Vector2.html b/docs/api/it/math/Vector2.html new file mode 100644 index 00000000000000..6a1ee84606ed3b --- /dev/null +++ b/docs/api/it/math/Vector2.html @@ -0,0 +1,354 @@ + + + + + + + + + +

    [name]

    + +

    + Classe che rappresenta un [link:https://en.wikipedia.org/wiki/Vector_space vettore] 2D. + + Un vettore 2D è una coppia ordinata di numeri (etichettati con x e y), che può essere + utilizzata per rappresentare una serie di cose, come: +

    + +
      +
    • + Un punto nello spazio 2D (cioè una posizione su un piano). +
    • +
    • + Una direzione e lunghezza su un piano. In three.js la lunghezza sarà sempre la + [link:https://en.wikipedia.org/wiki/Euclidean_distance distanza Euclidea] + (distanza in liena retta) da `(0, 0)` a `(x, y)` e anche la direzione viene misurata da + `(0, 0)` verso `(x, y)`. +
    • +
    • + Qualsiasi coppia di numeri ordinata arbitrariamente. +
    • +
    + +

    + Ci sono altre cose che possono essere rappresentate da un vettore 2D, come i vettori + di quantità di moto, numeri complessi e così via, tuttavia questi sono gli usi comuni in three.js. +

    + +

    + L'iterazione di un'istanza [name] produrrà i suoi componenti `(x, y)` nell'ordine corrispondente. +

    + +

    Codice di Esempio

    + + + const a = new THREE.Vector2( 0, 1 ); + + // nessun argomento; sarà inizializzato a (0, 0) + const b = new THREE.Vector2( ); + + const d = a.distanceTo( b ); + + + +

    Costruttore

    + +

    [name]( [param:Float x], [param:Float y] )

    +

    + [page:Float x] - il valore x di questo vettore. Il valore predefinito è `0`.
    + [page:Float y] - il valore y di questo vettore. Il valore predefinito è `0`.

    + + Crea un nuovo [name]. +

    + + +

    Proprietà

    + +

    [property:Float height]

    +

    Alternativa per [page:.y y].

    + +

    [property:Boolean isVector2]

    +

    + Flag di sola lettura per verificare che l'oggetto dato sia di tipo [name]. +

    + +

    [property:Float width]

    +

    lternativa per [page:.x x].

    + +

    [property:Float x]

    + +

    [property:Float y]

    + + +

    Metodi

    + +

    [method:this add]( [param:Vector2 v] )

    +

    Aggiunge [page:Vector2 v] a questo vettore.

    + +

    [method:this addScalar]( [param:Float s] )

    +

    Aggiunge il valore scalare [page:Float s] ai valori [page:.x x] e [page:.y y] di questo vettore.

    + +

    [method:this addScaledVector]( [param:Vector2 v], [param:Float s] )

    +

    Aggiunge il multiplo di [page:Vector2 v] e [page:Float s] a questo vettore.

    + +

    [method:this addVectors]( [param:Vector2 a], [param:Vector2 b] )

    +

    Imposta questo vettore a [page:Vector2 a] + [page:Vector2 b].

    + +

    [method:Float angle]()

    +

    + Calcola l'angolo in radianti di questo vettore rispetto all'asse x positivo. +

    + +

    [method:this applyMatrix3]( [param:Matrix3 m] )

    +

    + Moltiplica questo vettore (con un 1 implicito come terza componente) per m. +

    + +

    [method:this ceil]()

    +

    + I componenti [page:.x x] e [page:.y y] di questo vettore vengono arrotondati per eccesso al valore intero più vicino. +

    + +

    [method:this clamp]( [param:Vector2 min], [param:Vector2 max] )

    +

    + [page:Vector2 min] - i valori minimi x e y.
    + [page:Vector2 max] - i valori massimi x e y nell'intervallo desiderato.

    + + Se il valore x o y di questo vettore è maggiore del valore x o y del vettore massimo, verrà sostituito dal valore corrispondente.

    + Se il valore x o y di questo vettore è minore del valore x o y del vettore minimo, verrà sostituito dal valore corrispondente.

    +

    + +

    [method:this clampLength]( [param:Float min], [param:Float max] )

    +

    + [page:Float min] - il valore minimo a cui verrà fissata la lunghezza.
    + [page:Float max] - il valore massimo a cui verrà fissata la lunghezza.

    + + Se la lunghezza di questo vettore è maggiore del valore massimo, verrà sostituita dal valore massimo.

    + Se la lunghezza di questo vettore è minore del valore minimo, verrà sostituita dal valore minimo. +

    + +

    [method:this clampScalar]( [param:Float min], [param:Float max] )

    +

    + [page:Float min] - il valore minimo a cui verranno fissati i componenti.
    + [page:Float max] - il valore massimo a cui verranno fissati i componenti.

    + + Se i valori di x o y di questo vettore sono maggiori del valore massimo, verranno sostuiti dal valore massimo.

    + Se i valori di x o y di questo vettore sono minori del valore minimo, verranno sostuiti dal valore minimo. +

    + +

    [method:Vector2 clone]()

    +

    + Restituisce un nuovo Vector2 con gli stessi valori [page:.x x] e [page:.y y] di questo. +

    + +

    [method:this copy]( [param:Vector2 v] )

    +

    + Copia i valori delle proprietà [page:.x x] e [page:.y y] del vettore passate di questo Vector2. +

    + +

    [method:Float distanceTo]( [param:Vector2 v] )

    +

    Calcola la distanza da questo vettore a [page:Vector2 v].

    + +

    [method:Float manhattanDistanceTo]( [param:Vector2 v] )

    +

    + Calcola la [link:https://en.wikipedia.org/wiki/Taxicab_geometry distanza Manhattan] da questo vettore a [page:Vector2 v]. +

    + +

    [method:Float distanceToSquared]( [param:Vector2 v] )

    +

    + Calcola la distanza al quadrato da questo vettore a [page:Vector2 v]. Se stai semplicemente + confrontando la distanza con un'altra distanza, dovresti invece confrontare la distanza al quadrato + poiché è leggermente più efficiente da calcolare. +

    + +

    [method:this divide]( [param:Vector2 v] )

    +

    Divide questo vettore per [page:Vector2 v].

    + +

    [method:this divideScalar]( [param:Float s] )

    +

    + Divide questo vettore per lo scalare [page:Float s]. +

    + +

    [method:Float dot]( [param:Vector2 v] )

    +

    + Calcola il [link:https://en.wikipedia.org/wiki/Dot_product prodotto scalare] di questo vettore e + [page:Vector2 v]. +

    + +

    [method:Float cross]( [param:Vector2 v] )

    +

    + Calcola il [link:https://en.wikipedia.org/wiki/Cross_product prodotto vettoriale] di questo vettore e + [page:Vector2 v]. Si noti che un 'prodotto vettoriale' in 2D non è ben definito. + Questa funzione calcola un prodotto vettoriale geometrico spesso utilizzato nella grafica 2D. +

    + +

    [method:Boolean equals]( [param:Vector2 v] )

    +

    Restituisce `true` se il componente di questo vettore e [page:Vector2 v] sono strettamente uguali; `false` altrimenti.

    + +

    [method:this floor]()

    +

    I componenti di questo vettore vengono arrotondati per difetto al valore intero più vicino.

    + +

    [method:this fromArray]( [param:Array array], [param:Integer offset] )

    +

    + [page:Array array] - l'array sorgente.
    + [page:Integer offset] - (opzionale) l'offset nell'array. Il valore predefinito è 0.

    + + Imposta il valore [page:.x x] di questo vettore su `array[ offset ]` e il valore [page:.y y] su `array[ offset + 1 ]`. +

    + +

    [method:this fromBufferAttribute]( [param:BufferAttribute attribute], [param:Integer index] )

    +

    + [page:BufferAttribute attribute] - l'array sorgente.
    + [page:Integer index] - indice nell'attributo.

    + + Imposta i valori [page:.x x] e [page:.y y] di questo vettore nell'[page:BufferAttribute attributo]. +

    + +

    [method:Float getComponent]( [param:Integer index] )

    +

    + [page:Integer index] - 0 o 1.

    + + Se l'indice è uguale 0 restituisce il valore [page:.x x].
    + Se l'indice è uguale 1 restituisce il valore [page:.y y]. +

    + +

    [method:Float length]()

    +

    + Calcola la [link:https://en.wikipedia.org/wiki/Euclidean_distance lunghezza Euclidea] + (lunghezza in linea retta) da (0, 0) a (x, y).

    + +

    [method:Float manhattanLength]()

    +

    + Calcola la [link:http://en.wikipedia.org/wiki/Taxicab_geometry lunghezza Manhattan] di questo vettore. +

    + +

    [method:Float lengthSq]()

    +

    + Calcola il quadrato della [link:https://en.wikipedia.org/wiki/Euclidean_distance lunghezza Euclidea] + (lunghezza in linea retta) da (0, 0) a (x, y). Se stai comparando le lunghezze dei vettori, dovresti invece + confrontare la lunghezza quadrata poiché è leggermente più efficiente da calcolare. +

    + +

    [method:this lerp]( [param:Vector2 v], [param:Float alpha] )

    +

    + [page:Vector2 v] - [page:Vector2] verso cui interpolare.
    + [page:Float alpha] - fattore interpolazione, tipicamente nell'intervallo chiuso `[0, 1]`.

    + + Interpola linearmente tra questo vettore e [page:Vector2 v], dove alfa è la distanza percentuale + lungo la linea - alfa = 0 sarà questo vettore e alfa = 1 sarà [page:Vector2 v]. +

    + +

    [method:this lerpVectors]( [param:Vector2 v1], [param:Vector2 v2], [param:Float alpha] )

    +

    + [page:Vector2 v1] - il [page:Vector2] iniziale.
    + [page:Vector2 v2] - [page:Vector2] verso cui interpolare.
    + [page:Float alpha] - fattore interpolazione, tipicamente nell'intervallo chiuso `[0, 1]`.

    + + Imposta questo vettore per essere il vettore lineare interpolato tra [page:Vector2 v1] e + [page:Vector2 v2] dove alfa è la distanza percentuale lungo la linea che collega i due vettori + - alfa = 0 sarà [page:Vector2 v1] e alfa = 1 sarà [page:Vector2 v]. +

    + +

    [method:this negate]()

    +

    Inverte questo vettore - cioè imposta x = -x e y = -y.

    + +

    [method:this normalize]()

    +

    + Converte questo vettore ad un [link:https://en.wikipedia.org/wiki/Unit_vector vettore unitario] - cioè, lo imposta uguale + ad un vettore con la stessa direzione di questo, ma con [page:.length lunghezza] 1. +

    + +

    [method:this max]( [param:Vector2 v] )

    +

    + Se il valore x o y di questo vettore è minore del valore x o y di [page:Vector2 v], sostituisce + questo valore con il valore massimo corrispondente. +

    + +

    [method:this min]( [param:Vector2 v] )

    +

    + Se il valore x o y di questo vettore è maggiore del valore x o y di [page:Vector2 v], sostituisce + questo valore con il valore minimo corrispondente. +

    + +

    [method:this multiply]( [param:Vector2 v] )

    +

    Moltiplica questo vettore per [page:Vector2 v].

    + + +

    [method:this multiplyScalar]( [param:Float s] )

    +

    Moltiplica questo vettore per lo scalare [page:Float s].

    + +

    [method:this rotateAround]( [param:Vector2 center], [param:Float angle] )

    +

    + [page:Vector2 center] - il punto attorno al quale ruotare.
    + [page:Float angle] - l'angolo di rotazione, in radianti.

    + + Ruota questo vettore attorno al [page:Vector2 centro] di un [page:Float angolo] in radianti. +

    + +

    [method:this round]()

    +

    I componenti di questo vettore vengono arrotondati al valore intero più vicino.

    + +

    [method:this roundToZero]()

    +

    + I componenti di questo vettore vengono arrotondati per difetto (per eccesso se negativo, per difetto se positivo) a un valore intero. +

    + +

    [method:this set]( [param:Float x], [param:Float y] )

    +

    Imposta i componenti [page:.x x] e [page:.y y] di questo.

    + +

    [method:this setComponent]( [param:Integer index], [param:Float value] )

    +

    + [page:Integer index] - 0 o 1.
    + [page:Float value] - [page:Float]

    + + Se l'indice è uguale a 0 imposta [page:.x x] a [page:Float value].
    + Se l'indice è uguale a 1 imposta [page:.y y] a [page:Float value].
    +

    + +

    [method:this setLength]( [param:Float l] )

    +

    + Imposta questo vettore ad un vettore con la stessa direzione di questo, ma con [page:.length lunghezza] + [page:Float l]. +

    + +

    [method:this setScalar]( [param:Float scalar] )

    +

    + Imposta i valori [page:.x x] e [page:.y y] di questo vettore entrambi uguali allo [page:Float scalare]. +

    + +

    [method:this setX]( [param:Float x] )

    +

    Sostuisce il valore di [page:.x x] di questo vettore con [page:Float x].

    + +

    [method:this setY]( [param:Float y] )

    +

    Sostuisce il valore di [page:.y y] di questo vettore con [page:Float y].

    + +

    [method:this sub]( [param:Vector2 v] )

    +

    Sottrae [page:Vector2 v] da questo vettore.

    + +

    [method:this subScalar]( [param:Float s] )

    +

    Sottrae [page:Float s] dai componenti [page:.x x] e [page:.y y] di questo vettore.

    + +

    [method:this subVectors]( [param:Vector2 a], [param:Vector2 b] )

    +

    Imposta questo vettore a [page:Vector2 a] - [page:Vector2 b].

    + +

    [method:Array toArray]( [param:Array array], [param:Integer offset] )

    +

    + [page:Array array] - (opzionale) array in cui memorizzare questo vettore. Se non viene fornito, verrà creato un nuovo array.
    + [page:Integer offset] - (opzionale) offset opzionale nell'array.

    + + Restituisce un array [x, y], o copia x e y nell'[page:Array array] fornito. +

    + +

    [method:this random]()

    +

    + Imposta ogni componente di questo vettore ad un valore pseudo-random tra 0 e 1, escludendo 1. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Vector3.html b/docs/api/it/math/Vector3.html new file mode 100644 index 00000000000000..60e6348843236a --- /dev/null +++ b/docs/api/it/math/Vector3.html @@ -0,0 +1,467 @@ + + + + + + + + + +

    [name]

    + +

    + Classe che rappresenta un [link:https://en.wikipedia.org/wiki/Vector_space vettore] 3D. + + Un vettore 3D è una tripletta ordinata di numeri (etichettati con x, y e z), che può essere + utilizzata per rappresentare una serie di cose, come: +

    + +
      +
    • + Un punto nello spazio 3D. +
    • +
    • + Una direzione e lunghezza nello spazio 3D. In three.js la lunghezza sarà sempre la + [link:https://en.wikipedia.org/wiki/Euclidean_distance distanza Euclidea] + (distanza in liena retta) da `(0, 0, 0)` a `(x, y, z)` e anche la direzione viene misurata da + `(0, 0, 0)` verso `(x, y, z)`. +
    • +
    • + Qualsiasi tripletta di numeri ordinata arbitrariamente. +
    • +
    + +

    + Ci sono altre cose che possono essere rappresentate da un vettore 3D, come i vettori + di quantità di moto e così via, tuttavia questi sono gli usi comuni in three.js. +

    + +

    + L'iterazione di un'istanza [name] produrrà i suoi componenti `(x, y, z)` nell'ordine corrispondente. +

    + +

    Codice di Esempio

    + + + const a = new THREE.Vector3( 0, 1, 0 ); + + // nessun argomento; sarà inizializzato a (0, 0, 0) + const b = new THREE.Vector3( ); + + const d = a.distanceTo( b ); + + + +

    Costruttore

    + +

    [name]( [param:Float x], [param:Float y], [param:Float z] )

    +

    + [page:Float x] - il valore x di questo vettore. Il valore predefinito è `0`.
    + [page:Float y] - il valore y di questo vettore. Il valore predefinito è `0`.
    + [page:Float z] - il valore z di questo vettore. Il valore predefinito è `0`.

    + + Crea un nuovo [name]. +

    + + +

    Proprietà

    + +

    [property:Boolean isVector3]

    +

    + Flag di sola lettura per verificare che l'oggetto dato sia di tipo [name]. +

    + +

    [property:Float x]

    + +

    [property:Float y]

    + +

    [property:Float z]

    + + +

    Metodi

    + +

    [method:this add]( [param:Vector3 v] )

    +

    Aggiunge [page:Vector3 v] a questo vettore.

    + +

    [method:this addScalar]( [param:Float s] )

    +

    Aggiunge il valore scalare [page:Float s] ai valori [page:.x x], [page:.y y] e [page:.z z] di questo vettore.

    + +

    [method:this addScaledVector]( [param:Vector3 v], [param:Float s] )

    +

    Aggiunge il multiplo di [page:Vector3 v] e [page:Float s] a questo vettore.

    + +

    [method:this addVectors]( [param:Vector3 a], [param:Vector3 b] )

    +

    Imposta questo vettore a [page:Vector3 a] + [page:Vector3 b].

    + +

    [method:this applyAxisAngle]( [param:Vector3 axis], [param:Float angle] )

    +

    + [page:Vector3 axis] - Un [page:Vector3] normalizzato.
    + [page:Float angle] - Un angolo in radianti.

    + + Applica una rotazione specifica da un asse e un angolo a questo vettore. +

    + +

    [method:this applyEuler]( [param:Euler euler] )

    +

    + Applica la trasformazione di Eulero a questo vettore convertendo l'oggetto [page:Euler Eulero] + a un [page:Quaternion Quaternione] e applicandolo. +

    + +

    [method:this applyMatrix3]( [param:Matrix3 m] )

    +

    Moltiplica questo vettore per [page:Matrix3 m]

    + +

    [method:this applyMatrix4]( [param:Matrix4 m] )

    +

    + Moltiplica questo vettore (con un 1 implicito come quarto componente) per m, e divide per prospettiva. +

    + +

    [method:this applyNormalMatrix]( [param:Matrix3 m] )

    +

    Moltiplica questo vettore per la matrice normale [page:Matrix3 m] e normalizza il risultato.

    + +

    [method:this applyQuaternion]( [param:Quaternion quaternion] )

    +

    + Applica una trasformata [page:Quaternion Quaternione] a questo vettore. +

    + + +

    [method:Float angleTo]( [param:Vector3 v] )

    +

    + Restituisce l'angolo tra questo vettore e il vettore [page:Vector3 v] in radianti. +

    + +

    [method:this ceil]()

    +

    + I componenti [page:.x x], [page:.y y] e [page:.z z] di questo vettore vengono arrotondati per eccesso al valore intero più vicino. +

    + +

    [method:this clamp]( [param:Vector3 min], [param:Vector3 max] )

    +

    + [page:Vector3 min] - i valori minimi [page:.x x], [page:.y y] e [page:.z z].
    + [page:Vector3 max] - i valori massimi [page:.x x], [page:.y y] e [page:.z z] nell'intervallo desiderato.

    + + Se il valore x, y o z di questo vettore è maggiore del valore di x, y o z del vettore massimo, verrà sostuito dal corrispondente valore.

    + Se il valore x, y o z di questo vettore è minore del valore di x, y o z del vettore minimo, verrà sostuito dal corrispondente valore. +

    + +

    [method:this clampLength]( [param:Float min], [param:Float max] )

    +

    + [page:Float min] - il valore minimo a cui verrà fissata la lunghezza.
    + [page:Float max] - il valore massimo a cui verrà fissata la lunghezza.

    + + Se la lunghezza di questo vettore è maggiore del valore massimo, il vettore verrà sostituito in modo che la sua lunghezza sia il valore massimo.

    + Se la lunghezza di questo vettore è minore del valore minimo, il vettore verrà sostituito in modo che la sua lunghezza sia il valore minimo. +

    + +

    [method:this clampScalar]( [param:Float min], [param:Float max] )

    +

    + [page:Float min] - il valore minimo a cui verranno fissati i componenti.
    + [page:Float max] - il valore massimo a cui verranno fissati i componenti.

    + + Se i valori di x, y o z di questo vettore sono maggiori del valore massimo, verranno sostuiti dal valore massimo.

    + Se i valori di x, y o z di questo vettore sono minori del valore minimo, verranno sostuiti dal valore minimo. +

    + +

    [method:Vector3 clone]()

    +

    + Restituisce un nuovo Vector3 con gli stessi valori [page:.x x], [page:.y y] e [page:.z z] di questo. +

    + +

    [method:this copy]( [param:Vector3 v] )

    +

    + Copia i valori delle proprietà [page:.x x], [page:.y y] e [page:.z z] del vettore passato in questo vettore. +

    + +

    [method:this cross]( [param:Vector3 v] )

    +

    + Imposta questo vettore come [link:https://en.wikipedia.org/wiki/Cross_product prodotto vettoriale] di se stesso e [page:Vector3 v]. +

    + +

    [method:this crossVectors]( [param:Vector3 a], [param:Vector3 b] )

    +

    + Imposta questo vettore come [link:https://en.wikipedia.org/wiki/Cross_product prodotto vettoriale] di [page:Vector3 a] e [page:Vector3 b]. +

    + +

    [method:Float distanceTo]( [param:Vector3 v] )

    +

    Calcola la distanza da questo vettore e [page:Vector3 v].

    + +

    [method:Float manhattanDistanceTo]( [param:Vector3 v] )

    +

    + Calcola la [link:https://en.wikipedia.org/wiki/Taxicab_geometry distanza Manhattan] tra questo vettore e [page:Vector3 v]. +

    + +

    [method:Float distanceToSquared]( [param:Vector3 v] )

    +

    + Calcola la distanza al quadrato da questo vettore a [page:Vector3 v]. Se stai semplicemente + confrontando la distanza con un'altra distanza, dovresti invece confrontare la distanza al quadrato + poiché è leggermente più efficiente da calcolare. +

    + +

    [method:this divide]( [param:Vector3 v] )

    +

    Divide questo vettore per [page:Vector3 v].

    + +

    [method:this divideScalar]( [param:Float s] )

    +

    + Divide questo vettore per lo scalare [page:Float s]. +

    + +

    [method:Float dot]( [param:Vector3 v] )

    +

    + Calcola il [link:https://en.wikipedia.org/wiki/Dot_product prodotto scalare] di questo vettore e + [page:Vector3 v]. +

    + +

    [method:Boolean equals]( [param:Vector3 v] )

    +

    Restituisce `true` se i componenti di questo vettore e [page:Vector3 v] sono strettamente uguali; `false` altrimenti.

    + +

    [method:this floor]()

    +

    I componenti di questo vettore vengono arrotondati per difetto al valore intero più vicino.

    + +

    [method:this fromArray]( [param:Array array], [param:Integer offset] )

    +

    + [page:Array array] - l'array sorgente.
    + [page:Integer offset] - (opzionale) l'offset nell'array. Il valore predefinito è 0.

    + + Imposta il valore [page:.x x] di questo vettore su `array[ offset + 0 ]`, il valore [page:.y y] su `array[ offset + 1 ]` + e il valore [page:.z z] su `array[ offset + 2 ]`. +

    + +

    [method:this fromBufferAttribute]( [param:BufferAttribute attribute], [param:Integer index] )

    +

    + [page:BufferAttribute attribute] - l'attributo sorgente.
    + [page:Integer index] - l'indice nell'attributo.

    + + Imposta i valori [page:.x x], [page:.y y] e [page:.z z] di questo vettore nell'[page:BufferAttribute attributo]. +

    + +

    [method:Float getComponent]( [param:Integer index] )

    +

    + [page:Integer index] - 0, 1 o 2.

    + + Se l'indice è uguale a 0 restituisce il valore [page:.x x].
    + Se l'indice è uguale a 1 restituisce il valore [page:.y y].
    + Se l'indice è uguale a 2 restituisce il valore [page:.z z]. +

    + +

    [method:Float length]()

    +

    Calcola la [link:https://en.wikipedia.org/wiki/Euclidean_distance lunghezza Euclidea] + (lunghezza in linea retta) da (0, 0, 0) a (x, y, z).

    + +

    [method:Float manhattanLength]()

    +

    + Calcola la [link:http://en.wikipedia.org/wiki/Taxicab_geometry lunghezza Manhattan] di questo vettore. +

    + +

    [method:Float lengthSq]()

    +

    + Calcola il quadrato della [link:https://en.wikipedia.org/wiki/Euclidean_distance lunghezza Euclidea] + (lunghezza in linea retta) da (0, 0, 0) a (x, y, z). Se stai comparando le lunghezze dei vettori, dovresti invece + confrontare la lunghezza quadrata poiché è leggermente più efficiente da calcolare. +

    + +

    [method:this lerp]( [param:Vector3 v], [param:Float alpha] )

    +

    + [page:Vector3 v] - [page:Vector3] verso in cui interpolare.
    + [page:Float alpha] - fattore di interpolazione, tipicamente nell'intervallo chiuso `[0, 1]`.

    + + Interpola linearmente tra questo vettore e [page:Vector3 v], dove alfa è la distanza percentuale + lungo la linea - alfa = 0 sarà questo vettore e alfa = 1 sarà [page:Vector3 v]. +

    + +

    [method:this lerpVectors]( [param:Vector3 v1], [param:Vector3 v2], [param:Float alpha] )

    +

    + [page:Vector3 v1] - il [page:Vector3] iniziale.
    + [page:Vector3 v2] - [page:Vector3] verso cui interpolare.
    + [page:Float alpha] - fattore di interpolazione, tipicamente nell'intervallo chiuso `[0, 1]`.

    + + Imposta questo vettore per essere il vettore lineare interpolato tra [page:Vector3 v1] e + [page:Vector3 v2] dove alfa è la distanza percentuale lungo la linea che collega i due vettori + - alfa = 0 sarà [page:Vector3 v1] e alfa = 1 sarà [page:Vector3 v2]. +

    + +

    [method:this max]( [param:Vector3 v] )

    +

    + Se il valore x, y o z di questo vettore è minore del valore x, y o z di [page:Vector3 v], sostituisce + questo valore con il valore massimo corrispondente. +

    + +

    [method:this min]( [param:Vector3 v] )

    +

    + Se il valore x, y o z di questo vettore è maggiore del valore x, y o z di [page:Vector3 v], sostituisce + questo valore con il valore minimo corrispondente. +

    + +

    [method:this multiply]( [param:Vector3 v] )

    +

    Moltiplica questo vettore per [page:Vector3 v].

    + +

    [method:this multiplyScalar]( [param:Float s] )

    +

    Moltiplica questo vettore per lo scalare [page:Float s].

    + +

    [method:this multiplyVectors]( [param:Vector3 a], [param:Vector3 b] )

    +

    Imposta questo vettore uguale a [page:Vector3 a] * [page:Vector3 b], dal punto di vista dei componenti.

    + +

    [method:this negate]()

    +

    Inverte questo vettore - cioè imposta x = -x, y = -y e z = -z.

    + +

    [method:this normalize]()

    +

    + Converte questo vettore in un [link:https://en.wikipedia.org/wiki/Unit_vector vettore unitario] - cioè, lo imposta uguale ad un vettore + con la stessa direzione di questo, ma con [page:.length lunghezza] 1. +

    + +

    [method:this project]( [param:Camera camera] )

    +

    + [page:Camera camera] — telecamera da utilizzare nella proiezione.

    + + Proietta questo vettore dallo spazio world nello spazio delle coordinate normalizzate del dispositivo (NDC) della telecamera. +

    + +

    [method:this projectOnPlane]( [param:Vector3 planeNormal] )

    +

    + [page:Vector3 planeNormal] - Un vettore che rappresenta un piano normale.

    + + [link:https://en.wikipedia.org/wiki/Vector_projection Proietta] questo vettore su un piano sottraendo + questo vettore proiettato sulla normale del piano da questo vettore. +

    + +

    [method:this projectOnVector]( [param:Vector3 v] )

    +

    [link:https://en.wikipedia.org/wiki/Vector_projection Proietta] questo vettore in [page:Vector3 v].

    + +

    [method:this reflect]( [param:Vector3 normal] )

    +

    + [page:Vector3 normal] - la normale al piano riflettente.

    + + Riflette questo vettore fuori dal piano ortogonale alla [page:Vector3 normale]. Si suppone che la normale + abbia lunghezza unitaria. +

    + +

    [method:this round]()

    +

    I componenti di questo vettore vengono arrotondati al valore intero più vicino.

    + +

    [method:this roundToZero]()

    +

    + I componenti di questo vettore vengono arrotondati verso zero (per eccesso se negativo, per difetto se positivo) a un valore intero. +

    + +

    [method:this set]( [param:Float x], [param:Float y], [param:Float z] )

    +

    Imposta i componenti [page:.x x], [page:.y y] e [page:.z z] di questo vettore.

    + +

    [method:this setComponent]( [param:Integer index], [param:Float value] )

    +

    + [page:Integer index] - 0, 1 o 2.
    + [page:Float value] - [page:Float]

    + + Se l'indice è uguale a 0 imposta [page:.x x] a [page:Float value].
    + Se l'indice è uguale a 1 imposta [page:.y y] a [page:Float value].
    + Se l'indice è uguale a 2 imposta [page:.z z] a [page:Float value]. +

    + +

    [method:this setFromCylindrical]( [param:Cylindrical c] )

    +

    + Imposta questo vettore dalle coordinate cilindriche [page:Cylindrical c]. +

    + +

    [method:this setFromCylindricalCoords]( [param:Float radius], [param:Float theta], [param:Float y] )

    +

    Imposta questo vettore dalle coordinate cilindriche [page:Cylindrical radius], [page:Cylindrical theta] and [page:Cylindrical y].

    + +

    [method:this setFromEuler]( [param:Euler euler] )

    +

    + Imposta i componenti [page:.x x], [page:.y y] e [page:.z z] di questo vettore dai componenti x, y, e z + dell'[page:Euler angolo di Eulero] specificato. +

    + +

    [method:this setFromMatrixColumn]( [param:Matrix4 matrix], [param:Integer index] )

    +

    + Imposta i componenti [page:.x x], [page:.y y] e [page:.z z] di questo vettore dalla colonna [page:Integer indice] della [page:Matrix4 matrice]. +

    + +

    [method:this setFromMatrix3Column]( [param:Matrix3 matrix], [param:Integer index] )

    +

    + Imposta i componenti [page:.x x], [page:.y y] e [page:.z z] di questo vettore dalla colonna [page:Integer indice] della [page:Matrix4 matrice]. +

    + +

    [method:this setFromMatrixPosition]( [param:Matrix4 m] )

    +

    + Imposta questo vettore sugli elementi di posizione della + [link:https://en.wikipedia.org/wiki/Transformation_matrix matrice di trasformazione] [page:Matrix4 m]. +

    + +

    [method:this setFromMatrixScale]( [param:Matrix4 m] )

    +

    + Imposta questo vettore sugli elementi scale della + [link:https://en.wikipedia.org/wiki/Transformation_matrix matrice di trasformazione] [page:Matrix4 m]. +

    + +

    [method:this setFromSpherical]( [param:Spherical s] )

    +

    + Imposta questo vettore dalle coordinate sferiche [page:Spherical s]. +

    + +

    [method:this setFromSphericalCoords]( [param:Float radius], [param:Float phi], [param:Float theta] )

    +

    Imposta questo vettore dalle coordinate sferiche [page:Spherical radius], [page:Spherical phi] e [page:Spherical theta].

    + +

    [method:this setLength]( [param:Float l] )

    +

    + Imposta questo vettore ad un vettore con la stessa direzione di questo, ma con la [page:.length lunghezza] + [page:Float l]. +

    + +

    [method:this setScalar]( [param:Float scalar] )

    +

    + Imposta i valori [page:.x x], [page:.y y] e [page:.z z] di questo vettore tutti ugualmente allo [page:Float scalare]. +

    + +

    [method:this setX]( [param:Float x] )

    +

    Sostuisce il valore [page:.x x] di questo vettore con [page:Float x].

    + +

    [method:this setY]( [param:Float y] )

    +

    Sostuisce il valore [page:.y y] di questo vettore con [page:Float y].

    + +

    [method:this setZ]( [param:Float z] )

    +

    Sostuisce il valore [page:.z z] di questo vettore con [page:Float z].

    + +

    [method:this sub]( [param:Vector3 v] )

    +

    Sottrae [page:Vector3 v] da questo vettore.

    + +

    [method:this subScalar]( [param:Float s] )

    +

    Sottrae [page:Float s] dai componenti [page:.x x], [page:.y y] e [page:.z z] di questo vettore.

    + +

    [method:this subVectors]( [param:Vector3 a], [param:Vector3 b] )

    +

    Imposta questo vettore a [page:Vector3 a] - [page:Vector3 b].

    + +

    [method:Array toArray]( [param:Array array], [param:Integer offset] )

    +

    + [page:Array array] - (opzionale) array per memorizzare questo vettore. Se non viene fornito, verrà creato un nuovo array.
    + [page:Integer offset] - (opzionale) offset opzionale nell'array.

    + + Restituisce un array [x, y, z], o copia x, y e z nell'[page:Array array] fornito. +

    + +

    [method:this transformDirection]( [param:Matrix4 m] )

    +

    + Trasforma la direzione di questo vettore da una matrice (3 x 3 in alto a sinistra sottoinsieme di [page:Matrix4 m]) + e [page:.normalize normalizza] il risultato. +

    + +

    [method:this unproject]( [param:Camera camera] )

    +

    + [page:Camera camera] — telecamera da usare nella proiezione.

    + + Proietta questo vettore dallo spazio delle coordinate normalizzate del dispositivo (NDC) della telecamera nello spazio world. +

    + +

    [method:this random]()

    +

    + Imposta ogni componente di questo vettore ad un valore pseudo random tra 0 e 1, escludendo 1. +

    + +

    [method:this randomDirection]()

    +

    + Imposta questo vettore su un punto uniformemente casuale su una sfera unitaria. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/Vector4.html b/docs/api/it/math/Vector4.html new file mode 100644 index 00000000000000..16542c439c0a39 --- /dev/null +++ b/docs/api/it/math/Vector4.html @@ -0,0 +1,348 @@ + + + + + + + + + +

    [name]

    + +

    + Classe che rappresenta un [link:https://en.wikipedia.org/wiki/Vector_space vettore] 4D. + + Un vettore 4D è una quadrupla ordinata di numeri (etichettati con x, y, z e w), che può essere + utilizzata per rappresentare una serie di cose, come: +

    + +
      +
    • + Un punto nello spazio 4D. +
    • +
    • + Una direzione e lunghezza nello spazio 4D. In three.js la lunghezza sarà sempre la + [link:https://en.wikipedia.org/wiki/Euclidean_distance distanza Euclidea] + (distanza in liena retta) da `(0, 0, 0, 0)` a `(x, y, z, w)` e anche la direzione viene misurata da + `(0, 0, 0, 0)` verso `(x, y, z, w)`. +
    • +
    • + Qualsiasi quadrupla di numeri ordinata arbitrariamente. +
    • +
    + +

    + Ci sono altre cose che possono essere rappresentate da un vettore 4D, tuttavia questi sono gli usi più comuni in *three.js*. +

    + +

    + L'iterazione di un'istanza [name] produrrà i suoi componenti `(x, y, z, w)` nell'ordine corrispondente. +

    + +

    Codice di Esempio

    + + + const a = new THREE.Vector4( 0, 1, 0, 0 ); + + // nessun argomento; sarà inizializzato a (0, 0, 0, 1) + const b = new THREE.Vector4( ); + + const d = a.dot( b ); + + + +

    Costruttore

    + +

    [name]( [param:Float x], [param:Float y], [param:Float z], [param:Float w] )

    +

    + [page:Float x] - il valore x di questo vettore. Il valore predefinito è `0`.
    + [page:Float y] - il valore y di questo vettore. Il valore predefinito è `0`.
    + [page:Float z] - il valore z di questo vettore. Il valore predefinito è `0`.
    + [page:Float w] - il valore w di questo vettore. Il valore predefinito è `1`.

    + + Crea un nuovo [name]. +

    + + +

    Proprietà

    + +

    [property:Boolean isVector4]

    +

    + Flag di sola lettura per verificare che l'oggetto dato sia di tipo [name]. +

    + +

    [property:Float x]

    + +

    [property:Float y]

    + +

    [property:Float z]

    + +

    [property:Float w]

    + +

    [property:Float width]

    +

    Alias per [page:.z z].

    + +

    [property:Float height]

    +

    Alias per [page:.w w].

    + + +

    Metodi

    + +

    [method:this add]( [param:Vector4 v] )

    +

    Aggiunge [page:Vector4 v] a questo vettore.

    + +

    [method:this addScalar]( [param:Float s] )

    +

    Aggiunge il valore scalare [page:Float s] ai valori [page:.x x], [page:.y y], [page:.z z] e [page:.w w] di questo vettore.

    + +

    [method:this addScaledVector]( [param:Vector4 v], [param:Float s] )

    +

    Aggiunge il multiplo di [page:Vector4 v] e [page:Float s] a questo vettore.

    + +

    [method:this addVectors]( [param:Vector4 a], [param:Vector4 b] )

    +

    Imposta questo vettore a [page:Vector4 a] + [page:Vector4 b].

    + +

    [method:this applyMatrix4]( [param:Matrix4 m] )

    +

    + Moltiplica questo vettore per 4 x 4 [page:Matrix4 m]. +

    + +

    [method:this ceil]()

    +

    + I componenti [page:.x x], [page:.y y], [page:.z z] e [page:.w w] di questo vettore vengono arrotondati per eccesso al valore intero più vicino. +

    + +

    [method:this clamp]( [param:Vector4 min], [param:Vector4 max] )

    +

    + [page:Vector4 min] - i valori minimi [page:.x x], [page:.y y], [page:.z z] e [page:.w w].
    + [page:Vector4 max] - i valori massimi [page:.x x], [page:.y y], [page:.z z] e [page:.w w] nell'intervallo desiderato

    + + Se il valore x, y, z o w di questo vettore è maggiore del valore di x, y, z o w del vettore massimo, verrà sostuito dal corrispondente valore.

    + Se il valore x, y, z o w di questo vettore è minore del valore di x, y, z o w del vettore minimo, verrà sostuito dal corrispondente valore. +

    + +

    [method:this clampLength]( [param:Float min], [param:Float max] )

    +

    + [page:Float min] - il valore minimo a cui verrà fissata la lunghezza.
    + [page:Float max] - il valore massimo a cui verrà fissata la lunghezza.

    + + Se la lunghezza di questo vettore è maggiore del valore massimo, il vettore verrà sostituito dal valore massimo.

    + Se la lunghezza di questo vettore è minore del valore minimo, il vettore verrà sostituito dal valore minimo. +

    + +

    [method:this clampScalar]( [param:Float min], [param:Float max] )

    +

    + [page:Float min] - il valore minimo a cui verranno fissati i componenti.
    + [page:Float max] - il valore massimo a cui verranno fissati i componenti.

    + + Se i valori di x, y, z o w di questo vettore sono maggiori del valore massimo, verranno sostuiti dal valore massimo.

    + Se i valori di x, y, z o w di questo vettore sono minori del valore minimo, verranno sostuiti dal valore minimo. +

    + +

    [method:Vector4 clone]()

    +

    + Restituisce un nuovo Vector4 con gli stessi valori [page:.x x], [page:.y y], [page:.z z] e [page:.w w] di questo. +

    + +

    [method:this copy]( [param:Vector4 v] )

    +

    + Copia i valori delle proprietà [page:.x x], [page:.y y], [page:.z z] e [page:.w w] del vettore passato in questo vettore Vector4. +

    + +

    [method:this divideScalar]( [param:Float s] )

    +

    + Divide questo vettore per lo scalare [page:Float s]. +

    + +

    [method:Float dot]( [param:Vector4 v] )

    +

    + Calcola il [link:https://en.wikipedia.org/wiki/Dot_product prodotto scalare] di questo vettore e + [page:Vector4 v]. +

    + +

    [method:Boolean equals]( [param:Vector4 v] )

    +

    Restituisce `true` se i componenti di questo vettore e [page:Vector4 v] sono strettamente uguali; `false` altrimenti.

    + +

    [method:this floor]()

    +

    I componenti di questo vettore vengono arrotondati per difetto al valore intero più vicino.

    + +

    [method:this fromArray]( [param:Array array], [param:Integer offset] )

    +

    + [page:Array array] - l'array sorgente.
    + [page:Integer offset] - (opzionale) l'offset nell'array. Il valore predefinito è 0.

    + + Imposta il valore [page:.x x] di questo vettore su `array[ offset + 0 ]`, il valore [page:.y y] su `array[ offset + 1 ]`, + il valore [page:.z z] su `array[ offset + 2 ]` e il valore [page:.w w] su `array[ offset + 3 ]`. +

    + +

    [method:this fromBufferAttribute]( [param:BufferAttribute attribute], [param:Integer index] )

    +

    + [page:BufferAttribute attribute] - l'attributo sorgente.
    + [page:Integer index] - l'indice nell'attributo.

    + + Imposta i valori [page:.x x], [page:.y y], [page:.z z] e [page:.w w] di questo vettore nell'[page:BufferAttribute attributo]. +

    + +

    [method:Float getComponent]( [param:Integer index] )

    +

    + [page:Integer index] - 0, 1, 2 o 3.

    + + Se l'indice è uguale a 0 restituisce il valore [page:.x x].
    + Se l'indice è uguale a 1 restituisce il valore [page:.y y].
    + Se l'indice è uguale a 2 restituisce il valore [page:.z z].
    + Se l'indice è uguale a 3 restituisce il valore [page:.w w].
    +

    + +

    [method:Float length]()

    +

    + Calcola la [link:https://en.wikipedia.org/wiki/Euclidean_distance lunghezza Euclidea] + (lunghezza in linea retta) da `(0, 0, 0, 0)` a `(x, y, z, w)`. +

    + +

    [method:Float manhattanLength]()

    +

    + Calcola la [link:http://en.wikipedia.org/wiki/Taxicab_geometry lunghezza Manhattan] di questo vettore. +

    + +

    [method:Float lengthSq]()

    +

    + Calcola il quadrato della [link:https://en.wikipedia.org/wiki/Euclidean_distance lunghezza Euclidea] + (lunghezza in linea retta) da `(0, 0, 0, 0)` a `(x, y, z, w)`. Se stai comparando le lunghezze dei vettori, dovresti invece + confrontare la lunghezza quadrata poiché è leggermente più efficiente da calcolare. +

    + +

    [method:this lerp]( [param:Vector4 v], [param:Float alpha] )

    +

    + [page:Vector4 v] - [page:Vector4] verso in cui interpolare.
    + [page:Float alpha] - fattore di interpolazione, tipicamente nell'intervallo chiuso `[0, 1]`.

    + + Interpola linearmente tra questo vettore e [page:Vector4 v], dove alfa è la distanza percentuale + lungo la linea - `alpha = 0` sarà questo vettore e `alpha = 1` sarà [page:Vector4 v]. +

    + +

    [method:this lerpVectors]( [param:Vector4 v1], [param:Vector4 v2], [param:Float alpha] )

    +

    + [page:Vector4 v1] - il [page:Vector4] iniziale.
    + [page:Vector4 v2] - [page:Vector4] verso cui interpolare.
    + [page:Float alpha] - fattore di interpolazione, tipicamente nell'intervallo chiuso `[0, 1]`.

    + + Imposta questo vettore per essere il vettore lineare interpolato tra [page:Vector4 v1] e + [page:Vector4 v2] dove alfa è la distanza percentuale lungo la linea che collega i due vettori + - alfa = 0 sarà [page:Vector4 v1] e alfa = 1 sarà [page:Vector4 v2]. +

    + +

    [method:this negate]()

    +

    Inverte questo vettore - cioè imposta x = -x, y = -y, z = -z e w = -w.

    + +

    [method:this normalize]()

    +

    + Converte questo vettore in un [link:https://en.wikipedia.org/wiki/Unit_vector vettore unitario] - cioè, lo imposta uguale ad un vettore + con la stessa direzione di questo, ma con [page:.length lunghezza] 1. +

    + +

    [method:this max]( [param:Vector4 v] )

    +

    + Se il valore x, y, z o w di questo vettore è minore del valore x, y, z o w di [page:Vector4 v], sostituisce + questo valore con il valore massimo corrispondente. +

    + +

    [method:this min]( [param:Vector4 v] )

    +

    + Se il valore x, y, z o w di questo vettore è maggiore del valore x, y, z o w di [page:Vector4 v], sostituisce + questo valore con il valore minimo corrispondente. +

    + +

    [method:this multiply]( [param:Vector4 v] )

    +

    Moltiplica questo vettore per [page:Vector4 v].

    + +

    [method:this multiplyScalar]( [param:Float s] )

    +

    Moltiplica questo vettore per lo scalare [page:Float s].

    + +

    [method:this round]()

    +

    I componenti di questo vettore sono arrotondati al valore intero più vicino.

    + +

    [method:this roundToZero]()

    +

    + I componenti di questo vettore sono arrotondati verso zero (per eccesso se negativo, per difetto se positivo) a un valore intero. +

    + +

    [method:this set]( [param:Float x], [param:Float y], [param:Float z], [param:Float w] )

    +

    Imposta i componenti [page:.x x], [page:.y y], [page:.z z] e [page:.w w] di questo vettore.

    + +

    [method:this setAxisAngleFromQuaternion]( [param:Quaternion q] )

    +

    + [page:Quaternion q] - un [page:Quaternione] normalizzato.

    + + Imposta i componenti [page:.x x], [page:.y y] e [page:.z z] di questo vettore sull'asse + del quaternione e [page:.w w] all'angolo. +

    + +

    [method:this setAxisAngleFromRotationMatrix]( [param:Matrix4 m] )

    +

    + [page:Matrix4 m] - una [page:Matrix4] di cui la matrice 3x3 in alto a sinistra è una matrice di rotazione pura.

    + + Imposta [page:.x x], [page:.y y] e [page:.z z] all'asse di rotazione e [page:.w w] all'angolo. +

    + +

    [method:this setComponent]( [param:Integer index], [param:Float value] )

    +

    + [page:Integer index] - 0, 1 o 2.
    + [page:Float value] - [page:Float]

    + + Se l'indice è uguale a 0 imposta [page:.x x] a [page:Float value].
    + Se l'indice è uguale a 1 imposta [page:.y y] a [page:Float value].
    + Se l'indice è uguale a 2 imposta [page:.z z] a [page:Float value].
    + Se l'indice è uguale a 3 imposta [page:.w w] a [page:Float value].
    +

    + + +

    [method:this setLength]( [param:Float l] )

    +

    + Imposta questo vettore ad un vettore con la stessa direzione di questo, ma con la [page:.length lunghezza] + [page:Float l]. +

    + +

    [method:this setScalar]( [param:Float scalar] )

    +

    + Imposta i valori [page:.x x], [page:.y y], [page:.z z] e [page:.w w] di questo vettore tutti ugualmente allo [page:Float scalare]. +

    + +

    [method:this setX]( [param:Float x] )

    +

    Sostuisce il valore [page:.x x] di questo vettore con [page:Float x].

    + +

    [method:this setY]( [param:Float y] )

    +

    Sostuisce il valore [page:.y y] di questo vettore con [page:Float y].

    + +

    [method:this setZ]( [param:Float z] )

    +

    Sostuisce il valore [page:.z z] di questo vettore con [page:Float z].

    + +

    [method:this setW]( [param:Float w] )

    +

    Sostuisce il valore [page:.w w] di questo vettore con [page:Float w].

    + +

    [method:this sub]( [param:Vector4 v] )

    +

    Sottrae [page:Vector4 v] da questo vettore.

    + +

    [method:this subScalar]( [param:Float s] )

    +

    Sottrae [page:Float s] dai componenti [page:.x x], [page:.y y], [page:.z z] e [page:.w w] di questo vettore.

    + +

    [method:this subVectors]( [param:Vector4 a], [param:Vector4 b] )

    +

    Imposta questo vettore a [page:Vector4 a] - [page:Vector4 b].

    + +

    [method:Array toArray]( [param:Array array], [param:Integer offset] )

    +

    + [page:Array array] - (opzionale) array per memorizzare questo vettore. Se non viene fornito, verrà creato un nuovo array.
    + [page:Integer offset] - (opzionale) offset opzionale nell'array.

    + + Restituisce un array [x, y, z, w], o copia x, y, z e w nell'[page:Array array] fornito. +

    + +

    [method:this random]()

    +

    + Imposta ogni componente di questo vettore ad un valore pseudo random tra 0 e 1, escludendo 1. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/interpolants/CubicInterpolant.html b/docs/api/it/math/interpolants/CubicInterpolant.html new file mode 100644 index 00000000000000..1c2cc061d3a982 --- /dev/null +++ b/docs/api/it/math/interpolants/CubicInterpolant.html @@ -0,0 +1,82 @@ + + + + + + + + + + [page:Interpolant] → + +

    [name]

    + +

    + +

    + +

    Codice di Esempio

    + + +const interpolant = new THREE.[name]( + new Float32Array( 2 ), + new Float32Array( 2 ), + 1, + new Float32Array( 1 ) +); + +interpolant.evaluate( 0.5 ); + + + +

    Costruttore

    + +

    [name]( parameterPositions, sampleValues, sampleSize, resultBuffer )

    +

    + parameterPositions -- array di posizioni
    + sampleValues -- array di campioni
    + sampleSize -- numero di campioni
    + resultBuffer -- buffer per memorizzare i risultati dell'interpolazione.

    +

    + +

    Proprietà

    + +

    [property:null parameterPositions]

    +

    + +

    + +

    [property:null resultBuffer]

    +

    + +

    + +

    [property:null sampleValues]

    +

    + +

    + +

    [property:Object settings]

    +

    + +

    + +

    [property:null valueSize]

    +

    + +

    + +

    Metodi

    + +

    [method:Array evaluate]( [param:Number t] )

    +

    + Valuta l'interpolante alla posizione *t*. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/interpolants/DiscreteInterpolant.html b/docs/api/it/math/interpolants/DiscreteInterpolant.html new file mode 100644 index 00000000000000..a1f4cdad1683a6 --- /dev/null +++ b/docs/api/it/math/interpolants/DiscreteInterpolant.html @@ -0,0 +1,82 @@ + + + + + + + + + + [page:Interpolant] → + +

    [name]

    + +

    + +

    + +

    Codice di Esempio

    + + +const interpolant = new THREE.[name]( + new Float32Array( 2 ), + new Float32Array( 2 ), + 1, + new Float32Array( 1 ) +); + +interpolant.evaluate( 0.5 ); + + + +

    Costruttore

    + +

    [name]( parameterPositions, sampleValues, sampleSize, resultBuffer )

    +

    + parameterPositions -- array di posizioni
    + sampleValues -- array di campioni
    + sampleSize -- numero di campioni
    + resultBuffer -- buffer per memorizzare il risultato dell'interpolazione.

    +

    + +

    Proprietà

    + +

    [property:null parameterPositions]

    +

    + +

    + +

    [property:null resultBuffer]

    +

    + +

    + +

    [property:null sampleValues]

    +

    + +

    + +

    [property:Object settings]

    +

    + +

    + +

    [property:null valueSize]

    +

    + +

    + +

    Metodi

    + +

    [method:Array evaluate]( [param:Number t] )

    +

    + Valuta l'interpolante alla posizione *t*. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/interpolants/LinearInterpolant.html b/docs/api/it/math/interpolants/LinearInterpolant.html new file mode 100644 index 00000000000000..a1f4cdad1683a6 --- /dev/null +++ b/docs/api/it/math/interpolants/LinearInterpolant.html @@ -0,0 +1,82 @@ + + + + + + + + + + [page:Interpolant] → + +

    [name]

    + +

    + +

    + +

    Codice di Esempio

    + + +const interpolant = new THREE.[name]( + new Float32Array( 2 ), + new Float32Array( 2 ), + 1, + new Float32Array( 1 ) +); + +interpolant.evaluate( 0.5 ); + + + +

    Costruttore

    + +

    [name]( parameterPositions, sampleValues, sampleSize, resultBuffer )

    +

    + parameterPositions -- array di posizioni
    + sampleValues -- array di campioni
    + sampleSize -- numero di campioni
    + resultBuffer -- buffer per memorizzare il risultato dell'interpolazione.

    +

    + +

    Proprietà

    + +

    [property:null parameterPositions]

    +

    + +

    + +

    [property:null resultBuffer]

    +

    + +

    + +

    [property:null sampleValues]

    +

    + +

    + +

    [property:Object settings]

    +

    + +

    + +

    [property:null valueSize]

    +

    + +

    + +

    Metodi

    + +

    [method:Array evaluate]( [param:Number t] )

    +

    + Valuta l'interpolante alla posizione *t*. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/math/interpolants/QuaternionLinearInterpolant.html b/docs/api/it/math/interpolants/QuaternionLinearInterpolant.html new file mode 100644 index 00000000000000..a1f4cdad1683a6 --- /dev/null +++ b/docs/api/it/math/interpolants/QuaternionLinearInterpolant.html @@ -0,0 +1,82 @@ + + + + + + + + + + [page:Interpolant] → + +

    [name]

    + +

    + +

    + +

    Codice di Esempio

    + + +const interpolant = new THREE.[name]( + new Float32Array( 2 ), + new Float32Array( 2 ), + 1, + new Float32Array( 1 ) +); + +interpolant.evaluate( 0.5 ); + + + +

    Costruttore

    + +

    [name]( parameterPositions, sampleValues, sampleSize, resultBuffer )

    +

    + parameterPositions -- array di posizioni
    + sampleValues -- array di campioni
    + sampleSize -- numero di campioni
    + resultBuffer -- buffer per memorizzare il risultato dell'interpolazione.

    +

    + +

    Proprietà

    + +

    [property:null parameterPositions]

    +

    + +

    + +

    [property:null resultBuffer]

    +

    + +

    + +

    [property:null sampleValues]

    +

    + +

    + +

    [property:Object settings]

    +

    + +

    + +

    [property:null valueSize]

    +

    + +

    + +

    Metodi

    + +

    [method:Array evaluate]( [param:Number t] )

    +

    + Valuta l'interpolante alla posizione *t*. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/objects/Bone.html b/docs/api/it/objects/Bone.html new file mode 100644 index 00000000000000..ae1da86512a5eb --- /dev/null +++ b/docs/api/it/objects/Bone.html @@ -0,0 +1,58 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + Un osso che è parte di uno [page:Skeleton Scheletro]. Lo scheletro a sua volta viene + utilizzato da [page:SkinnedMesh]. Le ossa sono quasi identiche ad un [page:Object3D] vuoto. +

    + +

    Codice di Esempio

    + + + const root = new THREE.Bone(); + const child = new THREE.Bone(); + + root.add( child ); + child.position.y = 5; + + +

    Costruttore

    + +

    [name]( )

    +

    + Crea un nuovo [name]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Object3D] per le proprietà comuni.

    + +

    [property:Boolean isBone]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + + +

    [property:String type]

    +

    Impostato su 'Bone', può essere utilizzato per trovare tutte le ossa in una scena.

    + + +

    Metodi

    +

    Vedi la classe base [page:Object3D] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/objects/Group.html b/docs/api/it/objects/Group.html new file mode 100644 index 00000000000000..e3b8b1339bb762 --- /dev/null +++ b/docs/api/it/objects/Group.html @@ -0,0 +1,65 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + Questo è quasi identico ad un [page:Object3D Object3D]. + Il suo scopo è rendere sintatticamente più chiaro il lavoro con gruppi di oggetti. +

    + +

    Codice di Esempio

    + + + const geometry = new THREE.BoxGeometry( 1, 1, 1 ); + const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); + + const cubeA = new THREE.Mesh( geometry, material ); + cubeA.position.set( 100, 100, 0 ); + + const cubeB = new THREE.Mesh( geometry, material ); + cubeB.position.set( -100, -100, 0 ); + + // Crea un gruppo e aggiunge due cubi + // Questi cubi possono essere ruotati / ridimensionati etc come gruppo + const group = new THREE.Group(); + group.add( cubeA ); + group.add( cubeB ); + + scene.add( group ); + + + +

    Costruttore

    + +

    [name]( )

    + +

    Proprietà

    +

    Vedi la classe base [page:Object3D] per le proprietà comuni.

    + +

    [property:Boolean isGroup]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:String type]

    +

    Una stringa 'Group'. Non deve essere modificata.

    + +

    Metodi

    +

    Vedi la classe base [page:Object3D] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/objects/InstancedMesh.html b/docs/api/it/objects/InstancedMesh.html new file mode 100644 index 00000000000000..2b5bc774e6984e --- /dev/null +++ b/docs/api/it/objects/InstancedMesh.html @@ -0,0 +1,133 @@ + + + + + + + + + + [page:Mesh] → + +

    [name]

    + +

    + Una versione speciale di [page:Mesh] con il supporto per il rendering istanziato. Utilizza [name] + se devi renderizzare un grande numero di oggetti con la stessa geometria e materiale ma con + diverse trasformazioni world. L'utilizzo di [name] ti aiuterà a ridurre il numero di + chiamate di disegno e quindi migliorare le prestazioni complessive del rendering nell'applicazione. +

    + +

    Esempi

    + +

    + [example:webgl_instancing_dynamic WebGL / instancing / dynamic]
    + [example:webgl_instancing_performance WebGL / instancing / performance]
    + [example:webgl_instancing_scatter WebGL / instancing / scatter]
    + [example:webgl_instancing_raycast WebGL / instancing / raycast] +

    + +

    Costruttore

    +

    [name]( [param:BufferGeometry geometry], [param:Material material], [param:Integer count] )

    +

    + [page:BufferGeometry geometry] - un'istanza di [page:BufferGeometry].
    + [page:Material material] - un'istanza di [page:Material]. Il valore di default è un nuovo [page:MeshBasicMaterial].
    + [page:Integer count] - il numero di istanze.
    +

    + +

    Proprietà

    +

    Vedi la classe base [page:Mesh] per le proprietà comuni.

    + +

    [property:Integer count]

    +

    + Il numero di istanze. Il valore `count` passato nel costruttore rappresenta il numero + massimo di istanze di questa mesh. Puoi modificare il numero di istanze in fase di esecuzione ad un valore intero + nell'intervallo [0, count]. +

    +

    + Se hai bisogno di più istanze del valore count originale, devi creare una nuova [name]. +

    + +

    [property:InstancedBufferAttribute instanceColor]

    +

    + Rappresenta i colori di tutte le istanze. Il valore predefinito è `null`. + È necessario impostare il suo flag [page:BufferAttribute.needsUpdate needsUpdate] + a true se si modificano i dati di istanza tramite [page:.setColorAt](). +

    + +

    [property:InstancedBufferAttribute instanceMatrix]

    +

    + Rappresenta la trasformazione locale di tutte le istanze. + È necessario impostare il suo flag [page:BufferAttribute.needsUpdate needsUpdate] + a true se si modificano i dati di istanza tramite [page:.setMatrixAt](). +

    + +

    [property:Boolean isInstancedMesh]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    Metodi

    +

    Vedi la classe base [page:Mesh] per i metodi comuni.

    + +

    [method:undefined dispose]()

    +

    + Libera le risorse relative alla GPU allocate da questa istanza. + Chiama questo metodo ogni volta che questa istanza non è più utilizzata nella tua applicazione. +

    + +

    [method:undefined getColorAt]( [param:Integer index], [param:Color color] )

    +

    + [page:Integer index]: L'indice di un'istanza. I valori devono essere nell'intervallo [0, count]. +

    +

    + [page:Color color]: Il colore dell'oggetto sarà impostato al colore dell'istanza definita. +

    +

    + Ottieni il colore dell'istanza definita. +

    + +

    [method:undefined getMatrixAt]( [param:Integer index], [param:Matrix4 matrix] )

    +

    + [page:Integer index]: L'indice di un'istanza. I valori devono essere nell'intervallo [0, count]. +

    +

    + [page:Matrix4 matrix]: Questa matrice 4x4 sarà impostata alla matrice trasformazione locale dell'istanza definita. +

    +

    + Ottieni la matrice trasformazione locale dell'istanza definita. +

    + +

    [method:undefined setColorAt]( [param:Integer index], [param:Color color] )

    +

    + [page:Integer index]: L'indice di un'istanza. I valori devono essere nell'intervallo [0, count]. +

    +

    + [page:Color color]: Il colore di una singola istanza. +

    +

    + Imposta il colore dato all'istanza definita. + Assicurati di impostare [page:.instanceColor][page:BufferAttribute.needsUpdate .needsUpdate] + a true dopo l'aggiornamento di tutti i colori. +

    + +

    [method:undefined setMatrixAt]( [param:Integer index], [param:Matrix4 matrix] )

    +

    + [page:Integer index]: L'indice di un'istanza. I valori devono essere nell'intervallo [0, count]. +

    +

    + [page:Matrix4 matrix]: Una matrice 4x4 che rappresenta la trasformazione locale di una singola istanza. +

    +

    + Imposta la matrice trasformazione locale data all'istanza definita. + Assicurati di impostare [page:.instanceColor][page:BufferAttribute.needsUpdate .needsUpdate] + a true dopo l'aggiornamento di tutte le matrici. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/objects/LOD.html b/docs/api/it/objects/LOD.html new file mode 100644 index 00000000000000..5e92fbf883f72a --- /dev/null +++ b/docs/api/it/objects/LOD.html @@ -0,0 +1,130 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + Livello di Dettaglio - mostra mesh con più o meno geometria in base alla distanza dalla telecamera.

    + + Ogni livello è associato ad un oggetto, e il rendering può essere commutato tra di loro alle distanze specificate. + In genere creeresti, per esempio, tre mesh, una per il lontano (dettaglio basse), una per la gamma media (medio dettaglio) + e una per i primi piani (alto dettaglio). +

    + +

    Codice di Esempio

    + + + const lod = new THREE.LOD(); + + // Crea sfere con 3 livelli di dettaglio e crea nuovi livelli LOD per loro + for( let i = 0; i < 3; i++ ) { + + const geometry = new THREE.IcosahedronGeometry( 10, 3 - i ) + + const mesh = new THREE.Mesh( geometry, material ); + + lod.addLevel( mesh, i * 75 ); + + } + + scene.add( lod ); + + +

    Esempi

    + +

    + [example:webgl_lod webgl / lod ] +

    + +

    Costruttore

    +

    [name]( )

    +

    + Crea un nuovo [name]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Object3D] per le proprietà comuni.

    + +

    [property:Boolean autoUpdate]

    +

    + Indica se l'oggetto LOD viene aggiornato automaticamente dal renderer per frame o no. + Se impostato a false, devi chiamare da solo [page:LOD.update]() nel ciclo di rendering. + Il valore predefinito è true. +

    + +

    [property:Boolean isLOD]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:Array levels]

    +

    + Un array di oggetti [page:Object level].

    + + Ogni livello è un oggetto con due proprietà:
    + [page:Object3D object] - L'[page:Object3D] da visualizzare a questo livello.
    + [page:Float distance] - La distanza alla quale visualizzare questo livello di dettaglio.
    + [page:Float hysteresis] - Threshold used to avoid flickering at LOD boundaries, as a fraction of distance. +

    + +

    Metodi

    +

    Vedi la classe base [page:Object3D] per i metodi comuni.

    + +

    [method:this addLevel]( [param:Object3D object], [param:Float distance], [param:Float hysteresis] )

    +

    + [page:Object3D object] - L'[page:Object3D] da visualizzare a questo livello.
    + [page:Float distance] - La distanza alla quale visualizzare questo livello di dettaglio.
    + [page:Float hysteresis] - Threshold used to avoid flickering at LOD boundaries, as a fraction of distance. Default 0.0.

    + + Aggiunge una mesh che sarà visualizzata ad una certa distanza e maggiore. In genere, maggiore è + la distanza, minore è il dettaglio sulla mesh. +

    + +

    [method:LOD clone]()

    +

    + Restituisce un clone di questo oggetto LOD e degli oggetti specifici della distanza ad esso associati. +

    + + +

    [method:Integer getCurrentLevel]()

    +

    + Ottiene il livello LOD attivo attualmente. Come indice dell'array dei livelli. +

    + +

    [method:Object3D getObjectForDistance]( [param:Float distance] )

    +

    + Ottiene un riferimento al primo [page:Object3D] (mesh) che è maggiore della [page:Float distance]. +

    + +

    [method:undefined raycast]( [param:Raycaster raycaster], [param:Array intersects] )

    +

    + Ottiene le intersezioni tra un [page:Ray] lanciato a questo LOD. + [page:Raycaster.intersectObject] chiamerà questo metodo. +

    + +

    [method:Object toJSON]( meta )

    +

    + Crea una struttura JSON con i dettagli di questo oggetto LOD. +

    + +

    [method:undefined update]( [param:Camera camera] )

    +

    + Imposta la visibilità di ogni [page:Object3D oggetto] del [page:levels livello] in base + alla distanza dalla [page:Camera telecamera]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/objects/Line.html b/docs/api/it/objects/Line.html new file mode 100644 index 00000000000000..173ad66f833b33 --- /dev/null +++ b/docs/api/it/objects/Line.html @@ -0,0 +1,110 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + Una linea continua.

    + + Questo è quasi lo stesso di [page:LineSegments]; l'unica differenza è che questo viene renderizzato utilizzando + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements gl.LINE_STRIP] + invece di [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements gl.LINES] + +

    + +

    Codice di Esempio

    + + + const material = new THREE.LineBasicMaterial({ + color: 0x0000ff + }); + + const points = []; + points.push( new THREE.Vector3( - 10, 0, 0 ) ); + points.push( new THREE.Vector3( 0, 10, 0 ) ); + points.push( new THREE.Vector3( 10, 0, 0 ) ); + + const geometry = new THREE.BufferGeometry().setFromPoints( points ); + + const line = new THREE.Line( geometry, material ); + scene.add( line ); + + + +

    Costruttore

    + +

    [name]( [param:BufferGeometry geometry], [param:Material material] )

    + +

    + [page:BufferGeometry geometry] — vertici che rappresentano il segmento(i) di linea. Il valore predefinito è una nuova [page:BufferGeometry].
    + [page:Material material] — materiale per la linea. Il valore predefinito è una nuova [page:LineBasicMaterial].
    +

    + +

    Proprietà

    +

    Vedi la classe base [page:Object3D] per le proprietà comuni.

    + +

    [property:BufferGeometry geometry]

    +

    Vertici che rappresentano il segmento(i) di linea.

    + +

    [property:Boolean isLine]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:Material material]

    +

    Materiale per la linea.

    + +

    [property:Array morphTargetInfluences]

    +

    + Un array di pesi solitamente da 0 a 1 che specifica la quantità di morph applicata. + Non definito per impostazione predefinita, ma reimpostato su un array vuoto da [page:.updateMorphTargets](). +

    + +

    [property:Object morphTargetDictionary]

    +

    + Un dizionario di morphTargets basato sulla proprietà morphTarget.name. + Non definito per impostazione predefinita, ma ricompilato [page:.updateMorphTargets](). +

    + +

    Metodi

    +

    Vedi la classe base [page:Object3D] per i metodi comuni.

    + +

    [method:this computeLineDistances]()

    +

    + Calcola un array di valori di distanza necessari per [page:LineDashedMaterial]. + Per ogni vertice nella geometria, il metodo calcola la lunghezza cumulativa dal punto + corrente fino all'inizio della linea. +

    + +

    [method:undefined raycast]( [param:Raycaster raycaster], [param:Array intersects] )

    +

    + Ottiene le intersezioni tra un [page:Ray] lanciato e questa linea. + [page:Raycaster.intersectObject] chiamerà questo metodo. +

    + +

    [method:Line clone]()

    +

    + Restituisce un clone di questo oggetto Line e i suoi discendenti. +

    + +

    [method:undefined updateMorphTargets]()

    +

    + Aggiorna i morphTargets in modo che non abbiano alcuna influenza sull'oggetto. + Reimposta le proprietà [page:.morphTargetInfluences] e [page:.morphTargetDictionary]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/objects/LineLoop.html b/docs/api/it/objects/LineLoop.html new file mode 100644 index 00000000000000..b0235cb107879a --- /dev/null +++ b/docs/api/it/objects/LineLoop.html @@ -0,0 +1,52 @@ + + + + + + + + + + [page:Object3D] → [page:Line] → + +

    [name]

    + +

    + Una linea continua che si ricollega alla partenza.

    + + Questo è quasi lo stesso di [page:Line]; l'unica differenza è che viene + renderizzato utilizzando + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements gl.LINE_LOOP] + invece di [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements gl.LINE_STRIP], + il quale disegna una linea retta al vertice successivo, e ricollega l'ultimo vertice al primo. +

    + + +

    Costruttore

    + +

    [name]( [param:BufferGeometry geometry], [param:Material material] )

    + +

    + [page:BufferGeometry geometry] — Elenco di vertici che rappresentano i punti del ciclo della linea.
    + [page:Material material] — Materiale per la linea. Il valore predefinito è [page:LineBasicMaterial LineBasicMaterial]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Line] per le proprietà comuni.

    + +

    [property:Boolean isLineLoop]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + + +

    Metodi

    +

    Vedi la classe base [page:Line] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/objects/LineSegments.html b/docs/api/it/objects/LineSegments.html new file mode 100644 index 00000000000000..b4bf26b0bfe394 --- /dev/null +++ b/docs/api/it/objects/LineSegments.html @@ -0,0 +1,51 @@ + + + + + + + + + + [page:Object3D] → [page:Line] → + +

    [name]

    + +

    + Una serie di linee tracciate tra coppie di vertici.

    + + Questo è quasi lo stesso di [page:Line]; l'unica differenza è che viene + renderizzato utilizzando + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements gl.LINES] + invece di [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements gl.LINE_STRIP]. +

    + + +

    Costruttore

    + +

    [name]( [param:BufferGeometry geometry], [param:Material material] )

    + +

    + [page:BufferGeometry geometry] — Coppia(e) di vertici che rappresentano ogni segmento(i) di linea.
    + [page:Material material] — Materiale per la linea. Il valore predefinito è [page:LineBasicMaterial LineBasicMaterial]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Line] per le proprietà comuni.

    + +

    [property:Boolean isLineSegments]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + + +

    Metodi

    +

    Vedi la classe base [page:Line] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/objects/Mesh.html b/docs/api/it/objects/Mesh.html new file mode 100644 index 00000000000000..180eeda9bedde8 --- /dev/null +++ b/docs/api/it/objects/Mesh.html @@ -0,0 +1,93 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + Una classe che rappresenta oggetti basati su [link:https://en.wikipedia.org/wiki/Polygon_mesh mesh poligonali] triangolari. + Serve anche come base per altre classi come [page:SkinnedMesh]. +

    + +

    Codice di Esempio

    + + + const geometry = new THREE.BoxGeometry( 1, 1, 1 ); + const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); + const mesh = new THREE.Mesh( geometry, material ); + scene.add( mesh ); + + +

    Costruttore

    + +

    [name]( [param:BufferGeometry geometry], [param:Material material] )

    +

    + [page:BufferGeometry geometry] — (opzionale) un'istanza di [page:BufferGeometry]. Il valore predefinito è una nuova [page:BufferGeometry].
    + [page:Material material] — (opzionale) un singolo o un array di [page:Material Material]. Il valore predefinito è una nuova [page:MeshBasicMaterial]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Object3D] per le proprietà comuni.

    + +

    [property:BufferGeometry geometry]

    +

    + Un'istanza di [page:BufferGeometry] (o classi derivate), che definisce la struttura dell'oggetto. +

    + +

    [property:Boolean isMesh]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:Material material]

    +

    + Un'istanza di materiale derivata dalla classe base [page:Material] o un array di materiali, che definisce + l'aspetto dell'oggetto. Il valore predefinito è [page:MeshBasicMaterial]. +

    + +

    [property:Array morphTargetInfluences]

    +

    + Un array di pesi solitamente da 0 a 1 che specifica la quantità di morph applicata. + Non definito per impostazione predefinita, ma reimpostato su un array vuoto da [page:Mesh.updateMorphTargets updateMorphTargets]. +

    + +

    [property:Object morphTargetDictionary]

    +

    + Un dizionario di morphTargets basato sulla proprietà morphTarget.name. + Non definito per impostazione predefinita, ma ricompilato [page:Mesh.updateMorphTargets updateMorphTargets]. +

    + +

    Metodi

    +

    Vedi la classe base [page:Object3D] per i metodi comuni.

    + +

    [method:Mesh clone]()

    +

    Restituisce un clone di questo oggetto [name] e i suoi discendenti.

    + +

    [method:undefined raycast]( [param:Raycaster raycaster], [param:Array intersects] )

    +

    + Ottiene le intersezioni tra un raggio lanciato e questa mesh. + [page:Raycaster.intersectObject] chiamerà questo metodo, ma i risultati non saranno ordinati. +

    + +

    [method:undefined updateMorphTargets]()

    +

    + Aggiorna i morphTargets in modo che non abbiano influenza sull'oggetto. Reimposta le proprietà + [page:Mesh.morphTargetInfluences morphTargetInfluences] e + [page:Mesh.morphTargetDictionary morphTargetDictionary]. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/objects/Points.html b/docs/api/it/objects/Points.html new file mode 100644 index 00000000000000..b0667a2f6955b8 --- /dev/null +++ b/docs/api/it/objects/Points.html @@ -0,0 +1,88 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + Una classe per visualizzare punti. + I punti sono renderizzati dal [page:WebGLRenderer] utilizzando + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements gl.POINTS]. +

    + + +

    Costruttore

    + +

    [name]( [param:BufferGeometry geometry], [param:Material material] )

    +

    + [page:BufferGeometry geometry] — (opzionale) un'istanza di [page:BufferGeometry]. Il valore predefinito è una nuova [page:BufferGeometry].
    + [page:Material material] — (opzionale) un [page:Material Materiale]. Il valore predefinito è una nuova [page:PointsMaterial]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Object3D] per le proprietà comuni.

    + +

    [property:BufferGeometry geometry]

    +

    + Un'istanza di [page:BufferGeometry] (o classi derivate), che definisce la struttura dell'oggetto. +

    + +

    [property:Boolean isPoints]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:Material material]

    +

    + Un'istanza di [page:Material], che definisce + l'aspetto dell'oggetto. Il valore predefinito è [page:PointsMaterial]. +

    + +

    [property:Array morphTargetInfluences]

    +

    + Un array di pesi solitamente da 0 a 1 che specifica la quantità di morph applicata. + Non definito per impostazione predefinita, ma reimpostato su un array vuoto da [page:Points.updateMorphTargets updateMorphTargets]. +

    + +

    [property:Object morphTargetDictionary]

    +

    + Un dizionario di morphTargets basato sulla proprietà morphTarget.name. + Non definito per impostazione predefinita, ma ricompilato [page:Points.updateMorphTargets updateMorphTargets]. +

    + +

    Metodi

    +

    Vedi la classe base [page:Object3D] per i metodi comuni.

    + +

    [method:undefined raycast]( [param:Raycaster raycaster], [param:Array intersects] )

    +

    + Ottiene le intersezioni tra un raggio lanciato e questo Points. + [page:Raycaster.intersectObject] chiamerà questo metodo, ma i risultati non saranno ordinati. +

    + +

    [method:Points clone]()

    +

    + Restituisce un clone di questo oggetto [name] e i suoi discendenti.

    +

    + +

    [method:undefined updateMorphTargets]()

    +

    + Aggiorna i morphTargets in modo che non abbiano influenza sull'oggetto. Reimposta le proprietà + [page:Points.morphTargetInfluences morphTargetInfluences] e + [page:Points.morphTargetDictionary morphTargetDictionary]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + + diff --git a/docs/api/it/objects/Skeleton.html b/docs/api/it/objects/Skeleton.html new file mode 100644 index 00000000000000..4d3c46f531e2f8 --- /dev/null +++ b/docs/api/it/objects/Skeleton.html @@ -0,0 +1,129 @@ + + + + + + + + + + +

    [name]

    + +

    + Utilizza un array di [page:Bone ossa] per creare uno scheletro che può essere utilizzato da una + [page:SkinnedMesh]. +

    + +

    Codice di Esempio

    + + // Crea un semplice "braccio" + + const bones = []; + + const shoulder = new THREE.Bone(); + const elbow = new THREE.Bone(); + const hand = new THREE.Bone(); + + shoulder.add( elbow ); + elbow.add( hand ); + + bones.push( shoulder ); + bones.push( elbow ); + bones.push( hand ); + + shoulder.position.y = -5; + elbow.position.y = 0; + hand.position.y = 5; + + const armSkeleton = new THREE.Skeleton( bones ); + + +

    + Vedi la pagina [page:SkinnedMesh] per un esempio dell'utilizzo con [page:BufferGeometry]. +

    + +

    Costruttore

    + + +

    [name]( [param:Array bones], [param:Array boneInverses] )

    +

    + [page:Array bones] - L'array di [page:Bone ossa]. Il valore predefinito è un array vuoto.
    + [page:Array boneInverses] - (opzionale) Un array di [page:Matrix4 Matrix4].

    + + Crea un nuovo [name]. +

    + + +

    Proprietà

    + +

    [property:Array bones]

    +

    + L'array di [page:Bone ossa]. Si noti che questa è una copia dell'array originale, non un riferimento, + quindi puoi modificare l'array originale senza che ci siano effetti su questo. +

    + +

    [property:Array boneInverses]

    +

    + Un array di [page:Matrix4 Matrix4] che rappresenta l'inverso della [page:Matrix4 matrixWorld] + delle singole ossa. +

    + +

    [property:Float32Array boneMatrices]

    +

    + Il buffer dell'array che contiene i dati dell'osso quando si utilizza una texture di vertice. +

    + +

    [property:DataTexture boneTexture]

    +

    + Il [page:DataTexture] che contiene i dati dell'osso quando si utilizza una texture di vertice. +

    + +

    [property:Integer boneTextureSize]

    +

    + La dimensione del [page:.boneTexture]. +

    + +

    Metodi

    + +

    [method:Skeleton clone]()

    +

    + Restituisce un clone di questo oggetto Skeleton. +

    + +

    [method:undefined calculateInverses]()

    +

    Genera l'array [page:.boneInverses boneInverses] se non viene fornito nel costruttore.

    + +

    [method:this computeBoneTexture]()

    +

    Calcola un'istanza di [page:DataTexture] in moda da passare i dati dell'osso in modo più efficiente allo shader. + La texture viene assegnata a [page:.boneTexture boneTexture].

    + +

    [method:undefined pose]()

    +

    Restituisce lo scheletro nella posa di base.

    + +

    [method:undefined update]()

    +

    + Aggiorna [page:Float32Array boneMatrices] e [page:DataTexture boneTexture] dopo che le ossa sono state modificate. + Questo viene chiamato automaticamente dal [page:WebGLRenderer] se lo scheletro viene utilizzato con una [page:SkinnedMesh]. +

    + +

    [method:Bone getBoneByName]( [param:String name] )

    +

    + name -- Stringa da abbinare alla proprietà .name di Bone.

    + + Cerca nell'array osseo dello scheletro e restituisce il primo con un nome corrispondente.
    +

    + +

    [method:undefined dispose]()

    +

    + Libera le risorse relative alla GPU allocate da questa istanza. Chiama questo metodo ogni + volta che questa istanza non viene più utilizzata nella tua app. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/objects/SkinnedMesh.html b/docs/api/it/objects/SkinnedMesh.html new file mode 100644 index 00000000000000..b0608c714adf30 --- /dev/null +++ b/docs/api/it/objects/SkinnedMesh.html @@ -0,0 +1,174 @@ + + + + + + + + + + [page:Object3D] → [page:Mesh] → + +

    [name]

    + +

    + Una mesh che ha uno [page:Skeleton scheletro] con [page:Bone ossa] che può essere + utilizzata per animare i vertici della geometria.

    + + [name] può essere utilizzata solo con WebGL 2. Con WebGL 1 è necessario il supporto delle texture del vertice + e `OES_texture_float`. +

    + + + + + +

    Codice di Esempio

    + + + const geometry = new THREE.CylinderGeometry( 5, 5, 5, 5, 15, 5, 30 ); + + // crea manualmente gli indici della pelle e i pesi della pelle + // (tipicamente un loader leggerebbe questi dati da un modello 3D per te) + + const position = geometry.attributes.position; + + const vertex = new THREE.Vector3(); + + const skinIndices = []; + const skinWeights = []; + + for ( let i = 0; i < position.count; i ++ ) { + + vertex.fromBufferAttribute( position, i ); + + // calcola skinIndex e skinWeight in base ad alcuni dati di configurazione + + const y = ( vertex.y + sizing.halfHeight ); + + const skinIndex = Math.floor( y / sizing.segmentHeight ); + const skinWeight = ( y % sizing.segmentHeight ) / sizing.segmentHeight; + + skinIndices.push( skinIndex, skinIndex + 1, 0, 0 ); + skinWeights.push( 1 - skinWeight, skinWeight, 0, 0 ); + + } + + geometry.setAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( skinIndices, 4 ) ); + geometry.setAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeights, 4 ) ); + + // crea skinned mesh e skeleton + + const mesh = new THREE.SkinnedMesh( geometry, material ); + const skeleton = new THREE.Skeleton( bones ); + + // vedi esempio da THREE.Skeleton + + const rootBone = skeleton.bones[ 0 ]; + mesh.add( rootBone ); + + // lega lo scheletro alla mesh + + mesh.bind( skeleton ); + + // muove le ossa e manipola il modello + + skeleton.bones[ 0 ].rotation.x = -0.1; + skeleton.bones[ 1 ].rotation.x = 0.2; + + +

    Costruttore

    +

    [name]( [param:BufferGeometry geometry], [param:Material material] )

    +

    + [page:BufferGeometry geometry] - un'istanza di [page:BufferGeometry].
    + [page:Material material] - (opzionale) un'istanza di [page:Material]. Il valore predefinito è un nuovo [page:MeshBasicMaterial]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Mesh] per le proprietà comuni.

    + +

    [property:String bindMode]

    +

    + O "attached" o "detached". "attached" utilizza la proprietà [page:SkinnedMesh.matrixWorld] + per la matrice di trasformazione delle ossa. "detached" utilizza [page:SkinnedMesh.bindMatrix]. Il valore predefinito è "attached". +

    + +

    [property:Matrix4 bindMatrix]

    +

    + La matrice di base che viene utilizzata per le trasformazioni ossee vincolate. +

    + +

    [property:Matrix4 bindMatrixInverse]

    +

    + La matrice di base che viene utilizzata per reimpostare le trasformazioni ossee vincolate. +

    + +

    [property:Boolean isSkinnedMesh]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:Skeleton skeleton]

    +

    + [page:Skeleton] che rappresenta la gerarchia ossea della skinned mesh. +

    + +

    Metodi

    +

    Vedi la classe base [page:Mesh] per i metodi comuni.

    + +

    [method:undefined bind]( [param:Skeleton skeleton], [param:Matrix4 bindMatrix] )

    +

    + [page:Skeleton skeleton] - [page:Skeleton] creato da un albero di [page:Bone Bones].
    + [page:Matrix4 bindMatrix] - [page:Matrix4] che rappresenta la trasformazione base dello scheletro.

    + + Lega uno scheletro alla skinned mesh. Il bindMatrix viene salvato nella proprietà .bindMatrix + e il .bindMatrixInverse viene calcolato. +

    + +

    [method:SkinnedMesh clone]()

    +

    + Questo metodo attualmente non clona correttamente un'istanza di [name]. Si prega di utilizzare [page:SkeletonUtils.clone]() nel frattempo. +

    + +

    [method:undefined normalizeSkinWeights]()

    +

    + Normalizza i pesi della skin. +

    + +

    [method:undefined pose]()

    +

    + Questo metodo imposta la skinned mesh nella posa di riposo (reimposta la posa). +

    + +

    [method:Vector3 boneTransform]( [param:Integer index], [param:Vector3 target] )

    +

    + Calcola la posizione del vertice in corrispondenza dell'indice specificato rispetto alle attuali trasformazioni ossee. + Il vettore target deve essere inizializzato con le coordinate del vertice prima della trasformazione: + +const target = new THREE.Vector3(); +target.fromBufferAttribute( mesh.geometry.attributes.position, index ); +mesh.boneTransform( index, target ); + +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/objects/Sprite.html b/docs/api/it/objects/Sprite.html new file mode 100644 index 00000000000000..6270e5ce00f4d5 --- /dev/null +++ b/docs/api/it/objects/Sprite.html @@ -0,0 +1,89 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + Una sprite è un piano che è sempre rivolto verso la telecamera, generalmente con + una texture parzialmente trasparente applicata.

    + + Le sprite non proiettano ombre, impostare castShadow = true non avrà alcun effetto. +

    + +

    Codice di Esempio

    + + + const map = new THREE.TextureLoader().load( 'sprite.png' ); + const material = new THREE.SpriteMaterial( { map: map } ); + + const sprite = new THREE.Sprite( material ); + scene.add( sprite ); + + +

    Costruttore

    + +

    [name]( [param:Material material] )

    +

    + [page:Material material] - (opzionale) un'istanza di [page:SpriteMaterial]. Il valore predefinito è una [page:SpriteMaterial] bianca.

    + + Crea una nuova [name]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:Object3D] per le proprietà comuni.

    + +

    [property:Boolean isSprite]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + + +

    [property:SpriteMaterial material]

    +

    + Un'istanza di [page:SpriteMaterial], che definisce l'aspetto dell'oggetto. + Il valore predefinito è una [page:SpriteMaterial] bianca. +

    + + +

    [property:Vector2 center]

    +

    + Il punto di ancoraggio della sprite, e il punto attorno al quale ruota la sprite. Un valore di (0.5, 0.5) + corrisponde al punto medio della sprite. Un valore di (0, 0) corrisponde all'angolo inferiore sinistro della sprite. + Il valore predefinito è (0.5, 0.5). +

    + +

    Metodi

    +

    Vedi la classe base [page:Object3D] per i metodi comuni.

    + +

    [method:Sprite clone]()

    +

    + Restituisce un clone di questo oggetto Sprite e i suoi discendenti. +

    + +

    [method:this copy]( [param:Sprite sprite] )

    +

    + Copia le proprietà della sprite passata in questa. +

    + +

    [method:undefined raycast]( [param:Raycaster raycaster], [param:Array intersects] )

    +

    + Ottiene le intersezioni tra un raggio lanciato e questa sprite. [page:Raycaster.intersectObject]() chiamerà questo metodo. + Il raycaster deve essere inizializzato chiamando [page:Raycaster.setFromCamera]() prima di eseguire il raycast contro le sprite. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/renderers/WebGL1Renderer.html b/docs/api/it/renderers/WebGL1Renderer.html new file mode 100644 index 00000000000000..91f5069b8b70a9 --- /dev/null +++ b/docs/api/it/renderers/WebGL1Renderer.html @@ -0,0 +1,52 @@ + + + + + + + + + + [page:WebGLRenderer] → + +

    [name]

    + +

    + Poiché la versione r118 [page:WebGLRenderer] utilizza automaticamente un contesto di rendering WebGL 2, quando viene aggiornato un progetto estistente a + => r118, l'applicazione potrebbe rompersi per due ragioni: + +

      +
    • Il codice dello shader personalizzato deve essere conforme a GLSL 3.0.
    • +
    • I controlli dell'estensione WebGL 1 devono essere cambiati.
    • +
    + + Se non hai tempo di cambiare il tuo codice ma vuoi ancora utilizzare l'ultima versione, puoi usare [name]. + Questa versione di renderer forzerà un contesto di rendering WebGL 1. +

    + +

    Costruttore

    + +

    [name]( [param:Object parameters] )

    +

    + Crea un nuovo [name]. +

    + +

    Proprietà

    +

    Vedi la classe base [page:WebGLRenderer] per le proprietà comuni.

    + +

    [property:Boolean isWebGL1Renderer]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + + +

    Metodi

    +

    Vedi la classe base [page:WebGLRenderer] per i metodi comuni.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/renderers/WebGL3DRenderTarget.html b/docs/api/it/renderers/WebGL3DRenderTarget.html new file mode 100644 index 00000000000000..079b9e87e56af4 --- /dev/null +++ b/docs/api/it/renderers/WebGL3DRenderTarget.html @@ -0,0 +1,53 @@ + + + + + + + + + + [page:WebGLRenderTarget] → + +

    [name]

    + +

    + Rappresenta un render target tridimensionale. +

    + +

    Costruttore

    + +

    [name]( [param:Number width], [param:Number height], [param:Number depth] )

    +

    + [page:Number width] - la lunghezza del render target, in pixel. Il valore predefinito è `1`.
    + [page:Number height] - l'altezza del render target, in pixel. Il valore predefinito è `1`.
    + [page:Number depth] - la profondità del render target. Il valore predefinito è `1`.

    + + Crea un nuovo [name]. +

    + +

    Proprietà

    + +

    Vedi [page:WebGLRenderTarget] per le proprietà ereditate

    + +

    [property:number depth]

    +

    + La profondità del render target. +

    + +

    [property:Data3DTexture texture]

    +

    + La proprietà texture è sovrasctitta con un'istanza di [page:Data3DTexture]. +

    + +

    Metodi

    + +

    Vedi [page:WebGLRenderTarget] per i metodi ereditati

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/renderers/WebGLArrayRenderTarget.html b/docs/api/it/renderers/WebGLArrayRenderTarget.html new file mode 100644 index 00000000000000..64f450b2a98de1 --- /dev/null +++ b/docs/api/it/renderers/WebGLArrayRenderTarget.html @@ -0,0 +1,59 @@ + + + + + + + + + + [page:WebGLRenderTarget] → + +

    [name]

    + +

    + Questo tipo di render target rappresenta un array di texture. +

    + +

    Esempi

    + +

    + [example:webgl2_rendertarget_texture2darray WebGL 2 / render target / array]
    +

    + +

    Costruttore

    + +

    [name]( [param:Number width], [param:Number height], [param:Number depth] )

    +

    + [page:Number width] - la lunghezza del render target, in pixel. Il valore predefinito è `1`.
    + [page:Number height] - l'altezza del render target, in pixel. Il valore predefinito è `1`.
    + [page:Number depth] - la profondità del render target. Il valore predefinito è `1`.

    + + Crea un nuovo [name]. +

    + +

    Proprietà

    + +

    Vedi [page:WebGLRenderTarget] per le proprietà ereditate

    + +

    [property:number depth]

    +

    + La profondità del render target. +

    + +

    [property:DataArrayTexture texture]

    +

    + La proprietà texture è sovrasctitta con un'istanza di [page:DataArrayTexture]. +

    + +

    Metodi

    + +

    Vedi [page:WebGLRenderTarget] per i metodi ereditati

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/renderers/WebGLCubeRenderTarget.html b/docs/api/it/renderers/WebGLCubeRenderTarget.html new file mode 100644 index 00000000000000..d7ea771d77b688 --- /dev/null +++ b/docs/api/it/renderers/WebGLCubeRenderTarget.html @@ -0,0 +1,79 @@ + + + + + + + + + + [page:WebGLRenderTarget] → + +

    [name]

    + +

    + Utilizzato da [page:CubeCamera] come suo [page:WebGLRenderTarget]. +

    + +

    Esempi

    + +

    Vedi [page:CubeCamera] per gli esempi.

    + + +

    Costruttore

    + + +

    [name]([param:Number size], [param:Object options])

    +

    + [page:Float size] - la dimensione, in pixel. Il valore predefinito è `1`.
    + options - (opzionale) oggetto che contiene i parametri della texture per un target texture auto generato + e i booleani depthBuffer/stencilBuffer. + + Per una spiegazione dei parametri della texture vedi [page:Texture Texture]. Le seguenti + sono opzioni valide:

    + + [page:Constant wrapS] - Il valore predefinito è [page:Textures ClampToEdgeWrapping].
    + [page:Constant wrapT] - Il valore predefinito è [page:Textures ClampToEdgeWrapping].
    + [page:Constant magFilter] - Il valore predefinito è [page:Textures .LinearFilter].
    + [page:Constant minFilter] - Il valore predefinito è [page:Textures LinearFilter].
    + [page:Boolean generateMipmaps] - Il valore predefinito è `false`.
    + [page:Constant format] - Il valore predefinito è [page:Textures RGBAFormat].
    + [page:Constant type] - Il valore predefinito è [page:Textures UnsignedByteType].
    + [page:Number anisotropy] - Il valore predefinito è `1`. Vedi [page:Texture.anisotropy]
    + [page:Constant encoding] - Il valore predefinito è [page:Textures LinearEncoding].
    + [page:Boolean depthBuffer] - Il valore predefinito è `true`.
    + [page:Boolean stencilBuffer] - Il valore predefinito è `false`.

    + + Crea un nuovo [name] +

    + +

    Proprietà

    + +

    Vedi [page:WebGLRenderTarget] per le proprietà ereditate

    + +

    Metodi

    + +

    Vedi [page:WebGLRenderTarget] per i metodi ereditati

    + +

    [method:this fromEquirectangularTexture]( [param:WebGLRenderer renderer], [param:Texture texture] )

    +

    + [page:WebGLRenderer renderer] — il renderer.
    + [page:Texture texture] — la texture equirettangolare. +

    +

    + Utilizza questo metodo se vuoi convertire un panorama equirettangolare nel formato cubemap. +

    + +

    [method:undefined clear]( [param:WebGLRenderer renderer], [param:Boolean color], [param:Boolean depth], [param:Boolean stencil] )

    +

    + Chiama questo metodo per cancellare il colore, la profondità e/o i buffer stencil del render target. + Il buffer del colore è impostato al colore corrente del renderer. L'impostazione predefinita degli argomenti è `true`. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/renderers/WebGLMultipleRenderTargets.html b/docs/api/it/renderers/WebGLMultipleRenderTargets.html new file mode 100644 index 00000000000000..2815d4ef168e15 --- /dev/null +++ b/docs/api/it/renderers/WebGLMultipleRenderTargets.html @@ -0,0 +1,67 @@ + + + + + + + + + + [page:WebGLRenderTarget] → + +

    [name]

    + +

    + Un target di rendering speciale che consente a un fragment shader di scrivere su più texture. + Questo approccio è utile per le tecniche di rendering avanzate come la post-eleborazione o il rendering differito. + + Attenzione: [name] può solo essere utilizzato in un contesto di rendering WebGL 2. +

    + +

    Esempi

    + +

    + [example:webgl2_multiple_rendertargets webgl2 / multiple / rendertargets ] +

    + +

    Costruttore

    + + +

    [name]([param:Number width], [param:Number height], [param:Number count], [param:Object options])

    + +

    + [page:Number width] - La larghezza del target di rendering. Il valore predefinito è `1`.
    + [page:Number height] - L'altezza del target di rendering. Il valore predefinito è `1`.
    + [page:Number count] - Il numero di target di rendering. Il valore predefinito è `1`.
    + + options - (oggetto opzionale che contiene i parametri della texture per una texture target auto generata + e i booleani depthBuffer/stencilBuffer. Per una spiegazione dei parametri della texture consultare [page:Texture Texture]. + Per un elenco di opzioni valide, consultare [page:WebGLRenderTarget WebGLRenderTarget].)

    +

    + +

    Proprietà

    + +

    [property:Boolean isWebGLMultipleRenderTargets]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:Array texture]

    +

    + La proprietà texture viene sovrascritta in [name] e sostituita con un array. Questo array contiene i + riferimenti alla [page:WebGLRenderTarget.texture texture] dei rispettivi target di rendering. +

    + +

    Le proprietà [page:WebGLRenderTarget WebGLRenderTarget] sono disponibili su questa classe.

    + +

    Metodi

    + +

    I metodi [page:WebGLRenderTarget WebGLRenderTarget] sono disponibili su questa classe.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/renderers/WebGLRenderTarget.html b/docs/api/it/renderers/WebGLRenderTarget.html new file mode 100644 index 00000000000000..d0454663814a45 --- /dev/null +++ b/docs/api/it/renderers/WebGLRenderTarget.html @@ -0,0 +1,137 @@ + + + + + + + + + +

    [name]

    + +

    + Un [link:https://webglfundamentals.org/webgl/lessons/webgl-render-to-texture.html render target] è un buffer + dove la scheda video disegna i pixel per una scena che viene renderizzata in background. + Viene utilizzata in diversi effetti, come applicare la post-elaborazione a un'immagine + renderizzata prima di visualizzarla sullo schermo. +

    + + +

    Costruttore

    + + +

    [name]([param:Number width], [param:Number height], [param:Object options])

    + +

    + [page:Float width] - La lunghezza del renderTarget. Il valore predefinito è `1`.
    + [page:Float height] - L'altezza del renderTarget. Il valore predefinito è `1`.
    + options - oggetto opzionale che contiene i parametri della texture per una texture target auto generata + e i booleani depthBuffer/stencilBuffer. + + Per una spiegazione dei parametri della texture vedi [page:Texture Texture]. Le seguenti + sono opzioni valide:

    + + [page:Constant wrapS] - il valore predefinito è [page:Textures ClampToEdgeWrapping].
    + [page:Constant wrapT] - il valore predefinito è [page:Textures ClampToEdgeWrapping].
    + [page:Constant magFilter] - il valore predefinito è [page:Textures LinearFilter].
    + [page:Constant minFilter] - il valore predefinito è [page:Textures LinearFilter].
    + [page:Boolean generateMipmaps] - il valore predefinito è `false`.
    + [page:Constant format] - il valore predefinito è [page:Textures RGBAFormat].
    + [page:Constant type] - il valore predefinito è [page:Textures UnsignedByteType].
    + [page:Number anisotropy] - il valore predefinito è `1`. Vedi [page:Texture.anisotropy]
    + [page:Constant encoding] - il valore predefinito è [page:Textures LinearEncoding].
    + [page:Boolean depthBuffer] - il valore predefinito è `true`.
    + [page:Boolean stencilBuffer] - il valore predefinito è `false`.
    + [page:Number samples] - il valore predefinito è 0.

    + + Crea un nuovo [name] +

    + +

    Proprietà

    + +

    [property:Boolean isWebGLRenderTarget]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:number width]

    +

    + La lunghezza del render target. +

    + +

    [property:number height]

    +

    + L'altezza del render target. +

    + +

    [property:Vector4 scissor]

    +

    + Un area rettangolare all'interno della viewport del render target. I frammenti che sono fuori dall'area verranno scartati. +

    + +

    [property:Boolean scissorTest]

    +

    + Indica se il test scissor è attivo o no. +

    + +

    [property:Vector4 viewport]

    +

    + Il viewport di questo render target. +

    + +

    [property:Texture texture]

    +

    + Questa istanza della texture contiene i pixel renderizzati. Utilizzalo come input per ulteriori informazioni. +

    + +

    [property:Boolean depthBuffer]

    +

    + Effettua il rendering al buffer di profondità. L'impostazione predefinita è `true`. +

    + +

    [property:Boolean stencilBuffer]

    +

    + Effettua il rendering al buffer stencil. Il valore predefinito è `false`. +

    + +

    [property:DepthTexture depthTexture]

    +

    + Se impostato, la profondità della scena verrà renderizzata su questa texture. Il valore predefinito è `null`. +

    + +

    [property:Number samples]

    +

    + Definisce il conteggio di campioni MSAA. Può essere utilizzato solo con WebGL 2. Il valore predefinito è `0`. +

    + +

    Metodi

    + +

    [method:undefined setSize]( [param:Number width], [param:Number height] )

    +

    + Imposta la dimensione del render target. +

    + +

    [method:WebGLRenderTarget clone]()

    +

    + Crea una copia di questo render target. +

    + +

    [method:this copy]( [param:WebGLRenderTarget source] )

    +

    + Adotta le impostazioni del render target dato. +

    + +

    [method:undefined dispose]()

    +

    + Libera le risorse relative alla GPU allocate a questa istanza. Chiama questo metodo ogni volta che questa istanza non viene più utilizzata nella tua app. +

    + +

    I metodi [page:EventDispatcher EventDispatcher] sono disponibili in questa classe.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/renderers/WebGLRenderer.html b/docs/api/it/renderers/WebGLRenderer.html new file mode 100644 index 00000000000000..2fcd7cda80755d --- /dev/null +++ b/docs/api/it/renderers/WebGLRenderer.html @@ -0,0 +1,520 @@ + + + + + + + + + +

    [name]

    + +

    + Il WebGL rendering mostra le tue scene meravigliosamente realizzate utilizzando + [link:https://en.wikipedia.org/wiki/WebGL WebGL]. +

    + +

    Costruttore

    + +

    [name]( [param:Object parameters] )

    +

    + [page:Object parameters] - (opzionale) oggetto con proprietà che definiscono il comportamento del renderer. + Il costruttore inoltre non accetta alcun parametro. In tutti i casi, assumerà impostazioni predefinite + quando i parametri mancheranno. I seguenti sono parametri validi:

    + + [page:DOMElement canvas] - Un [link:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas canvas] + dove il renderer disegna il suo output. + Questo corrisponde alla proprietà [page:WebGLRenderer.domElement domElement] di seguito. + Se non viene passato, un nuovo elemento canvas sarà creato.
    + + + [page:WebGLRenderingContext context] - Questo può essere utilizzato per collegare il renderer ad un + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext RenderingContext] esistente. + Il valore predefinito è `null`.
    + + [page:String precision] - Precisione dello shader. Può essere `"highp"`, `"mediump"` o `"lowp"`. + Il valore predefinito è `"highp"` se supportato dal dispositivo.
    + + [page:Boolean alpha] - controlla il valore predefinito di alfa. Quando impostato a `true`, il valore è `0`. Altrimenti è `1`. Il valore predefinito è `false`.
    + + [page:Boolean premultipliedAlpha] - Indica se il renderer presumerà che i colori abbiano + [link:https://en.wikipedia.org/wiki/Glossary_of_computer_graphics#Premultiplied_alpha premoltiplicato alfa]. + Il valore predefinito è `true`.
    + + [page:Boolean antialias] - Indica se eseguire l'antialiasing. Il valore predefinito è `false`.
    + + [page:Boolean stencil] - Indica se il buffer di disegno ha un + [link:https://en.wikipedia.org/wiki/Stencil_buffer buffer stencil] di almeno 8 bit. + Il valore predefinito è `true`.
    + + [page:Boolean preserveDrawingBuffer] - Indica se conservare i buffer finché non verranno cancellati + o sovrascritti manualmente. Il valore predefinito è `false`.
    + + [page:String powerPreference] - Fornisce un suggerimento allo user agent indicando quale configurazione della + GPU è adatta per questo contesto WebGL. Può essere `"high-performance"`, `"low-power"` o `"default"`. Il valore predefinito è `"default"`. + Vedi [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.2 WebGL spec] per i dettagli.
    + + [page:Boolean failIfMajorPerformanceCaveat] - Indica se la creazione del renderer avrà esito negativo in caso di rilevamento + di prestazioni ridotte. Il valore predefinito è `false`. + Vedi [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.2 WebGL spec] per i dettagli.
    + + [page:Boolean depth] - Indica se il buffer di disegno ha un + [link:https://en.wikipedia.org/wiki/Z-buffering buffer di depth] di almeno 16 bit. + Il valore predefinito è `true`.
    + + [page:Boolean logarithmicDepthBuffer] - Indica se usare un buffer di depth logaritmico. Potrebbe essere necessario utilizzare + questa opzione se si ha a che fare con enormi differenze di scala in una singola scena. Si noti che questa impostazione + utilizza gl_FragDepth, se disponibile, che disabilita l'ottimizzione [link:https://www.khronos.org/opengl/wiki/Early_Fragment_Test Early Fragment Test] + e può causare una riduzione delle prestazioni. + Il valore predefinito è `false`. Vedi l'esempio [example:webgl_camera_logarithmicdepthbuffer camera / logarithmicdepthbuffer]. +

    + +

    Proprietà

    + +

    [property:Boolean autoClear]

    +

    Definisce se il renderer deve cancellare automaticamente il suo output prima di eseguire il rendering di un frame.

    + + +

    [property:Boolean autoClearColor]

    +

    + Se [page:.autoClear autoClear] è `true`, definisce se il renderer deve cancellare il buffer del colore. + Il valore predefinito è `true`. +

    + + +

    [property:Boolean autoClearDepth]

    +

    + Se [page:.autoClear autoClear] è `true`, definisce se il renderer deve cancellare il buffer di depth. + Il valore predefinito è `true`. +

    + + +

    [property:Boolean autoClearStencil]

    +

    + Se [page:.autoClear autoClear] è `true`, definisce se il renderer deve cancellare il buffer dello stencil. + Il valore predefinito è `true`. +

    + +

    [property:Object debug]

    +

    + - [page:Boolean checkShaderErrors]: + Se è `true`, definisce se i programmi material shader devono essere controllati per errori + durante la compilazione e il processo di collegamento. + Può essere utile disabilitare questo controllo in produzione per aumentare le prestazioni. + È fortemente raccomandato mantenere questi controlli attivi durante lo sviluppo. + Se lo shader non si compila e non si collega - non funzionerà e il materiale associato non verrà visualizzato. + Il valore predefinito è `true`. +

    + +

    [property:Object capabilities]

    +

    + Un oggetto che contiene i dettagli sulle capacità del [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext RenderingContext] corrente.
    + + - [page:Boolean floatFragmentTextures]: indica se il contesto supporta l'estensione [link:https://developer.mozilla.org/en-US/docs/Web/API/OES_texture_float OES_texture_float].
    + - [page:Boolean floatVertexTextures]: `true` se [page:Boolean floatFragmentTextures] e [page:Boolean vertexTextures] sono entrambi true.
    + - [page:Method getMaxAnisotropy](): Restituisce l'anisotropia massima disponibile.
    + - [page:Method getMaxPrecision](): Restituisce la precisione massima disponibile per gli shader vertex e fragment.
    + - [page:Boolean isWebGL2]: `true` se il contesto in uso è un oggetto WebGL2RenderingContext.
    + - [page:Boolean logarithmicDepthBuffer]: `true` se il [page:parameter logarithmicDepthBuffer] era impostato a true nel costruttore e + il contesto supporta l'estensione [link:https://developer.mozilla.org/en-US/docs/Web/API/EXT_frag_depth EXT_frag_depth].
    + - [page:Integer maxAttributes]: Il valore di `gl.MAX_VERTEX_ATTRIBS`.
    + - [page:Integer maxCubemapSize]: Il valore di `gl.MAX_CUBE_MAP_TEXTURE_SIZE`. + Altezza massima * larghezza delle texture della mappa del cubo che uno shader può utilizzare.
    + - [page:Integer maxFragmentUniforms]: Il valore di `gl.MAX_FRAGMENT_UNIFORM_VECTORS`. + Il numero di uniforms che possono essere utilizzate da un fragment shader.
    + - [page:Integer maxSamples]: Il valore di `gl.MAX_SAMPLES`. + Il numero massimo di campioni nel contesto dell'anti-aliasing multicampione (MSAA).
    + - [page:Integer maxTextureSize]: Il valore di `gl.MAX_TEXTURE_SIZE`. + Altezza massima * larghezza di una texture che uno shader utilizza.
    + - [page:Integer maxTextures]: Il valore di `gl.MAX_TEXTURE_IMAGE_UNITS`. + Il numero massimo di texture che possono essere utilizzate da uno shader.
    + - [page:Integer maxVaryings]: Il valore di `gl.MAX_VARYING_VECTORS`. + Il numero di vettori varying che possono essere utilizzati dagli shader.
    + - [page:Integer maxVertexTextures]: Il valore di `gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS`. + Il numero di texture che possono essere utilizzate in un vertex shader.
    + - [page:Integer maxVertexUniforms]: Il valore di `gl.MAX_VERTEX_UNIFORM_VECTORS`. + Il numero massimo di uniforms che possono essere utilizzate in un vertex shader.
    + - [page:String precision]: La precisione dello shader attualmente utilizzata dal renderer.
    + - [page:Boolean vertexTextures]: `true` se [property:Integer maxVertexTextures] è maggiore di 0 (ad es. è possibile utilizzare vertex texture).
    +

    + +

    [property:Array clippingPlanes]

    +

    + L'utente definisce piani di taglio specificati come oggetti THREE.Plane nello spazio world. + Questi piani si applicano a livello globale. I punti nello spazio il cui prodotto scalare con il + piano è negativo vengono tagliati. + Il valore predefinito è []. +

    + +

    [property:DOMElement domElement]

    +

    + Un [link:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas canvas] dove il renderer disegna il suo output.
    + Questo viene automaticamente creato dal renderer nel costruttore (se non è già stato fornito); + devi solo aggiungerlo alla tua pagina in questo modo:
    + + document.body.appendChild( renderer.domElement ); + +

    + +

    [property:Object extensions]

    +

    + - [page:Object get]( [param:String extensionName] ): + Utilizzato per verificare se le varie estensioni sono supportate e restituisce un oggetto con i dettagli dell'estensione se disponibile. + Questo metodo può controllare per le seguenti estensioni:
    + +

      +
    • `WEBGL_depth_texture`
    • +
    • `EXT_texture_filter_anisotropic`
    • +
    • `WEBGL_compressed_texture_s3tc`
    • +
    • `WEBGL_compressed_texture_pvrtc`
    • +
    • `WEBGL_compressed_texture_etc1`
    • +
    +

    + +

    [property:number outputEncoding]

    +

    Definisce la codifica di output del renderer. Il valore predefinito è [page:Textures THREE.LinearEncoding].

    +

    Se il target render è stato impostato utilizzando [page:WebGLRenderer.setRenderTarget .setRenderTarget], + verrà invece utilizzato renderTarget.texture.encoding.

    +

    Vedi la pagina [page:Textures texture constants] per i dettagli su altri formati.

    + +

    [property:Object info]

    +

    + Un oggetto con una serie di informazioni statistiche sulla memoria della scheda grafica e sul processo di rendering. + Utile per il debug o solo per curiosità. L'oggetto contiene i seguenti campi:

    +

    +

      +
    • memory: +
        +
      • geometries
      • +
      • textures
      • +
      +
    • +
    • render: +
        +
      • calls
      • +
      • triangles
      • +
      • points
      • +
      • lines
      • +
      • frame
      • +
      +
    • +
    • programs +
    • +
    +

    +

    + Per impostazione predefinita questi dati vengono reimpostati ad ogni chiamata di rendering ma quando si + hanno più passaggi di rendering per frame (ad esempio quando si utilizza la post elaborazione) può essere + preferibile ripristinare con un modello personalizzato. + Inanzitutto, imposta `autoReset` a `false`. + + renderer.info.autoReset = false; + + Chiama `reset()` ogni volta che hai terminato di renderizzare ogni singolo frame. + + renderer.info.reset(); + +

    + +

    [property:Boolean localClippingEnabled]

    +

    Definisce se il render rispetta i piani di taglio a livello di oggetto. Il valore predefinito è `false`.

    + +

    [property:Boolean physicallyCorrectLights]

    +

    + Indica se utilizzare la modalità di illuminazione fisicamente corretta. Il valore predefinito è `false`. + Vedi l'esempio [example:webgl_lights_physical lights / physical]. +

    + +

    [property:Object properties]

    +

    + Utilizzato internamente dal renderer per mantenere traccia delle proprietà dei vari oggetti secondari. +

    + +

    [property:WebGLRenderLists renderLists]

    +

    + Utilizzato internamente per gestire l'ordine del rendering degli oggetti della scena. +

    + +

    [property:WebGLShadowMap shadowMap]

    +

    + Questo contiene il riferimento alla mappa delle ombre, se utilizzato.
    + - [page:Boolean enabled]: + Se impostato, utilizza le mappe delle ombre nella scena. Il valore predefinito è `false`.
    + - [page:Boolean autoUpdate]: + Abilita aggiornamenti automatici delle ombre nella scena. Il valore predefinito è `true`.
    + Se non hai bisogno di luci/ombre, puoi impostarlo su `false` quando viene creata un'istanza del renderer.
    + - [page:Boolean needsUpdate]: + Quando impostato a `true`, le mappe delle ombre nella scena verranno aggiornate nella prossima chiamata a `render`. Il valore predefinito è `false`.
    + Se hai disabilitato gli aggiornamenti automatici alle mappe della ombre (`shadowMap.autoUpdate = false`), + avrai bisogno di impostare questo a `true` e poi fare una chiamata a `render` per aggiornare le ombre nella tua scena.
    + - [page:Integer type]: + Definisce il tipo di mappa delle ombre (non filtrato, filtro di chiusura percentuale, filtro di chiusura percentuale con filtro + bilineare nello shader). + Le opzioni sono: +

      +
    • THREE.BasicShadowMap
    • +
    • THREE.PCFShadowMap (default)
    • +
    • THREE.PCFSoftShadowMap
    • +
    • THREE.VSMShadowMap
    • +
    + Vedi [page:Renderer Renderer constants] per i dettagli.
    +

    + +

    [property:Boolean sortObjects]

    +

    + Definisce se il renderer deve ordinare gli oggetti. Il valore predefinito è `true`.

    + + Nota: L'ordinamento viene utilizzato per tentare di eseguire correttamente il rendering di oggetti + con un certo grado di trasparenza. Per definizione, l'ordinamento degli oggetti potrebbe non funzionare + in tutti i casi. A seconda delle esigenze dell'applicazione, potrebbe essere necessario disattivare + l'ordinamento e utilizzare altri metodi per gestire il rendering della trasparenza, ad es. + determinare manualmente l'ordine di rendering di ciascun oggetto. +

    + +

    [property:Object state]

    +

    + Contiene funzioni per settare varie proprietà dello stato [page:WebGLRenderer.context]. +

    + +

    [property:Constant toneMapping]

    +

    + Il valore predefinito è [page:Renderer NoToneMapping]. Vedi [page:Renderer Renderer constants] per altre scelte. +

    + +

    [property:Number toneMappingExposure]

    +

    + Livello della mappatura dei toni. Il valore predefinito è `1`. +

    + +

    [property:WebXRManager xr]

    +

    + Fornisce accesso all'[page:WebXRManager interfaccia] relativa al WebXR del renderer. +

    + +

    Metodi

    + +

    [method:undefined clear]( [param:Boolean color], [param:Boolean depth], [param:Boolean stencil] )

    +

    + Dice al renderer di cancellare il suo colore, il(i) buffer di disegno depth e stancil. + Questo metodo inizializza il buffer del colore al valore di color corrente.
    + Il valore predefinito degli argomenti è `true`. +

    + +

    [method:undefined clearColor]( )

    +

    Cancella il buffer di colore. Equivalente a chiamare [page:WebGLRenderer.clear .clear]( true, false, false ).

    + +

    [method:undefined clearDepth]( )

    +

    Cancella il buffer di profondità. Equivalente a chiamare [page:WebGLRenderer.clear .clear]( false, true, false ).

    + +

    [method:undefined clearStencil]( )

    +

    Cancella il buffer di stencil. Equivalente a chiamare [page:WebGLRenderer.clear .clear]( false, false, true ).

    + +

    [method:undefined compile]( [param:Object3D scene], [param:Camera camera] )

    +

    Compila tutti i materiali nella scena con la telecamera. Questo è utile per precompilare le ombre prima del primo rendering.

    + +

    [method:undefined copyFramebufferToTexture]( [param:Vector2 position], [param:FramebufferTexture texture], [param:Number level] )

    +

    + Copia i pixel dal WebGLFramebuffer corrente in una texture 2D. Abilita l'accesso a + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/copyTexImage2D WebGLRenderingContext.copyTexImage2D]. +

    + +

    [method:undefined copyTextureToTexture]( [param:Vector2 position], [param:Texture srcTexture], [param:Texture dstTexture], [param:Number level] )

    +

    + Copia tutti i pixel della texture in una texture esistente partendo dalla posizione data. Abilita l'accesso a + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texSubImage2D WebGLRenderingContext.texSubImage2D]. +

    + +

    [method:undefined copyTextureToTexture3D]( [param:Box3 sourceBox], [param:Vector3 position], [param:Texture srcTexture], [param:Texture dstTexture], [param:Number level] )

    +

    + Copia i pixel della texture nei limiti '[page:Box3 sourceBox]' nella texture di destinazione partendo dalla posizione data. Abilita l'accesso a + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/texSubImage3D WebGL2RenderingContext.texSubImage3D]. +

    + +

    [method:undefined dispose]( )

    +

    + Libera le risorse relative alla GPU allocata a questa istanza. Chiama questo metodo ogni volta che questa istanza non viene più utilizzata nella + tua applicazione. +

    + +

    [method:undefined forceContextLoss]()

    +

    + Simula la perdita del contesto WebGL. Questo richiede il supporto per le + estensioni [link:https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context WEBGL_lose_context]. +

    + +

    [method:undefined forceContextRestore]( )

    +

    + Simula il ripristino del contesto WebGL. Questo richiede il supporto per le + estensioni [link:https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context WEBGL_lose_context]. +

    + +

    [method:Float getClearAlpha]()

    +

    Restituisce un [page:Float float] con l'alfa corrente. Intervallo tra 0 e 1.

    + +

    [method:Color getClearColor]( [param:Color target] )

    +

    Restituisce un'istanza [page:Color THREE.Color] con l'alfa corrente.

    + +

    [method:WebGL2RenderingContext getContext]()

    +

    Restituisce il contesto WebGL corrente.

    + +

    [method:WebGLContextAttributes getContextAttributes]()

    +

    Restituisce un oggetto che descrive gli attributi impostati sul contesto WebGL quando è stato creato.

    + +

    [method:Integer getActiveCubeFace]()

    +

    Restituisce la faccia del cubo attiva corrente.

    + +

    [method:Integer getActiveMipmapLevel]()

    +

    Restituisce il livello mipmap attivo corrente.

    + +

    [method:RenderTarget getRenderTarget]()

    +

    Restituisce il [page:RenderTarget RenderTarget] correnti se ci sono; altrimenti restituisce `null`.

    + +

    [method:Vector4 getCurrentViewport]( [param:Vector4 target] )

    +

    + [page:Vector4 target] — il risultato verrà copiato in questo Vector4.

    + + Restituisce il viewport corrente. +

    + +

    [method:Vector2 getDrawingBufferSize]( [param:Vector2 target] )

    +

    + [page:Vector2 target] — il risultato verrà copiato in questo Vector2.

    + + Restituisce la lunghezza e l'altezza del buffer di disegno del renderer, in pixel. +

    + +

    [method:number getPixelRatio]()

    +

    Restituisce il pixel ratio del dispotivo corrente utilizzato.

    + +

    [method:Vector4 getScissor]( [param:Vector4 target] )

    +

    + [page:Vector4 target] — il risultato verrà copiato in questo Vector4.

    + + Restituisce la regione scissor. +

    + +

    [method:Boolean getScissorTest]()

    +

    Restituisce `true` se scissor test è abilitato; altrimenti restituisce `false`.

    + +

    [method:Vector2 getSize]( [param:Vector2 target] )

    +

    + [page:Vector2 target] — il risultato verrà copiato in questo Vector2.

    + + Restituisce la lunghezza e l'altezza del canvas di output del renderer, in pixel. +

    + +

    [method:Vector4 getViewport]( [param:Vector4 target] )

    +

    + [page:Vector4 target] — il risultato verrà copiato in questo Vector4.

    + + Restituisce il viewport. +

    + +

    [method:undefined initTexture]( [param:Texture texture] )

    +

    + Inizializza la texture data. Utilizzato per precaricare una texture piuttosto che aspettare fino al primo rendering + (il quale può causare notevoli ritardi dovuti alla decodifica e al sovraccarico di caricamento della GPU). +

    + +

    [method:undefined resetGLState]( )

    +

    Reimposta lo stato GL al valore predefinito. Chiamato internamente se il contesto WebGL viene perso.

    + +

    [method:undefined readRenderTargetPixels]( [param:WebGLRenderTarget renderTarget], [param:Float x], [param:Float y], [param:Float width], [param:Float height], [param:TypedArray buffer], [param:Integer activeCubeFaceIndex] )

    +

    buffer - Uint8Array è l'unico tipo di destinazione supportato in tutti i casi, altri tipi dipendono dal renderTarget e dalla piattaforma. Vedi [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.12 WebGL spec] per i dettagli.

    +

    Legge le informazioni dei pixel dal renderTarget nel buffer che gli hai passato. Questo è un wrapper attorno a [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/readPixels WebGLRenderingContext.readPixels]().

    +

    Vedi l'esempio [example:webgl_interactive_cubes_gpu interactive / cubes / gpu].

    +

    Per leggere un [page:WebGLCubeRenderTarget WebGLCubeRenderTarget] utilizzare il parametro opzionale activeCubeFaceIndex per determinare quale faccia deve essere letta.

    + + +

    [method:undefined render]( [param:Object3D scene], [param:Camera camera] )

    +

    + Renderizza una [page:Scene scena] o un altro tipo di [page:Object3D oggetto] utilizzando una [page:Camera telecamera].
    + + Il rendering viene seguito su un set [page:WebGLRenderTarget renderTarget] specificato chiamando + [page:WebGLRenderer.setRenderTarget .setRenderTarget] o sul canvas come al solito.
    + + Per impostazione predefinita i buffer sono cancellati prima del rendering ma puoi prevenirlo imposstando la proprietà [page:WebGLRenderer.autoClear autoClear] a false. + Se vuoi prevenire solo certi buffer dall'essere cancellati puoi impostare le proprietà [page:WebGLRenderer.autoClearColor autoClearColor], [page:WebGLRenderer.autoClearStencil autoClearStencil] o + [page:WebGLRenderer.autoClearDepth autoClearDepth] a false. Per cancellare forzatamente uno o più buffer chiama [page:WebGLRenderer.clear .clear]. +

    + +

    [method:undefined resetState]()

    +

    Può essere utilizzato per reimpostare lo stato interno WebGL. Questo metodo è principalmente rilevante per applicazioni che condividono un singolo contesto WebGL tra multiple librerie WebGL.

    + +

    [method:undefined setAnimationLoop]( [param:Function callback] )

    +

    [page:Function callback] — La funzione cancellerà ogni frame disponibile. Se viene passato `null`, si interromperà qualsiasi animazione già in corso.

    +

    Una funzione incorporata che può essere utilizzata al posto di [link:https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame requestAnimationFrame]. + Questa funzione deve essere utilizza per oggetti WebXR.

    + +

    [method:undefined setClearAlpha]( [param:Float alpha] )

    +

    Imposta l'alfa. L'input valido è un float tra `0.0` e `1.0`.

    + +

    [method:undefined setClearColor]( [param:Color color], [param:Float alpha] )

    +

    Imposta il colore e l'opacità.

    + +

    [method:undefined setPixelRatio]( [param:number value] )

    +

    Imposta la pixel ratio del dispositivo. Questo viene utilizzato per il dispositivo HiDPI per evitare la sfocatura del canvas di output.

    + +

    [method:undefined setRenderTarget]( [param:WebGLRenderTarget renderTarget], [param:Integer activeCubeFace], [param:Integer activeMipmapLevel] )

    +

    + renderTarget -- Il [page:WebGLRenderTarget renderTarget] cha ha bisogno di essere attivato. Quando viene fornito `null`, il canvas invece viene impostato come target di rendering attivo.
    + activeCubeFace -- Specifica il lato attivo del cubo (PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5) di [page:WebGLCubeRenderTarget]. + Quando si passa un [page:WebGLArrayRenderTarget] o [page:WebGL3DRenderTarget] questo indica il livello z in cui eseguire il rendering (opzionale).
    + activeMipmapLevel -- Specifica il livello mipmap attivo (opzionale).

    + Questo metodo imposta il renderTarget attivo. +

    + +

    [method:undefined setScissor]( [param:Integer x], [param:Integer y], [param:Integer width], [param:Integer height] )
    + [method:undefined setScissor]( [param:Vector4 vector] )

    + +

    + I parametri x, y, lunghezza, e altezza della regione di scissor.
    + Opzionale, un vettore component-4 che specifica i parametri della regione.

    + + Imposta la regione di scissor da (x, y) a (x + width, y + height).
    + (x, y) indica l'angolo in basso a sinistra della regione di scissor. +

    + +

    [method:undefined setScissorTest]( [param:Boolean boolean] )

    +

    + Abilita o disabilita lo scissor test. Quando questo è abilitato, solo i pixel con l'area di + scissor definita saranno influenzati da ulteriori azioni del render. +

    + +

    [method:undefined setOpaqueSort]( [param:Function method] )

    +

    + Imposta la funzione di ordinamento opaco per la WebGLRenderLists. + Passa null per utilizzare la funzione predefinita painterSortStable. +

    + +

    [method:undefined setTransparentSort]( [param:Function method] )

    +

    + Imposta la funzione di ordinamento trasparente per la WebGLRenderLists. + Passa null per utilizzare la funzione predefinita reversePainterSortStable. +

    + +

    [method:undefined setSize]( [param:Integer width], [param:Integer height], [param:Boolean updateStyle] )

    +

    + Ridimensiona il canvas di output a (width, height) con la pixel ratio del device presa nell'account, + e inoltre imposta il viewport per adattarsi a quella dimensione, partendo da (0, 0). + Impostando [page:Boolean updateStyle] a false impedisce qualsiasi modifica di stile al canvas di output. +

    + +

    [method:undefined setViewport]( [param:Integer x], [param:Integer y], [param:Integer width], [param:Integer height] )
    + [method:undefined setViewport]( [param:Vector4 vector] )

    + +

    + I parametri x, y, lunghezza, e altezza del viewport.
    + Opzionale, un vettore component-4 che specifica i parametri del viewport.

    + + Imposta il viewport per il rendering da (x, y) a (x + width, y + height).
    + (x, y) indica l'angolo in basso a sinistra della regione. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/renderers/shaders/ShaderChunk.html b/docs/api/it/renderers/shaders/ShaderChunk.html new file mode 100644 index 00000000000000..8f004c798c34d4 --- /dev/null +++ b/docs/api/it/renderers/shaders/ShaderChunk.html @@ -0,0 +1,30 @@ + + + + + + + + + +

    [name]

    + +

    Blocchi shader per la libreria Shader WebGL.

    + + + +

    Proprietà

    + + + +

    Metodi

    + + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/renderers/shaders/ShaderLib.html b/docs/api/it/renderers/shaders/ShaderLib.html new file mode 100644 index 00000000000000..9e124f57bc563a --- /dev/null +++ b/docs/api/it/renderers/shaders/ShaderLib.html @@ -0,0 +1,29 @@ + + + + + + + + + +

    [name]

    + +

    Libreria Shader WebGL per three.js.

    + + +

    Proprietà

    + + + +

    Metodi

    + + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/renderers/shaders/UniformsLib.html b/docs/api/it/renderers/shaders/UniformsLib.html new file mode 100644 index 00000000000000..0c2c87daed1a07 --- /dev/null +++ b/docs/api/it/renderers/shaders/UniformsLib.html @@ -0,0 +1,30 @@ + + + + + + + + + +

    [name]

    + +

    Libreria di uniformi per shared webgl condivisi.

    + + + +

    Proprietà

    + + + +

    Metodi

    + + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/renderers/shaders/UniformsUtils.html b/docs/api/it/renderers/shaders/UniformsUtils.html new file mode 100644 index 00000000000000..c0e23c26cac026 --- /dev/null +++ b/docs/api/it/renderers/shaders/UniformsUtils.html @@ -0,0 +1,41 @@ + + + + + + + + + +

    [name]

    + +

    + Fornisce funzioni di utilità per gestire le uniformi. +

    + +

    Metodi

    + +

    [method:Object clone]( [param:Object src] )

    +

    + src -- Un oggetto che rappresenta le definizioni delle uniformi.

    + + Clona le definizioni delle uniformi date eseguendo una copia profonda. Questo significa che se + il [page:Uniform.value valore] di una uniforme si riferisce ad un oggetto come un [page:Vector3] + o una [page:Texture], la uniforme clonata farà riferimento a un nuovo oggetto di riferimento. +

    + +

    [method:Object merge]( [param:Array uniforms] )

    +

    + uniforms -- Un array di oggetti contente le definizioni della uniforme.

    + + Unisce le definizioni della uniforme date nel singolo oggetto. Poiché il metodo + utilizza internamente [page:.clone](), esegue una copia profonda durante + la produzione delle definizioni della uniforme unita. + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/renderers/webgl/WebGLProgram.html b/docs/api/it/renderers/webgl/WebGLProgram.html new file mode 100644 index 00000000000000..d7192534725d5e --- /dev/null +++ b/docs/api/it/renderers/webgl/WebGLProgram.html @@ -0,0 +1,169 @@ + + + + + + + + + +

    [name]

    + +

    Costruttore per il programma GLSL inviato agli shader vertex e fragment, comprese le uniformi e gli attributi.

    + +

    Uniformi e attributi incorporati

    + +

    Vertex shader (incondizionato):

    +
    + + // = object.matrixWorld + uniform mat4 modelMatrix; + + // = camera.matrixWorldInverse * object.matrixWorld + uniform mat4 modelViewMatrix; + + // = camera.projectionMatrix + uniform mat4 projectionMatrix; + + // = camera.matrixWorldInverse + uniform mat4 viewMatrix; + + // = trasposizione inversa di modelViewMatrix + uniform mat3 normalMatrix; + + // = posizione della telecamera nello spazio world + uniform vec3 cameraPosition; + + + // attributi di vertice predefiniti forniti da Geometry e BufferGeometry + attribute vec3 position; + attribute vec3 normal; + attribute vec2 uv; + +

    + Si noti che è possibile quindi calcolare la posizione di un vertice nel vertex shader con: + + gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); + + o in alternativa + + gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4( position, 1.0 ); + +

    +
    + +

    Vertex shader (condizionale):

    +
    + + #if defined( USE_COLOR_ALPHA ) + // attributo del colore del vertice con alfa + attribute vec4 color; + #elif defined( USE_COLOR ) + // attributo del colore del vertice + 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 + + + #ifdef USE_INSTANCING + // Si noti che modelViewMatrix non è impostato durante il rendering di un modello istanziato, + // ma può essere calcolato da viewMatrix * modelMatrix. + // + // Utilizzo di base: + // gl_Position = projectionMatrix * viewMatrix * modelMatrix * instanceMatrix * vec4(position, 1.0); + attribute mat4 instanceMatrix; + #endif + +
    + +

    Fragment shader:

    +
    + + uniform mat4 viewMatrix; + uniform vec3 cameraPosition; + +
    + + +

    Costruttore

    + +

    [name]( [param:WebGLRenderer renderer], [param:String cacheKey], [param:Object parameters] )

    +

    Per i parametri vedere [page:WebGLRenderer WebGLRenderer].

    + +

    Proprietà

    + +

    [property:String name]

    +

    Il nome del rispettivo programma di shader.

    + +

    [property:String id]

    +

    L'identificativo di questa istanza.

    + +

    [property:String cacheKey]

    +

    Questa chiave consente la riutilizzabilità di un unico [name] per diversi materiali.

    + +

    [property:Integer usedTimes]

    +

    Quante volte questa istanza viene utilizzata per il rendering di elementi di rendering.

    + +

    [property:Object program]

    +

    L'attuale programma di shader.

    + +

    [property:WebGLShader vertexShader]

    +

    Il vertex shader.

    + +

    [property:WebGLShader fragmentShader]

    +

    Il fragment shader.

    + +

    Metodi

    + +

    [method:Object getUniforms]()

    +

    + Restituisce una mappa nome-valore di tutte le posizioni uniformi attive. +

    + +

    [method:Object getAttributes]()

    +

    + Restituisce una mappa nome-valore di tutte le posizioni degli attributi dei vertici attivi. +

    + +

    [method:undefined destroy]()

    +

    + Distrugge un'istanza di [name]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/renderers/webxr/WebXRManager.html b/docs/api/it/renderers/webxr/WebXRManager.html new file mode 100644 index 00000000000000..6c2ae7f94644ba --- /dev/null +++ b/docs/api/it/renderers/webxr/WebXRManager.html @@ -0,0 +1,152 @@ + + + + + + + + + + +

    [name]

    + +

    + Questa classe rappresenta un'astrazione dell'API WebXR Device ed è utilizzata internamente da [page:WebGLRenderer]. + [name] inoltre fornisce un'interfaccia pubblica che permette agli utenti di abilitare e disabilitare XR ed + eseguire attività relative a XR come ad esempio il recupero dei controller. +

    + +

    Proprietà

    + +

    [property:Boolean cameraAutoUpdate]

    +

    + Indica se la telecamera XR del manager deve essere aggiornata automaticamente o no. Il valore predefinito è `true`. +

    + +

    [property:Boolean enabled]

    +

    + Questo flag notifica al renderer di essere pronto per il rendering XR. L'impostazione predefinita è `false`. + Impostalo a `true` se stai utilizzando XR nella tua applicazione. +

    + +

    [property:Boolean isPresenting]

    +

    + Indica se la presentazione XR è attiva o meno. Il valore predefinito è `false`. Questo flag è di sola + lettura e impostato automaticamente da [name]. +

    + +

    Metodi

    + +

    [method:ArrayCamera getCamera]()

    +

    + Restituisce un'istanza di [page:ArrayCamera] che rappresenta la telecamera XR sessione XR attiva. + Per ogni vista contiene un oggetto telecamera separato nella sua proprietà [page:ArrayCamera.cameras telecamere]. +

    +

    + Il `fov` della telecamera non viene utilizzato attualmente e non riflette il fov della telecamera XR. Se hai bisogno del fov a + livello di app, devi calcolare manualmente dalle matrici di proiezione della telecamera XR. +

    + +

    [method:Group getController]( [param:Integer index] )

    +

    + [page:Integer index] — L'indice del controller.

    + + Restituisce un [page:Group gruppo] che rappresenta il cosidetto spazio *target ray* del controller XR. + Utilizza questo spazio per visualizzare gli oggetti 3D che supportano l'utente nel puntare attività come + l'intersezione dell'interfaccia utente. +

    + +

    [method:Group getControllerGrip]( [param:Integer index] )

    +

    + [page:Integer index] — L'indice del controller.

    + + Restituisce un [page:Group gruppo] che rappresenta il cosidetto spazio `grip` del controller XR. + Utilizza questo spazio se l'utente terrà altri oggetti 3D come una spada laser. +

    + +

    + Nota: Se vuoi mostrare qualcosa nella mano dell'utente e offrire un raggio di puntamento allo stesso tempo, ti consigliamo di allegare + l'oggetto tenuto in mano al gruppo restituito da [page:.getControllerGrip]() e il raggio al gruppo restituito da [page:.getController](). + L'idea è quella di avere due gruppi diversi in due coordinate delle spazio diverse per lo stesso controller WebXR. +

    + +

    [method:Float getFoveation]()

    +

    + Restituisce la quantità di foveazione utilizzata dal compositore XR per il livello di proiezione. +

    + +

    [method:Group getHand]( [param:Integer index] )

    +

    + [page:Integer index] — L'indice del controller.

    + + Restituisce un [page:Group gruppo] che rappresenta il cosidetto spazio `hand` o `joint` per il controller XR. + Utilizza questo spazio per visualizzare le mani dell'utente quando vengono utilizzati i controller non fisici. +

    + +

    [method:String getReferenceSpace]()

    +

    + Restituisce lo spazio di riferimento. +

    + +

    [method:XRSession getSession]()

    +

    + Restituisce l'oggetto `XRSession` il quale permette una maggiore gestione delle sessioni WebXR attive a livello di applicazione. +

    + +

    [method:undefined setFoveation]( [param:Float foveation] )

    +

    + [page:Float foveation] — Il foveazione da impostare.

    + + Specifica la quantità di foveazione utilizzata dal compositore XR per il livello. Deve essere un valore tra `0` e `1`. +

    + +

    [method:undefined setFramebufferScaleFactor]( [param:Float factor], [param:Boolean limited] )

    +

    + [page:Float factor] — Il fattore di scala del framebuffer da impostare.

    + [page:Boolean limited] — Whether the framebuffer scale factor should be reduced to the native limit if the value ends up being higher than the device's capabilities. Default is `false`.

    + + Specifica il fattore di ridimensionamento da utilizzare per determinare la dimensione del framebuffer durante il rendering + su un dispositivo XR. Il valore è relativo alla risoluzione del dispositivo XR predefinito. Il valore predefinito è `1`. + Un valore di `0.5` specificherebbe un framebuffer con il 50% della risoluzione nativa del display. +

    + +

    + Nota: Non è possibile modificare il fattore di scala del framebuffer durante la presentazione del contenuto. +

    + +

    [method:undefined setReferenceSpace]( [param:XRReferenceSpace referenceSpace] )

    +

    + [page:XRReferenceSpace referenceSpace] — Uno spazio personalizzato di riferimento.

    + + Può essere utilizzato per configurare uno spazio personalizzato di riferimento il quale sovrascrive + lo spazio di riferimento predefinito. +

    + +

    [method:undefined setReferenceSpaceType]( [param:String referenceSpaceType] )

    +

    + [page:String referenceSpaceType] — Il tipo dello spazio di riferimento da impostare.

    + + Può essere utilizzare per configurare una relazione spaziale con l'ambiente fisico dell'utente. A seconda di come l'utente + si muove nello spazio 3D, l'impostazione di uno spazio di riferimento appropriato può migliorare il tracciamento. + Il valore predefinito è `local-floor`. + Consultare l'[link:https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpaceType MDN] per i possibli valori e i relativi casi d'uso. +

    + +

    [method:undefined updateCamera]( [param:PerspectiveCamera camera] )

    +

    + Aggiorna lo stato della telecamera XR. Utilizza questo metodo a livello di app, se imposti [page:.cameraAutoUpdate] a `false`. + Questo metodo richiede la telecamera non XR della scena come parametro. La trasformazione della telecamera passata viene automaticamente + regolata sulla posizione della telecamera XR quando si chiama questo metodo. +

    + +

    + Nota: Non è possibile modificare il tipo dello spazio di riferimento durante la presentazione del contenuto XR. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/scenes/Fog.html b/docs/api/it/scenes/Fog.html new file mode 100644 index 00000000000000..39d1bbefe3e194 --- /dev/null +++ b/docs/api/it/scenes/Fog.html @@ -0,0 +1,63 @@ + + + + + + + + + +

    [name]

    + +

    Questa classe contiene i parametri che definiscono la nebbia lineare, cioè che cresce linearmente con la distanza.

    + + +

    Costruttore

    + + +

    [name]( [param:Integer color], [param:Float near], [param:Float far] )

    +

    + Il parametro colore è passato al costruttore [page:Color] per impostare la proprietà colore. + La proprietà colore può essere un intero esadecimale o una stringa CSS.

    + +

    Proprietà

    + +

    [property:Boolean isFog]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:String name]

    +

    Nome opzionale dell'oggetto (non è necessario che sia univoco). Il valore predefinito è una stringa vuota.

    + +

    [property:Color color]

    +

    Colore della nebbia. Esempio: Se impostato su nero, gli oggetti lontani saranno neri.

    + +

    [property:Float near]

    +

    + La distanza minima per iniziare ad applicare la nebbia. Gli oggetti che si trovano a meno di 'vicino' + dalla telecamera attiva non saranno influenzati dalla nebbia. +

    +

    Il valore predefinito è 1.

    + +

    [property:Float far]

    +

    + La distanza massima alla quale la nebbia smette di essere calcolata e applicata. Gli oggetti che si trovano a più di 'lontano' + dalla telecamera attiva non saranno influenzati dalla nebbia. +

    Il valore predefinito è 1000.

    + +

    Metodi

    + +

    [method:Fog clone]()

    +

    Restituisce una nuova istanza di nebbia con gli stessi parametri di questa.

    + +

    [method:Object toJSON]()

    +

    Restituisce i dati della nebbia nel formato JSON.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/scenes/FogExp2.html b/docs/api/it/scenes/FogExp2.html new file mode 100644 index 00000000000000..927670675b4b9d --- /dev/null +++ b/docs/api/it/scenes/FogExp2.html @@ -0,0 +1,59 @@ + + + + + + + + + +

    [name]

    + +

    + Questa classe contiene i parametri che definiscono la nebbia quadrata esponenziale, + che offre una visione chiara vicino alla telecamera e una nebbia più veloce di quella + a densità esponenziale più lontana dalla telecamera. +

    + +

    Costruttore

    + + +

    [name]( [param:Integer color], [param:Float density] )

    + +

    + Il parametro colore è passato al costruttore [page:Color] per impostare la proprietà colore. + La proprietà colore può essere un intero esadecimale o una stringa CSS. +

    + +

    Proprietà

    + +

    [property:Boolean isFogExp2]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:String name]

    +

    Nome opzionale dell'oggetto (non è necessario che sia univoco). Il valore predefinito è una stringa vuota.

    + +

    [property:Color color]

    +

    Colore della nebbia. Esempio: Se impostato su nero, gli oggetti lontani saranno neri.

    + +

    [property:Float density]

    +

    Definisce la velocità con cui la nebbia diventerà densa.

    +

    Il valore predefinito è 0.00025.

    + +

    Metodi

    + +

    [method:FogExp2 clone]()

    +

    Restituisce una nuova istanza di FogExp2 con gli stessi parametri di questa.

    + +

    [method:Object toJSON]()

    +

    Restituisce i dati di FogExp2 nel formato JSON.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/scenes/Scene.html b/docs/api/it/scenes/Scene.html new file mode 100644 index 00000000000000..3ecaa8985afba7 --- /dev/null +++ b/docs/api/it/scenes/Scene.html @@ -0,0 +1,83 @@ + + + + + + + + + + [page:Object3D] → +

    [name]

    + +

    + Le scene ti consentono di impostare cosa e dove deve essere renderizzato da three.js. + Qui è dove posizioni gli oggetti, le luci e le telecamere.

    + + +

    Crostruttore

    + + +

    [name]()

    +

    + Crea un nuovo oggetto scena. +

    + + +

    Proprietà

    + +

    [property:Object background]

    +

    + Definisce lo sfondo della scena. Il valore predefinito è `null`. Gli input validi sono: +

      +
    • Un [page:Color Colore] per definire un background uniformemente colorato.
    • +
    • Una [page:Texture] per definire un background con texture (piatto).
    • +
    • Cubi di texture ([page:CubeTexture]) o texture equirettangolari per la definizione di uno skybox.
    • +
    + Nota: Tutte le configurazioni relative alla telecamera come lo `zoom` o la `view` vengono ignorate. +

    + +

    [property:Float backgroundBlurriness]

    +

    + Imposta la sfocatura dello sfondo. Influisce solo sulle mappe ambientali assegnate a [page:Scene.background]. + L'imput valido è un float compreso tra *0* e *1*. Il valore predefinito è *0*. +

    + +

    [property:Texture environment]

    +

    + Imposta la mappa ambientale per tutti i materiali fisici nella scena. + Tuttavia, non è possibile sovrascrivere una texture esistente assegnata a [page:MeshStandardMaterial.envMap]. + Il valore predefinito è `null`. +

    + +

    [property:Fog fog]

    + +

    + Un'istanza della [page:Fog nebbia] che definisce il tipo di nebbia che influisce su qualsiasi cosa sia visualizzata nella scena. + Il valore predefinito è `null`. +

    + +

    [property:Boolean isScene]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:Material overrideMaterial]

    + +

    Forza tutto quello che c'è nella scena ad essere renderizzato con il materiale definito. Il valore predefinito è `null`.

    + +

    Metodi

    + +

    [method:Object toJSON]( [param:Object meta] )

    +

    + meta -- oggetto contenente i metadati come le texture o le immagini per la scena.
    + Converte la scena nel [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 formato JSON Oggetto/Scena] di three.js. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/textures/CanvasTexture.html b/docs/api/it/textures/CanvasTexture.html new file mode 100644 index 00000000000000..a42a870e8549a8 --- /dev/null +++ b/docs/api/it/textures/CanvasTexture.html @@ -0,0 +1,85 @@ + + + + + + + + + + [page:Texture] → + +

    [name]

    + +

    + Crea una texture da un elemento canvas.

    + + Questa classe è quasi la stessa cosa della classe [page:Texture Texture], tranne per il fatto che imposta + [page:Texture.needsUpdate needsUpdate] a `true` immediatamente. +

    + + +

    Costruttore

    +

    [name]( [param:HTMLElement canvas], [param:Constant mapping], [param:Constant wrapS], [param:Constant wrapT], [param:Constant magFilter], [param:Constant minFilter], [param:Constant format], [param:Constant type], [param:Number anisotropy] )

    +

    + [page:HTMLElement canvas] -- L'elemento canvas HTML dal quale caricare la texture.
    + + [page:Constant mapping] -- Come l'immagine viene applicata all'oggetto. Un tipo di oggetto di [page:Textures THREE.UVMapping]. + Vedi [page:Textures mapping constants] per altre scelte.
    + + [page:Constant wrapS] -- L'impostazione predefinita è [page:Textures THREE.ClampToEdgeWrapping]. + Vedi [page:Textures wrap mode constants] per altre scelte.
    + + [page:Constant wrapT] -- L'impostazione predefinita è [page:Textures THREE.ClampToEdgeWrapping]. + Vedi [page:Textures wrap mode constants] per altre scelte.
    + + [page:Constant magFilter] -- Come viene campionata la texture quando un texel copre più di un pixel. + L'impostazione predefinita è [page:Textures THREE.LinearFilter]. Vedi [page:Textures magnification filter constants] per altre scelte.
    + + [page:Constant minFilter] -- Come viene campionata la texture quando un texel copre meno di un pixel. + L'impostazione predefinita è [page:Textures THREE.LinearMipmapLinearFilter]. Vedi [page:Textures minification filter constants] per altre scelte.
    + + [page:Constant format] -- Il formato utilizzato nella texture. + Vedi [page:Textures format constants] per altre scelte.
    + + [page:Constant type] -- L'impostazione predefinita è [page:Textures THREE.UnsignedByteType]. + Vedi [page:Textures type constants] per altre scelte.
    + + [page:Number anisotropy] -- Il numero di campioni prelevati lungo l'asse attravero il pixel che ha la densità di texel più alta. + Per impostazione predefinita, questo valore è 1. Un valore più alto fornisce un risultato meno sfuocato rispetto ad una mipmap di base, + a costo di utilizzare più campioni di texture. Usa [page:WebGLrenderer.getMaxAnisotropy renderer.getMaxAnisotropy]() + per trovare il valore di anisotropia massimo valido per la GPU; questo valore è solitamente una potenza di 2.

    +

    + + +

    Proprietà

    + +

    + Vedi la classe base [page:Texture Texture] per le proprietà comuni. +

    + +

    [property:Boolean isCanvasTexture]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:Boolean needsUpdate]

    + +

    + True per impostazione predefinita. Ciò è necessario affinchè i dati della texture vengano caricati. +

    + +

    Metodi

    + +

    + Vedi la classe base [page:Texture Texture] per i metodi comuni. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/textures/CompressedArrayTexture.html b/docs/api/it/textures/CompressedArrayTexture.html new file mode 100644 index 00000000000000..67cb2562a89038 --- /dev/null +++ b/docs/api/it/textures/CompressedArrayTexture.html @@ -0,0 +1,76 @@ + + + + + + + + + + [page:CompressedTexture] → + +

    [name]

    + +

    + Crea un array di texture 2D basato su dati in forma compressa, ad esempio da un file [link:https://en.wikipedia.org/wiki/DirectDraw_Surface DDS].

    + + Da utilizzare con [page:CompressedTextureLoader CompressedTextureLoader]. +

    + + +

    Costruttore

    + + +

    [name]( [param:Array mipmaps], [param:Number width], [param:Number height], [param:Constant format], [param:Constant type] )

    +

    + [page:Array mipmaps] -- L'array mipmap dovrebbe contenere oggetti con dati, larghezza e altezza. Le mipmap dovrebbero essere del formato e del tipo corretti.
    + + [page:Number width] -- La larghezza della mipmap più grande.
    + + [page:Number height] -- L'altezza della mipmap più grande.
    + + [page:Number depth] -- La profondità della mipmap più grande.
    + + [page:Constant format] -- Il formato utilizzato nelle mipmap. + Vedi [page:Textures ST3C Compressed Texture Formats], + [page:Textures PVRTC Compressed Texture Formats] e + [page:Textures ETC Compressed Texture Format] per altre scelte.
    + + [page:Constant type] -- Il valore predefinito è [page:Textures THREE.UnsignedByteType]. + Vedi [page:Textures type constants] per altre scelte.
    + +

    + + +

    Proprietà

    + +

    + Vedi la classe base [page:CompressedTexture CompressedTexture] per le proprietà comuni. +

    + +

    [property:number wrapR]

    +

    + Questa proprietà definisce come la texture viene wrappata nella direzione della profondità.
    + Il valore predefinito è [page:Textures THREE.ClampToEdgeWrapping], in cui il bordo è bloccato ai texel del bordo esterno. + Le altre due scelte sono [page:Textures THREE.RepeatWrapping] e [page:Textures THREE.MirroredRepeatWrapping]. + Vedi la pagina [page:Textures texture constants] per i dettagli. +

    + +

    [property:Boolean isCompressedArrayTexture]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    Metodi

    + +

    + Vedi la classe base [page:CompressedTexture CompressedTexture] per i metodi comuni. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/textures/CompressedTexture.html b/docs/api/it/textures/CompressedTexture.html new file mode 100644 index 00000000000000..7482bf461e341c --- /dev/null +++ b/docs/api/it/textures/CompressedTexture.html @@ -0,0 +1,98 @@ + + + + + + + + + + [page:Texture] → + +

    [name]

    + +

    + Crea una texture basata su dati in forma compressa, per esempio per un file + [link:https://en.wikipedia.org/wiki/DirectDraw_Surface DDS].

    + + Da utilizzare con [page:CompressedTextureLoader CompressedTextureLoader]. +

    + + +

    Costruttore

    + + +

    [name]( [param:Array mipmaps], [param:Number width], [param:Number height], [param:Constant format], [param:Constant type], [param:Constant mapping], [param:Constant wrapS], [param:Constant wrapT], [param:Constant magFilter], [param:Constant minFilter], [param:Number anisotropy] )

    +

    + [page:Array mipmaps] -- L'array mipmap dovrebbe contenere oggetti con dati, larghezza e altezza. Le mipmap dovrebbero essere del formato e del tipo corretti.
    + + [page:Number width] -- La larghezza della mipmap più grande.
    + + [page:Number height] -- L'altezza della mipmap più grande.
    + + [page:Constant format] -- Il formato utilizzato nelle mipmap. + Vedi [page:Textures ST3C Compressed Texture Formats], + [page:Textures PVRTC Compressed Texture Formats] e + [page:Textures ETC Compressed Texture Format] per altre scelte.
    + + [page:Constant type] -- Il valore predefinito è [page:Textures THREE.UnsignedByteType]. + Vedi [page:Textures type constants] per altre scelte.
    + + [page:Constant mapping] -- Come l'immagine viene applicata all'oggetto. Un tipo di oggetto di [page:Textures THREE.UVMapping]. + Vedi [page:Textures mapping constants] per altre scelte.
    + + [page:Constant wrapS] -- Il valore predefinito è [page:Textures THREE.ClampToEdgeWrapping]. + Vedi [page:Textures wrap mode constants] per altre scelte.
    + + [page:Constant wrapT] -- Il valore predefinito è [page:Textures THREE.ClampToEdgeWrapping]. + Vedi [page:Textures wrap mode constants] per altre scelte.
    + + [page:Constant magFilter] -- Come viene campionata la texture quando un texel copre più di un pixel. + Il valore predefinito è [page:Textures THREE.LinearFilter]. Vedi [page:Textures magnification filter constants] per altre scelte.
    + + [page:Constant minFilter] -- Come viene campionata la texture quando un texel copre meno di un pixel. + Il valore predefinito è [page:Textures THREE.LinearMipmapLinearFilter]. Vedi [page:Textures minification filter constants] per altre scelte.
    + + [page:Number anisotropy] -- Il numero di campioni prelevati lungo l'asse attravero il pixel che ha la densità di texel più alta. + Per impostazione predefinita, questo valore è 1. Un valore più alto fornisce un risultato meno sfuocato rispetto ad una mipmap di base, + a costo di utilizzare più campioni di texture. Usa [page:WebGLrenderer.getMaxAnisotropy renderer.getMaxAnisotropy]() + per trovare il valore di anisotropia massimo valido per la GPU; questo valore è solitamente una potenza di 2.

    +

    + + +

    Proprietà

    + +

    + Vedi la classe base [page:Texture Texture] per le proprietà comuni. +

    + +

    [property:Boolean flipY]

    + +

    + False per impostazione predefinita. Capovolgere le texture non funziona per le texture compresse. +

    + +

    [property:Boolean generateMipmaps]

    + +

    + False per impostazione predefinita. I mipmap non possono essere generati per le texture compresse. +

    + +

    [property:Boolean isCompressedTexture]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    Metodi

    + +

    + Vedi la classe base [page:Texture Texture] per i metodi comuni. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/textures/CubeTexture.html b/docs/api/it/textures/CubeTexture.html new file mode 100644 index 00000000000000..d5525d3ecb8870 --- /dev/null +++ b/docs/api/it/textures/CubeTexture.html @@ -0,0 +1,71 @@ + + + + + + + + + + [page:Texture] → + +

    [name]

    + +

    Crea una texture a cubo composta da sei immagini.

    + +

    Codice di Esempio

    + + + const loader = new THREE.CubeTextureLoader(); + loader.setPath( 'textures/cube/pisa/' ); + + const textureCube = loader.load( [ + 'px.png', 'nx.png', + 'py.png', 'ny.png', + 'pz.png', 'nz.png' + ] ); + + const material = new THREE.MeshBasicMaterial( { color: 0xffffff, envMap: textureCube } ); + + +

    Costruttore

    + + +

    [name]( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy )

    + +

    + CubeTexture è quasi equivalente in funzionalità ed utilizzo alla classe [page:Texture]. Le uniche differenze sono che le immagini + sono un array di 6 immagini anziché una singola immagine e le opzioni di mappatura sono + [page:Textures THREE.CubeReflectionMapping] (predefinita) o [page:Textures THREE.CubeRefractionMapping]. +

    + + +

    Proprietà

    + +

    + Vedi la classe base [page:Texture Texture] per le proprietà comuni. +

    + +

    [property:Boolean flipY]

    +

    + Se impostato a `true`, la texture viene capovolta lungo l'asse verticale quando viene caricata sulla GPU. L'impostazione predefinita è `false`. +

    + +

    [property:Boolean isCubeTexture]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    Metodi

    + +

    + Vedi la classe base [page:Texture Texture] per i metodi comuni. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/textures/Data3DTexture.html b/docs/api/it/textures/Data3DTexture.html new file mode 100644 index 00000000000000..67b3ba015cbefb --- /dev/null +++ b/docs/api/it/textures/Data3DTexture.html @@ -0,0 +1,61 @@ + + + + + + + + + + [page:Texture] → + +

    [name]

    + +

    Crea una texture tridimensionale. Questo tipo di texture può solo essere utilizzata in un contesto di rendering WebGL 2.

    + +

    Costruttore

    + +

    [name]( [param:TypedArray data], [param:Number width], [param:Number height], [param:Number depth] )

    +

    + [page:Object data] -- dati della texture.
    + + [page:Number width] -- larghezza della texture.
    + + [page:Number height] -- altezza della texture.
    + + [page:Number depth] -- profondità della texture. +

    + +

    Esempi

    + +

    + [example:webgl2_materials_texture3d WebGL2 / materials / texture3d] +

    + +

    Proprietà

    + +

    + Vedi la classe base [page:Texture Texture] per le proprietà comuni. +

    + +

    [property:number wrapR]

    +

    + Questa proprietà definisce come la texture viene wrappata nella direzione della profondità.
    + Il valore predefinito è [page:Textures THREE.ClampToEdgeWrapping], in cui il bordo è bloccato ai texel del bordo esterno. + Le altre due scelte sono [page:Textures THREE.RepeatWrapping] e [page:Textures THREE.MirroredRepeatWrapping]. + Vedi la pagina [page:Textures texture constants] per i dettagli. +

    + +

    Metodi

    + +

    + Vedi la classe base [page:Texture Texture] per i metodi comuni. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/textures/DataArrayTexture.html b/docs/api/it/textures/DataArrayTexture.html new file mode 100644 index 00000000000000..a54843676947ed --- /dev/null +++ b/docs/api/it/textures/DataArrayTexture.html @@ -0,0 +1,109 @@ + + + + + + + + + + [page:Texture] → + +

    [name]

    + +

    + Crea un array di texture direttamente da dati grezzi, dalla larghezza, dall'altezza e dalla profondità. + Questo tipo di texture può solo essere utilizzata in un contesto di rendering WebGL 2. +

    + +

    Costruttore

    + +

    [name]( data, width, height, depth )

    +

    + L'argomento data deve essere un [link:https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView ArrayBufferView]. + Le proprietà ereditate da [page:Texture] sono predefinite, eccetto magFilter e minFilter per impostazione predefinita THREE.NearestFilter. + Le proprietà flipY e generateMipmaps sono inizialmente impostate a false. +

    +

    + L'interpretazione dei dati dipende dal tipo e dal formato: + Se il tipo è THREE.UnsignedByteType, un Uint8Array sarà utile per indirizzare i dati texel. + Se il formato è THREE.RGBAFormat, i dati necessitano di quattro valori per un texel; Rosso, Verde, Blu e Alfa (tipicamente l'opacità).
    + + Per i tipi compressi, THREE.UnsignedShort4444Type e THREE.UnsignedShort5551Type tutti i componenti di colore di un texel possono essere + indirizzati come campi di bit all'interno di un elemento intero di un Uint16Array.
    + + Per utilizzare i tipi THREE.FloatType e THREE.HalfFloatType, l'implementazione WebGL deve supportare le + rispettive estensioni OES_texture_float e OES_texture_half_float. + Per utilizzare THREE.LinearFilter per l'interpolazione bilineare component-wise dei texel basati + su questi tipi, devono essere presenti anche le estensioni WebGL OES_texture_float_linear o OES_texture_half_float_linear. +

    + +

    Codice di Esempio

    + +

    Crea un [name] dove ogni texture ha un colore diverso.

    + + + // crea un buffer con i dati del colore + + const width = 512; + const height = 512; + const depth = 100; + + const size = width * height; + const data = new Uint8Array( 4 * size * depth ); + + for ( let i = 0; i < depth; i ++ ) { + + const color = new THREE.Color( Math.random(), Math.random(), Math.random() ); + const r = Math.floor( color.r * 255 ); + const g = Math.floor( color.g * 255 ); + const b = Math.floor( color.b * 255 ); + + for ( let j = 0; j < size; j ++ ) { + + const stride = ( i * size + j ) * 4; + + data[ stride ] = r; + data[ stride + 1 ] = g; + data[ stride + 2 ] = b; + data[ stride + 3 ] = 255; + + } + } + + // utilizza il buffer per creare un [name] + + const texture = new THREE.DataArrayTexture( data, width, height, depth ); + texture.needsUpdate = true; + + +

    Esempi

    + +

    + [example:webgl2_materials_texture2darray WebGL2 / materials / texture2darray] +

    + +

    Proprietà

    + +

    + Vedi la classe base [page:Texture Texture] per le proprietà comuni. +

    + +

    [property:Image image]

    +

    + Sostituito con un tipo di record contenente dati, larghezza, altezza e profondità. +

    + +

    Metodi

    + +

    + Vedi la classe base [page:Texture Texture] per i metodi comuni. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/textures/DataTexture.html b/docs/api/it/textures/DataTexture.html new file mode 100644 index 00000000000000..1daf374a4add6a --- /dev/null +++ b/docs/api/it/textures/DataTexture.html @@ -0,0 +1,117 @@ + + + + + + + + + + [page:Texture] → + +

    [name]

    + +

    Crea una texture direttamente da dati grezzi, larghezza e altezza.

    + +

    Costruttore

    + +

    [name]( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding )

    +

    + L'argomento data deve essere un [link:https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView ArrayBufferView]. + Ulteriori parametri corrispondono alle proprietà ereditate da [page:Texture], dove sia magFilter che minFilter per impostazione predefinita sono THREE.NearestFilter. +

    +

    + L'interpretazione dei dati dipende dal tipo e dal formato: + Se il tipo è THREE.UnsignedByteType, un Uint8Array sarà utile per indirizzare i dati texel. + Se il formato è THREE.RGBAFormat, i dati necessitano di quattro valori per un texel; Rosso, Verde, Blu e Alfa (tipicamente l'opacità).
    + + Per i tipi compressi, THREE.UnsignedShort4444Type e THREE.UnsignedShort5551Type tutti i componenti di colore di un texel possono essere + indirizzati come campi di bit all'interno di un elemento intero di un Uint16Array.
    + + Per utilizzare i tipi THREE.FloatType e THREE.HalfFloatType, l'implementazione WebGL deve supportare le + rispettive estensioni OES_texture_float e OES_texture_half_float. + Per utilizzare THREE.LinearFilter per l'interpolazione bilineare component-wise dei texel basati + su questi tipi, devono essere presenti anche le estensioni WebGL OES_texture_float_linear o OES_texture_half_float_linear. +

    + +

    Codice di Esempio

    + + + // crea un buffer con i dati del colore + + const width = 512; + const height = 512; + + const size = width * height; + const data = new Uint8Array( 4 * size ); + const color = new THREE.Color( 0xffffff ); + + const r = Math.floor( color.r * 255 ); + const g = Math.floor( color.g * 255 ); + const b = Math.floor( color.b * 255 ); + + for ( let i = 0; i < size; i ++ ) { + + const stride = i * 4; + + data[ stride ] = r; + data[ stride + 1 ] = g; + data[ stride + 2 ] = b; + data[ stride + 3 ] = 255; + + } + + // utilizza il buffer per creare un [name] + + const texture = new THREE.DataTexture( data, width, height ); + texture.needsUpdate = true; + + +

    Proprietà

    + +

    + Vedi la classe base [page:Texture Texture] per le proprietà comuni. +

    + +

    [property:Boolean flipY]

    +

    + Se impostato a `true`, la texture viene capovolta lungo l'asse verticale quando viene caricata sulla GPU. L'impostazione predefinita è `false`. +

    + +

    [property:Boolean generateMipmaps]

    +

    + Indica se generare mipmap (se possibile) per una texture. Falso per impostazione predefinita. +

    + +

    [property:Image image]

    +

    + Sostituito con un tipo di record contenente dati, larghezza, altezza e profondità. +

    + +

    [property:Boolean isDataTexture]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:number unpackAlignment]

    +

    + 1 per impostazione predefinita. Specifica i requisiti di allineamento per l'inizio di ogni riga di pixel in memoria. + I valori consentiti sono 1 (allineamento byte), 2 (righe allineate a byte pari), 4 (allineamento delle parole) e 8 + (le righe iniziano su limiti di parole doppie). + Vedi [link:http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml glPixelStorei] + per maggiori informazioni. +

    + +

    Metodi

    + +

    + Vedi la classe base [page:Texture Texture] per i metodi comuni. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/textures/DepthTexture.html b/docs/api/it/textures/DepthTexture.html new file mode 100644 index 00000000000000..7e463baaeb8127 --- /dev/null +++ b/docs/api/it/textures/DepthTexture.html @@ -0,0 +1,124 @@ + + + + + + + + + + [page:Texture] → + +

    [name]

    + +

    + Questa classe può essere utilizzata per salvare automaticamente le informazioni di profondità di un rendering in una texture. + Quando viene utilizzato un contesto di rendering WebGL 1, [name] richiede supporto per l'estensione + [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/ WEBGL_depth_texture]. +

    + +

    Esempi

    + +

    + [example:webgl_depth_texture depth / texture] +

    + +

    Costruttore

    +

    [name]( [param:Number width], [param:Number height], [param:Constant type], [param:Constant mapping], [param:Constant wrapS], [param:Constant wrapT], [param:Constant magFilter], [param:Constant minFilter], [param:Number anisotropy], [param:Constant format] )

    + +

    + [page:Number width] -- larghezza della texture.
    + + [page:Number height] -- altezza della texture.
    + + [page:Constant type] -- Il valore predefinito è [page:Textures THREE.UnsignedIntType] quando utilizzi [page:Textures DepthFormat] e + [page:Textures THREE.UnsignedInt248Type] quando utilizzi [page:Textures DepthStencilFormat]. + Vedi [page:Textures type constants] per altre scelte.
    + + [page:Constant mapping] -- + Vedi [page:Textures mapping mode constants] per i dettagli.
    + + [page:Constant wrapS] -- Il valore predefinito è [page:Textures THREE.ClampToEdgeWrapping]. + Vedi [page:Textures wrap mode constants] per altre scelte.
    + + [page:Constant wrapT] -- Il valore predefinito è [page:Textures THREE.ClampToEdgeWrapping]. + Vedi [page:Textures wrap mode constants] per altre scelte.
    + + [page:Constant magFilter] -- Come viene campionata la texture quando un texel copre più di un pixel. + Il valore predefinito è [page:Textures THREE.NearestFilter]. Vedi [page:Textures magnification filter constants] per altre scelte.
    + + [page:Constant minFilter] -- Come viene campionata la texture quando un texel copre meno di un pixel. + Il valore predefinito è [page:Textures THREE.NearestFilter]. Vedi [page:Textures minification filter constants] per altre scelte.
    + + [page:Number anisotropy] -- Il numero di campioni prelevati lungo l'asse attravero il pixel che ha la densità di texel più alta. + Per impostazione predefinita, questo valore è 1. Un valore più alto fornisce un risultato meno sfuocato rispetto ad una mipmap di base, + a costo di utilizzare più campioni di texture. Usa [page:WebGLrenderer.getMaxAnisotropy renderer.getMaxAnisotropy]() + per trovare il valore di anisotropia massimo valido per la GPU; questo valore è solitamente una potenza di 2.
    + + [page:Constant format] -- deve essere [page:Textures DepthFormat] (predefinito) o [page:Textures DepthStencilFormat]. + Vedi [page:Textures format constants] per i dettagli.
    +

    + + +

    Proprietà

    + +

    + Vedi la classe base [page:Texture Texture] per le proprietà comuni. + - anche le seguenti proprietà fanno parte della classe texture, ma qui hanno impostazioni predefinite diverse. +

    + +

    [page:Texture.format format]

    +

    + [page:Textures DepthFormat] (predefinito) o [page:Textures DepthStencilFormat]. + Vedi [page:Textures format constants] per i dettagli.
    +

    + +

    [page:Texture.type type]

    +

    + Il valore predefinito è [page:Textures THREE.UnsignedIntType] quando utilizzi [page:Textures DepthFormat] e + [page:Textures THREE.UnsignedInt248Type] quando utilizzi [page:Textures DepthStencilFormat]. + Vedi [page:Textures format constants] per i dettagli.
    +

    + +

    [page:Texture.magFilter magFilter]

    +

    + Come viene campionata la texture quando un texel copre più di un pixel. + Il valore predefinito è [page:Textures THREE.NearestFilter]. + Vedi le [page:Textures costanti del filtro di ingrandimento] per altre scelte. +

    + +

    [page:Texture.minFilter minFilter]

    +

    + Come viene campionata la texture quando un texel copre meno di un pixel. + Il valore predefinito è [page:Textures THREE.NearestFilter]. + Vedi le [page:Textures costanti del filtro di ingrandimento] per altre scelte. +

    + +

    [page:Texture.flipY flipY]

    +

    + Le texture di profondità non hanno bisogno di essere capovolte, quindi questo è `false` per impostazione predefinita. +

    + +

    [page:Texture.generateMipmaps .generateMipmaps]

    +

    + Le texture di profondità non usano i mipmap. +

    + +

    [property:Boolean isDepthTexture]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    Metodi

    + +

    + Vedi la classe base [page:Texture Texture] per i metodi comuni. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/textures/FramebufferTexture.html b/docs/api/it/textures/FramebufferTexture.html new file mode 100644 index 00000000000000..e770af62384d7c --- /dev/null +++ b/docs/api/it/textures/FramebufferTexture.html @@ -0,0 +1,60 @@ + + + + + + + + + + [page:Texture] → + +

    [name]

    + +

    + Questa classe può solo essere utilizzata in combinazione con [page:WebGLRenderer.copyFramebufferToTexture](). +

    + +

    Costruttore

    +

    [name]( [param:Number width], [param:Number height], [param:Constant format] )

    +

    + [page:Number width] -- La larghezza della texture.
    + + [page:Number height] -- L'altezza della texture.
    + + [page:Constant format] -- Il formato utilizzato nella texture. + Vedi [page:Textures format constants] per altre scelte.
    +

    + + +

    Proprietà

    + +

    + Vedi la classe base [page:Texture Texture] per le proprietà comuni. +

    + +

    [property:Boolean isFramebufferTexture]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:Boolean needsUpdate]

    + +

    + True da impostazione predefinita. Ciò è necessario affinché i dati del canvas vengano caricati. +

    + +

    Metodi

    + +

    + Vedi la classe base [page:Texture Texture] per i metodi comuni. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/textures/Source.html b/docs/api/it/textures/Source.html new file mode 100644 index 00000000000000..ed9193d2e92700 --- /dev/null +++ b/docs/api/it/textures/Source.html @@ -0,0 +1,60 @@ + + + + + + + + + +

    [name]

    + +

    + Rappresenta l'origine dati di una texture. +

    + +

    Costruttore

    + +

    [name]( [param:Any data] )

    +

    + [page:Any data] -- La definizione dei dati della texture. Il valore predefinito è `null`. +

    + +

    Proprietà

    + +

    [property:Any data]

    +

    + I dati effettivi di una texture. Il tipo di questa proprietà dipende dalla texture che utilizza questa istanza. +

    + +

    [property:Boolean needsUpdate]

    +

    + Impostalo a `true` per attivare un caricamento di dati sulla GPU la prossima volta che viene utilizzata la sorgente. +

    + +

    [property:String uuid]

    +

    + [link:http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] di questa istanza dell'oggetto. + Questo viene assegnato automaticamente, quindi non deve essere modificato. +

    + +

    [property:Integer version]

    +

    + Questo inizia a `0` e conta quante volte [page:Source.needsUpdate .needsUpdate] viene impostato a `true`. +

    + +

    Metodi

    + +

    [method:Object toJSON]( [param:Object meta] )

    +

    + meta -- oggetto opzionale contenente i metadati.
    + Converte l'origine dati nel [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 formato JSON Oggetto/Scena] di three.js. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/textures/Texture.html b/docs/api/it/textures/Texture.html new file mode 100644 index 00000000000000..4a47dcd14857b8 --- /dev/null +++ b/docs/api/it/textures/Texture.html @@ -0,0 +1,330 @@ + + + + + + + + + +

    [name]

    + +

    + Crea una texture da applicare ad una superficie o come mappa di riflessione o rifrazione. +

    + +

    + Nota: Dopo l'utilizzo iniziale di una texture, le sue dimensioni, formato, e il tipo non possono essere cambiati. + Invece, chiama [page:.dispose]() sulla texture e creane una nuova. +

    + +

    Codice di Esempio

    + + + // carica una texture, imposta la modalità wrap per ripetere + const texture = new THREE.TextureLoader().load( "textures/water.jpg" ); + texture.wrapS = THREE.RepeatWrapping; + texture.wrapT = THREE.RepeatWrapping; + texture.repeat.set( 4, 4 ); + + +

    Costruttore

    + +

    [name]( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding )

    + +

    Proprietà

    + +

    [property:Integer id]

    +

    + Sola lettura - numero univoco per questa istanza della texture. +

    + +

    [property:Boolean isTexture]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:String uuid]

    +

    + [link:http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] di questa istanza dell'oggetto. + Questo viene assegnato automaticamente, quindi non deve essere modificato. +

    + +

    [property:String name]

    +

    + Nome opzionale dell'oggetto (non è necessario che sia univoco). Il valore predefinito é una stringa vuota. +

    + +

    [property:Image image]

    +

    + Un oggetto immagine, tipicamente creato utilizzando il metodo [page:TextureLoader.load]. + Questo può essere qualsiasi tipo di immagine (e.g., PNG, JPG, GIF, DDS) o video (e.g., MP4, OGG/OGV) supportato da three.js.

    + + Per utilizzare il video come texture è necessario disporre di un elemento video HTML5 + in riproduzione come sorgente per l'immagine della texture e aggiornare + continuamente questa texture finchè il video è in riproduzione - + la classe [page:VideoTexture VideoTexture] gestisce questa operazione automaticamente. +

    + +

    [property:Array mipmaps]

    +

    + Array di mipmap specificate dall'utente (opzionale). +

    + +

    [property:number mapping]

    +

    + Come l'immagine viene applicata all'oggetto. Un tipo di oggetto di [page:Textures THREE.UVMapping] è l'impostazione predefinita, + dove le coordinate U,V vengono utilizzate per applicare la mappa.
    + + Vedi la pagina [page:Textures texture constants] per altri tipi di mapping. +

    + +

    [property:number wrapS]

    +

    + Questo definisce come la texture è wrappata orizzontalmente e corrisponde a *U* nel mapping UV.
    + L'impostazione predefinita è [page:Textures THREE.ClampToEdgeWrapping], dove il bordo è fissato ai texel del bordo esterno. + Le altre due scelte sono [page:Textures THREE.RepeatWrapping] e [page:Textures THREE.MirroredRepeatWrapping]. + Vedi la pagina [page:Textures texture constants] per i dettagli. +

    + +

    [property:number wrapT]

    +

    + Questo definisce come la texture è wrappata verticalmente e corrisponde a *V* nel mapping UV.
    + Sono disponibili le stesse scelte di [property:number wrapS].

    + + NOTA: la piastrellatura delle immagini nelle texture funziona solo se le dimensioni dell'immagine sono potenze di due + (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, ...) in termini di pixel. + Le dimensioni individuali non devono essere necessariamente uguali, ma ciascuna deve essere una potenza di due. + Questa è una limitazione di WebGL, non di three.js. +

    + +

    [property:number magFilter]

    +

    + Come viene campionata la texture quando un texel copre più di un pixel. Il valore predefinito è + [page:Textures THREE.LinearFilter], che prende i quattro texel più vicini e li interpola bilinearmente. + L'altra opzione è [page:Textures THREE.NearestFilter], che utilizza il valore del texel più vicino.
    + Vedi la pagina [page:Textures texture constants] per i dettagli. +

    + +

    [property:number minFilter]

    +

    + Come viene campionata la texture quando un texel copre meno di un pixel. Il valore predefinito è + [page:Textures THREE.LinearMipmapLinearFilter], che utilizza il mipmapping e un filtro trilineare.

    + + Vedi la pagina [page:Textures texture constants] per tutte le scelte possibili. +

    + +

    [property:number anisotropy]

    +

    + Il numero di campioni prelevati lungo l'asse attravero il pixel che ha la densità di texel più alta. + Per impostazione predefinita, questo valore è 1. Un valore più alto fornisce un risultato meno sfuocato rispetto ad una mipmap di base, + a costo di utilizzare più campioni di texture. Usa [page:WebGLRenderer.capabilities renderer.capabilities.getMaxAnisotropy]() + per trovare il valore di anisotropia massimo valido per la GPU; questo valore è solitamente una potenza di 2. +

    + +

    [property:number format]

    +

    + Il valore predefinito è [page:Textures THREE.RGBAFormat].

    + + Vedi la pagina [page:Textures texture constants] per i dettagli di altri formati. +

    + +

    [property:String internalFormat]

    +

    + Il valore predefinito è ottenuto utilizzando una combinazione di [page:Texture.format .format] e + [page:Texture.type .type].
    + + Il formato GPU permette allo sviluppatore di specificare come i dati verranno memorizzati nella GPU.

    + + Vedi la pagina [page:Textures texture constants] per i dettagli relativi a tutti i formati interni supportati. +

    + +

    [property:number type]

    +

    + Questo deve corrispondere al [page:Texture.format .format]. Il valore predefinito è [page:Textures THREE.UnsignedByteType], + il quale sarà utilizzato per la maggior parte dei formati della texture.

    + + Vedi la pagina [page:Textures texture constants] per i dettagli sugli altri formati. +

    + +

    [property:Vector2 offset]

    +

    + Di quanto una singola ripetizione della texture è sfalsata dall'inizio, in ciascuna direzione U e V. + L'intervallo tipico è compreso tra `0.0` e `1.0`. +

    +

    + I tipi di texture seguenti condividono il `primo` canale uv nel motore. L'impostazione dell'offset (e della ripetizione) viene valutata + in base alle seguenti priorità e quindi condivisa da tali texture: +

      +
    1. color map
    2. +
    3. specular map
    4. +
    5. displacement map
    6. +
    7. normal map
    8. +
    9. bump map
    10. +
    11. roughness map
    12. +
    13. metalness map
    14. +
    15. alpha map
    16. +
    17. emissive map
    18. +
    19. clearcoat map
    20. +
    21. clearcoat normal map
    22. +
    23. clearcoat roughnessMap map
    24. +
    +

    +

    + I tipi di texture seguenti condividono il `secondo` canale uv nel motore. L'impostazione dell'offset (e della ripetizione) viene valutata + in base alle seguenti priorità e quindi condivisa da tali texture: +

      +
    1. ao map
    2. +
    3. light map
    4. +
    +

    + +

    [property:Vector2 repeat]

    +

    + Quante volte la texture è ripetuta sulla superficie, in ogni direzione U e V. Se la proprietà ripeat è + impostata su un valore maggiore di 1 in entrambe le direzioni, anche il parametro Wrap corrispondente + deve essere impostato su [page:Textures THREE.RepeatWrapping] o [page:Textures THREE.MirroredRepeatWrapping] per ottenere l'effetto + di piastrellatura desiderato. + L'impostazione di diversi valori di ripetizione per le texture è limitata allo stesso modo di [page:.offset]. +

    + +

    [property:number rotation]

    +

    + Di quanto la texture viene ruotata attorno al punto centrale, in radianti. I valori positivi sono in senso antiorario. + Il valore predefinito è `0`. +

    + +

    [property:Vector2 center]

    +

    + Il punto attorno al quale avviene la rotazione. Un valore (0.5, 0.5) che corrisponde al centro della texture. Il + valore predefinito è (0, 0), in basso a sinistra. +

    + +

    [property:Boolean matrixAutoUpdate]

    +

    + Indica se aggiornare la [page:Texture.matrix .matrix] uv-transform della texture dalle proprietà della texture + [page:Texture.offset .offset], [page:Texture.repeat .repeat], [page:Texture.rotation .rotation], e [page:Texture.center .center]. + Il valore predefinito è `true`. + Impostalo a `false` se stai specificando la matrice uv-transform direttamente. +

    + +

    [property:Matrix3 matrix]

    +

    + La matrice uv-transform della texture. Aggiornata dal renderer delle proprietà della texture [page:Texture.offset .offset], [page:Texture.repeat .repeat], + [page:Texture.rotation .rotation], e [page:Texture.center .center] quando la proprietà [page:Texture.matrixAutoUpdate .matrixAutoUpdate] della texture è `true`. + Quando la proprietà [page:Texture.matrixAutoUpdate .matrixAutoUpdate] è `false`, questa matrice deve essere impostata manualmente. + Il valore predefinito è la matrice identità +

    + +

    [property:Boolean generateMipmaps]

    +

    + Indica se generare mipmap (se possibile) per una texure. Il valore predefinito è `true`. + Impostalo a false se stai creando il mipmap manualmente. +

    + +

    [property:Boolean premultiplyAlpha]

    +

    + Se impostato a `true`, il canale alfa, se presente, viene moltiplicato nei canali del colore + quando la texture viene caricata sulla GPU. Il valore predefinito è `false`.

    + + Si noti che questa proprietà non ha effetto per [link:https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap ImageBitmap]. + È invece necessario configurare sulla creazione di bitmap. Vedi [page:ImageBitmapLoader]. +

    + +

    [property:Boolean flipY]

    +

    + Se impostato a `true`, la texture viene capovolta lungo l'asse verticale quando caricata sulla GPU. Il valore predefinito è `true`.

    + + Si noti che questa proprietà non ha effetto per [link:https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap ImageBitmap]. + È invece necessario configurare sulla creazione di bitmap. Vedi [page:ImageBitmapLoader]. +

    + +

    [property:number unpackAlignment]

    +

    + Il valore predefinito è 4. Specifica i requisiti di allineamento per l'inizio di ogni riga di pixel in memoria. + I valori consentiti sono 1 (allineamento di byte), 2 (righe allineate a byte pari), 4 (allineamento di parole) + e 8 (le righe iniziano su limiti di doppia parola). + Vedi [link:http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml glPixelStorei] per maggiori informazioni. +

    + +

    [property:number encoding]

    +

    + [page:Textures THREE.LinearEncoding] è l'impostazione predefinita. + Vedi la pagina [page:Textures texture constants] per i dettagli su altri formati.

    + + Si noti che questo valore viene modificato su una texture dopo che il materiale è stato utilizzato, + è necessario attivare un Material.needsUpdate affinché questo valore venga realizzato nello shader. +

    + +

    [property:Integer version]

    +

    + Questo inizia a `0` e conta quante volte [page:Texture.needsUpdate .needsUpdate] viene impostato a `true`. +

    + +

    [property:Function onUpdate]

    +

    + Una funzione di callback, chiamata quando la texture viene aggiornata (per esempio, quando needsUpdate è stato impostato + a true e quindi viene utilizzata la texture). +

    + +

    [property:Boolean needsUpdate]

    +

    + Imposta questo a `true` per attivare un aggiornamento la prossima volta che viene utilizzata la texture. + Particolarmente importante per impostare la modalità di wrapping. +

    + +

    [property:Object userData]

    +

    + Un oggetto che può essere utilizzato per memorizzare dati personalizzati della texture. + Non deve contenere riferimenti a funzioni poiché queste non verranno clonate. +

    + +

    [property:Source source]

    +

    + La definizione dei dati di una texture. Un riferimento alla sorgente dati può essere condiviso tra le texture. + Questo è spesso utile nel contesto di spritesheets in cui più texture rendono gli stessi dati ma con diverse trasformazioni di texture. +

    + +

    Metodi

    + +

    I metodi [page:EventDispatcher EventDispatcher] sono disponibili su questa classe.

    + +

    [method:undefined updateMatrix]()

    +

    + Aggiorna la [page:Texture.matrix .matrix] uv-transform della texture dalle proprietà della texture + [page:Texture.offset .offset], [page:Texture.repeat .repeat], [page:Texture.rotation .rotation], e [page:Texture.center .center]. +

    + +

    [method:Texture clone]()

    +

    + Crea una copia della texture. Si noti che non è una "copia profonda", l'immagine è condivisa. + Inoltre, la clonazione della texture non la contrassegna automaticamente per il caricamento di una texture. + Devi impostare [page:Texture.needsUpdate .needsUpdate] a true non appena la sua proprietà dell'immagine + (l'origine dati) è completamente caricata o pronta. +

    + +

    [method:Object toJSON]( [param:Object meta] )

    +

    + meta -- oggetto opzionale contenente i metadati.
    + Converte l'origine dati nel [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 formato JSON Oggetto/Scena] di three.js. +

    + +

    [method:undefined dispose]()

    +

    + Libera le risorse relative alla GPU allocate da questa istanza. + Chiama questo metodo ogni volta che questa istanza non viene più utilizzata dall'applicazione. +

    + +

    [method:Vector2 transformUv]( [param:Vector2 uv] )

    +

    + Trasforma l'uv in base al valore delle proprietà [page:Texture.offset .offset], [page:Texture.repeat .repeat], + [page:Texture.wrapS .wrapS], [page:Texture.wrapT .wrapT] e [page:Texture.flipY .flipY]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/it/textures/VideoTexture.html b/docs/api/it/textures/VideoTexture.html new file mode 100644 index 00000000000000..d9aa769e47bb68 --- /dev/null +++ b/docs/api/it/textures/VideoTexture.html @@ -0,0 +1,113 @@ + + + + + + + + + + [page:Texture] → + +

    [name]

    + +

    + Crea una texture da utilizzare con un video. +

    + +

    + Nota: Dopo l'utilizzo iniziale di una texture, il video non può essere cambiato. Invece, chiama [page:.dispose]() sulla texture e creane una nuova. +

    + +

    Codice di Esempio

    + + + // supponendo che tu abbia creato un elemento video HTML con id="video" + const video = document.getElementById( 'video' ); + const texture = new THREE.VideoTexture( video ); + + +

    Esempi

    + +

    + [example:webgl_materials_video materials / video]
    + [example:webgl_materials_video_webcam materials / video / webcam]
    + [example:webgl_video_kinect video / kinect]
    + [example:webgl_video_panorama_equirectangular video / panorama / equirectangular]
    + [example:webxr_vr_video vr / video] +

    + +

    Constructor

    +

    [name]( [param:Video video], [param:Constant mapping], [param:Constant wrapS], [param:Constant wrapT], [param:Constant magFilter], [param:Constant minFilter], [param:Constant format], [param:Constant type], [param:Number anisotropy] )

    +

    + [page:Video video] -- L'elemento video da utilizzare come texture.
    + + [page:Constant mapping] -- Come l'immagine viene applicata all'oggetto. Un tipo di oggetto di [page:Textures THREE.UVMapping]. + Vedi [page:Textures mapping constants] per altre scelte.
    + + [page:Constant wrapS] -- Il valore predefinito è [page:Textures THREE.ClampToEdgeWrapping]. + Vedi [page:Textures wrap mode constants] per altre scelte.
    + + [page:Constant wrapT] -- Il valore predefinito è [page:Textures THREE.ClampToEdgeWrapping]. + Vedi [page:Textures wrap mode constants] per altre scelte.
    + + [page:Constant magFilter] -- Come viene campionata la texture quando un texel copre più di un pixel. + Il valore predefinito è [page:Textures THREE.LinearFilter]. Vedi [page:Textures magnification filter constants] per altre scelte.
    + + [page:Constant minFilter] -- Come viene campionata la texture quando un texel copre meno di un pixel. + Il valore predefinito è [page:Textures THREE.LinearFilter]. Vedi [page:Textures minification filter constants] per altre scelte.
    + + [page:Constant format] -- Il valore predefinito è [page:Textures THREE.RGBAFormat]. + Vedi [page:Textures format constants] per altre scelte.
    + + [page:Constant type] -- Il valore predefinito è [page:Textures THREE.UnsignedByteType]. + Vedi [page:Textures type constants] per altre scelte.
    + + [page:Number anisotropy] -- Il numero di campioni prelevati lungo l'asse attravero il pixel che ha la densità di texel più alta. + Per impostazione predefinita, questo valore è 1. Un valore più alto fornisce un risultato meno sfuocato rispetto ad una mipmap di base, + a costo di utilizzare più campioni di texture. Usa [page:WebGLrenderer.getMaxAnisotropy renderer.getMaxAnisotropy]() + per trovare il valore di anisotropia massimo valido per la GPU; questo valore è solitamente una potenza di 2.

    +

    + + +

    Proprietà

    + +

    + Vedi la classe base [page:Texture Texture] per le proprietà comuni. +

    + +

    [property:Boolean generateMipmaps]

    +

    + Indica se generare mipmap. Il valore predefinito è `false`. +

    + +

    [property:Boolean isVideoTexture]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [property:Boolean needsUpdate]

    +

    + Non avrai bisogno di impostarlo manualmente qui poiché è gestito dal metodo [page:VideoTexture.update update](). +

    + +

    Metodi

    + +

    + Vedi la classe base [page:Texture Texture] per i metodi comuni. +

    + +

    [method:undefined update]()

    +

    + Questo viene chiamato automaticamente e imposta [page:VideoTexture.needsUpdate .needsUpdate] a `true` ogni + volta che un nuovo frame è disponibile. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/ko/constants/Materials.html b/docs/api/ko/constants/Materials.html index 6960d5c034d682..fe61fd230d9a74 100644 --- a/docs/api/ko/constants/Materials.html +++ b/docs/api/ko/constants/Materials.html @@ -128,6 +128,12 @@

    스텐실 연산

    [page:Materials InvertStencilOp]는 현재 스텐실 값의 비트값 반전을 수행합니다.

    +

    GLSL Version

    + + THREE.GLSL1 + THREE.GLSL3 + +

    소스 코드

    diff --git a/docs/api/ko/core/BufferAttribute.html b/docs/api/ko/core/BufferAttribute.html index 65abdcc1b017bd..060a119ad1f678 100644 --- a/docs/api/ko/core/BufferAttribute.html +++ b/docs/api/ko/core/BufferAttribute.html @@ -139,18 +139,6 @@

    [method:this copyArray]( array )

    [method:this copyAt] ( [param:Integer index1], [param:BufferAttribute bufferAttribute], [param:Integer index2] )

    bufferAttribute[index2]의 벡터를 [page:BufferAttribute.array array][index1]에 복사합니다.

    -

    [method:this copyColorsArray]( [param:Array colors] )

    -

    RGB 색상 값을 나타내는 배열을 [page:BufferAttribute.array array]에 복사합니다.

    - -

    [method:this copyVector2sArray]( [param:Array vectors] )

    -

    [page:Vector2]값을 나타내는 배열을 [page:BufferAttribute.array array]에 복사합니다.

    - -

    [method:this copyVector3sArray]( [param:Array vectors] )

    -

    [page:Vector3]값을 나타내는 배열을 [page:BufferAttribute.array array]에 복사합니다.

    - -

    [method:this copyVector4sArray]( [param:Array vectors] )

    -

    [page:Vector4]값을 나타내는 배열을 [page:BufferAttribute.array array]에 복사합니다.

    -

    [method:Number getX]( [param:Integer index] )

    해당 index의 벡터의 x 컴포넌트 값을 리턴합니다.

    diff --git a/docs/api/ko/core/BufferGeometry.html b/docs/api/ko/core/BufferGeometry.html index db95e33e466fb2..89ca5fdb7eb163 100644 --- a/docs/api/ko/core/BufferGeometry.html +++ b/docs/api/ko/core/BufferGeometry.html @@ -239,9 +239,6 @@

    [method:this lookAt] ( [param:Vector3 vector] )

    일반적인 리얼타임 메쉬 사용은 [page:Object3D.lookAt] 을 사용하세요.

    -

    [method:this merge]( [param:BufferGeometry bufferGeometry], [param:Integer offset] )

    -

    병합을 시작할 지점인 임의의 오프셋으로 다른 BufferGeometry에 병합합니다.

    -

    [method:undefined normalizeNormals]()

    기하학의 모든 법선 벡터는 1의 크기를 갖습니다. diff --git a/docs/api/ko/core/Object3D.html b/docs/api/ko/core/Object3D.html index eac76952508da2..995de164816a4e 100644 --- a/docs/api/ko/core/Object3D.html +++ b/docs/api/ko/core/Object3D.html @@ -83,6 +83,12 @@

    [property:Matrix4 matrixWorld]

    객체의 글로벌 변형입니다. Object3D가 부모를 가지고 있지 않다면, 로컬 변형 [page:.matrix]와 동일합니다.

    +

    [property:Boolean matrixWorldAutoUpdate]

    +

    + Default is true. If set, then the renderer checks every frame if the object and its children need matrix updates. + When it isn't, then you have to maintain all matrices in the object and its children yourself. +

    +

    [property:Boolean matrixWorldNeedsUpdate]

    이 값을 설정하면 When this is set, it calculates the 해당 프레임의 matrixWorld를 계산하고 이 프로퍼티를 false로 초기화합니다. @@ -307,7 +313,7 @@

    [method:undefined lookAt]( [param:Vector3 vector] )
    이 메서드는 비균일 스케일 부모를 가진 객체들은 지원하지 않습니다.

    -

    [method:Array raycast]( [param:Raycaster raycaster], [param:Array intersects] )

    +

    [method:undefined raycast]( [param:Raycaster raycaster], [param:Array intersects] )

    객체와 레이캐스팅 사이의 인터섹션을 구하는 추상 (빈) 메서드입니다. Subclasses such as [page:Mesh], [page:Line], 및 [page:Points] 같은 서브클래스들은 레이캐스팅을 사용하는 순서에 따라 이 메서드를 실행합니다. diff --git a/docs/api/ko/extras/core/ShapePath.html b/docs/api/ko/extras/core/ShapePath.html index bda85c65d6b85e..51c5ac9a8e6638 100644 --- a/docs/api/ko/extras/core/ShapePath.html +++ b/docs/api/ko/extras/core/ShapePath.html @@ -64,15 +64,13 @@

    [method:this splineThru] ( [param:Array points] )

    [page:ShapePath.currentPath currentPath] 위에 새 [page:SplineCurve]를 연결합니다.

    -

    [method:Array toShapes]( [param:Boolean isCCW], [param:Boolean noHoles] )

    +

    [method:Array toShapes]( [param:Boolean isCCW] )

    - isCCW -- solids와 holes가 생성되는 방식을 변경합니다
    - noHoles -- holes를 생성할지 안 할지를 설정합니다. + isCCW -- solids와 holes가 생성되는 방식을 변경합니다

    [page:ShapePath.subPaths subPaths] 배열을 Shapes 배열로 변환합니다. 기본값으로 solid shapes는 시계방향(CW)이고 holes는 반시계방향(CCW)입니다. isCCW가 true면, 이 값들이 반대가 됩니다. - noHoles 파라미터가 true면 모든 path들은 solid shapes로 설정되고 isCCW는 무시됩니다.

    diff --git a/docs/api/pt-br/animation/AnimationAction.html b/docs/api/pt-br/animation/AnimationAction.html new file mode 100644 index 00000000000000..5bb556606f1f8b --- /dev/null +++ b/docs/api/pt-br/animation/AnimationAction.html @@ -0,0 +1,359 @@ + + + + + + + + + +

    [name]

    + +

    + AnimationAction programa o desempenho das animações que são armazenadas em + [page:AnimationClip AnimationClips].

    + + Nota: A maioria dos métodos da AnimationAction podem ser encadeados.

    + + Para obter uma visão geral dos diferentes elementos do sistema de animação three.js, consulte o + artigo "Sistema de animação" na seção "Próximos Passos" do manual. +

    + + +

    Construtor

    + +

    [name]( [param:AnimationMixer mixer], [param:AnimationClip clip], [param:Object3D localRoot] )

    +

    + [page:AnimationMixer mixer] - o `AnimationMixer` que é controlado por esta ação.
    + [page:AnimationClip clip] - o `AnimationClip` que contém os dados da animação para esta ação.
    + [page:Object3D localRoot] - o objeto raiz no qual esta ação é executada.

    + + Nota: Ao invés de chamar este construtor diretamente, você deve instanciar um AnimationAction com + [page:AnimationMixer.clipAction] uma vez que este método fornece cache para melhor desempenho. +

    + + +

    Propriedades

    + +

    [property:Boolean clampWhenFinished]

    +

    + Se `clampWhenFinished` estiver definido como true a animação será automaticamente [page:.paused pausada] + em seu último quadro.

    + + Se `clampWhenFinished` estiver definido como false, [page:.enabled enabled] será trocado automaticamente + para false quando o último loop da ação terminar, para que esta ação não tenha mais impacto.

    + + O padrão é falso.

    + + Nota: `clampWhenFinished` não tem impacto se a ação for interrompida (só tem efeito se + seu último loop realmente terminou). +

    + +

    [property:Boolean enabled]

    +

    + Definir `enabled` como `false` desativa esta ação, para que não tenha efeito. O padrão é `true`.

    + + Quando a ação é reativada, a animação continua de seu [page:.time time] (tempo) + (configurar `enabled` para `false` não redefine a ação).

    + + Nota: Definir `enabled` como `true` não reinicia automaticamente a animação. Configurar `enabled` + para `true` só reiniciará a animação imediatamente se a seguinte condição for atendida: + [page:.paused paused] é `false`, esta ação não foi desativada nesse meio tempo + (executando um comando [page:.stop stop] ou [page:.reset reset]), e nem [page:.weight weight] + nem [page:.timeScale timeScale] são `0`. +

    + +

    [property:Number loop]

    +

    + O modo de looping (pode ser alterado com [page:.setLoop setLoop]). O padrão é + [page:Animation THREE.LoopRepeat] (com um número infinito de [page:.repetitions repetitions] (repetições)).

    + + Deve ser uma destas constantes:

    + [page:Animation THREE.LoopOnce] - reproduzindo o clipe uma vez,
    + [page:Animation THREE.LoopRepeat] - reproduzindo o clipe com o número escolhido de `repetições`, + cada vez pulando do final do clipe diretamente para o início,
    + [page:Animation THREE.LoopPingPong] - reproduzindo o clipe com o número escolhido de `repetições`, + tocando alternadamente para frente e para trás. +

    + +

    [property:Boolean paused]

    +

    + Definir `paused` como `true` pausa a execução da ação definindo a escala de tempo efetiva + para '0'. O padrão é `false`.

    +

    + +

    [property:Number repetitions]

    +

    + O número de repetições do [page:AnimationClip] ao longo desta ação. + Pode ser definido através de [page:.setLoop setLoop]. O padrão é `Infinity`.

    + Definir este número não tem efeito se o [page:.loop modo de loop] está configurado como + [page:Animation THREE.LoopOnce]. +

    + +

    [property:Number time]

    +

    + O tempo local desta ação (em segundos, começando com `0`).

    + + O valor é fixado ou encapsulado em `0...clip.duration` (de acordo com o estado do loop). Pode ser + dimensionado em relação ao tempo do mixer global, alterando [page:.timeScale timeScale] (usando + [page:.setEffectiveTimeScale setEffectiveTimeScale] ou [page:.setDuration setDuration]).
    +

    + +

    [property:Number timeScale]

    +

    + Fator de escala para o [page:.time tempo]. Um valor de `0` faz com que a animação seja pausada. Valores + negativos fazem com que a animação seja reproduzida para trás. O padrão é `1`.

    + Propriedades/métodos referentes a `timeScale` (respectivamente `time`) são: + [page:.getEffectiveTimeScale getEffectiveTimeScale], + [page:.halt halt], + [page:.paused paused], + [page:.setDuration setDuration], + [page:.setEffectiveTimeScale setEffectiveTimeScale], + [page:.stopWarping stopWarping], + [page:.syncWith syncWith], + [page:.warp warp]. +

    + +

    [property:Number weight]

    +

    + O grau de influência desta ação (no intervalo `[0, 1]`). Valores entre '0' (sem impacto) + e 1 (impacto total) podem ser usados para mesclar várias ações. O padrão é `1`.

    + Propriedades/métodos relativos a `weight` são: + [page:.crossFadeFrom crossFadeFrom], + [page:.crossFadeTo crossFadeTo], + [page:.enabled enabled], + [page:.fadeIn fadeIn], + [page:.fadeOut fadeOut], + [page:.getEffectiveWeight getEffectiveWeight], + [page:.setEffectiveWeight setEffectiveWeight], + [page:.stopFading stopFading]. +

    + +

    [property:Boolean zeroSlopeAtEnd]

    +

    + Ativa interpolação suave sem separar clipes por início, loop e fim. O padrão é `true`. +

    + +

    [property:Boolean zeroSlopeAtStart]

    +

    + Ativa interpolação suave sem separar clipes por início, loop e fim. O padrão é `true`. +

    + + +

    Métodos

    + + +

    [method:this crossFadeFrom]( [param:AnimationAction fadeOutAction], [param:Number durationInSeconds], [param:Boolean warpBoolean] )

    +

    + Faz com que a ação [page:.fadeIn fade in] esmaeça outra ação simultaneamente, dentro do + intervalo de tempo passado. Este método pode ser encadeado.

    + + Se warpBoolean for true, [page:.warp warping] (mudanças graduais das escalas de tempo) adicional + será aplicado.

    + + Nota: Como em `fadeIn`/`fadeOut`, o desvanecimento começa/termina com um peso de 1. +

    + +

    [method:this crossFadeTo]( [param:AnimationAction fadeInAction], [param:Number durationInSeconds], [param:Boolean warpBoolean] )

    +

    + Faz com que a ação [page:.fadeOut fade out] esmaeça em outra ação simultaneamente, dentro do + intervalo de tempo passado. Este método pode ser encadeado.

    + Se warpBoolean for true, [page:.warp warping] (mudanças graduais das escalas de tempo) adicional + será aplicado.

    + + Nota: Como com `fadeIn`/`fadeOut`, o desvanecimento começa/termina com um peso de 1. +

    + +

    [method:this fadeIn]( [param:Number durationInSeconds] )

    +

    + Aumenta o [page:.weight weight] desta ação gradualmente de `0` para `1`, dentro do intervalo de + tempo decorrido. Este método pode ser encadeado. +

    + +

    [method:this fadeOut]( [param:Number durationInSeconds] )

    +

    + Diminui o [page:.weight weight] desta ação gradualmente de `1` para `0`, dentro do intervalo de + tempo decorrido. Este método pode ser encadeado. +

    + +

    [method:Number getEffectiveTimeScale]()

    +

    + Retorna a escala de tempo efetiva (considerando os estados atuais de distorção (warping) e + [page:.paused paused]). +

    + +

    [method:Number getEffectiveWeight]()

    +

    + Retorna o peso efetivo (considerando os estados atuais de desvanecimento (fading) e + [page:.enabled enabled]). +

    + +

    [method:AnimationClip getClip]()

    +

    + Retorna o clipe que contém os dados de animação para esta ação. +

    + +

    [method:AnimationMixer getMixer]()

    +

    + Retorna o mixer que é responsável por reproduzir esta ação. +

    + +

    [method:Object3D getRoot]()

    +

    + Retorna o objeto raiz no qual esta ação é executada. +

    + +

    [method:this halt]( [param:Number durationInSeconds] )

    +

    + Desacelera a velocidade desta animação para '0' diminuindo [page:.timeScale timeScale] gradualmente + (a partir de seu valor atual), dentro do intervalo de tempo decorrido. Este método pode ser encadeado. +

    + +

    [method:Boolean isRunning]()

    +

    + Retorna verdadeiro se a ação [page:.time time] estiver em execução no momento.

    + + Além de ser ativado no mixer (consulte [page:.isScheduled isScheduled]), as seguintes condições devem ser atendidas: + [page:.paused paused] é igual a false, [page:.enabled enabled] é igual a true, + [page:.timeScale timeScale] é diferente de `0` e não há agendamento para início atrasado + ([page:.startAt startAt]).

    + + Nota: `isRunning` sendo true não significa necessariamente que a animação pode realmente ser vista. + Este é apenas o caso, se [page:.weight weight] for definido adicionalmente para um valor diferente de zero. +

    + +

    [method:Boolean isScheduled]()

    +

    + Retorna verdadeiro, se esta ação estiver ativada no mixer.

    + Nota: Isso não significa necessariamente que a animação está realmente em execução (compare as + condições para [page:.isRunning isRunning]). +

    + +

    [method:this play]()

    +

    + Diz ao mixer para ativar a ação. Este método pode ser encadeado.

    + + Nota: A ativação desta ação não significa necessariamente que a animação começará imediatamente: + Se a ação já havia terminado antes (chegando ao final de seu último loop), ou se o tempo + para um início atrasado foi definido (via [page:.startAt startAt]), um [page:.reset reset] deve ser + executado primeiro. Algumas outras configurações ([page:.paused paused]=true, [page:.enabled enabled]=false, + [page:.weight weight]=0, [page:.timeScale timeScale]=0) podem também impedir a reprodução da animação. +

    + +

    [method:this reset]()

    +

    + Redefine a ação. Este método pode ser encadeado.

    + + Este método define [page:.paused paused] como false, [page:.enabled enabled] como true, + [page:.time time] para `0`, interrompe qualquer desvanecimento e distorção programados e remove a + contagem de loop e agendamento para início atrasado.

    + + Nota: .`reset` é sempre chamado por [page:.stop stop], mas .`reset` não chama .`stop` em si. + Isso significa: Se você quer ambos, resetar e parar, não chame .`reset`; chame .`stop` em vez disso. +

    + +

    [method:this setDuration]( [param:Number durationInSeconds] )

    +

    + Define a duração de um único loop desta ação (ajustando [page:.timeScale timeScale] + e parando qualquer distorção programada). Este método pode ser encadeado. +

    + +

    [method:this setEffectiveTimeScale]( [param:Number timeScale] )

    +

    + Define [page:.timeScale timeScale] e interrompe qualquer distorção (warping) programada. Este método pode ser encadeado.

    + + Se [page:.paused paused] for falso, a escala de tempo efetiva (uma propriedade interna) também será definida + com este valor; caso contrário, a escala de tempo efetiva (afetando diretamente a animação + neste momento) será definida como '0'.

    + + Nota: .`paused` não será alterado para `true` automaticamente, se .`timeScale` for definido como `0` por + este método. +

    + +

    [method:this setEffectiveWeight]( [param:Number weight] )

    +

    + Define o [page:.weight weight] e interrompe qualquer desvanecimento (fading) programado. Este método pode ser encadeado.

    + + Se [page:.enabled enabled] for true, o peso (weight) efetivo (uma propriedade interna) também será definido + com este valor; caso contrário, o peso efetivo (afetando diretamente a animação neste momento) + será definido como '0'.

    + + Nota: .`enabled` não será alterado para `false` automaticamente, se .`weight` for definido como `0` com + este método. +

    + +

    [method:this setLoop]( [param:Number loopMode], [param:Number repetitions] )

    +

    + Define o [page:.loop loop mode] e o número de [page:.repetitions repetitions]. Este método + pode ser encadeado. +

    + +

    [method:this startAt]( [param:Number startTimeInSeconds] )

    +

    + Define o tempo para um início atrasado (geralmente passado como [page:AnimationMixer.time] + + deltaTimeInSeconds). Este método pode ser encadeado.

    + + Nota: A animação só começará em um dado momento se .`startAt` estiver encadeado com + [page:.play play], ou se a ação já foi ativada no mixer (por uma + chamada de .`play`, sem parar ou redefini-lo nesse meio tempo). +

    + +

    [method:this stop]()

    +

    + Diz ao mixer para desativar esta ação. Este método pode ser encadeado.

    + + A ação será imediatamente interrompida e completamente [page:.reset resetada] (reset).

    + + Nota: Você pode parar todas as ações ativas no mesmo mixer de uma só vez usando + [page:AnimationMixer.stopAllAction mixer.stopAllAction]. +

    + +

    [method:this stopFading]()

    +

    + Interrompe qualquer [page:.fadeIn fading] agendado que seria aplicado a esta ação. Este método pode ser + encadeado. +

    + +

    [method:this stopWarping]()

    +

    + Interrompe qualquer [page:.warp warp] agendado que seria aplicado a esta ação. Este método pode ser + encadeado. +

    + +

    [method:this syncWith]( [param:AnimationAction otherAction] )

    +

    + Sincroniza esta ação com a outra ação passada. Este método pode ser encadeado.

    + + A sincronização é feita definindo os valores [page:.time time] e [page:.timeScale timeScale] desta ação + aos valores correspondentes da outra ação (parando qualquer distorção (warping) programada).

    + + Nota: Alterações futuras do `time` e do `timeScale` da outra ação não serão detectadas. +

    + +

    [method:this warp]( [param:Number startTimeScale], [param:Number endTimeScale], [param:Number durationInSeconds] )

    +

    + Altera a velocidade de reprodução, dentro do intervalo de tempo passado, modificando + [page:.timeScale timeScale] gradualmente de `startTimeScale` para `endTimeScale`. Este método pode + ser encadeado. +

    + + +

    Eventos

    + + +

    + Existem dois eventos que indicam quando um único ciclo da ação ou toda a ação é concluída. + Você pode reagir a eles com: +

    + + mixer.addEventListener( 'loop', function( e ) { …} ); // properties of e: type, action and loopDelta + mixer.addEventListener( 'finished', function( e ) { …} ); // properties of e: type, action and direction + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/animation/AnimationClip.html b/docs/api/pt-br/animation/AnimationClip.html new file mode 100644 index 00000000000000..d555478daa3afa --- /dev/null +++ b/docs/api/pt-br/animation/AnimationClip.html @@ -0,0 +1,145 @@ + + + + + + + + + +

    [name]

    + +

    + Um AnimationClip é um conjunto reutilizável de keyframe tracks que representam uma animação.

    + + Para obter uma visão geral dos diferentes elementos do sistema de animação three.js, consulte o + artigo "Sistema de animação" na seção "Próximos Passos" do manual. +

    + + +

    Construtor

    + + +

    [name]( [param:String name], [param:Number duration], [param:Array tracks] )

    +

    + [page:String name] - um nome para este clipe.
    + [page:Number duration] - a duração deste clipe (em segundos). Se for passado um valor negativo, + a duração será calculada a partir do array `tracks` passado.
    + [page:Array tracks] - um array de [page:KeyframeTrack KeyframeTracks].

    + + Nota: Em vez de instanciar um AnimationClip diretamente com o construtor, você pode usar um + de seus métodos estáticos para criar AnimationClips: de JSON ([page:.parse parse]), da sequência morph + target ([page:.CreateFromMorphTargetSequence CreateFromMorphTargetSequence], + [page:.CreateClipsFromMorphTargetSequences CreateClipsFromMorphTargetSequences]) ou de + hierarquias de animação ([page:.parseAnimation parseAnimation]) - se o seu modelo ainda não + contiver AnimationClips no array de animações de sua geometria. +

    + + +

    Propriedades

    + + +

    [property:Number duration]

    +

    + A duração deste clipe (em segundos). Pode ser calculado a partir do array de [page:.tracks tracks] + através de [page:.resetDuration resetDuration]. +

    + +

    [property:String name]

    +

    + Um nome para este clipe. Um determinado clipe pode ser pesquisado via [page:.findByName findByName]. +

    + +

    [property:Array tracks]

    +

    + Um array contendo um [page:KeyframeTrack] para cada propriedade animada por este clipe. +

    + +

    [property:String uuid]

    +

    + O [link:http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] desta instância de clipe. + Ele é atribuído automaticamente e não deve ser editado. +

    + + +

    Métodos

    + + +

    [method:AnimationClip clone]()

    +

    + Retorna uma cópia deste clipe. +

    + +

    [method:this optimize]()

    +

    + Otimiza cada faixa (track) removendo chaves sequenciais equivalentes (que são comuns em sequências morph target). +

    + +

    [method:this resetDuration]()

    +

    + Define a [page:.duration duration] do clipe para a duração de seu maior + [page:KeyframeTrack]. +

    + +

    [method:Object toJSON]()

    +

    + Retorna um objeto JSON que representa o clipe de animação serializado. +

    + +

    [method:this trim]()

    +

    + Apara todas as faixas para a duração do clipe. +

    + +

    [method:Boolean validate]()

    +

    + Executa a validação mínima em cada faixa (track) do clipe. Retorna verdadeiro se todas as faixas forem válidas. +

    + + +

    Métodos estáticos

    + + +

    [method:Array CreateClipsFromMorphTargetSequences]( [param:String name], [param:Array morphTargetSequence], [param:Number fps], [param:Boolean noLoop] )

    +

    + Retorna um array de novos AnimationClips criados a partir + de sequências morph target de uma geometria, tentando classificar nomes de morph targets em grupos de animação + padrão como "Walk_001, Walk_002, Run_001, Run_002 ...". +

    + +

    [method:AnimationClip CreateFromMorphTargetSequence]( [param:String name], [param:Array morphTargetSequence], [param:Number fps], [param:Boolean noLoop] )

    +

    + Retorna um novo AnimationClip do array de morph targets passado de uma geometria, recebendo um nome e o número de quadros por segundo.

    + + Nota: O parâmetro fps é obrigatório, mas a velocidade da animação pode ser sobrescrita em um + `AnimationAction` via [page:AnimationAction.setDuration animationAction.setDuration]. +

    + +

    [method:AnimationClip findByName]( [param:Object objectOrClipArray], [param:String name] )

    +

    + Procura um AnimationClip por nome, tendo como primeiro parâmetro um array de + AnimationClips ou um mesh ou geometria que contém um array chamado "animations". +

    + +

    [method:AnimationClip parse]( [param:Object json] )

    +

    + Analisa uma representação JSON de um clipe e retorna um AnimationClip. +

    + +

    [method:AnimationClip parseAnimation]( [param:Object animation], [param:Array bones] )

    +

    + Analisa o formato animation.hierarchy e retorna um AnimationClip. +

    + +

    [method:Object toJSON]( [param:AnimationClip clip] )

    +

    + Recebe um AnimationClip e retorna um objeto JSON. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/animation/AnimationMixer.html b/docs/api/pt-br/animation/AnimationMixer.html new file mode 100644 index 00000000000000..cf4c18026c1ae5 --- /dev/null +++ b/docs/api/pt-br/animation/AnimationMixer.html @@ -0,0 +1,116 @@ + + + + + + + + + +

    [name]

    + +

    + O AnimationMixer é um player para animações em um determinado objeto na cena. Quando + vários objetos na cena são animados independentemente, um AnimationMixer pode ser usado para + cada objeto.

    + + Para obter uma visão geral dos diferentes elementos do sistema de animação three.js, consulte o + artigo "Sistema de animação" na seção "Próximos Passos" do manual. +

    + + +

    Construtor

    + + +

    [name]( [param:Object3D rootObject] )

    +

    + [page:Object3D rootObject] - o objeto cujas animações serão reproduzidas por este mixer.
    +

    + + +

    Propriedades

    + + +

    [property:Number time]

    +

    + O tempo global do mixer (em segundos; começando com '0' na criação do mixer). +

    + +

    [property:Number timeScale]

    +

    + Um fator de escala para o [page:.time mixer time] global.

    + + Nota: Definir o timeScale do mixer para `0` e depois voltar para `1` é uma possibilidade de pausar/retomar + todas as ações que são controladas por este mixer. +

    + + +

    Métodos

    + + +

    [method:AnimationAction clipAction]([param:AnimationClip clip], [param:Object3D optionalRoot])

    +

    + Retorna um [page:AnimationAction] para o clipe passado, opcionalmente usando um objeto raiz diferente + da raiz padrão do mixer. O primeiro parâmetro pode ser um objeto [page:AnimationClip] + ou o nome de um AnimationClip.

    + + Se uma ação que se encaixa nos parâmetros de clipe e raiz ainda não existir, ela será criada por + este método. Chamar este método várias vezes com os mesmos parâmetros de clipe e raiz sempre + retorna a mesma instância de clipe. +

    + +

    [method:AnimationAction existingAction]([param:AnimationClip clip], [param:Object3D optionalRoot])

    +

    + Retorna um [page:AnimationAction] existente para o clipe passado, opcionalmente usando um objeto raiz + diferente da raiz padrão do mixer.

    + + O primeiro parâmetro pode ser um objeto [page:AnimationClip] ou o nome de um AnimationClip. +

    + +

    [method:Object3D getRoot]()

    +

    + Retorna o objeto raiz deste mixer. +

    + +

    [method:this stopAllAction]()

    +

    + Desativa todas as ações previamente agendadas neste mixer. +

    + +

    [method:this update]([param:Number deltaTimeInSeconds])

    +

    + Avança o tempo do mixer global e atualiza a animação.

    + + Isso geralmente é feito no loop de renderização, passando [page:Clock.getDelta clock.getDelta] dimensionado pelo [page:.timeScale timeScale] do mixer). +

    + +

    [method:this setTime]([param:Number timeInSeconds])

    +

    + Define o mixer global para um tempo específico e atualiza a animação de acordo.

    + + Isso é útil quando você precisa pular para um momento exato de uma animação. O parâmetro de entrada será dimensionado pelo [page:.timeScale timeScale] do mixer. +

    + +

    [method:undefined uncacheClip]([param:AnimationClip clip])

    + +

    + Desaloca todos os recursos de memória para um clipe. Antes de usar este método, certifique-se de chamar [page:AnimationAction.stop]() para todas as ações relacionadas. +

    + +

    [method:undefined uncacheRoot]([param:Object3D root])

    +

    + Desaloca todos os recursos de memória para um objeto raiz. Antes de usar este método, certifique-se de chamar [page:AnimationAction.stop]() para todas as ações relacionadas. +

    + +

    [method:undefined uncacheAction]([param:AnimationClip clip], [param:Object3D optionalRoot])

    +

    + Desaloca todos os recursos de memória para uma ação. Antes de usar este método, certifique-se de chamar [page:AnimationAction.stop]() para desativar a ação. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/animation/AnimationObjectGroup.html b/docs/api/pt-br/animation/AnimationObjectGroup.html new file mode 100644 index 00000000000000..5572f02c0c8594 --- /dev/null +++ b/docs/api/pt-br/animation/AnimationObjectGroup.html @@ -0,0 +1,89 @@ + + + + + + + + + +

    [name]

    + +

    Um grupo de objetos que recebe um estado de animação compartilhado.

    + + Para obter uma visão geral dos diferentes elementos do sistema de animação three.js, consulte o + artigo "Sistema de animação" na seção "Próximos Passos" do manual. +

    + +

    Uso:

    + +

    + Adicione objetos que você passaria como 'root' para o construtor ou o método [page:AnimationMixer.clipAction clipAction] + do [page:AnimationMixer AnimationMixer] e, em vez disso, passe este objeto como 'root'.

    + + Observe que os objetos desta classe aparecem como um único objeto para o mixer, + portanto, o controle de cache dos objetos individuais deve ser feito no grupo. +

    + + +

    Limitações

    +

    + As propriedades animadas devem ser compatíveis entre todos os objetos do grupo.

    + + Uma única propriedade pode ser controlada por meio de um grupo target ou diretamente, mas não ambos. +

    + + +

    Construtor

    + +

    [name]( [param:Object obj1], [param:Object obj2], [param:Object obj3], ... )

    +

    + [page:Object obj] - um número arbitrário de meshes que compartilham o mesmo estado de animação. +

    + +

    Propriedades

    + +

    [property:Boolean isAnimationObjectGroup]

    +

    + Sinalizador somente leitura para verificar se um determinado objeto é do tipo [name]. +

    + + +

    [property:Object stats]

    +

    + Um objeto que contém algumas informações deste `AnimationObjectGroup` (número total, número + em uso, número de ligações por objeto) +

    + +

    [property:String uuid]

    +

    + O [link:http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] deste + `AnimationObjectGroup`. Ele é atribuído automaticamente e não deve ser editado. +

    + + +

    Métodos

    + + +

    [method:undefined add]( [param:Object obj1], [param:Object obj2], [param:Object obj3], ... )

    +

    + Adiciona um número arbitrário de objetos a este `AnimationObjectGroup`. +

    + +

    [method:undefined remove]( [param:Object obj1], [param:Object obj2], [param:Object obj3], ... )

    +

    + Remove um número arbitrário de objetos deste `AnimationObjectGroup`. +

    + +

    [method:undefined uncache]( [param:Object obj1], [param:Object obj2], [param:Object obj3], ... )

    +

    + Desaloca todos os recursos de memória para os objetos passados ​​deste `AnimationObjectGroup`. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/animation/AnimationUtils.html b/docs/api/pt-br/animation/AnimationUtils.html new file mode 100644 index 00000000000000..6ffc76fcb1339b --- /dev/null +++ b/docs/api/pt-br/animation/AnimationUtils.html @@ -0,0 +1,66 @@ + + + + + + + + + +

    [name]

    + +

    + Um objeto com várias funções para auxiliar nas animações, usado internamente. +

    + + +

    Métodos

    + + +

    [method:Array arraySlice]( array, from, to )

    +

    + É o mesmo que Array.prototype.slice, mas também funciona em arrays tipados. +

    + +

    [method:Array convertArray]( array, type, forceClone )

    +

    + Converte um array em um tipo específico. +

    + +

    [method:Array flattenJSON]( jsonKeys, times, values, valuePropertyName )

    +

    + Usado para analisar formatos de keyframes AOS. +

    + +

    [method:Array getKeyframeOrder]( times )

    +

    + Retorna uma matriz pela qual os tempos e os valores podem ser classificados. +

    + +

    [method:Boolean isTypedArray]( object )

    +

    + Retorna `true` se o objeto for um array tipado. +

    + +

    [method:AnimationClip makeClipAdditive]( [param:AnimationClip targetClip], [param:Number referenceFrame], [param:AnimationClip referenceClip], [param:Number fps] )

    +

    + Converte os keyframes do clipe de animação fornecido em um formato aditivo. +

    + +

    [method:Array sortedArray]( values, stride, order )

    +

    + Classifica o array retornado anteriormente por [page:AnimationUtils.getKeyframeOrder getKeyframeOrder]. +

    + +

    [method:AnimationClip subclip]( [param:AnimationClip clip], [param:String name], [param:Number startFrame], [param:Number endFrame], [param:Number fps] )

    +

    + Cria um novo clipe, contendo apenas o segmento do clipe original entre os quadros fornecidos. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/animation/KeyframeTrack.html b/docs/api/pt-br/animation/KeyframeTrack.html new file mode 100644 index 00000000000000..9f893267f7426e --- /dev/null +++ b/docs/api/pt-br/animation/KeyframeTrack.html @@ -0,0 +1,261 @@ + + + + + + + + + + +

    [name]

    + +

    + Um KeyframeTrack é uma sequência cronometrada de [link:https://en.wikipedia.org/wiki/Key_frame keyframes], + que são compostos de listas de tempos e valores relacionados, e que são usados ​​para animar uma + propriedade específica de um objeto. +

    + +

    + Para obter uma visão geral dos diferentes elementos do sistema de animação three.js, consulte o + artigo "Sistema de animação" na seção "Próximos Passos" do manual. +

    + +

    + Em contraste com a hierarquia de animação do + [link:https://github.com/mrdoob/three.js/wiki/JSON-Model-format-3 JSON model format] uma + `KeyframeTrack` não armazena seus keyframes únicos como objetos em um array de "chaves" (mantendo os + tempos e os valores de cada frame juntos em um só lugar). +

    + +

    + Em vez disso, há sempre dois arrays em um `KeyframeTrack`: o array [page:.times times] + armazena os valores de tempo para todos os keyframes desta track em ordem sequencial, e o + array [page:.values values] contém os valores alterados correspondentes da propriedade animada. +

    + +

    + Um único valor, pertencente a um determinado ponto do tempo, pode não ser apenas um simples número, mas (por + exemplo) um vetor (se uma posição for animada) ou um quaternion (se uma rotação for animada). Por + isso o array de valores (que também é um array plano) pode ser três ou quatro vezes maior que + o array de tempo. +

    + +

    + Correspondendo aos diferentes tipos possíveis de valores animados existem várias subclasses de + `KeyframeTrack`, herdando a maioria das propriedades e métodos: +

    + +
      +
    • [page:BooleanKeyframeTrack]
    • +
    • [page:ColorKeyframeTrack]
    • +
    • [page:NumberKeyframeTrack]
    • +
    • [page:QuaternionKeyframeTrack]
    • +
    • [page:StringKeyframeTrack]
    • +
    • [page:VectorKeyframeTrack]
    • +
    + +

    + Alguns exemplos de como criar manualmente [page:AnimationClip AnimationClips] com diferentes tipos de + KeyframeTracks pode ser encontrado no arquivo [link:https://threejs.org/examples/jsm/animation/AnimationClipCreator.js AnimationClipCreator]. +

    + +

    + Como os valores explícitos são especificados apenas para os pontos discretos de tempo armazenados no array de tempo, + todos os valores intermediários devem ser interpolados. +

    + +

    + O nome da track é importante para a conexão desta track com uma propriedade específica do + nó animado (feito por [page:PropertyBinding]). +

    + + +

    Construtor

    + + +

    [name]( [param:String name], [param:Array times], [param:Array values], [param:Constant interpolation] )

    +

    + [page:String name] - o identificador do `KeyframeTrack`.
    + [page:Array times] - um array de keyframes, convertidos internamente para um + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array].
    + [page:Array values] - um array com os valores relacionados ao array times, convertidos internamente para um + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array].
    + [page:Constant interpolation] - o tipo de interpolação a ser usado. Ver + [page:Animation Animation Constants] para valores possíveis. O padrão é [page:Animation InterpolateLinear]. +

    + + +

    Propriedades

    + + +

    [property:String name]

    +

    + O nome da track pode se referir a morph targets ou [page:SkinnedMesh bones] ou possivelmente outros valores dentro de um objeto animado. Ver + [page:PropertyBinding.parseTrackName] para as formas de strings que podem ser analisadas para propriedades + vinculativas: +

    + +

    + O nome pode especificar o nó usando seu nome ou seu uuid (embora precise estar na + subárvore do nó do grafo de cena passado para o mixer). Ou, se o nome da track começar com um ponto, + a track se aplica ao nó raiz que foi passado para o mixer. +

    + +

    + Normalmente, após o nó, uma propriedade será especificada diretamente. Mas você também pode especificar um + subpropriedade, como .rotation[x], se você quiser apenas direcionar o componente X da rotação + através de uma track flutuante. +

    + +

    + Você também pode especificar bones ou multimateriais usando um nome de objeto, por exemplo: + .bones[R_hand].scale; o canal vermelho da cor difusa do quarto material em um + array de materiais - como um exemplo - pode ser acessado com .materials[3].diffuse[r]. +

    + +

    + PropertyBinding também resolverá nomes de morph targets, por exemplo: .morphTargetInfluences[run]. +

    + +

    + Nota: o nome da track não precisa necessariamente ser único. Várias tracks podem conduzir a mesma + propriedade. O resultado deve ser baseado em uma mistura ponderada entre as várias tracks de acordo com + os pesos de suas respectivas ações. +

    + +

    [property:Float32Array times]

    +

    + Um [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array], + convertido do array de tempos que é passado no construtor. +

    + +

    [property:Float32Array values]

    +

    + Um [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array], + convertido do array de valores que é passada no construtor. +

    + +

    [property:Constant DefaultInterpolation]

    +

    + O tipo de interpolação padrão: [page:Animation InterpolateLinear]. +

    + +

    [property:Constant TimeBufferType ]

    +

    + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array], + o tipo de buffer usado internamente para os tempos. +

    + +

    [property:Constant ValueBufferType ]

    +

    + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array], + o tipo de buffer usado internamente para os valores. +

    + + +

    Métodos

    + + +

    [method:KeyframeTrack clone]()

    +

    + Retorna uma cópia desta track. +

    + +

    [method:Interpolant createInterpolant]()

    +

    + Cria um [page:LinearInterpolant LinearInterpolant], [page:CubicInterpolant CubicInterpolant] + ou [page:DiscreteInterpolant DiscreteInterpolant], dependendo do valor do parâmetro interpolação + passado no construtor. +

    + +

    [method:Interpolant getInterpolation]()

    +

    + Retorna o tipo da interpolação. +

    + +

    [method:Number getValueSize]()

    +

    + Retorna o tamanho de cada valor (que é o comprimento do array [page:.values values] dividido + pelo comprimento do array [page:.times times]). +

    + +

    [method:DiscreteInterpolant InterpolantFactoryMethodDiscrete]( [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array result] )

    +

    + Cria uma nova [page:DiscreteInterpolant DiscreteInterpolant] a partir do + [page:KeyframeTrack.times times] e [page:KeyframeTrack.times values]. Um Float32Array pode ser + passado e receberá os resultados. Caso contrário, um novo array com o tamanho apropriado será + criado automaticamente. +

    + +

    [method:LinearInterpolant InterpolantFactoryMethodLinear]( [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array result] )

    +

    + Cria uma nova [page:LinearInterpolant LinearInterpolant] a partir do + [page:KeyframeTrack.times times] e [page:KeyframeTrack.times values]. Um Float32Array pode ser + passado e receberá os resultados. Caso contrário, um novo array com o tamanho apropriado será + criado automaticamente. +

    + +

    [method:CubicInterpolant InterpolantFactoryMethodSmooth]( [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array result] )

    +

    + Cria uma nova [page:CubicInterpolant CubicInterpolant] a partir do + [page:KeyframeTrack.times times] e [page:KeyframeTrack.times values]. Um Float32Array pode ser + passado e receberá os resultados. Caso contrário, um novo array com o tamanho apropriado será + criado automaticamente. +

    + +

    [method:this optimize]()

    +

    + Remove chaves sequenciais equivalentes, que são comuns em morph targets. +

    + +

    [method:this scale]()

    +

    + Dimensiona todos os tempos de keyframe por um fator.

    + + Nota: Isso é útil, por exemplo, para conversões para uma determinada taxa de quadros por segundo (como + é feito internamente por + [page:AnimationClip.CreateFromMorphTargetSequence animationClip.CreateFromMorphTargetSequence]). +

    + +

    [method:this setInterpolation]( [param:Constant interpolationType] )

    +

    + Define o tipo de interpolação. Veja [page:Animation Animation Constants] para opções. +

    + +

    [method:this shift]( [param:Number timeOffsetInSeconds] )

    +

    + Move todos os keyframes para frente ou para trás no tempo. +

    + +

    [method:this trim]( [param:Number startTimeInSeconds], [param:Number endTimeInSeconds] )

    +

    + Remove keyframes antes de `startTime` e depois de `endTime`, + sem alterar nenhum valor dentro do intervalo [`startTime`, `endTime`]. +

    + +

    [method:Boolean validate]()

    +

    + Executa validação mínima nas tracks. Retorna verdadeiro se válido. +

    + +

    + Este método registra erros no console se uma track estiver vazia, se o [page:.valueSize value size] não for + válido, se um item no array [page:.times times] ou [page:.values values] + não for um número válido ou se os itens no array `times` estiverem fora de ordem. +

    + +

    Métodos Estáticos

    + +

    [method:JSON toJSON]( [param:KeyframeTrack track] )

    +

    + Converte a track para JSON. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/animation/PropertyBinding.html b/docs/api/pt-br/animation/PropertyBinding.html new file mode 100644 index 00000000000000..ace336fd81991d --- /dev/null +++ b/docs/api/pt-br/animation/PropertyBinding.html @@ -0,0 +1,128 @@ + + + + + + + + + +

    [name]

    + +

    + Contém uma referência a uma propriedade real no grafo da cena; usado internamente. +

    + + +

    Construtor

    + + +

    [name]( [param:Object3D rootNode], path, parsedPath )

    +

    + -- [page:Object3D rootNode]: + -- path + -- parsedPath (opcional) + +

    + +

    Propriedades

    + +

    [property:Number path]

    +

    + +

    + +

    [property:Number parsedPath]

    +

    + +

    + +

    [property:Number node]

    +

    + +

    + +

    [property:Number rootNode]

    +

    + +

    + +

    [property:Object BindingType]

    +

    + +

    + +

    [property:Object Versioning]

    +

    + +

    + +

    [property:Array GetterByBindingType]

    +

    + +

    + +

    [property:Array SetterByBindingTypeAndVersioning]

    +

    + +

    + + + +

    Métodos

    + +

    [method:undefined getValue]( [param:Array targetArray], [param:Number offset] )

    +

    +

    + +

    [method:undefined setValue]( [param:Array sourceArray], [param:Number offset] )

    +

    +

    + +

    [method:undefined bind]( )

    +

    + Cria um par getter/setter para uma propriedade no grafo da cena. Usado internamente por + [page:PropertyBinding.getValue getValue] e [page:PropertyBinding.setValue setValue]. +

    + +

    [method:undefined unbind]( )

    +

    + Desvincula o par getter/setter para uma propriedade no gráfico de cena. +

    + +

    [method:Constructor Composite]( targetGroup, path, optionalParsedPath )

    +

    + Cria um novo Composite PropertyBinding. +

    + +

    [method:Constructor create]( root, path, parsedPath )

    +

    + Cria um novo Composite PropertyBinding (se a raiz é um [page:AnimationObjectGroup]) ou PropertyBinding. +

    + +

    [method:Constructor parseTrackName]( trackName )

    +

    + Corresponde a strings nas seguintes formas:
    + -- nodeName.property
    + -- nodeName.property[accessor]
    + -- nodeName.material.property[accessor]
    + -- uuid.property[accessor]
    + -- uuid.objectName[objectIndex].propertyName[propertyIndex]
    + -- parentName/nodeName.property
    + -- parentName/parentName/nodeName.property[index]
    + -- .bone[Armature.DEF_cog].position
    + -- scene:helium_balloon_model:helium_balloon_model.position +

    + +

    [method:Constructor findNode]( root, nodeName )

    +

    + Encontra um nó em uma árvore de nós ou em um [page:Skeleton Skeleton]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/animation/PropertyMixer.html b/docs/api/pt-br/animation/PropertyMixer.html new file mode 100644 index 00000000000000..5183c9cd79c7c8 --- /dev/null +++ b/docs/api/pt-br/animation/PropertyMixer.html @@ -0,0 +1,110 @@ + + + + + + + + + +

    [name]

    + +

    + Propriedade de grafo de cena em buffer que permite acumulação ponderada; usado internamente. +

    + + +

    Construtor

    + + +

    [name]( [param:PropertyBinding binding], [param:String typeName], [param:Number valueSize] )

    +

    + -- binding
    + -- typeName
    + -- valueSize
    +

    + + +

    Propriedades

    + + +

    [property:PropertyBinding binding]

    +

    + +

    + +

    [property:TypedArray buffer]

    +

    + Buffer com tamanho [page:PropertyMixer valueSize] * 4.

    + Possui o layout: [ incoming | accu0 | accu1 | orig ]

    + Os interpoladores podem usar .buffer como seu .result e os dados então vão para 'incoming'. + 'accu0' e 'accu1' são usados ​​intercalados por quadros para o resultado cumulativo e + são comparados para detectar alterações. 'orig' armazena o estado original da propriedade. +

    + +

    [property:Number cumulativeWeight]

    +

    + O padrão é `0`. +

    + +

    [property:Number cumulativeWeightAdditive]

    +

    + O padrão é `0`. +

    + +

    [property:Number valueSize]

    +

    + +

    + +

    [property:Number referenceCount]

    +

    + O padrão é `0`. +

    + +

    [property:Number useCount]

    +

    + O padrão é `0`. +

    + + +

    Métodos

    + + +

    [method:undefined accumulate]( [param:Number accuIndex], [param:Number weight] )

    +

    + Acumula dados em [page:PropertyMixer.buffer buffer][accuIndex] na região 'incoming' em 'accu[i]'.
    + + Se o weight é `0` isso não faz nada. +

    + +

    [method:undefined accumulateAdditive]( [param:Number weight] )

    +

    + Acumule dados na região 'incoming' em 'add'.
    + + Se o weight é `0` isso não faz nada. +

    + + +

    [method:undefined apply]( [param:Number accuIndex] )

    +

    + Aplica o estado de [page:PropertyMixer.buffer buffer] 'accu[i]' à ligação quando os accus forem diferentes. +

    + +

    [method:undefined saveOriginalState]( )

    +

    + Lembra o estado da propriedade vinculada e copia para ambos os accus. +

    + +

    [method:undefined restoreOriginalState]( )

    +

    + Aplica o estado obtido anteriormente por meio de 'saveOriginalState' à ligação. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/animation/tracks/BooleanKeyframeTrack.html b/docs/api/pt-br/animation/tracks/BooleanKeyframeTrack.html new file mode 100644 index 00000000000000..142748f83f82f3 --- /dev/null +++ b/docs/api/pt-br/animation/tracks/BooleanKeyframeTrack.html @@ -0,0 +1,72 @@ + + + + + + + + + + + [page:KeyframeTrack] → + +

    [name]

    + +

    + Uma track de valores de keyframes booleanos. +

    + +

    Construtor

    + +

    [name]( [param:String name], [param:Array times], [param:Array values] )

    +

    + [page:String name] - (obrigatório) identificador para o KeyframeTrack.
    + [page:Array times] - (obrigatório) array de tempos de keyframes.
    + [page:Array values] - valores para os keyframes nos tempos especificados.
    +

    + +

    Propriedades

    + +

    + Veja [page:KeyframeTrack] para propriedades herdadas. +

    + +

    [property:Constant DefaultInterpolation]

    +

    + O tipo de interpolação padrão a ser usado, [page:Animation InterpolateDiscrete]. +

    + +

    [property:Array ValueBufferType]

    +

    + Um Array normal (sem Float32Array neste caso, ao contrário de `ValueBufferType` do [page:KeyframeTrack]). +

    + +

    [property:String ValueTypeName]

    +

    + String 'bool'. +

    + + +

    Métodos

    + +

    + Veja [page:KeyframeTrack] para propriedades herdadas. +

    + +

    [method:undefined InterpolantFactoryMethodLinear ]()

    +

    + O valor deste método aqui é 'undefined', pois não faz sentido para propriedades discretas. +

    + +

    [method:undefined InterpolantFactoryMethodSmooth ]()

    +

    + O valor deste método aqui é 'undefined', pois não faz sentido para propriedades discretas. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/animation/tracks/ColorKeyframeTrack.html b/docs/api/pt-br/animation/tracks/ColorKeyframeTrack.html new file mode 100644 index 00000000000000..296b9aad243e8f --- /dev/null +++ b/docs/api/pt-br/animation/tracks/ColorKeyframeTrack.html @@ -0,0 +1,59 @@ + + + + + + + + + + + [page:KeyframeTrack] → + +

    [name]

    + +

    + Uma track de valores de keyframes que representam alterações de cor.

    + A implementação muito básica desta subclasse não tem nada de especial ainda. No entanto, este é o lugar + para parametrização do espaço de cores. +

    + + +

    Construtor

    + +

    [name]( [param:String name], [param:Array times], [param:Array values] )

    +

    + [page:String name] - (obrigatório) identificador para o KeyframeTrack.
    + [page:Array times] - (obrigatório) array de tempos de keyframes.
    + [page:Array values] - valores para os keyframes nos tempos especificados, um array plano de componentes de cores entre 0 e 1.
    + [page:Constant interpolation] - o tipo de interpolação a ser usada. Ver + [page:Animation Animation Constants] para valores possíveis. O padrão é + [page:Animation InterpolateLinear]. +

    + + +

    Propriedades

    + +

    + Veja [page:KeyframeTrack] para propriedades herdadas. +

    + +

    [property:String ValueTypeName]

    +

    + String 'color'. +

    + + +

    Métodos

    + +

    + Veja [page:KeyframeTrack] para métodos herdados. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/animation/tracks/NumberKeyframeTrack.html b/docs/api/pt-br/animation/tracks/NumberKeyframeTrack.html new file mode 100644 index 00000000000000..00c08a1bc92b85 --- /dev/null +++ b/docs/api/pt-br/animation/tracks/NumberKeyframeTrack.html @@ -0,0 +1,59 @@ + + + + + + + + + + + [page:KeyframeTrack] → + +

    [name]

    + +

    + Uma track de valores númericos de keyframe. +

    + + +

    Construtor

    + +

    [name]( [param:String name], [param:Array times], [param:Array values] )

    +

    + [page:String name] - (obrigatório) identificador para o KeyframeTrack.
    + [page:Array times] - (obrigatório) array de tempos de keyframes.
    + [page:Array values] - valores para os keyframes nos tempos especificados.
    + [page:Constant interpolation] - o tipo de interpolação a ser usada. Ver + [page:Animation Animation Constants] para valores possíveis. O padrão é + [page:Animation InterpolateLinear]. +

    + + +

    Propriedades

    + +

    + Ver [page:KeyframeTrack] para propriedades herdadas. +

    + + +

    [property:String ValueTypeName]

    +

    + String 'number'. +

    + + +

    Métodos

    + +

    + Ver [page:KeyframeTrack] para métodos herdados. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/animation/tracks/QuaternionKeyframeTrack.html b/docs/api/pt-br/animation/tracks/QuaternionKeyframeTrack.html new file mode 100644 index 00000000000000..10e83133db3352 --- /dev/null +++ b/docs/api/pt-br/animation/tracks/QuaternionKeyframeTrack.html @@ -0,0 +1,71 @@ + + + + + + + + + + + [page:KeyframeTrack] → + +

    [name]

    + +

    + Uma track de valores de keyframes quaternion. +

    + + +

    Construtor

    + +

    [name]( [param:String name], [param:Array times], [param:Array values] )

    +

    + [page:String name] - (obrigatório) identificador para o KeyframeTrack.
    + [page:Array times] - (obrigatório) array de tempos de keyframes.
    + [page:Array values] - valores para os keyframes nos tempos especificados, um array plano de componentes quaternion.
    + [page:Constant interpolation] - o tipo de interpolação a ser usada. Ver + [page:Animation Animation Constants] para valores possíveis. O padrão é + [page:Animation InterpolateLinear]. +

    + + +

    Propriedades

    + +

    + Ver [page:KeyframeTrack] para propriedades herdadas. +

    + +

    [property:Constant DefaultInterpolation]

    +

    + O tipo da interpolação padrão para usar, [page:Animation InterpolateLinear]. +

    + +

    [property:String ValueTypeName]

    +

    + String 'quaternion'. +

    + + +

    Métodos

    + + +

    + Ver [page:KeyframeTrack] para métodos herdados. +

    + +

    [method:QuaternionLinearInterpolant InterpolantFactoryMethodLinear]()

    +

    + Retorna um novo [page:QuaternionLinearInterpolant QuaternionLinearInterpolant] baseado nos + [page:KeyframeTrack.values values], [page:KeyframeTrack.times times] e + [page:KeyframeTrack.valueSize valueSize] dos keyframes. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/animation/tracks/StringKeyframeTrack.html b/docs/api/pt-br/animation/tracks/StringKeyframeTrack.html new file mode 100644 index 00000000000000..ca14eab41ce083 --- /dev/null +++ b/docs/api/pt-br/animation/tracks/StringKeyframeTrack.html @@ -0,0 +1,79 @@ + + + + + + + + + + + [page:KeyframeTrack] → + +

    [name]

    + +

    + Uma track de valores de keyframes de string. +

    + + +

    Construtor

    + +

    [name]( [param:String name], [param:Array times], [param:Array values] )

    +

    + [page:String name] - (obrigatório) identificador para o KeyframeTrack.
    + [page:Array times] - (obrigatório) array de tempos de keyframes.
    + [page:Array values] - valores para os keyframes nos tempos especificados.
    + [page:Constant interpolation] - o tipo de interpolação a ser usada. Ver + [page:Animation Animation Constants] para valores possíveis. O padrão é + [page:Animation InterpolateDiscrete]. +

    + + +

    Propriedades

    + +

    + Ver [page:KeyframeTrack] para propriedades herdadas. +

    + +

    [property:Constant DefaultInterpolation]

    +

    + O tipo de interpolação padrão para usar, [page:Animation InterpolateDiscrete]. +

    + +

    [property:Array ValueBufferType]

    +

    + Um array normal (sem Float32Array nesse caso, ao contrário de `ValueBufferType` do [page:KeyframeTrack]). +

    + +

    [property:String ValueTypeName]

    +

    + String 'string'. +

    + + +

    Métodos

    + + +

    + Ver [page:KeyframeTrack] para métodos herdados. +

    + +

    [method:undefined InterpolantFactoryMethodLinear]()

    +

    + O valor deste método aqui é 'undefined', pois não faz sentido para propriedades discretas. +

    + +

    [method:undefined InterpolantFactoryMethodSmooth]()

    +

    + O valor deste método aqui é 'undefined', pois não faz sentido para propriedades discretas. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/animation/tracks/VectorKeyframeTrack.html b/docs/api/pt-br/animation/tracks/VectorKeyframeTrack.html new file mode 100644 index 00000000000000..bfd9f20f29cc69 --- /dev/null +++ b/docs/api/pt-br/animation/tracks/VectorKeyframeTrack.html @@ -0,0 +1,59 @@ + + + + + + + + + + + [page:KeyframeTrack] → + +

    [name]

    + +

    + Uma track de valores de keyframes de vetor. +

    + + +

    Construtor

    + +

    [name]( [param:String name], [param:Array times], [param:Array values] )

    +

    + [page:String name] - (obrigatório) identificador para o KeyframeTrack.
    + [page:Array times] - (obrigatório) array de tempos de keyframes.
    + [page:Array values] - valores para os keyframes nos tempos especificados, um array plano de componentes de vetor.
    + [page:Constant interpolation] - o tipo de interpolação a ser usada. Ver + [page:Animation Animation Constants] para valores possíveis. O padrão é + [page:Animation InterpolateLinear]. +

    + + +

    Propriedades

    + +

    + Ver [page:KeyframeTrack] para propriedades herdadas. +

    + +

    [property:String ValueTypeName]

    +

    + String 'vector'. +

    + + +

    Métodos

    + + +

    + Ver [page:KeyframeTrack] para métodos herdados. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/audio/Audio.html b/docs/api/pt-br/audio/Audio.html new file mode 100644 index 00000000000000..9912622916eb51 --- /dev/null +++ b/docs/api/pt-br/audio/Audio.html @@ -0,0 +1,247 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + Cria um objeto de áudio não posicional ( global ).

    + + Utiliza a [link:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API Web Audio API]. +

    + +

    Exemplo de Código

    + + + // create an AudioListener and add it to the camera + const listener = new THREE.AudioListener(); + camera.add( listener ); + + // create a global audio source + const sound = new THREE.Audio( listener ); + + // load a sound and set it as the Audio object's buffer + const audioLoader = new THREE.AudioLoader(); + audioLoader.load( 'sounds/ambient.ogg', function( buffer ) { + sound.setBuffer( buffer ); + sound.setLoop( true ); + sound.setVolume( 0.5 ); + sound.play(); + }); + + +

    Exemplos

    + +

    + [example:webaudio_sandbox webaudio / sandbox ]
    + [example:webaudio_visualizer webaudio / visualizer ] +

    + +

    Construtor

    + + +

    [name]( [param:AudioListener listener] )

    +

    + listener — (obrigatório) instância [page:AudioListener AudioListener]. +

    + + +

    Propriedades

    + +

    [property:Boolean autoplay]

    +

    Se deve iniciar a reprodução automaticamente. O padrão é `false`.

    + +

    [property:AudioContext context]

    +

    O [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext] do [page:AudioListener listener] dado no construtor.

    + +

    [property:Number detune]

    +

    Modifica o tom, medido em centenas. +/- 100 é um semitom. +/- 1200 é uma oitava. O padrão é `0`.

    + +

    [property:Array filters]

    +

    Representa um array de [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNodes]. Pode ser usado para aplicar uma variedade de filtros de baixa ordem para criar efeitos sonoros mais complexos. + Na maioria dos casos, o array contém instâncias de [link:https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode BiquadFilterNodes]. Filtros são definidos por [page:Audio.setFilter] ou [page:Audio.setFilters].

    + +

    [property:GainNode gain]

    +

    Um [link:https://developer.mozilla.org/en-US/docs/Web/API/GainNode GainNode] criado + usando [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createGain AudioContext.createGain]().

    + +

    [property:Boolean hasPlaybackControl]

    +

    Se a reprodução pode ser controlada usando os métodos [page:Audio.play play](), + [page:Audio.pause pause]() etc. O padrão é `true`.

    + +

    [property:Boolean isPlaying]

    +

    Se o áudio está sendo reproduzido no momento.

    + +

    [property:AudioListener listener]

    +

    Uma referência ao objeto ouvinte (listener) deste áudio.

    + +

    [property:Number playbackRate]

    +

    Velocidade de reprodução. O padrão é `1`.

    + +

    [property:Number offset]

    +

    Um deslocamento para o tempo dentro do buffer de áudio em que a reprodução deve começar. Igual ao parâmetro `offset` do [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start](). O padrão é `0`.

    + +

    [property:Number duration]

    +

    Substitui a duração do áudio. O mesmo que o parâmetro `duration` do [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start](). O padrão é `undefined` para reproduzir todo o buffer.

    + +

    [property:String source]

    +

    Um [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode AudioBufferSourceNode] criado + usando [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createBufferSource AudioContext.createBufferSource]().

    + +

    [property:String sourceType]

    +

    Tipo da fonte de áudio. O padrão é a string 'empty'.

    + +

    [property:String type]

    +

    String que denota o tipo, definido como 'Audio'.

    + + +

    Métodos

    + +

    [method:this connect]()

    +

    + Conecta-se ao [page:Audio.source]. Isso é usado internamente na inicialização e quando + configurar / remover filtros. +

    + +

    [method:this disconnect]()

    +

    + Desconecta-se do [page:Audio.source]. Isso é usado internamente quando + configurar / remover filtros. +

    + +

    [method:Float getDetune]()

    +

    + Retorna a desafinação da oscilação em centenas. +

    + +

    [method:BiquadFilterNode getFilter]()

    +

    + Retorna o primeiro elemento do array [page:Audio.filters filters]. +

    + +

    [method:Array getFilters]()

    +

    + Retorna o array [page:Audio.filters filters]. +

    + +

    [method:Boolean getLoop]()

    +

    + Retorna o valor do [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loop source.loop] + (se a reprodução deve fazer um loop). +

    + +

    [method:GainNode getOutput]()

    +

    + Retorna o [page:Audio.gain gainNode]. +

    + +

    [method:Float getPlaybackRate]()

    +

    + Retorna o valor do [page:Audio.playbackRate playbackRate]. +

    + +

    [method:Float getVolume]( value )

    +

    + Retorna o volume atual. +

    + +

    [method:this play]( delay )

    +

    + Se [page:Audio.hasPlaybackControl hasPlaybackControl] é true, começa a reprodução. +

    + +

    [method:this pause]()

    +

    + Se [page:Audio.hasPlaybackControl hasPlaybackControl] é true, pausa a reprodução. +

    + +

    [method:undefined onEnded]()

    +

    + Chamado automaticamente quando a reprodução termina. +

    + +

    [method:this setBuffer]( audioBuffer )

    +

    + Configura a [page:Audio.source source] para o audioBuffer e define [page:Audio.sourceType sourceType] para 'buffer'.
    + Se [page:Audio.autoplay autoplay], também inicia a reprodução. +

    + +

    [method:this setDetune]( [param:Float value] )

    +

    + Define a desafinação da oscilação em centenas. +

    + +

    [method:this setFilter]( filter )

    +

    + Aplica um único nó de filtro ao áudio. +

    + +

    [method:this setFilters]( [param:Array value] )

    +

    + value -array de filtros.
    + Aplica um array de nós de filtro ao áudio. +

    + +

    [method:this setLoop]( [param:Boolean value] )

    +

    + Configura [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loop source.loop] para `value` + (se a reprodução deve fazer um loop). +

    + +

    [method:this setLoopStart]( [param:Float value] )

    +

    + Configura [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopStart source.loopStart] para `value`. +

    + +

    [method:this setLoopEnd]( [param:Float value] )

    +

    + Configura [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopEnd source.loopEnd] para `value`. +

    + +

    [method:this setMediaElementSource]( mediaElement )

    +

    + Aplica o objeto dado do tipo [link:https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement HTMLMediaElement] como a fonte deste áudio.
    + Também define [page:Audio.hasPlaybackControl hasPlaybackControl] para false. +

    + +

    [method:this setMediaStreamSource]( mediaStream )

    +

    + Aplica o objeto dado do tipo [link:https://developer.mozilla.org/en-US/docs/Web/API/MediaStream MediaStream] como a fonte deste áudio.
    + Também define [page:Audio.hasPlaybackControl hasPlaybackControl] para false. +

    + +

    [method:this setNodeSource]( audioNode )

    +

    + Configura o [page:Audio.source source] para o audioBuffer e define [page:Audio.sourceType sourceType] para 'audioNode'.
    + Também define [page:Audio.hasPlaybackControl hasPlaybackControl] para false. +

    + +

    [method:this setPlaybackRate]( [param:Float value] )

    +

    + Se [page:Audio.hasPlaybackControl hasPlaybackControl] está ativado, configura o [page:Audio.playbackRate playbackRate] para `value`. +

    + +

    [method:this setVolume]( [param:Float value] )

    +

    + Configura o volume. +

    + +

    [method:this stop]()

    +

    + Se [page:Audio.hasPlaybackControl hasPlaybackControl] está ativado, para a reprodução. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/audio/AudioAnalyser.html b/docs/api/pt-br/audio/AudioAnalyser.html new file mode 100644 index 00000000000000..b71d25fab2d270 --- /dev/null +++ b/docs/api/pt-br/audio/AudioAnalyser.html @@ -0,0 +1,99 @@ + + + + + + + + + +

    [name]

    + +

    + Cria um objeto AudioAnalyser, que usa um [link:https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode AnalyserNode] + para analisar informações de audio.

    + + Utiliza a [link:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API Web Audio API]. +

    + +

    Exemplo de Código

    + + + // create an AudioListener and add it to the camera + const listener = new THREE.AudioListener(); + camera.add( listener ); + + // create an Audio source + const sound = new THREE.Audio( listener ); + + // load a sound and set it as the Audio object's buffer + const audioLoader = new THREE.AudioLoader(); + audioLoader.load( 'sounds/ambient.ogg', function( buffer ) { + sound.setBuffer( buffer ); + sound.setLoop(true); + sound.setVolume(0.5); + sound.play(); + }); + + // create an AudioAnalyser, passing in the sound and desired fftSize + const analyser = new THREE.AudioAnalyser( sound, 32 ); + + // get the average frequency of the sound + const data = analyser.getAverageFrequency(); + + +

    Exemplos

    + +

    + [example:webaudio_sandbox webaudio / sandbox ]
    + [example:webaudio_visualizer webaudio / visualizer ] +

    + +

    Construtor

    + + +

    [name]( audio, [link:https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/fftSize fftSize] )

    +

    + Cria um novo [page:AudioAnalyser AudioAnalyser]. +

    + + +

    Propriedades

    + +

    [property:AnalyserNode analyser]

    +

    Um [link:https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode AnalyserNode] usado para analisar áudio.

    + +

    [property:Integer fftSize]

    +

    + Uma potência diferente de zero que vai de 2 até 2048, representando o tamanho da FFT (Fast Fourier Transform - Transformada Rápida de Fourier) a ser usada para determinar o domínio da frequência. + Ver [link:https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/fftSize esse link] para detalhes. +

    + +

    [property:Uint8Array data]

    +

    + Um Uint8Array com tamanho determinado por [link:https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/frequencyBinCount analyser.frequencyBinCount] + usado para armazenar dados de análise. +

    + + +

    Métodos

    + + +

    [method:Uint8Array getFrequencyData]()

    +

    + Usa o método [link:https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getByteFrequencyData getByteFrequencyData] do Web Audio. + Veja essa página. +

    + +

    [method:Number getAverageFrequency]()

    +

    + Obtenha a média das frequências retornadas pelo método [page:AudioAnalyser.getFrequencyData getFrequencyData]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/audio/AudioContext.html b/docs/api/pt-br/audio/AudioContext.html new file mode 100644 index 00000000000000..e17fb56d64b4c5 --- /dev/null +++ b/docs/api/pt-br/audio/AudioContext.html @@ -0,0 +1,42 @@ + + + + + + + + + + +

    [name]

    + +

    + Contém métodos para configurar um [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext].

    + + Usado internamente pelas classes [page:AudioListener AudioListener] e [page:AudioLoader AudioLoader].

    + + Utiliza a [link:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API Web Audio API]. +

    + + +

    Métodos

    + +

    [method:AudioContext getContext]()

    +

    + Retorna o valor da variável `context` no escopo externo, se definido, + caso contrário configura-o para um novo [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext]. +

    + +

    [method:AudioContext setContext]( [param:AudioContext value] )

    +

    + Define a variável `context` no escopo externo para `value`. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/audio/AudioListener.html b/docs/api/pt-br/audio/AudioListener.html new file mode 100644 index 00000000000000..2bd39d61368e24 --- /dev/null +++ b/docs/api/pt-br/audio/AudioListener.html @@ -0,0 +1,112 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + O [name] representa um [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioListener listener] virtual de todos os efeitos de áudio posicionais e não posicionais na cena.
    + Um aplicativo three.js geralmente cria uma única instância de [name]. É um parâmetro obrigatório do construtor para entidades de áudios como [page:Audio Audio] e [page:PositionalAudio PositionalAudio].
    + Na maioria dos casos, o objeto ouvinte (listener) é um filho da câmera. Assim, a transformação 3D da câmera representa a transformação 3D do ouvinte. +

    + +

    Exemplo de Código

    + + + // create an AudioListener and add it to the camera + const listener = new THREE.AudioListener(); + camera.add( listener ); + + // create a global audio source + const sound = new THREE.Audio( listener ); + + // load a sound and set it as the Audio object's buffer + const audioLoader = new THREE.AudioLoader(); + audioLoader.load( 'sounds/ambient.ogg', function( buffer ) { + sound.setBuffer( buffer ); + sound.setLoop(true); + sound.setVolume(0.5); + sound.play(); + }); + + +

    Exemplos

    + +

    + [example:webaudio_sandbox webaudio / sandbox ]
    + [example:webaudio_timing webaudio / timing ]
    + [example:webaudio_visualizer webaudio / visualizer ] +

    + +

    Construtor

    + + +

    [name]( )

    +

    + Cria um novo AudioListener. +

    + + +

    Propriedades

    + +

    [property:AudioContext context]

    +

    O [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext] do [page:AudioListener listener] fornecido no construtor.

    + +

    [property:GainNode gain]

    +

    Um [link:https://developer.mozilla.org/en-US/docs/Web/API/GainNode GainNode] criado + usando [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createGain AudioContext.createGain]().

    + +

    [property:AudioNode filter]

    +

    O padrão é `null`.

    + +

    [property:Number timeDelta]

    +

    Valor delta de tempo para entidades de áudio. Usado no contexto de [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/linearRampToValueAtTime AudioParam.linearRampToValueAtTimeDefault]().

    + +

    Métodos

    + + +

    [method:GainNode getInput]()

    +

    + Retorna o [page:AudioListener.gain gainNode]. +

    + +

    [method:this removeFilter]()

    +

    + Configura a propriedade [page:AudioListener.filter filter] para `null`. +

    + +

    [method:AudioNode getFilter]()

    +

    + Retorna o valor da propriedade [page:AudioListener.filter filter]. +

    + +

    [method:this setFilter]( [param:AudioNode value] )

    +

    + Configura a propriedade [page:AudioListener.filter filter] para `value`. +

    + +

    [method:Float getMasterVolume]()

    +

    + Retorna o volume. +

    + +

    [method:this setMasterVolume]( [param:Number value] )

    +

    + Configura o volume. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/audio/PositionalAudio.html b/docs/api/pt-br/audio/PositionalAudio.html new file mode 100644 index 00000000000000..111a707cdb1849 --- /dev/null +++ b/docs/api/pt-br/audio/PositionalAudio.html @@ -0,0 +1,136 @@ + + + + + + + + + + [page:Object3D] → [page:Audio] → + +

    [name]

    + +

    + Cria um objeto de áudio posicional.

    + + Utiliza a [link:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API Web Audio API]. +

    + +

    Exemplo de Código

    + + + // create an AudioListener and add it to the camera + const listener = new THREE.AudioListener(); + camera.add( listener ); + + // create the PositionalAudio object (passing in the listener) + const sound = new THREE.PositionalAudio( listener ); + + // load a sound and set it as the PositionalAudio object's buffer + const audioLoader = new THREE.AudioLoader(); + audioLoader.load( 'sounds/song.ogg', function( buffer ) { + sound.setBuffer( buffer ); + sound.setRefDistance( 20 ); + sound.play(); + }); + + // create an object for the sound to play from + const sphere = new THREE.SphereGeometry( 20, 32, 16 ); + const material = new THREE.MeshPhongMaterial( { color: 0xff2200 } ); + const mesh = new THREE.Mesh( sphere, material ); + scene.add( mesh ); + + // finally add the sound to the mesh + mesh.add( sound ); + + +

    Exemplos

    + +

    + [example:webaudio_orientation webaudio / orientation ]
    + [example:webaudio_sandbox webaudio / sandbox ]
    + [example:webaudio_timing webaudio / timing ] +

    + +

    Construtor

    + +

    [name]( [param:AudioListener listener] )

    +

    + listener — (obrigatório) instância [page:AudioListener AudioListener]. +

    + + +

    Propriedades

    + +

    + Veja a classe [page:Audio Audio] para propriedades herdadas. +

    + +

    [property:PannerNode panner]

    +

    O [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode PannerNode] do PositionalAudio.

    + + +

    Métodos

    + +

    + Veja a classe [page:Audio Audio] para métodos herdados. +

    + +

    [method:PannerNode getOutput]()

    +

    + Retorna o [page:PositionalAudio.panner panner]. +

    + +

    [method:Float getRefDistance]()

    +

    + Retorna o valor de [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/refDistance panner.refDistance]. +

    + +

    [method:this setRefDistance]( [param:Float value] )

    +

    + Configura o valor de [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/refDistance panner.refDistance]. +

    + +

    [method:Float getRolloffFactor]()

    +

    + Retorna o valor de [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/rolloffFactor panner.rolloffFactor]. +

    + +

    [method:this setRolloffFactor]( [param:Float value] )

    +

    + Configura o valor de [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/rolloffFactor panner.rolloffFactor]. +

    + +

    [method:String getDistanceModel]()

    +

    + Retorna o valor de [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/distanceModel panner.distanceModel]. +

    + +

    [method:this setDistanceModel]( [param:String value] )

    +

    + Configura o valor de [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/distanceModel panner.distanceModel]. +

    + +

    [method:Float getMaxDistance]()

    +

    + Retorna o valor de [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/maxDistance panner.maxDistance]. +

    + +

    [method:this setMaxDistance]( [param:Float value] )

    +

    + Configura o valor de [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/maxDistance panner.maxDistance]. +

    + +

    [method:this setDirectionalCone]( [param:Float coneInnerAngle], [param:Float coneOuterAngle], [param:Float coneOuterGain] )

    +

    + Este método pode ser usado para transformar um som omnidirecional em um som [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode direcional]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/cameras/ArrayCamera.html b/docs/api/pt-br/cameras/ArrayCamera.html new file mode 100644 index 00000000000000..5975b8931957aa --- /dev/null +++ b/docs/api/pt-br/cameras/ArrayCamera.html @@ -0,0 +1,53 @@ + + + + + + + + + + [page:Object3D] → [page:Camera] → [page:PerspectiveCamera] → + +

    [name]

    + +

    + [name] pode ser usado para renderizar com eficiência uma cena com um conjunto predefinido de câmeras. Este é um aspecto de desempenho importante para renderizar cenas de VR.
    + Uma instância de [name] sempre tem um array de subcâmeras. É obrigatório definir para cada subcâmera a propriedade `viewport` que determina a parte da viewport que é renderizada com esta câmera. +

    + +

    Exemplos

    + +

    [example:webgl_camera_array camera / array ]

    + +

    Construtor

    + +

    [name]( [param:Array array] )

    +

    + Um array de câmeras. +

    + + +

    Propriedades

    +

    Veja a classe base [page:PerspectiveCamera] para propriedades comuns.

    + +

    [property:Array cameras]

    +

    + Um array de câmeras. +

    + +

    [property:Boolean isArrayCamera]

    +

    + Sinalizador somente leitura para verificar se um determinado objeto é do tipo [name]. +

    + +

    Methods

    +

    Veja a classe base [page:PerspectiveCamera] para propriedades comuns.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/cameras/Camera.html b/docs/api/pt-br/cameras/Camera.html new file mode 100644 index 00000000000000..0fc17bcd4c2824 --- /dev/null +++ b/docs/api/pt-br/cameras/Camera.html @@ -0,0 +1,86 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + Classe base abstrata para câmeras. Essa classe sempre deve ser herdada quando você cria uma nova câmera. +

    + + +

    Construtor

    + + +

    [name]()

    +

    + Cria uma nova [name]. Observe que esta classe não se destina a ser chamada diretamente; + você provavelmente quer uma [page:PerspectiveCamera] ou uma [page:OrthographicCamera] ao invés disso. +

    + + +

    Propriedades

    +

    Veja a classe base [page:Object3D] para propriedades comuns.

    + +

    [property:Boolean isCamera]

    +

    + Sinalizador somente leitura para verificar se um determinado objeto é do tipo [name]. +

    + +

    [property:Layers layers]

    +

    + As [page:Layers layers] das quais a câmera faz parte. Esta é uma propriedade + herdada de [page:Object3D].

    + + Os objetos devem compartilhar pelo menos uma camada (layer) com a câmera para serem vistos + quando o ponto de vista da câmera é renderizado. +

    + +

    [property:Matrix4 matrixWorldInverse]

    +

    + Este é o inverso de matrixWorld. MatrixWorld contém a Matrix que tem + a transformação do mundo da Câmera. +

    + +

    [property:Matrix4 projectionMatrix]

    +

    Esta é a matriz que contém a projeção.

    + +

    [property:Matrix4 projectionMatrixInverse]

    +

    O inverso da projectionMatrix.

    + + +

    Métodos

    +

    Veja a classe base [page:Object3D] para métodos comuns.

    + +

    [method:Camera clone]( )

    +

    + Retorna uma nova câmera com as mesmas propriedades desta. +

    + +

    [method:this copy]( [param:Camera source], [param:Boolean recursive] )

    +

    + Copia as propriedades da câmera de origem para esta. +

    + +

    [method:Vector3 getWorldDirection]( [param:Vector3 target] )

    +

    + [page:Vector3 target] — o resultado será copiado para este Vector3.

    + + Retorna um [page:Vector3] representando a direção do espaço do mundo em que a câmera está olhando. + (Nota: Uma câmera olha para baixo em sua posição, eixo z negativo).

    +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/cameras/CubeCamera.html b/docs/api/pt-br/cameras/CubeCamera.html new file mode 100644 index 00000000000000..342b975ff2beba --- /dev/null +++ b/docs/api/pt-br/cameras/CubeCamera.html @@ -0,0 +1,88 @@ + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    Cria 6 câmeras que renderizam para um [page:WebGLCubeRenderTarget].

    + +

    Exemplo de Código

    + + + // Create cube render target + const cubeRenderTarget = new THREE.WebGLCubeRenderTarget( 128, { generateMipmaps: true, minFilter: THREE.LinearMipmapLinearFilter } ); + + // Create cube camera + const cubeCamera = new THREE.CubeCamera( 1, 100000, cubeRenderTarget ); + scene.add( cubeCamera ); + + // Create car + const chromeMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: cubeRenderTarget.texture } ); + const car = new THREE.Mesh( carGeometry, chromeMaterial ); + scene.add( car ); + + // Update the render target cube + car.visible = false; + cubeCamera.position.copy( car.position ); + cubeCamera.update( renderer, scene ); + + // Render the scene + car.visible = true; + renderer.render( scene, camera ); + + +

    Exemplos

    + +

    + [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ] +

    + +

    Construtor

    + + +

    [name]( [param:Number near], [param:Number far], [param:WebGLCubeRenderTarget renderTarget] )

    +

    + near -- A distância de corte próxima.
    + far -- A distância de corte distante.
    + renderTarget -- O destino de renderização do cubo target. +

    + +

    + Constrói uma CubeCamera que contém 6 [page:PerspectiveCamera PerspectiveCameras] que + renderizam para um [page:WebGLCubeRenderTarget]. +

    + +

    Propriedades

    +

    Veja a classe base [page:Object3D] para propriedades comuns.

    + +

    [property:WebGLCubeRenderTarget renderTarget]

    +

    + O destino de renderização do cubo target. +

    + +

    Métodos

    +

    Veja a classe base [page:Object3D] para métodos comuns.

    + +

    [method:undefined update]( [param:WebGLRenderer renderer], [param:Scene scene] )

    +

    + renderer -- O renderizador (renderer) WebGL atual
    + scene -- A cena (scene) atual +

    +

    + Chame isso para atualizar o [page:CubeCamera.renderTarget renderTarget]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/cameras/OrthographicCamera.html b/docs/api/pt-br/cameras/OrthographicCamera.html new file mode 100644 index 00000000000000..c4636a06bb53a1 --- /dev/null +++ b/docs/api/pt-br/cameras/OrthographicCamera.html @@ -0,0 +1,145 @@ + + + + + + + + + + [page:Object3D] → [page:Camera] → + +

    [name]

    + +

    + Câmera que usa [link:https://en.wikipedia.org/wiki/Orthographic_projection orthographic projection].

    + + Neste modo de projeção, o tamanho de um objeto na imagem renderizada permanece constante + independentemente de sua distância da câmera.

    + + Isso pode ser útil para renderizar cenas 2D e elementos de interface do usuário, entre outras coisas. +

    + +

    Exemplo de Código

    + + + const camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 ); + scene.add( camera ); + + +

    Exemplos

    + +

    + [example:webgl_camera camera ]
    + [example:webgl_interactive_cubes_ortho interactive / cubes / ortho ]
    + [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]
    + [example:webgl_postprocessing_advanced postprocessing / advanced ]
    + [example:webgl_postprocessing_dof2 postprocessing / dof2 ]
    + [example:webgl_postprocessing_godrays postprocessing / godrays ]
    + [example:webgl_rtt rtt ]
    + [example:webgl_shaders_tonemapping shaders / tonemapping ]
    + [example:webgl_shadowmap shadowmap ] +

    + +

    Construtor

    + + +

    [name]( [param:Number left], [param:Number right], [param:Number top], [param:Number bottom], [param:Number near], [param:Number far] )

    +

    + left — Plano esquerdo do tronco da câmera.
    + right — Plano direito do tronco da câmera.
    + top — Plano superior do tronco da câmera.
    + bottom — Plano inferior do tronco da câmera.
    + near — Plano próximo do tronco da câmera.
    + far — Plano distante do tronco da câmera.

    + + Juntos, eles definem a visão do [link:https://en.wikipedia.org/wiki/Viewing_frustum tronco] (frustrum) da câmera. +

    + + +

    Propriedades

    +

    + Veja a classe base [page:Camera] para propriedades comuns.
    + Observe que depois de fazer alterações na maioria dessas propriedades, você terá que chamar + [page:OrthographicCamera.updateProjectionMatrix .updateProjectionMatrix] para que as alterações tenham efeito. +

    + +

    [property:Float bottom]

    +

    Plano inferior do tronco da câmera.

    + +

    [property:Float far]

    +

    + Plano distante do tronco da câmera. O padrão é `2000`.

    + + Deve ser maior que o valor atual do plano [page:.near near] (próximo). +

    + +

    [property:Boolean isOrthographicCamera]

    +

    + Sinalizador somente leitura para verificar se um determinado objeto é do tipo [name]. +

    + +

    [property:Float left]

    +

    Plano esquerdo do tronco da câmera.

    + +

    [property:Float near]

    +

    + Plano próximo do tronco da câmera. O padrão é `0.1`.

    + + O intervalo válido está entre `0` e o valor atual do plano [page:.far far] (distante). + Observe que, diferentemente da [page:PerspectiveCamera], `0` é um valor válido para um + plano próximo da OrthographicCamera. +

    + +

    [property:Float right]

    +

    Plano direito do tronco da câmera.

    + +

    [property:Float top]

    +

    Plano superior do tronco da câmera.

    + +

    [property:Object view]

    +

    Definido por [page:OrthographicCamera.setViewOffset setViewOffset]. O padrão é `null`.

    + +

    [property:number zoom]

    +

    Obtém ou define o fator de zoom da câmera. O padrão é `1`.

    + +

    Métodos

    +

    Veja a classe base [page:Camera] para métodos comuns.

    + +

    [method:undefined setViewOffset]( [param:Float fullWidth], [param:Float fullHeight], [param:Float x], [param:Float y], [param:Float width], [param:Float height] )

    +

    + fullWidth — largura total da configuração multiview
    + fullHeight — altura total da configuração multiview
    + x — deslocamento horizontal da subcâmera
    + y — deslocamento vertical da subcâmera
    + width — largura da subcâmera
    + height — altura da subcâmera

    + + Define um deslocamento em um [link:https://en.wikipedia.org/wiki/Viewing_frustum tronco] de visualização maior. + Isso é útil para configurações de várias janelas ou vários monitores/várias máquinas. + Para um exemplo de como usá-lo, veja [page:PerspectiveCamera.setViewOffset PerspectiveCamera]. +

    + +

    [method:undefined clearViewOffset]()

    +

    + Remove qualquer deslocamento definido pelo método .setViewOffset. +

    + +

    [method:undefined updateProjectionMatrix]()

    +

    + Atualiza a matriz de projeção da câmera. Deve ser chamado após qualquer alteração de parâmetros. +

    + +

    [method:Object toJSON]([param:Object meta])

    +

    + meta -- objeto contendo metadados como texturas ou imagens em descendentes de objetos.
    + Converte a câmera para o formato [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene] three.js. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/cameras/PerspectiveCamera.html b/docs/api/pt-br/cameras/PerspectiveCamera.html new file mode 100644 index 00000000000000..a0329c2b364695 --- /dev/null +++ b/docs/api/pt-br/cameras/PerspectiveCamera.html @@ -0,0 +1,206 @@ + + + + + + + + + + [page:Object3D] → [page:Camera] → + +

    [name]

    + +

    + Câmera que usa projeção [link:https://en.wikipedia.org/wiki/Perspective_(graphical) perspectiva].

    + + Este modo de projeção é desenvolvido para imitar a forma como o olho humano enxerga. É o + modo de projeção mais comum usado para renderizar uma cena 3D. +

    + +

    Exemplo de Código

    + + + const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 ); + scene.add( camera ); + + +

    Exemplos

    + +

    + [example:webgl_animation_skinning_blending animation / skinning / blending ]
    + [example:webgl_animation_skinning_morph animation / skinning / morph ]
    + [example:webgl_effects_stereo effects / stereo ]
    + [example:webgl_interactive_cubes interactive / cubes ]
    + [example:webgl_loader_collada_skinning loader / collada / skinning ] +

    + +

    Construtor

    + +

    [name]( [param:Number fov], [param:Number aspect], [param:Number near], [param:Number far] )

    +

    + fov — Campo de visão vertical do tronco da câmera.
    + aspect — Taxa de proporção do tronco da câmera.
    + near — Plano próximo do tronco da câmera.
    + far — Plano distante do tronco da câmera.

    + + Juntos, eles definem a visão do [link:https://en.wikipedia.org/wiki/Viewing_frustum tronco] (frustrum) da câmera. +

    + + +

    Propriedades

    +

    + Veja a classe base [page:Camera] para propriedades comuns.
    + Observe que depois de fazer alterações na maioria dessas propriedades, você terá que chamar + [page:PerspectiveCamera.updateProjectionMatrix .updateProjectionMatrix] para que as alterações tenham efeito. +

    + +

    [property:Float aspect]

    +

    Taxa de proporção do tronco da câmera, geralmente a largura do canvas / altura do canvas. O padrão é `1` (canvas quadrado).

    + +

    [property:Float far]

    +

    + Plano distante do tronco da câmera. O padrão é `2000`.

    + + Deve ser maior que o valor atual do plano [page:.near near] (próximo). +

    + +

    [property:Float filmGauge]

    +

    Tamanho do filme usado para o eixo maior. O padrão é 35 (milímetros). Este parâmetro não influencia a matriz de projeção, a menos que .filmOffset seja definido como um valor diferente de zero.

    + +

    [property:Float filmOffset]

    +

    Deslocamento horizontal descentralizado na mesma unidade que `.filmGauge`. O padrão é '0'.

    + +

    [property:Float focus]

    +

    Distância do objeto usada para efeitos de estereoscopia e profundidade de campo. + Este parâmetro não influencia a matriz de projeção a menos que uma [page:StereoCamera] esteja sendo usada. + O padrão é `10`. +

    + +

    [property:Float fov]

    +

    Campo de visão vertical do tronco da câmera, de baixo para cima, em graus. O padrão é `50`.

    + +

    [property:Boolean isPerspectiveCamera]

    +

    + Sinalizador somente leitura para verificar se um determinado objeto é do tipo [name]. +

    + + +

    [property:Float near]

    +

    + Plano próximo do tronco da câmera. O padrão é `0.1`.

    + + O intervalo válido é maior que 0 e menor que o valor atual do plano [page:.far far] (distante). + Observe que, diferentemente da [page:OrthographicCamera], `0` não é um valor válido + para um plano próximo da PerspectiveCamera. +

    + +

    [property:Object view]

    +

    + Especificação do tronco da janela ou null. + Isso é definido usando o método [page:PerspectiveCamera.setViewOffset .setViewOffset] + e limpo usando [page:PerspectiveCamera.clearViewOffset .clearViewOffset]. +

    + +

    [property:number zoom]

    +

    Obtém ou define o fator de zoom da câmera. O padrão é `1`.

    + + +

    Métodos

    +

    Veja a classe base [page:Camera] para métodos comuns.

    + +

    [method:undefined clearViewOffset]()

    +

    Remove qualquer deslocamento definido pelo método [page:PerspectiveCamera.setViewOffset .setViewOffset].

    + +

    [method:Float getEffectiveFOV]()

    +

    Retorna o ângulo de visão vertical atual em graus considerando .zoom.

    + +

    [method:Float getFilmHeight]()

    +

    + Retorna a altura da imagem no filme. Se .aspect for menor ou igual a um + (formato retrato), o resultado é igual a .filmGauge. +

    + +

    [method:Float getFilmWidth]()

    +

    + Retorna a largura da imagem no filme. Se .aspect for maior ou igual a um + (formato paisagem), o resultado é igual a .filmGauge. +

    + +

    [method:Float getFocalLength]()

    +

    Retorna a distância focal do .fov atual em relação ao .filmGauge.

    + +

    [method:undefined setFocalLength]( [param:Float focalLength] )

    +

    + Define o FOV por distância focal em relação ao [page:PerspectiveCamera.filmGauge .filmGauge] atual.

    + + Por padrão, a distância focal é especificada para uma câmera de 35 mm (full frame). +

    + +

    [method:undefined setViewOffset]( [param:Float fullWidth], [param:Float fullHeight], [param:Float x], [param:Float y], [param:Float width], [param:Float height] )

    +

    + fullWidth — largura total da configuração multiview
    + fullHeight — altura total da configuração multiview
    + x — deslocamento horizontal da subcâmera
    + y — deslocamento vertical da subcâmera
    + width — largura da subcâmera
    + height — altura da subcâmera +

    + +

    + Define um deslocamento em um tronco maior. Isso é útil para configurações de várias janelas ou vários monitores/várias máquinas. +

    + +

    + Por exemplo, se você tem monitores 3x2, cada um com 1920x1080, distribuídos em um grid assim:
    + +

    ++---+---+---+
    +| A | B | C |
    ++---+---+---+
    +| D | E | F |
    ++---+---+---+
    +		
    + + então, para cada monitor, você chamaria:
    + + 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 ); + + + Observe que não há motivo para que os monitores tenham o mesmo tamanho ou estejam em um grid. +

    + +

    [method:undefined updateProjectionMatrix]()

    +

    + Atualiza a matriz de projeção da câmera. Deve ser chamado após qualquer alteração de parâmetros. +

    + +

    [method:Object toJSON]([param:Object meta])

    +

    + meta -- objeto contendo metadados como texturas ou imagens em descendentes de objetos.
    + Converte a câmera para o formato [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene] three.js. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/cameras/StereoCamera.html b/docs/api/pt-br/cameras/StereoCamera.html new file mode 100644 index 00000000000000..b80166467ffdb0 --- /dev/null +++ b/docs/api/pt-br/cameras/StereoCamera.html @@ -0,0 +1,60 @@ + + + + + + + + + + +

    [name]

    + +

    + [page:PerspectiveCamera PerspectiveCamera] dupla usada para efeitos como + [link:https://en.wikipedia.org/wiki/Anaglyph_3D 3D Anaglyph] ou [link:https://en.wikipedia.org/wiki/parallax_barrier Parallax Barrier]. +

    + +

    Exemplos

    + +

    + [example:webgl_effects_anaglyph effects / anaglyph ]
    + [example:webgl_effects_parallaxbarrier effects / parallaxbarrier ]
    + [example:webgl_effects_stereo effects / stereo ] +

    + +

    Construtor

    + +

    [name]( )

    + +

    Propriedades

    + +

    [property:Float aspect]

    +

    O padrão é `1`.

    + +

    [property:Float eyeSep]

    +

    O padrão é `0.064`.

    + +

    [property:PerspectiveCamera cameraL]

    +

    Câmera esquerda. Isso é adicionado a [page:Layers layer 1] - objetos a serem renderizados + pela câmera esquerda também deve ser adicionados a esta camada (layer).

    + +

    [property:PerspectiveCamera cameraR]

    +

    Câmera direita. Isso é adicionado a [page:Layers layer 2] - objetos a serem renderizados + pela câmera direita também deve ser adicionados a esta camada (layer).

    + + +

    Métodos

    + +

    [method:undefined update]( [param:PerspectiveCamera camera] )

    +

    + Atualiza as câmeras estéreo com base na câmera passada. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/pt-br/constants/Animation.html b/docs/api/pt-br/constants/Animation.html new file mode 100644 index 00000000000000..e8bf438bc6addb --- /dev/null +++ b/docs/api/pt-br/constants/Animation.html @@ -0,0 +1,46 @@ + + + + + + + + + +

    Constantes de Animação

    + +

    Modos de Loop (Loop Modes)

    + + +THREE.LoopOnce +THREE.LoopRepeat +THREE.LoopPingPong + + +

    Modos de Interpolação (Interpolation Modes)

    + +THREE.InterpolateDiscrete +THREE.InterpolateLinear +THREE.InterpolateSmooth + + +

    Modos de Finalização (Ending Modes)

    + +THREE.ZeroCurvatureEnding +THREE.ZeroSlopeEnding +THREE.WrapAroundEnding + + +

    Modos de Mistura de Animação (Animation Blend Modes)

    + +THREE.NormalAnimationBlendMode +THREE.AdditiveAnimationBlendMode + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + diff --git a/docs/api/pt-br/constants/BufferAttributeUsage.html b/docs/api/pt-br/constants/BufferAttributeUsage.html new file mode 100644 index 00000000000000..deb5fea2ea9a95 --- /dev/null +++ b/docs/api/pt-br/constants/BufferAttributeUsage.html @@ -0,0 +1,51 @@ + + + + + + + + + +

    Constantes de Uso do Atributo Buffer

    + +

    + As constantes de uso podem ser usadas para fornecer uma dica à API sobre como o atributo de buffer da geometria será usado para otimizar o desempenho. +

    + +

    Exemplo de Código

    + + + const geometry = new THREE.BufferGeometry(); + const positionAttribute = new THREE.BufferAttribute( array, 3 , false ); + positionAttribute.setUsage( THREE.DynamicDrawUsage ); + geometry.setAttribute( 'position', positionAttribute ); + + +

    Exemplos

    +

    [example:webgl_buffergeometry_drawrange materials / buffergeometry / drawrange ]

    + +

    Uso de Geometria

    + + THREE.StaticDrawUsage + THREE.DynamicDrawUsage + THREE.StreamDrawUsage + + THREE.StaticReadUsage + THREE.DynamicReadUsage + THREE.StreamReadUsage + + THREE.StaticCopyUsage + THREE.DynamicCopyUsage + THREE.StreamCopyUsage + + + Para obter informações mais detalhadas sobre cada uma dessas constantes, consulte a documentação [link:https://www.khronos.org/opengl/wiki/Buffer_Object#Buffer_Object_Usage OpenGL]. + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + diff --git a/docs/api/pt-br/constants/Core.html b/docs/api/pt-br/constants/Core.html new file mode 100644 index 00000000000000..795980e3a4246c --- /dev/null +++ b/docs/api/pt-br/constants/Core.html @@ -0,0 +1,80 @@ + + + + + + + + + +

    Constantes do Core

    + +

    Número de Revisão

    + + +THREE.REVISION + + +
    + O [link:https://github.com/mrdoob/three.js/releases revision number] (número de revisão) atual do three.js. +
    + +

    Espaço de Cores

    + +THREE.NoColorSpace +THREE.SRGBColorSpace +THREE.LinearSRGBColorSpace + +

    + [page:NoColorSpace] não define nenhum espaço de cor específico. +

    +

    + [page:SRGBColorSpace] (“sRGB”) refere-se ao espaço de cores definido pelo Rec. 709 primárias, D65 + ponto branco e funções de transferência sRGB não lineares. sRGB é o espaço de cor padrão em + CSS, e é frequentemente encontrado em paletas e seletores de cores. Cores expressas em + notação hexadecimal ou CSS estão normalmente no espaço de cores sRGB. +

    + +

    + [page:LinearSRGBColorSpace] (“Linear-sRGB”) refere-se ao espaço de cores sRGB (acima) com + funções de transferência lineares. Linear-sRGB é o espaço de cores de trabalho em three.js, usado + durante a maior parte do processo de renderização. Componentes RGB encontrados em materiais three.js + e os shaders estão no espaço de cores Linear-sRGB. +

    + +

    + Para mais informações e uso, consulte Gerenciamento de cor. +

    + +

    Botões do Mouse

    + +THREE.MOUSE.LEFT +THREE.MOUSE.MIDDLE +THREE.MOUSE.RIGHT +THREE.MOUSE.ROTATE +THREE.MOUSE.DOLLY +THREE.MOUSE.PAN + +

    + As constantes LEFT e ROTATE têm o mesmo valor subjacente. + As constantes MIDDLE e DOLLY têm o mesmo valor subjacente. + As constantes RIGHT e PAN têm o mesmo valor subjacente. +

    + +

    Ações de Toque

    + +THREE.TOUCH.ROTATE +THREE.TOUCH.PAN +THREE.TOUCH.DOLLY_PAN +THREE.TOUCH.DOLLY_ROTATE + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + + + diff --git a/docs/api/pt-br/constants/CustomBlendingEquations.html b/docs/api/pt-br/constants/CustomBlendingEquations.html new file mode 100644 index 00000000000000..929edf149ae7c8 --- /dev/null +++ b/docs/api/pt-br/constants/CustomBlendingEquations.html @@ -0,0 +1,64 @@ + + + + + + + + + +

    Constantes de Equação de Mesclagem Personalizada (Custom Blending Equation)

    + +

    + Funcionam com todos os tipos de materiais. Primeiro defina o modo de mesclagem do material para THREE.CustomBlending, em seguida, defina a equação de mesclagem desejada, o fator de origem e o fator de destino. +

    + +

    Exemplo de Código

    + + + const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); + material.blending = THREE.CustomBlending; + material.blendEquation = THREE.AddEquation; //default + material.blendSrc = THREE.SrcAlphaFactor; //default + material.blendDst = THREE.OneMinusSrcAlphaFactor; //default + + +

    Exemplos

    +

    [example:webgl_materials_blending_custom materials / blending / custom ]

    + +

    Equações de Mesclagem

    + + THREE.AddEquation + THREE.SubtractEquation + THREE.ReverseSubtractEquation + THREE.MinEquation + THREE.MaxEquation + + +

    Fatores de Origem

    + + THREE.ZeroFactor + THREE.OneFactor + THREE.SrcColorFactor + THREE.OneMinusSrcColorFactor + THREE.SrcAlphaFactor + THREE.OneMinusSrcAlphaFactor + THREE.DstAlphaFactor + THREE.OneMinusDstAlphaFactor + THREE.DstColorFactor + THREE.OneMinusDstColorFactor + THREE.SrcAlphaSaturateFactor + + +

    Fatores de Destino

    +

    + Todos os Fatores de Origem são válidos como Fatores de Destino, exceto, THREE.SrcAlphaSaturateFactor +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + diff --git a/docs/api/pt-br/constants/Materials.html b/docs/api/pt-br/constants/Materials.html new file mode 100644 index 00000000000000..2cd4b6b83dae22 --- /dev/null +++ b/docs/api/pt-br/constants/Materials.html @@ -0,0 +1,152 @@ + + + + + + + + + +

    Constantes de Material

    + +

    + Essas constantes definem propriedades comuns a todos os tipos de materiais, + com exceção das Operações de Combinação de Texturas que se aplicam apenas a [page:MeshBasicMaterial.combine MeshBasicMaterial], [page:MeshLambertMaterial.combine MeshLambertMaterial] e [page:MeshPhongMaterial.combine MeshPhongMaterial].
    +

    + +

    Lado (Side)

    + + THREE.FrontSide + THREE.BackSide + THREE.DoubleSide + +

    + Define qual lado das faces será renderizado - frente, verso ou ambos. + O padrão é [page:Constant FrontSide]. +

    + +

    Modo de Mesclagem (Blending Mode)

    + + THREE.NoBlending + THREE.NormalBlending + THREE.AdditiveBlending + THREE.SubtractiveBlending + THREE.MultiplyBlending + THREE.CustomBlending + + + +

    + Eles controlam as equações de mesclagem de origem e destino para RGB e Alpha do material enviadas ao WebGLRenderer para uso pelo WebGL.
    + [page:Constant NormalBlending] é o padrão.
    + Note que [page:Constant CustomBlending] deve ser definido para usar Equações de [page:CustomBlendingEquation Mesclagem Personalizadas].
    + Veja os exemplos [example:webgl_materials_blending materials / blending].
    +

    + +

    Modo de Profundidade (Depth Mode)

    + + THREE.NeverDepth + THREE.AlwaysDepth + THREE.EqualDepth + THREE.LessDepth + THREE.LessEqualDepth + THREE.GreaterEqualDepth + THREE.GreaterDepth + THREE.NotEqualDepth + +

    + Define qual função de profundidade o material usa para comparar a profundidade Z dos pixels de entrada com o valor atual do buffer de profundidade Z. Se o resultado da comparação for verdadeiro, o pixel será desenhado.
    + [page:Materials NeverDepth] nunca retornará true.
    + [page:Materials AlwaysDepth] sempre vai retornar true.
    + [page:Materials EqualDepth] retornará true se a profundidade Z do pixel de entrada for igual à profundidade Z do buffer atual.
    + [page:Materials LessDepth] retornará true se a profundidade Z do pixel de entrada for menor que a profundidade Z do buffer atual.
    + [page:Materials LessEqualDepth] é o padrão e retornará true se a profundidade Z do pixel de entrada for menor ou igual à profundidade Z do buffer atual.
    + [page:Materials GreaterEqualDepth] retornará true se a profundidade Z do pixel de entrada for maior ou igual à profundidade Z do buffer atual.
    + [page:Materials GreaterDepth] retornará true se a profundidade Z do pixel de entrada for maior que a profundidade Z do buffer atual.
    + [page:Materials NotEqualDepth] retornará true se a profundidade Z do pixel de entrada não for igual à profundidade Z do buffer atual.
    +

    + +

    Operações de Combinação de Texturas

    + + THREE.MultiplyOperation + THREE.MixOperation + THREE.AddOperation + +

    + Definem como o resultado da cor da superfície é combinado com o mapa do ambiente (se presente), por [page:MeshBasicMaterial.combine MeshBasicMaterial], [page:MeshLambertMaterial.combine MeshLambertMaterial] e [page:MeshPhongMaterial.combine MeshPhongMaterial].
    + [page:Constant MultiplyOperation] é o padrão e multiplica a cor do mapa de ambiente pela cor da superfície.
    + [page:Constant MixOperation] usa refletividade para misturar as duas cores.
    + [page:Constant AddOperation] adiciona as duas cores. +

    + +

    Funções de Estêncil (Stencil Functions)

    + + THREE.NeverStencilFunc + THREE.LessStencilFunc + THREE.EqualStencilFunc + THREE.LessEqualStencilFunc + THREE.GreaterStencilFunc + THREE.NotEqualStencilFunc + THREE.GreaterEqualStencilFunc + THREE.AlwaysStencilFunc + +

    + Define qual função de estêncil o material usa para determinar se deve ou não realizar uma operação de estêncil.
    + [page:Materials NeverStencilFunc] nunca retornará true.
    + [page:Materials LessStencilFunc] retornará true se o valor de referência do estêncil for menor que o valor do estêncil atual.
    + [page:Materials EqualStencilFunc] retornará true se o valor de referência do estêncil for igual ao valor atual do estêncil.
    + [page:Materials LessEqualStencilFunc] retornará true se o valor de referência do estêncil for menor ou igual ao valor do estêncil atual.
    + [page:Materials GreaterStencilFunc] retornará true se o valor de referência de estêncil for maior que o valor de estêncil atual.
    + [page:Materials NotEqualStencilFunc] retornará true se o valor de referência do estêncil não for igual ao valor do estêncil atual.
    + [page:Materials GreaterEqualStencilFunc] retornará true se o valor de referência do estêncil for maior ou igual ao valor do estêncil atual.
    + [page:Materials AlwaysStencilFunc] sempre retornará true.
    +

    + +

    Operações de Estêncil (Stencil Operations)

    + + THREE.ZeroStencilOp + THREE.KeepStencilOp + THREE.ReplaceStencilOp + THREE.IncrementStencilOp + THREE.DecrementStencilOp + THREE.IncrementWrapStencilOp + THREE.DecrementWrapStencilOp + THREE.InvertStencilOp + +

    + Define qual operação de estêncil o material executará no pixel de buffer de estêncil se a função de estêncil fornecida for aprovada.
    + [page:Materials ZeroStencilOp] definirá o valor do estêncil para 0.
    + [page:Materials KeepStencilOp] não alterará o valor atual do estêncil.
    + [page:Materials ReplaceStencilOp] substituirá o valor de estêncil pelo valor de referência do estêncil especificado.
    + [page:Materials IncrementStencilOp] irá incrementar o valor atual do estêncil em `1`.
    + [page:Materials DecrementStencilOp] diminuirá o valor atual do estêncil em `1`.
    + [page:Materials IncrementWrapStencilOp] irá incrementar o valor atual do estêncil em `1`. Se o valor aumentar além de `255`, ele será definido como `0`.
    + [page:Materials DecrementWrapStencilOp] irá incrementar o valor atual do estêncil em `1`. Se o valor diminuir abaixo de `0`, será definido como `255`.
    + [page:Materials InvertStencilOp] executará uma inversão bit a bit do valor de estêncil atual.
    +

    + +

    Tipo de mapa normal

    + + THREE.TangentSpaceNormalMap + THREE.ObjectSpaceNormalMap + +

    + Define o tipo do mapa normal + Para TangentSpaceNormalMap, as informações são relativas à superfície subjacente. + Para ObjectSpaceNormalMap, as informações são relativas à orientação do objeto. + O padrão é [page:Constant TangentSpaceNormalMap]. +

    + +

    Versão GLSL

    + + THREE.GLSL1 + THREE.GLSL3 + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + diff --git a/docs/api/pt-br/constants/Renderer.html b/docs/api/pt-br/constants/Renderer.html new file mode 100644 index 00000000000000..ce399497219b44 --- /dev/null +++ b/docs/api/pt-br/constants/Renderer.html @@ -0,0 +1,68 @@ + + + + + + + + + +

    Constantes do WebGLRenderer

    + +

    Modos de Eliminação de Faces (Cull Face Modes)

    + + THREE.CullFaceNone + THREE.CullFaceBack + THREE.CullFaceFront + THREE.CullFaceFrontBack + +

    + [page:constant CullFaceNone] desativa a eliminação de faces.
    + [page:constant CullFaceBack] elimina as faces traseiras (padrão)
    + [page:constant CullFaceFront] elimina faces frontais.
    + [page:constant CullFaceFrontBack] elimina as faces frontal e traseira. +

    + +

    Tipos de Sombra (Shadow Types)

    + + THREE.BasicShadowMap + THREE.PCFShadowMap + THREE.PCFSoftShadowMap + THREE.VSMShadowMap + +

    + Definem a propriedade [page:WebGLRenderer.shadowMap.type shadowMap.type] do WebGLRenderer.

    + + [page:constant BasicShadowMap] fornece mapas de sombra não filtrados - mais rápido, mas de menor qualidade.
    + [page:constant PCFShadowMap] filtra mapas de sombra usando o algoritmo Percentage-Closer Filtering (PCF) (padrão).
    + [page:constant PCFSoftShadowMap] filtra mapas de sombra usando o algoritmo Percentage-Closer Filtering (PCF) com melhores sombras suaves, especialmente ao usar mapas de sombra de baixa resolução.
    + [page:constant VSMShadowMap] filtra mapas de sombra usando o algoritmo Variance Shadow Map (VSM). Ao usar o VSMShadowMap, todos os receptores de sombra também projetarão sombras. +

    + +

    Mapeamento de Tom (Tone Mapping)

    + + THREE.NoToneMapping + THREE.LinearToneMapping + THREE.ReinhardToneMapping + THREE.CineonToneMapping + THREE.ACESFilmicToneMapping + THREE.CustomToneMapping + +

    + Eles definem a propriedade [page:WebGLRenderer.toneMapping toneMapping] do WebGLRenderer. + Isso é usado para aproximar a aparência da faixa dinâmica alta (HDR) no + médio da faixa dinâmica baixa de um monitor de computador padrão ou tela de dispositivo móvel. +

    +

    + THREE.LinearToneMapping, THREE.ReinhardToneMapping, THREE.CineonToneMapping e THREE.ACESFilmicToneMapping são implementações internas de mapeamento de tom. + THREE.CustomToneMapping espera uma implementação personalizada modificando o código GLSL do sombreador de fragmento do material. + Vejo o exemplo [example:webgl_tonemapping WebGL / tonemapping]. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + diff --git a/docs/api/pt-br/constants/Textures.html b/docs/api/pt-br/constants/Textures.html new file mode 100644 index 00000000000000..29e21adfcc2c4f --- /dev/null +++ b/docs/api/pt-br/constants/Textures.html @@ -0,0 +1,560 @@ + + + + + + + + + +

    Constantes de Textura

    + +

    Modos de Mapeamento

    + + THREE.UVMapping + THREE.CubeReflectionMapping + THREE.CubeRefractionMapping + THREE.EquirectangularReflectionMapping + THREE.EquirectangularRefractionMapping + THREE.CubeUVReflectionMapping + + +

    + Definem o modo de mapeamento da textura.
    + [page:Constant UVMapping] é o padrão e mapeia a textura usando as coordenadas UV do mesh.

    + + O restante define tipos de mapeamento de ambiente.

    + + [page:Constant CubeReflectionMapping] e [page:Constant CubeRefractionMapping] são usados + com um [page:CubeTexture CubeTexture], que é composto por seis texturas, uma para cada face do cubo. + [page:Constant CubeReflectionMapping] é o padrão para um [page:CubeTexture CubeTexture].

    + + [page:Constant EquirectangularReflectionMapping] e [page:Constant EquirectangularRefractionMapping] + são para uso com um mapa de ambiente equirretangular. Também chamado de mapa lat-long, uma textura equirretangular + representa uma vista de 360 ​​graus ao longo da linha central horizontal e uma vista de 180 graus ao longo da + eixo vertical, com as bordas superior e inferior da imagem correspondendo aos pólos norte e sul + de uma esfera mapeada.

    + + Veja o exemplo [example:webgl_materials_envmaps materials / envmaps]. +

    + + +

    Modos de Envolvimento (Wrapping Modes)

    + + THREE.RepeatWrapping + THREE.ClampToEdgeWrapping + THREE.MirroredRepeatWrapping + +

    + Eles definem as propriedades [page:Texture.wrapS wrapS] e [page:Texture.wrapT wrapT] da textura, + que definem o envolvimento de textura horizontal e vertical.

    + + Com [page:constant RepeatWrapping] a textura simplesmente se repetirá até o infinito.

    + + [page:constant ClampToEdgeWrapping] é o padrão. + O último pixel da textura se estende até a borda da malha.

    + + Com [page:constant MirroredRepeatWrapping] a textura se repetirá ao infinito, espelhando-se em cada repetição. +

    + +

    Filtros de Ampliação (Magnification Filters)

    + + THREE.NearestFilter + THREE.LinearFilter + + +

    + Para uso com a propriedade [page:Texture.magFilter magFilter] de uma textura, + eles definem a função de ampliação de textura que é usada quando o pixel que está sendo texturizado mapeia para uma + área menor ou igual a um elemento de textura (texel).

    + + [page:constant NearestFilter] retorna o valor do elemento de textura mais próximo + (na distância Manhattan) para as coordenadas de textura especificadas.

    + + [page:constant LinearFilter] é o padrão e retorna a média ponderada + dos quatro elementos de textura que estão mais próximos das coordenadas de textura especificadas, + e pode incluir itens embrulhados ou repetidos de outras partes de uma textura, + dependendo dos valores de [page:Texture.wrapS wrapS] e [page:Texture.wrapT wrapT], e no mapeamento exato. +

    + +

    Filtros de Redução (Minification Filters)

    + + THREE.NearestFilter + THREE.NearestMipmapNearestFilter + THREE.NearestMipmapLinearFilter + THREE.LinearFilter + THREE.LinearMipmapNearestFilter + THREE.LinearMipmapLinearFilter + + +

    + Para uso com a propriedade [page:Texture.minFilter minFilter] de uma textura, eles definem + a função de redução de textura que é usada sempre que o pixel que está sendo texturizado mapeia + para uma área maior que um elemento de textura (texel).

    + + Além do [page:constant NearestFilter] e do [page:constant LinearFilter], + as quatro funções a seguir podem ser usadas para minificação:

    + + [page:constant NearestMipmapNearestFilter] escolhe o mipmap que mais se aproxima + ao tamanho do pixel que está sendo texturizado + e usa o critério [page:constant NearestFilter] (o texel mais próximo do + centro do pixel) para produzir um valor de textura.

    + + [page:constant NearestMipmapLinearFilter] escolhe os dois mipmaps que mais se aproximam + ao tamanho do pixel que está sendo texturizado e usa o critério [page:constant NearestFilter] para produzir + um valor de textura de cada mipmap. O valor final da textura é uma média ponderada desses dois valores.

    + + [page:constant LinearMipmapNearestFilter] escolhe o mipmap que mais se aproxima + do tamanho do pixel que está sendo texturizado e usa o critério [page:constant LinearFilter] + (uma média ponderada dos quatro texels que estão mais próximos do centro do pixel) + para produzir um valor de textura.

    + + [page:constant LinearMipmapLinearFilter] é o padrão e escolhe os dois mipmaps + que mais se aproximam do tamanho do pixel que está sendo texturizado e usa o critério [page:constant LinearFilter] + para produzir um valor de textura de cada mipmap. O valor final da textura é uma média ponderada desses dois valores.

    + + Veja o exemplo [example:webgl_materials_texture_filters materials / texture / filters]. +

    + +

    Tipos

    + + THREE.UnsignedByteType + THREE.ByteType + THREE.ShortType + THREE.UnsignedShortType + THREE.IntType + THREE.UnsignedIntType + THREE.FloatType + THREE.HalfFloatType + THREE.UnsignedShort4444Type + THREE.UnsignedShort5551Type + THREE.UnsignedInt248Type + +

    + Para uso com a propriedade [page:Texture.type type] de uma textura, que deve corresponder ao formato correto. Veja abaixo para detalhes.

    + + [page:constant UnsignedByteType] é o padrão. +

    + +

    Formatos

    + + THREE.AlphaFormat + THREE.RedFormat + THREE.RedIntegerFormat + THREE.RGFormat + THREE.RGIntegerFormat + THREE.RGBAFormat + THREE.RGBAIntegerFormat + THREE.LuminanceFormat + THREE.LuminanceAlphaFormat + THREE.DepthFormat + THREE.DepthStencilFormat + +

    + Para uso com a propriedade [page:Texture.format format] de uma textura, eles definem + como os elementos de uma textura 2D, ou `texels`, são lidos por shaders.

    + + [page:constant AlphaFormat] descarta os componentes vermelho, verde e azul e lê apenas o componente alfa.

    + + [page:constant RedFormat] descarta os componentes verde e azul e lê apenas o componente vermelho.

    + + [page:constant RedIntegerFormat] descarta os componentes verde e azul e lê apenas o componente vermelho. + Os texels são lidos como inteiros em vez de ponto flutuante. + (só pode ser usado com um contexto de renderização WebGL 2). +

    + + [page:constant RGFormat] descarta os componentes alfa e azul e lê os componentes vermelho e verde. + (só pode ser usado com um contexto de renderização WebGL 2). +

    + + [page:constant RGIntegerFormat] descarta os componentes alfa e azul e lê os componentes vermelho e verde. + Os texels são lidos como inteiros em vez de ponto flutuante. + (só pode ser usado com um contexto de renderização WebGL 2). +

    + + [page:constant RGBAFormat] é o padrão e lê os componentes vermelho, verde, azul e alfa.

    + + [page:constant RGBAIntegerFormat] é o padrão e lê os componentes vermelho, verde, azul e alfa. + Os texels são lidos como inteiros em vez de ponto flutuante. + (só pode ser usado com um contexto de renderização WebGL 2). +

    + + [page:constant LuminanceFormat] lê cada elemento como um único componente de luminância. + Este é então convertido em um ponto flutuante, fixado no intervalo [0,1], e então montado + em um elemento RGBA, colocando o valor de luminância nos canais vermelho, verde e azul, + e anexando 1.0 ao canal alfa.

    + + [page:constant LuminanceAlphaFormat] lê cada elemento como um duplo de luminância/alfa. + O mesmo processo ocorre para o [page:constant LuminanceFormat], exceto que o + o canal alfa pode ter valores diferentes de `1.0`.

    + + [page:constant DepthFormat] lê cada elemento como um único valor de profundidade, converte-o em ponto flutuante e fixa no intervalo [0,1]. + Este é o padrão para [page:DepthTexture DepthTexture].

    + + [page:constant DepthStencilFormat] lê cada elemento como um par de valores de profundidade e estêncil. + O componente de profundidade do par é interpretado como um [page:constant DepthFormat]. + O componente de estêncil é interpretado com base no formato interno de profundidade + estêncil. +

    + + Observe que a textura deve ter o conjunto [page:Texture.type type] correto, conforme descrito acima. + Veja [link:https://developer.mozilla.org/en/docs/Web/API/WebGLRenderingContext/texImage2D WebGLRenderingContext.texImage2D] para detalhes. +

    + +

    Formatos de Textura Compactados DDS / ST3C

    + + THREE.RGB_S3TC_DXT1_Format + THREE.RGBA_S3TC_DXT1_Format + THREE.RGBA_S3TC_DXT3_Format + THREE.RGBA_S3TC_DXT5_Format + +

    + Para uso com a propriedade [page:Texture.format format] de uma [page:CompressedTexture CompressedTexture], + requerem suporte para a extensão [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/ WEBGL_compressed_texture_s3tc].

    + + Existem quatro formatos [link:https://en.wikipedia.org/wiki/S3_Texture_Compression S3TC] disponíveis por meio desta extensão. São esses:
    + [page:constant RGB_S3TC_DXT1_Format]: Uma imagem compactada em DXT1 em um formato de imagem RGB.
    + [page:constant RGBA_S3TC_DXT1_Format]: Uma imagem compactada em DXT1 em um formato de imagem RGB com um valor alfa de ativação/desativação simples.
    + [page:constant RGBA_S3TC_DXT3_Format]: Uma imagem compactada em DXT3 em um formato de imagem RGBA. Comparado a uma textura RGBA de 32 bits, oferece compressão 4:1.
    + [page:constant RGBA_S3TC_DXT5_Format]: Uma imagem compactada em DXT5 em um formato de imagem RGBA. Ele também fornece uma compactação 4:1, mas difere da compactação DXT3 na forma como a compactação alfa é feita.
    +

    + +

    Formato de Textura Compactado PVRTC

    + + THREE.RGB_PVRTC_4BPPV1_Format + THREE.RGB_PVRTC_2BPPV1_Format + THREE.RGBA_PVRTC_4BPPV1_Format + THREE.RGBA_PVRTC_2BPPV1_Format + +

    + Para uso com a propriedade [page:Texture.format format] de uma [page:CompressedTexture CompressedTexture], + requerem suporte para a extensão [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/ WEBGL_compressed_texture_pvrtc].
    + PVRTC is typically only available on mobile devices with PowerVR chipsets, which are mainly Apple devices.

    + + Existem quatro formatos [link:https://en.wikipedia.org/wiki/PVRTC PVRTC] disponíveis por meio desta extensão. São esses:
    + [page:constant RGB_PVRTC_4BPPV1_Format]: Compressão RGB no modo de 4 bits. Um bloco para cada 4×4 pixels.
    + [page:constant RGB_PVRTC_2BPPV1_Format]: Compressão RGB no modo de 2 bits. Um bloco para cada 8×4 pixels.
    + [page:constant RGBA_PVRTC_4BPPV1_Format]: Compressão RGBA no modo de 4 bits. Um bloco para cada 4×4 pixels.
    + [page:constant RGBA_PVRTC_2BPPV1_Format]: Compressão RGBA no modo de 2 bits. Um bloco para cada 8×4 pixels.
    +

    + +

    Formato de Textura Compactado ETC

    + + THREE.RGB_ETC1_Format + THREE.RGB_ETC2_Format + THREE.RGBA_ETC2_EAC_Format + +

    + Para uso com a propriedade [page:Texture.format format] de uma [page:CompressedTexture CompressedTexture], + requerem suporte para a extensão [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc1/ WEBGL_compressed_texture_etc1] + (ETC1) ou [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc/ WEBGL_compressed_texture_etc] + (ETC2).

    +

    + +

    Formato de Textura Compactado ASTC

    + + THREE.RGBA_ASTC_4x4_Format + THREE.RGBA_ASTC_5x4_Format + THREE.RGBA_ASTC_5x5_Format + THREE.RGBA_ASTC_6x5_Format + THREE.RGBA_ASTC_6x6_Format + THREE.RGBA_ASTC_8x5_Format + THREE.RGBA_ASTC_8x6_Format + THREE.RGBA_ASTC_8x8_Format + THREE.RGBA_ASTC_10x5_Format + THREE.RGBA_ASTC_10x6_Format + THREE.RGBA_ASTC_10x8_Format + THREE.RGBA_ASTC_10x10_Format + THREE.RGBA_ASTC_12x10_Format + THREE.RGBA_ASTC_12x12_Format + +

    + Para uso com a propriedade [page:Texture.format format] de uma [page:CompressedTexture CompressedTexture], + requerem suporte para a extensão [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_astc/ WEBGL_compressed_texture_astc].

    +

    + +

    BPTC Compressed Texture Format

    + + THREE.RGBA_BPTC_Format + +

    + Para uso com a propriedade [page:Texture.format format] de uma [page:CompressedTexture CompressedTexture], + requerem suporte para a extensão [link:https://www.khronos.org/registry/webgl/extensions/EXT_texture_compression_bptc/ EXT_texture_compression_bptc].

    +

    + +

    Formatos Internos

    + + 'ALPHA' + 'RGB' + 'RGBA' + 'LUMINANCE' + 'LUMINANCE_ALPHA' + 'RED_INTEGER' + 'R8' + 'R8_SNORM' + 'R8I' + 'R8UI' + 'R16I' + 'R16UI' + 'R16F' + 'R32I' + 'R32UI' + 'R32F' + 'RG8' + 'RG8_SNORM' + 'RG8I' + 'RG8UI' + 'RG16I' + 'RG16UI' + 'RG16F' + 'RG32I' + 'RG32UI' + 'RG32F' + 'RGB565' + 'RGB8' + 'RGB8_SNORM' + 'RGB8I' + 'RGB8UI' + 'RGB16I' + 'RGB16UI' + 'RGB16F' + 'RGB32I' + 'RGB32UI' + 'RGB32F' + 'RGB9_E5' + 'SRGB8' + 'R11F_G11F_B10F' + 'RGBA4' + 'RGBA8' + 'RGBA8_SNORM' + 'RGBA8I' + 'RGBA8UI' + 'RGBA16I' + 'RGBA16UI' + 'RGBA16F' + 'RGBA32I' + 'RGBA32UI' + 'RGBA32F' + 'RGB5_A1' + 'RGB10_A2' + 'RGB10_A2UI' + 'SRGB8_ALPHA8' + 'DEPTH_COMPONENT16' + 'DEPTH_COMPONENT24' + 'DEPTH_COMPONENT32F' + 'DEPTH24_STENCIL8' + 'DEPTH32F_STENCIL8' + + +

    + + Atenção: alterar o formato interno de uma textura afetará a + textura apenas quando for usado um contexto de renderização WebGL 2.

    + + Para uso com a propriedade [page:Texture.internalFormat internalFormat] de uma textura, + definem como os elementos de uma textura, ou `texels`, são armazenados na GPU.

    + + [page:constant R8] armazena o componente vermelho em 8 bits.

    + + [page:constant R8_SNORM] armazena o componente vermelho em 8 bits. O componente é armazenado como normalizado.

    + + [page:constant R8I] armazena o componente vermelho em 8 bits. O componente é armazenado como um inteiro.

    + + [page:constant R8UI] armazena o componente vermelho em 8 bits. O componente é armazenado como um inteiro sem sinal.

    + + [page:constant R16I] armazena o componente vermelho em 16 bits. O componente é armazenado como um inteiro.

    + + [page:constant R16UI] armazena o componente vermelho em 16 bits. O componente é armazenado como um inteiro sem sinal.

    + + [page:constant R16F] armazena o componente vermelho em 16 bits. O componente é armazenado como ponto flutuante.

    + + [page:constant R32I] armazena o componente vermelho em 32 bits. O componente é armazenado como um inteiro.

    + + [page:constant R32UI] armazena o componente vermelho em 32 bits. O componente é armazenado como um inteiro sem sinal.

    + + [page:constant R32F] armazena o componente vermelho em 32 bits. O componente é armazenado como ponto flutuante.

    + + [page:constant RG8] armazena os componentes vermelho e verde em 8 bits cada.

    + + [page:constant RG8_SNORM] armazena os componentes vermelho e verde em 8 bits cada. + Cada componente é armazenado como normalizado. +

    + + [page:constant RG8I] armazena os componentes vermelho e verde em 8 bits cada. + Cada componente é armazenado como um inteiro. +

    + + [page:constant RG8UI] armazena os componentes vermelho e verde em 8 bits cada. + Cada componente é armazenado como um inteiro sem sinal. +

    + + [page:constant RG16I] armazena os componentes vermelho e verde em 16 bits cada. + Cada componente é armazenado como um inteiro. +

    + + [page:constant RG16UI] armazena os componentes vermelho e verde em 16 bits cada. + Cada componente é armazenado como um inteiro sem sinal. +

    + + [page:constant RG16F] armazena os componentes vermelho e verde em 16 bits cada. + Cada componente é armazenado como ponto flutuante. +

    + + [page:constant RG32I] armazena os componentes vermelho e verde em 32 bits cada. + Cada componente é armazenado como um inteiro. +

    + + [page:constant RG32UI] armazena os componentes vermelho e verde em 32 bits. + Cada componente é armazenado como um inteiro sem sinal. +

    + + [page:constant RG32F] armazena os componentes vermelho e verde em 32 bits. + Cada componente é armazenado como ponto flutuante. +

    + + [page:constant RGB8] armazena os componentes vermelho, verde e azul em 8 bits cada. + + [page:constant RGB8_SNORM] armazena os componentes vermelho, verde e azul em 8 bits cada. + Cada componente é armazenado como normalizado. +

    + + [page:constant RGB8I] armazena os componentes vermelho, verde e azul em 8 bits cada. + Cada componente é armazenado como um inteiro. +

    + + [page:constant RGB8UI] armazena os componentes vermelho, verde e azul em 8 bits cada. + Cada componente é armazenado como um inteiro sem sinal. +

    + + [page:constant RGB16I] armazena os componentes vermelho, verde e azul em 16 bits cada. + Cada componente é armazenado como um inteiro. +

    + + [page:constant RGB16UI] armazena os componentes vermelho, verde e azul em 16 bits cada. + Cada componente é armazenado como um inteiro sem sinal. +

    + + [page:constant RGB16F] armazena os componentes vermelho, verde e azul em 16 bits cada. + Cada componente é armazenado como ponto flutuante. +

    + + [page:constant RGB32I] armazena os componentes vermelho, verde e azul em 32 bits cada. + Cada componente é armazenado como um inteiro. +

    + + [page:constant RGB32UI] armazena os componentes vermelho, verde e azul em 32 bits cada. + Cada componente é armazenado como um inteiro sem sinal. +

    + + [page:constant RGB32F] armazena os componentes vermelho, verde e azul em 32 bits cada. + Cada componente é armazenado como ponto flutuante. +

    + + [page:constant R11F_G11F_B10F] armazena os componentes vermelho, verde e azul, respectivamente, em 11 bits, 11 bits e 10 bits. + Cada componente é armazenado como ponto flutuante. +

    + + [page:constant RGB565] armazena os componentes vermelho, verde e azul, respectivamente, em 5 bits, 6 bits e 5 bits.

    + + [page:constant RGB9_E5] armazena os componentes vermelho, verde e azul em 9 bits cada.

    + + [page:constant RGBA8] armazena os componentes vermelho, verde, azul e alfa em 8 bits cada.

    + + [page:constant RGBA8_SNORM] armazena os componentes vermelho, verde, azul e alfa em 8 bits. + Cada componente é armazenado como normalizado. +

    + + [page:constant RGBA8I] armazena os componentes vermelho, verde, azul e alfa em 8 bits cada. + Cada componente é armazenado como um inteiro. +

    + + [page:constant RGBA8UI] armazena os componentes vermelho, verde, azul e alfa em 8 bits. + Cada componente é armazenado como um inteiro sem sinal. +

    + + [page:constant RGBA16I] armazena os componentes vermelho, verde, azul e alfa em 16 bits. + Cada componente é armazenado como um inteiro. +

    + + [page:constant RGBA16UI] armazena os componentes vermelho, verde, azul e alfa em 16 bits. + Cada componente é armazenado como um inteiro sem sinal. +

    + + [page:constant RGBA16F] armazena os componentes vermelho, verde, azul e alfa em 16 bits. + Cada componente é armazenado como ponto flutuante. +

    + + [page:constant RGBA32I] armazena os componentes vermelho, verde, azul e alfa em 32 bits. + Cada componente é armazenado como um inteiro. +

    + + [page:constant RGBA32UI] armazena os componentes vermelho, verde, azul e alfa em 32 bits. + Cada componente é armazenado como um inteiro sem sinal. +

    + + [page:constant RGBA32F] armazena os componentes vermelho, verde, azul e alfa em 32 bits. + Cada componente é armazenado como ponto flutuante. +

    + + [page:constant RGB5_A1] armazena os componentes vermelho, verde, azul e alfa, respectivamente, em 5 bits, 5 bits, 5 bits e 1 bit.

    + + [page:constant RGB10_A2] armazena os componentes vermelho, verde, azul e alfa, respectivamente, em 10 bits, 10 bits, 10 bits e 2 bits.

    + + [page:constant RGB10_A2UI] armazena os componentes vermelho, verde, azul e alfa, respectivamente, em 10 bits, 10 bits, 10 bits e 2 bits. + Cada componente é armazenado como um inteiro sem sinal. +

    + + [page:constant SRGB8] armazena os componentes vermelho, verde e azul em 8 bits cada.

    + + [page:constant SRGB8_ALPHA8] armazena os componentes vermelho, verde, azul e alfa em 8 bits cada.

    + + [page:constant DEPTH_COMPONENT16] armazena o componente de profundidade em 16 bits.

    + + [page:constant DEPTH_COMPONENT24] armazena o componente de profundidade em 24 bits.

    + + [page:constant DEPTH_COMPONENT32F] armazena o componente de profundidade em 32 bits. O componente é armazenado como ponto flutuante.

    + + [page:constant DEPTH24_STENCIL8] armazena os componentes de profundidade e estêncil, respectivamente, em 24 bits e 8 bits. + O componente de estêncil é armazenado como um inteiro sem sinal. +

    + + [page:constant DEPTH32F_STENCIL8] armazena os componentes de profundidade e estêncil, respectivamente, em 32 bits e 8 bits. + O componente de profundidade é armazenado como ponto flutuante e o componente de estêncil como um inteiro sem sinal. +

    + + Observe que a textura deve ter o [page:Texture.type type] correto, + bem como o [page:Texture.format format] correto. + + Veja [link:https://developer.mozilla.org/en/docs/Web/API/WebGLRenderingContext/texImage2D WebGLRenderingContext.texImage2D], e + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/texImage3D WebGL2RenderingContext.texImage3D], + para obter mais detalhes sobre a possível combinação de [page:Texture.format format], [page:Texture.internalFormat internalFormat], + e [page:Texture.type type].

    + + Para obter informações mais detalhadas sobre os formatos internos, você também pode consultar diretamente + a especificação [link:https://www.khronos.org/registry/webgl/specs/latest/2.0/ WebGL2] e + a especificação [link:https://www.khronos.org/registry/OpenGL/specs/es/3.0/es_spec_3.0.pdf OpenGL ES 3.0]. +

    + +

    Encoding

    + + THREE.LinearEncoding + THREE.sRGBEncoding + THREE.BasicDepthPacking + THREE.RGBADepthPacking + +

    + Para uso com a propriedade [page:Texture.encoding encoding] de uma textura.

    + + Se o tipo de codificação for alterado após a textura já ter sido usada por um material, + você precisará definir [page:Material.needsUpdate Material.needsUpdate] como `true` para fazer o material recompilar.

    + + [page:constant LinearEncoding] é o padrão. + Valores diferentes deste são válidos apenas para o mapa de um material, envMap e emissiveMap. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + + diff --git a/docs/api/zh/constants/Materials.html b/docs/api/zh/constants/Materials.html index ba8e60b4820348..9029fdf9598e18 100644 --- a/docs/api/zh/constants/Materials.html +++ b/docs/api/zh/constants/Materials.html @@ -125,6 +125,12 @@

    模板操作

    [page:Materials InvertStencilOp] 将当前模板值按位反转.

    +

    GLSL Version

    + + THREE.GLSL1 + THREE.GLSL3 + +

    源代码

    diff --git a/docs/api/zh/core/BufferAttribute.html b/docs/api/zh/core/BufferAttribute.html index ff11f5b3e065b4..929d4af72dd761 100644 --- a/docs/api/zh/core/BufferAttribute.html +++ b/docs/api/zh/core/BufferAttribute.html @@ -130,18 +130,6 @@

    [method:this copyArray]( array )

    [method:this copyAt] ( [param:Integer index1], [param:BufferAttribute bufferAttribute], [param:Integer index2] )

    将一个矢量从 bufferAttribute[index2] 拷贝到 [page:BufferAttribute.array array][index1] 中。

    -

    [method:this copyColorsArray]( [param:Array colors] )

    -

    将一个存储 RGB 颜色值的队列拷贝到 [page:BufferAttribute.array array] 中。

    - -

    [method:this copyVector2sArray]( [param:Array vectors] )

    -

    将一个存储 [page:Vector2] 的队列拷贝到 [page:BufferAttribute.array array] 中。

    - -

    [method:this copyVector3sArray]( [param:Array vectors] )

    -

    将一个存储 [page:Vector3] 的队列拷贝到 [page:BufferAttribute.array array] 中。

    - -

    [method:this copyVector4sArray]( [param:Array vectors] )

    -

    将一个存储 [page:Vector4] 的队列拷贝到 [page:BufferAttribute.array array] 中。

    -

    [method:Number getX]( [param:Integer index] )

    获取给定索引的矢量的第一维元素 (即 X 值)。

    diff --git a/docs/api/zh/core/BufferGeometry.html b/docs/api/zh/core/BufferGeometry.html index 81a702df098097..5551016ce4fa88 100644 --- a/docs/api/zh/core/BufferGeometry.html +++ b/docs/api/zh/core/BufferGeometry.html @@ -232,9 +232,6 @@

    [method:this lookAt] ( [param:Vector3 vector] )

    旋转几何体朝向控件中的一点。该过程通常在一次处理中完成,不会循环处理。典型的用法是过通过调用 [page:Object3D.lookAt] 实时改变 mesh 朝向。

    -

    [method:this merge]( [param:BufferGeometry bufferGeometry], [param:Integer offset] )

    -

    同参数指定的 BufferGeometry 进行合并。可以通过可选参数指定,从哪个偏移位置开始进行 merge。

    -

    [method:undefined normalizeNormals]()

    几何体中的每个法向量长度将会为 1。这样操作会更正光线在表面的效果。 diff --git a/docs/api/zh/core/Object3D.html b/docs/api/zh/core/Object3D.html index ba94517b2e4cca..a48fc7e2323420 100644 --- a/docs/api/zh/core/Object3D.html +++ b/docs/api/zh/core/Object3D.html @@ -80,6 +80,12 @@

    [property:Matrix4 matrixWorld]

    物体的世界变换。若这个Object3D没有父级,则它将和local transform [page:.matrix](局部变换矩阵)相同。

    +

    [property:Boolean matrixWorldAutoUpdate]

    +

    + Default is true. If set, then the renderer checks every frame if the object and its children need matrix updates. + When it isn't, then you have to maintain all matrices in the object and its children yourself. +

    +

    [property:Boolean matrixWorldNeedsUpdate]

    当这个属性设置了之后,它将计算在那一帧中的matrixWorld,并将这个值重置为false。默认值为*false*。 @@ -298,7 +304,7 @@

    [method:undefined lookAt]( [param:Vector3 vector] )
    这一方法不支持其父级被旋转过或者被位移过的物体。

    -

    [method:Array raycast]( [param:Raycaster raycaster], [param:Array intersects] )

    +

    [method:undefined raycast]( [param:Raycaster raycaster], [param:Array intersects] )

    抽象(空方法),在一条被投射出的射线与这个物体之间获得交点。 在一些子类,例如[page:Mesh], [page:Line], and [page:Points]实现了这个方法,以用于光线投射。

    diff --git a/docs/api/zh/extras/core/ShapePath.html b/docs/api/zh/extras/core/ShapePath.html index 8b42a3409a41ff..11247d3a073128 100644 --- a/docs/api/zh/extras/core/ShapePath.html +++ b/docs/api/zh/extras/core/ShapePath.html @@ -67,14 +67,13 @@

    [method:this splineThru] ( [param:Array points] )

    连接一个新的[page:SplineCurve](样条曲线)到[page:ShapePath.currentPath currentPath](当前路径)。

    -

    [method:Array toShapes]( [param:Boolean isCCW], [param:Boolean noHoles] )

    +

    [method:Array toShapes]( [param:Boolean isCCW] )

    - isCCW -- 更改实体形状和孔洞的生成方式。
    - noHoles -- 是否创建孔洞。 + isCCW -- 更改实体形状和孔洞的生成方式。

    将[page:ShapePath.subPaths subPaths]数组转换为到Shapes数组。默认情况下,实体形状按照顺时针(CW)来定义,孔洞按照逆时针(CCW)来定义。 - 如果isCCW被设置为true,则孔洞和实体形状的定义将被反转。如果noHoles参数设置为true,则所有路径将被设置为实体形状,isCCW将被忽略。 + 如果isCCW被设置为true,则孔洞和实体形状的定义将被反转。

    diff --git a/docs/api/zh/helpers/PolarGridHelper.html b/docs/api/zh/helpers/PolarGridHelper.html index 26b239b4ebfe8e..2e36fce25ba65d 100644 --- a/docs/api/zh/helpers/PolarGridHelper.html +++ b/docs/api/zh/helpers/PolarGridHelper.html @@ -17,11 +17,11 @@

    代码示例

    const radius = 10; - const radials = 16; - const circles = 8; + const sectors = 16; + const rings = 8; const divisions = 64; - const helper = new THREE.PolarGridHelper( radius, radials, circles, divisions ); + const helper = new THREE.PolarGridHelper( radius, sectors, rings, divisions ); scene.add( helper ); @@ -33,17 +33,17 @@

    例子

    构造函数

    -

    [name]( [param:Number radius], [param:Number radials], [param:Number circles], [param:Number divisions], [param:Color color1], [param:Color color2] )

    +

    [name]( [param:Number radius], [param:Number sectors], [param:Number rings], [param:Number divisions], [param:Color color1], [param:Color color2] )

    radius -- 极坐标格半径. 可以为任何正数. 默认为 10.
    - radials -- 径向辐射线数量. 可以为任何正整数. 默认为 16.
    - circles -- 圆圈的数量. 可以为任何正整数. 默认为 8.
    + sectors -- The number of sectors the grid will be divided into. This can be any positive integer. Default is 16.
    + rings -- The number of rings. This can be any positive integer. Default is 8.
    divisions -- 圆圈细分段数. 可以为任何大于或等于3的正整数. 默认为 64.
    color1 -- 极坐标格使用的第一个颜色. 值可以为 [page:Color] 类型, 16进制 和 CSS 颜色名. 默认为 0x444444
    color2 -- 极坐标格使用的第二个颜色. 值可以为 [page:Color] 类型, 16进制 和 CSS 颜色名. 默认为 0x888888

    - 创建一个半径为'radius' 包含 'radials' 条径向辐射线 和 'circles' 个细分成 'divisions' 段的圆圈的极坐标格辅助对象. 颜色可选. + Creates a new [name] of radius 'radius' with 'sectors' number of sectors and 'rings' number of rings, where each circle is smoothed into 'divisions' number of line segments. Colors are optional.

    源码

    diff --git a/docs/api/zh/lights/DirectionalLight.html b/docs/api/zh/lights/DirectionalLight.html index 467baa8e9127ce..93dca302109792 100644 --- a/docs/api/zh/lights/DirectionalLight.html +++ b/docs/api/zh/lights/DirectionalLight.html @@ -26,8 +26,7 @@

    关于位置、目标和旋转说明

    这意味着它的方向是从一个平行光的位置 [page:Object3D.position position] 到 [page:.target target]的位置。 (而不是一个只有旋转分量的'自由平行光')。

    - 这样做的原因是为了让光线投射阴影。 - the [page:.shadow shadow] - 摄像机需要一个位置来计算阴影。

    + 这样做的原因是为了让光线投射阴影。[page:.shadow shadow]摄像机需要一个位置来计算阴影。

    有关更新目标的详细信息,请参阅 [page:.target target] 下面的目标属性。

    diff --git a/docs/api/zh/lights/PointLight.html b/docs/api/zh/lights/PointLight.html index 0c0254477715c6..1ece0844a68060 100644 --- a/docs/api/zh/lights/PointLight.html +++ b/docs/api/zh/lights/PointLight.html @@ -39,12 +39,10 @@

    构造器(Constructor)

    [name]( [param:Integer color], [param:Float intensity], [param:Number distance], [param:Float decay] )

    [page:Integer color] - (可选参数)) 十六进制光照颜色。 缺省值 0xffffff (白色)。
    - [page:Float intensity] - (可选参数) 光照强度。 缺省值 1。

    + [page:Float intensity] - (可选参数) 光照强度。 缺省值 1。
    [page:Number distance] - 这个距离表示从光源到光照强度为0的位置。 当设置为0时,光永远不会消失(距离无穷大)。缺省值 0.
    - [page:Float decay] - 沿着光照距离的衰退量。缺省值 1。 - - 在 [page:WebGLRenderer.physicallyCorrectLights physically correct] 模式中,decay = 2。

    + [page:Float decay] - 沿着光照距离的衰退量。缺省值 2。

    创建一个新的点光源(PointLight)。

    @@ -56,9 +54,8 @@

    属性(Properties)

    [property:Float decay]

    - 沿着光照距离的衰减量
    - 在 [page:WebGLRenderer.physicallyCorrectLights physically correct] 模式下,decay 设置为等于2将实现现实世界的光衰减。
    - 缺省值为 *1*。 + The amount the light dims along the distance of the light. Default is `2`.
    + In context of physically-correct rendering the default value should not be changed.

    [property:Float distance]

    diff --git a/docs/api/zh/lights/SpotLight.html b/docs/api/zh/lights/SpotLight.html index 6ff1b095d0249b..9cc4e5f6cce50a 100644 --- a/docs/api/zh/lights/SpotLight.html +++ b/docs/api/zh/lights/SpotLight.html @@ -19,10 +19,11 @@

    聚光灯([name])

    代码示例

    - // white spotlight shining from the side, casting a shadow + // white spotlight shining from the side, modulated by a texture, casting a shadow const spotLight = new THREE.SpotLight( 0xffffff ); spotLight.position.set( 100, 1000, 100 ); + spotLight.map = new THREE.TextureLoader().load( url ); spotLight.castShadow = true; @@ -49,7 +50,7 @@

    构造器(Constructor)

    [name]( [param:Integer color], [param:Float intensity], [param:Float distance], [param:Radians angle], [param:Float penumbra], [param:Float decay] )

    [page:Integer color] - (可选参数) 十六进制光照颜色。 缺省值 0xffffff (白色)。
    - [page:Float intensity] - (可选参数) 光照强度。 缺省值 1。

    + [page:Float intensity] - (可选参数) 光照强度。 缺省值 1。
    [page:Float distance] - 从光源发出光的最大距离,其强度根据光源的距离线性衰减。
    [page:Radians angle] - 光线散射角度,最大为Math.PI/2。
    [page:Float penumbra] - 聚光锥的半影衰减百分比。在0和1之间的值。默认为0。
    @@ -77,9 +78,8 @@

    [property:Boolean castShadow]

    [property:Float decay]

    - 沿着光照距离的衰减量
    - 在 [page:WebGLRenderer.physicallyCorrectLights physically correct] 模式下,decay 设置为等于2将实现现实世界的光衰减。
    - 缺省值为 *1*。 + The amount the light dims along the distance of the light. Default is `2`.
    + In context of physically-correct rendering the default value should not be changed.

    [property:Float distance]

    @@ -144,6 +144,14 @@

    [property:Object3D target]

    完成上述操作后,聚光灯现在就可以追踪到目标对像了。

    +

    [property:Texture map]

    +

    + A [page:Texture] used to modulate the color of the light. The spot light color is mixed + with the RGB value of this texture, with a ratio corresponding to its + alpha value. The cookie-like masking effect is reproduced using pixel values (0, 0, 0, 1-cookie_value). + *Warning*: [param:SpotLight map] is disabled if [param:SpotLight castShadow] is *false*. +

    +

    方法(Methods)

    diff --git a/docs/api/zh/lights/shadows/PointLightShadow.html b/docs/api/zh/lights/shadows/PointLightShadow.html index ec424853e83d86..c5783e350b90e2 100644 --- a/docs/api/zh/lights/shadows/PointLightShadow.html +++ b/docs/api/zh/lights/shadows/PointLightShadow.html @@ -7,6 +7,7 @@ + [page:LightShadow] →

    [name]

    diff --git a/docs/api/zh/materials/Material.html b/docs/api/zh/materials/Material.html index 67599be0f5398f..6f653f35d4eb67 100644 --- a/docs/api/zh/materials/Material.html +++ b/docs/api/zh/materials/Material.html @@ -28,7 +28,7 @@

    [property:Float alphaTest]

    设置运行alphaTest时要使用的alpha值。如果不透明度低于此值,则不会渲染材质。默认值为*0*。

    -

    [property:Float alphaToCoverage]

    +

    [property:Boolean alphaToCoverage]

    启用alpha to coverage. 只能在开启了MSAA的渲染环境中使用 (当渲染器创建的时候*antialias* 属性要*true*才能使用). 默认为 *false*. diff --git a/docs/api/zh/materials/MeshLambertMaterial.html b/docs/api/zh/materials/MeshLambertMaterial.html index ad38865aacae5e..5fa9c7d3a4f9ea 100644 --- a/docs/api/zh/materials/MeshLambertMaterial.html +++ b/docs/api/zh/materials/MeshLambertMaterial.html @@ -13,11 +13,8 @@

    Lambert网格材质([name])

    一种非光泽表面的材质,没有镜面高光。

    该材质使用基于非物理的[link:https://en.wikipedia.org/wiki/Lambertian_reflectance Lambertian]模型来计算反射率。 - 这可以很好地模拟一些表面(例如未经处理的木材或石材),但不能模拟具有镜面高光的光泽表面(例如涂漆木材)。

    + 这可以很好地模拟一些表面(例如未经处理的木材或石材),但不能模拟具有镜面高光的光泽表面(例如涂漆木材)。 [name] uses per-fragment shading。

    - - 使用[link:https://en.wikipedia.org/wiki/Gouraud_shading Gouraud]着色模型计算着色。这将计算每个顶点的着色 - (即在[link:https://en.wikipedia.org/wiki/Shader#Vertex_shaders vertex shader]中)并在多边形的面上插入结果。

    由于反射率和光照模型的简单性,[page:MeshPhongMaterial],[page:MeshStandardMaterial]或者[page:MeshPhysicalMaterial] 上使用这种材质时会以一些图形精度为代价,得到更高的性能。

    @@ -67,6 +64,13 @@

    [property:Texture aoMap]

    [property:Float aoMapIntensity]

    环境遮挡效果的强度。默认值为1。零是不遮挡效果。

    +

    [property:Texture bumpMap]

    +

    用于创建凹凸贴图的纹理。黑色和白色值映射到与光照相关的感知深度。凹凸实际上不会影响对象的几何形状,只影响光照。如果定义了法线贴图,则将忽略该贴图。 +

    + +

    [property:Float bumpScale]

    +

    凹凸贴图会对材质产生多大影响。典型范围是0-1。默认值为1。

    +

    [property:Color color]

    材质的颜色([page:Color]),默认值为白色 (0xffffff)。

    @@ -77,6 +81,20 @@

    [property:Integer combine]

    [page:Materials THREE.AddOperation]。如果选择多个,则使用[page:.reflectivity]在两种颜色之间进行混合。

    +

    [property:Texture displacementMap]

    +

    位移贴图会影响网格顶点的位置,与仅影响材质的光照和阴影的其他贴图不同,移位的顶点可以投射阴影,阻挡其他对象, + 以及充当真实的几何体。位移纹理是指:网格的所有顶点被映射为图像中每个像素的值(白色是最高的),并且被重定位。 +

    + +

    [property:Float displacementScale]

    +

    位移贴图对网格的影响程度(黑色是无位移,白色是最大位移)。如果没有设置位移贴图,则不会应用此值。默认值为1。 +

    + +

    [property:Float displacementBias]

    +

    + 位移贴图在网格顶点上的偏移量。如果没有设置位移贴图,则不会应用此值。默认值为0。 +

    +

    [property:Color emissive]

    材质的放射(光)颜色,基本上是不受其他光照影响的固有颜色。默认为黑色。

    @@ -92,6 +110,10 @@

    [property:Float emissiveIntensity]

    [property:Texture envMap]

    环境贴图。默认值为null。

    +

    [property:Boolean flatShading]

    +

    定义材质是否使用平面着色进行渲染。默认值为false。 +

    +

    [property:Boolean fog]

    材质是否受雾影响。默认为*true*。

    @@ -107,6 +129,21 @@

    [property:Texture map]

    或[page:Material.alphaTest .alphaTest]。默认为null。

    +

    [property:Texture normalMap]

    +

    用于创建法线贴图的纹理。RGB值会影响每个像素片段的曲面法线,并更改颜色照亮的方式。法线贴图不会改变曲面的实际形状,只会改变光照。 + In case the material has a normal map authored using the left handed convention, the y component of normalScale + should be negated to compensate for the different handedness. +

    + +

    [property:Integer normalMapType]

    +

    法线贴图的类型。

    + 选项为[page:constant THREE.TangentSpaceNormalMap](默认)和[page:constant THREE.ObjectSpaceNormalMap]。 +

    + +

    [property:Vector2 normalScale]

    +

    法线贴图对材质的影响程度。典型范围是0-1。默认值是[page:Vector2]设置为(1,1)。 +

    +

    [property:Float reflectivity]

    环境贴图对表面的影响程度; 见[page:.combine]。默认值为1,有效范围介于0(无反射)和1(完全反射)之间。

    diff --git a/docs/api/zh/materials/MeshPhongMaterial.html b/docs/api/zh/materials/MeshPhongMaterial.html index 6d4679364f5b26..17d0fccd9596ca 100644 --- a/docs/api/zh/materials/MeshPhongMaterial.html +++ b/docs/api/zh/materials/MeshPhongMaterial.html @@ -13,10 +13,8 @@

    Phong网格材质([name])

    一种用于具有镜面高光的光泽表面的材质。

    该材质使用非物理的[link:https://en.wikipedia.org/wiki/Blinn-Phong_shading_model Blinn-Phong]模型来计算反射率。 - 与[page:MeshLambertMaterial]中使用的Lambertian模型不同,该材质可以模拟具有镜面高光的光泽表面(例如涂漆木材)。

    - 使用[link:https://en.wikipedia.org/wiki/Phong_shading Phong]着色模型计算着色时,会计算每个像素的阴影(在[link:https://en.wikipedia.org/wiki/Shader#Pixel_shaders fragment shader], - AKA pixel shader中),与[page:MeshLambertMaterial]使用的Gouraud模型相比,该模型的结果更准确,但代价是牺牲一些性能。 - [page:MeshStandardMaterial]和[page:MeshPhysicalMaterial]也使用这个着色模型。

    + 与[page:MeshLambertMaterial]中使用的Lambertian模型不同,该材质可以模拟具有镜面高光的光泽表面(例如涂漆木材)。[name] uses per-fragment shading。

    + 在[page:MeshStandardMaterial]或[page:MeshPhysicalMaterial]上使用此材质时,性能通常会更高 ,但会牺牲一些图形精度。

    diff --git a/docs/api/zh/materials/MeshPhysicalMaterial.html b/docs/api/zh/materials/MeshPhysicalMaterial.html index 9d55fcaff24632..fed77cfa5a8daf 100644 --- a/docs/api/zh/materials/MeshPhysicalMaterial.html +++ b/docs/api/zh/materials/MeshPhysicalMaterial.html @@ -25,6 +25,9 @@

    物理网格材质([name])

  • 高级光线反射: 为非金属材质提供了更多更灵活的光线反射。
  • +
  • + Sheen: Can be used for representing cloth and fabric materials. +
  • @@ -55,6 +58,7 @@

    例子

    [example:webgl_materials_variations_physical materials / variations / physical]
    [example:webgl_materials_physical_clearcoat materials / physical / clearcoat]
    [example:webgl_materials_physical_reflectivity materials / physical / reflectivity]
    + [example:webgl_loader_gltf_sheen loader / gltf / sheen]
    [example:webgl_materials_physical_transmission materials / physical / transmission]

    @@ -77,7 +81,7 @@

    [property:Color attenuationColor]

    [property:Float attenuationDistance]

    - Density of the medium given as the average distance that light travels in the medium before interacting with a particle. The value is given in world space. Default is *0*. + Density of the medium given as the average distance that light travels in the medium before interacting with a particle. The value is given in world space units, and must be greater than zero. Default is `Infinity`.

    [property:Float clearcoat]

    diff --git a/docs/api/zh/materials/MeshStandardMaterial.html b/docs/api/zh/materials/MeshStandardMaterial.html index abffeb887b6efa..cd8ce1614d04a3 100644 --- a/docs/api/zh/materials/MeshStandardMaterial.html +++ b/docs/api/zh/materials/MeshStandardMaterial.html @@ -18,12 +18,7 @@

    标准网格材质([name])

    这种方法与旧方法的不同之处在于,不使用近似值来表示光与表面的相互作用,而是使用物理上正确的模型。 我们的想法是,不是在特定照明下调整材质以使其看起来很好,而是可以创建一种材质,能够“正确”地应对所有光照场景。

    - 在实践中,该材质提供了比[page:MeshLambertMaterial] 或[page:MeshPhongMaterial] 更精确和逼真的结果,代价是计算成本更高。

    - - - 计算着色的方式与[page:MeshPhongMaterial]相同,都使用[link:https://en.wikipedia.org/wiki/Phong_shading Phong]着色模型, - 这会计算每个像素的阴影(即在[link:https://en.wikipedia.org/wiki/Shader#Pixel_shaders fragment shader], - AKA pixel shader中), 与[page:MeshLambertMaterial]使用的Gouraud模型相比,该模型的结果更准确,但代价是牺牲一些性能。

    + 在实践中,该材质提供了比[page:MeshLambertMaterial] 或[page:MeshPhongMaterial] 更精确和逼真的结果,代价是计算成本更高。[name] uses per-fragment shading。

    请注意,为获得最佳效果,您在使用此材质时应始终指定[page:.envMap environment map]。

    有关PBR概念的非技术性介绍以及如何设置PBR材质,请查看[link:https://www.marmoset.co marmoset]成员的这些文章: diff --git a/docs/api/zh/math/Euler.html b/docs/api/zh/math/Euler.html index f4d27c82d10a4c..0a11718514c925 100644 --- a/docs/api/zh/math/Euler.html +++ b/docs/api/zh/math/Euler.html @@ -145,14 +145,6 @@

    [method:Array toArray]( [param:Array array], [param:Integer offset] )

    返回一个数组:[[page:.x x], [page:.y y], [page:.z z], [page:.order order ]]。

    -

    [method:Vector3 toVector3]( [param:Vector3 optionalResult] )

    -

    - [page:Vector3 optionalResult] — (可选参数) 如果指定了该参数结果将会被复制给该参数,否者会创建一个新的 Vector3

    - - 以 [page:Vector3] 的形式返回欧拉角的 [page:.x x], [page:.y y] 和 [page:.z z]。 -

    - -

    源码(Source)

    diff --git a/docs/api/zh/math/MathUtils.html b/docs/api/zh/math/MathUtils.html index 6d357e3cc93f69..c16840b19b3f40 100644 --- a/docs/api/zh/math/MathUtils.html +++ b/docs/api/zh/math/MathUtils.html @@ -75,7 +75,7 @@

    [method:Float mapLinear]( [param:Float x], [param:Float a1], [param:Float a2 [page:Float a1] — A区间最小值。
    [page:Float a2] — A区间最大值。
    [page:Float b1] — B区间最小值。
    - [page:Float b2] — A区间最大值。

    + [page:Float b2] — B区间最大值。

    x从范围[[page:Float a1], [page:Float a2]] 到范围[[page:Float b1], [page:Float b2]]的线性映射。

    diff --git a/docs/api/zh/math/Matrix3.html b/docs/api/zh/math/Matrix3.html index 626ecc6ce9b6bb..03df1e51aa128b 100644 --- a/docs/api/zh/math/Matrix3.html +++ b/docs/api/zh/math/Matrix3.html @@ -123,6 +123,45 @@

    [method:this identity]()

    +

    [method:this makeRotation]( [param:Float theta] )

    +

    + [page:Float theta] — Rotation angle in radians. Positive values rotate counterclockwise.

    + + Sets this matrix as a 2D rotational transformation by [page:Float theta] radians. + The resulting matrix will be: + +cos(θ) -sin(θ) 0 +sin(θ) cos(θ) 0 +0 0 1 + +

    + +

    [method:this makeScale]( [param:Float x], [param:Float y] )

    +

    + [page:Float x] - the amount to scale in the X axis.
    + [page:Float y] - the amount to scale in the Y axis.
    + + Sets this matrix as a 2D scale transform: + +x, 0, 0, +0, y, 0, +0, 0, 1 + +

    + +

    [method:this makeTranslation]( [param:Float x], [param:Float y] )

    +

    + [page:Float x] - the amount to translate in the X axis.
    + [page:Float y] - the amount to translate in the Y axis.
    + + Sets this matrix as a 2D translation transform: + +1, 0, x, +0, 1, y, +0, 0, 1 + +

    +

    [method:this multiply]( [param:Matrix3 m] )

    将当前矩阵乘以矩阵[page:Matrix3 m]。

    @@ -156,7 +195,7 @@

    [method:this setUvTransform]( [param:Float tx], [param:Float ty], [param:Flo [page:Float ty] - y偏移量
    [page:Float sx] - x方向的重复比例
    [page:Float sy] - y方向的重复比例
    - [page:Float rotation] - 旋转(弧度)
    + [page:Float rotation] - 旋转, 弧度。Positive values rotate counterclockwise
    [page:Float cx] - 旋转中心x
    [page:Float cy] - 旋转中心y

    diff --git a/docs/api/zh/math/Vector3.html b/docs/api/zh/math/Vector3.html index abcb421244f945..7ed6f8c781c7d9 100644 --- a/docs/api/zh/math/Vector3.html +++ b/docs/api/zh/math/Vector3.html @@ -358,6 +358,11 @@

    [method:this setFromCylindrical]( [param:Cylindrical c] )

    [method:this setFromCylindricalCoords]( [param:Float radius], [param:Float theta], [param:Float y] )

    从圆柱坐标中的[page:Cylindrical radius]、[page:Cylindrical theta]和[page:Cylindrical y]设置该向量。

    +

    [method:this setFromEuler]( [param:Euler euler] )

    +

    + 根据指定的[page:Euler Euler Angle]的x、y、z分量来设置该向量的[page:.x x]、[page:.y y]、[page:.z z]分量。 +

    +

    [method:this setFromMatrixColumn]( [param:Matrix4 matrix], [param:Integer index] )

    从传入的四阶矩阵[page:Matrix4 matrix]由[page:Integer index]指定的列中, diff --git a/docs/api/zh/objects/LOD.html b/docs/api/zh/objects/LOD.html index 140982a986c9c4..ade60bffbf559b 100644 --- a/docs/api/zh/objects/LOD.html +++ b/docs/api/zh/objects/LOD.html @@ -70,16 +70,18 @@

    [property:Array levels]

    每一个层级都是一个对象,具有以下两个属性: [page:Object3D object] —— 在这个层次中将要显示的[page:Object3D]。
    - [page:Float distance] —— 将显示这一细节层次的距离。 + [page:Float distance] —— 将显示这一细节层次的距离。
    + [page:Float hysteresis] —— Threshold used to avoid flickering at LOD boundaries, as a fraction of distance.

    方法

    共有方法请参见其基类[page:Object3D]。

    -

    [method:this addLevel]( [param:Object3D object], [param:Float distance] )

    +

    [method:this addLevel]( [param:Object3D object], [param:Float distance], [param:Float hysteresis] )

    [page:Object3D object] —— 在这个层次中将要显示的[page:Object3D]。
    - [page:Float distance] —— 将显示这一细节层次的距离。

    + [page:Float distance] —— 将显示这一细节层次的距离。
    + [page:Float hysteresis] —— Threshold used to avoid flickering at LOD boundaries, as a fraction of distance. Default 0.0.

    添加在一定距离和更大范围内显示的网格。通常来说,距离越远,网格中的细节就越少。

    @@ -99,7 +101,7 @@

    [method:Object3D getObjectForDistance]( [param:Float distance] )

    获得第一个比[page:Float distance]大的[page:Object3D](网格)的引用。

    -

    [method:Array raycast]( [param:Raycaster raycaster], [param:Array intersects] )

    +

    [method:undefined raycast]( [param:Raycaster raycaster], [param:Array intersects] )

    在一条投射出去的[page:Ray](射线)和这个LOD之间获得交互。 [page:Raycaster.intersectObject]将会调用这个方法。 diff --git a/docs/api/zh/renderers/WebGLCubeRenderTarget.html b/docs/api/zh/renderers/WebGLCubeRenderTarget.html index f24b861714b846..16c62fa168bea0 100644 --- a/docs/api/zh/renderers/WebGLCubeRenderTarget.html +++ b/docs/api/zh/renderers/WebGLCubeRenderTarget.html @@ -25,7 +25,7 @@

    构造器

    [name]([param:Number size], [param:Object options])

    - [page:Float size] - the size, in pixels.
    + [page:Float size] - the size, in pixels. Default is `1`.
    options - (可选)一个保存着自动生成的目标纹理的纹理参数以及表示是否使用深度缓存/模板缓存的布尔值的对象。 有关纹理参数的说明,请参阅[page:Texture Texture]. 以下是合理选项:

    diff --git a/docs/api/zh/renderers/WebGLMultipleRenderTargets.html b/docs/api/zh/renderers/WebGLMultipleRenderTargets.html index aab362228ec9c2..b4c9f3d7e2ee6e 100644 --- a/docs/api/zh/renderers/WebGLMultipleRenderTargets.html +++ b/docs/api/zh/renderers/WebGLMultipleRenderTargets.html @@ -30,9 +30,9 @@

    Constructor

    [name]([param:Number width], [param:Number height], [param:Number count])

    - [page:Number width] - The width of the render target.
    - [page:Number height] - The height of the render target.
    - [page:Number count] - The number of render targets. + [page:Number width] - The width of the render target. Default is `1`.
    + [page:Number height] - The height of the render target. Default is `1`.
    + [page:Number count] - The number of render targets. Default is `1`.

    Properties

    diff --git a/docs/api/zh/renderers/WebGLRenderTarget.html b/docs/api/zh/renderers/WebGLRenderTarget.html index b0608471d6c8cd..edc56ae8242267 100644 --- a/docs/api/zh/renderers/WebGLRenderTarget.html +++ b/docs/api/zh/renderers/WebGLRenderTarget.html @@ -22,8 +22,8 @@

    构造器

    [name]([param:Number width], [param:Number height], [param:Object options])

    - [page:Float width] -renderTarget的宽度
    - [page:Float height] - renderTarget的高度
    + [page:Float width] -renderTarget的宽度. Default is `1`.
    + [page:Float height] - renderTarget的高度. Default is `1`.
    options - (可选)一个保存着自动生成的目标纹理的纹理参数以及表示是否使用深度缓存/模板缓存的布尔值的对象 以下是一些合法选项:

    @@ -31,13 +31,14 @@

    [name]([param:Number width], [param:Number height], [param:Object options])< [page:Constant wrapT] - 默认是[page:Textures ClampToEdgeWrapping].
    [page:Constant magFilter] - 默认是[page:Textures LinearFilter].
    [page:Constant minFilter] - 默认是[page:Textures LinearFilter].
    - [page:Boolean generateMipmaps] - 默认是*false*.
    + [page:Boolean generateMipmaps] - 默认是`false`.
    [page:Constant format] - 默认是[page:Textures RGBAFormat].
    [page:Constant type] - 默认是[page:Textures UnsignedByteType].
    - [page:Number anisotropy] - 默认是*1*. 参见[page:Texture.anisotropy]
    + [page:Number anisotropy] - 默认是`1`. 参见[page:Texture.anisotropy]
    [page:Constant encoding] - 默认是[page:Textures LinearEncoding].
    - [page:Boolean depthBuffer] - 默认是*true*.
    - [page:Boolean stencilBuffer] - 默认是*false*.

    + [page:Boolean depthBuffer] - 默认是`true`.
    + [page:Boolean stencilBuffer] - 默认是`false`.
    + [page:Number samples] - 默认是`0`.

    创建一个新[name]

    diff --git a/docs/api/zh/renderers/WebGLRenderer.html b/docs/api/zh/renderers/WebGLRenderer.html index 56ec054733ac64..57f8e119da9ed6 100644 --- a/docs/api/zh/renderers/WebGLRenderer.html +++ b/docs/api/zh/renderers/WebGLRenderer.html @@ -335,7 +335,7 @@

    [method:undefined resetGLState]( )

    [method:undefined readRenderTargetPixels]( [param:WebGLRenderTarget renderTarget], [param:Float x], [param:Float y], [param:Float width], [param:Float height], [param:TypedArray buffer], [param:Integer activeCubeFaceIndex] )

    buffer - Uint8Array is the only destination type supported in all cases, other types are renderTarget and platform dependent. See [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.12 WebGL spec] for details.

    -

    将enderTarget中的像素数据读取到传入的缓冲区中。这是[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/readPixels WebGLRenderingContext.readPixels]()的包装器
    +

    将renderTarget中的像素数据读取到传入的缓冲区中。这是[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/readPixels WebGLRenderingContext.readPixels]()的包装器
    示例:[example:webgl_interactive_cubes_gpu interactive / cubes / gpu]

    For reading out a [page:WebGLCubeRenderTarget WebGLCubeRenderTarget] use the optional parameter activeCubeFaceIndex to determine which face should be read.

    diff --git a/docs/api/zh/renderers/webgl/WebGLProgram.html b/docs/api/zh/renderers/webgl/WebGLProgram.html index 770c0c78857f86..764abe0c6d61ca 100644 --- a/docs/api/zh/renderers/webgl/WebGLProgram.html +++ b/docs/api/zh/renderers/webgl/WebGLProgram.html @@ -35,7 +35,7 @@

    顶点着色器(无条件的):

    uniform vec3 cameraPosition;
    - // default vertex attributes provided by Geometry and BufferGeometry + // default vertex attributes provided by BufferGeometry attribute vec3 position; attribute vec3 normal; attribute vec2 uv; @@ -55,6 +55,9 @@

    顶点着色器(无条件的):

    顶点着色器(有条件的):

    + #ifdef USE_TANGENT + attribute vec4 tangent; + #endif #if defined( USE_COLOR_ALPHA ) // vertex color attribute with alpha attribute vec4 color; diff --git a/docs/api/zh/renderers/webxr/WebXRManager.html b/docs/api/zh/renderers/webxr/WebXRManager.html index 1ff660a44cef37..8c5a0caf4fc79e 100644 --- a/docs/api/zh/renderers/webxr/WebXRManager.html +++ b/docs/api/zh/renderers/webxr/WebXRManager.html @@ -77,6 +77,11 @@

    [method:Group getHand]( [param:Integer index] )

    Use this space for visualizing the user's hands when no physical controllers are used.

    +

    [method:Set getPlanes]()

    +

    + Returns the set of planes detected by WebXR's plane detection API. +

    +

    [method:String getReferenceSpace]()

    Returns the reference space. @@ -87,9 +92,10 @@

    [method:XRSession getSession]()

    Returns the *XRSession* object which allows a more fine-grained management of active WebXR sessions on application level.

    -

    [method:undefined setFramebufferScaleFactor]( [param:Float framebufferScaleFactor] )

    +

    [method:undefined setFramebufferScaleFactor]( [param:Float factor], [param:Boolean limited] )

    - [page:Float framebufferScaleFactor] — The framebuffer scale factor to set.

    + [page:Float factor] — The framebuffer scale factor to set.
    + [page:Boolean limited] — Whether the framebuffer scale factor should be reduced to the native limit if the value ends up being higher than the device's capabilities. Default is `false`.

    Specifies the scaling factor to use when determining the size of the framebuffer when rendering to a XR device. The value is relative to the default XR device display resolution. Default is *1*. A value of *0.5* would specify diff --git a/docs/api/zh/scenes/Scene.html b/docs/api/zh/scenes/Scene.html index 65d4396977af18..b98c97efa96d49 100644 --- a/docs/api/zh/scenes/Scene.html +++ b/docs/api/zh/scenes/Scene.html @@ -25,12 +25,6 @@

    [name]()

    属性

    -

    [property:Boolean autoUpdate]

    -

    - 默认值为true,若设置了这个值,则渲染器会检查每一帧是否需要更新场景及其中物体的矩阵。 - 当设为false时,你必须亲自手动维护场景中的矩阵。 -

    -

    [property:Object background]

    若不为空,在渲染场景的时候将设置背景,且背景总是首先被渲染的。 @@ -38,6 +32,11 @@

    [property:Object background]

    或是 a cubemap as a [page:CubeTexture] or an equirectangular as a [page:Texture]。默认值为null。

    +

    [property:Float backgroundBlurriness]

    +

    + Sets the blurriness of the background. Only influences environment maps assigned to [page:Scene.background]. Valid input is a float between *0* and *1*. Default is *0*. +

    +

    [property:Texture environment]

    若该值不为null,则该纹理贴图将会被设为场景中所有物理材质的环境贴图。 diff --git a/docs/api/zh/textures/CompressedArrayTexture.html b/docs/api/zh/textures/CompressedArrayTexture.html new file mode 100644 index 00000000000000..8383f04f18c6e8 --- /dev/null +++ b/docs/api/zh/textures/CompressedArrayTexture.html @@ -0,0 +1,75 @@ + + + + + + + + + + [page:CompressedTexture] → + +

    [name]

    + +

    + Creates an texture 2D array based on data in compressed form, for example from a [link:https://en.wikipedia.org/wiki/DirectDraw_Surface DDS] file.

    + + + For use with the [page:CompressedTextureLoader CompressedTextureLoader]. +

    + + +

    Constructor

    + + +

    [name]( [param:Array mipmaps], [param:Number width], [param:Number height], [param:Constant format], [param:Constant type] )

    +

    + [page:Array mipmaps] -- The mipmaps array should contain objects with data, width and height. The mipmaps should be of the correct format and type.
    + + [page:Number width] -- The width of the biggest mipmap.
    + + [page:Number height] -- The height of the biggest mipmap.
    + + [page:Number depth] -- The number of layers of the 2D array texture.
    + + [page:Constant format] -- The format used in the mipmaps. + See [page:Textures ST3C Compressed Texture Formats], + [page:Textures PVRTC Compressed Texture Formats] and + [page:Textures ETC Compressed Texture Format] for other choices.
    + + [page:Constant type] -- Default is [page:Textures THREE.UnsignedByteType]. + See [page:Textures type constants] for other choices.
    + +

    + + +

    Properties

    + + See the base [page:CompressedTexture CompressedTexture] class for common properties. + +

    [property:number wrapR]

    +

    + This defines how the texture is wrapped in the depth direction.
    + The default is [page:Textures THREE.ClampToEdgeWrapping], where the edge is clamped to the outer edge texels. + The other two choices are [page:Textures THREE.RepeatWrapping] and [page:Textures THREE.MirroredRepeatWrapping]. + See the [page:Textures texture constants] page for details. +

    + +

    [property:Boolean isCompressedArrayTexture]

    +

    + Read-only flag to check if a given object is of type [name]. +

    + +

    Methods

    + +

    + See the base [page:CompressedTexture CompressedTexture] class for common methods. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/zh/textures/Source.html b/docs/api/zh/textures/Source.html index 82ee9b466d771a..6ecccd4814554a 100644 --- a/docs/api/zh/textures/Source.html +++ b/docs/api/zh/textures/Source.html @@ -40,7 +40,7 @@

    [property:String uuid]

    [property:Integer version]

    - This starts at *0* and counts how many times [property:Boolean needsUpdate] is set to *true*. + This starts at *0* and counts how many times [page:Source.needsUpdate .needsUpdate] is set to *true*.

    Methods

    diff --git a/docs/api/zh/textures/VideoTexture.html b/docs/api/zh/textures/VideoTexture.html index f5c62682ec1243..5a6b41683fcd67 100644 --- a/docs/api/zh/textures/VideoTexture.html +++ b/docs/api/zh/textures/VideoTexture.html @@ -12,9 +12,11 @@

    视频纹理([name])

    - 创建一个使用视频来作为贴图的纹理对象。

    + 创建一个使用视频来作为贴图的纹理对象。 +

    - 它和其基类[page:Texture Texture]几乎是相同的,除了它总是将[page:Texture.needsUpdate needsUpdate]设置为*true*,以便使得贴图能够在视频播放时进行更新。自动创建[page:Texture.mipmaps mipmaps]也会被禁用。 +

    + Note: After the initial use of a texture, the video cannot be changed. Instead, call [page:.dispose]() on the texture and instantiate a new one.

    代码示例

    @@ -27,7 +29,13 @@

    代码示例

    例子

    -

    [example:webgl_materials_video materials / video ]

    +

    + [example:webgl_materials_video materials / video]
    + [example:webgl_materials_video_webcam materials / video / webcam]
    + [example:webgl_video_kinect video / kinect]
    + [example:webgl_video_panorama_equirectangular video / panorama / equirectangular]
    + [example:webxr_vr_video vr / video] +

    构造函数

    [name]( [param:Video video], [param:Constant mapping], [param:Constant wrapS], [param:Constant wrapT], [param:Constant magFilter], [param:Constant minFilter], [param:Constant format], [param:Constant type], [param:Number anisotropy] )

    @@ -47,7 +55,7 @@

    [name]( [param:Video video], [param:Constant mapping], [param:Constant wrapS 其默认值为[page:Textures THREE.LinearFilter]。请参阅[page:Textures magnification filter constants](放大滤镜常量)来了解其它选项。
    [page:Constant minFilter] -- 当一个纹素覆盖小于一个像素时,贴图将如何采样。 - 其默认值为[page:Textures THREE.LinearMipmapLinearFilter]。请参阅[page:Textures minification filter constants](缩小滤镜常量)来了解其它选项。
    + 其默认值为[page:Textures THREE.LinearFilter]。请参阅[page:Textures minification filter constants](缩小滤镜常量)来了解其它选项。
    [page:Constant format] -- The default is [page:Textures THREE.RGBAFormat]. 请参阅[page:Textures format constants](格式常量)来了解各个选项。
    @@ -69,7 +77,7 @@

    属性

    [property:Boolean generateMipmaps]

    - Whether to generate mipmaps. False by default. + Whether to generate mipmaps. `false` by default.

    [property:Boolean isVideoTexture]

    @@ -79,7 +87,7 @@

    [property:Boolean isVideoTexture]

    [property:Boolean needsUpdate]

    - 在这里,你不必手动设置这个值,因为它是由[page:VideoTexture.update update]方法来进行控制的。 + 在这里,你不必手动设置这个值,因为它是由[page:VideoTexture.update update]()方法来进行控制的。

    方法

    diff --git a/docs/examples/en/animations/CCDIKSolver.html b/docs/examples/en/animations/CCDIKSolver.html index db4f6f34e79e68..7025708e0d6cb1 100644 --- a/docs/examples/en/animations/CCDIKSolver.html +++ b/docs/examples/en/animations/CCDIKSolver.html @@ -105,6 +105,7 @@

    Code Example

    Examples

    + [example:webgl_animation_skinning_ik]
    [example:webgl_loader_mmd]
    [example:webgl_loader_mmd_pose]
    [example:webgl_loader_mmd_audio] diff --git a/docs/examples/en/controls/OrbitControls.html b/docs/examples/en/controls/OrbitControls.html index 20bbac2f1aa592..c7429566a84a04 100644 --- a/docs/examples/en/controls/OrbitControls.html +++ b/docs/examples/en/controls/OrbitControls.html @@ -94,7 +94,7 @@

    [property:Float autoRotateSpeed]

    [property:Float dampingFactor]

    - The damping inertia used if [page:.enableDamping] is set to true.
    Note that for this to work, you must + The damping inertia used if [page:.enableDamping] is set to `true`. Default is `0.05`.
    Note that for this to work, you must call [page:.update] () in your animation loop.

    diff --git a/docs/examples/en/exporters/GLTFExporter.html b/docs/examples/en/exporters/GLTFExporter.html index 170fcd820bceec..4c5312a1ee6a07 100644 --- a/docs/examples/en/exporters/GLTFExporter.html +++ b/docs/examples/en/exporters/GLTFExporter.html @@ -117,7 +117,6 @@

    [method:undefined parse]( [param:Object3D input], [param:Function onComplete
    • trs - bool. Export position, rotation and scale instead of matrix per node. Default is false
    • onlyVisible - bool. Export only visible objects. Default is true.
    • -
    • truncateDrawRange - bool. Export just the attributes within the drawRange, if defined, instead of exporting the whole array. Default is true.
    • binary - bool. Export in binary (.glb) format, returning an ArrayBuffer. Default is false.
    • maxTextureSize - int. Restricts the image maximum size (both width and height) to the given value. Default is Infinity.
    • animations - Array<[page:AnimationClip AnimationClip]>. List of animations to be included in the export.
    • diff --git a/docs/examples/en/helpers/LightProbeHelper.html b/docs/examples/en/helpers/LightProbeHelper.html index 1655913fec67b1..328e5cbd3059a0 100644 --- a/docs/examples/en/helpers/LightProbeHelper.html +++ b/docs/examples/en/helpers/LightProbeHelper.html @@ -48,7 +48,9 @@

      Methods

      See the base [page:Mesh] class for common methods.

      [method:undefined dispose]()

      -

      Frees internal resources.

      +

      + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

      Source

      diff --git a/docs/examples/en/helpers/PositionalAudioHelper.html b/docs/examples/en/helpers/PositionalAudioHelper.html index b5e11308d8e018..abc75a9d7ce7fe 100644 --- a/docs/examples/en/helpers/PositionalAudioHelper.html +++ b/docs/examples/en/helpers/PositionalAudioHelper.html @@ -7,7 +7,7 @@ - [page:Object3D] → + [page:Object3D] → [page:Line] →

      [name]

      @@ -56,14 +56,16 @@

      [property:Number divisionsOuterAngle]

      The amount of divisions of the outer part of the directional cone.

      Methods

      -

      See the base [page:Object3D] class for common methods.

      - -

      [method:undefined dispose]()

      -

      Disposes of the helper.

      +

      See the base [page:Line] class for common methods.

      [method:undefined update]()

      Updates the helper.

      +

      [method:undefined dispose]()

      +

      + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

      +

      Source

      diff --git a/docs/examples/en/helpers/RectAreaLightHelper.html b/docs/examples/en/helpers/RectAreaLightHelper.html index 4226f9cb55e03f..096fd880ae9e7e 100644 --- a/docs/examples/en/helpers/RectAreaLightHelper.html +++ b/docs/examples/en/helpers/RectAreaLightHelper.html @@ -7,7 +7,7 @@ - [page:Object3D] → + [page:Object3D] → [page:Line] →

      [name]

      @@ -48,10 +48,12 @@

      [property:hex color]

      Methods

      -

      See the base [page:Object3D] class for common methods.

      +

      See the base [page:Line] class for common methods.

      [method:undefined dispose]()

      -

      Dispose of the rectAreaLightHelper.

      +

      + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

      Source

      diff --git a/docs/examples/en/helpers/VertexNormalsHelper.html b/docs/examples/en/helpers/VertexNormalsHelper.html index 6a1daf31d7fd92..e8c9fe2732e3ce 100644 --- a/docs/examples/en/helpers/VertexNormalsHelper.html +++ b/docs/examples/en/helpers/VertexNormalsHelper.html @@ -7,12 +7,12 @@ - [page:Object3D] → [page:Line] → + [page:Object3D] → [page:Line] → [page:LineSegments] →

      [name]

      - Renders [page:ArrowHelper arrows] to visualize an object's vertex normal vectors. + Visualizes an object's vertex normals. Requires that normals have been specified in a [page:BufferAttribute custom attribute] or have been calculated using [page:BufferGeometry.computeVertexNormals computeVertexNormals].

      @@ -21,12 +21,12 @@

      Code Example

      const geometry = new THREE.BoxGeometry( 10, 10, 10, 2, 2, 2 ); - const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); - const box = new THREE.Mesh( geometry, material ); + const material = new THREE.MeshStandardMaterial(); + const mesh = new THREE.Mesh( geometry, material ); - const helper = new VertexNormalsHelper( box, 2, 0x00ff00, 1 ); + const helper = new VertexNormalsHelper( mesh, 1, 0xff0000 ); - scene.add( box ); + scene.add( mesh ); scene.add( helper ); @@ -38,12 +38,11 @@

      Examples

      Constructor

      -

      [name]( [param:Object3D object], [param:Number size], [param:Hex color], [param:Number linewidth] )

      +

      [name]( [param:Object3D object], [param:Number size], [param:Hex color] )

      [page:Object3D object] -- object for which to render vertex normals.
      - [page:Number size] -- (optional) length of the arrows. Default is 1.
      - [page:Hex color] -- hex color of the arrows. Default is 0xff0000.
      - [page:Number linewidth] -- (optional) width of the arrow lines. Default is 1. + [page:Number size] -- (optional) length of the arrows. Default is *1*.
      + [page:Hex color] -- (optional) hex color of the arrows. Default is *0xff0000*.

      @@ -68,8 +67,12 @@

      Methods

      [method:undefined update]()

      -

      Updates the vertex normal preview based on movement of the object.

      +

      Updates the vertex tangents preview based on the object's world transform.

      +

      [method:undefined dispose]()

      +

      + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

      Source

      diff --git a/docs/examples/en/helpers/VertexTangentsHelper.html b/docs/examples/en/helpers/VertexTangentsHelper.html index 5bacbbd591f544..21b38592573047 100644 --- a/docs/examples/en/helpers/VertexTangentsHelper.html +++ b/docs/examples/en/helpers/VertexTangentsHelper.html @@ -12,22 +12,21 @@

      [name]

      - Renders arrows to visualize an object's vertex tangent vectors. + Visualizes an object's vertex tangents. Requires that tangents have been specified in a [page:BufferAttribute custom attribute] or have been calculated using [page:BufferGeometry.computeTangents computeTangents].

      - - This helper supports [page:BufferGeometry] only.

      Code Example

      + const geometry = new THREE.BoxGeometry( 10, 10, 10, 2, 2, 2 ); - const material = new THREE.MeshNormalMaterial(); - const box = new THREE.Mesh( geometry, material ); + const material = new THREE.MeshStandardMaterial(); + const mesh = new THREE.Mesh( geometry, material ); - const helper = new VertexTangentsHelper( box, 1, 0x00ffff, 1 ); + const helper = new VertexTangentsHelper( mesh, 1, 0x00ffff ); - scene.add( box ); + scene.add( mesh ); scene.add( helper ); @@ -39,12 +38,11 @@

      Examples

      Constructor

      -

      [name]( [param:Object3D object], [param:Number size], [param:Hex color], [param:Number linewidth] )

      +

      [name]( [param:Object3D object], [param:Number size], [param:Hex color] )

      [page:Object3D object] -- object for which to render vertex tangents.
      [page:Number size] -- (optional) length of the arrows. Default is *1*.
      - [page:Hex color] -- hex color of the arrows. Default is 0x00ffff.
      - [page:Number linewidth] -- (optional) width of the arrow lines. Default is *1*. (Setting lineWidth is currently not supported.) + [page:Hex color] -- (optional) hex color of the arrows. Default is *0x00ffff*.

      @@ -71,6 +69,10 @@

      Methods

      [method:undefined update]()

      Updates the vertex tangents preview based on the object's world transform.

      +

      [method:undefined dispose]()

      +

      + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

      Source

      diff --git a/docs/examples/en/loaders/GLTFLoader.html b/docs/examples/en/loaders/GLTFLoader.html index 99e67d46bd4ee0..85caa001577078 100644 --- a/docs/examples/en/loaders/GLTFLoader.html +++ b/docs/examples/en/loaders/GLTFLoader.html @@ -36,7 +36,6 @@

      Extensions

    • KHR_draco_mesh_compression
    • KHR_materials_clearcoat
    • KHR_materials_ior
    • -
    • KHR_materials_pbrSpecularGlossiness
    • KHR_materials_specular
    • KHR_materials_transmission
    • KHR_materials_iridescence
    • @@ -48,6 +47,7 @@

      Extensions

    • KHR_texture_transform2
    • EXT_texture_webp
    • EXT_meshopt_compression
    • +
    • EXT_mesh_gpu_instancing

    @@ -221,13 +221,13 @@

    [method:this setKTX2Loader]( [param:KTX2Loader ktx2Loader] )

    [method:undefined parse]( [param:ArrayBuffer data], [param:String path], [param:Function onLoad], [param:Function onError] )

    - [page:ArrayBuffer data] — glTF asset to parse, as an ArrayBuffer or `JSON` string.
    + [page:ArrayBuffer data] — glTF asset to parse, as an `ArrayBuffer`, `JSON` string or object.
    [page:String path] — The base path from which to find subsequent glTF resources such as textures and .bin data files.
    [page:Function onLoad] — A function to be called when parse completes.
    [page:Function onError] — (optional) A function to be called if an error occurs during parsing. The function receives error as an argument.

    - Parse a glTF-based ArrayBuffer or `JSON` String and fire [page:Function onLoad] callback when complete. The argument to [page:Function onLoad] will be an [page:Object] that contains loaded parts: .[page:Group scene], .[page:Array scenes], .[page:Array cameras], .[page:Array animations], and .[page:Object asset]. + Parse a glTF-based `ArrayBuffer`, `JSON` string or object and fire [page:Function onLoad] callback when complete. The argument to [page:Function onLoad] will be an [page:Object] that contains loaded parts: .[page:Group scene], .[page:Array scenes], .[page:Array cameras], .[page:Array animations], and .[page:Object asset].

    Source

    diff --git a/docs/examples/en/loaders/LDrawLoader.html b/docs/examples/en/loaders/LDrawLoader.html index 7aa28b1c6e7834..a7132bcf4a430f 100644 --- a/docs/examples/en/loaders/LDrawLoader.html +++ b/docs/examples/en/loaders/LDrawLoader.html @@ -62,7 +62,7 @@

    Code Example

    // Optionally, use LDrawUtils.mergeObject() from // 'examples/jsm/utils/LDrawUtils.js' to merge all // geometries by material (it gives better runtime - // performance, but construction steps are lost) + // performance, but building steps are lost) // group = LDrawUtils.mergeObject( group ); scene.add( group ); @@ -103,10 +103,10 @@

    Metadata in .userData

    type, its .userData member will contain the following members:
    In a [page:Group], the userData member will contain:
      -
    • .numConstructionSteps: Only in the root [page:Group], Indicates total number of construction steps in - the model. These can be used to set visibility of objects to show different construction steps, which is +
    • .numBuildingSteps: Only in the root [page:Group], Indicates total number of building steps in + the model. These can be used to set visibility of objects to show different building steps, which is done in the example.
    • -
    • .constructionStep: Indicates the construction index of this step.
    • +
    • .buildingStep: Indicates the building index of this step.
    • .category: Contains, if not null, the [page:String] category for this piece or model.
    • .keywords: Contains, if not null, an array of [page:String] keywords for this piece or model.
    diff --git a/docs/examples/en/loaders/PCDLoader.html b/docs/examples/en/loaders/PCDLoader.html index b940f1e5af2d49..9b1eb3eb7493bb 100644 --- a/docs/examples/en/loaders/PCDLoader.html +++ b/docs/examples/en/loaders/PCDLoader.html @@ -11,9 +11,15 @@

    [name]

    -

    A loader for loading a `.pcd` resource.
    - Point Cloud Data is a file format for Point Cloud Library.
    - Loader support ascii and (compressed) binary. +

    + A loader for the PCD (Point Cloud Data) file format. [name] supports ASCII and (compressed) binary files as well as the following PCD fields: +

      +
    • x y z
    • +
    • rgb
    • +
    • normal_x normal_y normal_z
    • +
    • intensity
    • +
    • label
    • +

    Code Example

    @@ -28,9 +34,9 @@

    Code Example

    // resource URL 'pointcloud.pcd', // called when the resource is loaded - function ( mesh ) { + function ( points ) { - scene.add( mesh ); + scene.add( points ); }, // called when loading is in progresses diff --git a/docs/examples/en/postprocessing/EffectComposer.html b/docs/examples/en/postprocessing/EffectComposer.html index f5cae1ef5fefe7..db89c9451d3b6d 100644 --- a/docs/examples/en/postprocessing/EffectComposer.html +++ b/docs/examples/en/postprocessing/EffectComposer.html @@ -89,6 +89,11 @@

    [method:undefined addPass]( [param:Pass pass] )

    Adds the given pass to the pass chain.

    +

    [method:undefined dispose]()

    +

    + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

    +

    [method:undefined insertPass]( [param:Pass pass], [param:Integer index] )

    diff --git a/docs/examples/en/utils/BufferGeometryUtils.html b/docs/examples/en/utils/BufferGeometryUtils.html index 8a008d0a785c10..08af0f8e6d1b54 100644 --- a/docs/examples/en/utils/BufferGeometryUtils.html +++ b/docs/examples/en/utils/BufferGeometryUtils.html @@ -16,24 +16,52 @@

    [name]

    Methods

    -

    [method:BufferGeometry mergeBufferGeometries]( [param:Array geometries], [param:Boolean useGroups] )

    +

    [method:Object computeMikkTSpaceTangents]( [param:BufferGeometry geometry], [param:Object MikkTSpace], [param:Boolean negateSign] = true )

    +
      +
    • geometry -- Instance of [page:BufferGeometry].
    • +
    • MikkTSpace -- Instance of examples/jsm/libs/mikktspace.module.js, or mikktspace npm package. Await MikkTSpace.ready before use. +
    • negateSign -- Whether to negate the sign component (.w) of each tangent. Required for normal map conventions in some formats, including glTF.
    • +
    +

    - geometries -- Array of [page:BufferGeometry BufferGeometry] instances.
    - useGroups -- Whether groups should be generated for the merged geometry or not.

    + Computes vertex tangents using the [link:http://www.mikktspace.com/ MikkTSpace] algorithm. + MikkTSpace generates the same tangents consistently, and is used in most modelling tools and + normal map bakers. Use MikkTSpace for materials with normal maps, because inconsistent + tangents may lead to subtle visual issues in the normal map, particularly around mirrored + UV seams. +

    - Merges a set of geometries into a single instance. All geometries must have compatible attributes. - If merge does not succeed, the method returns null. +

    + In comparison to this method, [page:BufferGeometry.computeTangents] (a + custom algorithm) generates tangents that probably will not match the tangents + in other software. The custom algorithm is sufficient for general use with a + [page:ShaderMaterial], and may be faster than MikkTSpace. +

    +

    + Returns the original [page:BufferGeometry]. Indexed geometries will be de-indexed. + Requires position, normal, and uv attributes.

    -

    [method:BufferAttribute mergeBufferAttributes]( [param:Array attributes] )

    +

    [method:Object computeMorphedAttributes]( [param:Mesh | Line | Points object] )

    - attributes -- Array of [page:BufferAttribute BufferAttribute] instances.

    + object -- Instance of [page:Mesh Mesh] | [page:Line Line] | [page:Points Points].

    - Merges a set of attributes into a single instance. All attributes must have compatible properties - and types, and [page:InterleavedBufferAttribute InterleavedBufferAttributes] are not supported. If merge does not succeed, the method - returns null. + Returns the current attributes (Position and Normal) of a morphed/skinned [page:Object3D Object3D] whose geometry is a + [page:BufferGeometry BufferGeometry], together with the original ones: An Object with 4 properties: + `positionAttribute`, `normalAttribute`, `morphedPositionAttribute` and `morphedNormalAttribute`. + Helpful for Raytracing or Decals (i.e. a [page:DecalGeometry DecalGeometry] applied to a morphed Object + with a [page:BufferGeometry BufferGeometry] will use the original BufferGeometry, not the morphed/skinned one, + generating an incorrect result. + Using this function to create a shadow Object3D the DecalGeometry can be correctly generated). +

    + +

    [method:Number estimateBytesUsed]( [param:BufferGeometry geometry] )

    +

    + geometry -- Instance of [page:BufferGeometry BufferGeometry] to estimate the memory use of.

    + + Returns the amount of bytes used by all attributes to represent the geometry.

    [method:InterleavedBufferAttribute interleaveAttributes]( [param:Array attributes] )

    @@ -46,11 +74,23 @@

    [method:InterleavedBufferAttribute interleaveAttributes]( [param:Array attri

    -

    [method:Number estimateBytesUsed]( [param:BufferGeometry geometry] )

    +

    [method:BufferAttribute mergeBufferAttributes]( [param:Array attributes] )

    - geometry -- Instance of [page:BufferGeometry BufferGeometry] to estimate the memory use of.

    + attributes -- Array of [page:BufferAttribute BufferAttribute] instances.

    - Returns the amount of bytes used by all attributes to represent the geometry. + Merges a set of attributes into a single instance. All attributes must have compatible properties + and types, and [page:InterleavedBufferAttribute InterleavedBufferAttributes] are not supported. If merge does not succeed, the method + returns null. + +

    + +

    [method:BufferGeometry mergeBufferGeometries]( [param:Array geometries], [param:Boolean useGroups] )

    +

    + geometries -- Array of [page:BufferGeometry BufferGeometry] instances.
    + useGroups -- Whether groups should be generated for the merged geometry or not.

    + + Merges a set of geometries into a single instance. All geometries must have compatible attributes. + If merge does not succeed, the method returns null.

    @@ -71,56 +111,20 @@

    [method:BufferGeometry mergeVertices]( [param:BufferGeometry geometry], [par

    -

    [method:BufferGeometry toTrianglesDrawMode]( [param:BufferGeometry geometry], [param:TrianglesDrawMode drawMode] )

    +

    [method:BufferGeometry toCreasedNormals]( [param:BufferGeometry geometry], [param:Number creaseAngle] )

    - geometry -- Instance of [page:BufferGeometry BufferGeometry].
    - drawMode -- The draw mode of the given geometry.

    - - Returns a new indexed [page:BufferGeometry BufferGeometry] based on the [page:DrawModes THREE.TrianglesDrawMode] draw mode. This mode - corresponds to the `gl.TRIANGLES` WebGL primitive. - -

    - -

    [method:Object computeMorphedAttributes]( [param:Mesh | Line | Points object] )

    -

    - object -- Instance of [page:Mesh Mesh] | [page:Line Line] | [page:Points Points].

    - - Returns the current attributes (Position and Normal) of a morphed/skinned [page:Object3D Object3D] whose geometry is a - [page:BufferGeometry BufferGeometry], together with the original ones: An Object with 4 properties: - `positionAttribute`, `normalAttribute`, `morphedPositionAttribute` and `morphedNormalAttribute`. - - Helpful for Raytracing or Decals (i.e. a [page:DecalGeometry DecalGeometry] applied to a morphed Object - with a [page:BufferGeometry BufferGeometry] will use the original BufferGeometry, not the morphed/skinned one, - generating an incorrect result. - Using this function to create a shadow Object3D the DecalGeometry can be correctly generated). + geometry -- The input geometry.
    + creaseAngle -- The crease angle.

    + Creates a new, non-indexed geometry with smooth normals everywhere except faces that meet at an angle greater than the crease angle.

    -

    [method:Object computeMikkTSpaceTangents]( [param:BufferGeometry geometry], [param:Object MikkTSpace], [param:Boolean negateSign] = true )

    -
      -
    • geometry -- Instance of [page:BufferGeometry].
    • -
    • MikkTSpace -- Instance of examples/jsm/libs/mikktspace.module.js, or mikktspace npm package. Await MikkTSpace.ready before use. -
    • negateSign -- Whether to negate the sign component (.w) of each tangent. Required for normal map conventions in some formats, including glTF.
    • -
    - -

    - Computes vertex tangents using the [link:http://www.mikktspace.com/ MikkTSpace] algorithm. - MikkTSpace generates the same tangents consistently, and is used in most modelling tools and - normal map bakers. Use MikkTSpace for materials with normal maps, because inconsistent - tangents may lead to subtle visual issues in the normal map, particularly around mirrored - UV seams. -

    - +

    [method:BufferGeometry toTrianglesDrawMode]( [param:BufferGeometry geometry], [param:TrianglesDrawMode drawMode] )

    - In comparison to this method, [page:BufferGeometry.computeTangents] (a - custom algorithm) generates tangents that probably will not match the tangents - in other software. The custom algorithm is sufficient for general use with a - [page:ShaderMaterial], and may be faster than MikkTSpace. -

    + geometry -- Instance of [page:BufferGeometry BufferGeometry].
    + drawMode -- The draw mode of the given geometry. Valid inputs are `THREE.TriangleStripDrawMode` and `THREE.TriangleFanDrawMode`.

    -

    - Returns the original [page:BufferGeometry]. Indexed geometries will be de-indexed. - Requires position, normal, and uv attributes. + Returns a new indexed geometry based on `THREE.TrianglesDrawMode` draw mode. This mode corresponds to the `gl.TRIANGLES` WebGL primitive.

    Source

    diff --git a/docs/examples/en/utils/SceneUtils.html b/docs/examples/en/utils/SceneUtils.html index d8e8e34446bece..79abeb9e073f19 100644 --- a/docs/examples/en/utils/SceneUtils.html +++ b/docs/examples/en/utils/SceneUtils.html @@ -40,6 +40,25 @@

    [method:Group createMultiMaterialObject]( [param:BufferGeometry geometry], [ This is mostly useful for objects that need both a material and a wireframe implementation.

    +

    [method:undefined sortInstancedMesh]( [param:InstancedMesh mesh], [param:Function compareFn] )

    +

    + mesh -- InstancedMesh in which instances will be sorted.
    + compareFn -- Comparator function defining the sort order. +

    +

    + Sorts the instances within an [page:InstancedMesh], according to a user-defined + callback. The callback will be provided with two arguments, indexA + and indexB, and must return a numerical value. See + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#description Array.prototype.sort] + for more information on sorting callbacks and their return values. +

    +

    + Because of the high performance cost, three.js does not sort + [page:InstancedMesh] instances automatically. Manually sorting may be + helpful to improve display of alpha blended materials (back to front), + and to reduce overdraw in opaque materials (front to back). +

    +

    Source

    diff --git a/docs/examples/ko/controls/OrbitControls.html b/docs/examples/ko/controls/OrbitControls.html index d4f0786526ed1b..c5e38dfa3ea678 100644 --- a/docs/examples/ko/controls/OrbitControls.html +++ b/docs/examples/ko/controls/OrbitControls.html @@ -91,7 +91,7 @@

    [property:Float autoRotateSpeed]

    [property:Float dampingFactor]

    -

    [page:.enableDamping]이 true일 경우 에니메이션 루프에서 [page:.update]()를 호출해야만 감쇠 관성를 사용할 수 있습니다. +

    [page:.enableDamping]이 `true`일 경우 에니메이션 루프에서 [page:.update]()를 호출해야만 감쇠 관성를 사용할 수 있습니다. Default is `0.05`.

    [property:HTMLDOMElement domElement]

    diff --git a/docs/examples/zh/controls/OrbitControls.html b/docs/examples/zh/controls/OrbitControls.html index 645e7d82baca3d..2d832284d00140 100644 --- a/docs/examples/zh/controls/OrbitControls.html +++ b/docs/examples/zh/controls/OrbitControls.html @@ -93,7 +93,7 @@

    [property:Float autoRotateSpeed]

    [property:Float dampingFactor]

    - 当[page:.enableDamping]设置为true的时候,阻尼惯性有多大。
    + 当[page:.enableDamping]设置为`true`的时候,阻尼惯性有多大。 Default is `0.05`.
    请注意,要使得这一值生效,你必须在你的动画循环里调用[page:.update]()。

    diff --git a/docs/examples/zh/exporters/GLTFExporter.html b/docs/examples/zh/exporters/GLTFExporter.html index 8ac4cdfc25cfc8..0d9954689017c0 100644 --- a/docs/examples/zh/exporters/GLTFExporter.html +++ b/docs/examples/zh/exporters/GLTFExporter.html @@ -117,7 +117,6 @@

    [method:undefined parse]( [param:Object3D input], [param:Function onComplete
    • trs - bool. Export position, rotation and scale instead of matrix per node. Default is false
    • onlyVisible - bool. Export only visible objects. Default is true.
    • -
    • truncateDrawRange - bool. Export just the attributes within the drawRange, if defined, instead of exporting the whole array. Default is true.
    • binary - bool. Export in binary (.glb) format, returning an ArrayBuffer. Default is false.
    • maxTextureSize - int. Restricts the image maximum size (both width and height) to the given value. Default is Infinity.
    • animations - Array<[page:AnimationClip AnimationClip]>. List of animations to be included in the export.
    • diff --git a/docs/examples/zh/loaders/GLTFLoader.html b/docs/examples/zh/loaders/GLTFLoader.html index b564dce24120da..a0fec63a9b02ed 100644 --- a/docs/examples/zh/loaders/GLTFLoader.html +++ b/docs/examples/zh/loaders/GLTFLoader.html @@ -34,7 +34,6 @@

      扩展

    • KHR_draco_mesh_compression
    • KHR_materials_clearcoat
    • KHR_materials_ior
    • -
    • KHR_materials_pbrSpecularGlossiness
    • KHR_materials_specular
    • KHR_materials_transmission
    • KHR_materials_iridescence
    • @@ -46,6 +45,7 @@

      扩展

    • KHR_texture_transform2
    • EXT_texture_webp
    • EXT_meshopt_compression
    • +
    • EXT_mesh_gpu_instancing

    diff --git a/docs/examples/zh/loaders/PCDLoader.html b/docs/examples/zh/loaders/PCDLoader.html index 1d5afe96759bed..6337160aaf1d2c 100644 --- a/docs/examples/zh/loaders/PCDLoader.html +++ b/docs/examples/zh/loaders/PCDLoader.html @@ -11,9 +11,15 @@

    [name]

    -

    用于加载 .pcd 资源的加载器。
    - 点云数据是 点云库 的文件格式。
    - 加载器支持 ascii 和 (压缩) 二进制编码。 +

    + A loader for the PCD (Point Cloud Data) file format. [name] supports ASCII and (compressed) binary files as well as the following PCD fields: +

      +
    • x y z
    • +
    • rgb
    • +
    • normal_x normal_y normal_z
    • +
    • intensity
    • +
    • label
    • +

    代码示例

    @@ -28,9 +34,9 @@

    代码示例

    // resource URL 'pointcloud.pcd', // called when the resource is loaded - function ( mesh ) { + function ( points ) { - scene.add( mesh ); + scene.add( points ); }, // called when loading is in progresses diff --git a/docs/examples/zh/postprocessing/EffectComposer.html b/docs/examples/zh/postprocessing/EffectComposer.html index 0ba144d78981c2..89a07bb649eb0e 100644 --- a/docs/examples/zh/postprocessing/EffectComposer.html +++ b/docs/examples/zh/postprocessing/EffectComposer.html @@ -88,6 +88,11 @@

    [method:undefined addPass]( [param:Pass pass] )

    将传入的过程添加到过程链。

    +

    [method:undefined dispose]()

    +

    + Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. +

    +

    [method:undefined insertPass]( [param:Pass pass], [param:Integer index] )

    diff --git a/docs/examples/zh/utils/BufferGeometryUtils.html b/docs/examples/zh/utils/BufferGeometryUtils.html index d1bd27d5310b25..0b1c7701e40fe3 100644 --- a/docs/examples/zh/utils/BufferGeometryUtils.html +++ b/docs/examples/zh/utils/BufferGeometryUtils.html @@ -16,30 +16,45 @@

    [name]

    方法

    -

    [method:BufferGeometry mergeBufferGeometries]( [param:Array geometries], [param:Boolean useGroups] )

    -

    - geometries -- 由 [page:BufferGeometry BufferGeometry] 实例的数组。
    - useGroups -- 是否要为了合并几何体而产生组。

    - - 将一组几何体合并到一个实例中。所有几何体都必须兼容该属性。 - 如果合并不成功,则该方法返回 null。 +

    [method:Object computeMikkTSpaceTangents]( [param:BufferGeometry geometry], [param:Object MikkTSpace], [param:Boolean negateSign] = true )

    +
      +
    • geometry -- Instance of [page:BufferGeometry].
    • +
    • MikkTSpace -- Instance of examples/jsm/libs/mikktspace.module.js, or mikktspace npm package. Await MikkTSpace.ready before use. +
    • negateSign -- Whether to negate the sign component (.w) of each tangent. Required for normal map conventions in some formats, including glTF.
    • +
    +

    + Computes vertex tangents using the [link:http://www.mikktspace.com/ MikkTSpace] algorithm. + MikkTSpace generates the same tangents consistently, and is used in most modelling tools and + normal map bakers. Use MikkTSpace for materials with normal maps, because inconsistent + tangents may lead to subtle visual issues in the normal map, particularly around mirrored + UV seams.

    -

    [method:BufferAttribute mergeBufferAttributes]( [param:Array attributes] )

    - attributes -- 由 [page:BufferAttribute BufferAttribute] 实例组成的数组。

    - - 将一组属性合并为一个单一的实例。所有几何体都必须兼容该属性,不支持 [page:InterleavedBufferAttribute InterleavedBufferAttributes] 。 - 如果合并不成功,则该方法返回 null 。 + In comparison to this method, [page:BufferGeometry.computeTangents] (a + custom algorithm) generates tangents that probably will not match the tangents + in other software. The custom algorithm is sufficient for general use with a + [page:ShaderMaterial], and may be faster than MikkTSpace. +

    +

    + Returns the original [page:BufferGeometry]. Indexed geometries will be de-indexed. + Requires position, normal, and uv attributes.

    -

    [method:InterleavedBufferAttribute interleaveAttributes]( [param:Array attributes] )

    +

    [method:Object computeMorphedAttributes]( [param:Mesh | Line | Points object] )

    - attributes -- 由 [page:BufferAttribute BufferAttribute] 实例组成的数组。

    + object -- Instance of [page:Mesh Mesh] | [page:Line Line] | [page:Points Points].

    - 交叉存储一组属性并返回一个新的对应属性数组,这些属性共享一个 InterleavedBuffer 实例。所有属性都必须兼容的该类型。如果合并不成功,则该方法返回 null 。 + Returns the current attributes (Position and Normal) of a morphed/skinned [page:Object3D Object3D] whose geometry is a + [page:BufferGeometry BufferGeometry], together with the original ones: An Object with 4 properties: + `positionAttribute`, `normalAttribute`, `morphedPositionAttribute` and `morphedNormalAttribute`. + + Helpful for Raytracing or Decals (i.e. a [page:DecalGeometry DecalGeometry] applied to a morphed Object + with a [page:BufferGeometry BufferGeometry] will use the original BufferGeometry, not the morphed/skinned one, + generating an incorrect result. + Using this function to create a shadow Object3D the DecalGeometry can be correctly generated).

    @@ -51,74 +66,67 @@

    [method:Number estimateBytesUsed]( [param:BufferGeometry geometry] )

    -

    [method:BufferGeometry mergeGroups]( [param:BufferGeometry geometry] )

    +

    [method:InterleavedBufferAttribute interleaveAttributes]( [param:Array attributes] )

    - geometry -- Instance of [page:BufferGeometry BufferGeometry] to merge the groups of.

    + attributes -- 由 [page:BufferAttribute BufferAttribute] 实例组成的数组。

    + + 交叉存储一组属性并返回一个新的对应属性数组,这些属性共享一个 InterleavedBuffer 实例。所有属性都必须兼容的该类型。如果合并不成功,则该方法返回 null 。 - Merges the [page:BufferGeometry.groups groups] for the given geometry.

    -

    [method:BufferGeometry mergeVertices]( [param:BufferGeometry geometry], [param:Number tolerance] )

    +

    [method:BufferAttribute mergeBufferAttributes]( [param:Array attributes] )

    - geometry -- 用于合并顶点的 [page:BufferGeometry BufferGeometry] 实例。
    - tolerance -- 要合并的顶点属性之间允许的最大差异。 默认为 1e-4。

    + attributes -- 由 [page:BufferAttribute BufferAttribute] 实例组成的数组。

    - 返回一个新的 [page:BufferGeometry BufferGeometry] ,其中包含将所有(在容差范围内的)具有相似属性的顶点合并而成的顶点。 + 将一组属性合并为一个单一的实例。所有几何体都必须兼容该属性,不支持 [page:InterleavedBufferAttribute InterleavedBufferAttributes] 。 + 如果合并不成功,则该方法返回 null 。

    -

    [method:BufferGeometry toTrianglesDrawMode]( [param:BufferGeometry geometry], [param:TrianglesDrawMode drawMode] )

    +

    [method:BufferGeometry mergeBufferGeometries]( [param:Array geometries], [param:Boolean useGroups] )

    - geometry -- [page:BufferGeometry BufferGeometry] 实例。
    - drawMode -- 给定几何体的绘制模式。

    + geometries -- 由 [page:BufferGeometry BufferGeometry] 实例的数组。
    + useGroups -- 是否要为了合并几何体而产生组。

    - 基于 [page:DrawModes THREE.TrianglesDrawMode] 绘制模式,返回一个新的有索引值的 [page:BufferGeometry BufferGeometry]。 此模式对应于 WebGL 的原始术语 *gl.TRIANGLES* 。 + 将一组几何体合并到一个实例中。所有几何体都必须兼容该属性。 + 如果合并不成功,则该方法返回 null。

    -

    [method:Object computeMorphedAttributes]( [param:Mesh | Line | Points object] )

    +

    [method:BufferGeometry mergeGroups]( [param:BufferGeometry geometry] )

    - object -- Instance of [page:Mesh Mesh] | [page:Line Line] | [page:Points Points].

    + geometry -- Instance of [page:BufferGeometry BufferGeometry] to merge the groups of.

    - Returns the current attributes (Position and Normal) of a morphed/skinned [page:Object3D Object3D] whose geometry is a - [page:BufferGeometry BufferGeometry], together with the original ones: An Object with 4 properties: - `positionAttribute`, `normalAttribute`, `morphedPositionAttribute` and `morphedNormalAttribute`. + Merges the [page:BufferGeometry.groups groups] for the given geometry. +

    - Helpful for Raytracing or Decals (i.e. a [page:DecalGeometry DecalGeometry] applied to a morphed Object - with a [page:BufferGeometry BufferGeometry] will use the original BufferGeometry, not the morphed/skinned one, - generating an incorrect result. - Using this function to create a shadow Object3D the DecalGeometry can be correctly generated). +

    [method:BufferGeometry mergeVertices]( [param:BufferGeometry geometry], [param:Number tolerance] )

    +

    + geometry -- 用于合并顶点的 [page:BufferGeometry BufferGeometry] 实例。
    + tolerance -- 要合并的顶点属性之间允许的最大差异。 默认为 1e-4。

    -

    + 返回一个新的 [page:BufferGeometry BufferGeometry] ,其中包含将所有(在容差范围内的)具有相似属性的顶点合并而成的顶点。 -

    [method:Object computeMikkTSpaceTangents]( [param:BufferGeometry geometry], [param:Object MikkTSpace], [param:Boolean negateSign] = true )

    -
      -
    • geometry -- Instance of [page:BufferGeometry].
    • -
    • MikkTSpace -- Instance of examples/jsm/libs/mikktspace.module.js, or mikktspace npm package. Await MikkTSpace.ready before use. -
    • negateSign -- Whether to negate the sign component (.w) of each tangent. Required for normal map conventions in some formats, including glTF.
    • -
    +

    +

    [method:BufferGeometry toCreasedNormals]( [param:BufferGeometry geometry], [param:Number creaseAngle] )

    - Computes vertex tangents using the [link:http://www.mikktspace.com/ MikkTSpace] algorithm. - MikkTSpace generates the same tangents consistently, and is used in most modelling tools and - normal map bakers. Use MikkTSpace for materials with normal maps, because inconsistent - tangents may lead to subtle visual issues in the normal map, particularly around mirrored - UV seams. + geometry -- The input geometry.
    + creaseAngle -- The crease angle.

    -

    - In comparison to this method, [page:BufferGeometry.computeTangents] (a - custom algorithm) generates tangents that probably will not match the tangents - in other software. The custom algorithm is sufficient for general use with a - [page:ShaderMaterial], and may be faster than MikkTSpace. + Creates a new, non-indexed geometry with smooth normals everywhere except faces that meet at an angle greater than the crease angle.

    +

    [method:BufferGeometry toTrianglesDrawMode]( [param:BufferGeometry geometry], [param:TrianglesDrawMode drawMode] )

    - Returns the original [page:BufferGeometry]. Indexed geometries will be de-indexed. - Requires position, normal, and uv attributes. + geometry -- Instance of [page:BufferGeometry BufferGeometry].
    + drawMode -- The draw mode of the given geometry. Valid inputs are `THREE.TriangleStripDrawMode` and `THREE.TriangleFanDrawMode`.

    + + Returns a new indexed geometry based on `THREE.TrianglesDrawMode` draw mode. This mode corresponds to the `gl.TRIANGLES` WebGL primitive.

    -

    +

    Source

    [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/utils/BufferGeometryUtils.js examples/jsm/utils/BufferGeometryUtils.js] diff --git a/docs/examples/zh/utils/SceneUtils.html b/docs/examples/zh/utils/SceneUtils.html index 3233ebb1027699..2e8b1369823c19 100644 --- a/docs/examples/zh/utils/SceneUtils.html +++ b/docs/examples/zh/utils/SceneUtils.html @@ -40,6 +40,25 @@

    [method:Group createMultiMaterialObject]( [param:BufferGeometry geometry], [ 该方法对于同时需要材质和线框绘制的物体非常有用。

    +

    [method:undefined sortInstancedMesh]( [param:InstancedMesh mesh], [param:Function compareFn] )

    +

    + mesh -- InstancedMesh in which instances will be sorted.
    + compareFn -- Comparator function defining the sort order. +

    +

    + Sorts the instances within an [page:InstancedMesh], according to a user-defined + callback. The callback will be provided with two arguments, indexA + and indexB, and must return a numerical value. See + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#description Array.prototype.sort] + for more information on sorting callbacks and their return values. +

    +

    + Because of the high performance cost, three.js does not sort + [page:InstancedMesh] instances automatically. Manually sorting may be + helpful to improve display of alpha blended materials (back to front), + and to reduce overdraw in opaque materials (front to back). +

    +

    源代码

    diff --git a/docs/index.html b/docs/index.html index bcb873f9cc30a0..943eccffa9f4af 100644 --- a/docs/index.html +++ b/docs/index.html @@ -36,6 +36,10 @@

    three.js

    + + + +
    @@ -86,7 +90,7 @@

    three.js

    if ( /^(api|manual|examples)/.test( hash ) ) { - const hashLanguage = /^(api|manual|examples)\/(en|ar|ko|zh|ja)\//.exec( hash ); + const hashLanguage = /^(api|manual|examples)\/(en|ar|ko|zh|ja|it|pt-br|fr|ru)\//.exec( hash ); if ( hashLanguage === null ) { diff --git a/docs/list.json b/docs/list.json index 74df8c4b5f39ca..476b28c59471bb 100644 --- a/docs/list.json +++ b/docs/list.json @@ -313,6 +313,7 @@ "Textures": { "CanvasTexture": "api/en/textures/CanvasTexture", "CompressedTexture": "api/en/textures/CompressedTexture", + "CompressedArrayTexture": "api/en/textures/CompressedArrayTexture", "CubeTexture": "api/en/textures/CubeTexture", "Data3DTexture": "api/en/textures/Data3DTexture", "DataArrayTexture": "api/en/textures/DataArrayTexture", @@ -326,7 +327,7 @@ }, - "Examples": { + "Addons": { "Animations": { "CCDIKSolver": "examples/en/animations/CCDIKSolver", @@ -814,6 +815,7 @@ "纹理贴图": { "CanvasTexture": "api/zh/textures/CanvasTexture", "CompressedTexture": "api/zh/textures/CompressedTexture", + "CompressedArrayTexture": "api/zh/textures/CompressedArrayTexture", "CubeTexture": "api/zh/textures/CubeTexture", "DataArrayTexture": "api/zh/textures/DataArrayTexture", "Data3DTexture": "api/zh/textures/Data3DTexture", @@ -827,7 +829,7 @@ }, - "示例": { + "Addons": { "动画": { "CCDIKSolver": "examples/zh/animations/CCDIKSolver", @@ -1063,7 +1065,7 @@ }, - "예제": { + "Addons": { "컨트롤": { "DragControls": "examples/ko/controls/DragControls", @@ -1079,32 +1081,1000 @@ }, - "ja": { - "マニュアル": { - "はじめてみましょう": { - "シーンの作成": "manual/ja/introduction/Creating-a-scene", - "インストールの方法": "manual/ja/introduction/Installation", - "WebGLの互換性の確認": "manual/ja/introduction/WebGL-compatibility-check", - "localで実行する方法": "manual/ja/introduction/How-to-run-things-locally", - "線を引く": "manual/ja/introduction/Drawing-lines", - "テキストを作成する": "manual/ja/introduction/Creating-text", - "3Dモデルをロードする": "manual/ja/introduction/Loading-3D-models", - "ライブラリとプラグイン": "manual/ja/introduction/Libraries-and-Plugins", - "FAQ": "manual/ja/introduction/FAQ", - "役にたつリンク集": "manual/ja/introduction/Useful-links" - }, - "次の段階": { - "更新の仕方": "manual/ja/introduction/How-to-update-things", - "オブジェクトを廃棄する方法": "manual/ja/introduction/How-to-dispose-of-objects", - "VRコンテンツの作り方": "manual/ja/introduction/How-to-create-VR-content", - "post-processingの使い方": "manual/ja/introduction/How-to-use-post-processing", - "行列の変換": "manual/ja/introduction/Matrix-transformations", - "アニメーションシステム": "manual/ja/introduction/Animation-system" - }, - "ビルドツール": { - "NPMでテストを実行する": "manual/ja/buildTools/Testing-with-NPM" - } - } - } + "ja": { + + "マニュアル": { + + "はじめてみましょう": { + "シーンの作成": "manual/ja/introduction/Creating-a-scene", + "インストールの方法": "manual/ja/introduction/Installation", + "WebGLの互換性の確認": "manual/ja/introduction/WebGL-compatibility-check", + "localで実行する方法": "manual/ja/introduction/How-to-run-things-locally", + "線を引く": "manual/ja/introduction/Drawing-lines", + "テキストを作成する": "manual/ja/introduction/Creating-text", + "3Dモデルをロードする": "manual/ja/introduction/Loading-3D-models", + "ライブラリとプラグイン": "manual/ja/introduction/Libraries-and-Plugins", + "FAQ": "manual/ja/introduction/FAQ", + "役にたつリンク集": "manual/ja/introduction/Useful-links" + }, + + "次の段階": { + "更新の仕方": "manual/ja/introduction/How-to-update-things", + "オブジェクトを廃棄する方法": "manual/ja/introduction/How-to-dispose-of-objects", + "VRコンテンツの作り方": "manual/ja/introduction/How-to-create-VR-content", + "post-processingの使い方": "manual/ja/introduction/How-to-use-post-processing", + "行列の変換": "manual/ja/introduction/Matrix-transformations", + "アニメーションシステム": "manual/ja/introduction/Animation-system" + }, + + "ビルドツール": { + "NPMでテストを実行する": "manual/ja/buildTools/Testing-with-NPM" + } + + } + + }, + + "it": { + + "Manuale": { + + "Per iniziare": { + "Creare una scena": "manual/it/introduction/Creating-a-scene", + "Installazione": "manual/it/introduction/Installation", + "Controllo compatibilità WebGL": "manual/it/introduction/WebGL-compatibility-check", + "Esecuzione in locale": "manual/it/introduction/How-to-run-things-locally", + "Disegnare linee": "manual/it/introduction/Drawing-lines", + "Creare testo": "manual/it/introduction/Creating-text", + "Caricare modelli 3D": "manual/it/introduction/Loading-3D-models", + "Librerie e Plugins": "manual/it/introduction/Libraries-and-Plugins", + "FAQ": "manual/it/introduction/FAQ", + "Link utili": "manual/it/introduction/Useful-links" + }, + + "Prossimi passi": { + "Come aggiornare le cose": "manual/it/introduction/How-to-update-things", + "Come liberare le risorse": "manual/it/introduction/How-to-dispose-of-objects", + "Come creare contenuti VR": "manual/it/introduction/How-to-create-VR-content", + "Come utilizzare il post-processing": "manual/it/introduction/How-to-use-post-processing", + "Trasformazioni di matrici": "manual/it/introduction/Matrix-transformations", + "Sistema di animazione": "manual/it/introduction/Animation-system", + "Gestione del colore": "manual/it/introduction/Color-management" + }, + + "Strumenti di build": { + "Testare con NPM": "manual/it/buildTools/Testing-with-NPM" + } + + }, + + "Riferimenti": { + + "Animazione": { + "AnimationAction": "api/it/animation/AnimationAction", + "AnimationClip": "api/it/animation/AnimationClip", + "AnimationMixer": "api/it/animation/AnimationMixer", + "AnimationObjectGroup": "api/it/animation/AnimationObjectGroup", + "AnimationUtils": "api/it/animation/AnimationUtils", + "KeyframeTrack": "api/it/animation/KeyframeTrack", + "PropertyBinding": "api/it/animation/PropertyBinding", + "PropertyMixer": "api/it/animation/PropertyMixer" + }, + + "Animazione / Tracks": { + "BooleanKeyframeTrack": "api/it/animation/tracks/BooleanKeyframeTrack", + "ColorKeyframeTrack": "api/it/animation/tracks/ColorKeyframeTrack", + "NumberKeyframeTrack": "api/it/animation/tracks/NumberKeyframeTrack", + "QuaternionKeyframeTrack": "api/it/animation/tracks/QuaternionKeyframeTrack", + "StringKeyframeTrack": "api/it/animation/tracks/StringKeyframeTrack", + "VectorKeyframeTrack": "api/it/animation/tracks/VectorKeyframeTrack" + }, + + "Audio": { + "Audio": "api/it/audio/Audio", + "AudioAnalyser": "api/it/audio/AudioAnalyser", + "AudioContext": "api/it/audio/AudioContext", + "AudioListener": "api/it/audio/AudioListener", + "PositionalAudio": "api/it/audio/PositionalAudio" + }, + + "Telecamere": { + "ArrayCamera": "api/it/cameras/ArrayCamera", + "Camera": "api/it/cameras/Camera", + "CubeCamera": "api/it/cameras/CubeCamera", + "OrthographicCamera": "api/it/cameras/OrthographicCamera", + "PerspectiveCamera": "api/it/cameras/PerspectiveCamera", + "StereoCamera": "api/it/cameras/StereoCamera" + }, + + "Costanti": { + "Animazione": "api/it/constants/Animation", + "Core": "api/it/constants/Core", + "CustomBlendingEquation": "api/it/constants/CustomBlendingEquations", + "BufferAttributeUsage": "api/it/constants/BufferAttributeUsage", + "Materiali": "api/it/constants/Materials", + "Renderer": "api/it/constants/Renderer", + "Texture": "api/it/constants/Textures" + }, + + "Core": { + "BufferAttribute": "api/it/core/BufferAttribute", + "BufferGeometry": "api/it/core/BufferGeometry", + "Clock": "api/it/core/Clock", + "EventDispatcher": "api/it/core/EventDispatcher", + "GLBufferAttribute": "api/it/core/GLBufferAttribute", + "InstancedBufferAttribute": "api/it/core/InstancedBufferAttribute", + "InstancedBufferGeometry": "api/it/core/InstancedBufferGeometry", + "InstancedInterleavedBuffer": "api/it/core/InstancedInterleavedBuffer", + "InterleavedBuffer": "api/it/core/InterleavedBuffer", + "InterleavedBufferAttribute": "api/it/core/InterleavedBufferAttribute", + "Layers": "api/it/core/Layers", + "Object3D": "api/it/core/Object3D", + "Raycaster": "api/it/core/Raycaster", + "Uniform": "api/it/core/Uniform" + }, + + "Core / BufferAttributes": { + "BufferAttribute Types": "api/it/core/bufferAttributeTypes/BufferAttributeTypes" + }, + + "Extras": { + "DataUtils": "api/it/extras/DataUtils", + "Earcut": "api/it/extras/Earcut", + "ImageUtils": "api/it/extras/ImageUtils", + "PMREMGenerator": "api/it/extras/PMREMGenerator", + "ShapeUtils": "api/it/extras/ShapeUtils" + }, + + "Extras / Core": { + "Curve": "api/it/extras/core/Curve", + "CurvePath": "api/it/extras/core/CurvePath", + "Interpolations": "api/it/extras/core/Interpolations", + "Path": "api/it/extras/core/Path", + "Shape": "api/it/extras/core/Shape", + "ShapePath": "api/it/extras/core/ShapePath" + }, + + "Extras / Curves": { + "ArcCurve": "api/it/extras/curves/ArcCurve", + "CatmullRomCurve3": "api/it/extras/curves/CatmullRomCurve3", + "CubicBezierCurve": "api/it/extras/curves/CubicBezierCurve", + "CubicBezierCurve3": "api/it/extras/curves/CubicBezierCurve3", + "EllipseCurve": "api/it/extras/curves/EllipseCurve", + "LineCurve": "api/it/extras/curves/LineCurve", + "LineCurve3": "api/it/extras/curves/LineCurve3", + "QuadraticBezierCurve": "api/it/extras/curves/QuadraticBezierCurve", + "QuadraticBezierCurve3": "api/it/extras/curves/QuadraticBezierCurve3", + "SplineCurve": "api/it/extras/curves/SplineCurve" + }, + + "Geometrie": { + "BoxGeometry": "api/it/geometries/BoxGeometry", + "CapsuleGeometry": "api/it/geometries/CapsuleGeometry", + "CircleGeometry": "api/it/geometries/CircleGeometry", + "ConeGeometry": "api/it/geometries/ConeGeometry", + "CylinderGeometry": "api/it/geometries/CylinderGeometry", + "DodecahedronGeometry": "api/it/geometries/DodecahedronGeometry", + "EdgesGeometry": "api/it/geometries/EdgesGeometry", + "ExtrudeGeometry": "api/it/geometries/ExtrudeGeometry", + "IcosahedronGeometry": "api/it/geometries/IcosahedronGeometry", + "LatheGeometry": "api/it/geometries/LatheGeometry", + "OctahedronGeometry": "api/it/geometries/OctahedronGeometry", + "PlaneGeometry": "api/it/geometries/PlaneGeometry", + "PolyhedronGeometry": "api/it/geometries/PolyhedronGeometry", + "RingGeometry": "api/it/geometries/RingGeometry", + "ShapeGeometry": "api/it/geometries/ShapeGeometry", + "SphereGeometry": "api/it/geometries/SphereGeometry", + "TetrahedronGeometry": "api/it/geometries/TetrahedronGeometry", + "TorusGeometry": "api/it/geometries/TorusGeometry", + "TorusKnotGeometry": "api/it/geometries/TorusKnotGeometry", + "TubeGeometry": "api/it/geometries/TubeGeometry", + "WireframeGeometry": "api/it/geometries/WireframeGeometry" + }, + + "Helpers": { + "ArrowHelper": "api/it/helpers/ArrowHelper", + "AxesHelper": "api/it/helpers/AxesHelper", + "BoxHelper": "api/it/helpers/BoxHelper", + "Box3Helper": "api/it/helpers/Box3Helper", + "CameraHelper": "api/it/helpers/CameraHelper", + "DirectionalLightHelper": "api/it/helpers/DirectionalLightHelper", + "GridHelper": "api/it/helpers/GridHelper", + "PolarGridHelper": "api/it/helpers/PolarGridHelper", + "HemisphereLightHelper": "api/it/helpers/HemisphereLightHelper", + "PlaneHelper": "api/it/helpers/PlaneHelper", + "PointLightHelper": "api/it/helpers/PointLightHelper", + "SkeletonHelper": "api/it/helpers/SkeletonHelper", + "SpotLightHelper": "api/it/helpers/SpotLightHelper" + }, + + "Luci": { + "AmbientLight": "api/it/lights/AmbientLight", + "AmbientLightProbe": "api/it/lights/AmbientLightProbe", + "DirectionalLight": "api/it/lights/DirectionalLight", + "HemisphereLight": "api/it/lights/HemisphereLight", + "HemisphereLightProbe": "api/it/lights/HemisphereLightProbe", + "Light": "api/it/lights/Light", + "LightProbe": "api/it/lights/LightProbe", + "PointLight": "api/it/lights/PointLight", + "RectAreaLight": "api/it/lights/RectAreaLight", + "SpotLight": "api/it/lights/SpotLight" + }, + + "Luci / Ombre": { + "LightShadow": "api/it/lights/shadows/LightShadow", + "PointLightShadow": "api/it/lights/shadows/PointLightShadow", + "DirectionalLightShadow": "api/it/lights/shadows/DirectionalLightShadow", + "SpotLightShadow": "api/it/lights/shadows/SpotLightShadow" + }, + + "Loaders": { + "AnimationLoader": "api/it/loaders/AnimationLoader", + "AudioLoader": "api/it/loaders/AudioLoader", + "BufferGeometryLoader": "api/it/loaders/BufferGeometryLoader", + "Cache": "api/it/loaders/Cache", + "CompressedTextureLoader": "api/it/loaders/CompressedTextureLoader", + "CubeTextureLoader": "api/it/loaders/CubeTextureLoader", + "DataTextureLoader": "api/it/loaders/DataTextureLoader", + "FileLoader": "api/it/loaders/FileLoader", + "ImageBitmapLoader": "api/it/loaders/ImageBitmapLoader", + "ImageLoader": "api/it/loaders/ImageLoader", + "Loader": "api/it/loaders/Loader", + "LoaderUtils": "api/it/loaders/LoaderUtils", + "MaterialLoader": "api/it/loaders/MaterialLoader", + "ObjectLoader": "api/it/loaders/ObjectLoader", + "TextureLoader": "api/it/loaders/TextureLoader" + }, + + "Loaders / Managers": { + "DefaultLoadingManager": "api/it/loaders/managers/DefaultLoadingManager", + "LoadingManager": "api/it/loaders/managers/LoadingManager" + }, + + "Materiali": { + "LineBasicMaterial": "api/it/materials/LineBasicMaterial", + "LineDashedMaterial": "api/it/materials/LineDashedMaterial", + "Material": "api/it/materials/Material", + "MeshBasicMaterial": "api/it/materials/MeshBasicMaterial", + "MeshDepthMaterial": "api/it/materials/MeshDepthMaterial", + "MeshDistanceMaterial": "api/it/materials/MeshDistanceMaterial", + "MeshLambertMaterial": "api/it/materials/MeshLambertMaterial", + "MeshMatcapMaterial": "api/it/materials/MeshMatcapMaterial", + "MeshNormalMaterial": "api/it/materials/MeshNormalMaterial", + "MeshPhongMaterial": "api/it/materials/MeshPhongMaterial", + "MeshPhysicalMaterial": "api/it/materials/MeshPhysicalMaterial", + "MeshStandardMaterial": "api/it/materials/MeshStandardMaterial", + "MeshToonMaterial": "api/it/materials/MeshToonMaterial", + "PointsMaterial": "api/it/materials/PointsMaterial", + "RawShaderMaterial": "api/it/materials/RawShaderMaterial", + "ShaderMaterial": "api/it/materials/ShaderMaterial", + "ShadowMaterial": "api/it/materials/ShadowMaterial", + "SpriteMaterial": "api/it/materials/SpriteMaterial" + }, + + "Math": { + "Box2": "api/it/math/Box2", + "Box3": "api/it/math/Box3", + "Color": "api/it/math/Color", + "Cylindrical": "api/it/math/Cylindrical", + "Euler": "api/it/math/Euler", + "Frustum": "api/it/math/Frustum", + "Interpolant": "api/it/math/Interpolant", + "Line3": "api/it/math/Line3", + "MathUtils": "api/it/math/MathUtils", + "Matrix3": "api/it/math/Matrix3", + "Matrix4": "api/it/math/Matrix4", + "Plane": "api/it/math/Plane", + "Quaternion": "api/it/math/Quaternion", + "Ray": "api/it/math/Ray", + "Sphere": "api/it/math/Sphere", + "Spherical": "api/it/math/Spherical", + "SphericalHarmonics3": "api/it/math/SphericalHarmonics3", + "Triangle": "api/it/math/Triangle", + "Vector2": "api/it/math/Vector2", + "Vector3": "api/it/math/Vector3", + "Vector4": "api/it/math/Vector4" + }, + + "Math / Interpolants": { + "CubicInterpolant": "api/it/math/interpolants/CubicInterpolant", + "DiscreteInterpolant": "api/it/math/interpolants/DiscreteInterpolant", + "LinearInterpolant": "api/it/math/interpolants/LinearInterpolant", + "QuaternionLinearInterpolant": "api/it/math/interpolants/QuaternionLinearInterpolant" + }, + + "Oggetti": { + "Bone": "api/it/objects/Bone", + "Group": "api/it/objects/Group", + "InstancedMesh": "api/it/objects/InstancedMesh", + "Line": "api/it/objects/Line", + "LineLoop": "api/it/objects/LineLoop", + "LineSegments": "api/it/objects/LineSegments", + "LOD": "api/it/objects/LOD", + "Mesh": "api/it/objects/Mesh", + "Points": "api/it/objects/Points", + "Skeleton": "api/it/objects/Skeleton", + "SkinnedMesh": "api/it/objects/SkinnedMesh", + "Sprite": "api/it/objects/Sprite" + }, + + "Renderers": { + "WebGLMultipleRenderTargets": "api/it/renderers/WebGLMultipleRenderTargets", + "WebGLRenderer": "api/it/renderers/WebGLRenderer", + "WebGL1Renderer": "api/it/renderers/WebGL1Renderer", + "WebGLRenderTarget": "api/it/renderers/WebGLRenderTarget", + "WebGL3DRenderTarget": "api/it/renderers/WebGL3DRenderTarget", + "WebGLArrayRenderTarget": "api/it/renderers/WebGLArrayRenderTarget", + "WebGLCubeRenderTarget": "api/it/renderers/WebGLCubeRenderTarget" + }, + + "Renderers / Shaders": { + "ShaderChunk": "api/it/renderers/shaders/ShaderChunk", + "ShaderLib": "api/it/renderers/shaders/ShaderLib", + "UniformsLib": "api/it/renderers/shaders/UniformsLib", + "UniformsUtils": "api/it/renderers/shaders/UniformsUtils" + }, + + "Renderers / WebXR": { + "WebXRManager": "api/it/renderers/webxr/WebXRManager" + }, + + "Scene": { + "Fog": "api/it/scenes/Fog", + "FogExp2": "api/it/scenes/FogExp2", + "Scene": "api/it/scenes/Scene" + }, + + "Textures": { + "CanvasTexture": "api/it/textures/CanvasTexture", + "CompressedTexture": "api/it/textures/CompressedTexture", + "CompressedArrayTexture": "api/it/textures/CompressedArrayTexture", + "CubeTexture": "api/it/textures/CubeTexture", + "Data3DTexture": "api/it/textures/Data3DTexture", + "DataArrayTexture": "api/it/textures/DataArrayTexture", + "DataTexture": "api/it/textures/DataTexture", + "DepthTexture": "api/it/textures/DepthTexture", + "FramebufferTexture": "api/it/textures/FramebufferTexture", + "Source": "api/it/textures/Source", + "Texture": "api/it/textures/Texture", + "VideoTexture": "api/it/textures/VideoTexture" + } + } + }, + "pt-br": { + + "Manual": { + + "Comece a usar": { + "Criando uma cena": "manual/pt-br/introduction/Creating-a-scene", + "Instalação": "manual/pt-br/introduction/Installation", + "Compatibilidade WebGL": "manual/pt-br/introduction/WebGL-compatibility-check", + "Como executar localmente": "manual/pt-br/introduction/How-to-run-things-locally", + "Desenhando linhas": "manual/pt-br/introduction/Drawing-lines", + "Criando texto": "manual/pt-br/introduction/Creating-text", + "Carregando modelos 3D": "manual/pt-br/introduction/Loading-3D-models", + "Bibliotecas e Plugins": "manual/pt-br/introduction/Libraries-and-Plugins", + "FAQ": "manual/pt-br/introduction/FAQ", + "Links úteis": "manual/pt-br/introduction/Useful-links" + }, + + "Próximos Passos": { + "Como atualizar as coisas": "manual/pt-br/introduction/How-to-update-things", + "Como descartar objetos": "manual/pt-br/introduction/How-to-dispose-of-objects", + "Como criar conteúdo de VR": "manual/pt-br/introduction/How-to-create-VR-content", + "Como usar o pós-processamento": "manual/pt-br/introduction/How-to-use-post-processing", + "Transformações de matriz": "manual/pt-br/introduction/Matrix-transformations", + "Sistema de animação": "manual/pt-br/introduction/Animation-system", + "Gerenciamento de cor": "manual/pt-br/introduction/Color-management" + }, + + "Ferramentas de Build": { + "Testando com NPM": "manual/pt-br/buildTools/Testing-with-NPM" + } + + }, + + "Referência": { + + "Animation": { + "AnimationAction": "api/pt-br/animation/AnimationAction", + "AnimationClip": "api/pt-br/animation/AnimationClip", + "AnimationMixer": "api/pt-br/animation/AnimationMixer", + "AnimationObjectGroup": "api/pt-br/animation/AnimationObjectGroup", + "AnimationUtils": "api/pt-br/animation/AnimationUtils", + "KeyframeTrack": "api/pt-br/animation/KeyframeTrack", + "PropertyBinding": "api/pt-br/animation/PropertyBinding", + "PropertyMixer": "api/pt-br/animation/PropertyMixer" + }, + + "Animation / Tracks": { + "BooleanKeyframeTrack": "api/pt-br/animation/tracks/BooleanKeyframeTrack", + "ColorKeyframeTrack": "api/pt-br/animation/tracks/ColorKeyframeTrack", + "NumberKeyframeTrack": "api/pt-br/animation/tracks/NumberKeyframeTrack", + "QuaternionKeyframeTrack": "api/pt-br/animation/tracks/QuaternionKeyframeTrack", + "StringKeyframeTrack": "api/pt-br/animation/tracks/StringKeyframeTrack", + "VectorKeyframeTrack": "api/pt-br/animation/tracks/VectorKeyframeTrack" + }, + + "Audio": { + "Audio": "api/pt-br/audio/Audio", + "AudioAnalyser": "api/pt-br/audio/AudioAnalyser", + "AudioContext": "api/pt-br/audio/AudioContext", + "AudioListener": "api/pt-br/audio/AudioListener", + "PositionalAudio": "api/pt-br/audio/PositionalAudio" + }, + + "Cameras": { + "ArrayCamera": "api/pt-br/cameras/ArrayCamera", + "Camera": "api/pt-br/cameras/Camera", + "CubeCamera": "api/pt-br/cameras/CubeCamera", + "OrthographicCamera": "api/pt-br/cameras/OrthographicCamera", + "PerspectiveCamera": "api/pt-br/cameras/PerspectiveCamera", + "StereoCamera": "api/pt-br/cameras/StereoCamera" + }, + + "Constantes": { + "Animation": "api/pt-br/constants/Animation", + "Core": "api/pt-br/constants/Core", + "CustomBlendingEquation": "api/pt-br/constants/CustomBlendingEquations", + "BufferAttributeUsage": "api/pt-br/constants/BufferAttributeUsage", + "Materials": "api/pt-br/constants/Materials", + "Renderer": "api/pt-br/constants/Renderer", + "Textures": "api/pt-br/constants/Textures" + } + + } + + }, + + "fr": { + + "Manuel": { + + "Débuter": { + "Créer une scène": "manual/fr/introduction/Creating-a-scene", + "Installation": "manual/fr/introduction/Installation", + "Compatibilité WebGL": "manual/fr/introduction/WebGL-compatibility-check", + "Exécuter localement": "manual/fr/introduction/How-to-run-things-locally", + "Dessiner des lignes": "manual/fr/introduction/Drawing-lines", + "Créer un texte": "manual/fr/introduction/Creating-text", + "Importer des modèles 3D": "manual/fr/introduction/Loading-3D-models", + "Librairies et Plugins": "manual/fr/introduction/Libraries-and-Plugins", + "FAQ": "manual/fr/introduction/FAQ", + "Liens Utiles": "manual/fr/introduction/Useful-links" + }, + + "Étapes Suivantes": { + "Mettre les éléments à jour": "manual/fr/introduction/How-to-update-things", + "Supprimer un objet": "manual/fr/introduction/How-to-dispose-of-objects", + "Créer du contenu VR": "manual/fr/introduction/How-to-create-VR-content", + "Utiliser le post-processing": "manual/fr/introduction/How-to-use-post-processing", + "Matrices de transformation": "manual/fr/introduction/Matrix-transformations", + "Système d'animation": "manual/fr/introduction/Animation-system", + "Gestion des couleurs": "manual/fr/introduction/Color-management" + }, + + "Outils de build": { + "Tests avec NPM": "manual/fr/buildTools/Testing-with-NPM" + }, + "Noyau": { + "BufferAttribute": "api/fr/core/BufferAttribute", + "BufferGeometry": "api/fr/core/BufferGeometry" + } + + + }, + + "Référence": { + + "Animation": { + "AnimationAction": "api/fr/animation/AnimationAction", + "AnimationClip": "api/fr/animation/AnimationClip", + "AnimationMixer": "api/fr/animation/AnimationMixer", + "AnimationObjectGroup": "api/fr/animation/AnimationObjectGroup", + "AnimationUtils": "api/fr/animation/AnimationUtils", + "KeyframeTrack": "api/fr/animation/KeyframeTrack", + "PropertyBinding": "api/fr/animation/PropertyBinding", + "PropertyMixer": "api/fr/animation/PropertyMixer" + }, + + "Animation / Tracks": { + "BooleanKeyframeTrack": "api/fr/animation/tracks/BooleanKeyframeTrack", + "ColorKeyframeTrack": "api/fr/animation/tracks/ColorKeyframeTrack", + "NumberKeyframeTrack": "api/fr/animation/tracks/NumberKeyframeTrack", + "QuaternionKeyframeTrack": "api/fr/animation/tracks/QuaternionKeyframeTrack", + "StringKeyframeTrack": "api/fr/animation/tracks/StringKeyframeTrack", + "VectorKeyframeTrack": "api/fr/animation/tracks/VectorKeyframeTrack" + }, + + "Audio": { + "Audio": "api/fr/audio/Audio", + "AudioAnalyser": "api/fr/audio/AudioAnalyser", + "AudioContext": "api/fr/audio/AudioContext", + "AudioListener": "api/fr/audio/AudioListener", + "PositionalAudio": "api/fr/audio/PositionalAudio" + }, + + "Caméras": { + "ArrayCamera": "api/fr/cameras/ArrayCamera", + "Camera": "api/fr/cameras/Camera", + "CubeCamera": "api/fr/cameras/CubeCamera", + "OrthographicCamera": "api/fr/cameras/OrthographicCamera", + "PerspectiveCamera": "api/fr/cameras/PerspectiveCamera", + "StereoCamera": "api/fr/cameras/StereoCamera" + }, + "Constantes": { + "Animation": "api/fr/constants/Animation", + "Core": "api/fr/constants/Core", + "CustomBlendingEquation": "api/fr/constants/CustomBlendingEquations", + "BufferAttributeUsage": "api/fr/constants/BufferAttributeUsage", + "Materials": "api/fr/constants/Materials", + "Renderer": "api/fr/constants/Renderer", + "Textures": "api/fr/constants/Textures" + }, + "Géométries": { + "BoxGeometry": "api/fr/geometries/BoxGeometry", + "CapsuleGeometry": "api/fr/geometries/CapsuleGeometry", + "CircleGeometry": "api/fr/geometries/CircleGeometry", + "ConeGeometry": "api/fr/geometries/ConeGeometry", + "CylinderGeometry": "api/fr/geometries/CylinderGeometry", + "DodecahedronGeometry": "api/fr/geometries/DodecahedronGeometry", + "EdgesGeometry": "api/fr/geometries/EdgesGeometry", + "ExtrudeGeometry": "api/fr/geometries/ExtrudeGeometry", + "IcosahedronGeometry": "api/fr/geometries/IcosahedronGeometry", + "LatheGeometry": "api/fr/geometries/LatheGeometry", + "OctahedronGeometry": "api/fr/geometries/OctahedronGeometry", + "PlaneGeometry": "api/fr/geometries/PlaneGeometry", + "PolyhedronGeometry": "api/fr/geometries/PolyhedronGeometry", + "RingGeometry": "api/fr/geometries/RingGeometry", + "ShapeGeometry": "api/fr/geometries/ShapeGeometry", + "SphereGeometry": "api/fr/geometries/SphereGeometry", + "TetrahedronGeometry": "api/fr/geometries/TetrahedronGeometry", + "TorusGeometry": "api/fr/geometries/TorusGeometry", + "TorusKnotGeometry": "api/fr/geometries/TorusKnotGeometry", + "TubeGeometry": "api/fr/geometries/TubeGeometry", + "WireframeGeometry": "api/fr/geometries/WireframeGeometry" + } + + } + + }, + + "ru": { + + "Руководство": { + + "Приступая к работе": { + "Создание сцены": "manual/ru/introduction/Creating-a-scene", + "Установка": "manual/ru/introduction/Installation", + "Проверка совместимости с WebGL": "manual/ru/introduction/WebGL-compatibility-check", + "Локальная разработка ": "manual/ru/introduction/How-to-run-things-locally", + "Рисование линий": "manual/ru/introduction/Drawing-lines", + "Создание текста": "manual/ru/introduction/Creating-text", + "Загрузка 3D-моделей": "manual/ru/introduction/Loading-3D-models", + "Библиотеки и плагины": "manual/ru/introduction/Libraries-and-Plugins", + "Часто задаваемые вопросы": "manual/ru/introduction/FAQ", + "Полезные ссылки": "manual/ru/introduction/Useful-links" + }, + + "Next Steps": { + "How to update things": "manual/en/introduction/How-to-update-things", + "How to dispose of objects": "manual/en/introduction/How-to-dispose-of-objects", + "How to create VR content": "manual/en/introduction/How-to-create-VR-content", + "How to use post-processing": "manual/en/introduction/How-to-use-post-processing", + "Matrix transformations": "manual/en/introduction/Matrix-transformations", + "Animation system": "manual/en/introduction/Animation-system", + "Color management": "manual/en/introduction/Color-management" + }, + + "Build Tools": { + "Testing with NPM": "manual/en/buildTools/Testing-with-NPM" + } + + }, + + "Reference": { + + "Animation": { + "AnimationAction": "api/en/animation/AnimationAction", + "AnimationClip": "api/en/animation/AnimationClip", + "AnimationMixer": "api/en/animation/AnimationMixer", + "AnimationObjectGroup": "api/en/animation/AnimationObjectGroup", + "AnimationUtils": "api/en/animation/AnimationUtils", + "KeyframeTrack": "api/en/animation/KeyframeTrack", + "PropertyBinding": "api/en/animation/PropertyBinding", + "PropertyMixer": "api/en/animation/PropertyMixer" + }, + + "Animation / Tracks": { + "BooleanKeyframeTrack": "api/en/animation/tracks/BooleanKeyframeTrack", + "ColorKeyframeTrack": "api/en/animation/tracks/ColorKeyframeTrack", + "NumberKeyframeTrack": "api/en/animation/tracks/NumberKeyframeTrack", + "QuaternionKeyframeTrack": "api/en/animation/tracks/QuaternionKeyframeTrack", + "StringKeyframeTrack": "api/en/animation/tracks/StringKeyframeTrack", + "VectorKeyframeTrack": "api/en/animation/tracks/VectorKeyframeTrack" + }, + + "Audio": { + "Audio": "api/en/audio/Audio", + "AudioAnalyser": "api/en/audio/AudioAnalyser", + "AudioContext": "api/en/audio/AudioContext", + "AudioListener": "api/en/audio/AudioListener", + "PositionalAudio": "api/en/audio/PositionalAudio" + }, + + "Cameras": { + "ArrayCamera": "api/en/cameras/ArrayCamera", + "Camera": "api/en/cameras/Camera", + "CubeCamera": "api/en/cameras/CubeCamera", + "OrthographicCamera": "api/en/cameras/OrthographicCamera", + "PerspectiveCamera": "api/en/cameras/PerspectiveCamera", + "StereoCamera": "api/en/cameras/StereoCamera" + }, + + "Constants": { + "Animation": "api/en/constants/Animation", + "Core": "api/en/constants/Core", + "CustomBlendingEquation": "api/en/constants/CustomBlendingEquations", + "BufferAttributeUsage": "api/en/constants/BufferAttributeUsage", + "Materials": "api/en/constants/Materials", + "Renderer": "api/en/constants/Renderer", + "Textures": "api/en/constants/Textures" + }, + + "Core": { + "BufferAttribute": "api/en/core/BufferAttribute", + "BufferGeometry": "api/en/core/BufferGeometry", + "Clock": "api/en/core/Clock", + "EventDispatcher": "api/en/core/EventDispatcher", + "GLBufferAttribute": "api/en/core/GLBufferAttribute", + "InstancedBufferAttribute": "api/en/core/InstancedBufferAttribute", + "InstancedBufferGeometry": "api/en/core/InstancedBufferGeometry", + "InstancedInterleavedBuffer": "api/en/core/InstancedInterleavedBuffer", + "InterleavedBuffer": "api/en/core/InterleavedBuffer", + "InterleavedBufferAttribute": "api/en/core/InterleavedBufferAttribute", + "Layers": "api/en/core/Layers", + "Object3D": "api/en/core/Object3D", + "Raycaster": "api/en/core/Raycaster", + "Uniform": "api/en/core/Uniform" + }, + + "Core / BufferAttributes": { + "BufferAttribute Types": "api/en/core/bufferAttributeTypes/BufferAttributeTypes" + }, + + "Extras": { + "DataUtils": "api/en/extras/DataUtils", + "Earcut": "api/en/extras/Earcut", + "ImageUtils": "api/en/extras/ImageUtils", + "PMREMGenerator": "api/en/extras/PMREMGenerator", + "ShapeUtils": "api/en/extras/ShapeUtils" + }, + + "Extras / Core": { + "Curve": "api/en/extras/core/Curve", + "CurvePath": "api/en/extras/core/CurvePath", + "Interpolations": "api/en/extras/core/Interpolations", + "Path": "api/en/extras/core/Path", + "Shape": "api/en/extras/core/Shape", + "ShapePath": "api/en/extras/core/ShapePath" + }, + + "Extras / Curves": { + "ArcCurve": "api/en/extras/curves/ArcCurve", + "CatmullRomCurve3": "api/en/extras/curves/CatmullRomCurve3", + "CubicBezierCurve": "api/en/extras/curves/CubicBezierCurve", + "CubicBezierCurve3": "api/en/extras/curves/CubicBezierCurve3", + "EllipseCurve": "api/en/extras/curves/EllipseCurve", + "LineCurve": "api/en/extras/curves/LineCurve", + "LineCurve3": "api/en/extras/curves/LineCurve3", + "QuadraticBezierCurve": "api/en/extras/curves/QuadraticBezierCurve", + "QuadraticBezierCurve3": "api/en/extras/curves/QuadraticBezierCurve3", + "SplineCurve": "api/en/extras/curves/SplineCurve" + }, + + "Geometries": { + "BoxGeometry": "api/en/geometries/BoxGeometry", + "CapsuleGeometry": "api/en/geometries/CapsuleGeometry", + "CircleGeometry": "api/en/geometries/CircleGeometry", + "ConeGeometry": "api/en/geometries/ConeGeometry", + "CylinderGeometry": "api/en/geometries/CylinderGeometry", + "DodecahedronGeometry": "api/en/geometries/DodecahedronGeometry", + "EdgesGeometry": "api/en/geometries/EdgesGeometry", + "ExtrudeGeometry": "api/en/geometries/ExtrudeGeometry", + "IcosahedronGeometry": "api/en/geometries/IcosahedronGeometry", + "LatheGeometry": "api/en/geometries/LatheGeometry", + "OctahedronGeometry": "api/en/geometries/OctahedronGeometry", + "PlaneGeometry": "api/en/geometries/PlaneGeometry", + "PolyhedronGeometry": "api/en/geometries/PolyhedronGeometry", + "RingGeometry": "api/en/geometries/RingGeometry", + "ShapeGeometry": "api/en/geometries/ShapeGeometry", + "SphereGeometry": "api/en/geometries/SphereGeometry", + "TetrahedronGeometry": "api/en/geometries/TetrahedronGeometry", + "TorusGeometry": "api/en/geometries/TorusGeometry", + "TorusKnotGeometry": "api/en/geometries/TorusKnotGeometry", + "TubeGeometry": "api/en/geometries/TubeGeometry", + "WireframeGeometry": "api/en/geometries/WireframeGeometry" + }, + + "Helpers": { + "ArrowHelper": "api/en/helpers/ArrowHelper", + "AxesHelper": "api/en/helpers/AxesHelper", + "BoxHelper": "api/en/helpers/BoxHelper", + "Box3Helper": "api/en/helpers/Box3Helper", + "CameraHelper": "api/en/helpers/CameraHelper", + "DirectionalLightHelper": "api/en/helpers/DirectionalLightHelper", + "GridHelper": "api/en/helpers/GridHelper", + "PolarGridHelper": "api/en/helpers/PolarGridHelper", + "HemisphereLightHelper": "api/en/helpers/HemisphereLightHelper", + "PlaneHelper": "api/en/helpers/PlaneHelper", + "PointLightHelper": "api/en/helpers/PointLightHelper", + "SkeletonHelper": "api/en/helpers/SkeletonHelper", + "SpotLightHelper": "api/en/helpers/SpotLightHelper" + }, + + "Lights": { + "AmbientLight": "api/en/lights/AmbientLight", + "AmbientLightProbe": "api/en/lights/AmbientLightProbe", + "DirectionalLight": "api/en/lights/DirectionalLight", + "HemisphereLight": "api/en/lights/HemisphereLight", + "HemisphereLightProbe": "api/en/lights/HemisphereLightProbe", + "Light": "api/en/lights/Light", + "LightProbe": "api/en/lights/LightProbe", + "PointLight": "api/en/lights/PointLight", + "RectAreaLight": "api/en/lights/RectAreaLight", + "SpotLight": "api/en/lights/SpotLight" + }, + + "Lights / Shadows": { + "LightShadow": "api/en/lights/shadows/LightShadow", + "PointLightShadow": "api/en/lights/shadows/PointLightShadow", + "DirectionalLightShadow": "api/en/lights/shadows/DirectionalLightShadow", + "SpotLightShadow": "api/en/lights/shadows/SpotLightShadow" + }, + + "Loaders": { + "AnimationLoader": "api/en/loaders/AnimationLoader", + "AudioLoader": "api/en/loaders/AudioLoader", + "BufferGeometryLoader": "api/en/loaders/BufferGeometryLoader", + "Cache": "api/en/loaders/Cache", + "CompressedTextureLoader": "api/en/loaders/CompressedTextureLoader", + "CubeTextureLoader": "api/en/loaders/CubeTextureLoader", + "DataTextureLoader": "api/en/loaders/DataTextureLoader", + "FileLoader": "api/en/loaders/FileLoader", + "ImageBitmapLoader": "api/en/loaders/ImageBitmapLoader", + "ImageLoader": "api/en/loaders/ImageLoader", + "Loader": "api/en/loaders/Loader", + "LoaderUtils": "api/en/loaders/LoaderUtils", + "MaterialLoader": "api/en/loaders/MaterialLoader", + "ObjectLoader": "api/en/loaders/ObjectLoader", + "TextureLoader": "api/en/loaders/TextureLoader" + }, + + "Loaders / Managers": { + "DefaultLoadingManager": "api/en/loaders/managers/DefaultLoadingManager", + "LoadingManager": "api/en/loaders/managers/LoadingManager" + }, + + "Materials": { + "LineBasicMaterial": "api/en/materials/LineBasicMaterial", + "LineDashedMaterial": "api/en/materials/LineDashedMaterial", + "Material": "api/en/materials/Material", + "MeshBasicMaterial": "api/en/materials/MeshBasicMaterial", + "MeshDepthMaterial": "api/en/materials/MeshDepthMaterial", + "MeshDistanceMaterial": "api/en/materials/MeshDistanceMaterial", + "MeshLambertMaterial": "api/en/materials/MeshLambertMaterial", + "MeshMatcapMaterial": "api/en/materials/MeshMatcapMaterial", + "MeshNormalMaterial": "api/en/materials/MeshNormalMaterial", + "MeshPhongMaterial": "api/en/materials/MeshPhongMaterial", + "MeshPhysicalMaterial": "api/en/materials/MeshPhysicalMaterial", + "MeshStandardMaterial": "api/en/materials/MeshStandardMaterial", + "MeshToonMaterial": "api/en/materials/MeshToonMaterial", + "PointsMaterial": "api/en/materials/PointsMaterial", + "RawShaderMaterial": "api/en/materials/RawShaderMaterial", + "ShaderMaterial": "api/en/materials/ShaderMaterial", + "ShadowMaterial": "api/en/materials/ShadowMaterial", + "SpriteMaterial": "api/en/materials/SpriteMaterial" + }, + + "Math": { + "Box2": "api/en/math/Box2", + "Box3": "api/en/math/Box3", + "Color": "api/en/math/Color", + "Cylindrical": "api/en/math/Cylindrical", + "Euler": "api/en/math/Euler", + "Frustum": "api/en/math/Frustum", + "Interpolant": "api/en/math/Interpolant", + "Line3": "api/en/math/Line3", + "MathUtils": "api/en/math/MathUtils", + "Matrix3": "api/en/math/Matrix3", + "Matrix4": "api/en/math/Matrix4", + "Plane": "api/en/math/Plane", + "Quaternion": "api/en/math/Quaternion", + "Ray": "api/en/math/Ray", + "Sphere": "api/en/math/Sphere", + "Spherical": "api/en/math/Spherical", + "SphericalHarmonics3": "api/en/math/SphericalHarmonics3", + "Triangle": "api/en/math/Triangle", + "Vector2": "api/en/math/Vector2", + "Vector3": "api/en/math/Vector3", + "Vector4": "api/en/math/Vector4" + }, + + "Math / Interpolants": { + "CubicInterpolant": "api/en/math/interpolants/CubicInterpolant", + "DiscreteInterpolant": "api/en/math/interpolants/DiscreteInterpolant", + "LinearInterpolant": "api/en/math/interpolants/LinearInterpolant", + "QuaternionLinearInterpolant": "api/en/math/interpolants/QuaternionLinearInterpolant" + }, + + "Objects": { + "Bone": "api/en/objects/Bone", + "Group": "api/en/objects/Group", + "InstancedMesh": "api/en/objects/InstancedMesh", + "Line": "api/en/objects/Line", + "LineLoop": "api/en/objects/LineLoop", + "LineSegments": "api/en/objects/LineSegments", + "LOD": "api/en/objects/LOD", + "Mesh": "api/en/objects/Mesh", + "Points": "api/en/objects/Points", + "Skeleton": "api/en/objects/Skeleton", + "SkinnedMesh": "api/en/objects/SkinnedMesh", + "Sprite": "api/en/objects/Sprite" + }, + + "Renderers": { + "WebGLMultipleRenderTargets": "api/en/renderers/WebGLMultipleRenderTargets", + "WebGLRenderer": "api/en/renderers/WebGLRenderer", + "WebGL1Renderer": "api/en/renderers/WebGL1Renderer", + "WebGLRenderTarget": "api/en/renderers/WebGLRenderTarget", + "WebGL3DRenderTarget": "api/en/renderers/WebGL3DRenderTarget", + "WebGLArrayRenderTarget": "api/en/renderers/WebGLArrayRenderTarget", + "WebGLCubeRenderTarget": "api/en/renderers/WebGLCubeRenderTarget" + }, + + "Renderers / Shaders": { + "ShaderChunk": "api/en/renderers/shaders/ShaderChunk", + "ShaderLib": "api/en/renderers/shaders/ShaderLib", + "UniformsLib": "api/en/renderers/shaders/UniformsLib", + "UniformsUtils": "api/en/renderers/shaders/UniformsUtils" + }, + + "Renderers / WebXR": { + "WebXRManager": "api/en/renderers/webxr/WebXRManager" + }, + + "Scenes": { + "Fog": "api/en/scenes/Fog", + "FogExp2": "api/en/scenes/FogExp2", + "Scene": "api/en/scenes/Scene" + }, + + "Textures": { + "CanvasTexture": "api/en/textures/CanvasTexture", + "CompressedTexture": "api/en/textures/CompressedTexture", + "CompressedArrayTexture": "api/en/textures/CompressedArrayTexture", + "CubeTexture": "api/en/textures/CubeTexture", + "Data3DTexture": "api/en/textures/Data3DTexture", + "DataArrayTexture": "api/en/textures/DataArrayTexture", + "DataTexture": "api/en/textures/DataTexture", + "DepthTexture": "api/en/textures/DepthTexture", + "FramebufferTexture": "api/en/textures/FramebufferTexture", + "Source": "api/en/textures/Source", + "Texture": "api/en/textures/Texture", + "VideoTexture": "api/en/textures/VideoTexture" + } + + }, + + "Examples": { + + "Animations": { + "CCDIKSolver": "examples/en/animations/CCDIKSolver", + "MMDAnimationHelper": "examples/en/animations/MMDAnimationHelper", + "MMDPhysics": "examples/en/animations/MMDPhysics" + }, + + "Controls": { + "ArcballControls": "examples/en/controls/ArcballControls", + "DragControls": "examples/en/controls/DragControls", + "FirstPersonControls": "examples/en/controls/FirstPersonControls", + "FlyControls": "examples/en/controls/FlyControls", + "OrbitControls": "examples/en/controls/OrbitControls", + "PointerLockControls": "examples/en/controls/PointerLockControls", + "TrackballControls": "examples/en/controls/TrackballControls", + "TransformControls": "examples/en/controls/TransformControls" + }, + + "Geometries": { + "ConvexGeometry": "examples/en/geometries/ConvexGeometry", + "DecalGeometry": "examples/en/geometries/DecalGeometry", + "ParametricGeometry": "examples/en/geometries/ParametricGeometry", + "TextGeometry": "examples/en/geometries/TextGeometry" + }, + + "Helpers": { + "LightProbeHelper": "examples/en/helpers/LightProbeHelper", + "PositionalAudioHelper": "examples/en/helpers/PositionalAudioHelper", + "RectAreaLightHelper": "examples/en/helpers/RectAreaLightHelper", + "VertexNormalsHelper": "examples/en/helpers/VertexNormalsHelper", + "VertexTangentsHelper": "examples/en/helpers/VertexTangentsHelper" + }, + + "Lights": { + "LightProbeGenerator": "examples/en/lights/LightProbeGenerator" + }, + + "Loaders": { + "3DMLoader": "examples/en/loaders/3DMLoader", + "DRACOLoader": "examples/en/loaders/DRACOLoader", + "FontLoader": "examples/en/loaders/FontLoader", + "GLTFLoader": "examples/en/loaders/GLTFLoader", + "KTX2Loader": "examples/en/loaders/KTX2Loader", + "LDrawLoader": "examples/en/loaders/LDrawLoader", + "MMDLoader": "examples/en/loaders/MMDLoader", + "MTLLoader": "examples/en/loaders/MTLLoader", + "OBJLoader": "examples/en/loaders/OBJLoader", + "PCDLoader": "examples/en/loaders/PCDLoader", + "PDBLoader": "examples/en/loaders/PDBLoader", + "PRWMLoader": "examples/en/loaders/PRWMLoader", + "SVGLoader": "examples/en/loaders/SVGLoader", + "TGALoader": "examples/en/loaders/TGALoader" + }, + + "Objects": { + "Lensflare": "examples/en/objects/Lensflare" + }, + + "Post-Processing": { + "EffectComposer": "examples/en/postprocessing/EffectComposer" + }, + + "Exporters": { + "ColladaExporter": "examples/en/exporters/ColladaExporter", + "EXRExporter": "examples/en/exporters/EXRExporter", + "GLTFExporter": "examples/en/exporters/GLTFExporter", + "OBJExporter": "examples/en/exporters/OBJExporter", + "PLYExporter": "examples/en/exporters/PLYExporter" + }, + + "Math": { + "LookupTable": "examples/en/math/Lut", + "MeshSurfaceSampler": "examples/en/math/MeshSurfaceSampler", + "OBB": "examples/en/math/OBB" + }, + + "ConvexHull": { + "Face": "examples/en/math/convexhull/Face", + "HalfEdge": "examples/en/math/convexhull/HalfEdge", + "ConvexHull": "examples/en/math/convexhull/ConvexHull", + "VertexNode": "examples/en/math/convexhull/VertexNode", + "VertexList": "examples/en/math/convexhull/VertexList" + }, + + "Renderers": { + "CSS2DRenderer": "examples/en/renderers/CSS2DRenderer", + "CSS3DRenderer": "examples/en/renderers/CSS3DRenderer", + "SVGRenderer": "examples/en/renderers/SVGRenderer" + + }, + + "Utils": { + "BufferGeometryUtils": "examples/en/utils/BufferGeometryUtils", + "CameraUtils": "examples/en/utils/CameraUtils", + "SceneUtils": "examples/en/utils/SceneUtils", + "SkeletonUtils": "examples/en/utils/SkeletonUtils" + } + + }, + + "Developer Reference": { + + "WebGLRenderer": { + "WebGLProgram": "api/en/renderers/webgl/WebGLProgram" + } + + } + } } diff --git a/docs/manual/ar/introduction/How-to-create-VR-content.html b/docs/manual/ar/introduction/How-to-create-VR-content.html index 8a64ae8c639359..85f45c3b386e5a 100644 --- a/docs/manual/ar/introduction/How-to-create-VR-content.html +++ b/docs/manual/ar/introduction/How-to-create-VR-content.html @@ -22,7 +22,7 @@

    سير العمل

    -import { VRButton } from 'three/examples/jsm/webxr/VRButton.js'; +import { VRButton } from 'three/addons/webxr/VRButton.js';

    diff --git a/docs/manual/ar/introduction/How-to-use-post-processing.html b/docs/manual/ar/introduction/How-to-use-post-processing.html index e50896744a625d..7754c113567a9a 100644 --- a/docs/manual/ar/introduction/How-to-use-post-processing.html +++ b/docs/manual/ar/introduction/How-to-use-post-processing.html @@ -24,9 +24,9 @@

    سير العمل

    - import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'; - import { GlitchPass } from 'three/examples/jsm/postprocessing/GlitchPass.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { GlitchPass } from 'three/addons/postprocessing/GlitchPass.js';

    @@ -80,8 +80,8 @@

    تصاريح مخصصة

    - import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'; - import { LuminosityShader } from 'three/examples/jsm/shaders/LuminosityShader.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { LuminosityShader } from 'three/addons/shaders/LuminosityShader.js'; // later in your init routine diff --git a/docs/manual/ar/introduction/Installation.html b/docs/manual/ar/introduction/Installation.html index 09b42365a9d7eb..3286126daec76d 100644 --- a/docs/manual/ar/introduction/Installation.html +++ b/docs/manual/ar/introduction/Installation.html @@ -85,22 +85,25 @@

    التثبيت من CDN أو استضافة ثابتة

    - <script type="module"> + <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> + + <script type="importmap"> + { + "imports": { + "three": "https://unpkg.com/three@<version>/build/three.module.js" + } + } + </script> - // Find the latest version by visiting https://cdn.skypack.dev/three. + <script type="module"> - import * as THREE from 'https://cdn.skypack.dev/three@<version>'; + import * as THREE from 'three'; - const scene = new THREE.Scene(); + const scene = new THREE.Scene(); </script> -

    - ليست كل المزايا يمكن الوصول لها عبر وحدة build/three.module.js. بعض المكونات الأخرى من المكتبة - مثل الضوابط (controls) وعناصر التحميل (loaders) وتأثيرات ما بعد المعالجة (post-processing effects) - يجب إستدعائهم من الملفات الثانوية [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm]. -

    - -

    أمثلة

    @@ -113,7 +116,7 @@

    أمثلة

    - import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; const controls = new OrbitControls( camera, renderer.domElement ); @@ -123,13 +126,23 @@

    أمثلة

    - <script type="module"> + <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> + + <script type="importmap"> + { + "imports": { + "three": "https://unpkg.com/three@<version>/build/three.module.js", + "three/addons/": "https://unpkg.com/three@<version>/examples/jsm/" + } + } + </script> - // Find the latest version by visiting https://cdn.skypack.dev/three. + <script type="module"> - import { OrbitControls } from 'https://cdn.skypack.dev/three@<version>/examples/jsm/controls/OrbitControls.js'; + import * as THREE from 'three'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - const controls = new OrbitControls( camera, renderer.domElement ); + const controls = new OrbitControls( camera, renderer.domElement ); </script> diff --git a/docs/manual/ar/introduction/Loading-3D-models.html b/docs/manual/ar/introduction/Loading-3D-models.html index a424ff7d347846..83296cfe1977d9 100644 --- a/docs/manual/ar/introduction/Loading-3D-models.html +++ b/docs/manual/ar/introduction/Loading-3D-models.html @@ -69,7 +69,7 @@

    التحميل

    - import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

    diff --git a/docs/manual/ar/introduction/Useful-links.html b/docs/manual/ar/introduction/Useful-links.html index 249bc6d3b8646a..eb6c66525fb225 100644 --- a/docs/manual/ar/introduction/Useful-links.html +++ b/docs/manual/ar/introduction/Useful-links.html @@ -52,9 +52,6 @@

    مقالات ودورات أكثر شمولاً / متقدمة

  • [Link:https://aerotwist.com/tutorials/ Aerotwist] tutorials by [link:https://github.com/paullewis/ Paul Lewis]. -
  • -
  • - [link:http://learningthreejs.com/ Learning Three.js] – مدونة تحتوي على مقالات مخصصة لتدريس three.js
  • [link:https://discourse.threejs.org/t/three-js-bookshelf/2468 Three.js Bookshelf] - هل تبحث عن مزيد من الموارد حول three.js أو رسومات الكمبيوتر بشكل عام؟ تحقق من اختيار الأدبيات التي أوصى بها مجتمع المكتبة. diff --git a/docs/manual/en/introduction/Color-management.html b/docs/manual/en/introduction/Color-management.html index b5ee0a3c36386c..6fa1b1aabcb4f8 100644 --- a/docs/manual/en/introduction/Color-management.html +++ b/docs/manual/en/introduction/Color-management.html @@ -189,14 +189,6 @@

    Input color space

  • -
    -

    - ⚠️ WARNING: [page:Scene.fog], [page:Scene.background], and [page:WebGLRenderer.setClearColor] - are exceptions to the rule. These properties are unaffected by [page:WebGLRenderer.outputEncoding] - and so must store RGB components in the renderer's output color space. -

    -
    -

    ⚠️ WARNING: Many formats for 3D models do not correctly or consistently diff --git a/docs/manual/en/introduction/Creating-a-scene.html b/docs/manual/en/introduction/Creating-a-scene.html index f955b831d158c5..7ee97b030982a4 100644 --- a/docs/manual/en/introduction/Creating-a-scene.html +++ b/docs/manual/en/introduction/Creating-a-scene.html @@ -104,7 +104,7 @@

    Animating the cube

    If you insert all the code above into the file you created before we began, you should see a green box. Let's make it all a little more interesting by rotating it.

    -

    Add the following right above the `renderer.render` call in your `animate` function:

    +

    Add the following code right above the `renderer.render` call in your `animate` function:

    cube.rotation.x += 0.01; diff --git a/docs/manual/en/introduction/How-to-create-VR-content.html b/docs/manual/en/introduction/How-to-create-VR-content.html index d365f8072fbd21..c27063612bc0ce 100644 --- a/docs/manual/en/introduction/How-to-create-VR-content.html +++ b/docs/manual/en/introduction/How-to-create-VR-content.html @@ -24,7 +24,7 @@

    Workflow

    -import { VRButton } from 'three/examples/jsm/webxr/VRButton.js'; +import { VRButton } from 'three/addons/webxr/VRButton.js';

    diff --git a/docs/manual/en/introduction/How-to-use-post-processing.html b/docs/manual/en/introduction/How-to-use-post-processing.html index 677c3d5473bed0..31bb893b4d9546 100644 --- a/docs/manual/en/introduction/How-to-use-post-processing.html +++ b/docs/manual/en/introduction/How-to-use-post-processing.html @@ -28,9 +28,9 @@

    Workflow

    - import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'; - import { GlitchPass } from 'three/examples/jsm/postprocessing/GlitchPass.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { GlitchPass } from 'three/addons/postprocessing/GlitchPass.js';

    @@ -92,8 +92,8 @@

    Custom Passes

    - import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'; - import { LuminosityShader } from 'three/examples/jsm/shaders/LuminosityShader.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { LuminosityShader } from 'three/addons/shaders/LuminosityShader.js'; // later in your init routine diff --git a/docs/manual/en/introduction/Installation.html b/docs/manual/en/introduction/Installation.html index fb128f178454e8..8aaaa73bd45c97 100644 --- a/docs/manual/en/introduction/Installation.html +++ b/docs/manual/en/introduction/Installation.html @@ -64,7 +64,7 @@

    Install from CDN or static hosting

    The three.js library can be used without any build system, either by uploading files to your own web server or by using an existing CDN. Because the library relies on ES modules, any script that references it must use type="module" as shown below. - It is also required to define an Import Map which resolves the bare module specifier `three`. + It is also required to define an import map which resolves the bare module specifier `three`.

    @@ -88,37 +88,45 @@

    Install from CDN or static hosting

    - Not all features are accessed through the three entrypoint. Other popular parts of the library — such as controls, loaders, and post-processing effects — must be imported from the [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm] subfolder. To learn more, see Examples below. -

    -

    - Since Import maps are not yet supported by all browsers, it is necessary to add the polyfill *es-module-shims.js*. + Since import maps are not yet supported by all browsers, it is necessary to add the polyfill *es-module-shims.js*.

    -

    Examples

    +

    Addons

    - The core of three.js is focused on the most important components of a 3D engine. Many other useful components — such as controls, loaders, and post-processing effects — are part of the [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm] directory. They are referred to as "examples," because while you can use them off the shelf, they're also meant to be remixed and customized. These components are always kept in sync with the core library, whereas similar third-party packages on npm are maintained by different people and may not be up to date. + The core of three.js is focused on the most important components of a 3D engine. Many other useful components — such as controls, loaders, and post-processing effects — are part of the [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm] directory. They are referred to as "addons" (previously called "examples"), because while you can use them off the shelf, they're also meant to be remixed and customized. These components are always kept in sync with the core library, whereas similar third-party packages on npm are maintained by different people and may not be up to date.

    - Examples do not need to be installed separately, but do need to be imported separately. If three.js was installed with npm, you can load the [page:OrbitControls] component with: + Addons do not need to be installed separately, but do need to be imported separately. If three.js was installed with npm, you can load the [page:OrbitControls] component with:

    - - import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; const controls = new OrbitControls( camera, renderer.domElement );

    - If three.js was installed from a CDN, use the same CDN to install other components: + If three.js was installed from a CDN, use the same code, but with `three/addons/` in the import map.

    + <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> + + <script type="importmap"> + { + "imports": { + "three": "https://unpkg.com/three@<version>/build/three.module.js", + "three/addons/": "https://unpkg.com/three@<version>/examples/jsm/" + } + } + </script> + <script type="module"> - import { OrbitControls } from 'https://unpkg.com/three@<version>/examples/jsm/controls/OrbitControls.js'; + import * as THREE from 'three'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; const controls = new OrbitControls( camera, renderer.domElement ); @@ -126,7 +134,7 @@

    Examples

    - It's important that all files use the same version. Do not import different examples from different versions, or use examples from a different version than the three.js library itself. + It's important that all files use the same version. Do not import different addons from different versions, or use addons from a different version than the three.js library itself.

    Compatibility

    diff --git a/docs/manual/en/introduction/Libraries-and-Plugins.html b/docs/manual/en/introduction/Libraries-and-Plugins.html index 6e07b9e3d966af..17edb648526614 100644 --- a/docs/manual/en/introduction/Libraries-and-Plugins.html +++ b/docs/manual/en/introduction/Libraries-and-Plugins.html @@ -101,6 +101,7 @@

    Wrappers and Frameworks

  • [link:https://aframe.io/ A-Frame]
  • [link:https://github.com/pmndrs/react-three-fiber react-three-fiber]
  • [link:https://github.com/ecsyjs/ecsy-three ECSY]
  • +
  • [link:https://threlte.xyz/ Threlte]
  • diff --git a/docs/manual/en/introduction/Loading-3D-models.html b/docs/manual/en/introduction/Loading-3D-models.html index 76dc5257c93906..d0f7eb1a115b27 100644 --- a/docs/manual/en/introduction/Loading-3D-models.html +++ b/docs/manual/en/introduction/Loading-3D-models.html @@ -84,7 +84,7 @@

    Loading

    - import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

    diff --git a/docs/manual/en/introduction/Useful-links.html b/docs/manual/en/introduction/Useful-links.html index 8b311cd2a05b8a..3f1716e31baf2e 100644 --- a/docs/manual/en/introduction/Useful-links.html +++ b/docs/manual/en/introduction/Useful-links.html @@ -60,9 +60,6 @@

    More extensive / advanced articles and courses

  • [Link:https://aerotwist.com/tutorials/ Aerotwist] tutorials by [link:https://github.com/paullewis/ Paul Lewis]. -
  • -
  • - [link:http://learningthreejs.com/ Learning Three.js] – a blog with articles dedicated to teaching three.js
  • [link:https://discourse.threejs.org/t/three-js-bookshelf/2468 Three.js Bookshelf] - Looking for more resources about three.js or computer graphics in general? diff --git a/docs/manual/fr/buildTools/Testing-with-NPM.html b/docs/manual/fr/buildTools/Testing-with-NPM.html new file mode 100644 index 00000000000000..8c740bb26277c7 --- /dev/null +++ b/docs/manual/fr/buildTools/Testing-with-NPM.html @@ -0,0 +1,257 @@ + + + + + + + + + +

    Tests avec NPM ([name])

    + +

    + Ici vous sera expliqué comment obtenir three.js dans un environnement [link:https://nodejs.org/en/ node.js] pour que + vous puissez exécuter des tests automatisés. Les tests peuvent êtres lancés en lignes de commande, ou grâce à des + outils de CI automatisés comme [link:https://travis-ci.org/ Travis]. +

    + +

    La version courte

    + +

    + Si vous êtes à l'aise avec node et npm, + + $ npm install three --save-dev + + et ajoutez + + const THREE = require('three'); + + à votre test. +

    + +

    Créer un projet testable de zéro

    +

    + Si vous n'êtes pas familier avec ces outils, vous trouverez ici un guide rapide (pour linux, le processus d'installation + sera légèrement différent de celui pour Windows, mais les commandes NPM sont identiques). +

    + +

    Setup basique

    +
    +
      +
    1. + Installez [link:https://www.npmjs.org/ npm] et nodejs. La méthode la plus rapide ressemble généralement à + +$ sudo apt-get install -y npm nodejs-legacy +# fix any problems with SSL in the default registry URL +$ npm config set registry http://registry.npmjs.org/ + +
    2. + +
    3. + Créez un nouveau répertoire de projet + + $ mkdir test-example; cd test-example + +
    4. + +
    5. + Demandez à npm de créer un nouveau fichier de projet pour vous: + + $ npm init + + et acceptez tous les paramètres par défaut en appuyant sur Entrée à chaque prompt. + Cela créera package.json. +

    6. + +
    7. + Essayez la fonctionnalité de test avec + +$ npm test + + Cela va échouer, comme prévu. + Si vous jetez un coup d'oeil à votre package.json, la définition du test de script sera + + "test": "echo \"Error: no test specified\" && exit 1" + +
    8. + +
    +
    + +

    Ajouter mocha

    +
    + Nous allons utiliser [link:https://mochajs.org/ mocha]. + +
      +
    1. + Installez mocha avec + +$ npm install mocha --save-dev + + Remarquez que node_modules/ est créé et que vos dépendances y apparaissent. + Notez également que votre package.json a été mis à jour: la propriété devDependencies + est ajoutée et mis à jour par l'utilisation de --save-dev. +

    2. + +
    3. + Modifiez votre package.json pour qu'il utilise mocha pour effectuer les tests. Lorsqu'un test est invoqué, nous voulons simplement lancer + mocha et spécifier un verbose reporter. Par défaut cela lancera le contenu de test/ + (ne pas avoir de répertoire test/ peut causer une npm ERR!, créez le en utilisant mkdir test) + + "test": "mocha --reporter list" + +
    4. + +
    5. + Relancez les tests avec + + $ npm test + + + Cela doit maintenant réussir, signalant 0 passages (1ms) + ou similaire. +
    6. + +
    +
    + +

    Ajouter three.js

    +
    +
      +
    1. + Ajoutons notre dépendance de three.js avec + +$ npm install three --save-dev + +
        +
      • + Si vous avez besoin d'une version de three différente, utilisez + + $ npm show three versions + + pour voir + ce qui est disponible. Pour indiquer à npm la bonne, utilisez + + $ npm install three@0.84.0 --save + + (0.84.0 dans cet exemple). --save qui en fait une dépendance de ce projet, au lieu + d'une dépendance dev. Voir la documentation [link:https://docs.npmjs.com/cli/v8/configuring-npm/package-json ici] pour plus d'informations. +
      • +
      +
    2. + +
    3. + Mocha cherche des tests dans test/, exécutons donc la commande + + $ mkdir test + +
    4. + +
    5. + Finalement, nous avons besoin d'un test JS à lancer. Ajoutons un test simple qui va vérifier que + l'objet three.js est disponible et fonctionnel. Créez test/verify-three.js contenant: + +const THREE = require('three'); +const assert = require('assert'); + +describe('The THREE object', function() { + it('should have a defined BasicShadowMap constant', function() { + assert.notEqual('undefined', THREE.BasicShadowMap); + }), + + it('should be able to construct a Vector3 with default of x=0', function() { + const vec3 = new THREE.Vector3(); + assert.equal(0, vec3.x); + }) +}) + +
    6. + +
    7. + Finalement testons à nouveau avec $ npm test. Cela doit lancer le test ci-dessous et réussir, + affichant quelque chose du genre: + +The THREE object should have a defined BasicShadowMap constant: 0ms +The THREE object should be able to construct a Vector3 with default of x=0: 0ms +2 passing (8ms) + +
    8. +
    +
    + +

    Ajoutez votre propre code

    +
    + Vous devez faire trois choses: + +
      +
    1. + Écrivez un test pour un comportement attendu de votre code, et placez-le sous test/. + [link:https://github.com/air/encounter/blob/master/test/Physics-test.js Ici] vous trouverez un exemple issu d'un vrai projet. +
    2. + +
    3. + Exportez votre code de manière à ce que nodejs puisse le voir et l'utiliser quand la conjoncture le requiert. + Voir [link:https://github.com/air/encounter/blob/master/js/Physics.js ici]. +
    4. + +
    5. + Puis il faut require votre code dans le fichier de test, de la même manière que nous avons require('three') dans l'exemple au-dessus. +
    6. +
    + +

    + Les items 2 et 3 varient selon la façon dont vous organisez votre code. Dans l'exemple de Physics.js + montré plus-haut, la partie concernant l'export est à la toute fin. Nous assignons un objet à module.exports: +

    + +//============================================================================= +// make available in nodejs +//============================================================================= +if (typeof exports !== 'undefined') +{ + module.exports = Physics; +} + +
    + +

    Gérer les dépendances

    +
    +

    + Si vous utlisez déjà quelque chose d'astucieux comme require.js ou browserify, sautez cette partie. +

    +

    + Généralement un projet three.js s'exécute dans le navigateur. Le module de chargement est par conséquent réalisé par + le navigateur qui exécute un ensemble de scripts. Vos fichiers individuels n'ont pas à gérer les + dépendances. Dans un contexte nodejs, il n'y a pas d'index.html reliant tout + ensemble, vous devez donc être explicites. +

    +

    + Si vous exportez un module qui dépend d'autres fichiers, vous devrez dire à node de les charger. + Voici une approche: +

    +
      +
    1. + Au début de votre module, vérifiez si vous êtes dans un environnement nodejs. +
    2. +
    3. + Si c'est le cas, déclarez explicitement vos dépendances. +
    4. +
    5. + Si ce n'est pas le cas, vous êtes probablement dans un navigateur vous n'avez donc rien d'autre à faire. +
    6. +
    + Code d'exemple issu de Physics.js: + +//============================================================================= +// setup for server-side testing +//============================================================================= +if (typeof require === 'function') // test for nodejs environment +{ + const THREE = require('three'); + const MY3 = require('./MY3.js'); +} + +
    + + + diff --git a/docs/manual/fr/introduction/Animation-system.html b/docs/manual/fr/introduction/Animation-system.html new file mode 100644 index 00000000000000..babc395c6e71cc --- /dev/null +++ b/docs/manual/fr/introduction/Animation-system.html @@ -0,0 +1,147 @@ + + + + + + + + + +

    Système d'animation ([name])

    + +

    Aperçu

    + +

    + Dans le système d'animation de three.js vous pouvez animer différentes propriétés de vos modèles: + les os d'un [page:SkinnedMesh skinned and rigged model], les morph targets, les différentes propriétés des matériaux + (couleurs, opacité, booléens), la visibilité et les transformations. Les propriétés animées peuvent avoir différentes animations comme un fade-in, + un fade-out, un fondu ou un warp. Le poids et l'échelle temporelle des différentes animations simultanées + sur le même objet peuvent également être changées indépendamment. + Différentes animations sur le même objet peuvent-être + synchronisées.

    + + Pour effectuer tout cela dans un système homogène, le système d'animation three.js + [link:https://github.com/mrdoob/three.js/issues/6881 a complètement changé en 2015] + (attention aux informations dépassées!), et a maintenant une architecture similaire à + Unity/Unreal Engine 4. Cette page offre un bref aperçu des principaux composants du système + et de comment ils fonctionnent ensemble. + +

    + +

    Animation Clips

    + +

    + + Si vous aveez réussi à importer un modèle 3D (peu importe qu'il ait + des os ou une morph targets ou les deux) — par exemple en l'exportant depuis Blender avec le + [link:https://github.com/KhronosGroup/glTF-Blender-IO glTF Blender exporter] et + en le chargeant dans la scène three.js en utilisant [page:GLTFLoader] — un des champs doit-être + un tableau nommé "animations", contenant les [page:AnimationClip AnimationClips] + pour ce modèle (voir une liste des loaders possibles ci-dessous).

    + + Chaque `AnimationClip` conserve les données d'une certaine activité d'un objet. Si le + mesh est un personnage, par exemple, il pourrait y avoir un AnimationClip pour une marche, un second + pour un saut, un troisième pour un pas de côté et ainsi de suite. + +

    + +

    Keyframe Tracks

    + +

    + + A l'intérieur d'un `AnimationClip` les données pour chaque propriétés animées sont stockées + dans un [page:KeyframeTrack] séparé. En considérant que l'objet personnage a un [page:Skeleton skeleton], + un keyframe track pourrait stocker les changements de valeur de la position de l'os inférieur d'un bras + à travers le temps, un track différent stockerait les changements de valeur de la rotation du même bras, un troisème + pourrait stocker la position, la rotation ou l'échelle d'un autre os, ainsi de suite. Il doit-être clair qu'un, + AnimationClip peut-être composé de beaucoup de ce genre de tracks.

    + + En considérant que le modèle a un morph targets (par exemple un morph + target pour un visage amical et un autre pour un visage énervé), chaque track conserve + l'information de comment l'[page:Mesh.morphTargetInfluences influence] d'un certain morph + change durant l'exécution du clip. + +

    + +

    Mixer d'Animations

    + +

    + + Les informations stockées représentent uniquement la base de l'animation - le playback est en réalité contrôlé par + l'[page:AnimationMixer]. Vous vous doutez bien que ce n'est pas uniquement un visualiseur d'animations, mais + une simulation d'un hardware comme une vraie console de mixage , qui peut contrôler plusieurs animations + simultanément, les mélangeant et les fusionnant. + +

    + +

    Actions d'Animations

    + +

    + + L'`AnimationMixer` en lui-même a seulement quelques propriétés (générales) et méthodes, car il + peut-être contrôlé par l'[page:AnimationAction AnimationActions]. En configurant un + `AnimationAction` vous pouvez déterminer qu'un certain `AnimationClip` doit-être joué, mis en pause + ou stoppé sur un des mixers, si et à quelle fréquence le clip doit-être répeté, si il + doit-être joué avec un fade, une mise à l'échelle temporelle, et d'autres choses, comme le fondu + ou la synchronisation. + +

    + +

    Animations de Groupes d'Objets

    + +

    + + Si vous voulez qu'un groupe d'objets reçoive un statut d'animation partagé, vous pouvez utiliser un + [page:AnimationObjectGroup]. + +

    + +

    Formats et loaders supportés

    + +

    + Notez que tous les formats de modèles n'incluent pas les animations (notamment OBJ ne les supporte pas), et que seulement certains + loaders three.js supportent les séquences d'[page:AnimationClip AnimationClip]. Plusieurs autres supportent + ce type d'animations: +

    + +
      +
    • [page:ObjectLoader THREE.ObjectLoader]
    • +
    • THREE.BVHLoader
    • +
    • THREE.ColladaLoader
    • +
    • THREE.FBXLoader
    • +
    • [page:GLTFLoader THREE.GLTFLoader]
    • +
    • THREE.MMDLoader
    • +
    + +

    + Notez que 3ds max et Maya ne peuvent actuellement pas exporter plusieurs animations (qui ne sont pas sur + la même timeline) directement dans un seul fichier. +

    + +

    Exemple

    + + + let mesh; + + // Create an AnimationMixer, and get the list of AnimationClip instances + const mixer = new THREE.AnimationMixer( mesh ); + const clips = mesh.animations; + + // Update the mixer on each frame + function update () { + mixer.update( deltaSeconds ); + } + + // Play a specific animation + const clip = THREE.AnimationClip.findByName( clips, 'dance' ); + const action = mixer.clipAction( clip ); + action.play(); + + // Play all animations + clips.forEach( function ( clip ) { + mixer.clipAction( clip ).play(); + } ); + + + + diff --git a/docs/manual/fr/introduction/Color-management.html b/docs/manual/fr/introduction/Color-management.html new file mode 100644 index 00000000000000..4d4ad66bb9b8e1 --- /dev/null +++ b/docs/manual/fr/introduction/Color-management.html @@ -0,0 +1,328 @@ + + + + + + + + + + + + +

    Gestion des couleurs ([name])

    + +

    Qu'est ce qu'un espace colorimétrique?

    + +

    + Chaque espace colorimétrique est un ensemble de plusieurs décisions de design, choisies ensemble pour supporter + un large éventail de couleurs tout en satisfaisant les contraites techniques liées à la précision et aux technologies + d'affichage. Lors de la création d'un asset 3D, ou l'assemblage d'assets 3D ensemble dans une scène, il est + important de savoir quelles sont ces propriétés, et comment les propriétés d'un espace colorimétrique se rapporte + aux autres espaces colorimétriques de la scène. +

    + +
    + +
    + Les couleurs sRGB et le point blanc (D65) affichées dans le modèle CIE 1931 chromaticity + diagram. Les régions colorées représentent une projection 2D de la gamme sRGB, qui est un + volume 3D. Source: Wikipedia +
    +
    + +
      +
    • + Couleurs primaires: Les couleurs primaires (e.g. rouge, vert, bleu) ne sont pas absolues; elle sont + sélectionnées depuis le spectre visible basé sur les contraintes de la précision limitée et + les capacités des appareils d'affichage disponibles. Les couleurs sont exprimées comme un ratio des couleurs primaires. +
    • +
    • + Point blanc: La plupart des espaces colorimétriques sont conçus de telle manière qu'une somme équivalente + de couleurs primaires R = G = B apparaissent comme n'ayant pas de couleurs, ou "achromatique". L'apparition + des valeurs chromatiques (comme le blanc ou le gris) dépend de la perception humaine, qui dépend elle-même + fortement du contexte d'observation. Un espace colorimétrique spécifie son "point blanc" pour équilibrer + ces besoins. Le point blanc définit par l'espace colorimétrique sRGB est + D65. +
    • +
    • + Fonctions de transfert: Après avoir choisir la gamme de couleur et le modèle de couleur, il nous reste à toujours définir + le mapping ("fonctions de transfert") des valeurs numériques de l'espace colorimétrique. Est-ce-que r = 0.5 + représente 50% moins d'illumination physique que r = 1.0? Ou 50% de luminosité en moins, comme perçu + par l'oeil humain moyen? Ce sont différentes choses, et ces différences peuvent être représentées par + une fonction mathématique. Les fonctions de transfert peuvent être linéaires ou non-linéaires, selon + les objectifs de l'espace colorimétrique. Le sRGB définit des fonctions de transfert non-linéaires. Ces fonctions + fonctions sont parfois approximées en fonctions gamma, mais le terme "gamma" est + ambigu et doit-être évité dans ce contexte. +
    • +
    + + Ces trois paramètres — les couleurs primaires, le point blanc, et les fonctions de transfert — définissent un + espace colorimétrique, chacun est choisi pour un objectif particulier. Après avoir défini les paramètres, quelques termes supplémentaires + sont utiles: + +
      +
    • + Le modèle de couleur: La syntaxe pour identifier naturellement les couleurs au sein de la gamme de couleur choisie — + un système de coordonnées pour les couleurs. Dans three.js nous utilisons princpalement le système de couleurs RGB, + ayant trois coordonnées r, g, b ∈ [0,1] ("domaines fermés") ou + r, g, b ∈ [0,∞] ("domaine ouvert") chacune représentant une fraction d'une couleur + primaire. D'autres modèles de couleurs (HSL, Lab, LCH) sont communément utilisés pour un contrôle artistique. +
    • +
    • + La gamme de couleurs: Une fois que les couleurs primaires et le point blanc ont été choisis, ils représentent + un volume parmis le spectre visible (une "gamme"). Les couleurs qui ne sont pas dans ce volume ("hors de la gamme") + ne peuvent pas être exprimées par un domaine fermé [0,1] de valeurs RGB. Dans le domaine ouvert [0,∞], la gamme est + théoriquement infinie. +
    • +
    + +

    + Considérons deux espaces colorimétriques très communs: [page:SRGBColorSpace] ("sRGB") et + [page:LinearSRGBColorSpace] ("sRGB-Linéaire"). Les deux utilisent les mêmes primaires et point blanc, + et donc ont la même gamme de couleur. Le deux utilisent le modèle RGB. Leur seule différence sont + les fonctions de transfert — Le sRGB-Linéaire est linéaire et respecte l'intensité physique de la lumière. + Le sRGB utilise les fonctions de transfert non-linéaire du sRGB, et reproduit de manière plus proche la façon dont + l'oeil humain perçoit la lumière et la réactivité des écrans. +

    + +

    + Cette différence est imporante. Les calculs de lumières et les autres opérations de rendu doivent + généralement se produire dans un espace de lumière linéaire. Cependant, les espaces colorimétriques linéaires sont moins efficaces + dans le stockage d'images ou de framebuffer, et semblent incorrects qiuand ils sont vus par un humain. + Par conséquent, les textures d'entrée et l'image du rendu final vont généralement utiliser l'espace colorimétrique + sRGB non-linéaire. +

    + +
    +

    + ℹ️ NOTE: Alors que certains écrans modernes supportent des gammes plus larges comme Display-P3, + les APIs graphiques du web reposent largement sur le sRGB. Les applications utilisant three.js + aujourd'hui utilisent généralement uniquement le sRGB et les espaces colorimétriques sRGB-linéaires. +

    +
    + +

    Rôle des espaces colorimétriques

    + +

    + Workflows linéaires — requis pour les méthodes de rendu modernes — ils impliquent généralement + plus d'un espace de couleur, chacun assigné à un rôle particulier. Les espace colorimétriques linéaires et non-linéaires + sont appropriés pour différents usages, expliqués ci-dessous. +

    + +

    Espaces colorimétriques d'entrée

    + +

    + Les couleurs fournies à three.js — par les sélecteurs de couleurs, les textures, les modèles 3D, et d'autres sources — + ont toutes un espace colorimétrique associé. Celles qui ne sont pas déjà dans l'espace colorimétrique sRGB-Linéaire + doivent-être converties, et les textures doivent recevoir les bonnes consignes de texture.encoding. + Certaines conversions (pour l'héxadecimal et les couleurs CSS en sRGB) peuvent être automatisées si + l'héritage de la gestion des couleurs est désactivé avant l'initialisation des couleurs: +

    + + +THREE.ColorManagement.legacyMode = false; + + +
      +
    • + Matériaux, lumières, et shaders: Les couleurs des matériaux, lumières, et shaders stockent + des composantes RGB dans l'espace colorimétrique sRGB-Linéaire. +
    • +
    • + Vertex colors: [page:BufferAttribute BufferAttributes] stocke + des composantes RGB dans l'espace colorimétrique sRGB-Linéaire. +
    • +
    • + Textures colorées: PNG ou JPEG [page:Texture Textures] contiennent des informations de couleurs + (comme .map ou .emissiveMap) utilisant le domaine fermé de l'espace colorimétrique sRGB, et doivent être annotés avec + texture.encoding = sRGBEncoding. Des formats comme OpenEXR (parfois utilisés par .envMap pi + .lightMap) utilisent l'espace colorimétrique sRGB-Linéaire indiqué par texture.encoding = LinearEncoding, + et peuvent contenir des valeurs du domaine ouvert [0,∞]. +
    • +
    • + Textures non-colorées: Les textures qui ne stockent aucune information de couleur (comme .normalMap + ou .roughnessMap) n'ont pas d'espace colorimétrique associé, et utilisent généralement l'annotation de texture (par défaut) + texture.encoding = LinearEncoding. Dans de rares cas, les données ne concernant pas la couleur + peuvent être représentées par d'autres encodages non-linéaires pour des raisons techniques. +
    • +
    + +
    +

    + ⚠️ ATTENTION: Plusieurs formats de modèles 3D ne définissent par correctement ou de manière cohérente + les informations des espaces colorimétriques. Malgré le fait que three.js tente de gérer la plupart des situations, les problèmes + sont communs avec les formats de fichiers plus anciens. Pour de meilleurs résultats, utilisez glTF 2.0 ([page:GLTFLoader]) + et testez vos modèles 3D dans des visualiseurs en ligne relativement tôt pour vérifier que le modèle est correct en tant que tel. +

    +
    + +

    Espaces colorimétriques fonctionnels

    + +

    + Le rendu, l'interpolation, et plusieurs autres opérations doivent être performées dans un espace colorimétrique + au domaine ouvert, dans lequel les composantes RGB sont proportionnelles + à l'illumination physique. Dans three.js, l'espace colorimétrique est le sRGB-Linéaire. +

    + +

    L'espace colorimétrique de sortie

    + +

    + La sortie d'un écran, d'une image, ou d'une vidéo peut impliquer la conversion depuis un espace colorimétrique + sRGB-Linéaire au domaine ouvert vers un autre espace colorimétrique. Cette conversion peut être effectuée dans + le pass principal du moteur de rendu ([page:WebGLRenderer.outputEncoding]), ou durant le post-processing. +

    + + +renderer.outputEncoding = THREE.sRGBEncoding; // optional with post-processing + + +
      +
    • + Affichage: Les couleurs envoyées à un canvas WebGL pour affichage doivent-être dans l'espace colorimétrique + sRGB. +
    • +
    • + Image: Les couleurs envoyées à une image doivent utiliser l'espace colorimétrique approprié au + format et à l'utilisation. Les images entièrement rendues sur des textures au format PNG ou JPEG + utilisent généralement l'espace colorimétrique sRGB. Les images contenant de l'émission, des light maps, ou d'autres données + qui ne sont pas restreintes à l'intervalle [0,1] utiliseront généralement l'espace colorimétrique sRGB à domaine ouvert, + et un format d'image compatible comme OpenEXR. +
    • +
    + +
    +

    + ⚠️ ATTENTION: Les cibles de rendu doivent utiliser soit le sRGB soit le sRGB-Linéaire. Le sRGB gère + mieux la précision limitée. Dans le domaine fermé, 8 bits suffisent généralement au sRGB + tandis que ≥12 bits (demi float) peuvent être requis pour du sRGB-Linéaire. Si les étapes ultérieures + du pipeline nécessitent une entrée en sRGB-Linéaire, les conversions additionnelles peuvent + avoir un petit impact sur les performances. +

    +
    + +

    Utiliser des instances de THREE.Color

    + +

    + Les méthodes de lecture ou de modification des instances de [page:Color] partent du principe que les données sont déjà + dans l'espace colorimétrique de three.js, le sRGB-Linéaire. Les composantes RGB et HSL sont des représentations + directes de données stockées par l'instance Color, et ne sont jamais converties + implicitement. Les données Color peuvent être explicitement converties avec .convertLinearToSRGB() + ou .convertSRGBToLinear(). +

    + + + // RGB components (no change). + color.r = color.g = color.b = 0.5; + console.log( color.r ); // → 0.5 + + // Manual conversion. + color.r = 0.5; + color.convertSRGBToLinear(); + console.log( color.r ); // → 0.214041140 + + +

    + Avec ColorManagement.legacyMode = false d'activé (recommandé), certaines conversions + sont faites automatiquement. Parce que l'héxadécimal et les couleurs CSS sont généralement en sRGB, les méthodes [page:Color] + vont automatiquement convertir ces entrées du sRGB au sRGB-Linéaire dans des setters, ou + convertir depuis du sRGB-Linéaire au sRGB lors du renvoi de valeurs héxadécimales ou CSS depuis les getters. +

    + + + // Hexadecimal conversion. + color.setHex( 0x808080 ); + console.log( color.r ); // → 0.214041140 + console.log( color.getHex() ); // → 0x808080 + + // CSS conversion. + color.setStyle( 'rgb( 0.5, 0.5, 0.5 )' ); + console.log( color.r ); // → 0.214041140 + + // Override conversion with 'colorSpace' argument. + color.setHex( 0x808080, LinearSRGBColorSpace ); + console.log( color.r ); // → 0.5 + console.log( color.getHex( LinearSRGBColorSpace ) ); // → 0x808080 + console.log( color.getHex( SRGBColorSpace ) ); // → 0xBCBCBC + + +

    Erreurs communes

    + +

    + Quand une couleur ou une texture individuelle est mal configurée, elle apparaîtra plus lumineuse ou plus sombre + qu'attendu. Quand l'espace colorimétrique de sortie du moteur de rendu est mal configuré, la scène entière peut sembler + plus sombre (e.g. conversion manquante vers le sRGB) ou plus lumineuse (e.g. une double conversion vers le sRGB avec du + post-processing). Dans chaque cas le problème peut ne pas être uniforme, et simplement augmenter/diminuer + peut ne pas le résoudre. +

    + +

    + Un problème plus subtil peut se produire quand à la fois l'espace colorimétrique d'entrée et + l'espace colorimétrique de sortie sont incorrects — les niveaux de luminosité globaux peuvent être corrects, mais les couleurs peuvent changer + d'une manière inattendue sous différentes lumières, ou des ombres peuvent sembler plus abruptes et moins lisses + que prévu. Ces deux erreurs assemblées ne forment pas une réussite, et il est important que + l'espace colorimétrique soit linéaire ("scene referred") et que l'espace colorimétrique de sortie soit linéaire + ("display referred"). +

    + +

    Lectures additionnelles

    + + + + + + diff --git a/docs/manual/fr/introduction/Creating-a-scene.html b/docs/manual/fr/introduction/Creating-a-scene.html new file mode 100644 index 00000000000000..96b054512dae83 --- /dev/null +++ b/docs/manual/fr/introduction/Creating-a-scene.html @@ -0,0 +1,163 @@ + + + + + + + + + +

    Créer une scène ([name])

    + +

    L'objectif de cette section est d'effectuer une brève introduction à three.js. Nous commencerons par mettre en place une scène, avec un cube en rotation. Un exemple fonctionnel est fourni à la fin de la page au cas où vous seriez bloqués et que vous auriez besoin d'aide.

    + +

    Avant de commencer

    + +

    Avant de pouvoir utiliser three.js, vous aurez besoin d'un endroit pour l'afficher. Enregistrez le code HTML suivant dans un fichier sur votre ordinateur, ainsi qu'une copie de three.js dans le dossier js/, et ouvrez-le dans votre navigateur.

    + + + <!DOCTYPE html> + <html> + <head> + <meta charset="utf-8"> + <title>My first three.js app</title> + <style> + body { margin: 0; } + </style> + </head> + <body> + <script src="js/three.js"></script> + <script> + // Our Javascript will go here. + </script> + </body> + </html> + + +

    C'est tout. Tout le code qui va suivre doit aller dans la balise <script>.

    + +

    Créer la scène

    + +

    Pour pouvoir afficher quelque chose avec three.js, nous avons besoin de trois choses: une scène, une caméra et un moteur de rendu, afin de pouvoir effectuer un rendu de la scène à travers la caméra.

    + + + const scene = new THREE.Scene(); + const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); + + const renderer = new THREE.WebGLRenderer(); + renderer.setSize( window.innerWidth, window.innerHeight ); + document.body.appendChild( renderer.domElement ); + + +

    Prenons un moment pour expliquer ce qu'il se passe. Nous avons maintenant mis en place la scène, notre caméra et le moteur de rendu.

    + +

    Il existe différentes caméras dans three.js. Pour l'instant, utilisons une `PerspectiveCamera`.

    + +

    Le premier attribut est le `field of view`. Le champ de vision (FOV) est l'étendue de la scène visible sur l'écran à un moment donné. La valeur est en degrés.

    + +

    Le second attribut est nommé `aspect ratio`. Vous devrez presque toujours utiliser la largeur de l'élément divisée par sa hauteur, ou vous aurez le même résultat que lorsque vous regardez un vieux film sur une télévision avec un écran large - l'image semble écrasée.

    + +

    Les deux attributs suivants sont le `near` et le `far` du plan de coupe. Les objets plus loins de la caméra que la valeur `far` ou plus proches que `near` ne seront pas rendus. Vous n'avez pas besoin de vous préoccuper de ça pour l'instant, mais vous devriez ajuster ces valeurs dans vos applications afin d'obtenir de meilleures performances.

    + +

    Ensuite vient le moteur de rendu. C'est là où la magie opère. En plus du WebGLRenderer que nous utilisons ici, three.js est livré avec quelques autres moteurs de rendu, principalement utilisés comme moteurs de support pour les utilisateurs avec des navigateurs plus anciens ou n'ayant pas de support de WebGL.

    + +

    En plus d'instancier le moteur de rendu, nous avons aussi besoin de définir la taille à laquelle doit-être effectué le rendu de l'application. Il est recommandé d'utiliser la largeur et la hauteur de la zone qu'est censée occuper l'application - dans ce cas, la largeur et la hauteur de la fenêtre du navigateur. Pour les applications gourmandes en ressources, vous pouvez aussi donner à `setSize` des valeurs plus petites, comme `window.innerWidth/2` et `window.innerHeight/2`, qui permettra d'effectuer le rendu à un quart de sa taille initiale.

    + +

    Si vous souhaitez conserver la taille de votre application mais effectuer un rendu avec une résolution plus faible, vous pouvez le faire appelant `setSize` avec false comme `updateStyle` (le troisième argument). Par exemple, `setSize(window.innerWidth/2, window.innerHeight/2, false)` effectuera un rendu de votre application à demi-résolution, en considérant que votre <canvas> a 100% de largeur et de hauteur.

    + +

    Pour finir, nous ajoutons l'élement `renderer` à notre document HTML. C'est un élément <canvas> que le moteur de rendu utilise pour nous affficher la scène.

    + +

    "C'est sympa tout ça, mais où sont les cubes que tu nous avais promis?" Ajoutons-les maintenant.

    + + + const geometry = new THREE.BoxGeometry( 1, 1, 1 ); + const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); + const cube = new THREE.Mesh( geometry, material ); + scene.add( cube ); + + camera.position.z = 5; + + +

    Pour créer un cube, nous avons besoin d'une `BoxGeometry`. C'est un objet qui contient tous les points (`vertices`) et le remplissage (`faces`) du cube. Nous en verrons plus à ce propos dans le futur.

    + +

    En plus de la forme (geometry), nous avons besoin d'un matériau (material) pour le colorer. Three.js contient plusieurs matériaux, mais nous nous contenterons du `MeshBasicMaterial` pour l'instant. Tous les matériaux prennent un objet avec un ensemble de propriétés qui s'appliquent à eux. Pour rester dans la simplicité, ne renseignons qu'un attribut couleur avec la valeur `0x00ff00`, qui est du vert. Cela fonctionne de la même manière que les couleurs en CSS ou dans Photoshop (`hex colors`).

    + +

    La dernière chose dont nous avons besoin est un `Mesh`. Un mesh (maillage) est un objet qui prends une forme (geometry), et qui y applique un matériau (material), que nous pouvons ensuite insérer dans notre scène, et déplacer librement.

    + +

    Par défaut, quand nous appelons `scene.add()`, l'élément est ajouté aux coordonnées `(0,0,0)`. Cela causera la superposition du cube et de la caméra qui seront les uns à l'intérieur des autres. Pour éviter ça, nous devons simplement déplacer un peu la caméra.

    + +

    Faire un rendu de la scène

    + +

    Si vous avez copié le code du dessus dans le fichier HTML créé plus tôt, vous ne verrez rien. C'est parce que nous n'effectuons aucun rendu pour l'instant. Pour cela, nous avons besoin de ce que l'on appelle une `render or animate loop`.

    + + + function animate() { + requestAnimationFrame( animate ); + renderer.render( scene, camera ); + } + animate(); + + +

    Cela va créer une boucle qui va déclencher le moteur de rendu afin qu'il dessine la scène à chaque fois que l'écran est rafraîchi (sur un écran classique c'est 60 fois par secondes). Si l'écriture de jeux sur navigateur vous est étrangère, vous devez vous dire "Pourquoi nous ne créons pas de setInterval ?" C'est que - nous pourrions, mais `requestAnimationFrame` a plusieurs avantages. Le plus important est peut-être qu'il se met en pause lorsque l'utilisateur change d'onglet sur son navigateur, par conséquence, pas de perte de leur précieuse puissance de calcul ou de durée de vie de leur batterie.

    + +

    Animer le cube

    + +

    Si vous insérez tout le code au-dessus dans le fichier que vous avez créé avant que nous commencions, vous devriez voir un cube vert. Rendons tout ça un peu plus intéressant en le faisant tourner.

    + +

    Ajoutez le code suivant juste au dessus de l'appel `renderer.render` dans votre fonction `animate`:

    + + + cube.rotation.x += 0.01; + cube.rotation.y += 0.01; + + +

    Ceci sera exécuté à chaque frame (normalement 60 fois par secondes), et donnera au cube une belle animation de rotation. Pour résumer, tout ce que vous souhaitez déplacer ou changer pendant que l'application est en cours d'exécution doit passer par la boucle animate. Vous pouvez évidemment appeler d'autres fonctions depuis cet endroit, afin de ne pas finir avec une fonction `animate` de plusieurs centaines de lignes.

    + +

    Le résultat

    +

    Félicitations! Vous avez maintenant terminé votre première application three.js. C'est trivial, mais il faut bien commencer quelque part.

    + +

    Le code complet est disponible ci-dessous et ainsi que sous forme d'éditable [link:https://jsfiddle.net/fxurzeb4/ exemple live]. Amusez-vous avec pour avoir une meilleure idée de son fonctionnement.

    + + + <!DOCTYPE html> + <html> + <head> + <meta charset="utf-8"> + <title>My first three.js app</title> + <style> + body { margin: 0; } + </style> + </head> + <body> + <script src="js/three.js"></script> + <script> + const scene = new THREE.Scene(); + const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); + + const renderer = new THREE.WebGLRenderer(); + renderer.setSize( window.innerWidth, window.innerHeight ); + document.body.appendChild( renderer.domElement ); + + const geometry = new THREE.BoxGeometry( 1, 1, 1 ); + const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); + const cube = new THREE.Mesh( geometry, material ); + scene.add( cube ); + + camera.position.z = 5; + + function animate() { + requestAnimationFrame( animate ); + + cube.rotation.x += 0.01; + cube.rotation.y += 0.01; + + renderer.render( scene, camera ); + }; + + animate(); + </script> + </body> + </html> + + + diff --git a/docs/manual/fr/introduction/Creating-text.html b/docs/manual/fr/introduction/Creating-text.html new file mode 100644 index 00000000000000..65967cb8f4811f --- /dev/null +++ b/docs/manual/fr/introduction/Creating-text.html @@ -0,0 +1,142 @@ + + + + + + + + + +

    Créer un texte ([name])

    +
    +

    + Parfois vous aurez besoin d'utiliser du texte dans votre application three.js - ici + sont présentées quelques façons de le faire. +

    +
    + +

    1. DOM + CSS

    +
    +

    + Utiliser du HTML est généralement la manière la plus simple et la plus rapide d'ajouter du texte. Ceci est la méthode + utilisée pour les overlays descriptifs de la plupart des exemples three.js. +

    +

    Vous pouvez ajouter du contenu à une

    + <div id="info">Description</div> + +

    + et utiliser CSS pour donner une position absolute située au-dessus de tout le reste du contenu grâce au + z-index plus particulièrement si vous utilisez three.js en plein-écran. +

    + + +#info { + position: absolute; + top: 10px; + width: 100%; + text-align: center; + z-index: 100; + display:block; +} + + +
    + + +

    2. Utiliser [page:CSS2DRenderer] ou [page:CSS3DRenderer]

    +
    +

    + Utilisez ces moteurs de rendu pour dessiner des textes de haute-qualité contenus dans l'élément DOM de vos scène three.js. + Cette approche est similaire à la 1. excepté qu'avec ces moteurs de rendu les éléments peuvent être intégrés plus précisément et dynamiquement à la scène. +

    +
    + + +

    3. Associer un texte au canvas et l'utiliser comme [page:Texture]

    +
    +

    Utilisez cette méthode si vous souhaitez dessiner du texte facilement sur un plane dans votre scène three.js.

    +
    + + +

    4. Créez un modèle dans votre application 3D préférée et exportez le dans three.js

    +
    +

    Utilisez cette méthode si vous préférez travailler avec vos applications 3D puis importer vos modèles dans three.js.

    +
    + + +

    5. Forme de texte procédurale

    +
    +

    + Si vous souhaitez travailler en three.js pur ou créer des formes de texte 3D procédurales et dynamiques, + vous pouvez créer un mesh qui aura pour geometry une instance de THREE.TextGeometry: +

    +

    + new THREE.TextGeometry( text, parameters ); +

    +

    + Pour que cela fonctionne, dans tous les cas, votre TextGeometry aura besoin d'une instance de THREE.Font + avec comme paramètre "font". + + Voir [page:TextGeometry] pour avoir plus d'informations sur comment cela peut-être mis en place, une description de chaque + paramètre accepté, et une liste des fonts JSON qui viennent avec la distribution THREE.js. +

    + +

    Exemples

    + +

    + [example:webgl_geometry_text WebGL / geometry / text]
    + [example:webgl_shadowmap WebGL / shadowmap] +

    + +

    + Si Typeface ne fonctionne pas, ou que vous souhaitez une font qui n'est pas ici, il y a un tutoriel + avec un script python pour blender qui vous permet d'exporter du texte dans au format JSON de Three.js: + [link:http://www.jaanga.com/2012/03/blender-to-threejs-create-3d-text-with.html] +

    + +
    + + +

    6. Fonts Bitmap

    +
    +

    + BMFonts (bitmap fonts) permet de transformer les lots de glyphs en une seule BufferGeometry. Le rendu BMFont + supporte les sauts-de-ligne, l'espacement des lettres, le crénage, les fonctions de distance signée avec + des dérivées, les fonctions de distance signée multi-channel, les fonts multi-texture, et bien plus. + Voir [link:https://github.com/felixmariotto/three-mesh-ui three-mesh-ui] ou [link:https://github.com/Jam3/three-bmfont-text three-bmfont-text]. +

    +

    + Les fonts de base sont disponibles dans des projets comme + [link:https://github.com/etiennepinchon/aframe-fonts A-Frame Fonts], ou vous pouvez créer la votre + depuis n'importe quelle font .TTF, en optimisant les performances en n'incluant que les character requis par le projet. +

    +

    + Quelques outils utiles: +

    +
      +
    • [link:http://msdf-bmfont.donmccurdy.com/ msdf-bmfont-web] (web-based)
    • +
    • [link:https://github.com/soimy/msdf-bmfont-xml msdf-bmfont-xml] (ligne de commande)
    • +
    • [link:https://github.com/libgdx/libgdx/wiki/Hiero hiero] (applciations desktop)
    • +
    +
    + + +

    7. Troika Text

    +
    +

    + Le package [link:https://www.npmjs.com/package/troika-three-text troika-three-text] effectue un rendu + de qualité et anti-alisé des textes, utilisant une technique similaire à BMFonts, mais fonctionne directement avec n'importe quel fichier de font .TTF + ou .WOFF pour que vous n'ayez pas à pré-générer une texture glyph hors-ligne. Il ajoute également des fonctionnalités + comme: +

    +
      +
    • Des effets comme les strokes, les ombres portées, et les courbures
    • +
    • La capacité d'appliquer n'importe quel matériau three.js, même un ShaderMaterial customisé
    • +
    • Le support des ligatures de fonts, des scripts pour les lettres jointes, et un layout bi-directionnel de droite-à-gauche
    • +
    • Une optimisation pour les grandes quantités de textes dynamiques, en réalisant la plupart du travail en dehors du thread principal dans un web worker
    • +
    +
    + + + + diff --git a/docs/manual/fr/introduction/Drawing-lines.html b/docs/manual/fr/introduction/Drawing-lines.html new file mode 100644 index 00000000000000..58de372f59298d --- /dev/null +++ b/docs/manual/fr/introduction/Drawing-lines.html @@ -0,0 +1,64 @@ + + + + + + + + + +

    Dessiner des lignes ([name])

    +
    +

    + Disons que vous voulez dessiner une ligne ou un cercle, pas un wireframe [page:Mesh]. + Premièrement nous devons préparer le [page:WebGLRenderer renderer], [page:Scene scene] et la caméra (voir la page Créer une scène). +

    + +

    Voici le code que nous allons utiliser:

    + +const renderer = new THREE.WebGLRenderer(); +renderer.setSize( window.innerWidth, window.innerHeight ); +document.body.appendChild( renderer.domElement ); + +const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 500 ); +camera.position.set( 0, 0, 100 ); +camera.lookAt( 0, 0, 0 ); + +const scene = new THREE.Scene(); + +

    La prochaine chose que nous allons faire est définir un matériau (material). Pour les lignes, nous devons utiliser [page:LineBasicMaterial] ou [page:LineDashedMaterial].

    + +//create a blue LineBasicMaterial +const material = new THREE.LineBasicMaterial( { color: 0x0000ff } ); + + +

    + Après le matériau, nous devons utiliser une forme (geometry) avec quelques sommets: +

    + + +const points = []; +points.push( new THREE.Vector3( - 10, 0, 0 ) ); +points.push( new THREE.Vector3( 0, 10, 0 ) ); +points.push( new THREE.Vector3( 10, 0, 0 ) ); + +const geometry = new THREE.BufferGeometry().setFromPoints( points ); + + +

    Notez que les lignes sont tracées entre chaque paire consécutive de sommets, mais pas entre la première et la deuxième (la ligne n'est pas fermée).

    + +

    Maintenant que nous avons les points pour deux lignes et un matériau, nous pouvons les assembler pour former une ligne.

    + +const line = new THREE.Line( geometry, material ); + +

    Il ne manque qu'à l'ajouter à la scène et appeler [page:WebGLRenderer.render render].

    + + +scene.add( line ); +renderer.render( scene, camera ); + + +

    Vous devez maintenant voir une flèche pointant vers le haut, faite de deux lignes bleues.

    +
    + + diff --git a/docs/manual/fr/introduction/FAQ.html b/docs/manual/fr/introduction/FAQ.html new file mode 100644 index 00000000000000..04182d8a2ef412 --- /dev/null +++ b/docs/manual/fr/introduction/FAQ.html @@ -0,0 +1,60 @@ + + + + + + + + + +

    [name]

    + +

    Quel format de modèle 3D est le mieux supporté?

    +
    +

    + Le format recommandé pour l'import et l'export de modèles est glTF (GL Transmission Format). Parce que glTF est ciblé sur la rapidité du temps d'exécution, le format est compact et rapide à charger. +

    +

    + three.js fournit des loaders pour plusieurs autres formats populaires comme FBX, Collada ou OBJ. Néanmoins, vous devez toujours essayer d'établir un workflow basé sur glTF dans vos projets. Pour plus d'informations, voir [link:#manual/introduction/Loading-3D-models loading 3D models]. +

    +
    + +

    Pourquoi y a-t-il des tags meta viewport dans les exemples?

    +
    + <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> + +

    Ces tags contrôlent la taille du viewport et l'échelle pour les navigateurs mobiles (où le contenu de la page peut être rendu à des tailles différentes de celle du viewport visible).

    + +

    [link:https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html Safari: Using the Viewport]

    + +

    [link:https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag MDN: Using the viewport meta tag]

    +
    + +

    Comment conserver l'échelle de la scène au resize?

    +

    + Nous voulons que tous les objets, peu importe leur distance à la caméra, conservent leur taille, même si la fenêtre est redimensionnée. + + L'équation clé pour résoudre ce problème est la formule suivante, concernant la hauteur visible à une distance donnée: + + +visible_height = 2 * Math.tan( ( Math.PI / 180 ) * camera.fov / 2 ) * distance_from_camera; + + Si nous augmentons la hauteur de la fenêtre d'un certain pourcentage, alors nous souhaitons que la hauteur visible à toutes distances soit augmentée + du même pourcentage. + + Cela ne peut pas être fait en changeant la position de la camera. Il faut plutôt changer le champ de vision de celle-ci. + [link:http://jsfiddle.net/Q4Jpu/ Example]. +

    + +

    Pourquoi une partie de mon objet est invisible?

    +

    + Cela peut être causé par le face culling. Les faces ont une orientation qui décident quel côté est lequel. Et le culling retire la face arrière dans des circonstances normales. Pour voir si c'est bien votre problème, changez la propriété material side pour THREE.DoubleSide. + material.side = THREE.DoubleSide +

    + +

    Pourquoi three.js retourne quelques fois des valeurs étranges pour des inputs invalides?

    +

    + Pour des raisons de performances, three.js ne valide pas les inputs dans la plupart des cas. Il en va de la responsabilité de votre application de vérifier que tous les inputs sont valides. +

    + + diff --git a/docs/manual/fr/introduction/How-to-create-VR-content.html b/docs/manual/fr/introduction/How-to-create-VR-content.html new file mode 100644 index 00000000000000..bad2a211ede43a --- /dev/null +++ b/docs/manual/fr/introduction/How-to-create-VR-content.html @@ -0,0 +1,81 @@ + + + + + + + + + + + +

    Créer du contenu VR ([name])

    + +

    + Ce guide fournit une brève vue d'ensemble des composants basiques d'une application VR web + faite avec three.js. +

    + +

    Workflow

    + +

    + Premièrement, vous devez inclure [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/webxr/VRButton.js VRButton.js] + dans votre projet. +

    + + +import { VRButton } from 'three/addons/webxr/VRButton.js'; + + +

    + *VRButton.createButton()* fait deux choses importantes: Cela crée un bouton qui indique + la compatibilité VR. De plus, cela initie une session VR si l'utilisateur active le bouton. La seule chose que vous avez + à faire est d'ajouter la ligne de code suivante à votre application. +

    + + +document.body.appendChild( VRButton.createButton( renderer ) ); + + +

    + Ensuite, vous devez dire à votre instance de `WebGLRenderer` d'activer le rendu XR. +

    + + +renderer.xr.enabled = true; + + +

    + Finalement, vous n'avez plus qu'à ajuster votre boucle d'animation étant donné que nous ne pouvons pas utiliser notre fonction bien aimée + *window.requestAnimationFrame()*. Pour les projets VR nous utilisons [page:WebGLRenderer.setAnimationLoop setAnimationLoop]. + Le code minimal ressemble à cela: +

    + + +renderer.setAnimationLoop( function () { + + renderer.render( scene, camera ); + +} ); + + +

    Étapes Suivantes

    + +

    + Jetez un coup d'oeil à un des exemples officiels WebVR pour voir le workflow en action.

    + + [example:webxr_vr_ballshooter WebXR / VR / ballshooter]
    + [example:webxr_vr_cubes WebXR / VR / cubes]
    + [example:webxr_vr_dragging WebXR / VR / dragging]
    + [example:webxr_vr_paint WebXR / VR / paint]
    + [example:webxr_vr_panorama_depth WebXR / VR / panorama_depth]
    + [example:webxr_vr_panorama WebXR / VR / panorama]
    + [example:webxr_vr_rollercoaster WebXR / VR / rollercoaster]
    + [example:webxr_vr_sandbox WebXR / VR / sandbox]
    + [example:webxr_vr_sculpt WebXR / VR / sculpt]
    + [example:webxr_vr_video WebXR / VR / video] +

    + + + + diff --git a/docs/manual/fr/introduction/How-to-dispose-of-objects.html b/docs/manual/fr/introduction/How-to-dispose-of-objects.html new file mode 100644 index 00000000000000..b57a78dd14b1b1 --- /dev/null +++ b/docs/manual/fr/introduction/How-to-dispose-of-objects.html @@ -0,0 +1,124 @@ + + + + + + + + + + + +

    Supprimer un objet ([name])

    + +

    + Un des aspects importants dans l'amélioration des performances et qui permet d'éviter les fuites de mémoire dans votre application est la suppression des entités non-utilisées de la librairie. + Dès que vous créez une instance d'un type *three.js*, vous allouez une certaine quantité de mémoire. Toutefois, *three.js* crée pour certains objets + comme les formes ou les matériaux, des entités WebGL associées comme des buffers ou des programmes de shaders qui sont nécessaires au rendu. Il est important de + souligner que ces objets ne sont pas automatiquement débarassés. Au contraire, l'application doit utiliser une API particulière pour libérer ce genre de ressources. + Ce guide vous fournit une brève vue d'ensemble du fonctionnement de cette API et des objets considérés comme pertinents dans ce contexte. +

    + +

    Formes

    + +

    + Une forme représente généralement des informations concernant des sommets présentés comme un ensemble d'attributs. *three.js* crée en interne un objet de type [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer] + pour chaque attribut. Ces entités sont supprimées uniquement si vous appelez [page:BufferGeometry.dispose](). Si une forme devient obsolète dans votre application, + exécutez cette méthode pour libérer toutes les ressources associées. +

    + +

    Matériaux

    + +

    + Un matériau définit comment un objet est rendu. *three.js* utilise les informations de la définition du matériau pour construire un programme de shader pour le rendu. + Les programmes de shader peuvent être supprimés seulement si leur matériau respectif est supprimé. Dans un souci de performances, *three.js* essaye de réutiliser des + programmes de shaders existants si possible. Donc un programme de shader est supprimé uniquement si tous les matériaux associés sont supprimés. Vous pouvez indiquer la suppression d'un matériau en + exécutant [page:Material.dispose](). +

    + +

    Textures

    + +

    + La suppression d'un matériau n'a aucun effet sur les textures. Elles sont gérées séparément étant donné qu'une seule texture peut-être utilisée par plusieurs matériaux au même moment. + Chaque fois que vous créez une instance de [page:Texture], three.js crée en interne une instance de [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture]. + Comme les buffers, cet objet ne peut-être supprimé qu'en appelant [page:Texture.dispose](). +

    + +

    + Si vous utilisez une `ImageBitmap` comme source de données pour une texture, vous devez appeler [link:https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap/close ImageBitmap.close]() au niveau de l'application pour libérer toutes les ressources côté processeur. + Un appel automatisé de `ImageBitmap.close()` dans [page:Texture.dispose]() n'est pas possible, étant donné que le bitmap devient inutilisable, et que le moteur n'a aucun moyen de savoir si l'image bitmap est utilisée ailleurs. +

    + +

    Cibles de rendu

    + +

    + Les objets de type [page:WebGLRenderTarget] n'allouent pas qu'une instance de [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture] mais également + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLFramebuffer WebGLFramebuffer]s et [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderbuffer WebGLRenderbuffer]s + pour réaliser des rendus customisés. Ces objets ne sont désalloués qu'en exécutant [page:WebGLRenderTarget.dispose](). +

    + +

    Divers

    + +

    + Il y a d'autres classes du dossier example comme controls ou les effets de post processings qui fournissent la méthode `dispose()` pour retirer des event listeners internes + ou des cibles de rendu. En général, il est recommandé de jeter un coup d'oeil à l'API ou à la documentation d'une classe en cherchant un `dispose()`. Si il existe, vous devez l'utiliser pour faire votre petit ménage après utilisation. +

    + +

    FAQ

    + +

    Pourquoi *three.js* ne peut pas supprimer automatiquement les objets?

    + +

    + Cette question a été posée énormément de fois par la communauté, il est donc important de clarifier ce sujet. Le fait est que *three.js* ne connaît pas la durée de vie ou la portée des + entités comme les formes ou les matériaux créés par les utilisateurs. Il en va de la responsabilité de l'application. Par exemple, si un matériau n'est pas utilisé pour le rendu pour l'instant, + il peut être nécessaire pour le prochain frame. Donc si l'application décide qu'un certain objet peut-être supprimé, elle doit en notifier le moteur en appelant la méthode + `dispose()`. +

    + +

    Retirer un mesh de la scène supprime également sa forme et son matériau?

    + +

    + Non, vous devez explicitement supprimer la forme et le matériau via *dispose()*. Gardez à l'esprit que les formes et matériaux peuvent être partagés entre plusieurs objets 3D comme les meshes. +

    + +

    Est-ce que *three.js* fournit des informations à propos des objets en cache?

    + +

    + Oui. Il est possible d'interroger [page:WebGLRenderer.info], qui est une propriété spéciale du moteur de rendu avec une série d'informations et de statistiques à propos de l'usage graphique + et du proccessus de rendu. Entre autres, cela peut vous donner des informations comme le nombre de textures, de formes et de programmes de shaders stockés en interne. Si vous remarquez des problèmes de performance + dans votre application, une bonne idée serait de débugger cette propriété pour facilement identifier une fuite de mémoire. +

    + +

    Que se passe t-il quand on appelle `dispose()` sur une texture mais que l'image n'est pas encore chargée?

    + +

    + Des ressources internes sont allouées pour une texture uniquement si l'image est entièrement chargée. Si vous supprimez une texture avant que l'image soit chargée, + rien ne se produit. Aucune ressource n'était allouée il n'y a donc rien à libérer. +

    + +

    Que se passe t-il quand on appelle `dispose()` puis qu'on utilise l'objet plus tard?

    + +

    + Les ressources internes libérées sont réallouées par le moteur. Il n'y aura donc pas d'erreur d'exécution mais vous remarquerez probablement un impact négatif sur les performances au frame actuel, + particulièrement quand le programme de shaders doit-être compilé. +

    + +

    Comment gérer les objets *three.js* dans mon application? Quand dois-je supprimer les objets?

    + +

    + En général, il n'y a pas de recommandation universelle pour cette question. Savoir si l'utilisation de `dispose()` est appropriée dépend grandement des cas d'utilisation. Il est important de souligner qu'il + n'est pas nécessaire de toujours se débarasser des objets. Un bon exemple serait un jeu avec de multiple niveaux. Le bon moment pour supprimer les objets serait à un changement + de niveau. L'application devrait traverser les anciennes scènes et supprimer tous les matériaux, les formes et les textures obsolètes. Comme mentionné dans la section précédente, supprimer des + objets toujours utilisés ne produit pas d'erreur d'exécution. La pire chose qui pourrait se produire serait une baisse de la performance à un seul frame. +

    + +

    Exemples qui montrent l'utilisation de dispose()

    + +

    + [example:webgl_test_memory WebGL / test / memory]
    + [example:webgl_test_memory2 WebGL / test / memory2]
    +

    + + + + diff --git a/docs/manual/fr/introduction/How-to-run-things-locally.html b/docs/manual/fr/introduction/How-to-run-things-locally.html new file mode 100644 index 00000000000000..f7be7783c909dc --- /dev/null +++ b/docs/manual/fr/introduction/How-to-run-things-locally.html @@ -0,0 +1,169 @@ + + + + + + + + + +

    Exécuter localement ([name])

    +

    + Si vous n'utilisez que des formes procédurales et que vous ne chargez acune texture, vos pages web sont censées fonctionner + directement depuis le système de fichiers, vous n'avez qu'à double-cliquer sur le fichier HTML dans un explorateur de fichier et il + devrait apparaître en étant fonctionnel dans le navigateur (vous verrez file:///yourFile.html dans votre barre d'URL). +

    + +

    Contenu chargé depuis des fichiers externes

    +
    +

    + Si vous chargez des modèles ou des textures depuis des fichiers externes, à cause des restrictions de sécurité de la [link:http://en.wikipedia.org/wiki/Same_origin_policy same origin policy] des navigateurs, + charger depuis un système de fichiers échouera avec une security exception. +

    + +

    + Pour résoudre ce problème, exécutez vos fichiers depuis un serveur web local. Cela vous permettra d'accéder à votre page ainsi: +

    + +

    + http://localhost/yourFile.html +

    + +

    + Même s'il est également possible de changer les paramètres de sécurité du navigateur au lieu de faire tourner un serveur web local, + nous ne recommandons pas cette approche. Le faire pourrait exposer votre appareil à des vulnérabilités, si le + même navigateur est utilisé pour naviguer d'une manière classique sur le web. Utiliser un serveur local est une pratique standard dans + le développement web, et nous expliquons comment installer et utiliser un serveur local ci-dessous. +

    +
    + + +

    Créer un serveur local

    +
    +

    + Plusieurs langages de programmation ont un simple serveur HTTP d'intégré. Ils ne sont pas aussi fournis que + des serveurs de production comme [link:https://www.apache.org/ Apache] ou [link:https://nginx.org NGINX], néanmoins ils devraient être suffisants pour tester votre + application three.js. +

    + +

    Plugins pour les éditeurs de codes populaires

    +
    +

    Certains éditeurs de code ont des plugins qui créent un simple serveur à la demande.

    +
      +
    • [link:https://marketplace.visualstudio.com/items?itemName=yandeu.five-server Five Server] pour Visual Studio Code.
    • +
    • [link:https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer Live Server] pour Visual Studio Code.
    • +
    • [link:https://atom.io/packages/atom-live-server Live Server] pour Atom.
    • +
    +
    + +

    Servez

    +
    +

    + [link:https://greggman.github.io/servez Servez] est un serveur simple avec une interface graphique. +

    +
    + +

    Node.js five-server

    +
    +

    Serveur de développement avec capacité de redémarrage en direct. Pour l'installer:

    + +# Remove live-server (if you have it) +npm -g rm live-server + +# Install five-server +npm -g i five-server + +# Update five-server (from time to time) +npm -g i five-server@latest + + +

    Pour le lancer (depuis votre dossier local):

    + five-server . -p 8000 +
    + +

    Node.js http-server

    +
    +

    Node.js a un simple serveur de package HTTP. Pour l'installer:

    + npm install http-server -g + +

    Pour le lancer (depuis votre dossier local):

    + http-server . -p 8000 +
    + +

    Serveur Python

    +
    +

    + Si vous avez [link:http://python.org/ Python] d'installé, il devrait suffire pour exécuter + cela en ligne de commande (depuis votre dossier de travail): +

    + +//Python 2.x +python -m SimpleHTTPServer + +//Python 3.x +python -m http.server + + +

    Cela remontera les fichiers du dossier courant au localhost sur le port 8000, par exemple écrivez dans la barre d'URL:

    + + http://localhost:8000/ +
    + +

    Serveur Ruby

    +
    +

    Si vous avez Ruby d'installé, vous pouvez obtenir le même résultat en exécutant ceci à la place:

    + +ruby -r webrick -e "s = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => Dir.pwd); trap('INT') { s.shutdown }; s.start" + +
    + +

    Serveur PHP

    +
    +

    PHP a également un serveur web intégré, depuis la 5.4.0:

    + php -S localhost:8000 +
    + +

    Lighttpd

    +
    +

    + Lighttpd est un serveur web très léger pouvant servir pour des usages variés. Nous verrons comment l'installer sur OSX avec + HomeBrew ci-dessous. Contrairement aux autres serveurs cités ici, lighttpd est un serveur de production complet + et prêt à l'utilisation. +

    + +
      +
    1. + L'installer via homebrew + brew install lighttpd +
    2. +
    3. + Créez un fichier de configuration nommé lighttpd.conf dans le dossier où vous souhaitez exécuter votre + serveur web. Vous trouverez un exemple ici [link:http://redmine.lighttpd.net/projects/lighttpd/wiki/TutorialConfiguration here]. +
    4. +
    5. + Dans le fichier de configuration, changez le server.document-root pour le dossier d'où vous souhaitez remonter les fichiers. +
    6. +
    7. + Lancez-le avec + lighttpd -f lighttpd.conf +
    8. +
    9. + Rendez-vous sur http://localhost:3000/ et vous-y retrouverez les fichiers statiques du dossier + choisi. +
    10. +
    +
    +

    IIS

    +
    +

    Si vous utilisez Microsoft IIS comme serveur web. Veuillez ajouter un type de paramètres MIME concernant l'extension .fbx avant de charger.

    + File name extension: fbx MIME Type: text/plain +

    Par défaut, IIS bloque le téléchargementt des fichiers .fbx, .obj. Vous devez configurer IIS pour autoriser le téléchargement de ce genre de fichiers.

    +
    +

    + D'autres alternatives simples sont [link:http://stackoverflow.com/q/12905426/24874 présentées ici] + sur Stack Overflow. +

    +
    + + + diff --git a/docs/manual/fr/introduction/How-to-update-things.html b/docs/manual/fr/introduction/How-to-update-things.html new file mode 100644 index 00000000000000..601b9052e95599 --- /dev/null +++ b/docs/manual/fr/introduction/How-to-update-things.html @@ -0,0 +1,223 @@ + + + + + + + + + +

    Mettre les éléments à jour ([name])

    +
    +

    Tous les objets mettent par défaut automatiquement leur matrice à jour si ils ont été ajoutés dans la scène avec

    + +const object = new THREE.Object3D(); +scene.add( object ); + + ou si ils sont l'enfant d'un autre objet qui a été ajouté à la scène: + +const object1 = new THREE.Object3D(); +const object2 = new THREE.Object3D(); + +object1.add( object2 ); +scene.add( object1 ); //object1 and object2 will automatically update their matrices + +
    + +

    Cependant, si vous savez que l'objet va être statique, vous pouvez désactiver ce comportement et mettre la matrice à jour manuellement quand le besoin se présente.

    + + +object.matrixAutoUpdate = false; +object.updateMatrix(); + + +

    BufferGeometry

    +
    +

    + Les BufferGeometries stockent des informations comme (la position des sommets, l'indice des faces, les normales, les couleurs, + les UVs et tout autre attribut customisé) dans [page:BufferAttribute buffers] - c'est un, + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays typed arrays]. + Ceci les rend généralement plus rapides que les Geometries standard, le contrecoup est qu'il est plus difficile de les + utiliser. +

    +

    + En ce qui concerne la mise à jour des BufferGeometries, la chose la plus importante à comprendre est que + vous ne pouvez pas changer la taille des buffers (c'est très coûteux, en réalité, c'est équivalent à créer une nouvelle forme). + Vous pouvez toutefois mettre à jour le contenu des buffers. +

    +

    + Ce qui signifie que si vous savez qu'un attribut de votre BufferGeometry va augmenter, disons le nombre de sommets, + vous devez pré-allouer un buffer assez grand pour contenir n'importe quel nouveau sommet qui pourra être créé. Évidemment, + cela signifie également qu'il y aura une taille maximale pour votre BufferGeometry - il n'y a + aucun moyen de créer une BufferGeometry qui peut être étendue à l'infini d'une manière efficiente. +

    +

    + Nous utiliserons l'exemple d'une ligne qui est étendue à chaque rendu. Nous allouerons de l'espace + dans le buffer pour 500 sommets mais nous n'en dessinerons que deux au début, en utilisant [page:BufferGeometry.drawRange]. +

    + +const MAX_POINTS = 500; + +// geometry +const geometry = new THREE.BufferGeometry(); + +// attributes +const positions = new Float32Array( MAX_POINTS * 3 ); // 3 vertices per point +geometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); + +// draw range +const drawCount = 2; // draw the first 2 points, only +geometry.setDrawRange( 0, drawCount ); + +// material +const material = new THREE.LineBasicMaterial( { color: 0xff0000 } ); + +// line +const line = new THREE.Line( geometry, material ); +scene.add( line ); + +

    + Ensuite nous ajouterons aléatoirement des points à l'aide d'un pattern comme: +

    + +const positions = line.geometry.attributes.position.array; + +let x, y, z, index; +x = y = z = index = 0; + +for ( let i = 0, l = MAX_POINTS; i < l; i ++ ) { + + positions[ index ++ ] = x; + positions[ index ++ ] = y; + positions[ index ++ ] = z; + + x += ( Math.random() - 0.5 ) * 30; + y += ( Math.random() - 0.5 ) * 30; + z += ( Math.random() - 0.5 ) * 30; + +} + +

    + If you want to change the number of points rendered after the first render, do this: +

    + +line.geometry.setDrawRange( 0, newValue ); + +

    + If you want to change the position data values after the first render, you need to + set the needsUpdate flag like so: +

    + +line.geometry.attributes.position.needsUpdate = true; // required after the first render + + +

    + If you change the position data values after the initial render, you may need to recompute + bounding volumes so other features of the engine like view frustum culling or helpers properly work. +

    + +line.geometry.computeBoundingBox(); +line.geometry.computeBoundingSphere(); + + +

    + [link:https://jsfiddle.net/t4m85pLr/1/ Here is a fiddle] showing an animated line which you can adapt to your use case. +

    + +

    Examples

    + +

    + [example:webgl_custom_attributes WebGL / custom / attributes]
    + [example:webgl_buffergeometry_custom_attributes_particles WebGL / buffergeometry / custom / attributes / particles] +

    + +
    + +

    Materiaux

    +
    +

    Toutes les valeurs uniformes peuvent être changées librement(e.g. couleurs, textures, opacité, etc), les valeurs sont envoyées aux shaders à chaque frame.

    + +

    De plus, les paramètresen relation avec GLstate peuvent changer à tout moment (depthTest, blending, polygonOffset, etc).

    + +

    Les propriétés suivantes ne peuvent pas être changées facilement durant l'exécution (une fois que le matériau a été rendu au moins une fois):

    +
      +
    • numbers and types of uniforms
    • +
    • présence ou non de +
        +
      • texture
      • +
      • fog
      • +
      • vertex colors
      • +
      • morphing
      • +
      • shadow map
      • +
      • alpha test
      • +
      • transparent
      • +
      +
    • +
    + +

    Des changements dans ces propriétés exigent la création d'un nouveau programme de shader. Vous devrez définir

    + material.needsUpdate = true + +

    Gardez à l'esprit que cela risque d'être assez lent et de causer des saccades dans le framerate (particulièrement sur Windows, étant donné que la compilation de shader est plus lente dans DirectX que dans OpenGL).

    + +

    Pour des expériences pluis fluides vous pouvez émuler des changements dans ces fonctionnalités pour qu'elles contiennent un genre de valeurs "factices" comme zéro en intensité de lumières, des textures blanches ou zéro brouillard.

    + +

    Vous pouvez librement changer le matériau utilisé pour les différents morceaux de formes, mais pas comment un objet est divisé en morceaux (selon le matériau des faces).

    + +

    Si vous avez besoin d'avoir différentes configurations de matériaux durant l'exécution:

    +

    Si le nombre de matériaux / morceaux est petit, vous pouvez pré-diviser l'objet préalablement (e.g. cheveux / visage / corps / vêtements supérieurs / pantalon pour un humain, avant / côtés / toit / fenêtres / pneu / intérieur pour une voiture.).

    + +

    Si le nombre est grand (e.g. chaque face peut potentiellement être différente), songez à utiliser une autre solution, comme l'utilisation d'attributs / textures pour avoir une apparence différente par face.

    + +

    Exemples

    +

    + [example:webgl_materials_car WebGL / materials / car]
    + [example:webgl_postprocessing_dof WebGL / webgl_postprocessing / dof] +

    +
    + + +

    Textures

    +
    +

    Les images, canvas, vidéos et les données des textures doivent avoir le flag suivant si elles sont changées:

    + + texture.needsUpdate = true; + +

    La cible du rendu se met automatiquement à jour.

    + +

    Exemples

    +

    + [example:webgl_materials_video WebGL / materials / video]
    + [example:webgl_rtt WebGL / rtt] +

    + +
    + + +

    Caméras

    +
    +

    La position de la caméra et sa cible sont automatiquement mises à jour. Si vous devez changer

    +
      +
    • + fov +
    • +
    • + aspect +
    • +
    • + near +
    • +
    • + far +
    • +
    +

    + alors vous aurez besoin de recalculer la matrice de projection: +

    + +camera.aspect = window.innerWidth / window.innerHeight; +camera.updateProjectionMatrix(); + +
    + + diff --git a/docs/manual/fr/introduction/How-to-use-post-processing.html b/docs/manual/fr/introduction/How-to-use-post-processing.html new file mode 100644 index 00000000000000..e6619029e8b289 --- /dev/null +++ b/docs/manual/fr/introduction/How-to-use-post-processing.html @@ -0,0 +1,111 @@ + + + + + + + + + +

    Utiliser le post-processing ([name])

    + +

    + Plusieurs applications three.js effectuent un rendu de leurs objets 3D directement dans la scène. Parfois, vous souhaitez appliquer un ou plusieurs + effects graphiques comme la profondeur de champ, le flou lumineux, du grain, ou différents types d'Anti-aliasing. Le post-processing est une approche très utilisée + pour implémenter de tels effets. Premièrement, la scène est rendue dans une cible de rendu qui représente un buffer dans la mémoire de la carte vidéo. + A la prochaine étape un ou plusieurs effets de post-processing appliquent des filtres au buffer de l'image qui est finalement rendue à + l'écran. +

    +

    + three.js fournit une solution complète de post-processing via [page:EffectComposer] pour implémenter un tel workflow. +

    + +

    Workflow

    + +

    + La première étape est d'importer tous les fichiers nécessaires du dossier exemple. Le guide part du principe que vous utilisez le + [link:https://www.npmjs.com/package/three npm package] officiel de three.js. Pour notre démo basique, nous avons besoin des fichiers suivants. +

    + + + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { GlitchPass } from 'three/addons/postprocessing/GlitchPass.js'; + + +

    + Après avoir importé tous les fichiers correctement, nous pouvons créer notre composer en lui passant une instance de [page:WebGLRenderer]. +

    + + + const composer = new EffectComposer( renderer ); + + +

    + Lors de l'utilisation d'un composer, il est nécessaire de changer la boucle d'animation de l'application. Au lieu d'appeler la méthode de rendu + [page:WebGLRenderer], nous devons utiliser appeler [page:EffectComposer]. +

    + + + function animate() { + + requestAnimationFrame( animate ); + + composer.render(); + + } + + +

    + Notre composer est maintenant prêt, il est donc possible de configurer la chaîne d'effets de post-processing. Ces effets (passes) sont chargés de la création + de l'apparence visuelle finale de l'application. Ils sont traités dans l'ordre de leur ajout/insertion. Dans notre example, l'instance de `RenderPass` + est exécutée en première, puis l'instance de `GlitchPass` est exécutée. Le dernier effet activé de la chaîne est automatiquement rendu dans la scène. Le setup + des effets ressemble à ça: +

    + + + const renderPass = new RenderPass( scene, camera ); + composer.addPass( renderPass ); + + const glitchPass = new GlitchPass(); + composer.addPass( glitchPass ); + + +

    + `RenderPass` est normalement placé au début de la chaîne pour fournir la scène rendue en tant qu'entrée pour les prochaines étapes de post-processing. Dans notre cas, + `GlitchPass` va utiliser les données de l'image pour appliquer un effet de glitch. Regardez cet [link:https://threejs.org/examples/webgl_postprocessing_glitch exemple live] + pour voir cela en action. +

    + +

    Effets Intégrés

    + +

    + Vous pouvez utiliser une large palette d'effets de post-processing pré-définis fournis par le moteur. Ils se trouvent dans le dossier + [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/postprocessing postprocessing]. +

    + +

    Effets Customisés

    + +

    + Parfois vous voulez écrire un shader de post-processing customisé et l'inclure dans les effets (passes) de post-processing. Dans ce scénario, + vous pouvez utiliser `ShaderPass`. Après avoir importé le fichier et votre shader customisé, vous pouvez utiliser le code suivant pour mettre en place l'effet (pass). +

    + + + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { LuminosityShader } from 'three/addons/shaders/LuminosityShader.js'; + + // later in your init routine + + const luminosityPass = new ShaderPass( LuminosityShader ); + composer.addPass( luminosityPass ); + + +

    + Ce repository fournit un fichier appelé [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/shaders/CopyShader.js CopyShader] qui est + une bonne base de code pour créer votre propose shader customisé. `CopyShader` copie simplement le contenu de l'image du buffer de l'[page:EffectComposer] + à son buffer d'écriture sans y appliquer aucun effet. +

    + + + diff --git a/docs/manual/fr/introduction/Installation.html b/docs/manual/fr/introduction/Installation.html new file mode 100644 index 00000000000000..685fabf36e3349 --- /dev/null +++ b/docs/manual/fr/introduction/Installation.html @@ -0,0 +1,160 @@ + + + + + + + + + +

    [name]

    + +

    + Vous pouvez installer three.js avec [link:https://www.npmjs.com/ npm] et d'autres outils de build modernes, ou commencer rapidement avec just un hébergement static ou un CDN. Pour la plupart des utilisateurs, installer depuis npm est le meilleur choix. +

    + +

    + Peu importe votre choix, soyez cohérents et importez tous vos fichiers avec la même version de la librairie. Mélanger des fichiers de différentes sources peut causer une duplication de certaines parties de code, ou même casser l'application d'une manière imprédictible. +

    + +

    + Toutes les méthodes d'installation de three.js dépendent des Modules ES (voir [link:https://eloquentjavascript.net/10_modules.html#h_hF2FmOVxw7 Eloquent JavaScript: ECMAScript Modules]), ce qui vous permet d'inclure uniquement les parties requises de la librairie dans le projet final. +

    + +

    Installer depuis npm

    + +

    + Pour installer le module npm [link:https://www.npmjs.com/package/three three], ouvrez une fenêtre de terminal dans le dossier de votre projet et lancez la commande suivante: +

    + + + npm install three + + +

    + Le package sera téléchargé et installé. Puis vous pouvez l'importer dans votre projet: +

    + + + // Option 1: Import the entire three.js core library. + import * as THREE from 'three'; + + const scene = new THREE.Scene(); + + + // Option 2: Import just the parts you need. + import { Scene } from 'three'; + + const scene = new Scene(); + + +

    + En l'installant depuis npm, vous utiliserez quasiment toujours une sorte de [link:https://eloquentjavascript.net/10_modules.html#h_zWTXAU93DC bundling tool] pour combiner tous les packages dont votre projet a besoin en un seul fichier JavaScript. N'importe quel bundler JavaScript modern peut être utilisé avec three.js, le choix le plus populaire est [link:https://webpack.js.org/ webpack]. +

    + +

    + Toutes les fonctionnalités ne sont pas directement accédées depuis le module three (également appelé "bare import"). D'autres parties populaires de la librairie — comme les contrôles, les loaders, et les effets de post-processing — doivent être importés depuis le sous-dossier [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm]. Pour en apprendre plus, consulter Examples ci-dessous. +

    + +

    + Apprenez-en plus à propos des modules npm depuis [link:https://eloquentjavascript.net/20_node.html#h_J6hW/SmL/a Eloquent JavaScript: Installation avec npm]. +

    + +

    Installer depuis un CDN ou un hébergement statique

    + +

    + La librairie three.js peut être utilisée sans aucun build system, soit en uploadant les fichiers sur votre propre server web ou en utilisant un CDN existant. Parce que la librairie repose sur les modules ES, n'importe quel script qui y fait référence doit utiliser le type="module" comme montré ci-dessous. + Il est également requis de définir une Import Map qui effectue la résolution du bare module specifier `three`. +

    + + + <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> + + <script type="importmap"> + { + "imports": { + "three": "https://unpkg.com/three@<version>/build/three.module.js" + } + } + </script> + + <script type="module"> + + import * as THREE from 'three'; + + const scene = new THREE.Scene(); + + </script> + + +

    + Étant donné que les Import maps ne sont pas encore supportées par tous les navigateurs, il est nécessaire d'ajouter le polyfill *es-module-shims.js*. +

    + +

    Addons

    + +

    + Le noyau de three.js est concentré sur les composants les plus importans d'un moteur 3D. Plusieurs autres composants utiles - comme les contrôles, les loaders, et les effets de post-processing - font partie du dossier [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm]. Ils sont désignés comme "exemples", parce que, en plus de pouvoir les utiliser directement tel qu'ils sont, ils sont aussi supposés être remixés et customisés. Ces composants sont toujours synchronisés avec le noyau de la librarie, là où des packages tiers similaires sur npm sont maintenus par différentes personnes et peuvent ne pas être à jour. +

    + +

    + Les addons n'ont pas besoin d'être installés séparément, mais doivent être importés séparément. Si three.js a été installé avec npm, vous pouvez charger le composant [page:OrbitControls] avec: +

    + + + + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + + const controls = new OrbitControls( camera, renderer.domElement ); + + +

    + Si three.js a été installé depuis un CDN, utilisez le même CDN pour installer d'autres composants: +

    + + + <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> + + <script type="importmap"> + { + "imports": { + "three": "https://unpkg.com/three@<version>/build/three.module.js", + "three/addons/": "https://unpkg.com/three@<version>/examples/jsm/" + } + } + </script> + + <script type="module"> + + import * as THREE from 'three'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + + const controls = new OrbitControls( camera, renderer.domElement ); + + </script> + + +

    + Il est important que tous les fichiers utilisent la même version. N'importez pas différents addons de différentes versions, ou n'utilisez pas d'addons d'une version de three.js différente de celle de la librarie elle-même. +

    + +

    Compatibilité

    + +

    Imports CommonJS

    + +

    + Alors que la plupart des bundlers JavaScript modernes supportent les modules ES par défaut, cela peut ne pas être le cas de certains build tools plus anciens. Dans ce cas, vous pouvez probablement configurer le bundler pour qu'il comprenne les modules ES: [link:http://browserify.org/ Browserify] a just besoin du plugin [link:https://github.com/babel/babelify babelify], par exemple. +

    + +

    Node.js

    + +

    + Parce que three.js est construit pour le web, il dépend de navigateurs et d'APIs DOM qui n'existent pas toujours dans Node.js. Certains de ces problèmes peuvent être résolus en utilisant des morceaux de code comme [link:https://github.com/stackgl/headless-gl headless-gl], ou en remplaçant des composents comme [page:TextureLoader] avec des alternatives customisées. D'autres APIs DOM peuvent être profondément entrelacées avec le code qui les utilises, et il sera compliqué de le modifier. Nous soutenons les pull requests simples et maintenables pour améliorer le support de Node.js, mais recommendons d'ouvrir une issue pour parler de vos améliorations avant. +

    + +

    + Faites attention à bien ajouter `{ "type": "module" }` à votre `package.json` pour autoriser les modules ES6 dans votre projet Node. +

    + + + diff --git a/docs/manual/fr/introduction/Libraries-and-Plugins.html b/docs/manual/fr/introduction/Libraries-and-Plugins.html new file mode 100644 index 00000000000000..0f516d5a996a27 --- /dev/null +++ b/docs/manual/fr/introduction/Libraries-and-Plugins.html @@ -0,0 +1,108 @@ + + + + + + + + + +

    Librairies et Plugins ([name])

    + +

    + Ici sont listés des plugins et librairies développés en externe et compatibles avec three.js. Cette + liste et les packages associés sont maintenus par la communauté et ne sont pas forcément + à jour. Si vous souhaitez mettre à jour cette liste, faites une PR! +

    + +

    Physique

    + +
      +
    • [link:https://github.com/lo-th/Oimo.js/ Oimo.js]
    • +
    • [link:https://enable3d.io/ enable3d]
    • +
    • [link:https://github.com/kripken/ammo.js/ ammo.js]
    • +
    • [link:https://github.com/pmndrs/cannon-es cannon-es]
    • +
    + +

    Postprocessing

    + +

    + En plus de [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/postprocessing official three.js postprocessing effects], + du support pour des effets et frameworks additionels sont disponibles à travers des librairies externes. +

    + +
      +
    • [link:https://github.com/vanruesc/postprocessing postprocessing]
    • +
    + +

    Intersections et Performance de Raycast

    + +
      +
    • [link:https://github.com/gkjohnson/three-mesh-bvh three-mesh-bvh]
    • +
    + +

    Path Tracing

    + +
      +
    • [link:https://github.com/gkjohnson/three-gpu-pathtracer three-gpu-pathtracer]
    • +
    + +

    Formats de fichiers

    + +

    + En plus de [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/loaders official three.js loaders], + du support pour des formats additionels sont disponibles à travers des librairies externes. +

    + +
      +
    • [link:https://github.com/gkjohnson/urdf-loaders/tree/master/javascript urdf-loader]
    • +
    • [link:https://github.com/NASA-AMMOS/3DTilesRendererJS 3d-tiles-renderer-js]
    • +
    • [link:https://github.com/kaisalmen/WWOBJLoader WebWorker OBJLoader]
    • +
    • [link:https://github.com/IFCjs/web-ifc-three IFC.js]
    • +
    + +

    Géometrie

    + +
      +
    • [link:https://github.com/spite/THREE.MeshLine THREE.MeshLine]
    • +
    + +

    Texte 3D et Layout

    + +
      +
    • [link:https://github.com/protectwise/troika/tree/master/packages/troika-three-text troika-three-text]
    • +
    • [link:https://github.com/felixmariotto/three-mesh-ui three-mesh-ui]
    • +
    + +

    Systèmes de particules

    + +
      +
    • [link:https://github.com/creativelifeform/three-nebula three-nebula]
    • +
    + +

    Cinématique inverse

    + +
      +
    • [link:https://github.com/jsantell/THREE.IK THREE.IK]
    • +
    • [link:https://github.com/lo-th/fullik fullik]
    • +
    • [link:https://github.com/gkjohnson/closed-chain-ik-js closed-chain-ik]
    • +
    + +

    Jeu IA

    + +
      +
    • [link:https://mugen87.github.io/yuka/ yuka]
    • +
    • [link:https://github.com/donmccurdy/three-pathfinding three-pathfinding]
    • +
    + +

    Wrappers et Frameworks

    + +
      +
    • [link:https://aframe.io/ A-Frame]
    • +
    • [link:https://github.com/pmndrs/react-three-fiber react-three-fiber]
    • +
    • [link:https://github.com/ecsyjs/ecsy-three ECSY]
    • +
    • [link:https://threlte.xyz/ Threlte]
    • +
    + + + diff --git a/docs/manual/fr/introduction/Loading-3D-models.html b/docs/manual/fr/introduction/Loading-3D-models.html new file mode 100644 index 00000000000000..09f99b9f46683d --- /dev/null +++ b/docs/manual/fr/introduction/Loading-3D-models.html @@ -0,0 +1,167 @@ + + + + + + + + + + + +

    Importer des modèles 3D ([name])

    + +

    + Les modèles 3D sont disponibles dans des centaines de formats, chacun ayant des objectifs + différents, des fonctionnalités assorties, et une complexité variable. Même si + + three.js fournit plusieurs loaders, choisir le bon format et + workflow vous fera gagner du temps et vous épargnera beaucoup de frustration par la suite. Certains formats sont + difficiles à appréhender, inefficaces pour les exépriences en temps-réel, ou simplement + pas entièrement supportés pour le moment. +

    + +

    + Ce guide vous fournit un workflow recommandé pour la plupart des utilisateurs, et des suggestions + concernant quoi essayer si les choses ne se déroulent pas comme prévu. +

    + +

    Avant de commencer

    + +

    + Si vous n'êtes pas familier avec le fait de lancer un serveur local, commencez par + [link:#manual/introduction/How-to-run-things-locally how to run things locally]. + Plusieurs erreurs communes concernant les modèles 3D peuvent-être évitées en hébergeant les fichiers + correctement. +

    + +

    Workflow recommandé

    + +

    + Dans la mesure du possible, nous recommandons l'utilisation de glTF (GL Transmission Format). Les versions + .GLB et .GLTF du format sont + bien supportées. Étant-donné que glTF se concentre sur la réduction du temps d'exécution du chargement des modèles, il est + compact et rapide à transmettre. Les fonctionnalités inclusent sont les meshes, les matériaux, + les textures, les skins, les squelettes, les morph targets, les animations, les lumières, et les + caméras. +

    + +

    + Les fichiers glTF appartenant au domaine public sont disponibles sur des sites comme + + Sketchfab, différents outils incluent l'export de glTF: +

    + + + +

    + Si votre outil de prédilection n'inclut pas le support des glTF, pensez à demander + aux auteurs d'inclure l'export des glTF, ou postez sur + the glTF roadmap thread. +

    + +

    + Quand glTF n'est pas utilisable, des formats populaires comme FBX, OBJ, ou COLLADA + sont également disponibles et régulièrement maintenus. +

    + +

    Charger les modèles

    + +

    + Seulement quelques loaders (e.g. [page:ObjectLoader]) sont inclus par défaut dans + three.js — les autres doivent être ajoutés individuellement à votre application. +

    + + + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + + +

    + Une fois que vous avez importé un loader, vous pouvez ajouter un modèle à votre scène. La syntaxe varie selon + les loaders — quand vous utilisez un autre format, jetez un oeil à la documentation de ce + loader. Pour glTF, l'utilisation avec des scripts globaux doit-être: +

    + + + const loader = new GLTFLoader(); + + loader.load( 'path/to/model.glb', function ( gltf ) { + + scene.add( gltf.scene ); + + }, undefined, function ( error ) { + + console.error( error ); + + } ); + + +

    + Voir [page:GLTFLoader GLTFLoader documentation] pour plus de détails. +

    + +

    Dépannage

    + +

    + Vous avez passé des heures à modeler votre chef-d'oeuvre artisanal, vous le chargez sur + la page web, et — oh non! 😭 Il est tordu, mal coloré, ou tout simplement porté-disparu. + Commencez par ces étapes de dépannage: +

    + +
      +
    1. + Vérifiez la console JavaScript à la recherche d'erreurs, et assurez-vous d'utiliser un callback + `onError` à l'appel de `.load()` pour afficher le résultat. +
    2. +
    3. + Visualisez le modèle dans une autre application. Pour glTF, des visualiseurs de type cliquez-glissez + sont disponibles pour + three.js et + babylon.js. Si le modèle + apparaît correctement dans une ou plusieurs autres applications, + signalez une erreur auprès de three.js. + Si le modèle ne peut être visualisé dans n'importe quelle application, nous encourageons fortement + le signalement d'un bug auprès de l'application avec laquelle vous avez réalisé le modèle 3D. +
    4. +
    5. + Essayez de divisier ou de multiplier la taille du modèle par un facteur de 1000. Plusieurs modèles sont mis à + l'échelles différemment, et les gros modèles peuvent ne pas apparaître si la caméra est + à l'intérieur du modèle. +
    6. +
    7. + Essayez d'ajouter et de positionner une source de lumière. Le modèle peut-être caché dans le noir. +
    8. +
    9. + Cherchez des requêtes concernant des textures erronnées dans votre onglet réseau, comme + `"C:\\Path\To\Model\texture.jpg"`. Utilisez des chemins relatifs menant à votre + modèle à la place, comme `images/texture.jpg` — cela peut nécessiter + la modification du fichier du modèle dans un éditeur de texte. +
    10. +
    + +

    Demander de l'aide

    + +

    + Si vous avez effectué le processus de dépannage ci-dessus et que votre modèle + ne fonctionne toujours pas, utiliser la bonne approche pour demander de l'aide vous mènera + plus rapidement à la solution. Postez une question sur le + forum three.js et, incluez dès que possible, + votre modèle (ou un modèle plus simple avec le même problème) dans n'importe quel format + qui vous est disponible. Incluez sufisamment d'informations pour que quelqu'un puisse reproduire + ce problème rapidement — idéalement, une démo live. +

    + + + + diff --git a/docs/manual/fr/introduction/Matrix-transformations.html b/docs/manual/fr/introduction/Matrix-transformations.html new file mode 100644 index 00000000000000..547d02adb86c77 --- /dev/null +++ b/docs/manual/fr/introduction/Matrix-transformations.html @@ -0,0 +1,67 @@ + + + + + + + + + +

    Matrices de transformation ([name])

    + +

    + Three.js utilise des `matrices` pour encoder des transformations 3D---translations (position), rotations, et mise à l'échelle. Chaque instance d'un [page:Object3D] a une [page:Object3D.matrix matrix] qui stocke la position de l'objet, sa rotation, ainsi que son échelle. Cette page décrit comment mettre à jour les transformations d'un objet. +

    + +

    Propriétés de commodité et `matrixAutoUpdate`

    + +

    + Il y a deux façons de mettre à jour les transformations d'un objet: +

    +
      +
    1. + Modifier les propriétés `position`, `quaternion`, et `scale` de l'objet, et laissez three.js recalculer + la matrice de l'objet à l'aide de ces propriétés: + +object.position.copy( start_position ); +object.quaternion.copy( quaternion ); + + Par défaut, la propriété `matrixAutoUpdate` est à true, et la matrice sera automatiquement recalculée. + Si l'objet est statique, ou si vous souhaitez contrôler manuellement quand le recalcul de la matrice intervient, de meilleur performances peuvent-être obtenues en définissant la propriété comme false: + +object.matrixAutoUpdate = false; + + Et après avoir changé n'importe quelle propriété, mettez manuellement la matrice à jour: + +object.updateMatrix(); + +
    2. +
    3. + Modifier la matrice de l'objet directement. La classe [page:Matrix4] dipose de différentes méthodes pour modifier les matrices: + +object.matrix.setRotationFromQuaternion( quaternion ); +object.matrix.setPosition( start_position ); +object.matrixAutoUpdate = false; + + Notez que `matrixAutoUpdate` doit être définie comme `false` dans ce cas, et vous devez vérifier que vous n'appelez pas `updateMatrix`. Appeler `updateMatrix` écrasera les modifications manuelles apportées à la matrice, en recalculant la matrice grâce à sa `position`, `scale`, ainsi de suite. +
    4. +
    + +

    Matrices d'objets et du monde

    +

    + La [page:Object3D.matrix matrix] d'un objet stocke les transformations relatives au [page:Object3D.parent parent] de l'objet; pour obtenir les transformations de l'objets en coordonnées du monde, vous devez accéder à la [page:Object3D.matrixWorld] de l'objet. +

    +

    + Quand les transformations de l'objet parent ou enfant changent, vous pouvez demander que la [page:Object3D.matrixWorld matrixWorld] de l'objet enfant soit mise à jour en appelant [page:Object3D.updateMatrixWorld updateMatrixWorld](). +

    + +

    Rotation et Quaternions

    +

    + Three.js propose deux manières de représenter les rotations 3D: [page:Euler Euler angles] et [page:Quaternion Quaternions], ainsi que des méthodes pour effectuer des conversions entre les deux. Les angles d'Euler sont sujets à un problème nommé "gimbal lock", où certaines configurations peuvent perdre un certain degré de liberté (empêchant l'objet d'effectuer une rotation sur un axe). Pour cette raison, les rotations d'objets sont toujours stockées dans la propriété [page:Object3D.quaternion quaternion] de l'objet. +

    +

    + Des versions précédentes de la librairie incluaient une propriété `useQuaternion` qui, si réglée sur false, faisait que la [page:Object3D.matrix matrix] matrice de l'objet était calculée depuis un angle d'Euler. Cette pratique est dépassée---à la place, vous devez utiliser la méthode [page:Object3D.setRotationFromEuler setRotationFromEuler], qui mettra le quaternion à jour. +

    + + + diff --git a/docs/manual/fr/introduction/Useful-links.html b/docs/manual/fr/introduction/Useful-links.html new file mode 100644 index 00000000000000..5bc471813442ce --- /dev/null +++ b/docs/manual/fr/introduction/Useful-links.html @@ -0,0 +1,177 @@ + + + + + + + + + +

    Liens Utiles ([name])

    + +

    + Sur cette page vous trouverez un ensemble de liens qui pourraient vous êtres utiles dans votre apprentissage de three.js.
    + Si vous souhaitez ajouter quelque chose ici, ou si vous pensez que quelque chose n'est plus + pertinant ou fonctionnel, n'hésitez pas à cliquer sur le bouton 'edit' en bas à droite de la page pour faire quelques modifications!

    + + Notez également que three.js connaît un développement rapide, beaucoup de ces liens contiennent des informations qui sont + dépassées - si quelque chose ne fonctionne pas comme vous l'attendiez, ou comme un de ces liens l'annonce, + jetez un oeil à la console du navigateur à la recherche d'erreurs ou de warnings. Regardez également la documentation appropriée. +

    + +

    Forums d'aide

    +

    + Three.js utilise officiellement le [link:https://discourse.threejs.org/ forum] et [link:http://stackoverflow.com/tags/three.js/info Stack Overflow] pour les demandes d'aide. + Si vous avez besoin d'assistance avec quelque chose, c'est là où vous devez vous rendre. N'ouvrez PAS d'issue sur Github pour les demandes d'aide. +

    + +

    Cours et tutoriels

    + +

    Commencer three.js

    +
      +
    • + [link:https://threejs.org/manual/#en/fundamentals Three.js Fundamentals starting lesson] +
    • +
    • + [link:https://codepen.io/rachsmith/post/beginning-with-3d-webgl-pt-1-the-scene Beginning with 3D WebGL] par [link:https://codepen.io/rachsmith/ Rachel Smith]. +
    • +
    • + [link:https://www.august.com.au/blog/animating-scenes-with-webgl-three-js/ Animating scenes with WebGL and three.js] +
    • +
    + +

    More extensive / advanced articles and courses

    +
      +
    • + [link:https://threejs-journey.com/ Three Journey] par [link:https://bruno-simon.com/ Bruno Simon] - Ce cours apprends aux débutants à utiliser Three.js étape par étape +
    • +
    • + [link:https://discoverthreejs.com/ Discover three.js] +
    • +
    • + [link:http://blog.cjgammon.com/ Collection of tutorials] par [link:http://www.cjgammon.com/ CJ Gammon]. +
    • +
    • + [link:https://medium.com/soffritti.pierfrancesco/glossy-spheres-in-three-js-bfd2785d4857 Glossy spheres in three.js]. +
    • +
    • + [link:https://www.udacity.com/course/cs291 Interactive 3D Graphics] - un cours gratuit sur Udacity qui enseigne les fondamentaux de l'infographie 3D, + et qui utilise three.js comme outil de code. +
    • +
    • + [Link:https://aerotwist.com/tutorials/ Aerotwist] tutoriels par [link:https://github.com/paullewis/ Paul Lewis]. +
    • +
    • + [link:https://discourse.threejs.org/t/three-js-bookshelf/2468 Three.js Bookshelf] - Vous cherchez plus de ressources concernant three.js ou sur l'infographie en général? + Jetez un oeil à la sélection de littérature recommandée par la communauté. +
    • +
    + +

    News et Mises à jour

    +
      +
    • + [link:https://twitter.com/hashtag/threejs Three.js on Twitter] +
    • +
    • + [link:http://www.reddit.com/r/threejs/ Three.js on reddit] +
    • +
    • + [link:http://www.reddit.com/r/webgl/ WebGL on reddit] +
    • +
    + +

    Examples

    +
      +
    • + [link:https://github.com/edwinwebb/three-seed/ three-seed] - un projet prêt à l'emploi three.js avec ES6 et Webpack +
    • +
    • + [link:http://stemkoski.github.io/Three.js/index.html Professor Stemkoskis Examples] - une collection d'exemples adaptés aux débutant + construits three.js r60. +
    • +
    • + [link:https://threejs.org/examples/ Official three.js examples] - ces exemples sont + conservés dans le dossier three.js, et utilisent toujours la dernière version de three.js. +
    • +
    • + [link:https://raw.githack.com/mrdoob/three.js/dev/examples/ Official three.js dev branch examples] - + Pareil qu'au dessus, sauf que ceux-ci utilisent la branche dev de three.js, et sont utilisés pour s'assurer + que tout fonctionne durant le développement de three.js. +
    • +
    + +

    Outils

    +
      +
    • + [link:https://github.com/tbensky/physgl physgl.org] - un front-end JavaScript avec des wrappers pour three.js, pour montrer des graphiques WebGL + aux étudiants qui apprennent les mathématiques et la physique. +
    • +
    • + [link:https://whsjs.readme.io/ Whitestorm.js] – Framework three.js modulaire avec le plugin de physique AmmoNext. +
    • +
    • + [link:http://zz85.github.io/zz85-bookmarklets/threelabs.html Three.js Inspector] +
    • +
    • + [link:http://idflood.github.io/ThreeNodes.js/ ThreeNodes.js]. +
    • +
    • + [link:https://marketplace.visualstudio.com/items?itemName=slevesque.shader vscode shader] - Coloration syntaxique pour le langage des shaders. +
      + [link:https://marketplace.visualstudio.com/items?itemName=bierner.comment-tagged-templates vscode comment-tagged-templates] - Coloration syntaxique pour les littéraux de gabarits, comme: glsl.js. +
    • +
    • + [link:https://github.com/MozillaReality/WebXR-emulator-extension WebXR-emulator-extension] +
    • +
    + +

    Références WebGL

    +
      +
    • + [link:https://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf webgl-reference-card.pdf] - Référentiel de tous les mots-clés de WebGL et GLSL, la terminologie, syntaxe et les définitions. +
    • +
    + +

    Anciens Liens

    +

    + Ces liens sont conservés pour des raisons d'historisation - vous pouvez les trouver encore utile, mais gardez à l'esprit qu'ils + peuvent contenir des informations qui font référence à de très anciennes versions de three.js. +

    + +
      +
    • + AlterQualia at WebGL Camp 3 +
    • +
    • + [link:http://yomotsu.github.io/threejs-examples/ Yomotsus Examples] - une liste d'exemple utilisant three.js r45. +
    • +
    • + [link:http://fhtr.org/BasicsOfThreeJS/#1 Introduction to Three.js] par [link:http://github.com/kig/ Ilmari Heikkinen] (slideshow). +
    • +
    • + [link:http://www.slideshare.net/yomotsu/webgl-and-threejs WebGL and Three.js] par [link:http://github.com/yomotsu Akihiro Oyamada] (slideshow). +
    • +
    • + Trigger Rally par [link:https://github.com/jareiko jareiko] (video). +
    • +
    • + [link:http://blackjk3.github.io/threefab/ ThreeFab] - éditeur de scène, maintenu jusqu'à three.js r50 environ. +
    • +
    • + [link:http://bkcore.com/blog/3d/webgl-three-js-workflow-tips.html Max to Three.js workflow tips and tricks] par [link:https://github.com/BKcore BKcore] +
    • +
    • + [link:http://12devsofxmas.co.uk/2012/01/webgl-and-three-js/ A whirlwind look at Three.js] + par [link:http://github.com/nrocy Paul King] +
    • +
    • + [link:http://bkcore.com/blog/3d/webgl-three-js-animated-selective-glow.html Animated selective glow in Three.js] + par [link:https://github.com/BKcore BKcore] +
    • +
    • + [link:http://www.natural-science.or.jp/article/20120220155529.php Building A Physics Simulation Environment] - tutoriel three.js en Japonais +
    • +
    + + + diff --git a/docs/manual/fr/introduction/WebGL-compatibility-check.html b/docs/manual/fr/introduction/WebGL-compatibility-check.html new file mode 100644 index 00000000000000..9d2f58f101cb9f --- /dev/null +++ b/docs/manual/fr/introduction/WebGL-compatibility-check.html @@ -0,0 +1,35 @@ + + + + + + + + + +

    Compatibilité WebGL ([name])

    +

    + Même si le problème se présente de moins en moins, certains appareils ou navigateurs peuvent ne toujours pas supporter WebGL. + La méthode suivante vous permet de vérifier si il est supporté et d'afficher un message à l'utilisateur si il ne l'est pas. +

    + +

    + Ajoutez [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/capabilities/WebGL.js] + à votre JavaScript et exécutez ce qui suit avant de tenter d'effectuer un rendu de quoi que ce soit. +

    + + + if ( WebGL.isWebGLAvailable() ) { + + // Initiate function or other initializations here + animate(); + + } else { + + const warning = WebGL.getWebGLErrorMessage(); + document.getElementById( 'container' ).appendChild( warning ); + + } + + + diff --git a/docs/manual/it/buildTools/Testing-with-NPM.html b/docs/manual/it/buildTools/Testing-with-NPM.html new file mode 100644 index 00000000000000..2700cb4b1dc0cf --- /dev/null +++ b/docs/manual/it/buildTools/Testing-with-NPM.html @@ -0,0 +1,239 @@ + + + + + + + + + +

    Testare con NPM ([name])

    + +

    + Questo articolo mostra come inserire three.js in un ambiente + [link:https://nodejs.org/en/ node.js] così che tu possa eseguire test + automatici. I test possono essere eseguiti da linea di comando o da + strumenti CI automatici come [link:https://travis-ci.org/ Travis]. +

    + +

    Versione breve

    + +

    + Se sei a tuo agio con node e npm, installa npm + $ npm install three --save-dev + e aggiungi + const THREE = require('three'); + al tuo test. +

    + +

    Creare un progetto testabile da zero

    +

    + Se non sei familiare con questi strumenti, ecco una guida rapida per + linux (il processo di installazione sarà leggermente diverso usando + Windows, ma i comandi NPM saranno uguali). +

    + +

    Configurazione di base

    +
    +
      +
    1. + Installa [link:https://www.npmjs.org/ npm] e nodejs. Il percorso più + breve in genere assomiglia a qualcosa del simile: + +$ sudo apt-get install -y npm nodejs-legacy +# fix any problems with SSL in the default registry URL +$ npm config set registry http://registry.npmjs.org/ + +
    2. + +
    3. + Crea una nuova cartella per il progetto + $ mkdir test-example; cd test-example +
    4. + +
    5. + Crea un nuovo file di progetto tramite npm: + $ npm init + e accetta tutti i valori suggeriti premendo Enter per ogni richiesta. + Con queste richieste si creerà il file package.json. +
    6. +
      + +
    7. + Prova ad avviare la funzione di test con: + $ npm test + fallirà, come ci aspettiamo. Se controlli nel file package.json la + definizione dello script di test è: + "test": "echo \"Error: no test specified\" && exit 1" +
    8. +
    +
    + +

    Aggiungere mocha

    +
    + Utilizzeremo [link:https://mochajs.org/ mocha]. + +
      +
    1. + Installare mocha con: + $ npm install mocha --save-dev + Si noti che è stata creata la cartella node_modules/ e le tue + dipendenze sono state installate al suo interno. Inoltre, si noti che + il file package.json è stato aggiornato: è stata aggiunta la proprietà + devDependencies, aggiornata dal comando --save-dev. +
    2. +
      + +
    3. + Modificare il file package.json per usare mocha per i test. Quando + viene invocato il test, vogliamo eseguire mocha e specificare un + reporter dettagliato. Per impostazione predefinita questo eseguirà + qualsiasi cosa nella cartella test/ (non avendo una cartella test/ si può + incorrere in un npm ERR!, bisogna crearla con il comando mkdir test) + "test": "mocha --reporter list" +
    4. + +
    5. + Rilanciare il test con: + $ npm test + + Adesso il test dovrebbe essere eseguito con successo, riportando "0 passing (1ms) or + similar". +
    6. +
    +
    + +

    Aggiungere three.js

    +
    +
      +
    1. + Inseriamo la nostra dipendenza three.js con il comando: + $ npm install three --save-dev +
        +
      • + Se hai bisogno di una versione di three.js diversa, usa + $ npm show three versions + per vedere quali sono le versioni disponibili. Per dire ad npm la versione + scelta, usa + $ npm install three@0.84.0 --save + (0.84.0 nell'esempio). --save fa sì che sia una dipendenza del + progetto piuttosto che una devDependecy. Per maggiori informazioni + consulta il documento + [link:https://docs.npmjs.com/cli/v8/configuring-npm/package-json qui]. +
      • +
      +
    2. + +
    3. + Mocha cercherà i test nella cartella test/, quindi creiamola + $ mkdir test +
    4. + +
    5. + Infine abbiamo effettivamente bisogno di un test JS per l'esecuzione. + Aggiungiamo un semplice test il quale verificherà che l'oggetto + three.js sia disponibile e funzionante. Crea il file + test/verify-three.js contenente: + +const THREE = require('three'); +const assert = require('assert'); + +describe('The THREE object', function() { + it('should have a defined BasicShadowMap constant', function() { + assert.notEqual('undefined', THREE.BasicShadowMap); + }), + + it('should be able to construct a Vector3 with default of x=0', function() { + const vec3 = new THREE.Vector3(); + assert.equal(0, vec3.x); + }) +}) + +
    6. + +
    7. + Adesso rieseguiamo il test con il comando $ npm test. Questo dovrebbe + eseguire i test sopra definiti e terminare con successo, mostrando qualcosa del tipo: + +The THREE object should have a defined BasicShadowMap constant: 0ms +The THREE object should be able to construct a Vector3 with default of x=0: 0ms +2 passing (8ms) + +
    8. +
    +
    + +

    Aggiungere il tuo codice

    +
    + Hai bisogno di fare tre cose: + +
      +
    1. + Scrivere un test per il comportamento che di aspetti dal tuo codice, e + metterlo all'interno della cartella test/. + [link:https://github.com/air/encounter/blob/master/test/Physics-test.js Qui] un esempio di un progetto reale. +
    2. + +
    3. + Esportare il tuo codice funzionale in modo tale che nodejs possa vederlo + per usarlo insieme a require. Controlla + [link:https://github.com/air/encounter/blob/master/js/Physics.js qui]. +
    4. + +
    5. + Richiamare il tuo codice nel file di test, allo stesso modo in cui + abbiamo fatto per richiamare three nell'esempio sopra `require('three')` +
    6. +
    + +

    + Il punto 2 e 3 saranno molto dipendenti da come hai gestito il tuo codice. + Nell'esempio di Physics.js fornito sopra, la parte di esportazione si trova giustamente + alla fine. Assegniamo un oggetto a module.exports: +

    + +//============================================================================= +// make available in nodejs +//============================================================================= +if (typeof exports !== 'undefined') { module.exports = Physics; } + +
    + +

    Affrontare le dipendenze

    +
    +

    + Se stai già utilizzando qualcosa di smart come require.js o browserify, + salta questa parte. +

    +

    + Tipicamente un progetto three.js verrà eseguito nel browser. Il caricamento + del modulo viene quindi eseguito dal browser che esegue una serie di tag + di script. I tuo singoli file non si devono preoccupare per le dipendenze. + Tuttavia, in un contesto nodejs non è presente il file index.html che lega tutto + insieme, quindi devi essere esplicito. +

    +

    + Se stai esportando un modulo che dipende da altri file, dovrai dire a node + di caricarli. Di seguito un approccio: +

    +
      +
    1. + All'inizio del tuo modulo, controlla se ti trovi in un ambiente nodejs. +
    2. +
    3. Se è così, dichiara esplicitamente le tue dipendenze.
    4. +
    5. + In caso contrario, probabilmente sei in un browser e quindi non devi fare + nient'altro. +
    6. +
    + Esempio di codice da Physics.js: + +//============================================================================= +// setup for server-side testing +//============================================================================= +if (typeof require === 'function') // test for nodejs environment { + const THREE = require('three'); const MY3 = require('./MY3.js'); } + +
    + + diff --git a/docs/manual/it/introduction/Animation-system.html b/docs/manual/it/introduction/Animation-system.html new file mode 100644 index 00000000000000..afe562f31c6c9d --- /dev/null +++ b/docs/manual/it/introduction/Animation-system.html @@ -0,0 +1,122 @@ + + + + + + + + + +

    Sistema di animazione ([name])

    + +

    Panoramica

    + +

    + Con il sistema di animazione di three.js si possono animare varie proprietà dei modelli: + le ossa di un [page:SkinnedMesh modello skinned], i target morph, le diverse proprietà dei materiali + (colori, opacità, booleani), la visibilità e le trasformazioni. Le proprietà di animazione possono essere + sfumate, incrociate e deformate. Il peso e la scala temporale di diverse animazioni simultanee sullo stesso + oggetto o su oggetti diversi possono essere modificate in modo indipendente. È possibile sincronizzare + diverse animazioni sullo stesso oggetto e su oggetti diversi.

    + + Per ottenere tutto questo in un sistema omogeneo, il [link:https://github.com/mrdoob/three.js/issues/6881 sistema di animazione di three.js] + è stato cambiato completamente nel 2015 (attenzione alle informazioni non aggiornate!), ed ora ha un'architettura simile a quella di Unity/Unreal Engine 4. + Questa pagina fornisce una breve panoramica dei componenti principali del sistema e di come lavorano insieme. +

    + +

    Clip di animazione (AnimationClips)

    + +

    + Se si è importato con successo un oggetto 3D animato (non importa se ha ossa o target morph o entrambi) + - per esempio esportandolo da Blender con [link:https://github.com/KhronosGroup/glTF-Blender-IO l'exporter glTF Blender] e caricandolo + nella scena three.js usando [page:GLTFLoader] - uno dei campi di risposta dovrà essere un array chiamato "animations", contenente + gli [page:AnimationClip AnimationClips] per questo modello (vedi l'elenco dei possibili loader qui sotto).

    + + Ogni `AnimationClip` contiene solitamente i dati per una certa attività dell'oggetto. Se la mesh è un personaggio, + per esempio, ci può essere un AnimationClip per la camminata, un altro per il salto e un terzo per il salto laterale e così via. +

    + +

    Keyframe Tracks

    + +

    + All'interno di un `AnimationClip` i dati, per ogni propietà di animazione, sono memorizzati in un [page:KeyframeTrack] separato. + Supponendo che un oggetto personaggio abbia uno [page:Skeleton scheletro], un keyframe track potrebbe memorizzare i dati relativi alle variazioni di + posizione dell'osso inferiore del braccio nel tempo, un'altra traccia potrebbe memorizzare i dati relativi alle variazioni di rotazione dello stesso osso, + una terza traccia la posizione, la rotazione e la scala di un altro osso e così via. Dovrebbe essere chiaro, che un AnimationClip può essere composto + da molte tracce di questo tipo.

    + + Supponendo che il modello abbia dei target morph (per esempio un target morph che mostra una faccia amichevole e un altro che mostra una faccia arrabbiata), + ogni traccia contiene le informazioni su come l'influenza di un certo target morph cambia durante l'esecuzione del clip. +

    + +

    Mixer di Animazioni

    + +

    + I dati memorizzati costituiscono solo la base per le animazioni - la riproduzione vera e propria è controllata dall'[page:AnimationMixer]. + È possibile immaginarlo non solo come un lettore di animazioni, ma come un simulatore di un hardware come una vera e propria console di mixaggio, + che può controllare diverse animazioni simultaneamente, mescolandole e fondendole. +

    + +

    Azioni di Animazioni

    + +

    + Lo stesso `AnimationMixer` ha pochissime proprietà e metodi (generali), perché può essere controllato dall'[page:AnimationAction AnimationActions]. + Per configurare un `AnimationAction` è necessario specificare quando un `AnimationClip` deve essere eseguito, messo in pausa o stoppato su uno dei mixer, + se e con quale frequenza la clip deve essere ripetuta, se deve essere eseguita con una dissolvenza o una scala temporale e altre cose aggiuntive come + dissolvenza incrociata o sincronizzazione. +

    + +

    Gruppi di oggetti Animati

    + +

    + Se si desidera che un gruppo di oggetti riceva uno stato di animazione condiviso, è possibile utilizzare un [page:AnimationObjectGroup]. +

    + +

    Formati supportati e Loader

    + +

    + Si noti che non tutti i formati includono le animazioni (in particolare OBJ non lo fa) e che solo alcuni loader di three.js + supportano le sequenze [page:AnimationClip AnimationClip]. Di seguito alcuni che supportano questo tipo di animazioni: +

    + +
      +
    • [page:ObjectLoader THREE.ObjectLoader]
    • +
    • THREE.BVHLoader
    • +
    • THREE.ColladaLoader
    • +
    • THREE.FBXLoader
    • +
    • [page:GLTFLoader THREE.GLTFLoader]
    • +
    • THREE.MMDLoader
    • +
    + +

    + Si noti che 3ds max e Maya attualmente non possono esportare più animazioni (ovvero animazioni che non si trovano nella stessa timeline) + direttamente in un singolo file. +

    + +

    Esempio

    + + + let mesh; + + // Create an AnimationMixer, and get the list of AnimationClip instances + const mixer = new THREE.AnimationMixer( mesh ); + const clips = mesh.animations; + + // Update the mixer on each frame + function update () { + mixer.update( deltaSeconds ); + } + + // Play a specific animation + const clip = THREE.AnimationClip.findByName( clips, 'dance' ); + const action = mixer.clipAction( clip ); + action.play(); + + // Play all animations + clips.forEach( function ( clip ) { + mixer.clipAction( clip ).play(); + } ); + + + + diff --git a/docs/manual/it/introduction/Color-management.html b/docs/manual/it/introduction/Color-management.html new file mode 100644 index 00000000000000..15bebacec206a3 --- /dev/null +++ b/docs/manual/it/introduction/Color-management.html @@ -0,0 +1,404 @@ + + + + + + + + + + + +

    Gestione del colore ([name])

    + +

    Cos'è lo spazio colore?

    + +

    + Ogni spazio colore è una collezione di diverse decisioni progettuali, + scelte insieme per supportare un'ampia gamma di colori e al contempo + soddisfare i vincoli tecnici legati alla precisione e alle tecnologie di + visualizzazione. Quando si crea una risorsa 3D, o si assemblano delle + risorse 3D insieme in una scena, è importante sapere quali sono queste + proprietà e come le proprietà di uno spazio colore si relazionano con + altri spazi colore nella scena. +

    + +
    + +
    + Colori sRGB e il punto di bianco (D65) visualizzati nel diagramma + cromatico di riferimento CIE 1931. La regione colorata rappresenta una + proiezione 2D della gamma sRGB, che è un volume 3D. Fonte: + Wikipedia +
    +
    + +
      +
    • + Colori primari: I colori primari (rosso, verde, blu) non sono + assoluti; vengono selezionati dallo spettro visibile in base ai vincoli + di precisione limitata e alla capacità dei dispositivi di + visualizzazione disponibili. I colori sono espressi come rapporto tra i + colori primari. +
    • +
    • + Punto di bianco: La maggior parte degli spazi colore è progettata + in modo tale che una somma equamente ponderata di primari + R = G = B appaia priva di colore o "acromatica". L'aspetto dei + valori cromatici (come il bianco o il grigio) dipende dalla percezione + umana, che a sua volta dipende fortemente dal contesto dell'osservatore. + Uno spazio colore specifica il suo "punto di bianco" per bilanciare + queste esigenze. Il punto di bianco definito dallo spazio colore sRGB è + D65. +
    • +
    • + Funzioni di trasferimento (transfer functions): Dopo aver scelto + la gamma cromatica e un modello di colore, dobbiamo ancora definire le + mappature ("funzioni di trasferimento") dei valori numerici da/verso lo + spazio colore. R = 0,5 rappresenta il 50% in meno di illuminazione + fisica rispetto a r = 1,0? O il 50% in meno di luminosità, come + percepito da un occhio umano medio? Sono cose diverse e questa + differenza può essere rappresentata come una funzione matematica. Le + funzioni di trasferimento possono essere lineari o + non lineari, a seconda degli obiettivi dello spazio colore. sRGB + definisce funzioni di trasferimento non lineari. Queste funzioni sono + talvolta approssimate come funzioni gamma, ma il termine "gamma" + è ambiguo e dovrebbe essere evitato in questo contesto. +
    • +
    + + Questi tre parametri - colori primari, punto di bianco e funzioni di + trasferimento - definiscono uno spazio colore, ognuno scelto per obiettivi + specifici. Dopo aver definito i parametri, sono utili alcuni termini + aggiuntivi: + +
      +
    • + Modello di colore: Sintassi per identificare numericamente i + colori all'interno della gamma cromatica scelta - un sistema di + coordinate per i colori. In three.js ci occupiamo principalmente del + modello di colore RGB, con tre coordinate + r, g, b ∈ [0,1] ("dominio chiuso") o + r, g, b ∈ [0,∞] ("dominio aperto") che rappresentano ciascuna una + frazione di un colore primario. Altri modelli di colore (HSL, Lab, LCH) + sono comunemente utilizzati per il controllo artistico. +
    • +
    • + Gamma di colori: Quando i colori primari e il punto di bianco + sono stati scelti, questi rappresentano un volume all'interno dello + spettro visibile (un "gamut"). I colori che non rientrano in questo + volume ("fuori gamut") non possono essere espressi dai valori RGB del + dominio chiuso [0,1]. Nel dominio aperto [0,∞], il gamut è tecnicamente + infinito. +
    • +
    + +

    + Consideriamo due spazi colori comuni: [page:SRGBColorSpace] ("sRGB") e + [page:LinearSRGBColorSpace] ("Linear-sRGB"). Entrambi usano gli stessi + colori primari e lo stesso punto di bianco, e quindi hanno la stessa gamma + di colori. Entrambi utilizzano il modello di colore RGB. Sono diversi solo + nelle funzioni di trasferimento - Linear-sRGB è lineare rispetto + all'intensità della luce fisica, mentre sRGB utilizza le funzioni di + trasferimento non lineari di sRGB e si avvicina maggiormente al modo in + cui l'occhio umano percepisce la luce e alla reattività dei comuni + dispositivi di visualizzazione. +

    + +

    + Questa differenza è importante. I calcoli di illuminazione e altre + operazioni di rendering devono generalmente avvenire in uno spazio di + colore lineare. Tuttavia, i colori lineari sono meno efficienti da + memorizzare in un'immagine o in un framebuffer e non hanno un aspetto + corretto quando vengono osservati da un osservatore umano. Di conseguenza, + le texture di input e l'immagine finale renderizzata utilizzano + generalmente lo spazio di colore sRGB non lineare. +

    + +
    +

    + ℹ️ + ATTENZIONE: Anche se alcuni display moderni supportano gamme + più ampie come Display-P3, le API grafiche della piattaforma web si + basano in gran parte su sRGB. Le applicazioni che utilizzano three.js + oggi utilizzano in genere solo gli spazi colore sRGB e Linear-sRGB. + +

    +
    + +

    Ruoli degli spazi colore

    + +

    + Un flusso di lavoro lineare - richiesto per moderni metodi di rendering - + generalmente coinvolge più di uno spazio di colore, ognuno assegnato ad un + ruolo specifico. Spazi colore lineari o non lineari sono adatti a ruoli + diversi, come spiegato di seguito. +

    + +

    Input color space

    + +

    + I colori forniti a three.js - dai color picker, dalle texture, dai modelli + 3D e da altre risorse - hanno ciascuno uno spazio colore associato. Quelli + che non sono già nello spazio colore di lavoro Linear-sRGB devono essere + convertiti e alle texture deve essere assegnata la corretta assegnazione + texture.encoding. Alcune conversioni (per i colori esadecimali e + CSS in sRGB) possono essere effettuate automaticamente se la modalità di + gestione del colore legacy è disabilitata prima dell'inizializzazione dei + colori: +

    + + THREE.ColorManagement.legacyMode = false; + +
      +
    • + Materiali, luci, e shader: I colori nei materiali, nelle luci e + negli shader memorizzano i componenti RGB nello spazio colore di lavoro + Linear-sRGB. +
    • +
    • + Colori dei vertici: [page:BufferAttribute BufferAttributes] + memorizza i componenti RGB nello spazio colore di lavoro Linear-sRGB. +
    • + +
    • + Colori delle texture: Le [page:Texture Texture] PNG o JPEG + contenti informazioni sul colore (come .map o .emissiveMap) usano lo + spazio colore sRGB a dominio chiuso, e devono essere annotate con + texture.encoding = sRGBEncoding. I formati come OpenEXR (a volte + usati per .envMap o .lightMap) utilizzano lo spazio colore Linear-sRGB + indicato con texture.encoding = LinearEncoding, e possono + contenere valori nel dominio aperto [0,∞]. +
    • +
    • + Texture non a colori: Le texture che non memorizzano informazioni + relative ai colori (come .normalMap o .roughnessMap) non hanno associato + uno spazio colore, e generalmente usano l'annotazione (predefinita) + texture.encoding = LinearEncoding. In rari casi, i dati non a + colori possono essere rappresentati con altre codifiche non lineari per + motivi tecnici. +
    • +
    + +
    +

    + ⚠️ + ATTENZIONE: Molti formati per modelli 3D non definiscono + correttamente o in modo coerente le informazioni sullo spazio colore. + Sebbene three.js tenti di gestire la maggior parte dei casi, i + problemi sono spesso con i file con formati meno recenti. Per ottenere + un miglior risultato bisogna utilizzare il formato glTF 2.0 + ([page:GLTFLoader]) e prima bisogna testare i modelli 3D in + visualizzatori online per confermare che la risorsa stessa sia + corretta. + +

    +
    + +

    Spazio colore di lavoro

    + +

    + Rendering, interpolazione e molte altre operazioni devono essere eseguite + in uno spazio colore di lavoro lineare, nel quale i componenti RGB sono + proporzionali all'illuminazione fisica. In three.js, lo spazio colore di + lavoro è Linear-sRGB. +

    + +

    Output color space

    + +

    + L'output su un dispositivo di visualizzazione, a un'immagine o a un video, + può comportare la conversione dallo spazio colore di lavoro Linear-sRGB di + dominio aperto a un altro spazio di colore. Questa conversione può essere + eseguita nel passaggio di rendering principale + ([page:WebGLRenderer.outputEncoding]), o durante il post-processing. +

    + + + renderer.outputEncoding = THREE.sRGBEncoding; // optional with post-processing + + +
      +
    • + Display: I colori scritti in un canvas WebGL per i display devono + essere nello spazio colore sRGB. +
    • +
    • + Immagine: I colori scritti su un'immagine devono utilizzare lo + spazio colore appropriato per il formato e per il suo uso. Le immagini + completamente renderizzate scritte per texture PNG o JPEG generalmente + usano lo spazio colore sRGB. Immagini contenenti emissioni, mappe di + luce, o altri dati non limitati all'intervallo [0,1] utilizzaranno + generalmente lo spazio colore Linear-sRGB a dominio aperto, e un formato + immagine compatibile come OpenEXR. +
    • +
    + +
    +

    + ⚠️ + ATTENZIONE: I target di rendering possono utilizzare sia sRGB + che Linear-sRGB. sRGB utilizza meglio la precisione limitata. Nel + dominio chiuso, 8 bit sono sufficienti per sRGB mentre ≥12 (mezzo + float) possono essere richiesti per Linear-sRGB. Se gli stadi + successivi delle pipeline richiedono un ingresso Linear-sRGB, le + conversioni aggiuntive possono avere un piccolo costo in termini di + prestazioni. +

    +
    + +

    Lavorare con le istanze di THREE.Color

    + +

    + I metodi di lettura o modifica delle istanze [page:Color] presuppongono + che i dati siano già nello spazio colore di lavoro di three.js, + Linear-sRGB. I componenti RGB e HSL sono rappresentazioni dirette dei dati + memorizzati dall'istanza Color, e non sono mai convertiti implicitamente. + I dati di Color possono essere esplicitamenre convertiti con + .convertLinearToSRGB() o .convertSRGBToLinear(). +

    + + + // RGB components (no change). + color.r = color.g = color.b = 0.5; + console.log( color.r ); // → 0.5 + + // Manual conversion. + color.r = 0.5; + color.convertSRGBToLinear(); + console.log( color.r ); // → 0.214041140 + + +

    + Con ColorManagement.legacyMode = false impostato (consigliato), + alcune conversioni vengono effettuate automaticamente. Poiché i colori + esadecimali e CSS sono generalmente sRGB, i metodi [page:Color] + convertiranno automaticamente questi input da sRGB a Linear-sRGB nei + setter, oppure convertiranno da Linear-sRGB a sRGB quando restituiscono + output esadecimali o CSS dai getter. +

    + + + // Hexadecimal conversion. + color.setHex( 0x808080 ); + console.log( color.r ); // → 0.214041140 + console.log( color.getHex() ); // → 0x808080 + + // CSS conversion. + color.setStyle( 'rgb( 0.5, 0.5, 0.5 )' ); + console.log( color.r ); // → 0.214041140 + + // Override conversion with 'colorSpace' argument. + color.setHex( 0x808080, LinearSRGBColorSpace ); + console.log( color.r ); // → 0.5 + console.log( color.getHex( LinearSRGBColorSpace ) ); // → 0x808080 + console.log( color.getHex( SRGBColorSpace ) ); // → 0xBCBCBC + + +

    Errori comuni

    + +

    + Quando un singolo colore o una texture non sono configurati correttamente, + apparirà più scuro o più chiaro del previsto. Quando lo spazio colore di + output del renderer non è configurato correttamente, l'intera scena + potrebbe essere più scura (ad es. manca la conversione ad sRGB) o più + chiara (ad es. una doppia conversione a sRGB con post-processing). In ogni + caso il problema potrebbe non essere uniforme e semplicemente + aumentare/dimunire la luminosità non lo risolverebbe. +

    + +

    + Un problema più sottile si verifica quando entrambi lo spazio colore di + input e quello di output non sono corretti - i livelli di luminosità complessivi + potrebbero andare bene, ma i colori potrebbero cambiare in modo imprevisto in + condizioni di illuminazione diversa o l'ombreggiatura potrebbe apparire più sbiadita + e meno morbida del previsto. Questi due errori non fanno una cosa giusta, ed è importante + che lo spazio colore di lavoro sia lineare ("riferito alla scena") e che lo spazio di colore + dell'output sia non lineare ("riferito alla visualizzazione"). +

    + +

    Ulteriori letture

    + + + + diff --git a/docs/manual/it/introduction/Creating-a-scene.html b/docs/manual/it/introduction/Creating-a-scene.html new file mode 100644 index 00000000000000..9f105c7e44fba9 --- /dev/null +++ b/docs/manual/it/introduction/Creating-a-scene.html @@ -0,0 +1,184 @@ + + + + + + + + + +

    Creare una scena ([name])

    + +

    Lo scopo di questa sezione è quello di fornire una breve introduzione di three.js. + Inizieremo impostando una scena con un cubo rotante. + Se sei bloccato e hai bisogno di aiuto, in fondo alla pagina troverai un esempio funzionante.

    + +

    Prima di iniziare

    + +

    Prima di poter utilizzare three.js hai bisogno di un posto dove visualizzarlo. + Salva il seguente codice HTML in un file sul tuo computer insieme ad una copia + di [link:https://threejs.org/build/three.js three.js] nella cartella js/, e aprilo nel browser.

    + + + <!DOCTYPE html> + <html> + <head> + <meta charset="utf-8"> + <title>My first three.js app</title> + <style> + body { margin: 0; } + </style> + </head> + <body> + <script src="js/three.js"></script> + <script> + // Il nostro Javascript andrà qui + </script> + </body> + </html> + + +

    Questo è quanto. Tutto il codice seguente va nel tag vuoto <script>.

    + +

    Creare la scena

    + +

    Per poter visualizzare qualsiasi cosa con three.js abbiamo bisogno di tre cose: scena, + telecamera e renderer, in modo da poter renderizzare la scena con la telecamera.

    + + + const scene = new THREE.Scene(); + const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); + + const renderer = new THREE.WebGLRenderer(); + renderer.setSize( window.innerWidth, window.innerHeight ); + document.body.appendChild( renderer.domElement ); + + +

    Spieghiamo un attimo cosa sta succedendo. Abbiamo impostato la scena, la telecamera e il renderer.

    + +

    Esistono diverse telecamere in three.js. Per ora usiamo una `PerspectiveCamera`.

    + +

    Il primo attributo è il `field of view` (campo visivo). Il FOV è l'estensione della scena che + viene vista sul display in qualsiasi momento. Il valore è espresso in gradi.

    + +

    Il secondo attributo è l'`aspect ratio` (rapporto di aspetto). + È quasi sempre consigliabile usare la larghezza dell'elemento divisa per l'altezza, + altrimenti si otterrà lo stesso risultato di quando si riproducono vecchi film su un televisore widescreen - l'immagine appare schiacciata.

    + +

    I successivi due attributi sono il piano di ritaglio, `near` (il vicino) e `far` (il lontano). + Ciò significa che gli oggetti più lontani dalla telecamera rispetto al valore `far` o più vicini + rispetto al valore `near` non saranno renderizzati. Non è neccessario preoccuparsi di questo + aspetto adesso, ma potresti voler usare altri valori nella tua applicazione per avere delle prestazioni migliori.

    + +

    Il prossimo passo è il renderer. È qui che avviene la magia. Oltre al WebGLRenderer che usiamo qui, + three.js fornisce altri renderer, spesso usati come alternativa per utenti che usano browser più vecchi + o per quelli che, per qualche motivo, non hanno il supporto WebGL.

    + +

    Oltre a creare l'istanza del renderer, abbiamo bisogno di impostare le dimensioni con cui vogliamo che l'applicazione venga visualizzata. È una buona idea usare la larghezza e l'altezza dell'area che vogliamo riempire con la nostra applicazione - in questo caso, la larghezza e l'altezza della finestra del browser. Per le applicazioni ad alte prestazioni si possono dare a `setSize` dei valori più piccoli, come `window.innerWidth/2` e `window.innerHeight/2`, che faranno si che l'applicazione venga renderizzata ad una dimensione di un quarto.

    + +

    Se si desidera mantenere la dimensione dell'applicazione ma visualizzarla ad una risoluzione minore, è possibile farlo aggiungendo a `setSize` il valore false, corrispondente a `updateStyle` (il terzo parametro). Per esempio, `setSize(window.innerWidth/2, window.innerHeight/2, false)` visualizzerà l'applicazione a metà risoluzione, dato che il <canvas> ha larghezza e altezza del 100%.

    + +

    Infine, aggiungiamo l'elemento `renderer` al nostro documento HTML. Si tratta di un elemento <canvas> che il renderer utilizza per visualizzare la scena.

    + +

    "Va bene, ma dov'è il cubo che ci avevi promesso?" Aggiungiamolo ora.

    + + + const geometry = new THREE.BoxGeometry( 1, 1, 1 ); + const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); + const cube = new THREE.Mesh( geometry, material ); + scene.add( cube ); + + camera.position.z = 5; + + +

    Per creare un cubo abbiamo bisogno di una `BoxGeometry`. Un oggetto che contiene tutti i punti (`vertices`) e le facce (`faces`) del cubo. Lo esploreremo meglio in futuro.

    + +

    Oltre alla geometria, abbiamo bisogno di un materiale per colorarla. Three.js mette a disposizione molti materiali, ma per ora ci limiteremo al `MeshBasicMaterial`. Tutti i materiali come parametro accettano un oggetto al cui interno avrà delle proprietà che li verrano applicate. Per mantenere le cose molto semplici, impostiamo solo un attributo di colore verde `0x00ff00`. Questo funziona come i colori nei CSS o in Photoshop (`hex colors`).

    + +

    La terza cosa di cui abbiamo bisogno è una `Mesh`. Una mesh è un oggetto che prende una geometria, e le applica un materiale, che possiamo, poi, inserire nella scena e spostare liberamente.

    + +

    Per impostazione predefinita, quando chiamiamo `scene.add()`, la cosa che sarà aggiunta verrà posizionata nelle coordinate `(0,0,0)`. In questo modo la telecamera e il cubo si troveranno l'uno dentro l'altro. Per evitare questo inconveniente, è sufficiente spostare la telecamera un po' più in là.

    + +

    Renderizzare la scena

    + +

    Se si copiasse il codice qui sopra nel file HTML creato in precedenza, non si vedrebbe nulla. Questo perché ancora non stiamo visualizzando nulla. Per questo abbiamo bisogno di quello che viene chiamato un ciclo `render o animate`.

    + + + function animate() { + requestAnimationFrame( animate ); + renderer.render( scene, camera ); + } + animate(); + + +

    Questa funzione creerà un loop che fa sì che il renderer disegni la scena ogni volta che la scena viene aggiornata + (su uno schermo tipico questo vuol dire 60 volte al secondo). Se sei nuovo nella scrittura di giochi su browser, + potresti dire "perché non creiamo semplicemente un setInterval?" Il fatto è che potremmo ma `requestAnimationFrame` + ha una serie di vantaggi. Forse il più importante è che si interrompe quando l'utente passa ad un'altra scheda del browser, + così da non sprecare la preziosa potenza di elaborazione e la vita della batteria del computer.

    + +

    Animare il cubo

    + +

    Se inserisci tutto il codice sopra nel file che hai creato prima di iniziare, dovresti vedere un box verde. + Rendiamo tutto un po' più interessante ruotandolo.

    + +

    Aggiungi quanto segue proprio sopra la chiamata `renderer.render` nella tua funzione `animate`:

    + + + cube.rotation.x += 0.01; + cube.rotation.y += 0.01; + + +

    Verrà eseguito per ogni frame (normalmente 60 volte per secondo) e darà al cubo un'animazione di rotazione. + Fondamentalmente, tutto ciò che vuoi spostare o modificare mentre l'applicazione è in esecuzione deve passare + attraverso il ciclo di animazione. Ovviamente, si possono chiamare altre funzioni all'interno di `animate`, + in modo da non avere una funzione con centinaia di righe.

    + +

    Il risultato

    +

    Congratulazioni! Hai completato la tua prima applicazione three.js. È semplice, ma da qualche parte devi pur iniziare.

    + +

    Il codice completo è disponibile di seguito e come esempio modificabile [link:https://jsfiddle.net/fxurzeb4/ live example]. Giocaci per capire meglio come funziona.

    + + + <!DOCTYPE html> + <html> + <head> + <meta charset="utf-8"> + <title>My first three.js app</title> + <style> + body { margin: 0; } + </style> + </head> + <body> + <script src="js/three.js"></script> + <script> + const scene = new THREE.Scene(); + const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); + + const renderer = new THREE.WebGLRenderer(); + renderer.setSize( window.innerWidth, window.innerHeight ); + document.body.appendChild( renderer.domElement ); + + const geometry = new THREE.BoxGeometry( 1, 1, 1 ); + const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); + const cube = new THREE.Mesh( geometry, material ); + scene.add( cube ); + + camera.position.z = 5; + + function animate() { + requestAnimationFrame( animate ); + + cube.rotation.x += 0.01; + cube.rotation.y += 0.01; + + renderer.render( scene, camera ); + }; + + animate(); + </script> + </body> + </html> + + + diff --git a/docs/manual/it/introduction/Creating-text.html b/docs/manual/it/introduction/Creating-text.html new file mode 100644 index 00000000000000..5042250d68c741 --- /dev/null +++ b/docs/manual/it/introduction/Creating-text.html @@ -0,0 +1,138 @@ + + + + + + + + + +

    Creare testo ([name])

    +
    +

    + Spesso si ha la necessità di utilizzare del testo nella propria applicazione three.js - ecco un paio di modi per farlo. +

    +
    + +

    1. DOM + CSS

    +
    +

    + L'uso dell'HTML è generalmente il modo più facile e veloce per aggiungere testo. Questo è il metodo + usato per gli overlay descrittivi in quasi tutti gli esempi di three.js. +

    +

    È possibile aggiungere contenuto ad un div:

    + <div id="info">Description</div> + +

    + e usare il markup CSS per posizionare l'elemento in modo assoluto, in una posizione sopra tutti gli altri elementi + con la proprietà z-index, specialmente se three.js viene eseguito in modalità full screen. +

    + + +#info { + position: absolute; + top: 10px; + width: 100%; + text-align: center; + z-index: 100; + display:block; +} + + +
    + + +

    2. Usare [page:CSS2DRenderer] o [page:CSS3DRenderer]

    +
    +

    + Questi renderer vengono utilizzati per disegnare testo di alta qualità all'interno di elementi del DOM nella scena three.js. + Questo metodo è simile al punto 1 eccetto per il fatto che con questi renderer è possibile integrare più facilmente e dinamicamente gli elementi nella scena three.js. +

    +
    + + +

    3. Disegnare il testo nel canvas e usarlo come [page:Texture]

    +
    +

    Utilizza questo metodo se desideri disegnare testo facilmente su un piano nella scena three.js.

    +
    + + +

    4. Disegnare un modello nella tua applicazione 3D preferita ed esportarlo in three.js

    +
    +

    Utilizza questo metodo se preferisci lavorare con la tua applicazione 3D e importare i modelli in three.js.

    +
    + + +

    5. Text Geometry Procedurale

    +
    +

    + Se preferisci lavorare solo in three.js o creare geometrie di testo 3D dinamiche e procedurali, è possibile creare una mesh che abbia come geometria + un'istanza di THREE.TextGeometry: +

    +

    + new THREE.TextGeometry( text, parameters ); +

    +

    + In modo tale che questo funzioni correttamente, TextGeometry necessita che un'istanza di THREE.Font venga impostata come valore del parametro "font". + Per avere maggiori informazioni su come implementare questo metodo, consulta la pagina [page:TextGeometry], contenente la descrizione di ogni + parametro che la classe accetta e una lista di font JSON che vengono forniti con la distribuzione di three.js. +

    + +

    Esempi

    + +

    + [example:webgl_geometry_text WebGL / geometry / text]
    + [example:webgl_shadowmap WebGL / shadowmap] +

    + +

    + TextGeometry utilizza i font generati da typeface.json. + Se Typeface è inattivo, o si preferisce usare un font che non è presente, esiste un tutorial che mostra come con uno script python + per blender è possibile esportare il testo nel formato JSON di Three.js: + [link:http://www.jaanga.com/2012/03/blender-to-threejs-create-3d-text-with.html] +

    + +
    + + +

    6. Font Bitmap

    +
    +

    + BMFont (font bitmap) consente di raggruppare glyphs in un unico BufferGeometry. Il rendering di BMFont + supporta il word-wrapping, letter spacing, kerning, signed distance fields with standard derivatives, multi-channel signed distance fields, multi-texture fonts, ed altro ancora. + Per saperne di più consulta [link:https://github.com/felixmariotto/three-mesh-ui three-mesh-ui] o [link:https://github.com/Jam3/three-bmfont-text three-bmfont-text]. +

    +

    + I font sono disponibili in progetti come + [link:https://github.com/etiennepinchon/aframe-fonts A-Frame Fonts], o puoi creare il tuo personale partendo da qualsiasi font .TTF, + ottimizzazione per includere solo caratteri richiesti per il progetto. +

    +

    + Alcuni strumenti utili: +

    +
      +
    • [link:http://msdf-bmfont.donmccurdy.com/ msdf-bmfont-web] (web-based)
    • +
    • [link:https://github.com/soimy/msdf-bmfont-xml msdf-bmfont-xml] (commandline)
    • +
    • [link:https://github.com/libgdx/libgdx/wiki/Hiero hiero] (desktop app)
    • +
    +
    + + +

    7. Troika Text

    +
    +

    + Il pacchetto [link:https://www.npmjs.com/package/troika-three-text troika-three-text] esegue il rendering + del testo con antialias utilizzando una tecnica simile a BMFont, ma funziona direttamente con font di tipo .TTF o .WOFF + in modo da non dover pregenerare una texture glyph offline. Ha anche altre funzionalità, tra cui: +

    +
      +
    • Effetti come pennellate, ombreggiature e curvature
    • +
    • La capacità di applicare qualsiasi materiale three.js, anche un ShaderMaterial personalizzato
    • +
    • Supporto per le legature dei font, script con lettere unite e il layout da destra-a-sinistra/bidirezionale
    • +
    • Ottimizzazione per grandi quantità di testo dinamico, eseguendo la maggior parte del lavoro fuori dal thread principale in un web worker
    • +
    +
    + + + + diff --git a/docs/manual/it/introduction/Drawing-lines.html b/docs/manual/it/introduction/Drawing-lines.html new file mode 100644 index 00000000000000..d7c326b336a085 --- /dev/null +++ b/docs/manual/it/introduction/Drawing-lines.html @@ -0,0 +1,64 @@ + + + + + + + + + +

    Disegnare linee ([name])

    +
    +

    + Diciamo che tu voglia disegnare una linea o un cerchio, non un wireframe [page:Mesh]. + Prima bisogna impostare il [page:WebGLRenderer renderer], la [page:Scene scene] e la camera (vedi la pagina Creare una scena). +

    + +

    Di seguito il codice che utilizzeremo:

    + +const renderer = new THREE.WebGLRenderer(); +renderer.setSize( window.innerWidth, window.innerHeight ); +document.body.appendChild( renderer.domElement ); + +const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 500 ); +camera.position.set( 0, 0, 100 ); +camera.lookAt( 0, 0, 0 ); + +const scene = new THREE.Scene(); + +

    La prossima cosa da fare è definire il materiale. Per le linee possiamo usare [page:LineBasicMaterial] o [page:LineDashedMaterial].

    + +//crea una LineBasicMaterial blu +const material = new THREE.LineBasicMaterial( { color: 0x0000ff } ); + + +

    + Dopo la definizione del materiale abbiamo bisogno di una geometria con alcuni vertici: +

    + + +const points = []; +points.push( new THREE.Vector3( - 10, 0, 0 ) ); +points.push( new THREE.Vector3( 0, 10, 0 ) ); +points.push( new THREE.Vector3( 10, 0, 0 ) ); + +const geometry = new THREE.BufferGeometry().setFromPoints( points ); + + +

    Da notare che le linee vengono tracciate tra ogni coppia consecutiva di vertici, ma non tra il primo e l'ultimo vertice (la linea non è chiusa).

    + +

    Ora che abbiamo i punti per due linee e un materiale, possiamo unirli per formare una linea.

    + +const line = new THREE.Line( geometry, material ); + +

    Non resta che aggiungerlo alla scena e chiamare il [page:WebGLRenderer.render render].

    + + +scene.add( line ); +renderer.render( scene, camera ); + + +

    Ora dovresti vedere una freccia che punta verso l'alto formata da due linee blu.

    +
    + + diff --git a/docs/manual/it/introduction/FAQ.html b/docs/manual/it/introduction/FAQ.html new file mode 100644 index 00000000000000..ae39b91935bb89 --- /dev/null +++ b/docs/manual/it/introduction/FAQ.html @@ -0,0 +1,64 @@ + + + + + + + + + +

    FAQ ([name])

    + +

    Qual è il formato per i modelli 3D meglio supportato?

    +
    +

    + Il formato raccomandato per importare ed esportare modelli 3D è il glTF (GL Transmission Format). + Poiché è focalizzato sulla distribuzione di risorse in runtime, è compatto da trasmettere e veloce da caricare. +

    +

    + Three.js mette a disposizione loader per molti altri formati popolari come FBX, Collada o OBJ. + Tuttavia, si dovrebbe, nei propri progetti, sempre cercare di stabilire prima un flusso di lavoro basato su glTF. + Per maggiori informazioni consultare la guida sul [link:#manual/introduction/Loading-3D-models caricamento dei modelli 3D]. +

    +
    + +

    Perché negli esempi sono presenti meta tag viewport?

    +
    + <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> + +

    Questi tag controllano le dimensioni e la scala del viewport per i browser su mobile (dove il contenuto della pagina può essere visualizzato con dimensioni diverse rispetto al viewport).

    + +

    [link:https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html Safari: Usare il Viewport]

    + +

    [link:https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag MDN: Usare il meta tag viewport]

    +
    + +

    Come si può conservare la scala della scena durante il ridimensionamento?

    +

    + Vogliamo che tutti gli oggetti indipendentemente dalla loro distanza dalla camera, siano visualizzati con le stesse dimensioni anche se la finestra viene ridimensionata. + + L'equazione chiave per risolvere questo problema è data da questa formula per l'altezza visibile ad una data distanza: + + +visible_height = 2 * Math.tan( ( Math.PI / 180 ) * camera.fov / 2 ) * distance_from_camera; + + Se aumentiamo l'altezza della finestra di una certa percentuale, vogliamo che l'altezza visibile a tutte le distanze aumenti della stessa percentuale. + + Questo non può essere fatto cambiando la posizione della camera. È invece necessario modificare il valore del campo visivo (fov) della camera. + [link:http://jsfiddle.net/Q4Jpu/ Esempio]. +

    + +

    Perché una parte del mio oggetto è invisibile?

    +

    + Questo comportamento può essere causato dal "face culling" (eliminazione delle facce). Le facce hanno un orientamento che decide quale lato è quello giusto. + E il culling (eliminazione) rimuove il lato posteriore in circostanze normali. Per verificare se il problema è questo cambia la proprietà side del materiale con THREE.DoubleSide. + + material.side = THREE.DoubleSide +

    + +

    Perché three.js a volte restituisce strani risultati per input non validi?

    +

    + Per ragioni di performance three.js nella maggior parte dei casi non convalida gli input. È responsabilità della tua applicazione di controllare i dati che vengono passati a three.js. +

    + + diff --git a/docs/manual/it/introduction/How-to-create-VR-content.html b/docs/manual/it/introduction/How-to-create-VR-content.html new file mode 100644 index 00000000000000..e54f2478fdd5e7 --- /dev/null +++ b/docs/manual/it/introduction/How-to-create-VR-content.html @@ -0,0 +1,79 @@ + + + + + + + + + + + +

    Come creare contenuti VR ([name])

    + +

    + Questa guida fornisce una breve panoramica sui componenti di base di un'applicazione VR basata sul web realizzata con three.js. +

    + +

    Workflow

    + +

    + Prima di tutto devi includere [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/webxr/VRButton.js VRButton.js] nel tuo progetto. +

    + + +import { VRButton } from 'three/addons/webxr/VRButton.js'; + + +

    + *VRButton.createButton()* fa due cose importanti: Crea un bottone per indicare la compatibilità con il VR. + Inoltre, se l'utente attiva il bottone, viene avviata una sessione VR. L'unica cosa che devi fare è aggiungere la seguente + linea di codice al tuo progetto. +

    + + +document.body.appendChild( VRButton.createButton( renderer ) ); + + +

    + Successivamente, hai bisogno di dire alla tua istanza di `WebGLRenderer` di abilitare il rendering XR. +

    + + +renderer.xr.enabled = true; + + +

    + Infine, devi regolare il ciclo di animazione poiché non possiamo utilizzare la nota funzione *window.requestAnimationFrame()*. + Per i progetti VR viene utilizzato il metodo [page:WebGLRenderer.setAnimationLoop setAnimationLoop]. + Il codice minimo si presenta così: +

    + + +renderer.setAnimationLoop( function () { + + renderer.render( scene, camera ); + +} ); + + +

    Prossimi passi

    + +

    + Dai un'occhiata ad uno degli esempi ufficiali di WebVR per vedere questo flusso di lavoro in azione.

    + + [example:webxr_vr_ballshooter WebXR / VR / ballshooter]
    + [example:webxr_vr_cubes WebXR / VR / cubes]
    + [example:webxr_vr_dragging WebXR / VR / dragging]
    + [example:webxr_vr_paint WebXR / VR / paint]
    + [example:webxr_vr_panorama_depth WebXR / VR / panorama_depth]
    + [example:webxr_vr_panorama WebXR / VR / panorama]
    + [example:webxr_vr_rollercoaster WebXR / VR / rollercoaster]
    + [example:webxr_vr_sandbox WebXR / VR / sandbox]
    + [example:webxr_vr_sculpt WebXR / VR / sculpt]
    + [example:webxr_vr_video WebXR / VR / video] +

    + + + + diff --git a/docs/manual/it/introduction/How-to-dispose-of-objects.html b/docs/manual/it/introduction/How-to-dispose-of-objects.html new file mode 100644 index 00000000000000..c8a478fe7fe225 --- /dev/null +++ b/docs/manual/it/introduction/How-to-dispose-of-objects.html @@ -0,0 +1,124 @@ + + + + + + + + + + + +

    Come liberare le risorse ([name])

    + +

    + Un aspetto importante per migliorare le prestazioni ed evitare perdite di memoria nella tua applicazione è l'eliminazione delle entità della libreria non utilizzate. + Ogni volta che viene creata un'istanza di un tipo *three.js*, viene allocata una certa quantità di memoria. Tuttavia, *three.js* crea per oggetti specifici + come le geometrie o i materiali, entità correlate WebGL, come buffer o programmi shader, necessari per il rendering. È importante sottolineare che + questi oggetti non vengono rilasciati automaticamente. Invece, l'applicazione utilizza una speciale API per liberare tali risorse. Questa guida fornisce + una breve panoramica su come l'API viene utilizzata e quali oggetti sono rilevanti in questo contesto. +

    + +

    Geometrie

    + +

    + Una geometria solitamente rappresenta le informazioni sui vertici come una collezione di attributi. *three.js* internamente crea un oggetto di tipo [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer] + per ogni attributo. Queste entità vengono cancellate solo se viene chiamato il metodo [page:BufferGeometry.dispose](). Se una geometria, nella tua applicazione, + diventa obsoleta, esegui questo metodo per liberare tutte le risorse correlate. +

    + +

    Materiali

    + +

    + Un materiale definisce come sono visualizzati gli oggetti. *three.js* utilizza le informazioni di una definizione di materiale per costruire un programma shader per il rendering. + I programmi shader possono essere cancellati solo se il respettivo materiale è eliminato. Per ragioni di prestazioni, *three.js* prova, se possibile, a riutilizzare + il programma shader già esiste. Quindi un progamma di shader può essere cancellato solo se tutti i relativi materiali sono eliminati. Puoi eseguire l'eliminazione + di un materiale eseguendo il metodo [page:Material.dispose](). +

    + +

    Texture

    + +

    + L'eliminazione di un materiale non ha effetti sulle texture. Queste vengono gestite separatamente, poiché una singola texture può essere usata da più materiali contemporaneamente. + Ogni volta che crei un'istanza di [page:Texture], three.js internamente crea un'istanza di [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture]. + Come per i buffer, questo oggetto può essere eliminato solo chiamando il metodo[page:Texture.dispose](). +

    + +

    + Se stai usando `ImageBitmap` come origine dati della texture, devi chiamare il metodo [link:https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap/close ImageBitmap.close]() a livello applicativo per liberare le risorse lato CPU. + Una chiamata automatica di `ImageBitmap.close()`in [page:Texture.dispose]() non è possibile, poiché il bitmap dell'immagine diventa inutilizzabile, e l'engine non ha modo di sapere se il bitmap dell'immagine è utilizzata da altre parti. +

    + +

    Render Target

    + +

    + Oggetti di tipo [page:WebGLRenderTarget] non allocano solo un'istanza di [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture] ma anche + di [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLFramebuffer WebGLFramebuffer] e di [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderbuffer WebGLRenderbuffer] + per realizzare destinazioni di rendering personalizzate. Questi oggetti vengono solo deallocati eseguendo il metodo [page:WebGLRenderTarget.dispose](). +

    + +

    Varie

    + +

    + Ci sono altre classi nella cartella degli esempi come i control o passaggi di post-processing che forniscono metodi `dispose()` per rimuovere i listener di eventi interni o + renderizzare i target. In generale, viene raccomandato di controllare le API o la documentazione della classe e controllare il metodo `dispose()`. Se presente dovresti utilizzarlo per liberare le risorse. +

    + +

    FAQ

    + +

    Perché *three.js* non può eliminare gli oggetti automaticamente?

    + +

    + Questa domanda è stata fatta spesso dalla community, quindi è importante chiarire la questione. Il fatto è che *three.js* non conosce il ciclo di vita o lo scopo + delle entità create dall'utente come le geometrie o i materiali, questa è una responsabilità dell'applicazione. Per esempio, anche se un materiale non è momentamenente utilizzato per il + rendering, potrebbe essere necessario per il prossimo frame. Quindi se l'applicazione decide che un determianto oggetto può essere cancellato lo notifica all'engine tramite la chiamata + al rispettivo metodo `dispose()`. +

    + +

    La rimozione di una mesh dalla scena elimina anche la sua geometria e il suo materiale?

    + +

    + No, devi eliminare esplicitamente la geometria e il materiale chiamando il metodo *dispose()*. Tieni a mente che le geometrie e i materiali possono essere condivisi tra oggetti 3D come le mesh. +

    + +

    *three.js* fornisce informazioni sulla quantità di oggetti memorizzati nella cache?

    + +

    + Si, è possibile consultare [page:WebGLRenderer.info]. Una proprietà speciale del renderer con una serie di informazioni statistiche sulla memoria della scheda grafica + e il processo di rendering. Tra le altre cose, riporta anche quante texture, geometrie e programmi shader sono internamente memorizzati. Se noti che ci sono problemi + di performance nell'applicazione, è una buona idea debuggare questa proprietà per identificare facilmente se c'è una perdita di memoria. +

    + +

    Che cosa succede quando il metodo `dispose()` viene chiamato su una texture ma l'immagine non è ancora stata caricata?

    + +

    + Le risorse interne di una texture vengono allocate solo se l'immagine è caricata con successo. Se elimini una texture prima che l'immagine venga caricata + non succede niente. Nessuna risorsa è stata allocata, quindi niente deve essere pulito. +

    + +

    Cosa succede quando chiamo `dispose()` e poi utilizzo il rispettivo oggetto in un secondo momento?

    + +

    + Le risorse interne che sono state cancellate saranno ricreate dall'engine, in questo modo non ci saranno errori a runtime. Probabilmente, però, noterai un impatto negativo sulle performance nel + frame corrente quando il programma shader sarà compilato. +

    + +

    Come devo gestire gli oggetti *three.js* nella mia app? Quando so che devo eliminare le risorse?

    + +

    + In generale non c'è una raccomandazione definitiva per questo. Dipende molto dal caso d'uso specifico. È importante sottolineare che non è sempre necessario + eliminare oggetti tutto il tempo. Un buon esempio esemplificativo è un gioco a più livelli. Un buon momento per eliminare gli oggetti è quando viene cambiato il livello. + L'applicazione può attraversare tutta la vecchia scena (livello) ed eliminare tutti i vecchi materiali, geometrie e texture. Come accennato nella sezione precedente, + se viene cancellato un oggetto che è attualmente in uso non produce un errore a runtime. La cosa peggiore che può accadere è un calo delle prestazioni in un singolo frame. +

    + +

    Esempi che mostarno l'uso del metodo dispose()

    + +

    + [example:webgl_test_memory WebGL / test / memory]
    + [example:webgl_test_memory2 WebGL / test / memory2]
    +

    + + + + diff --git a/docs/manual/it/introduction/How-to-run-things-locally.html b/docs/manual/it/introduction/How-to-run-things-locally.html new file mode 100644 index 00000000000000..bb6826ce1bb327 --- /dev/null +++ b/docs/manual/it/introduction/How-to-run-things-locally.html @@ -0,0 +1,167 @@ + + + + + + + + + +

    Esecuzione in locale ([name])

    +

    + Se si usano solo geometrie procedurali e non si caricano texture, le pagine web dovrebbero funzionare direttamente + dal file system, basta fare doppio click sul file HTML in un file manager e la pagina dovrebbe apparire funzionante nel browser + (si vedrà file:///yourFile.html nella barra degli indirizzi del browser). +

    + +

    Contenuto caricato da file esterni

    +
    +

    + Se si caricano modelli o texture da file esterni, a causa delle restrizioni di sicurezza del [link:http://en.wikipedia.org/wiki/Same_origin_policy same origin policy] del browser, + il caricamento da un file system fallirà con un'eccezione di sicurezza. +

    + +

    + Per risolvere questo problema, conviene eseguire i file da un server locale. Questo permette di accedere alla pagina come: +

    + +

    + http://localhost/yourFile.html +

    + +

    + Anche se è possibile cambiare le impostazioni di sicurezza del browser invece di lanciare un server in locale, + non lo raccomandiamo. Utilizzando questo approccio si potrebbe esporre il proprio dispositivo a molte vulnerabilità soprattutto se + lo stesso browser viene utilizzato per la regolare navigazione sul web. Usare un server locale è una pratica standard nello sviluppo + web. Qui sotto, spieghiamo come si installa e utilizza un server locale. +

    +
    + + +

    Eseguire un server locale

    +
    +

    + Molti linguaggi di programmazione hanno semplici server HTTP integrati. Non sono completi come i server di produzione + come ad esempio [link:https://www.apache.org/ Apache] o [link:https://nginx.org NGINX], ma sono sufficienti per testare la tua applicazione three.js. +

    + +

    Plugin per i principali editor

    +
    +

    Alcuni editor hanno plugin che genereranno un semplice server su richiesta.

    +
      +
    • [link:https://marketplace.visualstudio.com/items?itemName=yandeu.five-server Five Server] per Visual Studio Code.
    • +
    • [link:https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer Live Server] per Visual Studio Code.
    • +
    • [link:https://atom.io/packages/atom-live-server Live Server] per Atom.
    • +
    +
    + +

    Servez

    +
    +

    + [link:https://greggman.github.io/servez Servez] è un semplice server con GUI. +

    +
    + +

    Node.js five-server

    +
    +

    Server di sviluppo con un reload in tempo reale. Installazione:

    + +# Eliminare live-server (se è presente) +npm -g rm live-server + +# Installare five-server +npm -g i five-server + +# Aggiornare five-server (di volta in volta) +npm -g i five-server@latest + + +

    Esecuzione (dalla tua cartella locale):

    + five-server . -p 8000 +
    + +

    Node.js http-server

    +
    +

    Node.js ha un semplice server HTTP. Installazione:

    + npm install http-server -g + +

    Esecuzione (dalla tua cartella locale):

    + http-server . -p 8000 +
    + +

    Python server

    +
    +

    + Se hai installato [link:http://python.org/ Python], dovrebbe essere sufficiente eseguire + i seguenti comandi da terminale (dalla cartella di lavoro): +

    + +//Python 2.x +python -m SimpleHTTPServer + +//Python 3.x +python -m http.server + + +

    Questo servirà i file dalla cartella corrente a localhost sotto la porta 8000, cioè nella barra degli indirizzi digita:

    + + http://localhost:8000/ +
    + +

    Ruby server

    +
    +

    Se hai installato Ruby, puoi avere lo stesso risultato eseguendo il seguente comando:

    + +ruby -r webrick -e "s = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => Dir.pwd); trap('INT') { s.shutdown }; s.start" + +
    + +

    PHP server

    +
    +

    Anche PHP ha un server web integrato, a partire da php 5.4.0:

    + php -S localhost:8000 +
    + +

    Lighttpd

    +
    +

    + Lighttpd è un server web generico molto leggero. Tratteremo l'installazione su OSX con HomeBrew. + Diversamente dagli altri server di cui abbiamo discusso qui, lighttpd è un server di produzione completo + pronto per la produzione. +

    + +
      +
    1. + Installazione tramite homebrew + brew install lighttpd +
    2. +
    3. + Creare un file di configurazione chiamato lighttpd.conf nella cartella in cui vuoi eseguire il server. + [link:http://redmine.lighttpd.net/projects/lighttpd/wiki/TutorialConfiguration Qui] trovi un esempio. +
    4. +
    5. + Nel file di configurazione deve essere cambiato il valore di server.document-root con la directory da cui vuoi servire i file. +
    6. +
    7. + Avvialo con + lighttpd -f lighttpd.conf +
    8. +
    9. + Inserisci l'indirizzo http://localhost:3000/ nella barra degli indirizzi del browser, questo servirà file statici + dalla cartella che hai scelto. +
    10. +
    +
    +

    IIS

    +
    +

    Se usi Microsoft IIS come web server. Per favore aggiungi le impostazioni del MIME type relative all'estensione .fbx prima del caricamento.

    + File name extension: fbx MIME Type: text/plain +

    Per impostazione predefinita IIS blocca i download di file .fbx, .obj. È necessario configurare IIS per abilitare il download di questo tipo di file

    +
    +

    + Altre semplici alternative sono [link:http://stackoverflow.com/q/12905426/24874 trattate qui] su Stack Overflow. +

    +
    + + + diff --git a/docs/manual/it/introduction/How-to-update-things.html b/docs/manual/it/introduction/How-to-update-things.html new file mode 100644 index 00000000000000..7910e7ad715af5 --- /dev/null +++ b/docs/manual/it/introduction/How-to-update-things.html @@ -0,0 +1,223 @@ + + + + + + + + + +

    Come aggiornare le cose ([name])

    +
    +

    Tutti gli oggetti di default, automaticamente aggiornano le loro matrici se vengono aggiunti alla scena seguendo il codice qui sotto:

    + +const object = new THREE.Object3D(); +scene.add( object ); + + o se sono figli di un altro oggetto che è stato aggiunto alla scena: + +const object1 = new THREE.Object3D(); +const object2 = new THREE.Object3D(); + +object1.add( object2 ); +scene.add( object1 ); // object1 e object2 aggiorneranno automaticamente le loro matrici + +
    + +

    Comunque, se sai che l'oggetto sarà statico, puoi disabilitare questo automatismo e aggiornare manualmente la matrice di trasformazione, solo quando necessario.

    + + +object.matrixAutoUpdate = false; +object.updateMatrix(); + + +

    BufferGeometry

    +
    +

    + Le BufferGeometry memorizzano le informazioni (come le posizioni dei vertici, gli indici delle facce, le normali, i colori, + le coordinate UV, e qualsiasi attributo personalizzato) nel [page:BufferAttribute buffer] - cioè in + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays array tipizzati]. + Ciò le rende generalmente più veloci delle Geometry standard, al costo di essere un po' più difficili da lavorare. +

    +

    + Per quanto riguarda l'aggiornamento delle BufferGeometry, la cosa più importante da capire è che + il buffer non può essere ridimensionato (questo è molto costoso e basicamente equivalente a creare una nuova geometria). + Indipendetemente da questo il contenuto dei buffer può essere comunque aggiornato. +

    +

    + Questo significa che se sai che un attributo della BufferGeometry crescerà, ad esempio il numero di vertici, + è necessario preallocare un buffer sufficientemente grande per contenere i nuovi vertici che potrebbero essere creati. + Ovviamente, questo significa anche che ci sarà una dimensione massima per la tua BufferGeometry - non è possibile + creare una BufferGeometry che possa essere estesa in modo efficiente indefinitamente. +

    +

    + Useremo l'esempio di una linea che viene estesa al momento del rendering. Allocheremo spazio nel buffer per contenere 500 vertici + ma all'inizio ne disegneremo soltanto due, usando [page:BufferGeometry.drawRange]. +

    + +const MAX_POINTS = 500; + +// geometry +const geometry = new THREE.BufferGeometry(); + +// attributes +const positions = new Float32Array( MAX_POINTS * 3 ); // 3 vertices per point +geometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); + +// draw range +const drawCount = 2; // draw the first 2 points, only +geometry.setDrawRange( 0, drawCount ); + +// material +const material = new THREE.LineBasicMaterial( { color: 0xff0000 } ); + +// line +const line = new THREE.Line( geometry, material ); +scene.add( line ); + +

    + Quindi, aggiungeremo punti alla linea in maniera random usando un pattern come questo: +

    + +const positions = line.geometry.attributes.position.array; + +let x, y, z, index; +x = y = z = index = 0; + +for ( let i = 0, l = MAX_POINTS; i < l; i ++ ) { + + positions[ index ++ ] = x; + positions[ index ++ ] = y; + positions[ index ++ ] = z; + + x += ( Math.random() - 0.5 ) * 30; + y += ( Math.random() - 0.5 ) * 30; + z += ( Math.random() - 0.5 ) * 30; + +} + +

    + Se vuoi cambiare il numero di punti visualizzati dopo il primo render, procedi come segue; +

    + +line.geometry.setDrawRange( 0, newValue ); + +

    + Se vuoi cambiare i valori dei dati di posizione dopo il primo render, è necessario + impostare il flag di needsUpdate come segue: +

    + +line.geometry.attributes.position.needsUpdate = true; // required after the first render + + +

    + Se vuoi modificare i valori dei dati di posizione dopo il rendering iniziale, è necessario + ricalcolare i volumi di delimitazione (bounding volumes) in modo che altre funzionalità dell'engine + come l'eliminazione del frustum di visualizzazione o gli helpers possano funzionare correttamente. +

    + +line.geometry.computeBoundingBox(); +line.geometry.computeBoundingSphere(); + + +

    + [link:https://jsfiddle.net/t4m85pLr/1/ Qui un fiddle] che mostra una linea animata che può essere adattata al tuo caso d'uso. +

    + +

    Esempi

    + +

    + [example:webgl_custom_attributes WebGL / custom / attributes]
    + [example:webgl_buffergeometry_custom_attributes_particles WebGL / buffergeometry / custom / attributes / particles] +

    + +
    + +

    Materiali

    +
    +

    Tutti i valori costanti possono essere cambiati liberamente (come i colori, le texture, l'opacità, etc), valori che vengono inviati allo shader ad ogni frame.

    + +

    Anche i parametri relativi a GLstate possono essere cambiati in qualsiasi momento (depthTest, blending, polygonOffset, etc).

    + +

    Invece, le proprietà seguenti non possono essere modificare facilmente in fase di esecuzione (una volta che il materiale è stato renderizzato almeno una volta):

    +
      +
    • numero e tipi di costanti
    • +
    • presenza oppure no di +
        +
      • texture
      • +
      • fog
      • +
      • vertex colors
      • +
      • morphing
      • +
      • shadow map
      • +
      • alpha test
      • +
      • transparent
      • +
      +
    • +
    + +

    Le modifiche di questi richiedono la creazione di un nuovo programma di shader. Dovrai impostare:

    + material.needsUpdate = true + +

    Tieni presente che questa operazione potrebbe essere piuttosto lenta e causare scatti nel framerate (specialmente su Windows, poiché la compilazione degli shader è più lenta in DirectX che in OpenGL).

    + +

    Per creare un'esperienza più fluida puoi emulare in una certa misura le modifiche a queste funzionalità avendo valori "fittizi" come luci ad intensità zero, texture bianche, o fog a zero densità.

    + +

    È possibile cambiare liberamente il materiale utilizzato per i blocchi di geometria, tuttavia non è possibile modificare il modo in cui un oggetto è diviso in blocchi (in base ai materiali della faccia).

    + +

    Se è necessario disporre di diverse configurazioni dei materiali durante l'esecuzione:

    +

    Se il numero di materiali / blocchi è piccolo, puoi dividere l'oggetto in anticipo (per esempio capelli / faccia / corpo / vestiti superiori / pantaloni per un umano / davanti / dietro / parte superiore / occhiali / pneumatico / interni di una macchina).

    + +

    Se, invece, il numero è grande (per esempio, ogni faccia potrebbe essere potenzialmente diversa), considera una soluzione divera, come usare attributi / texture per ottenere un aspetto diverso per faccia.

    + +

    Esempi

    +

    + [example:webgl_materials_car WebGL / materials / car]
    + [example:webgl_postprocessing_dof WebGL / webgl_postprocessing / dof] +

    +
    + + +

    Texture

    +
    +

    Se immagini, canvas, video e texture vengono modificate devono avere il flag needsUpdate impostato come segue:

    + + texture.needsUpdate = true; + +

    Le destinazioni di rendering si aggiornano automaticamente.

    + +

    Esempi

    +

    + [example:webgl_materials_video WebGL / materials / video]
    + [example:webgl_rtt WebGL / rtt] +

    + +
    + + +

    Telecamere

    +
    +

    La posizione e il target di una camera vengono aggiornati automaticamente. Se hai bisogno di cambiare

    +
      +
    • + fov +
    • +
    • + aspect +
    • +
    • + near +
    • +
    • + far +
    • +
    +

    + dovrai ricalcolare la matrice di proiezione: +

    + +camera.aspect = window.innerWidth / window.innerHeight; +camera.updateProjectionMatrix(); + +
    + + diff --git a/docs/manual/it/introduction/How-to-use-post-processing.html b/docs/manual/it/introduction/How-to-use-post-processing.html new file mode 100644 index 00000000000000..60b3a0d0c0a69c --- /dev/null +++ b/docs/manual/it/introduction/How-to-use-post-processing.html @@ -0,0 +1,113 @@ + + + + + + + + + +

    Come utilizzare il post-processing (How to use post-processing)

    + +

    + Molte applicazioni 3D visualizzano i loro oggetti 3D direttamente sullo schermo. A volte, tuttavia, si vuole applicare uno o più effetti grafici + come Depth-Of-Field, Bloom, Film Grain o vari tipi di Anti-aliasing. Il Post-processing è una soluzione ampiamente utilizzata per implementare questi effetti. + Prima di tutto, la scena viene renderizzata su un target di rendering che rappresenta un buffer nella memoria della scheda video. + Nella fase successiva, uno o più passaggi di post-processing applicano filtri ed effetti al buffer dell'immagine prima che questa venga infine renderizzata + sullo schermo. +

    +

    + three.js fornisce una soluzione di post-processing completa tramite [page:EffectComposer] per implementare tale flusso di lavoro. +

    + +

    Workflow

    + +

    + Il primo step, nel processo, è quello di importare tutti i file necessari dalla cartella degli esempi. La guida presuppone che si utilizzi + il [link:https://www.npmjs.com/package/three pacchetto npm] ufficiale di three.js. Per la nostra demo di base in questa guida abbiamo + bisogno dei seguenti file: +

    + + + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { GlitchPass } from 'three/addons/postprocessing/GlitchPass.js'; + + +

    + Dopo che tutti i file sono stati importati con successo, possiamo creare il nostro composer passandogli un'istanza di [page:WebGLRenderer]. +

    + + + const composer = new EffectComposer( renderer ); + + +

    + Quando viene usato un composer è necessario modificare il ciclo di animazine dell'applicazione. Invece di chiamare il metodo render di + [page:WebGLRenderer], usiamo la rispettiva controparte di [page:EffectComposer]. +

    + + + function animate() { + + requestAnimationFrame( animate ); + + composer.render(); + + } + + +

    + Il composer è pronto, ed è possibile configurare la catena di passaggi di post-processing. Questi passaggi sono i responsabili per la creazione + dell'output visivo finale dell'applicazione. Vengono elaborati nello stesso ordine in cui sono stati aggiunti/inseriti. Nel nostro esempio, l'istanza + di `RenderPass` viene eseguita per prima, poi l'istanza di `GlitchPass`. L'ultimo passaggio abilitato della catena viene automaticamente renderizzato sullo schermo. + La configurazione dei passaggi è la seguente: +

    + + + const renderPass = new RenderPass( scene, camera ); + composer.addPass( renderPass ); + + const glitchPass = new GlitchPass(); + composer.addPass( glitchPass ); + + +

    + `RenderPass` viene normalmente posizionata all'inizio della catena per fornire la scena renderizzata come input per il passaggio successivo di post-processing. + Nel nostro caso `GlitchPass` utilizzarà questi dati di immagine per applicare un effetto glitch selvaggio. Guarda questo [link:https://threejs.org/examples/webgl_postprocessing_glitch esempio live] + per vederli in azione. +

    + +

    Passi Built-in

    + +

    + È possibile utilizzare un'ampia gamma di passaggi di post-processing predefiniti forniti dall'engine. Si possono trovare nella + cartella di [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/postprocessing postprocessing]. +

    + +

    Passi personalizzati

    + +

    + A volte si desidera scrivere uno shader di post-processing personalizzato e includerlo nella catena dei passi di post-processing. + Per questo scenario puoi utilizzare `ShaderPass`. Dopo aver importato il file e lo shader personalizzato, si può usare il seguente codice per + impostare i passaggi: +

    + + + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { LuminosityShader } from 'three/addons/shaders/LuminosityShader.js'; + + // later in your init routine + + const luminosityPass = new ShaderPass( LuminosityShader ); + composer.addPass( luminosityPass ); + + +

    + Il repository fornisce un file chiamato [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/shaders/CopyShader.js CopyShader], il quale è un ottimo + punto di partenza per il tuo shader personalizzato. `CopyShader` copia semplicemente il contenuto dell'immagine del buffer di lettura dell'[page:EffectComposer] + nel buffer di scrittura senza applicare alcun effetto. +

    + + + diff --git a/docs/manual/it/introduction/Installation.html b/docs/manual/it/introduction/Installation.html new file mode 100644 index 00000000000000..bb9a82fa7a117b --- /dev/null +++ b/docs/manual/it/introduction/Installation.html @@ -0,0 +1,160 @@ + + + + + + + + + +

    Installazione ([name])

    + +

    + È possibile installare three.js con [link:https://www.npmjs.com/ npm] e i moderni strumenti di compilazione, o iniziare rapidamente con un hosting statico o un CDN. Per la maggior parte degli utenti fare l'installazione usando npm è la scelta migliore. +

    + +

    + Qualsiasi soluzione venga scelta, sii coerente e importa tutti i file della stessa versione della libreria. + Mescolare file provenienti da fonti diverse può causare l'inclusione di codice duplicato o addirittura rompere l'applicazione in modo imprevisto. +

    + +

    + Tutti i metodi di installazione di three.js dipendono dai moduli ES (vedi [link:https://eloquentjavascript.net/10_modules.html#h_hF2FmOVxw7 Eloquent JavaScript: ECMAScript Modules]), i quali permettono di includere nel progetto finale solo le parti della libreria necessarie. +

    + +

    Installazione tramite npm

    + +

    + Per installare il modulo npm di [link:https://www.npmjs.com/package/three three], apri il terminale nella cartella del progetto ed esegui: +

    + + + npm install three + + +

    + Il pacchetto verrà scaricato e installato. Quindi sarà pronto per essere importato nel tuo codice: +

    + + + // Opzione 1: Importa l'intera libreria di base di three.js + import * as THREE from 'three'; + + const scene = new THREE.Scene(); + + + // Opzione 2: Importa solo le parti di cui hai bisogno + import { Scene } from 'three'; + + const scene = new Scene(); + + +

    + Quando la libreria viene installata da npm, verrà quasi sempre utilizzato uno [link:https://eloquentjavascript.net/10_modules.html#h_zWTXAU93DC strumento di bundling] per combinare tutti i pacchetti richiesti dal tuo progetto in un unico file JavaScript. Sebbene con three.js si possa utilizzare qualsiasi moderno strumento di bundling, la scelta più popolare è [link:https://webpack.js.org/ webpack]. +

    + +

    + Non tutte le funzioni sono accessibili direttamente attraverso il modulo three (chiamato anche "bare import"). Altre parti popolari della libreria — come i controls, i loaders e gli effetti di post-processing — devono essere importati dalla sottocartella [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm]. Per saperne di più si vedano gli Esempi qui sotto. +

    + +

    + Per saperne di più sui moduli npm, consultare [link:https://eloquentjavascript.net/20_node.html#h_J6hW/SmL/a Eloquent JavaScript: Installing with npm]. +

    + +

    Installazione da CDN o hosting statico

    + +

    + La libreria three.js può essere usata senza alcun sistema di building, sia caricando i file sul tuo server web o usando un CDN esistente. Poiché la libreria si basa su moduli ES, qualsiasi script che fa riferimento ad essa deve usare type="module" come mostrato di seguito. + Inoltre è necessario anche definire un Import Map che risolva il bare module `three`. +

    + + + <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> + + <script type="importmap"> + { + "imports": { + "three": "https://unpkg.com/three@<version>/build/three.module.js" + } + } + </script> + + <script type="module"> + + import * as THREE from 'three'; + + const scene = new THREE.Scene(); + + </script> + + +

    + Poiché le mappe di importazione non sono ancora supportate da tutti i browser, è necessario aggiungere il polyfill *es-module-shims.js*. +

    + +

    Addons

    + +

    + Il core di three.js è incentrato sui componenti più importanti di un engine 3D. Molti altri componenti utili - come i controls, i loaders e gli effetti post-processing - sono parte della sottocartella [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm]. Vengono definiti "esempi" perché, pur potendo essere utilizzati in modo immediato, sono anche destinati a essere remixati e personalizzati. Questi componenti vengono sempre mantenuti sincronizzati con la libreria principale, mentre i pacchetti di terze parti su npm sono gestiti da persone differenti e potrebbero non essere aggiornati. +

    + +

    + Non è necessario installare gli addons separatamente, ma dovranno essere importati separatamente. Se three.js è stato installato con npm, è possibile caricare il componente [page:OrbitControls] con: +

    + + + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + + const controls = new OrbitControls( camera, renderer.domElement ); + + +

    + Se three.js è stato installato da un CDN, usare lo stesso CDN per installare altri componenti: +

    + + + <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> + + <script type="importmap"> + { + "imports": { + "three": "https://unpkg.com/three@<version>/build/three.module.js", + "three/addons/": "https://unpkg.com/three@<version>/examples/jsm/" + } + } + </script> + + <script type="module"> + + import * as THREE from 'three'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + + const controls = new OrbitControls( camera, renderer.domElement ); + + </script> + + +

    + È importante che tutti i file usino la stessa versione. Non devono essere importati addons diversi con versioni diverse, o usare addons che derivano da una versione differente di three.js. +

    + +

    Compatibilità

    + +

    Import CommonJS

    + +

    + La maggior parte dei bundler JavaScript moderni supportano i moduli ES di default, ma questo non è detto per bundler più vecchi. In questo caso è possibile configurare il bundler per riconoscere i moduli ES. Ad esempio [link:http://browserify.org/ Browserify] ha solo bisogno del plugin [link:https://github.com/babel/babelify babelify]. +

    + +

    Node.js

    + +

    + Poiché three.js è stato creato per il web, dipende dal browser e dalle API del DOM che non sempre esistono in Node.js. Alcuni di questi problemi possono essere risolti usando dei "tappa buchi" come [link:https://github.com/stackgl/headless-gl headless-gl], o sostituendo i componenti come [page:TextureLoader] con alternative personalizzate. Altre API del DOM potrebbero essere profondamente intrecciate con il codice che le utilizza e potrebbe essere più difficile aggirarle. Accettiamo benvolentieri le pull request semplici e gestibili per migliorare il supporto di Node.js, ma raccomandiamo di aprire prima una issue per discutere dei tuoi miglioramenti. +

    + +

    + Assicurati di aggiungere `{ "type": "module" }` al tuo `package.json` per abilitare i moduli ES nel tuo progetto Node. +

    + + + diff --git a/docs/manual/it/introduction/Libraries-and-Plugins.html b/docs/manual/it/introduction/Libraries-and-Plugins.html new file mode 100644 index 00000000000000..a65b8ac7fe7626 --- /dev/null +++ b/docs/manual/it/introduction/Libraries-and-Plugins.html @@ -0,0 +1,108 @@ + + + + + + + + + +

    Librerie e Plugin ([name])

    + +

    + Di seguito sono elencate librerie e plugin, sviluppati esternamente, compatibili con three.js. + Questo elenco e i pacchetti associati sono mantenuti e gestiti dalla community e non è garantito che siano + aggiornati. Se vuoi aggiornare questa lista apri una PR! +

    + +

    Fisica

    + +
      +
    • [link:https://github.com/lo-th/Oimo.js/ Oimo.js]
    • +
    • [link:https://enable3d.io/ enable3d]
    • +
    • [link:https://github.com/kripken/ammo.js/ ammo.js]
    • +
    • [link:https://github.com/pmndrs/cannon-es cannon-es]
    • +
    + +

    Post-processing

    + +

    + Oltre agli [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/postprocessing effetti di post-processing ufficiali di three.js] + è disponibile tramite librerie esterne il supporto per alcuni effetti e framework aggiuntivi. +

    + +
      +
    • [link:https://github.com/vanruesc/postprocessing postprocessing]
    • +
    + +

    Intersezione e Performance Raycast

    + +
      +
    • [link:https://github.com/gkjohnson/three-mesh-bvh three-mesh-bvh]
    • +
    + +

    Path Tracing

    + +
      +
    • [link:https://github.com/gkjohnson/three-gpu-pathtracer three-gpu-pathtracer]
    • +
    + +

    File Formats

    + +

    + Oltre [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/loaders ai loaders ufficili di three.js], + è disponibile tramite librerie esterne il supporto per alcuni formati aggiuntivi. +

    + +
      +
    • [link:https://github.com/gkjohnson/urdf-loaders/tree/master/javascript urdf-loader]
    • +
    • [link:https://github.com/NASA-AMMOS/3DTilesRendererJS 3d-tiles-renderer-js]
    • +
    • [link:https://github.com/kaisalmen/WWOBJLoader WebWorker OBJLoader]
    • +
    • [link:https://github.com/IFCjs/web-ifc-three IFC.js]
    • +
    + +

    Geometria

    + +
      +
    • [link:https://github.com/spite/THREE.MeshLine THREE.MeshLine]
    • +
    + +

    Layout e Testo 3D

    + +
      +
    • [link:https://github.com/protectwise/troika/tree/master/packages/troika-three-text troika-three-text]
    • +
    • [link:https://github.com/felixmariotto/three-mesh-ui three-mesh-ui]
    • +
    + +

    Sistemi di particelle

    + +
      +
    • [link:https://github.com/creativelifeform/three-nebula three-nebula]
    • +
    + +

    Cinematica inversa

    + +
      +
    • [link:https://github.com/jsantell/THREE.IK THREE.IK]
    • +
    • [link:https://github.com/lo-th/fullik fullik]
    • +
    • [link:https://github.com/gkjohnson/closed-chain-ik-js closed-chain-ik]
    • +
    + +

    Game AI

    + +
      +
    • [link:https://mugen87.github.io/yuka/ yuka]
    • +
    • [link:https://github.com/donmccurdy/three-pathfinding three-pathfinding]
    • +
    + +

    Wrappers e Frameworks

    + +
      +
    • [link:https://aframe.io/ A-Frame]
    • +
    • [link:https://github.com/pmndrs/react-three-fiber react-three-fiber]
    • +
    • [link:https://github.com/ecsyjs/ecsy-three ECSY]
    • +
    • [link:https://threlte.xyz/ Threlte]
    • +
    + + + diff --git a/docs/manual/it/introduction/Loading-3D-models.html b/docs/manual/it/introduction/Loading-3D-models.html new file mode 100644 index 00000000000000..0d293c82181622 --- /dev/null +++ b/docs/manual/it/introduction/Loading-3D-models.html @@ -0,0 +1,155 @@ + + + + + + + + + + + +

    Caricare modelli 3D ([name])

    + +

    + I modelli 3D sono disponibili in centinai di formati, ognuno con uno scopo differente, diverse funzioni + e complessità varie. Sebbene + three.js metta a disposizione molti loader, la scelta del formato e del flusso di lavoro giusti farà risparmiare tempo e frustrazione in seguito. + Con alcuni formati è difficile lavorare, possono essere inefficienti per le esperienze in tempo reale, o semplicemente non supportati al momento. +

    + +

    + Questa guida mette a dispozione un flusso di lavoro consigliato per la maggior parte degli utenti, e dei suggerimenti + per affrontare i malfunzionamenti nel caso in cui non funzionasse come ci si aspetta. +

    + +

    Prima di iniziare

    + +

    + Se siete alle prime armi con la gestione di un server locale, + iniziate prima di tutto a capire [link:#manual/introduction/How-to-run-things-locally come gestire le cose a livello locale]. + Molti errori comuni nella visualizzazione dei modelli 3D possono essere evitati gestendo correttamente l'hosting dei file. +

    + +

    Workflow consigliato

    + +

    + Dove possibile, consigliamo di utilizzare il formato glTF (GL Transmission Format). + Entrambe le versioni .GLB e .GLTF sono supportate. + Il formato glTF è incentrato sulla distribuzione di asset in runtime, è compatto da trasmette e veloce da caricare. + Le carattestistiche includono mesh, materiali, texture, skin, skeleton, morph target, animazioni, luci, e camera. +

    + +

    + Modelli glTF pubblici sono disponibili su siti come + Sketchfab, o vari strumenti di sviluppo di modelli includono l'esportazione glTF: +

    + + + +

    + Se i tuoi strumenti preferiti di sviluppo dei modelli, non supportano il formato glTF, + considera di richiedere l'esportazione glTF agli autori, + o di fare un post sul thread della roadmap di glTF. +

    + +

    + Quando il formato glTF non è disponibile, i formati popolari come FBX, OBJ, o COLLADA + sono comunque disponibili e mantenuti regolarmente. +

    + +

    Caricamento

    + +

    + Solo alcuni loader (ad es. [page:ObjectLoader]) sono inclusi di default con three.js — altri devono essere aggiunti all'applicazione individualmente. +

    + + + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + + +

    + Una volta importato un loader, sei pronto per aggiungere e caricare un modello alla scena. La sintassi + varia a seconda del loader utilizzato - quando vengono utilizzati altri formati, contralla gli esempi e la + documentazione del loader. Per il formato glTF, l'utilizzo con gli script globali sarebbe: +

    + + + const loader = new GLTFLoader(); + + loader.load( 'path/to/model.glb', function ( gltf ) { + + scene.add( gltf.scene ); + + }, undefined, function ( error ) { + + console.error( error ); + + } ); + + +

    + Per maggiori dettagli consulta la [page:GLTFLoader documentazione GLTFLoader]. +

    + +

    Troubleshooting

    + +

    + Hai passato ore a modellare un capolavoro artigianale, lo carichi nella pagina web e — oh no! 😭 + è distorto, scolorito o mancante. + Inizia con questi passaggi per la risoluzione dei problemi: +

    + +
      +
    1. + Controlla la console JavaScript per vedere se ci sono errori, + ed accertati di aver usato la funzione di callback `onError` del meotodo `.load()` + per visualizzare il risultato nella console. +
    2. +
    3. + Visualizza il modello in un'altra applicazione. Per il formato glTF, sono disponibili visualizzatori drag-and-drop per + three.js e + babylon.js. + Se il modello viene visualizzato correttamente in una o più applicazioni, + segnala il bug a three.js. + Se il modello non è visualizzabile in nessuna applicazione, incoraggiamo vivamente di segnalare un bug + all'applicazione utilizzata per creare il modello. +
    4. +
    5. + Prova a scalare il modello verso l'alto o il basso di un fattore di 1000. Molti modelli sono scalati diversamente, + e molti modelli di grandi dimensioni non vengono visualizzati se la telecamera si trova all'interno del modello. +
    6. +
    7. + Prova ad aggiungere e posizionare una luce nella scena. Il modello potrebbe essere nascosto nell'oscurità. +
    8. +
    9. + Cerca le richieste delle texture fallite nel tab network degli strumenti per sviluppatori del browser, + come `"C:\\Path\To\Model\texture.jpg"`. Utilizza path relativi al tuo modello come `images/texture.jpg` - + ciò potrebbe richiedere una modifica del file del modello in un editor di testo. +
    10. +
    + +

    Chiedere aiuto

    + +

    + Se hai eseguito la procedura di risoluzione dei problemi qui sopra e il tuo modello ancora non funziona, + il giusto approccio è chiedere aiuto per una soluzione più veloce. Scrivi una domanda sul + forum three.js e, quando possibile, + includi il tuo modello (o un modello più semplice con lo stesso problema) in qualsiasi formato disponibile. + Includi informazioni sufficienti per consentire a qualcun altro di riprodurre rapidamente il problema - idealmente, una demo dal vivo. +

    + + + + diff --git a/docs/manual/it/introduction/Matrix-transformations.html b/docs/manual/it/introduction/Matrix-transformations.html new file mode 100644 index 00000000000000..2b44eee4ddb05c --- /dev/null +++ b/docs/manual/it/introduction/Matrix-transformations.html @@ -0,0 +1,78 @@ + + + + + + + + + +

    Trasformazioni di matrici ([name])

    + +

    + Three.js utilizza le `matrici` per codificare le trasformazioni 3D, traslazioni (posizione), rotazioni e ridimensionamento. Ogni istanza di [page:Object3D] + ha una [page:Object3D.matrix matrice] che memorizza la posizione, la rotazione e il ridimensionamento. Questa pagina descrive come aggiornare la trasformazione + di un oggetto. +

    + +

    Proprietà di convenienza e `matrixAutoUpdate`

    + +

    + Ci sono due modi per aggiornare la trasformazione di un oggetto: +

    +
      +
    1. + Modificare le proprietà `position`, `quaternion` e `scale` dell'oggetto e lasciare che three.js ricalcoli la + matrice dell'oggetto da queste proprietà: + +object.position.copy( start_position ); +object.quaternion.copy( quaternion ); + + Per impostazione predefinita, la proprietà `matrixAutoUpdate` è impostata su true e la matrice viene ricalcolata automaticamente. + Se l'oggetto è statico, o desideri controllare manualmente quando avviene il ricalcolo, è possibile ottenere prestazioni migliori se la + proprietà è impostata a false. + +object.matrixAutoUpdate = false; + + E dopo aver modificato le proprietà, aggiornare manualmente la matrice: + +object.updateMatrix(); + +
    2. +
    3. + Modificare direttamente la matrice dell'oggetto. La classe [page:Matrix4] possiede vari metodi per modificare la matrice: + +object.matrix.setRotationFromQuaternion( quaternion ); +object.matrix.setPosition( start_position ); +object.matrixAutoUpdate = false; + + Nota che, in questo caso, `matrixAutoUpdate` deve essere impostata a `false`, e devi essere sicuro di non chiamare `updateMatrix`. + La chiamata di `updateMatrix` eliminerà le modifiche manuali apportate alla matrice, ricalcolando la matrice da `position`, `scale`, e così via. +
    4. +
    + +

    Oggetto e matrici del mondo (world matrices)

    +

    + La [page:Object3D.matrix matrice] dell'oggetto memorizza la trsformazione dell'oggetto relativa al [page:Object3D.parent genitore] dell'oggetto: + per ottenere la trasformazione dell'oggetto nelle coordinate del mondo, è necessario accedere alla [page:Object3D.matrixWorld] dell'oggetto. +

    +

    + Quando la trasformazione dell'oggetto padre o dell'oggetto figlio cambia, puoi richiedere che la [page:Object3D.matrixWorld matrixWorld] dell'oggetto + figlio venga aggiornata chiamando il metodo [page:Object3D.updateMatrixWorld updateMatrixWorld](). +

    + +

    Rotazione e Quaternione

    +

    + Three.js fornisce due modi per rappresentare le rotazioni 3D: [page:Euler angoli di Eulero] e [page:Quaternion Quaternioni], + nonché metodi per la conversione tra i due. Gli angoli di Eulero sono soggetti ad un problema chiamato "gimbal lock", in cui alcune + configurazioni possono perdere un grado di libertà (impedendo all'oggetto di essere ruotato su un asse). Per questo motivo, le + rotazioni degli oggetti sono sempre memorizzate nei [page:Object3D.quaternion quaternioni] dell'oggetto. +

    +

    + Le versioni precedenti della libreria includevano una proprietà `useQuaternion` che, se impostata a false, faceva si che la + [page:Object3D.matrix matrix] dell'oggetto fosse calcolata da un angolo di Eulero. Questa pratica è deprecata, si deve invece + usare il metodo [page:Object3D.setRotationFromEuler setRotationFromEuler], il quale aggiornerà il quaternione. +

    + + + diff --git a/docs/manual/it/introduction/Useful-links.html b/docs/manual/it/introduction/Useful-links.html new file mode 100644 index 00000000000000..72cc3bef4944bc --- /dev/null +++ b/docs/manual/it/introduction/Useful-links.html @@ -0,0 +1,176 @@ + + + + + + + + + +

    Link utili ([name])

    + +

    + Quella che segue è una raccolta di link che potresti trovare utili durante lo studio di three.js.
    + Se trovi qualcosa che ti piacerebbe aggiungere a questa lista o se pensi che uno dei link qui sotto non sia rilevante o non funzioni, + sentiti libero di modificare la pagina cliccando sul bottone 'edit' in basso a destra.

    + + Considera anche che, essendo three.js in rapida crescita, molti di questi link conterranno informazioni non aggiornate - + se qualcosa non funziona come ti aspetti o come uno di questi link dice che dovrebbe, controlla la console + del browser per verificare la presenza di warning o errori. Controlla anche le pagine dei documenti pertinenti. +

    + +

    Forum di supporto

    +

    + Three.js ufficialmente utilizza il [link:https://discourse.threejs.org/ forum] e [link:http://stackoverflow.com/tags/three.js/info Stack Overflow] per richieste di aiuto. + Se hai bisogno di assistenza con qualcosa, questi sono i posti dove andare a chiedere e cercare una soluzione. NON aprire una issue su Github per richieste di aiuto. +

    + +

    Corsi e tutorial

    + +

    Iniziare con three.js

    +
      +
    • + [link:https://threejs.org/manual/#en/fundamentals Three.js Fundamentals starting lesson] +
    • +
    • + [link:https://codepen.io/rachsmith/post/beginning-with-3d-webgl-pt-1-the-scene Beginning with 3D WebGL] di [link:https://codepen.io/rachsmith/ Rachel Smith]. +
    • +
    • + [link:https://www.august.com.au/blog/animating-scenes-with-webgl-three-js/ Animating scenes with WebGL and three.js] +
    • +
    + +

    Articoli e corsi avanzati

    +
      +
    • + [link:https://threejs-journey.com/ Three Journey] Corso di [link:https://bruno-simon.com/ Bruno Simon] - Insegna ai beginners come usare Three.js step by step +
    • +
    • + [link:https://discoverthreejs.com/ Discover three.js] +
    • +
    • + [link:http://blog.cjgammon.com/ Collection of tutorials] di [link:http://www.cjgammon.com/ CJ Gammon]. +
    • +
    • + [link:https://medium.com/soffritti.pierfrancesco/glossy-spheres-in-three-js-bfd2785d4857 Glossy spheres in three.js]. +
    • +
    • + [link:https://www.udacity.com/course/cs291 Interactive 3D Graphics] - un corso gratuito su Udacity che insegna i fondamenti della grafica 3D, + utilizza three.js come strumenti di coding. +
    • +
    • + [Link:https://aerotwist.com/tutorials/ Aerotwist] tutorial di [link:https://github.com/paullewis/ Paul Lewis]. +
    • +
    • + [link:https://discourse.threejs.org/t/three-js-bookshelf/2468 Three.js Bookshelf] - Stai cercando più risorse relative a three.js o alla computer graphics in generale? + Controlla la selezione di letteratura suggerita dalla community. +
    • +
    + +

    News e Aggiornamenti

    +
      +
    • + [link:https://twitter.com/hashtag/threejs Three.js on Twitter] +
    • +
    • + [link:http://www.reddit.com/r/threejs/ Three.js on reddit] +
    • +
    • + [link:http://www.reddit.com/r/webgl/ WebGL on reddit] +
    • +
    + +

    Esempi

    +
      +
    • + [link:https://github.com/edwinwebb/three-seed/ three-seed] - starter kit di un progetto three.js con ES6 e Webpack +
    • +
    • + [link:http://stemkoski.github.io/Three.js/index.html Professor Stemkoskis Examples] - una raccolta di esempi per principianti creati utilizzando three.js r60. +
    • +
    • + [link:https://threejs.org/examples/ Esempi three.js ufficiali] - questi esempi sono gestiti come parte del repository di three.js e usano sempre l'ultima versione della libreria. +
    • +
    • + [link:https://raw.githack.com/mrdoob/three.js/dev/examples/ Esempi three.js ufficiali del branch di dev] - + Come sopra, tranne che questi usano il branch di dev di three.js, e vengono utilizzati per verificare + che tutto funzioni mentre viene sviluppato three.js. +
    • +
    + +

    Strumenti

    +
      +
    • + [link:https://github.com/tbensky/physgl physgl.org] - Applicazione front-end JavaScript con un wrapper per three.js, per avvicinare la grafica WebGL + agli studenti che stanno imparando fisica e matematica. +
    • +
    • + [link:https://whsjs.readme.io/ Whitestorm.js] – Framework modulare three.js con plugin per la fisica AmmoNext. +
    • +
    • + [link:http://zz85.github.io/zz85-bookmarklets/threelabs.html Three.js Inspector] +
    • +
    • + [link:http://idflood.github.io/ThreeNodes.js/ ThreeNodes.js]. +
    • +
    • + [link:https://marketplace.visualstudio.com/items?itemName=slevesque.shader vscode shader] - Syntax highlighter per il linguaggio dello shader. +
      + [link:https://marketplace.visualstudio.com/items?itemName=bierner.comment-tagged-templates vscode comment-tagged-templates] - Syntax highlighting per le stringhe di template etichettate + usando i commenti al linguaggio shader, come: glsl.js. +
    • +
    • + [link:https://github.com/MozillaReality/WebXR-emulator-extension WebXR-emulator-extension] +
    • +
    + +

    Riferimenti WebGL

    +
      +
    • + [link:https://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf webgl-reference-card.pdf] - Riferimento di tutte le parole chiave, terminologia, sintassi e definizioni WebGL e GLSL. +
    • +
    + +

    Vecchi Link

    +

    + Questi link sono conservati per scopi storici - potresti trovarli utili, ma tieni presente che + potrebbero contenere informazioni relative a versioni molto vecchie di three.js. +

    + +
      +
    • + AlterQualia at WebGL Camp 3 +
    • +
    • + [link:http://yomotsu.github.io/threejs-examples/ Yomotsus Examples] - una collezione di esempi che utilizza la versione r45 di three.js. +
    • +
    • + [link:http://fhtr.org/BasicsOfThreeJS/#1 Introduction to Three.js] di [link:http://github.com/kig/ Ilmari Heikkinen] (slideshow). +
    • +
    • + [link:http://www.slideshare.net/yomotsu/webgl-and-threejs WebGL and Three.js] di [link:http://github.com/yomotsu Akihiro Oyamada] (slideshow). +
    • +
    • + Trigger Rally di [link:https://github.com/jareiko jareiko] (video). +
    • +
    • + [link:http://blackjk3.github.io/threefab/ ThreeFab] - editor di scene, mantenuto fino alla versione r50 di three.js. +
    • +
    • + [link:http://bkcore.com/blog/3d/webgl-three-js-workflow-tips.html Max to Three.js workflow tips and tricks] di [link:https://github.com/BKcore BKcore] +
    • +
    • + [link:http://12devsofxmas.co.uk/2012/01/webgl-and-three-js/ A whirlwind look at Three.js] + di [link:http://github.com/nrocy Paul King] +
    • +
    • + [link:http://bkcore.com/blog/3d/webgl-three-js-animated-selective-glow.html Animated selective glow in Three.js] + di [link:https://github.com/BKcore BKcore] +
    • +
    • + [link:http://www.natural-science.or.jp/article/20120220155529.php Building A Physics Simulation Environment] - tutorial di three.js in Giapponese +
    • +
    + + + diff --git a/docs/manual/it/introduction/WebGL-compatibility-check.html b/docs/manual/it/introduction/WebGL-compatibility-check.html new file mode 100644 index 00000000000000..f0097c4aaebf41 --- /dev/null +++ b/docs/manual/it/introduction/WebGL-compatibility-check.html @@ -0,0 +1,35 @@ + + + + + + + + + +

    Controllo compatibilità WebGL ([name])

    +

    + Anche se questo sta diventano sempre meno un problema, alcuni dispositivi o browser potrebbero ancora non supportare WebGL. + Il seguente codice è utile per controllare se WebGL è supportato, infatti se non lo fosse viene mostrato un messaggio di errore all'utente. +

    + +

    + Aggiungere il seguente link [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/capabilities/WebGL.js] + al file javascript ed inserire il seguente codice prima di provare a renderizzare qualsiasi cosa: +

    + + + if ( WebGL.isWebGLAvailable() ) { + + // Avviare qui la funzione o altre inizializzazioni + animate(); + + } else { + + const warning = WebGL.getWebGLErrorMessage(); + document.getElementById( 'container' ).appendChild( warning ); + + } + + + diff --git a/docs/manual/ja/introduction/How-to-create-VR-content.html b/docs/manual/ja/introduction/How-to-create-VR-content.html index d1db7a733fa016..9fd2dd351530df 100644 --- a/docs/manual/ja/introduction/How-to-create-VR-content.html +++ b/docs/manual/ja/introduction/How-to-create-VR-content.html @@ -22,7 +22,7 @@

    Workflow

    -import { VRButton } from 'three/examples/jsm/webxr/VRButton.js'; +import { VRButton } from 'three/addons/webxr/VRButton.js';

    diff --git a/docs/manual/ja/introduction/How-to-use-post-processing.html b/docs/manual/ja/introduction/How-to-use-post-processing.html index 8da4ba8c832bdf..fd311f4afae066 100644 --- a/docs/manual/ja/introduction/How-to-use-post-processing.html +++ b/docs/manual/ja/introduction/How-to-use-post-processing.html @@ -30,9 +30,9 @@

    Workflow

    - import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'; - import { GlitchPass } from 'three/examples/jsm/postprocessing/GlitchPass.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { GlitchPass } from 'three/addons/postprocessing/GlitchPass.js';

    @@ -96,8 +96,8 @@

    Custom Passes(カスタムpass)

    - import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'; - import { LuminosityShader } from 'three/examples/jsm/shaders/LuminosityShader.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { LuminosityShader } from 'three/addons/shaders/LuminosityShader.js'; // later in your init routine diff --git a/docs/manual/ja/introduction/Installation.html b/docs/manual/ja/introduction/Installation.html index 872d9ad9822f97..980f947fb1da15 100644 --- a/docs/manual/ja/introduction/Installation.html +++ b/docs/manual/ja/introduction/Installation.html @@ -69,35 +69,38 @@

    CDNや静的ホスティングからインストールをする

    - <script type="module"> +<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> - // Find the latest version by visiting https://cdn.skypack.dev/three. +<script type="importmap"> + { + "imports": { + "three": "https://unpkg.com/three@<version>/build/three.module.js" + } + } +</script> - import * as THREE from 'https://cdn.skypack.dev/three@<version>'; +<script type="module"> - const scene = new THREE.Scene(); + import * as THREE from 'three'; - </script> - - -

    - すべての機能が build/three.module.js モジュールからアクセスできるわけではありません。コントロール、ローダー、エフェクトの前処理など、ライブラリの他の一般的な部分は、[link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm] サブフォルダからインポートする必要があります。詳細については、以下のExamplesを参照してください。 -

    + const scene = new THREE.Scene(); +</script> +
    -

    Examples

    +

    Addons

    three.jsのコアは、3Dエンジンの最も重要なコンポーネントに焦点を当てています。コントロール、ローダー、エフェクトの前処理といった、他の多くの便利なコンポーネントは [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm] ディレクトリの一部です。これらは「examples」と呼ばれています。その理由としては、ユーザーが既製品を使用でき、リミックスやカスタマイズも可能だからです。これらのコンポーネントは常にコアライブラリと同期していますが、npm上の同様のサードパーティ製パッケージは別の人によってメンテナンスされており、最新ではないかもしれません。

    - Examplesはそれだけ別でインストールする必要はありませんが、importは分けて行う必要があります。 three.jsをnpmでインストールしている場合、以下のようにして[page:OrbitControls]コンポーネントを読み込むことができます。 + Addonsはそれだけ別でインストールする必要はありませんが、importは分けて行う必要があります。 three.jsをnpmでインストールしている場合、以下のようにして[page:OrbitControls]コンポーネントを読み込むことができます。

    - import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; const controls = new OrbitControls( camera, renderer.domElement ); @@ -107,19 +110,29 @@

    Examples

    - <script type="module"> +<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> - // Find the latest version by visiting https://cdn.skypack.dev/three. The URL will - // redirect to the newest stable release. - import { OrbitControls } from 'https://cdn.skypack.dev/three/examples/jsm/controls/OrbitControls.js'; +<script type="importmap"> + { + "imports": { + "three": "https://unpkg.com/three@<version>/build/three.module.js", + "three/addons/": "https://unpkg.com/three@<version>/examples/jsm/" + } + } +</script> - const controls = new OrbitControls( camera, renderer.domElement ); +<script type="module"> - </script> - + import * as THREE from 'three'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + + const controls = new OrbitControls( camera, renderer.domElement ); + +</script> +

    - 重要なのは、すべてのファイルで同じバージョンを使用することです。異なるバージョンの異なるExamplesをインポートしたり、three.jsライブラリ自体とは異なるバージョンのExamplesを使用したりしないでください。 + 重要なのは、すべてのファイルで同じバージョンを使用することです。異なるバージョンの異なるAddonsをインポートしたり、three.jsライブラリ自体とは異なるバージョンのAddonsを使用したりしないでください。

    互換性について

    diff --git a/docs/manual/ja/introduction/Libraries-and-Plugins.html b/docs/manual/ja/introduction/Libraries-and-Plugins.html index 7b70eec1979dee..56b46372ca780b 100644 --- a/docs/manual/ja/introduction/Libraries-and-Plugins.html +++ b/docs/manual/ja/introduction/Libraries-and-Plugins.html @@ -94,6 +94,7 @@

    Wrappers and Frameworks

  • [link:https://aframe.io/ A-Frame]
  • [link:https://github.com/pmndrs/react-three-fiber react-three-fiber]
  • [link:https://github.com/ecsyjs/ecsy-three ECSY]
  • +
  • [link:https://threlte.xyz/ Threlte]
  • diff --git a/docs/manual/ja/introduction/Loading-3D-models.html b/docs/manual/ja/introduction/Loading-3D-models.html index 19eeab3779c788..300844e02fb154 100644 --- a/docs/manual/ja/introduction/Loading-3D-models.html +++ b/docs/manual/ja/introduction/Loading-3D-models.html @@ -84,7 +84,7 @@

    Loading

    - import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

    diff --git a/docs/manual/ja/introduction/Useful-links.html b/docs/manual/ja/introduction/Useful-links.html index 9d0e6d1ff451cd..45c28e31090c5e 100644 --- a/docs/manual/ja/introduction/Useful-links.html +++ b/docs/manual/ja/introduction/Useful-links.html @@ -55,9 +55,6 @@

    より先進的な内容の記事やコース

  • [Link:https://aerotwist.com/tutorials/ Aerotwist] tutorials by [link:https://github.com/paullewis/ Paul Lewis]. -
  • -
  • - [link:http://learningthreejs.com/ Learning Three.js] – a blog with articles dedicated to teaching three.js
  • [link:https://discourse.threejs.org/t/three-js-bookshelf/2468 Three.js Bookshelf] - Looking for more resources about three.js or computer graphics in general? diff --git a/docs/manual/ko/introduction/How-to-create-VR-content.html b/docs/manual/ko/introduction/How-to-create-VR-content.html index 8b2f8a4abe443a..2534d9d5e19a3e 100644 --- a/docs/manual/ko/introduction/How-to-create-VR-content.html +++ b/docs/manual/ko/introduction/How-to-create-VR-content.html @@ -23,7 +23,7 @@

    작업 순서

    -import { VRButton } from 'three/examples/jsm/webxr/VRButton.js'; +import { VRButton } from 'three/addons/webxr/VRButton.js';

    diff --git a/docs/manual/ko/introduction/How-to-use-post-processing.html b/docs/manual/ko/introduction/How-to-use-post-processing.html index ca3832d0850ce7..6dce9e4b086378 100644 --- a/docs/manual/ko/introduction/How-to-use-post-processing.html +++ b/docs/manual/ko/introduction/How-to-use-post-processing.html @@ -28,9 +28,9 @@

    작업 절차

    - import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'; - import { GlitchPass } from 'three/examples/jsm/postprocessing/GlitchPass.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { GlitchPass } from 'three/addons/postprocessing/GlitchPass.js';

    @@ -92,8 +92,8 @@

    커스텀 방식

    - import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'; - import { LuminosityShader } from 'three/examples/jsm/shaders/LuminosityShader.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { LuminosityShader } from 'three/addons/shaders/LuminosityShader.js'; // later in your init routine diff --git a/docs/manual/ko/introduction/Installation.html b/docs/manual/ko/introduction/Installation.html index 698bd09fa062ed..0feb01f3884355 100644 --- a/docs/manual/ko/introduction/Installation.html +++ b/docs/manual/ko/introduction/Installation.html @@ -77,24 +77,26 @@

    static hosting 및 CDN을 통한 설치

    - <script type="module"> +<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> - // Find the latest version by visiting https://cdn.skypack.dev/three. +<script type="importmap"> + { + "imports": { + "three": "https://unpkg.com/three@<version>/build/three.module.js" + } + } +</script> - import * as THREE from 'https://cdn.skypack.dev/three@<version>'; +<script type="module"> - const scene = new THREE.Scene(); + import * as THREE from 'three'; - </script> - - -

    - 모든 속성들이 build/three.module.js 모듈을 통해 접근하는 것은 아닙니다. 다른 자주 쓰이는 라이브러리들, controls, loaders, post-processing effects 같은 것들은 - [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm] 의 하위폴더에서 불러와야 합니다. 더 자세한 내용을 알아보려면, 아래 예제를 참고하세요. -

    + const scene = new THREE.Scene(); +</script> +
    -

    예제

    +

    Addons

    three.js는 3D 엔진의 주요 컴포넌트들에 초점을 두고 있습니다. 다른 여러 유용한 컴포넌트들 — @@ -110,7 +112,7 @@

    예제

    - import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; const controls = new OrbitControls( camera, renderer.domElement ); @@ -120,16 +122,26 @@

    예제

    - <script type="module"> +<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> - // Find the latest version by visiting https://cdn.skypack.dev/three. +<script type="importmap"> + { + "imports": { + "three": "https://unpkg.com/three@<version>/build/three.module.js", + "three/addons/": "https://unpkg.com/three@<version>/examples/jsm/" + } + } +</script> - import { OrbitControls } from 'https://cdn.skypack.dev/three@<version>/examples/jsm/controls/OrbitControls.js'; +<script type="module"> - const controls = new OrbitControls( camera, renderer.domElement ); + import * as THREE from 'three'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - </script> - + const controls = new OrbitControls( camera, renderer.domElement ); + +</script> +

    모든 파일들의 버전을 동일하게 맞추는것이 무엇보다 중요합니다. 서로 다른 버전에서 import를 하거나, three.js 라이브러리 자체가 아닌 다른 버전의 예제를 사용하지 마세요. diff --git a/docs/manual/ko/introduction/Loading-3D-models.html b/docs/manual/ko/introduction/Loading-3D-models.html index 3dcfc38190bd28..cd410cda7309a6 100644 --- a/docs/manual/ko/introduction/Loading-3D-models.html +++ b/docs/manual/ko/introduction/Loading-3D-models.html @@ -76,7 +76,7 @@

    로딩

    - import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

    diff --git a/docs/manual/ko/introduction/Useful-links.html b/docs/manual/ko/introduction/Useful-links.html index 9cbb0f4949a172..15f0ba3cca801f 100644 --- a/docs/manual/ko/introduction/Useful-links.html +++ b/docs/manual/ko/introduction/Useful-links.html @@ -56,9 +56,6 @@

    심화 확장 기사 및 강의

  • [Link:https://aerotwist.com/tutorials/ Aerotwist] tutorials by [link:https://github.com/paullewis/ Paul Lewis]. -
  • -
  • - [link:http://learningthreejs.com/ Learning Three.js] – a blog with articles dedicated to teaching three.js
  • [link:https://discourse.threejs.org/t/three-js-bookshelf/2468 Three.js Bookshelf] - Looking for more resources about three.js or computer graphics in general? diff --git a/docs/manual/pt-br/buildTools/Testing-with-NPM.html b/docs/manual/pt-br/buildTools/Testing-with-NPM.html new file mode 100644 index 00000000000000..f56e18cf8ebb0d --- /dev/null +++ b/docs/manual/pt-br/buildTools/Testing-with-NPM.html @@ -0,0 +1,255 @@ + + + + + + + + + +

    Testando com NPM

    + +

    + Este artigo mostra como colocar o three.js em um ambiente [link:https://nodejs.org/en/ node.js] para que você + possa executar testes automatizados. Os testes podem ser executados na linha de comando ou por + ferramentas de CI como [link:https://travis-ci.org/ Travis]. +

    + +

    A versão curta

    + +

    + Se você estiver confortável com node e npm, + + $ npm install three --save-dev + + e adicione + + const THREE = require('three'); + + para o seu teste. +

    + +

    Criar um projeto testável do zero

    +

    + Se você não estiver familiarizado com essas ferramentas, aqui está um guia rápido (para linux, o processo de instalação + será um pouco diferente do que usando o Windows, mas os comandos do NPM são idênticos). +

    + +

    Configuração básica

    +
    +
      +
    1. + Instale o [link:https://www.npmjs.org/ npm] e o nodejs. O caminho mais curto normalmente parece algo como + +$ sudo apt-get install -y npm nodejs-legacy +# fix any problems with SSL in the default registry URL +$ npm config set registry http://registry.npmjs.org/ + +
    2. + +
    3. + Crie um novo diretório de projeto + + $ mkdir test-example; cd test-example + +
    4. + +
    5. + Peça ao npm para criar um novo arquivo de projeto para você: + + $ npm init + + e aceite todas as opções default pressionando Enter em todos os prompts. + Isso criará o package.json. +

    6. + +
    7. + Experimente iniciar o recurso de teste com + +$ npm test + + Isso falhará, o que é esperado. + Se você olhar no package.json, a definição do script de teste é + + "test": "echo \"Error: no test specified\" && exit 1" + +
    8. + +
    +
    + +

    Adicionar mocha

    +
    + Vamos usar o [link:https://mochajs.org/mocha]. + +
      +
    1. + Instale o mocha com + +$ npm install mocha --save-dev + + Observe que a pasta node_modules/ é criada e suas dependências aparecem lá. + Observe também que seu package.json foi atualizado: a propriedade devDependencies + é adicionada e atualizada pelo uso de --save-dev. +

    2. + +
    3. + Edite o package.json para usar o mocha para teste. Quando o teste for chamado, queremos apenas executar + o mocha e especificar um relatório detalhado. Por padrão, isso executará qualquer coisa em test/ + (não ter a pasta test/ pode levar a um ERR! no npm, crie-a pelo comando mkdir test) + + "test": "mocha --reporter list" + +
    4. + +
    5. + Reexecute o teste com + + $ npm test + + Isso agora deve correr bem, reportando "0 passing (1ms)" + ou similar. +
    6. + +
    +
    + +

    Adicionar three.js

    +
    +
      +
    1. + Vamos baixar nossa dependência three.js com + +$ npm install three --save-dev + +
        +
      • + Se você precisar de uma versão diferente do three.js, use + + $ npm show three versions + + para listar o que está disponível. Para escolher pelo npm a versão correta, use + + $ npm install three@0.84.0 --save + + (0.84.0 nesse exemplo). --save torna isso uma dependência do projeto, em vez de + dependência dev. Veja os documentos [link:https://docs.npmjs.com/cli/v8/configuring-npm/package-json aqui] para mais informações. +
      • +
      +
    2. + +
    3. + Mocha irá procurar por testes em test/, então vamos executar + + $ mkdir test + +
    4. + +
    5. + Finalmente, precisamos de um teste JS para ser executado. Vamos adicionar um teste simples que verificará que + o objeto three.js está disponível e funcionando. Crie test/verify-three.js contendo: + +const THREE = require('three'); +const assert = require('assert'); + +describe('The THREE object', function() { + it('should have a defined BasicShadowMap constant', function() { + assert.notEqual('undefined', THREE.BasicShadowMap); + }), + + it('should be able to construct a Vector3 with default of x=0', function() { + const vec3 = new THREE.Vector3(); + assert.equal(0, vec3.x); + }) +}) + +
    6. + +
    7. + Finalmente vamos testar novamente com $ npm test. Isso deve executar os testes acima e ter sucesso, + mostrando algo como: + +The THREE object should have a defined BasicShadowMap constant: 0ms +The THREE object should be able to construct a Vector3 with default of x=0: 0ms +2 passing (8ms) + +
    8. +
    +
    + +

    Adicione seu próprio código

    +
    + Você precisa fazer três coisas: + +
      +
    1. + Escreva um teste para o comportamento esperado do seu código e coloque-o em test/. + [link:https://github.com/air/encounter/blob/master/test/Physics-test.js aqui] tem um exemplo de um projeto real. +
    2. + +
    3. + Exporte seu código funcional de forma que o nodejs possa vê-lo, para uso em conjunto com require. + Veja isso [link:https://github.com/air/encounter/blob/master/js/Physics.js aqui]. +
    4. + +
    5. + Requisite seu código no arquivo de teste, da mesma forma que fizemos um require('three') no exemplo acima. +
    6. +
    + +

    + Os itens 2 e 3 variam dependendo de como você gerencia seu código. No exemplo de Physics.js + dado acima, a parte de exportação está bem no final. Atribuímos um objeto a module.exports: +

    + +//============================================================================= +// make available in nodejs +//============================================================================= +if (typeof exports !== 'undefined') +{ + module.exports = Physics; +} + +
    + +

    Lidando com dependências

    +
    +

    + Se você já estiver usando algo como require.js ou browserify, pule esta parte. +

    +

    + Normalmente, um projeto three.js será executado no navegador. O carregamento do módulo é, portanto, feito pelo + navegador, executando um monte de tags de script. Seus arquivos individuais não precisam se preocupar + com dependências. No entanto, em um contexto nodejs, não há index.html vinculando tudo + junto, então você tem que ser explícito. +

    +

    + Se você estiver exportando um módulo que depende de outros arquivos, precisará dizer ao node para carregá-los. + Aqui está uma abordagem: +

    +
      +
    1. + No início do seu módulo, verifique se você está em um ambiente nodejs. +
    2. +
    3. + Em caso afirmativo, declare explicitamente suas dependências. +
    4. +
    5. + Caso contrário, você provavelmente está em um navegador, então não precisa fazer mais nada. +
    6. +
    + Código de exemplo de Physics.js: + +//============================================================================= +// setup for server-side testing +//============================================================================= +if (typeof require === 'function') // test for nodejs environment +{ + const THREE = require('three'); + const MY3 = require('./MY3.js'); +} + +
    + + + diff --git a/docs/manual/pt-br/introduction/Animation-system.html b/docs/manual/pt-br/introduction/Animation-system.html new file mode 100644 index 00000000000000..e837a4c38ad617 --- /dev/null +++ b/docs/manual/pt-br/introduction/Animation-system.html @@ -0,0 +1,149 @@ + + + + + + + + + +

    Sistema de animação

    + +

    Visão geral

    + +

    + + No sistema de animação three.js, você pode animar várias propriedades de seus modelos: + os ossos (bones) de um [page:SkinnedMesh skinned e rigged model], morph targets, + diferentes propriedades de material + (cores, opacidade, booleanos), visibilidade e transformações. As propriedades animadas podem ser utilizadas com fade in, + fade out, crossfaded e warped. As escalas de peso e tempo de diferentes + animações no mesmo objeto, bem como em objetos diferentes, podem ser alteradas + independentemente. Várias animações no mesmo objeto e em objetos diferentes podem ser + sincronizadas.

    + + Para conseguir tudo isso em um sistema homogêneo, o sistema de animação three.js + [link:https://github.com/mrdoob/three.js/issues/6881 mudou completamente em 2015] + (cuidado com informações desatualizadas!), e agora tem uma arquitetura semelhante à + Unity/Unreal Engine 4. Esta página fornece uma breve visão geral dos principais componentes do + sistema e como eles trabalham juntos. + +

    + +

    Clipes de animação (Animation Clips)

    + +

    + + Se você importou com sucesso um objeto 3D animado (não importa se + bones ou morph targets ou ambos) — por exemplo, exportando-o do Blender com o + [link:https://github.com/KhronosGroup/glTF-Blender-IO glTF Blender] e + carregando-o em uma cena three.js usando [page:GLTFLoader] — um dos campos da resposta + deve ser um array chamado "animations", contendo o [page:AnimationClip AnimationClips] + para este modelo (veja uma lista de carregadores possíveis abaixo).

    + + Cada `AnimationClip` geralmente contém os dados de uma determinada atividade do objeto. Se o + mesh é um personagem, por exemplo, pode haver um AnimationClip para caminhar, um segundo + para salto, um terceiro para contornar e assim por diante. + +

    + +

    Keyframe Tracks

    + +

    + + Dentro de tal 'AnimationClip' os dados para cada propriedade animada são armazenados em um + [page:KeyframeTrack] separado. Supondo que um objeto de personagem tenha um [page:Skeleton esqueleto] (skeleton), + uma keyframe track pode armazenar os dados para as mudanças de posição do osso do antebraço + ao longo do tempo, uma faixa diferente dos dados para as mudanças de rotação do mesmo osso, uma terceira + a posição da pista, rotação ou dimensionamento de outro osso, e assim por diante. Deve ficar claro, + que um AnimationClip pode ser composto de muitas dessas tracks.

    + + Supondo que o modelo tenha morph targets (por exemplo, um + morph target mostrando um rosto amigável e outro mostrando um rosto irritado), cada track contém as + informações sobre como a [page:Mesh.morphTargetInfluences influence] de um certo morph target + muda durante a execução do clipe. + +

    + +

    Animation Mixer

    + +

    + + Os dados armazenados formam apenas a base para as animações - a reprodução real é controlada pelo + [page:AnimationMixer]. Você pode imaginar isso não apenas como um player de animações, mas + como uma simulação de um hardware como um mixer real, que pode controlar várias animações + simultaneamente, misturando-os e fundindo-os. + +

    + +

    Ações de animação (Animation Actions)

    + +

    + + O próprio `AnimationMixer` tem muito poucas propriedades e métodos (gerais), porque + pode ser controlado por [page:AnimationAction AnimationActions]. Ao configurar um + `AnimationAction` você pode determinar quando um certo `AnimationClip` deve ser reproduzido, pausado + ou parado em um dos mixers, se e com que frequência o clipe deve ser repetido, seja + executado com um fade ou uma escala de tempo, e algumas coisas adicionais, como crossfading + ou sincronização. + +

    + +

    Animação de Grupos de Objetos

    + +

    + + Se você quiser que um grupo de objetos receba um estado de animação compartilhado, você pode usar um + [page:AnimationObjectGroup]. + +

    + +

    Formatos e Loaders suportados

    + +

    + Observe que nem todos os formatos de modelo incluem animação (notadamente o OBJ não inclui), e que apenas alguns + loaders do three.js suportam sequências [page:AnimationClip AnimationClip]. Vários que tem + suporte para este tipo de animação: +

    + +
      +
    • [page:ObjectLoader THREE.ObjectLoader]
    • +
    • THREE.BVHLoader
    • +
    • THREE.ColladaLoader
    • +
    • THREE.FBXLoader
    • +
    • [page:GLTFLoader THREE.GLTFLoader]
    • +
    • THREE.MMDLoader
    • +
    + +

    + Observe que o 3ds max e o Maya atualmente não podem exportar várias animações (ou seja, animações que não estão + na mesma linha do tempo) diretamente para um único arquivo. +

    + +

    Exemplo

    + + + let mesh; + + // Create an AnimationMixer, and get the list of AnimationClip instances + const mixer = new THREE.AnimationMixer( mesh ); + const clips = mesh.animations; + + // Update the mixer on each frame + function update () { + mixer.update( deltaSeconds ); + } + + // Play a specific animation + const clip = THREE.AnimationClip.findByName( clips, 'dance' ); + const action = mixer.clipAction( clip ); + action.play(); + + // Play all animations + clips.forEach( function ( clip ) { + mixer.clipAction( clip ).play(); + } ); + + + + diff --git a/docs/manual/pt-br/introduction/Color-management.html b/docs/manual/pt-br/introduction/Color-management.html new file mode 100644 index 00000000000000..0136889d79fb8a --- /dev/null +++ b/docs/manual/pt-br/introduction/Color-management.html @@ -0,0 +1,329 @@ + + + + + + + + + + + + +

    Gerenciamento de cor

    + +

    O que é um espaço de cor?

    + +

    + Cada espaço de cor é uma coleção de várias decisões de design, escolhidas em conjunto para dar suporte a uma + grande variedade de cores, satisfazendo as restrições técnicas relacionadas à precisão e a tecnologia das telas. Ao criar um recurso 3D ou ao montar recursos 3D em uma cena, é + importante saber quais são essas propriedades e como as propriedades de um espaço de cores se relacionam + com outros espaços de cor na cena. +

    + +
    + +
    + Cores sRGB e ponto branco (D65) exibidos no diagrama de referência cromaticidade CIE 1931. + A região colorida representa uma projeção 2D da gama sRGB, que é um volume 3D. + Fonte: Wikipedia +
    +
    + +
      +
    • + + Cores primárias: As cores primárias (por exemplo, vermelho, verde, azul) não são absolutas; elas são + selecionadas a partir do espectro visível com base em restrições de precisão limitada e + capacidades dos dispositivos de exibição disponíveis. As cores são expressas como uma proporção das cores primárias. +
    • +
    • + Ponto branco: a maioria dos espaços de cores é projetada de forma que uma soma igualmente ponderada das + primárias R = G = B parecerão sem cor, ou "acromáticas". A aparência + de valores acromáticos (como branco ou cinza) dependem da percepção humana, que por sua vez depende + fortemente no contexto do observador. Um espaço de cor especifica seu "ponto branco" para equilibrar + essas necessidades. O ponto branco definido pelo espaço de cores sRGB é + D65. +
    • +
    • + Transfer functions: depois de escolher a gama de cores e um modelo de cores, ainda precisamos + definir mapeamentos ("transfer functions") de valores numéricos para o espaço de cores. r = 0,5 + representa 50% menos iluminação física do que r = 1.0? Ou 50% menos brilhante, conforme percebido + por um olho humano médio? São coisas diferentes, e essa diferença pode ser representada como + uma função matemática. As transfer functions podem ser lineares ou não lineares, dependendo + dos objetivos do espaço de cores. sRGB define transfer functions não lineares. Aquelas + funções são às vezes aproximadas como funções gamma, mas o termo "gamma" é + ambíguo e deve ser evitado neste contexto. +
    • +
    + + Esses três parâmetros — cores primárias, ponto branco e transfer functions — definem um espaço de cores, + cada um escolhido para objetivos particulares. Tendo definido os parâmetros, alguns termos adicionais + são úteis: + +
      +
    • + Modelo de cores: Sintaxe para identificar numericamente as cores dentro da gama de cores escolhida — + um sistema de coordenadas para cores. No three.js estamos preocupados principalmente com o modelo de cor RGB, + tendo três coordenadas r, g, b ∈ [0,1] ("domínio fechado") ou + r, g, b ∈ [0,∞] ("domínio aberto"), cada um representando uma fração de uma cor primária. + Outros modelos de cores (HSL, Lab, LCH) são comumente usados ​​para controle artístico. +
    • +
    • + Gama de cores: uma vez que as cores primárias e um ponto branco tenham sido escolhidos, eles representam + um volume dentro do espectro visível (uma "gama"). Cores fora deste volume ("fora da gama") + não podem ser expressas por valores RGB de domínio fechado [0,1]. No domínio aberto [0,∞], a gama é + tecnicamente infinita. +
    • +
    + +

    + Considere dois espaços de cores muito comuns: [page:SRGBColorSpace] ("sRGB") e + [page:LinearSRGBColorSpace] ("Linear-sRGB"). Ambos usam as mesmas cores primárias e ponto branco, + e, portanto, têm a mesma gama de cores. Ambos usam o modelo de cores RGB. Eles diferem apenas + nas transfer functions — Linear-sRGB é linear em relação à intensidade da luz física. + sRGB usa as transfer functions sRGB não lineares e se assemelha mais à maneira que + o olho humano percebe a luz e a capacidade de resposta de dispositivos de exibição comuns. +

    + +

    + Essa diferença é importante. Cálculos de iluminação e outras operações de renderização devem + geralmente ocorrem em um espaço de cores linear. No entanto, cores lineares são menos eficientes para + armazenar em uma imagem ou framebuffer e não parecem corretas quando vistas por um observador humano. + Como resultado, as texturas de entrada e a imagem final renderizada geralmente usarão o método não linear + do espaço de cores sRGB. +

    + +
    +

    + ℹ️ AVISO: Embora alguns monitores modernos sejam compatíveis com gamas mais amplas, como Display-P3, + as APIs gráficas da plataforma web dependem em grande parte do sRGB. Aplicativos que usam three.js + hoje normalmente usarão apenas os espaços de cores sRGB e Linear-sRGB. +

    +
    + +

    Atribuições dos espaços de cores

    + +

    + Fluxos de trabalho lineares - necessários para métodos modernos de renderização - geralmente envolvem mais de + um espaço de cores, cada um atribuído a uma função específica. Espaços de cores lineares e não lineares são + apropriados para diferentes funções, como explicado abaixo. +

    + +

    Input do espaço de cores

    + +

    + Cores fornecidas ao three.js — de seletores de cores, texturas, modelos 3D e outras fontes — + cada um tem um espaço de cor associado. Aqueles que ainda não estão na cor de trabalho Linear-sRGB, + devem ser convertidos e as texturas devem receber a atribuição texture.encoding correta. + Certas conversões (para cores hexadecimais e CSS em sRGB) podem ser feitas automaticamente se + o modo de gerenciamento de cores herdado é desabilitado antes de inicializar as cores: +

    + + +THREE.ColorManagement.legacyMode = false; + + +
      +
    • + Materiais, luzes e shaders: cores nos materiais, luzes e shaders armazenam + componentes RGB no espaço de cores de trabalho Linear-sRGB. +
    • +
    • + Cores de vértices: [page:BufferAttribute BufferAttributes] armazena componentes RGB no + Espaço de cores de trabalho linear-sRGB. +
    • +
    • + Texturas de cores: PNG ou JPEG [page:Texture Textures] contendo informações de cores + (como .map ou .emissiveMap) usam o espaço de cores sRGB de domínio fechado e devem ser anotados com + texture.encoding = sRGBEncoding. Formatos como OpenEXR (às vezes usado para .envMap ou + .lightMap) usam o espaço de cores Linear-sRGB indicado com texture.encoding = LinearEncoding, + e podem conter valores no domínio aberto [0,∞]. +
    • +
    • + Texturas não coloridas: Texturas que não armazenam informações de cores (como .normalMap + ou .roughnessMap) não têm um espaço de cores associado e geralmente usam a textura (padrão) + como texture.encoding = LinearEncoding. Em casos raros, dados sem cor + podem ser representados com outras codificações não lineares por motivos técnicos. +
    • +
    + +
    +

    + ⚠️ AVISO: Muitos formatos para modelos 3D não funcionam de forma correta ou consistente + na definição das informações do espaço de cores. Enquanto o three.js tenta lidar com a maioria dos casos, problemas + são comuns com formatos de arquivo mais antigos. Para melhores resultados, use glTF 2.0 ([page:GLTFLoader]) + e teste modelos 3D em visualizadores on-line antecipadamente para confirmar que o recurso em si está correto. +

    +
    + +

    Espaço de cores de trabalho

    + +

    + Renderização, interpolação e muitas outras operações devem ser executadas em um domínio aberto + do espaço de cores de trabalho linear, no qual os componentes RGB são proporcionais a iluminação + física. No three.js, o espaço de cores de trabalho é Linear-sRGB. +

    + +

    Output do espaço de cores

    + +

    + A saída para um dispositivo de exibição, imagem ou vídeo pode envolver a conversão do domínio aberto + do espaço de cores de trabalho linear-sRGB para outro espaço de cores. Essa conversão pode ser feita em + uma passagem de renderização principal ([page:WebGLRenderer.outputEncoding]), ou durante o pós-processamento. +

    + + +renderer.outputEncoding = THREE.sRGBEncoding; // optional with post-processing + + +
      +
    • + Tela: as cores gravadas em um canvas WebGL para exibição devem estar no espaço sRGB + colorido. +
    • +
    • + Imagem: as cores gravadas em uma imagem devem usar o espaço de cores apropriado para + o formato e o uso. Imagens totalmente renderizadas gravadas em texturas PNG ou JPEG geralmente + usam o espaço de cores sRGB. Imagens contendo emissão, mapas de luz ou outros dados não + confinados ao intervalo [0,1] geralmente usarão o espaço de cores Linear-sRGB de domínio aberto, + e um formato de imagem compatível como OpenEXR. +
    • +
    + +
    +

    + ⚠️ AVISO: + Os render targets podem usar sRGB ou Linear-sRGB. sRGB faz + melhor uso de precisão limitada. No domínio fechado, 8 bits geralmente são suficientes para sRGB + enquanto que ≥12 bits (meio flutuante) podem ser necessários para Linear-sRGB. Se mais tarde + os estágios pipeline precisarem de entrada Linear-sRGB, as conversões adicionais podem ter um pequeno + custo de desempenho. +

    +
    + +

    Trabalhando com instâncias THREE.Color

    + +

    + Métodos de leitura ou modificação de instâncias [page:Color] assumem que os dados já estão no + espaço de cores de trabalho three.js, Linear-sRGB. Os componentes RGB e HSL são + representações diretas de dados armazenados pela instância Color e nunca são convertidos + implicitamente. Os dados de cores podem ser convertidos explicitamente com .convertLinearToSRGB() + ou .convertSRGBToLinear(). +

    + + + // RGB components (no change). + color.r = color.g = color.b = 0.5; + console.log( color.r ); // → 0.5 + + // Manual conversion. + color.r = 0.5; + color.convertSRGBToLinear(); + console.log( color.r ); // → 0.214041140 + + +

    + Com ColorManagement.legacyMode = false definido (recomendado), determinadas conversões + são feitas automaticamente. Como as cores hexadecimais e CSS geralmente são sRGB, métodos [page:Color] + irão converter automaticamente essas entradas de sRGB para Linear-sRGB em setters, ou + converter de Linear-sRGB para sRGB ao retornar hexadecimal ou CSS de getters. +

    + + + // Hexadecimal conversion. + color.setHex( 0x808080 ); + console.log( color.r ); // → 0.214041140 + console.log( color.getHex() ); // → 0x808080 + + // CSS conversion. + color.setStyle( 'rgb( 0.5, 0.5, 0.5 )' ); + console.log( color.r ); // → 0.214041140 + + // Override conversion with 'colorSpace' argument. + color.setHex( 0x808080, LinearSRGBColorSpace ); + console.log( color.r ); // → 0.5 + console.log( color.getHex( LinearSRGBColorSpace ) ); // → 0x808080 + console.log( color.getHex( SRGBColorSpace ) ); // → 0xBCBCBC + + +

    Erros comuns

    + +

    + Quando uma cor ou textura individual é configurada incorretamente, ela aparecerá mais escura ou mais clara do que + esperado. Quando o espaço de cores de saída do renderizador está mal configurado, a cena inteira pode aparecer + mais escura (por exemplo, conversão ausente para sRGB) ou mais clara (por exemplo, uma conversão dupla para sRGB com + pós-processamento). Em cada caso, o problema pode não ser uniforme e simplesmente aumentar/diminuir + a iluminação não resolve. +

    + +

    + Um problema mais sutil aparece quando ambos os espaços de cores de entrada e saída + estão incorretos — os níveis gerais de brilho podem ser bons, mas as cores podem mudar + inesperadamente sob iluminação diferente, ou o sombreamento pode parecer mais estourado e menos suave + do que o pretendido. Esses dois erros não fazem um acerto, e é importante que o trabalho + espaço de cores funcional seja linear ("cena referida") e o espaço de cores de saída seja não linear + ("exibição referida"). +

    + +

    Leitura adicional

    + + + + + + diff --git a/docs/manual/pt-br/introduction/Creating-a-scene.html b/docs/manual/pt-br/introduction/Creating-a-scene.html new file mode 100644 index 00000000000000..50b128dc98d4dd --- /dev/null +++ b/docs/manual/pt-br/introduction/Creating-a-scene.html @@ -0,0 +1,165 @@ + + + + + + + + + +

    Criando uma cena

    + +

    O objetivo dessa seção é dar uma breve introdução ao three.js. Nós iremos começar configurando uma cena (scene) com um cubo giratório. Um exemplo é apresentado no final dessa página, caso você precise de ajuda.

    + +

    Antes de começar

    + +

    Antes de começar usar o three.js, você precisa de algum lugar para mostrá-lo. Salve o HTML abaixo em um arquivo no seu computador, junto com uma cópia do [link:https://threejs.org/build/three.js three.js] na pasta js/, e abra o arquivo no navegador.

    + + + <!DOCTYPE html> + <html> + <head> + <meta charset="utf-8"> + <title>My first three.js app</title> + <style> + body { margin: 0; } + </style> + </head> + <body> + <script src="js/three.js"></script> + <script> + // Our Javascript will go here. + </script> + </body> + </html> + + +

    Isso é tudo. Todo o código abaixo vai dentro da tag <script> vazia.

    + +

    Criando a cena

    + +

    Para realmente ser capaz de exibir algum conteúdo com o three.js, nós precisamos de três coisas: cena (scene), câmera (camera) e renderizador (renderer), para que possamos então renderizar a cena com a câmera. +

    + + + const scene = new THREE.Scene(); + const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); + + const renderer = new THREE.WebGLRenderer(); + renderer.setSize( window.innerWidth, window.innerHeight ); + document.body.appendChild( renderer.domElement ); + + +

    Vamos tirar um momento para explicar o que está acontecendo aqui. Nós temos agora configurados a cena, nossa câmera e o renderizador.

    + +

    Existem alguns diferentes tipos de câmera no three.js. Por enquanto usaremos a `PerspectiveCamera`.

    + +

    O primeiro atributo é o `field of view`. FOV é a extensão da cena que é vista na tela em um dado momento. O valor está em graus.

    + +

    O segundo atributo é o `aspect ratio`. Você quase sempre irá usar o comprimento do elemento dividido pela sua altura, ou você terá o mesmo resultado de quando reproduz filmes antigos em uma TV widescreen - a imagem parece esmagada.

    + +

    Os próximos dois atributos são os planos de corte `near` e `far`. Isso significa que os objetos mais distantes da câmera do que o valor `far` ou mais próximos que o valor `near` não serão renderizados. Você não precisa se preocupar com isso agora, mas pode ser necessário usar outros valores em seus apps para obter uma melhor performance.

    + +

    Em seguida temos o renderizador. É aqui que a mágica acontece. Além do WebGLRenderer que usamos aqui, three.js vem com alguns outros, frequentemente usados como substitutos para usuários com navegadores antigos ou para aqueles que não possuem suporte para WebGL por algum motivo.

    + +

    Além da criação da intância do renderizador, nós também precisamos configurar o tamanho em que queremos renderizar nossa aplicação. É uma boa ideia usar o comprimento e a altura da área que queremos preencher com nossa aplicação - no nosso caso, o comprimento e altura da janela do navegador. Para aplicativos de alto desempenho, você pode fornecer valores menores para o `setSize`, como `window.innerWidth/2` e `window.innerHeight/2`, o que fará com que a aplicação seja renderizada no tamanho de um quarto do original.

    + +

    Se você deseja manter o tamanho do seu aplicativo mas renderizá-lo em uma resolução mais baixa, você pode chamar o `setSize` passando false como `updateStyle` (o terceiro argumento). Por exemplo, `setSize(window.innerWidth/2, window.innerHeight/2, false)` irá renderizar sua aplicação na metade da resolução, já que seu elemento <canvas> tem 100% de comprimento e altura.

    + +

    Por último mas não menos importante, nós adicionamos o elemento `renderer` ao nosso HTML. Este é o elemento <canvas> que o renderizador usa para exibir a cena para nós.

    + +

    "Tudo bem, mas onde está aquele cubo que você prometeu?". Vamos adicioná-lo agora.

    + + + const geometry = new THREE.BoxGeometry( 1, 1, 1 ); + const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); + const cube = new THREE.Mesh( geometry, material ); + scene.add( cube ); + + camera.position.z = 5; + + +

    Para criar um cubo, nós precisamos de um `BoxGeometry`. Este é um objeto que contém todos os pontos (`vertices`) e preenchimento (`faces`) do cubo. Nós vamos explorar mais sobre isso no futuro.

    + +

    Além da geometria, nós precisamos de um material para colorir. Three.js vem com vários materiais, mas vamos nos ater ao `MeshBasicMaterial` por enquanto. Todos os materiais têm um objeto de propriedades que serão aplicadas a eles. Para manter as coisas simples, forneceremos apenas um atributo de cor `0x00ff00`, que é verde. Isso funciona da mesma maneira que as cores no CSS ou no Photoshop (`hex colors`).

    + +

    A terceira coisa que precisamos é de um `Mesh`. Um mesh é um objeto que pega a geometria e aplica um material a ela, para que então possamos inseri-lo em nossa cena e move-lo livremente.

    + +

    Por padrão, quando nós chamamos `scene.add()`, o elemento que queremos adicionar será inserido nas coordenadas `(0,0,0)`. Isso faz com que a câmera e o cubo fiquem um dentro do outro. Para evitar isso, simplesmente movemos a câmera um pouco para fora.

    + +

    Renderizando a cena

    + +

    Se você copiou o código acima para o arquivo HTML criado anteriormente, você não será capaz de ver nada. Isso acontece porque ainda não estamos renderizando nada. Para isso, precisamos chamar um `render ou animate loop`.

    + + + function animate() { + requestAnimationFrame( animate ); + renderer.render( scene, camera ); + } + animate(); + + +

    Isso criará um loop que fará com que o renderizador desenhe a cena novamente toda vez que a tela for atualizada (em uma tela típica, isso significa 60 vezes por segundo). Se você é novato em escrever jogos no navegador, pode perguntar "por que não criamos um setInterval?". A questão é - nós poderíamos, mas `requestAnimationFrame` tem várias vantagens. Talvez a mais importante seja que ele pausa quando o usuário navega para outra aba do navegador, portanto, não desperdiçando seu precioso poder de processamento e vida útil da bateria.

    + +

    Animando o cubo

    + +

    Se você inseriu todo o código acima no arquivo que criamos no início, deve visualizar uma caixa verde. Vamos deixar isso tudo um pouco mais interessante rotacionando o cubo. +

    + +

    Adicione o seguinte trecho logo acima da chamada `renderer.render` na função `animate`:

    + + + cube.rotation.x += 0.01; + cube.rotation.y += 0.01; + + +

    Isso será executado a cada quadro (normalmento 60 vezes por segundo), e dará ao cubo uma boa animação de rotação. Basicamente, quaquer coisa que você queira mover ou alterar enquanto a aplicação está sendo executada tem que passar pelo loop de animação. É claro que você pode chamar outras funções de lá para que não acabe com uma função `animate` com centenas de linhas.

    + +

    O resultado

    +

    Parabéns! Agora você concluiu seu primeiro aplicativo three.js. É simples, mas você tem que começar de algum lugar.

    + +

    O código completo está disponível abaixo e como um [link:https://jsfiddle.net/fxurzeb4/ exemplo] editável. Brinque com ele para entender melhor como funciona.

    + + + <!DOCTYPE html> + <html> + <head> + <meta charset="utf-8"> + <title>My first three.js app</title> + <style> + body { margin: 0; } + </style> + </head> + <body> + <script src="js/three.js"></script> + <script> + const scene = new THREE.Scene(); + const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); + + const renderer = new THREE.WebGLRenderer(); + renderer.setSize( window.innerWidth, window.innerHeight ); + document.body.appendChild( renderer.domElement ); + + const geometry = new THREE.BoxGeometry( 1, 1, 1 ); + const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); + const cube = new THREE.Mesh( geometry, material ); + scene.add( cube ); + + camera.position.z = 5; + + function animate() { + requestAnimationFrame( animate ); + + cube.rotation.x += 0.01; + cube.rotation.y += 0.01; + + renderer.render( scene, camera ); + }; + + animate(); + </script> + </body> + </html> + + + diff --git a/docs/manual/pt-br/introduction/Creating-text.html b/docs/manual/pt-br/introduction/Creating-text.html new file mode 100644 index 00000000000000..406025631b4e4f --- /dev/null +++ b/docs/manual/pt-br/introduction/Creating-text.html @@ -0,0 +1,144 @@ + + + + + + + + + +

    Criando texto

    +
    +

    + Muitas vezes, você pode precisar usar texto em sua aplicação three.js - aqui estão algumas maneiras de fazer isso. +

    +
    + +

    1. DOM + CSS

    +
    +

    + Usar HTML geralmente é a maneira mais fácil e rápida de adicionar texto. Este é o método + usado para sobreposições descritivas na maioria dos exemplos three.js. +

    +

    Você pode adicionar conteúdo para uma

    + <div id="info">Description</div> + +

    + e usar marcação CSS para posicionar absolutamente em uma posição acima de todas as outras com um + z-index, especialmente se você estiver executando o three.js em tela cheia. +

    + + +#info { + position: absolute; + top: 10px; + width: 100%; + text-align: center; + z-index: 100; + display:block; +} + + +
    + + +

    2. Usar [page:CSS2DRenderer] ou [page:CSS3DRenderer]

    +
    +

    + Use esses renderizadores para desenhar texto de alta qualidade contido em elementos DOM para sua cena three.js. + Isso é semelhante ao item 1. exceto que esses elementos de renderização podem ser integrados + mais firmemente e dinamicamente na cena. +

    +
    + + +

    3. Desenhe texto na tela e use como [page:Texture]

    +
    +

    + Use este método se deseja desenhar texto facilmente em um plano na sua cena three.js. +

    +
    + + +

    4. Crie um modelo em seu aplicativo 3D favorito e exporte para three.js

    +
    +

    Use este método se preferir trabalhar com seus aplicativos 3D e importar os modelos para o three.js.

    +
    + + +

    5. Geometria de Texto Procedural

    +
    +

    + Se você preferir trabalhar puramente em THREE.js ou criar geometrias de texto 3D + procedurais e dinâmicas, você pode criar um mesh cuja geometria é uma instância de THREE.TextGeometry: +

    +

    + new THREE.TextGeometry( text, parameters ); +

    +

    + Para que isso funcione, no entanto, seu TextGeometry precisará de uma instância de THREE.Font + para ser definido em seu parâmetro "fonte". + + Veja a página [page:TextGeometry] para mais informações sobre como isso pode ser feito, descrição de cada + um dos parâmetros aceitos e uma lista das fontes JSON que vêm com a própria distribuição THREE.js. +

    + +

    Exemplos

    + +

    + [example:webgl_geometry_text WebGL / geometry / text]
    + [example:webgl_shadowmap WebGL / shadowmap] +

    + +

    + Se o Typeface estiver desativado ou você quiser usar uma fonte que não está lá, há um tutorial + com um script python para blender que permite exportar texto para o formato JSON do Three.js: + [link:http://www.jaanga.com/2012/03/blender-to-threejs-create-3d-text-with.html] +

    + +
    + + +

    6. Fontes Bitmap

    +
    +

    + BMFonts (fontes Bitmap) permitem agrupar glifos em um único BufferGeometry. A renderização do + BMFont suporta quebra de palavras, espaçamento entre letras, kerning, campos de distância assinados com padrão + derivados, campos de distância com sinal multicanal, fontes com várias texturas e muito mais. + Veja [link:https://github.com/felixmariotto/three-mesh-ui three-mesh-ui] ou [link:https://github.com/Jam3/three-bmfont-text three-bmfont-text]. +

    +

    + As Stock Fonts estão disponíveis em projetos como + [link:https://github.com/etiennepinchon/aframe-fonts A-Frame Fonts], ou você pode criar o seu próprio + de qualquer fonte .TTF, otimizando para incluir apenas os caracteres necessários para um projeto. +

    +

    + Algumas ferramentas úteis: +

    +
      +
    • [link:http://msdf-bmfont.donmccurdy.com/ msdf-bmfont-web] (web)
    • +
    • [link:https://github.com/soimy/msdf-bmfont-xml msdf-bmfont-xml] (linha de comando)
    • +
    • [link:https://github.com/libgdx/libgdx/wiki/Hiero hiero] (desktop)
    • +
    +
    + + +

    7. Troika Text

    +
    +

    + O pacote [link:https://www.npmjs.com/package/troika-three-text troika-three-text] renderiza + texto com suavização de qualidade usando uma técnica semelhante ao BMFonts, mas funciona diretamente com qualquer + arquivo de fonte .TTF ou .WOFF, para que você não precise pré-gerar uma textura de glifo offline. Também adiciona + capacidades incluindo: +

    +
      +
    • Efeitos como traços, sombras e curvatura
    • +
    • A capacidade de aplicar qualquer material three.js, até mesmo um ShaderMaterial personalizado
    • +
    • Suporte para ligaduras de fonte, scripts com letras unidas e layout da direita para a esquerda/bidirecional
    • +
    • Otimização para grandes quantidades de texto dinâmico, realizando a maior parte do trabalho fora da thread principal em um web worker
    • +
    +
    + + + + diff --git a/docs/manual/pt-br/introduction/Drawing-lines.html b/docs/manual/pt-br/introduction/Drawing-lines.html new file mode 100644 index 00000000000000..578ad018008aab --- /dev/null +++ b/docs/manual/pt-br/introduction/Drawing-lines.html @@ -0,0 +1,83 @@ + + + + + + + + + +

    Desenhando linhas

    +
    +

    + Digamos que você queira desenhar uma linha ou um círculo, não um wireframe [page:Mesh]. + Primeiro precisamos configurar o [page:WebGLRenderer renderizador] (renderer), a [page:Scene cena] (scene) e + a câmera (camera) (veja a página Criando uma cena). +

    + +

    + Aqui está o código que vamos usar: +

    + +const renderer = new THREE.WebGLRenderer(); +renderer.setSize( window.innerWidth, window.innerHeight ); +document.body.appendChild( renderer.domElement ); + +const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 500 ); +camera.position.set( 0, 0, 100 ); +camera.lookAt( 0, 0, 0 ); + +const scene = new THREE.Scene(); + + +

    + A próxima coisa que vamos fazer é definir um material. + Para linhas nós temos que usar [page:LineBasicMaterial] ou [page:LineDashedMaterial]. +

    + + +//create a blue LineBasicMaterial +const material = new THREE.LineBasicMaterial( { color: 0x0000ff } ); + + +

    + Depois do material, nós vamos precisar de uma geometria com alguns vértices: +

    + + +const points = []; +points.push( new THREE.Vector3( - 10, 0, 0 ) ); +points.push( new THREE.Vector3( 0, 10, 0 ) ); +points.push( new THREE.Vector3( 10, 0, 0 ) ); + +const geometry = new THREE.BufferGeometry().setFromPoints( points ); + + +

    + Note que linhas são desenhadas entre cada par consecutivo de vértices, + mas não entre o primeiro e o último (a linha não é fechada). +

    + +

    + Agora que nós temos os pontos para duas linhas e um material, + podemos juntar tudo e formar uma linha +

    + +const line = new THREE.Line( geometry, material ); + + +

    + Tudo o que falta é adicioná-la na cena e chamar o [page:WebGLRenderer.render renderizador]. +

    + + +scene.add( line ); +renderer.render( scene, camera ); + + +

    + Agora você deve estar vendo uma seta apontando para cima, feita de duas linhas azuis. +

    +
    + + diff --git a/docs/manual/pt-br/introduction/FAQ.html b/docs/manual/pt-br/introduction/FAQ.html new file mode 100644 index 00000000000000..7a453f6b9505f7 --- /dev/null +++ b/docs/manual/pt-br/introduction/FAQ.html @@ -0,0 +1,75 @@ + + + + + + + + + +

    FAQ

    + +

    Qual formato de modelo 3D é melhor suportado?

    +
    +

    + O formato recomendado para importar e exportar recursos é + o glTF (GL Transmission Format). Isso porque o glTF é focado na entrega de recursos em + tempo de execução, é compacto para transmitir e rápido para carregar. +

    +

    + O three.js também fornece loaders para muitos outros formatos populares como FBX, Collada ou OBJ. + No entanto, primeiro você deve sempre tentar estabelecer um fluxo de trabalho baseado em glTF em seus projetos. + Para obter mais informações, consulte [link:#manual/introduction/Loading-3D-models Carregando modelos 3D]. +

    +
    + +

    Por que existem meta tags de viewport nos exemplos?

    +
    + <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> + +

    + Essas tags controlam o tamanho e a escala da janela de visualização para navegadores móveis + (onde o conteúdo da página pode ser renderizado em tamanho diferente da janela de visualização visível). +

    + +

    [link:https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html Safari: Using the Viewport]

    + +

    [link:https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag MDN: Using the viewport meta tag]

    +
    + +

    Como a escala da cena pode ser preservada no redimensionamento?

    +

    + Queremos que todos os objetos, independentemente da sua distância da câmera, apareçam do mesmo tamanho, + mesmo que a janela seja redimensionada. + + A equação chave para resolver isso é esta fórmula para a altura visível dada uma determinada distância da câmera: + + +visible_height = 2 * Math.tan( ( Math.PI / 180 ) * camera.fov / 2 ) * distance_from_camera; + + Se aumentarmos a altura da janela por uma certa porcentagem, o que queremos é que a altura visível em todas as distâncias + aumentem na mesma porcentagem. + + Isso não pode ser feito alterando a posição da câmera. Em vez disso, você tem que mudar + o campo de visão da câmera (FOV). + [link:http://jsfiddle.net/Q4Jpu/ Exemplo]. +

    + +

    Por que parte do meu objeto está invisível?

    +

    + Isso pode acontecer por causa do corte de faces. As faces têm uma orientação que decide qual lado + é qual. E o corte remove a parte traseira em circunstâncias normais. + Para verificar se este é o seu problema, altere o lado do material para THREE.DoubleSide. + + material.side = THREE.DoubleSide +

    + +

    + Por que o three.js às vezes retorna resultados estranhos para entradas inválidas? +

    +

    + Por motivos de desempenho, o three.js não valida entradas na maioria dos casos. + É responsabilidade do seu aplicativo garantir que todas as entradas sejam válidas. +

    + + diff --git a/docs/manual/pt-br/introduction/How-to-create-VR-content.html b/docs/manual/pt-br/introduction/How-to-create-VR-content.html new file mode 100644 index 00000000000000..1fe33be277a179 --- /dev/null +++ b/docs/manual/pt-br/introduction/How-to-create-VR-content.html @@ -0,0 +1,81 @@ + + + + + + + + + + + +

    Como criar conteúdo de VR

    + +

    + Este guia fornece uma breve visão geral dos componentes básicos de uma aplicação de VR baseada na web + feita com three.js. +

    + +

    Workflow

    + +

    + Primeiro, você deve incluir [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/webxr/VRButton.js VRButton.js] + em seu projeto. +

    + + +import { VRButton } from 'three/addons/webxr/VRButton.js'; + + +

    + *VRButton.createButton()* faz duas coisas importantes: Cria um botão que indica + compatibilidade com VR. Além disso, inicia uma sessão de VR se o usuário ativar o botão. A única coisa que você tem + fazer é adicionar a seguinte linha de código ao seu aplicativo. +

    + + +document.body.appendChild( VRButton.createButton( renderer ) ); + + +

    + Em seguida, você deve informar sua instância do `WebGLRenderer` para habilitar a renderização XR. +

    + + +renderer.xr.enabled = true; + + +

    + Finalmente, você precisa ajustar seu loop de animação, pois não podemos usar nossa conhecida função + *window.requestAnimationFrame()*. Para projetos de VR usamos [page:WebGLRenderer.setAnimationLoop setAnimationLoop]. + O código mínimo fica assim: +

    + + +renderer.setAnimationLoop( function () { + + renderer.render( scene, camera ); + +} ); + + +

    Próximos Passos

    + +

    + Dê uma olhada em um dos exemplos oficiais de WebVR para ver esse workflow em ação

    + + [example:webxr_vr_ballshooter WebXR / VR / ballshooter]
    + [example:webxr_vr_cubes WebXR / VR / cubes]
    + [example:webxr_vr_dragging WebXR / VR / dragging]
    + [example:webxr_vr_paint WebXR / VR / paint]
    + [example:webxr_vr_panorama_depth WebXR / VR / panorama_depth]
    + [example:webxr_vr_panorama WebXR / VR / panorama]
    + [example:webxr_vr_rollercoaster WebXR / VR / rollercoaster]
    + [example:webxr_vr_sandbox WebXR / VR / sandbox]
    + [example:webxr_vr_sculpt WebXR / VR / sculpt]
    + [example:webxr_vr_video WebXR / VR / video] +

    + + + + diff --git a/docs/manual/pt-br/introduction/How-to-dispose-of-objects.html b/docs/manual/pt-br/introduction/How-to-dispose-of-objects.html new file mode 100644 index 00000000000000..fe76a535104815 --- /dev/null +++ b/docs/manual/pt-br/introduction/How-to-dispose-of-objects.html @@ -0,0 +1,124 @@ + + + + + + + + + + + +

    Como descartar objetos

    + +

    + Um aspecto importante para aumentar o desempenho e evitar vazamentos de memória em sua aplicação é o descarte de entidades da biblioteca não utilizadas. + Sempre que você cria uma instância do tipo *three.js*, você aloca uma certa quantidade de memória. No entanto, o *three.js* cria para objetos específicos, + como geometrias ou materiais, entidades relacionadas ao WebGL como buffers ou programas de shader que são necessários para renderização. É importante + destacar que esses objetos não são liberados automaticamente. Em vez disso, o aplicativo precisa usar uma API especial para liberar esses recursos. + Este guia fornece uma breve visão geral sobre como essa API é utilizada e quais objetos são relevantes nesse contexto. +

    + +

    Geometrias (Geometries)

    + +

    + Uma geometria geralmente representa informações de vértices definidas como uma coleção de atributos. *three.js* cria internamente um objeto do tipo [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer] + para cada atributo. Essas entidades são excluídas apenas se você chamar [page:BufferGeometry.dispose](). Se uma geometria se tornar obsoleta em seu aplicativo, + execute o método para liberar todos os recursos relacionados. +

    + +

    Materiais (Materials)

    + +

    + Um material define como os objetos são renderizados. *three.js* usa as informações de uma definição de material para construir um shader para a renderização. + Os shaders só podem ser excluídos se o respectivo material for descartado. Por motivos de desempenho, o *three.js* tenta reutilizar + shaders, se possível. Portanto, um shader só é excluído se todos os materiais relacionados forem descartados. Você pode indicar o descarte de um material + executando [page:Material.dispose](). +

    + +

    Texturas (Textures)

    + +

    + O descarte de um material não afeta as texturas. Eles são manuseados separadamente, pois uma única textura pode ser usada por vários materiais ao mesmo tempo. + Sempre que você cria uma instância de [page:Texture], o three.js cria internamente uma instância de [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture]. + Semelhante aos buffers, este objeto só pode ser excluído chamando [page:Texture.dispose](). +

    + +

    + Se você usar uma `ImageBitmap` como fonte de dados da textura, você deve chamar [link:https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap/close ImageBitmap.close]() no nível da aplicação para descartar todos os recursos relacionados à CPU. + Uma chamada automatizada de `ImageBitmap.close()` em [page:Texture.dispose]() não é possível, pois o bitmap da imagem se torna inutilizável e o mecanismo não tem como saber se o bitmap da imagem é usado em outro lugar. +

    + +

    Render Targets

    + +

    + Objetos do tipo [page:WebGLRenderTarget] não apenas alocam uma instância de [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture], mas também + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLFramebuffer WebGLFramebuffer]s e [link:https://developer.mozilla.org/en-US/docs/Web/API WebGLRenderbuffer]s + para realizar render targets personalizados. Esses objetos são desalocados apenas executando [page:WebGLRenderTarget.dispose](). +

    + +

    Diversos

    + +

    + Existem outras classes da pasta de exemplos como controles ou passes de pós-processamento que fornecem métodos `dispose()` para remover listeners de eventos internos + ou renderizar targets. Em geral, é recomendado verificar a API ou a documentação de uma classe e procurar o método `dispose()`. Se existir, você deve usá-lo ao limpar as coisas. +

    + +

    FAQ

    + +

    Por que o *three.js* não pode descartar objetos automaticamente?

    + +

    + Esta pergunta foi feita muitas vezes pela comunidade, por isso é importante esclarecer este assunto. O fato é que o *three.js* não conhece o tempo de vida ou o escopo + das entidades criadas pelo usuário, como geometrias ou materiais. Isso é responsabilidade do aplicativo. Por exemplo, mesmo que um material não seja usado atualmente para renderização, + ele pode ser necessário no próximo quadro. Portanto, se o aplicativo decidir que um determinado objeto pode ser excluído, ele deve notificar a engine chamando o respectivo + método `dispose()`. +

    + +

    A remoção de um mesh da cena também descarta sua geometria e material?

    + +

    + Não, você precisa descartar explicitamente a geometria e o material via *dispose()*. Tenha em mente que geometrias e materiais podem ser compartilhados entre objetos 3D como meshes. +

    + +

    *three.js* fornece informações sobre a quantidade de objetos em cache?

    + +

    + Sim. É possível avaliar [page:WebGLRenderer.info], uma propriedade especial do renderizador (renderer) com uma série de informações estatísticas sobre a memória da placa gráfica + e o processo de renderização. Entre outras coisas, ele informa quantas texturas, geometrias e shaders são armazenados internamente. Se você notar problemas de desempenho + em seu aplicativo, é uma boa ideia depurar essa propriedade para identificar facilmente um vazamento de memória. +

    + +

    O que acontece quando você chama `dispose()` em uma textura, mas a imagem ainda não foi carregada?

    + +

    + Os recursos internos para uma textura são alocados apenas se a imagem estiver totalmente carregada. Se você descartar uma textura antes de carregar a imagem, + nada acontece. Nenhum recurso foi alocado, portanto, também não há necessidade de limpeza. +

    + +

    O que acontece quando eu chamo `dispose()` e uso o respectivo objeto posteriormente?

    + +

    + Os recursos internos excluídos serão criados novamente pela engine. Portanto, nenhum erro em tempo de execução ocorrerá, mas você poderá notar um impacto negativo no desempenho do quadro atual, + especialmente quando shaders precisam ser compilados. +

    + +

    Como devo gerenciar objetos *three.js* em minha aplicação? Quando eu sei como descartar as coisas?

    + +

    + Em geral, não existe uma recomendação definitiva para isso. Depende muito do caso específico de uso quando será mais apropriado chamar `dispose()`. É importante destacar que + nem sempre é necessário descartar objetos o tempo todo. Um bom exemplo disso é um jogo que consiste de vários níveis. Um bom momento para descarte de objetos é quando + ocorre uma mudança de nível. A aplicação pode percorrer a cena antiga e descartar todos os materiais, geometrias e texturas obsoletos. Como mencionado na seção anterior, não + ocorrerá um erro em tempo de execução se você descartar um objeto que ainda está em uso. A pior coisa que pode acontecer é a queda de desempenho para um único quadro. +

    + +

    Exemplos que demonstram o uso de dispose()

    + +

    + [example:webgl_test_memory WebGL / test / memory]
    + [example:webgl_test_memory2 WebGL / test / memory2]
    +

    + + + + diff --git a/docs/manual/pt-br/introduction/How-to-run-things-locally.html b/docs/manual/pt-br/introduction/How-to-run-things-locally.html new file mode 100644 index 00000000000000..f062fb4cc7d9f2 --- /dev/null +++ b/docs/manual/pt-br/introduction/How-to-run-things-locally.html @@ -0,0 +1,186 @@ + + + + + + + + + +

    Como executar localmente

    + +

    + Se você usar apenas geometrias procedurais e não carregar nenhuma textura, + as páginas web devem funcionar direto do sistema de arquivos, bastando clicar duas vezes + no arquivo HTML em um gerenciador de arquivos para então funcionar no navegador (você verá file:///yourFile.html na barra de endereço). +

    + +

    Conteúdo carregado de arquivos externos

    + +
    +

    + Se você carregar modelos ou texturas de arquivos externos, devido a [link:http://en.wikipedia.org/wiki/Same_origin_policy same origin policy] + dos navegadores, o carregamento de um sistema de arquivos falhará com uma exceção de segurança. +

    + +

    + Para resolver isso, execute os arquivos de um servidor web local. Isso permitirá acessar a página por: +

    + +

    + http://localhost/yourFile.html +

    + +

    + Embora também seja possível alterar as configurações de segurança do navegador ao invés de executar + um servidor local, não recomendamos essa abordagem. Isso pode abrir seu dispositivo para vulnerabilidades, + se o mesmo navegador é usado para navegação regular na web. O uso de um servidor local é uma prática padrão + em desenvolvimento web e explicamos abaixo como instalar e usar um servidor local. +

    +
    + + +

    Rodando um servidor local

    +
    +

    + Muitas linguagens de programação têm servidores HTTP simples embutidos. Eles não são tão + completos quanto servidores de produção como o [link:https://www.apache.org/ Apache] ou o + [link:https://nginx.org NGINX], no entanto devem ser suficientes para testar sua aplicação three.js. +

    + +

    Plugins para editores populares de código

    +
    +

    + Alguns editores de código tem plugins que irão rodar um servidor simples. +

    +
      +
    • [link:https://marketplace.visualstudio.com/items?itemName=yandeu.five-server Five Server] para Visual Studio Code.
    • +
    • [link:https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer Live Server] para Visual Studio Code.
    • +
    • [link:https://atom.io/packages/atom-live-server Live Server] para Atom.
    • +
    +
    + +

    Servez

    +
    +

    + [link:https://greggman.github.io/servez Servez] é um servidor simples com uma interface gráfica. +

    +
    + +

    Node.js five-server

    +
    +

    + Servidor de desenvolvimento com live reload. Para instalar: +

    + +# Remove live-server (if you have it) +npm -g rm live-server + +# Install five-server +npm -g i five-server + +# Update five-server (from time to time) +npm -g i five-server@latest + + +

    Para executar (do seu diretório local):

    + five-server . -p 8000 +
    + +

    Node.js http-server

    +
    +

    + O Node.js tem um pacote simples de um servidor HTTP. Para instalar: +

    + npm install http-server -g + +

    Para executar (do seu diretório local):

    + http-server . -p 8000 +
    + +

    Servidor Python

    +
    +

    + Se você tem [link:http://python.org/ Python] instalado, deve ser suficiente para + executar esse comando (do seu diretório de trabalho): +

    + +//Python 2.x +python -m SimpleHTTPServer + +//Python 3.x +python -m http.server + + +

    Isso vai servir os arquivos do diretório atual para localhost na porta 8000, + isto é, na barra de endereço digite: +

    + + http://localhost:8000/ +
    + +

    Servidor Ruby

    +
    +

    + Se você tem Ruby instalado, você poder ter o mesmo resultado executando: +

    + + ruby -r webrick -e "s = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => Dir.pwd); trap('INT') { s.shutdown }; s.start" + +
    + +

    Servidor PHP

    +
    +

    PHP também tem um servidor web embutido, começando com php 5.4.0:

    + php -S localhost:8000 +
    + +

    Lighttpd

    +
    +

    + Lighttpd é um servidor web de uso geral muito leve. Abordaremos a instalação no OSX + com HomeBrew aqui. Ao contrário dos outros servidores discutidos, Lighttpd é um servidor + completo de produção. +

    + +
      +
    1. + Instale via homebrew + brew install lighttpd +
    2. +
    3. + Crie um arquivo de configuração chamado lighttpd.conf no diretório onde você irá executar + o servidor web. Um exemplo está [link:http://redmine.lighttpd.net/projects/lighttpd/wiki/TutorialConfiguration aqui]. +
    4. +
    5. + No arquivo conf, mude o server.document-root para o diretório do qual você quer servir os arquivos. +
    6. +
    7. + Comece com + lighttpd -f lighttpd.conf +
    8. +
    9. + Navegue até http://localhost:8000/ e ele servirá os arquivos estáticos do diretório que você + escolheu. +
    10. +
    +
    +

    IIS

    +
    +

    + Se você estiver usando o Microsoft IIS como servidor web. Por favor adicione + configurações de tipo MIME em relação à extensão .fbx antes de carregar. +

    + File name extension: fbx MIME Type: text/plain +

    + Por padrão, o IIS bloqueia downloads de arquivos .fbx e .obj. Você tem que + configurar o IIS para habilitar que esse tipo de arquivo possa ser baixado. +

    +
    +

    + Outras alternativas simples são [link:http://stackoverflow.com/q/12905426/24874 discutidas aqui] no StackOverflow. +

    +
    + + + diff --git a/docs/manual/pt-br/introduction/How-to-update-things.html b/docs/manual/pt-br/introduction/How-to-update-things.html new file mode 100644 index 00000000000000..b28f36f9f90a76 --- /dev/null +++ b/docs/manual/pt-br/introduction/How-to-update-things.html @@ -0,0 +1,259 @@ + + + + + + + + + +

    Como atualizar as coisas

    +
    +

    Todos os objetos, por padrão, atualizam automaticamente suas matrizes se + forem adicionados à cena (scene) dessa forma

    + +const object = new THREE.Object3D(); +scene.add( object ); + + ou se eles são filhos de outro objeto que foi adicionado à cena: + +const object1 = new THREE.Object3D(); +const object2 = new THREE.Object3D(); + +object1.add( object2 ); +scene.add( object1 ); //object1 and object2 will automatically update their matrices + +
    + +

    + No entanto, se você sabe que o objeto será estático, pode desativar este recurso e atualizar + a matriz de transformação manualmente apenas quando necessário. +

    + + +object.matrixAutoUpdate = false; +object.updateMatrix(); + + +

    BufferGeometry

    +
    +

    + BufferGeometries armazenam informações (tais como posições de vértice, índice de faces, normais, cores, + UVs, e quaisquer outros atributos personalizados) em [page:BufferAttribute buffers] - isto é, + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays arrays tipados]. + Isso os torna geralmente mais rápidos do que os Geometries padrão, ao custo de serem um pouco mais difíceis de + trabalhar. +

    +

    + Com relação à atualização dos BufferGeometries, o mais importante é entender que + você não pode redimensionar buffers (isso é muito custoso, sendo basicamente o equivalente a criar uma nova geometria). + No entanto, você pode atualizar o conteúdo dos buffers. +

    +

    + Isso significa que se você sabe que um atributo do seu BufferGeometry vai crescer, digamos o número de vértices, + você deve pré-alocar um buffer grande o suficiente para conter quaisquer novos vértices que possam ser criados. + É claro, isso também significa que haverá um tamanho máximo para o seu BufferGeometry - + não há como criar um BufferGeometry que possa ser estendido de forma eficiente indefinidamente. +

    +

    + Usaremos o exemplo de uma linha que é estendida em tempo de renderização. Vamos alocar espaço + no buffer para 500 vértices, mas desenhando apenas dois primeiro, usando [page:BufferGeometry.drawRange]. +

    + +const MAX_POINTS = 500; + +// geometry +const geometry = new THREE.BufferGeometry(); + +// attributes +const positions = new Float32Array( MAX_POINTS * 3 ); // 3 vertices per point +geometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); + +// draw range +const drawCount = 2; // draw the first 2 points, only +geometry.setDrawRange( 0, drawCount ); + +// material +const material = new THREE.LineBasicMaterial( { color: 0xff0000 } ); + +// line +const line = new THREE.Line( geometry, material ); +scene.add( line ); + +

    + Em seguida, adicionaremos aleatoriamente pontos à linha usando um padrão como: +

    + +const positions = line.geometry.attributes.position.array; + +let x, y, z, index; +x = y = z = index = 0; + +for ( let i = 0, l = MAX_POINTS; i < l; i ++ ) { + + positions[ index ++ ] = x; + positions[ index ++ ] = y; + positions[ index ++ ] = z; + + x += ( Math.random() - 0.5 ) * 30; + y += ( Math.random() - 0.5 ) * 30; + z += ( Math.random() - 0.5 ) * 30; + +} + +

    + Se você quiser alterar o número de pontos renderizados após a primeira renderização, faça o seguinte: +

    + +line.geometry.setDrawRange( 0, newValue ); + +

    + Se você deseja alterar os valores dos dados de posição após a primeira renderização, você precisa + definir a propriedade needsUpdate assim: +

    + +line.geometry.attributes.position.needsUpdate = true; // required after the first render + + +

    + Se você alterar os valores dos dados de posição após a renderização inicial, pode ser necessário recalcular + os limites de volume para que outros recursos da engine, como view frustum culling ou helpers, + funcionem corretamente +

    + +line.geometry.computeBoundingBox(); +line.geometry.computeBoundingSphere(); + + +

    + [link:https://jsfiddle.net/t4m85pLr/1/ O fiddle] mostra uma linha animada que você pode adaptar ao seu caso de uso. +

    + +

    Exemplos

    + +

    + [example:webgl_custom_attributes WebGL / custom / attributes]
    + [example:webgl_buffergeometry_custom_attributes_particles WebGL / buffergeometry / custom / attributes / particles] +

    + +
    + +

    Materiais (Materials)

    +
    +

    + Todos os valores uniformes podem ser alterados livremente (por exemplo, cores, texturas, opacidade, etc), + os valores são enviados para o shader a cada quadro. +

    + +

    + Também os parâmetros relacionados ao GLstate podem mudar a qualquer momento + (depthTest, blending, polygonOffset, etc). +

    + +

    + As seguintes propriedades não podem ser alteradas facilmente em tempo de execução + (uma vez que o material é renderizado pelo menos uma vez): +

    +
      +
    • números e tipos de uniformes
    • +
    • presença ou não de +
        +
      • textura (texture)
      • +
      • fog
      • +
      • cores dos vértices (vertex colors)
      • +
      • morphing
      • +
      • shadow map
      • +
      • alpha test
      • +
      • transparent
      • +
      +
    • +
    + +

    + Mudanças nestas propriedades requerem a construção de um novo programa de shader. Você precisará definir

    + material.needsUpdate = true + +

    + Tenha em mente que isso pode ser bastante lento e induzir lags na taxa de quadros (especialmente no Windows, pois a compilação do shader é mais lenta no DirectX do que no OpenGL). +

    + +

    + Para uma experiência mais suave, você pode emular alterações nessas propriedades + até certo ponto, por ter valores "fictícios" como luzes de intensidade zero, texturas brancas ou fog de densidade zero. +

    + +

    + Você pode alterar livremente o material usado para partes da geometria, + no entanto, você não pode alterar como um objeto é dividido em partes (de acordo com os materiais da face). +

    + +

    Se você precisar ter diferentes configurações de materiais durante o tempo de execução:

    +

    + Se o número de materiais / partes for pequeno, você pode pré-dividir o objeto + de antemão (por exemplo, cabelo / rosto / corpo / roupa superior / calças para um humano, + frente / laterais /topo / vidro / pneu / interior para um carro). +

    + +

    + Se o número for grande (por exemplo, cada rosto pode ser potencialmente diferente), + considere uma solução diferente, como usar atributos / texturas para produzir diferenças + nos rostos. +

    + +

    Exemplos

    +

    + [example:webgl_materials_car WebGL / materials / car]
    + [example:webgl_postprocessing_dof WebGL / webgl_postprocessing / dof] +

    +
    + + +

    Texturas

    +
    +

    + Imagem, canvas, vídeo e dados de textura precisam ter a seguinte + propriedade definida se eles forem alterados: +

    + + texture.needsUpdate = true; + +

    Os alvos de renderização são atualizados automaticamente.

    + +

    Exemplos

    +

    + [example:webgl_materials_video WebGL / materials / video]
    + [example:webgl_rtt WebGL / rtt] +

    + +
    + + +

    Câmeras

    +
    +

    + A posição e o alvo de uma câmera são atualizados automaticamente. Se você precisa mudar +

    +
      +
    • + fov +
    • +
    • + aspect +
    • +
    • + near +
    • +
    • + far +
    • +
    +

    + então você precisará recalcular a matriz de projeção: +

    + +camera.aspect = window.innerWidth / window.innerHeight; +camera.updateProjectionMatrix(); + +
    + + diff --git a/docs/manual/pt-br/introduction/How-to-use-post-processing.html b/docs/manual/pt-br/introduction/How-to-use-post-processing.html new file mode 100644 index 00000000000000..b91a9c9ab42fd5 --- /dev/null +++ b/docs/manual/pt-br/introduction/How-to-use-post-processing.html @@ -0,0 +1,111 @@ + + + + + + + + + +

    Como usar o pós-processamento

    + +

    + Muitas aplicações three.js renderizam seus objetos 3D diretamente na tela. Às vezes, no entanto, você deseja aplicar um ou mais efeitos gráficos + como Depth-Of-Field, Bloom, Film Grain ou vários tipos de Anti-aliasing. + + O pós-processamento é uma abordagem amplamente utilizada para implementar tais efeitos. Primeiro, a cena é renderizada para um render target que representa + um buffer na memória da placa de vídeo. Na próxima etapa, um ou mais passos de pós-processamento aplicam filtros e efeitos ao buffer de imagem antes que ele seja renderizado para a tela. +

    +

    + three.js fornece uma solução completa de pós-processamento via [page:EffectComposer] para implementar esse workflow. +

    + +

    Workflow

    + +

    + A primeira etapa do processo é importar todos os arquivos necessários do diretório de exemplos. Este guia assume que você está usando o + pacote [link:https://www.npmjs.com/package/three npm] do three.js. Para nossa demonstração básica, precisamos dos seguintes arquivos. +

    + + + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { GlitchPass } from 'three/addons/postprocessing/GlitchPass.js'; + + +

    + Depois que todos os arquivos forem importados com sucesso, podemos criar nosso composer passando uma instância de [page:WebGLRenderer]. +

    + + + const composer = new EffectComposer( renderer ); + + +

    + Ao usar um composer, é necessário alterar o loop de animação da aplicação. Em vez de chamar o método render de + [page:WebGLRenderer], agora usamos a respectiva contraparte de [page:EffectComposer]. +

    + + + function animate() { + + requestAnimationFrame( animate ); + + composer.render(); + + } + + +

    + Nosso composer já está pronto para que seja possível configurar a cadeia de passos de pós-processamento. Esses passos são responsáveis ​​por criar + a saída visual final do aplicativo. Eles são processados ​​na ordem de sua adição/inserção. Em nosso exemplo, a instância de `RenderPass` + é executada primeiro e depois a instância de `GlitchPass`. A última passagem habilitada na cadeia é renderizada automaticamente na tela. A configuração + dos passos fica assim: +

    + + + const renderPass = new RenderPass( scene, camera ); + composer.addPass( renderPass ); + + const glitchPass = new GlitchPass(); + composer.addPass( glitchPass ); + + +

    + O `RenderPass` é normalmente colocado no início da cadeia para fornecer a cena renderizada como entrada para a próxima etapa de pós-processamento. No nosso caso, + o `GlitchPass` usará esses dados de imagem para aplicar um efeito de glitch selvagem. Confira este [link:https://threejs.org/examples/webgl_postprocessing_glitch exemplo] + para vê-lo em ação. +

    + +

    Passes integrados

    + +

    + Você pode usar uma ampla variedade de passos de pós-processamento predefinidos fornecidos pela engine. Estão localizados no diretório + [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/postprocessing postprocessing]. +

    + +

    Passos Personalizados

    + +

    + Às vezes, você deseja escrever um shader de pós-processamento personalizado e incluí-lo na cadeia de passos de pós-processamento. Para este cenário, + você pode utilizar o `ShaderPass`. Depois de importar o arquivo e seu shader personalizado, você pode usar o código a seguir para configurar o passo. +

    + + + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { LuminosityShader } from 'three/addons/shaders/LuminosityShader.js'; + + // later in your init routine + + const luminosityPass = new ShaderPass( LuminosityShader ); + composer.addPass( luminosityPass ); + + +

    + O repositório fornece um arquivo chamado [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/shaders/CopyShader.js CopyShader] que é um + bom código inicial para seu próprio shader personalizado. `CopyShader` apenas copia o conteúdo da imagem do buffer de leitura do [page:EffectComposer] + para seu buffer de gravação sem aplicar nenhum efeito. +

    + + + diff --git a/docs/manual/pt-br/introduction/Installation.html b/docs/manual/pt-br/introduction/Installation.html new file mode 100644 index 00000000000000..8fa7c182e7787f --- /dev/null +++ b/docs/manual/pt-br/introduction/Installation.html @@ -0,0 +1,146 @@ + + + + + + + + + +

    Instalação

    + +

    Você pode instalar o three.js através do [link:https://www.npmjs.com/ npm] e modernas ferramentas de build ou começar rapidamente apenas com hospedagem estática ou um CDN. Para a maioria dos usuários, instalar pelo npm é a melhor opção.

    + +

    Seja qual for a maneira que escolher, seja consistente e importe todos os arquivos na mesma versão da biblioteca. A mistura de arquivos de versões diferentes pode causar a inclusão de código duplicado ou até mesmo quebrar a aplicação de maneiras inesperadas.

    + +

    Todos os métodos de instalação do three.js dependem dos ES modules (veja [link:https://eloquentjavascript.net/10_modules.html#h_hF2FmOVxw7 Eloquent JavaScript: ECMAScript Modules]), que permitem incluir somente as partes necessárias da biblioteca no projeto final.

    + +

    Instalar pelo npm

    + +

    + Para instalar o módulo do npm do [link:https://www.npmjs.com/package/three three], abra uma janela do terminal na sua pasta do projeto e execute: +

    + + + npm install three + + +

    + O pacote será baixado e instalado. Então você estará pronto para importar no seu código: +

    + + + // Option 1: Import the entire three.js core library. + import * as THREE from 'three'; + + const scene = new THREE.Scene(); + + + // Option 2: Import just the parts you need. + import { Scene } from 'three'; + + const scene = new Scene(); + + +

    Ao instalar a partir do npm, você quase sempre usará algum tipo de [link:https://eloquentjavascript.net/10_modules.html#h_zWTXAU93DC ferramenta de build] para combinar todos os pacotes que seu projeto precisa em um único arquivo JavaScript. Embora alguns modernos empacotadores JavaScript possam ser usados com o three.js, a escolha mais popular é o [link:https://webpack.js.org/ webpack].

    + +

    Nem todos os recursos são acessados diretamente pelo módulo three. Outras partes populares da biblioteca - tais como controls, loaders e post-processing effects - devem ser importados da subpasta [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm]. Para aprender mais, veja o Exemplo abaixo.

    + +

    Aprenda mais sobre módulos do npm em [link:https://eloquentjavascript.net/20_node.html#h_J6hW/SmL/a Eloquent JavaScript: Installing with npm].

    + +

    Instalar através de CDN ou hospedagem estática

    + +

    A biblioteca three.js pode ser utilizada sem nenhum sistema de build, seja fazendo o upload dos arquivos para seu próprio servidor web ou usando um CDN existente. Como a biblioteca depende dos ES modules, qualquer script que faça referência a eles deve usar type="module" como mostrado abaixo. Também é necessário definir um mapa de importação que resolva a importação direta do `three`.

    + + + <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> + + <script type="importmap"> + { + "imports": { + "three": "https://unpkg.com/three@<version>/build/three.module.js" + } + } + </script> + + <script type="module"> + + import * as THREE from 'three'; + + const scene = new THREE.Scene(); + + </script> + + +

    + Nem todos os recursos disponíveis são acessados diretamente através do módulo three. Outras partes populares da biblioteca - tais como controls, loaders e post-processing effects - devem ser importados da subpasta [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm]. Para aprender mais, veja o Exemplo abaixo. +

    + +

    + Como os mapas de importação ainda não são suportados por todos os navegadores, é necessário adicionar o polyfill *es-module-shims.js*. +

    + +

    Addons

    + +

    + O núcleo do three.js está focado nos componentes mais importantes de uma engine 3D. Muitos outros componentes úteis - como controls, loaders e post-processing effects - fazem parte da pasta [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm]. Eles são chamados de "exemplos" porque embora você possa usá-los diretamente, eles também podem ser remixados e personalizados. Esses componentes são sempre mantidos em sincronia com a biblioteca principal, enquanto pacotes semelhantes de terceiros no npm são mantidos por pessoas diferentes e podem estar desatualizados. +

    + +

    + Os addons não precisam ser instalados separadamente, mas precisam ser importados separadamente. Se o three.js foi instalado com npm, você pode carregar o componente [page:OrbitControls] com: +

    + + + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + + const controls = new OrbitControls( camera, renderer.domElement ); + + +

    Se o three.js foi instalado de um CDN, use o mesmo CDN para instalar outros componentes:

    + + + <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> + + <script type="importmap"> + { + "imports": { + "three": "https://unpkg.com/three@<version>/build/three.module.js", + "three/addons/": "https://unpkg.com/three@<version>/examples/jsm/" + } + } + </script> + + <script type="module"> + + import * as THREE from 'three'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + + const controls = new OrbitControls( camera, renderer.domElement ); + + </script> + + +

    + É importante que todos os arquivos utilizem a mesma versão. Não importe diferentes addons de diferentes versões, ou use addons de uma versão diferente que a própria biblioteca three.js. +

    + +

    Compatibilidade

    + +

    Importação CommonJS

    + +

    + Embora a maioria dos bundlers JavaScript modernos atualmente suportem os ES modules por padrão, algumas ferramentas de build mais antigas podem não suportar. Nesses casos você provavelmente pode configurar o bundler para entender os ES modules: [link:http://browserify.org/ Browserify] precisa apenas do plugin [link:https://github.com/babel/babelify babelify], por exemplo. +

    + +

    Node.js

    + +

    + Como o three.js foi desenvolvido para a web, ele depende do navegador e das APIs DOM que nem sempre existem no Node.js. Alguns desses problemas podem ser resolvidos usando ferramentas como [link:https://github.com/stackgl/headless-gl headless-gl], ou substituindo componentes como [page:TextureLoader] por alternativas personalizadas. Outras APIs DOM podem ser profundamente entrelaçadas com o código que as utiliza, e serão mais difíceis de contornar. Aceitamos solicitações de pull simples e fáceis de manter para melhorar o suporte ao Node.js, mas recomendo abrir uma issue para discutir suas melhorias primeiro. +

    + +

    + Certifique-se de adicionar `{ "type": "module" }` ao seu `package.json` para habilitar os ES6 modules em seu projeto Node.js. +

    + + + diff --git a/docs/manual/pt-br/introduction/Libraries-and-Plugins.html b/docs/manual/pt-br/introduction/Libraries-and-Plugins.html new file mode 100644 index 00000000000000..3dd11050a17bf4 --- /dev/null +++ b/docs/manual/pt-br/introduction/Libraries-and-Plugins.html @@ -0,0 +1,108 @@ + + + + + + + + + +

    Bibliotecas e Plugins

    + +

    + Aqui estão listadas bibliotecas e plugins para three.js desenvolvidos por terceiros. Esta + lista e os pacotes associados são mantidos pela comunidade e não é garantido que estejam atualizados. + Se você gostaria de atualizar esta lista faça uma PR! +

    + +

    Física

    + +
      +
    • [link:https://github.com/lo-th/Oimo.js/ Oimo.js]
    • +
    • [link:https://enable3d.io/ enable3d]
    • +
    • [link:https://github.com/kripken/ammo.js/ ammo.js]
    • +
    • [link:https://github.com/pmndrs/cannon-es cannon-es]
    • +
    + +

    Pós-processamento

    + +

    + Além do oficial [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/postprocessing postprocessing effects], + suporte para alguns efeitos e estruturas adicionais estão disponíveis por meio de bibliotecas externas. +

    + +
      +
    • [link:https://github.com/vanruesc/postprocessing postprocessing]
    • +
    + +

    Intersecção e Performance Raycast

    + +
      +
    • [link:https://github.com/gkjohnson/three-mesh-bvh three-mesh-bvh]
    • +
    + +

    Path Tracing

    + +
      +
    • [link:https://github.com/gkjohnson/three-gpu-pathtracer three-gpu-pathtracer]
    • +
    + +

    Formatos de arquivos

    + +

    + Além do oficial [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/loaders loaders], + suporte para alguns formatos adicionais estão disponíveis por meio de bibliotecas externas. +

    + +
      +
    • [link:https://github.com/gkjohnson/urdf-loaders/tree/master/javascript urdf-loader]
    • +
    • [link:https://github.com/NASA-AMMOS/3DTilesRendererJS 3d-tiles-renderer-js]
    • +
    • [link:https://github.com/kaisalmen/WWOBJLoader WebWorker OBJLoader]
    • +
    • [link:https://github.com/IFCjs/web-ifc-three IFC.js]
    • +
    + +

    Geometria

    + +
      +
    • [link:https://github.com/spite/THREE.MeshLine THREE.MeshLine]
    • +
    + +

    Texto e Layout 3D

    + +
      +
    • [link:https://github.com/protectwise/troika/tree/master/packages/troika-three-text troika-three-text]
    • +
    • [link:https://github.com/felixmariotto/three-mesh-ui three-mesh-ui]
    • +
    + +

    Sistema de partículas

    + +
      +
    • [link:https://github.com/creativelifeform/three-nebula three-nebula]
    • +
    + +

    Inverse Kinematics

    + +
      +
    • [link:https://github.com/jsantell/THREE.IK THREE.IK]
    • +
    • [link:https://github.com/lo-th/fullik fullik]
    • +
    • [link:https://github.com/gkjohnson/closed-chain-ik-js closed-chain-ik]
    • +
    + +

    IA para Games

    + +
      +
    • [link:https://mugen87.github.io/yuka/ yuka]
    • +
    • [link:https://github.com/donmccurdy/three-pathfinding three-pathfinding]
    • +
    + +

    Wrappers e Frameworks

    + +
      +
    • [link:https://aframe.io/ A-Frame]
    • +
    • [link:https://github.com/pmndrs/react-three-fiber react-three-fiber]
    • +
    • [link:https://github.com/ecsyjs/ecsy-three ECSY]
    • +
    • [link:https://threlte.xyz/ Threlte]
    • +
    + + + diff --git a/docs/manual/pt-br/introduction/Loading-3D-models.html b/docs/manual/pt-br/introduction/Loading-3D-models.html new file mode 100644 index 00000000000000..cc47bb69a49161 --- /dev/null +++ b/docs/manual/pt-br/introduction/Loading-3D-models.html @@ -0,0 +1,165 @@ + + + + + + + + + + + +

    Carregando modelos 3D

    + +

    + Os modelos 3D estão disponíveis em centenas de formatos de arquivo, cada um com diferentes + propósitos, recursos variados e complexidade variável. Embora o + + three.js forneça muitos loaders, escolher o formato e o fluxo de trabalho certos economizará tempo e frustração mais tarde. + Alguns formatos são difíceis de trabalhar, ineficientes para experiências em tempo real + ou simplesmente não são totalmente suportados por enquanto. +

    + +

    + Este guia fornece um fluxo de trabalho recomendado para a maioria dos usuários e sugestões + do que tentar se as coisas não correrem como o esperado. +

    + +

    Antes de começar

    + +

    + Se você é iniciante na execução de um servidor local, comece com + [link:#manual/introduction/How-to-run-things-locally Como executar localmente] + primeiro. Muitos erros comuns de visualização de modelos 3D podem ser evitados hospedando arquivos + corretamente. +

    + +

    Fluxo de trabalho recomendado

    + +

    + Sempre que possível, recomendamos o uso do glTF (GL Transmission Format). Ambas versões do formato, + .GLB e .GLTF, são bem suportadas. + Como o glTF está focado na entrega de recursos em tempo de execução, + ele é compacto para transmitir e rápido para carregar. Seus recursos incluem meshs, materiais, + texturas, skins, skeletons, morph targets, animações, luzes e câmeras. +

    + +

    + Os arquivos glTF de domínio público estão disponíveis em sites como + + Sketchfab, ou várias ferramentas que incluem exportação glTF: +

    + + + +

    + Se suas ferramentas preferidas não suportam glTF, considere solicitar exportação de glTF para os autores, + ou postar no glTF roadmap thread. +

    + +

    + Quando o glTF não é uma opção, formatos populares como FBX, OBJ ou COLLADA + também estão disponíveis e são mantidos regularmente. +

    + +

    Carregando

    + +

    + Apenas alguns poucos loaders (por exemplo [page:ObjectLoader]) são incluídos por padrão com o + three.js — outros devem ser adicionados ao seu aplicativo individualmente. +

    + + + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + + +

    + Depois de importar um loader você está pronto para adicionar um modelo à sua cena. A sintaxe varia entre + loaders diferentes — ao usar outro formato, verifique os exemplos e a documentação para esse loader. + Para glTF, o uso com scripts globais ficaria: +

    + + + const loader = new GLTFLoader(); + + loader.load( 'path/to/model.glb', function ( gltf ) { + + scene.add( gltf.scene ); + + }, undefined, function ( error ) { + + console.error( error ); + + } ); + + +

    + Veja a documentação [page:GLTFLoader GLTFLoader] para mais detalhes. +

    + +

    Solução de problemas

    + +

    + Você passou horas modelando uma obra-prima artesanal, você a carrega em + uma página web e — ah, não! 😭 Está distorcido, descolorido ou totalmente ausente. + Comece com estas etapas de solução de problemas: +

    + +
      +
    1. + Verifique se há erros no console JavaScript e certifique-se de ter usado um + callback `onError` ao chamar `.load()` para logar o resultado. +
    2. +
    3. + Visualize o modelo em outro aplicativo. Para glTF, visualizadores drag-and-drop + estão disponíveis para + three.js e + babylon.js. + Se o modelo aparece corretamente em um ou mais aplicativos, + registre um bug do three.js. + Se o modelo não puder ser mostrado em nenhum aplicativo, recomendamos + registrar um bug com o aplicativo usado para criar o modelo. +
    4. +
    5. + Tente dimensionar o modelo para cima ou para baixo por um fator de 1.000. Muitos modelos são + dimensionados de forma diferente, e modelos grandes podem não aparecer se a câmera estiver + dentro do modelo. +
    6. +
    7. + Tente adicionar e posicionar uma fonte de luz. O modelo pode estar escondido no escuro. +
    8. +
    9. + Procure requisições de textura com falha na aba network, como + `"C:\\Path\To\Model\texture.jpg"`. Use caminhos relativos ao seu + modelo em vez disso, tal como `images/texture.jpg` — + isso pode exigir edição do arquivo de modelo em um editor de texto. +
    10. +
    + +

    Pedindo ajuda

    + +

    + Se você passou pelo processo de solução de problemas acima e seu modelo + ainda não está funcionando, uma abordagem correta para pedir ajuda fará com que você + tenha uma solução mais rápida. Poste uma pergunta no + fórum three.js + e, sempre que possível, + inclua seu modelo (ou um modelo mais simples com o mesmo problema) em qualquer formato que + você tiver disponível. Inclua informações suficientes para outra pessoa reproduzir + o problema rapidamente - idealmente, uma demonstração ao vivo. +

    + + + + diff --git a/docs/manual/pt-br/introduction/Matrix-transformations.html b/docs/manual/pt-br/introduction/Matrix-transformations.html new file mode 100644 index 00000000000000..4b38d09049d06a --- /dev/null +++ b/docs/manual/pt-br/introduction/Matrix-transformations.html @@ -0,0 +1,70 @@ + + + + + + + + + +

    Transformações de matriz

    + +

    + Three.js usa `matrizes` para codificar transformações 3D --- translações (posição), rotações e dimensionamento. + Cada instância de [page:Object3D] tem uma [page:Object3D.matrix matriz] (matrix) que armazena a + posição, rotação e escala. Esta página descreve como atualizar a transformação de um objeto. +

    + +

    Propriedades de conveniência e `matrixAutoUpdate`

    + +

    + Existem duas maneiras de atualizar a transformação de um objeto: +

    +
      +
    1. + Modifique as propriedades `position`, `quaternion` e `scale` do objeto e deixe o three.js recalcular + a matriz do objeto a partir destas propriedades: + +object.position.copy( start_position ); +object.quaternion.copy( quaternion ); + + Por padrão, a propriedade `matrixAutoUpdate` é definida como verdadeira e a matriz será recalculada automaticamente. + Se o objeto é estático, ou você deseja controlar manualmente quando ocorre o recálculo, um melhor desempenho pode ser obtido configurando a propriedade false: + +object.matrixAutoUpdate = false; + + E depois de alterar qualquer propriedade, atualize manualmente a matriz: + +object.updateMatrix(); + +
    2. +
    3. + Modifique a matriz do objeto diretamente. A classe [page:Matrix4] tem vários métodos para modificar a matriz: + +object.matrix.setRotationFromQuaternion( quaternion ); +object.matrix.setPosition( start_position ); +object.matrixAutoUpdate = false; + + Observe que `matrixAutoUpdate` deve ser definido como `false` neste caso, e você deve ter certeza de não chamar `updateMatrix`. Chamar `updateMatrix` irá destruir as alterações manuais feitas na matriz, recalculando a matriz de `position`, `scale` e assim por diante. +
    4. +
    + +

    Objeto e matrizes mundo (world matrices)

    +

    + A [page:Object3D.matrix matriz] (matrix) de um objeto armazena a transformação do objeto relativa ao objeto [page:Object3D.parent pai] (parent); para obter a transformação do objeto em coordenadas mundo, deve-se acessar a [page:Object3D.matrixWorld] do objeto. +

    +

    + Quando a transformação do objeto pai ou filho muda, você pode solicitar que a [page:Object3D.matrixWorld matrixWorld] do objeto filho seja atualizada chamando [page:Object3D.updateMatrixWorld updateMatrixWorld](). +

    + +

    Rotação e Quaternion

    +

    + Three.js fornece duas maneiras de representar rotações 3D: [page:Euler Euler angles] e [page:Quaternion Quaternions], bem como métodos para converter entre os dois. + Os ângulos de Euler estão sujeitos a um problema chamado "gimbal lock", onde certas configurações podem perder um grau de liberdade (impedindo que o objeto seja girado em torno de um eixo). Por esta razão, + as rotações do objeto são sempre armazenadas no objeto [page:Object3D.quaternion quaternion]. +

    +

    + As versões anteriores da biblioteca incluíam uma propriedade `useQuaternion` que, quando definida como false, faria com que a [page:Object3D.matrix matrix] do objeto fosse calculada a partir de um ângulo de Euler. Essa prática está obsoleta --- em vez disso, você deve usar o método [page:Object3D.setRotationFromEuler setRotationFromEuler], que atualizará o quaternion. +

    + + diff --git a/docs/manual/pt-br/introduction/Useful-links.html b/docs/manual/pt-br/introduction/Useful-links.html new file mode 100644 index 00000000000000..271f29c17381ed --- /dev/null +++ b/docs/manual/pt-br/introduction/Useful-links.html @@ -0,0 +1,185 @@ + + + + + + + + + +

    Links úteis

    + +

    + Veja a seguir uma coleção de links que podem ser úteis para aprender three.js.
    + Se você encontrar algo que gostaria de adicionar aqui ou achar que um dos links abaixo não está mais + relevante ou funcionando, sinta-se à vontade para clicar no botão 'editar' no canto inferior direito e fazer algumas alterações!

    + + Note também que, como o three.js está em rápido desenvolvimento, muitos desses links conterão informações que estão + desatualizadas - se algo não estiver funcionando como esperado ou como um desses links diz que deveria funcionar, + verifique se há avisos ou erros no console do navegador. Verifique também as páginas de documentação relevantes. +

    + +

    Fóruns de ajuda

    +

    + Three.js utiliza oficialmente o [link:https://discourse.threejs.org/ forum] e o [link:http://stackoverflow.com/tags/three.js/info Stack Overflow] para + pedidos de ajuda. + + Se você precisar de ajuda com algo, esse é o caminho. NÃO abra uma issue no Github para pedidos de ajuda. +

    + +

    Cursos e tutoriais

    + +

    Primeiros passos com o three.js

    +
      +
    • + [link:https://threejs.org/manual/#en/fundamentals Three.js Fundamentals starting lesson] +
    • +
    • + [link:https://codepen.io/rachsmith/post/beginning-with-3d-webgl-pt-1-the-scene Beginning with 3D WebGL] de [link:https://codepen.io/rachsmith/ Rachel Smith]. +
    • +
    • + [link:https://www.august.com.au/blog/animating-scenes-with-webgl-three-js/ Animating scenes with WebGL and three.js] +
    • +
    + +

    Artigos e cursos mais extensos / avançados

    +
      +
    • + [link:https://threejs-journey.com/ Three Journey] Curso do [link:https://bruno-simon.com/ Bruno Simon] - + Ensina os iniciantes a usar o Three.js passo a passo +
    • +
    • + [link:https://discoverthreejs.com/ Discover three.js] +
    • +
    • + [link:http://blog.cjgammon.com/ Collection of tutorials] do [link:http://www.cjgammon.com/ CJ Gammon]. +
    • +
    • + [link:https://medium.com/soffritti.pierfrancesco/glossy-spheres-in-three-js-bfd2785d4857 Glossy spheres in three.js]. +
    • +
    • + [link:https://www.udacity.com/course/cs291 Interactive 3D Graphics] - um curso gratuito da Udacity que ensina os fundamentos de gráficos 3D, + e usa three.js como sua ferramenta de codificação. +
    • +
    • + [Link:https://aerotwist.com/tutorials/ Aerotwist] tutoriais do [link:https://github.com/paullewis/ Paul Lewis]. +
    • +
    • + [link:http://learningthreejs.com/ Learning Three.js] – um blog com artigos dedicados ao ensino de three.js +
    • +
    • + [link:https://discourse.threejs.org/t/three-js-bookshelf/2468 Three.js Bookshelf] - Procurando mais recursos sobre three.js ou computação gráfica em geral? + Confira a seleção de literatura recomendada pela comunidade. +
    • +
    + +

    Notícias e atualizações

    +
      +
    • + [link:https://twitter.com/hashtag/threejs Three.js no Twitter] +
    • +
    • + [link:http://www.reddit.com/r/threejs/ Three.js no reddit] +
    • +
    • + [link:http://www.reddit.com/r/webgl/ WebGL no reddit] +
    • +
    + +

    Exemplos

    +
      +
    • + [link:https://github.com/edwinwebb/three-seed/ three-seed] - Projeto inicial three.js com ES6 e Webpack +
    • +
    • + [link:http://stemkoski.github.io/Three.js/index.html Professor Stemkoskis Examples] - Uma coleção de exemplos + amigáveis para iniciantes desenvolvidos com three.js. +
    • +
    • + [link:https://threejs.org/examples/ Official three.js examples] - esses exemplos são + mantidos como parte do repositório three.js e sempre usam a versão mais recente da biblioteca. +
    • +
    • + [link:https://raw.githack.com/mrdoob/three.js/dev/examples/ Official three.js dev branch examples] - + Igual ao anterior, exceto que eles usam a branch dev do three.js e são usados ​​para verificar se + tudo está funcionando enquanto o three.js está sendo desenvolvido. +
    • +
    + +

    Ferramentas

    +
      +
    • + [link:https://github.com/tbensky/physgl physgl.org] - Front-end JavaScript com wrappers para three.js, com o intuito de trazer gráficos WebGL + para alunos que estão aprendendo física e matemática. +
    • +
    • + [link:https://whsjs.readme.io/ Whitestorm.js] – Framework modular three.js com o plugin de física AmmoNext. +
    • +
    • + [link:http://zz85.github.io/zz85-bookmarklets/threelabs.html Three.js Inspector] +
    • +
    • + [link:http://idflood.github.io/ThreeNodes.js/ ThreeNodes.js]. +
    • +
    • + [link:https://marketplace.visualstudio.com/items?itemName=slevesque.shader vscode shader] - Marcador de sintaxe para linguagem de shader. +
      + [link:https://marketplace.visualstudio.com/items?itemName=bierner.comment-tagged-templates vscode comment-tagged-templates] - + Marcador de sintaxe para modelo de strings com tags usando comentários para linguagem de shader, como: glsl.js. +
    • +
    • + [link:https://github.com/MozillaReality/WebXR-emulator-extension WebXR-emulator-extension] +
    • +
    + +

    Referências WebGL

    +
      +
    • + [link:https://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf webgl-reference-card.pdf] - Referência de todas as palavras-chave WebGL e GLSL, terminologia, sintaxe e definições. +
    • +
    + +

    Links antigos

    +

    + Esses links são mantidos para fins históricos - você ainda pode achá-los úteis, mas esteja avisado de que + eles podem ter informações relacionadas a versões muito antigas do three.js. +

    + +
      +
    • + AlterQualia at WebGL Camp 3 +
    • +
    • + [link:http://yomotsu.github.io/threejs-examples/ Yomotsus Examples] - uma coleção de exemplos usando three.js r45 +
    • +
    • + [link:http://fhtr.org/BasicsOfThreeJS/#1 Introduction to Three.js] de [link:http://github.com/kig/ Ilmari Heikkinen] (slides). +
    • +
    • + [link:http://www.slideshare.net/yomotsu/webgl-and-threejs WebGL and Three.js] de [link:http://github.com/yomotsu Akihiro Oyamada] (slides). +
    • +
    • + Trigger Rally de [link:https://github.com/jareiko jareiko] (vídeo). +
    • +
    • + [link:http://blackjk3.github.io/threefab/ ThreeFab] - editor de cena, mantido até cerca do three.js r50. +
    • +
    • + [link:http://bkcore.com/blog/3d/webgl-three-js-workflow-tips.html Max to Three.js workflow tips and tricks] de [link:https://github.com/BKcore BKcore] +
    • +
    • + [link:http://12devsofxmas.co.uk/2012/01/webgl-and-three-js/ A whirlwind look at Three.js] + de [link:http://github.com/nrocy Paul King] +
    • +
    • + [link:http://bkcore.com/blog/3d/webgl-three-js-animated-selective-glow.html Animated selective glow in Three.js] + de [link:https://github.com/BKcore BKcore] +
    • +
    • + [link:http://www.natural-science.or.jp/article/20120220155529.php Building A Physics Simulation Environment] - + tutorial three.js em japonês +
    • +
    + + + diff --git a/docs/manual/pt-br/introduction/WebGL-compatibility-check.html b/docs/manual/pt-br/introduction/WebGL-compatibility-check.html new file mode 100644 index 00000000000000..93e327fdd521b1 --- /dev/null +++ b/docs/manual/pt-br/introduction/WebGL-compatibility-check.html @@ -0,0 +1,34 @@ + + + + + + + + + +

    Compatibilidade WebGL

    + +

    + Mesmo que isso esteja se tornando um problema cada vez menor, alguns dispositivos ou navegadores podem ainda não suportar WebGL. O método a seguir permite verificar se há suporte e exibe uma mensagem para o usuário se não existir. +

    + +

    + Adicione [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/capabilities/WebGL.js] ao seu JavaScript e execute o seguinte código antes de tentar renderizar qualquer coisa. +

    + + + if ( WebGL.isWebGLAvailable() ) { + + // Initiate function or other initializations here + animate(); + + } else { + + const warning = WebGL.getWebGLErrorMessage(); + document.getElementById( 'container' ).appendChild( warning ); + + } + + + diff --git a/docs/manual/ru/introduction/Creating-a-scene.html b/docs/manual/ru/introduction/Creating-a-scene.html new file mode 100644 index 00000000000000..8aa955e64e63cf --- /dev/null +++ b/docs/manual/ru/introduction/Creating-a-scene.html @@ -0,0 +1,162 @@ + + + + + + + + + +

    Создание сцены

    + +

    Цель этого раздела - дать краткое введение в three.js . Мы начнем с создания сцены с вращающимся кубом. Рабочий пример приведен внизу страницы на случай, если вы где то застряли и вам понадобится помощь.

    + +

    Прежде чем мы начнем

    + +

    + Прежде чем вы сможете использовать three.js , вам нужно где-то его отобразить. Сохраните следующий HTML-код в файл на вашем компьютере вместе с копией [link:https://threejs.org/build/three.js three.js] в каталоге js/ и откройте его в своем браузере. +

    + + + <!DOCTYPE html> + <html> + <head> + <meta charset="utf-8"> + <title>My first three.js app</title> + <style> + body { margin: 0; } + </style> + </head> + <body> + <script src="js/three.js"></script> + <script> + // Наш Javascript будет здесь.. + </script> + </body> + </html> + + +

    Пока это все. Весь приведенный ниже код помещается в пустой тег <script>.

    + +

    Создание сцены

    + +

    Чтобы на самом деле иметь возможность отображать что-либо с three.js, Нам нужны три вещи: сцена, камера и средство визуализации, чтобы мы могли визуализировать сцену с помощью камеры.

    + + + const scene = new THREE.Scene(); + const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); + + const renderer = new THREE.WebGLRenderer(); + renderer.setSize( window.innerWidth, window.innerHeight ); + document.body.appendChild( renderer.domElement ); + + +

    Давайте воспользуемся моментом, чтобы объяснить, что здесь происходит. Теперь мы настроили сцену, нашу камеру и средство визуализации.

    + +

    Есть несколько разных камер в three.js . А пока давайте воспользуемся `PerspectiveCamera`.

    +

    Первый атрибут - это `поле зрения (field of view)`. FOV - это масштаб сцены, которая видна на дисплее в любой данный момент. Значение указано в градусах.

    + +

    Второй - это `соотношение сторон (aspect ratio)`. Вы почти всегда хотите использовать ширину элемента, деленную на высоту, иначе вы получите тот же результат, что и при воспроизведении старых фильмов на широкоэкранном телевизоре - изображение выглядит сплющенным.

    + +

    Следующие два атрибута - это `ближняя (near)` и `дальняя (far)` плоскость отсечения. Это означает, что объекты, находящиеся дальше от камеры, чем значение `far`, или ближе, чем `near`, не будут отображаться. Сейчас вам не нужно беспокоиться об этом, но вы можете использовать другие значения в своих приложениях, чтобы повысить производительность.

    + +

    Далее следует средство визуализации. Вот тут-то и происходит волшебство. В дополнение к средству визуализации WebGL, которое мы используем здесь, three.js поставляется с несколькими другими, часто используемыми в качестве резервных для пользователей со старыми браузерами или для тех, у кого по какой-либо причине нет поддержки WebGL.

    +

    В дополнение к созданию экземпляра средства визуализации нам также необходимо установить размер, в котором мы хотим, чтобы оно отображало наше приложение. Рекомендуется использовать ширину и высоту области, которую мы хотим заполнить с помощью нашего приложения - в данном случае ширину и высоту окна браузера. Для приложений с высокой производительностью вы также можете задать `setSize` меньшее значения, например `window.innerWidth/2` и `window.innerHeight/2`, что приведет к рендерингу приложения в четверть размера.

    +

    Если вы хотите сохранить размер своего приложения, но отобразить его с меньшим разрешением, вы можете сделать это, вызвав `setSize` с `updateStyle`(третий аргумент) равному false. Например, `setSize(window.innerWidth/2, window.innerHeight/2, false)` будет отображать ваше приложение с половинным разрешением, учитывая, что ваш <canvas > имеет 100% ширины и высоты.

    + +

    И последнее, но не менее важное: мы добавляем элемент `renderer` в наш HTML-документ. Это элемент <canvas>, который рендерер использует для отображения сцены для нас.

    +

    "Все это хорошо, но, где тот кубик, который Вы так обещали?" Давайте добавим его сейчас.

    + + + const geometry = new THREE.BoxGeometry( 1, 1, 1 ); + const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); + const cube = new THREE.Mesh( geometry, material ); + scene.add( cube ); + + camera.position.z = 5; + + +

    Чтобы создать куб, нам нужна `BoxGeometry`. Это объект, который содержит все точки (`vertices/вершины`) и заливку (`faces/грани`) куба. Мы подробнее рассмотрим это в будущем.

    + +

    В дополнение к геометрии нам нужен материал, чтобы раскрасить его. Three.js поставляется с несколькими материалами, но пока мы будем придерживаться `MeshBasicMaterial`. Все материалы приобретают объект свойств, которые будут к ним применены. Чтобы все было очень просто, мы предоставляем только атрибут цвета `0x00ff00`, который является зеленым. Это работает так же, как цвета работают в CSS или Photoshop (`шестнадцатеричные цвета/hex colors`).

    + +

    Третья вещь, которая нам нужна, - это `Mesh(Сетка)`. Сетка - это объект, который принимает геометрию и применяет к ней материал, который затем мы можем вставить в нашу сцену и свободно перемещать по ней.

    + +

    По умолчанию, когда мы вызываем `scene.add()`, то, что мы добавляем, будет добавлено к координатам `(0,0,0)`. Это привело бы к тому, что и камера, и куб оказались бы внутри друг друга. Чтобы избежать этого, мы просто немного выдвигаем камеру.

    + +

    Рендеринг сцены

    + +

    Если бы вы скопировали приведенный выше код в HTML-файл, который мы создали ранее, вы бы ничего не смогли увидеть. Это потому, что на самом деле мы еще ничего не рендерим. Для этого нам нужно то, что называется `цикл рендеринга или анимации`.

    + + + function animate() { + requestAnimationFrame( animate ); + renderer.render( scene, camera ); + } + animate(); + + +

    Это создаст цикл, который заставляет средство визуализации отрисовывать сцену каждый раз при обновлении экрана (на обычном экране это означает 60 раз в секунду). Если вы новичок в написании игр в браузере, вы можете сказать "Почему бы нам просто не создать setInterval?" Дело в том, что мы могли бы, но `requestAnimationFrame` имеет ряд преимуществ. Возможно, самым важным из них является то, что он приостанавливается, когда пользователь переходит на другую вкладку браузера, следовательно, не тратя впустую свою драгоценную вычислительную мощность и время автономной работы.

    + +

    Анимация куба

    + +

    Если вы вставите весь приведенный выше код в файл, который вы создали до того, как мы начали, вы должны увидеть зеленое поле. Давайте сделаем все это немного интереснее, повернув его.

    + +

    Добавьте следующий код прямо над вызовом `renderer.render` в вашей функции `animate`:

    + + + cube.rotation.x += 0.01; + cube.rotation.y += 0.01; + + +

    Это будет выполняться каждый кадр (обычно 60 раз в секунду) и придаст кубу приятную анимацию вращения. По сути, все, что вы хотите переместить или изменить во время работы приложения, должно пройти через цикл анимации. Конечно, вы можете вызывать оттуда другие функции, чтобы в итоге не получить `анимированную` функцию, состоящую из сотен строк.

    + +

    Результат

    + +

    Поздравляю! Теперь вы завершили свой первый three.js применение. Это просто, но вы должны с чего-то начать.

    + +

    Полный код доступен ниже и доступен для редактирования [link:https://jsfiddle.net/fxurzeb4/ live example]. Поиграйте с ним, чтобы лучше понять, как он работает.

    + + + <!DOCTYPE html> + <html> + <head> + <meta charset="utf-8"> + <title>My first three.js app</title> + <style> + body { margin: 0; } + </style> + </head> + <body> + <script src="js/three.js"></script> + <script> + const scene = new THREE.Scene(); + const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); + + const renderer = new THREE.WebGLRenderer(); + renderer.setSize( window.innerWidth, window.innerHeight ); + document.body.appendChild( renderer.domElement ); + + const geometry = new THREE.BoxGeometry( 1, 1, 1 ); + const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); + const cube = new THREE.Mesh( geometry, material ); + scene.add( cube ); + + camera.position.z = 5; + + function animate() { + requestAnimationFrame( animate ); + + cube.rotation.x += 0.01; + cube.rotation.y += 0.01; + + renderer.render( scene, camera ); + }; + + animate(); + </script> + </body> + </html> + + + diff --git a/docs/manual/ru/introduction/Creating-text.html b/docs/manual/ru/introduction/Creating-text.html new file mode 100644 index 00000000000000..5708532389f88d --- /dev/null +++ b/docs/manual/ru/introduction/Creating-text.html @@ -0,0 +1,142 @@ + + + + + + + + + +

    Создание текста ([name])

    +
    +

    + Часто бывают случаи, когда вам может понадобиться использовать текст в вашем three.js приложение - вот + несколько способов, как это сделать. +

    +
    + +

    1. DOM + CSS

    +
    +

    + Использование HTML, как правило, является самым простым и быстрым способом добавления текста. Этот метод + используется для наложения текста в большинстве three.js приложений. +

    +

    Вы можете добавлять содержимое в

    + <div id="info">Описание</div> + +

    + и использовать разметку CSS для абсолютного позиционирования над всеми остальным с + z-index, особенно если вы используете полноэкранный режим three.js. +

    + + +#info { + position: absolute; + top: 10px; + width: 100%; + text-align: center; + z-index: 100; + display:block; +} + + +
    + + +

    2. Использование [page:CSS2DRenderer] или [page:CSS3DRenderer]

    +
    +

    + Используйте эти рендереры для отрисовки высококачественного текста, содержащегося в элементах DOM, в вашу сцену three.js. + Это похоже на 1. за исключением того, что с помощью этих средств визуализации элементы могут быть более тесно и динамично интегрированы в сцену. +

    +
    + + +

    3. Нарисуйте текст на холсте используя [page:Texture]

    +
    +

    Используйте этот способ, если вы хотите легко нарисовать текст на плоскости в вашем three.js сцене.

    +
    + + +

    4. Создайте модель в вашем любимом 3D-приложении и экспортируйте в three.js

    +
    +

    Используйте этот способ, если вы предпочитаете работать со своими 3d-приложениями и импортировать модели в three.js .

    +
    + + +

    5. Процедурная геометрия текста

    +
    +

    + Если вы предпочитаете работать исключительно в three.js или создавать процедурные и динамические 3D + текстовые геометрии, вы можете создать mesh, геометрия которой является экземпляром THREE.TextGeometry: +

    +

    + new THREE.TextGeometry( text, parameters ); +

    +

    + Однако для того, чтобы это сработало, вашей текстовой геометрии потребуется экземпляр из THREE.Font + должен быть установлен в его параметре "шрифт". + + Смотрите страницу [page:TextGeometry] для получения дополнительной информации о том, как это можно сделать, описания каждого + принимаемого параметра и список шрифтов JSON, которые поставляются с THREE.js. +

    + +

    Примеры

    + +

    + [example:webgl_geometry_text WebGL / geometry / text]
    + [example:webgl_shadowmap WebGL / shadowmap] +

    + +

    + Если шрифт не работает или вы хотите использовать шрифт, которого там нет, есть учебное пособие по + скрипту python для blender, который позволит экспортировать текст в Three.js в формате JSON: + [link:http://www.jaanga.com/2012/03/blender-to-threejs-create-3d-text-with.html] +

    + +
    + + +

    6. Растровые шрифты

    +
    +

    + Растровые шрифты (bitmap fonts) позволяют группировать глифы в единую BufferGeometry. Рендеринг BMFont + поддерживает перенос слов, межбуквенный интервал, кернинг, поля расстояния со знаком со стандартными + производными, многоканальные поля расстояния со знаком, шрифты с несколькими текстурами и многое другое. + Смотрите [link:https://github.com/felixmariotto/three-mesh-ui three-mesh-ui] или [link:https://github.com/Jam3/three-bmfont-text three-bmfont-text]. +

    +

    + Стандартные шрифты доступны в таких проектах, как + [link:https://github.com/etiennepinchon/aframe-fonts A-Frame Fonts], или вы можете создать свой собственный + из любого .TTF шрифта, оптимизированный для включения только символов, необходимых для проекта. +

    +

    + Некоторые полезные инструменты: +

    +
      +
    • [link:http://msdf-bmfont.donmccurdy.com/ msdf-bmfont-web] (web-based)
    • +
    • [link:https://github.com/soimy/msdf-bmfont-xml msdf-bmfont-xml] (commandline)
    • +
    • [link:https://github.com/libgdx/libgdx/wiki/Hiero hiero] (desktop app)
    • +
    +
    + + +

    7. Текст Тройка (Troika Text)

    +
    +

    + Пакет [link:https://www.npmjs.com/package/troika-three-text troika-three-text] отображает + качественный сглаженный текст, использующий ту же технику, что и BMFonts, но работающий напрямую с любым .TTF + или .WOFF файлом шрифта, чтобы вам не приходилось восстанавливать текстуру глифа в автономном режиме. Он также добавляет + возможности, в том числе: +

    +
      +
    • Такие эффекты, как штрихи, отбрасываемые тени и кривизна
    • +
    • Возможность применять любые three.js Материал, даже пользовательский шейдерный материал
    • +
    • Поддержка лигатур шрифтов, скриптов с соединенными буквами и компоновки справа-налево/двунаправленно
    • +
    • Оптимизация для больших объемов динамического текста, выполнение большей части работы вне основного потока в веб-воркере
    • +
    +
    + + + + diff --git a/docs/manual/ru/introduction/Drawing-lines.html b/docs/manual/ru/introduction/Drawing-lines.html new file mode 100644 index 00000000000000..019e278e143c6b --- /dev/null +++ b/docs/manual/ru/introduction/Drawing-lines.html @@ -0,0 +1,64 @@ + + + + + + + + + +

    Рисование линий ([name])

    +
    +

    + Допустим, вы хотите нарисовать линию или круг, а не каркас [page:Mesh]. + Сначала нам нужно настроить [page:WebGLRenderer renderer](рендеринг), [page:Scene scene](сцену) и камеру (см. страницу Создания сцены). +

    + +

    Вот код, который мы будем использовать:

    + +const renderer = new THREE.WebGLRenderer(); +renderer.setSize( window.innerWidth, window.innerHeight ); +document.body.appendChild( renderer.domElement ); + +const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 500 ); +camera.position.set( 0, 0, 100 ); +camera.lookAt( 0, 0, 0 ); + +const scene = new THREE.Scene(); + +

    Следующее, что мы сделаем, - это определим материал. Для линий мы должны использовать [page:LineBasicMaterial] или [page:LineDashedMaterial].

    + +// создаем синий LineBasicMaterial +const material = new THREE.LineBasicMaterial( { color: 0x0000ff } ); + + +

    + После материала нам понадобится геометрия с некоторыми вершинами: +

    + + +const points = []; +points.push( new THREE.Vector3( - 10, 0, 0 ) ); +points.push( new THREE.Vector3( 0, 10, 0 ) ); +points.push( new THREE.Vector3( 10, 0, 0 ) ); + +const geometry = new THREE.BufferGeometry().setFromPoints( points ); + + +

    Обратите внимание, что линии рисуются между каждой последовательной парой вершин, но не между первой и последней (линия не замкнута).

    + +

    Теперь, когда у нас есть точки для двух линий и материал, мы можем соединить их вместе, чтобы сформировать линию.

    + +const line = new THREE.Line( geometry, material ); + +

    Все, что осталось, это добавить его в сцену и вызвать [page:WebGLRenderer.render render].

    + + +scene.add( line ); +renderer.render( scene, camera ); + + +

    Теперь вы должны увидеть стрелку, направленную вверх, сделанную из двух синих линий.

    +
    + + diff --git a/docs/manual/ru/introduction/FAQ.html b/docs/manual/ru/introduction/FAQ.html new file mode 100644 index 00000000000000..5b1cbfef6470ea --- /dev/null +++ b/docs/manual/ru/introduction/FAQ.html @@ -0,0 +1,63 @@ + + + + + + + + + +

    Часто задаваемые вопросы [name]

    + +

    Какой формат 3D-модели лучше всего поддерживается?

    +
    +

    + Рекомендуемый формат для импорта и экспорта - golf (формат передачи GL). Поскольку glTF ориентирован на доставку ресурсов во время выполнения, он компактен для передачи и быстр для загрузки. +

    +

    + three.js предоставляет загрузчики для многих других популярных форматов, таких как FBX, Collada или OBJ. Тем не менее, вы всегда должны сначала пытаться настроить рабочий процесс на основе glTF в своих проектах. Для получения дополнительной информации см. [link:#manual/introduction/Loading-3D-models loading 3D models] (загрузка 3D-моделей). +

    +
    + +

    Почему в примерах присутствуют теги meta viewport?

    +
    + <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> + +

    + Эти теги управляют размером и масштабом областью просмотра экрана для мобильных браузеров (где содержимое страницы может отображаться с размером, отличным от видимой области просмотра экрана). +

    + +

    [link:https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html Safari: Using the Viewport] (Safari: Использование области видимости экрана)

    + +

    [link:https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag MDN: Using the viewport meta tag] (MDN: Использование мета-тега области видимости экрана)

    +
    + +

    Как можно сохранить масштаб сцены при изменении размера?

    +

    + Мы хотим, чтобы все объекты, независимо от их расстояния от камеры, отображались одинакового размера, даже при изменении размера окна. + + Ключевым уравнением для решения этой проблемы является следующая формула для видимой высоты на заданном расстоянии: + + +visible_height = 2 * Math.tan( ( Math.PI / 180 ) * camera.fov / 2 ) * distance_from_camera; + + Если мы увеличим высоту окна на определенный процент, то мы хотим, чтобы видимая высота на всех расстояниях + увеличилась на тот же процент. Этого нельзя сделать, просто изменив положение камеры. + Вместо этого вы должны изменить поле зрения камеры. + [link:http://jsfiddle.net/Q4Jpu/ Example] (пример). +

    + +

    Почему часть моего объекта невидима?

    +

    + Это может быть связано с определением граней. Грани имеют ориентацию, которая определяет, + какая сторона является какой. И определение удаляет заднюю часть при нормальных условиях. + Чтобы увидеть, это ли ваша проблема, измените сторону материала на THREE.DoubleSide. + material.side = THREE.DoubleSide +

    + +

    Почему three.js иногда возвращает странные результаты для недопустимых входных данных?

    +

    + Из соображений производительности в большинстве случаев three.js не проверяет входные данные. Ваше приложение должно убедиться, что все входные данные действительны. +

    + + diff --git a/docs/manual/ru/introduction/How-to-run-things-locally.html b/docs/manual/ru/introduction/How-to-run-things-locally.html new file mode 100644 index 00000000000000..291166d06ecad4 --- /dev/null +++ b/docs/manual/ru/introduction/How-to-run-things-locally.html @@ -0,0 +1,184 @@ + + + + + + + + + +

    Локальная разработка ([name])

    +

    + Если вы используете только процедурную геометрию и не загружаете никаких текстур, веб-страницы должны работать + прямо из файловой системы, просто дважды щелкните по HTML-файлу в файловом менеджере, и он + должен появиться в браузере (вы увидите file:///вашФайл.html в адресной строке). +

    + +

    Контент загружен из внешних файлов

    +
    +

    + Если вы загружаете модели или текстуры из внешних файлов, из-за того, что браузеры + [link:http://en.wikipedia.org/wiki/Same_origin_policy same origin policy](политика одинакового происхождения) + ограничения безопасности, загрузка из файловой системы завершится ошибкой с исключением безопасности. +

    + +

    + Чтобы решить эту проблему, запустите файлы с локального веб-сервера. Это позволит вам получить доступ к вашей + странице как: +

    + +

    + http://localhost/yourFile.html +

    + +

    + Хотя также можно изменить настройки безопасности браузера вместо запуска локального сервера, + мы не рекомендуем такой подход. Это может открыть ваше устройство для уязвимостей, если + тот же браузер используется для обычного веб-серфинга. Использование локального сервера является стандартной + практикой в + веб-разработки, и ниже мы объясним, как установить и использовать локальный сервер. +

    +
    + + +

    Запуск локального сервера

    +
    +

    + Многие языки программирования имеют встроенные простые HTTP-серверы. Они не так полнофункциональны, как + рабочие серверы, такие как [link:https://www.apache.org/ Apache] или [link:https://nginx.org NGINX], однако их + должно быть достаточно для тестирования вашего + three.js приложение. +

    + +

    Плагины для популярных редакторов кода

    +
    +

    В некоторых редакторах кода есть плагины, которые по запросу создают простой сервер.

    +
      +
    • [link:https://marketplace.visualstudio.com/items?itemName=yandeu.five-server Five Server] для Visual + Studio Code. +
    • +
    • [link:https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer Live Server] для Visual + Studio Code. +
    • +
    • [link:https://atom.io/packages/atom-live-server Live Server] для Atom.
    • +
    • для ide от jetbrains уже все из коробки (как всегда)
    • +
    +
    + +

    Servez

    +
    +

    + [link:https://greggman.github.io/servez Servez] это простой сервер с графическим интерфейсом. +

    +
    + +

    Node.js five-server

    +
    +

    Сервер разработки с возможностью горячей перезагрузки. Установка:

    + + + # Удалите live-server (если он у вас есть) + npm -g rm live-server + + # Установите five-server + npm -g i five-server + + # Обновление five-server (иногда) + npm -g i five-server@latest + + +

    Для запуска (из вашей локальной директории):

    + five-server . -p 8000 +
    + +

    Node.js http-server

    +
    +

    Node.js имеет простой пакет HTTP-сервера. Установка:

    + npm install http-server -g + +

    Для запуска (из вашей локальной директории):

    + http-server . -p 8000 +
    + +

    Python сервер

    +
    +

    + Если у вас установлен [link:http://python.org/ Python], этого должно быть достаточно для запуска + из командной строки (из вашей локальной директории): +

    + + //Python 2.x + python -m SimpleHTTPServer + + //Python 3.x + python -m http.server + + +

    Это поднимет сервер для файлов из текущего каталога на localhost на порте 8000, т.е. в адресной строке + введите:

    + + http://localhost:8000/ +
    + +

    Ruby сервер

    +
    +

    Если у вас установлен Ruby, вы можете получить тот же результат, выполнив:

    + + ruby -r webrick -e "s = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => Dir.pwd); trap('INT') { s.shutdown }; s.start" + +
    + +

    PHP сервер

    +
    +

    PHP также имеет встроенный веб-сервер, начиная с php 5.4.0:

    + php -S localhost:8000 +
    + +

    Lighttpd

    +
    +

    + Lighttpd - это очень легкий веб-сервер общего назначения. Мы рассмотрим установку его на OSX с помощью + HomeBrew. В отличие от других серверов, обсуждаемых здесь, lighttpd является полноценным прод. сервером. +

    + +
      +
    1. + Установка с помощью homebrew + brew install lighttpd +
    2. +
    3. + Создайте конфигурационный файл с именем lighttpd.conf в каталоге, в котором вы хотите запустить + ваш веб-сервер. Пример [link:http://redmine.lighttpd.net/projects/lighttpd/wiki/TutorialConfiguration + here]. +
    4. +
    5. + В файле conf измените корневой каталог server.document на каталог, из которого вы хотите обслуживать + файлы. +
    6. +
    7. + Запуск + lighttpd -f lighttpd.conf +
    8. +
    9. + Перейдите в http://localhost:3000/ и он будет обслуживать статические файлы из каталога, который вы + выбрали. +
    10. +
    +
    +

    IIS

    +
    +

    Если вы используете Microsoft IIS в качестве веб-сервера. Пожалуйста, добавьте настройки типа MIME для + расширения .fbx перед загрузкой.

    + File name extension: fbx MIME Type: text/plain +

    По умолчанию IIS блокирует загрузку файлов .fbx, .obj. Вы должны настроить IIS, чтобы такие файлы можно было + загружать.

    +
    +

    + Другими простыми альтернативами являются [link:http://stackoverflow.com/q/12905426/24874 discussed + here](обсуждается здесь) + на Stack Overflow. +

    +
    + + + diff --git a/docs/manual/ru/introduction/Installation.html b/docs/manual/ru/introduction/Installation.html new file mode 100644 index 00000000000000..c79b43221257c4 --- /dev/null +++ b/docs/manual/ru/introduction/Installation.html @@ -0,0 +1,200 @@ + + + + + + + + + +

    Установка ([name])

    + +

    + Вы можете установить three.js с помощью [link:https://www.npmjs.com/ npm] и современных инструментов сборки или + быстро начните работу со статического хостинга или CDN. Для большинства пользователей установка из npm является + лучшим выбором. +

    + +

    + Что бы вы ни выбрали, будьте последовательны и импортируйте все файлы из одной и той же версии библиотеки. + Смешивание файлов из разных источников может привести к включению дублирующегося кода или даже к неожиданной + поломке + приложения. +

    + + +

    + Все способы установки three.js зависят от модулей ES (см. + [link:https://eloquentjavascript.net/10_modules.html#h_hF2FmOVxw7 Eloquent JavaScript: ECMAScript Modules]), + которые + позволяют включать в конечный проект только те части библиотеки, которые необходимы. +

    + +

    Установка из npm

    + +

    + Чтобы установить [link:https://www.npmjs.com/package/three three] модуль npm, откройте окно терминала в папке + вашего + проекта и запустите: +

    + + + npm install three + + +

    + Пакет будет загружен и установлен. Когда вы будете готовы импортировать его в свой код: +

    + + + // Вариант 1: Импортируйте весь three.js основная библиотека. + import * as THREE from 'three'; + + const scene = new THREE.Scene(); + + + // Вариант 2: Импортируйте только те детали, которые вам нужны. + import { Scene } from 'three'; + + const scene = new Scene(); + + +

    + При установке из npm вы почти всегда будете использовать какой-либо + [link:https://eloquentjavascript.net/10_modules.html#h_zWTXAU93DC bundling tool], чтобы объединить все пакеты, + необходимые вашему проекту, в один файл JavaScript. В то время как любой современный пакет JavaScript можно + использовать с three.js , самым популярным выбором является [link:https://webpack.js.org/ webpack]. +

    + +

    + Не ко всем функциям можно получить доступ непосредственно через модуль three (также называемый "голым + импортом"). Другие популярные части библиотеки, такие как элементы управления, загрузчики и эффекты + постобработки, + должны быть импортированы из подпапки [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm + examples/jsm]. + Чтобы узнать больше, смотрите Примеры ниже. +

    + +

    + Узнайте больше о модулях npm по ссылке [link:https://eloquentjavascript.net/20_node.html#h_J6hW/SmL/a Eloquent + JavaScript: Installing with npm](Выразительный JavaScript: Установка с помощью npm). +

    + +

    Установка с CDN или статического хостинга

    + +

    + В three.js библиотеку можно использовать без какой-либо системы сборки, либо загрузив файлы на свой собственный + веб-сервер, либо используя существующий CDN. Поскольку библиотека полагается на модули ES, любой скрипт, который + ссылается на нее, должен использовать type="module", как показано ниже. + Также требуется определить карту импорта, которая разрешает пустой модуль, указанный как `three`. +

    + + + <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> + + <script type="importmap"> + { + "imports": { + "three": "https://unpkg.com/three@<version>/build/three.module.js" + } + } + </script> + + <script type="module"> + + import * as THREE from 'three'; + + const scene = new THREE.Scene(); + + </script> + + +

    + Поскольку импорт карт еще не поддерживается всеми браузерами, необходимо добавить полифил *es-module-shims.js*. +

    + +

    Дополнения

    + +

    + Ядро three.js сосредоточен на наиболее важных компонентах 3D-движка. Многие другие полезные компоненты, такие + как элементы управления, загрузчики и эффекты постобработки, являются частью каталога + [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm]. Они называются "дополнениями"(addons) (ранее назывались "примерами"(examples)), + потому что, хотя вы можете использовать их в готовом виде, они также предназначены для ремиксов и кастомизации. + Эти компоненты всегда синхронизируются с основной библиотекой, в то время как аналогичные пакеты сторонних + разработчиков в npm поддерживаются разными пользователями и могут быть устаревшими. +

    + +

    + Дополнения не нужно устанавливать отдельно, но их нужно импортировать отдельно. Если three.js был + установлен с помощью npm, вы можете загрузить компонент [page:OrbitControls](Управление орбитой) с помощью: +

    + + + + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + + const controls = new OrbitControls( camera, renderer.domElement ); + + +

    + Если three.js был установлен с CDN, используйте тот же код, но с `three/addons/` в карте импорта. +

    + + + <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> + + <script type="importmap"> + { + "imports": { + "three": "https://unpkg.com/three@<version>/build/three.module.js", + "three/addons/": "https://unpkg.com/three@<version>/examples/jsm/" + } + } + </script> + <script type="module"> + + import * as THREE from 'three'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + + const controls = new OrbitControls( camera, renderer.domElement ); + + </script> + + +

    + Важно, чтобы все файлы использовали одну и ту же версию. Не импортируйте разные дополнения(addons) из разных версий и + не используйте дополнения(addons) из версии, отличной от three.js самой библиотека. +

    + +

    Совместимость

    + +

    CommonJS импорт

    + +

    + В то время как большинство современных пакетов JavaScript теперь поддерживают модули по умолчанию, некоторые + старые + инструменты сборки могут этого не делать. В этих случаях вы, вероятно, можете настроить пакет для подключения + модулей ES: [link:http://browserify.org/ Browserify] просто нужен плагин [link:https://github.com/babel/babelify babelify] , как пример. + +

    + +

    Node.js

    + +

    + Так как three.js создан для Интернета, он зависит от браузера и DOM API, которые не всегда существуют в Node.js. + Некоторые из этих проблем могут быть решены с помощью прослоек, таких как + [link:https://github.com/stackgl/headless-gl headless-gl], или путем замены компонентов, таких как + [page:TextureLoader], пользовательскими альтернативами. Другие API-интерфейсы DOM могут быть глубоко переплетены + с использующим их кодом, и обойти их будет сложнее. + Мы приветствуем простые и поддерживаемые предложения `pull requests` для улучшения поддержки Node.js, но + рекомендуем сначала открыть `issue`(вопрос), чтобы обсудить ваши улучшения. +

    + +

    + Обязательно добавьте `{ "type": "module" }` в свой `package.json`, чтобы включить модули ES6 в ваш проект. +

    + + + diff --git a/docs/manual/ru/introduction/Libraries-and-Plugins.html b/docs/manual/ru/introduction/Libraries-and-Plugins.html new file mode 100644 index 00000000000000..8900a6d9847249 --- /dev/null +++ b/docs/manual/ru/introduction/Libraries-and-Plugins.html @@ -0,0 +1,108 @@ + + + + + + + + + +

    Библиотеки и плагины ([name])

    + +

    + Здесь перечислены совместимые библиотеки и плагины, разработанные опенсорсом для three.js . Этот + список и связанные с ним пакеты поддерживаются сообществом и не гарантируют + их актуальность. Если вы хотите обновить этот список, сделайте PR! +

    + +

    Физика

    + +
      +
    • [link:https://github.com/lo-th/Oimo.js/ Oimo.js]
    • +
    • [link:https://enable3d.io/ enable3d]
    • +
    • [link:https://github.com/kripken/ammo.js/ ammo.js]
    • +
    • [link:https://github.com/pmndrs/cannon-es cannon-es]
    • +
    + +

    Постобработка

    + +

    + В дополнение к [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/postprocessing official three.js postprocessing effects] (оф. эффекты постобработки three.js ], + поддержка некоторых дополнительных эффектов и фреймворков доступна через внешние библиотеки. +

    + +
      +
    • [link:https://github.com/vanruesc/postprocessing postprocessing]
    • +
    + +

    Пересечение и производительность Raycast

    + +
      +
    • [link:https://github.com/gkjohnson/three-mesh-bvh three-mesh-bvh]
    • +
    + +

    Трассировка лучей

    + +
      +
    • [link:https://github.com/gkjohnson/three-gpu-pathtracer three-gpu-pathtracer]
    • +
    + +

    Форматы файлов

    + +

    + В дополнение к [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/loaders official three.js loaders] (оф. three.js загрузчики), + поддержка некоторых дополнительных форматов доступна через внешние библиотеки. +

    + +
      +
    • [link:https://github.com/gkjohnson/urdf-loaders/tree/master/javascript urdf-loader]
    • +
    • [link:https://github.com/NASA-AMMOS/3DTilesRendererJS 3d-tiles-renderer-js]
    • +
    • [link:https://github.com/kaisalmen/WWOBJLoader WebWorker OBJLoader]
    • +
    • [link:https://github.com/IFCjs/web-ifc-three IFC.js]
    • +
    + +

    Геометрия

    + +
      +
    • [link:https://github.com/spite/THREE.MeshLine THREE.MeshLine]
    • +
    + +

    3D Текст и Расположение (3D Text and Layout)

    + +
      +
    • [link:https://github.com/protectwise/troika/tree/master/packages/troika-three-text troika-three-text]
    • +
    • [link:https://github.com/felixmariotto/three-mesh-ui three-mesh-ui]
    • +
    + +

    Системы частиц

    + +
      +
    • [link:https://github.com/creativelifeform/three-nebula three-nebula]
    • +
    + +

    Обратная кинематика

    + +
      +
    • [link:https://github.com/jsantell/THREE.IK THREE.IK]
    • +
    • [link:https://github.com/lo-th/fullik fullik]
    • +
    • [link:https://github.com/gkjohnson/closed-chain-ik-js closed-chain-ik]
    • +
    + +

    Игровой искусственный интеллект

    + +
      +
    • [link:https://mugen87.github.io/yuka/ yuka]
    • +
    • [link:https://github.com/donmccurdy/three-pathfinding three-pathfinding]
    • +
    + +

    Обертки и фреймворки

    + +
      +
    • [link:https://aframe.io/ A-Frame]
    • +
    • [link:https://github.com/pmndrs/react-three-fiber react-three-fiber]
    • +
    • [link:https://github.com/ecsyjs/ecsy-three ECSY]
    • +
    • [link:https://threlte.xyz/ Threlte]
    • +
    + + + diff --git a/docs/manual/ru/introduction/Loading-3D-models.html b/docs/manual/ru/introduction/Loading-3D-models.html new file mode 100644 index 00000000000000..0e95b7849bb7ea --- /dev/null +++ b/docs/manual/ru/introduction/Loading-3D-models.html @@ -0,0 +1,165 @@ + + + + + + + + + + + +

    Загрузка 3D-моделей ([name])

    + +

    + 3D-модели доступны в сотнях форматов, каждый из которых имеет различные + цели, разнообразные функции и различную сложность. Хотя three.js предоставляет множество + + загрузчиков, выбор правильного формата и + рабочего процесса сэкономит время и не разочарует в дальнейшем. С некоторыми форматами + сложно работать, они неэффективны для работы в реальном времени или просто не + поддерживаются в полной мере в настоящее время. +

    + +

    + В этом руководстве представлен рабочий процесс, рекомендуемый для большинства пользователей, и рекомендации + о том, что предпринять, если что-то пойдет не так, как ожидалось. +

    + +

    + +

    + Если вы новичок в управлении локальным сервером, начните с раздела + [link:#manual/introduction/How-to-run-things-locally how to run things locally] (Локальная разработка). + Многих распространенных ошибок при просмотре 3D-моделей можно избежать, правильно разместив файлы. +

    + +

    Прежде чем начать

    + +

    + Там, где это возможно, мы рекомендуем использовать glTF (GL Transmission Format). Оба + .GLB и .GLTF версии формата + хорошо поддерживаются. Поскольку glTF ориентирован на доставку ресурсов во время выполнения, он + компактен для передачи и быстр для загрузки. Объекты включают в себя mesh, материалы, + текстуры, скины, скелеты, цели морфинга, анимацию, освещение и + камеры. +

    + +

    + Файлы glTF, находящиеся в открытом доступе, доступны на таких сайтах, как + + Sketchfab, так же есть различные инструменты включающие экспорт glTF: +

    + + + +

    + Если предпочитаемые вами инструменты не поддерживают glTF, рассмотрите возможность запроса экспорта glTF у авторов или опубликуйте + в ветке glTF roadmap. +

    + +

    + Если glTF не подходит, используйте популярные форматы, такие как FBX, OBJ или COLLADA + также доступны и регулярно обновляются. +

    + +

    Loading

    + +

    + Только несколько загрузчиков (например, [page:ObjectLoader]) включены по умолчанию с + three.js — другие должны быть добавлены в ваше приложение индивидуально. +

    + + + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + + +

    + После того, как вы импортировали загрузчик, вы готовы добавить модель в свою сцену. Синтаксис отличается у + разных загрузчиков — при использовании другого формата ознакомьтесь с примерами и документацией для этого + загрузчика. Для glTF использование с глобальными скриптами было бы: +

    + + + const loader = new GLTFLoader(); + + loader.load( 'path/to/model.glb', function ( gltf ) { + + scene.add( gltf.scene ); + + }, undefined, function ( error ) { + + console.error( error ); + + } ); + + +

    + См. [page:GLTFLoader GLTFLoader documentation] для получения более подробной информации. +

    + +

    Диагностика

    + +

    + Вы потратили часы на создание шедевра ручной работы, загружаете его на + веб—страницу и - о нет! 😭 Он искажен, неправильно окрашен или полностью отсутствует. + Начните с выполнения следующих действий по устранению неполадок: +

    + +
      +
    1. + Проверьте консоль JavaScript на наличие ошибок и убедитесь, что вы использовали + обратный вызов `onError` при вызове `.load()` для регистрации результата. +
    2. +
    3. + Просмотрите модель в другом приложении. Для glTF, средства просмотра с помощью перетаскивания + доступны для + three.js и + babylon.js. Если модель + отображается правильно в одном или нескольких приложениях, + сообщить об ошибке в three.js. + Если модель не может быть показана ни в одном приложении, мы настоятельно рекомендуем предоставить приложение + (можно в песочнице) для воспроизведения бага. +
    4. +
    5. + Попробуйте увеличить или уменьшить масштаб модели в 1000 раз. Многие модели + масштабируются по-разному, и большие модели могут не отображаться, если камера находится + внутри модели. +
    6. +
    7. + Попробуйте добавить и расположить источник света. Модель может быть скрыта в темноте. +
    8. +
    9. + Ищите неудачные запросы текстур на вкладке сеть, например + `"C:\\Path\To\Model\texture.jpg "`. Вместо этого используйте пути относительно вашей + модели, например `images/texture.jpg ` — для этого может потребоваться + редактирование файла модели в текстовом редакторе. +
    10. +
    + +

    Помощь

    + +

    + Если вы прошли шаги описанные выше для устранения неполадок, а ваша модель + по-прежнему не работает, правильный подход это обращение за помощью которое поможет вам + быстрее найти решение. Разместите вопрос на + форуме three.js и, по возможности, + приложите свою модель (или более простую модель с той же проблемой) в любых + доступных вам форматах. Предоставьте достаточно информации, чтобы кто-то другой мог воспроизвести + проблему быстро — в идеале, живая демонстрация. +

    + + + + diff --git a/docs/manual/ru/introduction/Useful-links.html b/docs/manual/ru/introduction/Useful-links.html new file mode 100644 index 00000000000000..3d121c93be9499 --- /dev/null +++ b/docs/manual/ru/introduction/Useful-links.html @@ -0,0 +1,177 @@ + + + + + + + + + +

    Полезные ссылки ([name])

    + +

    + Ниже приведен список ссылок, которые могут оказаться полезными при изучении three.js .
    + Если вы нашли что-то, что хотели бы добавить сюда, или считаете, что одна из приведенных ниже ссылок больше не + актуально или работает, не стесняйтесь нажать кнопку "Редактировать" в правом нижнем углу и внести некоторые изменения!

    + + Отметим также, что в качестве three.js находится в стадии быстрой разработки, многие из этих ссылок будут содержать + устаревшую информацию - если что-то работает не так, как вы ожидаете или как следует по одной из этих ссылок, + проверьте консоль браузера на наличие предупреждений или ошибок. Также проверьте соответствующие страницы документов. +

    + +

    Форумы для помощи

    +

    + Three.js официально использует [link:https://discourse.threejs.org/ forum] и [link: http://stackoverflow.com/tags/three.js/info StackOverflow] для просьб о помощи. + Если вам нужна помощь в чем-то, это то место, куда нужно обратиться. Не открывайте проблему на Github для просьб о помощи. +

    + +

    Учебники и курсы

    + +

    Начало работы с three.js

    +
      +
    • + Основы Three.js фундаментальные знания +
    • +
    • + [link:https://codepen.io/rachsmith/post/beginning-with-3d-webgl-pt-1-the-scene Beginning with 3D WebGL] (Начиная с 3D WebGL) вместе с [link:https://codepen.io/rachsmith/ Rachel Smith]. +
    • +
    • + [link:https://www.august.com.au/blog/animating-scenes-with-webgl-three-js/ Animating scenes with WebGL and three.js] (Анимация сцен с помощью WebGL и three.js) +
    • +
    + +

    Более обширные / продвинутые статьи и курсы

    +
      +
    • + [link:https://threejs-journey.com/ Three Journey] Курс [link:https://bruno-simon.com/ Bruno Simon] - Учит начинающих, как использовать Three.js шаг за шагом +
    • +
    • + [link:https://discoverthreejs.com/ Discover three.js] +
    • +
    • + [link:http://blog.cjgammon.com/ Collection of tutorials] by [link:http://www.cjgammon.com/ CJ Gammon]. +
    • +
    • + [link:https://medium.com/soffritti.pierfrancesco/glossy-spheres-in-three-js-bfd2785d4857 Glossy spheres in three.js]. +
    • +
    • + [link:https://www.udacity.com/course/cs291 Interactive 3D Graphics] - a free course on Udacity that teaches the fundamentals of 3D Graphics, + and uses three.js as its coding tool. +
    • +
    • + [Link:https://aerotwist.com/tutorials/ Aerotwist] tutorials by [link:https://github.com/paullewis/ Paul Lewis]. +
    • +
    • + [link:https://discourse.threejs.org/t/three-js-bookshelf/2468 Three.js Bookshelf] - Ищете больше ресурсов о three.js или компьютерную графику в целом? + Ознакомьтесь с подборкой литературы, рекомендованной сообществом. +
    • +
    + +

    Новости и обновления

    +
      +
    • + [link:https://twitter.com/hashtag/threejs Three.js on Twitter] +
    • +
    • + [link:http://www.reddit.com/r/threejs/ Three.js on reddit] +
    • +
    • + [link:http://www.reddit.com/r/webgl/ WebGL on reddit] +
    • +
    + +

    Примеры

    +
      +
    • + [link:https://github.com/edwinwebb/three-seed/ three-seed] - three.js стартовый проект с ES6 и Webpack +
    • +
    • + [link:http://stemkoski.github.io/Three.js/index.html Professor Stemkoskis Examples] - коллекция примеров удобных для начинающих, + построенные с использованием three.js r60. +
    • +
    • + [link:https://threejs.org/examples/ Official three.js examples] - эти примеры + поддерживаются как часть three.js репозиторий и всегда используйте последнюю версию three.js . +
    • +
    • + [link:https://raw.githack.com/mrdoob/three.js/dev/examples/ Official three.js dev branch examples] - + То же, что и выше, за исключением того, что они используют ветвь dev three.js , и используются для проверки того, что + все работает как когда разрабатывается three.js . +
    • +
    + +

    Инструменты

    +
      +
    • + [link:https://github.com/tbensky/physgl physgl.org] - Внешний интерфейс JavaScript с обертками для three.js, чтобы добавить WebGL + графику для студентов, изучающих физику и математику. +
    • +
    • + [link:https://whsjs.readme.io/ Whitestorm.js] – Модульный фреймворк three.js с физическим плагином AmmoNext. +
    • +
    • + [link:http://zz85.github.io/zz85-bookmarklets/threelabs.html Three.js Inspector] Инспектор Three.js +
    • +
    • + [link:http://idflood.github.io/ThreeNodes.js/ ThreeNodes.js]. +
    • +
    • + [link:https://marketplace.visualstudio.com/items?itemName=slevesque.shader vscode shader] - Подсветка синтаксиса для языка шейдеров. +
      + [link:https://marketplace.visualstudio.com/items?itemName=bierner.comment-tagged-templates vscode comment-tagged-templates] - Подсветка синтаксиса для помеченных строк шаблона с использованием комментариев к языку шейдеров, например: glsl.js. +
    • +
    • + [link:https://github.com/MozillaReality/WebXR-emulator-extension WebXR-emulator-extension] +
    • +
    + +

    Ссылки на WebGL

    +
      +
    • + [link:https://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf webgl-reference-card.pdf] - Ссылка на все ключевые слова WebGL и GLSL, терминологию, синтаксис и определения. +
    • +
    + +

    Старые ссылки

    +

    + Эти ссылки сохранены в исторических целях - вы все еще можете найти их полезными, но имейте в виду, что + они могут содержать информацию, относящуюся к очень старым версиям three.js . +

    + +
      +
    • + AlterQualia at WebGL Camp 3 +
    • +
    • + [link:http://yomotsu.github.io/threejs-examples/ Yomotsus Examples] - коллекция примеров, использующих three.js r45. +
    • +
    • + [link:http://fhtr.org/BasicsOfThreeJS/#1 Introduction to Three.js] by [link:http://github.com/kig/ Ilmari Heikkinen] (слайд-шоу). +
    • +
    • + [link:http://www.slideshare.net/yomotsu/webgl-and-threejs WebGL and Three.js] by [link:http://github.com/yomotsu Akihiro Oyamada] (слайд-шоу). +
    • +
    • + Trigger Rally by [link:https://github.com/jareiko jareiko] (видео). +
    • +
    • + [link:http://blackjk3.github.io/threefab/ ThreeFab] - редактор сцен, поддерживаемый примерно до three.js r50. +
    • +
    • + [link:http://bkcore.com/blog/3d/webgl-three-js-workflow-tips.html Max to Three.js workflow tips and tricks] by [link:https://github.com/BKcore BKcore] +
    • +
    • + [link:http://12devsofxmas.co.uk/2012/01/webgl-and-three-js/ A whirlwind look at Three.js] + by [link:http://github.com/nrocy Paul King] +
    • +
    • + [link:http://bkcore.com/blog/3d/webgl-three-js-animated-selective-glow.html Animated selective glow in Three.js] + by [link:https://github.com/BKcore BKcore] +
    • +
    • + [link:http://www.natural-science.or.jp/article/20120220155529.php Building A Physics Simulation Environment] - three.js учебное пособие на японском языке +
    • +
    + + + diff --git a/docs/manual/ru/introduction/WebGL-compatibility-check.html b/docs/manual/ru/introduction/WebGL-compatibility-check.html new file mode 100644 index 00000000000000..3ceef1f546f1e2 --- /dev/null +++ b/docs/manual/ru/introduction/WebGL-compatibility-check.html @@ -0,0 +1,35 @@ + + + + + + + + + +

    Проверка совместимости с WebGL ([name])

    +

    + Несмотря на то, что это становится все менее и менее серьезной проблемой, но все еще некоторые устройства или браузеры могут не поддерживать WebGL. + Следующий метод позволяет вам проверить, поддерживается ли он, и отобразить сообщение пользователю, если это не так. +

    + +

    + Добавьте [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/capabilities/WebGL.js] + к вашему javascript и выполните следующее, прежде чем пытаться что-либо отобразить. +

    + + + if ( WebGL.isWebGLAvailable() ) { + + // Инициализируйте функцию или другие инициализации здесь + animate(); + + } else { + + const warning = WebGL.getWebGLErrorMessage(); + document.getElementById( 'container' ).appendChild( warning ); + + } + + + diff --git a/docs/manual/zh/introduction/How-to-create-VR-content.html b/docs/manual/zh/introduction/How-to-create-VR-content.html index c6962b7adee205..37d6c3c7b5c5a5 100644 --- a/docs/manual/zh/introduction/How-to-create-VR-content.html +++ b/docs/manual/zh/introduction/How-to-create-VR-content.html @@ -23,7 +23,7 @@

    工作流程

    -import { VRButton } from 'three/examples/jsm/webxr/VRButton.js'; +import { VRButton } from 'three/addons/webxr/VRButton.js';

    *VRButton.createButton()*做了两件重要的事情:首先,它创建了一个按钮,指示了VR的兼容性; diff --git a/docs/manual/zh/introduction/How-to-use-post-processing.html b/docs/manual/zh/introduction/How-to-use-post-processing.html index ad26fbfac0950f..5007e574870c5d 100644 --- a/docs/manual/zh/introduction/How-to-use-post-processing.html +++ b/docs/manual/zh/introduction/How-to-use-post-processing.html @@ -28,9 +28,9 @@

    工作流程

    - import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'; - import { GlitchPass } from 'three/examples/jsm/postprocessing/GlitchPass.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { GlitchPass } from 'three/addons/postprocessing/GlitchPass.js';

    @@ -92,8 +92,8 @@

    自定义过程

    - import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'; - import { LuminosityShader } from 'three/examples/jsm/shaders/LuminosityShader.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { LuminosityShader } from 'three/addons/shaders/LuminosityShader.js'; // later in your init routine diff --git a/docs/manual/zh/introduction/Installation.html b/docs/manual/zh/introduction/Installation.html index b8bb654906b467..68d9e914a17e69 100644 --- a/docs/manual/zh/introduction/Installation.html +++ b/docs/manual/zh/introduction/Installation.html @@ -67,23 +67,26 @@

    从CDN或静态主机安装

    - <script type="module"> + <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> + + <script type="importmap"> + { + "imports": { + "three": "https://unpkg.com/three@<version>/build/three.module.js" + } + } + </script> - // 通过访问 https://cdn.skypack.dev/three 来查找最新版本。 + <script type="module"> - import * as THREE from 'https://cdn.skypack.dev/three@<version>'; + import * as THREE from 'three'; - const scene = new THREE.Scene(); + const scene = new THREE.Scene(); </script> -

    - 并非所有功能都可以通过 build/three.module.js 模块来直接访问。three.js 中其它较为流行的部分 —— 如控制器(control)、加载器(loader)以及后期处理效果(post-processing effect) —— 必须从 [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm] 子目录下导入。了解更多信息,请参阅下方的示例。 -

    - - -

    示例

    +

    Addons

    three.js的核心专注于3D引擎最重要的组件。其它很多有用的组件 —— 如控制器(control)、加载器(loader)以及后期处理效果(post-processing effect) —— 是 [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm] 目录的一部分。它们被称为“示例”,虽然你可以直接将它们拿来使用,但它们也需要重新混合以及定制。这些组件和 three.js 的核心保持同步,而 npm 上类似的第三方包则由不同的作者进行维护,可能不是最新的。 @@ -95,7 +98,7 @@

    示例

    - import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; const controls = new OrbitControls( camera, renderer.domElement ); @@ -105,13 +108,23 @@

    示例

    - <script type="module"> + <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> + + <script type="importmap"> + { + "imports": { + "three": "https://unpkg.com/three@<version>/build/three.module.js", + "three/addons/": "https://unpkg.com/three@<version>/examples/jsm/" + } + } + </script> - // 通过访问 https://cdn.skypack.dev/three 来查找最新版本。 + <script type="module"> - import { OrbitControls } from 'https://cdn.skypack.dev/three@<version>/examples/jsm/controls/OrbitControls.js'; + import * as THREE from 'three'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - const controls = new OrbitControls( camera, renderer.domElement ); + const controls = new OrbitControls( camera, renderer.domElement ); </script> diff --git a/docs/manual/zh/introduction/Loading-3D-models.html b/docs/manual/zh/introduction/Loading-3D-models.html index 442e04d64e8501..eec092662d967b 100644 --- a/docs/manual/zh/introduction/Loading-3D-models.html +++ b/docs/manual/zh/introduction/Loading-3D-models.html @@ -73,7 +73,7 @@

    加载

    - import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

    diff --git a/docs/manual/zh/introduction/Useful-links.html b/docs/manual/zh/introduction/Useful-links.html index e107424537a8e7..a171ef4f947ac0 100644 --- a/docs/manual/zh/introduction/Useful-links.html +++ b/docs/manual/zh/introduction/Useful-links.html @@ -59,9 +59,6 @@

    更加广泛、高级的文章与教程

  • [Link:https://aerotwist.com/tutorials/ Aerotwist] tutorials by [link:https://github.com/paullewis/ Paul Lewis]. -
  • -
  • - [link:http://learningthreejs.com/ Learning Three.js] – a blog with articles dedicated to teaching three.js
  • [link:https://discourse.threejs.org/t/three-js-bookshelf/2468 Three.js Bookshelf] - Looking for more resources about three.js or computer graphics in general? diff --git a/docs/scenes/bones-browser.html b/docs/scenes/bones-browser.html index 4333429e511885..4695eb29a5753d 100644 --- a/docs/scenes/bones-browser.html +++ b/docs/scenes/bones-browser.html @@ -30,7 +30,8 @@ @@ -56,8 +57,8 @@ WebGLRenderer } from 'three'; - import { GUI } from '../../examples/jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from '../../examples/jsm/controls/OrbitControls.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let gui, scene, camera, renderer, orbit, lights, mesh, bones, skeletonHelper; diff --git a/docs/scenes/ccdiksolver-browser.html b/docs/scenes/ccdiksolver-browser.html index 3072de60242c40..17e0f857840998 100644 --- a/docs/scenes/ccdiksolver-browser.html +++ b/docs/scenes/ccdiksolver-browser.html @@ -30,7 +30,8 @@ @@ -58,10 +59,10 @@ Uint16BufferAttribute, WebGLRenderer } from 'three'; - import { CCDIKSolver, CCDIKHelper } from '../../examples/jsm/animation/CCDIKSolver.js'; + import { CCDIKSolver, CCDIKHelper } from 'three/addons/animation/CCDIKSolver.js'; - import { GUI } from '../../examples/jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from '../../examples/jsm/controls/OrbitControls.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let gui, scene, camera, renderer, orbit, mesh, bones, skeletonHelper, ikSolver; @@ -223,9 +224,9 @@ folder.add( bone.position, 'x', - delta + bone.position.x, delta + bone.position.x ); folder.add( bone.position, 'y', - bone.position.y, bone.position.y ); folder.add( bone.position, 'z', - delta + bone.position.z, delta + bone.position.z ); - + } ); - + gui.add( ikSolver, 'update' ).name( 'ikSolver.update()' ); gui.add( state, 'ikSolverAutoUpdate' ); diff --git a/docs/scenes/geometry-browser.html b/docs/scenes/geometry-browser.html index caeac744e97a43..cd5c86375ddb01 100644 --- a/docs/scenes/geometry-browser.html +++ b/docs/scenes/geometry-browser.html @@ -30,7 +30,8 @@ @@ -77,8 +78,8 @@ WebGLRenderer } from 'three'; - import { GUI } from '../../examples/jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from '../../examples/jsm/controls/OrbitControls.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; const twoPi = Math.PI * 2; @@ -172,13 +173,13 @@ radius: 5, length: 5, capSegments: 10, - heightSegments: 20 + radialSegments: 20 }; function generateGeometry() { updateGroupGeometry( mesh, - new CapsuleGeometry( data.radius, data.length, data.capSegments, data.heightSegments ), + new CapsuleGeometry( data.radius, data.length, data.capSegments, data.radialSegments ), ); } @@ -188,7 +189,7 @@ folder.add( data, 'radius', 1, 30 ).onChange( generateGeometry ); folder.add( data, 'length', 1, 30 ).onChange( generateGeometry ); folder.add( data, 'capSegments', 1, 32 ).step( 1 ).onChange( generateGeometry ); - folder.add( data, 'heightSegments', 1, 64 ).step( 1 ).onChange( generateGeometry ); + folder.add( data, 'radialSegments', 1, 64 ).step( 1 ).onChange( generateGeometry ); generateGeometry(); diff --git a/docs/scenes/material-browser.html b/docs/scenes/material-browser.html index 5d2e9dfb12cf18..2608341d21b2d2 100644 --- a/docs/scenes/material-browser.html +++ b/docs/scenes/material-browser.html @@ -30,7 +30,8 @@ @@ -40,8 +41,8 @@ - @@ -25,6 +23,8 @@ + + @@ -47,12 +47,13 @@ - + @@ -69,7 +70,7 @@ import { Sidebar } from './js/Sidebar.js'; import { Menubar } from './js/Menubar.js'; import { Resizer } from './js/Resizer.js'; - import { VRButton } from '../examples/jsm/webxr/VRButton.js'; + import { VRButton } from 'three/addons/webxr/VRButton.js'; window.URL = window.URL || window.webkitURL; window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder; diff --git a/editor/js/Loader.js b/editor/js/Loader.js index 18ac71481f6bf5..d7f3345e3e99b9 100644 --- a/editor/js/Loader.js +++ b/editor/js/Loader.js @@ -1,13 +1,13 @@ import * as THREE from 'three'; -import { TGALoader } from '../../examples/jsm/loaders/TGALoader.js'; +import { TGALoader } from 'three/addons/loaders/TGALoader.js'; import { AddObjectCommand } from './commands/AddObjectCommand.js'; import { SetSceneCommand } from './commands/SetSceneCommand.js'; import { LoaderUtils } from './LoaderUtils.js'; -import { unzipSync, strFromU8 } from '../../examples/jsm/libs/fflate.module.js'; +import { unzipSync, strFromU8 } from 'three/addons/libs/fflate.module.js'; function Loader( editor ) { @@ -87,7 +87,7 @@ function Loader( editor ) { const contents = event.target.result; - const { Rhino3dmLoader } = await import( '../../examples/jsm/loaders/3DMLoader.js' ); + const { Rhino3dmLoader } = await import( 'three/addons/loaders/3DMLoader.js' ); const loader = new Rhino3dmLoader(); loader.setLibraryPath( '../examples/jsm/libs/rhino3dm/' ); @@ -110,7 +110,7 @@ function Loader( editor ) { reader.addEventListener( 'load', async function ( event ) { - const { TDSLoader } = await import( '../../examples/jsm/loaders/TDSLoader.js' ); + const { TDSLoader } = await import( 'three/addons/loaders/TDSLoader.js' ); const loader = new TDSLoader(); const object = loader.parse( event.target.result ); @@ -130,7 +130,7 @@ function Loader( editor ) { reader.addEventListener( 'load', async function ( event ) { - const { ThreeMFLoader } = await import( '../../examples/jsm/loaders/3MFLoader.js' ); + const { ThreeMFLoader } = await import( 'three/addons/loaders/3MFLoader.js' ); const loader = new ThreeMFLoader(); const object = loader.parse( event.target.result ); @@ -150,7 +150,7 @@ function Loader( editor ) { reader.addEventListener( 'load', async function ( event ) { - const { AMFLoader } = await import( '../../examples/jsm/loaders/AMFLoader.js' ); + const { AMFLoader } = await import( 'three/addons/loaders/AMFLoader.js' ); const loader = new AMFLoader(); const amfobject = loader.parse( event.target.result ); @@ -172,7 +172,7 @@ function Loader( editor ) { const contents = event.target.result; - const { ColladaLoader } = await import( '../../examples/jsm/loaders/ColladaLoader.js' ); + const { ColladaLoader } = await import( 'three/addons/loaders/ColladaLoader.js' ); const loader = new ColladaLoader( manager ); const collada = loader.parse( contents ); @@ -196,7 +196,7 @@ function Loader( editor ) { const contents = event.target.result; - const { DRACOLoader } = await import( '../../examples/jsm/loaders/DRACOLoader.js' ); + const { DRACOLoader } = await import( 'three/addons/loaders/DRACOLoader.js' ); const loader = new DRACOLoader(); loader.setDecoderPath( '../examples/js/libs/draco/' ); @@ -241,7 +241,7 @@ function Loader( editor ) { const contents = event.target.result; - const { FBXLoader } = await import( '../../examples/jsm/loaders/FBXLoader.js' ); + const { FBXLoader } = await import( 'three/addons/loaders/FBXLoader.js' ); const loader = new FBXLoader( manager ); const object = loader.parse( contents ); @@ -263,8 +263,8 @@ function Loader( editor ) { const contents = event.target.result; - const { DRACOLoader } = await import( '../../examples/jsm/loaders/DRACOLoader.js' ); - const { GLTFLoader } = await import( '../../examples/jsm/loaders/GLTFLoader.js' ); + const { DRACOLoader } = await import( 'three/addons/loaders/DRACOLoader.js' ); + const { GLTFLoader } = await import( 'three/addons/loaders/GLTFLoader.js' ); const dracoLoader = new DRACOLoader(); dracoLoader.setDecoderPath( '../examples/js/libs/draco/gltf/' ); @@ -304,8 +304,8 @@ function Loader( editor ) { } else { - const { DRACOLoader } = await import( '../../examples/jsm/loaders/DRACOLoader.js' ); - const { GLTFLoader } = await import( '../../examples/jsm/loaders/GLTFLoader.js' ); + const { DRACOLoader } = await import( 'three/addons/loaders/DRACOLoader.js' ); + const { GLTFLoader } = await import( 'three/addons/loaders/GLTFLoader.js' ); const dracoLoader = new DRACOLoader(); dracoLoader.setDecoderPath( '../examples/js/libs/draco/gltf/' ); @@ -393,10 +393,10 @@ function Loader( editor ) { reader.addEventListener( 'load', async function ( event ) { - const { IFCLoader } = await import( '../../examples/jsm/loaders/IFCLoader.js' ); + const { IFCLoader } = await import( 'three/addons/loaders/IFCLoader.js' ); - const loader = new IFCLoader(); - loader.ifcManager.setWasmPath( '../../examples/jsm/loaders/ifc/' ); + var loader = new IFCLoader(); + loader.ifcManager.setWasmPath( 'three/addons/loaders/ifc/' ); const model = await loader.parse( event.target.result ); model.mesh.name = filename; @@ -416,7 +416,7 @@ function Loader( editor ) { reader.addEventListener( 'load', async function ( event ) { - const { KMZLoader } = await import( '../../examples/jsm/loaders/KMZLoader.js' ); + const { KMZLoader } = await import( 'three/addons/loaders/KMZLoader.js' ); const loader = new KMZLoader(); const collada = loader.parse( event.target.result ); @@ -439,7 +439,7 @@ function Loader( editor ) { reader.addEventListener( 'load', async function ( event ) { - const { LDrawLoader } = await import( '../../examples/jsm/loaders/LDrawLoader.js' ); + const { LDrawLoader } = await import( 'three/addons/loaders/LDrawLoader.js' ); const loader = new LDrawLoader(); loader.setPath( '../../examples/models/ldraw/officialLibrary/' ); @@ -468,7 +468,7 @@ function Loader( editor ) { const contents = event.target.result; - const { MD2Loader } = await import( '../../examples/jsm/loaders/MD2Loader.js' ); + const { MD2Loader } = await import( 'three/addons/loaders/MD2Loader.js' ); const geometry = new MD2Loader().parse( contents ); const material = new THREE.MeshStandardMaterial(); @@ -495,7 +495,7 @@ function Loader( editor ) { const contents = event.target.result; - const { OBJLoader } = await import( '../../examples/jsm/loaders/OBJLoader.js' ); + const { OBJLoader } = await import( 'three/addons/loaders/OBJLoader.js' ); const object = new OBJLoader().parse( contents ); object.name = filename; @@ -539,7 +539,7 @@ function Loader( editor ) { const contents = event.target.result; - const { PLYLoader } = await import( '../../examples/jsm/loaders/PLYLoader.js' ); + const { PLYLoader } = await import( 'three/addons/loaders/PLYLoader.js' ); const geometry = new PLYLoader().parse( contents ); let object; @@ -578,7 +578,7 @@ function Loader( editor ) { const contents = event.target.result; - const { STLLoader } = await import( '../../examples/jsm/loaders/STLLoader.js' ); + const { STLLoader } = await import( 'three/addons/loaders/STLLoader.js' ); const geometry = new STLLoader().parse( contents ); const material = new THREE.MeshStandardMaterial(); @@ -612,7 +612,7 @@ function Loader( editor ) { const contents = event.target.result; - const { SVGLoader } = await import( '../../examples/jsm/loaders/SVGLoader.js' ); + const { SVGLoader } = await import( 'three/addons/loaders/SVGLoader.js' ); const loader = new SVGLoader(); const paths = loader.parse( contents ).paths; @@ -656,6 +656,28 @@ function Loader( editor ) { } + case 'usdz': + + { + + reader.addEventListener( 'load', async function ( event ) { + + const contents = event.target.result; + + const { USDZLoader } = await import( '../../examples/jsm/loaders/USDZLoader.js' ); + + const group = new USDZLoader().parse( contents ); + group.name = filename; + + editor.execute( new AddObjectCommand( editor, group ) ); + + }, false ); + reader.readAsArrayBuffer( file ); + + break; + + } + case 'vox': { @@ -664,7 +686,7 @@ function Loader( editor ) { const contents = event.target.result; - const { VOXLoader, VOXMesh } = await import( '../../examples/jsm/loaders/VOXLoader.js' ); + const { VOXLoader, VOXMesh } = await import( 'three/addons/loaders/VOXLoader.js' ); const chunks = new VOXLoader().parse( contents ); @@ -698,7 +720,7 @@ function Loader( editor ) { const contents = event.target.result; - const { VTKLoader } = await import( '../../examples/jsm/loaders/VTKLoader.js' ); + const { VTKLoader } = await import( 'three/addons/loaders/VTKLoader.js' ); const geometry = new VTKLoader().parse( contents ); const material = new THREE.MeshStandardMaterial(); @@ -723,7 +745,7 @@ function Loader( editor ) { const contents = event.target.result; - const { VRMLLoader } = await import( '../../examples/jsm/loaders/VRMLLoader.js' ); + const { VRMLLoader } = await import( 'three/addons/loaders/VRMLLoader.js' ); const result = new VRMLLoader().parse( contents ); @@ -744,7 +766,7 @@ function Loader( editor ) { const contents = event.target.result; - const { XYZLoader } = await import( '../../examples/jsm/loaders/XYZLoader.js' ); + const { XYZLoader } = await import( 'three/addons/loaders/XYZLoader.js' ); const geometry = new XYZLoader().parse( contents ); @@ -874,8 +896,8 @@ function Loader( editor ) { if ( zip[ 'model.obj' ] && zip[ 'materials.mtl' ] ) { - const { MTLLoader } = await import( '../../examples/jsm/loaders/MTLLoader.js' ); - const { OBJLoader } = await import( '../../examples/jsm/loaders/OBJLoader.js' ); + const { MTLLoader } = await import( 'three/addons/loaders/MTLLoader.js' ); + const { OBJLoader } = await import( 'three/addons/loaders/OBJLoader.js' ); const materials = new MTLLoader().parse( strFromU8( zip[ 'materials.mtl' ] ) ); const object = new OBJLoader().setMaterials( materials ).parse( strFromU8( zip[ 'model.obj' ] ) ); @@ -915,7 +937,7 @@ function Loader( editor ) { { - const { FBXLoader } = await import( '../../examples/jsm/loaders/FBXLoader.js' ); + const { FBXLoader } = await import( 'three/addons/loaders/FBXLoader.js' ); const loader = new FBXLoader( manager ); const object = loader.parse( file.buffer ); @@ -930,8 +952,8 @@ function Loader( editor ) { { - const { DRACOLoader } = await import( '../../examples/jsm/loaders/DRACOLoader.js' ); - const { GLTFLoader } = await import( '../../examples/jsm/loaders/GLTFLoader.js' ); + const { DRACOLoader } = await import( 'three/addons/loaders/DRACOLoader.js' ); + const { GLTFLoader } = await import( 'three/addons/loaders/GLTFLoader.js' ); const dracoLoader = new DRACOLoader(); dracoLoader.setDecoderPath( '../examples/js/libs/draco/gltf/' ); @@ -956,8 +978,8 @@ function Loader( editor ) { { - const { DRACOLoader } = await import( '../../examples/jsm/loaders/DRACOLoader.js' ); - const { GLTFLoader } = await import( '../../examples/jsm/loaders/GLTFLoader.js' ); + const { DRACOLoader } = await import( 'three/addons/loaders/DRACOLoader.js' ); + const { GLTFLoader } = await import( 'three/addons/loaders/GLTFLoader.js' ); const dracoLoader = new DRACOLoader(); dracoLoader.setDecoderPath( '../examples/js/libs/draco/gltf/' ); diff --git a/editor/js/Menubar.File.js b/editor/js/Menubar.File.js index 11932144c841fb..1dc357728b1e2e 100644 --- a/editor/js/Menubar.File.js +++ b/editor/js/Menubar.File.js @@ -1,6 +1,6 @@ import * as THREE from 'three'; -import { zipSync, strToU8 } from '../../examples/jsm/libs/fflate.module.js'; +import { zipSync, strToU8 } from 'three/addons/libs/fflate.module.js'; import { UIPanel, UIRow, UIHorizontalRule } from './libs/ui.js'; @@ -185,7 +185,7 @@ function MenubarFile( editor ) { option.setTextContent( strings.getKey( 'menubar/file/export/dae' ) ); option.onClick( async function () { - const { ColladaExporter } = await import( '../../examples/jsm/exporters/ColladaExporter.js' ); + const { ColladaExporter } = await import( 'three/addons/exporters/ColladaExporter.js' ); const exporter = new ColladaExporter(); @@ -214,7 +214,7 @@ function MenubarFile( editor ) { } - const { DRACOExporter } = await import( '../../examples/jsm/exporters/DRACOExporter.js' ); + const { DRACOExporter } = await import( 'three/addons/exporters/DRACOExporter.js' ); const exporter = new DRACOExporter(); @@ -245,7 +245,7 @@ function MenubarFile( editor ) { const scene = editor.scene; const animations = getAnimations( scene ); - const { GLTFExporter } = await import( '../../examples/jsm/exporters/GLTFExporter.js' ); + const { GLTFExporter } = await import( 'three/addons/exporters/GLTFExporter.js' ); const exporter = new GLTFExporter(); @@ -268,7 +268,7 @@ function MenubarFile( editor ) { const scene = editor.scene; const animations = getAnimations( scene ); - const { GLTFExporter } = await import( '../../examples/jsm/exporters/GLTFExporter.js' ); + const { GLTFExporter } = await import( 'three/addons/exporters/GLTFExporter.js' ); const exporter = new GLTFExporter(); @@ -298,7 +298,7 @@ function MenubarFile( editor ) { } - const { OBJExporter } = await import( '../../examples/jsm/exporters/OBJExporter.js' ); + const { OBJExporter } = await import( 'three/addons/exporters/OBJExporter.js' ); const exporter = new OBJExporter(); @@ -314,7 +314,7 @@ function MenubarFile( editor ) { option.setTextContent( strings.getKey( 'menubar/file/export/ply' ) ); option.onClick( async function () { - const { PLYExporter } = await import( '../../examples/jsm/exporters/PLYExporter.js' ); + const { PLYExporter } = await import( 'three/addons/exporters/PLYExporter.js' ); const exporter = new PLYExporter(); @@ -334,7 +334,7 @@ function MenubarFile( editor ) { option.setTextContent( strings.getKey( 'menubar/file/export/ply_binary' ) ); option.onClick( async function () { - const { PLYExporter } = await import( '../../examples/jsm/exporters/PLYExporter.js' ); + const { PLYExporter } = await import( 'three/addons/exporters/PLYExporter.js' ); const exporter = new PLYExporter(); @@ -354,7 +354,7 @@ function MenubarFile( editor ) { option.setTextContent( strings.getKey( 'menubar/file/export/stl' ) ); option.onClick( async function () { - const { STLExporter } = await import( '../../examples/jsm/exporters/STLExporter.js' ); + const { STLExporter } = await import( 'three/addons/exporters/STLExporter.js' ); const exporter = new STLExporter(); @@ -370,7 +370,7 @@ function MenubarFile( editor ) { option.setTextContent( strings.getKey( 'menubar/file/export/stl_binary' ) ); option.onClick( async function () { - const { STLExporter } = await import( '../../examples/jsm/exporters/STLExporter.js' ); + const { STLExporter } = await import( 'three/addons/exporters/STLExporter.js' ); const exporter = new STLExporter(); @@ -386,7 +386,7 @@ function MenubarFile( editor ) { option.setTextContent( strings.getKey( 'menubar/file/export/usdz' ) ); option.onClick( async function () { - const { USDZExporter } = await import( '../../examples/jsm/exporters/USDZExporter.js' ); + const { USDZExporter } = await import( 'three/addons/exporters/USDZExporter.js' ); const exporter = new USDZExporter(); diff --git a/editor/js/Sidebar.Geometry.TeapotGeometry.js b/editor/js/Sidebar.Geometry.TeapotGeometry.js index db0b237297f376..e51d1639331d6f 100644 --- a/editor/js/Sidebar.Geometry.TeapotGeometry.js +++ b/editor/js/Sidebar.Geometry.TeapotGeometry.js @@ -1,6 +1,6 @@ import { UIDiv, UIRow, UIText, UIInteger, UICheckbox, UINumber } from './libs/ui.js'; -import { TeapotGeometry } from '../../examples/jsm/geometries/TeapotGeometry.js'; +import { TeapotGeometry } from 'three/addons/geometries/TeapotGeometry.js'; function GeometryParametersPanel( signals, object ) { diff --git a/editor/js/Sidebar.Geometry.js b/editor/js/Sidebar.Geometry.js index efcd520f17d955..01f1aaf6a71bf0 100644 --- a/editor/js/Sidebar.Geometry.js +++ b/editor/js/Sidebar.Geometry.js @@ -7,7 +7,7 @@ import { SetGeometryValueCommand } from './commands/SetGeometryValueCommand.js'; import { SidebarGeometryBufferGeometry } from './Sidebar.Geometry.BufferGeometry.js'; import { SidebarGeometryModifiers } from './Sidebar.Geometry.Modifiers.js'; -import { VertexNormalsHelper } from '../../examples/jsm/helpers/VertexNormalsHelper.js'; +import { VertexNormalsHelper } from 'three/addons/helpers/VertexNormalsHelper.js'; function SidebarGeometry( editor ) { diff --git a/editor/js/Sidebar.Material.js b/editor/js/Sidebar.Material.js index b700658d76b88a..43d46b02adb2f0 100644 --- a/editor/js/Sidebar.Material.js +++ b/editor/js/Sidebar.Material.js @@ -146,6 +146,21 @@ function SidebarMaterial( editor ) { const materialIridescenceThicknessMax = new SidebarMaterialRangeValueProperty( editor, 'iridescenceThicknessRange', strings.getKey( 'sidebar/material/iridescenceThicknessMax' ), false, [ 0, Infinity ], 0, 10, 1, 'nm' ); container.add( materialIridescenceThicknessMax ); + // sheen + + const materialSheen = new SidebarMaterialNumberProperty( editor, 'sheen', strings.getKey( 'sidebar/material/sheen' ), [ 0, 1 ] ); + container.add( materialSheen ); + + // sheen roughness + + const materialSheenRoughness = new SidebarMaterialNumberProperty( editor, 'sheenRoughness', strings.getKey( 'sidebar/material/sheenroughness' ), [ 0, 1 ] ); + container.add( materialSheenRoughness ); + + // sheen color + + const materialSheenColor = new SidebarMaterialColorProperty( editor, 'sheenColor', strings.getKey( 'sidebar/material/sheencolor' ) ); + container.add( materialSheenColor ); + // transmission const materialTransmission = new SidebarMaterialNumberProperty( editor, 'transmission', strings.getKey( 'sidebar/material/transmission' ), [ 0, 1 ] ); @@ -241,6 +256,16 @@ function SidebarMaterial( editor ) { const materialIridescenceMap = new SidebarMaterialMapProperty( editor, 'iridescenceMap', strings.getKey( 'sidebar/material/iridescencemap' ) ); container.add( materialIridescenceMap ); + // sheen color map + + const materialSheenColorMap = new SidebarMaterialMapProperty( editor, 'sheenColorMap', strings.getKey( 'sidebar/material/sheencolormap' ) ); + container.add( materialSheenColorMap ); + + // sheen roughness map + + const materialSheenRoughnessMap = new SidebarMaterialMapProperty( editor, 'sheenRoughnessMap', strings.getKey( 'sidebar/material/sheenroughnessmap' ) ); + container.add( materialSheenRoughnessMap ); + // iridescence thickness map const materialIridescenceThicknessMap = new SidebarMaterialMapProperty( editor, 'iridescenceThicknessMap', strings.getKey( 'sidebar/material/iridescencethicknessmap' ) ); @@ -266,6 +291,16 @@ function SidebarMaterial( editor ) { const materialGradientMap = new SidebarMaterialMapProperty( editor, 'gradientMap', strings.getKey( 'sidebar/material/gradientmap' ) ); container.add( materialGradientMap ); + // transmission map + + const transmissionMap = new SidebarMaterialMapProperty( editor, 'transmissionMap', strings.getKey( 'sidebar/material/transmissionmap' ) ); + container.add( transmissionMap ); + + // thickness map + + const thicknessMap = new SidebarMaterialMapProperty( editor, 'thicknessMap', strings.getKey( 'sidebar/material/thicknessmap' ) ); + container.add( thicknessMap ); + // side const materialSideOptions = { diff --git a/editor/js/Sidebar.Scene.js b/editor/js/Sidebar.Scene.js index bc09377528970b..e544353f779749 100644 --- a/editor/js/Sidebar.Scene.js +++ b/editor/js/Sidebar.Scene.js @@ -185,13 +185,23 @@ function SidebarScene( editor ) { container.add( backgroundRow ); + const backgroundEquirectRow = new UIRow(); + backgroundEquirectRow.setDisplay( 'none' ); + backgroundEquirectRow.setMarginLeft( '90px' ); + + const backgroundBlurriness = new UINumber( 0 ).setWidth( '40px' ).setRange( 0, 1 ).onChange( onBackgroundChanged ); + backgroundEquirectRow.add( backgroundBlurriness ); + + container.add( backgroundEquirectRow ); + function onBackgroundChanged() { signals.sceneBackgroundChanged.dispatch( backgroundType.getValue(), backgroundColor.getHexValue(), backgroundTexture.getValue(), - backgroundEquirectangularTexture.getValue() + backgroundEquirectangularTexture.getValue(), + backgroundBlurriness.getValue() ); } @@ -204,6 +214,7 @@ function SidebarScene( editor ) { backgroundColor.setDisplay( type === 'Color' ? '' : 'none' ); backgroundTexture.setDisplay( type === 'Texture' ? '' : 'none' ); backgroundEquirectangularTexture.setDisplay( type === 'Equirectangular' ? '' : 'none' ); + backgroundEquirectRow.setDisplay( type === 'Equirectangular' ? '' : 'none' ); } diff --git a/editor/js/Strings.js b/editor/js/Strings.js index 8e0d30cd22863f..d8e7d466edef3c 100644 --- a/editor/js/Strings.js +++ b/editor/js/Strings.js @@ -262,6 +262,9 @@ function Strings( config ) { 'sidebar/material/iridescence': 'Iridescence', 'sidebar/material/iridescenceIOR': 'Thin-Film IOR', 'sidebar/material/iridescenceThicknessMax': 'Thin-Film Thickness', + 'sidebar/material/sheen': 'Sheen', + 'sidebar/material/sheenroughness': 'Sheen Roughness', + 'sidebar/material/sheencolor': 'Sheen Color', 'sidebar/material/transmission': 'Transmission', 'sidebar/material/attenuationDistance': 'Attenuation Distance', 'sidebar/material/attenuationColor': 'Attenuation Color', @@ -279,11 +282,15 @@ function Strings( config ) { 'sidebar/material/specularmap': 'Specular Map', 'sidebar/material/iridescencemap': 'Irid. Map', 'sidebar/material/iridescencethicknessmap': 'Thin-Film Thickness Map', + 'sidebar/material/sheencolormap': 'Sheen Color Map', + 'sidebar/material/sheenroughnessmap': 'Sheen Rough. Map', 'sidebar/material/envmap': 'Env Map', 'sidebar/material/lightmap': 'Light Map', 'sidebar/material/aomap': 'AO Map', 'sidebar/material/emissivemap': 'Emissive Map', 'sidebar/material/gradientmap': 'Gradient Map', + 'sidebar/material/transmissionmap': 'Transmission Map', + 'sidebar/material/thicknessmap': 'Thickness Map', 'sidebar/material/side': 'Side', 'sidebar/material/size': 'Size', 'sidebar/material/sizeAttenuation': 'Size Attenuation', @@ -603,6 +610,12 @@ function Strings( config ) { 'sidebar/material/shininess': 'Brillance', 'sidebar/material/clearcoat': 'Vernis', 'sidebar/material/clearcoatroughness': 'Rugosité du vernis', + 'sidebar/material/iridescence': 'Iridescence', + 'sidebar/material/iridescenceIOR': 'Thin-Film IOR', + 'sidebar/material/iridescenceThicknessMax': 'Thin-Film Thickness', + 'sidebar/material/sheen': 'Sheen', + 'sidebar/material/sheenroughness': 'Sheen Roughness', + 'sidebar/material/sheencolor': 'Sheen Color', 'sidebar/material/transmission': 'Transmission', 'sidebar/material/attenuationDistance': 'Attenuation Distance', 'sidebar/material/attenuationColor': 'Attenuation Color', @@ -618,11 +631,17 @@ function Strings( config ) { 'sidebar/material/roughnessmap': 'Texture de rugosité', 'sidebar/material/metalnessmap': 'Texture métallique', 'sidebar/material/specularmap': 'Texture spéculaire', + 'sidebar/material/iridescencemap': 'Irid. Map', + 'sidebar/material/iridescencethicknessmap': 'Thin-Film Thickness Map', + 'sidebar/material/sheencolormap': 'Sheen Color Map', + 'sidebar/material/sheenroughnessmap': 'Sheen Rough. Map', 'sidebar/material/envmap': 'Texture d\'environnement', 'sidebar/material/lightmap': 'Texture d\'éclairage', 'sidebar/material/aomap': 'Texture d\'occlusion ambiante', 'sidebar/material/emissivemap': 'Texture d\'émission', 'sidebar/material/gradientmap': 'Texture de gradient', + 'sidebar/material/transmissionmap': 'Transmission Map', + 'sidebar/material/thicknessmap': 'Thickness Map', 'sidebar/material/side': 'Côté', 'sidebar/material/size': 'Size', 'sidebar/material/sizeAttenuation': 'Size Attenuation', @@ -942,9 +961,15 @@ function Strings( config ) { 'sidebar/material/shininess': '高光大小', 'sidebar/material/clearcoat': '清漆', 'sidebar/material/clearcoatroughness': '清漆粗糙度', + 'sidebar/material/iridescence': '彩虹色', + 'sidebar/material/iridescenceIOR': '彩虹色折射率', + 'sidebar/material/iridescenceThicknessMax': '彩虹色厚度', + 'sidebar/material/sheen': 'Sheen', + 'sidebar/material/sheenroughness': 'Sheen Roughness', + 'sidebar/material/sheencolor': 'Sheen Color', 'sidebar/material/transmission': '透光', 'sidebar/material/attenuationDistance': '衰减距离', - 'sidebar/material/attenuationColor': 'Attenuation Color', + 'sidebar/material/attenuationColor': '衰减色', 'sidebar/material/thickness': '厚度', 'sidebar/material/vertexcolors': '顶点颜色', 'sidebar/material/matcap': '材质捕获', @@ -957,11 +982,17 @@ function Strings( config ) { 'sidebar/material/roughnessmap': '粗糙贴图', 'sidebar/material/metalnessmap': '金属贴图', 'sidebar/material/specularmap': '高光贴图', + 'sidebar/material/iridescencemap': '彩虹色贴图', + 'sidebar/material/iridescencethicknessmap': '彩虹色厚度贴图', + 'sidebar/material/sheencolormap': 'Sheen Color Map', + 'sidebar/material/sheenroughnessmap': 'Sheen Rough. Map', 'sidebar/material/envmap': '环境贴图', 'sidebar/material/lightmap': '光照贴图', 'sidebar/material/aomap': '环境光遮蔽贴图', 'sidebar/material/emissivemap': '自发光贴图', 'sidebar/material/gradientmap': '渐变贴图', + 'sidebar/material/transmissionmap': '透光贴图', + 'sidebar/material/thicknessmap': '厚度贴图', 'sidebar/material/side': '面', 'sidebar/material/size': '大小', 'sidebar/material/sizeAttenuation': '大小衰减', diff --git a/editor/js/Viewport.VR.js b/editor/js/Viewport.VR.js index 48db645b1b6f34..701babffb3d582 100644 --- a/editor/js/Viewport.VR.js +++ b/editor/js/Viewport.VR.js @@ -1,9 +1,9 @@ import * as THREE from 'three'; -import { HTMLMesh } from '../../examples/jsm/interactive/HTMLMesh.js'; -import { InteractiveGroup } from '../../examples/jsm/interactive/InteractiveGroup.js'; +import { HTMLMesh } from 'three/addons/interactive/HTMLMesh.js'; +import { InteractiveGroup } from 'three/addons/interactive/InteractiveGroup.js'; -import { XRControllerModelFactory } from '../../examples/jsm/webxr/XRControllerModelFactory.js'; +import { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFactory.js'; class VR { diff --git a/editor/js/Viewport.js b/editor/js/Viewport.js index c19ed305b98496..7e0d9a13e62a5a 100644 --- a/editor/js/Viewport.js +++ b/editor/js/Viewport.js @@ -1,6 +1,6 @@ import * as THREE from 'three'; -import { TransformControls } from '../../examples/jsm/controls/TransformControls.js'; +import { TransformControls } from 'three/addons/controls/TransformControls.js'; import { UIPanel } from './libs/ui.js'; @@ -15,7 +15,7 @@ import { SetPositionCommand } from './commands/SetPositionCommand.js'; import { SetRotationCommand } from './commands/SetRotationCommand.js'; import { SetScaleCommand } from './commands/SetScaleCommand.js'; -import { RoomEnvironment } from '../../examples/jsm/environments/RoomEnvironment.js'; +import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; function Viewport( editor ) { @@ -450,9 +450,11 @@ function Viewport( editor ) { } - if ( editor.helpers[ object.id ] !== undefined ) { + const helper = editor.helpers[ object.id ]; - editor.helpers[ object.id ].update(); + if ( helper !== undefined && helper.isSkeletonHelper !== true ) { + + helper.update(); } @@ -479,7 +481,7 @@ function Viewport( editor ) { // background - signals.sceneBackgroundChanged.add( function ( backgroundType, backgroundColor, backgroundTexture, backgroundEquirectangularTexture ) { + signals.sceneBackgroundChanged.add( function ( backgroundType, backgroundColor, backgroundTexture, backgroundEquirectangularTexture, backgroundBlurriness ) { switch ( backgroundType ) { @@ -511,6 +513,7 @@ function Viewport( editor ) { backgroundEquirectangularTexture.mapping = THREE.EquirectangularReflectionMapping; scene.background = backgroundEquirectangularTexture; + scene.backgroundBlurriness = backgroundBlurriness; } diff --git a/editor/js/libs/es-module-shims.js b/editor/js/libs/es-module-shims.js new file mode 100644 index 00000000000000..b550ba8c81f365 --- /dev/null +++ b/editor/js/libs/es-module-shims.js @@ -0,0 +1,789 @@ +/* ES Module Shims 1.3.6 */ +(function () { + + const edge = navigator.userAgent.match(/Edge\/\d\d\.\d+$/); + + let baseUrl; + + function createBlob (source, type = 'text/javascript') { + return URL.createObjectURL(new Blob([source], { type })); + } + + const noop = () => {}; + + const baseEl = document.querySelector('base[href]'); + if (baseEl) + baseUrl = baseEl.href; + + if (!baseUrl && typeof location !== 'undefined') { + baseUrl = location.href.split('#')[0].split('?')[0]; + const lastSepIndex = baseUrl.lastIndexOf('/'); + if (lastSepIndex !== -1) + baseUrl = baseUrl.slice(0, lastSepIndex + 1); + } + + function isURL (url) { + try { + new URL(url); + return true; + } + catch { + return false; + } + } + + const backslashRegEx = /\\/g; + function resolveIfNotPlainOrUrl (relUrl, parentUrl) { + // strip off any trailing query params or hashes + parentUrl = parentUrl && parentUrl.split('#')[0].split('?')[0]; + if (relUrl.indexOf('\\') !== -1) + relUrl = relUrl.replace(backslashRegEx, '/'); + // protocol-relative + if (relUrl[0] === '/' && relUrl[1] === '/') { + return parentUrl.slice(0, parentUrl.indexOf(':') + 1) + relUrl; + } + // relative-url + else if (relUrl[0] === '.' && (relUrl[1] === '/' || relUrl[1] === '.' && (relUrl[2] === '/' || relUrl.length === 2 && (relUrl += '/')) || + relUrl.length === 1 && (relUrl += '/')) || + relUrl[0] === '/') { + const parentProtocol = parentUrl.slice(0, parentUrl.indexOf(':') + 1); + // Disabled, but these cases will give inconsistent results for deep backtracking + //if (parentUrl[parentProtocol.length] !== '/') + // throw new Error('Cannot resolve'); + // read pathname from parent URL + // pathname taken to be part after leading "/" + let pathname; + if (parentUrl[parentProtocol.length + 1] === '/') { + // resolving to a :// so we need to read out the auth and host + if (parentProtocol !== 'file:') { + pathname = parentUrl.slice(parentProtocol.length + 2); + pathname = pathname.slice(pathname.indexOf('/') + 1); + } + else { + pathname = parentUrl.slice(8); + } + } + else { + // resolving to :/ so pathname is the /... part + pathname = parentUrl.slice(parentProtocol.length + (parentUrl[parentProtocol.length] === '/')); + } + + if (relUrl[0] === '/') + return parentUrl.slice(0, parentUrl.length - pathname.length - 1) + relUrl; + + // join together and split for removal of .. and . segments + // looping the string instead of anything fancy for perf reasons + // '../../../../../z' resolved to 'x/y' is just 'z' + const segmented = pathname.slice(0, pathname.lastIndexOf('/') + 1) + relUrl; + + const output = []; + let segmentIndex = -1; + for (let i = 0; i < segmented.length; i++) { + // busy reading a segment - only terminate on '/' + if (segmentIndex !== -1) { + if (segmented[i] === '/') { + output.push(segmented.slice(segmentIndex, i + 1)); + segmentIndex = -1; + } + } + + // new segment - check if it is relative + else if (segmented[i] === '.') { + // ../ segment + if (segmented[i + 1] === '.' && (segmented[i + 2] === '/' || i + 2 === segmented.length)) { + output.pop(); + i += 2; + } + // ./ segment + else if (segmented[i + 1] === '/' || i + 1 === segmented.length) { + i += 1; + } + else { + // the start of a new segment as below + segmentIndex = i; + } + } + // it is the start of a new segment + else { + segmentIndex = i; + } + } + // finish reading out the last segment + if (segmentIndex !== -1) + output.push(segmented.slice(segmentIndex)); + return parentUrl.slice(0, parentUrl.length - pathname.length) + output.join(''); + } + } + + /* + * Import maps implementation + * + * To make lookups fast we pre-resolve the entire import map + * and then match based on backtracked hash lookups + * + */ + function resolveUrl (relUrl, parentUrl) { + return resolveIfNotPlainOrUrl(relUrl, parentUrl) || (relUrl.indexOf(':') !== -1 ? relUrl : resolveIfNotPlainOrUrl('./' + relUrl, parentUrl)); + } + + function resolveAndComposePackages (packages, outPackages, baseUrl, parentMap) { + for (let p in packages) { + const resolvedLhs = resolveIfNotPlainOrUrl(p, baseUrl) || p; + if (outPackages[resolvedLhs]) { + throw new Error(`Dynamic import map rejected: Overrides entry "${resolvedLhs}" from ${outPackages[resolvedLhs]} to ${packages[resolvedLhs]}.`); + } + let target = packages[p]; + if (typeof target !== 'string') + continue; + const mapped = resolveImportMap(parentMap, resolveIfNotPlainOrUrl(target, baseUrl) || target, baseUrl); + if (mapped) { + outPackages[resolvedLhs] = mapped; + continue; + } + targetWarning(p, packages[p], 'bare specifier did not resolve'); + } + } + + function resolveAndComposeImportMap (json, baseUrl, parentMap) { + const outMap = { imports: Object.assign({}, parentMap.imports), scopes: Object.assign({}, parentMap.scopes) }; + + if (json.imports) + resolveAndComposePackages(json.imports, outMap.imports, baseUrl, parentMap); + + if (json.scopes) + for (let s in json.scopes) { + const resolvedScope = resolveUrl(s, baseUrl); + resolveAndComposePackages(json.scopes[s], outMap.scopes[resolvedScope] || (outMap.scopes[resolvedScope] = {}), baseUrl, parentMap); + } + + return outMap; + } + + function getMatch (path, matchObj) { + if (matchObj[path]) + return path; + let sepIndex = path.length; + do { + const segment = path.slice(0, sepIndex + 1); + if (segment in matchObj) + return segment; + } while ((sepIndex = path.lastIndexOf('/', sepIndex - 1)) !== -1) + } + + function applyPackages (id, packages) { + const pkgName = getMatch(id, packages); + if (pkgName) { + const pkg = packages[pkgName]; + if (pkg === null) return; + if (id.length > pkgName.length && pkg[pkg.length - 1] !== '/') + targetWarning(pkgName, pkg, "should have a trailing '/'"); + else + return pkg + id.slice(pkgName.length); + } + } + + function targetWarning (match, target, msg) { + console.warn("Package target " + msg + ", resolving target '" + target + "' for " + match); + } + + function resolveImportMap (importMap, resolvedOrPlain, parentUrl) { + let scopeUrl = parentUrl && getMatch(parentUrl, importMap.scopes); + while (scopeUrl) { + const packageResolution = applyPackages(resolvedOrPlain, importMap.scopes[scopeUrl]); + if (packageResolution) + return packageResolution; + scopeUrl = getMatch(scopeUrl.slice(0, scopeUrl.lastIndexOf('/')), importMap.scopes); + } + return applyPackages(resolvedOrPlain, importMap.imports) || resolvedOrPlain.indexOf(':') !== -1 && resolvedOrPlain; + } + + const optionsScript = document.querySelector('script[type=esms-options]'); + + const esmsInitOptions = optionsScript ? JSON.parse(optionsScript.innerHTML) : self.esmsInitOptions ? self.esmsInitOptions : {}; + + let shimMode = !!esmsInitOptions.shimMode; + const resolveHook = globalHook(shimMode && esmsInitOptions.resolve); + + const skip = esmsInitOptions.skip ? new RegExp(esmsInitOptions.skip) : null; + + let nonce = esmsInitOptions.nonce; + + if (!nonce) { + const nonceElement = document.querySelector('script[nonce]'); + if (nonceElement) + nonce = nonceElement.nonce || nonceElement.getAttribute('nonce'); + } + + const onerror = globalHook(esmsInitOptions.onerror || noop); + const onpolyfill = globalHook(esmsInitOptions.onpolyfill || noop); + + const { revokeBlobURLs, noLoadEventRetriggers } = esmsInitOptions; + + const fetchHook = esmsInitOptions.fetch ? globalHook(esmsInitOptions.fetch) : fetch; + + function globalHook (name) { + return typeof name === 'string' ? self[name] : name; + } + + const enable = Array.isArray(esmsInitOptions.polyfillEnable) ? esmsInitOptions.polyfillEnable : []; + const cssModulesEnabled = enable.includes('css-modules'); + const jsonModulesEnabled = enable.includes('json-modules'); + + function setShimMode () { + shimMode = true; + } + + let err; + window.addEventListener('error', _err => err = _err); + function dynamicImportScript (url, { errUrl = url } = {}) { + err = undefined; + const src = createBlob(`import*as m from'${url}';self._esmsi=m`); + const s = Object.assign(document.createElement('script'), { type: 'module', src }); + s.setAttribute('nonce', nonce); + s.setAttribute('noshim', ''); + const p = new Promise((resolve, reject) => { + // Safari is unique in supporting module script error events + s.addEventListener('error', cb); + s.addEventListener('load', cb); + + function cb (_err) { + document.head.removeChild(s); + if (self._esmsi) { + resolve(self._esmsi, baseUrl); + self._esmsi = undefined; + } + else { + reject(!(_err instanceof Event) && _err || err && err.error || new Error(`Error loading or executing the graph of ${errUrl} (check the console for ${src}).`)); + err = undefined; + } + } + }); + document.head.appendChild(s); + return p; + } + + let dynamicImport = dynamicImportScript; + + const supportsDynamicImportCheck = dynamicImportScript(createBlob('export default u=>import(u)')).then(_dynamicImport => { + if (_dynamicImport) + dynamicImport = _dynamicImport.default; + return !!_dynamicImport; + }, noop); + + // support browsers without dynamic import support (eg Firefox 6x) + let supportsJsonAssertions = false; + let supportsCssAssertions = false; + + let supportsImportMeta = false; + let supportsImportMaps = false; + + let supportsDynamicImport = false; + + const featureDetectionPromise = Promise.resolve(supportsDynamicImportCheck).then(_supportsDynamicImport => { + if (!_supportsDynamicImport) + return; + supportsDynamicImport = true; + + return Promise.all([ + dynamicImport(createBlob('import.meta')).then(() => supportsImportMeta = true, noop), + cssModulesEnabled && dynamicImport(createBlob('import"data:text/css,{}"assert{type:"css"}')).then(() => supportsCssAssertions = true, noop), + jsonModulesEnabled && dynamicImport(createBlob('import"data:text/json,{}"assert{type:"json"}')).then(() => supportsJsonAssertions = true, noop), + new Promise(resolve => { + self._$s = v => { + document.head.removeChild(iframe); + if (v) supportsImportMaps = true; + delete self._$s; + resolve(); + }; + const iframe = document.createElement('iframe'); + iframe.style.display = 'none'; + document.head.appendChild(iframe); + iframe.src = createBlob(` @@ -33,10 +34,10 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { CSS2DRenderer, CSS2DObject } from './jsm/renderers/CSS2DRenderer.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let gui; @@ -66,7 +67,7 @@ } - } + }; const clock = new THREE.Clock(); const textureLoader = new THREE.TextureLoader(); diff --git a/examples/css3d_molecules.html b/examples/css3d_molecules.html index 882af9b639945d..b4e081055ca404 100644 --- a/examples/css3d_molecules.html +++ b/examples/css3d_molecules.html @@ -29,7 +29,8 @@ @@ -38,10 +39,10 @@ import * as THREE from 'three'; - import { TrackballControls } from './jsm/controls/TrackballControls.js'; - import { PDBLoader } from './jsm/loaders/PDBLoader.js'; - import { CSS3DRenderer, CSS3DObject, CSS3DSprite } from './jsm/renderers/CSS3DRenderer.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; + import { PDBLoader } from 'three/addons/loaders/PDBLoader.js'; + import { CSS3DRenderer, CSS3DObject, CSS3DSprite } from 'three/addons/renderers/CSS3DRenderer.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let camera, scene, renderer; let controls; diff --git a/examples/css3d_orthographic.html b/examples/css3d_orthographic.html index a792fb62e8f802..bb37c0a10b5e65 100644 --- a/examples/css3d_orthographic.html +++ b/examples/css3d_orthographic.html @@ -27,7 +27,8 @@ @@ -36,8 +37,8 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { CSS3DRenderer, CSS3DObject } from './jsm/renderers/CSS3DRenderer.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js'; let camera, scene, renderer; diff --git a/examples/css3d_periodictable.html b/examples/css3d_periodictable.html index 0e752651488890..d10fdc5d354e6c 100644 --- a/examples/css3d_periodictable.html +++ b/examples/css3d_periodictable.html @@ -98,7 +98,8 @@ @@ -107,9 +108,9 @@ import * as THREE from 'three'; - import { TWEEN } from './jsm/libs/tween.module.min.js'; - import { TrackballControls } from './jsm/controls/TrackballControls.js'; - import { CSS3DRenderer, CSS3DObject } from './jsm/renderers/CSS3DRenderer.js'; + import { TWEEN } from 'three/addons/libs/tween.module.min.js'; + import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; + import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js'; const table = [ 'H', 'Hydrogen', '1.00794', 1, 1, diff --git a/examples/css3d_sandbox.html b/examples/css3d_sandbox.html index a1ade1bc87b5b1..1d8efdc1550be2 100644 --- a/examples/css3d_sandbox.html +++ b/examples/css3d_sandbox.html @@ -23,7 +23,8 @@ @@ -32,8 +33,8 @@ import * as THREE from 'three'; - import { TrackballControls } from './jsm/controls/TrackballControls.js'; - import { CSS3DRenderer, CSS3DObject } from './jsm/renderers/CSS3DRenderer.js'; + import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; + import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js'; let camera, scene, renderer; diff --git a/examples/css3d_sprites.html b/examples/css3d_sprites.html index 2b4565e368af73..382055dcbff41f 100644 --- a/examples/css3d_sprites.html +++ b/examples/css3d_sprites.html @@ -27,7 +27,8 @@ @@ -36,9 +37,9 @@ import * as THREE from 'three'; - import { TWEEN } from './jsm/libs/tween.module.min.js'; - import { TrackballControls } from './jsm/controls/TrackballControls.js'; - import { CSS3DRenderer, CSS3DSprite } from './jsm/renderers/CSS3DRenderer.js'; + import { TWEEN } from 'three/addons/libs/tween.module.min.js'; + import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; + import { CSS3DRenderer, CSS3DSprite } from 'three/addons/renderers/CSS3DRenderer.js'; let camera, scene, renderer; let controls; diff --git a/examples/css3d_youtube.html b/examples/css3d_youtube.html index 3ce146ef2c0237..e70da0f41e913f 100644 --- a/examples/css3d_youtube.html +++ b/examples/css3d_youtube.html @@ -30,7 +30,8 @@ @@ -39,8 +40,8 @@ import * as THREE from 'three'; - import { TrackballControls } from './jsm/controls/TrackballControls.js'; - import { CSS3DRenderer, CSS3DObject } from './jsm/renderers/CSS3DRenderer.js'; + import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; + import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js'; let camera, scene, renderer; let controls; diff --git a/examples/files.json b/examples/files.json index 44b9258f0f87fc..51248d6713b316 100644 --- a/examples/files.json +++ b/examples/files.json @@ -3,6 +3,7 @@ "webgl_animation_keyframes", "webgl_animation_skinning_blending", "webgl_animation_skinning_additive_blending", + "webgl_animation_skinning_ik", "webgl_animation_skinning_morph", "webgl_animation_multiple", "webgl_camera", @@ -85,6 +86,7 @@ "webgl_loader_gcode", "webgl_loader_gltf", "webgl_loader_gltf_compressed", + "webgl_loader_gltf_instancing", "webgl_loader_gltf_iridescence", "webgl_loader_gltf_sheen", "webgl_loader_gltf_transmission", @@ -120,7 +122,9 @@ "webgl_loader_texture_pvrtc", "webgl_loader_texture_rgbm", "webgl_loader_texture_tga", + "webgl_loader_texture_tiff", "webgl_loader_ttf", + "webgl_loader_usdz", "webgl_loader_vox", "webgl_loader_vrml", "webgl_loader_vtk", @@ -174,6 +178,7 @@ "webgl_modifier_curve_instanced", "webgl_modifier_edgesplit", "webgl_modifier_simplifier", + "webgl_modifier_subdivision", "webgl_modifier_tessellation", "webgl_morphtargets", "webgl_morphtargets_face", @@ -201,6 +206,7 @@ "webgl_raycaster_sprite", "webgl_raycaster_texture", "webgl_read_float_buffer", + "webgl_renderer_pathtracer", "webgl_refraction", "webgl_rtt", "webgl_shader", @@ -228,10 +234,14 @@ "webgl_water_flowmap" ], "webgl / nodes": [ + "webgl_nodes_loader_gltf_iridescence", + "webgl_nodes_loader_gltf_transmission", "webgl_nodes_loader_gltf_sheen", + "webgl_nodes_loader_materialx", "webgl_nodes_materials_instance_uniform", "webgl_nodes_materials_physical_clearcoat", "webgl_nodes_materials_standard", + "webgl_nodes_materialx_noise", "webgl_nodes_playground", "webgl_nodes_points" ], @@ -300,22 +310,26 @@ ], "webgl2": [ "webgl2_buffergeometry_attributes_integer", + "webgl2_buffergeometry_attributes_none", "webgl2_materials_texture2darray", "webgl2_materials_texture3d", "webgl2_materials_texture3d_partialupdate", "webgl2_multiple_rendertargets", "webgl2_multisampled_renderbuffers", "webgl2_rendertarget_texture2darray", + "webgl2_texture2darray_compressed", "webgl2_ubo", "webgl2_volume_cloud", "webgl2_volume_instancing", "webgl2_volume_perlin" ], "webgpu": [ + "webgpu_audio_processing", "webgpu_compute", "webgpu_cubemap_adjustments", "webgpu_cubemap_mix", "webgpu_depth_texture", + "webgpu_equirectangular", "webgpu_instance_mesh", "webgpu_instance_uniform", "webgpu_lights_custom", @@ -343,6 +357,7 @@ "webxr_ar_hittest", "webxr_ar_lighting", "webxr_ar_paint", + "webxr_ar_plane_detection", "webxr_vr_ballshooter", "webxr_vr_cubes", "webxr_vr_dragging", diff --git a/examples/games_fps.html b/examples/games_fps.html index d2be18f647c58c..ff7a5a3631703f 100644 --- a/examples/games_fps.html +++ b/examples/games_fps.html @@ -21,7 +21,8 @@ @@ -30,16 +31,16 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { Octree } from './jsm/math/Octree.js'; - import { OctreeHelper } from './jsm/helpers/OctreeHelper.js'; + import { Octree } from 'three/addons/math/Octree.js'; + import { OctreeHelper } from 'three/addons/helpers/OctreeHelper.js'; - import { Capsule } from './jsm/math/Capsule.js'; + import { Capsule } from 'three/addons/math/Capsule.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; const clock = new THREE.Clock(); diff --git a/examples/index.html b/examples/index.html index 1658869da47ca9..86dcf1cd56cd99 100644 --- a/examples/index.html +++ b/examples/index.html @@ -312,10 +312,8 @@

    three.js

    function filterExample( file, exp, tags ) { const link = links[ file ]; - const name = getName( file ); if ( file in tags ) file += ' ' + tags[ file ].join( ' ' ); - const res = file.match( exp ); - let text; + const res = file.replace( /_+/g, ' ' ).match( exp ); if ( res && res.length > 0 ) { diff --git a/examples/js/animation/AnimationClipCreator.js b/examples/js/animation/AnimationClipCreator.js index dc399c51c75afc..29a0588ebd9ed7 100644 --- a/examples/js/animation/AnimationClipCreator.js +++ b/examples/js/animation/AnimationClipCreator.js @@ -11,7 +11,6 @@ return new THREE.AnimationClip( null, period, [ track ] ); } - static CreateScaleAxisAnimation( period, axis = 'x' ) { const times = [ 0, period ], @@ -21,13 +20,11 @@ return new THREE.AnimationClip( null, period, [ track ] ); } - static CreateShakeAnimation( duration, shakeScale ) { const times = [], values = [], tmp = new THREE.Vector3(); - for ( let i = 0; i < duration * 10; i ++ ) { times.push( i / 10 ); @@ -40,13 +37,11 @@ return new THREE.AnimationClip( null, duration, [ track ] ); } - static CreatePulsationAnimation( duration, pulseScale ) { const times = [], values = [], tmp = new THREE.Vector3(); - for ( let i = 0; i < duration * 10; i ++ ) { times.push( i / 10 ); @@ -60,7 +55,6 @@ return new THREE.AnimationClip( null, duration, [ track ] ); } - static CreateVisibilityAnimation( duration ) { const times = [ 0, duration / 2, duration ], @@ -70,13 +64,11 @@ return new THREE.AnimationClip( null, duration, [ track ] ); } - static CreateMaterialColorAnimation( duration, colors ) { const times = [], values = [], timeStep = duration / colors.length; - for ( let i = 0; i <= colors.length; i ++ ) { times.push( i * timeStep ); diff --git a/examples/js/animation/CCDIKSolver.js b/examples/js/animation/CCDIKSolver.js index c177b2b217ea8a..7384eff144dd3c 100644 --- a/examples/js/animation/CCDIKSolver.js +++ b/examples/js/animation/CCDIKSolver.js @@ -1,26 +1,17 @@ ( function () { const _q = new THREE.Quaternion(); - const _targetPos = new THREE.Vector3(); - const _targetVec = new THREE.Vector3(); - const _effectorPos = new THREE.Vector3(); - const _effectorVec = new THREE.Vector3(); - const _linkPos = new THREE.Vector3(); - const _invLinkQ = new THREE.Quaternion(); - const _linkScale = new THREE.Vector3(); - const _axis = new THREE.Vector3(); - const _vector = new THREE.Vector3(); - const _matrix = new THREE.Matrix4(); + /** * CCD Algorithm * - https://sites.google.com/site/auraliusproject/ccd-algorithm @@ -41,7 +32,6 @@ * } ]; */ - class CCDIKSolver { /** @@ -52,21 +42,18 @@ this.mesh = mesh; this.iks = iks; - this._valid(); } + /** * Update all IK bones. * * @return {CCDIKSolver} */ - - update() { const iks = this.iks; - for ( let i = 0, il = iks.length; i < il; i ++ ) { this.updateOne( iks[ i ] ); @@ -76,64 +63,55 @@ return this; } + /** * Update one IK bone * * @param {Object} ik parameter * @return {CCDIKSolver} */ - - updateOne( ik ) { - const bones = this.mesh.skeleton.bones; // for reference overhead reduction in loop + const bones = this.mesh.skeleton.bones; + // for reference overhead reduction in loop const math = Math; const effector = bones[ ik.effector ]; - const target = bones[ ik.target ]; // don't use getWorldPosition() here for the performance - // because it calls updateMatrixWorld( true ) inside. + const target = bones[ ik.target ]; + // don't use getWorldPosition() here for the performance + // because it calls updateMatrixWorld( true ) inside. _targetPos.setFromMatrixPosition( target.matrixWorld ); - const links = ik.links; const iteration = ik.iteration !== undefined ? ik.iteration : 1; - for ( let i = 0; i < iteration; i ++ ) { let rotated = false; - for ( let j = 0, jl = links.length; j < jl; j ++ ) { - const link = bones[ links[ j ].index ]; // skip this link and following links. - // this skip is used for MMD performance optimization. + const link = bones[ links[ j ].index ]; + // skip this link and following links. + // this skip is used for MMD performance optimization. if ( links[ j ].enabled === false ) break; const limitation = links[ j ].limitation; const rotationMin = links[ j ].rotationMin; - const rotationMax = links[ j ].rotationMax; // don't use getWorldPosition/Quaternion() here for the performance - // because they call updateMatrixWorld( true ) inside. + const rotationMax = links[ j ].rotationMax; + // don't use getWorldPosition/Quaternion() here for the performance + // because they call updateMatrixWorld( true ) inside. link.matrixWorld.decompose( _linkPos, _invLinkQ, _linkScale ); - _invLinkQ.invert(); + _effectorPos.setFromMatrixPosition( effector.matrixWorld ); - _effectorPos.setFromMatrixPosition( effector.matrixWorld ); // work in link world - - + // work in link world _effectorVec.subVectors( _effectorPos, _linkPos ); - _effectorVec.applyQuaternion( _invLinkQ ); - _effectorVec.normalize(); - _targetVec.subVectors( _targetPos, _linkPos ); - _targetVec.applyQuaternion( _invLinkQ ); - _targetVec.normalize(); - let angle = _targetVec.dot( _effectorVec ); - if ( angle > 1.0 ) { angle = 1.0; @@ -144,10 +122,10 @@ } - angle = math.acos( angle ); // skip if changing angle is too small to prevent vibration of bone + angle = math.acos( angle ); + // skip if changing angle is too small to prevent vibration of bone if ( angle < 1e-5 ) continue; - if ( ik.minAngle !== undefined && angle < ik.minAngle ) { angle = ik.minAngle; @@ -161,13 +139,11 @@ } _axis.crossVectors( _effectorVec, _targetVec ); - _axis.normalize(); - _q.setFromAxisAngle( _axis, angle ); + link.quaternion.multiply( _q ); - link.quaternion.multiply( _q ); // TODO: re-consider the limitation specification - + // TODO: re-consider the limitation specification if ( limitation !== undefined ) { let c = link.quaternion.w; @@ -201,25 +177,24 @@ return this; } + /** * Creates Helper * * @return {CCDIKHelper} */ - - createHelper() { - return new CCDIKHelper( this.mesh, this.mesh.geometry.userData.MMD.iks ); + return new CCDIKHelper( this.mesh, this.iks ); - } // private methods + } + // private methods _valid() { const iks = this.iks; const bones = this.mesh.skeleton.bones; - for ( let i = 0, il = iks.length; i < il; i ++ ) { const ik = iks[ i ]; @@ -227,11 +202,9 @@ const links = ik.links; let link0, link1; link0 = effector; - for ( let j = 0, jl = links.length; j < jl; j ++ ) { link1 = bones[ links[ j ].index ]; - if ( link0.parent !== link1 ) { console.warn( 'THREE.CCDIKSolver: bone ' + link0.name + ' is not the child of bone ' + link1.name ); @@ -247,7 +220,6 @@ } } - function getPosition( bone, matrixWorldInv ) { return _vector.setFromMatrixPosition( bone.matrixWorld ).applyMatrix4( matrixWorldInv ); @@ -262,24 +234,23 @@ array[ index * 3 + 2 ] = v.z; } + /** * Visualize IK bones * * @param {SkinnedMesh} mesh * @param {Array} iks */ - - class CCDIKHelper extends THREE.Object3D { - constructor( mesh, iks = [] ) { + constructor( mesh, iks = [], sphereSize = 0.25 ) { super(); this.root = mesh; this.iks = iks; this.matrix.copy( mesh.matrixWorld ); this.matrixAutoUpdate = false; - this.sphereGeometry = new THREE.SphereGeometry( 0.25, 16, 8 ); + this.sphereGeometry = new THREE.SphereGeometry( sphereSize, 16, 8 ); this.targetSphereMaterial = new THREE.MeshBasicMaterial( { color: new THREE.Color( 0xff8888 ), depthTest: false, @@ -304,27 +275,22 @@ depthWrite: false, transparent: true } ); - this._init(); } + /** * Updates IK bones visualization. */ - - updateMatrixWorld( force ) { const mesh = this.root; - if ( this.visible ) { let offset = 0; const iks = this.iks; const bones = mesh.skeleton.bones; - _matrix.copy( mesh.matrixWorld ).invert(); - for ( let i = 0, il = iks.length; i < il; i ++ ) { const ik = iks[ i ]; @@ -334,7 +300,6 @@ const effectorMesh = this.children[ offset ++ ]; targetMesh.position.copy( getPosition( targetBone, _matrix ) ); effectorMesh.position.copy( getPosition( effectorBone, _matrix ) ); - for ( let j = 0, jl = ik.links.length; j < jl; j ++ ) { const link = ik.links[ j ]; @@ -348,7 +313,6 @@ const array = line.geometry.attributes.position.array; setPositionOfBoneToAttributeArray( array, 0, targetBone, _matrix ); setPositionOfBoneToAttributeArray( array, 1, effectorBone, _matrix ); - for ( let j = 0, jl = ik.links.length; j < jl; j ++ ) { const link = ik.links[ j ]; @@ -366,14 +330,34 @@ this.matrix.copy( mesh.matrixWorld ); super.updateMatrixWorld( force ); - } // private method + } + /** + * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. + */ + dispose() { + + this.sphereGeometry.dispose(); + this.targetSphereMaterial.dispose(); + this.effectorSphereMaterial.dispose(); + this.linkSphereMaterial.dispose(); + this.lineMaterial.dispose(); + const children = this.children; + for ( let i = 0; i < children.length; i ++ ) { + + const child = children[ i ]; + if ( child.isLine ) child.geometry.dispose(); + + } + + } + + // private method _init() { const scope = this; const iks = this.iks; - function createLineGeometry( ik ) { const geometry = new THREE.BufferGeometry(); @@ -412,7 +396,6 @@ const ik = iks[ i ]; this.add( createTargetMesh() ); this.add( createEffectorMesh() ); - for ( let j = 0, jl = ik.links.length; j < jl; j ++ ) { this.add( createLinkMesh() ); diff --git a/examples/js/animation/MMDAnimationHelper.js b/examples/js/animation/MMDAnimationHelper.js index 181e436e61cb14..8aa74652804b8e 100644 --- a/examples/js/animation/MMDAnimationHelper.js +++ b/examples/js/animation/MMDAnimationHelper.js @@ -12,7 +12,6 @@ * TODO * - more precise grant skinning support. */ - class MMDAnimationHelper { /** @@ -43,16 +42,14 @@ physics: true, cameraAnimation: true }; + this.onBeforePhysics = function /* mesh */ () {}; - this.onBeforePhysics = function - /* mesh */ - () {}; // experimental - - + // experimental this.sharedPhysics = false; this.masterPhysics = null; } + /** * Adds an Three.js Object to helper and setups animation. * The anmation durations of added objects are synched @@ -69,8 +66,6 @@ * @param {Number} params.delayTime - Only for THREE.Audio. Default is 0.0. * @return {MMDAnimationHelper} */ - - add( object, params = {} ) { if ( object.isSkinnedMesh ) { @@ -95,14 +90,13 @@ return this; } + /** * Removes an Three.js Object from helper. * * @param {THREE.SkinnedMesh|THREE.Camera|THREE.Audio} object * @return {MMDAnimationHelper} */ - - remove( object ) { if ( object.isSkinnedMesh ) { @@ -127,18 +121,16 @@ return this; } + /** * Updates the animation. * * @param {Number} delta * @return {MMDAnimationHelper} */ - - update( delta ) { if ( this.audioManager !== null ) this.audioManager.control( delta ); - for ( let i = 0; i < this.meshes.length; i ++ ) { this._animateMesh( this.meshes[ i ], delta ); @@ -150,6 +142,7 @@ return this; } + /** * Changes the pose of SkinnedMesh as VPD specifies. * @@ -161,15 +154,12 @@ * @param {boolean} params.grant - Default is true. * @return {MMDAnimationHelper} */ - - pose( mesh, vpd, params = {} ) { if ( params.resetPose !== false ) mesh.pose(); const bones = mesh.skeleton.bones; const boneParams = vpd.bones; const boneNameDictionary = {}; - for ( let i = 0, il = bones.length; i < il; i ++ ) { boneNameDictionary[ bones[ i ].name ] = i; @@ -178,7 +168,6 @@ const vector = new THREE.Vector3(); const quaternion = new THREE.Quaternion(); - for ( let i = 0, il = boneParams.length; i < il; i ++ ) { const boneParam = boneParams[ i ]; @@ -190,15 +179,14 @@ } - mesh.updateMatrixWorld( true ); // PMX animation system special path + mesh.updateMatrixWorld( true ); + // PMX animation system special path if ( this.configuration.pmxAnimation && mesh.geometry.userData.MMD && mesh.geometry.userData.MMD.format === 'pmx' ) { const sortedBonesData = this._sortBoneDataArray( mesh.geometry.userData.MMD.bones.slice() ); - const ikSolver = params.ik !== false ? this._createCCDIKSolver( mesh ) : null; const grantSolver = params.grant !== false ? this.createGrantSolver( mesh ) : null; - this._animatePMXMesh( mesh, sortedBonesData, ikSolver, grantSolver ); } else { @@ -220,6 +208,7 @@ return this; } + /** * Enabes/Disables an animation feature. * @@ -227,8 +216,6 @@ * @param {boolean} enabled * @return {MMDAnimationHelper} */ - - enable( key, enabled ) { if ( this.enabled[ key ] === undefined ) { @@ -238,7 +225,6 @@ } this.enabled[ key ] = enabled; - if ( key === 'physics' ) { for ( let i = 0, il = this.meshes.length; i < il; i ++ ) { @@ -252,20 +238,20 @@ return this; } + /** * Creates an GrantSolver instance. * * @param {THREE.SkinnedMesh} mesh * @return {GrantSolver} */ - - createGrantSolver( mesh ) { return new GrantSolver( mesh, mesh.geometry.userData.MMD.grants ); - } // private methods + } + // private methods _addMesh( mesh, params ) { @@ -279,9 +265,7 @@ this.objects.set( mesh, { looped: false } ); - this._setupMeshAnimation( mesh, params.animation ); - if ( params.physics !== false ) { this._setupMeshPhysics( mesh, params ); @@ -291,7 +275,6 @@ return this; } - _setupCamera( camera, params ) { if ( this.camera === camera ) { @@ -304,7 +287,6 @@ this.camera = camera; camera.add( this.cameraTarget ); this.objects.set( camera, {} ); - if ( params.animation !== undefined ) { this._setupCameraAnimation( camera, params.animation ); @@ -314,7 +296,6 @@ return this; } - _setupAudio( audio, params ) { if ( this.audio === audio ) { @@ -332,12 +313,10 @@ return this; } - _removeMesh( mesh ) { let found = false; let writeIndex = 0; - for ( let i = 0, il = this.meshes.length; i < il; i ++ ) { if ( this.meshes[ i ] === mesh ) { @@ -362,7 +341,6 @@ return this; } - _clearCamera( camera ) { if ( camera !== this.camera ) { @@ -377,7 +355,6 @@ return this; } - _clearAudio( audio ) { if ( audio !== this.audio ) { @@ -392,23 +369,20 @@ return this; } - _setupMeshAnimation( mesh, animation ) { const objects = this.objects.get( mesh ); - if ( animation !== undefined ) { const animations = Array.isArray( animation ) ? animation : [ animation ]; objects.mixer = new THREE.AnimationMixer( mesh ); - for ( let i = 0, il = animations.length; i < il; i ++ ) { objects.mixer.clipAction( animations[ i ] ).play(); - } // TODO: find a workaround not to access ._clip looking like a private property - + } + // TODO: find a workaround not to access ._clip looking like a private property objects.mixer.addEventListener( 'loop', function ( event ) { const tracks = event.action._clip.tracks; @@ -424,13 +398,11 @@ return this; } - _setupCameraAnimation( camera, animation ) { const animations = Array.isArray( animation ) ? animation : [ animation ]; const objects = this.objects.get( camera ); objects.mixer = new THREE.AnimationMixer( camera ); - for ( let i = 0, il = animations.length; i < il; i ++ ) { objects.mixer.clipAction( animations[ i ] ).play(); @@ -438,35 +410,31 @@ } } - _setupMeshPhysics( mesh, params ) { - const objects = this.objects.get( mesh ); // shared physics is experimental + const objects = this.objects.get( mesh ); + + // shared physics is experimental if ( params.world === undefined && this.sharedPhysics ) { const masterPhysics = this._getMasterPhysics(); - if ( masterPhysics !== null ) world = masterPhysics.world; // eslint-disable-line no-undef } objects.physics = this._createMMDPhysics( mesh, params ); - if ( objects.mixer && params.animationWarmup !== false ) { this._animateMesh( mesh, 0 ); - objects.physics.reset(); } objects.physics.warmup( params.warmup !== undefined ? params.warmup : 60 ); - this._optimizeIK( mesh, true ); } - _animateMesh( mesh, delta ) { const objects = this.objects.get( mesh ); @@ -475,23 +443,20 @@ const grantSolver = objects.grantSolver; const physics = objects.physics; const looped = objects.looped; - if ( mixer && this.enabled.animation ) { // alternate solution to save/restore bones but less performant? //mesh.pose(); //this._updatePropertyMixersBuffer( mesh ); - this._restoreBones( mesh ); + this._restoreBones( mesh ); mixer.update( delta ); + this._saveBones( mesh ); - this._saveBones( mesh ); // PMX animation system special path - - + // PMX animation system special path if ( this.configuration.pmxAnimation && mesh.geometry.userData.MMD && mesh.geometry.userData.MMD.format === 'pmx' ) { if ( ! objects.sortedBonesData ) objects.sortedBonesData = this._sortBoneDataArray( mesh.geometry.userData.MMD.bones.slice() ); - this._animatePMXMesh( mesh, objects.sortedBonesData, ikSolver && this.enabled.ik ? ikSolver : null, grantSolver && this.enabled.grant ? grantSolver : null ); } else { @@ -527,11 +492,11 @@ } - } // Sort bones in order by 1. transformationClass and 2. bone index. + } + + // Sort bones in order by 1. transformationClass and 2. bone index. // In PMX animation system, bone transformations should be processed // in this order. - - _sortBoneDataArray( boneDataArray ) { return boneDataArray.sort( function ( a, b ) { @@ -548,21 +513,19 @@ } ); - } // PMX Animation system is a bit too complex and doesn't great match to + } + + // PMX Animation system is a bit too complex and doesn't great match to // Three.js Animation system. This method attempts to simulate it as much as // possible but doesn't perfectly simulate. // This method is more costly than the regular one so // you are recommended to set constructor parameter "pmxAnimation: true" // only if your PMX model animation doesn't work well. // If you need better method you would be required to write your own. - - _animatePMXMesh( mesh, sortedBonesData, ikSolver, grantSolver ) { _quaternionIndex = 0; - _grantResultMap.clear(); - for ( let i = 0, il = sortedBonesData.length; i < il; i ++ ) { updateOne( mesh, sortedBonesData[ i ].index, ikSolver, grantSolver ); @@ -573,11 +536,9 @@ return this; } - _animateCamera( camera, delta ) { const mixer = this.objects.get( camera ).mixer; - if ( mixer && this.enabled.cameraAnimation ) { mixer.update( delta ); @@ -589,21 +550,17 @@ } } - _optimizeIK( mesh, physicsEnabled ) { const iks = mesh.geometry.userData.MMD.iks; const bones = mesh.geometry.userData.MMD.bones; - for ( let i = 0, il = iks.length; i < il; i ++ ) { const ik = iks[ i ]; const links = ik.links; - for ( let j = 0, jl = links.length; j < jl; j ++ ) { const link = links[ j ]; - if ( physicsEnabled === true ) { // disable IK of the bone the corresponding rigidBody type of which is 1 or 2 @@ -621,7 +578,6 @@ } } - _createCCDIKSolver( mesh ) { if ( THREE.CCDIKSolver === undefined ) { @@ -633,7 +589,6 @@ return new THREE.CCDIKSolver( mesh, mesh.geometry.userData.MMD.iks ); } - _createMMDPhysics( mesh, params ) { if ( THREE.MMDPhysics === undefined ) { @@ -645,29 +600,28 @@ return new THREE.MMDPhysics( mesh, mesh.geometry.userData.MMD.rigidBodies, mesh.geometry.userData.MMD.constraints, params ); } + /* * Detects the longest duration and then sets it to them to sync. * TODO: Not to access private properties ( ._actions and ._clip ) */ - - _syncDuration() { let max = 0.0; const objects = this.objects; const meshes = this.meshes; const camera = this.camera; - const audioManager = this.audioManager; // get the longest duration + const audioManager = this.audioManager; + + // get the longest duration for ( let i = 0, il = meshes.length; i < il; i ++ ) { const mixer = this.objects.get( meshes[ i ] ).mixer; if ( mixer === undefined ) continue; - for ( let j = 0; j < mixer._actions.length; j ++ ) { const clip = mixer._actions[ j ]._clip; - if ( ! objects.has( clip ) ) { objects.set( clip, { @@ -685,13 +639,11 @@ if ( camera !== null ) { const mixer = this.objects.get( camera ).mixer; - if ( mixer !== undefined ) { for ( let i = 0, il = mixer._actions.length; i < il; i ++ ) { const clip = mixer._actions[ i ]._clip; - if ( ! objects.has( clip ) ) { objects.set( clip, { @@ -714,13 +666,14 @@ } - max += this.configuration.afterglow; // update the duration + max += this.configuration.afterglow; + + // update the duration for ( let i = 0, il = this.meshes.length; i < il; i ++ ) { const mixer = this.objects.get( this.meshes[ i ] ).mixer; if ( mixer === undefined ) continue; - for ( let j = 0, jl = mixer._actions.length; j < jl; j ++ ) { mixer._actions[ j ]._clip.duration = max; @@ -732,7 +685,6 @@ if ( camera !== null ) { const mixer = this.objects.get( camera ).mixer; - if ( mixer !== undefined ) { for ( let i = 0, il = mixer._actions.length; i < il; i ++ ) { @@ -751,15 +703,15 @@ } - } // workaround + } + // workaround _updatePropertyMixersBuffer( mesh ) { const mixer = this.objects.get( mesh ).mixer; const propertyMixers = mixer._bindings; const accuIndex = mixer._accuIndex; - for ( let i = 0, il = propertyMixers.length; i < il; i ++ ) { const propertyMixer = propertyMixers[ i ]; @@ -771,6 +723,7 @@ } } + /* * Avoiding these two issues by restore/save bones before/after mixer animation. * @@ -780,14 +733,11 @@ * * 2. Applying Grant two or more times without reset the posing breaks model. */ - - _saveBones( mesh ) { const objects = this.objects.get( mesh ); const bones = mesh.skeleton.bones; let backupBones = objects.backupBones; - if ( backupBones === undefined ) { backupBones = new Float32Array( bones.length * 7 ); @@ -804,14 +754,12 @@ } } - _restoreBones( mesh ) { const objects = this.objects.get( mesh ); const backupBones = objects.backupBones; if ( backupBones === undefined ) return; const bones = mesh.skeleton.bones; - for ( let i = 0, il = bones.length; i < il; i ++ ) { const bone = bones[ i ]; @@ -820,17 +768,16 @@ } - } // experimental + } + // experimental _getMasterPhysics() { if ( this.masterPhysics !== null ) return this.masterPhysics; - for ( let i = 0, il = this.meshes.length; i < il; i ++ ) { const physics = this.meshes[ i ].physics; - if ( physics !== undefined && physics !== null ) { this.masterPhysics = physics; @@ -843,19 +790,14 @@ return null; } - _updateSharedPhysics( delta ) { if ( this.meshes.length === 0 || ! this.enabled.physics || ! this.sharedPhysics ) return; - const physics = this._getMasterPhysics(); - if ( physics === null ) return; - for ( let i = 0, il = this.meshes.length; i < il; i ++ ) { const p = this.meshes[ i ].physics; - if ( p !== null && p !== undefined ) { p.updateRigidBodies(); @@ -865,11 +807,9 @@ } physics.stepSimulation( delta ); - for ( let i = 0, il = this.meshes.length; i < il; i ++ ) { const p = this.meshes[ i ].physics; - if ( p !== null && p !== undefined ) { p.updateBones(); @@ -880,12 +820,11 @@ } - } // Keep working quaternions for less GC - + } + // Keep working quaternions for less GC const _quaternions = []; let _quaternionIndex = 0; - function getQuaternion() { if ( _quaternionIndex >= _quaternions.length ) { @@ -896,33 +835,33 @@ return _quaternions[ _quaternionIndex ++ ]; - } // Save rotation whose grant and IK are already applied - // used by grant children - + } + // Save rotation whose grant and IK are already applied + // used by grant children const _grantResultMap = new Map(); - function updateOne( mesh, boneIndex, ikSolver, grantSolver ) { const bones = mesh.skeleton.bones; const bonesData = mesh.geometry.userData.MMD.bones; const boneData = bonesData[ boneIndex ]; - const bone = bones[ boneIndex ]; // Return if already updated by being referred as a grant parent. + const bone = bones[ boneIndex ]; + // Return if already updated by being referred as a grant parent. if ( _grantResultMap.has( boneIndex ) ) return; - const quaternion = getQuaternion(); // Initialize grant result here to prevent infinite loop. + const quaternion = getQuaternion(); + + // Initialize grant result here to prevent infinite loop. // If it's referred before updating with actual result later // result without applyting IK or grant is gotten // but better than composing of infinite loop. + _grantResultMap.set( boneIndex, quaternion.copy( bone.quaternion ) ); - _grantResultMap.set( boneIndex, quaternion.copy( bone.quaternion ) ); // @TODO: Support global grant and grant position - - + // @TODO: Support global grant and grant position if ( grantSolver && boneData.grant && ! boneData.grant.isLocal && boneData.grant.affectRotation ) { const parentIndex = boneData.grant.parentIndex; const ratio = boneData.grant.ratio; - if ( ! _grantResultMap.has( parentIndex ) ) { updateOne( mesh, parentIndex, ikSolver, grantSolver ); @@ -938,16 +877,15 @@ // @TODO: Updating world matrices every time solving an IK bone is // costly. Optimize if possible. mesh.updateMatrixWorld( true ); - ikSolver.updateOne( boneData.ik ); // No confident, but it seems the grant results with ik links should be updated? + ikSolver.updateOne( boneData.ik ); + // No confident, but it seems the grant results with ik links should be updated? const links = boneData.ik.links; - for ( let i = 0, il = links.length; i < il; i ++ ) { const link = links[ i ]; if ( link.enabled === false ) continue; const linkIndex = link.index; - if ( _grantResultMap.has( linkIndex ) ) { _grantResultMap.set( linkIndex, _grantResultMap.get( linkIndex ).copy( bones[ linkIndex ].quaternion ) ); @@ -956,13 +894,14 @@ } - } // Update with the actual result here - + } + // Update with the actual result here quaternion.copy( bone.quaternion ); - } // + } + // class AudioManager { @@ -981,12 +920,11 @@ this.duration = this.audioDuration + this.delayTime; } + /** * @param {Number} delta * @return {AudioManager} */ - - control( delta ) { this.elapsed += delta; @@ -995,26 +933,26 @@ if ( this._shouldStartAudio() ) this.audio.play(); return this; - } // private methods + } + // private methods _shouldStartAudio() { if ( this.audio.isPlaying ) return false; - while ( this.currentTime >= this.duration ) { this.currentTime -= this.duration; } - if ( this.currentTime < this.delayTime ) return false; // 'duration' can be bigger than 'audioDuration + delayTime' because of sync configuration + if ( this.currentTime < this.delayTime ) return false; + // 'duration' can be bigger than 'audioDuration + delayTime' because of sync configuration if ( this.currentTime - this.delayTime > this.audioDuration ) return false; return true; } - _shouldStopAudio() { return this.audio.isPlaying && this.currentTime >= this.duration; @@ -1022,8 +960,8 @@ } } - const _q = new THREE.Quaternion(); + /** * Solver for Grant (Fuyo in Japanese. I just google translated because * Fuyo may be MMD specific term and may not be common word in 3D CG terms.) @@ -1032,8 +970,6 @@ * @param {THREE.SkinnedMesh} mesh * @param {Array} grants */ - - class GrantSolver { constructor( mesh, grants = [] ) { @@ -1042,16 +978,14 @@ this.grants = grants; } + /** * Solve all the grant bones * @return {GrantSolver} */ - - update() { const grants = this.grants; - for ( let i = 0, il = grants.length; i < il; i ++ ) { this.updateOne( grants[ i ] ); @@ -1061,25 +995,23 @@ return this; } + /** * Solve a grant bone * @param {Object} grant - grant parameter * @return {GrantSolver} */ - - updateOne( grant ) { const bones = this.mesh.skeleton.bones; const bone = bones[ grant.index ]; const parentBone = bones[ grant.parentIndex ]; - if ( grant.isLocal ) { // TODO: implement - if ( grant.affectPosition ) {} // TODO: implement - + if ( grant.affectPosition ) {} + // TODO: implement if ( grant.affectRotation ) {} } else { @@ -1098,13 +1030,10 @@ return this; } - addGrantRotation( bone, q, ratio ) { _q.set( 0, 0, 0, 1 ); - _q.slerp( q, ratio ); - bone.quaternion.multiply( _q ); return this; diff --git a/examples/js/animation/MMDPhysics.js b/examples/js/animation/MMDPhysics.js index a7a293b351718c..f48291c644292c 100644 --- a/examples/js/animation/MMDPhysics.js +++ b/examples/js/animation/MMDPhysics.js @@ -34,13 +34,13 @@ this.manager = new ResourceManager(); this.mesh = mesh; + /* * I don't know why but 1/60 unitStep easily breaks models * so I set it 1/65 so far. * Don't set too small unitStep because * the smaller unitStep can make the performance worse. */ - this.unitStep = params.unitStep !== undefined ? params.unitStep : 1 / 65; this.maxStepNum = params.maxStepNum !== undefined ? params.maxStepNum : 3; this.gravity = new THREE.Vector3( 0, - 9.8 * 10, 0 ); @@ -49,22 +49,22 @@ this.bodies = []; this.constraints = []; - this._init( mesh, rigidBodyParams, constraintParams ); } + /** * Advances Physics calculation and updates bones. * * @param {Number} delta - time in second * @return {MMDPhysics} */ - - update( delta ) { const manager = this.manager; - const mesh = this.mesh; // rigid bodies and constrains are for + const mesh = this.mesh; + + // rigid bodies and constrains are for // mesh's world scale (1, 1, 1). // Convert to (1, 1, 1) if it isn't. @@ -73,7 +73,6 @@ const quaternion = manager.allocThreeQuaternion(); const scale = manager.allocThreeVector3(); mesh.matrixWorld.decompose( position, quaternion, scale ); - if ( scale.x !== 1 || scale.y !== 1 || scale.z !== 1 ) { isNonDefaultScale = true; @@ -81,7 +80,6 @@ } let parent; - if ( isNonDefaultScale ) { parent = mesh.parent; @@ -90,15 +88,15 @@ mesh.scale.set( 1, 1, 1 ); mesh.updateMatrixWorld( true ); - } // calculate physics and update bones + } + // calculate physics and update bones this._updateRigidBodies(); - this._stepSimulation( delta ); + this._updateBones(); - this._updateBones(); // restore mesh if converted above - + // restore mesh if converted above if ( isNonDefaultScale ) { @@ -113,13 +111,12 @@ return this; } + /** * Resets rigid bodies transorm to current bone's. * * @return {MMDPhysics} */ - - reset() { for ( let i = 0, il = this.bodies.length; i < il; i ++ ) { @@ -131,14 +128,13 @@ return this; } + /** * Warm ups Rigid bodies. Calculates cycles steps. * * @param {Integer} cycles * @return {MMDPhysics} */ - - warmup( cycles ) { for ( let i = 0; i < cycles; i ++ ) { @@ -150,14 +146,13 @@ return this; } + /** * Sets gravity. * * @param {Vector3} gravity * @return {MMDPhysicsHelper} */ - - setGravity( gravity ) { this.world.setGravity( new Ammo.btVector3( gravity.x, gravity.y, gravity.z ) ); @@ -165,23 +160,25 @@ return this; } + /** * Creates MMDPhysicsHelper * * @return {MMDPhysicsHelper} */ - - createHelper() { return new MMDPhysicsHelper( this.mesh, this ); - } // private methods + } + // private methods _init( mesh, rigidBodyParams, constraintParams ) { - const manager = this.manager; // rigid body/constraint parameters are for + const manager = this.manager; + + // rigid body/constraint parameters are for // mesh's default world transform as position(0, 0, 0), // quaternion(0, 0, 0, 1) and scale(0, 0, 0) @@ -197,7 +194,6 @@ mesh.quaternion.set( 0, 0, 0, 1 ); mesh.scale.set( 1, 1, 1 ); mesh.updateMatrixWorld( true ); - if ( this.world === null ) { this.world = this._createWorld(); @@ -206,9 +202,7 @@ } this._initRigidBodies( rigidBodyParams ); - this._initConstraints( constraintParams ); - if ( parent !== null ) mesh.parent = parent; mesh.position.copy( currentPosition ); mesh.quaternion.copy( currentQuaternion ); @@ -220,7 +214,6 @@ manager.freeThreeVector3( currentScale ); } - _createWorld() { const config = new Ammo.btDefaultCollisionConfiguration(); @@ -231,7 +224,6 @@ return world; } - _initRigidBodies( rigidBodies ) { for ( let i = 0, il = rigidBodies.length; i < il; i ++ ) { @@ -241,7 +233,6 @@ } } - _initConstraints( constraints ) { for ( let i = 0, il = constraints.length; i < il; i ++ ) { @@ -254,13 +245,11 @@ } } - _stepSimulation( delta ) { const unitStep = this.unitStep; let stepTime = delta; let maxStepNum = ( delta / unitStep | 0 ) + 1; - if ( stepTime < unitStep ) { stepTime = unitStep; @@ -277,7 +266,6 @@ this.world.stepSimulation( stepTime, maxStepNum, unitStep ); } - _updateRigidBodies() { for ( let i = 0, il = this.bodies.length; i < il; i ++ ) { @@ -287,7 +275,6 @@ } } - _updateBones() { for ( let i = 0, il = this.bodies.length; i < il; i ++ ) { @@ -299,6 +286,7 @@ } } + /** * This manager's responsibilies are * @@ -308,8 +296,6 @@ * * 2. provide simple Ammo object operations. */ - - class ResourceManager { constructor() { @@ -318,104 +304,89 @@ this.threeVector3s = []; this.threeMatrix4s = []; this.threeQuaternions = []; - this.threeEulers = []; // for Ammo.js + this.threeEulers = []; + // for Ammo.js this.transforms = []; this.quaternions = []; this.vector3s = []; } - allocThreeVector3() { return this.threeVector3s.length > 0 ? this.threeVector3s.pop() : new THREE.Vector3(); } - freeThreeVector3( v ) { this.threeVector3s.push( v ); } - allocThreeMatrix4() { return this.threeMatrix4s.length > 0 ? this.threeMatrix4s.pop() : new THREE.Matrix4(); } - freeThreeMatrix4( m ) { this.threeMatrix4s.push( m ); } - allocThreeQuaternion() { return this.threeQuaternions.length > 0 ? this.threeQuaternions.pop() : new THREE.Quaternion(); } - freeThreeQuaternion( q ) { this.threeQuaternions.push( q ); } - allocThreeEuler() { return this.threeEulers.length > 0 ? this.threeEulers.pop() : new THREE.Euler(); } - freeThreeEuler( e ) { this.threeEulers.push( e ); } - allocTransform() { return this.transforms.length > 0 ? this.transforms.pop() : new Ammo.btTransform(); } - freeTransform( t ) { this.transforms.push( t ); } - allocQuaternion() { return this.quaternions.length > 0 ? this.quaternions.pop() : new Ammo.btQuaternion(); } - freeQuaternion( q ) { this.quaternions.push( q ); } - allocVector3() { return this.vector3s.length > 0 ? this.vector3s.pop() : new Ammo.btVector3(); } - freeVector3( v ) { this.vector3s.push( v ); } - setIdentity( t ) { t.setIdentity(); } - getBasis( t ) { var q = this.allocQuaternion(); @@ -423,7 +394,6 @@ return q; } - getBasisAsMatrix3( t ) { var q = this.getBasis( t ); @@ -432,32 +402,27 @@ return m; } - getOrigin( t ) { return t.getOrigin(); } - setOrigin( t, v ) { t.getOrigin().setValue( v.x(), v.y(), v.z() ); } - copyOrigin( t1, t2 ) { var o = t2.getOrigin(); this.setOrigin( t1, o ); } - setBasis( t, q ) { t.setRotation( q ); } - setBasisFromMatrix3( t, m ) { var q = this.matrix3ToQuaternion( m ); @@ -465,19 +430,16 @@ this.freeQuaternion( q ); } - setOriginFromArray3( t, a ) { t.getOrigin().setValue( a[ 0 ], a[ 1 ], a[ 2 ] ); } - setOriginFromThreeVector3( t, v ) { t.getOrigin().setValue( v.x, v.y, v.z ); } - setBasisFromArray3( t, a ) { var thQ = this.allocThreeQuaternion(); @@ -488,7 +450,6 @@ this.freeThreeQuaternion( thQ ); } - setBasisFromThreeQuaternion( t, a ) { var q = this.allocQuaternion(); @@ -500,7 +461,6 @@ this.freeQuaternion( q ); } - multiplyTransforms( t1, t2 ) { var t = this.allocTransform(); @@ -519,7 +479,6 @@ return t; } - inverseTransform( t ) { var t2 = this.allocTransform(); @@ -535,7 +494,6 @@ return t2; } - multiplyMatrices3( m1, m2 ) { var m3 = []; @@ -563,7 +521,6 @@ return m3; } - addVector3( v1, v2 ) { var v = this.allocVector3(); @@ -571,13 +528,11 @@ return v; } - dotVectors3( v1, v2 ) { return v1.x() * v2.x() + v1.y() * v2.y() + v1.z() * v2.z(); } - rowOfMatrix3( m, i ) { var v = this.allocVector3(); @@ -585,7 +540,6 @@ return v; } - columnOfMatrix3( m, i ) { var v = this.allocVector3(); @@ -593,7 +547,6 @@ return v; } - negativeVector3( v ) { var v2 = this.allocVector3(); @@ -601,7 +554,6 @@ return v2; } - multiplyMatrix3ByVector3( m, v ) { var v4 = this.allocVector3(); @@ -618,7 +570,6 @@ return v4; } - transposeMatrix3( m ) { var m2 = []; @@ -634,7 +585,6 @@ return m2; } - quaternionToMatrix3( q ) { var m = []; @@ -663,12 +613,10 @@ return m; } - matrix3ToQuaternion( m ) { var t = m[ 0 ] + m[ 4 ] + m[ 8 ]; var s, x, y, z, w; - if ( t > 0 ) { s = Math.sqrt( t + 1.0 ) * 2; @@ -713,14 +661,13 @@ } } + /** * @param {THREE.SkinnedMesh} mesh * @param {Ammo.btDiscreteDynamicsWorld} world * @param {Object} params * @param {ResourceManager} manager */ - - class RigidBody { constructor( mesh, world, params, manager ) { @@ -733,31 +680,27 @@ this.bone = null; this.boneOffsetForm = null; this.boneOffsetFormInverse = null; - this._init(); } + /** * Resets rigid body transform to the current bone's. * * @return {RigidBody} */ - - reset() { this._setTransformFromBone(); - return this; } + /** * Updates rigid body's transform from the current bone. * * @return {RidigBody} */ - - updateFromBone() { if ( this.params.boneIndex !== - 1 && this.params.type === 0 ) { @@ -769,13 +712,12 @@ return this; } + /** * Updates bone from the current ridid body's transform. * * @return {RidigBody} */ - - updateBone() { if ( this.params.type === 0 || this.params.boneIndex === - 1 ) { @@ -785,7 +727,6 @@ } this._updateBoneRotation(); - if ( this.params.type === 1 ) { this._updateBonePosition(); @@ -793,7 +734,6 @@ } this.bone.updateMatrixWorld( true ); - if ( this.params.type === 2 ) { this._setPositionFromBone(); @@ -802,8 +742,9 @@ return this; - } // private methods + } + // private methods _init() { @@ -813,13 +754,10 @@ case 0: return new Ammo.btSphereShape( p.width ); - case 1: return new Ammo.btBoxShape( new Ammo.btVector3( p.width, p.height, p.depth ) ); - case 2: return new Ammo.btCapsuleShape( p.width, p.height ); - default: throw new Error( 'unknown shape type ' + p.shapeType ); @@ -835,7 +773,6 @@ const weight = params.type === 0 ? 0 : params.weight; const localInertia = manager.allocVector3(); localInertia.setValue( 0, 0, 0 ); - if ( weight !== 0 ) { shape.calculateLocalInertia( weight, localInertia ); @@ -856,16 +793,15 @@ info.set_m_friction( params.friction ); info.set_m_restitution( params.restitution ); const body = new Ammo.btRigidBody( info ); - if ( params.type === 0 ) { body.setCollisionFlags( body.getCollisionFlags() | 2 ); + /* * It'd be better to comment out this line though in general I should call this method * because I'm not sure why but physics will be more like MMD's * if I comment out. */ - body.setActivationState( 4 ); } @@ -883,7 +819,6 @@ manager.freeThreeVector3( vector ); } - _getBoneTransform() { const manager = this.manager; @@ -902,7 +837,6 @@ return form; } - _getWorldTransformForBone() { const manager = this.manager; @@ -910,45 +844,38 @@ return manager.multiplyTransforms( tr, this.boneOffsetFormInverse ); } - _setTransformFromBone() { const manager = this.manager; + const form = this._getBoneTransform(); - const form = this._getBoneTransform(); // TODO: check the most appropriate way to set + // TODO: check the most appropriate way to set //this.body.setWorldTransform( form ); - - this.body.setCenterOfMassTransform( form ); this.body.getMotionState().setWorldTransform( form ); manager.freeTransform( form ); } - _setPositionFromBone() { const manager = this.manager; - const form = this._getBoneTransform(); - const tr = manager.allocTransform(); this.body.getMotionState().getWorldTransform( tr ); - manager.copyOrigin( tr, form ); // TODO: check the most appropriate way to set - //this.body.setWorldTransform( tr ); + manager.copyOrigin( tr, form ); + // TODO: check the most appropriate way to set + //this.body.setWorldTransform( tr ); this.body.setCenterOfMassTransform( tr ); this.body.getMotionState().setWorldTransform( tr ); manager.freeTransform( tr ); manager.freeTransform( form ); } - _updateBoneRotation() { const manager = this.manager; - const tr = this._getWorldTransformForBone(); - const q = manager.getBasis( tr ); const thQ = manager.allocThreeQuaternion(); const thQ2 = manager.allocThreeQuaternion(); @@ -956,12 +883,15 @@ thQ.set( q.x(), q.y(), q.z(), q.w() ); thQ2.setFromRotationMatrix( this.bone.matrixWorld ); thQ2.conjugate(); - thQ2.multiply( thQ ); //this.bone.quaternion.multiply( thQ2 ); + thQ2.multiply( thQ ); - thQ3.setFromRotationMatrix( this.bone.matrix ); // Renormalizing quaternion here because repeatedly transforming + //this.bone.quaternion.multiply( thQ2 ); + + thQ3.setFromRotationMatrix( this.bone.matrix ); + + // Renormalizing quaternion here because repeatedly transforming // quaternion continuously accumulates floating point error and // can end up being overflow. See #15335 - this.bone.quaternion.copy( thQ2.multiply( thQ3 ).normalize() ); manager.freeThreeQuaternion( thQ ); manager.freeThreeQuaternion( thQ2 ); @@ -970,17 +900,13 @@ manager.freeTransform( tr ); } - _updateBonePosition() { const manager = this.manager; - const tr = this._getWorldTransformForBone(); - const thV = manager.allocThreeVector3(); const o = manager.getOrigin( tr ); thV.set( o.x(), o.y(), o.z() ); - if ( this.bone.parent ) { this.bone.parent.worldToLocal( thV ); @@ -993,8 +919,9 @@ } - } // + } + // class Constraint { @@ -1015,11 +942,11 @@ this.params = params; this.manager = manager; this.constraint = null; - this._init(); - } // private method + } + // private method _init() { @@ -1052,7 +979,6 @@ constraint.setLinearUpperLimit( lul ); constraint.setAngularLowerLimit( all ); constraint.setAngularUpperLimit( aul ); - for ( let i = 0; i < 3; i ++ ) { if ( params.springPosition[ i ] !== 0 ) { @@ -1074,14 +1000,13 @@ } } + /* * Currently(10/31/2016) official ammo.js doesn't support * btGeneric6DofSpringConstraint.setParam method. * You need custom ammo.js (add the method into idl) if you wanna use. * By setting this parameter, physics will be more like MMD's */ - - if ( constraint.setParam !== undefined ) { for ( let i = 0; i < 6; i ++ ) { @@ -1108,17 +1033,14 @@ } - } // + } + // const _position = new THREE.Vector3(); - const _quaternion = new THREE.Quaternion(); - const _scale = new THREE.Vector3(); - const _matrixWorldInv = new THREE.Matrix4(); - class MMDPhysicsHelper extends THREE.Object3D { /** @@ -1159,25 +1081,42 @@ opacity: 0.25, transparent: true } ) ); - this._init(); } + /** - * Updates Rigid Bodies visualization. + * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. */ + dispose() { + + const materials = this.materials; + const children = this.children; + for ( let i = 0; i < materials.length; i ++ ) { + + materials[ i ].dispose(); + + } + + for ( let i = 0; i < children.length; i ++ ) { + + const child = children[ i ]; + if ( child.isMesh ) child.geometry.dispose(); + + } + } + /** + * Updates Rigid Bodies visualization. + */ updateMatrixWorld( force ) { var mesh = this.root; - if ( this.visible ) { var bodies = this.physics.bodies; - _matrixWorldInv.copy( mesh.matrixWorld ).decompose( _position, _quaternion, _scale ).compose( _position, _quaternion, _scale.set( 1, 1, 1 ) ).invert(); - for ( var i = 0, il = bodies.length; i < il; i ++ ) { var body = bodies[ i ].body; @@ -1195,26 +1134,23 @@ this.matrix.copy( mesh.matrixWorld ).decompose( _position, _quaternion, _scale ).compose( _position, _quaternion, _scale.set( 1, 1, 1 ) ); super.updateMatrixWorld( force ); - } // private method + } + // private method _init() { var bodies = this.physics.bodies; - function createGeometry( param ) { switch ( param.shapeType ) { case 0: return new THREE.SphereGeometry( param.width, 16, 8 ); - case 1: return new THREE.BoxGeometry( param.width * 2, param.height * 2, param.depth * 2, 8, 8, 8 ); - case 2: - return new createCapsuleGeometry( param.width, param.height, 16, 8 ); - + return new THREE.CapsuleGeometry( param.width, param.height, 8, 16 ); default: return null; @@ -1222,21 +1158,6 @@ } - function createCapsuleGeometry( radius, cylinderHeight, segmentsRadius, segmentsHeight ) { - - var geometry = new THREE.CylinderGeometry( radius, radius, cylinderHeight, segmentsRadius, segmentsHeight, true ); - var upperSphere = new THREE.Mesh( new THREE.SphereGeometry( radius, segmentsRadius, segmentsHeight, 0, Math.PI * 2, 0, Math.PI / 2 ) ); - var lowerSphere = new THREE.Mesh( new THREE.SphereGeometry( radius, segmentsRadius, segmentsHeight, 0, Math.PI * 2, Math.PI / 2, Math.PI / 2 ) ); - upperSphere.position.set( 0, cylinderHeight / 2, 0 ); - lowerSphere.position.set( 0, - cylinderHeight / 2, 0 ); - upperSphere.updateMatrix(); - lowerSphere.updateMatrix(); - geometry.merge( upperSphere.geometry, upperSphere.matrix ); - geometry.merge( lowerSphere.geometry, lowerSphere.matrix ); - return geometry; - - } - for ( var i = 0, il = bodies.length; i < il; i ++ ) { var param = bodies[ i ].params; diff --git a/examples/js/cameras/CinematicCamera.js b/examples/js/cameras/CinematicCamera.js index 63acf090b60af5..4db223f99b3fcd 100644 --- a/examples/js/cameras/CinematicCamera.js +++ b/examples/js/cameras/CinematicCamera.js @@ -20,29 +20,31 @@ fragmentShader: depthShader.fragmentShader } ); this.materialDepth.uniforms[ 'mNear' ].value = near; - this.materialDepth.uniforms[ 'mFar' ].value = far; // In case of cinematicCamera, having a default lens set is important + this.materialDepth.uniforms[ 'mFar' ].value = far; + // In case of cinematicCamera, having a default lens set is important this.setLens(); this.initPostProcessing(); - } // providing fnumber and coc(Circle of Confusion) as extra arguments + } + + // providing fnumber and coc(Circle of Confusion) as extra arguments // In case of cinematicCamera, having a default lens set is important // if fnumber and coc are not provided, cinematicCamera tries to act as a basic THREE.PerspectiveCamera - - setLens( focalLength = 35, filmGauge = 35, fNumber = 8, coc = 0.019 ) { this.filmGauge = filmGauge; this.setFocalLength( focalLength ); this.fNumber = fNumber; - this.coc = coc; // fNumber is focalLength by aperture + this.coc = coc; - this.aperture = focalLength / this.fNumber; // hyperFocal is required to calculate depthOfField when a lens tries to focus at a distance with given fNumber and focalLength + // fNumber is focalLength by aperture + this.aperture = focalLength / this.fNumber; + // hyperFocal is required to calculate depthOfField when a lens tries to focus at a distance with given fNumber and focalLength this.hyperFocal = focalLength * focalLength / ( this.aperture * this.coc ); } - linearize( depth ) { const zfar = this.far; @@ -50,40 +52,42 @@ return - zfar * znear / ( depth * ( zfar - znear ) - zfar ); } - smoothstep( near, far, depth ) { const x = this.saturate( ( depth - near ) / ( far - near ) ); return x * x * ( 3 - 2 * x ); } - saturate( x ) { return Math.max( 0, Math.min( 1, x ) ); - } // function for focusing at a distance from the camera - + } + // function for focusing at a distance from the camera focusAt( focusDistance = 20 ) { - const focalLength = this.getFocalLength(); // distance from the camera (normal to frustrum) to focus on + const focalLength = this.getFocalLength(); - this.focus = focusDistance; // the nearest point from the camera which is in focus (unused) + // distance from the camera (normal to frustrum) to focus on + this.focus = focusDistance; - this.nearPoint = this.hyperFocal * this.focus / ( this.hyperFocal + ( this.focus - focalLength ) ); // the farthest point from the camera which is in focus (unused) + // the nearest point from the camera which is in focus (unused) + this.nearPoint = this.hyperFocal * this.focus / ( this.hyperFocal + ( this.focus - focalLength ) ); - this.farPoint = this.hyperFocal * this.focus / ( this.hyperFocal - ( this.focus - focalLength ) ); // the gap or width of the space in which is everything is in focus (unused) + // the farthest point from the camera which is in focus (unused) + this.farPoint = this.hyperFocal * this.focus / ( this.hyperFocal - ( this.focus - focalLength ) ); - this.depthOfField = this.farPoint - this.nearPoint; // Considering minimum distance of focus for a standard lens (unused) + // the gap or width of the space in which is everything is in focus (unused) + this.depthOfField = this.farPoint - this.nearPoint; + // Considering minimum distance of focus for a standard lens (unused) if ( this.depthOfField < 0 ) this.depthOfField = 0; this.sdistance = this.smoothstep( this.near, this.far, this.focus ); this.ldistance = this.linearize( 1 - this.sdistance ); this.postprocessing.bokeh_uniforms[ 'focalDepth' ].value = this.ldistance; } - initPostProcessing() { if ( this.postprocessing.enabled ) { @@ -101,7 +105,9 @@ this.postprocessing.bokeh_uniforms[ 'shaderFocus' ].value = 0; this.postprocessing.bokeh_uniforms[ 'fstop' ].value = 2.8; this.postprocessing.bokeh_uniforms[ 'showFocus' ].value = 1; - this.postprocessing.bokeh_uniforms[ 'focalDepth' ].value = 0.1; //console.log( this.postprocessing.bokeh_uniforms[ "focalDepth" ].value ); + this.postprocessing.bokeh_uniforms[ 'focalDepth' ].value = 0.1; + + //console.log( this.postprocessing.bokeh_uniforms[ "focalDepth" ].value ); this.postprocessing.bokeh_uniforms[ 'znear' ].value = this.near; this.postprocessing.bokeh_uniforms[ 'zfar' ].value = this.near; @@ -124,23 +130,28 @@ } } - renderCinematic( scene, renderer ) { if ( this.postprocessing.enabled ) { const currentRenderTarget = renderer.getRenderTarget(); - renderer.clear(); // Render scene into texture + renderer.clear(); + + // Render scene into texture scene.overrideMaterial = null; renderer.setRenderTarget( this.postprocessing.rtTextureColor ); renderer.clear(); - renderer.render( scene, this ); // Render depth into texture + renderer.render( scene, this ); + + // Render depth into texture scene.overrideMaterial = this.materialDepth; renderer.setRenderTarget( this.postprocessing.rtTextureDepth ); renderer.clear(); - renderer.render( scene, this ); // Render bokeh composite + renderer.render( scene, this ); + + // Render bokeh composite renderer.setRenderTarget( null ); renderer.render( this.postprocessing.scene, this.postprocessing.camera ); diff --git a/examples/js/controls/ArcballControls.js b/examples/js/controls/ArcballControls.js index 42851f71a700ed..5dc50d4facd237 100644 --- a/examples/js/controls/ArcballControls.js +++ b/examples/js/controls/ArcballControls.js @@ -1,5 +1,6 @@ ( function () { + //trackball state const STATE = { IDLE: Symbol(), ROTATE: Symbol(), @@ -19,18 +20,21 @@ TWO_FINGER: Symbol(), MULT_FINGER: Symbol(), CURSOR: Symbol() - }; //cursor center coordinates + }; + //cursor center coordinates const _center = { x: 0, y: 0 - }; //transformation matrices for gizmos and camera + }; + //transformation matrices for gizmos and camera const _transformation = { camera: new THREE.Matrix4(), gizmos: new THREE.Matrix4() - }; //events + }; + //events const _changeEvent = { type: 'change' }; @@ -40,15 +44,10 @@ const _endEvent = { type: 'end' }; - const _raycaster = new THREE.Raycaster(); - const _offset = new THREE.Vector3(); - const _gizmoMatrixStateTemp = new THREE.Matrix4(); - const _cameraMatrixStateTemp = new THREE.Matrix4(); - const _scalePointTemp = new THREE.Vector3(); /** * @@ -56,14 +55,11 @@ * @param {HTMLElement} domElement Renderer's dom element * @param {Scene} scene The scene to be rendered */ - - class ArcballControls extends THREE.EventDispatcher { constructor( _camera, domElement, scene = null ) { super(); - this.onWindowResize = () => { const scale = ( this._gizmos.scale.x + this._gizmos.scale.y + this._gizmos.scale.z ) / 3; @@ -72,7 +68,6 @@ const curve = new THREE.EllipseCurve( 0, 0, newRadius, newRadius ); const points = curve.getPoints( this._curvePts ); const curveGeometry = new THREE.BufferGeometry().setFromPoints( points ); - for ( const gizmo in this._gizmos.children ) { this._gizmos.children[ gizmo ].geometry = curveGeometry; @@ -108,9 +103,7 @@ this.onPointerCancel = () => { this._touchStart.splice( 0, this._touchStart.length ); - this._touchCurrent.splice( 0, this._touchCurrent.length ); - this._input = INPUT.NONE; }; @@ -120,9 +113,7 @@ if ( event.button == 0 && event.isPrimary ) { this._downValid = true; - this._downEvents.push( event ); - this._downStart = performance.now(); } else { @@ -134,9 +125,7 @@ if ( event.pointerType == 'touch' && this._input != INPUT.CURSOR ) { this._touchStart.push( event ); - this._touchCurrent.push( event ); - switch ( this._input ) { case INPUT.NONE: @@ -146,7 +135,6 @@ window.addEventListener( 'pointermove', this.onPointerMove ); window.addEventListener( 'pointerup', this.onPointerUp ); break; - case INPUT.ONE_FINGER: case INPUT.ONE_FINGER_SWITCHED: //doubleStart @@ -155,7 +143,6 @@ this.onPinchStart(); this.onDoublePanStart(); break; - case INPUT.TWO_FINGER: //multipleStart this._input = INPUT.MULT_FINGER; @@ -167,7 +154,6 @@ } else if ( event.pointerType != 'touch' && this._input == INPUT.NONE ) { let modifier = null; - if ( event.ctrlKey || event.metaKey ) { modifier = 'CTRL'; @@ -179,12 +165,12 @@ } this._mouseOp = this.getOpFromAction( event.button, modifier ); - if ( this._mouseOp != null ) { window.addEventListener( 'pointermove', this.onPointerMove ); - window.addEventListener( 'pointerup', this.onPointerUp ); //singleStart + window.addEventListener( 'pointerup', this.onPointerUp ); + //singleStart this._input = INPUT.CURSOR; this._button = event.button; this.onSinglePanStart( event, this._mouseOp ); @@ -206,10 +192,8 @@ this.updateTouchEvent( event ); this.onSinglePanMove( event, STATE.ROTATE ); break; - case INPUT.ONE_FINGER_SWITCHED: const movement = this.calculatePointersDistance( this._touchCurrent[ 0 ], event ) * this._devPxRatio; - if ( movement >= this._switchSensibility ) { //singleMove @@ -221,7 +205,6 @@ } break; - case INPUT.TWO_FINGER: //rotate/pan/pinchMove this.updateTouchEvent( event ); @@ -229,7 +212,6 @@ this.onPinchMove(); this.onDoublePanMove(); break; - case INPUT.MULT_FINGER: //multMove this.updateTouchEvent( event ); @@ -241,7 +223,6 @@ } else if ( event.pointerType != 'touch' && this._input == INPUT.CURSOR ) { let modifier = null; - if ( event.ctrlKey || event.metaKey ) { modifier = 'CTRL'; @@ -253,20 +234,18 @@ } const mouseOpState = this.getOpStateFromAction( this._button, modifier ); - if ( mouseOpState != null ) { this.onSinglePanMove( event, mouseOpState ); } - } //checkDistance - + } + //checkDistance if ( this._downValid ) { const movement = this.calculatePointersDistance( this._downEvents[ this._downEvents.length - 1 ], event ) * this._devPxRatio; - if ( movement > this._movementThreshold ) { this._downValid = false; @@ -282,15 +261,12 @@ if ( event.pointerType == 'touch' && this._input != INPUT.CURSOR ) { const nTouch = this._touchCurrent.length; - for ( let i = 0; i < nTouch; i ++ ) { if ( this._touchCurrent[ i ].pointerId == event.pointerId ) { this._touchCurrent.splice( i, 1 ); - this._touchStart.splice( i, 1 ); - break; } @@ -307,22 +283,22 @@ this._input = INPUT.NONE; this.onSinglePanEnd(); break; - case INPUT.TWO_FINGER: //doubleEnd this.onDoublePanEnd( event ); this.onPinchEnd( event ); - this.onRotateEnd( event ); //switching to singleStart + this.onRotateEnd( event ); + //switching to singleStart this._input = INPUT.ONE_FINGER_SWITCHED; break; - case INPUT.MULT_FINGER: if ( this._touchCurrent.length == 0 ) { window.removeEventListener( 'pointermove', this.onPointerMove ); - window.removeEventListener( 'pointerup', this.onPointerUp ); //multCancel + window.removeEventListener( 'pointerup', this.onPointerUp ); + //multCancel this._input = INPUT.NONE; this.onTriplePanEnd(); @@ -347,7 +323,6 @@ if ( this._downValid ) { const downTime = event.timeStamp - this._downEvents[ this._downEvents.length - 1 ].timeStamp; - if ( downTime <= this._maxDownTime ) { if ( this._nclicks == 0 ) { @@ -359,26 +334,20 @@ } else { const clickInterval = event.timeStamp - this._clickStart; - const movement = this.calculatePointersDistance( this._downEvents[ 1 ], this._downEvents[ 0 ] ) * this._devPxRatio; - if ( clickInterval <= this._maxInterval && movement <= this._posThreshold ) { //second valid click detected //fire double tap and reset values this._nclicks = 0; - this._downEvents.splice( 0, this._downEvents.length ); - this.onDoubleTap( event ); } else { //new 'first click' this._nclicks = 1; - this._downEvents.shift(); - this._clickStart = performance.now(); } @@ -389,7 +358,6 @@ this._downValid = false; this._nclicks = 0; - this._downEvents.splice( 0, this._downEvents.length ); } @@ -397,7 +365,6 @@ } else { this._nclicks = 0; - this._downEvents.splice( 0, this._downEvents.length ); } @@ -411,7 +378,6 @@ if ( this.enabled && this.enableZoom ) { let modifier = null; - if ( event.ctrlKey || event.metaKey ) { modifier = 'CTRL'; @@ -423,16 +389,13 @@ } const mouseOp = this.getOpFromAction( 'WHEEL', modifier ); - if ( mouseOp != null ) { event.preventDefault(); this.dispatchEvent( _startEvent ); const notchDeltaY = 125; //distance of one notch of mouse wheel - let sgn = event.deltaY / notchDeltaY; let size = 1; - if ( sgn > 0 ) { size = 1 / this.scaleFactor; @@ -447,7 +410,6 @@ case 'ZOOM': this.updateTbState( STATE.SCALE, true ); - if ( sgn > 0 ) { size = 1 / Math.pow( this.scaleFactor, sgn ); @@ -461,7 +423,6 @@ if ( this.cursorZoom && this.enablePan ) { let scalePoint; - if ( this.camera.isOrthographicCamera ) { scalePoint = this.unprojectOnTbPlane( this.camera, event.clientX, event.clientY, this.domElement ).applyQuaternion( this.camera.quaternion ).multiplyScalar( 1 / this.camera.zoom ).add( this._gizmos.position ); @@ -491,11 +452,13 @@ this.dispatchEvent( _changeEvent ); this.dispatchEvent( _endEvent ); break; - case 'FOV': if ( this.camera.isPerspectiveCamera ) { - this.updateTbState( STATE.FOV, true ); //Vertigo effect + this.updateTbState( STATE.FOV, true ); + + //Vertigo effect + // fov / 2 // |\ // | \ @@ -505,13 +468,12 @@ // | \ // | _ _ _\ // y - //check for iOs shift shortcut + //check for iOs shift shortcut if ( event.deltaX != 0 ) { sgn = event.deltaX / notchDeltaY; size = 1; - if ( sgn > 0 ) { size = 1 / Math.pow( this.scaleFactor, sgn ); @@ -525,17 +487,17 @@ } this._v3_1.setFromMatrixPosition( this._cameraMatrixState ); - const x = this._v3_1.distanceTo( this._gizmos.position ); - let xNew = x / size; //distance between camera and gizmos if scale(size, scalepoint) would be performed - //check min and max distance + //check min and max distance xNew = THREE.MathUtils.clamp( xNew, this.minDistance, this.maxDistance ); - const y = x * Math.tan( THREE.MathUtils.DEG2RAD * this.camera.fov * 0.5 ); //calculate new fov + const y = x * Math.tan( THREE.MathUtils.DEG2RAD * this.camera.fov * 0.5 ); - let newFov = THREE.MathUtils.RAD2DEG * ( Math.atan( y / xNew ) * 2 ); //check min and max fov + //calculate new fov + let newFov = THREE.MathUtils.RAD2DEG * ( Math.atan( y / xNew ) * 2 ); + //check min and max fov if ( newFov > this.maxFov ) { newFov = this.maxFov; @@ -579,7 +541,6 @@ this.dispatchEvent( _startEvent ); this.setCenter( event.clientX, event.clientY ); - switch ( operation ) { case 'PAN': @@ -600,9 +561,7 @@ } this.updateTbState( STATE.PAN, true ); - this._startCursorPosition.copy( this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement ) ); - if ( this.enableGrid ) { this.drawGrid(); @@ -611,7 +570,6 @@ } break; - case 'ROTATE': if ( ! this.enableRotate ) { @@ -628,20 +586,14 @@ } this.updateTbState( STATE.ROTATE, true ); - this._startCursorPosition.copy( this.unprojectOnTbSurface( this.camera, _center.x, _center.y, this.domElement, this._tbRadius ) ); - this.activateGizmos( true ); - if ( this.enableAnimations ) { this._timePrev = this._timeCurrent = performance.now(); this._angleCurrent = this._anglePrev = 0; - this._cursorPosPrev.copy( this._startCursorPosition ); - this._cursorPosCurr.copy( this._cursorPosPrev ); - this._wCurr = 0; this._wPrev = this._wCurr; @@ -649,7 +601,6 @@ this.dispatchEvent( _changeEvent ); break; - case 'FOV': if ( ! this.camera.isPerspectiveCamera || ! this.enableZoom ) { @@ -668,13 +619,9 @@ } this.updateTbState( STATE.FOV, true ); - this._startCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 ); - this._currentCursorPosition.copy( this._startCursorPosition ); - break; - case 'ZOOM': if ( ! this.enableZoom ) { @@ -693,11 +640,8 @@ } this.updateTbState( STATE.SCALE, true ); - this._startCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 ); - this._currentCursorPosition.copy( this._startCursorPosition ); - break; } @@ -712,7 +656,6 @@ const restart = opState != this._state; this.setCenter( event.clientX, event.clientY ); - switch ( opState ) { case STATE.PAN: @@ -721,12 +664,11 @@ if ( restart ) { //switch to pan operation + this.dispatchEvent( _endEvent ); this.dispatchEvent( _startEvent ); this.updateTbState( opState, true ); - this._startCursorPosition.copy( this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement ) ); - if ( this.enableGrid ) { this.drawGrid(); @@ -739,7 +681,6 @@ //continue with pan operation this._currentCursorPosition.copy( this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement ) ); - this.applyTransformMatrix( this.pan( this._startCursorPosition, this._currentCursorPosition ) ); } @@ -747,19 +688,17 @@ } break; - case STATE.ROTATE: if ( this.enableRotate ) { if ( restart ) { //switch to rotate operation + this.dispatchEvent( _endEvent ); this.dispatchEvent( _startEvent ); this.updateTbState( opState, true ); - this._startCursorPosition.copy( this.unprojectOnTbSurface( this.camera, _center.x, _center.y, this.domElement, this._tbRadius ) ); - if ( this.enableGrid ) { this.disposeGrid(); @@ -772,26 +711,19 @@ //continue with rotate operation this._currentCursorPosition.copy( this.unprojectOnTbSurface( this.camera, _center.x, _center.y, this.domElement, this._tbRadius ) ); - const distance = this._startCursorPosition.distanceTo( this._currentCursorPosition ); - const angle = this._startCursorPosition.angleTo( this._currentCursorPosition ); - const amount = Math.max( distance / this._tbRadius, angle ); //effective rotation angle this.applyTransformMatrix( this.rotate( this.calculateRotationAxis( this._startCursorPosition, this._currentCursorPosition ), amount ) ); - if ( this.enableAnimations ) { this._timePrev = this._timeCurrent; this._timeCurrent = performance.now(); this._anglePrev = this._angleCurrent; this._angleCurrent = amount; - this._cursorPosPrev.copy( this._cursorPosCurr ); - this._cursorPosCurr.copy( this._currentCursorPosition ); - this._wPrev = this._wCurr; this._wCurr = this.calculateAngularSpeed( this._anglePrev, this._angleCurrent, this._timePrev, this._timeCurrent ); @@ -802,21 +734,18 @@ } break; - case STATE.SCALE: if ( this.enableZoom ) { if ( restart ) { //switch to zoom operation + this.dispatchEvent( _endEvent ); this.dispatchEvent( _startEvent ); this.updateTbState( opState, true ); - this._startCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 ); - this._currentCursorPosition.copy( this._startCursorPosition ); - if ( this.enableGrid ) { this.disposeGrid(); @@ -829,12 +758,9 @@ //continue with zoom operation const screenNotches = 8; //how many wheel notches corresponds to a full screen pan - this._currentCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 ); - const movement = this._currentCursorPosition.y - this._startCursorPosition.y; let size = 1; - if ( movement < 0 ) { size = 1 / Math.pow( this.scaleFactor, - movement * screenNotches ); @@ -846,7 +772,6 @@ } this._v3_1.setFromMatrixPosition( this._gizmoMatrixState ); - this.applyTransformMatrix( this.scale( size, this._v3_1 ) ); } @@ -854,21 +779,18 @@ } break; - case STATE.FOV: if ( this.enableZoom && this.camera.isPerspectiveCamera ) { if ( restart ) { //switch to fov operation + this.dispatchEvent( _endEvent ); this.dispatchEvent( _startEvent ); this.updateTbState( opState, true ); - this._startCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 ); - this._currentCursorPosition.copy( this._startCursorPosition ); - if ( this.enableGrid ) { this.disposeGrid(); @@ -881,12 +803,9 @@ //continue with fov operation const screenNotches = 8; //how many wheel notches corresponds to a full screen pan - this._currentCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 ); - const movement = this._currentCursorPosition.y - this._startCursorPosition.y; let size = 1; - if ( movement < 0 ) { size = 1 / Math.pow( this.scaleFactor, - movement * screenNotches ); @@ -898,28 +817,26 @@ } this._v3_1.setFromMatrixPosition( this._cameraMatrixState ); - const x = this._v3_1.distanceTo( this._gizmos.position ); - let xNew = x / size; //distance between camera and gizmos if scale(size, scalepoint) would be performed - //check min and max distance + //check min and max distance xNew = THREE.MathUtils.clamp( xNew, this.minDistance, this.maxDistance ); - const y = x * Math.tan( THREE.MathUtils.DEG2RAD * this._fovState * 0.5 ); //calculate new fov + const y = x * Math.tan( THREE.MathUtils.DEG2RAD * this._fovState * 0.5 ); - let newFov = THREE.MathUtils.RAD2DEG * ( Math.atan( y / xNew ) * 2 ); //check min and max fov + //calculate new fov + let newFov = THREE.MathUtils.RAD2DEG * ( Math.atan( y / xNew ) * 2 ); + //check min and max fov newFov = THREE.MathUtils.clamp( newFov, this.minFov, this.maxFov ); const newDistance = y / Math.tan( THREE.MathUtils.DEG2RAD * ( newFov / 2 ) ); size = x / newDistance; - this._v3_2.setFromMatrixPosition( this._gizmoMatrixState ); - this.setFov( newFov ); - this.applyTransformMatrix( this.scale( size, this._v3_2, false ) ); //adjusting distance + this.applyTransformMatrix( this.scale( size, this._v3_2, false ) ); + //adjusting distance _offset.copy( this._gizmos.position ).sub( this.camera.position ).normalize().multiplyScalar( newDistance / x ); - this._m4_1.makeTranslation( _offset.x, _offset.y, _offset.z ); } @@ -950,7 +867,6 @@ //perform rotation animation const deltaTime = performance.now() - this._timeCurrent; - if ( deltaTime < 120 ) { const w = Math.abs( ( this._wPrev + this._wCurr ) / 2 ); @@ -983,7 +899,6 @@ } else if ( this._state == STATE.PAN || this._state == STATE.IDLE ) { this.updateTbState( STATE.IDLE, false ); - if ( this.enableGrid ) { this.disposeGrid(); @@ -1006,11 +921,9 @@ this.dispatchEvent( _startEvent ); this.setCenter( event.clientX, event.clientY ); const hitP = this.unprojectOnObj( this.getCursorNDC( _center.x, _center.y, this.domElement ), this.camera ); - if ( hitP != null && this.enableAnimations ) { const self = this; - if ( this._animationId != - 1 ) { window.cancelAnimationFrame( this._animationId ); @@ -1047,11 +960,8 @@ this.dispatchEvent( _startEvent ); this.updateTbState( STATE.PAN, true ); this.setCenter( ( this._touchCurrent[ 0 ].clientX + this._touchCurrent[ 1 ].clientX ) / 2, ( this._touchCurrent[ 0 ].clientY + this._touchCurrent[ 1 ].clientY ) / 2 ); - this._startCursorPosition.copy( this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement, true ) ); - this._currentCursorPosition.copy( this._startCursorPosition ); - this.activateGizmos( false ); } @@ -1063,17 +973,14 @@ if ( this.enabled && this.enablePan ) { this.setCenter( ( this._touchCurrent[ 0 ].clientX + this._touchCurrent[ 1 ].clientX ) / 2, ( this._touchCurrent[ 0 ].clientY + this._touchCurrent[ 1 ].clientY ) / 2 ); - if ( this._state != STATE.PAN ) { this.updateTbState( STATE.PAN, true ); - this._startCursorPosition.copy( this._currentCursorPosition ); } this._currentCursorPosition.copy( this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement, true ) ); - this.applyTransformMatrix( this.pan( this._startCursorPosition, this._currentCursorPosition, true ) ); this.dispatchEvent( _changeEvent ); @@ -1093,7 +1000,9 @@ if ( this.enabled && this.enableRotate ) { this.dispatchEvent( _startEvent ); - this.updateTbState( STATE.ZROTATE, true ); //this._startFingerRotation = event.rotation; + this.updateTbState( STATE.ZROTATE, true ); + + //this._startFingerRotation = event.rotation; this._startFingerRotation = this.getAngle( this._touchCurrent[ 1 ], this._touchCurrent[ 0 ] ) + this.getAngle( this._touchStart[ 1 ], this._touchStart[ 0 ] ); this._currentFingerRotation = this._startFingerRotation; @@ -1115,17 +1024,15 @@ this.setCenter( ( this._touchCurrent[ 0 ].clientX + this._touchCurrent[ 1 ].clientX ) / 2, ( this._touchCurrent[ 0 ].clientY + this._touchCurrent[ 1 ].clientY ) / 2 ); let rotationPoint; - if ( this._state != STATE.ZROTATE ) { this.updateTbState( STATE.ZROTATE, true ); this._startFingerRotation = this._currentFingerRotation; - } //this._currentFingerRotation = event.rotation; - + } + //this._currentFingerRotation = event.rotation; this._currentFingerRotation = this.getAngle( this._touchCurrent[ 1 ], this._touchCurrent[ 0 ] ) + this.getAngle( this._touchStart[ 1 ], this._touchStart[ 0 ] ); - if ( ! this.enablePan ) { rotationPoint = new THREE.Vector3().setFromMatrixPosition( this._gizmoMatrixState ); @@ -1133,7 +1040,6 @@ } else { this._v3_2.setFromMatrixPosition( this._gizmoMatrixState ); - rotationPoint = this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement ).applyQuaternion( this.camera.quaternion ).multiplyScalar( 1 / this.camera.zoom ).add( this._v3_2 ); } @@ -1185,7 +1091,6 @@ this._currentFingerDistance = Math.max( this.calculatePointersDistance( this._touchCurrent[ 0 ], this._touchCurrent[ 1 ] ), minDistance * this._devPxRatio ); const amount = this._currentFingerDistance / this._startFingerDistance; let scalePoint; - if ( ! this.enablePan ) { scalePoint = this._gizmos.position; @@ -1223,12 +1128,12 @@ if ( this.enabled && this.enableZoom ) { this.dispatchEvent( _startEvent ); - this.updateTbState( STATE.SCALE, true ); //const center = event.center; + this.updateTbState( STATE.SCALE, true ); + //const center = event.center; let clientX = 0; let clientY = 0; const nFingers = this._touchCurrent.length; - for ( let i = 0; i < nFingers; i ++ ) { clientX += this._touchCurrent[ i ].clientX; @@ -1237,9 +1142,7 @@ } this.setCenter( clientX / nFingers, clientY / nFingers ); - this._startCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 ); - this._currentCursorPosition.copy( this._startCursorPosition ); } @@ -1259,11 +1162,11 @@ // | \ // | _ _ _\ // y + //const center = event.center; let clientX = 0; let clientY = 0; const nFingers = this._touchCurrent.length; - for ( let i = 0; i < nFingers; i ++ ) { clientX += this._touchCurrent[ i ].clientX; @@ -1273,12 +1176,9 @@ this.setCenter( clientX / nFingers, clientY / nFingers ); const screenNotches = 8; //how many wheel notches corresponds to a full screen pan - this._currentCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 ); - const movement = this._currentCursorPosition.y - this._startCursorPosition.y; let size = 1; - if ( movement < 0 ) { size = 1 / Math.pow( this.scaleFactor, - movement * screenNotches ); @@ -1290,30 +1190,27 @@ } this._v3_1.setFromMatrixPosition( this._cameraMatrixState ); - const x = this._v3_1.distanceTo( this._gizmos.position ); - let xNew = x / size; //distance between camera and gizmos if scale(size, scalepoint) would be performed - //check min and max distance + //check min and max distance xNew = THREE.MathUtils.clamp( xNew, this.minDistance, this.maxDistance ); - const y = x * Math.tan( THREE.MathUtils.DEG2RAD * this._fovState * 0.5 ); //calculate new fov + const y = x * Math.tan( THREE.MathUtils.DEG2RAD * this._fovState * 0.5 ); - let newFov = THREE.MathUtils.RAD2DEG * ( Math.atan( y / xNew ) * 2 ); //check min and max fov + //calculate new fov + let newFov = THREE.MathUtils.RAD2DEG * ( Math.atan( y / xNew ) * 2 ); + //check min and max fov newFov = THREE.MathUtils.clamp( newFov, this.minFov, this.maxFov ); const newDistance = y / Math.tan( THREE.MathUtils.DEG2RAD * ( newFov / 2 ) ); size = x / newDistance; - this._v3_2.setFromMatrixPosition( this._gizmoMatrixState ); - this.setFov( newFov ); - this.applyTransformMatrix( this.scale( size, this._v3_2, false ) ); //adjusting distance + this.applyTransformMatrix( this.scale( size, this._v3_2, false ) ); + //adjusting distance _offset.copy( this._gizmos.position ).sub( this.camera.position ).normalize().multiplyScalar( newDistance / x ); - this._m4_1.makeTranslation( _offset.x, _offset.y, _offset.z ); - this.dispatchEvent( _changeEvent ); } @@ -1323,7 +1220,8 @@ this.onTriplePanEnd = () => { this.updateTbState( STATE.IDLE, false ); - this.dispatchEvent( _endEvent ); //this.dispatchEvent( _changeEvent ); + this.dispatchEvent( _endEvent ); + //this.dispatchEvent( _changeEvent ); }; @@ -1374,7 +1272,6 @@ const mouseInput = [ 0, 1, 2, 'WHEEL' ]; const keyInput = [ 'CTRL', 'SHIFT', null ]; let state; - if ( ! operationInput.includes( operation ) || ! mouseInput.includes( mouse ) || ! keyInput.includes( key ) ) { //invalid parameters @@ -1398,15 +1295,12 @@ case 'PAN': state = STATE.PAN; break; - case 'ROTATE': state = STATE.ROTATE; break; - case 'ZOOM': state = STATE.SCALE; break; - case 'FOV': state = STATE.FOV; break; @@ -1419,7 +1313,6 @@ key: key, state: state }; - for ( let i = 0; i < this.mouseActions.length; i ++ ) { if ( this.mouseActions[ i ].mouse == action.mouse && this.mouseActions[ i ].key == action.key ) { @@ -1456,11 +1349,9 @@ this.getOpFromAction = ( mouse, key ) => { let action; - for ( let i = 0; i < this.mouseActions.length; i ++ ) { action = this.mouseActions[ i ]; - if ( action.mouse == mouse && action.key == key ) { return action.operation; @@ -1474,7 +1365,6 @@ for ( let i = 0; i < this.mouseActions.length; i ++ ) { action = this.mouseActions[ i ]; - if ( action.mouse == mouse && action.key == null ) { return action.operation; @@ -1492,11 +1382,9 @@ this.getOpStateFromAction = ( mouse, key ) => { let action; - for ( let i = 0; i < this.mouseActions.length; i ++ ) { action = this.mouseActions[ i ]; - if ( action.mouse == mouse && action.key == key ) { return action.state; @@ -1510,7 +1398,6 @@ for ( let i = 0; i < this.mouseActions.length; i ++ ) { action = this.mouseActions[ i ]; - if ( action.mouse == mouse && action.key == null ) { return action.state; @@ -1538,7 +1425,6 @@ if ( this._touchCurrent[ i ].pointerId == event.pointerId ) { this._touchCurrent.splice( i, 1, event ); - break; } @@ -1551,7 +1437,6 @@ const s = p1 - p0; const t = ( t1 - t0 ) / 1000; - if ( t == 0 ) { return 0; @@ -1571,11 +1456,8 @@ this.calculateRotationAxis = ( vec1, vec2 ) => { this._rotationMatrix.extractRotation( this._cameraMatrixState ); - this._quat.setFromRotationMatrix( this._rotationMatrix ); - this._rotationAxis.crossVectors( vec1, vec2 ).applyQuaternion( this._quat ); - return this._rotationAxis.normalize().clone(); }; @@ -1583,13 +1465,10 @@ this.calculateTbRadius = camera => { const distance = camera.position.distanceTo( this._gizmos.position ); - if ( camera.type == 'PerspectiveCamera' ) { const halfFovV = THREE.MathUtils.DEG2RAD * camera.fov * 0.5; //vertical fov/2 in radians - const halfFovH = Math.atan( camera.aspect * Math.tan( halfFovV ) ); //horizontal fov/2 in radians - return Math.tan( Math.min( halfFovV, halfFovH ) ) * distance * this.radiusFactor; } else if ( camera.type == 'OrthographicCamera' ) { @@ -1604,22 +1483,15 @@ //move center of camera (along with gizmos) towards point of interest _offset.copy( point ).sub( this._gizmos.position ).multiplyScalar( amount ); - this._translationMatrix.makeTranslation( _offset.x, _offset.y, _offset.z ); - _gizmoMatrixStateTemp.copy( this._gizmoMatrixState ); - this._gizmoMatrixState.premultiply( this._translationMatrix ); - this._gizmoMatrixState.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale ); - _cameraMatrixStateTemp.copy( this._cameraMatrixState ); - this._cameraMatrixState.premultiply( this._translationMatrix ); + this._cameraMatrixState.decompose( this.camera.position, this.camera.quaternion, this.camera.scale ); - this._cameraMatrixState.decompose( this.camera.position, this.camera.quaternion, this.camera.scale ); //apply zoom - - + //apply zoom if ( this.enableZoom ) { this.applyTransformMatrix( this.scale( size, this._gizmos.position ) ); @@ -1627,7 +1499,6 @@ } this._gizmoMatrixState.copy( _gizmoMatrixStateTemp ); - this._cameraMatrixState.copy( _cameraMatrixStateTemp ); }; @@ -1639,7 +1510,6 @@ const color = 0x888888; const multiplier = 3; let size, divisions, maxLength, tick; - if ( this.camera.isOrthographicCamera ) { const width = this.camera.right - this.camera.left; @@ -1664,15 +1534,10 @@ if ( this._grid == null ) { this._grid = new THREE.GridHelper( size, divisions, color, color ); - this._grid.position.copy( this._gizmos.position ); - this._gridPosition.copy( this._grid.position ); - this._grid.quaternion.copy( this.camera.quaternion ); - this._grid.rotateX( Math.PI * 0.5 ); - this.scene.add( this._grid ); } @@ -1723,7 +1588,6 @@ const gizmoX = this._gizmos.children[ 0 ]; const gizmoY = this._gizmos.children[ 1 ]; const gizmoZ = this._gizmos.children[ 2 ]; - if ( isActive ) { gizmoX.material.setValues( { @@ -1755,11 +1619,8 @@ this.getCursorNDC = ( cursorX, cursorY, canvas ) => { const canvasRect = canvas.getBoundingClientRect(); - this._v2_1.setX( ( cursorX - canvasRect.left ) / canvasRect.width * 2 - 1 ); - this._v2_1.setY( ( canvasRect.bottom - cursorY ) / canvasRect.height * 2 - 1 ); - return this._v2_1.clone(); }; @@ -1767,7 +1628,6 @@ this.getCursorPosition = ( cursorX, cursorY, canvas ) => { this._v2_1.copy( this.getCursorNDC( cursorX, cursorY, canvas ) ); - this._v2_1.x *= ( this.camera.right - this.camera.left ) * 0.5; this._v2_1.y *= ( this.camera.top - this.camera.bottom ) * 0.5; return this._v2_1.clone(); @@ -1777,8 +1637,9 @@ this.setCamera = camera => { camera.lookAt( this.target ); - camera.updateMatrix(); //setting state + camera.updateMatrix(); + //setting state if ( camera.type == 'PerspectiveCamera' ) { this._fov0 = camera.fov; @@ -1787,11 +1648,8 @@ } this._cameraMatrixState0.copy( camera.matrix ); - this._cameraMatrixState.copy( this._cameraMatrixState0 ); - this._cameraProjectionState.copy( camera.projectionMatrix ); - this._zoom0 = camera.zoom; this._zoomState = this._zoom0; this._initialNear = camera.near; @@ -1800,14 +1658,12 @@ this._initialFar = camera.far; this._farPos0 = camera.position.distanceTo( this.target ) - camera.far; this._farPos = this._initialFar; - this._up0.copy( camera.up ); - this._upState.copy( camera.up ); - this.camera = camera; - this.camera.updateProjectionMatrix(); //making gizmos + this.camera.updateProjectionMatrix(); + //making gizmos this._tbRadius = this.calculateTbRadius( camera ); this.makeGizmos( this.target, this._tbRadius ); @@ -1816,10 +1672,12 @@ this.makeGizmos = ( tbCenter, tbRadius ) => { const curve = new THREE.EllipseCurve( 0, 0, tbRadius, tbRadius ); - const points = curve.getPoints( this._curvePts ); //geometry + const points = curve.getPoints( this._curvePts ); - const curveGeometry = new THREE.BufferGeometry().setFromPoints( points ); //material + //geometry + const curveGeometry = new THREE.BufferGeometry().setFromPoints( points ); + //material const curveMaterialX = new THREE.LineBasicMaterial( { color: 0xff8080, fog: false, @@ -1837,38 +1695,34 @@ fog: false, transparent: true, opacity: 0.6 - } ); //line + } ); + //line const gizmoX = new THREE.Line( curveGeometry, curveMaterialX ); const gizmoY = new THREE.Line( curveGeometry, curveMaterialY ); const gizmoZ = new THREE.Line( curveGeometry, curveMaterialZ ); const rotation = Math.PI * 0.5; gizmoX.rotation.x = rotation; - gizmoY.rotation.y = rotation; //setting state + gizmoY.rotation.y = rotation; + //setting state this._gizmoMatrixState0.identity().setPosition( tbCenter ); - this._gizmoMatrixState.copy( this._gizmoMatrixState0 ); - if ( this.camera.zoom !== 1 ) { //adapt gizmos size to camera zoom const size = 1 / this.camera.zoom; - this._scaleMatrix.makeScale( size, size, size ); - this._translationMatrix.makeTranslation( - tbCenter.x, - tbCenter.y, - tbCenter.z ); - this._gizmoMatrixState.premultiply( this._translationMatrix ).premultiply( this._scaleMatrix ); - this._translationMatrix.makeTranslation( tbCenter.x, tbCenter.y, tbCenter.z ); - this._gizmoMatrixState.premultiply( this._translationMatrix ); } - this._gizmoMatrixState.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale ); // + this._gizmoMatrixState.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale ); + // this._gizmos.traverse( function ( object ) { @@ -1880,14 +1734,12 @@ } } ); + this._gizmos.clear(); - this._gizmos.clear(); // - + // this._gizmos.add( gizmoX ); - this._gizmos.add( gizmoY ); - this._gizmos.add( gizmoZ ); }; @@ -1905,14 +1757,12 @@ const deltaTime = time - this._timeStart; const animTime = deltaTime / this.focusAnimationTime; - this._gizmoMatrixState.copy( gizmoMatrix ); - if ( animTime >= 1 ) { //animation end - this._gizmoMatrixState.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale ); + this._gizmoMatrixState.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale ); this.focus( point, this.scaleFactor ); this._timeStart = - 1; this.updateTbState( STATE.IDLE, false ); @@ -1923,9 +1773,7 @@ const amount = this.easeOutCubic( animTime ); const size = 1 - amount + this.scaleFactor * amount; - this._gizmoMatrixState.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale ); - this.focus( point, size, amount ); this.dispatchEvent( _changeEvent ); const self = this; @@ -1940,6 +1788,7 @@ } else { //interrupt animation + this._animationId = - 1; this._timeStart = - 1; @@ -1963,7 +1812,6 @@ //w = w0 + alpha * t const deltaTime = ( time - this._timeStart ) / 1000; const w = w0 + - this.dampingFactor * deltaTime; - if ( w > 0 ) { //tetha = 0.5 * alpha * t^2 + w0 * t + tetha0 @@ -1990,9 +1838,9 @@ } else { //interrupt animation + this._animationId = - 1; this._timeStart = - 1; - if ( this._state != STATE.ROTATE ) { this.activateGizmos( false ); @@ -2007,7 +1855,6 @@ this.pan = ( p0, p1, adjust = false ) => { const movement = p0.clone().sub( p1 ); - if ( this.camera.isOrthographicCamera ) { //adjust movement amount @@ -2017,20 +1864,14 @@ //adjust movement amount this._v3_1.setFromMatrixPosition( this._cameraMatrixState0 ); //camera's initial position - - this._v3_2.setFromMatrixPosition( this._gizmoMatrixState0 ); //gizmo's initial position - - const distanceFactor = this._v3_1.distanceTo( this._v3_2 ) / this.camera.position.distanceTo( this._gizmos.position ); movement.multiplyScalar( 1 / distanceFactor ); } this._v3_1.set( movement.x, movement.y, 0 ).applyQuaternion( this.camera.quaternion ); - this._m4_1.makeTranslation( this._v3_1.x, this._v3_1.y, this._v3_1.z ); - this.setTransformationMatrices( this._m4_1, this._m4_1 ); return _transformation; @@ -2039,7 +1880,6 @@ this.reset = () => { this.camera.zoom = this._zoom0; - if ( this.camera.isPerspectiveCamera ) { this.camera.fov = this._fov0; @@ -2048,21 +1888,14 @@ this.camera.near = this._nearPos; this.camera.far = this._farPos; - this._cameraMatrixState.copy( this._cameraMatrixState0 ); - this._cameraMatrixState.decompose( this.camera.position, this.camera.quaternion, this.camera.scale ); - this.camera.up.copy( this._up0 ); this.camera.updateMatrix(); this.camera.updateProjectionMatrix(); - this._gizmoMatrixState.copy( this._gizmoMatrixState0 ); - this._gizmoMatrixState0.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale ); - this._gizmos.updateMatrix(); - this._tbRadius = this.calculateTbRadius( this.camera ); this.makeGizmos( this._gizmos.position, this._tbRadius ); this.camera.lookAt( this._gizmos.position ); @@ -2074,18 +1907,13 @@ this.rotate = ( axis, angle ) => { const point = this._gizmos.position; //rotation center - this._translationMatrix.makeTranslation( - point.x, - point.y, - point.z ); + this._rotationMatrix.makeRotationAxis( axis, - angle ); - this._rotationMatrix.makeRotationAxis( axis, - angle ); //rotate camera - - + //rotate camera this._m4_1.makeTranslation( point.x, point.y, point.z ); - this._m4_1.multiply( this._rotationMatrix ); - this._m4_1.multiply( this._translationMatrix ); - this.setTransformationMatrices( this._m4_1 ); return _transformation; @@ -2094,7 +1922,6 @@ this.copyState = () => { let state; - if ( this.camera.isOrthographicCamera ) { state = JSON.stringify( { @@ -2142,15 +1969,11 @@ this.saveState = () => { this._cameraMatrixState0.copy( this.camera.matrix ); - this._gizmoMatrixState0.copy( this._gizmos.matrix ); - this._nearPos = this.camera.near; this._farPos = this.camera.far; this._zoom0 = this.camera.zoom; - this._up0.copy( this.camera.up ); - if ( this.camera.isPerspectiveCamera ) { this._fov0 = this.camera.fov; @@ -2162,15 +1985,14 @@ this.scale = ( size, point, scaleGizmos = true ) => { _scalePointTemp.copy( point ); - let sizeInverse = 1 / size; - if ( this.camera.isOrthographicCamera ) { //camera zoom this.camera.zoom = this._zoomState; - this.camera.zoom *= size; //check min and max zoom + this.camera.zoom *= size; + //check min and max zoom if ( this.camera.zoom > this.maxZoom ) { this.camera.zoom = this.maxZoom; @@ -2184,46 +2006,34 @@ } this.camera.updateProjectionMatrix(); - this._v3_1.setFromMatrixPosition( this._gizmoMatrixState ); //gizmos position - //scale gizmos so they appear in the same spot having the same dimension - + //scale gizmos so they appear in the same spot having the same dimension this._scaleMatrix.makeScale( sizeInverse, sizeInverse, sizeInverse ); - this._translationMatrix.makeTranslation( - this._v3_1.x, - this._v3_1.y, - this._v3_1.z ); - this._m4_2.makeTranslation( this._v3_1.x, this._v3_1.y, this._v3_1.z ).multiply( this._scaleMatrix ); + this._m4_2.multiply( this._translationMatrix ); - this._m4_2.multiply( this._translationMatrix ); //move camera and gizmos to obtain pinch effect - - + //move camera and gizmos to obtain pinch effect _scalePointTemp.sub( this._v3_1 ); - const amount = _scalePointTemp.clone().multiplyScalar( sizeInverse ); - _scalePointTemp.sub( amount ); - this._m4_1.makeTranslation( _scalePointTemp.x, _scalePointTemp.y, _scalePointTemp.z ); - this._m4_2.premultiply( this._m4_1 ); - this.setTransformationMatrices( this._m4_1, this._m4_2 ); return _transformation; } else if ( this.camera.isPerspectiveCamera ) { this._v3_1.setFromMatrixPosition( this._cameraMatrixState ); + this._v3_2.setFromMatrixPosition( this._gizmoMatrixState ); - this._v3_2.setFromMatrixPosition( this._gizmoMatrixState ); //move camera - - + //move camera let distance = this._v3_1.distanceTo( _scalePointTemp ); + let amount = distance - distance * sizeInverse; - let amount = distance - distance * sizeInverse; //check min and max distance - + //check min and max distance const newDistance = distance - amount; - if ( newDistance < this.minDistance ) { sizeInverse = this.minDistance / distance; @@ -2237,30 +2047,20 @@ } _offset.copy( _scalePointTemp ).sub( this._v3_1 ).normalize().multiplyScalar( amount ); - this._m4_1.makeTranslation( _offset.x, _offset.y, _offset.z ); - if ( scaleGizmos ) { //scale gizmos so they appear in the same spot having the same dimension const pos = this._v3_2; distance = pos.distanceTo( _scalePointTemp ); amount = distance - distance * sizeInverse; - _offset.copy( _scalePointTemp ).sub( this._v3_2 ).normalize().multiplyScalar( amount ); - this._translationMatrix.makeTranslation( pos.x, pos.y, pos.z ); - this._scaleMatrix.makeScale( sizeInverse, sizeInverse, sizeInverse ); - this._m4_2.makeTranslation( _offset.x, _offset.y, _offset.z ).multiply( this._translationMatrix ); - this._m4_2.multiply( this._scaleMatrix ); - this._translationMatrix.makeTranslation( - pos.x, - pos.y, - pos.z ); - this._m4_2.multiply( this._translationMatrix ); - this.setTransformationMatrices( this._m4_1, this._m4_2 ); } else { @@ -2289,25 +2089,14 @@ this.zRotate = ( point, angle ) => { this._rotationMatrix.makeRotationAxis( this._rotationAxis, angle ); - this._translationMatrix.makeTranslation( - point.x, - point.y, - point.z ); - this._m4_1.makeTranslation( point.x, point.y, point.z ); - this._m4_1.multiply( this._rotationMatrix ); - this._m4_1.multiply( this._translationMatrix ); - this._v3_1.setFromMatrixPosition( this._gizmoMatrixState ).sub( point ); //vector from rotation center to gizmos position - - this._v3_2.copy( this._v3_1 ).applyAxisAngle( this._rotationAxis, angle ); //apply rotation - - this._v3_2.sub( this._v3_1 ); - this._m4_2.makeTranslation( this._v3_2.x, this._v3_2.y, this._v3_2.z ); - this.setTransformationMatrices( this._m4_1, this._m4_2 ); return _transformation; @@ -2320,7 +2109,6 @@ raycaster.far = camera.far; raycaster.setFromCamera( cursor, camera ); const intersect = raycaster.intersectObjects( this.scene.children, true ); - for ( let i = 0; i < intersect.length; i ++ ) { if ( intersect[ i ].object.uuid != this._gizmos.uuid && intersect[ i ].face != null ) { @@ -2340,13 +2128,10 @@ if ( camera.type == 'OrthographicCamera' ) { this._v2_1.copy( this.getCursorPosition( cursorX, cursorY, canvas ) ); - this._v3_1.set( this._v2_1.x, this._v2_1.y, 0 ); - const x2 = Math.pow( this._v2_1.x, 2 ); const y2 = Math.pow( this._v2_1.y, 2 ); const r2 = Math.pow( this._tbRadius, 2 ); - if ( x2 + y2 <= r2 * 0.5 ) { //intersection with sphere @@ -2365,16 +2150,13 @@ //unproject cursor on the near plane this._v2_1.copy( this.getCursorNDC( cursorX, cursorY, canvas ) ); - this._v3_1.set( this._v2_1.x, this._v2_1.y, - 1 ); - this._v3_1.applyMatrix4( camera.projectionMatrixInverse ); - const rayDir = this._v3_1.clone().normalize(); //unprojected ray direction - - const cameraGizmoDistance = camera.position.distanceTo( this._gizmos.position ); - const radius2 = Math.pow( tbRadius, 2 ); // camera + const radius2 = Math.pow( tbRadius, 2 ); + + // camera // |\ // | \ // | \ @@ -2386,7 +2168,6 @@ const h = this._v3_1.z; const l = Math.sqrt( Math.pow( this._v3_1.x, 2 ) + Math.pow( this._v3_1.y, 2 ) ); - if ( l == 0 ) { //ray aligned with camera @@ -2397,6 +2178,7 @@ const m = h / l; const q = cameraGizmoDistance; + /* * calculate intersection point between unprojected ray and trackball surface *|y = m * x + q @@ -2404,25 +2186,21 @@ * * (m^2 + 1) * x^2 + (2 * m * q) * x + q^2 - r^2 = 0 */ - let a = Math.pow( m, 2 ) + 1; let b = 2 * m * q; let c = Math.pow( q, 2 ) - radius2; let delta = Math.pow( b, 2 ) - 4 * a * c; - if ( delta >= 0 ) { //intersection with sphere this._v2_1.setX( ( - b - Math.sqrt( delta ) ) / ( 2 * a ) ); - this._v2_1.setY( m * this._v2_1.x + q ); - const angle = THREE.MathUtils.RAD2DEG * this._v2_1.angle(); - if ( angle >= 45 ) { //if angle between intersection point and X' axis is >= 45°, return that point //otherwise, calculate intersection point with hyperboloid + const rayLength = Math.sqrt( Math.pow( this._v2_1.x, 2 ) + Math.pow( cameraGizmoDistance - this._v2_1.y, 2 ) ); rayDir.multiplyScalar( rayLength ); rayDir.z += cameraGizmoDistance; @@ -2430,8 +2208,9 @@ } - } //intersection with hyperboloid + } + //intersection with hyperboloid /* *|y = m * x + q *|y = (1 / x) * (r^2 / 2) @@ -2439,16 +2218,12 @@ * m * x^2 + q * x - r^2 / 2 = 0 */ - a = m; b = q; c = - radius2 * 0.5; delta = Math.pow( b, 2 ) - 4 * a * c; - this._v2_1.setX( ( - b - Math.sqrt( delta ) ) / ( 2 * a ) ); - this._v2_1.setY( m * this._v2_1.x + q ); - const rayLength = Math.sqrt( Math.pow( this._v2_1.x, 2 ) + Math.pow( cameraGizmoDistance - this._v2_1.y, 2 ) ); rayDir.multiplyScalar( rayLength ); rayDir.z += cameraGizmoDistance; @@ -2463,21 +2238,18 @@ if ( camera.type == 'OrthographicCamera' ) { this._v2_1.copy( this.getCursorPosition( cursorX, cursorY, canvas ) ); - this._v3_1.set( this._v2_1.x, this._v2_1.y, 0 ); - return this._v3_1.clone(); } else if ( camera.type == 'PerspectiveCamera' ) { - this._v2_1.copy( this.getCursorNDC( cursorX, cursorY, canvas ) ); //unproject cursor on the near plane - + this._v2_1.copy( this.getCursorNDC( cursorX, cursorY, canvas ) ); + //unproject cursor on the near plane this._v3_1.set( this._v2_1.x, this._v2_1.y, - 1 ); - this._v3_1.applyMatrix4( camera.projectionMatrixInverse ); - const rayDir = this._v3_1.clone().normalize(); //unprojected ray direction + // camera // |\ // | \ @@ -2488,11 +2260,9 @@ // _ _ | _ _ _\ _ _ near plane // l - const h = this._v3_1.z; const l = Math.sqrt( Math.pow( this._v3_1.x, 2 ) + Math.pow( this._v3_1.y, 2 ) ); let cameraGizmoDistance; - if ( initialDistance ) { cameraGizmoDistance = this._v3_1.setFromMatrixPosition( this._cameraMatrixState0 ).distanceTo( this._v3_2.setFromMatrixPosition( this._gizmoMatrixState0 ) ); @@ -2502,6 +2272,7 @@ cameraGizmoDistance = camera.position.distanceTo( this._gizmos.position ); } + /* * calculate intersection point between unprojected ray and the plane *|y = mx + q @@ -2509,8 +2280,6 @@ * * x = -q/m */ - - if ( l == 0 ) { //ray aligned with camera @@ -2535,13 +2304,10 @@ //update camera and gizmos state this._cameraMatrixState.copy( this.camera.matrix ); - this._gizmoMatrixState.copy( this._gizmos.matrix ); - if ( this.camera.isOrthographicCamera ) { this._cameraProjectionState.copy( this.camera.projectionMatrix ); - this.camera.updateProjectionMatrix(); this._zoomState = this.camera.zoom; @@ -2556,7 +2322,6 @@ this.updateTbState = ( newState, updateMatrices ) => { this._state = newState; - if ( updateMatrices ) { this.updateMatrixState(); @@ -2568,20 +2333,16 @@ this.update = () => { const EPS = 0.000001; - if ( this.target.equals( this._currentTarget ) === false ) { this._gizmos.position.copy( this.target ); //for correct radius calculation - - this._tbRadius = this.calculateTbRadius( this.camera ); this.makeGizmos( this.target, this._tbRadius ); - this._currentTarget.copy( this.target ); - } //check min/max parameters - + } + //check min/max parameters if ( this.camera.isOrthographicCamera ) { //check zoom @@ -2596,16 +2357,15 @@ //check distance const distance = this.camera.position.distanceTo( this._gizmos.position ); - if ( distance > this.maxDistance + EPS || distance < this.minDistance - EPS ) { const newDistance = THREE.MathUtils.clamp( distance, this.minDistance, this.maxDistance ); this.applyTransformMatrix( this.scale( newDistance / distance, this._gizmos.position ) ); this.updateMatrixState(); - } //check fov - + } + //check fov if ( this.camera.fov < this.minFov || this.camera.fov > this.maxFov ) { this.camera.fov = THREE.MathUtils.clamp( this.camera.fov, this.minFov, this.maxFov ); @@ -2615,7 +2375,6 @@ const oldRadius = this._tbRadius; this._tbRadius = this.calculateTbRadius( this.camera ); - if ( oldRadius < this._tbRadius - EPS || oldRadius > this._tbRadius + EPS ) { const scale = ( this._gizmos.scale.x + this._gizmos.scale.y + this._gizmos.scale.z ) / 3; @@ -2623,7 +2382,6 @@ const curve = new THREE.EllipseCurve( 0, 0, newRadius, newRadius ); const points = curve.getPoints( this._curvePts ); const curveGeometry = new THREE.BufferGeometry().setFromPoints( points ); - for ( const gizmo in this._gizmos.children ) { this._gizmos.children[ gizmo ].geometry = curveGeometry; @@ -2641,18 +2399,14 @@ this.setStateFromJSON = json => { const state = JSON.parse( json ); - if ( state.arcballState != undefined ) { this._cameraMatrixState.fromArray( state.arcballState.cameraMatrix.elements ); - this._cameraMatrixState.decompose( this.camera.position, this.camera.quaternion, this.camera.scale ); - this.camera.up.copy( state.arcballState.cameraUp ); this.camera.near = state.arcballState.cameraNear; this.camera.far = state.arcballState.cameraFar; this.camera.zoom = state.arcballState.cameraZoom; - if ( this.camera.isPerspectiveCamera ) { this.camera.fov = state.arcballState.cameraFov; @@ -2660,20 +2414,14 @@ } this._gizmoMatrixState.fromArray( state.arcballState.gizmoMatrix.elements ); - this._gizmoMatrixState.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale ); - this.camera.updateMatrix(); this.camera.updateProjectionMatrix(); - this._gizmos.updateMatrix(); - this._tbRadius = this.calculateTbRadius( this.camera ); const gizmoTmp = new THREE.Matrix4().copy( this._gizmoMatrixState0 ); this.makeGizmos( this._gizmos.position, this._tbRadius ); - this._gizmoMatrixState0.copy( gizmoTmp ); - this.camera.lookAt( this._gizmos.position ); this.updateTbState( STATE.IDLE, false ); this.dispatchEvent( _changeEvent ); @@ -2689,24 +2437,24 @@ this._currentTarget = new THREE.Vector3(); this.radiusFactor = 0.67; this.mouseActions = []; - this._mouseOp = null; //global vectors and matrices that are used in some operations to avoid creating new objects every time (e.g. every time cursor moves) + this._mouseOp = null; + //global vectors and matrices that are used in some operations to avoid creating new objects every time (e.g. every time cursor moves) this._v2_1 = new THREE.Vector2(); this._v3_1 = new THREE.Vector3(); this._v3_2 = new THREE.Vector3(); this._m4_1 = new THREE.Matrix4(); this._m4_2 = new THREE.Matrix4(); - this._quat = new THREE.Quaternion(); //transformation matrices + this._quat = new THREE.Quaternion(); + //transformation matrices this._translationMatrix = new THREE.Matrix4(); //matrix for translation operation - this._rotationMatrix = new THREE.Matrix4(); //matrix for rotation operation - this._scaleMatrix = new THREE.Matrix4(); //matrix for scaling operation this._rotationAxis = new THREE.Vector3(); //axis for rotate operation - //camera state + //camera state this._cameraMatrixState = new THREE.Matrix4(); this._cameraProjectionState = new THREE.Matrix4(); this._fovState = 1; @@ -2714,8 +2462,9 @@ this._zoomState = 1; this._nearPos = 0; this._farPos = 0; - this._gizmoMatrixState = new THREE.Matrix4(); //initial values + this._gizmoMatrixState = new THREE.Matrix4(); + //initial values this._up0 = new THREE.Vector3(); this._zoom0 = 1; this._fov0 = 0; @@ -2724,81 +2473,70 @@ this._initialFar = 0; this._farPos0 = 0; this._cameraMatrixState0 = new THREE.Matrix4(); - this._gizmoMatrixState0 = new THREE.Matrix4(); //pointers array + this._gizmoMatrixState0 = new THREE.Matrix4(); + //pointers array this._button = - 1; this._touchStart = []; this._touchCurrent = []; - this._input = INPUT.NONE; //two fingers touch interaction + this._input = INPUT.NONE; + //two fingers touch interaction this._switchSensibility = 32; //minimum movement to be performed to fire single pan start after the second finger has been released - this._startFingerDistance = 0; //distance between two fingers - this._currentFingerDistance = 0; this._startFingerRotation = 0; //amount of rotation performed with two fingers + this._currentFingerRotation = 0; - this._currentFingerRotation = 0; //double tap - + //double tap this._devPxRatio = 0; this._downValid = true; this._nclicks = 0; this._downEvents = []; this._downStart = 0; //pointerDown time - this._clickStart = 0; //first click time - this._maxDownTime = 250; this._maxInterval = 300; this._posThreshold = 24; - this._movementThreshold = 24; //cursor positions + this._movementThreshold = 24; + //cursor positions this._currentCursorPosition = new THREE.Vector3(); - this._startCursorPosition = new THREE.Vector3(); //grid + this._startCursorPosition = new THREE.Vector3(); + //grid this._grid = null; //grid to be visualized during pan operation + this._gridPosition = new THREE.Vector3(); - this._gridPosition = new THREE.Vector3(); //gizmos - + //gizmos this._gizmos = new THREE.Group(); - this._curvePts = 128; //animations + this._curvePts = 128; + //animations this._timeStart = - 1; //initial time + this._animationId = - 1; - this._animationId = - 1; //focus animation - + //focus animation this.focusAnimationTime = 500; //duration of focus animation in ms - //rotate animation + //rotate animation this._timePrev = 0; //time at which previous rotate operation has been detected - this._timeCurrent = 0; //time at which current rotate operation has been detected - this._anglePrev = 0; //angle of previous rotation - this._angleCurrent = 0; //angle of current rotation - this._cursorPosPrev = new THREE.Vector3(); //cursor position when previous rotate operation has been detected - this._cursorPosCurr = new THREE.Vector3(); //cursor position when current rotate operation has been detected - this._wPrev = 0; //angular velocity of the previous rotate operation - this._wCurr = 0; //angular velocity of the current rotate operation - //parameters + //parameters this.adjustNearFar = false; this.scaleFactor = 1.1; //zoom/distance multiplier - this.dampingFactor = 25; this.wMax = 20; //maximum angular velocity allowed - this.enableAnimations = true; //if animations should be performed - this.enableGrid = false; //if grid should be showed during pan operation - this.cursorZoom = false; //if wheel zoom should be cursor centered - this.minFov = 5; this.maxFov = 90; this.enabled = true; @@ -2809,13 +2547,14 @@ this.minDistance = 0; this.maxDistance = Infinity; this.minZoom = 0; - this.maxZoom = Infinity; //trackball parameters + this.maxZoom = Infinity; - this._tbRadius = 1; //FSA + //trackball parameters + this._tbRadius = 1; + //FSA this._state = STATE.IDLE; this.setCamera( _camera ); - if ( this.scene != null ) { this.scene.add( this._gizmos ); @@ -2831,8 +2570,9 @@ this.domElement.addEventListener( 'pointercancel', this.onPointerCancel ); window.addEventListener( 'resize', this.onWindowResize ); - } //listeners + } + //listeners /** * Apply a transformation matrix, to the camera and gizmos @@ -2843,11 +2583,10 @@ if ( transformation.camera != null ) { this._m4_1.copy( this._cameraMatrixState ).premultiply( transformation.camera ); - this._m4_1.decompose( this.camera.position, this.camera.quaternion, this.camera.scale ); + this.camera.updateMatrix(); - this.camera.updateMatrix(); //update camera up vector - + //update camera up vector if ( this._state == STATE.ROTATE || this._state == STATE.ZROTATE || this._state == STATE.ANIMATION_ROTATE ) { this.camera.up.copy( this._upState ).applyQuaternion( this.camera.quaternion ); @@ -2859,9 +2598,7 @@ if ( transformation.gizmos != null ) { this._m4_1.copy( this._gizmoMatrixState ).premultiply( transformation.gizmos ); - this._m4_1.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale ); - this._gizmos.updateMatrix(); } @@ -2869,7 +2606,6 @@ if ( this._state == STATE.SCALE || this._state == STATE.FOCUS || this._state == STATE.ANIMATION_FOCUS ) { this._tbRadius = this.calculateTbRadius( this.camera ); - if ( this.adjustNearFar ) { const cameraDistance = this.camera.position.distanceTo( this._gizmos.position ); @@ -2890,7 +2626,6 @@ } else { let update = false; - if ( this.camera.near != this._initialNear ) { this.camera.near = this._initialNear; @@ -2916,6 +2651,7 @@ } } + /** * Calculate the angular speed * @param {Number} p0 Position at t0 @@ -2924,7 +2660,6 @@ * @param {Number} t1 Ending time in milliseconds */ - /** * Set gizmos visibility * @param {Boolean} value Value of gizmos visibility @@ -2935,12 +2670,11 @@ this.dispatchEvent( _changeEvent ); } + /** * Set gizmos radius factor and redraws gizmos * @param {Float} value Value of radius factor */ - - setTbRadius( value ) { this.radiusFactor = value; @@ -2948,7 +2682,6 @@ const curve = new THREE.EllipseCurve( 0, 0, this._tbRadius, this._tbRadius ); const points = curve.getPoints( this._curvePts ); const curveGeometry = new THREE.BufferGeometry().setFromPoints( points ); - for ( const gizmo in this._gizmos.children ) { this._gizmos.children[ gizmo ].geometry = curveGeometry; @@ -2958,13 +2691,13 @@ this.dispatchEvent( _changeEvent ); } + /** * Creates the rotation gizmos matching trackball center and radius * @param {Vector3} tbCenter The trackball center * @param {number} tbRadius The trackball radius */ - /** * Set values in transformation object * @param {Matrix4} camera Transformation to be applied to the camera @@ -3009,6 +2742,7 @@ } } + /** * Rotate camera around its direction axis passing by a given point by a given angle * @param {Vector3} point The point where the rotation axis is passing trough @@ -3016,12 +2750,12 @@ * @returns The computed transormation matix */ - getRaycaster() { return _raycaster; } + /** * Unproject the cursor on the 3D object surface * @param {Vector2} cursor Cursor coordinates in NDC @@ -3029,7 +2763,6 @@ * @returns {Vector3} The point of intersection with the model, if exist, null otherwise */ - } THREE.ArcballControls = ArcballControls; diff --git a/examples/js/controls/DragControls.js b/examples/js/controls/DragControls.js index d034b641ad7ff1..7f733d4128ef3d 100644 --- a/examples/js/controls/DragControls.js +++ b/examples/js/controls/DragControls.js @@ -1,19 +1,12 @@ ( function () { const _plane = new THREE.Plane(); - const _raycaster = new THREE.Raycaster(); - const _pointer = new THREE.Vector2(); - const _offset = new THREE.Vector3(); - const _intersection = new THREE.Vector3(); - const _worldPosition = new THREE.Vector3(); - const _inverseMatrix = new THREE.Matrix4(); - class DragControls extends THREE.EventDispatcher { constructor( _objects, _camera, _domElement ) { @@ -23,18 +16,16 @@ let _selected = null, _hovered = null; - const _intersections = []; // + const _intersections = []; - const scope = this; + // + const scope = this; function activate() { _domElement.addEventListener( 'pointermove', onPointerMove ); - _domElement.addEventListener( 'pointerdown', onPointerDown ); - _domElement.addEventListener( 'pointerup', onPointerCancel ); - _domElement.addEventListener( 'pointerleave', onPointerCancel ); } @@ -42,13 +33,9 @@ function deactivate() { _domElement.removeEventListener( 'pointermove', onPointerMove ); - _domElement.removeEventListener( 'pointerdown', onPointerDown ); - _domElement.removeEventListener( 'pointerup', onPointerCancel ); - _domElement.removeEventListener( 'pointerleave', onPointerCancel ); - _domElement.style.cursor = ''; } @@ -75,9 +62,7 @@ if ( scope.enabled === false ) return; updatePointer( event ); - _raycaster.setFromCamera( _pointer, _camera ); - if ( _selected ) { if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { @@ -92,23 +77,19 @@ } ); return; - } // hover support + } + // hover support if ( event.pointerType === 'mouse' || event.pointerType === 'pen' ) { _intersections.length = 0; - _raycaster.setFromCamera( _pointer, _camera ); - _raycaster.intersectObjects( _objects, true, _intersections ); - if ( _intersections.length > 0 ) { const object = _intersections[ 0 ].object; - _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) ); - if ( _hovered !== object && _hovered !== null ) { scope.dispatchEvent( { @@ -155,21 +136,15 @@ if ( scope.enabled === false ) return; updatePointer( event ); _intersections.length = 0; - _raycaster.setFromCamera( _pointer, _camera ); - _raycaster.intersectObjects( _objects, true, _intersections ); - if ( _intersections.length > 0 ) { _selected = scope.transformGroup === true ? _objects[ 0 ] : _intersections[ 0 ].object; - _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) ); - if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { _inverseMatrix.copy( _selected.parent.matrixWorld ).invert(); - _offset.copy( _intersection ).sub( _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) ); } @@ -187,7 +162,6 @@ function onPointerCancel() { if ( scope.enabled === false ) return; - if ( _selected ) { scope.dispatchEvent( { @@ -205,13 +179,14 @@ function updatePointer( event ) { const rect = _domElement.getBoundingClientRect(); - _pointer.x = ( event.clientX - rect.left ) / rect.width * 2 - 1; _pointer.y = - ( event.clientY - rect.top ) / rect.height * 2 + 1; } - activate(); // API + activate(); + + // API this.enabled = true; this.transformGroup = false; diff --git a/examples/js/controls/FirstPersonControls.js b/examples/js/controls/FirstPersonControls.js index f21b0f021bf266..d944645a0e3fe2 100644 --- a/examples/js/controls/FirstPersonControls.js +++ b/examples/js/controls/FirstPersonControls.js @@ -1,24 +1,16 @@ ( function () { const _lookDirection = new THREE.Vector3(); - const _spherical = new THREE.Spherical(); - const _target = new THREE.Vector3(); - class FirstPersonControls { constructor( object, domElement ) { - if ( domElement === undefined ) { - - console.warn( 'THREE.FirstPersonControls: The second parameter "domElement" is now mandatory.' ); - domElement = document; - - } - this.object = object; - this.domElement = domElement; // API + this.domElement = domElement; + + // API this.enabled = true; this.movementSpeed = 1.0; @@ -33,20 +25,26 @@ this.constrainVertical = false; this.verticalMin = 0; this.verticalMax = Math.PI; - this.mouseDragOn = false; // internals + this.mouseDragOn = false; + + // internals this.autoSpeedFactor = 0.0; - this.mouseX = 0; - this.mouseY = 0; + this.pointerX = 0; + this.pointerY = 0; this.moveForward = false; this.moveBackward = false; this.moveLeft = false; this.moveRight = false; this.viewHalfX = 0; - this.viewHalfY = 0; // private variables + this.viewHalfY = 0; + + // private variables let lat = 0; - let lon = 0; // + let lon = 0; + + // this.handleResize = function () { @@ -64,7 +62,7 @@ }; - this.onMouseDown = function ( event ) { + this.onPointerDown = function ( event ) { if ( this.domElement !== document ) { @@ -79,7 +77,6 @@ case 0: this.moveForward = true; break; - case 2: this.moveBackward = true; break; @@ -92,7 +89,7 @@ }; - this.onMouseUp = function ( event ) { + this.onPointerUp = function ( event ) { if ( this.activeLook ) { @@ -101,7 +98,6 @@ case 0: this.moveForward = false; break; - case 2: this.moveBackward = false; break; @@ -114,17 +110,17 @@ }; - this.onMouseMove = function ( event ) { + this.onPointerMove = function ( event ) { if ( this.domElement === document ) { - this.mouseX = event.pageX - this.viewHalfX; - this.mouseY = event.pageY - this.viewHalfY; + this.pointerX = event.pageX - this.viewHalfX; + this.pointerY = event.pageY - this.viewHalfY; } else { - this.mouseX = event.pageX - this.domElement.offsetLeft - this.viewHalfX; - this.mouseY = event.pageY - this.domElement.offsetTop - this.viewHalfY; + this.pointerX = event.pageX - this.domElement.offsetLeft - this.viewHalfX; + this.pointerY = event.pageY - this.domElement.offsetTop - this.viewHalfY; } @@ -138,26 +134,21 @@ case 'KeyW': this.moveForward = true; break; - case 'ArrowLeft': case 'KeyA': this.moveLeft = true; break; - case 'ArrowDown': case 'KeyS': this.moveBackward = true; break; - case 'ArrowRight': case 'KeyD': this.moveRight = true; break; - case 'KeyR': this.moveUp = true; break; - case 'KeyF': this.moveDown = true; break; @@ -174,26 +165,21 @@ case 'KeyW': this.moveForward = false; break; - case 'ArrowLeft': case 'KeyA': this.moveLeft = false; break; - case 'ArrowDown': case 'KeyS': this.moveBackward = false; break; - case 'ArrowRight': case 'KeyD': this.moveRight = false; break; - case 'KeyR': this.moveUp = false; break; - case 'KeyF': this.moveDown = false; break; @@ -226,7 +212,6 @@ return function update( delta ) { if ( this.enabled === false ) return; - if ( this.heightSpeed ) { const y = THREE.MathUtils.clamp( this.object.position.y, this.heightMin, this.heightMax ); @@ -247,7 +232,6 @@ if ( this.moveUp ) this.object.translateY( actualMoveSpeed ); if ( this.moveDown ) this.object.translateY( - actualMoveSpeed ); let actualLookSpeed = delta * this.lookSpeed; - if ( ! this.activeLook ) { actualLookSpeed = 0; @@ -255,19 +239,17 @@ } let verticalLookRatio = 1; - if ( this.constrainVertical ) { verticalLookRatio = Math.PI / ( this.verticalMax - this.verticalMin ); } - lon -= this.mouseX * actualLookSpeed; - if ( this.lookVertical ) lat -= this.mouseY * actualLookSpeed * verticalLookRatio; + lon -= this.pointerX * actualLookSpeed; + if ( this.lookVertical ) lat -= this.pointerY * actualLookSpeed * verticalLookRatio; lat = Math.max( - 85, Math.min( 85, lat ) ); let phi = THREE.MathUtils.degToRad( 90 - lat ); const theta = THREE.MathUtils.degToRad( lon ); - if ( this.constrainVertical ) { phi = THREE.MathUtils.mapLinear( phi, 0, Math.PI, this.verticalMin, this.verticalMax ); @@ -281,43 +263,33 @@ }; }(); - this.dispose = function () { this.domElement.removeEventListener( 'contextmenu', contextmenu ); - this.domElement.removeEventListener( 'mousedown', _onMouseDown ); - this.domElement.removeEventListener( 'mousemove', _onMouseMove ); - this.domElement.removeEventListener( 'mouseup', _onMouseUp ); + this.domElement.removeEventListener( 'pointerdown', _onPointerDown ); + this.domElement.removeEventListener( 'pointermove', _onPointerMove ); + this.domElement.removeEventListener( 'pointerup', _onPointerUp ); window.removeEventListener( 'keydown', _onKeyDown ); window.removeEventListener( 'keyup', _onKeyUp ); }; - const _onMouseMove = this.onMouseMove.bind( this ); - - const _onMouseDown = this.onMouseDown.bind( this ); - - const _onMouseUp = this.onMouseUp.bind( this ); - + const _onPointerMove = this.onPointerMove.bind( this ); + const _onPointerDown = this.onPointerDown.bind( this ); + const _onPointerUp = this.onPointerUp.bind( this ); const _onKeyDown = this.onKeyDown.bind( this ); - const _onKeyUp = this.onKeyUp.bind( this ); - this.domElement.addEventListener( 'contextmenu', contextmenu ); - this.domElement.addEventListener( 'mousemove', _onMouseMove ); - this.domElement.addEventListener( 'mousedown', _onMouseDown ); - this.domElement.addEventListener( 'mouseup', _onMouseUp ); + this.domElement.addEventListener( 'pointerdown', _onPointerDown ); + this.domElement.addEventListener( 'pointermove', _onPointerMove ); + this.domElement.addEventListener( 'pointerup', _onPointerUp ); window.addEventListener( 'keydown', _onKeyDown ); window.addEventListener( 'keyup', _onKeyUp ); - function setOrientation( controls ) { const quaternion = controls.object.quaternion; - _lookDirection.set( 0, 0, - 1 ).applyQuaternion( quaternion ); - _spherical.setFromVector3( _lookDirection ); - lat = 90 - THREE.MathUtils.radToDeg( _spherical.phi ); lon = THREE.MathUtils.radToDeg( _spherical.theta ); @@ -329,7 +301,6 @@ } } - function contextmenu( event ) { event.preventDefault(); diff --git a/examples/js/controls/FlyControls.js b/examples/js/controls/FlyControls.js index 223915d7be29be..d19f55f6ee7164 100644 --- a/examples/js/controls/FlyControls.js +++ b/examples/js/controls/FlyControls.js @@ -3,27 +3,23 @@ const _changeEvent = { type: 'change' }; - class FlyControls extends THREE.EventDispatcher { constructor( object, domElement ) { super(); - - if ( domElement === undefined ) { - - console.warn( 'THREE.FlyControls: The second parameter "domElement" is now mandatory.' ); - domElement = document; - - } - this.object = object; - this.domElement = domElement; // API + this.domElement = domElement; + + // API this.movementSpeed = 1.0; this.rollSpeed = 0.005; this.dragToLook = false; - this.autoForward = false; // disable default target object behavior + this.autoForward = false; + + // disable default target object behavior + // internals const scope = this; @@ -31,7 +27,7 @@ const lastQuaternion = new THREE.Quaternion(); const lastPosition = new THREE.Vector3(); this.tmpQuaternion = new THREE.Quaternion(); - this.mouseStatus = 0; + this.status = 0; this.moveState = { up: 0, down: 0, @@ -48,7 +44,6 @@ }; this.moveVector = new THREE.Vector3( 0, 0, 0 ); this.rotationVector = new THREE.Vector3( 0, 0, 0 ); - this.keydown = function ( event ) { if ( event.altKey ) { @@ -63,51 +58,39 @@ case 'ShiftRight': this.movementSpeedMultiplier = .1; break; - case 'KeyW': this.moveState.forward = 1; break; - case 'KeyS': this.moveState.back = 1; break; - case 'KeyA': this.moveState.left = 1; break; - case 'KeyD': this.moveState.right = 1; break; - case 'KeyR': this.moveState.up = 1; break; - case 'KeyF': this.moveState.down = 1; break; - case 'ArrowUp': this.moveState.pitchUp = 1; break; - case 'ArrowDown': this.moveState.pitchDown = 1; break; - case 'ArrowLeft': this.moveState.yawLeft = 1; break; - case 'ArrowRight': this.moveState.yawRight = 1; break; - case 'KeyQ': this.moveState.rollLeft = 1; break; - case 'KeyE': this.moveState.rollRight = 1; break; @@ -127,51 +110,39 @@ case 'ShiftRight': this.movementSpeedMultiplier = 1; break; - case 'KeyW': this.moveState.forward = 0; break; - case 'KeyS': this.moveState.back = 0; break; - case 'KeyA': this.moveState.left = 0; break; - case 'KeyD': this.moveState.right = 0; break; - case 'KeyR': this.moveState.up = 0; break; - case 'KeyF': this.moveState.down = 0; break; - case 'ArrowUp': this.moveState.pitchUp = 0; break; - case 'ArrowDown': this.moveState.pitchDown = 0; break; - case 'ArrowLeft': this.moveState.yawLeft = 0; break; - case 'ArrowRight': this.moveState.yawRight = 0; break; - case 'KeyQ': this.moveState.rollLeft = 0; break; - case 'KeyE': this.moveState.rollRight = 0; break; @@ -183,11 +154,11 @@ }; - this.mousedown = function ( event ) { + this.pointerdown = function ( event ) { if ( this.dragToLook ) { - this.mouseStatus ++; + this.status ++; } else { @@ -196,7 +167,6 @@ case 0: this.moveState.forward = 1; break; - case 2: this.moveState.back = 1; break; @@ -209,9 +179,9 @@ }; - this.mousemove = function ( event ) { + this.pointermove = function ( event ) { - if ( ! this.dragToLook || this.mouseStatus > 0 ) { + if ( ! this.dragToLook || this.status > 0 ) { const container = this.getContainerDimensions(); const halfWidth = container.size[ 0 ] / 2; @@ -224,11 +194,11 @@ }; - this.mouseup = function ( event ) { + this.pointerup = function ( event ) { if ( this.dragToLook ) { - this.mouseStatus --; + this.status --; this.moveState.yawLeft = this.moveState.pitchDown = 0; } else { @@ -238,7 +208,6 @@ case 0: this.moveState.forward = 0; break; - case 2: this.moveState.back = 0; break; @@ -262,7 +231,6 @@ scope.object.translateZ( scope.moveVector.z * moveMult ); scope.tmpQuaternion.set( scope.rotationVector.x * rotMult, scope.rotationVector.y * rotMult, scope.rotationVector.z * rotMult, 1 ).normalize(); scope.object.quaternion.multiply( scope.tmpQuaternion ); - if ( lastPosition.distanceToSquared( scope.object.position ) > EPS || 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) { scope.dispatchEvent( _changeEvent ); @@ -278,7 +246,9 @@ const forward = this.moveState.forward || this.autoForward && ! this.moveState.back ? 1 : 0; this.moveVector.x = - this.moveState.left + this.moveState.right; this.moveVector.y = - this.moveState.down + this.moveState.up; - this.moveVector.z = - forward + this.moveState.back; //console.log( 'move:', [ this.moveVector.x, this.moveVector.y, this.moveVector.z ] ); + this.moveVector.z = - forward + this.moveState.back; + + //console.log( 'move:', [ this.moveVector.x, this.moveVector.y, this.moveVector.z ] ); }; @@ -286,7 +256,9 @@ this.rotationVector.x = - this.moveState.pitchDown + this.moveState.pitchUp; this.rotationVector.y = - this.moveState.yawRight + this.moveState.yawLeft; - this.rotationVector.z = - this.moveState.rollRight + this.moveState.rollLeft; //console.log( 'rotate:', [ this.rotationVector.x, this.rotationVector.y, this.rotationVector.z ] ); + this.rotationVector.z = - this.moveState.rollRight + this.moveState.rollLeft; + + //console.log( 'rotate:', [ this.rotationVector.x, this.rotationVector.y, this.rotationVector.z ] ); }; @@ -313,28 +285,23 @@ this.dispose = function () { this.domElement.removeEventListener( 'contextmenu', contextmenu ); - this.domElement.removeEventListener( 'mousedown', _mousedown ); - this.domElement.removeEventListener( 'mousemove', _mousemove ); - this.domElement.removeEventListener( 'mouseup', _mouseup ); + this.domElement.removeEventListener( 'pointerdown', _pointerdown ); + this.domElement.removeEventListener( 'pointermove', _pointermove ); + this.domElement.removeEventListener( 'pointerup', _pointerup ); window.removeEventListener( 'keydown', _keydown ); window.removeEventListener( 'keyup', _keyup ); }; - const _mousemove = this.mousemove.bind( this ); - - const _mousedown = this.mousedown.bind( this ); - - const _mouseup = this.mouseup.bind( this ); - + const _pointermove = this.pointermove.bind( this ); + const _pointerdown = this.pointerdown.bind( this ); + const _pointerup = this.pointerup.bind( this ); const _keydown = this.keydown.bind( this ); - const _keyup = this.keyup.bind( this ); - this.domElement.addEventListener( 'contextmenu', contextmenu ); - this.domElement.addEventListener( 'mousemove', _mousemove ); - this.domElement.addEventListener( 'mousedown', _mousedown ); - this.domElement.addEventListener( 'mouseup', _mouseup ); + this.domElement.addEventListener( 'pointerdown', _pointerdown ); + this.domElement.addEventListener( 'pointermove', _pointermove ); + this.domElement.addEventListener( 'pointerup', _pointerup ); window.addEventListener( 'keydown', _keydown ); window.addEventListener( 'keyup', _keyup ); this.updateMovementVector(); @@ -343,7 +310,6 @@ } } - function contextmenu( event ) { event.preventDefault(); diff --git a/examples/js/controls/OrbitControls.js b/examples/js/controls/OrbitControls.js index 931d5abe0031d2..e414ce2db74ac5 100644 --- a/examples/js/controls/OrbitControls.js +++ b/examples/js/controls/OrbitControls.js @@ -1,5 +1,6 @@ ( function () { + // This set of controls performs orbiting, dollying (zooming), and panning. // Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default). // // Orbit - left mouse / touch: one-finger move @@ -15,87 +16,94 @@ const _endEvent = { type: 'end' }; - class OrbitControls extends THREE.EventDispatcher { constructor( object, domElement ) { super(); - if ( domElement === undefined ) console.warn( 'THREE.OrbitControls: The second parameter "domElement" is now mandatory.' ); - if ( domElement === document ) console.error( 'THREE.OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.' ); this.object = object; this.domElement = domElement; this.domElement.style.touchAction = 'none'; // disable touch scroll - // Set to false to disable this control - this.enabled = true; // "target" sets the location of focus, where the object orbits around + // Set to false to disable this control + this.enabled = true; - this.target = new THREE.Vector3(); // How far you can dolly in and out ( PerspectiveCamera only ) + // "target" sets the location of focus, where the object orbits around + this.target = new THREE.Vector3(); + // How far you can dolly in and out ( PerspectiveCamera only ) this.minDistance = 0; - this.maxDistance = Infinity; // How far you can zoom in and out ( OrthographicCamera only ) + this.maxDistance = Infinity; + // How far you can zoom in and out ( OrthographicCamera only ) this.minZoom = 0; - this.maxZoom = Infinity; // How far you can orbit vertically, upper and lower limits. - // Range is 0 to Math.PI radians. + this.maxZoom = Infinity; + // How far you can orbit vertically, upper and lower limits. + // Range is 0 to Math.PI radians. this.minPolarAngle = 0; // radians - this.maxPolarAngle = Math.PI; // radians + // How far you can orbit horizontally, upper and lower limits. // If set, the interval [ min, max ] must be a sub-interval of [ - 2 PI, 2 PI ], with ( max - min < 2 PI ) - this.minAzimuthAngle = - Infinity; // radians - this.maxAzimuthAngle = Infinity; // radians + // Set to true to enable damping (inertia) // If damping is enabled, you must call controls.update() in your animation loop - this.enableDamping = false; - this.dampingFactor = 0.05; // This option actually enables dollying in and out; left as "zoom" for backwards compatibility. - // Set to false to disable zooming + this.dampingFactor = 0.05; + // This option actually enables dollying in and out; left as "zoom" for backwards compatibility. + // Set to false to disable zooming this.enableZoom = true; - this.zoomSpeed = 1.0; // Set to false to disable rotating + this.zoomSpeed = 1.0; + // Set to false to disable rotating this.enableRotate = true; - this.rotateSpeed = 1.0; // Set to false to disable panning + this.rotateSpeed = 1.0; + // Set to false to disable panning this.enablePan = true; this.panSpeed = 1.0; this.screenSpacePanning = true; // if false, pan orthogonal to world-space direction camera.up - this.keyPanSpeed = 7.0; // pixels moved per arrow key push + // Set to true to automatically rotate around the target // If auto-rotate is enabled, you must call controls.update() in your animation loop - this.autoRotate = false; this.autoRotateSpeed = 2.0; // 30 seconds per orbit when fps is 60 - // The four arrow keys + // The four arrow keys this.keys = { LEFT: 'ArrowLeft', UP: 'ArrowUp', RIGHT: 'ArrowRight', BOTTOM: 'ArrowDown' - }; // Mouse buttons + }; + // Mouse buttons this.mouseButtons = { LEFT: THREE.MOUSE.ROTATE, MIDDLE: THREE.MOUSE.DOLLY, RIGHT: THREE.MOUSE.PAN - }; // Touch fingers + }; + // Touch fingers this.touches = { ONE: THREE.TOUCH.ROTATE, TWO: THREE.TOUCH.DOLLY_PAN - }; // for reset + }; + // for reset this.target0 = this.target.clone(); this.position0 = this.object.position.clone(); - this.zoom0 = this.object.zoom; // the target DOM element for key events + this.zoom0 = this.object.zoom; - this._domElementKeyEvents = null; // + // the target DOM element for key events + this._domElementKeyEvents = null; + + // // public methods // @@ -142,13 +150,14 @@ scope.update(); state = STATE.NONE; - }; // this method is exposed, but perhaps it would be better if we can make it private... - + }; + // this method is exposed, but perhaps it would be better if we can make it private... this.update = function () { - const offset = new THREE.Vector3(); // so camera.up is the orbit axis + const offset = new THREE.Vector3(); + // so camera.up is the orbit axis const quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) ); const quatInverse = quat.clone().invert(); const lastPosition = new THREE.Vector3(); @@ -157,12 +166,13 @@ return function update() { const position = scope.object.position; - offset.copy( position ).sub( scope.target ); // rotate offset to "y-axis-is-up" space + offset.copy( position ).sub( scope.target ); - offset.applyQuaternion( quat ); // angle from z-axis around y-axis + // rotate offset to "y-axis-is-up" space + offset.applyQuaternion( quat ); + // angle from z-axis around y-axis spherical.setFromVector3( offset ); - if ( scope.autoRotate && state === STATE.NONE ) { rotateLeft( getAutoRotationAngle() ); @@ -179,17 +189,16 @@ spherical.theta += sphericalDelta.theta; spherical.phi += sphericalDelta.phi; - } // restrict theta to be between desired limits + } + // restrict theta to be between desired limits let min = scope.minAzimuthAngle; let max = scope.maxAzimuthAngle; - if ( isFinite( min ) && isFinite( max ) ) { if ( min < - Math.PI ) min += twoPI; else if ( min > Math.PI ) min -= twoPI; if ( max < - Math.PI ) max += twoPI; else if ( max > Math.PI ) max -= twoPI; - if ( min <= max ) { spherical.theta = Math.max( min, Math.min( max, spherical.theta ) ); @@ -200,14 +209,17 @@ } - } // restrict phi to be between desired limits - + } + // restrict phi to be between desired limits spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) ); spherical.makeSafe(); - spherical.radius *= scale; // restrict radius to be between desired limits + spherical.radius *= scale; + + // restrict radius to be between desired limits + spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) ); - spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) ); // move target to panned location + // move target to panned location if ( scope.enableDamping === true ) { @@ -219,12 +231,12 @@ } - offset.setFromSpherical( spherical ); // rotate offset back to "camera-up-vector-is-up" space + offset.setFromSpherical( spherical ); + // rotate offset back to "camera-up-vector-is-up" space offset.applyQuaternion( quatInverse ); position.copy( scope.target ).add( offset ); scope.object.lookAt( scope.target ); - if ( scope.enableDamping === true ) { sphericalDelta.theta *= 1 - scope.dampingFactor; @@ -238,7 +250,9 @@ } - scale = 1; // update condition is: + scale = 1; + + // update condition is: // min(camera displacement, camera rotation in radians)^2 > EPS // using small-angle approximation cos(x/2) = 1 - x^2 / 8 @@ -257,7 +271,6 @@ }; }(); - this.dispose = function () { scope.domElement.removeEventListener( 'contextmenu', onContextMenu ); @@ -266,18 +279,20 @@ scope.domElement.removeEventListener( 'wheel', onMouseWheel ); scope.domElement.removeEventListener( 'pointermove', onPointerMove ); scope.domElement.removeEventListener( 'pointerup', onPointerUp ); - if ( scope._domElementKeyEvents !== null ) { scope._domElementKeyEvents.removeEventListener( 'keydown', onKeyDown ); - } //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here? + } + + //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here? + + }; - }; // + // // internals // - const scope = this; const STATE = { NONE: - 1, @@ -290,8 +305,9 @@ TOUCH_DOLLY_ROTATE: 6 }; let state = STATE.NONE; - const EPS = 0.000001; // current position in spherical coordinates + const EPS = 0.000001; + // current position in spherical coordinates const spherical = new THREE.Spherical(); const sphericalDelta = new THREE.Spherical(); let scale = 1; @@ -308,7 +324,6 @@ const dollyDelta = new THREE.Vector2(); const pointers = []; const pointerPositions = {}; - function getAutoRotationAngle() { return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed; @@ -339,14 +354,12 @@ return function panLeft( distance, objectMatrix ) { v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix - v.multiplyScalar( - distance ); panOffset.add( v ); }; }(); - const panUp = function () { const v = new THREE.Vector3(); @@ -368,25 +381,26 @@ }; - }(); // deltaX and deltaY are in pixels; right and down are positive - + }(); + // deltaX and deltaY are in pixels; right and down are positive const pan = function () { const offset = new THREE.Vector3(); return function pan( deltaX, deltaY ) { const element = scope.domElement; - if ( scope.object.isPerspectiveCamera ) { // perspective const position = scope.object.position; offset.copy( position ).sub( scope.target ); - let targetDistance = offset.length(); // half of the fov is center to top of screen + let targetDistance = offset.length(); - targetDistance *= Math.tan( scope.object.fov / 2 * Math.PI / 180.0 ); // we use only clientHeight here so aspect ratio does not distort speed + // half of the fov is center to top of screen + targetDistance *= Math.tan( scope.object.fov / 2 * Math.PI / 180.0 ); + // we use only clientHeight here so aspect ratio does not distort speed panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix ); panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix ); @@ -407,7 +421,6 @@ }; }(); - function dollyOut( dollyScale ) { if ( scope.object.isPerspectiveCamera ) { @@ -448,11 +461,12 @@ } - } // + } + + // // event callbacks - update the object state // - function handleMouseDownRotate( event ) { rotateStart.set( event.clientX, event.clientY ); @@ -488,7 +502,6 @@ dollyEnd.set( event.clientX, event.clientY ); dollyDelta.subVectors( dollyEnd, dollyStart ); - if ( dollyDelta.y > 0 ) { dollyOut( getZoomScale() ); @@ -533,26 +546,58 @@ function handleKeyDown( event ) { let needsUpdate = false; - switch ( event.code ) { case scope.keys.UP: - pan( 0, scope.keyPanSpeed ); + if ( event.ctrlKey || event.metaKey || event.shiftKey ) { + + rotateUp( 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight ); + + } else { + + pan( 0, scope.keyPanSpeed ); + + } + needsUpdate = true; break; - case scope.keys.BOTTOM: - pan( 0, - scope.keyPanSpeed ); + if ( event.ctrlKey || event.metaKey || event.shiftKey ) { + + rotateUp( - 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight ); + + } else { + + pan( 0, - scope.keyPanSpeed ); + + } + needsUpdate = true; break; - case scope.keys.LEFT: - pan( scope.keyPanSpeed, 0 ); + if ( event.ctrlKey || event.metaKey || event.shiftKey ) { + + rotateLeft( 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight ); + + } else { + + pan( scope.keyPanSpeed, 0 ); + + } + needsUpdate = true; break; - case scope.keys.RIGHT: - pan( - scope.keyPanSpeed, 0 ); + if ( event.ctrlKey || event.metaKey || event.shiftKey ) { + + rotateLeft( - 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight ); + + } else { + + pan( - scope.keyPanSpeed, 0 ); + + } + needsUpdate = true; break; @@ -693,26 +738,26 @@ if ( scope.enableZoom ) handleTouchMoveDolly( event ); if ( scope.enableRotate ) handleTouchMoveRotate( event ); - } // + } + + // // event handlers - FSM: listen for events and reset state // - function onPointerDown( event ) { if ( scope.enabled === false ) return; - if ( pointers.length === 0 ) { scope.domElement.setPointerCapture( event.pointerId ); scope.domElement.addEventListener( 'pointermove', onPointerMove ); scope.domElement.addEventListener( 'pointerup', onPointerUp ); - } // + } + // addPointer( event ); - if ( event.pointerType === 'touch' ) { onTouchStart( event ); @@ -728,7 +773,6 @@ function onPointerMove( event ) { if ( scope.enabled === false ) return; - if ( event.pointerType === 'touch' ) { onTouchMove( event ); @@ -744,7 +788,6 @@ function onPointerUp( event ) { removePointer( event ); - if ( pointers.length === 0 ) { scope.domElement.releasePointerCapture( event.pointerId ); @@ -767,21 +810,17 @@ function onMouseDown( event ) { let mouseAction; - switch ( event.button ) { case 0: mouseAction = scope.mouseButtons.LEFT; break; - case 1: mouseAction = scope.mouseButtons.MIDDLE; break; - case 2: mouseAction = scope.mouseButtons.RIGHT; break; - default: mouseAction = - 1; @@ -794,7 +833,6 @@ handleMouseDownDolly( event ); state = STATE.DOLLY; break; - case THREE.MOUSE.ROTATE: if ( event.ctrlKey || event.metaKey || event.shiftKey ) { @@ -811,7 +849,6 @@ } break; - case THREE.MOUSE.PAN: if ( event.ctrlKey || event.metaKey || event.shiftKey ) { @@ -828,7 +865,6 @@ } break; - default: state = STATE.NONE; @@ -850,12 +886,10 @@ if ( scope.enableRotate === false ) return; handleMouseMoveRotate( event ); break; - case STATE.DOLLY: if ( scope.enableZoom === false ) return; handleMouseMoveDolly( event ); break; - case STATE.PAN: if ( scope.enablePan === false ) return; handleMouseMovePan( event ); @@ -885,7 +919,6 @@ function onTouchStart( event ) { trackPointer( event ); - switch ( pointers.length ) { case 1: @@ -896,20 +929,17 @@ handleTouchStartRotate(); state = STATE.TOUCH_ROTATE; break; - case THREE.TOUCH.PAN: if ( scope.enablePan === false ) return; handleTouchStartPan(); state = STATE.TOUCH_PAN; break; - default: state = STATE.NONE; } break; - case 2: switch ( scope.touches.TWO ) { @@ -918,20 +948,17 @@ handleTouchStartDollyPan(); state = STATE.TOUCH_DOLLY_PAN; break; - case THREE.TOUCH.DOLLY_ROTATE: if ( scope.enableZoom === false && scope.enableRotate === false ) return; handleTouchStartDollyRotate(); state = STATE.TOUCH_DOLLY_ROTATE; break; - default: state = STATE.NONE; } break; - default: state = STATE.NONE; @@ -948,7 +975,6 @@ function onTouchMove( event ) { trackPointer( event ); - switch ( state ) { case STATE.TOUCH_ROTATE: @@ -956,25 +982,21 @@ handleTouchMoveRotate( event ); scope.update(); break; - case STATE.TOUCH_PAN: if ( scope.enablePan === false ) return; handleTouchMovePan( event ); scope.update(); break; - case STATE.TOUCH_DOLLY_PAN: if ( scope.enableZoom === false && scope.enablePan === false ) return; handleTouchMoveDollyPan( event ); scope.update(); break; - case STATE.TOUCH_DOLLY_ROTATE: if ( scope.enableZoom === false && scope.enableRotate === false ) return; handleTouchMoveDollyRotate( event ); scope.update(); break; - default: state = STATE.NONE; @@ -998,7 +1020,6 @@ function removePointer( event ) { delete pointerPositions[ event.pointerId ]; - for ( let i = 0; i < pointers.length; i ++ ) { if ( pointers[ i ].pointerId == event.pointerId ) { @@ -1015,7 +1036,6 @@ function trackPointer( event ) { let position = pointerPositions[ event.pointerId ]; - if ( position === undefined ) { position = new THREE.Vector2(); @@ -1032,21 +1052,26 @@ const pointer = event.pointerId === pointers[ 0 ].pointerId ? pointers[ 1 ] : pointers[ 0 ]; return pointerPositions[ pointer.pointerId ]; - } // + } + // scope.domElement.addEventListener( 'contextmenu', onContextMenu ); scope.domElement.addEventListener( 'pointerdown', onPointerDown ); scope.domElement.addEventListener( 'pointercancel', onPointerCancel ); scope.domElement.addEventListener( 'wheel', onMouseWheel, { passive: false - } ); // force an update at start + } ); + + // force an update at start this.update(); } - } // This set of controls performs orbiting, dollying (zooming), and panning. + } + + // This set of controls performs orbiting, dollying (zooming), and panning. // Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default). // This is very similar to OrbitControls, another set of touch behavior // @@ -1054,7 +1079,6 @@ // Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish // Pan - left mouse, or arrow keys / touch: one-finger move - class MapControls extends OrbitControls { constructor( object, domElement ) { diff --git a/examples/js/controls/PointerLockControls.js b/examples/js/controls/PointerLockControls.js index a329286f5862ea..df349bf5062851 100644 --- a/examples/js/controls/PointerLockControls.js +++ b/examples/js/controls/PointerLockControls.js @@ -1,9 +1,7 @@ ( function () { const _euler = new THREE.Euler( 0, 0, 0, 'YXZ' ); - const _vector = new THREE.Vector3(); - const _changeEvent = { type: 'change' }; @@ -13,41 +11,28 @@ const _unlockEvent = { type: 'unlock' }; - const _PI_2 = Math.PI / 2; - class PointerLockControls extends THREE.EventDispatcher { constructor( camera, domElement ) { super(); - - if ( domElement === undefined ) { - - console.warn( 'THREE.PointerLockControls: The second parameter "domElement" is now mandatory.' ); - domElement = document.body; - - } - this.domElement = domElement; - this.isLocked = false; // Set to constrain the pitch of the camera - // Range is 0 to Math.PI radians + this.isLocked = false; + // Set to constrain the pitch of the camera + // Range is 0 to Math.PI radians this.minPolarAngle = 0; // radians - this.maxPolarAngle = Math.PI; // radians this.pointerSpeed = 1.0; const scope = this; - function onMouseMove( event ) { if ( scope.isLocked === false ) return; const movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; const movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; - _euler.setFromQuaternion( camera.quaternion ); - _euler.y -= movementX * 0.002 * scope.pointerSpeed; _euler.x -= movementY * 0.002 * scope.pointerSpeed; _euler.x = Math.max( _PI_2 - scope.maxPolarAngle, Math.min( _PI_2 - scope.minPolarAngle, _euler.x ) ); @@ -103,6 +88,7 @@ this.getObject = function () { // retaining this method for backward compatibility + return camera; }; @@ -117,15 +103,13 @@ }; }(); - this.moveForward = function ( distance ) { // move forward parallel to the xz-plane // assumes camera.up is y-up - _vector.setFromMatrixColumn( camera.matrix, 0 ); + _vector.setFromMatrixColumn( camera.matrix, 0 ); _vector.crossVectors( camera.up, _vector ); - camera.position.addScaledVector( _vector, distance ); }; @@ -133,7 +117,6 @@ this.moveRight = function ( distance ) { _vector.setFromMatrixColumn( camera.matrix, 0 ); - camera.position.addScaledVector( _vector, distance ); }; diff --git a/examples/js/controls/TrackballControls.js b/examples/js/controls/TrackballControls.js index 54a1acaa0b1479..55ece36431ee0f 100644 --- a/examples/js/controls/TrackballControls.js +++ b/examples/js/controls/TrackballControls.js @@ -9,14 +9,11 @@ const _endEvent = { type: 'end' }; - class TrackballControls extends THREE.EventDispatcher { constructor( object, domElement ) { super(); - if ( domElement === undefined ) console.warn( 'THREE.TrackballControls: The second parameter "domElement" is now mandatory.' ); - if ( domElement === document ) console.error( 'THREE.TrackballControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.' ); const scope = this; const STATE = { NONE: - 1, @@ -29,6 +26,7 @@ this.object = object; this.domElement = domElement; this.domElement.style.touchAction = 'none'; // disable touch scroll + // API this.enabled = true; @@ -48,18 +46,15 @@ this.dynamicDampingFactor = 0.2; this.minDistance = 0; this.maxDistance = Infinity; - this.keys = [ 'KeyA', - /*A*/ - 'KeyS', - /*S*/ - 'KeyD' - /*D*/ - ]; + this.keys = [ 'KeyA' /*A*/, 'KeyS' /*S*/, 'KeyD' /*D*/]; + this.mouseButtons = { LEFT: THREE.MOUSE.ROTATE, MIDDLE: THREE.MOUSE.DOLLY, RIGHT: THREE.MOUSE.PAN - }; // internals + }; + + // internals this.target = new THREE.Vector3(); const EPS = 0.000001; @@ -70,7 +65,6 @@ _touchZoomDistanceStart = 0, _touchZoomDistanceEnd = 0, _lastAngle = 0; - const _eye = new THREE.Vector3(), _movePrev = new THREE.Vector2(), _moveCurr = new THREE.Vector2(), @@ -80,18 +74,21 @@ _panStart = new THREE.Vector2(), _panEnd = new THREE.Vector2(), _pointers = [], - _pointerPositions = {}; // for reset + _pointerPositions = {}; + // for reset this.target0 = this.target.clone(); this.position0 = this.object.position.clone(); this.up0 = this.object.up.clone(); - this.zoom0 = this.object.zoom; // methods + this.zoom0 = this.object.zoom; - this.handleResize = function () { + // methods - const box = scope.domElement.getBoundingClientRect(); // adjustments come from similar code in the jquery offset() function + this.handleResize = function () { + const box = scope.domElement.getBoundingClientRect(); + // adjustments come from similar code in the jquery offset() function const d = scope.domElement.ownerDocument.documentElement; scope.screen.left = box.left + window.pageXOffset - d.clientLeft; scope.screen.top = box.top + window.pageYOffset - d.clientTop; @@ -111,7 +108,6 @@ }; }(); - const getMouseOnCircle = function () { const vector = new THREE.Vector2(); @@ -119,12 +115,12 @@ vector.set( ( pageX - scope.screen.width * 0.5 - scope.screen.left ) / ( scope.screen.width * 0.5 ), ( scope.screen.height + 2 * ( scope.screen.top - pageY ) ) / scope.screen.width // screen.width intentional ); + return vector; }; }(); - this.rotateCamera = function () { const axis = new THREE.Vector3(), @@ -137,11 +133,9 @@ moveDirection.set( _moveCurr.x - _movePrev.x, _moveCurr.y - _movePrev.y, 0 ); let angle = moveDirection.length(); - if ( angle ) { _eye.copy( scope.object.position ).sub( scope.target ); - eyeDirection.copy( _eye ).normalize(); objectUpDirection.copy( scope.object.up ).normalize(); objectSidewaysDirection.crossVectors( objectUpDirection, eyeDirection ).normalize(); @@ -151,25 +145,17 @@ axis.crossVectors( moveDirection, _eye ).normalize(); angle *= scope.rotateSpeed; quaternion.setFromAxisAngle( axis, angle ); - _eye.applyQuaternion( quaternion ); - scope.object.up.applyQuaternion( quaternion ); - _lastAxis.copy( axis ); - _lastAngle = angle; } else if ( ! scope.staticMoving && _lastAngle ) { _lastAngle *= Math.sqrt( 1.0 - scope.dynamicDampingFactor ); - _eye.copy( scope.object.position ).sub( scope.target ); - quaternion.setFromAxisAngle( _lastAxis, _lastAngle ); - _eye.applyQuaternion( quaternion ); - scope.object.up.applyQuaternion( quaternion ); } @@ -179,16 +165,13 @@ }; }(); - this.zoomCamera = function () { let factor; - if ( _state === STATE.TOUCH_ZOOM_PAN ) { factor = _touchZoomDistanceStart / _touchZoomDistanceEnd; _touchZoomDistanceStart = _touchZoomDistanceEnd; - if ( scope.object.isPerspectiveCamera ) { _eye.multiplyScalar( factor ); @@ -207,7 +190,6 @@ } else { factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * scope.zoomSpeed; - if ( factor !== 1.0 && factor > 0.0 ) { if ( scope.object.isPerspectiveCamera ) { @@ -249,7 +231,6 @@ return function panCamera() { mouseChange.copy( _panEnd ).sub( _panStart ); - if ( mouseChange.lengthSq() ) { if ( scope.object.isOrthographicCamera ) { @@ -266,7 +247,6 @@ pan.add( objectUp.copy( scope.object.up ).setLength( mouseChange.y ) ); scope.object.position.add( pan ); scope.target.add( pan ); - if ( scope.staticMoving ) { _panStart.copy( _panEnd ); @@ -282,7 +262,6 @@ }; }(); - this.checkDistances = function () { if ( ! scope.noZoom || ! scope.noPan ) { @@ -290,7 +269,6 @@ if ( _eye.lengthSq() > scope.maxDistance * scope.maxDistance ) { scope.object.position.addVectors( scope.target, _eye.setLength( scope.maxDistance ) ); - _zoomStart.copy( _zoomEnd ); } @@ -298,7 +276,6 @@ if ( _eye.lengthSq() < scope.minDistance * scope.minDistance ) { scope.object.position.addVectors( scope.target, _eye.setLength( scope.minDistance ) ); - _zoomStart.copy( _zoomEnd ); } @@ -310,7 +287,6 @@ this.update = function () { _eye.subVectors( scope.object.position, scope.target ); - if ( ! scope.noRotate ) { scope.rotateCamera(); @@ -330,12 +306,10 @@ } scope.object.position.addVectors( scope.target, _eye ); - if ( scope.object.isPerspectiveCamera ) { scope.checkDistances(); scope.object.lookAt( scope.target ); - if ( lastPosition.distanceToSquared( scope.object.position ) > EPS ) { scope.dispatchEvent( _changeEvent ); @@ -346,7 +320,6 @@ } else if ( scope.object.isOrthographicCamera ) { scope.object.lookAt( scope.target ); - if ( lastPosition.distanceToSquared( scope.object.position ) > EPS || lastZoom !== scope.object.zoom ) { scope.dispatchEvent( _changeEvent ); @@ -372,32 +345,30 @@ scope.object.up.copy( scope.up0 ); scope.object.zoom = scope.zoom0; scope.object.updateProjectionMatrix(); - _eye.subVectors( scope.object.position, scope.target ); - scope.object.lookAt( scope.target ); scope.dispatchEvent( _changeEvent ); lastPosition.copy( scope.object.position ); lastZoom = scope.object.zoom; - }; // listeners + }; + // listeners function onPointerDown( event ) { if ( scope.enabled === false ) return; - if ( _pointers.length === 0 ) { scope.domElement.setPointerCapture( event.pointerId ); scope.domElement.addEventListener( 'pointermove', onPointerMove ); scope.domElement.addEventListener( 'pointerup', onPointerUp ); - } // + } + // addPointer( event ); - if ( event.pointerType === 'touch' ) { onTouchStart( event ); @@ -413,7 +384,6 @@ function onPointerMove( event ) { if ( scope.enabled === false ) return; - if ( event.pointerType === 'touch' ) { onTouchMove( event ); @@ -429,7 +399,6 @@ function onPointerUp( event ) { if ( scope.enabled === false ) return; - if ( event.pointerType === 'touch' ) { onTouchEnd( event ); @@ -438,11 +407,11 @@ onMouseUp(); - } // + } + // removePointer( event ); - if ( _pointers.length === 0 ) { scope.domElement.releasePointerCapture( event.pointerId ); @@ -463,7 +432,6 @@ if ( scope.enabled === false ) return; window.removeEventListener( 'keydown', keydown ); - if ( _keyState !== STATE.NONE ) { return; @@ -501,11 +469,9 @@ case scope.mouseButtons.LEFT: _state = STATE.ROTATE; break; - case scope.mouseButtons.MIDDLE: _state = STATE.ZOOM; break; - case scope.mouseButtons.RIGHT: _state = STATE.PAN; break; @@ -515,23 +481,19 @@ } const state = _keyState !== STATE.NONE ? _keyState : _state; - if ( state === STATE.ROTATE && ! scope.noRotate ) { _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) ); - _movePrev.copy( _moveCurr ); } else if ( state === STATE.ZOOM && ! scope.noZoom ) { _zoomStart.copy( getMouseOnScreen( event.pageX, event.pageY ) ); - _zoomEnd.copy( _zoomStart ); } else if ( state === STATE.PAN && ! scope.noPan ) { _panStart.copy( getMouseOnScreen( event.pageX, event.pageY ) ); - _panEnd.copy( _panStart ); } @@ -543,11 +505,9 @@ function onMouseMove( event ) { const state = _keyState !== STATE.NONE ? _keyState : _state; - if ( state === STATE.ROTATE && ! scope.noRotate ) { _movePrev.copy( _moveCurr ); - _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) ); } else if ( state === STATE.ZOOM && ! scope.noZoom ) { @@ -574,19 +534,16 @@ if ( scope.enabled === false ) return; if ( scope.noZoom === true ) return; event.preventDefault(); - switch ( event.deltaMode ) { case 2: // Zoom in pages _zoomStart.y -= event.deltaY * 0.025; break; - case 1: // Zoom in lines _zoomStart.y -= event.deltaY * 0.01; break; - default: // undefined, 0, assume pixels _zoomStart.y -= event.deltaY * 0.00025; @@ -602,18 +559,13 @@ function onTouchStart( event ) { trackPointer( event ); - switch ( _pointers.length ) { case 1: _state = STATE.TOUCH_ROTATE; - _moveCurr.copy( getMouseOnCircle( _pointers[ 0 ].pageX, _pointers[ 0 ].pageY ) ); - _movePrev.copy( _moveCurr ); - break; - default: // 2 or more _state = STATE.TOUCH_ZOOM_PAN; @@ -622,11 +574,8 @@ _touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy ); const x = ( _pointers[ 0 ].pageX + _pointers[ 1 ].pageX ) / 2; const y = ( _pointers[ 0 ].pageY + _pointers[ 1 ].pageY ) / 2; - _panStart.copy( getMouseOnScreen( x, y ) ); - _panEnd.copy( _panStart ); - break; } @@ -638,27 +587,22 @@ function onTouchMove( event ) { trackPointer( event ); - switch ( _pointers.length ) { case 1: _movePrev.copy( _moveCurr ); - _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) ); - break; - default: // 2 or more + const position = getSecondPointerPosition( event ); const dx = event.pageX - position.x; const dy = event.pageY - position.y; _touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy ); const x = ( event.pageX + position.x ) / 2; const y = ( event.pageY + position.y ) / 2; - _panEnd.copy( getMouseOnScreen( x, y ) ); - break; } @@ -672,22 +616,25 @@ case 0: _state = STATE.NONE; break; - case 1: _state = STATE.TOUCH_ROTATE; - _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) ); - _movePrev.copy( _moveCurr ); - break; - case 2: _state = STATE.TOUCH_ZOOM_PAN; + for ( let i = 0; i < _pointers.length; i ++ ) { - _moveCurr.copy( getMouseOnCircle( event.pageX - _movePrev.x, event.pageY - _movePrev.y ) ); + if ( _pointers[ i ].pointerId !== event.pointerId ) { - _movePrev.copy( _moveCurr ); + const position = _pointerPositions[ _pointers[ i ].pointerId ]; + _moveCurr.copy( getMouseOnCircle( position.x, position.y ) ); + _movePrev.copy( _moveCurr ); + break; + + } + + } break; @@ -713,13 +660,11 @@ function removePointer( event ) { delete _pointerPositions[ event.pointerId ]; - for ( let i = 0; i < _pointers.length; i ++ ) { if ( _pointers[ i ].pointerId == event.pointerId ) { _pointers.splice( i, 1 ); - return; } @@ -731,7 +676,6 @@ function trackPointer( event ) { let position = _pointerPositions[ event.pointerId ]; - if ( position === undefined ) { position = new THREE.Vector2(); @@ -771,8 +715,9 @@ } ); window.addEventListener( 'keydown', keydown ); window.addEventListener( 'keyup', keyup ); - this.handleResize(); // force an update at start + this.handleResize(); + // force an update at start this.update(); } diff --git a/examples/js/controls/TransformControls.js b/examples/js/controls/TransformControls.js index 511a2527622576..44e615d8953d91 100644 --- a/examples/js/controls/TransformControls.js +++ b/examples/js/controls/TransformControls.js @@ -1,13 +1,9 @@ ( function () { const _raycaster = new THREE.Raycaster(); - const _tempVector = new THREE.Vector3(); - const _tempVector2 = new THREE.Vector3(); - const _tempQuaternion = new THREE.Quaternion(); - const _unit = { X: new THREE.Vector3( 1, 0, 0 ), Y: new THREE.Vector3( 0, 1, 0 ), @@ -26,13 +22,11 @@ const _objectChangeEvent = { type: 'objectChange' }; - class TransformControls extends THREE.Object3D { constructor( camera, domElement ) { super(); - if ( domElement === undefined ) { console.warn( 'THREE.TransformControls: The second parameter "domElement" is now mandatory.' ); @@ -46,16 +40,14 @@ this.domElement.style.touchAction = 'none'; // disable touch scroll const _gizmo = new TransformControlsGizmo(); - this._gizmo = _gizmo; this.add( _gizmo ); - const _plane = new TransformControlsPlane(); - this._plane = _plane; this.add( _plane ); - const scope = this; // Defined getter, setter and store for a property + const scope = this; + // Defined getter, setter and store for a property function defineProperty( propName, defaultValue ) { let propValue = defaultValue; @@ -86,11 +78,12 @@ _plane[ propName ] = defaultValue; _gizmo[ propName ] = defaultValue; - } // Define properties with getters/setter + } + + // Define properties with getters/setter // Setting the defined property will automatically trigger change event // Defined properties are passed down to gizmo and plane - defineProperty( 'camera', camera ); defineProperty( 'object', undefined ); defineProperty( 'enabled', true ); @@ -104,7 +97,9 @@ defineProperty( 'dragging', false ); defineProperty( 'showX', true ); defineProperty( 'showY', true ); - defineProperty( 'showZ', true ); // Reusable utility variables + defineProperty( 'showZ', true ); + + // Reusable utility variables const worldPosition = new THREE.Vector3(); const worldPositionStart = new THREE.Vector3(); @@ -116,7 +111,9 @@ const pointEnd = new THREE.Vector3(); const rotationAxis = new THREE.Vector3(); const rotationAngle = 0; - const eye = new THREE.Vector3(); // TODO: remove properties unused in plane and gizmo + const eye = new THREE.Vector3(); + + // TODO: remove properties unused in plane and gizmo defineProperty( 'worldPosition', worldPosition ); defineProperty( 'worldPositionStart', worldPositionStart ); @@ -152,15 +149,14 @@ this.domElement.addEventListener( 'pointermove', this._onPointerHover ); this.domElement.addEventListener( 'pointerup', this._onPointerUp ); - } // updateMatrixWorld updates key transformation variables - + } + // updateMatrixWorld updates key transformation variables updateMatrixWorld() { if ( this.object !== undefined ) { this.object.updateMatrixWorld(); - if ( this.object.parent === null ) { console.error( 'TransformControls: The attached 3D object must be a part of the scene graph.' ); @@ -172,19 +168,16 @@ } this.object.matrixWorld.decompose( this.worldPosition, this.worldQuaternion, this._worldScale ); - this._parentQuaternionInv.copy( this._parentQuaternion ).invert(); - this._worldQuaternionInv.copy( this.worldQuaternion ).invert(); } this.camera.updateMatrixWorld(); this.camera.matrixWorld.decompose( this.cameraPosition, this.cameraQuaternion, this._cameraScale ); - if ( this.camera.isOrthographicCamera ) { - this.camera.getWorldDirection( this.eye ); + this.camera.getWorldDirection( this.eye ).negate(); } else { @@ -195,15 +188,11 @@ super.updateMatrixWorld( this ); } - pointerHover( pointer ) { if ( this.object === undefined || this.dragging === true ) return; - _raycaster.setFromCamera( pointer, this.camera ); - const intersect = intersectObjectWithRay( this._gizmo.picker[ this.mode ], _raycaster ); - if ( intersect ) { this.axis = intersect.object.name; @@ -215,28 +204,20 @@ } } - pointerDown( pointer ) { if ( this.object === undefined || this.dragging === true || pointer.button !== 0 ) return; - if ( this.axis !== null ) { _raycaster.setFromCamera( pointer, this.camera ); - const planeIntersect = intersectObjectWithRay( this._plane, _raycaster, true ); - if ( planeIntersect ) { this.object.updateMatrixWorld(); this.object.parent.updateMatrixWorld(); - this._positionStart.copy( this.object.position ); - this._quaternionStart.copy( this.object.quaternion ); - this._scaleStart.copy( this.object.scale ); - this.object.matrixWorld.decompose( this.worldPositionStart, this.worldQuaternionStart, this._worldScaleStart ); this.pointStart.copy( planeIntersect.point ).sub( this.worldPositionStart ); @@ -249,14 +230,12 @@ } } - pointerMove( pointer ) { const axis = this.axis; const mode = this.mode; const object = this.object; let space = this.space; - if ( mode === 'scale' ) { space = 'local'; @@ -268,18 +247,15 @@ } if ( object === undefined || axis === null || this.dragging === false || pointer.button !== - 1 ) return; - _raycaster.setFromCamera( pointer, this.camera ); - const planeIntersect = intersectObjectWithRay( this._plane, _raycaster, true ); if ( ! planeIntersect ) return; this.pointEnd.copy( planeIntersect.point ).sub( this.worldPositionStart ); - if ( mode === 'translate' ) { // Apply translate - this._offset.copy( this.pointEnd ).sub( this.pointStart ); + this._offset.copy( this.pointEnd ).sub( this.pointStart ); if ( space === 'local' && axis !== 'XYZ' ) { this._offset.applyQuaternion( this._worldQuaternionInv ); @@ -289,7 +265,6 @@ if ( axis.indexOf( 'X' ) === - 1 ) this._offset.x = 0; if ( axis.indexOf( 'Y' ) === - 1 ) this._offset.y = 0; if ( axis.indexOf( 'Z' ) === - 1 ) this._offset.z = 0; - if ( space === 'local' && axis !== 'XYZ' ) { this._offset.applyQuaternion( this._quaternionStart ).divide( this._parentScale ); @@ -300,14 +275,15 @@ } - object.position.copy( this._offset ).add( this._positionStart ); // Apply translation snap + object.position.copy( this._offset ).add( this._positionStart ); + + // Apply translation snap if ( this.translationSnap ) { if ( space === 'local' ) { object.position.applyQuaternion( _tempQuaternion.copy( this._quaternionStart ).invert() ); - if ( axis.search( 'X' ) !== - 1 ) { object.position.x = Math.round( object.position.x / this.translationSnap ) * this.translationSnap; @@ -372,21 +348,15 @@ let d = this.pointEnd.length() / this.pointStart.length(); if ( this.pointEnd.dot( this.pointStart ) < 0 ) d *= - 1; - _tempVector2.set( d, d, d ); } else { _tempVector.copy( this.pointStart ); - _tempVector2.copy( this.pointEnd ); - _tempVector.applyQuaternion( this._worldQuaternionInv ); - _tempVector2.applyQuaternion( this._worldQuaternionInv ); - _tempVector2.divide( _tempVector ); - if ( axis.search( 'X' ) === - 1 ) { _tempVector2.x = 1; @@ -405,11 +375,11 @@ } - } // Apply scale + } + // Apply scale object.scale.copy( this._scaleStart ).multiply( _tempVector2 ); - if ( this.scaleSnap ) { if ( axis.search( 'X' ) !== - 1 ) { @@ -435,18 +405,13 @@ } else if ( mode === 'rotate' ) { this._offset.copy( this.pointEnd ).sub( this.pointStart ); - const ROTATION_SPEED = 20 / this.worldPosition.distanceTo( _tempVector.setFromMatrixPosition( this.camera.matrixWorld ) ); - if ( axis === 'E' ) { this.rotationAxis.copy( this.eye ); this.rotationAngle = this.pointEnd.angleTo( this.pointStart ); - this._startNorm.copy( this.pointStart ).normalize(); - this._endNorm.copy( this.pointEnd ).normalize(); - this.rotationAngle *= this._endNorm.cross( this._startNorm ).dot( this.eye ) < 0 ? 1 : - 1; } else if ( axis === 'XYZE' ) { @@ -457,9 +422,7 @@ } else if ( axis === 'X' || axis === 'Y' || axis === 'Z' ) { this.rotationAxis.copy( _unit[ axis ] ); - _tempVector.copy( _unit[ axis ] ); - if ( space === 'local' ) { _tempVector.applyQuaternion( this.worldQuaternion ); @@ -468,11 +431,13 @@ this.rotationAngle = this._offset.dot( _tempVector.cross( this.eye ).normalize() ) * ROTATION_SPEED; - } // Apply rotation snap + } + // Apply rotation snap - if ( this.rotationSnap ) this.rotationAngle = Math.round( this.rotationAngle / this.rotationSnap ) * this.rotationSnap; // Apply rotate + if ( this.rotationSnap ) this.rotationAngle = Math.round( this.rotationAngle / this.rotationSnap ) * this.rotationSnap; + // Apply rotate if ( space === 'local' && axis !== 'E' && axis !== 'XYZE' ) { object.quaternion.copy( this._quaternionStart ); @@ -492,11 +457,9 @@ this.dispatchEvent( _objectChangeEvent ); } - pointerUp( pointer ) { if ( pointer.button !== 0 ) return; - if ( this.dragging && this.axis !== null ) { _mouseUpEvent.mode = this.mode; @@ -508,7 +471,6 @@ this.axis = null; } - dispose() { this.domElement.removeEventListener( 'pointerdown', this._onPointerDown ); @@ -522,18 +484,18 @@ } ); - } // Set current object - + } + // Set current object attach( object ) { this.object = object; this.visible = true; return this; - } // Detatch from object - + } + // Detach from object detach() { this.object = undefined; @@ -542,11 +504,9 @@ return this; } - reset() { if ( ! this.enabled ) return; - if ( this.dragging ) { this.object.position.copy( this._positionStart ); @@ -559,64 +519,53 @@ } } - getRaycaster() { return _raycaster; - } // TODO: deprecate + } + // TODO: deprecate getMode() { return this.mode; } - setMode( mode ) { this.mode = mode; } - setTranslationSnap( translationSnap ) { this.translationSnap = translationSnap; } - setRotationSnap( rotationSnap ) { this.rotationSnap = rotationSnap; } - setScaleSnap( scaleSnap ) { this.scaleSnap = scaleSnap; } - setSize( size ) { this.size = size; } - setSpace( space ) { this.space = space; } - update() { - - console.warn( 'THREE.TransformControls: update function has no more functionality and therefore has been deprecated.' ); - - } - - } // mouse / touch event handlers + } + // mouse / touch event handlers function getPointer( event ) { @@ -644,7 +593,6 @@ function onPointerHover( event ) { if ( ! this.enabled ) return; - switch ( event.pointerType ) { case 'mouse': @@ -659,7 +607,6 @@ function onPointerDown( event ) { if ( ! this.enabled ) return; - if ( ! document.pointerLockElement ) { this.domElement.setPointerCapture( event.pointerId ); @@ -691,7 +638,6 @@ function intersectObjectWithRay( object, raycaster, includeInvisible ) { const allIntersections = raycaster.intersectObject( object, true ); - for ( let i = 0; i < allIntersections.length; i ++ ) { if ( allIntersections[ i ].object.visible || includeInvisible ) { @@ -704,45 +650,35 @@ return false; - } // - // Reusable utility variables + } + // - const _tempEuler = new THREE.Euler(); + // Reusable utility variables + const _tempEuler = new THREE.Euler(); const _alignVector = new THREE.Vector3( 0, 1, 0 ); - const _zeroVector = new THREE.Vector3( 0, 0, 0 ); - const _lookAtMatrix = new THREE.Matrix4(); - const _tempQuaternion2 = new THREE.Quaternion(); - const _identityQuaternion = new THREE.Quaternion(); - const _dirVector = new THREE.Vector3(); - const _tempMatrix = new THREE.Matrix4(); - const _unitX = new THREE.Vector3( 1, 0, 0 ); - const _unitY = new THREE.Vector3( 0, 1, 0 ); - const _unitZ = new THREE.Vector3( 0, 0, 1 ); - const _v1 = new THREE.Vector3(); - const _v2 = new THREE.Vector3(); - const _v3 = new THREE.Vector3(); - class TransformControlsGizmo extends THREE.Object3D { constructor() { super(); this.isTransformControlsGizmo = true; - this.type = 'TransformControlsGizmo'; // shared materials + this.type = 'TransformControlsGizmo'; + + // shared materials const gizmoMaterial = new THREE.MeshBasicMaterial( { depthTest: false, @@ -757,7 +693,9 @@ fog: false, toneMapped: false, transparent: true - } ); // Make unique material for each axis/color + } ); + + // Make unique material for each axis/color const matInvisible = gizmoMaterial.clone(); matInvisible.opacity = 0.15; @@ -786,7 +724,9 @@ const matYellow = gizmoMaterial.clone(); matYellow.color.setHex( 0xffff00 ); const matGray = gizmoMaterial.clone(); - matGray.color.setHex( 0x787878 ); // reusable geometry + matGray.color.setHex( 0x787878 ); + + // reusable geometry const arrowGeometry = new THREE.CylinderGeometry( 0, 0.04, 0.1, 12 ); arrowGeometry.translate( 0, 0.05, 0 ); @@ -796,7 +736,6 @@ lineGeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ 0, 0, 0, 1, 0, 0 ], 3 ) ); const lineGeometry2 = new THREE.CylinderGeometry( 0.0075, 0.0075, 0.5, 3 ); lineGeometry2.translate( 0, 0.25, 0 ); - function CircleGeometry( radius, arc ) { const geometry = new THREE.TorusGeometry( radius, 0.0075, 3, 64, arc * Math.PI * 2 ); @@ -804,8 +743,9 @@ geometry.rotateX( Math.PI / 2 ); return geometry; - } // Special geometry for transform helper. If scaled with position vector it spans from [0,0,0] to position + } + // Special geometry for transform helper. If scaled with position vector it spans from [0,0,0] to position function TranslateHelperGeometry() { @@ -813,8 +753,9 @@ geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ 0, 0, 0, 1, 1, 1 ], 3 ) ); return geometry; - } // Gizmo definitions - custom hierarchy definitions for setupGizmo() function + } + // Gizmo definitions - custom hierarchy definitions for setupGizmo() function const gizmoTranslate = { X: [[ new THREE.Mesh( arrowGeometry, matRed ), [ 0.5, 0, 0 ], [ 0, 0, - Math.PI / 2 ]], [ new THREE.Mesh( arrowGeometry, matRed ), [ - 0.5, 0, 0 ], [ 0, 0, Math.PI / 2 ]], [ new THREE.Mesh( lineGeometry2, matRed ), [ 0, 0, 0 ], [ 0, 0, - Math.PI / 2 ]]], @@ -881,12 +822,13 @@ X: [[ new THREE.Line( lineGeometry, matHelper.clone() ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]], Y: [[ new THREE.Line( lineGeometry, matHelper.clone() ), [ 0, - 1e3, 0 ], [ 0, 0, Math.PI / 2 ], [ 1e6, 1, 1 ], 'helper' ]], Z: [[ new THREE.Line( lineGeometry, matHelper.clone() ), [ 0, 0, - 1e3 ], [ 0, - Math.PI / 2, 0 ], [ 1e6, 1, 1 ], 'helper' ]] - }; // Creates an THREE.Object3D with gizmos described in custom hierarchy definition. + }; + + // Creates an THREE.Object3D with gizmos described in custom hierarchy definition. function setupGizmo( gizmoMap ) { const gizmo = new THREE.Object3D(); - for ( const name in gizmoMap ) { for ( let i = gizmoMap[ name ].length; i --; ) { @@ -895,11 +837,11 @@ const position = gizmoMap[ name ][ i ][ 1 ]; const rotation = gizmoMap[ name ][ i ][ 2 ]; const scale = gizmoMap[ name ][ i ][ 3 ]; - const tag = gizmoMap[ name ][ i ][ 4 ]; // name and tag properties are essential for picking and updating logic. + const tag = gizmoMap[ name ][ i ][ 4 ]; + // name and tag properties are essential for picking and updating logic. object.name = name; object.tag = tag; - if ( position ) { object.position.set( position[ 0 ], position[ 1 ], position[ 2 ] ); @@ -934,8 +876,9 @@ return gizmo; - } // Gizmo creation + } + // Gizmo creation this.gizmo = {}; this.picker = {}; @@ -948,20 +891,25 @@ this.add( this.picker[ 'scale' ] = setupGizmo( pickerScale ) ); this.add( this.helper[ 'translate' ] = setupGizmo( helperTranslate ) ); this.add( this.helper[ 'rotate' ] = setupGizmo( helperRotate ) ); - this.add( this.helper[ 'scale' ] = setupGizmo( helperScale ) ); // Pickers should be hidden always + this.add( this.helper[ 'scale' ] = setupGizmo( helperScale ) ); + + // Pickers should be hidden always this.picker[ 'translate' ].visible = false; this.picker[ 'rotate' ].visible = false; this.picker[ 'scale' ].visible = false; - } // updateMatrixWorld will update transformations and appearance of individual handles + } + // updateMatrixWorld will update transformations and appearance of individual handles updateMatrixWorld( force ) { const space = this.mode === 'scale' ? 'local' : this.space; // scale always oriented to local rotation - const quaternion = space === 'local' ? this.worldQuaternion : _identityQuaternion; // Show only gizmos for current transform mode + const quaternion = space === 'local' ? this.worldQuaternion : _identityQuaternion; + + // Show only gizmos for current transform mode this.gizmo[ 'translate' ].visible = this.mode === 'translate'; this.gizmo[ 'rotate' ].visible = this.mode === 'rotate'; @@ -973,16 +921,16 @@ handles = handles.concat( this.picker[ this.mode ].children ); handles = handles.concat( this.gizmo[ this.mode ].children ); handles = handles.concat( this.helper[ this.mode ].children ); - for ( let i = 0; i < handles.length; i ++ ) { - const handle = handles[ i ]; // hide aligned to camera + const handle = handles[ i ]; + + // hide aligned to camera handle.visible = true; handle.rotation.set( 0, 0, 0 ); handle.position.copy( this.worldPosition ); let factor; - if ( this.camera.isOrthographicCamera ) { factor = ( this.camera.top - this.camera.bottom ) / this.camera.zoom; @@ -993,23 +941,21 @@ } - handle.scale.set( 1, 1, 1 ).multiplyScalar( factor * this.size / 4 ); // TODO: simplify helpers and consider decoupling from gizmo + handle.scale.set( 1, 1, 1 ).multiplyScalar( factor * this.size / 4 ); + + // TODO: simplify helpers and consider decoupling from gizmo if ( handle.tag === 'helper' ) { handle.visible = false; - if ( handle.name === 'AXIS' ) { handle.position.copy( this.worldPositionStart ); handle.visible = !! this.axis; - if ( this.axis === 'X' ) { _tempQuaternion.setFromEuler( _tempEuler.set( 0, 0, 0 ) ); - handle.quaternion.copy( quaternion ).multiply( _tempQuaternion ); - if ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) { handle.visible = false; @@ -1021,9 +967,7 @@ if ( this.axis === 'Y' ) { _tempQuaternion.setFromEuler( _tempEuler.set( 0, 0, Math.PI / 2 ) ); - handle.quaternion.copy( quaternion ).multiply( _tempQuaternion ); - if ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) { handle.visible = false; @@ -1035,9 +979,7 @@ if ( this.axis === 'Z' ) { _tempQuaternion.setFromEuler( _tempEuler.set( 0, Math.PI / 2, 0 ) ); - handle.quaternion.copy( quaternion ).multiply( _tempQuaternion ); - if ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) { handle.visible = false; @@ -1049,9 +991,7 @@ if ( this.axis === 'XYZE' ) { _tempQuaternion.setFromEuler( _tempEuler.set( 0, Math.PI / 2, 0 ) ); - _alignVector.copy( this.rotationAxis ); - handle.quaternion.setFromRotationMatrix( _lookAtMatrix.lookAt( _zeroVector, _alignVector, _unitY ) ); handle.quaternion.multiply( _tempQuaternion ); handle.visible = this.dragging; @@ -1078,18 +1018,14 @@ handle.position.copy( this.worldPositionStart ); handle.quaternion.copy( this.worldQuaternionStart ); - _tempVector.set( 1e-10, 1e-10, 1e-10 ).add( this.worldPositionStart ).sub( this.worldPosition ).multiplyScalar( - 1 ); - _tempVector.applyQuaternion( this.worldQuaternionStart.clone().invert() ); - handle.scale.copy( _tempVector ); handle.visible = this.dragging; } else { handle.quaternion.copy( quaternion ); - if ( this.dragging ) { handle.position.copy( this.worldPositionStart ); @@ -1106,25 +1042,25 @@ } - } // If updating helper, skip rest of the loop - + } + // If updating helper, skip rest of the loop continue; - } // Align handles to current local or world rotation + } + // Align handles to current local or world rotation handle.quaternion.copy( quaternion ); - if ( this.mode === 'translate' || this.mode === 'scale' ) { // Hide translate and scale axis facing the camera - const AXIS_HIDE_TRESHOLD = 0.99; - const PLANE_HIDE_TRESHOLD = 0.2; + const AXIS_HIDE_THRESHOLD = 0.99; + const PLANE_HIDE_THRESHOLD = 0.2; if ( handle.name === 'X' ) { - if ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_TRESHOLD ) { + if ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_THRESHOLD ) { handle.scale.set( 1e-10, 1e-10, 1e-10 ); handle.visible = false; @@ -1135,7 +1071,7 @@ if ( handle.name === 'Y' ) { - if ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_TRESHOLD ) { + if ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_THRESHOLD ) { handle.scale.set( 1e-10, 1e-10, 1e-10 ); handle.visible = false; @@ -1146,7 +1082,7 @@ if ( handle.name === 'Z' ) { - if ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_TRESHOLD ) { + if ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_THRESHOLD ) { handle.scale.set( 1e-10, 1e-10, 1e-10 ); handle.visible = false; @@ -1157,7 +1093,7 @@ if ( handle.name === 'XY' ) { - if ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_TRESHOLD ) { + if ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_THRESHOLD ) { handle.scale.set( 1e-10, 1e-10, 1e-10 ); handle.visible = false; @@ -1168,7 +1104,7 @@ if ( handle.name === 'YZ' ) { - if ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_TRESHOLD ) { + if ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_THRESHOLD ) { handle.scale.set( 1e-10, 1e-10, 1e-10 ); handle.visible = false; @@ -1179,7 +1115,7 @@ if ( handle.name === 'XZ' ) { - if ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_TRESHOLD ) { + if ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_THRESHOLD ) { handle.scale.set( 1e-10, 1e-10, 1e-10 ); handle.visible = false; @@ -1191,10 +1127,9 @@ } else if ( this.mode === 'rotate' ) { // Align handles to current local or world rotation - _tempQuaternion2.copy( quaternion ); + _tempQuaternion2.copy( quaternion ); _alignVector.copy( this.eye ).applyQuaternion( _tempQuaternion.copy( quaternion ).invert() ); - if ( handle.name.search( 'E' ) !== - 1 ) { handle.quaternion.setFromRotationMatrix( _lookAtMatrix.lookAt( this.eye, _zeroVector, _unitY ) ); @@ -1204,9 +1139,7 @@ if ( handle.name === 'X' ) { _tempQuaternion.setFromAxisAngle( _unitX, Math.atan2( - _alignVector.y, _alignVector.z ) ); - _tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion ); - handle.quaternion.copy( _tempQuaternion ); } @@ -1214,9 +1147,7 @@ if ( handle.name === 'Y' ) { _tempQuaternion.setFromAxisAngle( _unitY, Math.atan2( _alignVector.x, _alignVector.z ) ); - _tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion ); - handle.quaternion.copy( _tempQuaternion ); } @@ -1224,26 +1155,25 @@ if ( handle.name === 'Z' ) { _tempQuaternion.setFromAxisAngle( _unitZ, Math.atan2( _alignVector.y, _alignVector.x ) ); - _tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion ); - handle.quaternion.copy( _tempQuaternion ); } - } // Hide disabled axes - + } + // Hide disabled axes handle.visible = handle.visible && ( handle.name.indexOf( 'X' ) === - 1 || this.showX ); handle.visible = handle.visible && ( handle.name.indexOf( 'Y' ) === - 1 || this.showY ); handle.visible = handle.visible && ( handle.name.indexOf( 'Z' ) === - 1 || this.showZ ); - handle.visible = handle.visible && ( handle.name.indexOf( 'E' ) === - 1 || this.showX && this.showY && this.showZ ); // highlight selected axis + handle.visible = handle.visible && ( handle.name.indexOf( 'E' ) === - 1 || this.showX && this.showY && this.showZ ); + + // highlight selected axis handle.material._color = handle.material._color || handle.material.color.clone(); handle.material._opacity = handle.material._opacity || handle.material.opacity; handle.material.color.copy( handle.material._color ); handle.material.opacity = handle.material._opacity; - if ( this.enabled && this.axis ) { if ( handle.name === this.axis ) { @@ -1270,8 +1200,9 @@ } - } // + } + // class TransformControlsPlane extends THREE.Mesh { @@ -1289,7 +1220,6 @@ this.type = 'TransformControlsPlane'; } - updateMatrixWorld( force ) { let space = this.space; @@ -1297,14 +1227,12 @@ if ( this.mode === 'scale' ) space = 'local'; // scale always oriented to local rotation _v1.copy( _unitX ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion ); - _v2.copy( _unitY ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion ); + _v3.copy( _unitZ ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion ); - _v3.copy( _unitZ ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion ); // Align the plane for current transform mode, axis and space. - + // Align the plane for current transform mode, axis and space. _alignVector.copy( _v2 ); - switch ( this.mode ) { case 'translate': @@ -1313,52 +1241,34 @@ case 'X': _alignVector.copy( this.eye ).cross( _v1 ); - _dirVector.copy( _v1 ).cross( _alignVector ); - break; - case 'Y': _alignVector.copy( this.eye ).cross( _v2 ); - _dirVector.copy( _v2 ).cross( _alignVector ); - break; - case 'Z': _alignVector.copy( this.eye ).cross( _v3 ); - _dirVector.copy( _v3 ).cross( _alignVector ); - break; - case 'XY': _dirVector.copy( _v3 ); - break; - case 'YZ': _dirVector.copy( _v1 ); - break; - case 'XZ': _alignVector.copy( _v3 ); - _dirVector.copy( _v2 ); - break; - case 'XYZ': case 'E': _dirVector.set( 0, 0, 0 ); - break; } break; - case 'rotate': default: // special case for rotate @@ -1374,7 +1284,6 @@ } else { _tempMatrix.lookAt( _tempVector.set( 0, 0, 0 ), _dirVector, _alignVector ); - this.quaternion.setFromRotationMatrix( _tempMatrix ); } diff --git a/examples/js/csm/CSM.js b/examples/js/csm/CSM.js index c8d5326bad891b..ff0dcb918ebc87 100644 --- a/examples/js/csm/CSM.js +++ b/examples/js/csm/CSM.js @@ -1,13 +1,9 @@ ( function () { const _cameraToLightMatrix = new THREE.Matrix4(); - const _lightSpaceFrustum = new THREE.CSMFrustum(); - const _center = new THREE.Vector3(); - const _bbox = new THREE.Box3(); - const _uniformArray = []; const _logArray = []; class CSM { @@ -39,7 +35,6 @@ this.injectInclude(); } - createLights() { for ( let i = 0; i < this.cascades; i ++ ) { @@ -58,7 +53,6 @@ } } - initCascades() { const camera = this.camera; @@ -67,24 +61,22 @@ this.mainFrustum.split( this.breaks, this.frustums ); } - updateShadowBounds() { const frustums = this.frustums; - for ( let i = 0; i < frustums.length; i ++ ) { const light = this.lights[ i ]; const shadowCam = light.shadow.camera; - const frustum = this.frustums[ i ]; // Get the two points that represent that furthest points on the frustum assuming + const frustum = this.frustums[ i ]; + + // Get the two points that represent that furthest points on the frustum assuming // that's either the diagonal across the far plane or the diagonal across the whole // frustum itself. - const nearVerts = frustum.vertices.near; const farVerts = frustum.vertices.far; const point1 = farVerts[ 0 ]; let point2; - if ( point1.distanceTo( farVerts[ 2 ] ) > point1.distanceTo( nearVerts[ 2 ] ) ) { point2 = farVerts[ 2 ]; @@ -96,7 +88,6 @@ } let squaredBBWidth = point1.distanceTo( point2 ); - if ( this.fade ) { // expand the shadow extents by the fade margin if fade is enabled. @@ -117,27 +108,22 @@ } } - getBreaks() { const camera = this.camera; const far = Math.min( camera.far, this.maxFar ); this.breaks.length = 0; - switch ( this.mode ) { case 'uniform': uniformSplit( this.cascades, camera.near, far, this.breaks ); break; - case 'logarithmic': logarithmicSplit( this.cascades, camera.near, far, this.breaks ); break; - case 'practical': practicalSplit( this.cascades, camera.near, far, 0.5, this.breaks ); break; - case 'custom': if ( this.customSplitsCallback === undefined ) console.error( 'CSM: Custom split scheme callback not defined.' ); this.customSplitsCallback( this.cascades, camera.near, far, this.breaks ); @@ -175,7 +161,6 @@ _logArray.length = 0; logarithmicSplit( amount, near, far, _logArray ); uniformSplit( amount, near, far, _uniformArray ); - for ( let i = 1; i < amount; i ++ ) { target.push( THREE.MathUtils.lerp( _uniformArray[ i - 1 ], _logArray[ i - 1 ], lambda ) ); @@ -187,12 +172,10 @@ } } - update() { const camera = this.camera; const frustums = this.frustums; - for ( let i = 0; i < frustums.length; i ++ ) { const light = this.lights[ i ]; @@ -200,31 +183,23 @@ const texelWidth = ( shadowCam.right - shadowCam.left ) / this.shadowMapSize; const texelHeight = ( shadowCam.top - shadowCam.bottom ) / this.shadowMapSize; light.shadow.camera.updateMatrixWorld( true ); - _cameraToLightMatrix.multiplyMatrices( light.shadow.camera.matrixWorldInverse, camera.matrixWorld ); - frustums[ i ].toSpace( _cameraToLightMatrix, _lightSpaceFrustum ); const nearVerts = _lightSpaceFrustum.vertices.near; const farVerts = _lightSpaceFrustum.vertices.far; - _bbox.makeEmpty(); - for ( let j = 0; j < 4; j ++ ) { _bbox.expandByPoint( nearVerts[ j ] ); - _bbox.expandByPoint( farVerts[ j ] ); } _bbox.getCenter( _center ); - _center.z = _bbox.max.z + this.lightMargin; _center.x = Math.floor( _center.x / texelWidth ) * texelWidth; _center.y = Math.floor( _center.y / texelHeight ) * texelHeight; - _center.applyMatrix4( light.shadow.camera.matrixWorld ); - light.position.copy( _center ); light.target.position.copy( _center ); light.target.position.x += this.lightDirection.x; @@ -234,20 +209,17 @@ } } - injectInclude() { THREE.ShaderChunk.lights_fragment_begin = THREE.CSMShader.lights_fragment_begin; THREE.ShaderChunk.lights_pars_begin = THREE.CSMShader.lights_pars_begin; } - setupMaterial( material ) { material.defines = material.defines || {}; material.defines.USE_CSM = 1; material.defines.CSM_CASCADES = this.cascades; - if ( this.fade ) { material.defines.CSM_FADE = ''; @@ -257,7 +229,6 @@ const breaksVec2 = []; const scope = this; const shaders = this.shaders; - material.onBeforeCompile = function ( shader ) { const far = Math.min( scope.camera.far, scope.maxFar ); @@ -278,7 +249,6 @@ shaders.set( material, null ); } - updateUniforms() { const far = Math.min( this.camera.far, this.maxFar ); @@ -309,7 +279,6 @@ }, this ); } - getExtendedBreaks( target ) { while ( target.length < this.breaks.length ) { @@ -319,7 +288,6 @@ } target.length = this.breaks.length; - for ( let i = 0; i < this.cascades; i ++ ) { const amount = this.breaks[ i ]; @@ -330,7 +298,6 @@ } } - updateFrustums() { this.getBreaks(); @@ -339,17 +306,16 @@ this.updateUniforms(); } - remove() { for ( let i = 0; i < this.lights.length; i ++ ) { + this.parent.remove( this.lights[ i ].target ); this.parent.remove( this.lights[ i ] ); } } - dispose() { const shaders = this.shaders; @@ -359,7 +325,6 @@ delete material.defines.USE_CSM; delete material.defines.CSM_CASCADES; delete material.defines.CSM_FADE; - if ( shader !== null ) { delete shader.uniforms.CSM_cascades; diff --git a/examples/js/csm/CSMFrustum.js b/examples/js/csm/CSMFrustum.js index 1c59239c9c688d..9778d1e6d03903 100644 --- a/examples/js/csm/CSMFrustum.js +++ b/examples/js/csm/CSMFrustum.js @@ -1,7 +1,6 @@ ( function () { const inverseProjectionMatrix = new THREE.Matrix4(); - class CSMFrustum { constructor( data ) { @@ -11,7 +10,6 @@ near: [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ], far: [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ] }; - if ( data.projectionMatrix !== undefined ) { this.setFromProjectionMatrix( data.projectionMatrix, data.maxFar || 10000 ); @@ -19,11 +17,12 @@ } } - setFromProjectionMatrix( projectionMatrix, maxFar ) { const isOrthographic = projectionMatrix.elements[ 2 * 4 + 3 ] === 0; - inverseProjectionMatrix.copy( projectionMatrix ).invert(); // 3 --- 0 vertices.near/far order + inverseProjectionMatrix.copy( projectionMatrix ).invert(); + + // 3 --- 0 vertices.near/far order // | | // 2 --- 1 // clip space spans from [-1, 1] @@ -45,7 +44,6 @@ v.applyMatrix4( inverseProjectionMatrix ); const absZ = Math.abs( v.z ); - if ( isOrthographic ) { v.z *= Math.min( maxFar / absZ, 1.0 ); @@ -60,7 +58,6 @@ return this.vertices; } - split( breaks, target ) { while ( breaks.length > target.length ) { @@ -70,11 +67,9 @@ } target.length = breaks.length; - for ( let i = 0; i < breaks.length; i ++ ) { const cascade = target[ i ]; - if ( i === 0 ) { for ( let j = 0; j < 4; j ++ ) { @@ -114,7 +109,6 @@ } } - toSpace( cameraMatrix, target ) { for ( let i = 0; i < 4; i ++ ) { diff --git a/examples/js/csm/CSMHelper.js b/examples/js/csm/CSMHelper.js index df372b8058accf..624cbb7d946626 100644 --- a/examples/js/csm/CSMHelper.js +++ b/examples/js/csm/CSMHelper.js @@ -22,7 +22,6 @@ this.shadowLines = []; } - updateVisibility() { const displayFrustum = this.displayFrustum; @@ -32,7 +31,6 @@ const cascadeLines = this.cascadeLines; const cascadePlanes = this.cascadePlanes; const shadowLines = this.shadowLines; - for ( let i = 0, l = cascadeLines.length; i < l; i ++ ) { const cascadeLine = cascadeLines[ i ]; @@ -47,7 +45,6 @@ frustumLines.visible = displayFrustum; } - update() { const csm = this.csm; @@ -65,7 +62,6 @@ this.quaternion.copy( camera.quaternion ); this.scale.copy( camera.scale ); this.updateMatrixWorld( true ); - while ( cascadeLines.length > cascades ) { this.remove( cascadeLines.pop() ); @@ -137,6 +133,30 @@ frustumLinePositions.needsUpdate = true; } + dispose() { + + const frustumLines = this.frustumLines; + const cascadeLines = this.cascadeLines; + const cascadePlanes = this.cascadePlanes; + const shadowLines = this.shadowLines; + frustumLines.geometry.dispose(); + frustumLines.material.dispose(); + const cascades = this.csm.cascades; + for ( let i = 0; i < cascades; i ++ ) { + + const cascadeLine = cascadeLines[ i ]; + const cascadePlane = cascadePlanes[ i ]; + const shadowLineGroup = shadowLines[ i ]; + const shadowLine = shadowLineGroup.children[ 0 ]; + cascadeLine.dispose(); // THREE.Box3Helper + + cascadePlane.geometry.dispose(); + cascadePlane.material.dispose(); + shadowLine.dispose(); // THREE.Box3Helper + + } + + } } diff --git a/examples/js/csm/CSMShader.js b/examples/js/csm/CSMShader.js index 398634b2f6525b..a072c16e893f1e 100644 --- a/examples/js/csm/CSMShader.js +++ b/examples/js/csm/CSMShader.js @@ -1,9 +1,7 @@ ( function () { const CSMShader = { - lights_fragment_begin: - /* glsl */ - ` + lights_fragment_begin: /* glsl */` GeometricContext geometry; geometry.position = - vViewPosition; @@ -241,9 +239,7 @@ IncidentLight directLight; #endif `, - lights_pars_begin: - /* glsl */ - ` + lights_pars_begin: /* glsl */` #if defined( USE_CSM ) && defined( CSM_CASCADES ) uniform vec2 CSM_cascades[CSM_CASCADES]; uniform float cameraNear; diff --git a/examples/js/curves/CurveExtras.js b/examples/js/curves/CurveExtras.js index f7772f0191e2ea..9effdbaecdfa1e 100644 --- a/examples/js/curves/CurveExtras.js +++ b/examples/js/curves/CurveExtras.js @@ -9,6 +9,7 @@ * http://www.mi.sanu.ac.rs/vismath/taylorapril2011/Taylor.pdf * https://prideout.net/blog/old/blog/index.html@p=44.html */ + // GrannyKnot class GrannyKnot extends THREE.Curve { @@ -24,8 +25,9 @@ } - } // HeartCurve + } + // HeartCurve class HeartCurve extends THREE.Curve { @@ -35,7 +37,6 @@ this.scale = scale; } - getPoint( t, optionalTarget = new THREE.Vector3() ) { const point = optionalTarget; @@ -47,8 +48,9 @@ } - } // Viviani's THREE.Curve + } + // Viviani's THREE.Curve class VivianiCurve extends THREE.Curve { @@ -58,12 +60,10 @@ this.scale = scale; } - getPoint( t, optionalTarget = new THREE.Vector3() ) { const point = optionalTarget; t = t * 4 * Math.PI; // normalized to 0..1 - const a = this.scale / 2; const x = a * ( 1 + Math.cos( t ) ); const y = a * Math.sin( t ); @@ -72,8 +72,9 @@ } - } // KnotCurve + } + // KnotCurve class KnotCurve extends THREE.Curve { @@ -90,8 +91,9 @@ } - } // HelixCurve + } + // HelixCurve class HelixCurve extends THREE.Curve { @@ -99,7 +101,6 @@ const point = optionalTarget; const a = 30; // radius - const b = 150; // height const t2 = 2 * Math.PI * t * b / 30; @@ -110,8 +111,9 @@ } - } // TrefoilKnot + } + // TrefoilKnot class TrefoilKnot extends THREE.Curve { @@ -121,7 +123,6 @@ this.scale = scale; } - getPoint( t, optionalTarget = new THREE.Vector3() ) { const point = optionalTarget; @@ -133,8 +134,9 @@ } - } // TorusKnot + } + // TorusKnot class TorusKnot extends THREE.Curve { @@ -144,7 +146,6 @@ this.scale = scale; } - getPoint( t, optionalTarget = new THREE.Vector3() ) { const point = optionalTarget; @@ -158,8 +159,9 @@ } - } // CinquefoilKnot + } + // CinquefoilKnot class CinquefoilKnot extends THREE.Curve { @@ -169,7 +171,6 @@ this.scale = scale; } - getPoint( t, optionalTarget = new THREE.Vector3() ) { const point = optionalTarget; @@ -183,8 +184,9 @@ } - } // TrefoilPolynomialKnot + } + // TrefoilPolynomialKnot class TrefoilPolynomialKnot extends THREE.Curve { @@ -194,7 +196,6 @@ this.scale = scale; } - getPoint( t, optionalTarget = new THREE.Vector3() ) { const point = optionalTarget; @@ -207,14 +208,14 @@ } } - function scaleTo( x, y, t ) { const r = y - x; return t * r + x; - } // FigureEightPolynomialKnot + } + // FigureEightPolynomialKnot class FigureEightPolynomialKnot extends THREE.Curve { @@ -224,7 +225,6 @@ this.scale = scale; } - getPoint( t, optionalTarget = new THREE.Vector3() ) { const point = optionalTarget; @@ -236,8 +236,9 @@ } - } // DecoratedTorusKnot4a + } + // DecoratedTorusKnot4a class DecoratedTorusKnot4a extends THREE.Curve { @@ -247,7 +248,6 @@ this.scale = scale; } - getPoint( t, optionalTarget = new THREE.Vector3() ) { const point = optionalTarget; @@ -259,8 +259,9 @@ } - } // DecoratedTorusKnot4b + } + // DecoratedTorusKnot4b class DecoratedTorusKnot4b extends THREE.Curve { @@ -270,7 +271,6 @@ this.scale = scale; } - getPoint( t, optionalTarget = new THREE.Vector3() ) { const point = optionalTarget; @@ -282,8 +282,9 @@ } - } // DecoratedTorusKnot5a + } + // DecoratedTorusKnot5a class DecoratedTorusKnot5a extends THREE.Curve { @@ -293,7 +294,6 @@ this.scale = scale; } - getPoint( t, optionalTarget = new THREE.Vector3() ) { const point = optionalTarget; @@ -305,8 +305,9 @@ } - } // DecoratedTorusKnot5c + } + // DecoratedTorusKnot5c class DecoratedTorusKnot5c extends THREE.Curve { @@ -316,7 +317,6 @@ this.scale = scale; } - getPoint( t, optionalTarget = new THREE.Vector3() ) { const point = optionalTarget; diff --git a/examples/js/curves/NURBSCurve.js b/examples/js/curves/NURBSCurve.js index 21d0ceecaa31a7..e2df88e82ab1a9 100644 --- a/examples/js/curves/NURBSCurve.js +++ b/examples/js/curves/NURBSCurve.js @@ -11,24 +11,15 @@ class NURBSCurve extends THREE.Curve { - constructor( degree, knots - /* array of reals */ - , controlPoints - /* array of Vector(2|3|4) */ - , startKnot - /* index in knots */ - , endKnot - /* index in knots */ - ) { + constructor( degree, knots /* array of reals */, controlPoints /* array of Vector(2|3|4) */, startKnot /* index in knots */, endKnot /* index in knots */ ) { super(); this.degree = degree; this.knots = knots; - this.controlPoints = []; // Used by periodic NURBS to remove hidden spans - + this.controlPoints = []; + // Used by periodic NURBS to remove hidden spans this.startKnot = startKnot || 0; this.endKnot = endKnot || this.knots.length - 1; - for ( let i = 0; i < controlPoints.length; ++ i ) { // ensure THREE.Vector4 for control points @@ -38,15 +29,13 @@ } } - getPoint( t, optionalTarget = new THREE.Vector3() ) { const point = optionalTarget; const u = this.knots[ this.startKnot ] + t * ( this.knots[ this.endKnot ] - this.knots[ this.startKnot ] ); // linear mapping t->u - // following results in (wx, wy, wz, w) homogeneous point + // following results in (wx, wy, wz, w) homogeneous point const hpoint = THREE.NURBSUtils.calcBSplinePoint( this.degree, this.knots, this.controlPoints, u ); - if ( hpoint.w !== 1.0 ) { // project to 3D space: (wx, wy, wz, w) -> (x, y, z, 1) @@ -57,7 +46,6 @@ return point.set( hpoint.x, hpoint.y, hpoint.z ); } - getTangent( t, optionalTarget = new THREE.Vector3() ) { const tangent = optionalTarget; diff --git a/examples/js/curves/NURBSSurface.js b/examples/js/curves/NURBSSurface.js index 7c67c0fd06e536..1aa4f40d719623 100644 --- a/examples/js/curves/NURBSSurface.js +++ b/examples/js/curves/NURBSSurface.js @@ -8,11 +8,7 @@ class NURBSSurface { - constructor( degree1, degree2, knots1, knots2 - /* arrays of reals */ - , controlPoints - /* array^2 of Vector(2|3|4) */ - ) { + constructor( degree1, degree2, knots1, knots2 /* arrays of reals */, controlPoints /* array^2 of Vector(2|3|4) */ ) { this.degree1 = degree1; this.degree2 = degree2; @@ -20,12 +16,12 @@ this.knots2 = knots2; this.controlPoints = []; const len1 = knots1.length - degree1 - 1; - const len2 = knots2.length - degree2 - 1; // ensure THREE.Vector4 for control points + const len2 = knots2.length - degree2 - 1; + // ensure THREE.Vector4 for control points for ( let i = 0; i < len1; ++ i ) { this.controlPoints[ i ] = []; - for ( let j = 0; j < len2; ++ j ) { const point = controlPoints[ i ][ j ]; @@ -36,11 +32,9 @@ } } - getPoint( t1, t2, target ) { const u = this.knots1[ 0 ] + t1 * ( this.knots1[ this.knots1.length - 1 ] - this.knots1[ 0 ] ); // linear mapping t1->u - const v = this.knots2[ 0 ] + t2 * ( this.knots2[ this.knots2.length - 1 ] - this.knots2[ 0 ] ); // linear mapping t2->u THREE.NURBSUtils.calcSurfacePoint( this.degree1, this.degree2, this.knots1, this.knots2, this.controlPoints, u, v, target ); diff --git a/examples/js/curves/NURBSUtils.js b/examples/js/curves/NURBSUtils.js index d42b0259f18b8d..5fbd1213db3f64 100644 --- a/examples/js/curves/NURBSUtils.js +++ b/examples/js/curves/NURBSUtils.js @@ -19,11 +19,9 @@ U : knot vector returns the span */ - function findSpan( p, u, U ) { const n = U.length - p - 1; - if ( u >= U[ n ] ) { return n - 1; @@ -39,7 +37,6 @@ returns the span let low = p; let high = n; let mid = Math.floor( ( low + high ) / 2 ); - while ( u < U[ mid ] || u >= U[ mid + 1 ] ) { if ( u < U[ mid ] ) { @@ -59,6 +56,7 @@ returns the span return mid; } + /* Calculate basis functions. See The NURBS Book, page 70, algorithm A2.2 @@ -69,21 +67,17 @@ U : knot vector returns array[p+1] with basis functions values. */ - - function calcBasisFunctions( span, u, p, U ) { const N = []; const left = []; const right = []; N[ 0 ] = 1.0; - for ( let j = 1; j <= p; ++ j ) { left[ j ] = u - U[ span + 1 - j ]; right[ j ] = U[ span + j ] - u; let saved = 0.0; - for ( let r = 0; r < j; ++ r ) { const rv = right[ r + 1 ]; @@ -101,6 +95,7 @@ returns array[p+1] with basis functions values. return N; } + /* Calculate B-Spline curve points. See The NURBS Book, page 82, algorithm A3.1. @@ -111,14 +106,11 @@ u : parametric point returns point for given u */ - - function calcBSplinePoint( p, U, P, u ) { const span = findSpan( p, u, U ); const N = calcBasisFunctions( span, u, p, U ); const C = new THREE.Vector4( 0, 0, 0, 0 ); - for ( let j = 0; j <= p; ++ j ) { const point = P[ span - p + j ]; @@ -134,6 +126,7 @@ returns point for given u return C; } + /* Calculate basis functions derivatives. See The NURBS Book, page 72, algorithm A2.3. @@ -145,32 +138,22 @@ U : knot vector returns array[n+1][p+1] with basis functions derivatives */ - - function calcBasisFunctionDerivatives( span, u, p, n, U ) { const zeroArr = []; - for ( let i = 0; i <= p; ++ i ) zeroArr[ i ] = 0.0; - const ders = []; - for ( let i = 0; i <= n; ++ i ) ders[ i ] = zeroArr.slice( 0 ); - const ndu = []; - for ( let i = 0; i <= p; ++ i ) ndu[ i ] = zeroArr.slice( 0 ); - ndu[ 0 ][ 0 ] = 1.0; const left = zeroArr.slice( 0 ); const right = zeroArr.slice( 0 ); - for ( let j = 1; j <= p; ++ j ) { left[ j ] = u - U[ span + 1 - j ]; right[ j ] = U[ span + j ] - u; let saved = 0.0; - for ( let r = 0; r < j; ++ r ) { const rv = right[ r + 1 ]; @@ -197,7 +180,6 @@ returns array[n+1][p+1] with basis functions derivatives let s1 = 0; let s2 = 1; const a = []; - for ( let i = 0; i <= p; ++ i ) { a[ i ] = zeroArr.slice( 0 ); @@ -205,13 +187,11 @@ returns array[n+1][p+1] with basis functions derivatives } a[ 0 ][ 0 ] = 1.0; - for ( let k = 1; k <= n; ++ k ) { let d = 0.0; const rk = r - k; const pk = p - k; - if ( r >= k ) { a[ s2 ][ 0 ] = a[ s1 ][ 0 ] / ndu[ pk + 1 ][ rk ]; @@ -221,7 +201,6 @@ returns array[n+1][p+1] with basis functions derivatives const j1 = rk >= - 1 ? 1 : - rk; const j2 = r - 1 <= pk ? k - 1 : p - r; - for ( let j = j1; j <= j2; ++ j ) { a[ s2 ][ j ] = ( a[ s1 ][ j ] - a[ s1 ][ j - 1 ] ) / ndu[ pk + 1 ][ rk + j ]; @@ -246,7 +225,6 @@ returns array[n+1][p+1] with basis functions derivatives } let r = p; - for ( let k = 1; k <= n; ++ k ) { for ( let j = 0; j <= p; ++ j ) { @@ -262,6 +240,7 @@ returns array[n+1][p+1] with basis functions derivatives return ders; } + /* Calculate derivatives of a B-Spline. See The NURBS Book, page 93, algorithm A3.2. @@ -273,8 +252,6 @@ returns array[n+1][p+1] with basis functions derivatives returns array[d+1] with derivatives */ - - function calcBSplineDerivatives( p, U, P, u, nd ) { const du = nd < p ? nd : p; @@ -282,7 +259,6 @@ returns array[n+1][p+1] with basis functions derivatives const span = findSpan( p, u, U ); const nders = calcBasisFunctionDerivatives( span, u, p, du, U ); const Pw = []; - for ( let i = 0; i < P.length; ++ i ) { const point = P[ i ].clone(); @@ -297,7 +273,6 @@ returns array[n+1][p+1] with basis functions derivatives for ( let k = 0; k <= du; ++ k ) { const point = Pw[ span - p ].clone().multiplyScalar( nders[ k ][ 0 ] ); - for ( let j = 1; j <= p; ++ j ) { point.add( Pw[ span - p + j ].clone().multiplyScalar( nders[ k ][ j ] ) ); @@ -317,17 +292,15 @@ returns array[n+1][p+1] with basis functions derivatives return CK; } + /* Calculate "K over I" returns k!/(i!(k-i)!) */ - - function calcKoverI( k, i ) { let nom = 1; - for ( let j = 2; j <= k; ++ j ) { nom *= j; @@ -335,7 +308,6 @@ returns k!/(i!(k-i)!) } let denom = 1; - for ( let j = 2; j <= i; ++ j ) { denom *= j; @@ -351,6 +323,7 @@ returns k!/(i!(k-i)!) return nom / denom; } + /* Calculate derivatives (0-nd) of rational curve. See The NURBS Book, page 127, algorithm A4.2. @@ -358,14 +331,11 @@ Pders : result of function calcBSplineDerivatives returns array with derivatives for rational curve. */ - - function calcRationalCurveDerivatives( Pders ) { const nd = Pders.length; const Aders = []; const wders = []; - for ( let i = 0; i < nd; ++ i ) { const point = Pders[ i ]; @@ -375,11 +345,9 @@ returns array with derivatives for rational curve. } const CK = []; - for ( let k = 0; k < nd; ++ k ) { const v = Aders[ k ].clone(); - for ( let i = 1; i <= k; ++ i ) { v.sub( CK[ k - i ].clone().multiplyScalar( calcKoverI( k, i ) * wders[ i ] ) ); @@ -393,6 +361,7 @@ returns array with derivatives for rational curve. return CK; } + /* Calculate NURBS curve derivatives. See The NURBS Book, page 127, algorithm A4.2. @@ -404,14 +373,13 @@ nd : number of derivatives returns array with derivatives. */ - - function calcNURBSDerivatives( p, U, P, u, nd ) { const Pders = calcBSplineDerivatives( p, U, P, u, nd ); return calcRationalCurveDerivatives( Pders ); } + /* Calculate rational B-Spline surface point. See The NURBS Book, page 134, algorithm A4.3. @@ -422,8 +390,6 @@ u, v : parametric values returns point for given (u, v) */ - - function calcSurfacePoint( p, q, U, V, P, u, v, target ) { const uspan = findSpan( p, u, U ); @@ -431,11 +397,9 @@ returns point for given (u, v) const Nu = calcBasisFunctions( uspan, u, p, U ); const Nv = calcBasisFunctions( vspan, v, q, V ); const temp = []; - for ( let l = 0; l <= q; ++ l ) { temp[ l ] = new THREE.Vector4( 0, 0, 0, 0 ); - for ( let k = 0; k <= p; ++ k ) { const point = P[ uspan - p + k ][ vspan - q + l ].clone(); @@ -450,7 +414,6 @@ returns point for given (u, v) } const Sw = new THREE.Vector4( 0, 0, 0, 0 ); - for ( let l = 0; l <= q; ++ l ) { Sw.add( temp[ l ].multiplyScalar( Nv[ l ] ) ); diff --git a/examples/js/effects/AnaglyphEffect.js b/examples/js/effects/AnaglyphEffect.js index be737968f8ccee..4af3631e2f6f9a 100644 --- a/examples/js/effects/AnaglyphEffect.js +++ b/examples/js/effects/AnaglyphEffect.js @@ -5,25 +5,19 @@ constructor( renderer, width = 512, height = 512 ) { // Dubois matrices from https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.7.6968&rep=rep1&type=pdf#page=4 + this.colorMatrixLeft = new THREE.Matrix3().fromArray( [ 0.456100, - 0.0400822, - 0.0152161, 0.500484, - 0.0378246, - 0.0205971, 0.176381, - 0.0157589, - 0.00546856 ] ); this.colorMatrixRight = new THREE.Matrix3().fromArray( [ - 0.0434706, 0.378476, - 0.0721527, - 0.0879388, 0.73364, - 0.112961, - 0.00155529, - 0.0184503, 1.2264 ] ); - const _camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); - const _scene = new THREE.Scene(); - const _stereo = new THREE.StereoCamera(); - const _params = { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat }; - const _renderTargetL = new THREE.WebGLRenderTarget( width, height, _params ); - const _renderTargetR = new THREE.WebGLRenderTarget( width, height, _params ); - const _material = new THREE.ShaderMaterial( { uniforms: { 'mapLeft': { @@ -40,21 +34,18 @@ } }, vertexShader: [ 'varying vec2 vUv;', 'void main() {', ' vUv = vec2( uv.x, uv.y );', ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ), - fragmentShader: [ 'uniform sampler2D mapLeft;', 'uniform sampler2D mapRight;', 'varying vec2 vUv;', 'uniform mat3 colorMatrixLeft;', 'uniform mat3 colorMatrixRight;', // These functions implement sRGB linearization and gamma correction + fragmentShader: [ 'uniform sampler2D mapLeft;', 'uniform sampler2D mapRight;', 'varying vec2 vUv;', 'uniform mat3 colorMatrixLeft;', 'uniform mat3 colorMatrixRight;', + // These functions implement sRGB linearization and gamma correction + 'float lin( float c ) {', ' return c <= 0.04045 ? c * 0.0773993808 :', ' pow( c * 0.9478672986 + 0.0521327014, 2.4 );', '}', 'vec4 lin( vec4 c ) {', ' return vec4( lin( c.r ), lin( c.g ), lin( c.b ), c.a );', '}', 'float dev( float c ) {', ' return c <= 0.0031308 ? c * 12.92', ' : pow( c, 0.41666 ) * 1.055 - 0.055;', '}', 'void main() {', ' vec2 uv = vUv;', ' vec4 colorL = lin( texture2D( mapLeft, uv ) );', ' vec4 colorR = lin( texture2D( mapRight, uv ) );', ' vec3 color = clamp(', ' colorMatrixLeft * colorL.rgb +', ' colorMatrixRight * colorR.rgb, 0., 1. );', ' gl_FragColor = vec4(', ' dev( color.r ), dev( color.g ), dev( color.b ),', ' max( colorL.a, colorR.a ) );', '}' ].join( '\n' ) } ); - const _mesh = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), _material ); - _scene.add( _mesh ); - this.setSize = function ( width, height ) { renderer.setSize( width, height ); const pixelRatio = renderer.getPixelRatio(); - _renderTargetL.setSize( width * pixelRatio, height * pixelRatio ); - _renderTargetR.setSize( width * pixelRatio, height * pixelRatio ); }; @@ -62,11 +53,9 @@ this.render = function ( scene, camera ) { const currentRenderTarget = renderer.getRenderTarget(); - scene.updateMatrixWorld(); - if ( camera.parent === null ) camera.updateMatrixWorld(); - + if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld(); + if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld(); _stereo.update( camera ); - renderer.setRenderTarget( _renderTargetL ); renderer.clear(); renderer.render( scene, _stereo.cameraL ); @@ -82,11 +71,8 @@ this.dispose = function () { _renderTargetL.dispose(); - _renderTargetR.dispose(); - _mesh.geometry.dispose(); - _mesh.material.dispose(); }; diff --git a/examples/js/effects/AsciiEffect.js b/examples/js/effects/AsciiEffect.js index ecd24e03f5650e..c2ac817e278ad7 100644 --- a/examples/js/effects/AsciiEffect.js +++ b/examples/js/effects/AsciiEffect.js @@ -5,6 +5,7 @@ * * 16 April 2012 - @blurspline */ + class AsciiEffect { constructor( renderer, charSet = ' .:-=+*#%@', options = {} ) { @@ -12,18 +13,15 @@ // ' .,:;=|iI+hHOE#`$'; // darker bolder character set from https://github.com/saw/Canvas-ASCII-Art/ // ' .\'`^",:;Il!i~+_-?][}{1)(|/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$'.split(''); + // Some ASCII settings - const fResolution = options[ 'resolution' ] || 0.15; // Higher for more details + const fResolution = options[ 'resolution' ] || 0.15; // Higher for more details const iScale = options[ 'scale' ] || 1; const bColor = options[ 'color' ] || false; // nice but slows down rendering! - const bAlpha = options[ 'alpha' ] || false; // Transparency - const bBlock = options[ 'block' ] || false; // blocked characters. like good O dos - const bInvert = options[ 'invert' ] || false; // black is white, white is black - const strResolution = options[ 'strResolution' ] || 'low'; let width, height; const domElement = document.createElement( 'div' ); @@ -32,7 +30,6 @@ domElement.appendChild( oAscii ); let iWidth, iHeight; let oImg; - this.setSize = function ( w, h ) { width = w; @@ -49,19 +46,21 @@ }; - this.domElement = domElement; // Throw in ascii library from https://github.com/hassadee/jsascii/blob/master/jsascii.js (MIT License) + this.domElement = domElement; + + // Throw in ascii library from https://github.com/hassadee/jsascii/blob/master/jsascii.js (MIT License) function initAsciiSize() { iWidth = Math.round( width * fResolution ); iHeight = Math.round( height * fResolution ); oCanvas.width = iWidth; - oCanvas.height = iHeight; // oCanvas.style.display = "none"; + oCanvas.height = iHeight; + // oCanvas.style.display = "none"; // oCanvas.style.width = iWidth; // oCanvas.style.height = iHeight; oImg = renderer.domElement; - if ( oImg.style.backgroundColor ) { oAscii.rows[ 0 ].cells[ 0 ].style.backgroundColor = oImg.style.backgroundColor; @@ -92,7 +91,6 @@ const strFont = 'courier new, monospace'; const oCanvasImg = renderer.domElement; const oCanvas = document.createElement( 'canvas' ); - if ( ! oCanvas.getContext ) { return; @@ -100,7 +98,6 @@ } const oCtx = oCanvas.getContext( '2d' ); - if ( ! oCtx.getImageData ) { return; @@ -108,13 +105,16 @@ } let aCharList = bColor ? aDefaultColorCharList : aDefaultCharList; - if ( charSet ) aCharList = charSet; // Setup dom + if ( charSet ) aCharList = charSet; + + // Setup dom const fFontSize = 2 / fResolution * iScale; - const fLineHeight = 2 / fResolution * iScale; // adjust letter-spacing for all combinations of scale and resolution to get it to fit the image width. + const fLineHeight = 2 / fResolution * iScale; - let fLetterSpacing = 0; + // adjust letter-spacing for all combinations of scale and resolution to get it to fit the image width. + let fLetterSpacing = 0; if ( strResolution == 'low' ) { switch ( iScale ) { @@ -122,16 +122,13 @@ case 1: fLetterSpacing = - 1; break; - case 2: case 3: fLetterSpacing = - 2.1; break; - case 4: fLetterSpacing = - 3.1; break; - case 5: fLetterSpacing = - 4.15; break; @@ -147,15 +144,12 @@ case 1: fLetterSpacing = 0; break; - case 2: fLetterSpacing = - 1; break; - case 3: fLetterSpacing = - 1.04; break; - case 4: case 5: fLetterSpacing = - 2.1; @@ -173,7 +167,6 @@ case 2: fLetterSpacing = 0; break; - case 3: case 4: case 5: @@ -182,17 +175,22 @@ } - } // can't get a span or div to flow like an img element, but a table works? - // convert img element to ascii + } + // can't get a span or div to flow like an img element, but a table works? + + // convert img element to ascii function asciifyImage( oAscii ) { oCtx.clearRect( 0, 0, iWidth, iHeight ); oCtx.drawImage( oCanvasImg, 0, 0, iWidth, iHeight ); - const oImgData = oCtx.getImageData( 0, 0, iWidth, iHeight ).data; // Coloring loop starts now + const oImgData = oCtx.getImageData( 0, 0, iWidth, iHeight ).data; - let strChars = ''; // console.time('rendering'); + // Coloring loop starts now + let strChars = ''; + + // console.time('rendering'); for ( let y = 0; y < iHeight; y += 2 ) { @@ -205,7 +203,8 @@ const iAlpha = oImgData[ iOffset + 3 ]; let iCharIdx; let fBrightness; - fBrightness = ( 0.3 * iRed + 0.59 * iGreen + 0.11 * iBlue ) / 255; // fBrightness = (0.3*iRed + 0.5*iGreen + 0.3*iBlue) / 255; + fBrightness = ( 0.3 * iRed + 0.59 * iGreen + 0.11 * iBlue ) / 255; + // fBrightness = (0.3*iRed + 0.5*iGreen + 0.3*iBlue) / 255; if ( iAlpha == 0 ) { @@ -216,19 +215,18 @@ } iCharIdx = Math.floor( ( 1 - fBrightness ) * ( aCharList.length - 1 ) ); - if ( bInvert ) { iCharIdx = aCharList.length - iCharIdx - 1; - } // good for debugging + } + + // good for debugging //fBrightness = Math.floor(fBrightness * 10); //strThisChar = fBrightness; - let strThisChar = aCharList[ iCharIdx ]; if ( strThisChar === undefined || strThisChar == ' ' ) strThisChar = ' '; - if ( bColor ) { strChars += '' + strThisChar + ''; @@ -245,7 +243,10 @@ } - oAscii.innerHTML = '' + strChars + ''; // console.timeEnd('rendering'); + oAscii.innerHTML = '' + strChars + ''; + + // console.timeEnd('rendering'); + // return oAscii; } diff --git a/examples/js/effects/OutlineEffect.js b/examples/js/effects/OutlineEffect.js index 3d9bdbf89613bc..bfab7f6408b3b4 100644 --- a/examples/js/effects/OutlineEffect.js +++ b/examples/js/effects/OutlineEffect.js @@ -49,7 +49,7 @@ * // How to set outline parameters for each material * material.userData.outlineParameters = { * thickness: 0.01, - * color: [ 0, 0, 0 ] + * color: [ 0, 0, 0 ], * alpha: 0.8, * visible: true, * keepAlive: true @@ -64,21 +64,26 @@ const defaultThickness = parameters.defaultThickness !== undefined ? parameters.defaultThickness : 0.003; const defaultColor = new THREE.Color().fromArray( parameters.defaultColor !== undefined ? parameters.defaultColor : [ 0, 0, 0 ] ); const defaultAlpha = parameters.defaultAlpha !== undefined ? parameters.defaultAlpha : 1.0; - const defaultKeepAlive = parameters.defaultKeepAlive !== undefined ? parameters.defaultKeepAlive : false; // object.material.uuid -> outlineMaterial or + const defaultKeepAlive = parameters.defaultKeepAlive !== undefined ? parameters.defaultKeepAlive : false; + + // object.material.uuid -> outlineMaterial or // object.material[ n ].uuid -> outlineMaterial // save at the outline material creation and release // if it's unused removeThresholdCount frames // unless keepAlive is true. - const cache = {}; - const removeThresholdCount = 60; // outlineMaterial.uuid -> object.material or + const removeThresholdCount = 60; + + // outlineMaterial.uuid -> object.material or // outlineMaterial.uuid -> object.material[ n ] // save before render and release after render. + const originalMaterials = {}; - const originalMaterials = {}; // object.uuid -> originalOnBeforeRender + // object.uuid -> originalOnBeforeRender // save before render and release after render. + const originalOnBeforeRenders = {}; - const originalOnBeforeRenders = {}; //this.cache = cache; // for debug + //this.cache = cache; // for debug const uniformsOutline = { outlineThickness: { @@ -91,12 +96,15 @@ value: defaultAlpha } }; - const vertexShader = [ '#include ', '#include ', '#include ', '#include ', '#include ', '#include ', '#include ', '#include ', 'uniform float outlineThickness;', 'vec4 calculateOutline( vec4 pos, vec3 normal, vec4 skinned ) {', ' float thickness = outlineThickness;', ' const float ratio = 1.0;', // TODO: support outline thickness ratio for each vertex - ' vec4 pos2 = projectionMatrix * modelViewMatrix * vec4( skinned.xyz + normal, 1.0 );', // NOTE: subtract pos2 from pos because THREE.BackSide objectNormal is negative - ' vec4 norm = normalize( pos - pos2 );', ' return pos + norm * thickness * pos.w * ratio;', '}', 'void main() {', ' #include ', ' #include ', ' #include ', ' #include ', ' #include ', ' #include ', ' #include ', ' #include ', ' #include ', ' #include ', ' vec3 outlineNormal = - objectNormal;', // the outline material is always rendered with THREE.BackSide + const vertexShader = [ '#include ', '#include ', '#include ', '#include ', '#include ', '#include ', '#include ', '#include ', 'uniform float outlineThickness;', 'vec4 calculateOutline( vec4 pos, vec3 normal, vec4 skinned ) {', ' float thickness = outlineThickness;', ' const float ratio = 1.0;', + // TODO: support outline thickness ratio for each vertex + ' vec4 pos2 = projectionMatrix * modelViewMatrix * vec4( skinned.xyz + normal, 1.0 );', + // NOTE: subtract pos2 from pos because THREE.BackSide objectNormal is negative + ' vec4 norm = normalize( pos - pos2 );', ' return pos + norm * thickness * pos.w * ratio;', '}', 'void main() {', ' #include ', ' #include ', ' #include ', ' #include ', ' #include ', ' #include ', ' #include ', ' #include ', ' #include ', ' #include ', ' vec3 outlineNormal = - objectNormal;', + // the outline material is always rendered with THREE.BackSide + ' gl_Position = calculateOutline( gl_Position, outlineNormal, vec4( transformed, 1.0 ) );', ' #include ', ' #include ', ' #include ', '}' ].join( '\n' ); const fragmentShader = [ '#include ', '#include ', '#include ', '#include ', 'uniform vec3 outlineColor;', 'uniform float outlineAlpha;', 'void main() {', ' #include ', ' #include ', ' gl_FragColor = vec4( outlineColor, outlineAlpha );', ' #include ', ' #include ', ' #include ', ' #include ', '}' ].join( '\n' ); - function createMaterial() { return new THREE.ShaderMaterial( { @@ -112,7 +120,6 @@ function getOutlineMaterialFromCache( originalMaterial ) { let data = cache[ originalMaterial.uuid ]; - if ( data === undefined ) { data = { @@ -143,7 +150,6 @@ const geometry = object.geometry; let hasNormals = false; - if ( object.geometry !== undefined ) { if ( geometry.isBufferGeometry ) { @@ -165,7 +171,6 @@ function setOutlineMaterial( object ) { if ( isCompatible( object ) === false ) return; - if ( Array.isArray( object.material ) ) { for ( let i = 0, il = object.material.length; i < il; i ++ ) { @@ -188,7 +193,6 @@ function restoreOriginalMaterial( object ) { if ( isCompatible( object ) === false ) return; - if ( Array.isArray( object.material ) ) { for ( let i = 0, il = object.material.length; i < il; i ++ ) { @@ -209,8 +213,9 @@ function onBeforeRender( renderer, scene, camera, geometry, material ) { - const originalMaterial = originalMaterials[ material.uuid ]; // just in case + const originalMaterial = originalMaterials[ material.uuid ]; + // just in case if ( originalMaterial === undefined ) return; updateUniforms( material, originalMaterial ); @@ -220,7 +225,6 @@ const outlineParameters = originalMaterial.userData.outlineParameters; material.uniforms.outlineAlpha.value = originalMaterial.opacity; - if ( outlineParameters !== undefined ) { if ( outlineParameters.thickness !== undefined ) material.uniforms.outlineThickness.value = outlineParameters.thickness; @@ -247,7 +251,6 @@ material.toneMapped = originalMaterial.toneMapped; material.premultipliedAlpha = originalMaterial.premultipliedAlpha; material.displacementMap = originalMaterial.displacementMap; - if ( outlineParameters !== undefined ) { if ( originalMaterial.visible === false ) { @@ -271,7 +274,6 @@ } if ( originalMaterial.wireframe === true || originalMaterial.depthTest === false ) material.visible = false; - if ( originalMaterial.clippingPlanes ) { material.clipping = true; @@ -287,36 +289,32 @@ function cleanupCache() { - let keys; // clear originialMaterials + let keys; + // clear originialMaterials keys = Object.keys( originalMaterials ); - for ( let i = 0, il = keys.length; i < il; i ++ ) { originalMaterials[ keys[ i ] ] = undefined; - } // clear originalOnBeforeRenders - + } + // clear originalOnBeforeRenders keys = Object.keys( originalOnBeforeRenders ); - for ( let i = 0, il = keys.length; i < il; i ++ ) { originalOnBeforeRenders[ keys[ i ] ] = undefined; - } // remove unused outlineMaterial from cache - + } + // remove unused outlineMaterial from cache keys = Object.keys( cache ); - for ( let i = 0, il = keys.length; i < il; i ++ ) { const key = keys[ i ]; - if ( cache[ key ].used === false ) { cache[ key ].count ++; - if ( cache[ key ].keepAlive === false && cache[ key ].count > removeThresholdCount ) { delete cache[ key ]; @@ -336,26 +334,6 @@ this.render = function ( scene, camera ) { - let renderTarget; - let forceClear = false; - - if ( arguments[ 2 ] !== undefined ) { - - console.warn( 'THREE.OutlineEffect.render(): the renderTarget argument has been removed. Use .setRenderTarget() instead.' ); - renderTarget = arguments[ 2 ]; - - } - - if ( arguments[ 3 ] !== undefined ) { - - console.warn( 'THREE.OutlineEffect.render(): the forceClear argument has been removed. Use .clear() instead.' ); - forceClear = arguments[ 3 ]; - - } - - if ( renderTarget !== undefined ) renderer.setRenderTarget( renderTarget ); - if ( forceClear ) renderer.clear(); - if ( this.enabled === false ) { renderer.render( scene, camera ); @@ -374,10 +352,10 @@ this.renderOutline = function ( scene, camera ) { const currentAutoClear = renderer.autoClear; - const currentSceneAutoUpdate = scene.autoUpdate; + const currentSceneAutoUpdate = scene.matrixWorldAutoUpdate; const currentSceneBackground = scene.background; const currentShadowMapEnabled = renderer.shadowMap.enabled; - scene.autoUpdate = false; + scene.matrixWorldAutoUpdate = false; scene.background = null; renderer.autoClear = false; renderer.shadowMap.enabled = false; @@ -385,12 +363,13 @@ renderer.render( scene, camera ); scene.traverse( restoreOriginalMaterial ); cleanupCache(); - scene.autoUpdate = currentSceneAutoUpdate; + scene.matrixWorldAutoUpdate = currentSceneAutoUpdate; scene.background = currentSceneBackground; renderer.autoClear = currentAutoClear; renderer.shadowMap.enabled = currentShadowMapEnabled; }; + /* * See #9918 * @@ -405,12 +384,9 @@ * * } */ - - this.autoClear = renderer.autoClear; this.domElement = renderer.domElement; this.shadowMap = renderer.shadowMap; - this.clear = function ( color, depth, stencil ) { renderer.clear( color, depth, stencil ); diff --git a/examples/js/effects/ParallaxBarrierEffect.js b/examples/js/effects/ParallaxBarrierEffect.js index 409ea922573e41..1d6d0b5bfa6451 100644 --- a/examples/js/effects/ParallaxBarrierEffect.js +++ b/examples/js/effects/ParallaxBarrierEffect.js @@ -5,21 +5,15 @@ constructor( renderer ) { const _camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); - const _scene = new THREE.Scene(); - const _stereo = new THREE.StereoCamera(); - const _params = { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat }; - const _renderTargetL = new THREE.WebGLRenderTarget( 512, 512, _params ); - const _renderTargetR = new THREE.WebGLRenderTarget( 512, 512, _params ); - const _material = new THREE.ShaderMaterial( { uniforms: { 'mapLeft': { @@ -32,29 +26,22 @@ vertexShader: [ 'varying vec2 vUv;', 'void main() {', ' vUv = vec2( uv.x, uv.y );', ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ), fragmentShader: [ 'uniform sampler2D mapLeft;', 'uniform sampler2D mapRight;', 'varying vec2 vUv;', 'void main() {', ' vec2 uv = vUv;', ' if ( ( mod( gl_FragCoord.y, 2.0 ) ) > 1.00 ) {', ' gl_FragColor = texture2D( mapLeft, uv );', ' } else {', ' gl_FragColor = texture2D( mapRight, uv );', ' }', '}' ].join( '\n' ) } ); - const mesh = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), _material ); - _scene.add( mesh ); - this.setSize = function ( width, height ) { renderer.setSize( width, height ); const pixelRatio = renderer.getPixelRatio(); - _renderTargetL.setSize( width * pixelRatio, height * pixelRatio ); - _renderTargetR.setSize( width * pixelRatio, height * pixelRatio ); }; this.render = function ( scene, camera ) { - scene.updateMatrixWorld(); - if ( camera.parent === null ) camera.updateMatrixWorld(); - + if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld(); + if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld(); _stereo.update( camera ); - renderer.setRenderTarget( _renderTargetL ); renderer.clear(); renderer.render( scene, _stereo.cameraL ); diff --git a/examples/js/effects/PeppersGhostEffect.js b/examples/js/effects/PeppersGhostEffect.js index b7ca0567e4c311..905f0fd080391c 100644 --- a/examples/js/effects/PeppersGhostEffect.js +++ b/examples/js/effects/PeppersGhostEffect.js @@ -10,35 +10,24 @@ const scope = this; scope.cameraDistance = 15; - scope.reflectFromAbove = false; // Internals + scope.reflectFromAbove = false; + // Internals let _halfWidth, _width, _height; - const _cameraF = new THREE.PerspectiveCamera(); //front - - const _cameraB = new THREE.PerspectiveCamera(); //back - - const _cameraL = new THREE.PerspectiveCamera(); //left - - const _cameraR = new THREE.PerspectiveCamera(); //right - const _position = new THREE.Vector3(); - const _quaternion = new THREE.Quaternion(); + const _scale = new THREE.Vector3(); - const _scale = new THREE.Vector3(); // Initialization - - + // Initialization renderer.autoClear = false; - this.setSize = function ( width, height ) { _halfWidth = width / 2; - if ( width < height ) { _width = width / 3; @@ -57,53 +46,40 @@ this.render = function ( scene, camera ) { - scene.updateMatrixWorld(); - if ( camera.parent === null ) camera.updateMatrixWorld(); - camera.matrixWorld.decompose( _position, _quaternion, _scale ); // front + if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld(); + if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld(); + camera.matrixWorld.decompose( _position, _quaternion, _scale ); + // front _cameraF.position.copy( _position ); - _cameraF.quaternion.copy( _quaternion ); - _cameraF.translateZ( scope.cameraDistance ); + _cameraF.lookAt( scene.position ); - _cameraF.lookAt( scene.position ); // back - - + // back _cameraB.position.copy( _position ); - _cameraB.quaternion.copy( _quaternion ); - _cameraB.translateZ( - scope.cameraDistance ); - _cameraB.lookAt( scene.position ); + _cameraB.rotation.z += 180 * ( Math.PI / 180 ); - _cameraB.rotation.z += 180 * ( Math.PI / 180 ); // left - + // left _cameraL.position.copy( _position ); - _cameraL.quaternion.copy( _quaternion ); - _cameraL.translateX( - scope.cameraDistance ); - _cameraL.lookAt( scene.position ); + _cameraL.rotation.x += 90 * ( Math.PI / 180 ); - _cameraL.rotation.x += 90 * ( Math.PI / 180 ); // right - + // right _cameraR.position.copy( _position ); - _cameraR.quaternion.copy( _quaternion ); - _cameraR.translateX( scope.cameraDistance ); - _cameraR.lookAt( scene.position ); - _cameraR.rotation.x += 90 * ( Math.PI / 180 ); renderer.clear(); renderer.setScissorTest( true ); renderer.setScissor( _halfWidth - _width / 2, _height * 2, _width, _height ); renderer.setViewport( _halfWidth - _width / 2, _height * 2, _width, _height ); - if ( scope.reflectFromAbove ) { renderer.render( scene, _cameraB ); @@ -116,7 +92,6 @@ renderer.setScissor( _halfWidth - _width / 2, 0, _width, _height ); renderer.setViewport( _halfWidth - _width / 2, 0, _width, _height ); - if ( scope.reflectFromAbove ) { renderer.render( scene, _cameraF ); @@ -129,7 +104,6 @@ renderer.setScissor( _halfWidth - _width / 2 - _width, _height, _width, _height ); renderer.setViewport( _halfWidth - _width / 2 - _width, _height, _width, _height ); - if ( scope.reflectFromAbove ) { renderer.render( scene, _cameraR ); @@ -142,7 +116,6 @@ renderer.setScissor( _halfWidth + _width / 2, _height, _width, _height ); renderer.setViewport( _halfWidth + _width / 2, _height, _width, _height ); - if ( scope.reflectFromAbove ) { renderer.render( scene, _cameraL ); diff --git a/examples/js/effects/StereoEffect.js b/examples/js/effects/StereoEffect.js index 8a7a0944affed9..22bf1ae3a08439 100644 --- a/examples/js/effects/StereoEffect.js +++ b/examples/js/effects/StereoEffect.js @@ -5,10 +5,8 @@ constructor( renderer ) { const _stereo = new THREE.StereoCamera(); - _stereo.aspect = 0.5; const size = new THREE.Vector2(); - this.setEyeSeparation = function ( eyeSep ) { _stereo.eyeSep = eyeSep; @@ -23,11 +21,9 @@ this.render = function ( scene, camera ) { - scene.updateMatrixWorld(); - if ( camera.parent === null ) camera.updateMatrixWorld(); - + if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld(); + if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld(); _stereo.update( camera ); - renderer.getSize( size ); if ( renderer.autoClear ) renderer.clear(); renderer.setScissorTest( true ); diff --git a/examples/js/environments/RoomEnvironment.js b/examples/js/environments/RoomEnvironment.js index f698528f84338e..baa03acfa9141a 100644 --- a/examples/js/environments/RoomEnvironment.js +++ b/examples/js/environments/RoomEnvironment.js @@ -3,7 +3,6 @@ /** * https://github.com/google/model-viewer/blob/master/packages/model-viewer/src/three-components/EnvironmentScene.ts */ - class RoomEnvironment extends THREE.Scene { constructor() { @@ -51,42 +50,67 @@ box6.position.set( - 2.193, - 0.369, - 5.547 ); box6.rotation.set( 0, 0.516, 0 ); box6.scale.set( 3.875, 3.487, 2.986 ); - this.add( box6 ); // -x right + this.add( box6 ); + // -x right const light1 = new THREE.Mesh( geometry, createAreaLightMaterial( 50 ) ); light1.position.set( - 16.116, 14.37, 8.208 ); light1.scale.set( 0.1, 2.428, 2.739 ); - this.add( light1 ); // -x left + this.add( light1 ); + // -x left const light2 = new THREE.Mesh( geometry, createAreaLightMaterial( 50 ) ); light2.position.set( - 16.109, 18.021, - 8.207 ); light2.scale.set( 0.1, 2.425, 2.751 ); - this.add( light2 ); // +x + this.add( light2 ); + // +x const light3 = new THREE.Mesh( geometry, createAreaLightMaterial( 17 ) ); light3.position.set( 14.904, 12.198, - 1.832 ); light3.scale.set( 0.15, 4.265, 6.331 ); - this.add( light3 ); // +z + this.add( light3 ); + // +z const light4 = new THREE.Mesh( geometry, createAreaLightMaterial( 43 ) ); light4.position.set( - 0.462, 8.89, 14.520 ); light4.scale.set( 4.38, 5.441, 0.088 ); - this.add( light4 ); // -z + this.add( light4 ); + // -z const light5 = new THREE.Mesh( geometry, createAreaLightMaterial( 20 ) ); light5.position.set( 3.235, 11.486, - 12.541 ); light5.scale.set( 2.5, 2.0, 0.1 ); - this.add( light5 ); // +y + this.add( light5 ); + // +y const light6 = new THREE.Mesh( geometry, createAreaLightMaterial( 100 ) ); light6.position.set( 0.0, 20.0, 0.0 ); light6.scale.set( 1.0, 0.1, 1.0 ); this.add( light6 ); } + dispose() { - } + const resources = new Set(); + this.traverse( object => { + + if ( object.isMesh ) { + + resources.add( object.geometry ); + resources.add( object.material ); + + } + + } ); + for ( const resource of resources ) { + + resource.dispose(); + + } + } + + } function createAreaLightMaterial( intensity ) { const material = new THREE.MeshBasicMaterial(); diff --git a/examples/js/exporters/ColladaExporter.js b/examples/js/exporters/ColladaExporter.js index 6458e8ef07d866..f4e0b3b5b83c60 100644 --- a/examples/js/exporters/ColladaExporter.js +++ b/examples/js/exporters/ColladaExporter.js @@ -24,7 +24,6 @@ unitName: null, unitMeter: null }, options ); - if ( options.upAxis.match( /^[XYZ]_UP$/ ) === null ) { console.error( 'ColladaExporter: Invalid upAxis: valid values are X_UP, Y_UP or Z_UP.' ); @@ -53,23 +52,20 @@ } const version = options.version; - if ( version !== '1.4.1' && version !== '1.5.0' ) { console.warn( `ColladaExporter : Version ${version} not supported for export. Only 1.4.1 and 1.5.0.` ); return null; - } // Convert the urdf xml into a well-formatted, indented format - + } + // Convert the urdf xml into a well-formatted, indented format function format( urdf ) { const IS_END_TAG = /^<\//; const IS_SELF_CLOSING = /(\?>$)|(\/>$)/; const HAS_TEXT = /<[^>]+>[^<]*<\/[^<]+>/; - const pad = ( ch, num ) => num > 0 ? ch + pad( ch, num - 1 ) : ''; - let tagnum = 0; return urdf.match( /(<[^>]+>[^<]+<\/[^<]+>)|(<[^>]+>)/g ).map( tag => { @@ -80,7 +76,6 @@ } const res = `${pad( ' ', tagnum )}${tag}`; - if ( ! HAS_TEXT.test( tag ) && ! IS_SELF_CLOSING.test( tag ) && ! IS_END_TAG.test( tag ) ) { tagnum ++; @@ -91,14 +86,13 @@ } ).join( '\n' ); - } // Convert an image into a png format for saving - + } + // Convert an image into a png format for saving function base64ToBuffer( str ) { const b = atob( str ); const buf = new Uint8Array( b.length ); - for ( let i = 0, l = buf.length; i < l; i ++ ) { buf[ i ] = b.charCodeAt( i ); @@ -110,25 +104,25 @@ } let canvas, ctx; - function imageToData( image, ext ) { canvas = canvas || document.createElement( 'canvas' ); ctx = ctx || canvas.getContext( '2d' ); canvas.width = image.width; canvas.height = image.height; - ctx.drawImage( image, 0, 0 ); // Get the base64 encoded data + ctx.drawImage( image, 0, 0 ); - const base64data = canvas.toDataURL( `image/${ext}`, 1 ).replace( /^data:image\/(png|jpg);base64,/, '' ); // Convert to a uint8 array + // Get the base64 encoded data + const base64data = canvas.toDataURL( `image/${ext}`, 1 ).replace( /^data:image\/(png|jpg);base64,/, '' ); + // Convert to a uint8 array return base64ToBuffer( base64data ); - } // gets the attribute array. Generate a new array if the attribute is interleaved - + } + // gets the attribute array. Generate a new array if the attribute is interleaved const getFuncs = [ 'getX', 'getY', 'getZ', 'getW' ]; const tempColor = new THREE.Color(); - function attrBufferToArray( attr, isColor = false ) { if ( isColor ) { @@ -136,7 +130,6 @@ // convert the colors to srgb before export // colors are always written as floats const arr = new Float32Array( attr.count * 3 ); - for ( let i = 0, l = attr.count; i < l; i ++ ) { tempColor.fromBufferAttribute( attr, i ).convertLinearToSRGB(); @@ -153,7 +146,6 @@ // use the typed array constructor to save on memory const arr = new attr.array.constructor( attr.count * attr.itemSize ); const size = attr.itemSize; - for ( let i = 0, l = attr.count; i < l; i ++ ) { for ( let j = 0; j < size; j ++ ) { @@ -172,28 +164,27 @@ } - } // Returns an array of the same type starting at the `st` index, - // and `ct` length - + } + // Returns an array of the same type starting at the `st` index, + // and `ct` length function subArray( arr, st, ct ) { if ( Array.isArray( arr ) ) return arr.slice( st, st + ct ); else return new arr.constructor( arr.buffer, st * arr.BYTES_PER_ELEMENT, ct ); - } // Returns the string for a geometry's attribute - + } + // Returns the string for a geometry's attribute function getAttribute( attr, name, params, type, isColor = false ) { const array = attrBufferToArray( attr, isColor ); const res = `` + `` + array.join( ' ' ) + '' + '' + `` + params.map( n => `` ).join( '' ) + '' + '' + ''; return res; - } // Returns the string for a node's transform information - + } + // Returns the string for a node's transform information let transMat; - function getTransform( o ) { // ensure the object's matrix is up to date @@ -204,25 +195,15 @@ transMat.transpose(); return `${transMat.toArray().join( ' ' )}`; - } // Process the given piece of geometry into the geometry library - // Returns the mesh id - - - function processGeometry( g ) { + } - let info = geometryInfo.get( g ); + // Process the given piece of geometry into the geometry library + // Returns the mesh id + function processGeometry( bufferGeometry ) { + let info = geometryInfo.get( bufferGeometry ); if ( ! info ) { - // convert the geometry to bufferGeometry if it isn't already - const bufferGeometry = g; - - if ( bufferGeometry.isBufferGeometry !== true ) { - - throw new Error( 'THREE.ColladaExporter: Geometry is not of type THREE.BufferGeometry.' ); - - } - const meshid = `Mesh${libraryGeometries.length + 1}`; const indexCount = bufferGeometry.index ? bufferGeometry.index.count * bufferGeometry.index.itemSize : bufferGeometry.attributes.position.count; const groups = bufferGeometry.groups != null && bufferGeometry.groups.length !== 0 ? bufferGeometry.groups : [ { @@ -230,47 +211,49 @@ count: indexCount, materialIndex: 0 } ]; - const gname = g.name ? ` name="${g.name}"` : ''; - let gnode = ``; // define the geometry node and the vertices for the geometry + const gname = bufferGeometry.name ? ` name="${bufferGeometry.name}"` : ''; + let gnode = ``; + // define the geometry node and the vertices for the geometry const posName = `${meshid}-position`; const vertName = `${meshid}-vertices`; gnode += getAttribute( bufferGeometry.attributes.position, posName, [ 'X', 'Y', 'Z' ], 'float' ); - gnode += ``; // NOTE: We're not optimizing the attribute arrays here, so they're all the same length and + gnode += ``; + + // NOTE: We're not optimizing the attribute arrays here, so they're all the same length and // can therefore share the same triangle indices. However, MeshLab seems to have trouble opening // models with attributes that share an offset. // MeshLab Bug#424: https://sourceforge.net/p/meshlab/bugs/424/ - // serialize normals + // serialize normals let triangleInputs = ``; - if ( 'normal' in bufferGeometry.attributes ) { const normName = `${meshid}-normal`; gnode += getAttribute( bufferGeometry.attributes.normal, normName, [ 'X', 'Y', 'Z' ], 'float' ); triangleInputs += ``; - } // serialize uvs - + } + // serialize uvs if ( 'uv' in bufferGeometry.attributes ) { const uvName = `${meshid}-texcoord`; gnode += getAttribute( bufferGeometry.attributes.uv, uvName, [ 'S', 'T' ], 'float' ); triangleInputs += ``; - } // serialize lightmap uvs - + } + // serialize lightmap uvs if ( 'uv2' in bufferGeometry.attributes ) { const uvName = `${meshid}-texcoord2`; gnode += getAttribute( bufferGeometry.attributes.uv2, uvName, [ 'S', 'T' ], 'float' ); triangleInputs += ``; - } // serialize colors - + } + // serialize colors if ( 'color' in bufferGeometry.attributes ) { // colors are always written as floats @@ -281,7 +264,6 @@ } let indexArray = null; - if ( bufferGeometry.index ) { indexArray = attrBufferToArray( bufferGeometry.index ); @@ -289,7 +271,6 @@ } else { indexArray = new Array( indexCount ); - for ( let i = 0, l = indexArray.length; i < l; i ++ ) indexArray[ i ] = i; } @@ -312,27 +293,25 @@ meshid: meshid, bufferGeometry: bufferGeometry }; - geometryInfo.set( g, info ); + geometryInfo.set( bufferGeometry, info ); } return info; - } // Process the given texture into the image library - // Returns the image library - + } + // Process the given texture into the image library + // Returns the image library function processTexture( tex ) { let texid = imageMap.get( tex ); - if ( texid == null ) { texid = `image-${libraryImages.length + 1}`; const ext = 'png'; const name = tex.name || texid; let imageNode = ``; - if ( version === '1.5.0' ) { imageNode += `${options.textureDirectory}${name}.${ext}`; @@ -359,19 +338,17 @@ return texid; - } // Process the given material into the material and effect libraries - // Returns the material id - + } + // Process the given material into the material and effect libraries + // Returns the material id function processMaterial( m ) { let matid = materialMap.get( m ); - if ( matid == null ) { matid = `Mat${libraryEffects.length + 1}`; let type = 'phong'; - if ( m.isMeshLambertMaterial === true ) { type = 'lambert'; @@ -379,7 +356,6 @@ } else if ( m.isMeshBasicMaterial === true ) { type = 'constant'; - if ( m.map !== null ) { // The Collada spec does not support diffuse texture maps with the @@ -398,16 +374,15 @@ const reflectivity = m.reflectivity || 0; emissive.convertLinearToSRGB(); specular.convertLinearToSRGB(); - diffuse.convertLinearToSRGB(); // Do not export and alpha map for the reasons mentioned in issue (#13792) + diffuse.convertLinearToSRGB(); + + // Do not export and alpha map for the reasons mentioned in issue (#13792) // in three.js alpha maps are black and white, but collada expects the alpha // channel to specify the transparency - let transparencyNode = ''; - if ( m.transparent === true ) { transparencyNode += '' + ( m.map ? '' : '1' ) + ''; - if ( m.opacity < 1 ) { transparencyNode += `${m.opacity}`; @@ -428,30 +403,30 @@ return matid; - } // Recursively process the object into a scene - + } + // Recursively process the object into a scene function processObject( o ) { let node = ``; node += getTransform( o ); - if ( o.isMesh === true && o.geometry !== null ) { // function returns the id associated with the mesh and a "BufferGeometry" version // of the geometry in case it's not a geometry. const geomInfo = processGeometry( o.geometry ); const meshid = geomInfo.meshid; - const geometry = geomInfo.bufferGeometry; // ids of the materials to bind to the geometry + const geometry = geomInfo.bufferGeometry; + // ids of the materials to bind to the geometry let matids = null; - let matidsArray; // get a list of materials to bind to the sub groups of the geometry. + let matidsArray; + + // get a list of materials to bind to the sub groups of the geometry. // If the amount of subgroups is greater than the materials, than reuse // the materials. - const mat = o.material || new THREE.MeshBasicMaterial(); const materials = Array.isArray( mat ) ? mat : [ mat ]; - if ( geometry.groups.length > materials.length ) { matidsArray = new Array( geometry.groups.length ); @@ -495,7 +470,6 @@ data: format( dae ), textures }; - if ( typeof onDone === 'function' ) { requestAnimationFrame( () => onDone( res ) ); diff --git a/examples/js/exporters/DRACOExporter.js b/examples/js/exporters/DRACOExporter.js index 3f71a8bbb8fef1..73574e283b6be7 100644 --- a/examples/js/exporters/DRACOExporter.js +++ b/examples/js/exporters/DRACOExporter.js @@ -15,6 +15,7 @@ */ /* global DracoEncoderModule */ + class DRACOExporter { parse( object, options = { @@ -27,12 +28,6 @@ exportColor: false } ) { - if ( object.isBufferGeometry === true ) { - - throw new Error( 'DRACOExporter: The first parameter of parse() is now an instance of Mesh or Points.' ); - - } - if ( DracoEncoderModule === undefined ) { throw new Error( 'THREE.DRACOExporter: required the draco_encoder to work.' ); @@ -44,13 +39,6 @@ const encoder = new dracoEncoder.Encoder(); let builder; let dracoObject; - - if ( geometry.isBufferGeometry !== true ) { - - throw new Error( 'THREE.DRACOExporter.parse(geometry, options): geometry is not a THREE.BufferGeometry instance.' ); - - } - if ( object.isMesh === true ) { builder = new dracoEncoder.MeshBuilder(); @@ -58,7 +46,6 @@ const vertices = geometry.getAttribute( 'position' ); builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.POSITION, vertices.count, vertices.itemSize, vertices.array ); const faces = geometry.getIndex(); - if ( faces !== null ) { builder.AddFacesToMesh( dracoObject, faces.count / 3, faces.array ); @@ -66,7 +53,6 @@ } else { const faces = new ( vertices.count > 65535 ? Uint32Array : Uint16Array )( vertices.count ); - for ( let i = 0; i < faces.length; i ++ ) { faces[ i ] = i; @@ -80,7 +66,6 @@ if ( options.exportNormals === true ) { const normals = geometry.getAttribute( 'normal' ); - if ( normals !== undefined ) { builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.NORMAL, normals.count, normals.itemSize, normals.array ); @@ -92,7 +77,6 @@ if ( options.exportUvs === true ) { const uvs = geometry.getAttribute( 'uv' ); - if ( uvs !== undefined ) { builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.TEX_COORD, uvs.count, uvs.itemSize, uvs.array ); @@ -104,7 +88,6 @@ if ( options.exportColor === true ) { const colors = geometry.getAttribute( 'color' ); - if ( colors !== undefined ) { builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.COLOR, colors.count, colors.itemSize, colors.array ); @@ -119,11 +102,9 @@ dracoObject = new dracoEncoder.PointCloud(); const vertices = geometry.getAttribute( 'position' ); builder.AddFloatAttribute( dracoObject, dracoEncoder.POSITION, vertices.count, vertices.itemSize, vertices.array ); - if ( options.exportColor === true ) { const colors = geometry.getAttribute( 'color' ); - if ( colors !== undefined ) { builder.AddFloatAttribute( dracoObject, dracoEncoder.COLOR, colors.count, colors.itemSize, colors.array ); @@ -136,23 +117,28 @@ throw new Error( 'DRACOExporter: Unsupported object type.' ); - } //Compress using draco encoder + } + + //Compress using draco encoder + const encodedData = new dracoEncoder.DracoInt8Array(); - const encodedData = new dracoEncoder.DracoInt8Array(); //Sets the desired encoding and decoding speed for the given options from 0 (slowest speed, but the best compression) to 10 (fastest, but the worst compression). + //Sets the desired encoding and decoding speed for the given options from 0 (slowest speed, but the best compression) to 10 (fastest, but the worst compression). const encodeSpeed = options.encodeSpeed !== undefined ? options.encodeSpeed : 5; const decodeSpeed = options.decodeSpeed !== undefined ? options.decodeSpeed : 5; - encoder.SetSpeedOptions( encodeSpeed, decodeSpeed ); // Sets the desired encoding method for a given geometry. + encoder.SetSpeedOptions( encodeSpeed, decodeSpeed ); + + // Sets the desired encoding method for a given geometry. if ( options.encoderMethod !== undefined ) { encoder.SetEncodingMethod( options.encoderMethod ); - } // Sets the quantization (number of bits used to represent) compression options for a named attribute. - // The attribute values will be quantized in a box defined by the maximum extent of the attribute values. - + } + // Sets the quantization (number of bits used to represent) compression options for a named attribute. + // The attribute values will be quantized in a box defined by the maximum extent of the attribute values. if ( options.quantization !== undefined ) { for ( let i = 0; i < 5; i ++ ) { @@ -168,7 +154,6 @@ } let length; - if ( object.isMesh === true ) { length = encoder.EncodeMeshToDracoBuffer( dracoObject, encodedData ); @@ -180,16 +165,14 @@ } dracoEncoder.destroy( dracoObject ); - if ( length === 0 ) { throw new Error( 'THREE.DRACOExporter: Draco encoding failed.' ); - } //Copy encoded data to buffer. - + } + //Copy encoded data to buffer. const outputData = new Int8Array( new ArrayBuffer( length ) ); - for ( let i = 0; i < length; i ++ ) { outputData[ i ] = encodedData.GetValue( i ); @@ -203,14 +186,19 @@ } - } // Encoder methods + } + // Encoder methods DRACOExporter.MESH_EDGEBREAKER_ENCODING = 1; - DRACOExporter.MESH_SEQUENTIAL_ENCODING = 0; // Geometry type + DRACOExporter.MESH_SEQUENTIAL_ENCODING = 0; + + // Geometry type DRACOExporter.POINT_CLOUD = 0; - DRACOExporter.TRIANGULAR_MESH = 1; // Attribute type + DRACOExporter.TRIANGULAR_MESH = 1; + + // Attribute type DRACOExporter.INVALID = - 1; DRACOExporter.POSITION = 0; diff --git a/examples/js/exporters/EXRExporter.js b/examples/js/exporters/EXRExporter.js index d2153ea33f9a5c..3205ce10e6f375 100644 --- a/examples/js/exporters/EXRExporter.js +++ b/examples/js/exporters/EXRExporter.js @@ -10,7 +10,6 @@ const NO_COMPRESSION = 0; const ZIPS_COMPRESSION = 2; const ZIP_COMPRESSION = 3; - class EXRExporter { parse( renderer, renderTarget, options ) { @@ -25,7 +24,6 @@ } } - function supported( renderer, renderTarget ) { if ( ! renderer || ! renderer.isWebGLRenderer ) { @@ -97,7 +95,6 @@ function getPixelData( renderer, rtt, info ) { let dataBuffer; - if ( info.type === THREE.FloatType ) { dataBuffer = new Float32Array( info.width * info.height * info.numInputChannels ); @@ -131,7 +128,6 @@ setValue = info.dataType == 1 ? setFloat16 : setFloat32, outBuffer = new Uint8Array( info.width * info.height * info.numOutputChannels * info.dataSize ), dv = new DataView( outBuffer.buffer ); - for ( let y = 0; y < h; ++ y ) { for ( let x = 0; x < w; ++ x ) { @@ -170,13 +166,11 @@ totalSize: 0 }, size = info.width * info.numOutputChannels * info.blockLines * info.dataSize; - switch ( info.compression ) { case 0: compress = compressNONE; break; - case 2: case 3: compress = compressZIP; @@ -218,11 +212,11 @@ // // Reorder the pixel data. // + let t1 = 0, t2 = Math.floor( ( data.length + 1 ) / 2 ), s = 0; const stop = data.length - 1; - while ( true ) { if ( s > stop ) break; @@ -230,13 +224,13 @@ if ( s > stop ) break; tmpBuffer[ t2 ++ ] = data[ s ++ ]; - } // + } + + // // Predictor. // - let p = tmpBuffer[ 0 ]; - for ( let t = 1; t < tmpBuffer.length; t ++ ) { const d = tmpBuffer[ t ] - p + ( 128 + 256 ); @@ -264,8 +258,8 @@ }; const dv = new DataView( outBuffer.buffer ); setUint32( dv, 20000630, offset ); // magic - setUint32( dv, 2, offset ); // mask + // = HEADER = setString( dv, 'compression', offset ); @@ -326,12 +320,14 @@ offset.value += 4; setUint32( dv, 1, offset ); setUint32( dv, 1, offset ); - setUint8( dv, 0, offset ); // null-byte + setUint8( dv, 0, offset ); - setUint8( dv, 0, offset ); // = OFFSET TABLE = + // null-byte + setUint8( dv, 0, offset ); - let sum = offset.value + info.numBlocks * 8; + // = OFFSET TABLE = + let sum = offset.value + info.numBlocks * 8; for ( let i = 0; i < chunks.data.length; ++ i ) { setUint64( dv, sum, offset ); @@ -352,7 +348,6 @@ outBuffer = new Uint8Array( HeaderSize + TableSize + chunks.totalSize + info.numBlocks * 8 ), dv = new DataView( outBuffer.buffer ); fillHeader( outBuffer, chunks, info ); - for ( let i = 0; i < chunks.data.length; ++ i ) { const data = chunks.data[ i ].dataChunk; @@ -375,13 +370,16 @@ dec.b = b; dec.a = a; - } // function decodeSRGB( dec, r, g, b, a ) { + } + + // function decodeSRGB( dec, r, g, b, a ) { + // dec.r = r > 0.04045 ? Math.pow( r * 0.9478672986 + 0.0521327014, 2.4 ) : r * 0.0773993808; // dec.g = g > 0.04045 ? Math.pow( g * 0.9478672986 + 0.0521327014, 2.4 ) : g * 0.0773993808; // dec.b = b > 0.04045 ? Math.pow( b * 0.9478672986 + 0.0521327014, 2.4 ) : b * 0.0773993808; // dec.a = a; - // } + // } function setUint8( dv, value, offset ) { @@ -421,7 +419,6 @@ function setString( dv, string, offset ) { const tmp = textEncoder.encode( string + '\0' ); - for ( let i = 0; i < tmp.length; ++ i ) { setUint8( dv, tmp[ i ], offset ); diff --git a/examples/js/exporters/GLTFExporter.js b/examples/js/exporters/GLTFExporter.js index 7b4ec25ff0e42c..79fbcbf4b9dc47 100644 --- a/examples/js/exporters/GLTFExporter.js +++ b/examples/js/exporters/GLTFExporter.js @@ -14,11 +14,6 @@ return new GLTFMaterialsUnlitExtension( writer ); - } ); - this.register( function ( writer ) { - - return new GLTFMaterialsPBRSpecularGlossiness( writer ); - } ); this.register( function ( writer ) { @@ -42,7 +37,6 @@ } ); } - register( callback ) { if ( this.pluginCallbacks.indexOf( callback ) === - 1 ) { @@ -54,7 +48,6 @@ return this; } - unregister( callback ) { if ( this.pluginCallbacks.indexOf( callback ) !== - 1 ) { @@ -66,6 +59,7 @@ return this; } + /** * Parse scenes and generate GLTF output * @param {Scene or [THREE.Scenes]} input THREE.Scene or Array of THREE.Scenes @@ -73,20 +67,10 @@ * @param {Function} onError Callback on errors * @param {Object} options options */ - - parse( input, onDone, onError, options ) { - if ( typeof onError === 'object' ) { - - console.warn( 'THREE.GLTFExporter: parse() expects options as the fourth argument now.' ); - options = onError; - - } - const writer = new GLTFWriter(); const plugins = []; - for ( let i = 0, il = this.pluginCallbacks.length; i < il; i ++ ) { plugins.push( this.pluginCallbacks[ i ]( writer ) ); @@ -97,7 +81,6 @@ writer.write( input, onDone, options ).catch( onError ); } - parseAsync( input, options ) { const scope = this; @@ -109,11 +92,12 @@ } - } //------------------------------------------------------------------------------ + } + + //------------------------------------------------------------------------------ // Constants //------------------------------------------------------------------------------ - const WEBGL_CONSTANTS = { POINTS: 0x0000, LINES: 0x0001, @@ -153,7 +137,9 @@ position: 'translation', quaternion: 'rotation', morphTargetInfluences: 'weights' - }; // GLB constants + }; + + // GLB constants // https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification const GLB_HEADER_BYTES = 12; @@ -161,7 +147,9 @@ const GLB_VERSION = 2; const GLB_CHUNK_PREFIX_BYTES = 8; const GLB_CHUNK_TYPE_JSON = 0x4E4F534A; - const GLB_CHUNK_TYPE_BIN = 0x004E4942; //------------------------------------------------------------------------------ + const GLB_CHUNK_TYPE_BIN = 0x004E4942; + + //------------------------------------------------------------------------------ // Utility functions //------------------------------------------------------------------------------ @@ -171,7 +159,6 @@ * @param {Array} array2 Array 2 to compare * @return {Boolean} Returns true if both arrays are equal */ - function equalArray( array1, array2 ) { return array1.length === array2.length && array1.every( function ( element, index ) { @@ -181,31 +168,30 @@ } ); } + /** * Converts a string to an ArrayBuffer. * @param {string} text * @return {ArrayBuffer} */ - - function stringToArrayBuffer( text ) { return new TextEncoder().encode( text ).buffer; } + /** * Is identity matrix * * @param {Matrix4} matrix * @returns {Boolean} Returns true, if parameter is identity matrix */ - - function isIdentityMatrix( matrix ) { return equalArray( matrix.elements, [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] ); } + /** * Get the min and max vectors from the given attribute * @param {BufferAttribute} attribute Attribute to find the min/max in range from start to start + count @@ -213,24 +199,21 @@ * @param {Integer} count * @return {Object} Object containing the `min` and `max` values (As an array of attribute.itemSize components) */ - - function getMinMax( attribute, start, count ) { const output = { min: new Array( attribute.itemSize ).fill( Number.POSITIVE_INFINITY ), max: new Array( attribute.itemSize ).fill( Number.NEGATIVE_INFINITY ) }; - for ( let i = start; i < start + count; i ++ ) { for ( let a = 0; a < attribute.itemSize; a ++ ) { let value; - if ( attribute.itemSize > 4 ) { // no support for interleaved data for itemSize > 4 + value = attribute.array[ i * attribute.itemSize + a ]; } else { @@ -249,6 +232,7 @@ return output; } + /** * Get the required size + padding for a buffer, rounded to the next 4-byte boundary. * https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment @@ -257,13 +241,12 @@ * @returns {Integer} new buffer size with required padding. * */ - - function getPaddedBufferSize( bufferSize ) { return Math.ceil( bufferSize / 4 ) * 4; } + /** * Returns a buffer aligned to 4-byte boundary. * @@ -271,17 +254,13 @@ * @param {Integer} paddingByte (Optional) * @returns {ArrayBuffer} The same buffer if it's already aligned to 4-byte boundary or a new buffer */ - - function getPaddedArrayBuffer( arrayBuffer, paddingByte = 0 ) { const paddedLength = getPaddedBufferSize( arrayBuffer.byteLength ); - if ( paddedLength !== arrayBuffer.byteLength ) { const array = new Uint8Array( paddedLength ); array.set( new Uint8Array( arrayBuffer ) ); - if ( paddingByte !== 0 ) { for ( let i = arrayBuffer.byteLength; i < paddedLength; i ++ ) { @@ -320,9 +299,10 @@ } - let quality; // Blink's implementation of convertToBlob seems to default to a quality level of 100% - // Use the Blink default quality levels of toBlob instead so that file sizes are comparable. + let quality; + // Blink's implementation of convertToBlob seems to default to a quality level of 100% + // Use the Blink default quality levels of toBlob instead so that file sizes are comparable. if ( mimeType === 'image/jpeg' ) { quality = 0.92; @@ -339,11 +319,10 @@ } ); } + /** * Writer */ - - class GLTFWriter { constructor() { @@ -375,20 +354,18 @@ }; } - setPlugins( plugins ) { this.plugins = plugins; } + /** * Parse scenes and generate GLTF output * @param {Scene or [THREE.Scenes]} input THREE.Scene or Array of THREE.Scenes * @param {Function} onDone Callback on completed * @param {Object} options options */ - - async write( input, onDone, options ) { this.options = Object.assign( {}, { @@ -396,12 +373,10 @@ binary: false, trs: false, onlyVisible: true, - truncateDrawRange: true, maxTextureSize: Infinity, animations: [], includeCustomExtensions: false }, options ); - if ( this.options.animations.length > 0 ) { // Only TRS properties, and not matrices, may be targeted by animation. @@ -415,36 +390,40 @@ const buffers = writer.buffers; const json = writer.json; options = writer.options; - const extensionsUsed = writer.extensionsUsed; // Merge buffers. + const extensionsUsed = writer.extensionsUsed; + // Merge buffers. const blob = new Blob( buffers, { type: 'application/octet-stream' - } ); // Declare extensions. + } ); + // Declare extensions. const extensionsUsedList = Object.keys( extensionsUsed ); - if ( extensionsUsedList.length > 0 ) json.extensionsUsed = extensionsUsedList; // Update bytelength of the single buffer. + if ( extensionsUsedList.length > 0 ) json.extensionsUsed = extensionsUsedList; + // Update bytelength of the single buffer. if ( json.buffers && json.buffers.length > 0 ) json.buffers[ 0 ].byteLength = blob.size; - if ( options.binary === true ) { // https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification + const reader = new FileReader(); reader.readAsArrayBuffer( blob ); - reader.onloadend = function () { // Binary chunk. const binaryChunk = getPaddedArrayBuffer( reader.result ); const binaryChunkPrefix = new DataView( new ArrayBuffer( GLB_CHUNK_PREFIX_BYTES ) ); binaryChunkPrefix.setUint32( 0, binaryChunk.byteLength, true ); - binaryChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_BIN, true ); // JSON chunk. + binaryChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_BIN, true ); + // JSON chunk. const jsonChunk = getPaddedArrayBuffer( stringToArrayBuffer( JSON.stringify( json ) ), 0x20 ); const jsonChunkPrefix = new DataView( new ArrayBuffer( GLB_CHUNK_PREFIX_BYTES ) ); jsonChunkPrefix.setUint32( 0, jsonChunk.byteLength, true ); - jsonChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_JSON, true ); // GLB header. + jsonChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_JSON, true ); + // GLB header. const header = new ArrayBuffer( GLB_HEADER_BYTES ); const headerView = new DataView( header ); headerView.setUint32( 0, GLB_HEADER_MAGIC, true ); @@ -456,7 +435,6 @@ } ); const glbReader = new FileReader(); glbReader.readAsArrayBuffer( glbBlob ); - glbReader.onloadend = function () { onDone( glbReader.result ); @@ -471,7 +449,6 @@ const reader = new FileReader(); reader.readAsDataURL( blob ); - reader.onloadend = function () { const base64data = reader.result; @@ -489,28 +466,24 @@ } } + /** * Serializes a userData. * * @param {THREE.Object3D|THREE.Material} object * @param {Object} objectDef */ - - serializeUserData( object, objectDef ) { if ( Object.keys( object.userData ).length === 0 ) return; const options = this.options; const extensionsUsed = this.extensionsUsed; - try { const json = JSON.parse( JSON.stringify( object.userData ) ); - if ( options.includeCustomExtensions && json.gltfExtensions ) { if ( objectDef.extensions === undefined ) objectDef.extensions = {}; - for ( const extensionName in json.gltfExtensions ) { objectDef.extensions[ extensionName ] = json.gltfExtensions[ extensionName ]; @@ -531,13 +504,12 @@ } } + /** * Returns ids for buffer attributes. * @param {Object} object * @return {Integer} */ - - getUID( attribute, isRelativeCopy = false ) { if ( this.uids.has( attribute ) === false ) { @@ -553,20 +525,18 @@ return uids.get( isRelativeCopy ); } + /** * Checks if normal attribute values are normalized. * * @param {BufferAttribute} normal * @returns {Boolean} */ - - isNormalizedNormalAttribute( normal ) { const cache = this.cache; if ( cache.attributesNormalized.has( normal ) ) return false; const v = new THREE.Vector3(); - for ( let i = 0, il = normal.count; i < il; i ++ ) { // 0.0005 is from glTF-validator @@ -577,6 +547,7 @@ return true; } + /** * Creates normalized normal buffer attribute. * @@ -584,19 +555,15 @@ * @returns {BufferAttribute} * */ - - createNormalizedNormalAttribute( normal ) { const cache = this.cache; if ( cache.attributesNormalized.has( normal ) ) return cache.attributesNormalized.get( normal ); const attribute = normal.clone(); const v = new THREE.Vector3(); - for ( let i = 0, il = attribute.count; i < il; i ++ ) { v.fromBufferAttribute( attribute, i ); - if ( v.x === 0 && v.y === 0 && v.z === 0 ) { // if values can't be normalized set (1, 0, 0) @@ -616,6 +583,7 @@ return attribute; } + /** * Applies a texture transform, if present, to the map definition. Requires * the KHR_texture_transform extension. @@ -623,13 +591,10 @@ * @param {Object} mapDef * @param {THREE.Texture} texture */ - - applyTextureTransform( mapDef, texture ) { let didTransform = false; const transformDef = {}; - if ( texture.offset.x !== 0 || texture.offset.y !== 0 ) { transformDef.offset = texture.offset.toArray(); @@ -660,11 +625,9 @@ } } - buildMetalRoughTexture( metalnessMap, roughnessMap ) { if ( metalnessMap === roughnessMap ) return metalnessMap; - function getEncodingConversion( map ) { if ( map.encoding === THREE.sRGBEncoding ) { @@ -697,13 +660,11 @@ context.fillStyle = '#00ffff'; context.fillRect( 0, 0, width, height ); const composite = context.getImageData( 0, 0, width, height ); - if ( metalness ) { context.drawImage( metalness, 0, 0, width, height ); const convert = getEncodingConversion( metalnessMap ); const data = context.getImageData( 0, 0, width, height ).data; - for ( let i = 2; i < data.length; i += 4 ) { composite.data[ i ] = convert( data[ i ] / 256 ) * 256; @@ -717,7 +678,6 @@ context.drawImage( roughness, 0, 0, width, height ); const convert = getEncodingConversion( roughnessMap ); const data = context.getImageData( 0, 0, width, height ).data; - for ( let i = 1; i < data.length; i += 4 ) { composite.data[ i ] = convert( data[ i ] / 256 ) * 256; @@ -726,7 +686,9 @@ } - context.putImageData( composite, 0, 0 ); // + context.putImageData( composite, 0, 0 ); + + // const reference = metalnessMap || roughnessMap; const texture = reference.clone(); @@ -735,25 +697,26 @@ return texture; } + /** * Process a buffer to append to the default one. * @param {ArrayBuffer} buffer * @return {Integer} */ - - processBuffer( buffer ) { const json = this.json; const buffers = this.buffers; if ( ! json.buffers ) json.buffers = [ { byteLength: 0 - } ]; // All buffers are merged before export. + } ]; + // All buffers are merged before export. buffers.push( buffer ); return 0; } + /** * Process and generate a BufferView * @param {BufferAttribute} attribute @@ -763,15 +726,14 @@ * @param {number} target (Optional) Target usage of the BufferView * @return {Object} */ - - processBufferView( attribute, componentType, start, count, target ) { const json = this.json; - if ( ! json.bufferViews ) json.bufferViews = []; // Create a new dataview and dump the attribute's array into it + if ( ! json.bufferViews ) json.bufferViews = []; - let componentSize; + // Create a new dataview and dump the attribute's array into it + let componentSize; if ( componentType === WEBGL_CONSTANTS.UNSIGNED_BYTE ) { componentSize = 1; @@ -789,16 +751,15 @@ const byteLength = getPaddedBufferSize( count * attribute.itemSize * componentSize ); const dataView = new DataView( new ArrayBuffer( byteLength ) ); let offset = 0; - for ( let i = start; i < start + count; i ++ ) { for ( let a = 0; a < attribute.itemSize; a ++ ) { let value; - if ( attribute.itemSize > 4 ) { // no support for interleaved data for itemSize > 4 + value = attribute.array[ i * attribute.itemSize + a ]; } else { @@ -837,7 +798,6 @@ byteLength: byteLength }; if ( target !== undefined ) bufferViewDef.target = target; - if ( target === WEBGL_CONSTANTS.ARRAY_BUFFER ) { // Only define byteStride for vertex attributes. @@ -846,8 +806,9 @@ } this.byteOffset += byteLength; - json.bufferViews.push( bufferViewDef ); // @TODO Merge bufferViews where possible. + json.bufferViews.push( bufferViewDef ); + // @TODO Merge bufferViews where possible. const output = { id: json.bufferViews.length - 1, byteLength: 0 @@ -855,13 +816,12 @@ return output; } + /** * Process and generate a BufferView from an image Blob. * @param {Blob} blob * @return {Promise} */ - - processBufferViewImage( blob ) { const writer = this; @@ -871,7 +831,6 @@ const reader = new FileReader(); reader.readAsArrayBuffer( blob ); - reader.onloadend = function () { const buffer = getPaddedArrayBuffer( reader.result ); @@ -888,6 +847,7 @@ } ); } + /** * Process attribute to generate an accessor * @param {BufferAttribute} attribute Attribute to process @@ -896,11 +856,8 @@ * @param {Integer} count (Optional) * @return {Integer|null} Index of the processed accessor on the "accessors" array */ - - processAccessor( attribute, geometry, start, count ) { - const options = this.options; const json = this.json; const types = { 1: 'SCALAR', @@ -909,8 +866,9 @@ 4: 'VEC4', 16: 'MAT4' }; - let componentType; // Detect the component type of the attribute array (float, uint or ushort) + let componentType; + // Detect the component type of the attribute array (float, uint or ushort) if ( attribute.array.constructor === Float32Array ) { componentType = WEBGL_CONSTANTS.FLOAT; @@ -934,24 +892,15 @@ } if ( start === undefined ) start = 0; - if ( count === undefined ) count = attribute.count; // @TODO Indexed buffer geometry with drawRange not supported yet - - if ( options.truncateDrawRange && geometry !== undefined && geometry.index === null ) { - - const end = start + count; - const end2 = geometry.drawRange.count === Infinity ? attribute.count : geometry.drawRange.start + geometry.drawRange.count; - start = Math.max( start, geometry.drawRange.start ); - count = Math.min( end, end2 ) - start; - if ( count < 0 ) count = 0; - - } // Skip creating an accessor if the attribute doesn't have data to export - + if ( count === undefined ) count = attribute.count; + // Skip creating an accessor if the attribute doesn't have data to export if ( count === 0 ) return null; const minMax = getMinMax( attribute, start, count ); - let bufferViewTarget; // If geometry isn't provided, don't infer the target usage of the bufferView. For - // animation samplers, target must not be set. + let bufferViewTarget; + // If geometry isn't provided, don't infer the target usage of the bufferView. For + // animation samplers, target must not be set. if ( geometry !== undefined ) { bufferViewTarget = attribute === geometry.index ? WEBGL_CONSTANTS.ELEMENT_ARRAY_BUFFER : WEBGL_CONSTANTS.ARRAY_BUFFER; @@ -973,6 +922,7 @@ return json.accessors.push( accessorDef ) - 1; } + /** * Process image * @param {Image} image to process @@ -981,8 +931,6 @@ * @param {String} mimeType export format * @return {Integer} Index of the processed texture in the "images" array */ - - processImage( image, format, flipY, mimeType = 'image/png' ) { const writer = this; @@ -1002,7 +950,6 @@ canvas.width = Math.min( image.width, options.maxTextureSize ); canvas.height = Math.min( image.height, options.maxTextureSize ); const ctx = canvas.getContext( '2d' ); - if ( flipY === true ) { ctx.translate( 0, canvas.height ); @@ -1013,6 +960,7 @@ if ( image.data !== undefined ) { // THREE.DataTexture + if ( format !== THREE.RGBAFormat ) { console.error( 'GLTFExporter: Only THREE.RGBAFormat is supported.' ); @@ -1026,7 +974,6 @@ } const data = new Uint8ClampedArray( image.height * image.width * 4 ); - for ( let i = 0; i < data.length; i += 4 ) { data[ i + 0 ] = image.data[ i + 0 ]; @@ -1075,13 +1022,12 @@ return index; } + /** * Process sampler * @param {Texture} map Texture to process * @return {Integer} Index of the processed texture in the "samplers" array */ - - processSampler( map ) { const json = this.json; @@ -1095,13 +1041,12 @@ return json.samplers.push( samplerDef ) - 1; } + /** * Process texture * @param {Texture} map Map to process * @return {Integer} Index of the processed texture in the "textures" array */ - - processTexture( map ) { const cache = this.cache; @@ -1115,31 +1060,27 @@ source: this.processImage( map.image, map.format, map.flipY, mimeType ) }; if ( map.name ) textureDef.name = map.name; - this._invokeAll( function ( ext ) { ext.writeTexture && ext.writeTexture( map, textureDef ); } ); - const index = json.textures.push( textureDef ) - 1; cache.textures.set( map, index ); return index; } + /** * Process material * @param {THREE.Material} material Material to process * @return {Integer|null} Index of the processed material in the "materials" array */ - - processMaterial( material ) { const cache = this.cache; const json = this.json; if ( cache.materials.has( material ) ) return cache.materials.get( material ); - if ( material.isShaderMaterial ) { console.warn( 'GLTFExporter: THREE.ShaderMaterial not supported.' ); @@ -1147,21 +1088,20 @@ } - if ( ! json.materials ) json.materials = []; // @QUESTION Should we avoid including any attribute that has the default value? + if ( ! json.materials ) json.materials = []; + // @QUESTION Should we avoid including any attribute that has the default value? const materialDef = { pbrMetallicRoughness: {} }; - if ( material.isMeshStandardMaterial !== true && material.isMeshBasicMaterial !== true ) { console.warn( 'GLTFExporter: Use MeshStandardMaterial or MeshBasicMaterial for best results.' ); - } // pbrMetallicRoughness.baseColorFactor - + } + // pbrMetallicRoughness.baseColorFactor const color = material.color.toArray().concat( [ material.opacity ] ); - if ( ! equalArray( color, [ 1, 1, 1, 1 ] ) ) { materialDef.pbrMetallicRoughness.baseColorFactor = color; @@ -1178,9 +1118,9 @@ materialDef.pbrMetallicRoughness.metallicFactor = 0.5; materialDef.pbrMetallicRoughness.roughnessFactor = 0.5; - } // pbrMetallicRoughness.metallicRoughnessTexture - + } + // pbrMetallicRoughness.metallicRoughnessTexture if ( material.metalnessMap || material.roughnessMap ) { const metalRoughTexture = this.buildMetalRoughTexture( material.metalnessMap, material.roughnessMap ); @@ -1190,9 +1130,9 @@ this.applyTextureTransform( metalRoughMapDef, metalRoughTexture ); materialDef.pbrMetallicRoughness.metallicRoughnessTexture = metalRoughMapDef; - } // pbrMetallicRoughness.baseColorTexture or pbrSpecularGlossiness diffuseTexture - + } + // pbrMetallicRoughness.baseColorTexture or pbrSpecularGlossiness diffuseTexture if ( material.map ) { const baseColorMapDef = { @@ -1208,7 +1148,6 @@ // note: emissive components are limited to stay within the 0 - 1 range to accommodate glTF spec. see #21849 and #22000. const emissive = material.emissive.clone().multiplyScalar( material.emissiveIntensity ); const maxEmissiveComponent = Math.max( emissive.r, emissive.g, emissive.b ); - if ( maxEmissiveComponent > 1 ) { emissive.multiplyScalar( 1 / maxEmissiveComponent ); @@ -1220,9 +1159,9 @@ materialDef.emissiveFactor = emissive.toArray(); - } // emissiveTexture - + } + // emissiveTexture if ( material.emissiveMap ) { const emissiveMapDef = { @@ -1233,15 +1172,14 @@ } - } // normalTexture - + } + // normalTexture if ( material.normalMap ) { const normalMapDef = { index: this.processTexture( material.normalMap ) }; - if ( material.normalScale && material.normalScale.x !== 1 ) { // glTF normal scale is univariate. Ignore `y`, which may be flipped. @@ -1253,16 +1191,15 @@ this.applyTextureTransform( normalMapDef, material.normalMap ); materialDef.normalTexture = normalMapDef; - } // occlusionTexture - + } + // occlusionTexture if ( material.aoMap ) { const occlusionMapDef = { index: this.processTexture( material.aoMap ), texCoord: 1 }; - if ( material.aoMapIntensity !== 1.0 ) { occlusionMapDef.strength = material.aoMapIntensity; @@ -1272,9 +1209,9 @@ this.applyTextureTransform( occlusionMapDef, material.aoMap ); materialDef.occlusionTexture = occlusionMapDef; - } // alphaMode - + } + // alphaMode if ( material.transparent ) { materialDef.alphaMode = 'BLEND'; @@ -1288,37 +1225,33 @@ } - } // doubleSided - + } + // doubleSided if ( material.side === THREE.DoubleSide ) materialDef.doubleSided = true; if ( material.name !== '' ) materialDef.name = material.name; this.serializeUserData( material, materialDef ); - this._invokeAll( function ( ext ) { ext.writeMaterial && ext.writeMaterial( material, materialDef ); } ); - const index = json.materials.push( materialDef ) - 1; cache.materials.set( material, index ); return index; } + /** * Process mesh * @param {THREE.Mesh} mesh Mesh to process * @return {Integer|null} Index of the processed mesh in the "meshes" array */ - - processMesh( mesh ) { const cache = this.cache; const json = this.json; const meshCacheKeyParts = [ mesh.geometry.uuid ]; - if ( Array.isArray( mesh.material ) ) { for ( let i = 0, l = mesh.material.length; i < l; i ++ ) { @@ -1336,8 +1269,9 @@ const meshCacheKey = meshCacheKeyParts.join( ':' ); if ( cache.meshes.has( meshCacheKey ) ) return cache.meshes.get( meshCacheKey ); const geometry = mesh.geometry; - let mode; // Use the correct mode + let mode; + // Use the correct mode if ( mesh.isLineSegments ) { mode = WEBGL_CONSTANTS.LINES; @@ -1360,17 +1294,12 @@ } - if ( geometry.isBufferGeometry !== true ) { - - throw new Error( 'THREE.GLTFExporter: Geometry is not of type THREE.BufferGeometry.' ); - - } - const meshDef = {}; const attributes = {}; const primitives = []; - const targets = []; // Conversion between attributes names in threejs and gltf spec + const targets = []; + // Conversion between attributes names in threejs and gltf spec const nameConversion = { uv: 'TEXCOORD_0', uv2: 'TEXCOORD_1', @@ -1379,40 +1308,37 @@ skinIndex: 'JOINTS_0' }; const originalNormal = geometry.getAttribute( 'normal' ); - if ( originalNormal !== undefined && ! this.isNormalizedNormalAttribute( originalNormal ) ) { console.warn( 'THREE.GLTFExporter: Creating normalized normal attribute from the non-normalized one.' ); geometry.setAttribute( 'normal', this.createNormalizedNormalAttribute( originalNormal ) ); - } // @QUESTION Detect if .vertexColors = true? - // For every attribute create an accessor - + } + // @QUESTION Detect if .vertexColors = true? + // For every attribute create an accessor let modifiedAttribute = null; - for ( let attributeName in geometry.attributes ) { // Ignore morph target attributes, which are exported later. if ( attributeName.slice( 0, 5 ) === 'morph' ) continue; const attribute = geometry.attributes[ attributeName ]; - attributeName = nameConversion[ attributeName ] || attributeName.toUpperCase(); // Prefix all geometry attributes except the ones specifically - // listed in the spec; non-spec attributes are considered custom. + attributeName = nameConversion[ attributeName ] || attributeName.toUpperCase(); + // Prefix all geometry attributes except the ones specifically + // listed in the spec; non-spec attributes are considered custom. const validVertexAttributes = /^(POSITION|NORMAL|TANGENT|TEXCOORD_\d+|COLOR_\d+|JOINTS_\d+|WEIGHTS_\d+)$/; if ( ! validVertexAttributes.test( attributeName ) ) attributeName = '_' + attributeName; - if ( cache.attributes.has( this.getUID( attribute ) ) ) { attributes[ attributeName ] = cache.attributes.get( this.getUID( attribute ) ); continue; - } // JOINTS_0 must be UNSIGNED_BYTE or UNSIGNED_SHORT. - + } + // JOINTS_0 must be UNSIGNED_BYTE or UNSIGNED_SHORT. modifiedAttribute = null; const array = attribute.array; - if ( attributeName === 'JOINTS_0' && ! ( array instanceof Uint16Array ) && ! ( array instanceof Uint8Array ) ) { console.warn( 'GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.' ); @@ -1421,7 +1347,6 @@ } const accessor = this.processAccessor( modifiedAttribute || attribute, geometry ); - if ( accessor !== null ) { attributes[ attributeName ] = accessor; @@ -1431,16 +1356,17 @@ } - if ( originalNormal !== undefined ) geometry.setAttribute( 'normal', originalNormal ); // Skip if no exportable attributes found + if ( originalNormal !== undefined ) geometry.setAttribute( 'normal', originalNormal ); - if ( Object.keys( attributes ).length === 0 ) return null; // Morph targets + // Skip if no exportable attributes found + if ( Object.keys( attributes ).length === 0 ) return null; + // Morph targets if ( mesh.morphTargetInfluences !== undefined && mesh.morphTargetInfluences.length > 0 ) { const weights = []; const targetNames = []; const reverseDictionary = {}; - if ( mesh.morphTargetDictionary !== undefined ) { for ( const key in mesh.morphTargetDictionary ) { @@ -1455,11 +1381,11 @@ const target = {}; let warned = false; - for ( const attributeName in geometry.morphAttributes ) { // glTF 2.0 morph supports only POSITION/NORMAL/TANGENT. // Three.js doesn't support TANGENT yet. + if ( attributeName !== 'position' && attributeName !== 'normal' ) { if ( ! warned ) { @@ -1474,23 +1400,23 @@ } const attribute = geometry.morphAttributes[ attributeName ][ i ]; - const gltfAttributeName = attributeName.toUpperCase(); // Three.js morph attribute has absolute values while the one of glTF has relative values. + const gltfAttributeName = attributeName.toUpperCase(); + + // Three.js morph attribute has absolute values while the one of glTF has relative values. // // glTF 2.0 Specification: // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#morph-targets const baseAttribute = geometry.attributes[ attributeName ]; - if ( cache.attributes.has( this.getUID( attribute, true ) ) ) { target[ gltfAttributeName ] = cache.attributes.get( this.getUID( attribute, true ) ); continue; - } // Clones attribute not to override - + } + // Clones attribute not to override const relativeAttribute = attribute.clone(); - if ( ! geometry.morphTargetsRelative ) { for ( let j = 0, jl = attribute.count; j < jl; j ++ ) { @@ -1513,7 +1439,6 @@ } meshDef.weights = weights; - if ( targetNames.length > 0 ) { meshDef.extras = {}; @@ -1531,7 +1456,6 @@ start: undefined, count: undefined } ]; - for ( let i = 0, il = groups.length; i < il; i ++ ) { const primitive = { @@ -1540,11 +1464,9 @@ }; this.serializeUserData( geometry, primitive ); if ( targets.length > 0 ) primitive.targets = targets; - if ( geometry.index !== null ) { let cacheKey = this.getUID( geometry.index ); - if ( groups[ i ].start !== undefined || groups[ i ].count !== undefined ) { cacheKey += ':' + groups[ i ].start + ':' + groups[ i ].count; @@ -1574,25 +1496,22 @@ meshDef.primitives = primitives; if ( ! json.meshes ) json.meshes = []; - this._invokeAll( function ( ext ) { ext.writeMesh && ext.writeMesh( mesh, meshDef ); } ); - const index = json.meshes.push( meshDef ) - 1; cache.meshes.set( meshCacheKey, index ); return index; } + /** * Process camera * @param {THREE.Camera} camera Camera to process * @return {Integer} Index of the processed mesh in the "camera" array */ - - processCamera( camera ) { const json = this.json; @@ -1601,7 +1520,6 @@ const cameraDef = { type: isOrtho ? 'orthographic' : 'perspective' }; - if ( isOrtho ) { cameraDef.orthographic = { @@ -1620,13 +1538,14 @@ znear: camera.near < 0 ? 0 : camera.near }; - } // Question: Is saving "type" as name intentional? - + } + // Question: Is saving "type" as name intentional? if ( camera.name !== '' ) cameraDef.name = camera.type; return json.cameras.push( cameraDef ) - 1; } + /** * Creates glTF animation entry from AnimationClip object. * @@ -1637,8 +1556,6 @@ * @param {THREE.Object3D} root * @return {number|null} */ - - processAnimation( clip, root ) { const json = this.json; @@ -1648,14 +1565,12 @@ const tracks = clip.tracks; const channels = []; const samplers = []; - for ( let i = 0; i < tracks.length; ++ i ) { const track = tracks[ i ]; const trackBinding = THREE.PropertyBinding.parseTrackName( track.name ); let trackNode = THREE.PropertyBinding.findNode( root, trackBinding.nodeName ); const trackProperty = PATH_PROPERTIES[ trackBinding.propertyName ]; - if ( trackBinding.objectName === 'bones' ) { if ( trackNode.isSkinnedMesh === true ) { @@ -1679,24 +1594,26 @@ const inputItemSize = 1; let outputItemSize = track.values.length / track.times.length; - if ( trackProperty === PATH_PROPERTIES.morphTargetInfluences ) { outputItemSize /= trackNode.morphTargetInfluences.length; } - let interpolation; // @TODO export CubicInterpolant(InterpolateSmooth) as CUBICSPLINE + let interpolation; + + // @TODO export CubicInterpolant(InterpolateSmooth) as CUBICSPLINE + // Detecting glTF cubic spline interpolant by checking factory method's special property // GLTFCubicSplineInterpolant is a custom interpolant and track doesn't return // valid value from .getInterpolation(). - if ( track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline === true ) { - interpolation = 'CUBICSPLINE'; // itemSize of CUBICSPLINE keyframe is 9 + interpolation = 'CUBICSPLINE'; + + // itemSize of CUBICSPLINE keyframe is 9 // (VEC3 * 3: inTangent, splineVertex, and outTangent) // but needs to be stored as VEC3 so dividing by 3 here. - outputItemSize /= 3; } else if ( track.getInterpolation() === THREE.InterpolateDiscrete ) { @@ -1732,12 +1649,11 @@ return json.animations.length - 1; } + /** * @param {THREE.Object3D} object * @return {number|null} */ - - processSkin( object ) { const json = this.json; @@ -1750,7 +1666,6 @@ const joints = []; const inverseBindMatrices = new Float32Array( skeleton.bones.length * 16 ); const temporaryBoneInverse = new THREE.Matrix4(); - for ( let i = 0; i < skeleton.bones.length; ++ i ) { joints.push( nodeMap.get( skeleton.bones[ i ] ) ); @@ -1769,13 +1684,12 @@ return skinIndex; } + /** * Process Object3D node * @param {THREE.Object3D} node Object3D to processNode * @return {Integer} Index of the node in the nodes list */ - - processNode( object ) { const json = this.json; @@ -1783,13 +1697,11 @@ const nodeMap = this.nodeMap; if ( ! json.nodes ) json.nodes = []; const nodeDef = {}; - if ( options.trs ) { const rotation = object.quaternion.toArray(); const position = object.position.toArray(); const scale = object.scale.toArray(); - if ( ! equalArray( rotation, [ 0, 0, 0, 1 ] ) ) { nodeDef.rotation = rotation; @@ -1822,12 +1734,11 @@ } - } // We don't export empty strings name because it represents no-name in Three.js. - + } + // We don't export empty strings name because it represents no-name in Three.js. if ( object.name !== '' ) nodeDef.name = String( object.name ); this.serializeUserData( object, nodeDef ); - if ( object.isMesh || object.isLine || object.isPoints ) { const meshIndex = this.processMesh( object ); @@ -1840,15 +1751,12 @@ } if ( object.isSkinnedMesh ) this.skins.push( object ); - if ( object.children.length > 0 ) { const children = []; - for ( let i = 0, l = object.children.length; i < l; i ++ ) { const child = object.children[ i ]; - if ( child.visible || options.onlyVisible === false ) { const nodeIndex = this.processNode( child ); @@ -1867,23 +1775,20 @@ ext.writeNode && ext.writeNode( object, nodeDef ); } ); - const nodeIndex = json.nodes.push( nodeDef ) - 1; nodeMap.set( object, nodeIndex ); return nodeIndex; } + /** * Process THREE.Scene * @param {Scene} node THREE.Scene to process */ - - processScene( scene ) { const json = this.json; const options = this.options; - if ( ! json.scenes ) { json.scenes = []; @@ -1895,11 +1800,9 @@ if ( scene.name !== '' ) sceneDef.name = scene.name; json.scenes.push( sceneDef ); const nodes = []; - for ( let i = 0, l = scene.children.length; i < l; i ++ ) { const child = scene.children[ i ]; - if ( child.visible || options.onlyVisible === false ) { const nodeIndex = this.processNode( child ); @@ -1913,17 +1816,15 @@ this.serializeUserData( scene, sceneDef ); } + /** * Creates a THREE.Scene to hold a list of objects and parse it * @param {Array} objects List of objects to process */ - - processObjects( objects ) { const scene = new THREE.Scene(); scene.name = 'AuxScene'; - for ( let i = 0; i < objects.length; i ++ ) { // We push directly to children instead of calling `add` to prevent @@ -1935,24 +1836,20 @@ this.processScene( scene ); } + /** * @param {THREE.Object3D|Array} input */ - - processInput( input ) { const options = this.options; input = input instanceof Array ? input : [ input ]; - this._invokeAll( function ( ext ) { ext.beforeParse && ext.beforeParse( input ); } ); - const objectsWithoutScene = []; - for ( let i = 0; i < input.length; i ++ ) { if ( input[ i ] instanceof THREE.Scene ) { @@ -1968,7 +1865,6 @@ } if ( objectsWithoutScene.length > 0 ) this.processObjects( objectsWithoutScene ); - for ( let i = 0; i < this.skins.length; ++ i ) { this.processSkin( this.skins[ i ] ); @@ -1988,7 +1884,6 @@ } ); } - _invokeAll( func ) { for ( let i = 0, il = this.plugins.length; i < il; i ++ ) { @@ -2000,13 +1895,12 @@ } } + /** * Punctual Lights Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual */ - - class GLTFLightExtension { constructor( writer ) { @@ -2015,11 +1909,9 @@ this.name = 'KHR_lights_punctual'; } - writeNode( light, nodeDef ) { if ( ! light.isLight ) return; - if ( ! light.isDirectionalLight && ! light.isPointLight && ! light.isSpotLight ) { console.warn( 'THREE.GLTFExporter: Only directional, point, and spot lights are supported.', light ); @@ -2034,7 +1926,6 @@ if ( light.name ) lightDef.name = light.name; lightDef.color = light.color.toArray(); lightDef.intensity = light.intensity; - if ( light.isDirectionalLight ) { lightDef.type = 'directional'; @@ -2086,13 +1977,12 @@ } } + /** * Unlit Materials Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit */ - - class GLTFMaterialsUnlitExtension { constructor( writer ) { @@ -2101,7 +1991,6 @@ this.name = 'KHR_materials_unlit'; } - writeMaterial( material, materialDef ) { if ( ! material.isMeshBasicMaterial ) return; @@ -2116,70 +2005,12 @@ } } - /** - * Specular-Glossiness Extension - * - * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness - */ - - - class GLTFMaterialsPBRSpecularGlossiness { - - constructor( writer ) { - - this.writer = writer; - this.name = 'KHR_materials_pbrSpecularGlossiness'; - - } - - writeMaterial( material, materialDef ) { - - if ( ! material.isGLTFSpecularGlossinessMaterial ) return; - const writer = this.writer; - const extensionsUsed = writer.extensionsUsed; - const extensionDef = {}; - - if ( materialDef.pbrMetallicRoughness.baseColorFactor ) { - - extensionDef.diffuseFactor = materialDef.pbrMetallicRoughness.baseColorFactor; - } - - const specularFactor = [ 1, 1, 1 ]; - material.specular.toArray( specularFactor, 0 ); - extensionDef.specularFactor = specularFactor; - extensionDef.glossinessFactor = material.glossiness; - - if ( materialDef.pbrMetallicRoughness.baseColorTexture ) { - - extensionDef.diffuseTexture = materialDef.pbrMetallicRoughness.baseColorTexture; - - } - - if ( material.specularMap ) { - - const specularMapDef = { - index: writer.processTexture( material.specularMap ) - }; - writer.applyTextureTransform( specularMapDef, material.specularMap ); - extensionDef.specularGlossinessTexture = specularMapDef; - - } - - materialDef.extensions = materialDef.extensions || {}; - materialDef.extensions[ this.name ] = extensionDef; - extensionsUsed[ this.name ] = true; - - } - - } /** * Clearcoat Materials Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat */ - - class GLTFMaterialsClearcoatExtension { constructor( writer ) { @@ -2188,7 +2019,6 @@ this.name = 'KHR_materials_clearcoat'; } - writeMaterial( material, materialDef ) { if ( ! material.isMeshPhysicalMaterial ) return; @@ -2196,7 +2026,6 @@ const extensionsUsed = writer.extensionsUsed; const extensionDef = {}; extensionDef.clearcoatFactor = material.clearcoat; - if ( material.clearcoatMap ) { const clearcoatMapDef = { @@ -2208,7 +2037,6 @@ } extensionDef.clearcoatRoughnessFactor = material.clearcoatRoughness; - if ( material.clearcoatRoughnessMap ) { const clearcoatRoughnessMapDef = { @@ -2236,13 +2064,12 @@ } } + /** * Iridescence Materials Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_iridescence */ - - class GLTFMaterialsIridescenceExtension { constructor( writer ) { @@ -2251,7 +2078,6 @@ this.name = 'KHR_materials_iridescence'; } - writeMaterial( material, materialDef ) { if ( ! material.isMeshPhysicalMaterial ) return; @@ -2259,7 +2085,6 @@ const extensionsUsed = writer.extensionsUsed; const extensionDef = {}; extensionDef.iridescenceFactor = material.iridescence; - if ( material.iridescenceMap ) { const iridescenceMapDef = { @@ -2273,7 +2098,6 @@ extensionDef.iridescenceIor = material.iridescenceIOR; extensionDef.iridescenceThicknessMinimum = material.iridescenceThicknessRange[ 0 ]; extensionDef.iridescenceThicknessMaximum = material.iridescenceThicknessRange[ 1 ]; - if ( material.iridescenceThicknessMap ) { const iridescenceThicknessMapDef = { @@ -2291,13 +2115,12 @@ } } + /** * Transmission Materials Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission */ - - class GLTFMaterialsTransmissionExtension { constructor( writer ) { @@ -2306,7 +2129,6 @@ this.name = 'KHR_materials_transmission'; } - writeMaterial( material, materialDef ) { if ( ! material.isMeshPhysicalMaterial || material.transmission === 0 ) return; @@ -2314,7 +2136,6 @@ const extensionsUsed = writer.extensionsUsed; const extensionDef = {}; extensionDef.transmissionFactor = material.transmission; - if ( material.transmissionMap ) { const transmissionMapDef = { @@ -2332,13 +2153,12 @@ } } + /** * Materials Volume Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_volume */ - - class GLTFMaterialsVolumeExtension { constructor( writer ) { @@ -2347,7 +2167,6 @@ this.name = 'KHR_materials_volume'; } - writeMaterial( material, materialDef ) { if ( ! material.isMeshPhysicalMaterial || material.transmission === 0 ) return; @@ -2355,7 +2174,6 @@ const extensionsUsed = writer.extensionsUsed; const extensionDef = {}; extensionDef.thicknessFactor = material.thickness; - if ( material.thicknessMap ) { const thicknessMapDef = { @@ -2375,26 +2193,22 @@ } } + /** * Static utility functions */ - - GLTFExporter.Utils = { insertKeyframe: function ( track, time ) { const tolerance = 0.001; // 1ms - const valueSize = track.getValueSize(); const times = new track.TimeBufferType( track.times.length + 1 ); const values = new track.ValueBufferType( track.values.length + valueSize ); const interpolant = track.createInterpolant( new track.ValueBufferType( valueSize ) ); let index; - if ( track.times.length === 0 ) { times[ 0 ] = time; - for ( let i = 0; i < valueSize; i ++ ) { values[ i ] = 0; @@ -2431,7 +2245,6 @@ for ( let i = 0; i < track.times.length; i ++ ) { if ( Math.abs( track.times[ i ] - time ) < tolerance ) return i; - if ( track.times[ i ] < time && track.times[ i + 1 ] > time ) { times.set( track.times.slice( 0, i + 1 ), 0 ); @@ -2459,13 +2272,11 @@ const tracks = []; const mergedTracks = {}; const sourceTracks = clip.tracks; - for ( let i = 0; i < sourceTracks.length; ++ i ) { let sourceTrack = sourceTracks[ i ]; const sourceTrackBinding = THREE.PropertyBinding.parseTrackName( sourceTrack.name ); const sourceTrackNode = THREE.PropertyBinding.findNode( root, sourceTrackBinding.nodeName ); - if ( sourceTrackBinding.propertyName !== 'morphTargetInfluences' || sourceTrackBinding.propertyIndex === undefined ) { // Tracks that don't affect morph targets, or that affect all morph targets together, can be left as-is. @@ -2492,29 +2303,28 @@ const targetCount = sourceTrackNode.morphTargetInfluences.length; const targetIndex = sourceTrackNode.morphTargetDictionary[ sourceTrackBinding.propertyIndex ]; - if ( targetIndex === undefined ) { throw new Error( 'THREE.GLTFExporter: Morph target name not found: ' + sourceTrackBinding.propertyIndex ); } - let mergedTrack; // If this is the first time we've seen this object, create a new - // track to store merged keyframe data for each morph target. + let mergedTrack; + // If this is the first time we've seen this object, create a new + // track to store merged keyframe data for each morph target. if ( mergedTracks[ sourceTrackNode.uuid ] === undefined ) { mergedTrack = sourceTrack.clone(); const values = new mergedTrack.ValueBufferType( targetCount * mergedTrack.times.length ); - for ( let j = 0; j < mergedTrack.times.length; j ++ ) { values[ j * targetCount + targetIndex ] = mergedTrack.values[ j ]; - } // We need to take into consideration the intended target node - // of our original un-merged morphTarget animation. - + } + // We need to take into consideration the intended target node + // of our original un-merged morphTarget animation. mergedTrack.name = ( sourceTrackBinding.nodeName || '' ) + '.morphTargetInfluences'; mergedTrack.values = values; mergedTracks[ sourceTrackNode.uuid ] = mergedTrack; @@ -2524,18 +2334,19 @@ } const sourceInterpolant = sourceTrack.createInterpolant( new sourceTrack.ValueBufferType( 1 ) ); - mergedTrack = mergedTracks[ sourceTrackNode.uuid ]; // For every existing keyframe of the merged track, write a (possibly - // interpolated) value from the source track. + mergedTrack = mergedTracks[ sourceTrackNode.uuid ]; + // For every existing keyframe of the merged track, write a (possibly + // interpolated) value from the source track. for ( let j = 0; j < mergedTrack.times.length; j ++ ) { mergedTrack.values[ j * targetCount + targetIndex ] = sourceInterpolant.evaluate( mergedTrack.times[ j ] ); - } // For every existing keyframe of the source track, write a (possibly + } + + // For every existing keyframe of the source track, write a (possibly // new) keyframe to the merged track. Values from the previous loop may // be written again, but keyframes are de-duplicated. - - for ( let j = 0; j < sourceTrack.times.length; j ++ ) { const keyframeIndex = this.insertKeyframe( mergedTrack, sourceTrack.times[ j ] ); diff --git a/examples/js/exporters/MMDExporter.js b/examples/js/exporters/MMDExporter.js index 90fd2326d6991e..d9a3ac6bd94c33 100644 --- a/examples/js/exporters/MMDExporter.js +++ b/examples/js/exporters/MMDExporter.js @@ -42,7 +42,6 @@ if ( Math.abs( num ) < 1e-6 ) num = 0; let a = num.toString(); - if ( a.indexOf( '.' ) === - 1 ) { a += '.'; @@ -60,7 +59,6 @@ function toStringsFromArray( array ) { const a = []; - for ( let i = 0, il = array.length; i < il; i ++ ) { a.push( toStringsFromNumber( array[ i ] ) ); @@ -84,16 +82,15 @@ array.push( ( skin.name !== '' ? skin.name.replace( /\s/g, '_' ) : 'skin' ) + '.osm;' ); array.push( bones.length + ';' ); array.push( '' ); - for ( let i = 0, il = bones.length; i < il; i ++ ) { const bone = bones[ i ]; const bone2 = bones2[ i ]; + /* * use the bone matrix saved before solving IK. * see CCDIKSolver for the detail. */ - if ( useOriginalBones === true && bone.userData.ik !== undefined && bone.userData.ik.originalMatrix !== undefined ) { matrix.fromArray( bone.userData.ik.originalMatrix ); @@ -107,8 +104,9 @@ position.setFromMatrixPosition( matrix ); quaternion.setFromRotationMatrix( matrix ); const pArray = position.sub( bone2.position ).toArray(); - const qArray = quaternion2.copy( bone2.quaternion ).conjugate().multiply( quaternion ).toArray(); // right to left + const qArray = quaternion2.copy( bone2.quaternion ).conjugate().multiply( quaternion ).toArray(); + // right to left pArray[ 2 ] = - pArray[ 2 ]; qArray[ 0 ] = - qArray[ 0 ]; qArray[ 1 ] = - qArray[ 1 ]; @@ -126,21 +124,18 @@ } - } // Unicode to Shift_JIS table - + } + // Unicode to Shift_JIS table let u2sTable; - function unicodeToShiftjis( str ) { if ( u2sTable === undefined ) { const encoder = new MMDParser.CharsetEncoder(); // eslint-disable-line no-undef - const table = encoder.s2uTable; u2sTable = {}; const keys = Object.keys( table ); - for ( let i = 0, il = keys.length; i < il; i ++ ) { let key = keys[ i ]; @@ -153,12 +148,10 @@ } const array = []; - for ( let i = 0, il = str.length; i < il; i ++ ) { const code = str.charCodeAt( i ); const value = u2sTable[ code ]; - if ( value === undefined ) { throw new Error( 'cannot convert charcode 0x' + code.toString( 16 ) ); diff --git a/examples/js/exporters/OBJExporter.js b/examples/js/exporters/OBJExporter.js index 2f015139d52099..295ff99309df0f 100644 --- a/examples/js/exporters/OBJExporter.js +++ b/examples/js/exporters/OBJExporter.js @@ -13,7 +13,6 @@ const normal = new THREE.Vector3(); const uv = new THREE.Vector2(); const face = []; - function parseMesh( mesh ) { let nbVertex = 0; @@ -22,71 +21,75 @@ const geometry = mesh.geometry; const normalMatrixWorld = new THREE.Matrix3(); - if ( geometry.isBufferGeometry !== true ) { - - throw new Error( 'THREE.OBJExporter: Geometry is not of type THREE.BufferGeometry.' ); - - } // shortcuts - - + // shortcuts const vertices = geometry.getAttribute( 'position' ); const normals = geometry.getAttribute( 'normal' ); const uvs = geometry.getAttribute( 'uv' ); - const indices = geometry.getIndex(); // name of the mesh object + const indices = geometry.getIndex(); - output += 'o ' + mesh.name + '\n'; // name of the mesh material + // name of the mesh object + output += 'o ' + mesh.name + '\n'; + // name of the mesh material if ( mesh.material && mesh.material.name ) { output += 'usemtl ' + mesh.material.name + '\n'; - } // vertices + } + // vertices if ( vertices !== undefined ) { for ( let i = 0, l = vertices.count; i < l; i ++, nbVertex ++ ) { - vertex.fromBufferAttribute( vertices, i ); // transform the vertex to world space + vertex.fromBufferAttribute( vertices, i ); - vertex.applyMatrix4( mesh.matrixWorld ); // transform the vertex to export format + // transform the vertex to world space + vertex.applyMatrix4( mesh.matrixWorld ); + // transform the vertex to export format output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n'; } - } // uvs + } + // uvs if ( uvs !== undefined ) { for ( let i = 0, l = uvs.count; i < l; i ++, nbVertexUvs ++ ) { - uv.fromBufferAttribute( uvs, i ); // transform the uv to export format + uv.fromBufferAttribute( uvs, i ); + // transform the uv to export format output += 'vt ' + uv.x + ' ' + uv.y + '\n'; } - } // normals + } + // normals if ( normals !== undefined ) { normalMatrixWorld.getNormalMatrix( mesh.matrixWorld ); - for ( let i = 0, l = normals.count; i < l; i ++, nbNormals ++ ) { - normal.fromBufferAttribute( normals, i ); // transform the normal to world space + normal.fromBufferAttribute( normals, i ); - normal.applyMatrix3( normalMatrixWorld ).normalize(); // transform the normal to export format + // transform the normal to world space + normal.applyMatrix3( normalMatrixWorld ).normalize(); + // transform the normal to export format output += 'vn ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n'; } - } // faces + } + // faces if ( indices !== null ) { @@ -97,9 +100,9 @@ const j = indices.getX( i + m ) + 1; face[ m ] = indexVertex + j + ( normals || uvs ? '/' + ( uvs ? indexVertexUvs + j : '' ) + ( normals ? '/' + ( indexNormals + j ) : '' ) : '' ); - } // transform the face to export format - + } + // transform the face to export format output += 'f ' + face.join( ' ' ) + '\n'; } @@ -113,16 +116,16 @@ const j = i + m + 1; face[ m ] = indexVertex + j + ( normals || uvs ? '/' + ( uvs ? indexVertexUvs + j : '' ) + ( normals ? '/' + ( indexNormals + j ) : '' ) : '' ); - } // transform the face to export format - + } + // transform the face to export format output += 'f ' + face.join( ' ' ) + '\n'; } - } // update index - + } + // update index indexVertex += nbVertex; indexVertexUvs += nbVertexUvs; indexNormals += nbNormals; @@ -135,25 +138,21 @@ const geometry = line.geometry; const type = line.type; - if ( geometry.isBufferGeometry !== true ) { - - throw new Error( 'THREE.OBJExporter: Geometry is not of type THREE.BufferGeometry.' ); - - } // shortcuts - - - const vertices = geometry.getAttribute( 'position' ); // name of the line object + // shortcuts + const vertices = geometry.getAttribute( 'position' ); + // name of the line object output += 'o ' + line.name + '\n'; - if ( vertices !== undefined ) { for ( let i = 0, l = vertices.count; i < l; i ++, nbVertex ++ ) { - vertex.fromBufferAttribute( vertices, i ); // transform the vertex to world space + vertex.fromBufferAttribute( vertices, i ); - vertex.applyMatrix4( line.matrixWorld ); // transform the vertex to export format + // transform the vertex to world space + vertex.applyMatrix4( line.matrixWorld ); + // transform the vertex to export format output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n'; } @@ -163,7 +162,6 @@ if ( type === 'Line' ) { output += 'l '; - for ( let j = 1, l = vertices.count; j <= l; j ++ ) { output += indexVertex + j + ' '; @@ -182,9 +180,9 @@ } - } // update index - + } + // update index indexVertex += nbVertex; } @@ -193,17 +191,9 @@ let nbVertex = 0; const geometry = points.geometry; - - if ( geometry.isBufferGeometry !== true ) { - - throw new Error( 'THREE.OBJExporter: Geometry is not of type THREE.BufferGeometry.' ); - - } - const vertices = geometry.getAttribute( 'position' ); const colors = geometry.getAttribute( 'color' ); output += 'o ' + points.name + '\n'; - if ( vertices !== undefined ) { for ( let i = 0, l = vertices.count; i < l; i ++, nbVertex ++ ) { @@ -211,7 +201,6 @@ vertex.fromBufferAttribute( vertices, i ); vertex.applyMatrix4( points.matrixWorld ); output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z; - if ( colors !== undefined ) { color.fromBufferAttribute( colors, i ).convertLinearToSRGB(); @@ -224,7 +213,6 @@ } output += 'p '; - for ( let j = 1, l = vertices.count; j <= l; j ++ ) { output += indexVertex + j + ' '; @@ -233,9 +221,9 @@ output += '\n'; - } // update index - + } + // update index indexVertex += nbVertex; } diff --git a/examples/js/exporters/PLYExporter.js b/examples/js/exporters/PLYExporter.js index d9145f6ae26530..16bd63d3be090b 100644 --- a/examples/js/exporters/PLYExporter.js +++ b/examples/js/exporters/PLYExporter.js @@ -17,30 +17,15 @@ parse( object, onDone, options ) { - if ( onDone && typeof onDone === 'object' ) { - - console.warn( 'THREE.PLYExporter: The options parameter is now the third argument to the "parse" function. See the documentation for the new API.' ); - options = onDone; - onDone = undefined; - - } // Iterate over the valid meshes in the object - - + // Iterate over the valid meshes in the object function traverseMeshes( cb ) { object.traverse( function ( child ) { - if ( child.isMesh === true ) { + if ( child.isMesh === true || child.isPoints ) { const mesh = child; const geometry = mesh.geometry; - - if ( geometry.isBufferGeometry !== true ) { - - throw new Error( 'THREE.PLYExporter: Geometry is not of type THREE.BufferGeometry.' ); - - } - if ( geometry.hasAttribute( 'position' ) === true ) { cb( mesh, geometry ); @@ -51,9 +36,9 @@ } ); - } // Default options - + } + // Default options const defaultOptions = { binary: false, excludeAttributes: [], @@ -62,11 +47,13 @@ }; options = Object.assign( defaultOptions, options ); const excludeAttributes = options.excludeAttributes; + let includeIndices = true; let includeNormals = false; let includeColors = false; - let includeUVs = false; // count the vertices, check which properties are used, - // and cache the BufferGeometry + let includeUVs = false; + // count the vertices, check which properties are used, + // and cache the BufferGeometry let vertexCount = 0; let faceCount = 0; object.traverse( function ( child ) { @@ -75,19 +62,11 @@ const mesh = child; const geometry = mesh.geometry; - - if ( geometry.isBufferGeometry !== true ) { - - throw new Error( 'THREE.PLYExporter: Geometry is not of type THREE.BufferGeometry.' ); - - } - const vertices = geometry.getAttribute( 'position' ); const normals = geometry.getAttribute( 'normal' ); const uvs = geometry.getAttribute( 'uv' ); const colors = geometry.getAttribute( 'color' ); const indices = geometry.getIndex(); - if ( vertices === undefined ) { return; @@ -100,15 +79,22 @@ if ( uvs !== undefined ) includeUVs = true; if ( colors !== undefined ) includeColors = true; + } else if ( child.isPoints ) { + + const mesh = child; + const geometry = mesh.geometry; + const vertices = geometry.getAttribute( 'position' ); + vertexCount += vertices.count; + includeIndices = false; + } } ); const tempColor = new THREE.Color(); - const includeIndices = excludeAttributes.indexOf( 'index' ) === - 1; + includeIndices = includeIndices && excludeAttributes.indexOf( 'index' ) === - 1; includeNormals = includeNormals && excludeAttributes.indexOf( 'normal' ) === - 1; includeColors = includeColors && excludeAttributes.indexOf( 'color' ) === - 1; includeUVs = includeUVs && excludeAttributes.indexOf( 'uv' ) === - 1; - if ( includeIndices && faceCount !== Math.floor( faceCount ) ) { // point cloud meshes will not have an index array and may not have a @@ -120,9 +106,9 @@ } const indexByteCount = 4; - let header = 'ply\n' + `format ${options.binary ? options.littleEndian ? 'binary_little_endian' : 'binary_big_endian' : 'ascii'} 1.0\n` + `element vertex ${vertexCount}\n` + // position + let header = 'ply\n' + `format ${options.binary ? options.littleEndian ? 'binary_little_endian' : 'binary_big_endian' : 'ascii'} 1.0\n` + `element vertex ${vertexCount}\n` + + // position 'property float x\n' + 'property float y\n' + 'property float z\n'; - if ( includeNormals === true ) { // normal @@ -151,23 +137,25 @@ } - header += 'end_header\n'; // Generate attribute data + header += 'end_header\n'; + // Generate attribute data const vertex = new THREE.Vector3(); const normalMatrixWorld = new THREE.Matrix3(); let result = null; - if ( options.binary === true ) { // Binary File Generation - const headerBin = new TextEncoder().encode( header ); // 3 position values at 4 bytes + const headerBin = new TextEncoder().encode( header ); + + // 3 position values at 4 bytes // 3 normal values at 4 bytes // 3 color channels with 1 byte // 2 uv values at 4 bytes + const vertexListLength = vertexCount * ( 4 * 3 + ( includeNormals ? 4 * 3 : 0 ) + ( includeColors ? 3 : 0 ) + ( includeUVs ? 4 * 2 : 0 ) ); - const vertexListLength = vertexCount * ( 4 * 3 + ( includeNormals ? 4 * 3 : 0 ) + ( includeColors ? 3 : 0 ) + ( includeUVs ? 4 * 2 : 0 ) ); // 1 byte shape desciptor + // 1 byte shape desciptor // 3 vertex indices at ${indexByteCount} bytes - const faceListLength = includeIndices ? faceCount * ( indexByteCount * 3 + 1 ) : 0; const output = new DataView( new ArrayBuffer( headerBin.length + vertexListLength + faceListLength ) ); new Uint8Array( output.buffer ).set( headerBin, 0 ); @@ -182,19 +170,20 @@ const colors = geometry.getAttribute( 'color' ); const indices = geometry.getIndex(); normalMatrixWorld.getNormalMatrix( mesh.matrixWorld ); - for ( let i = 0, l = vertices.count; i < l; i ++ ) { vertex.fromBufferAttribute( vertices, i ); - vertex.applyMatrix4( mesh.matrixWorld ); // Position information + vertex.applyMatrix4( mesh.matrixWorld ); + // Position information output.setFloat32( vOffset, vertex.x, options.littleEndian ); vOffset += 4; output.setFloat32( vOffset, vertex.y, options.littleEndian ); vOffset += 4; output.setFloat32( vOffset, vertex.z, options.littleEndian ); - vOffset += 4; // Normal information + vOffset += 4; + // Normal information if ( includeNormals === true ) { if ( normals != null ) { @@ -219,9 +208,9 @@ } - } // UV information - + } + // UV information if ( includeUVs === true ) { if ( uvs != null ) { @@ -240,9 +229,9 @@ } - } // THREE.Color information - + } + // THREE.Color information if ( includeColors === true ) { if ( colors != null ) { @@ -273,6 +262,7 @@ if ( includeIndices === true ) { // Create the face list + if ( indices !== null ) { for ( let i = 0, l = indices.count; i < l; i += 3 ) { @@ -305,10 +295,10 @@ } - } // Save the amount of verts we've already written so we can offset - // the face index on the next mesh - + } + // Save the amount of verts we've already written so we can offset + // the face index on the next mesh writtenVertices += vertices.count; } ); @@ -328,15 +318,18 @@ const uvs = geometry.getAttribute( 'uv' ); const colors = geometry.getAttribute( 'color' ); const indices = geometry.getIndex(); - normalMatrixWorld.getNormalMatrix( mesh.matrixWorld ); // form each line + normalMatrixWorld.getNormalMatrix( mesh.matrixWorld ); + // form each line for ( let i = 0, l = vertices.count; i < l; i ++ ) { vertex.fromBufferAttribute( vertices, i ); - vertex.applyMatrix4( mesh.matrixWorld ); // Position information + vertex.applyMatrix4( mesh.matrixWorld ); - let line = vertex.x + ' ' + vertex.y + ' ' + vertex.z; // Normal information + // Position information + let line = vertex.x + ' ' + vertex.y + ' ' + vertex.z; + // Normal information if ( includeNormals === true ) { if ( normals != null ) { @@ -351,9 +344,9 @@ } - } // UV information - + } + // UV information if ( includeUVs === true ) { if ( uvs != null ) { @@ -366,9 +359,9 @@ } - } // THREE.Color information - + } + // THREE.Color information if ( includeColors === true ) { if ( colors != null ) { @@ -386,9 +379,9 @@ vertexList += line + '\n'; - } // Create the face list - + } + // Create the face list if ( includeIndices === true ) { if ( indices !== null ) { diff --git a/examples/js/exporters/STLExporter.js b/examples/js/exporters/STLExporter.js index a85e18d907937b..774f54cd89ce7c 100644 --- a/examples/js/exporters/STLExporter.js +++ b/examples/js/exporters/STLExporter.js @@ -13,7 +13,9 @@ parse( scene, options = {} ) { - const binary = options.binary !== undefined ? options.binary : false; // + const binary = options.binary !== undefined ? options.binary : false; + + // const objects = []; let triangles = 0; @@ -22,13 +24,6 @@ if ( object.isMesh ) { const geometry = object.geometry; - - if ( geometry.isBufferGeometry !== true ) { - - throw new Error( 'THREE.STLExporter: Geometry is not of type THREE.BufferGeometry.' ); - - } - const index = geometry.index; const positionAttribute = geometry.getAttribute( 'position' ); triangles += index !== null ? index.count / 3 : positionAttribute.count / 3; @@ -64,17 +59,16 @@ const cb = new THREE.Vector3(); const ab = new THREE.Vector3(); const normal = new THREE.Vector3(); - for ( let i = 0, il = objects.length; i < il; i ++ ) { const object = objects[ i ].object3d; const geometry = objects[ i ].geometry; const index = geometry.index; const positionAttribute = geometry.getAttribute( 'position' ); - if ( index !== null ) { // indexed geometry + for ( let j = 0; j < index.count; j += 3 ) { const a = index.getX( j + 0 ); @@ -87,6 +81,7 @@ } else { // non-indexed geometry + for ( let j = 0; j < positionAttribute.count; j += 3 ) { const a = j + 0; @@ -107,13 +102,11 @@ } return output; - function writeFace( a, b, c, positionAttribute, object ) { vA.fromBufferAttribute( positionAttribute, a ); vB.fromBufferAttribute( positionAttribute, b ); vC.fromBufferAttribute( positionAttribute, c ); - if ( object.isSkinnedMesh === true ) { object.boneTransform( a, vA ); @@ -129,7 +122,6 @@ writeVertex( vA ); writeVertex( vB ); writeVertex( vC ); - if ( binary === true ) { output.setUint16( offset, 0, true ); @@ -150,7 +142,6 @@ ab.subVectors( vA, vB ); cb.cross( ab ).normalize(); normal.copy( cb ).normalize(); - if ( binary === true ) { output.setFloat32( offset, normal.x, true ); diff --git a/examples/js/exporters/USDZExporter.js b/examples/js/exporters/USDZExporter.js index bd03aaf460ac13..9c83429ccd6006 100644 --- a/examples/js/exporters/USDZExporter.js +++ b/examples/js/exporters/USDZExporter.js @@ -2,25 +2,35 @@ class USDZExporter { - async parse( scene ) { + async parse( scene, options = { + ar: { + anchoring: { + type: 'plane' + }, + planeAnchoring: { + alignment: 'horizontal' + } + } + } ) { const files = {}; - const modelFileName = 'model.usda'; // model file should be first in USDZ archive so we init it here + const modelFileName = 'model.usda'; + // model file should be first in USDZ archive so we init it here files[ modelFileName ] = null; let output = buildHeader(); + output += buildSceneStart( options ); const materials = {}; const textures = {}; scene.traverseVisible( object => { if ( object.isMesh ) { - if ( object.material.isMeshStandardMaterial ) { + const geometry = object.geometry; + const material = object.material; + if ( material.isMeshStandardMaterial ) { - const geometry = object.geometry; - const material = object.material; const geometryFileName = 'geometries/Geometry_' + geometry.id + '.usd'; - if ( ! ( geometryFileName in files ) ) { const meshObject = buildMeshObject( geometry ); @@ -42,13 +52,17 @@ } + } else if ( object.isCamera ) { + + output += buildCamera( object ); + } } ); + output += buildSceneEnd(); output += buildMaterials( materials, textures ); files[ modelFileName ] = fflate.strToU8( output ); output = null; - for ( const id in textures ) { const texture = textures[ id ]; @@ -58,19 +72,18 @@ const blob = await new Promise( resolve => canvas.toBlob( resolve, isRGBA ? 'image/png' : 'image/jpeg', 1 ) ); files[ `textures/Texture_${id}.${isRGBA ? 'png' : 'jpg'}` ] = new Uint8Array( await blob.arrayBuffer() ); - } // 64 byte alignment - // https://github.com/101arrowz/fflate/issues/39#issuecomment-777263109 + } + // 64 byte alignment + // https://github.com/101arrowz/fflate/issues/39#issuecomment-777263109 let offset = 0; - for ( const filename in files ) { const file = files[ filename ]; const headerSize = 34 + filename.length; offset += headerSize; const offsetMod64 = offset & 63; - if ( offsetMod64 !== 4 ) { const padLength = 64 - offsetMod64; @@ -94,7 +107,6 @@ } } - function imageToCanvas( image, color ) { if ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof OffscreenCanvas !== 'undefined' && image instanceof OffscreenCanvas || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) { @@ -105,7 +117,6 @@ canvas.height = image.height * Math.min( 1, scale ); const context = canvas.getContext( '2d' ); context.drawImage( image, 0, 0, canvas.width, canvas.height ); - if ( color !== undefined ) { const hex = parseInt( color, 16 ); @@ -114,7 +125,6 @@ const b = ( hex & 255 ) / 255; const imagedata = context.getImageData( 0, 0, canvas.width, canvas.height ); const data = imagedata.data; - for ( let i = 0; i < data.length; i += 4 ) { data[ i + 0 ] = data[ i + 0 ] * r; @@ -131,11 +141,11 @@ } - } // + } + // const PRECISION = 7; - function buildHeader() { return `#usda 1.0 @@ -147,6 +157,40 @@ upAxis = "Y" ) +`; + + } + + function buildSceneStart( options ) { + + return `def Xform "Root" +{ + def Scope "Scenes" ( + kind = "sceneLibrary" + ) + { + def Xform "Scene" ( + customData = { + bool preliminary_collidesWithEnvironment = 0 + string sceneName = "Scene" + } + sceneName = "Scene" + ) + { + token preliminary:anchoring:type = "${options.ar.anchoring.type}" + token preliminary:planeAnchoring:alignment = "${options.ar.planeAnchoring.alignment}" + +`; + + } + + function buildSceneEnd() { + + return ` + } + } +} + `; } @@ -157,14 +201,14 @@ output += dataToInsert; return fflate.strToU8( output ); - } // Xform + } + // Xform function buildXform( object, geometry, material ) { const name = 'Object_' + object.id; const transform = buildMatrix( object.matrixWorld ); - if ( object.matrixWorld.determinant() < 0 ) { console.warn( 'THREE.USDZExporter: USDZ does not support negative scales', object ); @@ -196,8 +240,9 @@ return `(${array[ offset + 0 ]}, ${array[ offset + 1 ]}, ${array[ offset + 2 ]}, ${array[ offset + 3 ]})`; - } // Mesh + } + // Mesh function buildMeshObject( geometry ) { @@ -245,7 +290,6 @@ def "Geometry" const index = geometry.index; const array = []; - if ( index !== null ) { for ( let i = 0; i < index.count; i ++ ) { @@ -257,7 +301,6 @@ def "Geometry" } else { const length = geometry.attributes.position.count; - for ( let i = 0; i < length; i ++ ) { array.push( i ); @@ -280,7 +323,6 @@ def "Geometry" } const array = []; - for ( let i = 0; i < attribute.count; i ++ ) { const x = attribute.getX( i ); @@ -304,7 +346,6 @@ def "Geometry" } const array = []; - for ( let i = 0; i < attribute.count; i ++ ) { const x = attribute.getX( i ); @@ -315,13 +356,13 @@ def "Geometry" return array.join( ', ' ); - } // Materials + } + // Materials function buildMaterials( materials, textures ) { const array = []; - for ( const uuid in materials ) { const material = materials[ uuid ]; @@ -341,10 +382,10 @@ ${array.join( '' )} function buildMaterial( material, textures ) { // https://graphics.pixar.com/usd/docs/UsdPreviewSurface-Proposal.html + const pad = ' '; const inputs = []; const samplers = []; - function buildTexture( texture, mapType, color ) { const id = texture.id + ( color ? '_' + color.getHexString() : '' ); @@ -389,7 +430,6 @@ ${array.join( '' )} if ( material.map !== null ) { inputs.push( `${pad}color3f inputs:diffuseColor.connect = ` ); - if ( material.transparent ) { inputs.push( `${pad}float inputs:opacity.connect = ` ); @@ -517,6 +557,52 @@ ${samplers.join( '\n' )} } + function buildCamera( camera ) { + + const name = camera.name ? camera.name : 'Camera_' + camera.id; + const transform = buildMatrix( camera.matrixWorld ); + if ( camera.matrixWorld.determinant() < 0 ) { + + console.warn( 'THREE.USDZExporter: USDZ does not support negative scales', camera ); + + } + + if ( camera.isOrthographicCamera ) { + + return `def Camera "${name}" + { + matrix4d xformOp:transform = ${transform} + uniform token[] xformOpOrder = ["xformOp:transform"] + + float2 clippingRange = (${camera.near.toPrecision( PRECISION )}, ${camera.far.toPrecision( PRECISION )}) + float horizontalAperture = ${( ( Math.abs( camera.left ) + Math.abs( camera.right ) ) * 10 ).toPrecision( PRECISION )} + float verticalAperture = ${( ( Math.abs( camera.top ) + Math.abs( camera.bottom ) ) * 10 ).toPrecision( PRECISION )} + token projection = "orthographic" + } + + `; + + } else { + + return `def Camera "${name}" + { + matrix4d xformOp:transform = ${transform} + uniform token[] xformOpOrder = ["xformOp:transform"] + + float2 clippingRange = (${camera.near.toPrecision( PRECISION )}, ${camera.far.toPrecision( PRECISION )}) + float focalLength = ${camera.getFocalLength().toPrecision( PRECISION )} + float focusDistance = ${camera.focus.toPrecision( PRECISION )} + float horizontalAperture = ${camera.getFilmWidth().toPrecision( PRECISION )} + token projection = "perspective" + float verticalAperture = ${camera.getFilmHeight().toPrecision( PRECISION )} + } + + `; + + } + + } + THREE.USDZExporter = USDZExporter; } )(); diff --git a/examples/js/geometries/BoxLineGeometry.js b/examples/js/geometries/BoxLineGeometry.js index 97a1ec33407568..8844dedadd035f 100644 --- a/examples/js/geometries/BoxLineGeometry.js +++ b/examples/js/geometries/BoxLineGeometry.js @@ -18,7 +18,6 @@ let x = - widthHalf; let y = - heightHalf; let z = - depthHalf; - for ( let i = 0; i <= widthSegments; i ++ ) { vertices.push( x, - heightHalf, - depthHalf, x, heightHalf, - depthHalf ); diff --git a/examples/js/geometries/ConvexGeometry.js b/examples/js/geometries/ConvexGeometry.js index 42d5be8876ae19..d4b9743933b5e4 100644 --- a/examples/js/geometries/ConvexGeometry.js +++ b/examples/js/geometries/ConvexGeometry.js @@ -4,25 +4,29 @@ constructor( points = [] ) { - super(); // buffers + super(); + + // buffers const vertices = []; const normals = []; - if ( THREE.ConvexHull === undefined ) { - console.error( 'THREE.ConvexBufferGeometry: ConvexBufferGeometry relies on THREE.ConvexHull' ); + console.error( 'THREE.ConvexGeometry: ConvexGeometry relies on THREE.ConvexHull' ); } - const convexHull = new THREE.ConvexHull().setFromPoints( points ); // generate vertices and normals + const convexHull = new THREE.ConvexHull().setFromPoints( points ); - const faces = convexHull.faces; + // generate vertices and normals + const faces = convexHull.faces; for ( let i = 0; i < faces.length; i ++ ) { const face = faces[ i ]; - let edge = face.edge; // we move along a doubly-connected edge list to access all face points (see HalfEdge docs) + let edge = face.edge; + + // we move along a doubly-connected edge list to access all face points (see HalfEdge docs) do { @@ -33,8 +37,9 @@ } while ( edge !== face.edge ); - } // build geometry + } + // build geometry this.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); this.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); diff --git a/examples/js/geometries/DecalGeometry.js b/examples/js/geometries/DecalGeometry.js index 156f4d638bd25c..708d18297226b4 100644 --- a/examples/js/geometries/DecalGeometry.js +++ b/examples/js/geometries/DecalGeometry.js @@ -19,35 +19,48 @@ constructor( mesh, position, orientation, size ) { - super(); // buffers + super(); + + // buffers const vertices = []; const normals = []; - const uvs = []; // helpers + const uvs = []; + + // helpers - const plane = new THREE.Vector3(); // this matrix represents the transformation of the decal projector + const plane = new THREE.Vector3(); + + // this matrix represents the transformation of the decal projector const projectorMatrix = new THREE.Matrix4(); projectorMatrix.makeRotationFromEuler( orientation ); projectorMatrix.setPosition( position ); const projectorMatrixInverse = new THREE.Matrix4(); - projectorMatrixInverse.copy( projectorMatrix ).invert(); // generate buffers + projectorMatrixInverse.copy( projectorMatrix ).invert(); + + // generate buffers - generate(); // build geometry + generate(); + + // build geometry this.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); this.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); this.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); - function generate() { let decalVertices = []; const vertex = new THREE.Vector3(); - const normal = new THREE.Vector3(); // handle different geometry types + const normal = new THREE.Vector3(); + + // handle different geometry types const geometry = mesh.geometry; const positionAttribute = geometry.attributes.position; - const normalAttribute = geometry.attributes.normal; // first, create an array of 'DecalVertex' objects + const normalAttribute = geometry.attributes.normal; + + // first, create an array of 'DecalVertex' objects // three consecutive 'DecalVertex' objects represent a single face // // this data structure will be later used to perform the clipping @@ -55,8 +68,8 @@ if ( geometry.index !== null ) { // indexed THREE.BufferGeometry - const index = geometry.index; + const index = geometry.index; for ( let i = 0; i < index.count; i ++ ) { vertex.fromBufferAttribute( positionAttribute, index.getX( i ) ); @@ -68,6 +81,7 @@ } else { // non-indexed THREE.BufferGeometry + for ( let i = 0; i < positionAttribute.count; i ++ ) { vertex.fromBufferAttribute( positionAttribute, i ); @@ -76,23 +90,32 @@ } - } // second, clip the geometry so that it doesn't extend out from the projector + } + // second, clip the geometry so that it doesn't extend out from the projector decalVertices = clipGeometry( decalVertices, plane.set( 1, 0, 0 ) ); decalVertices = clipGeometry( decalVertices, plane.set( - 1, 0, 0 ) ); decalVertices = clipGeometry( decalVertices, plane.set( 0, 1, 0 ) ); decalVertices = clipGeometry( decalVertices, plane.set( 0, - 1, 0 ) ); decalVertices = clipGeometry( decalVertices, plane.set( 0, 0, 1 ) ); - decalVertices = clipGeometry( decalVertices, plane.set( 0, 0, - 1 ) ); // third, generate final vertices, normals and uvs + decalVertices = clipGeometry( decalVertices, plane.set( 0, 0, - 1 ) ); + + // third, generate final vertices, normals and uvs for ( let i = 0; i < decalVertices.length; i ++ ) { - const decalVertex = decalVertices[ i ]; // create texture coordinates (we are still in projector space) + const decalVertex = decalVertices[ i ]; + + // create texture coordinates (we are still in projector space) - uvs.push( 0.5 + decalVertex.position.x / size.x, 0.5 + decalVertex.position.y / size.y ); // transform the vertex back to world space + uvs.push( 0.5 + decalVertex.position.x / size.x, 0.5 + decalVertex.position.y / size.y ); - decalVertex.position.applyMatrix4( projectorMatrix ); // now create vertex and normal buffer data + // transform the vertex back to world space + + decalVertex.position.applyMatrix4( projectorMatrix ); + + // now create vertex and normal buffer data vertices.push( decalVertex.position.x, decalVertex.position.y, decalVertex.position.z ); normals.push( decalVertex.normal.x, decalVertex.normal.y, decalVertex.normal.z ); @@ -104,6 +127,7 @@ function pushDecalVertex( decalVertices, vertex, normal ) { // transform the vertex to world space, then to projector space + vertex.applyMatrix4( mesh.matrixWorld ); vertex.applyMatrix4( projectorMatrixInverse ); normal.transformDirection( mesh.matrixWorld ); @@ -114,7 +138,9 @@ function clipGeometry( inVertices, plane ) { const outVertices = []; - const s = 0.5 * Math.abs( size.dot( plane ) ); // a single iteration clips one face, + const s = 0.5 * Math.abs( size.dot( plane ) ); + + // a single iteration clips one face, // which consists of three consecutive 'DecalVertex' objects for ( let i = 0; i < inVertices.length; i += 3 ) { @@ -129,16 +155,18 @@ const d3 = inVertices[ i + 2 ].position.dot( plane ) - s; const v1Out = d1 > 0; const v2Out = d2 > 0; - const v3Out = d3 > 0; // calculate, how many vertices of the face lie outside of the clipping plane + const v3Out = d3 > 0; - total = ( v1Out ? 1 : 0 ) + ( v2Out ? 1 : 0 ) + ( v3Out ? 1 : 0 ); + // calculate, how many vertices of the face lie outside of the clipping plane + total = ( v1Out ? 1 : 0 ) + ( v2Out ? 1 : 0 ) + ( v3Out ? 1 : 0 ); switch ( total ) { case 0: { // the entire face lies inside of the plane, no clipping needed + outVertices.push( inVertices[ i ] ); outVertices.push( inVertices[ i + 1 ] ); outVertices.push( inVertices[ i + 2 ] ); @@ -150,6 +178,7 @@ { // one vertex lies outside of the plane, perform clipping + if ( v1Out ) { nV1 = inVertices[ i + 1 ]; @@ -198,6 +227,7 @@ { // two vertices lies outside of the plane, perform clipping + if ( ! v1Out ) { nV1 = inVertices[ i ].clone(); @@ -239,6 +269,7 @@ { // the entire face lies outside of the plane, so let's discard the corresponding vertices + break; } @@ -256,7 +287,9 @@ const d0 = v0.position.dot( p ) - s; const d1 = v1.position.dot( p ) - s; const s0 = d0 / ( d0 - d1 ); - const v = new DecalVertex( new THREE.Vector3( v0.position.x + s0 * ( v1.position.x - v0.position.x ), v0.position.y + s0 * ( v1.position.y - v0.position.y ), v0.position.z + s0 * ( v1.position.z - v0.position.z ) ), new THREE.Vector3( v0.normal.x + s0 * ( v1.normal.x - v0.normal.x ), v0.normal.y + s0 * ( v1.normal.y - v0.normal.y ), v0.normal.z + s0 * ( v1.normal.z - v0.normal.z ) ) ); // need to clip more values (texture coordinates)? do it this way: + const v = new DecalVertex( new THREE.Vector3( v0.position.x + s0 * ( v1.position.x - v0.position.x ), v0.position.y + s0 * ( v1.position.y - v0.position.y ), v0.position.z + s0 * ( v1.position.z - v0.position.z ) ), new THREE.Vector3( v0.normal.x + s0 * ( v1.normal.x - v0.normal.x ), v0.normal.y + s0 * ( v1.normal.y - v0.normal.y ), v0.normal.z + s0 * ( v1.normal.z - v0.normal.z ) ) ); + + // need to clip more values (texture coordinates)? do it this way: // intersectpoint.value = a.value + s * ( b.value - a.value ); return v; @@ -265,8 +298,9 @@ } - } // helper + } + // helper class DecalVertex { @@ -276,7 +310,6 @@ this.normal = normal; } - clone() { return new this.constructor( this.position.clone(), this.normal.clone() ); diff --git a/examples/js/geometries/LightningStrike.js b/examples/js/geometries/LightningStrike.js index 0a3f2c347f90d4..e32816a24a2428 100644 --- a/examples/js/geometries/LightningStrike.js +++ b/examples/js/geometries/LightningStrike.js @@ -107,19 +107,19 @@ super(); this.isLightningStrike = true; - this.type = 'LightningStrike'; // Set parameters, and set undefined parameters to default values + this.type = 'LightningStrike'; - this.init( LightningStrike.copyParameters( rayParameters, rayParameters ) ); // Creates and populates the mesh + // Set parameters, and set undefined parameters to default values + this.init( LightningStrike.copyParameters( rayParameters, rayParameters ) ); + // Creates and populates the mesh this.createMesh(); } - static createRandomGenerator() { const numSeeds = 2053; const seeds = []; - for ( let i = 0; i < numSeeds; i ++ ) { seeds.push( Math.random() ); @@ -149,7 +149,6 @@ return generator; } - static copyParameters( dest = {}, source = {} ) { const vecCopy = function ( v ) { @@ -167,8 +166,12 @@ }; dest.sourceOffset = source.sourceOffset !== undefined ? vecCopy( source.sourceOffset ) : new THREE.Vector3( 0, 100, 0 ), dest.destOffset = source.destOffset !== undefined ? vecCopy( source.destOffset ) : new THREE.Vector3( 0, 0, 0 ), dest.timeScale = source.timeScale !== undefined ? source.timeScale : 1, dest.roughness = source.roughness !== undefined ? source.roughness : 0.9, dest.straightness = source.straightness !== undefined ? source.straightness : 0.7, dest.up0 = source.up0 !== undefined ? vecCopy( source.up0 ) : new THREE.Vector3( 0, 0, 1 ); - dest.up1 = source.up1 !== undefined ? vecCopy( source.up1 ) : new THREE.Vector3( 0, 0, 1 ), dest.radius0 = source.radius0 !== undefined ? source.radius0 : 1, dest.radius1 = source.radius1 !== undefined ? source.radius1 : 1, dest.radius0Factor = source.radius0Factor !== undefined ? source.radius0Factor : 0.5, dest.radius1Factor = source.radius1Factor !== undefined ? source.radius1Factor : 0.2, dest.minRadius = source.minRadius !== undefined ? source.minRadius : 0.2, // These parameters should not be changed after lightning creation. They can be changed but the ray will change its form abruptly: - dest.isEternal = source.isEternal !== undefined ? source.isEternal : source.birthTime === undefined || source.deathTime === undefined, dest.birthTime = source.birthTime, dest.deathTime = source.deathTime, dest.propagationTimeFactor = source.propagationTimeFactor !== undefined ? source.propagationTimeFactor : 0.1, dest.vanishingTimeFactor = source.vanishingTimeFactor !== undefined ? source.vanishingTimeFactor : 0.9, dest.subrayPeriod = source.subrayPeriod !== undefined ? source.subrayPeriod : 4, dest.subrayDutyCycle = source.subrayDutyCycle !== undefined ? source.subrayDutyCycle : 0.6; // These parameters cannot change after lightning creation: + dest.up1 = source.up1 !== undefined ? vecCopy( source.up1 ) : new THREE.Vector3( 0, 0, 1 ), dest.radius0 = source.radius0 !== undefined ? source.radius0 : 1, dest.radius1 = source.radius1 !== undefined ? source.radius1 : 1, dest.radius0Factor = source.radius0Factor !== undefined ? source.radius0Factor : 0.5, dest.radius1Factor = source.radius1Factor !== undefined ? source.radius1Factor : 0.2, dest.minRadius = source.minRadius !== undefined ? source.minRadius : 0.2, + // These parameters should not be changed after lightning creation. They can be changed but the ray will change its form abruptly: + + dest.isEternal = source.isEternal !== undefined ? source.isEternal : source.birthTime === undefined || source.deathTime === undefined, dest.birthTime = source.birthTime, dest.deathTime = source.deathTime, dest.propagationTimeFactor = source.propagationTimeFactor !== undefined ? source.propagationTimeFactor : 0.1, dest.vanishingTimeFactor = source.vanishingTimeFactor !== undefined ? source.vanishingTimeFactor : 0.9, dest.subrayPeriod = source.subrayPeriod !== undefined ? source.subrayPeriod : 4, dest.subrayDutyCycle = source.subrayDutyCycle !== undefined ? source.subrayDutyCycle : 0.6; + + // These parameters cannot change after lightning creation: dest.maxIterations = source.maxIterations !== undefined ? source.maxIterations : 9; dest.isStatic = source.isStatic !== undefined ? source.isStatic : false; @@ -180,15 +183,12 @@ return dest; } - update( time ) { if ( this.isStatic ) return; - if ( this.rayParameters.isEternal || this.rayParameters.birthTime <= time && time <= this.rayParameters.deathTime ) { this.updateMesh( time ); - if ( time < this.subrays[ 0 ].endPropagationTime ) { this.state = LightningStrike.RAY_PROPAGATING; @@ -208,7 +208,6 @@ } else { this.visible = false; - if ( time < this.rayParameters.birthTime ) { this.state = LightningStrike.RAY_UNBORN; @@ -222,11 +221,13 @@ } } - init( rayParameters ) { // Init all the state from the parameters - this.rayParameters = rayParameters; // These parameters cannot change after lightning creation: + + this.rayParameters = rayParameters; + + // These parameters cannot change after lightning creation: this.maxIterations = rayParameters.maxIterations !== undefined ? Math.floor( rayParameters.maxIterations ) : 9; rayParameters.maxIterations = this.maxIterations; @@ -239,13 +240,13 @@ this.recursionProbability = rayParameters.recursionProbability !== undefined ? rayParameters.recursionProbability : 0.6; rayParameters.recursionProbability = this.recursionProbability; this.generateUVs = rayParameters.generateUVs !== undefined ? rayParameters.generateUVs : false; - rayParameters.generateUVs = this.generateUVs; // Random generator + rayParameters.generateUVs = this.generateUVs; + // Random generator if ( rayParameters.randomGenerator !== undefined ) { this.randomGenerator = rayParameters.randomGenerator; this.seedGenerator = rayParameters.randomGenerator; - if ( rayParameters.noiseSeed !== undefined ) { this.seedGenerator.setSeed( rayParameters.noiseSeed ); @@ -257,9 +258,9 @@ this.randomGenerator = LightningStrike.createRandomGenerator(); this.seedGenerator = Math; - } // Ray creation callbacks - + } + // Ray creation callbacks if ( rayParameters.onDecideSubrayCreation !== undefined ) { this.onDecideSubrayCreation = rayParameters.onDecideSubrayCreation; @@ -267,22 +268,21 @@ } else { this.createDefaultSubrayCreationCallbacks(); - if ( rayParameters.onSubrayCreation !== undefined ) { this.onSubrayCreation = rayParameters.onSubrayCreation; } - } // Internal state + } + // Internal state this.state = LightningStrike.RAY_INITIALIZED; this.maxSubrays = Math.ceil( 1 + Math.pow( this.ramification, Math.max( 0, this.maxSubrayRecursion - 1 ) ) ); rayParameters.maxSubrays = this.maxSubrays; this.maxRaySegments = 2 * ( 1 << this.maxIterations ); this.subrays = []; - for ( let i = 0; i < this.maxSubrays; i ++ ) { this.subrays.push( this.createSubray() ); @@ -290,7 +290,6 @@ } this.raySegments = []; - for ( let i = 0; i < this.maxRaySegments; i ++ ) { this.raySegments.push( this.createSegment() ); @@ -317,8 +316,9 @@ this.uvsAttribute = null; this.simplexX = new THREE.SimplexNoise( this.seedGenerator ); this.simplexY = new THREE.SimplexNoise( this.seedGenerator ); - this.simplexZ = new THREE.SimplexNoise( this.seedGenerator ); // Temp vectors + this.simplexZ = new THREE.SimplexNoise( this.seedGenerator ); + // Temp vectors this.forwards = new THREE.Vector3(); this.forwardsFill = new THREE.Vector3(); this.side = new THREE.Vector3(); @@ -330,7 +330,6 @@ this.cross1 = new THREE.Vector3(); } - createMesh() { const maxDrawableSegmentsPerSubRay = 1 << this.maxIterations; @@ -338,19 +337,17 @@ const maxIndices = 18 * maxDrawableSegmentsPerSubRay * this.maxSubrays; this.vertices = new Float32Array( maxVerts * 3 ); this.indices = new Uint32Array( maxIndices ); - if ( this.generateUVs ) { this.uvs = new Float32Array( maxVerts * 2 ); - } // Populate the mesh - + } + // Populate the mesh this.fillMesh( 0 ); this.setIndex( new THREE.Uint32BufferAttribute( this.indices, 1 ) ); this.positionAttribute = new THREE.Float32BufferAttribute( this.vertices, 3 ); this.setAttribute( 'position', this.positionAttribute ); - if ( this.generateUVs ) { this.uvsAttribute = new THREE.Float32BufferAttribute( new Float32Array( this.uvs ), 2 ); @@ -362,19 +359,17 @@ this.index.usage = THREE.DynamicDrawUsage; this.positionAttribute.usage = THREE.DynamicDrawUsage; - if ( this.generateUVs ) { this.uvsAttribute.usage = THREE.DynamicDrawUsage; } - } // Store buffers for later modification - + } + // Store buffers for later modification this.vertices = this.positionAttribute.array; this.indices = this.index.array; - if ( this.generateUVs ) { this.uvs = this.uvsAttribute.array; @@ -382,14 +377,12 @@ } } - updateMesh( time ) { this.fillMesh( time ); this.drawRange.count = this.currentIndex; this.index.needsUpdate = true; this.positionAttribute.needsUpdate = true; - if ( this.generateUVs ) { this.uvsAttribute.needsUpdate = true; @@ -397,7 +390,6 @@ } } - fillMesh( time ) { const scope = this; @@ -408,15 +400,16 @@ this.fractalRay( time, function fillVertices( segment ) { const subray = scope.currentSubray; - if ( time < subray.birthTime ) { //&& ( ! this.rayParameters.isEternal || scope.currentSubray.recursion > 0 ) ) { + return; } else if ( this.rayParameters.isEternal && scope.currentSubray.recursion == 0 ) { // Eternal rays don't propagate nor vanish, but its subrays do + scope.createPrism( segment ); scope.onDecideSubrayCreation( segment, scope ); @@ -425,6 +418,7 @@ if ( scope.timeFraction >= segment.fraction0 * subray.propagationTimeFactor ) { // Ray propagation has arrived to this segment + scope.createPrism( segment ); scope.onDecideSubrayCreation( segment, scope ); @@ -433,6 +427,7 @@ } else if ( time < subray.beginVanishingTime ) { // Ray is steady (nor propagating nor vanishing) + scope.createPrism( segment ); scope.onDecideSubrayCreation( segment, scope ); @@ -441,6 +436,7 @@ if ( scope.timeFraction <= subray.vanishingTimeFactor + segment.fraction1 * ( 1 - subray.vanishingTimeFactor ) ) { // Segment has not yet vanished + scope.createPrism( segment ); } @@ -452,13 +448,11 @@ } ); } - addNewSubray() { return this.subrays[ this.numSubrays ++ ]; } - initSubray( subray, rayParameters ) { subray.pos0.copy( rayParameters.sourceOffset ); @@ -479,15 +473,16 @@ subray.recursion = 0; } - fractalRay( time, segmentCallback ) { this.time = time; this.currentSegmentCallback = segmentCallback; - this.numSubrays = 0; // Add the top level subray + this.numSubrays = 0; - this.initSubray( this.addNewSubray(), this.rayParameters ); // Process all subrays that are being generated until consuming all of them + // Add the top level subray + this.initSubray( this.addNewSubray(), this.rayParameters ); + // Process all subrays that are being generated until consuming all of them for ( let subrayIndex = 0; subrayIndex < this.numSubrays; subrayIndex ++ ) { const subray = this.subrays[ subrayIndex ]; @@ -523,7 +518,6 @@ this.currentSubray = null; } - fractalRayRecursive( segment ) { // Leave recursion condition @@ -532,12 +526,11 @@ this.currentSegmentCallback( segment ); return; - } // Interpolation - + } + // Interpolation this.forwards.subVectors( segment.pos1, segment.pos0 ); let lForwards = this.forwards.length(); - if ( lForwards < 0.000001 ) { this.forwards.set( 0, 0, 0.01 ); @@ -550,11 +543,14 @@ const timeDimension = this.time * this.currentSubray.timeScale * Math.pow( 2, segment.iteration ); this.middlePos.lerpVectors( segment.pos0, segment.pos1, 0.5 ); this.middleLinPos.lerpVectors( segment.linPos0, segment.linPos1, 0.5 ); - const p = this.middleLinPos; // Noise + const p = this.middleLinPos; + // Noise this.newPos.set( this.simplexX.noise4d( p.x, p.y, p.z, timeDimension ), this.simplexY.noise4d( p.x, p.y, p.z, timeDimension ), this.simplexZ.noise4d( p.x, p.y, p.z, timeDimension ) ); this.newPos.multiplyScalar( segment.positionVariationFactor * lForwards ); - this.newPos.add( this.middlePos ); // Recursion + this.newPos.add( this.middlePos ); + + // Recursion const newSegment1 = this.getNewSegment(); newSegment1.pos0.copy( segment.pos0 ); @@ -587,12 +583,11 @@ this.fractalRayRecursive( newSegment2 ); } - createPrism( segment ) { // Creates one triangular prism and its vertices at the segment - this.forwardsFill.subVectors( segment.pos1, segment.pos0 ).normalize(); + this.forwardsFill.subVectors( segment.pos1, segment.pos0 ).normalize(); if ( this.isInitialSegment ) { this.currentCreateTriangleVertices( segment.pos0, segment.up0, this.forwardsFill, segment.radius0, 0 ); @@ -604,10 +599,10 @@ this.createPrismFaces(); } - createTriangleVerticesWithoutUVs( pos, up, forwards, radius ) { // Create an equilateral triangle (only vertices) + this.side.crossVectors( up, forwards ).multiplyScalar( radius * LightningStrike.COS30DEG ); this.down.copy( up ).multiplyScalar( - radius * LightningStrike.SIN30DEG ); const p = this.vPos; @@ -627,10 +622,10 @@ this.currentVertex += 3; } - createTriangleVerticesWithUVs( pos, up, forwards, radius, u ) { // Create an equilateral triangle (only vertices) + this.side.crossVectors( up, forwards ).multiplyScalar( radius * LightningStrike.COS30DEG ); this.down.copy( up ).multiplyScalar( - radius * LightningStrike.SIN30DEG ); const p = this.vPos; @@ -657,10 +652,7 @@ this.currentVertex += 3; } - - createPrismFaces( vertex - /*, index*/ - ) { + createPrismFaces( vertex /*, index*/ ) { const indices = this.indices; vertex = this.currentVertex - 6; @@ -684,14 +676,13 @@ indices[ this.currentIndex ++ ] = vertex + 5; } - createDefaultSubrayCreationCallbacks() { const random1 = this.randomGenerator.random; - this.onDecideSubrayCreation = function ( segment, lightningStrike ) { // Decide subrays creation at parent (sub)ray segment + const subray = lightningStrike.currentSubray; const period = lightningStrike.rayParameters.subrayPeriod; const dutyCycle = lightningStrike.rayParameters.subrayDutyCycle; @@ -701,10 +692,10 @@ const childSubraySeed = random1() * ( currentCycle + 1 ); const isActive = phase % period <= dutyCycle * period; let probability = 0; - if ( isActive ) { - probability = lightningStrike.subrayProbability; // Distribution test: probability *= segment.fraction0 > 0.5 && segment.fraction0 < 0.9 ? 1 / 0.4 : 0; + probability = lightningStrike.subrayProbability; + // Distribution test: probability *= segment.fraction0 > 0.5 && segment.fraction0 < 0.9 ? 1 / 0.4 : 0; } @@ -724,7 +715,6 @@ childSubray.radius1 = Math.min( lightningStrike.rayParameters.minRadius, segment.radius1 * lightningStrike.rayParameters.radius1Factor ); childSubray.birthTime = phase0 + currentCycle * period; childSubray.deathTime = childSubray.birthTime + period * dutyCycle; - if ( ! lightningStrike.rayParameters.isEternal && subray.recursion == 0 ) { childSubray.birthTime = Math.max( childSubray.birthTime, subray.birthTime ); @@ -748,10 +738,10 @@ const vec2Forward = new THREE.Vector3(); const vec3Side = new THREE.Vector3(); const vec4Up = new THREE.Vector3(); - this.onSubrayCreation = function ( segment, parentSubray, childSubray, lightningStrike ) { // Decide childSubray origin and destination positions (pos0 and pos1) and possibly other properties of childSubray + // Just use the default cone position generator lightningStrike.subrayCylinderPosition( segment, parentSubray, childSubray, 0.5, 0.6, 0.2 ); @@ -760,6 +750,7 @@ this.subrayConePosition = function ( segment, parentSubray, childSubray, heightFactor, sideWidthFactor, minSideWidthFactor ) { // Sets childSubray pos0 and pos1 in a cone + childSubray.pos0.copy( segment.pos0 ); vec1Pos.subVectors( parentSubray.pos1, parentSubray.pos0 ); vec2Forward.copy( vec1Pos ).normalize(); @@ -776,6 +767,7 @@ this.subrayCylinderPosition = function ( segment, parentSubray, childSubray, heightFactor, sideWidthFactor, minSideWidthFactor ) { // Sets childSubray pos0 and pos1 in a cylinder + childSubray.pos0.copy( segment.pos0 ); vec1Pos.subVectors( parentSubray.pos1, parentSubray.pos0 ); vec2Forward.copy( vec1Pos ).normalize(); @@ -790,7 +782,6 @@ }; } - createSubray() { return { @@ -817,7 +808,6 @@ }; } - createSegment() { return { @@ -836,13 +826,11 @@ }; } - getNewSegment() { return this.raySegments[ this.currentSegmentIndex ++ ]; } - copy( source ) { super.copy( source ); @@ -850,16 +838,15 @@ return this; } - clone() { return new this.constructor( LightningStrike.copyParameters( {}, this.rayParameters ) ); } - } // Ray states - + } + // Ray states LightningStrike.RAY_INITIALIZED = 0; LightningStrike.RAY_UNBORN = 1; LightningStrike.RAY_PROPAGATING = 2; diff --git a/examples/js/geometries/ParametricGeometries.js b/examples/js/geometries/ParametricGeometries.js index 5791c3cdab6ac5..d808a50b83629e 100644 --- a/examples/js/geometries/ParametricGeometries.js +++ b/examples/js/geometries/ParametricGeometries.js @@ -11,7 +11,6 @@ v *= 2 * Math.PI; u = u * 2; let x, z; - if ( u < Math.PI ) { x = 3 * Math.cos( u ) * ( 1 + Math.sin( u ) ) + 2 * ( 1 - Math.cos( u ) / 2 ) * Math.cos( u ) * Math.cos( v ); @@ -56,6 +55,7 @@ mobius3d: function ( u, t, target ) { // volumetric mobius strip + u *= Math.PI; t *= 2 * Math.PI; u = u * 2; @@ -71,6 +71,7 @@ } }; + /********************************************* * * Parametric Replacement for TubeGeometry @@ -87,7 +88,6 @@ normals = frames.normals, binormals = frames.binormals; const position = new THREE.Vector3(); - function ParametricTube( u, v, target ) { v *= 2 * Math.PI; @@ -96,7 +96,6 @@ const normal = normals[ i ]; const binormal = binormals[ i ]; const cx = - radius * Math.cos( v ); // TODO: Hack: Negating it so it faces outside. - const cy = radius * Math.sin( v ); position.x += cx * normal.x + cy * binormal.x; position.y += cx * normal.y + cy * binormal.y; @@ -105,7 +104,9 @@ } - super( ParametricTube, segments, segmentsRadius ); // proxy internals + super( ParametricTube, segments, segmentsRadius ); + + // proxy internals this.tangents = tangents; this.normals = normals; @@ -119,12 +120,12 @@ } }; + /********************************************* * * Parametric Replacement for TorusKnotGeometry * *********************************************/ - ParametricGeometries.TorusKnotGeometry = class TorusKnotGeometry extends ParametricGeometries.TubeGeometry { constructor( radius = 200, tube = 40, segmentsT = 64, segmentsR = 8, p = 2, q = 3 ) { @@ -144,7 +145,6 @@ } } - const segments = segmentsT; const radiusSegments = segmentsR; const extrudePath = new TorusKnotCurve(); @@ -159,12 +159,12 @@ } }; + /********************************************* * * Parametric Replacement for SphereGeometry * *********************************************/ - ParametricGeometries.SphereGeometry = class SphereGeometry extends THREE.ParametricGeometry { constructor( size, u, v ) { @@ -185,6 +185,7 @@ } }; + /********************************************* * * Parametric Replacement for PlaneGeometry diff --git a/examples/js/geometries/ParametricGeometry.js b/examples/js/geometries/ParametricGeometry.js index d7ccc4a1b603c3..c026b1fdca14f5 100644 --- a/examples/js/geometries/ParametricGeometry.js +++ b/examples/js/geometries/ParametricGeometry.js @@ -4,7 +4,6 @@ * Parametric Surfaces Geometry * based on the brilliant article by @prideout https://prideout.net/blog/old/blog/index.html@p=44.html */ - class ParametricGeometry extends THREE.BufferGeometry { constructor( func = ( u, v, target ) => target.set( u, v, Math.cos( u ) * Math.sin( v ) ), slices = 8, stacks = 8 ) { @@ -15,7 +14,9 @@ func: func, slices: slices, stacks: stacks - }; // buffers + }; + + // buffers const indices = []; const vertices = []; @@ -28,25 +29,23 @@ const pu = new THREE.Vector3(), pv = new THREE.Vector3(); - if ( func.length < 3 ) { - - console.error( 'THREE.ParametricGeometry: Function must now modify a THREE.Vector3 as third parameter.' ); - - } // generate vertices, normals and uvs - + // generate vertices, normals and uvs const sliceCount = slices + 1; - for ( let i = 0; i <= stacks; i ++ ) { const v = i / stacks; - for ( let j = 0; j <= slices; j ++ ) { - const u = j / slices; // vertex + const u = j / slices; + + // vertex func( u, v, p0 ); - vertices.push( p0.x, p0.y, p0.z ); // normal + vertices.push( p0.x, p0.y, p0.z ); + + // normal + // approximate tangent vectors via finite differences if ( u - EPS >= 0 ) { @@ -71,18 +70,22 @@ func( u, v + EPS, p1 ); pv.subVectors( p1, p0 ); - } // cross product of tangent vectors returns surface normal + } + // cross product of tangent vectors returns surface normal normal.crossVectors( pu, pv ).normalize(); - normals.push( normal.x, normal.y, normal.z ); // uv + normals.push( normal.x, normal.y, normal.z ); + + // uv uvs.push( u, v ); } - } // generate indices + } + // generate indices for ( let i = 0; i < stacks; i ++ ) { @@ -91,15 +94,18 @@ const a = i * sliceCount + j; const b = i * sliceCount + j + 1; const c = ( i + 1 ) * sliceCount + j + 1; - const d = ( i + 1 ) * sliceCount + j; // faces one and two + const d = ( i + 1 ) * sliceCount + j; + + // faces one and two indices.push( a, b, d ); indices.push( b, c, d ); } - } // build geometry + } + // build geometry this.setIndex( indices ); this.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); diff --git a/examples/js/geometries/RoundedBoxGeometry.js b/examples/js/geometries/RoundedBoxGeometry.js index 883cea47bc0041..fe9e18e0354867 100644 --- a/examples/js/geometries/RoundedBoxGeometry.js +++ b/examples/js/geometries/RoundedBoxGeometry.js @@ -1,25 +1,24 @@ ( function () { const _tempNormal = new THREE.Vector3(); - function getUv( faceDirVector, normal, uvAxis, projectionAxis, radius, sideLength ) { - const totArcLength = 2 * Math.PI * radius / 4; // length of the planes between the arcs on each axis + const totArcLength = 2 * Math.PI * radius / 4; + // length of the planes between the arcs on each axis const centerLength = Math.max( sideLength - 2 * radius, 0 ); - const halfArc = Math.PI / 4; // Get the vector projected onto the Y plane + const halfArc = Math.PI / 4; + // Get the vector projected onto the Y plane _tempNormal.copy( normal ); - _tempNormal[ projectionAxis ] = 0; + _tempNormal.normalize(); - _tempNormal.normalize(); // total amount of UV space alloted to a single arc - - - const arcUvRatio = 0.5 * totArcLength / ( totArcLength + centerLength ); // the distance along one arc the point is at + // total amount of UV space alloted to a single arc + const arcUvRatio = 0.5 * totArcLength / ( totArcLength + centerLength ); + // the distance along one arc the point is at const arcAngleRatio = 1.0 - _tempNormal.angleTo( faceDirVector ) / halfArc; - if ( Math.sign( _tempNormal[ uvAxis ] ) === 1 ) { return arcAngleRatio * arcUvRatio; @@ -39,17 +38,21 @@ constructor( width = 1, height = 1, depth = 1, segments = 2, radius = 0.1 ) { // ensure segments is odd so we have a plane connecting the rounded corners - segments = segments * 2 + 1; // ensure radius isn't bigger than shortest side + segments = segments * 2 + 1; + // ensure radius isn't bigger than shortest side radius = Math.min( width / 2, height / 2, depth / 2, radius ); - super( 1, 1, 1, segments, segments, segments ); // if we just have one segment we're the same as a regular box + super( 1, 1, 1, segments, segments, segments ); + // if we just have one segment we're the same as a regular box if ( segments === 1 ) return; const geometry2 = this.toNonIndexed(); this.index = null; this.attributes.position = geometry2.attributes.position; this.attributes.normal = geometry2.attributes.normal; - this.attributes.uv = geometry2.attributes.uv; // + this.attributes.uv = geometry2.attributes.uv; + + // const position = new THREE.Vector3(); const normal = new THREE.Vector3(); @@ -60,7 +63,6 @@ const faceTris = positions.length / 6; const faceDirVector = new THREE.Vector3(); const halfSegmentSize = 0.5 / segments; - for ( let i = 0, j = 0; i < positions.length; i += 3, j += 2 ) { position.fromArray( positions, i ); @@ -76,51 +78,51 @@ normals[ i + 1 ] = normal.y; normals[ i + 2 ] = normal.z; const side = Math.floor( i / faceTris ); - switch ( side ) { case 0: // right + // generate UVs along Z then Y faceDirVector.set( 1, 0, 0 ); uvs[ j + 0 ] = getUv( faceDirVector, normal, 'z', 'y', radius, depth ); uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'z', radius, height ); break; - case 1: // left + // generate UVs along Z then Y faceDirVector.set( - 1, 0, 0 ); uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'z', 'y', radius, depth ); uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'z', radius, height ); break; - case 2: // top + // generate UVs along X then Z faceDirVector.set( 0, 1, 0 ); uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'z', radius, width ); uvs[ j + 1 ] = getUv( faceDirVector, normal, 'z', 'x', radius, depth ); break; - case 3: // bottom + // generate UVs along X then Z faceDirVector.set( 0, - 1, 0 ); uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'z', radius, width ); uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'z', 'x', radius, depth ); break; - case 4: // front + // generate UVs along X then Y faceDirVector.set( 0, 0, 1 ); uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'y', radius, width ); uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'x', radius, height ); break; - case 5: // back + // generate UVs along X then Y faceDirVector.set( 0, 0, - 1 ); uvs[ j + 0 ] = getUv( faceDirVector, normal, 'x', 'y', radius, width ); diff --git a/examples/js/geometries/TeapotGeometry.js b/examples/js/geometries/TeapotGeometry.js index e5395a23f9df63..3620fcd0103ac3 100644 --- a/examples/js/geometries/TeapotGeometry.js +++ b/examples/js/geometries/TeapotGeometry.js @@ -53,37 +53,35 @@ constructor( size = 50, segments = 10, bottom = true, lid = true, body = true, fitLid = true, blinn = true ) { // 32 * 4 * 4 Bezier spline patches - const teapotPatches = [ - /*rim*/ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 3, 16, 17, 18, 7, 19, 20, 21, 11, 22, 23, 24, 15, 25, 26, 27, 18, 28, 29, 30, 21, 31, 32, 33, 24, 34, 35, 36, 27, 37, 38, 39, 30, 40, 41, 0, 33, 42, 43, 4, 36, 44, 45, 8, 39, 46, 47, 12, - /*body*/ - 12, 13, 14, 15, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 15, 25, 26, 27, 51, 60, 61, 62, 55, 63, 64, 65, 59, 66, 67, 68, 27, 37, 38, 39, 62, 69, 70, 71, 65, 72, 73, 74, 68, 75, 76, 77, 39, 46, 47, 12, 71, 78, 79, 48, 74, 80, 81, 52, 77, 82, 83, 56, 56, 57, 58, 59, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 59, 66, 67, 68, 87, 96, 97, 98, 91, 99, 100, 101, 95, 102, 103, 104, 68, 75, 76, 77, 98, 105, 106, 107, 101, 108, 109, 110, 104, 111, 112, 113, 77, 82, 83, 56, 107, 114, 115, 84, 110, 116, 117, 88, 113, 118, 119, 92, - /*handle*/ - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 123, 136, 137, 120, 127, 138, 139, 124, 131, 140, 141, 128, 135, 142, 143, 132, 132, 133, 134, 135, 144, 145, 146, 147, 148, 149, 150, 151, 68, 152, 153, 154, 135, 142, 143, 132, 147, 155, 156, 144, 151, 157, 158, 148, 154, 159, 160, 68, - /*spout*/ - 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 164, 177, 178, 161, 168, 179, 180, 165, 172, 181, 182, 169, 176, 183, 184, 173, 173, 174, 175, 176, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 176, 183, 184, 173, 188, 197, 198, 185, 192, 199, 200, 189, 196, 201, 202, 193, - /*lid*/ - 203, 203, 203, 203, 204, 205, 206, 207, 208, 208, 208, 208, 209, 210, 211, 212, 203, 203, 203, 203, 207, 213, 214, 215, 208, 208, 208, 208, 212, 216, 217, 218, 203, 203, 203, 203, 215, 219, 220, 221, 208, 208, 208, 208, 218, 222, 223, 224, 203, 203, 203, 203, 221, 225, 226, 204, 208, 208, 208, 208, 224, 227, 228, 209, 209, 210, 211, 212, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 212, 216, 217, 218, 232, 241, 242, 243, 236, 244, 245, 246, 240, 247, 248, 249, 218, 222, 223, 224, 243, 250, 251, 252, 246, 253, 254, 255, 249, 256, 257, 258, 224, 227, 228, 209, 252, 259, 260, 229, 255, 261, 262, 233, 258, 263, 264, 237, - /*bottom*/ + const teapotPatches = [/*rim*/ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 3, 16, 17, 18, 7, 19, 20, 21, 11, 22, 23, 24, 15, 25, 26, 27, 18, 28, 29, 30, 21, 31, 32, 33, 24, 34, 35, 36, 27, 37, 38, 39, 30, 40, 41, 0, 33, 42, 43, 4, 36, 44, 45, 8, 39, 46, 47, 12, /*body*/ + 12, 13, 14, 15, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 15, 25, 26, 27, 51, 60, 61, 62, 55, 63, 64, 65, 59, 66, 67, 68, 27, 37, 38, 39, 62, 69, 70, 71, 65, 72, 73, 74, 68, 75, 76, 77, 39, 46, 47, 12, 71, 78, 79, 48, 74, 80, 81, 52, 77, 82, 83, 56, 56, 57, 58, 59, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 59, 66, 67, 68, 87, 96, 97, 98, 91, 99, 100, 101, 95, 102, 103, 104, 68, 75, 76, 77, 98, 105, 106, 107, 101, 108, 109, 110, 104, 111, 112, 113, 77, 82, 83, 56, 107, 114, 115, 84, 110, 116, 117, 88, 113, 118, 119, 92, /*handle*/ + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 123, 136, 137, 120, 127, 138, 139, 124, 131, 140, 141, 128, 135, 142, 143, 132, 132, 133, 134, 135, 144, 145, 146, 147, 148, 149, 150, 151, 68, 152, 153, 154, 135, 142, 143, 132, 147, 155, 156, 144, 151, 157, 158, 148, 154, 159, 160, 68, /*spout*/ + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 164, 177, 178, 161, 168, 179, 180, 165, 172, 181, 182, 169, 176, 183, 184, 173, 173, 174, 175, 176, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 176, 183, 184, 173, 188, 197, 198, 185, 192, 199, 200, 189, 196, 201, 202, 193, /*lid*/ + 203, 203, 203, 203, 204, 205, 206, 207, 208, 208, 208, 208, 209, 210, 211, 212, 203, 203, 203, 203, 207, 213, 214, 215, 208, 208, 208, 208, 212, 216, 217, 218, 203, 203, 203, 203, 215, 219, 220, 221, 208, 208, 208, 208, 218, 222, 223, 224, 203, 203, 203, 203, 221, 225, 226, 204, 208, 208, 208, 208, 224, 227, 228, 209, 209, 210, 211, 212, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 212, 216, 217, 218, 232, 241, 242, 243, 236, 244, 245, 246, 240, 247, 248, 249, 218, 222, 223, 224, 243, 250, 251, 252, 246, 253, 254, 255, 249, 256, 257, 258, 224, 227, 228, 209, 252, 259, 260, 229, 255, 261, 262, 233, 258, 263, 264, 237, /*bottom*/ 265, 265, 265, 265, 266, 267, 268, 269, 270, 271, 272, 273, 92, 119, 118, 113, 265, 265, 265, 265, 269, 274, 275, 276, 273, 277, 278, 279, 113, 112, 111, 104, 265, 265, 265, 265, 276, 280, 281, 282, 279, 283, 284, 285, 104, 103, 102, 95, 265, 265, 265, 265, 282, 286, 287, 266, 285, 288, 289, 270, 95, 94, 93, 92 ]; const teapotVertices = [ 1.4, 0, 2.4, 1.4, - 0.784, 2.4, 0.784, - 1.4, 2.4, 0, - 1.4, 2.4, 1.3375, 0, 2.53125, 1.3375, - 0.749, 2.53125, 0.749, - 1.3375, 2.53125, 0, - 1.3375, 2.53125, 1.4375, 0, 2.53125, 1.4375, - 0.805, 2.53125, 0.805, - 1.4375, 2.53125, 0, - 1.4375, 2.53125, 1.5, 0, 2.4, 1.5, - 0.84, 2.4, 0.84, - 1.5, 2.4, 0, - 1.5, 2.4, - 0.784, - 1.4, 2.4, - 1.4, - 0.784, 2.4, - 1.4, 0, 2.4, - 0.749, - 1.3375, 2.53125, - 1.3375, - 0.749, 2.53125, - 1.3375, 0, 2.53125, - 0.805, - 1.4375, 2.53125, - 1.4375, - 0.805, 2.53125, - 1.4375, 0, 2.53125, - 0.84, - 1.5, 2.4, - 1.5, - 0.84, 2.4, - 1.5, 0, 2.4, - 1.4, 0.784, 2.4, - 0.784, 1.4, 2.4, 0, 1.4, 2.4, - 1.3375, 0.749, 2.53125, - 0.749, 1.3375, 2.53125, 0, 1.3375, 2.53125, - 1.4375, 0.805, 2.53125, - 0.805, 1.4375, 2.53125, 0, 1.4375, 2.53125, - 1.5, 0.84, 2.4, - 0.84, 1.5, 2.4, 0, 1.5, 2.4, 0.784, 1.4, 2.4, 1.4, 0.784, 2.4, 0.749, 1.3375, 2.53125, 1.3375, 0.749, 2.53125, 0.805, 1.4375, 2.53125, 1.4375, 0.805, 2.53125, 0.84, 1.5, 2.4, 1.5, 0.84, 2.4, 1.75, 0, 1.875, 1.75, - 0.98, 1.875, 0.98, - 1.75, 1.875, 0, - 1.75, 1.875, 2, 0, 1.35, 2, - 1.12, 1.35, 1.12, - 2, 1.35, 0, - 2, 1.35, 2, 0, 0.9, 2, - 1.12, 0.9, 1.12, - 2, 0.9, 0, - 2, 0.9, - 0.98, - 1.75, 1.875, - 1.75, - 0.98, 1.875, - 1.75, 0, 1.875, - 1.12, - 2, 1.35, - 2, - 1.12, 1.35, - 2, 0, 1.35, - 1.12, - 2, 0.9, - 2, - 1.12, 0.9, - 2, 0, 0.9, - 1.75, 0.98, 1.875, - 0.98, 1.75, 1.875, 0, 1.75, 1.875, - 2, 1.12, 1.35, - 1.12, 2, 1.35, 0, 2, 1.35, - 2, 1.12, 0.9, - 1.12, 2, 0.9, 0, 2, 0.9, 0.98, 1.75, 1.875, 1.75, 0.98, 1.875, 1.12, 2, 1.35, 2, 1.12, 1.35, 1.12, 2, 0.9, 2, 1.12, 0.9, 2, 0, 0.45, 2, - 1.12, 0.45, 1.12, - 2, 0.45, 0, - 2, 0.45, 1.5, 0, 0.225, 1.5, - 0.84, 0.225, 0.84, - 1.5, 0.225, 0, - 1.5, 0.225, 1.5, 0, 0.15, 1.5, - 0.84, 0.15, 0.84, - 1.5, 0.15, 0, - 1.5, 0.15, - 1.12, - 2, 0.45, - 2, - 1.12, 0.45, - 2, 0, 0.45, - 0.84, - 1.5, 0.225, - 1.5, - 0.84, 0.225, - 1.5, 0, 0.225, - 0.84, - 1.5, 0.15, - 1.5, - 0.84, 0.15, - 1.5, 0, 0.15, - 2, 1.12, 0.45, - 1.12, 2, 0.45, 0, 2, 0.45, - 1.5, 0.84, 0.225, - 0.84, 1.5, 0.225, 0, 1.5, 0.225, - 1.5, 0.84, 0.15, - 0.84, 1.5, 0.15, 0, 1.5, 0.15, 1.12, 2, 0.45, 2, 1.12, 0.45, 0.84, 1.5, 0.225, 1.5, 0.84, 0.225, 0.84, 1.5, 0.15, 1.5, 0.84, 0.15, - 1.6, 0, 2.025, - 1.6, - 0.3, 2.025, - 1.5, - 0.3, 2.25, - 1.5, 0, 2.25, - 2.3, 0, 2.025, - 2.3, - 0.3, 2.025, - 2.5, - 0.3, 2.25, - 2.5, 0, 2.25, - 2.7, 0, 2.025, - 2.7, - 0.3, 2.025, - 3, - 0.3, 2.25, - 3, 0, 2.25, - 2.7, 0, 1.8, - 2.7, - 0.3, 1.8, - 3, - 0.3, 1.8, - 3, 0, 1.8, - 1.5, 0.3, 2.25, - 1.6, 0.3, 2.025, - 2.5, 0.3, 2.25, - 2.3, 0.3, 2.025, - 3, 0.3, 2.25, - 2.7, 0.3, 2.025, - 3, 0.3, 1.8, - 2.7, 0.3, 1.8, - 2.7, 0, 1.575, - 2.7, - 0.3, 1.575, - 3, - 0.3, 1.35, - 3, 0, 1.35, - 2.5, 0, 1.125, - 2.5, - 0.3, 1.125, - 2.65, - 0.3, 0.9375, - 2.65, 0, 0.9375, - 2, - 0.3, 0.9, - 1.9, - 0.3, 0.6, - 1.9, 0, 0.6, - 3, 0.3, 1.35, - 2.7, 0.3, 1.575, - 2.65, 0.3, 0.9375, - 2.5, 0.3, 1.125, - 1.9, 0.3, 0.6, - 2, 0.3, 0.9, 1.7, 0, 1.425, 1.7, - 0.66, 1.425, 1.7, - 0.66, 0.6, 1.7, 0, 0.6, 2.6, 0, 1.425, 2.6, - 0.66, 1.425, 3.1, - 0.66, 0.825, 3.1, 0, 0.825, 2.3, 0, 2.1, 2.3, - 0.25, 2.1, 2.4, - 0.25, 2.025, 2.4, 0, 2.025, 2.7, 0, 2.4, 2.7, - 0.25, 2.4, 3.3, - 0.25, 2.4, 3.3, 0, 2.4, 1.7, 0.66, 0.6, 1.7, 0.66, 1.425, 3.1, 0.66, 0.825, 2.6, 0.66, 1.425, 2.4, 0.25, 2.025, 2.3, 0.25, 2.1, 3.3, 0.25, 2.4, 2.7, 0.25, 2.4, 2.8, 0, 2.475, 2.8, - 0.25, 2.475, 3.525, - 0.25, 2.49375, 3.525, 0, 2.49375, 2.9, 0, 2.475, 2.9, - 0.15, 2.475, 3.45, - 0.15, 2.5125, 3.45, 0, 2.5125, 2.8, 0, 2.4, 2.8, - 0.15, 2.4, 3.2, - 0.15, 2.4, 3.2, 0, 2.4, 3.525, 0.25, 2.49375, 2.8, 0.25, 2.475, 3.45, 0.15, 2.5125, 2.9, 0.15, 2.475, 3.2, 0.15, 2.4, 2.8, 0.15, 2.4, 0, 0, 3.15, 0.8, 0, 3.15, 0.8, - 0.45, 3.15, 0.45, - 0.8, 3.15, 0, - 0.8, 3.15, 0, 0, 2.85, 0.2, 0, 2.7, 0.2, - 0.112, 2.7, 0.112, - 0.2, 2.7, 0, - 0.2, 2.7, - 0.45, - 0.8, 3.15, - 0.8, - 0.45, 3.15, - 0.8, 0, 3.15, - 0.112, - 0.2, 2.7, - 0.2, - 0.112, 2.7, - 0.2, 0, 2.7, - 0.8, 0.45, 3.15, - 0.45, 0.8, 3.15, 0, 0.8, 3.15, - 0.2, 0.112, 2.7, - 0.112, 0.2, 2.7, 0, 0.2, 2.7, 0.45, 0.8, 3.15, 0.8, 0.45, 3.15, 0.112, 0.2, 2.7, 0.2, 0.112, 2.7, 0.4, 0, 2.55, 0.4, - 0.224, 2.55, 0.224, - 0.4, 2.55, 0, - 0.4, 2.55, 1.3, 0, 2.55, 1.3, - 0.728, 2.55, 0.728, - 1.3, 2.55, 0, - 1.3, 2.55, 1.3, 0, 2.4, 1.3, - 0.728, 2.4, 0.728, - 1.3, 2.4, 0, - 1.3, 2.4, - 0.224, - 0.4, 2.55, - 0.4, - 0.224, 2.55, - 0.4, 0, 2.55, - 0.728, - 1.3, 2.55, - 1.3, - 0.728, 2.55, - 1.3, 0, 2.55, - 0.728, - 1.3, 2.4, - 1.3, - 0.728, 2.4, - 1.3, 0, 2.4, - 0.4, 0.224, 2.55, - 0.224, 0.4, 2.55, 0, 0.4, 2.55, - 1.3, 0.728, 2.55, - 0.728, 1.3, 2.55, 0, 1.3, 2.55, - 1.3, 0.728, 2.4, - 0.728, 1.3, 2.4, 0, 1.3, 2.4, 0.224, 0.4, 2.55, 0.4, 0.224, 2.55, 0.728, 1.3, 2.55, 1.3, 0.728, 2.55, 0.728, 1.3, 2.4, 1.3, 0.728, 2.4, 0, 0, 0, 1.425, 0, 0, 1.425, 0.798, 0, 0.798, 1.425, 0, 0, 1.425, 0, 1.5, 0, 0.075, 1.5, 0.84, 0.075, 0.84, 1.5, 0.075, 0, 1.5, 0.075, - 0.798, 1.425, 0, - 1.425, 0.798, 0, - 1.425, 0, 0, - 0.84, 1.5, 0.075, - 1.5, 0.84, 0.075, - 1.5, 0, 0.075, - 1.425, - 0.798, 0, - 0.798, - 1.425, 0, 0, - 1.425, 0, - 1.5, - 0.84, 0.075, - 0.84, - 1.5, 0.075, 0, - 1.5, 0.075, 0.798, - 1.425, 0, 1.425, - 0.798, 0, 0.84, - 1.5, 0.075, 1.5, - 0.84, 0.075 ]; - super(); // number of segments per patch + super(); - segments = Math.max( 2, Math.floor( segments ) ); // Jim Blinn scaled the teapot down in size by about 1.3 for + // number of segments per patch + segments = Math.max( 2, Math.floor( segments ) ); + + // Jim Blinn scaled the teapot down in size by about 1.3 for // some rendering tests. He liked the new proportions that he kept // the data in this form. The model was distributed with these new // proportions and became the norm. Trivia: comparing images of the // real teapot and the computer model, the ratio for the bowl of the // real teapot is more like 1.25, but since 1.3 is the traditional // value given, we use it here. + const blinnScale = 1.3; - const blinnScale = 1.3; // scale the size to be the real scaling factor - + // scale the size to be the real scaling factor const maxHeight = 3.15 * ( blinn ? 1 : blinnScale ); const maxHeight2 = maxHeight / 2; - const trueSize = size / maxHeight2; // Number of elements depends on what is needed. Subtract degenerate - // triangles at tip of bottom and lid out in advance. + const trueSize = size / maxHeight2; + // Number of elements depends on what is needed. Subtract degenerate + // triangles at tip of bottom and lid out in advance. let numTriangles = bottom ? ( 8 * segments - 4 ) * segments : 0; numTriangles += lid ? ( 16 * segments - 4 ) * segments : 0; numTriangles += body ? 40 * segments * segments : 0; @@ -94,17 +92,19 @@ numVertices *= ( segments + 1 ) * ( segments + 1 ); const vertices = new Float32Array( numVertices * 3 ); const normals = new Float32Array( numVertices * 3 ); - const uvs = new Float32Array( numVertices * 2 ); // Bezier form + const uvs = new Float32Array( numVertices * 2 ); + // Bezier form const ms = new THREE.Matrix4(); ms.set( - 1.0, 3.0, - 3.0, 1.0, 3.0, - 6.0, 3.0, 0.0, - 3.0, 3.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0 ); const g = []; const sp = []; const tp = []; const dsp = []; - const dtp = []; // M * G * M matrix, sort of see - // http://www.cs.helsinki.fi/group/goa/mallinnus/curves/surfaces.html + const dtp = []; + // M * G * M matrix, sort of see + // http://www.cs.helsinki.fi/group/goa/mallinnus/curves/surfaces.html const mgm = []; const vert = []; const sdir = []; @@ -126,12 +126,13 @@ const vsdir = new THREE.Vector3(); const vtdir = new THREE.Vector3(); const mst = ms.clone(); - mst.transpose(); // internal function: test if triangle has any matching vertices; - // if so, don't save triangle, since it won't display anything. + mst.transpose(); - const notDegenerate = ( vtx1, vtx2, vtx3 ) => // if any vertex matches, return false + // internal function: test if triangle has any matching vertices; + // if so, don't save triangle, since it won't display anything. + const notDegenerate = ( vtx1, vtx2, vtx3 ) => + // if any vertex matches, return false ! ( vertices[ vtx1 * 3 ] === vertices[ vtx2 * 3 ] && vertices[ vtx1 * 3 + 1 ] === vertices[ vtx2 * 3 + 1 ] && vertices[ vtx1 * 3 + 2 ] === vertices[ vtx2 * 3 + 2 ] || vertices[ vtx1 * 3 ] === vertices[ vtx3 * 3 ] && vertices[ vtx1 * 3 + 1 ] === vertices[ vtx3 * 3 + 1 ] && vertices[ vtx1 * 3 + 2 ] === vertices[ vtx3 * 3 + 2 ] || vertices[ vtx2 * 3 ] === vertices[ vtx3 * 3 ] && vertices[ vtx2 * 3 + 1 ] === vertices[ vtx3 * 3 + 1 ] && vertices[ vtx2 * 3 + 2 ] === vertices[ vtx3 * 3 + 2 ] ); - for ( let i = 0; i < 3; i ++ ) { mgm[ i ] = new THREE.Matrix4(); @@ -146,7 +147,6 @@ let normCount = 0; let uvCount = 0; let indexCount = 0; - for ( let surf = minPatches; surf < maxPatches; surf ++ ) { // lid is in the middle of the data, patches 20-27, @@ -162,9 +162,10 @@ for ( let c = 0; c < 4; c ++ ) { // transposed - g[ c * 4 + r ] = teapotVertices[ teapotPatches[ surf * 16 + r * 4 + c ] * 3 + i ]; // is the lid to be made larger, and is this a point on the lid - // that is X or Y? + g[ c * 4 + r ] = teapotVertices[ teapotPatches[ surf * 16 + r * 4 + c ] * 3 + i ]; + // is the lid to be made larger, and is this a point on the lid + // that is X or Y? if ( fitLid && surf >= 20 && surf < 28 && i !== 2 ) { // increase XY size by 7.7%, found empirically. I don't @@ -172,10 +173,10 @@ // space -1 to 1 for Y (Y is up for the final model). g[ c * 4 + r ] *= 1.077; - } // Blinn "fixed" the teapot by dividing Z by blinnScale, and that's the - // data we now use. The original teapot is taller. Fix it: - + } + // Blinn "fixed" the teapot by dividing Z by blinnScale, and that's the + // data we now use. The original teapot is taller. Fix it: if ( ! blinn && i === 2 ) { g[ c * 4 + r ] *= blinnScale; @@ -190,25 +191,24 @@ tmtx.multiplyMatrices( gmx, ms ); mgm[ i ].multiplyMatrices( mst, tmtx ); - } // step along, get points, and output - + } + // step along, get points, and output for ( let sstep = 0; sstep <= segments; sstep ++ ) { const s = sstep / segments; - for ( let tstep = 0; tstep <= segments; tstep ++ ) { - const t = tstep / segments; // point from basis - // get power vectors and their derivatives + const t = tstep / segments; + // point from basis + // get power vectors and their derivatives for ( p = 4, sval = tval = 1.0; p --; ) { sp[ p ] = sval; tp[ p ] = tval; sval *= s; tval *= t; - if ( p === 3 ) { dsp[ p ] = dtp[ p ] = 0.0; @@ -228,15 +228,17 @@ vsp.fromArray( sp ); vtp.fromArray( tp ); vdsp.fromArray( dsp ); - vdtp.fromArray( dtp ); // do for x,y,z + vdtp.fromArray( dtp ); + // do for x,y,z for ( let i = 0; i < 3; i ++ ) { // multiply power vectors times matrix to get value tcoord = vsp.clone(); tcoord.applyMatrix4( mgm[ i ] ); - vert[ i ] = tcoord.dot( vtp ); // get s and t tangent vectors + vert[ i ] = tcoord.dot( vtp ); + // get s and t tangent vectors tcoord = vdsp.clone(); tcoord.applyMatrix4( mgm[ i ] ); sdir[ i ] = tcoord.dot( vtp ); @@ -244,14 +246,15 @@ tcoord.applyMatrix4( mgm[ i ] ); tdir[ i ] = tcoord.dot( vdtp ); - } // find normal - + } + // find normal vsdir.fromArray( sdir ); vtdir.fromArray( tdir ); norm.crossVectors( vtdir, vsdir ); - norm.normalize(); // if X and Z length is 0, at the cusp, so point the normal up or down, depending on patch number + norm.normalize(); + // if X and Z length is 0, at the cusp, so point the normal up or down, depending on patch number if ( vert[ 0 ] === 0 && vert[ 1 ] === 0 ) { // if above the middle of the teapot, normal points up, else down @@ -262,9 +265,9 @@ // standard output: rotate on X axis normOut.set( norm.x, norm.z, - norm.y ); - } // store it all - + } + // store it all vertices[ vertCount ++ ] = trueSize * vert[ 0 ]; vertices[ vertCount ++ ] = trueSize * ( vert[ 2 ] - maxHeight2 ); vertices[ vertCount ++ ] = - trueSize * vert[ 1 ]; @@ -276,9 +279,9 @@ } - } // save the faces - + } + // save the faces for ( let sstep = 0; sstep < segments; sstep ++ ) { for ( let tstep = 0; tstep < segments; tstep ++ ) { @@ -286,9 +289,10 @@ const v1 = surfCount * vertPerRow * vertPerRow + sstep * vertPerRow + tstep; const v2 = v1 + 1; const v3 = v2 + vertPerRow; - const v4 = v1 + vertPerRow; // Normals and UVs cannot be shared. Without clone(), you can see the consequences - // of sharing if you call geometry.applyMatrix4( matrix ). + const v4 = v1 + vertPerRow; + // Normals and UVs cannot be shared. Without clone(), you can see the consequences + // of sharing if you call geometry.applyMatrix4( matrix ). if ( notDegenerate( v1, v2, v3 ) ) { indices[ indexCount ++ ] = v1; @@ -307,9 +311,9 @@ } - } // increment only if a surface was used - + } + // increment only if a surface was used surfCount ++; } diff --git a/examples/js/geometries/TextGeometry.js b/examples/js/geometries/TextGeometry.js index 7cbdaa35cea515..b1b49ce5508747 100644 --- a/examples/js/geometries/TextGeometry.js +++ b/examples/js/geometries/TextGeometry.js @@ -16,22 +16,24 @@ * bevelOffset: // how far from text outline does bevel start * } */ - class TextGeometry extends THREE.ExtrudeGeometry { constructor( text, parameters = {} ) { const font = parameters.font; - if ( font === undefined ) { super(); // generate default extrude geometry } else { - const shapes = font.generateShapes( text, parameters.size ); // translate parameters to THREE.ExtrudeGeometry API + const shapes = font.generateShapes( text, parameters.size ); + + // translate parameters to THREE.ExtrudeGeometry API + + parameters.depth = parameters.height !== undefined ? parameters.height : 50; - parameters.depth = parameters.height !== undefined ? parameters.height : 50; // defaults + // defaults if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10; if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8; diff --git a/examples/js/helpers/LightProbeHelper.js b/examples/js/helpers/LightProbeHelper.js index e3e9cbeef10155..1540bdd05e6aee 100644 --- a/examples/js/helpers/LightProbeHelper.js +++ b/examples/js/helpers/LightProbeHelper.js @@ -11,6 +11,7 @@ value: lightProbe.sh.coefficients }, // by reference + intensity: { value: lightProbe.intensity } @@ -26,14 +27,12 @@ this.onBeforeRender(); } - dispose() { this.geometry.dispose(); this.material.dispose(); } - onBeforeRender() { this.position.copy( this.lightProbe.position ); diff --git a/examples/js/helpers/OctreeHelper.js b/examples/js/helpers/OctreeHelper.js index 86c0d3c162112c..88e4c9bb9188b8 100644 --- a/examples/js/helpers/OctreeHelper.js +++ b/examples/js/helpers/OctreeHelper.js @@ -4,8 +4,19 @@ constructor( octree, color = 0xffff00 ) { - const vertices = []; + super( new THREE.BufferGeometry(), new THREE.LineBasicMaterial( { + color: color, + toneMapped: false + } ) ); + this.octree = octree; + this.color = color; + this.type = 'OctreeHelper'; + this.update(); + } + update() { + + const vertices = []; function traverse( tree ) { for ( let i = 0; i < tree.length; i ++ ) { @@ -14,37 +25,28 @@ const max = tree[ i ].box.max; vertices.push( max.x, max.y, max.z ); vertices.push( min.x, max.y, max.z ); // 0, 1 - vertices.push( min.x, max.y, max.z ); vertices.push( min.x, min.y, max.z ); // 1, 2 - vertices.push( min.x, min.y, max.z ); vertices.push( max.x, min.y, max.z ); // 2, 3 - vertices.push( max.x, min.y, max.z ); vertices.push( max.x, max.y, max.z ); // 3, 0 vertices.push( max.x, max.y, min.z ); vertices.push( min.x, max.y, min.z ); // 4, 5 - vertices.push( min.x, max.y, min.z ); vertices.push( min.x, min.y, min.z ); // 5, 6 - vertices.push( min.x, min.y, min.z ); vertices.push( max.x, min.y, min.z ); // 6, 7 - vertices.push( max.x, min.y, min.z ); vertices.push( max.x, max.y, min.z ); // 7, 4 vertices.push( max.x, max.y, max.z ); vertices.push( max.x, max.y, min.z ); // 0, 4 - vertices.push( min.x, max.y, max.z ); vertices.push( min.x, max.y, min.z ); // 1, 5 - vertices.push( min.x, min.y, max.z ); vertices.push( min.x, min.y, min.z ); // 2, 6 - vertices.push( max.x, min.y, max.z ); vertices.push( max.x, min.y, min.z ); // 3, 7 @@ -54,16 +56,16 @@ } - traverse( octree.subTrees ); - const geometry = new THREE.BufferGeometry(); - geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); - super( geometry, new THREE.LineBasicMaterial( { - color: color, - toneMapped: false - } ) ); - this.octree = octree; - this.color = color; - this.type = 'OctreeHelper'; + traverse( this.octree.subTrees ); + this.geometry.dispose(); + this.geometry = new THREE.BufferGeometry(); + this.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); + + } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); } diff --git a/examples/js/helpers/PositionalAudioHelper.js b/examples/js/helpers/PositionalAudioHelper.js index a89d61561b5356..203065ed4cfd00 100644 --- a/examples/js/helpers/PositionalAudioHelper.js +++ b/examples/js/helpers/PositionalAudioHelper.js @@ -23,7 +23,6 @@ this.update(); } - update() { const audio = this.audio; @@ -40,14 +39,15 @@ let stride; const geometry = this.geometry; const positionAttribute = geometry.attributes.position; - geometry.clearGroups(); // + geometry.clearGroups(); + + // function generateSegment( from, to, divisions, materialIndex ) { const step = ( to - from ) / divisions; positionAttribute.setXYZ( start, 0, 0, 0 ); count ++; - for ( i = from; i < to; i += step ) { stride = start + count; @@ -62,18 +62,20 @@ start += count; count = 0; - } // + } + // generateSegment( - halfConeOuterAngle, - halfConeInnerAngle, divisionsOuterAngle, 0 ); generateSegment( - halfConeInnerAngle, halfConeInnerAngle, divisionsInnerAngle, 1 ); - generateSegment( halfConeInnerAngle, halfConeOuterAngle, divisionsOuterAngle, 0 ); // + generateSegment( halfConeInnerAngle, halfConeOuterAngle, divisionsOuterAngle, 0 ); + + // positionAttribute.needsUpdate = true; if ( coneInnerAngle === coneOuterAngle ) this.material[ 0 ].visible = false; } - dispose() { this.geometry.dispose(); diff --git a/examples/js/helpers/RectAreaLightHelper.js b/examples/js/helpers/RectAreaLightHelper.js index faeb7508d33be9..13c06eb8de5d40 100644 --- a/examples/js/helpers/RectAreaLightHelper.js +++ b/examples/js/helpers/RectAreaLightHelper.js @@ -18,8 +18,9 @@ super( geometry, material ); this.light = light; this.color = color; // optional hardwired color for the helper + this.type = 'RectAreaLightHelper'; - this.type = 'RectAreaLightHelper'; // + // const positions2 = [ 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, 1, 0, - 1, - 1, 0, 1, - 1, 0 ]; const geometry2 = new THREE.BufferGeometry(); @@ -31,11 +32,9 @@ } ) ) ); } - updateMatrixWorld() { this.scale.set( 0.5 * this.light.width, 0.5 * this.light.height, 1 ); - if ( this.color !== undefined ) { this.material.color.set( this.color ); @@ -43,21 +42,21 @@ } else { - this.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity ); // prevent hue shift + this.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity ); + // prevent hue shift const c = this.material.color; const max = Math.max( c.r, c.g, c.b ); if ( max > 1 ) c.multiplyScalar( 1 / max ); this.children[ 0 ].material.color.copy( this.material.color ); - } // ignore world scale on light - + } + // ignore world scale on light this.matrixWorld.extractRotation( this.light.matrixWorld ).scale( this.scale ).copyPosition( this.light.matrixWorld ); this.children[ 0 ].matrixWorld.copy( this.matrixWorld ); } - dispose() { this.geometry.dispose(); diff --git a/examples/js/helpers/VertexNormalsHelper.js b/examples/js/helpers/VertexNormalsHelper.js index ad1d709433aac0..355d1457e16f53 100644 --- a/examples/js/helpers/VertexNormalsHelper.js +++ b/examples/js/helpers/VertexNormalsHelper.js @@ -1,11 +1,8 @@ ( function () { const _v1 = new THREE.Vector3(); - const _v2 = new THREE.Vector3(); - const _normalMatrix = new THREE.Matrix3(); - class VertexNormalsHelper extends THREE.LineSegments { constructor( object, size = 1, color = 0xff0000 ) { @@ -20,38 +17,37 @@ } ) ); this.object = object; this.size = size; - this.type = 'VertexNormalsHelper'; // + this.type = 'VertexNormalsHelper'; + + // this.matrixAutoUpdate = false; this.update(); } - update() { this.object.updateMatrixWorld( true ); - _normalMatrix.getNormalMatrix( this.object.matrixWorld ); - const matrixWorld = this.object.matrixWorld; - const position = this.geometry.attributes.position; // + const position = this.geometry.attributes.position; - const objGeometry = this.object.geometry; + // + const objGeometry = this.object.geometry; if ( objGeometry ) { const objPos = objGeometry.attributes.position; const objNorm = objGeometry.attributes.normal; - let idx = 0; // for simplicity, ignore index and drawcalls, and render every normal + let idx = 0; + + // for simplicity, ignore index and drawcalls, and render every normal for ( let j = 0, jl = objPos.count; j < jl; j ++ ) { _v1.fromBufferAttribute( objPos, j ).applyMatrix4( matrixWorld ); - _v2.fromBufferAttribute( objNorm, j ); - _v2.applyMatrix3( _normalMatrix ).normalize().multiplyScalar( this.size ).add( _v1 ); - position.setXYZ( idx, _v1.x, _v1.y, _v1.z ); idx = idx + 1; position.setXYZ( idx, _v2.x, _v2.y, _v2.z ); @@ -64,6 +60,12 @@ position.needsUpdate = true; } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + + } } diff --git a/examples/js/helpers/VertexTangentsHelper.js b/examples/js/helpers/VertexTangentsHelper.js index 299e84815faa8f..8b14d701674d78 100644 --- a/examples/js/helpers/VertexTangentsHelper.js +++ b/examples/js/helpers/VertexTangentsHelper.js @@ -1,9 +1,7 @@ ( function () { const _v1 = new THREE.Vector3(); - const _v2 = new THREE.Vector3(); - class VertexTangentsHelper extends THREE.LineSegments { constructor( object, size = 1, color = 0x00ffff ) { @@ -18,32 +16,34 @@ } ) ); this.object = object; this.size = size; - this.type = 'VertexTangentsHelper'; // + this.type = 'VertexTangentsHelper'; + + // this.matrixAutoUpdate = false; this.update(); } - update() { this.object.updateMatrixWorld( true ); const matrixWorld = this.object.matrixWorld; - const position = this.geometry.attributes.position; // + const position = this.geometry.attributes.position; + + // const objGeometry = this.object.geometry; const objPos = objGeometry.attributes.position; const objTan = objGeometry.attributes.tangent; - let idx = 0; // for simplicity, ignore index and drawcalls, and render every tangent + let idx = 0; + + // for simplicity, ignore index and drawcalls, and render every tangent for ( let j = 0, jl = objPos.count; j < jl; j ++ ) { _v1.fromBufferAttribute( objPos, j ).applyMatrix4( matrixWorld ); - _v2.fromBufferAttribute( objTan, j ); - _v2.transformDirection( matrixWorld ).multiplyScalar( this.size ).add( _v1 ); - position.setXYZ( idx, _v1.x, _v1.y, _v1.z ); idx = idx + 1; position.setXYZ( idx, _v2.x, _v2.y, _v2.z ); @@ -54,6 +54,12 @@ position.needsUpdate = true; } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + + } } diff --git a/examples/js/helpers/ViewHelper.js b/examples/js/helpers/ViewHelper.js index aa5cf9bb7aab0a..176494e6b1380f 100644 --- a/examples/js/helpers/ViewHelper.js +++ b/examples/js/helpers/ViewHelper.js @@ -1,7 +1,6 @@ ( function () { const vpTemp = new THREE.Vector4(); - class ViewHelper extends THREE.Object3D { constructor( editorCamera, dom ) { @@ -71,7 +70,6 @@ this.updateMatrixWorld(); point.set( 0, 0, 1 ); point.applyQuaternion( editorCamera.quaternion ); - if ( point.x >= 0 ) { posXAxisHelper.material.opacity = 1; @@ -106,8 +104,9 @@ posZAxisHelper.material.opacity = 0.5; negZAxisHelper.material.opacity = 1; - } // + } + // const x = dom.offsetWidth - dim; renderer.clearDepth(); @@ -123,7 +122,6 @@ const q1 = new THREE.Quaternion(); const q2 = new THREE.Quaternion(); let radius = 0; - this.handleClick = function ( event ) { if ( this.animating === true ) return false; @@ -134,7 +132,6 @@ mouse.y = - ( ( event.clientY - offsetY ) / ( rect.bottom - offsetY ) ) * 2 + 1; raycaster.setFromCamera( mouse, camera ); const intersects = raycaster.intersectObjects( interactiveObjects ); - if ( intersects.length > 0 ) { const intersection = intersects[ 0 ]; @@ -154,13 +151,16 @@ this.update = function ( delta ) { const step = delta * turnRate; - const focusPoint = this.controls.center; // animate position by doing a slerp and then scaling the position on the unit sphere + const focusPoint = this.controls.center; + + // animate position by doing a slerp and then scaling the position on the unit sphere q1.rotateTowards( q2, step ); - editorCamera.position.set( 0, 0, 1 ).applyQuaternion( q1 ).multiplyScalar( radius ).add( focusPoint ); // animate orientation + editorCamera.position.set( 0, 0, 1 ).applyQuaternion( q1 ).multiplyScalar( radius ).add( focusPoint ); - editorCamera.quaternion.rotateTowards( targetQuaternion, step ); + // animate orientation + editorCamera.quaternion.rotateTowards( targetQuaternion, step ); if ( q1.angleTo( q2 ) === 0 ) { this.animating = false; @@ -169,6 +169,27 @@ }; + this.dispose = function () { + + geometry.dispose(); + xAxis.material.dispose(); + yAxis.material.dispose(); + zAxis.material.dispose(); + posXAxisHelper.material.map.dispose(); + posYAxisHelper.material.map.dispose(); + posZAxisHelper.material.map.dispose(); + negXAxisHelper.material.map.dispose(); + negYAxisHelper.material.map.dispose(); + negZAxisHelper.material.map.dispose(); + posXAxisHelper.material.dispose(); + posYAxisHelper.material.dispose(); + posZAxisHelper.material.dispose(); + negXAxisHelper.material.dispose(); + negYAxisHelper.material.dispose(); + negZAxisHelper.material.dispose(); + + }; + function prepareAnimationData( object, focusPoint ) { switch ( object.userData.type ) { @@ -177,37 +198,32 @@ targetPosition.set( 1, 0, 0 ); targetQuaternion.setFromEuler( new THREE.Euler( 0, Math.PI * 0.5, 0 ) ); break; - case 'posY': targetPosition.set( 0, 1, 0 ); targetQuaternion.setFromEuler( new THREE.Euler( - Math.PI * 0.5, 0, 0 ) ); break; - case 'posZ': targetPosition.set( 0, 0, 1 ); targetQuaternion.setFromEuler( new THREE.Euler() ); break; - case 'negX': targetPosition.set( - 1, 0, 0 ); targetQuaternion.setFromEuler( new THREE.Euler( 0, - Math.PI * 0.5, 0 ) ); break; - case 'negY': targetPosition.set( 0, - 1, 0 ); targetQuaternion.setFromEuler( new THREE.Euler( Math.PI * 0.5, 0, 0 ) ); break; - case 'negZ': targetPosition.set( 0, 0, - 1 ); targetQuaternion.setFromEuler( new THREE.Euler( 0, Math.PI, 0 ) ); break; - default: console.error( 'ViewHelper: Invalid axis.' ); - } // + } + // radius = editorCamera.position.distanceTo( focusPoint ); targetPosition.multiplyScalar( radius ).add( focusPoint ); @@ -239,7 +255,6 @@ context.closePath(); context.fillStyle = color.getStyle(); context.fill(); - if ( text !== null ) { context.font = '24px Arial'; diff --git a/examples/js/interactive/HTMLMesh.js b/examples/js/interactive/HTMLMesh.js index e71e90d687890d..ecdf9b769a5809 100644 --- a/examples/js/interactive/HTMLMesh.js +++ b/examples/js/interactive/HTMLMesh.js @@ -12,7 +12,6 @@ transparent: true } ); super( geometry, material ); - function onEvent( event ) { material.map.dispatchDOMEvent( event ); @@ -23,12 +22,12 @@ this.addEventListener( 'mousemove', onEvent ); this.addEventListener( 'mouseup', onEvent ); this.addEventListener( 'click', onEvent ); - this.dispose = function () { geometry.dispose(); material.dispose(); material.map.dispose(); + canvases.delete( dom ); this.removeEventListener( 'mousedown', onEvent ); this.removeEventListener( 'mousemove', onEvent ); this.removeEventListener( 'mouseup', onEvent ); @@ -39,7 +38,6 @@ } } - class HTMLTexture extends THREE.CanvasTexture { constructor( dom ) { @@ -49,8 +47,9 @@ this.anisotropy = 16; this.encoding = THREE.sRGBEncoding; this.minFilter = THREE.LinearFilter; - this.magFilter = THREE.LinearFilter; // Create an observer on the DOM, and run html2canvas update in the next loop + this.magFilter = THREE.LinearFilter; + // Create an observer on the DOM, and run html2canvas update in the next loop const observer = new MutationObserver( () => { if ( ! this.scheduleUpdate ) { @@ -71,7 +70,6 @@ this.observer = observer; } - dispatchDOMEvent( event ) { if ( event.data ) { @@ -81,7 +79,6 @@ } } - update() { this.image = html2canvas( this.dom ); @@ -89,7 +86,6 @@ this.scheduleUpdate = null; } - dispose() { if ( this.observer ) { @@ -103,21 +99,19 @@ } - } // + } + // const canvases = new WeakMap(); - function html2canvas( element ) { const range = document.createRange(); const color = new THREE.Color(); - function Clipper( context ) { const clips = []; let isClipping = false; - function doClip() { if ( isClipping ) { @@ -132,7 +126,6 @@ minY = - Infinity; let maxX = Infinity, maxY = Infinity; - for ( let i = 0; i < clips.length; i ++ ) { const clip = clips[ i ]; @@ -206,7 +199,6 @@ const borderWidth = style[ which + 'Width' ]; const borderStyle = style[ which + 'Style' ]; const borderColor = style[ which + 'Color' ]; - if ( borderWidth !== '0px' && borderStyle !== 'none' && borderColor !== 'transparent' && borderColor !== 'rgba(0, 0, 0, 0)' ) { context.strokeStyle = borderColor; @@ -226,10 +218,10 @@ y = 0, width = 0, height = 0; - if ( element.nodeType === Node.TEXT_NODE ) { // text + range.selectNode( element ); const rect = range.getBoundingClientRect(); x = rect.left - offset.left - 0.5; @@ -260,23 +252,24 @@ y = rect.top - offset.top - 0.5; width = rect.width; height = rect.height; - style = window.getComputedStyle( element ); // Get the border of the element used for fill and border + style = window.getComputedStyle( element ); + + // Get the border of the element used for fill and border buildRectPath( x, y, width, height, parseFloat( style.borderRadius ) ); const backgroundColor = style.backgroundColor; - if ( backgroundColor !== 'transparent' && backgroundColor !== 'rgba(0, 0, 0, 0)' ) { context.fillStyle = backgroundColor; context.fill(); - } // If all the borders match then stroke the round rectangle + } + // If all the borders match then stroke the round rectangle const borders = [ 'borderTop', 'borderLeft', 'borderBottom', 'borderRight' ]; let match = true; let prevBorder = null; - for ( const border of borders ) { if ( prevBorder !== null ) { @@ -293,8 +286,8 @@ if ( match === true ) { // They all match so stroke the rectangle from before allows for border-radius - const width = parseFloat( style.borderTopWidth ); + const width = parseFloat( style.borderTopWidth ); if ( style.borderTopWidth !== '0px' && style.borderTopStyle !== 'none' && style.borderTopColor !== 'transparent' && style.borderTopColor !== 'rgba(0, 0, 0, 0)' ) { context.strokeStyle = style.borderTopColor; @@ -306,6 +299,7 @@ } else { // Otherwise draw individual borders + drawBorder( style, 'borderTop', x, y, width, 0 ); drawBorder( style, 'borderLeft', x, y, 0, height ); drawBorder( style, 'borderBottom', x, y + height, width, 0 ); @@ -320,7 +314,6 @@ color.set( accentColor ); const luminance = Math.sqrt( 0.299 * color.r ** 2 + 0.587 * color.g ** 2 + 0.114 * color.b ** 2 ); const accentTextColor = luminance < 0.5 ? 'white' : '#111111'; - if ( element.type === 'radio' ) { buildRectPath( x, y, width, height, height ); @@ -329,7 +322,6 @@ context.lineWidth = 1; context.fill(); context.stroke(); - if ( element.checked ) { buildRectPath( x + 2, y + 2, width - 4, height - 4, height ); @@ -351,7 +343,6 @@ context.lineWidth = 1; context.stroke(); context.fill(); - if ( element.checked ) { const currentTextAlign = context.textAlign; @@ -404,13 +395,13 @@ } } + /* // debug context.strokeStyle = '#' + Math.random().toString( 16 ).slice( - 3 ); context.strokeRect( x - 0.5, y - 0.5, width + 1, height + 1 ); */ - const isClipping = style.overflow === 'auto' || style.overflow === 'hidden'; if ( isClipping ) clipper.add( { x: x, @@ -418,7 +409,6 @@ width: width, height: height } ); - for ( let i = 0; i < element.childNodes.length; i ++ ) { drawElement( element.childNodes[ i ], style ); @@ -430,26 +420,25 @@ } const offset = element.getBoundingClientRect(); - let canvas; - - if ( canvases.has( element ) ) { - - canvas = canvases.get( element ); - - } else { + let canvas = canvases.get( element ); + if ( canvas === undefined ) { canvas = document.createElement( 'canvas' ); canvas.width = offset.width; canvas.height = offset.height; + canvases.set( element, canvas ); } - const context = canvas.getContext( '2d' - /*, { alpha: false }*/ - ); - const clipper = new Clipper( context ); // console.time( 'drawElement' ); + const context = canvas.getContext( '2d' /*, { alpha: false }*/ ); + + const clipper = new Clipper( context ); + + // console.time( 'drawElement' ); - drawElement( element ); // console.timeEnd( 'drawElement' ); + drawElement( element ); + + // console.timeEnd( 'drawElement' ); return canvas; @@ -466,17 +455,14 @@ const rect = element.getBoundingClientRect(); x = x * rect.width + rect.left; y = y * rect.height + rect.top; - function traverse( element ) { if ( element.nodeType !== Node.TEXT_NODE && element.nodeType !== Node.COMMENT_NODE ) { const rect = element.getBoundingClientRect(); - if ( x > rect.left && x < rect.right && y > rect.top && y < rect.bottom ) { element.dispatchEvent( new MouseEvent( event, mouseEventInit ) ); - if ( element instanceof HTMLInputElement && element.type === 'range' && ( event === 'mousedown' || event === 'click' ) ) { const [ min, max ] = [ 'min', 'max' ].map( property => parseFloat( element[ property ] ) ); diff --git a/examples/js/interactive/InteractiveGroup.js b/examples/js/interactive/InteractiveGroup.js index 14682dfd2ac2ef..be0cbe2d32595c 100644 --- a/examples/js/interactive/InteractiveGroup.js +++ b/examples/js/interactive/InteractiveGroup.js @@ -1,12 +1,10 @@ ( function () { const _pointer = new THREE.Vector2(); - const _event = { type: '', data: _pointer }; - class InteractiveGroup extends THREE.Group { constructor( renderer, camera ) { @@ -14,27 +12,26 @@ super(); const scope = this; const raycaster = new THREE.Raycaster(); - const tempMatrix = new THREE.Matrix4(); // Pointer Events + const tempMatrix = new THREE.Matrix4(); - const element = renderer.domElement; + // Pointer Events + const element = renderer.domElement; function onPointerEvent( event ) { event.stopPropagation(); - _pointer.x = event.clientX / element.clientWidth * 2 - 1; - _pointer.y = - ( event.clientY / element.clientHeight ) * 2 + 1; + const rect = renderer.domElement.getBoundingClientRect(); + _pointer.x = ( event.clientX - rect.left ) / rect.width * 2 - 1; + _pointer.y = - ( event.clientY - rect.top ) / rect.height * 2 + 1; raycaster.setFromCamera( _pointer, camera ); const intersects = raycaster.intersectObjects( scope.children, false ); - if ( intersects.length > 0 ) { const intersection = intersects[ 0 ]; const object = intersection.object; const uv = intersection.uv; _event.type = event.type; - _event.data.set( uv.x, 1 - uv.y ); - object.dispatchEvent( _event ); } @@ -47,7 +44,9 @@ element.addEventListener( 'mousedown', onPointerEvent ); element.addEventListener( 'mouseup', onPointerEvent ); element.addEventListener( 'mousemove', onPointerEvent ); - element.addEventListener( 'click', onPointerEvent ); // WebXR Controller Events + element.addEventListener( 'click', onPointerEvent ); + + // WebXR Controller Events // TODO: Dispatch pointerevents too const events = { @@ -56,7 +55,6 @@ 'selectstart': 'mousedown', 'selectend': 'mouseup' }; - function onXRControllerEvent( event ) { const controller = event.target; @@ -64,16 +62,13 @@ raycaster.ray.origin.setFromMatrixPosition( controller.matrixWorld ); raycaster.ray.direction.set( 0, 0, - 1 ).applyMatrix4( tempMatrix ); const intersections = raycaster.intersectObjects( scope.children, false ); - if ( intersections.length > 0 ) { const intersection = intersections[ 0 ]; const object = intersection.object; const uv = intersection.uv; _event.type = events[ event.type ]; - _event.data.set( uv.x, 1 - uv.y ); - object.dispatchEvent( _event ); } diff --git a/examples/js/interactive/SelectionBox.js b/examples/js/interactive/SelectionBox.js index adc9d4857ae78d..d0c5281617861a 100644 --- a/examples/js/interactive/SelectionBox.js +++ b/examples/js/interactive/SelectionBox.js @@ -5,41 +5,23 @@ */ const _frustum = new THREE.Frustum(); - const _center = new THREE.Vector3(); - const _tmpPoint = new THREE.Vector3(); - const _vecNear = new THREE.Vector3(); - const _vecTopLeft = new THREE.Vector3(); - const _vecTopRight = new THREE.Vector3(); - const _vecDownRight = new THREE.Vector3(); - const _vecDownLeft = new THREE.Vector3(); - const _vecFarTopLeft = new THREE.Vector3(); - const _vecFarTopRight = new THREE.Vector3(); - const _vecFarDownRight = new THREE.Vector3(); - const _vecFarDownLeft = new THREE.Vector3(); - const _vectemp1 = new THREE.Vector3(); - const _vectemp2 = new THREE.Vector3(); - const _vectemp3 = new THREE.Vector3(); - const _matrix = new THREE.Matrix4(); - const _quaternion = new THREE.Quaternion(); - const _scale = new THREE.Vector3(); - class SelectionBox { constructor( camera, scene, deep = Number.MAX_VALUE ) { @@ -53,7 +35,6 @@ this.deep = deep; } - select( startPoint, endPoint ) { this.startPoint = startPoint || this.startPoint; @@ -64,11 +45,12 @@ return this.collection; } - updateFrustum( startPoint, endPoint ) { startPoint = startPoint || this.startPoint; - endPoint = endPoint || this.endPoint; // Avoid invalid frustum + endPoint = endPoint || this.endPoint; + + // Avoid invalid frustum if ( startPoint.x === endPoint.x ) { @@ -84,58 +66,34 @@ this.camera.updateProjectionMatrix(); this.camera.updateMatrixWorld(); - if ( this.camera.isPerspectiveCamera ) { _tmpPoint.copy( startPoint ); - _tmpPoint.x = Math.min( startPoint.x, endPoint.x ); _tmpPoint.y = Math.max( startPoint.y, endPoint.y ); endPoint.x = Math.max( startPoint.x, endPoint.x ); endPoint.y = Math.min( startPoint.y, endPoint.y ); - _vecNear.setFromMatrixPosition( this.camera.matrixWorld ); - _vecTopLeft.copy( _tmpPoint ); - _vecTopRight.set( endPoint.x, _tmpPoint.y, 0 ); - _vecDownRight.copy( endPoint ); - _vecDownLeft.set( _tmpPoint.x, endPoint.y, 0 ); - _vecTopLeft.unproject( this.camera ); - _vecTopRight.unproject( this.camera ); - _vecDownRight.unproject( this.camera ); - _vecDownLeft.unproject( this.camera ); - _vectemp1.copy( _vecTopLeft ).sub( _vecNear ); - _vectemp2.copy( _vecTopRight ).sub( _vecNear ); - _vectemp3.copy( _vecDownRight ).sub( _vecNear ); - _vectemp1.normalize(); - _vectemp2.normalize(); - _vectemp3.normalize(); - _vectemp1.multiplyScalar( this.deep ); - _vectemp2.multiplyScalar( this.deep ); - _vectemp3.multiplyScalar( this.deep ); - _vectemp1.add( _vecNear ); - _vectemp2.add( _vecNear ); - _vectemp3.add( _vecNear ); - const planes = _frustum.planes; planes[ 0 ].setFromCoplanarPoints( _vecNear, _vecTopLeft, _vecTopRight ); planes[ 1 ].setFromCoplanarPoints( _vecNear, _vecTopRight, _vecDownRight ); @@ -151,39 +109,22 @@ const top = Math.max( startPoint.y, endPoint.y ); const right = Math.max( startPoint.x, endPoint.x ); const down = Math.min( startPoint.y, endPoint.y ); - _vecTopLeft.set( left, top, - 1 ); - _vecTopRight.set( right, top, - 1 ); - _vecDownRight.set( right, down, - 1 ); - _vecDownLeft.set( left, down, - 1 ); - _vecFarTopLeft.set( left, top, 1 ); - _vecFarTopRight.set( right, top, 1 ); - _vecFarDownRight.set( right, down, 1 ); - _vecFarDownLeft.set( left, down, 1 ); - _vecTopLeft.unproject( this.camera ); - _vecTopRight.unproject( this.camera ); - _vecDownRight.unproject( this.camera ); - _vecDownLeft.unproject( this.camera ); - _vecFarTopLeft.unproject( this.camera ); - _vecFarTopRight.unproject( this.camera ); - _vecFarDownRight.unproject( this.camera ); - _vecFarDownLeft.unproject( this.camera ); - const planes = _frustum.planes; planes[ 0 ].setFromCoplanarPoints( _vecTopLeft, _vecFarTopLeft, _vecFarTopRight ); planes[ 1 ].setFromCoplanarPoints( _vecTopRight, _vecFarTopRight, _vecFarDownRight ); @@ -200,7 +141,6 @@ } } - searchChildInFrustum( frustum, object ) { if ( object.isMesh || object.isLine || object.isPoints ) { @@ -208,15 +148,11 @@ if ( object.isInstancedMesh ) { this.instances[ object.uuid ] = []; - for ( let instanceId = 0; instanceId < object.count; instanceId ++ ) { object.getMatrixAt( instanceId, _matrix ); - _matrix.decompose( _center, _quaternion, _scale ); - _center.applyMatrix4( object.matrixWorld ); - if ( frustum.containsPoint( _center ) ) { this.instances[ object.uuid ].push( instanceId ); @@ -228,11 +164,8 @@ } else { if ( object.geometry.boundingSphere === null ) object.geometry.computeBoundingSphere(); - _center.copy( object.geometry.boundingSphere.center ); - _center.applyMatrix4( object.matrixWorld ); - if ( frustum.containsPoint( _center ) ) { this.collection.push( object ); diff --git a/examples/js/interactive/SelectionHelper.js b/examples/js/interactive/SelectionHelper.js index 36a171b201a159..2282a61f7257ed 100644 --- a/examples/js/interactive/SelectionHelper.js +++ b/examples/js/interactive/SelectionHelper.js @@ -12,14 +12,12 @@ this.pointTopLeft = new THREE.Vector2(); this.pointBottomRight = new THREE.Vector2(); this.isDown = false; - this.onPointerDown = function ( event ) { this.isDown = true; this.onSelectStart( event ); }.bind( this ); - this.onPointerMove = function ( event ) { if ( this.isDown ) { @@ -29,20 +27,17 @@ } }.bind( this ); - this.onPointerUp = function () { this.isDown = false; this.onSelectOver(); }.bind( this ); - this.renderer.domElement.addEventListener( 'pointerdown', this.onPointerDown ); this.renderer.domElement.addEventListener( 'pointermove', this.onPointerMove ); this.renderer.domElement.addEventListener( 'pointerup', this.onPointerUp ); } - dispose() { this.renderer.domElement.removeEventListener( 'pointerdown', this.onPointerDown ); @@ -50,9 +45,9 @@ this.renderer.domElement.removeEventListener( 'pointerup', this.onPointerUp ); } - onSelectStart( event ) { + this.element.style.display = 'none'; this.renderer.domElement.parentElement.appendChild( this.element ); this.element.style.left = event.clientX + 'px'; this.element.style.top = event.clientY + 'px'; @@ -62,9 +57,9 @@ this.startPoint.y = event.clientY; } - onSelectMove( event ) { + this.element.style.display = 'block'; this.pointBottomRight.x = Math.max( this.startPoint.x, event.clientX ); this.pointBottomRight.y = Math.max( this.startPoint.y, event.clientY ); this.pointTopLeft.x = Math.min( this.startPoint.x, event.clientX ); @@ -75,7 +70,6 @@ this.element.style.height = this.pointBottomRight.y - this.pointTopLeft.y + 'px'; } - onSelectOver() { this.element.parentElement.removeChild( this.element ); diff --git a/examples/js/libs/lottie_canvas.js b/examples/js/libs/lottie_canvas.js deleted file mode 100755 index ab90f404fcce2c..00000000000000 --- a/examples/js/libs/lottie_canvas.js +++ /dev/null @@ -1,12751 +0,0 @@ -(typeof navigator !== "undefined") && (function(root, factory) { - if (typeof define === "function" && define.amd) { - define(function() { - return factory(root); - }); - } else if (typeof module === "object" && module.exports) { - module.exports = factory(root); - } else { - root.lottie = factory(root); - root.bodymovin = root.lottie; - } -}((window || {}), function(window) { - "use strict"; -var svgNS = "http://www.w3.org/2000/svg"; - -var locationHref = ''; - -var initialDefaultFrame = -999999; - -var subframeEnabled = true; -var expressionsPlugin; -var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); -var cachedColors = {}; -var bm_rounder = Math.round; -var bm_rnd; -var bm_pow = Math.pow; -var bm_sqrt = Math.sqrt; -var bm_abs = Math.abs; -var bm_floor = Math.floor; -var bm_max = Math.max; -var bm_min = Math.min; -var blitter = 10; - -var BMMath = {}; -(function(){ - var propertyNames = ["abs", "acos", "acosh", "asin", "asinh", "atan", "atanh", "atan2", "ceil", "cbrt", "expm1", "clz32", "cos", "cosh", "exp", "floor", "fround", "hypot", "imul", "log", "log1p", "log2", "log10", "max", "min", "pow", "random", "round", "sign", "sin", "sinh", "sqrt", "tan", "tanh", "trunc", "E", "LN10", "LN2", "LOG10E", "LOG2E", "PI", "SQRT1_2", "SQRT2"]; - var i, len = propertyNames.length; - for(i=0;i 1) { - hsv[1] = 1; - } - else if (hsv[1] <= 0) { - hsv[1] = 0; - } - return HSVtoRGB(hsv[0],hsv[1],hsv[2]); -} - -function addBrightnessToRGB(color,offset){ - var hsv = RGBtoHSV(color[0]*255,color[1]*255,color[2]*255); - hsv[2] += offset; - if (hsv[2] > 1) { - hsv[2] = 1; - } - else if (hsv[2] < 0) { - hsv[2] = 0; - } - return HSVtoRGB(hsv[0],hsv[1],hsv[2]); -} - -function addHueToRGB(color,offset) { - var hsv = RGBtoHSV(color[0]*255,color[1]*255,color[2]*255); - hsv[0] += offset/360; - if (hsv[0] > 1) { - hsv[0] -= 1; - } - else if (hsv[0] < 0) { - hsv[0] += 1; - } - return HSVtoRGB(hsv[0],hsv[1],hsv[2]); -} - -var rgbToHex = (function(){ - var colorMap = []; - var i; - var hex; - for(i=0;i<256;i+=1){ - hex = i.toString(16); - colorMap[i] = hex.length == 1 ? '0' + hex : hex; - } - - return function(r, g, b) { - if(r<0){ - r = 0; - } - if(g<0){ - g = 0; - } - if(b<0){ - b = 0; - } - return '#' + colorMap[r] + colorMap[g] + colorMap[b]; - }; -}()); -function BaseEvent(){} -BaseEvent.prototype = { - triggerEvent: function (eventName, args) { - if (this._cbs[eventName]) { - var len = this._cbs[eventName].length; - for (var i = 0; i < len; i++){ - this._cbs[eventName][i](args); - } - } - }, - addEventListener: function (eventName, callback) { - if (!this._cbs[eventName]){ - this._cbs[eventName] = []; - } - this._cbs[eventName].push(callback); - - return function() { - this.removeEventListener(eventName, callback); - }.bind(this); - }, - removeEventListener: function (eventName,callback){ - if (!callback){ - this._cbs[eventName] = null; - }else if(this._cbs[eventName]){ - var i = 0, len = this._cbs[eventName].length; - while(i 0) || (val > -0.000001 && val < 0)) { - return _rnd(val * v) / v; - } - return val; - } - - function to2dCSS() { - //Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed. - /*if(this.isIdentity()) { - return ''; - }*/ - var props = this.props; - var _a = roundMatrixProperty(props[0]); - var _b = roundMatrixProperty(props[1]); - var _c = roundMatrixProperty(props[4]); - var _d = roundMatrixProperty(props[5]); - var _e = roundMatrixProperty(props[12]); - var _f = roundMatrixProperty(props[13]); - return "matrix(" + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ")"; - } - - return function(){ - this.reset = reset; - this.rotate = rotate; - this.rotateX = rotateX; - this.rotateY = rotateY; - this.rotateZ = rotateZ; - this.skew = skew; - this.skewFromAxis = skewFromAxis; - this.shear = shear; - this.scale = scale; - this.setTransform = setTransform; - this.translate = translate; - this.transform = transform; - this.applyToPoint = applyToPoint; - this.applyToX = applyToX; - this.applyToY = applyToY; - this.applyToZ = applyToZ; - this.applyToPointArray = applyToPointArray; - this.applyToTriplePoints = applyToTriplePoints; - this.applyToPointStringified = applyToPointStringified; - this.toCSS = toCSS; - this.to2dCSS = to2dCSS; - this.clone = clone; - this.cloneFromProps = cloneFromProps; - this.equals = equals; - this.inversePoints = inversePoints; - this.inversePoint = inversePoint; - this.getInverseMatrix = getInverseMatrix; - this._t = this.transform; - this.isIdentity = isIdentity; - this._identity = true; - this._identityCalculated = false; - - this.props = createTypedArray('float32', 16); - this.reset(); - }; -}()); - -/* - Copyright 2014 David Bau. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - */ - -(function (pool, math) { -// -// The following constants are related to IEEE 754 limits. -// - var global = this, - width = 256, // each RC4 output is 0 <= x < 256 - chunks = 6, // at least six RC4 outputs for each double - digits = 52, // there are 52 significant digits in a double - rngname = 'random', // rngname: name for Math.random and Math.seedrandom - startdenom = math.pow(width, chunks), - significance = math.pow(2, digits), - overflow = significance * 2, - mask = width - 1, - nodecrypto; // node.js crypto module, initialized at the bottom. - -// -// seedrandom() -// This is the seedrandom function described above. -// - function seedrandom(seed, options, callback) { - var key = []; - options = (options === true) ? { entropy: true } : (options || {}); - - // Flatten the seed string or build one from local entropy if needed. - var shortseed = mixkey(flatten( - options.entropy ? [seed, tostring(pool)] : - (seed === null) ? autoseed() : seed, 3), key); - - // Use the seed to initialize an ARC4 generator. - var arc4 = new ARC4(key); - - // This function returns a random double in [0, 1) that contains - // randomness in every bit of the mantissa of the IEEE 754 value. - var prng = function() { - var n = arc4.g(chunks), // Start with a numerator n < 2 ^ 48 - d = startdenom, // and denominator d = 2 ^ 48. - x = 0; // and no 'extra last byte'. - while (n < significance) { // Fill up all significant digits by - n = (n + x) * width; // shifting numerator and - d *= width; // denominator and generating a - x = arc4.g(1); // new least-significant-byte. - } - while (n >= overflow) { // To avoid rounding up, before adding - n /= 2; // last byte, shift everything - d /= 2; // right using integer math until - x >>>= 1; // we have exactly the desired bits. - } - return (n + x) / d; // Form the number within [0, 1). - }; - - prng.int32 = function() { return arc4.g(4) | 0; }; - prng.quick = function() { return arc4.g(4) / 0x100000000; }; - prng.double = prng; - - // Mix the randomness into accumulated entropy. - mixkey(tostring(arc4.S), pool); - - // Calling convention: what to return as a function of prng, seed, is_math. - return (options.pass || callback || - function(prng, seed, is_math_call, state) { - if (state) { - // Load the arc4 state from the given state if it has an S array. - if (state.S) { copy(state, arc4); } - // Only provide the .state method if requested via options.state. - prng.state = function() { return copy(arc4, {}); }; - } - - // If called as a method of Math (Math.seedrandom()), mutate - // Math.random because that is how seedrandom.js has worked since v1.0. - if (is_math_call) { math[rngname] = prng; return seed; } - - // Otherwise, it is a newer calling convention, so return the - // prng directly. - else return prng; - })( - prng, - shortseed, - 'global' in options ? options.global : (this == math), - options.state); - } - math['seed' + rngname] = seedrandom; - -// -// ARC4 -// -// An ARC4 implementation. The constructor takes a key in the form of -// an array of at most (width) integers that should be 0 <= x < (width). -// -// The g(count) method returns a pseudorandom integer that concatenates -// the next (count) outputs from ARC4. Its return value is a number x -// that is in the range 0 <= x < (width ^ count). -// - function ARC4(key) { - var t, keylen = key.length, - me = this, i = 0, j = me.i = me.j = 0, s = me.S = []; - - // The empty key [] is treated as [0]. - if (!keylen) { key = [keylen++]; } - - // Set up S using the standard key scheduling algorithm. - while (i < width) { - s[i] = i++; - } - for (i = 0; i < width; i++) { - s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))]; - s[j] = t; - } - - // The "g" method returns the next (count) outputs as one number. - me.g = function(count) { - // Using instance members instead of closure state nearly doubles speed. - var t, r = 0, - i = me.i, j = me.j, s = me.S; - while (count--) { - t = s[i = mask & (i + 1)]; - r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))]; - } - me.i = i; me.j = j; - return r; - // For robust unpredictability, the function call below automatically - // discards an initial batch of values. This is called RC4-drop[256]. - // See http://google.com/search?q=rsa+fluhrer+response&btnI - }; - } - -// -// copy() -// Copies internal state of ARC4 to or from a plain object. -// - function copy(f, t) { - t.i = f.i; - t.j = f.j; - t.S = f.S.slice(); - return t; - } - -// -// flatten() -// Converts an object tree to nested arrays of strings. -// - function flatten(obj, depth) { - var result = [], typ = (typeof obj), prop; - if (depth && typ == 'object') { - for (prop in obj) { - try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {} - } - } - return (result.length ? result : typ == 'string' ? obj : obj + '\0'); - } - -// -// mixkey() -// Mixes a string seed into a key that is an array of integers, and -// returns a shortened string seed that is equivalent to the result key. -// - function mixkey(seed, key) { - var stringseed = seed + '', smear, j = 0; - while (j < stringseed.length) { - key[mask & j] = - mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++)); - } - return tostring(key); - } - -// -// autoseed() -// Returns an object for autoseeding, using window.crypto and Node crypto -// module if available. -// - function autoseed() { - try { - if (nodecrypto) { return tostring(nodecrypto.randomBytes(width)); } - var out = new Uint8Array(width); - (global.crypto || global.msCrypto).getRandomValues(out); - return tostring(out); - } catch (e) { - var browser = global.navigator, - plugins = browser && browser.plugins; - return [+new Date(), global, plugins, global.screen, tostring(pool)]; - } - } - -// -// tostring() -// Converts an array of charcodes to a string -// - function tostring(a) { - return String.fromCharCode.apply(0, a); - } - -// -// When seedrandom.js is loaded, we immediately mix a few bits -// from the built-in RNG into the entropy pool. Because we do -// not want to interfere with deterministic PRNG state later, -// seedrandom will not call math.random on its own again after -// initialization. -// - mixkey(math.random(), pool); - -// -// Nodejs and AMD support: export the implementation as a module using -// either convention. -// - -// End anonymous scope, and pass initial values. -})( - [], // pool: entropy pool starts empty - BMMath // math: package containing random, pow, and seedrandom -); -var BezierFactory = (function(){ - /** - * BezierEasing - use bezier curve for transition easing function - * by Gaëtan Renaudeau 2014 - 2015 – MIT License - * - * Credits: is based on Firefox's nsSMILKeySpline.cpp - * Usage: - * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ]) - * spline.get(x) => returns the easing value | x must be in [0, 1] range - * - */ - - var ob = {}; - ob.getBezierEasing = getBezierEasing; - var beziers = {}; - - function getBezierEasing(a,b,c,d,nm){ - var str = nm || ('bez_' + a+'_'+b+'_'+c+'_'+d).replace(/\./g, 'p'); - if(beziers[str]){ - return beziers[str]; - } - var bezEasing = new BezierEasing([a,b,c,d]); - beziers[str] = bezEasing; - return bezEasing; - } - -// These values are established by empiricism with tests (tradeoff: performance VS precision) - var NEWTON_ITERATIONS = 4; - var NEWTON_MIN_SLOPE = 0.001; - var SUBDIVISION_PRECISION = 0.0000001; - var SUBDIVISION_MAX_ITERATIONS = 10; - - var kSplineTableSize = 11; - var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0); - - var float32ArraySupported = typeof Float32Array === "function"; - - function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; } - function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; } - function C (aA1) { return 3.0 * aA1; } - -// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2. - function calcBezier (aT, aA1, aA2) { - return ((A(aA1, aA2)*aT + B(aA1, aA2))*aT + C(aA1))*aT; - } - -// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2. - function getSlope (aT, aA1, aA2) { - return 3.0 * A(aA1, aA2)*aT*aT + 2.0 * B(aA1, aA2) * aT + C(aA1); - } - - function binarySubdivide (aX, aA, aB, mX1, mX2) { - var currentX, currentT, i = 0; - do { - currentT = aA + (aB - aA) / 2.0; - currentX = calcBezier(currentT, mX1, mX2) - aX; - if (currentX > 0.0) { - aB = currentT; - } else { - aA = currentT; - } - } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS); - return currentT; - } - - function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) { - for (var i = 0; i < NEWTON_ITERATIONS; ++i) { - var currentSlope = getSlope(aGuessT, mX1, mX2); - if (currentSlope === 0.0) return aGuessT; - var currentX = calcBezier(aGuessT, mX1, mX2) - aX; - aGuessT -= currentX / currentSlope; - } - return aGuessT; - } - - /** - * points is an array of [ mX1, mY1, mX2, mY2 ] - */ - function BezierEasing (points) { - this._p = points; - this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize); - this._precomputed = false; - - this.get = this.get.bind(this); - } - - BezierEasing.prototype = { - - get: function (x) { - var mX1 = this._p[0], - mY1 = this._p[1], - mX2 = this._p[2], - mY2 = this._p[3]; - if (!this._precomputed) this._precompute(); - if (mX1 === mY1 && mX2 === mY2) return x; // linear - // Because JavaScript number are imprecise, we should guarantee the extremes are right. - if (x === 0) return 0; - if (x === 1) return 1; - return calcBezier(this._getTForX(x), mY1, mY2); - }, - - // Private part - - _precompute: function () { - var mX1 = this._p[0], - mY1 = this._p[1], - mX2 = this._p[2], - mY2 = this._p[3]; - this._precomputed = true; - if (mX1 !== mY1 || mX2 !== mY2) - this._calcSampleValues(); - }, - - _calcSampleValues: function () { - var mX1 = this._p[0], - mX2 = this._p[2]; - for (var i = 0; i < kSplineTableSize; ++i) { - this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2); - } - }, - - /** - * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection. - */ - _getTForX: function (aX) { - var mX1 = this._p[0], - mX2 = this._p[2], - mSampleValues = this._mSampleValues; - - var intervalStart = 0.0; - var currentSample = 1; - var lastSample = kSplineTableSize - 1; - - for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) { - intervalStart += kSampleStepSize; - } - --currentSample; - - // Interpolate to provide an initial guess for t - var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample+1] - mSampleValues[currentSample]); - var guessForT = intervalStart + dist * kSampleStepSize; - - var initialSlope = getSlope(guessForT, mX1, mX2); - if (initialSlope >= NEWTON_MIN_SLOPE) { - return newtonRaphsonIterate(aX, guessForT, mX1, mX2); - } else if (initialSlope === 0.0) { - return guessForT; - } else { - return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2); - } - } - }; - - return ob; - -}()); -(function () { - var lastTime = 0; - var vendors = ['ms', 'moz', 'webkit', 'o']; - for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { - window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; - window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame']; - } - if(!window.requestAnimationFrame) - window.requestAnimationFrame = function (callback, element) { - var currTime = new Date().getTime(); - var timeToCall = Math.max(0, 16 - (currTime - lastTime)); - var id = setTimeout(function () { - callback(currTime + timeToCall); - }, - timeToCall); - lastTime = currTime + timeToCall; - return id; - }; - if(!window.cancelAnimationFrame) - window.cancelAnimationFrame = function (id) { - clearTimeout(id); - }; -}()); - -function extendPrototype(sources,destination){ - var i, len = sources.length, sourcePrototype; - for (i = 0;i < len;i += 1) { - sourcePrototype = sources[i].prototype; - for (var attr in sourcePrototype) { - if (sourcePrototype.hasOwnProperty(attr)) destination.prototype[attr] = sourcePrototype[attr]; - } - } -} - -function getDescriptor(object, prop) { - return Object.getOwnPropertyDescriptor(object, prop); -} - -function createProxyFunction(prototype) { - function ProxyFunction(){} - ProxyFunction.prototype = prototype; - return ProxyFunction; -} -function bezFunction(){ - - var easingFunctions = []; - var math = Math; - - function pointOnLine2D(x1,y1, x2,y2, x3,y3){ - var det1 = (x1*y2) + (y1*x3) + (x2*y3) - (x3*y2) - (y3*x1) - (x2*y1); - return det1 > -0.001 && det1 < 0.001; - } - - function pointOnLine3D(x1,y1,z1, x2,y2,z2, x3,y3,z3){ - if(z1 === 0 && z2 === 0 && z3 === 0) { - return pointOnLine2D(x1,y1, x2,y2, x3,y3); - } - var dist1 = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2) + Math.pow(z2 - z1, 2)); - var dist2 = Math.sqrt(Math.pow(x3 - x1, 2) + Math.pow(y3 - y1, 2) + Math.pow(z3 - z1, 2)); - var dist3 = Math.sqrt(Math.pow(x3 - x2, 2) + Math.pow(y3 - y2, 2) + Math.pow(z3 - z2, 2)); - var diffDist; - if(dist1 > dist2){ - if(dist1 > dist3){ - diffDist = dist1 - dist2 - dist3; - } else { - diffDist = dist3 - dist2 - dist1; - } - } else if(dist3 > dist2){ - diffDist = dist3 - dist2 - dist1; - } else { - diffDist = dist2 - dist1 - dist3; - } - return diffDist > -0.0001 && diffDist < 0.0001; - } - - var getBezierLength = (function(){ - - return function(pt1,pt2,pt3,pt4){ - var curveSegments = defaultCurveSegments; - var k; - var i, len; - var ptCoord,perc,addedLength = 0; - var ptDistance; - var point = [],lastPoint = []; - var lengthData = bezier_length_pool.newElement(); - len = pt3.length; - for(k=0;k lengthPos ? -1 : 1; - var flag = true; - while(flag){ - if(lengths[initPos] <= lengthPos && lengths[initPos+1] > lengthPos){ - lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos+1] - lengths[initPos]); - flag = false; - }else{ - initPos += dir; - } - if(initPos < 0 || initPos >= len - 1){ - //FIX for TypedArrays that don't store floating point values with enough accuracy - if(initPos === len - 1) { - return percents[initPos]; - } - flag = false; - } - } - return percents[initPos] + (percents[initPos+1] - percents[initPos])*lPerc; - } - } - - function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) { - var t1 = getDistancePerc(percent,bezierData); - var u0 = 1; - var u1 = 1 - t1; - var ptX = Math.round((u1*u1*u1* pt1[0] + (t1*u1*u1 + u1*t1*u1 + u1*u1*t1)* pt3[0] + (t1*t1*u1 + u1*t1*t1 + t1*u1*t1)*pt4[0] + t1*t1*t1* pt2[0])* 1000) / 1000; - var ptY = Math.round((u1*u1*u1* pt1[1] + (t1*u1*u1 + u1*t1*u1 + u1*u1*t1)* pt3[1] + (t1*t1*u1 + u1*t1*t1 + t1*u1*t1)*pt4[1] + t1*t1*t1* pt2[1])* 1000) / 1000; - return [ptX, ptY]; - } - - function getSegmentArray() { - - } - - var bezier_segment_points = createTypedArray('float32', 8); - - function getNewSegment(pt1,pt2,pt3,pt4,startPerc,endPerc, bezierData){ - - startPerc = startPerc < 0 ? 0 : startPerc > 1 ? 1 : startPerc; - var t0 = getDistancePerc(startPerc,bezierData); - endPerc = endPerc > 1 ? 1 : endPerc; - var t1 = getDistancePerc(endPerc,bezierData); - var i, len = pt1.length; - var u0 = 1 - t0; - var u1 = 1 - t1; - var u0u0u0 = u0*u0*u0; - var t0u0u0_3 = t0*u0*u0*3; - var t0t0u0_3 = t0*t0*u0*3; - var t0t0t0 = t0*t0*t0; - // - var u0u0u1 = u0*u0*u1; - var t0u0u1_3 = t0*u0*u1 + u0*t0*u1 + u0*u0*t1; - var t0t0u1_3 = t0*t0*u1 + u0*t0*t1 + t0*u0*t1; - var t0t0t1 = t0*t0*t1; - // - var u0u1u1 = u0*u1*u1; - var t0u1u1_3 = t0*u1*u1 + u0*t1*u1 + u0*u1*t1; - var t0t1u1_3 = t0*t1*u1 + u0*t1*t1 + t0*u1*t1; - var t0t1t1 = t0*t1*t1; - // - var u1u1u1 = u1*u1*u1; - var t1u1u1_3 = t1*u1*u1 + u1*t1*u1 + u1*u1*t1; - var t1t1u1_3 = t1*t1*u1 + u1*t1*t1 + t1*u1*t1; - var t1t1t1 = t1*t1*t1; - for(i=0;i=0;i-=1){ - if(arr[i].ty == 'sh'){ - if(arr[i].ks.k.i){ - convertPathsToAbsoluteValues(arr[i].ks.k); - }else{ - jLen = arr[i].ks.k.length; - for(j=0;janimVersion[0]){ - return true; - } else if(animVersion[0] > minimum[0]){ - return false; - } - if(minimum[1]>animVersion[1]){ - return true; - } else if(animVersion[1] > minimum[1]){ - return false; - } - if(minimum[2]>animVersion[2]){ - return true; - } else if(animVersion[2] > minimum[2]){ - return false; - } - } - - var checkText = (function(){ - var minimumVersion = [4,4,14]; - - function updateTextLayer(textLayer){ - var documentData = textLayer.t.d; - textLayer.t.d = { - k: [ - { - s:documentData, - t:0 - } - ] - }; - } - - function iterateLayers(layers){ - var i, len = layers.length; - for(i=0;i=0;i-=1){ - if(arr[i].ty == 'sh'){ - if(arr[i].ks.k.i){ - arr[i].ks.k.c = arr[i].closed; - }else{ - jLen = arr[i].ks.k.length; - for(j=0;j 0) { - shouldLoadFont = false; - } - - if (shouldLoadFont) { - var s = createTag('style'); - s.setAttribute('f-forigin', fontArr[i].fOrigin); - s.setAttribute('f-origin', fontArr[i].origin); - s.setAttribute('f-family', fontArr[i].fFamily); - s.type = "text/css"; - s.innerText = "@font-face {" + "font-family: "+fontArr[i].fFamily+"; font-style: normal; src: url('"+fontArr[i].fPath+"');}"; - defs.appendChild(s); - } - } else if(fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1){ - loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'); - - for (j = 0; j < loadedSelector.length; j++) { - if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) { - // Font is already loaded - shouldLoadFont = false; - } - } - - if (shouldLoadFont) { - var l = createTag('link'); - l.setAttribute('f-forigin', fontArr[i].fOrigin); - l.setAttribute('f-origin', fontArr[i].origin); - l.type = "text/css"; - l.rel = "stylesheet"; - l.href = fontArr[i].fPath; - document.body.appendChild(l); - } - } else if(fontArr[i].fOrigin === 't' || fontArr[i].origin === 2){ - loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'); - - for (j = 0; j < loadedSelector.length; j++) { - if (fontArr[i].fPath === loadedSelector[j].src) { - // Font is already loaded - shouldLoadFont = false; - } - } - - if (shouldLoadFont) { - var sc = createTag('link'); - sc.setAttribute('f-forigin', fontArr[i].fOrigin); - sc.setAttribute('f-origin', fontArr[i].origin); - sc.setAttribute('rel','stylesheet'); - sc.setAttribute('href',fontArr[i].fPath); - defs.appendChild(sc); - } - } - fontArr[i].helper = createHelper(defs,fontArr[i]); - fontArr[i].cache = {}; - this.fonts.push(fontArr[i]); - } - if (_pendingFonts === 0) { - this.isLoaded = true; - } else { - //On some cases even if the font is loaded, it won't load correctly when measuring text on canvas. - //Adding this timeout seems to fix it - setTimeout(this.checkLoadedFonts.bind(this), 100); - } - } - - function addChars(chars){ - if(!chars){ - return; - } - if(!this.chars){ - this.chars = []; - } - var i, len = chars.length; - var j, jLen = this.chars.length, found; - for(i=0;i= nextKeyData.t - offsetTime){ - if(keyData.h){ - keyData = nextKeyData; - } - iterationIndex = 0; - break; - } - if ((nextKeyData.t - offsetTime) > frameNum){ - iterationIndex = i; - break; - } - if (i < len - 1){ - i += 1; - } else { - iterationIndex = 0; - flag = false; - } - } - - var k, kLen, perc, jLen, j, fnc; - var nextKeyTime = nextKeyData.t - offsetTime; - var keyTime = keyData.t - offsetTime; - var endValue; - if (keyData.to) { - if (!keyData.bezierData) { - keyData.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti); - } - var bezierData = keyData.bezierData; - if (frameNum >= nextKeyTime || frameNum < keyTime) { - var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0; - kLen = bezierData.points[ind].point.length; - for (k = 0; k < kLen; k += 1) { - newValue[k] = bezierData.points[ind].point[k]; - } - // caching._lastKeyframeIndex = -1; - } else { - if (keyData.__fnct) { - fnc = keyData.__fnct; - } else { - fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get; - keyData.__fnct = fnc; - } - perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime)); - var distanceInLine = bezierData.segmentLength*perc; - - var segmentPerc; - var addedLength = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastAddedLength : 0; - j = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastPoint : 0; - flag = true; - jLen = bezierData.points.length; - while (flag) { - addedLength += bezierData.points[j].partialLength; - if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) { - kLen = bezierData.points[j].point.length; - for (k = 0; k < kLen; k += 1) { - newValue[k] = bezierData.points[j].point[k]; - } - break; - } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) { - segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength; - kLen = bezierData.points[j].point.length; - for (k = 0; k < kLen; k += 1) { - newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc; - } - break; - } - if (j < jLen - 1){ - j += 1; - } else { - flag = false; - } - } - caching._lastPoint = j; - caching._lastAddedLength = addedLength - bezierData.points[j].partialLength; - caching._lastKeyframeIndex = i; - } - } else { - var outX, outY, inX, inY, keyValue; - len = keyData.s.length; - endValue = nextKeyData.s || keyData.e; - if (this.sh && keyData.h !== 1) { - if (frameNum >= nextKeyTime) { - newValue[0] = endValue[0]; - newValue[1] = endValue[1]; - newValue[2] = endValue[2]; - } else if (frameNum <= keyTime) { - newValue[0] = keyData.s[0]; - newValue[1] = keyData.s[1]; - newValue[2] = keyData.s[2]; - } else { - var quatStart = createQuaternion(keyData.s); - var quatEnd = createQuaternion(endValue); - var time = (frameNum - keyTime) / (nextKeyTime - keyTime); - quaternionToEuler(newValue, slerp(quatStart, quatEnd, time)); - } - - } else { - for(i = 0; i < len; i += 1) { - if (keyData.h !== 1) { - if (frameNum >= nextKeyTime) { - perc = 1; - } else if(frameNum < keyTime) { - perc = 0; - } else { - if(keyData.o.x.constructor === Array) { - if (!keyData.__fnct) { - keyData.__fnct = []; - } - if (!keyData.__fnct[i]) { - outX = (typeof keyData.o.x[i] === 'undefined') ? keyData.o.x[0] : keyData.o.x[i]; - outY = (typeof keyData.o.y[i] === 'undefined') ? keyData.o.y[0] : keyData.o.y[i]; - inX = (typeof keyData.i.x[i] === 'undefined') ? keyData.i.x[0] : keyData.i.x[i]; - inY = (typeof keyData.i.y[i] === 'undefined') ? keyData.i.y[0] : keyData.i.y[i]; - fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get; - keyData.__fnct[i] = fnc; - } else { - fnc = keyData.__fnct[i]; - } - } else { - if (!keyData.__fnct) { - outX = keyData.o.x; - outY = keyData.o.y; - inX = keyData.i.x; - inY = keyData.i.y; - fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get; - keyData.__fnct = fnc; - } else { - fnc = keyData.__fnct; - } - } - perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime )); - } - } - - endValue = nextKeyData.s || keyData.e; - keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc; - - if (this.propType === 'multidimensional') { - newValue[i] = keyValue; - } else { - newValue = keyValue; - } - } - } - } - caching.lastIndex = iterationIndex; - return newValue; - } - - //based on @Toji's https://github.com/toji/gl-matrix/ - function slerp(a, b, t) { - var out = []; - var ax = a[0], ay = a[1], az = a[2], aw = a[3], - bx = b[0], by = b[1], bz = b[2], bw = b[3] - - var omega, cosom, sinom, scale0, scale1; - - cosom = ax * bx + ay * by + az * bz + aw * bw; - if (cosom < 0.0) { - cosom = -cosom; - bx = -bx; - by = -by; - bz = -bz; - bw = -bw; - } - if ((1.0 - cosom) > 0.000001) { - omega = Math.acos(cosom); - sinom = Math.sin(omega); - scale0 = Math.sin((1.0 - t) * omega) / sinom; - scale1 = Math.sin(t * omega) / sinom; - } else { - scale0 = 1.0 - t; - scale1 = t; - } - out[0] = scale0 * ax + scale1 * bx; - out[1] = scale0 * ay + scale1 * by; - out[2] = scale0 * az + scale1 * bz; - out[3] = scale0 * aw + scale1 * bw; - - return out; - } - - function quaternionToEuler(out, quat) { - var qx = quat[0]; - var qy = quat[1]; - var qz = quat[2]; - var qw = quat[3]; - var heading = Math.atan2(2*qy*qw-2*qx*qz , 1 - 2*qy*qy - 2*qz*qz) - var attitude = Math.asin(2*qx*qy + 2*qz*qw) - var bank = Math.atan2(2*qx*qw-2*qy*qz , 1 - 2*qx*qx - 2*qz*qz); - out[0] = heading/degToRads; - out[1] = attitude/degToRads; - out[2] = bank/degToRads; - } - - function createQuaternion(values) { - var heading = values[0] * degToRads; - var attitude = values[1] * degToRads; - var bank = values[2] * degToRads; - var c1 = Math.cos(heading / 2); - var c2 = Math.cos(attitude / 2); - var c3 = Math.cos(bank / 2); - var s1 = Math.sin(heading / 2); - var s2 = Math.sin(attitude / 2); - var s3 = Math.sin(bank / 2); - var w = c1 * c2 * c3 - s1 * s2 * s3; - var x = s1 * s2 * c3 + c1 * c2 * s3; - var y = s1 * c2 * c3 + c1 * s2 * s3; - var z = c1 * s2 * c3 - s1 * c2 * s3; - - return [x,y,z,w]; - } - - function getValueAtCurrentTime(){ - var frameNum = this.comp.renderedFrame - this.offsetTime; - var initTime = this.keyframes[0].t - this.offsetTime; - var endTime = this.keyframes[this.keyframes.length- 1].t-this.offsetTime; - if(!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))){ - if(this._caching.lastFrame >= frameNum) { - this._caching._lastKeyframeIndex = -1; - this._caching.lastIndex = 0; - } - - var renderResult = this.interpolateValue(frameNum, this._caching); - this.pv = renderResult; - } - this._caching.lastFrame = frameNum; - return this.pv; - } - - function setVValue(val) { - var multipliedValue; - if(this.propType === 'unidimensional') { - multipliedValue = val * this.mult; - if(math_abs(this.v - multipliedValue) > 0.00001) { - this.v = multipliedValue; - this._mdf = true; - } - } else { - var i = 0, len = this.v.length; - while (i < len) { - multipliedValue = val[i] * this.mult; - if (math_abs(this.v[i] - multipliedValue) > 0.00001) { - this.v[i] = multipliedValue; - this._mdf = true; - } - i += 1; - } - } - } - - function processEffectsSequence() { - if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) { - return; - } - if(this.lock) { - this.setVValue(this.pv); - return; - } - this.lock = true; - this._mdf = this._isFirstFrame; - var multipliedValue; - var i, len = this.effectsSequence.length; - var finalValue = this.kf ? this.pv : this.data.k; - for(i = 0; i < len; i += 1) { - finalValue = this.effectsSequence[i](finalValue); - } - this.setVValue(finalValue); - this._isFirstFrame = false; - this.lock = false; - this.frameId = this.elem.globalData.frameId; - } - - function addEffect(effectFunction) { - this.effectsSequence.push(effectFunction); - this.container.addDynamicProperty(this); - } - - function ValueProperty(elem, data, mult, container){ - this.propType = 'unidimensional'; - this.mult = mult || 1; - this.data = data; - this.v = mult ? data.k * mult : data.k; - this.pv = data.k; - this._mdf = false; - this.elem = elem; - this.container = container; - this.comp = elem.comp; - this.k = false; - this.kf = false; - this.vel = 0; - this.effectsSequence = []; - this._isFirstFrame = true; - this.getValue = processEffectsSequence; - this.setVValue = setVValue; - this.addEffect = addEffect; - } - - function MultiDimensionalProperty(elem, data, mult, container) { - this.propType = 'multidimensional'; - this.mult = mult || 1; - this.data = data; - this._mdf = false; - this.elem = elem; - this.container = container; - this.comp = elem.comp; - this.k = false; - this.kf = false; - this.frameId = -1; - var i, len = data.k.length; - this.v = createTypedArray('float32', len); - this.pv = createTypedArray('float32', len); - var arr = createTypedArray('float32', len); - this.vel = createTypedArray('float32', len); - for (i = 0; i < len; i += 1) { - this.v[i] = data.k[i] * this.mult; - this.pv[i] = data.k[i]; - } - this._isFirstFrame = true; - this.effectsSequence = []; - this.getValue = processEffectsSequence; - this.setVValue = setVValue; - this.addEffect = addEffect; - } - - function KeyframedValueProperty(elem, data, mult, container) { - this.propType = 'unidimensional'; - this.keyframes = data.k; - this.offsetTime = elem.data.st; - this.frameId = -1; - this._caching = {lastFrame: initFrame, lastIndex: 0, value: 0, _lastKeyframeIndex: -1}; - this.k = true; - this.kf = true; - this.data = data; - this.mult = mult || 1; - this.elem = elem; - this.container = container; - this.comp = elem.comp; - this.v = initFrame; - this.pv = initFrame; - this._isFirstFrame = true; - this.getValue = processEffectsSequence; - this.setVValue = setVValue; - this.interpolateValue = interpolateValue; - this.effectsSequence = [getValueAtCurrentTime.bind(this)]; - this.addEffect = addEffect; - } - - function KeyframedMultidimensionalProperty(elem, data, mult, container){ - this.propType = 'multidimensional'; - var i, len = data.k.length; - var s, e,to,ti; - for (i = 0; i < len - 1; i += 1) { - if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) { - s = data.k[i].s; - e = data.k[i + 1].s; - to = data.k[i].to; - ti = data.k[i].ti; - if((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0],s[1],e[0],e[1],s[0] + to[0],s[1] + to[1]) && bez.pointOnLine2D(s[0],s[1],e[0],e[1],e[0] + ti[0],e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0],s[1],s[2],e[0],e[1],e[2],s[0] + to[0],s[1] + to[1],s[2] + to[2]) && bez.pointOnLine3D(s[0],s[1],s[2],e[0],e[1],e[2],e[0] + ti[0],e[1] + ti[1],e[2] + ti[2]))){ - data.k[i].to = null; - data.k[i].ti = null; - } - if(s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) { - if(s.length === 2 || (s[2] === e[2] && to[2] === 0 && ti[2] === 0)) { - data.k[i].to = null; - data.k[i].ti = null; - } - } - } - } - this.effectsSequence = [getValueAtCurrentTime.bind(this)]; - this.keyframes = data.k; - this.offsetTime = elem.data.st; - this.k = true; - this.kf = true; - this._isFirstFrame = true; - this.mult = mult || 1; - this.elem = elem; - this.container = container; - this.comp = elem.comp; - this.getValue = processEffectsSequence; - this.setVValue = setVValue; - this.interpolateValue = interpolateValue; - this.frameId = -1; - var arrLen = data.k[0].s.length; - this.v = createTypedArray('float32', arrLen); - this.pv = createTypedArray('float32', arrLen); - for (i = 0; i < arrLen; i += 1) { - this.v[i] = initFrame; - this.pv[i] = initFrame; - } - this._caching={lastFrame:initFrame,lastIndex:0,value:createTypedArray('float32', arrLen)}; - this.addEffect = addEffect; - } - - function getProp(elem,data,type, mult, container) { - var p; - if(!data.k.length){ - p = new ValueProperty(elem,data, mult, container); - }else if(typeof(data.k[0]) === 'number'){ - p = new MultiDimensionalProperty(elem,data, mult, container); - }else{ - switch(type){ - case 0: - p = new KeyframedValueProperty(elem,data,mult, container); - break; - case 1: - p = new KeyframedMultidimensionalProperty(elem,data,mult, container); - break; - } - } - if(p.effectsSequence.length){ - container.addDynamicProperty(p); - } - return p; - } - - var ob = { - getProp: getProp - }; - return ob; -}()); -var TransformPropertyFactory = (function() { - - var defaultVector = [0,0] - - function applyToMatrix(mat) { - var _mdf = this._mdf; - this.iterateDynamicProperties(); - this._mdf = this._mdf || _mdf; - if (this.a) { - mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]); - } - if (this.s) { - mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]); - } - if (this.sk) { - mat.skewFromAxis(-this.sk.v, this.sa.v); - } - if (this.r) { - mat.rotate(-this.r.v); - } else { - mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]); - } - if (this.data.p.s) { - if (this.data.p.z) { - mat.translate(this.px.v, this.py.v, -this.pz.v); - } else { - mat.translate(this.px.v, this.py.v, 0); - } - } else { - mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]); - } - } - function processKeys(forceRender){ - if (this.elem.globalData.frameId === this.frameId) { - return; - } - if(this._isDirty) { - this.precalculateMatrix(); - this._isDirty = false; - } - - this.iterateDynamicProperties(); - - if (this._mdf || forceRender) { - this.v.cloneFromProps(this.pre.props); - if (this.appliedTransformations < 1) { - this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]); - } - if(this.appliedTransformations < 2) { - this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]); - } - if (this.sk && this.appliedTransformations < 3) { - this.v.skewFromAxis(-this.sk.v, this.sa.v); - } - if (this.r && this.appliedTransformations < 4) { - this.v.rotate(-this.r.v); - } else if (!this.r && this.appliedTransformations < 4){ - this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]); - } - if (this.autoOriented) { - var v1,v2, frameRate = this.elem.globalData.frameRate; - if(this.p && this.p.keyframes && this.p.getValueAtTime) { - if (this.p._caching.lastFrame+this.p.offsetTime <= this.p.keyframes[0].t) { - v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate,0); - v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0); - } else if(this.p._caching.lastFrame+this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) { - v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / frameRate), 0); - v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0); - } else { - v1 = this.p.pv; - v2 = this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime); - } - } else if(this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) { - v1 = []; - v2 = []; - var px = this.px, py = this.py, frameRate; - if (px._caching.lastFrame+px.offsetTime <= px.keyframes[0].t) { - v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate,0); - v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate,0); - v2[0] = px.getValueAtTime((px.keyframes[0].t) / frameRate,0); - v2[1] = py.getValueAtTime((py.keyframes[0].t) / frameRate,0); - } else if(px._caching.lastFrame+px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) { - v1[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t / frameRate),0); - v1[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t / frameRate),0); - v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate,0); - v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate,0); - } else { - v1 = [px.pv, py.pv]; - v2[0] = px.getValueAtTime((px._caching.lastFrame+px.offsetTime - 0.01) / frameRate,px.offsetTime); - v2[1] = py.getValueAtTime((py._caching.lastFrame+py.offsetTime - 0.01) / frameRate,py.offsetTime); - } - } else { - v1 = v2 = defaultVector - } - this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0])); - } - if(this.data.p && this.data.p.s){ - if(this.data.p.z) { - this.v.translate(this.px.v, this.py.v, -this.pz.v); - } else { - this.v.translate(this.px.v, this.py.v, 0); - } - }else{ - this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2]); - } - } - this.frameId = this.elem.globalData.frameId; - } - - function precalculateMatrix() { - if(!this.a.k) { - this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]); - this.appliedTransformations = 1; - } else { - return; - } - if(!this.s.effectsSequence.length) { - this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]); - this.appliedTransformations = 2; - } else { - return; - } - if(this.sk) { - if(!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) { - this.pre.skewFromAxis(-this.sk.v, this.sa.v); - this.appliedTransformations = 3; - } else { - return; - } - } - if (this.r) { - if(!this.r.effectsSequence.length) { - this.pre.rotate(-this.r.v); - this.appliedTransformations = 4; - } else { - return; - } - } else if(!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) { - this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]); - this.appliedTransformations = 4; - } - } - - function autoOrient(){ - // - //var prevP = this.getValueAtTime(); - } - - function addDynamicProperty(prop) { - this._addDynamicProperty(prop); - this.elem.addDynamicProperty(prop); - this._isDirty = true; - } - - function TransformProperty(elem,data,container){ - this.elem = elem; - this.frameId = -1; - this.propType = 'transform'; - this.data = data; - this.v = new Matrix(); - //Precalculated matrix with non animated properties - this.pre = new Matrix(); - this.appliedTransformations = 0; - this.initDynamicPropertyContainer(container || elem); - if(data.p && data.p.s){ - this.px = PropertyFactory.getProp(elem,data.p.x,0,0,this); - this.py = PropertyFactory.getProp(elem,data.p.y,0,0,this); - if(data.p.z){ - this.pz = PropertyFactory.getProp(elem,data.p.z,0,0,this); - } - }else{ - this.p = PropertyFactory.getProp(elem,data.p || {k:[0,0,0]},1,0,this); - } - if(data.rx) { - this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this); - this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this); - this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this); - if(data.or.k[0].ti) { - var i, len = data.or.k.length; - for(i=0;i= this._maxLength) { - this.doubleArrayLength(); - } - switch(type){ - case 'v': - arr = this.v; - break; - case 'i': - arr = this.i; - break; - case 'o': - arr = this.o; - break; - } - if(!arr[pos] || (arr[pos] && !replace)){ - arr[pos] = point_pool.newElement(); - } - arr[pos][0] = x; - arr[pos][1] = y; -}; - -ShapePath.prototype.setTripleAt = function(vX,vY,oX,oY,iX,iY,pos, replace) { - this.setXYAt(vX,vY,'v',pos, replace); - this.setXYAt(oX,oY,'o',pos, replace); - this.setXYAt(iX,iY,'i',pos, replace); -}; - -ShapePath.prototype.reverse = function() { - var newPath = new ShapePath(); - newPath.setPathData(this.c, this._length); - var vertices = this.v, outPoints = this.o, inPoints = this.i; - var init = 0; - if (this.c) { - newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false); - init = 1; - } - var cnt = this._length - 1; - var len = this._length; - - var i; - for (i = init; i < len; i += 1) { - newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false); - cnt -= 1; - } - return newPath; -}; -var ShapePropertyFactory = (function(){ - - var initFrame = -999999; - - function interpolateShape(frameNum, previousValue, caching) { - var iterationIndex = caching.lastIndex; - var keyPropS,keyPropE,isHold, j, k, jLen, kLen, perc, vertexValue; - var kf = this.keyframes; - if(frameNum < kf[0].t-this.offsetTime){ - keyPropS = kf[0].s[0]; - isHold = true; - iterationIndex = 0; - }else if(frameNum >= kf[kf.length - 1].t-this.offsetTime){ - keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0]; - /*if(kf[kf.length - 1].s){ - keyPropS = kf[kf.length - 1].s[0]; - }else{ - keyPropS = kf[kf.length - 2].e[0]; - }*/ - isHold = true; - }else{ - var i = iterationIndex; - var len = kf.length- 1,flag = true,keyData,nextKeyData; - while(flag){ - keyData = kf[i]; - nextKeyData = kf[i+1]; - if((nextKeyData.t - this.offsetTime) > frameNum){ - break; - } - if(i < len - 1){ - i += 1; - }else{ - flag = false; - } - } - isHold = keyData.h === 1; - iterationIndex = i; - if(!isHold){ - if(frameNum >= nextKeyData.t-this.offsetTime){ - perc = 1; - }else if(frameNum < keyData.t-this.offsetTime){ - perc = 0; - }else{ - var fnc; - if(keyData.__fnct){ - fnc = keyData.__fnct; - }else{ - fnc = BezierFactory.getBezierEasing(keyData.o.x,keyData.o.y,keyData.i.x,keyData.i.y).get; - keyData.__fnct = fnc; - } - perc = fnc((frameNum-(keyData.t-this.offsetTime))/((nextKeyData.t-this.offsetTime)-(keyData.t-this.offsetTime))); - } - keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0]; - } - keyPropS = keyData.s[0]; - } - jLen = previousValue._length; - kLen = keyPropS.i[0].length; - caching.lastIndex = iterationIndex; - - for(j=0;j endTime && frameNum > endTime)))){ - //// - this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0; - this.interpolateShape(frameNum, this.pv, this._caching); - //// - } - this._caching.lastFrame = frameNum; - return this.pv; - } - - function resetShape(){ - this.paths = this.localShapeCollection; - } - - function shapesEqual(shape1, shape2) { - if(shape1._length !== shape2._length || shape1.c !== shape2.c){ - return false; - } - var i, len = shape1._length; - for(i = 0; i < len; i += 1) { - if(shape1.v[i][0] !== shape2.v[i][0] - || shape1.v[i][1] !== shape2.v[i][1] - || shape1.o[i][0] !== shape2.o[i][0] - || shape1.o[i][1] !== shape2.o[i][1] - || shape1.i[i][0] !== shape2.i[i][0] - || shape1.i[i][1] !== shape2.i[i][1]) { - return false; - } - } - return true; - } - - function setVValue(newPath) { - if(!shapesEqual(this.v, newPath)) { - this.v = shape_pool.clone(newPath); - this.localShapeCollection.releaseShapes(); - this.localShapeCollection.addShape(this.v); - this._mdf = true; - this.paths = this.localShapeCollection; - } - } - - function processEffectsSequence() { - if (this.elem.globalData.frameId === this.frameId) { - return; - } else if (!this.effectsSequence.length) { - this._mdf = false; - return; - } - if (this.lock) { - this.setVValue(this.pv); - return; - } - this.lock = true; - this._mdf = false; - var finalValue = this.kf ? this.pv : this.data.ks ? this.data.ks.k : this.data.pt.k; - var i, len = this.effectsSequence.length; - for(i = 0; i < len; i += 1) { - finalValue = this.effectsSequence[i](finalValue); - } - this.setVValue(finalValue); - this.lock = false; - this.frameId = this.elem.globalData.frameId; - }; - - function ShapeProperty(elem, data, type){ - this.propType = 'shape'; - this.comp = elem.comp; - this.container = elem; - this.elem = elem; - this.data = data; - this.k = false; - this.kf = false; - this._mdf = false; - var pathData = type === 3 ? data.pt.k : data.ks.k; - this.v = shape_pool.clone(pathData); - this.pv = shape_pool.clone(this.v); - this.localShapeCollection = shapeCollection_pool.newShapeCollection(); - this.paths = this.localShapeCollection; - this.paths.addShape(this.v); - this.reset = resetShape; - this.effectsSequence = []; - } - - function addEffect(effectFunction) { - this.effectsSequence.push(effectFunction); - this.container.addDynamicProperty(this); - } - - ShapeProperty.prototype.interpolateShape = interpolateShape; - ShapeProperty.prototype.getValue = processEffectsSequence; - ShapeProperty.prototype.setVValue = setVValue; - ShapeProperty.prototype.addEffect = addEffect; - - function KeyframedShapeProperty(elem,data,type){ - this.propType = 'shape'; - this.comp = elem.comp; - this.elem = elem; - this.container = elem; - this.offsetTime = elem.data.st; - this.keyframes = type === 3 ? data.pt.k : data.ks.k; - this.k = true; - this.kf = true; - var i, len = this.keyframes[0].s[0].i.length; - var jLen = this.keyframes[0].s[0].i[0].length; - this.v = shape_pool.newElement(); - this.v.setPathData(this.keyframes[0].s[0].c, len); - this.pv = shape_pool.clone(this.v); - this.localShapeCollection = shapeCollection_pool.newShapeCollection(); - this.paths = this.localShapeCollection; - this.paths.addShape(this.v); - this.lastFrame = initFrame; - this.reset = resetShape; - this._caching = {lastFrame: initFrame, lastIndex: 0}; - this.effectsSequence = [interpolateShapeCurrentTime.bind(this)]; - } - KeyframedShapeProperty.prototype.getValue = processEffectsSequence; - KeyframedShapeProperty.prototype.interpolateShape = interpolateShape; - KeyframedShapeProperty.prototype.setVValue = setVValue; - KeyframedShapeProperty.prototype.addEffect = addEffect; - - var EllShapeProperty = (function(){ - - var cPoint = roundCorner; - - function EllShapeProperty(elem,data) { - /*this.v = { - v: createSizedArray(4), - i: createSizedArray(4), - o: createSizedArray(4), - c: true - };*/ - this.v = shape_pool.newElement(); - this.v.setPathData(true, 4); - this.localShapeCollection = shapeCollection_pool.newShapeCollection(); - this.paths = this.localShapeCollection; - this.localShapeCollection.addShape(this.v); - this.d = data.d; - this.elem = elem; - this.comp = elem.comp; - this.frameId = -1; - this.initDynamicPropertyContainer(elem); - this.p = PropertyFactory.getProp(elem,data.p,1,0,this); - this.s = PropertyFactory.getProp(elem,data.s,1,0,this); - if(this.dynamicProperties.length){ - this.k = true; - }else{ - this.k = false; - this.convertEllToPath(); - } - }; - - EllShapeProperty.prototype = { - reset: resetShape, - getValue: function (){ - if(this.elem.globalData.frameId === this.frameId){ - return; - } - this.frameId = this.elem.globalData.frameId; - this.iterateDynamicProperties(); - - if(this._mdf){ - this.convertEllToPath(); - } - }, - convertEllToPath: function() { - var p0 = this.p.v[0], p1 = this.p.v[1], s0 = this.s.v[0]/2, s1 = this.s.v[1]/2; - var _cw = this.d !== 3; - var _v = this.v; - _v.v[0][0] = p0; - _v.v[0][1] = p1 - s1; - _v.v[1][0] = _cw ? p0 + s0 : p0 - s0; - _v.v[1][1] = p1; - _v.v[2][0] = p0; - _v.v[2][1] = p1 + s1; - _v.v[3][0] = _cw ? p0 - s0 : p0 + s0; - _v.v[3][1] = p1; - _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint; - _v.i[0][1] = p1 - s1; - _v.i[1][0] = _cw ? p0 + s0 : p0 - s0; - _v.i[1][1] = p1 - s1 * cPoint; - _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint; - _v.i[2][1] = p1 + s1; - _v.i[3][0] = _cw ? p0 - s0 : p0 + s0; - _v.i[3][1] = p1 + s1 * cPoint; - _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint; - _v.o[0][1] = p1 - s1; - _v.o[1][0] = _cw ? p0 + s0 : p0 - s0; - _v.o[1][1] = p1 + s1 * cPoint; - _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint; - _v.o[2][1] = p1 + s1; - _v.o[3][0] = _cw ? p0 - s0 : p0 + s0; - _v.o[3][1] = p1 - s1 * cPoint; - } - } - - extendPrototype([DynamicPropertyContainer], EllShapeProperty); - - return EllShapeProperty; - }()); - - var StarShapeProperty = (function() { - - function StarShapeProperty(elem,data) { - this.v = shape_pool.newElement(); - this.v.setPathData(true, 0); - this.elem = elem; - this.comp = elem.comp; - this.data = data; - this.frameId = -1; - this.d = data.d; - this.initDynamicPropertyContainer(elem); - if(data.sy === 1){ - this.ir = PropertyFactory.getProp(elem,data.ir,0,0,this); - this.is = PropertyFactory.getProp(elem,data.is,0,0.01,this); - this.convertToPath = this.convertStarToPath; - } else { - this.convertToPath = this.convertPolygonToPath; - } - this.pt = PropertyFactory.getProp(elem,data.pt,0,0,this); - this.p = PropertyFactory.getProp(elem,data.p,1,0,this); - this.r = PropertyFactory.getProp(elem,data.r,0,degToRads,this); - this.or = PropertyFactory.getProp(elem,data.or,0,0,this); - this.os = PropertyFactory.getProp(elem,data.os,0,0.01,this); - this.localShapeCollection = shapeCollection_pool.newShapeCollection(); - this.localShapeCollection.addShape(this.v); - this.paths = this.localShapeCollection; - if(this.dynamicProperties.length){ - this.k = true; - }else{ - this.k = false; - this.convertToPath(); - } - }; - - StarShapeProperty.prototype = { - reset: resetShape, - getValue: function() { - if(this.elem.globalData.frameId === this.frameId){ - return; - } - this.frameId = this.elem.globalData.frameId; - this.iterateDynamicProperties(); - if(this._mdf){ - this.convertToPath(); - } - }, - convertStarToPath: function() { - var numPts = Math.floor(this.pt.v)*2; - var angle = Math.PI*2/numPts; - /*this.v.v.length = numPts; - this.v.i.length = numPts; - this.v.o.length = numPts;*/ - var longFlag = true; - var longRad = this.or.v; - var shortRad = this.ir.v; - var longRound = this.os.v; - var shortRound = this.is.v; - var longPerimSegment = 2*Math.PI*longRad/(numPts*2); - var shortPerimSegment = 2*Math.PI*shortRad/(numPts*2); - var i, rad,roundness,perimSegment, currentAng = -Math.PI/ 2; - currentAng += this.r.v; - var dir = this.data.d === 3 ? -1 : 1; - this.v._length = 0; - for(i=0;i= 1) { - segments.push({ - s: s - 1, - e: e - 1 - }); - } else { - segments.push({ - s: s, - e: 1 - }); - segments.push({ - s: 0, - e: e - 1 - }); - } - var shapeSegments = []; - var i, len = segments.length, segmentOb; - for (i = 0; i < len; i += 1) { - segmentOb = segments[i]; - if (segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength) { - - } else { - var shapeS, shapeE; - if (segmentOb.s * totalModifierLength <= addedLength) { - shapeS = 0; - } else { - shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength; - } - if(segmentOb.e * totalModifierLength >= addedLength + shapeLength) { - shapeE = 1; - } else { - shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength); - } - shapeSegments.push([shapeS, shapeE]); - } - } - if (!shapeSegments.length) { - shapeSegments.push([0, 0]); - } - return shapeSegments; -}; - -TrimModifier.prototype.releasePathsData = function(pathsData) { - var i, len = pathsData.length; - for (i = 0; i < len; i += 1) { - segments_length_pool.release(pathsData[i]); - } - pathsData.length = 0; - return pathsData; -}; - -TrimModifier.prototype.processShapes = function(_isFirstFrame) { - var s, e; - if (this._mdf || _isFirstFrame) { - var o = (this.o.v % 360) / 360; - if (o < 0) { - o += 1; - } - s = (this.s.v > 1 ? 1 : this.s.v < 0 ? 0 : this.s.v) + o; - e = (this.e.v > 1 ? 1 : this.e.v < 0 ? 0 : this.e.v) + o; - if (s === e) { - - } - if (s > e) { - var _s = s; - s = e; - e = _s; - } - s = Math.round(s * 10000) * 0.0001; - e = Math.round(e * 10000) * 0.0001; - this.sValue = s; - this.eValue = e; - } else { - s = this.sValue; - e = this.eValue; - } - var shapePaths; - var i, len = this.shapes.length, j, jLen; - var pathsData, pathData, totalShapeLength, totalModifierLength = 0; - - if (e === s) { - for (i = 0; i < len; i += 1) { - this.shapes[i].localShapeCollection.releaseShapes(); - this.shapes[i].shape._mdf = true; - this.shapes[i].shape.paths = this.shapes[i].localShapeCollection; - if (this._mdf) { - this.shapes[i].pathsData.length = 0; - } - } - } else if (!((e === 1 && s === 0) || (e===0 && s === 1))){ - var segments = [], shapeData, localShapeCollection; - for (i = 0; i < len; i += 1) { - shapeData = this.shapes[i]; - // if shape hasn't changed and trim properties haven't changed, cached previous path can be used - if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) { - shapeData.shape.paths = shapeData.localShapeCollection; - } else { - shapePaths = shapeData.shape.paths; - jLen = shapePaths._length; - totalShapeLength = 0; - if (!shapeData.shape._mdf && shapeData.pathsData.length) { - totalShapeLength = shapeData.totalShapeLength; - } else { - pathsData = this.releasePathsData(shapeData.pathsData); - for (j = 0; j < jLen; j += 1) { - pathData = bez.getSegmentsLength(shapePaths.shapes[j]); - pathsData.push(pathData); - totalShapeLength += pathData.totalLength; - } - shapeData.totalShapeLength = totalShapeLength; - shapeData.pathsData = pathsData; - } - - totalModifierLength += totalShapeLength; - shapeData.shape._mdf = true; - } - } - var shapeS = s, shapeE = e, addedLength = 0, edges; - for (i = len - 1; i >= 0; i -= 1) { - shapeData = this.shapes[i]; - if (shapeData.shape._mdf) { - localShapeCollection = shapeData.localShapeCollection; - localShapeCollection.releaseShapes(); - //if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group - if (this.m === 2 && len > 1) { - edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength); - addedLength += shapeData.totalShapeLength; - } else { - edges = [[shapeS, shapeE]]; - } - jLen = edges.length; - for (j = 0; j < jLen; j += 1) { - shapeS = edges[j][0]; - shapeE = edges[j][1]; - segments.length = 0; - if (shapeE <= 1) { - segments.push({ - s:shapeData.totalShapeLength * shapeS, - e:shapeData.totalShapeLength * shapeE - }); - } else if (shapeS >= 1) { - segments.push({ - s:shapeData.totalShapeLength * (shapeS - 1), - e:shapeData.totalShapeLength * (shapeE - 1) - }); - } else { - segments.push({ - s:shapeData.totalShapeLength * shapeS, - e:shapeData.totalShapeLength - }); - segments.push({ - s:0, - e:shapeData.totalShapeLength * (shapeE - 1) - }); - } - var newShapesData = this.addShapes(shapeData,segments[0]); - if (segments[0].s !== segments[0].e) { - if (segments.length > 1) { - var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1]; - if (lastShapeInCollection.c) { - var lastShape = newShapesData.pop(); - this.addPaths(newShapesData, localShapeCollection); - newShapesData = this.addShapes(shapeData, segments[1], lastShape); - } else { - this.addPaths(newShapesData, localShapeCollection); - newShapesData = this.addShapes(shapeData, segments[1]); - } - } - this.addPaths(newShapesData, localShapeCollection); - } - - } - shapeData.shape.paths = localShapeCollection; - } - } - } else if (this._mdf) { - for (i = 0; i < len; i += 1) { - //Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween. - //Don't remove this even if it's losing cached info. - this.shapes[i].pathsData.length = 0; - this.shapes[i].shape._mdf = true; - } - } -}; - -TrimModifier.prototype.addPaths = function(newPaths, localShapeCollection) { - var i, len = newPaths.length; - for (i = 0; i < len; i += 1) { - localShapeCollection.addShape(newPaths[i]); - } -}; - -TrimModifier.prototype.addSegment = function(pt1, pt2, pt3, pt4, shapePath, pos, newShape) { - shapePath.setXYAt(pt2[0], pt2[1], 'o', pos); - shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1); - if(newShape){ - shapePath.setXYAt(pt1[0], pt1[1], 'v', pos); - } - shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1); -}; - -TrimModifier.prototype.addSegmentFromArray = function(points, shapePath, pos, newShape) { - shapePath.setXYAt(points[1], points[5], 'o', pos); - shapePath.setXYAt(points[2], points[6], 'i', pos + 1); - if(newShape){ - shapePath.setXYAt(points[0], points[4], 'v', pos); - } - shapePath.setXYAt(points[3], points[7], 'v', pos + 1); -}; - -TrimModifier.prototype.addShapes = function(shapeData, shapeSegment, shapePath) { - var pathsData = shapeData.pathsData; - var shapePaths = shapeData.shape.paths.shapes; - var i, len = shapeData.shape.paths._length, j, jLen; - var addedLength = 0; - var currentLengthData,segmentCount; - var lengths; - var segment; - var shapes = []; - var initPos; - var newShape = true; - if (!shapePath) { - shapePath = shape_pool.newElement(); - segmentCount = 0; - initPos = 0; - } else { - segmentCount = shapePath._length; - initPos = shapePath._length; - } - shapes.push(shapePath); - for (i = 0; i < len; i += 1) { - lengths = pathsData[i].lengths; - shapePath.c = shapePaths[i].c; - jLen = shapePaths[i].c ? lengths.length : lengths.length + 1; - for (j = 1; j < jLen; j +=1) { - currentLengthData = lengths[j-1]; - if (addedLength + currentLengthData.addedLength < shapeSegment.s) { - addedLength += currentLengthData.addedLength; - shapePath.c = false; - } else if(addedLength > shapeSegment.e) { - shapePath.c = false; - break; - } else { - if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) { - this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape); - newShape = false; - } else { - segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength)/currentLengthData.addedLength,(shapeSegment.e - addedLength)/currentLengthData.addedLength, lengths[j-1]); - this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); - // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape); - newShape = false; - shapePath.c = false; - } - addedLength += currentLengthData.addedLength; - segmentCount += 1; - } - } - if (shapePaths[i].c && lengths.length) { - currentLengthData = lengths[j - 1]; - if (addedLength <= shapeSegment.e) { - var segmentLength = lengths[j - 1].addedLength; - if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) { - this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape); - newShape = false; - } else { - segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]); - this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); - // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape); - newShape = false; - shapePath.c = false; - } - } else { - shapePath.c = false; - } - addedLength += currentLengthData.addedLength; - segmentCount += 1; - } - if (shapePath._length) { - shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos); - shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1],'o', shapePath._length - 1); - } - if (addedLength > shapeSegment.e) { - break; - } - if (i < len - 1) { - shapePath = shape_pool.newElement(); - newShape = true; - shapes.push(shapePath); - segmentCount = 0; - } - } - return shapes; -}; - - -ShapeModifiers.registerModifier('tm', TrimModifier); -function RoundCornersModifier(){} -extendPrototype([ShapeModifier],RoundCornersModifier); -RoundCornersModifier.prototype.initModifierProperties = function(elem,data){ - this.getValue = this.processKeys; - this.rd = PropertyFactory.getProp(elem,data.r,0,null,this); - this._isAnimated = !!this.rd.effectsSequence.length; -}; - -RoundCornersModifier.prototype.processPath = function(path, round){ - var cloned_path = shape_pool.newElement(); - cloned_path.c = path.c; - var i, len = path._length; - var currentV,currentI,currentO,closerV, newV,newO,newI,distance,newPosPerc,index = 0; - var vX,vY,oX,oY,iX,iY; - for(i=0;i0){ - pos -= 1; - //this._elements.unshift(arr.splice(pos,1)[0]); - this._elements.unshift(arr[pos]); - cont += 1; - } - if(this.dynamicProperties.length){ - this.k = true; - }else{ - this.getValue(true); - } -}; - -RepeaterModifier.prototype.resetElements = function(elements){ - var i, len = elements.length; - for(i = 0; i < len; i += 1) { - elements[i]._processed = false; - if(elements[i].ty === 'gr'){ - this.resetElements(elements[i].it); - } - } -}; - -RepeaterModifier.prototype.cloneElements = function(elements){ - var i, len = elements.length; - var newElements = JSON.parse(JSON.stringify(elements)); - this.resetElements(newElements); - return newElements; -}; - -RepeaterModifier.prototype.changeGroupRender = function(elements, renderFlag) { - var i, len = elements.length; - for(i = 0; i < len; i += 1) { - elements[i]._render = renderFlag; - if(elements[i].ty === 'gr') { - this.changeGroupRender(elements[i].it, renderFlag); - } - } -}; - -RepeaterModifier.prototype.processShapes = function(_isFirstFrame) { - var items, itemsTransform, i, dir, cont; - if(this._mdf || _isFirstFrame){ - var copies = Math.ceil(this.c.v); - if(this._groups.length < copies){ - while(this._groups.length < copies){ - var group = { - it:this.cloneElements(this._elements), - ty:'gr' - }; - group.it.push({"a":{"a":0,"ix":1,"k":[0,0]},"nm":"Transform","o":{"a":0,"ix":7,"k":100},"p":{"a":0,"ix":2,"k":[0,0]},"r":{"a":1,"ix":6,"k":[{s:0,e:0,t:0},{s:0,e:0,t:1}]},"s":{"a":0,"ix":3,"k":[100,100]},"sa":{"a":0,"ix":5,"k":0},"sk":{"a":0,"ix":4,"k":0},"ty":"tr"}); - - this.arr.splice(0,0,group); - this._groups.splice(0,0,group); - this._currentCopies += 1; - } - this.elem.reloadShapes(); - } - cont = 0; - var renderFlag; - for(i = 0; i <= this._groups.length - 1; i += 1){ - renderFlag = cont < copies; - this._groups[i]._render = renderFlag; - this.changeGroupRender(this._groups[i].it, renderFlag); - cont += 1; - } - - this._currentCopies = copies; - //// - - var offset = this.o.v; - var offsetModulo = offset%1; - var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset); - var k; - var tMat = this.tr.v.props; - var pProps = this.pMatrix.props; - var rProps = this.rMatrix.props; - var sProps = this.sMatrix.props; - this.pMatrix.reset(); - this.rMatrix.reset(); - this.sMatrix.reset(); - this.tMatrix.reset(); - this.matrix.reset(); - var iteration = 0; - - if(offset > 0) { - while(iterationroundOffset){ - this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true); - iteration -= 1; - } - if(offsetModulo){ - this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, - offsetModulo, true); - iteration -= offsetModulo; - } - } - i = this.data.m === 1 ? 0 : this._currentCopies - 1; - dir = this.data.m === 1 ? 1 : -1; - cont = this._currentCopies; - var j, jLen; - while(cont){ - items = this.elemsData[i].it; - itemsTransform = items[items.length - 1].transform.mProps.v.props; - jLen = itemsTransform.length; - items[items.length - 1].transform.mProps._mdf = true; - items[items.length - 1].transform.op._mdf = true; - items[items.length - 1].transform.op.v = this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1)); - if(iteration !== 0){ - if((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)){ - this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false); - } - this.matrix.transform(rProps[0],rProps[1],rProps[2],rProps[3],rProps[4],rProps[5],rProps[6],rProps[7],rProps[8],rProps[9],rProps[10],rProps[11],rProps[12],rProps[13],rProps[14],rProps[15]); - this.matrix.transform(sProps[0],sProps[1],sProps[2],sProps[3],sProps[4],sProps[5],sProps[6],sProps[7],sProps[8],sProps[9],sProps[10],sProps[11],sProps[12],sProps[13],sProps[14],sProps[15]); - this.matrix.transform(pProps[0],pProps[1],pProps[2],pProps[3],pProps[4],pProps[5],pProps[6],pProps[7],pProps[8],pProps[9],pProps[10],pProps[11],pProps[12],pProps[13],pProps[14],pProps[15]); - - for(j=0;j 0.01){ - return false; - } - i += 1; - } - return true; -}; - -GradientProperty.prototype.checkCollapsable = function() { - if (this.o.length/2 !== this.c.length/4) { - return false; - } - if (this.data.k.k[0].s) { - var i = 0, len = this.data.k.k.length; - while (i < len) { - if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) { - return false; - } - i += 1; - } - } else if(!this.comparePoints(this.data.k.k, this.data.p)) { - return false; - } - return true; -}; - -GradientProperty.prototype.getValue = function(forceRender){ - this.prop.getValue(); - this._mdf = false; - this._cmdf = false; - this._omdf = false; - if(this.prop._mdf || forceRender){ - var i, len = this.data.p*4; - var mult, val; - for(i=0;i= currentLength + animatorOffset || !points) { - perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength; - xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc; - yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc; - matrixHelper.translate(-alignment[0]*letters[i].an/200, -(alignment[1] * yOff / 100)); - flag = false; - } else if (points) { - segmentLength += currentPoint.partialLength; - pointInd += 1; - if (pointInd >= points.length) { - pointInd = 0; - segmentInd += 1; - if (!segments[segmentInd]) { - if (mask.v.c) { - pointInd = 0; - segmentInd = 0; - points = segments[segmentInd].points; - } else { - segmentLength -= currentPoint.partialLength; - points = null; - } - } else { - points = segments[segmentInd].points; - } - } - if (points) { - prevPoint = currentPoint; - currentPoint = points[pointInd]; - partialLength = currentPoint.partialLength; - } - } - } - offf = letters[i].an / 2 - letters[i].add; - matrixHelper.translate(-offf, 0, 0); - } else { - offf = letters[i].an/2 - letters[i].add; - matrixHelper.translate(-offf,0,0); - - // Grouping alignment - matrixHelper.translate(-alignment[0]*letters[i].an/200, -alignment[1]*yOff/100, 0); - } - - lineLength += letters[i].l/2; - for(j=0;j 1; - if(this.kf) { - this.addEffect(this.getKeyframeValue.bind(this)); - } - return this.kf; -} - -TextProperty.prototype.addEffect = function(effectFunction) { - this.effectsSequence.push(effectFunction); - this.elem.addDynamicProperty(this); -}; - -TextProperty.prototype.getValue = function(_finalValue) { - if((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) { - return; - } - this.currentData.t = this.data.d.k[this.keysIndex].s.t; - var currentValue = this.currentData; - var currentIndex = this.keysIndex; - if(this.lock) { - this.setCurrentData(this.currentData); - return; - } - this.lock = true; - this._mdf = false; - var multipliedValue; - var i, len = this.effectsSequence.length; - var finalValue = _finalValue || this.data.d.k[this.keysIndex].s; - for(i = 0; i < len; i += 1) { - //Checking if index changed to prevent creating a new object every time the expression updates. - if(currentIndex !== this.keysIndex) { - finalValue = this.effectsSequence[i](finalValue, finalValue.t); - } else { - finalValue = this.effectsSequence[i](this.currentData, finalValue.t); - } - } - if(currentValue !== finalValue) { - this.setCurrentData(finalValue); - } - this.pv = this.v = this.currentData; - this.lock = false; - this.frameId = this.elem.globalData.frameId; -} - -TextProperty.prototype.getKeyframeValue = function() { - var textKeys = this.data.d.k, textDocumentData; - var frameNum = this.elem.comp.renderedFrame; - var i = 0, len = textKeys.length; - while(i <= len - 1) { - textDocumentData = textKeys[i].s; - if(i === len - 1 || textKeys[i+1].t > frameNum){ - break; - } - i += 1; - } - if(this.keysIndex !== i) { - this.keysIndex = i; - } - return this.data.d.k[this.keysIndex].s; -}; - -TextProperty.prototype.buildFinalText = function(text) { - var combinedCharacters = FontManager.getCombinedCharacterCodes(); - var charactersArray = []; - var i = 0, len = text.length; - var charCode; - while (i < len) { - charCode = text.charCodeAt(i); - if (combinedCharacters.indexOf(charCode) !== -1) { - charactersArray[charactersArray.length - 1] += text.charAt(i); - } else { - if (charCode >= 0xD800 && charCode <= 0xDBFF) { - charCode = text.charCodeAt(i + 1); - if (charCode >= 0xDC00 && charCode <= 0xDFFF) { - charactersArray.push(text.substr(i, 2)); - ++i; - } else { - charactersArray.push(text.charAt(i)); - } - } else { - charactersArray.push(text.charAt(i)); - } - } - i += 1; - } - return charactersArray; -} - -TextProperty.prototype.completeTextData = function(documentData) { - documentData.__complete = true; - var fontManager = this.elem.globalData.fontManager; - var data = this.data; - var letters = []; - var i, len; - var newLineFlag, index = 0, val; - var anchorGrouping = data.m.g; - var currentSize = 0, currentPos = 0, currentLine = 0, lineWidths = []; - var lineWidth = 0; - var maxLineWidth = 0; - var j, jLen; - var fontData = fontManager.getFontByName(documentData.f); - var charData, cLength = 0; - var styles = fontData.fStyle ? fontData.fStyle.split(' ') : []; - - var fWeight = 'normal', fStyle = 'normal'; - len = styles.length; - var styleName; - for(i=0;i boxWidth && finalText[i] !== ' '){ - if(lastSpaceIndex === -1){ - len += 1; - } else { - i = lastSpaceIndex; - } - currentHeight += documentData.finalLineHeight || documentData.finalSize*1.2; - finalText.splice(i, lastSpaceIndex === i ? 1 : 0,"\r"); - //finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i); - lastSpaceIndex = -1; - lineWidth = 0; - }else { - lineWidth += cLength; - lineWidth += trackingOffset; - } - } - currentHeight += fontData.ascent*documentData.finalSize/100; - if(this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) { - documentData.finalSize -= 1; - documentData.finalLineHeight = documentData.finalSize * documentData.lh / documentData.s; - } else { - documentData.finalText = finalText; - len = documentData.finalText.length; - flag = false; - } - } - - } - lineWidth = - trackingOffset; - cLength = 0; - var uncollapsedSpaces = 0; - var currentChar; - for (i = 0;i < len ;i += 1) { - newLineFlag = false; - currentChar = documentData.finalText[i]; - charCode = currentChar.charCodeAt(0); - if (charCode === 13 || charCode === 3) { - uncollapsedSpaces = 0; - lineWidths.push(lineWidth); - maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth; - lineWidth = - 2 * trackingOffset; - val = ''; - newLineFlag = true; - currentLine += 1; - }else{ - val = currentChar; - } - if(fontManager.chars){ - charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily); - cLength = newLineFlag ? 0 : charData.w*documentData.finalSize/100; - }else{ - //var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize); - //tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily; - cLength = fontManager.measureText(val, documentData.f, documentData.finalSize); - } - - // - if(currentChar === ' '){ - uncollapsedSpaces += cLength + trackingOffset; - } else { - lineWidth += cLength + trackingOffset + uncollapsedSpaces; - uncollapsedSpaces = 0; - } - letters.push({l:cLength,an:cLength,add:currentSize,n:newLineFlag, anIndexes:[], val: val, line: currentLine, animatorJustifyOffset: 0}); - if(anchorGrouping == 2){ - currentSize += cLength; - if(val === '' || val === ' ' || i === len - 1){ - if(val === '' || val === ' '){ - currentSize -= cLength; - } - while(currentPos<=i){ - letters[currentPos].an = currentSize; - letters[currentPos].ind = index; - letters[currentPos].extra = cLength; - currentPos += 1; - } - index += 1; - currentSize = 0; - } - }else if(anchorGrouping == 3){ - currentSize += cLength; - if(val === '' || i === len - 1){ - if(val === ''){ - currentSize -= cLength; - } - while(currentPos<=i){ - letters[currentPos].an = currentSize; - letters[currentPos].ind = index; - letters[currentPos].extra = cLength; - currentPos += 1; - } - currentSize = 0; - index += 1; - } - }else{ - letters[index].ind = index; - letters[index].extra = 0; - index += 1; - } - } - documentData.l = letters; - maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth; - lineWidths.push(lineWidth); - if(documentData.sz){ - documentData.boxWidth = documentData.sz[0]; - documentData.justifyOffset = 0; - }else{ - documentData.boxWidth = maxLineWidth; - switch(documentData.j){ - case 1: - documentData.justifyOffset = - documentData.boxWidth; - break; - case 2: - documentData.justifyOffset = - documentData.boxWidth/2; - break; - default: - documentData.justifyOffset = 0; - } - } - documentData.lineWidths = lineWidths; - - var animators = data.a, animatorData, letterData; - jLen = animators.length; - var based, ind, indexes = []; - for(j=0;j 0) { - x1 = this.ne.v / 100.0; - } - else { - y1 = -this.ne.v / 100.0; - } - if(this.xe.v > 0) { - x2 = 1.0 - this.xe.v / 100.0; - } - else { - y2 = 1.0 + this.xe.v / 100.0; - } - var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get; - - var mult = 0; - var s = this.finalS; - var e = this.finalE; - var type = this.data.sh; - if (type === 2){ - if (e === s) { - mult = ind >= e ? 1 : 0; - } else { - mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1)); - } - mult = easer(mult); - } else if(type === 3) { - if (e === s) { - mult = ind >= e ? 0 : 1; - }else{ - mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s),1)); - } - - mult = easer(mult); - } else if (type === 4) { - if (e === s) { - mult = 0; - } else { - mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1)); - if (mult < 0.5) { - mult *= 2; - } else { - mult = 1 - 2 * (mult - 0.5); - } - } - mult = easer(mult); - } else if (type === 5) { - if (e === s){ - mult = 0; - } else { - var tot = e - s; - /*ind += 0.5; - mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind;*/ - ind = min(max(0, ind + 0.5 - s), e - s); - var x = -tot/2+ind; - var a = tot/2; - mult = Math.sqrt(1 - (x * x) / (a * a)); - } - mult = easer(mult); - } else if (type === 6) { - if (e === s){ - mult = 0; - } else { - ind = min(max(0, ind + 0.5 - s), e - s); - mult = (1 + (Math.cos((Math.PI + Math.PI * 2 * (ind) / (e - s))))) / 2; - } - mult = easer(mult); - } else { - if (ind >= floor(s)) { - if (ind - s < 0) { - mult = max(0, min(min(e, 1) - (s - ind), 1)); - } else { - mult = max(0, min(e - ind, 1)); - } - } - mult = easer(mult); - } - return mult*this.a.v; - }, - getValue: function(newCharsFlag) { - this.iterateDynamicProperties(); - this._mdf = newCharsFlag || this._mdf; - this._currentTextLength = this.elem.textProperty.currentData.l.length || 0; - if(newCharsFlag && this.data.r === 2) { - this.e.v = this._currentTextLength; - } - var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars; - var o = this.o.v/divisor; - var s = this.s.v/divisor + o; - var e = (this.e.v/divisor) + o; - if(s>e){ - var _s = s; - s = e; - e = _s; - } - this.finalS = s; - this.finalE = e; - } - } - extendPrototype([DynamicPropertyContainer], TextSelectorProp); - - function getTextSelectorProp(elem, data,arr) { - return new TextSelectorProp(elem, data, arr); - } - - return { - getTextSelectorProp: getTextSelectorProp - }; -}()); - - -var pool_factory = (function() { - return function(initialLength, _create, _release, _clone) { - - var _length = 0; - var _maxLength = initialLength; - var pool = createSizedArray(_maxLength); - - var ob = { - newElement: newElement, - release: release - }; - - function newElement(){ - var element; - if(_length){ - _length -= 1; - element = pool[_length]; - } else { - element = _create(); - } - return element; - } - - function release(element) { - if(_length === _maxLength) { - pool = pooling.double(pool); - _maxLength = _maxLength*2; - } - if (_release) { - _release(element); - } - pool[_length] = element; - _length += 1; - } - - function clone() { - var clonedElement = newElement(); - return _clone(clonedElement); - } - - return ob; - }; -}()); - -var pooling = (function(){ - - function double(arr){ - return arr.concat(createSizedArray(arr.length)); - } - - return { - double: double - }; -}()); -var point_pool = (function(){ - - function create() { - return createTypedArray('float32', 2); - } - return pool_factory(8, create); -}()); -var shape_pool = (function(){ - - function create() { - return new ShapePath(); - } - - function release(shapePath) { - var len = shapePath._length, i; - for(i = 0; i < len; i += 1) { - point_pool.release(shapePath.v[i]); - point_pool.release(shapePath.i[i]); - point_pool.release(shapePath.o[i]); - shapePath.v[i] = null; - shapePath.i[i] = null; - shapePath.o[i] = null; - } - shapePath._length = 0; - shapePath.c = false; - } - - function clone(shape) { - var cloned = factory.newElement(); - var i, len = shape._length === undefined ? shape.v.length : shape._length; - cloned.setLength(len); - cloned.c = shape.c; - var pt; - - for(i = 0; i < len; i += 1) { - cloned.setTripleAt(shape.v[i][0],shape.v[i][1],shape.o[i][0],shape.o[i][1],shape.i[i][0],shape.i[i][1], i); - } - return cloned; - } - - var factory = pool_factory(4, create, release); - factory.clone = clone; - - return factory; -}()); -var shapeCollection_pool = (function(){ - var ob = { - newShapeCollection: newShapeCollection, - release: release - }; - - var _length = 0; - var _maxLength = 4; - var pool = createSizedArray(_maxLength); - - function newShapeCollection(){ - var shapeCollection; - if(_length){ - _length -= 1; - shapeCollection = pool[_length]; - } else { - shapeCollection = new ShapeCollection(); - } - return shapeCollection; - } - - function release(shapeCollection) { - var i, len = shapeCollection._length; - for(i = 0; i < len; i += 1) { - shape_pool.release(shapeCollection.shapes[i]); - } - shapeCollection._length = 0; - - if(_length === _maxLength) { - pool = pooling.double(pool); - _maxLength = _maxLength*2; - } - pool[_length] = shapeCollection; - _length += 1; - } - - return ob; -}()); -var segments_length_pool = (function(){ - - function create() { - return { - lengths: [], - totalLength: 0 - }; - } - - function release(element) { - var i, len = element.lengths.length; - for(i=0;i= 0; i--) { - if (!this.elements[i]) { - data = this.layers[i]; - if(data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st)) - { - this.buildItem(i); - } - } - this.completeLayers = this.elements[i] ? this.completeLayers:false; - } - this.checkPendingElements(); -}; - -BaseRenderer.prototype.createItem = function(layer){ - switch(layer.ty){ - case 2: - return this.createImage(layer); - case 0: - return this.createComp(layer); - case 1: - return this.createSolid(layer); - case 3: - return this.createNull(layer); - case 4: - return this.createShape(layer); - case 5: - return this.createText(layer); - case 6: - return this.createAudio(layer); - case 13: - return this.createCamera(layer); - } - return this.createNull(layer); -}; - -BaseRenderer.prototype.createCamera = function(){ - throw new Error('You\'re using a 3d camera. Try the html renderer.'); -}; - -BaseRenderer.prototype.createAudio = function(data){ - return new AudioElement(data, this.globalData, this); -}; - -BaseRenderer.prototype.buildAllItems = function(){ - var i, len = this.layers.length; - for(i=0;i= 0; i--) { - if(this.completeLayers || this.elements[i]){ - this.elements[i].prepareFrame(num - this.layers[i].st); - } - } - if(this.globalData._mdf) { - for (i = 0; i < len; i += 1) { - if(this.completeLayers || this.elements[i]){ - this.elements[i].renderFrame(); - } - } - } -}; - -SVGRenderer.prototype.appendElementInPos = function(element, pos){ - var newElement = element.getBaseElement(); - if(!newElement){ - return; - } - var i = 0; - var nextElement; - while(ielementRel && fillType === 'meet' || animationRelelementRel && fillType === 'slice'))){ - this.transformCanvas.tx = (elementWidth-this.transformCanvas.w*(elementHeight/this.transformCanvas.h))/2*this.renderConfig.dpr; - } else if(xPos === 'xMax' && ((animationRelelementRel && fillType === 'slice'))){ - this.transformCanvas.tx = (elementWidth-this.transformCanvas.w*(elementHeight/this.transformCanvas.h))*this.renderConfig.dpr; - } else { - this.transformCanvas.tx = 0; - } - if(yPos === 'YMid' && ((animationRel>elementRel && fillType==='meet') || (animationRelelementRel && fillType==='meet') || (animationRel= 0; i-=1) { - if(this.elements[i]) { - this.elements[i].destroy(); - } - } - this.elements.length = 0; - this.globalData.canvasContext = null; - this.animationItem.container = null; - this.destroyed = true; -}; - -CanvasRenderer.prototype.renderFrame = function(num, forceRender){ - if((this.renderedFrame === num && this.renderConfig.clearCanvas === true && !forceRender) || this.destroyed || num === -1){ - return; - } - this.renderedFrame = num; - this.globalData.frameNum = num - this.animationItem._isFirstFrame; - this.globalData.frameId += 1; - this.globalData._mdf = !this.renderConfig.clearCanvas || forceRender; - this.globalData.projectInterface.currentFrame = num; - - // console.log('--------'); - // console.log('NEW: ',num); - var i, len = this.layers.length; - if(!this.completeLayers){ - this.checkLayers(num); - } - - for (i = 0; i < len; i++) { - if(this.completeLayers || this.elements[i]){ - this.elements[i].prepareFrame(num - this.layers[i].st); - } - } - if(this.globalData._mdf) { - if(this.renderConfig.clearCanvas === true){ - this.canvasContext.clearRect(0, 0, this.transformCanvas.w, this.transformCanvas.h); - }else{ - this.save(); - } - for (i = len - 1; i >= 0; i-=1) { - if(this.completeLayers || this.elements[i]){ - this.elements[i].renderFrame(); - } - } - if(this.renderConfig.clearCanvas !== true){ - this.restore(); - } - } -}; - -CanvasRenderer.prototype.buildItem = function(pos){ - var elements = this.elements; - if(elements[pos] || this.layers[pos].ty == 99){ - return; - } - var element = this.createItem(this.layers[pos], this,this.globalData); - elements[pos] = element; - element.initExpressions(); - /*if(this.layers[pos].ty === 0){ - element.resize(this.globalData.transformCanvas); - }*/ -}; - -CanvasRenderer.prototype.checkPendingElements = function(){ - while(this.pendingElements.length){ - var element = this.pendingElements.pop(); - element.checkParenting(); - } -}; - -CanvasRenderer.prototype.hide = function(){ - this.animationItem.container.style.display = 'none'; -}; - -CanvasRenderer.prototype.show = function(){ - this.animationItem.container.style.display = 'block'; -}; - -function MaskElement(data,element,globalData) { - this.data = data; - this.element = element; - this.globalData = globalData; - this.storedData = []; - this.masksProperties = this.data.masksProperties || []; - this.maskElement = null; - var defs = this.globalData.defs; - var i, len = this.masksProperties ? this.masksProperties.length : 0; - this.viewData = createSizedArray(len); - this.solidPath = ''; - - - var path, properties = this.masksProperties; - var count = 0; - var currentMasks = []; - var j, jLen; - var layerId = createElementID(); - var rect, expansor, feMorph,x; - var maskType = 'clipPath', maskRef = 'clip-path'; - for (i = 0; i < len; i++) { - if((properties[i].mode !== 'a' && properties[i].mode !== 'n')|| properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x){ - maskType = 'mask'; - maskRef = 'mask'; - } - - if((properties[i].mode == 's' || properties[i].mode == 'i') && count === 0){ - rect = createNS( 'rect'); - rect.setAttribute('fill', '#ffffff'); - rect.setAttribute('width', this.element.comp.data.w || 0); - rect.setAttribute('height', this.element.comp.data.h || 0); - currentMasks.push(rect); - } else { - rect = null; - } - - path = createNS( 'path'); - if(properties[i].mode == 'n') { - // TODO move this to a factory or to a constructor - this.viewData[i] = { - op: PropertyFactory.getProp(this.element,properties[i].o,0,0.01,this.element), - prop: ShapePropertyFactory.getShapeProp(this.element,properties[i],3), - elem: path, - lastPath: '' - }; - defs.appendChild(path); - continue; - } - count += 1; - - path.setAttribute('fill', properties[i].mode === 's' ? '#000000':'#ffffff'); - path.setAttribute('clip-rule','nonzero'); - var filterID; - - if (properties[i].x.k !== 0) { - maskType = 'mask'; - maskRef = 'mask'; - x = PropertyFactory.getProp(this.element,properties[i].x,0,null,this.element); - filterID = createElementID(); - expansor = createNS('filter'); - expansor.setAttribute('id',filterID); - feMorph = createNS('feMorphology'); - feMorph.setAttribute('operator','erode'); - feMorph.setAttribute('in','SourceGraphic'); - feMorph.setAttribute('radius','0'); - expansor.appendChild(feMorph); - defs.appendChild(expansor); - path.setAttribute('stroke', properties[i].mode === 's' ? '#000000':'#ffffff'); - } else { - feMorph = null; - x = null; - } - - // TODO move this to a factory or to a constructor - this.storedData[i] = { - elem: path, - x: x, - expan: feMorph, - lastPath: '', - lastOperator:'', - filterId:filterID, - lastRadius:0 - }; - if(properties[i].mode == 'i'){ - jLen = currentMasks.length; - var g = createNS('g'); - for(j=0;j 0){ - this.maskElement.setAttribute('id', layerId); - this.element.maskedElement.setAttribute(maskRef, "url(" + locationHref + "#" + layerId + ")"); - defs.appendChild(this.maskElement); - } - if (this.viewData.length) { - this.element.addRenderableComponent(this); - } - -} - -MaskElement.prototype.getMaskProperty = function(pos){ - return this.viewData[pos].prop; -}; - -MaskElement.prototype.renderFrame = function (isFirstFrame) { - var finalMat = this.element.finalTransform.mat; - var i, len = this.masksProperties.length; - for (i = 0; i < len; i++) { - if(this.viewData[i].prop._mdf || isFirstFrame){ - this.drawPath(this.masksProperties[i],this.viewData[i].prop.v,this.viewData[i]); - } - if(this.viewData[i].op._mdf || isFirstFrame){ - this.viewData[i].elem.setAttribute('fill-opacity',this.viewData[i].op.v); - } - if(this.masksProperties[i].mode !== 'n'){ - if(this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)){ - this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS()) - } - if(this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)){ - var feMorph = this.storedData[i].expan; - if(this.storedData[i].x.v < 0){ - if(this.storedData[i].lastOperator !== 'erode'){ - this.storedData[i].lastOperator = 'erode'; - this.storedData[i].elem.setAttribute('filter','url(' + locationHref + '#'+this.storedData[i].filterId+')'); - } - feMorph.setAttribute('radius',-this.storedData[i].x.v); - }else{ - if(this.storedData[i].lastOperator !== 'dilate'){ - this.storedData[i].lastOperator = 'dilate'; - this.storedData[i].elem.setAttribute('filter',null); - } - this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v*2); - - } - } - } - } -}; - -MaskElement.prototype.getMaskelement = function () { - return this.maskElement; -}; - -MaskElement.prototype.createLayerSolidPath = function(){ - var path = 'M0,0 '; - path += ' h' + this.globalData.compSize.w ; - path += ' v' + this.globalData.compSize.h ; - path += ' h-' + this.globalData.compSize.w ; - path += ' v-' + this.globalData.compSize.h + ' '; - return path; -}; - -MaskElement.prototype.drawPath = function(pathData,pathNodes,viewData){ - var pathString = " M"+pathNodes.v[0][0]+','+pathNodes.v[0][1]; - var i, len; - len = pathNodes._length; - for(i=1;i 1){ - pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1]; - } - //pathNodes.__renderedString = pathString; - - if(viewData.lastPath !== pathString){ - var pathShapeValue = ''; - if(viewData.elem){ - if(pathNodes.c){ - pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString; - } - viewData.elem.setAttribute('d',pathShapeValue); - } - viewData.lastPath = pathString; - } -}; - -MaskElement.prototype.destroy = function(){ - this.element = null; - this.globalData = null; - this.maskElement = null; - this.data = null; - this.masksProperties = null; -}; - -/** - * @file - * Handles AE's layer parenting property. - * - */ - -function HierarchyElement(){} - -HierarchyElement.prototype = { - /** - * @function - * Initializes hierarchy properties - * - */ - initHierarchy: function() { - //element's parent list - this.hierarchy = []; - //if element is parent of another layer _isParent will be true - this._isParent = false; - this.checkParenting(); - }, - /** - * @function - * Sets layer's hierarchy. - * @param {array} hierarch - * layer's parent list - * - */ - setHierarchy: function(hierarchy){ - this.hierarchy = hierarchy; - }, - /** - * @function - * Sets layer as parent. - * - */ - setAsParent: function() { - this._isParent = true; - }, - /** - * @function - * Searches layer's parenting chain - * - */ - checkParenting: function(){ - if (this.data.parent !== undefined){ - this.comp.buildElementParenting(this, this.data.parent, []); - } - } -}; -/** - * @file - * Handles element's layer frame update. - * Checks layer in point and out point - * - */ - -function FrameElement(){} - -FrameElement.prototype = { - /** - * @function - * Initializes frame related properties. - * - */ - initFrame: function(){ - //set to true when inpoint is rendered - this._isFirstFrame = false; - //list of animated properties - this.dynamicProperties = []; - // If layer has been modified in current tick this will be true - this._mdf = false; - }, - /** - * @function - * Calculates all dynamic values - * - * @param {number} num - * current frame number in Layer's time - * @param {boolean} isVisible - * if layers is currently in range - * - */ - prepareProperties: function(num, isVisible) { - var i, len = this.dynamicProperties.length; - for (i = 0;i < len; i += 1) { - if (isVisible || (this._isParent && this.dynamicProperties[i].propType === 'transform')) { - this.dynamicProperties[i].getValue(); - if (this.dynamicProperties[i]._mdf) { - this.globalData._mdf = true; - this._mdf = true; - } - } - } - }, - addDynamicProperty: function(prop) { - if(this.dynamicProperties.indexOf(prop) === -1) { - this.dynamicProperties.push(prop); - } - } -}; -function TransformElement(){} - -TransformElement.prototype = { - initTransform: function() { - this.finalTransform = { - mProp: this.data.ks ? TransformPropertyFactory.getTransformProperty(this, this.data.ks, this) : {o:0}, - _matMdf: false, - _opMdf: false, - mat: new Matrix() - }; - if (this.data.ao) { - this.finalTransform.mProp.autoOriented = true; - } - - //TODO: check TYPE 11: Guided elements - if (this.data.ty !== 11) { - //this.createElements(); - } - }, - renderTransform: function() { - - this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame; - this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame; - - if (this.hierarchy) { - var mat; - var finalMat = this.finalTransform.mat; - var i = 0, len = this.hierarchy.length; - //Checking if any of the transformation matrices in the hierarchy chain has changed. - if (!this.finalTransform._matMdf) { - while (i < len) { - if (this.hierarchy[i].finalTransform.mProp._mdf) { - this.finalTransform._matMdf = true; - break; - } - i += 1; - } - } - - if (this.finalTransform._matMdf) { - mat = this.finalTransform.mProp.v.props; - finalMat.cloneFromProps(mat); - for (i = 0; i < len; i += 1) { - mat = this.hierarchy[i].finalTransform.mProp.v.props; - finalMat.transform(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]); - } - } - } - }, - globalToLocal: function(pt) { - var transforms = []; - transforms.push(this.finalTransform); - var flag = true; - var comp = this.comp; - while (flag) { - if (comp.finalTransform) { - if (comp.data.hasMask) { - transforms.splice(0, 0, comp.finalTransform); - } - comp = comp.comp; - } else { - flag = false; - } - } - var i, len = transforms.length,ptNew; - for (i = 0; i < len; i += 1) { - ptNew = transforms[i].mat.applyToPointArray(0, 0, 0); - //ptNew = transforms[i].mat.applyToPointArray(pt[0],pt[1],pt[2]); - pt = [pt[0] - ptNew[0], pt[1] - ptNew[1], 0]; - } - return pt; - }, - mHelper: new Matrix() -}; -function RenderableElement(){ - -} - -RenderableElement.prototype = { - initRenderable: function() { - //layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange - this.isInRange = false; - //layer's display state - this.hidden = false; - // If layer's transparency equals 0, it can be hidden - this.isTransparent = false; - //list of animated components - this.renderableComponents = []; - }, - addRenderableComponent: function(component) { - if(this.renderableComponents.indexOf(component) === -1) { - this.renderableComponents.push(component); - } - }, - removeRenderableComponent: function(component) { - if(this.renderableComponents.indexOf(component) !== -1) { - this.renderableComponents.splice(this.renderableComponents.indexOf(component), 1); - } - }, - prepareRenderableFrame: function(num) { - this.checkLayerLimits(num); - }, - checkTransparency: function(){ - if(this.finalTransform.mProp.o.v <= 0) { - if(!this.isTransparent && this.globalData.renderConfig.hideOnTransparent){ - this.isTransparent = true; - this.hide(); - } - } else if(this.isTransparent) { - this.isTransparent = false; - this.show(); - } - }, - /** - * @function - * Initializes frame related properties. - * - * @param {number} num - * current frame number in Layer's time - * - */ - checkLayerLimits: function(num) { - if(this.data.ip - this.data.st <= num && this.data.op - this.data.st > num) - { - if(this.isInRange !== true){ - this.globalData._mdf = true; - this._mdf = true; - this.isInRange = true; - this.show(); - } - } else { - if(this.isInRange !== false){ - this.globalData._mdf = true; - this.isInRange = false; - this.hide(); - } - } - }, - renderRenderable: function() { - var i, len = this.renderableComponents.length; - for(i = 0; i < len; i += 1) { - this.renderableComponents[i].renderFrame(this._isFirstFrame); - } - /*this.maskManager.renderFrame(this.finalTransform.mat); - this.renderableEffectsManager.renderFrame(this._isFirstFrame);*/ - }, - sourceRectAtTime: function(){ - return { - top:0, - left:0, - width:100, - height:100 - }; - }, - getLayerSize: function(){ - if(this.data.ty === 5){ - return {w:this.data.textData.width,h:this.data.textData.height}; - }else{ - return {w:this.data.width,h:this.data.height}; - } - } -}; -function RenderableDOMElement() {} - -(function(){ - var _prototype = { - initElement: function(data,globalData,comp) { - this.initFrame(); - this.initBaseData(data, globalData, comp); - this.initTransform(data, globalData, comp); - this.initHierarchy(); - this.initRenderable(); - this.initRendererElement(); - this.createContainerElements(); - this.createRenderableComponents(); - this.createContent(); - this.hide(); - }, - hide: function(){ - if (!this.hidden && (!this.isInRange || this.isTransparent)) { - var elem = this.baseElement || this.layerElement; - elem.style.display = 'none'; - this.hidden = true; - } - }, - show: function(){ - if (this.isInRange && !this.isTransparent){ - if (!this.data.hd) { - var elem = this.baseElement || this.layerElement; - elem.style.display = 'block'; - } - this.hidden = false; - this._isFirstFrame = true; - } - }, - renderFrame: function() { - //If it is exported as hidden (data.hd === true) no need to render - //If it is not visible no need to render - if (this.data.hd || this.hidden) { - return; - } - this.renderTransform(); - this.renderRenderable(); - this.renderElement(); - this.renderInnerContent(); - if (this._isFirstFrame) { - this._isFirstFrame = false; - } - }, - renderInnerContent: function() {}, - prepareFrame: function(num) { - this._mdf = false; - this.prepareRenderableFrame(num); - this.prepareProperties(num, this.isInRange); - this.checkTransparency(); - }, - destroy: function(){ - this.innerElem = null; - this.destroyBaseElement(); - } - }; - extendPrototype([RenderableElement, createProxyFunction(_prototype)], RenderableDOMElement); -}()); -function ProcessedElement(element, position) { - this.elem = element; - this.pos = position; -} -function SVGShapeData(transformers, level, shape) { - this.caches = []; - this.styles = []; - this.transformers = transformers; - this.lStr = ''; - this.sh = shape; - this.lvl = level; - //TODO find if there are some cases where _isAnimated can be false. - // For now, since shapes add up with other shapes. They have to be calculated every time. - // One way of finding out is checking if all styles associated to this shape depend only of this shape - this._isAnimated = !!shape.k; - // TODO: commenting this for now since all shapes are animated - var i = 0, len = transformers.length; - while(i < len) { - if(transformers[i].mProps.dynamicProperties.length) { - this._isAnimated = true; - break; - } - i += 1; - } -} - -SVGShapeData.prototype.setAsAnimated = function() { - this._isAnimated = true; -} -function ShapeGroupData() { - this.it = []; - this.prevViewData = []; - this.gr = createNS('g'); -} -function ShapeTransformManager() { - this.sequences = {}; - this.sequenceList = []; - this.transform_key_count = 0; -} - -ShapeTransformManager.prototype = { - addTransformSequence: function(transforms) { - var i, len = transforms.length; - var key = '_'; - for(i = 0; i < len; i += 1) { - key += transforms[i].transform.key + '_'; - } - var sequence = this.sequences[key]; - if(!sequence) { - sequence = { - transforms: [].concat(transforms), - finalTransform: new Matrix(), - _mdf: false - }; - this.sequences[key] = sequence; - this.sequenceList.push(sequence); - } - return sequence; - }, - processSequence: function(sequence, isFirstFrame) { - var i = 0, len = sequence.transforms.length, _mdf = isFirstFrame; - while (i < len && !isFirstFrame) { - if (sequence.transforms[i].transform.mProps._mdf) { - _mdf = true; - break; - } - i += 1 - } - if (_mdf) { - var props; - sequence.finalTransform.reset(); - for (i = len - 1; i >= 0; i -= 1) { - props = sequence.transforms[i].transform.mProps.v.props; - sequence.finalTransform.transform(props[0],props[1],props[2],props[3],props[4],props[5],props[6],props[7],props[8],props[9],props[10],props[11],props[12],props[13],props[14],props[15]); - } - } - sequence._mdf = _mdf; - - }, - processSequences: function(isFirstFrame) { - var i, len = this.sequenceList.length; - for (i = 0; i < len; i += 1) { - this.processSequence(this.sequenceList[i], isFirstFrame); - } - - }, - getNewKey: function() { - return '_' + this.transform_key_count++; - } -} -function CVShapeData(element, data, styles, transformsManager) { - this.styledShapes = []; - this.tr = [0,0,0,0,0,0]; - var ty = 4; - if(data.ty == 'rc'){ - ty = 5; - }else if(data.ty == 'el'){ - ty = 6; - }else if(data.ty == 'sr'){ - ty = 7; - } - this.sh = ShapePropertyFactory.getShapeProp(element,data,ty,element); - var i , len = styles.length,styledShape; - for (i = 0; i < len; i += 1) { - if (!styles[i].closed) { - styledShape = { - transforms: transformsManager.addTransformSequence(styles[i].transforms), - trNodes: [] - } - this.styledShapes.push(styledShape); - styles[i].elements.push(styledShape); - } - } -} - -CVShapeData.prototype.setAsAnimated = SVGShapeData.prototype.setAsAnimated; -function BaseElement(){ -} - -BaseElement.prototype = { - checkMasks: function(){ - if(!this.data.hasMask){ - return false; - } - var i = 0, len = this.data.masksProperties.length; - while(i=0;i-=1){ - this.shapeModifiers[i].processShapes(this._isFirstFrame); - } - }, - lcEnum: { - '1': 'butt', - '2': 'round', - '3': 'square' - }, - ljEnum: { - '1': 'miter', - '2': 'round', - '3': 'bevel' - }, - searchProcessedElement: function(elem){ - var elements = this.processedElements; - var i = 0, len = elements.length; - while (i < len) { - if (elements[i].elem === elem) { - return elements[i].pos; - } - i += 1; - } - return 0; - }, - addProcessedElement: function(elem, pos){ - var elements = this.processedElements; - var i = elements.length; - while(i) { - i -= 1; - if (elements[i].elem === elem) { - elements[i].pos = pos; - return; - } - } - elements.push(new ProcessedElement(elem, pos)); - }, - prepareFrame: function(num) { - this.prepareRenderableFrame(num); - this.prepareProperties(num, this.isInRange); - } -}; -function ITextElement(){ -} - -ITextElement.prototype.initElement = function(data,globalData,comp){ - this.lettersChangedFlag = true; - this.initFrame(); - this.initBaseData(data, globalData, comp); - this.textProperty = new TextProperty(this, data.t, this.dynamicProperties); - this.textAnimator = new TextAnimatorProperty(data.t, this.renderType, this); - this.initTransform(data, globalData, comp); - this.initHierarchy(); - this.initRenderable(); - this.initRendererElement(); - this.createContainerElements(); - this.createRenderableComponents(); - this.createContent(); - this.hide(); - this.textAnimator.searchProperties(this.dynamicProperties); -}; - -ITextElement.prototype.prepareFrame = function(num) { - this._mdf = false; - this.prepareRenderableFrame(num); - this.prepareProperties(num, this.isInRange); - if(this.textProperty._mdf || this.textProperty._isFirstFrame) { - this.buildNewText(); - this.textProperty._isFirstFrame = false; - this.textProperty._mdf = false; - } -}; - -ITextElement.prototype.createPathShape = function(matrixHelper, shapes) { - var j,jLen = shapes.length; - var k, kLen, pathNodes; - var shapeStr = ''; - for(j=0;j= 0; i -= 1 ){ - if(this.completeLayers || this.elements[i]){ - this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st); - if(this.elements[i]._mdf) { - this._mdf = true; - } - } - } -}; - -ICompElement.prototype.renderInnerContent = function() { - var i,len = this.layers.length; - for( i = 0; i < len; i += 1 ){ - if(this.completeLayers || this.elements[i]){ - this.elements[i].renderFrame(); - } - } -}; - -ICompElement.prototype.setElements = function(elems){ - this.elements = elems; -}; - -ICompElement.prototype.getElements = function(){ - return this.elements; -}; - -ICompElement.prototype.destroyElements = function(){ - var i,len = this.layers.length; - for( i = 0; i < len; i+=1 ){ - if(this.elements[i]){ - this.elements[i].destroy(); - } - } -}; - -ICompElement.prototype.destroy = function(){ - this.destroyElements(); - this.destroyBaseElement(); -}; - -function IImageElement(data,globalData,comp){ - this.assetData = globalData.getAssetData(data.refId); - this.initElement(data,globalData,comp); - this.sourceRect = {top:0,left:0,width:this.assetData.w,height:this.assetData.h}; -} - -extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement], IImageElement); - -IImageElement.prototype.createContent = function(){ - - var assetPath = this.globalData.getAssetsPath(this.assetData); - - this.innerElem = createNS('image'); - this.innerElem.setAttribute('width',this.assetData.w+"px"); - this.innerElem.setAttribute('height',this.assetData.h+"px"); - this.innerElem.setAttribute('preserveAspectRatio',this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio); - this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink','href',assetPath); - - this.layerElement.appendChild(this.innerElem); -}; - -IImageElement.prototype.sourceRectAtTime = function() { - return this.sourceRect; -} -function ISolidElement(data,globalData,comp){ - this.initElement(data,globalData,comp); -} -extendPrototype([IImageElement], ISolidElement); - -ISolidElement.prototype.createContent = function(){ - - var rect = createNS('rect'); - ////rect.style.width = this.data.sw; - ////rect.style.height = this.data.sh; - ////rect.style.fill = this.data.sc; - rect.setAttribute('width',this.data.sw); - rect.setAttribute('height',this.data.sh); - rect.setAttribute('fill',this.data.sc); - this.layerElement.appendChild(rect); -}; -function AudioElement(data,globalData,comp){ - this.initFrame(); - this.initRenderable(); - this.assetData = globalData.getAssetData(data.refId); - this.initBaseData(data, globalData, comp); - this._isPlaying = false; - this._canPlay = false; - var assetPath = this.globalData.getAssetsPath(this.assetData); - this.audio = this.globalData.audioController.createAudio(assetPath); - this._currentTime = 0; - this.globalData.audioController.addAudio(this); - this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate,this) : {_placeholder:true}; -} - -AudioElement.prototype.prepareFrame = function(num) { - this.prepareRenderableFrame(num, true); - this.prepareProperties(num, true); - if (!this.tm._placeholder) { - var timeRemapped = this.tm.v; - this._currentTime = timeRemapped; - } else { - this._currentTime = num / this.data.sr; - } -}; - -extendPrototype([RenderableElement,BaseElement,FrameElement], AudioElement); - -AudioElement.prototype.renderFrame = function() { - if (this.isInRange && this._canPlay) { - if (!this._isPlaying) { - this.audio.play(); - this.audio.seek(this._currentTime / this.globalData.frameRate); - this._isPlaying = true; - } else if (!this.audio.playing() - || Math.abs(this._currentTime / this.globalData.frameRate - this.audio.seek()) > 0.1 - ) { - this.audio.seek(this._currentTime / this.globalData.frameRate) - } - } -}; - -AudioElement.prototype.show = function() { - // this.audio.play() -}; - -AudioElement.prototype.hide = function() { - this.audio.pause(); - this._isPlaying = false; -}; - -AudioElement.prototype.pause = function() { - this.audio.pause(); - this._isPlaying = false; - this._canPlay = false; -}; - -AudioElement.prototype.resume = function() { - this._canPlay = true; -}; - -AudioElement.prototype.setRate = function(rateValue) { - this.audio.rate(rateValue); -}; - -AudioElement.prototype.volume = function(volumeValue) { - this.audio.volume(volumeValue); -}; - -AudioElement.prototype.getBaseElement = function() { - return null; -}; - -AudioElement.prototype.destroy = function() { -}; - -AudioElement.prototype.sourceRectAtTime = function() { -}; - -AudioElement.prototype.initExpressions = function() { -}; - - -function SVGShapeElement(data,globalData,comp){ - //List of drawable elements - this.shapes = []; - // Full shape data - this.shapesData = data.shapes; - //List of styles that will be applied to shapes - this.stylesList = []; - //List of modifiers that will be applied to shapes - this.shapeModifiers = []; - //List of items in shape tree - this.itemsData = []; - //List of items in previous shape tree - this.processedElements = []; - // List of animated components - this.animatedContents = []; - this.initElement(data,globalData,comp); - //Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties. - // List of elements that have been created - this.prevViewData = []; - //Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties. -} - -extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement], SVGShapeElement); - -SVGShapeElement.prototype.initSecondaryElement = function() { -}; - -SVGShapeElement.prototype.identityMatrix = new Matrix(); - -SVGShapeElement.prototype.buildExpressionInterface = function(){}; - -SVGShapeElement.prototype.createContent = function(){ - this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement, 0, [], true); - this.filterUniqueShapes(); -}; - -/* -This method searches for multiple shapes that affect a single element and one of them is animated -*/ -SVGShapeElement.prototype.filterUniqueShapes = function(){ - var i, len = this.shapes.length, shape; - var j, jLen = this.stylesList.length; - var style, count = 0; - var tempShapes = []; - var areAnimated = false; - for(j = 0; j < jLen; j += 1) { - style = this.stylesList[j]; - areAnimated = false; - tempShapes.length = 0; - for(i = 0; i < len; i += 1) { - shape = this.shapes[i]; - if(shape.styles.indexOf(style) !== -1) { - tempShapes.push(shape); - areAnimated = shape._isAnimated || areAnimated; - } - } - if(tempShapes.length > 1 && areAnimated) { - this.setShapesAsAnimated(tempShapes); - } - } -} - -SVGShapeElement.prototype.setShapesAsAnimated = function(shapes){ - var i, len = shapes.length; - for(i = 0; i < len; i += 1) { - shapes[i].setAsAnimated(); - } -} - -SVGShapeElement.prototype.createStyleElement = function(data, level){ - //TODO: prevent drawing of hidden styles - var elementData; - var styleOb = new SVGStyleData(data, level); - - var pathElement = styleOb.pElem; - if(data.ty === 'st') { - elementData = new SVGStrokeStyleData(this, data, styleOb); - } else if(data.ty === 'fl') { - elementData = new SVGFillStyleData(this, data, styleOb); - } else if(data.ty === 'gf' || data.ty === 'gs') { - var gradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData; - elementData = new gradientConstructor(this, data, styleOb); - this.globalData.defs.appendChild(elementData.gf); - if (elementData.maskId) { - this.globalData.defs.appendChild(elementData.ms); - this.globalData.defs.appendChild(elementData.of); - pathElement.setAttribute('mask','url(' + locationHref + '#' + elementData.maskId + ')'); - } - } - - if(data.ty === 'st' || data.ty === 'gs') { - pathElement.setAttribute('stroke-linecap', this.lcEnum[data.lc] || 'round'); - pathElement.setAttribute('stroke-linejoin',this.ljEnum[data.lj] || 'round'); - pathElement.setAttribute('fill-opacity','0'); - if(data.lj === 1) { - pathElement.setAttribute('stroke-miterlimit',data.ml); - } - } - - if(data.r === 2) { - pathElement.setAttribute('fill-rule', 'evenodd'); - } - - if(data.ln){ - pathElement.setAttribute('id',data.ln); - } - if(data.cl){ - pathElement.setAttribute('class',data.cl); - } - if(data.bm){ - pathElement.style['mix-blend-mode'] = getBlendMode(data.bm); - } - this.stylesList.push(styleOb); - this.addToAnimatedContents(data, elementData); - return elementData; -}; - -SVGShapeElement.prototype.createGroupElement = function(data) { - var elementData = new ShapeGroupData(); - if(data.ln){ - elementData.gr.setAttribute('id',data.ln); - } - if(data.cl){ - elementData.gr.setAttribute('class',data.cl); - } - if(data.bm){ - elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm); - } - return elementData; -}; - -SVGShapeElement.prototype.createTransformElement = function(data, container) { - var transformProperty = TransformPropertyFactory.getTransformProperty(this,data,this); - var elementData = new SVGTransformData(transformProperty, transformProperty.o, container); - this.addToAnimatedContents(data, elementData); - return elementData; -}; - -SVGShapeElement.prototype.createShapeElement = function(data, ownTransformers, level) { - var ty = 4; - if(data.ty === 'rc'){ - ty = 5; - }else if(data.ty === 'el'){ - ty = 6; - }else if(data.ty === 'sr'){ - ty = 7; - } - var shapeProperty = ShapePropertyFactory.getShapeProp(this,data,ty,this); - var elementData = new SVGShapeData(ownTransformers, level, shapeProperty); - this.shapes.push(elementData); - this.addShapeToModifiers(elementData); - this.addToAnimatedContents(data, elementData); - return elementData; -}; - -SVGShapeElement.prototype.addToAnimatedContents = function(data, element) { - var i = 0, len = this.animatedContents.length; - while(i < len) { - if(this.animatedContents[i].element === element) { - return; - } - i += 1; - } - this.animatedContents.push({ - fn: SVGElementsRenderer.createRenderFunction(data), - element: element, - data: data - }); -}; - -SVGShapeElement.prototype.setElementStyles = function(elementData){ - var arr = elementData.styles; - var j, jLen = this.stylesList.length; - for (j = 0; j < jLen; j += 1) { - if (!this.stylesList[j].closed) { - arr.push(this.stylesList[j]); - } - } -}; - -SVGShapeElement.prototype.reloadShapes = function(){ - this._isFirstFrame = true; - var i, len = this.itemsData.length; - for( i = 0; i < len; i += 1) { - this.prevViewData[i] = this.itemsData[i]; - } - this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement, 0, [], true); - this.filterUniqueShapes(); - len = this.dynamicProperties.length; - for(i = 0; i < len; i += 1) { - this.dynamicProperties[i].getValue(); - } - this.renderModifiers(); -}; - -SVGShapeElement.prototype.searchShapes = function(arr,itemsData,prevViewData,container, level, transformers, render){ - var ownTransformers = [].concat(transformers); - var i, len = arr.length - 1; - var j, jLen; - var ownStyles = [], ownModifiers = [], styleOb, currentTransform, modifier, processedPos; - for(i=len;i>=0;i-=1){ - processedPos = this.searchProcessedElement(arr[i]); - if(!processedPos){ - arr[i]._render = render; - } else { - itemsData[i] = prevViewData[processedPos - 1]; - } - if(arr[i].ty == 'fl' || arr[i].ty == 'st' || arr[i].ty == 'gf' || arr[i].ty == 'gs'){ - if(!processedPos){ - itemsData[i] = this.createStyleElement(arr[i], level); - } else { - itemsData[i].style.closed = false; - } - if(arr[i]._render){ - container.appendChild(itemsData[i].style.pElem); - } - ownStyles.push(itemsData[i].style); - }else if(arr[i].ty == 'gr'){ - if(!processedPos){ - itemsData[i] = this.createGroupElement(arr[i]); - } else { - jLen = itemsData[i].it.length; - for(j=0;j canvasRel && par === 'xMidYMid slice') || (imgRel < canvasRel && par !== 'xMidYMid slice')) { - heightCrop = imgH; - widthCrop = heightCrop*canvasRel; - } else { - widthCrop = imgW; - heightCrop = widthCrop/canvasRel; - } - ctx.drawImage(this.img,(imgW-widthCrop)/2,(imgH-heightCrop)/2,widthCrop,heightCrop,0,0,this.assetData.w,this.assetData.h); - this.img = canvas; - } - -}; - -CVImageElement.prototype.renderInnerContent = function(parentMatrix){ - this.canvasContext.drawImage(this.img, 0, 0); -}; - -CVImageElement.prototype.destroy = function(){ - this.img = null; -}; -function CVCompElement(data, globalData, comp) { - this.completeLayers = false; - this.layers = data.layers; - this.pendingElements = []; - this.elements = createSizedArray(this.layers.length); - this.initElement(data, globalData, comp); - this.tm = data.tm ? PropertyFactory.getProp(this,data.tm,0,globalData.frameRate, this) : {_placeholder:true}; -} - -extendPrototype([CanvasRenderer, ICompElement, CVBaseElement], CVCompElement); - -CVCompElement.prototype.renderInnerContent = function() { - var ctx = this.canvasContext; - ctx.beginPath(); - ctx.moveTo(0, 0); - ctx.lineTo(this.data.w, 0); - ctx.lineTo(this.data.w, this.data.h); - ctx.lineTo(0, this.data.h); - ctx.lineTo(0, 0); - ctx.clip(); - var i,len = this.layers.length; - for( i = len - 1; i >= 0; i -= 1 ){ - if(this.completeLayers || this.elements[i]){ - this.elements[i].renderFrame(); - } - } -}; - -CVCompElement.prototype.destroy = function(){ - var i,len = this.layers.length; - for( i = len - 1; i >= 0; i -= 1 ){ - if(this.elements[i]) { - this.elements[i].destroy(); - } - } - this.layers = null; - this.elements = null; -}; - -function CVMaskElement(data,element){ - this.data = data; - this.element = element; - this.masksProperties = this.data.masksProperties || []; - this.viewData = createSizedArray(this.masksProperties.length); - var i, len = this.masksProperties.length, hasMasks = false; - for (i = 0; i < len; i++) { - if(this.masksProperties[i].mode !== 'n'){ - hasMasks = true; - } - this.viewData[i] = ShapePropertyFactory.getShapeProp(this.element,this.masksProperties[i],3); - } - this.hasMasks = hasMasks; - if(hasMasks) { - this.element.addRenderableComponent(this); - } -} - -CVMaskElement.prototype.renderFrame = function () { - if(!this.hasMasks){ - return; - } - var transform = this.element.finalTransform.mat; - var ctx = this.element.canvasContext; - var i, len = this.masksProperties.length; - var pt,pts,data; - ctx.beginPath(); - for (i = 0; i < len; i++) { - if(this.masksProperties[i].mode !== 'n'){ - if (this.masksProperties[i].inv) { - ctx.moveTo(0, 0); - ctx.lineTo(this.element.globalData.compSize.w, 0); - ctx.lineTo(this.element.globalData.compSize.w, this.element.globalData.compSize.h); - ctx.lineTo(0, this.element.globalData.compSize.h); - ctx.lineTo(0, 0); - } - data = this.viewData[i].v; - pt = transform.applyToPointArray(data.v[0][0],data.v[0][1],0); - ctx.moveTo(pt[0], pt[1]); - var j, jLen = data._length; - for (j = 1; j < jLen; j++) { - pts = transform.applyToTriplePoints(data.o[j - 1], data.i[j], data.v[j]); - ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]); - } - pts = transform.applyToTriplePoints(data.o[j - 1], data.i[0], data.v[0]); - ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]); - } - } - this.element.globalData.renderer.save(true); - ctx.clip(); -}; - -CVMaskElement.prototype.getMaskProperty = MaskElement.prototype.getMaskProperty; - -CVMaskElement.prototype.destroy = function(){ - this.element = null; -}; -function CVShapeElement(data, globalData, comp) { - this.shapes = []; - this.shapesData = data.shapes; - this.stylesList = []; - this.itemsData = []; - this.prevViewData = []; - this.shapeModifiers = []; - this.processedElements = []; - this.transformsManager = new ShapeTransformManager(); - this.initElement(data, globalData, comp); -} - -extendPrototype([BaseElement,TransformElement,CVBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableElement], CVShapeElement); - -CVShapeElement.prototype.initElement = RenderableDOMElement.prototype.initElement; - -CVShapeElement.prototype.transformHelper = {opacity:1,_opMdf:false}; - -CVShapeElement.prototype.dashResetter = []; - -CVShapeElement.prototype.createContent = function(){ - this.searchShapes(this.shapesData,this.itemsData,this.prevViewData, true, []); -}; - -CVShapeElement.prototype.createStyleElement = function(data, transforms) { - var styleElem = { - data: data, - type: data.ty, - preTransforms: this.transformsManager.addTransformSequence(transforms), - transforms: [], - elements: [], - closed: data.hd === true - }; - var elementData = {}; - if(data.ty == 'fl' || data.ty == 'st'){ - elementData.c = PropertyFactory.getProp(this,data.c,1,255,this); - if(!elementData.c.k){ - styleElem.co = 'rgb('+bm_floor(elementData.c.v[0])+','+bm_floor(elementData.c.v[1])+','+bm_floor(elementData.c.v[2])+')'; - } - } else if (data.ty === 'gf' || data.ty === 'gs') { - elementData.s = PropertyFactory.getProp(this,data.s,1,null,this); - elementData.e = PropertyFactory.getProp(this,data.e,1,null,this); - elementData.h = PropertyFactory.getProp(this,data.h||{k:0},0,0.01,this); - elementData.a = PropertyFactory.getProp(this,data.a||{k:0},0,degToRads,this); - elementData.g = new GradientProperty(this,data.g,this); - } - elementData.o = PropertyFactory.getProp(this,data.o,0,0.01,this); - if(data.ty == 'st' || data.ty == 'gs') { - styleElem.lc = this.lcEnum[data.lc] || 'round'; - styleElem.lj = this.ljEnum[data.lj] || 'round'; - if(data.lj == 1) { - styleElem.ml = data.ml; - } - elementData.w = PropertyFactory.getProp(this,data.w,0,null,this); - if(!elementData.w.k){ - styleElem.wi = elementData.w.v; - } - if(data.d){ - var d = new DashProperty(this,data.d,'canvas', this); - elementData.d = d; - if(!elementData.d.k){ - styleElem.da = elementData.d.dashArray; - styleElem.do = elementData.d.dashoffset[0]; - } - } - } else { - styleElem.r = data.r === 2 ? 'evenodd' : 'nonzero'; - } - this.stylesList.push(styleElem); - elementData.style = styleElem; - return elementData; -}; - -CVShapeElement.prototype.createGroupElement = function(data) { - var elementData = { - it: [], - prevViewData: [] - }; - return elementData; -}; - -CVShapeElement.prototype.createTransformElement = function(data) { - var elementData = { - transform : { - opacity: 1, - _opMdf:false, - key: this.transformsManager.getNewKey(), - op: PropertyFactory.getProp(this,data.o,0,0.01,this), - mProps: TransformPropertyFactory.getTransformProperty(this,data,this) - } - }; - return elementData; -}; - -CVShapeElement.prototype.createShapeElement = function(data) { - var elementData = new CVShapeData(this, data, this.stylesList, this.transformsManager); - - this.shapes.push(elementData); - this.addShapeToModifiers(elementData); - return elementData; -}; - -CVShapeElement.prototype.reloadShapes = function() { - this._isFirstFrame = true; - var i, len = this.itemsData.length; - for (i = 0; i < len; i += 1) { - this.prevViewData[i] = this.itemsData[i]; - } - this.searchShapes(this.shapesData,this.itemsData,this.prevViewData, true, []); - len = this.dynamicProperties.length; - for (i = 0; i < len; i += 1) { - this.dynamicProperties[i].getValue(); - } - this.renderModifiers(); - this.transformsManager.processSequences(this._isFirstFrame); -}; - -CVShapeElement.prototype.addTransformToStyleList = function(transform) { - var i, len = this.stylesList.length; - for (i = 0; i < len; i += 1) { - if(!this.stylesList[i].closed) { - this.stylesList[i].transforms.push(transform); - } - } -} - -CVShapeElement.prototype.removeTransformFromStyleList = function() { - var i, len = this.stylesList.length; - for (i = 0; i < len; i += 1) { - if(!this.stylesList[i].closed) { - this.stylesList[i].transforms.pop(); - } - } -} - -CVShapeElement.prototype.closeStyles = function(styles) { - var i, len = styles.length, j, jLen; - for (i = 0; i < len; i += 1) { - styles[i].closed = true; - } -} - -CVShapeElement.prototype.searchShapes = function(arr,itemsData, prevViewData, shouldRender, transforms){ - var i, len = arr.length - 1; - var j, jLen; - var ownStyles = [], ownModifiers = [], processedPos, modifier, currentTransform; - var ownTransforms = [].concat(transforms); - for(i=len;i>=0;i-=1){ - processedPos = this.searchProcessedElement(arr[i]); - if(!processedPos){ - arr[i]._shouldRender = shouldRender; - } else { - itemsData[i] = prevViewData[processedPos - 1]; - } - if(arr[i].ty == 'fl' || arr[i].ty == 'st'|| arr[i].ty == 'gf'|| arr[i].ty == 'gs'){ - if(!processedPos){ - itemsData[i] = this.createStyleElement(arr[i], ownTransforms); - } else { - itemsData[i].style.closed = false; - } - - ownStyles.push(itemsData[i].style); - }else if(arr[i].ty == 'gr'){ - if(!processedPos){ - itemsData[i] = this.createGroupElement(arr[i]); - } else { - jLen = itemsData[i].it.length; - for(j=0;j=0;i-=1){ - if(items[i].ty == 'tr'){ - groupTransform = data[i].transform; - this.renderShapeTransform(parentTransform, groupTransform); - }else if(items[i].ty == 'sh' || items[i].ty == 'el' || items[i].ty == 'rc' || items[i].ty == 'sr'){ - this.renderPath(items[i],data[i]); - }else if(items[i].ty == 'fl'){ - this.renderFill(items[i],data[i],groupTransform); - }else if(items[i].ty == 'st'){ - this.renderStroke(items[i],data[i],groupTransform); - }else if(items[i].ty == 'gf' || items[i].ty == 'gs'){ - this.renderGradientFill(items[i],data[i],groupTransform); - }else if(items[i].ty == 'gr'){ - this.renderShape(groupTransform,items[i].it,data[i].it); - }else if(items[i].ty == 'tm'){ - // - } - } - if(isMain){ - this.drawLayer(); - } - -}; - -CVShapeElement.prototype.renderStyledShape = function(styledShape, shape){ - if(this._isFirstFrame || shape._mdf || styledShape.transforms._mdf) { - var shapeNodes = styledShape.trNodes; - var paths = shape.paths; - var i, len, j, jLen = paths._length; - shapeNodes.length = 0; - var groupTransformMat = styledShape.transforms.finalTransform; - for (j = 0; j < jLen; j += 1) { - var pathNodes = paths.shapes[j]; - if(pathNodes && pathNodes.v){ - len = pathNodes._length; - for (i = 1; i < len; i += 1) { - if (i === 1) { - shapeNodes.push({ - t: 'm', - p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0) - }); - } - shapeNodes.push({ - t: 'c', - pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[i], pathNodes.v[i]) - }); - } - if (len === 1) { - shapeNodes.push({ - t: 'm', - p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0) - }); - } - if (pathNodes.c && len) { - shapeNodes.push({ - t: 'c', - pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[0], pathNodes.v[0]) - }); - shapeNodes.push({ - t: 'z' - }); - } - } - } - styledShape.trNodes = shapeNodes; - } -} - -CVShapeElement.prototype.renderPath = function(pathData,itemData){ - if(pathData.hd !== true && pathData._shouldRender) { - var i, len = itemData.styledShapes.length; - for (i = 0; i < len; i += 1) { - this.renderStyledShape(itemData.styledShapes[i], itemData.sh); - } - } -}; - -CVShapeElement.prototype.renderFill = function(styleData,itemData, groupTransform){ - var styleElem = itemData.style; - - if (itemData.c._mdf || this._isFirstFrame) { - styleElem.co = 'rgb(' - + bm_floor(itemData.c.v[0]) + ',' - + bm_floor(itemData.c.v[1]) + ',' - + bm_floor(itemData.c.v[2]) + ')'; - } - if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) { - styleElem.coOp = itemData.o.v * groupTransform.opacity; - } -}; - -CVShapeElement.prototype.renderGradientFill = function(styleData,itemData, groupTransform){ - var styleElem = itemData.style; - if(!styleElem.grd || itemData.g._mdf || itemData.s._mdf || itemData.e._mdf || (styleData.t !== 1 && (itemData.h._mdf || itemData.a._mdf))) { - var ctx = this.globalData.canvasContext; - var grd; - var pt1 = itemData.s.v, pt2 = itemData.e.v; - if (styleData.t === 1) { - grd = ctx.createLinearGradient(pt1[0], pt1[1], pt2[0], pt2[1]); - } else { - var rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2)); - var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]); - - var percent = itemData.h.v >= 1 ? 0.99 : itemData.h.v <= -1 ? -0.99: itemData.h.v; - var dist = rad * percent; - var x = Math.cos(ang + itemData.a.v) * dist + pt1[0]; - var y = Math.sin(ang + itemData.a.v) * dist + pt1[1]; - var grd = ctx.createRadialGradient(x, y, 0, pt1[0], pt1[1], rad); - } - - var i, len = styleData.g.p; - var cValues = itemData.g.c; - var opacity = 1; - - for (i = 0; i < len; i += 1){ - if(itemData.g._hasOpacity && itemData.g._collapsable) { - opacity = itemData.g.o[i*2 + 1]; - } - grd.addColorStop(cValues[i * 4] / 100,'rgba('+ cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ','+cValues[i * 4 + 3] + ',' + opacity + ')'); - } - styleElem.grd = grd; - } - styleElem.coOp = itemData.o.v*groupTransform.opacity; - -}; - -CVShapeElement.prototype.renderStroke = function(styleData,itemData, groupTransform){ - var styleElem = itemData.style; - var d = itemData.d; - if(d && (d._mdf || this._isFirstFrame)){ - styleElem.da = d.dashArray; - styleElem.do = d.dashoffset[0]; - } - if(itemData.c._mdf || this._isFirstFrame){ - styleElem.co = 'rgb('+bm_floor(itemData.c.v[0])+','+bm_floor(itemData.c.v[1])+','+bm_floor(itemData.c.v[2])+')'; - } - if(itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame){ - styleElem.coOp = itemData.o.v*groupTransform.opacity; - } - if(itemData.w._mdf || this._isFirstFrame){ - styleElem.wi = itemData.w.v; - } -}; - - -CVShapeElement.prototype.destroy = function(){ - this.shapesData = null; - this.globalData = null; - this.canvasContext = null; - this.stylesList.length = 0; - this.itemsData.length = 0; -}; - - -function CVSolidElement(data, globalData, comp) { - this.initElement(data,globalData,comp); -} -extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVSolidElement); - -CVSolidElement.prototype.initElement = SVGShapeElement.prototype.initElement; -CVSolidElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame; - -CVSolidElement.prototype.renderInnerContent = function() { - var ctx = this.canvasContext; - ctx.fillStyle = this.data.sc; - ctx.fillRect(0, 0, this.data.sw, this.data.sh); - // -}; -function CVTextElement(data, globalData, comp){ - this.textSpans = []; - this.yOffset = 0; - this.fillColorAnim = false; - this.strokeColorAnim = false; - this.strokeWidthAnim = false; - this.stroke = false; - this.fill = false; - this.justifyOffset = 0; - this.currentRender = null; - this.renderType = 'canvas'; - this.values = { - fill: 'rgba(0,0,0,0)', - stroke: 'rgba(0,0,0,0)', - sWidth: 0, - fValue: '' - }; - this.initElement(data,globalData,comp); -} -extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement,ITextElement], CVTextElement); - -CVTextElement.prototype.tHelper = createTag('canvas').getContext('2d'); - -CVTextElement.prototype.buildNewText = function(){ - var documentData = this.textProperty.currentData; - this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0); - - var hasFill = false; - if(documentData.fc) { - hasFill = true; - this.values.fill = this.buildColor(documentData.fc); - }else{ - this.values.fill = 'rgba(0,0,0,0)'; - } - this.fill = hasFill; - var hasStroke = false; - if(documentData.sc){ - hasStroke = true; - this.values.stroke = this.buildColor(documentData.sc); - this.values.sWidth = documentData.sw; - } - var fontData = this.globalData.fontManager.getFontByName(documentData.f); - var i, len; - var letters = documentData.l; - var matrixHelper = this.mHelper; - this.stroke = hasStroke; - this.values.fValue = documentData.finalSize + 'px '+ this.globalData.fontManager.getFontByName(documentData.f).fFamily; - len = documentData.finalText.length; - //this.tHelper.font = this.values.fValue; - var charData, shapeData, k, kLen, shapes, j, jLen, pathNodes, commands, pathArr, singleShape = this.data.singleShape; - var trackingOffset = documentData.tr/1000*documentData.finalSize; - var xPos = 0, yPos = 0, firstLine = true; - var cnt = 0; - for (i = 0; i < len; i += 1) { - charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily); - shapeData = charData && charData.data || {}; - matrixHelper.reset(); - if(singleShape && letters[i].n) { - xPos = -trackingOffset; - yPos += documentData.yOffset; - yPos += firstLine ? 1 : 0; - firstLine = false; - } - - shapes = shapeData.shapes ? shapeData.shapes[0].it : []; - jLen = shapes.length; - matrixHelper.scale(documentData.finalSize/100,documentData.finalSize/100); - if(singleShape){ - this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos); - } - commands = createSizedArray(jLen); - for(j=0;j=0;i-=1){ - registeredAnimations[i].animation.destroy(animation); - } - } - - function searchAnimations(animationData, standalone, renderer){ - var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')), - [].slice.call(document.getElementsByClassName('bodymovin'))); - var i, len = animElements.length; - for(i=0;i this.animationData.op){ - this.animationData.op = data.op; - this.totalFrames = Math.floor(data.op - this.animationData.ip); - } - var layers = this.animationData.layers; - var i, len = layers.length; - var newLayers = data.layers; - var j, jLen = newLayers.length; - for(j=0;j this.timeCompleted){ - this.currentFrame = this.timeCompleted; - } - this.trigger('enterFrame'); - this.renderFrame(); -}; - -AnimationItem.prototype.renderFrame = function () { - if(this.isLoaded === false){ - return; - } - try { - this.renderer.renderFrame(this.currentFrame + this.firstFrame); - } catch(error) { - this.triggerRenderFrameError(error); - } -}; - -AnimationItem.prototype.play = function (name) { - if(name && this.name != name){ - return; - } - if (this.isPaused === true) { - this.isPaused = false; - this.audioController.resume(); - if(this._idle){ - this._idle = false; - this.trigger('_active'); - } - } -}; - -AnimationItem.prototype.pause = function (name) { - if(name && this.name != name){ - return; - } - if(this.isPaused === false){ - this.isPaused = true; - this._idle = true; - this.trigger('_idle'); - this.audioController.pause(); - } -}; - -AnimationItem.prototype.togglePause = function (name) { - if(name && this.name != name){ - return; - } - if(this.isPaused === true){ - this.play(); - }else{ - this.pause(); - } -}; - -AnimationItem.prototype.stop = function (name) { - if(name && this.name != name){ - return; - } - this.pause(); - this.playCount = 0; - this._completedLoop = false; - this.setCurrentRawFrameValue(0); -}; - -AnimationItem.prototype.goToAndStop = function (value, isFrame, name) { - if(name && this.name != name){ - return; - } - if(isFrame){ - this.setCurrentRawFrameValue(value); - }else{ - this.setCurrentRawFrameValue(value * this.frameModifier); - } - this.pause(); -}; - -AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) { - this.goToAndStop(value, isFrame, name); - this.play(); -}; - -AnimationItem.prototype.advanceTime = function (value) { - if (this.isPaused === true || this.isLoaded === false) { - return; - } - var nextValue = this.currentRawFrame + value * this.frameModifier; - var _isComplete = false; - // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations. - // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop. - if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) { - if (!this.loop || this.playCount === this.loop) { - if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) { - _isComplete = true; - nextValue = this.totalFrames - 1; - } - } else if (nextValue >= this.totalFrames) { - this.playCount += 1; - if (!this.checkSegments(nextValue % this.totalFrames)) { - this.setCurrentRawFrameValue(nextValue % this.totalFrames); - this._completedLoop = true; - this.trigger('loopComplete'); - } - } else { - this.setCurrentRawFrameValue(nextValue); - } - } else if(nextValue < 0) { - if (!this.checkSegments(nextValue % this.totalFrames)) { - if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) { - this.setCurrentRawFrameValue(this.totalFrames + (nextValue % this.totalFrames)); - if(!this._completedLoop) { - this._completedLoop = true; - } else { - this.trigger('loopComplete'); - } - } else { - _isComplete = true; - nextValue = 0; - } - } - } else { - this.setCurrentRawFrameValue(nextValue); - } - if (_isComplete) { - this.setCurrentRawFrameValue(nextValue); - this.pause(); - this.trigger('complete'); - } -}; - -AnimationItem.prototype.adjustSegment = function(arr, offset){ - this.playCount = 0; - if(arr[1] < arr[0]){ - if(this.frameModifier > 0){ - if(this.playSpeed < 0){ - this.setSpeed(-this.playSpeed); - } else { - this.setDirection(-1); - } - } - this.timeCompleted = this.totalFrames = arr[0] - arr[1]; - this.firstFrame = arr[1]; - this.setCurrentRawFrameValue(this.totalFrames - 0.001 - offset); - } else if(arr[1] > arr[0]){ - if(this.frameModifier < 0){ - if(this.playSpeed < 0){ - this.setSpeed(-this.playSpeed); - } else { - this.setDirection(1); - } - } - this.timeCompleted = this.totalFrames = arr[1] - arr[0]; - this.firstFrame = arr[0]; - this.setCurrentRawFrameValue(0.001 + offset); - } - this.trigger('segmentStart'); -}; -AnimationItem.prototype.setSegment = function (init,end) { - var pendingFrame = -1; - if(this.isPaused) { - if (this.currentRawFrame + this.firstFrame < init) { - pendingFrame = init; - } else if (this.currentRawFrame + this.firstFrame > end) { - pendingFrame = end - init; - } - } - - this.firstFrame = init; - this.timeCompleted = this.totalFrames = end - init; - if(pendingFrame !== -1) { - this.goToAndStop(pendingFrame,true); - } -}; - -AnimationItem.prototype.playSegments = function (arr, forceFlag) { - if (forceFlag) { - this.segments.length = 0; - } - if (typeof arr[0] === 'object') { - var i, len = arr.length; - for (i = 0; i < len; i += 1) { - this.segments.push(arr[i]); - } - } else { - this.segments.push(arr); - } - if (this.segments.length && forceFlag) { - this.adjustSegment(this.segments.shift(), 0); - } - if (this.isPaused) { - this.play(); - } -}; - -AnimationItem.prototype.resetSegments = function (forceFlag) { - this.segments.length = 0; - this.segments.push([this.animationData.ip,this.animationData.op]); - //this.segments.push([this.animationData.ip*this.frameRate,Math.floor(this.animationData.op - this.animationData.ip+this.animationData.ip*this.frameRate)]); - if (forceFlag) { - this.checkSegments(0); - } -}; -AnimationItem.prototype.checkSegments = function(offset) { - if (this.segments.length) { - this.adjustSegment(this.segments.shift(), offset); - return true; - } - return false; -}; - -AnimationItem.prototype.destroy = function (name) { - if ((name && this.name != name) || !this.renderer) { - return; - } - this.renderer.destroy(); - this.imagePreloader.destroy(); - this.trigger('destroy'); - this._cbs = null; - this.onEnterFrame = this.onLoopComplete = this.onComplete = this.onSegmentStart = this.onDestroy = null; - this.renderer = null; -}; - -AnimationItem.prototype.setCurrentRawFrameValue = function(value){ - this.currentRawFrame = value; - this.gotoFrame(); -}; - -AnimationItem.prototype.setSpeed = function (val) { - this.playSpeed = val; - this.updaFrameModifier(); -}; - -AnimationItem.prototype.setDirection = function (val) { - this.playDirection = val < 0 ? -1 : 1; - this.updaFrameModifier(); -}; - -AnimationItem.prototype.setVolume = function (val, name) { - if (name && this.name !== name) { - return; - } - this.audioController.setVolume(val); -}; - -AnimationItem.prototype.getVolume = function () { - return this.audioController.getVolume(); -}; - -AnimationItem.prototype.mute = function (name) { - if (name && this.name !== name) { - return; - } - this.audioController.mute(); -}; - -AnimationItem.prototype.unmute = function (name) { - if(name && this.name !== name){ - return; - } - this.audioController.unmute(); -}; - -AnimationItem.prototype.updaFrameModifier = function () { - this.frameModifier = this.frameMult * this.playSpeed * this.playDirection; - this.audioController.setRate(this.playSpeed * this.playDirection) -}; - -AnimationItem.prototype.getPath = function () { - return this.path; -}; - -AnimationItem.prototype.getAssetsPath = function (assetData) { - var path = ''; - if(assetData.e) { - path = assetData.p; - } else if(this.assetsPath){ - var imagePath = assetData.p; - if(imagePath.indexOf('images/') !== -1){ - imagePath = imagePath.split('/')[1]; - } - path = this.assetsPath + imagePath; - } else { - path = this.path; - path += assetData.u ? assetData.u : ''; - path += assetData.p; - } - return path; -}; - -AnimationItem.prototype.getAssetData = function (id) { - var i = 0, len = this.assets.length; - while (i < len) { - if(id == this.assets[i].id){ - return this.assets[i]; - } - i += 1; - } -}; - -AnimationItem.prototype.hide = function () { - this.renderer.hide(); -}; - -AnimationItem.prototype.show = function () { - this.renderer.show(); -}; - -AnimationItem.prototype.getDuration = function (isFrame) { - return isFrame ? this.totalFrames : this.totalFrames / this.frameRate; -}; - -AnimationItem.prototype.trigger = function(name){ - if(this._cbs && this._cbs[name]){ - switch(name){ - case 'enterFrame': - this.triggerEvent(name,new BMEnterFrameEvent(name,this.currentFrame,this.totalFrames,this.frameModifier)); - break; - case 'loopComplete': - this.triggerEvent(name,new BMCompleteLoopEvent(name,this.loop,this.playCount,this.frameMult)); - break; - case 'complete': - this.triggerEvent(name,new BMCompleteEvent(name,this.frameMult)); - break; - case 'segmentStart': - this.triggerEvent(name,new BMSegmentStartEvent(name,this.firstFrame,this.totalFrames)); - break; - case 'destroy': - this.triggerEvent(name,new BMDestroyEvent(name,this)); - break; - default: - this.triggerEvent(name); - } - } - if(name === 'enterFrame' && this.onEnterFrame){ - this.onEnterFrame.call(this,new BMEnterFrameEvent(name,this.currentFrame,this.totalFrames,this.frameMult)); - } - if(name === 'loopComplete' && this.onLoopComplete){ - this.onLoopComplete.call(this,new BMCompleteLoopEvent(name,this.loop,this.playCount,this.frameMult)); - } - if(name === 'complete' && this.onComplete){ - this.onComplete.call(this,new BMCompleteEvent(name,this.frameMult)); - } - if(name === 'segmentStart' && this.onSegmentStart){ - this.onSegmentStart.call(this,new BMSegmentStartEvent(name,this.firstFrame,this.totalFrames)); - } - if(name === 'destroy' && this.onDestroy){ - this.onDestroy.call(this,new BMDestroyEvent(name,this)); - } -}; - -AnimationItem.prototype.triggerRenderFrameError = function(nativeError) { - - var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame); - this.triggerEvent('error', error); - - if (this.onError) { - this.onError.call(this, error); - } -} - -AnimationItem.prototype.triggerConfigError = function(nativeError) { - - var error = new BMConfigErrorEvent(nativeError, this.currentFrame); - this.triggerEvent('error', error); - - if (this.onError) { - this.onError.call(this, error); - } -} -var Expressions = (function(){ - var ob = {}; - ob.initExpressions = initExpressions; - - - function initExpressions(animation){ - - var stackCount = 0; - var registers = []; - - function pushExpression() { - stackCount += 1; - } - - function popExpression() { - stackCount -= 1; - if (stackCount === 0) { - releaseInstances(); - } - } - - function registerExpressionProperty(expression) { - if (registers.indexOf(expression) === -1) { - registers.push(expression) - } - } - - function releaseInstances() { - var i, len = registers.length; - for (i = 0; i < len; i += 1) { - registers[i].release(); - } - registers.length = 0; - } - - animation.renderer.compInterface = CompExpressionInterface(animation.renderer); - animation.renderer.globalData.projectInterface.registerComposition(animation.renderer); - animation.renderer.globalData.pushExpression = pushExpression; - animation.renderer.globalData.popExpression = popExpression; - animation.renderer.globalData.registerExpressionProperty = registerExpressionProperty; - } - return ob; -}()); - -expressionsPlugin = Expressions; - -var ExpressionManager = (function(){ - 'use strict'; - var ob = {}; - var Math = BMMath; - var window = null; - var document = null; - - function $bm_isInstanceOfArray(arr) { - return arr.constructor === Array || arr.constructor === Float32Array; - } - - function isNumerable(tOfV, v) { - return tOfV === 'number' || tOfV === 'boolean' || tOfV === 'string' || v instanceof Number; - } - - function $bm_neg(a){ - var tOfA = typeof a; - if(tOfA === 'number' || tOfA === 'boolean' || a instanceof Number ){ - return -a; - } - if($bm_isInstanceOfArray(a)){ - var i, lenA = a.length; - var retArr = []; - for(i=0;i max){ - var mm = max; - max = min; - min = mm; - } - return Math.min(Math.max(num, min), max); - } - - function radiansToDegrees(val) { - return val/degToRads; - } - var radians_to_degrees = radiansToDegrees; - - function degreesToRadians(val) { - return val*degToRads; - } - var degrees_to_radians = radiansToDegrees; - - var helperLengthArray = [0,0,0,0,0,0]; - - function length(arr1, arr2) { - if (typeof arr1 === 'number' || arr1 instanceof Number) { - arr2 = arr2 || 0; - return Math.abs(arr1 - arr2); - } - if(!arr2) { - arr2 = helperLengthArray; - } - var i, len = Math.min(arr1.length, arr2.length); - var addedLength = 0; - for (i = 0; i < len; i += 1) { - addedLength += Math.pow(arr2[i] - arr1[i], 2); - } - return Math.sqrt(addedLength); - } - - function normalize(vec) { - return div(vec, length(vec)); - } - - function rgbToHsl(val) { - var r = val[0]; var g = val[1]; var b = val[2]; - var max = Math.max(r, g, b), min = Math.min(r, g, b); - var h, s, l = (max + min) / 2; - - if(max == min){ - h = s = 0; // achromatic - }else{ - var d = max - min; - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - switch(max){ - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } - - return [h, s, l,val[3]]; - } - - 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) * (2/3 - t) * 6; - return p; - } - - function hslToRgb(val){ - var h = val[0]; - var s = val[1]; - var l = val[2]; - - var r, g, b; - - if(s === 0){ - r = g = b = l; // achromatic - }else{ - - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; - r = hue2rgb(p, q, h + 1/3); - g = hue2rgb(p, q, h); - b = hue2rgb(p, q, h - 1/3); - } - - return [r, g , b, val[3]]; - } - - function linear(t, tMin, tMax, value1, value2){ - if(value1 === undefined || value2 === undefined){ - value1 = tMin; - value2 = tMax; - tMin = 0; - tMax = 1; - } - if(tMax < tMin) { - var _tMin = tMax; - tMax = tMin; - tMin = _tMin; - } - if(t <= tMin) { - return value1; - }else if(t >= tMax){ - return value2; - } - var perc = tMax === tMin ? 0 : (t-tMin)/(tMax-tMin); - if(!value1.length){ - return value1 + (value2-value1)*perc; - } - var i, len = value1.length; - var arr = createTypedArray('float32', len); - for(i=0;i1){ - for(j=0;j 1 ? 1 : t < 0 ? 0 : t; - var mult = fn(t); - if($bm_isInstanceOfArray(val1)) { - var i, len = val1.length; - var arr = createTypedArray('float32', len); - for (i = 0; i < len; i += 1) { - arr[i] = (val2[i] - val1[i]) * mult + val1[i]; - } - return arr; - } else { - return (val2 - val1) * mult + val1; - } - } - - function nearestKey(time){ - var i, len = data.k.length,index,keyTime; - if(!data.k.length || typeof(data.k[0]) === 'number'){ - index = 0; - keyTime = 0; - } else { - index = -1; - time *= elem.comp.globalData.frameRate; - if (time < data.k[0].t) { - index = 1; - keyTime = data.k[0].t; - } else { - for(i=0;idata.k[i].t && time data.k[i+1].t - time){ - index = i + 2; - keyTime = data.k[i+1].t; - } else { - index = i + 1; - keyTime = data.k[i].t; - } - break; - } - } - if(index === -1){ - index = i + 1; - keyTime = data.k[i].t; - } - } - - } - var ob = {}; - ob.index = index; - ob.time = keyTime/elem.comp.globalData.frameRate; - return ob; - } - - function key(ind){ - var ob, i, len; - if(!data.k.length || typeof(data.k[0]) === 'number'){ - throw new Error('The property has no keyframe at index ' + ind); - } - ind -= 1; - ob = { - time: data.k[ind].t/elem.comp.globalData.frameRate, - value: [] - }; - var arr = data.k[ind].hasOwnProperty('s') ? data.k[ind].s : data.k[ind - 1].e; - - len = arr.length; - for(i=0;i keyframes.length - 1){ - duration = keyframes.length - 1; - } - firstKeyFrame = keyframes[keyframes.length - 1 - duration].t; - cycleDuration = lastKeyFrame - firstKeyFrame; - } else { - if(!duration){ - cycleDuration = Math.max(0,lastKeyFrame - this.elem.data.ip); - } else { - cycleDuration = Math.abs(lastKeyFrame - elem.comp.globalData.frameRate*duration); - } - firstKeyFrame = lastKeyFrame - cycleDuration; - } - var i, len, ret; - if(type === 'pingpong') { - var iterations = Math.floor((currentFrame - firstKeyFrame)/cycleDuration); - if(iterations % 2 !== 0){ - return this.getValueAtTime(((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); - } - } else if(type === 'offset'){ - var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0); - var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0); - var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); - var repeats = Math.floor((currentFrame - firstKeyFrame)/cycleDuration); - if(this.pv.length){ - ret = new Array(initV.length); - len = ret.length; - for(i=0;i=firstKeyFrame){ - return this.pv; - }else{ - var cycleDuration, lastKeyFrame; - if(!durationFlag){ - if(!duration || duration > keyframes.length - 1){ - duration = keyframes.length - 1; - } - lastKeyFrame = keyframes[duration].t; - cycleDuration = lastKeyFrame - firstKeyFrame; - } else { - if(!duration){ - cycleDuration = Math.max(0,this.elem.data.op - firstKeyFrame); - } else { - cycleDuration = Math.abs(elem.comp.globalData.frameRate*duration); - } - lastKeyFrame = firstKeyFrame + cycleDuration; - } - var i, len, ret; - if(type === 'pingpong') { - var iterations = Math.floor((firstKeyFrame - currentFrame)/cycleDuration); - if(iterations % 2 === 0){ - return this.getValueAtTime((((firstKeyFrame - currentFrame)%cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); - } - } else if(type === 'offset'){ - var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0); - var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0); - var current = this.getValueAtTime((cycleDuration - (firstKeyFrame - currentFrame)%cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); - var repeats = Math.floor((firstKeyFrame - currentFrame)/cycleDuration)+1; - if(this.pv.length){ - ret = new Array(initV.length); - len = ret.length; - for(i=0;i 1 ? (endFrame - initFrame) / (samples - 1) : 1; - var i = 0, j = 0; - var value; - if (this.pv.length) { - value = createTypedArray('float32', this.pv.length); - } else { - value = 0; - } - var sampleValue; - while (i < samples) { - sampleValue = this.getValueAtTime(initFrame + i * sampleFrequency); - if(this.pv.length) { - for (j = 0; j < this.pv.length; j += 1) { - value[j] += sampleValue[j]; - } - } else { - value += sampleValue; - } - i += 1; - } - if(this.pv.length) { - for (j = 0; j < this.pv.length; j += 1) { - value[j] /= samples; - } - } else { - value /= samples; - } - return value; - } - - function getValueAtTime(frameNum) { - frameNum *= this.elem.globalData.frameRate; - frameNum -= this.offsetTime; - if(frameNum !== this._cachingAtTime.lastFrame) { - this._cachingAtTime.lastIndex = this._cachingAtTime.lastFrame < frameNum ? this._cachingAtTime.lastIndex : 0; - this._cachingAtTime.value = this.interpolateValue(frameNum, this._cachingAtTime); - this._cachingAtTime.lastFrame = frameNum; - } - return this._cachingAtTime.value; - - } - - function getTransformValueAtTime(time) { - if (!this._transformCachingAtTime) { - this._transformCachingAtTime = { - v: new Matrix(), - }; - } - //// - var matrix = this._transformCachingAtTime.v; - matrix.cloneFromProps(this.pre.props); - if (this.appliedTransformations < 1) { - var anchor = this.a.getValueAtTime(time); - matrix.translate(-anchor[0], -anchor[1], anchor[2]); - } - if (this.appliedTransformations < 2) { - var scale = this.s.getValueAtTime(time); - matrix.scale(scale[0], scale[1], scale[2]); - } - if (this.sk && this.appliedTransformations < 3) { - var skew = this.sk.getValueAtTime(time); - var skewAxis = this.sa.getValueAtTime(time); - matrix.skewFromAxis(-skew, skewAxis); - } - if (this.r && this.appliedTransformations < 4) { - var rotation = this.r.getValueAtTime(time); - matrix.rotate(-rotation); - } else if (!this.r && this.appliedTransformations < 4){ - var rotationZ = this.rz.getValueAtTime(time); - var rotationY = this.ry.getValueAtTime(time); - var rotationX = this.rx.getValueAtTime(time); - var orientation = this.or.getValueAtTime(time); - matrix.rotateZ(-rotationZ.v) - .rotateY(rotationY.v) - .rotateX(rotationX.v) - .rotateZ(-orientation[2]) - .rotateY(orientation[1]) - .rotateX(orientation[0]); - } - if (this.data.p && this.data.p.s) { - var positionX = this.px.getValueAtTime(time); - var positionY = this.py.getValueAtTime(time); - if (this.data.p.z) { - var positionZ = this.pz.getValueAtTime(time); - matrix.translate(positionX, positionY, -positionZ); - } else { - matrix.translate(positionX, positionY, 0); - } - } else { - var position = this.p.getValueAtTime(time); - matrix.translate(position[0], position[1], -position[2]); - } - return matrix; - //// - } - - function getTransformStaticValueAtTime(time) { - - } - - var getTransformProperty = TransformPropertyFactory.getTransformProperty; - TransformPropertyFactory.getTransformProperty = function(elem, data, container) { - var prop = getTransformProperty(elem, data, container); - if(prop.dynamicProperties.length) { - prop.getValueAtTime = getTransformValueAtTime.bind(prop); - } else { - prop.getValueAtTime = getTransformStaticValueAtTime.bind(prop); - } - prop.setGroupProperty = expressionHelpers.setGroupProperty; - return prop; - }; - - var propertyGetProp = PropertyFactory.getProp; - PropertyFactory.getProp = function(elem,data,type, mult, container){ - var prop = propertyGetProp(elem,data,type, mult, container); - //prop.getVelocityAtTime = getVelocityAtTime; - //prop.loopOut = loopOut; - //prop.loopIn = loopIn; - if(prop.kf){ - prop.getValueAtTime = expressionHelpers.getValueAtTime.bind(prop); - } else { - prop.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(prop); - } - prop.setGroupProperty = expressionHelpers.setGroupProperty; - prop.loopOut = loopOut; - prop.loopIn = loopIn; - prop.smooth = smooth; - prop.getVelocityAtTime = expressionHelpers.getVelocityAtTime.bind(prop); - prop.getSpeedAtTime = expressionHelpers.getSpeedAtTime.bind(prop); - prop.numKeys = data.a === 1 ? data.k.length : 0; - prop.propertyIndex = data.ix; - var value = 0; - if(type !== 0) { - value = createTypedArray('float32', data.a === 1 ? data.k[0].s.length : data.k.length); - } - prop._cachingAtTime = { - lastFrame: initialDefaultFrame, - lastIndex: 0, - value: value - }; - expressionHelpers.searchExpressions(elem,data,prop); - if(prop.k){ - container.addDynamicProperty(prop); - } - - return prop; - }; - - function getShapeValueAtTime(frameNum) { - //For now this caching object is created only when needed instead of creating it when the shape is initialized. - if (!this._cachingAtTime) { - this._cachingAtTime = { - shapeValue: shape_pool.clone(this.pv), - lastIndex: 0, - lastTime: initialDefaultFrame - }; - } - - frameNum *= this.elem.globalData.frameRate; - frameNum -= this.offsetTime; - if(frameNum !== this._cachingAtTime.lastTime) { - this._cachingAtTime.lastIndex = this._cachingAtTime.lastTime < frameNum ? this._caching.lastIndex : 0; - this._cachingAtTime.lastTime = frameNum; - this.interpolateShape(frameNum, this._cachingAtTime.shapeValue, this._cachingAtTime); - } - return this._cachingAtTime.shapeValue; - } - - var ShapePropertyConstructorFunction = ShapePropertyFactory.getConstructorFunction(); - var KeyframedShapePropertyConstructorFunction = ShapePropertyFactory.getKeyframedConstructorFunction(); - - function ShapeExpressions(){} - ShapeExpressions.prototype = { - vertices: function(prop, time){ - if (this.k) { - this.getValue(); - } - var shapePath = this.v; - if(time !== undefined) { - shapePath = this.getValueAtTime(time, 0); - } - var i, len = shapePath._length; - var vertices = shapePath[prop]; - var points = shapePath.v; - var arr = createSizedArray(len); - for(i = 0; i < len; i += 1) { - if(prop === 'i' || prop === 'o') { - arr[i] = [vertices[i][0] - points[i][0], vertices[i][1] - points[i][1]]; - } else { - arr[i] = [vertices[i][0], vertices[i][1]]; - } - - } - return arr; - }, - points: function(time){ - return this.vertices('v', time); - }, - inTangents: function(time){ - return this.vertices('i', time); - }, - outTangents: function(time){ - return this.vertices('o', time); - }, - isClosed: function(){ - return this.v.c; - }, - pointOnPath: function(perc, time){ - var shapePath = this.v; - if(time !== undefined) { - shapePath = this.getValueAtTime(time, 0); - } - if(!this._segmentsLength) { - this._segmentsLength = bez.getSegmentsLength(shapePath); - } - - var segmentsLength = this._segmentsLength; - var lengths = segmentsLength.lengths; - var lengthPos = segmentsLength.totalLength * perc; - var i = 0, len = lengths.length; - var j = 0, jLen; - var accumulatedLength = 0, pt; - while(i < len) { - if(accumulatedLength + lengths[i].addedLength > lengthPos) { - var initIndex = i; - var endIndex = (shapePath.c && i === len - 1) ? 0 : i + 1; - var segmentPerc = (lengthPos - accumulatedLength)/lengths[i].addedLength; - pt = bez.getPointInSegment(shapePath.v[initIndex], shapePath.v[endIndex], shapePath.o[initIndex], shapePath.i[endIndex], segmentPerc, lengths[i]); - break; - } else { - accumulatedLength += lengths[i].addedLength; - } - i += 1; - } - if(!pt){ - pt = shapePath.c ? [shapePath.v[0][0],shapePath.v[0][1]]:[shapePath.v[shapePath._length-1][0],shapePath.v[shapePath._length-1][1]]; - } - return pt; - }, - vectorOnPath: function(perc, time, vectorType){ - //perc doesn't use triple equality because it can be a Number object as well as a primitive. - perc = perc == 1 ? this.v.c ? 0 : 0.999 : perc; - var pt1 = this.pointOnPath(perc, time); - var pt2 = this.pointOnPath(perc + 0.001, time); - var xLength = pt2[0] - pt1[0]; - var yLength = pt2[1] - pt1[1]; - var magnitude = Math.sqrt(Math.pow(xLength,2) + Math.pow(yLength,2)); - if (magnitude === 0) { - return [0,0]; - } - var unitVector = vectorType === 'tangent' ? [xLength/magnitude, yLength/magnitude] : [-yLength/magnitude, xLength/magnitude]; - return unitVector; - }, - tangentOnPath: function(perc, time){ - return this.vectorOnPath(perc, time, 'tangent'); - }, - normalOnPath: function(perc, time){ - return this.vectorOnPath(perc, time, 'normal'); - }, - setGroupProperty: expressionHelpers.setGroupProperty, - getValueAtTime: expressionHelpers.getStaticValueAtTime - }; - extendPrototype([ShapeExpressions], ShapePropertyConstructorFunction); - extendPrototype([ShapeExpressions], KeyframedShapePropertyConstructorFunction); - KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime; - KeyframedShapePropertyConstructorFunction.prototype.initiateExpression = ExpressionManager.initiateExpression; - - var propertyGetShapeProp = ShapePropertyFactory.getShapeProp; - ShapePropertyFactory.getShapeProp = function(elem,data,type, arr, trims){ - var prop = propertyGetShapeProp(elem,data,type, arr, trims); - prop.propertyIndex = data.ix; - prop.lock = false; - if(type === 3){ - expressionHelpers.searchExpressions(elem,data.pt,prop); - } else if(type === 4){ - expressionHelpers.searchExpressions(elem,data.ks,prop); - } - if(prop.k){ - elem.addDynamicProperty(prop); - } - return prop; - }; -}()); -(function addDecorator() { - - function searchExpressions(){ - if(this.data.d.x){ - this.calculateExpression = ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this); - this.addEffect(this.getExpressionValue.bind(this)); - return true; - } - } - - TextProperty.prototype.getExpressionValue = function(currentValue, text) { - var newValue = this.calculateExpression(text); - if(currentValue.t !== newValue) { - var newData = {}; - this.copyData(newData, currentValue); - newData.t = newValue.toString(); - newData.__complete = false; - return newData; - } - return currentValue; - } - - TextProperty.prototype.searchProperty = function(){ - - var isKeyframed = this.searchKeyframes(); - var hasExpressions = this.searchExpressions(); - this.kf = isKeyframed || hasExpressions; - return this.kf; - }; - - TextProperty.prototype.searchExpressions = searchExpressions; - -}()); -var ShapePathInterface = ( - - function() { - - return function pathInterfaceFactory(shape,view,propertyGroup){ - var prop = view.sh; - - function interfaceFunction(val){ - if(val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path' || val === 'ADBE Vector Shape' || val === 2){ - return interfaceFunction.path; - } - } - - var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup); - prop.setGroupProperty(PropertyInterface('Path', _propertyGroup)); - Object.defineProperties(interfaceFunction, { - 'path': { - get: function(){ - if(prop.k){ - prop.getValue(); - } - return prop; - } - }, - 'shape': { - get: function(){ - if(prop.k){ - prop.getValue(); - } - return prop; - } - }, - '_name': { value: shape.nm }, - 'ix': { value: shape.ix }, - 'propertyIndex': { value: shape.ix }, - 'mn': { value: shape.mn }, - 'propertyGroup': {value: propertyGroup}, - }); - return interfaceFunction; - } - }() -) -var propertyGroupFactory = (function() { - return function(interfaceFunction, parentPropertyGroup) { - return function(val) { - val = val === undefined ? 1 : val - if(val <= 0){ - return interfaceFunction; - } else{ - return parentPropertyGroup(val-1); - } - } - } -}()) -var PropertyInterface = (function() { - return function(propertyName, propertyGroup) { - - var interfaceFunction = { - _name: propertyName - } - - function _propertyGroup(val){ - val = val === undefined ? 1 : val - if(val <= 0){ - return interfaceFunction; - } else { - return propertyGroup(--val); - } - } - - return _propertyGroup; - } -}()) -var ShapeExpressionInterface = (function(){ - - function iterateElements(shapes,view, propertyGroup){ - var arr = []; - var i, len = shapes ? shapes.length : 0; - for(i=0;i 1) { - defaultCurveSegments = value; - } - if (defaultCurveSegments >= 50) { - roundValues(false); - } else { - roundValues(true); - } -} - -function inBrowser() { - return typeof navigator !== 'undefined'; -} - -function installPlugin(type, plugin) { - if (type === 'expressions') { - expressionsPlugin = plugin; - } -} - -function getFactory(name) { - switch (name) { - case "propertyFactory": - return PropertyFactory; - case "shapePropertyFactory": - return ShapePropertyFactory; - case "matrix": - return Matrix; - } -} - -lottie.play = animationManager.play; -lottie.pause = animationManager.pause; -lottie.setLocationHref = setLocationHref; -lottie.togglePause = animationManager.togglePause; -lottie.setSpeed = animationManager.setSpeed; -lottie.setDirection = animationManager.setDirection; -lottie.stop = animationManager.stop; -lottie.searchAnimations = searchAnimations; -lottie.registerAnimation = animationManager.registerAnimation; -lottie.loadAnimation = loadAnimation; -lottie.setSubframeRendering = setSubframeRendering; -lottie.resize = animationManager.resize; -//lottie.start = start; -lottie.goToAndStop = animationManager.goToAndStop; -lottie.destroy = animationManager.destroy; -lottie.setQuality = setQuality; -lottie.inBrowser = inBrowser; -lottie.installPlugin = installPlugin; -lottie.freeze = animationManager.freeze; -lottie.unfreeze = animationManager.unfreeze; -lottie.setVolume = animationManager.setVolume; -lottie.mute = animationManager.mute; -lottie.unmute = animationManager.unmute; -lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations; -lottie.__getFactory = getFactory; -lottie.version = '5.7.3'; - -function checkReady() { - if (document.readyState === "complete") { - clearInterval(readyStateCheckInterval); - searchAnimations(); - } -} - -function getQueryVariable(variable) { - var vars = queryString.split('&'); - for (var i = 0; i < vars.length; i++) { - var pair = vars[i].split('='); - if (decodeURIComponent(pair[0]) == variable) { - return decodeURIComponent(pair[1]); - } - } -} -var standalone = '__[STANDALONE]__'; -var animationData = '__[ANIMATIONDATA]__'; -var renderer = ''; -if (standalone) { - var scripts = document.getElementsByTagName('script'); - var index = scripts.length - 1; - var myScript = scripts[index] || { - src: '' - }; - var queryString = myScript.src.replace(/^[^\?]+\??/, ''); - renderer = getQueryVariable('renderer'); -} -var readyStateCheckInterval = setInterval(checkReady, 100); - -return lottie; -})); diff --git a/examples/js/libs/meshopt_decoder.js b/examples/js/libs/meshopt_decoder.js index ce5c53ceb4005f..3b96f3b446b1f3 100644 --- a/examples/js/libs/meshopt_decoder.js +++ b/examples/js/libs/meshopt_decoder.js @@ -1,36 +1,27 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. -// Copyright (C) 2016-2020, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) +// Copyright (C) 2016-2022, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) var MeshoptDecoder = (function() { "use strict"; - // Built with clang version 11.0.0 (https://github.com/llvm/llvm-project.git 0160ad802e899c2922bc9b29564080c22eb0908c) - // Built from meshoptimizer 0.14 - var wasm_base = "B9h9z9tFBBBF8fL9gBB9gLaaaaaFa9gEaaaB9gFaFa9gEaaaFaEMcBFFFGGGEIIILF9wFFFLEFBFKNFaFCx/IFMO/LFVK9tv9t9vq95GBt9f9f939h9z9t9f9j9h9s9s9f9jW9vq9zBBp9tv9z9o9v9wW9f9kv9j9v9kv9WvqWv94h919m9mvqBF8Z9tv9z9o9v9wW9f9kv9j9v9kv9J9u9kv94h919m9mvqBGy9tv9z9o9v9wW9f9kv9j9v9kv9J9u9kv949TvZ91v9u9jvBEn9tv9z9o9v9wW9f9kv9j9v9kv69p9sWvq9P9jWBIi9tv9z9o9v9wW9f9kv9j9v9kv69p9sWvq9R919hWBLn9tv9z9o9v9wW9f9kv9j9v9kv69p9sWvq9F949wBKI9z9iqlBOc+x8ycGBM/qQFTa8jUUUUBCU/EBlHL8kUUUUBC9+RKGXAGCFJAI9LQBCaRKAE2BBC+gF9HQBALAEAIJHOAGlAGTkUUUBRNCUoBAG9uC/wgBZHKCUGAKCUG9JyRVAECFJRICBRcGXEXAcAF9PQFAVAFAclAcAVJAF9JyRMGXGXAG9FQBAMCbJHKC9wZRSAKCIrCEJCGrRQANCUGJRfCBRbAIRTEXGXAOATlAQ9PQBCBRISEMATAQJRIGXAS9FQBCBRtCBREEXGXAOAIlCi9PQBCBRISLMANCU/CBJAEJRKGXGXGXGXGXATAECKrJ2BBAtCKZrCEZfIBFGEBMAKhB83EBAKCNJhB83EBSEMAKAI2BIAI2BBHmCKrHYAYCE6HYy86BBAKCFJAICIJAYJHY2BBAmCIrCEZHPAPCE6HPy86BBAKCGJAYAPJHY2BBAmCGrCEZHPAPCE6HPy86BBAKCEJAYAPJHY2BBAmCEZHmAmCE6Hmy86BBAKCIJAYAmJHY2BBAI2BFHmCKrHPAPCE6HPy86BBAKCLJAYAPJHY2BBAmCIrCEZHPAPCE6HPy86BBAKCKJAYAPJHY2BBAmCGrCEZHPAPCE6HPy86BBAKCOJAYAPJHY2BBAmCEZHmAmCE6Hmy86BBAKCNJAYAmJHY2BBAI2BGHmCKrHPAPCE6HPy86BBAKCVJAYAPJHY2BBAmCIrCEZHPAPCE6HPy86BBAKCcJAYAPJHY2BBAmCGrCEZHPAPCE6HPy86BBAKCMJAYAPJHY2BBAmCEZHmAmCE6Hmy86BBAKCSJAYAmJHm2BBAI2BEHICKrHYAYCE6HYy86BBAKCQJAmAYJHm2BBAICIrCEZHYAYCE6HYy86BBAKCfJAmAYJHm2BBAICGrCEZHYAYCE6HYy86BBAKCbJAmAYJHK2BBAICEZHIAICE6HIy86BBAKAIJRISGMAKAI2BNAI2BBHmCIrHYAYCb6HYy86BBAKCFJAICNJAYJHY2BBAmCbZHmAmCb6Hmy86BBAKCGJAYAmJHm2BBAI2BFHYCIrHPAPCb6HPy86BBAKCEJAmAPJHm2BBAYCbZHYAYCb6HYy86BBAKCIJAmAYJHm2BBAI2BGHYCIrHPAPCb6HPy86BBAKCLJAmAPJHm2BBAYCbZHYAYCb6HYy86BBAKCKJAmAYJHm2BBAI2BEHYCIrHPAPCb6HPy86BBAKCOJAmAPJHm2BBAYCbZHYAYCb6HYy86BBAKCNJAmAYJHm2BBAI2BIHYCIrHPAPCb6HPy86BBAKCVJAmAPJHm2BBAYCbZHYAYCb6HYy86BBAKCcJAmAYJHm2BBAI2BLHYCIrHPAPCb6HPy86BBAKCMJAmAPJHm2BBAYCbZHYAYCb6HYy86BBAKCSJAmAYJHm2BBAI2BKHYCIrHPAPCb6HPy86BBAKCQJAmAPJHm2BBAYCbZHYAYCb6HYy86BBAKCfJAmAYJHm2BBAI2BOHICIrHYAYCb6HYy86BBAKCbJAmAYJHK2BBAICbZHIAICb6HIy86BBAKAIJRISFMAKAI8pBB83BBAKCNJAICNJ8pBB83BBAICTJRIMAtCGJRtAECTJHEAS9JQBMMGXAIQBCBRISEMGXAM9FQBANAbJ2BBRtCBRKAfREEXAEANCU/CBJAKJ2BBHTCFrCBATCFZl9zAtJHt86BBAEAGJREAKCFJHKAM9HQBMMAfCFJRfAIRTAbCFJHbAG9HQBMMABAcAG9sJANCUGJAMAG9sTkUUUBpANANCUGJAMCaJAG9sJAGTkUUUBpMAMCBAIyAcJRcAIQBMC9+RKSFMCBC99AOAIlAGCAAGCA9Ly6yRKMALCU/EBJ8kUUUUBAKM+OmFTa8jUUUUBCoFlHL8kUUUUBC9+RKGXAFCE9uHOCtJAI9LQBCaRKAE2BBHNC/wFZC/gF9HQBANCbZHVCF9LQBALCoBJCgFCUFT+JUUUBpALC84Jha83EBALC8wJha83EBALC8oJha83EBALCAJha83EBALCiJha83EBALCTJha83EBALha83ENALha83EBAEAIJC9wJRcAECFJHNAOJRMGXAF9FQBCQCbAVCF6yRSABRECBRVCBRQCBRfCBRICBRKEXGXAMAcuQBC9+RKSEMGXGXAN2BBHOC/vF9LQBALCoBJAOCIrCa9zAKJCbZCEWJHb8oGIRTAb8oGBRtGXAOCbZHbAS9PQBALAOCa9zAIJCbZCGWJ8oGBAVAbyROAb9FRbGXGXAGCG9HQBABAt87FBABCIJAO87FBABCGJAT87FBSFMAEAtjGBAECNJAOjGBAECIJATjGBMAVAbJRVALCoBJAKCEWJHmAOjGBAmATjGIALAICGWJAOjGBALCoBJAKCFJCbZHKCEWJHTAtjGBATAOjGIAIAbJRIAKCFJRKSGMGXGXAbCb6QBAQAbJAbC989zJCFJRQSFMAM1BBHbCgFZROGXGXAbCa9MQBAMCFJRMSFMAM1BFHbCgBZCOWAOCgBZqROGXAbCa9MQBAMCGJRMSFMAM1BGHbCgBZCfWAOqROGXAbCa9MQBAMCEJRMSFMAM1BEHbCgBZCdWAOqROGXAbCa9MQBAMCIJRMSFMAM2BIC8cWAOqROAMCLJRMMAOCFrCBAOCFZl9zAQJRQMGXGXAGCG9HQBABAt87FBABCIJAQ87FBABCGJAT87FBSFMAEAtjGBAECNJAQjGBAECIJATjGBMALCoBJAKCEWJHOAQjGBAOATjGIALAICGWJAQjGBALCoBJAKCFJCbZHKCEWJHOAtjGBAOAQjGIAICFJRIAKCFJRKSFMGXAOCDF9LQBALAIAcAOCbZJ2BBHbCIrHTlCbZCGWJ8oGBAVCFJHtATyROALAIAblCbZCGWJ8oGBAtAT9FHmJHtAbCbZHTyRbAT9FRTGXGXAGCG9HQBABAV87FBABCIJAb87FBABCGJAO87FBSFMAEAVjGBAECNJAbjGBAECIJAOjGBMALAICGWJAVjGBALCoBJAKCEWJHYAOjGBAYAVjGIALAICFJHICbZCGWJAOjGBALCoBJAKCFJCbZCEWJHYAbjGBAYAOjGIALAIAmJCbZHICGWJAbjGBALCoBJAKCGJCbZHKCEWJHOAVjGBAOAbjGIAKCFJRKAIATJRIAtATJRVSFMAVCBAM2BBHYyHTAOC/+F6HPJROAYCbZRtGXGXAYCIrHmQBAOCFJRbSFMAORbALAIAmlCbZCGWJ8oGBROMGXGXAtQBAbCFJRVSFMAbRVALAIAYlCbZCGWJ8oGBRbMGXGXAP9FQBAMCFJRYSFMAM1BFHYCgFZRTGXGXAYCa9MQBAMCGJRYSFMAM1BGHYCgBZCOWATCgBZqRTGXAYCa9MQBAMCEJRYSFMAM1BEHYCgBZCfWATqRTGXAYCa9MQBAMCIJRYSFMAM1BIHYCgBZCdWATqRTGXAYCa9MQBAMCLJRYSFMAMCKJRYAM2BLC8cWATqRTMATCFrCBATCFZl9zAQJHQRTMGXGXAmCb6QBAYRPSFMAY1BBHMCgFZROGXGXAMCa9MQBAYCFJRPSFMAY1BFHMCgBZCOWAOCgBZqROGXAMCa9MQBAYCGJRPSFMAY1BGHMCgBZCfWAOqROGXAMCa9MQBAYCEJRPSFMAY1BEHMCgBZCdWAOqROGXAMCa9MQBAYCIJRPSFMAYCLJRPAY2BIC8cWAOqROMAOCFrCBAOCFZl9zAQJHQROMGXGXAtCb6QBAPRMSFMAP1BBHMCgFZRbGXGXAMCa9MQBAPCFJRMSFMAP1BFHMCgBZCOWAbCgBZqRbGXAMCa9MQBAPCGJRMSFMAP1BGHMCgBZCfWAbqRbGXAMCa9MQBAPCEJRMSFMAP1BEHMCgBZCdWAbqRbGXAMCa9MQBAPCIJRMSFMAPCLJRMAP2BIC8cWAbqRbMAbCFrCBAbCFZl9zAQJHQRbMGXGXAGCG9HQBABAT87FBABCIJAb87FBABCGJAO87FBSFMAEATjGBAECNJAbjGBAECIJAOjGBMALCoBJAKCEWJHYAOjGBAYATjGIALAICGWJATjGBALCoBJAKCFJCbZCEWJHYAbjGBAYAOjGIALAICFJHICbZCGWJAOjGBALCoBJAKCGJCbZCEWJHOATjGBAOAbjGIALAIAm9FAmCb6qJHICbZCGWJAbjGBAIAt9FAtCb6qJRIAKCEJRKMANCFJRNABCKJRBAECSJREAKCbZRKAICbZRIAfCEJHfAF9JQBMMCBC99AMAc6yRKMALCoFJ8kUUUUBAKM/tIFGa8jUUUUBCTlRLC9+RKGXAFCLJAI9LQBCaRKAE2BBC/+FZC/QF9HQBALhB83ENAECFJRKAEAIJC98JREGXAF9FQBGXAGCG6QBEXGXAKAE9JQBC9+bMAK1BBHGCgFZRIGXGXAGCa9MQBAKCFJRKSFMAK1BFHGCgBZCOWAICgBZqRIGXAGCa9MQBAKCGJRKSFMAK1BGHGCgBZCfWAIqRIGXAGCa9MQBAKCEJRKSFMAK1BEHGCgBZCdWAIqRIGXAGCa9MQBAKCIJRKSFMAK2BIC8cWAIqRIAKCLJRKMALCNJAICFZCGWqHGAICGrCBAICFrCFZl9zAG8oGBJHIjGBABAIjGBABCIJRBAFCaJHFQBSGMMEXGXAKAE9JQBC9+bMAK1BBHGCgFZRIGXGXAGCa9MQBAKCFJRKSFMAK1BFHGCgBZCOWAICgBZqRIGXAGCa9MQBAKCGJRKSFMAK1BGHGCgBZCfWAIqRIGXAGCa9MQBAKCEJRKSFMAK1BEHGCgBZCdWAIqRIGXAGCa9MQBAKCIJRKSFMAK2BIC8cWAIqRIAKCLJRKMABAICGrCBAICFrCFZl9zALCNJAICFZCGWqHI8oGBJHG87FBAIAGjGBABCGJRBAFCaJHFQBMMCBC99AKAE6yRKMAKM+lLKFaF99GaG99FaG99GXGXAGCI9HQBAF9FQFEXGXGX9DBBB8/9DBBB+/ABCGJHG1BB+yAB1BBHE+yHI+L+TABCFJHL1BBHK+yHO+L+THN9DBBBB9gHVyAN9DBB/+hANAN+U9DBBBBANAVyHcAc+MHMAECa3yAI+SHIAI+UAcAMAKCa3yAO+SHcAc+U+S+S+R+VHO+U+SHN+L9DBBB9P9d9FQBAN+oRESFMCUUUU94REMAGAE86BBGXGX9DBBB8/9DBBB+/Ac9DBBBB9gyAcAO+U+SHN+L9DBBB9P9d9FQBAN+oRGSFMCUUUU94RGMALAG86BBGXGX9DBBB8/9DBBB+/AI9DBBBB9gyAIAO+U+SHN+L9DBBB9P9d9FQBAN+oRGSFMCUUUU94RGMABAG86BBABCIJRBAFCaJHFQBSGMMAF9FQBEXGXGX9DBBB8/9DBBB+/ABCIJHG8uFB+yAB8uFBHE+yHI+L+TABCGJHL8uFBHK+yHO+L+THN9DBBBB9gHVyAN9DB/+g6ANAN+U9DBBBBANAVyHcAc+MHMAECa3yAI+SHIAI+UAcAMAKCa3yAO+SHcAc+U+S+S+R+VHO+U+SHN+L9DBBB9P9d9FQBAN+oRESFMCUUUU94REMAGAE87FBGXGX9DBBB8/9DBBB+/Ac9DBBBB9gyAcAO+U+SHN+L9DBBB9P9d9FQBAN+oRGSFMCUUUU94RGMALAG87FBGXGX9DBBB8/9DBBB+/AI9DBBBB9gyAIAO+U+SHN+L9DBBB9P9d9FQBAN+oRGSFMCUUUU94RGMABAG87FBABCNJRBAFCaJHFQBMMM/SEIEaE99EaF99GXAF9FQBCBREABRIEXGXGX9D/zI818/AICKJ8uFBHLCEq+y+VHKAI8uFB+y+UHO9DB/+g6+U9DBBB8/9DBBB+/AO9DBBBB9gy+SHN+L9DBBB9P9d9FQBAN+oRVSFMCUUUU94RVMAICIJ8uFBRcAICGJ8uFBRMABALCFJCEZAEqCFWJAV87FBGXGXAKAM+y+UHN9DB/+g6+U9DBBB8/9DBBB+/AN9DBBBB9gy+SHS+L9DBBB9P9d9FQBAS+oRMSFMCUUUU94RMMABALCGJCEZAEqCFWJAM87FBGXGXAKAc+y+UHK9DB/+g6+U9DBBB8/9DBBB+/AK9DBBBB9gy+SHS+L9DBBB9P9d9FQBAS+oRcSFMCUUUU94RcMABALCaJCEZAEqCFWJAc87FBGXGX9DBBU8/AOAO+U+TANAN+U+TAKAK+U+THO9DBBBBAO9DBBBB9gy+R9DB/+g6+U9DBBB8/+SHO+L9DBBB9P9d9FQBAO+oRcSFMCUUUU94RcMABALCEZAEqCFWJAc87FBAICNJRIAECIJREAFCaJHFQBMMM9JBGXAGCGrAF9sHF9FQBEXABAB8oGBHGCNWCN91+yAGCi91CnWCUUU/8EJ+++U84GBABCIJRBAFCaJHFQBMMM9TFEaCBCB8oGUkUUBHFABCEJC98ZJHBjGUkUUBGXGXAB8/BCTWHGuQBCaREABAGlCggEJCTrXBCa6QFMAFREMAEM/lFFFaGXGXAFABqCEZ9FQBABRESFMGXGXAGCT9PQBABRESFMABREEXAEAF8oGBjGBAECIJAFCIJ8oGBjGBAECNJAFCNJ8oGBjGBAECSJAFCSJ8oGBjGBAECTJREAFCTJRFAGC9wJHGCb9LQBMMAGCI9JQBEXAEAF8oGBjGBAFCIJRFAECIJREAGC98JHGCE9LQBMMGXAG9FQBEXAEAF2BB86BBAECFJREAFCFJRFAGCaJHGQBMMABMoFFGaGXGXABCEZ9FQBABRESFMAFCgFZC+BwsN9sRIGXGXAGCT9PQBABRESFMABREEXAEAIjGBAECSJAIjGBAECNJAIjGBAECIJAIjGBAECTJREAGC9wJHGCb9LQBMMAGCI9JQBEXAEAIjGBAECIJREAGC98JHGCE9LQBMMGXAG9FQBEXAEAF86BBAECFJREAGCaJHGQBMMABMMMFBCUNMIT9kBB"; - var wasm_simd = "B9h9z9tFBBBFiI9gBB9gLaaaaaFa9gEaaaB9gFaFaEMcBBFBFFGGGEILF9wFFFLEFBFKNFaFCx/aFMO/LFVK9tv9t9vq95GBt9f9f939h9z9t9f9j9h9s9s9f9jW9vq9zBBp9tv9z9o9v9wW9f9kv9j9v9kv9WvqWv94h919m9mvqBG8Z9tv9z9o9v9wW9f9kv9j9v9kv9J9u9kv94h919m9mvqBIy9tv9z9o9v9wW9f9kv9j9v9kv9J9u9kv949TvZ91v9u9jvBLn9tv9z9o9v9wW9f9kv9j9v9kv69p9sWvq9P9jWBKi9tv9z9o9v9wW9f9kv9j9v9kv69p9sWvq9R919hWBOn9tv9z9o9v9wW9f9kv9j9v9kv69p9sWvq9F949wBNI9z9iqlBVc+N9IcIBTEM9+FLa8jUUUUBCTlRBCBRFEXCBRGCBREEXABCNJAGJAECUaAFAGrCFZHIy86BBAEAIJREAGCFJHGCN9HQBMAFCx+YUUBJAE86BBAFCEWCxkUUBJAB8pEN83EBAFCFJHFCUG9HQBMMk8lLbaE97F9+FaL978jUUUUBCU/KBlHL8kUUUUBC9+RKGXAGCFJAI9LQBCaRKAE2BBC+gF9HQBALAEAIJHOAGlAG/8cBBCUoBAG9uC/wgBZHKCUGAKCUG9JyRNAECFJRKCBRVGXEXAVAF9PQFANAFAVlAVANJAF9JyRcGXGXAG9FQBAcCbJHIC9wZHMCE9sRSAMCFWRQAICIrCEJCGrRfCBRbEXAKRTCBRtGXEXGXAOATlAf9PQBCBRKSLMALCU/CBJAtAM9sJRmATAfJRKCBREGXAMCoB9JQBAOAKlC/gB9JQBCBRIEXAmAIJREGXGXGXGXGXATAICKrJ2BBHYCEZfIBFGEBMAECBDtDMIBSEMAEAKDBBIAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnHPCGD+MFAPDQBTFtGmEYIPLdKeOnC0+G+MiDtD9OHdCEDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHiCEWCxkUUBJDBEBAiCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHiCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMIBAKCIJAeDeBJAiCx+YUUBJ2BBJRKSGMAEAKDBBNAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnC+P+e+8/4BDtD9OHdCbDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHiCEWCxkUUBJDBEBAiCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHiCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMIBAKCNJAeDeBJAiCx+YUUBJ2BBJRKSFMAEAKDBBBDMIBAKCTJRKMGXGXGXGXGXAYCGrCEZfIBFGEBMAECBDtDMITSEMAEAKDBBIAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnHPCGD+MFAPDQBTFtGmEYIPLdKeOnC0+G+MiDtD9OHdCEDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHiCEWCxkUUBJDBEBAiCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHiCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMITAKCIJAeDeBJAiCx+YUUBJ2BBJRKSGMAEAKDBBNAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnC+P+e+8/4BDtD9OHdCbDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHiCEWCxkUUBJDBEBAiCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHiCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMITAKCNJAeDeBJAiCx+YUUBJ2BBJRKSFMAEAKDBBBDMITAKCTJRKMGXGXGXGXGXAYCIrCEZfIBFGEBMAECBDtDMIASEMAEAKDBBIAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnHPCGD+MFAPDQBTFtGmEYIPLdKeOnC0+G+MiDtD9OHdCEDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHiCEWCxkUUBJDBEBAiCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHiCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMIAAKCIJAeDeBJAiCx+YUUBJ2BBJRKSGMAEAKDBBNAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnC+P+e+8/4BDtD9OHdCbDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHiCEWCxkUUBJDBEBAiCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHiCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMIAAKCNJAeDeBJAiCx+YUUBJ2BBJRKSFMAEAKDBBBDMIAAKCTJRKMGXGXGXGXGXAYCKrfIBFGEBMAECBDtDMI8wSEMAEAKDBBIAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnHPCGD+MFAPDQBTFtGmEYIPLdKeOnC0+G+MiDtD9OHdCEDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHYCEWCxkUUBJDBEBAYCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHYCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMI8wAKCIJAeDeBJAYCx+YUUBJ2BBJRKSGMAEAKDBBNAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnC+P+e+8/4BDtD9OHdCbDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHYCEWCxkUUBJDBEBAYCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHYCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMI8wAKCNJAeDeBJAYCx+YUUBJ2BBJRKSFMAEAKDBBBDMI8wAKCTJRKMAICoBJREAICUFJAM9LQFAERIAOAKlC/fB9LQBMMGXAEAM9PQBAECErRIEXGXAOAKlCi9PQBCBRKSOMAmAEJRYGXGXGXGXGXATAECKrJ2BBAICKZrCEZfIBFGEBMAYCBDtDMIBSEMAYAKDBBIAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnHPCGD+MFAPDQBTFtGmEYIPLdKeOnC0+G+MiDtD9OHdCEDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHiCEWCxkUUBJDBEBAiCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHiCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMIBAKCIJAeDeBJAiCx+YUUBJ2BBJRKSGMAYAKDBBNAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnC+P+e+8/4BDtD9OHdCbDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHiCEWCxkUUBJDBEBAiCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHiCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMIBAKCNJAeDeBJAiCx+YUUBJ2BBJRKSFMAYAKDBBBDMIBAKCTJRKMAICGJRIAECTJHEAM9JQBMMGXAK9FQBAKRTAtCFJHtCI6QGSFMMCBRKSEMGXAM9FQBALCUGJAbJREALAbJDBGBReCBRYEXAEALCU/CBJAYJHIDBIBHdCFD9tAdCFDbHPD9OD9hD9RHdAIAMJDBIBH8ZCFD9tA8ZAPD9OD9hD9RH8ZDQBTFtGmEYIPLdKeOnHpAIAQJDBIBHyCFD9tAyAPD9OD9hD9RHyAIASJDBIBH8cCFD9tA8cAPD9OD9hD9RH8cDQBTFtGmEYIPLdKeOnH8dDQBFTtGEmYILPdKOenHPAPDQBFGEBFGEBFGEBFGEAeD9uHeDyBjGBAEAGJHIAeAPAPDQILKOILKOILKOILKOD9uHeDyBjGBAIAGJHIAeAPAPDQNVcMNVcMNVcMNVcMD9uHeDyBjGBAIAGJHIAeAPAPDQSQfbSQfbSQfbSQfbD9uHeDyBjGBAIAGJHIAeApA8dDQNVi8ZcMpySQ8c8dfb8e8fHPAPDQBFGEBFGEBFGEBFGED9uHeDyBjGBAIAGJHIAeAPAPDQILKOILKOILKOILKOD9uHeDyBjGBAIAGJHIAeAPAPDQNVcMNVcMNVcMNVcMD9uHeDyBjGBAIAGJHIAeAPAPDQSQfbSQfbSQfbSQfbD9uHeDyBjGBAIAGJHIAeAdA8ZDQNiV8ZcpMyS8cQ8df8eb8fHdAyA8cDQNiV8ZcpMyS8cQ8df8eb8fH8ZDQBFTtGEmYILPdKOenHPAPDQBFGEBFGEBFGEBFGED9uHeDyBjGBAIAGJHIAeAPAPDQILKOILKOILKOILKOD9uHeDyBjGBAIAGJHIAeAPAPDQNVcMNVcMNVcMNVcMD9uHeDyBjGBAIAGJHIAeAPAPDQSQfbSQfbSQfbSQfbD9uHeDyBjGBAIAGJHIAeAdA8ZDQNVi8ZcMpySQ8c8dfb8e8fHPAPDQBFGEBFGEBFGEBFGED9uHeDyBjGBAIAGJHIAeAPAPDQILKOILKOILKOILKOD9uHeDyBjGBAIAGJHIAeAPAPDQNVcMNVcMNVcMNVcMD9uHeDyBjGBAIAGJHIAeAPAPDQSQfbSQfbSQfbSQfbD9uHeDyBjGBAIAGJREAYCTJHYAM9JQBMMAbCIJHbAG9JQBMMABAVAG9sJALCUGJAcAG9s/8cBBALALCUGJAcCaJAG9sJAG/8cBBMAcCBAKyAVJRVAKQBMC9+RKSFMCBC99AOAKlAGCAAGCA9Ly6yRKMALCU/KBJ8kUUUUBAKMNBT+BUUUBM+KmFTa8jUUUUBCoFlHL8kUUUUBC9+RKGXAFCE9uHOCtJAI9LQBCaRKAE2BBHNC/wFZC/gF9HQBANCbZHVCF9LQBALCoBJCgFCUF/8MBALC84Jha83EBALC8wJha83EBALC8oJha83EBALCAJha83EBALCiJha83EBALCTJha83EBALha83ENALha83EBAEAIJC9wJRcAECFJHNAOJRMGXAF9FQBCQCbAVCF6yRSABRECBRVCBRQCBRfCBRICBRKEXGXAMAcuQBC9+RKSEMGXGXAN2BBHOC/vF9LQBALCoBJAOCIrCa9zAKJCbZCEWJHb8oGIRTAb8oGBRtGXAOCbZHbAS9PQBALAOCa9zAIJCbZCGWJ8oGBAVAbyROAb9FRbGXGXAGCG9HQBABAt87FBABCIJAO87FBABCGJAT87FBSFMAEAtjGBAECNJAOjGBAECIJATjGBMAVAbJRVALCoBJAKCEWJHmAOjGBAmATjGIALAICGWJAOjGBALCoBJAKCFJCbZHKCEWJHTAtjGBATAOjGIAIAbJRIAKCFJRKSGMGXGXAbCb6QBAQAbJAbC989zJCFJRQSFMAM1BBHbCgFZROGXGXAbCa9MQBAMCFJRMSFMAM1BFHbCgBZCOWAOCgBZqROGXAbCa9MQBAMCGJRMSFMAM1BGHbCgBZCfWAOqROGXAbCa9MQBAMCEJRMSFMAM1BEHbCgBZCdWAOqROGXAbCa9MQBAMCIJRMSFMAM2BIC8cWAOqROAMCLJRMMAOCFrCBAOCFZl9zAQJRQMGXGXAGCG9HQBABAt87FBABCIJAQ87FBABCGJAT87FBSFMAEAtjGBAECNJAQjGBAECIJATjGBMALCoBJAKCEWJHOAQjGBAOATjGIALAICGWJAQjGBALCoBJAKCFJCbZHKCEWJHOAtjGBAOAQjGIAICFJRIAKCFJRKSFMGXAOCDF9LQBALAIAcAOCbZJ2BBHbCIrHTlCbZCGWJ8oGBAVCFJHtATyROALAIAblCbZCGWJ8oGBAtAT9FHmJHtAbCbZHTyRbAT9FRTGXGXAGCG9HQBABAV87FBABCIJAb87FBABCGJAO87FBSFMAEAVjGBAECNJAbjGBAECIJAOjGBMALAICGWJAVjGBALCoBJAKCEWJHYAOjGBAYAVjGIALAICFJHICbZCGWJAOjGBALCoBJAKCFJCbZCEWJHYAbjGBAYAOjGIALAIAmJCbZHICGWJAbjGBALCoBJAKCGJCbZHKCEWJHOAVjGBAOAbjGIAKCFJRKAIATJRIAtATJRVSFMAVCBAM2BBHYyHTAOC/+F6HPJROAYCbZRtGXGXAYCIrHmQBAOCFJRbSFMAORbALAIAmlCbZCGWJ8oGBROMGXGXAtQBAbCFJRVSFMAbRVALAIAYlCbZCGWJ8oGBRbMGXGXAP9FQBAMCFJRYSFMAM1BFHYCgFZRTGXGXAYCa9MQBAMCGJRYSFMAM1BGHYCgBZCOWATCgBZqRTGXAYCa9MQBAMCEJRYSFMAM1BEHYCgBZCfWATqRTGXAYCa9MQBAMCIJRYSFMAM1BIHYCgBZCdWATqRTGXAYCa9MQBAMCLJRYSFMAMCKJRYAM2BLC8cWATqRTMATCFrCBATCFZl9zAQJHQRTMGXGXAmCb6QBAYRPSFMAY1BBHMCgFZROGXGXAMCa9MQBAYCFJRPSFMAY1BFHMCgBZCOWAOCgBZqROGXAMCa9MQBAYCGJRPSFMAY1BGHMCgBZCfWAOqROGXAMCa9MQBAYCEJRPSFMAY1BEHMCgBZCdWAOqROGXAMCa9MQBAYCIJRPSFMAYCLJRPAY2BIC8cWAOqROMAOCFrCBAOCFZl9zAQJHQROMGXGXAtCb6QBAPRMSFMAP1BBHMCgFZRbGXGXAMCa9MQBAPCFJRMSFMAP1BFHMCgBZCOWAbCgBZqRbGXAMCa9MQBAPCGJRMSFMAP1BGHMCgBZCfWAbqRbGXAMCa9MQBAPCEJRMSFMAP1BEHMCgBZCdWAbqRbGXAMCa9MQBAPCIJRMSFMAPCLJRMAP2BIC8cWAbqRbMAbCFrCBAbCFZl9zAQJHQRbMGXGXAGCG9HQBABAT87FBABCIJAb87FBABCGJAO87FBSFMAEATjGBAECNJAbjGBAECIJAOjGBMALCoBJAKCEWJHYAOjGBAYATjGIALAICGWJATjGBALCoBJAKCFJCbZCEWJHYAbjGBAYAOjGIALAICFJHICbZCGWJAOjGBALCoBJAKCGJCbZCEWJHOATjGBAOAbjGIALAIAm9FAmCb6qJHICbZCGWJAbjGBAIAt9FAtCb6qJRIAKCEJRKMANCFJRNABCKJRBAECSJREAKCbZRKAICbZRIAfCEJHfAF9JQBMMCBC99AMAc6yRKMALCoFJ8kUUUUBAKM/tIFGa8jUUUUBCTlRLC9+RKGXAFCLJAI9LQBCaRKAE2BBC/+FZC/QF9HQBALhB83ENAECFJRKAEAIJC98JREGXAF9FQBGXAGCG6QBEXGXAKAE9JQBC9+bMAK1BBHGCgFZRIGXGXAGCa9MQBAKCFJRKSFMAK1BFHGCgBZCOWAICgBZqRIGXAGCa9MQBAKCGJRKSFMAK1BGHGCgBZCfWAIqRIGXAGCa9MQBAKCEJRKSFMAK1BEHGCgBZCdWAIqRIGXAGCa9MQBAKCIJRKSFMAK2BIC8cWAIqRIAKCLJRKMALCNJAICFZCGWqHGAICGrCBAICFrCFZl9zAG8oGBJHIjGBABAIjGBABCIJRBAFCaJHFQBSGMMEXGXAKAE9JQBC9+bMAK1BBHGCgFZRIGXGXAGCa9MQBAKCFJRKSFMAK1BFHGCgBZCOWAICgBZqRIGXAGCa9MQBAKCGJRKSFMAK1BGHGCgBZCfWAIqRIGXAGCa9MQBAKCEJRKSFMAK1BEHGCgBZCdWAIqRIGXAGCa9MQBAKCIJRKSFMAK2BIC8cWAIqRIAKCLJRKMABAICGrCBAICFrCFZl9zALCNJAICFZCGWqHI8oGBJHG87FBAIAGjGBABCGJRBAFCaJHFQBMMCBC99AKAE6yRKMAKM/dLEK97FaF97GXGXAGCI9HQBAF9FQFCBRGEXABABDBBBHECiD+rFCiD+sFD/6FHIAECND+rFCiD+sFD/6FAID/gFAECTD+rFCiD+sFD/6FHLD/gFD/kFD/lFHKCBDtD+2FHOAICUUUU94DtHND9OD9RD/kFHI9DBB/+hDYAIAID/mFAKAKD/mFALAOALAND9OD9RD/kFHIAID/mFD/kFD/kFD/jFD/nFHLD/mF9DBBX9LDYHOD/kFCgFDtD9OAECUUU94DtD9OD9QAIALD/mFAOD/kFCND+rFCU/+EDtD9OD9QAKALD/mFAOD/kFCTD+rFCUU/8ODtD9OD9QDMBBABCTJRBAGCIJHGAF9JQBSGMMAF9FQBCBRGEXABCTJHVAVDBBBHECBDtHOCUU98D8cFCUU98D8cEHND9OABDBBBHKAEDQILKOSQfbPden8c8d8e8fCggFDtD9OD/6FAKAEDQBFGENVcMTtmYi8ZpyHECTD+sFD/6FHID/gFAECTD+rFCTD+sFD/6FHLD/gFD/kFD/lFHE9DB/+g6DYALAEAOD+2FHOALCUUUU94DtHcD9OD9RD/kFHLALD/mFAEAED/mFAIAOAIAcD9OD9RD/kFHEAED/mFD/kFD/kFD/jFD/nFHID/mF9DBBX9LDYHOD/kFCTD+rFALAID/mFAOD/kFCggEDtD9OD9QHLAEAID/mFAOD/kFCaDbCBDnGCBDnECBDnKCBDnOCBDncCBDnMCBDnfCBDnbD9OHEDQNVi8ZcMpySQ8c8dfb8e8fD9QDMBBABAKAND9OALAEDQBFTtGEmYILPdKOenD9QDMBBABCAJRBAGCIJHGAF9JQBMMM/hEIGaF97FaL978jUUUUBCTlREGXAF9FQBCBRIEXAEABDBBBHLABCTJHKDBBBHODQILKOSQfbPden8c8d8e8fHNCTD+sFHVCID+rFDMIBAB9DBBU8/DY9D/zI818/DYAVCEDtD9QD/6FD/nFHVALAODQBFGENVcMTtmYi8ZpyHLCTD+rFCTD+sFD/6FD/mFHOAOD/mFAVALCTD+sFD/6FD/mFHcAcD/mFAVANCTD+rFCTD+sFD/6FD/mFHNAND/mFD/kFD/kFD/lFCBDtD+4FD/jF9DB/+g6DYHVD/mF9DBBX9LDYHLD/kFCggEDtHMD9OAcAVD/mFALD/kFCTD+rFD9QHcANAVD/mFALD/kFCTD+rFAOAVD/mFALD/kFAMD9OD9QHVDQBFTtGEmYILPdKOenHLD8dBAEDBIBDyB+t+J83EBABCNJALD8dFAEDBIBDyF+t+J83EBAKAcAVDQNVi8ZcMpySQ8c8dfb8e8fHVD8dBAEDBIBDyG+t+J83EBABCiJAVD8dFAEDBIBDyE+t+J83EBABCAJRBAICIJHIAF9JQBMMM9jFF97GXAGCGrAF9sHG9FQBCBRFEXABABDBBBHECND+rFCND+sFD/6FAECiD+sFCnD+rFCUUU/8EDtD+uFD/mFDMBBABCTJRBAFCIJHFAG9JQBMMM9TFEaCBCB8oGUkUUBHFABCEJC98ZJHBjGUkUUBGXGXAB8/BCTWHGuQBCaREABAGlCggEJCTrXBCa6QFMAFREMAEMMMFBCUNMIT9tBB"; + // Built with clang version 14.0.4 + // Built from meshoptimizer 0.18 + var wasm_base = "b9H79Tebbbe8Fv9Gbb9Gvuuuuueu9Giuuub9Geueu9Giuuueuikqbeeedddillviebeoweuec:q;iekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbeY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVbdE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbiL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtblK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbol79IV9Rbrq:P8Yqdbk;3sezu8Jjjjjbcj;eb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Radz1jjjbhwcj;abad9UhoaicefhldnadTmbaoc;WFbGgocjdaocjd6EhDcbhqinaqae9pmeaDaeaq9RaqaDfae6Egkcsfgocl4cifcd4hxdndndndnaoc9WGgmTmbcbhPcehsawcjdfhzalhHinaraH9Rax6midnaraHaxfgl9RcK6mbczhoinawcj;cbfaogifgoc9WfhOdndndndndnaHaic9WfgAco4fRbbaAci4coG4ciGPlbedibkaO9cb83ibaOcwf9cb83ibxikaOalRblalRbbgAco4gCaCciSgCE86bbaocGfalclfaCfgORbbaAcl4ciGgCaCciSgCE86bbaocVfaOaCfgORbbaAcd4ciGgCaCciSgCE86bbaoc7faOaCfgORbbaAciGgAaAciSgAE86bbaoctfaOaAfgARbbalRbegOco4gCaCciSgCE86bbaoc91faAaCfgARbbaOcl4ciGgCaCciSgCE86bbaoc4faAaCfgARbbaOcd4ciGgCaCciSgCE86bbaoc93faAaCfgARbbaOciGgOaOciSgOE86bbaoc94faAaOfgARbbalRbdgOco4gCaCciSgCE86bbaoc95faAaCfgARbbaOcl4ciGgCaCciSgCE86bbaoc96faAaCfgARbbaOcd4ciGgCaCciSgCE86bbaoc97faAaCfgARbbaOciGgOaOciSgOE86bbaoc98faAaOfgORbbalRbiglco4gAaAciSgAE86bbaoc99faOaAfgORbbalcl4ciGgAaAciSgAE86bbaoc9:faOaAfgORbbalcd4ciGgAaAciSgAE86bbaocufaOaAfgoRbbalciGglalciSglE86bbaoalfhlxdkaOalRbwalRbbgAcl4gCaCcsSgCE86bbaocGfalcwfaCfgORbbaAcsGgAaAcsSgAE86bbaocVfaOaAfgORbbalRbegAcl4gCaCcsSgCE86bbaoc7faOaCfgORbbaAcsGgAaAcsSgAE86bbaoctfaOaAfgORbbalRbdgAcl4gCaCcsSgCE86bbaoc91faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc4faOaAfgORbbalRbigAcl4gCaCcsSgCE86bbaoc93faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc94faOaAfgORbbalRblgAcl4gCaCcsSgCE86bbaoc95faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc96faOaAfgORbbalRbvgAcl4gCaCcsSgCE86bbaoc97faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc98faOaAfgORbbalRbogAcl4gCaCcsSgCE86bbaoc99faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc9:faOaAfgORbbalRbrglcl4gAaAcsSgAE86bbaocufaOaAfgoRbbalcsGglalcsSglE86bbaoalfhlxekaOal8Pbb83bbaOcwfalcwf8Pbb83bbalczfhlkdnaiam9pmbaiczfhoaral9RcL0mekkaiam6mialTmidnakTmbawaPfRbbhOcbhoazhiinaiawcj;cbfaofRbbgAce4cbaAceG9R7aOfgO86bbaiadfhiaocefgoak9hmbkkazcefhzaPcefgPad6hsalhHaPad9hmexvkkcbhlasceGmdxikalaxad2fhCdnakTmbcbhHcehsawcjdfhminaral9Rax6mialTmdalaxfhlawaHfRbbhOcbhoamhiinaiawcj;cbfaofRbbgAce4cbaAceG9R7aOfgO86bbaiadfhiaocefgoak9hmbkamcefhmaHcefgHad6hsaHad9hmbkaChlxikcbhocehsinaral9Rax6mdalTmealaxfhlaocefgoad6hsadao9hmbkaChlxdkcbhlasceGTmekc9:hoxikabaqad2fawcjdfakad2z1jjjb8Aawawcjdfakcufad2fadz1jjjb8Aakaqfhqalmbkc9:hoxekcbc99aral9Radcaadca0ESEhokavcj;ebf8Kjjjjbaok;yzeHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgDce0mbavc;abfcFecjez:jjjjb8AavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhqaicefgwarfhodnaeTmbcmcsaDceSEhkcbhxcbhmcbhDcbhicbhlindnaoaq9nmbc9:hoxikdndnawRbbgrc;Ve0mbavc;abfalarcl4cu7fcsGcitfgPydlhsaPydbhzdnarcsGgPak9pmbavaiarcu7fcsGcdtfydbaxaPEhraPThPdndnadcd9hmbabaDcetfgHaz87ebaHcdfas87ebaHclfar87ebxekabaDcdtfgHazBdbaHclfasBdbaHcwfarBdbkaxaPfhxavc;abfalcitfgHarBdbaHasBdlavaicdtfarBdbavc;abfalcefcsGglcitfgHazBdbaHarBdlaiaPfhialcefhlxdkdndnaPcsSmbamaPfaPc987fcefhmxekaocefhrao8SbbgPcFeGhHdndnaPcu9mmbarhoxekaocvfhoaHcFbGhHcrhPdninar8SbbgOcFbGaPtaHVhHaOcu9kmearcefhraPcrfgPc8J9hmbxdkkarcefhokaHce4cbaHceG9R7amfhmkdndnadcd9hmbabaDcetfgraz87ebarcdfas87ebarclfam87ebxekabaDcdtfgrazBdbarclfasBdbarcwfamBdbkavc;abfalcitfgramBdbarasBdlavaicdtfamBdbavc;abfalcefcsGglcitfgrazBdbaramBdlaicefhialcefhlxekdnarcpe0mbaxcefgOavaiaqarcsGfRbbgPcl49RcsGcdtfydbaPcz6gHEhravaiaP9RcsGcdtfydbaOaHfgsaPcsGgOEhPaOThOdndnadcd9hmbabaDcetfgzax87ebazcdfar87ebazclfaP87ebxekabaDcdtfgzaxBdbazclfarBdbazcwfaPBdbkavaicdtfaxBdbavc;abfalcitfgzarBdbazaxBdlavaicefgicsGcdtfarBdbavc;abfalcefcsGcitfgzaPBdbazarBdlavaiaHfcsGgicdtfaPBdbavc;abfalcdfcsGglcitfgraxBdbaraPBdlalcefhlaiaOfhiasaOfhxxekaxcbaoRbbgzEgAarc;:eSgrfhsazcsGhCazcl4hXdndnazcs0mbascefhOxekashOavaiaX9RcsGcdtfydbhskdndnaCmbaOcefhxxekaOhxavaiaz9RcsGcdtfydbhOkdndnarTmbaocefhrxekaocdfhrao8SbegHcFeGhPdnaHcu9kmbaocofhAaPcFbGhPcrhodninar8SbbgHcFbGaotaPVhPaHcu9kmearcefhraocrfgoc8J9hmbkaAhrxekarcefhrkaPce4cbaPceG9R7amfgmhAkdndnaXcsSmbarhPxekarcefhPar8SbbgocFeGhHdnaocu9kmbarcvfhsaHcFbGhHcrhodninaP8SbbgrcFbGaotaHVhHarcu9kmeaPcefhPaocrfgoc8J9hmbkashPxekaPcefhPkaHce4cbaHceG9R7amfgmhskdndnaCcsSmbaPhoxekaPcefhoaP8SbbgrcFeGhHdnarcu9kmbaPcvfhOaHcFbGhHcrhrdninao8SbbgPcFbGartaHVhHaPcu9kmeaocefhoarcrfgrc8J9hmbkaOhoxekaocefhokaHce4cbaHceG9R7amfgmhOkdndnadcd9hmbabaDcetfgraA87ebarcdfas87ebarclfaO87ebxekabaDcdtfgraABdbarclfasBdbarcwfaOBdbkavc;abfalcitfgrasBdbaraABdlavaicdtfaABdbavc;abfalcefcsGcitfgraOBdbarasBdlavaicefgicsGcdtfasBdbavc;abfalcdfcsGcitfgraABdbaraOBdlavaiazcz6aXcsSVfgicsGcdtfaOBdbaiaCTaCcsSVfhialcifhlkawcefhwalcsGhlaicsGhiaDcifgDae6mbkkcbc99aoaqSEhokavc;aef8Kjjjjbaok:llevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaicd4cbaice4ceG9R7avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaicd4cbaice4ceG9R7avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:Lvoeue99dud99eud99dndnadcl9hmbaeTmeindndnabcdfgd8Sbb:Yab8Sbbgi:Ygl:l:tabcefgv8Sbbgo:Ygr:l:tgwJbb;:9cawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai86bbdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad86bbdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad86bbabclfhbaecufgembxdkkaeTmbindndnabclfgd8Ueb:Yab8Uebgi:Ygl:l:tabcdfgv8Uebgo:Ygr:l:tgwJb;:FSawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai87ebdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad87ebdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad87ebabcwfhbaecufgembkkk;siliui99iue99dnaeTmbcbhiabhlindndnJ;Zl81Zalcof8UebgvciV:Y:vgoal8Ueb:YNgrJb;:FSNJbbbZJbbb:;arJbbbb9GEMgw:lJbbb9p9DTmbaw:OhDxekcjjjj94hDkalclf8Uebhqalcdf8UebhkabavcefciGaiVcetfaD87ebdndnaoak:YNgwJb;:FSNJbbbZJbbb:;awJbbbb9GEMgx:lJbbb9p9DTmbax:Ohkxekcjjjj94hkkabavcdfciGaiVcetfak87ebdndnaoaq:YNgoJb;:FSNJbbbZJbbb:;aoJbbbb9GEMgx:lJbbb9p9DTmbax:Ohqxekcjjjj94hqkabavcufciGaiVcetfaq87ebdndnJbbjZararN:tawawN:taoaoN:tgrJbbbbarJbbbb9GE:rJb;:FSNJbbbZMgr:lJbbb9p9DTmbar:Ohqxekcjjjj94hqkabavciGaiVcetfaq87ebalcwfhlaiclfhiaecufgembkkk9mbdnadcd4ae2geTmbinababydbgdcwtcw91:Yadce91cjjj;8ifcjjj98G::NUdbabclfhbaecufgembkkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaiczfhiaeczfheadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabkkkebcjwklz9Kbb"; + var wasm_simd = "b9H79TebbbeKl9Gbb9Gvuuuuueu9Giuuub9Geueuikqbbebeedddilve9Weeeviebeoweuec:q;Aekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbdY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVblE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtboK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbrL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbwl79IV9RbDq;t9tqlbzik9:evu8Jjjjjbcz9Rhbcbheincbhdcbhiinabcwfadfaicjuaead4ceGglE86bbaialfhiadcefgdcw9hmbkaec:q:yjjbfai86bbaecitc:q1jjbfab8Piw83ibaecefgecjd9hmbkk;h8JlHud97euo978Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Rad;8qbbcj;abad9UhoaicefhldnadTmbaoc;WFbGgocjdaocjd6EhwcbhDinaDae9pmeawaeaD9RaDawfae6Egqcsfgoc9WGgkci2hxakcethmaocl4cifcd4hPabaDad2fhscbhzdnincehHalhOcbhAdninaraO9RaP6miavcj;cbfaAak2fhCaOaPfhlcbhidnakc;ab6mbaral9Rc;Gb6mbcbhoinaCaofhidndndndndnaOaoco4fRbbgXciGPlbedibkaipxbbbbbbbbbbbbbbbbpklbxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaialpbbbpklbalczfhlkdndndndndnaXcd4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklzxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaialpbbbpklzalczfhlkdndndndndnaXcl4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklaxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaialpbbbpklaalczfhlkdndndndndnaXco4Plbedibkaipxbbbbbbbbbbbbbbbbpkl8WxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WalclfaYpQbfaXc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WalcwfaYpQbfaXc:q:yjjbfRbbfhlxekaialpbbbpkl8Walczfhlkaoc;abfhiaocjefak0meaihoaral9Rc;Fb0mbkkdndnaiak9pmbaici4hoinaral9RcK6mdaCaifhXdndndndndnaOaico4fRbbaocoG4ciGPlbedibkaXpxbbbbbbbbbbbbbbbbpklbxikaXalpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaXalpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaXalpbbbpklbalczfhlkaocdfhoaiczfgiak6mbkkalTmbaAci6hHalhOaAcefgohAaoclSmdxekkcbhlaHceGmdkdnakTmbavcjdfazfhiavazfpbdbhYcbhXinaiavcj;cbfaXfgopblbgLcep9TaLpxeeeeeeeeeeeeeeeegQp9op9Hp9rgLaoakfpblbg8Acep9Ta8AaQp9op9Hp9rg8ApmbzeHdOiAlCvXoQrLgEaoamfpblbg3cep9Ta3aQp9op9Hp9rg3aoaxfpblbg5cep9Ta5aQp9op9Hp9rg5pmbzeHdOiAlCvXoQrLg8EpmbezHdiOAlvCXorQLgQaQpmbedibedibedibediaYp9UgYp9AdbbaiadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfgoaYaEa8EpmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaoadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfgoaYaLa8ApmwKDYq8AkEx3m5P8Es8FgLa3a5pmwKDYq8AkEx3m5P8Es8Fg8ApmbezHdiOAlvCXorQLgQaQpmbedibedibedibedip9UgYp9AdbbaoadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfgoaYaLa8ApmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaoadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfhiaXczfgXak6mbkkazclfgzad6mbkasavcjdfaqad2;8qbbavavcjdfaqcufad2fad;8qbbaqaDfhDc9:hoalmexikkc9:hoxekcbc99aral9Radcaadca0ESEhokavcj;kbf8Kjjjjbaokwbz:bjjjbk;uzeHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgDce0mbavc;abfcFecje;8kbavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhqaicefgwarfhodnaeTmbcmcsaDceSEhkcbhxcbhmcbhDcbhicbhlindnaoaq9nmbc9:hoxikdndnawRbbgrc;Ve0mbavc;abfalarcl4cu7fcsGcitfgPydlhsaPydbhzdnarcsGgPak9pmbavaiarcu7fcsGcdtfydbaxaPEhraPThPdndnadcd9hmbabaDcetfgHaz87ebaHcdfas87ebaHclfar87ebxekabaDcdtfgHazBdbaHclfasBdbaHcwfarBdbkaxaPfhxavc;abfalcitfgHarBdbaHasBdlavaicdtfarBdbavc;abfalcefcsGglcitfgHazBdbaHarBdlaiaPfhialcefhlxdkdndnaPcsSmbamaPfaPc987fcefhmxekaocefhrao8SbbgPcFeGhHdndnaPcu9mmbarhoxekaocvfhoaHcFbGhHcrhPdninar8SbbgOcFbGaPtaHVhHaOcu9kmearcefhraPcrfgPc8J9hmbxdkkarcefhokaHce4cbaHceG9R7amfhmkdndnadcd9hmbabaDcetfgraz87ebarcdfas87ebarclfam87ebxekabaDcdtfgrazBdbarclfasBdbarcwfamBdbkavc;abfalcitfgramBdbarasBdlavaicdtfamBdbavc;abfalcefcsGglcitfgrazBdbaramBdlaicefhialcefhlxekdnarcpe0mbaxcefgOavaiaqarcsGfRbbgPcl49RcsGcdtfydbaPcz6gHEhravaiaP9RcsGcdtfydbaOaHfgsaPcsGgOEhPaOThOdndnadcd9hmbabaDcetfgzax87ebazcdfar87ebazclfaP87ebxekabaDcdtfgzaxBdbazclfarBdbazcwfaPBdbkavaicdtfaxBdbavc;abfalcitfgzarBdbazaxBdlavaicefgicsGcdtfarBdbavc;abfalcefcsGcitfgzaPBdbazarBdlavaiaHfcsGgicdtfaPBdbavc;abfalcdfcsGglcitfgraxBdbaraPBdlalcefhlaiaOfhiasaOfhxxekaxcbaoRbbgzEgAarc;:eSgrfhsazcsGhCazcl4hXdndnazcs0mbascefhOxekashOavaiaX9RcsGcdtfydbhskdndnaCmbaOcefhxxekaOhxavaiaz9RcsGcdtfydbhOkdndnarTmbaocefhrxekaocdfhrao8SbegHcFeGhPdnaHcu9kmbaocofhAaPcFbGhPcrhodninar8SbbgHcFbGaotaPVhPaHcu9kmearcefhraocrfgoc8J9hmbkaAhrxekarcefhrkaPce4cbaPceG9R7amfgmhAkdndnaXcsSmbarhPxekarcefhPar8SbbgocFeGhHdnaocu9kmbarcvfhsaHcFbGhHcrhodninaP8SbbgrcFbGaotaHVhHarcu9kmeaPcefhPaocrfgoc8J9hmbkashPxekaPcefhPkaHce4cbaHceG9R7amfgmhskdndnaCcsSmbaPhoxekaPcefhoaP8SbbgrcFeGhHdnarcu9kmbaPcvfhOaHcFbGhHcrhrdninao8SbbgPcFbGartaHVhHaPcu9kmeaocefhoarcrfgrc8J9hmbkaOhoxekaocefhokaHce4cbaHceG9R7amfgmhOkdndnadcd9hmbabaDcetfgraA87ebarcdfas87ebarclfaO87ebxekabaDcdtfgraABdbarclfasBdbarcwfaOBdbkavc;abfalcitfgrasBdbaraABdlavaicdtfaABdbavc;abfalcefcsGcitfgraOBdbarasBdlavaicefgicsGcdtfasBdbavc;abfalcdfcsGcitfgraABdbaraOBdlavaiazcz6aXcsSVfgicsGcdtfaOBdbaiaCTaCcsSVfhialcifhlkawcefhwalcsGhlaicsGhiaDcifgDae6mbkkcbc99aoaqSEhokavc;aef8Kjjjjbaok:llevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaicd4cbaice4ceG9R7avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaicd4cbaice4ceG9R7avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:EPliuo97eue978Jjjjjbca9Rhidndnadcl9hmbdnaec98GglTmbcbhvabhdinadadpbbbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpkbbadczfhdavclfgval6mbkkalae9pmeaiaeciGgvcdtgdVcbczad9R;8kbaiabalcdtfglad;8qbbdnavTmbaiaipblbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpklbkalaiad;8qbbskdnaec98GgxTmbcbhvabhdinadczfglalpbbbgopxbbbbbbFFbbbbbbFFgkp9oadpbbbgDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eaDaopmbediwDqkzHOAKY8AEgoczp:Sep;6egrp;Geaoczp:Reczp:Sep;6egwp;Gep;Kep;Legopxb;:FSb;:FSb;:FSb;:FSawaopxbbbbbbbbbbbbbbbbp:2egqawpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegwawp;Meaoaop;Mearaqaramp9op9rp;Kegoaop;Mep;Kep;Kep;Jep;Negrp;Mepxbbn0bbn0bbn0bbn0gqp;Keczp:Reawarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9op9qgwaoarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogopmwDKYqk8AExm35Ps8E8Fp9qpkbbadaDakp9oawaopmbezHdiOAlvCXorQLp9qpkbbadcafhdavclfgvax6mbkkaxae9pmbaiaeciGgvcitgdfcbcaad9R;8kbaiabaxcitfglad;8qbbdnavTmbaiaipblzgopxbbbbbbFFbbbbbbFFgkp9oaipblbgDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eaDaopmbediwDqkzHOAKY8AEgoczp:Sep;6egrp;Geaoczp:Reczp:Sep;6egwp;Gep;Kep;Legopxb;:FSb;:FSb;:FSb;:FSawaopxbbbbbbbbbbbbbbbbp:2egqawpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegwawp;Meaoaop;Mearaqaramp9op9rp;Kegoaop;Mep;Kep;Kep;Jep;Negrp;Mepxbbn0bbn0bbn0bbn0gqp;Keczp:Reawarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9op9qgwaoarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogopmwDKYqk8AExm35Ps8E8Fp9qpklzaiaDakp9oawaopmbezHdiOAlvCXorQLp9qpklbkalaiad;8qbbkk;4wllue97euv978Jjjjjbc8W9Rhidnaec98GglTmbcbhvabhoinaiaopbbbgraoczfgwpbbbgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklbaopxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaqakp;Mearp;Keczp:ReaDakp;Mearp;Keamp9op9qgkpmbezHdiOAlvCXorQLgrp5baipblbpEb:T:j83ibaocwfarp5eaipblbpEe:T:j83ibawaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblbpEd:T:j83ibaocKfakp5eaipblbpEi:T:j83ibaocafhoavclfgval6mbkkdnalae9pmbaiaeciGgvcitgofcbcaao9R;8kbaiabalcitfgwao;8qbbdnavTmbaiaipblbgraipblzgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklaaipxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaqakp;Mearp;Keczp:ReaDakp;Mearp;Keamp9op9qgkpmbezHdiOAlvCXorQLgrp5baipblapEb:T:j83ibaiarp5eaipblapEe:T:j83iwaiaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblapEd:T:j83izaiakp5eaipblapEi:T:j83iKkawaiao;8qbbkk:Pddiue978Jjjjjbc;ab9Rhidnadcd4ae2glc98GgvTmbcbhdabheinaeaepbbbgocwp:Recwp:Sep;6eaocep:SepxbbjZbbjZbbjZbbjZp:UepxbbjFbbjFbbjFbbjFp9op;Mepkbbaeczfheadclfgdav6mbkkdnaval9pmbaialciGgdcdtgeVcbc;abae9R;8kbaiabavcdtfgvae;8qbbdnadTmbaiaipblbgocwp:Recwp:Sep;6eaocep:SepxbbjZbbjZbbjZbbjZp:UepxbbjFbbjFbbjFbbjFp9op;Mepklbkavaiae;8qbbkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaikkkebcjwklz9Tbb"; - // Uses bulk-memory and simd extensions var detector = new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,3,2,0,0,5,3,1,0,1,12,1,0,10,22,2,12,0,65,0,65,0,65,0,252,10,0,0,11,7,0,65,0,253,15,26,11]); - - // Used to unpack wasm - var wasmpack = new Uint8Array([32,0,65,253,3,1,2,34,4,106,6,5,11,8,7,20,13,33,12,16,128,9,116,64,19,113,127,15,10,21,22,14,255,66,24,54,136,107,18,23,192,26,114,118,132,17,77,101,130,144,27,87,131,44,45,74,156,154,70,167]); + var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); if (typeof WebAssembly !== 'object') { - // This module requires WebAssembly to function return { supported: false, }; } - var wasm = wasm_base; - - if (WebAssembly.validate(detector)) { - wasm = wasm_simd; - console.log("Warning: meshopt_decoder is using experimental SIMD support"); - } + var wasm = WebAssembly.validate(detector) ? wasm_simd : wasm_base; var instance; - var promise = + var ready = WebAssembly.instantiate(unpack(wasm), {}) .then(function(result) { instance = result.instance; @@ -41,7 +32,7 @@ var MeshoptDecoder = (function() { var result = new Uint8Array(data.length); for (var i = 0; i < data.length; ++i) { var ch = data.charCodeAt(i); - result[i] = ch > 96 ? ch - 71 : ch > 64 ? ch - 65 : ch > 47 ? ch + 4 : ch > 46 ? 63 : 62; + result[i] = ch > 96 ? ch - 97 : ch > 64 ? ch - 39 : ch + 4; } var write = 0; for (var i = 0; i < data.length; ++i) { @@ -52,7 +43,7 @@ var MeshoptDecoder = (function() { function decode(fun, target, count, size, source, filter) { var sbrk = instance.exports.sbrk; - var count4 = (count + 3) & ~3; // pad for SIMD filter + var count4 = (count + 3) & ~3; var tp = sbrk(count4 * size); var sp = sbrk(source.length); var heap = new Uint8Array(instance.exports.memory.buffer); @@ -66,15 +57,9 @@ var MeshoptDecoder = (function() { if (res != 0) { throw new Error("Malformed buffer data: " + res); } - }; + } var filters = { - // legacy index-based enums for glTF - 0: "", - 1: "meshopt_decodeFilterOct", - 2: "meshopt_decodeFilterQuat", - 3: "meshopt_decodeFilterExp", - // string-based enums for glTF NONE: "", OCTAHEDRAL: "meshopt_decodeFilterOct", QUATERNION: "meshopt_decodeFilterQuat", @@ -82,19 +67,88 @@ var MeshoptDecoder = (function() { }; var decoders = { - // legacy index-based enums for glTF - 0: "meshopt_decodeVertexBuffer", - 1: "meshopt_decodeIndexBuffer", - 2: "meshopt_decodeIndexSequence", - // string-based enums for glTF ATTRIBUTES: "meshopt_decodeVertexBuffer", TRIANGLES: "meshopt_decodeIndexBuffer", INDICES: "meshopt_decodeIndexSequence", }; + var workers = []; + var requestId = 0; + + function createWorker(url) { + var worker = { + object: new Worker(url), + pending: 0, + requests: {} + }; + + worker.object.onmessage = function(event) { + var data = event.data; + + worker.pending -= data.count; + worker.requests[data.id][data.action](data.value); + + delete worker.requests[data.id]; + }; + + return worker; + } + + function initWorkers(count) { + var source = + "var instance; var ready = WebAssembly.instantiate(new Uint8Array([" + new Uint8Array(unpack(wasm)) + "]), {})" + + ".then(function(result) { instance = result.instance; instance.exports.__wasm_call_ctors(); });" + + "self.onmessage = workerProcess;" + + decode.toString() + workerProcess.toString(); + + var blob = new Blob([source], {type: 'text/javascript'}); + var url = URL.createObjectURL(blob); + + for (var i = 0; i < count; ++i) { + workers[i] = createWorker(url); + } + + URL.revokeObjectURL(url); + } + + function decodeWorker(count, size, source, mode, filter) { + var worker = workers[0]; + + for (var i = 1; i < workers.length; ++i) { + if (workers[i].pending < worker.pending) { + worker = workers[i]; + } + } + + return new Promise(function (resolve, reject) { + var data = new Uint8Array(source); + var id = requestId++; + + worker.pending += count; + worker.requests[id] = { resolve: resolve, reject: reject }; + worker.object.postMessage({ id: id, count: count, size: size, source: data, mode: mode, filter: filter }, [ data.buffer ]); + }); + } + + function workerProcess(event) { + ready.then(function() { + var data = event.data; + try { + var target = new Uint8Array(data.count * data.size); + decode(instance.exports[data.mode], target, data.count, data.size, data.source, instance.exports[data.filter]); + self.postMessage({ id: data.id, count: data.count, action: "resolve", value: target }, [ target.buffer ]); + } catch (error) { + self.postMessage({ id: data.id, count: data.count, action: "reject", value: error }); + } + }); + } + return { - ready: promise, + ready: ready, supported: true, + useWorkers: function(count) { + initWorkers(count); + }, decodeVertexBuffer: function(target, count, size, source, filter) { decode(instance.exports.meshopt_decodeVertexBuffer, target, count, size, source, instance.exports[filters[filter]]); }, @@ -106,10 +160,22 @@ var MeshoptDecoder = (function() { }, decodeGltfBuffer: function(target, count, size, source, mode, filter) { decode(instance.exports[decoders[mode]], target, count, size, source, instance.exports[filters[filter]]); + }, + decodeGltfBufferAsync: function(count, size, source, mode, filter) { + if (workers.length > 0) { + return decodeWorker(count, size, source, decoders[mode], filters[filter]); + } + + return ready.then(function() { + var target = new Uint8Array(count * size); + decode(instance.exports[decoders[mode]], target, count, size, source, instance.exports[filters[filter]]); + return target; + }); } }; })(); +// UMD-style export if (typeof exports === 'object' && typeof module === 'object') module.exports = MeshoptDecoder; else if (typeof define === 'function' && define['amd']) diff --git a/examples/js/lights/LightProbeGenerator.js b/examples/js/lights/LightProbeGenerator.js index 0bd40380fd0302..ef70ff5fc427a5 100644 --- a/examples/js/lights/LightProbeGenerator.js +++ b/examples/js/lights/LightProbeGenerator.js @@ -12,7 +12,6 @@ const shBasis = [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; const sh = new THREE.SphericalHarmonics3(); const shCoefficients = sh.coefficients; - for ( let faceIndex = 0; faceIndex < 6; faceIndex ++ ) { const image = cubeTexture.image[ faceIndex ]; @@ -28,56 +27,57 @@ const imageWidth = imageData.width; // assumed to be square const pixelSize = 2 / imageWidth; - for ( let i = 0, il = data.length; i < il; i += 4 ) { // RGBA assumed + // pixel color - color.setRGB( data[ i ] / 255, data[ i + 1 ] / 255, data[ i + 2 ] / 255 ); // convert to linear color space + color.setRGB( data[ i ] / 255, data[ i + 1 ] / 255, data[ i + 2 ] / 255 ); - convertColorToLinear( color, cubeTexture.encoding ); // pixel coordinate on unit cube + // convert to linear color space + convertColorToLinear( color, cubeTexture.encoding ); + + // pixel coordinate on unit cube const pixelIndex = i / 4; const col = - 1 + ( pixelIndex % imageWidth + 0.5 ) * pixelSize; const row = 1 - ( Math.floor( pixelIndex / imageWidth ) + 0.5 ) * pixelSize; - switch ( faceIndex ) { case 0: coord.set( - 1, row, - col ); break; - case 1: coord.set( 1, row, col ); break; - case 2: coord.set( - col, 1, - row ); break; - case 3: coord.set( - col, - 1, row ); break; - case 4: coord.set( - col, row, 1 ); break; - case 5: coord.set( col, row, - 1 ); break; - } // weight assigned to this pixel + } + // weight assigned to this pixel const lengthSq = coord.lengthSq(); const weight = 4 / ( Math.sqrt( lengthSq ) * lengthSq ); - totalWeight += weight; // direction vector to this pixel + totalWeight += weight; - dir.copy( coord ).normalize(); // evaluate SH basis functions in direction dir + // direction vector to this pixel + dir.copy( coord ).normalize(); - THREE.SphericalHarmonics3.getBasisAt( dir, shBasis ); // accummuulate + // evaluate SH basis functions in direction dir + THREE.SphericalHarmonics3.getBasisAt( dir, shBasis ); + // accummuulate for ( let j = 0; j < 9; j ++ ) { shCoefficients[ j ].x += shBasis[ j ] * color.r * weight; @@ -88,11 +88,10 @@ } - } // normalize - + } + // normalize const norm = 4 * Math.PI / totalWeight; - for ( let j = 0; j < 9; j ++ ) { shCoefficients[ j ].x *= norm; @@ -104,7 +103,6 @@ return new THREE.LightProbe( sh ); } - static fromCubeRenderTarget( renderer, cubeRenderTarget ) { // The renderTarget must be set to RGBA in order to make readRenderTargetPixels works @@ -115,64 +113,63 @@ const shBasis = [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; const sh = new THREE.SphericalHarmonics3(); const shCoefficients = sh.coefficients; - for ( let faceIndex = 0; faceIndex < 6; faceIndex ++ ) { const imageWidth = cubeRenderTarget.width; // assumed to be square - const data = new Uint8Array( imageWidth * imageWidth * 4 ); renderer.readRenderTargetPixels( cubeRenderTarget, 0, 0, imageWidth, imageWidth, data, faceIndex ); const pixelSize = 2 / imageWidth; - for ( let i = 0, il = data.length; i < il; i += 4 ) { // RGBA assumed + // pixel color - color.setRGB( data[ i ] / 255, data[ i + 1 ] / 255, data[ i + 2 ] / 255 ); // convert to linear color space + color.setRGB( data[ i ] / 255, data[ i + 1 ] / 255, data[ i + 2 ] / 255 ); - convertColorToLinear( color, cubeRenderTarget.texture.encoding ); // pixel coordinate on unit cube + // convert to linear color space + convertColorToLinear( color, cubeRenderTarget.texture.encoding ); + + // pixel coordinate on unit cube const pixelIndex = i / 4; const col = - 1 + ( pixelIndex % imageWidth + 0.5 ) * pixelSize; const row = 1 - ( Math.floor( pixelIndex / imageWidth ) + 0.5 ) * pixelSize; - switch ( faceIndex ) { case 0: coord.set( 1, row, - col ); break; - case 1: coord.set( - 1, row, col ); break; - case 2: coord.set( col, 1, - row ); break; - case 3: coord.set( col, - 1, row ); break; - case 4: coord.set( col, row, 1 ); break; - case 5: coord.set( - col, row, - 1 ); break; - } // weight assigned to this pixel + } + // weight assigned to this pixel const lengthSq = coord.lengthSq(); const weight = 4 / ( Math.sqrt( lengthSq ) * lengthSq ); - totalWeight += weight; // direction vector to this pixel + totalWeight += weight; - dir.copy( coord ).normalize(); // evaluate SH basis functions in direction dir + // direction vector to this pixel + dir.copy( coord ).normalize(); - THREE.SphericalHarmonics3.getBasisAt( dir, shBasis ); // accummuulate + // evaluate SH basis functions in direction dir + THREE.SphericalHarmonics3.getBasisAt( dir, shBasis ); + // accummuulate for ( let j = 0; j < 9; j ++ ) { shCoefficients[ j ].x += shBasis[ j ] * color.r * weight; @@ -183,11 +180,10 @@ } - } // normalize - + } + // normalize const norm = 4 * Math.PI / totalWeight; - for ( let j = 0; j < 9; j ++ ) { shCoefficients[ j ].x *= norm; @@ -201,7 +197,6 @@ } } - function convertColorToLinear( color, encoding ) { switch ( encoding ) { @@ -209,10 +204,8 @@ case THREE.sRGBEncoding: color.convertSRGBToLinear(); break; - case THREE.LinearEncoding: break; - default: console.warn( 'WARNING: LightProbeGenerator convertColorToLinear() encountered an unsupported encoding.' ); break; diff --git a/examples/js/lights/RectAreaLightUniformsLib.js b/examples/js/lights/RectAreaLightUniformsLib.js index c47418328ae554..1b8fb0bb9e5b24 100644 --- a/examples/js/lights/RectAreaLightUniformsLib.js +++ b/examples/js/lights/RectAreaLightUniformsLib.js @@ -12,6 +12,7 @@ * * TODO: figure out a way to compress the LTC BRDF data */ + // Real-Time Polygonal-Light Shading with Linearly Transformed Cosines // by Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt // code: https://github.com/selfshadow/ltc_code/ @@ -21,8 +22,11 @@ static init() { // source: https://github.com/selfshadow/ltc_code/tree/master/fit/results/ltc.js + const LTC_MAT_1 = [ 1, 0, 0, 2e-05, 1, 0, 0, 0.000503905, 1, 0, 0, 0.00201562, 1, 0, 0, 0.00453516, 1, 0, 0, 0.00806253, 1, 0, 0, 0.0125978, 1, 0, 0, 0.018141, 1, 0, 0, 0.0246924, 1, 0, 0, 0.0322525, 1, 0, 0, 0.0408213, 1, 0, 0, 0.0503999, 1, 0, 0, 0.0609894, 1, 0, 0, 0.0725906, 1, 0, 0, 0.0852058, 1, 0, 0, 0.0988363, 1, 0, 0, 0.113484, 1, 0, 0, 0.129153, 1, 0, 0, 0.145839, 1, 0, 0, 0.163548, 1, 0, 0, 0.182266, 1, 0, 0, 0.201942, 1, 0, 0, 0.222314, 1, 0, 0, 0.241906, 1, 0, 0, 0.262314, 1, 0, 0, 0.285754, 1, 0, 0, 0.310159, 1, 0, 0, 0.335426, 1, 0, 0, 0.361341, 1, 0, 0, 0.387445, 1, 0, 0, 0.412784, 1, 0, 0, 0.438197, 1, 0, 0, 0.466966, 1, 0, 0, 0.49559, 1, 0, 0, 0.523448, 1, 0, 0, 0.549938, 1, 0, 0, 0.57979, 1, 0, 0, 0.608746, 1, 0, 0, 0.636185, 1, 0, 0, 0.664748, 1, 0, 0, 0.69313, 1, 0, 0, 0.71966, 1, 0, 0, 0.747662, 1, 0, 0, 0.774023, 1, 0, 0, 0.799775, 1, 0, 0, 0.825274, 1, 0, 0, 0.849156, 1, 0, 0, 0.873248, 1, 0, 0, 0.89532, 1, 0, 0, 0.917565, 1, 0, 0, 0.937863, 1, 0, 0, 0.958139, 1, 0, 0, 0.976563, 1, 0, 0, 0.994658, 1, 0, 0, 1.0112, 1, 0, 0, 1.02712, 1, 0, 0, 1.04189, 1, 0, 0, 1.05568, 1, 0, 0, 1.06877, 1, 0, 0, 1.08058, 1, 0, 0, 1.09194, 1, 0, 0, 1.10191, 1, 0, 0, 1.11161, 1, 0, 0, 1.1199, 1, 0, 0, 1.12813, 0.999547, - 4.48815e-07, 0.0224417, 1.99902e-05, 0.999495, - 1.13079e-05, 0.0224406, 0.000503651, 0.999496, - 4.52317e-05, 0.0224406, 0.00201461, 0.999496, - 0.000101772, 0.0224406, 0.00453287, 0.999495, - 0.000180928, 0.0224406, 0.00805845, 0.999497, - 0.000282702, 0.0224406, 0.0125914, 0.999496, - 0.000407096, 0.0224406, 0.0181319, 0.999498, - 0.000554114, 0.0224406, 0.02468, 0.999499, - 0.000723768, 0.0224406, 0.0322363, 0.999495, - 0.000916058, 0.0224405, 0.0408009, 0.999499, - 0.00113101, 0.0224408, 0.050375, 0.999494, - 0.00136863, 0.0224405, 0.0609586, 0.999489, - 0.00162896, 0.0224401, 0.0725537, 0.999489, - 0.00191201, 0.0224414, 0.0851619, 0.999498, - 0.00221787, 0.0224413, 0.0987867, 0.999492, - 0.00254642, 0.0224409, 0.113426, 0.999507, - 0.00289779, 0.0224417, 0.129088, 0.999494, - 0.0032716, 0.0224386, 0.145767, 0.999546, - 0.0036673, 0.0224424, 0.163472, 0.999543, - 0.00408166, 0.0224387, 0.182182, 0.999499, - 0.00450056, 0.0224338, 0.201843, 0.999503, - 0.00483661, 0.0224203, 0.222198, 0.999546, - 0.00452928, 0.022315, 0.241714, 0.999508, - 0.00587403, 0.0224329, 0.262184, 0.999509, - 0.00638806, 0.0224271, 0.285609, 0.999501, - 0.00691028, 0.0224166, 0.309998, 0.999539, - 0.00741979, 0.0223989, 0.335262, 0.999454, - 0.00786282, 0.0223675, 0.361154, 0.999529, - 0.00811928, 0.0222828, 0.387224, 0.999503, - 0.00799941, 0.0221063, 0.41252, 0.999561, - 0.00952753, 0.0223057, 0.438006, 0.999557, - 0.0099134, 0.0222065, 0.466735, 0.999541, - 0.0100935, 0.0220402, 0.495332, 0.999562, - 0.00996821, 0.0218067, 0.523197, 0.999556, - 0.0105031, 0.0217096, 0.550223, 0.999561, - 0.0114191, 0.0217215, 0.579498, 0.999588, - 0.0111818, 0.0213357, 0.608416, 0.999633, - 0.0107725, 0.0208689, 0.635965, 0.999527, - 0.0121671, 0.0210149, 0.664476, 0.999508, - 0.0116005, 0.020431, 0.692786, 0.999568, - 0.0115604, 0.0199791, 0.719709, 0.999671, - 0.0121117, 0.0197415, 0.74737, 0.999688, - 0.0110769, 0.0188846, 0.773692, 0.99962, - 0.0122368, 0.0188452, 0.799534, 0.999823, - 0.0110325, 0.0178001, 0.825046, 0.999599, - 0.0114923, 0.0174221, 0.849075, 0.999619, - 0.0105923, 0.0164345, 0.872999, 0.999613, - 0.0105988, 0.0158227, 0.895371, 0.99964, - 0.00979861, 0.0148131, 0.917364, 0.99977, - 0.00967238, 0.0140721, 0.938002, 0.999726, - 0.00869175, 0.0129543, 0.957917, 0.99973, - 0.00866872, 0.0122329, 0.976557, 0.999773, - 0.00731956, 0.0108958, 0.994459, 0.999811, - 0.00756027, 0.0102715, 1.01118, 0.999862, - 0.00583732, 0.00878781, 1.02701, 0.999835, - 0.00631438, 0.00827529, 1.04186, 0.999871, - 0.00450785, 0.00674583, 1.05569, 0.999867, - 0.00486079, 0.00621041, 1.06861, 0.999939, - 0.00322072, 0.00478301, 1.08064, 0.999918, - 0.00318199, 0.00406395, 1.09181, 1.00003, - 0.00193348, 0.00280682, 1.10207, 0.999928, - 0.00153729, 0.00198741, 1.11152, 0.999933, - 0.000623666, 0.000917714, 1.12009, 1, - 1.02387e-06, 9.07581e-07, 1.12813, 0.997866, - 8.96716e-07, 0.0448334, 1.99584e-05, 0.997987, - 2.25945e-05, 0.0448389, 0.000502891, 0.997987, - 9.03781e-05, 0.0448388, 0.00201156, 0.997985, - 0.000203351, 0.0448388, 0.00452602, 0.997986, - 0.000361514, 0.0448388, 0.00804629, 0.997987, - 0.00056487, 0.0448389, 0.0125724, 0.997988, - 0.000813423, 0.0448389, 0.0181045, 0.997984, - 0.00110718, 0.0448387, 0.0246427, 0.997985, - 0.00144616, 0.0448388, 0.0321875, 0.997987, - 0.00183038, 0.044839, 0.0407392, 0.997983, - 0.00225987, 0.0448387, 0.0502986, 0.997991, - 0.00273467, 0.0448389, 0.0608667, 0.997984, - 0.00325481, 0.0448384, 0.0724444, 0.998002, - 0.00382043, 0.044839, 0.0850348, 0.997997, - 0.00443145, 0.0448396, 0.0986372, 0.998007, - 0.00508796, 0.0448397, 0.113255, 0.998008, - 0.00578985, 0.04484, 0.128891, 0.998003, - 0.00653683, 0.0448384, 0.145548, 0.997983, - 0.00732713, 0.0448358, 0.163221, 0.997985, - 0.00815454, 0.0448358, 0.181899, 0.998005, - 0.00898985, 0.0448286, 0.201533, 0.998026, - 0.00964404, 0.0447934, 0.221821, 0.998055, - 0.00922677, 0.044611, 0.241282, 0.99804, - 0.0117361, 0.0448245, 0.261791, 0.998048, - 0.0127628, 0.0448159, 0.285181, 0.998088, - 0.0138055, 0.0447996, 0.30954, 0.998058, - 0.0148206, 0.0447669, 0.334751, 0.998099, - 0.0156998, 0.044697, 0.36061, 0.998116, - 0.0161976, 0.0445122, 0.386603, 0.998195, - 0.015945, 0.0441711, 0.411844, 0.998168, - 0.0183947, 0.0444255, 0.43773, 0.998184, - 0.0197913, 0.0443809, 0.466009, 0.998251, - 0.0201426, 0.0440689, 0.494574, 0.998305, - 0.0198847, 0.0435632, 0.522405, 0.998273, - 0.0210577, 0.043414, 0.549967, 0.998254, - 0.0227901, 0.0433943, 0.578655, 0.998349, - 0.0223108, 0.0426529, 0.60758, 0.99843, - 0.0223088, 0.042, 0.635524, 0.998373, - 0.0241141, 0.0418987, 0.663621, 0.998425, - 0.0231446, 0.0408118, 0.691906, 0.998504, - 0.0233684, 0.0400565, 0.719339, 0.998443, - 0.0241652, 0.0394634, 0.74643, 0.99848, - 0.0228715, 0.0380002, 0.773086, 0.998569, - 0.023519, 0.0372322, 0.798988, 0.998619, - 0.0223108, 0.0356468, 0.824249, 0.998594, - 0.0223105, 0.034523, 0.848808, 0.998622, - 0.0213426, 0.0328887, 0.87227, 0.998669, - 0.0207912, 0.0314374, 0.895157, 0.998705, - 0.0198416, 0.0296925, 0.916769, 0.998786, - 0.0189168, 0.0279634, 0.937773, 0.998888, - 0.0178811, 0.0261597, 0.957431, 0.99906, - 0.0166845, 0.0242159, 0.976495, 0.999038, - 0.0155464, 0.0222638, 0.994169, 0.999237, - 0.0141349, 0.0201967, 1.01112, 0.999378, - 0.0129324, 0.0181744, 1.02692, 0.999433, - 0.0113192, 0.0159898, 1.04174, 0.999439, - 0.0101244, 0.0140385, 1.05559, 0.999614, - 0.00837456, 0.0117826, 1.06852, 0.999722, - 0.00721769, 0.00983745, 1.08069, 0.999817, - 0.00554067, 0.00769002, 1.09176, 0.99983, - 0.00426961, 0.005782, 1.10211, 0.999964, - 0.00273904, 0.00374503, 1.11152, 1.00001, - 0.00136739, 0.00187176, 1.12031, 0.999946, 3.93227e-05, - 2.8919e-05, 1.12804, 0.995847, - 1.3435e-06, 0.0671785, 1.9916e-05, 0.995464, - 3.38387e-05, 0.0671527, 0.000501622, 0.99547, - 0.000135355, 0.0671531, 0.00200649, 0.995471, - 0.00030455, 0.0671532, 0.00451461, 0.99547, - 0.000541423, 0.0671531, 0.008026, 0.995471, - 0.00084598, 0.0671531, 0.0125407, 0.99547, - 0.00121823, 0.0671531, 0.0180589, 0.99547, - 0.00165817, 0.0671531, 0.0245806, 0.995463, - 0.00216583, 0.0671526, 0.0321062, 0.995468, - 0.00274127, 0.0671527, 0.0406366, 0.995474, - 0.00338447, 0.0671534, 0.0501717, 0.995473, - 0.00409554, 0.0671533, 0.0607131, 0.995478, - 0.00487451, 0.0671531, 0.0722618, 0.995476, - 0.00572148, 0.0671532, 0.0848191, 0.995477, - 0.00663658, 0.0671539, 0.0983882, 0.995498, - 0.00761986, 0.0671541, 0.112972, 0.995509, - 0.00867094, 0.0671542, 0.128568, 0.995509, - 0.00978951, 0.0671531, 0.145183, 0.995503, - 0.0109725, 0.0671491, 0.162808, 0.995501, - 0.012211, 0.0671465, 0.181441, 0.99553, - 0.0134565, 0.0671371, 0.201015, 0.99555, - 0.014391, 0.0670831, 0.221206, 0.99558, - 0.014351, 0.0668883, 0.240813, 0.995577, - 0.0173997, 0.0671055, 0.261257, 0.995602, - 0.0191111, 0.0671178, 0.284467, 0.995623, - 0.0206705, 0.0670946, 0.308765, 0.995658, - 0.022184, 0.0670472, 0.333905, 0.995705, - 0.0234832, 0.0669417, 0.359677, 0.995719, - 0.0241933, 0.0666714, 0.385554, 0.995786, - 0.0243539, 0.066266, 0.410951, 0.995887, - 0.0271866, 0.0664367, 0.437163, 0.995944, - 0.0296012, 0.0664931, 0.464842, 0.996004, - 0.0301045, 0.0660105, 0.49332, 0.996128, - 0.0298311, 0.0652694, 0.521131, 0.996253, - 0.0316426, 0.0650739, 0.549167, 0.996244, - 0.0339043, 0.0649433, 0.57737, 0.996309, - 0.033329, 0.0638926, 0.606073, 0.996417, - 0.0338935, 0.0630849, 0.634527, 0.996372, - 0.0353104, 0.0625083, 0.66256, 0.996542, - 0.0348942, 0.0611986, 0.690516, 0.996568, - 0.0351614, 0.060069, 0.718317, 0.996711, - 0.0354317, 0.0588522, 0.74528, 0.996671, - 0.0349513, 0.0571902, 0.772061, 0.996865, - 0.0345622, 0.0555321, 0.798089, 0.996802, - 0.0342566, 0.0537816, 0.823178, 0.996992, - 0.0330862, 0.0516095, 0.847949, 0.996944, - 0.0324666, 0.0495537, 0.871431, 0.997146, - 0.0309544, 0.0470302, 0.894357, 0.997189, - 0.0299372, 0.0446043, 0.916142, 0.997471, - 0.0281389, 0.0418812, 0.937193, 0.997515, - 0.0268702, 0.0391823, 0.957, 0.997812, - 0.0247166, 0.0361338, 0.975936, 0.998027, - 0.0233525, 0.0333945, 0.99391, 0.998233, - 0.0209839, 0.0301917, 1.01075, 0.998481, - 0.0194309, 0.027271, 1.02669, 0.998859, - 0.0169728, 0.0240162, 1.04173, 0.99894, - 0.0152322, 0.0210517, 1.05551, 0.999132, - 0.0127497, 0.0178632, 1.06856, 0.999369, - 0.0108282, 0.014787, 1.08054, 0.999549, - 0.00845886, 0.0116185, 1.09185, 0.999805, - 0.0063937, 0.00867209, 1.10207, 0.99985, - 0.00414582, 0.00566823, 1.1117, 0.999912, - 0.00207443, 0.00277562, 1.12022, 1.00001, 8.70226e-05, - 5.3766e-05, 1.12832, 0.991943, - 1.78672e-06, 0.0893382, 1.98384e-05, 0.991952, - 4.50183e-05, 0.089339, 0.000499849, 0.991956, - 0.000180074, 0.0893394, 0.0019994, 0.991955, - 0.000405167, 0.0893393, 0.00449867, 0.991953, - 0.000720298, 0.0893391, 0.00799764, 0.991955, - 0.00112548, 0.0893393, 0.0124964, 0.991957, - 0.0016207, 0.0893395, 0.0179951, 0.991958, - 0.00220601, 0.0893396, 0.0244939, 0.991947, - 0.00288137, 0.0893385, 0.0319929, 0.991962, - 0.00364693, 0.0893399, 0.0404933, 0.991965, - 0.00450264, 0.0893399, 0.049995, 0.99198, - 0.00544862, 0.0893411, 0.0604995, 0.99197, - 0.00648491, 0.0893397, 0.0720074, 0.991976, - 0.00761164, 0.089341, 0.0845207, 0.99198, - 0.00882891, 0.0893405, 0.0980413, 0.991982, - 0.0101367, 0.0893396, 0.112571, 0.992008, - 0.011535, 0.0893415, 0.128115, 0.992026, - 0.0130228, 0.0893414, 0.144672, 0.992064, - 0.0145966, 0.0893418, 0.162241, 0.992041, - 0.0162421, 0.0893359, 0.180801, 0.992086, - 0.0178888, 0.0893214, 0.200302, 0.992157, - 0.0190368, 0.0892401, 0.220332, 0.992181, - 0.0195584, 0.0890525, 0.240144, 0.992175, - 0.0227257, 0.0892153, 0.260728, 0.99221, - 0.0254195, 0.089304, 0.283473, 0.99222, - 0.0274883, 0.0892703, 0.307673, 0.992317, - 0.0294905, 0.0892027, 0.332729, 0.992374, - 0.0311861, 0.0890577, 0.358387, 0.992505, - 0.0320656, 0.0886994, 0.384102, 0.992568, - 0.0329715, 0.0883198, 0.409767, 0.992675, - 0.036006, 0.0883602, 0.436145, 0.992746, - 0.0392897, 0.0884591, 0.463217, 0.992873, - 0.0399337, 0.0878287, 0.491557, 0.992934, - 0.040231, 0.0870108, 0.519516, 0.993091, - 0.0422013, 0.0865857, 0.547741, 0.993259, - 0.0443503, 0.0861937, 0.575792, 0.993455, - 0.0446368, 0.0851187, 0.604233, 0.993497, - 0.0454299, 0.0840576, 0.632925, 0.993694, - 0.0463296, 0.0829671, 0.660985, 0.993718, - 0.0470619, 0.0817185, 0.688714, 0.993973, - 0.0468838, 0.0800294, 0.716743, 0.994207, - 0.046705, 0.0781286, 0.74377, 0.994168, - 0.0469698, 0.0763337, 0.77042, 0.9945, - 0.0456816, 0.0738184, 0.796659, 0.994356, - 0.0455518, 0.0715545, 0.821868, 0.994747, - 0.0439488, 0.0686085, 0.846572, 0.994937, - 0.0430056, 0.065869, 0.870435, 0.995142, - 0.0413414, 0.0626446, 0.893272, 0.995451, - 0.0396521, 0.05929, 0.915376, 0.995445, - 0.0378453, 0.0558503, 0.936196, 0.995967, - 0.0355219, 0.0520949, 0.956376, 0.996094, - 0.0335146, 0.048377, 0.975327, 0.996622, - 0.030682, 0.0442575, 0.993471, 0.996938, - 0.0285504, 0.0404693, 1.01052, 0.997383, - 0.0253399, 0.0360903, 1.02637, 0.997714, - 0.0231651, 0.0322176, 1.04139, 0.998249, - 0.0198138, 0.0278433, 1.05542, 0.998596, - 0.0174337, 0.0238759, 1.06846, 0.998946, - 0.0141349, 0.0195944, 1.08056, 0.99928, - 0.0115603, 0.0156279, 1.09181, 0.999507, - 0.00839065, 0.0114607, 1.10213, 0.999697, - 0.005666, 0.00763325, 1.11169, 0.999869, - 0.00269902, 0.00364946, 1.12042, 1.00001, 6.23836e-05, - 3.19288e-05, 1.12832, 0.987221, - 2.22675e-06, 0.111332, 1.97456e-05, 0.98739, - 5.61116e-05, 0.111351, 0.000497563, 0.987448, - 0.000224453, 0.111357, 0.00199031, 0.987441, - 0.000505019, 0.111357, 0.0044782, 0.987442, - 0.000897816, 0.111357, 0.00796129, 0.987442, - 0.00140284, 0.111357, 0.0124396, 0.987444, - 0.00202012, 0.111357, 0.0179132, 0.987442, - 0.00274964, 0.111357, 0.0243824, 0.987446, - 0.00359147, 0.111357, 0.0318474, 0.987435, - 0.00454562, 0.111356, 0.0403086, 0.987461, - 0.00561225, 0.111358, 0.0497678, 0.987458, - 0.00679125, 0.111358, 0.0602239, 0.987443, - 0.0080828, 0.111356, 0.0716792, 0.987476, - 0.0094872, 0.111358, 0.0841364, 0.98749, - 0.0110044, 0.111361, 0.097597, 0.987508, - 0.0126344, 0.111362, 0.112062, 0.987494, - 0.0143767, 0.111357, 0.127533, 0.987526, - 0.0162307, 0.111359, 0.144015, 0.987558, - 0.0181912, 0.111361, 0.161502, 0.987602, - 0.0202393, 0.111355, 0.179979, 0.987692, - 0.022273, 0.111346, 0.199386, 0.987702, - 0.0235306, 0.111215, 0.219183, 0.987789, - 0.0247628, 0.111061, 0.239202, 0.987776, - 0.0280668, 0.111171, 0.259957, 0.987856, - 0.0316751, 0.111327, 0.282198, 0.987912, - 0.0342468, 0.111282, 0.306294, 0.988, - 0.0367205, 0.111198, 0.331219, 0.988055, - 0.0387766, 0.110994, 0.356708, 0.988241, - 0.0397722, 0.110547, 0.382234, 0.988399, - 0.0416076, 0.110198, 0.408227, 0.988539, - 0.0448192, 0.110137, 0.434662, 0.988661, - 0.0483793, 0.110143, 0.461442, 0.988967, - 0.0495895, 0.109453, 0.489318, 0.989073, - 0.0506797, 0.108628, 0.517516, 0.989274, - 0.0526953, 0.108003, 0.545844, 0.989528, - 0.054578, 0.107255, 0.573823, 0.989709, - 0.0561503, 0.106294, 0.601944, 0.989991, - 0.056866, 0.104896, 0.630855, 0.990392, - 0.0572914, 0.103336, 0.658925, 0.990374, - 0.0586224, 0.10189, 0.686661, 0.990747, - 0.0584764, 0.099783, 0.714548, 0.991041, - 0.0582662, 0.0974309, 0.74186, 0.991236, - 0.0584118, 0.0951678, 0.768422, 0.991585, - 0.0573055, 0.0921581, 0.794817, 0.991984, - 0.0564241, 0.0891167, 0.820336, 0.9921, - 0.0553608, 0.085805, 0.84493, 0.992749, - 0.0533816, 0.0820354, 0.868961, 0.99288, - 0.0518661, 0.0782181, 0.891931, 0.993511, - 0.0492492, 0.0738935, 0.914186, 0.993617, - 0.0471956, 0.0696402, 0.93532, 0.99411, - 0.044216, 0.0649659, 0.95543, 0.994595, - 0.0416654, 0.0603177, 0.974685, 0.994976, - 0.0384314, 0.0553493, 0.992807, 0.995579, - 0.0353491, 0.0503942, 1.00996, 0.996069, - 0.0319787, 0.0452123, 1.02606, 0.996718, - 0.028472, 0.0400112, 1.04114, 0.997173, - 0.0250789, 0.0349456, 1.05517, 0.997818, - 0.0213326, 0.029653, 1.0683, 0.998318, - 0.0178509, 0.024549, 1.0805, 0.998853, - 0.0141118, 0.0194197, 1.09177, 0.999218, - 0.0105914, 0.0143869, 1.1022, 0.999594, - 0.00693474, 0.00943517, 1.11175, 0.99975, - 0.00340478, 0.00464051, 1.12056, 1.00001, 0.000109172, - 0.000112821, 1.12853, 0.983383, - 2.66524e-06, 0.133358, 1.96534e-05, 0.981942, - 6.71009e-05, 0.133162, 0.000494804, 0.981946, - 0.000268405, 0.133163, 0.00197923, 0.981944, - 0.000603912, 0.133163, 0.00445326, 0.981941, - 0.00107362, 0.133162, 0.00791693, 0.981946, - 0.00167755, 0.133163, 0.0123703, 0.981944, - 0.00241569, 0.133162, 0.0178135, 0.981945, - 0.00328807, 0.133163, 0.0242466, 0.981945, - 0.00429472, 0.133162, 0.03167, 0.981955, - 0.00543573, 0.133164, 0.0400846, 0.981951, - 0.00671105, 0.133163, 0.0494901, 0.981968, - 0.00812092, 0.133165, 0.0598886, 0.981979, - 0.00966541, 0.133166, 0.0712811, 0.981996, - 0.0113446, 0.133168, 0.083669, 0.982014, - 0.0131585, 0.133169, 0.0970533, 0.982011, - 0.0151073, 0.133167, 0.111438, 0.982062, - 0.0171906, 0.133172, 0.126826, 0.9821, - 0.0194067, 0.133175, 0.143215, 0.982149, - 0.0217502, 0.133176, 0.160609, 0.982163, - 0.0241945, 0.133173, 0.178981, 0.982247, - 0.0265907, 0.133148, 0.198249, 0.982291, - 0.027916, 0.132974, 0.217795, 0.982396, - 0.0299663, 0.132868, 0.238042, 0.982456, - 0.0334544, 0.132934, 0.258901, 0.982499, - 0.0378636, 0.133137, 0.280639, 0.982617, - 0.0409274, 0.133085, 0.304604, 0.98274, - 0.0438523, 0.132985, 0.329376, 0.982944, - 0.0462288, 0.132728, 0.354697, 0.98308, - 0.0475995, 0.132228, 0.380102, 0.983391, - 0.0501901, 0.131924, 0.406256, 0.983514, - 0.0535899, 0.131737, 0.432735, 0.98373, - 0.0571858, 0.131567, 0.459359, 0.984056, - 0.0592353, 0.130932, 0.486637, 0.984234, - 0.0610488, 0.130092, 0.51509, 0.984748, - 0.0630758, 0.12923, 0.543461, 0.985073, - 0.0647398, 0.128174, 0.571376, 0.985195, - 0.0671941, 0.127133, 0.599414, 0.985734, - 0.0681345, 0.125576, 0.628134, 0.986241, - 0.0686089, 0.123639, 0.656399, 0.986356, - 0.0698511, 0.121834, 0.684258, 0.986894, - 0.0700931, 0.119454, 0.711818, 0.987382, - 0.0698321, 0.116718, 0.739511, 0.988109, - 0.0693975, 0.113699, 0.766267, 0.988363, - 0.0689584, 0.110454, 0.792456, 0.989112, - 0.0672353, 0.106602, 0.81813, 0.989241, - 0.0662034, 0.10267, 0.842889, 0.990333, - 0.0638938, 0.0981381, 0.867204, 0.990591, - 0.0618534, 0.0935388, 0.89038, 0.991106, - 0.0593117, 0.088553, 0.912576, 0.991919, - 0.0562676, 0.0832187, 0.934118, 0.992111, - 0.0534085, 0.0778302, 0.954254, 0.992997, - 0.0495459, 0.0720453, 0.973722, 0.993317, - 0.0463707, 0.0663458, 0.991949, 0.994133, - 0.0421245, 0.0601883, 1.00936, 0.994705, - 0.0384977, 0.0542501, 1.02559, 0.995495, - 0.0340956, 0.0479862, 1.04083, 0.996206, - 0.030105, 0.041887, 1.05497, 0.996971, - 0.0256095, 0.0355355, 1.06824, 0.997796, - 0.0213932, 0.0293655, 1.08056, 0.998272, - 0.0169612, 0.0232926, 1.09182, 0.998857, - 0.0126756, 0.0172786, 1.10219, 0.99939, - 0.00832486, 0.0113156, 1.11192, 0.999752, - 0.00410826, 0.00557892, 1.12075, 1, 0.000150957, - 0.000119101, 1.12885, 0.975169, - 3.09397e-06, 0.154669, 1.95073e-05, 0.975439, - 7.79608e-05, 0.154712, 0.000491534, 0.975464, - 0.000311847, 0.154716, 0.00196617, 0.975464, - 0.000701656, 0.154716, 0.00442387, 0.975462, - 0.0012474, 0.154715, 0.0078647, 0.975461, - 0.00194906, 0.154715, 0.0122886, 0.975464, - 0.00280667, 0.154715, 0.0176959, 0.975468, - 0.00382025, 0.154716, 0.0240867, 0.975471, - 0.00498985, 0.154716, 0.0314612, 0.975472, - 0.00631541, 0.154717, 0.0398199, 0.975486, - 0.00779719, 0.154718, 0.0491639, 0.975489, - 0.00943505, 0.154718, 0.0594932, 0.975509, - 0.0112295, 0.154721, 0.0708113, 0.97554, - 0.0131802, 0.154724, 0.0831176, 0.975557, - 0.0152876, 0.154726, 0.096415, 0.975585, - 0.0175512, 0.154728, 0.110705, 0.975605, - 0.0199713, 0.154729, 0.125992, 0.975645, - 0.0225447, 0.154729, 0.142272, 0.975711, - 0.0252649, 0.154735, 0.159549, 0.975788, - 0.0280986, 0.154736, 0.177805, 0.975872, - 0.0308232, 0.154704, 0.196911, 0.975968, - 0.0324841, 0.154525, 0.216324, 0.976063, - 0.0351281, 0.154432, 0.236628, 0.976157, - 0.0388618, 0.15446, 0.257539, 0.976204, - 0.0437704, 0.154665, 0.278975, 0.976358, - 0.047514, 0.154652, 0.302606, 0.976571, - 0.0508638, 0.154535, 0.327204, 0.976725, - 0.0534995, 0.154221, 0.352276, 0.977013, - 0.0555547, 0.153737, 0.377696, 0.977294, - 0.0586728, 0.153403, 0.403855, 0.977602, - 0.0622715, 0.15312, 0.430333, 0.977932, - 0.0658166, 0.152755, 0.456855, 0.978241, - 0.0689877, 0.152233, 0.483668, 0.978602, - 0.0712805, 0.15132, 0.512097, 0.979234, - 0.0732775, 0.150235, 0.540455, 0.97977, - 0.075163, 0.148978, 0.568486, 0.979995, - 0.0778026, 0.147755, 0.596524, 0.98078, - 0.0791854, 0.146019, 0.624825, 0.981628, - 0.0799666, 0.143906, 0.653403, 0.982067, - 0.0808532, 0.141561, 0.681445, 0.98271, - 0.0816024, 0.139025, 0.708918, 0.983734, - 0.0812511, 0.135764, 0.736594, 0.98431, - 0.0806201, 0.132152, 0.763576, 0.985071, - 0.0801605, 0.12846, 0.789797, 0.98618, - 0.0784208, 0.124084, 0.815804, 0.986886, - 0.0766643, 0.1193, 0.840869, 0.987485, - 0.0747744, 0.114236, 0.864952, 0.988431, - 0.0716701, 0.108654, 0.888431, 0.988886, - 0.0691609, 0.102994, 0.910963, 0.990024, - 0.0654048, 0.0967278, 0.932629, 0.990401, - 0.0619765, 0.090384, 0.95313, 0.991093, - 0.0579296, 0.0837885, 0.972587, 0.992018, - 0.0536576, 0.0770171, 0.991184, 0.992536, - 0.0493719, 0.0701486, 1.00863, 0.993421, - 0.0444813, 0.062953, 1.02494, 0.993928, - 0.040008, 0.0560455, 1.04017, 0.994994, - 0.0347982, 0.04856, 1.05463, 0.995866, - 0.0301017, 0.0416152, 1.06807, 0.996916, - 0.0248225, 0.0342597, 1.08039, 0.997766, - 0.0199229, 0.0271668, 1.09177, 0.998479, - 0.0147422, 0.0201387, 1.10235, 0.99921, - 0.00980173, 0.0131944, 1.11206, 0.999652, - 0.0047426, 0.00640712, 1.12104, 0.999998, 8.91673e-05, - 0.00010379, 1.12906, 0.967868, - 3.51885e-06, 0.175947, 1.93569e-05, 0.968001, - 8.86733e-05, 0.175972, 0.000487782, 0.96801, - 0.000354697, 0.175973, 0.00195115, 0.968012, - 0.000798063, 0.175974, 0.00439006, 0.968011, - 0.00141879, 0.175973, 0.00780461, 0.968011, - 0.00221686, 0.175973, 0.0121948, 0.968016, - 0.00319231, 0.175974, 0.0175607, 0.968019, - 0.00434515, 0.175974, 0.0239027, 0.968018, - 0.00567538, 0.175974, 0.0312208, 0.968033, - 0.00718308, 0.175977, 0.0395158, 0.968049, - 0.00886836, 0.175979, 0.0487885, 0.968047, - 0.0107312, 0.175978, 0.0590394, 0.968072, - 0.0127719, 0.175981, 0.0702705, 0.968108, - 0.0149905, 0.175986, 0.0824836, 0.968112, - 0.0173866, 0.175985, 0.0956783, 0.968173, - 0.0199611, 0.175993, 0.109862, 0.96827, - 0.0227128, 0.176008, 0.125033, 0.968292, - 0.025639, 0.17601, 0.141193, 0.968339, - 0.0287299, 0.176007, 0.158336, 0.968389, - 0.0319399, 0.176001, 0.176441, 0.968501, - 0.034941, 0.175962, 0.195359, 0.968646, - 0.0370812, 0.175793, 0.214686, 0.968789, - 0.0402329, 0.175708, 0.234973, 0.96886, - 0.0442601, 0.1757, 0.255871, 0.969013, - 0.049398, 0.175876, 0.277238, 0.969242, - 0.0539932, 0.17594, 0.300326, 0.969419, - 0.0577299, 0.175781, 0.324702, 0.969763, - 0.0605643, 0.175432, 0.349527, 0.970093, - 0.0634488, 0.174992, 0.374976, 0.970361, - 0.0670589, 0.174611, 0.401097, 0.970825, - 0.0708246, 0.174226, 0.427496, 0.971214, - 0.0742871, 0.173684, 0.453858, 0.971622, - 0.0782608, 0.173186, 0.480637, 0.972175, - 0.0813151, 0.172288, 0.508655, 0.972944, - 0.0832678, 0.170979, 0.536973, 0.973595, - 0.0855964, 0.169573, 0.565138, 0.974345, - 0.0882163, 0.168152, 0.593222, 0.975233, - 0.0901671, 0.166314, 0.621201, 0.976239, - 0.0912111, 0.163931, 0.649919, 0.977289, - 0.0916959, 0.161106, 0.678011, 0.978076, - 0.0927061, 0.158272, 0.705717, 0.979533, - 0.0925562, 0.15475, 0.733228, 0.980335, - 0.0918159, 0.150638, 0.760454, 0.981808, - 0.0908508, 0.146201, 0.786918, 0.983061, - 0.0896172, 0.141386, 0.812953, 0.984148, - 0.0871588, 0.135837, 0.838281, 0.985047, - 0.0850624, 0.130135, 0.862594, 0.986219, - 0.0818541, 0.123882, 0.88633, 0.987043, - 0.0784523, 0.117126, 0.908952, 0.988107, - 0.0749601, 0.110341, 0.930744, 0.988955, - 0.0703548, 0.102885, 0.951728, 0.989426, - 0.0662798, 0.0954167, 0.971166, 0.990421, - 0.0610834, 0.0876331, 0.989984, 0.991032, - 0.0562936, 0.0797785, 1.00765, 0.992041, - 0.0508154, 0.0718166, 1.02434, 0.992794, - 0.0454045, 0.0637125, 1.03976, 0.993691, - 0.0398194, 0.0555338, 1.05418, 0.994778, - 0.0341482, 0.0473388, 1.06772, 0.995915, - 0.028428, 0.0391016, 1.08028, 0.997109, - 0.022642, 0.0309953, 1.09185, 0.998095, - 0.0168738, 0.0230288, 1.10247, 0.998985, - 0.0111274, 0.0150722, 1.11229, 0.999581, - 0.00543881, 0.00740605, 1.12131, 1.00003, 0.000162239, - 0.000105549, 1.12946, 0.959505, - 3.93734e-06, 0.196876, 1.91893e-05, 0.959599, - 9.92157e-05, 0.196895, 0.000483544, 0.959641, - 0.000396868, 0.196903, 0.0019342, 0.959599, - 0.000892948, 0.196895, 0.00435193, 0.959603, - 0.00158747, 0.196896, 0.0077368, 0.959604, - 0.00248042, 0.196896, 0.0120888, 0.959605, - 0.00357184, 0.196896, 0.0174082, 0.959605, - 0.00486169, 0.196896, 0.0236949, 0.959613, - 0.00635008, 0.196897, 0.0309497, 0.959619, - 0.00803696, 0.196898, 0.0391725, 0.959636, - 0.00992255, 0.196901, 0.0483649, 0.959634, - 0.0120067, 0.1969, 0.0585266, 0.959675, - 0.0142898, 0.196906, 0.0696609, 0.959712, - 0.0167717, 0.196911, 0.0817678, 0.959752, - 0.0194524, 0.196918, 0.0948494, 0.959807, - 0.0223321, 0.196925, 0.10891, 0.959828, - 0.0254091, 0.196924, 0.123947, 0.959906, - 0.0286815, 0.196934, 0.139968, 0.960005, - 0.0321371, 0.196944, 0.156968, 0.960071, - 0.0357114, 0.196936, 0.17491, 0.960237, - 0.0389064, 0.196882, 0.193597, 0.960367, - 0.041623, 0.196731, 0.21285, 0.960562, - 0.0452655, 0.196654, 0.233075, 0.960735, - 0.0496207, 0.196643, 0.253941, 0.960913, - 0.0549379, 0.196774, 0.275278, 0.961121, - 0.0603414, 0.196893, 0.297733, 0.96139, - 0.0644244, 0.196717, 0.321877, 0.961818, - 0.067556, 0.196314, 0.346476, 0.962175, - 0.0712709, 0.195917, 0.371907, 0.96255, - 0.0752848, 0.1955, 0.397916, 0.963164, - 0.0792073, 0.195026, 0.424229, 0.963782, - 0.0828225, 0.194424, 0.450637, 0.964306, - 0.0873119, 0.193831, 0.477288, 0.964923, - 0.0911051, 0.192973, 0.504716, 0.966048, - 0.093251, 0.19151, 0.533053, 0.967024, - 0.0958983, 0.190013, 0.561366, 0.968038, - 0.09835, 0.188253, 0.589464, 0.969152, - 0.100754, 0.186257, 0.617433, 0.970557, - 0.102239, 0.183775, 0.645801, 0.972104, - 0.102767, 0.180645, 0.674278, 0.973203, - 0.103492, 0.177242, 0.702004, 0.975123, - 0.103793, 0.17345, 0.729529, 0.97641, - 0.102839, 0.168886, 0.756712, 0.978313, - 0.101687, 0.163892, 0.783801, 0.980036, - 0.100314, 0.158439, 0.809671, 0.981339, - 0.097836, 0.152211, 0.835402, 0.982794, - 0.0950006, 0.145679, 0.860081, 0.984123, - 0.0920994, 0.138949, 0.883757, 0.984918, - 0.0878641, 0.131283, 0.90685, 0.985999, - 0.083939, 0.123464, 0.928786, 0.987151, - 0.0791234, 0.115324, 0.94983, 0.987827, - 0.0739332, 0.106854, 0.96962, 0.988806, - 0.0688088, 0.0982691, 0.98861, 0.989588, - 0.0628962, 0.0893456, 1.00667, 0.990438, - 0.0573146, 0.0805392, 1.02344, 0.991506, - 0.0509433, 0.0713725, 1.03933, 0.992492, - 0.0448724, 0.0623732, 1.05378, 0.993663, - 0.0383497, 0.0530838, 1.06747, 0.994956, - 0.0319593, 0.0439512, 1.08007, 0.99634, - 0.025401, 0.0347803, 1.09182, 0.99761, - 0.0189687, 0.0257954, 1.1025, 0.99863, - 0.0124441, 0.0169893, 1.11247, 0.99947, - 0.00614003, 0.00829498, 1.12151, 1.00008, 0.000216624, - 0.000146107, 1.12993, 0.950129, - 4.34955e-06, 0.217413, 1.90081e-05, 0.950264, - 0.00010957, 0.217444, 0.00047884, 0.9503, - 0.000438299, 0.217451, 0.00191543, 0.950246, - 0.000986124, 0.21744, 0.00430951, 0.950246, - 0.00175311, 0.21744, 0.00766137, 0.950245, - 0.00273923, 0.21744, 0.011971, 0.950253, - 0.00394453, 0.217441, 0.0172385, 0.950258, - 0.00536897, 0.217442, 0.0234641, 0.950267, - 0.00701262, 0.217444, 0.030648, 0.950277, - 0.00887551, 0.217446, 0.038791, 0.950284, - 0.0109576, 0.217446, 0.0478931, 0.950312, - 0.0132591, 0.217451, 0.0579568, 0.950334, - 0.01578, 0.217454, 0.0689821, 0.950378, - 0.0185204, 0.217462, 0.0809714, 0.950417, - 0.0214803, 0.217467, 0.0939265, 0.950488, - 0.0246594, 0.217479, 0.10785, 0.950534, - 0.0280565, 0.217483, 0.122743, 0.950633, - 0.0316685, 0.217498, 0.138611, 0.950698, - 0.0354787, 0.217499, 0.155442, 0.950844, - 0.0394003, 0.217507, 0.173208, 0.950999, - 0.0426812, 0.217419, 0.191605, 0.951221, - 0.0461302, 0.217317, 0.21084, 0.951412, - 0.0502131, 0.217238, 0.230945, 0.951623, - 0.0549183, 0.21722, 0.251745, 0.951867, - 0.0604493, 0.217306, 0.273001, 0.952069, - 0.0665189, 0.217466, 0.294874, 0.952459, - 0.0709179, 0.217266, 0.318732, 0.952996, - 0.0746112, 0.216891, 0.34318, 0.953425, - 0.0789252, 0.216503, 0.36849, 0.953885, - 0.0833293, 0.216042, 0.394373, 0.954617, - 0.087371, 0.215469, 0.420505, 0.955429, - 0.0914054, 0.214802, 0.446907, 0.956068, - 0.0961671, 0.214146, 0.473522, 0.957094, - 0.10048, 0.213286, 0.50052, 0.958372, - 0.103248, 0.211796, 0.528715, 0.959654, - 0.106033, 0.21016, 0.557065, 0.961305, - 0.108384, 0.208149, 0.585286, 0.962785, - 0.111122, 0.206024, 0.613334, 0.964848, - 0.112981, 0.203442, 0.641334, 0.966498, - 0.113717, 0.19996, 0.669955, 0.968678, - 0.114121, 0.196105, 0.698094, 0.970489, - 0.114524, 0.191906, 0.725643, 0.972903, - 0.113792, 0.186963, 0.752856, 0.974701, - 0.112406, 0.181343, 0.780013, 0.976718, - 0.110685, 0.175185, 0.806268, 0.978905, - 0.108468, 0.168535, 0.832073, 0.980267, - 0.105061, 0.161106, 0.857149, 0.981967, - 0.101675, 0.153387, 0.881145, 0.983063, - 0.0974492, 0.145199, 0.904255, 0.984432, - 0.0925815, 0.136527, 0.926686, 0.985734, - 0.0877983, 0.127584, 0.947901, 0.986228, - 0.081884, 0.118125, 0.968111, 0.98719, - 0.0761208, 0.108594, 0.98719, 0.988228, - 0.0698196, 0.0989996, 1.00559, 0.989046, - 0.0632739, 0.0890074, 1.02246, 0.990242, - 0.056522, 0.0790832, 1.03841, 0.991252, - 0.0495272, 0.0689182, 1.05347, 0.992542, - 0.0425373, 0.0588592, 1.06724, 0.994096, - 0.0353198, 0.0486833, 1.08009, 0.995593, - 0.028235, 0.0385977, 1.09177, 0.99711, - 0.0209511, 0.0286457, 1.10274, 0.998263, - 0.0139289, 0.0188497, 1.11262, 0.999254, - 0.0067359, 0.009208, 1.12191, 0.999967, 0.000141846, - 6.57764e-05, 1.13024, 0.935608, - 4.74692e-06, 0.236466, 1.87817e-05, 0.93996, - 0.00011971, 0.237568, 0.000473646, 0.939959, - 0.000478845, 0.237567, 0.0018946, 0.939954, - 0.0010774, 0.237566, 0.00426284, 0.939956, - 0.00191538, 0.237566, 0.00757842, 0.939954, - 0.00299277, 0.237566, 0.0118413, 0.93996, - 0.00430961, 0.237567, 0.0170518, 0.939969, - 0.00586589, 0.237569, 0.02321, 0.939982, - 0.00766166, 0.237572, 0.0303164, 0.939987, - 0.00969686, 0.237572, 0.0383711, 0.939997, - 0.0119715, 0.237574, 0.0473751, 0.940031, - 0.0144858, 0.237581, 0.0573298, 0.940073, - 0.0172399, 0.237589, 0.0682366, 0.94012, - 0.0202335, 0.237598, 0.080097, 0.940162, - 0.0234663, 0.237604, 0.0929116, 0.940237, - 0.0269387, 0.237615, 0.106686, 0.940328, - 0.0306489, 0.237632, 0.121421, 0.940419, - 0.0345917, 0.237645, 0.137115, 0.940522, - 0.0387481, 0.237654, 0.153766, 0.940702, - 0.0429906, 0.237661, 0.17133, 0.940871, - 0.0465089, 0.237561, 0.189502, 0.941103, - 0.050531, 0.23748, 0.208616, 0.941369, - 0.0550657, 0.237423, 0.228595, 0.941641, - 0.0601337, 0.237399, 0.249287, 0.941903, - 0.0658804, 0.237443, 0.270467, 0.942224, - 0.0722674, 0.237597, 0.292024, 0.942633, - 0.0771788, 0.237419, 0.315272, 0.943172, - 0.0815623, 0.237068, 0.339579, 0.943691, - 0.0863973, 0.236682, 0.364717, 0.944382, - 0.0911536, 0.236213, 0.390435, 0.945392, - 0.0952967, 0.235562, 0.416425, 0.946185, - 0.0998948, 0.234832, 0.442772, 0.947212, - 0.104796, 0.234114, 0.469347, 0.948778, - 0.10928, 0.233222, 0.496162, 0.950149, - 0.113081, 0.231845, 0.523978, 0.951989, - 0.115893, 0.230005, 0.552295, 0.953921, - 0.11846, 0.227862, 0.580569, 0.955624, - 0.12115, 0.225439, 0.608698, 0.958234, - 0.123373, 0.222635, 0.636696, 0.960593, - 0.124519, 0.219093, 0.665208, 0.963201, - 0.124736, 0.214749, 0.693557, 0.965642, - 0.125012, 0.210059, 0.721334, 0.968765, - 0.124661, 0.204935, 0.748613, 0.971753, - 0.122996, 0.198661, 0.776224, 0.973751, - 0.120998, 0.191823, 0.802461, 0.976709, - 0.118583, 0.184359, 0.828399, 0.977956, - 0.115102, 0.176437, 0.853693, 0.979672, - 0.111077, 0.167681, 0.877962, 0.981816, - 0.10688, 0.158872, 0.901564, 0.98238, - 0.101469, 0.149398, 0.924057, 0.983964, - 0.0960013, 0.139436, 0.945751, 0.984933, - 0.0899626, 0.12943, 0.966272, 0.985694, - 0.0832973, 0.11894, 0.985741, 0.986822, - 0.0767082, 0.108349, 1.00407, 0.987725, - 0.0693614, 0.0976026, 1.02154, 0.98877, - 0.06211, 0.086652, 1.03757, 0.990129, - 0.0544143, 0.0756182, 1.05296, 0.991337, - 0.046744, 0.0645753, 1.06683, 0.992978, - 0.0387931, 0.0534683, 1.0798, 0.994676, - 0.030973, 0.0424137, 1.09181, 0.99645, - 0.0230311, 0.0314035, 1.10286, 0.997967, - 0.0152065, 0.0206869, 1.11291, 0.99922, - 0.00744837, 0.010155, 1.12237, 1.00002, 0.000240209, - 7.52767e-05, 1.13089, 0.922948, - 5.15351e-06, 0.255626, 1.86069e-05, 0.928785, - 0.000129623, 0.257244, 0.000468009, 0.928761, - 0.00051849, 0.257237, 0.00187202, 0.928751, - 0.0011666, 0.257235, 0.00421204, 0.928751, - 0.00207395, 0.257234, 0.0074881, 0.928754, - 0.00324055, 0.257235, 0.0117002, 0.92876, - 0.00466639, 0.257236, 0.0168486, 0.928763, - 0.00635149, 0.257237, 0.0229334, 0.928774, - 0.00829584, 0.257239, 0.029955, 0.928791, - 0.0104995, 0.257243, 0.0379139, 0.928804, - 0.0129623, 0.257245, 0.0468108, 0.928847, - 0.0156846, 0.257255, 0.0566473, 0.92889, - 0.0186661, 0.257263, 0.0674246, 0.928924, - 0.0219067, 0.257268, 0.0791433, 0.928989, - 0.0254066, 0.257282, 0.0918076, 0.92909, - 0.0291651, 0.257301, 0.105419, 0.92918, - 0.0331801, 0.257316, 0.119978, 0.92929, - 0.0374469, 0.257332, 0.135491, 0.929453, - 0.041939, 0.257357, 0.151948, 0.929586, - 0.0464612, 0.257347, 0.169275, 0.929858, - 0.0503426, 0.257269, 0.187257, 0.930125, - 0.0548409, 0.257199, 0.206204, 0.930403, - 0.0598063, 0.257149, 0.22601, 0.930726, - 0.0652437, 0.257122, 0.246561, 0.931098, - 0.0712376, 0.257153, 0.267618, 0.931396, - 0.0777506, 0.257237, 0.288993, 0.931947, - 0.0832374, 0.257124, 0.311527, 0.932579, - 0.0883955, 0.25683, 0.335697, 0.933194, - 0.0937037, 0.256444, 0.360634, 0.934013, - 0.0987292, 0.255939, 0.386126, 0.935307, - 0.103215, 0.255282, 0.412018, 0.936374, - 0.108234, 0.254538, 0.438292, 0.93776, - 0.113234, 0.253728, 0.464805, 0.939599, - 0.118013, 0.25275, 0.491464, 0.941036, - 0.122661, 0.251404, 0.518751, 0.94337, - 0.125477, 0.249435, 0.547133, 0.945318, - 0.128374, 0.247113, 0.575456, 0.947995, - 0.130996, 0.244441, 0.60372, 0.950818, - 0.133438, 0.241352, 0.63174, 0.954378, - 0.135004, 0.237849, 0.659971, 0.957151, - 0.135313, 0.233188, 0.688478, 0.960743, - 0.13521, 0.228001, 0.716767, 0.964352, - 0.135007, 0.222249, 0.744349, 0.967273, - 0.133523, 0.21542, 0.771786, 0.969767, - 0.131155, 0.208039, 0.798639, 0.973195, - 0.128492, 0.200076, 0.824774, 0.975557, - 0.125094, 0.191451, 0.850222, 0.977692, - 0.120578, 0.18184, 0.874761, 0.98026, - 0.115882, 0.172102, 0.898497, 0.981394, - 0.110372, 0.161859, 0.921636, 0.982386, - 0.10415, 0.15108, 0.943467, 0.983783, - 0.0978128, 0.140407, 0.964045, 0.98422, - 0.0906171, 0.129058, 0.98398, 0.985447, - 0.0832921, 0.117614, 1.00276, 0.986682, - 0.0754412, 0.10585, 1.02047, 0.987326, - 0.0673885, 0.0940943, 1.03678, 0.988707, - 0.0592565, 0.0822093, 1.05218, 0.990185, - 0.050717, 0.070192, 1.06652, 0.991866, - 0.0423486, 0.0582081, 1.07965, 0.993897, - 0.0336118, 0.0460985, 1.09188, 0.995841, - 0.0252178, 0.0342737, 1.10307, 0.997605, - 0.0164893, 0.0224829, 1.11324, 0.999037, - 0.00817112, 0.0110647, 1.12262, 1.00003, 0.000291686, - 0.000168673, 1.13139, 0.915304, - 5.52675e-06, 0.275999, 1.83285e-05, 0.91668, - 0.000139285, 0.276414, 0.000461914, 0.916664, - 0.00055713, 0.276409, 0.00184763, 0.916653, - 0.00125354, 0.276406, 0.00415715, 0.916651, - 0.00222851, 0.276405, 0.00739053, 0.916655, - 0.00348205, 0.276406, 0.0115478, 0.916653, - 0.00501414, 0.276405, 0.0166291, 0.916667, - 0.00682478, 0.276409, 0.0226346, 0.91668, - 0.00891398, 0.276412, 0.0295648, 0.91669, - 0.0112817, 0.276413, 0.0374199, 0.916727, - 0.013928, 0.276422, 0.0462016, 0.916759, - 0.0168528, 0.276429, 0.0559101, 0.916793, - 0.0200558, 0.276436, 0.0665466, 0.916849, - 0.0235373, 0.276448, 0.0781139, 0.916964, - 0.0272973, 0.276474, 0.0906156, 0.917047, - 0.0313344, 0.276491, 0.104051, 0.917152, - 0.0356465, 0.276511, 0.118424, 0.917286, - 0.0402271, 0.276533, 0.133736, 0.917469, - 0.0450408, 0.276564, 0.149978, 0.917686, - 0.0497872, 0.276563, 0.167057, 0.917953, - 0.0540937, 0.276493, 0.184846, 0.918228, - 0.0590709, 0.276437, 0.203614, 0.918572, - 0.0644277, 0.276398, 0.223212, 0.918918, - 0.0702326, 0.276362, 0.243584, 0.919356, - 0.076484, 0.276383, 0.264465, 0.919842, - 0.0830808, 0.276434, 0.285701, 0.920451, - 0.0892972, 0.276407, 0.307559, 0.921113, - 0.095016, 0.276128, 0.331501, 0.921881, - 0.100771, 0.275754, 0.356207, 0.923027, - 0.106029, 0.275254, 0.381477, 0.924364, - 0.111029, 0.274595, 0.40722, 0.925818, - 0.116345, 0.273841, 0.433385, 0.92746, - 0.121424, 0.272913, 0.459848, 0.929167, - 0.12657, 0.271837, 0.486493, 0.931426, - 0.131581, 0.270575, 0.513432, 0.934001, - 0.135038, 0.268512, 0.541502, 0.936296, - 0.138039, 0.266135, 0.569658, 0.939985, - 0.140687, 0.263271, 0.598375, 0.943516, - 0.143247, 0.260058, 0.626563, 0.94782, - 0.145135, 0.256138, 0.654711, 0.951023, - 0.145733, 0.251154, 0.683285, 0.955338, - 0.145554, 0.245562, 0.711831, 0.959629, - 0.145008, 0.239265, 0.739573, 0.963123, - 0.144003, 0.232064, 0.767027, 0.966742, - 0.141289, 0.224036, 0.794359, 0.969991, - 0.138247, 0.215305, 0.820361, 0.973403, - 0.134786, 0.206051, 0.846548, 0.975317, - 0.129966, 0.195914, 0.871541, 0.977647, - 0.12471, 0.185184, 0.895313, 0.980137, - 0.119086, 0.174161, 0.918398, 0.981031, - 0.112297, 0.162792, 0.940679, 0.982037, - 0.105372, 0.150952, 0.961991, 0.983164, - 0.097821, 0.138921, 0.981913, 0.983757, - 0.0897245, 0.126611, 1.00109, 0.985036, - 0.0815974, 0.114228, 1.01902, 0.986289, - 0.0727725, 0.101389, 1.03604, 0.987329, - 0.0639323, 0.0886476, 1.05149, 0.989193, - 0.0548109, 0.0756837, 1.06619, 0.990716, - 0.045687, 0.0627581, 1.07948, 0.992769, - 0.0364315, 0.0498337, 1.09172, 0.99524, - 0.0271761, 0.0370305, 1.1033, 0.997154, - 0.0179609, 0.0243959, 1.11353, 0.998845, - 0.00878063, 0.0119567, 1.12319, 1.00002, 0.000259038, - 0.000108146, 1.13177, 0.903945, - 5.91681e-06, 0.295126, 1.81226e-05, 0.903668, - 0.000148672, 0.295037, 0.000455367, 0.903677, - 0.000594683, 0.29504, 0.00182145, 0.903673, - 0.00133805, 0.295039, 0.00409831, 0.903666, - 0.00237872, 0.295036, 0.00728584, 0.903668, - 0.00371676, 0.295037, 0.0113842, 0.903679, - 0.00535212, 0.29504, 0.0163936, 0.903684, - 0.00728479, 0.295041, 0.0223141, 0.903698, - 0.00951473, 0.295044, 0.0291462, 0.903718, - 0.0120419, 0.295049, 0.0368904, 0.903754, - 0.0148664, 0.295058, 0.0455477, 0.903801, - 0.017988, 0.29507, 0.0551194, 0.903851, - 0.0214064, 0.295082, 0.0656058, 0.903921, - 0.0251219, 0.295097, 0.0770109, 0.904002, - 0.0291337, 0.295116, 0.0893354, 0.904111, - 0.033441, 0.29514, 0.102583, 0.904246, - 0.0380415, 0.295169, 0.116755, 0.904408, - 0.0429258, 0.295202, 0.131853, 0.904637, - 0.0480468, 0.295245, 0.147869, 0.904821, - 0.0529208, 0.295214, 0.164658, 0.905163, - 0.0577748, 0.295185, 0.182274, 0.905469, - 0.0631763, 0.295143, 0.200828, 0.905851, - 0.068917, 0.295112, 0.2202, 0.906322, - 0.0750861, 0.295104, 0.240372, 0.906761, - 0.0815855, 0.295086, 0.261082, 0.90735, - 0.0882138, 0.295095, 0.282123, 0.908087, - 0.095082, 0.295139, 0.303563, 0.908826, - 0.101488, 0.29492, 0.327028, 0.909832, - 0.107577, 0.294577, 0.351464, 0.911393, - 0.113033, 0.294115, 0.376497, 0.912804, - 0.118629, 0.293446, 0.402115, 0.914081, - 0.124232, 0.292581, 0.428111, 0.91637, - 0.129399, 0.29166, 0.454442, 0.91814, - 0.134892, 0.290422, 0.481024, 0.921179, - 0.140069, 0.289194, 0.507924, 0.924544, - 0.144431, 0.287421, 0.535557, 0.927995, - 0.147498, 0.284867, 0.563984, 0.931556, - 0.150197, 0.281722, 0.5923, 0.935777, - 0.152711, 0.278207, 0.620832, 0.940869, - 0.154836, 0.274148, 0.649069, 0.945994, - 0.155912, 0.269057, 0.677746, 0.949634, - 0.155641, 0.262799, 0.706293, 0.955032, - 0.154809, 0.256097, 0.734278, 0.95917, - 0.153678, 0.248618, 0.761751, 0.962931, - 0.151253, 0.239794, 0.789032, 0.966045, - 0.147625, 0.230281, 0.815422, 0.96971, - 0.143964, 0.220382, 0.841787, 0.972747, - 0.139464, 0.209846, 0.867446, 0.975545, - 0.133459, 0.198189, 0.892004, 0.978381, - 0.127424, 0.186362, 0.915458, 0.979935, - 0.120506, 0.173964, 0.937948, 0.980948, - 0.11282, 0.161429, 0.959732, 0.982234, - 0.104941, 0.148557, 0.980118, 0.982767, - 0.0962905, 0.135508, 0.999463, 0.983544, - 0.0873625, 0.122338, 1.01756, 0.984965, - 0.0783447, 0.108669, 1.03492, 0.986233, - 0.0684798, 0.0949911, 1.05087, 0.987796, - 0.0590867, 0.0811386, 1.0656, 0.989885, - 0.0489145, 0.0673099, 1.0794, 0.991821, - 0.0391, 0.0535665, 1.09174, 0.99448, - 0.029087, 0.0397529, 1.10341, 0.996769, - 0.019114, 0.0261463, 1.11383, 0.998641, - 0.00947007, 0.0128731, 1.1237, 0.999978, 0.000446316, - 0.000169093, 1.13253, 0.888362, - 6.27064e-06, 0.312578, 1.78215e-05, 0.889988, - 0.000157791, 0.313148, 0.000448451, 0.889825, - 0.000631076, 0.313092, 0.00179356, 0.88984, - 0.00141994, 0.313097, 0.00403554, 0.889828, - 0.0025243, 0.313092, 0.00717429, 0.889831, - 0.00394421, 0.313093, 0.0112099, 0.889831, - 0.00567962, 0.313093, 0.0161425, 0.889844, - 0.00773051, 0.313096, 0.0219724, 0.889858, - 0.0100968, 0.3131, 0.0286999, 0.889882, - 0.0127786, 0.313106, 0.0363256, 0.889918, - 0.0157757, 0.313116, 0.0448509, 0.889967, - 0.0190878, 0.313129, 0.0542758, 0.89003, - 0.022715, 0.313145, 0.0646032, 0.890108, - 0.0266566, 0.313165, 0.0758339, 0.890218, - 0.0309131, 0.313193, 0.0879729, 0.890351, - 0.0354819, 0.313226, 0.101019, 0.89051, - 0.0403613, 0.313263, 0.114979, 0.890672, - 0.0455385, 0.313294, 0.129848, 0.890882, - 0.0509444, 0.313333, 0.145616, 0.891189, - 0.0559657, 0.313324, 0.162122, 0.891457, - 0.0613123, 0.313281, 0.179524, 0.891856, - 0.0671488, 0.313281, 0.197855, 0.892312, - 0.0732732, 0.313268, 0.216991, 0.892819, - 0.0797865, 0.313263, 0.236924, 0.893369, - 0.0865269, 0.313247, 0.257433, 0.894045, - 0.0931592, 0.313205, 0.278215, 0.894884, - 0.100532, 0.313276, 0.299467, 0.895832, - 0.107716, 0.313205, 0.322276, 0.897043, - 0.114099, 0.312873, 0.34642, 0.898515, - 0.119941, 0.312331, 0.371187, 0.900191, - 0.126044, 0.311731, 0.396656, 0.90188, - 0.131808, 0.310859, 0.422488, 0.904359, - 0.137289, 0.309857, 0.448744, 0.906923, - 0.142991, 0.308714, 0.475239, 0.910634, - 0.148253, 0.307465, 0.501983, 0.914502, - 0.153332, 0.305774, 0.529254, 0.919046, - 0.156646, 0.303156, 0.557709, 0.923194, - 0.159612, 0.299928, 0.586267, 0.928858, - 0.162027, 0.296245, 0.614925, 0.934464, - 0.164203, 0.291832, 0.643187, 0.939824, - 0.165602, 0.286565, 0.671601, 0.944582, - 0.165383, 0.280073, 0.700213, 0.949257, - 0.164439, 0.272891, 0.728432, 0.954389, - 0.162953, 0.264771, 0.756082, 0.958595, - 0.161007, 0.255927, 0.78369, 0.962138, - 0.157243, 0.245769, 0.810769, 0.966979, - 0.152872, 0.235127, 0.836999, 0.969566, - 0.148209, 0.22347, 0.862684, 0.972372, - 0.142211, 0.211147, 0.887847, 0.975916, - 0.135458, 0.198606, 0.911843, 0.978026, - 0.128398, 0.185498, 0.934795, 0.979686, - 0.120313, 0.17171, 0.956787, 0.980748, - 0.11166, 0.158159, 0.978046, 0.981622, - 0.103035, 0.144399, 0.997693, 0.982356, - 0.0930328, 0.13001, 1.01642, 0.983308, - 0.0834627, 0.115778, 1.03366, 0.985037, - 0.0732249, 0.101327, 1.05014, 0.986493, - 0.0628145, 0.086554, 1.06507, 0.988484, - 0.0526556, 0.0720413, 1.07907, 0.991051, - 0.0415744, 0.0571151, 1.09189, 0.993523, - 0.0314275, 0.0426643, 1.10369, 0.99628, - 0.0203603, 0.0279325, 1.11423, 0.998344, - 0.0102446, 0.0138182, 1.12421, 0.999997, 0.00042612, - 0.000193628, 1.1333, 0.871555, - 6.60007e-06, 0.329176, 1.74749e-05, 0.875255, - 0.000166579, 0.330571, 0.000441051, 0.875644, - 0.000666394, 0.330718, 0.00176441, 0.875159, - 0.00149903, 0.330536, 0.00396899, 0.87516, - 0.00266493, 0.330536, 0.007056, 0.875158, - 0.00416393, 0.330535, 0.0110251, 0.87516, - 0.00599598, 0.330535, 0.0158764, 0.875163, - 0.00816108, 0.330536, 0.0216101, 0.875174, - 0.0106591, 0.330538, 0.0282266, 0.875199, - 0.0134899, 0.330545, 0.0357266, 0.875257, - 0.0166538, 0.330563, 0.0441117, 0.875304, - 0.0201501, 0.330575, 0.0533821, 0.875373, - 0.0239785, 0.330595, 0.0635395, 0.875464, - 0.0281389, 0.330619, 0.0745872, 0.875565, - 0.0326301, 0.330645, 0.0865255, 0.875691, - 0.0374516, 0.330676, 0.0993599, 0.875897, - 0.0425993, 0.330733, 0.113093, 0.876091, - 0.0480576, 0.330776, 0.127722, 0.876353, - 0.0537216, 0.330826, 0.143227, 0.876649, - 0.0589807, 0.330809, 0.159462, 0.877034, - 0.0647865, 0.330819, 0.176642, 0.877443, - 0.0709789, 0.330817, 0.194702, 0.877956, - 0.0774782, 0.330832, 0.213577, 0.878499, - 0.0843175, 0.330822, 0.233246, 0.879144, - 0.0912714, 0.330804, 0.253512, 0.879982, - 0.0980824, 0.330766, 0.274137, 0.88097, - 0.105823, 0.330864, 0.295209, 0.882051, - 0.113671, 0.330896, 0.317226, 0.883397, - 0.120303, 0.330545, 0.341068, 0.884987, - 0.12667, 0.330068, 0.365613, 0.886789, - 0.133118, 0.329418, 0.390807, 0.889311, - 0.139024, 0.328683, 0.416494, 0.891995, - 0.144971, 0.327729, 0.442618, 0.895106, - 0.150747, 0.326521, 0.469131, 0.899527, - 0.156283, 0.325229, 0.495921, 0.90504, - 0.161707, 0.32378, 0.523162, 0.909875, - 0.165661, 0.32122, 0.55092, 0.91561, - 0.168755, 0.317942, 0.579928, 0.921225, - 0.171193, 0.313983, 0.608539, 0.927308, - 0.17319, 0.309636, 0.636854, 0.933077, - 0.174819, 0.304262, 0.66523, 0.938766, - 0.175002, 0.297563, 0.693609, 0.943667, - 0.173946, 0.289613, 0.722157, 0.949033, - 0.172221, 0.281227, 0.750021, 0.953765, - 0.169869, 0.271545, 0.777466, 0.95804, - 0.166578, 0.261034, 0.804853, 0.962302, - 0.161761, 0.249434, 0.831569, 0.966544, - 0.156636, 0.237484, 0.857779, 0.969372, - 0.150784, 0.224395, 0.883051, 0.972486, - 0.143672, 0.210786, 0.907864, 0.975853, - 0.135772, 0.196556, 0.931223, 0.977975, - 0.127942, 0.182307, 0.954061, 0.979122, - 0.118347, 0.167607, 0.97531, 0.980719, - 0.109112, 0.152739, 0.995666, 0.981223, - 0.0991789, 0.137932, 1.01475, 0.98216, - 0.0883553, 0.122692, 1.03253, 0.983379, - 0.0780825, 0.107493, 1.04917, 0.985434, - 0.0665646, 0.0917791, 1.06464, 0.987332, - 0.0557714, 0.0764949, 1.07896, 0.990004, - 0.0442805, 0.060721, 1.09199, 0.992975, - 0.0331676, 0.0452284, 1.10393, 0.995811, - 0.0219547, 0.0297934, 1.11476, 0.9982, - 0.0107613, 0.0146415, 1.12484, 1.00002, 0.000248678, - 0.00014555, 1.13413, 0.859519, - 6.93595e-06, 0.347264, 1.71673e-05, 0.859843, - 0.00017503, 0.347394, 0.000433219, 0.859656, - 0.000700076, 0.347319, 0.00173277, 0.859671, - 0.00157517, 0.347325, 0.00389875, 0.859669, - 0.00280028, 0.347324, 0.00693112, 0.85967, - 0.0043754, 0.347324, 0.01083, 0.859665, - 0.00630049, 0.347321, 0.0155954, 0.859685, - 0.0085755, 0.347328, 0.0212278, 0.859694, - 0.0112003, 0.347329, 0.0277273, 0.859718, - 0.0141747, 0.347336, 0.0350946, 0.85976, - 0.0174988, 0.347348, 0.0433314, 0.85982, - 0.0211722, 0.347366, 0.0524384, 0.859892, - 0.0251941, 0.347387, 0.0624168, 0.860006, - 0.0295649, 0.347422, 0.0732708, 0.860122, - 0.0342825, 0.347453, 0.0849999, 0.860282, - 0.0393462, 0.347499, 0.0976102, 0.860482, - 0.0447513, 0.347554, 0.111104, 0.860719, - 0.0504775, 0.347614, 0.125479, 0.860998, - 0.0563577, 0.347666, 0.140703, 0.861322, - 0.0619473, 0.347662, 0.156681, 0.861724, - 0.0681277, 0.347684, 0.173597, 0.862198, - 0.0746567, 0.347709, 0.191371, 0.862733, - 0.0815234, 0.347727, 0.209976, 0.863371, - 0.0886643, 0.347744, 0.229351, 0.86414, - 0.0957908, 0.347734, 0.24934, 0.865138, - 0.102912, 0.34772, 0.269797, 0.866182, - 0.110924, 0.3478, 0.290654, 0.867436, - 0.119223, 0.347911, 0.312074, 0.869087, - 0.126197, 0.347649, 0.335438, 0.870859, - 0.133145, 0.347222, 0.359732, 0.872997, - 0.139869, 0.346645, 0.38467, 0.875939, - 0.146089, 0.345935, 0.41019, 0.879012, - 0.152334, 0.345012, 0.436218, 0.883353, - 0.15821, 0.343924, 0.462641, 0.888362, - 0.164097, 0.342636, 0.489449, 0.895026, - 0.169528, 0.341351, 0.516629, 0.900753, - 0.174408, 0.339115, 0.544109, 0.906814, - 0.17751, 0.335809, 0.572857, 0.912855, - 0.180101, 0.331597, 0.601554, 0.919438, - 0.182116, 0.32698, 0.630198, 0.925962, - 0.183494, 0.321449, 0.658404, 0.931734, - 0.184159, 0.314595, 0.686625, 0.93762, - 0.18304, 0.306462, 0.71531, 0.943858, - 0.181323, 0.297514, 0.744272, 0.948662, - 0.178683, 0.287447, 0.771462, 0.953299, - 0.175379, 0.276166, 0.798593, 0.957346, - 0.170395, 0.263758, 0.8256, 0.962565, - 0.165042, 0.251019, 0.852575, 0.966075, - 0.158655, 0.237011, 0.878316, 0.969048, - 0.151707, 0.222518, 0.90329, 0.972423, - 0.143271, 0.207848, 0.927745, 0.975833, - 0.134824, 0.192463, 0.950859, 0.977629, - 0.125444, 0.1768, 0.972947, 0.978995, - 0.114949, 0.161033, 0.993263, 0.980533, - 0.104936, 0.145523, 1.01337, 0.980745, - 0.0935577, 0.129799, 1.03128, 0.981814, - 0.0822956, 0.113486, 1.04825, 0.983943, - 0.0710082, 0.0972925, 1.06405, 0.986141, - 0.0587931, 0.0808138, 1.0785, 0.988878, - 0.0472755, 0.0644915, 1.09204, 0.992132, - 0.0349128, 0.0478128, 1.10413, 0.9953, - 0.0232407, 0.031621, 1.11527, 0.998117, - 0.0112713, 0.0154935, 1.12551, 1.00003, 0.000339743, - 0.000195763, 1.13504, 0.845441, - 7.29126e-06, 0.364305, 1.69208e-05, 0.843588, - 0.000183164, 0.363506, 0.000425067, 0.843412, - 0.00073253, 0.36343, 0.00169999, 0.843401, - 0.00164818, 0.363426, 0.00382495, 0.843399, - 0.00293008, 0.363425, 0.00679993, 0.843401, - 0.00457822, 0.363425, 0.010625, 0.843394, - 0.00659249, 0.363421, 0.0153002, 0.843398, - 0.00897282, 0.363421, 0.0208258, 0.843415, - 0.0117191, 0.363426, 0.0272024, 0.843438, - 0.0148312, 0.363432, 0.0344305, 0.843483, - 0.018309, 0.363447, 0.0425116, 0.84356, - 0.0221521, 0.363472, 0.0514471, 0.843646, - 0.0263597, 0.363499, 0.061238, 0.843743, - 0.0309315, 0.363527, 0.0718873, 0.84388, - 0.0358658, 0.363569, 0.0833969, 0.844079, - 0.0411624, 0.363631, 0.0957742, 0.844279, - 0.0468128, 0.363688, 0.109015, 0.844549, - 0.0527923, 0.363761, 0.123124, 0.844858, - 0.0588204, 0.363817, 0.138044, 0.84522, - 0.0647573, 0.36383, 0.153755, 0.845669, - 0.0713181, 0.363879, 0.170394, 0.846155, - 0.0781697, 0.363908, 0.187861, 0.846789, - 0.0853913, 0.363969, 0.206176, 0.847502, - 0.0928086, 0.363999, 0.225244, 0.8484, - 0.10005, 0.363997, 0.244926, 0.849461, - 0.107615, 0.364008, 0.265188, 0.850562, - 0.115814, 0.364055, 0.28587, 0.851962, - 0.124334, 0.364179, 0.306926, 0.854326, - 0.131995, 0.364233, 0.329605, 0.856295, - 0.139338, 0.363856, 0.35359, 0.858857, - 0.146346, 0.363347, 0.37831, 0.862428, - 0.152994, 0.362807, 0.403722, 0.866203, - 0.159463, 0.361963, 0.429537, 0.871629, - 0.165623, 0.36112, 0.456, 0.877365, - 0.171649, 0.359917, 0.482773, 0.883744, - 0.177151, 0.35848, 0.509705, 0.890693, - 0.182381, 0.356523, 0.537215, 0.897278, - 0.186076, 0.3533, 0.565493, 0.903958, - 0.188602, 0.349095, 0.594293, 0.910908, - 0.190755, 0.344215, 0.623165, 0.918117, - 0.192063, 0.338606, 0.651573, 0.924644, - 0.192758, 0.331544, 0.679869, 0.931054, - 0.192238, 0.323163, 0.708668, 0.937303, - 0.190035, 0.313529, 0.737201, 0.943387, - 0.187162, 0.303152, 0.764977, 0.948494, - 0.183876, 0.29146, 0.792683, 0.952546, - 0.178901, 0.277917, 0.819228, 0.958077, - 0.173173, 0.264753, 0.846559, 0.962462, - 0.16645, 0.25002, 0.872962, 0.966569, - 0.159452, 0.234873, 0.898729, 0.969108, - 0.15074, 0.218752, 0.923126, 0.973072, - 0.141523, 0.202673, 0.947278, 0.975452, - 0.132075, 0.186326, 0.969938, 0.977784, - 0.121257, 0.169396, 0.991325, 0.97899, - 0.110182, 0.153044, 1.01123, 0.979777, - 0.0989634, 0.136485, 1.0299, 0.980865, - 0.0865894, 0.119343, 1.04727, 0.982432, - 0.0746115, 0.102452, 1.06341, 0.984935, - 0.0621822, 0.0852423, 1.07834, 0.987776, - 0.0495694, 0.0678546, 1.092, 0.99103, - 0.0372386, 0.0506917, 1.1043, 0.99474, - 0.0244353, 0.0333316, 1.11576, 0.997768, - 0.0121448, 0.0164348, 1.12617, 1.00003, 0.00031774, - 0.000169504, 1.13598, 0.825551, - 7.56799e-06, 0.378425, 1.65099e-05, 0.82664, - 0.000190922, 0.378923, 0.000416504, 0.826323, - 0.000763495, 0.378779, 0.0016656, 0.826359, - 0.00171789, 0.378795, 0.00374768, 0.82636, - 0.00305402, 0.378795, 0.00666259, 0.826368, - 0.00477185, 0.378798, 0.0104104, 0.826364, - 0.00687131, 0.378795, 0.0149912, 0.826368, - 0.00935232, 0.378795, 0.0204054, 0.826376, - 0.0122146, 0.378797, 0.0266532, 0.826399, - 0.0154581, 0.378803, 0.0337355, 0.82646, - 0.0190825, 0.378824, 0.0416537, 0.826525, - 0.0230873, 0.378846, 0.0504091, 0.826614, - 0.0274719, 0.378876, 0.0600032, 0.82674, - 0.0322355, 0.378917, 0.0704393, 0.826888, - 0.0373766, 0.378964, 0.0817195, 0.827078, - 0.0428936, 0.379024, 0.0938492, 0.827318, - 0.0487778, 0.379099, 0.106828, 0.82764, - 0.0549935, 0.379199, 0.120659, 0.827926, - 0.0611058, 0.379227, 0.13526, 0.828325, - 0.0675054, 0.379275, 0.150713, 0.828801, - 0.0743455, 0.379332, 0.167034, 0.8294, - 0.0815523, 0.379415, 0.184209, 0.830094, - 0.0890779, 0.379495, 0.202203, 0.8309, - 0.096736, 0.379555, 0.220945, 0.831943, - 0.104135, 0.379577, 0.240306, 0.833037, - 0.112106, 0.379604, 0.260317, 0.834278, - 0.120554, 0.379668, 0.2808, 0.836192, - 0.129128, 0.3799, 0.301654, 0.838671, - 0.137541, 0.380109, 0.323502, 0.840939, - 0.14523, 0.379809, 0.347176, 0.844575, - 0.15248, 0.379593, 0.371706, 0.848379, - 0.159607, 0.37909, 0.39688, 0.853616, - 0.166267, 0.378617, 0.422702, 0.858921, - 0.172698, 0.377746, 0.448919, 0.865324, - 0.178823, 0.376749, 0.475661, 0.872207, - 0.184542, 0.375363, 0.502599, 0.880018, - 0.189836, 0.373657, 0.529914, 0.88694, - 0.194294, 0.370673, 0.557683, 0.894779, - 0.197022, 0.36662, 0.586848, 0.902242, - 0.199108, 0.36138, 0.615831, 0.909914, - 0.200398, 0.355434, 0.644478, 0.917088, - 0.20094, 0.348173, 0.672905, 0.923888, - 0.200671, 0.339482, 0.701327, 0.930495, - 0.198773, 0.32956, 0.730101, 0.937247, - 0.195394, 0.318363, 0.758383, 0.943108, - 0.191956, 0.306323, 0.786539, 0.948296, - 0.187227, 0.292576, 0.813637, 0.953472, - 0.181165, 0.278234, 0.840793, 0.958485, - 0.174119, 0.263054, 0.867712, 0.962714, - 0.166564, 0.246756, 0.893635, 0.966185, - 0.158181, 0.229945, 0.919028, 0.970146, - 0.148275, 0.212633, 0.943413, 0.973491, - 0.138157, 0.195229, 0.966627, 0.975741, - 0.127574, 0.178048, 0.988817, 0.977238, - 0.11554, 0.160312, 1.00924, 0.978411, - 0.10364, 0.142857, 1.02845, 0.979811, - 0.0913122, 0.125317, 1.04648, 0.98116, - 0.0782558, 0.107627, 1.06284, 0.983543, - 0.0655957, 0.0895862, 1.07798, 0.986789, - 0.0520411, 0.0713756, 1.092, 0.990292, - 0.0389727, 0.053228, 1.10484, 0.994187, - 0.025808, 0.0351945, 1.11642, 0.997499, - 0.0126071, 0.0173198, 1.12703, 0.999999, 0.000275604, - 0.000148602, 1.13674, 0.81075, - 7.8735e-06, 0.394456, 1.61829e-05, 0.808692, - 0.000198293, 0.393453, 0.000407564, 0.80846, - 0.000792877, 0.39334, 0.00162965, 0.808595, - 0.00178416, 0.393407, 0.00366711, 0.808597, - 0.00317182, 0.393408, 0.00651934, 0.808598, - 0.00495589, 0.393408, 0.0101866, 0.808591, - 0.00713627, 0.393403, 0.0146689, 0.808592, - 0.00971285, 0.393402, 0.0199667, 0.80861, - 0.0126855, 0.393407, 0.0260803, 0.808633, - 0.0160538, 0.393413, 0.0330107, 0.80868, - 0.0198175, 0.393429, 0.0407589, 0.808748, - 0.0239758, 0.393453, 0.0493264, 0.808854, - 0.0285286, 0.39349, 0.0587161, 0.808992, - 0.0334748, 0.39354, 0.0689304, 0.809141, - 0.0388116, 0.393588, 0.0799707, 0.809352, - 0.0445375, 0.39366, 0.0918432, 0.809608, - 0.0506427, 0.393742, 0.104549, 0.809915, - 0.0570708, 0.393834, 0.118085, 0.810253, - 0.0633526, 0.393885, 0.132377, 0.810687, - 0.0700966, 0.393953, 0.147537, 0.811233, - 0.0772274, 0.394047, 0.163543, 0.811865, - 0.0847629, 0.394148, 0.180394, 0.812648, - 0.0925663, 0.394265, 0.198051, 0.813583, - 0.100416, 0.394363, 0.216443, 0.814683, - 0.108119, 0.394402, 0.235502, 0.815948, - 0.11644, 0.394489, 0.255242, 0.817278, - 0.125036, 0.394542, 0.275441, 0.819605, - 0.133655, 0.39486, 0.296094, 0.822256, - 0.142682, 0.395248, 0.317309, 0.825349, - 0.150756, 0.395241, 0.340516, 0.829605, - 0.158392, 0.395285, 0.364819, 0.83391, - 0.165801, 0.394922, 0.389736, 0.839808, - 0.172677, 0.394691, 0.415409, 0.845708, - 0.179448, 0.394006, 0.441546, 0.853025, - 0.185746, 0.393279, 0.46832, 0.859666, - 0.191684, 0.391655, 0.495302, 0.86789, - 0.197146, 0.390068, 0.52262, 0.875845, - 0.201904, 0.38727, 0.550336, 0.882634, - 0.205023, 0.382688, 0.578825, 0.891076, - 0.207098, 0.377543, 0.608103, 0.900589, - 0.208474, 0.371752, 0.63723, 0.90791, - 0.209068, 0.364016, 0.665769, 0.915971, - 0.208655, 0.355593, 0.694428, 0.923455, - 0.20729, 0.345439, 0.723224, 0.931514, - 0.203821, 0.334099, 0.751925, 0.937885, - 0.19986, 0.321069, 0.780249, 0.943136, - 0.194993, 0.306571, 0.8077, 0.948818, - 0.189132, 0.291556, 0.83497, 0.954433, - 0.181617, 0.275745, 0.86188, 0.959078, - 0.173595, 0.258695, 0.888562, 0.962705, - 0.164855, 0.240825, 0.914008, 0.966753, - 0.155129, 0.22268, 0.939145, 0.970704, - 0.144241, 0.204542, 0.963393, 0.973367, - 0.133188, 0.185927, 0.985983, 0.975984, - 0.121146, 0.167743, 1.00704, 0.976994, - 0.108366, 0.149218, 1.02715, 0.978485, - 0.0956746, 0.13131, 1.0455, 0.980074, - 0.0820733, 0.112513, 1.06221, 0.98225, - 0.0684061, 0.0938323, 1.07782, 0.98553, - 0.0549503, 0.0749508, 1.09199, 0.989529, - 0.0407857, 0.055848, 1.10508, 0.993536, - 0.0271978, 0.0368581, 1.11684, 0.997247, - 0.0132716, 0.0181845, 1.12789, 1, 0.000431817, - 0.000198809, 1.13792, 0.785886, - 8.12608e-06, 0.405036, 1.57669e-05, 0.790388, - 0.000205278, 0.407355, 0.000398297, 0.790145, - 0.000820824, 0.407231, 0.00159263, 0.790135, - 0.00184681, 0.407226, 0.00358336, 0.790119, - 0.00328316, 0.407218, 0.00637039, 0.790126, - 0.00512988, 0.40722, 0.0099539, 0.79013, - 0.00738684, 0.407221, 0.0143339, 0.790135, - 0.0100538, 0.407221, 0.0195107, 0.790134, - 0.0131306, 0.407217, 0.0254848, 0.79016, - 0.0166169, 0.407224, 0.0322572, 0.790197, - 0.020512, 0.407236, 0.0398284, 0.790273, - 0.0248157, 0.407263, 0.0482014, 0.790381, - 0.029527, 0.407304, 0.0573777, 0.790521, - 0.0346446, 0.407355, 0.0673602, 0.790704, - 0.0401665, 0.40742, 0.0781522, 0.790925, - 0.0460896, 0.407499, 0.0897582, 0.791195, - 0.0524017, 0.407589, 0.10218, 0.791522, - 0.0590121, 0.407691, 0.11541, 0.791878, - 0.0654876, 0.407748, 0.12939, 0.792361, - 0.0725207, 0.407849, 0.144237, 0.792942, - 0.0799844, 0.407963, 0.159924, 0.79362, - 0.0877896, 0.408087, 0.176425, 0.794529, - 0.0958451, 0.408259, 0.193733, 0.795521, - 0.103827, 0.408362, 0.211756, 0.796778, - 0.111937, 0.408482, 0.230524, 0.798027, - 0.120521, 0.408547, 0.249967, 0.799813, - 0.129242, 0.408721, 0.269926, 0.802387, - 0.138048, 0.409148, 0.290338, 0.805279, - 0.147301, 0.409641, 0.311193, 0.809251, - 0.155895, 0.410154, 0.333611, 0.813733, - 0.163942, 0.410297, 0.357615, 0.819081, - 0.171666, 0.410373, 0.382339, 0.825427, - 0.178905, 0.410348, 0.407828, 0.83172, - 0.185812, 0.409486, 0.434034, 0.83877, - 0.192318, 0.408776, 0.460493, 0.845817, - 0.198249, 0.407176, 0.487346, 0.854664, - 0.204034, 0.405719, 0.514832, 0.863495, - 0.208908, 0.403282, 0.542401, 0.871883, - 0.212765, 0.399293, 0.570683, 0.88065, - 0.214911, 0.393803, 0.599947, 0.89004, - 0.216214, 0.387536, 0.62932, 0.898476, - 0.216745, 0.379846, 0.658319, 0.906738, - 0.216387, 0.370625, 0.687138, 0.914844, - 0.215053, 0.360139, 0.71601, 0.923877, - 0.212007, 0.348849, 0.745124, 0.931925, - 0.207481, 0.335639, 0.773366, 0.938054, - 0.202418, 0.320798, 0.801636, 0.943895, - 0.196507, 0.304772, 0.829055, 0.949468, - 0.189009, 0.288033, 0.856097, 0.955152, - 0.180539, 0.270532, 0.88301, 0.959403, - 0.171437, 0.251639, 0.909296, 0.963309, - 0.161661, 0.232563, 0.934868, 0.967399, - 0.150425, 0.213231, 0.959662, 0.972009, - 0.138659, 0.194247, 0.98302, 0.97433, - 0.126595, 0.174718, 1.00517, 0.975823, - 0.113205, 0.155518, 1.02566, 0.976371, - 0.0996096, 0.136709, 1.04418, 0.978705, - 0.0860754, 0.117571, 1.06146, 0.981477, - 0.0714438, 0.0980046, 1.07777, 0.984263, - 0.0572304, 0.0782181, 1.09214, 0.988423, - 0.0428875, 0.0584052, 1.10553, 0.993, - 0.0282442, 0.038522, 1.11758, 0.99704, - 0.0140183, 0.0190148, 1.12864, 0.999913, 0.000369494, - 0.000145203, 1.13901, 0.777662, - 8.4153e-06, 0.423844, 1.54403e-05, 0.770458, - 0.000211714, 0.419915, 0.00038845, 0.770716, - 0.000846888, 0.420055, 0.00155386, 0.770982, - 0.00190567, 0.420202, 0.00349653, 0.770981, - 0.00338782, 0.420201, 0.00621606, 0.77098, - 0.00529338, 0.4202, 0.00971274, 0.770983, - 0.00762223, 0.4202, 0.0139867, 0.770985, - 0.0103741, 0.420198, 0.0190381, 0.770996, - 0.0135489, 0.4202, 0.0248677, 0.771029, - 0.0171461, 0.420212, 0.0314764, 0.771052, - 0.0211647, 0.420215, 0.0388648, 0.771131, - 0.0256048, 0.420245, 0.047036, 0.771235, - 0.0304647, 0.420284, 0.0559911, 0.771383, - 0.0357436, 0.420341, 0.0657346, 0.771591, - 0.0414392, 0.420423, 0.0762694, 0.771819, - 0.0475462, 0.420506, 0.0875984, 0.772123, - 0.0540506, 0.420617, 0.099727, 0.772464, - 0.060797, 0.42072, 0.112637, 0.772855, - 0.0675393, 0.420799, 0.126313, 0.773317, - 0.0748323, 0.420893, 0.140824, 0.773981, - 0.0825681, 0.421058, 0.15617, 0.774746, - 0.0906307, 0.421226, 0.172322, 0.77566, - 0.0988982, 0.421397, 0.189253, 0.776837, - 0.106994, 0.421569, 0.206912, 0.778097, - 0.115528, 0.421704, 0.225359, 0.779588, - 0.124317, 0.421849, 0.24447, 0.781574, - 0.133139, 0.422097, 0.264156, 0.784451, - 0.142179, 0.422615, 0.284318, 0.787682, - 0.15165, 0.423269, 0.304902, 0.792433, - 0.160771, 0.424396, 0.3265, 0.797359, - 0.169166, 0.424772, 0.35014, 0.803986, - 0.177149, 0.425475, 0.374768, 0.809504, - 0.184745, 0.424996, 0.399928, 0.815885, - 0.19173, 0.424247, 0.425796, 0.823513, - 0.198525, 0.423515, 0.452287, 0.832549, - 0.204709, 0.422787, 0.479321, 0.841653, - 0.210447, 0.421187, 0.506718, 0.850401, - 0.215501, 0.418519, 0.53432, 0.859854, - 0.219752, 0.414715, 0.56242, 0.869364, - 0.222305, 0.409462, 0.591558, 0.878837, - 0.223744, 0.402926, 0.621074, 0.888636, - 0.224065, 0.395043, 0.650538, 0.898132, - 0.223742, 0.38564, 0.679538, 0.907181, - 0.222308, 0.375378, 0.708674, 0.915621, - 0.219837, 0.363212, 0.737714, 0.9239, - 0.215233, 0.349313, 0.767014, 0.931644, - 0.209592, 0.334162, 0.795133, 0.938887, - 0.203644, 0.317943, 0.823228, 0.945282, - 0.196349, 0.300581, 0.850822, 0.950758, - 0.18742, 0.282195, 0.877594, 0.956146, - 0.177879, 0.262481, 0.904564, 0.960355, - 0.167643, 0.242487, 0.930741, 0.965256, - 0.156671, 0.222668, 0.955868, 0.968029, - 0.144123, 0.201907, 0.979869, 0.97251, - 0.131305, 0.18202, 1.00291, 0.974925, - 0.118335, 0.161909, 1.02392, 0.975402, - 0.103714, 0.142129, 1.0433, 0.976987, - 0.089415, 0.122447, 1.06089, 0.979677, - 0.0748858, 0.102248, 1.07713, 0.983184, - 0.0596086, 0.0814851, 1.09218, 0.987466, - 0.0447671, 0.0609484, 1.10585, 0.992348, - 0.0295217, 0.0401835, 1.11829, 0.996674, - 0.0143917, 0.0198163, 1.12966, 1.00003, 0.000321364, - 0.000149983, 1.1402, 0.757901, - 8.69074e-06, 0.436176, 1.51011e-05, 0.751195, - 0.000217848, 0.432317, 0.000378533, 0.751178, - 0.000871373, 0.432307, 0.0015141, 0.751195, - 0.00196061, 0.432317, 0.0034068, 0.751198, - 0.00348552, 0.432318, 0.00605659, 0.751195, - 0.00544599, 0.432315, 0.00946353, 0.751207, - 0.00784203, 0.43232, 0.013628, 0.751213, - 0.0106732, 0.43232, 0.0185499, 0.751221, - 0.0139393, 0.432319, 0.0242302, 0.751244, - 0.0176398, 0.432325, 0.0306694, 0.7513, - 0.0217743, 0.432348, 0.0378698, 0.751358, - 0.0263412, 0.432367, 0.0458321, 0.751458, - 0.0313396, 0.432404, 0.0545587, 0.751608, - 0.0367682, 0.432464, 0.0640543, 0.7518, - 0.0426246, 0.43254, 0.0743222, 0.752065, - 0.0489031, 0.432645, 0.0853668, 0.752376, - 0.0555828, 0.432762, 0.0971911, 0.752715, - 0.0623861, 0.432859, 0.109768, 0.753137, - 0.069415, 0.432958, 0.123126, 0.753676, - 0.0770039, 0.433099, 0.137308, 0.754345, - 0.084971, 0.433272, 0.15229, 0.755235, - 0.0932681, 0.433504, 0.168075, 0.756186, - 0.10171, 0.433693, 0.184625, 0.757363, - 0.110019, 0.433857, 0.201897, 0.75884, - 0.11887, 0.434102, 0.220014, 0.760467, - 0.127881, 0.434306, 0.238778, 0.762969, - 0.136766, 0.434751, 0.258172, 0.765823, - 0.14612, 0.43529, 0.278062, 0.769676, - 0.15566, 0.436236, 0.298437, 0.774909, - 0.165177, 0.437754, 0.319532, 0.77994, - 0.17402, 0.438343, 0.342505, 0.785757, - 0.182201, 0.438609, 0.366693, 0.792487, - 0.190104, 0.438762, 0.391668, 0.80038, - 0.197438, 0.438795, 0.417494, 0.808494, - 0.204365, 0.438226, 0.443933, 0.817695, - 0.210714, 0.437283, 0.470929, 0.828111, - 0.216651, 0.436087, 0.498569, 0.837901, - 0.221804, 0.433717, 0.526165, 0.847813, - 0.226318, 0.430133, 0.554155, 0.858314, - 0.229297, 0.425213, 0.582822, 0.868891, - 0.230999, 0.418576, 0.612847, 0.878941, - 0.231155, 0.410405, 0.642445, 0.888809, - 0.230935, 0.400544, 0.672024, 0.898089, - 0.229343, 0.389613, 0.701366, 0.908081, - 0.226886, 0.377197, 0.730763, 0.916819, - 0.222676, 0.363397, 0.759642, 0.924968, - 0.216835, 0.347437, 0.788775, 0.932906, - 0.210245, 0.32995, 0.817135, 0.940025, - 0.202992, 0.312262, 0.844912, 0.946101, - 0.19436, 0.293313, 0.872164, 0.952835, - 0.184125, 0.273638, 0.899443, 0.957347, - 0.173657, 0.252385, 0.926389, 0.961434, - 0.162204, 0.231038, 0.951947, 0.965522, - 0.14979, 0.209834, 0.976751, 0.969412, - 0.136307, 0.188821, 1.00022, 0.973902, - 0.122527, 0.168013, 1.02229, 0.974045, - 0.108213, 0.147634, 1.04199, 0.975775, - 0.0927397, 0.12705, 1.06019, 0.978383, - 0.0778212, 0.106309, 1.07711, 0.98211, - 0.0621216, 0.0849279, 1.09245, 0.986517, - 0.0463847, 0.0633519, 1.10651, 0.991696, - 0.0309353, 0.0419698, 1.11903, 0.996349, - 0.0150914, 0.0206272, 1.13073, 1.00003, 0.000442449, - 0.000231396, 1.14146, 0.727498, - 8.85074e-06, 0.441528, 1.45832e-05, 0.730897, - 0.000223525, 0.443589, 0.000368298, 0.730796, - 0.000893996, 0.443528, 0.00147303, 0.730805, - 0.00201149, 0.443533, 0.00331433, 0.730814, - 0.00357596, 0.443538, 0.00589222, 0.730815, - 0.00558734, 0.443538, 0.00920678, 0.730822, - 0.00804544, 0.44354, 0.0132582, 0.730836, - 0.0109501, 0.443545, 0.0180468, 0.730848, - 0.0143008, 0.443546, 0.0235732, 0.730871, - 0.0180969, 0.443552, 0.0298382, 0.730915, - 0.022338, 0.443567, 0.0368438, 0.730982, - 0.0270225, 0.443591, 0.044591, 0.731076, - 0.0321491, 0.443627, 0.0530831, 0.731245, - 0.0377166, 0.443699, 0.0623243, 0.73144, - 0.0437216, 0.443777, 0.0723181, 0.7317, - 0.0501576, 0.443881, 0.0830691, 0.732034, - 0.0569942, 0.444014, 0.0945809, 0.732388, - 0.0638756, 0.444113, 0.106825, 0.732853, - 0.071203, 0.444247, 0.119859, 0.733473, - 0.0790076, 0.444442, 0.13369, 0.734195, - 0.0871937, 0.444645, 0.148304, 0.735069, - 0.095696, 0.444877, 0.163702, 0.736169, - 0.10426, 0.445133, 0.179861, 0.73747, - 0.112853, 0.44537, 0.196778, 0.738991, - 0.12199, 0.445651, 0.214496, 0.740865, - 0.131153, 0.445958, 0.232913, 0.743637, - 0.140245, 0.446548, 0.251977, 0.746797, - 0.149722, 0.447246, 0.271551, 0.751517, - 0.159341, 0.448656, 0.291774, 0.756156, - 0.169106, 0.449866, 0.312455, 0.761519, - 0.178436, 0.450919, 0.334552, 0.768295, - 0.186904, 0.451776, 0.358491, 0.776613, - 0.195117, 0.452832, 0.383446, 0.783966, - 0.202695, 0.45249, 0.408945, 0.793542, - 0.20985, 0.452587, 0.435364, 0.803192, - 0.216403, 0.451852, 0.462336, 0.813892, - 0.22251, 0.450708, 0.48987, 0.824968, - 0.227676, 0.4486, 0.517697, 0.835859, - 0.232443, 0.445156, 0.545975, 0.846825, - 0.235775, 0.440351, 0.574483, 0.858085, - 0.237897, 0.433641, 0.604246, 0.868825, - 0.238074, 0.425354, 0.634101, 0.879638, - 0.237661, 0.415383, 0.664201, 0.889966, - 0.236186, 0.404136, 0.693918, 0.899479, - 0.233599, 0.390917, 0.723481, 0.908769, - 0.229737, 0.376352, 0.75258, 0.917966, - 0.223836, 0.360372, 0.781764, 0.926304, - 0.217067, 0.342551, 0.811139, 0.934626, - 0.209309, 0.324238, 0.839585, 0.941841, - 0.20071, 0.304484, 0.867044, 0.94789, - 0.190602, 0.283607, 0.894579, 0.954196, - 0.179253, 0.262205, 0.921743, 0.958383, - 0.167646, 0.239847, 0.948026, 0.963119, - 0.155073, 0.218078, 0.973296, 0.966941, - 0.141426, 0.195899, 0.998135, 0.970836, - 0.126849, 0.174121, 1.02021, 0.973301, - 0.112296, 0.153052, 1.04085, 0.97448, - 0.0964965, 0.131733, 1.05946, 0.977045, - 0.080489, 0.10997, 1.07693, 0.980751, - 0.064844, 0.0881657, 1.09254, 0.985475, - 0.0481938, 0.0657987, 1.10697, 0.991089, - 0.0319185, 0.0435215, 1.12004, 0.996122, - 0.0158088, 0.0214779, 1.13173, 1.00001, 0.000372455, - 0.000200295, 1.14291, 0.708622, - 9.07597e-06, 0.45304, 1.41962e-05, 0.711162, - 0.000228911, 0.454662, 0.000358052, 0.709812, - 0.000914446, 0.453797, 0.00143034, 0.709865, - 0.00205819, 0.453834, 0.00321935, 0.709864, - 0.00365894, 0.453833, 0.00572331, 0.709855, - 0.00571692, 0.453826, 0.00894278, 0.709862, - 0.00823201, 0.453828, 0.012878, 0.709875, - 0.011204, 0.453832, 0.0175295, 0.709896, - 0.0146323, 0.453839, 0.0228978, 0.709925, - 0.0185163, 0.453847, 0.0289839, 0.709974, - 0.0228551, 0.453866, 0.0357894, 0.710045, - 0.0276473, 0.453892, 0.0433161, 0.710133, - 0.032891, 0.453924, 0.0515665, 0.710292, - 0.0385851, 0.453992, 0.0605458, 0.710485, - 0.0447254, 0.45407, 0.0702574, 0.710769, - 0.0513051, 0.454192, 0.0807077, 0.711106, - 0.0582733, 0.454329, 0.091896, 0.711516, - 0.0652866, 0.45446, 0.103814, 0.712071, - 0.0728426, 0.454653, 0.116508, 0.712676, - 0.0808307, 0.45484, 0.129968, 0.713476, - 0.0892216, 0.455096, 0.144206, 0.714377, - 0.0979047, 0.455346, 0.159212, 0.715579, - 0.106531, 0.455647, 0.174973, 0.716977, - 0.115492, 0.455961, 0.191504, 0.71862, - 0.124821, 0.456315, 0.208835, 0.72084, - 0.134079, 0.4568, 0.226869, 0.723786, - 0.143427, 0.457521, 0.245582, 0.727464, - 0.153061, 0.458475, 0.264957, 0.732771, - 0.162768, 0.460239, 0.284948, 0.736515, - 0.172627, 0.460899, 0.30522, 0.743519, - 0.182487, 0.463225, 0.326717, 0.750041, - 0.191295, 0.464027, 0.350113, 0.758589, - 0.199746, 0.465227, 0.374782, 0.767703, - 0.207584, 0.465877, 0.400226, 0.777484, - 0.214973, 0.465996, 0.426442, 0.788792, - 0.221796, 0.466019, 0.453688, 0.800194, - 0.228038, 0.465083, 0.481246, 0.811234, - 0.233346, 0.462506, 0.509086, 0.822859, - 0.238073, 0.459257, 0.537338, 0.835082, - 0.241764, 0.454863, 0.566108, 0.846332, - 0.244241, 0.448163, 0.595126, 0.858355, - 0.244736, 0.439709, 0.625574, 0.87034, - 0.244278, 0.429837, 0.65617, 0.881027, - 0.24255, 0.418002, 0.686029, 0.891007, - 0.239912, 0.404325, 0.716039, 0.900874, - 0.236133, 0.389222, 0.745518, 0.911072, - 0.230672, 0.373269, 0.775026, 0.920359, - 0.22356, 0.355083, 0.804521, 0.928604, - 0.215591, 0.335533, 0.834045, 0.937175, - 0.206503, 0.315278, 0.861612, 0.942825, - 0.196684, 0.293653, 0.889131, 0.949805, - 0.185116, 0.271503, 0.916853, 0.955535, - 0.172703, 0.248821, 0.943541, 0.959843, - 0.159978, 0.225591, 0.970132, 0.964393, - 0.146375, 0.202719, 0.994709, 0.968008, - 0.131269, 0.179928, 1.0186, 0.971013, - 0.11569, 0.158007, 1.03928, 0.973334, - 0.1003, 0.13624, 1.05887, 0.975775, - 0.0833352, 0.1138, 1.07652, 0.979579, - 0.0668981, 0.0913141, 1.09297, 0.984323, - 0.0500902, 0.0683051, 1.10734, 0.990351, - 0.0332377, 0.0451771, 1.12084, 0.995823, - 0.0161491, 0.0221705, 1.13296, 1.0001, 0.000234083, - 0.000108712, 1.14441, 0.683895, - 9.24677e-06, 0.46015, 1.37429e-05, 0.68833, - 0.000233383, 0.463134, 0.000346865, 0.688368, - 0.000933547, 0.463159, 0.00138748, 0.688367, - 0.00210049, 0.463159, 0.00312187, 0.688369, - 0.00373415, 0.463159, 0.00555004, 0.688377, - 0.00583449, 0.463163, 0.00867216, 0.688386, - 0.00840128, 0.463166, 0.0124884, 0.688398, - 0.0114343, 0.463169, 0.0169993, 0.688418, - 0.0149329, 0.463175, 0.0222054, 0.688453, - 0.0188964, 0.463188, 0.028108, 0.688515, - 0.0233239, 0.463214, 0.0347085, 0.68857, - 0.0282136, 0.463231, 0.0420091, 0.688679, - 0.033564, 0.463276, 0.0500132, 0.688854, - 0.0393733, 0.463356, 0.0587255, 0.689038, - 0.0456354, 0.46343, 0.0681476, 0.689321, - 0.0523433, 0.463553, 0.0782897, 0.689662, - 0.059412, 0.463693, 0.0891501, 0.690188, - 0.0665736, 0.4639, 0.100735, 0.690755, - 0.0743106, 0.464107, 0.113074, 0.691405, - 0.0824722, 0.464329, 0.126161, 0.692198, - 0.0910484, 0.464585, 0.140007, 0.693196, - 0.0998778, 0.464893, 0.154612, 0.69454, - 0.108651, 0.465285, 0.169984, 0.695921, - 0.117855, 0.465596, 0.186106, 0.697749, - 0.12734, 0.466056, 0.203034, 0.700375, - 0.136714, 0.466771, 0.220703, 0.703395, - 0.146386, 0.467579, 0.239062, 0.707904, - 0.156096, 0.469067, 0.258188, 0.711673, - 0.165904, 0.469851, 0.277759, 0.717489, - 0.175812, 0.471815, 0.297935, 0.724051, - 0.185931, 0.47389, 0.318916, 0.731965, - 0.195238, 0.47587, 0.341591, 0.741151, - 0.204021, 0.477523, 0.366062, 0.751416, - 0.212113, 0.478881, 0.391396, 0.761848, - 0.21979, 0.479226, 0.417599, 0.771886, - 0.2267, 0.478495, 0.444401, 0.783998, - 0.232991, 0.477622, 0.472084, 0.796523, - 0.238645, 0.475833, 0.500193, 0.808851, - 0.243396, 0.472568, 0.52865, 0.821191, - 0.247226, 0.467857, 0.557362, 0.834261, - 0.250102, 0.461871, 0.586768, 0.846762, - 0.251056, 0.453543, 0.617085, 0.859867, - 0.250604, 0.443494, 0.647659, 0.871948, - 0.248783, 0.431711, 0.678119, 0.882967, - 0.245855, 0.417911, 0.708399, 0.892826, - 0.242168, 0.401993, 0.738256, 0.90332, - 0.237062, 0.385371, 0.767999, 0.913633, - 0.22997, 0.366837, 0.798191, 0.922774, - 0.221687, 0.346372, 0.827756, 0.931371, - 0.212345, 0.325682, 0.856425, 0.938929, - 0.20206, 0.303665, 0.884299, 0.944821, - 0.190981, 0.280786, 0.912023, 0.951792, - 0.178065, 0.2573, 0.939669, 0.957712, - 0.164634, 0.233448, 0.96655, 0.961912, - 0.150863, 0.209504, 0.992366, 0.966382, - 0.13577, 0.18597, 1.01633, 0.969588, - 0.119593, 0.162905, 1.03843, 0.971777, - 0.103203, 0.14053, 1.05841, 0.97433, - 0.0865888, 0.117909, 1.07632, 0.978686, - 0.0690829, 0.0944101, 1.09326, 0.983281, - 0.0516568, 0.0705671, 1.10796, 0.989562, - 0.034558, 0.0468592, 1.12182, 0.995465, - 0.0167808, 0.0229846, 1.1342, 0.999991, 0.000373016, - 0.000235606, 1.1459, 0.662251, - 9.39016e-06, 0.468575, 1.32714e-05, 0.666634, - 0.000237624, 0.471675, 0.000335842, 0.666411, - 0.000950385, 0.471516, 0.00134321, 0.666399, - 0.00213833, 0.471509, 0.00302221, 0.666386, - 0.0038014, 0.471499, 0.00537283, 0.666405, - 0.00593958, 0.471511, 0.00839533, 0.666406, - 0.00855253, 0.471508, 0.0120898, 0.666428, - 0.0116401, 0.471519, 0.0164569, 0.666444, - 0.0152015, 0.471522, 0.0214971, 0.66649, - 0.0192362, 0.471543, 0.027212, 0.666537, - 0.0237428, 0.471558, 0.033603, 0.666617, - 0.0287198, 0.471591, 0.0406728, 0.666718, - 0.0341647, 0.471631, 0.0484238, 0.666889, - 0.0400759, 0.47171, 0.0568621, 0.667104, - 0.0464479, 0.471805, 0.0659915, 0.667374, - 0.0532677, 0.471923, 0.0758178, 0.667772, - 0.0603805, 0.472098, 0.0863425, 0.668371, - 0.0677392, 0.472363, 0.0975917, 0.668971, - 0.0756028, 0.472596, 0.109567, 0.669696, - 0.0839293, 0.472869, 0.122272, 0.670481, - 0.0926683, 0.473126, 0.135718, 0.6715, - 0.1016, 0.473442, 0.149914, 0.672911, - 0.110566, 0.47389, 0.164882, 0.674512, - 0.119984, 0.474354, 0.180602, 0.67651, - 0.129574, 0.474922, 0.19711, 0.679292, - 0.139106, 0.475764, 0.214371, 0.682798, - 0.148993, 0.476886, 0.232405, 0.686955, - 0.158737, 0.478179, 0.251153, 0.691406, - 0.168754, 0.479432, 0.270436, 0.697438, - 0.178703, 0.481481, 0.290374, 0.704761, - 0.188955, 0.484143, 0.311044, 0.713599, - 0.198814, 0.487007, 0.333003, 0.723194, - 0.207869, 0.488962, 0.357144, 0.732601, - 0.216189, 0.489815, 0.382169, 0.744193, - 0.22398, 0.490888, 0.408227, 0.754907, - 0.231156, 0.490355, 0.434928, 0.767403, - 0.23747, 0.489548, 0.462599, 0.78107, - 0.243503, 0.488274, 0.490908, 0.793893, - 0.248114, 0.484843, 0.519421, 0.807296, - 0.25222, 0.4803, 0.548561, 0.820529, - 0.255265, 0.474097, 0.577772, 0.833716, - 0.256741, 0.466041, 0.607782, 0.848403, - 0.25637, 0.456547, 0.638807, 0.860755, - 0.254804, 0.443946, 0.670058, 0.874012, - 0.251834, 0.430852, 0.700749, 0.885619, - 0.247867, 0.414903, 0.731446, 0.896069, - 0.242634, 0.397276, 0.761191, 0.906266, - 0.236093, 0.378535, 0.791053, 0.916759, - 0.227543, 0.358038, 0.821298, 0.92523, - 0.21783, 0.335705, 0.850747, 0.93436, - 0.207534, 0.313797, 0.879258, 0.941631, - 0.195983, 0.289671, 0.907734, 0.947564, - 0.183567, 0.265319, 0.935206, 0.953681, - 0.169345, 0.240815, 0.962739, 0.960008, - 0.154909, 0.216119, 0.989227, 0.964145, - 0.140161, 0.192096, 1.01465, 0.968171, - 0.123411, 0.167855, 1.03737, 0.969859, - 0.106525, 0.144817, 1.05767, 0.972666, - 0.0891023, 0.12149, 1.0761, 0.977055, - 0.0718094, 0.0975306, 1.09336, 0.982527, - 0.0534213, 0.0730217, 1.10878, 0.989001, - 0.0355579, 0.0483366, 1.12285, 0.99512, - 0.0176383, 0.023938, 1.13548, 1.00007, 0.000368831, - 0.000211581, 1.14744, 0.651047, - 9.60845e-06, 0.484101, 1.2922e-05, 0.644145, - 0.000241347, 0.478968, 0.000324578, 0.64396, - 0.000965142, 0.478831, 0.00129798, 0.64396, - 0.00217154, 0.47883, 0.00292046, 0.643968, - 0.00386049, 0.478835, 0.00519202, 0.643974, - 0.00603186, 0.478838, 0.0081128, 0.643977, - 0.0086854, 0.478836, 0.011683, 0.643982, - 0.0118207, 0.478834, 0.0159031, 0.644024, - 0.0154374, 0.478856, 0.0207743, 0.644059, - 0.0195343, 0.478868, 0.0262975, 0.644122, - 0.0241103, 0.478896, 0.0324747, 0.644207, - 0.0291638, 0.478933, 0.039309, 0.64432, - 0.0346919, 0.478981, 0.0468029, 0.644481, - 0.0406919, 0.479053, 0.0549614, 0.644722, - 0.047159, 0.479169, 0.0637909, 0.645013, - 0.0540748, 0.479302, 0.0732974, 0.645503, - 0.0612001, 0.479541, 0.0834898, 0.646117, - 0.0687303, 0.479829, 0.0943873, 0.646707, - 0.0767846, 0.480061, 0.105991, 0.647431, - 0.0852465, 0.480343, 0.11831, 0.64831, - 0.0940719, 0.48066, 0.131348, 0.649486, - 0.103056, 0.481083, 0.14514, 0.650864, - 0.112261, 0.481528, 0.159676, 0.652604, - 0.121852, 0.482102, 0.174979, 0.654825, - 0.131505, 0.482813, 0.191079, 0.657876, - 0.141189, 0.483876, 0.207927, 0.661339, - 0.151239, 0.48499, 0.225586, 0.665463, - 0.161091, 0.486279, 0.243947, 0.670542, - 0.171235, 0.487968, 0.262957, 0.677361, - 0.181347, 0.49053, 0.282781, 0.685672, - 0.191679, 0.493862, 0.303311, 0.694551, - 0.201781, 0.49699, 0.324607, 0.703753, - 0.211164, 0.498884, 0.347916, 0.713703, - 0.219675, 0.500086, 0.372628, 0.725911, - 0.227836, 0.501554, 0.398694, 0.73862, - 0.23533, 0.502193, 0.425529, 0.752118, - 0.241786, 0.501811, 0.453209, 0.76579, - 0.247865, 0.500185, 0.481381, 0.779568, - 0.252696, 0.497159, 0.51011, 0.793991, - 0.256802, 0.492765, 0.539322, 0.808182, - 0.259942, 0.486827, 0.569078, 0.821698, - 0.261703, 0.478386, 0.598818, 0.836009, - 0.262006, 0.468772, 0.629762, 0.849824, - 0.260333, 0.456352, 0.661366, 0.863888, - 0.257398, 0.442533, 0.69295, 0.876585, - 0.253264, 0.426573, 0.723608, 0.888665, - 0.248026, 0.408964, 0.754378, 0.899537, - 0.241487, 0.389677, 0.784761, 0.9094, - 0.233463, 0.368516, 0.814688, 0.920166, - 0.223397, 0.346624, 0.845009, 0.928899, - 0.21255, 0.322717, 0.874431, 0.937156, - 0.200869, 0.298698, 0.902922, 0.943861, - 0.188387, 0.273491, 0.931356, 0.949557, - 0.174341, 0.247866, 0.958854, 0.955862, - 0.158994, 0.222496, 0.986098, 0.961721, - 0.143664, 0.197522, 1.01229, 0.965976, - 0.127412, 0.17302, 1.03571, 0.968652, - 0.109798, 0.148954, 1.05699, 0.971084, - 0.0916787, 0.125044, 1.07587, 0.975584, - 0.0739634, 0.100577, 1.09372, 0.98122, - 0.055322, 0.0753666, 1.10948, 0.988253, - 0.0366825, 0.0498899, 1.12394, 0.99482, - 0.0180389, 0.024611, 1.13694, 1.00001, 0.000229839, - 0.000188283, 1.14919, 0.613867, - 9.64198e-06, 0.479449, 1.23452e-05, 0.621485, - 0.000244534, 0.485399, 0.000313091, 0.621429, - 0.000978202, 0.485353, 0.00125245, 0.62112, - 0.00220004, 0.485114, 0.00281687, 0.621119, - 0.0039111, 0.485112, 0.00500783, 0.621122, - 0.00611091, 0.485112, 0.00782498, 0.621133, - 0.00879922, 0.485117, 0.0112687, 0.621152, - 0.0119756, 0.485125, 0.0153394, 0.621183, - 0.0156396, 0.485139, 0.0200382, 0.621227, - 0.0197898, 0.485158, 0.0253663, 0.621298, - 0.0244253, 0.485192, 0.0313261, 0.621388, - 0.0295441, 0.485233, 0.0379204, 0.621507, - 0.0351432, 0.485286, 0.0451523, 0.621693, - 0.0412198, 0.485378, 0.0530277, 0.621933, - 0.0477673, 0.485495, 0.0615522, 0.622232, - 0.0547574, 0.485635, 0.0707316, 0.622809, - 0.0619417, 0.485943, 0.0805883, 0.623407, - 0.069625, 0.486232, 0.0911267, 0.62406, - 0.077796, 0.486516, 0.102354, 0.624835, - 0.0863731, 0.486838, 0.114279, 0.625758, - 0.095251, 0.487188, 0.126902, 0.627043, - 0.104299, 0.487695, 0.140285, 0.628438, - 0.113724, 0.488163, 0.154397, 0.630325, - 0.123417, 0.488858, 0.169267, 0.632801, - 0.133137, 0.489754, 0.184941, 0.635784, - 0.143052, 0.490815, 0.20136, 0.639406, - 0.153132, 0.492048, 0.218643, 0.643872, - 0.163143, 0.49363, 0.236615, 0.6499, - 0.17333, 0.496009, 0.255449, 0.657201, - 0.183622, 0.498994, 0.275006, 0.666221, - 0.194019, 0.502888, 0.295354, 0.674419, - 0.204192, 0.505459, 0.316244, 0.683729, - 0.21406, 0.507771, 0.33849, 0.695584, - 0.222854, 0.510245, 0.363166, 0.708583, - 0.231315, 0.512293, 0.389071, 0.721233, - 0.238911, 0.512747, 0.415737, 0.735134, - 0.245657, 0.512482, 0.443331, 0.750179, - 0.251879, 0.511526, 0.471891, 0.765073, - 0.256911, 0.508935, 0.500892, 0.779794, - 0.261144, 0.504341, 0.530294, 0.794801, - 0.264316, 0.498515, 0.560144, 0.810339, - 0.266276, 0.491015, 0.590213, 0.824818, - 0.266981, 0.481126, 0.620865, 0.839375, - 0.265778, 0.468685, 0.652687, 0.853043, - 0.262748, 0.453925, 0.684759, 0.867335, - 0.258474, 0.437912, 0.716209, 0.88037, - 0.253187, 0.419648, 0.747508, 0.891711, - 0.246476, 0.39982, 0.77797, 0.902896, - 0.238735, 0.37879, 0.808586, 0.913601, - 0.22885, 0.355891, 0.838843, 0.923019, - 0.217656, 0.331773, 0.869014, 0.933432, - 0.205539, 0.307356, 0.898512, 0.939691, - 0.192595, 0.281321, 0.9269, 0.946938, - 0.178945, 0.255441, 0.955297, 0.952372, - 0.163587, 0.229013, 0.983231, 0.95909, - 0.147214, 0.203179, 1.00971, 0.963675, - 0.13064, 0.17792, 1.03438, 0.968247, - 0.113121, 0.152898, 1.05625, 0.97001, - 0.0945824, 0.128712, 1.07598, 0.974458, - 0.0755648, 0.103349, 1.094, 0.980168, - 0.0571998, 0.0776731, 1.1104, 0.987295, - 0.0377994, 0.0514445, 1.12491, 0.994432, - 0.0186417, 0.025429, 1.13851, 0.999975, 0.000542714, - 0.000282356, 1.15108, 0.592656, - 9.80249e-06, 0.486018, 1.19532e-05, 0.598467, - 0.000247275, 0.490781, 0.000301531, 0.597934, - 0.000988317, 0.490343, 0.00120517, 0.597903, - 0.00222366, 0.490319, 0.0027116, 0.597913, - 0.00395315, 0.490327, 0.00482077, 0.597919, - 0.00617653, 0.490329, 0.00753264, 0.597936, - 0.00889375, 0.490339, 0.0108478, 0.597956, - 0.0121043, 0.490347, 0.0147668, 0.597992, - 0.0158073, 0.490365, 0.0192905, 0.598032, - 0.0200017, 0.490382, 0.0244204, 0.598109, - 0.0246865, 0.49042, 0.0301593, 0.598215, - 0.0298594, 0.490474, 0.03651, 0.59833, - 0.0355167, 0.490524, 0.0434757, 0.598525, - 0.0416559, 0.490624, 0.0510629, 0.598778, - 0.0482692, 0.490753, 0.0592781, 0.599135, - 0.0553114, 0.49094, 0.0681304, 0.599802, - 0.062542, 0.491328, 0.0776467, 0.600361, - 0.0703638, 0.491598, 0.0878184, 0.60101, - 0.0786256, 0.491882, 0.0986573, 0.601811, - 0.0872962, 0.492232, 0.11018, 0.602861, - 0.0962284, 0.492684, 0.1224, 0.604167, - 0.10538, 0.493213, 0.135354, 0.605693, - 0.114896, 0.493799, 0.149034, 0.607682, - 0.124654, 0.494576, 0.163469, 0.610672, - 0.13456, 0.4959, 0.178747, 0.613313, - 0.144581, 0.496713, 0.194723, 0.617603, - 0.154703, 0.498499, 0.211617, 0.622174, - 0.16489, 0.500188, 0.229183, 0.628855, - 0.175164, 0.503072, 0.247786, 0.636963, - 0.185565, 0.506798, 0.267116, 0.644866, - 0.195911, 0.509719, 0.28702, 0.653741, - 0.206104, 0.512776, 0.307763, 0.664942, - 0.216447, 0.516812, 0.329631, 0.67633, - 0.22552, 0.519181, 0.353515, 0.690012, - 0.234316, 0.521681, 0.379226, 0.704243, - 0.242032, 0.523129, 0.405901, 0.719396, - 0.249172, 0.523768, 0.433585, 0.734471, - 0.255543, 0.522541, 0.462085, 0.750539, - 0.260697, 0.520217, 0.491233, 0.766365, - 0.26501, 0.516293, 0.521094, 0.781677, - 0.268409, 0.509708, 0.551014, 0.797132, - 0.270399, 0.501944, 0.581463, 0.812655, - 0.271247, 0.492025, 0.612402, 0.828592, - 0.270708, 0.480424, 0.643798, 0.844044, - 0.268085, 0.465955, 0.67682, 0.857305, - 0.263459, 0.448425, 0.708496, 0.87114, - 0.258151, 0.430243, 0.74046, 0.884936, - 0.251171, 0.410578, 0.771583, 0.895772, - 0.243305, 0.38862, 0.802234, 0.906961, - 0.234037, 0.365214, 0.833179, 0.917775, - 0.222714, 0.34116, 0.86353, 0.927883, - 0.210175, 0.31572, 0.893557, 0.936617, - 0.196925, 0.289159, 0.922976, 0.943384, - 0.182788, 0.261996, 0.951606, 0.949713, - 0.167965, 0.235324, 0.979958, 0.955818, - 0.151109, 0.208408, 1.00765, 0.961344, - 0.133834, 0.182591, 1.03329, 0.965469, - 0.115987, 0.156958, 1.0557, 0.968693, - 0.09746, 0.132239, 1.07583, 0.973165, - 0.0778514, 0.106195, 1.09451, 0.979387, - 0.0585067, 0.0797669, 1.11137, 0.98671, - 0.0390409, 0.0530263, 1.12643, 0.994093, - 0.019408, 0.0263163, 1.14016, 1.00002, 0.000540029, - 0.000194487, 1.15299, 0.574483, - 9.89066e-06, 0.494533, 1.14896e-05, 0.574478, - 0.000249127, 0.494528, 0.000289403, 0.574607, - 0.000996811, 0.494637, 0.00115797, 0.574396, - 0.00224241, 0.494458, 0.00260498, 0.574377, - 0.00398632, 0.49444, 0.00463102, 0.574386, - 0.00622836, 0.494445, 0.00723623, 0.574401, - 0.0089683, 0.494453, 0.010421, 0.574419, - 0.0122056, 0.49446, 0.0141859, 0.574459, - 0.0159396, 0.494481, 0.0185322, 0.574525, - 0.0201692, 0.49452, 0.0234617, 0.574587, - 0.0248924, 0.494547, 0.0289762, 0.574697, - 0.0301074, 0.494604, 0.0350797, 0.574853, - 0.0358114, 0.494688, 0.0417767, 0.575027, - 0.041999, 0.494772, 0.0490718, 0.575294, - 0.0486618, 0.494915, 0.0569728, 0.575733, - 0.0557148, 0.495173, 0.0654955, 0.576356, - 0.0630489, 0.495537, 0.0746612, 0.576944, - 0.0709285, 0.495836, 0.0844615, 0.57765, - 0.0792723, 0.496177, 0.0949142, 0.578491, - 0.0880167, 0.496563, 0.10603, 0.579639, - 0.0969462, 0.497096, 0.117841, 0.580989, - 0.10622, 0.497684, 0.130367, 0.582587, - 0.115861, 0.498337, 0.143609, 0.584951, - 0.125605, 0.499414, 0.157625, 0.587602, - 0.135608, 0.500518, 0.172413, 0.59076, - 0.145742, 0.501767, 0.187999, 0.594992, - 0.155934, 0.503542, 0.20445, 0.600656, - 0.166303, 0.506135, 0.221764, 0.607816, - 0.176681, 0.509542, 0.24002, 0.61522, - 0.187071, 0.51263, 0.258992, 0.623702, - 0.197465, 0.516021, 0.278773, 0.634192, - 0.207816, 0.520422, 0.299377, 0.644936, - 0.218183, 0.524073, 0.320802, 0.657888, - 0.2278, 0.528049, 0.34384, 0.670666, - 0.236747, 0.52986, 0.36916, 0.685626, - 0.24484, 0.531892, 0.395867, 0.701304, - 0.252071, 0.532727, 0.423488, 0.717727, - 0.258714, 0.532146, 0.452201, 0.733914, - 0.264211, 0.529883, 0.481579, 0.750529, - 0.26859, 0.5259, 0.511558, 0.76747, - 0.272046, 0.51999, 0.542042, 0.785189, - 0.274225, 0.513083, 0.572799, 0.800954, - 0.275189, 0.502936, 0.603816, 0.816962, - 0.274946, 0.490921, 0.635461, 0.83336, - 0.272695, 0.47684, 0.6676, 0.848143, - 0.268223, 0.459405, 0.70051, 0.861818, - 0.262768, 0.440319, 0.732902, 0.876828, - 0.255872, 0.420123, 0.765084, 0.889312, - 0.247703, 0.398379, 0.796391, 0.900412, - 0.238381, 0.374496, 0.827333, 0.912251, - 0.227783, 0.349874, 0.858385, 0.921792, - 0.214832, 0.323181, 0.888652, 0.931273, - 0.200949, 0.296624, 0.917763, 0.940295, - 0.186537, 0.269211, 0.947878, 0.946812, - 0.171538, 0.241447, 0.977016, 0.953588, - 0.155254, 0.213829, 1.00501, 0.958841, - 0.137156, 0.186807, 1.03179, 0.963746, - 0.118699, 0.160706, 1.05502, 0.966468, - 0.0998358, 0.135504, 1.07568, 0.971178, - 0.0805186, 0.109131, 1.09479, 0.97831, - 0.0599348, 0.0818293, 1.1123, 0.985886, - 0.0399661, 0.0545872, 1.12771, 0.994021, - 0.0198682, 0.0269405, 1.14186, 1.00009, 0.000271022, - 0.00012989, 1.15514, 0.538716, - 9.90918e-06, 0.486732, 1.09675e-05, 0.550656, - 0.000250642, 0.497518, 0.000277412, 0.55057, - 0.00100265, 0.497441, 0.00110974, 0.550903, - 0.00225672, 0.497733, 0.00249779, 0.550568, - 0.00401046, 0.497438, 0.00443906, 0.550574, - 0.00626613, 0.49744, 0.00693637, 0.550591, - 0.0090226, 0.497449, 0.00998921, 0.550623, - 0.0122795, 0.497469, 0.0135984, 0.550667, - 0.0160361, 0.497495, 0.0177654, 0.550724, - 0.0202908, 0.497526, 0.0224915, 0.550792, - 0.0250421, 0.497557, 0.0277795, 0.550918, - 0.0302878, 0.49763, 0.0336334, 0.551058, - 0.0360241, 0.497701, 0.0400573, 0.551276, - 0.0422473, 0.497824, 0.0470585, 0.551551, - 0.0489441, 0.497977, 0.0546433, 0.552074, - 0.0559596, 0.498312, 0.0628367, 0.552681, - 0.0633978, 0.498679, 0.071646, 0.553324, - 0.0713176, 0.499031, 0.0810746, 0.554011, - 0.0797268, 0.499365, 0.091129, 0.55488, - 0.0885238, 0.499779, 0.101837, 0.556171, - 0.0974417, 0.500444, 0.113239, 0.557498, - 0.106841, 0.501025, 0.125316, 0.559299, - 0.116533, 0.501864, 0.138128, 0.561647, - 0.126298, 0.502967, 0.151695, 0.564347, - 0.136388, 0.504129, 0.16604, 0.567863, - 0.146576, 0.505713, 0.181207, 0.572569, - 0.156832, 0.507953, 0.197259, 0.578919, - 0.167323, 0.511186, 0.214258, 0.585387, - 0.177712, 0.514042, 0.232038, 0.593134, - 0.188184, 0.517484, 0.250733, 0.603295, - 0.198717, 0.522345, 0.270454, 0.613854, - 0.209177, 0.526751, 0.290807, 0.626092, - 0.219644, 0.531595, 0.312202, 0.637868, - 0.229494, 0.534721, 0.334435, 0.652458, - 0.238718, 0.538304, 0.359184, 0.666985, - 0.247061, 0.539875, 0.385637, 0.683301, - 0.254652, 0.541042, 0.41328, 0.69998, - 0.261376, 0.540735, 0.441903, 0.717824, - 0.267085, 0.539139, 0.471609, 0.734617, - 0.271465, 0.534958, 0.501446, 0.753663, - 0.27528, 0.53032, 0.532571, 0.770512, - 0.277617, 0.522134, 0.563641, 0.787356, - 0.278525, 0.51206, 0.595067, 0.806252, - 0.278512, 0.50119, 0.627226, 0.822061, - 0.277023, 0.486791, 0.659402, 0.838959, - 0.273175, 0.470467, 0.692874, 0.85379, - 0.267238, 0.450688, 0.725702, 0.868268, - 0.260327, 0.429741, 0.75832, 0.881994, - 0.251946, 0.407223, 0.790189, 0.893885, - 0.242432, 0.383214, 0.821625, 0.905118, - 0.231904, 0.357297, 0.853011, 0.916045, - 0.219545, 0.330733, 0.883773, 0.927614, - 0.205378, 0.303916, 0.914435, 0.936005, - 0.190388, 0.275941, 0.944502, 0.944533, - 0.1749, 0.247493, 0.974439, 0.950758, - 0.158588, 0.218996, 1.00286, 0.957078, - 0.141027, 0.191559, 1.0304, 0.962448, - 0.121507, 0.164457, 1.05466, 0.964993, - 0.102068, 0.138636, 1.0761, 0.970017, - 0.0822598, 0.111861, 1.09541, 0.97661, - 0.062033, 0.0843438, 1.11317, 0.985073, - 0.0409832, 0.0558496, 1.12911, 0.993515, - 0.020146, 0.0275331, 1.1438, 1.00006, 0.00027329, - 0.000107883, 1.15736, 0.525324, - 9.99341e-06, 0.498153, 1.05385e-05, 0.526513, - 0.000251605, 0.499277, 0.000265329, 0.526517, - 0.00100641, 0.499282, 0.0010613, 0.526588, - 0.00226466, 0.499337, 0.00238823, 0.526539, - 0.0040255, 0.499302, 0.00424535, 0.526547, - 0.00628954, 0.499306, 0.00663364, 0.526561, - 0.00905628, 0.499313, 0.00955337, 0.526593, - 0.0123253, 0.499334, 0.0130054, 0.526642, - 0.0160957, 0.499365, 0.0169911, 0.5267, - 0.0203661, 0.499396, 0.0215122, 0.526792, - 0.0251347, 0.499451, 0.0265718, 0.526904, - 0.0303985, 0.499511, 0.0321732, 0.527079, - 0.0361554, 0.499617, 0.0383231, 0.527285, - 0.0423982, 0.499731, 0.045026, 0.527602, - 0.0491121, 0.499924, 0.0522936, 0.528166, - 0.0561127, 0.500306, 0.0601528, 0.52879, - 0.0635988, 0.5007, 0.0686059, 0.529421, - 0.071581, 0.501048, 0.0776518, 0.530144, - 0.0799854, 0.501421, 0.0873148, 0.531062, - 0.0888032, 0.501884, 0.0976084, 0.532374, - 0.0977643, 0.50259, 0.108588, 0.533828, - 0.107197, 0.50329, 0.120234, 0.53581, - 0.116887, 0.504312, 0.132602, 0.538063, - 0.126755, 0.505365, 0.145721, 0.5409, - 0.136819, 0.506668, 0.159617, 0.544882, - 0.147117, 0.508731, 0.174369, 0.550238, - 0.157446, 0.511601, 0.190028, 0.556038, - 0.167988, 0.514431, 0.206587, 0.563031, - 0.178364, 0.517808, 0.224046, 0.571543, - 0.189007, 0.521937, 0.242503, 0.582255, - 0.199546, 0.527415, 0.261977, 0.59272, - 0.210084, 0.531682, 0.282162, 0.605648, - 0.220448, 0.537123, 0.303426, 0.61785, - 0.230593, 0.540664, 0.325323, 0.632223, - 0.240238, 0.544467, 0.348993, 0.648819, - 0.24887, 0.547594, 0.375462, 0.665825, - 0.256657, 0.54912, 0.403024, 0.683389, - 0.263711, 0.549294, 0.431773, 0.701495, - 0.269666, 0.547649, 0.461494, 0.719197, - 0.274169, 0.543786, 0.491623, 0.737906, - 0.278124, 0.538644, 0.522994, 0.756652, - 0.280632, 0.531057, 0.554775, 0.775279, - 0.281741, 0.521972, 0.586441, 0.792688, - 0.281652, 0.509613, 0.618596, 0.811894, - 0.280345, 0.496497, 0.651462, 0.827938, - 0.277128, 0.47968, 0.684023, 0.844837, - 0.271646, 0.460688, 0.718024, 0.859239, - 0.264397, 0.438872, 0.751207, 0.874088, - 0.256144, 0.41577, 0.784232, 0.887693, - 0.246311, 0.391369, 0.816191, 0.899402, - 0.235497, 0.365872, 0.847828, 0.910973, - 0.223631, 0.338618, 0.87934, 0.92204, - 0.209874, 0.310803, 0.910325, 0.930987, - 0.194265, 0.281802, 0.940695, 0.94, - 0.178125, 0.252836, 0.970958, 0.948018, - 0.161479, 0.224239, 1.00078, 0.955141, - 0.144038, 0.195857, 1.0288, 0.960513, - 0.124915, 0.168487, 1.05371, 0.963964, - 0.104284, 0.141495, 1.07596, 0.968713, - 0.0838732, 0.114437, 1.09628, 0.975524, - 0.0635579, 0.0863105, 1.11448, 0.98431, - 0.042291, 0.0574774, 1.13069, 0.992916, - 0.0209131, 0.0284343, 1.14568, 0.999926, 0.000743097, - 0.000379265, 1.15955, 0.501042, - 9.98428e-06, 0.498726, 1.00306e-05, 0.502992, - 0.000252112, 0.500665, 0.000253283, 0.502417, - 0.00100791, 0.500092, 0.00101259, 0.502965, - 0.00226919, 0.500621, 0.00227978, 0.502318, - 0.00403109, 0.499994, 0.00405011, 0.502333, - 0.00629832, 0.500005, 0.00632868, 0.502362, - 0.00906907, 0.500027, 0.00911446, 0.502369, - 0.0123423, 0.500023, 0.0124078, 0.50243, - 0.0161178, 0.500066, 0.016211, 0.502493, - 0.0203937, 0.500103, 0.0205256, 0.502592, - 0.0251684, 0.500166, 0.0253548, 0.502707, - 0.0304389, 0.50023, 0.0307029, 0.502881, - 0.0362015, 0.500335, 0.0365753, 0.503124, - 0.0424507, 0.500488, 0.0429798, 0.503443, - 0.0491582, 0.500686, 0.0499268, 0.504083, - 0.0561476, 0.501155, 0.0574541, 0.504668, - 0.0636846, 0.501524, 0.0655408, 0.505319, - 0.0716834, 0.501904, 0.0742072, 0.50609, - 0.0800925, 0.502321, 0.0834699, 0.507122, - 0.0888425, 0.502896, 0.0933603, 0.508414, - 0.097855, 0.503603, 0.10391, 0.509955, - 0.107304, 0.504416, 0.115113, 0.512061, - 0.116921, 0.505565, 0.127054, 0.514419, - 0.12689, 0.506732, 0.139709, 0.517529, - 0.136934, 0.508338, 0.153173, 0.522085, - 0.147327, 0.510987, 0.167528, 0.526986, - 0.157612, 0.513527, 0.182708, 0.533122, - 0.168213, 0.516717, 0.198881, 0.540807, - 0.178688, 0.520832, 0.215986, 0.550687, - 0.189511, 0.52632, 0.234335, 0.560567, - 0.199998, 0.531009, 0.253375, 0.571698, - 0.210652, 0.535839, 0.273499, 0.584364, - 0.220917, 0.541091, 0.294355, 0.599066, - 0.23137, 0.546875, 0.316525, 0.614148, - 0.241206, 0.551306, 0.339671, 0.631157, - 0.250379, 0.555187, 0.36531, 0.647919, - 0.258397, 0.556595, 0.392767, 0.666112, - 0.265528, 0.556949, 0.421397, 0.686158, - 0.271827, 0.556617, 0.451433, 0.704838, - 0.27674, 0.552975, 0.482131, 0.723957, - 0.280733, 0.547814, 0.513458, 0.74262, - 0.283359, 0.53997, 0.545446, 0.762009, - 0.284541, 0.530422, 0.57775, 0.781314, - 0.284507, 0.518546, 0.610434, 0.799116, - 0.283309, 0.504178, 0.643178, 0.817604, - 0.280378, 0.48843, 0.676248, 0.83459, - 0.275619, 0.469457, 0.709698, 0.850974, - 0.26856, 0.447698, 0.744245, 0.866747, - 0.260094, 0.424791, 0.777695, 0.881412, - 0.249929, 0.399913, 0.810392, 0.8936, - 0.239137, 0.37308, 0.842872, 0.905943, - 0.226818, 0.345705, 0.874677, 0.916408, - 0.213699, 0.31706, 0.906257, 0.927215, - 0.198428, 0.288444, 0.936881, 0.935625, - 0.181643, 0.258329, 0.96795, 0.944076, - 0.164386, 0.228488, 0.998216, 0.951229, - 0.146339, 0.199763, 1.02689, 0.958793, - 0.127709, 0.172153, 1.0535, 0.963219, - 0.107244, 0.144989, 1.07646, 0.967562, - 0.0857764, 0.11685, 1.09675, 0.974866, - 0.0645377, 0.0880571, 1.11576, 0.983353, - 0.0431732, 0.0587352, 1.13227, 0.992503, - 0.0218356, 0.0294181, 1.1478, 1.00003, 0.000605203, - 0.000231013, 1.16207, 0.482935, - 1.01177e-05, 0.504695, 9.68142e-06, 0.477554, - 0.000251521, 0.499071, 0.000240676, 0.477904, - 0.00100683, 0.499436, 0.00096342, 0.478368, - 0.00226636, 0.499899, 0.0021687, 0.477977, - 0.00402719, 0.499513, 0.00385384, 0.477993, - 0.00629226, 0.499525, 0.0060221, 0.478011, - 0.00906011, 0.499536, 0.00867289, 0.478051, - 0.0123305, 0.499566, 0.0118074, 0.478089, - 0.016102, 0.499587, 0.0154269, 0.478171, - 0.0203736, 0.499645, 0.0195341, 0.478254, - 0.025143, 0.499692, 0.0241318, 0.47839, - 0.0304071, 0.499779, 0.0292247, 0.478588, - 0.0361631, 0.499911, 0.0348196, 0.478812, - 0.0424023, 0.500046, 0.0409231, 0.479208, - 0.0490724, 0.500326, 0.047552, 0.479841, - 0.0560722, 0.500805, 0.0547377, 0.480392, - 0.0636125, 0.501152, 0.0624607, 0.481068, - 0.0716134, 0.501561, 0.0707473, 0.481898, - 0.0800062, 0.502054, 0.0796118, 0.483022, - 0.0886568, 0.502728, 0.0890974, 0.484332, - 0.0977553, 0.503479, 0.0992099, 0.486126, - 0.107173, 0.504546, 0.10999, 0.488066, - 0.11677, 0.50557, 0.121476, 0.490521, - 0.126725, 0.506849, 0.133672, 0.494232, - 0.136793, 0.50911, 0.146731, 0.498302, - 0.147116, 0.511345, 0.160577, 0.503565, - 0.157446, 0.514344, 0.175335, 0.510902, - 0.168121, 0.518824, 0.191207, 0.519263, - 0.178799, 0.523666, 0.208058, 0.528204, - 0.189407, 0.528296, 0.225875, 0.538854, - 0.200145, 0.533724, 0.244782, 0.551278, - 0.210701, 0.539833, 0.264753, 0.565222, - 0.221303, 0.546131, 0.285745, 0.579403, - 0.231688, 0.551496, 0.307592, 0.595469, - 0.241718, 0.556809, 0.330582, 0.610929, - 0.250992, 0.559641, 0.354995, 0.629433, - 0.259602, 0.562379, 0.382471, 0.648504, - 0.267038, 0.563676, 0.411126, 0.66756, - 0.273388, 0.562092, 0.440924, 0.689143, - 0.278788, 0.560807, 0.472118, 0.709056, - 0.282783, 0.555701, 0.503774, 0.729855, - 0.285836, 0.548698, 0.536364, 0.748954, - 0.287078, 0.538544, 0.56895, 0.768373, - 0.287133, 0.526711, 0.601991, 0.78827, - 0.285839, 0.512511, 0.635403, 0.807465, - 0.283238, 0.496323, 0.668797, 0.825194, - 0.27906, 0.477638, 0.702584, 0.842203, - 0.272286, 0.456253, 0.736393, 0.857749, - 0.263854, 0.432412, 0.77096, 0.874799, - 0.253943, 0.407806, 0.80489, 0.887497, - 0.24237, 0.38033, 0.83771, 0.89966, - 0.230278, 0.352446, 0.870376, 0.911753, - 0.21646, 0.323268, 0.902256, 0.923011, - 0.202071, 0.294314, 0.933306, 0.932375, - 0.185519, 0.264104, 0.965177, 0.940537, - 0.167604, 0.234035, 0.996303, 0.948904, - 0.149068, 0.20412, 1.0261, 0.955263, - 0.129539, 0.175431, 1.05304, 0.960303, - 0.109932, 0.148116, 1.07617, 0.965512, - 0.0880572, 0.119693, 1.09742, 0.973466, - 0.0660548, 0.0901619, 1.11721, 0.98284, - 0.0439228, 0.0599875, 1.13436, 0.992216, - 0.0219588, 0.0298975, 1.15006, 0.999946, 0.000119402, - 2.08547e-05, 1.16471, 0.447827, - 1.00414e-05, 0.491543, 9.14833e-06, 0.454778, - 0.000251257, 0.499172, 0.00022891, 0.453519, - 0.00100342, 0.497787, 0.000914184, 0.45357, - 0.00225776, 0.497847, 0.00205701, 0.453578, - 0.00401371, 0.497855, 0.00365705, 0.45357, - 0.00627107, 0.497841, 0.00571453, 0.453598, - 0.00902968, 0.497864, 0.00823019, 0.453627, - 0.0122888, 0.497882, 0.0112049, 0.453684, - 0.0160475, 0.497923, 0.0146405, 0.453764, - 0.0203044, 0.49798, 0.0185394, 0.453866, - 0.0250576, 0.498049, 0.0229054, 0.453996, - 0.0303028, 0.49813, 0.0277424, 0.454196, - 0.0360379, 0.498267, 0.0330587, 0.454457, - 0.0422521, 0.498445, 0.0388613, 0.454926, - 0.0488393, 0.498812, 0.0451767, 0.455525, - 0.0558653, 0.499272, 0.0520153, 0.456074, - 0.0633772, 0.499625, 0.0593754, 0.456752, - 0.0713606, 0.500049, 0.0672751, 0.457648, - 0.07971, 0.500615, 0.0757447, 0.458849, - 0.0883032, 0.501399, 0.0848231, 0.46029, - 0.0974095, 0.502293, 0.0945135, 0.462, - 0.106729, 0.503301, 0.104848, 0.464121, - 0.116354, 0.504533, 0.115884, 0.466889, - 0.126214, 0.506172, 0.127652, 0.470744, - 0.136324, 0.508667, 0.14024, 0.47488, - 0.146595, 0.510995, 0.153673, 0.480845, - 0.157027, 0.514832, 0.168053, 0.488262, - 0.167658, 0.519506, 0.183508, 0.496547, - 0.178343, 0.524347, 0.199948, 0.506254, - 0.188916, 0.52983, 0.217503, 0.517961, - 0.199975, 0.536357, 0.236272, 0.531484, - 0.210624, 0.543641, 0.256096, 0.545496, - 0.221227, 0.550048, 0.277085, 0.559497, - 0.231568, 0.555076, 0.298615, 0.575752, - 0.241698, 0.560541, 0.321547, 0.591999, - 0.251172, 0.564156, 0.345602, 0.610654, - 0.260178, 0.567607, 0.371851, 0.630484, - 0.268094, 0.56923, 0.40076, 0.651807, - 0.274661, 0.569779, 0.430801, 0.67239, - 0.280331, 0.566791, 0.461939, 0.693024, - 0.284501, 0.562007, 0.493854, 0.715473, - 0.287852, 0.555791, 0.526992, 0.736323, - 0.28929, 0.546345, 0.560102, 0.755771, - 0.289405, 0.534, 0.593543, 0.775424, - 0.2881, 0.519114, 0.627256, 0.795447, - 0.285562, 0.502543, 0.661464, 0.815319, - 0.281416, 0.484773, 0.695206, 0.831769, - 0.275523, 0.463445, 0.729044, 0.849464, - 0.267516, 0.440269, 0.764069, 0.866775, - 0.257584, 0.415049, 0.799089, 0.881252, - 0.245817, 0.388049, 0.831948, 0.894209, - 0.233127, 0.35889, 0.865526, 0.906922, - 0.219579, 0.329915, 0.89818, 0.919686, - 0.204491, 0.300441, 0.930013, 0.929044, - 0.188962, 0.269445, 0.962061, 0.938393, - 0.171079, 0.238402, 0.994214, 0.94661, - 0.15199, 0.208204, 1.02533, 0.953095, - 0.131953, 0.178653, 1.0529, 0.958644, - 0.111233, 0.150684, 1.0771, 0.963925, - 0.0903098, 0.122359, 1.09855, 0.971995, - 0.0680505, 0.0923342, 1.11874, 0.981658, - 0.0448512, 0.0614195, 1.13635, 0.991649, - 0.0221931, 0.0303582, 1.15238, 0.999985, 0.000393403, - 0.000111086, 1.16772, 0.396806, - 9.71563e-06, 0.457671, 8.42355e-06, 0.429186, - 0.000249421, 0.495017, 0.00021625, 0.429324, - 0.000998052, 0.495173, 0.000865322, 0.429175, - 0.00224487, 0.494999, 0.00194637, 0.429129, - 0.00399041, 0.494952, 0.00346004, 0.429153, - 0.00623476, 0.494974, 0.00540684, 0.429168, - 0.0089773, 0.494983, 0.00778714, 0.429207, - 0.0122175, 0.495012, 0.0106022, 0.429257, - 0.0159542, 0.495047, 0.0138535, 0.429338, - 0.0201864, 0.495106, 0.0175443, 0.429431, - 0.0249104, 0.495165, 0.0216774, 0.429587, - 0.0301252, 0.495279, 0.0262594, 0.429796, - 0.0358249, 0.495432, 0.0312968, 0.430065, - 0.0419972, 0.495621, 0.0367985, 0.430588, - 0.0485144, 0.496061, 0.042798, 0.43113, - 0.0555028, 0.496472, 0.0492914, 0.431743, - 0.0629852, 0.496904, 0.0562907, 0.432448, - 0.0709256, 0.497369, 0.0638056, 0.433414, - 0.0791942, 0.498032, 0.071885, 0.434638, - 0.0877346, 0.498854, 0.0805517, 0.43611, - 0.0968056, 0.499812, 0.0898047, 0.437859, - 0.106002, 0.500891, 0.0997142, 0.440017, - 0.115648, 0.502198, 0.110289, 0.443236, - 0.125427, 0.504389, 0.121644, 0.44697, - 0.135492, 0.506809, 0.133769, 0.451689, - 0.145746, 0.509858, 0.146787, 0.45811, - 0.156219, 0.514247, 0.160793, 0.465305, - 0.166834, 0.518816, 0.175791, 0.474085, - 0.177546, 0.524331, 0.191906, 0.484808, - 0.188262, 0.53104, 0.209199, 0.49732, - 0.199346, 0.538511, 0.227825, 0.509693, - 0.209951, 0.544554, 0.247269, 0.524367, - 0.220533, 0.551616, 0.267978, 0.539228, - 0.231082, 0.557368, 0.289672, 0.55644, - 0.241342, 0.563782, 0.31268, 0.574204, - 0.250964, 0.568851, 0.33651, 0.593388, - 0.260306, 0.57312, 0.362219, 0.613358, - 0.268667, 0.574916, 0.390322, 0.634512, - 0.275591, 0.575053, 0.420478, 0.65563, - 0.281328, 0.572404, 0.451614, 0.678265, - 0.285948, 0.568893, 0.484112, 0.70011, - 0.289408, 0.561878, 0.517348, 0.723005, - 0.291328, 0.55359, 0.551355, 0.743744, - 0.291418, 0.541099, 0.585109, 0.763949, - 0.290252, 0.526489, 0.619487, 0.784186, - 0.287648, 0.509496, 0.65404, 0.804304, - 0.283782, 0.491484, 0.688649, 0.823629, - 0.278067, 0.470517, 0.723133, 0.84094, - 0.270588, 0.44705, 0.757163, 0.857852, - 0.261188, 0.421252, 0.792816, 0.874934, - 0.249313, 0.394191, 0.827248, 0.888709, - 0.236492, 0.365359, 0.861074, 0.902589, - 0.222185, 0.336016, 0.894417, 0.914201, - 0.207314, 0.30527, 0.926825, 0.925978, - 0.191146, 0.274532, 0.9595, 0.93512, - 0.174135, 0.243393, 0.991583, 0.943656, - 0.155231, 0.212414, 1.02356, 0.951719, - 0.134403, 0.182005, 1.05239, 0.957164, - 0.113023, 0.153043, 1.07754, 0.962656, - 0.0914493, 0.124186, 1.09984, 0.970695, - 0.0694179, 0.0941654, 1.12, 0.980749, - 0.0466199, 0.0629671, 1.13849, 0.991205, - 0.0227032, 0.0311146, 1.15494, 0.999884, 0.000632388, - 0.000254483, 1.1706, 0.379821, - 9.57289e-06, 0.460637, 7.89337e-06, 0.405188, - 0.000247483, 0.491396, 0.000204064, 0.404796, - 0.000989434, 0.490914, 0.000815853, 0.40483, - 0.00222607, 0.490949, 0.00183559, 0.40473, - 0.00395723, 0.49084, 0.00326332, 0.404731, - 0.00618287, 0.490836, 0.00509945, 0.404768, - 0.00890258, 0.490871, 0.00734463, 0.404791, - 0.0121156, 0.490883, 0.00999992, 0.404857, - 0.0158214, 0.490938, 0.0130676, 0.404943, - 0.0200178, 0.491004, 0.0165503, 0.405059, - 0.0247027, 0.491093, 0.0204521, 0.405213, - 0.0298729, 0.491205, 0.0247788, 0.405399, - 0.0355226, 0.491333, 0.0295373, 0.405731, - 0.0416352, 0.491604, 0.034741, 0.406303, - 0.0480807, 0.492116, 0.0404255, 0.406814, - 0.0550458, 0.492506, 0.0465732, 0.407404, - 0.0624652, 0.492926, 0.0532058, 0.408149, - 0.0702958, 0.493442, 0.0603442, 0.409128, - 0.0784623, 0.494136, 0.0680297, 0.410408, - 0.087007, 0.495054, 0.0762786, 0.411813, - 0.0959639, 0.495962, 0.0851046, 0.413735, - 0.105075, 0.497257, 0.0945878, 0.416137, - 0.114646, 0.498882, 0.104725, 0.41934, - 0.124394, 0.501132, 0.11563, 0.423326, - 0.134328, 0.503883, 0.127325, 0.428419, - 0.14458, 0.50747, 0.139911, 0.43484, - 0.154979, 0.511964, 0.153481, 0.442641, - 0.165628, 0.517328, 0.168114, 0.452511, - 0.176365, 0.524258, 0.183995, 0.463473, - 0.187298, 0.531248, 0.200953, 0.475564, - 0.198244, 0.538367, 0.219176, 0.488664, - 0.208938, 0.545175, 0.238514, 0.504073, - 0.219599, 0.553227, 0.259129, 0.520832, - 0.230378, 0.560653, 0.280997, 0.538455, - 0.240703, 0.567523, 0.303821, 0.55709, - 0.250548, 0.573287, 0.327948, 0.576646, - 0.259964, 0.577795, 0.353362, 0.596705, - 0.268721, 0.580077, 0.380336, 0.618053, - 0.276054, 0.58018, 0.4101, 0.640303, - 0.282176, 0.578747, 0.44161, 0.662365, - 0.286931, 0.574294, 0.474106, 0.684542, - 0.290521, 0.567035, 0.507549, 0.707984, - 0.292672, 0.558687, 0.541853, 0.730913, - 0.293189, 0.547606, 0.576581, 0.752948, - 0.292199, 0.533471, 0.61172, 0.773452, - 0.289508, 0.516395, 0.646339, 0.794715, - 0.285716, 0.497873, 0.682131, 0.814251, - 0.280051, 0.476845, 0.716396, 0.833057, - 0.272873, 0.453449, 0.751503, 0.84959, - 0.263982, 0.427857, 0.786085, 0.867022, - 0.252745, 0.400335, 0.821355, 0.882277, - 0.239655, 0.371304, 0.85646, 0.895375, - 0.225386, 0.340397, 0.890828, 0.909347, - 0.209587, 0.310005, 0.923532, 0.921885, - 0.193433, 0.2796, 0.956419, 0.932127, - 0.176135, 0.247276, 0.989445, 0.941869, - 0.157872, 0.216186, 1.02221, 0.949735, - 0.137577, 0.185602, 1.05195, 0.956617, - 0.115285, 0.155767, 1.07822, 0.961974, - 0.0928418, 0.126103, 1.10149, 0.96972, - 0.0700592, 0.0956758, 1.12207, 0.98012, - 0.0474671, 0.0643269, 1.1408, 0.990825, - 0.0238113, 0.0320863, 1.1577, 0.999876, 0.000381574, - 8.12203e-05, 1.17403, 0.367636, - 9.61342e-06, 0.469176, 7.53287e-06, 0.380377, - 0.000244772, 0.485434, 0.000191797, 0.380416, - 0.000978857, 0.485475, 0.000767015, 0.380376, - 0.00220165, 0.485435, 0.00172522, 0.380419, - 0.00391408, 0.485487, 0.00306734, 0.380438, - 0.00611549, 0.485505, 0.00479332, 0.380462, - 0.00880558, 0.485525, 0.00690391, 0.380496, - 0.0119837, 0.485551, 0.00940039, 0.38056, - 0.0156487, 0.485605, 0.0122848, 0.38064, - 0.0197988, 0.485666, 0.0155601, 0.380767, - 0.0244324, 0.48577, 0.0192313, 0.380909, - 0.0295444, 0.485871, 0.0233032, 0.381142, - 0.0351321, 0.48606, 0.0277861, 0.381472, - 0.0411535, 0.486336, 0.0326939, 0.382015, - 0.0475408, 0.486833, 0.0380565, 0.382523, - 0.0544395, 0.487231, 0.0438615, 0.383129, - 0.061784, 0.487683, 0.0501332, 0.383952, - 0.0695085, 0.488313, 0.0568996, 0.38498, - 0.0775819, 0.489077, 0.0641952, 0.386331, - 0.0860443, 0.490113, 0.0720324, 0.387788, - 0.0948406, 0.491099, 0.0804379, 0.389808, - 0.103899, 0.492566, 0.0894899, 0.39252, - 0.113313, 0.494601, 0.0992098, 0.395493, - 0.123007, 0.496619, 0.109641, 0.399826, - 0.132859, 0.499912, 0.120919, 0.405341, - 0.143077, 0.504061, 0.133107, 0.411932, - 0.153465, 0.508905, 0.146263, 0.420591, - 0.164108, 0.515482, 0.160544, 0.43101, - 0.174893, 0.523191, 0.176123, 0.441881, - 0.185839, 0.53026, 0.192757, 0.453919, - 0.196633, 0.537295, 0.210535, 0.468715, - 0.207611, 0.546156, 0.229886, 0.485182, - 0.218517, 0.555173, 0.250543, 0.501926, - 0.229249, 0.562728, 0.27221, 0.51785, - 0.239481, 0.567494, 0.294892, 0.536947, - 0.249395, 0.573889, 0.318987, 0.557115, - 0.259, 0.578831, 0.344348, 0.577966, - 0.268075, 0.582055, 0.371223, 0.599489, - 0.276115, 0.583307, 0.399834, 0.62479, - 0.282523, 0.583902, 0.431415, 0.647504, - 0.287663, 0.57953, 0.464301, 0.670601, - 0.291538, 0.573103, 0.498123, 0.693539, - 0.293842, 0.563731, 0.532662, 0.717385, - 0.294681, 0.553169, 0.567925, 0.741533, - 0.293717, 0.539908, 0.603502, 0.762142, - 0.291156, 0.521902, 0.639074, 0.783014, - 0.28719, 0.502815, 0.674439, 0.805158, - 0.281773, 0.482598, 0.710497, 0.823646, - 0.274682, 0.458949, 0.7456, 0.841879, - 0.266184, 0.433129, 0.781085, 0.859515, - 0.255682, 0.406064, 0.816, 0.875335, - 0.242849, 0.376509, 0.851074, 0.890147, - 0.228329, 0.345502, 0.886473, 0.903144, - 0.212491, 0.31428, 0.920751, 0.916618, - 0.195695, 0.282994, 0.954606, 0.927953, - 0.178267, 0.251091, 0.988402, 0.937414, - 0.159549, 0.219107, 1.02141, 0.946823, - 0.140022, 0.18896, 1.05167, 0.954651, - 0.118154, 0.158667, 1.07819, 0.959955, - 0.0946636, 0.128808, 1.1025, 0.96858, - 0.0711792, 0.0973787, 1.12391, 0.97938, - 0.0475046, 0.0650965, 1.14322, 0.990498, - 0.024059, 0.0326267, 1.16077, 0.999844, - 5.12408e-05, 0.000112444, 1.17727, 0.316912, - 9.34977e-06, 0.425996, 6.95559e-06, 0.356423, - 0.000241372, 0.479108, 0.000179562, 0.356272, - 0.000965292, 0.478897, 0.00071811, 0.356262, - 0.00217182, 0.478894, 0.00161574, 0.356265, - 0.00386092, 0.478895, 0.00287261, 0.356278, - 0.0060324, 0.478905, 0.00448907, 0.356293, - 0.00868565, 0.478914, 0.00646572, 0.356346, - 0.0118207, 0.478965, 0.00880438, 0.356395, - 0.0154355, 0.479001, 0.0115066, 0.356484, - 0.019529, 0.479075, 0.0145762, 0.356609, - 0.0240991, 0.47918, 0.018018, 0.356766, - 0.0291413, 0.479305, 0.0218379, 0.357009, - 0.0346498, 0.479512, 0.0260454, 0.357424, - 0.0405462, 0.479909, 0.0306657, 0.357899, - 0.0468825, 0.480337, 0.0357054, 0.358424, - 0.0536887, 0.480771, 0.0411728, 0.359041, - 0.0609416, 0.481242, 0.0470841, 0.359903, - 0.0685239, 0.481943, 0.0534831, 0.360932, - 0.0764883, 0.482741, 0.0603795, 0.362196, - 0.0848364, 0.483688, 0.0678028, 0.363847, - 0.0935002, 0.484947, 0.0758086, 0.365972, - 0.102471, 0.486588, 0.0844173, 0.368741, - 0.111751, 0.488787, 0.0937199, 0.372146, - 0.121334, 0.491405, 0.103732, 0.377114, - 0.131147, 0.495604, 0.114608, 0.38226, - 0.141213, 0.499436, 0.126345, 0.389609, - 0.151632, 0.505334, 0.139116, 0.397925, - 0.162073, 0.51168, 0.152995, 0.407824, - 0.172819, 0.518876, 0.168071, 0.420014, - 0.183929, 0.527639, 0.184495, 0.434266, - 0.195032, 0.537588, 0.20232, 0.447352, - 0.205792, 0.544379, 0.221189, 0.463726, - 0.216704, 0.553422, 0.241616, 0.481406, - 0.227531, 0.562074, 0.263298, 0.498707, - 0.238017, 0.568227, 0.286116, 0.518039, - 0.247936, 0.574473, 0.3101, 0.538277, - 0.257437, 0.579191, 0.335401, 0.561166, - 0.266829, 0.584807, 0.362246, 0.583189, - 0.275329, 0.586476, 0.390609, 0.606024, - 0.28234, 0.585578, 0.420998, 0.632419, - 0.287924, 0.584496, 0.454357, 0.656128, - 0.291972, 0.577766, 0.488233, 0.679953, - 0.29456, 0.56875, 0.523248, 0.704654, - 0.295816, 0.558388, 0.559168, 0.729016, - 0.295157, 0.544826, 0.595326, 0.752062, - 0.292779, 0.528273, 0.631864, 0.773138, - 0.288681, 0.508482, 0.667793, 0.794869, - 0.283358, 0.487341, 0.704035, 0.815101, - 0.27608, 0.46354, 0.739925, 0.834212, - 0.26767, 0.438672, 0.775539, 0.852368, - 0.257397, 0.411239, 0.810895, 0.870207, - 0.245689, 0.3829, 0.846472, 0.884063, - 0.231452, 0.351496, 0.881788, 0.898284, - 0.215561, 0.31895, 0.917438, 0.912964, - 0.198208, 0.287367, 0.952422, 0.924666, - 0.180426, 0.254487, 0.987551, 0.934429, - 0.161525, 0.222226, 1.02142, 0.943485, - 0.141197, 0.191143, 1.05218, 0.9521, - 0.120085, 0.161112, 1.07937, 0.957876, - 0.0975881, 0.130982, 1.10403, 0.966943, - 0.0726842, 0.0990553, 1.12616, 0.978313, - 0.0483705, 0.0662818, 1.14619, 0.990048, - 0.0239072, 0.0329243, 1.16413, 0.999984, 0.000461885, - 7.72859e-05, 1.18099, 0.321287, - 9.35049e-06, 0.455413, 6.59662e-06, 0.332595, - 0.000237513, 0.471437, 0.000167562, 0.332729, - 0.000949964, 0.471618, 0.000670192, 0.332305, - 0.00213618, 0.471028, 0.00150712, 0.332326, - 0.00379765, 0.471055, 0.00267959, 0.332344, - 0.00593353, 0.471072, 0.00418751, 0.332356, - 0.00854349, 0.471077, 0.00603172, 0.332403, - 0.0116268, 0.471121, 0.00821362, 0.332461, - 0.0151824, 0.47117, 0.0107357, 0.332552, - 0.0192088, 0.471251, 0.0136014, 0.332657, - 0.0237024, 0.47133, 0.0168152, 0.332835, - 0.0286615, 0.471487, 0.0203853, 0.333083, - 0.0340765, 0.471708, 0.0243212, 0.333547, - 0.0398563, 0.47219, 0.0286518, 0.333989, - 0.0460916, 0.472587, 0.0333763, 0.334532, - 0.0527897, 0.473054, 0.0385084, 0.335167, - 0.0599284, 0.473568, 0.0440638, 0.33608, - 0.0673514, 0.474362, 0.0500962, 0.337146, - 0.0752237, 0.475231, 0.0566022, 0.338462, - 0.083418, 0.476282, 0.0636272, 0.34014, - 0.0919382, 0.477615, 0.0712153, 0.342341, - 0.100741, 0.479404, 0.079417, 0.345088, - 0.109905, 0.481618, 0.0882631, 0.349049, - 0.119369, 0.485081, 0.0978851, 0.353939, - 0.129033, 0.489317, 0.108336, 0.359893, - 0.139038, 0.494309, 0.119698, 0.366945, - 0.149411, 0.499983, 0.132024, 0.375814, - 0.159843, 0.507185, 0.145558, 0.387112, - 0.170664, 0.516392, 0.160433, 0.40023, - 0.181897, 0.526519, 0.176648, 0.412555, - 0.192785, 0.53423, 0.193922, 0.427023, - 0.203663, 0.542741, 0.212662, 0.443685, - 0.214695, 0.552066, 0.232944, 0.461499, - 0.225561, 0.560762, 0.254495, 0.480975, - 0.236257, 0.569421, 0.277531, 0.501, - 0.24639, 0.576101, 0.301724, 0.521691, - 0.256101, 0.581493, 0.327112, 0.543478, - 0.265289, 0.585221, 0.353917, 0.566094, - 0.273938, 0.587614, 0.381941, 0.589578, - 0.281679, 0.587991, 0.41172, 0.614583, - 0.287655, 0.585928, 0.444148, 0.641813, - 0.292228, 0.582092, 0.478617, 0.666189, - 0.295172, 0.57398, 0.51397, 0.690475, - 0.29648, 0.561676, 0.550118, 0.715543, - 0.296203, 0.548758, 0.586933, 0.740405, - 0.293999, 0.532792, 0.62384, 0.762183, - 0.28998, 0.512735, 0.660723, 0.786069, - 0.28478, 0.492402, 0.69807, 0.806812, - 0.277568, 0.469058, 0.734422, 0.826987, - 0.268951, 0.443017, 0.770946, 0.844588, - 0.259049, 0.415501, 0.80699, 0.863725, - 0.2471, 0.387328, 0.842107, 0.879137, - 0.234157, 0.356108, 0.878078, 0.894634, - 0.218719, 0.324315, 0.914058, 0.909162, - 0.201293, 0.291813, 0.949922, 0.92072, - 0.18267, 0.258474, 0.985337, 0.93158, - 0.163212, 0.225593, 1.0205, 0.941238, - 0.142771, 0.193986, 1.05273, 0.949293, - 0.120956, 0.163392, 1.08075, 0.956226, - 0.0985743, 0.132934, 1.10559, 0.96546, - 0.075118, 0.101255, 1.12823, 0.977403, - 0.0497921, 0.0675441, 1.149, 0.989648, - 0.0241574, 0.0334681, 1.16765, 1.00001, 0.0005762, - 0.000184807, 1.18519, 0.303474, - 9.16603e-06, 0.4542, 6.1243e-06, 0.308894, - 0.000232869, 0.462306, 0.000155592, 0.309426, - 0.000931661, 0.463093, 0.000622499, 0.308643, - 0.0020949, 0.461933, 0.00139979, 0.308651, - 0.0037242, 0.461941, 0.00248874, 0.308662, - 0.00581873, 0.46195, 0.00388933, 0.308687, - 0.00837818, 0.461974, 0.00560247, 0.308728, - 0.0114016, 0.462011, 0.00762948, 0.308789, - 0.0148884, 0.462067, 0.00997326, 0.308882, - 0.0188369, 0.462151, 0.0126375, 0.309007, - 0.0232436, 0.462263, 0.0156271, 0.30918, - 0.0281054, 0.462417, 0.0189498, 0.309442, - 0.0334065, 0.462667, 0.0226167, 0.309901, - 0.0390589, 0.463162, 0.0266614, 0.310331, - 0.0452042, 0.463555, 0.0310715, 0.310858, - 0.0517735, 0.464019, 0.0358698, 0.311576, - 0.0587359, 0.464669, 0.0410848, 0.312436, - 0.0660383, 0.465406, 0.0467453, 0.313526, - 0.0737266, 0.466339, 0.0528718, 0.314903, - 0.0817574, 0.467504, 0.0595039, 0.316814, - 0.090167, 0.469226, 0.0666888, 0.318965, - 0.0987555, 0.470981, 0.0744658, 0.322077, - 0.107792, 0.473814, 0.082912, 0.325947, - 0.117098, 0.477241, 0.0920846, 0.331008, - 0.126602, 0.48184, 0.102137, 0.337893, - 0.136619, 0.488334, 0.113135, 0.345106, - 0.146838, 0.494415, 0.12511, 0.355111, - 0.157357, 0.503275, 0.138356, 0.365095, - 0.167955, 0.510966, 0.152686, 0.378344, - 0.179157, 0.521508, 0.16856, 0.391599, - 0.190143, 0.530455, 0.18561, 0.407786, - 0.20123, 0.541275, 0.204308, 0.425294, - 0.212456, 0.551784, 0.224623, 0.444021, - 0.223568, 0.561493, 0.246172, 0.463418, - 0.234154, 0.569886, 0.268979, 0.484077, - 0.244546, 0.577116, 0.293411, 0.505513, - 0.254301, 0.582914, 0.318936, 0.527672, - 0.263564, 0.587208, 0.345856, 0.550565, - 0.272332, 0.589277, 0.374054, 0.573656, - 0.280011, 0.588426, 0.403276, 0.59827, - 0.286924, 0.587504, 0.43474, 0.624731, - 0.291994, 0.583401, 0.468767, 0.652396, - 0.295159, 0.576997, 0.504411, 0.67732, - 0.296954, 0.565863, 0.54114, 0.703147, - 0.296877, 0.552316, 0.57816, 0.728715, - 0.295147, 0.536773, 0.616124, 0.752448, - 0.291275, 0.51771, 0.653885, 0.775169, - 0.285905, 0.496087, 0.691537, 0.799307, - 0.279064, 0.474232, 0.729251, 0.819482, - 0.270294, 0.447676, 0.766267, 0.837659, - 0.260032, 0.419656, 0.802616, 0.856903, - 0.248497, 0.391328, 0.838583, 0.873325, - 0.235252, 0.360285, 0.874711, 0.889788, - 0.221126, 0.329215, 0.91077, 0.904486, - 0.204304, 0.296392, 0.94653, 0.917711, - 0.185562, 0.262159, 0.983828, 0.928969, - 0.165635, 0.229142, 1.01955, 0.939707, - 0.14442, 0.19673, 1.05317, 0.948167, - 0.122147, 0.165095, 1.0823, 0.955222, - 0.099098, 0.13451, 1.10791, 0.964401, - 0.0755332, 0.102476, 1.1312, 0.976605, - 0.0513817, 0.0689667, 1.15218, 0.989085, - 0.0258499, 0.034506, 1.17129, 0.999908, 0.000617773, - 0.000271268, 1.18961, 0.285803, - 9.05752e-06, 0.452348, 5.72272e-06, 0.284689, - 0.00022732, 0.450581, 0.000143626, 0.285263, - 0.000910214, 0.451482, 0.000575099, 0.285302, - 0.00204784, 0.451553, 0.00129395, 0.285318, - 0.00364057, 0.451574, 0.0023006, 0.28533, - 0.00568813, 0.451585, 0.00359547, 0.285361, - 0.00819001, 0.451618, 0.00517934, 0.285397, - 0.0111458, 0.45165, 0.007054, 0.285447, - 0.0145536, 0.451688, 0.00922167, 0.285527, - 0.0184127, 0.451758, 0.0116869, 0.285688, - 0.0227207, 0.451929, 0.0144555, 0.28584, - 0.0274712, 0.452055, 0.0175341, 0.286136, - 0.0326278, 0.452369, 0.0209406, 0.286574, - 0.0381792, 0.452853, 0.0246965, 0.287012, - 0.0441879, 0.453272, 0.0287996, 0.287542, - 0.0506096, 0.453752, 0.033268, 0.288299, - 0.0573634, 0.454488, 0.0381504, 0.289186, - 0.0645458, 0.455294, 0.0434447, 0.290302, - 0.0720405, 0.456301, 0.0491973, 0.291776, - 0.0799046, 0.457648, 0.0554453, 0.29372, - 0.088117, 0.459483, 0.0622311, 0.296052, - 0.0965328, 0.461571, 0.0695992, 0.299563, - 0.105409, 0.465085, 0.077658, 0.30335, - 0.114553, 0.468506, 0.0864176, 0.309167, - 0.123917, 0.474423, 0.0961078, 0.31529, - 0.13381, 0.47995, 0.106643, 0.324163, - 0.144021, 0.488592, 0.118322, 0.333272, - 0.154382, 0.496461, 0.131133, 0.344224, - 0.165015, 0.50562, 0.145208, 0.357733, - 0.176168, 0.516719, 0.16073, 0.373046, - 0.187468, 0.528513, 0.177807, 0.38788, - 0.198488, 0.537713, 0.196072, 0.405133, - 0.209545, 0.547999, 0.21605, 0.423845, - 0.220724, 0.55759, 0.237484, 0.443777, - 0.231518, 0.566246, 0.26039, 0.464824, - 0.242035, 0.574326, 0.284835, 0.486635, - 0.251898, 0.58037, 0.310518, 0.51012, - 0.261304, 0.58568, 0.337678, 0.535301, - 0.270384, 0.590197, 0.366242, 0.559193, - 0.27841, 0.590569, 0.395873, 0.583544, - 0.285325, 0.588161, 0.426857, 0.608834, - 0.291113, 0.584249, 0.459477, 0.635753, - 0.294882, 0.57763, 0.494734, 0.664367, - 0.297088, 0.569479, 0.532023, 0.689688, - 0.297364, 0.555064, 0.569629, 0.715732, - 0.295949, 0.539522, 0.608124, 0.741307, - 0.292259, 0.521613, 0.646231, 0.764949, - 0.287063, 0.49969, 0.684938, 0.788599, - 0.28012, 0.476747, 0.723548, 0.81048, - 0.27153, 0.45116, 0.761135, 0.831372, - 0.261289, 0.424101, 0.798916, 0.850092, - 0.249559, 0.39443, 0.835952, 0.867777, - 0.236348, 0.363849, 0.871606, 0.884632, - 0.221569, 0.332477, 0.907843, 0.90047, - 0.20618, 0.300667, 0.944187, 0.914524, - 0.188771, 0.266552, 0.981371, 0.926892, - 0.168362, 0.232349, 1.01841, 0.937951, - 0.146761, 0.199359, 1.05308, 0.947236, - 0.123813, 0.1675, 1.0839, 0.954367, - 0.099984, 0.136166, 1.11047, 0.963907, - 0.0759278, 0.103808, 1.13414, 0.976218, - 0.0511367, 0.0697061, 1.15575, 0.988772, - 0.0267415, 0.0352529, 1.17531, 0.999888, - 0.000520778, 0.000289926, 1.19389, 0.263546, - 8.83274e-06, 0.441896, 5.26783e-06, 0.262352, - 0.000221849, 0.439889, 0.000132311, 0.262325, - 0.000886683, 0.439848, 0.000528824, 0.26228, - 0.00199476, 0.439765, 0.00118975, 0.262372, - 0.00354671, 0.439922, 0.00211568, 0.26239, - 0.00554141, 0.439941, 0.00330652, 0.262412, - 0.00797888, 0.439961, 0.00476346, 0.262453, - 0.0108584, 0.440002, 0.00648818, 0.262528, - 0.0141788, 0.440085, 0.0084835, 0.262615, - 0.017938, 0.440166, 0.0107533, 0.262744, - 0.0221346, 0.440291, 0.0133044, 0.262939, - 0.026762, 0.440493, 0.0161445, 0.263277, - 0.0317573, 0.440889, 0.0192974, 0.26368, - 0.0371832, 0.441338, 0.0227699, 0.264106, - 0.0430371, 0.441753, 0.0265698, 0.264624, - 0.0493035, 0.442227, 0.0307178, 0.265378, - 0.0558669, 0.442985, 0.0352616, 0.266253, - 0.0628718, 0.443795, 0.0401968, 0.267478, - 0.0701569, 0.445008, 0.04559, 0.269062, - 0.077845, 0.446599, 0.0514539, 0.270926, - 0.0857941, 0.448349, 0.0578382, 0.273693, - 0.0940773, 0.451221, 0.0648363, 0.276746, - 0.102704, 0.454097, 0.0724389, 0.281693, - 0.111735, 0.459517, 0.0808744, 0.287335, - 0.121004, 0.46531, 0.0901551, 0.29448, - 0.130734, 0.472605, 0.100371, 0.30257, - 0.140777, 0.480251, 0.111644, 0.312465, - 0.15111, 0.489444, 0.124111, 0.324856, - 0.16189, 0.500919, 0.137979, 0.33774, - 0.172946, 0.511317, 0.153163, 0.35255, - 0.184152, 0.522684, 0.169817, 0.367786, - 0.19522, 0.53248, 0.187886, 0.385474, - 0.20632, 0.543326, 0.207634, 0.404976, - 0.217744, 0.554109, 0.229165, 0.425203, - 0.228691, 0.563395, 0.252068, 0.446704, - 0.239299, 0.571565, 0.276471, 0.468951, - 0.249348, 0.577935, 0.302323, 0.493487, - 0.258933, 0.584309, 0.329882, 0.517861, - 0.268009, 0.58773, 0.358525, 0.543309, - 0.276238, 0.589612, 0.388585, 0.569704, - 0.28356, 0.589294, 0.419787, 0.594871, - 0.289497, 0.585137, 0.452114, 0.622555, - 0.294452, 0.580356, 0.486466, 0.651167, - 0.296918, 0.57185, 0.523079, 0.677332, - 0.297647, 0.558428, 0.5611, 0.703718, - 0.296321, 0.542232, 0.599592, 0.730262, - 0.293339, 0.524541, 0.639138, 0.754304, - 0.288036, 0.502691, 0.677978, 0.778051, - 0.281018, 0.479212, 0.716537, 0.801557, - 0.272414, 0.454071, 0.75586, 0.822559, - 0.262419, 0.425952, 0.794477, 0.843051, - 0.250702, 0.397313, 0.832664, 0.86232, - 0.237264, 0.366534, 0.869876, 0.879044, - 0.222716, 0.334816, 0.906973, 0.896362, - 0.206827, 0.303143, 0.943558, 0.910342, - 0.189659, 0.269699, 0.979759, 0.924119, - 0.171108, 0.236411, 1.01718, 0.935374, - 0.149579, 0.202224, 1.05289, 0.944295, - 0.126295, 0.16989, 1.08496, 0.952227, - 0.101511, 0.138089, 1.11256, 0.962041, - 0.0766392, 0.105053, 1.1375, 0.97528, - 0.0511967, 0.070329, 1.15983, 0.988476, - 0.025463, 0.0351268, 1.17987, 0.999962, 2.86808e-05, 1.45564e-05, 1.19901, 0.227089, - 8.41413e-06, 0.404216, 4.72707e-06, 0.239725, - 0.000215083, 0.426708, 0.000120833, 0.239904, - 0.000860718, 0.427028, 0.000483555, 0.239911, - 0.00193661, 0.427039, 0.00108806, 0.239914, - 0.00344276, 0.42704, 0.00193457, 0.239933, - 0.00537907, 0.427064, 0.00302363, 0.239944, - 0.00774482, 0.427065, 0.00435604, 0.239993, - 0.01054, 0.427122, 0.00593398, 0.240052, - 0.0137626, 0.427179, 0.00775987, 0.240148, - 0.0174115, 0.427279, 0.00983854, 0.240278, - 0.021484, 0.42741, 0.0121763, 0.240472, - 0.0259729, 0.427618, 0.0147827, 0.240839, - 0.0308131, 0.428086, 0.0176837, 0.241201, - 0.0360893, 0.428482, 0.0208775, 0.241626, - 0.0417723, 0.428907, 0.0243821, 0.242207, - 0.0478337, 0.42952, 0.0282228, 0.24298, - 0.0542199, 0.430332, 0.0324333, 0.243881, - 0.0610015, 0.431222, 0.0370252, 0.245123, - 0.0680874, 0.432512, 0.0420535, 0.24667, - 0.0755482, 0.434088, 0.0475414, 0.248779, - 0.0832873, 0.436323, 0.0535542, 0.251665, - 0.0913546, 0.439509, 0.0601716, 0.255305, - 0.0998489, 0.443478, 0.0674282, 0.260049, - 0.108576, 0.448713, 0.0754673, 0.266192, - 0.117754, 0.455524, 0.084339, 0.273158, - 0.127294, 0.4627, 0.0941683, 0.282131, - 0.137311, 0.472068, 0.10515, 0.293332, - 0.147736, 0.483565, 0.117402, 0.304667, - 0.158357, 0.493702, 0.130824, 0.317785, - 0.169274, 0.504708, 0.145724, 0.333245, - 0.180595, 0.517107, 0.16215, 0.349843, - 0.191892, 0.528849, 0.180149, 0.367944, - 0.203168, 0.540301, 0.199746, 0.387579, - 0.214443, 0.551514, 0.221047, 0.408247, - 0.225624, 0.560906, 0.243981, 0.43014, - 0.236422, 0.56959, 0.268513, 0.452669, - 0.24654, 0.576098, 0.294409, 0.476196, - 0.256157, 0.580925, 0.322002, 0.501157, - 0.265289, 0.584839, 0.351052, 0.527632, - 0.273671, 0.587614, 0.3812, 0.555754, - 0.281254, 0.589119, 0.412994, 0.581682, - 0.287448, 0.585204, 0.445498, 0.608196, - 0.292614, 0.579006, 0.479505, 0.635661, - 0.296068, 0.571297, 0.514643, 0.664999, - 0.297395, 0.560855, 0.552213, 0.691039, - 0.296645, 0.544525, 0.591365, 0.7179, - 0.293785, 0.526535, 0.630883, 0.744059, - 0.289089, 0.50545, 0.670932, 0.76863, - 0.282239, 0.482514, 0.710904, 0.793273, - 0.273688, 0.457246, 0.750259, 0.814731, - 0.26328, 0.428872, 0.78948, 0.835603, - 0.251526, 0.399384, 0.828597, 0.85489, - 0.238339, 0.368811, 0.866892, 0.872828, - 0.223607, 0.336617, 0.90563, 0.889462, - 0.207538, 0.303997, 0.943538, 0.904929, - 0.190297, 0.270812, 0.980591, 0.919101, - 0.172034, 0.237453, 1.01935, 0.930536, - 0.152058, 0.204431, 1.05498, 0.941223, - 0.129515, 0.172495, 1.08717, 0.94982, - 0.104263, 0.140175, 1.11551, 0.960592, - 0.0781944, 0.106465, 1.14098, 0.974629, - 0.051688, 0.0711592, 1.16418, 0.98811, - 0.0253929, 0.0354432, 1.18465, 1.00004, 0.000804378, - 0.000330876, 1.20462, 0.214668, - 8.21282e-06, 0.406619, 4.33582e-06, 0.218053, - 0.000208144, 0.413025, 0.000109887, 0.217987, - 0.000832212, 0.412901, 0.000439362, 0.217971, - 0.00187246, 0.412876, 0.000988623, 0.217968, - 0.00332855, 0.41286, 0.00175772, 0.217985, - 0.00520055, 0.412882, 0.00274729, 0.218014, - 0.00748814, 0.412916, 0.00395842, 0.218054, - 0.0101901, 0.412957, 0.00539274, 0.218106, - 0.0133057, 0.413005, 0.00705348, 0.218217, - 0.0168342, 0.413139, 0.00894581, 0.218338, - 0.0207707, 0.413258, 0.0110754, 0.21855, - 0.0251001, 0.413509, 0.0134551, 0.218913, - 0.0297861, 0.413992, 0.0161081, 0.219265, - 0.0348956, 0.414383, 0.0190307, 0.219696, - 0.0403909, 0.414839, 0.0222458, 0.220329, - 0.0462003, 0.415567, 0.025792, 0.220989, - 0.0524208, 0.41621, 0.0296637, 0.222027, - 0.058948, 0.417385, 0.0339323, 0.223301, - 0.0658208, 0.418779, 0.0386055, 0.224988, - 0.0730347, 0.420665, 0.0437355, 0.227211, - 0.0805274, 0.423198, 0.0493844, 0.230131, - 0.088395, 0.426566, 0.0556135, 0.233908, - 0.0966208, 0.43091, 0.0624829, 0.239092, - 0.105223, 0.437148, 0.0701636, 0.245315, - 0.11424, 0.444302, 0.0786949, 0.253166, - 0.12368, 0.453262, 0.0882382, 0.262374, - 0.133569, 0.463211, 0.0988682, 0.273145, - 0.143836, 0.474271, 0.110727, 0.285512, - 0.154577, 0.4863, 0.123945, 0.299512, - 0.165501, 0.498817, 0.138581, 0.314287, - 0.176698, 0.510341, 0.154676, 0.331083, - 0.188066, 0.522583, 0.172459, 0.349615, - 0.199597, 0.534879, 0.191979, 0.369318, - 0.210843, 0.546083, 0.21309, 0.390377, - 0.222068, 0.5562, 0.235998, 0.412411, - 0.233059, 0.564704, 0.260518, 0.435715, - 0.24357, 0.572314, 0.286795, 0.461196, - 0.253356, 0.579395, 0.314559, 0.485587, - 0.262362, 0.581985, 0.343581, 0.511908, - 0.270895, 0.584347, 0.374367, 0.539798, - 0.278452, 0.58505, 0.406015, 0.567974, - 0.284877, 0.583344, 0.439168, 0.594303, - 0.290124, 0.577348, 0.473005, 0.622951, - 0.294183, 0.570751, 0.508534, 0.652404, - 0.296389, 0.561541, 0.544764, 0.679291, - 0.296605, 0.546426, 0.582927, 0.706437, - 0.294095, 0.528599, 0.622681, 0.734485, - 0.28978, 0.508676, 0.663567, 0.758841, - 0.283363, 0.484768, 0.704092, 0.78537, - 0.275015, 0.460434, 0.745101, 0.807315, - 0.264689, 0.432166, 0.784712, 0.8271, - 0.252597, 0.401807, 0.824241, 0.849191, - 0.239154, 0.371458, 0.863803, 0.867046, - 0.224451, 0.338873, 0.903063, 0.8852, - 0.208342, 0.306175, 0.942763, 0.901771, - 0.190684, 0.272759, 0.981559, 0.915958, - 0.172105, 0.239306, 1.02048, 0.928046, - 0.152214, 0.206071, 1.05765, 0.939961, - 0.130247, 0.17367, 1.08999, 0.948711, - 0.10672, 0.142201, 1.11829, 0.959305, - 0.0808688, 0.108454, 1.14467, 0.973009, - 0.0539145, 0.0728109, 1.16839, 0.987631, - 0.0262947, 0.0360625, 1.19004, 0.999978, 0.00132758, - 0.000559424, 1.21058, 0.193925, - 7.93421e-06, 0.391974, 3.92537e-06, 0.196746, - 0.000200315, 0.397675, 9.91033e-05, 0.19667, - 0.000801099, 0.397521, 0.000396342, 0.196633, - 0.00180246, 0.397445, 0.000891829, 0.196654, - 0.00320443, 0.397482, 0.00158582, 0.196659, - 0.00500647, 0.39748, 0.00247867, 0.196683, - 0.0072086, 0.397506, 0.00357167, 0.196728, - 0.00981001, 0.397562, 0.00486675, 0.196792, - 0.0128096, 0.397633, 0.00636707, 0.19689, - 0.0162055, 0.397746, 0.00807752, 0.197017, - 0.0199943, 0.397884, 0.0100052, 0.19729, - 0.024139, 0.39827, 0.0121691, 0.197583, - 0.0286671, 0.398639, 0.0145755, 0.197927, - 0.0335858, 0.399034, 0.0172355, 0.198383, - 0.0388806, 0.399554, 0.0201718, 0.199002, - 0.0444736, 0.400289, 0.0234194, 0.199739, - 0.0504583, 0.401111, 0.026984, 0.200784, - 0.056729, 0.402349, 0.0309217, 0.202075, - 0.0633643, 0.403841, 0.0352496, 0.203898, - 0.0703247, 0.406076, 0.0400313, 0.206199, - 0.0775565, 0.408841, 0.0453282, 0.209252, - 0.085184, 0.41259, 0.0511794, 0.213638, - 0.0931994, 0.418288, 0.0577459, 0.21881, - 0.101617, 0.424681, 0.0650508, 0.225642, - 0.11052, 0.433429, 0.0732759, 0.233717, - 0.119772, 0.442897, 0.0824683, 0.242823, - 0.129505, 0.452888, 0.0927484, 0.254772, - 0.139906, 0.466407, 0.104417, 0.266603, - 0.150402, 0.477413, 0.117211, 0.28073, - 0.161395, 0.490519, 0.131598, 0.295399, - 0.172465, 0.50201, 0.147407, 0.312705, - 0.183982, 0.515311, 0.165031, 0.331335, - 0.195532, 0.52786, 0.184336, 0.351037, - 0.206971, 0.5392, 0.205361, 0.372175, - 0.218117, 0.54941, 0.228043, 0.394548, - 0.229327, 0.558642, 0.25267, 0.419598, - 0.240052, 0.567861, 0.279071, 0.443922, - 0.249937, 0.573332, 0.306882, 0.471495, - 0.259407, 0.58013, 0.33661, 0.496769, - 0.267749, 0.580564, 0.367328, 0.524951, - 0.275524, 0.581696, 0.399753, 0.55318, - 0.282148, 0.579885, 0.433134, 0.581577, - 0.287533, 0.575471, 0.467534, 0.609231, - 0.291612, 0.567445, 0.502943, 0.637478, - 0.293911, 0.557657, 0.53871, 0.667795, - 0.295096, 0.546535, 0.576568, 0.694272, - 0.294073, 0.529561, 0.614929, 0.722937, - 0.290386, 0.510561, 0.655909, 0.749682, - 0.284481, 0.487846, 0.697663, 0.774754, - 0.276188, 0.462487, 0.738515, 0.799301, - 0.266215, 0.43481, 0.779802, 0.820762, - 0.254116, 0.404879, 0.820045, 0.843231, - 0.240393, 0.374559, 0.860294, 0.861857, - 0.225503, 0.341582, 0.900965, 0.880815, - 0.209382, 0.308778, 0.941727, 0.89766, - 0.19155, 0.275232, 0.980916, 0.912926, - 0.172346, 0.240938, 1.02162, 0.926391, - 0.151799, 0.207223, 1.0597, 0.938429, - 0.129968, 0.17484, 1.09291, 0.947834, - 0.10651, 0.142984, 1.12248, 0.958432, - 0.0824098, 0.109902, 1.149, 0.972402, - 0.0565242, 0.0744454, 1.1733, 0.987191, - 0.028427, 0.0373794, 1.19538, 0.999975, 3.85685e-05, - 4.203e-05, 1.21676, 0.178114, - 7.66075e-06, 0.385418, 3.54027e-06, 0.176074, - 0.000191966, 0.381002, 8.87135e-05, 0.17601, - 0.000767549, 0.380861, 0.000354715, 0.17598, - 0.00172696, 0.380798, 0.000798168, 0.175994, - 0.00307012, 0.380824, 0.00141928, 0.176017, - 0.00479684, 0.380858, 0.00221859, 0.176019, - 0.00690648, 0.380839, 0.00319714, 0.176072, - 0.00939888, 0.380913, 0.0043572, 0.176131, - 0.0122726, 0.380979, 0.005702, 0.176239, - 0.0155264, 0.38112, 0.00723689, 0.176371, - 0.0191551, 0.381272, 0.00896907, 0.176638, - 0.023117, 0.381669, 0.0109194, 0.176912, - 0.0274633, 0.382015, 0.0130903, 0.177279, - 0.032173, 0.382476, 0.0154949, 0.17774, - 0.0372219, 0.383041, 0.0181669, 0.178344, - 0.0426132, 0.38378, 0.0211209, 0.179153, - 0.0483309, 0.384773, 0.0243899, 0.180197, - 0.0543447, 0.386076, 0.0280062, 0.181581, - 0.0607122, 0.387809, 0.032004, 0.18344, - 0.0673855, 0.390205, 0.036453, 0.186139, - 0.0743989, 0.393944, 0.0414162, 0.189432, - 0.0817731, 0.39832, 0.0469394, 0.193795, - 0.0895464, 0.404188, 0.0531442, 0.199641, - 0.0978264, 0.4121, 0.0601374, 0.206679, - 0.106499, 0.421425, 0.0680078, 0.214865, - 0.115654, 0.431504, 0.076919, 0.224406, - 0.125268, 0.442526, 0.0868835, 0.235876, - 0.135475, 0.455465, 0.0981875, 0.248335, - 0.146023, 0.4681, 0.110759, 0.262868, - 0.157016, 0.482069, 0.124885, 0.278962, - 0.168245, 0.496182, 0.140645, 0.295082, - 0.17958, 0.507401, 0.157838, 0.313738, - 0.191227, 0.520252, 0.17695, 0.333573, - 0.202718, 0.531708, 0.197817, 0.356433, - 0.214424, 0.544509, 0.220785, 0.378853, - 0.225492, 0.55373, 0.245306, 0.402717, - 0.236236, 0.561348, 0.271593, 0.428375, - 0.246568, 0.568538, 0.299776, 0.454724, - 0.255941, 0.573462, 0.329433, 0.482291, - 0.264511, 0.576356, 0.360598, 0.509706, - 0.272129, 0.576446, 0.393204, 0.538805, - 0.278979, 0.575298, 0.427227, 0.568919, - 0.284528, 0.572154, 0.462157, 0.596804, - 0.288801, 0.564691, 0.497997, 0.625987, - 0.291334, 0.555134, 0.534467, 0.656414, - 0.292722, 0.545051, 0.571736, 0.683916, - 0.292185, 0.528813, 0.610158, 0.711809, - 0.290043, 0.51106, 0.649061, 0.739547, - 0.285246, 0.490103, 0.690081, 0.766914, - 0.277647, 0.465523, 0.732554, 0.791375, - 0.267603, 0.437718, 0.773982, 0.814772, - 0.256109, 0.40882, 0.81609, 0.836691, - 0.242281, 0.377823, 0.856849, 0.856984, - 0.227155, 0.34496, 0.898363, 0.876332, - 0.210395, 0.311335, 0.939471, 0.894988, - 0.192612, 0.277703, 0.980799, 0.911113, - 0.173236, 0.243019, 1.02215, 0.924092, - 0.152258, 0.209037, 1.06139, 0.936828, - 0.129575, 0.175909, 1.09635, 0.946869, - 0.10594, 0.143852, 1.12707, 0.958284, - 0.081318, 0.110289, 1.15419, 0.972325, - 0.0556133, 0.0747232, 1.17909, 0.986878, - 0.0297899, 0.0383149, 1.20163, 0.999936, - 0.00197169, 0.000912402, 1.22338, 0.151174, - 7.20365e-06, 0.351531, 3.09789e-06, 0.155594, - 0.00018279, 0.361806, 7.8608e-05, 0.156099, - 0.000731569, 0.362982, 0.000314615, 0.156053, - 0.00164578, 0.362869, 0.000707845, 0.156093, - 0.0029261, 0.362961, 0.00125884, 0.156099, - 0.00457155, 0.362959, 0.00196783, 0.15612, - 0.00658224, 0.362982, 0.00283622, 0.156168, - 0.00895774, 0.363048, 0.00386625, 0.156221, - 0.0116962, 0.363101, 0.00506109, 0.156324, - 0.0147973, 0.363241, 0.00642675, 0.156476, - 0.0182503, 0.363448, 0.00797175, 0.156731, - 0.0220266, 0.36384, 0.00971484, 0.156994, - 0.026176, 0.364179, 0.0116575, 0.157341, - 0.0306701, 0.36462, 0.0138207, 0.157867, - 0.0354591, 0.365364, 0.0162356, 0.15846, - 0.0406141, 0.366111, 0.0189092, 0.159308, - 0.0460519, 0.367248, 0.021885, 0.160426, - 0.0518096, 0.368767, 0.0252004, 0.161877, - 0.0578906, 0.370745, 0.0288825, 0.163995, - 0.0642812, 0.373831, 0.0330139, 0.16655, - 0.0710067, 0.377366, 0.0376283, 0.170237, - 0.0781522, 0.382799, 0.0428493, 0.175096, - 0.0857172, 0.389915, 0.0487324, 0.181069, - 0.0938025, 0.398487, 0.0554214, 0.188487, - 0.102363, 0.408799, 0.0630189, 0.197029, - 0.111343, 0.419991, 0.071634, 0.206684, - 0.120812, 0.431455, 0.0812797, 0.218698, - 0.131033, 0.445746, 0.0923651, 0.230726, - 0.141373, 0.457471, 0.104545, 0.245516, - 0.152387, 0.472388, 0.118449, 0.261551, - 0.163628, 0.486671, 0.133923, 0.277437, - 0.174814, 0.49762, 0.150849, 0.296662, - 0.186713, 0.51162, 0.169924, 0.31795, - 0.198513, 0.525435, 0.190848, 0.339422, - 0.210119, 0.536267, 0.213504, 0.362143, - 0.221354, 0.545982, 0.237947, 0.387198, - 0.23224, 0.555364, 0.264427, 0.412349, - 0.24257, 0.561489, 0.292519, 0.439274, - 0.252284, 0.566903, 0.322561, 0.466779, - 0.261023, 0.569614, 0.353952, 0.496011, - 0.26899, 0.571589, 0.387278, 0.524964, - 0.275498, 0.570325, 0.421356, 0.556518, - 0.281449, 0.568792, 0.457314, 0.584363, - 0.285526, 0.560268, 0.493199, 0.614214, - 0.28844, 0.55205, 0.530276, 0.645684, - 0.289777, 0.541906, 0.56855, 0.673446, - 0.289722, 0.526464, 0.606927, 0.701924, - 0.287792, 0.509872, 0.645945, 0.73037, - 0.284315, 0.490649, 0.685564, 0.757405, - 0.278804, 0.467964, 0.726511, 0.784025, - 0.269543, 0.441468, 0.768601, 0.808255, - 0.258117, 0.41216, 0.811321, 0.830739, - 0.244728, 0.380606, 0.853496, 0.851914, - 0.229428, 0.348111, 0.895374, 0.872586, - 0.212508, 0.314732, 0.937674, 0.891581, - 0.194025, 0.280338, 0.979869, 0.907641, - 0.174711, 0.245203, 1.02253, 0.922233, - 0.153509, 0.21077, 1.06371, 0.935878, - 0.130418, 0.177399, 1.09972, 0.946338, - 0.105558, 0.144507, 1.13124, 0.957265, - 0.080059, 0.110508, 1.15973, 0.971668, - 0.0539766, 0.0742311, 1.18515, 0.9866, - 0.0277101, 0.0375224, 1.20858, 1.00021, - 0.000515531, 0.000135226, 1.23135, 0.137468, - 6.86011e-06, 0.345041, 2.73315e-06, 0.13703, - 0.000173378, 0.343936, 6.90761e-05, 0.136986, - 0.000693048, 0.34383, 0.000276126, 0.136964, - 0.00155931, 0.343761, 0.000621337, 0.137003, - 0.00277211, 0.343863, 0.00110494, 0.137012, - 0.00433103, 0.343868, 0.00172744, 0.137043, - 0.00623606, 0.343916, 0.00249022, 0.13709, - 0.0084868, 0.343986, 0.00339559, 0.137145, - 0.0110814, 0.344045, 0.00444687, 0.137242, - 0.0140187, 0.344177, 0.00565007, 0.137431, - 0.0172713, 0.344491, 0.00701868, 0.137644, - 0.0208605, 0.344805, 0.00856042, 0.13791, - 0.024792, 0.345172, 0.0102863, 0.138295, - 0.0290461, 0.345734, 0.0122185, 0.138764, - 0.0335957, 0.346371, 0.0143771, 0.139415, - 0.038467, 0.347298, 0.0167894, 0.140272, - 0.0436176, 0.348527, 0.0194895, 0.141457, - 0.0491016, 0.350276, 0.0225043, 0.14303, - 0.0548764, 0.352646, 0.0258962, 0.145289, - 0.0610096, 0.356206, 0.0297168, 0.148502, - 0.0674777, 0.361488, 0.0340562, 0.152188, - 0.074345, 0.367103, 0.0389534, 0.157359, - 0.0817442, 0.375247, 0.0445541, 0.16379, - 0.0896334, 0.385064, 0.0509535, 0.171376, - 0.098005, 0.396082, 0.0582611, 0.179901, - 0.106817, 0.407418, 0.06654, 0.189892, - 0.116239, 0.420031, 0.075994, 0.201838, - 0.12627, 0.434321, 0.0867239, 0.214311, - 0.136701, 0.447631, 0.0987517, 0.228902, - 0.147616, 0.462046, 0.112353, 0.245107, - 0.158871, 0.476942, 0.127605, 0.262292, - 0.170261, 0.490285, 0.144469, 0.281215, - 0.182017, 0.503783, 0.163282, 0.301058, - 0.193729, 0.515505, 0.183873, 0.322752, - 0.205512, 0.52682, 0.206466, 0.347547, - 0.217214, 0.539473, 0.231194, 0.370969, - 0.227966, 0.546625, 0.257288, 0.397533, - 0.238555, 0.55472, 0.285789, 0.42398, - 0.248278, 0.559468, 0.315746, 0.452928, - 0.257422, 0.564095, 0.347724, 0.482121, - 0.265306, 0.565426, 0.380922, 0.510438, - 0.272043, 0.563205, 0.415639, 0.541188, - 0.277614, 0.561087, 0.451702, 0.571667, - 0.281927, 0.554922, 0.48845, 0.602432, - 0.285015, 0.546838, 0.526442, 0.634126, - 0.286512, 0.537415, 0.564896, 0.662816, - 0.286388, 0.522906, 0.604037, 0.692411, - 0.284734, 0.507003, 0.643795, 0.720946, - 0.281297, 0.488398, 0.68298, 0.748293, - 0.276262, 0.466353, 0.723466, 0.776931, - 0.269978, 0.443573, 0.764565, 0.801065, - 0.260305, 0.415279, 0.805838, 0.825843, - 0.247426, 0.384773, 0.849985, 0.84807, - 0.232437, 0.352555, 0.893174, 0.869122, - 0.215806, 0.318642, 0.936564, 0.888963, - 0.197307, 0.28381, 0.980253, 0.905547, - 0.177203, 0.247888, 1.02463, 0.918554, - 0.155542, 0.212904, 1.06714, 0.931395, - 0.131948, 0.1787, 1.10451, 0.941749, - 0.106723, 0.145902, 1.13694, 0.954551, - 0.0804939, 0.111193, 1.1666, 0.970279, - 0.0534239, 0.0744697, 1.19249, 0.986117, - 0.0257452, 0.0368788, 1.21665, 0.999938, 0.00190634, - 0.0010291, 1.23981, 0.118493, - 6.47439e-06, 0.32272, 2.3772e-06, 0.118765, - 0.000163023, 0.323456, 5.98573e-05, 0.118772, - 0.00065212, 0.323477, 0.000239447, 0.118843, - 0.00146741, 0.323657, 0.000538881, 0.118804, - 0.00260846, 0.323553, 0.00095826, 0.118826, - 0.00407576, 0.323595, 0.00149845, 0.118846, - 0.00586826, 0.323617, 0.00216047, 0.118886, - 0.00798578, 0.32367, 0.00294679, 0.118947, - 0.0104273, 0.323753, 0.00386124, 0.119055, - 0.0131909, 0.323922, 0.00490999, 0.119241, - 0.0162444, 0.324251, 0.00610804, 0.11944, - 0.0196339, 0.324544, 0.00745805, 0.119739, - 0.0233378, 0.325026, 0.00897805, 0.12011, - 0.0273179, 0.325586, 0.0106895, 0.120571, - 0.0316143, 0.326231, 0.0126073, 0.12124, - 0.0361939, 0.327264, 0.0147654, 0.122162, - 0.0410511, 0.328733, 0.0172001, 0.123378, - 0.0462233, 0.330659, 0.0199375, 0.125183, - 0.0517109, 0.333754, 0.0230498, 0.127832, - 0.0575652, 0.338507, 0.026597, 0.130909, - 0.0637441, 0.343666, 0.0306345, 0.135221, - 0.0704302, 0.351063, 0.035273, 0.14082, - 0.0776364, 0.360604, 0.0406137, 0.146781, - 0.0852293, 0.369638, 0.0466788, 0.155121, - 0.0935351, 0.3827, 0.0537628, 0.16398, - 0.102234, 0.39522, 0.0617985, 0.173926, - 0.111465, 0.40793, 0.07097, 0.185137, - 0.121296, 0.42105, 0.0813426, 0.19826, - 0.13169, 0.435735, 0.0931596, 0.212938, - 0.142614, 0.450932, 0.106547, 0.229046, - 0.153884, 0.465726, 0.121575, 0.246246, - 0.165382, 0.479461, 0.138286, 0.264637, - 0.176806, 0.492106, 0.15666, 0.284959, - 0.188793, 0.504774, 0.17728, 0.308157, - 0.200763, 0.518805, 0.19988, 0.330951, - 0.21239, 0.528231, 0.224293, 0.3549, - 0.223521, 0.536376, 0.250541, 0.381502, - 0.234169, 0.544846, 0.278902, 0.409529, - 0.244077, 0.551717, 0.309227, 0.437523, - 0.253363, 0.55517, 0.341426, 0.467624, - 0.261659, 0.557772, 0.37518, 0.497268, - 0.268498, 0.556442, 0.41007, 0.528294, - 0.274018, 0.553915, 0.446445, 0.559053, - 0.278169, 0.549153, 0.483779, 0.589329, - 0.281229, 0.539878, 0.522249, 0.622503, - 0.282902, 0.53162, 0.561754, 0.652382, - 0.282815, 0.518119, 0.601544, 0.681847, - 0.281247, 0.502187, 0.641574, 0.712285, - 0.277986, 0.484824, 0.682633, 0.740094, - 0.273017, 0.463483, 0.723426, 0.768478, - 0.266692, 0.441299, 0.763747, 0.794556, - 0.258358, 0.415238, 0.805565, 0.819408, - 0.248807, 0.386912, 0.847254, 0.843411, - 0.236214, 0.356165, 0.891091, 0.862397, - 0.219794, 0.320562, 0.936174, 0.883113, - 0.201768, 0.285322, 0.982562, 0.90023, - 0.181672, 0.249713, 1.02862, 0.915192, - 0.159279, 0.214546, 1.07163, 0.928458, - 0.134725, 0.180285, 1.10995, 0.94069, - 0.10913, 0.147119, 1.14354, 0.953409, - 0.0821315, 0.112492, 1.17372, 0.969537, - 0.0542677, 0.0752014, 1.20043, 0.985612, - 0.0259096, 0.0370361, 1.22528, 0.999835, 0.00298198, - 0.00151801, 1.24959, 0.10097, - 6.02574e-06, 0.300277, 2.02619e-06, 0.101577, - 0.000152164, 0.302077, 5.11662e-05, 0.101572, - 0.000608889, 0.302066, 0.000204751, 0.101566, - 0.00136997, 0.302047, 0.000460753, 0.101592, - 0.00243557, 0.302114, 0.000819497, 0.101608, - 0.0038053, 0.30214, 0.00128154, 0.101627, - 0.00547906, 0.30216, 0.0018483, 0.101669, - 0.00745647, 0.302224, 0.00252223, 0.101732, - 0.00973615, 0.302318, 0.00330716, 0.101844, - 0.0123097, 0.302513, 0.00421061, 0.102025, - 0.0151681, 0.30285, 0.00524481, 0.102224, - 0.0183334, 0.303166, 0.0064154, 0.102515, - 0.0217819, 0.303654, 0.00774063, 0.102886, - 0.0255067, 0.304243, 0.0092398, 0.103395, - 0.029514, 0.305089, 0.0109339, 0.104109, - 0.0337912, 0.306301, 0.0128561, 0.105074, - 0.0383565, 0.30798, 0.0150338, 0.10654, - 0.0432132, 0.310726, 0.0175228, 0.108478, - 0.0484244, 0.314351, 0.0203648, 0.111015, - 0.0539339, 0.319032, 0.0236325, 0.114682, - 0.0598885, 0.32605, 0.0274188, 0.11911, - 0.0663375, 0.334109, 0.0317905, 0.124736, - 0.0733011, 0.344013, 0.0368502, 0.131479, - 0.0807744, 0.355358, 0.0427104, 0.139283, - 0.0888204, 0.367614, 0.0494788, 0.148054, - 0.0973394, 0.380072, 0.0572367, 0.159037, - 0.10665, 0.395678, 0.0662704, 0.169794, - 0.116221, 0.40795, 0.0763192, 0.18314, - 0.126632, 0.423546, 0.087956, 0.197515, - 0.137383, 0.438213, 0.101042, 0.213514, - 0.148641, 0.453248, 0.115827, 0.23065, - 0.160117, 0.46688, 0.132283, 0.249148, - 0.171807, 0.479962, 0.150644, 0.270219, - 0.183695, 0.494618, 0.171073, 0.292338, - 0.195574, 0.506937, 0.193378, 0.314999, - 0.207205, 0.516463, 0.217585, 0.340991, - 0.218955, 0.528123, 0.24428, 0.367982, - 0.229917, 0.537025, 0.272784, 0.39432, - 0.239737, 0.541627, 0.302742, 0.423364, - 0.249048, 0.546466, 0.335112, 0.453751, - 0.257329, 0.549466, 0.369032, 0.48416, - 0.264623, 0.549503, 0.404577, 0.515262, - 0.270411, 0.547008, 0.441337, 0.547036, - 0.274581, 0.542249, 0.479162, 0.576614, - 0.277266, 0.533015, 0.517904, 0.611143, - 0.279144, 0.525512, 0.558508, 0.640989, - 0.279001, 0.51154, 0.598995, 0.671182, - 0.277324, 0.495641, 0.639935, 0.700848, - 0.273908, 0.477526, 0.681017, 0.729862, - 0.269063, 0.457955, 0.722764, 0.758273, - 0.262282, 0.434846, 0.764349, 0.784121, - 0.254281, 0.409203, 0.806206, 0.809798, - 0.24505, 0.382694, 0.848617, 0.834953, - 0.233861, 0.354034, 0.892445, 0.856817, - 0.221308, 0.321764, 0.936263, 0.877609, - 0.205996, 0.288118, 0.982401, 0.897489, - 0.186702, 0.253277, 1.02975, 0.913792, - 0.164618, 0.217963, 1.07488, 0.92785, - 0.140023, 0.183221, 1.11487, 0.940378, - 0.11328, 0.149385, 1.14947, 0.95273, - 0.0853958, 0.114152, 1.1807, 0.969059, - 0.0568698, 0.0769845, 1.20912, 0.985574, - 0.0276502, 0.0381186, 1.23498, 0.999943, 0.00239052, - 0.00126861, 1.25987, 0.0852715, - 5.60067e-06, 0.279021, 1.71162e-06, 0.0854143, - 0.000140871, 0.279483, 4.30516e-05, 0.0854191, - 0.000563385, 0.2795, 0.000172184, 0.0854188, - 0.00126753, 0.279493, 0.000387464, 0.0854229, - 0.00225337, 0.279501, 0.00068918, 0.0854443, - 0.00352086, 0.279549, 0.00107803, 0.0854697, - 0.00506962, 0.279591, 0.00155536, 0.0855093, - 0.00689873, 0.279652, 0.00212354, 0.0855724, - 0.00900821, 0.279752, 0.00278703, 0.0856991, - 0.0113799, 0.280011, 0.0035551, 0.085855, - 0.0140314, 0.280297, 0.00443449, 0.0860682, - 0.016963, 0.280682, 0.00543636, 0.086344, - 0.0201438, 0.281159, 0.0065788, 0.0867426, - 0.0235999, 0.281886, 0.00787977, 0.087239, - 0.0273069, 0.282745, 0.0093606, 0.0879815, - 0.031269, 0.284139, 0.011056, 0.0891258, - 0.035531, 0.28647, 0.0130065, 0.0906909, - 0.0400947, 0.289708, 0.0152495, 0.0927624, - 0.0449638, 0.293904, 0.0178454, 0.0958376, - 0.0502427, 0.300471, 0.0208915, 0.0995827, - 0.0559514, 0.30806, 0.0244247, 0.104526, - 0.0622152, 0.317874, 0.0285721, 0.110532, - 0.0690046, 0.329332, 0.0334227, 0.117385, - 0.0763068, 0.341217, 0.0390466, 0.12522, - 0.084184, 0.353968, 0.0455786, 0.134037, - 0.0925248, 0.366797, 0.0530773, 0.144014, - 0.101487, 0.380209, 0.0617424, 0.156013, - 0.111273, 0.395956, 0.071777, 0.168872, - 0.121431, 0.41053, 0.0830905, 0.183089, - 0.132105, 0.425073, 0.0959341, 0.198763, - 0.143286, 0.439833, 0.110448, 0.216159, - 0.154841, 0.454507, 0.126769, 0.234859, - 0.166588, 0.468368, 0.14495, 0.255879, - 0.178626, 0.482846, 0.165233, 0.27677, - 0.190218, 0.493489, 0.187217, 0.301184, - 0.202227, 0.506549, 0.211659, 0.325852, - 0.213764, 0.5158, 0.237922, 0.352824, - 0.22487, 0.525442, 0.26632, 0.380882, - 0.235246, 0.532487, 0.296691, 0.410137, - 0.244847, 0.537703, 0.329179, 0.439787, - 0.253122, 0.540361, 0.363135, 0.472291, - 0.260517, 0.542734, 0.399222, 0.501856, - 0.266519, 0.538826, 0.436352, 0.534816, - 0.270905, 0.535152, 0.474505, 0.565069, - 0.273826, 0.525979, 0.513988, 0.597154, - 0.275333, 0.516394, 0.554852, 0.630473, - 0.275314, 0.506206, 0.596592, 0.660574, - 0.273323, 0.489769, 0.638117, 0.692015, - 0.270008, 0.472578, 0.680457, 0.720647, - 0.265001, 0.452134, 0.723008, 0.750528, - 0.258311, 0.430344, 0.765954, 0.777568, - 0.250046, 0.405624, 0.809012, 0.80387, - 0.240114, 0.378339, 0.852425, 0.828439, - 0.228737, 0.349877, 0.895346, 0.851472, - 0.216632, 0.318968, 0.940695, 0.873906, - 0.202782, 0.287489, 0.987235, 0.89467, - 0.187059, 0.254394, 1.03348, 0.912281, - 0.168818, 0.221294, 1.07812, 0.927358, - 0.146494, 0.18675, 1.11928, 0.940385, - 0.120009, 0.152322, 1.15609, 0.952672, - 0.0917183, 0.117514, 1.18875, 0.968496, - 0.0620321, 0.0797405, 1.21821, 0.985236, - 0.0314945, 0.0402383, 1.24523, 0.99998, - 0.000575153, 0.000110644, 1.27133, 0.0702429, - 5.12222e-06, 0.255273, 1.40947e-06, 0.0702981, - 0.000128826, 0.255469, 3.54488e-05, 0.0703691, - 0.000515562, 0.255727, 0.000141874, 0.0703805, - 0.00116, 0.255754, 0.00031929, 0.0703961, - 0.00206224, 0.255813, 0.000567999, 0.0704102, - 0.00322223, 0.255839, 0.00088871, 0.0704298, - 0.00463928, 0.255863, 0.00128272, 0.0704759, - 0.00631375, 0.255953, 0.00175283, 0.0705434, - 0.00824317, 0.256079, 0.00230342, 0.0706693, - 0.010412, 0.25636, 0.0029443, 0.0708189, - 0.0128439, 0.256647, 0.00368031, 0.0710364, - 0.0155177, 0.257084, 0.00452614, 0.0713223, - 0.0184374, 0.257637, 0.00549706, 0.0717182, - 0.0216002, 0.258416, 0.00661246, 0.072321, - 0.0249966, 0.259699, 0.00790147, 0.0731446, - 0.0286566, 0.261475, 0.0093884, 0.0743352, - 0.0325888, 0.264132, 0.0111186, 0.0760676, - 0.036843, 0.26815, 0.013145, 0.078454, - 0.0414292, 0.273636, 0.0155251, 0.0818618, - 0.0464634, 0.281653, 0.0183525, 0.0857382, - 0.0519478, 0.289992, 0.0216642, 0.0908131, - 0.0579836, 0.30066, 0.0255956, 0.0967512, - 0.0645124, 0.312204, 0.0301954, 0.103717, - 0.0716505, 0.325001, 0.0356017, 0.111596, - 0.0793232, 0.338129, 0.041896, 0.120933, - 0.087645, 0.352853, 0.0492447, 0.130787, - 0.096492, 0.366192, 0.0576749, 0.142311, - 0.105973, 0.380864, 0.0673969, 0.155344, - 0.116182, 0.396575, 0.0785899, 0.169535, - 0.126815, 0.411443, 0.0912377, 0.185173, - 0.138015, 0.426256, 0.105607, 0.201755, - 0.149325, 0.439607, 0.121551, 0.221334, - 0.161207, 0.455467, 0.139608, 0.241461, - 0.173162, 0.469096, 0.159591, 0.26294, - 0.18504, 0.481014, 0.18156, 0.286776, - 0.196881, 0.493291, 0.205781, 0.311596, - 0.208311, 0.503556, 0.231819, 0.338667, - 0.219671, 0.513268, 0.260274, 0.366021, - 0.230451, 0.519414, 0.290862, 0.395875, - 0.240131, 0.526766, 0.323196, 0.425564, - 0.248566, 0.52905, 0.357071, 0.457094, - 0.256195, 0.530796, 0.393262, 0.488286, - 0.262331, 0.528703, 0.430797, 0.522291, - 0.267141, 0.52727, 0.470231, 0.554172, - 0.270411, 0.519848, 0.510477, 0.586427, - 0.271986, 0.510307, 0.551594, 0.619638, - 0.27192, 0.499158, 0.593849, 0.650656, - 0.269817, 0.483852, 0.636314, 0.68284, - 0.266267, 0.467515, 0.679679, 0.714356, - 0.26113, 0.44931, 0.723884, 0.742717, - 0.254067, 0.425789, 0.767245, 0.770894, - 0.245652, 0.401144, 0.811819, 0.797358, - 0.235554, 0.374224, 0.856315, 0.823377, - 0.223896, 0.346167, 0.901077, 0.847456, - 0.210865, 0.316056, 0.946502, 0.870697, - 0.196574, 0.284503, 0.993711, 0.891068, - 0.180814, 0.251628, 1.04134, 0.909267, - 0.163314, 0.219065, 1.08609, 0.925653, - 0.143304, 0.186446, 1.12702, 0.940017, - 0.121322, 0.153416, 1.16371, 0.952398, - 0.0973872, 0.120334, 1.19712, 0.967568, - 0.0698785, 0.08352, 1.22791, 0.984772, - 0.0390031, 0.0439209, 1.25672, 1.00026, - 0.0070087, 0.00315668, 1.28428, 0.0556653, - 4.59654e-06, 0.227325, 1.12556e-06, 0.0565238, - 0.000116382, 0.230826, 2.84985e-05, 0.0565717, - 0.000465666, 0.231026, 0.000114036, 0.0565859, - 0.00104773, 0.231079, 0.000256656, 0.0565761, - 0.00186255, 0.231025, 0.00045663, 0.0565913, - 0.00291002, 0.231058, 0.000714664, 0.0566108, - 0.00418998, 0.231085, 0.00103224, 0.0566532, - 0.00570206, 0.231169, 0.00141202, 0.0567473, - 0.00743666, 0.231417, 0.00186018, 0.0568567, - 0.00940298, 0.231661, 0.00238264, 0.0569859, - 0.0115991, 0.231895, 0.00298699, 0.0572221, - 0.0140096, 0.232456, 0.00368957, 0.057519, - 0.0166508, 0.233096, 0.00450303, 0.0579534, - 0.01951, 0.234094, 0.00544945, 0.0585922, - 0.0225991, 0.235629, 0.00655564, 0.0595647, - 0.0259416, 0.238106, 0.00785724, 0.0609109, - 0.0295661, 0.241557, 0.00939127, 0.0628751, - 0.0335126, 0.246652, 0.0112198, 0.0656908, - 0.0378604, 0.254091, 0.0134168, 0.0691347, - 0.0426543, 0.262666, 0.0160374, 0.0732165, - 0.0478967, 0.272029, 0.0191514, 0.0782863, - 0.0536716, 0.283007, 0.0228597, 0.0843973, - 0.0600683, 0.295732, 0.0272829, 0.0913598, - 0.0670095, 0.308779, 0.032484, 0.0994407, - 0.0745516, 0.322886, 0.0385886, 0.108189, - 0.082712, 0.336408, 0.0457133, 0.118574, - 0.0914927, 0.351692, 0.0539832, 0.129989, - 0.100854, 0.366502, 0.0635162, 0.142722, - 0.110837, 0.381675, 0.0744386, 0.156654, - 0.121353, 0.3963, 0.0868483, 0.172151, - 0.132414, 0.411477, 0.100963, 0.188712, - 0.143809, 0.42508, 0.116795, 0.208093, - 0.155765, 0.441328, 0.134715, 0.227936, - 0.167608, 0.454328, 0.154396, 0.249495, - 0.179579, 0.467235, 0.176179, 0.27362, - 0.191488, 0.480248, 0.200193, 0.296371, - 0.202618, 0.487886, 0.225775, 0.324234, - 0.214133, 0.499632, 0.25441, 0.353049, - 0.225212, 0.509532, 0.285077, 0.381785, - 0.234875, 0.514265, 0.317047, 0.414038, - 0.244205, 0.521282, 0.351874, 0.445251, - 0.252145, 0.522931, 0.388279, 0.476819, - 0.258433, 0.520947, 0.425825, 0.509209, - 0.263411, 0.517669, 0.465104, 0.542759, - 0.266732, 0.512841, 0.505741, 0.574822, - 0.268263, 0.503317, 0.547611, 0.609324, - 0.268489, 0.493035, 0.590953, 0.641772, - 0.266941, 0.478816, 0.63488, 0.674049, - 0.263297, 0.462863, 0.679072, 0.705071, - 0.257618, 0.442931, 0.723487, 0.734709, - 0.250625, 0.421299, 0.768708, 0.763704, - 0.24179, 0.397085, 0.814375, 0.791818, - 0.231115, 0.370577, 0.859907, 0.817439, - 0.21922, 0.34232, 0.906715, 0.843202, - 0.205658, 0.312627, 0.953943, 0.866639, - 0.190563, 0.280933, 1.00185, 0.888129, - 0.173978, 0.248393, 1.05105, 0.907239, - 0.155485, 0.216007, 1.09704, 0.923893, - 0.134782, 0.183233, 1.13857, 0.938882, - 0.11249, 0.150376, 1.17539, 0.952464, - 0.0890706, 0.117177, 1.20924, 0.968529, - 0.0646523, 0.0813095, 1.24055, 0.984763, - 0.038606, 0.0439378, 1.27018, 1.00053, - 0.01238, 0.00598668, 1.29873, 0.0437928, - 4.09594e-06, 0.204012, 8.79224e-07, 0.0440166, - 0.000103395, 0.205049, 2.21946e-05, 0.0440529, - 0.000413633, 0.205225, 8.87981e-05, 0.0440493, - 0.000930594, 0.2052, 0.000199858, 0.0439884, - 0.00165352, 0.204901, 0.000355495, 0.0440716, - 0.0025849, 0.205255, 0.000556983, 0.0440968, - 0.00372222, 0.205311, 0.000805326, 0.0441359, - 0.00506478, 0.205391, 0.00110333, 0.0442231, - 0.00660384, 0.205638, 0.00145768, 0.0443254, - 0.00835246, 0.205877, 0.00187275, 0.0444832, - 0.0102992, 0.20627, 0.00235938, 0.0447001, - 0.0124449, 0.206796, 0.0029299, 0.0450168, - 0.0147935, 0.207593, 0.0036005, 0.0454816, - 0.017336, 0.208819, 0.00439246, 0.0462446, - 0.0201156, 0.211036, 0.00533864, 0.0473694, - 0.0231568, 0.214388, 0.00646984, 0.0490191, - 0.0264941, 0.219357, 0.00783856, 0.0512776, - 0.030184, 0.226061, 0.00950182, 0.0541279, - 0.0342661, 0.234094, 0.0115156, 0.0578989, - 0.0388539, 0.244297, 0.0139687, 0.0620835, - 0.0438735, 0.254457, 0.0169015, 0.0673497, - 0.04951, 0.266706, 0.0204554, 0.0731759, - 0.0556263, 0.278753, 0.0246606, 0.0803937, - 0.0624585, 0.29309, 0.0297126, 0.0879287, - 0.0697556, 0.305856, 0.0355868, 0.0970669, - 0.0778795, 0.321059, 0.0425768, 0.106508, - 0.0863541, 0.333873, 0.05056, 0.11776, - 0.0955935, 0.349008, 0.0598972, 0.130081, - 0.105438, 0.363776, 0.0706314, 0.144454, - 0.115899, 0.380112, 0.0828822, 0.1596, - 0.126827, 0.394843, 0.0967611, 0.176097, - 0.138161, 0.409033, 0.112381, 0.194726, - 0.149904, 0.424257, 0.129952, 0.213944, - 0.161675, 0.436945, 0.149333, 0.235516, - 0.173659, 0.450176, 0.170892, 0.260564, - 0.185963, 0.466305, 0.194984, 0.285183, - 0.197582, 0.477328, 0.220805, 0.311095, - 0.208697, 0.486566, 0.248694, 0.338924, - 0.219519, 0.494811, 0.279015, 0.369757, - 0.229766, 0.504065, 0.311725, 0.3996, - 0.238879, 0.507909, 0.345844, 0.430484, - 0.246802, 0.509805, 0.381749, 0.46413, - 0.253924, 0.511436, 0.420251, 0.497077, - 0.259319, 0.508787, 0.459957, 0.530434, - 0.263297, 0.50394, 0.501356, 0.565725, - 0.265619, 0.49804, 0.544252, 0.599254, - 0.265842, 0.487346, 0.587856, 0.631251, - 0.263978, 0.472975, 0.631969, 0.663972, - 0.26043, 0.457135, 0.677471, 0.697724, - 0.255358, 0.439844, 0.723744, 0.727725, - 0.248308, 0.417872, 0.770653, 0.756417, - 0.239181, 0.39273, 0.817357, 0.785419, - 0.22814, 0.367839, 0.864221, 0.81266, - 0.215681, 0.339449, 0.912701, 0.839391, - 0.201623, 0.309279, 0.962419, 0.86366, - 0.185624, 0.278029, 1.0122, 0.885028, - 0.16797, 0.245294, 1.06186, 0.904639, - 0.148336, 0.212689, 1.10934, 0.922048, - 0.12637, 0.179616, 1.15063, 0.936952, - 0.102928, 0.146749, 1.18885, 0.951895, - 0.0785268, 0.112733, 1.22352, 0.967198, - 0.0530153, 0.0760056, 1.25681, 0.984405, - 0.02649, 0.0383183, 1.28762, 1.00021, 0.00070019, - 0.00020039, 1.31656, 0.0325964, - 3.55447e-06, 0.176706, 6.55682e-07, 0.0329333, - 8.99174e-05, 0.178527, 1.65869e-05, 0.0329181, - 0.000359637, 0.178453, 6.63498e-05, 0.0329085, - 0.000808991, 0.178383, 0.000149332, 0.0329181, - 0.00143826, 0.178394, 0.000265873, 0.0329425, - 0.00224678, 0.178517, 0.000416597, 0.0329511, - 0.00323575, 0.17849, 0.000603299, 0.033011, - 0.00439875, 0.178695, 0.000829422, 0.0330733, - 0.00574059, 0.178843, 0.00109908, 0.0331857, - 0.00725896, 0.179176, 0.00141933, 0.0333445, - 0.00895289, 0.179618, 0.0017999, 0.0335674, - 0.0108219, 0.180238, 0.00225316, 0.033939, - 0.0128687, 0.181417, 0.00279765, 0.0345239, - 0.015114, 0.183395, 0.0034564, 0.0354458, - 0.017596, 0.186616, 0.00425864, 0.0368313, - 0.0203524, 0.191547, 0.00524936, 0.0386115, - 0.0234105, 0.197508, 0.00647033, 0.0410303, - 0.0268509, 0.205395, 0.00798121, 0.0442245, - 0.0307481, 0.215365, 0.0098557, 0.0478659, - 0.0350863, 0.225595, 0.0121417, 0.0522416, - 0.0399506, 0.236946, 0.0149385, 0.0574513, - 0.045357, 0.249442, 0.0183189, 0.0631208, - 0.0512863, 0.261222, 0.0223644, 0.0701124, - 0.0579273, 0.275418, 0.0272418, 0.0777331, - 0.0650652, 0.288989, 0.0329458, 0.0862709, - 0.0728813, 0.302546, 0.0396819, 0.096103, - 0.081363, 0.317164, 0.04757, 0.106976, - 0.0904463, 0.331733, 0.0567012, 0.119175, - 0.100105, 0.34661, 0.067202, 0.132919, - 0.110375, 0.362249, 0.0792588, 0.147727, - 0.121115, 0.376978, 0.0928672, 0.163618, - 0.132299, 0.390681, 0.108228, 0.182234, - 0.143887, 0.406571, 0.125502, 0.201809, - 0.155827, 0.42042, 0.144836, 0.225041, - 0.168357, 0.438411, 0.166706, 0.247621, - 0.18004, 0.450368, 0.189909, 0.27097, - 0.191536, 0.460083, 0.215251, 0.296658, - 0.203024, 0.469765, 0.243164, 0.325892, - 0.214056, 0.481837, 0.273388, 0.35406, - 0.224104, 0.487474, 0.305344, 0.384372, - 0.233489, 0.492773, 0.339741, 0.41749, - 0.241874, 0.498451, 0.376287, 0.45013, - 0.248834, 0.499632, 0.414195, 0.481285, - 0.254658, 0.495233, 0.454077, 0.519183, - 0.259367, 0.496401, 0.496352, 0.551544, - 0.261818, 0.487686, 0.538798, 0.587349, - 0.262964, 0.479453, 0.583626, 0.621679, - 0.262128, 0.467709, 0.629451, 0.654991, - 0.258998, 0.452123, 0.67566, 0.686873, - 0.254119, 0.433495, 0.723248, 0.719801, - 0.246946, 0.413657, 0.771156, 0.750355, - 0.237709, 0.390366, 0.81989, 0.780033, - 0.226549, 0.364947, 0.868601, 0.809254, - 0.214186, 0.337256, 0.920034, 0.836576, - 0.199639, 0.307395, 0.971706, 0.861774, - 0.183169, 0.275431, 1.02479, 0.885707, - 0.165111, 0.243431, 1.07837, 0.904742, - 0.144363, 0.210921, 1.12783, 0.915604, - 0.121305, 0.17647, 1.17254, 0.930959, - 0.0962119, 0.143106, 1.21012, 0.948404, - 0.069969, 0.108112, 1.24474, 0.967012, - 0.0427586, 0.0708478, 1.27718, 0.984183, - 0.0147043, 0.032335, 1.3083, 0.999577, 0.0142165, - 0.00726867, 1.3382, 0.0229227, - 2.99799e-06, 0.148623, 4.62391e-07, 0.0232194, - 7.58796e-05, 0.15054, 1.17033e-05, 0.0232315, - 0.000303636, 0.15063, 4.68397e-05, 0.0232354, - 0.000683189, 0.150624, 0.000105472, 0.0232092, - 0.0012136, 0.150445, 0.000187744, 0.0232523, - 0.00189765, 0.150679, 0.000294847, 0.0232828, - 0.00273247, 0.150789, 0.000428013, 0.0233371, - 0.00371287, 0.150995, 0.000591134, 0.0234015, - 0.00484794, 0.15118, 0.000787642, 0.023514, - 0.00612877, 0.151562, 0.00102547, 0.023679, - 0.00756125, 0.152116, 0.00131351, 0.0239559, - 0.00914651, 0.153162, 0.00166594, 0.0244334, - 0.010904, 0.155133, 0.00210182, 0.025139, - 0.0128615, 0.158035, 0.00264406, 0.0262598, - 0.0150628, 0.162751, 0.00332923, 0.0277875, - 0.0175532, 0.168944, 0.00419773, 0.0298472, - 0.0203981, 0.176835, 0.00530034, 0.0325444, - 0.023655, 0.186686, 0.00669777, 0.0355581, - 0.0272982, 0.196248, 0.00842661, 0.0392841, - 0.0314457, 0.207352, 0.0105854, 0.0436815, - 0.0361157, 0.219279, 0.0132458, 0.0485272, - 0.0412932, 0.230728, 0.0164736, 0.0541574, - 0.0470337, 0.242994, 0.0203715, 0.0609479, - 0.0535002, 0.257042, 0.0250953, 0.0685228, - 0.0605409, 0.27102, 0.0306856, 0.0768042, - 0.0680553, 0.28406, 0.037193, 0.0864844, - 0.0765011, 0.299186, 0.0449795, 0.0969415, - 0.0852674, 0.3132, 0.0538316, 0.108478, - 0.0947333, 0.327138, 0.0641149, 0.121705, - 0.10481, 0.342345, 0.0759185, 0.136743, - 0.115474, 0.358472, 0.0894116, 0.152986, - 0.126536, 0.374067, 0.104562, 0.170397, - 0.138061, 0.388267, 0.121632, 0.191392, - 0.150203, 0.406467, 0.140996, 0.211566, - 0.161751, 0.418641, 0.161696, 0.233567, - 0.173407, 0.430418, 0.184557, 0.257769, - 0.185397, 0.44277, 0.210092, 0.28531, - 0.197048, 0.457191, 0.237827, 0.311726, - 0.20784, 0.464712, 0.267253, 0.340537, - 0.218345, 0.472539, 0.299332, 0.372921, - 0.228306, 0.482331, 0.333988, 0.402924, - 0.236665, 0.484378, 0.369722, 0.434475, - 0.244097, 0.484717, 0.407836, 0.469736, - 0.250547, 0.487093, 0.448465, 0.505045, - 0.25511, 0.485575, 0.490263, 0.540262, - 0.258444, 0.481225, 0.534495, 0.576347, - 0.259903, 0.473481, 0.579451, 0.608656, - 0.259572, 0.4603, 0.625604, 0.646679, - 0.257908, 0.450341, 0.674511, 0.679902, - 0.253663, 0.431561, 0.723269, 0.714159, - 0.247419, 0.412684, 0.773263, 0.745345, - 0.239122, 0.389388, 0.824182, 0.778248, - 0.228837, 0.365361, 0.876634, 0.807208, - 0.216197, 0.337667, 0.92945, 0.835019, - 0.201772, 0.307197, 0.985261, 0.860261, - 0.185291, 0.274205, 1.04299, 0.877601, - 0.165809, 0.240178, 1.09816, 0.898211, - 0.143897, 0.207571, 1.14694, 0.915789, - 0.119513, 0.174904, 1.19008, 0.931831, - 0.0932919, 0.141423, 1.2297, 0.949244, - 0.0656528, 0.105603, 1.26553, 0.967527, - 0.0370262, 0.0679551, 1.29986, 0.984139, - 0.00730117, 0.0283133, 1.33252, 0.999713, 0.0234648, - 0.0121785, 1.36397, 0.0152135, - 2.45447e-06, 0.122795, 3.04092e-07, 0.0151652, - 6.15778e-05, 0.122399, 7.6292e-06, 0.0151181, - 0.000245948, 0.122023, 3.04802e-05, 0.0151203, - 0.000553394, 0.12203, 6.86634e-05, 0.015125, - 0.000983841, 0.122037, 0.000122463, 0.0151427, - 0.00153774, 0.12214, 0.000192706, 0.0151708, - 0.0022103, 0.122237, 0.000281219, 0.0152115, - 0.00300741, 0.12238, 0.000390804, 0.0152877, - 0.00392494, 0.1227, 0.000526317, 0.015412, - 0.00496597, 0.123244, 0.00069443, 0.0156201, - 0.00613314, 0.124228, 0.00090547, 0.0159658, - 0.00744113, 0.125945, 0.0011732, 0.0165674, - 0.00892546, 0.129098, 0.00151888, 0.017487, - 0.010627, 0.133865, 0.00197007, 0.018839, - 0.0126043, 0.140682, 0.0025637, 0.020554, - 0.0148814, 0.148534, 0.00333637, 0.0226727, - 0.0175123, 0.157381, 0.00433738, 0.0251879, - 0.0205266, 0.166685, 0.00561664, 0.0283635, - 0.0240319, 0.177796, 0.00725563, 0.0318694, - 0.0279432, 0.188251, 0.00928811, 0.0361044, - 0.0324313, 0.200038, 0.011835, 0.0406656, - 0.0373527, 0.210685, 0.0149146, 0.0463846, - 0.0430132, 0.224182, 0.0187254, 0.0525696, - 0.0491013, 0.23634, 0.0232283, 0.0598083, - 0.0559175, 0.250013, 0.0286521, 0.0679437, - 0.0633657, 0.263981, 0.0350634, 0.0771181, - 0.0714602, 0.278072, 0.0425882, 0.0881273, - 0.0803502, 0.29511, 0.0514487, 0.0996628, - 0.0896903, 0.309976, 0.0615766, 0.112702, - 0.099644, 0.325611, 0.0732139, 0.126488, - 0.109829, 0.339321, 0.0862324, 0.142625, - 0.120859, 0.35574, 0.101275, 0.15953, - 0.131956, 0.369845, 0.117892, 0.176991, - 0.143145, 0.38146, 0.136205, 0.199715, - 0.155292, 0.40052, 0.157252, 0.220787, - 0.167066, 0.412055, 0.179966, 0.243697, - 0.178396, 0.423133, 0.204418, 0.272106, - 0.190433, 0.439524, 0.232141, 0.297637, - 0.201265, 0.447041, 0.261109, 0.325273, - 0.211834, 0.454488, 0.292627, 0.357219, - 0.221889, 0.465004, 0.326669, 0.387362, - 0.230729, 0.468527, 0.362426, 0.423131, - 0.23924, 0.475836, 0.401533, 0.45543, - 0.246067, 0.475017, 0.441902, 0.493393, - 0.251557, 0.478017, 0.484239, 0.526253, - 0.255571, 0.4709, 0.528586, 0.560554, - 0.257752, 0.463167, 0.574346, 0.599306, - 0.258076, 0.456452, 0.621655, 0.634541, - 0.256471, 0.443725, 0.670492, 0.668907, - 0.253283, 0.428719, 0.721943, 0.705619, - 0.247562, 0.411348, 0.772477, 0.739034, - 0.240626, 0.388939, 0.8264, 0.771408, - 0.231493, 0.36425, 0.881702, 0.803312, - 0.220125, 0.337321, 0.9385, 0.828457, - 0.206645, 0.305364, 0.997437, 0.854819, - 0.190664, 0.273715, 1.05693, 0.878666, - 0.171429, 0.242218, 1.11251, 0.898404, - 0.149235, 0.209556, 1.16398, 0.917416, - 0.12435, 0.176863, 1.21014, 0.933133, - 0.0972703, 0.142775, 1.25178, 0.95066, - 0.0683607, 0.106735, 1.29028, 0.968589, - 0.0378724, 0.0681609, 1.32703, 0.984776, - 0.00605712, 0.0273966, 1.36158, 0.99994, 0.0263276, - 0.0138124, 1.3943, 0.00867437, - 1.86005e-06, 0.0928979, 1.73682e-07, 0.00864003, - 4.66389e-05, 0.0925237, 4.35505e-06, 0.00864593, - 0.000186594, 0.0925806, 1.74322e-05, 0.00864095, - 0.000419639, 0.0924903, 3.92862e-05, 0.00863851, - 0.000746272, 0.0924589, 7.02598e-05, 0.00868531, - 0.00116456, 0.0929, 0.000111188, 0.00869667, - 0.00167711, 0.0928529, 0.000163867, 0.00874332, - 0.00228051, 0.0930914, 0.00023104, 0.00882709, - 0.00297864, 0.0935679, 0.00031741, 0.00898874, - 0.00377557, 0.0946165, 0.000430186, 0.00929346, - 0.00469247, 0.0967406, 0.000580383, 0.00978271, - 0.00575491, 0.100084, 0.000783529, 0.0105746, - 0.00701514, 0.105447, 0.00106304, 0.0116949, - 0.00851797, 0.112494, 0.00144685, 0.0130419, - 0.0102757, 0.119876, 0.00196439, 0.0148375, - 0.012381, 0.129034, 0.00266433, 0.0168725, - 0.01482, 0.137812, 0.00358364, 0.0193689, - 0.0176563, 0.147696, 0.00478132, 0.0222691, - 0.0209211, 0.157795, 0.00631721, 0.0256891, - 0.0246655, 0.168431, 0.00826346, 0.0294686, - 0.0288597, 0.178587, 0.0106714, 0.0340412, - 0.0336441, 0.190251, 0.0136629, 0.0393918, - 0.039033, 0.202999, 0.0173272, 0.0453947, - 0.0450087, 0.215655, 0.0217448, 0.0521936, - 0.0515461, 0.228686, 0.0269941, 0.0600279, - 0.058817, 0.242838, 0.033272, 0.0692398, - 0.0667228, 0.258145, 0.0406457, 0.0793832, - 0.0752401, 0.273565, 0.0492239, 0.0902297, - 0.0841851, 0.287735, 0.0590105, 0.102014, - 0.0936479, 0.301161, 0.0702021, 0.116054, - 0.103967, 0.317438, 0.0832001, 0.13191, - 0.114622, 0.334166, 0.0977951, 0.148239, - 0.125452, 0.348192, 0.113985, 0.165809, - 0.136453, 0.361094, 0.131928, 0.184616, - 0.147648, 0.373534, 0.151811, 0.207491, - 0.159607, 0.39101, 0.174476, 0.230106, - 0.171119, 0.402504, 0.198798, 0.257036, - 0.182906, 0.418032, 0.225796, 0.281172, - 0.193605, 0.425468, 0.254027, 0.312034, - 0.204771, 0.440379, 0.285713, 0.340402, - 0.214988, 0.445406, 0.319196, 0.370231, - 0.224711, 0.44968, 0.35537, 0.407105, - 0.233516, 0.460747, 0.393838, 0.439037, - 0.240801, 0.460624, 0.433747, 0.47781, - 0.24762, 0.465957, 0.477234, 0.510655, - 0.251823, 0.460054, 0.52044, 0.550584, - 0.255552, 0.459172, 0.567853, 0.585872, - 0.257036, 0.450311, 0.615943, 0.620466, - 0.257535, 0.437763, 0.667693, 0.660496, - 0.255248, 0.426639, 0.718988, 0.695578, - 0.251141, 0.409185, 0.772503, 0.732176, - 0.244718, 0.39015, 0.827023, 0.760782, - 0.236782, 0.362594, 0.885651, 0.79422, - 0.225923, 0.33711, 0.943756, 0.824521, - 0.213855, 0.308272, 1.00874, 0.854964, - 0.197723, 0.278529, 1.06764, 0.878065, - 0.179209, 0.246208, 1.12836, 0.899834, - 0.157569, 0.21329, 1.18318, 0.918815, - 0.133206, 0.181038, 1.23161, 0.934934, - 0.106545, 0.146993, 1.27644, 0.952115, - 0.0780574, 0.111175, 1.31842, 0.96906, - 0.0478279, 0.0728553, 1.35839, 0.985178, - 0.0160014, 0.032579, 1.39697, 1.00039, 0.0173126, - 0.0095256, 1.43312, 0.00384146, - 1.24311e-06, 0.0613583, 7.78271e-08, 0.00390023, - 3.14043e-05, 0.0622919, 1.96626e-06, 0.00389971, - 0.000125622, 0.0622632, 7.87379e-06, 0.00389491, - 0.000282352, 0.0620659, 1.778e-05, 0.00391618, - 0.000502512, 0.0624687, 3.20918e-05, 0.00392662, - 0.000784458, 0.0625113, 5.15573e-05, 0.00396053, - 0.00112907, 0.0628175, 7.78668e-05, 0.00401911, - 0.00153821, 0.0633286, 0.000113811, 0.00414994, - 0.0020208, 0.0646443, 0.00016445, 0.00441223, - 0.00260007, 0.0673886, 0.000237734, 0.00484427, - 0.0033097, 0.0716528, 0.000345929, 0.00549109, - 0.00418966, 0.0774998, 0.000505987, 0.00636293, - 0.00527331, 0.0844758, 0.000739208, 0.00746566, - 0.00660428, 0.0921325, 0.00107347, 0.00876625, - 0.00818826, 0.0997067, 0.00153691, 0.0103125, - 0.0100811, 0.107433, 0.00217153, 0.0123309, - 0.0123643, 0.117088, 0.00303427, 0.0146274, - 0.0150007, 0.126438, 0.00416018, 0.0172295, - 0.0180531, 0.135672, 0.00561513, 0.0204248, - 0.0215962, 0.146244, 0.007478, 0.0241597, - 0.0256234, 0.157481, 0.00981046, 0.0284693, - 0.0302209, 0.169125, 0.0127148, 0.033445, - 0.0353333, 0.181659, 0.0162453, 0.0391251, - 0.0410845, 0.1944, 0.0205417, 0.0454721, - 0.0473451, 0.207082, 0.0256333, 0.0530983, - 0.0542858, 0.221656, 0.0317036, 0.0615356, - 0.0618384, 0.236036, 0.0388319, 0.0703363, - 0.0697631, 0.248398, 0.046974, 0.0810391, - 0.0784757, 0.263611, 0.0565246, 0.0920144, - 0.0873488, 0.275857, 0.0671724, 0.105584, - 0.0973652, 0.292555, 0.0798105, 0.119506, - 0.107271, 0.306333, 0.0935945, 0.134434, - 0.117608, 0.318888, 0.109106, 0.153399, - 0.128938, 0.337552, 0.127074, 0.171258, - 0.139944, 0.349955, 0.14643, 0.191059, - 0.151288, 0.361545, 0.168, 0.215069, - 0.163018, 0.378421, 0.192082, 0.237838, - 0.174226, 0.38879, 0.217838, 0.266965, - 0.186063, 0.405857, 0.246931, 0.292827, - 0.196909, 0.414146, 0.277505, 0.324352, - 0.207473, 0.426955, 0.310711, 0.354427, - 0.217713, 0.433429, 0.346794, 0.389854, - 0.227183, 0.443966, 0.385237, 0.420749, - 0.235131, 0.44471, 0.424955, 0.459597, - 0.242786, 0.451729, 0.468446, 0.495316, - 0.248767, 0.45072, 0.513422, 0.534903, - 0.253351, 0.450924, 0.560618, 0.572369, - 0.256277, 0.445266, 0.609677, 0.612383, - 0.2576, 0.438798, 0.660995, 0.644037, - 0.256931, 0.421693, 0.713807, 0.686749, - 0.254036, 0.4109, 0.767616, 0.719814, - 0.249785, 0.390151, 0.82533, 0.754719, - 0.244283, 0.367847, 0.888311, 0.792022, - 0.235076, 0.345013, 0.948177, 0.822404, - 0.225061, 0.316193, 1.01661, 0.853084, - 0.211113, 0.287013, 1.08075, 0.879871, - 0.19449, 0.255424, 1.14501, 0.901655, - 0.174023, 0.222879, 1.20203, 0.919957, - 0.1509, 0.18989, 1.25698, 0.938412, - 0.124923, 0.15606, 1.30588, 0.953471, - 0.0968139, 0.120512, 1.3529, 0.970451, - 0.066734, 0.0828515, 1.3986, 0.985522, - 0.034734, 0.0424458, 1.44148, 1.00099, - 0.00102222, 0.000678929, 1.48398, 0.000965494, - 6.27338e-07, 0.0306409, 1.97672e-08, 0.00099168, - 1.58573e-05, 0.0314638, 4.99803e-07, 0.000991068, - 6.34012e-05, 0.031363, 2.00682e-06, 0.000974567, - 0.00014144, 0.03036, 4.57312e-06, 0.000998079, - 0.000252812, 0.031496, 8.60131e-06, 0.00102243, - 0.000396506, 0.0319955, 1.48288e-05, 0.00107877, - 0.000577593, 0.0331376, 2.49141e-05, 0.00121622, - 0.000816816, 0.0359396, 4.23011e-05, 0.0014455, - 0.00113761, 0.0399652, 7.24613e-05, 0.00178791, - 0.00156959, 0.0450556, 0.000123929, 0.00225668, - 0.00214064, 0.0508025, 0.000208531, 0.00285627, - 0.00287655, 0.0568443, 0.000341969, 0.0035991, - 0.00380271, 0.0630892, 0.000544158, 0.00455524, - 0.00496264, 0.0702204, 0.000842423, 0.00569143, - 0.0063793, 0.0773426, 0.00126704, 0.00716928, - 0.00813531, 0.0860839, 0.00186642, 0.00885307, - 0.0101946, 0.0944079, 0.00267014, 0.0109316, - 0.0126386, 0.103951, 0.00374033, 0.0133704, - 0.0154876, 0.113786, 0.0051304, 0.0161525, - 0.0187317, 0.123477, 0.00688858, 0.0194267, - 0.0224652, 0.133986, 0.00910557, 0.0230967, - 0.0265976, 0.143979, 0.0118074, 0.0273627, - 0.0312848, 0.154645, 0.0151266, 0.0323898, - 0.0365949, 0.166765, 0.0191791, 0.0379225, - 0.0422914, 0.177932, 0.0239236, 0.0447501, - 0.0487469, 0.19167, 0.0296568, 0.0519391, - 0.0556398, 0.203224, 0.0362924, 0.0599464, - 0.0631646, 0.215652, 0.0440585, 0.0702427, - 0.0714308, 0.232089, 0.0531619, 0.0806902, - 0.0800605, 0.245258, 0.0634564, 0.0923194, - 0.0892815, 0.258609, 0.0752481, 0.106938, - 0.09931, 0.276654, 0.0888914, 0.121238, - 0.109575, 0.289847, 0.104055, 0.138817, - 0.120461, 0.307566, 0.121266, 0.15595, - 0.131209, 0.320117, 0.139944, 0.178418, - 0.143049, 0.339677, 0.161591, 0.197875, - 0.154074, 0.349886, 0.184303, 0.224368, - 0.166307, 0.369352, 0.210669, 0.252213, - 0.178051, 0.386242, 0.238895, 0.277321, - 0.189335, 0.395294, 0.269182, 0.310332, - 0.200683, 0.412148, 0.302508, 0.338809, - 0.210856, 0.418266, 0.337264, 0.372678, - 0.220655, 0.428723, 0.374881, 0.405632, - 0.230053, 0.433887, 0.415656, 0.442293, - 0.237993, 0.439911, 0.457982, 0.477256, - 0.244897, 0.440175, 0.502831, 0.515592, - 0.250657, 0.441079, 0.550277, 0.550969, - 0.255459, 0.435219, 0.601102, 0.592883, - 0.257696, 0.432882, 0.651785, 0.629092, - 0.259894, 0.421054, 0.708961, 0.672033, - 0.258592, 0.41177, 0.763806, 0.709147, - 0.256525, 0.395267, 0.824249, 0.745367, - 0.254677, 0.375013, 0.8951, 0.784715, - 0.247892, 0.353906, 0.959317, 0.818107, - 0.240162, 0.327801, 1.03153, 0.847895, - 0.229741, 0.298821, 1.10601, 0.879603, - 0.213084, 0.269115, 1.164, 0.902605, - 0.195242, 0.236606, 1.22854, 0.922788, - 0.174505, 0.203442, 1.29017, 0.944831, - 0.150169, 0.169594, 1.34157, 0.959656, - 0.124099, 0.135909, 1.3956, 0.972399, - 0.0960626, 0.0990563, 1.45128, 0.986549, - 0.0657097, 0.0602348, 1.50312, 1.00013, - 0.0333558, 0.0186694, 1.55364, 6.19747e-06, - 1e-07, 0.00778326, 7.96756e-11, 2.37499e-08, - 9.99999e-08, 2.82592e-05, 1.14596e-10, 1.00292e-06, - 1.66369e-06, 0.000250354, 6.77492e-09, 3.50752e-06, - 6.37769e-06, 0.000357289, 6.31655e-08, 8.26445e-06, - 1.74689e-05, 0.000516179, 3.1851e-07, 2.42481e-05, - 4.50868e-05, 0.0010223, 1.30577e-06, 4.55631e-05, - 8.9044e-05, 0.00144302, 3.74587e-06, 9.71222e-05, - 0.000178311, 0.00241912, 1.02584e-05, 0.000171403, - 0.000313976, 0.00354938, 2.36481e-05, 0.000292747, - 0.000520026, 0.00513765, 4.96014e-05, 0.000789827, - 0.00118187, 0.0238621, 0.000139056, 0.00114093, - 0.00171827, 0.0286691, 0.000244093, 0.00176119, - 0.00249667, 0.0368565, 0.000420623, 0.0022233, - 0.00333742, 0.0400469, 0.00065673, 0.00343382, - 0.00481976, 0.0535751, 0.00109323, 0.00427602, - 0.00600755, 0.057099, 0.00155268, 0.00461435, - 0.00737637, 0.0551084, 0.00215031, 0.00695698, - 0.00971401, 0.0715767, 0.00316529, 0.00867619, - 0.0120943, 0.0793314, 0.00436995, 0.0106694, - 0.0148202, 0.0869391, 0.0058959, 0.0140351, - 0.0183501, 0.101572, 0.00798757, 0.0168939, - 0.022006, 0.11018, 0.0104233, 0.020197, - 0.0261568, 0.119041, 0.0134167, 0.0254702, - 0.0312778, 0.135404, 0.0173009, 0.0298384, - 0.0362469, 0.1437, 0.0215428, 0.035159, - 0.042237, 0.15512, 0.0268882, 0.0427685, - 0.0488711, 0.17128, 0.033235, 0.0494848, - 0.0557997, 0.181813, 0.0404443, 0.0592394, - 0.0635578, 0.198745, 0.0490043, 0.0681463, - 0.071838, 0.210497, 0.0588239, 0.0804753, - 0.0809297, 0.228864, 0.0702835, 0.0942205, - 0.0906488, 0.247008, 0.0834012, 0.106777, - 0.100216, 0.258812, 0.0975952, 0.124471, - 0.110827, 0.278617, 0.114162, 0.138389, - 0.121193, 0.287049, 0.131983, 0.159543, - 0.13253, 0.307151, 0.152541, 0.176432, - 0.143611, 0.31564, 0.174673, 0.201723, - 0.15548, 0.33538, 0.199842, 0.229721, - 0.167166, 0.355256, 0.227097, 0.250206, - 0.178238, 0.360047, 0.256014, 0.282118, - 0.189905, 0.378761, 0.28855, 0.312821, - 0.201033, 0.39181, 0.323348, 0.341482, - 0.211584, 0.397716, 0.360564, 0.377368, - 0.221314, 0.410141, 0.400004, 0.418229, - 0.230474, 0.423485, 0.442371, 0.444881, - 0.239443, 0.418874, 0.488796, 0.488899, - 0.245987, 0.427545, 0.535012, 0.520317, - 0.253948, 0.422147, 0.589678, 0.568566, - 0.256616, 0.42719, 0.637683, 0.599607, - 0.26376, 0.415114, 0.703363, 0.64222, - 0.268687, 0.408715, 0.771363, 0.685698, - 0.2694, 0.399722, 0.83574, 0.732327, - 0.266642, 0.388651, 0.897764, 0.769873, - 0.267712, 0.369198, 0.983312, 0.806733, - 0.263479, 0.346802, 1.06222, 0.843466, - 0.254575, 0.321368, 1.13477, 0.873008, - 0.242749, 0.29211, 1.20712, 0.908438, - 0.22725, 0.262143, 1.27465, 0.936321, - 0.207621, 0.228876, 1.33203, 0.950353, - 0.187932, 0.19484, 1.40439, 0.96442, - 0.165154, 0.163178, 1.4732, 0.979856, - 0.139302, 0.127531, 1.53574, 0.982561, - 0.11134, 0.0903457, 1.59982, 0.996389, - 0.0808124, 0.0489007, 1.6577 ]; - const LTC_MAT_2 = [ 1, 0, 0, 0, 1, 7.91421e-31, 0, 0, 1, 1.04392e-24, 0, 0, 1, 3.49405e-21, 0, 0, 1, 1.09923e-18, 0, 0, 1, 9.47414e-17, 0, 0, 1, 3.59627e-15, 0, 0, 1, 7.72053e-14, 0, 0, 1, 1.08799e-12, 0, 0, 1, 1.10655e-11, 0, 0, 1, 8.65818e-11, 0, 0, 0.999998, 5.45037e-10, 0, 0, 0.999994, 2.85095e-09, 0, 0, 0.999989, 1.26931e-08, 0, 0, 0.999973, 4.89938e-08, 0, 0, 0.999947, 1.66347e-07, 0, 0, 0.999894, 5.02694e-07, 0, 0, 0.999798, 1.36532e-06, 0, 0, 0.999617, 3.35898e-06, 0, 0, 0.999234, 7.52126e-06, 0, 0, 0.998258, 1.52586e-05, 0, 0, 0.99504, 2.66207e-05, 0, 0, 0.980816, 2.36802e-05, 0, 0, 0.967553, 2.07684e-06, 0, 0, 0.966877, 4.03733e-06, 0, 0, 0.965752, 7.41174e-06, 0, 0, 0.96382, 1.27746e-05, 0, 0, 0.960306, 2.02792e-05, 0, 0, 0.953619, 2.80232e-05, 0, 0, 0.941103, 2.78816e-05, 0, 0, 0.926619, 1.60221e-05, 0, 0, 0.920983, 2.35164e-05, 0, 0, 0.912293, 3.11924e-05, 0, 0.0158731, 0.899277, 3.48118e-05, 0, 0.0476191, 0.880884, 2.6041e-05, 0, 0.0793651, 0.870399, 3.38726e-05, 0, 0.111111, 0.856138, 3.92906e-05, 0, 0.142857, 0.837436, 3.72874e-05, 0, 0.174603, 0.820973, 3.92558e-05, 0, 0.206349, 0.803583, 4.34658e-05, 0, 0.238095, 0.782168, 4.0256e-05, 0, 0.269841, 0.764107, 4.48159e-05, 0, 0.301587, 0.743092, 4.57627e-05, 0, 0.333333, 0.721626, 4.55314e-05, 0, 0.365079, 0.700375, 4.77335e-05, 0, 0.396825, 0.677334, 4.61072e-05, 0, 0.428571, 0.655702, 4.84393e-05, 0, 0.460317, 0.632059, 4.64583e-05, 0, 0.492064, 0.610125, 4.83923e-05, 0, 0.52381, 0.58653, 4.64342e-05, 0, 0.555556, 0.564508, 4.77033e-05, 0, 0.587302, 0.541405, 4.59263e-05, 0, 0.619048, 0.519556, 4.6412e-05, 0, 0.650794, 0.497292, 4.48913e-05, 0, 0.68254, 0.475898, 4.45789e-05, 0, 0.714286, 0.454722, 4.33496e-05, 0, 0.746032, 0.434042, 4.23054e-05, 0, 0.777778, 0.414126, 4.13737e-05, 0, 0.809524, 0.394387, 3.97265e-05, 0, 0.84127, 0.375841, 3.90709e-05, 0, 0.873016, 0.357219, 3.69938e-05, 0, 0.904762, 0.340084, 3.65618e-05, 0, 0.936508, 0.322714, 3.42533e-05, 0, 0.968254, 0.306974, 3.39596e-05, 0, 1, 1, 1.01524e-18, 0, 0, 1, 1.0292e-18, 0, 0, 1, 1.30908e-18, 0, 0, 1, 4.73331e-18, 0, 0, 1, 6.25319e-17, 0, 0, 1, 1.07932e-15, 0, 0, 1, 1.63779e-14, 0, 0, 1, 2.03198e-13, 0, 0, 1, 2.04717e-12, 0, 0, 0.999999, 1.68995e-11, 0, 0, 0.999998, 1.15855e-10, 0, 0, 0.999996, 6.6947e-10, 0, 0, 0.999991, 3.30863e-09, 0, 0, 0.999983, 1.41737e-08, 0, 0, 0.999968, 5.32626e-08, 0, 0, 0.99994, 1.77431e-07, 0, 0, 0.999891, 5.28835e-07, 0, 0, 0.999797, 1.42169e-06, 0, 0, 0.999617, 3.47057e-06, 0, 0, 0.999227, 7.7231e-06, 0, 0, 0.998239, 1.55753e-05, 0, 0, 0.994937, 2.68495e-05, 0, 0, 0.980225, 2.13742e-05, 0, 0, 0.967549, 2.1631e-06, 0, 0, 0.966865, 4.17989e-06, 0, 0, 0.965739, 7.63341e-06, 0, 0, 0.963794, 1.30892e-05, 0, 0, 0.960244, 2.06456e-05, 0, 0, 0.953495, 2.82016e-05, 0, 0.000148105, 0.940876, 2.71581e-05, 0, 0.002454, 0.926569, 1.64159e-05, 0, 0.00867491, 0.920905, 2.39521e-05, 0, 0.01956, 0.912169, 3.15127e-05, 0, 0.035433, 0.899095, 3.46626e-05, 0, 0.056294, 0.882209, 2.90223e-05, 0, 0.0818191, 0.870272, 3.42992e-05, 0, 0.111259, 0.855977, 3.94164e-05, 0, 0.142857, 0.837431, 3.72343e-05, 0, 0.174603, 0.820826, 3.96691e-05, 0, 0.206349, 0.803408, 4.35395e-05, 0, 0.238095, 0.782838, 4.19579e-05, 0, 0.269841, 0.763941, 4.50953e-05, 0, 0.301587, 0.742904, 4.55847e-05, 0, 0.333333, 0.721463, 4.58833e-05, 0, 0.365079, 0.700197, 4.77159e-05, 0, 0.396825, 0.677501, 4.70641e-05, 0, 0.428571, 0.655527, 4.84732e-05, 0, 0.460317, 0.6324, 4.76834e-05, 0, 0.492064, 0.609964, 4.84213e-05, 0, 0.52381, 0.586839, 4.75541e-05, 0, 0.555556, 0.564353, 4.76951e-05, 0, 0.587302, 0.541589, 4.67611e-05, 0, 0.619048, 0.519413, 4.63493e-05, 0, 0.650794, 0.497337, 4.53994e-05, 0, 0.68254, 0.475797, 4.45308e-05, 0, 0.714286, 0.454659, 4.35787e-05, 0, 0.746032, 0.434065, 4.24839e-05, 0, 0.777778, 0.414018, 4.1436e-05, 0, 0.809524, 0.39455, 4.01902e-05, 0, 0.84127, 0.375742, 3.90813e-05, 0, 0.873016, 0.357501, 3.77116e-05, 0, 0.904762, 0.339996, 3.6535e-05, 0, 0.936508, 0.323069, 3.51265e-05, 0, 0.968254, 0.306897, 3.39112e-05, 0, 1, 1, 1.0396e-15, 0, 0, 1, 1.04326e-15, 0, 0, 1, 1.10153e-15, 0, 0, 1, 1.44668e-15, 0, 0, 1, 3.4528e-15, 0, 0, 1, 1.75958e-14, 0, 0, 1, 1.2627e-13, 0, 0, 1, 9.36074e-13, 0, 0, 1, 6.45742e-12, 0, 0, 0.999998, 4.01228e-11, 0, 0, 0.999997, 2.22338e-10, 0, 0, 0.999995, 1.0967e-09, 0, 0, 0.999991, 4.82132e-09, 0, 0, 0.999981, 1.89434e-08, 0, 0, 0.999967, 6.67716e-08, 0, 0, 0.999938, 2.12066e-07, 0, 0, 0.999886, 6.0977e-07, 0, 0, 0.999792, 1.59504e-06, 0, 0, 0.999608, 3.81191e-06, 0, 0, 0.999209, 8.33727e-06, 0, 0, 0.998179, 1.65288e-05, 0, 0, 0.994605, 2.74387e-05, 0, 0, 0.979468, 1.67316e-05, 0, 0, 0.967529, 2.42877e-06, 0, 0, 0.966836, 4.61696e-06, 0, 0, 0.96569, 8.30977e-06, 0, 0, 0.963706, 1.40427e-05, 0, 2.44659e-06, 0.960063, 2.17353e-05, 0, 0.000760774, 0.953113, 2.86606e-05, 0, 0.00367261, 0.940192, 2.47691e-05, 0, 0.00940263, 0.927731, 1.95814e-05, 0, 0.018333, 0.920669, 2.52531e-05, 0, 0.0306825, 0.911799, 3.24277e-05, 0, 0.0465556, 0.89857, 3.40982e-05, 0, 0.0659521, 0.883283, 3.19622e-05, 0, 0.0887677, 0.86989, 3.5548e-05, 0, 0.114784, 0.855483, 3.97143e-05, 0, 0.143618, 0.837987, 3.91665e-05, 0, 0.174606, 0.820546, 4.11306e-05, 0, 0.206349, 0.802878, 4.36753e-05, 0, 0.238095, 0.783402, 4.44e-05, 0, 0.269841, 0.763439, 4.58726e-05, 0, 0.301587, 0.742925, 4.67097e-05, 0, 0.333333, 0.721633, 4.78887e-05, 0, 0.365079, 0.69985, 4.81251e-05, 0, 0.396825, 0.67783, 4.91811e-05, 0, 0.428571, 0.655126, 4.88199e-05, 0, 0.460318, 0.632697, 4.96025e-05, 0, 0.492064, 0.609613, 4.8829e-05, 0, 0.52381, 0.587098, 4.92754e-05, 0, 0.555556, 0.564119, 4.82625e-05, 0, 0.587302, 0.541813, 4.82807e-05, 0, 0.619048, 0.519342, 4.71552e-05, 0, 0.650794, 0.497514, 4.66765e-05, 0, 0.68254, 0.475879, 4.55582e-05, 0, 0.714286, 0.454789, 4.46007e-05, 0, 0.746032, 0.434217, 4.35382e-05, 0, 0.777778, 0.414086, 4.21753e-05, 0, 0.809524, 0.394744, 4.12093e-05, 0, 0.84127, 0.375782, 3.96634e-05, 0, 0.873016, 0.357707, 3.86419e-05, 0, 0.904762, 0.340038, 3.70345e-05, 0, 0.936508, 0.323284, 3.59725e-05, 0, 0.968254, 0.306954, 3.436e-05, 0, 1, 1, 5.99567e-14, 0, 0, 1, 6.00497e-14, 0, 0, 1, 6.14839e-14, 0, 0, 1, 6.86641e-14, 0, 0, 1, 9.72658e-14, 0, 0, 1, 2.21271e-13, 0, 0, 1, 8.33195e-13, 0, 0, 1, 4.03601e-12, 0, 0, 0.999999, 2.06001e-11, 0, 0, 0.999998, 1.01739e-10, 0, 0, 0.999997, 4.70132e-10, 0, 0, 0.999993, 2.00436e-09, 0, 0, 0.999988, 7.83682e-09, 0, 0, 0.999979, 2.80338e-08, 0, 0, 0.999962, 9.17033e-08, 0, 0, 0.999933, 2.74514e-07, 0, 0, 0.999881, 7.53201e-07, 0, 0, 0.999783, 1.89826e-06, 0, 0, 0.999594, 4.40279e-06, 0, 0, 0.999178, 9.3898e-06, 0, 0, 0.998073, 1.81265e-05, 0, 0, 0.993993, 2.80487e-05, 0, 0, 0.979982, 1.49422e-05, 0, 0, 0.968145, 3.78481e-06, 0, 0, 0.966786, 5.3771e-06, 0, 0, 0.965611, 9.47508e-06, 0, 3.88934e-05, 0.963557, 1.56616e-05, 0, 0.0009693, 0.959752, 2.35144e-05, 0, 0.00370329, 0.952461, 2.91568e-05, 0, 0.00868428, 0.940193, 2.40102e-05, 0, 0.0161889, 0.929042, 2.31235e-05, 0, 0.0263948, 0.920266, 2.73968e-05, 0, 0.0394088, 0.911178, 3.37915e-05, 0, 0.0552818, 0.897873, 3.33629e-05, 0, 0.0740138, 0.884053, 3.51405e-05, 0, 0.0955539, 0.869455, 3.78034e-05, 0, 0.119795, 0.854655, 3.99378e-05, 0, 0.14656, 0.838347, 4.19108e-05, 0, 0.175573, 0.820693, 4.40831e-05, 0, 0.206388, 0.802277, 4.45599e-05, 0, 0.238095, 0.783634, 4.72691e-05, 0, 0.269841, 0.763159, 4.76984e-05, 0, 0.301587, 0.742914, 4.91487e-05, 0, 0.333333, 0.721662, 5.02312e-05, 0, 0.365079, 0.699668, 5.02817e-05, 0, 0.396825, 0.677839, 5.1406e-05, 0, 0.428571, 0.655091, 5.11095e-05, 0, 0.460317, 0.632665, 5.16067e-05, 0, 0.492064, 0.609734, 5.12255e-05, 0, 0.52381, 0.587043, 5.10263e-05, 0, 0.555556, 0.564298, 5.0565e-05, 0, 0.587302, 0.541769, 4.97951e-05, 0, 0.619048, 0.519529, 4.92698e-05, 0, 0.650794, 0.497574, 4.82066e-05, 0, 0.68254, 0.476028, 4.73689e-05, 0, 0.714286, 0.454961, 4.61941e-05, 0, 0.746032, 0.434341, 4.50618e-05, 0, 0.777778, 0.414364, 4.38355e-05, 0, 0.809524, 0.394832, 4.24196e-05, 0, 0.84127, 0.376109, 4.12563e-05, 0, 0.873016, 0.35779, 3.96226e-05, 0, 0.904762, 0.340379, 3.84886e-05, 0, 0.936508, 0.323385, 3.68214e-05, 0, 0.968254, 0.307295, 3.56636e-05, 0, 1, 1, 1.06465e-12, 0, 0, 1, 1.06555e-12, 0, 0, 1, 1.07966e-12, 0, 0, 1, 1.14601e-12, 0, 0, 1, 1.37123e-12, 0, 0, 1, 2.1243e-12, 0, 0, 0.999999, 4.89653e-12, 0, 0, 0.999999, 1.60283e-11, 0, 0, 0.999998, 6.2269e-11, 0, 0, 0.999997, 2.51859e-10, 0, 0, 0.999996, 9.96192e-10, 0, 0, 0.999992, 3.74531e-09, 0, 0, 0.999986, 1.32022e-08, 0, 0, 0.999975, 4.33315e-08, 0, 0, 0.999959, 1.31956e-07, 0, 0, 0.999927, 3.72249e-07, 0, 0, 0.999871, 9.72461e-07, 0, 0, 0.999771, 2.35343e-06, 0, 0, 0.999572, 5.2768e-06, 0, 0, 0.999133, 1.09237e-05, 0, 0, 0.997912, 2.03675e-05, 0, 0, 0.993008, 2.79396e-05, 0, 0, 0.980645, 1.39604e-05, 0, 0, 0.970057, 6.46596e-06, 0, 0, 0.966717, 6.5089e-06, 0, 4.74145e-05, 0.965497, 1.11863e-05, 0, 0.00089544, 0.96334, 1.79857e-05, 0, 0.0032647, 0.959294, 2.59045e-05, 0, 0.0075144, 0.951519, 2.92327e-05, 0, 0.0138734, 0.940517, 2.49769e-05, 0, 0.0224952, 0.93014, 2.6803e-05, 0, 0.0334828, 0.91972, 3.03656e-05, 0, 0.0468973, 0.910294, 3.53323e-05, 0, 0.0627703, 0.897701, 3.51002e-05, 0, 0.0811019, 0.884522, 3.88104e-05, 0, 0.10186, 0.869489, 4.12932e-05, 0, 0.124985, 0.853983, 4.15781e-05, 0, 0.150372, 0.838425, 4.54066e-05, 0, 0.177868, 0.820656, 4.71624e-05, 0, 0.207245, 0.801875, 4.75243e-05, 0, 0.238143, 0.783521, 5.05621e-05, 0, 0.269841, 0.763131, 5.0721e-05, 0, 0.301587, 0.74261, 5.23293e-05, 0, 0.333333, 0.72148, 5.28699e-05, 0, 0.365079, 0.699696, 5.38677e-05, 0, 0.396825, 0.677592, 5.39255e-05, 0, 0.428571, 0.65525, 5.46367e-05, 0, 0.460317, 0.632452, 5.41348e-05, 0, 0.492064, 0.609903, 5.44976e-05, 0, 0.52381, 0.586928, 5.36201e-05, 0, 0.555556, 0.564464, 5.35185e-05, 0, 0.587302, 0.541801, 5.24949e-05, 0, 0.619048, 0.519681, 5.1812e-05, 0, 0.650794, 0.497685, 5.07687e-05, 0, 0.68254, 0.47622, 4.96243e-05, 0, 0.714286, 0.455135, 4.85714e-05, 0, 0.746032, 0.4346, 4.71847e-05, 0, 0.777778, 0.414564, 4.59294e-05, 0, 0.809524, 0.395165, 4.44705e-05, 0, 0.84127, 0.376333, 4.30772e-05, 0, 0.873016, 0.358197, 4.16229e-05, 0, 0.904762, 0.34064, 4.01019e-05, 0, 0.936508, 0.323816, 3.86623e-05, 0, 0.968254, 0.307581, 3.70933e-05, 0, 1, 1, 9.91541e-12, 0, 0, 1, 9.92077e-12, 0, 0, 1, 1.00041e-11, 0, 0, 1, 1.0385e-11, 0, 0, 1, 1.15777e-11, 0, 0, 1, 1.50215e-11, 0, 0, 0.999999, 2.54738e-11, 0, 0, 0.999999, 5.98822e-11, 0, 0, 0.999998, 1.79597e-10, 0, 0, 0.999997, 6.02367e-10, 0, 0, 0.999994, 2.06835e-09, 0, 0, 0.99999, 6.94952e-09, 0, 0, 0.999984, 2.23363e-08, 0, 0, 0.999972, 6.78578e-08, 0, 0, 0.999952, 1.93571e-07, 0, 0, 0.999919, 5.16594e-07, 0, 0, 0.99986, 1.28739e-06, 0, 0, 0.999753, 2.99298e-06, 0, 0, 0.999546, 6.48258e-06, 0, 0, 0.999074, 1.29985e-05, 0, 0, 0.997671, 2.32176e-05, 0, 0, 0.991504, 2.56701e-05, 0, 0, 0.981148, 1.31141e-05, 0, 0, 0.971965, 8.69048e-06, 0, 2.80182e-05, 0.966624, 8.08301e-06, 0, 0.000695475, 0.965344, 1.35235e-05, 0, 0.00265522, 0.963048, 2.10592e-05, 0, 0.00622975, 0.958673, 2.87473e-05, 0, 0.0116234, 0.950262, 2.81379e-05, 0, 0.018976, 0.940836, 2.71089e-05, 0, 0.0283844, 0.930996, 3.0926e-05, 0, 0.0399151, 0.919848, 3.48359e-05, 0, 0.0536063, 0.909136, 3.66092e-05, 0, 0.0694793, 0.897554, 3.84162e-05, 0, 0.0875342, 0.884691, 4.30971e-05, 0, 0.107749, 0.869414, 4.47803e-05, 0, 0.130087, 0.853462, 4.52858e-05, 0, 0.154481, 0.838187, 4.95769e-05, 0, 0.180833, 0.820381, 5.02709e-05, 0, 0.209005, 0.801844, 5.22713e-05, 0, 0.238791, 0.783061, 5.41505e-05, 0, 0.269869, 0.763205, 5.53712e-05, 0, 0.301587, 0.742362, 5.64909e-05, 0, 0.333333, 0.721393, 5.72646e-05, 0, 0.365079, 0.699676, 5.81012e-05, 0, 0.396825, 0.677395, 5.8096e-05, 0, 0.428571, 0.655208, 5.85766e-05, 0, 0.460317, 0.632451, 5.83602e-05, 0, 0.492064, 0.609839, 5.80234e-05, 0, 0.52381, 0.587093, 5.77161e-05, 0, 0.555556, 0.564467, 5.68447e-05, 0, 0.587302, 0.542043, 5.63166e-05, 0, 0.619048, 0.519826, 5.5156e-05, 0, 0.650794, 0.497952, 5.41682e-05, 0, 0.68254, 0.476477, 5.28971e-05, 0, 0.714286, 0.455412, 5.14952e-05, 0, 0.746032, 0.434926, 5.02222e-05, 0, 0.777778, 0.4149, 4.85779e-05, 0, 0.809524, 0.395552, 4.72242e-05, 0, 0.84127, 0.376712, 4.54891e-05, 0, 0.873016, 0.358622, 4.40924e-05, 0, 0.904762, 0.341048, 4.22984e-05, 0, 0.936508, 0.324262, 4.08582e-05, 0, 0.968254, 0.308013, 3.90839e-05, 0, 1, 1, 6.13913e-11, 0, 0, 1, 6.14145e-11, 0, 0, 1, 6.17708e-11, 0, 0, 1, 6.33717e-11, 0, 0, 1, 6.81648e-11, 0, 0, 1, 8.08291e-11, 0, 0, 1, 1.14608e-10, 0, 0, 0.999998, 2.10507e-10, 0, 0, 0.999997, 4.99595e-10, 0, 0, 0.999995, 1.39897e-09, 0, 0, 0.999994, 4.19818e-09, 0, 0, 0.999988, 1.27042e-08, 0, 0, 0.999979, 3.75153e-08, 0, 0, 0.999965, 1.06206e-07, 0, 0, 0.999945, 2.85381e-07, 0, 0, 0.999908, 7.23611e-07, 0, 0, 0.999846, 1.7255e-06, 0, 0, 0.999733, 3.86104e-06, 0, 0, 0.999511, 8.08493e-06, 0, 0, 0.998993, 1.56884e-05, 0, 0, 0.997326, 2.65538e-05, 0, 0, 0.989706, 2.06466e-05, 0, 0, 0.981713, 1.30756e-05, 0, 7.0005e-06, 0.973636, 1.06473e-05, 0, 0.000464797, 0.966509, 1.0194e-05, 0, 0.00201743, 0.965149, 1.65881e-05, 0, 0.00497549, 0.962669, 2.49147e-05, 0, 0.00953262, 0.95786, 3.17449e-05, 0, 0.0158211, 0.949334, 2.81045e-05, 0, 0.0239343, 0.941041, 3.03263e-05, 0, 0.0339372, 0.931575, 3.56754e-05, 0, 0.0458738, 0.920102, 3.97075e-05, 0, 0.059772, 0.908002, 3.84886e-05, 0, 0.075645, 0.897269, 4.3027e-05, 0, 0.0934929, 0.884559, 4.79925e-05, 0, 0.113302, 0.869161, 4.8246e-05, 0, 0.135045, 0.853342, 5.09505e-05, 0, 0.158678, 0.837633, 5.42846e-05, 0, 0.184136, 0.820252, 5.54139e-05, 0, 0.211325, 0.801872, 5.81412e-05, 0, 0.240113, 0.782418, 5.85535e-05, 0, 0.270306, 0.7631, 6.10923e-05, 0, 0.301594, 0.742183, 6.13678e-05, 0, 0.333333, 0.721098, 6.27275e-05, 0, 0.365079, 0.699512, 6.29413e-05, 0, 0.396825, 0.677372, 6.36351e-05, 0, 0.428571, 0.655059, 6.33555e-05, 0, 0.460317, 0.632567, 6.36513e-05, 0, 0.492064, 0.609784, 6.28965e-05, 0, 0.52381, 0.587237, 6.25546e-05, 0, 0.555556, 0.564525, 6.15825e-05, 0, 0.587302, 0.542181, 6.05048e-05, 0, 0.619048, 0.520017, 5.96329e-05, 0, 0.650794, 0.498204, 5.81516e-05, 0, 0.68254, 0.476742, 5.69186e-05, 0, 0.714286, 0.455803, 5.53833e-05, 0, 0.746032, 0.435251, 5.37807e-05, 0, 0.777778, 0.415374, 5.22025e-05, 0, 0.809524, 0.395921, 5.03421e-05, 0, 0.84127, 0.377253, 4.88211e-05, 0, 0.873016, 0.359021, 4.68234e-05, 0, 0.904762, 0.341637, 4.53269e-05, 0, 0.936508, 0.3247, 4.33014e-05, 0, 0.968254, 0.308625, 4.18007e-05, 0, 1, 1, 2.86798e-10, 0, 0, 1, 2.86877e-10, 0, 0, 1, 2.88094e-10, 0, 0, 1, 2.93506e-10, 0, 0, 1, 3.09262e-10, 0, 0, 0.999999, 3.48593e-10, 0, 0, 0.999999, 4.44582e-10, 0, 0, 0.999998, 6.88591e-10, 0, 0, 0.999996, 1.34391e-09, 0, 0, 0.999993, 3.17438e-09, 0, 0, 0.999989, 8.35609e-09, 0, 0, 0.999983, 2.28677e-08, 0, 0, 0.999974, 6.23361e-08, 0, 0, 0.999959, 1.65225e-07, 0, 0, 0.999936, 4.19983e-07, 0, 0, 0.999896, 1.01546e-06, 0, 0, 0.99983, 2.32376e-06, 0, 0, 0.999709, 5.0156e-06, 0, 0, 0.999469, 1.0167e-05, 0, 0, 0.998886, 1.90775e-05, 0, 0, 0.996819, 3.00511e-05, 0, 0, 0.988837, 1.85092e-05, 0, 1.68222e-07, 0.982178, 1.34622e-05, 0, 0.000259622, 0.975017, 1.25961e-05, 0, 0.00142595, 0.967101, 1.3507e-05, 0, 0.00382273, 0.964905, 2.05003e-05, 0, 0.00764164, 0.96218, 2.9546e-05, 0, 0.0130121, 0.956821, 3.43738e-05, 0, 0.0200253, 0.948829, 3.05063e-05, 0, 0.0287452, 0.941092, 3.46487e-05, 0, 0.039218, 0.931883, 4.12061e-05, 0, 0.0514748, 0.920211, 4.44651e-05, 0, 0.0655351, 0.907307, 4.31252e-05, 0, 0.0814082, 0.89684, 4.90382e-05, 0, 0.0990939, 0.884119, 5.3334e-05, 0, 0.118583, 0.869148, 5.4114e-05, 0, 0.139856, 0.853377, 5.78536e-05, 0, 0.162882, 0.836753, 5.92285e-05, 0, 0.187615, 0.820063, 6.22787e-05, 0, 0.213991, 0.801694, 6.45492e-05, 0, 0.241918, 0.782116, 6.5353e-05, 0, 0.271267, 0.762673, 6.74344e-05, 0, 0.301847, 0.742133, 6.82788e-05, 0, 0.333333, 0.720779, 6.91959e-05, 0, 0.365079, 0.699386, 6.96817e-05, 0, 0.396826, 0.67732, 6.99583e-05, 0, 0.428572, 0.654888, 6.98447e-05, 0, 0.460318, 0.632499, 6.94063e-05, 0, 0.492064, 0.609825, 6.91612e-05, 0, 0.52381, 0.587287, 6.81576e-05, 0, 0.555556, 0.564743, 6.74138e-05, 0, 0.587302, 0.542409, 6.61617e-05, 0, 0.619048, 0.520282, 6.47785e-05, 0, 0.650794, 0.498506, 6.33836e-05, 0, 0.68254, 0.477102, 6.15905e-05, 0, 0.714286, 0.456167, 6.01013e-05, 0, 0.746032, 0.435728, 5.81457e-05, 0, 0.777778, 0.415809, 5.64215e-05, 0, 0.809524, 0.396517, 5.44997e-05, 0, 0.84127, 0.377737, 5.25061e-05, 0, 0.873016, 0.359698, 5.06831e-05, 0, 0.904762, 0.342164, 4.8568e-05, 0, 0.936508, 0.325417, 4.67826e-05, 0, 0.968254, 0.309186, 4.46736e-05, 0, 1, 1, 1.09018e-09, 0, 0, 1, 1.0904e-09, 0, 0, 1, 1.09393e-09, 0, 0, 1, 1.1095e-09, 0, 0, 1, 1.154e-09, 0, 0, 1, 1.26089e-09, 0, 0, 0.999999, 1.5059e-09, 0, 0, 0.999997, 2.07899e-09, 0, 0, 0.999994, 3.48164e-09, 0, 0, 0.999993, 7.05728e-09, 0, 0, 0.999987, 1.63692e-08, 0, 0, 0.999981, 4.06033e-08, 0, 0, 0.999969, 1.0245e-07, 0, 0, 0.999953, 2.55023e-07, 0, 0, 0.999925, 6.1511e-07, 0, 0, 0.999881, 1.42218e-06, 0, 0, 0.99981, 3.13086e-06, 0, 0, 0.99968, 6.53119e-06, 0, 0, 0.999418, 1.2832e-05, 0, 0, 0.998748, 2.32497e-05, 0, 0, 0.996066, 3.29522e-05, 0, 0, 0.988379, 1.79613e-05, 0, 0.000108799, 0.982567, 1.43715e-05, 0, 0.000921302, 0.976097, 1.48096e-05, 0, 0.00280738, 0.968475, 1.78905e-05, 0, 0.00596622, 0.964606, 2.53921e-05, 0, 0.0105284, 0.961564, 3.48623e-05, 0, 0.0165848, 0.955517, 3.57612e-05, 0, 0.0242, 0.948381, 3.43493e-05, 0, 0.03342, 0.941095, 4.05849e-05, 0, 0.0442777, 0.931923, 4.75394e-05, 0, 0.0567958, 0.91996, 4.84328e-05, 0, 0.0709879, 0.907419, 5.02146e-05, 0, 0.086861, 0.89618, 5.61654e-05, 0, 0.104415, 0.88337, 5.87612e-05, 0, 0.123643, 0.869046, 6.18057e-05, 0, 0.144531, 0.853278, 6.57392e-05, 0, 0.167057, 0.836091, 6.6303e-05, 0, 0.191188, 0.819644, 7.04445e-05, 0, 0.216878, 0.801246, 7.14071e-05, 0, 0.244062, 0.782031, 7.40093e-05, 0, 0.272649, 0.762066, 7.4685e-05, 0, 0.302509, 0.741964, 7.66647e-05, 0, 0.333442, 0.720554, 7.66328e-05, 0, 0.365079, 0.699098, 7.77857e-05, 0, 0.396826, 0.677189, 7.74633e-05, 0, 0.428572, 0.65484, 7.76235e-05, 0, 0.460318, 0.632496, 7.70316e-05, 0, 0.492064, 0.609908, 7.62669e-05, 0, 0.52381, 0.587312, 7.53972e-05, 0, 0.555556, 0.564938, 7.39994e-05, 0, 0.587302, 0.542577, 7.28382e-05, 0, 0.619048, 0.52062, 7.1112e-05, 0, 0.650794, 0.498819, 6.94004e-05, 0, 0.68254, 0.477555, 6.75575e-05, 0, 0.714286, 0.456568, 6.53449e-05, 0, 0.746032, 0.436278, 6.36068e-05, 0, 0.777778, 0.41637, 6.13466e-05, 0, 0.809524, 0.397144, 5.94177e-05, 0, 0.84127, 0.378412, 5.70987e-05, 0, 0.873016, 0.360376, 5.50419e-05, 0, 0.904762, 0.342906, 5.27422e-05, 0, 0.936508, 0.326136, 5.06544e-05, 0, 0.968254, 0.30997, 4.84307e-05, 0, 1, 1, 3.54014e-09, 0, 0, 1, 3.54073e-09, 0, 0, 1, 3.54972e-09, 0, 0, 1, 3.58929e-09, 0, 0, 1, 3.70093e-09, 0, 0, 0.999999, 3.96194e-09, 0, 0, 0.999998, 4.53352e-09, 0, 0, 0.999997, 5.78828e-09, 0, 0, 0.999994, 8.63812e-09, 0, 0, 0.999991, 1.53622e-08, 0, 0, 0.999985, 3.16356e-08, 0, 0, 0.999977, 7.12781e-08, 0, 0, 0.999964, 1.66725e-07, 0, 0, 0.999945, 3.90501e-07, 0, 0, 0.999912, 8.95622e-07, 0, 0, 0.999866, 1.98428e-06, 0, 0, 0.999786, 4.21038e-06, 0, 0, 0.999647, 8.50239e-06, 0, 0, 0.999356, 1.62059e-05, 0, 0, 0.998563, 2.82652e-05, 0, 0, 0.994928, 3.36309e-05, 0, 2.44244e-05, 0.987999, 1.78458e-05, 0, 0.000523891, 0.982893, 1.59162e-05, 0, 0.00194729, 0.977044, 1.78056e-05, 0, 0.00451099, 0.969972, 2.30624e-05, 0, 0.00835132, 0.964237, 3.13922e-05, 0, 0.013561, 0.960791, 4.06145e-05, 0, 0.0202056, 0.954292, 3.72796e-05, 0, 0.0283321, 0.948052, 4.03199e-05, 0, 0.0379739, 0.940938, 4.79537e-05, 0, 0.0491551, 0.931689, 5.45292e-05, 0, 0.0618918, 0.91987, 5.4038e-05, 0, 0.0761941, 0.907665, 5.89909e-05, 0, 0.0920672, 0.895281, 6.42651e-05, 0, 0.109511, 0.882621, 6.59707e-05, 0, 0.12852, 0.86873, 7.09973e-05, 0, 0.149085, 0.853008, 7.42221e-05, 0, 0.171189, 0.835944, 7.61754e-05, 0, 0.194809, 0.818949, 7.97052e-05, 0, 0.21991, 0.800951, 8.12434e-05, 0, 0.246447, 0.781847, 8.38075e-05, 0, 0.274352, 0.761649, 8.4501e-05, 0, 0.303535, 0.74152, 8.60258e-05, 0, 0.333857, 0.720495, 8.66233e-05, 0, 0.365104, 0.698742, 8.68326e-05, 0, 0.396826, 0.677096, 8.7133e-05, 0, 0.428572, 0.654782, 8.63497e-05, 0, 0.460318, 0.632335, 8.60206e-05, 0, 0.492064, 0.610031, 8.49337e-05, 0, 0.52381, 0.587457, 8.38279e-05, 0, 0.555556, 0.56513, 8.2309e-05, 0, 0.587302, 0.542877, 8.03542e-05, 0, 0.619048, 0.5209, 7.86928e-05, 0, 0.650794, 0.499291, 7.65171e-05, 0, 0.68254, 0.477971, 7.44753e-05, 0, 0.714286, 0.457221, 7.2209e-05, 0, 0.746032, 0.436803, 6.97448e-05, 0, 0.777778, 0.417083, 6.75333e-05, 0, 0.809524, 0.397749, 6.48058e-05, 0, 0.84127, 0.379177, 6.25759e-05, 0, 0.873016, 0.361061, 5.98584e-05, 0, 0.904762, 0.343713, 5.75797e-05, 0, 0.936508, 0.326894, 5.49999e-05, 0, 0.968254, 0.310816, 5.27482e-05, 0, 1, 1, 1.0153e-08, 0, 0, 1, 1.01544e-08, 0, 0, 1, 1.01751e-08, 0, 0, 1, 1.02662e-08, 0, 0, 1, 1.0521e-08, 0, 0, 0.999999, 1.11049e-08, 0, 0, 0.999999, 1.23408e-08, 0, 0, 0.999996, 1.4924e-08, 0, 0, 0.999992, 2.04471e-08, 0, 0, 0.999989, 3.26539e-08, 0, 0, 0.99998, 6.03559e-08, 0, 0, 0.999971, 1.23936e-07, 0, 0, 0.999955, 2.69058e-07, 0, 0, 0.999933, 5.93604e-07, 0, 0, 0.999901, 1.29633e-06, 0, 0, 0.999847, 2.75621e-06, 0, 0, 0.999761, 5.64494e-06, 0, 0, 0.999607, 1.10485e-05, 0, 0, 0.999282, 2.04388e-05, 0, 0, 0.99831, 3.41084e-05, 0, 2.2038e-07, 0.993288, 2.94949e-05, 0, 0.000242388, 0.987855, 1.92736e-05, 0, 0.0012503, 0.983167, 1.82383e-05, 0, 0.0032745, 0.977908, 2.18633e-05, 0, 0.00646321, 0.971194, 2.90662e-05, 0, 0.0109133, 0.963867, 3.86401e-05, 0, 0.0166927, 0.95982, 4.62827e-05, 0, 0.0238494, 0.953497, 4.20705e-05, 0, 0.0324178, 0.947621, 4.77743e-05, 0, 0.0424225, 0.940611, 5.68258e-05, 0, 0.0538808, 0.931174, 6.18061e-05, 0, 0.0668047, 0.919919, 6.27098e-05, 0, 0.0812014, 0.907856, 6.94714e-05, 0, 0.0970745, 0.894509, 7.35008e-05, 0, 0.114424, 0.881954, 7.63369e-05, 0, 0.133246, 0.868309, 8.21896e-05, 0, 0.153534, 0.852511, 8.3769e-05, 0, 0.175275, 0.835821, 8.81615e-05, 0, 0.198453, 0.817981, 8.96368e-05, 0, 0.223042, 0.800504, 9.30906e-05, 0, 0.249009, 0.78141, 9.45056e-05, 0, 0.276304, 0.761427, 9.63605e-05, 0, 0.304862, 0.74094, 9.68088e-05, 0, 0.334584, 0.720233, 9.81481e-05, 0, 0.365322, 0.698592, 9.79122e-05, 0, 0.396826, 0.676763, 9.81057e-05, 0, 0.428571, 0.654808, 9.73956e-05, 0, 0.460318, 0.632326, 9.62619e-05, 0, 0.492064, 0.610049, 9.52996e-05, 0, 0.52381, 0.58763, 9.33334e-05, 0, 0.555556, 0.565261, 9.17573e-05, 0, 0.587302, 0.543244, 8.96636e-05, 0, 0.619048, 0.521273, 8.73304e-05, 0, 0.650794, 0.499818, 8.52648e-05, 0, 0.68254, 0.478536, 8.23961e-05, 0, 0.714286, 0.457826, 7.9939e-05, 0, 0.746032, 0.437549, 7.7126e-05, 0, 0.777778, 0.41776, 7.43043e-05, 0, 0.809524, 0.39863, 7.16426e-05, 0, 0.84127, 0.379954, 6.86456e-05, 0, 0.873016, 0.362025, 6.60514e-05, 0, 0.904762, 0.344581, 6.30755e-05, 0, 0.936508, 0.327909, 6.05439e-05, 0, 0.968254, 0.311736, 5.76345e-05, 0, 1, 1, 2.63344e-08, 0, 0, 1, 2.63373e-08, 0, 0, 1, 2.63815e-08, 0, 0, 1, 2.65753e-08, 0, 0, 1, 2.71132e-08, 0, 0, 0.999999, 2.83279e-08, 0, 0, 0.999997, 3.0833e-08, 0, 0, 0.999995, 3.58711e-08, 0, 0, 0.999992, 4.61266e-08, 0, 0, 0.999985, 6.7574e-08, 0, 0, 0.999977, 1.1358e-07, 0, 0, 0.999966, 2.13657e-07, 0, 0, 0.999948, 4.31151e-07, 0, 0, 0.999923, 8.96656e-07, 0, 0, 0.999884, 1.86603e-06, 0, 0, 0.999826, 3.81115e-06, 0, 0, 0.999732, 7.54184e-06, 0, 0, 0.999561, 1.43192e-05, 0, 0, 0.999191, 2.57061e-05, 0, 0, 0.997955, 4.05724e-05, 0, 7.44132e-05, 0.992228, 2.76537e-05, 0, 0.000716477, 0.987638, 2.08885e-05, 0, 0.0022524, 0.983395, 2.15226e-05, 0, 0.00484816, 0.978614, 2.70795e-05, 0, 0.00860962, 0.972389, 3.65282e-05, 0, 0.0136083, 0.964392, 4.74747e-05, 0, 0.0198941, 0.95861, 5.09141e-05, 0, 0.0275023, 0.952806, 4.8963e-05, 0, 0.0364584, 0.94712, 5.71119e-05, 0, 0.04678, 0.940104, 6.71704e-05, 0, 0.0584799, 0.930398, 6.87586e-05, 0, 0.0715665, 0.919866, 7.38161e-05, 0, 0.086045, 0.907853, 8.13235e-05, 0, 0.101918, 0.894078, 8.34582e-05, 0, 0.119186, 0.881177, 8.92093e-05, 0, 0.137845, 0.867575, 9.44548e-05, 0, 0.157891, 0.852107, 9.69607e-05, 0, 0.179316, 0.835502, 0.000101456, 0, 0.202106, 0.81756, 0.000103256, 0, 0.226243, 0.79984, 0.000106954, 0, 0.251704, 0.780998, 0.000108066, 0, 0.278451, 0.761132, 0.000110111, 0, 0.306436, 0.740429, 0.000110459, 0, 0.335586, 0.719836, 0.000111219, 0, 0.365796, 0.698467, 0.00011145, 0, 0.3969, 0.676446, 0.000110393, 0, 0.428571, 0.654635, 0.000110035, 0, 0.460318, 0.632411, 0.000108548, 0, 0.492064, 0.609986, 0.000106963, 0, 0.52381, 0.587872, 0.000105238, 0, 0.555556, 0.565528, 0.000102665, 0, 0.587302, 0.543563, 0.000100543, 0, 0.619048, 0.52176, 9.76182e-05, 0, 0.650794, 0.500188, 9.47099e-05, 0, 0.68254, 0.479204, 9.19929e-05, 0, 0.714286, 0.458413, 8.86139e-05, 0, 0.746032, 0.438314, 8.57839e-05, 0, 0.777778, 0.418573, 8.2411e-05, 0, 0.809524, 0.39947, 7.92211e-05, 0, 0.84127, 0.380892, 7.59546e-05, 0, 0.873016, 0.362953, 7.27571e-05, 0, 0.904762, 0.345601, 6.95738e-05, 0, 0.936508, 0.328895, 6.64907e-05, 0, 0.968254, 0.312808, 6.34277e-05, 0, 1, 1, 6.28647e-08, 0, 0, 1, 6.28705e-08, 0, 0, 1, 6.29587e-08, 0, 0, 1, 6.33441e-08, 0, 0, 0.999999, 6.44087e-08, 0, 0, 0.999998, 6.67856e-08, 0, 0, 0.999997, 7.15889e-08, 0, 0, 0.999995, 8.09577e-08, 0, 0, 0.999989, 9.92764e-08, 0, 0, 0.999983, 1.35834e-07, 0, 0, 0.999974, 2.10482e-07, 0, 0, 0.999959, 3.65215e-07, 0, 0, 0.999939, 6.86693e-07, 0, 0, 0.999911, 1.3472e-06, 0, 0, 0.999868, 2.6731e-06, 0, 0, 0.999804, 5.24756e-06, 0, 0, 0.9997, 1.00403e-05, 0, 0, 0.99951, 1.85019e-05, 0, 0, 0.999078, 3.22036e-05, 0, 6.20676e-06, 0.997428, 4.70002e-05, 0, 0.000341552, 0.99162, 2.87123e-05, 0, 0.00143727, 0.987479, 2.34706e-05, 0, 0.00349201, 0.983582, 2.60083e-05, 0, 0.0066242, 0.979186, 3.37927e-05, 0, 0.0109113, 0.97325, 4.54689e-05, 0, 0.0164064, 0.965221, 5.73759e-05, 0, 0.0231463, 0.957262, 5.44114e-05, 0, 0.0311571, 0.952211, 5.87006e-05, 0, 0.0404572, 0.946631, 6.92256e-05, 0, 0.0510592, 0.939391, 7.87819e-05, 0, 0.0629723, 0.929795, 7.92368e-05, 0, 0.0762025, 0.91965, 8.75075e-05, 0, 0.090753, 0.907737, 9.50903e-05, 0, 0.106626, 0.893899, 9.72963e-05, 0, 0.123822, 0.880239, 0.00010459, 0, 0.142337, 0.866562, 0.000107689, 0, 0.16217, 0.85164, 0.000113081, 0, 0.183314, 0.835021, 0.000116636, 0, 0.20576, 0.817311, 0.000120074, 0, 0.229496, 0.798845, 0.000121921, 0, 0.254502, 0.780479, 0.00012475, 0, 0.280753, 0.760694, 0.000125255, 0, 0.308212, 0.740142, 0.000126719, 0, 0.336825, 0.719248, 0.00012636, 0, 0.366517, 0.698209, 0.000126712, 0, 0.397167, 0.676398, 0.000125769, 0, 0.428578, 0.654378, 0.000124432, 0, 0.460318, 0.632484, 0.000123272, 0, 0.492064, 0.610113, 0.00012085, 0, 0.52381, 0.587931, 0.000118411, 0, 0.555556, 0.565872, 0.00011569, 0, 0.587302, 0.543814, 0.000112521, 0, 0.619048, 0.522265, 0.000109737, 0, 0.650794, 0.500835, 0.000106228, 0, 0.68254, 0.479818, 0.000102591, 0, 0.714286, 0.459258, 9.91288e-05, 0, 0.746032, 0.439061, 9.52325e-05, 0, 0.777778, 0.419552, 9.1895e-05, 0, 0.809524, 0.400399, 8.79051e-05, 0, 0.84127, 0.381976, 8.44775e-05, 0, 0.873016, 0.364009, 8.06316e-05, 0, 0.904762, 0.346761, 7.71848e-05, 0, 0.936508, 0.330049, 7.35429e-05, 0, 0.968254, 0.314018, 7.02103e-05, 0, 1, 1, 1.39968e-07, 0, 0, 1, 1.39979e-07, 0, 0, 1, 1.40145e-07, 0, 0, 1, 1.4087e-07, 0, 0, 0.999999, 1.42865e-07, 0, 0, 0.999998, 1.47279e-07, 0, 0, 0.999997, 1.56057e-07, 0, 0, 0.999992, 1.7276e-07, 0, 0, 0.999989, 2.04352e-07, 0, 0, 0.99998, 2.6494e-07, 0, 0, 0.999969, 3.83435e-07, 0, 0, 0.999953, 6.18641e-07, 0, 0, 0.999929, 1.08755e-06, 0, 0, 0.999898, 2.01497e-06, 0, 0, 0.999849, 3.81346e-06, 0, 0, 0.999778, 7.19815e-06, 0, 0, 0.999661, 1.33215e-05, 0, 0, 0.999451, 2.38313e-05, 0, 0, 0.998936, 4.01343e-05, 0, 0.000113724, 0.99662, 5.17346e-05, 0, 0.000820171, 0.991094, 3.04323e-05, 0, 0.00238143, 0.987487, 2.81757e-05, 0, 0.00493527, 0.983731, 3.20048e-05, 0, 0.00856859, 0.979647, 4.23905e-05, 0, 0.0133393, 0.973837, 5.62935e-05, 0, 0.0192863, 0.96584, 6.77442e-05, 0, 0.0264369, 0.956309, 6.23073e-05, 0, 0.03481, 0.951523, 7.04131e-05, 0, 0.0444184, 0.946003, 8.36594e-05, 0, 0.0552713, 0.938454, 9.11736e-05, 0, 0.0673749, 0.929279, 9.38264e-05, 0, 0.0807329, 0.919239, 0.000103754, 0, 0.0953479, 0.907293, 0.000109928, 0, 0.111221, 0.893936, 0.000115257, 0, 0.128352, 0.879674, 0.000122265, 0, 0.14674, 0.865668, 0.000125733, 0, 0.166382, 0.850998, 0.000132305, 0, 0.187276, 0.834498, 0.000134844, 0, 0.209413, 0.816903, 0.000139276, 0, 0.232786, 0.798235, 0.000140984, 0, 0.257382, 0.779724, 0.00014378, 0, 0.283181, 0.760251, 0.000144623, 0, 0.310156, 0.739808, 0.000145228, 0, 0.338269, 0.718762, 0.00014539, 0, 0.367461, 0.697815, 0.000144432, 0, 0.397646, 0.67631, 0.000143893, 0, 0.428685, 0.654278, 0.000141846, 0, 0.460318, 0.632347, 0.00013935, 0, 0.492064, 0.610296, 0.000137138, 0, 0.52381, 0.588039, 0.000133806, 0, 0.555556, 0.566218, 0.000130755, 0, 0.587302, 0.544346, 0.000127128, 0, 0.619048, 0.522701, 0.000123002, 0, 0.650794, 0.501542, 0.000119443, 0, 0.68254, 0.480508, 0.000115055, 0, 0.714286, 0.460092, 0.000111032, 0, 0.746032, 0.440021, 0.000106635, 0, 0.777778, 0.420446, 0.000102162, 0, 0.809524, 0.401512, 9.8184e-05, 0, 0.84127, 0.38299, 9.36497e-05, 0, 0.873016, 0.365232, 8.9813e-05, 0, 0.904762, 0.347865, 8.53073e-05, 0, 0.936508, 0.331342, 8.17068e-05, 0, 0.968254, 0.315202, 7.73818e-05, 0, 1, 1, 2.9368e-07, 0, 0, 1, 2.937e-07, 0, 0, 1, 2.93998e-07, 0, 0, 1, 2.95298e-07, 0, 0, 0.999999, 2.98865e-07, 0, 0, 0.999998, 3.067e-07, 0, 0, 0.999995, 3.22082e-07, 0, 0, 0.999992, 3.50767e-07, 0, 0, 0.999986, 4.03538e-07, 0, 0, 0.999976, 5.01372e-07, 0, 0, 0.999964, 6.8562e-07, 0, 0, 0.999945, 1.0374e-06, 0, 0, 0.999919, 1.71269e-06, 0, 0, 0.999882, 3.00175e-06, 0, 0, 0.999829, 5.42144e-06, 0, 0, 0.999749, 9.84182e-06, 0, 0, 0.99962, 1.76213e-05, 0, 0, 0.999382, 3.05995e-05, 0, 1.38418e-05, 0.998751, 4.96686e-05, 0, 0.000389844, 0.995344, 5.10733e-05, 0, 0.00150343, 0.990768, 3.45829e-05, 0, 0.00352451, 0.987464, 3.42841e-05, 0, 0.00655379, 0.983846, 3.99072e-05, 0, 0.0106554, 0.980007, 5.33219e-05, 0, 0.0158723, 0.974494, 6.96992e-05, 0, 0.0222333, 0.96622, 7.76754e-05, 0, 0.029758, 0.956273, 7.47718e-05, 0, 0.0384596, 0.950952, 8.64611e-05, 0, 0.0483473, 0.945215, 0.000100464, 0, 0.0594266, 0.937287, 0.000103729, 0, 0.0717019, 0.928649, 0.000111665, 0, 0.0851752, 0.918791, 0.00012353, 0, 0.0998479, 0.906685, 0.000127115, 0, 0.115721, 0.893706, 0.00013628, 0, 0.132794, 0.879248, 0.000142427, 0, 0.151067, 0.864685, 0.000148091, 0, 0.170538, 0.850032, 0.000153517, 0, 0.191204, 0.833853, 0.000157322, 0, 0.213063, 0.816353, 0.000161086, 0, 0.236107, 0.797834, 0.000164111, 0, 0.260329, 0.778831, 0.000165446, 0, 0.285714, 0.759756, 0.000167492, 0, 0.312243, 0.739419, 0.000166928, 0, 0.339887, 0.718491, 0.000167, 0, 0.368604, 0.697392, 0.000165674, 0, 0.398329, 0.676102, 0.000163815, 0, 0.428961, 0.654243, 0.000162003, 0, 0.460331, 0.632176, 0.000158831, 0, 0.492064, 0.610407, 0.000155463, 0, 0.52381, 0.588394, 0.000152062, 0, 0.555556, 0.56645, 0.000147665, 0, 0.587302, 0.5449, 0.00014375, 0, 0.619048, 0.523276, 0.000138905, 0, 0.650794, 0.502179, 0.000134189, 0, 0.68254, 0.481359, 0.000129392, 0, 0.714286, 0.46092, 0.000124556, 0, 0.746032, 0.441084, 0.00011957, 0, 0.777778, 0.421517, 0.000114652, 0, 0.809524, 0.402721, 0.000109688, 0, 0.84127, 0.384222, 0.000104667, 0, 0.873016, 0.366534, 9.99633e-05, 0, 0.904762, 0.349205, 9.50177e-05, 0, 0.936508, 0.332702, 9.07301e-05, 0, 0.968254, 0.316599, 8.59769e-05, 0, 1, 1, 5.85473e-07, 0, 0, 1, 5.85507e-07, 0, 0, 1, 5.8602e-07, 0, 0, 0.999999, 5.88259e-07, 0, 0, 0.999999, 5.94381e-07, 0, 0, 0.999998, 6.07754e-07, 0, 0, 0.999995, 6.33729e-07, 0, 0, 0.99999, 6.8137e-07, 0, 0, 0.999984, 7.67003e-07, 0, 0, 0.999973, 9.21212e-07, 0, 0, 0.999959, 1.20218e-06, 0, 0, 0.999936, 1.72024e-06, 0, 0, 0.999907, 2.68088e-06, 0, 0, 0.999866, 4.45512e-06, 0, 0, 0.999806, 7.68481e-06, 0, 0, 0.999716, 1.342e-05, 0, 0, 0.999576, 2.32473e-05, 0, 0, 0.9993, 3.91694e-05, 0, 0.000129917, 0.998498, 6.08429e-05, 0, 0.000845035, 0.994132, 4.89743e-05, 0, 0.00237616, 0.99031, 3.84644e-05, 0, 0.00484456, 0.987409, 4.21768e-05, 0, 0.00832472, 0.983981, 5.04854e-05, 0, 0.0128643, 0.980268, 6.71028e-05, 0, 0.0184947, 0.974875, 8.52749e-05, 0, 0.025237, 0.966063, 8.5531e-05, 0, 0.0331046, 0.956779, 9.00588e-05, 0, 0.0421067, 0.950259, 0.00010577, 0, 0.0522487, 0.944239, 0.000119458, 0, 0.0635343, 0.936341, 0.000122164, 0, 0.0759654, 0.928047, 0.000134929, 0, 0.0895434, 0.918065, 0.000145544, 0, 0.104269, 0.906267, 0.000150531, 0, 0.120142, 0.893419, 0.000161652, 0, 0.137163, 0.878758, 0.00016593, 0, 0.15533, 0.863699, 0.000174014, 0, 0.174645, 0.848876, 0.000177877, 0, 0.195106, 0.833032, 0.000184049, 0, 0.21671, 0.815557, 0.000186088, 0, 0.239454, 0.797323, 0.00019054, 0, 0.263332, 0.778124, 0.000191765, 0, 0.288336, 0.758929, 0.000192535, 0, 0.314451, 0.738979, 0.000192688, 0, 0.341658, 0.718213, 0.000191522, 0, 0.369924, 0.696947, 0.000190491, 0, 0.399202, 0.675807, 0.000187913, 0, 0.429416, 0.654147, 0.000184451, 0, 0.460447, 0.63229, 0.000181442, 0, 0.492064, 0.610499, 0.000177139, 0, 0.523809, 0.588747, 0.000172596, 0, 0.555555, 0.566783, 0.000167457, 0, 0.587301, 0.545359, 0.000162518, 0, 0.619048, 0.523984, 0.000156818, 0, 0.650794, 0.502917, 0.000151884, 0, 0.68254, 0.482294, 0.000145514, 0, 0.714286, 0.461945, 0.000140199, 0, 0.746032, 0.442133, 0.000134101, 0, 0.777778, 0.422705, 0.000128374, 0, 0.809524, 0.403916, 0.000122996, 0, 0.84127, 0.38554, 0.000116808, 0, 0.873016, 0.367909, 0.000111973, 0, 0.904762, 0.350651, 0.000105938, 0, 0.936508, 0.334208, 0.000101355, 0, 0.968254, 0.318123, 9.57629e-05, 0, 1, 1, 1.11633e-06, 0, 0, 1, 1.11639e-06, 0, 0, 1, 1.11725e-06, 0, 0, 1, 1.12096e-06, 0, 0, 0.999999, 1.1311e-06, 0, 0, 0.999997, 1.15315e-06, 0, 0, 0.999995, 1.1956e-06, 0, 0, 0.999989, 1.27239e-06, 0, 0, 0.999981, 1.40772e-06, 0, 0, 0.999969, 1.64541e-06, 0, 0, 0.999952, 2.06607e-06, 0, 0, 0.999928, 2.81783e-06, 0, 0, 0.999895, 4.16835e-06, 0, 0, 0.999848, 6.58728e-06, 0, 0, 0.999781, 1.08648e-05, 0, 0, 0.999682, 1.82579e-05, 0, 0, 0.999523, 3.06003e-05, 0, 1.59122e-05, 0.999205, 4.99862e-05, 0, 0.000391184, 0.998131, 7.3306e-05, 0, 0.00147534, 0.993334, 5.13229e-05, 0, 0.0034227, 0.99016, 4.67783e-05, 0, 0.00632232, 0.987321, 5.23413e-05, 0, 0.0102295, 0.984099, 6.4267e-05, 0, 0.0151794, 0.980432, 8.43042e-05, 0, 0.0211947, 0.974976, 0.000102819, 0, 0.0282899, 0.966429, 9.96234e-05, 0, 0.0364739, 0.957633, 0.000111074, 0, 0.0457522, 0.949422, 0.000128644, 0, 0.0561278, 0.943045, 0.000140076, 0, 0.0676023, 0.935448, 0.000146349, 0, 0.0801762, 0.927225, 0.000161854, 0, 0.0938499, 0.917033, 0.000169135, 0, 0.108623, 0.905762, 0.000179987, 0, 0.124496, 0.892879, 0.000189832, 0, 0.141469, 0.878435, 0.000195881, 0, 0.159541, 0.863114, 0.00020466, 0, 0.178713, 0.84776, 0.000209473, 0, 0.198985, 0.832084, 0.000214861, 0, 0.220355, 0.814915, 0.000217695, 0, 0.242823, 0.796711, 0.000220313, 0, 0.266385, 0.777603, 0.00022313, 0, 0.291036, 0.757991, 0.000222471, 0, 0.316767, 0.738371, 0.000222869, 0, 0.343563, 0.717872, 0.000221243, 0, 0.371402, 0.696619, 0.000218089, 0, 0.400248, 0.675379, 0.00021562, 0, 0.430047, 0.65411, 0.00021169, 0, 0.460709, 0.63241, 0.000206947, 0, 0.492079, 0.61046, 0.000201709, 0, 0.52381, 0.58903, 0.000196753, 0, 0.555556, 0.567267, 0.000189637, 0, 0.587302, 0.545886, 0.000184735, 0, 0.619048, 0.524714, 0.000177257, 0, 0.650794, 0.503789, 0.000171424, 0, 0.68254, 0.483204, 0.000164688, 0, 0.714286, 0.462976, 0.000157172, 0, 0.746032, 0.443294, 0.000151341, 0, 0.777778, 0.423988, 0.000143737, 0, 0.809524, 0.405325, 0.000138098, 0, 0.84127, 0.386981, 0.000130698, 0, 0.873016, 0.369436, 0.000125276, 0, 0.904762, 0.35219, 0.000118349, 0, 0.936508, 0.335804, 0.00011312, 0, 0.968254, 0.319749, 0.000106687, 0, 1, 1, 2.04685e-06, 0, 0, 1, 2.04694e-06, 0, 0, 1, 2.04831e-06, 0, 0, 0.999999, 2.05428e-06, 0, 0, 0.999999, 2.07056e-06, 0, 0, 0.999997, 2.10581e-06, 0, 0, 0.999993, 2.1732e-06, 0, 0, 0.999987, 2.29365e-06, 0, 0, 0.999979, 2.50243e-06, 0, 0, 0.999965, 2.86127e-06, 0, 0, 0.999947, 3.48028e-06, 0, 0, 0.999918, 4.55588e-06, 0, 0, 0.999881, 6.43303e-06, 0, 0, 0.999828, 9.70064e-06, 0, 0, 0.999753, 1.53233e-05, 0, 0, 0.999642, 2.4793e-05, 0, 0, 0.999464, 4.02032e-05, 0, 0.000122947, 0.999089, 6.35852e-05, 0, 0.000807414, 0.997567, 8.57026e-05, 0, 0.00227206, 0.992903, 5.94912e-05, 0, 0.00462812, 0.990011, 5.78515e-05, 0, 0.00794162, 0.987192, 6.5399e-05, 0, 0.0122534, 0.98418, 8.19675e-05, 0, 0.0175888, 0.980491, 0.000105514, 0, 0.0239635, 0.974779, 0.000121532, 0, 0.031387, 0.96675, 0.000119144, 0, 0.0398644, 0.958248, 0.000136125, 0, 0.0493982, 0.948884, 0.000155408, 0, 0.0599896, 0.941673, 0.000162281, 0, 0.0716382, 0.934521, 0.000176754, 0, 0.0843437, 0.926205, 0.000192873, 0, 0.0981056, 0.916089, 0.000200038, 0, 0.112923, 0.904963, 0.000213624, 0, 0.128796, 0.892089, 0.000221834, 0, 0.145725, 0.878028, 0.000232619, 0, 0.163709, 0.86249, 0.000238632, 0, 0.182749, 0.846587, 0.000247002, 0, 0.202847, 0.830988, 0.000250702, 0, 0.224001, 0.814165, 0.000255562, 0, 0.246214, 0.796135, 0.000257505, 0, 0.269482, 0.777052, 0.000258625, 0, 0.293805, 0.757201, 0.000258398, 0, 0.319176, 0.737655, 0.000256714, 0, 0.345587, 0.717477, 0.000255187, 0, 0.373021, 0.696433, 0.000251792, 0, 0.401454, 0.675084, 0.000247223, 0, 0.430844, 0.653907, 0.000242213, 0, 0.461125, 0.632561, 0.000237397, 0, 0.492187, 0.610658, 0.000229313, 0, 0.52381, 0.589322, 0.000224402, 0, 0.555556, 0.567857, 0.000216116, 0, 0.587302, 0.54652, 0.000209124, 0, 0.619048, 0.525433, 0.000201601, 0, 0.650794, 0.504679, 0.000192957, 0, 0.68254, 0.484203, 0.000186052, 0, 0.714286, 0.464203, 0.000177672, 0, 0.746032, 0.444549, 0.000170005, 0, 0.777778, 0.425346, 0.000162401, 0, 0.809524, 0.406706, 0.0001544, 0, 0.84127, 0.388576, 0.000147437, 0, 0.873016, 0.37094, 0.000139493, 0, 0.904762, 0.353996, 0.000133219, 0, 0.936508, 0.337391, 0.000125573, 0, 0.968254, 0.321648, 0.000119867, 0, 1, 1, 3.62511e-06, 0, 0, 1, 3.62525e-06, 0, 0, 1, 3.62739e-06, 0, 0, 0.999999, 3.63673e-06, 0, 0, 0.999998, 3.66214e-06, 0, 0, 0.999996, 3.71698e-06, 0, 0, 0.999992, 3.82116e-06, 0, 0, 0.999986, 4.00554e-06, 0, 0, 0.999976, 4.32058e-06, 0, 0, 0.999961, 4.85194e-06, 0, 0, 0.999938, 5.74808e-06, 0, 0, 0.999908, 7.26643e-06, 0, 0, 0.999865, 9.84707e-06, 0, 0, 0.999807, 1.42217e-05, 0, 0, 0.999723, 2.15581e-05, 0, 0, 0.999602, 3.36114e-05, 0, 1.19113e-05, 0.999398, 5.27353e-05, 0, 0.000355813, 0.998946, 8.05809e-05, 0, 0.00137768, 0.996647, 9.42908e-05, 0, 0.00322469, 0.992298, 6.68733e-05, 0, 0.00597897, 0.989802, 7.16564e-05, 0, 0.00968903, 0.987019, 8.21355e-05, 0, 0.0143845, 0.984219, 0.000104555, 0, 0.0200831, 0.980425, 0.000131245, 0, 0.0267948, 0.974241, 0.000139613, 0, 0.034525, 0.967006, 0.000145931, 0, 0.0432757, 0.95893, 0.000167153, 0, 0.0530471, 0.949157, 0.000188146, 0, 0.0638386, 0.94062, 0.000194625, 0, 0.0756487, 0.933509, 0.000213721, 0, 0.0884762, 0.925088, 0.000229616, 0, 0.10232, 0.915178, 0.000239638, 0, 0.117178, 0.904093, 0.000254814, 0, 0.133051, 0.891337, 0.000263685, 0, 0.149939, 0.877326, 0.000274789, 0, 0.167841, 0.861794, 0.000280534, 0, 0.18676, 0.845758, 0.000289534, 0, 0.206696, 0.829792, 0.000294446, 0, 0.22765, 0.813037, 0.000296877, 0, 0.249625, 0.795285, 0.000300217, 0, 0.27262, 0.776323, 0.000299826, 0, 0.296636, 0.756673, 0.000299787, 0, 0.321671, 0.736856, 0.000297867, 0, 0.347718, 0.716883, 0.000294052, 0, 0.374768, 0.696089, 0.000289462, 0, 0.402804, 0.67505, 0.000285212, 0, 0.431796, 0.653509, 0.00027653, 0, 0.461695, 0.63258, 0.000271759, 0, 0.49242, 0.61104, 0.000262811, 0, 0.523822, 0.589567, 0.000255151, 0, 0.555556, 0.568322, 0.000246434, 0, 0.587302, 0.547235, 0.000237061, 0, 0.619048, 0.52616, 0.000228343, 0, 0.650794, 0.505716, 0.000219236, 0, 0.68254, 0.485274, 0.000209595, 0, 0.714286, 0.465411, 0.000201011, 0, 0.746032, 0.445854, 0.00019109, 0, 0.777778, 0.426911, 0.000182897, 0, 0.809524, 0.408222, 0.000173569, 0, 0.84127, 0.390307, 0.000165496, 0, 0.873016, 0.372624, 0.000156799, 0, 0.904762, 0.355804, 0.00014917, 0, 0.936508, 0.33924, 0.000140907, 0, 0.968254, 0.323534, 0.000134062, 0, 1, 1, 6.22487e-06, 0, 0, 1, 6.2251e-06, 0, 0, 1, 6.22837e-06, 0, 0, 0.999999, 6.24259e-06, 0, 0, 0.999998, 6.28127e-06, 0, 0, 0.999996, 6.36451e-06, 0, 0, 0.999991, 6.5218e-06, 0, 0, 0.999984, 6.79782e-06, 0, 0, 0.999973, 7.26361e-06, 0, 0, 0.999955, 8.03644e-06, 0, 0, 0.999931, 9.31397e-06, 0, 0, 0.999896, 1.14299e-05, 0, 0, 0.999847, 1.49402e-05, 0, 0, 0.999784, 2.07461e-05, 0, 0, 0.999692, 3.02493e-05, 0, 0, 0.999554, 4.54957e-05, 0, 9.97275e-05, 0.999326, 6.90762e-05, 0, 0.000724813, 0.998757, 0.000101605, 0, 0.0020972, 0.995367, 9.58745e-05, 0, 0.00432324, 0.99209, 8.32808e-05, 0, 0.00746347, 0.989517, 8.87601e-05, 0, 0.0115534, 0.987008, 0.00010564, 0, 0.0166134, 0.98421, 0.000133179, 0, 0.0226552, 0.98021, 0.000161746, 0, 0.0296838, 0.973676, 0.000161821, 0, 0.0377016, 0.967052, 0.000178635, 0, 0.0467079, 0.959385, 0.000206765, 0, 0.0567013, 0.949461, 0.00022476, 0, 0.0676796, 0.939578, 0.00023574, 0, 0.0796403, 0.932416, 0.00025893, 0, 0.0925812, 0.923759, 0.000271228, 0, 0.106501, 0.914223, 0.000289165, 0, 0.121397, 0.902942, 0.000301156, 0, 0.13727, 0.890419, 0.000313852, 0, 0.15412, 0.876639, 0.000324408, 0, 0.171946, 0.861316, 0.00033249, 0, 0.190751, 0.84496, 0.000338497, 0, 0.210537, 0.828427, 0.000345861, 0, 0.231305, 0.811871, 0.000347863, 0, 0.253057, 0.794397, 0.000350225, 0, 0.275797, 0.775726, 0.000349915, 0, 0.299525, 0.75617, 0.000347297, 0, 0.324242, 0.736091, 0.000344232, 0, 0.349947, 0.716213, 0.000340835, 0, 0.376633, 0.695736, 0.000332369, 0, 0.404289, 0.674961, 0.000327943, 0, 0.432895, 0.653518, 0.000318533, 0, 0.462415, 0.632574, 0.000310391, 0, 0.492788, 0.61134, 0.000300755, 0, 0.523909, 0.590017, 0.000290506, 0, 0.555556, 0.568752, 0.000280446, 0, 0.587302, 0.548061, 0.000269902, 0, 0.619048, 0.52711, 0.000258815, 0, 0.650794, 0.506682, 0.000248481, 0, 0.68254, 0.486524, 0.000237141, 0, 0.714286, 0.466812, 0.000226872, 0, 0.746032, 0.44732, 0.000216037, 0, 0.777778, 0.428473, 0.000205629, 0, 0.809524, 0.409921, 0.000195691, 0, 0.84127, 0.392028, 0.000185457, 0, 0.873016, 0.374606, 0.000176436, 0, 0.904762, 0.357601, 0.000166508, 0, 0.936508, 0.341348, 0.000158385, 0, 0.968254, 0.32542, 0.000149203, 0, 1, 1, 1.03967e-05, 0, 0, 1, 1.0397e-05, 0, 0, 1, 1.04019e-05, 0, 0, 0.999999, 1.04231e-05, 0, 0, 0.999998, 1.04806e-05, 0, 0, 0.999995, 1.06042e-05, 0, 0, 0.999991, 1.08366e-05, 0, 0, 0.999982, 1.12415e-05, 0, 0, 0.999968, 1.19174e-05, 0, 0, 0.99995, 1.30227e-05, 0, 0, 0.999922, 1.48176e-05, 0, 0, 0.999884, 1.77303e-05, 0, 0, 0.99983, 2.24564e-05, 0, 0, 0.999758, 3.00966e-05, 0, 0, 0.999654, 4.23193e-05, 0, 5.49083e-06, 0.999503, 6.14848e-05, 0, 0.000296087, 0.999237, 9.03576e-05, 0, 0.00123144, 0.998491, 0.0001271, 0, 0.00295954, 0.994594, 0.000107754, 0, 0.00555829, 0.99178, 0.000103025, 0, 0.00907209, 0.989265, 0.00011154, 0, 0.0135257, 0.986998, 0.000136296, 0, 0.0189327, 0.984137, 0.000169154, 0, 0.0252993, 0.979798, 0.000196671, 0, 0.0326272, 0.97337, 0.000196678, 0, 0.0409157, 0.967239, 0.000223121, 0, 0.0501623, 0.959543, 0.000253809, 0, 0.0603638, 0.949466, 0.000265972, 0, 0.0715171, 0.939074, 0.000288372, 0, 0.0836187, 0.931118, 0.000310983, 0, 0.0966657, 0.922525, 0.000325561, 0, 0.110656, 0.912983, 0.000345725, 0, 0.125588, 0.901617, 0.0003556, 0, 0.141461, 0.889487, 0.000374012, 0, 0.158275, 0.875787, 0.000383445, 0, 0.176031, 0.860654, 0.000393972, 0, 0.19473, 0.844417, 0.000400311, 0, 0.214374, 0.82741, 0.000405004, 0, 0.234967, 0.810545, 0.000407378, 0, 0.256512, 0.793312, 0.000407351, 0, 0.279011, 0.774847, 0.000406563, 0, 0.302468, 0.755621, 0.000404903, 0, 0.326887, 0.735511, 0.000397486, 0, 0.352266, 0.715435, 0.00039357, 0, 0.378605, 0.695403, 0.000384739, 0, 0.405897, 0.674681, 0.000376108, 0, 0.43413, 0.65359, 0.000365997, 0, 0.463277, 0.632471, 0.000354957, 0, 0.493295, 0.61151, 0.000343593, 0, 0.524106, 0.59064, 0.000331841, 0, 0.555561, 0.569386, 0.000318891, 0, 0.587302, 0.548785, 0.0003072, 0, 0.619048, 0.528146, 0.00029361, 0, 0.650794, 0.507872, 0.000281709, 0, 0.68254, 0.487805, 0.000268627, 0, 0.714286, 0.468196, 0.000255887, 0, 0.746032, 0.448922, 0.000243997, 0, 0.777778, 0.430093, 0.000231662, 0, 0.809524, 0.411845, 0.000220339, 0, 0.84127, 0.393808, 0.000208694, 0, 0.873016, 0.376615, 0.000198045, 0, 0.904762, 0.359655, 0.000187375, 0, 0.936508, 0.343452, 0.000177371, 0, 0.968254, 0.32765, 0.000167525, 0, 1, 1, 1.69351e-05, 0, 0, 1, 1.69356e-05, 0, 0, 1, 1.69427e-05, 0, 0, 0.999999, 1.69736e-05, 0, 0, 0.999998, 1.70575e-05, 0, 0, 0.999995, 1.72372e-05, 0, 0, 0.99999, 1.75739e-05, 0, 0, 0.999979, 1.81568e-05, 0, 0, 0.999966, 1.91206e-05, 0, 0, 0.999944, 2.0677e-05, 0, 0, 0.999912, 2.31644e-05, 0, 0, 0.999869, 2.71268e-05, 0, 0, 0.999811, 3.34272e-05, 0, 0, 0.99973, 4.33979e-05, 0, 0, 0.999617, 5.90083e-05, 0, 6.80315e-05, 0.999445, 8.29497e-05, 0, 0.000612796, 0.999138, 0.000118019, 0, 0.00187408, 0.998095, 0.000156712, 0, 0.00395791, 0.993919, 0.000125054, 0, 0.00692144, 0.991333, 0.000126091, 0, 0.0107962, 0.989226, 0.000144912, 0, 0.0155986, 0.986954, 0.000175737, 0, 0.0213364, 0.983982, 0.000213883, 0, 0.0280114, 0.979128, 0.000234526, 0, 0.0356226, 0.973327, 0.000243725, 0, 0.0441668, 0.967416, 0.0002773, 0, 0.0536399, 0.959729, 0.000308799, 0, 0.0640376, 0.949758, 0.000322447, 0, 0.0753554, 0.939173, 0.000350021, 0, 0.0875893, 0.9296, 0.000370089, 0, 0.100736, 0.921181, 0.000391365, 0, 0.114793, 0.91164, 0.000413636, 0, 0.129759, 0.900435, 0.000427068, 0, 0.145632, 0.888183, 0.000441046, 0, 0.162412, 0.874772, 0.000454968, 0, 0.180101, 0.859566, 0.000461882, 0, 0.1987, 0.843579, 0.000471556, 0, 0.218213, 0.826453, 0.000474335, 0, 0.238641, 0.809164, 0.000477078, 0, 0.259989, 0.792179, 0.00047755, 0, 0.282262, 0.773866, 0.000472573, 0, 0.305464, 0.754944, 0.000469765, 0, 0.329599, 0.735133, 0.000462371, 0, 0.35467, 0.714858, 0.000453674, 0, 0.380678, 0.694829, 0.000443888, 0, 0.407622, 0.674453, 0.000432052, 0, 0.435493, 0.653685, 0.000420315, 0, 0.464275, 0.632666, 0.000406829, 0, 0.493938, 0.611676, 0.000392234, 0, 0.524422, 0.591193, 0.000379208, 0, 0.555624, 0.570145, 0.00036319, 0, 0.587302, 0.549566, 0.000349111, 0, 0.619048, 0.529278, 0.000334166, 0, 0.650794, 0.509026, 0.000318456, 0, 0.68254, 0.489186, 0.00030449, 0, 0.714286, 0.469662, 0.000289051, 0, 0.746032, 0.450691, 0.000275494, 0, 0.777778, 0.431841, 0.000261437, 0, 0.809524, 0.413752, 0.000247846, 0, 0.84127, 0.395951, 0.000235085, 0, 0.873016, 0.378633, 0.000222245, 0, 0.904762, 0.36194, 0.000210533, 0, 0.936508, 0.345599, 0.000198494, 0, 0.968254, 0.329999, 0.000188133, 0, 1, 1, 2.69663e-05, 0, 0, 1, 2.6967e-05, 0, 0, 1, 2.69772e-05, 0, 0, 0.999999, 2.70214e-05, 0, 0, 0.999998, 2.71415e-05, 0, 0, 0.999994, 2.7398e-05, 0, 0, 0.999988, 2.78771e-05, 0, 0, 0.999977, 2.87019e-05, 0, 0, 0.999961, 3.00544e-05, 0, 0, 0.999937, 3.22138e-05, 0, 0, 0.999904, 3.56163e-05, 0, 0, 0.999854, 4.09465e-05, 0, 0, 0.99979, 4.92651e-05, 0, 0, 0.999699, 6.21722e-05, 0, 8.8288e-07, 0.999572, 8.19715e-05, 0, 0.000223369, 0.999381, 0.000111689, 0, 0.00105414, 0.999016, 0.000153862, 0, 0.0026493, 0.997437, 0.000187667, 0, 0.00508608, 0.993545, 0.000155672, 0, 0.00840554, 0.991135, 0.000161455, 0, 0.012629, 0.989157, 0.000188241, 0, 0.0177661, 0.986874, 0.000226229, 0, 0.0238198, 0.983714, 0.000268668, 0, 0.0307887, 0.978301, 0.000277109, 0, 0.0386688, 0.973227, 0.000303446, 0, 0.0474554, 0.967317, 0.000341851, 0, 0.0571428, 0.959477, 0.000370885, 0, 0.0677256, 0.950012, 0.000392753, 0, 0.0791988, 0.939484, 0.00042781, 0, 0.0915576, 0.928135, 0.000443866, 0, 0.104798, 0.919819, 0.000472959, 0, 0.118918, 0.910049, 0.000491551, 0, 0.133915, 0.899181, 0.000512616, 0, 0.149788, 0.886881, 0.000523563, 0, 0.166537, 0.87359, 0.000540183, 0, 0.184164, 0.858613, 0.000547386, 0, 0.202669, 0.842809, 0.000554809, 0, 0.222056, 0.825727, 0.000558316, 0, 0.242329, 0.808086, 0.000557824, 0, 0.263492, 0.790728, 0.000556346, 0, 0.285551, 0.772987, 0.000552672, 0, 0.30851, 0.7541, 0.000543738, 0, 0.332376, 0.734669, 0.000536107, 0, 0.357153, 0.714411, 0.000523342, 0, 0.382845, 0.694196, 0.000512238, 0, 0.409454, 0.674252, 0.000497465, 0, 0.436977, 0.65357, 0.000481096, 0, 0.465404, 0.632999, 0.000467054, 0, 0.494713, 0.611994, 0.000448771, 0, 0.524864, 0.591604, 0.000431889, 0, 0.555779, 0.571134, 0.000415238, 0, 0.587302, 0.550528, 0.000396369, 0, 0.619048, 0.530292, 0.000379477, 0, 0.650794, 0.510364, 0.000361488, 0, 0.68254, 0.490749, 0.000343787, 0, 0.714286, 0.471266, 0.000327822, 0, 0.746032, 0.452462, 0.000310626, 0, 0.777778, 0.433907, 0.000295352, 0, 0.809524, 0.415659, 0.000279179, 0, 0.84127, 0.398138, 0.000264685, 0, 0.873016, 0.380833, 0.000249905, 0, 0.904762, 0.364247, 0.000236282, 0, 0.936508, 0.348041, 0.000222905, 0, 0.968254, 0.332389, 0.000210522, 0, 1, 1, 4.20604e-05, 0, 0, 1, 4.20614e-05, 0, 0, 1, 4.20757e-05, 0, 0, 0.999999, 4.2138e-05, 0, 0, 0.999997, 4.23067e-05, 0, 0, 0.999993, 4.26668e-05, 0, 0, 0.999986, 4.33372e-05, 0, 0, 0.999974, 4.44857e-05, 0, 0, 0.999956, 4.63554e-05, 0, 0, 0.99993, 4.93105e-05, 0, 0, 0.999892, 5.39077e-05, 0, 0, 0.999838, 6.10005e-05, 0, 0, 0.999767, 7.18822e-05, 0, 0, 0.999666, 8.84581e-05, 0, 3.65471e-05, 0.999525, 0.000113398, 0, 0.000485623, 0.999311, 0.000150043, 0, 0.00162096, 0.998865, 0.000200063, 0, 0.00355319, 0.996278, 0.000211014, 0, 0.00633818, 0.992956, 0.000189672, 0, 0.0100043, 0.991017, 0.000210262, 0, 0.0145648, 0.989055, 0.000244292, 0, 0.0200237, 0.986741, 0.000290481, 0, 0.0263798, 0.983288, 0.000334303, 0, 0.033629, 0.977784, 0.000340307, 0, 0.0417652, 0.973037, 0.000377864, 0, 0.0507821, 0.967181, 0.0004239, 0, 0.060673, 0.958971, 0.000443854, 0, 0.0714314, 0.950093, 0.000483039, 0, 0.0830518, 0.939552, 0.000517934, 0, 0.0955288, 0.927678, 0.000539449, 0, 0.108859, 0.918278, 0.000568604, 0, 0.123038, 0.908449, 0.000588505, 0, 0.138065, 0.897713, 0.000612473, 0, 0.153938, 0.885533, 0.000625575, 0, 0.170657, 0.872131, 0.00063854, 0, 0.188224, 0.857517, 0.000647034, 0, 0.20664, 0.841796, 0.00065209, 0, 0.225909, 0.824726, 0.0006544, 0, 0.246035, 0.807297, 0.000655744, 0, 0.267022, 0.789058, 0.000646716, 0, 0.288878, 0.77189, 0.000643898, 0, 0.311607, 0.753082, 0.000629973, 0, 0.335216, 0.7341, 0.000621564, 0, 0.359713, 0.714094, 0.000605171, 0, 0.385103, 0.693839, 0.000588752, 0, 0.41139, 0.673891, 0.000573294, 0, 0.438576, 0.653565, 0.000552682, 0, 0.466656, 0.633326, 0.000533446, 0, 0.495617, 0.612582, 0.000514635, 0, 0.525431, 0.59205, 0.00049303, 0, 0.556041, 0.571918, 0.000471842, 0, 0.587338, 0.551572, 0.000451713, 0, 0.619048, 0.531553, 0.000430049, 0, 0.650794, 0.51175, 0.000410445, 0, 0.68254, 0.49238, 0.000390098, 0, 0.714286, 0.473143, 0.000370033, 0, 0.746032, 0.45423, 0.000351205, 0, 0.777778, 0.435963, 0.000332049, 0, 0.809524, 0.41787, 0.000315021, 0, 0.84127, 0.400387, 0.000297315, 0, 0.873016, 0.383332, 0.000281385, 0, 0.904762, 0.366665, 0.000265397, 0, 0.936508, 0.350633, 0.000250601, 0, 0.968254, 0.334964, 0.00023589, 0, 1, 1, 6.43736e-05, 0, 0, 1, 6.4375e-05, 0, 0, 1, 6.43947e-05, 0, 0, 0.999999, 6.4481e-05, 0, 0, 0.999997, 6.47143e-05, 0, 0, 0.999994, 6.52119e-05, 0, 0, 0.999985, 6.61359e-05, 0, 0, 0.999972, 6.77116e-05, 0, 0, 0.999952, 7.02599e-05, 0, 0, 0.999922, 7.42517e-05, 0, 0, 0.99988, 8.03906e-05, 0, 0, 0.99982, 8.97315e-05, 0, 0, 0.999741, 0.000103838, 0, 0, 0.999629, 0.00012496, 0, 0.000149024, 0.999474, 0.000156161, 0, 0.000861027, 0.999229, 0.000201034, 0, 0.00231198, 0.998662, 0.000259069, 0, 0.00458147, 0.995299, 0.000245439, 0, 0.00770895, 0.992732, 0.00024498, 0, 0.0117126, 0.990847, 0.000273211, 0, 0.0165989, 0.988911, 0.000316492, 0, 0.0223674, 0.98654, 0.00037161, 0, 0.0290135, 0.982636, 0.000410352, 0, 0.0365309, 0.977346, 0.000421756, 0, 0.0449117, 0.972909, 0.000475578, 0, 0.0541481, 0.966821, 0.000522482, 0, 0.0642326, 0.958686, 0.000545008, 0, 0.075158, 0.949754, 0.000589286, 0, 0.0869181, 0.939184, 0.000619995, 0, 0.0995074, 0.927505, 0.000654266, 0, 0.112922, 0.916606, 0.000682362, 0, 0.127157, 0.906707, 0.000704286, 0, 0.142212, 0.895937, 0.000725909, 0, 0.158085, 0.883913, 0.000743939, 0, 0.174776, 0.870642, 0.000755157, 0, 0.192287, 0.856241, 0.000764387, 0, 0.210619, 0.84069, 0.000771032, 0, 0.229775, 0.823728, 0.000765906, 0, 0.249761, 0.806481, 0.000767604, 0, 0.270582, 0.787924, 0.000754385, 0, 0.292243, 0.770588, 0.000749668, 0, 0.314753, 0.751991, 0.000731613, 0, 0.338118, 0.733407, 0.000717655, 0, 0.362347, 0.713688, 0.000700604, 0, 0.387447, 0.693595, 0.000678765, 0, 0.413424, 0.673426, 0.000657042, 0, 0.440284, 0.65359, 0.000635892, 0, 0.468027, 0.633576, 0.000611569, 0, 0.496645, 0.613144, 0.000586011, 0, 0.526122, 0.592711, 0.000563111, 0, 0.556417, 0.572722, 0.000537699, 0, 0.587451, 0.552762, 0.000512556, 0, 0.619048, 0.532985, 0.000489757, 0, 0.650794, 0.513219, 0.000464139, 0, 0.68254, 0.493992, 0.000442193, 0, 0.714286, 0.47509, 0.000418629, 0, 0.746032, 0.456287, 0.000397045, 0, 0.777778, 0.438152, 0.000375504, 0, 0.809524, 0.420294, 0.00035492, 0, 0.84127, 0.402749, 0.000335327, 0, 0.873016, 0.385879, 0.000316422, 0, 0.904762, 0.369352, 0.000298333, 0, 0.936508, 0.353301, 0.000281417, 0, 0.968254, 0.337781, 0.000265203, 0, 1, 1, 9.68267e-05, 0, 0, 1, 9.68284e-05, 0, 0, 1, 9.68556e-05, 0, 0, 0.999999, 9.69733e-05, 0, 0, 0.999997, 9.72913e-05, 0, 0, 0.999993, 9.79688e-05, 0, 0, 0.999984, 9.92239e-05, 0, 0, 0.999969, 0.000101356, 0, 0, 0.999946, 0.000104784, 0, 0, 0.999913, 0.000110111, 0, 0, 0.999868, 0.000118217, 0, 0, 0.999801, 0.000130396, 0, 0, 0.999712, 0.000148523, 0, 1.24907e-05, 0.999589, 0.000175233, 0, 0.000355405, 0.999416, 0.000213999, 0, 0.0013528, 0.999136, 0.000268529, 0, 0.00312557, 0.998367, 0.000333088, 0, 0.00573045, 0.994701, 0.000304757, 0, 0.00919397, 0.992497, 0.000318031, 0, 0.0135261, 0.990608, 0.000353863, 0, 0.0187278, 0.988715, 0.000409044, 0, 0.0247947, 0.986241, 0.000472967, 0, 0.0317196, 0.981696, 0.000495104, 0, 0.039494, 0.977097, 0.000532873, 0, 0.0481087, 0.972583, 0.000594447, 0, 0.0575549, 0.966142, 0.000636867, 0, 0.0678242, 0.95823, 0.000669899, 0, 0.0789089, 0.949677, 0.000719499, 0, 0.0908023, 0.939226, 0.000750584, 0, 0.103499, 0.927501, 0.000793183, 0, 0.116993, 0.915199, 0.00081995, 0, 0.131282, 0.90498, 0.000847654, 0, 0.146364, 0.894243, 0.000868929, 0, 0.162237, 0.882154, 0.000884278, 0, 0.178902, 0.869161, 0.000898108, 0, 0.196358, 0.854751, 0.000901254, 0, 0.21461, 0.839368, 0.00090679, 0, 0.23366, 0.822874, 0.000901541, 0, 0.253512, 0.805514, 0.000897297, 0, 0.274174, 0.78716, 0.000881856, 0, 0.29565, 0.769061, 0.000870032, 0, 0.31795, 0.751, 0.000851719, 0, 0.341081, 0.732614, 0.000830671, 0, 0.365053, 0.713171, 0.000806569, 0, 0.389874, 0.693472, 0.00078338, 0, 0.415553, 0.673528, 0.000756404, 0, 0.442098, 0.653397, 0.000726872, 0, 0.469512, 0.633781, 0.000700494, 0, 0.497794, 0.613877, 0.00067105, 0, 0.526935, 0.593506, 0.000640361, 0, 0.556908, 0.573667, 0.000613502, 0, 0.587657, 0.553932, 0.000583177, 0, 0.61906, 0.534345, 0.000554375, 0, 0.650794, 0.515042, 0.000527811, 0, 0.68254, 0.495674, 0.000499367, 0, 0.714286, 0.477132, 0.00047429, 0, 0.746032, 0.458609, 0.000447726, 0, 0.777778, 0.440354, 0.000424205, 0, 0.809524, 0.422765, 0.000399549, 0, 0.84127, 0.405472, 0.000378315, 0, 0.873016, 0.388482, 0.000355327, 0, 0.904762, 0.372191, 0.000336122, 0, 0.936508, 0.356099, 0.000315247, 0, 0.968254, 0.340737, 0.00029794, 0, 1, 1, 0.000143327, 0, 0, 1, 0.00014333, 0, 0, 1, 0.000143366, 0, 0, 0.999999, 0.000143524, 0, 0, 0.999996, 0.000143952, 0, 0, 0.999991, 0.000144862, 0, 0, 0.999981, 0.000146544, 0, 0, 0.999966, 0.000149391, 0, 0, 0.999941, 0.000153946, 0, 0, 0.999905, 0.000160971, 0, 0, 0.999852, 0.000171562, 0, 0, 0.99978, 0.00018729, 0, 0, 0.999681, 0.000210386, 0, 8.26239e-05, 0.999546, 0.000243906, 0, 0.000664807, 0.999352, 0.000291739, 0, 0.00196192, 0.999027, 0.000357419, 0, 0.00405941, 0.997886, 0.000422349, 0, 0.00699664, 0.99419, 0.000385008, 0, 0.0107896, 0.99214, 0.000409775, 0, 0.0154415, 0.990274, 0.000456418, 0, 0.0209488, 0.988455, 0.000527008, 0, 0.0273037, 0.985804, 0.000597685, 0, 0.0344969, 0.98103, 0.000613124, 0, 0.0425183, 0.976674, 0.000668321, 0, 0.0513575, 0.972021, 0.000736985, 0, 0.0610046, 0.965274, 0.000773789, 0, 0.0714508, 0.958046, 0.000830852, 0, 0.0826877, 0.949333, 0.000875766, 0, 0.0947085, 0.939135, 0.000917088, 0, 0.107507, 0.927119, 0.000952244, 0, 0.121078, 0.91469, 0.000990626, 0, 0.135419, 0.903006, 0.00101304, 0, 0.150526, 0.892368, 0.00103834, 0, 0.166399, 0.880231, 0.00105002, 0, 0.183038, 0.867432, 0.00106331, 0, 0.200443, 0.853208, 0.00106783, 0, 0.218618, 0.837956, 0.00106458, 0, 0.237566, 0.821772, 0.00105945, 0, 0.257291, 0.804328, 0.00104685, 0, 0.2778, 0.786465, 0.00103178, 0, 0.2991, 0.768004, 0.00101077, 0, 0.321199, 0.74972, 0.000985504, 0, 0.344106, 0.731682, 0.000962893, 0, 0.36783, 0.712813, 0.000932146, 0, 0.392383, 0.693139, 0.00089871, 0, 0.417774, 0.673566, 0.000869678, 0, 0.444013, 0.653483, 0.000835525, 0, 0.471107, 0.633891, 0.000799853, 0, 0.49906, 0.614433, 0.000766838, 0, 0.527869, 0.594586, 0.000732227, 0, 0.557517, 0.574769, 0.000696442, 0, 0.587966, 0.555149, 0.000663935, 0, 0.61913, 0.535898, 0.000629826, 0, 0.650794, 0.516753, 0.000596486, 0, 0.68254, 0.497816, 0.000567078, 0, 0.714286, 0.479034, 0.000534399, 0, 0.746032, 0.460975, 0.000507013, 0, 0.777778, 0.442935, 0.000477421, 0, 0.809524, 0.425263, 0.000451101, 0, 0.84127, 0.408248, 0.000424964, 0, 0.873016, 0.391339, 0.00039993, 0, 0.904762, 0.37513, 0.000377619, 0, 0.936508, 0.359172, 0.000354418, 0, 0.968254, 0.343876, 0.000334823, 0, 1, 1, 0.000209042, 0, 0, 1, 0.000209045, 0, 0, 1, 0.000209093, 0, 0, 0.999999, 0.000209304, 0, 0, 0.999996, 0.000209871, 0, 0, 0.999991, 0.000211078, 0, 0, 0.999979, 0.000213304, 0, 0, 0.999963, 0.000217061, 0, 0, 0.999933, 0.000223042, 0, 0, 0.999894, 0.000232206, 0, 0, 0.999837, 0.000245901, 0, 0, 0.999756, 0.000266023, 0, 1.02927e-06, 0.999648, 0.000295204, 0, 0.000233468, 0.999499, 0.000336958, 0, 0.00108237, 0.999283, 0.000395563, 0, 0.00268832, 0.998896, 0.000473785, 0, 0.00511138, 0.997006, 0.000520008, 0, 0.00837705, 0.993819, 0.000497261, 0, 0.0124928, 0.991632, 0.000523722, 0, 0.0174561, 0.989875, 0.000587258, 0, 0.0232596, 0.988109, 0.000676329, 0, 0.0298932, 0.985155, 0.000747701, 0, 0.0373453, 0.980479, 0.000768803, 0, 0.0456045, 0.976271, 0.000841054, 0, 0.0546593, 0.971347, 0.000911469, 0, 0.0644994, 0.964528, 0.000953057, 0, 0.0751152, 0.957632, 0.00102221, 0, 0.0864981, 0.948681, 0.00106122, 0, 0.0986407, 0.938716, 0.00111857, 0, 0.111537, 0.926629, 0.00114762, 0, 0.125182, 0.914025, 0.00118995, 0, 0.139571, 0.901026, 0.00121228, 0, 0.154703, 0.890358, 0.00123946, 0, 0.170576, 0.878283, 0.0012527, 0, 0.18719, 0.865459, 0.00125536, 0, 0.204547, 0.851407, 0.00126134, 0, 0.222648, 0.836276, 0.00124759, 0, 0.241498, 0.820436, 0.00124443, 0, 0.261101, 0.803253, 0.00122071, 0, 0.281465, 0.785562, 0.00120107, 0, 0.302595, 0.76718, 0.00117762, 0, 0.324501, 0.748551, 0.00114289, 0, 0.347192, 0.730564, 0.00110872, 0, 0.370679, 0.712253, 0.00107636, 0, 0.394973, 0.692867, 0.00103646, 0, 0.420085, 0.673695, 0.000996793, 0, 0.446027, 0.653912, 0.00095675, 0, 0.47281, 0.634129, 0.000916739, 0, 0.500441, 0.615004, 0.000874401, 0, 0.528921, 0.595587, 0.000833411, 0, 0.558244, 0.575965, 0.000794556, 0, 0.588384, 0.5566, 0.00075196, 0, 0.619281, 0.537428, 0.000716381, 0, 0.650795, 0.518623, 0.000676558, 0, 0.68254, 0.499964, 0.00064074, 0, 0.714286, 0.481356, 0.000605984, 0, 0.746032, 0.463279, 0.000570256, 0, 0.777778, 0.445673, 0.000540138, 0, 0.809524, 0.428032, 0.000507299, 0, 0.84127, 0.411112, 0.000479553, 0, 0.873016, 0.394444, 0.000450737, 0, 0.904762, 0.378247, 0.000424269, 0, 0.936508, 0.362415, 0.000399111, 0, 0.968254, 0.347103, 0.000375274, 0, 1, 1, 0.000300729, 0, 0, 1, 0.000300733, 0, 0, 1, 0.000300797, 0, 0, 0.999998, 0.000301072, 0, 0, 0.999996, 0.000301817, 0, 0, 0.999989, 0.000303398, 0, 0, 0.999977, 0.000306309, 0, 0, 0.999958, 0.000311209, 0, 0, 0.999927, 0.000318975, 0, 0, 0.999884, 0.000330804, 0, 0, 0.99982, 0.00034834, 0, 0, 0.999733, 0.000373854, 0, 3.26995e-05, 0.999613, 0.000410424, 0, 0.000477174, 0.999447, 0.000462047, 0, 0.00161099, 0.999204, 0.000533322, 0, 0.00353153, 0.998725, 0.000624964, 0, 0.00627965, 0.995871, 0.000631786, 0, 0.0098693, 0.993194, 0.000632017, 0, 0.0143011, 0.991541, 0.00068923, 0, 0.019568, 0.989773, 0.000766892, 0, 0.0256593, 0.987647, 0.000863668, 0, 0.0325625, 0.984193, 0.000922089, 0, 0.0402647, 0.980016, 0.000970749, 0, 0.0487532, 0.975859, 0.00106027, 0, 0.058016, 0.970514, 0.00112239, 0, 0.0680419, 0.963625, 0.00117212, 0, 0.0788208, 0.956959, 0.00125211, 0, 0.0903439, 0.947956, 0.00129411, 0, 0.102604, 0.93809, 0.00135879, 0, 0.115594, 0.92659, 0.00139309, 0, 0.129309, 0.913829, 0.00143253, 0, 0.143745, 0.90005, 0.00145809, 0, 0.158901, 0.888129, 0.0014748, 0, 0.174774, 0.87607, 0.00148756, 0, 0.191365, 0.863461, 0.00148714, 0, 0.208674, 0.849594, 0.00148892, 0, 0.226705, 0.834531, 0.00146496, 0, 0.245461, 0.81903, 0.0014579, 0, 0.264947, 0.802122, 0.00143039, 0, 0.28517, 0.78445, 0.00139717, 0, 0.306137, 0.766434, 0.00136312, 0, 0.327857, 0.747816, 0.00132597, 0, 0.350341, 0.729519, 0.00128323, 0, 0.373598, 0.711454, 0.00123803, 0, 0.397642, 0.692699, 0.00119097, 0, 0.422485, 0.673723, 0.00114565, 0, 0.448139, 0.654386, 0.00109552, 0, 0.474619, 0.634673, 0.00104553, 0, 0.501933, 0.615554, 0.00099985, 0, 0.530089, 0.596462, 0.000948207, 0, 0.559087, 0.577385, 0.000902299, 0, 0.588913, 0.558257, 0.000856448, 0, 0.619525, 0.5392, 0.000810395, 0, 0.650826, 0.520543, 0.000768558, 0, 0.68254, 0.502206, 0.0007239, 0, 0.714286, 0.48402, 0.000685794, 0, 0.746032, 0.465779, 0.00064471, 0, 0.777778, 0.448455, 0.000609583, 0, 0.809524, 0.431091, 0.00057227, 0, 0.84127, 0.414147, 0.00054042, 0, 0.873016, 0.39765, 0.000506545, 0, 0.904762, 0.381576, 0.000477635, 0, 0.936508, 0.365881, 0.000448446, 0, 0.968254, 0.350582, 0.000421424, 0, 1, 1, 0.000427144, 0, 0, 1, 0.000427151, 0, 0, 1, 0.000427232, 0, 0, 0.999998, 0.00042759, 0, 0, 0.999995, 0.000428555, 0, 0, 0.999988, 0.000430603, 0, 0, 0.999976, 0.000434368, 0, 0, 0.999952, 0.000440688, 0, 0, 0.999919, 0.000450667, 0, 0, 0.999871, 0.00046578, 0, 0, 0.999801, 0.000488024, 0, 0, 0.999704, 0.000520092, 0, 0.000129791, 0.999572, 0.000565553, 0, 0.000821056, 0.999389, 0.000628906, 0, 0.00225241, 0.999114, 0.000714911, 0, 0.00449109, 0.998488, 0.000819218, 0, 0.00756249, 0.995234, 0.00080415, 0, 0.0114716, 0.993021, 0.000830181, 0, 0.0162131, 0.991407, 0.000902645, 0, 0.021776, 0.989625, 0.000996934, 0, 0.0281471, 0.987064, 0.00109707, 0, 0.0353118, 0.983265, 0.00114353, 0, 0.0432562, 0.979535, 0.0012272, 0, 0.0519665, 0.975224, 0.00132642, 0, 0.0614298, 0.969574, 0.00138092, 0, 0.0716348, 0.963021, 0.00145896, 0, 0.0825709, 0.956046, 0.00152834, 0, 0.094229, 0.947136, 0.00158217, 0, 0.106602, 0.937313, 0.0016347, 0, 0.119682, 0.926073, 0.00168383, 0, 0.133465, 0.913121, 0.00171627, 0, 0.147947, 0.899165, 0.00174229, 0, 0.163125, 0.885891, 0.00176137, 0, 0.178998, 0.873783, 0.00176406, 0, 0.195566, 0.861331, 0.00176156, 0, 0.21283, 0.847569, 0.00175346, 0, 0.230793, 0.832785, 0.00172753, 0, 0.249459, 0.817442, 0.00170204, 0, 0.268832, 0.800613, 0.00166576, 0, 0.28892, 0.783597, 0.00162909, 0, 0.30973, 0.76571, 0.0015826, 0, 0.331271, 0.747021, 0.00153106, 0, 0.353554, 0.728593, 0.00148036, 0, 0.37659, 0.710661, 0.00142808, 0, 0.400391, 0.692426, 0.00136906, 0, 0.424973, 0.673623, 0.00131066, 0, 0.450347, 0.65494, 0.00125569, 0, 0.476531, 0.635448, 0.00119517, 0, 0.503535, 0.616221, 0.00113828, 0, 0.531372, 0.597531, 0.0010816, 0, 0.560047, 0.578795, 0.00102673, 0, 0.589554, 0.559892, 0.000970985, 0, 0.619869, 0.541307, 0.000919773, 0, 0.650923, 0.522608, 0.000868479, 0, 0.68254, 0.504484, 0.00082137, 0, 0.714286, 0.486603, 0.000772916, 0, 0.746032, 0.468802, 0.000730353, 0, 0.777778, 0.451172, 0.000684955, 0, 0.809524, 0.434348, 0.000647565, 0, 0.84127, 0.417445, 0.000605863, 0, 0.873016, 0.401077, 0.000571885, 0, 0.904762, 0.385039, 0.000536034, 0, 0.936508, 0.369483, 0.000504227, 0, 0.968254, 0.354272, 0.000473165, 0, 1, 1, 0.000599525, 0, 0, 1, 0.000599533, 0, 0, 1, 0.000599639, 0, 0, 0.999998, 0.000600097, 0, 0, 0.999994, 0.000601336, 0, 0, 0.999987, 0.000603958, 0, 0, 0.999972, 0.000608775, 0, 0, 0.999949, 0.000616842, 0, 0, 0.999912, 0.000629534, 0, 0, 0.999857, 0.000648658, 0, 0, 0.999781, 0.000676615, 0, 5.38873e-06, 0.999674, 0.000716574, 0, 0.000308602, 0.999528, 0.000772641, 0, 0.00127003, 0.999326, 0.000849806, 0, 0.00300783, 0.999009, 0.000952682, 0, 0.00556637, 0.998112, 0.00106394, 0, 0.00895889, 0.994496, 0.00102228, 0, 0.0131827, 0.992806, 0.00108586, 0, 0.0182277, 0.991211, 0.0011759, 0, 0.0240795, 0.989415, 0.00128955, 0, 0.030723, 0.986499, 0.00139038, 0, 0.0381418, 0.982679, 0.00144539, 0, 0.046321, 0.978839, 0.00153954, 0, 0.0552459, 0.974295, 0.00164417, 0, 0.0649034, 0.968784, 0.00171517, 0, 0.0752814, 0.962324, 0.00180282, 0, 0.0863693, 0.954956, 0.00186387, 0, 0.0981578, 0.94624, 0.00193817, 0, 0.110639, 0.936517, 0.00198156, 0, 0.123806, 0.925186, 0.00203042, 0, 0.137655, 0.91252, 0.0020664, 0, 0.15218, 0.898441, 0.00207822, 0, 0.16738, 0.884394, 0.0020992, 0, 0.183253, 0.871273, 0.00208748, 0, 0.199799, 0.859057, 0.00208686, 0, 0.21702, 0.845243, 0.00205519, 0, 0.234918, 0.830723, 0.00202868, 0, 0.253496, 0.815801, 0.00199501, 0, 0.272761, 0.79914, 0.00194193, 0, 0.292719, 0.782372, 0.00188824, 0, 0.313377, 0.76482, 0.00183695, 0, 0.334745, 0.746586, 0.00177418, 0, 0.356833, 0.7281, 0.00170628, 0, 0.379654, 0.709842, 0.00164063, 0, 0.403221, 0.692019, 0.00157355, 0, 0.427548, 0.67364, 0.00150262, 0, 0.452651, 0.655277, 0.00143473, 0, 0.478545, 0.636438, 0.00136371, 0, 0.505246, 0.617364, 0.00129911, 0, 0.532768, 0.598603, 0.00123014, 0, 0.561122, 0.580195, 0.00116587, 0, 0.590309, 0.561786, 0.00110398, 0, 0.620318, 0.543377, 0.00104148, 0, 0.651102, 0.525093, 0.000983984, 0, 0.682545, 0.506791, 0.00092667, 0, 0.714286, 0.489291, 0.000874326, 0, 0.746032, 0.471811, 0.000821734, 0, 0.777778, 0.454435, 0.000774698, 0, 0.809524, 0.437493, 0.000727302, 0, 0.84127, 0.420977, 0.000684039, 0, 0.873016, 0.404729, 0.00064373, 0, 0.904762, 0.388756, 0.00060285, 0, 0.936508, 0.373344, 0.00056765, 0, 0.968254, 0.358191, 0.000531929, 0, 1, 1, 0.000832169, 0, 0, 1, 0.000832178, 0, 0, 1, 0.00083231, 0, 0, 0.999998, 0.000832893, 0, 0, 0.999995, 0.000834465, 0, 0, 0.999985, 0.000837791, 0, 0, 0.999969, 0.000843893, 0, 0, 0.999944, 0.000854086, 0, 0, 0.999903, 0.000870071, 0, 0, 0.999843, 0.000894042, 0, 0, 0.999759, 0.000928865, 0, 5.31805e-05, 0.999643, 0.000978242, 0, 0.000579365, 0.99948, 0.00104684, 0, 0.00182774, 0.999255, 0.00114012, 0, 0.00387804, 0.998885, 0.00126188, 0, 0.00675709, 0.997405, 0.00135888, 0, 0.010468, 0.99424, 0.00133626, 0, 0.0150018, 0.992458, 0.00140905, 0, 0.0203443, 0.990929, 0.00152305, 0, 0.0264786, 0.989116, 0.00165882, 0, 0.0333875, 0.985624, 0.00174128, 0, 0.0410536, 0.982003, 0.00182108, 0, 0.0494609, 0.978336, 0.00194498, 0, 0.0585941, 0.973184, 0.00202708, 0, 0.0684396, 0.9678, 0.00212166, 0, 0.0789851, 0.961348, 0.00221366, 0, 0.0902199, 0.953841, 0.00228219, 0, 0.102134, 0.94534, 0.00235662, 0, 0.114721, 0.935552, 0.00240572, 0, 0.127972, 0.924064, 0.00244405, 0, 0.141884, 0.911827, 0.00247557, 0, 0.156451, 0.897731, 0.00248374, 0, 0.171672, 0.883409, 0.00249863, 0, 0.187545, 0.868625, 0.00246688, 0, 0.20407, 0.856529, 0.00246523, 0, 0.221249, 0.842999, 0.00242368, 0, 0.239083, 0.828505, 0.00237354, 0, 0.257578, 0.813825, 0.00232588, 0, 0.276738, 0.797813, 0.00226731, 0, 0.296569, 0.781097, 0.00219704, 0, 0.31708, 0.764038, 0.00212394, 0, 0.338281, 0.746067, 0.00204786, 0, 0.360181, 0.727687, 0.00196728, 0, 0.382794, 0.709571, 0.00188779, 0, 0.406133, 0.691503, 0.00180532, 0, 0.430213, 0.673673, 0.00171849, 0, 0.45505, 0.655732, 0.00164147, 0, 0.480662, 0.637399, 0.00155858, 0, 0.507065, 0.618616, 0.00147641, 0, 0.534278, 0.60005, 0.00140125, 0, 0.562313, 0.581713, 0.00132441, 0, 0.59118, 0.563546, 0.00125014, 0, 0.620875, 0.545605, 0.00118249, 0, 0.651373, 0.527559, 0.0011116, 0, 0.682593, 0.509764, 0.00104979, 0, 0.714286, 0.49193, 0.000985977, 0, 0.746032, 0.475011, 0.000928592, 0, 0.777778, 0.457878, 0.000873466, 0, 0.809524, 0.440979, 0.000819585, 0, 0.84127, 0.424613, 0.000772365, 0, 0.873016, 0.408549, 0.000722195, 0, 0.904762, 0.392771, 0.000680014, 0, 0.936508, 0.377317, 0.000636797, 0, 0.968254, 0.362352, 0.000598318, 0, 1, 1, 0.00114313, 0, 0, 1, 0.00114314, 0, 0, 0.999999, 0.00114331, 0, 0, 0.999998, 0.00114404, 0, 0, 0.999994, 0.00114601, 0, 0, 0.999984, 0.00115019, 0, 0, 0.999967, 0.00115784, 0, 0, 0.999937, 0.0011706, 0, 0, 0.999894, 0.00119054, 0, 0, 0.999828, 0.00122031, 0, 0, 0.999735, 0.00126331, 0, 0.000169263, 0.999606, 0.00132382, 0, 0.000949167, 0.999426, 0.0014071, 0, 0.00249668, 0.999173, 0.00151895, 0, 0.00486392, 0.99873, 0.00166102, 0, 0.00806323, 0.996243, 0.0017023, 0, 0.0120895, 0.993779, 0.00172782, 0, 0.0169288, 0.9919, 0.0018108, 0, 0.0225633, 0.990524, 0.00196028, 0, 0.028974, 0.98868, 0.00212014, 0, 0.036142, 0.984663, 0.00217598, 0, 0.044049, 0.981457, 0.00230563, 0, 0.0526781, 0.977608, 0.00243966, 0, 0.0620137, 0.972215, 0.00251336, 0, 0.0720418, 0.966798, 0.0026285, 0, 0.0827499, 0.960241, 0.00271409, 0, 0.0941271, 0.952489, 0.00278381, 0, 0.106164, 0.944127, 0.00285399, 0, 0.118852, 0.934282, 0.00290994, 0, 0.132185, 0.923271, 0.00294558, 0, 0.146157, 0.910803, 0.00296269, 0, 0.160766, 0.896705, 0.00296803, 0, 0.176007, 0.88238, 0.00296637, 0, 0.19188, 0.867116, 0.00293163, 0, 0.208385, 0.853636, 0.00289418, 0, 0.225523, 0.840469, 0.00284663, 0, 0.243296, 0.82639, 0.00278594, 0, 0.261709, 0.811759, 0.00271618, 0, 0.280767, 0.796113, 0.00263187, 0, 0.300476, 0.779518, 0.00254589, 0, 0.320845, 0.763142, 0.00246003, 0, 0.341883, 0.745464, 0.00236529, 0, 0.363601, 0.727491, 0.00226536, 0, 0.386011, 0.709414, 0.00216375, 0, 0.409128, 0.691396, 0.00207127, 0, 0.432967, 0.67368, 0.00197106, 0, 0.457545, 0.656049, 0.00187022, 0, 0.482881, 0.638188, 0.00177605, 0, 0.508992, 0.620177, 0.00168482, 0, 0.535899, 0.601506, 0.00158909, 0, 0.563619, 0.58362, 0.00150583, 0, 0.592165, 0.565496, 0.00141791, 0, 0.621544, 0.54789, 0.00133693, 0, 0.651743, 0.530323, 0.00126038, 0, 0.682709, 0.512795, 0.00118556, 0, 0.714286, 0.495199, 0.00111527, 0, 0.746032, 0.478101, 0.0010489, 0, 0.777778, 0.461511, 0.000984264, 0, 0.809524, 0.444879, 0.00092591, 0, 0.84127, 0.428424, 0.000866582, 0, 0.873016, 0.412495, 0.000814463, 0, 0.904762, 0.396975, 0.000764498, 0, 0.936508, 0.381614, 0.000715967, 0, 0.968254, 0.366732, 0.000672483, 0, 1, 1, 0.00155501, 0, 0, 1, 0.00155503, 0, 0, 1, 0.00155524, 0, 0, 0.999998, 0.00155615, 0, 0, 0.999994, 0.0015586, 0, 0, 0.999983, 0.00156379, 0, 0, 0.999963, 0.0015733, 0, 0, 0.999932, 0.00158911, 0, 0, 0.999882, 0.00161376, 0, 0, 0.99981, 0.00165041, 0, 1.00875e-05, 0.999708, 0.00170304, 0, 0.000367658, 0.999565, 0.00177658, 0, 0.0014234, 0.999368, 0.00187688, 0, 0.00327939, 0.999081, 0.00200989, 0, 0.00596629, 0.99852, 0.00217177, 0, 0.0094852, 0.99549, 0.0021745, 0, 0.013824, 0.993252, 0.00222357, 0, 0.0189642, 0.991727, 0.00235022, 0, 0.0248856, 0.989951, 0.00250561, 0, 0.0315669, 0.988029, 0.00268829, 0, 0.0389882, 0.984029, 0.0027496, 0, 0.0471302, 0.980683, 0.00289793, 0, 0.0559754, 0.976554, 0.00303315, 0, 0.0655081, 0.97139, 0.00313257, 0, 0.0757138, 0.965544, 0.00323656, 0, 0.08658, 0.95912, 0.00333432, 0, 0.0980954, 0.951183, 0.0034039, 0, 0.110251, 0.942974, 0.00347515, 0, 0.123038, 0.932642, 0.00350381, 0, 0.13645, 0.922158, 0.00354519, 0, 0.150482, 0.909404, 0.00353851, 0, 0.165129, 0.896071, 0.0035435, 0, 0.18039, 0.881206, 0.00349936, 0, 0.196263, 0.866077, 0.00347256, 0, 0.212748, 0.85093, 0.003415, 0, 0.229847, 0.837703, 0.00333367, 0, 0.247561, 0.823878, 0.003249, 0, 0.265895, 0.809449, 0.00316347, 0, 0.284854, 0.794379, 0.00306351, 0, 0.304445, 0.778138, 0.0029499, 0, 0.324675, 0.761997, 0.00284099, 0, 0.345555, 0.744938, 0.00272104, 0, 0.367095, 0.727212, 0.00260715, 0, 0.389309, 0.709549, 0.00248855, 0, 0.41221, 0.691704, 0.00236783, 0, 0.435814, 0.673689, 0.00225178, 0, 0.460138, 0.656453, 0.00213765, 0, 0.485203, 0.639128, 0.00202178, 0, 0.511028, 0.621512, 0.00191443, 0, 0.537634, 0.603598, 0.00180977, 0, 0.565041, 0.58559, 0.00170456, 0, 0.593268, 0.567852, 0.00160927, 0, 0.622327, 0.5503, 0.00151395, 0, 0.652217, 0.533033, 0.00142499, 0, 0.682907, 0.515942, 0.00133955, 0, 0.714296, 0.498814, 0.0012602, 0, 0.746032, 0.481595, 0.00118188, 0, 0.777778, 0.465117, 0.00111171, 0, 0.809524, 0.448865, 0.00104091, 0, 0.84127, 0.432711, 0.000976618, 0, 0.873016, 0.416822, 0.00091859, 0, 0.904762, 0.401272, 0.000857704, 0, 0.936508, 0.386226, 0.000807172, 0, 0.968254, 0.371321, 0.00075464, 0, 1, 1, 0.00209596, 0, 0, 1, 0.00209598, 0, 0, 1, 0.00209624, 0, 0, 0.999997, 0.00209736, 0, 0, 0.999991, 0.00210039, 0, 0, 0.999979, 0.00210678, 0, 0, 0.999959, 0.00211847, 0, 0, 0.999925, 0.0021379, 0, 0, 0.99987, 0.00216809, 0, 0, 0.999791, 0.00221281, 0, 6.81487e-05, 0.999677, 0.00227669, 0, 0.000658161, 0.999521, 0.00236533, 0, 0.00200635, 0.999301, 0.00248514, 0, 0.0041779, 0.998977, 0.00264185, 0, 0.00718648, 0.998191, 0.00281695, 0, 0.0110239, 0.994801, 0.00278518, 0, 0.015672, 0.993091, 0.00288774, 0, 0.0211091, 0.991571, 0.00303931, 0, 0.0273123, 0.9897, 0.00321643, 0, 0.034259, 0.987023, 0.00337332, 0, 0.0419282, 0.983289, 0.00346146, 0, 0.0502998, 0.979892, 0.00363704, 0, 0.0593562, 0.975111, 0.00373601, 0, 0.069081, 0.970351, 0.0038842, 0, 0.0794598, 0.964131, 0.00397053, 0, 0.0904798, 0.957747, 0.00408078, 0, 0.10213, 0.949536, 0.00413533, 0, 0.1144, 0.941372, 0.00420305, 0, 0.127284, 0.931049, 0.00422815, 0, 0.140772, 0.920647, 0.00425048, 0, 0.154862, 0.908033, 0.0042281, 0, 0.169548, 0.895028, 0.00422026, 0, 0.184828, 0.879968, 0.00415042, 0, 0.200701, 0.864875, 0.00408821, 0, 0.217167, 0.84918, 0.00400909, 0, 0.234227, 0.834934, 0.00391178, 0, 0.251884, 0.821397, 0.00380066, 0, 0.270141, 0.807135, 0.00367974, 0, 0.289004, 0.792363, 0.00355172, 0, 0.308479, 0.776661, 0.003411, 0, 0.328575, 0.760705, 0.00328123, 0, 0.349301, 0.744408, 0.00314003, 0, 0.370668, 0.726994, 0.0029906, 0, 0.392689, 0.709598, 0.00285034, 0, 0.415379, 0.692112, 0.00271179, 0, 0.438754, 0.674435, 0.00257185, 0, 0.46283, 0.65676, 0.00243425, 0, 0.48763, 0.639982, 0.00230351, 0, 0.513173, 0.622983, 0.0021777, 0, 0.539482, 0.605471, 0.00204991, 0, 0.566579, 0.58796, 0.00193759, 0, 0.594488, 0.570463, 0.00181976, 0, 0.623226, 0.553058, 0.00171497, 0, 0.6528, 0.535894, 0.00161109, 0, 0.683198, 0.519089, 0.00151394, 0, 0.714354, 0.502454, 0.00142122, 0, 0.746032, 0.485681, 0.00133488, 0, 0.777778, 0.468935, 0.00124975, 0, 0.809524, 0.452951, 0.00117309, 0, 0.84127, 0.437139, 0.00110155, 0, 0.873016, 0.421446, 0.00103124, 0, 0.904762, 0.405951, 0.000966387, 0, 0.936508, 0.391003, 0.000908119, 0, 0.968254, 0.376198, 0.000848057, 0, 1, 1, 0.00280076, 0, 0, 1, 0.00280078, 0, 0, 0.999999, 0.00280109, 0, 0, 0.999997, 0.00280246, 0, 0, 0.999992, 0.00280616, 0, 0, 0.999979, 0.00281396, 0, 0, 0.999956, 0.00282822, 0, 0, 0.999916, 0.00285186, 0, 0, 0.999857, 0.0028885, 0, 0, 0.999768, 0.00294259, 0, 0.000196026, 0.999645, 0.00301946, 0, 0.00104842, 0.99947, 0.00312541, 0, 0.00270199, 0.999229, 0.00326733, 0, 0.00519449, 0.998852, 0.00344992, 0, 0.00852602, 0.997558, 0.00361052, 0, 0.0126804, 0.994417, 0.0035898, 0, 0.017635, 0.992824, 0.00372393, 0, 0.023365, 0.991344, 0.00390695, 0, 0.0298456, 0.989337, 0.00410392, 0, 0.0370529, 0.985811, 0.00420987, 0, 0.0449651, 0.982772, 0.00437488, 0, 0.0535615, 0.979001, 0.00455069, 0, 0.0628243, 0.974102, 0.00464462, 0, 0.0727368, 0.969197, 0.00480577, 0, 0.0832844, 0.962759, 0.00487818, 0, 0.0944545, 0.956207, 0.00498176, 0, 0.106236, 0.947909, 0.00503392, 0, 0.118619, 0.939596, 0.00507474, 0, 0.131595, 0.929642, 0.00509798, 0, 0.145159, 0.918807, 0.00508476, 0, 0.159305, 0.906921, 0.00505634, 0, 0.174028, 0.893312, 0.00498845, 0, 0.189327, 0.878933, 0.0049133, 0, 0.2052, 0.863986, 0.0048259, 0, 0.221647, 0.847936, 0.00470848, 0, 0.23867, 0.832253, 0.00456889, 0, 0.25627, 0.818619, 0.00442726, 0, 0.274453, 0.804788, 0.00427677, 0, 0.293222, 0.790241, 0.00411906, 0, 0.312585, 0.775162, 0.00394833, 0, 0.33255, 0.759463, 0.00377366, 0, 0.353126, 0.743598, 0.00361026, 0, 0.374324, 0.72697, 0.00343627, 0, 0.396158, 0.709646, 0.00326422, 0, 0.418641, 0.69277, 0.00309717, 0, 0.44179, 0.675371, 0.0029356, 0, 0.465624, 0.657863, 0.00277712, 0, 0.490163, 0.640772, 0.00261738, 0, 0.515429, 0.624441, 0.0024737, 0, 0.541445, 0.607497, 0.00233125, 0, 0.568236, 0.590438, 0.00218994, 0, 0.595828, 0.573224, 0.0020664, 0, 0.624242, 0.556168, 0.00193526, 0, 0.653496, 0.539232, 0.00182463, 0, 0.683588, 0.522352, 0.00170735, 0, 0.714482, 0.506172, 0.00160555, 0, 0.746032, 0.489842, 0.00150451, 0, 0.777778, 0.473463, 0.00140938, 0, 0.809524, 0.457266, 0.00132568, 0, 0.84127, 0.441609, 0.0012376, 0, 0.873016, 0.426348, 0.00116265, 0, 0.904762, 0.411002, 0.00108935, 0, 0.936508, 0.396045, 0.00101946, 0, 0.968254, 0.381448, 0.000955665, 0, 1, 1, 0.0037121, 0, 0, 1, 0.00371213, 0, 0, 1, 0.00371251, 0, 0, 0.999997, 0.00371417, 0, 0, 0.99999, 0.00371863, 0, 0, 0.999977, 0.00372807, 0, 0, 0.99995, 0.00374529, 0, 0, 0.999908, 0.0037738, 0, 0, 0.999843, 0.00381789, 0, 1.23596e-05, 0.999745, 0.00388273, 0, 0.000407442, 0.999608, 0.00397443, 0, 0.0015447, 0.999415, 0.00409998, 0, 0.00351385, 0.999143, 0.00426662, 0, 0.0063316, 0.9987, 0.00447625, 0, 0.00998679, 0.996363, 0.00455323, 0, 0.0144569, 0.994021, 0.00461052, 0, 0.0197151, 0.992372, 0.00476359, 0, 0.0257344, 0.991007, 0.00499101, 0, 0.0324882, 0.988767, 0.0051972, 0, 0.0399517, 0.984872, 0.00528407, 0, 0.0481022, 0.982004, 0.00548926, 0, 0.0569191, 0.977714, 0.00564385, 0, 0.0663839, 0.973076, 0.0057693, 0, 0.0764801, 0.967565, 0.0058924, 0, 0.0871928, 0.961384, 0.00599629, 0, 0.0985095, 0.954435, 0.00605998, 0, 0.110419, 0.946303, 0.0061133, 0, 0.122912, 0.937662, 0.00612028, 0, 0.13598, 0.927867, 0.00612209, 0, 0.149617, 0.916475, 0.00604813, 0, 0.163817, 0.90541, 0.00603088, 0, 0.178577, 0.891591, 0.00592218, 0, 0.193894, 0.877573, 0.00578854, 0, 0.209767, 0.862511, 0.00566648, 0, 0.226196, 0.846861, 0.00551481, 0, 0.243182, 0.83068, 0.00533754, 0, 0.260728, 0.815725, 0.00515487, 0, 0.278837, 0.802321, 0.0049655, 0, 0.297515, 0.787826, 0.00475421, 0, 0.316768, 0.773454, 0.00456002, 0, 0.336605, 0.758224, 0.00434727, 0, 0.357034, 0.74265, 0.00414444, 0, 0.378067, 0.726729, 0.00393738, 0, 0.399717, 0.710155, 0.00373575, 0, 0.421998, 0.693312, 0.00353736, 0, 0.444928, 0.67653, 0.00334368, 0, 0.468523, 0.659444, 0.00315981, 0, 0.492806, 0.642051, 0.00297809, 0, 0.517798, 0.625758, 0.00280592, 0, 0.543525, 0.609615, 0.00264254, 0, 0.570012, 0.592919, 0.00248459, 0, 0.597288, 0.576298, 0.00233327, 0, 0.625379, 0.559489, 0.00219519, 0, 0.654307, 0.542891, 0.00205441, 0, 0.684084, 0.526255, 0.00193385, 0, 0.714693, 0.509853, 0.00180745, 0, 0.746044, 0.494131, 0.00169817, 0, 0.777778, 0.478114, 0.0015913, 0, 0.809524, 0.462274, 0.00148981, 0, 0.84127, 0.446412, 0.00139537, 0, 0.873016, 0.431274, 0.00130984, 0, 0.904762, 0.41635, 0.00122403, 0, 0.936508, 0.401476, 0.00114809, 0, 0.968254, 0.386993, 0.00107563, 0, 1, 1, 0.00488216, 0, 0, 1, 0.0048822, 0, 0, 1, 0.00488265, 0, 0, 0.999997, 0.00488463, 0, 0, 0.999988, 0.00488999, 0, 0, 0.999974, 0.00490129, 0, 0, 0.999946, 0.00492191, 0, 0, 0.999897, 0.00495598, 0, 0, 0.999825, 0.00500855, 0, 7.44791e-05, 0.999718, 0.00508559, 0, 0.000712744, 0.999565, 0.005194, 0, 0.00215249, 0.999352, 0.00534147, 0, 0.00444576, 0.999046, 0.00553523, 0, 0.00759218, 0.998492, 0.00577016, 0, 0.0115714, 0.995564, 0.00578487, 0, 0.0163557, 0.993339, 0.00586414, 0, 0.021915, 0.991834, 0.00606002, 0, 0.0282201, 0.990496, 0.00633312, 0, 0.0352433, 0.987826, 0.00651941, 0, 0.042959, 0.98383, 0.00660842, 0, 0.0513439, 0.98109, 0.00685523, 0, 0.0603772, 0.976131, 0.00695778, 0, 0.0700402, 0.971922, 0.00714236, 0, 0.0803163, 0.965901, 0.00721437, 0, 0.0911908, 0.959606, 0.00732017, 0, 0.102651, 0.952504, 0.00735788, 0, 0.114686, 0.944365, 0.00738493, 0, 0.127286, 0.935652, 0.00737969, 0, 0.140443, 0.925813, 0.00733612, 0, 0.154151, 0.914397, 0.00723094, 0, 0.168405, 0.903257, 0.00714002, 0, 0.183201, 0.890015, 0.00700149, 0, 0.198536, 0.876014, 0.00682813, 0, 0.214409, 0.861436, 0.00665567, 0, 0.23082, 0.845752, 0.00644526, 0, 0.24777, 0.829169, 0.00621635, 0, 0.265263, 0.813435, 0.00597789, 0, 0.283301, 0.799701, 0.00575694, 0, 0.301889, 0.785726, 0.00549866, 0, 0.321035, 0.77152, 0.0052503, 0, 0.340746, 0.75683, 0.00499619, 0, 0.361032, 0.741951, 0.0047543, 0, 0.381904, 0.726367, 0.0045084, 0, 0.403374, 0.710537, 0.00426784, 0, 0.425457, 0.693965, 0.00403487, 0, 0.448169, 0.677724, 0.0038075, 0, 0.47153, 0.66117, 0.00359431, 0, 0.495561, 0.644274, 0.00338354, 0, 0.520284, 0.627449, 0.00318163, 0, 0.545725, 0.611645, 0.00299672, 0, 0.571911, 0.595614, 0.00281016, 0, 0.598873, 0.579426, 0.00264252, 0, 0.62664, 0.563016, 0.00247509, 0, 0.655239, 0.546728, 0.00232647, 0, 0.684692, 0.530539, 0.00217803, 0, 0.714999, 0.514164, 0.00204216, 0, 0.746106, 0.498344, 0.00191403, 0, 0.777778, 0.482957, 0.00179203, 0, 0.809524, 0.467336, 0.00167695, 0, 0.84127, 0.451994, 0.00157567, 0, 0.873016, 0.436514, 0.00147113, 0, 0.904762, 0.42178, 0.00138034, 0, 0.936508, 0.407271, 0.00129219, 0, 0.968254, 0.392822, 0.0012098, 0, 1, 1, 0.00637427, 0, 0, 1, 0.00637431, 0, 0, 0.999999, 0.00637485, 0, 0, 0.999996, 0.00637721, 0, 0, 0.999987, 0.00638357, 0, 0, 0.999971, 0.006397, 0, 0, 0.999939, 0.00642142, 0, 0, 0.999888, 0.00646177, 0, 0, 0.999807, 0.00652387, 0, 0.000207916, 0.999689, 0.00661454, 0, 0.00112051, 0.99952, 0.00674155, 0, 0.00287719, 0.999283, 0.00691313, 0, 0.00550145, 0.998936, 0.00713598, 0, 0.00897928, 0.998165, 0.00738501, 0, 0.0132829, 0.994847, 0.00734388, 0, 0.01838, 0.993182, 0.00749991, 0, 0.0242381, 0.991665, 0.0077246, 0, 0.030826, 0.989708, 0.00797579, 0, 0.0381152, 0.986663, 0.00813011, 0, 0.0460794, 0.983288, 0.00830365, 0, 0.0546951, 0.980104, 0.00853496, 0, 0.0639411, 0.974855, 0.00861045, 0, 0.0737988, 0.97045, 0.00879133, 0, 0.0842516, 0.964509, 0.00886377, 0, 0.0952848, 0.957594, 0.00890346, 0, 0.106886, 0.950546, 0.00893289, 0, 0.119044, 0.942225, 0.00890074, 0, 0.131749, 0.933365, 0.00886826, 0, 0.144994, 0.923202, 0.0087316, 0, 0.158772, 0.912605, 0.00863082, 0, 0.173078, 0.901099, 0.00847403, 0, 0.187908, 0.888177, 0.00825838, 0, 0.203261, 0.873955, 0.00801834, 0, 0.219134, 0.860091, 0.00779026, 0, 0.235527, 0.84434, 0.00752478, 0, 0.252443, 0.828517, 0.00724074, 0, 0.269883, 0.81239, 0.00693769, 0, 0.287851, 0.79721, 0.00664817, 0, 0.306352, 0.783489, 0.00634763, 0, 0.325393, 0.769514, 0.00604221, 0, 0.344981, 0.755419, 0.00573568, 0, 0.365126, 0.741083, 0.00544359, 0, 0.385839, 0.726059, 0.00515515, 0, 0.407132, 0.710809, 0.00487139, 0, 0.42902, 0.695052, 0.00459846, 0, 0.45152, 0.678886, 0.00433412, 0, 0.474651, 0.663042, 0.00407981, 0, 0.498433, 0.646634, 0.00384264, 0, 0.52289, 0.630117, 0.00360897, 0, 0.548048, 0.613804, 0.00338863, 0, 0.573936, 0.598338, 0.00318486, 0, 0.600584, 0.582687, 0.00298377, 0, 0.628027, 0.566809, 0.00280082, 0, 0.656295, 0.550817, 0.00262255, 0, 0.685417, 0.534937, 0.00245835, 0, 0.715406, 0.519151, 0.00230574, 0, 0.74624, 0.503118, 0.0021549, 0, 0.777778, 0.487723, 0.00202008, 0, 0.809524, 0.472725, 0.00189355, 0, 0.84127, 0.457599, 0.00177108, 0, 0.873016, 0.442558, 0.00165843, 0, 0.904762, 0.427624, 0.00155494, 0, 0.936508, 0.413171, 0.00145273, 0, 0.968254, 0.399122, 0.00136454, 0, 1, 1, 0.00826496, 0, 0, 1, 0.00826499, 0, 0, 1, 0.00826564, 0, 0, 0.999996, 0.00826842, 0, 0, 0.999987, 0.00827589, 0, 0, 0.999967, 0.00829167, 0, 0, 0.999933, 0.00832037, 0, 0, 0.999876, 0.00836768, 0, 1.09338e-05, 0.999786, 0.00844031, 0, 0.000427145, 0.999655, 0.00854603, 0, 0.0016384, 0.999468, 0.00869337, 0, 0.00372392, 0.999203, 0.008891, 0, 0.00668513, 0.998803, 0.00914387, 0, 0.0104968, 0.99748, 0.00935838, 0, 0.015125, 0.994446, 0.00933309, 0, 0.0205338, 0.99292, 0.00953084, 0, 0.0266884, 0.991414, 0.0097893, 0, 0.0335565, 0.989049, 0.0100228, 0, 0.0411086, 0.98582, 0.0101664, 0, 0.0493181, 0.982441, 0.0103582, 0, 0.0581613, 0.978595, 0.0105292, 0, 0.0676169, 0.973495, 0.0106274, 0, 0.0776661, 0.968405, 0.0107261, 0, 0.0882926, 0.962717, 0.0108234, 0, 0.0994817, 0.955478, 0.0108102, 0, 0.111221, 0.948275, 0.0107914, 0, 0.123499, 0.940006, 0.0107161, 0, 0.136308, 0.930831, 0.0106309, 0, 0.149639, 0.920648, 0.0104083, 0, 0.163485, 0.910205, 0.0102312, 0, 0.177843, 0.898445, 0.0100051, 0, 0.192707, 0.885986, 0.00971928, 0, 0.208077, 0.872204, 0.00940747, 0, 0.22395, 0.858436, 0.0091085, 0, 0.240326, 0.843454, 0.00876595, 0, 0.257208, 0.827437, 0.00839794, 0, 0.274596, 0.811488, 0.00803692, 0, 0.292496, 0.796039, 0.00767352, 0, 0.310911, 0.781083, 0.0073097, 0, 0.329849, 0.767642, 0.00694032, 0, 0.349316, 0.753901, 0.00657476, 0, 0.369323, 0.740131, 0.00622699, 0, 0.38988, 0.725845, 0.0058838, 0, 0.410999, 0.710991, 0.00555586, 0, 0.432696, 0.696002, 0.00523089, 0, 0.454987, 0.680461, 0.00492494, 0, 0.47789, 0.664875, 0.00463464, 0, 0.501426, 0.649273, 0.00435422, 0, 0.52562, 0.63302, 0.0040875, 0, 0.550498, 0.61705, 0.00384075, 0, 0.576089, 0.601154, 0.00359557, 0, 0.602427, 0.586008, 0.00337636, 0, 0.629544, 0.570699, 0.00316019, 0, 0.657479, 0.555166, 0.00296033, 0, 0.686264, 0.539645, 0.00277552, 0, 0.715924, 0.524159, 0.00259499, 0, 0.746459, 0.508682, 0.00243257, 0, 0.777789, 0.493163, 0.00227851, 0, 0.809524, 0.478004, 0.00213083, 0, 0.84127, 0.46347, 0.00199502, 0, 0.873016, 0.448778, 0.00186967, 0, 0.904762, 0.434105, 0.00174732, 0, 0.936508, 0.419576, 0.00163861, 0, 0.968254, 0.405541, 0.00153341, 0, 1, 1, 0.0106462, 0, 0, 1, 0.0106462, 0, 0, 0.999999, 0.010647, 0, 0, 0.999995, 0.0106502, 0, 0, 0.999985, 0.0106589, 0, 0, 0.999964, 0.0106773, 0, 0, 0.999925, 0.0107106, 0, 0, 0.999861, 0.0107655, 0, 7.12986e-05, 0.999763, 0.0108497, 0, 0.000743959, 0.999616, 0.0109716, 0, 0.00227361, 0.999408, 0.0111408, 0, 0.0046983, 0.999112, 0.0113659, 0, 0.00800158, 0.998637, 0.0116475, 0, 0.0121493, 0.996223, 0.0117231, 0, 0.0171023, 0.994006, 0.0118064, 0, 0.0228218, 0.992444, 0.0120254, 0, 0.0292711, 0.991028, 0.0123314, 0, 0.036417, 0.98803, 0.0124954, 0, 0.0442295, 0.984816, 0.0126538, 0, 0.0526815, 0.981399, 0.0128537, 0, 0.0617492, 0.977085, 0.0129694, 0, 0.0714114, 0.972154, 0.013091, 0, 0.0816495, 0.966617, 0.0131166, 0, 0.0924472, 0.960628, 0.0131583, 0, 0.10379, 0.953295, 0.0131094, 0, 0.115665, 0.94575, 0.0129966, 0, 0.128062, 0.937654, 0.0128796, 0, 0.140972, 0.927716, 0.0126477, 0, 0.154387, 0.917932, 0.0123889, 0, 0.168301, 0.907719, 0.012131, 0, 0.182709, 0.89584, 0.0118013, 0, 0.197608, 0.883526, 0.0114145, 0, 0.212994, 0.870301, 0.0110075, 0, 0.228867, 0.856272, 0.0106019, 0, 0.245227, 0.842251, 0.0101938, 0, 0.262074, 0.826466, 0.00973254, 0, 0.279412, 0.810859, 0.0092846, 0, 0.297244, 0.795051, 0.00883304, 0, 0.315575, 0.780053, 0.00840272, 0, 0.334412, 0.76575, 0.00796438, 0, 0.35376, 0.752298, 0.00752526, 0, 0.373631, 0.739153, 0.00711486, 0, 0.394034, 0.725514, 0.00670361, 0, 0.414983, 0.711473, 0.00632656, 0, 0.436491, 0.696936, 0.00595206, 0, 0.458575, 0.682126, 0.00559191, 0, 0.481253, 0.667027, 0.00525362, 0, 0.504547, 0.651875, 0.00493805, 0, 0.528481, 0.636463, 0.00462848, 0, 0.553081, 0.620641, 0.00433936, 0, 0.578377, 0.604931, 0.00407, 0, 0.604404, 0.589549, 0.00380864, 0, 0.631197, 0.574712, 0.00357049, 0, 0.658795, 0.559775, 0.00334466, 0, 0.687238, 0.544514, 0.00312505, 0, 0.716559, 0.529555, 0.00293199, 0, 0.746776, 0.514402, 0.00274204, 0, 0.777849, 0.499302, 0.00256647, 0, 0.809524, 0.484114, 0.00239901, 0, 0.84127, 0.469308, 0.00225148, 0, 0.873016, 0.455133, 0.00210178, 0, 0.904762, 0.440939, 0.0019727, 0, 0.936508, 0.426627, 0.00184382, 0, 0.968254, 0.412509, 0.00172548, 0, 1, 1, 0.013628, 0, 0, 1, 0.0136281, 0, 0, 0.999999, 0.0136289, 0, 0, 0.999995, 0.0136327, 0, 0, 0.999983, 0.0136427, 0, 0, 0.99996, 0.0136638, 0, 0, 0.999917, 0.0137022, 0, 0, 0.999846, 0.0137652, 0, 0.000204597, 0.999736, 0.0138615, 0, 0.00116837, 0.999573, 0.0140007, 0, 0.00303325, 0.99934, 0.0141927, 0, 0.00580613, 0.999004, 0.0144457, 0, 0.00945626, 0.998407, 0.0147489, 0, 0.0139421, 0.995464, 0.014731, 0, 0.0192202, 0.993328, 0.0148283, 0, 0.0252495, 0.991799, 0.0150797, 0, 0.0319921, 0.990397, 0.0154316, 0, 0.0394138, 0.986835, 0.0155005, 0, 0.0474843, 0.983938, 0.0157308, 0, 0.0561763, 0.980154, 0.0158753, 0, 0.0654661, 0.975659, 0.0159581, 0, 0.0753326, 0.970171, 0.0159832, 0, 0.0857571, 0.964803, 0.0160084, 0, 0.0967236, 0.958366, 0.0159484, 0, 0.108218, 0.950613, 0.0158001, 0, 0.120227, 0.942874, 0.0155845, 0, 0.132741, 0.935005, 0.0154292, 0, 0.145751, 0.924991, 0.0150742, 0, 0.159249, 0.914814, 0.0146757, 0, 0.17323, 0.904743, 0.0143097, 0, 0.187687, 0.893216, 0.0138695, 0, 0.202619, 0.880769, 0.0133706, 0, 0.218021, 0.868136, 0.0128606, 0, 0.233894, 0.85469, 0.0123403, 0, 0.250238, 0.840593, 0.0118091, 0, 0.267052, 0.825808, 0.011253, 0, 0.284341, 0.81009, 0.0107099, 0, 0.302106, 0.79504, 0.0101636, 0, 0.320354, 0.779757, 0.00964041, 0, 0.33909, 0.764697, 0.00911896, 0, 0.358322, 0.750913, 0.00859533, 0, 0.378059, 0.738175, 0.00811592, 0, 0.398311, 0.725242, 0.00764504, 0, 0.41909, 0.711864, 0.00718885, 0, 0.440412, 0.698009, 0.00675843, 0, 0.462292, 0.683841, 0.00634984, 0, 0.484748, 0.669391, 0.00595502, 0, 0.507802, 0.654731, 0.00558671, 0, 0.531477, 0.639805, 0.00523578, 0, 0.555802, 0.624789, 0.00490834, 0, 0.580805, 0.609325, 0.00459448, 0, 0.606522, 0.593975, 0.00430342, 0, 0.63299, 0.578983, 0.00403019, 0, 0.66025, 0.564442, 0.0037707, 0, 0.688346, 0.549835, 0.0035316, 0, 0.717319, 0.535039, 0.00330255, 0, 0.7472, 0.520403, 0.00308932, 0, 0.777982, 0.505687, 0.00289335, 0, 0.809524, 0.490939, 0.00270818, 0, 0.84127, 0.476233, 0.0025343, 0, 0.873016, 0.461624, 0.00237097, 0, 0.904762, 0.447833, 0.00222065, 0, 0.936508, 0.433992, 0.00207561, 0, 0.968254, 0.420147, 0.00194955, 0, 1, 1, 0.0173415, 0, 0, 1, 0.0173416, 0, 0, 0.999999, 0.0173426, 0, 0, 0.999995, 0.0173468, 0, 0, 0.999983, 0.0173582, 0, 0, 0.999954, 0.0173822, 0, 0, 0.999908, 0.0174258, 0, 6.69501e-06, 0.999828, 0.0174973, 0, 0.000427399, 0.999705, 0.0176063, 0, 0.00171019, 0.999524, 0.0177631, 0, 0.0039248, 0.999263, 0.0179781, 0, 0.00705382, 0.998878, 0.018258, 0, 0.0110552, 0.998012, 0.0185551, 0, 0.0158812, 0.994614, 0.0184264, 0, 0.0214852, 0.993132, 0.0186385, 0, 0.0278239, 0.991563, 0.0189067, 0, 0.0348585, 0.989298, 0.0191577, 0, 0.0425544, 0.986036, 0.0192522, 0, 0.050881, 0.982558, 0.0194063, 0, 0.059811, 0.978531, 0.019486, 0, 0.0693209, 0.974198, 0.0195847, 0, 0.0793895, 0.968148, 0.0194749, 0, 0.0899984, 0.962565, 0.0194277, 0, 0.101132, 0.956041, 0.0192991, 0, 0.112775, 0.947749, 0.0189893, 0, 0.124917, 0.94018, 0.018704, 0, 0.137547, 0.93165, 0.0183458, 0, 0.150655, 0.921798, 0.0178775, 0, 0.164236, 0.911573, 0.0173618, 0, 0.178281, 0.901569, 0.0168482, 0, 0.192788, 0.890341, 0.016265, 0, 0.207752, 0.877835, 0.0156199, 0, 0.223171, 0.865472, 0.0149516, 0, 0.239044, 0.852905, 0.0143274, 0, 0.255371, 0.838906, 0.0136643, 0, 0.272153, 0.824888, 0.0129903, 0, 0.289393, 0.809977, 0.0123218, 0, 0.307093, 0.794697, 0.0116572, 0, 0.325259, 0.780028, 0.0110307, 0, 0.343896, 0.765124, 0.0104236, 0, 0.363012, 0.750411, 0.0098219, 0, 0.382617, 0.737264, 0.00924397, 0, 0.402719, 0.724799, 0.00868719, 0, 0.423332, 0.712253, 0.00816476, 0, 0.444469, 0.699267, 0.00767262, 0, 0.466146, 0.685618, 0.00719746, 0, 0.488383, 0.671736, 0.00673916, 0, 0.511199, 0.657777, 0.00631937, 0, 0.534618, 0.643497, 0.00592411, 0, 0.558668, 0.62889, 0.00553928, 0, 0.58338, 0.614299, 0.0051934, 0, 0.608787, 0.599197, 0.00485985, 0, 0.634929, 0.584175, 0.00454357, 0, 0.661849, 0.569541, 0.00425787, 0, 0.689594, 0.555193, 0.00397905, 0, 0.718211, 0.540947, 0.00372364, 0, 0.747742, 0.526593, 0.00348599, 0, 0.778205, 0.512335, 0.00326103, 0, 0.80953, 0.498017, 0.00305137, 0, 0.84127, 0.483609, 0.00285485, 0, 0.873016, 0.469368, 0.00267472, 0, 0.904762, 0.455037, 0.00249945, 0, 0.936508, 0.441493, 0.00234792, 0, 0.968254, 0.428147, 0.00219936, 0, 1, 1, 0.0219422, 0, 0, 1, 0.0219423, 0, 0, 0.999998, 0.0219434, 0, 0, 0.999993, 0.0219481, 0, 0, 0.999981, 0.021961, 0, 0, 0.999949, 0.0219879, 0, 0, 0.999896, 0.0220367, 0, 5.93194e-05, 0.999808, 0.0221167, 0, 0.00075364, 0.99967, 0.0222383, 0, 0.00237884, 0.999466, 0.0224125, 0, 0.00495612, 0.999174, 0.0226495, 0, 0.00844887, 0.998725, 0.0229525, 0, 0.0128058, 0.996979, 0.0231123, 0, 0.0179742, 0.994317, 0.0230742, 0, 0.0239047, 0.992781, 0.0232895, 0, 0.0305526, 0.991191, 0.0235734, 0, 0.0378786, 0.987787, 0.0236152, 0, 0.0458475, 0.985092, 0.0237994, 0, 0.0544287, 0.981121, 0.0238553, 0, 0.0635952, 0.976924, 0.0238706, 0, 0.0733233, 0.97218, 0.0238704, 0, 0.0835922, 0.965956, 0.0236598, 0, 0.0943839, 0.959998, 0.0234735, 0, 0.105682, 0.953245, 0.0232277, 0, 0.117474, 0.944445, 0.0226973, 0, 0.129747, 0.937087, 0.0223527, 0, 0.142491, 0.928341, 0.0218144, 0, 0.155697, 0.9184, 0.0211516, 0, 0.169358, 0.907959, 0.0204553, 0, 0.183469, 0.89808, 0.0197673, 0, 0.198024, 0.887047, 0.0189915, 0, 0.21302, 0.875221, 0.0182082, 0, 0.228455, 0.86269, 0.0173584, 0, 0.244329, 0.850735, 0.0165718, 0, 0.260639, 0.837545, 0.0157524, 0, 0.277389, 0.823639, 0.0149482, 0, 0.29458, 0.809699, 0.0141431, 0, 0.312216, 0.794797, 0.0133527, 0, 0.3303, 0.780578, 0.0126193, 0, 0.34884, 0.766019, 0.0118914, 0, 0.367842, 0.751447, 0.0111839, 0, 0.387315, 0.737275, 0.010514, 0, 0.40727, 0.724545, 0.00987277, 0, 0.427717, 0.712644, 0.00926569, 0, 0.448671, 0.700432, 0.00869029, 0, 0.470149, 0.687664, 0.00814691, 0, 0.492167, 0.674288, 0.00763012, 0, 0.514746, 0.660966, 0.00714437, 0, 0.537911, 0.647264, 0.00668457, 0, 0.561688, 0.633431, 0.00626581, 0, 0.586108, 0.619133, 0.00585593, 0, 0.611206, 0.604935, 0.00548188, 0, 0.637022, 0.590236, 0.00513288, 0, 0.663599, 0.575473, 0.0047906, 0, 0.690989, 0.561228, 0.00448895, 0, 0.719242, 0.547054, 0.00420233, 0, 0.748411, 0.533175, 0.00392869, 0, 0.778531, 0.519163, 0.00367445, 0, 0.809583, 0.505328, 0.00344097, 0, 0.84127, 0.491446, 0.00322003, 0, 0.873016, 0.477356, 0.00301283, 0, 0.904762, 0.46356, 0.00282592, 0, 0.936508, 0.449623, 0.00264956, 0, 0.968254, 0.436068, 0.00246956, 0, 1, 1, 0.0276135, 0, 0, 1, 0.0276136, 0, 0, 0.999998, 0.0276148, 0, 0, 0.999993, 0.0276201, 0, 0, 0.999976, 0.0276342, 0, 0, 0.999945, 0.027664, 0, 0, 0.999884, 0.0277179, 0, 0.00018679, 0.999784, 0.027806, 0, 0.00119607, 0.99963, 0.0279394, 0, 0.00318407, 0.999401, 0.0281295, 0, 0.00613601, 0.999066, 0.0283858, 0, 0.00999963, 0.998524, 0.0287027, 0, 0.0147164, 0.995702, 0.0286256, 0, 0.0202295, 0.993593, 0.0286733, 0, 0.0264876, 0.992067, 0.0288989, 0, 0.0334452, 0.990548, 0.0292135, 0, 0.0410621, 0.986775, 0.0291296, 0, 0.0493032, 0.984054, 0.0293099, 0, 0.0581381, 0.979481, 0.0291881, 0, 0.0675397, 0.975297, 0.0291598, 0, 0.0774848, 0.96981, 0.028954, 0, 0.0879528, 0.963524, 0.028628, 0, 0.0989258, 0.957398, 0.0283135, 0, 0.110388, 0.950088, 0.0278469, 0, 0.122327, 0.941538, 0.0271798, 0, 0.134729, 0.933332, 0.0265388, 0, 0.147587, 0.924392, 0.0257776, 0, 0.160889, 0.914581, 0.024916, 0, 0.174631, 0.904347, 0.0240242, 0, 0.188806, 0.894324, 0.0231229, 0, 0.203409, 0.883724, 0.022153, 0, 0.218437, 0.872207, 0.0211355, 0, 0.233888, 0.859927, 0.0201048, 0, 0.249761, 0.848373, 0.0191263, 0, 0.266056, 0.836023, 0.0181306, 0, 0.282774, 0.82289, 0.0171718, 0, 0.299917, 0.809324, 0.0162196, 0, 0.317488, 0.795361, 0.0152622, 0, 0.335493, 0.781253, 0.01439, 0, 0.353936, 0.767338, 0.013533, 0, 0.372825, 0.753156, 0.0127244, 0, 0.392168, 0.739122, 0.0119454, 0, 0.411976, 0.725358, 0.0112054, 0, 0.432259, 0.712949, 0.010487, 0, 0.453032, 0.701621, 0.00984032, 0, 0.47431, 0.689703, 0.00921495, 0, 0.496111, 0.677216, 0.00862492, 0, 0.518456, 0.664217, 0.00806882, 0, 0.541367, 0.65137, 0.00755922, 0, 0.564872, 0.638, 0.00705705, 0, 0.589001, 0.62453, 0.00661266, 0, 0.613789, 0.610601, 0.00618432, 0, 0.639277, 0.59676, 0.00578033, 0, 0.66551, 0.582433, 0.00540927, 0, 0.692539, 0.568026, 0.00506104, 0, 0.720422, 0.55414, 0.0047353, 0, 0.749216, 0.540178, 0.00442889, 0, 0.778974, 0.526513, 0.00414363, 0, 0.809711, 0.512954, 0.00388237, 0, 0.84127, 0.499403, 0.00362875, 0, 0.873016, 0.486026, 0.00340827, 0, 0.904762, 0.472345, 0.00318598, 0, 0.936508, 0.458828, 0.00297635, 0, 0.968254, 0.445379, 0.00279447, 0, 1, 1, 0.0345716, 0, 0, 1, 0.0345717, 0, 0, 0.999999, 0.034573, 0, 0, 0.999991, 0.0345787, 0, 0, 0.999974, 0.0345941, 0, 0, 0.999937, 0.0346263, 0, 1.88589e-06, 0.999869, 0.0346847, 0, 0.000409238, 0.999757, 0.0347798, 0, 0.0017674, 0.999582, 0.0349233, 0, 0.00413658, 0.999322, 0.0351265, 0, 0.00747408, 0.998939, 0.0353967, 0, 0.0117157, 0.998219, 0.0357018, 0, 0.0167966, 0.994974, 0.0354726, 0, 0.0226572, 0.993201, 0.0355621, 0, 0.0292445, 0.991573, 0.0357641, 0, 0.0365123, 0.989301, 0.0359252, 0, 0.0444203, 0.985712, 0.0358017, 0, 0.0529334, 0.982411, 0.0358353, 0, 0.0620214, 0.977827, 0.035617, 0, 0.0716574, 0.973278, 0.0354398, 0, 0.0818186, 0.967397, 0.0350483, 0, 0.0924846, 0.960696, 0.0344795, 0, 0.103638, 0.954349, 0.0339861, 0, 0.115263, 0.946066, 0.0331323, 0, 0.127348, 0.938012, 0.032359, 0, 0.13988, 0.929413, 0.0314413, 0, 0.152849, 0.920355, 0.0304103, 0, 0.166248, 0.910586, 0.0292785, 0, 0.18007, 0.900609, 0.0281391, 0, 0.194308, 0.890093, 0.0269103, 0, 0.208958, 0.880013, 0.0257269, 0, 0.224018, 0.869001, 0.0244671, 0, 0.239485, 0.85751, 0.0232252, 0, 0.255359, 0.84582, 0.0220117, 0, 0.271638, 0.834383, 0.0208274, 0, 0.288324, 0.822158, 0.0196628, 0, 0.305419, 0.809056, 0.0185306, 0, 0.322927, 0.795832, 0.0174174, 0, 0.340851, 0.782547, 0.0163758, 0, 0.359199, 0.7689, 0.015391, 0, 0.377975, 0.755526, 0.0144488, 0, 0.397189, 0.741681, 0.0135372, 0, 0.416851, 0.728178, 0.0126957, 0, 0.436971, 0.714642, 0.0118812, 0, 0.457564, 0.702756, 0.0111165, 0, 0.478644, 0.69175, 0.0104145, 0, 0.500229, 0.680159, 0.00974439, 0, 0.522339, 0.668073, 0.00911926, 0, 0.544997, 0.655405, 0.00851393, 0, 0.56823, 0.642921, 0.00797637, 0, 0.592068, 0.629993, 0.00745119, 0, 0.616546, 0.616828, 0.00696972, 0, 0.641705, 0.603305, 0.00652425, 0, 0.66759, 0.589833, 0.00610188, 0, 0.694255, 0.575945, 0.00570834, 0, 0.72176, 0.561745, 0.00533384, 0, 0.750168, 0.548277, 0.00500001, 0, 0.779545, 0.534467, 0.00467582, 0, 0.809933, 0.521032, 0.00438092, 0, 0.841272, 0.507877, 0.00410348, 0, 0.873016, 0.494654, 0.00383618, 0, 0.904762, 0.481592, 0.00358699, 0, 0.936508, 0.468509, 0.00337281, 0, 0.968254, 0.455293, 0.00316196, 0, 1, 1, 0.0430698, 0, 0, 1, 0.0430699, 0, 0, 0.999998, 0.0430713, 0, 0, 0.999991, 0.0430773, 0, 0, 0.99997, 0.0430936, 0, 0, 0.999928, 0.0431277, 0, 4.06396e-05, 0.999852, 0.0431893, 0, 0.000744376, 0.999724, 0.0432895, 0, 0.0024806, 0.999527, 0.0434397, 0, 0.00524779, 0.99923, 0.0436507, 0, 0.00898164, 0.998783, 0.0439255, 0, 0.0136083, 0.997507, 0.0441104, 0, 0.0190582, 0.994418, 0.0438225, 0, 0.0252694, 0.992864, 0.0439396, 0, 0.0321879, 0.991127, 0.0440962, 0, 0.039767, 0.987331, 0.0438408, 0, 0.0479667, 0.984819, 0.0438991, 0, 0.056752, 0.980384, 0.0435906, 0, 0.0660929, 0.975846, 0.0432543, 0, 0.075963, 0.970748, 0.0428293, 0, 0.0863398, 0.964303, 0.042153, 0, 0.0972035, 0.95772, 0.0414111, 0, 0.108537, 0.950747, 0.0405893, 0, 0.120325, 0.942533, 0.0394887, 0, 0.132554, 0.934045, 0.0383544, 0, 0.145215, 0.924942, 0.037057, 0, 0.158296, 0.915811, 0.0356993, 0, 0.17179, 0.90612, 0.0342401, 0, 0.185691, 0.896434, 0.0328078, 0, 0.199993, 0.886021, 0.031288, 0, 0.214691, 0.876081, 0.0297776, 0, 0.229782, 0.865608, 0.0282334, 0, 0.245265, 0.854924, 0.026749, 0, 0.261138, 0.843607, 0.02526, 0, 0.277401, 0.832456, 0.0238214, 0, 0.294056, 0.821342, 0.0224682, 0, 0.311104, 0.809303, 0.0211297, 0, 0.328548, 0.796468, 0.0198387, 0, 0.346394, 0.784046, 0.0186227, 0, 0.364645, 0.771262, 0.0174561, 0, 0.38331, 0.758118, 0.0163806, 0, 0.402396, 0.745075, 0.0153287, 0, 0.421912, 0.731926, 0.0143647, 0, 0.44187, 0.71863, 0.0134363, 0, 0.462283, 0.705414, 0.0125603, 0, 0.483165, 0.693792, 0.0117508, 0, 0.504535, 0.683108, 0.0110016, 0, 0.52641, 0.67183, 0.0102757, 0, 0.548816, 0.66015, 0.00962044, 0, 0.571776, 0.647907, 0.00898031, 0, 0.595323, 0.635734, 0.00840811, 0, 0.619489, 0.623208, 0.00786211, 0, 0.644317, 0.610438, 0.00734953, 0, 0.669852, 0.597345, 0.00687688, 0, 0.696148, 0.584138, 0.00643469, 0, 0.723267, 0.5707, 0.00602236, 0, 0.75128, 0.556966, 0.0056324, 0, 0.780258, 0.543607, 0.00528277, 0, 0.810268, 0.530213, 0.00493999, 0, 0.841311, 0.516912, 0.00462265, 0, 0.873016, 0.503916, 0.0043307, 0, 0.904762, 0.491146, 0.00406858, 0, 0.936508, 0.478439, 0.00381436, 0, 0.968254, 0.465834, 0.00358003, 0, 1, 1, 0.0534039, 0, 0, 1, 0.053404, 0, 0, 0.999998, 0.0534055, 0, 0, 0.999989, 0.0534116, 0, 0, 0.999968, 0.0534283, 0, 0, 0.999918, 0.0534633, 0, 0.000155895, 0.99983, 0.0535262, 0, 0.00120914, 0.999685, 0.0536281, 0, 0.00334944, 0.999461, 0.0537799, 0, 0.00653077, 0.999119, 0.0539902, 0, 0.0106718, 0.998582, 0.0542524, 0, 0.0156907, 0.995919, 0.0540318, 0, 0.0215147, 0.993735, 0.0538914, 0, 0.0280801, 0.992126, 0.0539557, 0, 0.0353323, 0.990266, 0.0540401, 0, 0.0432247, 0.986317, 0.0536064, 0, 0.0517172, 0.983213, 0.0534425, 0, 0.0607754, 0.978303, 0.0528622, 0, 0.0703698, 0.973665, 0.0523363, 0, 0.0804742, 0.968091, 0.0516165, 0, 0.0910667, 0.961026, 0.0505434, 0, 0.102128, 0.954333, 0.049523, 0, 0.113641, 0.946372, 0.0481698, 0, 0.125591, 0.938254, 0.0467674, 0, 0.137965, 0.929516, 0.0452341, 0, 0.150754, 0.920106, 0.0435083, 0, 0.163947, 0.910899, 0.0417399, 0, 0.177537, 0.901532, 0.0399389, 0, 0.191516, 0.891919, 0.0380901, 0, 0.205881, 0.882006, 0.0362341, 0, 0.220626, 0.871965, 0.0343444, 0, 0.235749, 0.862145, 0.0324832, 0, 0.251248, 0.852058, 0.0306681, 0, 0.267121, 0.84161, 0.0289097, 0, 0.283368, 0.830806, 0.0272079, 0, 0.299992, 0.820476, 0.0256089, 0, 0.316992, 0.809514, 0.0240394, 0, 0.334374, 0.797865, 0.0225379, 0, 0.35214, 0.785621, 0.0211235, 0, 0.370296, 0.773765, 0.0197908, 0, 0.388849, 0.761629, 0.0185235, 0, 0.407807, 0.748891, 0.0173358, 0, 0.427178, 0.736437, 0.0162305, 0, 0.446974, 0.723707, 0.0151778, 0, 0.467207, 0.710606, 0.0141791, 0, 0.487892, 0.698019, 0.0132592, 0, 0.509046, 0.686203, 0.0123887, 0, 0.530687, 0.675692, 0.0115976, 0, 0.552839, 0.664826, 0.0108325, 0, 0.575527, 0.65349, 0.0101348, 0, 0.59878, 0.641774, 0.00947756, 0, 0.622634, 0.629794, 0.00886058, 0, 0.647128, 0.617647, 0.00828526, 0, 0.672308, 0.60534, 0.00775312, 0, 0.698231, 0.592718, 0.00726033, 0, 0.724958, 0.579746, 0.00679731, 0, 0.752563, 0.566763, 0.00636111, 0, 0.781127, 0.553515, 0.00595228, 0, 0.810733, 0.540118, 0.00556876, 0, 0.841426, 0.527325, 0.00523051, 0, 0.873016, 0.514265, 0.00490712, 0, 0.904762, 0.501406, 0.00460297, 0, 0.936508, 0.488922, 0.00431247, 0, 0.968254, 0.476541, 0.0040472, 0, 1, 1, 0.0659184, 0, 0, 1, 0.0659185, 0, 0, 0.999998, 0.06592, 0, 0, 0.999988, 0.0659259, 0, 0, 0.999963, 0.0659423, 0, 0, 0.999907, 0.0659764, 0, 0.000374198, 0.999806, 0.0660376, 0, 0.00182071, 0.999639, 0.0661361, 0, 0.0043894, 0.999378, 0.0662814, 0, 0.00800055, 0.998985, 0.0664779, 0, 0.0125594, 0.998285, 0.0666914, 0, 0.0179786, 0.995071, 0.0661989, 0, 0.0241822, 0.993172, 0.0660454, 0, 0.031106, 0.991438, 0.0660105, 0, 0.0386952, 0.988428, 0.0656875, 0, 0.0469032, 0.985218, 0.0652913, 0, 0.0556905, 0.981128, 0.0647107, 0, 0.065023, 0.976015, 0.0638491, 0, 0.0748717, 0.97097, 0.062993, 0, 0.0852112, 0.964582, 0.0617927, 0, 0.0960199, 0.957383, 0.0603626, 0, 0.107279, 0.949969, 0.0588128, 0, 0.118971, 0.941843, 0.0570274, 0, 0.131084, 0.933624, 0.0551885, 0, 0.143604, 0.924543, 0.053122, 0, 0.156521, 0.914919, 0.0508897, 0, 0.169825, 0.905773, 0.0486418, 0, 0.18351, 0.896434, 0.0463364, 0, 0.197569, 0.887195, 0.0440623, 0, 0.211997, 0.877706, 0.0417799, 0, 0.226789, 0.867719, 0.03945, 0, 0.241944, 0.858587, 0.037243, 0, 0.257458, 0.849317, 0.0350956, 0, 0.273331, 0.839585, 0.0329852, 0, 0.289563, 0.829856, 0.0310028, 0, 0.306154, 0.819589, 0.0290953, 0, 0.323108, 0.809714, 0.0272738, 0, 0.340426, 0.79934, 0.0255631, 0, 0.358113, 0.788224, 0.0239175, 0, 0.376175, 0.776619, 0.0223831, 0, 0.394616, 0.76521, 0.0209298, 0, 0.413445, 0.753716, 0.0195786, 0, 0.432671, 0.741564, 0.0183001, 0, 0.452305, 0.729413, 0.0171259, 0, 0.472358, 0.717146, 0.0159933, 0, 0.492845, 0.70436, 0.0149495, 0, 0.513783, 0.69219, 0.0139681, 0, 0.535189, 0.680289, 0.0130577, 0, 0.557087, 0.669611, 0.0122198, 0, 0.5795, 0.659113, 0.0114174, 0, 0.602459, 0.648148, 0.0106729, 0, 0.625997, 0.636905, 0.00998997, 0, 0.650154, 0.625154, 0.00934313, 0, 0.674976, 0.613481, 0.00874839, 0, 0.700518, 0.60154, 0.00818265, 0, 0.726845, 0.58943, 0.00766889, 0, 0.754032, 0.576828, 0.00717153, 0, 0.782167, 0.564194, 0.00672696, 0, 0.811344, 0.551501, 0.00630863, 0, 0.841644, 0.538635, 0.00592177, 0, 0.873016, 0.525724, 0.00554888, 0, 0.904762, 0.513209, 0.00520225, 0, 0.936508, 0.500457, 0.00488231, 0, 0.968254, 0.48799, 0.00457153, 0, 1, 1, 0.0810131, 0, 0, 1, 0.0810133, 0, 0, 0.999997, 0.0810145, 0, 0, 0.999985, 0.08102, 0, 0, 0.999956, 0.0810347, 0, 1.95026e-05, 0.999893, 0.0810656, 0, 0.000719316, 0.999777, 0.0811205, 0, 0.00259774, 0.999583, 0.081208, 0, 0.00561807, 0.999281, 0.0813343, 0, 0.00967472, 0.998813, 0.0814969, 0, 0.0146627, 0.997597, 0.0815217, 0, 0.0204902, 0.994379, 0.0808502, 0, 0.0270802, 0.992744, 0.0806792, 0, 0.0343674, 0.990745, 0.0804589, 0, 0.0422974, 0.986646, 0.0796107, 0, 0.0508242, 0.983611, 0.0790913, 0, 0.0599087, 0.978869, 0.0780746, 0, 0.0695175, 0.973475, 0.0768218, 0, 0.0796223, 0.967845, 0.0754926, 0, 0.0901983, 0.960778, 0.0737063, 0, 0.101224, 0.953333, 0.0718052, 0, 0.112682, 0.945274, 0.0695946, 0, 0.124555, 0.936955, 0.0672492, 0, 0.136831, 0.928319, 0.0647732, 0, 0.149496, 0.919075, 0.0620947, 0, 0.162542, 0.909114, 0.0591816, 0, 0.175958, 0.900137, 0.0563917, 0, 0.189739, 0.891069, 0.0535392, 0, 0.203877, 0.882262, 0.0507642, 0, 0.218368, 0.873232, 0.0479793, 0, 0.233208, 0.864042, 0.045226, 0, 0.248393, 0.855002, 0.0425413, 0, 0.263923, 0.846569, 0.0400126, 0, 0.279796, 0.837714, 0.0375269, 0, 0.296012, 0.828918, 0.0352027, 0, 0.312573, 0.819783, 0.0330011, 0, 0.329479, 0.810129, 0.0308908, 0, 0.346734, 0.800866, 0.0289112, 0, 0.364342, 0.79093, 0.0270255, 0, 0.382307, 0.780593, 0.0252758, 0, 0.400637, 0.769511, 0.0236178, 0, 0.419337, 0.758558, 0.0220652, 0, 0.438418, 0.747632, 0.0206289, 0, 0.457889, 0.736146, 0.0192873, 0, 0.477761, 0.724093, 0.0180333, 0, 0.49805, 0.71234, 0.0168264, 0, 0.51877, 0.700201, 0.015746, 0, 0.53994, 0.687949, 0.0147027, 0, 0.561581, 0.676163, 0.0137512, 0, 0.583718, 0.665001, 0.0128655, 0, 0.60638, 0.65472, 0.0120366, 0, 0.629599, 0.644213, 0.0112604, 0, 0.653415, 0.633382, 0.0105413, 0, 0.677874, 0.62212, 0.00986498, 0, 0.70303, 0.610631, 0.00923308, 0, 0.728948, 0.599078, 0.00864206, 0, 0.755706, 0.587519, 0.00811784, 0, 0.783396, 0.575505, 0.00761237, 0, 0.812121, 0.563148, 0.00713949, 0, 0.841989, 0.550828, 0.00668379, 0, 0.873035, 0.538458, 0.00627715, 0, 0.904762, 0.525905, 0.00588336, 0, 0.936508, 0.513517, 0.00552687, 0, 0.968254, 0.501395, 0.00519681, 0, 1, 1, 0.0991506, 0, 0, 1, 0.0991504, 0, 0, 0.999996, 0.0991515, 0, 0, 0.999984, 0.0991558, 0, 0, 0.999947, 0.0991672, 0, 0.000114389, 0.999874, 0.0991912, 0, 0.00121503, 0.999739, 0.0992331, 0, 0.00356108, 0.999514, 0.0992983, 0, 0.00705578, 0.999159, 0.0993877, 0, 0.011574, 0.998586, 0.0994837, 0, 0.017003, 0.995731, 0.0988425, 0, 0.0232484, 0.993384, 0.098276, 0, 0.0302318, 0.991615, 0.0979269, 0, 0.0378884, 0.989029, 0.0973432, 0, 0.0461641, 0.985373, 0.0963539, 0, 0.0550136, 0.981278, 0.0952306, 0, 0.0643988, 0.975777, 0.0936233, 0, 0.0742868, 0.970526, 0.0920219, 0, 0.0846501, 0.963755, 0.0898912, 0, 0.0954644, 0.956676, 0.0876064, 0, 0.106709, 0.948099, 0.0847751, 0, 0.118367, 0.939718, 0.0818638, 0, 0.130423, 0.931305, 0.078857, 0, 0.142862, 0.922342, 0.0756127, 0, 0.155674, 0.912842, 0.0721473, 0, 0.168849, 0.903304, 0.0686195, 0, 0.182378, 0.89411, 0.0650589, 0, 0.196255, 0.885512, 0.0616022, 0, 0.210473, 0.877193, 0.0582434, 0, 0.225027, 0.86877, 0.0548979, 0, 0.239915, 0.860267, 0.0516095, 0, 0.255132, 0.851915, 0.048468, 0, 0.270678, 0.843912, 0.0454447, 0, 0.286551, 0.83604, 0.0425612, 0, 0.302751, 0.828245, 0.0398752, 0, 0.31928, 0.820159, 0.0373198, 0, 0.336138, 0.81167, 0.034916, 0, 0.35333, 0.802659, 0.0326402, 0, 0.370858, 0.793921, 0.0304901, 0, 0.388728, 0.784713, 0.0284857, 0, 0.406944, 0.774946, 0.0266186, 0, 0.425515, 0.76448, 0.0248593, 0, 0.444449, 0.753793, 0.0232114, 0, 0.463756, 0.743506, 0.0217039, 0, 0.483447, 0.732555, 0.0202841, 0, 0.503535, 0.720965, 0.0189648, 0, 0.524036, 0.709422, 0.0177189, 0, 0.544968, 0.697756, 0.0165626, 0, 0.56635, 0.685565, 0.015483, 0, 0.588208, 0.673987, 0.0144892, 0, 0.610569, 0.66244, 0.0135607, 0, 0.633466, 0.651675, 0.0126956, 0, 0.656936, 0.641598, 0.0118788, 0, 0.681025, 0.63121, 0.0111261, 0, 0.705788, 0.620514, 0.010437, 0, 0.731289, 0.609366, 0.00978747, 0, 0.757606, 0.598137, 0.00917257, 0, 0.784834, 0.586966, 0.00859778, 0, 0.813085, 0.575549, 0.00806803, 0, 0.842485, 0.563797, 0.00757294, 0, 0.87313, 0.551758, 0.00710592, 0, 0.904762, 0.539894, 0.0066841, 0, 0.936508, 0.527901, 0.00627901, 0, 0.968254, 0.515819, 0.00590506, 0, 1, 1, 0.120864, 0, 0, 1, 0.120864, 0, 0, 0.999996, 0.120864, 0, 0, 0.99998, 0.120867, 0, 0, 0.99994, 0.120872, 0, 0.000323781, 0.999852, 0.120884, 0, 0.00188693, 0.999693, 0.120903, 0, 0.00473489, 0.999426, 0.120929, 0, 0.00872704, 0.999002, 0.120955, 0, 0.0137237, 0.998235, 0.120918, 0, 0.0196068, 0.994608, 0.119764, 0, 0.0262803, 0.992997, 0.119265, 0, 0.0336657, 0.990968, 0.11863, 0, 0.0416987, 0.987002, 0.117261, 0, 0.0503261, 0.983524, 0.116009, 0, 0.0595035, 0.97875, 0.114252, 0, 0.0691935, 0.972652, 0.11193, 0, 0.0793645, 0.966613, 0.109555, 0, 0.0899894, 0.959275, 0.106612, 0, 0.101045, 0.951272, 0.103375, 0, 0.112512, 0.942323, 0.0996594, 0, 0.124372, 0.933679, 0.0958841, 0, 0.136611, 0.924822, 0.0919265, 0, 0.149216, 0.915742, 0.0878061, 0, 0.162176, 0.906348, 0.0834894, 0, 0.175482, 0.896883, 0.079085, 0, 0.189125, 0.88774, 0.0746745, 0, 0.203098, 0.87986, 0.0705773, 0, 0.217396, 0.871998, 0.0665005, 0, 0.232015, 0.864325, 0.0625413, 0, 0.24695, 0.856685, 0.0586781, 0, 0.2622, 0.84925, 0.0550063, 0, 0.277761, 0.841719, 0.0514727, 0, 0.293634, 0.834755, 0.0481398, 0, 0.309819, 0.827853, 0.0450172, 0, 0.326315, 0.820888, 0.0420969, 0, 0.343126, 0.813616, 0.0393702, 0, 0.360254, 0.805767, 0.0367771, 0, 0.377701, 0.797338, 0.0343274, 0, 0.395474, 0.789122, 0.0320529, 0, 0.413577, 0.780601, 0.0299485, 0, 0.432018, 0.771424, 0.0279812, 0, 0.450804, 0.761502, 0.0261054, 0, 0.469944, 0.751166, 0.0243942, 0, 0.489451, 0.741276, 0.0228087, 0, 0.509337, 0.730898, 0.0213265, 0, 0.529617, 0.719878, 0.0199307, 0, 0.550307, 0.708379, 0.0186574, 0, 0.571428, 0.697165, 0.0174446, 0, 0.593003, 0.685554, 0.0163144, 0, 0.615059, 0.673631, 0.015276, 0, 0.637628, 0.662385, 0.0143003, 0, 0.660746, 0.651059, 0.0134112, 0, 0.68446, 0.640451, 0.0125794, 0, 0.70882, 0.630536, 0.011793, 0, 0.733893, 0.620316, 0.0110547, 0, 0.759756, 0.609722, 0.0103668, 0, 0.786505, 0.598804, 0.00973009, 0, 0.814259, 0.587871, 0.00912812, 0, 0.843157, 0.577121, 0.00858916, 0, 0.87334, 0.566019, 0.00807333, 0, 0.904762, 0.554664, 0.00759687, 0, 0.936508, 0.543101, 0.00714759, 0, 0.968254, 0.531558, 0.00673418, 0, 1, 1, 0.146767, 0, 0, 1, 0.146767, 0, 0, 0.999997, 0.146767, 0, 0, 0.999977, 0.146765, 0, 3.20658e-06, 0.999929, 0.146762, 0, 0.000682576, 0.999823, 0.146753, 0, 0.00276402, 0.999633, 0.146735, 0, 0.00614771, 0.999314, 0.146699, 0, 0.0106613, 0.998796, 0.14662, 0, 0.0161546, 0.997124, 0.146107, 0, 0.0225063, 0.994062, 0.144857, 0, 0.0296198, 0.992154, 0.144011, 0, 0.037417, 0.989186, 0.142712, 0, 0.0458348, 0.985279, 0.140926, 0, 0.0548211, 0.980826, 0.13885, 0, 0.0643326, 0.975056, 0.136168, 0, 0.074333, 0.969005, 0.133217, 0, 0.0847917, 0.961554, 0.12959, 0, 0.0956828, 0.954206, 0.125886, 0, 0.106984, 0.945046, 0.121335, 0, 0.118675, 0.935678, 0.116492, 0, 0.130741, 0.926748, 0.111635, 0, 0.143166, 0.917764, 0.106625, 0, 0.155939, 0.908358, 0.101325, 0, 0.169049, 0.899219, 0.0960249, 0, 0.182487, 0.890089, 0.0906527, 0, 0.196245, 0.881488, 0.0853905, 0, 0.210317, 0.874031, 0.0804177, 0, 0.224697, 0.866932, 0.0756005, 0, 0.23938, 0.859976, 0.0709019, 0, 0.254364, 0.853375, 0.0664391, 0, 0.269646, 0.846971, 0.0622012, 0, 0.285223, 0.840483, 0.058129, 0, 0.301096, 0.833969, 0.0542762, 0, 0.317265, 0.82806, 0.0507042, 0, 0.333729, 0.822128, 0.047368, 0, 0.350491, 0.815989, 0.044272, 0, 0.367554, 0.809336, 0.0413444, 0, 0.38492, 0.802177, 0.038601, 0, 0.402594, 0.79441, 0.0360227, 0, 0.420582, 0.786573, 0.0336383, 0, 0.438891, 0.778619, 0.0314321, 0, 0.457527, 0.77, 0.029362, 0, 0.476499, 0.760698, 0.0274102, 0, 0.49582, 0.750932, 0.0256146, 0, 0.5155, 0.740993, 0.023974, 0, 0.535555, 0.731159, 0.0224182, 0, 0.556, 0.720836, 0.0209889, 0, 0.576855, 0.709913, 0.0196411, 0, 0.598143, 0.698415, 0.0183824, 0, 0.619888, 0.68745, 0.0172222, 0, 0.642123, 0.676154, 0.0161509, 0, 0.664883, 0.664383, 0.0151397, 0, 0.688211, 0.6533, 0.0141873, 0, 0.71216, 0.642072, 0.0133105, 0, 0.736792, 0.631412, 0.0124932, 0, 0.762186, 0.621622, 0.0117408, 0, 0.788439, 0.611681, 0.0110358, 0, 0.815672, 0.60142, 0.0103775, 0, 0.844034, 0.59083, 0.00975623, 0, 0.873699, 0.580254, 0.00918084, 0, 0.904765, 0.569841, 0.00864721, 0, 0.936508, 0.559224, 0.00815731, 0, 0.968254, 0.548315, 0.00767924, 0, 1, 1, 0.177563, 0, 0, 1, 0.177563, 0, 0, 0.999994, 0.177562, 0, 0, 0.999972, 0.177555, 0, 6.64171e-05, 0.999914, 0.177536, 0, 0.0012276, 0.999787, 0.177496, 0, 0.00388025, 0.999556, 0.17742, 0, 0.00783463, 0.999165, 0.177285, 0, 0.0128953, 0.9985, 0.177037, 0, 0.0189053, 0.995388, 0.175634, 0, 0.025742, 0.993102, 0.174375, 0, 0.033309, 0.990992, 0.173121, 0, 0.0415298, 0.986932, 0.170896, 0, 0.0503425, 0.982786, 0.16847, 0, 0.0596964, 0.977592, 0.165455, 0, 0.0695498, 0.971075, 0.161676, 0, 0.0798676, 0.963967, 0.157458, 0, 0.0906201, 0.956397, 0.152836, 0, 0.101783, 0.947489, 0.147467, 0, 0.113333, 0.937564, 0.14145, 0, 0.125254, 0.928182, 0.135383, 0, 0.137529, 0.919027, 0.129212, 0, 0.150144, 0.909618, 0.12276, 0, 0.163088, 0.900492, 0.116273, 0, 0.176351, 0.891671, 0.1098, 0, 0.189924, 0.883146, 0.103362, 0, 0.203799, 0.875151, 0.0970799, 0, 0.21797, 0.868338, 0.0911732, 0, 0.232433, 0.862033, 0.0854966, 0, 0.247182, 0.856107, 0.0800691, 0, 0.262216, 0.850644, 0.0749618, 0, 0.27753, 0.845261, 0.070079, 0, 0.293124, 0.839885, 0.0654321, 0, 0.308997, 0.834609, 0.0610975, 0, 0.325149, 0.829083, 0.0569741, 0, 0.341581, 0.82404, 0.0531736, 0, 0.358294, 0.818968, 0.049665, 0, 0.37529, 0.813496, 0.0463856, 0, 0.392573, 0.807533, 0.0433217, 0, 0.410148, 0.80099, 0.0404402, 0, 0.428019, 0.793891, 0.0377578, 0, 0.446192, 0.786281, 0.0352616, 0, 0.464676, 0.778773, 0.0329577, 0, 0.483478, 0.770737, 0.030808, 0, 0.502608, 0.762094, 0.0287964, 0, 0.522079, 0.752898, 0.0269254, 0, 0.541905, 0.743306, 0.0251926, 0, 0.5621, 0.733416, 0.023595, 0, 0.582684, 0.723742, 0.0221155, 0, 0.603677, 0.713542, 0.0207435, 0, 0.625106, 0.702755, 0.019434, 0, 0.646998, 0.691484, 0.0182046, 0, 0.66939, 0.680531, 0.0170771, 0, 0.692324, 0.66953, 0.0160339, 0, 0.715849, 0.658126, 0.0150677, 0, 0.740028, 0.646933, 0.0141551, 0, 0.764937, 0.636107, 0.0133179, 0, 0.790673, 0.625271, 0.0125284, 0, 0.817358, 0.615225, 0.0117937, 0, 0.84515, 0.605678, 0.0111181, 0, 0.874244, 0.59583, 0.0104759, 0, 0.904828, 0.585704, 0.00986672, 0, 0.936508, 0.575413, 0.00929712, 0, 0.968254, 0.565373, 0.00876713, 0, 1, 1, 0.214058, 0, 0, 0.999999, 0.214058, 0, 0, 0.999994, 0.214055, 0, 0, 0.999966, 0.214039, 0, 0.000259642, 0.999893, 0.213998, 0, 0.00200075, 0.999737, 0.21391, 0, 0.00527775, 0.999449, 0.213745, 0, 0.00983959, 0.99896, 0.213458, 0, 0.0154755, 0.9979, 0.212855, 0, 0.0220249, 0.994278, 0.210779, 0, 0.0293654, 0.992254, 0.20926, 0, 0.0374021, 0.98881, 0.206908, 0, 0.0460604, 0.984715, 0.204009, 0, 0.0552802, 0.979738, 0.200471, 0, 0.0650127, 0.972884, 0.195813, 0, 0.0752175, 0.965996, 0.190856, 0, 0.0858612, 0.957974, 0.185077, 0, 0.0969155, 0.949155, 0.17868, 0, 0.108356, 0.939288, 0.171513, 0, 0.120163, 0.928996, 0.163838, 0, 0.132319, 0.919563, 0.156246, 0, 0.144808, 0.910004, 0.148359, 0, 0.157618, 0.900791, 0.140417, 0, 0.170737, 0.892135, 0.132569, 0, 0.184155, 0.883803, 0.124741, 0, 0.197866, 0.876034, 0.117091, 0, 0.211861, 0.869219, 0.109835, 0, 0.226134, 0.863062, 0.102859, 0, 0.240682, 0.857795, 0.0962928, 0, 0.255499, 0.853009, 0.0900725, 0, 0.270583, 0.848603, 0.0842101, 0, 0.285931, 0.844335, 0.0786527, 0, 0.301542, 0.840208, 0.0734397, 0, 0.317415, 0.836035, 0.0685334, 0, 0.33355, 0.83172, 0.0639275, 0, 0.349948, 0.827135, 0.0595909, 0, 0.36661, 0.822797, 0.0556204, 0, 0.383539, 0.818387, 0.0519394, 0, 0.400738, 0.813565, 0.0485317, 0, 0.41821, 0.808142, 0.0453138, 0, 0.435961, 0.802212, 0.0423354, 0, 0.453997, 0.79573, 0.0395553, 0, 0.472324, 0.788741, 0.036988, 0, 0.490951, 0.781093, 0.0345688, 0, 0.509887, 0.773597, 0.0323297, 0, 0.529144, 0.765622, 0.0302719, 0, 0.548735, 0.757083, 0.0283477, 0, 0.568674, 0.747992, 0.0265562, 0, 0.588979, 0.738591, 0.0248844, 0, 0.609671, 0.728719, 0.0233342, 0, 0.630773, 0.719146, 0.0219081, 0, 0.652314, 0.709165, 0.0205711, 0, 0.674328, 0.69875, 0.0193248, 0, 0.696854, 0.687884, 0.0181582, 0, 0.719942, 0.676818, 0.0170746, 0, 0.743651, 0.666247, 0.0160718, 0, 0.768057, 0.655284, 0.0151262, 0, 0.793253, 0.64401, 0.0142561, 0, 0.819363, 0.633353, 0.0134327, 0, 0.846547, 0.622674, 0.012653, 0, 0.875017, 0.612265, 0.0119354, 0, 0.905021, 0.602455, 0.0112533, 0, 0.936508, 0.593147, 0.0106234, 0, 0.968254, 0.583592, 0.0100213, 0, 1, 1, 0.25717, 0, 0, 1, 0.25717, 0, 0, 0.999992, 0.257164, 0, 0, 0.999958, 0.257135, 0, 0.000641715, 0.999864, 0.25706, 0, 0.00305314, 0.999666, 0.256897, 0, 0.00700975, 0.999302, 0.256596, 0, 0.0122194, 0.998663, 0.25607, 0, 0.0184622, 0.995607, 0.254123, 0, 0.0255773, 0.993094, 0.252081, 0, 0.0334439, 0.9907, 0.249867, 0, 0.0419696, 0.98594, 0.246118, 0, 0.0510823, 0.981214, 0.242049, 0, 0.0607242, 0.974966, 0.236869, 0, 0.0708486, 0.967589, 0.230724, 0, 0.081417, 0.95915, 0.223635, 0, 0.0923974, 0.950257, 0.21596, 0, 0.103763, 0.940165, 0.207296, 0, 0.115491, 0.929396, 0.197901, 0, 0.127562, 0.919288, 0.188437, 0, 0.13996, 0.909428, 0.178762, 0, 0.15267, 0.900105, 0.169072, 0, 0.165679, 0.891418, 0.159478, 0, 0.178979, 0.883347, 0.15002, 0, 0.192558, 0.875992, 0.140813, 0, 0.20641, 0.869466, 0.13196, 0, 0.220529, 0.863699, 0.123501, 0, 0.234907, 0.858553, 0.115436, 0, 0.249542, 0.854379, 0.107901, 0, 0.264428, 0.850894, 0.10088, 0, 0.279564, 0.847632, 0.0942296, 0, 0.294947, 0.844571, 0.0879861, 0, 0.310575, 0.84163, 0.0821534, 0, 0.326448, 0.838542, 0.0766409, 0, 0.342566, 0.835412, 0.0715322, 0, 0.358929, 0.831899, 0.0666883, 0, 0.37554, 0.828177, 0.0622175, 0, 0.392399, 0.82416, 0.0580452, 0, 0.409511, 0.820393, 0.054267, 0, 0.426878, 0.816068, 0.0507172, 0, 0.444506, 0.811201, 0.0474041, 0, 0.4624, 0.805785, 0.0443174, 0, 0.480566, 0.799878, 0.0414562, 0, 0.499013, 0.793469, 0.0388147, 0, 0.517749, 0.786473, 0.0363453, 0, 0.536785, 0.778874, 0.0340225, 0, 0.556134, 0.771277, 0.0318599, 0, 0.575809, 0.763426, 0.0298859, 0, 0.595827, 0.755044, 0.0280357, 0, 0.616207, 0.746161, 0.0262979, 0, 0.636973, 0.737124, 0.0247295, 0, 0.65815, 0.72761, 0.0232514, 0, 0.679772, 0.717822, 0.0218755, 0, 0.701876, 0.708279, 0.0205942, 0, 0.724509, 0.698333, 0.0193947, 0, 0.74773, 0.68802, 0.0182717, 0, 0.771609, 0.677321, 0.0172044, 0, 0.79624, 0.666504, 0.0162122, 0, 0.821743, 0.656184, 0.0152924, 0, 0.84828, 0.64556, 0.0144326, 0, 0.876069, 0.634636, 0.0136157, 0, 0.905404, 0.624124, 0.0128612, 0, 0.936508, 0.613914, 0.0121435, 0, 0.968254, 0.603589, 0.0114887, 0, 1, 1, 0.307946, 0, 0, 0.999999, 0.307945, 0, 0, 0.999988, 0.307934, 0, 2.04479e-05, 0.999944, 0.307886, 0, 0.00127833, 0.999824, 0.307756, 0, 0.00445047, 0.999565, 0.30748, 0, 0.00914673, 0.999085, 0.306966, 0, 0.0150498, 0.998103, 0.306004, 0, 0.0219367, 0.994249, 0.303028, 0, 0.0296485, 0.991807, 0.300435, 0, 0.038068, 0.987773, 0.296554, 0, 0.0471062, 0.982673, 0.2916, 0, 0.0566942, 0.976623, 0.285641, 0, 0.0667768, 0.968757, 0.27815, 0, 0.0773099, 0.959849, 0.269529, 0, 0.088257, 0.950663, 0.260248, 0, 0.0995879, 0.940129, 0.249704, 0, 0.111277, 0.92895, 0.238291, 0, 0.123304, 0.917996, 0.226501, 0, 0.13565, 0.907813, 0.214669, 0, 0.148299, 0.898305, 0.202835, 0, 0.161237, 0.889626, 0.191158, 0, 0.174455, 0.88175, 0.179695, 0, 0.187941, 0.874715, 0.168548, 0, 0.201687, 0.868746, 0.15792, 0, 0.215687, 0.863703, 0.147807, 0, 0.229933, 0.859315, 0.138149, 0, 0.24442, 0.855538, 0.128993, 0, 0.259145, 0.852428, 0.120414, 0, 0.274103, 0.850168, 0.112498, 0, 0.289293, 0.848132, 0.105054, 0, 0.304711, 0.846291, 0.0981087, 0, 0.320357, 0.844431, 0.0915942, 0, 0.33623, 0.842493, 0.0855056, 0, 0.35233, 0.840368, 0.0798204, 0, 0.368658, 0.83798, 0.0745097, 0, 0.385214, 0.83523, 0.0695424, 0, 0.402002, 0.832091, 0.0649092, 0, 0.419023, 0.828667, 0.0606291, 0, 0.436282, 0.824805, 0.0566523, 0, 0.453782, 0.820988, 0.0530229, 0, 0.471529, 0.816635, 0.0496364, 0, 0.489528, 0.811725, 0.0464658, 0, 0.507788, 0.806316, 0.0435082, 0, 0.526317, 0.800469, 0.0407873, 0, 0.545124, 0.794107, 0.038255, 0, 0.564221, 0.787218, 0.0358825, 0, 0.583621, 0.779872, 0.0336785, 0, 0.603341, 0.772097, 0.0316379, 0, 0.623397, 0.764484, 0.0297379, 0, 0.643812, 0.756428, 0.0279581, 0, 0.664611, 0.748022, 0.0263153, 0, 0.685824, 0.739268, 0.0247799, 0, 0.707488, 0.73024, 0.0233385, 0, 0.729646, 0.720893, 0.0220035, 0, 0.752354, 0.71119, 0.0207555, 0, 0.77568, 0.701791, 0.0195843, 0, 0.799715, 0.692184, 0.0184891, 0, 0.824574, 0.682258, 0.0174541, 0, 0.850417, 0.67206, 0.0164873, 0, 0.877466, 0.661717, 0.0155959, 0, 0.90604, 0.651462, 0.0147519, 0, 0.936528, 0.641467, 0.0139727, 0, 0.968254, 0.631229, 0.0132363, 0, 1, 1, 0.367573, 0, 0, 0.999999, 0.367571, 0, 0, 0.999984, 0.367553, 0, 0.000183382, 0.999925, 0.367473, 0, 0.00225254, 0.999759, 0.367259, 0, 0.00628165, 0.99941, 0.366801, 0, 0.0117858, 0.998739, 0.365946, 0, 0.0184359, 0.995529, 0.363191, 0, 0.0260114, 0.992875, 0.360171, 0, 0.0343581, 0.989135, 0.355981, 0, 0.0433637, 0.984166, 0.350401, 0, 0.0529438, 0.977871, 0.343348, 0, 0.0630334, 0.96951, 0.334341, 0, 0.0735805, 0.959964, 0.323862, 0, 0.0845437, 0.950162, 0.312521, 0, 0.095889, 0.938882, 0.299577, 0, 0.107588, 0.926992, 0.285573, 0, 0.119617, 0.915589, 0.271212, 0, 0.131957, 0.904791, 0.256611, 0, 0.144591, 0.895177, 0.242224, 0, 0.157503, 0.886403, 0.227952, 0, 0.170682, 0.878957, 0.214192, 0, 0.184117, 0.872418, 0.200795, 0, 0.197799, 0.867029, 0.188015, 0, 0.21172, 0.862835, 0.175975, 0, 0.225873, 0.859411, 0.164526, 0, 0.240253, 0.856655, 0.153693, 0, 0.254854, 0.854519, 0.14352, 0, 0.269673, 0.852828, 0.13397, 0, 0.284707, 0.851412, 0.124984, 0, 0.299953, 0.850609, 0.116748, 0, 0.315408, 0.849855, 0.10905, 0, 0.331073, 0.849017, 0.101839, 0, 0.346946, 0.848079, 0.0951359, 0, 0.363028, 0.846911, 0.0888774, 0, 0.379318, 0.845445, 0.0830375, 0, 0.395818, 0.84362, 0.0775844, 0, 0.41253, 0.841411, 0.0725054, 0, 0.429457, 0.838768, 0.0677691, 0, 0.446602, 0.835801, 0.0634016, 0, 0.463968, 0.832341, 0.0593095, 0, 0.481561, 0.828424, 0.0555121, 0, 0.499386, 0.824312, 0.052024, 0, 0.51745, 0.819918, 0.0487865, 0, 0.535761, 0.815072, 0.0457801, 0, 0.554328, 0.809863, 0.0430184, 0, 0.573162, 0.804164, 0.0404245, 0, 0.592275, 0.798034, 0.0380146, 0, 0.611681, 0.791436, 0.0357436, 0, 0.631398, 0.784498, 0.0336475, 0, 0.651445, 0.777125, 0.0316666, 0, 0.671845, 0.769365, 0.0298122, 0, 0.692628, 0.761579, 0.0281001, 0, 0.713827, 0.753746, 0.0265049, 0, 0.735484, 0.745573, 0.0250067, 0, 0.75765, 0.737083, 0.0236026, 0, 0.78039, 0.728545, 0.0223302, 0, 0.803789, 0.719691, 0.0211243, 0, 0.82796, 0.710569, 0.0199983, 0, 0.853056, 0.701216, 0.0189569, 0, 0.879298, 0.692094, 0.0179702, 0, 0.907014, 0.682909, 0.0170418, 0, 0.936691, 0.673509, 0.0161732, 0, 0.968254, 0.663863, 0.0153406, 0, 1, 1, 0.437395, 0, 0, 0.999998, 0.437394, 0, 0, 0.99998, 0.437363, 0, 0.000616704, 0.999891, 0.437232, 0, 0.00367925, 0.999656, 0.436877, 0, 0.00867446, 0.999148, 0.436121, 0, 0.0150679, 0.997959, 0.434564, 0, 0.022531, 0.993464, 0.430134, 0, 0.0308507, 0.990606, 0.426077, 0, 0.0398805, 0.985027, 0.419397, 0, 0.0495148, 0.978491, 0.41118, 0, 0.0596749, 0.969643, 0.40048, 0, 0.0703001, 0.959189, 0.38769, 0, 0.0813427, 0.948223, 0.373575, 0, 0.0927641, 0.935955, 0.357622, 0, 0.104533, 0.923237, 0.34043, 0, 0.116624, 0.911074, 0.322735, 0, 0.129015, 0.899724, 0.30479, 0, 0.141687, 0.890189, 0.287392, 0, 0.154626, 0.881796, 0.270248, 0, 0.167818, 0.874781, 0.253659, 0, 0.181252, 0.869166, 0.237786, 0, 0.194918, 0.864725, 0.222618, 0, 0.208807, 0.861565, 0.208356, 0, 0.222913, 0.859284, 0.194867, 0, 0.237229, 0.857677, 0.18212, 0, 0.25175, 0.856714, 0.17018, 0, 0.266473, 0.856155, 0.158969, 0, 0.281392, 0.8558, 0.148413, 0, 0.296505, 0.855672, 0.138578, 0, 0.311811, 0.855538, 0.129345, 0, 0.327306, 0.855689, 0.120861, 0, 0.342991, 0.855767, 0.112969, 0, 0.358864, 0.855618, 0.105593, 0, 0.374925, 0.85525, 0.0987451, 0, 0.391176, 0.854583, 0.0923727, 0, 0.407616, 0.853534, 0.0864143, 0, 0.424249, 0.852061, 0.0808338, 0, 0.441076, 0.850253, 0.0756771, 0, 0.4581, 0.848004, 0.0708612, 0, 0.475324, 0.845333, 0.0663784, 0, 0.492754, 0.842376, 0.0622631, 0, 0.510394, 0.838956, 0.0584112, 0, 0.528251, 0.835121, 0.0548328, 0, 0.546331, 0.830842, 0.0514838, 0, 0.564644, 0.826212, 0.048355, 0, 0.583198, 0.821522, 0.0454714, 0, 0.602005, 0.816551, 0.0428263, 0, 0.621078, 0.811211, 0.0403612, 0, 0.640434, 0.805479, 0.038039, 0, 0.660089, 0.799409, 0.0358739, 0, 0.680066, 0.79306, 0.0338727, 0, 0.70039, 0.786395, 0.0319985, 0, 0.721094, 0.779416, 0.030241, 0, 0.742215, 0.77214, 0.0285951, 0, 0.7638, 0.764636, 0.0270747, 0, 0.785912, 0.756836, 0.0256354, 0, 0.808628, 0.749315, 0.0243027, 0, 0.832055, 0.741561, 0.0230497, 0, 0.856338, 0.733589, 0.0218801, 0, 0.88169, 0.725479, 0.020784, 0, 0.908441, 0.717255, 0.0197702, 0, 0.937125, 0.708829, 0.0188168, 0, 0.968254, 0.700191, 0.0179113, 0, 1, 1, 0.518937, 0, 0, 0.999998, 0.518933, 0, 0, 0.999967, 0.518883, 0, 0.00147741, 0.999832, 0.51866, 0, 0.00573221, 0.999466, 0.518057, 0, 0.011826, 0.998644, 0.516752, 0, 0.0192116, 0.994458, 0.512347, 0, 0.027573, 0.991223, 0.507675, 0, 0.0367099, 0.985515, 0.500188, 0, 0.046487, 0.978308, 0.490408, 0, 0.0568071, 0.968359, 0.477357, 0, 0.0675984, 0.95682, 0.461752, 0, 0.0788059, 0.943929, 0.443796, 0, 0.090386, 0.930224, 0.423893, 0, 0.102304, 0.916514, 0.402682, 0, 0.114532, 0.903653, 0.380914, 0, 0.127047, 0.892315, 0.359212, 0, 0.139828, 0.882942, 0.338102, 0, 0.152861, 0.875438, 0.31773, 0, 0.16613, 0.869642, 0.298186, 0, 0.179624, 0.865304, 0.279491, 0, 0.193332, 0.862382, 0.261804, 0, 0.207247, 0.860666, 0.245146, 0, 0.22136, 0.859788, 0.229406, 0, 0.235666, 0.859608, 0.214605, 0, 0.250158, 0.859912, 0.200691, 0, 0.264832, 0.86053, 0.187623, 0, 0.279684, 0.861368, 0.17539, 0, 0.294711, 0.862237, 0.163901, 0, 0.309911, 0.863127, 0.153175, 0, 0.32528, 0.863923, 0.143147, 0, 0.340819, 0.864567, 0.133781, 0, 0.356524, 0.865013, 0.125042, 0, 0.372397, 0.86539, 0.116952, 0, 0.388438, 0.865591, 0.109476, 0, 0.404645, 0.865517, 0.102542, 0, 0.421022, 0.865084, 0.0960688, 0, 0.437569, 0.864309, 0.0900499, 0, 0.454287, 0.863151, 0.0844328, 0, 0.471181, 0.861649, 0.0792218, 0, 0.488253, 0.859742, 0.0743482, 0, 0.505507, 0.857446, 0.0697963, 0, 0.522947, 0.854757, 0.0655364, 0, 0.54058, 0.851783, 0.061608, 0, 0.558412, 0.848516, 0.0579701, 0, 0.576449, 0.844897, 0.0545742, 0, 0.594701, 0.840956, 0.0514167, 0, 0.613178, 0.836676, 0.0484598, 0, 0.631892, 0.832075, 0.0456934, 0, 0.650856, 0.827191, 0.0431178, 0, 0.670088, 0.822295, 0.0407718, 0, 0.689606, 0.817294, 0.0386032, 0, 0.709434, 0.812013, 0.0365675, 0, 0.7296, 0.806465, 0.0346547, 0, 0.750138, 0.800691, 0.0328717, 0, 0.771093, 0.794709, 0.031211, 0, 0.792519, 0.788493, 0.0296504, 0, 0.814488, 0.782049, 0.0281782, 0, 0.837097, 0.775403, 0.0267965, 0, 0.860481, 0.76857, 0.0255002, 0, 0.884842, 0.761536, 0.0242759, 0, 0.910494, 0.754303, 0.0231142, 0, 0.937985, 0.74692, 0.0220305, 0, 0.968254, 0.739745, 0.0210192, 0, 1, 1, 0.613914, 0, 0, 0.999996, 0.613907, 0, 9.63597e-05, 0.999942, 0.613814, 0, 0.00301247, 0.999704, 0.613407, 0, 0.00870385, 0.999046, 0.612302, 0, 0.0160714, 0.995516, 0.608266, 0, 0.0245899, 0.991726, 0.602863, 0, 0.0339681, 0.985157, 0.593956, 0, 0.0440254, 0.97642, 0.581748, 0, 0.0546409, 0.964404, 0.565183, 0, 0.0657284, 0.950601, 0.545273, 0, 0.0772246, 0.935158, 0.522129, 0, 0.0890812, 0.919364, 0.496782, 0, 0.10126, 0.904754, 0.470571, 0, 0.113731, 0.89176, 0.444037, 0, 0.126469, 0.881492, 0.418322, 0, 0.139454, 0.873656, 0.393522, 0, 0.15267, 0.868053, 0.369795, 0, 0.166101, 0.864336, 0.347171, 0, 0.179736, 0.862259, 0.325737, 0, 0.193565, 0.861556, 0.305532, 0, 0.207578, 0.861776, 0.286416, 0, 0.221769, 0.862661, 0.268355, 0, 0.23613, 0.864015, 0.251334, 0, 0.250656, 0.865711, 0.235352, 0, 0.265343, 0.867519, 0.220302, 0, 0.280187, 0.869351, 0.206161, 0, 0.295183, 0.871144, 0.192908, 0, 0.31033, 0.872839, 0.180505, 0, 0.325624, 0.874307, 0.168848, 0, 0.341065, 0.875667, 0.158021, 0, 0.35665, 0.876758, 0.147877, 0, 0.37238, 0.87764, 0.138441, 0, 0.388253, 0.878237, 0.129627, 0, 0.404269, 0.878563, 0.121415, 0, 0.42043, 0.878572, 0.113741, 0, 0.436735, 0.87842, 0.106652, 0, 0.453187, 0.878057, 0.100097, 0, 0.469786, 0.877413, 0.0940128, 0, 0.486536, 0.87646, 0.0883462, 0, 0.503439, 0.875233, 0.0830924, 0, 0.520498, 0.8737, 0.0781975, 0, 0.537717, 0.871873, 0.07364, 0, 0.555102, 0.86978, 0.0694103, 0, 0.572657, 0.867405, 0.0654696, 0, 0.59039, 0.864751, 0.0617914, 0, 0.608307, 0.861818, 0.0583491, 0, 0.626419, 0.858645, 0.0551443, 0, 0.644733, 0.855307, 0.0521894, 0, 0.663264, 0.851736, 0.0494334, 0, 0.682025, 0.847927, 0.0468504, 0, 0.701032, 0.843888, 0.0444261, 0, 0.720308, 0.839629, 0.0421497, 0, 0.739875, 0.835158, 0.0400082, 0, 0.759764, 0.830509, 0.0380076, 0, 0.780014, 0.825714, 0.0361488, 0, 0.800673, 0.820729, 0.0343956, 0, 0.821803, 0.815751, 0.0327781, 0, 0.843492, 0.810752, 0.031275, 0, 0.86586, 0.805587, 0.0298542, 0, 0.889087, 0.800317, 0.0285397, 0, 0.913466, 0.79489, 0.0272948, 0, 0.93952, 0.789314, 0.0261139, 0, 0.96835, 0.783593, 0.0249938, 0, 1, 1, 0.724258, 0, 0, 0.999992, 0.724243, 0, 0.000726889, 0.99987, 0.724044, 0, 0.00569574, 0.999336, 0.72317, 0, 0.0131702, 0.996271, 0.719432, 0, 0.0220738, 0.991159, 0.712576, 0, 0.0319405, 0.982465, 0.700927, 0, 0.0425202, 0.97049, 0.684297, 0, 0.0536599, 0.953973, 0.661244, 0, 0.065258, 0.935546, 0.633804, 0, 0.0772427, 0.916596, 0.603071, 0, 0.0895616, 0.899353, 0.57105, 0, 0.102175, 0.885216, 0.539206, 0, 0.11505, 0.875076, 0.508714, 0, 0.128164, 0.868334, 0.479571, 0, 0.141495, 0.864414, 0.451796, 0, 0.155026, 0.862678, 0.425328, 0, 0.168745, 0.862835, 0.400352, 0, 0.182639, 0.864067, 0.376532, 0, 0.196699, 0.866086, 0.35391, 0, 0.210915, 0.868557, 0.332424, 0, 0.225282, 0.871271, 0.312053, 0, 0.239792, 0.874058, 0.292764, 0, 0.25444, 0.8768, 0.27453, 0, 0.269223, 0.87939, 0.257297, 0, 0.284135, 0.8819, 0.24114, 0, 0.299174, 0.884187, 0.225934, 0, 0.314337, 0.886262, 0.211669, 0, 0.329622, 0.888119, 0.198311, 0, 0.345026, 0.889709, 0.185783, 0, 0.360549, 0.891054, 0.174063, 0, 0.376189, 0.892196, 0.163143, 0, 0.391946, 0.893101, 0.152952, 0, 0.407819, 0.893803, 0.143475, 0, 0.423808, 0.894277, 0.134647, 0, 0.439914, 0.894532, 0.126434, 0, 0.456137, 0.894576, 0.1188, 0, 0.472479, 0.894393, 0.111694, 0, 0.48894, 0.893976, 0.105069, 0, 0.505523, 0.893346, 0.0989077, 0, 0.52223, 0.892502, 0.0931724, 0, 0.539064, 0.891441, 0.0878276, 0, 0.556028, 0.890276, 0.082903, 0, 0.573125, 0.888972, 0.0783505, 0, 0.590361, 0.887469, 0.0741083, 0, 0.607741, 0.885785, 0.0701633, 0, 0.62527, 0.883914, 0.0664835, 0, 0.642957, 0.881872, 0.0630567, 0, 0.660809, 0.879651, 0.0598527, 0, 0.678836, 0.877267, 0.0568615, 0, 0.69705, 0.874717, 0.05406, 0, 0.715465, 0.872012, 0.0514378, 0, 0.734098, 0.869157, 0.0489805, 0, 0.752968, 0.866155, 0.0466727, 0, 0.772101, 0.863014, 0.0445056, 0, 0.791529, 0.859748, 0.0424733, 0, 0.81129, 0.856416, 0.0405957, 0, 0.831438, 0.852958, 0.0388273, 0, 0.852044, 0.849382, 0.0371619, 0, 0.87321, 0.845694, 0.0355959, 0, 0.89509, 0.841893, 0.0341155, 0, 0.917932, 0.837981, 0.0327141, 0, 0.942204, 0.833963, 0.0313856, 0, 0.968981, 0.829847, 0.0301275, 0, 1, 1, 0.85214, 0, 0, 0.999969, 0.852095, 0, 0.00279627, 0.999483, 0.851408, 0, 0.0107635, 0.994545, 0.84579, 0, 0.0206454, 0.986188, 0.835231, 0, 0.0315756, 0.969847, 0.814687, 0, 0.0432021, 0.945951, 0.783735, 0, 0.0553396, 0.91917, 0.746074, 0, 0.0678766, 0.895488, 0.706938, 0, 0.0807395, 0.878232, 0.669534, 0, 0.0938767, 0.868252, 0.635168, 0, 0.10725, 0.863873, 0.603069, 0, 0.120832, 0.863369, 0.572514, 0, 0.134598, 0.86545, 0.543169, 0, 0.148533, 0.868803, 0.514578, 0, 0.16262, 0.872794, 0.486762, 0, 0.176849, 0.87702, 0.459811, 0, 0.19121, 0.881054, 0.433654, 0, 0.205694, 0.884974, 0.408574, 0, 0.220294, 0.888587, 0.384525, 0, 0.235005, 0.891877, 0.36156, 0, 0.24982, 0.894793, 0.339661, 0, 0.264737, 0.89743, 0.318913, 0, 0.279751, 0.899796, 0.299302, 0, 0.294859, 0.901943, 0.280843, 0, 0.310058, 0.903858, 0.263481, 0, 0.325346, 0.905574, 0.247197, 0, 0.340721, 0.907069, 0.231915, 0, 0.356181, 0.908379, 0.217614, 0, 0.371725, 0.90952, 0.20425, 0, 0.387353, 0.910483, 0.191758, 0, 0.403063, 0.91128, 0.180092, 0, 0.418854, 0.911936, 0.169222, 0, 0.434727, 0.912454, 0.159098, 0, 0.450682, 0.912835, 0.149668, 0, 0.466718, 0.913078, 0.140884, 0, 0.482837, 0.913192, 0.132709, 0, 0.499038, 0.913175, 0.125095, 0, 0.515324, 0.91304, 0.118012, 0, 0.531695, 0.912781, 0.111417, 0, 0.548153, 0.91241, 0.105281, 0, 0.5647, 0.911924, 0.0995691, 0, 0.581338, 0.911331, 0.0942531, 0, 0.59807, 0.910637, 0.0893076, 0, 0.6149, 0.90984, 0.0846998, 0, 0.63183, 0.908941, 0.0804044, 0, 0.648865, 0.907944, 0.0763984, 0, 0.666011, 0.906857, 0.0726638, 0, 0.683273, 0.90568, 0.0691783, 0, 0.700659, 0.904416, 0.0659222, 0, 0.718176, 0.903067, 0.0628782, 0, 0.735834, 0.901637, 0.0600307, 0, 0.753646, 0.900128, 0.0573647, 0, 0.771625, 0.898544, 0.0548668, 0, 0.78979, 0.89689, 0.052527, 0, 0.808162, 0.895165, 0.0503306, 0, 0.826771, 0.893371, 0.0482668, 0, 0.845654, 0.891572, 0.0463605, 0, 0.864863, 0.889763, 0.0445998, 0, 0.884472, 0.887894, 0.0429451, 0, 0.904592, 0.885967, 0.0413884, 0, 0.925407, 0.883984, 0.0399225, 0, 0.947271, 0.881945, 0.0385405, 0, 0.97105, 0.879854, 0.0372362, 0, 1, 0.999804, 0.995833, 0, 0, 0.938155, 0.933611, 0, 0.0158731, 0.864755, 0.854311, 0, 0.0317461, 0.888594, 0.865264, 0, 0.0476191, 0.905575, 0.863922, 0, 0.0634921, 0.915125, 0.850558, 0, 0.0793651, 0.920665, 0.829254, 0, 0.0952381, 0.924073, 0.802578, 0, 0.111111, 0.926304, 0.772211, 0, 0.126984, 0.927829, 0.739366, 0, 0.142857, 0.928924, 0.705033, 0, 0.15873, 0.92973, 0.670019, 0, 0.174603, 0.930339, 0.634993, 0, 0.190476, 0.930811, 0.600485, 0, 0.206349, 0.931191, 0.566897, 0, 0.222222, 0.93149, 0.534485, 0, 0.238095, 0.931737, 0.503429, 0, 0.253968, 0.931939, 0.473811, 0, 0.269841, 0.932108, 0.445668, 0, 0.285714, 0.93225, 0.418993, 0, 0.301587, 0.932371, 0.393762, 0, 0.31746, 0.932474, 0.369939, 0, 0.333333, 0.932562, 0.347479, 0, 0.349206, 0.932638, 0.326336, 0, 0.365079, 0.932703, 0.306462, 0, 0.380952, 0.93276, 0.287805, 0, 0.396825, 0.932809, 0.270313, 0, 0.412698, 0.932851, 0.253933, 0, 0.428571, 0.932887, 0.23861, 0, 0.444444, 0.932917, 0.224289, 0, 0.460317, 0.932943, 0.210917, 0, 0.47619, 0.932965, 0.19844, 0, 0.492063, 0.932982, 0.186807, 0, 0.507937, 0.932995, 0.175966, 0, 0.52381, 0.933005, 0.165869, 0, 0.539683, 0.933011, 0.156468, 0, 0.555556, 0.933013, 0.147719, 0, 0.571429, 0.933013, 0.139579, 0, 0.587302, 0.93301, 0.132007, 0, 0.603175, 0.933004, 0.124965, 0, 0.619048, 0.932994, 0.118416, 0, 0.634921, 0.932982, 0.112326, 0, 0.650794, 0.932968, 0.106663, 0, 0.666667, 0.93295, 0.101397, 0, 0.68254, 0.932931, 0.0964993, 0, 0.698413, 0.932908, 0.0919438, 0, 0.714286, 0.932883, 0.0877057, 0, 0.730159, 0.932856, 0.0837623, 0, 0.746032, 0.932827, 0.0800921, 0, 0.761905, 0.932796, 0.0766754, 0, 0.777778, 0.932762, 0.0734936, 0, 0.793651, 0.932727, 0.0705296, 0, 0.809524, 0.932689, 0.0677676, 0, 0.825397, 0.93265, 0.0651929, 0, 0.84127, 0.932609, 0.0627917, 0, 0.857143, 0.932565, 0.0605515, 0, 0.873016, 0.932521, 0.0584606, 0, 0.888889, 0.932474, 0.0565082, 0, 0.904762, 0.932427, 0.0546841, 0, 0.920635, 0.932377, 0.0529793, 0, 0.936508, 0.932326, 0.0513851, 0, 0.952381, 0.932274, 0.0498936, 0, 0.968254, 0.93222, 0.0484975, 0, 0.984127, 0.932164, 0.0471899, 0, 1 ]; // data textures + const LTC_MAT_2 = [ 1, 0, 0, 0, 1, 7.91421e-31, 0, 0, 1, 1.04392e-24, 0, 0, 1, 3.49405e-21, 0, 0, 1, 1.09923e-18, 0, 0, 1, 9.47414e-17, 0, 0, 1, 3.59627e-15, 0, 0, 1, 7.72053e-14, 0, 0, 1, 1.08799e-12, 0, 0, 1, 1.10655e-11, 0, 0, 1, 8.65818e-11, 0, 0, 0.999998, 5.45037e-10, 0, 0, 0.999994, 2.85095e-09, 0, 0, 0.999989, 1.26931e-08, 0, 0, 0.999973, 4.89938e-08, 0, 0, 0.999947, 1.66347e-07, 0, 0, 0.999894, 5.02694e-07, 0, 0, 0.999798, 1.36532e-06, 0, 0, 0.999617, 3.35898e-06, 0, 0, 0.999234, 7.52126e-06, 0, 0, 0.998258, 1.52586e-05, 0, 0, 0.99504, 2.66207e-05, 0, 0, 0.980816, 2.36802e-05, 0, 0, 0.967553, 2.07684e-06, 0, 0, 0.966877, 4.03733e-06, 0, 0, 0.965752, 7.41174e-06, 0, 0, 0.96382, 1.27746e-05, 0, 0, 0.960306, 2.02792e-05, 0, 0, 0.953619, 2.80232e-05, 0, 0, 0.941103, 2.78816e-05, 0, 0, 0.926619, 1.60221e-05, 0, 0, 0.920983, 2.35164e-05, 0, 0, 0.912293, 3.11924e-05, 0, 0.0158731, 0.899277, 3.48118e-05, 0, 0.0476191, 0.880884, 2.6041e-05, 0, 0.0793651, 0.870399, 3.38726e-05, 0, 0.111111, 0.856138, 3.92906e-05, 0, 0.142857, 0.837436, 3.72874e-05, 0, 0.174603, 0.820973, 3.92558e-05, 0, 0.206349, 0.803583, 4.34658e-05, 0, 0.238095, 0.782168, 4.0256e-05, 0, 0.269841, 0.764107, 4.48159e-05, 0, 0.301587, 0.743092, 4.57627e-05, 0, 0.333333, 0.721626, 4.55314e-05, 0, 0.365079, 0.700375, 4.77335e-05, 0, 0.396825, 0.677334, 4.61072e-05, 0, 0.428571, 0.655702, 4.84393e-05, 0, 0.460317, 0.632059, 4.64583e-05, 0, 0.492064, 0.610125, 4.83923e-05, 0, 0.52381, 0.58653, 4.64342e-05, 0, 0.555556, 0.564508, 4.77033e-05, 0, 0.587302, 0.541405, 4.59263e-05, 0, 0.619048, 0.519556, 4.6412e-05, 0, 0.650794, 0.497292, 4.48913e-05, 0, 0.68254, 0.475898, 4.45789e-05, 0, 0.714286, 0.454722, 4.33496e-05, 0, 0.746032, 0.434042, 4.23054e-05, 0, 0.777778, 0.414126, 4.13737e-05, 0, 0.809524, 0.394387, 3.97265e-05, 0, 0.84127, 0.375841, 3.90709e-05, 0, 0.873016, 0.357219, 3.69938e-05, 0, 0.904762, 0.340084, 3.65618e-05, 0, 0.936508, 0.322714, 3.42533e-05, 0, 0.968254, 0.306974, 3.39596e-05, 0, 1, 1, 1.01524e-18, 0, 0, 1, 1.0292e-18, 0, 0, 1, 1.30908e-18, 0, 0, 1, 4.73331e-18, 0, 0, 1, 6.25319e-17, 0, 0, 1, 1.07932e-15, 0, 0, 1, 1.63779e-14, 0, 0, 1, 2.03198e-13, 0, 0, 1, 2.04717e-12, 0, 0, 0.999999, 1.68995e-11, 0, 0, 0.999998, 1.15855e-10, 0, 0, 0.999996, 6.6947e-10, 0, 0, 0.999991, 3.30863e-09, 0, 0, 0.999983, 1.41737e-08, 0, 0, 0.999968, 5.32626e-08, 0, 0, 0.99994, 1.77431e-07, 0, 0, 0.999891, 5.28835e-07, 0, 0, 0.999797, 1.42169e-06, 0, 0, 0.999617, 3.47057e-06, 0, 0, 0.999227, 7.7231e-06, 0, 0, 0.998239, 1.55753e-05, 0, 0, 0.994937, 2.68495e-05, 0, 0, 0.980225, 2.13742e-05, 0, 0, 0.967549, 2.1631e-06, 0, 0, 0.966865, 4.17989e-06, 0, 0, 0.965739, 7.63341e-06, 0, 0, 0.963794, 1.30892e-05, 0, 0, 0.960244, 2.06456e-05, 0, 0, 0.953495, 2.82016e-05, 0, 0.000148105, 0.940876, 2.71581e-05, 0, 0.002454, 0.926569, 1.64159e-05, 0, 0.00867491, 0.920905, 2.39521e-05, 0, 0.01956, 0.912169, 3.15127e-05, 0, 0.035433, 0.899095, 3.46626e-05, 0, 0.056294, 0.882209, 2.90223e-05, 0, 0.0818191, 0.870272, 3.42992e-05, 0, 0.111259, 0.855977, 3.94164e-05, 0, 0.142857, 0.837431, 3.72343e-05, 0, 0.174603, 0.820826, 3.96691e-05, 0, 0.206349, 0.803408, 4.35395e-05, 0, 0.238095, 0.782838, 4.19579e-05, 0, 0.269841, 0.763941, 4.50953e-05, 0, 0.301587, 0.742904, 4.55847e-05, 0, 0.333333, 0.721463, 4.58833e-05, 0, 0.365079, 0.700197, 4.77159e-05, 0, 0.396825, 0.677501, 4.70641e-05, 0, 0.428571, 0.655527, 4.84732e-05, 0, 0.460317, 0.6324, 4.76834e-05, 0, 0.492064, 0.609964, 4.84213e-05, 0, 0.52381, 0.586839, 4.75541e-05, 0, 0.555556, 0.564353, 4.76951e-05, 0, 0.587302, 0.541589, 4.67611e-05, 0, 0.619048, 0.519413, 4.63493e-05, 0, 0.650794, 0.497337, 4.53994e-05, 0, 0.68254, 0.475797, 4.45308e-05, 0, 0.714286, 0.454659, 4.35787e-05, 0, 0.746032, 0.434065, 4.24839e-05, 0, 0.777778, 0.414018, 4.1436e-05, 0, 0.809524, 0.39455, 4.01902e-05, 0, 0.84127, 0.375742, 3.90813e-05, 0, 0.873016, 0.357501, 3.77116e-05, 0, 0.904762, 0.339996, 3.6535e-05, 0, 0.936508, 0.323069, 3.51265e-05, 0, 0.968254, 0.306897, 3.39112e-05, 0, 1, 1, 1.0396e-15, 0, 0, 1, 1.04326e-15, 0, 0, 1, 1.10153e-15, 0, 0, 1, 1.44668e-15, 0, 0, 1, 3.4528e-15, 0, 0, 1, 1.75958e-14, 0, 0, 1, 1.2627e-13, 0, 0, 1, 9.36074e-13, 0, 0, 1, 6.45742e-12, 0, 0, 0.999998, 4.01228e-11, 0, 0, 0.999997, 2.22338e-10, 0, 0, 0.999995, 1.0967e-09, 0, 0, 0.999991, 4.82132e-09, 0, 0, 0.999981, 1.89434e-08, 0, 0, 0.999967, 6.67716e-08, 0, 0, 0.999938, 2.12066e-07, 0, 0, 0.999886, 6.0977e-07, 0, 0, 0.999792, 1.59504e-06, 0, 0, 0.999608, 3.81191e-06, 0, 0, 0.999209, 8.33727e-06, 0, 0, 0.998179, 1.65288e-05, 0, 0, 0.994605, 2.74387e-05, 0, 0, 0.979468, 1.67316e-05, 0, 0, 0.967529, 2.42877e-06, 0, 0, 0.966836, 4.61696e-06, 0, 0, 0.96569, 8.30977e-06, 0, 0, 0.963706, 1.40427e-05, 0, 2.44659e-06, 0.960063, 2.17353e-05, 0, 0.000760774, 0.953113, 2.86606e-05, 0, 0.00367261, 0.940192, 2.47691e-05, 0, 0.00940263, 0.927731, 1.95814e-05, 0, 0.018333, 0.920669, 2.52531e-05, 0, 0.0306825, 0.911799, 3.24277e-05, 0, 0.0465556, 0.89857, 3.40982e-05, 0, 0.0659521, 0.883283, 3.19622e-05, 0, 0.0887677, 0.86989, 3.5548e-05, 0, 0.114784, 0.855483, 3.97143e-05, 0, 0.143618, 0.837987, 3.91665e-05, 0, 0.174606, 0.820546, 4.11306e-05, 0, 0.206349, 0.802878, 4.36753e-05, 0, 0.238095, 0.783402, 4.44e-05, 0, 0.269841, 0.763439, 4.58726e-05, 0, 0.301587, 0.742925, 4.67097e-05, 0, 0.333333, 0.721633, 4.78887e-05, 0, 0.365079, 0.69985, 4.81251e-05, 0, 0.396825, 0.67783, 4.91811e-05, 0, 0.428571, 0.655126, 4.88199e-05, 0, 0.460318, 0.632697, 4.96025e-05, 0, 0.492064, 0.609613, 4.8829e-05, 0, 0.52381, 0.587098, 4.92754e-05, 0, 0.555556, 0.564119, 4.82625e-05, 0, 0.587302, 0.541813, 4.82807e-05, 0, 0.619048, 0.519342, 4.71552e-05, 0, 0.650794, 0.497514, 4.66765e-05, 0, 0.68254, 0.475879, 4.55582e-05, 0, 0.714286, 0.454789, 4.46007e-05, 0, 0.746032, 0.434217, 4.35382e-05, 0, 0.777778, 0.414086, 4.21753e-05, 0, 0.809524, 0.394744, 4.12093e-05, 0, 0.84127, 0.375782, 3.96634e-05, 0, 0.873016, 0.357707, 3.86419e-05, 0, 0.904762, 0.340038, 3.70345e-05, 0, 0.936508, 0.323284, 3.59725e-05, 0, 0.968254, 0.306954, 3.436e-05, 0, 1, 1, 5.99567e-14, 0, 0, 1, 6.00497e-14, 0, 0, 1, 6.14839e-14, 0, 0, 1, 6.86641e-14, 0, 0, 1, 9.72658e-14, 0, 0, 1, 2.21271e-13, 0, 0, 1, 8.33195e-13, 0, 0, 1, 4.03601e-12, 0, 0, 0.999999, 2.06001e-11, 0, 0, 0.999998, 1.01739e-10, 0, 0, 0.999997, 4.70132e-10, 0, 0, 0.999993, 2.00436e-09, 0, 0, 0.999988, 7.83682e-09, 0, 0, 0.999979, 2.80338e-08, 0, 0, 0.999962, 9.17033e-08, 0, 0, 0.999933, 2.74514e-07, 0, 0, 0.999881, 7.53201e-07, 0, 0, 0.999783, 1.89826e-06, 0, 0, 0.999594, 4.40279e-06, 0, 0, 0.999178, 9.3898e-06, 0, 0, 0.998073, 1.81265e-05, 0, 0, 0.993993, 2.80487e-05, 0, 0, 0.979982, 1.49422e-05, 0, 0, 0.968145, 3.78481e-06, 0, 0, 0.966786, 5.3771e-06, 0, 0, 0.965611, 9.47508e-06, 0, 3.88934e-05, 0.963557, 1.56616e-05, 0, 0.0009693, 0.959752, 2.35144e-05, 0, 0.00370329, 0.952461, 2.91568e-05, 0, 0.00868428, 0.940193, 2.40102e-05, 0, 0.0161889, 0.929042, 2.31235e-05, 0, 0.0263948, 0.920266, 2.73968e-05, 0, 0.0394088, 0.911178, 3.37915e-05, 0, 0.0552818, 0.897873, 3.33629e-05, 0, 0.0740138, 0.884053, 3.51405e-05, 0, 0.0955539, 0.869455, 3.78034e-05, 0, 0.119795, 0.854655, 3.99378e-05, 0, 0.14656, 0.838347, 4.19108e-05, 0, 0.175573, 0.820693, 4.40831e-05, 0, 0.206388, 0.802277, 4.45599e-05, 0, 0.238095, 0.783634, 4.72691e-05, 0, 0.269841, 0.763159, 4.76984e-05, 0, 0.301587, 0.742914, 4.91487e-05, 0, 0.333333, 0.721662, 5.02312e-05, 0, 0.365079, 0.699668, 5.02817e-05, 0, 0.396825, 0.677839, 5.1406e-05, 0, 0.428571, 0.655091, 5.11095e-05, 0, 0.460317, 0.632665, 5.16067e-05, 0, 0.492064, 0.609734, 5.12255e-05, 0, 0.52381, 0.587043, 5.10263e-05, 0, 0.555556, 0.564298, 5.0565e-05, 0, 0.587302, 0.541769, 4.97951e-05, 0, 0.619048, 0.519529, 4.92698e-05, 0, 0.650794, 0.497574, 4.82066e-05, 0, 0.68254, 0.476028, 4.73689e-05, 0, 0.714286, 0.454961, 4.61941e-05, 0, 0.746032, 0.434341, 4.50618e-05, 0, 0.777778, 0.414364, 4.38355e-05, 0, 0.809524, 0.394832, 4.24196e-05, 0, 0.84127, 0.376109, 4.12563e-05, 0, 0.873016, 0.35779, 3.96226e-05, 0, 0.904762, 0.340379, 3.84886e-05, 0, 0.936508, 0.323385, 3.68214e-05, 0, 0.968254, 0.307295, 3.56636e-05, 0, 1, 1, 1.06465e-12, 0, 0, 1, 1.06555e-12, 0, 0, 1, 1.07966e-12, 0, 0, 1, 1.14601e-12, 0, 0, 1, 1.37123e-12, 0, 0, 1, 2.1243e-12, 0, 0, 0.999999, 4.89653e-12, 0, 0, 0.999999, 1.60283e-11, 0, 0, 0.999998, 6.2269e-11, 0, 0, 0.999997, 2.51859e-10, 0, 0, 0.999996, 9.96192e-10, 0, 0, 0.999992, 3.74531e-09, 0, 0, 0.999986, 1.32022e-08, 0, 0, 0.999975, 4.33315e-08, 0, 0, 0.999959, 1.31956e-07, 0, 0, 0.999927, 3.72249e-07, 0, 0, 0.999871, 9.72461e-07, 0, 0, 0.999771, 2.35343e-06, 0, 0, 0.999572, 5.2768e-06, 0, 0, 0.999133, 1.09237e-05, 0, 0, 0.997912, 2.03675e-05, 0, 0, 0.993008, 2.79396e-05, 0, 0, 0.980645, 1.39604e-05, 0, 0, 0.970057, 6.46596e-06, 0, 0, 0.966717, 6.5089e-06, 0, 4.74145e-05, 0.965497, 1.11863e-05, 0, 0.00089544, 0.96334, 1.79857e-05, 0, 0.0032647, 0.959294, 2.59045e-05, 0, 0.0075144, 0.951519, 2.92327e-05, 0, 0.0138734, 0.940517, 2.49769e-05, 0, 0.0224952, 0.93014, 2.6803e-05, 0, 0.0334828, 0.91972, 3.03656e-05, 0, 0.0468973, 0.910294, 3.53323e-05, 0, 0.0627703, 0.897701, 3.51002e-05, 0, 0.0811019, 0.884522, 3.88104e-05, 0, 0.10186, 0.869489, 4.12932e-05, 0, 0.124985, 0.853983, 4.15781e-05, 0, 0.150372, 0.838425, 4.54066e-05, 0, 0.177868, 0.820656, 4.71624e-05, 0, 0.207245, 0.801875, 4.75243e-05, 0, 0.238143, 0.783521, 5.05621e-05, 0, 0.269841, 0.763131, 5.0721e-05, 0, 0.301587, 0.74261, 5.23293e-05, 0, 0.333333, 0.72148, 5.28699e-05, 0, 0.365079, 0.699696, 5.38677e-05, 0, 0.396825, 0.677592, 5.39255e-05, 0, 0.428571, 0.65525, 5.46367e-05, 0, 0.460317, 0.632452, 5.41348e-05, 0, 0.492064, 0.609903, 5.44976e-05, 0, 0.52381, 0.586928, 5.36201e-05, 0, 0.555556, 0.564464, 5.35185e-05, 0, 0.587302, 0.541801, 5.24949e-05, 0, 0.619048, 0.519681, 5.1812e-05, 0, 0.650794, 0.497685, 5.07687e-05, 0, 0.68254, 0.47622, 4.96243e-05, 0, 0.714286, 0.455135, 4.85714e-05, 0, 0.746032, 0.4346, 4.71847e-05, 0, 0.777778, 0.414564, 4.59294e-05, 0, 0.809524, 0.395165, 4.44705e-05, 0, 0.84127, 0.376333, 4.30772e-05, 0, 0.873016, 0.358197, 4.16229e-05, 0, 0.904762, 0.34064, 4.01019e-05, 0, 0.936508, 0.323816, 3.86623e-05, 0, 0.968254, 0.307581, 3.70933e-05, 0, 1, 1, 9.91541e-12, 0, 0, 1, 9.92077e-12, 0, 0, 1, 1.00041e-11, 0, 0, 1, 1.0385e-11, 0, 0, 1, 1.15777e-11, 0, 0, 1, 1.50215e-11, 0, 0, 0.999999, 2.54738e-11, 0, 0, 0.999999, 5.98822e-11, 0, 0, 0.999998, 1.79597e-10, 0, 0, 0.999997, 6.02367e-10, 0, 0, 0.999994, 2.06835e-09, 0, 0, 0.99999, 6.94952e-09, 0, 0, 0.999984, 2.23363e-08, 0, 0, 0.999972, 6.78578e-08, 0, 0, 0.999952, 1.93571e-07, 0, 0, 0.999919, 5.16594e-07, 0, 0, 0.99986, 1.28739e-06, 0, 0, 0.999753, 2.99298e-06, 0, 0, 0.999546, 6.48258e-06, 0, 0, 0.999074, 1.29985e-05, 0, 0, 0.997671, 2.32176e-05, 0, 0, 0.991504, 2.56701e-05, 0, 0, 0.981148, 1.31141e-05, 0, 0, 0.971965, 8.69048e-06, 0, 2.80182e-05, 0.966624, 8.08301e-06, 0, 0.000695475, 0.965344, 1.35235e-05, 0, 0.00265522, 0.963048, 2.10592e-05, 0, 0.00622975, 0.958673, 2.87473e-05, 0, 0.0116234, 0.950262, 2.81379e-05, 0, 0.018976, 0.940836, 2.71089e-05, 0, 0.0283844, 0.930996, 3.0926e-05, 0, 0.0399151, 0.919848, 3.48359e-05, 0, 0.0536063, 0.909136, 3.66092e-05, 0, 0.0694793, 0.897554, 3.84162e-05, 0, 0.0875342, 0.884691, 4.30971e-05, 0, 0.107749, 0.869414, 4.47803e-05, 0, 0.130087, 0.853462, 4.52858e-05, 0, 0.154481, 0.838187, 4.95769e-05, 0, 0.180833, 0.820381, 5.02709e-05, 0, 0.209005, 0.801844, 5.22713e-05, 0, 0.238791, 0.783061, 5.41505e-05, 0, 0.269869, 0.763205, 5.53712e-05, 0, 0.301587, 0.742362, 5.64909e-05, 0, 0.333333, 0.721393, 5.72646e-05, 0, 0.365079, 0.699676, 5.81012e-05, 0, 0.396825, 0.677395, 5.8096e-05, 0, 0.428571, 0.655208, 5.85766e-05, 0, 0.460317, 0.632451, 5.83602e-05, 0, 0.492064, 0.609839, 5.80234e-05, 0, 0.52381, 0.587093, 5.77161e-05, 0, 0.555556, 0.564467, 5.68447e-05, 0, 0.587302, 0.542043, 5.63166e-05, 0, 0.619048, 0.519826, 5.5156e-05, 0, 0.650794, 0.497952, 5.41682e-05, 0, 0.68254, 0.476477, 5.28971e-05, 0, 0.714286, 0.455412, 5.14952e-05, 0, 0.746032, 0.434926, 5.02222e-05, 0, 0.777778, 0.4149, 4.85779e-05, 0, 0.809524, 0.395552, 4.72242e-05, 0, 0.84127, 0.376712, 4.54891e-05, 0, 0.873016, 0.358622, 4.40924e-05, 0, 0.904762, 0.341048, 4.22984e-05, 0, 0.936508, 0.324262, 4.08582e-05, 0, 0.968254, 0.308013, 3.90839e-05, 0, 1, 1, 6.13913e-11, 0, 0, 1, 6.14145e-11, 0, 0, 1, 6.17708e-11, 0, 0, 1, 6.33717e-11, 0, 0, 1, 6.81648e-11, 0, 0, 1, 8.08291e-11, 0, 0, 1, 1.14608e-10, 0, 0, 0.999998, 2.10507e-10, 0, 0, 0.999997, 4.99595e-10, 0, 0, 0.999995, 1.39897e-09, 0, 0, 0.999994, 4.19818e-09, 0, 0, 0.999988, 1.27042e-08, 0, 0, 0.999979, 3.75153e-08, 0, 0, 0.999965, 1.06206e-07, 0, 0, 0.999945, 2.85381e-07, 0, 0, 0.999908, 7.23611e-07, 0, 0, 0.999846, 1.7255e-06, 0, 0, 0.999733, 3.86104e-06, 0, 0, 0.999511, 8.08493e-06, 0, 0, 0.998993, 1.56884e-05, 0, 0, 0.997326, 2.65538e-05, 0, 0, 0.989706, 2.06466e-05, 0, 0, 0.981713, 1.30756e-05, 0, 7.0005e-06, 0.973636, 1.06473e-05, 0, 0.000464797, 0.966509, 1.0194e-05, 0, 0.00201743, 0.965149, 1.65881e-05, 0, 0.00497549, 0.962669, 2.49147e-05, 0, 0.00953262, 0.95786, 3.17449e-05, 0, 0.0158211, 0.949334, 2.81045e-05, 0, 0.0239343, 0.941041, 3.03263e-05, 0, 0.0339372, 0.931575, 3.56754e-05, 0, 0.0458738, 0.920102, 3.97075e-05, 0, 0.059772, 0.908002, 3.84886e-05, 0, 0.075645, 0.897269, 4.3027e-05, 0, 0.0934929, 0.884559, 4.79925e-05, 0, 0.113302, 0.869161, 4.8246e-05, 0, 0.135045, 0.853342, 5.09505e-05, 0, 0.158678, 0.837633, 5.42846e-05, 0, 0.184136, 0.820252, 5.54139e-05, 0, 0.211325, 0.801872, 5.81412e-05, 0, 0.240113, 0.782418, 5.85535e-05, 0, 0.270306, 0.7631, 6.10923e-05, 0, 0.301594, 0.742183, 6.13678e-05, 0, 0.333333, 0.721098, 6.27275e-05, 0, 0.365079, 0.699512, 6.29413e-05, 0, 0.396825, 0.677372, 6.36351e-05, 0, 0.428571, 0.655059, 6.33555e-05, 0, 0.460317, 0.632567, 6.36513e-05, 0, 0.492064, 0.609784, 6.28965e-05, 0, 0.52381, 0.587237, 6.25546e-05, 0, 0.555556, 0.564525, 6.15825e-05, 0, 0.587302, 0.542181, 6.05048e-05, 0, 0.619048, 0.520017, 5.96329e-05, 0, 0.650794, 0.498204, 5.81516e-05, 0, 0.68254, 0.476742, 5.69186e-05, 0, 0.714286, 0.455803, 5.53833e-05, 0, 0.746032, 0.435251, 5.37807e-05, 0, 0.777778, 0.415374, 5.22025e-05, 0, 0.809524, 0.395921, 5.03421e-05, 0, 0.84127, 0.377253, 4.88211e-05, 0, 0.873016, 0.359021, 4.68234e-05, 0, 0.904762, 0.341637, 4.53269e-05, 0, 0.936508, 0.3247, 4.33014e-05, 0, 0.968254, 0.308625, 4.18007e-05, 0, 1, 1, 2.86798e-10, 0, 0, 1, 2.86877e-10, 0, 0, 1, 2.88094e-10, 0, 0, 1, 2.93506e-10, 0, 0, 1, 3.09262e-10, 0, 0, 0.999999, 3.48593e-10, 0, 0, 0.999999, 4.44582e-10, 0, 0, 0.999998, 6.88591e-10, 0, 0, 0.999996, 1.34391e-09, 0, 0, 0.999993, 3.17438e-09, 0, 0, 0.999989, 8.35609e-09, 0, 0, 0.999983, 2.28677e-08, 0, 0, 0.999974, 6.23361e-08, 0, 0, 0.999959, 1.65225e-07, 0, 0, 0.999936, 4.19983e-07, 0, 0, 0.999896, 1.01546e-06, 0, 0, 0.99983, 2.32376e-06, 0, 0, 0.999709, 5.0156e-06, 0, 0, 0.999469, 1.0167e-05, 0, 0, 0.998886, 1.90775e-05, 0, 0, 0.996819, 3.00511e-05, 0, 0, 0.988837, 1.85092e-05, 0, 1.68222e-07, 0.982178, 1.34622e-05, 0, 0.000259622, 0.975017, 1.25961e-05, 0, 0.00142595, 0.967101, 1.3507e-05, 0, 0.00382273, 0.964905, 2.05003e-05, 0, 0.00764164, 0.96218, 2.9546e-05, 0, 0.0130121, 0.956821, 3.43738e-05, 0, 0.0200253, 0.948829, 3.05063e-05, 0, 0.0287452, 0.941092, 3.46487e-05, 0, 0.039218, 0.931883, 4.12061e-05, 0, 0.0514748, 0.920211, 4.44651e-05, 0, 0.0655351, 0.907307, 4.31252e-05, 0, 0.0814082, 0.89684, 4.90382e-05, 0, 0.0990939, 0.884119, 5.3334e-05, 0, 0.118583, 0.869148, 5.4114e-05, 0, 0.139856, 0.853377, 5.78536e-05, 0, 0.162882, 0.836753, 5.92285e-05, 0, 0.187615, 0.820063, 6.22787e-05, 0, 0.213991, 0.801694, 6.45492e-05, 0, 0.241918, 0.782116, 6.5353e-05, 0, 0.271267, 0.762673, 6.74344e-05, 0, 0.301847, 0.742133, 6.82788e-05, 0, 0.333333, 0.720779, 6.91959e-05, 0, 0.365079, 0.699386, 6.96817e-05, 0, 0.396826, 0.67732, 6.99583e-05, 0, 0.428572, 0.654888, 6.98447e-05, 0, 0.460318, 0.632499, 6.94063e-05, 0, 0.492064, 0.609825, 6.91612e-05, 0, 0.52381, 0.587287, 6.81576e-05, 0, 0.555556, 0.564743, 6.74138e-05, 0, 0.587302, 0.542409, 6.61617e-05, 0, 0.619048, 0.520282, 6.47785e-05, 0, 0.650794, 0.498506, 6.33836e-05, 0, 0.68254, 0.477102, 6.15905e-05, 0, 0.714286, 0.456167, 6.01013e-05, 0, 0.746032, 0.435728, 5.81457e-05, 0, 0.777778, 0.415809, 5.64215e-05, 0, 0.809524, 0.396517, 5.44997e-05, 0, 0.84127, 0.377737, 5.25061e-05, 0, 0.873016, 0.359698, 5.06831e-05, 0, 0.904762, 0.342164, 4.8568e-05, 0, 0.936508, 0.325417, 4.67826e-05, 0, 0.968254, 0.309186, 4.46736e-05, 0, 1, 1, 1.09018e-09, 0, 0, 1, 1.0904e-09, 0, 0, 1, 1.09393e-09, 0, 0, 1, 1.1095e-09, 0, 0, 1, 1.154e-09, 0, 0, 1, 1.26089e-09, 0, 0, 0.999999, 1.5059e-09, 0, 0, 0.999997, 2.07899e-09, 0, 0, 0.999994, 3.48164e-09, 0, 0, 0.999993, 7.05728e-09, 0, 0, 0.999987, 1.63692e-08, 0, 0, 0.999981, 4.06033e-08, 0, 0, 0.999969, 1.0245e-07, 0, 0, 0.999953, 2.55023e-07, 0, 0, 0.999925, 6.1511e-07, 0, 0, 0.999881, 1.42218e-06, 0, 0, 0.99981, 3.13086e-06, 0, 0, 0.99968, 6.53119e-06, 0, 0, 0.999418, 1.2832e-05, 0, 0, 0.998748, 2.32497e-05, 0, 0, 0.996066, 3.29522e-05, 0, 0, 0.988379, 1.79613e-05, 0, 0.000108799, 0.982567, 1.43715e-05, 0, 0.000921302, 0.976097, 1.48096e-05, 0, 0.00280738, 0.968475, 1.78905e-05, 0, 0.00596622, 0.964606, 2.53921e-05, 0, 0.0105284, 0.961564, 3.48623e-05, 0, 0.0165848, 0.955517, 3.57612e-05, 0, 0.0242, 0.948381, 3.43493e-05, 0, 0.03342, 0.941095, 4.05849e-05, 0, 0.0442777, 0.931923, 4.75394e-05, 0, 0.0567958, 0.91996, 4.84328e-05, 0, 0.0709879, 0.907419, 5.02146e-05, 0, 0.086861, 0.89618, 5.61654e-05, 0, 0.104415, 0.88337, 5.87612e-05, 0, 0.123643, 0.869046, 6.18057e-05, 0, 0.144531, 0.853278, 6.57392e-05, 0, 0.167057, 0.836091, 6.6303e-05, 0, 0.191188, 0.819644, 7.04445e-05, 0, 0.216878, 0.801246, 7.14071e-05, 0, 0.244062, 0.782031, 7.40093e-05, 0, 0.272649, 0.762066, 7.4685e-05, 0, 0.302509, 0.741964, 7.66647e-05, 0, 0.333442, 0.720554, 7.66328e-05, 0, 0.365079, 0.699098, 7.77857e-05, 0, 0.396826, 0.677189, 7.74633e-05, 0, 0.428572, 0.65484, 7.76235e-05, 0, 0.460318, 0.632496, 7.70316e-05, 0, 0.492064, 0.609908, 7.62669e-05, 0, 0.52381, 0.587312, 7.53972e-05, 0, 0.555556, 0.564938, 7.39994e-05, 0, 0.587302, 0.542577, 7.28382e-05, 0, 0.619048, 0.52062, 7.1112e-05, 0, 0.650794, 0.498819, 6.94004e-05, 0, 0.68254, 0.477555, 6.75575e-05, 0, 0.714286, 0.456568, 6.53449e-05, 0, 0.746032, 0.436278, 6.36068e-05, 0, 0.777778, 0.41637, 6.13466e-05, 0, 0.809524, 0.397144, 5.94177e-05, 0, 0.84127, 0.378412, 5.70987e-05, 0, 0.873016, 0.360376, 5.50419e-05, 0, 0.904762, 0.342906, 5.27422e-05, 0, 0.936508, 0.326136, 5.06544e-05, 0, 0.968254, 0.30997, 4.84307e-05, 0, 1, 1, 3.54014e-09, 0, 0, 1, 3.54073e-09, 0, 0, 1, 3.54972e-09, 0, 0, 1, 3.58929e-09, 0, 0, 1, 3.70093e-09, 0, 0, 0.999999, 3.96194e-09, 0, 0, 0.999998, 4.53352e-09, 0, 0, 0.999997, 5.78828e-09, 0, 0, 0.999994, 8.63812e-09, 0, 0, 0.999991, 1.53622e-08, 0, 0, 0.999985, 3.16356e-08, 0, 0, 0.999977, 7.12781e-08, 0, 0, 0.999964, 1.66725e-07, 0, 0, 0.999945, 3.90501e-07, 0, 0, 0.999912, 8.95622e-07, 0, 0, 0.999866, 1.98428e-06, 0, 0, 0.999786, 4.21038e-06, 0, 0, 0.999647, 8.50239e-06, 0, 0, 0.999356, 1.62059e-05, 0, 0, 0.998563, 2.82652e-05, 0, 0, 0.994928, 3.36309e-05, 0, 2.44244e-05, 0.987999, 1.78458e-05, 0, 0.000523891, 0.982893, 1.59162e-05, 0, 0.00194729, 0.977044, 1.78056e-05, 0, 0.00451099, 0.969972, 2.30624e-05, 0, 0.00835132, 0.964237, 3.13922e-05, 0, 0.013561, 0.960791, 4.06145e-05, 0, 0.0202056, 0.954292, 3.72796e-05, 0, 0.0283321, 0.948052, 4.03199e-05, 0, 0.0379739, 0.940938, 4.79537e-05, 0, 0.0491551, 0.931689, 5.45292e-05, 0, 0.0618918, 0.91987, 5.4038e-05, 0, 0.0761941, 0.907665, 5.89909e-05, 0, 0.0920672, 0.895281, 6.42651e-05, 0, 0.109511, 0.882621, 6.59707e-05, 0, 0.12852, 0.86873, 7.09973e-05, 0, 0.149085, 0.853008, 7.42221e-05, 0, 0.171189, 0.835944, 7.61754e-05, 0, 0.194809, 0.818949, 7.97052e-05, 0, 0.21991, 0.800951, 8.12434e-05, 0, 0.246447, 0.781847, 8.38075e-05, 0, 0.274352, 0.761649, 8.4501e-05, 0, 0.303535, 0.74152, 8.60258e-05, 0, 0.333857, 0.720495, 8.66233e-05, 0, 0.365104, 0.698742, 8.68326e-05, 0, 0.396826, 0.677096, 8.7133e-05, 0, 0.428572, 0.654782, 8.63497e-05, 0, 0.460318, 0.632335, 8.60206e-05, 0, 0.492064, 0.610031, 8.49337e-05, 0, 0.52381, 0.587457, 8.38279e-05, 0, 0.555556, 0.56513, 8.2309e-05, 0, 0.587302, 0.542877, 8.03542e-05, 0, 0.619048, 0.5209, 7.86928e-05, 0, 0.650794, 0.499291, 7.65171e-05, 0, 0.68254, 0.477971, 7.44753e-05, 0, 0.714286, 0.457221, 7.2209e-05, 0, 0.746032, 0.436803, 6.97448e-05, 0, 0.777778, 0.417083, 6.75333e-05, 0, 0.809524, 0.397749, 6.48058e-05, 0, 0.84127, 0.379177, 6.25759e-05, 0, 0.873016, 0.361061, 5.98584e-05, 0, 0.904762, 0.343713, 5.75797e-05, 0, 0.936508, 0.326894, 5.49999e-05, 0, 0.968254, 0.310816, 5.27482e-05, 0, 1, 1, 1.0153e-08, 0, 0, 1, 1.01544e-08, 0, 0, 1, 1.01751e-08, 0, 0, 1, 1.02662e-08, 0, 0, 1, 1.0521e-08, 0, 0, 0.999999, 1.11049e-08, 0, 0, 0.999999, 1.23408e-08, 0, 0, 0.999996, 1.4924e-08, 0, 0, 0.999992, 2.04471e-08, 0, 0, 0.999989, 3.26539e-08, 0, 0, 0.99998, 6.03559e-08, 0, 0, 0.999971, 1.23936e-07, 0, 0, 0.999955, 2.69058e-07, 0, 0, 0.999933, 5.93604e-07, 0, 0, 0.999901, 1.29633e-06, 0, 0, 0.999847, 2.75621e-06, 0, 0, 0.999761, 5.64494e-06, 0, 0, 0.999607, 1.10485e-05, 0, 0, 0.999282, 2.04388e-05, 0, 0, 0.99831, 3.41084e-05, 0, 2.2038e-07, 0.993288, 2.94949e-05, 0, 0.000242388, 0.987855, 1.92736e-05, 0, 0.0012503, 0.983167, 1.82383e-05, 0, 0.0032745, 0.977908, 2.18633e-05, 0, 0.00646321, 0.971194, 2.90662e-05, 0, 0.0109133, 0.963867, 3.86401e-05, 0, 0.0166927, 0.95982, 4.62827e-05, 0, 0.0238494, 0.953497, 4.20705e-05, 0, 0.0324178, 0.947621, 4.77743e-05, 0, 0.0424225, 0.940611, 5.68258e-05, 0, 0.0538808, 0.931174, 6.18061e-05, 0, 0.0668047, 0.919919, 6.27098e-05, 0, 0.0812014, 0.907856, 6.94714e-05, 0, 0.0970745, 0.894509, 7.35008e-05, 0, 0.114424, 0.881954, 7.63369e-05, 0, 0.133246, 0.868309, 8.21896e-05, 0, 0.153534, 0.852511, 8.3769e-05, 0, 0.175275, 0.835821, 8.81615e-05, 0, 0.198453, 0.817981, 8.96368e-05, 0, 0.223042, 0.800504, 9.30906e-05, 0, 0.249009, 0.78141, 9.45056e-05, 0, 0.276304, 0.761427, 9.63605e-05, 0, 0.304862, 0.74094, 9.68088e-05, 0, 0.334584, 0.720233, 9.81481e-05, 0, 0.365322, 0.698592, 9.79122e-05, 0, 0.396826, 0.676763, 9.81057e-05, 0, 0.428571, 0.654808, 9.73956e-05, 0, 0.460318, 0.632326, 9.62619e-05, 0, 0.492064, 0.610049, 9.52996e-05, 0, 0.52381, 0.58763, 9.33334e-05, 0, 0.555556, 0.565261, 9.17573e-05, 0, 0.587302, 0.543244, 8.96636e-05, 0, 0.619048, 0.521273, 8.73304e-05, 0, 0.650794, 0.499818, 8.52648e-05, 0, 0.68254, 0.478536, 8.23961e-05, 0, 0.714286, 0.457826, 7.9939e-05, 0, 0.746032, 0.437549, 7.7126e-05, 0, 0.777778, 0.41776, 7.43043e-05, 0, 0.809524, 0.39863, 7.16426e-05, 0, 0.84127, 0.379954, 6.86456e-05, 0, 0.873016, 0.362025, 6.60514e-05, 0, 0.904762, 0.344581, 6.30755e-05, 0, 0.936508, 0.327909, 6.05439e-05, 0, 0.968254, 0.311736, 5.76345e-05, 0, 1, 1, 2.63344e-08, 0, 0, 1, 2.63373e-08, 0, 0, 1, 2.63815e-08, 0, 0, 1, 2.65753e-08, 0, 0, 1, 2.71132e-08, 0, 0, 0.999999, 2.83279e-08, 0, 0, 0.999997, 3.0833e-08, 0, 0, 0.999995, 3.58711e-08, 0, 0, 0.999992, 4.61266e-08, 0, 0, 0.999985, 6.7574e-08, 0, 0, 0.999977, 1.1358e-07, 0, 0, 0.999966, 2.13657e-07, 0, 0, 0.999948, 4.31151e-07, 0, 0, 0.999923, 8.96656e-07, 0, 0, 0.999884, 1.86603e-06, 0, 0, 0.999826, 3.81115e-06, 0, 0, 0.999732, 7.54184e-06, 0, 0, 0.999561, 1.43192e-05, 0, 0, 0.999191, 2.57061e-05, 0, 0, 0.997955, 4.05724e-05, 0, 7.44132e-05, 0.992228, 2.76537e-05, 0, 0.000716477, 0.987638, 2.08885e-05, 0, 0.0022524, 0.983395, 2.15226e-05, 0, 0.00484816, 0.978614, 2.70795e-05, 0, 0.00860962, 0.972389, 3.65282e-05, 0, 0.0136083, 0.964392, 4.74747e-05, 0, 0.0198941, 0.95861, 5.09141e-05, 0, 0.0275023, 0.952806, 4.8963e-05, 0, 0.0364584, 0.94712, 5.71119e-05, 0, 0.04678, 0.940104, 6.71704e-05, 0, 0.0584799, 0.930398, 6.87586e-05, 0, 0.0715665, 0.919866, 7.38161e-05, 0, 0.086045, 0.907853, 8.13235e-05, 0, 0.101918, 0.894078, 8.34582e-05, 0, 0.119186, 0.881177, 8.92093e-05, 0, 0.137845, 0.867575, 9.44548e-05, 0, 0.157891, 0.852107, 9.69607e-05, 0, 0.179316, 0.835502, 0.000101456, 0, 0.202106, 0.81756, 0.000103256, 0, 0.226243, 0.79984, 0.000106954, 0, 0.251704, 0.780998, 0.000108066, 0, 0.278451, 0.761132, 0.000110111, 0, 0.306436, 0.740429, 0.000110459, 0, 0.335586, 0.719836, 0.000111219, 0, 0.365796, 0.698467, 0.00011145, 0, 0.3969, 0.676446, 0.000110393, 0, 0.428571, 0.654635, 0.000110035, 0, 0.460318, 0.632411, 0.000108548, 0, 0.492064, 0.609986, 0.000106963, 0, 0.52381, 0.587872, 0.000105238, 0, 0.555556, 0.565528, 0.000102665, 0, 0.587302, 0.543563, 0.000100543, 0, 0.619048, 0.52176, 9.76182e-05, 0, 0.650794, 0.500188, 9.47099e-05, 0, 0.68254, 0.479204, 9.19929e-05, 0, 0.714286, 0.458413, 8.86139e-05, 0, 0.746032, 0.438314, 8.57839e-05, 0, 0.777778, 0.418573, 8.2411e-05, 0, 0.809524, 0.39947, 7.92211e-05, 0, 0.84127, 0.380892, 7.59546e-05, 0, 0.873016, 0.362953, 7.27571e-05, 0, 0.904762, 0.345601, 6.95738e-05, 0, 0.936508, 0.328895, 6.64907e-05, 0, 0.968254, 0.312808, 6.34277e-05, 0, 1, 1, 6.28647e-08, 0, 0, 1, 6.28705e-08, 0, 0, 1, 6.29587e-08, 0, 0, 1, 6.33441e-08, 0, 0, 0.999999, 6.44087e-08, 0, 0, 0.999998, 6.67856e-08, 0, 0, 0.999997, 7.15889e-08, 0, 0, 0.999995, 8.09577e-08, 0, 0, 0.999989, 9.92764e-08, 0, 0, 0.999983, 1.35834e-07, 0, 0, 0.999974, 2.10482e-07, 0, 0, 0.999959, 3.65215e-07, 0, 0, 0.999939, 6.86693e-07, 0, 0, 0.999911, 1.3472e-06, 0, 0, 0.999868, 2.6731e-06, 0, 0, 0.999804, 5.24756e-06, 0, 0, 0.9997, 1.00403e-05, 0, 0, 0.99951, 1.85019e-05, 0, 0, 0.999078, 3.22036e-05, 0, 6.20676e-06, 0.997428, 4.70002e-05, 0, 0.000341552, 0.99162, 2.87123e-05, 0, 0.00143727, 0.987479, 2.34706e-05, 0, 0.00349201, 0.983582, 2.60083e-05, 0, 0.0066242, 0.979186, 3.37927e-05, 0, 0.0109113, 0.97325, 4.54689e-05, 0, 0.0164064, 0.965221, 5.73759e-05, 0, 0.0231463, 0.957262, 5.44114e-05, 0, 0.0311571, 0.952211, 5.87006e-05, 0, 0.0404572, 0.946631, 6.92256e-05, 0, 0.0510592, 0.939391, 7.87819e-05, 0, 0.0629723, 0.929795, 7.92368e-05, 0, 0.0762025, 0.91965, 8.75075e-05, 0, 0.090753, 0.907737, 9.50903e-05, 0, 0.106626, 0.893899, 9.72963e-05, 0, 0.123822, 0.880239, 0.00010459, 0, 0.142337, 0.866562, 0.000107689, 0, 0.16217, 0.85164, 0.000113081, 0, 0.183314, 0.835021, 0.000116636, 0, 0.20576, 0.817311, 0.000120074, 0, 0.229496, 0.798845, 0.000121921, 0, 0.254502, 0.780479, 0.00012475, 0, 0.280753, 0.760694, 0.000125255, 0, 0.308212, 0.740142, 0.000126719, 0, 0.336825, 0.719248, 0.00012636, 0, 0.366517, 0.698209, 0.000126712, 0, 0.397167, 0.676398, 0.000125769, 0, 0.428578, 0.654378, 0.000124432, 0, 0.460318, 0.632484, 0.000123272, 0, 0.492064, 0.610113, 0.00012085, 0, 0.52381, 0.587931, 0.000118411, 0, 0.555556, 0.565872, 0.00011569, 0, 0.587302, 0.543814, 0.000112521, 0, 0.619048, 0.522265, 0.000109737, 0, 0.650794, 0.500835, 0.000106228, 0, 0.68254, 0.479818, 0.000102591, 0, 0.714286, 0.459258, 9.91288e-05, 0, 0.746032, 0.439061, 9.52325e-05, 0, 0.777778, 0.419552, 9.1895e-05, 0, 0.809524, 0.400399, 8.79051e-05, 0, 0.84127, 0.381976, 8.44775e-05, 0, 0.873016, 0.364009, 8.06316e-05, 0, 0.904762, 0.346761, 7.71848e-05, 0, 0.936508, 0.330049, 7.35429e-05, 0, 0.968254, 0.314018, 7.02103e-05, 0, 1, 1, 1.39968e-07, 0, 0, 1, 1.39979e-07, 0, 0, 1, 1.40145e-07, 0, 0, 1, 1.4087e-07, 0, 0, 0.999999, 1.42865e-07, 0, 0, 0.999998, 1.47279e-07, 0, 0, 0.999997, 1.56057e-07, 0, 0, 0.999992, 1.7276e-07, 0, 0, 0.999989, 2.04352e-07, 0, 0, 0.99998, 2.6494e-07, 0, 0, 0.999969, 3.83435e-07, 0, 0, 0.999953, 6.18641e-07, 0, 0, 0.999929, 1.08755e-06, 0, 0, 0.999898, 2.01497e-06, 0, 0, 0.999849, 3.81346e-06, 0, 0, 0.999778, 7.19815e-06, 0, 0, 0.999661, 1.33215e-05, 0, 0, 0.999451, 2.38313e-05, 0, 0, 0.998936, 4.01343e-05, 0, 0.000113724, 0.99662, 5.17346e-05, 0, 0.000820171, 0.991094, 3.04323e-05, 0, 0.00238143, 0.987487, 2.81757e-05, 0, 0.00493527, 0.983731, 3.20048e-05, 0, 0.00856859, 0.979647, 4.23905e-05, 0, 0.0133393, 0.973837, 5.62935e-05, 0, 0.0192863, 0.96584, 6.77442e-05, 0, 0.0264369, 0.956309, 6.23073e-05, 0, 0.03481, 0.951523, 7.04131e-05, 0, 0.0444184, 0.946003, 8.36594e-05, 0, 0.0552713, 0.938454, 9.11736e-05, 0, 0.0673749, 0.929279, 9.38264e-05, 0, 0.0807329, 0.919239, 0.000103754, 0, 0.0953479, 0.907293, 0.000109928, 0, 0.111221, 0.893936, 0.000115257, 0, 0.128352, 0.879674, 0.000122265, 0, 0.14674, 0.865668, 0.000125733, 0, 0.166382, 0.850998, 0.000132305, 0, 0.187276, 0.834498, 0.000134844, 0, 0.209413, 0.816903, 0.000139276, 0, 0.232786, 0.798235, 0.000140984, 0, 0.257382, 0.779724, 0.00014378, 0, 0.283181, 0.760251, 0.000144623, 0, 0.310156, 0.739808, 0.000145228, 0, 0.338269, 0.718762, 0.00014539, 0, 0.367461, 0.697815, 0.000144432, 0, 0.397646, 0.67631, 0.000143893, 0, 0.428685, 0.654278, 0.000141846, 0, 0.460318, 0.632347, 0.00013935, 0, 0.492064, 0.610296, 0.000137138, 0, 0.52381, 0.588039, 0.000133806, 0, 0.555556, 0.566218, 0.000130755, 0, 0.587302, 0.544346, 0.000127128, 0, 0.619048, 0.522701, 0.000123002, 0, 0.650794, 0.501542, 0.000119443, 0, 0.68254, 0.480508, 0.000115055, 0, 0.714286, 0.460092, 0.000111032, 0, 0.746032, 0.440021, 0.000106635, 0, 0.777778, 0.420446, 0.000102162, 0, 0.809524, 0.401512, 9.8184e-05, 0, 0.84127, 0.38299, 9.36497e-05, 0, 0.873016, 0.365232, 8.9813e-05, 0, 0.904762, 0.347865, 8.53073e-05, 0, 0.936508, 0.331342, 8.17068e-05, 0, 0.968254, 0.315202, 7.73818e-05, 0, 1, 1, 2.9368e-07, 0, 0, 1, 2.937e-07, 0, 0, 1, 2.93998e-07, 0, 0, 1, 2.95298e-07, 0, 0, 0.999999, 2.98865e-07, 0, 0, 0.999998, 3.067e-07, 0, 0, 0.999995, 3.22082e-07, 0, 0, 0.999992, 3.50767e-07, 0, 0, 0.999986, 4.03538e-07, 0, 0, 0.999976, 5.01372e-07, 0, 0, 0.999964, 6.8562e-07, 0, 0, 0.999945, 1.0374e-06, 0, 0, 0.999919, 1.71269e-06, 0, 0, 0.999882, 3.00175e-06, 0, 0, 0.999829, 5.42144e-06, 0, 0, 0.999749, 9.84182e-06, 0, 0, 0.99962, 1.76213e-05, 0, 0, 0.999382, 3.05995e-05, 0, 1.38418e-05, 0.998751, 4.96686e-05, 0, 0.000389844, 0.995344, 5.10733e-05, 0, 0.00150343, 0.990768, 3.45829e-05, 0, 0.00352451, 0.987464, 3.42841e-05, 0, 0.00655379, 0.983846, 3.99072e-05, 0, 0.0106554, 0.980007, 5.33219e-05, 0, 0.0158723, 0.974494, 6.96992e-05, 0, 0.0222333, 0.96622, 7.76754e-05, 0, 0.029758, 0.956273, 7.47718e-05, 0, 0.0384596, 0.950952, 8.64611e-05, 0, 0.0483473, 0.945215, 0.000100464, 0, 0.0594266, 0.937287, 0.000103729, 0, 0.0717019, 0.928649, 0.000111665, 0, 0.0851752, 0.918791, 0.00012353, 0, 0.0998479, 0.906685, 0.000127115, 0, 0.115721, 0.893706, 0.00013628, 0, 0.132794, 0.879248, 0.000142427, 0, 0.151067, 0.864685, 0.000148091, 0, 0.170538, 0.850032, 0.000153517, 0, 0.191204, 0.833853, 0.000157322, 0, 0.213063, 0.816353, 0.000161086, 0, 0.236107, 0.797834, 0.000164111, 0, 0.260329, 0.778831, 0.000165446, 0, 0.285714, 0.759756, 0.000167492, 0, 0.312243, 0.739419, 0.000166928, 0, 0.339887, 0.718491, 0.000167, 0, 0.368604, 0.697392, 0.000165674, 0, 0.398329, 0.676102, 0.000163815, 0, 0.428961, 0.654243, 0.000162003, 0, 0.460331, 0.632176, 0.000158831, 0, 0.492064, 0.610407, 0.000155463, 0, 0.52381, 0.588394, 0.000152062, 0, 0.555556, 0.56645, 0.000147665, 0, 0.587302, 0.5449, 0.00014375, 0, 0.619048, 0.523276, 0.000138905, 0, 0.650794, 0.502179, 0.000134189, 0, 0.68254, 0.481359, 0.000129392, 0, 0.714286, 0.46092, 0.000124556, 0, 0.746032, 0.441084, 0.00011957, 0, 0.777778, 0.421517, 0.000114652, 0, 0.809524, 0.402721, 0.000109688, 0, 0.84127, 0.384222, 0.000104667, 0, 0.873016, 0.366534, 9.99633e-05, 0, 0.904762, 0.349205, 9.50177e-05, 0, 0.936508, 0.332702, 9.07301e-05, 0, 0.968254, 0.316599, 8.59769e-05, 0, 1, 1, 5.85473e-07, 0, 0, 1, 5.85507e-07, 0, 0, 1, 5.8602e-07, 0, 0, 0.999999, 5.88259e-07, 0, 0, 0.999999, 5.94381e-07, 0, 0, 0.999998, 6.07754e-07, 0, 0, 0.999995, 6.33729e-07, 0, 0, 0.99999, 6.8137e-07, 0, 0, 0.999984, 7.67003e-07, 0, 0, 0.999973, 9.21212e-07, 0, 0, 0.999959, 1.20218e-06, 0, 0, 0.999936, 1.72024e-06, 0, 0, 0.999907, 2.68088e-06, 0, 0, 0.999866, 4.45512e-06, 0, 0, 0.999806, 7.68481e-06, 0, 0, 0.999716, 1.342e-05, 0, 0, 0.999576, 2.32473e-05, 0, 0, 0.9993, 3.91694e-05, 0, 0.000129917, 0.998498, 6.08429e-05, 0, 0.000845035, 0.994132, 4.89743e-05, 0, 0.00237616, 0.99031, 3.84644e-05, 0, 0.00484456, 0.987409, 4.21768e-05, 0, 0.00832472, 0.983981, 5.04854e-05, 0, 0.0128643, 0.980268, 6.71028e-05, 0, 0.0184947, 0.974875, 8.52749e-05, 0, 0.025237, 0.966063, 8.5531e-05, 0, 0.0331046, 0.956779, 9.00588e-05, 0, 0.0421067, 0.950259, 0.00010577, 0, 0.0522487, 0.944239, 0.000119458, 0, 0.0635343, 0.936341, 0.000122164, 0, 0.0759654, 0.928047, 0.000134929, 0, 0.0895434, 0.918065, 0.000145544, 0, 0.104269, 0.906267, 0.000150531, 0, 0.120142, 0.893419, 0.000161652, 0, 0.137163, 0.878758, 0.00016593, 0, 0.15533, 0.863699, 0.000174014, 0, 0.174645, 0.848876, 0.000177877, 0, 0.195106, 0.833032, 0.000184049, 0, 0.21671, 0.815557, 0.000186088, 0, 0.239454, 0.797323, 0.00019054, 0, 0.263332, 0.778124, 0.000191765, 0, 0.288336, 0.758929, 0.000192535, 0, 0.314451, 0.738979, 0.000192688, 0, 0.341658, 0.718213, 0.000191522, 0, 0.369924, 0.696947, 0.000190491, 0, 0.399202, 0.675807, 0.000187913, 0, 0.429416, 0.654147, 0.000184451, 0, 0.460447, 0.63229, 0.000181442, 0, 0.492064, 0.610499, 0.000177139, 0, 0.523809, 0.588747, 0.000172596, 0, 0.555555, 0.566783, 0.000167457, 0, 0.587301, 0.545359, 0.000162518, 0, 0.619048, 0.523984, 0.000156818, 0, 0.650794, 0.502917, 0.000151884, 0, 0.68254, 0.482294, 0.000145514, 0, 0.714286, 0.461945, 0.000140199, 0, 0.746032, 0.442133, 0.000134101, 0, 0.777778, 0.422705, 0.000128374, 0, 0.809524, 0.403916, 0.000122996, 0, 0.84127, 0.38554, 0.000116808, 0, 0.873016, 0.367909, 0.000111973, 0, 0.904762, 0.350651, 0.000105938, 0, 0.936508, 0.334208, 0.000101355, 0, 0.968254, 0.318123, 9.57629e-05, 0, 1, 1, 1.11633e-06, 0, 0, 1, 1.11639e-06, 0, 0, 1, 1.11725e-06, 0, 0, 1, 1.12096e-06, 0, 0, 0.999999, 1.1311e-06, 0, 0, 0.999997, 1.15315e-06, 0, 0, 0.999995, 1.1956e-06, 0, 0, 0.999989, 1.27239e-06, 0, 0, 0.999981, 1.40772e-06, 0, 0, 0.999969, 1.64541e-06, 0, 0, 0.999952, 2.06607e-06, 0, 0, 0.999928, 2.81783e-06, 0, 0, 0.999895, 4.16835e-06, 0, 0, 0.999848, 6.58728e-06, 0, 0, 0.999781, 1.08648e-05, 0, 0, 0.999682, 1.82579e-05, 0, 0, 0.999523, 3.06003e-05, 0, 1.59122e-05, 0.999205, 4.99862e-05, 0, 0.000391184, 0.998131, 7.3306e-05, 0, 0.00147534, 0.993334, 5.13229e-05, 0, 0.0034227, 0.99016, 4.67783e-05, 0, 0.00632232, 0.987321, 5.23413e-05, 0, 0.0102295, 0.984099, 6.4267e-05, 0, 0.0151794, 0.980432, 8.43042e-05, 0, 0.0211947, 0.974976, 0.000102819, 0, 0.0282899, 0.966429, 9.96234e-05, 0, 0.0364739, 0.957633, 0.000111074, 0, 0.0457522, 0.949422, 0.000128644, 0, 0.0561278, 0.943045, 0.000140076, 0, 0.0676023, 0.935448, 0.000146349, 0, 0.0801762, 0.927225, 0.000161854, 0, 0.0938499, 0.917033, 0.000169135, 0, 0.108623, 0.905762, 0.000179987, 0, 0.124496, 0.892879, 0.000189832, 0, 0.141469, 0.878435, 0.000195881, 0, 0.159541, 0.863114, 0.00020466, 0, 0.178713, 0.84776, 0.000209473, 0, 0.198985, 0.832084, 0.000214861, 0, 0.220355, 0.814915, 0.000217695, 0, 0.242823, 0.796711, 0.000220313, 0, 0.266385, 0.777603, 0.00022313, 0, 0.291036, 0.757991, 0.000222471, 0, 0.316767, 0.738371, 0.000222869, 0, 0.343563, 0.717872, 0.000221243, 0, 0.371402, 0.696619, 0.000218089, 0, 0.400248, 0.675379, 0.00021562, 0, 0.430047, 0.65411, 0.00021169, 0, 0.460709, 0.63241, 0.000206947, 0, 0.492079, 0.61046, 0.000201709, 0, 0.52381, 0.58903, 0.000196753, 0, 0.555556, 0.567267, 0.000189637, 0, 0.587302, 0.545886, 0.000184735, 0, 0.619048, 0.524714, 0.000177257, 0, 0.650794, 0.503789, 0.000171424, 0, 0.68254, 0.483204, 0.000164688, 0, 0.714286, 0.462976, 0.000157172, 0, 0.746032, 0.443294, 0.000151341, 0, 0.777778, 0.423988, 0.000143737, 0, 0.809524, 0.405325, 0.000138098, 0, 0.84127, 0.386981, 0.000130698, 0, 0.873016, 0.369436, 0.000125276, 0, 0.904762, 0.35219, 0.000118349, 0, 0.936508, 0.335804, 0.00011312, 0, 0.968254, 0.319749, 0.000106687, 0, 1, 1, 2.04685e-06, 0, 0, 1, 2.04694e-06, 0, 0, 1, 2.04831e-06, 0, 0, 0.999999, 2.05428e-06, 0, 0, 0.999999, 2.07056e-06, 0, 0, 0.999997, 2.10581e-06, 0, 0, 0.999993, 2.1732e-06, 0, 0, 0.999987, 2.29365e-06, 0, 0, 0.999979, 2.50243e-06, 0, 0, 0.999965, 2.86127e-06, 0, 0, 0.999947, 3.48028e-06, 0, 0, 0.999918, 4.55588e-06, 0, 0, 0.999881, 6.43303e-06, 0, 0, 0.999828, 9.70064e-06, 0, 0, 0.999753, 1.53233e-05, 0, 0, 0.999642, 2.4793e-05, 0, 0, 0.999464, 4.02032e-05, 0, 0.000122947, 0.999089, 6.35852e-05, 0, 0.000807414, 0.997567, 8.57026e-05, 0, 0.00227206, 0.992903, 5.94912e-05, 0, 0.00462812, 0.990011, 5.78515e-05, 0, 0.00794162, 0.987192, 6.5399e-05, 0, 0.0122534, 0.98418, 8.19675e-05, 0, 0.0175888, 0.980491, 0.000105514, 0, 0.0239635, 0.974779, 0.000121532, 0, 0.031387, 0.96675, 0.000119144, 0, 0.0398644, 0.958248, 0.000136125, 0, 0.0493982, 0.948884, 0.000155408, 0, 0.0599896, 0.941673, 0.000162281, 0, 0.0716382, 0.934521, 0.000176754, 0, 0.0843437, 0.926205, 0.000192873, 0, 0.0981056, 0.916089, 0.000200038, 0, 0.112923, 0.904963, 0.000213624, 0, 0.128796, 0.892089, 0.000221834, 0, 0.145725, 0.878028, 0.000232619, 0, 0.163709, 0.86249, 0.000238632, 0, 0.182749, 0.846587, 0.000247002, 0, 0.202847, 0.830988, 0.000250702, 0, 0.224001, 0.814165, 0.000255562, 0, 0.246214, 0.796135, 0.000257505, 0, 0.269482, 0.777052, 0.000258625, 0, 0.293805, 0.757201, 0.000258398, 0, 0.319176, 0.737655, 0.000256714, 0, 0.345587, 0.717477, 0.000255187, 0, 0.373021, 0.696433, 0.000251792, 0, 0.401454, 0.675084, 0.000247223, 0, 0.430844, 0.653907, 0.000242213, 0, 0.461125, 0.632561, 0.000237397, 0, 0.492187, 0.610658, 0.000229313, 0, 0.52381, 0.589322, 0.000224402, 0, 0.555556, 0.567857, 0.000216116, 0, 0.587302, 0.54652, 0.000209124, 0, 0.619048, 0.525433, 0.000201601, 0, 0.650794, 0.504679, 0.000192957, 0, 0.68254, 0.484203, 0.000186052, 0, 0.714286, 0.464203, 0.000177672, 0, 0.746032, 0.444549, 0.000170005, 0, 0.777778, 0.425346, 0.000162401, 0, 0.809524, 0.406706, 0.0001544, 0, 0.84127, 0.388576, 0.000147437, 0, 0.873016, 0.37094, 0.000139493, 0, 0.904762, 0.353996, 0.000133219, 0, 0.936508, 0.337391, 0.000125573, 0, 0.968254, 0.321648, 0.000119867, 0, 1, 1, 3.62511e-06, 0, 0, 1, 3.62525e-06, 0, 0, 1, 3.62739e-06, 0, 0, 0.999999, 3.63673e-06, 0, 0, 0.999998, 3.66214e-06, 0, 0, 0.999996, 3.71698e-06, 0, 0, 0.999992, 3.82116e-06, 0, 0, 0.999986, 4.00554e-06, 0, 0, 0.999976, 4.32058e-06, 0, 0, 0.999961, 4.85194e-06, 0, 0, 0.999938, 5.74808e-06, 0, 0, 0.999908, 7.26643e-06, 0, 0, 0.999865, 9.84707e-06, 0, 0, 0.999807, 1.42217e-05, 0, 0, 0.999723, 2.15581e-05, 0, 0, 0.999602, 3.36114e-05, 0, 1.19113e-05, 0.999398, 5.27353e-05, 0, 0.000355813, 0.998946, 8.05809e-05, 0, 0.00137768, 0.996647, 9.42908e-05, 0, 0.00322469, 0.992298, 6.68733e-05, 0, 0.00597897, 0.989802, 7.16564e-05, 0, 0.00968903, 0.987019, 8.21355e-05, 0, 0.0143845, 0.984219, 0.000104555, 0, 0.0200831, 0.980425, 0.000131245, 0, 0.0267948, 0.974241, 0.000139613, 0, 0.034525, 0.967006, 0.000145931, 0, 0.0432757, 0.95893, 0.000167153, 0, 0.0530471, 0.949157, 0.000188146, 0, 0.0638386, 0.94062, 0.000194625, 0, 0.0756487, 0.933509, 0.000213721, 0, 0.0884762, 0.925088, 0.000229616, 0, 0.10232, 0.915178, 0.000239638, 0, 0.117178, 0.904093, 0.000254814, 0, 0.133051, 0.891337, 0.000263685, 0, 0.149939, 0.877326, 0.000274789, 0, 0.167841, 0.861794, 0.000280534, 0, 0.18676, 0.845758, 0.000289534, 0, 0.206696, 0.829792, 0.000294446, 0, 0.22765, 0.813037, 0.000296877, 0, 0.249625, 0.795285, 0.000300217, 0, 0.27262, 0.776323, 0.000299826, 0, 0.296636, 0.756673, 0.000299787, 0, 0.321671, 0.736856, 0.000297867, 0, 0.347718, 0.716883, 0.000294052, 0, 0.374768, 0.696089, 0.000289462, 0, 0.402804, 0.67505, 0.000285212, 0, 0.431796, 0.653509, 0.00027653, 0, 0.461695, 0.63258, 0.000271759, 0, 0.49242, 0.61104, 0.000262811, 0, 0.523822, 0.589567, 0.000255151, 0, 0.555556, 0.568322, 0.000246434, 0, 0.587302, 0.547235, 0.000237061, 0, 0.619048, 0.52616, 0.000228343, 0, 0.650794, 0.505716, 0.000219236, 0, 0.68254, 0.485274, 0.000209595, 0, 0.714286, 0.465411, 0.000201011, 0, 0.746032, 0.445854, 0.00019109, 0, 0.777778, 0.426911, 0.000182897, 0, 0.809524, 0.408222, 0.000173569, 0, 0.84127, 0.390307, 0.000165496, 0, 0.873016, 0.372624, 0.000156799, 0, 0.904762, 0.355804, 0.00014917, 0, 0.936508, 0.33924, 0.000140907, 0, 0.968254, 0.323534, 0.000134062, 0, 1, 1, 6.22487e-06, 0, 0, 1, 6.2251e-06, 0, 0, 1, 6.22837e-06, 0, 0, 0.999999, 6.24259e-06, 0, 0, 0.999998, 6.28127e-06, 0, 0, 0.999996, 6.36451e-06, 0, 0, 0.999991, 6.5218e-06, 0, 0, 0.999984, 6.79782e-06, 0, 0, 0.999973, 7.26361e-06, 0, 0, 0.999955, 8.03644e-06, 0, 0, 0.999931, 9.31397e-06, 0, 0, 0.999896, 1.14299e-05, 0, 0, 0.999847, 1.49402e-05, 0, 0, 0.999784, 2.07461e-05, 0, 0, 0.999692, 3.02493e-05, 0, 0, 0.999554, 4.54957e-05, 0, 9.97275e-05, 0.999326, 6.90762e-05, 0, 0.000724813, 0.998757, 0.000101605, 0, 0.0020972, 0.995367, 9.58745e-05, 0, 0.00432324, 0.99209, 8.32808e-05, 0, 0.00746347, 0.989517, 8.87601e-05, 0, 0.0115534, 0.987008, 0.00010564, 0, 0.0166134, 0.98421, 0.000133179, 0, 0.0226552, 0.98021, 0.000161746, 0, 0.0296838, 0.973676, 0.000161821, 0, 0.0377016, 0.967052, 0.000178635, 0, 0.0467079, 0.959385, 0.000206765, 0, 0.0567013, 0.949461, 0.00022476, 0, 0.0676796, 0.939578, 0.00023574, 0, 0.0796403, 0.932416, 0.00025893, 0, 0.0925812, 0.923759, 0.000271228, 0, 0.106501, 0.914223, 0.000289165, 0, 0.121397, 0.902942, 0.000301156, 0, 0.13727, 0.890419, 0.000313852, 0, 0.15412, 0.876639, 0.000324408, 0, 0.171946, 0.861316, 0.00033249, 0, 0.190751, 0.84496, 0.000338497, 0, 0.210537, 0.828427, 0.000345861, 0, 0.231305, 0.811871, 0.000347863, 0, 0.253057, 0.794397, 0.000350225, 0, 0.275797, 0.775726, 0.000349915, 0, 0.299525, 0.75617, 0.000347297, 0, 0.324242, 0.736091, 0.000344232, 0, 0.349947, 0.716213, 0.000340835, 0, 0.376633, 0.695736, 0.000332369, 0, 0.404289, 0.674961, 0.000327943, 0, 0.432895, 0.653518, 0.000318533, 0, 0.462415, 0.632574, 0.000310391, 0, 0.492788, 0.61134, 0.000300755, 0, 0.523909, 0.590017, 0.000290506, 0, 0.555556, 0.568752, 0.000280446, 0, 0.587302, 0.548061, 0.000269902, 0, 0.619048, 0.52711, 0.000258815, 0, 0.650794, 0.506682, 0.000248481, 0, 0.68254, 0.486524, 0.000237141, 0, 0.714286, 0.466812, 0.000226872, 0, 0.746032, 0.44732, 0.000216037, 0, 0.777778, 0.428473, 0.000205629, 0, 0.809524, 0.409921, 0.000195691, 0, 0.84127, 0.392028, 0.000185457, 0, 0.873016, 0.374606, 0.000176436, 0, 0.904762, 0.357601, 0.000166508, 0, 0.936508, 0.341348, 0.000158385, 0, 0.968254, 0.32542, 0.000149203, 0, 1, 1, 1.03967e-05, 0, 0, 1, 1.0397e-05, 0, 0, 1, 1.04019e-05, 0, 0, 0.999999, 1.04231e-05, 0, 0, 0.999998, 1.04806e-05, 0, 0, 0.999995, 1.06042e-05, 0, 0, 0.999991, 1.08366e-05, 0, 0, 0.999982, 1.12415e-05, 0, 0, 0.999968, 1.19174e-05, 0, 0, 0.99995, 1.30227e-05, 0, 0, 0.999922, 1.48176e-05, 0, 0, 0.999884, 1.77303e-05, 0, 0, 0.99983, 2.24564e-05, 0, 0, 0.999758, 3.00966e-05, 0, 0, 0.999654, 4.23193e-05, 0, 5.49083e-06, 0.999503, 6.14848e-05, 0, 0.000296087, 0.999237, 9.03576e-05, 0, 0.00123144, 0.998491, 0.0001271, 0, 0.00295954, 0.994594, 0.000107754, 0, 0.00555829, 0.99178, 0.000103025, 0, 0.00907209, 0.989265, 0.00011154, 0, 0.0135257, 0.986998, 0.000136296, 0, 0.0189327, 0.984137, 0.000169154, 0, 0.0252993, 0.979798, 0.000196671, 0, 0.0326272, 0.97337, 0.000196678, 0, 0.0409157, 0.967239, 0.000223121, 0, 0.0501623, 0.959543, 0.000253809, 0, 0.0603638, 0.949466, 0.000265972, 0, 0.0715171, 0.939074, 0.000288372, 0, 0.0836187, 0.931118, 0.000310983, 0, 0.0966657, 0.922525, 0.000325561, 0, 0.110656, 0.912983, 0.000345725, 0, 0.125588, 0.901617, 0.0003556, 0, 0.141461, 0.889487, 0.000374012, 0, 0.158275, 0.875787, 0.000383445, 0, 0.176031, 0.860654, 0.000393972, 0, 0.19473, 0.844417, 0.000400311, 0, 0.214374, 0.82741, 0.000405004, 0, 0.234967, 0.810545, 0.000407378, 0, 0.256512, 0.793312, 0.000407351, 0, 0.279011, 0.774847, 0.000406563, 0, 0.302468, 0.755621, 0.000404903, 0, 0.326887, 0.735511, 0.000397486, 0, 0.352266, 0.715435, 0.00039357, 0, 0.378605, 0.695403, 0.000384739, 0, 0.405897, 0.674681, 0.000376108, 0, 0.43413, 0.65359, 0.000365997, 0, 0.463277, 0.632471, 0.000354957, 0, 0.493295, 0.61151, 0.000343593, 0, 0.524106, 0.59064, 0.000331841, 0, 0.555561, 0.569386, 0.000318891, 0, 0.587302, 0.548785, 0.0003072, 0, 0.619048, 0.528146, 0.00029361, 0, 0.650794, 0.507872, 0.000281709, 0, 0.68254, 0.487805, 0.000268627, 0, 0.714286, 0.468196, 0.000255887, 0, 0.746032, 0.448922, 0.000243997, 0, 0.777778, 0.430093, 0.000231662, 0, 0.809524, 0.411845, 0.000220339, 0, 0.84127, 0.393808, 0.000208694, 0, 0.873016, 0.376615, 0.000198045, 0, 0.904762, 0.359655, 0.000187375, 0, 0.936508, 0.343452, 0.000177371, 0, 0.968254, 0.32765, 0.000167525, 0, 1, 1, 1.69351e-05, 0, 0, 1, 1.69356e-05, 0, 0, 1, 1.69427e-05, 0, 0, 0.999999, 1.69736e-05, 0, 0, 0.999998, 1.70575e-05, 0, 0, 0.999995, 1.72372e-05, 0, 0, 0.99999, 1.75739e-05, 0, 0, 0.999979, 1.81568e-05, 0, 0, 0.999966, 1.91206e-05, 0, 0, 0.999944, 2.0677e-05, 0, 0, 0.999912, 2.31644e-05, 0, 0, 0.999869, 2.71268e-05, 0, 0, 0.999811, 3.34272e-05, 0, 0, 0.99973, 4.33979e-05, 0, 0, 0.999617, 5.90083e-05, 0, 6.80315e-05, 0.999445, 8.29497e-05, 0, 0.000612796, 0.999138, 0.000118019, 0, 0.00187408, 0.998095, 0.000156712, 0, 0.00395791, 0.993919, 0.000125054, 0, 0.00692144, 0.991333, 0.000126091, 0, 0.0107962, 0.989226, 0.000144912, 0, 0.0155986, 0.986954, 0.000175737, 0, 0.0213364, 0.983982, 0.000213883, 0, 0.0280114, 0.979128, 0.000234526, 0, 0.0356226, 0.973327, 0.000243725, 0, 0.0441668, 0.967416, 0.0002773, 0, 0.0536399, 0.959729, 0.000308799, 0, 0.0640376, 0.949758, 0.000322447, 0, 0.0753554, 0.939173, 0.000350021, 0, 0.0875893, 0.9296, 0.000370089, 0, 0.100736, 0.921181, 0.000391365, 0, 0.114793, 0.91164, 0.000413636, 0, 0.129759, 0.900435, 0.000427068, 0, 0.145632, 0.888183, 0.000441046, 0, 0.162412, 0.874772, 0.000454968, 0, 0.180101, 0.859566, 0.000461882, 0, 0.1987, 0.843579, 0.000471556, 0, 0.218213, 0.826453, 0.000474335, 0, 0.238641, 0.809164, 0.000477078, 0, 0.259989, 0.792179, 0.00047755, 0, 0.282262, 0.773866, 0.000472573, 0, 0.305464, 0.754944, 0.000469765, 0, 0.329599, 0.735133, 0.000462371, 0, 0.35467, 0.714858, 0.000453674, 0, 0.380678, 0.694829, 0.000443888, 0, 0.407622, 0.674453, 0.000432052, 0, 0.435493, 0.653685, 0.000420315, 0, 0.464275, 0.632666, 0.000406829, 0, 0.493938, 0.611676, 0.000392234, 0, 0.524422, 0.591193, 0.000379208, 0, 0.555624, 0.570145, 0.00036319, 0, 0.587302, 0.549566, 0.000349111, 0, 0.619048, 0.529278, 0.000334166, 0, 0.650794, 0.509026, 0.000318456, 0, 0.68254, 0.489186, 0.00030449, 0, 0.714286, 0.469662, 0.000289051, 0, 0.746032, 0.450691, 0.000275494, 0, 0.777778, 0.431841, 0.000261437, 0, 0.809524, 0.413752, 0.000247846, 0, 0.84127, 0.395951, 0.000235085, 0, 0.873016, 0.378633, 0.000222245, 0, 0.904762, 0.36194, 0.000210533, 0, 0.936508, 0.345599, 0.000198494, 0, 0.968254, 0.329999, 0.000188133, 0, 1, 1, 2.69663e-05, 0, 0, 1, 2.6967e-05, 0, 0, 1, 2.69772e-05, 0, 0, 0.999999, 2.70214e-05, 0, 0, 0.999998, 2.71415e-05, 0, 0, 0.999994, 2.7398e-05, 0, 0, 0.999988, 2.78771e-05, 0, 0, 0.999977, 2.87019e-05, 0, 0, 0.999961, 3.00544e-05, 0, 0, 0.999937, 3.22138e-05, 0, 0, 0.999904, 3.56163e-05, 0, 0, 0.999854, 4.09465e-05, 0, 0, 0.99979, 4.92651e-05, 0, 0, 0.999699, 6.21722e-05, 0, 8.8288e-07, 0.999572, 8.19715e-05, 0, 0.000223369, 0.999381, 0.000111689, 0, 0.00105414, 0.999016, 0.000153862, 0, 0.0026493, 0.997437, 0.000187667, 0, 0.00508608, 0.993545, 0.000155672, 0, 0.00840554, 0.991135, 0.000161455, 0, 0.012629, 0.989157, 0.000188241, 0, 0.0177661, 0.986874, 0.000226229, 0, 0.0238198, 0.983714, 0.000268668, 0, 0.0307887, 0.978301, 0.000277109, 0, 0.0386688, 0.973227, 0.000303446, 0, 0.0474554, 0.967317, 0.000341851, 0, 0.0571428, 0.959477, 0.000370885, 0, 0.0677256, 0.950012, 0.000392753, 0, 0.0791988, 0.939484, 0.00042781, 0, 0.0915576, 0.928135, 0.000443866, 0, 0.104798, 0.919819, 0.000472959, 0, 0.118918, 0.910049, 0.000491551, 0, 0.133915, 0.899181, 0.000512616, 0, 0.149788, 0.886881, 0.000523563, 0, 0.166537, 0.87359, 0.000540183, 0, 0.184164, 0.858613, 0.000547386, 0, 0.202669, 0.842809, 0.000554809, 0, 0.222056, 0.825727, 0.000558316, 0, 0.242329, 0.808086, 0.000557824, 0, 0.263492, 0.790728, 0.000556346, 0, 0.285551, 0.772987, 0.000552672, 0, 0.30851, 0.7541, 0.000543738, 0, 0.332376, 0.734669, 0.000536107, 0, 0.357153, 0.714411, 0.000523342, 0, 0.382845, 0.694196, 0.000512238, 0, 0.409454, 0.674252, 0.000497465, 0, 0.436977, 0.65357, 0.000481096, 0, 0.465404, 0.632999, 0.000467054, 0, 0.494713, 0.611994, 0.000448771, 0, 0.524864, 0.591604, 0.000431889, 0, 0.555779, 0.571134, 0.000415238, 0, 0.587302, 0.550528, 0.000396369, 0, 0.619048, 0.530292, 0.000379477, 0, 0.650794, 0.510364, 0.000361488, 0, 0.68254, 0.490749, 0.000343787, 0, 0.714286, 0.471266, 0.000327822, 0, 0.746032, 0.452462, 0.000310626, 0, 0.777778, 0.433907, 0.000295352, 0, 0.809524, 0.415659, 0.000279179, 0, 0.84127, 0.398138, 0.000264685, 0, 0.873016, 0.380833, 0.000249905, 0, 0.904762, 0.364247, 0.000236282, 0, 0.936508, 0.348041, 0.000222905, 0, 0.968254, 0.332389, 0.000210522, 0, 1, 1, 4.20604e-05, 0, 0, 1, 4.20614e-05, 0, 0, 1, 4.20757e-05, 0, 0, 0.999999, 4.2138e-05, 0, 0, 0.999997, 4.23067e-05, 0, 0, 0.999993, 4.26668e-05, 0, 0, 0.999986, 4.33372e-05, 0, 0, 0.999974, 4.44857e-05, 0, 0, 0.999956, 4.63554e-05, 0, 0, 0.99993, 4.93105e-05, 0, 0, 0.999892, 5.39077e-05, 0, 0, 0.999838, 6.10005e-05, 0, 0, 0.999767, 7.18822e-05, 0, 0, 0.999666, 8.84581e-05, 0, 3.65471e-05, 0.999525, 0.000113398, 0, 0.000485623, 0.999311, 0.000150043, 0, 0.00162096, 0.998865, 0.000200063, 0, 0.00355319, 0.996278, 0.000211014, 0, 0.00633818, 0.992956, 0.000189672, 0, 0.0100043, 0.991017, 0.000210262, 0, 0.0145648, 0.989055, 0.000244292, 0, 0.0200237, 0.986741, 0.000290481, 0, 0.0263798, 0.983288, 0.000334303, 0, 0.033629, 0.977784, 0.000340307, 0, 0.0417652, 0.973037, 0.000377864, 0, 0.0507821, 0.967181, 0.0004239, 0, 0.060673, 0.958971, 0.000443854, 0, 0.0714314, 0.950093, 0.000483039, 0, 0.0830518, 0.939552, 0.000517934, 0, 0.0955288, 0.927678, 0.000539449, 0, 0.108859, 0.918278, 0.000568604, 0, 0.123038, 0.908449, 0.000588505, 0, 0.138065, 0.897713, 0.000612473, 0, 0.153938, 0.885533, 0.000625575, 0, 0.170657, 0.872131, 0.00063854, 0, 0.188224, 0.857517, 0.000647034, 0, 0.20664, 0.841796, 0.00065209, 0, 0.225909, 0.824726, 0.0006544, 0, 0.246035, 0.807297, 0.000655744, 0, 0.267022, 0.789058, 0.000646716, 0, 0.288878, 0.77189, 0.000643898, 0, 0.311607, 0.753082, 0.000629973, 0, 0.335216, 0.7341, 0.000621564, 0, 0.359713, 0.714094, 0.000605171, 0, 0.385103, 0.693839, 0.000588752, 0, 0.41139, 0.673891, 0.000573294, 0, 0.438576, 0.653565, 0.000552682, 0, 0.466656, 0.633326, 0.000533446, 0, 0.495617, 0.612582, 0.000514635, 0, 0.525431, 0.59205, 0.00049303, 0, 0.556041, 0.571918, 0.000471842, 0, 0.587338, 0.551572, 0.000451713, 0, 0.619048, 0.531553, 0.000430049, 0, 0.650794, 0.51175, 0.000410445, 0, 0.68254, 0.49238, 0.000390098, 0, 0.714286, 0.473143, 0.000370033, 0, 0.746032, 0.45423, 0.000351205, 0, 0.777778, 0.435963, 0.000332049, 0, 0.809524, 0.41787, 0.000315021, 0, 0.84127, 0.400387, 0.000297315, 0, 0.873016, 0.383332, 0.000281385, 0, 0.904762, 0.366665, 0.000265397, 0, 0.936508, 0.350633, 0.000250601, 0, 0.968254, 0.334964, 0.00023589, 0, 1, 1, 6.43736e-05, 0, 0, 1, 6.4375e-05, 0, 0, 1, 6.43947e-05, 0, 0, 0.999999, 6.4481e-05, 0, 0, 0.999997, 6.47143e-05, 0, 0, 0.999994, 6.52119e-05, 0, 0, 0.999985, 6.61359e-05, 0, 0, 0.999972, 6.77116e-05, 0, 0, 0.999952, 7.02599e-05, 0, 0, 0.999922, 7.42517e-05, 0, 0, 0.99988, 8.03906e-05, 0, 0, 0.99982, 8.97315e-05, 0, 0, 0.999741, 0.000103838, 0, 0, 0.999629, 0.00012496, 0, 0.000149024, 0.999474, 0.000156161, 0, 0.000861027, 0.999229, 0.000201034, 0, 0.00231198, 0.998662, 0.000259069, 0, 0.00458147, 0.995299, 0.000245439, 0, 0.00770895, 0.992732, 0.00024498, 0, 0.0117126, 0.990847, 0.000273211, 0, 0.0165989, 0.988911, 0.000316492, 0, 0.0223674, 0.98654, 0.00037161, 0, 0.0290135, 0.982636, 0.000410352, 0, 0.0365309, 0.977346, 0.000421756, 0, 0.0449117, 0.972909, 0.000475578, 0, 0.0541481, 0.966821, 0.000522482, 0, 0.0642326, 0.958686, 0.000545008, 0, 0.075158, 0.949754, 0.000589286, 0, 0.0869181, 0.939184, 0.000619995, 0, 0.0995074, 0.927505, 0.000654266, 0, 0.112922, 0.916606, 0.000682362, 0, 0.127157, 0.906707, 0.000704286, 0, 0.142212, 0.895937, 0.000725909, 0, 0.158085, 0.883913, 0.000743939, 0, 0.174776, 0.870642, 0.000755157, 0, 0.192287, 0.856241, 0.000764387, 0, 0.210619, 0.84069, 0.000771032, 0, 0.229775, 0.823728, 0.000765906, 0, 0.249761, 0.806481, 0.000767604, 0, 0.270582, 0.787924, 0.000754385, 0, 0.292243, 0.770588, 0.000749668, 0, 0.314753, 0.751991, 0.000731613, 0, 0.338118, 0.733407, 0.000717655, 0, 0.362347, 0.713688, 0.000700604, 0, 0.387447, 0.693595, 0.000678765, 0, 0.413424, 0.673426, 0.000657042, 0, 0.440284, 0.65359, 0.000635892, 0, 0.468027, 0.633576, 0.000611569, 0, 0.496645, 0.613144, 0.000586011, 0, 0.526122, 0.592711, 0.000563111, 0, 0.556417, 0.572722, 0.000537699, 0, 0.587451, 0.552762, 0.000512556, 0, 0.619048, 0.532985, 0.000489757, 0, 0.650794, 0.513219, 0.000464139, 0, 0.68254, 0.493992, 0.000442193, 0, 0.714286, 0.47509, 0.000418629, 0, 0.746032, 0.456287, 0.000397045, 0, 0.777778, 0.438152, 0.000375504, 0, 0.809524, 0.420294, 0.00035492, 0, 0.84127, 0.402749, 0.000335327, 0, 0.873016, 0.385879, 0.000316422, 0, 0.904762, 0.369352, 0.000298333, 0, 0.936508, 0.353301, 0.000281417, 0, 0.968254, 0.337781, 0.000265203, 0, 1, 1, 9.68267e-05, 0, 0, 1, 9.68284e-05, 0, 0, 1, 9.68556e-05, 0, 0, 0.999999, 9.69733e-05, 0, 0, 0.999997, 9.72913e-05, 0, 0, 0.999993, 9.79688e-05, 0, 0, 0.999984, 9.92239e-05, 0, 0, 0.999969, 0.000101356, 0, 0, 0.999946, 0.000104784, 0, 0, 0.999913, 0.000110111, 0, 0, 0.999868, 0.000118217, 0, 0, 0.999801, 0.000130396, 0, 0, 0.999712, 0.000148523, 0, 1.24907e-05, 0.999589, 0.000175233, 0, 0.000355405, 0.999416, 0.000213999, 0, 0.0013528, 0.999136, 0.000268529, 0, 0.00312557, 0.998367, 0.000333088, 0, 0.00573045, 0.994701, 0.000304757, 0, 0.00919397, 0.992497, 0.000318031, 0, 0.0135261, 0.990608, 0.000353863, 0, 0.0187278, 0.988715, 0.000409044, 0, 0.0247947, 0.986241, 0.000472967, 0, 0.0317196, 0.981696, 0.000495104, 0, 0.039494, 0.977097, 0.000532873, 0, 0.0481087, 0.972583, 0.000594447, 0, 0.0575549, 0.966142, 0.000636867, 0, 0.0678242, 0.95823, 0.000669899, 0, 0.0789089, 0.949677, 0.000719499, 0, 0.0908023, 0.939226, 0.000750584, 0, 0.103499, 0.927501, 0.000793183, 0, 0.116993, 0.915199, 0.00081995, 0, 0.131282, 0.90498, 0.000847654, 0, 0.146364, 0.894243, 0.000868929, 0, 0.162237, 0.882154, 0.000884278, 0, 0.178902, 0.869161, 0.000898108, 0, 0.196358, 0.854751, 0.000901254, 0, 0.21461, 0.839368, 0.00090679, 0, 0.23366, 0.822874, 0.000901541, 0, 0.253512, 0.805514, 0.000897297, 0, 0.274174, 0.78716, 0.000881856, 0, 0.29565, 0.769061, 0.000870032, 0, 0.31795, 0.751, 0.000851719, 0, 0.341081, 0.732614, 0.000830671, 0, 0.365053, 0.713171, 0.000806569, 0, 0.389874, 0.693472, 0.00078338, 0, 0.415553, 0.673528, 0.000756404, 0, 0.442098, 0.653397, 0.000726872, 0, 0.469512, 0.633781, 0.000700494, 0, 0.497794, 0.613877, 0.00067105, 0, 0.526935, 0.593506, 0.000640361, 0, 0.556908, 0.573667, 0.000613502, 0, 0.587657, 0.553932, 0.000583177, 0, 0.61906, 0.534345, 0.000554375, 0, 0.650794, 0.515042, 0.000527811, 0, 0.68254, 0.495674, 0.000499367, 0, 0.714286, 0.477132, 0.00047429, 0, 0.746032, 0.458609, 0.000447726, 0, 0.777778, 0.440354, 0.000424205, 0, 0.809524, 0.422765, 0.000399549, 0, 0.84127, 0.405472, 0.000378315, 0, 0.873016, 0.388482, 0.000355327, 0, 0.904762, 0.372191, 0.000336122, 0, 0.936508, 0.356099, 0.000315247, 0, 0.968254, 0.340737, 0.00029794, 0, 1, 1, 0.000143327, 0, 0, 1, 0.00014333, 0, 0, 1, 0.000143366, 0, 0, 0.999999, 0.000143524, 0, 0, 0.999996, 0.000143952, 0, 0, 0.999991, 0.000144862, 0, 0, 0.999981, 0.000146544, 0, 0, 0.999966, 0.000149391, 0, 0, 0.999941, 0.000153946, 0, 0, 0.999905, 0.000160971, 0, 0, 0.999852, 0.000171562, 0, 0, 0.99978, 0.00018729, 0, 0, 0.999681, 0.000210386, 0, 8.26239e-05, 0.999546, 0.000243906, 0, 0.000664807, 0.999352, 0.000291739, 0, 0.00196192, 0.999027, 0.000357419, 0, 0.00405941, 0.997886, 0.000422349, 0, 0.00699664, 0.99419, 0.000385008, 0, 0.0107896, 0.99214, 0.000409775, 0, 0.0154415, 0.990274, 0.000456418, 0, 0.0209488, 0.988455, 0.000527008, 0, 0.0273037, 0.985804, 0.000597685, 0, 0.0344969, 0.98103, 0.000613124, 0, 0.0425183, 0.976674, 0.000668321, 0, 0.0513575, 0.972021, 0.000736985, 0, 0.0610046, 0.965274, 0.000773789, 0, 0.0714508, 0.958046, 0.000830852, 0, 0.0826877, 0.949333, 0.000875766, 0, 0.0947085, 0.939135, 0.000917088, 0, 0.107507, 0.927119, 0.000952244, 0, 0.121078, 0.91469, 0.000990626, 0, 0.135419, 0.903006, 0.00101304, 0, 0.150526, 0.892368, 0.00103834, 0, 0.166399, 0.880231, 0.00105002, 0, 0.183038, 0.867432, 0.00106331, 0, 0.200443, 0.853208, 0.00106783, 0, 0.218618, 0.837956, 0.00106458, 0, 0.237566, 0.821772, 0.00105945, 0, 0.257291, 0.804328, 0.00104685, 0, 0.2778, 0.786465, 0.00103178, 0, 0.2991, 0.768004, 0.00101077, 0, 0.321199, 0.74972, 0.000985504, 0, 0.344106, 0.731682, 0.000962893, 0, 0.36783, 0.712813, 0.000932146, 0, 0.392383, 0.693139, 0.00089871, 0, 0.417774, 0.673566, 0.000869678, 0, 0.444013, 0.653483, 0.000835525, 0, 0.471107, 0.633891, 0.000799853, 0, 0.49906, 0.614433, 0.000766838, 0, 0.527869, 0.594586, 0.000732227, 0, 0.557517, 0.574769, 0.000696442, 0, 0.587966, 0.555149, 0.000663935, 0, 0.61913, 0.535898, 0.000629826, 0, 0.650794, 0.516753, 0.000596486, 0, 0.68254, 0.497816, 0.000567078, 0, 0.714286, 0.479034, 0.000534399, 0, 0.746032, 0.460975, 0.000507013, 0, 0.777778, 0.442935, 0.000477421, 0, 0.809524, 0.425263, 0.000451101, 0, 0.84127, 0.408248, 0.000424964, 0, 0.873016, 0.391339, 0.00039993, 0, 0.904762, 0.37513, 0.000377619, 0, 0.936508, 0.359172, 0.000354418, 0, 0.968254, 0.343876, 0.000334823, 0, 1, 1, 0.000209042, 0, 0, 1, 0.000209045, 0, 0, 1, 0.000209093, 0, 0, 0.999999, 0.000209304, 0, 0, 0.999996, 0.000209871, 0, 0, 0.999991, 0.000211078, 0, 0, 0.999979, 0.000213304, 0, 0, 0.999963, 0.000217061, 0, 0, 0.999933, 0.000223042, 0, 0, 0.999894, 0.000232206, 0, 0, 0.999837, 0.000245901, 0, 0, 0.999756, 0.000266023, 0, 1.02927e-06, 0.999648, 0.000295204, 0, 0.000233468, 0.999499, 0.000336958, 0, 0.00108237, 0.999283, 0.000395563, 0, 0.00268832, 0.998896, 0.000473785, 0, 0.00511138, 0.997006, 0.000520008, 0, 0.00837705, 0.993819, 0.000497261, 0, 0.0124928, 0.991632, 0.000523722, 0, 0.0174561, 0.989875, 0.000587258, 0, 0.0232596, 0.988109, 0.000676329, 0, 0.0298932, 0.985155, 0.000747701, 0, 0.0373453, 0.980479, 0.000768803, 0, 0.0456045, 0.976271, 0.000841054, 0, 0.0546593, 0.971347, 0.000911469, 0, 0.0644994, 0.964528, 0.000953057, 0, 0.0751152, 0.957632, 0.00102221, 0, 0.0864981, 0.948681, 0.00106122, 0, 0.0986407, 0.938716, 0.00111857, 0, 0.111537, 0.926629, 0.00114762, 0, 0.125182, 0.914025, 0.00118995, 0, 0.139571, 0.901026, 0.00121228, 0, 0.154703, 0.890358, 0.00123946, 0, 0.170576, 0.878283, 0.0012527, 0, 0.18719, 0.865459, 0.00125536, 0, 0.204547, 0.851407, 0.00126134, 0, 0.222648, 0.836276, 0.00124759, 0, 0.241498, 0.820436, 0.00124443, 0, 0.261101, 0.803253, 0.00122071, 0, 0.281465, 0.785562, 0.00120107, 0, 0.302595, 0.76718, 0.00117762, 0, 0.324501, 0.748551, 0.00114289, 0, 0.347192, 0.730564, 0.00110872, 0, 0.370679, 0.712253, 0.00107636, 0, 0.394973, 0.692867, 0.00103646, 0, 0.420085, 0.673695, 0.000996793, 0, 0.446027, 0.653912, 0.00095675, 0, 0.47281, 0.634129, 0.000916739, 0, 0.500441, 0.615004, 0.000874401, 0, 0.528921, 0.595587, 0.000833411, 0, 0.558244, 0.575965, 0.000794556, 0, 0.588384, 0.5566, 0.00075196, 0, 0.619281, 0.537428, 0.000716381, 0, 0.650795, 0.518623, 0.000676558, 0, 0.68254, 0.499964, 0.00064074, 0, 0.714286, 0.481356, 0.000605984, 0, 0.746032, 0.463279, 0.000570256, 0, 0.777778, 0.445673, 0.000540138, 0, 0.809524, 0.428032, 0.000507299, 0, 0.84127, 0.411112, 0.000479553, 0, 0.873016, 0.394444, 0.000450737, 0, 0.904762, 0.378247, 0.000424269, 0, 0.936508, 0.362415, 0.000399111, 0, 0.968254, 0.347103, 0.000375274, 0, 1, 1, 0.000300729, 0, 0, 1, 0.000300733, 0, 0, 1, 0.000300797, 0, 0, 0.999998, 0.000301072, 0, 0, 0.999996, 0.000301817, 0, 0, 0.999989, 0.000303398, 0, 0, 0.999977, 0.000306309, 0, 0, 0.999958, 0.000311209, 0, 0, 0.999927, 0.000318975, 0, 0, 0.999884, 0.000330804, 0, 0, 0.99982, 0.00034834, 0, 0, 0.999733, 0.000373854, 0, 3.26995e-05, 0.999613, 0.000410424, 0, 0.000477174, 0.999447, 0.000462047, 0, 0.00161099, 0.999204, 0.000533322, 0, 0.00353153, 0.998725, 0.000624964, 0, 0.00627965, 0.995871, 0.000631786, 0, 0.0098693, 0.993194, 0.000632017, 0, 0.0143011, 0.991541, 0.00068923, 0, 0.019568, 0.989773, 0.000766892, 0, 0.0256593, 0.987647, 0.000863668, 0, 0.0325625, 0.984193, 0.000922089, 0, 0.0402647, 0.980016, 0.000970749, 0, 0.0487532, 0.975859, 0.00106027, 0, 0.058016, 0.970514, 0.00112239, 0, 0.0680419, 0.963625, 0.00117212, 0, 0.0788208, 0.956959, 0.00125211, 0, 0.0903439, 0.947956, 0.00129411, 0, 0.102604, 0.93809, 0.00135879, 0, 0.115594, 0.92659, 0.00139309, 0, 0.129309, 0.913829, 0.00143253, 0, 0.143745, 0.90005, 0.00145809, 0, 0.158901, 0.888129, 0.0014748, 0, 0.174774, 0.87607, 0.00148756, 0, 0.191365, 0.863461, 0.00148714, 0, 0.208674, 0.849594, 0.00148892, 0, 0.226705, 0.834531, 0.00146496, 0, 0.245461, 0.81903, 0.0014579, 0, 0.264947, 0.802122, 0.00143039, 0, 0.28517, 0.78445, 0.00139717, 0, 0.306137, 0.766434, 0.00136312, 0, 0.327857, 0.747816, 0.00132597, 0, 0.350341, 0.729519, 0.00128323, 0, 0.373598, 0.711454, 0.00123803, 0, 0.397642, 0.692699, 0.00119097, 0, 0.422485, 0.673723, 0.00114565, 0, 0.448139, 0.654386, 0.00109552, 0, 0.474619, 0.634673, 0.00104553, 0, 0.501933, 0.615554, 0.00099985, 0, 0.530089, 0.596462, 0.000948207, 0, 0.559087, 0.577385, 0.000902299, 0, 0.588913, 0.558257, 0.000856448, 0, 0.619525, 0.5392, 0.000810395, 0, 0.650826, 0.520543, 0.000768558, 0, 0.68254, 0.502206, 0.0007239, 0, 0.714286, 0.48402, 0.000685794, 0, 0.746032, 0.465779, 0.00064471, 0, 0.777778, 0.448455, 0.000609583, 0, 0.809524, 0.431091, 0.00057227, 0, 0.84127, 0.414147, 0.00054042, 0, 0.873016, 0.39765, 0.000506545, 0, 0.904762, 0.381576, 0.000477635, 0, 0.936508, 0.365881, 0.000448446, 0, 0.968254, 0.350582, 0.000421424, 0, 1, 1, 0.000427144, 0, 0, 1, 0.000427151, 0, 0, 1, 0.000427232, 0, 0, 0.999998, 0.00042759, 0, 0, 0.999995, 0.000428555, 0, 0, 0.999988, 0.000430603, 0, 0, 0.999976, 0.000434368, 0, 0, 0.999952, 0.000440688, 0, 0, 0.999919, 0.000450667, 0, 0, 0.999871, 0.00046578, 0, 0, 0.999801, 0.000488024, 0, 0, 0.999704, 0.000520092, 0, 0.000129791, 0.999572, 0.000565553, 0, 0.000821056, 0.999389, 0.000628906, 0, 0.00225241, 0.999114, 0.000714911, 0, 0.00449109, 0.998488, 0.000819218, 0, 0.00756249, 0.995234, 0.00080415, 0, 0.0114716, 0.993021, 0.000830181, 0, 0.0162131, 0.991407, 0.000902645, 0, 0.021776, 0.989625, 0.000996934, 0, 0.0281471, 0.987064, 0.00109707, 0, 0.0353118, 0.983265, 0.00114353, 0, 0.0432562, 0.979535, 0.0012272, 0, 0.0519665, 0.975224, 0.00132642, 0, 0.0614298, 0.969574, 0.00138092, 0, 0.0716348, 0.963021, 0.00145896, 0, 0.0825709, 0.956046, 0.00152834, 0, 0.094229, 0.947136, 0.00158217, 0, 0.106602, 0.937313, 0.0016347, 0, 0.119682, 0.926073, 0.00168383, 0, 0.133465, 0.913121, 0.00171627, 0, 0.147947, 0.899165, 0.00174229, 0, 0.163125, 0.885891, 0.00176137, 0, 0.178998, 0.873783, 0.00176406, 0, 0.195566, 0.861331, 0.00176156, 0, 0.21283, 0.847569, 0.00175346, 0, 0.230793, 0.832785, 0.00172753, 0, 0.249459, 0.817442, 0.00170204, 0, 0.268832, 0.800613, 0.00166576, 0, 0.28892, 0.783597, 0.00162909, 0, 0.30973, 0.76571, 0.0015826, 0, 0.331271, 0.747021, 0.00153106, 0, 0.353554, 0.728593, 0.00148036, 0, 0.37659, 0.710661, 0.00142808, 0, 0.400391, 0.692426, 0.00136906, 0, 0.424973, 0.673623, 0.00131066, 0, 0.450347, 0.65494, 0.00125569, 0, 0.476531, 0.635448, 0.00119517, 0, 0.503535, 0.616221, 0.00113828, 0, 0.531372, 0.597531, 0.0010816, 0, 0.560047, 0.578795, 0.00102673, 0, 0.589554, 0.559892, 0.000970985, 0, 0.619869, 0.541307, 0.000919773, 0, 0.650923, 0.522608, 0.000868479, 0, 0.68254, 0.504484, 0.00082137, 0, 0.714286, 0.486603, 0.000772916, 0, 0.746032, 0.468802, 0.000730353, 0, 0.777778, 0.451172, 0.000684955, 0, 0.809524, 0.434348, 0.000647565, 0, 0.84127, 0.417445, 0.000605863, 0, 0.873016, 0.401077, 0.000571885, 0, 0.904762, 0.385039, 0.000536034, 0, 0.936508, 0.369483, 0.000504227, 0, 0.968254, 0.354272, 0.000473165, 0, 1, 1, 0.000599525, 0, 0, 1, 0.000599533, 0, 0, 1, 0.000599639, 0, 0, 0.999998, 0.000600097, 0, 0, 0.999994, 0.000601336, 0, 0, 0.999987, 0.000603958, 0, 0, 0.999972, 0.000608775, 0, 0, 0.999949, 0.000616842, 0, 0, 0.999912, 0.000629534, 0, 0, 0.999857, 0.000648658, 0, 0, 0.999781, 0.000676615, 0, 5.38873e-06, 0.999674, 0.000716574, 0, 0.000308602, 0.999528, 0.000772641, 0, 0.00127003, 0.999326, 0.000849806, 0, 0.00300783, 0.999009, 0.000952682, 0, 0.00556637, 0.998112, 0.00106394, 0, 0.00895889, 0.994496, 0.00102228, 0, 0.0131827, 0.992806, 0.00108586, 0, 0.0182277, 0.991211, 0.0011759, 0, 0.0240795, 0.989415, 0.00128955, 0, 0.030723, 0.986499, 0.00139038, 0, 0.0381418, 0.982679, 0.00144539, 0, 0.046321, 0.978839, 0.00153954, 0, 0.0552459, 0.974295, 0.00164417, 0, 0.0649034, 0.968784, 0.00171517, 0, 0.0752814, 0.962324, 0.00180282, 0, 0.0863693, 0.954956, 0.00186387, 0, 0.0981578, 0.94624, 0.00193817, 0, 0.110639, 0.936517, 0.00198156, 0, 0.123806, 0.925186, 0.00203042, 0, 0.137655, 0.91252, 0.0020664, 0, 0.15218, 0.898441, 0.00207822, 0, 0.16738, 0.884394, 0.0020992, 0, 0.183253, 0.871273, 0.00208748, 0, 0.199799, 0.859057, 0.00208686, 0, 0.21702, 0.845243, 0.00205519, 0, 0.234918, 0.830723, 0.00202868, 0, 0.253496, 0.815801, 0.00199501, 0, 0.272761, 0.79914, 0.00194193, 0, 0.292719, 0.782372, 0.00188824, 0, 0.313377, 0.76482, 0.00183695, 0, 0.334745, 0.746586, 0.00177418, 0, 0.356833, 0.7281, 0.00170628, 0, 0.379654, 0.709842, 0.00164063, 0, 0.403221, 0.692019, 0.00157355, 0, 0.427548, 0.67364, 0.00150262, 0, 0.452651, 0.655277, 0.00143473, 0, 0.478545, 0.636438, 0.00136371, 0, 0.505246, 0.617364, 0.00129911, 0, 0.532768, 0.598603, 0.00123014, 0, 0.561122, 0.580195, 0.00116587, 0, 0.590309, 0.561786, 0.00110398, 0, 0.620318, 0.543377, 0.00104148, 0, 0.651102, 0.525093, 0.000983984, 0, 0.682545, 0.506791, 0.00092667, 0, 0.714286, 0.489291, 0.000874326, 0, 0.746032, 0.471811, 0.000821734, 0, 0.777778, 0.454435, 0.000774698, 0, 0.809524, 0.437493, 0.000727302, 0, 0.84127, 0.420977, 0.000684039, 0, 0.873016, 0.404729, 0.00064373, 0, 0.904762, 0.388756, 0.00060285, 0, 0.936508, 0.373344, 0.00056765, 0, 0.968254, 0.358191, 0.000531929, 0, 1, 1, 0.000832169, 0, 0, 1, 0.000832178, 0, 0, 1, 0.00083231, 0, 0, 0.999998, 0.000832893, 0, 0, 0.999995, 0.000834465, 0, 0, 0.999985, 0.000837791, 0, 0, 0.999969, 0.000843893, 0, 0, 0.999944, 0.000854086, 0, 0, 0.999903, 0.000870071, 0, 0, 0.999843, 0.000894042, 0, 0, 0.999759, 0.000928865, 0, 5.31805e-05, 0.999643, 0.000978242, 0, 0.000579365, 0.99948, 0.00104684, 0, 0.00182774, 0.999255, 0.00114012, 0, 0.00387804, 0.998885, 0.00126188, 0, 0.00675709, 0.997405, 0.00135888, 0, 0.010468, 0.99424, 0.00133626, 0, 0.0150018, 0.992458, 0.00140905, 0, 0.0203443, 0.990929, 0.00152305, 0, 0.0264786, 0.989116, 0.00165882, 0, 0.0333875, 0.985624, 0.00174128, 0, 0.0410536, 0.982003, 0.00182108, 0, 0.0494609, 0.978336, 0.00194498, 0, 0.0585941, 0.973184, 0.00202708, 0, 0.0684396, 0.9678, 0.00212166, 0, 0.0789851, 0.961348, 0.00221366, 0, 0.0902199, 0.953841, 0.00228219, 0, 0.102134, 0.94534, 0.00235662, 0, 0.114721, 0.935552, 0.00240572, 0, 0.127972, 0.924064, 0.00244405, 0, 0.141884, 0.911827, 0.00247557, 0, 0.156451, 0.897731, 0.00248374, 0, 0.171672, 0.883409, 0.00249863, 0, 0.187545, 0.868625, 0.00246688, 0, 0.20407, 0.856529, 0.00246523, 0, 0.221249, 0.842999, 0.00242368, 0, 0.239083, 0.828505, 0.00237354, 0, 0.257578, 0.813825, 0.00232588, 0, 0.276738, 0.797813, 0.00226731, 0, 0.296569, 0.781097, 0.00219704, 0, 0.31708, 0.764038, 0.00212394, 0, 0.338281, 0.746067, 0.00204786, 0, 0.360181, 0.727687, 0.00196728, 0, 0.382794, 0.709571, 0.00188779, 0, 0.406133, 0.691503, 0.00180532, 0, 0.430213, 0.673673, 0.00171849, 0, 0.45505, 0.655732, 0.00164147, 0, 0.480662, 0.637399, 0.00155858, 0, 0.507065, 0.618616, 0.00147641, 0, 0.534278, 0.60005, 0.00140125, 0, 0.562313, 0.581713, 0.00132441, 0, 0.59118, 0.563546, 0.00125014, 0, 0.620875, 0.545605, 0.00118249, 0, 0.651373, 0.527559, 0.0011116, 0, 0.682593, 0.509764, 0.00104979, 0, 0.714286, 0.49193, 0.000985977, 0, 0.746032, 0.475011, 0.000928592, 0, 0.777778, 0.457878, 0.000873466, 0, 0.809524, 0.440979, 0.000819585, 0, 0.84127, 0.424613, 0.000772365, 0, 0.873016, 0.408549, 0.000722195, 0, 0.904762, 0.392771, 0.000680014, 0, 0.936508, 0.377317, 0.000636797, 0, 0.968254, 0.362352, 0.000598318, 0, 1, 1, 0.00114313, 0, 0, 1, 0.00114314, 0, 0, 0.999999, 0.00114331, 0, 0, 0.999998, 0.00114404, 0, 0, 0.999994, 0.00114601, 0, 0, 0.999984, 0.00115019, 0, 0, 0.999967, 0.00115784, 0, 0, 0.999937, 0.0011706, 0, 0, 0.999894, 0.00119054, 0, 0, 0.999828, 0.00122031, 0, 0, 0.999735, 0.00126331, 0, 0.000169263, 0.999606, 0.00132382, 0, 0.000949167, 0.999426, 0.0014071, 0, 0.00249668, 0.999173, 0.00151895, 0, 0.00486392, 0.99873, 0.00166102, 0, 0.00806323, 0.996243, 0.0017023, 0, 0.0120895, 0.993779, 0.00172782, 0, 0.0169288, 0.9919, 0.0018108, 0, 0.0225633, 0.990524, 0.00196028, 0, 0.028974, 0.98868, 0.00212014, 0, 0.036142, 0.984663, 0.00217598, 0, 0.044049, 0.981457, 0.00230563, 0, 0.0526781, 0.977608, 0.00243966, 0, 0.0620137, 0.972215, 0.00251336, 0, 0.0720418, 0.966798, 0.0026285, 0, 0.0827499, 0.960241, 0.00271409, 0, 0.0941271, 0.952489, 0.00278381, 0, 0.106164, 0.944127, 0.00285399, 0, 0.118852, 0.934282, 0.00290994, 0, 0.132185, 0.923271, 0.00294558, 0, 0.146157, 0.910803, 0.00296269, 0, 0.160766, 0.896705, 0.00296803, 0, 0.176007, 0.88238, 0.00296637, 0, 0.19188, 0.867116, 0.00293163, 0, 0.208385, 0.853636, 0.00289418, 0, 0.225523, 0.840469, 0.00284663, 0, 0.243296, 0.82639, 0.00278594, 0, 0.261709, 0.811759, 0.00271618, 0, 0.280767, 0.796113, 0.00263187, 0, 0.300476, 0.779518, 0.00254589, 0, 0.320845, 0.763142, 0.00246003, 0, 0.341883, 0.745464, 0.00236529, 0, 0.363601, 0.727491, 0.00226536, 0, 0.386011, 0.709414, 0.00216375, 0, 0.409128, 0.691396, 0.00207127, 0, 0.432967, 0.67368, 0.00197106, 0, 0.457545, 0.656049, 0.00187022, 0, 0.482881, 0.638188, 0.00177605, 0, 0.508992, 0.620177, 0.00168482, 0, 0.535899, 0.601506, 0.00158909, 0, 0.563619, 0.58362, 0.00150583, 0, 0.592165, 0.565496, 0.00141791, 0, 0.621544, 0.54789, 0.00133693, 0, 0.651743, 0.530323, 0.00126038, 0, 0.682709, 0.512795, 0.00118556, 0, 0.714286, 0.495199, 0.00111527, 0, 0.746032, 0.478101, 0.0010489, 0, 0.777778, 0.461511, 0.000984264, 0, 0.809524, 0.444879, 0.00092591, 0, 0.84127, 0.428424, 0.000866582, 0, 0.873016, 0.412495, 0.000814463, 0, 0.904762, 0.396975, 0.000764498, 0, 0.936508, 0.381614, 0.000715967, 0, 0.968254, 0.366732, 0.000672483, 0, 1, 1, 0.00155501, 0, 0, 1, 0.00155503, 0, 0, 1, 0.00155524, 0, 0, 0.999998, 0.00155615, 0, 0, 0.999994, 0.0015586, 0, 0, 0.999983, 0.00156379, 0, 0, 0.999963, 0.0015733, 0, 0, 0.999932, 0.00158911, 0, 0, 0.999882, 0.00161376, 0, 0, 0.99981, 0.00165041, 0, 1.00875e-05, 0.999708, 0.00170304, 0, 0.000367658, 0.999565, 0.00177658, 0, 0.0014234, 0.999368, 0.00187688, 0, 0.00327939, 0.999081, 0.00200989, 0, 0.00596629, 0.99852, 0.00217177, 0, 0.0094852, 0.99549, 0.0021745, 0, 0.013824, 0.993252, 0.00222357, 0, 0.0189642, 0.991727, 0.00235022, 0, 0.0248856, 0.989951, 0.00250561, 0, 0.0315669, 0.988029, 0.00268829, 0, 0.0389882, 0.984029, 0.0027496, 0, 0.0471302, 0.980683, 0.00289793, 0, 0.0559754, 0.976554, 0.00303315, 0, 0.0655081, 0.97139, 0.00313257, 0, 0.0757138, 0.965544, 0.00323656, 0, 0.08658, 0.95912, 0.00333432, 0, 0.0980954, 0.951183, 0.0034039, 0, 0.110251, 0.942974, 0.00347515, 0, 0.123038, 0.932642, 0.00350381, 0, 0.13645, 0.922158, 0.00354519, 0, 0.150482, 0.909404, 0.00353851, 0, 0.165129, 0.896071, 0.0035435, 0, 0.18039, 0.881206, 0.00349936, 0, 0.196263, 0.866077, 0.00347256, 0, 0.212748, 0.85093, 0.003415, 0, 0.229847, 0.837703, 0.00333367, 0, 0.247561, 0.823878, 0.003249, 0, 0.265895, 0.809449, 0.00316347, 0, 0.284854, 0.794379, 0.00306351, 0, 0.304445, 0.778138, 0.0029499, 0, 0.324675, 0.761997, 0.00284099, 0, 0.345555, 0.744938, 0.00272104, 0, 0.367095, 0.727212, 0.00260715, 0, 0.389309, 0.709549, 0.00248855, 0, 0.41221, 0.691704, 0.00236783, 0, 0.435814, 0.673689, 0.00225178, 0, 0.460138, 0.656453, 0.00213765, 0, 0.485203, 0.639128, 0.00202178, 0, 0.511028, 0.621512, 0.00191443, 0, 0.537634, 0.603598, 0.00180977, 0, 0.565041, 0.58559, 0.00170456, 0, 0.593268, 0.567852, 0.00160927, 0, 0.622327, 0.5503, 0.00151395, 0, 0.652217, 0.533033, 0.00142499, 0, 0.682907, 0.515942, 0.00133955, 0, 0.714296, 0.498814, 0.0012602, 0, 0.746032, 0.481595, 0.00118188, 0, 0.777778, 0.465117, 0.00111171, 0, 0.809524, 0.448865, 0.00104091, 0, 0.84127, 0.432711, 0.000976618, 0, 0.873016, 0.416822, 0.00091859, 0, 0.904762, 0.401272, 0.000857704, 0, 0.936508, 0.386226, 0.000807172, 0, 0.968254, 0.371321, 0.00075464, 0, 1, 1, 0.00209596, 0, 0, 1, 0.00209598, 0, 0, 1, 0.00209624, 0, 0, 0.999997, 0.00209736, 0, 0, 0.999991, 0.00210039, 0, 0, 0.999979, 0.00210678, 0, 0, 0.999959, 0.00211847, 0, 0, 0.999925, 0.0021379, 0, 0, 0.99987, 0.00216809, 0, 0, 0.999791, 0.00221281, 0, 6.81487e-05, 0.999677, 0.00227669, 0, 0.000658161, 0.999521, 0.00236533, 0, 0.00200635, 0.999301, 0.00248514, 0, 0.0041779, 0.998977, 0.00264185, 0, 0.00718648, 0.998191, 0.00281695, 0, 0.0110239, 0.994801, 0.00278518, 0, 0.015672, 0.993091, 0.00288774, 0, 0.0211091, 0.991571, 0.00303931, 0, 0.0273123, 0.9897, 0.00321643, 0, 0.034259, 0.987023, 0.00337332, 0, 0.0419282, 0.983289, 0.00346146, 0, 0.0502998, 0.979892, 0.00363704, 0, 0.0593562, 0.975111, 0.00373601, 0, 0.069081, 0.970351, 0.0038842, 0, 0.0794598, 0.964131, 0.00397053, 0, 0.0904798, 0.957747, 0.00408078, 0, 0.10213, 0.949536, 0.00413533, 0, 0.1144, 0.941372, 0.00420305, 0, 0.127284, 0.931049, 0.00422815, 0, 0.140772, 0.920647, 0.00425048, 0, 0.154862, 0.908033, 0.0042281, 0, 0.169548, 0.895028, 0.00422026, 0, 0.184828, 0.879968, 0.00415042, 0, 0.200701, 0.864875, 0.00408821, 0, 0.217167, 0.84918, 0.00400909, 0, 0.234227, 0.834934, 0.00391178, 0, 0.251884, 0.821397, 0.00380066, 0, 0.270141, 0.807135, 0.00367974, 0, 0.289004, 0.792363, 0.00355172, 0, 0.308479, 0.776661, 0.003411, 0, 0.328575, 0.760705, 0.00328123, 0, 0.349301, 0.744408, 0.00314003, 0, 0.370668, 0.726994, 0.0029906, 0, 0.392689, 0.709598, 0.00285034, 0, 0.415379, 0.692112, 0.00271179, 0, 0.438754, 0.674435, 0.00257185, 0, 0.46283, 0.65676, 0.00243425, 0, 0.48763, 0.639982, 0.00230351, 0, 0.513173, 0.622983, 0.0021777, 0, 0.539482, 0.605471, 0.00204991, 0, 0.566579, 0.58796, 0.00193759, 0, 0.594488, 0.570463, 0.00181976, 0, 0.623226, 0.553058, 0.00171497, 0, 0.6528, 0.535894, 0.00161109, 0, 0.683198, 0.519089, 0.00151394, 0, 0.714354, 0.502454, 0.00142122, 0, 0.746032, 0.485681, 0.00133488, 0, 0.777778, 0.468935, 0.00124975, 0, 0.809524, 0.452951, 0.00117309, 0, 0.84127, 0.437139, 0.00110155, 0, 0.873016, 0.421446, 0.00103124, 0, 0.904762, 0.405951, 0.000966387, 0, 0.936508, 0.391003, 0.000908119, 0, 0.968254, 0.376198, 0.000848057, 0, 1, 1, 0.00280076, 0, 0, 1, 0.00280078, 0, 0, 0.999999, 0.00280109, 0, 0, 0.999997, 0.00280246, 0, 0, 0.999992, 0.00280616, 0, 0, 0.999979, 0.00281396, 0, 0, 0.999956, 0.00282822, 0, 0, 0.999916, 0.00285186, 0, 0, 0.999857, 0.0028885, 0, 0, 0.999768, 0.00294259, 0, 0.000196026, 0.999645, 0.00301946, 0, 0.00104842, 0.99947, 0.00312541, 0, 0.00270199, 0.999229, 0.00326733, 0, 0.00519449, 0.998852, 0.00344992, 0, 0.00852602, 0.997558, 0.00361052, 0, 0.0126804, 0.994417, 0.0035898, 0, 0.017635, 0.992824, 0.00372393, 0, 0.023365, 0.991344, 0.00390695, 0, 0.0298456, 0.989337, 0.00410392, 0, 0.0370529, 0.985811, 0.00420987, 0, 0.0449651, 0.982772, 0.00437488, 0, 0.0535615, 0.979001, 0.00455069, 0, 0.0628243, 0.974102, 0.00464462, 0, 0.0727368, 0.969197, 0.00480577, 0, 0.0832844, 0.962759, 0.00487818, 0, 0.0944545, 0.956207, 0.00498176, 0, 0.106236, 0.947909, 0.00503392, 0, 0.118619, 0.939596, 0.00507474, 0, 0.131595, 0.929642, 0.00509798, 0, 0.145159, 0.918807, 0.00508476, 0, 0.159305, 0.906921, 0.00505634, 0, 0.174028, 0.893312, 0.00498845, 0, 0.189327, 0.878933, 0.0049133, 0, 0.2052, 0.863986, 0.0048259, 0, 0.221647, 0.847936, 0.00470848, 0, 0.23867, 0.832253, 0.00456889, 0, 0.25627, 0.818619, 0.00442726, 0, 0.274453, 0.804788, 0.00427677, 0, 0.293222, 0.790241, 0.00411906, 0, 0.312585, 0.775162, 0.00394833, 0, 0.33255, 0.759463, 0.00377366, 0, 0.353126, 0.743598, 0.00361026, 0, 0.374324, 0.72697, 0.00343627, 0, 0.396158, 0.709646, 0.00326422, 0, 0.418641, 0.69277, 0.00309717, 0, 0.44179, 0.675371, 0.0029356, 0, 0.465624, 0.657863, 0.00277712, 0, 0.490163, 0.640772, 0.00261738, 0, 0.515429, 0.624441, 0.0024737, 0, 0.541445, 0.607497, 0.00233125, 0, 0.568236, 0.590438, 0.00218994, 0, 0.595828, 0.573224, 0.0020664, 0, 0.624242, 0.556168, 0.00193526, 0, 0.653496, 0.539232, 0.00182463, 0, 0.683588, 0.522352, 0.00170735, 0, 0.714482, 0.506172, 0.00160555, 0, 0.746032, 0.489842, 0.00150451, 0, 0.777778, 0.473463, 0.00140938, 0, 0.809524, 0.457266, 0.00132568, 0, 0.84127, 0.441609, 0.0012376, 0, 0.873016, 0.426348, 0.00116265, 0, 0.904762, 0.411002, 0.00108935, 0, 0.936508, 0.396045, 0.00101946, 0, 0.968254, 0.381448, 0.000955665, 0, 1, 1, 0.0037121, 0, 0, 1, 0.00371213, 0, 0, 1, 0.00371251, 0, 0, 0.999997, 0.00371417, 0, 0, 0.99999, 0.00371863, 0, 0, 0.999977, 0.00372807, 0, 0, 0.99995, 0.00374529, 0, 0, 0.999908, 0.0037738, 0, 0, 0.999843, 0.00381789, 0, 1.23596e-05, 0.999745, 0.00388273, 0, 0.000407442, 0.999608, 0.00397443, 0, 0.0015447, 0.999415, 0.00409998, 0, 0.00351385, 0.999143, 0.00426662, 0, 0.0063316, 0.9987, 0.00447625, 0, 0.00998679, 0.996363, 0.00455323, 0, 0.0144569, 0.994021, 0.00461052, 0, 0.0197151, 0.992372, 0.00476359, 0, 0.0257344, 0.991007, 0.00499101, 0, 0.0324882, 0.988767, 0.0051972, 0, 0.0399517, 0.984872, 0.00528407, 0, 0.0481022, 0.982004, 0.00548926, 0, 0.0569191, 0.977714, 0.00564385, 0, 0.0663839, 0.973076, 0.0057693, 0, 0.0764801, 0.967565, 0.0058924, 0, 0.0871928, 0.961384, 0.00599629, 0, 0.0985095, 0.954435, 0.00605998, 0, 0.110419, 0.946303, 0.0061133, 0, 0.122912, 0.937662, 0.00612028, 0, 0.13598, 0.927867, 0.00612209, 0, 0.149617, 0.916475, 0.00604813, 0, 0.163817, 0.90541, 0.00603088, 0, 0.178577, 0.891591, 0.00592218, 0, 0.193894, 0.877573, 0.00578854, 0, 0.209767, 0.862511, 0.00566648, 0, 0.226196, 0.846861, 0.00551481, 0, 0.243182, 0.83068, 0.00533754, 0, 0.260728, 0.815725, 0.00515487, 0, 0.278837, 0.802321, 0.0049655, 0, 0.297515, 0.787826, 0.00475421, 0, 0.316768, 0.773454, 0.00456002, 0, 0.336605, 0.758224, 0.00434727, 0, 0.357034, 0.74265, 0.00414444, 0, 0.378067, 0.726729, 0.00393738, 0, 0.399717, 0.710155, 0.00373575, 0, 0.421998, 0.693312, 0.00353736, 0, 0.444928, 0.67653, 0.00334368, 0, 0.468523, 0.659444, 0.00315981, 0, 0.492806, 0.642051, 0.00297809, 0, 0.517798, 0.625758, 0.00280592, 0, 0.543525, 0.609615, 0.00264254, 0, 0.570012, 0.592919, 0.00248459, 0, 0.597288, 0.576298, 0.00233327, 0, 0.625379, 0.559489, 0.00219519, 0, 0.654307, 0.542891, 0.00205441, 0, 0.684084, 0.526255, 0.00193385, 0, 0.714693, 0.509853, 0.00180745, 0, 0.746044, 0.494131, 0.00169817, 0, 0.777778, 0.478114, 0.0015913, 0, 0.809524, 0.462274, 0.00148981, 0, 0.84127, 0.446412, 0.00139537, 0, 0.873016, 0.431274, 0.00130984, 0, 0.904762, 0.41635, 0.00122403, 0, 0.936508, 0.401476, 0.00114809, 0, 0.968254, 0.386993, 0.00107563, 0, 1, 1, 0.00488216, 0, 0, 1, 0.0048822, 0, 0, 1, 0.00488265, 0, 0, 0.999997, 0.00488463, 0, 0, 0.999988, 0.00488999, 0, 0, 0.999974, 0.00490129, 0, 0, 0.999946, 0.00492191, 0, 0, 0.999897, 0.00495598, 0, 0, 0.999825, 0.00500855, 0, 7.44791e-05, 0.999718, 0.00508559, 0, 0.000712744, 0.999565, 0.005194, 0, 0.00215249, 0.999352, 0.00534147, 0, 0.00444576, 0.999046, 0.00553523, 0, 0.00759218, 0.998492, 0.00577016, 0, 0.0115714, 0.995564, 0.00578487, 0, 0.0163557, 0.993339, 0.00586414, 0, 0.021915, 0.991834, 0.00606002, 0, 0.0282201, 0.990496, 0.00633312, 0, 0.0352433, 0.987826, 0.00651941, 0, 0.042959, 0.98383, 0.00660842, 0, 0.0513439, 0.98109, 0.00685523, 0, 0.0603772, 0.976131, 0.00695778, 0, 0.0700402, 0.971922, 0.00714236, 0, 0.0803163, 0.965901, 0.00721437, 0, 0.0911908, 0.959606, 0.00732017, 0, 0.102651, 0.952504, 0.00735788, 0, 0.114686, 0.944365, 0.00738493, 0, 0.127286, 0.935652, 0.00737969, 0, 0.140443, 0.925813, 0.00733612, 0, 0.154151, 0.914397, 0.00723094, 0, 0.168405, 0.903257, 0.00714002, 0, 0.183201, 0.890015, 0.00700149, 0, 0.198536, 0.876014, 0.00682813, 0, 0.214409, 0.861436, 0.00665567, 0, 0.23082, 0.845752, 0.00644526, 0, 0.24777, 0.829169, 0.00621635, 0, 0.265263, 0.813435, 0.00597789, 0, 0.283301, 0.799701, 0.00575694, 0, 0.301889, 0.785726, 0.00549866, 0, 0.321035, 0.77152, 0.0052503, 0, 0.340746, 0.75683, 0.00499619, 0, 0.361032, 0.741951, 0.0047543, 0, 0.381904, 0.726367, 0.0045084, 0, 0.403374, 0.710537, 0.00426784, 0, 0.425457, 0.693965, 0.00403487, 0, 0.448169, 0.677724, 0.0038075, 0, 0.47153, 0.66117, 0.00359431, 0, 0.495561, 0.644274, 0.00338354, 0, 0.520284, 0.627449, 0.00318163, 0, 0.545725, 0.611645, 0.00299672, 0, 0.571911, 0.595614, 0.00281016, 0, 0.598873, 0.579426, 0.00264252, 0, 0.62664, 0.563016, 0.00247509, 0, 0.655239, 0.546728, 0.00232647, 0, 0.684692, 0.530539, 0.00217803, 0, 0.714999, 0.514164, 0.00204216, 0, 0.746106, 0.498344, 0.00191403, 0, 0.777778, 0.482957, 0.00179203, 0, 0.809524, 0.467336, 0.00167695, 0, 0.84127, 0.451994, 0.00157567, 0, 0.873016, 0.436514, 0.00147113, 0, 0.904762, 0.42178, 0.00138034, 0, 0.936508, 0.407271, 0.00129219, 0, 0.968254, 0.392822, 0.0012098, 0, 1, 1, 0.00637427, 0, 0, 1, 0.00637431, 0, 0, 0.999999, 0.00637485, 0, 0, 0.999996, 0.00637721, 0, 0, 0.999987, 0.00638357, 0, 0, 0.999971, 0.006397, 0, 0, 0.999939, 0.00642142, 0, 0, 0.999888, 0.00646177, 0, 0, 0.999807, 0.00652387, 0, 0.000207916, 0.999689, 0.00661454, 0, 0.00112051, 0.99952, 0.00674155, 0, 0.00287719, 0.999283, 0.00691313, 0, 0.00550145, 0.998936, 0.00713598, 0, 0.00897928, 0.998165, 0.00738501, 0, 0.0132829, 0.994847, 0.00734388, 0, 0.01838, 0.993182, 0.00749991, 0, 0.0242381, 0.991665, 0.0077246, 0, 0.030826, 0.989708, 0.00797579, 0, 0.0381152, 0.986663, 0.00813011, 0, 0.0460794, 0.983288, 0.00830365, 0, 0.0546951, 0.980104, 0.00853496, 0, 0.0639411, 0.974855, 0.00861045, 0, 0.0737988, 0.97045, 0.00879133, 0, 0.0842516, 0.964509, 0.00886377, 0, 0.0952848, 0.957594, 0.00890346, 0, 0.106886, 0.950546, 0.00893289, 0, 0.119044, 0.942225, 0.00890074, 0, 0.131749, 0.933365, 0.00886826, 0, 0.144994, 0.923202, 0.0087316, 0, 0.158772, 0.912605, 0.00863082, 0, 0.173078, 0.901099, 0.00847403, 0, 0.187908, 0.888177, 0.00825838, 0, 0.203261, 0.873955, 0.00801834, 0, 0.219134, 0.860091, 0.00779026, 0, 0.235527, 0.84434, 0.00752478, 0, 0.252443, 0.828517, 0.00724074, 0, 0.269883, 0.81239, 0.00693769, 0, 0.287851, 0.79721, 0.00664817, 0, 0.306352, 0.783489, 0.00634763, 0, 0.325393, 0.769514, 0.00604221, 0, 0.344981, 0.755419, 0.00573568, 0, 0.365126, 0.741083, 0.00544359, 0, 0.385839, 0.726059, 0.00515515, 0, 0.407132, 0.710809, 0.00487139, 0, 0.42902, 0.695052, 0.00459846, 0, 0.45152, 0.678886, 0.00433412, 0, 0.474651, 0.663042, 0.00407981, 0, 0.498433, 0.646634, 0.00384264, 0, 0.52289, 0.630117, 0.00360897, 0, 0.548048, 0.613804, 0.00338863, 0, 0.573936, 0.598338, 0.00318486, 0, 0.600584, 0.582687, 0.00298377, 0, 0.628027, 0.566809, 0.00280082, 0, 0.656295, 0.550817, 0.00262255, 0, 0.685417, 0.534937, 0.00245835, 0, 0.715406, 0.519151, 0.00230574, 0, 0.74624, 0.503118, 0.0021549, 0, 0.777778, 0.487723, 0.00202008, 0, 0.809524, 0.472725, 0.00189355, 0, 0.84127, 0.457599, 0.00177108, 0, 0.873016, 0.442558, 0.00165843, 0, 0.904762, 0.427624, 0.00155494, 0, 0.936508, 0.413171, 0.00145273, 0, 0.968254, 0.399122, 0.00136454, 0, 1, 1, 0.00826496, 0, 0, 1, 0.00826499, 0, 0, 1, 0.00826564, 0, 0, 0.999996, 0.00826842, 0, 0, 0.999987, 0.00827589, 0, 0, 0.999967, 0.00829167, 0, 0, 0.999933, 0.00832037, 0, 0, 0.999876, 0.00836768, 0, 1.09338e-05, 0.999786, 0.00844031, 0, 0.000427145, 0.999655, 0.00854603, 0, 0.0016384, 0.999468, 0.00869337, 0, 0.00372392, 0.999203, 0.008891, 0, 0.00668513, 0.998803, 0.00914387, 0, 0.0104968, 0.99748, 0.00935838, 0, 0.015125, 0.994446, 0.00933309, 0, 0.0205338, 0.99292, 0.00953084, 0, 0.0266884, 0.991414, 0.0097893, 0, 0.0335565, 0.989049, 0.0100228, 0, 0.0411086, 0.98582, 0.0101664, 0, 0.0493181, 0.982441, 0.0103582, 0, 0.0581613, 0.978595, 0.0105292, 0, 0.0676169, 0.973495, 0.0106274, 0, 0.0776661, 0.968405, 0.0107261, 0, 0.0882926, 0.962717, 0.0108234, 0, 0.0994817, 0.955478, 0.0108102, 0, 0.111221, 0.948275, 0.0107914, 0, 0.123499, 0.940006, 0.0107161, 0, 0.136308, 0.930831, 0.0106309, 0, 0.149639, 0.920648, 0.0104083, 0, 0.163485, 0.910205, 0.0102312, 0, 0.177843, 0.898445, 0.0100051, 0, 0.192707, 0.885986, 0.00971928, 0, 0.208077, 0.872204, 0.00940747, 0, 0.22395, 0.858436, 0.0091085, 0, 0.240326, 0.843454, 0.00876595, 0, 0.257208, 0.827437, 0.00839794, 0, 0.274596, 0.811488, 0.00803692, 0, 0.292496, 0.796039, 0.00767352, 0, 0.310911, 0.781083, 0.0073097, 0, 0.329849, 0.767642, 0.00694032, 0, 0.349316, 0.753901, 0.00657476, 0, 0.369323, 0.740131, 0.00622699, 0, 0.38988, 0.725845, 0.0058838, 0, 0.410999, 0.710991, 0.00555586, 0, 0.432696, 0.696002, 0.00523089, 0, 0.454987, 0.680461, 0.00492494, 0, 0.47789, 0.664875, 0.00463464, 0, 0.501426, 0.649273, 0.00435422, 0, 0.52562, 0.63302, 0.0040875, 0, 0.550498, 0.61705, 0.00384075, 0, 0.576089, 0.601154, 0.00359557, 0, 0.602427, 0.586008, 0.00337636, 0, 0.629544, 0.570699, 0.00316019, 0, 0.657479, 0.555166, 0.00296033, 0, 0.686264, 0.539645, 0.00277552, 0, 0.715924, 0.524159, 0.00259499, 0, 0.746459, 0.508682, 0.00243257, 0, 0.777789, 0.493163, 0.00227851, 0, 0.809524, 0.478004, 0.00213083, 0, 0.84127, 0.46347, 0.00199502, 0, 0.873016, 0.448778, 0.00186967, 0, 0.904762, 0.434105, 0.00174732, 0, 0.936508, 0.419576, 0.00163861, 0, 0.968254, 0.405541, 0.00153341, 0, 1, 1, 0.0106462, 0, 0, 1, 0.0106462, 0, 0, 0.999999, 0.010647, 0, 0, 0.999995, 0.0106502, 0, 0, 0.999985, 0.0106589, 0, 0, 0.999964, 0.0106773, 0, 0, 0.999925, 0.0107106, 0, 0, 0.999861, 0.0107655, 0, 7.12986e-05, 0.999763, 0.0108497, 0, 0.000743959, 0.999616, 0.0109716, 0, 0.00227361, 0.999408, 0.0111408, 0, 0.0046983, 0.999112, 0.0113659, 0, 0.00800158, 0.998637, 0.0116475, 0, 0.0121493, 0.996223, 0.0117231, 0, 0.0171023, 0.994006, 0.0118064, 0, 0.0228218, 0.992444, 0.0120254, 0, 0.0292711, 0.991028, 0.0123314, 0, 0.036417, 0.98803, 0.0124954, 0, 0.0442295, 0.984816, 0.0126538, 0, 0.0526815, 0.981399, 0.0128537, 0, 0.0617492, 0.977085, 0.0129694, 0, 0.0714114, 0.972154, 0.013091, 0, 0.0816495, 0.966617, 0.0131166, 0, 0.0924472, 0.960628, 0.0131583, 0, 0.10379, 0.953295, 0.0131094, 0, 0.115665, 0.94575, 0.0129966, 0, 0.128062, 0.937654, 0.0128796, 0, 0.140972, 0.927716, 0.0126477, 0, 0.154387, 0.917932, 0.0123889, 0, 0.168301, 0.907719, 0.012131, 0, 0.182709, 0.89584, 0.0118013, 0, 0.197608, 0.883526, 0.0114145, 0, 0.212994, 0.870301, 0.0110075, 0, 0.228867, 0.856272, 0.0106019, 0, 0.245227, 0.842251, 0.0101938, 0, 0.262074, 0.826466, 0.00973254, 0, 0.279412, 0.810859, 0.0092846, 0, 0.297244, 0.795051, 0.00883304, 0, 0.315575, 0.780053, 0.00840272, 0, 0.334412, 0.76575, 0.00796438, 0, 0.35376, 0.752298, 0.00752526, 0, 0.373631, 0.739153, 0.00711486, 0, 0.394034, 0.725514, 0.00670361, 0, 0.414983, 0.711473, 0.00632656, 0, 0.436491, 0.696936, 0.00595206, 0, 0.458575, 0.682126, 0.00559191, 0, 0.481253, 0.667027, 0.00525362, 0, 0.504547, 0.651875, 0.00493805, 0, 0.528481, 0.636463, 0.00462848, 0, 0.553081, 0.620641, 0.00433936, 0, 0.578377, 0.604931, 0.00407, 0, 0.604404, 0.589549, 0.00380864, 0, 0.631197, 0.574712, 0.00357049, 0, 0.658795, 0.559775, 0.00334466, 0, 0.687238, 0.544514, 0.00312505, 0, 0.716559, 0.529555, 0.00293199, 0, 0.746776, 0.514402, 0.00274204, 0, 0.777849, 0.499302, 0.00256647, 0, 0.809524, 0.484114, 0.00239901, 0, 0.84127, 0.469308, 0.00225148, 0, 0.873016, 0.455133, 0.00210178, 0, 0.904762, 0.440939, 0.0019727, 0, 0.936508, 0.426627, 0.00184382, 0, 0.968254, 0.412509, 0.00172548, 0, 1, 1, 0.013628, 0, 0, 1, 0.0136281, 0, 0, 0.999999, 0.0136289, 0, 0, 0.999995, 0.0136327, 0, 0, 0.999983, 0.0136427, 0, 0, 0.99996, 0.0136638, 0, 0, 0.999917, 0.0137022, 0, 0, 0.999846, 0.0137652, 0, 0.000204597, 0.999736, 0.0138615, 0, 0.00116837, 0.999573, 0.0140007, 0, 0.00303325, 0.99934, 0.0141927, 0, 0.00580613, 0.999004, 0.0144457, 0, 0.00945626, 0.998407, 0.0147489, 0, 0.0139421, 0.995464, 0.014731, 0, 0.0192202, 0.993328, 0.0148283, 0, 0.0252495, 0.991799, 0.0150797, 0, 0.0319921, 0.990397, 0.0154316, 0, 0.0394138, 0.986835, 0.0155005, 0, 0.0474843, 0.983938, 0.0157308, 0, 0.0561763, 0.980154, 0.0158753, 0, 0.0654661, 0.975659, 0.0159581, 0, 0.0753326, 0.970171, 0.0159832, 0, 0.0857571, 0.964803, 0.0160084, 0, 0.0967236, 0.958366, 0.0159484, 0, 0.108218, 0.950613, 0.0158001, 0, 0.120227, 0.942874, 0.0155845, 0, 0.132741, 0.935005, 0.0154292, 0, 0.145751, 0.924991, 0.0150742, 0, 0.159249, 0.914814, 0.0146757, 0, 0.17323, 0.904743, 0.0143097, 0, 0.187687, 0.893216, 0.0138695, 0, 0.202619, 0.880769, 0.0133706, 0, 0.218021, 0.868136, 0.0128606, 0, 0.233894, 0.85469, 0.0123403, 0, 0.250238, 0.840593, 0.0118091, 0, 0.267052, 0.825808, 0.011253, 0, 0.284341, 0.81009, 0.0107099, 0, 0.302106, 0.79504, 0.0101636, 0, 0.320354, 0.779757, 0.00964041, 0, 0.33909, 0.764697, 0.00911896, 0, 0.358322, 0.750913, 0.00859533, 0, 0.378059, 0.738175, 0.00811592, 0, 0.398311, 0.725242, 0.00764504, 0, 0.41909, 0.711864, 0.00718885, 0, 0.440412, 0.698009, 0.00675843, 0, 0.462292, 0.683841, 0.00634984, 0, 0.484748, 0.669391, 0.00595502, 0, 0.507802, 0.654731, 0.00558671, 0, 0.531477, 0.639805, 0.00523578, 0, 0.555802, 0.624789, 0.00490834, 0, 0.580805, 0.609325, 0.00459448, 0, 0.606522, 0.593975, 0.00430342, 0, 0.63299, 0.578983, 0.00403019, 0, 0.66025, 0.564442, 0.0037707, 0, 0.688346, 0.549835, 0.0035316, 0, 0.717319, 0.535039, 0.00330255, 0, 0.7472, 0.520403, 0.00308932, 0, 0.777982, 0.505687, 0.00289335, 0, 0.809524, 0.490939, 0.00270818, 0, 0.84127, 0.476233, 0.0025343, 0, 0.873016, 0.461624, 0.00237097, 0, 0.904762, 0.447833, 0.00222065, 0, 0.936508, 0.433992, 0.00207561, 0, 0.968254, 0.420147, 0.00194955, 0, 1, 1, 0.0173415, 0, 0, 1, 0.0173416, 0, 0, 0.999999, 0.0173426, 0, 0, 0.999995, 0.0173468, 0, 0, 0.999983, 0.0173582, 0, 0, 0.999954, 0.0173822, 0, 0, 0.999908, 0.0174258, 0, 6.69501e-06, 0.999828, 0.0174973, 0, 0.000427399, 0.999705, 0.0176063, 0, 0.00171019, 0.999524, 0.0177631, 0, 0.0039248, 0.999263, 0.0179781, 0, 0.00705382, 0.998878, 0.018258, 0, 0.0110552, 0.998012, 0.0185551, 0, 0.0158812, 0.994614, 0.0184264, 0, 0.0214852, 0.993132, 0.0186385, 0, 0.0278239, 0.991563, 0.0189067, 0, 0.0348585, 0.989298, 0.0191577, 0, 0.0425544, 0.986036, 0.0192522, 0, 0.050881, 0.982558, 0.0194063, 0, 0.059811, 0.978531, 0.019486, 0, 0.0693209, 0.974198, 0.0195847, 0, 0.0793895, 0.968148, 0.0194749, 0, 0.0899984, 0.962565, 0.0194277, 0, 0.101132, 0.956041, 0.0192991, 0, 0.112775, 0.947749, 0.0189893, 0, 0.124917, 0.94018, 0.018704, 0, 0.137547, 0.93165, 0.0183458, 0, 0.150655, 0.921798, 0.0178775, 0, 0.164236, 0.911573, 0.0173618, 0, 0.178281, 0.901569, 0.0168482, 0, 0.192788, 0.890341, 0.016265, 0, 0.207752, 0.877835, 0.0156199, 0, 0.223171, 0.865472, 0.0149516, 0, 0.239044, 0.852905, 0.0143274, 0, 0.255371, 0.838906, 0.0136643, 0, 0.272153, 0.824888, 0.0129903, 0, 0.289393, 0.809977, 0.0123218, 0, 0.307093, 0.794697, 0.0116572, 0, 0.325259, 0.780028, 0.0110307, 0, 0.343896, 0.765124, 0.0104236, 0, 0.363012, 0.750411, 0.0098219, 0, 0.382617, 0.737264, 0.00924397, 0, 0.402719, 0.724799, 0.00868719, 0, 0.423332, 0.712253, 0.00816476, 0, 0.444469, 0.699267, 0.00767262, 0, 0.466146, 0.685618, 0.00719746, 0, 0.488383, 0.671736, 0.00673916, 0, 0.511199, 0.657777, 0.00631937, 0, 0.534618, 0.643497, 0.00592411, 0, 0.558668, 0.62889, 0.00553928, 0, 0.58338, 0.614299, 0.0051934, 0, 0.608787, 0.599197, 0.00485985, 0, 0.634929, 0.584175, 0.00454357, 0, 0.661849, 0.569541, 0.00425787, 0, 0.689594, 0.555193, 0.00397905, 0, 0.718211, 0.540947, 0.00372364, 0, 0.747742, 0.526593, 0.00348599, 0, 0.778205, 0.512335, 0.00326103, 0, 0.80953, 0.498017, 0.00305137, 0, 0.84127, 0.483609, 0.00285485, 0, 0.873016, 0.469368, 0.00267472, 0, 0.904762, 0.455037, 0.00249945, 0, 0.936508, 0.441493, 0.00234792, 0, 0.968254, 0.428147, 0.00219936, 0, 1, 1, 0.0219422, 0, 0, 1, 0.0219423, 0, 0, 0.999998, 0.0219434, 0, 0, 0.999993, 0.0219481, 0, 0, 0.999981, 0.021961, 0, 0, 0.999949, 0.0219879, 0, 0, 0.999896, 0.0220367, 0, 5.93194e-05, 0.999808, 0.0221167, 0, 0.00075364, 0.99967, 0.0222383, 0, 0.00237884, 0.999466, 0.0224125, 0, 0.00495612, 0.999174, 0.0226495, 0, 0.00844887, 0.998725, 0.0229525, 0, 0.0128058, 0.996979, 0.0231123, 0, 0.0179742, 0.994317, 0.0230742, 0, 0.0239047, 0.992781, 0.0232895, 0, 0.0305526, 0.991191, 0.0235734, 0, 0.0378786, 0.987787, 0.0236152, 0, 0.0458475, 0.985092, 0.0237994, 0, 0.0544287, 0.981121, 0.0238553, 0, 0.0635952, 0.976924, 0.0238706, 0, 0.0733233, 0.97218, 0.0238704, 0, 0.0835922, 0.965956, 0.0236598, 0, 0.0943839, 0.959998, 0.0234735, 0, 0.105682, 0.953245, 0.0232277, 0, 0.117474, 0.944445, 0.0226973, 0, 0.129747, 0.937087, 0.0223527, 0, 0.142491, 0.928341, 0.0218144, 0, 0.155697, 0.9184, 0.0211516, 0, 0.169358, 0.907959, 0.0204553, 0, 0.183469, 0.89808, 0.0197673, 0, 0.198024, 0.887047, 0.0189915, 0, 0.21302, 0.875221, 0.0182082, 0, 0.228455, 0.86269, 0.0173584, 0, 0.244329, 0.850735, 0.0165718, 0, 0.260639, 0.837545, 0.0157524, 0, 0.277389, 0.823639, 0.0149482, 0, 0.29458, 0.809699, 0.0141431, 0, 0.312216, 0.794797, 0.0133527, 0, 0.3303, 0.780578, 0.0126193, 0, 0.34884, 0.766019, 0.0118914, 0, 0.367842, 0.751447, 0.0111839, 0, 0.387315, 0.737275, 0.010514, 0, 0.40727, 0.724545, 0.00987277, 0, 0.427717, 0.712644, 0.00926569, 0, 0.448671, 0.700432, 0.00869029, 0, 0.470149, 0.687664, 0.00814691, 0, 0.492167, 0.674288, 0.00763012, 0, 0.514746, 0.660966, 0.00714437, 0, 0.537911, 0.647264, 0.00668457, 0, 0.561688, 0.633431, 0.00626581, 0, 0.586108, 0.619133, 0.00585593, 0, 0.611206, 0.604935, 0.00548188, 0, 0.637022, 0.590236, 0.00513288, 0, 0.663599, 0.575473, 0.0047906, 0, 0.690989, 0.561228, 0.00448895, 0, 0.719242, 0.547054, 0.00420233, 0, 0.748411, 0.533175, 0.00392869, 0, 0.778531, 0.519163, 0.00367445, 0, 0.809583, 0.505328, 0.00344097, 0, 0.84127, 0.491446, 0.00322003, 0, 0.873016, 0.477356, 0.00301283, 0, 0.904762, 0.46356, 0.00282592, 0, 0.936508, 0.449623, 0.00264956, 0, 0.968254, 0.436068, 0.00246956, 0, 1, 1, 0.0276135, 0, 0, 1, 0.0276136, 0, 0, 0.999998, 0.0276148, 0, 0, 0.999993, 0.0276201, 0, 0, 0.999976, 0.0276342, 0, 0, 0.999945, 0.027664, 0, 0, 0.999884, 0.0277179, 0, 0.00018679, 0.999784, 0.027806, 0, 0.00119607, 0.99963, 0.0279394, 0, 0.00318407, 0.999401, 0.0281295, 0, 0.00613601, 0.999066, 0.0283858, 0, 0.00999963, 0.998524, 0.0287027, 0, 0.0147164, 0.995702, 0.0286256, 0, 0.0202295, 0.993593, 0.0286733, 0, 0.0264876, 0.992067, 0.0288989, 0, 0.0334452, 0.990548, 0.0292135, 0, 0.0410621, 0.986775, 0.0291296, 0, 0.0493032, 0.984054, 0.0293099, 0, 0.0581381, 0.979481, 0.0291881, 0, 0.0675397, 0.975297, 0.0291598, 0, 0.0774848, 0.96981, 0.028954, 0, 0.0879528, 0.963524, 0.028628, 0, 0.0989258, 0.957398, 0.0283135, 0, 0.110388, 0.950088, 0.0278469, 0, 0.122327, 0.941538, 0.0271798, 0, 0.134729, 0.933332, 0.0265388, 0, 0.147587, 0.924392, 0.0257776, 0, 0.160889, 0.914581, 0.024916, 0, 0.174631, 0.904347, 0.0240242, 0, 0.188806, 0.894324, 0.0231229, 0, 0.203409, 0.883724, 0.022153, 0, 0.218437, 0.872207, 0.0211355, 0, 0.233888, 0.859927, 0.0201048, 0, 0.249761, 0.848373, 0.0191263, 0, 0.266056, 0.836023, 0.0181306, 0, 0.282774, 0.82289, 0.0171718, 0, 0.299917, 0.809324, 0.0162196, 0, 0.317488, 0.795361, 0.0152622, 0, 0.335493, 0.781253, 0.01439, 0, 0.353936, 0.767338, 0.013533, 0, 0.372825, 0.753156, 0.0127244, 0, 0.392168, 0.739122, 0.0119454, 0, 0.411976, 0.725358, 0.0112054, 0, 0.432259, 0.712949, 0.010487, 0, 0.453032, 0.701621, 0.00984032, 0, 0.47431, 0.689703, 0.00921495, 0, 0.496111, 0.677216, 0.00862492, 0, 0.518456, 0.664217, 0.00806882, 0, 0.541367, 0.65137, 0.00755922, 0, 0.564872, 0.638, 0.00705705, 0, 0.589001, 0.62453, 0.00661266, 0, 0.613789, 0.610601, 0.00618432, 0, 0.639277, 0.59676, 0.00578033, 0, 0.66551, 0.582433, 0.00540927, 0, 0.692539, 0.568026, 0.00506104, 0, 0.720422, 0.55414, 0.0047353, 0, 0.749216, 0.540178, 0.00442889, 0, 0.778974, 0.526513, 0.00414363, 0, 0.809711, 0.512954, 0.00388237, 0, 0.84127, 0.499403, 0.00362875, 0, 0.873016, 0.486026, 0.00340827, 0, 0.904762, 0.472345, 0.00318598, 0, 0.936508, 0.458828, 0.00297635, 0, 0.968254, 0.445379, 0.00279447, 0, 1, 1, 0.0345716, 0, 0, 1, 0.0345717, 0, 0, 0.999999, 0.034573, 0, 0, 0.999991, 0.0345787, 0, 0, 0.999974, 0.0345941, 0, 0, 0.999937, 0.0346263, 0, 1.88589e-06, 0.999869, 0.0346847, 0, 0.000409238, 0.999757, 0.0347798, 0, 0.0017674, 0.999582, 0.0349233, 0, 0.00413658, 0.999322, 0.0351265, 0, 0.00747408, 0.998939, 0.0353967, 0, 0.0117157, 0.998219, 0.0357018, 0, 0.0167966, 0.994974, 0.0354726, 0, 0.0226572, 0.993201, 0.0355621, 0, 0.0292445, 0.991573, 0.0357641, 0, 0.0365123, 0.989301, 0.0359252, 0, 0.0444203, 0.985712, 0.0358017, 0, 0.0529334, 0.982411, 0.0358353, 0, 0.0620214, 0.977827, 0.035617, 0, 0.0716574, 0.973278, 0.0354398, 0, 0.0818186, 0.967397, 0.0350483, 0, 0.0924846, 0.960696, 0.0344795, 0, 0.103638, 0.954349, 0.0339861, 0, 0.115263, 0.946066, 0.0331323, 0, 0.127348, 0.938012, 0.032359, 0, 0.13988, 0.929413, 0.0314413, 0, 0.152849, 0.920355, 0.0304103, 0, 0.166248, 0.910586, 0.0292785, 0, 0.18007, 0.900609, 0.0281391, 0, 0.194308, 0.890093, 0.0269103, 0, 0.208958, 0.880013, 0.0257269, 0, 0.224018, 0.869001, 0.0244671, 0, 0.239485, 0.85751, 0.0232252, 0, 0.255359, 0.84582, 0.0220117, 0, 0.271638, 0.834383, 0.0208274, 0, 0.288324, 0.822158, 0.0196628, 0, 0.305419, 0.809056, 0.0185306, 0, 0.322927, 0.795832, 0.0174174, 0, 0.340851, 0.782547, 0.0163758, 0, 0.359199, 0.7689, 0.015391, 0, 0.377975, 0.755526, 0.0144488, 0, 0.397189, 0.741681, 0.0135372, 0, 0.416851, 0.728178, 0.0126957, 0, 0.436971, 0.714642, 0.0118812, 0, 0.457564, 0.702756, 0.0111165, 0, 0.478644, 0.69175, 0.0104145, 0, 0.500229, 0.680159, 0.00974439, 0, 0.522339, 0.668073, 0.00911926, 0, 0.544997, 0.655405, 0.00851393, 0, 0.56823, 0.642921, 0.00797637, 0, 0.592068, 0.629993, 0.00745119, 0, 0.616546, 0.616828, 0.00696972, 0, 0.641705, 0.603305, 0.00652425, 0, 0.66759, 0.589833, 0.00610188, 0, 0.694255, 0.575945, 0.00570834, 0, 0.72176, 0.561745, 0.00533384, 0, 0.750168, 0.548277, 0.00500001, 0, 0.779545, 0.534467, 0.00467582, 0, 0.809933, 0.521032, 0.00438092, 0, 0.841272, 0.507877, 0.00410348, 0, 0.873016, 0.494654, 0.00383618, 0, 0.904762, 0.481592, 0.00358699, 0, 0.936508, 0.468509, 0.00337281, 0, 0.968254, 0.455293, 0.00316196, 0, 1, 1, 0.0430698, 0, 0, 1, 0.0430699, 0, 0, 0.999998, 0.0430713, 0, 0, 0.999991, 0.0430773, 0, 0, 0.99997, 0.0430936, 0, 0, 0.999928, 0.0431277, 0, 4.06396e-05, 0.999852, 0.0431893, 0, 0.000744376, 0.999724, 0.0432895, 0, 0.0024806, 0.999527, 0.0434397, 0, 0.00524779, 0.99923, 0.0436507, 0, 0.00898164, 0.998783, 0.0439255, 0, 0.0136083, 0.997507, 0.0441104, 0, 0.0190582, 0.994418, 0.0438225, 0, 0.0252694, 0.992864, 0.0439396, 0, 0.0321879, 0.991127, 0.0440962, 0, 0.039767, 0.987331, 0.0438408, 0, 0.0479667, 0.984819, 0.0438991, 0, 0.056752, 0.980384, 0.0435906, 0, 0.0660929, 0.975846, 0.0432543, 0, 0.075963, 0.970748, 0.0428293, 0, 0.0863398, 0.964303, 0.042153, 0, 0.0972035, 0.95772, 0.0414111, 0, 0.108537, 0.950747, 0.0405893, 0, 0.120325, 0.942533, 0.0394887, 0, 0.132554, 0.934045, 0.0383544, 0, 0.145215, 0.924942, 0.037057, 0, 0.158296, 0.915811, 0.0356993, 0, 0.17179, 0.90612, 0.0342401, 0, 0.185691, 0.896434, 0.0328078, 0, 0.199993, 0.886021, 0.031288, 0, 0.214691, 0.876081, 0.0297776, 0, 0.229782, 0.865608, 0.0282334, 0, 0.245265, 0.854924, 0.026749, 0, 0.261138, 0.843607, 0.02526, 0, 0.277401, 0.832456, 0.0238214, 0, 0.294056, 0.821342, 0.0224682, 0, 0.311104, 0.809303, 0.0211297, 0, 0.328548, 0.796468, 0.0198387, 0, 0.346394, 0.784046, 0.0186227, 0, 0.364645, 0.771262, 0.0174561, 0, 0.38331, 0.758118, 0.0163806, 0, 0.402396, 0.745075, 0.0153287, 0, 0.421912, 0.731926, 0.0143647, 0, 0.44187, 0.71863, 0.0134363, 0, 0.462283, 0.705414, 0.0125603, 0, 0.483165, 0.693792, 0.0117508, 0, 0.504535, 0.683108, 0.0110016, 0, 0.52641, 0.67183, 0.0102757, 0, 0.548816, 0.66015, 0.00962044, 0, 0.571776, 0.647907, 0.00898031, 0, 0.595323, 0.635734, 0.00840811, 0, 0.619489, 0.623208, 0.00786211, 0, 0.644317, 0.610438, 0.00734953, 0, 0.669852, 0.597345, 0.00687688, 0, 0.696148, 0.584138, 0.00643469, 0, 0.723267, 0.5707, 0.00602236, 0, 0.75128, 0.556966, 0.0056324, 0, 0.780258, 0.543607, 0.00528277, 0, 0.810268, 0.530213, 0.00493999, 0, 0.841311, 0.516912, 0.00462265, 0, 0.873016, 0.503916, 0.0043307, 0, 0.904762, 0.491146, 0.00406858, 0, 0.936508, 0.478439, 0.00381436, 0, 0.968254, 0.465834, 0.00358003, 0, 1, 1, 0.0534039, 0, 0, 1, 0.053404, 0, 0, 0.999998, 0.0534055, 0, 0, 0.999989, 0.0534116, 0, 0, 0.999968, 0.0534283, 0, 0, 0.999918, 0.0534633, 0, 0.000155895, 0.99983, 0.0535262, 0, 0.00120914, 0.999685, 0.0536281, 0, 0.00334944, 0.999461, 0.0537799, 0, 0.00653077, 0.999119, 0.0539902, 0, 0.0106718, 0.998582, 0.0542524, 0, 0.0156907, 0.995919, 0.0540318, 0, 0.0215147, 0.993735, 0.0538914, 0, 0.0280801, 0.992126, 0.0539557, 0, 0.0353323, 0.990266, 0.0540401, 0, 0.0432247, 0.986317, 0.0536064, 0, 0.0517172, 0.983213, 0.0534425, 0, 0.0607754, 0.978303, 0.0528622, 0, 0.0703698, 0.973665, 0.0523363, 0, 0.0804742, 0.968091, 0.0516165, 0, 0.0910667, 0.961026, 0.0505434, 0, 0.102128, 0.954333, 0.049523, 0, 0.113641, 0.946372, 0.0481698, 0, 0.125591, 0.938254, 0.0467674, 0, 0.137965, 0.929516, 0.0452341, 0, 0.150754, 0.920106, 0.0435083, 0, 0.163947, 0.910899, 0.0417399, 0, 0.177537, 0.901532, 0.0399389, 0, 0.191516, 0.891919, 0.0380901, 0, 0.205881, 0.882006, 0.0362341, 0, 0.220626, 0.871965, 0.0343444, 0, 0.235749, 0.862145, 0.0324832, 0, 0.251248, 0.852058, 0.0306681, 0, 0.267121, 0.84161, 0.0289097, 0, 0.283368, 0.830806, 0.0272079, 0, 0.299992, 0.820476, 0.0256089, 0, 0.316992, 0.809514, 0.0240394, 0, 0.334374, 0.797865, 0.0225379, 0, 0.35214, 0.785621, 0.0211235, 0, 0.370296, 0.773765, 0.0197908, 0, 0.388849, 0.761629, 0.0185235, 0, 0.407807, 0.748891, 0.0173358, 0, 0.427178, 0.736437, 0.0162305, 0, 0.446974, 0.723707, 0.0151778, 0, 0.467207, 0.710606, 0.0141791, 0, 0.487892, 0.698019, 0.0132592, 0, 0.509046, 0.686203, 0.0123887, 0, 0.530687, 0.675692, 0.0115976, 0, 0.552839, 0.664826, 0.0108325, 0, 0.575527, 0.65349, 0.0101348, 0, 0.59878, 0.641774, 0.00947756, 0, 0.622634, 0.629794, 0.00886058, 0, 0.647128, 0.617647, 0.00828526, 0, 0.672308, 0.60534, 0.00775312, 0, 0.698231, 0.592718, 0.00726033, 0, 0.724958, 0.579746, 0.00679731, 0, 0.752563, 0.566763, 0.00636111, 0, 0.781127, 0.553515, 0.00595228, 0, 0.810733, 0.540118, 0.00556876, 0, 0.841426, 0.527325, 0.00523051, 0, 0.873016, 0.514265, 0.00490712, 0, 0.904762, 0.501406, 0.00460297, 0, 0.936508, 0.488922, 0.00431247, 0, 0.968254, 0.476541, 0.0040472, 0, 1, 1, 0.0659184, 0, 0, 1, 0.0659185, 0, 0, 0.999998, 0.06592, 0, 0, 0.999988, 0.0659259, 0, 0, 0.999963, 0.0659423, 0, 0, 0.999907, 0.0659764, 0, 0.000374198, 0.999806, 0.0660376, 0, 0.00182071, 0.999639, 0.0661361, 0, 0.0043894, 0.999378, 0.0662814, 0, 0.00800055, 0.998985, 0.0664779, 0, 0.0125594, 0.998285, 0.0666914, 0, 0.0179786, 0.995071, 0.0661989, 0, 0.0241822, 0.993172, 0.0660454, 0, 0.031106, 0.991438, 0.0660105, 0, 0.0386952, 0.988428, 0.0656875, 0, 0.0469032, 0.985218, 0.0652913, 0, 0.0556905, 0.981128, 0.0647107, 0, 0.065023, 0.976015, 0.0638491, 0, 0.0748717, 0.97097, 0.062993, 0, 0.0852112, 0.964582, 0.0617927, 0, 0.0960199, 0.957383, 0.0603626, 0, 0.107279, 0.949969, 0.0588128, 0, 0.118971, 0.941843, 0.0570274, 0, 0.131084, 0.933624, 0.0551885, 0, 0.143604, 0.924543, 0.053122, 0, 0.156521, 0.914919, 0.0508897, 0, 0.169825, 0.905773, 0.0486418, 0, 0.18351, 0.896434, 0.0463364, 0, 0.197569, 0.887195, 0.0440623, 0, 0.211997, 0.877706, 0.0417799, 0, 0.226789, 0.867719, 0.03945, 0, 0.241944, 0.858587, 0.037243, 0, 0.257458, 0.849317, 0.0350956, 0, 0.273331, 0.839585, 0.0329852, 0, 0.289563, 0.829856, 0.0310028, 0, 0.306154, 0.819589, 0.0290953, 0, 0.323108, 0.809714, 0.0272738, 0, 0.340426, 0.79934, 0.0255631, 0, 0.358113, 0.788224, 0.0239175, 0, 0.376175, 0.776619, 0.0223831, 0, 0.394616, 0.76521, 0.0209298, 0, 0.413445, 0.753716, 0.0195786, 0, 0.432671, 0.741564, 0.0183001, 0, 0.452305, 0.729413, 0.0171259, 0, 0.472358, 0.717146, 0.0159933, 0, 0.492845, 0.70436, 0.0149495, 0, 0.513783, 0.69219, 0.0139681, 0, 0.535189, 0.680289, 0.0130577, 0, 0.557087, 0.669611, 0.0122198, 0, 0.5795, 0.659113, 0.0114174, 0, 0.602459, 0.648148, 0.0106729, 0, 0.625997, 0.636905, 0.00998997, 0, 0.650154, 0.625154, 0.00934313, 0, 0.674976, 0.613481, 0.00874839, 0, 0.700518, 0.60154, 0.00818265, 0, 0.726845, 0.58943, 0.00766889, 0, 0.754032, 0.576828, 0.00717153, 0, 0.782167, 0.564194, 0.00672696, 0, 0.811344, 0.551501, 0.00630863, 0, 0.841644, 0.538635, 0.00592177, 0, 0.873016, 0.525724, 0.00554888, 0, 0.904762, 0.513209, 0.00520225, 0, 0.936508, 0.500457, 0.00488231, 0, 0.968254, 0.48799, 0.00457153, 0, 1, 1, 0.0810131, 0, 0, 1, 0.0810133, 0, 0, 0.999997, 0.0810145, 0, 0, 0.999985, 0.08102, 0, 0, 0.999956, 0.0810347, 0, 1.95026e-05, 0.999893, 0.0810656, 0, 0.000719316, 0.999777, 0.0811205, 0, 0.00259774, 0.999583, 0.081208, 0, 0.00561807, 0.999281, 0.0813343, 0, 0.00967472, 0.998813, 0.0814969, 0, 0.0146627, 0.997597, 0.0815217, 0, 0.0204902, 0.994379, 0.0808502, 0, 0.0270802, 0.992744, 0.0806792, 0, 0.0343674, 0.990745, 0.0804589, 0, 0.0422974, 0.986646, 0.0796107, 0, 0.0508242, 0.983611, 0.0790913, 0, 0.0599087, 0.978869, 0.0780746, 0, 0.0695175, 0.973475, 0.0768218, 0, 0.0796223, 0.967845, 0.0754926, 0, 0.0901983, 0.960778, 0.0737063, 0, 0.101224, 0.953333, 0.0718052, 0, 0.112682, 0.945274, 0.0695946, 0, 0.124555, 0.936955, 0.0672492, 0, 0.136831, 0.928319, 0.0647732, 0, 0.149496, 0.919075, 0.0620947, 0, 0.162542, 0.909114, 0.0591816, 0, 0.175958, 0.900137, 0.0563917, 0, 0.189739, 0.891069, 0.0535392, 0, 0.203877, 0.882262, 0.0507642, 0, 0.218368, 0.873232, 0.0479793, 0, 0.233208, 0.864042, 0.045226, 0, 0.248393, 0.855002, 0.0425413, 0, 0.263923, 0.846569, 0.0400126, 0, 0.279796, 0.837714, 0.0375269, 0, 0.296012, 0.828918, 0.0352027, 0, 0.312573, 0.819783, 0.0330011, 0, 0.329479, 0.810129, 0.0308908, 0, 0.346734, 0.800866, 0.0289112, 0, 0.364342, 0.79093, 0.0270255, 0, 0.382307, 0.780593, 0.0252758, 0, 0.400637, 0.769511, 0.0236178, 0, 0.419337, 0.758558, 0.0220652, 0, 0.438418, 0.747632, 0.0206289, 0, 0.457889, 0.736146, 0.0192873, 0, 0.477761, 0.724093, 0.0180333, 0, 0.49805, 0.71234, 0.0168264, 0, 0.51877, 0.700201, 0.015746, 0, 0.53994, 0.687949, 0.0147027, 0, 0.561581, 0.676163, 0.0137512, 0, 0.583718, 0.665001, 0.0128655, 0, 0.60638, 0.65472, 0.0120366, 0, 0.629599, 0.644213, 0.0112604, 0, 0.653415, 0.633382, 0.0105413, 0, 0.677874, 0.62212, 0.00986498, 0, 0.70303, 0.610631, 0.00923308, 0, 0.728948, 0.599078, 0.00864206, 0, 0.755706, 0.587519, 0.00811784, 0, 0.783396, 0.575505, 0.00761237, 0, 0.812121, 0.563148, 0.00713949, 0, 0.841989, 0.550828, 0.00668379, 0, 0.873035, 0.538458, 0.00627715, 0, 0.904762, 0.525905, 0.00588336, 0, 0.936508, 0.513517, 0.00552687, 0, 0.968254, 0.501395, 0.00519681, 0, 1, 1, 0.0991506, 0, 0, 1, 0.0991504, 0, 0, 0.999996, 0.0991515, 0, 0, 0.999984, 0.0991558, 0, 0, 0.999947, 0.0991672, 0, 0.000114389, 0.999874, 0.0991912, 0, 0.00121503, 0.999739, 0.0992331, 0, 0.00356108, 0.999514, 0.0992983, 0, 0.00705578, 0.999159, 0.0993877, 0, 0.011574, 0.998586, 0.0994837, 0, 0.017003, 0.995731, 0.0988425, 0, 0.0232484, 0.993384, 0.098276, 0, 0.0302318, 0.991615, 0.0979269, 0, 0.0378884, 0.989029, 0.0973432, 0, 0.0461641, 0.985373, 0.0963539, 0, 0.0550136, 0.981278, 0.0952306, 0, 0.0643988, 0.975777, 0.0936233, 0, 0.0742868, 0.970526, 0.0920219, 0, 0.0846501, 0.963755, 0.0898912, 0, 0.0954644, 0.956676, 0.0876064, 0, 0.106709, 0.948099, 0.0847751, 0, 0.118367, 0.939718, 0.0818638, 0, 0.130423, 0.931305, 0.078857, 0, 0.142862, 0.922342, 0.0756127, 0, 0.155674, 0.912842, 0.0721473, 0, 0.168849, 0.903304, 0.0686195, 0, 0.182378, 0.89411, 0.0650589, 0, 0.196255, 0.885512, 0.0616022, 0, 0.210473, 0.877193, 0.0582434, 0, 0.225027, 0.86877, 0.0548979, 0, 0.239915, 0.860267, 0.0516095, 0, 0.255132, 0.851915, 0.048468, 0, 0.270678, 0.843912, 0.0454447, 0, 0.286551, 0.83604, 0.0425612, 0, 0.302751, 0.828245, 0.0398752, 0, 0.31928, 0.820159, 0.0373198, 0, 0.336138, 0.81167, 0.034916, 0, 0.35333, 0.802659, 0.0326402, 0, 0.370858, 0.793921, 0.0304901, 0, 0.388728, 0.784713, 0.0284857, 0, 0.406944, 0.774946, 0.0266186, 0, 0.425515, 0.76448, 0.0248593, 0, 0.444449, 0.753793, 0.0232114, 0, 0.463756, 0.743506, 0.0217039, 0, 0.483447, 0.732555, 0.0202841, 0, 0.503535, 0.720965, 0.0189648, 0, 0.524036, 0.709422, 0.0177189, 0, 0.544968, 0.697756, 0.0165626, 0, 0.56635, 0.685565, 0.015483, 0, 0.588208, 0.673987, 0.0144892, 0, 0.610569, 0.66244, 0.0135607, 0, 0.633466, 0.651675, 0.0126956, 0, 0.656936, 0.641598, 0.0118788, 0, 0.681025, 0.63121, 0.0111261, 0, 0.705788, 0.620514, 0.010437, 0, 0.731289, 0.609366, 0.00978747, 0, 0.757606, 0.598137, 0.00917257, 0, 0.784834, 0.586966, 0.00859778, 0, 0.813085, 0.575549, 0.00806803, 0, 0.842485, 0.563797, 0.00757294, 0, 0.87313, 0.551758, 0.00710592, 0, 0.904762, 0.539894, 0.0066841, 0, 0.936508, 0.527901, 0.00627901, 0, 0.968254, 0.515819, 0.00590506, 0, 1, 1, 0.120864, 0, 0, 1, 0.120864, 0, 0, 0.999996, 0.120864, 0, 0, 0.99998, 0.120867, 0, 0, 0.99994, 0.120872, 0, 0.000323781, 0.999852, 0.120884, 0, 0.00188693, 0.999693, 0.120903, 0, 0.00473489, 0.999426, 0.120929, 0, 0.00872704, 0.999002, 0.120955, 0, 0.0137237, 0.998235, 0.120918, 0, 0.0196068, 0.994608, 0.119764, 0, 0.0262803, 0.992997, 0.119265, 0, 0.0336657, 0.990968, 0.11863, 0, 0.0416987, 0.987002, 0.117261, 0, 0.0503261, 0.983524, 0.116009, 0, 0.0595035, 0.97875, 0.114252, 0, 0.0691935, 0.972652, 0.11193, 0, 0.0793645, 0.966613, 0.109555, 0, 0.0899894, 0.959275, 0.106612, 0, 0.101045, 0.951272, 0.103375, 0, 0.112512, 0.942323, 0.0996594, 0, 0.124372, 0.933679, 0.0958841, 0, 0.136611, 0.924822, 0.0919265, 0, 0.149216, 0.915742, 0.0878061, 0, 0.162176, 0.906348, 0.0834894, 0, 0.175482, 0.896883, 0.079085, 0, 0.189125, 0.88774, 0.0746745, 0, 0.203098, 0.87986, 0.0705773, 0, 0.217396, 0.871998, 0.0665005, 0, 0.232015, 0.864325, 0.0625413, 0, 0.24695, 0.856685, 0.0586781, 0, 0.2622, 0.84925, 0.0550063, 0, 0.277761, 0.841719, 0.0514727, 0, 0.293634, 0.834755, 0.0481398, 0, 0.309819, 0.827853, 0.0450172, 0, 0.326315, 0.820888, 0.0420969, 0, 0.343126, 0.813616, 0.0393702, 0, 0.360254, 0.805767, 0.0367771, 0, 0.377701, 0.797338, 0.0343274, 0, 0.395474, 0.789122, 0.0320529, 0, 0.413577, 0.780601, 0.0299485, 0, 0.432018, 0.771424, 0.0279812, 0, 0.450804, 0.761502, 0.0261054, 0, 0.469944, 0.751166, 0.0243942, 0, 0.489451, 0.741276, 0.0228087, 0, 0.509337, 0.730898, 0.0213265, 0, 0.529617, 0.719878, 0.0199307, 0, 0.550307, 0.708379, 0.0186574, 0, 0.571428, 0.697165, 0.0174446, 0, 0.593003, 0.685554, 0.0163144, 0, 0.615059, 0.673631, 0.015276, 0, 0.637628, 0.662385, 0.0143003, 0, 0.660746, 0.651059, 0.0134112, 0, 0.68446, 0.640451, 0.0125794, 0, 0.70882, 0.630536, 0.011793, 0, 0.733893, 0.620316, 0.0110547, 0, 0.759756, 0.609722, 0.0103668, 0, 0.786505, 0.598804, 0.00973009, 0, 0.814259, 0.587871, 0.00912812, 0, 0.843157, 0.577121, 0.00858916, 0, 0.87334, 0.566019, 0.00807333, 0, 0.904762, 0.554664, 0.00759687, 0, 0.936508, 0.543101, 0.00714759, 0, 0.968254, 0.531558, 0.00673418, 0, 1, 1, 0.146767, 0, 0, 1, 0.146767, 0, 0, 0.999997, 0.146767, 0, 0, 0.999977, 0.146765, 0, 3.20658e-06, 0.999929, 0.146762, 0, 0.000682576, 0.999823, 0.146753, 0, 0.00276402, 0.999633, 0.146735, 0, 0.00614771, 0.999314, 0.146699, 0, 0.0106613, 0.998796, 0.14662, 0, 0.0161546, 0.997124, 0.146107, 0, 0.0225063, 0.994062, 0.144857, 0, 0.0296198, 0.992154, 0.144011, 0, 0.037417, 0.989186, 0.142712, 0, 0.0458348, 0.985279, 0.140926, 0, 0.0548211, 0.980826, 0.13885, 0, 0.0643326, 0.975056, 0.136168, 0, 0.074333, 0.969005, 0.133217, 0, 0.0847917, 0.961554, 0.12959, 0, 0.0956828, 0.954206, 0.125886, 0, 0.106984, 0.945046, 0.121335, 0, 0.118675, 0.935678, 0.116492, 0, 0.130741, 0.926748, 0.111635, 0, 0.143166, 0.917764, 0.106625, 0, 0.155939, 0.908358, 0.101325, 0, 0.169049, 0.899219, 0.0960249, 0, 0.182487, 0.890089, 0.0906527, 0, 0.196245, 0.881488, 0.0853905, 0, 0.210317, 0.874031, 0.0804177, 0, 0.224697, 0.866932, 0.0756005, 0, 0.23938, 0.859976, 0.0709019, 0, 0.254364, 0.853375, 0.0664391, 0, 0.269646, 0.846971, 0.0622012, 0, 0.285223, 0.840483, 0.058129, 0, 0.301096, 0.833969, 0.0542762, 0, 0.317265, 0.82806, 0.0507042, 0, 0.333729, 0.822128, 0.047368, 0, 0.350491, 0.815989, 0.044272, 0, 0.367554, 0.809336, 0.0413444, 0, 0.38492, 0.802177, 0.038601, 0, 0.402594, 0.79441, 0.0360227, 0, 0.420582, 0.786573, 0.0336383, 0, 0.438891, 0.778619, 0.0314321, 0, 0.457527, 0.77, 0.029362, 0, 0.476499, 0.760698, 0.0274102, 0, 0.49582, 0.750932, 0.0256146, 0, 0.5155, 0.740993, 0.023974, 0, 0.535555, 0.731159, 0.0224182, 0, 0.556, 0.720836, 0.0209889, 0, 0.576855, 0.709913, 0.0196411, 0, 0.598143, 0.698415, 0.0183824, 0, 0.619888, 0.68745, 0.0172222, 0, 0.642123, 0.676154, 0.0161509, 0, 0.664883, 0.664383, 0.0151397, 0, 0.688211, 0.6533, 0.0141873, 0, 0.71216, 0.642072, 0.0133105, 0, 0.736792, 0.631412, 0.0124932, 0, 0.762186, 0.621622, 0.0117408, 0, 0.788439, 0.611681, 0.0110358, 0, 0.815672, 0.60142, 0.0103775, 0, 0.844034, 0.59083, 0.00975623, 0, 0.873699, 0.580254, 0.00918084, 0, 0.904765, 0.569841, 0.00864721, 0, 0.936508, 0.559224, 0.00815731, 0, 0.968254, 0.548315, 0.00767924, 0, 1, 1, 0.177563, 0, 0, 1, 0.177563, 0, 0, 0.999994, 0.177562, 0, 0, 0.999972, 0.177555, 0, 6.64171e-05, 0.999914, 0.177536, 0, 0.0012276, 0.999787, 0.177496, 0, 0.00388025, 0.999556, 0.17742, 0, 0.00783463, 0.999165, 0.177285, 0, 0.0128953, 0.9985, 0.177037, 0, 0.0189053, 0.995388, 0.175634, 0, 0.025742, 0.993102, 0.174375, 0, 0.033309, 0.990992, 0.173121, 0, 0.0415298, 0.986932, 0.170896, 0, 0.0503425, 0.982786, 0.16847, 0, 0.0596964, 0.977592, 0.165455, 0, 0.0695498, 0.971075, 0.161676, 0, 0.0798676, 0.963967, 0.157458, 0, 0.0906201, 0.956397, 0.152836, 0, 0.101783, 0.947489, 0.147467, 0, 0.113333, 0.937564, 0.14145, 0, 0.125254, 0.928182, 0.135383, 0, 0.137529, 0.919027, 0.129212, 0, 0.150144, 0.909618, 0.12276, 0, 0.163088, 0.900492, 0.116273, 0, 0.176351, 0.891671, 0.1098, 0, 0.189924, 0.883146, 0.103362, 0, 0.203799, 0.875151, 0.0970799, 0, 0.21797, 0.868338, 0.0911732, 0, 0.232433, 0.862033, 0.0854966, 0, 0.247182, 0.856107, 0.0800691, 0, 0.262216, 0.850644, 0.0749618, 0, 0.27753, 0.845261, 0.070079, 0, 0.293124, 0.839885, 0.0654321, 0, 0.308997, 0.834609, 0.0610975, 0, 0.325149, 0.829083, 0.0569741, 0, 0.341581, 0.82404, 0.0531736, 0, 0.358294, 0.818968, 0.049665, 0, 0.37529, 0.813496, 0.0463856, 0, 0.392573, 0.807533, 0.0433217, 0, 0.410148, 0.80099, 0.0404402, 0, 0.428019, 0.793891, 0.0377578, 0, 0.446192, 0.786281, 0.0352616, 0, 0.464676, 0.778773, 0.0329577, 0, 0.483478, 0.770737, 0.030808, 0, 0.502608, 0.762094, 0.0287964, 0, 0.522079, 0.752898, 0.0269254, 0, 0.541905, 0.743306, 0.0251926, 0, 0.5621, 0.733416, 0.023595, 0, 0.582684, 0.723742, 0.0221155, 0, 0.603677, 0.713542, 0.0207435, 0, 0.625106, 0.702755, 0.019434, 0, 0.646998, 0.691484, 0.0182046, 0, 0.66939, 0.680531, 0.0170771, 0, 0.692324, 0.66953, 0.0160339, 0, 0.715849, 0.658126, 0.0150677, 0, 0.740028, 0.646933, 0.0141551, 0, 0.764937, 0.636107, 0.0133179, 0, 0.790673, 0.625271, 0.0125284, 0, 0.817358, 0.615225, 0.0117937, 0, 0.84515, 0.605678, 0.0111181, 0, 0.874244, 0.59583, 0.0104759, 0, 0.904828, 0.585704, 0.00986672, 0, 0.936508, 0.575413, 0.00929712, 0, 0.968254, 0.565373, 0.00876713, 0, 1, 1, 0.214058, 0, 0, 0.999999, 0.214058, 0, 0, 0.999994, 0.214055, 0, 0, 0.999966, 0.214039, 0, 0.000259642, 0.999893, 0.213998, 0, 0.00200075, 0.999737, 0.21391, 0, 0.00527775, 0.999449, 0.213745, 0, 0.00983959, 0.99896, 0.213458, 0, 0.0154755, 0.9979, 0.212855, 0, 0.0220249, 0.994278, 0.210779, 0, 0.0293654, 0.992254, 0.20926, 0, 0.0374021, 0.98881, 0.206908, 0, 0.0460604, 0.984715, 0.204009, 0, 0.0552802, 0.979738, 0.200471, 0, 0.0650127, 0.972884, 0.195813, 0, 0.0752175, 0.965996, 0.190856, 0, 0.0858612, 0.957974, 0.185077, 0, 0.0969155, 0.949155, 0.17868, 0, 0.108356, 0.939288, 0.171513, 0, 0.120163, 0.928996, 0.163838, 0, 0.132319, 0.919563, 0.156246, 0, 0.144808, 0.910004, 0.148359, 0, 0.157618, 0.900791, 0.140417, 0, 0.170737, 0.892135, 0.132569, 0, 0.184155, 0.883803, 0.124741, 0, 0.197866, 0.876034, 0.117091, 0, 0.211861, 0.869219, 0.109835, 0, 0.226134, 0.863062, 0.102859, 0, 0.240682, 0.857795, 0.0962928, 0, 0.255499, 0.853009, 0.0900725, 0, 0.270583, 0.848603, 0.0842101, 0, 0.285931, 0.844335, 0.0786527, 0, 0.301542, 0.840208, 0.0734397, 0, 0.317415, 0.836035, 0.0685334, 0, 0.33355, 0.83172, 0.0639275, 0, 0.349948, 0.827135, 0.0595909, 0, 0.36661, 0.822797, 0.0556204, 0, 0.383539, 0.818387, 0.0519394, 0, 0.400738, 0.813565, 0.0485317, 0, 0.41821, 0.808142, 0.0453138, 0, 0.435961, 0.802212, 0.0423354, 0, 0.453997, 0.79573, 0.0395553, 0, 0.472324, 0.788741, 0.036988, 0, 0.490951, 0.781093, 0.0345688, 0, 0.509887, 0.773597, 0.0323297, 0, 0.529144, 0.765622, 0.0302719, 0, 0.548735, 0.757083, 0.0283477, 0, 0.568674, 0.747992, 0.0265562, 0, 0.588979, 0.738591, 0.0248844, 0, 0.609671, 0.728719, 0.0233342, 0, 0.630773, 0.719146, 0.0219081, 0, 0.652314, 0.709165, 0.0205711, 0, 0.674328, 0.69875, 0.0193248, 0, 0.696854, 0.687884, 0.0181582, 0, 0.719942, 0.676818, 0.0170746, 0, 0.743651, 0.666247, 0.0160718, 0, 0.768057, 0.655284, 0.0151262, 0, 0.793253, 0.64401, 0.0142561, 0, 0.819363, 0.633353, 0.0134327, 0, 0.846547, 0.622674, 0.012653, 0, 0.875017, 0.612265, 0.0119354, 0, 0.905021, 0.602455, 0.0112533, 0, 0.936508, 0.593147, 0.0106234, 0, 0.968254, 0.583592, 0.0100213, 0, 1, 1, 0.25717, 0, 0, 1, 0.25717, 0, 0, 0.999992, 0.257164, 0, 0, 0.999958, 0.257135, 0, 0.000641715, 0.999864, 0.25706, 0, 0.00305314, 0.999666, 0.256897, 0, 0.00700975, 0.999302, 0.256596, 0, 0.0122194, 0.998663, 0.25607, 0, 0.0184622, 0.995607, 0.254123, 0, 0.0255773, 0.993094, 0.252081, 0, 0.0334439, 0.9907, 0.249867, 0, 0.0419696, 0.98594, 0.246118, 0, 0.0510823, 0.981214, 0.242049, 0, 0.0607242, 0.974966, 0.236869, 0, 0.0708486, 0.967589, 0.230724, 0, 0.081417, 0.95915, 0.223635, 0, 0.0923974, 0.950257, 0.21596, 0, 0.103763, 0.940165, 0.207296, 0, 0.115491, 0.929396, 0.197901, 0, 0.127562, 0.919288, 0.188437, 0, 0.13996, 0.909428, 0.178762, 0, 0.15267, 0.900105, 0.169072, 0, 0.165679, 0.891418, 0.159478, 0, 0.178979, 0.883347, 0.15002, 0, 0.192558, 0.875992, 0.140813, 0, 0.20641, 0.869466, 0.13196, 0, 0.220529, 0.863699, 0.123501, 0, 0.234907, 0.858553, 0.115436, 0, 0.249542, 0.854379, 0.107901, 0, 0.264428, 0.850894, 0.10088, 0, 0.279564, 0.847632, 0.0942296, 0, 0.294947, 0.844571, 0.0879861, 0, 0.310575, 0.84163, 0.0821534, 0, 0.326448, 0.838542, 0.0766409, 0, 0.342566, 0.835412, 0.0715322, 0, 0.358929, 0.831899, 0.0666883, 0, 0.37554, 0.828177, 0.0622175, 0, 0.392399, 0.82416, 0.0580452, 0, 0.409511, 0.820393, 0.054267, 0, 0.426878, 0.816068, 0.0507172, 0, 0.444506, 0.811201, 0.0474041, 0, 0.4624, 0.805785, 0.0443174, 0, 0.480566, 0.799878, 0.0414562, 0, 0.499013, 0.793469, 0.0388147, 0, 0.517749, 0.786473, 0.0363453, 0, 0.536785, 0.778874, 0.0340225, 0, 0.556134, 0.771277, 0.0318599, 0, 0.575809, 0.763426, 0.0298859, 0, 0.595827, 0.755044, 0.0280357, 0, 0.616207, 0.746161, 0.0262979, 0, 0.636973, 0.737124, 0.0247295, 0, 0.65815, 0.72761, 0.0232514, 0, 0.679772, 0.717822, 0.0218755, 0, 0.701876, 0.708279, 0.0205942, 0, 0.724509, 0.698333, 0.0193947, 0, 0.74773, 0.68802, 0.0182717, 0, 0.771609, 0.677321, 0.0172044, 0, 0.79624, 0.666504, 0.0162122, 0, 0.821743, 0.656184, 0.0152924, 0, 0.84828, 0.64556, 0.0144326, 0, 0.876069, 0.634636, 0.0136157, 0, 0.905404, 0.624124, 0.0128612, 0, 0.936508, 0.613914, 0.0121435, 0, 0.968254, 0.603589, 0.0114887, 0, 1, 1, 0.307946, 0, 0, 0.999999, 0.307945, 0, 0, 0.999988, 0.307934, 0, 2.04479e-05, 0.999944, 0.307886, 0, 0.00127833, 0.999824, 0.307756, 0, 0.00445047, 0.999565, 0.30748, 0, 0.00914673, 0.999085, 0.306966, 0, 0.0150498, 0.998103, 0.306004, 0, 0.0219367, 0.994249, 0.303028, 0, 0.0296485, 0.991807, 0.300435, 0, 0.038068, 0.987773, 0.296554, 0, 0.0471062, 0.982673, 0.2916, 0, 0.0566942, 0.976623, 0.285641, 0, 0.0667768, 0.968757, 0.27815, 0, 0.0773099, 0.959849, 0.269529, 0, 0.088257, 0.950663, 0.260248, 0, 0.0995879, 0.940129, 0.249704, 0, 0.111277, 0.92895, 0.238291, 0, 0.123304, 0.917996, 0.226501, 0, 0.13565, 0.907813, 0.214669, 0, 0.148299, 0.898305, 0.202835, 0, 0.161237, 0.889626, 0.191158, 0, 0.174455, 0.88175, 0.179695, 0, 0.187941, 0.874715, 0.168548, 0, 0.201687, 0.868746, 0.15792, 0, 0.215687, 0.863703, 0.147807, 0, 0.229933, 0.859315, 0.138149, 0, 0.24442, 0.855538, 0.128993, 0, 0.259145, 0.852428, 0.120414, 0, 0.274103, 0.850168, 0.112498, 0, 0.289293, 0.848132, 0.105054, 0, 0.304711, 0.846291, 0.0981087, 0, 0.320357, 0.844431, 0.0915942, 0, 0.33623, 0.842493, 0.0855056, 0, 0.35233, 0.840368, 0.0798204, 0, 0.368658, 0.83798, 0.0745097, 0, 0.385214, 0.83523, 0.0695424, 0, 0.402002, 0.832091, 0.0649092, 0, 0.419023, 0.828667, 0.0606291, 0, 0.436282, 0.824805, 0.0566523, 0, 0.453782, 0.820988, 0.0530229, 0, 0.471529, 0.816635, 0.0496364, 0, 0.489528, 0.811725, 0.0464658, 0, 0.507788, 0.806316, 0.0435082, 0, 0.526317, 0.800469, 0.0407873, 0, 0.545124, 0.794107, 0.038255, 0, 0.564221, 0.787218, 0.0358825, 0, 0.583621, 0.779872, 0.0336785, 0, 0.603341, 0.772097, 0.0316379, 0, 0.623397, 0.764484, 0.0297379, 0, 0.643812, 0.756428, 0.0279581, 0, 0.664611, 0.748022, 0.0263153, 0, 0.685824, 0.739268, 0.0247799, 0, 0.707488, 0.73024, 0.0233385, 0, 0.729646, 0.720893, 0.0220035, 0, 0.752354, 0.71119, 0.0207555, 0, 0.77568, 0.701791, 0.0195843, 0, 0.799715, 0.692184, 0.0184891, 0, 0.824574, 0.682258, 0.0174541, 0, 0.850417, 0.67206, 0.0164873, 0, 0.877466, 0.661717, 0.0155959, 0, 0.90604, 0.651462, 0.0147519, 0, 0.936528, 0.641467, 0.0139727, 0, 0.968254, 0.631229, 0.0132363, 0, 1, 1, 0.367573, 0, 0, 0.999999, 0.367571, 0, 0, 0.999984, 0.367553, 0, 0.000183382, 0.999925, 0.367473, 0, 0.00225254, 0.999759, 0.367259, 0, 0.00628165, 0.99941, 0.366801, 0, 0.0117858, 0.998739, 0.365946, 0, 0.0184359, 0.995529, 0.363191, 0, 0.0260114, 0.992875, 0.360171, 0, 0.0343581, 0.989135, 0.355981, 0, 0.0433637, 0.984166, 0.350401, 0, 0.0529438, 0.977871, 0.343348, 0, 0.0630334, 0.96951, 0.334341, 0, 0.0735805, 0.959964, 0.323862, 0, 0.0845437, 0.950162, 0.312521, 0, 0.095889, 0.938882, 0.299577, 0, 0.107588, 0.926992, 0.285573, 0, 0.119617, 0.915589, 0.271212, 0, 0.131957, 0.904791, 0.256611, 0, 0.144591, 0.895177, 0.242224, 0, 0.157503, 0.886403, 0.227952, 0, 0.170682, 0.878957, 0.214192, 0, 0.184117, 0.872418, 0.200795, 0, 0.197799, 0.867029, 0.188015, 0, 0.21172, 0.862835, 0.175975, 0, 0.225873, 0.859411, 0.164526, 0, 0.240253, 0.856655, 0.153693, 0, 0.254854, 0.854519, 0.14352, 0, 0.269673, 0.852828, 0.13397, 0, 0.284707, 0.851412, 0.124984, 0, 0.299953, 0.850609, 0.116748, 0, 0.315408, 0.849855, 0.10905, 0, 0.331073, 0.849017, 0.101839, 0, 0.346946, 0.848079, 0.0951359, 0, 0.363028, 0.846911, 0.0888774, 0, 0.379318, 0.845445, 0.0830375, 0, 0.395818, 0.84362, 0.0775844, 0, 0.41253, 0.841411, 0.0725054, 0, 0.429457, 0.838768, 0.0677691, 0, 0.446602, 0.835801, 0.0634016, 0, 0.463968, 0.832341, 0.0593095, 0, 0.481561, 0.828424, 0.0555121, 0, 0.499386, 0.824312, 0.052024, 0, 0.51745, 0.819918, 0.0487865, 0, 0.535761, 0.815072, 0.0457801, 0, 0.554328, 0.809863, 0.0430184, 0, 0.573162, 0.804164, 0.0404245, 0, 0.592275, 0.798034, 0.0380146, 0, 0.611681, 0.791436, 0.0357436, 0, 0.631398, 0.784498, 0.0336475, 0, 0.651445, 0.777125, 0.0316666, 0, 0.671845, 0.769365, 0.0298122, 0, 0.692628, 0.761579, 0.0281001, 0, 0.713827, 0.753746, 0.0265049, 0, 0.735484, 0.745573, 0.0250067, 0, 0.75765, 0.737083, 0.0236026, 0, 0.78039, 0.728545, 0.0223302, 0, 0.803789, 0.719691, 0.0211243, 0, 0.82796, 0.710569, 0.0199983, 0, 0.853056, 0.701216, 0.0189569, 0, 0.879298, 0.692094, 0.0179702, 0, 0.907014, 0.682909, 0.0170418, 0, 0.936691, 0.673509, 0.0161732, 0, 0.968254, 0.663863, 0.0153406, 0, 1, 1, 0.437395, 0, 0, 0.999998, 0.437394, 0, 0, 0.99998, 0.437363, 0, 0.000616704, 0.999891, 0.437232, 0, 0.00367925, 0.999656, 0.436877, 0, 0.00867446, 0.999148, 0.436121, 0, 0.0150679, 0.997959, 0.434564, 0, 0.022531, 0.993464, 0.430134, 0, 0.0308507, 0.990606, 0.426077, 0, 0.0398805, 0.985027, 0.419397, 0, 0.0495148, 0.978491, 0.41118, 0, 0.0596749, 0.969643, 0.40048, 0, 0.0703001, 0.959189, 0.38769, 0, 0.0813427, 0.948223, 0.373575, 0, 0.0927641, 0.935955, 0.357622, 0, 0.104533, 0.923237, 0.34043, 0, 0.116624, 0.911074, 0.322735, 0, 0.129015, 0.899724, 0.30479, 0, 0.141687, 0.890189, 0.287392, 0, 0.154626, 0.881796, 0.270248, 0, 0.167818, 0.874781, 0.253659, 0, 0.181252, 0.869166, 0.237786, 0, 0.194918, 0.864725, 0.222618, 0, 0.208807, 0.861565, 0.208356, 0, 0.222913, 0.859284, 0.194867, 0, 0.237229, 0.857677, 0.18212, 0, 0.25175, 0.856714, 0.17018, 0, 0.266473, 0.856155, 0.158969, 0, 0.281392, 0.8558, 0.148413, 0, 0.296505, 0.855672, 0.138578, 0, 0.311811, 0.855538, 0.129345, 0, 0.327306, 0.855689, 0.120861, 0, 0.342991, 0.855767, 0.112969, 0, 0.358864, 0.855618, 0.105593, 0, 0.374925, 0.85525, 0.0987451, 0, 0.391176, 0.854583, 0.0923727, 0, 0.407616, 0.853534, 0.0864143, 0, 0.424249, 0.852061, 0.0808338, 0, 0.441076, 0.850253, 0.0756771, 0, 0.4581, 0.848004, 0.0708612, 0, 0.475324, 0.845333, 0.0663784, 0, 0.492754, 0.842376, 0.0622631, 0, 0.510394, 0.838956, 0.0584112, 0, 0.528251, 0.835121, 0.0548328, 0, 0.546331, 0.830842, 0.0514838, 0, 0.564644, 0.826212, 0.048355, 0, 0.583198, 0.821522, 0.0454714, 0, 0.602005, 0.816551, 0.0428263, 0, 0.621078, 0.811211, 0.0403612, 0, 0.640434, 0.805479, 0.038039, 0, 0.660089, 0.799409, 0.0358739, 0, 0.680066, 0.79306, 0.0338727, 0, 0.70039, 0.786395, 0.0319985, 0, 0.721094, 0.779416, 0.030241, 0, 0.742215, 0.77214, 0.0285951, 0, 0.7638, 0.764636, 0.0270747, 0, 0.785912, 0.756836, 0.0256354, 0, 0.808628, 0.749315, 0.0243027, 0, 0.832055, 0.741561, 0.0230497, 0, 0.856338, 0.733589, 0.0218801, 0, 0.88169, 0.725479, 0.020784, 0, 0.908441, 0.717255, 0.0197702, 0, 0.937125, 0.708829, 0.0188168, 0, 0.968254, 0.700191, 0.0179113, 0, 1, 1, 0.518937, 0, 0, 0.999998, 0.518933, 0, 0, 0.999967, 0.518883, 0, 0.00147741, 0.999832, 0.51866, 0, 0.00573221, 0.999466, 0.518057, 0, 0.011826, 0.998644, 0.516752, 0, 0.0192116, 0.994458, 0.512347, 0, 0.027573, 0.991223, 0.507675, 0, 0.0367099, 0.985515, 0.500188, 0, 0.046487, 0.978308, 0.490408, 0, 0.0568071, 0.968359, 0.477357, 0, 0.0675984, 0.95682, 0.461752, 0, 0.0788059, 0.943929, 0.443796, 0, 0.090386, 0.930224, 0.423893, 0, 0.102304, 0.916514, 0.402682, 0, 0.114532, 0.903653, 0.380914, 0, 0.127047, 0.892315, 0.359212, 0, 0.139828, 0.882942, 0.338102, 0, 0.152861, 0.875438, 0.31773, 0, 0.16613, 0.869642, 0.298186, 0, 0.179624, 0.865304, 0.279491, 0, 0.193332, 0.862382, 0.261804, 0, 0.207247, 0.860666, 0.245146, 0, 0.22136, 0.859788, 0.229406, 0, 0.235666, 0.859608, 0.214605, 0, 0.250158, 0.859912, 0.200691, 0, 0.264832, 0.86053, 0.187623, 0, 0.279684, 0.861368, 0.17539, 0, 0.294711, 0.862237, 0.163901, 0, 0.309911, 0.863127, 0.153175, 0, 0.32528, 0.863923, 0.143147, 0, 0.340819, 0.864567, 0.133781, 0, 0.356524, 0.865013, 0.125042, 0, 0.372397, 0.86539, 0.116952, 0, 0.388438, 0.865591, 0.109476, 0, 0.404645, 0.865517, 0.102542, 0, 0.421022, 0.865084, 0.0960688, 0, 0.437569, 0.864309, 0.0900499, 0, 0.454287, 0.863151, 0.0844328, 0, 0.471181, 0.861649, 0.0792218, 0, 0.488253, 0.859742, 0.0743482, 0, 0.505507, 0.857446, 0.0697963, 0, 0.522947, 0.854757, 0.0655364, 0, 0.54058, 0.851783, 0.061608, 0, 0.558412, 0.848516, 0.0579701, 0, 0.576449, 0.844897, 0.0545742, 0, 0.594701, 0.840956, 0.0514167, 0, 0.613178, 0.836676, 0.0484598, 0, 0.631892, 0.832075, 0.0456934, 0, 0.650856, 0.827191, 0.0431178, 0, 0.670088, 0.822295, 0.0407718, 0, 0.689606, 0.817294, 0.0386032, 0, 0.709434, 0.812013, 0.0365675, 0, 0.7296, 0.806465, 0.0346547, 0, 0.750138, 0.800691, 0.0328717, 0, 0.771093, 0.794709, 0.031211, 0, 0.792519, 0.788493, 0.0296504, 0, 0.814488, 0.782049, 0.0281782, 0, 0.837097, 0.775403, 0.0267965, 0, 0.860481, 0.76857, 0.0255002, 0, 0.884842, 0.761536, 0.0242759, 0, 0.910494, 0.754303, 0.0231142, 0, 0.937985, 0.74692, 0.0220305, 0, 0.968254, 0.739745, 0.0210192, 0, 1, 1, 0.613914, 0, 0, 0.999996, 0.613907, 0, 9.63597e-05, 0.999942, 0.613814, 0, 0.00301247, 0.999704, 0.613407, 0, 0.00870385, 0.999046, 0.612302, 0, 0.0160714, 0.995516, 0.608266, 0, 0.0245899, 0.991726, 0.602863, 0, 0.0339681, 0.985157, 0.593956, 0, 0.0440254, 0.97642, 0.581748, 0, 0.0546409, 0.964404, 0.565183, 0, 0.0657284, 0.950601, 0.545273, 0, 0.0772246, 0.935158, 0.522129, 0, 0.0890812, 0.919364, 0.496782, 0, 0.10126, 0.904754, 0.470571, 0, 0.113731, 0.89176, 0.444037, 0, 0.126469, 0.881492, 0.418322, 0, 0.139454, 0.873656, 0.393522, 0, 0.15267, 0.868053, 0.369795, 0, 0.166101, 0.864336, 0.347171, 0, 0.179736, 0.862259, 0.325737, 0, 0.193565, 0.861556, 0.305532, 0, 0.207578, 0.861776, 0.286416, 0, 0.221769, 0.862661, 0.268355, 0, 0.23613, 0.864015, 0.251334, 0, 0.250656, 0.865711, 0.235352, 0, 0.265343, 0.867519, 0.220302, 0, 0.280187, 0.869351, 0.206161, 0, 0.295183, 0.871144, 0.192908, 0, 0.31033, 0.872839, 0.180505, 0, 0.325624, 0.874307, 0.168848, 0, 0.341065, 0.875667, 0.158021, 0, 0.35665, 0.876758, 0.147877, 0, 0.37238, 0.87764, 0.138441, 0, 0.388253, 0.878237, 0.129627, 0, 0.404269, 0.878563, 0.121415, 0, 0.42043, 0.878572, 0.113741, 0, 0.436735, 0.87842, 0.106652, 0, 0.453187, 0.878057, 0.100097, 0, 0.469786, 0.877413, 0.0940128, 0, 0.486536, 0.87646, 0.0883462, 0, 0.503439, 0.875233, 0.0830924, 0, 0.520498, 0.8737, 0.0781975, 0, 0.537717, 0.871873, 0.07364, 0, 0.555102, 0.86978, 0.0694103, 0, 0.572657, 0.867405, 0.0654696, 0, 0.59039, 0.864751, 0.0617914, 0, 0.608307, 0.861818, 0.0583491, 0, 0.626419, 0.858645, 0.0551443, 0, 0.644733, 0.855307, 0.0521894, 0, 0.663264, 0.851736, 0.0494334, 0, 0.682025, 0.847927, 0.0468504, 0, 0.701032, 0.843888, 0.0444261, 0, 0.720308, 0.839629, 0.0421497, 0, 0.739875, 0.835158, 0.0400082, 0, 0.759764, 0.830509, 0.0380076, 0, 0.780014, 0.825714, 0.0361488, 0, 0.800673, 0.820729, 0.0343956, 0, 0.821803, 0.815751, 0.0327781, 0, 0.843492, 0.810752, 0.031275, 0, 0.86586, 0.805587, 0.0298542, 0, 0.889087, 0.800317, 0.0285397, 0, 0.913466, 0.79489, 0.0272948, 0, 0.93952, 0.789314, 0.0261139, 0, 0.96835, 0.783593, 0.0249938, 0, 1, 1, 0.724258, 0, 0, 0.999992, 0.724243, 0, 0.000726889, 0.99987, 0.724044, 0, 0.00569574, 0.999336, 0.72317, 0, 0.0131702, 0.996271, 0.719432, 0, 0.0220738, 0.991159, 0.712576, 0, 0.0319405, 0.982465, 0.700927, 0, 0.0425202, 0.97049, 0.684297, 0, 0.0536599, 0.953973, 0.661244, 0, 0.065258, 0.935546, 0.633804, 0, 0.0772427, 0.916596, 0.603071, 0, 0.0895616, 0.899353, 0.57105, 0, 0.102175, 0.885216, 0.539206, 0, 0.11505, 0.875076, 0.508714, 0, 0.128164, 0.868334, 0.479571, 0, 0.141495, 0.864414, 0.451796, 0, 0.155026, 0.862678, 0.425328, 0, 0.168745, 0.862835, 0.400352, 0, 0.182639, 0.864067, 0.376532, 0, 0.196699, 0.866086, 0.35391, 0, 0.210915, 0.868557, 0.332424, 0, 0.225282, 0.871271, 0.312053, 0, 0.239792, 0.874058, 0.292764, 0, 0.25444, 0.8768, 0.27453, 0, 0.269223, 0.87939, 0.257297, 0, 0.284135, 0.8819, 0.24114, 0, 0.299174, 0.884187, 0.225934, 0, 0.314337, 0.886262, 0.211669, 0, 0.329622, 0.888119, 0.198311, 0, 0.345026, 0.889709, 0.185783, 0, 0.360549, 0.891054, 0.174063, 0, 0.376189, 0.892196, 0.163143, 0, 0.391946, 0.893101, 0.152952, 0, 0.407819, 0.893803, 0.143475, 0, 0.423808, 0.894277, 0.134647, 0, 0.439914, 0.894532, 0.126434, 0, 0.456137, 0.894576, 0.1188, 0, 0.472479, 0.894393, 0.111694, 0, 0.48894, 0.893976, 0.105069, 0, 0.505523, 0.893346, 0.0989077, 0, 0.52223, 0.892502, 0.0931724, 0, 0.539064, 0.891441, 0.0878276, 0, 0.556028, 0.890276, 0.082903, 0, 0.573125, 0.888972, 0.0783505, 0, 0.590361, 0.887469, 0.0741083, 0, 0.607741, 0.885785, 0.0701633, 0, 0.62527, 0.883914, 0.0664835, 0, 0.642957, 0.881872, 0.0630567, 0, 0.660809, 0.879651, 0.0598527, 0, 0.678836, 0.877267, 0.0568615, 0, 0.69705, 0.874717, 0.05406, 0, 0.715465, 0.872012, 0.0514378, 0, 0.734098, 0.869157, 0.0489805, 0, 0.752968, 0.866155, 0.0466727, 0, 0.772101, 0.863014, 0.0445056, 0, 0.791529, 0.859748, 0.0424733, 0, 0.81129, 0.856416, 0.0405957, 0, 0.831438, 0.852958, 0.0388273, 0, 0.852044, 0.849382, 0.0371619, 0, 0.87321, 0.845694, 0.0355959, 0, 0.89509, 0.841893, 0.0341155, 0, 0.917932, 0.837981, 0.0327141, 0, 0.942204, 0.833963, 0.0313856, 0, 0.968981, 0.829847, 0.0301275, 0, 1, 1, 0.85214, 0, 0, 0.999969, 0.852095, 0, 0.00279627, 0.999483, 0.851408, 0, 0.0107635, 0.994545, 0.84579, 0, 0.0206454, 0.986188, 0.835231, 0, 0.0315756, 0.969847, 0.814687, 0, 0.0432021, 0.945951, 0.783735, 0, 0.0553396, 0.91917, 0.746074, 0, 0.0678766, 0.895488, 0.706938, 0, 0.0807395, 0.878232, 0.669534, 0, 0.0938767, 0.868252, 0.635168, 0, 0.10725, 0.863873, 0.603069, 0, 0.120832, 0.863369, 0.572514, 0, 0.134598, 0.86545, 0.543169, 0, 0.148533, 0.868803, 0.514578, 0, 0.16262, 0.872794, 0.486762, 0, 0.176849, 0.87702, 0.459811, 0, 0.19121, 0.881054, 0.433654, 0, 0.205694, 0.884974, 0.408574, 0, 0.220294, 0.888587, 0.384525, 0, 0.235005, 0.891877, 0.36156, 0, 0.24982, 0.894793, 0.339661, 0, 0.264737, 0.89743, 0.318913, 0, 0.279751, 0.899796, 0.299302, 0, 0.294859, 0.901943, 0.280843, 0, 0.310058, 0.903858, 0.263481, 0, 0.325346, 0.905574, 0.247197, 0, 0.340721, 0.907069, 0.231915, 0, 0.356181, 0.908379, 0.217614, 0, 0.371725, 0.90952, 0.20425, 0, 0.387353, 0.910483, 0.191758, 0, 0.403063, 0.91128, 0.180092, 0, 0.418854, 0.911936, 0.169222, 0, 0.434727, 0.912454, 0.159098, 0, 0.450682, 0.912835, 0.149668, 0, 0.466718, 0.913078, 0.140884, 0, 0.482837, 0.913192, 0.132709, 0, 0.499038, 0.913175, 0.125095, 0, 0.515324, 0.91304, 0.118012, 0, 0.531695, 0.912781, 0.111417, 0, 0.548153, 0.91241, 0.105281, 0, 0.5647, 0.911924, 0.0995691, 0, 0.581338, 0.911331, 0.0942531, 0, 0.59807, 0.910637, 0.0893076, 0, 0.6149, 0.90984, 0.0846998, 0, 0.63183, 0.908941, 0.0804044, 0, 0.648865, 0.907944, 0.0763984, 0, 0.666011, 0.906857, 0.0726638, 0, 0.683273, 0.90568, 0.0691783, 0, 0.700659, 0.904416, 0.0659222, 0, 0.718176, 0.903067, 0.0628782, 0, 0.735834, 0.901637, 0.0600307, 0, 0.753646, 0.900128, 0.0573647, 0, 0.771625, 0.898544, 0.0548668, 0, 0.78979, 0.89689, 0.052527, 0, 0.808162, 0.895165, 0.0503306, 0, 0.826771, 0.893371, 0.0482668, 0, 0.845654, 0.891572, 0.0463605, 0, 0.864863, 0.889763, 0.0445998, 0, 0.884472, 0.887894, 0.0429451, 0, 0.904592, 0.885967, 0.0413884, 0, 0.925407, 0.883984, 0.0399225, 0, 0.947271, 0.881945, 0.0385405, 0, 0.97105, 0.879854, 0.0372362, 0, 1, 0.999804, 0.995833, 0, 0, 0.938155, 0.933611, 0, 0.0158731, 0.864755, 0.854311, 0, 0.0317461, 0.888594, 0.865264, 0, 0.0476191, 0.905575, 0.863922, 0, 0.0634921, 0.915125, 0.850558, 0, 0.0793651, 0.920665, 0.829254, 0, 0.0952381, 0.924073, 0.802578, 0, 0.111111, 0.926304, 0.772211, 0, 0.126984, 0.927829, 0.739366, 0, 0.142857, 0.928924, 0.705033, 0, 0.15873, 0.92973, 0.670019, 0, 0.174603, 0.930339, 0.634993, 0, 0.190476, 0.930811, 0.600485, 0, 0.206349, 0.931191, 0.566897, 0, 0.222222, 0.93149, 0.534485, 0, 0.238095, 0.931737, 0.503429, 0, 0.253968, 0.931939, 0.473811, 0, 0.269841, 0.932108, 0.445668, 0, 0.285714, 0.93225, 0.418993, 0, 0.301587, 0.932371, 0.393762, 0, 0.31746, 0.932474, 0.369939, 0, 0.333333, 0.932562, 0.347479, 0, 0.349206, 0.932638, 0.326336, 0, 0.365079, 0.932703, 0.306462, 0, 0.380952, 0.93276, 0.287805, 0, 0.396825, 0.932809, 0.270313, 0, 0.412698, 0.932851, 0.253933, 0, 0.428571, 0.932887, 0.23861, 0, 0.444444, 0.932917, 0.224289, 0, 0.460317, 0.932943, 0.210917, 0, 0.47619, 0.932965, 0.19844, 0, 0.492063, 0.932982, 0.186807, 0, 0.507937, 0.932995, 0.175966, 0, 0.52381, 0.933005, 0.165869, 0, 0.539683, 0.933011, 0.156468, 0, 0.555556, 0.933013, 0.147719, 0, 0.571429, 0.933013, 0.139579, 0, 0.587302, 0.93301, 0.132007, 0, 0.603175, 0.933004, 0.124965, 0, 0.619048, 0.932994, 0.118416, 0, 0.634921, 0.932982, 0.112326, 0, 0.650794, 0.932968, 0.106663, 0, 0.666667, 0.93295, 0.101397, 0, 0.68254, 0.932931, 0.0964993, 0, 0.698413, 0.932908, 0.0919438, 0, 0.714286, 0.932883, 0.0877057, 0, 0.730159, 0.932856, 0.0837623, 0, 0.746032, 0.932827, 0.0800921, 0, 0.761905, 0.932796, 0.0766754, 0, 0.777778, 0.932762, 0.0734936, 0, 0.793651, 0.932727, 0.0705296, 0, 0.809524, 0.932689, 0.0677676, 0, 0.825397, 0.93265, 0.0651929, 0, 0.84127, 0.932609, 0.0627917, 0, 0.857143, 0.932565, 0.0605515, 0, 0.873016, 0.932521, 0.0584606, 0, 0.888889, 0.932474, 0.0565082, 0, 0.904762, 0.932427, 0.0546841, 0, 0.920635, 0.932377, 0.0529793, 0, 0.936508, 0.932326, 0.0513851, 0, 0.952381, 0.932274, 0.0498936, 0, 0.968254, 0.93222, 0.0484975, 0, 0.984127, 0.932164, 0.0471899, 0, 1 ]; + + // data textures const ltc_float_1 = new Float32Array( LTC_MAT_1 ); const ltc_float_2 = new Float32Array( LTC_MAT_2 ); diff --git a/examples/js/lines/LineGeometry.js b/examples/js/lines/LineGeometry.js index bd311da13259df..57d3c9bfbade80 100644 --- a/examples/js/lines/LineGeometry.js +++ b/examples/js/lines/LineGeometry.js @@ -9,13 +9,12 @@ this.type = 'LineGeometry'; } - setPositions( array ) { // converts [ x1, y1, z1, x2, y2, z2, ... ] to pairs format + const length = array.length - 3; const points = new Float32Array( 2 * length ); - for ( let i = 0; i < length; i += 3 ) { points[ 2 * i ] = array[ i ]; @@ -31,13 +30,12 @@ return this; } - setColors( array ) { // converts [ r1, g1, b1, r2, g2, b2, ... ] to pairs format + const length = array.length - 3; const colors = new Float32Array( 2 * length ); - for ( let i = 0; i < length; i += 3 ) { colors[ 2 * i ] = array[ i ]; @@ -53,11 +51,11 @@ return this; } - fromLine( line ) { const geometry = line.geometry; this.setPositions( geometry.attributes.position.array ); // assumes non-indexed + // set colors, maybe return this; diff --git a/examples/js/lines/LineMaterial.js b/examples/js/lines/LineMaterial.js index 0daef4d800bd51..dff2d69f1c6052 100644 --- a/examples/js/lines/LineMaterial.js +++ b/examples/js/lines/LineMaterial.js @@ -34,13 +34,11 @@ gapSize: { value: 1 } // todo FIX - maybe change to totalSize - }; + THREE.ShaderLib[ 'line' ] = { uniforms: THREE.UniformsUtils.merge( [ THREE.UniformsLib.common, THREE.UniformsLib.fog, THREE.UniformsLib.line ] ), - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` #include #include #include @@ -269,9 +267,7 @@ } `, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform vec3 diffuse; uniform float opacity; uniform float linewidth; @@ -432,7 +428,6 @@ } ` }; - class LineMaterial extends THREE.ShaderMaterial { constructor( parameters ) { @@ -443,8 +438,8 @@ vertexShader: THREE.ShaderLib[ 'line' ].vertexShader, fragmentShader: THREE.ShaderLib[ 'line' ].fragmentShader, clipping: true // required for clipping support - } ); + this.isLineMaterial = true; Object.defineProperties( this, { color: { @@ -501,7 +496,6 @@ return Boolean( 'USE_DASH' in this.defines ); }, - set( value ) { if ( Boolean( value ) !== Boolean( 'USE_DASH' in this.defines ) ) { @@ -521,7 +515,6 @@ } } - }, dashScale: { enumerable: true, diff --git a/examples/js/lines/LineSegments2.js b/examples/js/lines/LineSegments2.js index d7c1a59a78ead9..e5d1507534029c 100644 --- a/examples/js/lines/LineSegments2.js +++ b/examples/js/lines/LineSegments2.js @@ -1,68 +1,48 @@ ( function () { const _start = new THREE.Vector3(); - const _end = new THREE.Vector3(); - const _start4 = new THREE.Vector4(); - const _end4 = new THREE.Vector4(); - const _ssOrigin = new THREE.Vector4(); - const _ssOrigin3 = new THREE.Vector3(); - const _mvMatrix = new THREE.Matrix4(); - const _line = new THREE.Line3(); - const _closestPoint = new THREE.Vector3(); - const _box = new THREE.Box3(); - const _sphere = new THREE.Sphere(); - const _clipToWorldVector = new THREE.Vector4(); + let _ray, _instanceStart, _instanceEnd, _lineWidth; - let _ray, _instanceStart, _instanceEnd, _lineWidth; // Returns the margin required to expand by in world space given the distance from the camera, + // Returns the margin required to expand by in world space given the distance from the camera, // line width, resolution, and camera projection - - function getWorldSpaceHalfWidth( camera, distance, resolution ) { // transform into clip space, adjust the x and y values by the pixel width offset, then // transform back into world space to get world offset. Note clip space is [-1, 1] so full // width does not need to be halved. _clipToWorldVector.set( 0, 0, - distance, 1.0 ).applyMatrix4( camera.projectionMatrix ); - _clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w ); - _clipToWorldVector.x = _lineWidth / resolution.width; _clipToWorldVector.y = _lineWidth / resolution.height; - _clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse ); - _clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w ); - return Math.abs( Math.max( _clipToWorldVector.x, _clipToWorldVector.y ) ); } function raycastWorldUnits( lineSegments, intersects ) { + const matrixWorld = lineSegments.matrixWorld; for ( let i = 0, l = _instanceStart.count; i < l; i ++ ) { _line.start.fromBufferAttribute( _instanceStart, i ); - _line.end.fromBufferAttribute( _instanceEnd, i ); - + _line.applyMatrix4( matrixWorld ); const pointOnLine = new THREE.Vector3(); const point = new THREE.Vector3(); - _ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine ); - const isInside = point.distanceTo( pointOnLine ) < _lineWidth * 0.5; - if ( isInside ) { intersects.push( { @@ -91,119 +71,98 @@ const geometry = lineSegments.geometry; const instanceStart = geometry.attributes.instanceStart; const instanceEnd = geometry.attributes.instanceEnd; - const near = - camera.near; // + const near = - camera.near; + + // + // pick a point 1 unit out along the ray to avoid the ray origin // sitting at the camera origin which will cause "w" to be 0 when // applying the projection matrix. + _ray.at( 1, _ssOrigin ); - _ray.at( 1, _ssOrigin ); // ndc space [ - 1.0, 1.0 ] - - + // ndc space [ - 1.0, 1.0 ] _ssOrigin.w = 1; - _ssOrigin.applyMatrix4( camera.matrixWorldInverse ); - _ssOrigin.applyMatrix4( projectionMatrix ); + _ssOrigin.multiplyScalar( 1 / _ssOrigin.w ); - _ssOrigin.multiplyScalar( 1 / _ssOrigin.w ); // screen space - - + // screen space _ssOrigin.x *= resolution.x / 2; _ssOrigin.y *= resolution.y / 2; _ssOrigin.z = 0; - _ssOrigin3.copy( _ssOrigin ); - _mvMatrix.multiplyMatrices( camera.matrixWorldInverse, matrixWorld ); - for ( let i = 0, l = instanceStart.count; i < l; i ++ ) { _start4.fromBufferAttribute( instanceStart, i ); - _end4.fromBufferAttribute( instanceEnd, i ); - _start4.w = 1; - _end4.w = 1; // camera space + _end4.w = 1; + // camera space _start4.applyMatrix4( _mvMatrix ); + _end4.applyMatrix4( _mvMatrix ); - _end4.applyMatrix4( _mvMatrix ); // skip the segment if it's entirely behind the camera - - + // skip the segment if it's entirely behind the camera const isBehindCameraNear = _start4.z > near && _end4.z > near; - if ( isBehindCameraNear ) { continue; - } // trim the segment if it extends behind camera near - + } + // trim the segment if it extends behind camera near if ( _start4.z > near ) { const deltaDist = _start4.z - _end4.z; const t = ( _start4.z - near ) / deltaDist; - _start4.lerp( _end4, t ); } else if ( _end4.z > near ) { const deltaDist = _end4.z - _start4.z; const t = ( _end4.z - near ) / deltaDist; - _end4.lerp( _start4, t ); - } // clip space - + } + // clip space _start4.applyMatrix4( projectionMatrix ); + _end4.applyMatrix4( projectionMatrix ); - _end4.applyMatrix4( projectionMatrix ); // ndc space [ - 1.0, 1.0 ] - - + // ndc space [ - 1.0, 1.0 ] _start4.multiplyScalar( 1 / _start4.w ); + _end4.multiplyScalar( 1 / _end4.w ); - _end4.multiplyScalar( 1 / _end4.w ); // screen space - - + // screen space _start4.x *= resolution.x / 2; _start4.y *= resolution.y / 2; _end4.x *= resolution.x / 2; - _end4.y *= resolution.y / 2; // create 2d segment + _end4.y *= resolution.y / 2; + // create 2d segment _line.start.copy( _start4 ); - _line.start.z = 0; - _line.end.copy( _end4 ); + _line.end.z = 0; - _line.end.z = 0; // get closest point on ray to segment - + // get closest point on ray to segment const param = _line.closestPointToPointParameter( _ssOrigin3, true ); + _line.at( param, _closestPoint ); - _line.at( param, _closestPoint ); // check if the intersection point is within clip space - - + // check if the intersection point is within clip space const zPos = THREE.MathUtils.lerp( _start4.z, _end4.z, param ); const isInClipSpace = zPos >= - 1 && zPos <= 1; - const isInside = _ssOrigin3.distanceTo( _closestPoint ) < _lineWidth * 0.5; - if ( isInClipSpace && isInside ) { _line.start.fromBufferAttribute( instanceStart, i ); - _line.end.fromBufferAttribute( instanceEnd, i ); - _line.start.applyMatrix4( matrixWorld ); - _line.end.applyMatrix4( matrixWorld ); - const pointOnLine = new THREE.Vector3(); const point = new THREE.Vector3(); - _ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine ); - intersects.push( { point: point, pointOnLine: pointOnLine, @@ -231,8 +190,9 @@ this.isLineSegments2 = true; this.type = 'LineSegments2'; - } // for backwards-compatibility, but could be a method of THREE.LineSegmentsGeometry... + } + // for backwards-compatibility, but could be a method of THREE.LineSegmentsGeometry... computeLineDistances() { @@ -240,13 +200,10 @@ const instanceStart = geometry.attributes.instanceStart; const instanceEnd = geometry.attributes.instanceEnd; const lineDistances = new Float32Array( 2 * instanceStart.count ); - for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) { _start.fromBufferAttribute( instanceStart, i ); - _end.fromBufferAttribute( instanceEnd, i ); - lineDistances[ j ] = j === 0 ? 0 : lineDistances[ j - 1 ]; lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end ); @@ -255,18 +212,15 @@ const instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1 geometry.setAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0 - geometry.setAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1 return this; } - raycast( raycaster, intersects ) { const worldUnits = this.material.worldUnits; const camera = raycaster.camera; - if ( camera === null && ! worldUnits ) { console.error( 'LineSegments2: "Raycaster.camera" needs to be set in order to raycast against LineSegments2 while worldUnits is set to false.' ); @@ -280,19 +234,19 @@ const material = this.material; _lineWidth = material.linewidth + threshold; _instanceStart = geometry.attributes.instanceStart; - _instanceEnd = geometry.attributes.instanceEnd; // check if we intersect the sphere bounds + _instanceEnd = geometry.attributes.instanceEnd; + // check if we intersect the sphere bounds if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); } - _sphere.copy( geometry.boundingSphere ).applyMatrix4( matrixWorld ); // increase the sphere bounds by the worst case line screen space width - + _sphere.copy( geometry.boundingSphere ).applyMatrix4( matrixWorld ); + // increase the sphere bounds by the worst case line screen space width let sphereMargin; - if ( worldUnits ) { sphereMargin = _lineWidth * 0.5; @@ -305,25 +259,23 @@ } _sphere.radius += sphereMargin; - if ( _ray.intersectsSphere( _sphere ) === false ) { return; - } // check if we intersect the box bounds - + } + // check if we intersect the box bounds if ( geometry.boundingBox === null ) { geometry.computeBoundingBox(); } - _box.copy( geometry.boundingBox ).applyMatrix4( matrixWorld ); // increase the box bounds by the worst case line width - + _box.copy( geometry.boundingBox ).applyMatrix4( matrixWorld ); + // increase the box bounds by the worst case line width let boxMargin; - if ( worldUnits ) { boxMargin = _lineWidth * 0.5; @@ -336,7 +288,6 @@ } _box.expandByScalar( boxMargin ); - if ( _ray.intersectsBox( _box ) === false ) { return; diff --git a/examples/js/lines/LineSegmentsGeometry.js b/examples/js/lines/LineSegmentsGeometry.js index cae1f2112f9879..2434c7498db0f8 100644 --- a/examples/js/lines/LineSegmentsGeometry.js +++ b/examples/js/lines/LineSegmentsGeometry.js @@ -1,9 +1,7 @@ ( function () { const _box = new THREE.Box3(); - const _vector = new THREE.Vector3(); - class LineSegmentsGeometry extends THREE.InstancedBufferGeometry { constructor() { @@ -19,12 +17,10 @@ this.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); } - applyMatrix4( matrix ) { const start = this.attributes.instanceStart; const end = this.attributes.instanceEnd; - if ( start !== undefined ) { start.applyMatrix4( matrix ); @@ -48,11 +44,9 @@ return this; } - setPositions( array ) { let lineSegments; - if ( array instanceof Float32Array ) { lineSegments = array; @@ -66,8 +60,8 @@ const instanceBuffer = new THREE.InstancedInterleavedBuffer( lineSegments, 6, 1 ); // xyz, xyz this.setAttribute( 'instanceStart', new THREE.InterleavedBufferAttribute( instanceBuffer, 3, 0 ) ); // xyz - this.setAttribute( 'instanceEnd', new THREE.InterleavedBufferAttribute( instanceBuffer, 3, 3 ) ); // xyz + // this.computeBoundingBox(); @@ -75,11 +69,9 @@ return this; } - setColors( array ) { let colors; - if ( array instanceof Float32Array ) { colors = array; @@ -93,45 +85,42 @@ const instanceColorBuffer = new THREE.InstancedInterleavedBuffer( colors, 6, 1 ); // rgb, rgb this.setAttribute( 'instanceColorStart', new THREE.InterleavedBufferAttribute( instanceColorBuffer, 3, 0 ) ); // rgb - this.setAttribute( 'instanceColorEnd', new THREE.InterleavedBufferAttribute( instanceColorBuffer, 3, 3 ) ); // rgb return this; } - fromWireframeGeometry( geometry ) { this.setPositions( geometry.attributes.position.array ); return this; } - fromEdgesGeometry( geometry ) { this.setPositions( geometry.attributes.position.array ); return this; } - fromMesh( mesh ) { - this.fromWireframeGeometry( new THREE.WireframeGeometry( mesh.geometry ) ); // set colors, maybe + this.fromWireframeGeometry( new THREE.WireframeGeometry( mesh.geometry ) ); + + // set colors, maybe return this; } - fromLineSegments( lineSegments ) { const geometry = lineSegments.geometry; this.setPositions( geometry.attributes.position.array ); // assumes non-indexed + // set colors, maybe return this; } - computeBoundingBox() { if ( this.boundingBox === null ) { @@ -142,19 +131,15 @@ const start = this.attributes.instanceStart; const end = this.attributes.instanceEnd; - if ( start !== undefined && end !== undefined ) { this.boundingBox.setFromBufferAttribute( start ); - _box.setFromBufferAttribute( end ); - this.boundingBox.union( _box ); } } - computeBoundingSphere() { if ( this.boundingSphere === null ) { @@ -171,27 +156,21 @@ const start = this.attributes.instanceStart; const end = this.attributes.instanceEnd; - if ( start !== undefined && end !== undefined ) { const center = this.boundingSphere.center; this.boundingBox.getCenter( center ); let maxRadiusSq = 0; - for ( let i = 0, il = start.count; i < il; i ++ ) { _vector.fromBufferAttribute( start, i ); - maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) ); - _vector.fromBufferAttribute( end, i ); - maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) ); } this.boundingSphere.radius = Math.sqrt( maxRadiusSq ); - if ( isNaN( this.boundingSphere.radius ) ) { console.error( 'THREE.LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this ); @@ -201,10 +180,10 @@ } } + toJSON() { - toJSON() { // todo + // todo } - applyMatrix( matrix ) { console.warn( 'THREE.LineSegmentsGeometry: applyMatrix() has been renamed to applyMatrix4().' ); diff --git a/examples/js/lines/Wireframe.js b/examples/js/lines/Wireframe.js index 3befb4c5e916c9..1dad1aae9828c3 100644 --- a/examples/js/lines/Wireframe.js +++ b/examples/js/lines/Wireframe.js @@ -1,9 +1,7 @@ ( function () { const _start = new THREE.Vector3(); - const _end = new THREE.Vector3(); - class Wireframe extends THREE.Mesh { constructor( geometry = new THREE.LineSegmentsGeometry(), material = new THREE.LineMaterial( { @@ -14,8 +12,9 @@ this.isWireframe = true; this.type = 'Wireframe'; - } // for backwards-compatibility, but could be a method of THREE.LineSegmentsGeometry... + } + // for backwards-compatibility, but could be a method of THREE.LineSegmentsGeometry... computeLineDistances() { @@ -23,13 +22,10 @@ const instanceStart = geometry.attributes.instanceStart; const instanceEnd = geometry.attributes.instanceEnd; const lineDistances = new Float32Array( 2 * instanceStart.count ); - for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) { _start.fromBufferAttribute( instanceStart, i ); - _end.fromBufferAttribute( instanceEnd, i ); - lineDistances[ j ] = j === 0 ? 0 : lineDistances[ j - 1 ]; lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end ); @@ -38,7 +34,6 @@ const instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1 geometry.setAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0 - geometry.setAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1 return this; diff --git a/examples/js/lines/WireframeGeometry2.js b/examples/js/lines/WireframeGeometry2.js index d51ba0f8839bc4..8d0ae39a3b9709 100644 --- a/examples/js/lines/WireframeGeometry2.js +++ b/examples/js/lines/WireframeGeometry2.js @@ -7,7 +7,9 @@ super(); this.isWireframeGeometry2 = true; this.type = 'WireframeGeometry2'; - this.fromWireframeGeometry( new THREE.WireframeGeometry( geometry ) ); // set colors, maybe + this.fromWireframeGeometry( new THREE.WireframeGeometry( geometry ) ); + + // set colors, maybe } diff --git a/examples/js/loaders/3DMLoader.js b/examples/js/loaders/3DMLoader.js index cb575b6377669b..1e2ef5b11e6956 100644 --- a/examples/js/loaders/3DMLoader.js +++ b/examples/js/loaders/3DMLoader.js @@ -1,7 +1,6 @@ ( function () { const _taskCache = new WeakMap(); - class Rhino3dmLoader extends THREE.Loader { constructor( manager ) { @@ -21,21 +20,18 @@ this.warnings = []; } - setLibraryPath( path ) { this.libraryPath = path; return this; } - setWorkerLimit( workerLimit ) { this.workerLimit = workerLimit; return this; } - load( url, onLoad, onProgress, onError ) { const loader = new THREE.FileLoader( this.manager ); @@ -50,7 +46,6 @@ if ( _taskCache.has( buffer ) ) { const cachedTask = _taskCache.get( buffer ); - return cachedTask.promise.then( onLoad ).catch( onError ); } @@ -65,19 +60,16 @@ }, onProgress, onError ); } - debug() { console.log( 'Task load: ', this.workerPool.map( worker => worker._taskLoad ) ); } - decodeObjects( buffer, url ) { let worker; let taskID; const taskCost = buffer.byteLength; - const objectPending = this._getWorker( taskCost ).then( _worker => { worker = _worker; @@ -92,7 +84,9 @@ type: 'decode', id: taskID, buffer - }, [ buffer ] ); // this.debug(); + }, [ buffer ] ); + + // this.debug(); } ); @@ -100,29 +94,30 @@ throw e; - } ); // Remove task from the task list. - // Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416) - + } ); + // Remove task from the task list. + // Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416) objectPending.catch( () => true ).then( () => { if ( worker && taskID ) { - this._releaseTask( worker, taskID ); //this.debug(); + this._releaseTask( worker, taskID ); + + //this.debug(); } - } ); // Cache the task result. + } ); + // Cache the task result. _taskCache.set( buffer, { url: url, promise: objectPending } ); - return objectPending; } - parse( data, onLoad, onError ) { this.decodeObjects( data, '' ).then( result => { @@ -133,7 +128,6 @@ } ).catch( e => onError( e ) ); } - _compareMaterials( material ) { const mat = {}; @@ -143,7 +137,6 @@ mat.color.g = material.color.g; mat.color.b = material.color.b; mat.type = material.type; - for ( let i = 0; i < this.materials.length; i ++ ) { const m = this.materials[ i ]; @@ -154,7 +147,6 @@ _mat.color.g = m.color.g; _mat.color.b = m.color.b; _mat.type = m.type; - if ( JSON.stringify( mat ) === JSON.stringify( _mat ) ) { return m; @@ -167,7 +159,6 @@ return material; } - _createMaterial( material ) { if ( material === undefined ) { @@ -183,15 +174,15 @@ const _diffuseColor = material.diffuseColor; const diffusecolor = new THREE.Color( _diffuseColor.r / 255.0, _diffuseColor.g / 255.0, _diffuseColor.b / 255.0 ); - if ( _diffuseColor.r === 0 && _diffuseColor.g === 0 && _diffuseColor.b === 0 ) { diffusecolor.r = 1; diffusecolor.g = 1; diffusecolor.b = 1; - } // console.log( material ); + } + // console.log( material ); const mat = new THREE.MeshStandardMaterial( { color: diffusecolor, @@ -201,30 +192,24 @@ opacity: 1.0 - material.transparency } ); const textureLoader = new THREE.TextureLoader(); - for ( let i = 0; i < material.textures.length; i ++ ) { const texture = material.textures[ i ]; - if ( texture.image !== null ) { const map = textureLoader.load( texture.image ); - switch ( texture.type ) { case 'Diffuse': mat.map = map; break; - case 'Bump': mat.bumpMap = map; break; - case 'Transparency': mat.alphaMap = map; mat.transparent = true; break; - case 'Emap': mat.envMap = map; break; @@ -242,10 +227,10 @@ return mat; } - _createGeometry( data ) { // console.log(data); + const object = new THREE.Object3D(); const instanceDefinitionObjects = []; const instanceDefinitions = []; @@ -258,38 +243,30 @@ object.name = this.url; let objects = data.objects; const materials = data.materials; - for ( let i = 0; i < objects.length; i ++ ) { const obj = objects[ i ]; const attributes = obj.attributes; - switch ( obj.objectType ) { case 'InstanceDefinition': instanceDefinitions.push( obj ); break; - case 'InstanceReference': instanceReferences.push( obj ); break; - default: let _object; - if ( attributes.materialIndex >= 0 ) { const rMaterial = materials[ attributes.materialIndex ]; - let material = this._createMaterial( rMaterial ); - material = this._compareMaterials( material ); _object = this._createObject( obj, material ); } else { const material = this._createMaterial(); - _object = this._createObject( obj, material ); } @@ -302,7 +279,6 @@ const layer = data.layers[ attributes.layerIndex ]; _object.visible = layer ? data.layers[ attributes.layerIndex ].visible : true; - if ( attributes.isInstanceDefinitionObject ) { instanceDefinitionObjects.push( _object ); @@ -323,15 +299,12 @@ const iDef = instanceDefinitions[ i ]; objects = []; - for ( let j = 0; j < iDef.attributes.objectIds.length; j ++ ) { const objId = iDef.attributes.objectIds[ j ]; - for ( let p = 0; p < instanceDefinitionObjects.length; p ++ ) { const idoId = instanceDefinitionObjects[ p ].userData.attributes.id; - if ( objId === idoId ) { objects.push( instanceDefinitionObjects[ p ] ); @@ -340,13 +313,13 @@ } - } // Currently clones geometry and does not take advantage of instancing + } + // Currently clones geometry and does not take advantage of instancing for ( let j = 0; j < instanceReferences.length; j ++ ) { const iRef = instanceReferences[ j ]; - if ( iRef.geometry.parentIdefId === iDef.attributes.id ) { const iRefObject = new THREE.Object3D(); @@ -354,7 +327,6 @@ const matrix = new THREE.Matrix4(); matrix.set( xf[ 0 ], xf[ 1 ], xf[ 2 ], xf[ 3 ], xf[ 4 ], xf[ 5 ], xf[ 6 ], xf[ 7 ], xf[ 8 ], xf[ 9 ], xf[ 10 ], xf[ 11 ], xf[ 12 ], xf[ 13 ], xf[ 14 ], xf[ 15 ] ); iRefObject.applyMatrix4( matrix ); - for ( let p = 0; p < objects.length; p ++ ) { iRefObject.add( objects[ p ].clone( true ) ); @@ -373,20 +345,16 @@ return object; } - _createObject( obj, mat ) { const loader = new THREE.BufferGeometryLoader(); const attributes = obj.attributes; - let geometry, material, _color, color; - switch ( obj.objectType ) { case 'Point': case 'PointSet': geometry = loader.parse( obj.geometry ); - if ( geometry.attributes.hasOwnProperty( 'color' ) ) { material = new THREE.PointsMaterial( { @@ -411,7 +379,6 @@ const points = new THREE.Points( geometry, material ); points.userData[ 'attributes' ] = attributes; points.userData[ 'objectType' ] = obj.objectType; - if ( attributes.name ) { points.name = attributes.name; @@ -419,14 +386,12 @@ } return points; - case 'Mesh': case 'Extrusion': case 'SubD': case 'Brep': if ( obj.geometry === null ) return; geometry = loader.parse( obj.geometry ); - if ( geometry.attributes.hasOwnProperty( 'color' ) ) { mat.vertexColors = true; @@ -445,7 +410,6 @@ mesh.receiveShadow = attributes.receivesShadows; mesh.userData[ 'attributes' ] = attributes; mesh.userData[ 'objectType' ] = obj.objectType; - if ( attributes.name ) { mesh.name = attributes.name; @@ -453,7 +417,6 @@ } return mesh; - case 'Curve': geometry = loader.parse( obj.geometry ); _color = attributes.drawColor; @@ -465,7 +428,6 @@ const lines = new THREE.Line( geometry, material ); lines.userData[ 'attributes' ] = attributes; lines.userData[ 'objectType' ] = obj.objectType; - if ( attributes.name ) { lines.name = attributes.name; @@ -473,7 +435,6 @@ } return lines; - case 'TextDot': geometry = obj.geometry; const ctx = document.createElement( 'canvas' ).getContext( '2d' ); @@ -508,7 +469,6 @@ sprite.scale.set( width / 10, height / 10, 1.0 ); sprite.userData[ 'attributes' ] = attributes; sprite.userData[ 'objectType' ] = obj.objectType; - if ( attributes.name ) { sprite.name = attributes.name; @@ -516,11 +476,9 @@ } return sprite; - case 'Light': geometry = obj.geometry; let light; - switch ( geometry.lightStyle.name ) { case 'LightStyle_WorldPoint': @@ -529,7 +487,6 @@ light.position.set( geometry.location[ 0 ], geometry.location[ 1 ], geometry.location[ 2 ] ); light.shadow.normalBias = 0.1; break; - case 'LightStyle_WorldSpot': light = new THREE.SpotLight(); light.castShadow = attributes.castsShadows; @@ -538,7 +495,6 @@ light.angle = geometry.spotAngleRadians; light.shadow.normalBias = 0.1; break; - case 'LightStyle_WorldRectangular': light = new THREE.RectAreaLight(); const width = Math.abs( geometry.width[ 2 ] ); @@ -546,9 +502,8 @@ light.position.set( geometry.location[ 0 ] - height / 2, geometry.location[ 1 ], geometry.location[ 2 ] - width / 2 ); light.height = height; light.width = width; - light.lookAt( new THREE.Vector3( geometry.direction[ 0 ], geometry.direction[ 1 ], geometry.direction[ 2 ] ) ); + light.lookAt( geometry.direction[ 0 ], geometry.direction[ 1 ], geometry.direction[ 2 ] ); break; - case 'LightStyle_WorldDirectional': light = new THREE.DirectionalLight(); light.castShadow = attributes.castsShadows; @@ -556,11 +511,9 @@ light.target.position.set( geometry.direction[ 0 ], geometry.direction[ 1 ], geometry.direction[ 2 ] ); light.shadow.normalBias = 0.1; break; - case 'LightStyle_WorldLinear': // not conversion exists, warning has already been printed to the console break; - default: break; @@ -582,7 +535,6 @@ } } - _initLibrary() { if ( ! this.libraryPending ) { @@ -594,8 +546,9 @@ jsLoader.load( 'rhino3dm.js', resolve, undefined, reject ); - } ); // Load rhino3dm WASM binary. + } ); + // Load rhino3dm WASM binary. const binaryLoader = new THREE.FileLoader( this.manager ); binaryLoader.setPath( this.libraryPath ); binaryLoader.setResponseType( 'arraybuffer' ); @@ -619,7 +572,6 @@ return this.libraryPending; } - _getWorker( taskCost ) { return this._initLibrary().then( () => { @@ -634,28 +586,21 @@ type: 'init', libraryConfig: this.libraryConfig } ); - worker.onmessage = e => { const message = e.data; - switch ( message.type ) { case 'warning': this.warnings.push( message.data ); console.warn( message.data ); break; - case 'decode': worker._callbacks[ message.id ].resolve( message ); - break; - case 'error': worker._callbacks[ message.id ].reject( message ); - break; - default: console.error( 'THREE.Rhino3dmLoader: Unexpected message, "' + message.type + '"' ); @@ -682,7 +627,6 @@ } ); } - _releaseTask( worker, taskID ) { worker._taskLoad -= worker._taskCosts[ taskID ]; @@ -690,7 +634,6 @@ delete worker._taskCosts[ taskID ]; } - dispose() { for ( let i = 0; i < this.workerPool.length; ++ i ) { @@ -705,8 +648,8 @@ } } - /* WEB WORKER */ + /* WEB WORKER */ function Rhino3dmWorker() { @@ -714,11 +657,9 @@ let libraryConfig; let rhino; let taskID; - onmessage = function ( e ) { const message = e.data; - switch ( message.type ) { case 'init': @@ -741,7 +682,6 @@ } ); break; - case 'decode': taskID = message.id; const buffer = message.buffer; @@ -783,28 +723,27 @@ const views = []; const namedViews = []; const groups = []; - const strings = []; //Handle objects + const strings = []; + + //Handle objects const objs = doc.objects(); const cnt = objs.count; - for ( let i = 0; i < cnt; i ++ ) { const _object = objs.get( i ); - const object = extractObjectData( _object, doc ); - _object.delete(); - if ( object ) { objects.push( object ); } - } // Handle instance definitions - // console.log( `Instance Definitions Count: ${doc.instanceDefinitions().count()}` ); + } + // Handle instance definitions + // console.log( `Instance Definitions Count: ${doc.instanceDefinitions().count()}` ); for ( let i = 0; i < doc.instanceDefinitions().count(); i ++ ) { @@ -817,26 +756,23 @@ objectType: 'InstanceDefinition' } ); - } // Handle materials + } + // Handle materials - const textureTypes = [// rhino.TextureType.Bitmap, + const textureTypes = [ + // rhino.TextureType.Bitmap, rhino.TextureType.Diffuse, rhino.TextureType.Bump, rhino.TextureType.Transparency, rhino.TextureType.Opacity, rhino.TextureType.Emap ]; const pbrTextureTypes = [ rhino.TextureType.PBR_BaseColor, rhino.TextureType.PBR_Subsurface, rhino.TextureType.PBR_SubsurfaceScattering, rhino.TextureType.PBR_SubsurfaceScatteringRadius, rhino.TextureType.PBR_Metallic, rhino.TextureType.PBR_Specular, rhino.TextureType.PBR_SpecularTint, rhino.TextureType.PBR_Roughness, rhino.TextureType.PBR_Anisotropic, rhino.TextureType.PBR_Anisotropic_Rotation, rhino.TextureType.PBR_Sheen, rhino.TextureType.PBR_SheenTint, rhino.TextureType.PBR_Clearcoat, rhino.TextureType.PBR_ClearcoatBump, rhino.TextureType.PBR_ClearcoatRoughness, rhino.TextureType.PBR_OpacityIor, rhino.TextureType.PBR_OpacityRoughness, rhino.TextureType.PBR_Emission, rhino.TextureType.PBR_AmbientOcclusion, rhino.TextureType.PBR_Displacement ]; - for ( let i = 0; i < doc.materials().count(); i ++ ) { const _material = doc.materials().get( i ); - const _pbrMaterial = _material.physicallyBased(); - let material = extractProperties( _material ); const textures = []; - for ( let j = 0; j < textureTypes.length; j ++ ) { const _texture = _material.getTexture( textureTypes[ j ] ); - if ( _texture ) { let textureType = textureTypes[ j ].constructor.name; @@ -848,11 +784,8 @@ texture.wrapU = _texture.wrapU; texture.wrapV = _texture.wrapV; texture.wrapW = _texture.wrapW; - const uvw = _texture.uvwTransform.toFloatArray( true ); - texture.repeat = [ uvw[ 0 ], uvw[ 5 ] ]; - if ( image ) { texture.image = 'data:image/png;base64,' + image; @@ -872,7 +805,6 @@ } textures.push( texture ); - _texture.delete(); } @@ -880,13 +812,11 @@ } material.textures = textures; - if ( _pbrMaterial.supported ) { for ( let j = 0; j < pbrTextureTypes.length; j ++ ) { const _texture = _material.getTexture( pbrTextureTypes[ j ] ); - if ( _texture ) { const image = doc.getEmbeddedFileAsBase64( _texture.fileName ); @@ -897,7 +827,6 @@ image: 'data:image/png;base64,' + image }; textures.push( texture ); - _texture.delete(); } @@ -910,74 +839,73 @@ } materials.push( material ); - _material.delete(); - _pbrMaterial.delete(); - } // Handle layers + } + // Handle layers for ( let i = 0; i < doc.layers().count(); i ++ ) { const _layer = doc.layers().get( i ); - const layer = extractProperties( _layer ); layers.push( layer ); - _layer.delete(); - } // Handle views + } + // Handle views for ( let i = 0; i < doc.views().count(); i ++ ) { const _view = doc.views().get( i ); - const view = extractProperties( _view ); views.push( view ); - _view.delete(); - } // Handle named views + } + // Handle named views for ( let i = 0; i < doc.namedViews().count(); i ++ ) { const _namedView = doc.namedViews().get( i ); - const namedView = extractProperties( _namedView ); namedViews.push( namedView ); - _namedView.delete(); - } // Handle groups + } + // Handle groups for ( let i = 0; i < doc.groups().count(); i ++ ) { const _group = doc.groups().get( i ); - const group = extractProperties( _group ); groups.push( group ); - _group.delete(); - } // Handle settings + } + + // Handle settings + const settings = extractProperties( doc.settings() ); + + //TODO: Handle other document stuff like dimstyles, instance definitions, bitmaps etc. - const settings = extractProperties( doc.settings() ); //TODO: Handle other document stuff like dimstyles, instance definitions, bitmaps etc. // Handle dimstyles // console.log( `Dimstyle Count: ${doc.dimstyles().count()}` ); + // Handle bitmaps // console.log( `Bitmap Count: ${doc.bitmaps().count()}` ); + // Handle strings // console.log( `Document Strings Count: ${doc.strings().count()}` ); // Note: doc.strings().documentUserTextCount() counts any doc.strings defined in a section //console.log( `Document User Text Count: ${doc.strings().documentUserTextCount()}` ); const strings_count = doc.strings().count(); - for ( let i = 0; i < strings_count; i ++ ) { strings.push( doc.strings().get( i ) ); @@ -1001,14 +929,14 @@ function extractObjectData( object, doc ) { const _geometry = object.geometry(); - const _attributes = object.attributes(); - let objectType = _geometry.objectType; - let geometry, attributes, position, data, mesh; // skip instance definition objects + let geometry, attributes, position, data, mesh; + + // skip instance definition objects //if( _attributes.isInstanceDefinitionObject ) { continue; } - // TODO: handle other geometry types + // TODO: handle other geometry types switch ( objectType ) { case rhino.ObjectType.Curve: @@ -1019,7 +947,6 @@ position.itemSize = 3; position.type = 'Float32Array'; position.array = []; - for ( let j = 0; j < pts.length; j ++ ) { position.array.push( pts[ j ][ 0 ] ); @@ -1034,7 +961,6 @@ data }; break; - case rhino.ObjectType.Point: const pt = _geometry.location; position = {}; @@ -1044,9 +970,7 @@ position.itemSize = 3; position.type = 'Float32Array'; position.array = [ pt[ 0 ], pt[ 1 ], pt[ 2 ] ]; - const _color = _attributes.drawColor( doc ); - color.itemSize = 3; color.type = 'Float32Array'; color.array = [ _color.r / 255.0, _color.g / 255.0, _color.b / 255.0 ]; @@ -1057,27 +981,20 @@ data }; break; - case rhino.ObjectType.PointSet: case rhino.ObjectType.Mesh: geometry = _geometry.toThreejsJSON(); break; - case rhino.ObjectType.Brep: const faces = _geometry.faces(); - mesh = new rhino.Mesh(); - for ( let faceIndex = 0; faceIndex < faces.count; faceIndex ++ ) { const face = faces.get( faceIndex ); - const _mesh = face.getMesh( rhino.MeshType.Any ); - if ( _mesh ) { mesh.append( _mesh ); - _mesh.delete(); } @@ -1096,10 +1013,8 @@ mesh.delete(); break; - case rhino.ObjectType.Extrusion: mesh = _geometry.getMesh( rhino.MeshType.Any ); - if ( mesh ) { geometry = mesh.toThreejsJSON(); @@ -1108,14 +1023,11 @@ } break; - case rhino.ObjectType.TextDot: geometry = extractProperties( _geometry ); break; - case rhino.ObjectType.Light: geometry = extractProperties( _geometry ); - if ( geometry.lightStyle.name === 'LightStyle_WorldLinear' ) { self.postMessage( { @@ -1131,19 +1043,15 @@ } break; - case rhino.ObjectType.InstanceReference: geometry = extractProperties( _geometry ); geometry.xform = extractProperties( _geometry.xform ); geometry.xform.array = _geometry.xform.toFloatArray( true ); break; - case rhino.ObjectType.SubD: // TODO: precalculate resulting vertices and faces and warn on excessive results _geometry.subdivide( 3 ); - mesh = rhino.Mesh.createFromSubDControlNet( _geometry ); - if ( mesh ) { geometry = mesh.toThreejsJSON(); @@ -1177,7 +1085,6 @@ attributes = extractProperties( _attributes ); attributes.geometry = extractProperties( _geometry ); - if ( _attributes.groupCount > 0 ) { attributes.groupIds = _attributes.getGroupList(); @@ -1224,11 +1131,9 @@ function extractProperties( object ) { const result = {}; - for ( const property in object ) { const value = object[ property ]; - if ( typeof value !== 'function' ) { if ( typeof value === 'object' && value !== null && value.hasOwnProperty( 'constructor' ) ) { @@ -1244,7 +1149,9 @@ } - } else { // these are functions that could be called to extract more data. + } else { + + // these are functions that could be called to extract more data. //console.log( `${property}: ${object[ property ].constructor.name}` ); } @@ -1259,7 +1166,6 @@ let pointCount = pointLimit; let rc = []; const ts = []; - if ( curve instanceof rhino.LineCurve ) { return [ curve.pointAtStart, curve.pointAtEnd ]; @@ -1269,7 +1175,6 @@ if ( curve instanceof rhino.PolylineCurve ) { pointCount = curve.pointCount; - for ( let i = 0; i < pointCount; i ++ ) { rc.push( curve.point( i ) ); @@ -1283,7 +1188,6 @@ if ( curve instanceof rhino.PolyCurve ) { const segmentCount = curve.segmentCount; - for ( let i = 0; i < segmentCount; i ++ ) { const segment = curve.segmentCurve( i ); @@ -1300,14 +1204,14 @@ if ( curve instanceof rhino.ArcCurve ) { pointCount = Math.floor( curve.angleDegrees / 5 ); - pointCount = pointCount < 2 ? 2 : pointCount; // alternative to this hardcoded version: https://stackoverflow.com/a/18499923/2179399 + pointCount = pointCount < 2 ? 2 : pointCount; + // alternative to this hardcoded version: https://stackoverflow.com/a/18499923/2179399 } if ( curve instanceof rhino.NurbsCurve && curve.degree === 1 ) { const pLine = curve.tryGetPolyline(); - for ( let i = 0; i < pLine.count; i ++ ) { rc.push( pLine.get( i ) ); @@ -1321,11 +1225,9 @@ const domain = curve.domain; const divisions = pointCount - 1.0; - for ( let j = 0; j < pointCount; j ++ ) { const t = domain[ 0 ] + j / divisions * ( domain[ 1 ] - domain[ 0 ] ); - if ( t === domain[ 0 ] || t === domain[ 1 ] ) { ts.push( t ); @@ -1334,14 +1236,15 @@ } const tan = curve.tangentAt( t ); - const prevTan = curve.tangentAt( ts.slice( - 1 )[ 0 ] ); // Duplicated from THREE.Vector3 + const prevTan = curve.tangentAt( ts.slice( - 1 )[ 0 ] ); + + // Duplicated from THREE.Vector3 // How to pass imports to worker? const tS = tan[ 0 ] * tan[ 0 ] + tan[ 1 ] * tan[ 1 ] + tan[ 2 ] * tan[ 2 ]; const ptS = prevTan[ 0 ] * prevTan[ 0 ] + prevTan[ 1 ] * prevTan[ 1 ] + prevTan[ 2 ] * prevTan[ 2 ]; const denominator = Math.sqrt( tS * ptS ); let angle; - if ( denominator === 0 ) { angle = Math.PI / 2; diff --git a/examples/js/loaders/3MFLoader.js b/examples/js/loaders/3MFLoader.js index fe3980d75655b1..1baef550e20d64 100644 --- a/examples/js/loaders/3MFLoader.js +++ b/examples/js/loaders/3MFLoader.js @@ -26,7 +26,6 @@ this.availableExtensions = []; } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -60,12 +59,10 @@ }, onProgress, onError ); } - parse( data ) { const scope = this; const textureLoader = new THREE.TextureLoader( this.manager ); - function loadDocument( data ) { let zip = null; @@ -78,7 +75,6 @@ const modelParts = {}; const printTicketParts = {}; const texturesParts = {}; - try { zip = fflate.unzipSync( new Uint8Array( data ) ); // eslint-disable-line no-undef @@ -114,12 +110,15 @@ } - } // + } + // const relsView = zip[ relsName ]; const relsFileText = THREE.LoaderUtils.decodeText( relsView ); - const rels = parseRelsXml( relsFileText ); // + const rels = parseRelsXml( relsFileText ); + + // if ( modelRelsName ) { @@ -127,8 +126,9 @@ const relsFileText = THREE.LoaderUtils.decodeText( relsView ); modelRels = parseRelsXml( relsFileText ); - } // + } + // for ( let i = 0; i < modelPartNames.length; i ++ ) { @@ -136,7 +136,6 @@ const view = zip[ modelPart ]; const fileText = THREE.LoaderUtils.decodeText( view ); const xmlData = new DOMParser().parseFromString( fileText, 'application/xml' ); - if ( xmlData.documentElement.nodeName.toLowerCase() !== 'model' ) { console.error( 'THREE.3MFLoader: Error loading 3MF - no 3MF document found: ', modelPart ); @@ -145,11 +144,9 @@ const modelNode = xmlData.querySelector( 'model' ); const extensions = {}; - for ( let i = 0; i < modelNode.attributes.length; i ++ ) { const attr = modelNode.attributes[ i ]; - if ( attr.name.match( /^xmlns:(.+)$/ ) ) { extensions[ attr.value ] = RegExp.$1; @@ -160,7 +157,6 @@ const modelData = parseModelNode( modelNode ); modelData[ 'xml' ] = modelNode; - if ( 0 < Object.keys( extensions ).length ) { modelData[ 'extensions' ] = extensions; @@ -169,8 +165,9 @@ modelParts[ modelPart ] = modelData; - } // + } + // for ( let i = 0; i < texturesPartNames.length; i ++ ) { @@ -194,7 +191,6 @@ const relationships = []; const relsXmlData = new DOMParser().parseFromString( relsFileText, 'application/xml' ); const relsNodes = relsXmlData.querySelectorAll( 'Relationship' ); - for ( let i = 0; i < relsNodes.length; i ++ ) { const relsNode = relsNodes[ i ]; @@ -204,8 +200,8 @@ id: relsNode.getAttribute( 'Id' ), //required type: relsNode.getAttribute( 'Type' ) //required - }; + relationships.push( relationship ); } @@ -217,13 +213,11 @@ function parseMetadataNodes( metadataNodes ) { const metadataData = {}; - for ( let i = 0; i < metadataNodes.length; i ++ ) { const metadataNode = metadataNodes[ i ]; const name = metadataNode.getAttribute( 'name' ); const validNames = [ 'Title', 'Designer', 'Description', 'Copyright', 'LicenseTerms', 'Rating', 'CreationDate', 'ModificationDate' ]; - if ( 0 <= validNames.indexOf( name ) ) { metadataData[ name ] = metadataNode.textContent; @@ -244,13 +238,11 @@ basematerials: [] }; const basematerialNodes = basematerialsNode.querySelectorAll( 'base' ); - for ( let i = 0; i < basematerialNodes.length; i ++ ) { const basematerialNode = basematerialNodes[ i ]; const basematerialData = parseBasematerialNode( basematerialNode ); basematerialData.index = i; // the order and count of the material nodes form an implicit 0-based index - basematerialsData.basematerials.push( basematerialData ); } @@ -287,7 +279,6 @@ }; const tex2coordNodes = texture2DGroupNode.querySelectorAll( 'tex2coord' ); const uvs = []; - for ( let i = 0; i < tex2coordNodes.length; i ++ ) { const tex2coordNode = tex2coordNodes[ i ]; @@ -312,7 +303,6 @@ const colorNodes = colorGroupNode.querySelectorAll( 'color' ); const colors = []; const colorObject = new THREE.Color(); - for ( let i = 0; i < colorNodes.length; i ++ ) { const colorNode = colorNodes[ i ]; @@ -333,11 +323,10 @@ const metallicDisplaypropertiesData = { id: metallicDisplaypropetiesNode.getAttribute( 'id' ) // required - }; + const metallicNodes = metallicDisplaypropetiesNode.querySelectorAll( 'pbmetallic' ); const metallicData = []; - for ( let i = 0; i < metallicNodes.length; i ++ ) { const metallicNode = metallicNodes[ i ]; @@ -347,7 +336,6 @@ metallicness: parseFloat( metallicNode.getAttribute( 'metallicness' ) ), // required roughness: parseFloat( metallicNode.getAttribute( 'roughness' ) ) // required - } ); } @@ -361,9 +349,7 @@ const basematerialData = {}; basematerialData[ 'name' ] = basematerialNode.getAttribute( 'name' ); // required - basematerialData[ 'displaycolor' ] = basematerialNode.getAttribute( 'displaycolor' ); // required - basematerialData[ 'displaypropertiesid' ] = basematerialNode.getAttribute( 'displaypropertiesid' ); return basematerialData; @@ -374,7 +360,6 @@ const meshData = {}; const vertices = []; const vertexNodes = meshNode.querySelectorAll( 'vertices vertex' ); - for ( let i = 0; i < vertexNodes.length; i ++ ) { const vertexNode = vertexNodes[ i ]; @@ -389,7 +374,6 @@ const triangleProperties = []; const triangles = []; const triangleNodes = meshNode.querySelectorAll( 'triangles triangle' ); - for ( let i = 0; i < triangleNodes.length; i ++ ) { const triangleNode = triangleNodes[ i ]; @@ -404,7 +388,9 @@ triangleProperty[ 'v1' ] = parseInt( v1, 10 ); triangleProperty[ 'v2' ] = parseInt( v2, 10 ); triangleProperty[ 'v3' ] = parseInt( v3, 10 ); - triangles.push( triangleProperty[ 'v1' ], triangleProperty[ 'v2' ], triangleProperty[ 'v3' ] ); // optional + triangles.push( triangleProperty[ 'v1' ], triangleProperty[ 'v2' ], triangleProperty[ 'v3' ] ); + + // optional if ( p1 ) { @@ -448,7 +434,6 @@ const components = []; const componentNodes = componentsNode.querySelectorAll( 'component' ); - for ( let i = 0; i < componentNodes.length; i ++ ) { const componentNode = componentNodes[ i ]; @@ -467,7 +452,6 @@ componentData[ 'objectId' ] = componentNode.getAttribute( 'objectid' ); // required const transform = componentNode.getAttribute( 'transform' ); - if ( transform ) { componentData[ 'transform' ] = parseTransform( transform ); @@ -498,7 +482,6 @@ type: objectNode.getAttribute( 'type' ) }; const id = objectNode.getAttribute( 'id' ); - if ( id ) { objectData[ 'id' ] = id; @@ -506,7 +489,6 @@ } const pid = objectNode.getAttribute( 'pid' ); - if ( pid ) { objectData[ 'pid' ] = pid; @@ -514,7 +496,6 @@ } const pindex = objectNode.getAttribute( 'pindex' ); - if ( pindex ) { objectData[ 'pindex' ] = pindex; @@ -522,7 +503,6 @@ } const thumbnail = objectNode.getAttribute( 'thumbnail' ); - if ( thumbnail ) { objectData[ 'thumbnail' ] = thumbnail; @@ -530,7 +510,6 @@ } const partnumber = objectNode.getAttribute( 'partnumber' ); - if ( partnumber ) { objectData[ 'partnumber' ] = partnumber; @@ -538,7 +517,6 @@ } const name = objectNode.getAttribute( 'name' ); - if ( name ) { objectData[ 'name' ] = name; @@ -546,7 +524,6 @@ } const meshNode = objectNode.querySelector( 'mesh' ); - if ( meshNode ) { objectData[ 'mesh' ] = parseMeshNode( meshNode ); @@ -554,7 +531,6 @@ } const componentsNode = objectNode.querySelector( 'components' ); - if ( componentsNode ) { objectData[ 'components' ] = parseComponentsNode( componentsNode ); @@ -570,67 +546,66 @@ const resourcesData = {}; resourcesData[ 'basematerials' ] = {}; const basematerialsNodes = resourcesNode.querySelectorAll( 'basematerials' ); - for ( let i = 0; i < basematerialsNodes.length; i ++ ) { const basematerialsNode = basematerialsNodes[ i ]; const basematerialsData = parseBasematerialsNode( basematerialsNode ); resourcesData[ 'basematerials' ][ basematerialsData[ 'id' ] ] = basematerialsData; - } // + } + // resourcesData[ 'texture2d' ] = {}; const textures2DNodes = resourcesNode.querySelectorAll( 'texture2d' ); - for ( let i = 0; i < textures2DNodes.length; i ++ ) { const textures2DNode = textures2DNodes[ i ]; const texture2DData = parseTexture2DNode( textures2DNode ); resourcesData[ 'texture2d' ][ texture2DData[ 'id' ] ] = texture2DData; - } // + } + // resourcesData[ 'colorgroup' ] = {}; const colorGroupNodes = resourcesNode.querySelectorAll( 'colorgroup' ); - for ( let i = 0; i < colorGroupNodes.length; i ++ ) { const colorGroupNode = colorGroupNodes[ i ]; const colorGroupData = parseColorGroupNode( colorGroupNode ); resourcesData[ 'colorgroup' ][ colorGroupData[ 'id' ] ] = colorGroupData; - } // + } + // resourcesData[ 'pbmetallicdisplayproperties' ] = {}; const pbmetallicdisplaypropertiesNodes = resourcesNode.querySelectorAll( 'pbmetallicdisplayproperties' ); - for ( let i = 0; i < pbmetallicdisplaypropertiesNodes.length; i ++ ) { const pbmetallicdisplaypropertiesNode = pbmetallicdisplaypropertiesNodes[ i ]; const pbmetallicdisplaypropertiesData = parseMetallicDisplaypropertiesNode( pbmetallicdisplaypropertiesNode ); resourcesData[ 'pbmetallicdisplayproperties' ][ pbmetallicdisplaypropertiesData[ 'id' ] ] = pbmetallicdisplaypropertiesData; - } // + } + // resourcesData[ 'texture2dgroup' ] = {}; const textures2DGroupNodes = resourcesNode.querySelectorAll( 'texture2dgroup' ); - for ( let i = 0; i < textures2DGroupNodes.length; i ++ ) { const textures2DGroupNode = textures2DGroupNodes[ i ]; const textures2DGroupData = parseTextures2DGroupNode( textures2DGroupNode ); resourcesData[ 'texture2dgroup' ][ textures2DGroupData[ 'id' ] ] = textures2DGroupData; - } // + } + // resourcesData[ 'object' ] = {}; const objectNodes = resourcesNode.querySelectorAll( 'object' ); - for ( let i = 0; i < objectNodes.length; i ++ ) { const objectNode = objectNodes[ i ]; @@ -647,7 +622,6 @@ const buildData = []; const itemNodes = buildNode.querySelectorAll( 'item' ); - for ( let i = 0; i < itemNodes.length; i ++ ) { const itemNode = itemNodes[ i ]; @@ -655,7 +629,6 @@ objectId: itemNode.getAttribute( 'objectid' ) }; const transform = itemNode.getAttribute( 'transform' ); - if ( transform ) { buildItem[ 'transform' ] = parseTransform( transform ); @@ -676,7 +649,6 @@ unit: modelNode.getAttribute( 'unit' ) || 'millimeter' }; const metadataNodes = modelNode.querySelectorAll( 'metadata' ); - if ( metadataNodes ) { modelData[ 'metadata' ] = parseMetadataNodes( metadataNodes ); @@ -684,7 +656,6 @@ } const resourcesNode = modelNode.querySelector( 'resources' ); - if ( resourcesNode ) { modelData[ 'resources' ] = parseResourcesNode( resourcesNode ); @@ -692,7 +663,6 @@ } const buildNode = modelNode.querySelector( 'build' ); - if ( buildNode ) { modelData[ 'build' ] = parseBuildNode( buildNode ); @@ -708,7 +678,6 @@ const texid = texture2dgroup.texid; const texture2ds = modelData.resources.texture2d; const texture2d = texture2ds[ texid ]; - if ( texture2d ) { const data = textureData[ texture2d.path ]; @@ -722,23 +691,22 @@ URL.revokeObjectURL( sourceURI ); } ); - texture.encoding = THREE.sRGBEncoding; // texture parameters + texture.encoding = THREE.sRGBEncoding; + + // texture parameters switch ( texture2d.tilestyleu ) { case 'wrap': texture.wrapS = THREE.RepeatWrapping; break; - case 'mirror': texture.wrapS = THREE.MirroredRepeatWrapping; break; - case 'none': case 'clamp': texture.wrapS = THREE.ClampToEdgeWrapping; break; - default: texture.wrapS = THREE.RepeatWrapping; @@ -749,16 +717,13 @@ case 'wrap': texture.wrapT = THREE.RepeatWrapping; break; - case 'mirror': texture.wrapT = THREE.MirroredRepeatWrapping; break; - case 'none': case 'clamp': texture.wrapT = THREE.ClampToEdgeWrapping; break; - default: texture.wrapT = THREE.RepeatWrapping; @@ -770,17 +735,14 @@ texture.magFilter = THREE.LinearFilter; texture.minFilter = THREE.LinearMipmapLinearFilter; break; - case 'linear': texture.magFilter = THREE.LinearFilter; texture.minFilter = THREE.LinearFilter; break; - case 'nearest': texture.magFilter = THREE.NearestFilter; texture.minFilter = THREE.NearestFilter; break; - default: texture.magFilter = THREE.LinearFilter; texture.minFilter = THREE.LinearMipmapLinearFilter; @@ -801,7 +763,6 @@ const objectPindex = objectData.pindex; const materialMap = {}; - for ( let i = 0, l = triangleProperties.length; i < l; i ++ ) { const triangleProperty = triangleProperties[ i ]; @@ -809,23 +770,24 @@ if ( materialMap[ pindex ] === undefined ) materialMap[ pindex ] = []; materialMap[ pindex ].push( triangleProperty ); - } // + } + // const keys = Object.keys( materialMap ); const meshes = []; - for ( let i = 0, l = keys.length; i < l; i ++ ) { const materialIndex = keys[ i ]; const trianglePropertiesProps = materialMap[ materialIndex ]; const basematerialData = basematerials.basematerials[ materialIndex ]; - const material = getBuild( basematerialData, objects, modelData, textureData, objectData, buildBasematerial ); // + const material = getBuild( basematerialData, objects, modelData, textureData, objectData, buildBasematerial ); + + // const geometry = new THREE.BufferGeometry(); const positionData = []; const vertices = meshData.vertices; - for ( let j = 0, jl = trianglePropertiesProps.length; j < jl; j ++ ) { const triangleProperty = trianglePropertiesProps[ j ]; @@ -841,7 +803,9 @@ } - geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positionData, 3 ) ); // + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positionData, 3 ) ); + + // const mesh = new THREE.Mesh( geometry, material ); meshes.push( mesh ); @@ -855,12 +819,12 @@ function buildTexturedMesh( texture2dgroup, triangleProperties, meshData, objects, modelData, textureData, objectData ) { // geometry + const geometry = new THREE.BufferGeometry(); const positionData = []; const uvData = []; const vertices = meshData.vertices; const uvs = texture2dgroup.uvs; - for ( let i = 0, l = triangleProperties.length; i < l; i ++ ) { const triangleProperty = triangleProperties[ i ]; @@ -872,7 +836,9 @@ positionData.push( vertices[ triangleProperty.v2 * 3 + 2 ] ); positionData.push( vertices[ triangleProperty.v3 * 3 + 0 ] ); positionData.push( vertices[ triangleProperty.v3 * 3 + 1 ] ); - positionData.push( vertices[ triangleProperty.v3 * 3 + 2 ] ); // + positionData.push( vertices[ triangleProperty.v3 * 3 + 2 ] ); + + // uvData.push( uvs[ triangleProperty.p1 * 2 + 0 ] ); uvData.push( uvs[ triangleProperty.p1 * 2 + 1 ] ); @@ -884,13 +850,17 @@ } geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positionData, 3 ) ); - geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvData, 2 ) ); // material + geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvData, 2 ) ); + + // material const texture = getBuild( texture2dgroup, objects, modelData, textureData, objectData, buildTexture ); const material = new THREE.MeshPhongMaterial( { map: texture, flatShading: true - } ); // mesh + } ); + + // mesh const mesh = new THREE.Mesh( geometry, material ); return mesh; @@ -900,12 +870,12 @@ function buildVertexColorMesh( colorgroup, triangleProperties, meshData, objectData ) { // geometry + const geometry = new THREE.BufferGeometry(); const positionData = []; const colorData = []; const vertices = meshData.vertices; const colors = colorgroup.colors; - for ( let i = 0, l = triangleProperties.length; i < l; i ++ ) { const triangleProperty = triangleProperties[ i ]; @@ -920,7 +890,9 @@ positionData.push( vertices[ v2 * 3 + 2 ] ); positionData.push( vertices[ v3 * 3 + 0 ] ); positionData.push( vertices[ v3 * 3 + 1 ] ); - positionData.push( vertices[ v3 * 3 + 2 ] ); // + positionData.push( vertices[ v3 * 3 + 2 ] ); + + // const p1 = triangleProperty.p1 !== undefined ? triangleProperty.p1 : objectData.pindex; const p2 = triangleProperty.p2 !== undefined ? triangleProperty.p2 : p1; @@ -938,12 +910,16 @@ } geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positionData, 3 ) ); - geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colorData, 3 ) ); // material + geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colorData, 3 ) ); + + // material const material = new THREE.MeshPhongMaterial( { vertexColors: true, flatShading: true - } ); // mesh + } ); + + // mesh const mesh = new THREE.Mesh( geometry, material ); return mesh; @@ -968,19 +944,16 @@ const keys = Object.keys( resourceMap ); const meshes = []; - for ( let i = 0, il = keys.length; i < il; i ++ ) { const resourceId = keys[ i ]; const triangleProperties = resourceMap[ resourceId ]; const resourceType = getResourceType( resourceId, modelData ); - switch ( resourceType ) { case 'material': const basematerials = modelData.resources.basematerials[ resourceId ]; const newMeshes = buildBasematerialsMeshes( basematerials, triangleProperties, meshData, objects, modelData, textureData, objectData ); - for ( let j = 0, jl = newMeshes.length; j < jl; j ++ ) { meshes.push( newMeshes[ j ] ); @@ -988,21 +961,17 @@ } break; - case 'texture': const texture2dgroup = modelData.resources.texture2dgroup[ resourceId ]; meshes.push( buildTexturedMesh( texture2dgroup, triangleProperties, meshData, objects, modelData, textureData, objectData ) ); break; - case 'vertexColors': const colorgroup = modelData.resources.colorgroup[ resourceId ]; meshes.push( buildVertexColorMesh( colorgroup, triangleProperties, meshData, objectData ) ); break; - case 'default': meshes.push( buildDefaultMesh( meshData ) ); break; - default: console.error( 'THREE.3MFLoader: Unsupported resource type.' ); @@ -1055,7 +1024,6 @@ const resourceMap = {}; const triangleProperties = meshData[ 'triangleProperties' ]; const objectPid = objectData.pid; - for ( let i = 0, l = triangleProperties.length; i < l; i ++ ) { const triangleProperty = triangleProperties[ i ]; @@ -1075,7 +1043,6 @@ const group = new THREE.Group(); const resourceMap = analyzeObject( meshData, objectData ); const meshes = buildMeshes( resourceMap, meshData, objects, modelData, textureData, objectData ); - for ( let i = 0, l = meshes.length; i < l; i ++ ) { group.add( meshes[ i ] ); @@ -1096,15 +1063,12 @@ const availableExtensions = []; const keys = Object.keys( extensions ); - for ( let i = 0; i < keys.length; i ++ ) { const ns = keys[ i ]; - for ( let j = 0; j < scope.availableExtensions.length; j ++ ) { const extension = scope.availableExtensions[ j ]; - if ( extension.ns === ns ) { availableExtensions.push( extension ); @@ -1137,10 +1101,10 @@ let material; const displaypropertiesid = materialData.displaypropertiesid; const pbmetallicdisplayproperties = modelData.resources.pbmetallicdisplayproperties; - if ( displaypropertiesid !== null && pbmetallicdisplayproperties[ displaypropertiesid ] !== undefined ) { // metallic display property, use StandardMaterial + const pbmetallicdisplayproperty = pbmetallicdisplayproperties[ displaypropertiesid ]; const metallicData = pbmetallicdisplayproperty.data[ materialData.index ]; material = new THREE.MeshStandardMaterial( { @@ -1152,18 +1116,22 @@ } else { // otherwise use PhongMaterial + material = new THREE.MeshPhongMaterial( { flatShading: true } ); } - material.name = materialData.name; // displaycolor MUST be specified with a value of a 6 or 8 digit hexadecimal number, e.g. "#RRGGBB" or "#RRGGBBAA" + material.name = materialData.name; + + // displaycolor MUST be specified with a value of a 6 or 8 digit hexadecimal number, e.g. "#RRGGBB" or "#RRGGBBAA" const displaycolor = materialData.displaycolor; const color = displaycolor.substring( 0, 7 ); material.color.setStyle( color ); material.color.convertSRGBToLinear(); // displaycolor is in sRGB + // process alpha if set if ( displaycolor.length === 9 ) { @@ -1179,12 +1147,10 @@ function buildComposite( compositeData, objects, modelData, textureData ) { const composite = new THREE.Group(); - for ( let j = 0; j < compositeData.length; j ++ ) { const component = compositeData[ j ]; let build = objects[ component.objectId ]; - if ( build === undefined ) { buildObject( component.objectId, objects, modelData, textureData ); @@ -1192,10 +1158,11 @@ } - const object3D = build.clone(); // apply component transform + const object3D = build.clone(); - const transform = component.transform; + // apply component transform + const transform = component.transform; if ( transform ) { object3D.applyMatrix4( transform ); @@ -1213,7 +1180,6 @@ function buildObject( objectId, objects, modelData, textureData ) { const objectData = modelData[ 'resources' ][ 'object' ][ objectId ]; - if ( objectData[ 'mesh' ] ) { const meshData = objectData[ 'mesh' ]; @@ -1243,7 +1209,9 @@ const modelRels = data3mf.modelRels; const objects = {}; const modelsKeys = Object.keys( modelsData ); - const textureData = {}; // evaluate model relationships to textures + const textureData = {}; + + // evaluate model relationships to textures if ( modelRels ) { @@ -1251,7 +1219,6 @@ const modelRel = modelRels[ i ]; const textureKey = modelRel.target.substring( 1 ); - if ( data3mf.texture[ textureKey ] ) { textureData[ modelRel.target ] = data3mf.texture[ textureKey ]; @@ -1260,15 +1227,15 @@ } - } // start build + } + // start build for ( let i = 0; i < modelsKeys.length; i ++ ) { const modelsKey = modelsKeys[ i ]; const modelData = modelsData[ modelsKey ]; const objectIds = Object.keys( modelData[ 'resources' ][ 'object' ] ); - for ( let j = 0; j < objectIds.length; j ++ ) { const objectId = objectIds[ j ]; @@ -1299,14 +1266,14 @@ const group = new THREE.Group(); const relationship = fetch3DModelPart( data3mf[ 'rels' ] ); const buildData = data3mf.model[ relationship[ 'target' ].substring( 1 ) ][ 'build' ]; - for ( let i = 0; i < buildData.length; i ++ ) { const buildItem = buildData[ i ]; - const object3D = objects[ buildItem[ 'objectId' ] ].clone(); // apply transform + const object3D = objects[ buildItem[ 'objectId' ] ].clone(); - const transform = buildItem[ 'transform' ]; + // apply transform + const transform = buildItem[ 'transform' ]; if ( transform ) { object3D.applyMatrix4( transform ); @@ -1326,7 +1293,6 @@ return build( objects, data3mf ); } - addExtension( extension ) { this.availableExtensions.push( extension ); diff --git a/examples/js/loaders/AMFLoader.js b/examples/js/loaders/AMFLoader.js index b94ca6184ac2dd..a5e19d71be5b4d 100644 --- a/examples/js/loaders/AMFLoader.js +++ b/examples/js/loaders/AMFLoader.js @@ -23,7 +23,6 @@ super( manager ); } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -57,20 +56,17 @@ }, onProgress, onError ); } - parse( data ) { function loadDocument( data ) { let view = new DataView( data ); const magic = String.fromCharCode( view.getUint8( 0 ), view.getUint8( 1 ) ); - if ( magic === 'PK' ) { let zip = null; let file = null; console.log( 'THREE.AMFLoader: Loading Zip' ); - try { zip = fflate.unzipSync( new Uint8Array( data ) ); // eslint-disable-line no-undef @@ -103,7 +99,6 @@ const fileText = THREE.LoaderUtils.decodeText( view ); const xmlData = new DOMParser().parseFromString( fileText, 'application/xml' ); - if ( xmlData.documentElement.nodeName.toLowerCase() !== 'amf' ) { console.log( 'THREE.AMFLoader: Error loading AMF - no AMF document found.' ); @@ -119,7 +114,6 @@ let scale = 1.0; let unit = 'millimeter'; - if ( node.documentElement.attributes.unit !== undefined ) { unit = node.documentElement.attributes.unit.value.toLowerCase(); @@ -133,7 +127,6 @@ meter: 1000.0, micron: 0.001 }; - if ( scaleUnits[ unit ] !== undefined ) { scale = scaleUnits[ unit ]; @@ -156,11 +149,9 @@ a: 1.0 }; let loadedMaterial = null; - for ( let i = 0; i < node.childNodes.length; i ++ ) { const matChildEl = node.childNodes[ i ]; - if ( matChildEl.nodeName === 'metadata' && matChildEl.attributes.type !== undefined ) { if ( matChildEl.attributes.type.value === 'name' ) { @@ -182,7 +173,6 @@ color: new THREE.Color( color.r, color.g, color.b ), name: matName } ); - if ( color.a !== 1.0 ) { loadedMaterial.transparent = true; @@ -205,11 +195,9 @@ b: 1.0, a: 1.0 }; - for ( let i = 0; i < node.childNodes.length; i ++ ) { const matColor = node.childNodes[ i ]; - if ( matColor.nodeName === 'r' ) { color.r = matColor.textContent; @@ -242,7 +230,6 @@ materialid: null }; let currVolumeNode = node.firstElementChild; - if ( node.attributes.materialid !== undefined ) { volume.materialId = node.attributes.materialid.nodeValue; @@ -285,13 +272,11 @@ const vertArray = []; const normalArray = []; let currVerticesNode = node.firstElementChild; - while ( currVerticesNode ) { if ( currVerticesNode.nodeName === 'vertex' ) { let vNode = currVerticesNode.firstElementChild; - while ( vNode ) { if ( vNode.nodeName === 'coordinates' ) { @@ -336,7 +321,6 @@ }; let currColor = null; let currObjNode = node.firstElementChild; - while ( currObjNode ) { if ( currObjNode.nodeName === 'metadata' ) { @@ -364,7 +348,6 @@ volumes: [], color: currColor }; - while ( currMeshNode ) { if ( currMeshNode.nodeName === 'vertices' ) { @@ -406,11 +389,9 @@ const amfObjects = {}; const childNodes = xmlData.documentElement.childNodes; let i, j; - for ( i = 0; i < childNodes.length; i ++ ) { const child = childNodes[ i ]; - if ( child.nodeName === 'metadata' ) { if ( child.attributes.type !== undefined ) { @@ -449,21 +430,18 @@ sceneObject.name = amfName; sceneObject.userData.author = amfAuthor; sceneObject.userData.loader = 'AMF'; - for ( const id in amfObjects ) { const part = amfObjects[ id ]; const meshes = part.meshes; const newObject = new THREE.Group(); newObject.name = part.name || ''; - for ( i = 0; i < meshes.length; i ++ ) { let objDefaultMaterial = defaultMaterial; const mesh = meshes[ i ]; const vertices = new THREE.Float32BufferAttribute( mesh.vertices, 3 ); let normals = null; - if ( mesh.normals.length ) { normals = new THREE.Float32BufferAttribute( mesh.normals, 3 ); @@ -475,7 +453,6 @@ const color = mesh.color; objDefaultMaterial = defaultMaterial.clone(); objDefaultMaterial.color = new THREE.Color( color.r, color.g, color.b ); - if ( color.a !== 1.0 ) { objDefaultMaterial.transparent = true; @@ -486,7 +463,6 @@ } const volumes = mesh.volumes; - for ( j = 0; j < volumes.length; j ++ ) { const volume = volumes[ j ]; @@ -494,7 +470,6 @@ let material = objDefaultMaterial; newGeometry.setIndex( volume.triangles ); newGeometry.setAttribute( 'position', vertices.clone() ); - if ( normals ) { newGeometry.setAttribute( 'normal', normals.clone() ); diff --git a/examples/js/loaders/BVHLoader.js b/examples/js/loaders/BVHLoader.js index 3054afbd5c12ff..452ed5a9a58462 100644 --- a/examples/js/loaders/BVHLoader.js +++ b/examples/js/loaders/BVHLoader.js @@ -16,7 +16,6 @@ this.animateBoneRotations = true; } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -49,7 +48,6 @@ }, onProgress, onError ); } - parse( text ) { /* @@ -61,6 +59,7 @@ function readBvh( lines ) { // read model structure + if ( nextLine( lines ) !== 'HIERARCHY' ) { console.error( 'THREE.BVHLoader: HIERARCHY expected.' ); @@ -68,35 +67,37 @@ } const list = []; // collects flat array of all bones + const root = readNode( lines, nextLine( lines ), list ); - const root = readNode( lines, nextLine( lines ), list ); // read motion data + // read motion data if ( nextLine( lines ) !== 'MOTION' ) { console.error( 'THREE.BVHLoader: MOTION expected.' ); - } // number of frames + } + // number of frames let tokens = nextLine( lines ).split( /[\s]+/ ); const numFrames = parseInt( tokens[ 1 ] ); - if ( isNaN( numFrames ) ) { console.error( 'THREE.BVHLoader: Failed to read number of frames.' ); - } // frame time + } + // frame time tokens = nextLine( lines ).split( /[\s]+/ ); const frameTime = parseFloat( tokens[ 2 ] ); - if ( isNaN( frameTime ) ) { console.error( 'THREE.BVHLoader: Failed to read frame time.' ); - } // read frame data line by line + } + // read frame data line by line for ( let i = 0; i < numFrames; i ++ ) { @@ -108,6 +109,7 @@ return list; } + /* Recursively reads data from a single frame into the bone hierarchy. The passed bone hierarchy has to be structured in the same order as the BVH file. @@ -117,12 +119,13 @@ - frameTime: playback time for this keyframe. - bone: the bone to read frame data from. */ - - function readFrameData( data, frameTime, bone ) { // end sites have no motion data - if ( bone.type === 'ENDSITE' ) return; // add keyframe + + if ( bone.type === 'ENDSITE' ) return; + + // add keyframe const keyframe = { time: frameTime, @@ -133,7 +136,9 @@ const quat = new THREE.Quaternion(); const vx = new THREE.Vector3( 1, 0, 0 ); const vy = new THREE.Vector3( 0, 1, 0 ); - const vz = new THREE.Vector3( 0, 0, 1 ); // parse values for each channel in node + const vz = new THREE.Vector3( 0, 0, 1 ); + + // parse values for each channel in node for ( let i = 0; i < bone.channels.length; i ++ ) { @@ -142,37 +147,32 @@ case 'Xposition': keyframe.position.x = parseFloat( data.shift().trim() ); break; - case 'Yposition': keyframe.position.y = parseFloat( data.shift().trim() ); break; - case 'Zposition': keyframe.position.z = parseFloat( data.shift().trim() ); break; - case 'Xrotation': quat.setFromAxisAngle( vx, parseFloat( data.shift().trim() ) * Math.PI / 180 ); keyframe.rotation.multiply( quat ); break; - case 'Yrotation': quat.setFromAxisAngle( vy, parseFloat( data.shift().trim() ) * Math.PI / 180 ); keyframe.rotation.multiply( quat ); break; - case 'Zrotation': quat.setFromAxisAngle( vz, parseFloat( data.shift().trim() ) * Math.PI / 180 ); keyframe.rotation.multiply( quat ); break; - default: console.warn( 'THREE.BVHLoader: Invalid channel type.' ); } - } // parse child nodes + } + // parse child nodes for ( let i = 0; i < bone.children.length; i ++ ) { @@ -181,6 +181,7 @@ } } + /* Recursively parses the HIERACHY section of the BVH file - lines: all lines of the file. lines are consumed as we go along. @@ -188,8 +189,6 @@ - list: collects a flat list of nodes returns: a BVH node including children */ - - function readNode( lines, firstline, list ) { const node = { @@ -197,10 +196,11 @@ type: '', frames: [] }; - list.push( node ); // parse node type and name + list.push( node ); - let tokens = firstline.split( /[\s]+/ ); + // parse node type and name + let tokens = firstline.split( /[\s]+/ ); if ( tokens[ 0 ].toUpperCase() === 'END' && tokens[ 1 ].toUpperCase() === 'SITE' ) { node.type = 'ENDSITE'; @@ -217,11 +217,11 @@ console.error( 'THREE.BVHLoader: Expected opening { after type & name' ); - } // parse OFFSET + } + // parse OFFSET tokens = nextLine( lines ).split( /[\s]+/ ); - if ( tokens[ 0 ] !== 'OFFSET' ) { console.error( 'THREE.BVHLoader: Expected OFFSET but got: ' + tokens[ 0 ] ); @@ -235,19 +235,19 @@ } const offset = new THREE.Vector3( parseFloat( tokens[ 1 ] ), parseFloat( tokens[ 2 ] ), parseFloat( tokens[ 3 ] ) ); - if ( isNaN( offset.x ) || isNaN( offset.y ) || isNaN( offset.z ) ) { console.error( 'THREE.BVHLoader: Invalid values of OFFSET.' ); } - node.offset = offset; // parse CHANNELS definitions + node.offset = offset; + + // parse CHANNELS definitions if ( node.type !== 'ENDSITE' ) { tokens = nextLine( lines ).split( /[\s]+/ ); - if ( tokens[ 0 ] !== 'CHANNELS' ) { console.error( 'THREE.BVHLoader: Expected CHANNELS definition.' ); @@ -258,13 +258,13 @@ node.channels = tokens.splice( 2, numChannels ); node.children = []; - } // read children + } + // read children while ( true ) { const line = nextLine( lines ); - if ( line === '}' ) { return node; @@ -278,21 +278,19 @@ } } + /* recursively converts the internal bvh node structure to a THREE.Bone hierarchy source: the bvh root node list: pass an empty array, collects a flat list of all converted THREE.Bones returns the root THREE.Bone */ - - function toTHREEBone( source, list ) { const bone = new THREE.Bone(); list.push( bone ); bone.position.add( source.offset ); bone.name = source.name; - if ( source.type !== 'ENDSITE' ) { for ( let i = 0; i < source.children.length; i ++ ) { @@ -306,30 +304,34 @@ return bone; } + /* builds a THREE.AnimationClip from the keyframe data saved in each bone. bone: bvh root node returns: a THREE.AnimationClip containing position and quaternion tracks */ - - function toTHREEAnimation( bones ) { - const tracks = []; // create a position and quaternion animation track for each node + const tracks = []; + + // create a position and quaternion animation track for each node for ( let i = 0; i < bones.length; i ++ ) { const bone = bones[ i ]; - if ( bone.type === 'ENDSITE' ) continue; // track data + if ( bone.type === 'ENDSITE' ) continue; + + // track data const times = []; const positions = []; const rotations = []; - for ( let j = 0; j < bone.frames.length; j ++ ) { const frame = bone.frames[ j ]; - times.push( frame.time ); // the animation system animates the position property, + times.push( frame.time ); + + // the animation system animates the position property, // so we have to add the joint offset to all values positions.push( frame.position.x + bone.offset.x ); @@ -359,15 +361,14 @@ return new THREE.AnimationClip( 'animation', - 1, tracks ); } + /* returns the next non-empty line in lines */ - - function nextLine( lines ) { - let line; // skip empty lines - + let line; + // skip empty lines while ( ( line = lines.shift().trim() ).length === 0 ) {} return line; diff --git a/examples/js/loaders/BasisTextureLoader.js b/examples/js/loaders/BasisTextureLoader.js index dcfb7a458536e9..d28a34f1657898 100644 --- a/examples/js/loaders/BasisTextureLoader.js +++ b/examples/js/loaders/BasisTextureLoader.js @@ -14,7 +14,6 @@ */ const _taskCache = new WeakMap(); - class BasisTextureLoader extends THREE.Loader { constructor( manager ) { @@ -31,21 +30,18 @@ console.warn( 'THREE.BasisTextureLoader: This loader is deprecated, and will be removed in a future release. ' + 'Instead, use Basis Universal compression in KTX2 (.ktx2) files with THREE.KTX2Loader.' ); } - setTranscoderPath( path ) { this.transcoderPath = path; return this; } - setWorkerLimit( workerLimit ) { this.workerLimit = workerLimit; return this; } - detectSupport( renderer ) { this.workerConfig = { @@ -59,7 +55,6 @@ return this; } - load( url, onLoad, onProgress, onError ) { const loader = new THREE.FileLoader( this.manager ); @@ -73,7 +68,6 @@ if ( _taskCache.has( buffer ) ) { const cachedTask = _taskCache.get( buffer ); - return cachedTask.promise.then( onLoad ).catch( onError ); } @@ -90,41 +84,38 @@ return texture; } - /** Low-level transcoding API, exposed for use by KTX2Loader. */ - + /** Low-level transcoding API, exposed for use by KTX2Loader. */ parseInternalAsync( options ) { const { levels } = options; const buffers = new Set(); - for ( let i = 0; i < levels.length; i ++ ) { buffers.add( levels[ i ].data.buffer ); } - return this._createTexture( Array.from( buffers ), { ...options, + return this._createTexture( Array.from( buffers ), { + ...options, lowLevel: true } ); } + /** * @param {ArrayBuffer[]} buffers * @param {object?} config * @return {Promise} */ - - _createTexture( buffers, config = {} ) { let worker; let taskID; const taskConfig = config; let taskCost = 0; - for ( let i = 0; i < buffers.length; i ++ ) { taskCost += buffers[ i ].byteLength; @@ -165,9 +156,9 @@ texture.needsUpdate = true; return texture; - } ); // Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416) - + } ); + // Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416) texturePending.catch( () => true ).then( () => { if ( worker && taskID ) { @@ -177,16 +168,15 @@ } - } ); // Cache the task result. + } ); + // Cache the task result. _taskCache.set( buffers[ 0 ], { promise: texturePending } ); - return texturePending; } - _initTranscoder() { if ( ! this.transcoderPending ) { @@ -199,8 +189,9 @@ jsLoader.load( 'basis_transcoder.js', resolve, undefined, reject ); - } ); // Load transcoder WASM binary. + } ); + // Load transcoder WASM binary. const binaryLoader = new THREE.FileLoader( this.manager ); binaryLoader.setPath( this.transcoderPath ); binaryLoader.setResponseType( 'arraybuffer' ); @@ -224,7 +215,6 @@ return this.transcoderPending; } - _allocateWorker( taskCost ) { return this._initTranscoder().then( () => { @@ -239,23 +229,17 @@ config: this.workerConfig, transcoderBinary: this.transcoderBinary } ); - worker.onmessage = function ( e ) { const message = e.data; - switch ( message.type ) { case 'transcode': worker._callbacks[ message.id ].resolve( message ); - break; - case 'error': worker._callbacks[ message.id ].reject( message ); - break; - default: console.error( 'THREE.BasisTextureLoader: Unexpected message, "' + message.type + '"' ); @@ -282,7 +266,6 @@ } ); } - dispose() { for ( let i = 0; i < this.workerPool.length; i ++ ) { @@ -297,8 +280,8 @@ } } - /* CONSTANTS */ + /* CONSTANTS */ BasisTextureLoader.BasisFormat = { ETC1S: 0, @@ -335,6 +318,7 @@ RGB_PVRTC_4BPPV1_Format: THREE.RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format: THREE.RGB_S3TC_DXT1_Format }; + /* WEB WORKER */ BasisTextureLoader.BasisWorker = function () { @@ -343,22 +327,18 @@ let transcoderPending; let BasisModule; const EngineFormat = _EngineFormat; // eslint-disable-line no-undef - const TranscoderFormat = _TranscoderFormat; // eslint-disable-line no-undef - const BasisFormat = _BasisFormat; // eslint-disable-line no-undef onmessage = function ( e ) { const message = e.data; - switch ( message.type ) { case 'init': config = message.config; init( message.transcoderBinary ); break; - case 'transcode': transcoderPending.then( () => { @@ -372,7 +352,6 @@ format } = message.taskConfig.lowLevel ? transcodeLowLevel( message.taskConfig ) : transcode( message.buffers[ 0 ] ); const buffers = []; - for ( let i = 0; i < mipmaps.length; ++ i ) { buffers.push( mipmaps[ i ].data.buffer ); @@ -440,7 +419,6 @@ const blockByteLength = BasisModule.getBytesPerBlockOrPixel( transcoderFormat ); assert( BasisModule.isFormatSupported( transcoderFormat ), 'THREE.BasisTextureLoader: Unsupported format.' ); const mipmaps = []; - if ( basisFormat === BasisFormat.ETC1S ) { const transcoder = new BasisModule.LowLevelETC1SImageTranscoder(); @@ -451,7 +429,6 @@ selectorsData, tablesData } = taskConfig.globalData; - try { let ok; @@ -459,7 +436,6 @@ assert( ok, 'THREE.BasisTextureLoader: decodePalettes() failed.' ); ok = transcoder.decodeTables( tablesData ); assert( ok, 'THREE.BasisTextureLoader: decodeTables() failed.' ); - for ( let i = 0; i < taskConfig.levels.length; i ++ ) { const level = taskConfig.levels[ i ]; @@ -519,7 +495,6 @@ const height = basisFile.getImageHeight( 0, 0 ); const levels = basisFile.getNumLevels( 0 ); const hasAlpha = basisFile.getHasAlpha(); - function cleanup() { basisFile.close(); @@ -531,7 +506,6 @@ transcoderFormat, engineFormat } = getTranscoderFormat( basisFormat, width, height, hasAlpha ); - if ( ! width || ! height || ! levels ) { cleanup(); @@ -547,14 +521,12 @@ } const mipmaps = []; - for ( let mip = 0; mip < levels; mip ++ ) { const mipWidth = basisFile.getImageWidth( 0, mip ); const mipHeight = basisFile.getImageHeight( 0, mip ); const dst = new Uint8Array( basisFile.getImageTranscodedSizeInBytes( 0, mip, transcoderFormat ) ); const status = basisFile.transcodeImage( dst, 0, mip, transcoderFormat, 0, hasAlpha ); - if ( ! status ) { cleanup(); @@ -579,7 +551,10 @@ format: engineFormat }; - } // + } + + // + // Optimal choice of a transcoder target format depends on the Basis format (ETC1S or UASTC), // device capabilities, and texture dimensions. The list below ranks the formats separately // for ETC1S and UASTC. @@ -587,8 +562,6 @@ // In some cases, transcoding UASTC to RGBA32 might be preferred for higher quality (at // significant memory cost) compared to ETC1/2, BC1/3, and PVRTC. The transcoder currently // chooses RGBA32 only as a last resort and does not expose that option to the caller. - - const FORMAT_OPTIONS = [ { if: 'astcSupported', basisFormat: [ BasisFormat.UASTC_4x4 ], @@ -648,13 +621,11 @@ return a.priorityUASTC - b.priorityUASTC; } ); - function getTranscoderFormat( basisFormat, width, height, hasAlpha ) { let transcoderFormat; let engineFormat; const options = basisFormat === BasisFormat.ETC1S ? ETC1S_OPTIONS : UASTC_OPTIONS; - for ( let i = 0; i < options.length; i ++ ) { const opt = options[ i ]; @@ -701,7 +672,6 @@ function getTranscodedImageByteLength( transcoderFormat, width, height ) { const blockByteLength = BasisModule.getBytesPerBlockOrPixel( transcoderFormat ); - if ( BasisModule.formatIsUncompressed( transcoderFormat ) ) { return width * height * blockByteLength; diff --git a/examples/js/loaders/ColladaLoader.js b/examples/js/loaders/ColladaLoader.js index 605c695d591b38..8d994719b70478 100644 --- a/examples/js/loaders/ColladaLoader.js +++ b/examples/js/loaders/ColladaLoader.js @@ -7,7 +7,6 @@ super( manager ); } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -41,19 +40,17 @@ }, onProgress, onError ); } - parse( text, path ) { function getElementsByTagName( xml, name ) { // Non recursive xml.getElementsByTagName() ... + const array = []; const childNodes = xml.childNodes; - for ( let i = 0, l = childNodes.length; i < l; i ++ ) { const child = childNodes[ i ]; - if ( child.nodeName === name ) { array.push( child ); @@ -71,7 +68,6 @@ if ( text.length === 0 ) return []; const parts = text.trim().split( /\s+/ ); const array = new Array( parts.length ); - for ( let i = 0, l = parts.length; i < l; i ++ ) { array[ i ] = parts[ i ]; @@ -87,7 +83,6 @@ if ( text.length === 0 ) return []; const parts = text.trim().split( /\s+/ ); const array = new Array( parts.length ); - for ( let i = 0, l = parts.length; i < l; i ++ ) { array[ i ] = parseFloat( parts[ i ] ); @@ -103,7 +98,6 @@ if ( text.length === 0 ) return []; const parts = text.trim().split( /\s+/ ); const array = new Array( parts.length ); - for ( let i = 0, l = parts.length; i < l; i ++ ) { array[ i ] = parseInt( parts[ i ] ); @@ -130,8 +124,9 @@ return Object.keys( object ).length === 0; - } // asset + } + // asset function parseAsset( xml ) { @@ -160,17 +155,16 @@ return xml !== undefined ? xml.textContent : 'Y_UP'; - } // library + } + // library function parseLibrary( xml, libraryName, nodeName, parser ) { const library = getElementsByTagName( xml, libraryName )[ 0 ]; - if ( library !== undefined ) { const elements = getElementsByTagName( library, nodeName ); - for ( let i = 0; i < elements.length; i ++ ) { parser( elements[ i ] ); @@ -190,8 +184,9 @@ } - } // get + } + // get function getBuild( data, builder ) { @@ -199,8 +194,9 @@ data.build = builder( data ); return data.build; - } // animation + } + // animation function parseAnimation( xml ) { @@ -210,36 +206,30 @@ channels: {} }; let hasChildren = false; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; let id; - switch ( child.nodeName ) { case 'source': id = child.getAttribute( 'id' ); data.sources[ id ] = parseSource( child ); break; - case 'sampler': id = child.getAttribute( 'id' ); data.samplers[ id ] = parseAnimationSampler( child ); break; - case 'channel': id = child.getAttribute( 'target' ); data.channels[ id ] = parseAnimationChannel( child ); break; - case 'animation': // hierarchy of related animations parseAnimation( child ); hasChildren = true; break; - default: console.log( child ); @@ -250,6 +240,7 @@ if ( hasChildren === false ) { // since 'id' attributes can be optional, it's necessary to generate a UUID for unqiue assignment + library.animations[ xml.getAttribute( 'id' ) || THREE.MathUtils.generateUUID() ] = data; } @@ -261,12 +252,10 @@ const data = { inputs: {} }; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'input': @@ -286,18 +275,22 @@ function parseAnimationChannel( xml ) { const data = {}; - const target = xml.getAttribute( 'target' ); // parsing SID Addressing Syntax + const target = xml.getAttribute( 'target' ); + + // parsing SID Addressing Syntax let parts = target.split( '/' ); const id = parts.shift(); - let sid = parts.shift(); // check selection syntax + let sid = parts.shift(); + + // check selection syntax const arraySyntax = sid.indexOf( '(' ) !== - 1; const memberSyntax = sid.indexOf( '.' ) !== - 1; - if ( memberSyntax ) { // member selection access + parts = sid.split( '.' ); sid = parts.shift(); data.member = parts.shift(); @@ -305,9 +298,9 @@ } else if ( arraySyntax ) { // array-access syntax. can be used to express fields in one-dimensional vectors or two-dimensional matrices. + const indices = sid.split( '(' ); sid = indices.shift(); - for ( let i = 0; i < indices.length; i ++ ) { indices[ i ] = parseInt( indices[ i ].replace( /\)/, '' ) ); @@ -333,7 +326,6 @@ const channels = data.channels; const samplers = data.samplers; const sources = data.sources; - for ( const target in channels ) { if ( channels.hasOwnProperty( target ) ) { @@ -369,7 +361,9 @@ const defaultMatrix = node.matrix.clone().transpose(); let time, stride; let i, il, j, jl; - const data = {}; // the collada spec allows the animation of data in various ways. + const data = {}; + + // the collada spec allows the animation of data in various ways. // depending on the transform type (matrix, translate, rotate, scale), we execute different logic switch ( transform ) { @@ -380,7 +374,6 @@ time = inputSource.array[ i ]; stride = i * outputSource.stride; if ( data[ time ] === undefined ) data[ time ] = {}; - if ( channel.arraySyntax === true ) { const value = outputSource.array[ stride ]; @@ -400,15 +393,12 @@ } break; - case 'translate': console.warn( 'THREE.ColladaLoader: Animation transform type "%s" not yet implemented.', transform ); break; - case 'rotate': console.warn( 'THREE.ColladaLoader: Animation transform type "%s" not yet implemented.', transform ); break; - case 'scale': console.warn( 'THREE.ColladaLoader: Animation transform type "%s" not yet implemented.', transform ); break; @@ -426,7 +416,9 @@ function prepareAnimationData( data, defaultMatrix ) { - const keyframes = []; // transfer data into a sortable array + const keyframes = []; + + // transfer data into a sortable array for ( const time in data ) { @@ -435,10 +427,13 @@ value: data[ time ] } ); - } // ensure keyframes are sorted by time + } + + // ensure keyframes are sorted by time + keyframes.sort( ascending ); - keyframes.sort( ascending ); // now we clean up all animation data, so we can use them for keyframe tracks + // now we clean up all animation data, so we can use them for keyframe tracks for ( let i = 0; i < 16; i ++ ) { @@ -446,7 +441,9 @@ } - return keyframes; // array sort function + return keyframes; + + // array sort function function ascending( a, b ) { @@ -459,7 +456,6 @@ const position = new THREE.Vector3(); const scale = new THREE.Vector3(); const quaternion = new THREE.Quaternion(); - function createKeyframeTracks( animation, tracks ) { const keyframes = animation.keyframes; @@ -468,7 +464,6 @@ const positionData = []; const quaternionData = []; const scaleData = []; - for ( let i = 0, l = keyframes.length; i < l; i ++ ) { const keyframe = keyframes[ i ]; @@ -494,12 +489,13 @@ let keyframe; let empty = true; - let i, l; // check, if values of a property are missing in our keyframes + let i, l; + + // check, if values of a property are missing in our keyframes for ( i = 0, l = keyframes.length; i < l; i ++ ) { keyframe = keyframes[ i ]; - if ( keyframe.value[ property ] === undefined ) { keyframe.value[ property ] = null; // mark as missing @@ -515,6 +511,7 @@ if ( empty === true ) { // no values at all, so we set a default value + for ( i = 0, l = keyframes.length; i < l; i ++ ) { keyframe = keyframes[ i ]; @@ -525,6 +522,7 @@ } else { // filling gaps + createMissingKeyframes( keyframes, property ); } @@ -534,16 +532,13 @@ function createMissingKeyframes( keyframes, property ) { let prev, next; - for ( let i = 0, l = keyframes.length; i < l; i ++ ) { const keyframe = keyframes[ i ]; - if ( keyframe.value[ property ] === null ) { prev = getPrev( keyframes, i, property ); next = getNext( keyframes, i, property ); - if ( prev === null ) { keyframe.value[ property ] = next.value[ property ]; @@ -605,8 +600,9 @@ key.value[ property ] = ( key.time - prev.time ) * ( next.value[ property ] - prev.value[ property ] ) / ( next.time - prev.time ) + prev.value[ property ]; - } // animation clips + } + // animation clips function parseAnimationClip( xml ) { @@ -616,12 +612,10 @@ end: parseFloat( xml.getAttribute( 'end' ) || 0 ), animations: [] }; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'instance_animation': @@ -642,11 +636,9 @@ const name = data.name; const duration = data.end - data.start || - 1; const animations = data.animations; - for ( let i = 0, il = animations.length; i < il; i ++ ) { const animationTracks = getAnimation( animations[ i ] ); - for ( let j = 0, jl = animationTracks.length; j < jl; j ++ ) { tracks.push( animationTracks[ j ] ); @@ -663,18 +655,17 @@ return getBuild( library.clips[ id ], buildAnimationClip ); - } // controller + } + // controller function parseController( xml ) { const data = {}; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'skin': @@ -682,7 +673,6 @@ data.id = parseId( child.getAttribute( 'source' ) ); data.skin = parseSkin( child ); break; - case 'morph': data.id = parseId( child.getAttribute( 'source' ) ); console.warn( 'THREE.ColladaLoader: Morph target animation not supported yet.' ); @@ -701,27 +691,22 @@ const data = { sources: {} }; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'bind_shape_matrix': data.bindShapeMatrix = parseFloats( child.textContent ); break; - case 'source': const id = child.getAttribute( 'id' ); data.sources[ id ] = parseSource( child ); break; - case 'joints': data.joints = parseJoints( child ); break; - case 'vertex_weights': data.vertexWeights = parseVertexWeights( child ); break; @@ -739,12 +724,10 @@ const data = { inputs: {} }; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'input': @@ -766,12 +749,10 @@ const data = { inputs: {} }; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'input': @@ -783,11 +764,9 @@ offset: offset }; break; - case 'vcount': data.vcount = parseInts( child.textContent ); break; - case 'v': data.v = parseInts( child.textContent ); break; @@ -806,10 +785,11 @@ id: data.id }; const geometry = library.geometries[ build.id ]; - if ( data.skin !== undefined ) { - build.skin = buildSkin( data.skin ); // we enhance the 'sources' property of the corresponding geometry with our skin data + build.skin = buildSkin( data.skin ); + + // we enhance the 'sources' property of the corresponding geometry with our skin data geometry.sources.skinIndices = build.skin.indices; geometry.sources.skinWeights = build.skin.weights; @@ -845,14 +825,14 @@ const inverseSource = data.sources[ data.joints.inputs.INV_BIND_MATRIX ]; const weights = sources[ vertexWeights.inputs.WEIGHT.id ].array; let stride = 0; - let i, j, l; // procces skin data for each vertex + let i, j, l; + + // procces skin data for each vertex for ( i = 0, l = vcount.length; i < l; i ++ ) { const jointCount = vcount[ i ]; // this is the amount of joints that affect a single vertex - const vertexSkinData = []; - for ( j = 0; j < jointCount; j ++ ) { const skinIndex = v[ stride + jointOffset ]; @@ -864,17 +844,19 @@ } ); stride += 2; - } // we sort the joints in descending order based on the weights. + } + + // we sort the joints in descending order based on the weights. // this ensures, we only procced the most important joints of the vertex + vertexSkinData.sort( descending ); - vertexSkinData.sort( descending ); // now we provide for each vertex a set of four index and weight values. + // now we provide for each vertex a set of four index and weight values. // the order of the skin data matches the order of vertices for ( j = 0; j < BONE_LIMIT; j ++ ) { const d = vertexSkinData[ j ]; - if ( d !== undefined ) { build.indices.array.push( d.index ); @@ -889,8 +871,9 @@ } - } // setup bind matrix + } + // setup bind matrix if ( data.bindShapeMatrix ) { @@ -900,8 +883,9 @@ build.bindMatrix = new THREE.Matrix4().identity(); - } // process bones and inverse bind matrix data + } + // process bones and inverse bind matrix data for ( i = 0, l = jointSource.array.length; i < l; i ++ ) { @@ -914,7 +898,9 @@ } - return build; // array sort function + return build; + + // array sort function function descending( a, b ) { @@ -928,8 +914,9 @@ return getBuild( library.controllers[ id ], buildController ); - } // image + } + // image function parseImage( xml ) { @@ -950,7 +937,6 @@ function getImage( id ) { const data = library.images[ id ]; - if ( data !== undefined ) { return getBuild( data, buildImage ); @@ -960,18 +946,17 @@ console.warn( 'THREE.ColladaLoader: Couldn\'t find image with ID:', id ); return null; - } // effect + } + // effect function parseEffect( xml ) { const data = {}; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'profile_COMMON': @@ -992,22 +977,18 @@ surfaces: {}, samplers: {} }; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'newparam': parseEffectNewparam( child, data ); break; - case 'technique': data.technique = parseEffectTechnique( child ); break; - case 'extra': data.extra = parseEffectExtra( child ); break; @@ -1023,18 +1004,15 @@ function parseEffectNewparam( xml, data ) { const sid = xml.getAttribute( 'sid' ); - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'surface': data.surfaces[ sid ] = parseEffectSurface( child ); break; - case 'sampler2D': data.samplers[ sid ] = parseEffectSampler( child ); break; @@ -1048,12 +1026,10 @@ function parseEffectSurface( xml ) { const data = {}; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'init_from': @@ -1071,12 +1047,10 @@ function parseEffectSampler( xml ) { const data = {}; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'source': @@ -1094,12 +1068,10 @@ function parseEffectTechnique( xml ) { const data = {}; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'constant': @@ -1109,7 +1081,6 @@ data.type = child.nodeName; data.parameters = parseEffectParameters( child ); break; - case 'extra': data.extra = parseEffectExtra( child ); break; @@ -1125,12 +1096,10 @@ function parseEffectParameters( xml ) { const data = {}; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'emission': @@ -1142,7 +1111,6 @@ case 'transparency': data[ child.nodeName ] = parseEffectParameter( child ); break; - case 'transparent': data[ child.nodeName ] = { opaque: child.hasAttribute( 'opaque' ) ? child.getAttribute( 'opaque' ) : 'A_ONE', @@ -1161,22 +1129,18 @@ function parseEffectParameter( xml ) { const data = {}; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'color': data[ child.nodeName ] = parseFloats( child.textContent ); break; - case 'float': data[ child.nodeName ] = parseFloat( child.textContent ); break; - case 'texture': data[ child.nodeName ] = { id: child.getAttribute( 'texture' ), @@ -1197,12 +1161,10 @@ const data = { technique: {} }; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'extra': @@ -1223,7 +1185,6 @@ const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'technique': @@ -1242,7 +1203,6 @@ const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'repeatU': @@ -1251,10 +1211,10 @@ case 'offsetV': data.technique[ child.nodeName ] = parseFloat( child.textContent ); break; - case 'wrapU': case 'wrapV': // some files have values for wrapU/wrapV which become NaN via parseInt + if ( child.textContent.toUpperCase() === 'TRUE' ) { data.technique[ child.nodeName ] = 1; @@ -1270,7 +1230,6 @@ } break; - case 'bump': data[ child.nodeName ] = parseEffectExtraTechniqueBump( child ); break; @@ -1284,12 +1243,10 @@ function parseEffectExtra( xml ) { const data = {}; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'technique': @@ -1307,18 +1264,15 @@ function parseEffectExtraTechnique( xml ) { const data = {}; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'double_sided': data[ child.nodeName ] = parseInt( child.textContent ); break; - case 'bump': data[ child.nodeName ] = parseEffectExtraTechniqueBump( child ); break; @@ -1334,12 +1288,10 @@ function parseEffectExtraTechniqueBump( xml ) { const data = {}; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'texture': @@ -1368,20 +1320,19 @@ return getBuild( library.effects[ id ], buildEffect ); - } // material + } + // material function parseMaterial( xml ) { const data = { name: xml.getAttribute( 'name' ) }; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'instance_effect': @@ -1400,15 +1351,12 @@ let loader; let extension = image.slice( ( image.lastIndexOf( '.' ) - 1 >>> 0 ) + 2 ); // http://www.jstips.co/en/javascript/get-file-extension/ - extension = extension.toLowerCase(); - switch ( extension ) { case 'tga': loader = tgaLoader; break; - default: loader = textureLoader; @@ -1423,18 +1371,15 @@ const effect = getEffect( data.url ); const technique = effect.profile.technique; let material; - switch ( technique.type ) { case 'phong': case 'blinn': material = new THREE.MeshPhongMaterial(); break; - case 'lambert': material = new THREE.MeshLambertMaterial(); break; - default: material = new THREE.MeshBasicMaterial(); break; @@ -1442,11 +1387,12 @@ } material.name = data.name || ''; - function getTexture( textureObject, encoding = null ) { const sampler = effect.profile.samplers[ textureObject.id ]; - let image = null; // get image + let image = null; + + // get image if ( sampler !== undefined ) { @@ -1458,18 +1404,17 @@ console.warn( 'THREE.ColladaLoader: Undefined sampler. Access image directly (see #12530).' ); image = getImage( textureObject.id ); - } // create texture if image is avaiable + } + // create texture if image is avaiable if ( image !== null ) { const loader = getTextureLoader( image ); - if ( loader !== undefined ) { const texture = loader.load( image ); const extra = textureObject.extra; - if ( extra !== undefined && extra.technique !== undefined && isEmpty( extra.technique ) === false ) { const technique = extra.technique; @@ -1510,35 +1455,28 @@ } const parameters = technique.parameters; - for ( const key in parameters ) { const parameter = parameters[ key ]; - switch ( key ) { case 'diffuse': if ( parameter.color ) material.color.fromArray( parameter.color ); if ( parameter.texture ) material.map = getTexture( parameter.texture, THREE.sRGBEncoding ); break; - case 'specular': if ( parameter.color && material.specular ) material.specular.fromArray( parameter.color ); if ( parameter.texture ) material.specularMap = getTexture( parameter.texture ); break; - case 'bump': if ( parameter.texture ) material.normalMap = getTexture( parameter.texture ); break; - case 'ambient': if ( parameter.texture ) material.lightMap = getTexture( parameter.texture, THREE.sRGBEncoding ); break; - case 'shininess': if ( parameter.float && material.shininess ) material.shininess = parameter.float; break; - case 'emission': if ( parameter.color && material.emissive ) material.emissive.fromArray( parameter.color ); if ( parameter.texture ) material.emissiveMap = getTexture( parameter.texture, THREE.sRGBEncoding ); @@ -1550,10 +1488,14 @@ material.color.convertSRGBToLinear(); if ( material.specular ) material.specular.convertSRGBToLinear(); - if ( material.emissive ) material.emissive.convertSRGBToLinear(); // + if ( material.emissive ) material.emissive.convertSRGBToLinear(); + + // let transparent = parameters[ 'transparent' ]; - let transparency = parameters[ 'transparency' ]; // does not exist but + let transparency = parameters[ 'transparency' ]; + + // does not exist but if ( transparency === undefined && transparent ) { @@ -1561,8 +1503,9 @@ float: 1 }; - } // does not exist but + } + // does not exist but if ( transparent === undefined && transparency ) { @@ -1578,33 +1521,30 @@ if ( transparent && transparency ) { // handle case if a texture exists but no color + if ( transparent.data.texture ) { // we do not set an alpha map (see #13792) + material.transparent = true; } else { const color = transparent.data.color; - switch ( transparent.opaque ) { case 'A_ONE': material.opacity = color[ 3 ] * transparency.float; break; - case 'RGB_ZERO': material.opacity = 1 - color[ 0 ] * transparency.float; break; - case 'A_ZERO': material.opacity = 1 - color[ 3 ] * transparency.float; break; - case 'RGB_ONE': material.opacity = color[ 0 ] * transparency.float; break; - default: console.warn( 'THREE.ColladaLoader: Invalid opaque type "%s" of transparent tag.', transparent.opaque ); @@ -1614,23 +1554,21 @@ } - } // + } + // if ( technique.extra !== undefined && technique.extra.technique !== undefined ) { const techniques = technique.extra.technique; - for ( const k in techniques ) { const v = techniques[ k ]; - switch ( k ) { case 'double_sided': material.side = v === 1 ? THREE.DoubleSide : THREE.FrontSide; break; - case 'bump': material.normalMap = getTexture( v.texture ); material.normalScale = new THREE.Vector2( 1, 1 ); @@ -1650,20 +1588,19 @@ return getBuild( library.materials[ id ], buildMaterial ); - } // camera + } + // camera function parseCamera( xml ) { const data = { name: xml.getAttribute( 'name' ) }; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'optics': @@ -1683,7 +1620,6 @@ for ( let i = 0; i < xml.childNodes.length; i ++ ) { const child = xml.childNodes[ i ]; - switch ( child.nodeName ) { case 'technique_common': @@ -1700,11 +1636,9 @@ function parseCameraTechnique( xml ) { const data = {}; - for ( let i = 0; i < xml.childNodes.length; i ++ ) { const child = xml.childNodes[ i ]; - switch ( child.nodeName ) { case 'perspective': @@ -1724,11 +1658,9 @@ function parseCameraParameters( xml ) { const data = {}; - for ( let i = 0; i < xml.childNodes.length; i ++ ) { const child = xml.childNodes[ i ]; - switch ( child.nodeName ) { case 'xfov': @@ -1752,13 +1684,11 @@ function buildCamera( data ) { let camera; - switch ( data.optics.technique ) { case 'perspective': camera = new THREE.PerspectiveCamera( data.optics.parameters.yfov, data.optics.parameters.aspect_ratio, data.optics.parameters.znear, data.optics.parameters.zfar ); break; - case 'orthographic': let ymag = data.optics.parameters.ymag; let xmag = data.optics.parameters.xmag; @@ -1767,10 +1697,10 @@ ymag = ymag === undefined ? xmag / aspectRatio : ymag; xmag *= 0.5; ymag *= 0.5; - camera = new THREE.OrthographicCamera( - xmag, xmag, ymag, - ymag, // left, right, top, bottom + camera = new THREE.OrthographicCamera( - xmag, xmag, ymag, - ymag, + // left, right, top, bottom data.optics.parameters.znear, data.optics.parameters.zfar ); break; - default: camera = new THREE.PerspectiveCamera(); break; @@ -1785,7 +1715,6 @@ function getCamera( id ) { const data = library.cameras[ id ]; - if ( data !== undefined ) { return getBuild( data, buildCamera ); @@ -1795,18 +1724,17 @@ console.warn( 'THREE.ColladaLoader: Couldn\'t find camera with ID:', id ); return null; - } // light + } + // light function parseLight( xml ) { let data = {}; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'technique_common': @@ -1824,12 +1752,10 @@ function parseLightTechnique( xml ) { const data = {}; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'directional': @@ -1850,23 +1776,19 @@ function parseLightParameters( xml ) { const data = {}; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'color': const array = parseFloats( child.textContent ); data.color = new THREE.Color().fromArray( array ).convertSRGBToLinear(); break; - case 'falloff_angle': data.falloffAngle = parseFloat( child.textContent ); break; - case 'quadratic_attenuation': const f = parseFloat( child.textContent ); data.distance = f ? Math.sqrt( 1 / f ) : 0; @@ -1883,21 +1805,17 @@ function buildLight( data ) { let light; - switch ( data.technique ) { case 'directional': light = new THREE.DirectionalLight(); break; - case 'point': light = new THREE.PointLight(); break; - case 'spot': light = new THREE.SpotLight(); break; - case 'ambient': light = new THREE.AmbientLight(); break; @@ -1913,7 +1831,6 @@ function getLight( id ) { const data = library.lights[ id ]; - if ( data !== undefined ) { return getBuild( data, buildLight ); @@ -1923,8 +1840,9 @@ console.warn( 'THREE.ColladaLoader: Couldn\'t find light with ID:', id ); return null; - } // geometry + } + // geometry function parseGeometry( xml ) { @@ -1934,38 +1852,33 @@ vertices: {}, primitives: [] }; - const mesh = getElementsByTagName( xml, 'mesh' )[ 0 ]; // the following tags inside geometry are not supported yet (see https://github.com/mrdoob/three.js/pull/12606): convex_mesh, spline, brep + const mesh = getElementsByTagName( xml, 'mesh' )[ 0 ]; + // the following tags inside geometry are not supported yet (see https://github.com/mrdoob/three.js/pull/12606): convex_mesh, spline, brep if ( mesh === undefined ) return; - for ( let i = 0; i < mesh.childNodes.length; i ++ ) { const child = mesh.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; const id = child.getAttribute( 'id' ); - switch ( child.nodeName ) { case 'source': data.sources[ id ] = parseSource( child ); break; - case 'vertices': // data.sources[ id ] = data.sources[ parseId( getElementsByTagName( child, 'input' )[ 0 ].getAttribute( 'source' ) ) ]; data.vertices = parseGeometryVertices( child ); break; - case 'polygons': console.warn( 'THREE.ColladaLoader: Unsupported primitive type: ', child.nodeName ); break; - case 'lines': case 'linestrips': case 'polylist': case 'triangles': data.primitives.push( parseGeometryPrimitive( child ) ); break; - default: console.log( child ); @@ -1983,25 +1896,20 @@ array: [], stride: 3 }; - for ( let i = 0; i < xml.childNodes.length; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'float_array': data.array = parseFloats( child.textContent ); break; - case 'Name_array': data.array = parseStrings( child.textContent ); break; - case 'technique_common': const accessor = getElementsByTagName( child, 'accessor' )[ 0 ]; - if ( accessor !== undefined ) { data.stride = parseInt( accessor.getAttribute( 'stride' ) ); @@ -2021,7 +1929,6 @@ function parseGeometryVertices( xml ) { const data = {}; - for ( let i = 0; i < xml.childNodes.length; i ++ ) { const child = xml.childNodes[ i ]; @@ -2044,12 +1951,10 @@ stride: 0, hasUV: false }; - for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'input': @@ -2065,11 +1970,9 @@ primitive.stride = Math.max( primitive.stride, offset + 1 ); if ( semantic === 'TEXCOORD' ) primitive.hasUV = true; break; - case 'vcount': primitive.vcount = parseInts( child.textContent ); break; - case 'p': primitive.p = parseInts( child.textContent ); break; @@ -2085,7 +1988,6 @@ function groupPrimitives( primitives ) { const build = {}; - for ( let i = 0; i < primitives.length; i ++ ) { const primitive = primitives[ i ]; @@ -2101,11 +2003,9 @@ function checkUVCoordinates( primitives ) { let count = 0; - for ( let i = 0, l = primitives.length; i < l; i ++ ) { const primitive = primitives[ i ]; - if ( primitive.hasUV === true ) { count ++; @@ -2128,16 +2028,21 @@ const sources = data.sources; const vertices = data.vertices; const primitives = data.primitives; - if ( primitives.length === 0 ) return {}; // our goal is to create one buffer geometry for a single type of primitives + if ( primitives.length === 0 ) return {}; + + // our goal is to create one buffer geometry for a single type of primitives // first, we group all primitives by their type const groupedPrimitives = groupPrimitives( primitives ); - for ( const type in groupedPrimitives ) { - const primitiveType = groupedPrimitives[ type ]; // second, ensure consistent uv coordinates for each type of primitives (polylist,triangles or lines) + const primitiveType = groupedPrimitives[ type ]; + + // second, ensure consistent uv coordinates for each type of primitives (polylist,triangles or lines) + + checkUVCoordinates( primitiveType ); - checkUVCoordinates( primitiveType ); // third, create a buffer geometry for each type of primitives + // third, create a buffer geometry for each type of primitives build[ type ] = buildGeometryType( primitiveType, sources, vertices ); @@ -2181,45 +2086,37 @@ const geometry = new THREE.BufferGeometry(); const materialKeys = []; let start = 0; - for ( let p = 0; p < primitives.length; p ++ ) { const primitive = primitives[ p ]; - const inputs = primitive.inputs; // groups + const inputs = primitive.inputs; - let count = 0; + // groups + let count = 0; switch ( primitive.type ) { case 'lines': case 'linestrips': count = primitive.count * 2; break; - case 'triangles': count = primitive.count * 3; break; - case 'polylist': for ( let g = 0; g < primitive.count; g ++ ) { const vc = primitive.vcount[ g ]; - switch ( vc ) { case 3: count += 3; // single triangle - break; - case 4: count += 6; // quad, subdivided into two triangles - break; - default: count += ( vc - 2 ) * 3; // polylist with more than four vertices - break; } @@ -2227,55 +2124,55 @@ } break; - default: console.warn( 'THREE.ColladaLoader: Unknow primitive type:', primitive.type ); } geometry.addGroup( start, count, p ); - start += count; // material + start += count; + + // material if ( primitive.material ) { materialKeys.push( primitive.material ); - } // geometry data + } + // geometry data for ( const name in inputs ) { const input = inputs[ name ]; - switch ( name ) { case 'VERTEX': for ( const key in vertices ) { const id = vertices[ key ]; - switch ( key ) { case 'POSITION': const prevLength = position.array.length; buildGeometryData( primitive, sources[ id ], input.offset, position.array ); position.stride = sources[ id ].stride; - if ( sources.skinWeights && sources.skinIndices ) { buildGeometryData( primitive, sources.skinIndices, input.offset, skinIndex.array ); buildGeometryData( primitive, sources.skinWeights, input.offset, skinWeight.array ); - } // see #3803 + } + // see #3803 if ( primitive.hasUV === false && primitives.uvsNeedsFix === true ) { const count = ( position.array.length - prevLength ) / position.stride; - for ( let i = 0; i < count; i ++ ) { // fill missing uv coordinates + uv.array.push( 0, 0 ); } @@ -2283,27 +2180,22 @@ } break; - case 'NORMAL': buildGeometryData( primitive, sources[ id ], input.offset, normal.array ); normal.stride = sources[ id ].stride; break; - case 'COLOR': buildGeometryData( primitive, sources[ id ], input.offset, color.array ); color.stride = sources[ id ].stride; break; - case 'TEXCOORD': buildGeometryData( primitive, sources[ id ], input.offset, uv.array ); uv.stride = sources[ id ].stride; break; - case 'TEXCOORD1': buildGeometryData( primitive, sources[ id ], input.offset, uv2.array ); uv.stride = sources[ id ].stride; break; - default: console.warn( 'THREE.ColladaLoader: Semantic "%s" not handled in geometry build process.', key ); @@ -2312,22 +2204,18 @@ } break; - case 'NORMAL': buildGeometryData( primitive, sources[ input.id ], input.offset, normal.array ); normal.stride = sources[ input.id ].stride; break; - case 'COLOR': buildGeometryData( primitive, sources[ input.id ], input.offset, color.array, true ); color.stride = sources[ input.id ].stride; break; - case 'TEXCOORD': buildGeometryData( primitive, sources[ input.id ], input.offset, uv.array ); uv.stride = sources[ input.id ].stride; break; - case 'TEXCOORD1': buildGeometryData( primitive, sources[ input.id ], input.offset, uv2.array ); uv2.stride = sources[ input.id ].stride; @@ -2337,8 +2225,9 @@ } - } // build geometry + } + // build geometry if ( position.array.length > 0 ) geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( position.array, position.stride ) ); if ( normal.array.length > 0 ) geometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( normal.array, normal.stride ) ); @@ -2359,12 +2248,10 @@ const indices = primitive.p; const stride = primitive.stride; const vcount = primitive.vcount; - function pushVector( i ) { let index = indices[ i + offset ] * sourceStride; const length = index + sourceStride; - for ( ; index < length; index ++ ) { array.push( sourceArray[ index ] ); @@ -2386,15 +2273,12 @@ const sourceArray = source.array; const sourceStride = source.stride; - if ( primitive.vcount !== undefined ) { let index = 0; - for ( let i = 0, l = vcount.length; i < l; i ++ ) { const count = vcount[ i ]; - if ( count === 4 ) { const a = index + stride * 0; @@ -2452,8 +2336,9 @@ return getBuild( library.geometries[ id ], buildGeometry ); - } // kinematics + } + // kinematics function parseKinematicsModel( xml ) { @@ -2462,12 +2347,10 @@ joints: {}, links: [] }; - for ( let i = 0; i < xml.childNodes.length; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'technique_common': @@ -2501,13 +2384,11 @@ const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'joint': data.joints[ child.getAttribute( 'sid' ) ] = parseKinematicsJoint( child ); break; - case 'link': data.links.push( parseKinematicsLink( child ) ); break; @@ -2521,12 +2402,10 @@ function parseKinematicsJoint( xml ) { let data; - for ( let i = 0; i < xml.childNodes.length; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'prismatic': @@ -2557,19 +2436,16 @@ zeroPosition: 0, middlePosition: 0 }; - for ( let i = 0; i < xml.childNodes.length; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'axis': const array = parseFloats( child.textContent ); data.axis.fromArray( array ); break; - case 'limits': const max = child.getElementsByTagName( 'max' )[ 0 ]; const min = child.getElementsByTagName( 'min' )[ 0 ]; @@ -2579,15 +2455,17 @@ } - } // if min is equal to or greater than max, consider the joint static + } + // if min is equal to or greater than max, consider the joint static if ( data.limits.min >= data.limits.max ) { data.static = true; - } // calculate middle position + } + // calculate middle position data.middlePosition = ( data.limits.min + data.limits.max ) / 2.0; return data; @@ -2602,18 +2480,15 @@ attachments: [], transforms: [] }; - for ( let i = 0; i < xml.childNodes.length; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'attachment_full': data.attachments.push( parseKinematicsAttachment( child ) ); break; - case 'matrix': case 'translate': case 'rotate': @@ -2635,18 +2510,15 @@ transforms: [], links: [] }; - for ( let i = 0; i < xml.childNodes.length; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'link': data.links.push( parseKinematicsLink( child ) ); break; - case 'matrix': case 'translate': case 'rotate': @@ -2667,19 +2539,16 @@ type: xml.nodeName }; const array = parseFloats( xml.textContent ); - switch ( data.type ) { case 'matrix': data.obj = new THREE.Matrix4(); data.obj.fromArray( array ).transpose(); break; - case 'translate': data.obj = new THREE.Vector3(); data.obj.fromArray( array ); break; - case 'rotate': data.obj = new THREE.Vector3(); data.obj.fromArray( array ); @@ -2690,8 +2559,9 @@ return data; - } // physics + } + // physics function parsePhysicsModel( xml ) { @@ -2699,12 +2569,10 @@ name: xml.getAttribute( 'name' ) || '', rigidBodies: {} }; - for ( let i = 0; i < xml.childNodes.length; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'rigid_body': @@ -2726,7 +2594,6 @@ const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'technique_common': @@ -2745,13 +2612,11 @@ const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'inertia': data.inertia = parseFloats( child.textContent ); break; - case 'mass': data.mass = parseFloats( child.textContent )[ 0 ]; break; @@ -2760,20 +2625,19 @@ } - } // scene + } + // scene function parseKinematicsScene( xml ) { const data = { bindJointAxis: [] }; - for ( let i = 0; i < xml.childNodes.length; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'bind_joint_axis': @@ -2793,12 +2657,10 @@ const data = { target: xml.getAttribute( 'target' ).split( '/' ).pop() }; - for ( let i = 0; i < xml.childNodes.length; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { case 'axis': @@ -2840,17 +2702,20 @@ const visualScene = getVisualScene( visualSceneId ); const bindJointAxis = kinematicsScene.bindJointAxis; const jointMap = {}; - for ( let i = 0, l = bindJointAxis.length; i < l; i ++ ) { - const axis = bindJointAxis[ i ]; // the result of the following query is an element of type 'translate', 'rotate','scale' or 'matrix' + const axis = bindJointAxis[ i ]; - const targetElement = collada.querySelector( '[sid="' + axis.target + '"]' ); + // the result of the following query is an element of type 'translate', 'rotate','scale' or 'matrix' + const targetElement = collada.querySelector( '[sid="' + axis.target + '"]' ); if ( targetElement ) { // get the parent of the transform element - const parentVisualElement = targetElement.parentElement; // connect the joint of the kinematics model with the element in the visual scene + + const parentVisualElement = targetElement.parentElement; + + // connect the joint of the kinematics model with the element in the visual scene connect( axis.jointIndex, parentVisualElement ); @@ -2885,7 +2750,6 @@ getJointValue: function ( jointIndex ) { const jointData = jointMap[ jointIndex ]; - if ( jointData ) { return jointData.position; @@ -2900,11 +2764,9 @@ setJointValue: function ( jointIndex, value ) { const jointData = jointMap[ jointIndex ]; - if ( jointData ) { const joint = jointData.joint; - if ( value > joint.limits.max || value < joint.limits.min ) { console.warn( 'THREE.ColladaLoader: Joint ' + jointIndex + ' value ' + value + ' outside of limits (min: ' + joint.limits.min + ', max: ' + joint.limits.max + ').' ); @@ -2918,11 +2780,15 @@ const object = jointData.object; const axis = joint.axis; const transforms = jointData.transforms; - matrix.identity(); // each update, we have to apply all transforms in the correct order + matrix.identity(); + + // each update, we have to apply all transforms in the correct order for ( let i = 0; i < transforms.length; i ++ ) { - const transform = transforms[ i ]; // if there is a connection of the transform node with a joint, apply the joint value + const transform = transforms[ i ]; + + // if there is a connection of the transform node with a joint, apply the joint value if ( transform.sid && transform.sid.indexOf( jointIndex ) !== - 1 ) { @@ -2931,11 +2797,9 @@ case 'revolute': matrix.multiply( m0.makeRotationAxis( axis, THREE.MathUtils.degToRad( value ) ) ); break; - case 'prismatic': matrix.multiply( m0.makeTranslation( axis.x * value, axis.y * value, axis.z * value ) ); break; - default: console.warn( 'THREE.ColladaLoader: Unknown joint type: ' + joint.type ); break; @@ -2949,15 +2813,12 @@ case 'matrix': matrix.multiply( transform.obj ); break; - case 'translate': matrix.multiply( m0.makeTranslation( transform.obj.x, transform.obj.y, transform.obj.z ) ); break; - case 'scale': matrix.scale( transform.obj ); break; - case 'rotate': matrix.multiply( m0.makeRotationAxis( transform.obj, transform.angle ) ); break; @@ -2989,13 +2850,11 @@ const transforms = []; const xml = collada.querySelector( '[id="' + node.id + '"]' ); - for ( let i = 0; i < xml.childNodes.length; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; let array, vector; - switch ( child.nodeName ) { case 'matrix': @@ -3007,7 +2866,6 @@ obj: matrix } ); break; - case 'translate': case 'scale': array = parseFloats( child.textContent ); @@ -3018,7 +2876,6 @@ obj: vector } ); break; - case 'rotate': array = parseFloats( child.textContent ); vector = new THREE.Vector3().fromArray( array ); @@ -3037,17 +2894,19 @@ return transforms; - } // nodes + } + // nodes function prepareNodes( xml ) { - const elements = xml.getElementsByTagName( 'node' ); // ensure all node elements have id attributes + const elements = xml.getElementsByTagName( 'node' ); + + // ensure all node elements have id attributes for ( let i = 0; i < elements.length; i ++ ) { const element = elements[ i ]; - if ( element.hasAttribute( 'id' ) === false ) { element.setAttribute( 'id', generateId() ); @@ -3060,7 +2919,6 @@ const matrix = new THREE.Matrix4(); const vector = new THREE.Vector3(); - function parseNode( xml ) { const data = { @@ -3077,69 +2935,56 @@ instanceNodes: [], transforms: {} }; - for ( let i = 0; i < xml.childNodes.length; i ++ ) { const child = xml.childNodes[ i ]; if ( child.nodeType !== 1 ) continue; let array; - switch ( child.nodeName ) { case 'node': data.nodes.push( child.getAttribute( 'id' ) ); parseNode( child ); break; - case 'instance_camera': data.instanceCameras.push( parseId( child.getAttribute( 'url' ) ) ); break; - case 'instance_controller': data.instanceControllers.push( parseNodeInstance( child ) ); break; - case 'instance_light': data.instanceLights.push( parseId( child.getAttribute( 'url' ) ) ); break; - case 'instance_geometry': data.instanceGeometries.push( parseNodeInstance( child ) ); break; - case 'instance_node': data.instanceNodes.push( parseId( child.getAttribute( 'url' ) ) ); break; - case 'matrix': array = parseFloats( child.textContent ); data.matrix.multiply( matrix.fromArray( array ).transpose() ); data.transforms[ child.getAttribute( 'sid' ) ] = child.nodeName; break; - case 'translate': array = parseFloats( child.textContent ); vector.fromArray( array ); data.matrix.multiply( matrix.makeTranslation( vector.x, vector.y, vector.z ) ); data.transforms[ child.getAttribute( 'sid' ) ] = child.nodeName; break; - case 'rotate': array = parseFloats( child.textContent ); const angle = THREE.MathUtils.degToRad( array[ 3 ] ); data.matrix.multiply( matrix.makeRotationAxis( vector.fromArray( array ), angle ) ); data.transforms[ child.getAttribute( 'sid' ) ] = child.nodeName; break; - case 'scale': array = parseFloats( child.textContent ); data.matrix.scale( vector.fromArray( array ) ); data.transforms[ child.getAttribute( 'sid' ) ] = child.nodeName; break; - case 'extra': break; - default: console.log( child ); @@ -3168,16 +3013,13 @@ materials: {}, skeletons: [] }; - for ( let i = 0; i < xml.childNodes.length; i ++ ) { const child = xml.childNodes[ i ]; - switch ( child.nodeName ) { case 'bind_material': const instances = child.getElementsByTagName( 'instance_material' ); - for ( let j = 0; j < instances.length; j ++ ) { const instance = instances[ j ]; @@ -3188,11 +3030,9 @@ } break; - case 'skeleton': data.skeletons.push( parseId( child.textContent ) ); break; - default: break; @@ -3208,14 +3048,15 @@ const boneData = []; const sortedBoneData = []; - let i, j, data; // a skeleton can have multiple root bones. collada expresses this + let i, j, data; + + // a skeleton can have multiple root bones. collada expresses this // situtation with multiple "skeleton" tags per controller instance for ( i = 0; i < skeletons.length; i ++ ) { const skeleton = skeletons[ i ]; let root; - if ( hasNode( skeleton ) ) { root = getNode( skeleton ); @@ -3224,13 +3065,12 @@ } else if ( hasVisualScene( skeleton ) ) { // handle case where the skeleton refers to the visual scene (#13335) + const visualScene = library.visualScenes[ skeleton ]; const children = visualScene.children; - for ( let j = 0; j < children.length; j ++ ) { const child = children[ j ]; - if ( child.type === 'JOINT' ) { const root = getNode( child.id ); @@ -3246,15 +3086,15 @@ } - } // sort bone data (the order is defined in the corresponding controller) + } + // sort bone data (the order is defined in the corresponding controller) for ( i = 0; i < joints.length; i ++ ) { for ( j = 0; j < boneData.length; j ++ ) { data = boneData[ j ]; - if ( data.bone.name === joints[ i ].name ) { sortedBoneData[ i ] = data; @@ -3265,13 +3105,13 @@ } - } // add unprocessed bone data at the end of the list + } + // add unprocessed bone data at the end of the list for ( i = 0; i < boneData.length; i ++ ) { data = boneData[ i ]; - if ( data.processed === false ) { sortedBoneData.push( data ); @@ -3279,12 +3119,12 @@ } - } // setup arrays for skeleton creation + } + // setup arrays for skeleton creation const bones = []; const boneInverses = []; - for ( i = 0; i < sortedBoneData.length; i ++ ) { data = sortedBoneData[ i ]; @@ -3300,16 +3140,18 @@ function buildBoneHierarchy( root, joints, boneData ) { // setup bone data from visual scene + root.traverse( function ( object ) { if ( object.isBone === true ) { - let boneInverse; // retrieve the boneInverse from the controller data + let boneInverse; + + // retrieve the boneInverse from the controller data for ( let i = 0; i < joints.length; i ++ ) { const joint = joints[ i ]; - if ( joint.name === object.name ) { boneInverse = joint.boneInverse; @@ -3326,6 +3168,7 @@ // for the respective bone. This bone won't affect any vertices, because there are no skin indices // and weights defined for it. But we still have to add the bone to the sorted bone list in order to // ensure a correct animation of the model. + boneInverse = new THREE.Matrix4(); } @@ -3352,27 +3195,30 @@ const instanceControllers = data.instanceControllers; const instanceLights = data.instanceLights; const instanceGeometries = data.instanceGeometries; - const instanceNodes = data.instanceNodes; // nodes + const instanceNodes = data.instanceNodes; + + // nodes for ( let i = 0, l = nodes.length; i < l; i ++ ) { objects.push( getNode( nodes[ i ] ) ); - } // instance cameras + } + // instance cameras for ( let i = 0, l = instanceCameras.length; i < l; i ++ ) { const instanceCamera = getCamera( instanceCameras[ i ] ); - if ( instanceCamera !== null ) { objects.push( instanceCamera.clone() ); } - } // instance controllers + } + // instance controllers for ( let i = 0, l = instanceControllers.length; i < l; i ++ ) { @@ -3383,11 +3229,9 @@ const skeletons = instance.skeletons; const joints = controller.skin.joints; const skeleton = buildSkeleton( skeletons, joints ); - for ( let j = 0, jl = newObjects.length; j < jl; j ++ ) { const object = newObjects[ j ]; - if ( object.isSkinnedMesh ) { object.bind( skeleton, controller.skin.bindMatrix ); @@ -3399,38 +3243,41 @@ } - } // instance lights + } + // instance lights for ( let i = 0, l = instanceLights.length; i < l; i ++ ) { const instanceLight = getLight( instanceLights[ i ] ); - if ( instanceLight !== null ) { objects.push( instanceLight.clone() ); } - } // instance geometries + } + // instance geometries for ( let i = 0, l = instanceGeometries.length; i < l; i ++ ) { - const instance = instanceGeometries[ i ]; // a single geometry instance in collada can lead to multiple object3Ds. + const instance = instanceGeometries[ i ]; + + // a single geometry instance in collada can lead to multiple object3Ds. // this is the case when primitives are combined like triangles and lines const geometries = getGeometry( instance.id ); const newObjects = buildObjects( geometries, instance.materials ); - for ( let j = 0, jl = newObjects.length; j < jl; j ++ ) { objects.push( newObjects[ j ] ); } - } // instance nodes + } + // instance nodes for ( let i = 0, l = instanceNodes.length; i < l; i ++ ) { @@ -3439,7 +3286,6 @@ } let object; - if ( nodes.length === 0 && objects.length === 1 ) { object = objects[ 0 ]; @@ -3447,7 +3293,6 @@ } else { object = type === 'JOINT' ? new THREE.Bone() : new THREE.Group(); - for ( let i = 0; i < objects.length; i ++ ) { object.add( objects[ i ] ); @@ -3466,15 +3311,12 @@ const fallbackMaterial = new THREE.MeshBasicMaterial( { color: 0xff00ff } ); - function resolveMaterialBinding( keys, instanceMaterials ) { const materials = []; - for ( let i = 0, l = keys.length; i < l; i ++ ) { const id = instanceMaterials[ keys[ i ] ]; - if ( id === undefined ) { console.warn( 'THREE.ColladaLoader: Material with key %s not found. Apply fallback material.', keys[ i ] ); @@ -3495,11 +3337,12 @@ function buildObjects( geometries, instanceMaterials ) { const objects = []; - for ( const type in geometries ) { const geometry = geometries[ type ]; - const materials = resolveMaterialBinding( geometry.materialKeys, instanceMaterials ); // handle case if no materials are defined + const materials = resolveMaterialBinding( geometry.materialKeys, instanceMaterials ); + + // handle case if no materials are defined if ( materials.length === 0 ) { @@ -3513,25 +3356,54 @@ } - } // regard skinning + } + + // Collada allows to use phong and lambert materials with lines. Replacing these cases with THREE.LineBasicMaterial. + if ( type === 'lines' || type === 'linestrips' ) { - const skinning = geometry.data.attributes.skinIndex !== undefined; // choose between a single or multi materials (material array) + for ( let i = 0, l = materials.length; i < l; i ++ ) { - const material = materials.length === 1 ? materials[ 0 ] : materials; // now create a specific 3D object + const material = materials[ i ]; + if ( material.isMeshPhongMaterial === true || material.isMeshLambertMaterial === true ) { - let object; + const lineMaterial = new THREE.LineBasicMaterial(); + + // copy compatible properties + + lineMaterial.color.copy( material.color ); + lineMaterial.opacity = material.opacity; + lineMaterial.transparent = material.transparent; + + // replace material + + materials[ i ] = lineMaterial; + } + + } + + } + + // regard skinning + + const skinning = geometry.data.attributes.skinIndex !== undefined; + + // choose between a single or multi materials (material array) + + const material = materials.length === 1 ? materials[ 0 ] : materials; + + // now create a specific 3D object + + let object; switch ( type ) { case 'lines': object = new THREE.LineSegments( geometry.data, material ); break; - case 'linestrips': object = new THREE.Line( geometry.data, material ); break; - case 'triangles': case 'polylist': if ( skinning ) { @@ -3566,8 +3438,9 @@ return getBuild( library.nodes[ id ], buildNode ); - } // visual scenes + } + // visual scenes function parseVisualScene( xml ) { @@ -3577,7 +3450,6 @@ }; prepareNodes( xml ); const elements = getElementsByTagName( xml, 'node' ); - for ( let i = 0; i < elements.length; i ++ ) { data.children.push( parseNode( elements[ i ] ) ); @@ -3593,7 +3465,6 @@ const group = new THREE.Group(); group.name = data.name; const children = data.children; - for ( let i = 0; i < children.length; i ++ ) { const child = children[ i ]; @@ -3615,8 +3486,9 @@ return getBuild( library.visualScenes[ id ], buildVisualScene ); - } // scenes + } + // scenes function parseScene( xml ) { @@ -3628,18 +3500,16 @@ function setupAnimations() { const clips = library.clips; - if ( isEmpty( clips ) === true ) { if ( isEmpty( library.animations ) === false ) { // if there are animations but no clips, we create a default clip for playback - const tracks = []; + const tracks = []; for ( const id in library.animations ) { const animationTracks = getAnimation( id ); - for ( let i = 0, l = animationTracks.length; i < l; i ++ ) { tracks.push( animationTracks[ i ] ); @@ -3662,19 +3532,18 @@ } - } // convert the parser error element into text with each child elements text - // separated by new lines. + } + // convert the parser error element into text with each child elements text + // separated by new lines. function parserErrorToText( parserError ) { let result = ''; const stack = [ parserError ]; - while ( stack.length ) { const node = stack.shift(); - if ( node.nodeType === Node.TEXT_NODE ) { result += node.textContent; @@ -3703,13 +3572,12 @@ const xml = new DOMParser().parseFromString( text, 'application/xml' ); const collada = getElementsByTagName( xml, 'COLLADA' )[ 0 ]; const parserError = xml.getElementsByTagName( 'parsererror' )[ 0 ]; - if ( parserError !== undefined ) { // Chrome will return parser error with a div in it + const errorElement = getElementsByTagName( parserError, 'div' )[ 0 ]; let errorText; - if ( errorElement ) { errorText = errorElement.textContent; @@ -3723,8 +3591,9 @@ console.error( 'THREE.ColladaLoader: Failed to parse collada file.\n', errorText ); return null; - } // metadata + } + // metadata const version = collada.getAttribute( 'version' ); console.log( 'THREE.ColladaLoader: File version', version ); @@ -3732,19 +3601,21 @@ const textureLoader = new THREE.TextureLoader( this.manager ); textureLoader.setPath( this.resourcePath || path ).setCrossOrigin( this.crossOrigin ); let tgaLoader; - if ( THREE.TGALoader ) { tgaLoader = new THREE.TGALoader( this.manager ); tgaLoader.setPath( this.resourcePath || path ); - } // + } + // const tempColor = new THREE.Color(); const animations = []; let kinematics = {}; - let count = 0; // + let count = 0; + + // const library = { animations: {}, @@ -3790,9 +3661,9 @@ setupKinematics(); const scene = parseScene( getElementsByTagName( collada, 'scene' )[ 0 ] ); scene.animations = animations; - if ( asset.upAxis === 'Z_UP' ) { + console.warn( 'THREE.ColladaLoader: You are loading an asset with a Z-UP coordinate system. The loader just rotates the asset to transform it into Y-UP. The vertex data are not converted, see #24289.' ); scene.quaternion.setFromEuler( new THREE.Euler( - Math.PI / 2, 0, 0 ) ); } @@ -3805,7 +3676,6 @@ return animations; }, - kinematics: kinematics, library: library, scene: scene diff --git a/examples/js/loaders/DDSLoader.js b/examples/js/loaders/DDSLoader.js index acc5804f1bbd85..0a1477f1709391 100644 --- a/examples/js/loaders/DDSLoader.js +++ b/examples/js/loaders/DDSLoader.js @@ -7,7 +7,6 @@ super( manager ); } - parse( buffer, loadMipmaps ) { const dds = { @@ -16,19 +15,25 @@ height: 0, format: null, mipmapCount: 1 - }; // Adapted from @toji's DDS utils + }; + + // 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/ - const DDS_MAGIC = 0x20534444; // const DDSD_CAPS = 0x1; + const DDS_MAGIC = 0x20534444; + + // const DDSD_CAPS = 0x1; // const DDSD_HEIGHT = 0x2; // const DDSD_WIDTH = 0x4; // const DDSD_PITCH = 0x8; // const DDSD_PIXELFORMAT = 0x1000; - - const DDSD_MIPMAPCOUNT = 0x20000; // const DDSD_LINEARSIZE = 0x80000; + const DDSD_MIPMAPCOUNT = 0x20000; + // const DDSD_LINEARSIZE = 0x80000; // const DDSD_DEPTH = 0x800000; + // const DDSCAPS_COMPLEX = 0x8; // const DDSCAPS_MIPMAP = 0x400000; // const DDSCAPS_TEXTURE = 0x1000; @@ -39,7 +44,9 @@ const DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000; const DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000; const DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000; - const DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000; // const DDSCAPS2_VOLUME = 0x200000; + const DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000; + // const DDSCAPS2_VOLUME = 0x200000; + // const DDPF_ALPHAPIXELS = 0x1; // const DDPF_ALPHA = 0x2; // const DDPF_FOURCC = 0x4; @@ -66,7 +73,6 @@ const byteArray = new Uint8Array( dataLength ); let dst = 0; let src = 0; - for ( let y = 0; y < height; y ++ ) { for ( let x = 0; x < width; x ++ ) { @@ -81,13 +87,10 @@ src ++; byteArray[ dst ] = r; dst ++; //r - byteArray[ dst ] = g; dst ++; //g - byteArray[ dst ] = b; dst ++; //b - byteArray[ dst ] = a; dst ++; //a @@ -104,6 +107,7 @@ const FOURCC_DXT5 = fourCCToInt32( 'DXT5' ); const FOURCC_ETC1 = fourCCToInt32( 'ETC1' ); const headerLengthInt = 31; // The header length in 32 bit ints + // Offsets into the header array const off_magic = 0; @@ -111,21 +115,24 @@ const off_flags = 2; const off_height = 3; const off_width = 4; - const off_mipmapCount = 7; // const off_pfFlags = 20; + const off_mipmapCount = 7; + // const off_pfFlags = 20; const off_pfFourCC = 21; const off_RGBBitCount = 22; const off_RBitMask = 23; const off_GBitMask = 24; const off_BBitMask = 25; - const off_ABitMask = 26; // const off_caps = 27; + const off_ABitMask = 26; - const off_caps2 = 28; // const off_caps3 = 29; + // const off_caps = 27; + const off_caps2 = 28; + // const off_caps3 = 29; // const off_caps4 = 30; + // Parse header const header = new Int32Array( buffer, 0, headerLengthInt ); - if ( header[ off_magic ] !== DDS_MAGIC ) { console.error( 'THREE.DDSLoader.parse: Invalid magic number in DDS header.' ); @@ -136,29 +143,24 @@ let blockBytes; const fourCC = header[ off_pfFourCC ]; let 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; - case FOURCC_ETC1: blockBytes = 8; dds.format = THREE.RGB_ETC1_Format; break; - default: if ( header[ off_RGBBitCount ] === 32 && header[ off_RBitMask ] & 0xff0000 && header[ off_GBitMask ] & 0xff00 && header[ off_BBitMask ] & 0xff && header[ off_ABitMask ] & 0xff000000 ) { @@ -176,7 +178,6 @@ } dds.mipmapCount = 1; - if ( header[ off_flags ] & DDSD_MIPMAPCOUNT && loadMipmaps !== false ) { dds.mipmapCount = Math.max( 1, header[ off_mipmapCount ] ); @@ -185,7 +186,6 @@ const caps2 = header[ off_caps2 ]; dds.isCubemap = caps2 & DDSCAPS2_CUBEMAP ? true : false; - if ( dds.isCubemap && ( ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEX ) || ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX ) || ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEY ) || ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY ) || ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ ) || ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ ) ) ) { console.error( 'THREE.DDSLoader.parse: Incomplete cubemap faces' ); @@ -195,19 +195,18 @@ dds.width = header[ off_width ]; dds.height = header[ off_height ]; - let dataOffset = header[ off_size ] + 4; // Extract mipmaps buffers + let dataOffset = header[ off_size ] + 4; - const faces = dds.isCubemap ? 6 : 1; + // Extract mipmaps buffers + const faces = dds.isCubemap ? 6 : 1; for ( let face = 0; face < faces; face ++ ) { let width = dds.width; let height = dds.height; - for ( let i = 0; i < dds.mipmapCount; i ++ ) { let byteArray, dataLength; - if ( isRGBAUncompressed ) { byteArray = loadARGBMip( buffer, dataOffset, width, height ); diff --git a/examples/js/loaders/DRACOLoader.js b/examples/js/loaders/DRACOLoader.js index 5ca41b903b4726..e09407199f8ddf 100644 --- a/examples/js/loaders/DRACOLoader.js +++ b/examples/js/loaders/DRACOLoader.js @@ -1,7 +1,6 @@ ( function () { const _taskCache = new WeakMap(); - class DRACOLoader extends THREE.Loader { constructor( manager ) { @@ -29,28 +28,24 @@ }; } - setDecoderPath( path ) { this.decoderPath = path; return this; } - setDecoderConfig( config ) { this.decoderConfig = config; return this; } - setWorkerLimit( workerLimit ) { this.workerLimit = workerLimit; return this; } - load( url, onLoad, onProgress, onError ) { const loader = new THREE.FileLoader( this.manager ); @@ -60,19 +55,11 @@ loader.setWithCredentials( this.withCredentials ); loader.load( url, buffer => { - const taskConfig = { - attributeIDs: this.defaultAttributeIDs, - attributeTypes: this.defaultAttributeTypes, - useUniqueIDs: false - }; - this.decodeGeometry( buffer, taskConfig ).then( onLoad ).catch( onError ); + this.decodeDracoFile( buffer, onLoad ).catch( onError ); }, onProgress, onError ); } - /** @deprecated Kept for backward-compatibility with previous DRACOLoader versions. */ - - decodeDracoFile( buffer, callback, attributeIDs, attributeTypes ) { const taskConfig = { @@ -80,35 +67,18 @@ attributeTypes: attributeTypes || this.defaultAttributeTypes, useUniqueIDs: !! attributeIDs }; - this.decodeGeometry( buffer, taskConfig ).then( callback ); + return this.decodeGeometry( buffer, taskConfig ).then( callback ); } - decodeGeometry( buffer, taskConfig ) { - // TODO: For backward-compatibility, support 'attributeTypes' objects containing - // references (rather than names) to typed array constructors. These must be - // serialized before sending them to the worker. - for ( const attribute in taskConfig.attributeTypes ) { - - const type = taskConfig.attributeTypes[ attribute ]; + const taskKey = JSON.stringify( taskConfig ); - if ( type.BYTES_PER_ELEMENT !== undefined ) { - - taskConfig.attributeTypes[ attribute ] = type.name; - - } - - } // - - - const taskKey = JSON.stringify( taskConfig ); // Check for an existing task using this buffer. A transferred buffer cannot be transferred + // Check for an existing task using this buffer. A transferred buffer cannot be transferred // again from this thread. - if ( _taskCache.has( buffer ) ) { const cachedTask = _taskCache.get( buffer ); - if ( cachedTask.key === taskKey ) { return cachedTask.promise; @@ -123,14 +93,16 @@ } - } // + } + // let worker; const taskID = this.workerNextTaskID ++; - const taskCost = buffer.byteLength; // Obtain a worker and assign a task, and construct a geometry instance - // when the task completes. + const taskCost = buffer.byteLength; + // Obtain a worker and assign a task, and construct a geometry instance + // when the task completes. const geometryPending = this._getWorker( taskID, taskCost ).then( _worker => { worker = _worker; @@ -145,37 +117,39 @@ id: taskID, taskConfig, buffer - }, [ buffer ] ); // this.debug(); + }, [ buffer ] ); - } ); + // this.debug(); - } ).then( message => this._createGeometry( message.geometry ) ); // Remove task from the task list. - // Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416) + } ); + } ).then( message => this._createGeometry( message.geometry ) ); + // Remove task from the task list. + // Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416) geometryPending.catch( () => true ).then( () => { if ( worker && taskID ) { - this._releaseTask( worker, taskID ); // this.debug(); + this._releaseTask( worker, taskID ); + + // this.debug(); } - } ); // Cache the task result. + } ); + // Cache the task result. _taskCache.set( buffer, { key: taskKey, promise: geometryPending } ); - return geometryPending; } - _createGeometry( geometryData ) { const geometry = new THREE.BufferGeometry(); - if ( geometryData.index ) { geometry.setIndex( new THREE.BufferAttribute( geometryData.index.array, 1 ) ); @@ -195,7 +169,6 @@ return geometry; } - _loadLibrary( url, responseType ) { const loader = new THREE.FileLoader( this.manager ); @@ -209,21 +182,17 @@ } ); } - preload() { this._initDecoder(); - return this; } - _initDecoder() { if ( this.decoderPending ) return this.decoderPending; const useJS = typeof WebAssembly !== 'object' || this.decoderConfig.type === 'js'; const librariesPending = []; - if ( useJS ) { librariesPending.push( this._loadLibrary( 'draco_decoder.js', 'text' ) ); @@ -238,7 +207,6 @@ this.decoderPending = Promise.all( librariesPending ).then( libraries => { const jsContent = libraries[ 0 ]; - if ( ! useJS ) { this.decoderConfig.wasmBinary = libraries[ 1 ]; @@ -253,7 +221,6 @@ return this.decoderPending; } - _getWorker( taskID, taskCost ) { return this._initDecoder().then( () => { @@ -268,23 +235,17 @@ type: 'init', decoderConfig: this.decoderConfig } ); - worker.onmessage = function ( e ) { const message = e.data; - switch ( message.type ) { case 'decode': worker._callbacks[ message.id ].resolve( message ); - break; - case 'error': worker._callbacks[ message.id ].reject( message ); - break; - default: console.error( 'THREE.DRACOLoader: Unexpected message, "' + message.type + '"' ); @@ -312,7 +273,6 @@ } ); } - _releaseTask( worker, taskID ) { worker._taskLoad -= worker._taskCosts[ taskID ]; @@ -320,13 +280,11 @@ delete worker._taskCosts[ taskID ]; } - debug() { console.log( 'Task load: ', this.workerPool.map( worker => worker._taskLoad ) ); } - dispose() { for ( let i = 0; i < this.workerPool.length; ++ i ) { @@ -341,25 +299,21 @@ } } - /* WEB WORKER */ + /* WEB WORKER */ function DRACOWorker() { let decoderConfig; let decoderPending; - onmessage = function ( e ) { const message = e.data; - switch ( message.type ) { case 'init': decoderConfig = message.decoderConfig; - decoderPending = new Promise( function ( resolve - /*, reject*/ - ) { + decoderPending = new Promise( function ( resolve /*, reject*/ ) { decoderConfig.onModuleLoaded = function ( draco ) { @@ -373,8 +327,8 @@ DracoDecoderModule( decoderConfig ); // eslint-disable-line no-undef } ); - break; + break; case 'decode': const buffer = message.buffer; const taskConfig = message.taskConfig; @@ -384,7 +338,6 @@ const decoder = new draco.Decoder(); const decoderBuffer = new draco.DecoderBuffer(); decoderBuffer.Init( new Int8Array( buffer ), buffer.byteLength ); - try { const geometry = decodeGeometry( draco, decoder, decoderBuffer, taskConfig ); @@ -426,7 +379,6 @@ let dracoGeometry; let decodingStatus; const geometryType = decoder.GetEncodedGeometryType( decoderBuffer ); - if ( geometryType === draco.TRIANGULAR_MESH ) { dracoGeometry = new draco.Mesh(); @@ -452,17 +404,19 @@ const geometry = { index: null, attributes: [] - }; // Gather all vertex attributes. + }; + // Gather all vertex attributes. for ( const attributeName in attributeIDs ) { const attributeType = self[ attributeTypes[ attributeName ] ]; let attribute; - let attributeID; // A Draco file may be created with default vertex attributes, whose attribute IDs + let attributeID; + + // A Draco file may be created with default vertex attributes, whose attribute IDs // are mapped 1:1 from their semantic name (POSITION, NORMAL, ...). Alternatively, // a Draco file may contain a custom set of attributes, identified by known unique // IDs. glTF files always do the latter, and `.drc` files typically do the former. - if ( taskConfig.useUniqueIDs ) { attributeID = attributeIDs[ attributeName ]; @@ -478,9 +432,9 @@ geometry.attributes.push( decodeAttribute( draco, decoder, dracoGeometry, attributeName, attributeType, attribute ) ); - } // Add index. - + } + // Add index. if ( geometryType === draco.TRIANGULAR_MESH ) { geometry.index = decodeIndex( draco, decoder, dracoGeometry ); @@ -497,14 +451,10 @@ const numFaces = dracoGeometry.num_faces(); const numIndices = numFaces * 3; const byteLength = numIndices * 4; - const ptr = draco._malloc( byteLength ); - decoder.GetTrianglesUInt32Array( dracoGeometry, byteLength, ptr ); const index = new Uint32Array( draco.HEAPF32.buffer, ptr, numIndices ).slice(); - draco._free( ptr ); - return { array: index, itemSize: 1 @@ -519,14 +469,10 @@ const numValues = numPoints * numComponents; const byteLength = numValues * attributeType.BYTES_PER_ELEMENT; const dataType = getDracoDataType( draco, attributeType ); - const ptr = draco._malloc( byteLength ); - decoder.GetAttributeDataArrayForAllPoints( dracoGeometry, attribute, dataType, byteLength, ptr ); const array = new attributeType( draco.HEAPF32.buffer, ptr, numValues ).slice(); - draco._free( ptr ); - return { name: attributeName, array: array, @@ -541,22 +487,16 @@ case Float32Array: return draco.DT_FLOAT32; - case Int8Array: return draco.DT_INT8; - case Int16Array: return draco.DT_INT16; - case Int32Array: return draco.DT_INT32; - case Uint8Array: return draco.DT_UINT8; - case Uint16Array: return draco.DT_UINT16; - case Uint32Array: return draco.DT_UINT32; diff --git a/examples/js/loaders/EXRLoader.js b/examples/js/loaders/EXRLoader.js index 1d78348a971332..2865afebce790a 100644 --- a/examples/js/loaders/EXRLoader.js +++ b/examples/js/loaders/EXRLoader.js @@ -7,9 +7,11 @@ * Referred to the original Industrial Light & Magic OpenEXR implementation and the TinyEXR / Syoyo Fujita * implementation, so I have preserved their copyright notices. */ + // /* // Copyright (c) 2014 - 2017, Syoyo Fujita // All rights reserved. + // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // * Redistributions of source code must retain the above copyright @@ -20,6 +22,7 @@ // * Neither the name of the Syoyo Fujita nor the // names of its contributors may be used to endorse or promote products // derived from this software without specific prior written permission. + // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -31,7 +34,9 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // */ + // // TinyEXR contains some OpenEXR code, which is licensed under ------------ + // /////////////////////////////////////////////////////////////////////////// // // // // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas @@ -65,6 +70,7 @@ // // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // // /////////////////////////////////////////////////////////////////////////// + // // End of OpenEXR license ------------------------------------------------- class EXRLoader extends THREE.DataTextureLoader { @@ -75,19 +81,15 @@ this.type = THREE.HalfFloatType; } - parse( buffer ) { const USHORT_RANGE = 1 << 16; const BITMAP_SIZE = USHORT_RANGE >> 3; const HUF_ENCBITS = 16; // literal (value) bit length - const HUF_DECBITS = 14; // decoding bit size (>= 8) const HUF_ENCSIZE = ( 1 << HUF_ENCBITS ) + 1; // encoding table size - const HUF_DECSIZE = 1 << HUF_DECBITS; // decoding table size - const HUF_DECMASK = HUF_DECSIZE - 1; const NBITS = 16; const A_OFFSET = 1 << NBITS - 1; @@ -106,11 +108,9 @@ const LOSSY_DCT = 1; const RLE = 2; const logBase = Math.pow( 2.7182818, 2.2 ); - function reverseLutFromBitmap( bitmap, lut ) { let k = 0; - for ( let i = 0; i < USHORT_RANGE; ++ i ) { if ( i == 0 || bitmap[ i >> 3 ] & 1 << ( i & 7 ) ) { @@ -122,9 +122,7 @@ } const n = k - 1; - while ( k < USHORT_RANGE ) lut[ k ++ ] = 0; - return n; } @@ -147,7 +145,6 @@ c: 0, lc: 0 }; - function getBits( nBits, c, lc, uInt8Array, inOffset ) { while ( lc < nBits ) { @@ -165,15 +162,11 @@ } const hufTableBuffer = new Array( 59 ); - function hufCanonicalCodeTable( hcode ) { for ( let i = 0; i <= 58; ++ i ) hufTableBuffer[ i ] = 0; - for ( let i = 0; i < HUF_ENCSIZE; ++ i ) hufTableBuffer[ hcode[ i ] ] += 1; - let c = 0; - for ( let i = 58; i > 0; -- i ) { const nc = c + hufTableBuffer[ i ] >> 1; @@ -196,7 +189,6 @@ const p = inOffset; let c = 0; let lc = 0; - for ( ; im <= iM; im ++ ) { if ( p.value - inOffset.value > ni ) return false; @@ -205,7 +197,6 @@ c = getBitsReturn.c; lc = getBitsReturn.lc; hcode[ im ] = l; - if ( l == LONG_ZEROCODE_RUN ) { if ( p.value - inOffset.value > ni ) { @@ -218,7 +209,6 @@ let zerun = getBitsReturn.l + SHORTEST_LONG_RUN; c = getBitsReturn.c; lc = getBitsReturn.lc; - if ( im + zerun > iM + 1 ) { throw new Error( 'Something wrong with hufUnpackEncTable' ); @@ -226,13 +216,11 @@ } while ( zerun -- ) hcode[ im ++ ] = 0; - im --; } else if ( l >= SHORT_ZEROCODE_RUN ) { let zerun = l - SHORT_ZEROCODE_RUN + 2; - if ( im + zerun > iM + 1 ) { throw new Error( 'Something wrong with hufUnpackEncTable' ); @@ -240,7 +228,6 @@ } while ( zerun -- ) hcode[ im ++ ] = 0; - im --; } @@ -269,7 +256,6 @@ const c = hufCode( hcode[ im ] ); const l = hufLength( hcode[ im ] ); - if ( c >> l ) { throw new Error( 'Invalid table entry' ); @@ -279,7 +265,6 @@ if ( l > HUF_DECBITS ) { const pl = hdecod[ c >> l - HUF_DECBITS ]; - if ( pl.len ) { throw new Error( 'Invalid table entry' ); @@ -287,12 +272,10 @@ } pl.lit ++; - if ( pl.p ) { const p = pl.p; pl.p = new Array( pl.lit ); - for ( let i = 0; i < pl.lit - 1; ++ i ) { pl.p[ i ] = p[ i ]; @@ -310,11 +293,9 @@ } else if ( l ) { let plOffset = 0; - for ( let i = 1 << HUF_DECBITS - l; i > 0; i -- ) { const pl = hdecod[ ( c << HUF_DECBITS - l ) + plOffset ]; - if ( pl.len || pl.p ) { throw new Error( 'Invalid table entry' ); @@ -339,7 +320,6 @@ c: 0, lc: 0 }; - function getChar( c, lc, uInt8Array, inOffset ) { c = c << 8 | parseUint8Array( uInt8Array, inOffset ); @@ -353,7 +333,6 @@ c: 0, lc: 0 }; - function getCode( po, rlc, c, lc, uInt8Array, inOffset, outBuffer, outBufferOffset, outBufferEndOffset ) { if ( po == rlc ) { @@ -369,7 +348,6 @@ lc -= 8; let cs = c >> lc; cs = new Uint8Array( [ cs ] )[ 0 ]; - if ( outBufferOffset.value + cs > outBufferEndOffset ) { return false; @@ -377,7 +355,6 @@ } const s = outBuffer[ outBufferOffset.value - 1 ]; - while ( cs -- > 0 ) { outBuffer[ outBufferOffset.value ++ ] = s; @@ -416,7 +393,6 @@ a: 0, b: 0 }; - function wdec14( l, h ) { const ls = Int16( l ); @@ -448,13 +424,10 @@ let p = 1; let p2; let py; - while ( p <= n ) p <<= 1; - p >>= 1; p2 = p; p >>= 1; - while ( p >= 1 ) { py = 0; @@ -464,18 +437,15 @@ const ox1 = ox * p; const ox2 = ox * p2; let i00, i01, i10, i11; - for ( ; py <= ey; py += oy2 ) { let px = py; const ex = py + ox * ( nx - p2 ); - for ( ; px <= ex; px += ox2 ) { const p01 = px + ox1; const p10 = px + oy1; const p11 = p10 + ox1; - if ( w14 ) { wdec14( buffer[ px + j ], buffer[ p10 + j ] ); @@ -526,7 +496,6 @@ let px = py; const ex = py + ox * ( nx - p2 ); - for ( ; px <= ex; px += ox2 ) { const p01 = px + ox1; @@ -554,18 +523,15 @@ let lc = 0; const outBufferEndOffset = no; const inOffsetEnd = Math.trunc( inOffset.value + ( ni + 7 ) / 8 ); - while ( inOffset.value < inOffsetEnd ) { getChar( c, lc, uInt8Array, inOffset ); c = getCharReturn.c; lc = getCharReturn.lc; - while ( lc >= HUF_DECBITS ) { const index = c >> lc - HUF_DECBITS & HUF_DECMASK; const pl = decodingTable[ index ]; - if ( pl.len ) { lc -= pl.len; @@ -582,11 +548,9 @@ } let j; - for ( j = 0; j < pl.lit; j ++ ) { const l = hufLength( encodingTable[ pl.p[ j ] ] ); - while ( lc < l && inOffset.value < inOffsetEnd ) { getChar( c, lc, uInt8Array, inOffset ); @@ -626,11 +590,9 @@ const i = 8 - ni & 7; c >>= i; lc -= i; - while ( lc > 0 ) { const pl = decodingTable[ c << HUF_DECBITS - lc & HUF_DECMASK ]; - if ( pl.len ) { lc -= pl.len; @@ -661,7 +623,6 @@ inOffset.value += 4; const nBits = parseUint32( inDataView, inOffset ); inOffset.value += 4; - if ( im < 0 || im >= HUF_ENCSIZE || iM < 0 || iM >= HUF_ENCSIZE ) { throw new Error( 'Something wrong with HUF_ENCSIZE' ); @@ -673,7 +634,6 @@ hufClearDecTable( hdec ); const ni = nCompressed - ( inOffset.value - initialInOffset ); hufUnpackEncTable( uInt8Array, inOffset, ni, im, iM, freq ); - if ( nBits > 8 * ( nCompressed - ( inOffset.value - initialInOffset ) ) ) { throw new Error( 'Something wrong with hufUncompress' ); @@ -712,7 +672,6 @@ let t2 = Math.floor( ( source.length + 1 ) / 2 ); let s = 0; const stop = source.length - 1; - while ( true ) { if ( s > stop ) break; @@ -730,16 +689,13 @@ const out = new Array(); let p = 0; const reader = new DataView( source ); - while ( size > 0 ) { const l = reader.getInt8( p ++ ); - if ( l < 0 ) { const count = - l; size -= count + 1; - for ( let i = 0; i < count; i ++ ) { out.push( reader.getUint8( p ++ ) ); @@ -751,7 +707,6 @@ const count = l; size -= 2; const value = reader.getUint8( p ++ ); - for ( let i = 0; i < count + 1; i ++ ) { out.push( value ); @@ -785,7 +740,6 @@ const halfZigBlock = new Array( numComp ); const rowBlock = new Array( numComp ); const rowOffsets = new Array( numComp ); - for ( let comp = 0; comp < numComp; ++ comp ) { rowOffsets[ comp ] = rowPtrs[ cscSet.idx[ comp ] ]; @@ -801,21 +755,21 @@ let maxY = 8; if ( blocky == numBlocksY - 1 ) maxY = leftoverY; let maxX = 8; - for ( let blockx = 0; blockx < numBlocksX; ++ blockx ) { if ( blockx == numBlocksX - 1 ) maxX = leftoverX; - for ( let comp = 0; comp < numComp; ++ comp ) { - halfZigBlock[ comp ].fill( 0 ); // set block DC component + halfZigBlock[ comp ].fill( 0 ); - halfZigBlock[ comp ][ 0 ] = dcBuffer[ currDcComp[ comp ] ++ ]; // set block AC components - - unRleAC( currAcComp, acBuffer, halfZigBlock[ comp ] ); // UnZigZag block to float - - unZigZag( halfZigBlock[ comp ], dctData[ comp ] ); // decode float dct + // set block DC component + halfZigBlock[ comp ][ 0 ] = dcBuffer[ currDcComp[ comp ] ++ ]; + // set block AC components + unRleAC( currAcComp, acBuffer, halfZigBlock[ comp ] ); + // UnZigZag block to float + unZigZag( halfZigBlock[ comp ], dctData[ comp ] ); + // decode float dct dctInverse( dctData[ comp ] ); } @@ -834,17 +788,13 @@ } // blockx - let offset = 0; - for ( let comp = 0; comp < numComp; ++ comp ) { const type = channelData[ cscSet.idx[ comp ] ].type; - for ( let y = 8 * blocky; y < 8 * blocky + maxY; ++ y ) { offset = rowOffsets[ comp ][ y ]; - for ( let blockx = 0; blockx < numFullBlocksX; ++ blockx ) { const src = blockx * 64 + ( y & 0x7 ) * 8; @@ -860,16 +810,15 @@ } - } // handle partial X blocks - + } + // handle partial X blocks if ( numFullBlocksX != numBlocksX ) { for ( let y = 8 * blocky; y < 8 * blocky + maxY; ++ y ) { const offset = rowOffsets[ comp ][ y ] + 8 * numFullBlocksX * INT16_SIZE * type; const src = numFullBlocksX * 64 + ( y & 0x7 ) * 8; - for ( let x = 0; x < maxX; ++ x ) { dataView.setUint16( offset + x * INT16_SIZE * type, rowBlock[ comp ][ src + x ], true ); @@ -884,20 +833,18 @@ } // blocky - const halfRow = new Uint16Array( width ); - dataView = new DataView( outBuffer.buffer ); // convert channels back to float, if needed + dataView = new DataView( outBuffer.buffer ); + // convert channels back to float, if needed for ( let comp = 0; comp < numComp; ++ comp ) { channelData[ cscSet.idx[ comp ] ].decoded = true; const type = channelData[ cscSet.idx[ comp ] ].type; if ( channelData[ comp ].type != 2 ) continue; - for ( let y = 0; y < height; ++ y ) { const offset = rowOffsets[ comp ][ y ]; - for ( let x = 0; x < width; ++ x ) { halfRow[ x ] = dataView.getUint16( offset + x * INT16_SIZE * type, true ); @@ -920,11 +867,9 @@ let acValue; let dctComp = 1; - while ( dctComp < 64 ) { acValue = acBuffer[ currAcComp.value ]; - if ( acValue == 0xff00 ) { dctComp = 64; @@ -1028,7 +973,6 @@ const beta = new Array( 4 ); const theta = new Array( 4 ); const gamma = new Array( 4 ); - for ( let row = 0; row < 8; ++ row ) { const rowPtr = row * 8; @@ -1151,7 +1095,6 @@ function uncompressZIP( info ) { const compressed = info.array.slice( info.offset.value, info.offset.value + info.size ); - if ( typeof fflate === 'undefined' ) { console.error( 'THREE.EXRLoader: External library fflate.min.js required.' ); @@ -1159,7 +1102,6 @@ } const rawBuffer = fflate.unzlibSync( compressed ); // eslint-disable-line no-undef - const tmpBuffer = new Uint8Array( rawBuffer.length ); predictor( rawBuffer ); // revert predictor @@ -1176,11 +1118,11 @@ value: info.offset.value }; const outBuffer = new Uint16Array( info.width * info.scanlineBlockSize * ( info.channels * info.type ) ); - const bitmap = new Uint8Array( BITMAP_SIZE ); // Setup channel info + const bitmap = new Uint8Array( BITMAP_SIZE ); + // Setup channel info let outBufferEnd = 0; const pizChannelData = new Array( info.channels ); - for ( let i = 0; i < info.channels; i ++ ) { pizChannelData[ i ] = {}; @@ -1191,12 +1133,12 @@ pizChannelData[ i ][ 'size' ] = info.type; outBufferEnd += pizChannelData[ i ].nx * pizChannelData[ i ].ny * pizChannelData[ i ].size; - } // Read range compression data + } + // Read range compression data const minNonZero = parseUint16( inDataView, inOffset ); const maxNonZero = parseUint16( inDataView, inOffset ); - if ( maxNonZero >= BITMAP_SIZE ) { throw new Error( 'Something is wrong with PIZ_COMPRESSION BITMAP_SIZE' ); @@ -1211,33 +1153,34 @@ } - } // Reverse LUT - + } + // Reverse LUT const lut = new Uint16Array( USHORT_RANGE ); const maxValue = reverseLutFromBitmap( bitmap, lut ); - const length = parseUint32( inDataView, inOffset ); // Huffman decoding + const length = parseUint32( inDataView, inOffset ); - hufUncompress( info.array, inDataView, inOffset, length, outBuffer, outBufferEnd ); // Wavelet decoding + // Huffman decoding + hufUncompress( info.array, inDataView, inOffset, length, outBuffer, outBufferEnd ); + // Wavelet decoding for ( let i = 0; i < info.channels; ++ i ) { const cd = pizChannelData[ i ]; - for ( let j = 0; j < pizChannelData[ i ].size; ++ j ) { wav2Decode( outBuffer, cd.start + j, cd.nx, cd.size, cd.ny, cd.nx * cd.size, maxValue ); } - } // Expand the pixel data to their original range - + } - applyLut( lut, outBuffer, outBufferEnd ); // Rearrange the pixel data into the format expected by the caller. + // Expand the pixel data to their original range + applyLut( lut, outBuffer, outBufferEnd ); + // Rearrange the pixel data into the format expected by the caller. let tmpOffset = 0; const tmpBuffer = new Uint8Array( outBuffer.buffer.byteLength ); - for ( let y = 0; y < info.lines; y ++ ) { for ( let c = 0; c < info.channels; c ++ ) { @@ -1260,7 +1203,6 @@ function uncompressPXR( info ) { const compressed = info.array.slice( info.offset.value, info.offset.value + info.size ); - if ( typeof fflate === 'undefined' ) { console.error( 'THREE.EXRLoader: External library fflate.min.js required.' ); @@ -1274,20 +1216,17 @@ let tmpBufferEnd = 0; let writePtr = 0; const ptr = new Array( 4 ); - for ( let y = 0; y < info.lines; y ++ ) { for ( let c = 0; c < info.channels; c ++ ) { let pixel = 0; - switch ( info.type ) { case 1: ptr[ 0 ] = tmpBufferEnd; ptr[ 1 ] = ptr[ 0 ] + info.width; tmpBufferEnd = ptr[ 1 ] + info.width; - for ( let j = 0; j < info.width; ++ j ) { const diff = rawBuffer[ ptr[ 0 ] ++ ] << 8 | rawBuffer[ ptr[ 1 ] ++ ]; @@ -1298,13 +1237,11 @@ } break; - case 2: ptr[ 0 ] = tmpBufferEnd; ptr[ 1 ] = ptr[ 0 ] + info.width; ptr[ 2 ] = ptr[ 1 ] + info.width; tmpBufferEnd = ptr[ 2 ] + info.width; - for ( let j = 0; j < info.width; ++ j ) { const diff = rawBuffer[ ptr[ 0 ] ++ ] << 24 | rawBuffer[ ptr[ 1 ] ++ ] << 16 | rawBuffer[ ptr[ 2 ] ++ ] << 8; @@ -1332,8 +1269,9 @@ const inOffset = { value: info.offset.value }; - const outBuffer = new Uint8Array( info.width * info.lines * ( info.channels * info.type * INT16_SIZE ) ); // Read compression header information + const outBuffer = new Uint8Array( info.width * info.lines * ( info.channels * info.type * INT16_SIZE ) ); + // Read compression header information const dwaHeader = { version: parseInt64( inDataView, inOffset ), unknownUncompressedSize: parseInt64( inDataView, inOffset ), @@ -1347,11 +1285,11 @@ totalDcUncompressedCount: parseInt64( inDataView, inOffset ), acCompression: parseInt64( inDataView, inOffset ) }; - if ( dwaHeader.version < 2 ) throw new Error( 'EXRLoader.parse: ' + EXRHeader.compression + ' version ' + dwaHeader.version + ' is unsupported' ); // Read channel ruleset information + if ( dwaHeader.version < 2 ) throw new Error( 'EXRLoader.parse: ' + EXRHeader.compression + ' version ' + dwaHeader.version + ' is unsupported' ); + // Read channel ruleset information const channelRules = new Array(); let ruleSize = parseUint16( inDataView, inOffset ) - INT16_SIZE; - while ( ruleSize > 0 ) { const name = parseNullTerminatedString( inDataView.buffer, inOffset ); @@ -1368,12 +1306,11 @@ } ); ruleSize -= name.length + 3; - } // Classify channels - + } + // Classify channels const channels = EXRHeader.channels; const channelData = new Array( info.channels ); - for ( let i = 0; i < info.channels; ++ i ) { const cd = channelData[ i ] = {}; @@ -1391,19 +1328,15 @@ const cscSet = { idx: new Array( 3 ) }; - for ( let offset = 0; offset < info.channels; ++ offset ) { const cd = channelData[ offset ]; - for ( let i = 0; i < channelRules.length; ++ i ) { const rule = channelRules[ i ]; - if ( cd.name == rule.name ) { cd.compression = rule.compression; - if ( rule.index >= 0 ) { cscSet.idx[ rule.index ] = offset; @@ -1418,8 +1351,9 @@ } - let acBuffer, dcBuffer, rleBuffer; // Read DCT - AC component data + let acBuffer, dcBuffer, rleBuffer; + // Read DCT - AC component data if ( dwaHeader.acCompressedSize > 0 ) { switch ( dwaHeader.acCompression ) { @@ -1428,20 +1362,18 @@ acBuffer = new Uint16Array( dwaHeader.totalAcUncompressedCount ); hufUncompress( info.array, inDataView, inOffset, dwaHeader.acCompressedSize, acBuffer, dwaHeader.totalAcUncompressedCount ); break; - case DEFLATE: const compressed = info.array.slice( inOffset.value, inOffset.value + dwaHeader.totalAcUncompressedCount ); const data = fflate.unzlibSync( compressed ); // eslint-disable-line no-undef - acBuffer = new Uint16Array( data.buffer ); inOffset.value += dwaHeader.totalAcUncompressedCount; break; } - } // Read DCT - DC component data - + } + // Read DCT - DC component data if ( dwaHeader.dcCompressedSize > 0 ) { const zlibInfo = { @@ -1452,23 +1384,21 @@ dcBuffer = new Uint16Array( uncompressZIP( zlibInfo ).buffer ); inOffset.value += dwaHeader.dcCompressedSize; - } // Read RLE compressed data - + } + // Read RLE compressed data if ( dwaHeader.rleRawSize > 0 ) { const compressed = info.array.slice( inOffset.value, inOffset.value + dwaHeader.rleCompressedSize ); const data = fflate.unzlibSync( compressed ); // eslint-disable-line no-undef - rleBuffer = decodeRunLength( data.buffer ); inOffset.value += dwaHeader.rleCompressedSize; - } // Prepare outbuffer data offset - + } + // Prepare outbuffer data offset let outBufferEnd = 0; const rowOffsets = new Array( channelData.length ); - for ( let i = 0; i < rowOffsets.length; ++ i ) { rowOffsets[ i ] = new Array(); @@ -1484,26 +1414,24 @@ } - } // Lossy DCT decode RGB channels - + } - lossyDctDecode( cscSet, rowOffsets, channelData, acBuffer, dcBuffer, outBuffer ); // Decode other channels + // Lossy DCT decode RGB channels + lossyDctDecode( cscSet, rowOffsets, channelData, acBuffer, dcBuffer, outBuffer ); + // Decode other channels for ( let i = 0; i < channelData.length; ++ i ) { const cd = channelData[ i ]; if ( cd.decoded ) continue; - switch ( cd.compression ) { case RLE: let row = 0; let rleOffset = 0; - for ( let y = 0; y < info.lines; ++ y ) { let rowOffsetBytes = rowOffsets[ i ][ row ]; - for ( let x = 0; x < cd.width; ++ x ) { for ( let byte = 0; byte < INT16_SIZE * cd.type; ++ byte ) { @@ -1521,7 +1449,6 @@ } break; - case LOSSY_DCT: // skip default: @@ -1539,7 +1466,6 @@ const uintBuffer = new Uint8Array( buffer ); let endOffset = 0; - while ( uintBuffer[ offset.value + endOffset ] != 0 ) { endOffset += 1; @@ -1628,9 +1554,9 @@ return THREE.DataUtils.toHalfFloat( parseFloat32( dataView, offset ) ); - } // https://stackoverflow.com/questions/5678432/decompressing-half-precision-floats-in-javascript - + } + // https://stackoverflow.com/questions/5678432/decompressing-half-precision-floats-in-javascript function decodeFloat16( binary ) { const exponent = ( binary & 0x7C00 ) >> 10, @@ -1657,14 +1583,12 @@ const startOffset = offset.value; const channels = []; - while ( offset.value < startOffset + size - 1 ) { const name = parseNullTerminatedString( buffer, offset ); const pixelType = parseInt32( dataView, offset ); const pLinear = parseUint8( dataView, offset ); offset.value += 3; // reserved, three chars - const xSampling = parseInt32( dataView, offset ); const ySampling = parseInt32( dataView, offset ); channels.push( { @@ -1820,10 +1744,10 @@ function parseHeader( dataView, buffer, offset ) { const EXRHeader = {}; - if ( dataView.getUint32( 0, true ) != 20000630 ) { // magic + throw new Error( 'THREE.EXRLoader: provided file doesn\'t appear to be in OpenEXR format.' ); } @@ -1836,16 +1760,16 @@ longName: !! ( spec & 4 ), deepFormat: !! ( spec & 8 ), multiPart: !! ( spec & 16 ) - }; // start of header + }; + + // start of header offset.value = 8; // start at 8 - after pre-amble let keepReading = true; - while ( keepReading ) { const attributeName = parseNullTerminatedString( buffer, offset ); - if ( attributeName == 0 ) { keepReading = false; @@ -1855,7 +1779,6 @@ const attributeType = parseNullTerminatedString( buffer, offset ); const attributeSize = parseUint32( dataView, offset ); const attributeValue = parseValue( dataView, buffer, offset, attributeType, attributeSize ); - if ( attributeValue === undefined ) { console.warn( `EXRLoader.parse: skipped unknown header attribute type \'${attributeType}\'.` ); @@ -1873,6 +1796,7 @@ if ( ( spec & ~ 0x04 ) != 0 ) { // unsupported tiled, deep-image, multi-part + console.error( 'EXRHeader:', EXRHeader ); throw new Error( 'THREE.EXRLoader: provided file is currently unsupported.' ); @@ -1901,56 +1825,46 @@ format: null, encoding: null }; - switch ( EXRHeader.compression ) { case 'NO_COMPRESSION': EXRDecoder.lines = 1; EXRDecoder.uncompress = uncompressRAW; break; - case 'RLE_COMPRESSION': EXRDecoder.lines = 1; EXRDecoder.uncompress = uncompressRLE; break; - case 'ZIPS_COMPRESSION': EXRDecoder.lines = 1; EXRDecoder.uncompress = uncompressZIP; break; - case 'ZIP_COMPRESSION': EXRDecoder.lines = 16; EXRDecoder.uncompress = uncompressZIP; break; - case 'PIZ_COMPRESSION': EXRDecoder.lines = 32; EXRDecoder.uncompress = uncompressPIZ; break; - case 'PXR24_COMPRESSION': EXRDecoder.lines = 16; EXRDecoder.uncompress = uncompressPXR; break; - case 'DWAA_COMPRESSION': EXRDecoder.lines = 32; EXRDecoder.uncompress = uncompressDWA; break; - case 'DWAB_COMPRESSION': EXRDecoder.lines = 256; EXRDecoder.uncompress = uncompressDWA; break; - default: throw new Error( 'EXRLoader.parse: ' + EXRHeader.compression + ' is unsupported' ); } EXRDecoder.scanlineBlockSize = EXRDecoder.lines; - if ( EXRDecoder.type == 1 ) { // half @@ -1960,7 +1874,6 @@ EXRDecoder.getter = parseFloat16; EXRDecoder.inputSize = INT16_SIZE; break; - case THREE.HalfFloatType: EXRDecoder.getter = parseUint16; EXRDecoder.inputSize = INT16_SIZE; @@ -1977,7 +1890,6 @@ EXRDecoder.getter = parseFloat32; EXRDecoder.inputSize = FLOAT32_SIZE; break; - case THREE.HalfFloatType: EXRDecoder.getter = decodeFloat32; EXRDecoder.inputSize = FLOAT32_SIZE; @@ -1991,29 +1903,26 @@ } EXRDecoder.blockCount = ( EXRHeader.dataWindow.yMax + 1 ) / EXRDecoder.scanlineBlockSize; - for ( let i = 0; i < EXRDecoder.blockCount; i ++ ) parseInt64( dataView, offset ); // scanlineOffset - // we should be passed the scanline offset table, ready to start reading pixel data. - // RGB images will be converted to RGBA format, preventing software emulation in select devices. + // we should be passed the scanline offset table, ready to start reading pixel data. + // RGB images will be converted to RGBA format, preventing software emulation in select devices. EXRDecoder.outputChannels = EXRDecoder.channels == 3 ? 4 : EXRDecoder.channels; const size = EXRDecoder.width * EXRDecoder.height * EXRDecoder.outputChannels; - switch ( outputType ) { case THREE.FloatType: - EXRDecoder.byteArray = new Float32Array( size ); // Fill initially with 1s for the alpha value if the texture is not RGBA, RGB values will be overwritten + EXRDecoder.byteArray = new Float32Array( size ); + // Fill initially with 1s for the alpha value if the texture is not RGBA, RGB values will be overwritten if ( EXRDecoder.channels < EXRDecoder.outputChannels ) EXRDecoder.byteArray.fill( 1, 0, size ); break; - case THREE.HalfFloatType: EXRDecoder.byteArray = new Uint16Array( size ); if ( EXRDecoder.channels < EXRDecoder.outputChannels ) EXRDecoder.byteArray.fill( 0x3C00, 0, size ); // Uint16Array holds half float data, 0x3C00 is 1 break; - default: console.error( 'THREE.EXRLoader: unsupported type: ', outputType ); break; @@ -2021,7 +1930,6 @@ } EXRDecoder.bytesPerLine = EXRDecoder.width * EXRDecoder.inputSize * EXRDecoder.channels; - if ( EXRDecoder.outputChannels == 4 ) { EXRDecoder.format = THREE.RGBAFormat; @@ -2036,17 +1944,20 @@ return EXRDecoder; - } // start parsing file [START] + } + // start parsing file [START] const bufferDataView = new DataView( buffer ); const uInt8Array = new Uint8Array( buffer ); const offset = { value: 0 - }; // get header information and validate format. + }; - const EXRHeader = parseHeader( bufferDataView, buffer, offset ); // get input compression information and prepare decoding. + // get header information and validate format. + const EXRHeader = parseHeader( bufferDataView, buffer, offset ); + // get input compression information and prepare decoding. const EXRDecoder = setupDecoder( EXRHeader, bufferDataView, uInt8Array, offset, this.type ); const tmpOffset = { value: 0 @@ -2058,27 +1969,21 @@ A: 3, Y: 0 }; - for ( let scanlineBlockIdx = 0; scanlineBlockIdx < EXRDecoder.height / EXRDecoder.scanlineBlockSize; scanlineBlockIdx ++ ) { const line = parseUint32( bufferDataView, offset ); // line_no - EXRDecoder.size = parseUint32( bufferDataView, offset ); // data_len - EXRDecoder.lines = line + EXRDecoder.scanlineBlockSize > EXRDecoder.height ? EXRDecoder.height - line : EXRDecoder.scanlineBlockSize; const isCompressed = EXRDecoder.size < EXRDecoder.lines * EXRDecoder.bytesPerLine; const viewer = isCompressed ? EXRDecoder.uncompress( EXRDecoder ) : uncompressRAW( EXRDecoder ); offset.value += EXRDecoder.size; - for ( let line_y = 0; line_y < EXRDecoder.scanlineBlockSize; line_y ++ ) { const true_y = line_y + scanlineBlockIdx * EXRDecoder.scanlineBlockSize; if ( true_y >= EXRDecoder.height ) break; - for ( let channelID = 0; channelID < EXRDecoder.channels; channelID ++ ) { const cOff = channelOffsets[ EXRHeader.channels[ channelID ].name ]; - for ( let x = 0; x < EXRDecoder.width; x ++ ) { tmpOffset.value = ( line_y * ( EXRDecoder.channels * EXRDecoder.width ) + channelID * EXRDecoder.width + x ) * EXRDecoder.inputSize; @@ -2104,14 +2009,12 @@ }; } - setDataType( value ) { this.type = value; return this; } - load( url, onLoad, onProgress, onError ) { function onLoadCallback( texture, texData ) { diff --git a/examples/js/loaders/FBXLoader.js b/examples/js/loaders/FBXLoader.js index 3971845dac0f6b..e517c1853c24b9 100644 --- a/examples/js/loaders/FBXLoader.js +++ b/examples/js/loaders/FBXLoader.js @@ -18,7 +18,6 @@ let fbxTree; let connections; let sceneGraph; - class FBXLoader extends THREE.Loader { constructor( manager ) { @@ -26,7 +25,6 @@ super( manager ); } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -61,7 +59,6 @@ }, onProgress, onError ); } - parse( FBXBuffer, path ) { if ( isFbxFormatBinary( FBXBuffer ) ) { @@ -71,7 +68,6 @@ } else { const FBXText = convertArrayBufferToString( FBXBuffer ); - if ( ! isFbxFormatASCII( FBXText ) ) { throw new Error( 'THREE.FBXLoader: Unknown format.' ); @@ -86,17 +82,18 @@ fbxTree = new TextParser().parse( FBXText ); - } // console.log( fbxTree ); + } + // console.log( fbxTree ); const textureLoader = new THREE.TextureLoader( this.manager ).setPath( this.resourcePath || path ).setCrossOrigin( this.crossOrigin ); return new FBXTreeParser( textureLoader, this.manager ).parse( fbxTree ); } - } // Parse the FBXTree object returned by the BinaryParser or TextParser and return a THREE.Group - + } + // Parse the FBXTree object returned by the BinaryParser or TextParser and return a THREE.Group class FBXTreeParser { constructor( textureLoader, manager ) { @@ -105,7 +102,6 @@ this.manager = manager; } - parse() { connections = this.parseConnections(); @@ -117,14 +113,13 @@ this.parseScene( deformers, geometryMap, materials ); return sceneGraph; - } // Parses FBXTree.Connections which holds parent-child connections between objects (e.g. material -> texture, model->geometry ) - // and details the connection type - + } + // Parses FBXTree.Connections which holds parent-child connections between objects (e.g. material -> texture, model->geometry ) + // and details the connection type parseConnections() { const connectionMap = new Map(); - if ( 'Connections' in fbxTree ) { const rawConnections = fbxTree.Connections.connections; @@ -133,7 +128,6 @@ const fromID = rawConnection[ 0 ]; const toID = rawConnection[ 1 ]; const relationship = rawConnection[ 2 ]; - if ( ! connectionMap.has( fromID ) ) { connectionMap.set( fromID, { @@ -148,7 +142,6 @@ relationship: relationship }; connectionMap.get( fromID ).parents.push( parentRelationship ); - if ( ! connectionMap.has( toID ) ) { connectionMap.set( toID, { @@ -170,31 +163,29 @@ return connectionMap; - } // Parse FBXTree.Objects.Video for embedded image data + } + + // Parse FBXTree.Objects.Video for embedded image data // These images are connected to textures in FBXTree.Objects.Textures // via FBXTree.Connections. - - parseImages() { const images = {}; const blobs = {}; - if ( 'Video' in fbxTree.Objects ) { const videoNodes = fbxTree.Objects.Video; - for ( const nodeID in videoNodes ) { const videoNode = videoNodes[ nodeID ]; const id = parseInt( nodeID ); - images[ id ] = videoNode.RelativeFilename || videoNode.Filename; // raw image data is in videoNode.Content + images[ id ] = videoNode.RelativeFilename || videoNode.Filename; + // raw image data is in videoNode.Content if ( 'Content' in videoNode ) { const arrayBufferContent = videoNode.Content instanceof ArrayBuffer && videoNode.Content.byteLength > 0; const base64Content = typeof videoNode.Content === 'string' && videoNode.Content !== ''; - if ( arrayBufferContent || base64Content ) { const image = this.parseImage( videoNodes[ nodeID ] ); @@ -217,35 +208,30 @@ return images; - } // Parse embedded image data in FBXTree.Video.Content - + } + // Parse embedded image data in FBXTree.Video.Content parseImage( videoNode ) { const content = videoNode.Content; const fileName = videoNode.RelativeFilename || videoNode.Filename; const extension = fileName.slice( fileName.lastIndexOf( '.' ) + 1 ).toLowerCase(); let type; - switch ( extension ) { case 'bmp': type = 'image/bmp'; break; - case 'jpg': case 'jpeg': type = 'image/jpeg'; break; - case 'png': type = 'image/png'; break; - case 'tif': type = 'image/tiff'; break; - case 'tga': if ( this.manager.getHandler( '.tga' ) === null ) { @@ -255,7 +241,6 @@ type = 'image/tga'; break; - default: console.warn( 'FBXLoader: Image type "' + extension + '" is not supported.' ); return; @@ -265,11 +250,13 @@ if ( typeof content === 'string' ) { // ASCII format + return 'data:' + type + ';base64,' + content; } else { // Binary Format + const array = new Uint8Array( content ); return window.URL.createObjectURL( new Blob( [ array ], { type: type @@ -277,19 +264,17 @@ } - } // Parse nodes in FBXTree.Objects.Texture + } + + // Parse nodes in FBXTree.Objects.Texture // These contain details such as UV scaling, cropping, rotation etc and are connected // to images in FBXTree.Objects.Video - - parseTextures( images ) { const textureMap = new Map(); - if ( 'Texture' in fbxTree.Objects ) { const textureNodes = fbxTree.Objects.Texture; - for ( const nodeID in textureNodes ) { const texture = this.parseTexture( textureNodes[ nodeID ], images ); @@ -301,9 +286,9 @@ return textureMap; - } // Parse individual node in FBXTree.Objects.Texture - + } + // Parse individual node in FBXTree.Objects.Texture parseTexture( textureNode, images ) { const texture = this.loadTexture( textureNode, images ); @@ -312,12 +297,13 @@ const wrapModeU = textureNode.WrapModeU; const wrapModeV = textureNode.WrapModeV; const valueU = wrapModeU !== undefined ? wrapModeU.value : 0; - const valueV = wrapModeV !== undefined ? wrapModeV.value : 0; // http://download.autodesk.com/us/fbx/SDKdocs/FBX_SDK_Help/files/fbxsdkref/class_k_fbx_texture.html#889640e63e2e681259ea81061b85143a + const valueV = wrapModeV !== undefined ? wrapModeV.value : 0; + + // http://download.autodesk.com/us/fbx/SDKdocs/FBX_SDK_Help/files/fbxsdkref/class_k_fbx_texture.html#889640e63e2e681259ea81061b85143a // 0: repeat(default), 1: clamp texture.wrapS = valueU === 0 ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping; texture.wrapT = valueV === 0 ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping; - if ( 'Scaling' in textureNode ) { const values = textureNode.Scaling.value; @@ -336,19 +322,17 @@ return texture; - } // load a texture specified as a blob or data URI, or via an external URL using THREE.TextureLoader - + } + // load a texture specified as a blob or data URI, or via an external URL using THREE.TextureLoader loadTexture( textureNode, images ) { let fileName; const currentPath = this.textureLoader.path; const children = connections.get( textureNode.id ).children; - if ( children !== undefined && children.length > 0 && images[ children[ 0 ].ID ] !== undefined ) { fileName = images[ children[ 0 ].ID ]; - if ( fileName.indexOf( 'blob:' ) === 0 || fileName.indexOf( 'data:' ) === 0 ) { this.textureLoader.setPath( undefined ); @@ -359,11 +343,9 @@ let texture; const extension = textureNode.FileName.slice( - 3 ).toLowerCase(); - if ( extension === 'tga' ) { const loader = this.manager.getHandler( '.tga' ); - if ( loader === null ) { console.warn( 'FBXLoader: TGA loader not found, creating placeholder texture for', textureNode.RelativeFilename ); @@ -390,17 +372,15 @@ this.textureLoader.setPath( currentPath ); return texture; - } // Parse nodes in FBXTree.Objects.Material - + } + // Parse nodes in FBXTree.Objects.Material parseMaterials( textureMap ) { const materialMap = new Map(); - if ( 'Material' in fbxTree.Objects ) { const materialNodes = fbxTree.Objects.Material; - for ( const nodeID in materialNodes ) { const material = this.parseMaterial( materialNodes[ nodeID ], textureMap ); @@ -412,38 +392,36 @@ return materialMap; - } // Parse single node in FBXTree.Objects.Material + } + + // Parse single node in FBXTree.Objects.Material // Materials are connected to texture maps in FBXTree.Objects.Textures // FBX format currently only supports Lambert and Phong shading models - - parseMaterial( materialNode, textureMap ) { const ID = materialNode.id; const name = materialNode.attrName; - let type = materialNode.ShadingModel; // Case where FBX wraps shading model in property object. + let type = materialNode.ShadingModel; + // Case where FBX wraps shading model in property object. if ( typeof type === 'object' ) { type = type.value; - } // Ignore unused materials which don't have any connections. - + } + // Ignore unused materials which don't have any connections. if ( ! connections.has( ID ) ) return null; const parameters = this.parseParameters( materialNode, textureMap, ID ); let material; - switch ( type.toLowerCase() ) { case 'phong': material = new THREE.MeshPhongMaterial(); break; - case 'lambert': material = new THREE.MeshLambertMaterial(); break; - default: console.warn( 'THREE.FBXLoader: unknown material type "%s". Defaulting to THREE.MeshPhongMaterial.', type ); material = new THREE.MeshPhongMaterial(); @@ -455,14 +433,13 @@ material.name = name; return material; - } // Parse FBX material and return parameters suitable for a three.js material - // Also parse the texture map and return any textures associated with the material - + } + // Parse FBX material and return parameters suitable for a three.js material + // Also parse the texture map and return any textures associated with the material parseParameters( materialNode, textureMap, ID ) { const parameters = {}; - if ( materialNode.BumpFactor ) { parameters.bumpScale = materialNode.BumpFactor.value; @@ -542,21 +519,17 @@ connections.get( ID ).children.forEach( function ( child ) { const type = child.relationship; - switch ( type ) { case 'Bump': parameters.bumpMap = scope.getTexture( textureMap, child.ID ); break; - case 'Maya|TEX_ao_map': parameters.aoMap = scope.getTexture( textureMap, child.ID ); break; - case 'DiffuseColor': case 'Maya|TEX_color_map': parameters.map = scope.getTexture( textureMap, child.ID ); - if ( parameters.map !== undefined ) { parameters.map.encoding = THREE.sRGBEncoding; @@ -564,14 +537,11 @@ } break; - case 'DisplacementColor': parameters.displacementMap = scope.getTexture( textureMap, child.ID ); break; - case 'EmissiveColor': parameters.emissiveMap = scope.getTexture( textureMap, child.ID ); - if ( parameters.emissiveMap !== undefined ) { parameters.emissiveMap.encoding = THREE.sRGBEncoding; @@ -579,15 +549,12 @@ } break; - case 'NormalMap': case 'Maya|TEX_normal_map': parameters.normalMap = scope.getTexture( textureMap, child.ID ); break; - case 'ReflectionColor': parameters.envMap = scope.getTexture( textureMap, child.ID ); - if ( parameters.envMap !== undefined ) { parameters.envMap.mapping = THREE.EquirectangularReflectionMapping; @@ -596,10 +563,8 @@ } break; - case 'SpecularColor': parameters.specularMap = scope.getTexture( textureMap, child.ID ); - if ( parameters.specularMap !== undefined ) { parameters.specularMap.encoding = THREE.sRGBEncoding; @@ -607,20 +572,15 @@ } break; - case 'TransparentColor': case 'TransparencyFactor': parameters.alphaMap = scope.getTexture( textureMap, child.ID ); parameters.transparent = true; break; - case 'AmbientColor': case 'ShininessExponent': // AKA glossiness map - case 'SpecularFactor': // AKA specularLevel - case 'VectorDisplacementColor': // NOTE: Seems to be a copy of DisplacementColor - default: console.warn( 'THREE.FBXLoader: %s map is not supported in three.js, skipping texture.', type ); break; @@ -630,9 +590,9 @@ } ); return parameters; - } // get a texture from the textureMap for use by a material. - + } + // get a texture from the textureMap for use by a material. getTexture( textureMap, id ) { // if the texture is a layered texture, just use the first layer and issue a warning @@ -645,25 +605,22 @@ return textureMap.get( id ); - } // Parse nodes in FBXTree.Objects.Deformer + } + + // Parse nodes in FBXTree.Objects.Deformer // Deformer node can contain skinning or Vertex Cache animation data, however only skinning is supported here // Generates map of THREE.Skeleton-like objects for use later when generating and binding skeletons. - - parseDeformers() { const skeletons = {}; const morphTargets = {}; - if ( 'Deformer' in fbxTree.Objects ) { const DeformerNodes = fbxTree.Objects.Deformer; - for ( const nodeID in DeformerNodes ) { const deformerNode = DeformerNodes[ nodeID ]; const relationships = connections.get( parseInt( nodeID ) ); - if ( deformerNode.attrType === 'Skin' ) { const skeleton = this.parseSkeleton( relationships, DeformerNodes ); @@ -693,11 +650,11 @@ morphTargets: morphTargets }; - } // Parse single nodes in FBXTree.Objects.Deformer + } + + // Parse single nodes in FBXTree.Objects.Deformer // The top level skeleton node has type 'Skin' and sub nodes have type 'Cluster' // Each skin node represents a skeleton and each cluster node represents a bone - - parseSkeleton( relationships, deformerNodes ) { const rawBones = []; @@ -709,9 +666,9 @@ ID: child.ID, indices: [], weights: [], - transformLink: new THREE.Matrix4().fromArray( boneNode.TransformLink.a ) // transform: new THREE.Matrix4().fromArray( boneNode.Transform.a ), + transformLink: new THREE.Matrix4().fromArray( boneNode.TransformLink.a ) + // transform: new THREE.Matrix4().fromArray( boneNode.Transform.a ), // linkMode: boneNode.Mode, - }; if ( 'Indexes' in boneNode ) { @@ -729,13 +686,12 @@ bones: [] }; - } // The top level morph deformer node has type "BlendShape" and sub nodes have type "BlendShapeChannel" - + } + // The top level morph deformer node has type "BlendShape" and sub nodes have type "BlendShapeChannel" parseMorphTargets( relationships, deformerNodes ) { const rawMorphTargets = []; - for ( let i = 0; i < relationships.children.length; i ++ ) { const child = relationships.children[ i ]; @@ -758,9 +714,9 @@ return rawMorphTargets; - } // create the main THREE.Group() to be returned by the loader - + } + // create the main THREE.Group() to be returned by the loader parseScene( deformers, geometryMap, materialMap ) { sceneGraph = new THREE.Group(); @@ -778,7 +734,6 @@ if ( parent !== undefined ) parent.add( model ); } ); - if ( model.parent === null ) { sceneGraph.add( model ); @@ -806,8 +761,9 @@ } } ); - const animations = new AnimationParser().parse(); // if all the models where already combined in a single group, just return that + const animations = new AnimationParser().parse(); + // if all the models where already combined in a single group, just return that if ( sceneGraph.children.length === 1 && sceneGraph.children[ 0 ].isGroup ) { sceneGraph.children[ 0 ].animations = animations; @@ -817,21 +773,19 @@ sceneGraph.animations = animations; - } // parse nodes in FBXTree.Objects.Model - + } + // parse nodes in FBXTree.Objects.Model parseModels( skeletons, geometryMap, materialMap ) { const modelMap = new Map(); const modelNodes = fbxTree.Objects.Model; - for ( const nodeID in modelNodes ) { const id = parseInt( nodeID ); const node = modelNodes[ nodeID ]; const relationships = connections.get( id ); let model = this.buildSkeleton( relationships, skeletons, id, node.attrName ); - if ( ! model ) { switch ( node.attrType ) { @@ -839,24 +793,19 @@ case 'Camera': model = this.createCamera( relationships ); break; - case 'Light': model = this.createLight( relationships ); break; - case 'Mesh': model = this.createMesh( relationships, geometryMap, materialMap ); break; - case 'NurbsCurve': model = this.createCurve( relationships, geometryMap ); break; - case 'LimbNode': case 'Root': model = new THREE.Bone(); break; - case 'Null': default: model = new THREE.Group(); @@ -877,7 +826,6 @@ return modelMap; } - buildSkeleton( relationships, skeletons, id, name ) { let bone = null; @@ -892,13 +840,16 @@ const subBone = bone; bone = new THREE.Bone(); - bone.matrixWorld.copy( rawBone.transformLink ); // set name and id here - otherwise in cases where "subBone" is created it will not have a name / id + bone.matrixWorld.copy( rawBone.transformLink ); + + // set name and id here - otherwise in cases where "subBone" is created it will not have a name / id bone.name = name ? THREE.PropertyBinding.sanitizeNodeName( name ) : ''; bone.ID = id; - skeleton.bones[ i ] = bone; // In cases where a bone is shared between multiple meshes - // duplicate the bone here and and it as a child of the first bone + skeleton.bones[ i ] = bone; + // In cases where a bone is shared between multiple meshes + // duplicate the bone here and and it as a child of the first bone if ( subBone !== null ) { bone.add( subBone ); @@ -914,9 +865,9 @@ } ); return bone; - } // create a THREE.PerspectiveCamera or THREE.OrthographicCamera - + } + // create a THREE.PerspectiveCamera or THREE.OrthographicCamera createCamera( relationships ) { let model; @@ -924,7 +875,6 @@ relationships.children.forEach( function ( child ) { const attr = fbxTree.Objects.NodeAttribute[ child.ID ]; - if ( attr !== undefined ) { cameraAttribute = attr; @@ -932,7 +882,6 @@ } } ); - if ( cameraAttribute === undefined ) { model = new THREE.Object3D(); @@ -940,7 +889,6 @@ } else { let type = 0; - if ( cameraAttribute.CameraProjectionType !== undefined && cameraAttribute.CameraProjectionType.value === 1 ) { type = 1; @@ -948,7 +896,6 @@ } let nearClippingPlane = 1; - if ( cameraAttribute.NearPlane !== undefined ) { nearClippingPlane = cameraAttribute.NearPlane.value / 1000; @@ -956,7 +903,6 @@ } let farClippingPlane = 1000; - if ( cameraAttribute.FarPlane !== undefined ) { farClippingPlane = cameraAttribute.FarPlane.value / 1000; @@ -965,7 +911,6 @@ let width = window.innerWidth; let height = window.innerHeight; - if ( cameraAttribute.AspectWidth !== undefined && cameraAttribute.AspectHeight !== undefined ) { width = cameraAttribute.AspectWidth.value; @@ -975,7 +920,6 @@ const aspect = width / height; let fov = 45; - if ( cameraAttribute.FieldOfView !== undefined ) { fov = cameraAttribute.FieldOfView.value; @@ -983,7 +927,6 @@ } const focalLength = cameraAttribute.FocalLength ? cameraAttribute.FocalLength.value : null; - switch ( type ) { case 0: @@ -991,12 +934,10 @@ model = new THREE.PerspectiveCamera( fov, aspect, nearClippingPlane, farClippingPlane ); if ( focalLength !== null ) model.setFocalLength( focalLength ); break; - case 1: // Orthographic model = new THREE.OrthographicCamera( - width / 2, width / 2, height / 2, - height / 2, nearClippingPlane, farClippingPlane ); break; - default: console.warn( 'THREE.FBXLoader: Unknown camera type ' + type + '.' ); model = new THREE.Object3D(); @@ -1008,9 +949,9 @@ return model; - } // Create a THREE.DirectionalLight, THREE.PointLight or THREE.SpotLight - + } + // Create a THREE.DirectionalLight, THREE.PointLight or THREE.SpotLight createLight( relationships ) { let model; @@ -1018,7 +959,6 @@ relationships.children.forEach( function ( child ) { const attr = fbxTree.Objects.NodeAttribute[ child.ID ]; - if ( attr !== undefined ) { lightAttribute = attr; @@ -1026,15 +966,15 @@ } } ); - if ( lightAttribute === undefined ) { model = new THREE.Object3D(); } else { - let type; // LightType can be undefined for Point lights + let type; + // LightType can be undefined for Point lights if ( lightAttribute.LightType === undefined ) { type = 0; @@ -1046,15 +986,15 @@ } let color = 0xffffff; - if ( lightAttribute.Color !== undefined ) { color = new THREE.Color().fromArray( lightAttribute.Color.value ); } - let intensity = lightAttribute.Intensity === undefined ? 1 : lightAttribute.Intensity.value / 100; // light disabled + let intensity = lightAttribute.Intensity === undefined ? 1 : lightAttribute.Intensity.value / 100; + // light disabled if ( lightAttribute.CastLightOnObject !== undefined && lightAttribute.CastLightOnObject.value === 0 ) { intensity = 0; @@ -1062,7 +1002,6 @@ } let distance = 0; - if ( lightAttribute.FarAttenuationEnd !== undefined ) { if ( lightAttribute.EnableFarAttenuation !== undefined && lightAttribute.EnableFarAttenuation.value === 0 ) { @@ -1075,27 +1014,23 @@ } - } // TODO: could this be calculated linearly from FarAttenuationStart to FarAttenuationEnd? - + } + // TODO: could this be calculated linearly from FarAttenuationStart to FarAttenuationEnd? const decay = 1; - switch ( type ) { case 0: // Point model = new THREE.PointLight( color, intensity, distance, decay ); break; - case 1: // Directional model = new THREE.DirectionalLight( color, intensity ); break; - case 2: // Spot let angle = Math.PI / 3; - if ( lightAttribute.InnerAngle !== undefined ) { angle = THREE.MathUtils.degToRad( lightAttribute.InnerAngle.value ); @@ -1103,7 +1038,6 @@ } let penumbra = 0; - if ( lightAttribute.OuterAngle !== undefined ) { // TODO: this is not correct - FBX calculates outer and inner angle in degrees @@ -1116,7 +1050,6 @@ model = new THREE.SpotLight( color, intensity, distance, angle, penumbra, decay ); break; - default: console.warn( 'THREE.FBXLoader: Unknown light type ' + lightAttribute.LightType.value + ', defaulting to a THREE.PointLight.' ); model = new THREE.PointLight( color, intensity ); @@ -1135,14 +1068,14 @@ return model; } - createMesh( relationships, geometryMap, materialMap ) { let model; let geometry = null; let material = null; - const materials = []; // get geometry and materials(s) from connections + const materials = []; + // get geometry and materials(s) from connections relationships.children.forEach( function ( child ) { if ( geometryMap.has( child.ID ) ) { @@ -1158,7 +1091,6 @@ } } ); - if ( materials.length > 1 ) { material = materials; @@ -1200,7 +1132,6 @@ return model; } - createCurve( relationships, geometryMap ) { const geometry = relationships.children.reduce( function ( geo, child ) { @@ -1208,17 +1139,18 @@ if ( geometryMap.has( child.ID ) ) geo = geometryMap.get( child.ID ); return geo; - }, null ); // FBX does not list materials for Nurbs lines, so we'll just put our own in here. + }, null ); + // FBX does not list materials for Nurbs lines, so we'll just put our own in here. const material = new THREE.LineBasicMaterial( { color: 0x3300ff, linewidth: 1 } ); return new THREE.Line( geometry, material ); - } // parse the model node for transform data - + } + // parse the model node for transform data getTransformData( model, modelNode ) { const transformData = {}; @@ -1236,7 +1168,6 @@ model.userData.transformData = transformData; } - setLookAtProperties( model, modelNode ) { if ( 'LookAtProperty' in modelNode ) { @@ -1247,11 +1178,11 @@ if ( child.relationship === 'LookAtProperty' ) { const lookAtTarget = fbxTree.Objects.Model[ child.ID ]; - if ( 'Lcl_Translation' in lookAtTarget ) { - const pos = lookAtTarget.Lcl_Translation.value; // THREE.DirectionalLight, THREE.SpotLight + const pos = lookAtTarget.Lcl_Translation.value; + // THREE.DirectionalLight, THREE.SpotLight if ( model.target !== undefined ) { model.target.position.fromArray( pos ); @@ -1260,6 +1191,7 @@ } else { // Cameras and other Object3Ds + model.lookAt( new THREE.Vector3().fromArray( pos ) ); } @@ -1273,11 +1205,9 @@ } } - bindSkeleton( skeletons, geometryMap, modelMap ) { const bindMatrices = this.parsePoseNodes(); - for ( const ID in skeletons ) { const skeleton = skeletons[ ID ]; @@ -1306,21 +1236,17 @@ } } - parsePoseNodes() { const bindMatrices = {}; - if ( 'Pose' in fbxTree.Objects ) { const BindPoseNode = fbxTree.Objects.Pose; - for ( const nodeID in BindPoseNode ) { if ( BindPoseNode[ nodeID ].attrType === 'BindPose' && BindPoseNode[ nodeID ].NbPoseNodes > 0 ) { const poseNodes = BindPoseNode[ nodeID ].PoseNode; - if ( Array.isArray( poseNodes ) ) { poseNodes.forEach( function ( poseNode ) { @@ -1343,9 +1269,9 @@ return bindMatrices; - } // Parse ambient color in FBXTree.GlobalSettings - if it's not set to black (default), create an ambient light - + } + // Parse ambient color in FBXTree.GlobalSettings - if it's not set to black (default), create an ambient light createAmbientLight() { if ( 'GlobalSettings' in fbxTree && 'AmbientColor' in fbxTree.GlobalSettings ) { @@ -1354,7 +1280,6 @@ const r = ambientColor[ 0 ]; const g = ambientColor[ 1 ]; const b = ambientColor[ 2 ]; - if ( r !== 0 || g !== 0 || b !== 0 ) { const color = new THREE.Color( r, g, b ); @@ -1366,20 +1291,24 @@ } - } // parse Geometry data from FBXTree and return map of BufferGeometries - + } + // parse Geometry data from FBXTree and return map of BufferGeometries class GeometryParser { + constructor() { + + this.negativeMaterialIndices = false; + + } + // Parse nodes in FBXTree.Objects.Geometry parse( deformers ) { const geometryMap = new Map(); - if ( 'Geometry' in fbxTree.Objects ) { const geoNodes = fbxTree.Objects.Geometry; - for ( const nodeID in geoNodes ) { const relationships = connections.get( parseInt( nodeID ) ); @@ -1390,11 +1319,19 @@ } - return geometryMap; + // report warnings + + if ( this.negativeMaterialIndices === true ) { + + console.warn( 'THREE.FBXLoader: The FBX file contains invalid (negative) material indices. The asset might not render as expected.' ); + + } - } // Parse single node in FBXTree.Objects.Geometry + return geometryMap; + } + // Parse single node in FBXTree.Objects.Geometry parseGeometry( relationships, geoNode, deformers ) { switch ( geoNode.attrType ) { @@ -1402,16 +1339,15 @@ case 'Mesh': return this.parseMeshGeometry( relationships, geoNode, deformers ); break; - case 'NurbsCurve': return this.parseNurbsGeometry( geoNode ); break; } - } // Parse single node mesh geometry in FBXTree.Objects.Geometry - + } + // Parse single node mesh geometry in FBXTree.Objects.Geometry parseMeshGeometry( relationships, geoNode, deformers ) { const skeletons = deformers.skeletons; @@ -1420,8 +1356,9 @@ return fbxTree.Objects.Model[ parent.ID ]; - } ); // don't create geometry if it is not associated with any models + } ); + // don't create geometry if it is not associated with any models if ( modelNodes.length === 0 ) return; const skeleton = relationships.children.reduce( function ( skeleton, child ) { @@ -1437,9 +1374,10 @@ } - } ); // Assume one model and get the preRotation from that - // if there is more than one model associated with the geometry this may cause problems + } ); + // Assume one model and get the preRotation from that + // if there is more than one model associated with the geometry this may cause problems const modelNode = modelNodes[ 0 ]; const transformData = {}; if ( 'RotationOrder' in modelNode ) transformData.eulerOrder = getEulerOrder( modelNode.RotationOrder.value ); @@ -1450,9 +1388,9 @@ const transform = generateTransform( transformData ); return this.genGeometry( geoNode, skeleton, morphTargets, transform ); - } // Generate a THREE.BufferGeometry from a node in FBXTree.Objects.Geometry - + } + // Generate a THREE.BufferGeometry from a node in FBXTree.Objects.Geometry genGeometry( geoNode, skeleton, morphTargets, preTransform ) { const geo = new THREE.BufferGeometry(); @@ -1462,7 +1400,6 @@ const positionAttribute = new THREE.Float32BufferAttribute( buffers.vertex, 3 ); positionAttribute.applyMatrix4( preTransform ); geo.setAttribute( 'position', positionAttribute ); - if ( buffers.colors.length > 0 ) { geo.setAttribute( 'color', new THREE.Float32BufferAttribute( buffers.colors, 3 ) ); @@ -1472,8 +1409,9 @@ if ( skeleton ) { geo.setAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( buffers.weightsIndices, 4 ) ); - geo.setAttribute( 'skinWeight', new THREE.Float32BufferAttribute( buffers.vertexWeights, 4 ) ); // used later to bind the skeleton to the model + geo.setAttribute( 'skinWeight', new THREE.Float32BufferAttribute( buffers.vertexWeights, 4 ) ); + // used later to bind the skeleton to the model geo.FBX_Deformer = skeleton; } @@ -1490,8 +1428,9 @@ buffers.uvs.forEach( function ( uvBuffer, i ) { // subsequent uv buffers are called 'uv1', 'uv2', ... - let name = 'uv' + ( i + 1 ).toString(); // the first uv buffer is just called 'uv' + let name = 'uv' + ( i + 1 ).toString(); + // the first uv buffer is just called 'uv' if ( i === 0 ) { name = 'uv'; @@ -1501,7 +1440,6 @@ geo.setAttribute( name, new THREE.Float32BufferAttribute( buffers.uvs[ i ], 2 ) ); } ); - if ( geoInfo.material && geoInfo.material.mappingType !== 'AllSame' ) { // Convert the material indices of each vertex into rendering groups on the geometry. @@ -1517,23 +1455,23 @@ } - } ); // the loop above doesn't add the last group, do that here. + } ); + // the loop above doesn't add the last group, do that here. if ( geo.groups.length > 0 ) { const lastGroup = geo.groups[ geo.groups.length - 1 ]; const lastIndex = lastGroup.start + lastGroup.count; - if ( lastIndex !== buffers.materialIndex.length ) { geo.addGroup( lastIndex, buffers.materialIndex.length - lastIndex, prevMaterialIndex ); } - } // case where there are multiple materials but the whole geometry is only - // using one of them - + } + // case where there are multiple materials but the whole geometry is only + // using one of them if ( geo.groups.length === 0 ) { geo.addGroup( 0, buffers.materialIndex.length, buffers.materialIndex[ 0 ] ); @@ -1546,13 +1484,11 @@ return geo; } - parseGeoNode( geoNode, skeleton ) { const geoInfo = {}; geoInfo.vertexPositions = geoNode.Vertices !== undefined ? geoNode.Vertices.a : []; geoInfo.vertexIndices = geoNode.PolygonVertexIndex !== undefined ? geoNode.PolygonVertexIndex.a : []; - if ( geoNode.LayerElementColor ) { geoInfo.color = this.parseVertexColors( geoNode.LayerElementColor[ 0 ] ); @@ -1575,7 +1511,6 @@ geoInfo.uv = []; let i = 0; - while ( geoNode.LayerElementUV[ i ] ) { if ( geoNode.LayerElementUV[ i ].UV ) { @@ -1591,7 +1526,6 @@ } geoInfo.weightTable = {}; - if ( skeleton !== null ) { geoInfo.skeleton = skeleton; @@ -1615,7 +1549,6 @@ return geoInfo; } - genBuffers( geoInfo ) { const buffers = { @@ -1629,8 +1562,9 @@ }; let polygonIndex = 0; let faceLength = 0; - let displayedWeightsWarning = false; // these will hold data for a single face + let displayedWeightsWarning = false; + // these will hold data for a single face let facePositionIndexes = []; let faceNormals = []; let faceColors = []; @@ -1641,18 +1575,18 @@ geoInfo.vertexIndices.forEach( function ( vertexIndex, polygonVertexIndex ) { let materialIndex; - let endOfFace = false; // Face index and vertex index arrays are combined in a single array + let endOfFace = false; + + // Face index and vertex index arrays are combined in a single array // A cube with quad faces looks like this: // PolygonVertexIndex: *24 { // a: 0, 1, 3, -3, 2, 3, 5, -5, 4, 5, 7, -7, 6, 7, 1, -1, 1, 7, 5, -4, 6, 0, 2, -5 // } // Negative numbers mark the end of a face - first face here is 0, 1, 3, -3 // to find index of last vertex bit shift the index: ^ - 1 - if ( vertexIndex < 0 ) { vertexIndex = vertexIndex ^ - 1; // equivalent to ( x * -1 ) - 1 - endOfFace = true; } @@ -1660,7 +1594,6 @@ let weightIndices = []; let weights = []; facePositionIndexes.push( vertexIndex * 3, vertexIndex * 3 + 1, vertexIndex * 3 + 2 ); - if ( geoInfo.color ) { const data = getData( polygonVertexIndex, polygonIndex, vertexIndex, geoInfo.color ); @@ -1714,9 +1647,9 @@ weightIndices = wIndex; weights = Weight; - } // if the weight array is shorter than 4 pad with 0s - + } + // if the weight array is shorter than 4 pad with 0s while ( weights.length < 4 ) { weights.push( 0 ); @@ -1743,6 +1676,12 @@ if ( geoInfo.material && geoInfo.material.mappingType !== 'AllSame' ) { materialIndex = getData( polygonVertexIndex, polygonIndex, vertexIndex, geoInfo.material )[ 0 ]; + if ( materialIndex < 0 ) { + + scope.negativeMaterialIndices = true; + materialIndex = 0; // fallback + + } } @@ -1751,7 +1690,6 @@ geoInfo.uv.forEach( function ( uv, i ) { const data = getData( polygonVertexIndex, polygonIndex, vertexIndex, uv ); - if ( faceUVs[ i ] === undefined ) { faceUVs[ i ] = []; @@ -1766,13 +1704,14 @@ } faceLength ++; - if ( endOfFace ) { + if ( faceLength > 4 ) console.warn( 'THREE.FBXLoader: Polygons with more than four sides are not supported. Make sure to triangulate the geometry during export.' ); scope.genFace( buffers, geoInfo, facePositionIndexes, materialIndex, faceNormals, faceColors, faceUVs, faceWeights, faceWeightIndices, faceLength ); polygonIndex ++; - faceLength = 0; // reset arrays for the next face + faceLength = 0; + // reset arrays for the next face facePositionIndexes = []; faceNormals = []; faceColors = []; @@ -1785,9 +1724,9 @@ } ); return buffers; - } // Generate data for a single face in a geometry. If the face is a quad then split it into 2 tris - + } + // Generate data for a single face in a geometry. If the face is a quad then split it into 2 tris genFace( buffers, geoInfo, facePositionIndexes, materialIndex, faceNormals, faceColors, faceUVs, faceWeights, faceWeightIndices, faceLength ) { for ( let i = 2; i < faceLength; i ++ ) { @@ -1801,7 +1740,6 @@ buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ i * 3 ] ] ); buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ i * 3 + 1 ] ] ); buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ i * 3 + 2 ] ] ); - if ( geoInfo.skeleton ) { buffers.vertexWeights.push( faceWeights[ 0 ] ); @@ -1886,12 +1824,12 @@ } } - addMorphTargets( parentGeo, parentGeoNode, morphTargets, preTransform ) { if ( morphTargets.length === 0 ) return; parentGeo.morphTargetsRelative = true; - parentGeo.morphAttributes.position = []; // parentGeo.morphAttributes.normal = []; // not implemented + parentGeo.morphAttributes.position = []; + // parentGeo.morphAttributes.normal = []; // not implemented const scope = this; morphTargets.forEach( function ( morphTarget ) { @@ -1899,7 +1837,6 @@ morphTarget.rawTargets.forEach( function ( rawTarget ) { const morphGeoNode = fbxTree.Objects.Geometry[ rawTarget.geoID ]; - if ( morphGeoNode !== undefined ) { scope.genMorphGeometry( parentGeo, parentGeoNode, morphGeoNode, preTransform, rawTarget.name ); @@ -1910,12 +1847,12 @@ } ); - } // a morph geometry node is similar to a standard node, and the node is also contained + } + + // a morph geometry node is similar to a standard node, and the node is also contained // in FBXTree.Objects.Geometry, however it can only have attributes for position, normal // and a special attribute Index defining which vertices of the original geometry are affected // Normal and position attributes only have data for the vertices that are affected by the morph - - genMorphGeometry( parentGeo, parentGeoNode, morphGeoNode, preTransform, name ) { const vertexIndices = parentGeoNode.PolygonVertexIndex !== undefined ? parentGeoNode.PolygonVertexIndex.a : []; @@ -1923,7 +1860,6 @@ const indices = morphGeoNode.Indexes !== undefined ? morphGeoNode.Indexes.a : []; const length = parentGeo.attributes.position.count * 3; const morphPositions = new Float32Array( length ); - for ( let i = 0; i < indices.length; i ++ ) { const morphIndex = indices[ i ] * 3; @@ -1931,9 +1867,9 @@ morphPositions[ morphIndex + 1 ] = morphPositionsSparse[ i * 3 + 1 ]; morphPositions[ morphIndex + 2 ] = morphPositionsSparse[ i * 3 + 2 ]; - } // TODO: add morph normal support - + } + // TODO: add morph normal support const morphGeoInfo = { vertexIndices: vertexIndices, vertexPositions: morphPositions @@ -1944,16 +1880,15 @@ positionAttribute.applyMatrix4( preTransform ); parentGeo.morphAttributes.position.push( positionAttribute ); - } // Parse normal from FBXTree.Objects.Geometry.LayerElementNormal if it exists - + } + // Parse normal from FBXTree.Objects.Geometry.LayerElementNormal if it exists parseNormals( NormalNode ) { const mappingType = NormalNode.MappingInformationType; const referenceType = NormalNode.ReferenceInformationType; const buffer = NormalNode.Normals.a; let indexBuffer = []; - if ( referenceType === 'IndexToDirect' ) { if ( 'NormalIndex' in NormalNode ) { @@ -1976,16 +1911,15 @@ referenceType: referenceType }; - } // Parse UVs from FBXTree.Objects.Geometry.LayerElementUV if it exists - + } + // Parse UVs from FBXTree.Objects.Geometry.LayerElementUV if it exists parseUVs( UVNode ) { const mappingType = UVNode.MappingInformationType; const referenceType = UVNode.ReferenceInformationType; const buffer = UVNode.UV.a; let indexBuffer = []; - if ( referenceType === 'IndexToDirect' ) { indexBuffer = UVNode.UVIndex.a; @@ -2000,16 +1934,15 @@ referenceType: referenceType }; - } // Parse Vertex Colors from FBXTree.Objects.Geometry.LayerElementColor if it exists - + } + // Parse Vertex Colors from FBXTree.Objects.Geometry.LayerElementColor if it exists parseVertexColors( ColorNode ) { const mappingType = ColorNode.MappingInformationType; const referenceType = ColorNode.ReferenceInformationType; const buffer = ColorNode.Colors.a; let indexBuffer = []; - if ( referenceType === 'IndexToDirect' ) { indexBuffer = ColorNode.ColorIndex.a; @@ -2024,14 +1957,13 @@ referenceType: referenceType }; - } // Parse mapping and material data in FBXTree.Objects.Geometry.LayerElementMaterial if it exists - + } + // Parse mapping and material data in FBXTree.Objects.Geometry.LayerElementMaterial if it exists parseMaterialIndices( MaterialNode ) { const mappingType = MaterialNode.MappingInformationType; const referenceType = MaterialNode.ReferenceInformationType; - if ( mappingType === 'NoMappingInformation' ) { return { @@ -2044,12 +1976,12 @@ } - const materialIndexBuffer = MaterialNode.Materials.a; // Since materials are stored as indices, there's a bit of a mismatch between FBX and what + const materialIndexBuffer = MaterialNode.Materials.a; + + // Since materials are stored as indices, there's a bit of a mismatch between FBX and what // we expect.So we create an intermediate buffer that points to the index in the buffer, // for conforming with the other functions we've written for other data. - const materialIndices = []; - for ( let i = 0; i < materialIndexBuffer.length; ++ i ) { materialIndices.push( i ); @@ -2064,9 +1996,9 @@ referenceType: referenceType }; - } // Generate a NurbGeometry from a node in FBXTree.Objects.Geometry - + } + // Generate a NurbGeometry from a node in FBXTree.Objects.Geometry parseNurbsGeometry( geoNode ) { if ( THREE.NURBSCurve === undefined ) { @@ -2077,7 +2009,6 @@ } const order = parseInt( geoNode.Order ); - if ( isNaN( order ) ) { console.error( 'THREE.FBXLoader: Invalid Order %s given for geometry ID: %s', geoNode.Order, geoNode.id ); @@ -2089,7 +2020,6 @@ const knots = geoNode.KnotVector.a; const controlPoints = []; const pointsValues = geoNode.Points.a; - for ( let i = 0, l = pointsValues.length; i < l; i += 4 ) { controlPoints.push( new THREE.Vector4().fromArray( pointsValues, i ) ); @@ -2097,7 +2027,6 @@ } let startKnot, endKnot; - if ( geoNode.Form === 'Closed' ) { controlPoints.push( controlPoints[ 0 ] ); @@ -2106,7 +2035,6 @@ startKnot = degree; endKnot = knots.length - 1 - startKnot; - for ( let i = 0; i < degree; ++ i ) { controlPoints.push( controlPoints[ i ] ); @@ -2121,9 +2049,9 @@ } - } // parse animation data from FBXTree - + } + // parse animation data from FBXTree class AnimationParser { // take raw animation clips and turn them into three.js animation clips @@ -2131,7 +2059,6 @@ const animationClips = []; const rawClips = this.parseClips(); - if ( rawClips !== undefined ) { for ( const key in rawClips ) { @@ -2147,7 +2074,6 @@ return animationClips; } - parseClips() { // since the actual transformation data is stored in FBXTree.Objects.AnimationCurve, @@ -2159,20 +2085,18 @@ const rawClips = this.parseAnimStacks( layersMap ); return rawClips; - } // parse nodes in FBXTree.Objects.AnimationCurveNode + } + + // parse nodes in FBXTree.Objects.AnimationCurveNode // each AnimationCurveNode holds data for an animation transform for a model (e.g. left arm rotation ) // and is referenced by an AnimationLayer - - parseAnimationCurveNodes() { const rawCurveNodes = fbxTree.Objects.AnimationCurveNode; const curveNodesMap = new Map(); - for ( const nodeID in rawCurveNodes ) { const rawCurveNode = rawCurveNodes[ nodeID ]; - if ( rawCurveNode.attrName.match( /S|R|T|DeformPercent/ ) !== null ) { const curveNode = { @@ -2188,14 +2112,16 @@ return curveNodesMap; - } // parse nodes in FBXTree.Objects.AnimationCurve and connect them up to + } + + // parse nodes in FBXTree.Objects.AnimationCurve and connect them up to // previously parsed AnimationCurveNodes. Each AnimationCurve holds data for a single animated // axis ( e.g. times and values of x rotation) - - parseAnimationCurves( curveNodesMap ) { - const rawCurves = fbxTree.Objects.AnimationCurve; // TODO: Many values are identical up to roundoff error, but won't be optimised + const rawCurves = fbxTree.Objects.AnimationCurve; + + // TODO: Many values are identical up to roundoff error, but won't be optimised // e.g. position times: [0, 0.4, 0. 8] // position values: [7.23538335023477e-7, 93.67518615722656, -0.9982695579528809, 7.23538335023477e-7, 93.67518615722656, -0.9982695579528809, 7.235384487103147e-7, 93.67520904541016, -0.9982695579528809] // clearly, this should be optimised to @@ -2210,12 +2136,10 @@ values: rawCurves[ nodeID ].KeyValueFloat.a }; const relationships = connections.get( animationCurve.id ); - if ( relationships !== undefined ) { const animationCurveID = relationships.parents[ 0 ].ID; const animationCurveRelationship = relationships.parents[ 0 ].relationship; - if ( animationCurveRelationship.match( /X/ ) ) { curveNodesMap.get( animationCurveID ).curves[ 'x' ] = animationCurve; @@ -2238,21 +2162,19 @@ } - } // parse nodes in FBXTree.Objects.AnimationLayer. Each layers holds references + } + + // parse nodes in FBXTree.Objects.AnimationLayer. Each layers holds references // to various AnimationCurveNodes and is referenced by an AnimationStack node // note: theoretically a stack can have multiple layers, however in practice there always seems to be one per stack - - parseAnimationLayers( curveNodesMap ) { const rawLayers = fbxTree.Objects.AnimationLayer; const layersMap = new Map(); - for ( const nodeID in rawLayers ) { const layerCurveNodes = []; const connection = connections.get( parseInt( nodeID ) ); - if ( connection !== undefined ) { // all the animationCurveNodes used in the layer @@ -2261,8 +2183,9 @@ if ( curveNodesMap.has( child.ID ) ) { - const curveNode = curveNodesMap.get( child.ID ); // check that the curves are defined for at least one axis, otherwise ignore the curveNode + const curveNode = curveNodesMap.get( child.ID ); + // check that the curves are defined for at least one axis, otherwise ignore the curveNode if ( curveNode.curves.x !== undefined || curveNode.curves.y !== undefined || curveNode.curves.z !== undefined ) { if ( layerCurveNodes[ i ] === undefined ) { @@ -2272,11 +2195,9 @@ return parent.relationship !== undefined; } )[ 0 ].ID; - if ( modelID !== undefined ) { const rawModel = fbxTree.Objects.Model[ modelID.toString() ]; - if ( rawModel === undefined ) { console.warn( 'THREE.FBXLoader: Encountered a unused curve.', child ); @@ -2301,9 +2222,10 @@ } } ); - if ( ! node.transform ) node.transform = new THREE.Matrix4(); // if the animated model is pre rotated, we'll have to apply the pre rotations to every - // animation value as well + if ( ! node.transform ) node.transform = new THREE.Matrix4(); + // if the animated model is pre rotated, we'll have to apply the pre rotations to every + // animation value as well if ( 'PreRotation' in rawModel ) node.preRotation = rawModel.PreRotation.value; if ( 'PostRotation' in rawModel ) node.postRotation = rawModel.PostRotation.value; layerCurveNodes[ i ] = node; @@ -2324,8 +2246,9 @@ } )[ 0 ].ID; const morpherID = connections.get( deformerID ).parents[ 0 ].ID; - const geoID = connections.get( morpherID ).parents[ 0 ].ID; // assuming geometry is not used in more than one model + const geoID = connections.get( morpherID ).parents[ 0 ].ID; + // assuming geometry is not used in more than one model const modelID = connections.get( geoID ).parents[ 0 ].ID; const rawModel = fbxTree.Objects.Model[ modelID ]; const node = { @@ -2351,20 +2274,19 @@ return layersMap; - } // parse nodes in FBXTree.Objects.AnimationStack. These are the top level node in the animation - // hierarchy. Each Stack node will be used to create a THREE.AnimationClip - + } + // parse nodes in FBXTree.Objects.AnimationStack. These are the top level node in the animation + // hierarchy. Each Stack node will be used to create a THREE.AnimationClip parseAnimStacks( layersMap ) { - const rawStacks = fbxTree.Objects.AnimationStack; // connect the stacks (clips) up to the layers + const rawStacks = fbxTree.Objects.AnimationStack; + // connect the stacks (clips) up to the layers const rawClips = {}; - for ( const nodeID in rawStacks ) { const children = connections.get( parseInt( nodeID ) ).children; - if ( children.length > 1 ) { // it seems like stacks will always be associated with a single layer. But just in case there are files @@ -2384,7 +2306,6 @@ return rawClips; } - addClip( rawClip ) { let tracks = []; @@ -2397,7 +2318,6 @@ return new THREE.AnimationClip( rawClip.name, - 1, tracks ); } - generateTracks( rawTracks ) { const tracks = []; @@ -2408,7 +2328,6 @@ initialPosition = initialPosition.toArray(); initialRotation = new THREE.Euler().setFromQuaternion( initialRotation, rawTracks.eulerOrder ).toArray(); initialScale = initialScale.toArray(); - if ( rawTracks.T !== undefined && Object.keys( rawTracks.T.curves ).length > 0 ) { const positionTrack = this.generateVectorTrack( rawTracks.modelName, rawTracks.T.curves, initialPosition, 'position' ); @@ -2440,7 +2359,6 @@ return tracks; } - generateVectorTrack( modelName, curves, initialValue, type ) { const times = this.getTimesForAllAxes( curves ); @@ -2448,7 +2366,6 @@ return new THREE.VectorKeyframeTrack( modelName + '.' + type, times, values ); } - generateRotationTrack( modelName, curves, initialValue, preRotation, postRotation, eulerOrder ) { if ( curves.x !== undefined ) { @@ -2474,7 +2391,6 @@ const times = this.getTimesForAllAxes( curves ); const values = this.getKeyframeTrackValues( times, curves, initialValue ); - if ( preRotation !== undefined ) { preRotation = preRotation.map( THREE.MathUtils.degToRad ); @@ -2496,7 +2412,6 @@ const quaternion = new THREE.Quaternion(); const euler = new THREE.Euler(); const quaternionValues = []; - for ( let i = 0; i < values.length; i += 3 ) { euler.set( values[ i ], values[ i + 1 ], values[ i + 2 ], eulerOrder ); @@ -2510,7 +2425,6 @@ return new THREE.QuaternionKeyframeTrack( modelName + '.quaternion', times, quaternionValues ); } - generateMorphTrack( rawTracks ) { const curves = rawTracks.DeformPercent.curves.morph; @@ -2522,33 +2436,34 @@ const morphNum = sceneGraph.getObjectByName( rawTracks.modelName ).morphTargetDictionary[ rawTracks.morphName ]; return new THREE.NumberKeyframeTrack( rawTracks.modelName + '.morphTargetInfluences[' + morphNum + ']', curves.times, values ); - } // For all animated objects, times are defined separately for each axis - // Here we'll combine the times into one sorted array without duplicates - + } + // For all animated objects, times are defined separately for each axis + // Here we'll combine the times into one sorted array without duplicates getTimesForAllAxes( curves ) { - let times = []; // first join together the times for each axis, if defined + let times = []; + // first join together the times for each axis, if defined if ( curves.x !== undefined ) times = times.concat( curves.x.times ); if ( curves.y !== undefined ) times = times.concat( curves.y.times ); - if ( curves.z !== undefined ) times = times.concat( curves.z.times ); // then sort them + if ( curves.z !== undefined ) times = times.concat( curves.z.times ); + // then sort them times = times.sort( function ( a, b ) { return a - b; - } ); // and remove duplicates + } ); + // and remove duplicates if ( times.length > 1 ) { let targetIndex = 1; let lastValue = times[ 0 ]; - for ( let i = 1; i < times.length; i ++ ) { const currentValue = times[ i ]; - if ( currentValue !== lastValue ) { times[ targetIndex ] = currentValue; @@ -2566,7 +2481,6 @@ return times; } - getKeyframeTrackValues( times, curves, initialValue ) { const prevValue = initialValue; @@ -2578,8 +2492,9 @@ if ( curves.x ) xIndex = curves.x.times.indexOf( time ); if ( curves.y ) yIndex = curves.y.times.indexOf( time ); - if ( curves.z ) zIndex = curves.z.times.indexOf( time ); // if there is an x value defined for this frame, use that + if ( curves.z ) zIndex = curves.z.times.indexOf( time ); + // if there is an x value defined for this frame, use that if ( xIndex !== - 1 ) { const xValue = curves.x.values[ xIndex ]; @@ -2620,11 +2535,11 @@ } ); return values; - } // Rotations are defined as THREE.Euler angles which can have values of any size + } + + // Rotations are defined as THREE.Euler angles which can have values of any size // These will be converted to quaternions which don't support values greater than // PI, so we'll interpolate large rotations - - interpolateRotations( curve ) { for ( let i = 1; i < curve.values.length; i ++ ) { @@ -2632,7 +2547,6 @@ const initialValue = curve.values[ i - 1 ]; const valuesSpan = curve.values[ i ] - initialValue; const absoluteSpan = Math.abs( valuesSpan ); - if ( absoluteSpan >= 180 ) { const numSubIntervals = absoluteSpan / 180; @@ -2644,7 +2558,6 @@ let nextTime = initialTime + interval; const interpolatedTimes = []; const interpolatedValues = []; - while ( nextTime < curve.times[ i ] ) { interpolatedTimes.push( nextTime ); @@ -2663,9 +2576,9 @@ } - } // parse an FBX file in ASCII format - + } + // parse an FBX file in ASCII format class TextParser { getPrevNode() { @@ -2673,40 +2586,34 @@ return this.nodeStack[ this.currentIndent - 2 ]; } - getCurrentNode() { return this.nodeStack[ this.currentIndent - 1 ]; } - getCurrentProp() { return this.currentProp; } - pushStack( node ) { this.nodeStack.push( node ); this.currentIndent += 1; } - popStack() { this.nodeStack.pop(); this.currentIndent -= 1; } - setCurrentProp( val, name ) { this.currentProp = val; this.currentPropName = name; } - parse( text ) { this.currentIndent = 0; @@ -2724,7 +2631,6 @@ const matchBeginning = line.match( '^\\t{' + scope.currentIndent + '}(\\w+):(.*){', '' ); const matchProperty = line.match( '^\\t{' + scope.currentIndent + '}(\\w+):[\\s\\t\\r\\n](.*)' ); const matchEnd = line.match( '^\\t{' + ( scope.currentIndent - 1 ) + '}}' ); - if ( matchBeginning ) { scope.parseNodeBegin( line, matchBeginning ); @@ -2749,7 +2655,6 @@ return this.allNodes; } - parseNodeBegin( line, property ) { const nodeName = property[ 1 ].trim().replace( /^"/, '' ).replace( /"$/, '' ); @@ -2762,8 +2667,9 @@ name: nodeName }; const attrs = this.parseNodeAttr( nodeAttrs ); - const currentNode = this.getCurrentNode(); // a top node + const currentNode = this.getCurrentNode(); + // a top node if ( this.currentIndent === 0 ) { this.allNodes.add( nodeName, node ); @@ -2771,6 +2677,7 @@ } else { // a subnode + // if the subnode already exists, append it if ( nodeName in currentNode ) { @@ -2807,15 +2714,12 @@ this.pushStack( node ); } - parseNodeAttr( attrs ) { let id = attrs[ 0 ]; - if ( attrs[ 0 ] !== '' ) { id = parseInt( attrs[ 0 ] ); - if ( isNaN( id ) ) { id = attrs[ 0 ]; @@ -2826,7 +2730,6 @@ let name = '', type = ''; - if ( attrs.length > 1 ) { name = attrs[ 1 ].replace( /^(\w+)::/, '' ); @@ -2841,14 +2744,14 @@ }; } - parseNodeProperty( line, property, contentLine ) { let propName = property[ 1 ].replace( /^"/, '' ).replace( /"$/, '' ).trim(); - let propValue = property[ 2 ].replace( /^"/, '' ).replace( /"$/, '' ).trim(); // for special case: base64 image data follows "Content: ," line + let propValue = property[ 2 ].replace( /^"/, '' ).replace( /"$/, '' ).trim(); + + // for special case: base64 image data follows "Content: ," line // Content: , // "/9j/4RDaRXhpZgAATU0A..." - if ( propName === 'Content' && propValue === ',' ) { propValue = contentLine.replace( /"/g, '' ).replace( /,$/, '' ).trim(); @@ -2857,15 +2760,14 @@ const currentNode = this.getCurrentNode(); const parentName = currentNode.name; - if ( parentName === 'Properties70' ) { this.parseNodeSpecialProperty( line, propName, propValue ); return; - } // Connections - + } + // Connections if ( propName === 'C' ) { const connProps = propValue.split( ',' ).slice( 1 ); @@ -2880,18 +2782,18 @@ propName = 'connections'; propValue = [ from, to ]; append( propValue, rest ); - if ( currentNode[ propName ] === undefined ) { currentNode[ propName ] = []; } - } // Node - + } - if ( propName === 'Node' ) currentNode.id = propValue; // connections + // Node + if ( propName === 'Node' ) currentNode.id = propValue; + // connections if ( propName in currentNode && Array.isArray( currentNode[ propName ] ) ) { currentNode[ propName ].push( propValue ); @@ -2902,8 +2804,9 @@ } - this.setCurrentProp( currentNode, propName ); // convert string to array, unless it ends in ',' in which case more will be added to it + this.setCurrentProp( currentNode, propName ); + // convert string to array, unless it ends in ',' in which case more will be added to it if ( propName === 'a' && propValue.slice( - 1 ) !== ',' ) { currentNode.a = parseNumberArray( propValue ); @@ -2911,22 +2814,22 @@ } } - parseNodePropertyContinued( line ) { const currentNode = this.getCurrentNode(); - currentNode.a += line; // if the line doesn't end in ',' we have reached the end of the property value - // so convert the string to an array + currentNode.a += line; + // if the line doesn't end in ',' we have reached the end of the property value + // so convert the string to an array if ( line.slice( - 1 ) !== ',' ) { currentNode.a = parseNumberArray( currentNode.a ); } - } // parse "Property70" - + } + // parse "Property70" parseNodeSpecialProperty( line, propName, propValue ) { // split this @@ -2942,8 +2845,9 @@ const innerPropType1 = props[ 1 ]; const innerPropType2 = props[ 2 ]; const innerPropFlag = props[ 3 ]; - let innerPropValue = props[ 4 ]; // cast values where needed, otherwise leave as strings + let innerPropValue = props[ 4 ]; + // cast values where needed, otherwise leave as strings switch ( innerPropType1 ) { case 'int': @@ -2955,7 +2859,6 @@ case 'FieldOfView': innerPropValue = parseFloat( innerPropValue ); break; - case 'Color': case 'ColorRGB': case 'Vector3D': @@ -2965,9 +2868,9 @@ innerPropValue = parseNumberArray( innerPropValue ); break; - } // CAUTION: these props must append to parent's parent - + } + // CAUTION: these props must append to parent's parent this.getPrevNode()[ innerPropName ] = { 'type': innerPropType1, 'type2': innerPropType2, @@ -2978,9 +2881,9 @@ } - } // Parse an FBX file in Binary format - + } + // Parse an FBX file in Binary format class BinaryParser { parse( buffer ) { @@ -2989,7 +2892,6 @@ reader.skip( 23 ); // skip magic 23 bytes const version = reader.getUint32(); - if ( version < 6400 ) { throw new Error( 'THREE.FBXLoader: FBX version not supported, FileVersion: ' + version ); @@ -2997,7 +2899,6 @@ } const allNodes = new FBXTree(); - while ( ! this.endOfContent( reader ) ) { const node = this.parseNode( reader, version ); @@ -3007,9 +2908,9 @@ return allNodes; - } // Check if reader has reached the end of content. - + } + // Check if reader has reached the end of content. endOfContent( reader ) { // footer size: 160bytes + 16-byte alignment padding @@ -3030,37 +2931,38 @@ } - } // recursively parse nodes until the end of the file is reached - + } + // recursively parse nodes until the end of the file is reached parseNode( reader, version ) { - const node = {}; // The first three data sizes depends on version. + const node = {}; + // The first three data sizes depends on version. const endOffset = version >= 7500 ? reader.getUint64() : reader.getUint32(); const numProperties = version >= 7500 ? reader.getUint64() : reader.getUint32(); version >= 7500 ? reader.getUint64() : reader.getUint32(); // the returned propertyListLen is not used const nameLen = reader.getUint8(); - const name = reader.getString( nameLen ); // Regards this node as NULL-record if endOffset is zero + const name = reader.getString( nameLen ); + // Regards this node as NULL-record if endOffset is zero if ( endOffset === 0 ) return null; const propertyList = []; - for ( let i = 0; i < numProperties; i ++ ) { propertyList.push( this.parseProperty( reader ) ); - } // Regards the first three elements in propertyList as id, attrName, and attrType - + } + // Regards the first three elements in propertyList as id, attrName, and attrType const id = propertyList.length > 0 ? propertyList[ 0 ] : ''; const attrName = propertyList.length > 1 ? propertyList[ 1 ] : ''; - const attrType = propertyList.length > 2 ? propertyList[ 2 ] : ''; // check if this node represents just a single property - // like (name, 0) set or (name2, [0, 1, 2]) set of {name: 0, name2: [0, 1, 2]} + const attrType = propertyList.length > 2 ? propertyList[ 2 ] : ''; + // check if this node represents just a single property + // like (name, 0) set or (name2, [0, 1, 2]) set of {name: 0, name2: [0, 1, 2]} node.singleProperty = numProperties === 1 && reader.getOffset() === endOffset ? true : false; - while ( endOffset > reader.getOffset() ) { const subNode = this.parseNode( reader, version ); @@ -3077,14 +2979,12 @@ return node; } - parseSubNode( name, node, subNode ) { // special case: child node is single property if ( subNode.singleProperty === true ) { const value = subNode.propertyList[ 0 ]; - if ( Array.isArray( value ) ) { node[ subNode.name ] = subNode; @@ -3105,7 +3005,6 @@ if ( i !== 0 ) array.push( property ); } ); - if ( node.connections === undefined ) { node.connections = []; @@ -3132,7 +3031,6 @@ let innerPropValue; if ( innerPropName.indexOf( 'Lcl ' ) === 0 ) innerPropName = innerPropName.replace( 'Lcl ', 'Lcl_' ); if ( innerPropType1.indexOf( 'Lcl ' ) === 0 ) innerPropType1 = innerPropType1.replace( 'Lcl ', 'Lcl_' ); - if ( innerPropType1 === 'Color' || innerPropType1 === 'ColorRGB' || innerPropType1 === 'Vector' || innerPropType1 === 'Vector3D' || innerPropType1.indexOf( 'Lcl_' ) === 0 ) { innerPropValue = [ subNode.propertyList[ 4 ], subNode.propertyList[ 5 ], subNode.propertyList[ 6 ] ]; @@ -3141,9 +3039,9 @@ innerPropValue = subNode.propertyList[ 4 ]; - } // this will be copied to parent, see above - + } + // this will be copied to parent, see above node[ innerPropName ] = { 'type': innerPropType1, 'type2': innerPropType2, @@ -3185,40 +3083,30 @@ } } - parseProperty( reader ) { const type = reader.getString( 1 ); let length; - switch ( type ) { case 'C': return reader.getBoolean(); - case 'D': return reader.getFloat64(); - case 'F': return reader.getFloat32(); - case 'I': return reader.getInt32(); - case 'L': return reader.getInt64(); - case 'R': length = reader.getUint32(); return reader.getArrayBuffer( length ); - case 'S': length = reader.getUint32(); return reader.getString( length ); - case 'Y': return reader.getInt16(); - case 'b': case 'c': case 'd': @@ -3227,9 +3115,7 @@ case 'l': const arrayLength = reader.getUint32(); const encoding = reader.getUint32(); // 0: non-compressed, 1: compressed - const compressedLength = reader.getUint32(); - if ( encoding === 0 ) { switch ( type ) { @@ -3237,16 +3123,12 @@ case 'b': case 'c': return reader.getBooleanArray( arrayLength ); - case 'd': return reader.getFloat64Array( arrayLength ); - case 'f': return reader.getFloat32Array( arrayLength ); - case 'i': return reader.getInt32Array( arrayLength ); - case 'l': return reader.getInt64Array( arrayLength ); @@ -3261,24 +3143,18 @@ } const data = fflate.unzlibSync( new Uint8Array( reader.getArrayBuffer( compressedLength ) ) ); // eslint-disable-line no-undef - const reader2 = new BinaryReader( data.buffer ); - switch ( type ) { case 'b': case 'c': return reader2.getBooleanArray( arrayLength ); - case 'd': return reader2.getFloat64Array( arrayLength ); - case 'f': return reader2.getFloat32Array( arrayLength ); - case 'i': return reader2.getInt32Array( arrayLength ); - case 'l': return reader2.getInt64Array( arrayLength ); @@ -3295,7 +3171,6 @@ } } - class BinaryReader { constructor( buffer, littleEndian ) { @@ -3305,38 +3180,33 @@ this.littleEndian = littleEndian !== undefined ? littleEndian : true; } - getOffset() { return this.offset; } - size() { return this.dv.buffer.byteLength; } - skip( length ) { this.offset += length; - } // seems like true/false representation depends on exporter. + } + + // seems like true/false representation depends on exporter. // true: 1 or 'Y'(=0x59), false: 0 or 'T'(=0x54) // then sees LSB. - - getBoolean() { return ( this.getUint8() & 1 ) === 1; } - getBooleanArray( size ) { const a = []; - for ( let i = 0; i < size; i ++ ) { a.push( this.getBoolean() ); @@ -3346,7 +3216,6 @@ return a; } - getUint8() { const value = this.dv.getUint8( this.offset ); @@ -3354,7 +3223,6 @@ return value; } - getInt16() { const value = this.dv.getInt16( this.offset, this.littleEndian ); @@ -3362,7 +3230,6 @@ return value; } - getInt32() { const value = this.dv.getInt32( this.offset, this.littleEndian ); @@ -3370,11 +3237,9 @@ return value; } - getInt32Array( size ) { const a = []; - for ( let i = 0; i < size; i ++ ) { a.push( this.getInt32() ); @@ -3384,24 +3249,22 @@ return a; } - getUint32() { const value = this.dv.getUint32( this.offset, this.littleEndian ); this.offset += 4; return value; - } // JavaScript doesn't support 64-bit integer so calculate this here + } + + // JavaScript doesn't support 64-bit integer so calculate this here // 1 << 32 will return 1 so using multiply operation instead here. // There's a possibility that this method returns wrong value if the value // is out of the range between Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER. // TODO: safely handle 64-bit integer - - getInt64() { let low, high; - if ( this.littleEndian ) { low = this.getUint32(); @@ -3412,9 +3275,9 @@ high = this.getUint32(); low = this.getUint32(); - } // calculate negative value - + } + // calculate negative value if ( high & 0x80000000 ) { high = ~ high & 0xFFFFFFFF; @@ -3428,11 +3291,9 @@ return high * 0x100000000 + low; } - getInt64Array( size ) { const a = []; - for ( let i = 0; i < size; i ++ ) { a.push( this.getInt64() ); @@ -3441,13 +3302,12 @@ return a; - } // Note: see getInt64() comment - + } + // Note: see getInt64() comment getUint64() { let low, high; - if ( this.littleEndian ) { low = this.getUint32(); @@ -3463,7 +3323,6 @@ return high * 0x100000000 + low; } - getFloat32() { const value = this.dv.getFloat32( this.offset, this.littleEndian ); @@ -3471,11 +3330,9 @@ return value; } - getFloat32Array( size ) { const a = []; - for ( let i = 0; i < size; i ++ ) { a.push( this.getFloat32() ); @@ -3485,7 +3342,6 @@ return a; } - getFloat64() { const value = this.dv.getFloat64( this.offset, this.littleEndian ); @@ -3493,11 +3349,9 @@ return value; } - getFloat64Array( size ) { const a = []; - for ( let i = 0; i < size; i ++ ) { a.push( this.getFloat64() ); @@ -3507,7 +3361,6 @@ return a; } - getArrayBuffer( size ) { const value = this.dv.buffer.slice( this.offset, this.offset + size ); @@ -3515,12 +3368,10 @@ return value; } - getString( size ) { // note: safari 9 doesn't support Uint8Array.indexOf; create intermediate array instead let a = []; - for ( let i = 0; i < size; i ++ ) { a[ i ] = this.getUint8(); @@ -3533,10 +3384,10 @@ } - } // FBXTree holds a representation of the FBX data, returned by the TextParser ( FBX ASCII format) - // and BinaryParser( FBX Binary format) - + } + // FBXTree holds a representation of the FBX data, returned by the TextParser ( FBX ASCII format) + // and BinaryParser( FBX Binary format) class FBXTree { add( key, val ) { @@ -3545,8 +3396,9 @@ } - } // ************** UTILITY FUNCTIONS ************** + } + // ************** UTILITY FUNCTIONS ************** function isFbxFormatBinary( buffer ) { @@ -3559,7 +3411,6 @@ const CORRECT = [ 'K', 'a', 'y', 'd', 'a', 'r', 'a', '\\', 'F', 'B', 'X', '\\', 'B', 'i', 'n', 'a', 'r', 'y', '\\', '\\' ]; let cursor = 0; - function read( offset ) { const result = text[ offset - 1 ]; @@ -3572,7 +3423,6 @@ for ( let i = 0; i < CORRECT.length; ++ i ) { const num = read( 1 ); - if ( num === CORRECT[ i ] ) { return false; @@ -3589,7 +3439,6 @@ const versionRegExp = /FBXVersion: (\d+)/; const match = text.match( versionRegExp ); - if ( match ) { const version = parseInt( match[ 1 ] ); @@ -3599,39 +3448,35 @@ throw new Error( 'THREE.FBXLoader: Cannot find the version number for the file given.' ); - } // Converts FBX ticks into real time seconds. - + } + // Converts FBX ticks into real time seconds. function convertFBXTimeToSeconds( time ) { return time / 46186158000; } - const dataArray = []; // extracts the data from the correct position in the FBX array based on indexing type + const dataArray = []; + // extracts the data from the correct position in the FBX array based on indexing type function getData( polygonVertexIndex, polygonIndex, vertexIndex, infoObject ) { let index; - switch ( infoObject.mappingType ) { case 'ByPolygonVertex': index = polygonVertexIndex; break; - case 'ByPolygon': index = polygonIndex; break; - case 'ByVertice': index = vertexIndex; break; - case 'AllSame': index = infoObject.indices[ 0 ]; break; - default: console.warn( 'THREE.FBXLoader: unknown attribute mapping type ' + infoObject.mappingType ); @@ -3645,10 +3490,11 @@ } const tempEuler = new THREE.Euler(); - const tempVec = new THREE.Vector3(); // generate transformation from FBX transform data + const tempVec = new THREE.Vector3(); + + // generate transformation from FBX transform data // ref: https://help.autodesk.com/view/FBX/2017/ENU/?guid=__files_GUID_10CDD63C_79C1_4F2D_BB28_AD2BE65A02ED_htm // ref: http://docs.autodesk.com/FBX/2014/ENU/FBX-SDK-Documentation/index.html?url=cpp_ref/_transformations_2main_8cxx-example.html,topicNumber=cpp_ref__transformations_2main_8cxx_example_htmlfc10a1e1-b18d-4e72-9dc0-70d0f1959f5e - function generateTransform( transformData ) { const lTranslationM = new THREE.Matrix4(); @@ -3665,11 +3511,10 @@ const lGlobalT = new THREE.Matrix4(); const inheritType = transformData.inheritType ? transformData.inheritType : 0; if ( transformData.translation ) lTranslationM.setPosition( tempVec.fromArray( transformData.translation ) ); - if ( transformData.preRotation ) { const array = transformData.preRotation.map( THREE.MathUtils.degToRad ); - array.push( transformData.eulerOrder ); + array.push( transformData.eulerOrder || THREE.Euler.DefaultOrder ); lPreRotationM.makeRotationFromEuler( tempEuler.fromArray( array ) ); } @@ -3677,7 +3522,7 @@ if ( transformData.rotation ) { const array = transformData.rotation.map( THREE.MathUtils.degToRad ); - array.push( transformData.eulerOrder ); + array.push( transformData.eulerOrder || THREE.Euler.DefaultOrder ); lRotationM.makeRotationFromEuler( tempEuler.fromArray( array ) ); } @@ -3685,19 +3530,21 @@ if ( transformData.postRotation ) { const array = transformData.postRotation.map( THREE.MathUtils.degToRad ); - array.push( transformData.eulerOrder ); + array.push( transformData.eulerOrder || THREE.Euler.DefaultOrder ); lPostRotationM.makeRotationFromEuler( tempEuler.fromArray( array ) ); lPostRotationM.invert(); } - if ( transformData.scale ) lScalingM.scale( tempVec.fromArray( transformData.scale ) ); // Pivots and offsets + if ( transformData.scale ) lScalingM.scale( tempVec.fromArray( transformData.scale ) ); + // Pivots and offsets if ( transformData.scalingOffset ) lScalingOffsetM.setPosition( tempVec.fromArray( transformData.scalingOffset ) ); if ( transformData.scalingPivot ) lScalingPivotM.setPosition( tempVec.fromArray( transformData.scalingPivot ) ); if ( transformData.rotationOffset ) lRotationOffsetM.setPosition( tempVec.fromArray( transformData.rotationOffset ) ); - if ( transformData.rotationPivot ) lRotationPivotM.setPosition( tempVec.fromArray( transformData.rotationPivot ) ); // parent transform + if ( transformData.rotationPivot ) lRotationPivotM.setPosition( tempVec.fromArray( transformData.rotationPivot ) ); + // parent transform if ( transformData.parentMatrixWorld ) { lParentLX.copy( transformData.parentMatrix ); @@ -3705,18 +3552,18 @@ } - const lLRM = lPreRotationM.clone().multiply( lRotationM ).multiply( lPostRotationM ); // Global Rotation - + const lLRM = lPreRotationM.clone().multiply( lRotationM ).multiply( lPostRotationM ); + // Global Rotation const lParentGRM = new THREE.Matrix4(); - lParentGRM.extractRotation( lParentGX ); // Global Shear*Scaling + lParentGRM.extractRotation( lParentGX ); + // Global Shear*Scaling const lParentTM = new THREE.Matrix4(); lParentTM.copyPosition( lParentGX ); const lParentGRSM = lParentTM.clone().invert().multiply( lParentGX ); const lParentGSM = lParentGRM.clone().invert().multiply( lParentGRSM ); const lLSM = lScalingM; const lGlobalRS = new THREE.Matrix4(); - if ( inheritType === 0 ) { lGlobalRS.copy( lParentGRM ).multiply( lLRM ).multiply( lParentGSM ).multiply( lLSM ); @@ -3735,29 +3582,35 @@ } const lRotationPivotM_inv = lRotationPivotM.clone().invert(); - const lScalingPivotM_inv = lScalingPivotM.clone().invert(); // Calculate the local transform matrix - + const lScalingPivotM_inv = lScalingPivotM.clone().invert(); + // Calculate the local transform matrix let lTransform = lTranslationM.clone().multiply( lRotationOffsetM ).multiply( lRotationPivotM ).multiply( lPreRotationM ).multiply( lRotationM ).multiply( lPostRotationM ).multiply( lRotationPivotM_inv ).multiply( lScalingOffsetM ).multiply( lScalingPivotM ).multiply( lScalingM ).multiply( lScalingPivotM_inv ); const lLocalTWithAllPivotAndOffsetInfo = new THREE.Matrix4().copyPosition( lTransform ); const lGlobalTranslation = lParentGX.clone().multiply( lLocalTWithAllPivotAndOffsetInfo ); lGlobalT.copyPosition( lGlobalTranslation ); - lTransform = lGlobalT.clone().multiply( lGlobalRS ); // from global to local + lTransform = lGlobalT.clone().multiply( lGlobalRS ); + // from global to local lTransform.premultiply( lParentGX.invert() ); return lTransform; - } // Returns the three.js intrinsic THREE.Euler order corresponding to FBX extrinsic THREE.Euler order - // ref: http://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref_class_fbx_euler_html - + } + // Returns the three.js intrinsic THREE.Euler order corresponding to FBX extrinsic THREE.Euler order + // ref: http://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref_class_fbx_euler_html function getEulerOrder( order ) { order = order || 0; - const enums = [ 'ZYX', // -> XYZ extrinsic - 'YZX', // -> XZY extrinsic - 'XZY', // -> YZX extrinsic - 'ZXY', // -> YXZ extrinsic - 'YXZ', // -> ZXY extrinsic + const enums = [ 'ZYX', + // -> XYZ extrinsic + 'YZX', + // -> XZY extrinsic + 'XZY', + // -> YZX extrinsic + 'ZXY', + // -> YXZ extrinsic + 'YXZ', + // -> ZXY extrinsic 'XYZ' // -> ZYX extrinsic //'SphericXYZ', // not possible to support ]; @@ -3771,10 +3624,10 @@ return enums[ order ]; - } // Parses comma separated list of numbers and returns them an array. - // Used internally by the TextParser - + } + // Parses comma separated list of numbers and returns them an array. + // Used internally by the TextParser function parseNumberArray( value ) { const array = value.split( ',' ).map( function ( val ) { @@ -3814,9 +3667,9 @@ return a; - } // inject array a2 into array a1 at index - + } + // inject array a2 into array a1 at index function inject( a1, index, a2 ) { return a1.slice( 0, index ).concat( a2 ).concat( a1.slice( index ) ); diff --git a/examples/js/loaders/FontLoader.js b/examples/js/loaders/FontLoader.js index c24d688f82261f..d7723e96b26185 100644 --- a/examples/js/loaders/FontLoader.js +++ b/examples/js/loaders/FontLoader.js @@ -7,44 +7,30 @@ super( manager ); } - load( url, onLoad, onProgress, onError ) { const scope = this; const loader = new THREE.FileLoader( this.manager ); loader.setPath( this.path ); loader.setRequestHeader( this.requestHeader ); - loader.setWithCredentials( scope.withCredentials ); + loader.setWithCredentials( this.withCredentials ); loader.load( url, function ( text ) { - let 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 ) ); - - } - - const font = scope.parse( json ); + const font = scope.parse( JSON.parse( text ) ); if ( onLoad ) onLoad( font ); }, onProgress, onError ); } - parse( json ) { return new Font( json ); } - } // + } + // class Font { @@ -55,12 +41,10 @@ this.data = data; } - generateShapes( text, size = 100 ) { const shapes = []; const paths = createPaths( text, size, this.data ); - for ( let p = 0, pl = paths.length; p < pl; p ++ ) { shapes.push( ...paths[ p ].toShapes() ); @@ -72,7 +56,6 @@ } } - function createPaths( text, size, data ) { const chars = Array.from( text ); @@ -81,11 +64,9 @@ const paths = []; let offsetX = 0, offsetY = 0; - for ( let i = 0; i < chars.length; i ++ ) { const char = chars[ i ]; - if ( char === '\n' ) { offsetX = 0; @@ -108,7 +89,6 @@ function createPath( char, scale, offsetX, offsetY, data ) { const glyph = data.glyphs[ char ] || data.glyphs[ '?' ]; - if ( ! glyph ) { console.error( 'THREE.Font: character "' + char + '" does not exists in font family ' + data.familyName + '.' ); @@ -118,42 +98,40 @@ const path = new THREE.ShapePath(); let x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2; - if ( glyph.o ) { const outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) ); - for ( let i = 0, l = outline.length; i < l; ) { const action = outline[ i ++ ]; - switch ( action ) { case 'm': // moveTo + x = outline[ i ++ ] * scale + offsetX; y = outline[ i ++ ] * scale + offsetY; path.moveTo( x, y ); break; - case 'l': // lineTo + x = outline[ i ++ ] * scale + offsetX; y = outline[ i ++ ] * scale + offsetY; path.lineTo( x, y ); break; - 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; - case 'b': // bezierCurveTo + cpx = outline[ i ++ ] * scale + offsetX; cpy = outline[ i ++ ] * scale + offsetY; cpx1 = outline[ i ++ ] * scale + offsetX; diff --git a/examples/js/loaders/GCodeLoader.js b/examples/js/loaders/GCodeLoader.js index 82f2fc2485da48..9f6d723f3e5c2b 100644 --- a/examples/js/loaders/GCodeLoader.js +++ b/examples/js/loaders/GCodeLoader.js @@ -17,7 +17,6 @@ this.splitLayer = false; } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -50,7 +49,6 @@ }, onProgress, onError ); } - parse( data ) { let state = { @@ -72,7 +70,6 @@ color: 0x00FF00 } ); extrudingMaterial.name = 'extruded'; - function newLayer( line ) { currentLayer = { @@ -82,9 +79,9 @@ }; layers.push( currentLayer ); - } //Create lie segment between p1 and p2 - + } + //Create lie segment between p1 and p2 function addSegment( p1, p2 ) { if ( currentLayer === undefined ) { @@ -120,12 +117,12 @@ } const lines = data.replace( /;.+/g, '' ).split( '\n' ); - for ( let i = 0; i < lines.length; i ++ ) { const tokens = lines[ i ].split( ' ' ); - const cmd = tokens[ 0 ].toUpperCase(); //Argumments + const cmd = tokens[ 0 ].toUpperCase(); + //Argumments const args = {}; tokens.splice( 1 ).forEach( function ( token ) { @@ -137,9 +134,10 @@ } - } ); //Process commands - //G0/G1 – Linear Movement + } ); + //Process commands + //G0/G1 – Linear Movement if ( cmd === 'G0' || cmd === 'G1' ) { const line = { @@ -148,12 +146,12 @@ z: args.z !== undefined ? absolute( state.z, args.z ) : state.z, e: args.e !== undefined ? absolute( state.e, args.e ) : state.e, f: args.f !== undefined ? absolute( state.f, args.f ) : state.f - }; //Layer change detection is or made by watching Z, it's made by watching when we extrude at a new Z position + }; + //Layer change detection is or made by watching Z, it's made by watching when we extrude at a new Z position if ( delta( state.e, line.e ) > 0 ) { state.extruding = delta( state.e, line.e ) > 0; - if ( currentLayer == undefined || line.z != currentLayer.z ) { newLayer( line ); @@ -165,7 +163,9 @@ addSegment( state, line ); state = line; - } else if ( cmd === 'G2' || cmd === 'G3' ) { //G2/G3 - Arc Movement ( G2 clock wise and G3 counter clock wise ) + } else if ( cmd === 'G2' || cmd === 'G3' ) { + + //G2/G3 - Arc Movement ( G2 clock wise and G3 counter clock wise ) //console.warn( 'THREE.GCodeLoader: Arc command not supported' ); } else if ( cmd === 'G90' ) { @@ -186,7 +186,9 @@ line.z = args.z !== undefined ? args.z : line.z; line.e = args.e !== undefined ? args.e : line.e; - } else { //console.warn( 'THREE.GCodeLoader: Command not supported:' + cmd ); + } else { + + //console.warn( 'THREE.GCodeLoader: Command not supported:' + cmd ); } } @@ -203,7 +205,6 @@ const object = new THREE.Group(); object.name = 'gcode'; - if ( this.splitLayer ) { for ( let i = 0; i < layers.length; i ++ ) { @@ -218,13 +219,11 @@ const vertex = [], pathVertex = []; - for ( let i = 0; i < layers.length; i ++ ) { const layer = layers[ i ]; const layerVertex = layer.vertex; const layerPathVertex = layer.pathVertex; - for ( let j = 0; j < layerVertex.length; j ++ ) { vertex.push( layerVertex[ j ] ); diff --git a/examples/js/loaders/GLTFLoader.js b/examples/js/loaders/GLTFLoader.js index c2063e0077f11e..c22cdf4c6d7f08 100644 --- a/examples/js/loaders/GLTFLoader.js +++ b/examples/js/loaders/GLTFLoader.js @@ -69,14 +69,17 @@ return new GLTFMeshoptCompression( parser ); } ); + this.register( function ( parser ) { - } + return new GLTFMeshGpuInstancing( parser ); + + } ); + } load( url, onLoad, onProgress, onError ) { const scope = this; let resourcePath; - if ( this.resourcePath !== '' ) { resourcePath = this.resourcePath; @@ -89,13 +92,12 @@ resourcePath = THREE.LoaderUtils.extractUrlBase( url ); - } // Tells the LoadingManager to track an extra item, which resolves after + } + + // Tells the LoadingManager to track an extra item, which resolves after // the model is fully loaded. This means the count of items loaded will // be incorrect, but ensures manager.onLoad() does not fire early. - - this.manager.itemStart( url ); - const _onError = function ( e ) { if ( onError ) { @@ -138,34 +140,29 @@ }, onProgress, _onError ); } - setDRACOLoader( dracoLoader ) { this.dracoLoader = dracoLoader; return this; } - setDDSLoader() { throw new Error( 'THREE.GLTFLoader: "MSFT_texture_dds" no longer supported. Please update to "KHR_texture_basisu".' ); } - setKTX2Loader( ktx2Loader ) { this.ktx2Loader = ktx2Loader; return this; } - setMeshoptDecoder( meshoptDecoder ) { this.meshoptDecoder = meshoptDecoder; return this; } - register( callback ) { if ( this.pluginCallbacks.indexOf( callback ) === - 1 ) { @@ -177,7 +174,6 @@ return this; } - unregister( callback ) { if ( this.pluginCallbacks.indexOf( callback ) !== - 1 ) { @@ -189,21 +185,18 @@ return this; } - parse( data, path, onLoad, onError ) { - let content; + let json; const extensions = {}; const plugins = {}; - if ( typeof data === 'string' ) { - content = data; + json = JSON.parse( data ); - } else { + } else if ( data instanceof ArrayBuffer ) { const magic = THREE.LoaderUtils.decodeText( new Uint8Array( data, 0, 4 ) ); - if ( magic === BINARY_EXTENSION_HEADER_MAGIC ) { try { @@ -217,17 +210,19 @@ } - content = extensions[ EXTENSIONS.KHR_BINARY_GLTF ].content; + json = JSON.parse( extensions[ EXTENSIONS.KHR_BINARY_GLTF ].content ); } else { - content = THREE.LoaderUtils.decodeText( new Uint8Array( data ) ); + json = JSON.parse( THREE.LoaderUtils.decodeText( new Uint8Array( data ) ) ); } - } + } else { - const json = JSON.parse( content ); + json = data; + + } if ( json.asset === undefined || json.asset.version[ 0 ] < 2 ) { @@ -245,15 +240,15 @@ meshoptDecoder: this.meshoptDecoder } ); parser.fileLoader.setRequestHeader( this.requestHeader ); - for ( let i = 0; i < this.pluginCallbacks.length; i ++ ) { const plugin = this.pluginCallbacks[ i ]( parser ); - plugins[ plugin.name ] = plugin; // Workaround to avoid determining as unknown extension + plugins[ plugin.name ] = plugin; + + // Workaround to avoid determining as unknown extension // in addUnknownExtensionsToUserData(). // Remove this workaround if we move all the existing // extension handlers to plugin system - extensions[ plugin.name ] = true; } @@ -264,29 +259,20 @@ const extensionName = json.extensionsUsed[ i ]; const extensionsRequired = json.extensionsRequired || []; - switch ( extensionName ) { case EXTENSIONS.KHR_MATERIALS_UNLIT: extensions[ extensionName ] = new GLTFMaterialsUnlitExtension(); break; - - case EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: - extensions[ extensionName ] = new GLTFMaterialsPbrSpecularGlossinessExtension(); - break; - case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION: extensions[ extensionName ] = new GLTFDracoMeshCompressionExtension( json, this.dracoLoader ); break; - case EXTENSIONS.KHR_TEXTURE_TRANSFORM: extensions[ extensionName ] = new GLTFTextureTransformExtension(); break; - case EXTENSIONS.KHR_MESH_QUANTIZATION: extensions[ extensionName ] = new GLTFMeshQuantizationExtension(); break; - default: if ( extensionsRequired.indexOf( extensionName ) >= 0 && plugins[ extensionName ] === undefined ) { @@ -305,7 +291,6 @@ parser.parse( onLoad, onError ); } - parseAsync( data, path ) { const scope = this; @@ -318,8 +303,8 @@ } } - /* GLTFREGISTRY */ + /* GLTFREGISTRY */ function GLTFRegistry() { @@ -348,20 +333,17 @@ }; } - /*********************************/ + /*********************************/ /********** EXTENSIONS ***********/ - /*********************************/ - const EXTENSIONS = { KHR_BINARY_GLTF: 'KHR_binary_glTF', KHR_DRACO_MESH_COMPRESSION: 'KHR_draco_mesh_compression', KHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual', KHR_MATERIALS_CLEARCOAT: 'KHR_materials_clearcoat', KHR_MATERIALS_IOR: 'KHR_materials_ior', - KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness', KHR_MATERIALS_SHEEN: 'KHR_materials_sheen', KHR_MATERIALS_SPECULAR: 'KHR_materials_specular', KHR_MATERIALS_TRANSMISSION: 'KHR_materials_transmission', @@ -373,37 +355,36 @@ KHR_MESH_QUANTIZATION: 'KHR_mesh_quantization', KHR_MATERIALS_EMISSIVE_STRENGTH: 'KHR_materials_emissive_strength', EXT_TEXTURE_WEBP: 'EXT_texture_webp', - EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression' + EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression', + EXT_MESH_GPU_INSTANCING: 'EXT_mesh_gpu_instancing' }; + /** * Punctual Lights Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual */ - class GLTFLightsExtension { constructor( parser ) { this.parser = parser; - this.name = EXTENSIONS.KHR_LIGHTS_PUNCTUAL; // THREE.Object3D instance caches + this.name = EXTENSIONS.KHR_LIGHTS_PUNCTUAL; + // THREE.Object3D instance caches this.cache = { refs: {}, uses: {} }; } - _markDefs() { const parser = this.parser; const nodeDefs = this.parser.json.nodes || []; - for ( let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex ++ ) { const nodeDef = nodeDefs[ nodeIndex ]; - if ( nodeDef.extensions && nodeDef.extensions[ this.name ] && nodeDef.extensions[ this.name ].light !== undefined ) { parser._addNodeRef( this.cache, nodeDef.extensions[ this.name ].light ); @@ -413,7 +394,6 @@ } } - _loadLight( lightIndex ) { const parser = this.parser; @@ -428,7 +408,6 @@ const color = new THREE.Color( 0xffffff ); if ( lightDef.color !== undefined ) color.fromArray( lightDef.color ); const range = lightDef.range !== undefined ? lightDef.range : 0; - switch ( lightDef.type ) { case 'directional': @@ -436,16 +415,14 @@ lightNode.target.position.set( 0, 0, - 1 ); lightNode.add( lightNode.target ); break; - case 'point': lightNode = new THREE.PointLight( color ); lightNode.distance = range; break; - case 'spot': lightNode = new THREE.SpotLight( color ); - lightNode.distance = range; // Handle spotlight properties. - + lightNode.distance = range; + // Handle spotlight properties. lightDef.spot = lightDef.spot || {}; lightDef.spot.innerConeAngle = lightDef.spot.innerConeAngle !== undefined ? lightDef.spot.innerConeAngle : 0; lightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== undefined ? lightDef.spot.outerConeAngle : Math.PI / 4.0; @@ -454,16 +431,16 @@ lightNode.target.position.set( 0, 0, - 1 ); lightNode.add( lightNode.target ); break; - default: throw new Error( 'THREE.GLTFLoader: Unexpected light type: ' + lightDef.type ); - } // Some lights (e.g. spot) default to a position other than the origin. Reset the position - // here, because node-level parsing will only override position if explicitly specified. - + } + // Some lights (e.g. spot) default to a position other than the origin. Reset the position + // here, because node-level parsing will only override position if explicitly specified. lightNode.position.set( 0, 0, 0 ); lightNode.decay = 2; + assignExtrasToUserData( lightNode, lightDef ); if ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity; lightNode.name = parser.createUniqueName( lightDef.name || 'light_' + lightIndex ); dependency = Promise.resolve( lightNode ); @@ -471,7 +448,12 @@ return dependency; } + getDependency( type, index ) { + + if ( type !== 'light' ) return; + return this._loadLight( index ); + } createNodeAttachment( nodeIndex ) { const self = this; @@ -490,13 +472,12 @@ } } + /** * Unlit Materials Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit */ - - class GLTFMaterialsUnlitExtension { constructor() { @@ -504,20 +485,17 @@ this.name = EXTENSIONS.KHR_MATERIALS_UNLIT; } - getMaterialType() { return THREE.MeshBasicMaterial; } - extendParams( materialParams, materialDef, parser ) { const pending = []; materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 ); materialParams.opacity = 1.0; const metallicRoughness = materialDef.pbrMetallicRoughness; - if ( metallicRoughness ) { if ( Array.isArray( metallicRoughness.baseColorFactor ) ) { @@ -541,13 +519,12 @@ } } + /** * Materials Emissive Strength Extension * * Specification: https://github.com/KhronosGroup/glTF/blob/5768b3ce0ef32bc39cdf1bef10b948586635ead3/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md */ - - class GLTFMaterialsEmissiveStrengthExtension { constructor( parser ) { @@ -556,12 +533,10 @@ this.name = EXTENSIONS.KHR_MATERIALS_EMISSIVE_STRENGTH; } - extendMaterialParams( materialIndex, materialParams ) { const parser = this.parser; const materialDef = parser.json.materials[ materialIndex ]; - if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) { return Promise.resolve(); @@ -569,7 +544,6 @@ } const emissiveStrength = materialDef.extensions[ this.name ].emissiveStrength; - if ( emissiveStrength !== undefined ) { materialParams.emissiveIntensity = emissiveStrength; @@ -581,13 +555,12 @@ } } + /** * Clearcoat Materials Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat */ - - class GLTFMaterialsClearcoatExtension { constructor( parser ) { @@ -596,7 +569,6 @@ this.name = EXTENSIONS.KHR_MATERIALS_CLEARCOAT; } - getMaterialType( materialIndex ) { const parser = this.parser; @@ -605,12 +577,10 @@ return THREE.MeshPhysicalMaterial; } - extendMaterialParams( materialIndex, materialParams ) { const parser = this.parser; const materialDef = parser.json.materials[ materialIndex ]; - if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) { return Promise.resolve(); @@ -619,7 +589,6 @@ const pending = []; const extension = materialDef.extensions[ this.name ]; - if ( extension.clearcoatFactor !== undefined ) { materialParams.clearcoat = extension.clearcoatFactor; @@ -647,7 +616,6 @@ if ( extension.clearcoatNormalTexture !== undefined ) { pending.push( parser.assignTexture( materialParams, 'clearcoatNormalMap', extension.clearcoatNormalTexture ) ); - if ( extension.clearcoatNormalTexture.scale !== undefined ) { const scale = extension.clearcoatNormalTexture.scale; @@ -662,13 +630,12 @@ } } + /** * Iridescence Materials Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_iridescence */ - - class GLTFMaterialsIridescenceExtension { constructor( parser ) { @@ -677,7 +644,6 @@ this.name = EXTENSIONS.KHR_MATERIALS_IRIDESCENCE; } - getMaterialType( materialIndex ) { const parser = this.parser; @@ -686,12 +652,10 @@ return THREE.MeshPhysicalMaterial; } - extendMaterialParams( materialIndex, materialParams ) { const parser = this.parser; const materialDef = parser.json.materials[ materialIndex ]; - if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) { return Promise.resolve(); @@ -700,7 +664,6 @@ const pending = []; const extension = materialDef.extensions[ this.name ]; - if ( extension.iridescenceFactor !== undefined ) { materialParams.iridescence = extension.iridescenceFactor; @@ -748,13 +711,12 @@ } } + /** * Sheen Materials Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_sheen */ - - class GLTFMaterialsSheenExtension { constructor( parser ) { @@ -763,7 +725,6 @@ this.name = EXTENSIONS.KHR_MATERIALS_SHEEN; } - getMaterialType( materialIndex ) { const parser = this.parser; @@ -772,12 +733,10 @@ return THREE.MeshPhysicalMaterial; } - extendMaterialParams( materialIndex, materialParams ) { const parser = this.parser; const materialDef = parser.json.materials[ materialIndex ]; - if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) { return Promise.resolve(); @@ -789,7 +748,6 @@ materialParams.sheenRoughness = 0; materialParams.sheen = 1; const extension = materialDef.extensions[ this.name ]; - if ( extension.sheenColorFactor !== undefined ) { materialParams.sheenColor.fromArray( extension.sheenColorFactor ); @@ -819,14 +777,13 @@ } } + /** * Transmission Materials Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission * Draft: https://github.com/KhronosGroup/glTF/pull/1698 */ - - class GLTFMaterialsTransmissionExtension { constructor( parser ) { @@ -835,7 +792,6 @@ this.name = EXTENSIONS.KHR_MATERIALS_TRANSMISSION; } - getMaterialType( materialIndex ) { const parser = this.parser; @@ -844,12 +800,10 @@ return THREE.MeshPhysicalMaterial; } - extendMaterialParams( materialIndex, materialParams ) { const parser = this.parser; const materialDef = parser.json.materials[ materialIndex ]; - if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) { return Promise.resolve(); @@ -858,7 +812,6 @@ const pending = []; const extension = materialDef.extensions[ this.name ]; - if ( extension.transmissionFactor !== undefined ) { materialParams.transmission = extension.transmissionFactor; @@ -876,13 +829,12 @@ } } + /** * Materials Volume Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_volume */ - - class GLTFMaterialsVolumeExtension { constructor( parser ) { @@ -891,7 +843,6 @@ this.name = EXTENSIONS.KHR_MATERIALS_VOLUME; } - getMaterialType( materialIndex ) { const parser = this.parser; @@ -900,12 +851,10 @@ return THREE.MeshPhysicalMaterial; } - extendMaterialParams( materialIndex, materialParams ) { const parser = this.parser; const materialDef = parser.json.materials[ materialIndex ]; - if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) { return Promise.resolve(); @@ -915,14 +864,13 @@ const pending = []; const extension = materialDef.extensions[ this.name ]; materialParams.thickness = extension.thicknessFactor !== undefined ? extension.thicknessFactor : 0; - if ( extension.thicknessTexture !== undefined ) { pending.push( parser.assignTexture( materialParams, 'thicknessMap', extension.thicknessTexture ) ); } - materialParams.attenuationDistance = extension.attenuationDistance || 0; + materialParams.attenuationDistance = extension.attenuationDistance || Infinity; const colorArray = extension.attenuationColor || [ 1, 1, 1 ]; materialParams.attenuationColor = new THREE.Color( colorArray[ 0 ], colorArray[ 1 ], colorArray[ 2 ] ); return Promise.all( pending ); @@ -930,13 +878,12 @@ } } + /** * Materials ior Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_ior */ - - class GLTFMaterialsIorExtension { constructor( parser ) { @@ -945,7 +892,6 @@ this.name = EXTENSIONS.KHR_MATERIALS_IOR; } - getMaterialType( materialIndex ) { const parser = this.parser; @@ -954,12 +900,10 @@ return THREE.MeshPhysicalMaterial; } - extendMaterialParams( materialIndex, materialParams ) { const parser = this.parser; const materialDef = parser.json.materials[ materialIndex ]; - if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) { return Promise.resolve(); @@ -973,13 +917,12 @@ } } + /** * Materials specular Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_specular */ - - class GLTFMaterialsSpecularExtension { constructor( parser ) { @@ -988,7 +931,6 @@ this.name = EXTENSIONS.KHR_MATERIALS_SPECULAR; } - getMaterialType( materialIndex ) { const parser = this.parser; @@ -997,12 +939,10 @@ return THREE.MeshPhysicalMaterial; } - extendMaterialParams( materialIndex, materialParams ) { const parser = this.parser; const materialDef = parser.json.materials[ materialIndex ]; - if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) { return Promise.resolve(); @@ -1012,7 +952,6 @@ const pending = []; const extension = materialDef.extensions[ this.name ]; materialParams.specularIntensity = extension.specularFactor !== undefined ? extension.specularFactor : 1.0; - if ( extension.specularTexture !== undefined ) { pending.push( parser.assignTexture( materialParams, 'specularIntensityMap', extension.specularTexture ) ); @@ -1021,7 +960,6 @@ const colorArray = extension.specularColorFactor || [ 1, 1, 1 ]; materialParams.specularColor = new THREE.Color( colorArray[ 0 ], colorArray[ 1 ], colorArray[ 2 ] ); - if ( extension.specularColorTexture !== undefined ) { pending.push( parser.assignTexture( materialParams, 'specularColorMap', extension.specularColorTexture, THREE.sRGBEncoding ) ); @@ -1033,13 +971,12 @@ } } + /** * BasisU THREE.Texture Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_basisu */ - - class GLTFTextureBasisUExtension { constructor( parser ) { @@ -1048,13 +985,11 @@ this.name = EXTENSIONS.KHR_TEXTURE_BASISU; } - loadTexture( textureIndex ) { const parser = this.parser; const json = parser.json; const textureDef = json.textures[ textureIndex ]; - if ( ! textureDef.extensions || ! textureDef.extensions[ this.name ] ) { return null; @@ -1063,7 +998,6 @@ const extension = textureDef.extensions[ this.name ]; const loader = parser.options.ktx2Loader; - if ( ! loader ) { if ( json.extensionsRequired && json.extensionsRequired.indexOf( this.name ) >= 0 ) { @@ -1084,13 +1018,12 @@ } } + /** * WebP THREE.Texture Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_texture_webp */ - - class GLTFTextureWebPExtension { constructor( parser ) { @@ -1100,14 +1033,12 @@ this.isSupported = null; } - loadTexture( textureIndex ) { const name = this.name; const parser = this.parser; const json = parser.json; const textureDef = json.textures[ textureIndex ]; - if ( ! textureDef.extensions || ! textureDef.extensions[ name ] ) { return null; @@ -1117,7 +1048,6 @@ const extension = textureDef.extensions[ name ]; const source = json.images[ extension.source ]; let loader = parser.textureLoader; - if ( source.uri ) { const handler = parser.options.manager.getHandler( source.uri ); @@ -1128,31 +1058,29 @@ return this.detectSupport().then( function ( isSupported ) { if ( isSupported ) return parser.loadTextureImage( textureIndex, extension.source, loader ); - if ( json.extensionsRequired && json.extensionsRequired.indexOf( name ) >= 0 ) { throw new Error( 'THREE.GLTFLoader: WebP required by asset but unsupported.' ); - } // Fall back to PNG or JPEG. - + } + // Fall back to PNG or JPEG. return parser.loadTexture( textureIndex ); } ); } - detectSupport() { if ( ! this.isSupported ) { this.isSupported = new Promise( function ( resolve ) { - const image = new Image(); // Lossy test image. Support for lossy images doesn't guarantee support for all - // WebP images, unfortunately. + const image = new Image(); + // Lossy test image. Support for lossy images doesn't guarantee support for all + // WebP images, unfortunately. image.src = 'data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA'; - image.onload = image.onerror = function () { resolve( image.height === 1 ); @@ -1168,13 +1096,12 @@ } } + /** * meshopt BufferView Compression Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_meshopt_compression */ - - class GLTFMeshoptCompression { constructor( parser ) { @@ -1183,18 +1110,15 @@ this.parser = parser; } - loadBufferView( index ) { const json = this.parser.json; const bufferView = json.bufferViews[ index ]; - if ( bufferView.extensions && bufferView.extensions[ this.name ] ) { const extensionDef = bufferView.extensions[ this.name ]; const buffer = this.parser.getDependency( 'buffer', extensionDef.buffer ); const decoder = this.parser.options.meshoptDecoder; - if ( ! decoder || ! decoder.supported ) { if ( json.extensionsRequired && json.extensionsRequired.indexOf( this.name ) >= 0 ) { @@ -1210,16 +1134,33 @@ } - return Promise.all( [ buffer, decoder.ready ] ).then( function ( res ) { + return buffer.then( function ( res ) { const byteOffset = extensionDef.byteOffset || 0; const byteLength = extensionDef.byteLength || 0; const count = extensionDef.count; const stride = extensionDef.byteStride; - const result = new ArrayBuffer( count * stride ); - const source = new Uint8Array( res[ 0 ], byteOffset, byteLength ); - decoder.decodeGltfBuffer( new Uint8Array( result ), count, stride, source, extensionDef.mode, extensionDef.filter ); - return result; + const source = new Uint8Array( res, byteOffset, byteLength ); + if ( decoder.decodeGltfBufferAsync ) { + + return decoder.decodeGltfBufferAsync( count, stride, source, extensionDef.mode, extensionDef.filter ).then( function ( res ) { + + return res.buffer; + + } ); + + } else { + + // Support for MeshoptDecoder 0.18 or earlier, without decodeGltfBufferAsync + return decoder.ready.then( function () { + + const result = new ArrayBuffer( count * stride ); + decoder.decodeGltfBuffer( new Uint8Array( result ), count, stride, source, extensionDef.mode, extensionDef.filter ); + return result; + + } ); + + } } ); @@ -1232,16 +1173,152 @@ } } - /* BINARY EXTENSION */ + /** + * GPU Instancing Extension + * + * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_mesh_gpu_instancing + * + */ + class GLTFMeshGpuInstancing { + + constructor( parser ) { + + this.name = EXTENSIONS.EXT_MESH_GPU_INSTANCING; + this.parser = parser; + + } + createNodeMesh( nodeIndex ) { + + const json = this.parser.json; + const nodeDef = json.nodes[ nodeIndex ]; + if ( ! nodeDef.extensions || ! nodeDef.extensions[ this.name ] || nodeDef.mesh === undefined ) { + + return null; + + } + + const meshDef = json.meshes[ nodeDef.mesh ]; + + // No THREE.Points or Lines + Instancing support yet + + for ( const primitive of meshDef.primitives ) { + + if ( primitive.mode !== WEBGL_CONSTANTS.TRIANGLES && primitive.mode !== WEBGL_CONSTANTS.TRIANGLE_STRIP && primitive.mode !== WEBGL_CONSTANTS.TRIANGLE_FAN && primitive.mode !== undefined ) { + + return null; + + } + + } + + const extensionDef = nodeDef.extensions[ this.name ]; + const attributesDef = extensionDef.attributes; + + // @TODO: Can we support THREE.InstancedMesh + THREE.SkinnedMesh? + + const pending = []; + const attributes = {}; + for ( const key in attributesDef ) { + + pending.push( this.parser.getDependency( 'accessor', attributesDef[ key ] ).then( accessor => { + + attributes[ key ] = accessor; + return attributes[ key ]; + + } ) ); + + } + + if ( pending.length < 1 ) { + + return null; + + } + + pending.push( this.parser.createNodeMesh( nodeIndex ) ); + return Promise.all( pending ).then( results => { + + const nodeObject = results.pop(); + const meshes = nodeObject.isGroup ? nodeObject.children : [ nodeObject ]; + const count = results[ 0 ].count; // All attribute counts should be same + const instancedMeshes = []; + for ( const mesh of meshes ) { + + // Temporal variables + const m = new THREE.Matrix4(); + const p = new THREE.Vector3(); + const q = new THREE.Quaternion(); + const s = new THREE.Vector3( 1, 1, 1 ); + const instancedMesh = new THREE.InstancedMesh( mesh.geometry, mesh.material, count ); + for ( let i = 0; i < count; i ++ ) { + + if ( attributes.TRANSLATION ) { + + p.fromBufferAttribute( attributes.TRANSLATION, i ); + + } + + if ( attributes.ROTATION ) { + + q.fromBufferAttribute( attributes.ROTATION, i ); + + } + + if ( attributes.SCALE ) { + + s.fromBufferAttribute( attributes.SCALE, i ); + + } + + instancedMesh.setMatrixAt( i, m.compose( p, q, s ) ); + + } + // Add instance attributes to the geometry, excluding TRS. + for ( const attributeName in attributes ) { + + if ( attributeName !== 'TRANSLATION' && attributeName !== 'ROTATION' && attributeName !== 'SCALE' ) { + + mesh.geometry.setAttribute( attributeName, attributes[ attributeName ] ); + + } + + } + + // Just in case + THREE.Object3D.prototype.copy.call( instancedMesh, mesh ); + + // https://github.com/mrdoob/three.js/issues/18334 + instancedMesh.frustumCulled = false; + this.parser.assignFinalMaterial( instancedMesh ); + instancedMeshes.push( instancedMesh ); + + } + + if ( nodeObject.isGroup ) { + + nodeObject.clear(); + nodeObject.add( ...instancedMeshes ); + return nodeObject; + + } + + return instancedMeshes[ 0 ]; + + } ); + + } + + } + + /* BINARY EXTENSION */ const BINARY_EXTENSION_HEADER_MAGIC = 'glTF'; const BINARY_EXTENSION_HEADER_LENGTH = 12; const BINARY_EXTENSION_CHUNK_TYPES = { JSON: 0x4E4F534A, BIN: 0x004E4942 }; - class GLTFBinaryExtension { constructor( data ) { @@ -1255,7 +1332,6 @@ version: headerView.getUint32( 4, true ), length: headerView.getUint32( 8, true ) }; - if ( this.header.magic !== BINARY_EXTENSION_HEADER_MAGIC ) { throw new Error( 'THREE.GLTFLoader: Unsupported glTF-Binary header.' ); @@ -1269,14 +1345,12 @@ const chunkContentsLength = this.header.length - BINARY_EXTENSION_HEADER_LENGTH; const chunkView = new DataView( data, BINARY_EXTENSION_HEADER_LENGTH ); let chunkIndex = 0; - while ( chunkIndex < chunkContentsLength ) { const chunkLength = chunkView.getUint32( chunkIndex, true ); chunkIndex += 4; const chunkType = chunkView.getUint32( chunkIndex, true ); chunkIndex += 4; - if ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.JSON ) { const contentArray = new Uint8Array( data, BINARY_EXTENSION_HEADER_LENGTH + chunkIndex, chunkLength ); @@ -1287,8 +1361,9 @@ const byteOffset = BINARY_EXTENSION_HEADER_LENGTH + chunkIndex; this.body = data.slice( byteOffset, byteOffset + chunkLength ); - } // Clients must ignore chunks with unknown types. + } + // Clients must ignore chunks with unknown types. chunkIndex += chunkLength; @@ -1303,13 +1378,12 @@ } } + /** * DRACO THREE.Mesh Compression Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression */ - - class GLTFDracoMeshCompressionExtension { constructor( json, dracoLoader ) { @@ -1326,7 +1400,6 @@ this.dracoLoader.preload(); } - decodePrimitive( primitive, parser ) { const json = this.json; @@ -1336,7 +1409,6 @@ const threeAttributeMap = {}; const attributeNormalizedMap = {}; const attributeTypeMap = {}; - for ( const attributeName in gltfAttributeMap ) { const threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase(); @@ -1347,12 +1419,11 @@ for ( const attributeName in primitive.attributes ) { const threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase(); - if ( gltfAttributeMap[ attributeName ] !== undefined ) { const accessorDef = json.accessors[ primitive.attributes[ attributeName ] ]; const componentType = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ]; - attributeTypeMap[ threeAttributeName ] = componentType; + attributeTypeMap[ threeAttributeName ] = componentType.name; attributeNormalizedMap[ threeAttributeName ] = accessorDef.normalized === true; } @@ -1384,13 +1455,12 @@ } } + /** * THREE.Texture Transform Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_transform */ - - class GLTFTextureTransformExtension { constructor() { @@ -1398,7 +1468,6 @@ this.name = EXTENSIONS.KHR_TEXTURE_TRANSFORM; } - extendTexture( texture, transform ) { if ( transform.texCoord !== undefined ) { @@ -1415,7 +1484,6 @@ } texture = texture.clone(); - if ( transform.offset !== undefined ) { texture.offset.fromArray( transform.offset ); @@ -1440,254 +1508,12 @@ } } - /** - * Specular-Glossiness Extension - * - * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness - */ - /** - * A sub class of StandardMaterial with some of the functionality - * changed via the `onBeforeCompile` callback - * @pailhead - */ - - - class GLTFMeshStandardSGMaterial extends THREE.MeshStandardMaterial { - - constructor( params ) { - - super(); - this.isGLTFSpecularGlossinessMaterial = true; //various chunks that need replacing - - const specularMapParsFragmentChunk = [ '#ifdef USE_SPECULARMAP', ' uniform sampler2D specularMap;', '#endif' ].join( '\n' ); - const glossinessMapParsFragmentChunk = [ '#ifdef USE_GLOSSINESSMAP', ' uniform sampler2D glossinessMap;', '#endif' ].join( '\n' ); - const specularMapFragmentChunk = [ 'vec3 specularFactor = specular;', '#ifdef USE_SPECULARMAP', ' vec4 texelSpecular = texture2D( specularMap, vUv );', ' // reads channel RGB, compatible with a glTF Specular-Glossiness (RGBA) texture', ' specularFactor *= texelSpecular.rgb;', '#endif' ].join( '\n' ); - const glossinessMapFragmentChunk = [ 'float glossinessFactor = glossiness;', '#ifdef USE_GLOSSINESSMAP', ' vec4 texelGlossiness = texture2D( glossinessMap, vUv );', ' // reads channel A, compatible with a glTF Specular-Glossiness (RGBA) texture', ' glossinessFactor *= texelGlossiness.a;', '#endif' ].join( '\n' ); - const lightPhysicalFragmentChunk = [ 'PhysicalMaterial material;', 'material.diffuseColor = diffuseColor.rgb * ( 1. - max( specularFactor.r, max( specularFactor.g, specularFactor.b ) ) );', 'vec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );', 'float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );', 'material.roughness = max( 1.0 - glossinessFactor, 0.0525 ); // 0.0525 corresponds to the base mip of a 256 cubemap.', 'material.roughness += geometryRoughness;', 'material.roughness = min( material.roughness, 1.0 );', 'material.specularColor = specularFactor;' ].join( '\n' ); - const uniforms = { - specular: { - value: new THREE.Color().setHex( 0xffffff ) - }, - glossiness: { - value: 1 - }, - specularMap: { - value: null - }, - glossinessMap: { - value: null - } - }; - this._extraUniforms = uniforms; - - this.onBeforeCompile = function ( shader ) { - - for ( const uniformName in uniforms ) { - - shader.uniforms[ uniformName ] = uniforms[ uniformName ]; - - } - - shader.fragmentShader = shader.fragmentShader.replace( 'uniform float roughness;', 'uniform vec3 specular;' ).replace( 'uniform float metalness;', 'uniform float glossiness;' ).replace( '#include ', specularMapParsFragmentChunk ).replace( '#include ', glossinessMapParsFragmentChunk ).replace( '#include ', specularMapFragmentChunk ).replace( '#include ', glossinessMapFragmentChunk ).replace( '#include ', lightPhysicalFragmentChunk ); - - }; - - Object.defineProperties( this, { - specular: { - get: function () { - - return uniforms.specular.value; - - }, - set: function ( v ) { - - uniforms.specular.value = v; - - } - }, - specularMap: { - get: function () { - - return uniforms.specularMap.value; - - }, - set: function ( v ) { - - uniforms.specularMap.value = v; - - if ( v ) { - - this.defines.USE_SPECULARMAP = ''; // USE_UV is set by the renderer for specular maps - - } else { - - delete this.defines.USE_SPECULARMAP; - - } - - } - }, - glossiness: { - get: function () { - - return uniforms.glossiness.value; - - }, - set: function ( v ) { - - uniforms.glossiness.value = v; - - } - }, - glossinessMap: { - get: function () { - - return uniforms.glossinessMap.value; - - }, - set: function ( v ) { - - uniforms.glossinessMap.value = v; - - if ( v ) { - - this.defines.USE_GLOSSINESSMAP = ''; - this.defines.USE_UV = ''; - - } else { - - delete this.defines.USE_GLOSSINESSMAP; - delete this.defines.USE_UV; - - } - - } - } - } ); - delete this.metalness; - delete this.roughness; - delete this.metalnessMap; - delete this.roughnessMap; - this.setValues( params ); - - } - - copy( source ) { - - super.copy( source ); - this.specularMap = source.specularMap; - this.specular.copy( source.specular ); - this.glossinessMap = source.glossinessMap; - this.glossiness = source.glossiness; - delete this.metalness; - delete this.roughness; - delete this.metalnessMap; - delete this.roughnessMap; - return this; - - } - - } - - class GLTFMaterialsPbrSpecularGlossinessExtension { - - constructor() { - - this.name = EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS; - this.specularGlossinessParams = [ 'color', 'map', 'lightMap', 'lightMapIntensity', 'aoMap', 'aoMapIntensity', 'emissive', 'emissiveIntensity', 'emissiveMap', 'bumpMap', 'bumpScale', 'normalMap', 'normalMapType', 'displacementMap', 'displacementScale', 'displacementBias', 'specularMap', 'specular', 'glossinessMap', 'glossiness', 'alphaMap', 'envMap', 'envMapIntensity' ]; - - } - - getMaterialType() { - - return GLTFMeshStandardSGMaterial; - - } - - extendParams( materialParams, materialDef, parser ) { - - const pbrSpecularGlossiness = materialDef.extensions[ this.name ]; - materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 ); - materialParams.opacity = 1.0; - const pending = []; - - if ( Array.isArray( pbrSpecularGlossiness.diffuseFactor ) ) { - - const array = pbrSpecularGlossiness.diffuseFactor; - materialParams.color.fromArray( array ); - materialParams.opacity = array[ 3 ]; - - } - - if ( pbrSpecularGlossiness.diffuseTexture !== undefined ) { - - pending.push( parser.assignTexture( materialParams, 'map', pbrSpecularGlossiness.diffuseTexture, THREE.sRGBEncoding ) ); - - } - - materialParams.emissive = new THREE.Color( 0.0, 0.0, 0.0 ); - materialParams.glossiness = pbrSpecularGlossiness.glossinessFactor !== undefined ? pbrSpecularGlossiness.glossinessFactor : 1.0; - materialParams.specular = new THREE.Color( 1.0, 1.0, 1.0 ); - - if ( Array.isArray( pbrSpecularGlossiness.specularFactor ) ) { - - materialParams.specular.fromArray( pbrSpecularGlossiness.specularFactor ); - - } - - if ( pbrSpecularGlossiness.specularGlossinessTexture !== undefined ) { - - const specGlossMapDef = pbrSpecularGlossiness.specularGlossinessTexture; - pending.push( parser.assignTexture( materialParams, 'glossinessMap', specGlossMapDef ) ); - pending.push( parser.assignTexture( materialParams, 'specularMap', specGlossMapDef, THREE.sRGBEncoding ) ); - - } - - return Promise.all( pending ); - - } - - createMaterial( materialParams ) { - - const material = new GLTFMeshStandardSGMaterial( materialParams ); - material.fog = true; - material.color = materialParams.color; - material.map = materialParams.map === undefined ? null : materialParams.map; - material.lightMap = null; - material.lightMapIntensity = 1.0; - material.aoMap = materialParams.aoMap === undefined ? null : materialParams.aoMap; - material.aoMapIntensity = 1.0; - material.emissive = materialParams.emissive; - material.emissiveIntensity = materialParams.emissiveIntensity === undefined ? 1.0 : materialParams.emissiveIntensity; - material.emissiveMap = materialParams.emissiveMap === undefined ? null : materialParams.emissiveMap; - material.bumpMap = materialParams.bumpMap === undefined ? null : materialParams.bumpMap; - material.bumpScale = 1; - material.normalMap = materialParams.normalMap === undefined ? null : materialParams.normalMap; - material.normalMapType = THREE.TangentSpaceNormalMap; - if ( materialParams.normalScale ) material.normalScale = materialParams.normalScale; - material.displacementMap = null; - material.displacementScale = 1; - material.displacementBias = 0; - material.specularMap = materialParams.specularMap === undefined ? null : materialParams.specularMap; - material.specular = materialParams.specular; - material.glossinessMap = materialParams.glossinessMap === undefined ? null : materialParams.glossinessMap; - material.glossiness = materialParams.glossiness; - material.alphaMap = null; - material.envMap = materialParams.envMap === undefined ? null : materialParams.envMap; - material.envMapIntensity = 1.0; - return material; - - } - - } /** * THREE.Mesh Quantization Extension * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization */ - - class GLTFMeshQuantizationExtension { constructor() { @@ -1697,15 +1523,13 @@ } } - /*********************************/ + /*********************************/ /********** INTERPOLATION ********/ - /*********************************/ + // Spline Interpolation // Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#appendix-c-spline-interpolation - - class GLTFCubicSplineInterpolant extends THREE.Interpolant { constructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) { @@ -1713,16 +1537,15 @@ super( parameterPositions, sampleValues, sampleSize, resultBuffer ); } - copySampleValue_( index ) { // Copies a sample value to the result buffer. See description of glTF // CUBICSPLINE values layout in interpolate_() function below. + const result = this.resultBuffer, values = this.sampleValues, valueSize = this.valueSize, offset = index * valueSize * 3 + valueSize; - for ( let i = 0; i !== valueSize; i ++ ) { result[ i ] = values[ offset + i ]; @@ -1732,7 +1555,6 @@ return result; } - interpolate_( i1, t0, t, t1 ) { const result = this.resultBuffer; @@ -1749,17 +1571,15 @@ const s2 = - 2 * ppp + 3 * pp; const s3 = ppp - pp; const s0 = 1 - s2; - const s1 = s3 - pp + p; // Layout of keyframe output values for CUBICSPLINE animations: - // [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ] + const s1 = s3 - pp + p; + // Layout of keyframe output values for CUBICSPLINE animations: + // [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ] for ( let i = 0; i !== stride; i ++ ) { const p0 = values[ offset0 + i + stride ]; // splineVertex_k - const m0 = values[ offset0 + i + stride2 ] * td; // outTangent_k * (t_k+1 - t_k) - const p1 = values[ offset1 + i + stride ]; // splineVertex_k+1 - const m1 = values[ offset1 + i ] * td; // inTangent_k+1 * (t_k+1 - t_k) result[ i ] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1; @@ -1771,31 +1591,25 @@ } } - const _q = new THREE.Quaternion(); - class GLTFCubicSplineQuaternionInterpolant extends GLTFCubicSplineInterpolant { interpolate_( i1, t0, t, t1 ) { const result = super.interpolate_( i1, t0, t, t1 ); - _q.fromArray( result ).normalize().toArray( result ); - return result; } } - /*********************************/ + /*********************************/ /********** INTERNALS ************/ - /*********************************/ /* CONSTANTS */ - const WEBGL_CONSTANTS = { FLOAT: 5126, //FLOAT_MAT2: 35674, @@ -1875,10 +1689,10 @@ MASK: 'MASK', BLEND: 'BLEND' }; + /** * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#default-material */ - function createDefaultMaterial( cache ) { if ( cache[ 'DefaultMaterial' ] === undefined ) { @@ -1902,6 +1716,7 @@ function addUnknownExtensionsToUserData( knownExtensions, object, objectDef ) { // Add unknown glTF extensions to an object's userData. + for ( const name in objectDef.extensions ) { if ( knownExtensions[ name ] === undefined ) { @@ -1914,12 +1729,11 @@ } } + /** * @param {Object3D|Material|BufferGeometry} object * @param {GLTF.definition} gltfDef */ - - function assignExtrasToUserData( object, gltfDef ) { if ( gltfDef.extras !== undefined ) { @@ -1937,6 +1751,7 @@ } } + /** * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#morph-targets * @@ -1945,14 +1760,11 @@ * @param {GLTFParser} parser * @return {Promise} */ - - function addMorphTargets( geometry, targets, parser ) { let hasMorphPosition = false; let hasMorphNormal = false; let hasMorphColor = false; - for ( let i = 0, il = targets.length; i < il; i ++ ) { const target = targets[ i ]; @@ -1967,11 +1779,9 @@ const pendingPositionAccessors = []; const pendingNormalAccessors = []; const pendingColorAccessors = []; - for ( let i = 0, il = targets.length; i < il; i ++ ) { const target = targets[ i ]; - if ( hasMorphPosition ) { const pendingAccessor = target.POSITION !== undefined ? parser.getDependency( 'accessor', target.POSITION ) : geometry.attributes.position; @@ -2009,16 +1819,14 @@ } ); } + /** * @param {Mesh} mesh * @param {GLTF.Mesh} meshDef */ - - function updateMorphTargets( mesh, meshDef ) { mesh.updateMorphTargets(); - if ( meshDef.weights !== undefined ) { for ( let i = 0, il = meshDef.weights.length; i < il; i ++ ) { @@ -2027,17 +1835,15 @@ } - } // .extras has user-defined data, so check that .extras.targetNames is an array. - + } + // .extras has user-defined data, so check that .extras.targetNames is an array. if ( meshDef.extras && Array.isArray( meshDef.extras.targetNames ) ) { const targetNames = meshDef.extras.targetNames; - if ( mesh.morphTargetInfluences.length === targetNames.length ) { mesh.morphTargetDictionary = {}; - for ( let i = 0, il = targetNames.length; i < il; i ++ ) { mesh.morphTargetDictionary[ targetNames[ i ] ] = i; @@ -2058,7 +1864,6 @@ const dracoExtension = primitiveDef.extensions && primitiveDef.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ]; let geometryKey; - if ( dracoExtension ) { geometryKey = 'draco:' + dracoExtension.bufferView + ':' + dracoExtension.indices + ':' + createAttributesKey( dracoExtension.attributes ); @@ -2077,7 +1882,6 @@ let attributesKey = ''; const keys = Object.keys( attributes ).sort(); - for ( let i = 0, il = keys.length; i < il; i ++ ) { attributesKey += keys[ i ] + ':' + attributes[ keys[ i ] ] + ';'; @@ -2092,20 +1896,17 @@ // Reference: // https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization#encoding-quantized-data + switch ( constructor ) { case Int8Array: return 1 / 127; - case Uint8Array: return 1 / 255; - case Int16Array: return 1 / 32767; - case Uint16Array: return 1 / 65535; - default: throw new Error( 'THREE.GLTFLoader: Unsupported normalized accessor component type.' ); @@ -2120,8 +1921,8 @@ return 'image/png'; } - /* GLTF PARSER */ + /* GLTF PARSER */ class GLTFParser { @@ -2130,14 +1931,18 @@ this.json = json; this.extensions = {}; this.plugins = {}; - this.options = options; // loader object cache + this.options = options; - this.cache = new GLTFRegistry(); // associations between Three.js objects and glTF elements + // loader object cache + this.cache = new GLTFRegistry(); - this.associations = new Map(); // THREE.BufferGeometry caching + // associations between Three.js objects and glTF elements + this.associations = new Map(); - this.primitiveCache = {}; // THREE.Object3D instance caches + // THREE.BufferGeometry caching + this.primitiveCache = {}; + // THREE.Object3D instance caches this.meshCache = { refs: {}, uses: {} @@ -2151,14 +1956,24 @@ uses: {} }; this.sourceCache = {}; - this.textureCache = {}; // Track node names, to ensure no duplicates + this.textureCache = {}; - this.nodeNamesUsed = {}; // Use an THREE.ImageBitmapLoader if imageBitmaps are supported. Moves much of the + // Track node names, to ensure no duplicates + this.nodeNamesUsed = {}; + + // Use an THREE.ImageBitmapLoader if imageBitmaps are supported. Moves much of the // expensive work of uploading a texture to the GPU off the main thread. - const isSafari = /^((?!chrome|android).)*safari/i.test( navigator.userAgent ) === true; - const isFirefox = navigator.userAgent.indexOf( 'Firefox' ) > - 1; - const firefoxVersion = isFirefox ? navigator.userAgent.match( /Firefox\/([0-9]+)\./ )[ 1 ] : - 1; + let isSafari = false; + let isFirefox = false; + let firefoxVersion = - 1; + if ( typeof navigator !== 'undefined' ) { + + isSafari = /^((?!chrome|android).)*safari/i.test( navigator.userAgent ) === true; + isFirefox = navigator.userAgent.indexOf( 'Firefox' ) > - 1; + firefoxVersion = isFirefox ? navigator.userAgent.match( /Firefox\/([0-9]+)\./ )[ 1 ] : - 1; + + } if ( typeof createImageBitmap === 'undefined' || isSafari || isFirefox && firefoxVersion < 98 ) { @@ -2174,7 +1989,6 @@ this.textureLoader.setRequestHeader( this.options.requestHeader ); this.fileLoader = new THREE.FileLoader( this.options.manager ); this.fileLoader.setResponseType( 'arraybuffer' ); - if ( this.options.crossOrigin === 'use-credentials' ) { this.fileLoader.setWithCredentials( true ); @@ -2182,33 +1996,31 @@ } } - setExtensions( extensions ) { this.extensions = extensions; } - setPlugins( plugins ) { this.plugins = plugins; } - parse( onLoad, onError ) { const parser = this; const json = this.json; - const extensions = this.extensions; // Clear the loader cache + const extensions = this.extensions; - this.cache.removeAll(); // Mark the special nodes/meshes in json for efficient parse + // Clear the loader cache + this.cache.removeAll(); + // Mark the special nodes/meshes in json for efficient parse this._invokeAll( function ( ext ) { return ext._markDefs && ext._markDefs(); } ); - Promise.all( this._invokeAll( function ( ext ) { return ext.beforeRoot && ext.beforeRoot(); @@ -2243,43 +2055,41 @@ } ).catch( onError ); } + /** * Marks the special nodes/meshes in json for efficient parse. */ - - _markDefs() { const nodeDefs = this.json.nodes || []; const skinDefs = this.json.skins || []; - const meshDefs = this.json.meshes || []; // Nothing in the node definition indicates whether it is a THREE.Bone or an - // THREE.Object3D. Use the skins' joint references to mark bones. + const meshDefs = this.json.meshes || []; + // Nothing in the node definition indicates whether it is a THREE.Bone or an + // THREE.Object3D. Use the skins' joint references to mark bones. for ( let skinIndex = 0, skinLength = skinDefs.length; skinIndex < skinLength; skinIndex ++ ) { const joints = skinDefs[ skinIndex ].joints; - for ( let i = 0, il = joints.length; i < il; i ++ ) { nodeDefs[ joints[ i ] ].isBone = true; } - } // Iterate over all nodes, marking references to shared resources, - // as well as skeleton joints. - + } + // Iterate over all nodes, marking references to shared resources, + // as well as skeleton joints. for ( let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex ++ ) { const nodeDef = nodeDefs[ nodeIndex ]; - if ( nodeDef.mesh !== undefined ) { - this._addNodeRef( this.meshCache, nodeDef.mesh ); // Nothing in the mesh definition indicates whether it is - // a THREE.SkinnedMesh or THREE.Mesh. Use the node's mesh reference - // to mark THREE.SkinnedMesh if node has skin. - + this._addNodeRef( this.meshCache, nodeDef.mesh ); + // Nothing in the mesh definition indicates whether it is + // a THREE.SkinnedMesh or THREE.Mesh. Use the node's mesh reference + // to mark THREE.SkinnedMesh if node has skin. if ( nodeDef.skin !== undefined ) { meshDefs[ nodeDef.mesh ].isSkinnedMesh = true; @@ -2297,6 +2107,7 @@ } } + /** * Counts references to shared node / THREE.Object3D resources. These resources * can be reused, or "instantiated", at multiple nodes in the scene @@ -2306,12 +2117,9 @@ * * Example: CesiumMilkTruck sample model reuses "Wheel" meshes. */ - - _addNodeRef( cache, index ) { if ( index === undefined ) return; - if ( cache.refs[ index ] === undefined ) { cache.refs[ index ] = cache.uses[ index ] = 0; @@ -2321,19 +2129,18 @@ cache.refs[ index ] ++; } - /** Returns a reference to a shared resource, cloning it if necessary. */ - + /** Returns a reference to a shared resource, cloning it if necessary. */ _getNodeRef( cache, index, object ) { if ( cache.refs[ index ] <= 1 ) return object; - const ref = object.clone(); // Propagates mappings to the cloned object, prevents mappings on the - // original object from being lost. + const ref = object.clone(); + // Propagates mappings to the cloned object, prevents mappings on the + // original object from being lost. const updateMappings = ( original, clone ) => { const mappings = this.associations.get( original ); - if ( mappings != null ) { this.associations.set( clone, mappings ); @@ -2353,12 +2160,10 @@ return ref; } - _invokeOne( func ) { const extensions = Object.values( this.plugins ); extensions.push( this ); - for ( let i = 0; i < extensions.length; i ++ ) { const result = func( extensions[ i ] ); @@ -2369,13 +2174,11 @@ return null; } - _invokeAll( func ) { const extensions = Object.values( this.plugins ); extensions.unshift( this ); const pending = []; - for ( let i = 0; i < extensions.length; i ++ ) { const result = func( extensions[ i ] ); @@ -2386,19 +2189,17 @@ return pending; } + /** * Requests the specified dependency asynchronously, with caching. * @param {string} type * @param {number} index * @return {Promise} */ - - getDependency( type, index ) { const cacheKey = type + ':' + index; let dependency = this.cache.get( cacheKey ); - if ( ! dependency ) { switch ( type ) { @@ -2406,11 +2207,9 @@ case 'scene': dependency = this.loadScene( index ); break; - case 'node': dependency = this.loadNode( index ); break; - case 'mesh': dependency = this._invokeOne( function ( ext ) { @@ -2418,11 +2217,9 @@ } ); break; - case 'accessor': dependency = this.loadAccessor( index ); break; - case 'bufferView': dependency = this._invokeOne( function ( ext ) { @@ -2430,11 +2227,9 @@ } ); break; - case 'buffer': dependency = this.loadBuffer( index ); break; - case 'material': dependency = this._invokeOne( function ( ext ) { @@ -2442,7 +2237,6 @@ } ); break; - case 'texture': dependency = this._invokeOne( function ( ext ) { @@ -2450,11 +2244,9 @@ } ); break; - case 'skin': dependency = this.loadSkin( index ); break; - case 'animation': dependency = this._invokeOne( function ( ext ) { @@ -2462,13 +2254,22 @@ } ); break; - case 'camera': dependency = this.loadCamera( index ); break; - default: - throw new Error( 'Unknown type: ' + type ); + dependency = this._invokeOne( function ( ext ) { + + return ext != this && ext.getDependency && ext.getDependency( type, index ); + + } ); + if ( ! dependency ) { + + throw new Error( 'Unknown type: ' + type ); + + } + + break; } @@ -2479,17 +2280,15 @@ return dependency; } + /** * Requests all dependencies of the specified type asynchronously, with caching. * @param {string} type * @return {Promise>} */ - - getDependencies( type ) { let dependencies = this.cache.get( type ); - if ( ! dependencies ) { const parser = this; @@ -2506,25 +2305,23 @@ return dependencies; } + /** * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views * @param {number} bufferIndex * @return {Promise} */ - - loadBuffer( bufferIndex ) { const bufferDef = this.json.buffers[ bufferIndex ]; const loader = this.fileLoader; - if ( bufferDef.type && bufferDef.type !== 'arraybuffer' ) { throw new Error( 'THREE.GLTFLoader: ' + bufferDef.type + ' buffer type is not supported.' ); - } // If present, GLB container is required to be the first buffer. - + } + // If present, GLB container is required to be the first buffer. if ( bufferDef.uri === undefined && bufferIndex === 0 ) { return Promise.resolve( this.extensions[ EXTENSIONS.KHR_BINARY_GLTF ].body ); @@ -2543,13 +2340,12 @@ } ); } + /** * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views * @param {number} bufferViewIndex * @return {Promise} */ - - loadBufferView( bufferViewIndex ) { const bufferViewDef = this.json.bufferViews[ bufferViewIndex ]; @@ -2562,30 +2358,28 @@ } ); } + /** * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#accessors * @param {number} accessorIndex * @return {Promise} */ - - loadAccessor( accessorIndex ) { const parser = this; const json = this.json; const accessorDef = this.json.accessors[ accessorIndex ]; - if ( accessorDef.bufferView === undefined && accessorDef.sparse === undefined ) { - // Ignore empty accessors, which may be used to declare runtime - // information about attributes coming from another source (e.g. Draco - // compression extension). - return Promise.resolve( null ); + const itemSize = WEBGL_TYPE_SIZES[ accessorDef.type ]; + const TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ]; + const normalized = accessorDef.normalized === true; + const array = new TypedArray( accessorDef.count * itemSize ); + return Promise.resolve( new THREE.BufferAttribute( array, itemSize, normalized ) ); } const pendingBufferViews = []; - if ( accessorDef.bufferView !== undefined ) { pendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.bufferView ) ); @@ -2607,15 +2401,17 @@ const bufferView = bufferViews[ 0 ]; const itemSize = WEBGL_TYPE_SIZES[ accessorDef.type ]; - const TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ]; // For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12. + const TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ]; + // For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12. const elementBytes = TypedArray.BYTES_PER_ELEMENT; const itemBytes = elementBytes * itemSize; const byteOffset = accessorDef.byteOffset || 0; const byteStride = accessorDef.bufferView !== undefined ? json.bufferViews[ accessorDef.bufferView ].byteStride : undefined; const normalized = accessorDef.normalized === true; - let array, bufferAttribute; // The buffer is not interleaved if the stride is the item size in bytes. + let array, bufferAttribute; + // The buffer is not interleaved if the stride is the item size in bytes. if ( byteStride && byteStride !== itemBytes ) { // Each "slice" of the buffer, as defined by 'count' elements of 'byteStride' bytes, gets its own THREE.InterleavedBuffer @@ -2623,11 +2419,11 @@ const ibSlice = Math.floor( byteOffset / byteStride ); const ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType + ':' + ibSlice + ':' + accessorDef.count; let ib = parser.cache.get( ibCacheKey ); - if ( ! ib ) { - array = new TypedArray( bufferView, ibSlice * byteStride, accessorDef.count * byteStride / elementBytes ); // Integer parameters to IB/IBA are in array elements, not bytes. + array = new TypedArray( bufferView, ibSlice * byteStride, accessorDef.count * byteStride / elementBytes ); + // Integer parameters to IB/IBA are in array elements, not bytes. ib = new THREE.InterleavedBuffer( array, byteStride / elementBytes ); parser.cache.add( ibCacheKey, ib ); @@ -2649,9 +2445,9 @@ bufferAttribute = new THREE.BufferAttribute( array, itemSize, normalized ); - } // https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#sparse-accessors - + } + // https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#sparse-accessors if ( accessorDef.sparse !== undefined ) { const itemSizeIndices = WEBGL_TYPE_SIZES.SCALAR; @@ -2660,7 +2456,6 @@ const byteOffsetValues = accessorDef.sparse.values.byteOffset || 0; const sparseIndices = new TypedArrayIndices( bufferViews[ 1 ], byteOffsetIndices, accessorDef.sparse.count * itemSizeIndices ); const sparseValues = new TypedArray( bufferViews[ 2 ], byteOffsetValues, accessorDef.sparse.count * itemSize ); - if ( bufferView !== null ) { // Avoid modifying the original ArrayBuffer, if the bufferView wasn't initialized with zeroes. @@ -2686,13 +2481,12 @@ } ); } + /** * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#textures * @param {number} textureIndex - * @return {Promise} + * @return {Promise} */ - - loadTexture( textureIndex ) { const json = this.json; @@ -2701,7 +2495,6 @@ const sourceIndex = textureDef.source; const sourceDef = json.images[ sourceIndex ]; let loader = this.textureLoader; - if ( sourceDef.uri ) { const handler = options.manager.getHandler( sourceDef.uri ); @@ -2712,7 +2505,6 @@ return this.loadTextureImage( textureIndex, sourceIndex, loader ); } - loadTextureImage( textureIndex, sourceIndex, loader ) { const parser = this; @@ -2720,7 +2512,6 @@ const textureDef = json.textures[ textureIndex ]; const sourceDef = json.images[ sourceIndex ]; const cacheKey = ( sourceDef.uri || sourceDef.bufferView ) + ':' + textureDef.sampler; - if ( this.textureCache[ cacheKey ] ) { // See https://github.com/mrdoob/three.js/issues/21559. @@ -2731,7 +2522,7 @@ const promise = this.loadImageSource( sourceIndex, loader ).then( function ( texture ) { texture.flipY = false; - if ( textureDef.name ) texture.name = textureDef.name; + texture.name = textureDef.name || sourceDef.name || ''; const samplers = json.samplers || {}; const sampler = samplers[ textureDef.sampler ] || {}; texture.magFilter = WEBGL_FILTERS[ sampler.magFilter ] || THREE.LinearFilter; @@ -2752,13 +2543,11 @@ return promise; } - loadImageSource( sourceIndex, loader ) { const parser = this; const json = this.json; const options = this.options; - if ( this.sourceCache[ sourceIndex ] !== undefined ) { return this.sourceCache[ sourceIndex ].then( texture => texture.clone() ); @@ -2769,10 +2558,10 @@ const URL = self.URL || self.webkitURL; let sourceURI = sourceDef.uri || ''; let isObjectURL = false; - if ( sourceDef.bufferView !== undefined ) { // Load binary image data from bufferView, if provided. + sourceURI = parser.getDependency( 'bufferView', sourceDef.bufferView ).then( function ( bufferView ) { isObjectURL = true; @@ -2795,7 +2584,6 @@ return new Promise( function ( resolve, reject ) { let onLoad = resolve; - if ( loader.isImageBitmapLoader === true ) { onLoad = function ( imageBitmap ) { @@ -2815,6 +2603,7 @@ } ).then( function ( texture ) { // Clean up resources and configure THREE.Texture. + if ( isObjectURL === true ) { URL.revokeObjectURL( sourceURI ); @@ -2834,6 +2623,7 @@ return promise; } + /** * Asynchronously assigns a texture to the given material parameters. * @param {Object} materialParams @@ -2841,13 +2631,13 @@ * @param {Object} mapDef * @return {Promise} */ - - assignTexture( materialParams, mapName, mapDef, encoding ) { const parser = this; return this.getDependency( 'texture', mapDef.index ).then( function ( texture ) { + if ( ! texture ) return null; + // Materials sample aoMap from UV set 1 and other maps from UV set 0 - this can't be configured // However, we will copy UV set 0 to UV set 1 on demand for aoMap if ( mapDef.texCoord !== undefined && mapDef.texCoord != 0 && ! ( mapName === 'aoMap' && mapDef.texCoord == 1 ) ) { @@ -2859,7 +2649,6 @@ if ( parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] ) { const transform = mapDef.extensions !== undefined ? mapDef.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] : undefined; - if ( transform ) { const gltfReference = parser.associations.get( texture ); @@ -2882,6 +2671,7 @@ } ); } + /** * Assigns final material to a THREE.Mesh, THREE.Line, or THREE.Points instance. The instance * already has a material (generated from the glTF material options alone) @@ -2890,8 +2680,6 @@ * be created if necessary, and reused from a cache. * @param {Object3D} mesh THREE.Mesh, THREE.Line, or THREE.Points instance. */ - - assignFinalMaterial( mesh ) { const geometry = mesh.geometry; @@ -2899,12 +2687,10 @@ const useDerivativeTangents = geometry.attributes.tangent === undefined; const useVertexColors = geometry.attributes.color !== undefined; const useFlatShading = geometry.attributes.normal === undefined; - if ( mesh.isPoints ) { const cacheKey = 'PointsMaterial:' + material.uuid; let pointsMaterial = this.cache.get( cacheKey ); - if ( ! pointsMaterial ) { pointsMaterial = new THREE.PointsMaterial(); @@ -2923,7 +2709,6 @@ const cacheKey = 'LineBasicMaterial:' + material.uuid; let lineMaterial = this.cache.get( cacheKey ); - if ( ! lineMaterial ) { lineMaterial = new THREE.LineBasicMaterial(); @@ -2935,24 +2720,21 @@ material = lineMaterial; - } // Clone the material if it will be modified - + } + // Clone the material if it will be modified if ( useDerivativeTangents || useVertexColors || useFlatShading ) { let cacheKey = 'ClonedMaterial:' + material.uuid + ':'; - if ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:'; if ( useDerivativeTangents ) cacheKey += 'derivative-tangents:'; if ( useVertexColors ) cacheKey += 'vertex-colors:'; if ( useFlatShading ) cacheKey += 'flat-shading:'; let cachedMaterial = this.cache.get( cacheKey ); - if ( ! cachedMaterial ) { cachedMaterial = material.clone(); if ( useVertexColors ) cachedMaterial.vertexColors = true; if ( useFlatShading ) cachedMaterial.flatShading = true; - if ( useDerivativeTangents ) { // https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995 @@ -2968,8 +2750,9 @@ material = cachedMaterial; - } // workarounds for mesh and geometry + } + // workarounds for mesh and geometry if ( material.aoMap && geometry.attributes.uv2 === undefined && geometry.attributes.uv !== undefined ) { @@ -2980,19 +2763,17 @@ mesh.material = material; } - getMaterialType() { return THREE.MeshStandardMaterial; } + /** * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials * @param {number} materialIndex * @return {Promise} */ - - loadMaterial( materialIndex ) { const parser = this; @@ -3003,14 +2784,7 @@ const materialParams = {}; const materialExtensions = materialDef.extensions || {}; const pending = []; - - if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ] ) { - - const sgExtension = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ]; - materialType = sgExtension.getMaterialType(); - pending.push( sgExtension.extendParams( materialParams, materialDef, parser ) ); - - } else if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) { + if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) { const kmuExtension = extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ]; materialType = kmuExtension.getMaterialType(); @@ -3020,10 +2794,10 @@ // Specification: // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#metallic-roughness-material + const metallicRoughness = materialDef.pbrMetallicRoughness || {}; materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 ); materialParams.opacity = 1.0; - if ( Array.isArray( metallicRoughness.baseColorFactor ) ) { const array = metallicRoughness.baseColorFactor; @@ -3040,7 +2814,6 @@ materialParams.metalness = metallicRoughness.metallicFactor !== undefined ? metallicRoughness.metallicFactor : 1.0; materialParams.roughness = metallicRoughness.roughnessFactor !== undefined ? metallicRoughness.roughnessFactor : 1.0; - if ( metallicRoughness.metallicRoughnessTexture !== undefined ) { pending.push( parser.assignTexture( materialParams, 'metalnessMap', metallicRoughness.metallicRoughnessTexture ) ); @@ -3068,17 +2841,16 @@ } const alphaMode = materialDef.alphaMode || ALPHA_MODES.OPAQUE; - if ( alphaMode === ALPHA_MODES.BLEND ) { - materialParams.transparent = true; // See: https://github.com/mrdoob/three.js/issues/17706 + materialParams.transparent = true; + // See: https://github.com/mrdoob/three.js/issues/17706 materialParams.depthWrite = false; } else { materialParams.transparent = false; - if ( alphaMode === ALPHA_MODES.MASK ) { materialParams.alphaTest = materialDef.alphaCutoff !== undefined ? materialDef.alphaCutoff : 0.5; @@ -3091,7 +2863,6 @@ pending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture ) ); materialParams.normalScale = new THREE.Vector2( 1, 1 ); - if ( materialDef.normalTexture.scale !== undefined ) { const scale = materialDef.normalTexture.scale; @@ -3104,7 +2875,6 @@ if ( materialDef.occlusionTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) { pending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture ) ); - if ( materialDef.occlusionTexture.strength !== undefined ) { materialParams.aoMapIntensity = materialDef.occlusionTexture.strength; @@ -3127,18 +2897,7 @@ return Promise.all( pending ).then( function () { - let material; - - if ( materialType === GLTFMeshStandardSGMaterial ) { - - material = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].createMaterial( materialParams ); - - } else { - - material = new materialType( materialParams ); - - } - + const material = new materialType( materialParams ); if ( materialDef.name ) material.name = materialDef.name; assignExtrasToUserData( material, materialDef ); parser.associations.set( material, { @@ -3150,14 +2909,12 @@ } ); } - /** When THREE.Object3D instances are targeted by animation, they need unique names. */ - + /** When THREE.Object3D instances are targeted by animation, they need unique names. */ createUniqueName( originalName ) { const sanitizedName = THREE.PropertyBinding.sanitizeNodeName( originalName || '' ); let name = sanitizedName; - for ( let i = 1; this.nodeNamesUsed[ name ]; ++ i ) { name = sanitizedName + '_' + i; @@ -3168,6 +2925,7 @@ return name; } + /** * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#geometry * @@ -3176,14 +2934,11 @@ * @param {Array} primitives * @return {Promise>} */ - - loadGeometries( primitives ) { const parser = this; const extensions = this.extensions; const cache = this.primitiveCache; - function createDracoPrimitive( primitive ) { return extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ].decodePrimitive( primitive, parser ).then( function ( geometry ) { @@ -3195,14 +2950,13 @@ } const pending = []; - for ( let i = 0, il = primitives.length; i < il; i ++ ) { const primitive = primitives[ i ]; - const cacheKey = createPrimitiveKey( primitive ); // See if we've already created this geometry + const cacheKey = createPrimitiveKey( primitive ); + // See if we've already created this geometry const cached = cache[ cacheKey ]; - if ( cached ) { // Use the cached geometry if it exists @@ -3211,7 +2965,6 @@ } else { let geometryPromise; - if ( primitive.extensions && primitive.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] ) { // Use DRACO geometry if available @@ -3222,9 +2975,9 @@ // Otherwise create a new geometry geometryPromise = addPrimitiveAttributes( new THREE.BufferGeometry(), primitive, parser ); - } // Cache this geometry - + } + // Cache this geometry cache[ cacheKey ] = { primitive: primitive, promise: geometryPromise @@ -3238,13 +2991,12 @@ return Promise.all( pending ); } + /** * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#meshes * @param {number} meshIndex * @return {Promise} */ - - loadMesh( meshIndex ) { const parser = this; @@ -3253,7 +3005,6 @@ const meshDef = json.meshes[ meshIndex ]; const primitives = meshDef.primitives; const pending = []; - for ( let i = 0, il = primitives.length; i < il; i ++ ) { const material = primitives[ i ].material === undefined ? createDefaultMaterial( this.cache ) : this.getDependency( 'material', primitives[ i ].material ); @@ -3267,20 +3018,19 @@ const materials = results.slice( 0, results.length - 1 ); const geometries = results[ results.length - 1 ]; const meshes = []; - for ( let i = 0, il = geometries.length; i < il; i ++ ) { const geometry = geometries[ i ]; - const primitive = primitives[ i ]; // 1. create THREE.Mesh + const primitive = primitives[ i ]; + + // 1. create THREE.Mesh let mesh; const material = materials[ i ]; - if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES || primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP || primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN || primitive.mode === undefined ) { // .isSkinnedMesh isn't in glTF spec. See ._markDefs() mesh = meshDef.isSkinnedMesh === true ? new THREE.SkinnedMesh( geometry, material ) : new THREE.Mesh( geometry, material ); - if ( mesh.isSkinnedMesh === true && ! mesh.geometry.attributes.skinWeight.normalized ) { // we normalize floating point skin weight array to fix malformed assets (see #15319) @@ -3354,7 +3104,6 @@ parser.associations.set( group, { meshes: meshIndex } ); - for ( let i = 0, il = meshes.length; i < il; i ++ ) { group.add( meshes[ i ] ); @@ -3366,19 +3115,17 @@ } ); } + /** * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#cameras * @param {number} cameraIndex * @return {Promise} */ - - loadCamera( cameraIndex ) { let camera; const cameraDef = this.json.cameras[ cameraIndex ]; const params = cameraDef[ cameraDef.type ]; - if ( ! params ) { console.warn( 'THREE.GLTFLoader: Missing camera parameters.' ); @@ -3401,41 +3148,72 @@ return Promise.resolve( camera ); } + /** * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins * @param {number} skinIndex - * @return {Promise} + * @return {Promise} */ - - loadSkin( skinIndex ) { const skinDef = this.json.skins[ skinIndex ]; - const skinEntry = { - joints: skinDef.joints - }; + const pending = []; + for ( let i = 0, il = skinDef.joints.length; i < il; i ++ ) { - if ( skinDef.inverseBindMatrices === undefined ) { + pending.push( this.getDependency( 'node', skinDef.joints[ i ] ) ); - return Promise.resolve( skinEntry ); + } + + if ( skinDef.inverseBindMatrices !== undefined ) { + + pending.push( this.getDependency( 'accessor', skinDef.inverseBindMatrices ) ); + + } else { + + pending.push( null ); } - return this.getDependency( 'accessor', skinDef.inverseBindMatrices ).then( function ( accessor ) { + return Promise.all( pending ).then( function ( results ) { + + const inverseBindMatrices = results.pop(); + const jointNodes = results; + const bones = []; + const boneInverses = []; + for ( let i = 0, il = jointNodes.length; i < il; i ++ ) { + + const jointNode = jointNodes[ i ]; + if ( jointNode ) { + + bones.push( jointNode ); + const mat = new THREE.Matrix4(); + if ( inverseBindMatrices !== null ) { + + mat.fromArray( inverseBindMatrices.array, i * 16 ); + + } + + boneInverses.push( mat ); + + } else { + + console.warn( 'THREE.GLTFLoader: Joint "%s" could not be found.', skinDef.joints[ i ] ); + + } + + } - skinEntry.inverseBindMatrices = accessor; - return skinEntry; + return new THREE.Skeleton( bones, boneInverses ); } ); } + /** * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations * @param {number} animationIndex * @return {Promise} */ - - loadAnimation( animationIndex ) { const json = this.json; @@ -3445,14 +3223,12 @@ const pendingOutputAccessors = []; const pendingSamplers = []; const pendingTargets = []; - for ( let i = 0, il = animationDef.channels.length; i < il; i ++ ) { const channel = animationDef.channels[ i ]; const sampler = animationDef.samplers[ channel.sampler ]; const target = channel.target; - const name = target.node !== undefined ? target.node : target.id; // NOTE: target.id is deprecated. - + const name = target.node; const input = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.input ] : sampler.input; const output = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.output ] : sampler.output; pendingNodes.push( this.getDependency( 'node', name ) ); @@ -3471,7 +3247,6 @@ const samplers = dependencies[ 3 ]; const targets = dependencies[ 4 ]; const tracks = []; - for ( let i = 0, il = nodes.length; i < il; i ++ ) { const node = nodes[ i ]; @@ -3482,17 +3257,14 @@ if ( node === undefined ) continue; node.updateMatrix(); let TypedKeyframeTrack; - switch ( PATH_PROPERTIES[ target.path ] ) { case PATH_PROPERTIES.weights: TypedKeyframeTrack = THREE.NumberKeyframeTrack; break; - case PATH_PROPERTIES.rotation: TypedKeyframeTrack = THREE.QuaternionKeyframeTrack; break; - case PATH_PROPERTIES.position: case PATH_PROPERTIES.scale: default: @@ -3504,7 +3276,6 @@ const targetName = node.name ? node.name : node.uuid; const interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : THREE.InterpolateLinear; const targetNames = []; - if ( PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.weights ) { node.traverse( function ( object ) { @@ -3524,12 +3295,10 @@ } let outputArray = outputAccessor.array; - if ( outputAccessor.normalized ) { const scale = getNormalizedComponentScale( outputArray.constructor ); const scaled = new Float32Array( outputArray.length ); - for ( let j = 0, jl = outputArray.length; j < jl; j ++ ) { scaled[ j ] = outputArray[ j ] * scale; @@ -3542,8 +3311,9 @@ for ( let j = 0, jl = targetNames.length; j < jl; j ++ ) { - const track = new TypedKeyframeTrack( targetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ], inputAccessor.array, outputArray, interpolation ); // Override interpolation with custom factory method. + const track = new TypedKeyframeTrack( targetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ], inputAccessor.array, outputArray, interpolation ); + // Override interpolation with custom factory method. if ( sampler.interpolation === 'CUBICSPLINE' ) { track.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline( result ) { @@ -3551,12 +3321,13 @@ // A CUBICSPLINE keyframe in glTF has three output values for each input value, // representing inTangent, splineVertex, and outTangent. As a result, track.getValueSize() // must be divided by three to get the interpolant's sampleSize argument. + const interpolantType = this instanceof THREE.QuaternionKeyframeTrack ? GLTFCubicSplineQuaternionInterpolant : GLTFCubicSplineInterpolant; return new interpolantType( this.times, this.values, this.getValueSize() / 3, result ); - }; // Mark as CUBICSPLINE. `track.getInterpolation()` doesn't support custom interpolants. - + }; + // Mark as CUBICSPLINE. `track.getInterpolation()` doesn't support custom interpolants. track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true; } @@ -3573,7 +3344,6 @@ } ); } - createNodeMesh( nodeIndex ) { const json = this.json; @@ -3582,15 +3352,14 @@ if ( nodeDef.mesh === undefined ) return null; return parser.getDependency( 'mesh', nodeDef.mesh ).then( function ( mesh ) { - const node = parser._getNodeRef( parser.meshCache, nodeDef.mesh, mesh ); // if weights are provided on the node, override weights on the mesh. - + const node = parser._getNodeRef( parser.meshCache, nodeDef.mesh, mesh ); + // if weights are provided on the node, override weights on the mesh. if ( nodeDef.weights !== undefined ) { node.traverse( function ( o ) { if ( ! o.isMesh ) return; - for ( let i = 0, il = nodeDef.weights.length; i < il; i ++ ) { o.morphTargetInfluences[ i ] = nodeDef.weights[ i ]; @@ -3606,31 +3375,29 @@ } ); } + /** * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#nodes-and-hierarchy * @param {number} nodeIndex * @return {Promise} */ - - loadNode( nodeIndex ) { const json = this.json; const extensions = this.extensions; const parser = this; - const nodeDef = json.nodes[ nodeIndex ]; // reserve node's name before its dependencies, so the root has the intended name. + const nodeDef = json.nodes[ nodeIndex ]; + // reserve node's name before its dependencies, so the root has the intended name. const nodeName = nodeDef.name ? parser.createUniqueName( nodeDef.name ) : ''; return function () { const pending = []; - const meshPromise = parser._invokeOne( function ( ext ) { return ext.createNodeMesh && ext.createNodeMesh( nodeIndex ); } ); - if ( meshPromise ) { pending.push( meshPromise ); @@ -3656,13 +3423,13 @@ pending.push( promise ); } ); - return Promise.all( pending ); }().then( function ( objects ) { - let node; // .isBone isn't in glTF spec. See ._markDefs + let node; + // .isBone isn't in glTF spec. See ._markDefs if ( nodeDef.isBone === true ) { node = new THREE.Bone(); @@ -3700,7 +3467,6 @@ assignExtrasToUserData( node, nodeDef ); if ( nodeDef.extensions ) addUnknownExtensionsToUserData( extensions, node, nodeDef ); - if ( nodeDef.matrix !== undefined ) { const matrix = new THREE.Matrix4(); @@ -3741,28 +3507,27 @@ } ); } + /** * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#scenes * @param {number} sceneIndex * @return {Promise} */ - - loadScene( sceneIndex ) { const json = this.json; const extensions = this.extensions; const sceneDef = this.json.scenes[ sceneIndex ]; - const parser = this; // THREE.Loader returns THREE.Group, not Scene. - // See: https://github.com/mrdoob/three.js/issues/18342#issuecomment-578981172 + const parser = this; + // THREE.Loader returns THREE.Group, not Scene. + // See: https://github.com/mrdoob/three.js/issues/18342#issuecomment-578981172 const scene = new THREE.Group(); if ( sceneDef.name ) scene.name = parser.createUniqueName( sceneDef.name ); assignExtrasToUserData( scene, sceneDef ); if ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef ); const nodeIds = sceneDef.nodes || []; const pending = []; - for ( let i = 0, il = nodeIds.length; i < il; i ++ ) { pending.push( buildNodeHierarchy( nodeIds[ i ], scene, json, parser ) ); @@ -3776,7 +3541,6 @@ const reduceAssociations = node => { const reducedAssociations = new Map(); - for ( const [ key, value ] of parser.associations ) { if ( key instanceof THREE.Material || key instanceof THREE.Texture ) { @@ -3790,7 +3554,6 @@ node.traverse( node => { const mappings = parser.associations.get( node ); - if ( mappings != null ) { reducedAssociations.set( node, mappings ); @@ -3810,62 +3573,21 @@ } } - function buildNodeHierarchy( nodeId, parentObject, json, parser ) { const nodeDef = json.nodes[ nodeId ]; return parser.getDependency( 'node', nodeId ).then( function ( node ) { - if ( nodeDef.skin === undefined ) return node; // build skeleton here as well + if ( nodeDef.skin === undefined ) return node; - let skinEntry; - return parser.getDependency( 'skin', nodeDef.skin ).then( function ( skin ) { + // build skeleton here as well - skinEntry = skin; - const pendingJoints = []; - - for ( let i = 0, il = skinEntry.joints.length; i < il; i ++ ) { - - pendingJoints.push( parser.getDependency( 'node', skinEntry.joints[ i ] ) ); - - } - - return Promise.all( pendingJoints ); - - } ).then( function ( jointNodes ) { + return parser.getDependency( 'skin', nodeDef.skin ).then( function ( skeleton ) { node.traverse( function ( mesh ) { - if ( ! mesh.isMesh ) return; - const bones = []; - const boneInverses = []; - - for ( let j = 0, jl = jointNodes.length; j < jl; j ++ ) { - - const jointNode = jointNodes[ j ]; - - if ( jointNode ) { - - bones.push( jointNode ); - const mat = new THREE.Matrix4(); - - if ( skinEntry.inverseBindMatrices !== undefined ) { - - mat.fromArray( skinEntry.inverseBindMatrices.array, j * 16 ); - - } - - boneInverses.push( mat ); - - } else { - - console.warn( 'THREE.GLTFLoader: Joint "%s" could not be found.', skinEntry.joints[ j ] ); - - } - - } - - mesh.bind( new THREE.Skeleton( bones, boneInverses ), mesh.matrixWorld ); + if ( ! mesh.isSkinnedMesh ) return; + mesh.bind( skeleton, mesh.matrixWorld ); } ); return node; @@ -3875,13 +3597,12 @@ } ).then( function ( node ) { // build node hierachy + parentObject.add( node ); const pending = []; - if ( nodeDef.children ) { const children = nodeDef.children; - for ( let i = 0, il = children.length; i < il; i ++ ) { const child = children[ i ]; @@ -3896,28 +3617,27 @@ } ); } + /** * @param {BufferGeometry} geometry * @param {GLTF.Primitive} primitiveDef * @param {GLTFParser} parser */ - - function computeBounds( geometry, primitiveDef, parser ) { const attributes = primitiveDef.attributes; const box = new THREE.Box3(); - if ( attributes.POSITION !== undefined ) { const accessor = parser.json.accessors[ attributes.POSITION ]; const min = accessor.min; - const max = accessor.max; // glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement. + const max = accessor.max; + + // glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement. if ( min !== undefined && max !== undefined ) { box.set( new THREE.Vector3( min[ 0 ], min[ 1 ], min[ 2 ] ), new THREE.Vector3( max[ 0 ], max[ 1 ], max[ 2 ] ) ); - if ( accessor.normalized ) { const boxScale = getNormalizedComponentScale( WEBGL_COMPONENT_TYPES[ accessor.componentType ] ); @@ -3940,21 +3660,20 @@ } const targets = primitiveDef.targets; - if ( targets !== undefined ) { const maxDisplacement = new THREE.Vector3(); const vector = new THREE.Vector3(); - for ( let i = 0, il = targets.length; i < il; i ++ ) { const target = targets[ i ]; - if ( target.POSITION !== undefined ) { const accessor = parser.json.accessors[ target.POSITION ]; const min = accessor.min; - const max = accessor.max; // glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement. + const max = accessor.max; + + // glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement. if ( min !== undefined && max !== undefined ) { @@ -3962,18 +3681,17 @@ vector.setX( Math.max( Math.abs( min[ 0 ] ), Math.abs( max[ 0 ] ) ) ); vector.setY( Math.max( Math.abs( min[ 1 ] ), Math.abs( max[ 1 ] ) ) ); vector.setZ( Math.max( Math.abs( min[ 2 ] ), Math.abs( max[ 2 ] ) ) ); - if ( accessor.normalized ) { const boxScale = getNormalizedComponentScale( WEBGL_COMPONENT_TYPES[ accessor.componentType ] ); vector.multiplyScalar( boxScale ); - } // Note: this assumes that the sum of all weights is at most 1. This isn't quite correct - it's more conservative + } + + // Note: this assumes that the sum of all weights is at most 1. This isn't quite correct - it's more conservative // to assume that each target can have a max weight of 1. However, for some use cases - notably, when morph targets // are used to implement key-frame animations and as such only two are active at a time - this results in very large // boxes. So for now we make a box that's sometimes a touch too small but is hopefully mostly of reasonable size. - - maxDisplacement.max( vector ); } else { @@ -3984,9 +3702,9 @@ } - } // As per comment above this box isn't conservative, but has a reasonable size for a very large number of morph targets. - + } + // As per comment above this box isn't conservative, but has a reasonable size for a very large number of morph targets. box.expandByVector( maxDisplacement ); } @@ -3998,19 +3716,17 @@ geometry.boundingSphere = sphere; } + /** * @param {BufferGeometry} geometry * @param {GLTF.Primitive} primitiveDef * @param {GLTFParser} parser * @return {Promise} */ - - function addPrimitiveAttributes( geometry, primitiveDef, parser ) { const attributes = primitiveDef.attributes; const pending = []; - function assignAttributeAccessor( accessorIndex, attributeName ) { return parser.getDependency( 'accessor', accessorIndex ).then( function ( accessor ) { @@ -4023,8 +3739,9 @@ for ( const gltfAttributeName in attributes ) { - const threeAttributeName = ATTRIBUTES[ gltfAttributeName ] || gltfAttributeName.toLowerCase(); // Skip attributes already provided by e.g. Draco extension. + const threeAttributeName = ATTRIBUTES[ gltfAttributeName ] || gltfAttributeName.toLowerCase(); + // Skip attributes already provided by e.g. Draco extension. if ( threeAttributeName in geometry.attributes ) continue; pending.push( assignAttributeAccessor( attributes[ gltfAttributeName ], threeAttributeName ) ); @@ -4050,22 +3767,22 @@ } ); } + /** * @param {BufferGeometry} geometry * @param {Number} drawMode * @return {BufferGeometry} */ - - function toTrianglesDrawMode( geometry, drawMode ) { - let index = geometry.getIndex(); // generate index if not present + let index = geometry.getIndex(); + + // generate index if not present if ( index === null ) { const indices = []; const position = geometry.getAttribute( 'position' ); - if ( position !== undefined ) { for ( let i = 0; i < position.count; i ++ ) { @@ -4084,15 +3801,16 @@ } - } // + } + // const numberOfTriangles = index.count - 2; const newIndices = []; - if ( drawMode === THREE.TriangleFanDrawMode ) { // gl.TRIANGLE_FAN + for ( let i = 1; i <= numberOfTriangles; i ++ ) { newIndices.push( index.getX( 0 ) ); @@ -4104,6 +3822,7 @@ } else { // gl.TRIANGLE_STRIP + for ( let i = 0; i < numberOfTriangles; i ++ ) { if ( i % 2 === 0 ) { @@ -4128,8 +3847,9 @@ console.error( 'THREE.GLTFLoader.toTrianglesDrawMode(): Unable to generate correct amount of triangles.' ); - } // build final geometry + } + // build final geometry const newGeometry = geometry.clone(); newGeometry.setIndex( newIndices ); diff --git a/examples/js/loaders/HDRCubeTextureLoader.js b/examples/js/loaders/HDRCubeTextureLoader.js index 7a4e0bb4461e8e..cad8f8385b43fc 100644 --- a/examples/js/loaders/HDRCubeTextureLoader.js +++ b/examples/js/loaders/HDRCubeTextureLoader.js @@ -9,23 +9,10 @@ this.type = THREE.HalfFloatType; } - load( urls, onLoad, onProgress, onError ) { - if ( ! Array.isArray( urls ) ) { - - console.warn( 'THREE.HDRCubeTextureLoader signature has changed. Use .setDataType() instead.' ); - this.setDataType( urls ); - urls = onLoad; - onLoad = onProgress; - onProgress = onError; - onError = arguments[ 4 ]; - - } - const texture = new THREE.CubeTexture(); texture.type = this.type; - switch ( texture.type ) { case THREE.FloatType: @@ -34,7 +21,6 @@ texture.magFilter = THREE.LinearFilter; texture.generateMipmaps = false; break; - case THREE.HalfFloatType: texture.encoding = THREE.LinearEncoding; texture.minFilter = THREE.LinearFilter; @@ -46,7 +32,6 @@ const scope = this; let loaded = 0; - function loadHDRData( i, onLoad, onProgress, onError ) { new THREE.FileLoader( scope.manager ).setPath( scope.path ).setResponseType( 'arraybuffer' ).setWithCredentials( scope.withCredentials ).load( urls[ i ], function ( buffer ) { @@ -54,7 +39,6 @@ loaded ++; const texData = scope.hdrLoader.parse( buffer ); if ( ! texData ) return; - if ( texData.data !== undefined ) { const dataTexture = new THREE.DataTexture( texData.data, texData.width, texData.height ); @@ -88,7 +72,6 @@ return texture; } - setDataType( value ) { this.type = value; diff --git a/examples/js/loaders/KMZLoader.js b/examples/js/loaders/KMZLoader.js index 1a5adbfa0e5802..4672df50ebcfb6 100644 --- a/examples/js/loaders/KMZLoader.js +++ b/examples/js/loaders/KMZLoader.js @@ -7,7 +7,6 @@ super( manager ); } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -41,7 +40,6 @@ }, onProgress, onError ); } - parse( data ) { function findFile( url ) { @@ -62,7 +60,6 @@ manager.setURLModifier( function ( url ) { const image = findFile( url ); - if ( image ) { console.log( 'Loading', url ); @@ -75,7 +72,9 @@ return url; - } ); // + } ); + + // const zip = fflate.unzipSync( new Uint8Array( data ) ); // eslint-disable-line no-undef @@ -84,7 +83,6 @@ const xml = new DOMParser().parseFromString( fflate.strFromU8( zip[ 'doc.kml' ] ), 'application/xml' ); // eslint-disable-line no-undef const model = xml.querySelector( 'Placemark Model Link href' ); - if ( model ) { const loader = new THREE.ColladaLoader( manager ); @@ -95,11 +93,9 @@ } else { console.warn( 'KMZLoader: Missing doc.kml file.' ); - for ( const path in zip ) { const extension = path.split( '.' ).pop().toLowerCase(); - if ( extension === 'dae' ) { const loader = new THREE.ColladaLoader( manager ); diff --git a/examples/js/loaders/KTX2Loader.js b/examples/js/loaders/KTX2Loader.js deleted file mode 100644 index 78299f5742cb6f..00000000000000 --- a/examples/js/loaders/KTX2Loader.js +++ /dev/null @@ -1,655 +0,0 @@ -( function () { - - /** - * THREE.Loader for KTX 2.0 GPU Texture containers. - * - * KTX 2.0 is a container format for various GPU texture formats. The loader - * supports Basis Universal GPU textures, which can be quickly transcoded to - * a wide variety of GPU texture compression formats, as well as some - * uncompressed THREE.DataTexture and THREE.Data3DTexture formats. - * - * References: - * - KTX: http://github.khronos.org/KTX-Specification/ - * - DFD: https://www.khronos.org/registry/DataFormat/specs/1.3/dataformat.1.3.html#basicdescriptor - */ - const { - read, - KHR_DF_FLAG_ALPHA_PREMULTIPLIED, - KHR_DF_TRANSFER_SRGB, - VK_FORMAT_UNDEFINED, - VK_FORMAT_R16_SFLOAT, - VK_FORMAT_R16G16_SFLOAT, - VK_FORMAT_R16G16B16A16_SFLOAT, - VK_FORMAT_R32_SFLOAT, - VK_FORMAT_R32G32_SFLOAT, - VK_FORMAT_R32G32B32A32_SFLOAT, - VK_FORMAT_R8_SRGB, - VK_FORMAT_R8_UNORM, - VK_FORMAT_R8G8_SRGB, - VK_FORMAT_R8G8_UNORM, - VK_FORMAT_R8G8B8A8_SRGB, - VK_FORMAT_R8G8B8A8_UNORM - } = KTX; // eslint-disable-line no-undef - - const _taskCache = new WeakMap(); - - let _activeLoaders = 0; - - class KTX2Loader extends THREE.Loader { - - constructor( manager ) { - - super( manager ); - this.transcoderPath = ''; - this.transcoderBinary = null; - this.transcoderPending = null; - this.workerPool = new THREE.WorkerPool(); - this.workerSourceURL = ''; - this.workerConfig = null; - - if ( typeof MSC_TRANSCODER !== 'undefined' ) { - - console.warn( 'THREE.KTX2Loader: Please update to latest "basis_transcoder".' + ' "msc_basis_transcoder" is no longer supported in three.js r125+.' ); - - } - - } - - setTranscoderPath( path ) { - - this.transcoderPath = path; - return this; - - } - - setWorkerLimit( num ) { - - this.workerPool.setWorkerLimit( num ); - return this; - - } - - detectSupport( renderer ) { - - this.workerConfig = { - astcSupported: renderer.extensions.has( 'WEBGL_compressed_texture_astc' ), - etc1Supported: renderer.extensions.has( 'WEBGL_compressed_texture_etc1' ), - etc2Supported: renderer.extensions.has( 'WEBGL_compressed_texture_etc' ), - dxtSupported: renderer.extensions.has( 'WEBGL_compressed_texture_s3tc' ), - bptcSupported: renderer.extensions.has( 'EXT_texture_compression_bptc' ), - pvrtcSupported: renderer.extensions.has( 'WEBGL_compressed_texture_pvrtc' ) || renderer.extensions.has( 'WEBKIT_WEBGL_compressed_texture_pvrtc' ) - }; - - if ( renderer.capabilities.isWebGL2 ) { - - // https://github.com/mrdoob/three.js/pull/22928 - this.workerConfig.etc1Supported = false; - - } - - return this; - - } - - init() { - - if ( ! this.transcoderPending ) { - - // Load transcoder wrapper. - const jsLoader = new THREE.FileLoader( this.manager ); - jsLoader.setPath( this.transcoderPath ); - jsLoader.setWithCredentials( this.withCredentials ); - const jsContent = jsLoader.loadAsync( 'basis_transcoder.js' ); // Load transcoder WASM binary. - - const binaryLoader = new THREE.FileLoader( this.manager ); - binaryLoader.setPath( this.transcoderPath ); - binaryLoader.setResponseType( 'arraybuffer' ); - binaryLoader.setWithCredentials( this.withCredentials ); - const binaryContent = binaryLoader.loadAsync( 'basis_transcoder.wasm' ); - this.transcoderPending = Promise.all( [ jsContent, binaryContent ] ).then( ( [ jsContent, binaryContent ] ) => { - - const fn = KTX2Loader.BasisWorker.toString(); - const body = [ '/* constants */', 'let _EngineFormat = ' + JSON.stringify( KTX2Loader.EngineFormat ), 'let _TranscoderFormat = ' + JSON.stringify( KTX2Loader.TranscoderFormat ), 'let _BasisFormat = ' + JSON.stringify( KTX2Loader.BasisFormat ), '/* basis_transcoder.js */', jsContent, '/* worker */', fn.substring( fn.indexOf( '{' ) + 1, fn.lastIndexOf( '}' ) ) ].join( '\n' ); - this.workerSourceURL = URL.createObjectURL( new Blob( [ body ] ) ); - this.transcoderBinary = binaryContent; - this.workerPool.setWorkerCreator( () => { - - const worker = new Worker( this.workerSourceURL ); - const transcoderBinary = this.transcoderBinary.slice( 0 ); - worker.postMessage( { - type: 'init', - config: this.workerConfig, - transcoderBinary - }, [ transcoderBinary ] ); - return worker; - - } ); - - } ); - - if ( _activeLoaders > 0 ) { - - // Each instance loads a transcoder and allocates workers, increasing network and memory cost. - console.warn( 'THREE.KTX2Loader: Multiple active KTX2 loaders may cause performance issues.' + ' Use a single KTX2Loader instance, or call .dispose() on old instances.' ); - - } - - _activeLoaders ++; - - } - - return this.transcoderPending; - - } - - load( url, onLoad, onProgress, onError ) { - - if ( this.workerConfig === null ) { - - throw new Error( 'THREE.KTX2Loader: Missing initialization with `.detectSupport( renderer )`.' ); - - } - - const loader = new THREE.FileLoader( this.manager ); - loader.setResponseType( 'arraybuffer' ); - loader.setWithCredentials( this.withCredentials ); - loader.load( url, buffer => { - - // Check for an existing task using this buffer. A transferred buffer cannot be transferred - // again from this thread. - if ( _taskCache.has( buffer ) ) { - - const cachedTask = _taskCache.get( buffer ); - - return cachedTask.promise.then( onLoad ).catch( onError ); - - } - - this._createTexture( buffer ).then( texture => onLoad ? onLoad( texture ) : null ).catch( onError ); - - }, onProgress, onError ); - - } - - _createTextureFrom( transcodeResult ) { - - const { - mipmaps, - width, - height, - format, - type, - error, - dfdTransferFn, - dfdFlags - } = transcodeResult; - if ( type === 'error' ) return Promise.reject( error ); - const texture = new THREE.CompressedTexture( mipmaps, width, height, format, THREE.UnsignedByteType ); - texture.minFilter = mipmaps.length === 1 ? THREE.LinearFilter : THREE.LinearMipmapLinearFilter; - texture.magFilter = THREE.LinearFilter; - texture.generateMipmaps = false; - texture.needsUpdate = true; - texture.encoding = dfdTransferFn === KHR_DF_TRANSFER_SRGB ? THREE.sRGBEncoding : THREE.LinearEncoding; - texture.premultiplyAlpha = !! ( dfdFlags & KHR_DF_FLAG_ALPHA_PREMULTIPLIED ); - return texture; - - } - /** - * @param {ArrayBuffer} buffer - * @param {object?} config - * @return {Promise} - */ - - - _createTexture( buffer, config = {} ) { - - const container = read( new Uint8Array( buffer ) ); - - if ( container.vkFormat !== VK_FORMAT_UNDEFINED ) { - - return createDataTexture( container ); - - } // - - - const taskConfig = config; - const texturePending = this.init().then( () => { - - return this.workerPool.postMessage( { - type: 'transcode', - buffer, - taskConfig: taskConfig - }, [ buffer ] ); - - } ).then( e => this._createTextureFrom( e.data ) ); // Cache the task result. - - _taskCache.set( buffer, { - promise: texturePending - } ); - - return texturePending; - - } - - dispose() { - - this.workerPool.dispose(); - if ( this.workerSourceURL ) URL.revokeObjectURL( this.workerSourceURL ); - _activeLoaders --; - return this; - - } - - } - /* CONSTANTS */ - - - KTX2Loader.BasisFormat = { - ETC1S: 0, - UASTC_4x4: 1 - }; - KTX2Loader.TranscoderFormat = { - ETC1: 0, - ETC2: 1, - BC1: 2, - BC3: 3, - BC4: 4, - BC5: 5, - BC7_M6_OPAQUE_ONLY: 6, - BC7_M5: 7, - PVRTC1_4_RGB: 8, - PVRTC1_4_RGBA: 9, - ASTC_4x4: 10, - ATC_RGB: 11, - ATC_RGBA_INTERPOLATED_ALPHA: 12, - RGBA32: 13, - RGB565: 14, - BGR565: 15, - RGBA4444: 16 - }; - KTX2Loader.EngineFormat = { - RGBAFormat: THREE.RGBAFormat, - RGBA_ASTC_4x4_Format: THREE.RGBA_ASTC_4x4_Format, - RGBA_BPTC_Format: THREE.RGBA_BPTC_Format, - RGBA_ETC2_EAC_Format: THREE.RGBA_ETC2_EAC_Format, - RGBA_PVRTC_4BPPV1_Format: THREE.RGBA_PVRTC_4BPPV1_Format, - RGBA_S3TC_DXT5_Format: THREE.RGBA_S3TC_DXT5_Format, - RGB_ETC1_Format: THREE.RGB_ETC1_Format, - RGB_ETC2_Format: THREE.RGB_ETC2_Format, - RGB_PVRTC_4BPPV1_Format: THREE.RGB_PVRTC_4BPPV1_Format, - RGB_S3TC_DXT1_Format: THREE.RGB_S3TC_DXT1_Format - }; - /* WEB WORKER */ - - KTX2Loader.BasisWorker = function () { - - let config; - let transcoderPending; - let BasisModule; - const EngineFormat = _EngineFormat; // eslint-disable-line no-undef - - const TranscoderFormat = _TranscoderFormat; // eslint-disable-line no-undef - - const BasisFormat = _BasisFormat; // eslint-disable-line no-undef - - self.addEventListener( 'message', function ( e ) { - - const message = e.data; - - switch ( message.type ) { - - case 'init': - config = message.config; - init( message.transcoderBinary ); - break; - - case 'transcode': - transcoderPending.then( () => { - - try { - - const { - width, - height, - hasAlpha, - mipmaps, - format, - dfdTransferFn, - dfdFlags - } = transcode( message.buffer ); - const buffers = []; - - for ( let i = 0; i < mipmaps.length; ++ i ) { - - buffers.push( mipmaps[ i ].data.buffer ); - - } - - self.postMessage( { - type: 'transcode', - id: message.id, - width, - height, - hasAlpha, - mipmaps, - format, - dfdTransferFn, - dfdFlags - }, buffers ); - - } catch ( error ) { - - console.error( error ); - self.postMessage( { - type: 'error', - id: message.id, - error: error.message - } ); - - } - - } ); - break; - - } - - } ); - - function init( wasmBinary ) { - - transcoderPending = new Promise( resolve => { - - BasisModule = { - wasmBinary, - onRuntimeInitialized: resolve - }; - BASIS( BasisModule ); // eslint-disable-line no-undef - - } ).then( () => { - - BasisModule.initializeBasis(); - - if ( BasisModule.KTX2File === undefined ) { - - console.warn( 'THREE.KTX2Loader: Please update Basis Universal transcoder.' ); - - } - - } ); - - } - - function transcode( buffer ) { - - const ktx2File = new BasisModule.KTX2File( new Uint8Array( buffer ) ); - - function cleanup() { - - ktx2File.close(); - ktx2File.delete(); - - } - - if ( ! ktx2File.isValid() ) { - - cleanup(); - throw new Error( 'THREE.KTX2Loader: Invalid or unsupported .ktx2 file' ); - - } - - const basisFormat = ktx2File.isUASTC() ? BasisFormat.UASTC_4x4 : BasisFormat.ETC1S; - const width = ktx2File.getWidth(); - const height = ktx2File.getHeight(); - const levels = ktx2File.getLevels(); - const hasAlpha = ktx2File.getHasAlpha(); - const dfdTransferFn = ktx2File.getDFDTransferFunc(); - const dfdFlags = ktx2File.getDFDFlags(); - const { - transcoderFormat, - engineFormat - } = getTranscoderFormat( basisFormat, width, height, hasAlpha ); - - if ( ! width || ! height || ! levels ) { - - cleanup(); - throw new Error( 'THREE.KTX2Loader: Invalid texture' ); - - } - - if ( ! ktx2File.startTranscoding() ) { - - cleanup(); - throw new Error( 'THREE.KTX2Loader: .startTranscoding failed' ); - - } - - const mipmaps = []; - - for ( let mip = 0; mip < levels; mip ++ ) { - - const levelInfo = ktx2File.getImageLevelInfo( mip, 0, 0 ); - const mipWidth = levelInfo.origWidth; - const mipHeight = levelInfo.origHeight; - const dst = new Uint8Array( ktx2File.getImageTranscodedSizeInBytes( mip, 0, 0, transcoderFormat ) ); - const status = ktx2File.transcodeImage( dst, mip, 0, 0, transcoderFormat, 0, - 1, - 1 ); - - if ( ! status ) { - - cleanup(); - throw new Error( 'THREE.KTX2Loader: .transcodeImage failed.' ); - - } - - mipmaps.push( { - data: dst, - width: mipWidth, - height: mipHeight - } ); - - } - - cleanup(); - return { - width, - height, - hasAlpha, - mipmaps, - format: engineFormat, - dfdTransferFn, - dfdFlags - }; - - } // - // Optimal choice of a transcoder target format depends on the Basis format (ETC1S or UASTC), - // device capabilities, and texture dimensions. The list below ranks the formats separately - // for ETC1S and UASTC. - // - // In some cases, transcoding UASTC to RGBA32 might be preferred for higher quality (at - // significant memory cost) compared to ETC1/2, BC1/3, and PVRTC. The transcoder currently - // chooses RGBA32 only as a last resort and does not expose that option to the caller. - - - const FORMAT_OPTIONS = [ { - if: 'astcSupported', - basisFormat: [ BasisFormat.UASTC_4x4 ], - transcoderFormat: [ TranscoderFormat.ASTC_4x4, TranscoderFormat.ASTC_4x4 ], - engineFormat: [ EngineFormat.RGBA_ASTC_4x4_Format, EngineFormat.RGBA_ASTC_4x4_Format ], - priorityETC1S: Infinity, - priorityUASTC: 1, - needsPowerOfTwo: false - }, { - if: 'bptcSupported', - basisFormat: [ BasisFormat.ETC1S, BasisFormat.UASTC_4x4 ], - transcoderFormat: [ TranscoderFormat.BC7_M5, TranscoderFormat.BC7_M5 ], - engineFormat: [ EngineFormat.RGBA_BPTC_Format, EngineFormat.RGBA_BPTC_Format ], - priorityETC1S: 3, - priorityUASTC: 2, - needsPowerOfTwo: false - }, { - if: 'dxtSupported', - basisFormat: [ BasisFormat.ETC1S, BasisFormat.UASTC_4x4 ], - transcoderFormat: [ TranscoderFormat.BC1, TranscoderFormat.BC3 ], - engineFormat: [ EngineFormat.RGB_S3TC_DXT1_Format, EngineFormat.RGBA_S3TC_DXT5_Format ], - priorityETC1S: 4, - priorityUASTC: 5, - needsPowerOfTwo: false - }, { - if: 'etc2Supported', - basisFormat: [ BasisFormat.ETC1S, BasisFormat.UASTC_4x4 ], - transcoderFormat: [ TranscoderFormat.ETC1, TranscoderFormat.ETC2 ], - engineFormat: [ EngineFormat.RGB_ETC2_Format, EngineFormat.RGBA_ETC2_EAC_Format ], - priorityETC1S: 1, - priorityUASTC: 3, - needsPowerOfTwo: false - }, { - if: 'etc1Supported', - basisFormat: [ BasisFormat.ETC1S, BasisFormat.UASTC_4x4 ], - transcoderFormat: [ TranscoderFormat.ETC1 ], - engineFormat: [ EngineFormat.RGB_ETC1_Format ], - priorityETC1S: 2, - priorityUASTC: 4, - needsPowerOfTwo: false - }, { - if: 'pvrtcSupported', - basisFormat: [ BasisFormat.ETC1S, BasisFormat.UASTC_4x4 ], - transcoderFormat: [ TranscoderFormat.PVRTC1_4_RGB, TranscoderFormat.PVRTC1_4_RGBA ], - engineFormat: [ EngineFormat.RGB_PVRTC_4BPPV1_Format, EngineFormat.RGBA_PVRTC_4BPPV1_Format ], - priorityETC1S: 5, - priorityUASTC: 6, - needsPowerOfTwo: true - } ]; - const ETC1S_OPTIONS = FORMAT_OPTIONS.sort( function ( a, b ) { - - return a.priorityETC1S - b.priorityETC1S; - - } ); - const UASTC_OPTIONS = FORMAT_OPTIONS.sort( function ( a, b ) { - - return a.priorityUASTC - b.priorityUASTC; - - } ); - - function getTranscoderFormat( basisFormat, width, height, hasAlpha ) { - - let transcoderFormat; - let engineFormat; - const options = basisFormat === BasisFormat.ETC1S ? ETC1S_OPTIONS : UASTC_OPTIONS; - - for ( let i = 0; i < options.length; i ++ ) { - - const opt = options[ i ]; - if ( ! config[ opt.if ] ) continue; - if ( ! opt.basisFormat.includes( basisFormat ) ) continue; - if ( hasAlpha && opt.transcoderFormat.length < 2 ) continue; - if ( opt.needsPowerOfTwo && ! ( isPowerOfTwo( width ) && isPowerOfTwo( height ) ) ) continue; - transcoderFormat = opt.transcoderFormat[ hasAlpha ? 1 : 0 ]; - engineFormat = opt.engineFormat[ hasAlpha ? 1 : 0 ]; - return { - transcoderFormat, - engineFormat - }; - - } - - console.warn( 'THREE.KTX2Loader: No suitable compressed texture format found. Decoding to RGBA32.' ); - transcoderFormat = TranscoderFormat.RGBA32; - engineFormat = EngineFormat.RGBAFormat; - return { - transcoderFormat, - engineFormat - }; - - } - - function isPowerOfTwo( value ) { - - if ( value <= 2 ) return true; - return ( value & value - 1 ) === 0 && value !== 0; - - } - - }; // - // THREE.DataTexture and THREE.Data3DTexture parsing. - - - const FORMAT_MAP = { - [ VK_FORMAT_R32G32B32A32_SFLOAT ]: THREE.RGBAFormat, - [ VK_FORMAT_R16G16B16A16_SFLOAT ]: THREE.RGBAFormat, - [ VK_FORMAT_R8G8B8A8_UNORM ]: THREE.RGBAFormat, - [ VK_FORMAT_R8G8B8A8_SRGB ]: THREE.RGBAFormat, - [ VK_FORMAT_R32G32_SFLOAT ]: THREE.RGFormat, - [ VK_FORMAT_R16G16_SFLOAT ]: THREE.RGFormat, - [ VK_FORMAT_R8G8_UNORM ]: THREE.RGFormat, - [ VK_FORMAT_R8G8_SRGB ]: THREE.RGFormat, - [ VK_FORMAT_R32_SFLOAT ]: THREE.RedFormat, - [ VK_FORMAT_R16_SFLOAT ]: THREE.RedFormat, - [ VK_FORMAT_R8_SRGB ]: THREE.RedFormat, - [ VK_FORMAT_R8_UNORM ]: THREE.RedFormat - }; - const TYPE_MAP = { - [ VK_FORMAT_R32G32B32A32_SFLOAT ]: THREE.FloatType, - [ VK_FORMAT_R16G16B16A16_SFLOAT ]: THREE.HalfFloatType, - [ VK_FORMAT_R8G8B8A8_UNORM ]: THREE.UnsignedByteType, - [ VK_FORMAT_R8G8B8A8_SRGB ]: THREE.UnsignedByteType, - [ VK_FORMAT_R32G32_SFLOAT ]: THREE.FloatType, - [ VK_FORMAT_R16G16_SFLOAT ]: THREE.HalfFloatType, - [ VK_FORMAT_R8G8_UNORM ]: THREE.UnsignedByteType, - [ VK_FORMAT_R8G8_SRGB ]: THREE.UnsignedByteType, - [ VK_FORMAT_R32_SFLOAT ]: THREE.FloatType, - [ VK_FORMAT_R16_SFLOAT ]: THREE.HalfFloatType, - [ VK_FORMAT_R8_SRGB ]: THREE.UnsignedByteType, - [ VK_FORMAT_R8_UNORM ]: THREE.UnsignedByteType - }; - const ENCODING_MAP = { - [ VK_FORMAT_R8G8B8A8_SRGB ]: THREE.sRGBEncoding, - [ VK_FORMAT_R8G8_SRGB ]: THREE.sRGBEncoding, - [ VK_FORMAT_R8_SRGB ]: THREE.sRGBEncoding - }; - - function createDataTexture( container ) { - - const { - vkFormat, - pixelWidth, - pixelHeight, - pixelDepth - } = container; - - if ( FORMAT_MAP[ vkFormat ] === undefined ) { - - throw new Error( 'THREE.KTX2Loader: Unsupported vkFormat.' ); - - } // - - - let view; - const levelData = container.levels[ 0 ].levelData; - - if ( TYPE_MAP[ vkFormat ] === THREE.FloatType ) { - - view = new Float32Array( levelData.buffer, levelData.byteOffset, levelData.byteLength / Float32Array.BYTES_PER_ELEMENT ); - - } else if ( TYPE_MAP[ vkFormat ] === THREE.HalfFloatType ) { - - view = new Uint16Array( levelData.buffer, levelData.byteOffset, levelData.byteLength / Uint16Array.BYTES_PER_ELEMENT ); - - } else { - - view = levelData; - - } // - - - const texture = pixelDepth === 0 ? new THREE.DataTexture( view, pixelWidth, pixelHeight ) : new THREE.Data3DTexture( view, pixelWidth, pixelHeight, pixelDepth ); - texture.type = TYPE_MAP[ vkFormat ]; - texture.format = FORMAT_MAP[ vkFormat ]; - texture.encoding = ENCODING_MAP[ vkFormat ] || THREE.LinearEncoding; - texture.needsUpdate = true; // - - return Promise.resolve( texture ); - - } - - THREE.KTX2Loader = KTX2Loader; - -} )(); diff --git a/examples/js/loaders/KTXLoader.js b/examples/js/loaders/KTXLoader.js index 598d9a8ce20007..c32f8630dc920b 100644 --- a/examples/js/loaders/KTXLoader.js +++ b/examples/js/loaders/KTXLoader.js @@ -14,7 +14,6 @@ super( manager ); } - parse( buffer, loadMipmaps ) { const ktx = new KhronosTextureContainer( buffer, 1 ); @@ -30,10 +29,8 @@ } } - const HEADER_LEN = 12 + 13 * 4; // identifier + header elements (not including key value meta-data pairs) // load types - const COMPRESSED_2D = 0; // uses a gl.compressedTexImage2D() //const COMPRESSED_3D = 1; // uses a gl.compressedTexImage3D() //const TEX_2D = 2; // uses a gl.texImage2D() @@ -47,53 +44,40 @@ * @param {boolean} threeDExpected- provision for indicating that data should be a 3D texture, not implemented * @param {boolean} textureArrayExpected- provision for indicating that data should be a texture array, not implemented */ - constructor( arrayBuffer, facesExpected - /*, threeDExpected, textureArrayExpected */ - ) { + constructor( arrayBuffer, facesExpected /*, threeDExpected, textureArrayExpected */ ) { + + this.arrayBuffer = arrayBuffer; - this.arrayBuffer = arrayBuffer; // Test that it is a ktx formatted file, based on the first 12 bytes, character representation is: + // Test that it is a ktx formatted file, based on the first 12 bytes, character representation is: // '´', 'K', 'T', 'X', ' ', '1', '1', 'ª', '\r', '\n', '\x1A', '\n' // 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A - const identifier = new Uint8Array( this.arrayBuffer, 0, 12 ); - if ( identifier[ 0 ] !== 0xAB || identifier[ 1 ] !== 0x4B || identifier[ 2 ] !== 0x54 || identifier[ 3 ] !== 0x58 || identifier[ 4 ] !== 0x20 || identifier[ 5 ] !== 0x31 || identifier[ 6 ] !== 0x31 || identifier[ 7 ] !== 0xBB || identifier[ 8 ] !== 0x0D || identifier[ 9 ] !== 0x0A || identifier[ 10 ] !== 0x1A || identifier[ 11 ] !== 0x0A ) { console.error( 'texture missing KTX identifier' ); return; - } // load the reset of the header in native 32 bit uint - + } + // load the reset of the header in native 32 bit uint const dataSize = Uint32Array.BYTES_PER_ELEMENT; const headerDataView = new DataView( this.arrayBuffer, 12, 13 * dataSize ); const endianness = headerDataView.getUint32( 0, true ); const littleEndian = endianness === 0x04030201; this.glType = headerDataView.getUint32( 1 * dataSize, littleEndian ); // must be 0 for compressed textures - this.glTypeSize = headerDataView.getUint32( 2 * dataSize, littleEndian ); // must be 1 for compressed textures - this.glFormat = headerDataView.getUint32( 3 * dataSize, littleEndian ); // must be 0 for compressed textures - this.glInternalFormat = headerDataView.getUint32( 4 * dataSize, littleEndian ); // the value of arg passed to gl.compressedTexImage2D(,,x,,,,) - this.glBaseInternalFormat = headerDataView.getUint32( 5 * dataSize, littleEndian ); // specify GL_RGB, GL_RGBA, GL_ALPHA, etc (un-compressed only) - this.pixelWidth = headerDataView.getUint32( 6 * dataSize, littleEndian ); // level 0 value of arg passed to gl.compressedTexImage2D(,,,x,,,) - this.pixelHeight = headerDataView.getUint32( 7 * dataSize, littleEndian ); // level 0 value of arg passed to gl.compressedTexImage2D(,,,,x,,) - this.pixelDepth = headerDataView.getUint32( 8 * dataSize, littleEndian ); // level 0 value of arg passed to gl.compressedTexImage3D(,,,,,x,,) - this.numberOfArrayElements = headerDataView.getUint32( 9 * dataSize, littleEndian ); // used for texture arrays - this.numberOfFaces = headerDataView.getUint32( 10 * dataSize, littleEndian ); // used for cubemap textures, should either be 1 or 6 - this.numberOfMipmapLevels = headerDataView.getUint32( 11 * dataSize, littleEndian ); // number of levels; disregard possibility of 0 for compressed textures - this.bytesOfKeyValueData = headerDataView.getUint32( 12 * dataSize, littleEndian ); // the amount of space after the header for meta-data - // Make sure we have a compressed type. Not only reduces work, but probably better to let dev know they are not compressing. + // Make sure we have a compressed type. Not only reduces work, but probably better to let dev know they are not compressing. if ( this.glType !== 0 ) { console.warn( 'only compressed formats currently supported' ); @@ -125,27 +109,25 @@ console.warn( 'number of faces expected' + facesExpected + ', but found ' + this.numberOfFaces ); return; - } // we now have a completely validated file, so could use existence of loadType as success - // would need to make this more elaborate & adjust checks above to support more than one load type - + } + // we now have a completely validated file, so could use existence of loadType as success + // would need to make this more elaborate & adjust checks above to support more than one load type this.loadType = COMPRESSED_2D; } - mipmaps( loadMipmaps ) { - const mipmaps = []; // initialize width & height for level 1 + const mipmaps = []; + // initialize width & height for level 1 let dataOffset = HEADER_LEN + this.bytesOfKeyValueData; let width = this.pixelWidth; let height = this.pixelHeight; const mipmapCount = loadMipmaps ? this.numberOfMipmapLevels : 1; - for ( let level = 0; level < mipmapCount; level ++ ) { const imageSize = new Int32Array( this.arrayBuffer, dataOffset, 1 )[ 0 ]; // size per face, since not supporting array cubemaps - dataOffset += 4; // size of the image + 4 for the imageSize field for ( let face = 0; face < this.numberOfFaces; face ++ ) { diff --git a/examples/js/loaders/LDrawLoader.js b/examples/js/loaders/LDrawLoader.js index b6875c52b71291..3f9da1d7740f5d 100644 --- a/examples/js/loaders/LDrawLoader.js +++ b/examples/js/loaders/LDrawLoader.js @@ -1,15 +1,16 @@ ( function () { + // Special surface finish tag types. // Note: "MATERIAL" tag (e.g. GLITTER, SPECKLE) is not implemented - const FINISH_TYPE_DEFAULT = 0; const FINISH_TYPE_CHROME = 1; const FINISH_TYPE_PEARLESCENT = 2; const FINISH_TYPE_RUBBER = 3; const FINISH_TYPE_MATTE_METALLIC = 4; - const FINISH_TYPE_METAL = 5; // State machine to search a subobject path. - // The LDraw standard establishes these various possible subfolders. + const FINISH_TYPE_METAL = 5; + // State machine to search a subobject path. + // The LDraw standard establishes these various possible subfolders. const FILE_LOCATION_TRY_PARTS = 0; const FILE_LOCATION_TRY_P = 1; const FILE_LOCATION_TRY_MODELS = 2; @@ -19,11 +20,8 @@ const FILE_LOCATION_NOT_FOUND = 6; const MAIN_COLOUR_CODE = '16'; const MAIN_EDGE_COLOUR_CODE = '24'; - const _tempVec0 = new THREE.Vector3(); - const _tempVec1 = new THREE.Vector3(); - class LDrawConditionalLineMaterial extends THREE.ShaderMaterial { constructor( parameters ) { @@ -37,9 +35,7 @@ value: 1.0 } } ] ), - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` attribute vec3 control0; attribute vec3 control1; attribute vec3 direction; @@ -86,9 +82,7 @@ #include } `, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform vec3 diffuse; uniform float opacity; varying float discardFlag; @@ -143,7 +137,6 @@ } } - class ConditionalLineSegments extends THREE.LineSegments { constructor( geometry, material ) { @@ -154,7 +147,6 @@ } } - function generateFaceNormals( faces ) { for ( let i = 0, l = faces.length; i < l; i ++ ) { @@ -164,11 +156,8 @@ const v0 = vertices[ 0 ]; const v1 = vertices[ 1 ]; const v2 = vertices[ 2 ]; - _tempVec0.subVectors( v1, v0 ); - _tempVec1.subVectors( v2, v1 ); - face.faceNormal = new THREE.Vector3().crossVectors( _tempVec0, _tempVec1 ).normalize(); } @@ -176,7 +165,6 @@ } const _ray = new THREE.Ray(); - function smoothNormals( faces, lineSegments, checkSubSegments = false ) { // NOTE: 1e2 is pretty coarse but was chosen to quantize the resulting value because @@ -187,8 +175,8 @@ // vertices that should be merged might be set to "1.7" and "1.6999..." meaning they won't // get merged. This added epsilon attempts to push these error values to the same quantized // value for the sake of hashing. See "AT-ST mini" dishes. See mrdoob/three#23169. - const hashMultiplier = ( 1 + 1e-10 ) * 1e2; + const hashMultiplier = ( 1 + 1e-10 ) * 1e2; function hashVertex( v ) { const x = ~ ~ ( v.x * hashMultiplier ); @@ -202,10 +190,10 @@ return `${hashVertex( v0 )}_${hashVertex( v1 )}`; - } // converts the two vertices to a ray with a normalized direction and origin of 0, 0, 0 projected - // onto the original line. - + } + // converts the two vertices to a ray with a normalized direction and origin of 0, 0, 0 projected + // onto the original line. function toNormalizedRay( v0, v1, targetRay ) { targetRay.direction.subVectors( v1, v0 ).normalize(); @@ -224,8 +212,9 @@ const hardEdges = new Set(); const hardEdgeRays = new Map(); const halfEdgeList = {}; - const normals = []; // Save the list of hard edges by hash + const normals = []; + // Save the list of hard edges by hash for ( let i = 0, l = lineSegments.length; i < l; i ++ ) { const ls = lineSegments[ i ]; @@ -233,15 +222,15 @@ const v0 = vertices[ 0 ]; const v1 = vertices[ 1 ]; hardEdges.add( hashEdge( v0, v1 ) ); - hardEdges.add( hashEdge( v1, v0 ) ); // only generate the hard edge ray map if we're checking subsegments because it's more expensive to check - // and requires more memory. + hardEdges.add( hashEdge( v1, v0 ) ); + // only generate the hard edge ray map if we're checking subsegments because it's more expensive to check + // and requires more memory. if ( checkSubSegments ) { // add both ray directions to the map const ray = toNormalizedRay( v0, v1, new THREE.Ray() ); const rh1 = hashRay( ray ); - if ( ! hardEdgeRays.has( rh1 ) ) { toNormalizedRay( v1, v0, ray ); @@ -253,14 +242,13 @@ hardEdgeRays.set( rh1, info ); hardEdgeRays.set( rh2, info ); - } // store both segments ends in min, max order in the distances array to check if a face edge is a - // subsegment later. - + } + // store both segments ends in min, max order in the distances array to check if a face edge is a + // subsegment later. const info = hardEdgeRays.get( rh1 ); let d0 = info.ray.direction.dot( v0 ); let d1 = info.ray.direction.dot( v1 ); - if ( d0 > d1 ) { [ d0, d1 ] = [ d1, d0 ]; @@ -271,35 +259,34 @@ } - } // track the half edges associated with each triangle - + } + // track the half edges associated with each triangle for ( let i = 0, l = faces.length; i < l; i ++ ) { const tri = faces[ i ]; const vertices = tri.vertices; const vertCount = vertices.length; - for ( let i2 = 0; i2 < vertCount; i2 ++ ) { const index = i2; const next = ( i2 + 1 ) % vertCount; const v0 = vertices[ index ]; const v1 = vertices[ next ]; - const hash = hashEdge( v0, v1 ); // don't add the triangle if the edge is supposed to be hard + const hash = hashEdge( v0, v1 ); + // don't add the triangle if the edge is supposed to be hard if ( hardEdges.has( hash ) ) { continue; - } // if checking subsegments then check to see if this edge lies on a hard edge ray and whether its within any ray bounds - + } + // if checking subsegments then check to see if this edge lies on a hard edge ray and whether its within any ray bounds if ( checkSubSegments ) { toNormalizedRay( v0, v1, _ray ); const rayHash = hashRay( _ray ); - if ( hardEdgeRays.has( rayHash ) ) { const info = hardEdgeRays.get( rayHash ); @@ -309,16 +296,14 @@ } = info; let d0 = ray.direction.dot( v0 ); let d1 = ray.direction.dot( v1 ); - if ( d0 > d1 ) { [ d0, d1 ] = [ d1, d0 ]; - } // return early if the face edge is found to be a subsegment of a line edge meaning the edge will have "hard" normals - + } + // return early if the face edge is found to be a subsegment of a line edge meaning the edge will have "hard" normals let found = false; - for ( let i = 0, l = distances.length; i < l; i += 2 ) { if ( d0 >= distances[ i ] && d1 <= distances[ i + 1 ] ) { @@ -348,14 +333,13 @@ } - } // Iterate until we've tried to connect all faces to share normals - + } + // Iterate until we've tried to connect all faces to share normals while ( true ) { // Stop if there are no more faces left let halfEdge = null; - for ( const key in halfEdgeList ) { halfEdge = halfEdgeList[ key ]; @@ -367,62 +351,61 @@ break; - } // Exhaustively find all connected faces - + } + // Exhaustively find all connected faces const queue = [ halfEdge ]; - while ( queue.length > 0 ) { // initialize all vertex normals in this triangle const tri = queue.pop().tri; const vertices = tri.vertices; const vertNormals = tri.normals; - const faceNormal = tri.faceNormal; // Check if any edge is connected to another triangle edge + const faceNormal = tri.faceNormal; + // Check if any edge is connected to another triangle edge const vertCount = vertices.length; - for ( let i2 = 0; i2 < vertCount; i2 ++ ) { const index = i2; const next = ( i2 + 1 ) % vertCount; const v0 = vertices[ index ]; - const v1 = vertices[ next ]; // delete this triangle from the list so it won't be found again + const v1 = vertices[ next ]; + // delete this triangle from the list so it won't be found again const hash = hashEdge( v0, v1 ); delete halfEdgeList[ hash ]; const reverseHash = hashEdge( v1, v0 ); const otherInfo = halfEdgeList[ reverseHash ]; - if ( otherInfo ) { const otherTri = otherInfo.tri; const otherIndex = otherInfo.index; const otherNormals = otherTri.normals; const otherVertCount = otherNormals.length; - const otherFaceNormal = otherTri.faceNormal; // NOTE: If the angle between faces is > 67.5 degrees then assume it's + const otherFaceNormal = otherTri.faceNormal; + + // NOTE: If the angle between faces is > 67.5 degrees then assume it's // hard edge. There are some cases where the line segments do not line up exactly // with or span multiple triangle edges (see Lunar Vehicle wheels). - if ( Math.abs( otherTri.faceNormal.dot( tri.faceNormal ) ) < 0.25 ) { continue; - } // if this triangle has already been traversed then it won't be in + } + + // if this triangle has already been traversed then it won't be in // the halfEdgeList. If it has not then add it to the queue and delete // it so it won't be found again. - - if ( reverseHash in halfEdgeList ) { queue.push( otherInfo ); delete halfEdgeList[ reverseHash ]; - } // share the first normal - + } + // share the first normal const otherNext = ( otherIndex + 1 ) % otherVertCount; - if ( vertNormals[ index ] && otherNormals[ otherNext ] && vertNormals[ index ] !== otherNormals[ otherNext ] ) { otherNormals[ otherNext ].norm.add( vertNormals[ index ].norm ); @@ -431,7 +414,6 @@ } let sharedNormal1 = vertNormals[ index ] || otherNormals[ otherNext ]; - if ( sharedNormal1 === null ) { // it's possible to encounter an edge of a triangle that has already been traversed meaning @@ -456,9 +438,9 @@ otherNormals[ otherNext ] = sharedNormal1; sharedNormal1.norm.add( otherFaceNormal ); - } // share the second normal - + } + // share the second normal if ( vertNormals[ next ] && otherNormals[ otherIndex ] && vertNormals[ next ] !== otherNormals[ otherIndex ] ) { otherNormals[ otherIndex ].norm.add( vertNormals[ next ].norm ); @@ -467,7 +449,6 @@ } let sharedNormal2 = vertNormals[ next ] || otherNormals[ otherIndex ]; - if ( sharedNormal2 === null ) { sharedNormal2 = { @@ -497,9 +478,9 @@ } - } // The normals of each face have been added up so now we average them by normalizing the vector. - + } + // The normals of each face have been added up so now we average them by normalizing the vector. for ( let i = 0, l = normals.length; i < l; i ++ ) { normals[ i ].normalize(); @@ -531,13 +512,11 @@ this.lineNumber = lineNumber; } - seekNonSpace() { while ( this.currentCharIndex < this.lineLength ) { this.currentChar = this.line.charAt( this.currentCharIndex ); - if ( this.currentChar !== ' ' && this.currentChar !== '\t' ) { return; @@ -549,15 +528,14 @@ } } - getToken() { - const pos0 = this.currentCharIndex ++; // Seek space + const pos0 = this.currentCharIndex ++; + // Seek space while ( this.currentCharIndex < this.lineLength ) { this.currentChar = this.line.charAt( this.currentCharIndex ); - if ( this.currentChar === ' ' || this.currentChar === '\t' ) { break; @@ -573,40 +551,35 @@ return this.line.substring( pos0, pos1 ); } - getVector() { return new THREE.Vector3( parseFloat( this.getToken() ), parseFloat( this.getToken() ), parseFloat( this.getToken() ) ); } - getRemainingString() { return this.line.substring( this.currentCharIndex, this.lineLength ); } - isAtTheEnd() { return this.currentCharIndex >= this.lineLength; } - setToEnd() { this.currentCharIndex = this.lineLength; } - getLineNumberString() { return this.lineNumber >= 0 ? ' at line ' + this.lineNumber : ''; } - } // Fetches and parses an intermediate representation of LDraw parts files. - + } + // Fetches and parses an intermediate representation of LDraw parts files. class LDrawParsedCache { constructor( loader ) { @@ -615,12 +588,12 @@ this._cache = {}; } - cloneResult( original ) { - const result = {}; // vertices are transformed and normals computed before being converted to geometry - // so these pieces must be cloned. + const result = {}; + // vertices are transformed and normals computed before being converted to geometry + // so these pieces must be cloned. result.faces = original.faces.map( face => { return { @@ -650,8 +623,9 @@ vertices: face.vertices.map( v => v.clone() ) }; - } ); // none if this is subsequently modified + } ); + // none if this is subsequently modified result.type = original.type; result.category = original.category; result.keywords = original.keywords; @@ -659,48 +633,40 @@ result.subobjects = original.subobjects; result.fileName = original.fileName; result.totalFaces = original.totalFaces; - result.startingConstructionStep = original.startingConstructionStep; + result.startingBuildingStep = original.startingBuildingStep; result.materials = original.materials; result.group = null; return result; } - async fetchData( fileName ) { let triedLowerCase = false; let locationState = FILE_LOCATION_TRY_PARTS; - while ( locationState !== FILE_LOCATION_NOT_FOUND ) { let subobjectURL = fileName; - switch ( locationState ) { case FILE_LOCATION_AS_IS: locationState = locationState + 1; break; - case FILE_LOCATION_TRY_PARTS: subobjectURL = 'parts/' + subobjectURL; locationState = locationState + 1; break; - case FILE_LOCATION_TRY_P: subobjectURL = 'p/' + subobjectURL; locationState = locationState + 1; break; - case FILE_LOCATION_TRY_MODELS: subobjectURL = 'models/' + subobjectURL; locationState = locationState + 1; break; - case FILE_LOCATION_TRY_RELATIVE: subobjectURL = fileName.substring( 0, fileName.lastIndexOf( '/' ) + 1 ) + subobjectURL; locationState = locationState + 1; break; - case FILE_LOCATION_TRY_ABSOLUTE: if ( triedLowerCase ) { @@ -726,7 +692,6 @@ fileLoader.setPath( loader.partsLibraryPath ); fileLoader.setRequestHeader( loader.requestHeader ); fileLoader.setWithCredentials( loader.withCredentials ); - try { const text = await fileLoader.loadAsync( subobjectURL ); @@ -743,17 +708,16 @@ throw new Error( 'LDrawLoader: Subobject "' + fileName + '" could not be loaded.' ); } - parse( text, fileName = null ) { - const loader = this.loader; // final results + const loader = this.loader; + // final results const faces = []; const lineSegments = []; const conditionalSegments = []; const subobjects = []; const materials = {}; - const getLocalMaterial = colorCode => { return materials[ colorCode ] || null; @@ -764,8 +728,9 @@ let category = null; let keywords = null; let author = null; - let totalFaces = 0; // split into lines + let totalFaces = 0; + // split into lines if ( text.indexOf( '\r\n' ) !== - 1 ) { // This is faster than String.split with regex that splits on both @@ -782,20 +747,21 @@ let bfcCCW = true; let bfcInverted = false; let bfcCull = true; - let startingConstructionStep = false; // Parse all line commands + let startingBuildingStep = false; + // Parse all line commands for ( let lineIndex = 0; lineIndex < numLines; lineIndex ++ ) { const line = lines[ lineIndex ]; if ( line.length === 0 ) continue; - if ( parsingEmbeddedFiles ) { if ( line.startsWith( '0 FILE ' ) ) { // Save previous embedded file in the cache - this.setData( currentEmbeddedFileName, currentEmbeddedText ); // New embedded text file + this.setData( currentEmbeddedFileName, currentEmbeddedText ); + // New embedded text file currentEmbeddedFileName = line.substring( 7 ); currentEmbeddedText = ''; @@ -811,15 +777,14 @@ const lp = new LineParser( line, lineIndex + 1 ); lp.seekNonSpace(); - if ( lp.isAtTheEnd() ) { // Empty line continue; - } // Parse the line type - + } + // Parse the line type const lineType = lp.getToken(); let material; let colorCode; @@ -827,14 +792,12 @@ let ccw; let doubleSided; let v0, v1, v2, v3, c0, c1; - switch ( lineType ) { // Line type 0: Comment or META case '0': // Parse meta directive const meta = lp.getToken(); - if ( meta ) { switch ( meta ) { @@ -842,10 +805,8 @@ case '!LDRAW_ORG': type = lp.getToken(); break; - case '!COLOUR': material = loader.parseColorMetaDirective( lp ); - if ( material ) { materials[ material.userData.code ] = material; @@ -857,14 +818,11 @@ } break; - case '!CATEGORY': category = lp.getToken(); break; - case '!KEYWORDS': const newKeywords = lp.getRemainingString().split( ',' ); - if ( newKeywords.length > 0 ) { if ( ! keywords ) { @@ -882,7 +840,6 @@ } break; - case 'FILE': if ( lineIndex > 0 ) { @@ -896,13 +853,11 @@ } break; - case 'BFC': // Changes to the backface culling state while ( ! lp.isAtTheEnd() ) { const token = lp.getToken(); - switch ( token ) { case 'CERTIFY': @@ -910,21 +865,17 @@ bfcCertified = token === 'CERTIFY'; bfcCCW = true; break; - case 'CW': case 'CCW': bfcCCW = token === 'CCW'; break; - case 'INVERTNEXT': bfcInverted = true; break; - case 'CLIP': case 'NOCLIP': bfcCull = token === 'CLIP'; break; - default: console.warn( 'THREE.LDrawLoader: BFC directive "' + token + '" is unknown.' ); break; @@ -934,15 +885,12 @@ } break; - case 'STEP': - startingConstructionStep = true; + startingBuildingStep = true; break; - case 'Author:': author = lp.getToken(); break; - default: // Other meta directives are not implemented break; @@ -952,8 +900,8 @@ } break; - // Line type 1: Sub-object file + // Line type 1: Sub-object file case '1': colorCode = lp.getToken(); material = getLocalMaterial( colorCode ); @@ -971,7 +919,6 @@ const m8 = parseFloat( lp.getToken() ); const matrix = new THREE.Matrix4().set( m0, m1, m2, posX, m3, m4, m5, posY, m6, m7, m8, posZ, 0, 0, 0, 1 ); let fileName = lp.getRemainingString().trim().replace( /\\/g, '/' ); - if ( loader.fileMap[ fileName ] ) { // Found the subobject path in the preloaded file path map @@ -998,12 +945,13 @@ matrix: matrix, fileName: fileName, inverted: bfcInverted, - startingConstructionStep: startingConstructionStep + startingBuildingStep: startingBuildingStep } ); + startingBuildingStep = false; bfcInverted = false; break; - // Line type 2: Line segment + // Line type 2: Line segment case '2': colorCode = lp.getToken(); material = getLocalMaterial( colorCode ); @@ -1016,8 +964,8 @@ }; lineSegments.push( segment ); break; - // Line type 5: Conditional Line segment + // Line type 5: Conditional Line segment case '5': colorCode = lp.getToken(); material = getLocalMaterial( colorCode ); @@ -1033,14 +981,13 @@ }; conditionalSegments.push( segment ); break; - // Line type 3: Triangle + // Line type 3: Triangle case '3': colorCode = lp.getToken(); material = getLocalMaterial( colorCode ); ccw = bfcCCW; doubleSided = ! bfcCertified || ! bfcCull; - if ( ccw === true ) { v0 = lp.getVector(); @@ -1063,7 +1010,6 @@ normals: [ null, null, null ] } ); totalFaces ++; - if ( doubleSided === true ) { faces.push( { @@ -1078,14 +1024,13 @@ } break; - // Line type 4: Quadrilateral + // Line type 4: Quadrilateral case '4': colorCode = lp.getToken(); material = getLocalMaterial( colorCode ); ccw = bfcCCW; doubleSided = ! bfcCertified || ! bfcCull; - if ( ccw === true ) { v0 = lp.getVector(); @@ -1100,10 +1045,10 @@ v1 = lp.getVector(); v0 = lp.getVector(); - } // specifically place the triangle diagonal in the v0 and v1 slots so we can - // account for the doubling of vertices later when smoothing normals. - + } + // specifically place the triangle diagonal in the v0 and v1 slots so we can + // account for the doubling of vertices later when smoothing normals. faces.push( { material: material, colorCode: colorCode, @@ -1112,7 +1057,6 @@ normals: [ null, null, null, null ] } ); totalFaces += 2; - if ( doubleSided === true ) { faces.push( { @@ -1127,7 +1071,6 @@ } break; - default: throw new Error( 'LDrawLoader: Unknown line type "' + lineType + '"' + lp.getLineNumberString() + '.' ); @@ -1151,20 +1094,19 @@ author, subobjects, totalFaces, - startingConstructionStep, + startingBuildingStep, materials, fileName, group: null }; - } // returns an (optionally cloned) instance of the data - + } + // returns an (optionally cloned) instance of the data getData( fileName, clone = true ) { const key = fileName.toLowerCase(); const result = this._cache[ key ]; - if ( result === null || result instanceof Promise ) { return null; @@ -1181,14 +1123,13 @@ } - } // kicks off a fetch and parse of the requested data if it hasn't already been loaded. Returns when - // the data is ready to use and can be retrieved synchronously with "getData". - + } + // kicks off a fetch and parse of the requested data if it hasn't already been loaded. Returns when + // the data is ready to use and can be retrieved synchronously with "getData". async ensureDataLoaded( fileName ) { const key = fileName.toLowerCase(); - if ( ! ( key in this._cache ) ) { // replace the promise with a copy of the parsed data for immediate processing @@ -1204,9 +1145,9 @@ await this._cache[ key ]; - } // sets the data in the cache from parsed data - + } + // sets the data in the cache from parsed data setData( fileName, text ) { const key = fileName.toLowerCase(); @@ -1214,14 +1155,13 @@ } - } // returns the material for an associated color code. If the color code is 16 for a face or 24 for - // an edge then the passthroughColorCode is used. - + } + // returns the material for an associated color code. If the color code is 16 for a face or 24 for + // an edge then the passthroughColorCode is used. function getMaterialFromCode( colorCode, parentColorCode, materialHierarchy, forEdge ) { const isPassthrough = ! forEdge && colorCode === MAIN_COLOUR_CODE || forEdge && colorCode === MAIN_EDGE_COLOUR_CODE; - if ( isPassthrough ) { colorCode = parentColorCode; @@ -1230,9 +1170,9 @@ return materialHierarchy[ colorCode ] || null; - } // Class used to parse and build LDraw parts as three.js objects and cache them if they're a "Part" type. - + } + // Class used to parse and build LDraw parts as three.js objects and cache them if they're a "Part" type. class LDrawPartsGeometryCache { constructor( loader ) { @@ -1241,29 +1181,30 @@ this.parseCache = new LDrawParsedCache( loader ); this._cache = {}; - } // Convert the given file information into a mesh by processing subobjects. - + } + // Convert the given file information into a mesh by processing subobjects. async processIntoMesh( info ) { const loader = this.loader; const parseCache = this.parseCache; - const faceMaterials = new Set(); // Processes the part subobject information to load child parts and merge geometry onto part - // piece object. + const faceMaterials = new Set(); + // Processes the part subobject information to load child parts and merge geometry onto part + // piece object. const processInfoSubobjects = async ( info, subobject = null ) => { const subobjects = info.subobjects; - const promises = []; // Trigger load of all subobjects. If a subobject isn't a primitive then load it as a separate - // group which lets instruction steps apply correctly. + const promises = []; + // Trigger load of all subobjects. If a subobject isn't a primitive then load it as a separate + // group which lets instruction steps apply correctly. for ( let i = 0, l = subobjects.length; i < l; i ++ ) { const subobject = subobjects[ i ]; const promise = parseCache.ensureDataLoaded( subobject.fileName ).then( () => { const subobjectInfo = parseCache.getData( subobject.fileName, false ); - if ( ! isPrimitiveType( subobjectInfo.type ) ) { return this.loadModel( subobject.fileName ).catch( error => { @@ -1290,42 +1231,40 @@ group.userData.fileName = info.fileName; info.group = group; const subobjectInfos = await Promise.all( promises ); - for ( let i = 0, l = subobjectInfos.length; i < l; i ++ ) { const subobject = info.subobjects[ i ]; const subobjectInfo = subobjectInfos[ i ]; - if ( subobjectInfo === null ) { // the subobject failed to load continue; - } // if the subobject was loaded as a separate group then apply the parent scopes materials - + } + // if the subobject was loaded as a separate group then apply the parent scopes materials if ( subobjectInfo.isGroup ) { const subobjectGroup = subobjectInfo; subobject.matrix.decompose( subobjectGroup.position, subobjectGroup.quaternion, subobjectGroup.scale ); - subobjectGroup.userData.startingConstructionStep = subobject.startingConstructionStep; + subobjectGroup.userData.startingBuildingStep = subobject.startingBuildingStep; subobjectGroup.name = subobject.fileName; loader.applyMaterialsToMesh( subobjectGroup, subobject.colorCode, info.materials ); subobjectGroup.userData.colorCode = subobject.colorCode; group.add( subobjectGroup ); continue; - } // add the subobject group if it has children in case it has both children and primitives - + } + // add the subobject group if it has children in case it has both children and primitives if ( subobjectInfo.group.children.length ) { group.add( subobjectInfo.group ); - } // transform the primitives into the local space of the parent piece and append them to - // to the parent primitives list. - + } + // transform the primitives into the local space of the parent piece and append them to + // to the parent primitives list. const parentLineSegments = info.lineSegments; const parentConditionalSegments = info.conditionalSegments; const parentFaces = info.faces; @@ -1337,7 +1276,6 @@ const matrixScaleInverted = matrix.determinant() < 0; const colorCode = subobject.colorCode; const lineColorCode = colorCode === MAIN_COLOUR_CODE ? MAIN_EDGE_COLOUR_CODE : colorCode; - for ( let i = 0, l = lineSegments.length; i < l; i ++ ) { const ls = lineSegments[ i ]; @@ -1369,7 +1307,6 @@ const tri = faces[ i ]; const vertices = tri.vertices; - for ( let i = 0, l = vertices.length; i < l; i ++ ) { vertices[ i ].applyMatrix4( matrix ); @@ -1378,9 +1315,10 @@ tri.colorCode = tri.colorCode === MAIN_COLOUR_CODE ? colorCode : tri.colorCode; tri.material = tri.material || getMaterialFromCode( tri.colorCode, colorCode, info.materials, false ); - faceMaterials.add( tri.colorCode ); // If the scale of the object is negated then the triangle winding order - // needs to be flipped. + faceMaterials.add( tri.colorCode ); + // If the scale of the object is negated then the triangle winding order + // needs to be flipped. if ( matrixScaleInverted !== inverted ) { vertices.reverse(); @@ -1393,10 +1331,10 @@ info.totalFaces += subobjectInfo.totalFaces; - } // Apply the parent subobjects pass through material code to this object. This is done several times due - // to material scoping. - + } + // Apply the parent subobjects pass through material code to this object. This is done several times due + // to material scoping. if ( subobject ) { loader.applyMaterialsToMesh( group, subobject.colorCode, info.materials ); @@ -1406,9 +1344,9 @@ return info; - }; // Track material use to see if we need to use the normal smooth slow path for hard edges. - + }; + // Track material use to see if we need to use the normal smooth slow path for hard edges. for ( let i = 0, l = info.faces; i < l; i ++ ) { faceMaterials.add( info.faces[ i ].colorCode ); @@ -1416,18 +1354,16 @@ } await processInfoSubobjects( info ); - if ( loader.smoothNormals ) { const checkSubSegments = faceMaterials.size > 1; generateFaceNormals( info.faces ); smoothNormals( info.faces, info.lineSegments, checkSubSegments ); - } // Add the primitive objects and metadata. - + } + // Add the primitive objects and metadata. const group = info.group; - if ( info.faces.length > 0 ) { group.add( createObject( info.faces, 3, false, info.totalFaces ) ); @@ -1449,13 +1385,11 @@ return group; } - hasCachedModel( fileName ) { return fileName !== null && fileName.toLowerCase() in this._cache; } - async getCachedModel( fileName ) { if ( fileName !== null && this.hasCachedModel( fileName ) ) { @@ -1470,14 +1404,13 @@ } - } // Loads and parses the model with the given file name. Returns a cached copy if available. - + } + // Loads and parses the model with the given file name. Returns a cached copy if available. async loadModel( fileName ) { const parseCache = this.parseCache; const key = fileName.toLowerCase(); - if ( this.hasCachedModel( fileName ) ) { // Return cached model if available. @@ -1489,37 +1422,37 @@ // Ensure the file data is loaded and pre parsed. await parseCache.ensureDataLoaded( fileName ); const info = parseCache.getData( fileName ); - const promise = this.processIntoMesh( info ); // Now that the file has loaded it's possible that another part parse has been waiting in parallel + const promise = this.processIntoMesh( info ); + + // Now that the file has loaded it's possible that another part parse has been waiting in parallel // so check the cache again to see if it's been added since the last async operation so we don't // do unnecessary work. - if ( this.hasCachedModel( fileName ) ) { return this.getCachedModel( fileName ); - } // Cache object if it's a part so it can be reused later. - + } + // Cache object if it's a part so it can be reused later. if ( isPartType( info.type ) ) { this._cache[ key ] = promise; - } // return a copy - + } + // return a copy const group = await promise; return group.clone(); } - } // parses the given model text into a renderable object. Returns cached copy if available. - + } + // parses the given model text into a renderable object. Returns cached copy if available. async parseModel( text ) { const parseCache = this.parseCache; const info = parseCache.parse( text ); - if ( isPartType( info.type ) && this.hasCachedModel( info.fileName ) ) { return this.getCachedModel( info.fileName ); @@ -1531,7 +1464,6 @@ } } - function sortByMaterial( a, b ) { if ( a.colorCode === b.colorCode ) { @@ -1554,9 +1486,9 @@ // Creates a THREE.LineSegments (elementSize = 2) or a THREE.Mesh (elementSize = 3 ) // With per face / segment material, implemented with mesh groups and materials array + // Sort the faces or line segments by color code to make later the mesh groups elements.sort( sortByMaterial ); - if ( totalElements === null ) { totalElements = elements.length; @@ -1572,12 +1504,10 @@ let index0 = 0; let numGroupVerts = 0; let offset = 0; - for ( let iElem = 0, nElem = elements.length; iElem < nElem; iElem ++ ) { const elem = elements[ iElem ]; let vertices = elem.vertices; - if ( vertices.length === 4 ) { quadArray[ 0 ] = vertices[ 0 ]; @@ -1598,9 +1528,9 @@ positions[ index + 1 ] = v.y; positions[ index + 2 ] = v.z; - } // create the normals array if this is a set of faces - + } + // create the normals array if this is a set of faces if ( elementSize === 3 ) { if ( ! elem.faceNormal ) { @@ -1608,17 +1538,13 @@ const v0 = vertices[ 0 ]; const v1 = vertices[ 1 ]; const v2 = vertices[ 2 ]; - _tempVec0.subVectors( v1, v0 ); - _tempVec1.subVectors( v2, v1 ); - elem.faceNormal = new THREE.Vector3().crossVectors( _tempVec0, _tempVec1 ).normalize(); } let elemNormals = elem.normals; - if ( elemNormals.length === 4 ) { quadArray[ 0 ] = elemNormals[ 0 ]; @@ -1635,7 +1561,6 @@ // use face normal if a vertex normal is not provided let n = elem.faceNormal; - if ( elemNormals[ j ] ) { n = elemNormals[ j ].norm; @@ -1660,7 +1585,6 @@ } const material = elem.material; - if ( material !== null ) { if ( elementSize === 3 ) { @@ -1710,7 +1634,6 @@ } bufferGeometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); - if ( normals !== null ) { bufferGeometry.setAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); @@ -1718,7 +1641,6 @@ } let object3d = null; - if ( elementSize === 2 ) { if ( isConditionalSegments ) { @@ -1743,7 +1665,6 @@ const controlArray0 = new Float32Array( elements.length * 3 * 2 ); const controlArray1 = new Float32Array( elements.length * 3 * 2 ); const directionArray = new Float32Array( elements.length * 3 * 2 ); - for ( let i = 0, l = elements.length; i < l; i ++ ) { const os = elements[ i ]; @@ -1783,28 +1704,36 @@ return object3d; - } // + } + // class LDrawLoader extends THREE.Loader { constructor( manager ) { - super( manager ); // Array of THREE.Material + super( manager ); + // Array of THREE.Material this.materials = []; - this.materialLibrary = {}; // This also allows to handle the embedded text files ("0 FILE" lines) + this.materialLibrary = {}; - this.partsCache = new LDrawPartsGeometryCache( this ); // This object is a map from file names to paths. It agilizes the paths search. If it is not set then files will be searched by trial and error. + // This also allows to handle the embedded text files ("0 FILE" lines) + this.partsCache = new LDrawPartsGeometryCache( this ); - this.fileMap = {}; // Initializes the materials library with default materials + // This object is a map from file names to paths. It agilizes the paths search. If it is not set then files will be searched by trial and error. + this.fileMap = {}; - this.setMaterials( [] ); // If this flag is set to true the vertex normals will be smoothed. + // Initializes the materials library with default materials + this.setMaterials( [] ); - this.smoothNormals = true; // The path to load parts from the LDraw parts library from. + // If this flag is set to true the vertex normals will be smoothed. + this.smoothNormals = true; - this.partsLibraryPath = ''; // Material assigned to not available colors for meshes and edges + // The path to load parts from the LDraw parts library from. + this.partsLibraryPath = ''; + // Material assigned to not available colors for meshes and edges this.missingColorMaterial = new THREE.MeshStandardMaterial( { color: 0xFF00FF, roughness: 0.3, @@ -1824,14 +1753,12 @@ this.missingEdgeColorMaterial.userData.conditionalEdgeMaterial = this.missingConditionalEdgeColorMaterial; } - setPartsLibraryPath( path ) { this.partsLibraryPath = path; return this; } - async preloadMaterials( url ) { const fileLoader = new THREE.FileLoader( this.manager ); @@ -1842,11 +1769,9 @@ const colorLineRegex = /^0 !COLOUR/; const lines = text.split( /[\n\r]/g ); const materials = []; - for ( let i = 0, l = lines.length; i < l; i ++ ) { const line = lines[ i ]; - if ( colorLineRegex.test( line ) ) { const directive = line.replace( colorLineRegex, '' ); @@ -1860,7 +1785,6 @@ this.setMaterials( materials ); } - load( url, onLoad, onProgress, onError ) { const fileLoader = new THREE.FileLoader( this.manager ); @@ -1872,7 +1796,7 @@ this.partsCache.parseModel( text, this.materialLibrary ).then( group => { this.applyMaterialsToMesh( group, MAIN_COLOUR_CODE, this.materialLibrary, true ); - this.computeConstructionSteps( group ); + this.computeBuildingSteps( group ); group.userData.fileName = url; onLoad( group ); @@ -1881,50 +1805,45 @@ }, onProgress, onError ); } - parse( text, onLoad ) { this.partsCache.parseModel( text, this.materialLibrary ).then( group => { this.applyMaterialsToMesh( group, MAIN_COLOUR_CODE, this.materialLibrary, true ); - this.computeConstructionSteps( group ); + this.computeBuildingSteps( group ); group.userData.fileName = ''; onLoad( group ); } ); } - setMaterials( materials ) { this.materialLibrary = {}; this.materials = []; - for ( let i = 0, l = materials.length; i < l; i ++ ) { this.addMaterial( materials[ i ] ); - } // Add default main triangle and line edge materials (used in pieces that can be colored with a main color) - + } + // Add default main triangle and line edge materials (used in pieces that can be colored with a main color) this.addMaterial( this.parseColorMetaDirective( new LineParser( 'Main_Colour CODE 16 VALUE #FF8080 EDGE #333333' ) ) ); this.addMaterial( this.parseColorMetaDirective( new LineParser( 'Edge_Colour CODE 24 VALUE #A0A0A0 EDGE #333333' ) ) ); return this; } - setFileMap( fileMap ) { this.fileMap = fileMap; return this; } - addMaterial( material ) { // Adds a material to the material library which is on top of the parse scopes stack. And also to the materials array - const matLib = this.materialLibrary; + const matLib = this.materialLibrary; if ( ! matLib[ material.userData.code ] ) { this.materials.push( material ); @@ -1935,7 +1854,6 @@ return this; } - getMaterial( colorCode ) { if ( colorCode.startsWith( '0x2' ) ) { @@ -1948,10 +1866,10 @@ return this.materialLibrary[ colorCode ] || null; - } // Applies the appropriate materials to a prebuilt hierarchy of geometry. Assumes that color codes are present - // in the material array if they need to be filled in. - + } + // Applies the appropriate materials to a prebuilt hierarchy of geometry. Assumes that color codes are present + // in the material array if they need to be filled in. applyMaterialsToMesh( group, parentColorCode, materialHierarchy, finalMaterialPass = false ) { // find any missing materials as indicated by a color code string and replace it with a material from the current material lib @@ -1981,10 +1899,11 @@ } - } ); // Returns the appropriate material for the object (line or face) given color code. If the code is "pass through" + } ); + + // Returns the appropriate material for the object (line or face) given color code. If the code is "pass through" // (24 for lines, 16 for edges) then the pass through color code is used. If that is also pass through then it's // simply returned for the subsequent material application. - function getMaterial( c, colorCode ) { // if our parent is a passthrough color code and we don't have the current material color available then @@ -1997,7 +1916,6 @@ const forEdge = c.isLineSegments || c.isConditionalLine; const isPassthrough = ! forEdge && colorCode === MAIN_COLOUR_CODE || forEdge && colorCode === MAIN_EDGE_COLOUR_CODE; - if ( isPassthrough ) { colorCode = parentColorCode; @@ -2005,7 +1923,6 @@ } let material = null; - if ( colorCode in materialHierarchy ) { material = materialHierarchy[ colorCode ]; @@ -2015,12 +1932,12 @@ // see if we can get the final material from from the "getMaterial" function which will attempt to // parse the "direct" colors material = loader.getMaterial( colorCode ); - if ( material === null ) { // otherwise throw a warning if this is final opportunity to set the material - console.warn( `LDrawLoader: Material properties for code ${colorCode} not available.` ); // And return the 'missing color' material + console.warn( `LDrawLoader: Material properties for code ${colorCode} not available.` ); + // And return the 'missing color' material material = loader.missingColorMaterial; } @@ -2034,7 +1951,6 @@ if ( c.isLineSegments ) { material = material.userData.edgeMaterial; - if ( c.isConditionalLine ) { material = material.userData.conditionalEdgeMaterial; @@ -2048,49 +1964,46 @@ } } - getMainMaterial() { return this.getMaterial( MAIN_COLOUR_CODE ); } - getMainEdgeMaterial() { const mat = this.getMaterial( MAIN_EDGE_COLOUR_CODE ); return mat ? mat.userData.edgeMaterial : null; } - parseColorMetaDirective( lineParser ) { // Parses a color definition and returns a THREE.Material - let code = null; // Triangle and line colors + let code = null; + + // Triangle and line colors let color = 0xFF00FF; - let edgeColor = 0xFF00FF; // Transparency + let edgeColor = 0xFF00FF; + // Transparency let alpha = 1; - let isTransparent = false; // Self-illumination: - + let isTransparent = false; + // Self-illumination: let luminance = 0; let finishType = FINISH_TYPE_DEFAULT; let edgeMaterial = null; const name = lineParser.getToken(); - if ( ! name ) { throw new Error( 'LDrawLoader: Material name was expected after "!COLOUR tag' + lineParser.getLineNumberString() + '.' ); - } // Parse tag tokens and their parameters - + } + // Parse tag tokens and their parameters let token = null; - while ( true ) { token = lineParser.getToken(); - if ( ! token ) { break; @@ -2104,10 +2017,8 @@ case 'CODE': code = lineParser.getToken(); break; - case 'VALUE': color = lineParser.getToken(); - if ( color.startsWith( '0x' ) ) { color = '#' + color.substring( 2 ); @@ -2119,10 +2030,8 @@ } break; - case 'EDGE': edgeColor = lineParser.getToken(); - if ( edgeColor.startsWith( '0x' ) ) { edgeColor = '#' + edgeColor.substring( 2 ); @@ -2131,23 +2040,20 @@ // Try to see if edge color is a color code edgeMaterial = this.getMaterial( edgeColor ); - if ( ! edgeMaterial ) { throw new Error( 'LDrawLoader: Invalid edge color while parsing material' + lineParser.getLineNumberString() + '.' ); - } // Get the edge material for this triangle material - + } + // Get the edge material for this triangle material edgeMaterial = edgeMaterial.userData.edgeMaterial; } break; - case 'ALPHA': alpha = parseInt( lineParser.getToken() ); - if ( isNaN( alpha ) ) { throw new Error( 'LDrawLoader: Invalid alpha value in material definition' + lineParser.getLineNumberString() + '.' ); @@ -2155,7 +2061,6 @@ } alpha = Math.max( 0, Math.min( 1, alpha / 255 ) ); - if ( alpha < 1 ) { isTransparent = true; @@ -2163,7 +2068,6 @@ } break; - case 'LUMINANCE': if ( ! parseLuminance( lineParser.getToken() ) ) { @@ -2172,32 +2076,25 @@ } break; - case 'CHROME': finishType = FINISH_TYPE_CHROME; break; - case 'PEARLESCENT': finishType = FINISH_TYPE_PEARLESCENT; break; - case 'RUBBER': finishType = FINISH_TYPE_RUBBER; break; - case 'MATTE_METALLIC': finishType = FINISH_TYPE_MATTE_METALLIC; break; - case 'METAL': finishType = FINISH_TYPE_METAL; break; - case 'MATERIAL': // Not implemented lineParser.setToEnd(); break; - default: throw new Error( 'LDrawLoader: Unknown token "' + token + '" while parsing material' + lineParser.getLineNumberString() + '.' ); @@ -2208,7 +2105,6 @@ } let material = null; - switch ( finishType ) { case FINISH_TYPE_DEFAULT: @@ -2218,7 +2114,6 @@ metalness: 0 } ); break; - case FINISH_TYPE_PEARLESCENT: // Try to imitate pearlescency by making the surface glossy material = new THREE.MeshStandardMaterial( { @@ -2227,7 +2122,6 @@ metalness: 0.25 } ); break; - case FINISH_TYPE_CHROME: // Mirror finish surface material = new THREE.MeshStandardMaterial( { @@ -2236,7 +2130,6 @@ metalness: 1 } ); break; - case FINISH_TYPE_RUBBER: // Rubber finish material = new THREE.MeshStandardMaterial( { @@ -2245,7 +2138,6 @@ metalness: 0 } ); break; - case FINISH_TYPE_MATTE_METALLIC: // Brushed metal finish material = new THREE.MeshStandardMaterial( { @@ -2254,7 +2146,6 @@ metalness: 0.4 } ); break; - case FINISH_TYPE_METAL: // Average metal finish material = new THREE.MeshStandardMaterial( { @@ -2263,7 +2154,6 @@ metalness: 0.85 } ); break; - default: // Should not happen break; @@ -2277,7 +2167,6 @@ material.color.convertSRGBToLinear(); material.polygonOffset = true; material.polygonOffsetFactor = 1; - if ( luminance !== 0 ) { material.emissive.set( material.color ).multiplyScalar( luminance ); @@ -2295,8 +2184,9 @@ } ); edgeMaterial.userData.code = code; edgeMaterial.name = name + ' - Edge'; - edgeMaterial.color.convertSRGBToLinear(); // This is the material used for conditional edges + edgeMaterial.color.convertSRGBToLinear(); + // This is the material used for conditional edges edgeMaterial.userData.conditionalEdgeMaterial = new LDrawConditionalLineMaterial( { fog: true, transparent: isTransparent, @@ -2315,12 +2205,11 @@ material.userData.edgeMaterial = edgeMaterial; this.addMaterial( material ); return material; - function parseLuminance( token ) { // Returns success - let lum; + let lum; if ( token.startsWith( 'LUMINANCE' ) ) { lum = parseInt( token.substring( 9 ) ); @@ -2343,27 +2232,27 @@ } } + computeBuildingSteps( model ) { - computeConstructionSteps( model ) { + // Sets userdata.buildingStep number in THREE.Group objects and userData.numBuildingSteps number in the root THREE.Group object. - // Sets userdata.constructionStep number in THREE.Group objects and userData.numConstructionSteps number in the root THREE.Group object. let stepNumber = 0; model.traverse( c => { if ( c.isGroup ) { - if ( c.userData.startingConstructionStep ) { + if ( c.userData.startingBuildingStep ) { stepNumber ++; } - c.userData.constructionStep = stepNumber; + c.userData.buildingStep = stepNumber; } } ); - model.userData.numConstructionSteps = stepNumber + 1; + model.userData.numBuildingSteps = stepNumber + 1; } diff --git a/examples/js/loaders/LUT3dlLoader.js b/examples/js/loaders/LUT3dlLoader.js index 89dd5f7c50d8ea..f4531b8cc924c2 100644 --- a/examples/js/loaders/LUT3dlLoader.js +++ b/examples/js/loaders/LUT3dlLoader.js @@ -33,17 +33,16 @@ }, onProgress, onError ); } - parse( str ) { // remove empty lines and comment lints str = str.replace( /^#.*?(\n|\r)/gm, '' ).replace( /^\s*?(\n|\r)/gm, '' ).trim(); - const lines = str.split( /[\n\r]+/g ); // first line is the positions on the grid that are provided by the LUT + const lines = str.split( /[\n\r]+/g ); + // first line is the positions on the grid that are provided by the LUT const gridLines = lines[ 0 ].trim().split( /\s+/g ).map( e => parseFloat( e ) ); const gridStep = gridLines[ 1 ] - gridLines[ 0 ]; const size = gridLines.length; - for ( let i = 1, l = gridLines.length; i < l; i ++ ) { if ( gridStep !== gridLines[ i ] - gridLines[ i - 1 ] ) { @@ -57,7 +56,6 @@ const dataArray = new Array( size * size * size * 4 ); let index = 0; let maxOutputValue = 0.0; - for ( let i = 1, l = lines.length; i < l; i ++ ) { const line = lines[ i ].trim(); @@ -68,8 +66,9 @@ maxOutputValue = Math.max( maxOutputValue, r, g, b ); const bLayer = index % size; const gLayer = Math.floor( index / size ) % size; - const rLayer = Math.floor( index / ( size * size ) ) % size; // b grows first, then g, then r + const rLayer = Math.floor( index / ( size * size ) ) % size; + // b grows first, then g, then r const pixelIndex = bLayer * size * size + gLayer * size + rLayer; dataArray[ 4 * pixelIndex + 0 ] = r; dataArray[ 4 * pixelIndex + 1 ] = g; @@ -77,22 +76,19 @@ dataArray[ 4 * pixelIndex + 3 ] = 1.0; index += 1; - } // Find the apparent bit depth of the stored RGB values and map the - // values to [ 0, 255 ]. - + } + // Find the apparent bit depth of the stored RGB values and map the + // values to [ 0, 255 ]. const bits = Math.ceil( Math.log2( maxOutputValue ) ); const maxBitValue = Math.pow( 2.0, bits ); - for ( let i = 0, l = dataArray.length; i < l; i += 4 ) { const r = dataArray[ i + 0 ]; const g = dataArray[ i + 1 ]; const b = dataArray[ i + 2 ]; dataArray[ i + 0 ] = 255 * r / maxBitValue; // r - dataArray[ i + 1 ] = 255 * g / maxBitValue; // g - dataArray[ i + 2 ] = 255 * b / maxBitValue; // b } diff --git a/examples/js/loaders/LUTCubeLoader.js b/examples/js/loaders/LUTCubeLoader.js index 9c5e0382ce6819..d212ec9cf89121 100644 --- a/examples/js/loaders/LUTCubeLoader.js +++ b/examples/js/loaders/LUTCubeLoader.js @@ -33,7 +33,6 @@ }, onProgress, onError ); } - parse( str ) { // Remove empty lines and comments @@ -45,18 +44,15 @@ const lines = str.split( /[\n\r]+/g ); let data = null; let currIndex = 0; - for ( let i = 0, l = lines.length; i < l; i ++ ) { const line = lines[ i ].trim(); const split = line.split( /\s/g ); - switch ( split[ 0 ] ) { case 'TITLE': title = line.substring( 7, line.length - 1 ); break; - case 'LUT_3D_SIZE': // TODO: A .CUBE LUT file specifies floating point values and could be represented with // more precision than can be captured with Uint8Array. @@ -64,24 +60,20 @@ size = parseFloat( sizeToken ); data = new Uint8Array( size * size * size * 4 ); break; - case 'DOMAIN_MIN': domainMin.x = parseFloat( split[ 1 ] ); domainMin.y = parseFloat( split[ 2 ] ); domainMin.z = parseFloat( split[ 3 ] ); break; - case 'DOMAIN_MAX': domainMax.x = parseFloat( split[ 1 ] ); domainMax.y = parseFloat( split[ 2 ] ); domainMax.z = parseFloat( split[ 3 ] ); break; - default: const r = parseFloat( split[ 0 ] ); const g = parseFloat( split[ 1 ] ); const b = parseFloat( split[ 2 ] ); - if ( r > 1.0 || r < 0.0 || g > 1.0 || g < 0.0 || b > 1.0 || b < 0.0 ) { throw new Error( 'LUTCubeLoader : Non normalized values not supported.' ); diff --git a/examples/js/loaders/LWOLoader.js b/examples/js/loaders/LWOLoader.js index 189b051666009c..501ce7d0a28560 100644 --- a/examples/js/loaders/LWOLoader.js +++ b/examples/js/loaders/LWOLoader.js @@ -12,9 +12,7 @@ * https://static.lightwave3d.com/sdk/2019/html/filefmts/lwo2.html * **/ - let _lwoTree; - class LWOLoader extends THREE.Loader { constructor( manager, parameters = {} ) { @@ -23,12 +21,12 @@ this.resourcePath = parameters.resourcePath !== undefined ? parameters.resourcePath : ''; } - load( url, onLoad, onProgress, onError ) { const scope = this; - const path = scope.path === '' ? extractParentUrl( url, 'Objects' ) : scope.path; // give the mesh a default name based on the filename + const path = scope.path === '' ? extractParentUrl( url, 'Objects' ) : scope.path; + // give the mesh a default name based on the filename const modelName = url.split( path ).pop().split( '.' )[ 0 ]; const loader = new THREE.FileLoader( this.manager ); loader.setPath( scope.path ); @@ -36,6 +34,7 @@ loader.load( url, function ( buffer ) { // console.time( 'Total parsing: ' ); + try { onLoad( scope.parse( buffer, path, modelName ) ); @@ -54,24 +53,27 @@ scope.manager.itemError( url ); - } // console.timeEnd( 'Total parsing: ' ); + } + + // console.timeEnd( 'Total parsing: ' ); }, onProgress, onError ); } - parse( iffBuffer, path, modelName ) { - _lwoTree = new THREE.IFFParser().parse( iffBuffer ); // console.log( 'lwoTree', lwoTree ); + _lwoTree = new THREE.IFFParser().parse( iffBuffer ); + + // console.log( 'lwoTree', lwoTree ); const textureLoader = new THREE.TextureLoader( this.manager ).setPath( this.resourcePath || path ).setCrossOrigin( this.crossOrigin ); return new LWOTreeParser( textureLoader ).parse( modelName ); } - } // Parse the lwoTree object - + } + // Parse the lwoTree object class LWOTreeParser { constructor( textureLoader ) { @@ -79,7 +81,6 @@ this.textureLoader = textureLoader; } - parse( modelName ) { this.materials = new MaterialParser( this.textureLoader ).parse(); @@ -91,16 +92,15 @@ }; } - parseLayers() { // array of all meshes for building hierarchy - const meshes = []; // final array containing meshes with scene graph hierarchy set up + const meshes = []; + // final array containing meshes with scene graph hierarchy set up const finalMeshes = []; const geometryParser = new GeometryParser(); const scope = this; - _lwoTree.layers.forEach( function ( layer ) { const geometry = geometryParser.parse( layer.geometry, layer ); @@ -109,12 +109,10 @@ if ( layer.parent === - 1 ) finalMeshes.push( mesh ); else meshes[ layer.parent ].add( mesh ); } ); - this.applyPivots( finalMeshes ); return finalMeshes; } - parseMesh( geometry, layer ) { let mesh; @@ -125,9 +123,9 @@ mesh.userData.pivot = layer.pivot; return mesh; - } // TODO: may need to be reversed in z to convert LWO to three.js coordinates - + } + // TODO: may need to be reversed in z to convert LWO to three.js coordinates applyPivots( meshes ) { meshes.forEach( function ( mesh ) { @@ -138,7 +136,6 @@ child.position.x += pivot[ 0 ]; child.position.y += pivot[ 1 ]; child.position.z += pivot[ 2 ]; - if ( child.parent ) { const parentPivot = child.parent.userData.pivot; @@ -153,7 +150,6 @@ } ); } - getMaterials( namesArray, type ) { const materials = []; @@ -162,8 +158,9 @@ materials[ i ] = scope.getMaterialByName( name ); - } ); // convert materials to line or point mats if required + } ); + // convert materials to line or point mats if required if ( type === 'points' || type === 'lines' ) { materials.forEach( function ( mat, i ) { @@ -171,7 +168,6 @@ const spec = { color: mat.color }; - if ( type === 'points' ) { spec.size = 0.1; @@ -186,15 +182,14 @@ } ); - } // if there is only one material, return that directly instead of array - + } + // if there is only one material, return that directly instead of array const filtered = materials.filter( Boolean ); if ( filtered.length === 1 ) return filtered[ 0 ]; return materials; } - getMaterialByName( name ) { return this.materials.filter( function ( m ) { @@ -203,13 +198,12 @@ } )[ 0 ]; - } // If the material has an aoMap, duplicate UVs - + } + // If the material has an aoMap, duplicate UVs duplicateUVs( geometry, materials ) { let duplicateUVs = false; - if ( ! Array.isArray( materials ) ) { if ( materials.aoMap ) duplicateUVs = true; @@ -230,7 +224,6 @@ } } - class MaterialParser { constructor( textureLoader ) { @@ -238,12 +231,10 @@ this.textureLoader = textureLoader; } - parse() { const materials = []; this.textures = {}; - for ( const name in _lwoTree.materials ) { if ( _lwoTree.format === 'LWO3' ) { @@ -261,7 +252,6 @@ return materials; } - parseMaterial( materialData, name, textures ) { let params = { @@ -282,10 +272,7 @@ return new materialType( params ); } - - parseMaterialLwo2( materialData, name - /*, textures*/ - ) { + parseMaterialLwo2( materialData, name /*, textures*/ ) { let params = { name: name, @@ -296,38 +283,33 @@ params = Object.assign( params, attributes ); return new THREE.MeshPhongMaterial( params ); - } // Note: converting from left to right handed coords by switching x -> -x in vertices, and + } + + // Note: converting from left to right handed coords by switching x -> -x in vertices, and // then switching mat THREE.FrontSide -> THREE.BackSide // NB: this means that THREE.FrontSide and THREE.BackSide have been switched! - - getSide( attributes ) { if ( ! attributes.side ) return THREE.BackSide; - switch ( attributes.side ) { case 0: case 1: return THREE.BackSide; - case 2: return THREE.FrontSide; - case 3: return THREE.DoubleSide; } } - getSmooth( attributes ) { if ( ! attributes.smooth ) return true; return ! attributes.smooth; } - parseConnections( connections, nodes ) { const materialConnections = { @@ -361,7 +343,6 @@ return materialConnections; } - getNodeByRefName( refName, nodes ) { for ( const name in nodes ) { @@ -371,11 +352,9 @@ } } - parseTextureNodes( textureNodes ) { const maps = {}; - for ( const name in textureNodes ) { const node = textureNodes[ name ]; @@ -384,70 +363,60 @@ const texture = this.loadTexture( path ); if ( node.widthWrappingMode !== undefined ) texture.wrapS = this.getWrappingType( node.widthWrappingMode ); if ( node.heightWrappingMode !== undefined ) texture.wrapT = this.getWrappingType( node.heightWrappingMode ); - switch ( name ) { case 'Color': maps.map = texture; break; - case 'Roughness': maps.roughnessMap = texture; maps.roughness = 1; break; - case 'Specular': maps.specularMap = texture; maps.specular = 0xffffff; break; - case 'Luminous': maps.emissiveMap = texture; maps.emissive = 0x808080; break; - case 'Luminous THREE.Color': maps.emissive = 0x808080; break; - case 'Metallic': maps.metalnessMap = texture; maps.metalness = 1; break; - case 'Transparency': case 'Alpha': maps.alphaMap = texture; maps.transparent = true; break; - case 'Normal': maps.normalMap = texture; if ( node.amplitude !== undefined ) maps.normalScale = new THREE.Vector2( node.amplitude, node.amplitude ); break; - case 'Bump': maps.bumpMap = texture; break; } - } // LWO BSDF materials can have both spec and rough, but this is not valid in three - + } + // LWO BSDF materials can have both spec and rough, but this is not valid in three if ( maps.roughnessMap && maps.specularMap ) delete maps.specularMap; return maps; - } // maps can also be defined on individual material attributes, parse those here - // This occurs on Standard (Phong) surfaces - + } + // maps can also be defined on individual material attributes, parse those here + // This occurs on Standard (Phong) surfaces parseAttributeImageMaps( attributes, textures, maps ) { for ( const name in attributes ) { const attribute = attributes[ name ]; - if ( attribute.maps ) { const mapData = attribute.maps[ 0 ]; @@ -456,47 +425,38 @@ const texture = this.loadTexture( path ); if ( mapData.wrap !== undefined ) texture.wrapS = this.getWrappingType( mapData.wrap.w ); if ( mapData.wrap !== undefined ) texture.wrapT = this.getWrappingType( mapData.wrap.h ); - switch ( name ) { case 'Color': maps.map = texture; break; - case 'Diffuse': maps.aoMap = texture; break; - case 'Roughness': maps.roughnessMap = texture; maps.roughness = 1; break; - case 'Specular': maps.specularMap = texture; maps.specular = 0xffffff; break; - case 'Luminosity': maps.emissiveMap = texture; maps.emissive = 0x808080; break; - case 'Metallic': maps.metalnessMap = texture; maps.metalness = 1; break; - case 'Transparency': case 'Alpha': maps.alphaMap = texture; maps.transparent = true; break; - case 'Normal': maps.normalMap = texture; break; - case 'Bump': maps.bumpMap = texture; break; @@ -508,17 +468,16 @@ } } - parseAttributes( attributes, maps ) { - const params = {}; // don't use color data if color map is present + const params = {}; + // don't use color data if color map is present if ( attributes.Color && ! maps.map ) { params.color = new THREE.Color().fromArray( attributes.Color.value ); } else params.color = new THREE.Color(); - if ( attributes.Transparency && attributes.Transparency.value !== 0 ) { params.opacity = 1 - attributes.Transparency.value; @@ -533,15 +492,11 @@ return params; } - - parsePhysicalAttributes( params, attributes - /*, maps*/ - ) { + parsePhysicalAttributes( params, attributes /*, maps*/ ) { if ( attributes.Clearcoat && attributes.Clearcoat.value > 0 ) { params.clearcoat = attributes.Clearcoat.value; - if ( attributes[ 'Clearcoat Gloss' ] ) { params.clearcoatRoughness = 0.5 * ( 1 - attributes[ 'Clearcoat Gloss' ].value ); @@ -551,13 +506,11 @@ } } - parseStandardAttributes( params, attributes, maps ) { if ( attributes.Luminous ) { params.emissiveIntensity = attributes.Luminous.value; - if ( attributes[ 'Luminous THREE.Color' ] && ! maps.emissive ) { params.emissive = new THREE.Color().fromArray( attributes[ 'Luminous THREE.Color' ].value ); @@ -574,12 +527,10 @@ if ( attributes.Metallic && ! maps.metalnessMap ) params.metalness = attributes.Metallic.value; } - parsePhongAttributes( params, attributes, maps ) { if ( attributes[ 'Refraction Index' ] ) params.refractionRatio = 0.98 / attributes[ 'Refraction Index' ].value; if ( attributes.Diffuse ) params.color.multiplyScalar( attributes.Diffuse.value ); - if ( attributes.Reflection ) { params.reflectivity = attributes.Reflection.value; @@ -590,7 +541,6 @@ if ( attributes.Luminosity ) { params.emissiveIntensity = attributes.Luminosity.value; - if ( ! maps.emissiveMap && ! maps.map ) { params.emissive = params.color; @@ -601,9 +551,9 @@ } - } // parse specular if there is no roughness - we will interpret the material as 'Phong' in this case - + } + // parse specular if there is no roughness - we will interpret the material as 'Phong' in this case if ( ! attributes.Roughness && attributes.Specular && ! maps.specularMap ) { if ( attributes[ 'Color Highlight' ] ) { @@ -621,17 +571,16 @@ if ( params.specular && attributes.Glossiness ) params.shininess = 7 + Math.pow( 2, attributes.Glossiness.value * 12 + 2 ); } - parseEnvMap( connections, maps, attributes ) { if ( connections.envMap ) { const envMap = this.loadTexture( connections.envMap ); - if ( attributes.transparent && attributes.opacity < 0.999 ) { - envMap.mapping = THREE.EquirectangularRefractionMapping; // Reflectivity and refraction mapping don't work well together in Phong materials + envMap.mapping = THREE.EquirectangularRefractionMapping; + // Reflectivity and refraction mapping don't work well together in Phong materials if ( attributes.reflectivity !== undefined ) { delete attributes.reflectivity; @@ -648,29 +597,25 @@ attributes.opacity = 1; // transparency fades out refraction, forcing opacity to 1 ensures a closer visual match to the material in Lightwave. } else envMap.mapping = THREE.EquirectangularReflectionMapping; - maps.envMap = envMap; } - } // get texture defined at top level by its index - + } + // get texture defined at top level by its index getTexturePathByIndex( index ) { let fileName = ''; if ( ! _lwoTree.textures ) return fileName; - _lwoTree.textures.forEach( function ( texture ) { if ( texture.index === index ) fileName = texture.fileName; } ); - return fileName; } - loadTexture( path ) { if ( ! path ) return null; @@ -681,9 +626,9 @@ } ); return texture; - } // 0 = Reset, 1 = Repeat, 2 = Mirror, 3 = Edge - + } + // 0 = Reset, 1 = Repeat, 2 = Mirror, 3 = Edge getWrappingType( num ) { switch ( num ) { @@ -691,20 +636,16 @@ case 0: console.warn( 'LWOLoader: "Reset" texture wrapping type is not supported in three.js' ); return THREE.ClampToEdgeWrapping; - case 1: return THREE.RepeatWrapping; - case 2: return THREE.MirroredRepeatWrapping; - case 3: return THREE.ClampToEdgeWrapping; } } - getMaterialType( nodeData ) { if ( nodeData.Clearcoat && nodeData.Clearcoat.value > 0 ) return THREE.MeshPhysicalMaterial; @@ -714,7 +655,6 @@ } } - class GeometryParser { parse( geoData, layer ) { @@ -726,17 +666,20 @@ this.parseGroups( geometry, geoData ); geometry.computeVertexNormals(); this.parseUVs( geometry, layer, indices ); - this.parseMorphTargets( geometry, layer, indices ); // TODO: z may need to be reversed to account for coordinate system change + this.parseMorphTargets( geometry, layer, indices ); - geometry.translate( - layer.pivot[ 0 ], - layer.pivot[ 1 ], - layer.pivot[ 2 ] ); // let userData = geometry.userData; + // TODO: z may need to be reversed to account for coordinate system change + geometry.translate( - layer.pivot[ 0 ], - layer.pivot[ 1 ], - layer.pivot[ 2 ] ); + + // let userData = geometry.userData; // geometry = geometry.toNonIndexed() // geometry.userData = userData; return geometry; - } // split quads into tris - + } + // split quads into tris splitIndices( indices, polygonDimensions ) { const remappedIndices = []; @@ -768,9 +711,9 @@ } ); return remappedIndices; - } // NOTE: currently ignoring poly indices and assuming that they are intelligently ordered - + } + // NOTE: currently ignoring poly indices and assuming that they are intelligently ordered parseGroups( geometry, geoData ) { const tags = _lwoTree.tags; @@ -780,24 +723,20 @@ if ( geoData.type === 'points' ) elemSize = 1; const remappedIndices = this.splitMaterialIndices( geoData.polygonDimensions, geoData.materialIndices ); let indexNum = 0; // create new indices in numerical order - const indexPairs = {}; // original indices mapped to numerical indices let prevMaterialIndex; let materialIndex; let prevStart = 0; let currentCount = 0; - for ( let i = 0; i < remappedIndices.length; i += 2 ) { materialIndex = remappedIndices[ i + 1 ]; if ( i === 0 ) matNames[ indexNum ] = tags[ materialIndex ]; if ( prevMaterialIndex === undefined ) prevMaterialIndex = materialIndex; - if ( materialIndex !== prevMaterialIndex ) { let currentIndex; - if ( indexPairs[ tags[ prevMaterialIndex ] ] ) { currentIndex = indexPairs[ tags[ prevMaterialIndex ] ]; @@ -820,13 +759,12 @@ currentCount += elemSize; - } // the loop above doesn't add the last group, do that here. - + } + // the loop above doesn't add the last group, do that here. if ( geometry.groups.length > 0 ) { let currentIndex; - if ( indexPairs[ tags[ materialIndex ] ] ) { currentIndex = indexPairs[ tags[ materialIndex ] ]; @@ -841,13 +779,12 @@ geometry.addGroup( prevStart, currentCount, currentIndex ); - } // Mat names from TAGS chunk, used to build up an array of materials for this geometry - + } + // Mat names from TAGS chunk, used to build up an array of materials for this geometry geometry.userData.matNames = matNames; } - splitMaterialIndices( polygonDimensions, indices ) { const remappedIndices = []; @@ -875,7 +812,9 @@ } ); return remappedIndices; - } // UV maps: + } + + // UV maps: // 1: are defined via index into an array of points, not into a geometry // - the geometry is also defined by an index into this array, but the indexes may not match // 2: there can be any number of UV maps for a single geometry. Here these are combined, @@ -884,8 +823,6 @@ // 4: UV maps can be VMAP or VMAD (discontinuous, to allow for seams). In practice, most // UV maps are defined as partially VMAP and partially VMAD // VMADs are currently not supported - - parseUVs( geometry, layer ) { // start by creating a UV map set to zero for the whole geometry @@ -894,7 +831,6 @@ return 0; } ); - for ( const name in layer.uvs ) { const uvs = layer.uvs[ name ].uvs; @@ -911,11 +847,9 @@ geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( remappedUVs, 2 ) ); } - parseMorphTargets( geometry, layer ) { let num = 0; - for ( const name in layer.morphTargets ) { const remappedPoints = geometry.attributes.position.array.slice(); @@ -950,8 +884,9 @@ } - } // ************** UTILITY FUNCTIONS ************** + } + // ************** UTILITY FUNCTIONS ************** function extractParentUrl( url, dir ) { diff --git a/examples/js/loaders/LogLuvLoader.js b/examples/js/loaders/LogLuvLoader.js index e65f92f00329d8..0dfc7507b35add 100644 --- a/examples/js/loaders/LogLuvLoader.js +++ b/examples/js/loaders/LogLuvLoader.js @@ -8,7 +8,6 @@ this.type = THREE.HalfFloatType; } - parse( buffer ) { const ifds = UTIF.decode( buffer ); @@ -24,7 +23,6 @@ }; } - setDataType( value ) { this.type = value; @@ -32,30 +30,26 @@ } - } // from https://github.com/photopea/UTIF.js (MIT License) + } + // from https://github.com/photopea/UTIF.js (MIT License) const UTIF = {}; - UTIF.decode = function ( buff, prm ) { if ( prm == null ) prm = { parseMN: true, debug: false }; // read MakerNote, debug - var data = new Uint8Array( buff ), offset = 0; - var id = UTIF._binBE.readASCII( data, offset, 2 ); - offset += 2; var bin = id == 'II' ? UTIF._binLE : UTIF._binBE; bin.readUshort( data, offset ); offset += 2; var ifdo = bin.readUint( data, offset ); var ifds = []; - while ( true ) { var cnt = bin.readUshort( data, ifdo ), @@ -68,7 +62,6 @@ } UTIF._readIFD( bin, data, ifdo, ifds, 0, prm ); - ifdo = bin.readUint( data, ifdo + 2 + cnt * 12 ); if ( ifdo == 0 ) break; @@ -82,26 +75,19 @@ if ( img.data ) return; var data = new Uint8Array( buff ); - var id = UTIF._binBE.readASCII( data, 0, 2 ); - if ( img[ 't256' ] == null ) return; // No width => probably not an image - img.isLE = id == 'II'; img.width = img[ 't256' ][ 0 ]; //delete img["t256"]; - img.height = img[ 't257' ][ 0 ]; //delete img["t257"]; var cmpr = img[ 't259' ] ? img[ 't259' ][ 0 ] : 1; //delete img["t259"]; - var fo = img[ 't266' ] ? img[ 't266' ][ 0 ] : 1; //delete img["t266"]; - if ( img[ 't284' ] && img[ 't284' ][ 0 ] == 2 ) console.log( 'PlanarConfiguration 2 should not be used!' ); if ( cmpr == 7 && img[ 't258' ] && img[ 't258' ].length > 3 ) img[ 't258' ] = img[ 't258' ].slice( 0, 3 ); var bipp; // bits per pixel - - if ( img[ 't258' ] ) bipp = Math.min( 32, img[ 't258' ][ 0 ] ) * img[ 't258' ].length; else bipp = img[ 't277' ] ? img[ 't277' ][ 0 ] : 1; // Some .NEF files have t258==14, even though they use 16 bits per pixel - + if ( img[ 't258' ] ) bipp = Math.min( 32, img[ 't258' ][ 0 ] ) * img[ 't258' ].length; else bipp = img[ 't277' ] ? img[ 't277' ][ 0 ] : 1; + // Some .NEF files have t258==14, even though they use 16 bits per pixel if ( cmpr == 1 && img[ 't279' ] != null && img[ 't278' ] && img[ 't262' ][ 0 ] == 32803 ) { bipp = Math.round( img[ 't279' ][ 0 ] * 8 / ( img.width * img[ 't278' ][ 0 ] ) ); @@ -113,11 +99,10 @@ if ( soff == null ) soff = img[ 't324' ]; var bcnt = img[ 't279' ]; if ( cmpr == 1 && soff.length == 1 ) bcnt = [ img.height * ( bipl >>> 3 ) ]; - if ( bcnt == null ) bcnt = img[ 't325' ]; //bcnt[0] = Math.min(bcnt[0], data.length); // Hasselblad, "RAW_HASSELBLAD_H3D39II.3FR" - + if ( bcnt == null ) bcnt = img[ 't325' ]; + //bcnt[0] = Math.min(bcnt[0], data.length); // Hasselblad, "RAW_HASSELBLAD_H3D39II.3FR" var bytes = new Uint8Array( img.height * ( bipl >>> 3 ) ), bilen = 0; - if ( img[ 't322' ] != null ) { var tw = img[ 't322' ][ 0 ], @@ -125,16 +110,12 @@ var tx = Math.floor( ( img.width + tw - 1 ) / tw ); var ty = Math.floor( ( img.height + th - 1 ) / th ); var tbuff = new Uint8Array( Math.ceil( tw * th * bipp / 8 ) | 0 ); - for ( var y = 0; y < ty; y ++ ) for ( var x = 0; x < tx; x ++ ) { var i = y * tx + x; - for ( var j = 0; j < tbuff.length; j ++ ) tbuff[ j ] = 0; - - UTIF.decode._decompress( img, ifds, data, soff[ i ], bcnt[ i ], cmpr, tbuff, 0, fo ); // Might be required for 7 too. Need to check - - + UTIF.decode._decompress( img, ifds, data, soff[ i ], bcnt[ i ], cmpr, tbuff, 0, fo ); + // Might be required for 7 too. Need to check if ( cmpr == 6 ) bytes = tbuff; else UTIF._copyTile( tbuff, Math.ceil( tw * bipp / 8 ) | 0, th, bytes, Math.ceil( img.width * bipp / 8 ) | 0, img.height, Math.ceil( x * tw * bipp / 8 ) | 0, y * th ); } @@ -145,11 +126,9 @@ var rps = img[ 't278' ] ? img[ 't278' ][ 0 ] : img.height; rps = Math.min( rps, img.height ); - for ( var i = 0; i < soff.length; i ++ ) { UTIF.decode._decompress( img, ifds, data, soff[ i ], bcnt[ i ], cmpr, bytes, Math.ceil( bilen / 8 ) | 0, fo ); - bilen += bipl * rps; } @@ -166,20 +145,23 @@ //console.log("compression", cmpr); //var time = Date.now(); - if ( cmpr == 34676 ) UTIF.decode._decodeLogLuv32( img, data, off, len, tgt, toff ); else console.log( 'Unsupported compression', cmpr ); //console.log(Date.now()-time); + if ( cmpr == 34676 ) UTIF.decode._decodeLogLuv32( img, data, off, len, tgt, toff ); else console.log( 'Unsupported compression', cmpr ); + + //console.log(Date.now()-time); var bps = img[ 't258' ] ? Math.min( 32, img[ 't258' ][ 0 ] ) : 1; var noc = img[ 't277' ] ? img[ 't277' ][ 0 ] : 1, bpp = bps * noc >>> 3, h = img[ 't278' ] ? img[ 't278' ][ 0 ] : img.height, - bpl = Math.ceil( bps * noc * img.width / 8 ); // convert to Little Endian /* + bpl = Math.ceil( bps * noc * img.width / 8 ); - if ( bps == 16 && ! img.isLE && img[ 't33422' ] == null ) // not DNG + // convert to Little Endian /* + if ( bps == 16 && ! img.isLE && img[ 't33422' ] == null ) + // not DNG for ( var y = 0; y < h; y ++ ) { //console.log("fixing endianity"); var roff = toff + y * bpl; - for ( var x = 1; x < bpl; x += 2 ) { var t = tgt[ roff + x ]; @@ -221,29 +203,23 @@ qw = w * 4; var io = 0, out = new Uint8Array( qw ); - while ( io < len ) { var oo = 0; - while ( oo < qw ) { var c = data[ off + io ]; io ++; - if ( c < 128 ) { for ( var j = 0; j < c; j ++ ) out[ oo + j ] = data[ off + io + j ]; - oo += c; io += c; } else { c = c - 126; - for ( var j = 0; j < c; j ++ ) out[ oo + j ] = data[ off + io ]; - oo += c; io ++; @@ -265,9 +241,9 @@ }; - UTIF.tags = {}; //UTIF.ttypes = { 256:3,257:3,258:3, 259:3, 262:3, 273:4, 274:3, 277:3,278:4,279:4, 282:5, 283:5, 284:3, 286:5,287:5, 296:3, 305:2, 306:2, 338:3, 513:4, 514:4, 34665:4 }; + UTIF.tags = {}; + //UTIF.ttypes = { 256:3,257:3,258:3, 259:3, 262:3, 273:4, 274:3, 277:3,278:4,279:4, 282:5, 283:5, 284:3, 286:5,287:5, 296:3, 305:2, 306:2, 338:3, 513:4, 514:4, 34665:4 }; // start at tag 250 - UTIF._types = function () { var main = new Array( 250 ); @@ -339,14 +315,12 @@ }; }(); - UTIF._readIFD = function ( bin, data, offset, ifds, depth, prm ) { var cnt = bin.readUshort( data, offset ); offset += 2; var ifd = {}; if ( prm.debug ) console.log( ' '.repeat( depth ), ifds.length - 1, '>>>----------------' ); - for ( var i = 0; i < cnt; i ++ ) { var tag = bin.readUshort( data, offset ); @@ -357,8 +331,8 @@ offset += 4; var voff = bin.readUint( data, offset ); offset += 4; - var arr = []; //ifd["t"+tag+"-"+UTIF.tags[tag]] = arr; - + var arr = []; + //ifd["t"+tag+"-"+UTIF.tags[tag]] = arr; if ( type == 1 || type == 7 ) { arr = new Uint8Array( data.buffer, num < 5 ? offset - 4 : voff, num ); @@ -389,7 +363,6 @@ if ( type == 5 || type == 10 ) { var ri = type == 5 ? bin.readUint : bin.readInt; - for ( var j = 0; j < num; j ++ ) arr.push( [ ri( data, voff + j * 8 ), ri( data, voff + j * 8 + 4 ) ] ); } @@ -428,18 +401,14 @@ if ( prm.debug ) console.log( ' '.repeat( depth ), tag, type, UTIF.tags[ tag ], arr ); ifd[ 't' + tag ] = arr; - if ( tag == 330 || tag == 34665 || tag == 34853 || tag == 50740 && bin.readUshort( data, bin.readUint( arr, 0 ) ) < 300 || tag == 61440 ) { var oarr = tag == 50740 ? [ bin.readUint( arr, 0 ) ] : arr; var subfd = []; - for ( var j = 0; j < oarr.length; j ++ ) UTIF._readIFD( bin, data, oarr[ j ], subfd, depth + 1, prm ); - if ( tag == 330 ) ifd.subIFD = subfd; if ( tag == 34665 ) ifd.exifIFD = subfd[ 0 ]; if ( tag == 34853 ) ifd.gpsiIFD = subfd[ 0 ]; //console.log("gps", subfd[0]); } - if ( tag == 50740 ) ifd.dngPrvt = subfd[ 0 ]; if ( tag == 61440 ) ifd.fujiIFD = subfd[ 0 ]; @@ -447,14 +416,12 @@ if ( tag == 37500 && prm.parseMN ) { - var mn = arr; //console.log(bin.readASCII(mn,0,mn.length), mn); - + var mn = arr; + //console.log(bin.readASCII(mn,0,mn.length), mn); if ( bin.readASCII( mn, 0, 5 ) == 'Nikon' ) ifd.makerNote = UTIF[ 'decode' ]( mn.slice( 10 ).buffer )[ 0 ]; else if ( bin.readUshort( data, voff ) < 300 && bin.readUshort( data, voff + 4 ) <= 12 ) { var subsub = []; - UTIF._readIFD( bin, data, voff, subsub, depth + 1, prm ); - ifd.makerNote = subsub[ 0 ]; } @@ -476,17 +443,14 @@ area = w * h, data = out.data; let img; - switch ( type ) { case THREE.HalfFloatType: img = new Uint16Array( area * 4 ); break; - case THREE.FloatType: img = new Float32Array( area * 4 ); break; - default: console.error( 'THREE.LogLuvLoader: Unsupported texture data type:', type ); @@ -495,7 +459,6 @@ let intp = out[ 't262' ] ? out[ 't262' ][ 0 ] : 2; const bps = out[ 't258' ] ? Math.min( 32, out[ 't258' ][ 0 ] ) : 1; if ( out[ 't262' ] == null && bps == 1 ) intp = 0; - if ( intp == 32845 ) { for ( let y = 0; y < h; y ++ ) { @@ -507,20 +470,22 @@ let L = data[ si + 1 ] << 8 | data[ si ]; L = Math.pow( 2, ( L + 0.5 ) / 256 - 64 ); const u = ( data[ si + 3 ] + 0.5 ) / 410; - const v = ( data[ si + 5 ] + 0.5 ) / 410; // Luv to xyY + const v = ( data[ si + 5 ] + 0.5 ) / 410; + // Luv to xyY const sX = 9 * u / ( 6 * u - 16 * v + 12 ); const sY = 4 * v / ( 6 * u - 16 * v + 12 ); - const bY = L; // xyY to XYZ + const bY = L; + // xyY to XYZ const X = sX * bY / sY, Y = bY, - Z = ( 1 - sX - sY ) * bY / sY; // XYZ to linear RGB + Z = ( 1 - sX - sY ) * bY / sY; + // XYZ to linear RGB const r = 2.690 * X - 1.276 * Y - 0.414 * Z; const g = - 1.022 * X + 1.978 * Y + 0.044 * Z; const b = 0.061 * X - 0.224 * Y + 1.163 * Z; - if ( type === THREE.HalfFloatType ) { img[ qi ] = THREE.DataUtils.toHalfFloat( Math.min( r, 65504 ) ); @@ -555,7 +520,6 @@ nextZero: function ( data, o ) { while ( data[ o ] != 0 ) o ++; - return o; }, @@ -595,27 +559,21 @@ readASCII: function ( buff, p, l ) { var s = ''; - for ( var i = 0; i < l; i ++ ) s += String.fromCharCode( buff[ p + i ] ); - return s; }, readFloat: function ( buff, p ) { var a = UTIF._binBE.ui8; - for ( var i = 0; i < 4; i ++ ) a[ i ] = buff[ p + 3 - i ]; - return UTIF._binBE.fl32[ 0 ]; }, readDouble: function ( buff, p ) { var a = UTIF._binBE.ui8; - for ( var i = 0; i < 8; i ++ ) a[ i ] = buff[ p + 7 - i ]; - return UTIF._binBE.fl64[ 0 ]; }, @@ -651,7 +609,6 @@ writeDouble: function ( buff, p, n ) { UTIF._binBE.fl64[ 0 ] = n; - for ( var i = 0; i < 8; i ++ ) buff[ p + i ] = UTIF._binBE.ui8[ 7 - i ]; } @@ -701,18 +658,14 @@ readFloat: function ( buff, p ) { var a = UTIF._binBE.ui8; - for ( var i = 0; i < 4; i ++ ) a[ i ] = buff[ p + i ]; - return UTIF._binBE.fl32[ 0 ]; }, readDouble: function ( buff, p ) { var a = UTIF._binBE.ui8; - for ( var i = 0; i < 8; i ++ ) a[ i ] = buff[ p + i ]; - return UTIF._binBE.fl64[ 0 ]; }, @@ -742,18 +695,15 @@ }, writeASCII: UTIF._binBE.writeASCII }; - UTIF._copyTile = function ( tb, tw, th, b, w, h, xoff, yoff ) { //log("copyTile", tw, th, w, h, xoff, yoff); var xlim = Math.min( tw, w - xoff ); var ylim = Math.min( th, h - yoff ); - for ( var y = 0; y < ylim; y ++ ) { var tof = ( yoff + y ) * w + xoff; var sof = y * tw; - for ( var x = 0; x < xlim; x ++ ) b[ tof + x ] = tb[ sof + x ]; } diff --git a/examples/js/loaders/LottieLoader.js b/examples/js/loaders/LottieLoader.js index 11b272f9a658e2..abdb170c25e0ec 100644 --- a/examples/js/loaders/LottieLoader.js +++ b/examples/js/loaders/LottieLoader.js @@ -7,7 +7,6 @@ this._quality = value; } - load( url, onLoad, onProgress, onError ) { const quality = this._quality || 1; @@ -18,14 +17,16 @@ loader.setWithCredentials( this.withCredentials ); loader.load( url, function ( text ) { - const data = JSON.parse( text ); // bodymoving uses container.offetWidth and offsetHeight + const data = JSON.parse( text ); + + // lottie uses container.offetWidth and offsetHeight // to define width/height const container = document.createElement( 'div' ); container.style.width = data.w + 'px'; container.style.height = data.h + 'px'; document.body.appendChild( container ); - const animation = bodymovin.loadAnimation( { + const animation = lottie.loadAnimation( { container: container, animType: 'canvas', loop: true, @@ -43,7 +44,6 @@ } ); container.style.display = 'none'; - if ( onLoad !== undefined ) { onLoad( texture ); diff --git a/examples/js/loaders/MD2Loader.js b/examples/js/loaders/MD2Loader.js index fe5af260482248..4ff3055a047cdc 100644 --- a/examples/js/loaders/MD2Loader.js +++ b/examples/js/loaders/MD2Loader.js @@ -1,7 +1,6 @@ ( function () { const _normalData = [[ - 0.525731, 0.000000, 0.850651 ], [ - 0.442863, 0.238856, 0.864188 ], [ - 0.295242, 0.000000, 0.955423 ], [ - 0.309017, 0.500000, 0.809017 ], [ - 0.162460, 0.262866, 0.951056 ], [ 0.000000, 0.000000, 1.000000 ], [ 0.000000, 0.850651, 0.525731 ], [ - 0.147621, 0.716567, 0.681718 ], [ 0.147621, 0.716567, 0.681718 ], [ 0.000000, 0.525731, 0.850651 ], [ 0.309017, 0.500000, 0.809017 ], [ 0.525731, 0.000000, 0.850651 ], [ 0.295242, 0.000000, 0.955423 ], [ 0.442863, 0.238856, 0.864188 ], [ 0.162460, 0.262866, 0.951056 ], [ - 0.681718, 0.147621, 0.716567 ], [ - 0.809017, 0.309017, 0.500000 ], [ - 0.587785, 0.425325, 0.688191 ], [ - 0.850651, 0.525731, 0.000000 ], [ - 0.864188, 0.442863, 0.238856 ], [ - 0.716567, 0.681718, 0.147621 ], [ - 0.688191, 0.587785, 0.425325 ], [ - 0.500000, 0.809017, 0.309017 ], [ - 0.238856, 0.864188, 0.442863 ], [ - 0.425325, 0.688191, 0.587785 ], [ - 0.716567, 0.681718, - 0.147621 ], [ - 0.500000, 0.809017, - 0.309017 ], [ - 0.525731, 0.850651, 0.000000 ], [ 0.000000, 0.850651, - 0.525731 ], [ - 0.238856, 0.864188, - 0.442863 ], [ 0.000000, 0.955423, - 0.295242 ], [ - 0.262866, 0.951056, - 0.162460 ], [ 0.000000, 1.000000, 0.000000 ], [ 0.000000, 0.955423, 0.295242 ], [ - 0.262866, 0.951056, 0.162460 ], [ 0.238856, 0.864188, 0.442863 ], [ 0.262866, 0.951056, 0.162460 ], [ 0.500000, 0.809017, 0.309017 ], [ 0.238856, 0.864188, - 0.442863 ], [ 0.262866, 0.951056, - 0.162460 ], [ 0.500000, 0.809017, - 0.309017 ], [ 0.850651, 0.525731, 0.000000 ], [ 0.716567, 0.681718, 0.147621 ], [ 0.716567, 0.681718, - 0.147621 ], [ 0.525731, 0.850651, 0.000000 ], [ 0.425325, 0.688191, 0.587785 ], [ 0.864188, 0.442863, 0.238856 ], [ 0.688191, 0.587785, 0.425325 ], [ 0.809017, 0.309017, 0.500000 ], [ 0.681718, 0.147621, 0.716567 ], [ 0.587785, 0.425325, 0.688191 ], [ 0.955423, 0.295242, 0.000000 ], [ 1.000000, 0.000000, 0.000000 ], [ 0.951056, 0.162460, 0.262866 ], [ 0.850651, - 0.525731, 0.000000 ], [ 0.955423, - 0.295242, 0.000000 ], [ 0.864188, - 0.442863, 0.238856 ], [ 0.951056, - 0.162460, 0.262866 ], [ 0.809017, - 0.309017, 0.500000 ], [ 0.681718, - 0.147621, 0.716567 ], [ 0.850651, 0.000000, 0.525731 ], [ 0.864188, 0.442863, - 0.238856 ], [ 0.809017, 0.309017, - 0.500000 ], [ 0.951056, 0.162460, - 0.262866 ], [ 0.525731, 0.000000, - 0.850651 ], [ 0.681718, 0.147621, - 0.716567 ], [ 0.681718, - 0.147621, - 0.716567 ], [ 0.850651, 0.000000, - 0.525731 ], [ 0.809017, - 0.309017, - 0.500000 ], [ 0.864188, - 0.442863, - 0.238856 ], [ 0.951056, - 0.162460, - 0.262866 ], [ 0.147621, 0.716567, - 0.681718 ], [ 0.309017, 0.500000, - 0.809017 ], [ 0.425325, 0.688191, - 0.587785 ], [ 0.442863, 0.238856, - 0.864188 ], [ 0.587785, 0.425325, - 0.688191 ], [ 0.688191, 0.587785, - 0.425325 ], [ - 0.147621, 0.716567, - 0.681718 ], [ - 0.309017, 0.500000, - 0.809017 ], [ 0.000000, 0.525731, - 0.850651 ], [ - 0.525731, 0.000000, - 0.850651 ], [ - 0.442863, 0.238856, - 0.864188 ], [ - 0.295242, 0.000000, - 0.955423 ], [ - 0.162460, 0.262866, - 0.951056 ], [ 0.000000, 0.000000, - 1.000000 ], [ 0.295242, 0.000000, - 0.955423 ], [ 0.162460, 0.262866, - 0.951056 ], [ - 0.442863, - 0.238856, - 0.864188 ], [ - 0.309017, - 0.500000, - 0.809017 ], [ - 0.162460, - 0.262866, - 0.951056 ], [ 0.000000, - 0.850651, - 0.525731 ], [ - 0.147621, - 0.716567, - 0.681718 ], [ 0.147621, - 0.716567, - 0.681718 ], [ 0.000000, - 0.525731, - 0.850651 ], [ 0.309017, - 0.500000, - 0.809017 ], [ 0.442863, - 0.238856, - 0.864188 ], [ 0.162460, - 0.262866, - 0.951056 ], [ 0.238856, - 0.864188, - 0.442863 ], [ 0.500000, - 0.809017, - 0.309017 ], [ 0.425325, - 0.688191, - 0.587785 ], [ 0.716567, - 0.681718, - 0.147621 ], [ 0.688191, - 0.587785, - 0.425325 ], [ 0.587785, - 0.425325, - 0.688191 ], [ 0.000000, - 0.955423, - 0.295242 ], [ 0.000000, - 1.000000, 0.000000 ], [ 0.262866, - 0.951056, - 0.162460 ], [ 0.000000, - 0.850651, 0.525731 ], [ 0.000000, - 0.955423, 0.295242 ], [ 0.238856, - 0.864188, 0.442863 ], [ 0.262866, - 0.951056, 0.162460 ], [ 0.500000, - 0.809017, 0.309017 ], [ 0.716567, - 0.681718, 0.147621 ], [ 0.525731, - 0.850651, 0.000000 ], [ - 0.238856, - 0.864188, - 0.442863 ], [ - 0.500000, - 0.809017, - 0.309017 ], [ - 0.262866, - 0.951056, - 0.162460 ], [ - 0.850651, - 0.525731, 0.000000 ], [ - 0.716567, - 0.681718, - 0.147621 ], [ - 0.716567, - 0.681718, 0.147621 ], [ - 0.525731, - 0.850651, 0.000000 ], [ - 0.500000, - 0.809017, 0.309017 ], [ - 0.238856, - 0.864188, 0.442863 ], [ - 0.262866, - 0.951056, 0.162460 ], [ - 0.864188, - 0.442863, 0.238856 ], [ - 0.809017, - 0.309017, 0.500000 ], [ - 0.688191, - 0.587785, 0.425325 ], [ - 0.681718, - 0.147621, 0.716567 ], [ - 0.442863, - 0.238856, 0.864188 ], [ - 0.587785, - 0.425325, 0.688191 ], [ - 0.309017, - 0.500000, 0.809017 ], [ - 0.147621, - 0.716567, 0.681718 ], [ - 0.425325, - 0.688191, 0.587785 ], [ - 0.162460, - 0.262866, 0.951056 ], [ 0.442863, - 0.238856, 0.864188 ], [ 0.162460, - 0.262866, 0.951056 ], [ 0.309017, - 0.500000, 0.809017 ], [ 0.147621, - 0.716567, 0.681718 ], [ 0.000000, - 0.525731, 0.850651 ], [ 0.425325, - 0.688191, 0.587785 ], [ 0.587785, - 0.425325, 0.688191 ], [ 0.688191, - 0.587785, 0.425325 ], [ - 0.955423, 0.295242, 0.000000 ], [ - 0.951056, 0.162460, 0.262866 ], [ - 1.000000, 0.000000, 0.000000 ], [ - 0.850651, 0.000000, 0.525731 ], [ - 0.955423, - 0.295242, 0.000000 ], [ - 0.951056, - 0.162460, 0.262866 ], [ - 0.864188, 0.442863, - 0.238856 ], [ - 0.951056, 0.162460, - 0.262866 ], [ - 0.809017, 0.309017, - 0.500000 ], [ - 0.864188, - 0.442863, - 0.238856 ], [ - 0.951056, - 0.162460, - 0.262866 ], [ - 0.809017, - 0.309017, - 0.500000 ], [ - 0.681718, 0.147621, - 0.716567 ], [ - 0.681718, - 0.147621, - 0.716567 ], [ - 0.850651, 0.000000, - 0.525731 ], [ - 0.688191, 0.587785, - 0.425325 ], [ - 0.587785, 0.425325, - 0.688191 ], [ - 0.425325, 0.688191, - 0.587785 ], [ - 0.425325, - 0.688191, - 0.587785 ], [ - 0.587785, - 0.425325, - 0.688191 ], [ - 0.688191, - 0.587785, - 0.425325 ]]; - class MD2Loader extends THREE.Loader { constructor( manager ) { @@ -9,7 +8,6 @@ super( manager ); } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -43,14 +41,14 @@ }, onProgress, onError ); } - parse( buffer ) { - const data = new DataView( buffer ); // http://tfc.duke.free.fr/coding/md2-specs-en.html + const data = new DataView( buffer ); + + // http://tfc.duke.free.fr/coding/md2-specs-en.html const header = {}; const headerNames = [ 'ident', 'version', 'skinwidth', 'skinheight', 'framesize', 'num_skins', 'num_vertices', 'num_st', 'num_tris', 'num_glcmds', 'num_frames', 'offset_skins', 'offset_st', 'offset_tris', 'offset_frames', 'offset_glcmds', 'offset_end' ]; - for ( let i = 0; i < headerNames.length; i ++ ) { header[ headerNames[ i ] ] = data.getInt32( i * 4, true ); @@ -69,14 +67,16 @@ console.error( 'Corrupted MD2 file' ); return; - } // + } + + // + const geometry = new THREE.BufferGeometry(); - const geometry = new THREE.BufferGeometry(); // uvs + // uvs const uvsTemp = []; let offset = header.offset_st; - for ( let i = 0, l = header.num_st; i < l; i ++ ) { const u = data.getInt16( offset + 0, true ); @@ -84,34 +84,33 @@ uvsTemp.push( u / header.skinwidth, 1 - v / header.skinheight ); offset += 4; - } // triangles + } + // triangles offset = header.offset_tris; const vertexIndices = []; const uvIndices = []; - for ( let i = 0, l = header.num_tris; i < l; i ++ ) { vertexIndices.push( data.getUint16( offset + 0, true ), data.getUint16( offset + 2, true ), data.getUint16( offset + 4, true ) ); uvIndices.push( data.getUint16( offset + 6, true ), data.getUint16( offset + 8, true ), data.getUint16( offset + 10, true ) ); offset += 12; - } // frames + } + // frames const translation = new THREE.Vector3(); const scale = new THREE.Vector3(); const frames = []; offset = header.offset_frames; - for ( let i = 0, l = header.num_frames; i < l; i ++ ) { scale.set( data.getFloat32( offset + 0, true ), data.getFloat32( offset + 4, true ), data.getFloat32( offset + 8, true ) ); translation.set( data.getFloat32( offset + 12, true ), data.getFloat32( offset + 16, true ), data.getFloat32( offset + 20, true ) ); offset += 24; const string = []; - for ( let j = 0; j < 16; j ++ ) { const character = data.getUint8( offset + j ); @@ -126,49 +125,51 @@ normals: [] }; offset += 16; - for ( let j = 0; j < header.num_vertices; j ++ ) { let x = data.getUint8( offset ++ ); let y = data.getUint8( offset ++ ); let z = data.getUint8( offset ++ ); - const n = _normalData[ data.getUint8( offset ++ ) ]; - x = x * scale.x + translation.x; y = y * scale.y + translation.y; z = z * scale.z + translation.z; frame.vertices.push( x, z, y ); // convert to Y-up - frame.normals.push( n[ 0 ], n[ 2 ], n[ 1 ] ); // convert to Y-up } frames.push( frame ); - } // static + } + // static const positions = []; const normals = []; const uvs = []; const verticesTemp = frames[ 0 ].vertices; const normalsTemp = frames[ 0 ].normals; - for ( let i = 0, l = vertexIndices.length; i < l; i ++ ) { const vertexIndex = vertexIndices[ i ]; - let stride = vertexIndex * 3; // + let stride = vertexIndex * 3; + + // const x = verticesTemp[ stride ]; const y = verticesTemp[ stride + 1 ]; const z = verticesTemp[ stride + 2 ]; - positions.push( x, y, z ); // + positions.push( x, y, z ); + + // const nx = normalsTemp[ stride ]; const ny = normalsTemp[ stride + 1 ]; const nz = normalsTemp[ stride + 2 ]; - normals.push( nx, ny, nz ); // + normals.push( nx, ny, nz ); + + // const uvIndex = uvIndices[ i ]; stride = uvIndex * 2; @@ -180,20 +181,19 @@ geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); geometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); - geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); // animation + geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); + + // animation const morphPositions = []; const morphNormals = []; - for ( let i = 0, l = frames.length; i < l; i ++ ) { const frame = frames[ i ]; const attributeName = frame.name; - if ( frame.vertices.length > 0 ) { const positions = []; - for ( let j = 0, jl = vertexIndices.length; j < jl; j ++ ) { const vertexIndex = vertexIndices[ j ]; @@ -214,7 +214,6 @@ if ( frame.normals.length > 0 ) { const normals = []; - for ( let j = 0, jl = vertexIndices.length; j < jl; j ++ ) { const vertexIndex = vertexIndices[ j ]; diff --git a/examples/js/loaders/MDDLoader.js b/examples/js/loaders/MDDLoader.js index 3f7f9cda5bacfd..811bfeeb42ffec 100644 --- a/examples/js/loaders/MDDLoader.js +++ b/examples/js/loaders/MDDLoader.js @@ -11,7 +11,6 @@ * time values for each frame (sequence of float32) * vertex data for each frame (sequence of float32) */ - class MDDLoader extends THREE.Loader { constructor( manager ) { @@ -19,7 +18,6 @@ super( manager ); } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -33,17 +31,17 @@ }, onProgress, onError ); } - parse( data ) { const view = new DataView( data ); const totalFrames = view.getUint32( 0 ); const totalPoints = view.getUint32( 4 ); - let offset = 8; // animation clip + let offset = 8; + + // animation clip const times = new Float32Array( totalFrames ); const values = new Float32Array( totalFrames * totalFrames ).fill( 0 ); - for ( let i = 0; i < totalFrames; i ++ ) { times[ i ] = view.getFloat32( offset ); @@ -53,23 +51,21 @@ } const track = new THREE.NumberKeyframeTrack( '.morphTargetInfluences', times, values ); - const clip = new THREE.AnimationClip( 'default', times[ times.length - 1 ], [ track ] ); // morph targets + const clip = new THREE.AnimationClip( 'default', times[ times.length - 1 ], [ track ] ); - const morphTargets = []; + // morph targets + const morphTargets = []; for ( let i = 0; i < totalFrames; i ++ ) { const morphTarget = new Float32Array( totalPoints * 3 ); - for ( let j = 0; j < totalPoints; j ++ ) { const stride = j * 3; morphTarget[ stride + 0 ] = view.getFloat32( offset ); offset += 4; // x - morphTarget[ stride + 1 ] = view.getFloat32( offset ); offset += 4; // y - morphTarget[ stride + 2 ] = view.getFloat32( offset ); offset += 4; // z diff --git a/examples/js/loaders/MMDLoader.js b/examples/js/loaders/MMDLoader.js index b6d47995cac8bb..9485e3400f24b3 100644 --- a/examples/js/loaders/MMDLoader.js +++ b/examples/js/loaders/MMDLoader.js @@ -32,7 +32,6 @@ /** * @param {THREE.LoadingManager} manager */ - class MMDLoader extends THREE.Loader { constructor( manager ) { @@ -40,23 +39,23 @@ super( manager ); this.loader = new THREE.FileLoader( this.manager ); this.parser = null; // lazy generation - this.meshBuilder = new MeshBuilder( this.manager ); this.animationBuilder = new AnimationBuilder(); } + /** * @param {string} animationPath * @return {MMDLoader} */ - - setAnimationPath( animationPath ) { this.animationPath = animationPath; return this; - } // Load MMD assets as Three.js Object + } + + // Load MMD assets as Three.js Object /** * Loads Model file (.pmd or .pmx) as a THREE.SkinnedMesh. @@ -66,14 +65,13 @@ * @param {function} onProgress * @param {function} onError */ - - load( url, onLoad, onProgress, onError ) { - const builder = this.meshBuilder.setCrossOrigin( this.crossOrigin ); // resource path + const builder = this.meshBuilder.setCrossOrigin( this.crossOrigin ); - let resourcePath; + // resource path + let resourcePath; if ( this.resourcePath !== '' ) { resourcePath = this.resourcePath; @@ -88,9 +86,9 @@ } - const modelExtension = this._extractExtension( url ).toLowerCase(); // Should I detect by seeing header? - + const modelExtension = this._extractExtension( url ).toLowerCase(); + // Should I detect by seeing header? if ( modelExtension !== 'pmd' && modelExtension !== 'pmx' ) { if ( onError ) onError( new Error( 'THREE.MMDLoader: Unknown model file extension .' + modelExtension + '.' ) ); @@ -105,6 +103,7 @@ }, onProgress, onError ); } + /** * Loads Motion file(s) (.vmd) as a THREE.AnimationClip. * If two or more files are specified, they'll be merged. @@ -115,8 +114,6 @@ * @param {function} onProgress * @param {function} onError */ - - loadAnimation( url, object, onLoad, onProgress, onError ) { const builder = this.animationBuilder; @@ -127,6 +124,7 @@ }, onProgress, onError ); } + /** * Loads mode file and motion file(s) as an object containing * a THREE.SkinnedMesh and a THREE.AnimationClip. @@ -138,8 +136,6 @@ * @param {function} onProgress * @param {function} onError */ - - loadWithAnimation( modelUrl, vmdUrl, onLoad, onProgress, onError ) { const scope = this; @@ -156,7 +152,9 @@ }, onProgress, onError ); - } // Load MMD assets as Object data parsed by MMDParser + } + + // Load MMD assets as Object data parsed by MMDParser /** * Loads .pmd file as an Object. @@ -166,12 +164,9 @@ * @param {function} onProgress * @param {function} onError */ - - loadPMD( url, onLoad, onProgress, onError ) { const parser = this._getParser(); - this.loader.setMimeType( undefined ).setPath( this.path ).setResponseType( 'arraybuffer' ).setRequestHeader( this.requestHeader ).setWithCredentials( this.withCredentials ).load( url, function ( buffer ) { onLoad( parser.parsePmd( buffer, true ) ); @@ -179,6 +174,7 @@ }, onProgress, onError ); } + /** * Loads .pmx file as an Object. * @@ -187,12 +183,9 @@ * @param {function} onProgress * @param {function} onError */ - - loadPMX( url, onLoad, onProgress, onError ) { const parser = this._getParser(); - this.loader.setMimeType( undefined ).setPath( this.path ).setResponseType( 'arraybuffer' ).setRequestHeader( this.requestHeader ).setWithCredentials( this.withCredentials ).load( url, function ( buffer ) { onLoad( parser.parsePmx( buffer, true ) ); @@ -200,6 +193,7 @@ }, onProgress, onError ); } + /** * Loads .vmd file as an Object. If two or more files are specified * they'll be merged. @@ -209,18 +203,13 @@ * @param {function} onProgress * @param {function} onError */ - - loadVMD( url, onLoad, onProgress, onError ) { const urls = Array.isArray( url ) ? url : [ url ]; const vmds = []; const vmdNum = urls.length; - const parser = this._getParser(); - this.loader.setMimeType( undefined ).setPath( this.animationPath ).setResponseType( 'arraybuffer' ).setRequestHeader( this.requestHeader ).setWithCredentials( this.withCredentials ); - for ( let i = 0, il = urls.length; i < il; i ++ ) { this.loader.load( urls[ i ], function ( buffer ) { @@ -233,6 +222,7 @@ } } + /** * Loads .vpd file as an Object. * @@ -242,20 +232,18 @@ * @param {function} onProgress * @param {function} onError */ - - loadVPD( url, isUnicode, onLoad, onProgress, onError ) { const parser = this._getParser(); - this.loader.setMimeType( isUnicode ? undefined : 'text/plain; charset=shift_jis' ).setPath( this.animationPath ).setResponseType( 'text' ).setRequestHeader( this.requestHeader ).setWithCredentials( this.withCredentials ).load( url, function ( text ) { onLoad( parser.parseVpd( text, true ) ); }, onProgress, onError ); - } // private methods + } + // private methods _extractExtension( url ) { @@ -263,7 +251,6 @@ return index < 0 ? '' : url.slice( index + 1 ); } - _getParser() { if ( this.parser === null ) { @@ -282,21 +269,22 @@ } - } // Utilities + } + + // Utilities /* * base64 encoded defalut toon textures toon00.bmp - toon10.bmp. * We don't need to request external toon image files. */ - - const DEFAULT_TOON_TEXTURES = [ 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII=', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAN0lEQVRYR+3WQREAMBACsZ5/bWiiMvgEBTt5cW37hjsBBAgQIECAwFwgyfYPCCBAgAABAgTWAh8aBHZBl14e8wAAAABJRU5ErkJggg==', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAOUlEQVRYR+3WMREAMAwDsYY/yoDI7MLwIiP40+RJklfcCCBAgAABAgTqArfb/QMCCBAgQIAAgbbAB3z/e0F3js2cAAAAAElFTkSuQmCC', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAN0lEQVRYR+3WQREAMBACsZ5/B5ilMvgEBTt5cW37hjsBBAgQIECAwFwgyfYPCCBAgAABAgTWAh81dWyx0gFwKAAAAABJRU5ErkJggg==', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAOklEQVRYR+3WoREAMAwDsWb/UQtCy9wxTOQJ/oQ8SXKKGwEECBAgQIBAXeDt7f4BAQQIECBAgEBb4AOz8Hzx7WLY4wAAAABJRU5ErkJggg==', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABPUlEQVRYR+1XwW7CMAy1+f9fZOMysSEOEweEOPRNdm3HbdOyIhAcklPrOs/PLy9RygBALxzcCDQFmgJNgaZAU6Ap0BR4PwX8gsRMVLssMRH5HcpzJEaWL7EVg9F1IHRlyqQohgVr4FGUlUcMJSjcUlDw0zvjeun70cLWmneoyf7NgBTQSniBTQQSuJAZsOnnaczjIMb5hCiuHKxokCrJfVnrctyZL0PkJAJe1HMil4nxeyi3Ypfn1kX51jpPvo/JeCNC4PhVdHdJw2XjBR8brF8PEIhNVn12AgP7uHsTBguBn53MUZCqv7Lp07Pn5k1Ro+uWmUNn7D+M57rtk7aG0Vo73xyF/fbFf0bPJjDXngnGocDTdFhygZjwUQrMNrDcmZlQT50VJ/g/UwNyHpu778+yW+/ksOz/BFo54P4AsUXMfRq7XWsAAAAASUVORK5CYII=', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACMElEQVRYR+2Xv4pTQRTGf2dubhLdICiii2KnYKHVolhauKWPoGAnNr6BD6CvIVaihYuI2i1ia0BY0MZGRHQXjZj/mSPnnskfNWiWZUlzJ5k7M2cm833nO5Mziej2DWWJRUoCpQKlAntSQCqgw39/iUWAGmh37jrRnVsKlgpiqmkoGVABA7E57fvY+pJDdgKqF6HzFCSADkDq+F6AHABtQ+UMVE5D7zXod7fFNhTEckTbj5XQgHzNN+5tQvc5NG7C6BNkp6D3EmpXHDR+dQAjFLchW3VS9rlw3JBh+B7ys5Cf9z0GW1C/7P32AyBAOAz1q4jGliIH3YPuBnSfQX4OGreTIgEYQb/pBDtPnEQ4CivXYPAWBk13oHrB54yA9QuSn2H4AcKRpEILDt0BUzj+RLR1V5EqjD66NPRBVpLcQwjHoHYJOhsQv6U4mnzmrIXJCFr4LDwm/xBUoboG9XX4cc9VKdYoSA2yk5NQLJaKDUjTBoveG3Z2TElTxwjNK4M3LEZgUdDdruvcXzKBpStgp2NPiWi3ks9ZXxIoFVi+AvHLdc9TqtjL3/aYjpPlrzOcEnK62Szhimdd7xX232zFDTgtxezOu3WNMRLjiKgjtOhHVMd1loynVHvOgjuIIJMaELEqhJAV/RCSLbWTcfPFakFgFlALTRRvx+ok6Hlp/Q+v3fmx90bMyUzaEAhmM3KvHlXTL5DxnbGf/1M8RNNACLL5MNtPxP/mypJAqcDSFfgFhpYqWUzhTEAAAAAASUVORK5CYII=', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII=', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII=', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII=', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII=' ]; - const NON_ALPHA_CHANNEL_FORMATS = [ THREE.RGB_S3TC_DXT1_Format, THREE.RGB_PVRTC_4BPPV1_Format, THREE.RGB_PVRTC_2BPPV1_Format, THREE.RGB_ETC1_Format, THREE.RGB_ETC2_Format ]; // Builders. They build Three.js object from Object data parsed by MMDParser. + const NON_ALPHA_CHANNEL_FORMATS = [ THREE.RGB_S3TC_DXT1_Format, THREE.RGB_PVRTC_4BPPV1_Format, THREE.RGB_PVRTC_2BPPV1_Format, THREE.RGB_ETC1_Format, THREE.RGB_ETC2_Format ]; + + // Builders. They build Three.js object from Object data parsed by MMDParser. /** * @param {THREE.LoadingManager} manager */ - class MeshBuilder { constructor( manager ) { @@ -306,18 +294,18 @@ this.materialBuilder = new MaterialBuilder( manager ); } + /** * @param {string} crossOrigin * @return {MeshBuilder} */ - - setCrossOrigin( crossOrigin ) { this.crossOrigin = crossOrigin; return this; } + /** * @param {Object} data - parsed PMD/PMX data * @param {string} resourcePath @@ -325,73 +313,82 @@ * @param {function} onError * @return {SkinnedMesh} */ - - build( data, resourcePath, onProgress, onError ) { const geometry = this.geometryBuilder.build( data ); const material = this.materialBuilder.setCrossOrigin( this.crossOrigin ).setResourcePath( resourcePath ).build( data, geometry, onProgress, onError ); const mesh = new THREE.SkinnedMesh( geometry, material ); const skeleton = new THREE.Skeleton( initBones( mesh ) ); - mesh.bind( skeleton ); // console.log( mesh ); // for console debug + mesh.bind( skeleton ); + + // console.log( mesh ); // for console debug return mesh; } - } // TODO: Try to remove this function + } + // TODO: Try to remove this function function initBones( mesh ) { const geometry = mesh.geometry; const bones = []; - if ( geometry && geometry.bones !== undefined ) { // first, create array of 'Bone' objects from geometry data + for ( let i = 0, il = geometry.bones.length; i < il; i ++ ) { - const gbone = geometry.bones[ i ]; // create new 'Bone' object + const gbone = geometry.bones[ i ]; + + // create new 'Bone' object const bone = new THREE.Bone(); - bones.push( bone ); // apply values + bones.push( bone ); + + // apply values bone.name = gbone.name; bone.position.fromArray( gbone.pos ); bone.quaternion.fromArray( gbone.rotq ); if ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl ); - } // second, create bone hierarchy + } + // second, create bone hierarchy for ( let i = 0, il = geometry.bones.length; i < il; i ++ ) { const gbone = geometry.bones[ i ]; - if ( gbone.parent !== - 1 && gbone.parent !== null && bones[ gbone.parent ] !== undefined ) { // subsequent bones in the hierarchy + bones[ gbone.parent ].add( bones[ i ] ); } else { // topmost bone, immediate child of the skinned mesh + mesh.add( bones[ i ] ); } } - } // now the bones are part of the scene graph and children of the skinned mesh. - // let's update the corresponding matrices + } + // now the bones are part of the scene graph and children of the skinned mesh. + // let's update the corresponding matrices mesh.updateMatrixWorld( true ); return bones; - } // + } + // class GeometryBuilder { @@ -415,15 +412,17 @@ const iks = []; const grants = []; const rigidBodies = []; - const constraints = []; // for work + const constraints = []; + // for work let offset = 0; - const boneTypeTable = {}; // positions, normals, uvs, skinIndices, skinWeights + const boneTypeTable = {}; + + // positions, normals, uvs, skinIndices, skinWeights for ( let i = 0; i < data.metadata.vertexCount; i ++ ) { const v = data.vertices[ i ]; - for ( let j = 0, jl = v.position.length; j < jl; j ++ ) { positions.push( v.position[ j ] ); @@ -454,21 +453,22 @@ } - } // indices + } + // indices for ( let i = 0; i < data.metadata.faceCount; i ++ ) { const face = data.faces[ i ]; - for ( let j = 0, jl = face.indices.length; j < jl; j ++ ) { indices.push( face.indices[ j ] ); } - } // groups + } + // groups for ( let i = 0; i < data.metadata.materialCount; i ++ ) { @@ -479,14 +479,16 @@ } ); offset += material.faceCount; - } // bones + } + // bones for ( let i = 0; i < data.metadata.rigidBodyCount; i ++ ) { const body = data.rigidBodies[ i ]; - let value = boneTypeTable[ body.boneIndex ]; // keeps greater number if already value is set without any special reasons + let value = boneTypeTable[ body.boneIndex ]; + // keeps greater number if already value is set without any special reasons value = value === undefined ? body.type : Math.max( body.type, value ); boneTypeTable[ body.boneIndex ] = value; @@ -505,7 +507,6 @@ scl: [ 1, 1, 1 ], rigidBodyType: boneTypeTable[ i ] !== undefined ? boneTypeTable[ i ] : - 1 }; - if ( bone.parent !== - 1 ) { bone.pos[ 0 ] -= data.bones[ bone.parent ].position[ 0 ]; @@ -516,10 +517,11 @@ bones.push( bone ); - } // iks - // TODO: remove duplicated codes between PMD and PMX + } + // iks + // TODO: remove duplicated codes between PMD and PMX if ( data.metadata.format === 'pmd' ) { for ( let i = 0; i < data.metadata.ikCount; i ++ ) { @@ -532,13 +534,11 @@ maxAngle: ik.maxAngle * 4, links: [] }; - for ( let j = 0, jl = ik.links.length; j < jl; j ++ ) { const link = {}; link.index = ik.links[ j ].index; link.enabled = true; - if ( data.bones[ link.index ].name.indexOf( 'ひざ' ) >= 0 ) { link.limitation = new THREE.Vector3( 1.0, 0.0, 0.0 ); @@ -566,19 +566,20 @@ maxAngle: ik.maxAngle, links: [] }; - for ( let j = 0, jl = ik.links.length; j < jl; j ++ ) { const link = {}; link.index = ik.links[ j ].index; link.enabled = true; - if ( ik.links[ j ].angleLimitation === 1 ) { // Revert if rotationMin/Max doesn't work well // link.limitation = new THREE.Vector3( 1.0, 0.0, 0.0 ); + const rotationMin = ik.links[ j ].lowerLimitationAngle; - const rotationMax = ik.links[ j ].upperLimitationAngle; // Convert Left to Right coordinate by myself because + const rotationMax = ik.links[ j ].upperLimitationAngle; + + // Convert Left to Right coordinate by myself because // MMDParser doesn't convert. It's a MMDParser's bug const tmp1 = - rotationMax[ 0 ]; @@ -596,21 +597,22 @@ } - iks.push( param ); // Save the reference even from bone data for efficiently - // simulating PMX animation system + iks.push( param ); + // Save the reference even from bone data for efficiently + // simulating PMX animation system bones[ i ].ik = param; } - } // grants + } + // grants if ( data.metadata.format === 'pmx' ) { // bone index -> grant entry map const grantEntryMap = {}; - for ( let i = 0; i < data.metadata.boneCount; i ++ ) { const boneData = data.bones[ i ]; @@ -639,7 +641,9 @@ children: [], param: null, visited: false - }; // Build a tree representing grant hierarchy + }; + + // Build a tree representing grant hierarchy for ( const boneIndex in grantEntryMap ) { @@ -648,28 +652,30 @@ grantEntry.parent = parentGrantEntry; parentGrantEntry.children.push( grantEntry ); - } // Sort grant parameters from parents to children because + } + + // Sort grant parameters from parents to children because // grant uses parent's transform that parent's grant is already applied // so grant should be applied in order from parents to children - function traverse( entry ) { if ( entry.param ) { - grants.push( entry.param ); // Save the reference even from bone data for efficiently - // simulating PMX animation system + grants.push( entry.param ); + // Save the reference even from bone data for efficiently + // simulating PMX animation system bones[ entry.param.index ].grant = entry.param; } entry.visited = true; - for ( let i = 0, il = entry.children.length; i < il; i ++ ) { - const child = entry.children[ i ]; // Cut off a loop if exists. (Is a grant loop invalid?) + const child = entry.children[ i ]; + // Cut off a loop if exists. (Is a grant loop invalid?) if ( ! child.visited ) traverse( child ); } @@ -678,8 +684,9 @@ traverse( rootEntry ); - } // morph + } + // morph function updateAttributes( attribute, morph, ratio ) { @@ -687,7 +694,6 @@ const element = morph.elements[ i ]; let index; - if ( data.metadata.format === 'pmd' ) { index = data.morphs[ 0 ].elements[ element.index ].index; @@ -714,7 +720,6 @@ }; const attribute = new THREE.Float32BufferAttribute( data.metadata.vertexCount * 3, 3 ); attribute.name = morph.name; - for ( let j = 0; j < data.metadata.vertexCount * 3; j ++ ) { attribute.array[ j ] = positions[ j ]; @@ -734,16 +739,18 @@ if ( morph.type === 0 ) { // group + for ( let j = 0; j < morph.elementCount; j ++ ) { const morph2 = data.morphs[ morph.elements[ j ].index ]; const ratio = morph.elements[ j ].ratio; - if ( morph2.type === 1 ) { updateAttributes( attribute, morph2, ratio ); - } else { // TODO: implement + } else { + + // TODO: implement } } @@ -751,21 +758,29 @@ } else if ( morph.type === 1 ) { // vertex + updateAttributes( attribute, morph, 1.0 ); } else if ( morph.type === 2 ) { // bone + // TODO: implement } else if ( morph.type === 3 ) { // uv + // TODO: implement } else if ( morph.type === 4 ) { // additional uv1 + // TODO: implement } else if ( morph.type === 5 ) { // additional uv2 + // TODO: implement } else if ( morph.type === 6 ) { // additional uv3 + // TODO: implement } else if ( morph.type === 7 ) { // additional uv4 + // TODO: implement } else if ( morph.type === 8 ) { // material + // TODO: implement } @@ -774,26 +789,25 @@ morphTargets.push( params ); morphPositions.push( attribute ); - } // rigid bodies from rigidBodies field. + } + // rigid bodies from rigidBodies field. for ( let i = 0; i < data.metadata.rigidBodyCount; i ++ ) { const rigidBody = data.rigidBodies[ i ]; const params = {}; - for ( const key in rigidBody ) { params[ key ] = rigidBody[ key ]; } + /* * RigidBody position parameter in PMX seems global position * while the one in PMD seems offset from corresponding bone. * So unify being offset. */ - - if ( data.metadata.format === 'pmx' ) { if ( params.boneIndex !== - 1 ) { @@ -809,14 +823,14 @@ rigidBodies.push( params ); - } // constraints from constraints field. + } + // constraints from constraints field. for ( let i = 0; i < data.metadata.constraintCount; i ++ ) { const constraint = data.constraints[ i ]; const params = {}; - for ( const key in constraint ) { params[ key ] = constraint[ key ]; @@ -824,8 +838,9 @@ } const bodyA = rigidBodies[ params.rigidBodyIndex1 ]; - const bodyB = rigidBodies[ params.rigidBodyIndex2 ]; // Refer to http://www20.atpages.jp/katwat/wp/?p=4135 + const bodyB = rigidBodies[ params.rigidBodyIndex2 ]; + // Refer to http://www20.atpages.jp/katwat/wp/?p=4135 if ( bodyA.type !== 0 && bodyB.type === 2 ) { if ( bodyA.boneIndex !== - 1 && bodyB.boneIndex !== - 1 && data.bones[ bodyB.boneIndex ].parentIndex === bodyA.boneIndex ) { @@ -838,8 +853,9 @@ constraints.push( params ); - } // build THREE.BufferGeometry. + } + // build THREE.BufferGeometry. const geometry = new THREE.BufferGeometry(); geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); @@ -848,7 +864,6 @@ geometry.setAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( skinIndices, 4 ) ); geometry.setAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeights, 4 ) ); geometry.setIndex( indices ); - for ( let i = 0, il = groups.length; i < il; i ++ ) { geometry.addGroup( groups[ i ].offset, groups[ i ].count, i ); @@ -872,13 +887,13 @@ } - } // + } + + // /** * @param {THREE.LoadingManager} manager */ - - class MaterialBuilder { constructor( manager ) { @@ -891,30 +906,29 @@ this.resourcePath = undefined; } + /** * @param {string} crossOrigin * @return {MaterialBuilder} */ - - setCrossOrigin( crossOrigin ) { this.crossOrigin = crossOrigin; return this; } + /** * @param {string} resourcePath * @return {MaterialBuilder} */ - - setResourcePath( resourcePath ) { this.resourcePath = resourcePath; return this; } + /** * @param {Object} data - parsed PMD/PMX data * @param {BufferGeometry} geometry - some properties are dependend on geometry @@ -922,15 +936,13 @@ * @param {function} onError * @return {Array} */ - - - build( data, geometry - /*, onProgress, onError */ - ) { + build( data, geometry /*, onProgress, onError */ ) { const materials = []; const textures = {}; - this.textureLoader.setCrossOrigin( this.crossOrigin ); // materials + this.textureLoader.setCrossOrigin( this.crossOrigin ); + + // materials for ( let i = 0; i < data.metadata.materialCount; i ++ ) { @@ -941,6 +953,7 @@ } }; if ( material.name !== undefined ) params.name = material.name; + /* * THREE.Color * @@ -951,21 +964,26 @@ * MMDToonMaterial doesn't have ambient. Set it to emissive instead. * It'll be too bright if material has map texture so using coef 0.2. */ - params.diffuse = new THREE.Color().fromArray( material.diffuse ); params.opacity = material.diffuse[ 3 ]; params.specular = new THREE.Color().fromArray( material.specular ); params.shininess = material.shininess; params.emissive = new THREE.Color().fromArray( material.ambient ); - params.transparent = params.opacity !== 1.0; // + params.transparent = params.opacity !== 1.0; + + // + + params.fog = true; - params.fog = true; // blend + // blend params.blending = THREE.CustomBlending; params.blendSrc = THREE.SrcAlphaFactor; params.blendDst = THREE.OneMinusSrcAlphaFactor; params.blendSrcAlpha = THREE.SrcAlphaFactor; - params.blendDstAlpha = THREE.DstAlphaFactor; // side + params.blendDstAlpha = THREE.DstAlphaFactor; + + // side if ( data.metadata.format === 'pmx' && ( material.flag & 0x1 ) === 1 ) { @@ -980,14 +998,16 @@ if ( data.metadata.format === 'pmd' ) { // map, envMap + if ( material.fileName ) { const fileName = material.fileName; - const fileNames = fileName.split( '*' ); // fileNames[ 0 ]: mapFileName + const fileNames = fileName.split( '*' ); + + // fileNames[ 0 ]: mapFileName // fileNames[ 1 ]: envMapFileName( optional ) params.map = this._loadTexture( fileNames[ 0 ], textures ); - if ( fileNames.length > 1 ) { const extension = fileNames[ 1 ].slice( - 4 ).toLowerCase(); @@ -996,14 +1016,17 @@ } - } // gradientMap + } + // gradientMap const toonFileName = material.toonIndex === - 1 ? 'toon00.bmp' : data.toonTextures[ material.toonIndex ].fileName; params.gradientMap = this._loadTexture( toonFileName, textures, { isToonTexture: true, isDefaultToonTexture: this._isDefaultToonTexture( toonFileName ) - } ); // parameters for OutlineEffect + } ); + + // parameters for OutlineEffect params.userData.outlineParameters = { thickness: material.edgeFlag === 1 ? 0.003 : 0.0, @@ -1015,29 +1038,33 @@ } else { // map + if ( material.textureIndex !== - 1 ) { - params.map = this._loadTexture( data.textures[ material.textureIndex ], textures ); // Since PMX spec don't have standard to list map files except color map and env map, + params.map = this._loadTexture( data.textures[ material.textureIndex ], textures ); + + // Since PMX spec don't have standard to list map files except color map and env map, // we need to save file name for further mapping, like matching normal map file names after model loaded. // ref: https://gist.github.com/felixjones/f8a06bd48f9da9a4539f#texture - params.userData.MMD.mapFileName = data.textures[ material.textureIndex ]; - } // envMap TODO: support m.envFlag === 3 + } + // envMap TODO: support m.envFlag === 3 if ( material.envTextureIndex !== - 1 && ( material.envFlag === 1 || material.envFlag == 2 ) ) { - params.matcap = this._loadTexture( data.textures[ material.envTextureIndex ], textures ); // Same as color map above, keep file name in userData for further usage. + params.matcap = this._loadTexture( data.textures[ material.envTextureIndex ], textures ); + // Same as color map above, keep file name in userData for further usage. params.userData.MMD.matcapFileName = data.textures[ material.envTextureIndex ]; params.matcapCombine = material.envFlag === 1 ? THREE.MultiplyOperation : THREE.AddOperation; - } // gradientMap + } + // gradientMap let toonFileName, isDefaultToon; - if ( material.toonIndex === - 1 || material.toonFlag !== 0 ) { toonFileName = 'toon' + ( '0' + ( material.toonIndex + 1 ) ).slice( - 2 ) + '.bmp'; @@ -1053,8 +1080,9 @@ params.gradientMap = this._loadTexture( toonFileName, textures, { isToonTexture: true, isDefaultToonTexture: isDefaultToon - } ); // parameters for OutlineEffect + } ); + // parameters for OutlineEffect params.userData.outlineParameters = { thickness: material.edgeSize / 300, // TODO: better calculation? @@ -1084,6 +1112,7 @@ if ( data.metadata.format === 'pmx' ) { // set transparent true if alpha morph is defined. + function checkAlphaMorph( elements, materials ) { for ( let i = 0, il = elements.length; i < il; i ++ ) { @@ -1091,7 +1120,6 @@ const element = elements[ i ]; if ( element.index === - 1 ) continue; const material = materials[ element.index ]; - if ( material.opacity !== element.diffuse[ 3 ] ) { material.transparent = true; @@ -1106,7 +1134,6 @@ const morph = data.morphs[ i ]; const elements = morph.elements; - if ( morph.type === 0 ) { for ( let j = 0, jl = elements.length; j < jl; j ++ ) { @@ -1129,8 +1156,9 @@ return materials; - } // private methods + } + // private methods _getTGALoader() { @@ -1149,24 +1177,20 @@ return this.tgaLoader; } - _isDefaultToonTexture( name ) { if ( name.length !== 10 ) return false; return /toon(10|0[0-9])\.bmp/.test( name ); } - _loadTexture( filePath, textures, params, onProgress, onError ) { params = params || {}; const scope = this; let fullPath; - if ( params.isDefaultToonTexture === true ) { let index; - try { index = parseInt( filePath.match( /toon([0-9]{2})\.bmp$/ )[ 1 ] ); @@ -1188,7 +1212,6 @@ if ( textures[ fullPath ] !== undefined ) return textures[ fullPath ]; let loader = this.manager.getHandler( fullPath ); - if ( loader === null ) { loader = filePath.slice( - 4 ).toLowerCase() === '.tga' ? this._getTGALoader() : this.textureLoader; @@ -1211,7 +1234,6 @@ t.flipY = false; t.wrapS = THREE.RepeatWrapping; t.wrapT = THREE.RepeatWrapping; - for ( let i = 0; i < texture.readyCallbacks.length; i ++ ) { texture.readyCallbacks[ i ]( texture ); @@ -1226,7 +1248,6 @@ return texture; } - _getRotatedImage( image ) { const canvas = document.createElement( 'canvas' ); @@ -1238,14 +1259,13 @@ context.clearRect( 0, 0, width, height ); context.translate( width / 2.0, height / 2.0 ); context.rotate( 0.5 * Math.PI ); // 90.0 * Math.PI / 180.0 - context.translate( - width / 2.0, - height / 2.0 ); context.drawImage( image, 0, 0 ); return context.getImageData( 0, 0, width, height ); - } // Check if the partial image area used by the texture is transparent. - + } + // Check if the partial image area used by the texture is transparent. _checkImageTransparency( map, geometry, groupIndex ) { map.readyCallbacks.push( function ( texture ) { @@ -1269,14 +1289,12 @@ const data = image.data; const threshold = 253; if ( data.length / ( width * height ) !== 4 ) return false; - for ( let i = 0; i < indices.length; i += 3 ) { const centerUV = { x: 0.0, y: 0.0 }; - for ( let j = 0; j < 3; j ++ ) { const index = indices[ i * 3 + j ]; @@ -1299,6 +1317,7 @@ return false; } + /* * This method expects * texture.flipY = false @@ -1306,8 +1325,6 @@ * texture.wrapT = THREE.RepeatWrapping * TODO: more precise */ - - function getAlphaByUv( image, uv ) { const width = image.width; @@ -1340,7 +1357,6 @@ const imageData = texture.image.data !== undefined ? texture.image : createImageData( texture.image ); const group = geometry.groups[ groupIndex ]; - if ( detectImageTransparency( imageData, geometry.attributes.uv.array, geometry.index.array.slice( group.start, group.start + group.count ) ) ) { map.transparent = true; @@ -1351,8 +1367,9 @@ } - } // + } + // class AnimationBuilder { @@ -1364,9 +1381,9 @@ build( vmd, mesh ) { // combine skeletal and morph animations + const tracks = this.buildSkeletalAnimation( vmd, mesh ).tracks; const tracks2 = this.buildMorphAnimation( vmd, mesh ).tracks; - for ( let i = 0, il = tracks2.length; i < il; i ++ ) { tracks.push( tracks2[ i ] ); @@ -1376,23 +1393,19 @@ return new THREE.AnimationClip( '', - 1, tracks ); } + /** * @param {Object} vmd - parsed VMD data * @param {SkinnedMesh} mesh - tracks will be fitting to mesh * @return {AnimationClip} */ - - buildSkeletalAnimation( vmd, mesh ) { function pushInterpolation( array, interpolation, index ) { array.push( interpolation[ index + 0 ] / 127 ); // x1 - array.push( interpolation[ index + 8 ] / 127 ); // x2 - array.push( interpolation[ index + 4 ] / 127 ); // y1 - array.push( interpolation[ index + 12 ] / 127 ); // y2 } @@ -1401,7 +1414,6 @@ const motions = {}; const bones = mesh.skeleton.bones; const boneNameDictionary = {}; - for ( let i = 0, il = bones.length; i < il; i ++ ) { boneNameDictionary[ bones[ i ].name ] = true; @@ -1432,7 +1444,6 @@ const pInterpolations = []; const rInterpolations = []; const basePosition = mesh.skeleton.getBoneByName( key ).position.toArray(); - for ( let i = 0, il = array.length; i < il; i ++ ) { const time = array[ i ].frameNum / 30; @@ -1440,13 +1451,9 @@ const rotation = array[ i ].rotation; const interpolation = array[ i ].interpolation; times.push( time ); - for ( let j = 0; j < 3; j ++ ) positions.push( basePosition[ j ] + position[ j ] ); - for ( let j = 0; j < 4; j ++ ) rotations.push( rotation[ j ] ); - for ( let j = 0; j < 3; j ++ ) pushInterpolation( pInterpolations, interpolation, j ); - pushInterpolation( rInterpolations, interpolation, 3 ); } @@ -1460,19 +1467,17 @@ return new THREE.AnimationClip( '', - 1, tracks ); } + /** * @param {Object} vmd - parsed VMD data * @param {SkinnedMesh} mesh - tracks will be fitting to mesh * @return {AnimationClip} */ - - buildMorphAnimation( vmd, mesh ) { const tracks = []; const morphs = {}; const morphTargetDictionary = mesh.morphTargetDictionary; - for ( let i = 0; i < vmd.metadata.morphCount; i ++ ) { const morph = vmd.morphs[ i ]; @@ -1493,7 +1498,6 @@ } ); const times = []; const values = []; - for ( let i = 0, il = array.length; i < il; i ++ ) { times.push( array[ i ].frameNum / 30 ); @@ -1508,12 +1512,11 @@ return new THREE.AnimationClip( '', - 1, tracks ); } + /** * @param {Object} vmd - parsed VMD data * @return {AnimationClip} */ - - buildCameraAnimation( vmd ) { function pushVector3( array, vec ) { @@ -1536,11 +1539,8 @@ function pushInterpolation( array, interpolation, index ) { array.push( interpolation[ index * 4 + 0 ] / 127 ); // x1 - array.push( interpolation[ index * 4 + 1 ] / 127 ); // x2 - array.push( interpolation[ index * 4 + 2 ] / 127 ); // y1 - array.push( interpolation[ index * 4 + 3 ] / 127 ); // y2 } @@ -1564,7 +1564,6 @@ const euler = new THREE.Euler(); const position = new THREE.Vector3(); const center = new THREE.Vector3(); - for ( let i = 0, il = cameras.length; i < il; i ++ ) { const motion = cameras[ i ]; @@ -1585,15 +1584,15 @@ pushQuaternion( quaternions, quaternion ); pushVector3( positions, position ); fovs.push( fov ); - for ( let j = 0; j < 3; j ++ ) { pushInterpolation( cInterpolations, interpolation, j ); } - pushInterpolation( qInterpolations, interpolation, 3 ); // use the same parameter for x, y, z axis. + pushInterpolation( qInterpolations, interpolation, 3 ); + // use the same parameter for x, y, z axis. for ( let j = 0; j < 3; j ++ ) { pushInterpolation( pInterpolations, interpolation, 4 ); @@ -1604,16 +1603,18 @@ } - const tracks = []; // I expect an object whose name 'target' exists under THREE.Camera + const tracks = []; + // I expect an object whose name 'target' exists under THREE.Camera tracks.push( this._createTrack( 'target.position', THREE.VectorKeyframeTrack, times, centers, cInterpolations ) ); tracks.push( this._createTrack( '.quaternion', THREE.QuaternionKeyframeTrack, times, quaternions, qInterpolations ) ); tracks.push( this._createTrack( '.position', THREE.VectorKeyframeTrack, times, positions, pInterpolations ) ); tracks.push( this._createTrack( '.fov', THREE.NumberKeyframeTrack, times, fovs, fInterpolations ) ); return new THREE.AnimationClip( '', - 1, tracks ); - } // private method + } + // private method _createTrack( node, typedKeyframeTrack, times, values, interpolations ) { @@ -1630,7 +1631,6 @@ const stride = values.length / times.length; const interpolateStride = interpolations.length / times.length; let index = 1; - for ( let aheadIndex = 2, endIndex = times.length; aheadIndex < endIndex; aheadIndex ++ ) { for ( let i = 0; i < stride; i ++ ) { @@ -1647,7 +1647,6 @@ if ( aheadIndex > index ) { times[ index ] = times[ aheadIndex ]; - for ( let i = 0; i < stride; i ++ ) { values[ index * stride + i ] = values[ aheadIndex * stride + i ]; @@ -1671,7 +1670,6 @@ } const track = new typedKeyframeTrack( node, times, values ); - track.createInterpolant = function InterpolantFactoryMethodCubicBezier( result ) { return new CubicBezierInterpolation( this.times, this.values, this.getValueSize(), result, new Float32Array( interpolations ) ); @@ -1682,8 +1680,9 @@ } - } // interpolation + } + // interpolation class CubicBezierInterpolation extends THREE.Interpolant { @@ -1693,7 +1692,6 @@ this.interpolationParams = params; } - interpolate_( i1, t0, t, t1 ) { const result = this.resultBuffer; @@ -1701,36 +1699,34 @@ const stride = this.valueSize; const params = this.interpolationParams; const offset1 = i1 * stride; - const offset0 = offset1 - stride; // No interpolation if next key frame is in one frame in 30fps. + const offset0 = offset1 - stride; + + // No interpolation if next key frame is in one frame in 30fps. // This is from MMD animation spec. // '1.5' is for precision loss. times are Float32 in Three.js Animation system. - const weight1 = t1 - t0 < 1 / 30 * 1.5 ? 0.0 : ( t - t0 ) / ( t1 - t0 ); - if ( stride === 4 ) { // THREE.Quaternion + const x1 = params[ i1 * 4 + 0 ]; const x2 = params[ i1 * 4 + 1 ]; const y1 = params[ i1 * 4 + 2 ]; const y2 = params[ i1 * 4 + 3 ]; - const ratio = this._calculate( x1, x2, y1, y2, weight1 ); - THREE.Quaternion.slerpFlat( result, 0, values, offset0, values, offset1, ratio ); } else if ( stride === 3 ) { // THREE.Vector3 + for ( let i = 0; i !== stride; ++ i ) { const x1 = params[ i1 * 12 + i * 4 + 0 ]; const x2 = params[ i1 * 12 + i * 4 + 1 ]; const y1 = params[ i1 * 12 + i * 4 + 2 ]; const y2 = params[ i1 * 12 + i * 4 + 3 ]; - const ratio = this._calculate( x1, x2, y1, y2, weight1 ); - result[ i ] = values[ offset0 + i ] * ( 1 - ratio ) + values[ offset1 + i ] * ratio; } @@ -1738,13 +1734,12 @@ } else { // Number + const x1 = params[ i1 * 4 + 0 ]; const x2 = params[ i1 * 4 + 1 ]; const y1 = params[ i1 * 4 + 2 ]; const y2 = params[ i1 * 4 + 3 ]; - const ratio = this._calculate( x1, x2, y1, y2, weight1 ); - result[ 0 ] = values[ offset0 ] * ( 1 - ratio ) + values[ offset1 ] * ratio; } @@ -1752,7 +1747,6 @@ return result; } - _calculate( x1, x2, y1, y2, x ) { /* @@ -1791,6 +1785,7 @@ * (Another option: Newton's method * https://en.wikipedia.org/wiki/Newton%27s_method) */ + let c = 0.5; let t = c; let s = 1.0 - t; @@ -1798,7 +1793,6 @@ const eps = 1e-5; const math = Math; let sst3, stt3, ttt; - for ( let i = 0; i < loop; i ++ ) { sst3 = 3.0 * s * s * t; @@ -1817,7 +1811,6 @@ } } - class MMDToonMaterial extends THREE.ShaderMaterial { constructor( parameters ) { @@ -1844,14 +1837,12 @@ set: function ( value ) { this._matcapCombine = value; - switch ( value ) { case THREE.MultiplyOperation: this.defines.MATCAP_BLENDING_MULTIPLY = true; delete this.defines.MATCAP_BLENDING_ADD; break; - default: case THREE.AddOperation: this.defines.MATCAP_BLENDING_ADD = true; @@ -1862,10 +1853,10 @@ } } ); - this.uniforms = THREE.UniformsUtils.clone( THREE.MMDToonShader.uniforms ); // merged from MeshToon/Phong/MatcapMaterial + this.uniforms = THREE.UniformsUtils.clone( THREE.MMDToonShader.uniforms ); + // merged from MeshToon/Phong/MatcapMaterial const exposePropertyNames = [ 'specular', 'opacity', 'diffuse', 'map', 'matcap', 'gradientMap', 'lightMap', 'lightMapIntensity', 'aoMap', 'aoMapIntensity', 'emissive', 'emissiveMap', 'bumpMap', 'bumpScale', 'normalMap', 'normalScale', 'displacemantBias', 'displacemantMap', 'displacemantScale', 'specularMap', 'alphaMap', 'envMap', 'reflectivity', 'refractionRatio' ]; - for ( const propertyName of exposePropertyNames ) { Object.defineProperty( this, propertyName, { @@ -1881,9 +1872,9 @@ } } ); - } // Special path for shininess to handle zero shininess properly - + } + // Special path for shininess to handle zero shininess properly this._shininess = 30; Object.defineProperty( this, 'shininess', { get: function () { @@ -1898,11 +1889,11 @@ } } ); + Object.defineProperty( this, 'color', Object.getOwnPropertyDescriptor( this, 'diffuse' ) ); this.setValues( parameters ); } - copy( source ) { super.copy( source ); diff --git a/examples/js/loaders/MTLLoader.js b/examples/js/loaders/MTLLoader.js index 1519c670c5afd4..42aeba574660ca 100644 --- a/examples/js/loaders/MTLLoader.js +++ b/examples/js/loaders/MTLLoader.js @@ -11,6 +11,7 @@ super( manager ); } + /** * Loads and parses a MTL asset from a URL. * @@ -24,8 +25,6 @@ * @note In order for relative texture references to resolve correctly * you must call setResourcePath() explicitly prior to load. */ - - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -59,13 +58,13 @@ }, onProgress, onError ); } - setMaterialOptions( value ) { this.materialOptions = value; return this; } + /** * Parses a MTL file. * @@ -77,20 +76,16 @@ * @note In order for relative texture references to resolve correctly * you must call setResourcePath() explicitly prior to parse. */ - - parse( text, path ) { const lines = text.split( '\n' ); let info = {}; const delimiter_pattern = /\s+/; const materialsInfo = {}; - for ( let i = 0; i < lines.length; i ++ ) { let line = lines[ i ]; line = line.trim(); - if ( line.length === 0 || line.charAt( 0 ) === '#' ) { // Blank line or comment ignore @@ -103,10 +98,10 @@ key = key.toLowerCase(); let value = pos >= 0 ? line.substring( pos + 1 ) : ''; value = value.trim(); - if ( key === 'newmtl' ) { // New material + info = { name: value }; @@ -138,6 +133,7 @@ } } + /** * Create a new MTLLoader.MaterialCreator * @param baseUrl - Url relative to which textures are loaded @@ -153,7 +149,6 @@ * @constructor */ - class MaterialCreator { constructor( baseUrl = '', options = {} ) { @@ -169,20 +164,17 @@ this.wrap = this.options.wrap !== undefined ? this.options.wrap : THREE.RepeatWrapping; } - setCrossOrigin( value ) { this.crossOrigin = value; return this; } - setManager( value ) { this.manager = value; } - setMaterials( materialsInfo ) { this.materialsInfo = this.convert( materialsInfo ); @@ -191,31 +183,29 @@ this.nameLookup = {}; } - convert( materialsInfo ) { if ( ! this.options ) return materialsInfo; const converted = {}; - for ( const mn in materialsInfo ) { // Convert materials info into normalized form based on options + const mat = materialsInfo[ mn ]; const covmat = {}; converted[ mn ] = covmat; - for ( const prop in mat ) { let save = true; let value = mat[ prop ]; const lprop = prop.toLowerCase(); - switch ( lprop ) { case 'kd': case 'ka': case 'ks': // Diffuse color (color under white light) using RGB values + if ( this.options && this.options.normalizeRGB ) { value = [ value[ 0 ] / 255, value[ 1 ] / 255, value[ 2 ] / 255 ]; @@ -227,6 +217,7 @@ if ( value[ 0 ] === 0 && value[ 1 ] === 0 && value[ 2 ] === 0 ) { // ignore + save = false; } @@ -234,7 +225,6 @@ } break; - default: break; @@ -253,7 +243,6 @@ return converted; } - preload() { for ( const mn in this.materialsInfo ) { @@ -263,17 +252,14 @@ } } - getIndex( materialName ) { return this.nameLookup[ materialName ]; } - getAsArray() { let index = 0; - for ( const mn in this.materialsInfo ) { this.materialsArray[ index ] = this.create( mn ); @@ -285,7 +271,6 @@ return this.materialsArray; } - create( materialName ) { if ( this.materials[ materialName ] === undefined ) { @@ -297,21 +282,21 @@ return this.materials[ materialName ]; } - createMaterial_( materialName ) { // Create material + const scope = this; const mat = this.materialsInfo[ materialName ]; const params = { name: materialName, side: this.side }; - function resolveURL( baseUrl, url ) { - if ( typeof url !== 'string' || url === '' ) return ''; // Absolute URL + if ( typeof url !== 'string' || url === '' ) return ''; + // Absolute URL if ( /^https?:\/\//i.test( url ) ) return url; return baseUrl + url; @@ -327,7 +312,6 @@ map.offset.copy( texParams.offset ); map.wrapS = scope.wrap; map.wrapT = scope.wrap; - if ( mapType === 'map' || mapType === 'emissiveMap' ) { map.encoding = THREE.sRGBEncoding; @@ -343,65 +327,61 @@ const value = mat[ prop ]; let n; if ( value === '' ) continue; - switch ( prop.toLowerCase() ) { // Ns is material specular exponent + case 'kd': // Diffuse color (color under white light) using RGB values + params.color = new THREE.Color().fromArray( value ).convertSRGBToLinear(); break; - case 'ks': // Specular color (color when light is reflected from shiny surface) using RGB values params.specular = new THREE.Color().fromArray( value ).convertSRGBToLinear(); break; - case 'ke': // Emissive using RGB values params.emissive = new THREE.Color().fromArray( value ).convertSRGBToLinear(); break; - case 'map_kd': // Diffuse texture map + setMapForType( 'map', value ); break; - case 'map_ks': // Specular map + setMapForType( 'specularMap', value ); break; - case 'map_ke': // Emissive map + setMapForType( 'emissiveMap', value ); break; - case 'norm': setMapForType( 'normalMap', value ); break; - case 'map_bump': case 'bump': // Bump texture map + setMapForType( 'bumpMap', value ); break; - case 'map_d': // Alpha map + setMapForType( 'alphaMap', value ); params.transparent = true; break; - case 'ns': // The specular exponent (defines the focus of the specular highlight) // A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000. + params.shininess = parseFloat( value ); break; - case 'd': n = parseFloat( value ); - if ( n < 1 ) { params.opacity = n; @@ -410,11 +390,9 @@ } break; - case 'tr': n = parseFloat( value ); if ( this.options && this.options.invertTrProperty ) n = 1 - n; - if ( n > 0 ) { params.opacity = 1 - n; @@ -423,7 +401,6 @@ } break; - default: break; @@ -435,7 +412,6 @@ return this.materials[ materialName ]; } - getTextureParams( value, matParams ) { const texParams = { @@ -445,7 +421,6 @@ const items = value.split( /\s+/ ); let pos; pos = items.indexOf( '-bm' ); - if ( pos >= 0 ) { matParams.bumpScale = parseFloat( items[ pos + 1 ] ); @@ -454,7 +429,6 @@ } pos = items.indexOf( '-s' ); - if ( pos >= 0 ) { texParams.scale.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) ); @@ -463,7 +437,6 @@ } pos = items.indexOf( '-o' ); - if ( pos >= 0 ) { texParams.offset.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) ); @@ -475,12 +448,10 @@ return texParams; } - loadTexture( url, mapping, onLoad, onProgress, onError ) { const manager = this.manager !== undefined ? this.manager : THREE.DefaultLoadingManager; let loader = manager.getHandler( url ); - if ( loader === null ) { loader = new THREE.TextureLoader( manager ); diff --git a/examples/js/loaders/NRRDLoader.js b/examples/js/loaders/NRRDLoader.js index 067b29bffa925a..f2b123c1756929 100644 --- a/examples/js/loaders/NRRDLoader.js +++ b/examples/js/loaders/NRRDLoader.js @@ -7,7 +7,6 @@ super( manager ); } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -41,18 +40,15 @@ }, onProgress, onError ); } - parse( data ) { // this parser is largely inspired from the XTK NRRD parser : https://github.com/xtk/X + let _data = data; let _dataPointer = 0; - const _nativeLittleEndian = new Int8Array( new Int16Array( [ 1 ] ).buffer )[ 0 ] > 0; - const _littleEndian = true; const headerObject = {}; - function scan( type, chunks ) { if ( chunks === undefined || chunks === null ) { @@ -63,60 +59,51 @@ let _chunkSize = 1; let _array_type = Uint8Array; - switch ( type ) { // 1 byte data types case 'uchar': break; - case 'schar': _array_type = Int8Array; break; // 2 byte data types - case 'ushort': _array_type = Uint16Array; _chunkSize = 2; break; - case 'sshort': _array_type = Int16Array; _chunkSize = 2; break; // 4 byte data types - case 'uint': _array_type = Uint32Array; _chunkSize = 4; break; - case 'sint': _array_type = Int32Array; _chunkSize = 4; break; - case 'float': _array_type = Float32Array; _chunkSize = 4; break; - case 'complex': _array_type = Float64Array; _chunkSize = 8; break; - case 'double': _array_type = Float64Array; _chunkSize = 8; break; - } // increase the data pointer in-place - - - let _bytes = new _array_type( _data.slice( _dataPointer, _dataPointer += chunks * _chunkSize ) ); // if required, flip the endianness of the bytes + } + // increase the data pointer in-place + let _bytes = new _array_type( _data.slice( _dataPointer, _dataPointer += chunks * _chunkSize ) ); + // if required, flip the endianness of the bytes if ( _nativeLittleEndian != _littleEndian ) { // we need to flip here since the format doesn't match the native endianness @@ -129,18 +116,18 @@ // if only one chunk was requested, just return one value return _bytes[ 0 ]; - } // return the byte array - + } + // return the byte array return _bytes; - } //Flips typed array endianness in-place. Based on https://github.com/kig/DataStream.js/blob/master/DataStream.js. + } + //Flips typed array endianness in-place. Based on https://github.com/kig/DataStream.js/blob/master/DataStream.js. function flipEndianness( array, chunkSize ) { const u8 = new Uint8Array( array.buffer, array.byteOffset, array.byteLength ); - for ( let i = 0; i < array.byteLength; i += chunkSize ) { for ( let j = i + chunkSize - 1, k = i; j > k; j --, k ++ ) { @@ -155,19 +142,16 @@ return array; - } //parse the header - + } + //parse the header function parseHeader( header ) { let data, field, fn, i, l, m, _i, _len; - const lines = header.split( /\r?\n/ ); - for ( _i = 0, _len = lines.length; _i < _len; _i ++ ) { l = lines[ _i ]; - if ( l.match( /NRRD\d+/ ) ) { headerObject.isNrrd = true; @@ -177,7 +161,6 @@ field = m[ 1 ].trim(); data = m[ 2 ].trim(); fn = _fieldFunctions[ field ]; - if ( fn ) { fn.call( headerObject, data ); @@ -210,8 +193,9 @@ headerObject.vectors = []; headerObject.vectors.push( [ 1, 0, 0 ] ); headerObject.vectors.push( [ 0, 1, 0 ] ); - headerObject.vectors.push( [ 0, 0, 1 ] ); //apply spacing if defined + headerObject.vectors.push( [ 0, 0, 1 ] ); + //apply spacing if defined if ( headerObject.spacings ) { for ( i = 0; i <= 2; i ++ ) { @@ -232,23 +216,22 @@ } - } //parse the data when registred as one of this type : 'text', 'ascii', 'txt' - + } + //parse the data when registred as one of this type : 'text', 'ascii', 'txt' function parseDataAsText( data, start, end ) { let number = ''; start = start || 0; end = end || data.length; - let value; //length of the result is the product of the sizes - + let value; + //length of the result is the product of the sizes const lengthOfTheResult = headerObject.sizes.reduce( function ( previous, current ) { return previous * current; }, 1 ); let base = 10; - if ( headerObject.encoding === 'hex' ) { base = 16; @@ -258,7 +241,6 @@ const result = new headerObject.__array( lengthOfTheResult ); let resultIndex = 0; let parsingFunction = parseInt; - if ( headerObject.__array === Float32Array || headerObject.__array === Float64Array ) { parsingFunction = parseFloat; @@ -267,8 +249,8 @@ for ( let i = start; i < end; i ++ ) { - value = data[ i ]; //if value is not a space - + value = data[ i ]; + //if value is not a space if ( ( value < 9 || value > 13 ) && value !== 32 ) { number += String.fromCharCode( value ); @@ -300,31 +282,28 @@ } const _bytes = scan( 'uchar', data.byteLength ); - const _length = _bytes.length; let _header = null; let _data_start = 0; let i; - for ( i = 1; i < _length; i ++ ) { if ( _bytes[ i - 1 ] == 10 && _bytes[ i ] == 10 ) { // we found two line breaks in a row // now we know what the header is - _header = this.parseChars( _bytes, 0, i - 2 ); // this is were the data starts - + _header = this.parseChars( _bytes, 0, i - 2 ); + // this is were the data starts _data_start = i + 1; break; } - } // parse the header - + } + // parse the header parseHeader( _header ); _data = _bytes.subarray( _data_start ); // the data without header - if ( headerObject.encoding.substring( 0, 2 ) === 'gz' ) { // we need to decompress the datastream @@ -339,7 +318,6 @@ //we need to copy the array to create a new array buffer, else we retrieve the original arraybuffer with the header const _copy = new Uint8Array( _data.length ); - for ( let i = 0; i < _data.length; i ++ ) { _copy[ i ] = _data[ i ]; @@ -348,29 +326,31 @@ _data = _copy; - } // .. let's use the underlying array buffer - + } + // .. let's use the underlying array buffer _data = _data.buffer; const volume = new THREE.Volume(); - volume.header = headerObject; // + volume.header = headerObject; + // // parse the (unzipped) data to a datastream of the correct type // - - volume.data = new headerObject.__array( _data ); // get the min and max intensities - + volume.data = new headerObject.__array( _data ); + // get the min and max intensities const min_max = volume.computeMinMax(); const min = min_max[ 0 ]; - const max = min_max[ 1 ]; // attach the scalar range to the volume - + const max = min_max[ 1 ]; + // attach the scalar range to the volume volume.windowLow = min; - volume.windowHigh = max; // get the image dimensions + volume.windowHigh = max; + // get the image dimensions volume.dimensions = [ headerObject.sizes[ 0 ], headerObject.sizes[ 1 ], headerObject.sizes[ 2 ] ]; volume.xLength = volume.dimensions[ 0 ]; volume.yLength = volume.dimensions[ 1 ]; - volume.zLength = volume.dimensions[ 2 ]; // Identify axis order in the space-directions matrix from the header if possible. + volume.zLength = volume.dimensions[ 2 ]; + // Identify axis order in the space-directions matrix from the header if possible. if ( headerObject.vectors ) { const xIndex = headerObject.vectors.findIndex( vector => vector[ 0 ] !== 0 ); @@ -386,17 +366,17 @@ volume.axisOrder = [ 'x', 'y', 'z' ]; - } // spacing - + } + // spacing const spacingX = new THREE.Vector3().fromArray( headerObject.vectors[ 0 ] ).length(); const spacingY = new THREE.Vector3().fromArray( headerObject.vectors[ 1 ] ).length(); const spacingZ = new THREE.Vector3().fromArray( headerObject.vectors[ 2 ] ).length(); - volume.spacing = [ spacingX, spacingY, spacingZ ]; // Create IJKtoRAS matrix + volume.spacing = [ spacingX, spacingY, spacingZ ]; + // Create IJKtoRAS matrix volume.matrix = new THREE.Matrix4(); const transitionMatrix = new THREE.Matrix4(); - if ( headerObject.space === 'left-posterior-superior' ) { transitionMatrix.set( - 1, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ); @@ -422,9 +402,10 @@ volume.inverseMatrix = new THREE.Matrix4(); volume.inverseMatrix.copy( volume.matrix ).invert(); - volume.RASDimensions = new THREE.Vector3( volume.xLength, volume.yLength, volume.zLength ).applyMatrix4( volume.matrix ).round().toArray().map( Math.abs ); // .. and set the default threshold - // only if the threshold was not already set + volume.RASDimensions = new THREE.Vector3( volume.xLength, volume.yLength, volume.zLength ).applyMatrix4( volume.matrix ).round().toArray().map( Math.abs ); + // .. and set the default threshold + // only if the threshold was not already set if ( volume.lowerThreshold === - Infinity ) { volume.lowerThreshold = min; @@ -440,7 +421,6 @@ return volume; } - parseChars( array, start, end ) { // without borders, use the whole array @@ -456,10 +436,9 @@ } - let output = ''; // create and append the chars - + let output = ''; + // create and append the chars let i = 0; - for ( i = start; i < end; ++ i ) { output += String.fromCharCode( array[ i ] ); @@ -471,7 +450,6 @@ } } - const _fieldFunctions = { type: function ( data ) { @@ -483,13 +461,11 @@ case 'uint8_t': this.__array = Uint8Array; break; - case 'signed char': case 'int8': case 'int8_t': this.__array = Int8Array; break; - case 'short': case 'short int': case 'signed short': @@ -498,7 +474,6 @@ case 'int16_t': this.__array = Int16Array; break; - case 'ushort': case 'unsigned short': case 'unsigned short int': @@ -506,29 +481,24 @@ case 'uint16_t': this.__array = Uint16Array; break; - case 'int': case 'signed int': case 'int32': case 'int32_t': this.__array = Int32Array; break; - case 'uint': case 'unsigned int': case 'uint32': case 'uint32_t': this.__array = Uint32Array; break; - case 'float': this.__array = Float32Array; break; - case 'double': this.__array = Float64Array; break; - default: throw new Error( 'Unsupported NRRD data type: ' + data ); @@ -558,13 +528,10 @@ return this.sizes = function () { const _ref = data.split( /\s+/ ); - const _results = []; - for ( let _i = 0, _len = _ref.length; _i < _len; _i ++ ) { i = _ref[ _i ]; - _results.push( parseInt( i, 10 ) ); } @@ -591,21 +558,16 @@ return this.vectors = function () { const _results = []; - for ( let _i = 0, _len = parts.length; _i < _len; _i ++ ) { v = parts[ _i ]; - _results.push( function () { const _ref = v.slice( 1, - 1 ).split( /,/ ); - const _results2 = []; - for ( let _j = 0, _len2 = _ref.length; _j < _len2; _j ++ ) { f = _ref[ _j ]; - _results2.push( parseFloat( f ) ); } @@ -628,11 +590,9 @@ return this.spacings = function () { const _results = []; - for ( let _i = 0, _len = parts.length; _i < _len; _i ++ ) { f = parts[ _i ]; - _results.push( parseFloat( f ) ); } diff --git a/examples/js/loaders/OBJLoader.js b/examples/js/loaders/OBJLoader.js index a8b5c724469ee4..aede40e63b3b65 100644 --- a/examples/js/loaders/OBJLoader.js +++ b/examples/js/loaders/OBJLoader.js @@ -1,26 +1,20 @@ ( function () { - const _object_pattern = /^[og]\s*(.+)?/; // mtllib file_reference - - const _material_library_pattern = /^mtllib /; // usemtl material_name - - const _material_use_pattern = /^usemtl /; // usemap map_name - + // o object_name | g group_name + const _object_pattern = /^[og]\s*(.+)?/; + // mtllib file_reference + const _material_library_pattern = /^mtllib /; + // usemtl material_name + const _material_use_pattern = /^usemtl /; + // usemap map_name const _map_use_pattern = /^usemap /; const _face_vertex_data_separator_pattern = /\s+/; - const _vA = new THREE.Vector3(); - const _vB = new THREE.Vector3(); - const _vC = new THREE.Vector3(); - const _ab = new THREE.Vector3(); - const _cb = new THREE.Vector3(); - const _color = new THREE.Color(); - function ParserState() { const state = { @@ -45,7 +39,6 @@ } const previousMaterial = this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined; - if ( this.object && typeof this.object._finalize === 'function' ) { this.object._finalize( true ); @@ -66,10 +59,10 @@ smooth: true, startMaterial: function ( name, libraries ) { - const previous = this._finalize( false ); // New usemtl declaration overwrites an inherited material, except if faces were declared - // after the material, then it must be preserved for proper MultiMaterial continuation. - + const previous = this._finalize( false ); + // New usemtl declaration overwrites an inherited material, except if faces were declared + // after the material, then it must be preserved for proper MultiMaterial continuation. if ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) { this.materials.splice( previous.index, 1 ); @@ -120,16 +113,15 @@ _finalize: function ( end ) { const lastMultiMaterial = this.currentMaterial(); - if ( lastMultiMaterial && lastMultiMaterial.groupEnd === - 1 ) { lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3; lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart; lastMultiMaterial.inherited = false; - } // Ignore objects tail materials if no face declarations followed them before a new o/g started. - + } + // Ignore objects tail materials if no face declarations followed them before a new o/g started. if ( end && this.materials.length > 1 ) { for ( let mi = this.materials.length - 1; mi >= 0; mi -- ) { @@ -142,9 +134,9 @@ } - } // Guarantee at least one empty material, this makes the creation later more straight forward. - + } + // Guarantee at least one empty material, this makes the creation later more straight forward. if ( end && this.materials.length === 0 ) { this.materials.push( { @@ -157,7 +149,9 @@ return lastMultiMaterial; } - }; // Inherit previous objects material. + }; + + // Inherit previous objects material. // Spec tells us that a declared material must be set to all objects until a new material is declared. // If a usemtl declaration is encountered while this new object is being parsed, it will // overwrite the inherited material. Exception being that there was already face declarations @@ -237,21 +231,13 @@ const src = this.vertices; const dst = this.object.geometry.normals; - _vA.fromArray( src, a ); - _vB.fromArray( src, b ); - _vC.fromArray( src, c ); - _cb.subVectors( _vC, _vB ); - _ab.subVectors( _vA, _vB ); - _cb.cross( _ab ); - _cb.normalize(); - dst.push( _cb.x, _cb.y, _cb.z ); dst.push( _cb.x, _cb.y, _cb.z ); dst.push( _cb.x, _cb.y, _cb.z ); @@ -297,7 +283,9 @@ let ib = this.parseVertexIndex( b, vLen ); let ic = this.parseVertexIndex( c, vLen ); this.addVertex( ia, ib, ic ); - this.addColor( ia, ib, ic ); // normals + this.addColor( ia, ib, ic ); + + // normals if ( na !== undefined && na !== '' ) { @@ -311,8 +299,9 @@ this.addFaceNormal( ia, ib, ic ); - } // uvs + } + // uvs if ( ua !== undefined && ua !== '' ) { @@ -326,6 +315,7 @@ } else { // add placeholder values (for inconsistent face definitions) + this.addDefaultUV(); } @@ -335,7 +325,6 @@ this.object.geometry.type = 'Points'; const vLen = this.vertices.length; - for ( let vi = 0, l = vertices.length; vi < l; vi ++ ) { const index = this.parseVertexIndex( vertices[ vi ], vLen ); @@ -350,7 +339,6 @@ this.object.geometry.type = 'Line'; const vLen = this.vertices.length; const uvLen = this.uvs.length; - for ( let vi = 0, l = vertices.length; vi < l; vi ++ ) { this.addVertexLine( this.parseVertexIndex( vertices[ vi ], vLen ) ); @@ -368,8 +356,9 @@ state.startObject( '', false ); return state; - } // + } + // class OBJLoader extends THREE.Loader { @@ -379,7 +368,6 @@ this.materials = null; } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -412,18 +400,15 @@ }, onProgress, onError ); } - setMaterials( materials ) { this.materials = materials; return this; } - parse( text ) { const state = new ParserState(); - if ( text.indexOf( '\r\n' ) !== - 1 ) { // This is faster than String.split with regex that splits on both @@ -440,43 +425,38 @@ const lines = text.split( '\n' ); let result = []; - for ( let i = 0, l = lines.length; i < l; i ++ ) { const line = lines[ i ].trimStart(); if ( line.length === 0 ) continue; - const lineFirstChar = line.charAt( 0 ); // @todo invoke passed in handler if any + const lineFirstChar = line.charAt( 0 ); + // @todo invoke passed in handler if any if ( lineFirstChar === '#' ) continue; - if ( lineFirstChar === 'v' ) { const data = line.split( _face_vertex_data_separator_pattern ); - switch ( data[ 0 ] ) { case 'v': state.vertices.push( parseFloat( data[ 1 ] ), parseFloat( data[ 2 ] ), parseFloat( data[ 3 ] ) ); - if ( data.length >= 7 ) { _color.setRGB( parseFloat( data[ 4 ] ), parseFloat( data[ 5 ] ), parseFloat( data[ 6 ] ) ).convertSRGBToLinear(); - state.colors.push( _color.r, _color.g, _color.b ); } else { // if no colors are defined, add placeholders so color and vertex indices match + state.colors.push( undefined, undefined, undefined ); } break; - case 'vn': state.normals.push( parseFloat( data[ 1 ] ), parseFloat( data[ 2 ] ), parseFloat( data[ 3 ] ) ); break; - case 'vt': state.uvs.push( parseFloat( data[ 1 ] ), parseFloat( data[ 2 ] ) ); break; @@ -487,12 +467,13 @@ const lineData = line.slice( 1 ).trim(); const vertexData = lineData.split( _face_vertex_data_separator_pattern ); - const faceVertices = []; // Parse the face vertex data into an easy to work with format + const faceVertices = []; + + // Parse the face vertex data into an easy to work with format for ( let j = 0, jl = vertexData.length; j < jl; j ++ ) { const vertex = vertexData[ j ]; - if ( vertex.length > 0 ) { const vertexParts = vertex.split( '/' ); @@ -500,11 +481,11 @@ } - } // Draw an edge between the first vertex and all subsequent vertices to form an n-gon + } + // Draw an edge between the first vertex and all subsequent vertices to form an n-gon const v1 = faceVertices[ 0 ]; - for ( let j = 1, jl = faceVertices.length - 1; j < jl; j ++ ) { const v2 = faceVertices[ j ]; @@ -518,7 +499,6 @@ const lineParts = line.substring( 1 ).trim().split( ' ' ); let lineVertices = []; const lineUVs = []; - if ( line.indexOf( '/' ) === - 1 ) { lineVertices = lineParts; @@ -548,6 +528,7 @@ // o object_name // or // g group_name + // WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869 // let name = result[ 0 ].slice( 1 ).trim(); const name = ( ' ' + result[ 0 ].slice( 1 ).trim() ).slice( 1 ); @@ -556,22 +537,28 @@ } else if ( _material_use_pattern.test( line ) ) { // material + state.object.startMaterial( line.substring( 7 ).trim(), state.materialLibraries ); } else if ( _material_library_pattern.test( line ) ) { // mtl file + state.materialLibraries.push( line.substring( 7 ).trim() ); } else if ( _map_use_pattern.test( line ) ) { // the line is parsed but ignored since the loader assumes textures are defined MTL files // (according to https://www.okino.com/conv/imp_wave.htm, 'usemap' is the old-style Wavefront texture reference method) + console.warn( 'THREE.OBJLoader: Rendering identifier "usemap" not supported. Textures must be defined in MTL files.' ); } else if ( lineFirstChar === 's' ) { - result = line.split( ' ' ); // smooth shading + result = line.split( ' ' ); + + // smooth shading + // @todo Handle files that have varying smooth values for a set of faces inside one geometry, // but does not define a usemtl for each face set. // This should be detected and a dummy material created (later MultiMaterial and geometry groups). @@ -588,7 +575,6 @@ * surfaces, smoothing groups are either turned on or off; there is no difference between values greater * than 0." */ - if ( result.length > 1 ) { const value = result[ 1 ].trim().toLowerCase(); @@ -618,7 +604,6 @@ const container = new THREE.Group(); container.materialLibraries = [].concat( state.materialLibraries ); const hasPrimitives = ! ( state.objects.length === 1 && state.objects[ 0 ].geometry.vertices.length === 0 ); - if ( hasPrimitives === true ) { for ( let i = 0, l = state.objects.length; i < l; i ++ ) { @@ -628,12 +613,12 @@ const materials = object.materials; const isLine = geometry.type === 'Line'; const isPoints = geometry.type === 'Points'; - let hasVertexColors = false; // Skip o/g line declarations that did not follow with any faces + let hasVertexColors = false; + // Skip o/g line declarations that did not follow with any faces if ( geometry.vertices.length === 0 ) continue; const buffergeometry = new THREE.BufferGeometry(); buffergeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( geometry.vertices, 3 ) ); - if ( geometry.normals.length > 0 ) { buffergeometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( geometry.normals, 3 ) ); @@ -651,21 +636,21 @@ buffergeometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( geometry.uvs, 2 ) ); - } // Create materials + } + // Create materials const createdMaterials = []; - for ( let mi = 0, miLen = materials.length; mi < miLen; mi ++ ) { const sourceMaterial = materials[ mi ]; const materialHash = sourceMaterial.name + '_' + sourceMaterial.smooth + '_' + hasVertexColors; let material = state.materials[ materialHash ]; - if ( this.materials !== null ) { - material = this.materials.create( sourceMaterial.name ); // mtl etc. loaders probably can't create line materials correctly, copy properties to a line material. + material = this.materials.create( sourceMaterial.name ); + // mtl etc. loaders probably can't create line materials correctly, copy properties to a line material. if ( isLine && material && ! ( material instanceof THREE.LineBasicMaterial ) ) { const materialLine = new THREE.LineBasicMaterial(); @@ -716,11 +701,11 @@ createdMaterials.push( material ); - } // Create mesh + } + // Create mesh let mesh; - if ( createdMaterials.length > 1 ) { for ( let mi = 0, miLen = materials.length; mi < miLen; mi ++ ) { @@ -770,6 +755,7 @@ } else { // if there is only the default parser state object with no geometry data, interpret data as point cloud + if ( state.vertices.length > 0 ) { const material = new THREE.PointsMaterial( { @@ -778,7 +764,6 @@ } ); const buffergeometry = new THREE.BufferGeometry(); buffergeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( state.vertices, 3 ) ); - if ( state.colors.length > 0 && state.colors[ 0 ] !== undefined ) { buffergeometry.setAttribute( 'color', new THREE.Float32BufferAttribute( state.colors, 3 ) ); diff --git a/examples/js/loaders/PCDLoader.js b/examples/js/loaders/PCDLoader.js index dfbf429b22bceb..16f260e0e4d1c5 100644 --- a/examples/js/loaders/PCDLoader.js +++ b/examples/js/loaders/PCDLoader.js @@ -8,7 +8,6 @@ this.littleEndian = true; } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -42,10 +41,10 @@ }, onProgress, onError ); } - parse( data ) { // from https://gitlab.com/taketwo/three-pcd-loader/blob/master/decompress-lzf.js + function decompressLZF( inData, outLength ) { const inLength = inData.length; @@ -55,17 +54,14 @@ let ctrl; let len; let ref; - do { ctrl = inData[ inPtr ++ ]; - if ( ctrl < 1 << 5 ) { ctrl ++; if ( outPtr + ctrl > outLength ) throw new Error( 'Output buffer is not large enough' ); if ( inPtr + ctrl > inLength ) throw new Error( 'Invalid compressed data' ); - do { outData[ outPtr ++ ] = inData[ inPtr ++ ]; @@ -77,7 +73,6 @@ len = ctrl >> 5; ref = outPtr - ( ( ctrl & 0x1f ) << 8 ) - 1; if ( inPtr >= inLength ) throw new Error( 'Invalid compressed data' ); - if ( len === 7 ) { len += inData[ inPtr ++ ]; @@ -89,7 +84,6 @@ if ( outPtr + len + 2 > outLength ) throw new Error( 'Output buffer is not large enough' ); if ( ref < 0 ) throw new Error( 'Invalid compressed data' ); if ( ref >= outPtr ) throw new Error( 'Invalid compressed data' ); - do { outData[ outPtr ++ ] = outData[ ref ++ ]; @@ -111,9 +105,13 @@ const result2 = /[\r\n]DATA\s(\S*)\s/i.exec( data.slice( result1 - 1 ) ); PCDheader.data = result2[ 1 ]; PCDheader.headerLen = result2[ 0 ].length + result1; - PCDheader.str = data.slice( 0, PCDheader.headerLen ); // remove comments + PCDheader.str = data.slice( 0, PCDheader.headerLen ); - PCDheader.str = PCDheader.str.replace( /\#.*/gi, '' ); // parse + // remove comments + + PCDheader.str = PCDheader.str.replace( /#.*/gi, '' ); + + // parse PCDheader.version = /VERSION (.*)/i.exec( PCDheader.str ); PCDheader.fields = /FIELDS (.*)/i.exec( PCDheader.str ); @@ -123,7 +121,9 @@ PCDheader.width = /WIDTH (.*)/i.exec( PCDheader.str ); PCDheader.height = /HEIGHT (.*)/i.exec( PCDheader.str ); PCDheader.viewpoint = /VIEWPOINT (.*)/i.exec( PCDheader.str ); - PCDheader.points = /POINTS (.*)/i.exec( PCDheader.str ); // evaluate + PCDheader.points = /POINTS (.*)/i.exec( PCDheader.str ); + + // evaluate if ( PCDheader.version !== null ) PCDheader.version = parseFloat( PCDheader.version[ 1 ] ); PCDheader.fields = PCDheader.fields !== null ? PCDheader.fields[ 1 ].split( ' ' ) : []; @@ -133,7 +133,6 @@ if ( PCDheader.viewpoint !== null ) PCDheader.viewpoint = PCDheader.viewpoint[ 1 ]; if ( PCDheader.points !== null ) PCDheader.points = parseInt( PCDheader.points[ 1 ], 10 ); if ( PCDheader.points === null ) PCDheader.points = PCDheader.width * PCDheader.height; - if ( PCDheader.size !== null ) { PCDheader.size = PCDheader.size[ 1 ].split( ' ' ).map( function ( x ) { @@ -155,7 +154,6 @@ } else { PCDheader.count = []; - for ( let i = 0, l = PCDheader.fields.length; i < l; i ++ ) { PCDheader.count.push( 1 ); @@ -166,7 +164,6 @@ PCDheader.offset = {}; let sizeSum = 0; - for ( let i = 0, l = PCDheader.fields.length; i < l; i ++ ) { if ( PCDheader.data === 'ascii' ) { @@ -180,33 +177,40 @@ } - } // for binary only + } + // for binary only PCDheader.rowSize = sizeSum; return PCDheader; } - const textData = THREE.LoaderUtils.decodeText( new Uint8Array( data ) ); // parse header (always ascii format) + const textData = THREE.LoaderUtils.decodeText( new Uint8Array( data ) ); - const PCDheader = parseHeader( textData ); // parse data + // parse header (always ascii format) + + const PCDheader = parseHeader( textData ); + + // parse data const position = []; const normal = []; - const color = []; // ascii + const color = []; + const intensity = []; + const label = []; + + // ascii if ( PCDheader.data === 'ascii' ) { const offset = PCDheader.offset; const pcdData = textData.slice( PCDheader.headerLen ); const lines = pcdData.split( '\n' ); - for ( let i = 0, l = lines.length; i < l; i ++ ) { if ( lines[ i ] === '' ) continue; const line = lines[ i ].split( ' ' ); - if ( offset.x !== undefined ) { position.push( parseFloat( line[ offset.x ] ) ); @@ -221,7 +225,6 @@ const rgb_type = PCDheader.type[ rgb_field_index ]; const float = parseFloat( line[ offset.rgb ] ); let rgb = float; - if ( rgb_type === 'F' ) { // treat float values as int @@ -247,14 +250,28 @@ } + if ( offset.intensity !== undefined ) { + + intensity.push( parseFloat( line[ offset.intensity ] ) ); + + } + + if ( offset.label !== undefined ) { + + label.push( parseInt( line[ offset.label ] ) ); + + } + } - } // binary-compressed + } + + // binary-compressed + // normally data in PCD files are organized as array of structures: XYZRGBXYZRGB // binary compressed PCD files organize their data as structure of arrays: XXYYZZRGBRGB // that requires a totally different parsing approach compared to non-compressed data - if ( PCDheader.data === 'binary_compressed' ) { const sizes = new Uint32Array( data.slice( PCDheader.headerLen, PCDheader.headerLen + 8 ) ); @@ -263,7 +280,6 @@ const decompressed = decompressLZF( new Uint8Array( data, PCDheader.headerLen + 8, compressedSize ), decompressedSize ); const dataview = new DataView( decompressed.buffer ); const offset = PCDheader.offset; - for ( let i = 0; i < PCDheader.points; i ++ ) { if ( offset.x !== undefined ) { @@ -297,16 +313,30 @@ } + if ( offset.intensity !== undefined ) { + + const intensityIndex = PCDheader.fields.indexOf( 'intensity' ); + intensity.push( dataview.getFloat32( PCDheader.points * offset.intensity + PCDheader.size[ intensityIndex ] * i, this.littleEndian ) ); + + } + + if ( offset.label !== undefined ) { + + const labelIndex = PCDheader.fields.indexOf( 'label' ); + label.push( dataview.getInt32( PCDheader.points * offset.label + PCDheader.size[ labelIndex ] * i, this.littleEndian ) ); + + } + } - } // binary + } + // binary if ( PCDheader.data === 'binary' ) { const dataview = new DataView( data, PCDheader.headerLen ); const offset = PCDheader.offset; - for ( let i = 0, row = 0; i < PCDheader.points; i ++, row += PCDheader.rowSize ) { if ( offset.x !== undefined ) { @@ -333,31 +363,44 @@ } + if ( offset.intensity !== undefined ) { + + intensity.push( dataview.getFloat32( row + offset.intensity, this.littleEndian ) ); + + } + + if ( offset.label !== undefined ) { + + label.push( dataview.getInt32( row + offset.label, this.littleEndian ) ); + + } + } - } // build geometry + } + // build geometry const geometry = new THREE.BufferGeometry(); if ( position.length > 0 ) geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) ); if ( normal.length > 0 ) geometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( normal, 3 ) ); if ( color.length > 0 ) geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( color, 3 ) ); - geometry.computeBoundingSphere(); // build material + if ( intensity.length > 0 ) geometry.setAttribute( 'intensity', new THREE.Float32BufferAttribute( intensity, 1 ) ); + if ( label.length > 0 ) geometry.setAttribute( 'label', new THREE.Int32BufferAttribute( label, 1 ) ); + geometry.computeBoundingSphere(); + + // build material const material = new THREE.PointsMaterial( { size: 0.005 } ); - if ( color.length > 0 ) { material.vertexColors = true; - } else { - - material.color.setHex( Math.random() * 0xffffff ); - - } // build point cloud + } + // build point cloud return new THREE.Points( geometry, material ); diff --git a/examples/js/loaders/PDBLoader.js b/examples/js/loaders/PDBLoader.js index 0cf4aea2ac6e92..3e3bab6c816b83 100644 --- a/examples/js/loaders/PDBLoader.js +++ b/examples/js/loaders/PDBLoader.js @@ -7,7 +7,6 @@ super( manager ); } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -39,8 +38,9 @@ }, onProgress, onError ); - } // Based on CanvasMol PDB parser + } + // Based on CanvasMol PDB parser parse( text ) { @@ -65,18 +65,17 @@ function parseBond( start, length, satom, i ) { const eatom = parseInt( lines[ i ].slice( start, start + length ) ); - if ( eatom ) { const h = hash( satom, eatom ); - if ( _bhash[ h ] === undefined ) { _bonds.push( [ satom - 1, eatom - 1, 1 ] ); - _bhash[ h ] = _bonds.length - 1; - } else { // doesn't really work as almost all PDBs + } else { + + // doesn't really work as almost all PDBs // have just normal bonds appearing multiple // times instead of being double/triple bonds // bonds[bhash[h]][2] += 1; @@ -99,7 +98,9 @@ const geometryBonds = build.geometryBonds; const verticesAtoms = []; const colorsAtoms = []; - const verticesBonds = []; // atoms + const verticesBonds = []; + + // atoms for ( let i = 0, l = atoms.length; i < l; i ++ ) { @@ -113,8 +114,9 @@ const b = atom[ 3 ][ 2 ] / 255; colorsAtoms.push( r, g, b ); - } // bonds + } + // bonds for ( let i = 0, l = _bonds.length; i < l; i ++ ) { @@ -132,8 +134,9 @@ z = endAtom[ 2 ]; verticesBonds.push( x, y, z ); - } // build geometry + } + // build geometry geometryAtoms.setAttribute( 'position', new THREE.Float32BufferAttribute( verticesAtoms, 3 ) ); geometryAtoms.setAttribute( 'color', new THREE.Float32BufferAttribute( colorsAtoms, 3 ) ); @@ -265,10 +268,11 @@ const atoms = []; const _bonds = []; const _bhash = {}; - const _atomMap = {}; // parse + const _atomMap = {}; - const lines = text.split( '\n' ); + // parse + const lines = text.split( '\n' ); for ( let i = 0, l = lines.length; i < l; i ++ ) { if ( lines[ i ].slice( 0, 4 ) === 'ATOM' || lines[ i ].slice( 0, 6 ) === 'HETATM' ) { @@ -278,7 +282,6 @@ const z = parseFloat( lines[ i ].slice( 46, 53 ) ); const index = parseInt( lines[ i ].slice( 6, 11 ) ) - 1; let e = trim( lines[ i ].slice( 76, 78 ) ).toLowerCase(); - if ( e === '' ) { e = trim( lines[ i ].slice( 12, 14 ) ).toLowerCase(); @@ -299,8 +302,9 @@ } - } // build and return geometry + } + // build and return geometry return buildGeometry(); diff --git a/examples/js/loaders/PLYLoader.js b/examples/js/loaders/PLYLoader.js index 0bc8895dc33477..4a63c8bd11cb02 100644 --- a/examples/js/loaders/PLYLoader.js +++ b/examples/js/loaders/PLYLoader.js @@ -24,19 +24,28 @@ * diffuse_blue: 'blue' * } ); * + * Custom properties outside of the defaults for position, uv, normal + * and color attributes can be added using the setCustomPropertyMapping method. + * For example, the following maps the element properties “custom_property_a” + * and “custom_property_b” to an attribute “customAttribute” with an item size of 2. + * Attribute item sizes are set from the number of element properties in the property array. + * + * loader.setCustomPropertyMapping( { + * customAttribute: ['custom_property_a', 'custom_property_b'], + * } ); + * */ const _color = new THREE.Color(); - class PLYLoader extends THREE.Loader { constructor( manager ) { super( manager ); this.propertyNameMapping = {}; + this.customPropertyMapping = {}; } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -70,13 +79,16 @@ }, onProgress, onError ); } - setPropertyNameMapping( mapping ) { this.propertyNameMapping = mapping; } + setCustomPropertyNameMapping( mapping ) { + + this.customPropertyMapping = mapping; + } parse( data ) { function parseHeader( data ) { @@ -85,7 +97,6 @@ let headerText = ''; let headerLength = 0; const result = patternHeader.exec( data ); - if ( result !== null ) { headerText = result[ 1 ]; @@ -101,13 +112,11 @@ }; const lines = headerText.split( /\r\n|\r|\n/ ); let currentElement; - function make_ply_element_property( propertValues, propertyNameMapping ) { const property = { type: propertValues[ 0 ] }; - if ( property.type === 'list' ) { property.name = propertValues[ 3 ]; @@ -138,18 +147,15 @@ const lineValues = line.split( /\s+/ ); const lineType = lineValues.shift(); line = lineValues.join( ' ' ); - switch ( lineType ) { case 'format': header.format = lineValues[ 0 ]; header.version = lineValues[ 1 ]; break; - case 'comment': header.comments.push( line ); break; - case 'element': if ( currentElement !== undefined ) { @@ -162,15 +168,12 @@ currentElement.count = parseInt( lineValues[ 1 ] ); currentElement.properties = []; break; - case 'property': currentElement.properties.push( make_ply_element_property( lineValues, scope.propertyNameMapping ) ); break; - case 'obj_info': header.objInfo = line; break; - default: console.log( 'unhandled', lineType, lineValues ); @@ -205,7 +208,6 @@ case 'int32': case 'uint32': return parseInt( n ); - case 'float': case 'double': case 'float32': @@ -220,14 +222,12 @@ const values = line.split( /\s+/ ); const element = {}; - for ( let i = 0; i < properties.length; i ++ ) { if ( properties[ i ].type === 'list' ) { const list = []; const n = parseASCIINumber( values.shift(), properties[ i ].countType ); - for ( let j = 0; j < n; j ++ ) { list.push( parseASCIINumber( values.shift(), properties[ i ].itemType ) ); @@ -248,9 +248,8 @@ } - function parseASCII( data, header ) { + function createBuffer() { - // PLY ascii format specification, as per http://en.wikipedia.org/wiki/PLY_(file_format) const buffer = { indices: [], vertices: [], @@ -259,10 +258,24 @@ faceVertexUvs: [], colors: [] }; + for ( const customProperty of Object.keys( scope.customPropertyMapping ) ) { + + buffer[ customProperty ] = []; + + } + + return buffer; + + } + + function parseASCII( data, header ) { + + // PLY ascii format specification, as per http://en.wikipedia.org/wiki/PLY_(file_format) + + const buffer = createBuffer(); let result; const patternBody = /end_header\s([\s\S]*)$/; let body = ''; - if ( ( result = patternBody.exec( data ) ) !== null ) { body = result[ 1 ]; @@ -272,12 +285,10 @@ const lines = body.split( /\r\n|\r|\n/ ); let currentElement = 0; let currentElementCount = 0; - for ( let i = 0; i < lines.length; i ++ ) { let line = lines[ i ]; line = line.trim(); - if ( line === '' ) { continue; @@ -303,7 +314,9 @@ function postProcess( buffer ) { - let geometry = new THREE.BufferGeometry(); // mandatory buffer data + let geometry = new THREE.BufferGeometry(); + + // mandatory buffer data if ( buffer.indices.length > 0 ) { @@ -311,7 +324,9 @@ } - geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( buffer.vertices, 3 ) ); // optional buffer data + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( buffer.vertices, 3 ) ); + + // optional buffer data if ( buffer.normals.length > 0 ) { @@ -338,6 +353,18 @@ } + // custom buffer data + + for ( const customProperty of Object.keys( scope.customPropertyMapping ) ) { + + if ( buffer[ customProperty ].length > 0 ) { + + geometry.setAttribute( customProperty, new THREE.Float32BufferAttribute( buffer[ customProperty ], scope.customPropertyMapping[ customProperty ].length ) ); + + } + + } + geometry.computeBoundingSphere(); return geometry; @@ -369,11 +396,9 @@ const attrR = findAttrName( [ 'red', 'diffuse_red', 'r', 'diffuse_r' ] ); const attrG = findAttrName( [ 'green', 'diffuse_green', 'g', 'diffuse_g' ] ); const attrB = findAttrName( [ 'blue', 'diffuse_blue', 'b', 'diffuse_b' ] ); - if ( elementName === 'vertex' ) { buffer.vertices.push( element[ attrX ], element[ attrY ], element[ attrZ ] ); - if ( attrNX !== null && attrNY !== null && attrNZ !== null ) { buffer.normals.push( element[ attrNX ], element[ attrNY ], element[ attrNZ ] ); @@ -389,21 +414,27 @@ if ( attrR !== null && attrG !== null && attrB !== null ) { _color.setRGB( element[ attrR ] / 255.0, element[ attrG ] / 255.0, element[ attrB ] / 255.0 ).convertSRGBToLinear(); - buffer.colors.push( _color.r, _color.g, _color.b ); } + for ( const customProperty of Object.keys( scope.customPropertyMapping ) ) { + + for ( const elementProperty of scope.customPropertyMapping[ customProperty ] ) { + + buffer[ customProperty ].push( element[ elementProperty ] ); + + } + + } + } else if ( elementName === 'face' ) { const vertex_indices = element.vertex_indices || element.vertex_index; // issue #9338 - const texcoord = element.texcoord; - if ( vertex_indices.length === 3 ) { buffer.indices.push( vertex_indices[ 0 ], vertex_indices[ 1 ], vertex_indices[ 2 ] ); - if ( texcoord && texcoord.length === 6 ) { buffer.faceVertexUvs.push( texcoord[ 0 ], texcoord[ 1 ] ); @@ -431,31 +462,24 @@ case 'int8': case 'char': return [ dataview.getInt8( at ), 1 ]; - case 'uint8': case 'uchar': return [ dataview.getUint8( at ), 1 ]; - case 'int16': case 'short': return [ dataview.getInt16( at, little_endian ), 2 ]; - case 'uint16': case 'ushort': return [ dataview.getUint16( at, little_endian ), 2 ]; - case 'int32': case 'int': return [ dataview.getInt32( at, little_endian ), 4 ]; - case 'uint32': case 'uint': return [ dataview.getUint32( at, little_endian ), 4 ]; - case 'float32': case 'float': return [ dataview.getFloat32( at, little_endian ), 4 ]; - case 'float64': case 'double': return [ dataview.getFloat64( at, little_endian ), 8 ]; @@ -469,7 +493,6 @@ const element = {}; let result, read = 0; - for ( let i = 0; i < properties.length; i ++ ) { if ( properties[ i ].type === 'list' ) { @@ -478,7 +501,6 @@ result = binaryRead( dataview, at + read, properties[ i ].countType, little_endian ); const n = result[ 0 ]; read += result[ 1 ]; - for ( let j = 0; j < n; j ++ ) { result = binaryRead( dataview, at + read, properties[ i ].itemType, little_endian ); @@ -505,19 +527,11 @@ function parseBinary( data, header ) { - const buffer = { - indices: [], - vertices: [], - normals: [], - uvs: [], - faceVertexUvs: [], - colors: [] - }; + const buffer = createBuffer(); const little_endian = header.format === 'binary_little_endian'; const body = new DataView( data, header.headerLength ); let result, loc = 0; - for ( let currentElement = 0; currentElement < header.elements.length; currentElement ++ ) { for ( let currentElementCount = 0; currentElementCount < header.elements[ currentElement ].count; currentElementCount ++ ) { @@ -533,12 +547,12 @@ return postProcess( buffer ); - } // + } + // let geometry; const scope = this; - if ( data instanceof ArrayBuffer ) { const text = THREE.LoaderUtils.decodeText( new Uint8Array( data ) ); diff --git a/examples/js/loaders/PRWMLoader.js b/examples/js/loaders/PRWMLoader.js index e2e31965c0aca3..33f0bbcc258280 100644 --- a/examples/js/loaders/PRWMLoader.js +++ b/examples/js/loaders/PRWMLoader.js @@ -5,11 +5,11 @@ */ let bigEndianPlatform = null; + /** * Check if the endianness of the platform is big-endian (most significant bit first) * @returns {boolean} True if big-endian, false if little-endian */ - function isBigEndianPlatform() { if ( bigEndianPlatform === null ) { @@ -18,20 +18,19 @@ uint8Array = new Uint8Array( buffer ), uint16Array = new Uint16Array( buffer ); uint8Array[ 0 ] = 0xAA; // set first byte - uint8Array[ 1 ] = 0xBB; // set second byte - bigEndianPlatform = uint16Array[ 0 ] === 0xAABB; } return bigEndianPlatform; - } // match the values defined in the spec to the TypedArray types - + } - const InvertedEncodingTypes = [ null, Float32Array, null, Int8Array, Int16Array, null, Int32Array, Uint8Array, Uint16Array, null, Uint32Array ]; // define the method to use on a DataView, corresponding the TypedArray type + // match the values defined in the spec to the TypedArray types + const InvertedEncodingTypes = [ null, Float32Array, null, Int8Array, Int16Array, null, Int32Array, Uint8Array, Uint16Array, null, Uint32Array ]; + // define the method to use on a DataView, corresponding the TypedArray type const getMethods = { Uint16Array: 'getUint16', Uint32Array: 'getUint32', @@ -40,12 +39,10 @@ Float32Array: 'getFloat32', Float64Array: 'getFloat64' }; - function copyFromBuffer( sourceArrayBuffer, viewType, position, length, fromBigEndian ) { const bytesPerElement = viewType.BYTES_PER_ELEMENT; let result; - if ( fromBigEndian === isBigEndianPlatform() || bytesPerElement === 1 ) { result = new viewType( sourceArrayBuffer, position, length ); @@ -56,7 +53,6 @@ getMethod = getMethods[ viewType.name ], littleEndian = ! fromBigEndian; result = new viewType( length ); - for ( let i = 0; i < length; i ++ ) { result[ i ] = readView[ getMethod ]( i * bytesPerElement, littleEndian ); @@ -80,7 +76,6 @@ attributesNumber = flags & 0x1F; let valuesNumber = 0, indicesNumber = 0; - if ( bigEndian ) { valuesNumber = ( array[ 2 ] << 16 ) + ( array[ 3 ] << 8 ) + array[ 4 ]; @@ -92,8 +87,8 @@ indicesNumber = array[ 5 ] + ( array[ 6 ] << 8 ) + ( array[ 7 ] << 16 ); } - /** PRELIMINARY CHECKS **/ + /** PRELIMINARY CHECKS **/ if ( version === 0 ) { @@ -118,21 +113,18 @@ } } - /** PARSING **/ + /** PARSING **/ let pos = 8; const attributes = {}; - for ( let i = 0; i < attributesNumber; i ++ ) { let attributeName = ''; - while ( pos < array.length ) { const char = array[ pos ]; pos ++; - if ( char === 0 ) { break; @@ -150,8 +142,9 @@ const cardinality = ( flags >> 4 & 0x03 ) + 1; const encodingType = flags & 0x0F; const arrayType = InvertedEncodingTypes[ encodingType ]; - pos ++; // padding to next multiple of 4 + pos ++; + // padding to next multiple of 4 pos = Math.ceil( pos / 4 ) * 4; const values = copyFromBuffer( buffer, arrayType, pos, cardinality * valuesNumber, bigEndian ); pos += arrayType.BYTES_PER_ELEMENT * cardinality * valuesNumber; @@ -165,7 +158,6 @@ pos = Math.ceil( pos / 4 ) * 4; let indices = null; - if ( indexedGeometry ) { indices = copyFromBuffer( buffer, indicesType === 1 ? Uint32Array : Uint16Array, pos, indicesNumber, bigEndian ); @@ -178,8 +170,9 @@ indices: indices }; - } // Define the public interface + } + // Define the public interface class PRWMLoader extends THREE.Loader { @@ -188,7 +181,6 @@ super( manager ); } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -223,13 +215,11 @@ }, onProgress, onError ); } - parse( arrayBuffer ) { const data = decodePrwm( arrayBuffer ), attributesKey = Object.keys( data.attributes ), bufferGeometry = new THREE.BufferGeometry(); - for ( let i = 0; i < attributesKey.length; i ++ ) { const attribute = data.attributes[ attributesKey[ i ] ]; @@ -246,7 +236,6 @@ return bufferGeometry; } - static isBigEndianPlatform() { return isBigEndianPlatform(); diff --git a/examples/js/loaders/PVRLoader.js b/examples/js/loaders/PVRLoader.js index 17b8274e919c6f..0ec033dc93c19c 100644 --- a/examples/js/loaders/PVRLoader.js +++ b/examples/js/loaders/PVRLoader.js @@ -13,7 +13,6 @@ super( manager ); } - parse( buffer, loadMipmaps ) { const headerLengthInt = 13; @@ -23,15 +22,16 @@ header: header, loadMipmaps: loadMipmaps }; - if ( header[ 0 ] === 0x03525650 ) { // PVR v3 + return _parseV3( pvrDatas ); } else if ( header[ 11 ] === 0x21525650 ) { // PVR v2 + return _parseV2( pvrDatas ); } else { @@ -43,7 +43,6 @@ } } - function _parseV3( pvrDatas ) { const header = pvrDatas.header; @@ -55,7 +54,6 @@ // numSurfs = header[ 9 ], numFaces = header[ 10 ], numMipmaps = header[ 11 ]; - switch ( pixelFormat ) { case 0: @@ -63,25 +61,21 @@ bpp = 2; format = THREE.RGB_PVRTC_2BPPV1_Format; break; - case 1: // PVRTC 2bpp RGBA bpp = 2; format = THREE.RGBA_PVRTC_2BPPV1_Format; break; - case 2: // PVRTC 4bpp RGB bpp = 4; format = THREE.RGB_PVRTC_4BPPV1_Format; break; - case 3: // PVRTC 4bpp RGBA bpp = 4; format = THREE.RGBA_PVRTC_4BPPV1_Format; break; - default: console.error( 'THREE.PVRLoader: Unsupported PVR format:', pixelFormat ); @@ -120,9 +114,7 @@ PVRTC_4 = 25; const formatFlags = flags & TYPE_MASK; let bpp, format; - const _hasAlpha = bitmaskAlpha > 0; - if ( formatFlags === PVRTC_4 ) { format = _hasAlpha ? THREE.RGBA_PVRTC_4BPPV1_Format : THREE.RGB_PVRTC_4BPPV1_Format; @@ -145,9 +137,10 @@ pvrDatas.width = width; pvrDatas.height = height; pvrDatas.numSurfaces = numSurfs; - pvrDatas.numMipmaps = numMipmaps + 1; // guess cubemap type seems tricky in v2 - // it juste a pvr containing 6 surface (no explicit cubemap type) + pvrDatas.numMipmaps = numMipmaps + 1; + // guess cubemap type seems tricky in v2 + // it juste a pvr containing 6 surface (no explicit cubemap type) pvrDatas.isCubemap = numSurfs === 6; return _extract( pvrDatas ); @@ -173,7 +166,6 @@ heightBlocks = 0; const bpp = pvrDatas.bpp, numSurfs = pvrDatas.numSurfaces; - if ( bpp === 2 ) { blockWidth = 8; @@ -189,18 +181,17 @@ blockSize = blockWidth * blockHeight * bpp / 8; pvr.mipmaps.length = pvrDatas.numMipmaps * numSurfs; let mipLevel = 0; - while ( mipLevel < pvrDatas.numMipmaps ) { const sWidth = pvrDatas.width >> mipLevel, sHeight = pvrDatas.height >> mipLevel; widthBlocks = sWidth / blockWidth; - heightBlocks = sHeight / blockHeight; // Clamp to minimum number of blocks + heightBlocks = sHeight / blockHeight; + // Clamp to minimum number of blocks if ( widthBlocks < 2 ) widthBlocks = 2; if ( heightBlocks < 2 ) heightBlocks = 2; dataSize = widthBlocks * heightBlocks * blockSize; - for ( let surfIndex = 0; surfIndex < numSurfs; surfIndex ++ ) { const byteArray = new Uint8Array( buffer, dataOffset, dataSize ); diff --git a/examples/js/loaders/RGBELoader.js b/examples/js/loaders/RGBELoader.js index 1a4cae487a5a03..ab3e8910d0d2fe 100644 --- a/examples/js/loaders/RGBELoader.js +++ b/examples/js/loaders/RGBELoader.js @@ -1,5 +1,6 @@ ( function () { + // https://github.com/mrdoob/three.js/issues/5552 // http://en.wikipedia.org/wiki/RGBE_image_format class RGBELoader extends THREE.DataTextureLoader { @@ -9,16 +10,15 @@ super( manager ); this.type = THREE.HalfFloatType; - } // adapted from http://www.graphics.cornell.edu/~bjw/rgbe.html + } + // adapted from http://www.graphics.cornell.edu/~bjw/rgbe.html parse( buffer ) { - const - /* return codes for rgbe routines */ + const /* return codes for rgbe routines */ //RGBE_RETURN_SUCCESS = 0, RGBE_RETURN_FAILURE = - 1, - /* default error routine. change this to change error handling */ rgbe_read_error = 1, rgbe_write_error = 2, @@ -31,15 +31,12 @@ case rgbe_read_error: console.error( 'THREE.RGBELoader Read Error: ' + ( msg || '' ) ); break; - case rgbe_write_error: console.error( 'THREE.RGBELoader Write Error: ' + ( msg || '' ) ); break; - case rgbe_format_error: console.error( 'THREE.RGBELoader Bad File Format: ' + ( msg || '' ) ); break; - default: case rgbe_memory_error: console.error( 'THREE.RGBELoader: Error: ' + ( msg || '' ) ); @@ -49,7 +46,6 @@ return RGBE_RETURN_FAILURE; }, - /* offsets to red, green, and blue components in a data (float) pixel */ //RGBE_DATA_RED = 0, //RGBE_DATA_GREEN = 1, @@ -72,7 +68,6 @@ len = 0, s = '', chunk = String.fromCharCode.apply( null, new Uint16Array( buffer.subarray( p, p + chunkSize ) ) ); - while ( 0 > ( i = chunk.indexOf( NEWLINE ) ) && len < lineLimit && p < buffer.byteLength ) { s += chunk; @@ -85,11 +80,11 @@ if ( - 1 < i ) { /*for (i=l-1; i>=0; i--) { - byteCode = m.charCodeAt(i); - if (byteCode > 0x7f && byteCode <= 0x7ff) byteLen++; - else if (byteCode > 0x7ff && byteCode <= 0xffff) byteLen += 2; - if (byteCode >= 0xDC00 && byteCode <= 0xDFFF) i--; //trail surrogate - }*/ + byteCode = m.charCodeAt(i); + if (byteCode > 0x7f && byteCode <= 0x7ff) byteLen++; + else if (byteCode > 0x7ff && byteCode <= 0xffff) byteLen += 2; + if (byteCode >= 0xDC00 && byteCode <= 0xDFFF) i--; //trail surrogate + }*/ if ( false !== consume ) buffer.pos += len + i + 1; return s + chunk.slice( 0, i ); @@ -98,7 +93,6 @@ return false; }, - /* minimal header reading. modify if you want to parse more information */ RGBE_ReadHeader = function ( buffer ) { @@ -111,41 +105,38 @@ // RGBE format header struct header = { valid: 0, - /* indicate which fields are valid */ - string: '', + string: '', /* the actual header string */ - comments: '', + comments: '', /* comments found in header */ - programtype: 'RGBE', + programtype: 'RGBE', /* listed at beginning of file to identify it after "#?". defaults to "RGBE" */ - format: '', + format: '', /* RGBE format, default 32-bit_rle_rgbe */ - gamma: 1.0, + gamma: 1.0, /* image has already been gamma corrected with given gamma. defaults to 1.0 (no correction) */ - exposure: 1.0, + exposure: 1.0, /* a value of 1.0 in an image corresponds to watts/steradian/m^2. defaults to 1.0 */ - width: 0, - height: 0 - /* image dimensions, width/height */ + width: 0, + height: 0 /* image dimensions, width/height */ }; - let line, match; + let line, match; if ( buffer.pos >= buffer.byteLength || ! ( line = fgets( buffer ) ) ) { return rgbe_error( rgbe_read_error, 'no header found' ); } - /* if you want to require the magic token then uncomment the next line */ - + /* if you want to require the magic token then uncomment the next line */ if ( ! ( match = line.match( magic_token_re ) ) ) { return rgbe_error( rgbe_format_error, 'bad initial token' ); @@ -155,13 +146,11 @@ header.valid |= RGBE_VALID_PROGRAMTYPE; header.programtype = match[ 1 ]; header.string += line + '\n'; - while ( true ) { line = fgets( buffer ); if ( false === line ) break; header.string += line + '\n'; - if ( '#' === line.charAt( 0 ) ) { header.comments += line + '\n'; @@ -218,10 +207,11 @@ RGBE_ReadPixels_RLE = function ( buffer, w, h ) { const scanline_width = w; - - if ( // run length encoding is not allowed so read flat - scanline_width < 8 || scanline_width > 0x7fff || // this file is not run length encoded - 2 !== buffer[ 0 ] || 2 !== buffer[ 1 ] || buffer[ 2 ] & 0x80 ) { + if ( + // run length encoding is not allowed so read flat + scanline_width < 8 || scanline_width > 0x7fff || + // this file is not run length encoded + 2 !== buffer[ 0 ] || 2 !== buffer[ 1 ] || buffer[ 2 ] & 0x80 ) { // return the flat buffer return new Uint8Array( buffer ); @@ -235,7 +225,6 @@ } const data_rgba = new Uint8Array( 4 * w * h ); - if ( ! data_rgba.length ) { return rgbe_error( rgbe_memory_error, 'unable to allocate buffer space' ); @@ -247,8 +236,9 @@ const ptr_end = 4 * scanline_width; const rgbeStart = new Uint8Array( 4 ); const scanline_buffer = new Uint8Array( ptr_end ); - let num_scanlines = h; // read in each successive scanline + let num_scanlines = h; + // read in each successive scanline while ( num_scanlines > 0 && pos < buffer.byteLength ) { if ( pos + 4 > buffer.byteLength ) { @@ -261,24 +251,21 @@ rgbeStart[ 1 ] = buffer[ pos ++ ]; rgbeStart[ 2 ] = buffer[ pos ++ ]; rgbeStart[ 3 ] = buffer[ pos ++ ]; - if ( 2 != rgbeStart[ 0 ] || 2 != rgbeStart[ 1 ] || ( rgbeStart[ 2 ] << 8 | rgbeStart[ 3 ] ) != scanline_width ) { return rgbe_error( rgbe_format_error, 'bad rgbe scanline format' ); - } // read each of the four channels for the scanline into the buffer - // first red, then green, then blue, then exponent - + } + // read each of the four channels for the scanline into the buffer + // first red, then green, then blue, then exponent let ptr = 0, count; - while ( ptr < ptr_end && pos < buffer.byteLength ) { count = buffer[ pos ++ ]; const isEncodedRun = count > 128; if ( isEncodedRun ) count -= 128; - if ( 0 === count || ptr + count > ptr_end ) { return rgbe_error( rgbe_format_error, 'bad scanline data' ); @@ -289,12 +276,12 @@ // a (encoded) run of the same value const byteValue = buffer[ pos ++ ]; - for ( let i = 0; i < count; i ++ ) { scanline_buffer[ ptr ++ ] = byteValue; - } //ptr += count; + } + //ptr += count; } else { @@ -305,24 +292,20 @@ } - } // now convert data from buffer into rgba - // first red, then green, then blue, then exponent (alpha) - + } + // now convert data from buffer into rgba + // first red, then green, then blue, then exponent (alpha) const l = scanline_width; //scanline_buffer.byteLength; - for ( let i = 0; i < l; i ++ ) { let off = 0; data_rgba[ offset ] = scanline_buffer[ i + off ]; off += scanline_width; //1; - data_rgba[ offset + 1 ] = scanline_buffer[ i + off ]; off += scanline_width; //1; - data_rgba[ offset + 2 ] = scanline_buffer[ i + off ]; off += scanline_width; //1; - data_rgba[ offset + 3 ] = scanline_buffer[ i + off ]; offset += 4; @@ -350,8 +333,9 @@ const RGBEByteToRGBHalf = function ( sourceArray, sourceOffset, destArray, destOffset ) { const e = sourceArray[ sourceOffset + 3 ]; - const scale = Math.pow( 2.0, e - 128.0 ) / 255.0; // clamping to 65504, the maximum representable value in float16 + const scale = Math.pow( 2.0, e - 128.0 ) / 255.0; + // clamping to 65504, the maximum representable value in float16 destArray[ destOffset + 0 ] = THREE.DataUtils.toHalfFloat( Math.min( sourceArray[ sourceOffset + 0 ] * scale, 65504 ) ); destArray[ destOffset + 1 ] = THREE.DataUtils.toHalfFloat( Math.min( sourceArray[ sourceOffset + 1 ] * scale, 65504 ) ); destArray[ destOffset + 2 ] = THREE.DataUtils.toHalfFloat( Math.min( sourceArray[ sourceOffset + 2 ] * scale, 65504 ) ); @@ -362,24 +346,20 @@ const byteArray = new Uint8Array( buffer ); byteArray.pos = 0; const rgbe_header_info = RGBE_ReadHeader( byteArray ); - if ( RGBE_RETURN_FAILURE !== rgbe_header_info ) { const w = rgbe_header_info.width, h = rgbe_header_info.height, image_rgba_data = RGBE_ReadPixels_RLE( byteArray.subarray( byteArray.pos ), w, h ); - if ( RGBE_RETURN_FAILURE !== image_rgba_data ) { let data, type; let numElements; - switch ( this.type ) { case THREE.FloatType: numElements = image_rgba_data.length / 4; const floatArray = new Float32Array( numElements * 4 ); - for ( let j = 0; j < numElements; j ++ ) { RGBEByteToRGBFloat( image_rgba_data, j * 4, floatArray, j * 4 ); @@ -389,11 +369,9 @@ data = floatArray; type = THREE.FloatType; break; - case THREE.HalfFloatType: numElements = image_rgba_data.length / 4; const halfArray = new Uint16Array( numElements * 4 ); - for ( let j = 0; j < numElements; j ++ ) { RGBEByteToRGBHalf( image_rgba_data, j * 4, halfArray, j * 4 ); @@ -403,7 +381,6 @@ data = halfArray; type = THREE.HalfFloatType; break; - default: console.error( 'THREE.RGBELoader: unsupported type: ', this.type ); break; @@ -427,14 +404,12 @@ return null; } - setDataType( value ) { this.type = value; return this; } - load( url, onLoad, onProgress, onError ) { function onLoadCallback( texture, texData ) { diff --git a/examples/js/loaders/RGBMLoader.js b/examples/js/loaders/RGBMLoader.js index a9575b42b4a5ef..ca341406296ef5 100644 --- a/examples/js/loaders/RGBMLoader.js +++ b/examples/js/loaders/RGBMLoader.js @@ -16,27 +16,23 @@ return this; } - setMaxRange( value ) { this.maxRange = value; return this; } - loadCubemap( urls, onLoad, onProgress, onError ) { const texture = new THREE.CubeTexture(); let loaded = 0; const scope = this; - function loadTexture( i ) { scope.load( urls[ i ], function ( image ) { texture.images[ i ] = image; loaded ++; - if ( loaded === 6 ) { texture.needsUpdate = true; @@ -61,14 +57,15 @@ return texture; } - parse( buffer ) { const img = UPNG.decode( buffer ); const rgba = UPNG.toRGBA8( img )[ 0 ]; const data = new Uint8Array( rgba ); const size = img.width * img.height * 4; - const output = this.type === THREE.HalfFloatType ? new Uint16Array( size ) : new Float32Array( size ); // decode RGBM + const output = this.type === THREE.HalfFloatType ? new Uint16Array( size ) : new Float32Array( size ); + + // decode RGBM for ( let i = 0; i < data.length; i += 4 ) { @@ -76,7 +73,6 @@ const g = data[ i + 1 ] / 255; const b = data[ i + 2 ] / 255; const a = data[ i + 3 ] / 255; - if ( this.type === THREE.HalfFloatType ) { output[ i + 0 ] = THREE.DataUtils.toHalfFloat( Math.min( r * a * this.maxRange, 65504 ) ); @@ -106,11 +102,11 @@ } - } // from https://github.com/photopea/UPNG.js (MIT License) + } + // from https://github.com/photopea/UPNG.js (MIT License) var UPNG = {}; - UPNG.toRGBA8 = function ( out ) { var w = out.width, @@ -122,7 +118,6 @@ img = new Uint8Array( len ), empty = new Uint8Array( len ), prev = new Uint8Array( len ); - for ( var i = 0; i < out.frames.length; i ++ ) { var frm = out.frames[ i ]; @@ -146,7 +141,6 @@ var area = w * h, bpp = UPNG.decode._getBPP( out ); - var bpl = Math.ceil( w * bpp / 8 ); // bytes per line var bf = new Uint8Array( area * 4 ), @@ -154,10 +148,10 @@ var ctype = out.ctype, depth = out.depth; var rs = UPNG._bin.readUshort; - if ( ctype == 6 ) { // RGB + alpha + var qarea = area << 2; if ( depth == 8 ) for ( var i = 0; i < qarea; i += 4 ) { @@ -177,8 +171,8 @@ } else if ( ctype == 2 ) { // RGB - var ts = out.tabs[ 'tRNS' ]; + var ts = out.tabs[ 'tRNS' ]; if ( ts == null ) { if ( depth == 8 ) for ( var i = 0; i < area; i ++ ) { @@ -223,15 +217,15 @@ } else if ( ctype == 3 ) { // palette + var p = out.tabs[ 'PLTE' ], ap = out.tabs[ 'tRNS' ], - tl = ap ? ap.length : 0; //console.log(p, ap); - + tl = ap ? ap.length : 0; + //console.log(p, ap); if ( depth == 1 ) for ( var y = 0; y < h; y ++ ) { var s0 = y * bpl, t0 = y * w; - for ( var i = 0; i < w; i ++ ) { var qi = t0 + i << 2, @@ -250,7 +244,6 @@ var s0 = y * bpl, t0 = y * w; - for ( var i = 0; i < w; i ++ ) { var qi = t0 + i << 2, @@ -269,7 +262,6 @@ var s0 = y * bpl, t0 = y * w; - for ( var i = 0; i < w; i ++ ) { var qi = t0 + i << 2, @@ -299,6 +291,7 @@ } else if ( ctype == 4 ) { // gray + alpha + if ( depth == 8 ) for ( var i = 0; i < area; i ++ ) { var qi = i << 2, @@ -326,8 +319,8 @@ } else if ( ctype == 0 ) { // gray - var tr = out.tabs[ 'tRNS' ] ? out.tabs[ 'tRNS' ] : - 1; + var tr = out.tabs[ 'tRNS' ] ? out.tabs[ 'tRNS' ] : - 1; for ( var y = 0; y < h; y ++ ) { var off = y * bpl, @@ -366,9 +359,9 @@ } - } //console.log(Date.now()-time); - + } + //console.log(Date.now()-time); return bf; }; @@ -386,21 +379,18 @@ }; var dd = new Uint8Array( data.length ), doff = 0; // put all IDAT data into it - var fd, foff = 0; // frames - var text, keyw, bfr; var mgck = [ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a ]; - for ( var i = 0; i < 8; i ++ ) if ( data[ i ] != mgck[ i ] ) throw new Error( 'The input is not a PNG file!' ); - while ( offset < data.length ) { var len = bin.readUint( data, offset ); offset += 4; var type = bin.readASCII( data, offset, 4 ); - offset += 4; //console.log(type,len); + offset += 4; + //console.log(type,len); if ( type == 'IHDR' ) { @@ -413,7 +403,6 @@ } else if ( type == 'IDAT' ) { for ( var i = 0; i < len; i ++ ) dd[ doff + i ] = data[ offset + i ]; - doff += len; } else if ( type == 'acTL' ) { @@ -447,14 +436,13 @@ delay: Math.round( del * 1000 ), dispose: data[ offset + 24 ], blend: data[ offset + 25 ] - }; //console.log(frm); - + }; + //console.log(frm); out.frames.push( frm ); } else if ( type == 'fdAT' ) { for ( var i = 0; i < len - 4; i ++ ) fd[ foff + i ] = data[ offset + i + 4 ]; - foff += len - 4; } else if ( type == 'pHYs' ) { @@ -464,7 +452,6 @@ } else if ( type == 'cHRM' ) { out.tabs[ type ] = []; - for ( var i = 0; i < 8; i ++ ) out.tabs[ type ].push( bin.readUint( data, offset + i * 4 ) ); } else if ( type == 'tEXt' || type == 'zTXt' ) { @@ -516,12 +503,12 @@ var pl = out.tabs[ 'PLTE' ].length / 3; out.tabs[ type ] = []; - for ( var i = 0; i < pl; i ++ ) out.tabs[ type ].push( rUs( data, offset + i * 2 ) ); } else if ( type == 'tRNS' ) { - if ( out.ctype == 3 ) out.tabs[ type ] = bin.readBytes( data, offset, len ); else if ( out.ctype == 0 ) out.tabs[ type ] = rUs( data, offset ); else if ( out.ctype == 2 ) out.tabs[ type ] = [ rUs( data, offset ), rUs( data, offset + 2 ), rUs( data, offset + 4 ) ]; //else console.log("tRNS for unsupported color type",out.ctype, len); + if ( out.ctype == 3 ) out.tabs[ type ] = bin.readBytes( data, offset, len ); else if ( out.ctype == 0 ) out.tabs[ type ] = rUs( data, offset ); else if ( out.ctype == 2 ) out.tabs[ type ] = [ rUs( data, offset ), rUs( data, offset + 2 ), rUs( data, offset + 4 ) ]; + //else console.log("tRNS for unsupported color type",out.ctype, len); } else if ( type == 'gAMA' ) out.tabs[ type ] = bin.readUint( data, offset ) / 100000; else if ( type == 'sRGB' ) out.tabs[ type ] = data[ offset ]; else if ( type == 'bKGD' ) { @@ -531,9 +518,9 @@ break; - } //else { console.log("unknown chunk type", type, len); out.tabs[type]=data.slice(offset,offset+len); } - + } + //else { console.log("unknown chunk type", type, len); out.tabs[type]=data.slice(offset,offset+len); } offset += len; bin.readUint( data, offset ); offset += 4; @@ -560,7 +547,6 @@ var bpp = UPNG.decode._getBPP( out ), bpl = Math.ceil( w * bpp / 8 ), buff = new Uint8Array( ( bpl + 1 + out.interlace ) * h ); - if ( out.tabs[ 'CgBI' ] ) dd = UPNG.inflateRaw( dd, buff ); else dd = UPNG.decode._inflate( dd, buff ); if ( out.interlace == 0 ) dd = UPNG.decode._filterZero( dd, out, 0, w, h ); else if ( out.interlace == 1 ) dd = UPNG.decode._readInterlace( dd, out ); return dd; @@ -578,7 +564,6 @@ var H = {}; H.H = {}; - H.H.N = function ( N, W ) { var R = Uint8Array, @@ -604,13 +589,11 @@ b = V.m, Z = W == null; if ( Z ) W = new R( N.length >>> 2 << 5 ); - while ( i == 0 ) { i = n( N, d, 1 ); m = n( N, d + 1, 2 ); d += 3; - if ( m == 0 ) { if ( ( d & 7 ) != 0 ) d += 8 - ( d & 7 ); @@ -625,7 +608,6 @@ } if ( Z ) W = H.H.W( W, w + ( 1 << 17 ) ); - if ( m == 1 ) { v = b.J; @@ -642,7 +624,6 @@ Q = A( N, d + 10, 4 ) + 4; d += 14; var j = 1; - for ( var c = 0; c < 38; c += 2 ) { b.Q[ c ] = 0; @@ -680,7 +661,6 @@ var T = v[ e( N, d ) & X ]; d += T & 15; var p = T >>> 4; - if ( p >>> 8 == 0 ) { W[ w ++ ] = p; @@ -692,7 +672,6 @@ } else { var z = w + p - 254; - if ( p > 264 ) { var _ = b.q[ p - 257 ]; @@ -707,7 +686,6 @@ Y = b.c[ s ], a = ( Y >>> 4 ) + n( N, d, Y & 15 ); d += Y & 15; - while ( w < z ) { W[ w ] = W[ w ++ - a ]; @@ -744,13 +722,11 @@ var l = H.H.e, M = H.H.Z, I = 0; - while ( I < R ) { var e = N[ M( V, n ) & W ]; n += e & 15; var b = e >>> 4; - if ( b <= 15 ) { A[ I ] = b; @@ -760,7 +736,6 @@ var Z = 0, m = 0; - if ( b == 16 ) { m = 3 + l( V, n, 2 ); @@ -780,7 +755,6 @@ } var J = I + m; - while ( I < J ) { A[ I ] = Z; @@ -801,7 +775,6 @@ var n = 0, A = 0, l = V.length >>> 1; - while ( A < R ) { var M = N[ A + W ]; @@ -834,15 +807,11 @@ M, I, e = R.j; - for ( var M = 0; M <= W; M ++ ) e[ M ] = 0; - for ( M = 1; M < V; M += 2 ) e[ N[ M ] ] ++; - var b = R.K; n = 0; e[ 0 ] = 0; - for ( A = 1; A <= W; A ++ ) { n = n + e[ A - 1 ] << 1; @@ -853,7 +822,6 @@ for ( l = 0; l < V; l += 2 ) { I = N[ l + 1 ]; - if ( I != 0 ) { N[ l ] = b[ I ]; @@ -870,7 +838,6 @@ var V = N.length, n = H.H.m, A = n.r; - for ( var l = 0; l < V; l += 2 ) if ( N[ l + 1 ] != 0 ) { var M = l >> 1, @@ -879,7 +846,6 @@ b = W - I, Z = N[ l ] << b, m = Z + ( 1 << b ); - while ( Z != m ) { var J = A[ Z ] >>> 15 - W; @@ -896,7 +862,6 @@ var R = H.H.m.r, V = 15 - W; - for ( var n = 0; n < N.length; n += 2 ) { var A = N[ n ] << W - N[ n + 1 ]; @@ -984,12 +949,10 @@ }; }(); - ( function () { var N = H.H.m, W = 1 << 15; - for ( var R = 0; R < W; R ++ ) { var V = R; @@ -1035,16 +998,13 @@ return H.H.N; }(); - UPNG.decode._readInterlace = function ( data, out ) { var w = out.width, h = out.height; - var bpp = UPNG.decode._getBPP( out ), cbpp = bpp >> 3, bpl = Math.ceil( w * bpp / 8 ); - var img = new Uint8Array( h * bpl ); var di = 0; var starting_row = [ 0, 0, 4, 0, 2, 0, 1 ]; @@ -1052,7 +1012,6 @@ var row_increment = [ 8, 8, 8, 4, 4, 2, 2 ]; var col_increment = [ 8, 8, 4, 4, 2, 2, 1 ]; var pass = 0; - while ( pass < 7 ) { var ri = row_increment[ pass ], @@ -1060,7 +1019,6 @@ var sw = 0, sh = 0; var cr = starting_row[ pass ]; - while ( cr < h ) { cr += ri; @@ -1069,7 +1027,6 @@ } var cc = starting_col[ pass ]; - while ( cc < w ) { cc += ci; @@ -1078,18 +1035,14 @@ } var bpll = Math.ceil( sw * bpp / 8 ); - UPNG.decode._filterZero( data, out, di, sw, sh ); - var y = 0, row = starting_row[ pass ]; var val; - while ( row < h ) { var col = starting_col[ pass ]; var cdi = di + y * bpll << 3; - while ( col < w ) { if ( bpp == 1 ) { @@ -1119,7 +1072,6 @@ if ( bpp >= 8 ) { var ii = row * bpl + col * cbpp; - for ( var j = 0; j < cbpp; j ++ ) img[ ii + j ] = data[ ( cdi >> 3 ) + j ]; } @@ -1155,7 +1107,6 @@ var bpp = UPNG.decode._getBPP( out ), bpl = Math.ceil( w * bpp / 8 ), paeth = UPNG.decode._paeth; - bpp = Math.ceil( bpp / 8 ); var i, di, @@ -1163,7 +1114,6 @@ x = 0; if ( type > 1 ) data[ off ] = [ 0, 0, 1 ][ type - 2 ]; if ( type == 3 ) for ( x = bpp; x < bpl; x ++ ) data[ x + 1 ] = data[ x + 1 ] + ( data[ x + 1 - bpp ] >>> 1 ) & 255; - for ( var y = 0; y < h; y ++ ) { i = off + y * bpl; @@ -1173,7 +1123,6 @@ if ( type == 0 ) for ( ; x < bpl; x ++ ) data[ i + x ] = data[ di + x ]; else if ( type == 1 ) { for ( ; x < bpp; x ++ ) data[ i + x ] = data[ di + x ]; - for ( ; x < bpl; x ++ ) data[ i + x ] = data[ di + x ] + data[ i + x - bpp ]; } else if ( type == 2 ) { @@ -1183,13 +1132,11 @@ } else if ( type == 3 ) { for ( ; x < bpp; x ++ ) data[ i + x ] = data[ di + x ] + ( data[ i + x - bpl ] >>> 1 ); - for ( ; x < bpl; x ++ ) data[ i + x ] = data[ di + x ] + ( data[ i + x - bpl ] + data[ i + x - bpp ] >>> 1 ); } else { for ( ; x < bpp; x ++ ) data[ i + x ] = data[ di + x ] + paeth( 0, data[ i + x - bpl ], 0 ); - for ( ; x < bpl; x ++ ) data[ i + x ] = data[ di + x ] + paeth( data[ i + x - bpp ], data[ i + x - bpl ], data[ i + x - bpp - bpl ] ); } @@ -1235,7 +1182,6 @@ nextZero: function ( data, p ) { while ( data[ p ] != 0 ) p ++; - return p; }, @@ -1266,9 +1212,7 @@ readASCII: function ( buff, p, l ) { var s = ''; - for ( var i = 0; i < l; i ++ ) s += String.fromCharCode( buff[ p + i ] ); - return s; }, @@ -1280,9 +1224,7 @@ readBytes: function ( buff, p, l ) { var arr = []; - for ( var i = 0; i < l; i ++ ) arr.push( buff[ p + i ] ); - return arr; }, @@ -1295,9 +1237,7 @@ var s = '', ns; - for ( var i = 0; i < l; i ++ ) s += '%' + UPNG._bin.pad( buff[ p + i ].toString( 16 ) ); - try { ns = decodeURIComponent( s ); @@ -1312,14 +1252,12 @@ } }; - UPNG._copyTile = function ( sb, sw, sh, tb, tw, th, xoff, yoff, mode ) { var w = Math.min( sw, tw ), h = Math.min( sh, th ); var si = 0, ti = 0; - for ( var y = 0; y < h; y ++ ) for ( var x = 0; x < w; x ++ ) { if ( xoff >= 0 && yoff >= 0 ) { @@ -1362,6 +1300,7 @@ } else if ( mode == 2 ) { // copy only differences, otherwise zero + var fa = sb[ si + 3 ], fr = sb[ si ], fg = sb[ si + 1 ], @@ -1370,7 +1309,6 @@ br = tb[ ti ], bg = tb[ ti + 1 ], bb = tb[ ti + 2 ]; - if ( fa == ba && fr == br && fg == bg && fb == bb ) { tb[ ti ] = 0; @@ -1390,6 +1328,7 @@ } else if ( mode == 3 ) { // check if can be blended + var fa = sb[ si + 3 ], fr = sb[ si ], fg = sb[ si + 1 ], @@ -1398,8 +1337,8 @@ br = tb[ ti ], bg = tb[ ti + 1 ], bb = tb[ ti + 2 ]; - if ( fa == ba && fr == br && fg == bg && fb == bb ) continue; //if(fa!=255 && ba!=0) return false; - + if ( fa == ba && fr == br && fg == bg && fb == bb ) continue; + //if(fa!=255 && ba!=0) return false; if ( fa < 220 && ba > 20 ) return false; } diff --git a/examples/js/loaders/STLLoader.js b/examples/js/loaders/STLLoader.js index efd8d8cc767a2e..6554a59457369c 100644 --- a/examples/js/loaders/STLLoader.js +++ b/examples/js/loaders/STLLoader.js @@ -58,7 +58,6 @@ super( manager ); } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -92,7 +91,6 @@ }, onProgress, onError ); } - parse( data ) { function isBinary( data ) { @@ -101,29 +99,32 @@ const face_size = 32 / 8 * 3 + 32 / 8 * 3 * 3 + 16 / 8; const n_faces = reader.getUint32( 80, true ); const expect = 80 + 32 / 8 + n_faces * face_size; - if ( expect === reader.byteLength ) { return true; - } // An ASCII STL data must begin with 'solid ' as the first six bytes. + } + + // An ASCII STL data must begin with 'solid ' as the first six bytes. // However, ASCII STLs lacking the SPACE after the 'd' are known to be // plentiful. So, check the first 5 bytes for 'solid'. + // Several encodings, such as UTF-8, precede the text with up to 5 bytes: // https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding // Search for "solid" to start anywhere after those prefixes. - // US-ASCII ordinal values for 's', 'o', 'l', 'i', 'd' + // US-ASCII ordinal values for 's', 'o', 'l', 'i', 'd' const solid = [ 115, 111, 108, 105, 100 ]; - for ( let off = 0; off < 5; off ++ ) { // If "solid" text is matched to the current offset, declare it to be an ASCII STL. + if ( matchDataViewAt( solid, reader, off ) ) return false; - } // Couldn't find "solid" text at the beginning; it is binary STL. + } + // Couldn't find "solid" text at the beginning; it is binary STL. return true; @@ -132,6 +133,7 @@ function matchDataViewAt( query, reader, offset ) { // Check if each byte in query matches the corresponding byte from the current offset + for ( let i = 0, il = query.length; i < il; i ++ ) { if ( query[ i ] !== reader.getUint8( offset + i ) ) return false; @@ -151,18 +153,14 @@ b, hasColors = false, colors; - let defaultR, defaultG, defaultB, alpha; // process STL header + let defaultR, defaultG, defaultB, alpha; + + // process STL header // check for default color in header ("COLOR=rgba" sequence). for ( let index = 0; index < 80 - 10; index ++ ) { - if ( reader.getUint32( index, false ) == 0x434F4C4F - /*COLO*/ - && reader.getUint8( index + 4 ) == 0x52 - /*'R'*/ - && reader.getUint8( index + 5 ) == 0x3D - /*'='*/ - ) { + if ( reader.getUint32( index, false ) == 0x434F4C4F /*COLO*/ && reader.getUint8( index + 4 ) == 0x52 /*'R'*/ && reader.getUint8( index + 5 ) == 0x3D /*'='*/ ) { hasColors = true; colors = new Float32Array( faces * 3 * 3 ); @@ -180,21 +178,19 @@ const geometry = new THREE.BufferGeometry(); const vertices = new Float32Array( faces * 3 * 3 ); const normals = new Float32Array( faces * 3 * 3 ); - for ( let face = 0; face < faces; face ++ ) { const start = dataOffset + face * faceLength; const normalX = reader.getFloat32( start, true ); const normalY = reader.getFloat32( start + 4, true ); const normalZ = reader.getFloat32( start + 8, true ); - if ( hasColors ) { const packedColor = reader.getUint16( start + 48, true ); - if ( ( packedColor & 0x8000 ) === 0 ) { // facet has its own unique color + r = ( packedColor & 0x1F ) / 31; g = ( packedColor >> 5 & 0x1F ) / 31; b = ( packedColor >> 10 & 0x1F ) / 31; @@ -219,7 +215,6 @@ normals[ componentIdx ] = normalX; normals[ componentIdx + 1 ] = normalY; normals[ componentIdx + 2 ] = normalZ; - if ( hasColors ) { colors[ componentIdx ] = r; @@ -234,7 +229,6 @@ geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); geometry.setAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); - if ( hasColors ) { geometry.setAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) ); @@ -263,18 +257,15 @@ let groupCount = 0; let startVertex = 0; let endVertex = 0; - while ( ( result = patternSolid.exec( data ) ) !== null ) { startVertex = endVertex; const solid = result[ 0 ]; - while ( ( result = patternFace.exec( solid ) ) !== null ) { let vertexCountPerFace = 0; let normalCountPerFace = 0; const text = result[ 0 ]; - while ( ( result = patternNormal.exec( text ) ) !== null ) { normal.x = parseFloat( result[ 1 ] ); @@ -291,15 +282,17 @@ vertexCountPerFace ++; endVertex ++; - } // every face have to own ONE valid normal + } + // every face have to own ONE valid normal if ( normalCountPerFace !== 1 ) { console.error( 'THREE.STLLoader: Something isn\'t right with the normal of face number ' + faceCounter ); - } // each face have to own THREE valid vertices + } + // each face have to own THREE valid vertices if ( vertexCountPerFace !== 3 ) { @@ -341,7 +334,6 @@ if ( typeof buffer === 'string' ) { const array_buffer = new Uint8Array( buffer.length ); - for ( let i = 0; i < buffer.length; i ++ ) { array_buffer[ i ] = buffer.charCodeAt( i ) & 0xff; // implicitly assumes little-endian @@ -356,8 +348,9 @@ } - } // start + } + // start const binData = ensureBinary( data ); return isBinary( binData ) ? parseBinary( binData ) : parseASCII( ensureString( data ) ); diff --git a/examples/js/loaders/SVGLoader.js b/examples/js/loaders/SVGLoader.js index fd5368cd387a8f..7fd71f480d0dfb 100644 --- a/examples/js/loaders/SVGLoader.js +++ b/examples/js/loaders/SVGLoader.js @@ -4,14 +4,15 @@ constructor( manager ) { - super( manager ); // Default dots per inch + super( manager ); - this.defaultDPI = 90; // Accepted units: 'mm', 'cm', 'in', 'pt', 'pc', 'px' + // Default dots per inch + this.defaultDPI = 90; + // Accepted units: 'mm', 'cm', 'in', 'pt', 'pc', 'px' this.defaultUnit = 'px'; } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -44,77 +45,62 @@ }, onProgress, onError ); } - parse( text ) { const scope = this; - function parseNode( node, style ) { if ( node.nodeType !== 1 ) return; const transform = getNodeTransform( node ); let isDefsNode = false; let path = null; - switch ( node.nodeName ) { case 'svg': style = parseStyle( node, style ); break; - case 'style': parseCSSStylesheet( node ); break; - case 'g': style = parseStyle( node, style ); break; - case 'path': style = parseStyle( node, style ); if ( node.hasAttribute( 'd' ) ) path = parsePathNode( node ); break; - case 'rect': style = parseStyle( node, style ); path = parseRectNode( node ); break; - case 'polygon': style = parseStyle( node, style ); path = parsePolygonNode( node ); break; - case 'polyline': style = parseStyle( node, style ); path = parsePolylineNode( node ); break; - case 'circle': style = parseStyle( node, style ); path = parseCircleNode( node ); break; - case 'ellipse': style = parseStyle( node, style ); path = parseEllipseNode( node ); break; - case 'line': style = parseStyle( node, style ); path = parseLineNode( node ); break; - case 'defs': isDefsNode = true; break; - case 'use': style = parseStyle( node, style ); const href = node.getAttributeNS( 'http://www.w3.org/1999/xlink', 'href' ) || ''; const usedNodeId = href.substring( 1 ); const usedNode = node.viewportElement.getElementById( usedNodeId ); - if ( usedNode ) { parseNode( usedNode, style ); @@ -126,8 +112,8 @@ } break; - - default: // console.log( node ); + default: + // console.log( node ); } @@ -149,11 +135,9 @@ } const childNodes = node.childNodes; - for ( let i = 0; i < childNodes.length; i ++ ) { const node = childNodes[ i ]; - if ( isDefsNode && node.nodeName !== 'style' && node.nodeName !== 'defs' ) { // Ignore everything in defs except CSS style definitions @@ -170,7 +154,6 @@ if ( transform ) { transformStack.pop(); - if ( transformStack.length > 0 ) { currentTransform.copy( transformStack[ transformStack.length - 1 ] ); @@ -193,16 +176,16 @@ const firstPoint = new THREE.Vector2(); let isFirstPoint = true; let doSetFirstPoint = false; - const d = node.getAttribute( 'd' ); // console.log( d ); + const d = node.getAttribute( 'd' ); - const commands = d.match( /[a-df-z][^a-df-z]*/ig ); + // console.log( d ); + const commands = d.match( /[a-df-z][^a-df-z]*/ig ); for ( let i = 0, l = commands.length; i < l; i ++ ) { const command = commands[ i ]; const type = command.charAt( 0 ); const data = command.slice( 1 ).trim(); - if ( isFirstPoint === true ) { doSetFirstPoint = true; @@ -211,19 +194,16 @@ } let numbers; - switch ( type ) { case 'M': numbers = parseFloats( data ); - for ( let j = 0, jl = numbers.length; j < jl; j += 2 ) { point.x = numbers[ j + 0 ]; point.y = numbers[ j + 1 ]; control.x = point.x; control.y = point.y; - if ( j === 0 ) { path.moveTo( point.x, point.y ); @@ -239,10 +219,8 @@ } break; - case 'H': numbers = parseFloats( data ); - for ( let j = 0, jl = numbers.length; j < jl; j ++ ) { point.x = numbers[ j ]; @@ -254,10 +232,8 @@ } break; - case 'V': numbers = parseFloats( data ); - for ( let j = 0, jl = numbers.length; j < jl; j ++ ) { point.y = numbers[ j ]; @@ -269,10 +245,8 @@ } break; - case 'L': numbers = parseFloats( data ); - for ( let j = 0, jl = numbers.length; j < jl; j += 2 ) { point.x = numbers[ j + 0 ]; @@ -285,10 +259,8 @@ } break; - case 'C': numbers = parseFloats( data ); - for ( let j = 0, jl = numbers.length; j < jl; j += 6 ) { path.bezierCurveTo( numbers[ j + 0 ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ], numbers[ j + 4 ], numbers[ j + 5 ] ); @@ -301,10 +273,8 @@ } break; - case 'S': numbers = parseFloats( data ); - for ( let j = 0, jl = numbers.length; j < jl; j += 4 ) { path.bezierCurveTo( getReflection( point.x, control.x ), getReflection( point.y, control.y ), numbers[ j + 0 ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ] ); @@ -317,10 +287,8 @@ } break; - case 'Q': numbers = parseFloats( data ); - for ( let j = 0, jl = numbers.length; j < jl; j += 4 ) { path.quadraticCurveTo( numbers[ j + 0 ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ] ); @@ -333,10 +301,8 @@ } break; - case 'T': numbers = parseFloats( data ); - for ( let j = 0, jl = numbers.length; j < jl; j += 2 ) { const rx = getReflection( point.x, control.x ); @@ -351,10 +317,8 @@ } break; - case 'A': numbers = parseFloats( data, [ 3, 4 ], 7 ); - for ( let j = 0, jl = numbers.length; j < jl; j += 7 ) { // skip command if start point == end point @@ -370,17 +334,14 @@ } break; - case 'm': numbers = parseFloats( data ); - for ( let j = 0, jl = numbers.length; j < jl; j += 2 ) { point.x += numbers[ j + 0 ]; point.y += numbers[ j + 1 ]; control.x = point.x; control.y = point.y; - if ( j === 0 ) { path.moveTo( point.x, point.y ); @@ -396,10 +357,8 @@ } break; - case 'h': numbers = parseFloats( data ); - for ( let j = 0, jl = numbers.length; j < jl; j ++ ) { point.x += numbers[ j ]; @@ -411,10 +370,8 @@ } break; - case 'v': numbers = parseFloats( data ); - for ( let j = 0, jl = numbers.length; j < jl; j ++ ) { point.y += numbers[ j ]; @@ -426,10 +383,8 @@ } break; - case 'l': numbers = parseFloats( data ); - for ( let j = 0, jl = numbers.length; j < jl; j += 2 ) { point.x += numbers[ j + 0 ]; @@ -442,10 +397,8 @@ } break; - case 'c': numbers = parseFloats( data ); - for ( let j = 0, jl = numbers.length; j < jl; j += 6 ) { path.bezierCurveTo( point.x + numbers[ j + 0 ], point.y + numbers[ j + 1 ], point.x + numbers[ j + 2 ], point.y + numbers[ j + 3 ], point.x + numbers[ j + 4 ], point.y + numbers[ j + 5 ] ); @@ -458,10 +411,8 @@ } break; - case 's': numbers = parseFloats( data ); - for ( let j = 0, jl = numbers.length; j < jl; j += 4 ) { path.bezierCurveTo( getReflection( point.x, control.x ), getReflection( point.y, control.y ), point.x + numbers[ j + 0 ], point.y + numbers[ j + 1 ], point.x + numbers[ j + 2 ], point.y + numbers[ j + 3 ] ); @@ -474,10 +425,8 @@ } break; - case 'q': numbers = parseFloats( data ); - for ( let j = 0, jl = numbers.length; j < jl; j += 4 ) { path.quadraticCurveTo( point.x + numbers[ j + 0 ], point.y + numbers[ j + 1 ], point.x + numbers[ j + 2 ], point.y + numbers[ j + 3 ] ); @@ -490,10 +439,8 @@ } break; - case 't': numbers = parseFloats( data ); - for ( let j = 0, jl = numbers.length; j < jl; j += 2 ) { const rx = getReflection( point.x, control.x ); @@ -508,10 +455,8 @@ } break; - case 'a': numbers = parseFloats( data, [ 3, 4 ], 7 ); - for ( let j = 0, jl = numbers.length; j < jl; j += 7 ) { // skip command if no displacement @@ -527,11 +472,9 @@ } break; - case 'Z': case 'z': path.currentPath.autoClose = true; - if ( path.currentPath.curves.length > 0 ) { // Reset point to beginning of THREE.Path @@ -542,12 +485,12 @@ } break; - default: console.warn( command ); - } // console.log( type, parseFloats( data ), parseFloats( data ).length ) + } + // console.log( type, parseFloats( data ), parseFloats( data ).length ) doSetFirstPoint = false; @@ -560,13 +503,11 @@ function parseCSSStylesheet( node ) { if ( ! node.sheet || ! node.sheet.cssRules || ! node.sheet.cssRules.length ) return; - for ( let i = 0; i < node.sheet.cssRules.length; i ++ ) { const stylesheet = node.sheet.cssRules[ i ]; if ( stylesheet.type !== 1 ) continue; const selectorList = stylesheet.selectorText.split( /,/gm ).filter( Boolean ).map( i => i.trim() ); - for ( let j = 0; j < selectorList.length; j ++ ) { // Remove empty rules @@ -578,6 +519,7 @@ } } + /** * https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes * https://mortoray.com/2017/02/16/rendering-an-svg-elliptical-arc-as-bezier-curves/ Appendix: Endpoint to center arc conversion @@ -587,7 +529,6 @@ * aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation */ - function parseArcCommand( path, rx, ry, x_axis_rotation, large_arc_flag, sweep_flag, start, end ) { if ( rx == 0 || ry == 0 ) { @@ -598,23 +539,26 @@ } - x_axis_rotation = x_axis_rotation * Math.PI / 180; // Ensure radii are positive + x_axis_rotation = x_axis_rotation * Math.PI / 180; + // Ensure radii are positive rx = Math.abs( rx ); - ry = Math.abs( ry ); // Compute (x1', y1') + ry = Math.abs( ry ); + // Compute (x1', y1') const dx2 = ( start.x - end.x ) / 2.0; const dy2 = ( start.y - end.y ) / 2.0; const x1p = Math.cos( x_axis_rotation ) * dx2 + Math.sin( x_axis_rotation ) * dy2; - const y1p = - Math.sin( x_axis_rotation ) * dx2 + Math.cos( x_axis_rotation ) * dy2; // Compute (cx', cy') + const y1p = - Math.sin( x_axis_rotation ) * dx2 + Math.cos( x_axis_rotation ) * dy2; + // Compute (cx', cy') let rxs = rx * rx; let rys = ry * ry; const x1ps = x1p * x1p; - const y1ps = y1p * y1p; // Ensure radii are large enough + const y1ps = y1p * y1p; + // Ensure radii are large enough const cr = x1ps / rxs + y1ps / rys; - if ( cr > 1 ) { // scale up rx,ry equally so cr == 1 @@ -631,11 +575,13 @@ let q = Math.sqrt( Math.max( 0, pq ) ); if ( large_arc_flag === sweep_flag ) q = - q; const cxp = q * rx * y1p / ry; - const cyp = - q * ry * x1p / rx; // Step 3: Compute (cx, cy) from (cx', cy') + const cyp = - q * ry * x1p / rx; + // Step 3: Compute (cx, cy) from (cx', cy') const cx = Math.cos( x_axis_rotation ) * cxp - Math.sin( x_axis_rotation ) * cyp + ( start.x + end.x ) / 2; - const cy = Math.sin( x_axis_rotation ) * cxp + Math.cos( x_axis_rotation ) * cyp + ( start.y + end.y ) / 2; // Step 4: Compute θ1 and Δθ + const cy = Math.sin( x_axis_rotation ) * cxp + Math.cos( x_axis_rotation ) * cyp + ( start.y + end.y ) / 2; + // Step 4: Compute θ1 and Δθ const theta = svgAngle( 1, 0, ( x1p - cxp ) / rx, ( y1p - cyp ) / ry ); const delta = svgAngle( ( x1p - cxp ) / rx, ( y1p - cyp ) / ry, ( - x1p - cxp ) / rx, ( - y1p - cyp ) / ry ) % ( Math.PI * 2 ); path.currentPath.absellipse( cx, cy, rx, ry, theta, theta + delta, sweep_flag === 0, x_axis_rotation ); @@ -647,17 +593,15 @@ const dot = ux * vx + uy * vy; const len = Math.sqrt( ux * ux + uy * uy ) * Math.sqrt( vx * vx + vy * vy ); let ang = Math.acos( Math.max( - 1, Math.min( 1, dot / len ) ) ); // floating point precision, slightly over values appear - if ( ux * vy - uy * vx < 0 ) ang = - ang; return ang; } + /* * According to https://www.w3.org/TR/SVG/shapes.html#RectElementRXAttribute * rounded corner should be rendered to elliptical arc, but bezier curve does the job well enough */ - - function parseRectNode( node ) { const x = parseFloatWithUnits( node.getAttribute( 'x' ) || 0 ); @@ -665,43 +609,42 @@ const rx = parseFloatWithUnits( node.getAttribute( 'rx' ) || node.getAttribute( 'ry' ) || 0 ); const ry = parseFloatWithUnits( node.getAttribute( 'ry' ) || node.getAttribute( 'rx' ) || 0 ); const w = parseFloatWithUnits( node.getAttribute( 'width' ) ); - const h = parseFloatWithUnits( node.getAttribute( 'height' ) ); // Ellipse arc to Bezier approximation Coefficient (Inversed). See: - // https://spencermortensen.com/articles/bezier-circle/ + const h = parseFloatWithUnits( node.getAttribute( 'height' ) ); + // Ellipse arc to Bezier approximation Coefficient (Inversed). See: + // https://spencermortensen.com/articles/bezier-circle/ const bci = 1 - 0.551915024494; - const path = new THREE.ShapePath(); // top left + const path = new THREE.ShapePath(); - path.moveTo( x + rx, y ); // top right + // top left + path.moveTo( x + rx, y ); + // top right path.lineTo( x + w - rx, y ); - if ( rx !== 0 || ry !== 0 ) { path.bezierCurveTo( x + w - rx * bci, y, x + w, y + ry * bci, x + w, y + ry ); - } // bottom right - + } + // bottom right path.lineTo( x + w, y + h - ry ); - if ( rx !== 0 || ry !== 0 ) { path.bezierCurveTo( x + w, y + h - ry * bci, x + w - rx * bci, y + h, x + w - rx, y + h ); - } // bottom left - + } + // bottom left path.lineTo( x + rx, y + h ); - if ( rx !== 0 || ry !== 0 ) { path.bezierCurveTo( x + rx * bci, y + h, x, y + h - ry * bci, x, y + h - ry ); - } // back to top left - + } + // back to top left path.lineTo( x, y + ry ); - if ( rx !== 0 || ry !== 0 ) { path.bezierCurveTo( x, y + ry * bci, x + rx * bci, y, x + rx, y ); @@ -718,7 +661,6 @@ const x = parseFloatWithUnits( a ); const y = parseFloatWithUnits( b ); - if ( index === 0 ) { path.moveTo( x, y ); @@ -748,7 +690,6 @@ const x = parseFloatWithUnits( a ); const y = parseFloatWithUnits( b ); - if ( index === 0 ) { path.moveTo( x, y ); @@ -811,19 +752,18 @@ path.currentPath.autoClose = false; return path; - } // + } + // function parseStyle( node, style ) { style = Object.assign( {}, style ); // clone style let stylesheetStyles = {}; - if ( node.hasAttribute( 'class' ) ) { const classSelectors = node.getAttribute( 'class' ).split( /\s/ ).filter( Boolean ).map( i => i.trim() ); - for ( let i = 0; i < classSelectors.length; i ++ ) { stylesheetStyles = Object.assign( stylesheetStyles, stylesheets[ '.' + classSelectors[ i ] ] ); @@ -878,15 +818,17 @@ addStyle( 'visibility', 'visibility' ); return style; - } // http://www.w3.org/TR/SVG11/implnote.html#PathElementImplementationNotes + } + // http://www.w3.org/TR/SVG11/implnote.html#PathElementImplementationNotes function getReflection( a, b ) { return a - ( b - a ); - } // from https://github.com/ppvg/svg-numbers (MIT License) + } + // from https://github.com/ppvg/svg-numbers (MIT License) function parseFloats( input, flags, stride ) { @@ -894,9 +836,9 @@ throw new TypeError( 'Invalid input: ' + typeof input ); - } // Character groups - + } + // Character groups const RE = { SEPARATOR: /[ \t\r\n\,.\-+]/, WHITESPACE: /[ \t\r\n]/, @@ -906,8 +848,9 @@ COMMA: /,/, EXP: /e/i, FLAGS: /[01]/ - }; // States + }; + // States const SEP = 0; const INT = 1; const FLOAT = 2; @@ -917,7 +860,6 @@ let number = '', exponent = ''; const result = []; - function throwSyntaxError( current, i, partial ) { const error = new SyntaxError( 'Unexpected character "' + current + '" at index ' + i + '.' ); @@ -941,11 +883,11 @@ let current; const length = input.length; - for ( let i = 0; i < length; i ++ ) { - current = input[ i ]; // check for flags + current = input[ i ]; + // check for flags if ( Array.isArray( flags ) && flags.includes( result.length % stride ) && RE.FLAGS.test( current ) ) { state = INT; @@ -953,9 +895,9 @@ newNumber(); continue; - } // parse until next number - + } + // parse until next number if ( state === SEP ) { // eat whitespace @@ -963,9 +905,9 @@ continue; - } // start new number - + } + // start new number if ( RE.DIGIT.test( current ) || RE.SIGN.test( current ) ) { state = INT; @@ -980,9 +922,9 @@ number = current; continue; - } // throw on double commas (e.g. "1, , 2") - + } + // throw on double commas (e.g. "1, , 2") if ( RE.COMMA.test( current ) ) { if ( seenComma ) { @@ -995,9 +937,9 @@ } - } // parse integer part - + } + // parse integer part if ( state === INT ) { if ( RE.DIGIT.test( current ) ) { @@ -1020,18 +962,18 @@ state = EXP; continue; - } // throw on double signs ("-+1"), but not on sign as separator ("-1-2") - + } + // throw on double signs ("-+1"), but not on sign as separator ("-1-2") if ( RE.SIGN.test( current ) && number.length === 1 && RE.SIGN.test( number[ 0 ] ) ) { throwSyntaxError( current, i, result ); } - } // parse decimal part - + } + // parse decimal part if ( state === FLOAT ) { if ( RE.DIGIT.test( current ) ) { @@ -1046,18 +988,18 @@ state = EXP; continue; - } // throw on double decimal points (e.g. "1..2") - + } + // throw on double decimal points (e.g. "1..2") if ( RE.POINT.test( current ) && number[ number.length - 1 ] === '.' ) { throwSyntaxError( current, i, result ); } - } // parse exponent part - + } + // parse exponent part if ( state === EXP ) { if ( RE.DIGIT.test( current ) ) { @@ -1084,9 +1026,9 @@ } - } // end of number - + } + // end of number if ( RE.WHITESPACE.test( current ) ) { newNumber(); @@ -1117,17 +1059,19 @@ } - } // add the last number found (if any) - + } + // add the last number found (if any) newNumber(); return result; - } // Units + } + // Units - const units = [ 'mm', 'cm', 'in', 'pt', 'pc', 'px' ]; // Conversion: [ fromUnit ][ toUnit ] (-1 means dpi dependent) + const units = [ 'mm', 'cm', 'in', 'pt', 'pc', 'px' ]; + // Conversion: [ fromUnit ][ toUnit ] (-1 means dpi dependent) const unitConversion = { 'mm': { 'mm': 1, @@ -1173,17 +1117,14 @@ 'px': 1 } }; - function parseFloatWithUnits( string ) { let theUnit = 'px'; - if ( typeof string === 'string' || string instanceof String ) { for ( let i = 0, n = units.length; i < n; i ++ ) { const u = units[ i ]; - if ( string.endsWith( u ) ) { theUnit = u; @@ -1197,19 +1138,19 @@ } let scale = undefined; - if ( theUnit === 'px' && scope.defaultUnit !== 'px' ) { // Conversion scale from pixels to inches, then to default units + scale = unitConversion[ 'in' ][ scope.defaultUnit ] / scope.defaultDPI; } else { scale = unitConversion[ theUnit ][ scope.defaultUnit ]; - if ( scale < 0 ) { // Conversion scale to pixels + scale = unitConversion[ theUnit ][ 'in' ] * scope.defaultDPI; } @@ -1218,8 +1159,9 @@ return scale * parseFloat( string ); - } // Transforms + } + // Transforms function getNodeTransform( node ) { @@ -1230,7 +1172,6 @@ } const transform = parseNodeTransform( node ); - if ( transformStack.length > 0 ) { transform.premultiply( transformStack[ transformStack.length - 1 ] ); @@ -1247,7 +1188,6 @@ const transform = new THREE.Matrix3(); const currentTransform = tempTransform0; - if ( node.nodeName === 'use' && ( node.hasAttribute( 'x' ) || node.hasAttribute( 'y' ) ) ) { const tx = parseFloatWithUnits( node.getAttribute( 'x' ) ); @@ -1259,28 +1199,24 @@ if ( node.hasAttribute( 'transform' ) ) { const transformsTexts = node.getAttribute( 'transform' ).split( ')' ); - for ( let tIndex = transformsTexts.length - 1; tIndex >= 0; tIndex -- ) { const transformText = transformsTexts[ tIndex ].trim(); if ( transformText === '' ) continue; const openParPos = transformText.indexOf( '(' ); const closeParPos = transformText.length; - if ( openParPos > 0 && openParPos < closeParPos ) { const transformType = transformText.slice( 0, openParPos ); const array = parseFloats( transformText.slice( openParPos + 1 ) ); currentTransform.identity(); - switch ( transformType ) { case 'translate': if ( array.length >= 1 ) { const tx = array[ 0 ]; - let ty = tx; - + let ty = 0; if ( array.length >= 2 ) { ty = array[ 1 ]; @@ -1292,41 +1228,38 @@ } break; - case 'rotate': if ( array.length >= 1 ) { let angle = 0; let cx = 0; - let cy = 0; // Angle - - angle = - array[ 0 ] * Math.PI / 180; + let cy = 0; + // Angle + angle = array[ 0 ] * Math.PI / 180; if ( array.length >= 3 ) { // Center x, y cx = array[ 1 ]; cy = array[ 2 ]; - } // Rotate around center (cx, cy) - + } - tempTransform1.identity().translate( - cx, - cy ); - tempTransform2.identity().rotate( angle ); + // Rotate around center (cx, cy) + tempTransform1.makeTranslation( - cx, - cy ); + tempTransform2.makeRotation( angle ); tempTransform3.multiplyMatrices( tempTransform2, tempTransform1 ); - tempTransform1.identity().translate( cx, cy ); + tempTransform1.makeTranslation( cx, cy ); currentTransform.multiplyMatrices( tempTransform1, tempTransform3 ); } break; - case 'scale': if ( array.length >= 1 ) { const scaleX = array[ 0 ]; let scaleY = scaleX; - if ( array.length >= 2 ) { scaleY = array[ 1 ]; @@ -1338,7 +1271,6 @@ } break; - case 'skewX': if ( array.length === 1 ) { @@ -1347,7 +1279,6 @@ } break; - case 'skewY': if ( array.length === 1 ) { @@ -1356,7 +1287,6 @@ } break; - case 'matrix': if ( array.length === 6 ) { @@ -1389,18 +1319,99 @@ } - const isRotated = isTransformRotated( m ); - const subPaths = path.subPaths; + function transfEllipseGeneric( curve ) { + + // For math description see: + // https://math.stackexchange.com/questions/4544164 + + const a = curve.xRadius; + const b = curve.yRadius; + const cosTheta = Math.cos( curve.aRotation ); + const sinTheta = Math.sin( curve.aRotation ); + const v1 = new THREE.Vector3( a * cosTheta, a * sinTheta, 0 ); + const v2 = new THREE.Vector3( - b * sinTheta, b * cosTheta, 0 ); + const f1 = v1.applyMatrix3( m ); + const f2 = v2.applyMatrix3( m ); + const mF = tempTransform0.set( f1.x, f2.x, 0, f1.y, f2.y, 0, 0, 0, 1 ); + const mFInv = tempTransform1.copy( mF ).invert(); + const mFInvT = tempTransform2.copy( mFInv ).transpose(); + const mQ = mFInvT.multiply( mFInv ); + const mQe = mQ.elements; + const ed = eigenDecomposition( mQe[ 0 ], mQe[ 1 ], mQe[ 4 ] ); + const rt1sqrt = Math.sqrt( ed.rt1 ); + const rt2sqrt = Math.sqrt( ed.rt2 ); + curve.xRadius = 1 / rt1sqrt; + curve.yRadius = 1 / rt2sqrt; + curve.aRotation = Math.atan2( ed.sn, ed.cs ); + const isFullEllipse = ( curve.aEndAngle - curve.aStartAngle ) % ( 2 * Math.PI ) < Number.EPSILON; + + // Do not touch angles of a full ellipse because after transformation they + // would converge to a sinle value effectively removing the whole curve + + if ( ! isFullEllipse ) { + + const mDsqrt = tempTransform1.set( rt1sqrt, 0, 0, 0, rt2sqrt, 0, 0, 0, 1 ); + const mRT = tempTransform2.set( ed.cs, ed.sn, 0, - ed.sn, ed.cs, 0, 0, 0, 1 ); + const mDRF = mDsqrt.multiply( mRT ).multiply( mF ); + const transformAngle = phi => { + + const { + x: cosR, + y: sinR + } = new THREE.Vector3( Math.cos( phi ), Math.sin( phi ), 0 ).applyMatrix3( mDRF ); + return Math.atan2( sinR, cosR ); + + }; + + curve.aStartAngle = transformAngle( curve.aStartAngle ); + curve.aEndAngle = transformAngle( curve.aEndAngle ); + if ( isTransformFlipped( m ) ) { + + curve.aClockwise = ! curve.aClockwise; + + } + + } + + } + + function transfEllipseNoSkew( curve ) { + // Faster shortcut if no skew is applied + // (e.g, a euclidean transform of a group containing the ellipse) + + const sx = getTransformScaleX( m ); + const sy = getTransformScaleY( m ); + curve.xRadius *= sx; + curve.yRadius *= sy; + + // Extract rotation angle from the matrix of form: + // + // | cosθ sx -sinθ sy | + // | sinθ sx cosθ sy | + // + // Remembering that tanθ = sinθ / cosθ; and that + // `sx`, `sy`, or both might be zero. + const theta = sx > Number.EPSILON ? Math.atan2( m.elements[ 1 ], m.elements[ 0 ] ) : Math.atan2( - m.elements[ 3 ], m.elements[ 4 ] ); + curve.aRotation += theta; + if ( isTransformFlipped( m ) ) { + + curve.aStartAngle *= - 1; + curve.aEndAngle *= - 1; + curve.aClockwise = ! curve.aClockwise; + + } + + } + + const subPaths = path.subPaths; for ( let i = 0, n = subPaths.length; i < n; i ++ ) { const subPath = subPaths[ i ]; const curves = subPath.curves; - for ( let j = 0; j < curves.length; j ++ ) { const curve = curves[ j ]; - if ( curve.isLineCurve ) { transfVec2( curve.v1 ); @@ -1421,18 +1432,24 @@ } else if ( curve.isEllipseCurve ) { - if ( isRotated ) { - - console.warn( 'SVGLoader: Elliptic arc or ellipse rotation or skewing is not implemented.' ); - - } + // Transform ellipse center point tempV2.set( curve.aX, curve.aY ); transfVec2( tempV2 ); curve.aX = tempV2.x; curve.aY = tempV2.y; - curve.xRadius *= getTransformScaleX( m ); - curve.yRadius *= getTransformScaleY( m ); + + // Transform ellipse shape parameters + + if ( isTransformSkewed( m ) ) { + + transfEllipseGeneric( curve ); + + } else { + + transfEllipseNoSkew( curve ); + + } } @@ -1442,9 +1459,23 @@ } - function isTransformRotated( m ) { + function isTransformFlipped( m ) { + + const te = m.elements; + return te[ 0 ] * te[ 4 ] - te[ 1 ] * te[ 3 ] < 0; + + } + + function isTransformSkewed( m ) { + + const te = m.elements; + const basisDot = te[ 0 ] * te[ 3 ] + te[ 1 ] * te[ 4 ]; - return m.elements[ 1 ] !== 0 || m.elements[ 3 ] !== 0; + // Shortcut for trivial rotations and transformations + if ( basisDot === 0 ) return false; + const sx = getTransformScaleX( m ); + const sy = getTransformScaleY( m ); + return Math.abs( basisDot / ( sx * sy ) ) > Number.EPSILON; } @@ -1460,8 +1491,92 @@ const te = m.elements; return Math.sqrt( te[ 3 ] * te[ 3 ] + te[ 4 ] * te[ 4 ] ); - } // + } + + // Calculates the eigensystem of a real symmetric 2x2 matrix + // [ A B ] + // [ B C ] + // in the form + // [ A B ] = [ cs -sn ] [ rt1 0 ] [ cs sn ] + // [ B C ] [ sn cs ] [ 0 rt2 ] [ -sn cs ] + // where rt1 >= rt2. + // + // Adapted from: https://www.mpi-hd.mpg.de/personalhomes/globes/3x3/index.html + // -> Algorithms for real symmetric matrices -> Analytical (2x2 symmetric) + function eigenDecomposition( A, B, C ) { + + let rt1, rt2, cs, sn, t; + const sm = A + C; + const df = A - C; + const rt = Math.sqrt( df * df + 4 * B * B ); + if ( sm > 0 ) { + + rt1 = 0.5 * ( sm + rt ); + t = 1 / rt1; + rt2 = A * t * C - B * t * B; + + } else if ( sm < 0 ) { + + rt2 = 0.5 * ( sm - rt ); + + } else { + + // This case needs to be treated separately to avoid div by 0 + rt1 = 0.5 * rt; + rt2 = - 0.5 * rt; + + } + + // Calculate eigenvectors + + if ( df > 0 ) { + + cs = df + rt; + + } else { + + cs = df - rt; + + } + + if ( Math.abs( cs ) > 2 * Math.abs( B ) ) { + + t = - 2 * B / cs; + sn = 1 / Math.sqrt( 1 + t * t ); + cs = t * sn; + + } else if ( Math.abs( B ) === 0 ) { + + cs = 1; + sn = 0; + + } else { + + t = - 0.5 * cs / B; + cs = 1 / Math.sqrt( 1 + t * t ); + sn = t * cs; + + } + + if ( df > 0 ) { + + t = cs; + cs = - sn; + sn = t; + + } + + return { + rt1, + rt2, + cs, + sn + }; + + } + + // const paths = []; const stylesheets = {}; @@ -1487,16 +1602,17 @@ const data = { paths: paths, xml: xml.documentElement - }; // console.log( paths ); + }; + // console.log( paths ); return data; } - static createShapes( shapePath ) { // Param shapePath: a shapepath as returned by the parse function of this class // Returns THREE.Shape object + const BIGNUMBER = 999999999; const IntersectionLocationType = { ORIGIN: 0, @@ -1511,7 +1627,6 @@ loc: IntersectionLocationType.ORIGIN, t: 0 }; - function findEdgeIntersection( a0, a1, b0, b1 ) { const x1 = a0.x; @@ -1527,20 +1642,21 @@ const denom = ( y4 - y3 ) * ( x2 - x1 ) - ( x4 - x3 ) * ( y2 - y1 ); const t1 = nom1 / denom; const t2 = nom2 / denom; - if ( denom === 0 && nom1 !== 0 || t1 <= 0 || t1 >= 1 || t2 < 0 || t2 > 1 ) { //1. lines are parallel or edges don't intersect + return null; } else if ( nom1 === 0 && denom === 0 ) { //2. lines are colinear + //check if endpoints of edge2 (b0-b1) lies on edge1 (a0-a1) for ( let i = 0; i < 2; i ++ ) { - classifyPoint( i === 0 ? b0 : b1, a0, a1 ); //find position of this endpoints relatively to edge1 - + classifyPoint( i === 0 ? b0 : b1, a0, a1 ); + //find position of this endpoints relatively to edge1 if ( classifyResult.loc == IntersectionLocationType.ORIGIN ) { const point = i === 0 ? b0 : b1; @@ -1569,10 +1685,10 @@ } else { //3. edges intersect + for ( let i = 0; i < 2; i ++ ) { classifyPoint( i === 0 ? b0 : b1, a0, a1 ); - if ( classifyResult.loc == IntersectionLocationType.ORIGIN ) { const point = i === 0 ? b0 : b1; @@ -1605,7 +1721,6 @@ const bx = p.x - edgeStart.x; const by = p.y - edgeStart.y; const sa = ax * by - bx * ay; - if ( p.x === edgeStart.x && p.y === edgeStart.y ) { classifyResult.loc = IntersectionLocationType.ORIGIN; @@ -1651,7 +1766,6 @@ } let t; - if ( ax !== 0 ) { t = bx / ax; @@ -1671,18 +1785,15 @@ const intersectionsRaw = []; const intersections = []; - for ( let index = 1; index < path1.length; index ++ ) { const path1EdgeStart = path1[ index - 1 ]; const path1EdgeEnd = path1[ index ]; - for ( let index2 = 1; index2 < path2.length; index2 ++ ) { const path2EdgeStart = path2[ index2 - 1 ]; const path2EdgeEnd = path2[ index2 ]; const intersection = findEdgeIntersection( path1EdgeStart, path1EdgeEnd, path2EdgeStart, path2EdgeEnd ); - if ( intersection !== null && intersectionsRaw.find( i => i.t <= intersection.t + Number.EPSILON && i.t >= intersection.t - Number.EPSILON ) === undefined ) { intersectionsRaw.push( intersection ); @@ -1765,11 +1876,11 @@ } } ); - const firstXOfPath = baseIntersections[ 0 ].point.x; // build up the path hierarchy + const firstXOfPath = baseIntersections[ 0 ].point.x; + // build up the path hierarchy const stack = []; let i = 0; - while ( i < otherIntersections.length && otherIntersections[ i ].point.x < firstXOfPath ) { if ( stack.length > 0 && stack[ stack.length - 1 ] === otherIntersections[ i ].identifier ) { @@ -1787,7 +1898,6 @@ } stack.push( simplePath.identifier ); - if ( _fillRule === 'evenodd' ) { const isHole = stack.length % 2 === 0 ? true : false; @@ -1804,11 +1914,9 @@ let isHole = true; let isHoleFor = null; let lastCWValue = null; - for ( let i = 0; i < stack.length; i ++ ) { const identifier = stack[ i ]; - if ( isHole ) { lastCWValue = allPaths[ identifier ].isCW; @@ -1836,13 +1944,15 @@ } - } // check for self intersecting paths + } + + // check for self intersecting paths // TODO + // check intersecting paths // TODO - // prepare paths for hole detection - + // prepare paths for hole detection let identifier = 0; let scanlineMinX = BIGNUMBER; let scanlineMaxX = - BIGNUMBER; @@ -1852,12 +1962,13 @@ let maxY = - BIGNUMBER; let minY = BIGNUMBER; let maxX = - BIGNUMBER; - let minX = BIGNUMBER; //points.forEach(p => p.y *= -1); + let minX = BIGNUMBER; + + //points.forEach(p => p.y *= -1); for ( let i = 0; i < points.length; i ++ ) { const p = points[ i ]; - if ( p.y > maxY ) { maxY = p.y; @@ -1882,9 +1993,9 @@ } - } // - + } + // if ( scanlineMaxX <= maxX ) { scanlineMaxX = maxX + 1; @@ -1906,14 +2017,14 @@ }; } ); - simplePaths = simplePaths.filter( sp => sp.points.length > 1 ); // check if path is solid or a hole + simplePaths = simplePaths.filter( sp => sp.points.length > 1 ); - const isAHole = simplePaths.map( p => isHoleTo( p, simplePaths, scanlineMinX, scanlineMaxX, shapePath.userData.style.fillRule ) ); + // check if path is solid or a hole + const isAHole = simplePaths.map( p => isHoleTo( p, simplePaths, scanlineMinX, scanlineMaxX, shapePath.userData?.style.fillRule ) ); const shapesToReturn = []; simplePaths.forEach( p => { const amIAHole = isAHole[ p.identifier ]; - if ( ! amIAHole.isHole ) { const shape = new THREE.Shape(); @@ -1935,7 +2046,6 @@ return shapesToReturn; } - static getStrokeStyle( width, color, lineJoin, lineCap, miterLimit ) { // Param width: Stroke width @@ -1944,6 +2054,7 @@ // Param lineCap: One of "round", "square" or "butt" // Param miterLimit: Maximum join length, in multiples of the "width" parameter (join is truncated if it exceeds that distance) // Returns style object + width = width !== undefined ? width : 1; color = color !== undefined ? color : '#000'; lineJoin = lineJoin !== undefined ? lineJoin : 'miter'; @@ -1958,7 +2069,6 @@ }; } - static pointsToStroke( points, style, arcDivisions, minDistance ) { // Generates a stroke with some witdh around the given path. @@ -1968,10 +2078,10 @@ // Params arcDivisions: Arc divisions for round joins and endcaps. (Optional) // Param minDistance: Points closer to this distance will be merged. (Optional) // Returns THREE.BufferGeometry with stroke triangles (In plane z = 0). UV coordinates are generated ('u' along path. 'v' across it, from left to right) + const vertices = []; const normals = []; const uvs = []; - if ( SVGLoader.pointsToStrokeWithBuffers( points, style, arcDivisions, minDistance, vertices, normals, uvs ) === 0 ) { return null; @@ -1985,7 +2095,6 @@ return geometry; } - static pointsToStrokeWithBuffers( points, style, arcDivisions, minDistance, vertices, normals, uvs, vertexOffset ) { // This function can be called to update existing arrays or buffers. @@ -1994,6 +2103,7 @@ // Returns number of written vertices / normals / uvs pairs // if 'vertices' parameter is undefined no triangles will be generated, but the returned vertices count will still be valid (useful to preallocate the buffers) // 'normals' and 'uvs' buffers are optional + const tempV2_1 = new THREE.Vector2(); const tempV2_2 = new THREE.Vector2(); const tempV2_3 = new THREE.Vector2(); @@ -2013,8 +2123,9 @@ const outerPoint = new THREE.Vector2(); arcDivisions = arcDivisions !== undefined ? arcDivisions : 12; minDistance = minDistance !== undefined ? minDistance : 0.001; - vertexOffset = vertexOffset !== undefined ? vertexOffset : 0; // First ensure there are no duplicated points + vertexOffset = vertexOffset !== undefined ? vertexOffset : 0; + // First ensure there are no duplicated points points = removeDuplicatedPoints( points ); const numPoints = points.length; if ( numPoints < 2 ) return 0; @@ -2032,18 +2143,19 @@ let initialJoinIsOnLeftSide = false; let numVertices = 0; let currentCoordinate = vertexOffset * 3; - let currentCoordinateUV = vertexOffset * 2; // Get initial left and right stroke points + let currentCoordinateUV = vertexOffset * 2; + // Get initial left and right stroke points getNormal( points[ 0 ], points[ 1 ], tempV2_1 ).multiplyScalar( strokeWidth2 ); lastPointL.copy( points[ 0 ] ).sub( tempV2_1 ); lastPointR.copy( points[ 0 ] ).add( tempV2_1 ); point0L.copy( lastPointL ); point0R.copy( lastPointR ); - for ( let iPoint = 1; iPoint < numPoints; iPoint ++ ) { - currentPoint = points[ iPoint ]; // Get next point + currentPoint = points[ iPoint ]; + // Get next point if ( iPoint === numPoints - 1 ) { if ( isClosed ) { @@ -2057,9 +2169,9 @@ nextPoint = points[ iPoint + 1 ]; - } // Normal of previous segment in tempV2_1 - + } + // Normal of previous segment in tempV2_1 const normal1 = tempV2_1; getNormal( previousPoint, currentPoint, normal1 ); tempV2_3.copy( normal1 ).multiplyScalar( strokeWidth2 ); @@ -2067,7 +2179,6 @@ currentPointR.copy( currentPoint ).add( tempV2_3 ); u1 = u0 + deltaU; innerSideModified = false; - if ( nextPoint !== undefined ) { // Normal of next segment in tempV2_2 @@ -2077,7 +2188,6 @@ nextPointR.copy( currentPoint ).add( tempV2_3 ); joinIsOnLeftSide = true; tempV2_3.subVectors( nextPoint, previousPoint ); - if ( normal1.dot( tempV2_3 ) < 0 ) { joinIsOnLeftSide = false; @@ -2087,8 +2197,9 @@ if ( iPoint === 1 ) initialJoinIsOnLeftSide = joinIsOnLeftSide; tempV2_3.subVectors( nextPoint, currentPoint ); tempV2_3.normalize(); - const dot = Math.abs( normal1.dot( tempV2_3 ) ); // If path is straight, don't create join + const dot = Math.abs( normal1.dot( tempV2_3 ) ); + // If path is straight, don't create join if ( dot > Number.EPSILON ) { // Compute inner and outer segment intersections @@ -2102,8 +2213,8 @@ tempV2_4.divideScalar( segmentLengthPrev ); tempV2_6.subVectors( nextPoint, currentPoint ); const segmentLengthNext = tempV2_6.length(); - tempV2_6.divideScalar( segmentLengthNext ); // Check that previous and next segments doesn't overlap with the innerPoint of intersection - + tempV2_6.divideScalar( segmentLengthNext ); + // Check that previous and next segments doesn't overlap with the innerPoint of intersection if ( tempV2_4.dot( innerPoint ) < segmentLengthPrev && tempV2_6.dot( innerPoint ) < segmentLengthNext ) { innerSideModified = true; @@ -2113,7 +2224,6 @@ outerPoint.copy( tempV2_5 ).add( currentPoint ); innerPoint.add( currentPoint ); isMiter = false; - if ( innerSideModified ) { if ( joinIsOnLeftSide ) { @@ -2131,6 +2241,7 @@ } else { // The segment triangles are generated here if there was overlapping + makeSegmentTriangles(); } @@ -2140,10 +2251,12 @@ case 'bevel': makeSegmentWithBevelJoin( joinIsOnLeftSide, innerSideModified, u1 ); break; - case 'round': // Segment triangles - createSegmentTrianglesWithMiddleSection( joinIsOnLeftSide, innerSideModified ); // Join triangles + + createSegmentTrianglesWithMiddleSection( joinIsOnLeftSide, innerSideModified ); + + // Join triangles if ( joinIsOnLeftSide ) { @@ -2156,15 +2269,14 @@ } break; - case 'miter': case 'miter-clip': default: const miterFraction = strokeWidth2 * style.strokeMiterLimit / miterLength2; - if ( miterFraction < 1 ) { // The join miter length exceeds the miter limit + if ( style.strokeLineJoin !== 'miter-clip' ) { makeSegmentWithBevelJoin( joinIsOnLeftSide, innerSideModified, u1 ); @@ -2173,7 +2285,10 @@ } else { // Segment triangles - createSegmentTrianglesWithMiddleSection( joinIsOnLeftSide, innerSideModified ); // Miter-clip join triangles + + createSegmentTrianglesWithMiddleSection( joinIsOnLeftSide, innerSideModified ); + + // Miter-clip join triangles if ( joinIsOnLeftSide ) { @@ -2210,9 +2325,11 @@ } else { // Miter join segment triangles + if ( innerSideModified ) { // Optimized segment + join triangles + if ( joinIsOnLeftSide ) { addVertex( lastPointR, u0, 1 ); @@ -2246,6 +2363,7 @@ } else { // Add extra miter join triangles + if ( joinIsOnLeftSide ) { addVertex( currentPointL, u1, 0 ); @@ -2279,6 +2397,7 @@ } else { // The segment triangles are generated here when two consecutive points are collinear + makeSegmentTriangles(); } @@ -2286,6 +2405,7 @@ } else { // The segment triangles are generated here if it is the ending segment + makeSegmentTriangles(); } @@ -2295,8 +2415,9 @@ // Start line endcap addCapGeometry( points[ 0 ], point0L, point0R, joinIsOnLeftSide, true, u0 ); - } // Increment loop variables + } + // Increment loop variables u0 = u1; previousPoint = currentPoint; @@ -2313,9 +2434,9 @@ } else if ( innerSideModified && vertices ) { // Modify path first segment vertices to adjust to the segments inner and outer intersections + let lastOuter = outerPoint; let lastInner = innerPoint; - if ( initialJoinIsOnLeftSide !== joinIsOnLeftSide ) { lastOuter = innerPoint; @@ -2329,7 +2450,6 @@ lastInner.toArray( vertices, 0 * 3 ); lastInner.toArray( vertices, 3 * 3 ); - if ( isMiter ) { lastOuter.toArray( vertices, 1 * 3 ); @@ -2344,7 +2464,6 @@ lastInner.toArray( vertices, 1 * 3 ); lastInner.toArray( vertices, 3 * 3 ); - if ( isMiter ) { lastOuter.toArray( vertices, 0 * 3 ); @@ -2357,7 +2476,10 @@ } - return numVertices; // -- End of algorithm + return numVertices; + + // -- End of algorithm + // -- Functions function getNormal( p1, p2, result ) { @@ -2374,7 +2496,6 @@ vertices[ currentCoordinate ] = position.x; vertices[ currentCoordinate + 1 ] = position.y; vertices[ currentCoordinate + 2 ] = 0; - if ( normals ) { normals[ currentCoordinate ] = 0; @@ -2384,7 +2505,6 @@ } currentCoordinate += 3; - if ( uvs ) { uvs[ currentCoordinateUV ] = u; @@ -2403,6 +2523,7 @@ // param p1, p2: Points in the circle arc. // p1 and p2 are in clockwise direction. + tempV2_1.copy( p1 ).sub( center ).normalize(); tempV2_2.copy( p2 ).sub( center ).normalize(); let angle = Math.PI; @@ -2410,7 +2531,6 @@ if ( Math.abs( dot ) < 1 ) angle = Math.abs( Math.acos( dot ) ); angle /= arcDivisions; tempV2_3.copy( p1 ); - for ( let i = 0, il = arcDivisions - 1; i < il; i ++ ) { tempV2_4.copy( tempV2_3 ).rotateAround( center, angle ); @@ -2443,15 +2563,19 @@ if ( innerSideModified ) { // Optimized segment + bevel triangles + if ( joinIsOnLeftSide ) { // THREE.Path segments triangles + addVertex( lastPointR, u0, 1 ); addVertex( lastPointL, u0, 0 ); addVertex( currentPointL, u1, 0 ); addVertex( lastPointR, u0, 1 ); addVertex( currentPointL, u1, 0 ); - addVertex( innerPoint, u1, 1 ); // Bevel join triangle + addVertex( innerPoint, u1, 1 ); + + // Bevel join triangle addVertex( currentPointL, u, 0 ); addVertex( nextPointL, u, 0 ); @@ -2460,12 +2584,15 @@ } else { // THREE.Path segments triangles + addVertex( lastPointR, u0, 1 ); addVertex( lastPointL, u0, 0 ); addVertex( currentPointR, u1, 1 ); addVertex( lastPointL, u0, 0 ); addVertex( innerPoint, u1, 0 ); - addVertex( currentPointR, u1, 1 ); // Bevel join triangle + addVertex( currentPointR, u1, 1 ); + + // Bevel join triangle addVertex( currentPointR, u, 1 ); addVertex( nextPointR, u, 0 ); @@ -2476,6 +2603,7 @@ } else { // Bevel join triangle. The segment triangles are done in the main loop + if ( joinIsOnLeftSide ) { addVertex( currentPointL, u, 0 ); @@ -2538,6 +2666,7 @@ // param center: End point of the path // param p1, p2: Left and right cap points + switch ( style.strokeLineCap ) { case 'round': @@ -2552,15 +2681,15 @@ } break; - case 'square': if ( start ) { tempV2_1.subVectors( p1, center ); tempV2_2.set( tempV2_1.y, - tempV2_1.x ); tempV2_3.addVectors( tempV2_1, tempV2_2 ).add( center ); - tempV2_4.subVectors( tempV2_2, tempV2_1 ).add( center ); // Modify already existing vertices + tempV2_4.subVectors( tempV2_2, tempV2_1 ).add( center ); + // Modify already existing vertices if ( joinIsOnLeftSide ) { tempV2_3.toArray( vertices, 1 * 3 ); @@ -2581,8 +2710,9 @@ tempV2_2.set( tempV2_1.y, - tempV2_1.x ); tempV2_3.addVectors( tempV2_1, tempV2_2 ).add( center ); tempV2_4.subVectors( tempV2_2, tempV2_1 ).add( center ); - const vl = vertices.length; // Modify already existing vertices + const vl = vertices.length; + // Modify already existing vertices if ( joinIsOnLeftSide ) { tempV2_3.toArray( vertices, vl - 1 * 3 ); @@ -2600,7 +2730,6 @@ } break; - case 'butt': default: // Nothing to do here @@ -2614,8 +2743,8 @@ // Creates a new array if necessary with duplicated points removed. // This does not remove duplicated initial and ending points of a closed path. - let dupPoints = false; + let dupPoints = false; for ( let i = 1, n = points.length - 1; i < n; i ++ ) { if ( points[ i ].distanceTo( points[ i + 1 ] ) < minDistance ) { @@ -2630,7 +2759,6 @@ if ( ! dupPoints ) return points; const newPoints = []; newPoints.push( points[ 0 ] ); - for ( let i = 1, n = points.length - 1; i < n; i ++ ) { if ( points[ i ].distanceTo( points[ i + 1 ] ) >= minDistance ) { diff --git a/examples/js/loaders/TDSLoader.js b/examples/js/loaders/TDSLoader.js index d935a35a92219b..5d26e6bd8f2b61 100644 --- a/examples/js/loaders/TDSLoader.js +++ b/examples/js/loaders/TDSLoader.js @@ -20,6 +20,7 @@ this.meshes = []; } + /** * Load 3ds file from url. * @@ -29,8 +30,6 @@ * @param {Function} onProgress onProgress callback. * @param {Function} onError onError callback. */ - - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -65,6 +64,7 @@ }, onProgress, onError ); } + /** * Parse arraybuffer data and load 3ds file. * @@ -73,15 +73,12 @@ * @param {String} path Path for external resources. * @return {Group} THREE.Group loaded from 3ds file. */ - - parse( arraybuffer, path ) { this.group = new THREE.Group(); this.materials = []; this.meshes = []; this.readFile( arraybuffer, path ); - for ( let i = 0; i < this.meshes.length; i ++ ) { this.group.add( this.meshes[ i ] ); @@ -91,6 +88,7 @@ return this.group; } + /** * Decode file content to read 3ds data. * @@ -98,17 +96,13 @@ * @param {ArrayBuffer} arraybuffer Arraybuffer data to be loaded. * @param {String} path Path for external resources. */ - - readFile( arraybuffer, path ) { const data = new DataView( arraybuffer ); const chunk = new Chunk( data, 0, this.debugMessage ); - if ( chunk.id === MLIBMAGIC || chunk.id === CMAGIC || chunk.id === M3DMAGIC ) { let next = chunk.readChunk(); - while ( next ) { if ( next.id === M3D_VERSION ) { @@ -135,6 +129,7 @@ this.debugMessage( 'Parsed ' + this.meshes.length + ' meshes' ); } + /** * Read mesh data chunk. * @@ -142,12 +137,9 @@ * @param {Chunk} chunk to read mesh from * @param {String} path Path for external resources. */ - - readMeshData( chunk, path ) { let next = chunk.readChunk(); - while ( next ) { if ( next.id === MESH_VERSION ) { @@ -182,19 +174,17 @@ } } + /** * Read named object chunk. * * @method readNamedObject * @param {Chunk} chunk Chunk in use. */ - - readNamedObject( chunk ) { const name = chunk.readString(); let next = chunk.readChunk(); - while ( next ) { if ( next.id === N_TRI_OBJECT ) { @@ -214,6 +204,7 @@ } } + /** * Read material data chunk and add it to the material list. * @@ -221,13 +212,10 @@ * @param {Chunk} chunk Chunk in use. * @param {String} path Path for external resources. */ - - readMaterialEntry( chunk, path ) { let next = chunk.readChunk(); const material = new THREE.MeshPhongMaterial(); - while ( next ) { if ( next.id === MAT_NAME ) { @@ -317,6 +305,7 @@ this.materials[ material.name ] = material; } + /** * Read mesh data chunk. * @@ -324,8 +313,6 @@ * @param {Chunk} chunk Chunk in use. * @return {Mesh} The parsed mesh. */ - - readMesh( chunk ) { let next = chunk.readChunk(); @@ -333,16 +320,16 @@ const material = new THREE.MeshPhongMaterial(); const mesh = new THREE.Mesh( geometry, material ); mesh.name = 'mesh'; - while ( next ) { if ( next.id === POINT_ARRAY ) { const points = next.readWord(); - this.debugMessage( ' Vertex: ' + points ); //BufferGeometry + this.debugMessage( ' Vertex: ' + points ); - const vertices = []; + //BufferGeometry + const vertices = []; for ( let i = 0; i < points; i ++ ) { vertices.push( next.readFloat() ); @@ -360,10 +347,11 @@ } else if ( next.id === TEX_VERTS ) { const texels = next.readWord(); - this.debugMessage( ' UV: ' + texels ); //BufferGeometry + this.debugMessage( ' UV: ' + texels ); - const uvs = []; + //BufferGeometry + const uvs = []; for ( let i = 0; i < texels; i ++ ) { uvs.push( next.readFloat() ); @@ -377,30 +365,33 @@ this.debugMessage( ' Tranformation Matrix (TODO)' ); const values = []; - for ( let i = 0; i < 12; i ++ ) { values[ i ] = next.readFloat(); } - const matrix = new THREE.Matrix4(); //X Line + const matrix = new THREE.Matrix4(); + //X Line matrix.elements[ 0 ] = values[ 0 ]; matrix.elements[ 1 ] = values[ 6 ]; matrix.elements[ 2 ] = values[ 3 ]; - matrix.elements[ 3 ] = values[ 9 ]; //Y Line + matrix.elements[ 3 ] = values[ 9 ]; + //Y Line matrix.elements[ 4 ] = values[ 2 ]; matrix.elements[ 5 ] = values[ 8 ]; matrix.elements[ 6 ] = values[ 5 ]; - matrix.elements[ 7 ] = values[ 11 ]; //Z Line + matrix.elements[ 7 ] = values[ 11 ]; + //Z Line matrix.elements[ 8 ] = values[ 1 ]; matrix.elements[ 9 ] = values[ 7 ]; matrix.elements[ 10 ] = values[ 4 ]; - matrix.elements[ 11 ] = values[ 10 ]; //W Line + matrix.elements[ 11 ] = values[ 10 ]; + //W Line matrix.elements[ 12 ] = 0; matrix.elements[ 13 ] = 0; matrix.elements[ 14 ] = 0; @@ -425,6 +416,7 @@ return mesh; } + /** * Read face array data chunk. * @@ -432,14 +424,11 @@ * @param {Chunk} chunk Chunk in use. * @param {Mesh} mesh THREE.Mesh to be filled with the data read. */ - - readFaceArray( chunk, mesh ) { const faces = chunk.readWord(); this.debugMessage( ' Faces: ' + faces ); const index = []; - for ( let i = 0; i < faces; ++ i ) { index.push( chunk.readWord(), chunk.readWord(), chunk.readWord() ); @@ -447,15 +436,15 @@ } - mesh.geometry.setIndex( index ); //The rest of the FACE_ARRAY chunk is subchunks + mesh.geometry.setIndex( index ); + + //The rest of the FACE_ARRAY chunk is subchunks let materialIndex = 0; let start = 0; - while ( ! chunk.endOfChunk ) { const subchunk = chunk.readChunk(); - if ( subchunk.id === MSH_MAT_GROUP ) { this.debugMessage( ' Material THREE.Group' ); @@ -467,7 +456,6 @@ materialIndex ++; const material = this.materials[ group.name ]; if ( Array.isArray( mesh.material ) === false ) mesh.material = []; - if ( material !== undefined ) { mesh.material.push( material ); @@ -485,6 +473,7 @@ if ( mesh.material.length === 1 ) mesh.material = mesh.material[ 0 ]; // for backwards compatibility } + /** * Read texture map data chunk. * @@ -493,15 +482,12 @@ * @param {String} path Path for external resources. * @return {Texture} Texture read from this data chunk. */ - - readMap( chunk, path ) { let next = chunk.readChunk(); let texture = {}; const loader = new THREE.TextureLoader( this.manager ); loader.setPath( this.resourcePath || path ).setCrossOrigin( this.crossOrigin ); - while ( next ) { if ( next.id === MAT_MAPNAME ) { @@ -543,6 +529,7 @@ return texture; } + /** * Read material group data chunk. * @@ -550,8 +537,6 @@ * @param {Chunk} chunk Chunk in use. * @return {Object} Object with name and index of the object. */ - - readMaterialGroup( chunk ) { const name = chunk.readString(); @@ -559,7 +544,6 @@ this.debugMessage( ' Name: ' + name ); this.debugMessage( ' Faces: ' + numFaces ); const index = []; - for ( let i = 0; i < numFaces; ++ i ) { index.push( chunk.readWord() ); @@ -572,6 +556,7 @@ }; } + /** * Read a color value. * @@ -579,13 +564,10 @@ * @param {Chunk} chunk Chunk. * @return {Color} THREE.Color value read.. */ - - readColor( chunk ) { const subChunk = chunk.readChunk(); const color = new THREE.Color(); - if ( subChunk.id === COLOR_24 || subChunk.id === LIN_COLOR_24 ) { const r = subChunk.readByte(); @@ -611,6 +593,7 @@ return color; } + /** * Read percentage value. * @@ -618,22 +601,17 @@ * @param {Chunk} chunk Chunk to read data from. * @return {Number} Data read from the dataview. */ - - readPercentage( chunk ) { const subChunk = chunk.readChunk(); - switch ( subChunk.id ) { case INT_PERCENTAGE: return subChunk.readShort() / 100; break; - case FLOAT_PERCENTAGE: return subChunk.readFloat(); break; - default: this.debugMessage( ' Unknown percentage chunk: ' + subChunk.hexId ); return 0; @@ -641,6 +619,7 @@ } } + /** * Print debug message to the console. * @@ -649,8 +628,6 @@ * @method debugMessage * @param {Object} message Debug message to print to the console. */ - - debugMessage( message ) { if ( this.debug ) { @@ -662,9 +639,8 @@ } } - /** Read data/sub-chunks from chunk */ - + /** Read data/sub-chunks from chunk */ class Chunk { /** @@ -677,13 +653,12 @@ */ constructor( data, position, debugMessage ) { - this.data = data; // the offset to the begin of this chunk - - this.offset = position; // the current reading position - + this.data = data; + // the offset to the begin of this chunk + this.offset = position; + // the current reading position this.position = position; this.debugMessage = debugMessage; - if ( this.debugMessage instanceof Function ) { this.debugMessage = function () {}; @@ -693,7 +668,6 @@ this.id = this.readWord(); this.size = this.readDWord(); this.end = this.offset + this.size; - if ( this.end > data.byteLength ) { this.debugMessage( 'Bad chunk size for chunk at ' + position ); @@ -701,14 +675,13 @@ } } + /** * read a sub cchunk. * * @method readChunk * @return {Chunk | null} next sub chunk */ - - readChunk() { if ( this.endOfChunk ) { @@ -731,33 +704,30 @@ } } + /** * return the ID of this chunk as Hex * * @method idToString * @return {String} hex-string of id */ - - get hexId() { return this.id.toString( 16 ); } - get endOfChunk() { return this.position >= this.end; } + /** * Read byte value. * * @method readByte * @return {Number} Data read from the dataview. */ - - readByte() { const v = this.data.getUint8( this.position, true ); @@ -765,14 +735,13 @@ return v; } + /** * Read 32 bit float value. * * @method readFloat * @return {Number} Data read from the dataview. */ - - readFloat() { try { @@ -789,14 +758,13 @@ } } + /** * Read 32 bit signed integer value. * * @method readInt * @return {Number} Data read from the dataview. */ - - readInt() { const v = this.data.getInt32( this.position, true ); @@ -804,14 +772,13 @@ return v; } + /** * Read 16 bit signed integer value. * * @method readShort * @return {Number} Data read from the dataview. */ - - readShort() { const v = this.data.getInt16( this.position, true ); @@ -819,14 +786,13 @@ return v; } + /** * Read 64 bit unsigned integer value. * * @method readDWord * @return {Number} Data read from the dataview. */ - - readDWord() { const v = this.data.getUint32( this.position, true ); @@ -834,14 +800,13 @@ return v; } + /** * Read 32 bit unsigned integer value. * * @method readWord * @return {Number} Data read from the dataview. */ - - readWord() { const v = this.data.getUint16( this.position, true ); @@ -849,19 +814,17 @@ return v; } + /** * Read NULL terminated ASCII string value from chunk-pos. * * @method readString * @return {String} Data read from the dataview. */ - - readString() { let s = ''; let c = this.readByte(); - while ( c ) { s += String.fromCharCode( c ); @@ -873,17 +836,17 @@ } - } // const NULL_CHUNK = 0x0000; - + } - const M3DMAGIC = 0x4D4D; // const SMAGIC = 0x2D2D; + // const NULL_CHUNK = 0x0000; + const M3DMAGIC = 0x4D4D; + // const SMAGIC = 0x2D2D; // const LMAGIC = 0x2D3D; - - const MLIBMAGIC = 0x3DAA; // const MATMAGIC = 0x3DFF; - + const MLIBMAGIC = 0x3DAA; + // const MATMAGIC = 0x3DFF; const CMAGIC = 0xC23D; - const M3D_VERSION = 0x0002; // const M3D_KFVERSION = 0x0005; - + const M3D_VERSION = 0x0002; + // const M3D_KFVERSION = 0x0005; const COLOR_F = 0x0010; const COLOR_24 = 0x0011; const LIN_COLOR_24 = 0x0012; @@ -892,7 +855,8 @@ const FLOAT_PERCENTAGE = 0x0031; const MDATA = 0x3D3D; const MESH_VERSION = 0x3D3E; - const MASTER_SCALE = 0x0100; // const LO_SHADOW_BIAS = 0x1400; + const MASTER_SCALE = 0x0100; + // const LO_SHADOW_BIAS = 0x1400; // const HI_SHADOW_BIAS = 0x1410; // const SHADOW_MAP_SIZE = 0x1420; // const SHADOW_SAMPLES = 0x1430; @@ -915,47 +879,47 @@ // const USE_FOG = 0x2201; // const USE_LAYER_FOG = 0x2303; // const USE_DISTANCE_CUE = 0x2301; - const MAT_ENTRY = 0xAFFF; const MAT_NAME = 0xA000; const MAT_AMBIENT = 0xA010; const MAT_DIFFUSE = 0xA020; const MAT_SPECULAR = 0xA030; - const MAT_SHININESS = 0xA040; // const MAT_SHIN2PCT = 0xA041; - - const MAT_TRANSPARENCY = 0xA050; // const MAT_XPFALL = 0xA052; + const MAT_SHININESS = 0xA040; + // const MAT_SHIN2PCT = 0xA041; + const MAT_TRANSPARENCY = 0xA050; + // const MAT_XPFALL = 0xA052; // const MAT_USE_XPFALL = 0xA240; // const MAT_REFBLUR = 0xA053; // const MAT_SHADING = 0xA100; // const MAT_USE_REFBLUR = 0xA250; // const MAT_SELF_ILLUM = 0xA084; - - const MAT_TWO_SIDE = 0xA081; // const MAT_DECAL = 0xA082; - + const MAT_TWO_SIDE = 0xA081; + // const MAT_DECAL = 0xA082; const MAT_ADDITIVE = 0xA083; - const MAT_WIRE = 0xA085; // const MAT_FACEMAP = 0xA088; + const MAT_WIRE = 0xA085; + // const MAT_FACEMAP = 0xA088; // const MAT_TRANSFALLOFF_IN = 0xA08A; // const MAT_PHONGSOFT = 0xA08C; // const MAT_WIREABS = 0xA08E; - const MAT_WIRE_SIZE = 0xA087; - const MAT_TEXMAP = 0xA200; // const MAT_SXP_TEXT_DATA = 0xA320; + const MAT_TEXMAP = 0xA200; + // const MAT_SXP_TEXT_DATA = 0xA320; // const MAT_TEXMASK = 0xA33E; // const MAT_SXP_TEXTMASK_DATA = 0xA32A; // const MAT_TEX2MAP = 0xA33A; // const MAT_SXP_TEXT2_DATA = 0xA321; // const MAT_TEX2MASK = 0xA340; // const MAT_SXP_TEXT2MASK_DATA = 0xA32C; - - const MAT_OPACMAP = 0xA210; // const MAT_SXP_OPAC_DATA = 0xA322; + const MAT_OPACMAP = 0xA210; + // const MAT_SXP_OPAC_DATA = 0xA322; // const MAT_OPACMASK = 0xA342; // const MAT_SXP_OPACMASK_DATA = 0xA32E; - - const MAT_BUMPMAP = 0xA230; // const MAT_SXP_BUMP_DATA = 0xA324; + const MAT_BUMPMAP = 0xA230; + // const MAT_SXP_BUMP_DATA = 0xA324; // const MAT_BUMPMASK = 0xA344; // const MAT_SXP_BUMPMASK_DATA = 0xA330; - - const MAT_SPECMAP = 0xA204; // const MAT_SXP_SPEC_DATA = 0xA325; + const MAT_SPECMAP = 0xA204; + // const MAT_SXP_SPEC_DATA = 0xA325; // const MAT_SPECMASK = 0xA348; // const MAT_SXP_SPECMASK_DATA = 0xA332; // const MAT_SHINMAP = 0xA33C; @@ -970,21 +934,21 @@ // const MAT_REFLMASK = 0xA34C; // const MAT_SXP_REFLMASK_DATA = 0xA338; // const MAT_ACUBIC = 0xA310; - - const MAT_MAPNAME = 0xA300; // const MAT_MAP_TILING = 0xA351; + const MAT_MAPNAME = 0xA300; + // const MAT_MAP_TILING = 0xA351; // const MAT_MAP_TEXBLUR = 0xA353; - const MAT_MAP_USCALE = 0xA354; const MAT_MAP_VSCALE = 0xA356; const MAT_MAP_UOFFSET = 0xA358; - const MAT_MAP_VOFFSET = 0xA35A; // const MAT_MAP_ANG = 0xA35C; + const MAT_MAP_VOFFSET = 0xA35A; + // const MAT_MAP_ANG = 0xA35C; // const MAT_MAP_COL1 = 0xA360; // const MAT_MAP_COL2 = 0xA362; // const MAT_MAP_RCOL = 0xA364; // const MAT_MAP_GCOL = 0xA366; // const MAT_MAP_BCOL = 0xA368; - - const NAMED_OBJECT = 0x4000; // const N_DIRECT_LIGHT = 0x4600; + const NAMED_OBJECT = 0x4000; + // const N_DIRECT_LIGHT = 0x4600; // const DL_OFF = 0x4620; // const DL_OUTER_RANGE = 0x465A; // const DL_INNER_RANGE = 0x4659; @@ -1013,16 +977,15 @@ // const OBJ_FAST = 0x4014; // const OBJ_PROCEDURAL = 0x4015; // const OBJ_FROZEN = 0x4016; - const N_TRI_OBJECT = 0x4100; - const POINT_ARRAY = 0x4110; // const POINT_FLAG_ARRAY = 0x4111; - + const POINT_ARRAY = 0x4110; + // const POINT_FLAG_ARRAY = 0x4111; const FACE_ARRAY = 0x4120; - const MSH_MAT_GROUP = 0x4130; // const SMOOTH_GROUP = 0x4150; + const MSH_MAT_GROUP = 0x4130; + // const SMOOTH_GROUP = 0x4150; // const MSH_BOXMAP = 0x4190; - const TEX_VERTS = 0x4140; - const MESH_MATRIX = 0x4160; // const MESH_COLOR = 0x4165; + const MESH_MATRIX = 0x4160; THREE.TDSLoader = TDSLoader; diff --git a/examples/js/loaders/TGALoader.js b/examples/js/loaders/TGALoader.js index 6977c49f526aff..d7ecd49843ab06 100644 --- a/examples/js/loaders/TGALoader.js +++ b/examples/js/loaders/TGALoader.js @@ -7,15 +7,16 @@ super( manager ); } - parse( buffer ) { // reference from vthibault, https://github.com/vthibault/roBrowser/blob/master/src/Loaders/Targa.js + function tgaCheckHeader( header ) { switch ( header.image_type ) { // check indexed type + case TGA_TYPE_INDEXED: case TGA_TYPE_RLE_INDEXED: if ( header.colormap_length > 256 || header.colormap_size !== 24 || header.colormap_type !== 1 ) { @@ -25,6 +26,7 @@ } break; + // check colormap type case TGA_TYPE_RGB: @@ -38,24 +40,28 @@ } break; + // What the need of a file without data ? case TGA_TYPE_NO_DATA: console.error( 'THREE.TGALoader: No data.' ); + // Invalid type ? default: console.error( 'THREE.TGALoader: Invalid type "%s".', header.image_type ); - } // check image width and height + } + // check image width and height if ( header.width <= 0 || header.height <= 0 ) { console.error( 'THREE.TGALoader: Invalid image size.' ); - } // check image pixel size + } + // check image pixel size if ( header.pixel_size !== 8 && header.pixel_size !== 16 && header.pixel_size !== 24 && header.pixel_size !== 32 ) { @@ -63,21 +69,25 @@ } - } // parse tga image buffer + } + // parse tga image buffer function tgaParse( use_rle, use_pal, header, offset, data ) { let pixel_data, palettes; const pixel_size = header.pixel_size >> 3; - const pixel_total = header.width * header.height * pixel_size; // read palettes + const pixel_total = header.width * header.height * pixel_size; + + // read palettes if ( use_pal ) { palettes = data.subarray( offset, offset += header.colormap_length * ( header.colormap_size >> 3 ) ); - } // read RLE + } + // read RLE if ( use_rle ) { @@ -85,21 +95,24 @@ let c, count, i; let shift = 0; const pixels = new Uint8Array( pixel_size ); - while ( shift < pixel_total ) { c = data[ offset ++ ]; - count = ( c & 0x7f ) + 1; // RLE pixels + count = ( c & 0x7f ) + 1; + + // RLE pixels if ( c & 0x80 ) { // bind pixel tmp array + for ( i = 0; i < pixel_size; ++ i ) { pixels[ i ] = data[ offset ++ ]; - } // copy pixel array + } + // copy pixel array for ( i = 0; i < count; ++ i ) { @@ -112,8 +125,8 @@ } else { // raw pixels - count *= pixel_size; + count *= pixel_size; for ( i = 0; i < count; ++ i ) { pixel_data[ shift + i ] = data[ offset ++ ]; @@ -129,6 +142,7 @@ } else { // raw pixels + pixel_data = data.subarray( offset, offset += use_pal ? header.width * header.height : pixel_total ); } @@ -148,7 +162,6 @@ x, y; const width = header.width; - for ( y = y_start; y !== y_end; y += y_step ) { for ( x = x_start; x !== x_end; x += x_step, i ++ ) { @@ -174,7 +187,6 @@ x, y; const width = header.width; - for ( y = y_start; y !== y_end; y += y_step ) { for ( x = x_start; x !== x_end; x += x_step, i += 2 ) { @@ -199,7 +211,6 @@ x, y; const width = header.width; - for ( y = y_start; y !== y_end; y += y_step ) { for ( x = x_start; x !== x_end; x += x_step, i += 3 ) { @@ -223,7 +234,6 @@ x, y; const width = header.width; - for ( y = y_start; y !== y_end; y += y_step ) { for ( x = x_start; x !== x_end; x += x_step, i += 4 ) { @@ -248,7 +258,6 @@ x, y; const width = header.width; - for ( y = y_start; y !== y_end; y += y_step ) { for ( x = x_start; x !== x_end; x += x_step, i ++ ) { @@ -273,7 +282,6 @@ x, y; const width = header.width; - for ( y = y_start; y !== y_end; y += y_step ) { for ( x = x_start; x !== x_end; x += x_step, i += 2 ) { @@ -294,7 +302,6 @@ function getTgaRGBA( data, width, height, image, palette ) { let x_start, y_start, x_step, y_step, x_end, y_end; - switch ( ( header.flags & TGA_ORIGIN_MASK ) >> TGA_ORIGIN_SHIFT ) { default: @@ -306,7 +313,6 @@ y_step = 1; y_end = height; break; - case TGA_ORIGIN_BL: x_start = 0; x_step = 1; @@ -315,7 +321,6 @@ y_step = - 1; y_end = - 1; break; - case TGA_ORIGIN_UR: x_start = width - 1; x_step = - 1; @@ -324,7 +329,6 @@ y_step = 1; y_end = height; break; - case TGA_ORIGIN_BR: x_start = width - 1; x_step = - 1; @@ -343,11 +347,9 @@ case 8: tgaGetImageDataGrey8bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image ); break; - case 16: tgaGetImageDataGrey16bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image ); break; - default: console.error( 'THREE.TGALoader: Format not supported.' ); break; @@ -361,34 +363,31 @@ case 8: tgaGetImageData8bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image, palette ); break; - case 16: tgaGetImageData16bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image ); break; - case 24: tgaGetImageData24bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image ); break; - case 32: tgaGetImageData32bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image ); break; - default: console.error( 'THREE.TGALoader: Format not supported.' ); break; } - } // Load image data according to specific method + } + + // Load image data according to specific method // let func = 'tgaGetImageData' + (use_grey ? 'Grey' : '') + (header.pixel_size) + 'bits'; // func(data, y_start, y_step, y_end, x_start, x_step, x_end, width, image, palette ); - - return data; - } // TGA constants + } + // TGA constants const TGA_TYPE_NO_DATA = 0, TGA_TYPE_INDEXED = 1, @@ -418,52 +417,51 @@ height: content[ offset ++ ] | content[ offset ++ ] << 8, pixel_size: content[ offset ++ ], flags: content[ offset ++ ] - }; // check tga if it is valid format + }; - tgaCheckHeader( header ); + // check tga if it is valid format + tgaCheckHeader( header ); if ( header.id_length + offset > buffer.length ) { console.error( 'THREE.TGALoader: No data.' ); - } // skip the needn't data + } + + // skip the needn't data + offset += header.id_length; - offset += header.id_length; // get targa information about RLE compression and palette + // get targa information about RLE compression and palette let use_rle = false, use_pal = false, use_grey = false; - switch ( header.image_type ) { case TGA_TYPE_RLE_INDEXED: use_rle = true; use_pal = true; break; - case TGA_TYPE_INDEXED: use_pal = true; break; - case TGA_TYPE_RLE_RGB: use_rle = true; break; - case TGA_TYPE_RGB: break; - case TGA_TYPE_RLE_GREY: use_rle = true; use_grey = true; break; - case TGA_TYPE_GREY: use_grey = true; break; - } // + } + // const imageData = new Uint8Array( header.width * header.height * 4 ); const result = tgaParse( use_rle, use_pal, header, offset, content ); diff --git a/examples/js/loaders/TIFFLoader.js b/examples/js/loaders/TIFFLoader.js new file mode 100644 index 00000000000000..2ad1eae0980054 --- /dev/null +++ b/examples/js/loaders/TIFFLoader.js @@ -0,0 +1,30 @@ +( function () { + + class TIFFLoader extends THREE.DataTextureLoader { + + constructor( manager ) { + + super( manager ); + + } + parse( buffer ) { + + const ifds = UTIF.decode( buffer ); + UTIF.decodeImage( buffer, ifds[ 0 ] ); + const rgba = UTIF.toRGBA8( ifds[ 0 ] ); + return { + width: ifds[ 0 ].width, + height: ifds[ 0 ].height, + data: rgba, + flipY: true, + magFilter: THREE.LinearFilter, + minFilter: THREE.LinearMipmapLinearFilter + }; + + } + + } + + THREE.TIFFLoader = TIFFLoader; + +} )(); diff --git a/examples/js/loaders/TTFLoader.js b/examples/js/loaders/TTFLoader.js index 18f4f1d2a0858d..2031bc468d9d34 100644 --- a/examples/js/loaders/TTFLoader.js +++ b/examples/js/loaders/TTFLoader.js @@ -14,7 +14,6 @@ this.reversed = false; } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -48,7 +47,6 @@ }, onProgress, onError ); } - parse( arraybuffer ) { function convert( font, reversed ) { @@ -58,12 +56,10 @@ const scale = 100000 / ( ( font.unitsPerEm || 2048 ) * 72 ); const glyphIndexMap = font.encoding.cmap.glyphIndexMap; const unicodes = Object.keys( glyphIndexMap ); - for ( let i = 0; i < unicodes.length; i ++ ) { const unicode = unicodes[ i ]; const glyph = font.glyphs.glyphs[ glyphIndexMap[ unicode ] ]; - if ( unicode !== undefined ) { const token = { @@ -72,7 +68,6 @@ x_max: round( glyph.xMax * scale ), o: '' }; - if ( reversed ) { glyph.path.commands = reverseCommands( glyph.path.commands ); @@ -88,7 +83,6 @@ } token.o += command.type.toLowerCase() + ' '; - if ( command.x !== undefined && command.y !== undefined ) { token.o += round( command.x * scale ) + ' ' + round( command.y * scale ) + ' '; @@ -160,14 +154,12 @@ y: p[ p.length - 1 ].y }; reversed.push( result ); - for ( let i = p.length - 1; i > 0; i -- ) { const command = p[ i ]; const result = { type: command.type }; - if ( command.x2 !== undefined && command.y2 !== undefined ) { result.x1 = command.x2; diff --git a/examples/js/loaders/TiltLoader.js b/examples/js/loaders/TiltLoader.js index b3190283d61ed0..332182d0dd8b0c 100644 --- a/examples/js/loaders/TiltLoader.js +++ b/examples/js/loaders/TiltLoader.js @@ -34,12 +34,13 @@ }, onProgress, onError ); } - parse( buffer ) { - const group = new THREE.Group(); // https://docs.google.com/document/d/11ZsHozYn9FnWG7y3s3WAyKIACfbfwb4PbaS8cZ_xjvo/edit# + const group = new THREE.Group(); + // https://docs.google.com/document/d/11ZsHozYn9FnWG7y3s3WAyKIACfbfwb4PbaS8cZ_xjvo/edit# const zip = fflate.unzipSync( new Uint8Array( buffer.slice( 16 ) ) ); + /* const thumbnail = zip[ 'thumbnail.png' ].buffer; const img = document.createElement( 'img' ); @@ -48,6 +49,7 @@ */ const metadata = JSON.parse( fflate.strFromU8( zip[ 'metadata.json' ] ) ); + /* const blob = new Blob( [ zip[ 'data.sketch' ].buffer ], { type: 'application/octet-stream' } ); window.open( URL.createObjectURL( blob ) ); @@ -57,7 +59,6 @@ const num_strokes = data.getInt32( 16, true ); const brushes = {}; let offset = 20; - for ( let i = 0; i < num_strokes; i ++ ) { const brush_index = data.getInt32( offset, true ); @@ -67,26 +68,28 @@ const controlpoint_mask = data.getUint32( offset + 28, true ); let offset_stroke_mask = 0; let offset_controlpoint_mask = 0; - for ( let j = 0; j < 4; j ++ ) { // TOFIX: I don't understand these masks yet + const byte = 1 << j; if ( ( stroke_mask & byte ) > 0 ) offset_stroke_mask += 4; if ( ( controlpoint_mask & byte ) > 0 ) offset_controlpoint_mask += 4; - } // console.log( { brush_index, brush_color, brush_size, stroke_mask, controlpoint_mask } ); - // console.log( offset_stroke_mask, offset_controlpoint_mask ); + } + // console.log( { brush_index, brush_color, brush_size, stroke_mask, controlpoint_mask } ); + // console.log( offset_stroke_mask, offset_controlpoint_mask ); offset = offset + 28 + offset_stroke_mask + 4; // TOFIX: This is wrong - const num_control_points = data.getInt32( offset, true ); // console.log( { num_control_points } ); + const num_control_points = data.getInt32( offset, true ); + + // console.log( { num_control_points } ); const positions = new Float32Array( num_control_points * 3 ); const quaternions = new Float32Array( num_control_points * 4 ); offset = offset + 4; - for ( let j = 0, k = 0; j < positions.length; j += 3, k += 4 ) { positions[ j + 0 ] = data.getFloat32( offset + 0, true ); @@ -123,7 +126,6 @@ } } - class StrokeGeometry extends THREE.BufferGeometry { constructor( strokes ) { @@ -139,7 +141,9 @@ const vector1 = new THREE.Vector3(); const vector2 = new THREE.Vector3(); const vector3 = new THREE.Vector3(); - const vector4 = new THREE.Vector3(); // size = size / 2; + const vector4 = new THREE.Vector3(); + + // size = size / 2; for ( const k in strokes ) { @@ -150,7 +154,6 @@ const color = stroke[ 3 ]; prevPosition.fromArray( positions, 0 ); prevQuaternion.fromArray( quaternions, 0 ); - for ( let i = 3, j = 4, l = positions.length; i < l; i += 3, j += 4 ) { position.fromArray( positions, i ); @@ -201,7 +204,6 @@ } } - const BRUSH_LIST_ARRAY = { '89d104cd-d012-426b-b5b3-bbaee63ac43c': 'Bubbles', '700f3aa8-9a7c-2384-8b8a-ea028905dd8c': 'CelVinyl', @@ -335,7 +337,6 @@ } }; let shaders = null; - function getShaders() { if ( shaders === null ) { @@ -439,12 +440,10 @@ function getMaterial( GUID ) { const name = BRUSH_LIST_ARRAY[ GUID ]; - switch ( name ) { case 'Light': return new THREE.RawShaderMaterial( getShaders().Light ); - default: return new THREE.MeshBasicMaterial( { vertexColors: true, diff --git a/examples/js/loaders/VOXLoader.js b/examples/js/loaders/VOXLoader.js index 0cba64fbbad39f..f8a168116b5b19 100644 --- a/examples/js/loaders/VOXLoader.js +++ b/examples/js/loaders/VOXLoader.js @@ -34,13 +34,11 @@ }, onProgress, onError ); } - parse( buffer ) { const data = new DataView( buffer ); const id = data.getUint32( 0, true ); const version = data.getUint32( 4, true ); - if ( id !== 542658390 || version !== 150 ) { console.error( 'Not a valid VOX file' ); @@ -52,11 +50,9 @@ let i = 8; let chunk; const chunks = []; - while ( i < data.byteLength ) { let id = ''; - for ( let j = 0; j < 4; j ++ ) { id += String.fromCharCode( data.getUint8( i ++ ) ); @@ -96,7 +92,6 @@ } else if ( id === 'RGBA' ) { const palette = [ 0 ]; - for ( let j = 0; j < 256; j ++ ) { palette[ j + 1 ] = data.getUint32( i, true ); @@ -109,6 +104,7 @@ } else { // console.log( id, chunkSize, childChunks ); + i += chunkSize; } @@ -120,14 +116,15 @@ } } - class VOXMesh extends THREE.Mesh { constructor( chunk ) { const data = chunk.data; const size = chunk.size; - const palette = chunk.palette; // + const palette = chunk.palette; + + // const vertices = []; const colors = []; @@ -137,13 +134,11 @@ const ny = [ 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0 ]; const nz = [ 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0 ]; const pz = [ 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1 ]; - function add( tile, x, y, z, r, g, b ) { x -= size.x / 2; y -= size.z / 2; z += size.y / 2; - for ( let i = 0; i < 18; i += 3 ) { vertices.push( tile[ i + 0 ] + x, tile[ i + 1 ] + y, tile[ i + 2 ] + z ); @@ -151,13 +146,13 @@ } - } // Store data in a volume for sampling + } + // Store data in a volume for sampling const offsety = size.x; const offsetz = size.x * size.y; const array = new Uint8Array( size.x * size.y * size.z ); - for ( let j = 0; j < data.length; j += 4 ) { const x = data[ j + 0 ]; @@ -166,11 +161,11 @@ const index = x + y * offsety + z * offsetz; array[ index ] = 255; - } // Construct geometry + } + // Construct geometry let hasColors = false; - for ( let j = 0; j < data.length; j += 4 ) { const x = data[ j + 0 ]; @@ -196,7 +191,6 @@ geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); geometry.computeVertexNormals(); const material = new THREE.MeshStandardMaterial(); - if ( hasColors ) { geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) ); @@ -209,7 +203,6 @@ } } - class VOXData3DTexture extends THREE.Data3DTexture { constructor( chunk ) { @@ -219,7 +212,6 @@ const offsety = size.x; const offsetz = size.x * size.y; const array = new Uint8Array( size.x * size.y * size.z ); - for ( let j = 0; j < data.length; j += 4 ) { const x = data[ j + 0 ]; diff --git a/examples/js/loaders/VRMLLoader.js b/examples/js/loaders/VRMLLoader.js index 9e4a5e6c449301..d041569a85bc61 100644 --- a/examples/js/loaders/VRMLLoader.js +++ b/examples/js/loaders/VRMLLoader.js @@ -4,17 +4,19 @@ constructor( manager ) { - super( manager ); // dependency check + super( manager ); + + // dependency check if ( typeof chevrotain === 'undefined' ) { // eslint-disable-line no-undef + throw Error( 'THREE.VRMLLoader: External library chevrotain.min.js required.' ); } } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -48,31 +50,34 @@ }, onProgress, onError ); } - parse( data, path ) { const nodeMap = {}; - function generateVRMLTree( data ) { // create lexer, parser and visitor + const tokenData = createTokens(); const lexer = new VRMLLexer( tokenData.tokens ); const parser = new VRMLParser( tokenData.tokenVocabulary ); - const visitor = createVisitor( parser.getBaseCstVisitorConstructor() ); // lexing + const visitor = createVisitor( parser.getBaseCstVisitorConstructor() ); + + // lexing const lexingResult = lexer.lex( data ); - parser.input = lexingResult.tokens; // parsing + parser.input = lexingResult.tokens; - const cstOutput = parser.vrml(); + // parsing + const cstOutput = parser.vrml(); if ( parser.errors.length > 0 ) { console.error( parser.errors ); throw Error( 'THREE.VRMLLoader: Parsing errors detected.' ); - } // actions + } + // actions const ast = visitor.visit( cstOutput ); return ast; @@ -82,6 +87,7 @@ function createTokens() { const createToken = chevrotain.createToken; // eslint-disable-line no-undef + // from http://gun.teipir.gr/VRML-amgem/spec/part1/concepts.html#SyntaxBasics const RouteIdentifier = createToken( { @@ -92,19 +98,32 @@ name: 'Identifier', pattern: /[^\x30-\x39\0-\x20\x22\x27\x23\x2b\x2c\x2d\x2e\x5b\x5d\x5c\x7b\x7d][^\0-\x20\x22\x27\x23\x2b\x2c\x2d\x2e\x5b\x5d\x5c\x7b\x7d]*/, longer_alt: RouteIdentifier - } ); // from http://gun.teipir.gr/VRML-amgem/spec/part1/nodesRef.html - - const nodeTypes = [ 'Anchor', 'Billboard', 'Collision', 'Group', 'Transform', // grouping nodes - 'Inline', 'LOD', 'Switch', // special groups - 'AudioClip', 'DirectionalLight', 'PointLight', 'Script', 'Shape', 'Sound', 'SpotLight', 'WorldInfo', // common nodes - 'CylinderSensor', 'PlaneSensor', 'ProximitySensor', 'SphereSensor', 'TimeSensor', 'TouchSensor', 'VisibilitySensor', // sensors - 'Box', 'Cone', 'Cylinder', 'ElevationGrid', 'Extrusion', 'IndexedFaceSet', 'IndexedLineSet', 'PointSet', 'Sphere', // geometries - 'Color', 'Coordinate', 'Normal', 'TextureCoordinate', // geometric properties - 'Appearance', 'FontStyle', 'ImageTexture', 'Material', 'MovieTexture', 'PixelTexture', 'TextureTransform', // appearance - 'ColorInterpolator', 'CoordinateInterpolator', 'NormalInterpolator', 'OrientationInterpolator', 'PositionInterpolator', 'ScalarInterpolator', // interpolators - 'Background', 'Fog', 'NavigationInfo', 'Viewpoint', // bindable nodes + } ); + + // from http://gun.teipir.gr/VRML-amgem/spec/part1/nodesRef.html + + const nodeTypes = [ 'Anchor', 'Billboard', 'Collision', 'Group', 'Transform', + // grouping nodes + 'Inline', 'LOD', 'Switch', + // special groups + 'AudioClip', 'DirectionalLight', 'PointLight', 'Script', 'Shape', 'Sound', 'SpotLight', 'WorldInfo', + // common nodes + 'CylinderSensor', 'PlaneSensor', 'ProximitySensor', 'SphereSensor', 'TimeSensor', 'TouchSensor', 'VisibilitySensor', + // sensors + 'Box', 'Cone', 'Cylinder', 'ElevationGrid', 'Extrusion', 'IndexedFaceSet', 'IndexedLineSet', 'PointSet', 'Sphere', + // geometries + 'Color', 'Coordinate', 'Normal', 'TextureCoordinate', + // geometric properties + 'Appearance', 'FontStyle', 'ImageTexture', 'Material', 'MovieTexture', 'PixelTexture', 'TextureTransform', + // appearance + 'ColorInterpolator', 'CoordinateInterpolator', 'NormalInterpolator', 'OrientationInterpolator', 'PositionInterpolator', 'ScalarInterpolator', + // interpolators + 'Background', 'Fog', 'NavigationInfo', 'Viewpoint', + // bindable nodes 'Text' // Text must be placed at the end of the regex so there are no matches for TextureTransform and TextureCoordinate - ]; // + ]; + + // const Version = createToken( { name: 'Version', @@ -135,7 +154,9 @@ name: 'TO', pattern: /TO/, longer_alt: Identifier - } ); // + } ); + + // const StringLiteral = createToken( { name: 'StringLiteral', @@ -181,20 +202,22 @@ name: 'Comment', pattern: /#.*/, group: chevrotain.Lexer.SKIPPED // eslint-disable-line no-undef + } ); - } ); // commas, blanks, tabs, newlines and carriage returns are whitespace characters wherever they appear outside of string fields + // commas, blanks, tabs, newlines and carriage returns are whitespace characters wherever they appear outside of string fields const WhiteSpace = createToken( { name: 'WhiteSpace', pattern: /[ ,\s]/, group: chevrotain.Lexer.SKIPPED // eslint-disable-line no-undef - } ); - const tokens = [ WhiteSpace, // keywords appear before the Identifier - NodeName, DEF, USE, ROUTE, TO, TrueLiteral, FalseLiteral, NullLiteral, // the Identifier must appear after the keywords because all keywords are valid identifiers + + const tokens = [ WhiteSpace, + // keywords appear before the Identifier + NodeName, DEF, USE, ROUTE, TO, TrueLiteral, FalseLiteral, NullLiteral, + // the Identifier must appear after the keywords because all keywords are valid identifiers Version, Identifier, RouteIdentifier, StringLiteral, HexLiteral, NumberLiteral, LSquare, RSquare, LCurly, RCurly, Comment ]; const tokenVocabulary = {}; - for ( let i = 0, l = tokens.length; i < l; i ++ ) { const token = tokens[ i ]; @@ -212,6 +235,7 @@ function createVisitor( BaseVRMLVisitor ) { // the visitor is created dynmaically based on the given base class + class VRMLToASTVisitor extends BaseVRMLVisitor { constructor() { @@ -220,7 +244,6 @@ this.validateVisitor(); } - vrml( ctx ) { const data = { @@ -228,7 +251,6 @@ nodes: [], routes: [] }; - for ( let i = 0, l = ctx.node.length; i < l; i ++ ) { const node = ctx.node[ i ]; @@ -250,20 +272,17 @@ return data; } - version( ctx ) { return ctx.Version[ 0 ].image; } - node( ctx ) { const data = { name: ctx.NodeName[ 0 ].image, fields: [] }; - if ( ctx.field ) { for ( let i = 0, l = ctx.field.length; i < l; i ++ ) { @@ -273,8 +292,9 @@ } - } // DEF + } + // DEF if ( ctx.def ) { @@ -285,7 +305,6 @@ return data; } - field( ctx ) { const data = { @@ -293,14 +312,17 @@ type: null, values: null }; - let result; // SFValue + let result; + + // SFValue if ( ctx.singleFieldValue ) { result = this.visit( ctx.singleFieldValue[ 0 ] ); - } // MFValue + } + // MFValue if ( ctx.multiFieldValue ) { @@ -313,13 +335,11 @@ return data; } - def( ctx ) { return ( ctx.Identifier || ctx.NodeName )[ 0 ].image; } - use( ctx ) { return { @@ -327,19 +347,16 @@ }; } - singleFieldValue( ctx ) { return processField( this, ctx ); } - multiFieldValue( ctx ) { return processField( this, ctx ); } - route( ctx ) { const data = { @@ -351,18 +368,15 @@ } } - function processField( scope, ctx ) { const field = { type: null, values: [] }; - if ( ctx.node ) { field.type = 'node'; - for ( let i = 0, l = ctx.node.length; i < l; i ++ ) { const node = ctx.node[ i ]; @@ -375,7 +389,6 @@ if ( ctx.use ) { field.type = 'use'; - for ( let i = 0, l = ctx.use.length; i < l; i ++ ) { const use = ctx.use[ i ]; @@ -388,7 +401,6 @@ if ( ctx.StringLiteral ) { field.type = 'string'; - for ( let i = 0, l = ctx.StringLiteral.length; i < l; i ++ ) { const stringLiteral = ctx.StringLiteral[ i ]; @@ -401,7 +413,6 @@ if ( ctx.NumberLiteral ) { field.type = 'number'; - for ( let i = 0, l = ctx.NumberLiteral.length; i < l; i ++ ) { const numberLiteral = ctx.NumberLiteral[ i ]; @@ -414,7 +425,6 @@ if ( ctx.HexLiteral ) { field.type = 'hex'; - for ( let i = 0, l = ctx.HexLiteral.length; i < l; i ++ ) { const hexLiteral = ctx.HexLiteral[ i ]; @@ -427,7 +437,6 @@ if ( ctx.TrueLiteral ) { field.type = 'boolean'; - for ( let i = 0, l = ctx.TrueLiteral.length; i < l; i ++ ) { const trueLiteral = ctx.TrueLiteral[ i ]; @@ -440,7 +449,6 @@ if ( ctx.FalseLiteral ) { field.type = 'boolean'; - for ( let i = 0, l = ctx.FalseLiteral.length; i < l; i ++ ) { const falseLiteral = ctx.FalseLiteral[ i ]; @@ -472,16 +480,20 @@ function parseTree( tree ) { // console.log( JSON.stringify( tree, null, 2 ) ); + const nodes = tree.nodes; - const scene = new THREE.Scene(); // first iteration: build nodemap based on DEF statements + const scene = new THREE.Scene(); + + // first iteration: build nodemap based on DEF statements for ( let i = 0, l = nodes.length; i < l; i ++ ) { const node = nodes[ i ]; buildNodeMap( node ); - } // second iteration: build nodes + } + // second iteration: build nodes for ( let i = 0, l = nodes.length; i < l; i ++ ) { @@ -505,15 +517,12 @@ } const fields = node.fields; - for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; - if ( field.type === 'node' ) { const fieldValues = field.values; - for ( let j = 0, jl = fieldValues.length; j < jl; j ++ ) { buildNodeMap( fieldValues[ j ] ); @@ -529,6 +538,7 @@ function getNode( node ) { // handle case where a node refers to a different one + if ( node.USE ) { return resolveUSE( node.USE ); @@ -539,98 +549,79 @@ node.build = buildNode( node ); return node.build; - } // node builder + } + // node builder function buildNode( node ) { const nodeName = node.name; let build; - switch ( nodeName ) { + case 'Anchor': case 'Group': case 'Transform': case 'Collision': build = buildGroupingNode( node ); break; - case 'Background': build = buildBackgroundNode( node ); break; - case 'Shape': build = buildShapeNode( node ); break; - case 'Appearance': build = buildAppearanceNode( node ); break; - case 'Material': build = buildMaterialNode( node ); break; - case 'ImageTexture': build = buildImageTextureNode( node ); break; - case 'PixelTexture': build = buildPixelTextureNode( node ); break; - case 'TextureTransform': build = buildTextureTransformNode( node ); break; - case 'IndexedFaceSet': build = buildIndexedFaceSetNode( node ); break; - case 'IndexedLineSet': build = buildIndexedLineSetNode( node ); break; - case 'PointSet': build = buildPointSetNode( node ); break; - case 'Box': build = buildBoxNode( node ); break; - case 'Cone': build = buildConeNode( node ); break; - case 'Cylinder': build = buildCylinderNode( node ); break; - case 'Sphere': build = buildSphereNode( node ); break; - case 'ElevationGrid': build = buildElevationGridNode( node ); break; - case 'Extrusion': build = buildExtrusionNode( node ); break; - case 'Color': case 'Coordinate': case 'Normal': case 'TextureCoordinate': build = buildGeometricNode( node ); break; - case 'WorldInfo': build = buildWorldInfoNode( node ); break; - - case 'Anchor': case 'Billboard': case 'Inline': case 'LOD': @@ -662,7 +653,6 @@ case 'Viewpoint': // node not supported yet break; - default: console.warn( 'THREE.VRMLLoader: Unknown node:', nodeName ); break; @@ -681,60 +671,59 @@ function buildGroupingNode( node ) { - const object = new THREE.Group(); // + const object = new THREE.Group(); - const fields = node.fields; + // + const fields = node.fields; for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; const fieldName = field.name; const fieldValues = field.values; - switch ( fieldName ) { case 'bboxCenter': // field not supported break; - case 'bboxSize': // field not supported break; - case 'center': // field not supported break; - case 'children': parseFieldChildren( fieldValues, object ); break; - + case 'description': + // field not supported + break; case 'collide': // field not supported break; - + case 'parameter': + // field not supported + break; case 'rotation': const axis = new THREE.Vector3( fieldValues[ 0 ], fieldValues[ 1 ], fieldValues[ 2 ] ); const angle = fieldValues[ 3 ]; object.quaternion.setFromAxisAngle( axis, angle ); break; - case 'scale': object.scale.set( fieldValues[ 0 ], fieldValues[ 1 ], fieldValues[ 2 ] ); break; - case 'scaleOrientation': // field not supported break; - case 'translation': object.position.set( fieldValues[ 0 ], fieldValues[ 1 ], fieldValues[ 2 ] ); break; - case 'proxy': // field not supported break; - + case 'url': + // field not supported + break; default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; @@ -753,55 +742,43 @@ let groundAngle, groundColor; let skyAngle, skyColor; const fields = node.fields; - for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; const fieldName = field.name; const fieldValues = field.values; - switch ( fieldName ) { case 'groundAngle': groundAngle = fieldValues; break; - case 'groundColor': groundColor = fieldValues; break; - case 'backUrl': // field not supported break; - case 'bottomUrl': // field not supported break; - case 'frontUrl': // field not supported break; - case 'leftUrl': // field not supported break; - case 'rightUrl': // field not supported break; - case 'topUrl': // field not supported break; - case 'skyAngle': skyAngle = fieldValues; break; - case 'skyColor': skyColor = fieldValues; break; - default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; @@ -810,7 +787,9 @@ } - const radius = 10000; // sky + const radius = 10000; + + // sky if ( skyColor ) { @@ -821,7 +800,6 @@ depthWrite: false, depthTest: false } ); - if ( skyColor.length > 3 ) { paintFaces( skyGeometry, radius, skyAngle, toColorArray( skyColor ), true ); @@ -836,8 +814,9 @@ const sky = new THREE.Mesh( skyGeometry, skyMaterial ); group.add( sky ); - } // ground + } + // ground if ( groundColor ) { @@ -857,8 +836,9 @@ } - } // render background group first + } + // render background group first group.renderOrder = - Infinity; return group; @@ -867,19 +847,19 @@ function buildShapeNode( node ) { - const fields = node.fields; // if the appearance field is NULL or unspecified, lighting is off and the unlit object color is (0, 0, 0) + const fields = node.fields; + + // if the appearance field is NULL or unspecified, lighting is off and the unlit object color is (0, 0, 0) let material = new THREE.MeshBasicMaterial( { color: 0x000000 } ); let geometry; - for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; const fieldName = field.name; const fieldValues = field.values; - switch ( fieldName ) { case 'appearance': @@ -890,7 +870,6 @@ } break; - case 'geometry': if ( fieldValues[ 0 ] !== null ) { @@ -899,29 +878,27 @@ } break; - default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; } - } // build 3D object + } + // build 3D object let object; - if ( geometry && geometry.attributes.position ) { const type = geometry._type; - if ( type === 'points' ) { // points + const pointsMaterial = new THREE.PointsMaterial( { color: 0xffffff } ); - if ( geometry.attributes.color !== undefined ) { pointsMaterial.vertexColors = true; @@ -929,6 +906,7 @@ } else { // if the color field is NULL and there is a material defined for the appearance affecting this PointSet, then use the emissiveColor of the material to draw the points + if ( material.isMeshPhongMaterial ) { pointsMaterial.color.copy( material.emissive ); @@ -942,10 +920,10 @@ } else if ( type === 'line' ) { // lines + const lineMaterial = new THREE.LineBasicMaterial( { color: 0xffffff } ); - if ( geometry.attributes.color !== undefined ) { lineMaterial.vertexColors = true; @@ -953,6 +931,7 @@ } else { // if the color field is NULL and there is a material defined for the appearance affecting this IndexedLineSet, then use the emissiveColor of the material to draw the lines + if ( material.isMeshPhongMaterial ) { lineMaterial.color.copy( material.emissive ); @@ -966,13 +945,16 @@ } else { // consider meshes + // check "solid" hint (it's placed in the geometry but affects the material) + if ( geometry._solid !== undefined ) { material.side = geometry._solid ? THREE.FrontSide : THREE.DoubleSide; - } // check for vertex colors + } + // check for vertex colors if ( geometry.attributes.color !== undefined ) { @@ -986,7 +968,9 @@ } else { - object = new THREE.Object3D(); // if the geometry field is NULL or no vertices are defined the object is not drawn + object = new THREE.Object3D(); + + // if the geometry field is NULL or no vertices are defined the object is not drawn object.visible = false; @@ -1001,13 +985,11 @@ let material = new THREE.MeshPhongMaterial(); let transformData; const fields = node.fields; - for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; const fieldName = field.name; const fieldValues = field.values; - switch ( fieldName ) { case 'material': @@ -1024,6 +1006,7 @@ } else { // if the material field is NULL or unspecified, lighting is off and the unlit object color is (0, 0, 0) + material = new THREE.MeshBasicMaterial( { color: 0x000000 } ); @@ -1031,23 +1014,22 @@ } break; - case 'texture': const textureNode = fieldValues[ 0 ]; - if ( textureNode !== null ) { if ( textureNode.name === 'ImageTexture' || textureNode.name === 'PixelTexture' ) { material.map = getNode( textureNode ); - } else { // MovieTexture not supported yet + } else { + + // MovieTexture not supported yet } } break; - case 'textureTransform': if ( fieldValues[ 0 ] !== null ) { @@ -1056,48 +1038,43 @@ } break; - default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; } - } // only apply texture transform data if a texture was defined + } + // only apply texture transform data if a texture was defined if ( material.map ) { // respect VRML lighting model + if ( material.map.__type ) { switch ( material.map.__type ) { case TEXTURE_TYPE.INTENSITY_ALPHA: material.opacity = 1; // ignore transparency - break; - case TEXTURE_TYPE.RGB: material.color.set( 0xffffff ); // ignore material color - break; - case TEXTURE_TYPE.RGBA: material.color.set( 0xffffff ); // ignore material color - material.opacity = 1; // ignore transparency - break; - default: } delete material.map.__type; - } // apply texture transform + } + // apply texture transform if ( transformData ) { @@ -1118,39 +1095,31 @@ const materialData = {}; const fields = node.fields; - for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; const fieldName = field.name; const fieldValues = field.values; - switch ( fieldName ) { case 'ambientIntensity': // field not supported break; - case 'diffuseColor': materialData.diffuseColor = new THREE.Color( fieldValues[ 0 ], fieldValues[ 1 ], fieldValues[ 2 ] ); break; - case 'emissiveColor': materialData.emissiveColor = new THREE.Color( fieldValues[ 0 ], fieldValues[ 1 ], fieldValues[ 2 ] ); break; - case 'shininess': materialData.shininess = fieldValues[ 0 ]; break; - case 'specularColor': materialData.emissiveColor = new THREE.Color( fieldValues[ 0 ], fieldValues[ 1 ], fieldValues[ 2 ] ); break; - case 'transparency': materialData.transparency = fieldValues[ 0 ]; break; - default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; @@ -1166,7 +1135,6 @@ function parseHexColor( hex, textureType, color ) { let value; - switch ( textureType ) { case TEXTURE_TYPE.INTENSITY: @@ -1177,7 +1145,6 @@ color.b = value; color.a = 1; break; - case TEXTURE_TYPE.INTENSITY_ALPHA: // Intensity+Alpha texture: A two-component image specifies the intensity in the first (high) byte and the alpha opacity in the second (low) byte. value = parseInt( '0x' + hex.substring( 2, 4 ) ); @@ -1186,7 +1153,6 @@ color.b = value; color.a = parseInt( '0x' + hex.substring( 4, 6 ) ); break; - case TEXTURE_TYPE.RGB: // RGB texture: Pixels in a three-component image specify the red component in the first (high) byte, followed by the green and blue components color.r = parseInt( '0x' + hex.substring( 2, 4 ) ); @@ -1194,7 +1160,6 @@ color.b = parseInt( '0x' + hex.substring( 6, 8 ) ); color.a = 1; break; - case TEXTURE_TYPE.RGBA: // RGBA texture: Four-component images specify the alpha opacity byte after red/green/blue color.r = parseInt( '0x' + hex.substring( 2, 4 ) ); @@ -1202,7 +1167,6 @@ color.b = parseInt( '0x' + hex.substring( 6, 8 ) ); color.a = parseInt( '0x' + hex.substring( 8, 10 ) ); break; - default: } @@ -1212,25 +1176,20 @@ function getTextureType( num_components ) { let type; - switch ( num_components ) { case 1: type = TEXTURE_TYPE.INTENSITY; break; - case 2: type = TEXTURE_TYPE.INTENSITY_ALPHA; break; - case 3: type = TEXTURE_TYPE.RGB; break; - case 4: type = TEXTURE_TYPE.RGBA; break; - default: } @@ -1245,13 +1204,11 @@ let wrapS = THREE.RepeatWrapping; let wrapT = THREE.RepeatWrapping; const fields = node.fields; - for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; const fieldName = field.name; const fieldValues = field.values; - switch ( fieldName ) { case 'image': @@ -1266,7 +1223,6 @@ b: 0, a: 0 }; - for ( let j = 3, k = 0, jl = fieldValues.length; j < jl; j ++, k ++ ) { parseHexColor( fieldValues[ j ], textureType, color ); @@ -1281,17 +1237,13 @@ texture = new THREE.DataTexture( data, width, height ); texture.needsUpdate = true; texture.__type = textureType; // needed for material modifications - break; - case 'repeatS': if ( fieldValues[ 0 ] === false ) wrapS = THREE.ClampToEdgeWrapping; break; - case 'repeatT': if ( fieldValues[ 0 ] === false ) wrapT = THREE.ClampToEdgeWrapping; break; - default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; @@ -1317,28 +1269,23 @@ let wrapS = THREE.RepeatWrapping; let wrapT = THREE.RepeatWrapping; const fields = node.fields; - for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; const fieldName = field.name; const fieldValues = field.values; - switch ( fieldName ) { case 'url': const url = fieldValues[ 0 ]; if ( url ) texture = textureLoader.load( url ); break; - case 'repeatS': if ( fieldValues[ 0 ] === false ) wrapS = THREE.ClampToEdgeWrapping; break; - case 'repeatT': if ( fieldValues[ 0 ] === false ) wrapT = THREE.ClampToEdgeWrapping; break; - default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; @@ -1367,31 +1314,25 @@ translation: new THREE.Vector2() }; const fields = node.fields; - for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; const fieldName = field.name; const fieldValues = field.values; - switch ( fieldName ) { case 'center': transformData.center.set( fieldValues[ 0 ], fieldValues[ 1 ] ); break; - case 'rotation': transformData.rotation = fieldValues[ 0 ]; break; - case 'scale': transformData.scale.set( fieldValues[ 0 ], fieldValues[ 1 ] ); break; - case 'translation': transformData.translation.set( fieldValues[ 0 ], fieldValues[ 1 ] ); break; - default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; @@ -1414,23 +1355,19 @@ const worldInfo = {}; const fields = node.fields; - for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; const fieldName = field.name; const fieldValues = field.values; - switch ( fieldName ) { case 'title': worldInfo.title = fieldValues[ 0 ]; break; - case 'info': worldInfo.info = fieldValues; break; - default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; @@ -1453,18 +1390,15 @@ let colorPerVertex = true, normalPerVertex = true; const fields = node.fields; - for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; const fieldName = field.name; const fieldValues = field.values; - switch ( fieldName ) { case 'color': const colorNode = fieldValues[ 0 ]; - if ( colorNode !== null ) { color = getNode( colorNode ); @@ -1472,10 +1406,8 @@ } break; - case 'coord': const coordNode = fieldValues[ 0 ]; - if ( coordNode !== null ) { coord = getNode( coordNode ); @@ -1483,10 +1415,8 @@ } break; - case 'normal': const normalNode = fieldValues[ 0 ]; - if ( normalNode !== null ) { normal = getNode( normalNode ); @@ -1494,10 +1424,8 @@ } break; - case 'texCoord': const texCoordNode = fieldValues[ 0 ]; - if ( texCoordNode !== null ) { texCoord = getNode( texCoordNode ); @@ -1505,47 +1433,36 @@ } break; - case 'ccw': ccw = fieldValues[ 0 ]; break; - case 'colorIndex': colorIndex = fieldValues; break; - case 'colorPerVertex': colorPerVertex = fieldValues[ 0 ]; break; - case 'convex': // field not supported break; - case 'coordIndex': coordIndex = fieldValues; break; - case 'creaseAngle': creaseAngle = fieldValues[ 0 ]; break; - case 'normalIndex': normalIndex = fieldValues; break; - case 'normalPerVertex': normalPerVertex = fieldValues[ 0 ]; break; - case 'solid': solid = fieldValues[ 0 ]; break; - case 'texCoordIndex': texCoordIndex = fieldValues; break; - default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; @@ -1565,7 +1482,6 @@ let colorAttribute; let normalAttribute; let uvAttribute; - if ( color ) { if ( colorPerVertex === true ) { @@ -1573,12 +1489,14 @@ if ( colorIndex && colorIndex.length > 0 ) { // if the colorIndex field is not empty, then it is used to choose colors for each vertex of the IndexedFaceSet. + const triangulatedColorIndex = triangulateFaceIndex( colorIndex, ccw ); colorAttribute = computeAttributeFromIndexedData( triangulatedCoordIndex, triangulatedColorIndex, color, 3 ); } else { // if the colorIndex field is empty, then the coordIndex field is used to choose colors from the THREE.Color node + colorAttribute = toNonIndexedAttribute( triangulatedCoordIndex, new THREE.Float32BufferAttribute( color, 3 ) ); } @@ -1588,6 +1506,7 @@ if ( colorIndex && colorIndex.length > 0 ) { // if the colorIndex field is not empty, then they are used to choose one color for each face of the IndexedFaceSet + const flattenFaceColors = flattenData( color, colorIndex ); const triangulatedFaceColors = triangulateFaceData( flattenFaceColors, coordIndex ); colorAttribute = computeAttributeFromFaceData( triangulatedCoordIndex, triangulatedFaceColors ); @@ -1595,6 +1514,7 @@ } else { // if the colorIndex field is empty, then the color are applied to each face of the IndexedFaceSet in order + const triangulatedFaceColors = triangulateFaceData( color, coordIndex ); colorAttribute = computeAttributeFromFaceData( triangulatedCoordIndex, triangulatedFaceColors ); @@ -1609,15 +1529,18 @@ if ( normalPerVertex === true ) { // consider vertex normals + if ( normalIndex && normalIndex.length > 0 ) { // if the normalIndex field is not empty, then it is used to choose normals for each vertex of the IndexedFaceSet. + const triangulatedNormalIndex = triangulateFaceIndex( normalIndex, ccw ); normalAttribute = computeAttributeFromIndexedData( triangulatedCoordIndex, triangulatedNormalIndex, normal, 3 ); } else { // if the normalIndex field is empty, then the coordIndex field is used to choose normals from the Normal node + normalAttribute = toNonIndexedAttribute( triangulatedCoordIndex, new THREE.Float32BufferAttribute( normal, 3 ) ); } @@ -1625,9 +1548,11 @@ } else { // consider face normals + if ( normalIndex && normalIndex.length > 0 ) { // if the normalIndex field is not empty, then they are used to choose one normal for each face of the IndexedFaceSet + const flattenFaceNormals = flattenData( normal, normalIndex ); const triangulatedFaceNormals = triangulateFaceData( flattenFaceNormals, coordIndex ); normalAttribute = computeAttributeFromFaceData( triangulatedCoordIndex, triangulatedFaceNormals ); @@ -1635,6 +1560,7 @@ } else { // if the normalIndex field is empty, then the normals are applied to each face of the IndexedFaceSet in order + const triangulatedFaceNormals = triangulateFaceData( normal, coordIndex ); normalAttribute = computeAttributeFromFaceData( triangulatedCoordIndex, triangulatedFaceNormals ); @@ -1645,6 +1571,7 @@ } else { // if the normal field is NULL, then the loader should automatically generate normals, using creaseAngle to determine if and how normals are smoothed across shared vertices + normalAttribute = computeNormalAttribute( triangulatedCoordIndex, coord, creaseAngle ); } @@ -1652,15 +1579,18 @@ if ( texCoord ) { // texture coordinates are always defined on vertex level + if ( texCoordIndex && texCoordIndex.length > 0 ) { // if the texCoordIndex field is not empty, then it is used to choose texture coordinates for each vertex of the IndexedFaceSet. + const triangulatedTexCoordIndex = triangulateFaceIndex( texCoordIndex, ccw ); uvAttribute = computeAttributeFromIndexedData( triangulatedCoordIndex, triangulatedTexCoordIndex, texCoord, 2 ); } else { // if the texCoordIndex field is empty, then the coordIndex array is used to choose texture coordinates from the TextureCoordinate node + uvAttribute = toNonIndexedAttribute( triangulatedCoordIndex, new THREE.Float32BufferAttribute( texCoord, 2 ) ); } @@ -1670,10 +1600,14 @@ const geometry = new THREE.BufferGeometry(); const positionAttribute = toNonIndexedAttribute( triangulatedCoordIndex, new THREE.Float32BufferAttribute( coord, 3 ) ); geometry.setAttribute( 'position', positionAttribute ); - geometry.setAttribute( 'normal', normalAttribute ); // optional attributes + geometry.setAttribute( 'normal', normalAttribute ); + + // optional attributes if ( colorAttribute ) geometry.setAttribute( 'color', colorAttribute ); - if ( uvAttribute ) geometry.setAttribute( 'uv', uvAttribute ); // "solid" influences the material so let's store it for later use + if ( uvAttribute ) geometry.setAttribute( 'uv', uvAttribute ); + + // "solid" influences the material so let's store it for later use geometry._solid = solid; geometry._type = 'mesh'; @@ -1687,18 +1621,15 @@ let colorIndex, coordIndex; let colorPerVertex = true; const fields = node.fields; - for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; const fieldName = field.name; const fieldValues = field.values; - switch ( fieldName ) { case 'color': const colorNode = fieldValues[ 0 ]; - if ( colorNode !== null ) { color = getNode( colorNode ); @@ -1706,10 +1637,8 @@ } break; - case 'coord': const coordNode = fieldValues[ 0 ]; - if ( coordNode !== null ) { coord = getNode( coordNode ); @@ -1717,27 +1646,24 @@ } break; - case 'colorIndex': colorIndex = fieldValues; break; - case 'colorPerVertex': colorPerVertex = fieldValues[ 0 ]; break; - case 'coordIndex': coordIndex = fieldValues; break; - default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; } - } // build lines + } + // build lines let colorAttribute; const expandedLineIndex = expandLineIndex( coordIndex ); // create an index for three.js's linesegment primitive @@ -1749,13 +1675,14 @@ if ( colorIndex.length > 0 ) { // if the colorIndex field is not empty, then one color is used for each polyline of the IndexedLineSet. - const expandedColorIndex = expandLineIndex( colorIndex ); // compute colors for each line segment (rendering primitve) + const expandedColorIndex = expandLineIndex( colorIndex ); // compute colors for each line segment (rendering primitve) colorAttribute = computeAttributeFromIndexedData( expandedLineIndex, expandedColorIndex, color, 3 ); // compute data on vertex level } else { // if the colorIndex field is empty, then the colors are applied to each polyline of the IndexedLineSet in order. + colorAttribute = toNonIndexedAttribute( expandedLineIndex, new THREE.Float32BufferAttribute( color, 3 ) ); } @@ -1765,25 +1692,25 @@ if ( colorIndex.length > 0 ) { // if the colorIndex field is not empty, then colors are applied to each vertex of the IndexedLineSet - const flattenLineColors = flattenData( color, colorIndex ); // compute colors for each VRML primitve + const flattenLineColors = flattenData( color, colorIndex ); // compute colors for each VRML primitve const expandedLineColors = expandLineData( flattenLineColors, coordIndex ); // compute colors for each line segment (rendering primitve) - colorAttribute = computeAttributeFromLineData( expandedLineIndex, expandedLineColors ); // compute data on vertex level } else { // if the colorIndex field is empty, then the coordIndex field is used to choose colors from the THREE.Color node - const expandedLineColors = expandLineData( color, coordIndex ); // compute colors for each line segment (rendering primitve) + const expandedLineColors = expandLineData( color, coordIndex ); // compute colors for each line segment (rendering primitve) colorAttribute = computeAttributeFromLineData( expandedLineIndex, expandedLineColors ); // compute data on vertex level } } - } // + } + // const geometry = new THREE.BufferGeometry(); const positionAttribute = toNonIndexedAttribute( expandedLineIndex, new THREE.Float32BufferAttribute( coord, 3 ) ); @@ -1798,18 +1725,15 @@ let color, coord; const fields = node.fields; - for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; const fieldName = field.name; const fieldValues = field.values; - switch ( fieldName ) { case 'color': const colorNode = fieldValues[ 0 ]; - if ( colorNode !== null ) { color = getNode( colorNode ); @@ -1817,10 +1741,8 @@ } break; - case 'coord': const coordNode = fieldValues[ 0 ]; - if ( coordNode !== null ) { coord = getNode( coordNode ); @@ -1828,7 +1750,6 @@ } break; - default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; @@ -1849,13 +1770,11 @@ const size = new THREE.Vector3( 2, 2, 2 ); const fields = node.fields; - for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; const fieldName = field.name; const fieldValues = field.values; - switch ( fieldName ) { case 'size': @@ -1863,7 +1782,6 @@ size.y = fieldValues[ 1 ]; size.z = fieldValues[ 2 ]; break; - default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; @@ -1883,31 +1801,25 @@ height = 2, openEnded = false; const fields = node.fields; - for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; const fieldName = field.name; const fieldValues = field.values; - switch ( fieldName ) { case 'bottom': openEnded = ! fieldValues[ 0 ]; break; - case 'bottomRadius': radius = fieldValues[ 0 ]; break; - case 'height': height = fieldValues[ 0 ]; break; - case 'side': // field not supported break; - default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; @@ -1926,35 +1838,28 @@ let radius = 1, height = 2; const fields = node.fields; - for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; const fieldName = field.name; const fieldValues = field.values; - switch ( fieldName ) { case 'bottom': // field not supported break; - case 'radius': radius = fieldValues[ 0 ]; break; - case 'height': height = fieldValues[ 0 ]; break; - case 'side': // field not supported break; - case 'top': // field not supported break; - default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; @@ -1972,19 +1877,16 @@ let radius = 1; const fields = node.fields; - for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; const fieldName = field.name; const fieldValues = field.values; - switch ( fieldName ) { case 'radius': radius = fieldValues[ 0 ]; break; - default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; @@ -2014,18 +1916,15 @@ let xSpacing = 1; let zSpacing = 1; const fields = node.fields; - for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; const fieldName = field.name; const fieldValues = field.values; - switch ( fieldName ) { case 'color': const colorNode = fieldValues[ 0 ]; - if ( colorNode !== null ) { color = getNode( colorNode ); @@ -2033,10 +1932,8 @@ } break; - case 'normal': const normalNode = fieldValues[ 0 ]; - if ( normalNode !== null ) { normal = getNode( normalNode ); @@ -2044,10 +1941,8 @@ } break; - case 'texCoord': const texCoordNode = fieldValues[ 0 ]; - if ( texCoordNode !== null ) { texCoord = getNode( texCoordNode ); @@ -2055,72 +1950,66 @@ } break; - case 'height': height = fieldValues; break; - case 'ccw': ccw = fieldValues[ 0 ]; break; - case 'colorPerVertex': colorPerVertex = fieldValues[ 0 ]; break; - case 'creaseAngle': creaseAngle = fieldValues[ 0 ]; break; - case 'normalPerVertex': normalPerVertex = fieldValues[ 0 ]; break; - case 'solid': solid = fieldValues[ 0 ]; break; - case 'xDimension': xDimension = fieldValues[ 0 ]; break; - case 'xSpacing': xSpacing = fieldValues[ 0 ]; break; - case 'zDimension': zDimension = fieldValues[ 0 ]; break; - case 'zSpacing': zSpacing = fieldValues[ 0 ]; break; - default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; } - } // vertex data + } + // vertex data const vertices = []; const normals = []; const colors = []; const uvs = []; - for ( let i = 0; i < zDimension; i ++ ) { for ( let j = 0; j < xDimension; j ++ ) { // compute a row major index - const index = i * xDimension + j; // vertices + + const index = i * xDimension + j; + + // vertices const x = xSpacing * i; const y = height[ index ]; const z = zSpacing * j; - vertices.push( x, y, z ); // colors + vertices.push( x, y, z ); + + // colors if ( color && colorPerVertex === true ) { @@ -2129,8 +2018,9 @@ const b = color[ index * 3 + 2 ]; colors.push( r, g, b ); - } // normals + } + // normals if ( normal && normalPerVertex === true ) { @@ -2139,8 +2029,9 @@ const zn = normal[ index * 3 + 2 ]; normals.push( xn, yn, zn ); - } // uvs + } + // uvs if ( texCoord ) { @@ -2156,20 +2047,23 @@ } - } // indices + } + // indices const indices = []; - for ( let i = 0; i < xDimension - 1; i ++ ) { for ( let j = 0; j < zDimension - 1; j ++ ) { // from https://tecfa.unige.ch/guides/vrml/vrml97/spec/part1/nodesRef.html#ElevationGrid + const a = i + j * xDimension; const b = i + ( j + 1 ) * xDimension; const c = i + 1 + ( j + 1 ) * xDimension; - const d = i + 1 + j * xDimension; // faces + const d = i + 1 + j * xDimension; + + // faces if ( ccw === true ) { @@ -2185,13 +2079,16 @@ } - } // + } + // const positionAttribute = toNonIndexedAttribute( indices, new THREE.Float32BufferAttribute( vertices, 3 ) ); const uvAttribute = toNonIndexedAttribute( indices, new THREE.Float32BufferAttribute( uvs, 2 ) ); let colorAttribute; - let normalAttribute; // color attribute + let normalAttribute; + + // color attribute if ( color ) { @@ -2204,7 +2101,9 @@ const index = i + j * ( xDimension - 1 ); const r = color[ index * 3 + 0 ]; const g = color[ index * 3 + 1 ]; - const b = color[ index * 3 + 2 ]; // one color per quad + const b = color[ index * 3 + 2 ]; + + // one color per quad colors.push( r, g, b ); colors.push( r, g, b ); @@ -2225,8 +2124,9 @@ } - } // normal attribute + } + // normal attribute if ( normal ) { @@ -2239,7 +2139,9 @@ const index = i + j * ( xDimension - 1 ); const xn = normal[ index * 3 + 0 ]; const yn = normal[ index * 3 + 1 ]; - const zn = normal[ index * 3 + 2 ]; // one normal per quad + const zn = normal[ index * 3 + 2 ]; + + // one normal per quad normals.push( xn, yn, zn ); normals.push( xn, yn, zn ); @@ -2264,14 +2166,17 @@ normalAttribute = computeNormalAttribute( indices, vertices, creaseAngle ); - } // build geometry + } + // build geometry const geometry = new THREE.BufferGeometry(); geometry.setAttribute( 'position', positionAttribute ); geometry.setAttribute( 'normal', normalAttribute ); geometry.setAttribute( 'uv', uvAttribute ); - if ( colorAttribute ) geometry.setAttribute( 'color', colorAttribute ); // "solid" influences the material so let's store it for later use + if ( colorAttribute ) geometry.setAttribute( 'color', colorAttribute ); + + // "solid" influences the material so let's store it for later use geometry._solid = solid; geometry._type = 'mesh'; @@ -2291,56 +2196,43 @@ let endCap = true; let solid = true; const fields = node.fields; - for ( let i = 0, l = fields.length; i < l; i ++ ) { const field = fields[ i ]; const fieldName = field.name; const fieldValues = field.values; - switch ( fieldName ) { case 'beginCap': beginCap = fieldValues[ 0 ]; break; - case 'ccw': ccw = fieldValues[ 0 ]; break; - case 'convex': // field not supported break; - case 'creaseAngle': creaseAngle = fieldValues[ 0 ]; break; - case 'crossSection': crossSection = fieldValues; break; - case 'endCap': endCap = fieldValues[ 0 ]; break; - case 'orientation': orientation = fieldValues; break; - case 'scale': scale = fieldValues; break; - case 'solid': solid = fieldValues[ 0 ]; break; - case 'spine': spine = fieldValues; // only extrusion along the Y-axis are supported so far - break; - default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; @@ -2349,7 +2241,9 @@ } - const crossSectionClosed = crossSection[ 0 ] === crossSection[ crossSection.length - 2 ] && crossSection[ 1 ] === crossSection[ crossSection.length - 1 ]; // vertices + const crossSectionClosed = crossSection[ 0 ] === crossSection[ crossSection.length - 2 ] && crossSection[ 1 ] === crossSection[ crossSection.length - 1 ]; + + // vertices const vertices = []; const spineVector = new THREE.Vector3(); @@ -2357,7 +2251,6 @@ const axis = new THREE.Vector3(); const vertex = new THREE.Vector3(); const quaternion = new THREE.Quaternion(); - for ( let i = 0, j = 0, o = 0, il = spine.length; i < il; i += 3, j += 2, o += 4 ) { spineVector.fromArray( spine, i ); @@ -2368,30 +2261,35 @@ axis.y = orientation ? orientation[ o + 1 ] : 0; axis.z = orientation ? orientation[ o + 2 ] : 1; const angle = orientation ? orientation[ o + 3 ] : 0; - for ( let k = 0, kl = crossSection.length; k < kl; k += 2 ) { vertex.x = crossSection[ k + 0 ]; vertex.y = 0; - vertex.z = crossSection[ k + 1 ]; // scale + vertex.z = crossSection[ k + 1 ]; - vertex.multiply( scaling ); // rotate + // scale + + vertex.multiply( scaling ); + + // rotate quaternion.setFromAxisAngle( axis, angle ); - vertex.applyQuaternion( quaternion ); // translate + vertex.applyQuaternion( quaternion ); + + // translate vertex.add( spineVector ); vertices.push( vertex.x, vertex.y, vertex.z ); } - } // indices + } + // indices const indices = []; const spineCount = spine.length / 3; const crossSectionCount = crossSection.length / 2; - for ( let i = 0; i < spineCount - 1; i ++ ) { for ( let j = 0; j < crossSectionCount - 1; j ++ ) { @@ -2400,7 +2298,6 @@ let b = j + 1 + i * crossSectionCount; const c = j + ( i + 1 ) * crossSectionCount; let d = j + 1 + ( i + 1 ) * crossSectionCount; - if ( j === crossSectionCount - 2 && crossSectionClosed === true ) { b = i * crossSectionCount; @@ -2422,13 +2319,13 @@ } - } // triangulate cap + } + // triangulate cap if ( beginCap === true || endCap === true ) { const contour = []; - for ( let i = 0, l = crossSection.length; i < l; i += 2 ) { contour.push( new THREE.Vector2( crossSection[ i ], crossSection[ i + 1 ] ) ); @@ -2437,14 +2334,14 @@ const faces = THREE.ShapeUtils.triangulateShape( contour, [] ); const capIndices = []; - for ( let i = 0, l = faces.length; i < l; i ++ ) { const face = faces[ i ]; capIndices.push( face[ 0 ], face[ 1 ], face[ 2 ] ); - } // begin cap + } + // begin cap if ( beginCap === true ) { @@ -2462,8 +2359,9 @@ } - } // end cap + } + // end cap if ( endCap === true ) { @@ -2491,20 +2389,25 @@ const normalAttribute = computeNormalAttribute( indices, vertices, creaseAngle ); const geometry = new THREE.BufferGeometry(); geometry.setAttribute( 'position', positionAttribute ); - geometry.setAttribute( 'normal', normalAttribute ); // no uvs yet + geometry.setAttribute( 'normal', normalAttribute ); + // no uvs yet + // "solid" influences the material so let's store it for later use geometry._solid = solid; geometry._type = 'mesh'; return geometry; - } // helper functions + } + // helper functions function resolveUSE( identifier ) { const node = nodeMap[ identifier ]; - const build = getNode( node ); // because the same 3D objects can have different transformations, it's necessary to clone them. + const build = getNode( node ); + + // because the same 3D objects can have different transformations, it's necessary to clone them. // materials can be influenced by the geometry (e.g. vertex normals). cloning is necessary to avoid // any side effects @@ -2525,17 +2428,20 @@ function triangulateFaceIndex( index, ccw ) { - const indices = []; // since face defintions can have more than three vertices, it's necessary to + const indices = []; + + // since face defintions can have more than three vertices, it's necessary to // perform a simple triangulation let start = 0; - for ( let i = 0, l = index.length; i < l; i ++ ) { const i1 = index[ start ]; const i2 = index[ i + ( ccw ? 1 : 2 ) ]; const i3 = index[ i + ( ccw ? 2 : 1 ) ]; - indices.push( i1, i2, i3 ); // an index of -1 indicates that the current face has ended and the next one begins + indices.push( i1, i2, i3 ); + + // an index of -1 indicates that the current face has ended and the next one begins if ( index[ i + 3 ] === - 1 || i + 3 >= l ) { @@ -2554,14 +2460,15 @@ const triangulatedData = []; let start = 0; - for ( let i = 0, l = index.length; i < l; i ++ ) { const stride = start * 3; const x = data[ stride ]; const y = data[ stride + 1 ]; const z = data[ stride + 2 ]; - triangulatedData.push( x, y, z ); // an index of -1 indicates that the current face has ended and the next one begins + triangulatedData.push( x, y, z ); + + // an index of -1 indicates that the current face has ended and the next one begins if ( index[ i + 3 ] === - 1 || i + 3 >= l ) { @@ -2579,7 +2486,6 @@ function flattenData( data, index ) { const flattenData = []; - for ( let i = 0, l = index.length; i < l; i ++ ) { const i1 = index[ i ]; @@ -2598,12 +2504,13 @@ function expandLineIndex( index ) { const indices = []; - for ( let i = 0, l = index.length; i < l; i ++ ) { const i1 = index[ i ]; const i2 = index[ i + 1 ]; - indices.push( i1, i2 ); // an index of -1 indicates that the current line has ended and the next one begins + indices.push( i1, i2 ); + + // an index of -1 indicates that the current line has ended and the next one begins if ( index[ i + 2 ] === - 1 || i + 2 >= l ) { @@ -2621,14 +2528,15 @@ const triangulatedData = []; let start = 0; - for ( let i = 0, l = index.length; i < l; i ++ ) { const stride = start * 3; const x = data[ stride ]; const y = data[ stride + 1 ]; const z = data[ stride + 2 ]; - triangulatedData.push( x, y, z ); // an index of -1 indicates that the current line has ended and the next one begins + triangulatedData.push( x, y, z ); + + // an index of -1 indicates that the current line has ended and the next one begins if ( index[ i + 2 ] === - 1 || i + 2 >= l ) { @@ -2649,17 +2557,17 @@ const uvA = new THREE.Vector2(); const uvB = new THREE.Vector2(); const uvC = new THREE.Vector2(); - function computeAttributeFromIndexedData( coordIndex, index, data, itemSize ) { - const array = []; // we use the coordIndex.length as delimiter since normalIndex must contain at least as many indices + const array = []; + + // we use the coordIndex.length as delimiter since normalIndex must contain at least as many indices for ( let i = 0, l = coordIndex.length; i < l; i += 3 ) { const a = index[ i ]; const b = index[ i + 1 ]; const c = index[ i + 2 ]; - if ( itemSize === 2 ) { uvA.fromArray( data, a * itemSize ); @@ -2689,7 +2597,6 @@ function computeAttributeFromFaceData( index, faceData ) { const array = []; - for ( let i = 0, j = 0, l = index.length; i < l; i += 3, j ++ ) { vA.fromArray( faceData, j * 3 ); @@ -2706,7 +2613,6 @@ function computeAttributeFromLineData( index, lineData ) { const array = []; - for ( let i = 0, j = 0, l = index.length; i < l; i += 2, j ++ ) { vA.fromArray( lineData, j * 3 ); @@ -2726,11 +2632,9 @@ const array2 = new array.constructor( indices.length * itemSize ); let index = 0, index2 = 0; - for ( let i = 0, l = indices.length; i < l; i ++ ) { index = indices[ i ] * itemSize; - for ( let j = 0; j < itemSize; j ++ ) { array2[ index2 ++ ] = array[ index ++ ]; @@ -2745,11 +2649,12 @@ const ab = new THREE.Vector3(); const cb = new THREE.Vector3(); - function computeNormalAttribute( index, coord, creaseAngle ) { const faces = []; - const vertexNormals = {}; // prepare face and raw vertex normals + const vertexNormals = {}; + + // prepare face and raw vertex normals for ( let i = 0, l = index.length; i < l; i += 3 ) { @@ -2773,11 +2678,11 @@ vertexNormals[ c ].push( face.normal ); faces.push( face ); - } // compute vertex normals and build final geometry + } + // compute vertex normals and build final geometry const normals = []; - for ( let i = 0, l = faces.length; i < l; i ++ ) { const face = faces[ i ]; @@ -2800,7 +2705,6 @@ function weightedNormal( normals, vector, creaseAngle ) { const normal = new THREE.Vector3(); - if ( creaseAngle === 0 ) { normal.copy( vector ); @@ -2826,7 +2730,6 @@ function toColorArray( colors ) { const array = []; - for ( let i = 0, l = colors.length; i < l; i += 3 ) { array.push( new THREE.Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) ); @@ -2836,6 +2739,7 @@ return array; } + /** * Vertically paints the faces interpolating between the * specified colors at the specified angels. This is used for the Background @@ -2858,14 +2762,12 @@ * @param {array} colors * @param {boolean} topDown - Whether to work top down or bottom up. */ - - function paintFaces( geometry, radius, angles, colors, topDown ) { // compute threshold values + const thresholds = []; const startAngle = topDown === true ? 0 : Math.PI; - for ( let i = 0, l = colors.length; i < l; i ++ ) { let angle = i === 0 ? 0 : angles[ i - 1 ]; @@ -2874,32 +2776,31 @@ point.setFromSphericalCoords( radius, angle, 0 ); thresholds.push( point ); - } // generate vertex colors + } + // generate vertex colors const indices = geometry.index; const positionAttribute = geometry.attributes.position; const colorAttribute = new THREE.BufferAttribute( new Float32Array( geometry.attributes.position.count * 3 ), 3 ); const position = new THREE.Vector3(); const color = new THREE.Color(); - for ( let i = 0; i < indices.count; i ++ ) { const index = indices.getX( i ); position.fromBufferAttribute( positionAttribute, index ); let thresholdIndexA, thresholdIndexB; let t = 1; - for ( let j = 1; j < thresholds.length; j ++ ) { thresholdIndexA = j - 1; thresholdIndexB = j; const thresholdA = thresholds[ thresholdIndexA ]; const thresholdB = thresholds[ thresholdIndexB ]; - if ( topDown === true ) { // interpolation for sky color + if ( position.y <= thresholdA.y && position.y > thresholdB.y ) { t = Math.abs( thresholdA.y - position.y ) / Math.abs( thresholdA.y - thresholdB.y ); @@ -2910,6 +2811,7 @@ } else { // interpolation for ground color + if ( position.y >= thresholdA.y && position.y < thresholdB.y ) { t = Math.abs( thresholdA.y - position.y ) / Math.abs( thresholdA.y - thresholdB.y ); @@ -2930,20 +2832,26 @@ geometry.setAttribute( 'color', colorAttribute ); - } // + } + // const textureLoader = new THREE.TextureLoader( this.manager ); - textureLoader.setPath( this.resourcePath || path ).setCrossOrigin( this.crossOrigin ); // check version (only 2.0 is supported) + textureLoader.setPath( this.resourcePath || path ).setCrossOrigin( this.crossOrigin ); + + // check version (only 2.0 is supported) if ( data.indexOf( '#VRML V2.0' ) === - 1 ) { throw Error( 'THREE.VRMLLexer: Version of VRML asset not supported.' ); - } // create JSON representing the tree structure of the VRML asset + } + + // create JSON representing the tree structure of the VRML asset + const tree = generateVRMLTree( data ); - const tree = generateVRMLTree( data ); // parse the tree structure to a three.js scene + // parse the tree structure to a three.js scene const scene = parseTree( tree ); return scene; @@ -2951,7 +2859,6 @@ } } - class VRMLLexer { constructor( tokens ) { @@ -2963,7 +2870,6 @@ lex( inputText ) { const lexingResult = this.lexer.tokenize( inputText ); - if ( lexingResult.errors.length > 0 ) { console.error( lexingResult.errors ); @@ -2976,7 +2882,6 @@ } } - const CstParser = chevrotain.CstParser; // eslint-disable-line no-undef class VRMLParser extends CstParser { @@ -3211,7 +3116,6 @@ } } - class Face { constructor( a, b, c ) { @@ -3224,7 +3128,6 @@ } } - const TEXTURE_TYPE = { INTENSITY: 1, INTENSITY_ALPHA: 2, diff --git a/examples/js/loaders/VTKLoader.js b/examples/js/loaders/VTKLoader.js index e30adcdd177b1c..2a4192d8e4d090 100644 --- a/examples/js/loaders/VTKLoader.js +++ b/examples/js/loaders/VTKLoader.js @@ -7,7 +7,6 @@ super( manager ); } - load( url, onLoad, onProgress, onError ) { const scope = this; @@ -41,40 +40,52 @@ }, onProgress, onError ); } - parse( data ) { function parseASCII( data ) { // connectivity of the triangles - const indices = []; // triangles vertices + const indices = []; - const positions = []; // red, green, blue colors in the range 0 to 1 + // triangles vertices + const positions = []; - const colors = []; // normal vector, one per vertex + // red, green, blue colors in the range 0 to 1 + const colors = []; + // normal vector, one per vertex const normals = []; - let result; // pattern for detecting the end of a number sequence + let result; - const patWord = /^[^\d.\s-]+/; // pattern for reading vertices, 3 floats or integers + // pattern for detecting the end of a number sequence + const patWord = /^[^\d.\s-]+/; - const pat3Floats = /(\-?\d+\.?[\d\-\+e]*)\s+(\-?\d+\.?[\d\-\+e]*)\s+(\-?\d+\.?[\d\-\+e]*)/g; // pattern for connectivity, an integer followed by any number of ints - // the first integer is the number of polygon nodes + // pattern for reading vertices, 3 floats or integers + const pat3Floats = /(\-?\d+\.?[\d\-\+e]*)\s+(\-?\d+\.?[\d\-\+e]*)\s+(\-?\d+\.?[\d\-\+e]*)/g; - const patConnectivity = /^(\d+)\s+([\s\d]*)/; // indicates start of vertex data section + // pattern for connectivity, an integer followed by any number of ints + // the first integer is the number of polygon nodes + const patConnectivity = /^(\d+)\s+([\s\d]*)/; - const patPOINTS = /^POINTS /; // indicates start of polygon connectivity section + // indicates start of vertex data section + const patPOINTS = /^POINTS /; - const patPOLYGONS = /^POLYGONS /; // indicates start of triangle strips section + // indicates start of polygon connectivity section + const patPOLYGONS = /^POLYGONS /; - const patTRIANGLE_STRIPS = /^TRIANGLE_STRIPS /; // POINT_DATA number_of_values + // indicates start of triangle strips section + const patTRIANGLE_STRIPS = /^TRIANGLE_STRIPS /; - const patPOINT_DATA = /^POINT_DATA[ ]+(\d+)/; // CELL_DATA number_of_polys + // POINT_DATA number_of_values + const patPOINT_DATA = /^POINT_DATA[ ]+(\d+)/; - const patCELL_DATA = /^CELL_DATA[ ]+(\d+)/; // Start of color section + // CELL_DATA number_of_polys + const patCELL_DATA = /^CELL_DATA[ ]+(\d+)/; - const patCOLOR_SCALARS = /^COLOR_SCALARS[ ]+(\w+)[ ]+3/; // NORMALS Normals float + // Start of color section + const patCOLOR_SCALARS = /^COLOR_SCALARS[ ]+(\w+)[ ]+3/; + // NORMALS Normals float const patNORMALS = /^NORMALS[ ]+(\w+)[ ]+(\w+)/; let inPointsSection = false; let inPolygonsSection = false; @@ -84,11 +95,9 @@ let inColorSection = false; let inNormalsSection = false; const lines = data.split( '\n' ); - for ( const i in lines ) { const line = lines[ i ].trim(); - if ( line.indexOf( 'DATASET' ) === 0 ) { const dataset = line.split( ' ' )[ 1 ]; @@ -114,12 +123,11 @@ // numVertices i0 i1 i2 ... const numVertices = parseInt( result[ 1 ] ); const inds = result[ 2 ].split( /\s+/ ); - if ( numVertices >= 3 ) { const i0 = parseInt( inds[ 0 ] ); - let k = 1; // split the polygon in numVertices - 2 triangles - + let k = 1; + // split the polygon in numVertices - 2 triangles for ( let j = 0; j < numVertices - 2; ++ j ) { const i1 = parseInt( inds[ k ] ); @@ -140,7 +148,6 @@ // numVertices i0 i1 i2 ... const numVertices = parseInt( result[ 1 ] ); const inds = result[ 2 ].split( /\s+/ ); - if ( numVertices >= 3 ) { // split the polygon in numVertices - 2 triangles @@ -173,6 +180,7 @@ if ( inColorSection ) { // Get the colors + while ( ( result = pat3Floats.exec( line ) ) !== null ) { if ( patWord.exec( line ) !== null ) break; @@ -186,6 +194,7 @@ } else if ( inNormalsSection ) { // Get the normal vectors + while ( ( result = pat3Floats.exec( line ) ) !== null ) { if ( patWord.exec( line ) !== null ) break; @@ -255,7 +264,6 @@ let geometry = new THREE.BufferGeometry(); geometry.setIndex( indices ); geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); - if ( normals.length === positions.length ) { geometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); @@ -265,6 +273,7 @@ if ( colors.length !== indices.length ) { // stagger + if ( colors.length === positions.length ) { geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) ); @@ -274,13 +283,12 @@ } else { // cell + geometry = geometry.toNonIndexed(); const numTriangles = geometry.attributes.position.count / 3; - if ( colors.length === numTriangles * 3 ) { const newColors = []; - for ( let i = 0; i < numTriangles; i ++ ) { const r = colors[ 3 * i + 0 ]; @@ -305,19 +313,18 @@ function parseBinary( data ) { const buffer = new Uint8Array( data ); - const dataView = new DataView( data ); // Points and normals, by default, are empty + const dataView = new DataView( data ); + // Points and normals, by default, are empty let points = []; let normals = []; let indices = []; let index = 0; - function findString( buffer, start ) { let index = start; let c = buffer[ index ]; const s = []; - while ( c !== 10 ) { s.push( String.fromCharCode( c ) ); @@ -336,13 +343,11 @@ } let state, line; - while ( true ) { // Get a string state = findString( buffer, index ); line = state.parsedString; - if ( line.indexOf( 'DATASET' ) === 0 ) { const dataset = line.split( ' ' )[ 1 ]; @@ -351,12 +356,12 @@ } else if ( line.indexOf( 'POINTS' ) === 0 ) { // Add the points - const numberOfPoints = parseInt( line.split( ' ' )[ 1 ], 10 ); // Each point is 3 4-byte floats + const numberOfPoints = parseInt( line.split( ' ' )[ 1 ], 10 ); + // Each point is 3 4-byte floats const count = numberOfPoints * 4 * 3; points = new Float32Array( numberOfPoints * 3 ); let pointIndex = state.next; - for ( let i = 0; i < numberOfPoints; i ++ ) { points[ 3 * i ] = dataView.getFloat32( pointIndex, false ); @@ -364,36 +369,34 @@ points[ 3 * i + 2 ] = dataView.getFloat32( pointIndex + 8, false ); pointIndex = pointIndex + 12; - } // increment our next pointer - + } + // increment our next pointer state.next = state.next + count + 1; } else if ( line.indexOf( 'TRIANGLE_STRIPS' ) === 0 ) { const numberOfStrips = parseInt( line.split( ' ' )[ 1 ], 10 ); - const size = parseInt( line.split( ' ' )[ 2 ], 10 ); // 4 byte integers - + const size = parseInt( line.split( ' ' )[ 2 ], 10 ); + // 4 byte integers const count = size * 4; indices = new Uint32Array( 3 * size - 9 * numberOfStrips ); let indicesIndex = 0; let pointIndex = state.next; - for ( let i = 0; i < numberOfStrips; i ++ ) { // For each strip, read the first value, then record that many more points const indexCount = dataView.getInt32( pointIndex, false ); const strip = []; pointIndex += 4; - for ( let s = 0; s < indexCount; s ++ ) { strip.push( dataView.getInt32( pointIndex, false ) ); pointIndex += 4; - } // retrieves the n-2 triangles from the triangle strip - + } + // retrieves the n-2 triangles from the triangle strip for ( let j = 0; j < indexCount - 2; j ++ ) { if ( j % 2 ) { @@ -412,36 +415,34 @@ } - } // increment our next pointer - + } + // increment our next pointer state.next = state.next + count + 1; } else if ( line.indexOf( 'POLYGONS' ) === 0 ) { const numberOfStrips = parseInt( line.split( ' ' )[ 1 ], 10 ); - const size = parseInt( line.split( ' ' )[ 2 ], 10 ); // 4 byte integers - + const size = parseInt( line.split( ' ' )[ 2 ], 10 ); + // 4 byte integers const count = size * 4; indices = new Uint32Array( 3 * size - 9 * numberOfStrips ); let indicesIndex = 0; let pointIndex = state.next; - for ( let i = 0; i < numberOfStrips; i ++ ) { // For each strip, read the first value, then record that many more points const indexCount = dataView.getInt32( pointIndex, false ); const strip = []; pointIndex += 4; - for ( let s = 0; s < indexCount; s ++ ) { strip.push( dataView.getInt32( pointIndex, false ) ); pointIndex += 4; - } // divide the polygon in n-2 triangle - + } + // divide the polygon in n-2 triangle for ( let j = 1; j < indexCount - 1; j ++ ) { indices[ indicesIndex ++ ] = strip[ 0 ]; @@ -450,21 +451,22 @@ } - } // increment our next pointer - + } + // increment our next pointer state.next = state.next + count + 1; } else if ( line.indexOf( 'POINT_DATA' ) === 0 ) { - const numberOfPoints = parseInt( line.split( ' ' )[ 1 ], 10 ); // Grab the next line + const numberOfPoints = parseInt( line.split( ' ' )[ 1 ], 10 ); - state = findString( buffer, state.next ); // Now grab the binary data + // Grab the next line + state = findString( buffer, state.next ); + // Now grab the binary data const count = numberOfPoints * 4 * 3; normals = new Float32Array( numberOfPoints * 3 ); let pointIndex = state.next; - for ( let i = 0; i < numberOfPoints; i ++ ) { normals[ 3 * i ] = dataView.getFloat32( pointIndex, false ); @@ -472,16 +474,15 @@ normals[ 3 * i + 2 ] = dataView.getFloat32( pointIndex + 8, false ); pointIndex += 12; - } // Increment past our data - + } + // Increment past our data state.next = state.next + count; - } // Increment index - + } + // Increment index index = state.next; - if ( index >= buffer.byteLength ) { break; @@ -493,7 +494,6 @@ const geometry = new THREE.BufferGeometry(); geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) ); geometry.setAttribute( 'position', new THREE.BufferAttribute( points, 3 ) ); - if ( normals.length === points.length ) { geometry.setAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); @@ -527,21 +527,22 @@ function parseXML( stringFile ) { // Changes XML to JSON, based on https://davidwalsh.name/convert-xml-json + function xmlToJson( xml ) { // Create the return object let obj = {}; - if ( xml.nodeType === 1 ) { // element + // do attributes + if ( xml.attributes ) { if ( xml.attributes.length > 0 ) { obj[ 'attributes' ] = {}; - for ( let j = 0; j < xml.attributes.length; j ++ ) { const attribute = xml.attributes.item( j ); @@ -556,18 +557,18 @@ } else if ( xml.nodeType === 3 ) { // text - obj = xml.nodeValue.trim(); - } // do children + obj = xml.nodeValue.trim(); + } + // do children if ( xml.hasChildNodes() ) { for ( let i = 0; i < xml.childNodes.length; i ++ ) { const item = xml.childNodes.item( i ); const nodeName = item.nodeName; - if ( typeof obj[ nodeName ] === 'undefined' ) { const tmp = xmlToJson( item ); @@ -593,15 +594,14 @@ return obj; - } // Taken from Base64-js - + } + // Taken from Base64-js function Base64toByteArray( b64 ) { const Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array; const revLookup = []; const code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - for ( let i = 0, l = code.length; i < l; ++ i ) { revLookup[ code.charCodeAt( i ) ] = i; @@ -611,7 +611,6 @@ revLookup[ '-'.charCodeAt( 0 ) ] = 62; revLookup[ '_'.charCodeAt( 0 ) ] = 63; const len = b64.length; - if ( len % 4 > 0 ) { throw new Error( 'Invalid string. Length must be a multiple of 4' ); @@ -623,7 +622,6 @@ const l = placeHolders > 0 ? len - 4 : len; let L = 0; let i, j; - for ( i = 0, j = 0; i < l; i += 4, j += 3 ) { const tmp = revLookup[ b64.charCodeAt( i ) ] << 18 | revLookup[ b64.charCodeAt( i + 1 ) ] << 12 | revLookup[ b64.charCodeAt( i + 2 ) ] << 6 | revLookup[ b64.charCodeAt( i + 3 ) ]; @@ -653,7 +651,6 @@ function parseDataArray( ele, compressed ) { let numBytes = 0; - if ( json.attributes.header_type === 'UInt64' ) { numBytes = 8; @@ -664,8 +661,9 @@ } - let txt, content; // Check the format + let txt, content; + // Check the format if ( ele.attributes.format === 'binary' && compressed ) { if ( ele.attributes.type === 'Float32' ) { @@ -676,7 +674,9 @@ txt = new Int32Array(); - } // VTP data with the header has the following structure: + } + + // VTP data with the header has the following structure: // [#blocks][#u-size][#p-size][#c-size-1][#c-size-2]...[#c-size-#blocks][DATA] // // Each token is an integer value whose type is specified by "header_type" at the top of the file (UInt32 if no type specified). The token meanings are: @@ -688,14 +688,13 @@ // The [DATA] portion stores contiguously every block appended together. The offset from the beginning of the data section to the beginning of a block is // computed by summing the compressed block sizes from preceding blocks according to the header. - const textNode = ele[ '#text' ]; const rawData = Array.isArray( textNode ) ? textNode[ 0 ] : textNode; - const byteData = Base64toByteArray( rawData ); // Each data point consists of 8 bits regardless of the header type + const byteData = Base64toByteArray( rawData ); + // Each data point consists of 8 bits regardless of the header type const dataPointSize = 8; let blocks = byteData[ 0 ]; - for ( let i = 1; i < numBytes - 1; i ++ ) { blocks = blocks | byteData[ i ] << i * dataPointSize; @@ -707,15 +706,14 @@ headerSize = headerSize + padding; const dataOffsets = []; let currentOffset = headerSize; - dataOffsets.push( currentOffset ); // Get the blocks sizes after the compression. - // There are three blocks before c-size-i, so we skip 3*numBytes + dataOffsets.push( currentOffset ); + // Get the blocks sizes after the compression. + // There are three blocks before c-size-i, so we skip 3*numBytes const cSizeStart = 3 * numBytes; - for ( let i = 0; i < blocks; i ++ ) { let currentBlockSize = byteData[ i * numBytes + cSizeStart ]; - for ( let j = 1; j < numBytes - 1; j ++ ) { currentBlockSize = currentBlockSize | byteData[ i * numBytes + cSizeStart + j ] << j * dataPointSize; @@ -730,9 +728,7 @@ for ( let i = 0; i < dataOffsets.length - 1; i ++ ) { const data = fflate.unzlibSync( byteData.slice( dataOffsets[ i ], dataOffsets[ i + 1 ] ) ); // eslint-disable-line no-undef - content = data.buffer; - if ( ele.attributes.type === 'Float32' ) { content = new Float32Array( content ); @@ -748,7 +744,6 @@ } delete ele[ '#text' ]; - if ( ele.attributes.type === 'Int64' ) { if ( ele.attributes.format === 'binary' ) { @@ -767,10 +762,11 @@ if ( ele.attributes.format === 'binary' && ! compressed ) { - content = Base64toByteArray( ele[ '#text' ] ); // VTP data for the uncompressed case has the following structure: + content = Base64toByteArray( ele[ '#text' ] ); + + // VTP data for the uncompressed case has the following structure: // [#bytes][DATA] // where "[#bytes]" is an integer value specifying the number of bytes in the block of data following it. - content = content.slice( numBytes ).buffer; } else { @@ -791,8 +787,9 @@ } - delete ele[ '#text' ]; // Get the content and optimize it + delete ele[ '#text' ]; + // Get the content and optimize it if ( ele.attributes.type === 'Float32' ) { txt = new Float32Array( content ); @@ -804,7 +801,6 @@ } else if ( ele.attributes.type === 'Int64' ) { txt = new Int32Array( content ); - if ( ele.attributes.format === 'binary' ) { txt = txt.filter( function ( el, idx ) { @@ -819,42 +815,42 @@ } // endif ( ele.attributes.format === 'binary' && compressed ) - return txt; - } // Main part - // Get Dom - - - const dom = new DOMParser().parseFromString( stringFile, 'application/xml' ); // Get the doc + } - const doc = dom.documentElement; // Convert to json + // Main part + // Get Dom + const dom = new DOMParser().parseFromString( stringFile, 'application/xml' ); + // Get the doc + const doc = dom.documentElement; + // Convert to json const json = xmlToJson( doc ); let points = []; let normals = []; let indices = []; - if ( json.PolyData ) { const piece = json.PolyData.Piece; - const compressed = json.attributes.hasOwnProperty( 'compressor' ); // Can be optimized - // Loop through the sections + const compressed = json.attributes.hasOwnProperty( 'compressor' ); + // Can be optimized + // Loop through the sections const sections = [ 'PointData', 'Points', 'Strips', 'Polys' ]; // +['CellData', 'Verts', 'Lines']; - let sectionIndex = 0; const numberOfSections = sections.length; - while ( sectionIndex < numberOfSections ) { - const section = piece[ sections[ sectionIndex ] ]; // If it has a DataArray in it + const section = piece[ sections[ sectionIndex ] ]; + + // If it has a DataArray in it if ( section && section.DataArray ) { // Depending on the number of DataArrays - let arr; + let arr; if ( Array.isArray( section.DataArray ) ) { arr = section.DataArray; @@ -867,7 +863,6 @@ let dataArrayIndex = 0; const numberOfDataArrays = arr.length; - while ( dataArrayIndex < numberOfDataArrays ) { // Parse the DataArray @@ -889,7 +884,6 @@ const numberOfPoints = parseInt( piece.attributes.NumberOfPoints ); const normalsName = section.attributes.Normals; - if ( numberOfPoints > 0 ) { for ( let i = 0, len = arr.length; i < len; i ++ ) { @@ -909,13 +903,12 @@ } break; - // if it is points + // if it is points case 'Points': { const numberOfPoints = parseInt( piece.attributes.NumberOfPoints ); - if ( numberOfPoints > 0 ) { const components = section.DataArray.attributes.NumberOfComponents; @@ -927,13 +920,12 @@ } break; - // if it is strips + // if it is strips case 'Strips': { const numberOfStrips = parseInt( piece.attributes.NumberOfStrips ); - if ( numberOfStrips > 0 ) { const connectivity = new Int32Array( section.DataArray[ 0 ].text.length ); @@ -943,11 +935,9 @@ const size = numberOfStrips + connectivity.length; indices = new Uint32Array( 3 * size - 9 * numberOfStrips ); let indicesIndex = 0; - for ( let i = 0, len = numberOfStrips; i < len; i ++ ) { const strip = []; - for ( let s = 0, len1 = offset[ i ], len0 = 0; s < len1 - len0; s ++ ) { strip.push( connectivity[ s ] ); @@ -982,13 +972,12 @@ } break; - // if it is polys + // if it is polys case 'Polys': { const numberOfPolys = parseInt( piece.attributes.NumberOfPolys ); - if ( numberOfPolys > 0 ) { const connectivity = new Int32Array( section.DataArray[ 0 ].text.length ); @@ -1002,13 +991,11 @@ let i = 0, len0 = 0; const len = numberOfPolys; - while ( i < len ) { const poly = []; let s = 0; const len1 = offset[ i ]; - while ( s < len1 - len0 ) { poly.push( connectivity[ connectivityIndex ++ ] ); @@ -1017,7 +1004,6 @@ } let j = 1; - while ( j < len1 - len0 - 1 ) { indices[ indicesIndex ++ ] = poly[ 0 ]; @@ -1037,7 +1023,6 @@ } break; - default: break; @@ -1052,7 +1037,6 @@ const geometry = new THREE.BufferGeometry(); geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) ); geometry.setAttribute( 'position', new THREE.BufferAttribute( points, 3 ) ); - if ( normals.length === points.length ) { geometry.setAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); @@ -1067,11 +1051,10 @@ } - } // get the 5 first lines of the files to check if there is the key word binary - + } + // get the 5 first lines of the files to check if there is the key word binary const meta = THREE.LoaderUtils.decodeText( new Uint8Array( data, 0, 250 ) ).split( '\n' ); - if ( meta[ 0 ].indexOf( 'xml' ) !== - 1 ) { return parseXML( THREE.LoaderUtils.decodeText( data ) ); diff --git a/examples/js/loaders/XYZLoader.js b/examples/js/loaders/XYZLoader.js index cdb9cea9b5f6a5..dc5fa05248c21f 100644 --- a/examples/js/loaders/XYZLoader.js +++ b/examples/js/loaders/XYZLoader.js @@ -34,23 +34,21 @@ }, onProgress, onError ); } - parse( text ) { const lines = text.split( '\n' ); const vertices = []; const colors = []; - for ( let line of lines ) { line = line.trim(); if ( line.charAt( 0 ) === '#' ) continue; // skip comments const lineValues = line.split( /\s+/ ); - if ( lineValues.length === 3 ) { // XYZ + vertices.push( parseFloat( lineValues[ 0 ] ) ); vertices.push( parseFloat( lineValues[ 1 ] ) ); vertices.push( parseFloat( lineValues[ 2 ] ) ); @@ -60,6 +58,7 @@ if ( lineValues.length === 6 ) { // XYZRGB + vertices.push( parseFloat( lineValues[ 0 ] ) ); vertices.push( parseFloat( lineValues[ 1 ] ) ); vertices.push( parseFloat( lineValues[ 2 ] ) ); @@ -73,7 +72,6 @@ const geometry = new THREE.BufferGeometry(); geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); - if ( colors.length > 0 ) { geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) ); diff --git a/examples/js/loaders/lwo/IFFParser.js b/examples/js/loaders/lwo/IFFParser.js index cf8b3fedc8e6a2..b222346c64f620 100644 --- a/examples/js/loaders/lwo/IFFParser.js +++ b/examples/js/loaders/lwo/IFFParser.js @@ -33,10 +33,10 @@ * - The entire file is contained in one top level FORM * **/ - function IFFParser() { - this.debugger = new Debugger(); // this.debugger.enable(); // un-comment to log IFF hierarchy. + this.debugger = new Debugger(); + // this.debugger.enable(); // un-comment to log IFF hierarchy. } @@ -50,23 +50,21 @@ layers: [], tags: [], textures: [] - }; // start out at the top level to add any data before first layer is encountered + }; + // start out at the top level to add any data before first layer is encountered this.currentLayer = this.tree; this.currentForm = this.tree; this.parseTopForm(); if ( this.tree.format === undefined ) return; - if ( this.tree.format === 'LWO2' ) { this.parser = new THREE.LWO2Parser( this ); - while ( ! this.reader.endOfFile() ) this.parser.parseBlock(); } else if ( this.tree.format === 'LWO3' ) { this.parser = new THREE.LWO3Parser( this ); - while ( ! this.reader.endOfFile() ) this.parser.parseBlock(); } @@ -76,12 +74,10 @@ return this.tree; }, - parseTopForm() { this.debugger.offset = this.reader.offset; var topForm = this.reader.getIDTag(); - if ( topForm !== 'FORM' ) { console.warn( 'LWOLoader: Top-level FORM missing.' ); @@ -93,7 +89,6 @@ this.debugger.dataOffset = this.reader.offset; this.debugger.length = length; var type = this.reader.getIDTag(); - if ( type === 'LWO2' ) { this.tree.format = type; @@ -110,42 +105,37 @@ return; }, - /// // FORM PARSING METHODS /// + // Forms are organisational and can contain any number of sub chunks and sub forms // FORM ::= 'FORM'[ID4], length[U4], type[ID4], ( chunk[CHUNK] | form[FORM] ) * } parseForm( length ) { var type = this.reader.getIDTag(); - switch ( type ) { // SKIPPED FORMS // if skipForm( length ) is called, the entire form and any sub forms and chunks are skipped - case 'ISEQ': // Image sequence + case 'ISEQ': // Image sequence case 'ANIM': // plug in animation - case 'STCC': // Color-cycling Still - case 'VPVL': case 'VPRM': case 'NROT': case 'WRPW': // image wrap w ( for cylindrical and spherical projections) - case 'WRPH': // image wrap h - case 'FUNC': case 'FALL': case 'OPAC': case 'GRAD': // gradient texture - case 'ENVS': case 'VMOP': - case 'VMBG': // Car Material FORMS + case 'VMBG': + // Car Material FORMS case 'OMAX': case 'STEX': case 'CKBG': @@ -154,48 +144,40 @@ case 'VMLB': this.debugger.skipped = true; this.skipForm( length ); // not currently supported - break; + // if break; is called directly, the position in the lwoTree is not created // any sub chunks and forms are added to the parent form instead - case 'META': case 'NNDS': case 'NODS': case 'NDTA': case 'ADAT': case 'AOVS': - case 'BLOK': // used by texture nodes + case 'BLOK': + // used by texture nodes case 'IBGC': // imageBackgroundColor - case 'IOPC': // imageOpacity - case 'IIMG': // hold reference to image path - case 'TXTR': // this.setupForm( type, length ); this.debugger.length = 4; this.debugger.skipped = true; break; - case 'IFAL': // imageFallof - case 'ISCL': // imageScale - case 'IPOS': // imagePosition - case 'IROT': // imageRotation - case 'IBMP': case 'IUTD': case 'IVTD': this.parseTextureNodeAttribute( type ); break; - case 'ENVL': this.parseEnvelope( length ); break; + // CLIP FORM AND SUB FORMS case 'CLIP': @@ -210,93 +192,81 @@ } break; - case 'STIL': this.parseImage(); break; - case 'XREF': // clone of another STIL this.reader.skip( 8 ); // unknown - this.currentForm.referenceTexture = { index: this.reader.getUint32(), refName: this.reader.getString() // internal unique ref - }; + break; + // Not in spec, used by texture nodes case 'IMST': this.parseImageStateForm( length ); break; + // SURF FORM AND SUB FORMS case 'SURF': this.parseSurfaceForm( length ); break; - case 'VALU': // Not in spec this.parseValueForm( length ); break; - case 'NTAG': this.parseSubNode( length ); break; - case 'ATTR': // BSDF Node Attributes - case 'SATR': // Standard Node Attributes this.setupForm( 'attributes', length ); break; - case 'NCON': this.parseConnections( length ); break; - case 'SSHA': this.parentForm = this.currentForm; this.currentForm = this.currentSurface; this.setupForm( 'surfaceShader', length ); break; - case 'SSHD': this.setupForm( 'surfaceShaderData', length ); break; - case 'ENTR': // Not in spec this.parseEntryForm( length ); break; + // Image Map Layer case 'IMAP': this.parseImageMap( length ); break; - case 'TAMP': this.parseXVAL( 'amplitude', length ); break; + //Texture Mapping Form case 'TMAP': this.setupForm( 'textureMap', length ); break; - case 'CNTR': this.parseXVAL3( 'center', length ); break; - case 'SIZE': this.parseXVAL3( 'scale', length ); break; - case 'ROTA': this.parseXVAL3( 'rotation', length ); break; - default: this.parseUnknownForm( type, length ); @@ -307,13 +277,11 @@ this.debugger.log(); }, - setupForm( type, length ) { if ( ! this.currentForm ) this.currentForm = this.currentNode; this.currentFormEnd = this.reader.offset + length; this.parentForm = this.currentForm; - if ( ! this.currentForm[ type ] ) { this.currentForm[ type ] = {}; @@ -328,13 +296,11 @@ } }, - skipForm( length ) { this.reader.skip( length - 4 ); }, - parseUnknownForm( type, length ) { console.warn( 'LWOLoader: unknown FORM encountered: ' + type, length ); @@ -342,7 +308,6 @@ this.reader.skip( length - 4 ); }, - parseSurfaceForm( length ) { this.reader.skip( 8 ); // unknown Uint32 x2 @@ -364,7 +329,6 @@ this.currentFormEnd = this.reader.offset + length; }, - parseSurfaceLwo2( length ) { var name = this.reader.getString(); @@ -383,14 +347,13 @@ this.currentFormEnd = this.reader.offset + length; }, - parseSubNode( length ) { // parse the NRNM CHUNK of the subnode FORM to get // a meaningful name for the subNode // some subnodes can be renamed, but Input and Surface cannot - this.reader.skip( 8 ); // NRNM + length + this.reader.skip( 8 ); // NRNM + length var name = this.reader.getString(); var node = { name: name @@ -400,7 +363,6 @@ this.currentFormEnd = this.reader.offset + length; }, - // collect attributes from all nodes at the top level of a surface parseConnections( length ) { @@ -409,18 +371,15 @@ this.currentForm = this.currentSurface.connections; }, - // surface node attribute data, e.g. specular, roughness etc parseEntryForm( length ) { this.reader.skip( 8 ); // NAME + length - var name = this.reader.getString(); this.currentForm = this.currentNode.attributes; this.setupForm( name, length ); }, - // parse values from material - doesn't match up to other LWO3 data types // sub form of entry form parseValueForm() { @@ -428,7 +387,6 @@ this.reader.skip( 8 ); // unknown + length var valueType = this.reader.getString(); - if ( valueType === 'double' ) { this.currentForm.value = this.reader.getUint64(); @@ -450,7 +408,6 @@ } }, - // holds various data about texture node image state // Data other thanmipMapLevel unknown parseImageStateForm() { @@ -460,7 +417,6 @@ this.currentForm.mipMapLevel = this.reader.getFloat32(); }, - // LWO2 style image data node OR LWO3 textures defined at top level in editor (not as SURF node) parseImageMap( length ) { @@ -485,27 +441,21 @@ case 'ISCL': this.currentNode.scale = this.reader.getFloat32Array( 3 ); break; - case 'IPOS': this.currentNode.position = this.reader.getFloat32Array( 3 ); break; - case 'IROT': this.currentNode.rotation = this.reader.getFloat32Array( 3 ); break; - case 'IFAL': this.currentNode.falloff = this.reader.getFloat32Array( 3 ); break; - case 'IBMP': this.currentNode.amplitude = this.reader.getFloat32(); break; - case 'IUTD': this.currentNode.uTiles = this.reader.getFloat32(); break; - case 'IVTD': this.currentNode.vTiles = this.reader.getFloat32(); break; @@ -526,21 +476,23 @@ /// // CHUNK PARSING METHODS /// + // clips can either be defined inside a surface node, or at the top // level and they have a different format in each case parseClip( length ) { - var tag = this.reader.getIDTag(); // inside surface node + var tag = this.reader.getIDTag(); + // inside surface node if ( tag === 'FORM' ) { this.reader.skip( 16 ); this.currentNode.fileName = this.reader.getString(); return; - } // otherwise top level - + } + // otherwise top level this.reader.setOffset( this.reader.offset - 4 ); this.currentFormEnd = this.reader.offset + length; this.parentForm = this.currentForm; @@ -553,19 +505,18 @@ this.currentForm = texture; }, - parseClipLwo2( length ) { var texture = { index: this.reader.getUint32(), fileName: '' - }; // seach STIL block + }; + // seach STIL block while ( true ) { var tag = this.reader.getIDTag(); var n_length = this.reader.getUint16(); - if ( tag === 'STIL' ) { texture.fileName = this.reader.getString(); @@ -585,15 +536,12 @@ this.currentForm = texture; }, - parseImage() { this.reader.skip( 8 ); // unknown - this.currentForm.fileName = this.reader.getString(); }, - parseXVAL( type, length ) { var endOffset = this.reader.offset + length - 4; @@ -615,7 +563,6 @@ this.reader.setOffset( endOffset ); }, - // Tags associated with an object // OTAG { type[ID4], tag-string[S0] } parseObjectTag() { @@ -626,7 +573,6 @@ }; }, - // Signals the start of a new layer. All the data chunks which follow will be included in this layer until another layer chunk is encountered. // LAYR: number[U2], flags[U2], pivot[VEC12], name[S0], parent[U2] parseLayer( length ) { @@ -642,8 +588,8 @@ this.tree.layers.push( layer ); this.currentLayer = layer; var parsedLength = 16 + stringOffset( this.currentLayer.name ); // index ( 2 ) + flags( 2 ) + pivot( 12 ) + stringlength - // if we have not reached then end of the layer block, there must be a parent defined + // if we have not reached then end of the layer block, there must be a parent defined this.currentLayer.parent = parsedLength < length ? this.reader.getUint16() : - 1; // omitted or -1 for no parent }, @@ -654,7 +600,6 @@ parsePoints( length ) { this.currentPoints = []; - for ( var i = 0; i < length / 4; i += 3 ) { // z -> -z to match three.js right handed coords @@ -663,10 +608,10 @@ } }, - // parse VMAP or VMAD // Associates a set of floating-point vectors with a set of points. // VMAP: { type[ID4], dimension[U2], name[S0], ( vert[VX], value[F4] # dimension ) * } + // VMAD Associates a set of floating-point vectors with the vertices of specific polygons. // Similar to VMAP UVs, but associates with polygon vertices rather than points // to solve to problem of UV seams: VMAD chunks are paired with VMAPs of the same name, @@ -677,36 +622,30 @@ var finalOffset = this.reader.offset + length; var channelName = this.reader.getString(); - if ( this.reader.offset === finalOffset ) { // then we are in a texture node and the VMAP chunk is just a reference to a UV channel name this.currentForm.UVChannel = channelName; return; - } // otherwise reset to initial length and parse normal VMAP CHUNK - + } + // otherwise reset to initial length and parse normal VMAP CHUNK this.reader.setOffset( this.reader.offset - stringOffset( channelName ) ); var type = this.reader.getIDTag(); this.reader.getUint16(); // dimension - var name = this.reader.getString(); var remainingLength = length - 6 - stringOffset( name ); - switch ( type ) { case 'TXUV': this.parseUVMapping( name, finalOffset, discontinuous ); break; - case 'MORF': case 'SPOT': this.parseMorphTargets( name, finalOffset, type ); // can't be discontinuous - break; // unsupported VMAPs - case 'APSL': case 'NORM': case 'WGHT': @@ -716,7 +655,6 @@ case 'RGBA': this.reader.skip( remainingLength ); break; - default: console.warn( 'LWOLoader: unknown vertex map type: ' + type ); this.reader.skip( remainingLength ); @@ -724,13 +662,11 @@ } }, - parseUVMapping( name, finalOffset, discontinuous ) { var uvIndices = []; var polyIndices = []; var uvs = []; - while ( this.reader.offset < finalOffset ) { uvIndices.push( this.reader.getVariableLengthIndex() ); @@ -759,17 +695,15 @@ } }, - parseMorphTargets( name, finalOffset, type ) { var indices = []; var points = []; type = type === 'MORF' ? 'relative' : 'absolute'; - while ( this.reader.offset < finalOffset ) { - indices.push( this.reader.getVariableLengthIndex() ); // z -> -z to match three.js right handed coords - + indices.push( this.reader.getVariableLengthIndex() ); + // z -> -z to match three.js right handed coords points.push( this.reader.getFloat32(), this.reader.getFloat32(), - this.reader.getFloat32() ); } @@ -782,25 +716,23 @@ }; }, - // A list of polygons for the current layer. // POLS { type[ID4], ( numvert+flags[U2], vert[VX] # numvert ) * } parsePolygonList( length ) { var finalOffset = this.reader.offset + length; var type = this.reader.getIDTag(); - var indices = []; // hold a list of polygon sizes, to be split up later + var indices = []; + // hold a list of polygon sizes, to be split up later var polygonDimensions = []; - while ( this.reader.offset < finalOffset ) { - var numverts = this.reader.getUint16(); //var flags = numverts & 64512; // 6 high order bits are flags - ignoring for now + var numverts = this.reader.getUint16(); + //var flags = numverts & 64512; // 6 high order bits are flags - ignoring for now numverts = numverts & 1023; // remaining ten low order bits are vertex num - polygonDimensions.push( numverts ); - for ( var j = 0; j < numverts; j ++ ) indices.push( this.reader.getVariableLengthIndex() ); } @@ -810,13 +742,13 @@ vertexIndices: indices, polygonDimensions: polygonDimensions, points: this.currentPoints - }; // Note: assuming that all polys will be lines or points if the first is + }; + // Note: assuming that all polys will be lines or points if the first is if ( polygonDimensions[ 0 ] === 1 ) geometryData.type = 'points'; else if ( polygonDimensions[ 0 ] === 2 ) geometryData.type = 'lines'; this.currentLayer.geometry = geometryData; }, - // Lists the tag strings that can be associated with polygons by the PTAG chunk. // TAGS { tag-string[S0] * } parseTagStrings( length ) { @@ -824,7 +756,6 @@ this.tree.tags = this.reader.getStringArray( length ); }, - // Associates tags of a given type with polygons in the most recent POLS chunk. // PTAG { type[ID4], ( poly[VX], tag[U2] ) * } parsePolygonTagMapping( length ) { @@ -834,17 +765,16 @@ if ( type === 'SURF' ) this.parseMaterialIndices( finalOffset ); else { //PART, SMGP, COLR not supported + this.reader.skip( length - 4 ); } }, - parseMaterialIndices( finalOffset ) { // array holds polygon index followed by material index this.currentLayer.geometry.materialIndices = []; - while ( this.reader.offset < finalOffset ) { var polygonIndex = this.reader.getVariableLengthIndex(); @@ -854,19 +784,18 @@ } }, - parseUnknownCHUNK( blockID, length ) { - console.warn( 'LWOLoader: unknown chunk type: ' + blockID + ' length: ' + length ); // print the chunk plus some bytes padding either side + console.warn( 'LWOLoader: unknown chunk type: ' + blockID + ' length: ' + length ); + + // print the chunk plus some bytes padding either side // printBuffer( this.reader.dv.buffer, this.reader.offset - 20, length + 40 ); var data = this.reader.getString( length ); this.currentForm[ blockID ] = data; } - }; - function DataViewReader( buffer ) { this.dv = new DataView( buffer ); @@ -881,7 +810,6 @@ return this.dv.buffer.byteLength; }, - setOffset( offset ) { if ( offset > 0 && offset < this.dv.buffer.byteLength ) { @@ -895,7 +823,6 @@ } }, - endOfFile: function () { if ( this.offset >= this.size() ) return true; @@ -953,7 +880,6 @@ getFloat32Array: function ( size ) { var a = []; - for ( var i = 0; i < size; i ++ ) { a.push( this.getFloat32() ); @@ -973,7 +899,6 @@ getFloat64Array: function ( size ) { var a = []; - for ( var i = 0; i < size; i ++ ) { a.push( this.getFloat64() ); @@ -983,7 +908,6 @@ return a; }, - // get variable-length index data type // VX ::= index[U2] | (index + 0xFF000000)[U4] // If the index value is less than 65,280 (0xFF00),then VX === U2 @@ -993,7 +917,6 @@ getVariableLengthIndex() { var firstByte = this.getUint8(); - if ( firstByte === 255 ) { return this.getUint8() * 65536 + this.getUint8() * 256 + this.getUint8(); @@ -1003,20 +926,18 @@ return firstByte * 256 + this.getUint8(); }, - // An ID tag is a sequence of 4 bytes containing 7-bit ASCII values getIDTag() { return this.getString( 4 ); }, - getString: function ( size ) { - if ( size === 0 ) return; // note: safari 9 doesn't support Uint8Array.indexOf; create intermediate array instead + if ( size === 0 ) return; + // note: safari 9 doesn't support Uint8Array.indexOf; create intermediate array instead var a = []; - if ( size ) { for ( var i = 0; i < size; i ++ ) { @@ -1029,7 +950,6 @@ var currentChar; var len = 0; - while ( currentChar !== 0 ) { currentChar = this.getUint8(); @@ -1052,7 +972,9 @@ return a.filter( Boolean ); // return array with any empty strings removed } - }; // ************** DEBUGGER ************** + }; + + // ************** DEBUGGER ************** function Debugger() { @@ -1073,17 +995,14 @@ if ( ! this.active ) return; var nodeType; - switch ( this.node ) { case 0: nodeType = 'FORM'; break; - case 1: nodeType = 'CHK'; break; - case 2: nodeType = 'S-CHK'; break; @@ -1091,7 +1010,6 @@ } console.log( '| '.repeat( this.depth ) + nodeType, this.nodeID, `( ${this.offset} ) -> ( ${this.dataOffset + this.length} )`, this.node == 0 ? ' {' : '', this.skipped ? 'SKIPPED' : '', this.node == 0 && this.skipped ? '}' : '' ); - if ( this.node == 0 && ! this.skipped ) { this.depth += 1; @@ -1105,7 +1023,6 @@ closeForms: function () { if ( ! this.active ) return; - for ( var i = this.formList.length - 1; i >= 0; i -- ) { if ( this.offset >= this.formList[ i ] ) { @@ -1119,24 +1036,26 @@ } } - }; // ************** UTILITY FUNCTIONS ************** + }; + + // ************** UTILITY FUNCTIONS ************** function isEven( num ) { return num % 2; - } // calculate the length of the string in the buffer - // this will be string.length + nullbyte + optional padbyte to make the length even - + } + // calculate the length of the string in the buffer + // this will be string.length + nullbyte + optional padbyte to make the length even function stringOffset( string ) { return string.length + 1 + ( isEven( string.length + 1 ) ? 1 : 0 ); - } // for testing purposes, dump buffer to console - // printBuffer( this.reader.dv.buffer, this.reader.offset, length ); - + } + // for testing purposes, dump buffer to console + // printBuffer( this.reader.dv.buffer, this.reader.offset, length ); function printBuffer( buffer, from, to ) { console.log( THREE.LoaderUtils.decodeText( new Uint8Array( buffer, from, to ) ) ); diff --git a/examples/js/loaders/lwo/LWO2Parser.js b/examples/js/loaders/lwo/LWO2Parser.js index 59f2dc34ae4aec..e08ff3cc4f5c0a 100644 --- a/examples/js/loaders/lwo/LWO2Parser.js +++ b/examples/js/loaders/lwo/LWO2Parser.js @@ -7,14 +7,12 @@ this.IFF = IFFParser; } - parseBlock() { this.IFF.debugger.offset = this.IFF.reader.offset; this.IFF.debugger.closeForms(); const blockID = this.IFF.reader.getIDTag(); let length = this.IFF.reader.getUint32(); // size of data in bytes - if ( length > this.IFF.reader.dv.byteLength - this.IFF.reader.offset ) { this.IFF.reader.offset -= 4; @@ -23,35 +21,36 @@ } this.IFF.debugger.dataOffset = this.IFF.reader.offset; - this.IFF.debugger.length = length; // Data types may be found in either LWO2 OR LWO3 spec + this.IFF.debugger.length = length; + // Data types may be found in either LWO2 OR LWO3 spec switch ( blockID ) { case 'FORM': // form blocks may consist of sub -chunks or sub-forms this.IFF.parseForm( length ); break; + // SKIPPED CHUNKS // if break; is called directly, the position in the lwoTree is not created // any sub chunks and forms are added to the parent form instead // MISC skipped - case 'ICON': // Thumbnail Icon Image - case 'VMPA': // Vertex Map Parameter - case 'BBOX': // bounding box // case 'VMMD': // case 'VTYP': - // normal maps can be specified, normally on models imported from other applications. Currently ignored - case 'NORM': // ENVL FORM skipped + // normal maps can be specified, normally on models imported from other applications. Currently ignored + case 'NORM': + // ENVL FORM skipped case 'PRE ': case 'POST': case 'KEY ': - case 'SPAN': // CLIP FORM skipped + case 'SPAN': + // CLIP FORM skipped case 'TIME': case 'CLRS': case 'CLRA': @@ -64,46 +63,47 @@ case 'GAMM': case 'NEGA': case 'IFLT': - case 'PFLT': // Image Map Layer skipped + case 'PFLT': + // Image Map Layer skipped case 'PROJ': case 'AXIS': case 'AAST': case 'PIXB': case 'AUVO': - case 'STCK': // Procedural Textures skipped + case 'STCK': + // Procedural Textures skipped case 'PROC': case 'VALU': - case 'FUNC': // Gradient Textures skipped + case 'FUNC': + // Gradient Textures skipped case 'PNAM': case 'INAM': case 'GRST': case 'GREN': case 'GRPT': case 'FKEY': - case 'IKEY': // Texture Mapping Form skipped + case 'IKEY': - case 'CSYS': // Surface CHUNKs skipped + // Texture Mapping Form skipped + case 'CSYS': + // Surface CHUNKs skipped case 'OPAQ': // top level 'opacity' checkbox - case 'CMAP': // clip map + // Surface node CHUNKS skipped // These mainly specify the node editor setup in LW - case 'NLOC': case 'NZOM': case 'NVER': case 'NSRV': case 'NVSK': // unknown - case 'NCRD': case 'WRPW': // image wrap w ( for cylindrical and spherical projections) - case 'WRPH': // image wrap h - case 'NMOD': case 'NSEL': case 'NPRW': @@ -112,8 +112,9 @@ case 'VERS': case 'ENUM': case 'TAG ': - case 'OPAC': // Car Material CHUNKS + case 'OPAC': + // Car Material CHUNKS case 'CGMD': case 'CGTY': case 'CGST': @@ -127,7 +128,6 @@ case 'TRNL': case 'GLOW': case 'GVAL': // glow intensity - case 'SHRP': case 'RFOP': case 'RSAN': @@ -144,34 +144,23 @@ this.IFF.debugger.skipped = true; this.IFF.reader.skip( length ); break; - case 'SURF': this.IFF.parseSurfaceLwo2( length ); break; - case 'CLIP': this.IFF.parseClipLwo2( length ); break; - // Texture node chunks (not in spec) + // Texture node chunks (not in spec) case 'IPIX': // usePixelBlending - case 'IMIP': // useMipMaps - case 'IMOD': // imageBlendingMode - case 'AMOD': // unknown - case 'IINV': // imageInvertAlpha - case 'INCR': // imageInvertColor - case 'IAXS': // imageAxis ( for non-UV maps) - case 'IFOT': // imageFallofType - case 'ITIM': // timing for animated textures - case 'IWRL': case 'IUTI': case 'IINX': @@ -181,245 +170,205 @@ // possibly a VX for reused texture nodes if ( length === 4 ) this.IFF.currentNode[ blockID ] = this.IFF.reader.getInt32(); else this.IFF.reader.skip( length ); break; - case 'OTAG': this.IFF.parseObjectTag(); break; - case 'LAYR': this.IFF.parseLayer( length ); break; - case 'PNTS': this.IFF.parsePoints( length ); break; - case 'VMAP': this.IFF.parseVertexMapping( length ); break; - case 'AUVU': case 'AUVN': this.IFF.reader.skip( length - 1 ); this.IFF.reader.getVariableLengthIndex(); // VX - break; - case 'POLS': this.IFF.parsePolygonList( length ); break; - case 'TAGS': this.IFF.parseTagStrings( length ); break; - case 'PTAG': this.IFF.parsePolygonTagMapping( length ); break; - case 'VMAD': this.IFF.parseVertexMapping( length, true ); break; - // Misc CHUNKS + // Misc CHUNKS case 'DESC': // Description Line this.IFF.currentForm.description = this.IFF.reader.getString(); break; - case 'TEXT': case 'CMNT': case 'NCOM': this.IFF.currentForm.comment = this.IFF.reader.getString(); break; - // Envelope Form + // Envelope Form case 'NAME': this.IFF.currentForm.channelName = this.IFF.reader.getString(); break; - // Image Map Layer + // Image Map Layer case 'WRAP': this.IFF.currentForm.wrap = { w: this.IFF.reader.getUint16(), h: this.IFF.reader.getUint16() }; break; - case 'IMAG': const index = this.IFF.reader.getVariableLengthIndex(); this.IFF.currentForm.imageIndex = index; break; - // Texture Mapping Form + // Texture Mapping Form case 'OREF': this.IFF.currentForm.referenceObject = this.IFF.reader.getString(); break; - case 'ROID': this.IFF.currentForm.referenceObjectID = this.IFF.reader.getUint32(); break; - // Surface Blocks + // Surface Blocks case 'SSHN': this.IFF.currentSurface.surfaceShaderName = this.IFF.reader.getString(); break; - case 'AOVN': this.IFF.currentSurface.surfaceCustomAOVName = this.IFF.reader.getString(); break; - // Nodal Blocks + // Nodal Blocks case 'NSTA': this.IFF.currentForm.disabled = this.IFF.reader.getUint16(); break; - case 'NRNM': this.IFF.currentForm.realName = this.IFF.reader.getString(); break; - case 'NNME': this.IFF.currentForm.refName = this.IFF.reader.getString(); this.IFF.currentSurface.nodes[ this.IFF.currentForm.refName ] = this.IFF.currentForm; break; - // Nodal Blocks : connections + // Nodal Blocks : connections case 'INME': if ( ! this.IFF.currentForm.nodeName ) this.IFF.currentForm.nodeName = []; this.IFF.currentForm.nodeName.push( this.IFF.reader.getString() ); break; - case 'IINN': if ( ! this.IFF.currentForm.inputNodeName ) this.IFF.currentForm.inputNodeName = []; this.IFF.currentForm.inputNodeName.push( this.IFF.reader.getString() ); break; - case 'IINM': if ( ! this.IFF.currentForm.inputName ) this.IFF.currentForm.inputName = []; this.IFF.currentForm.inputName.push( this.IFF.reader.getString() ); break; - case 'IONM': if ( ! this.IFF.currentForm.inputOutputName ) this.IFF.currentForm.inputOutputName = []; this.IFF.currentForm.inputOutputName.push( this.IFF.reader.getString() ); break; - case 'FNAM': this.IFF.currentForm.fileName = this.IFF.reader.getString(); break; - case 'CHAN': // NOTE: ENVL Forms may also have CHAN chunk, however ENVL is currently ignored if ( length === 4 ) this.IFF.currentForm.textureChannel = this.IFF.reader.getIDTag(); else this.IFF.reader.skip( length ); break; - // LWO2 Spec chunks: these are needed since the SURF FORMs are often in LWO2 format + // LWO2 Spec chunks: these are needed since the SURF FORMs are often in LWO2 format case 'SMAN': const maxSmoothingAngle = this.IFF.reader.getFloat32(); this.IFF.currentSurface.attributes.smooth = maxSmoothingAngle < 0 ? false : true; break; - // LWO2: Basic Surface Parameters + // LWO2: Basic Surface Parameters case 'COLR': this.IFF.currentSurface.attributes.Color = { value: this.IFF.reader.getFloat32Array( 3 ) }; this.IFF.reader.skip( 2 ); // VX: envelope - break; - case 'LUMI': this.IFF.currentSurface.attributes.Luminosity = { value: this.IFF.reader.getFloat32() }; this.IFF.reader.skip( 2 ); break; - case 'SPEC': this.IFF.currentSurface.attributes.Specular = { value: this.IFF.reader.getFloat32() }; this.IFF.reader.skip( 2 ); break; - case 'DIFF': this.IFF.currentSurface.attributes.Diffuse = { value: this.IFF.reader.getFloat32() }; this.IFF.reader.skip( 2 ); break; - case 'REFL': this.IFF.currentSurface.attributes.Reflection = { value: this.IFF.reader.getFloat32() }; this.IFF.reader.skip( 2 ); break; - case 'GLOS': this.IFF.currentSurface.attributes.Glossiness = { value: this.IFF.reader.getFloat32() }; this.IFF.reader.skip( 2 ); break; - case 'TRAN': this.IFF.currentSurface.attributes.opacity = this.IFF.reader.getFloat32(); this.IFF.reader.skip( 2 ); break; - case 'BUMP': this.IFF.currentSurface.attributes.bumpStrength = this.IFF.reader.getFloat32(); this.IFF.reader.skip( 2 ); break; - case 'SIDE': this.IFF.currentSurface.attributes.side = this.IFF.reader.getUint16(); break; - case 'RIMG': this.IFF.currentSurface.attributes.reflectionMap = this.IFF.reader.getVariableLengthIndex(); break; - case 'RIND': this.IFF.currentSurface.attributes.refractiveIndex = this.IFF.reader.getFloat32(); this.IFF.reader.skip( 2 ); break; - case 'TIMG': this.IFF.currentSurface.attributes.refractionMap = this.IFF.reader.getVariableLengthIndex(); break; - case 'IMAP': this.IFF.reader.skip( 2 ); break; - case 'TMAP': this.IFF.debugger.skipped = true; this.IFF.reader.skip( length ); // needs implementing - break; - case 'IUVI': // uv channel name this.IFF.currentNode.UVChannel = this.IFF.reader.getString( length ); break; - case 'IUTL': // widthWrappingMode: 0 = Reset, 1 = Repeat, 2 = Mirror, 3 = Edge this.IFF.currentNode.widthWrappingMode = this.IFF.reader.getUint32(); break; - case 'IVTL': // heightWrappingMode this.IFF.currentNode.heightWrappingMode = this.IFF.reader.getUint32(); break; - // LWO2 USE + // LWO2 USE case 'BLOK': // skip break; - default: this.IFF.parseUnknownCHUNK( blockID, length ); diff --git a/examples/js/loaders/lwo/LWO3Parser.js b/examples/js/loaders/lwo/LWO3Parser.js index 9e2cfe87e41b27..e680d087341f28 100644 --- a/examples/js/loaders/lwo/LWO3Parser.js +++ b/examples/js/loaders/lwo/LWO3Parser.js @@ -7,7 +7,6 @@ this.IFF = IFFParser; } - parseBlock() { this.IFF.debugger.offset = this.IFF.reader.offset; @@ -16,35 +15,34 @@ const length = this.IFF.reader.getUint32(); // size of data in bytes this.IFF.debugger.dataOffset = this.IFF.reader.offset; - this.IFF.debugger.length = length; // Data types may be found in either LWO2 OR LWO3 spec + this.IFF.debugger.length = length; + // Data types may be found in either LWO2 OR LWO3 spec switch ( blockID ) { case 'FORM': // form blocks may consist of sub -chunks or sub-forms this.IFF.parseForm( length ); break; + // SKIPPED CHUNKS // MISC skipped - case 'ICON': // Thumbnail Icon Image - case 'VMPA': // Vertex Map Parameter - case 'BBOX': // bounding box // case 'VMMD': // case 'VTYP': - // normal maps can be specified, normally on models imported from other applications. Currently ignored - case 'NORM': // ENVL FORM skipped + // normal maps can be specified, normally on models imported from other applications. Currently ignored + case 'NORM': + // ENVL FORM skipped case 'PRE ': // Pre-loop behavior for the keyframe - case 'POST': // Post-loop behavior for the keyframe - case 'KEY ': - case 'SPAN': // CLIP FORM skipped + case 'SPAN': + // CLIP FORM skipped case 'TIME': case 'CLRS': case 'CLRA': @@ -57,32 +55,36 @@ case 'GAMM': case 'NEGA': case 'IFLT': - case 'PFLT': // Image Map Layer skipped + case 'PFLT': + // Image Map Layer skipped case 'PROJ': case 'AXIS': case 'AAST': case 'PIXB': - case 'STCK': // Procedural Textures skipped + case 'STCK': - case 'VALU': // Gradient Textures skipped + // Procedural Textures skipped + case 'VALU': + // Gradient Textures skipped case 'PNAM': case 'INAM': case 'GRST': case 'GREN': case 'GRPT': case 'FKEY': - case 'IKEY': // Texture Mapping Form skipped + case 'IKEY': - case 'CSYS': // Surface CHUNKs skipped + // Texture Mapping Form skipped + case 'CSYS': + // Surface CHUNKs skipped case 'OPAQ': // top level 'opacity' checkbox - case 'CMAP': // clip map + // Surface node CHUNKS skipped // These mainly specify the node editor setup in LW - case 'NLOC': case 'NZOM': case 'NVER': @@ -94,8 +96,9 @@ case 'NPLA': case 'VERS': case 'ENUM': - case 'TAG ': // Car Material CHUNKS + case 'TAG ': + // Car Material CHUNKS case 'CGMD': case 'CGTY': case 'CGST': @@ -124,26 +127,17 @@ this.IFF.debugger.skipped = true; this.IFF.reader.skip( length ); break; - // Texture node chunks (not in spec) + // Texture node chunks (not in spec) case 'IPIX': // usePixelBlending - case 'IMIP': // useMipMaps - case 'IMOD': // imageBlendingMode - case 'AMOD': // unknown - case 'IINV': // imageInvertAlpha - case 'INCR': // imageInvertColor - case 'IAXS': // imageAxis ( for non-UV maps) - case 'IFOT': // imageFallofType - case 'ITIM': // timing for animated textures - case 'IWRL': case 'IUTI': case 'IINX': @@ -153,227 +147,191 @@ // possibly a VX for reused texture nodes if ( length === 4 ) this.IFF.currentNode[ blockID ] = this.IFF.reader.getInt32(); else this.IFF.reader.skip( length ); break; - case 'OTAG': this.IFF.parseObjectTag(); break; - case 'LAYR': this.IFF.parseLayer( length ); break; - case 'PNTS': this.IFF.parsePoints( length ); break; - case 'VMAP': this.IFF.parseVertexMapping( length ); break; - case 'POLS': this.IFF.parsePolygonList( length ); break; - case 'TAGS': this.IFF.parseTagStrings( length ); break; - case 'PTAG': this.IFF.parsePolygonTagMapping( length ); break; - case 'VMAD': this.IFF.parseVertexMapping( length, true ); break; - // Misc CHUNKS + // Misc CHUNKS case 'DESC': // Description Line this.IFF.currentForm.description = this.IFF.reader.getString(); break; - case 'TEXT': case 'CMNT': case 'NCOM': this.IFF.currentForm.comment = this.IFF.reader.getString(); break; - // Envelope Form + // Envelope Form case 'NAME': this.IFF.currentForm.channelName = this.IFF.reader.getString(); break; - // Image Map Layer + // Image Map Layer case 'WRAP': this.IFF.currentForm.wrap = { w: this.IFF.reader.getUint16(), h: this.IFF.reader.getUint16() }; break; - case 'IMAG': const index = this.IFF.reader.getVariableLengthIndex(); this.IFF.currentForm.imageIndex = index; break; - // Texture Mapping Form + // Texture Mapping Form case 'OREF': this.IFF.currentForm.referenceObject = this.IFF.reader.getString(); break; - case 'ROID': this.IFF.currentForm.referenceObjectID = this.IFF.reader.getUint32(); break; - // Surface Blocks + // Surface Blocks case 'SSHN': this.IFF.currentSurface.surfaceShaderName = this.IFF.reader.getString(); break; - case 'AOVN': this.IFF.currentSurface.surfaceCustomAOVName = this.IFF.reader.getString(); break; - // Nodal Blocks + // Nodal Blocks case 'NSTA': this.IFF.currentForm.disabled = this.IFF.reader.getUint16(); break; - case 'NRNM': this.IFF.currentForm.realName = this.IFF.reader.getString(); break; - case 'NNME': this.IFF.currentForm.refName = this.IFF.reader.getString(); this.IFF.currentSurface.nodes[ this.IFF.currentForm.refName ] = this.IFF.currentForm; break; - // Nodal Blocks : connections + // Nodal Blocks : connections case 'INME': if ( ! this.IFF.currentForm.nodeName ) this.IFF.currentForm.nodeName = []; this.IFF.currentForm.nodeName.push( this.IFF.reader.getString() ); break; - case 'IINN': if ( ! this.IFF.currentForm.inputNodeName ) this.IFF.currentForm.inputNodeName = []; this.IFF.currentForm.inputNodeName.push( this.IFF.reader.getString() ); break; - case 'IINM': if ( ! this.IFF.currentForm.inputName ) this.IFF.currentForm.inputName = []; this.IFF.currentForm.inputName.push( this.IFF.reader.getString() ); break; - case 'IONM': if ( ! this.IFF.currentForm.inputOutputName ) this.IFF.currentForm.inputOutputName = []; this.IFF.currentForm.inputOutputName.push( this.IFF.reader.getString() ); break; - case 'FNAM': this.IFF.currentForm.fileName = this.IFF.reader.getString(); break; - case 'CHAN': // NOTE: ENVL Forms may also have CHAN chunk, however ENVL is currently ignored if ( length === 4 ) this.IFF.currentForm.textureChannel = this.IFF.reader.getIDTag(); else this.IFF.reader.skip( length ); break; - // LWO2 Spec chunks: these are needed since the SURF FORMs are often in LWO2 format + // LWO2 Spec chunks: these are needed since the SURF FORMs are often in LWO2 format case 'SMAN': const maxSmoothingAngle = this.IFF.reader.getFloat32(); this.IFF.currentSurface.attributes.smooth = maxSmoothingAngle < 0 ? false : true; break; - // LWO2: Basic Surface Parameters + // LWO2: Basic Surface Parameters case 'COLR': this.IFF.currentSurface.attributes.Color = { value: this.IFF.reader.getFloat32Array( 3 ) }; this.IFF.reader.skip( 2 ); // VX: envelope - break; - case 'LUMI': this.IFF.currentSurface.attributes.Luminosity = { value: this.IFF.reader.getFloat32() }; this.IFF.reader.skip( 2 ); break; - case 'SPEC': this.IFF.currentSurface.attributes.Specular = { value: this.IFF.reader.getFloat32() }; this.IFF.reader.skip( 2 ); break; - case 'DIFF': this.IFF.currentSurface.attributes.Diffuse = { value: this.IFF.reader.getFloat32() }; this.IFF.reader.skip( 2 ); break; - case 'REFL': this.IFF.currentSurface.attributes.Reflection = { value: this.IFF.reader.getFloat32() }; this.IFF.reader.skip( 2 ); break; - case 'GLOS': this.IFF.currentSurface.attributes.Glossiness = { value: this.IFF.reader.getFloat32() }; this.IFF.reader.skip( 2 ); break; - case 'TRAN': this.IFF.currentSurface.attributes.opacity = this.IFF.reader.getFloat32(); this.IFF.reader.skip( 2 ); break; - case 'BUMP': this.IFF.currentSurface.attributes.bumpStrength = this.IFF.reader.getFloat32(); this.IFF.reader.skip( 2 ); break; - case 'SIDE': this.IFF.currentSurface.attributes.side = this.IFF.reader.getUint16(); break; - case 'RIMG': this.IFF.currentSurface.attributes.reflectionMap = this.IFF.reader.getVariableLengthIndex(); break; - case 'RIND': this.IFF.currentSurface.attributes.refractiveIndex = this.IFF.reader.getFloat32(); this.IFF.reader.skip( 2 ); break; - case 'TIMG': this.IFF.currentSurface.attributes.refractionMap = this.IFF.reader.getVariableLengthIndex(); break; - case 'IMAP': this.IFF.currentSurface.attributes.imageMapIndex = this.IFF.reader.getUint32(); break; - case 'IUVI': // uv channel name this.IFF.currentNode.UVChannel = this.IFF.reader.getString( length ); break; - case 'IUTL': // widthWrappingMode: 0 = Reset, 1 = Repeat, 2 = Mirror, 3 = Edge this.IFF.currentNode.widthWrappingMode = this.IFF.reader.getUint32(); break; - case 'IVTL': // heightWrappingMode this.IFF.currentNode.heightWrappingMode = this.IFF.reader.getUint32(); break; - default: this.IFF.parseUnknownCHUNK( blockID, length ); diff --git a/examples/js/materials/MeshGouraudMaterial.js b/examples/js/materials/MeshGouraudMaterial.js new file mode 100644 index 00000000000000..ba6e958008ee85 --- /dev/null +++ b/examples/js/materials/MeshGouraudMaterial.js @@ -0,0 +1,387 @@ +( function () { + + /** + * MeshGouraudMaterial + * + * Lambert illumination model with Gouraud (per-vertex) shading + * + */ + const GouraudShader = { + uniforms: THREE.UniformsUtils.merge( [ THREE.UniformsLib.common, THREE.UniformsLib.specularmap, THREE.UniformsLib.envmap, THREE.UniformsLib.aomap, THREE.UniformsLib.lightmap, THREE.UniformsLib.emissivemap, THREE.UniformsLib.fog, THREE.UniformsLib.lights, { + emissive: { + value: new THREE.Color( 0x000000 ) + } + } ] ), + vertexShader: /* glsl */` + + #define GOURAUD + + varying vec3 vLightFront; + varying vec3 vIndirectFront; + + #ifdef DOUBLE_SIDED + varying vec3 vLightBack; + varying vec3 vIndirectBack; + #endif + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + void main() { + + #include + #include + #include + #include + + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + + #include + #include + + // inlining legacy + + vec3 diffuse = vec3( 1.0 ); + + GeometricContext geometry; + geometry.position = mvPosition.xyz; + geometry.normal = normalize( transformedNormal ); + geometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz ); + + GeometricContext backGeometry; + backGeometry.position = geometry.position; + backGeometry.normal = -geometry.normal; + backGeometry.viewDir = geometry.viewDir; + + vLightFront = vec3( 0.0 ); + vIndirectFront = vec3( 0.0 ); + #ifdef DOUBLE_SIDED + vLightBack = vec3( 0.0 ); + vIndirectBack = vec3( 0.0 ); + #endif + + IncidentLight directLight; + float dotNL; + vec3 directLightColor_Diffuse; + + vIndirectFront += getAmbientLightIrradiance( ambientLightColor ); + + vIndirectFront += getLightProbeIrradiance( lightProbe, geometry.normal ); + + #ifdef DOUBLE_SIDED + + vIndirectBack += getAmbientLightIrradiance( ambientLightColor ); + + vIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry.normal ); + + #endif + + #if NUM_POINT_LIGHTS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) { + + getPointLightInfo( pointLights[ i ], geometry, directLight ); + + dotNL = dot( geometry.normal, directLight.direction ); + directLightColor_Diffuse = directLight.color; + + vLightFront += saturate( dotNL ) * directLightColor_Diffuse; + + #ifdef DOUBLE_SIDED + + vLightBack += saturate( - dotNL ) * directLightColor_Diffuse; + + #endif + + } + #pragma unroll_loop_end + + #endif + + #if NUM_SPOT_LIGHTS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) { + + getSpotLightInfo( spotLights[ i ], geometry, directLight ); + + dotNL = dot( geometry.normal, directLight.direction ); + directLightColor_Diffuse = directLight.color; + + vLightFront += saturate( dotNL ) * directLightColor_Diffuse; + + #ifdef DOUBLE_SIDED + + vLightBack += saturate( - dotNL ) * directLightColor_Diffuse; + + #endif + } + #pragma unroll_loop_end + + #endif + + #if NUM_DIR_LIGHTS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) { + + getDirectionalLightInfo( directionalLights[ i ], geometry, directLight ); + + dotNL = dot( geometry.normal, directLight.direction ); + directLightColor_Diffuse = directLight.color; + + vLightFront += saturate( dotNL ) * directLightColor_Diffuse; + + #ifdef DOUBLE_SIDED + + vLightBack += saturate( - dotNL ) * directLightColor_Diffuse; + + #endif + + } + #pragma unroll_loop_end + + #endif + + #if NUM_HEMI_LIGHTS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) { + + vIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal ); + + #ifdef DOUBLE_SIDED + + vIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry.normal ); + + #endif + + } + #pragma unroll_loop_end + + #endif + + #include + #include + + }`, + fragmentShader: /* glsl */` + + #define GOURAUD + + uniform vec3 diffuse; + uniform vec3 emissive; + uniform float opacity; + + varying vec3 vLightFront; + varying vec3 vIndirectFront; + + #ifdef DOUBLE_SIDED + varying vec3 vLightBack; + varying vec3 vIndirectBack; + #endif + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + void main() { + + #include + + vec4 diffuseColor = vec4( diffuse, opacity ); + ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); + vec3 totalEmissiveRadiance = emissive; + + #include + #include + #include + #include + #include + #include + #include + + // accumulation + + #ifdef DOUBLE_SIDED + + reflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack; + + #else + + reflectedLight.indirectDiffuse += vIndirectFront; + + #endif + + #include + + reflectedLight.indirectDiffuse *= BRDF_Lambert( diffuseColor.rgb ); + + #ifdef DOUBLE_SIDED + + reflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack; + + #else + + reflectedLight.directDiffuse = vLightFront; + + #endif + + reflectedLight.directDiffuse *= BRDF_Lambert( diffuseColor.rgb ) * getShadowMask(); + + // modulation + + #include + + vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance; + + #include + + #include + #include + #include + #include + #include + #include + + }` + }; + + // + + class MeshGouraudMaterial extends THREE.ShaderMaterial { + + constructor( parameters ) { + + super(); + this.isMeshGouraudMaterial = true; + this.type = 'MeshGouraudMaterial'; + + //this.color = new THREE.Color( 0xffffff ); // diffuse + + //this.map = null; + + //this.lightMap = null; + //this.lightMapIntensity = 1.0; + + //this.aoMap = null; + //this.aoMapIntensity = 1.0; + + //this.emissive = new THREE.Color( 0x000000 ); + //this.emissiveIntensity = 1.0; + //this.emissiveMap = null; + + //this.specularMap = null; + + //this.alphaMap = null; + + //this.envMap = null; + this.combine = THREE.MultiplyOperation; // combine has no uniform + //this.reflectivity = 1; + //this.refractionRatio = 0.98; + + this.fog = false; // set to use scene fog + this.lights = true; // set to use scene lights + this.clipping = false; // set to use user-defined clipping planes + + const shader = GouraudShader; + this.defines = Object.assign( {}, shader.defines ); + this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); + this.vertexShader = shader.vertexShader; + this.fragmentShader = shader.fragmentShader; + const exposePropertyNames = [ 'map', 'lightMap', 'lightMapIntensity', 'aoMap', 'aoMapIntensity', 'emissive', 'emissiveIntensity', 'emissiveMap', 'specularMap', 'alphaMap', 'envMap', 'reflectivity', 'refractionRatio', 'opacity', 'diffuse' ]; + for ( const propertyName of exposePropertyNames ) { + + Object.defineProperty( this, propertyName, { + get: function () { + + return this.uniforms[ propertyName ].value; + + }, + set: function ( value ) { + + this.uniforms[ propertyName ].value = value; + + } + } ); + + } + + Object.defineProperty( this, 'color', Object.getOwnPropertyDescriptor( this, 'diffuse' ) ); + this.setValues( parameters ); + + } + copy( source ) { + + super.copy( 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.fog = source.fog; + return this; + + } + + } + + THREE.MeshGouraudMaterial = MeshGouraudMaterial; + +} )(); diff --git a/examples/js/math/Capsule.js b/examples/js/math/Capsule.js index fc83e7e06ef7b8..d4813013c20aef 100644 --- a/examples/js/math/Capsule.js +++ b/examples/js/math/Capsule.js @@ -1,13 +1,9 @@ ( function () { const _v1 = new THREE.Vector3(); - const _v2 = new THREE.Vector3(); - const _v3 = new THREE.Vector3(); - const EPS = 1e-10; - class Capsule { constructor( start = new THREE.Vector3( 0, 0, 0 ), end = new THREE.Vector3( 0, 1, 0 ), radius = 1 ) { @@ -17,13 +13,11 @@ this.radius = radius; } - clone() { return new Capsule( this.start.clone(), this.end.clone(), this.radius ); } - set( start, end, radius ) { this.start.copy( start ); @@ -31,7 +25,6 @@ this.radius = radius; } - copy( capsule ) { this.start.copy( capsule.start ); @@ -39,40 +32,32 @@ this.radius = capsule.radius; } - getCenter( target ) { return target.copy( this.end ).add( this.start ).multiplyScalar( 0.5 ); } - translate( v ) { this.start.add( v ); this.end.add( v ); } - checkAABBAxis( p1x, p1y, p2x, p2y, minx, maxx, miny, maxy, radius ) { return ( minx - p1x < radius || minx - p2x < radius ) && ( p1x - maxx < radius || p2x - maxx < radius ) && ( miny - p1y < radius || miny - p2y < radius ) && ( p1y - maxy < radius || p2y - maxy < radius ); } - intersectsBox( box ) { return this.checkAABBAxis( this.start.x, this.start.y, this.end.x, this.end.y, box.min.x, box.max.x, box.min.y, box.max.y, this.radius ) && this.checkAABBAxis( this.start.x, this.start.z, this.end.x, this.end.z, box.min.x, box.max.x, box.min.z, box.max.z, this.radius ) && this.checkAABBAxis( this.start.y, this.start.z, this.end.y, this.end.z, box.min.y, box.max.y, box.min.z, box.max.z, this.radius ); } - lineLineMinimumPoints( line1, line2 ) { const r = _v1.copy( line1.end ).sub( line1.start ); - const s = _v2.copy( line2.end ).sub( line2.start ); - const w = _v3.copy( line2.start ).sub( line1.start ); - const a = r.dot( s ), b = r.dot( r ), c = s.dot( s ), @@ -80,12 +65,10 @@ e = r.dot( w ); let t1, t2; const divisor = b * c - a * a; - if ( Math.abs( divisor ) < EPS ) { const d1 = - d / c; const d2 = ( a - d ) / c; - if ( Math.abs( d1 - 0.5 ) < Math.abs( d2 - 0.5 ) ) { t1 = 0; diff --git a/examples/js/math/ColorConverter.js b/examples/js/math/ColorConverter.js index 5569bfd93dbf59..5fe55576b90094 100644 --- a/examples/js/math/ColorConverter.js +++ b/examples/js/math/ColorConverter.js @@ -1,79 +1,29 @@ ( function () { const _hsl = {}; - class ColorConverter { static setHSV( color, h, s, v ) { // https://gist.github.com/xpansive/1337890#file-index-js + h = THREE.MathUtils.euclideanModulo( h, 1 ); s = THREE.MathUtils.clamp( s, 0, 1 ); v = THREE.MathUtils.clamp( v, 0, 1 ); return color.setHSL( h, s * v / ( ( h = ( 2 - s ) * v ) < 1 ? h : 2 - h ), h * 0.5 ); } - static getHSV( color, target ) { - if ( target === undefined ) { - - console.warn( 'THREE.ColorConverter: .getHSV() target is now required' ); - target = { - h: 0, - s: 0, - l: 0 - }; - - } - - color.getHSL( _hsl ); // based on https://gist.github.com/xpansive/1337890#file-index-js + color.getHSL( _hsl ); + // based on https://gist.github.com/xpansive/1337890#file-index-js _hsl.s *= _hsl.l < 0.5 ? _hsl.l : 1 - _hsl.l; target.h = _hsl.h; target.s = 2 * _hsl.s / ( _hsl.l + _hsl.s ); target.v = _hsl.l + _hsl.s; return target; - } // where c, m, y, k is between 0 and 1 - - - static setCMYK( color, c, m, y, k ) { - - const r = ( 1 - c ) * ( 1 - k ); - const g = ( 1 - m ) * ( 1 - k ); - const b = ( 1 - y ) * ( 1 - k ); - return color.setRGB( r, g, b ); - - } - - static getCMYK( color, target ) { - - if ( target === undefined ) { - - console.warn( 'THREE.ColorConverter: .getCMYK() target is now required' ); - target = { - c: 0, - m: 0, - y: 0, - k: 0 - }; - - } - - const r = color.r; - const g = color.g; - const b = color.b; - const k = 1 - Math.max( r, g, b ); - const c = ( 1 - r - k ) / ( 1 - k ); - const m = ( 1 - g - k ) / ( 1 - k ); - const y = ( 1 - b - k ) / ( 1 - k ); - target.c = c; - target.m = m; - target.y = y; - target.k = k; - return target; - } } diff --git a/examples/js/math/ConvexHull.js b/examples/js/math/ConvexHull.js index 91a456293e52b8..2fdc5b0dc9d577 100644 --- a/examples/js/math/ConvexHull.js +++ b/examples/js/math/ConvexHull.js @@ -6,25 +6,19 @@ const Visible = 0; const Deleted = 1; - const _v1 = new THREE.Vector3(); - const _line3 = new THREE.Line3(); - const _plane = new THREE.Plane(); - const _closestPoint = new THREE.Vector3(); - const _triangle = new THREE.Triangle(); - class ConvexHull { constructor() { this.tolerance = - 1; this.faces = []; // the generated faces of the convex hull - this.newFaces = []; // this array holds the faces that are generated within a single iteration + // the vertex lists work as follows: // // let 'a' and 'b' be 'Face' instances @@ -35,7 +29,6 @@ // | | // a.outside b.outside // - this.assigned = new VertexList(); this.unassigned = new VertexList(); this.vertices = []; // vertices of the hull (internal representation of given geometry data) @@ -45,10 +38,10 @@ setFromPoints( points ) { // The algorithm needs at least four points. + if ( points.length >= 4 ) { this.makeEmpty(); - for ( let i = 0, l = points.length; i < l; i ++ ) { this.vertices.push( new VertexNode( points[ i ] ) ); @@ -62,7 +55,6 @@ return this; } - setFromObject( object ) { const points = []; @@ -70,11 +62,9 @@ object.traverse( function ( node ) { const geometry = node.geometry; - if ( geometry !== undefined ) { const attribute = geometry.attributes.position; - if ( attribute !== undefined ) { for ( let i = 0, l = attribute.count; i < l; i ++ ) { @@ -93,14 +83,14 @@ return this.setFromPoints( points ); } - containsPoint( point ) { const faces = this.faces; - for ( let i = 0, l = faces.length; i < l; i ++ ) { - const face = faces[ i ]; // compute signed distance and check on what half space the point lies + const face = faces[ i ]; + + // compute signed distance and check on what half space the point lies if ( face.distanceToPoint( point ) > this.tolerance ) return false; @@ -109,37 +99,48 @@ return true; } - intersectRay( ray, target ) { - // based on "Fast Ray-Convex Polyhedron Intersection" by Eric Haines, GRAPHICS GEMS II + // based on "Fast Ray-Convex Polyhedron Intersection" by Eric Haines, GRAPHICS GEMS II + const faces = this.faces; let tNear = - Infinity; let tFar = Infinity; - for ( let i = 0, l = faces.length; i < l; i ++ ) { - const face = faces[ i ]; // interpret faces as planes for the further computation + const face = faces[ i ]; + + // interpret faces as planes for the further computation const vN = face.distanceToPoint( ray.origin ); - const vD = face.normal.dot( ray.direction ); // if the origin is on the positive side of a plane (so the plane can "see" the origin) and + const vD = face.normal.dot( ray.direction ); + + // if the origin is on the positive side of a plane (so the plane can "see" the origin) and // the ray is turned away or parallel to the plane, there is no intersection - if ( vN > 0 && vD >= 0 ) return null; // compute the distance from the ray’s origin to the intersection with the plane + if ( vN > 0 && vD >= 0 ) return null; - const t = vD !== 0 ? - vN / vD : 0; // only proceed if the distance is positive. a negative distance means the intersection point + // compute the distance from the ray’s origin to the intersection with the plane + + const t = vD !== 0 ? - vN / vD : 0; + + // only proceed if the distance is positive. a negative distance means the intersection point // lies "behind" the origin - if ( t <= 0 ) continue; // now categorized plane as front-facing or back-facing + if ( t <= 0 ) continue; + + // now categorized plane as front-facing or back-facing if ( vD > 0 ) { - // plane faces away from the ray, so this plane is a back-face + // plane faces away from the ray, so this plane is a back-face + tFar = Math.min( t, tFar ); } else { // front-face + tNear = Math.max( t, tNear ); } @@ -147,13 +148,16 @@ if ( tNear > tFar ) { // if tNear ever is greater than tFar, the ray must miss the convex hull + return null; } - } // evaluate intersection point - // always try tNear first since its the closer intersection point + } + // evaluate intersection point + + // always try tNear first since its the closer intersection point if ( tNear !== - Infinity ) { @@ -168,26 +172,24 @@ return target; } - intersectsRay( ray ) { return this.intersectRay( ray, _v1 ) !== null; } - makeEmpty() { this.faces = []; this.vertices = []; return this; - } // Adds a vertex to the 'assigned' list of vertices and assigns it to the given face + } + // Adds a vertex to the 'assigned' list of vertices and assigns it to the given face addVertexToFace( vertex, face ) { vertex.face = face; - if ( face.outside === null ) { this.assigned.append( vertex ); @@ -201,22 +203,26 @@ face.outside = vertex; return this; - } // Removes a vertex from the 'assigned' list of vertices and from the given face + } + // Removes a vertex from the 'assigned' list of vertices and from the given face removeVertexFromFace( vertex, face ) { if ( vertex === face.outside ) { // fix face.outside link + if ( vertex.next !== null && vertex.next.face === face ) { // face has at least 2 outside vertices, move the 'outside' reference + face.outside = vertex.next; } else { // vertex was the only outside vertex that face had + face.outside = null; } @@ -226,24 +232,27 @@ this.assigned.remove( vertex ); return this; - } // Removes all the visible vertices that a given face is able to see which are stored in the 'assigned' vertext list + } + // Removes all the visible vertices that a given face is able to see which are stored in the 'assigned' vertex list removeAllVerticesFromFace( face ) { if ( face.outside !== null ) { // reference to the first and last vertex of this face + const start = face.outside; let end = face.outside; - while ( end.next !== null && end.next.face === face ) { end = end.next; } - this.assigned.removeSubList( start, end ); // fix references + this.assigned.removeSubList( start, end ); + + // fix references start.prev = end.next = null; face.outside = null; @@ -251,31 +260,35 @@ } - } // Removes all the visible vertices that 'face' is able to see + } + // Removes all the visible vertices that 'face' is able to see deleteFaceVertices( face, absorbingFace ) { const faceVertices = this.removeAllVerticesFromFace( face ); - if ( faceVertices !== undefined ) { if ( absorbingFace === undefined ) { // mark the vertices to be reassigned to some other face + this.unassigned.appendChain( faceVertices ); } else { // if there's an absorbing face try to assign as many vertices as possible to it - let vertex = faceVertices; + let vertex = faceVertices; do { // we need to buffer the subsequent vertex at this point because the 'vertex.next' reference // will be changed by upcoming method calls + const nextVertex = vertex.next; - const distance = absorbingFace.distanceToPoint( vertex.point ); // check if 'vertex' is able to see 'absorbingFace' + const distance = absorbingFace.distanceToPoint( vertex.point ); + + // check if 'vertex' is able to see 'absorbingFace' if ( distance > this.tolerance ) { @@ -285,8 +298,9 @@ this.unassigned.append( vertex ); - } // now assign next vertex + } + // now assign next vertex vertex = nextVertex; @@ -298,30 +312,28 @@ return this; - } // Reassigns as many vertices as possible from the unassigned list to the new faces + } + // Reassigns as many vertices as possible from the unassigned list to the new faces resolveUnassignedPoints( newFaces ) { if ( this.unassigned.isEmpty() === false ) { let vertex = this.unassigned.first(); - do { // buffer 'next' reference, see .deleteFaceVertices() + const nextVertex = vertex.next; let maxDistance = this.tolerance; let maxFace = null; - for ( let i = 0; i < newFaces.length; i ++ ) { const face = newFaces[ i ]; - if ( face.mark === Visible ) { const distance = face.distanceToPoint( vertex.point ); - if ( distance > maxDistance ) { maxDistance = distance; @@ -333,8 +345,9 @@ } - } // 'maxFace' can be null e.g. if there are identical vertices + } + // 'maxFace' can be null e.g. if there are identical vertices if ( maxFace !== null ) { @@ -350,15 +363,18 @@ return this; - } // Computes the extremes of a simplex which will be the initial hull + } + // Computes the extremes of a simplex which will be the initial hull computeExtremes() { const min = new THREE.Vector3(); const max = new THREE.Vector3(); const minVertices = []; - const maxVertices = []; // initially assume that the first vertex is the min/max + const maxVertices = []; + + // initially assume that the first vertex is the min/max for ( let i = 0; i < 3; i ++ ) { @@ -367,12 +383,16 @@ } min.copy( this.vertices[ 0 ].point ); - max.copy( this.vertices[ 0 ].point ); // compute the min/max vertex on all six directions + max.copy( this.vertices[ 0 ].point ); + + // compute the min/max vertex on all six directions for ( let i = 0, l = this.vertices.length; i < l; i ++ ) { const vertex = this.vertices[ i ]; - const point = vertex.point; // update the min coordinates + const point = vertex.point; + + // update the min coordinates for ( let j = 0; j < 3; j ++ ) { @@ -383,8 +403,9 @@ } - } // update the max coordinates + } + // update the max coordinates for ( let j = 0; j < 3; j ++ ) { @@ -397,8 +418,9 @@ } - } // use min/max vectors to compute an optimal epsilon + } + // use min/max vectors to compute an optimal epsilon this.tolerance = 3 * Number.EPSILON * ( Math.max( Math.abs( min.x ), Math.abs( max.x ) ) + Math.max( Math.abs( min.y ), Math.abs( max.y ) ) + Math.max( Math.abs( min.z ), Math.abs( max.z ) ) ); return { @@ -406,27 +428,28 @@ max: maxVertices }; - } // Computes the initial simplex assigning to its faces all the points - // that are candidates to form part of the hull + } + // Computes the initial simplex assigning to its faces all the points + // that are candidates to form part of the hull computeInitialHull() { const vertices = this.vertices; const extremes = this.computeExtremes(); const min = extremes.min; - const max = extremes.max; // 1. Find the two vertices 'v0' and 'v1' with the greatest 1d separation + const max = extremes.max; + + // 1. Find the two vertices 'v0' and 'v1' with the greatest 1d separation // (max.x - min.x) // (max.y - min.y) // (max.z - min.z) let maxDistance = 0; let index = 0; - for ( let i = 0; i < 3; i ++ ) { const distance = max[ i ].point.getComponent( i ) - min[ i ].point.getComponent( i ); - if ( distance > maxDistance ) { maxDistance = distance; @@ -439,22 +462,19 @@ const v0 = min[ index ]; const v1 = max[ index ]; let v2; - let v3; // 2. The next vertex 'v2' is the one farthest to the line formed by 'v0' and 'v1' + let v3; - maxDistance = 0; + // 2. The next vertex 'v2' is the one farthest to the line formed by 'v0' and 'v1' + maxDistance = 0; _line3.set( v0.point, v1.point ); - for ( let i = 0, l = this.vertices.length; i < l; i ++ ) { const vertex = vertices[ i ]; - if ( vertex !== v0 && vertex !== v1 ) { _line3.closestPointToPoint( vertex.point, true, _closestPoint ); - const distance = _closestPoint.distanceToSquared( vertex.point ); - if ( distance > maxDistance ) { maxDistance = distance; @@ -464,21 +484,18 @@ } - } // 3. The next vertex 'v3' is the one farthest to the plane 'v0', 'v1', 'v2' + } + // 3. The next vertex 'v3' is the one farthest to the plane 'v0', 'v1', 'v2' maxDistance = - 1; - _plane.setFromCoplanarPoints( v0.point, v1.point, v2.point ); - for ( let i = 0, l = this.vertices.length; i < l; i ++ ) { const vertex = vertices[ i ]; - if ( vertex !== v0 && vertex !== v1 && vertex !== v2 ) { const distance = Math.abs( _plane.distanceToPoint( vertex.point ) ); - if ( distance > maxDistance ) { maxDistance = distance; @@ -491,17 +508,23 @@ } const faces = []; - if ( _plane.distanceToPoint( v3.point ) < 0 ) { // the face is not able to see the point so 'plane.normal' is pointing outside the tetrahedron - faces.push( Face.create( v0, v1, v2 ), Face.create( v3, v1, v0 ), Face.create( v3, v2, v1 ), Face.create( v3, v0, v2 ) ); // set the twin edge + + faces.push( Face.create( v0, v1, v2 ), Face.create( v3, v1, v0 ), Face.create( v3, v2, v1 ), Face.create( v3, v0, v2 ) ); + + // set the twin edge for ( let i = 0; i < 3; i ++ ) { - const j = ( i + 1 ) % 3; // join face[ i ] i > 0, with the first face + const j = ( i + 1 ) % 3; - faces[ i + 1 ].getEdge( 2 ).setTwin( faces[ 0 ].getEdge( j ) ); // join face[ i ] with face[ i + 1 ], 1 <= i <= 3 + // join face[ i ] i > 0, with the first face + + faces[ i + 1 ].getEdge( 2 ).setTwin( faces[ 0 ].getEdge( j ) ); + + // join face[ i ] with face[ i + 1 ], 1 <= i <= 3 faces[ i + 1 ].getEdge( 1 ).setTwin( faces[ j + 1 ].getEdge( 0 ) ); @@ -510,41 +533,47 @@ } else { // the face is able to see the point so 'plane.normal' is pointing inside the tetrahedron - faces.push( Face.create( v0, v2, v1 ), Face.create( v3, v0, v1 ), Face.create( v3, v1, v2 ), Face.create( v3, v2, v0 ) ); // set the twin edge + + faces.push( Face.create( v0, v2, v1 ), Face.create( v3, v0, v1 ), Face.create( v3, v1, v2 ), Face.create( v3, v2, v0 ) ); + + // set the twin edge for ( let i = 0; i < 3; i ++ ) { - const j = ( i + 1 ) % 3; // join face[ i ] i > 0, with the first face + const j = ( i + 1 ) % 3; + + // join face[ i ] i > 0, with the first face + + faces[ i + 1 ].getEdge( 2 ).setTwin( faces[ 0 ].getEdge( ( 3 - i ) % 3 ) ); - faces[ i + 1 ].getEdge( 2 ).setTwin( faces[ 0 ].getEdge( ( 3 - i ) % 3 ) ); // join face[ i ] with face[ i + 1 ] + // join face[ i ] with face[ i + 1 ] faces[ i + 1 ].getEdge( 0 ).setTwin( faces[ j + 1 ].getEdge( 1 ) ); } - } // the initial hull is the tetrahedron + } + // the initial hull is the tetrahedron for ( let i = 0; i < 4; i ++ ) { this.faces.push( faces[ i ] ); - } // initial assignment of vertices to the faces of the tetrahedron + } + // initial assignment of vertices to the faces of the tetrahedron for ( let i = 0, l = vertices.length; i < l; i ++ ) { const vertex = vertices[ i ]; - if ( vertex !== v0 && vertex !== v1 && vertex !== v2 && vertex !== v3 ) { maxDistance = this.tolerance; let maxFace = null; - for ( let j = 0; j < 4; j ++ ) { const distance = this.faces[ j ].distanceToPoint( vertex.point ); - if ( distance > maxDistance ) { maxDistance = distance; @@ -566,17 +595,16 @@ return this; - } // Removes inactive faces + } + // Removes inactive faces reindexFaces() { const activeFaces = []; - for ( let i = 0; i < this.faces.length; i ++ ) { const face = this.faces[ i ]; - if ( face.mark === Visible ) { activeFaces.push( face ); @@ -588,24 +616,29 @@ this.faces = activeFaces; return this; - } // Finds the next vertex to create faces with the current hull + } + // Finds the next vertex to create faces with the current hull nextVertexToAdd() { // if the 'assigned' list of vertices is empty, no vertices are left. return with 'undefined' + if ( this.assigned.isEmpty() === false ) { let eyeVertex, - maxDistance = 0; // grap the first available face and start with the first visible vertex of that face + maxDistance = 0; + + // grap the first available face and start with the first visible vertex of that face const eyeFace = this.assigned.first().face; - let vertex = eyeFace.outside; // now calculate the farthest vertex that face can see + let vertex = eyeFace.outside; + + // now calculate the farthest vertex that face can see do { const distance = eyeFace.distanceToPoint( vertex.point ); - if ( distance > maxDistance ) { maxDistance = distance; @@ -621,18 +654,19 @@ } - } // Computes a chain of half edges in CCW order called the 'horizon'. + } + + // Computes a chain of half edges in CCW order called the 'horizon'. // For an edge to be part of the horizon it must join a face that can see // 'eyePoint' and a face that cannot see 'eyePoint'. - computeHorizon( eyePoint, crossEdge, face, horizon ) { // moves face's vertices to the 'unassigned' vertex list + this.deleteFaceVertices( face ); face.mark = Deleted; let edge; - if ( crossEdge === null ) { edge = crossEdge = face.getEdge( 0 ); @@ -641,6 +675,7 @@ // start from the next edge since 'crossEdge' was already analyzed // (actually 'crossEdge.twin' was the edge who called this method recursively) + edge = crossEdge.next; } @@ -649,17 +684,18 @@ const twinEdge = edge.twin; const oppositeFace = twinEdge.face; - if ( oppositeFace.mark === Visible ) { if ( oppositeFace.distanceToPoint( eyePoint ) > this.tolerance ) { // the opposite face can see the vertex, so proceed with next edge + this.computeHorizon( eyePoint, twinEdge, oppositeFace, horizon ); } else { // the opposite face can't see the vertex, so this edge is part of the horizon + horizon.push( edge ); } @@ -672,34 +708,39 @@ return this; - } // Creates a face with the vertices 'eyeVertex.point', 'horizonEdge.tail' and 'horizonEdge.head' in CCW order + } + // Creates a face with the vertices 'eyeVertex.point', 'horizonEdge.tail' and 'horizonEdge.head' in CCW order addAdjoiningFace( eyeVertex, horizonEdge ) { // all the half edges are created in ccw order thus the face is always pointing outside the hull + const face = Face.create( eyeVertex, horizonEdge.tail(), horizonEdge.head() ); - this.faces.push( face ); // join face.getEdge( - 1 ) with the horizon's opposite edge face.getEdge( - 1 ) = face.getEdge( 2 ) + this.faces.push( face ); + + // join face.getEdge( - 1 ) with the horizon's opposite edge face.getEdge( - 1 ) = face.getEdge( 2 ) face.getEdge( - 1 ).setTwin( horizonEdge.twin ); return face.getEdge( 0 ); // the half edge whose vertex is the eyeVertex - } // Adds 'horizon.length' faces to the hull, each face will be linked with the - // horizon opposite face and the face on the left/right + } + // Adds 'horizon.length' faces to the hull, each face will be linked with the + // horizon opposite face and the face on the left/right addNewFaces( eyeVertex, horizon ) { this.newFaces = []; let firstSideEdge = null; let previousSideEdge = null; - for ( let i = 0; i < horizon.length; i ++ ) { - const horizonEdge = horizon[ i ]; // returns the right side edge + const horizonEdge = horizon[ i ]; - const sideEdge = this.addAdjoiningFace( eyeVertex, horizonEdge ); + // returns the right side edge + const sideEdge = this.addAdjoiningFace( eyeVertex, horizonEdge ); if ( firstSideEdge === null ) { firstSideEdge = sideEdge; @@ -707,6 +748,7 @@ } else { // joins face.getEdge( 1 ) with previousFace.getEdge( 0 ) + sideEdge.next.setTwin( previousSideEdge ); } @@ -714,29 +756,34 @@ this.newFaces.push( sideEdge.face ); previousSideEdge = sideEdge; - } // perform final join of new faces + } + // perform final join of new faces firstSideEdge.next.setTwin( previousSideEdge ); return this; - } // Adds a vertex to the hull + } + // Adds a vertex to the hull addVertexToHull( eyeVertex ) { const horizon = []; - this.unassigned.clear(); // remove 'eyeVertex' from 'eyeVertex.face' so that it can't be added to the 'unassigned' vertex list + this.unassigned.clear(); + + // remove 'eyeVertex' from 'eyeVertex.face' so that it can't be added to the 'unassigned' vertex list this.removeVertexFromFace( eyeVertex, eyeVertex.face ); this.computeHorizon( eyeVertex.point, null, eyeVertex.face, horizon ); - this.addNewFaces( eyeVertex, horizon ); // reassign 'unassigned' vertices to the new faces + this.addNewFaces( eyeVertex, horizon ); + + // reassign 'unassigned' vertices to the new faces this.resolveUnassignedPoints( this.newFaces ); return this; } - cleanup() { this.assigned.clear(); @@ -745,11 +792,12 @@ return this; } - compute() { let vertex; - this.computeInitialHull(); // add all available vertices gradually to the hull + this.computeInitialHull(); + + // add all available vertices gradually to the hull while ( ( vertex = this.nextVertexToAdd() ) !== undefined ) { @@ -763,8 +811,9 @@ } - } // + } + // class Face { @@ -774,34 +823,33 @@ this.midpoint = new THREE.Vector3(); this.area = 0; this.constant = 0; // signed distance from face to the origin - this.outside = null; // reference to a vertex in a vertex list this face can see - this.mark = Visible; this.edge = null; } - static create( a, b, c ) { const face = new Face(); const e0 = new HalfEdge( a, face ); const e1 = new HalfEdge( b, face ); - const e2 = new HalfEdge( c, face ); // join edges + const e2 = new HalfEdge( c, face ); + + // join edges e0.next = e2.prev = e1; e1.next = e0.prev = e2; - e2.next = e1.prev = e0; // main half edge reference + e2.next = e1.prev = e0; + + // main half edge reference face.edge = e0; return face.compute(); } - getEdge( i ) { let edge = this.edge; - while ( i > 0 ) { edge = edge.next; @@ -819,33 +867,28 @@ return edge; } - compute() { const a = this.edge.tail(); const b = this.edge.head(); const c = this.edge.next.head(); - _triangle.set( a.point, b.point, c.point ); - _triangle.getNormal( this.normal ); - _triangle.getMidpoint( this.midpoint ); - this.area = _triangle.getArea(); this.constant = this.normal.dot( this.midpoint ); return this; } - distanceToPoint( point ) { return this.normal.dot( point ) - this.constant; } - } // Entity for a Doubly-Connected Edge List (DCEL). + } + // Entity for a Doubly-Connected Edge List (DCEL). class HalfEdge { @@ -858,24 +901,20 @@ this.face = face; } - head() { return this.vertex; } - tail() { return this.prev ? this.prev.vertex : null; } - length() { const head = this.head(); const tail = this.tail(); - if ( tail !== null ) { return tail.point.distanceTo( head.point ); @@ -885,12 +924,10 @@ return - 1; } - lengthSquared() { const head = this.head(); const tail = this.tail(); - if ( tail !== null ) { return tail.point.distanceToSquared( head.point ); @@ -900,7 +937,6 @@ return - 1; } - setTwin( edge ) { this.twin = edge; @@ -909,8 +945,9 @@ } - } // A vertex as a double linked list node. + } + // A vertex as a double linked list node. class VertexNode { @@ -923,8 +960,9 @@ } - } // A double linked list that contains vertex nodes. + } + // A double linked list that contains vertex nodes. class VertexList { @@ -934,32 +972,29 @@ this.tail = null; } - first() { return this.head; } - last() { return this.tail; } - clear() { this.head = this.tail = null; return this; - } // Inserts a vertex before the target vertex + } + // Inserts a vertex before the target vertex insertBefore( target, vertex ) { vertex.prev = target.prev; vertex.next = target; - if ( vertex.prev === null ) { this.head = vertex; @@ -973,14 +1008,14 @@ target.prev = vertex; return this; - } // Inserts a vertex after the target vertex + } + // Inserts a vertex after the target vertex insertAfter( target, vertex ) { vertex.prev = target; vertex.next = target.next; - if ( vertex.next === null ) { this.tail = vertex; @@ -994,8 +1029,9 @@ target.next = vertex; return this; - } // Appends a vertex to the end of the linked list + } + // Appends a vertex to the end of the linked list append( vertex ) { @@ -1015,8 +1051,9 @@ this.tail = vertex; return this; - } // Appends a chain of vertices where 'vertex' is the head. + } + // Appends a chain of vertices where 'vertex' is the head. appendChain( vertex ) { @@ -1030,7 +1067,9 @@ } - vertex.prev = this.tail; // ensure that the 'tail' reference points to the last vertex of the chain + vertex.prev = this.tail; + + // ensure that the 'tail' reference points to the last vertex of the chain while ( vertex.next !== null ) { @@ -1041,8 +1080,9 @@ this.tail = vertex; return this; - } // Removes a vertex from the linked list + } + // Removes a vertex from the linked list remove( vertex ) { @@ -1068,8 +1108,9 @@ return this; - } // Removes a list of vertices whose 'head' is 'a' and whose 'tail' is b + } + // Removes a list of vertices whose 'head' is 'a' and whose 'tail' is b removeSubList( a, b ) { @@ -1096,7 +1137,6 @@ return this; } - isEmpty() { return this.head === null; @@ -1106,5 +1146,9 @@ } THREE.ConvexHull = ConvexHull; + THREE.Face = Face; + THREE.HalfEdge = HalfEdge; + THREE.VertexList = VertexList; + THREE.VertexNode = VertexNode; } )(); diff --git a/examples/js/math/ImprovedNoise.js b/examples/js/math/ImprovedNoise.js index a5aa4045c45daf..be13b5d89b3e0c 100644 --- a/examples/js/math/ImprovedNoise.js +++ b/examples/js/math/ImprovedNoise.js @@ -1,8 +1,8 @@ ( function () { // https://cs.nyu.edu/~perlin/noise/ - const _p = [ 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180 ]; + const _p = [ 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180 ]; for ( let i = 0; i < 256; i ++ ) { _p[ 256 + i ] = _p[ i ]; diff --git a/examples/js/math/Lut.js b/examples/js/math/Lut.js index 16272d04fceb9d..c07cb9b42497e4 100644 --- a/examples/js/math/Lut.js +++ b/examples/js/math/Lut.js @@ -13,7 +13,6 @@ this.setColorMap( colormap, count ); } - set( value ) { if ( value.isLut === true ) { @@ -25,21 +24,18 @@ return this; } - setMin( min ) { this.minV = min; return this; } - setMax( max ) { this.maxV = max; return this; } - setColorMap( colormap, count = 32 ) { this.map = ColorMapKeywords[ colormap ] || ColorMapKeywords.rainbow; @@ -47,14 +43,17 @@ const step = 1.0 / this.n; const minColor = new THREE.Color(); const maxColor = new THREE.Color(); - this.lut.length = 0; // sample at 0 + this.lut.length = 0; - this.lut.push( new THREE.Color( this.map[ 0 ][ 1 ] ) ); // sample at 1/n, ..., (n-1)/n + // sample at 0 + + this.lut.push( new THREE.Color( this.map[ 0 ][ 1 ] ) ); + + // sample at 1/n, ..., (n-1)/n for ( let i = 1; i < count; i ++ ) { const alpha = i * step; - for ( let j = 0; j < this.map.length - 1; j ++ ) { if ( alpha > this.map[ j ][ 0 ] && alpha <= this.map[ j + 1 ][ 0 ] ) { @@ -70,14 +69,14 @@ } - } // sample at 1 + } + // sample at 1 this.lut.push( new THREE.Color( this.map[ this.map.length - 1 ][ 1 ] ) ); return this; } - copy( lut ) { this.lut = lut.lut; @@ -88,7 +87,6 @@ return this; } - getColor( alpha ) { alpha = THREE.MathUtils.clamp( alpha, this.minV, this.maxV ); @@ -97,14 +95,12 @@ return this.lut[ colorPosition ]; } - addColorMap( name, arrayOfColors ) { ColorMapKeywords[ name ] = arrayOfColors; return this; } - createCanvas() { const canvas = document.createElement( 'canvas' ); @@ -114,7 +110,6 @@ return canvas; } - updateCanvas( canvas ) { const ctx = canvas.getContext( '2d', { @@ -127,7 +122,6 @@ const minColor = new THREE.Color(); const maxColor = new THREE.Color(); const finalColor = new THREE.Color(); - for ( let i = 1; i >= 0; i -= step ) { for ( let j = this.map.length - 1; j >= 0; j -- ) { @@ -157,7 +151,6 @@ } } - const ColorMapKeywords = { 'rainbow': [[ 0.0, 0x0000FF ], [ 0.2, 0x00FFFF ], [ 0.5, 0x00FF00 ], [ 0.8, 0xFFFF00 ], [ 1.0, 0xFF0000 ]], 'cooltowarm': [[ 0.0, 0x3C4EC2 ], [ 0.2, 0x9BBCFF ], [ 0.5, 0xDCDCDC ], [ 0.8, 0xF6A385 ], [ 1.0, 0xB40426 ]], diff --git a/examples/js/math/MeshSurfaceSampler.js b/examples/js/math/MeshSurfaceSampler.js index 718f05740e852a..6a75f6f2012811 100644 --- a/examples/js/math/MeshSurfaceSampler.js +++ b/examples/js/math/MeshSurfaceSampler.js @@ -12,15 +12,12 @@ */ const _face = new THREE.Triangle(); - const _color = new THREE.Vector3(); - class MeshSurfaceSampler { constructor( mesh ) { let geometry = mesh.geometry; - if ( ! geometry.isBufferGeometry || geometry.attributes.position.itemSize !== 3 ) { throw new Error( 'THREE.MeshSurfaceSampler: Requires BufferGeometry triangle mesh.' ); @@ -42,24 +39,23 @@ this.distribution = null; } - setWeightAttribute( name ) { this.weightAttribute = name ? this.geometry.getAttribute( name ) : null; return this; } - build() { const positionAttribute = this.positionAttribute; const weightAttribute = this.weightAttribute; - const faceWeights = new Float32Array( positionAttribute.count / 3 ); // Accumulate weights for each mesh face. + const faceWeights = new Float32Array( positionAttribute.count / 3 ); + + // Accumulate weights for each mesh face. for ( let i = 0; i < positionAttribute.count; i += 3 ) { let faceWeight = 1; - if ( weightAttribute ) { faceWeight = weightAttribute.getX( i ) + weightAttribute.getX( i + 1 ) + weightAttribute.getX( i + 2 ); @@ -67,21 +63,18 @@ } _face.a.fromBufferAttribute( positionAttribute, i ); - _face.b.fromBufferAttribute( positionAttribute, i + 1 ); - _face.c.fromBufferAttribute( positionAttribute, i + 2 ); - faceWeight *= _face.getArea(); faceWeights[ i / 3 ] = faceWeight; - } // Store cumulative total face weights in an array, where weight index - // corresponds to face index. + } + // Store cumulative total face weights in an array, where weight index + // corresponds to face index. this.distribution = new Float32Array( positionAttribute.count / 3 ); let cumulativeTotal = 0; - for ( let i = 0; i < faceWeights.length; i ++ ) { cumulativeTotal += faceWeights[ i ]; @@ -92,14 +85,12 @@ return this; } - setRandomGenerator( randomFunction ) { this.randomFunction = randomFunction; return this; } - sample( targetPosition, targetNormal, targetColor ) { const cumulativeTotal = this.distribution[ this.distribution.length - 1 ]; @@ -107,18 +98,15 @@ return this.sampleFace( faceIndex, targetPosition, targetNormal, targetColor ); } - binarySearch( x ) { const dist = this.distribution; let start = 0; let end = dist.length - 1; let index = - 1; - while ( start <= end ) { const mid = Math.ceil( ( start + end ) / 2 ); - if ( mid === 0 || dist[ mid - 1 ] <= x && dist[ mid ] > x ) { index = mid; @@ -139,12 +127,10 @@ return index; } - sampleFace( faceIndex, targetPosition, targetNormal, targetColor ) { let u = this.randomFunction(); let v = this.randomFunction(); - if ( u + v > 1 ) { u = 1 - u; @@ -153,13 +139,9 @@ } _face.a.fromBufferAttribute( this.positionAttribute, faceIndex * 3 ); - _face.b.fromBufferAttribute( this.positionAttribute, faceIndex * 3 + 1 ); - _face.c.fromBufferAttribute( this.positionAttribute, faceIndex * 3 + 2 ); - targetPosition.set( 0, 0, 0 ).addScaledVector( _face.a, u ).addScaledVector( _face.b, v ).addScaledVector( _face.c, 1 - ( u + v ) ); - if ( targetNormal !== undefined ) { _face.getNormal( targetNormal ); @@ -169,13 +151,9 @@ if ( targetColor !== undefined && this.colorAttribute !== undefined ) { _face.a.fromBufferAttribute( this.colorAttribute, faceIndex * 3 ); - _face.b.fromBufferAttribute( this.colorAttribute, faceIndex * 3 + 1 ); - _face.c.fromBufferAttribute( this.colorAttribute, faceIndex * 3 + 2 ); - _color.set( 0, 0, 0 ).addScaledVector( _face.a, u ).addScaledVector( _face.b, v ).addScaledVector( _face.c, 1 - ( u + v ) ); - targetColor.r = _color.x; targetColor.g = _color.y; targetColor.b = _color.z; diff --git a/examples/js/math/OBB.js b/examples/js/math/OBB.js index b2384545289f3f..16f37fbcf610ee 100644 --- a/examples/js/math/OBB.js +++ b/examples/js/math/OBB.js @@ -1,21 +1,23 @@ ( function () { + // module scope helper variables + const a = { c: null, // center u: [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ], // basis vectors e: [] // half width - }; + const b = { c: null, // center u: [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ], // basis vectors e: [] // half width - }; + const R = [[], [], []]; const AbsR = [[], [], []]; const t = []; @@ -29,7 +31,9 @@ const aabb = new THREE.Box3(); const matrix = new THREE.Matrix4(); const inverse = new THREE.Matrix4(); - const localRay = new THREE.Ray(); // OBB + const localRay = new THREE.Ray(); + + // OBB class OBB { @@ -40,7 +44,6 @@ this.rotation = rotation; } - set( center, halfSize, rotation ) { this.center = center; @@ -49,7 +52,6 @@ return this; } - copy( obb ) { this.center.copy( obb.center ); @@ -58,31 +60,32 @@ return this; } - clone() { return new this.constructor().copy( this ); } - getSize( result ) { return result.copy( this.halfSize ).multiplyScalar( 2 ); } + /** * Reference: Closest Point on OBB to Point in Real-Time Collision Detection * by Christer Ericson (chapter 5.1.4) */ - - clampPoint( point, result ) { const halfSize = this.halfSize; v1.subVectors( point, this.center ); - this.rotation.extractBasis( xAxis, yAxis, zAxis ); // start at the center position of the OBB + this.rotation.extractBasis( xAxis, yAxis, zAxis ); + + // start at the center position of the OBB + + result.copy( this.center ); - result.copy( this.center ); // project the target onto the OBB axes and walk towards that point + // project the target onto the OBB axes and walk towards that point const x = THREE.MathUtils.clamp( v1.dot( xAxis ), - halfSize.x, halfSize.x ); result.add( xAxis.multiplyScalar( x ) ); @@ -93,40 +96,42 @@ return result; } - containsPoint( point ) { v1.subVectors( point, this.center ); - this.rotation.extractBasis( xAxis, yAxis, zAxis ); // project v1 onto each axis and check if these points lie inside the OBB + this.rotation.extractBasis( xAxis, yAxis, zAxis ); + + // project v1 onto each axis and check if these points lie inside the OBB return Math.abs( v1.dot( xAxis ) ) <= this.halfSize.x && Math.abs( v1.dot( yAxis ) ) <= this.halfSize.y && Math.abs( v1.dot( zAxis ) ) <= this.halfSize.z; } - intersectsBox3( box3 ) { return this.intersectsOBB( obb.fromBox3( box3 ) ); } - intersectsSphere( sphere ) { // find the point on the OBB closest to the sphere center - this.clampPoint( sphere.center, closestPoint ); // if that point is inside the sphere, the OBB and sphere intersect + + this.clampPoint( sphere.center, closestPoint ); + + // if that point is inside the sphere, the OBB and sphere intersect return closestPoint.distanceToSquared( sphere.center ) <= sphere.radius * sphere.radius; } + /** * Reference: OBB-OBB Intersection in Real-Time Collision Detection * by Christer Ericson (chapter 4.4.1) * */ - - intersectsOBB( obb, epsilon = Number.EPSILON ) { // prepare data structures (the code uses the same nomenclature like the reference) + a.c = this.center; a.e[ 0 ] = this.halfSize.x; a.e[ 1 ] = this.halfSize.y; @@ -136,7 +141,9 @@ b.e[ 0 ] = obb.halfSize.x; b.e[ 1 ] = obb.halfSize.y; b.e[ 2 ] = obb.halfSize.z; - obb.rotation.extractBasis( b.u[ 0 ], b.u[ 1 ], b.u[ 2 ] ); // compute rotation matrix expressing b in a's coordinate frame + obb.rotation.extractBasis( b.u[ 0 ], b.u[ 1 ], b.u[ 2 ] ); + + // compute rotation matrix expressing b in a's coordinate frame for ( let i = 0; i < 3; i ++ ) { @@ -146,14 +153,19 @@ } - } // compute translation vector + } + // compute translation vector - v1.subVectors( b.c, a.c ); // bring translation into a's coordinate frame + v1.subVectors( b.c, a.c ); + + // bring translation into a's coordinate frame t[ 0 ] = v1.dot( a.u[ 0 ] ); t[ 1 ] = v1.dot( a.u[ 1 ] ); - t[ 2 ] = v1.dot( a.u[ 2 ] ); // compute common subexpressions. Add in an epsilon term to + t[ 2 ] = v1.dot( a.u[ 2 ] ); + + // compute common subexpressions. Add in an epsilon term to // counteract arithmetic errors when two edges are parallel and // their cross product is (near) null @@ -167,7 +179,9 @@ } - let ra, rb; // test axes L = A0, L = A1, L = A2 + let ra, rb; + + // test axes L = A0, L = A1, L = A2 for ( let i = 0; i < 3; i ++ ) { @@ -175,8 +189,9 @@ rb = b.e[ 0 ] * AbsR[ i ][ 0 ] + b.e[ 1 ] * AbsR[ i ][ 1 ] + b.e[ 2 ] * AbsR[ i ][ 2 ]; if ( Math.abs( t[ i ] ) > ra + rb ) return false; - } // test axes L = B0, L = B1, L = B2 + } + // test axes L = B0, L = B1, L = B2 for ( let i = 0; i < 3; i ++ ) { @@ -184,87 +199,118 @@ rb = b.e[ i ]; if ( Math.abs( t[ 0 ] * R[ 0 ][ i ] + t[ 1 ] * R[ 1 ][ i ] + t[ 2 ] * R[ 2 ][ i ] ) > ra + rb ) return false; - } // test axis L = A0 x B0 + } + // test axis L = A0 x B0 ra = a.e[ 1 ] * AbsR[ 2 ][ 0 ] + a.e[ 2 ] * AbsR[ 1 ][ 0 ]; rb = b.e[ 1 ] * AbsR[ 0 ][ 2 ] + b.e[ 2 ] * AbsR[ 0 ][ 1 ]; - if ( Math.abs( t[ 2 ] * R[ 1 ][ 0 ] - t[ 1 ] * R[ 2 ][ 0 ] ) > ra + rb ) return false; // test axis L = A0 x B1 + if ( Math.abs( t[ 2 ] * R[ 1 ][ 0 ] - t[ 1 ] * R[ 2 ][ 0 ] ) > ra + rb ) return false; + + // test axis L = A0 x B1 ra = a.e[ 1 ] * AbsR[ 2 ][ 1 ] + a.e[ 2 ] * AbsR[ 1 ][ 1 ]; rb = b.e[ 0 ] * AbsR[ 0 ][ 2 ] + b.e[ 2 ] * AbsR[ 0 ][ 0 ]; - if ( Math.abs( t[ 2 ] * R[ 1 ][ 1 ] - t[ 1 ] * R[ 2 ][ 1 ] ) > ra + rb ) return false; // test axis L = A0 x B2 + if ( Math.abs( t[ 2 ] * R[ 1 ][ 1 ] - t[ 1 ] * R[ 2 ][ 1 ] ) > ra + rb ) return false; + + // test axis L = A0 x B2 ra = a.e[ 1 ] * AbsR[ 2 ][ 2 ] + a.e[ 2 ] * AbsR[ 1 ][ 2 ]; rb = b.e[ 0 ] * AbsR[ 0 ][ 1 ] + b.e[ 1 ] * AbsR[ 0 ][ 0 ]; - if ( Math.abs( t[ 2 ] * R[ 1 ][ 2 ] - t[ 1 ] * R[ 2 ][ 2 ] ) > ra + rb ) return false; // test axis L = A1 x B0 + if ( Math.abs( t[ 2 ] * R[ 1 ][ 2 ] - t[ 1 ] * R[ 2 ][ 2 ] ) > ra + rb ) return false; + + // test axis L = A1 x B0 ra = a.e[ 0 ] * AbsR[ 2 ][ 0 ] + a.e[ 2 ] * AbsR[ 0 ][ 0 ]; rb = b.e[ 1 ] * AbsR[ 1 ][ 2 ] + b.e[ 2 ] * AbsR[ 1 ][ 1 ]; - if ( Math.abs( t[ 0 ] * R[ 2 ][ 0 ] - t[ 2 ] * R[ 0 ][ 0 ] ) > ra + rb ) return false; // test axis L = A1 x B1 + if ( Math.abs( t[ 0 ] * R[ 2 ][ 0 ] - t[ 2 ] * R[ 0 ][ 0 ] ) > ra + rb ) return false; + + // test axis L = A1 x B1 ra = a.e[ 0 ] * AbsR[ 2 ][ 1 ] + a.e[ 2 ] * AbsR[ 0 ][ 1 ]; rb = b.e[ 0 ] * AbsR[ 1 ][ 2 ] + b.e[ 2 ] * AbsR[ 1 ][ 0 ]; - if ( Math.abs( t[ 0 ] * R[ 2 ][ 1 ] - t[ 2 ] * R[ 0 ][ 1 ] ) > ra + rb ) return false; // test axis L = A1 x B2 + if ( Math.abs( t[ 0 ] * R[ 2 ][ 1 ] - t[ 2 ] * R[ 0 ][ 1 ] ) > ra + rb ) return false; + + // test axis L = A1 x B2 ra = a.e[ 0 ] * AbsR[ 2 ][ 2 ] + a.e[ 2 ] * AbsR[ 0 ][ 2 ]; rb = b.e[ 0 ] * AbsR[ 1 ][ 1 ] + b.e[ 1 ] * AbsR[ 1 ][ 0 ]; - if ( Math.abs( t[ 0 ] * R[ 2 ][ 2 ] - t[ 2 ] * R[ 0 ][ 2 ] ) > ra + rb ) return false; // test axis L = A2 x B0 + if ( Math.abs( t[ 0 ] * R[ 2 ][ 2 ] - t[ 2 ] * R[ 0 ][ 2 ] ) > ra + rb ) return false; + + // test axis L = A2 x B0 ra = a.e[ 0 ] * AbsR[ 1 ][ 0 ] + a.e[ 1 ] * AbsR[ 0 ][ 0 ]; rb = b.e[ 1 ] * AbsR[ 2 ][ 2 ] + b.e[ 2 ] * AbsR[ 2 ][ 1 ]; - if ( Math.abs( t[ 1 ] * R[ 0 ][ 0 ] - t[ 0 ] * R[ 1 ][ 0 ] ) > ra + rb ) return false; // test axis L = A2 x B1 + if ( Math.abs( t[ 1 ] * R[ 0 ][ 0 ] - t[ 0 ] * R[ 1 ][ 0 ] ) > ra + rb ) return false; + + // test axis L = A2 x B1 ra = a.e[ 0 ] * AbsR[ 1 ][ 1 ] + a.e[ 1 ] * AbsR[ 0 ][ 1 ]; rb = b.e[ 0 ] * AbsR[ 2 ][ 2 ] + b.e[ 2 ] * AbsR[ 2 ][ 0 ]; - if ( Math.abs( t[ 1 ] * R[ 0 ][ 1 ] - t[ 0 ] * R[ 1 ][ 1 ] ) > ra + rb ) return false; // test axis L = A2 x B2 + if ( Math.abs( t[ 1 ] * R[ 0 ][ 1 ] - t[ 0 ] * R[ 1 ][ 1 ] ) > ra + rb ) return false; + + // test axis L = A2 x B2 ra = a.e[ 0 ] * AbsR[ 1 ][ 2 ] + a.e[ 1 ] * AbsR[ 0 ][ 2 ]; rb = b.e[ 0 ] * AbsR[ 2 ][ 1 ] + b.e[ 1 ] * AbsR[ 2 ][ 0 ]; - if ( Math.abs( t[ 1 ] * R[ 0 ][ 2 ] - t[ 0 ] * R[ 1 ][ 2 ] ) > ra + rb ) return false; // since no separating axis is found, the OBBs must be intersecting + if ( Math.abs( t[ 1 ] * R[ 0 ][ 2 ] - t[ 0 ] * R[ 1 ][ 2 ] ) > ra + rb ) return false; + + // since no separating axis is found, the OBBs must be intersecting return true; } + /** * Reference: Testing Box Against Plane in Real-Time Collision Detection * by Christer Ericson (chapter 5.2.3) */ + intersectsPlane( plane ) { + this.rotation.extractBasis( xAxis, yAxis, zAxis ); - intersectsPlane( plane ) { + // compute the projection interval radius of this OBB onto L(t) = this->center + t * p.normal; + + const r = this.halfSize.x * Math.abs( plane.normal.dot( xAxis ) ) + this.halfSize.y * Math.abs( plane.normal.dot( yAxis ) ) + this.halfSize.z * Math.abs( plane.normal.dot( zAxis ) ); - this.rotation.extractBasis( xAxis, yAxis, zAxis ); // compute the projection interval radius of this OBB onto L(t) = this->center + t * p.normal; + // compute distance of the OBB's center from the plane - const r = this.halfSize.x * Math.abs( plane.normal.dot( xAxis ) ) + this.halfSize.y * Math.abs( plane.normal.dot( yAxis ) ) + this.halfSize.z * Math.abs( plane.normal.dot( zAxis ) ); // compute distance of the OBB's center from the plane + const d = plane.normal.dot( this.center ) - plane.constant; - const d = plane.normal.dot( this.center ) - plane.constant; // Intersection occurs when distance d falls within [-r,+r] interval + // Intersection occurs when distance d falls within [-r,+r] interval return Math.abs( d ) <= r; } + /** * Performs a ray/OBB intersection test and stores the intersection point * to the given 3D vector. If no intersection is detected, *null* is returned. */ - - intersectRay( ray, result ) { // the idea is to perform the intersection test in the local space // of the OBB. + this.getSize( size ); - aabb.setFromCenterAndSize( v1.set( 0, 0, 0 ), size ); // create a 4x4 transformation matrix + aabb.setFromCenterAndSize( v1.set( 0, 0, 0 ), size ); + + // create a 4x4 transformation matrix matrix.setFromMatrix3( this.rotation ); - matrix.setPosition( this.center ); // transform ray to the local space of the OBB + matrix.setPosition( this.center ); + + // transform ray to the local space of the OBB inverse.copy( matrix ).invert(); - localRay.copy( ray ).applyMatrix4( inverse ); // perform ray <-> AABB intersection test + localRay.copy( ray ).applyMatrix4( inverse ); + + // perform ray <-> AABB intersection test if ( localRay.intersectBox( aabb, result ) ) { // transform the intersection point back to world space + return result.applyMatrix4( matrix ); } else { @@ -274,18 +320,16 @@ } } + /** * Performs a ray/OBB intersection test. Returns either true or false if * there is a intersection or not. */ - - intersectsRay( ray ) { return this.intersectRay( ray, v1 ) !== null; } - fromBox3( box3 ) { box3.getCenter( this.center ); @@ -294,13 +338,11 @@ return this; } - equals( obb ) { return obb.center.equals( this.center ) && obb.halfSize.equals( this.halfSize ) && obb.rotation.equals( this.rotation ); } - applyMatrix4( matrix ) { const e = matrix.elements; @@ -333,7 +375,6 @@ } } - const obb = new OBB(); THREE.OBB = OBB; diff --git a/examples/js/math/Octree.js b/examples/js/math/Octree.js index 5febffe4665aee..fb36f449914f61 100644 --- a/examples/js/math/Octree.js +++ b/examples/js/math/Octree.js @@ -1,19 +1,12 @@ ( function () { const _v1 = new THREE.Vector3(); - const _v2 = new THREE.Vector3(); - const _plane = new THREE.Plane(); - const _line1 = new THREE.Line3(); - const _line2 = new THREE.Line3(); - const _sphere = new THREE.Sphere(); - const _capsule = new THREE.Capsule(); - class Octree { constructor( box ) { @@ -23,7 +16,6 @@ this.subTrees = []; } - addTriangle( triangle ) { if ( ! this.bounds ) this.bounds = new THREE.Box3(); @@ -37,25 +29,22 @@ return this; } - calcBox() { - this.box = this.bounds.clone(); // offset small ammount to account for regular grid + this.box = this.bounds.clone(); + // offset small amount to account for regular grid this.box.min.x -= 0.01; this.box.min.y -= 0.01; this.box.min.z -= 0.01; return this; } - split( level ) { if ( ! this.box ) return; const subTrees = []; - const halfsize = _v2.copy( this.box.max ).sub( this.box.min ).multiplyScalar( 0.5 ); - for ( let x = 0; x < 2; x ++ ) { for ( let y = 0; y < 2; y ++ ) { @@ -63,9 +52,7 @@ for ( let z = 0; z < 2; z ++ ) { const box = new THREE.Box3(); - const v = _v1.set( x, y, z ); - box.min.copy( this.box.min ).add( v.multiply( halfsize ) ); box.max.copy( box.min ).add( halfsize ); subTrees.push( new Octree( box ) ); @@ -77,7 +64,6 @@ } let triangle; - while ( triangle = this.triangles.pop() ) { for ( let i = 0; i < subTrees.length; i ++ ) { @@ -95,7 +81,6 @@ for ( let i = 0; i < subTrees.length; i ++ ) { const len = subTrees[ i ].triangles.length; - if ( len > 8 && level < 16 ) { subTrees[ i ].split( level + 1 ); @@ -113,7 +98,6 @@ return this; } - build() { this.calcBox(); @@ -121,14 +105,12 @@ return this; } - getRayTriangles( ray, triangles ) { for ( let i = 0; i < this.subTrees.length; i ++ ) { const subTree = this.subTrees[ i ]; if ( ! ray.intersectsBox( subTree.box ) ) continue; - if ( subTree.triangles.length > 0 ) { for ( let j = 0; j < subTree.triangles.length; j ++ ) { @@ -148,13 +130,11 @@ return triangles; } - triangleCapsuleIntersect( capsule, triangle ) { triangle.getPlane( _plane ); const d1 = _plane.distanceToPoint( capsule.start ) - capsule.radius; const d2 = _plane.distanceToPoint( capsule.end ) - capsule.radius; - if ( d1 > 0 && d2 > 0 || d1 < - capsule.radius && d2 < - capsule.radius ) { return false; @@ -162,9 +142,7 @@ } const delta = Math.abs( d1 / ( Math.abs( d1 ) + Math.abs( d2 ) ) ); - const intersectPoint = _v1.copy( capsule.start ).lerp( capsule.end, delta ); - if ( triangle.containsPoint( intersectPoint ) ) { return { @@ -176,17 +154,12 @@ } const r2 = capsule.radius * capsule.radius; - const line1 = _line1.set( capsule.start, capsule.end ); - const lines = [[ triangle.a, triangle.b ], [ triangle.b, triangle.c ], [ triangle.c, triangle.a ]]; - for ( let i = 0; i < lines.length; i ++ ) { const line2 = _line2.set( lines[ i ][ 0 ], lines[ i ][ 1 ] ); - const [ point1, point2 ] = capsule.lineLineMinimumPoints( line1, line2 ); - if ( point1.distanceToSquared( point2 ) < r2 ) { return { @@ -202,16 +175,13 @@ return false; } - triangleSphereIntersect( sphere, triangle ) { triangle.getPlane( _plane ); if ( ! sphere.intersectsPlane( _plane ) ) return false; const depth = Math.abs( _plane.distanceToSphere( sphere ) ); const r2 = sphere.radius * sphere.radius - depth * depth; - const plainPoint = _plane.projectPoint( sphere.center, _v1 ); - if ( triangle.containsPoint( sphere.center ) ) { return { @@ -223,15 +193,11 @@ } const lines = [[ triangle.a, triangle.b ], [ triangle.b, triangle.c ], [ triangle.c, triangle.a ]]; - for ( let i = 0; i < lines.length; i ++ ) { _line1.set( lines[ i ][ 0 ], lines[ i ][ 1 ] ); - _line1.closestPointToPoint( plainPoint, true, _v2 ); - const d = _v2.distanceToSquared( sphere.center ); - if ( d < r2 ) { return { @@ -247,14 +213,12 @@ return false; } - getSphereTriangles( sphere, triangles ) { for ( let i = 0; i < this.subTrees.length; i ++ ) { const subTree = this.subTrees[ i ]; if ( ! sphere.intersectsBox( subTree.box ) ) continue; - if ( subTree.triangles.length > 0 ) { for ( let j = 0; j < subTree.triangles.length; j ++ ) { @@ -272,14 +236,12 @@ } } - getCapsuleTriangles( capsule, triangles ) { for ( let i = 0; i < this.subTrees.length; i ++ ) { const subTree = this.subTrees[ i ]; if ( ! capsule.intersectsBox( subTree.box ) ) continue; - if ( subTree.triangles.length > 0 ) { for ( let j = 0; j < subTree.triangles.length; j ++ ) { @@ -297,22 +259,18 @@ } } - sphereIntersect( sphere ) { _sphere.copy( sphere ); - const triangles = []; let result, hit = false; this.getSphereTriangles( sphere, triangles ); - for ( let i = 0; i < triangles.length; i ++ ) { if ( result = this.triangleSphereIntersect( _sphere, triangles[ i ] ) ) { hit = true; - _sphere.center.add( result.normal.multiplyScalar( result.depth ) ); } @@ -322,7 +280,6 @@ if ( hit ) { const collisionVector = _sphere.center.clone().sub( sphere.center ); - const depth = collisionVector.length(); return { normal: collisionVector.normalize(), @@ -334,22 +291,18 @@ return false; } - capsuleIntersect( capsule ) { _capsule.copy( capsule ); - const triangles = []; let result, hit = false; this.getCapsuleTriangles( _capsule, triangles ); - for ( let i = 0; i < triangles.length; i ++ ) { if ( result = this.triangleCapsuleIntersect( _capsule, triangles[ i ] ) ) { hit = true; - _capsule.translate( result.normal.multiplyScalar( result.depth ) ); } @@ -359,7 +312,6 @@ if ( hit ) { const collisionVector = _capsule.getCenter( new THREE.Vector3() ).sub( capsule.getCenter( _v1 ) ); - const depth = collisionVector.length(); return { normal: collisionVector.normalize(), @@ -371,7 +323,6 @@ return false; } - rayIntersect( ray ) { if ( ray.direction.length() === 0 ) return; @@ -380,15 +331,12 @@ position, distance = 1e100; this.getRayTriangles( ray, triangles ); - for ( let i = 0; i < triangles.length; i ++ ) { const result = ray.intersectTriangle( triangles[ i ].a, triangles[ i ].b, triangles[ i ].c, true, _v1 ); - if ( result ) { const newdistance = result.sub( ray.origin ).length(); - if ( distance > newdistance ) { position = result.clone().add( ray.origin ); @@ -408,7 +356,6 @@ } : false; } - fromGraphNode( group ) { group.updateWorldMatrix( true, true ); @@ -418,7 +365,6 @@ let geometry, isTemp = false; - if ( obj.geometry.index !== null ) { isTemp = true; @@ -431,7 +377,6 @@ } const positionAttribute = geometry.getAttribute( 'position' ); - for ( let i = 0; i < positionAttribute.count; i += 3 ) { const v1 = new THREE.Vector3().fromBufferAttribute( positionAttribute, i ); diff --git a/examples/js/math/SimplexNoise.js b/examples/js/math/SimplexNoise.js index 7ed8f15ef8cb07..9e2d26545845fb 100644 --- a/examples/js/math/SimplexNoise.js +++ b/examples/js/math/SimplexNoise.js @@ -19,76 +19,68 @@ this.grad3 = [[ 1, 1, 0 ], [ - 1, 1, 0 ], [ 1, - 1, 0 ], [ - 1, - 1, 0 ], [ 1, 0, 1 ], [ - 1, 0, 1 ], [ 1, 0, - 1 ], [ - 1, 0, - 1 ], [ 0, 1, 1 ], [ 0, - 1, 1 ], [ 0, 1, - 1 ], [ 0, - 1, - 1 ]]; this.grad4 = [[ 0, 1, 1, 1 ], [ 0, 1, 1, - 1 ], [ 0, 1, - 1, 1 ], [ 0, 1, - 1, - 1 ], [ 0, - 1, 1, 1 ], [ 0, - 1, 1, - 1 ], [ 0, - 1, - 1, 1 ], [ 0, - 1, - 1, - 1 ], [ 1, 0, 1, 1 ], [ 1, 0, 1, - 1 ], [ 1, 0, - 1, 1 ], [ 1, 0, - 1, - 1 ], [ - 1, 0, 1, 1 ], [ - 1, 0, 1, - 1 ], [ - 1, 0, - 1, 1 ], [ - 1, 0, - 1, - 1 ], [ 1, 1, 0, 1 ], [ 1, 1, 0, - 1 ], [ 1, - 1, 0, 1 ], [ 1, - 1, 0, - 1 ], [ - 1, 1, 0, 1 ], [ - 1, 1, 0, - 1 ], [ - 1, - 1, 0, 1 ], [ - 1, - 1, 0, - 1 ], [ 1, 1, 1, 0 ], [ 1, 1, - 1, 0 ], [ 1, - 1, 1, 0 ], [ 1, - 1, - 1, 0 ], [ - 1, 1, 1, 0 ], [ - 1, 1, - 1, 0 ], [ - 1, - 1, 1, 0 ], [ - 1, - 1, - 1, 0 ]]; this.p = []; - for ( let i = 0; i < 256; i ++ ) { this.p[ i ] = Math.floor( r.random() * 256 ); - } // To remove the need for index wrapping, double the permutation table length - + } + // To remove the need for index wrapping, double the permutation table length this.perm = []; - for ( let i = 0; i < 512; i ++ ) { this.perm[ i ] = this.p[ i & 255 ]; - } // A lookup table to traverse the simplex around a given point in 4D. - // Details can be found where this table is used, in the 4D noise method. - + } + // A lookup table to traverse the simplex around a given point in 4D. + // Details can be found where this table is used, in the 4D noise method. this.simplex = [[ 0, 1, 2, 3 ], [ 0, 1, 3, 2 ], [ 0, 0, 0, 0 ], [ 0, 2, 3, 1 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 1, 2, 3, 0 ], [ 0, 2, 1, 3 ], [ 0, 0, 0, 0 ], [ 0, 3, 1, 2 ], [ 0, 3, 2, 1 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 1, 3, 2, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 1, 2, 0, 3 ], [ 0, 0, 0, 0 ], [ 1, 3, 0, 2 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 2, 3, 0, 1 ], [ 2, 3, 1, 0 ], [ 1, 0, 2, 3 ], [ 1, 0, 3, 2 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 2, 0, 3, 1 ], [ 0, 0, 0, 0 ], [ 2, 1, 3, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 2, 0, 1, 3 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 3, 0, 1, 2 ], [ 3, 0, 2, 1 ], [ 0, 0, 0, 0 ], [ 3, 1, 2, 0 ], [ 2, 1, 0, 3 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 3, 1, 0, 2 ], [ 0, 0, 0, 0 ], [ 3, 2, 0, 1 ], [ 3, 2, 1, 0 ]]; } - dot( g, x, y ) { return g[ 0 ] * x + g[ 1 ] * y; } - dot3( g, x, y, z ) { return g[ 0 ] * x + g[ 1 ] * y + g[ 2 ] * z; } - dot4( g, x, y, z, w ) { return g[ 0 ] * x + g[ 1 ] * y + g[ 2 ] * z + g[ 3 ] * w; } - noise( xin, yin ) { let n0; // Noise contributions from the three corners - let n1; - let n2; // Skew the input space to determine which simplex cell we're in - + let n2; + // Skew the input space to determine which simplex cell we're in const F2 = 0.5 * ( Math.sqrt( 3.0 ) - 1.0 ); const s = ( xin + yin ) * F2; // Hairy factor for 2D - const i = Math.floor( xin + s ); const j = Math.floor( yin + s ); const G2 = ( 3.0 - Math.sqrt( 3.0 ) ) / 6.0; const t = ( i + j ) * G2; const X0 = i - t; // Unskew the cell origin back to (x,y) space - const Y0 = j - t; const x0 = xin - X0; // The x,y distances from the cell origin + const y0 = yin - Y0; - const y0 = yin - Y0; // For the 2D case, the simplex shape is an equilateral triangle. + // For the 2D case, the simplex shape is an equilateral triangle. // Determine which simplex we are in. - let i1; // Offsets for second (middle) corner of simplex in (i,j) coords let j1; - if ( x0 > y0 ) { i1 = 1; - j1 = 0; // lower triangle, XY order: (0,0)->(1,0)->(1,1) + j1 = 0; + + // lower triangle, XY order: (0,0)->(1,0)->(1,1) } else { @@ -96,24 +88,21 @@ j1 = 1; } // upper triangle, YX order: (0,0)->(0,1)->(1,1) + // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where // c = (3-sqrt(3))/6 - - const x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords - const y1 = y0 - j1 + G2; const x2 = x0 - 1.0 + 2.0 * G2; // Offsets for last corner in (x,y) unskewed coords - - const y2 = y0 - 1.0 + 2.0 * G2; // Work out the hashed gradient indices of the three simplex corners - + const y2 = y0 - 1.0 + 2.0 * G2; + // Work out the hashed gradient indices of the three simplex corners const ii = i & 255; const jj = j & 255; const gi0 = this.perm[ ii + this.perm[ jj ] ] % 12; const gi1 = this.perm[ ii + i1 + this.perm[ jj + j1 ] ] % 12; - const gi2 = this.perm[ ii + 1 + this.perm[ jj + 1 ] ] % 12; // Calculate the contribution from the three corners - + const gi2 = this.perm[ ii + 1 + this.perm[ jj + 1 ] ] % 12; + // Calculate the contribution from the three corners let t0 = 0.5 - x0 * x0 - y0 * y0; if ( t0 < 0 ) n0 = 0.0; else { @@ -136,50 +125,45 @@ t2 *= t2; n2 = t2 * t2 * this.dot( this.grad3[ gi2 ], x2, y2 ); - } // Add contributions from each corner to get the final noise value. - // The result is scaled to return values in the interval [-1,1]. + } + // Add contributions from each corner to get the final noise value. + // The result is scaled to return values in the interval [-1,1]. return 70.0 * ( n0 + n1 + n2 ); - } // 3D simplex noise - + } + // 3D simplex noise noise3d( xin, yin, zin ) { let n0; // Noise contributions from the four corners - let n1; let n2; - let n3; // Skew the input space to determine which simplex cell we're in - + let n3; + // Skew the input space to determine which simplex cell we're in const F3 = 1.0 / 3.0; const s = ( xin + yin + zin ) * F3; // Very nice and simple skew factor for 3D - const i = Math.floor( xin + s ); const j = Math.floor( yin + s ); const k = Math.floor( zin + s ); const G3 = 1.0 / 6.0; // Very nice and simple unskew factor, too - const t = ( i + j + k ) * G3; const X0 = i - t; // Unskew the cell origin back to (x,y,z) space - const Y0 = j - t; const Z0 = k - t; const x0 = xin - X0; // The x,y,z distances from the cell origin - const y0 = yin - Y0; - const z0 = zin - Z0; // For the 3D case, the simplex shape is a slightly irregular tetrahedron. - // Determine which simplex we are in. + const z0 = zin - Z0; + // For the 3D case, the simplex shape is a slightly irregular tetrahedron. + // Determine which simplex we are in. let i1; // Offsets for second corner of simplex in (i,j,k) coords let j1; let k1; let i2; // Offsets for third corner of simplex in (i,j,k) coords - let j2; let k2; - if ( x0 >= y0 ) { if ( y0 >= z0 ) { @@ -189,7 +173,9 @@ k1 = 0; i2 = 1; j2 = 1; - k2 = 0; // X Y Z order + k2 = 0; + + // X Y Z order } else if ( x0 >= z0 ) { @@ -198,7 +184,9 @@ k1 = 0; i2 = 1; j2 = 0; - k2 = 1; // X Z Y order + k2 = 1; + + // X Z Y order } else { @@ -214,6 +202,7 @@ } else { // x0 y0 ? 32 : 0; const c2 = x0 > z0 ? 16 : 0; const c3 = y0 > z0 ? 8 : 0; const c4 = x0 > w0 ? 4 : 0; const c5 = y0 > w0 ? 2 : 0; const c6 = z0 > w0 ? 1 : 0; - const c = c1 + c2 + c3 + c4 + c5 + c6; // simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order. + const c = c1 + c2 + c3 + c4 + c5 + c6; + + // simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order. // Many values of c will never occur, since e.g. x>y>z>w makes x= 3 ? 1 : 0; const j1 = simplex[ c ][ 1 ] >= 3 ? 1 : 0; const k1 = simplex[ c ][ 2 ] >= 3 ? 1 : 0; - const l1 = simplex[ c ][ 3 ] >= 3 ? 1 : 0; // The number 2 in the "simplex" array is at the second largest coordinate. - + const l1 = simplex[ c ][ 3 ] >= 3 ? 1 : 0; + // The number 2 in the "simplex" array is at the second largest coordinate. const i2 = simplex[ c ][ 0 ] >= 2 ? 1 : 0; const j2 = simplex[ c ][ 1 ] >= 2 ? 1 : 0; const k2 = simplex[ c ][ 2 ] >= 2 ? 1 : 0; - const l2 = simplex[ c ][ 3 ] >= 2 ? 1 : 0; // The number 1 in the "simplex" array is at the second smallest coordinate. - + const l2 = simplex[ c ][ 3 ] >= 2 ? 1 : 0; + // The number 1 in the "simplex" array is at the second smallest coordinate. const i3 = simplex[ c ][ 0 ] >= 1 ? 1 : 0; const j3 = simplex[ c ][ 1 ] >= 1 ? 1 : 0; const k3 = simplex[ c ][ 2 ] >= 1 ? 1 : 0; - const l3 = simplex[ c ][ 3 ] >= 1 ? 1 : 0; // The fifth corner has all coordinate offsets = 1, so no need to look that up. - + const l3 = simplex[ c ][ 3 ] >= 1 ? 1 : 0; + // The fifth corner has all coordinate offsets = 1, so no need to look that up. const x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords - const y1 = y0 - j1 + G4; const z1 = z0 - k1 + G4; const w1 = w0 - l1 + G4; const x2 = x0 - i2 + 2.0 * G4; // Offsets for third corner in (x,y,z,w) coords - const y2 = y0 - j2 + 2.0 * G4; const z2 = z0 - k2 + 2.0 * G4; const w2 = w0 - l2 + 2.0 * G4; const x3 = x0 - i3 + 3.0 * G4; // Offsets for fourth corner in (x,y,z,w) coords - const y3 = y0 - j3 + 3.0 * G4; const z3 = z0 - k3 + 3.0 * G4; const w3 = w0 - l3 + 3.0 * G4; const x4 = x0 - 1.0 + 4.0 * G4; // Offsets for last corner in (x,y,z,w) coords - const y4 = y0 - 1.0 + 4.0 * G4; const z4 = z0 - 1.0 + 4.0 * G4; - const w4 = w0 - 1.0 + 4.0 * G4; // Work out the hashed gradient indices of the five simplex corners - + const w4 = w0 - 1.0 + 4.0 * G4; + // Work out the hashed gradient indices of the five simplex corners const ii = i & 255; const jj = j & 255; const kk = k & 255; @@ -406,8 +391,8 @@ const gi1 = perm[ ii + i1 + perm[ jj + j1 + perm[ kk + k1 + perm[ ll + l1 ] ] ] ] % 32; const gi2 = perm[ ii + i2 + perm[ jj + j2 + perm[ kk + k2 + perm[ ll + l2 ] ] ] ] % 32; const gi3 = perm[ ii + i3 + perm[ jj + j3 + perm[ kk + k3 + perm[ ll + l3 ] ] ] ] % 32; - const gi4 = perm[ ii + 1 + perm[ jj + 1 + perm[ kk + 1 + perm[ ll + 1 ] ] ] ] % 32; // Calculate the contribution from the five corners - + const gi4 = perm[ ii + 1 + perm[ jj + 1 + perm[ kk + 1 + perm[ ll + 1 ] ] ] ] % 32; + // Calculate the contribution from the five corners let t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0; if ( t0 < 0 ) n0 = 0.0; else { @@ -446,8 +431,9 @@ t4 *= t4; n4 = t4 * t4 * this.dot4( grad4[ gi4 ], x4, y4, z4, w4 ); - } // Sum up and scale the result to cover the range [-1,1] + } + // Sum up and scale the result to cover the range [-1,1] return 27.0 * ( n0 + n1 + n2 + n3 + n4 ); } diff --git a/examples/js/misc/ConvexObjectBreaker.js b/examples/js/misc/ConvexObjectBreaker.js index 126c746088ac92..e3b10af2e75955 100644 --- a/examples/js/misc/ConvexObjectBreaker.js +++ b/examples/js/misc/ConvexObjectBreaker.js @@ -30,7 +30,6 @@ */ const _v1 = new THREE.Vector3(); - class ConvexObjectBreaker { constructor( minSizeForBreak = 1.4, smallDelta = 0.0001 ) { @@ -59,16 +58,15 @@ }; this.segments = []; const n = 30 * 30; - for ( let i = 0; i < n; i ++ ) this.segments[ i ] = false; } - prepareBreakableObject( object, mass, velocity, angularVelocity, breakable ) { // object is a Object3d (normally a THREE.Mesh), must have a BufferGeometry, and it must be convex. // Its material property is propagated to its children (sub-pieces) // mass must be > 0 + if ( ! object.geometry.isBufferGeometry ) { console.error( 'THREE.ConvexObjectBreaker.prepareBreakableObject(): Parameter object must have a BufferGeometry.' ); @@ -82,14 +80,13 @@ userData.breakable = breakable; } + /* * @param {int} maxRadialIterations Iterations for radial cuts. * @param {int} maxRandomIterations Max random iterations for not-radial cuts * * Returns the array of pieces */ - - subdivideByImpact( object, pointOfImpact, normal, maxRadialIterations, maxRandomIterations ) { const debris = []; @@ -99,7 +96,6 @@ tempPlane1.setFromCoplanarPoints( pointOfImpact, object.position, this.tempVector3 ); const maxTotalIterations = maxRandomIterations + maxRadialIterations; const scope = this; - function subdivideRadial( subObject, startAngle, endAngle, numIterations ) { if ( Math.random() < numIterations * 0.05 || numIterations > maxTotalIterations ) { @@ -110,7 +106,6 @@ } let angle = Math.PI; - if ( numIterations === 0 ) { tempPlane2.normal.copy( tempPlane1.normal ); @@ -120,28 +115,29 @@ if ( numIterations <= maxRadialIterations ) { - angle = ( endAngle - startAngle ) * ( 0.2 + 0.6 * Math.random() ) + startAngle; // Rotate tempPlane2 at impact point around normal axis and the angle + angle = ( endAngle - startAngle ) * ( 0.2 + 0.6 * Math.random() ) + startAngle; + // Rotate tempPlane2 at impact point around normal axis and the angle scope.tempVector3_2.copy( object.position ).sub( pointOfImpact ).applyAxisAngle( normal, angle ).add( pointOfImpact ); tempPlane2.setFromCoplanarPoints( pointOfImpact, scope.tempVector3, scope.tempVector3_2 ); } else { - angle = ( 0.5 * ( numIterations & 1 ) + 0.2 * ( 2 - Math.random() ) ) * Math.PI; // Rotate tempPlane2 at object position around normal axis and the angle + angle = ( 0.5 * ( numIterations & 1 ) + 0.2 * ( 2 - Math.random() ) ) * Math.PI; + // Rotate tempPlane2 at object position around normal axis and the angle scope.tempVector3_2.copy( pointOfImpact ).sub( subObject.position ).applyAxisAngle( normal, angle ).add( subObject.position ); scope.tempVector3_3.copy( normal ).add( subObject.position ); tempPlane2.setFromCoplanarPoints( subObject.position, scope.tempVector3_3, scope.tempVector3_2 ); } - } // Perform the cut - + } + // Perform the cut scope.cutByPlane( subObject, tempPlane2, scope.tempResultObjects ); const obj1 = scope.tempResultObjects.object1; const obj2 = scope.tempResultObjects.object2; - if ( obj1 ) { subdivideRadial( obj1, startAngle, angle, numIterations + 1 ); @@ -160,20 +156,19 @@ return debris; } - cutByPlane( object, plane, output ) { // Returns breakable objects in output.object1 and output.object2 members, the resulting 2 pieces of the cut. // object2 can be null if the plane doesn't cut the object. // object1 can be null only in case of internal error // Returned value is number of pieces, 0 for error. + const geometry = object.geometry; const coords = geometry.attributes.position.array; const normals = geometry.attributes.normal.array; const numPoints = coords.length / 3; let numFaces = numPoints / 3; let indices = geometry.getIndex(); - if ( indices ) { indices = indices.array; @@ -184,6 +179,7 @@ function getVertexIndex( faceIdx, vert ) { // vert = 0, 1 or 2. + const idx = faceIdx * 3 + vert; return indices ? indices[ idx ] : idx; @@ -191,34 +187,34 @@ const points1 = []; const points2 = []; - const delta = this.smallDelta; // Reset segments mark + const delta = this.smallDelta; + // Reset segments mark const numPointPairs = numPoints * numPoints; - for ( let i = 0; i < numPointPairs; i ++ ) this.segments[ i ] = false; - const p0 = this.tempVector3_P0; const p1 = this.tempVector3_P1; const n0 = this.tempVector3_N0; - const n1 = this.tempVector3_N1; // Iterate through the faces to mark edges shared by coplanar faces + const n1 = this.tempVector3_N1; + // Iterate through the faces to mark edges shared by coplanar faces for ( let i = 0; i < numFaces - 1; i ++ ) { const a1 = getVertexIndex( i, 0 ); const b1 = getVertexIndex( i, 1 ); - const c1 = getVertexIndex( i, 2 ); // Assuming all 3 vertices have the same normal + const c1 = getVertexIndex( i, 2 ); + // Assuming all 3 vertices have the same normal n0.set( normals[ a1 ], normals[ a1 ] + 1, normals[ a1 ] + 2 ); - for ( let j = i + 1; j < numFaces; j ++ ) { const a2 = getVertexIndex( j, 0 ); const b2 = getVertexIndex( j, 1 ); - const c2 = getVertexIndex( j, 2 ); // Assuming all 3 vertices have the same normal + const c2 = getVertexIndex( j, 2 ); + // Assuming all 3 vertices have the same normal n1.set( normals[ a2 ], normals[ a2 ] + 1, normals[ a2 ] + 2 ); const coplanar = 1 - n0.dot( n1 ) < delta; - if ( coplanar ) { if ( a1 === a2 || a1 === b2 || a1 === c2 ) { @@ -246,35 +242,35 @@ } - } // Transform the plane to object local space - + } + // Transform the plane to object local space const localPlane = this.tempPlane_Cut; object.updateMatrix(); - ConvexObjectBreaker.transformPlaneToLocalSpace( plane, object.matrix, localPlane ); // Iterate through the faces adding points to both pieces + ConvexObjectBreaker.transformPlaneToLocalSpace( plane, object.matrix, localPlane ); + // Iterate through the faces adding points to both pieces for ( let i = 0; i < numFaces; i ++ ) { const va = getVertexIndex( i, 0 ); const vb = getVertexIndex( i, 1 ); const vc = getVertexIndex( i, 2 ); - for ( let segment = 0; segment < 3; segment ++ ) { const i0 = segment === 0 ? va : segment === 1 ? vb : vc; const i1 = segment === 0 ? vb : segment === 1 ? vc : va; const segmentState = this.segments[ i0 * numPoints + i1 ]; if ( segmentState ) continue; // The segment already has been processed in another face - // Mark segment as processed (also inverted segment) + // Mark segment as processed (also inverted segment) this.segments[ i0 * numPoints + i1 ] = true; this.segments[ i1 * numPoints + i0 ] = true; p0.set( coords[ 3 * i0 ], coords[ 3 * i0 + 1 ], coords[ 3 * i0 + 2 ] ); - p1.set( coords[ 3 * i1 ], coords[ 3 * i1 + 1 ], coords[ 3 * i1 + 2 ] ); // mark: 1 for negative side, 2 for positive side, 3 for coplanar point + p1.set( coords[ 3 * i1 ], coords[ 3 * i1 + 1 ], coords[ 3 * i1 + 2 ] ); + // mark: 1 for negative side, 2 for positive side, 3 for coplanar point let mark0 = 0; let d = localPlane.distanceToPoint( p0 ); - if ( d > delta ) { mark0 = 2; @@ -291,12 +287,11 @@ points1.push( p0.clone() ); points2.push( p0.clone() ); - } // mark: 1 for negative side, 2 for positive side, 3 for coplanar point - + } + // mark: 1 for negative side, 2 for positive side, 3 for coplanar point let mark1 = 0; d = localPlane.distanceToPoint( p1 ); - if ( d > delta ) { mark1 = 2; @@ -318,11 +313,11 @@ if ( mark0 === 1 && mark1 === 2 || mark0 === 2 && mark1 === 1 ) { // Intersection of segment with the plane + this.tempLine1.start.copy( p0 ); this.tempLine1.end.copy( p1 ); let intersection = new THREE.Vector3(); intersection = localPlane.intersectLine( this.tempLine1, intersection ); - if ( intersection === null ) { // Shouldn't happen @@ -340,21 +335,19 @@ } - } // Calculate debris mass (very fast and imprecise): - + } - const newMass = object.userData.mass * 0.5; // Calculate debris Center of Mass (again fast and imprecise) + // Calculate debris mass (very fast and imprecise): + const newMass = object.userData.mass * 0.5; + // Calculate debris Center of Mass (again fast and imprecise) this.tempCM1.set( 0, 0, 0 ); let radius1 = 0; const numPoints1 = points1.length; - if ( numPoints1 > 0 ) { for ( let i = 0; i < numPoints1; i ++ ) this.tempCM1.add( points1[ i ] ); - this.tempCM1.divideScalar( numPoints1 ); - for ( let i = 0; i < numPoints1; i ++ ) { const p = points1[ i ]; @@ -370,13 +363,10 @@ this.tempCM2.set( 0, 0, 0 ); let radius2 = 0; const numPoints2 = points2.length; - if ( numPoints2 > 0 ) { for ( let i = 0; i < numPoints2; i ++ ) this.tempCM2.add( points2[ i ] ); - this.tempCM2.divideScalar( numPoints2 ); - for ( let i = 0; i < numPoints2; i ++ ) { const p = points2[ i ]; @@ -392,7 +382,6 @@ let object1 = null; let object2 = null; let numObjects = 0; - if ( numPoints1 > 4 ) { object1 = new THREE.Mesh( new THREE.ConvexGeometry( points1 ), object.material ); @@ -418,12 +407,12 @@ return numObjects; } - static transformFreeVector( v, m ) { // input: // vector interpreted as a free vector // THREE.Matrix4 orthogonal matrix (matrix without scale) + const x = v.x, y = v.y, z = v.z; @@ -434,12 +423,12 @@ return v; } - static transformFreeVectorInverse( v, m ) { // input: // vector interpreted as a free vector // THREE.Matrix4 orthogonal matrix (matrix without scale) + const x = v.x, y = v.y, z = v.z; @@ -450,12 +439,12 @@ return v; } - static transformTiedVectorInverse( v, m ) { // input: // vector interpreted as a tied (ordinary) vector // THREE.Matrix4 orthogonal matrix (matrix without scale) + const x = v.x, y = v.y, z = v.z; @@ -466,14 +455,14 @@ return v; } - static transformPlaneToLocalSpace( plane, m, resultPlane ) { resultPlane.normal.copy( plane.normal ); resultPlane.constant = plane.constant; const referencePoint = ConvexObjectBreaker.transformTiedVectorInverse( plane.coplanarPoint( _v1 ), m ); - ConvexObjectBreaker.transformFreeVectorInverse( resultPlane.normal, m ); // recalculate constant (like in setFromNormalAndCoplanarPoint) + ConvexObjectBreaker.transformFreeVectorInverse( resultPlane.normal, m ); + // recalculate constant (like in setFromNormalAndCoplanarPoint) resultPlane.constant = - referencePoint.dot( resultPlane.normal ); } diff --git a/examples/js/misc/GPUComputationRenderer.js b/examples/js/misc/GPUComputationRenderer.js index 63fad76e8e87f8..1802469ff80b2c 100644 --- a/examples/js/misc/GPUComputationRenderer.js +++ b/examples/js/misc/GPUComputationRenderer.js @@ -115,7 +115,6 @@ const passThruShader = createShaderMaterial( getPassThroughFragmentShader(), passThruUniforms ); const mesh = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), passThruShader ); scene.add( mesh ); - this.setDataType = function ( type ) { dataType = type; @@ -164,27 +163,26 @@ for ( let i = 0; i < this.variables.length; i ++ ) { - const variable = this.variables[ i ]; // Creates rendertargets and initialize them with input texture + const variable = this.variables[ i ]; + // Creates rendertargets and initialize them with input texture variable.renderTargets[ 0 ] = this.createRenderTarget( sizeX, sizeY, variable.wrapS, variable.wrapT, variable.minFilter, variable.magFilter ); variable.renderTargets[ 1 ] = this.createRenderTarget( sizeX, sizeY, variable.wrapS, variable.wrapT, variable.minFilter, variable.magFilter ); this.renderTexture( variable.initialValueTexture, variable.renderTargets[ 0 ] ); - this.renderTexture( variable.initialValueTexture, variable.renderTargets[ 1 ] ); // Adds dependencies uniforms to the THREE.ShaderMaterial + this.renderTexture( variable.initialValueTexture, variable.renderTargets[ 1 ] ); + // Adds dependencies uniforms to the THREE.ShaderMaterial const material = variable.material; const uniforms = material.uniforms; - if ( variable.dependencies !== null ) { for ( let d = 0; d < variable.dependencies.length; d ++ ) { const depVar = variable.dependencies[ d ]; - if ( depVar.name !== variable.name ) { // Checks if variable exists let found = false; - for ( let j = 0; j < this.variables.length; j ++ ) { if ( depVar.name === this.variables[ j ].name ) { @@ -224,15 +222,14 @@ const currentTextureIndex = this.currentTextureIndex; const nextTextureIndex = this.currentTextureIndex === 0 ? 1 : 0; - for ( let i = 0, il = this.variables.length; i < il; i ++ ) { - const variable = this.variables[ i ]; // Sets texture dependencies uniforms + const variable = this.variables[ i ]; + // Sets texture dependencies uniforms if ( variable.dependencies !== null ) { const uniforms = variable.material.uniforms; - for ( let d = 0, dl = variable.dependencies.length; d < dl; d ++ ) { const depVar = variable.dependencies[ d ]; @@ -240,9 +237,9 @@ } - } // Performs the computation for this variable - + } + // Performs the computation for this variable this.doRenderTarget( variable.material, variable.renderTargets[ nextTextureIndex ] ); } @@ -263,13 +260,36 @@ }; + this.dispose = function () { + + mesh.geometry.dispose(); + mesh.material.dispose(); + const variables = this.variables; + for ( let i = 0; i < variables.length; i ++ ) { + + const variable = variables[ i ]; + variable.initialValueTexture?.dispose(); + const renderTargets = variable.renderTargets; + for ( let j = 0; j < renderTargets.length; j ++ ) { + + const renderTarget = renderTargets[ j ]; + renderTarget.dispose(); + + } + + } + + }; + function addResolutionDefine( materialShader ) { materialShader.defines.resolution = 'vec2( ' + sizeX.toFixed( 1 ) + ', ' + sizeY.toFixed( 1 ) + ' )'; } - this.addResolutionDefine = addResolutionDefine; // The following functions can be used to compute things manually + this.addResolutionDefine = addResolutionDefine; + + // The following functions can be used to compute things manually function createShaderMaterial( computeFragmentShader, uniforms ) { @@ -285,7 +305,6 @@ } this.createShaderMaterial = createShaderMaterial; - this.createRenderTarget = function ( sizeXTexture, sizeYTexture, wrapS, wrapT, minFilter, magFilter ) { sizeXTexture = sizeXTexture || sizeX; @@ -321,6 +340,7 @@ // Takes a texture, and render out in rendertarget // input = Texture // output = RenderTarget + passThruUniforms.passThruTexture.value = input; this.doRenderTarget( passThruShader, output ); passThruUniforms.passThruTexture.value = null; @@ -330,14 +350,27 @@ this.doRenderTarget = function ( material, output ) { const currentRenderTarget = renderer.getRenderTarget(); + const currentXrEnabled = renderer.xr.enabled; + const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate; + const currentOutputEncoding = renderer.outputEncoding; + const currentToneMapping = renderer.toneMapping; + renderer.xr.enabled = false; // Avoid camera modification + renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows + renderer.outputEncoding = THREE.LinearEncoding; + renderer.toneMapping = THREE.NoToneMapping; mesh.material = material; renderer.setRenderTarget( output ); renderer.render( scene, camera ); mesh.material = passThruShader; + renderer.xr.enabled = currentXrEnabled; + renderer.shadowMap.autoUpdate = currentShadowAutoUpdate; + renderer.outputEncoding = currentOutputEncoding; + renderer.toneMapping = currentToneMapping; renderer.setRenderTarget( currentRenderTarget ); - }; // Shaders + }; + // Shaders function getPassThroughVertexShader() { diff --git a/examples/js/misc/Gyroscope.js b/examples/js/misc/Gyroscope.js index 85f723caafabc0..dd1c5e2acad439 100644 --- a/examples/js/misc/Gyroscope.js +++ b/examples/js/misc/Gyroscope.js @@ -1,17 +1,11 @@ ( function () { const _translationObject = new THREE.Vector3(); - const _quaternionObject = new THREE.Quaternion(); - const _scaleObject = new THREE.Vector3(); - const _translationWorld = new THREE.Vector3(); - const _quaternionWorld = new THREE.Quaternion(); - const _scaleWorld = new THREE.Vector3(); - class Gyroscope extends THREE.Object3D { constructor() { @@ -19,10 +13,11 @@ super(); } - updateMatrixWorld( force ) { - this.matrixAutoUpdate && this.updateMatrix(); // update matrixWorld + this.matrixAutoUpdate && this.updateMatrix(); + + // update matrixWorld if ( this.matrixWorldNeedsUpdate || force ) { @@ -42,8 +37,9 @@ this.matrixWorldNeedsUpdate = false; force = true; - } // update children + } + // update children for ( let i = 0, l = this.children.length; i < l; i ++ ) { diff --git a/examples/js/misc/MD2Character.js b/examples/js/misc/MD2Character.js index 9a576d0cc96bc3..3102a9af08cfde 100644 --- a/examples/js/misc/MD2Character.js +++ b/examples/js/misc/MD2Character.js @@ -14,17 +14,14 @@ this.weapons = []; this.activeAnimation = null; this.mixer = null; - this.onLoadComplete = function () {}; this.loadCounter = 0; } - loadParts( config ) { const scope = this; - function createPart( geometry, skinMap ) { const materialWireframe = new THREE.MeshLambertMaterial( { @@ -35,12 +32,16 @@ color: 0xffffff, wireframe: false, map: skinMap - } ); // + } ); + + // const mesh = new THREE.Mesh( geometry, materialTexture ); mesh.rotation.y = - Math.PI / 2; mesh.castShadow = true; - mesh.receiveShadow = true; // + mesh.receiveShadow = true; + + // mesh.materialTexture = materialTexture; mesh.materialWireframe = materialWireframe; @@ -52,7 +53,6 @@ const textureLoader = new THREE.TextureLoader(); const textures = []; - for ( let i = 0; i < textureUrls.length; i ++ ) { textures[ i ] = textureLoader.load( baseUrl + textureUrls[ i ], checkLoadingComplete ); @@ -75,12 +75,13 @@ this.loadCounter = config.weapons.length * 2 + config.skins.length + 1; const weaponsTextures = []; - - for ( let i = 0; i < config.weapons.length; i ++ ) weaponsTextures[ i ] = config.weapons[ i ][ 1 ]; // SKINS - + for ( let i = 0; i < config.weapons.length; i ++ ) weaponsTextures[ i ] = config.weapons[ i ][ 1 ]; + // SKINS this.skinsBody = loadTextures( config.baseUrl + 'skins/', config.skins ); - this.skinsWeapon = loadTextures( config.baseUrl + 'skins/', weaponsTextures ); // BODY + this.skinsWeapon = loadTextures( config.baseUrl + 'skins/', weaponsTextures ); + + // BODY const loader = new THREE.MD2Loader(); loader.load( config.baseUrl + config.body, function ( geo ) { @@ -97,7 +98,9 @@ scope.mixer = new THREE.AnimationMixer( mesh ); checkLoadingComplete(); - } ); // WEAPONS + } ); + + // WEAPONS const generateCallback = function ( index, name ) { @@ -123,7 +126,6 @@ } } - setPlaybackRate( rate ) { if ( rate !== 0 ) { @@ -137,7 +139,6 @@ } } - setWireframe( wireframeEnabled ) { if ( wireframeEnabled ) { @@ -153,7 +154,6 @@ } } - setSkin( index ) { if ( this.meshBody && this.meshBody.material.wireframe === false ) { @@ -163,13 +163,10 @@ } } - setWeapon( index ) { for ( let i = 0; i < this.weapons.length; i ++ ) this.weapons[ i ].visible = false; - const activeWeapon = this.weapons[ index ]; - if ( activeWeapon ) { activeWeapon.visible = true; @@ -179,7 +176,6 @@ } } - setAnimation( clipName ) { if ( this.meshBody ) { @@ -192,7 +188,6 @@ } const action = this.mixer.clipAction( clipName, this.meshBody ); - if ( action ) { this.meshBody.activeAction = action.play(); @@ -205,11 +200,9 @@ this.syncWeaponAnimation(); } - syncWeaponAnimation() { const clipName = this.activeClipName; - if ( this.meshWeapon ) { if ( this.meshWeapon.activeAction ) { @@ -220,7 +213,6 @@ } const action = this.mixer.clipAction( clipName, this.meshWeapon ); - if ( action ) { this.meshWeapon.activeAction = action.syncWith( this.meshBody.activeAction ).play(); @@ -230,7 +222,6 @@ } } - update( delta ) { if ( this.mixer ) this.mixer.update( delta ); diff --git a/examples/js/misc/MD2CharacterComplex.js b/examples/js/misc/MD2CharacterComplex.js index ca7613af8c6633..f32f9fef0dfcaa 100644 --- a/examples/js/misc/MD2CharacterComplex.js +++ b/examples/js/misc/MD2CharacterComplex.js @@ -4,42 +4,59 @@ constructor() { - this.scale = 1; // animation parameters + this.scale = 1; + + // animation parameters this.animationFPS = 6; - this.transitionFrames = 15; // movement model parameters + this.transitionFrames = 15; + + // movement model parameters this.maxSpeed = 275; this.maxReverseSpeed = - 275; this.frontAcceleration = 600; this.backAcceleration = 600; this.frontDecceleration = 600; - this.angularSpeed = 2.5; // rig + this.angularSpeed = 2.5; + + // rig this.root = new THREE.Object3D(); this.meshBody = null; this.meshWeapon = null; - this.controls = null; // skins + this.controls = null; + + // skins this.skinsBody = []; this.skinsWeapon = []; this.weapons = []; - this.currentSkin = undefined; // + this.currentSkin = undefined; - this.onLoadComplete = function () {}; // internals + // + this.onLoadComplete = function () {}; + + // internals this.meshes = []; this.animations = {}; - this.loadCounter = 0; // internal movement control variables + this.loadCounter = 0; + + // internal movement control variables this.speed = 0; this.bodyOrientation = 0; this.walkSpeed = this.maxSpeed; - this.crouchSpeed = this.maxSpeed * 0.5; // internal animation parameters + this.crouchSpeed = this.maxSpeed * 0.5; + + // internal animation parameters this.activeAnimation = null; - this.oldAnimation = null; // API + this.oldAnimation = null; + + // API } @@ -53,7 +70,6 @@ } } - setVisible( enable ) { for ( let i = 0; i < this.meshes.length; i ++ ) { @@ -64,27 +80,28 @@ } } - shareParts( original ) { this.animations = original.animations; this.walkSpeed = original.walkSpeed; this.crouchSpeed = original.crouchSpeed; this.skinsBody = original.skinsBody; - this.skinsWeapon = original.skinsWeapon; // BODY + this.skinsWeapon = original.skinsWeapon; - const mesh = this._createPart( original.meshBody.geometry, this.skinsBody[ 0 ] ); + // BODY + const mesh = this._createPart( original.meshBody.geometry, this.skinsBody[ 0 ] ); mesh.scale.set( this.scale, this.scale, this.scale ); this.root.position.y = original.root.position.y; this.root.add( mesh ); this.meshBody = mesh; - this.meshes.push( mesh ); // WEAPONS + this.meshes.push( mesh ); + + // WEAPONS for ( let i = 0; i < original.weapons.length; i ++ ) { const meshWeapon = this._createPart( original.weapons[ i ].geometry, this.skinsWeapon[ i ] ); - meshWeapon.scale.set( this.scale, this.scale, this.scale ); meshWeapon.visible = false; meshWeapon.name = original.weapons[ i ].name; @@ -96,16 +113,13 @@ } } - loadParts( config ) { const scope = this; - function loadTextures( baseUrl, textureUrls ) { const textureLoader = new THREE.TextureLoader(); const textures = []; - for ( let i = 0; i < textureUrls.length; i ++ ) { textures[ i ] = textureLoader.load( baseUrl + textureUrls[ i ], checkLoadingComplete ); @@ -131,12 +145,14 @@ this.crouchSpeed = config.crouchSpeed; this.loadCounter = config.weapons.length * 2 + config.skins.length + 1; const weaponsTextures = []; + for ( let i = 0; i < config.weapons.length; i ++ ) weaponsTextures[ i ] = config.weapons[ i ][ 1 ]; - for ( let i = 0; i < config.weapons.length; i ++ ) weaponsTextures[ i ] = config.weapons[ i ][ 1 ]; // SKINS - + // SKINS this.skinsBody = loadTextures( config.baseUrl + 'skins/', config.skins ); - this.skinsWeapon = loadTextures( config.baseUrl + 'skins/', weaponsTextures ); // BODY + this.skinsWeapon = loadTextures( config.baseUrl + 'skins/', weaponsTextures ); + + // BODY const loader = new THREE.MD2Loader(); loader.load( config.baseUrl + config.body, function ( geo ) { @@ -144,23 +160,22 @@ const boundingBox = new THREE.Box3(); boundingBox.setFromBufferAttribute( geo.attributes.position ); scope.root.position.y = - scope.scale * boundingBox.min.y; - const mesh = scope._createPart( geo, scope.skinsBody[ 0 ] ); - mesh.scale.set( scope.scale, scope.scale, scope.scale ); scope.root.add( mesh ); scope.meshBody = mesh; scope.meshes.push( mesh ); checkLoadingComplete(); - } ); // WEAPONS + } ); + + // WEAPONS const generateCallback = function ( index, name ) { return function ( geo ) { const mesh = scope._createPart( geo, scope.skinsWeapon[ index ] ); - mesh.scale.set( scope.scale, scope.scale, scope.scale ); mesh.visible = false; mesh.name = name; @@ -181,14 +196,12 @@ } } - setPlaybackRate( rate ) { if ( this.meshBody ) this.meshBody.duration = this.meshBody.baseDuration / rate; if ( this.meshWeapon ) this.meshWeapon.duration = this.meshWeapon.baseDuration / rate; } - setWireframe( wireframeEnabled ) { if ( wireframeEnabled ) { @@ -204,7 +217,6 @@ } } - setSkin( index ) { if ( this.meshBody && this.meshBody.material.wireframe === false ) { @@ -215,18 +227,14 @@ } } - setWeapon( index ) { for ( let i = 0; i < this.weapons.length; i ++ ) this.weapons[ i ].visible = false; - const activeWeapon = this.weapons[ index ]; - if ( activeWeapon ) { activeWeapon.visible = true; this.meshWeapon = activeWeapon; - if ( this.activeAnimation ) { activeWeapon.playAnimation( this.activeAnimation ); @@ -237,11 +245,9 @@ } } - setAnimation( animationName ) { if ( animationName === this.activeAnimation || ! animationName ) return; - if ( this.meshBody ) { this.meshBody.setAnimationWeight( animationName, 0 ); @@ -260,11 +266,9 @@ } } - update( delta ) { if ( this.controls ) this.updateMovementModel( delta ); - if ( this.animations ) { this.updateBehaviors(); @@ -273,11 +277,9 @@ } } - updateAnimations( delta ) { let mix = 1; - if ( this.blendCounter > 0 ) { mix = ( this.transitionFrames - this.blendCounter ) / this.transitionFrames; @@ -302,12 +304,13 @@ } } - updateBehaviors() { const controls = this.controls; const animations = this.animations; - let moveAnimation, idleAnimation; // crouch vs stand + let moveAnimation, idleAnimation; + + // crouch vs stand if ( controls.crouch ) { @@ -319,8 +322,9 @@ moveAnimation = animations[ 'move' ]; idleAnimation = animations[ 'idle' ]; - } // actions + } + // actions if ( controls.jump ) { @@ -343,8 +347,9 @@ } - } // set animations + } + // set animations if ( controls.moveForward || controls.moveBackward || controls.moveLeft || controls.moveRight ) { @@ -364,8 +369,9 @@ } - } // set animation direction + } + // set animation direction if ( controls.moveForward ) { @@ -404,7 +410,6 @@ } } - updateMovementModel( delta ) { function exponentialEaseOut( k ) { @@ -413,16 +418,19 @@ } - const controls = this.controls; // speed based on controls + const controls = this.controls; + + // speed based on controls if ( controls.crouch ) this.maxSpeed = this.crouchSpeed; else this.maxSpeed = this.walkSpeed; this.maxReverseSpeed = - this.maxSpeed; if ( controls.moveForward ) this.speed = THREE.MathUtils.clamp( this.speed + delta * this.frontAcceleration, this.maxReverseSpeed, this.maxSpeed ); - if ( controls.moveBackward ) this.speed = THREE.MathUtils.clamp( this.speed - delta * this.backAcceleration, this.maxReverseSpeed, this.maxSpeed ); // orientation based on controls + if ( controls.moveBackward ) this.speed = THREE.MathUtils.clamp( this.speed - delta * this.backAcceleration, this.maxReverseSpeed, this.maxSpeed ); + + // orientation based on controls // (don't just stand while turning) const dir = 1; - if ( controls.moveLeft ) { this.bodyOrientation += delta * this.angularSpeed; @@ -435,8 +443,9 @@ this.bodyOrientation -= delta * this.angularSpeed; this.speed = THREE.MathUtils.clamp( this.speed + dir * delta * this.frontAcceleration, this.maxReverseSpeed, this.maxSpeed ); - } // speed decay + } + // speed decay if ( ! ( controls.moveForward || controls.moveBackward ) ) { @@ -452,17 +461,21 @@ } - } // displacement + } + // displacement const forwardDelta = this.speed * delta; this.root.position.x += Math.sin( this.bodyOrientation ) * forwardDelta; - this.root.position.z += Math.cos( this.bodyOrientation ) * forwardDelta; // steering + this.root.position.z += Math.cos( this.bodyOrientation ) * forwardDelta; + + // steering this.root.rotation.y = this.bodyOrientation; - } // internal + } + // internal _createPart( geometry, skinMap ) { @@ -474,13 +487,19 @@ color: 0xffffff, wireframe: false, map: skinMap - } ); // + } ); + + // const mesh = new THREE.MorphBlendMesh( geometry, materialTexture ); - mesh.rotation.y = - Math.PI / 2; // + mesh.rotation.y = - Math.PI / 2; + + // mesh.materialTexture = materialTexture; - mesh.materialWireframe = materialWireframe; // + mesh.materialWireframe = materialWireframe; + + // mesh.autoCreateAnimations( this.animationFPS ); return mesh; diff --git a/examples/js/misc/MorphAnimMesh.js b/examples/js/misc/MorphAnimMesh.js index 363ba8c5c9d0ba..5da1f4d2686594 100644 --- a/examples/js/misc/MorphAnimMesh.js +++ b/examples/js/misc/MorphAnimMesh.js @@ -10,19 +10,16 @@ this.activeAction = null; } - setDirectionForward() { this.mixer.timeScale = 1.0; } - setDirectionBackward() { this.mixer.timeScale = - 1.0; } - playAnimation( label, fps ) { if ( this.activeAction ) { @@ -33,7 +30,6 @@ } const clip = THREE.AnimationClip.findByName( this, label ); - if ( clip ) { const action = this.mixer.clipAction( clip ); @@ -47,13 +43,11 @@ } } - updateAnimation( delta ) { this.mixer.update( delta ); } - copy( source, recursive ) { super.copy( source, recursive ); diff --git a/examples/js/misc/MorphBlendMesh.js b/examples/js/misc/MorphBlendMesh.js index 9adbf6523317cb..a4d0e9d04dad81 100644 --- a/examples/js/misc/MorphBlendMesh.js +++ b/examples/js/misc/MorphBlendMesh.js @@ -6,7 +6,9 @@ super( geometry, material ); this.animationsMap = {}; - this.animationsList = []; // prepare default animation + this.animationsList = []; + + // prepare default animation // (all frames played together in 1 second) const numFrames = Object.keys( this.morphTargetDictionary ).length; @@ -18,7 +20,6 @@ this.setAnimationWeight( name, 1 ); } - createAnimation( name, start, end, fps ) { const animation = { @@ -40,18 +41,15 @@ this.animationsList.push( animation ); } - autoCreateAnimations( fps ) { const pattern = /([a-z]+)_?(\d+)/i; let firstAnimation; const frameRanges = {}; let i = 0; - for ( const key in this.morphTargetDictionary ) { const chunks = key.match( pattern ); - if ( chunks && chunks.length > 1 ) { const name = chunks[ 1 ]; @@ -80,11 +78,9 @@ this.firstAnimation = firstAnimation; } - setAnimationDirectionForward( name ) { const animation = this.animationsMap[ name ]; - if ( animation ) { animation.direction = 1; @@ -93,11 +89,9 @@ } } - setAnimationDirectionBackward( name ) { const animation = this.animationsMap[ name ]; - if ( animation ) { animation.direction = - 1; @@ -106,11 +100,9 @@ } } - setAnimationFPS( name, fps ) { const animation = this.animationsMap[ name ]; - if ( animation ) { animation.fps = fps; @@ -119,11 +111,9 @@ } } - setAnimationDuration( name, duration ) { const animation = this.animationsMap[ name ]; - if ( animation ) { animation.duration = duration; @@ -132,11 +122,9 @@ } } - setAnimationWeight( name, weight ) { const animation = this.animationsMap[ name ]; - if ( animation ) { animation.weight = weight; @@ -144,11 +132,9 @@ } } - setAnimationTime( name, time ) { const animation = this.animationsMap[ name ]; - if ( animation ) { animation.time = time; @@ -156,12 +142,10 @@ } } - getAnimationTime( name ) { let time = 0; const animation = this.animationsMap[ name ]; - if ( animation ) { time = animation.time; @@ -171,12 +155,10 @@ return time; } - getAnimationDuration( name ) { let duration = - 1; const animation = this.animationsMap[ name ]; - if ( animation ) { duration = animation.duration; @@ -186,11 +168,9 @@ return duration; } - playAnimation( name ) { const animation = this.animationsMap[ name ]; - if ( animation ) { animation.time = 0; @@ -203,11 +183,9 @@ } } - stopAnimation( name ) { const animation = this.animationsMap[ name ]; - if ( animation ) { animation.active = false; @@ -215,7 +193,6 @@ } } - update( delta ) { for ( let i = 0, il = this.animationsList.length; i < il; i ++ ) { @@ -224,13 +201,11 @@ if ( ! animation.active ) continue; const 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; @@ -256,7 +231,6 @@ const keyframe = animation.start + THREE.MathUtils.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 ); const weight = animation.weight; - if ( keyframe !== animation.currentFrame ) { this.morphTargetInfluences[ animation.lastFrame ] = 0; @@ -269,7 +243,6 @@ let mix = animation.time % frameTime / frameTime; if ( animation.directionBackwards ) mix = 1 - mix; - if ( animation.currentFrame !== animation.lastFrame ) { this.morphTargetInfluences[ animation.currentFrame ] = mix * weight; diff --git a/examples/js/misc/ProgressiveLightMap.js b/examples/js/misc/ProgressiveLightMap.js index e177624ecdacfc..0e0aa0343de850 100644 --- a/examples/js/misc/ProgressiveLightMap.js +++ b/examples/js/misc/ProgressiveLightMap.js @@ -16,7 +16,6 @@ * @param {WebGLRenderer} renderer A WebGL Rendering Context * @param {number} res The side-long dimension of you total lightmap */ - class ProgressiveLightMap { constructor( renderer, res = 1024 ) { @@ -30,59 +29,62 @@ this.tinyTarget = new THREE.WebGLRenderTarget( 1, 1 ); this.buffer1Active = false; this.firstUpdate = true; - this.warned = false; // Create the Progressive LightMap Texture + this.warned = false; + // Create the Progressive LightMap Texture const format = /(Android|iPad|iPhone|iPod)/g.test( navigator.userAgent ) ? THREE.HalfFloatType : THREE.FloatType; this.progressiveLightMap1 = new THREE.WebGLRenderTarget( this.res, this.res, { type: format } ); this.progressiveLightMap2 = new THREE.WebGLRenderTarget( this.res, this.res, { type: format - } ); // Inject some spicy new logic into a standard phong material + } ); + // Inject some spicy new logic into a standard phong material this.uvMat = new THREE.MeshPhongMaterial(); this.uvMat.uniforms = {}; - this.uvMat.onBeforeCompile = shader => { // Vertex Shader: Set Vertex Positions to the Unwrapped UV Positions - shader.vertexShader = '#define USE_LIGHTMAP\n' + shader.vertexShader.slice( 0, - 1 ) + ' gl_Position = vec4((uv2 - 0.5) * 2.0, 1.0, 1.0); }'; // Fragment Shader: Set Pixels to average in the Previous frame's Shadows + shader.vertexShader = '#define USE_LIGHTMAP\n' + shader.vertexShader.slice( 0, - 1 ) + ' gl_Position = vec4((uv2 - 0.5) * 2.0, 1.0, 1.0); }'; + // Fragment Shader: Set Pixels to average in the Previous frame's Shadows const bodyStart = shader.fragmentShader.indexOf( 'void main() {' ); shader.fragmentShader = 'varying vec2 vUv2;\n' + shader.fragmentShader.slice( 0, bodyStart ) + ' uniform sampler2D previousShadowMap;\n uniform float averagingWindow;\n' + shader.fragmentShader.slice( bodyStart - 1, - 1 ) + `\nvec3 texelOld = texture2D(previousShadowMap, vUv2).rgb; gl_FragColor.rgb = mix(texelOld, gl_FragColor.rgb, 1.0/averagingWindow); - }`; // Set the Previous Frame's Texture Buffer and Averaging Window + }`; + // Set the Previous Frame's Texture Buffer and Averaging Window shader.uniforms.previousShadowMap = { value: this.progressiveLightMap1.texture }; shader.uniforms.averagingWindow = { value: 100 }; - this.uvMat.uniforms = shader.uniforms; // Set the new Shader to this + this.uvMat.uniforms = shader.uniforms; + // Set the new Shader to this this.uvMat.userData.shader = shader; this.compiled = true; }; } + /** * Sets these objects' materials' lightmaps and modifies their uv2's. * @param {Object3D} objects An array of objects and lights to set up your lightmap. */ - - addObjectsToLightMap( objects ) { // Prepare list of UV bounding boxes for packing later... this.uv_boxes = []; const padding = 3 / this.res; - for ( let ob = 0; ob < objects.length; ob ++ ) { - const object = objects[ ob ]; // If this object is a light, simply add it to the internal scene + const object = objects[ ob ]; + // If this object is a light, simply add it to the internal scene if ( object.isLight ) { this.scene.attach( object ); @@ -101,16 +103,17 @@ this._initializeBlurPlane( this.res, this.progressiveLightMap1 ); - } // Apply the lightmap to the object - + } + // Apply the lightmap to the object object.material.lightMap = this.progressiveLightMap2.texture; object.material.dithering = true; object.castShadow = true; object.receiveShadow = true; - object.renderOrder = 1000 + ob; // Prepare UV boxes for potpack - // TODO: Size these by object surface area + object.renderOrder = 1000 + ob; + // Prepare UV boxes for potpack + // TODO: Size these by object surface area this.uv_boxes.push( { w: 1 + padding * 2, h: 1 + padding * 2, @@ -122,14 +125,13 @@ } ); this.compiled = false; - } // Pack the objects' lightmap UVs into the same global space - + } + // Pack the objects' lightmap UVs into the same global space const dimensions = potpack( this.uv_boxes ); this.uv_boxes.forEach( box => { const uv2 = objects[ box.index ].geometry.getAttribute( 'uv' ).clone(); - for ( let i = 0; i < uv2.array.length; i += uv2.itemSize ) { uv2.array[ i ] = ( uv2.array[ i ] + box.x + padding ) / dimensions.w; @@ -143,45 +145,45 @@ } ); } + /** * This function renders each mesh one at a time into their respective surface maps * @param {Camera} camera Standard Rendering Camera * @param {number} blendWindow When >1, samples will accumulate over time. * @param {boolean} blurEdges Whether to fix UV Edges via blurring */ - - update( camera, blendWindow = 100, blurEdges = true ) { if ( this.blurringPlane == null ) { return; - } // Store the original Render Target - + } - const oldTarget = this.renderer.getRenderTarget(); // The blurring plane applies blur to the seams of the lightmap + // Store the original Render Target + const oldTarget = this.renderer.getRenderTarget(); - this.blurringPlane.visible = blurEdges; // Steal the Object3D from the real world to our special dimension + // The blurring plane applies blur to the seams of the lightmap + this.blurringPlane.visible = blurEdges; + // Steal the Object3D from the real world to our special dimension for ( let l = 0; l < this.lightMapContainers.length; l ++ ) { this.lightMapContainers[ l ].object.oldScene = this.lightMapContainers[ l ].object.parent; this.scene.attach( this.lightMapContainers[ l ].object ); - } // Render once normally to initialize everything - + } + // Render once normally to initialize everything if ( this.firstUpdate ) { this.renderer.setRenderTarget( this.tinyTarget ); // Tiny for Speed - this.renderer.render( this.scene, camera ); this.firstUpdate = false; - } // Set each object's material to the UV Unwrapped Surface Mapping Version - + } + // Set each object's material to the UV Unwrapped Surface Mapping Version for ( let l = 0; l < this.lightMapContainers.length; l ++ ) { this.uvMat.uniforms.averagingWindow = { @@ -191,12 +193,13 @@ this.lightMapContainers[ l ].object.oldFrustumCulled = this.lightMapContainers[ l ].object.frustumCulled; this.lightMapContainers[ l ].object.frustumCulled = false; - } // Ping-pong two surface buffers for reading/writing - + } + // Ping-pong two surface buffers for reading/writing const activeMap = this.buffer1Active ? this.progressiveLightMap1 : this.progressiveLightMap2; - const inactiveMap = this.buffer1Active ? this.progressiveLightMap2 : this.progressiveLightMap1; // Render the object's surface maps + const inactiveMap = this.buffer1Active ? this.progressiveLightMap2 : this.progressiveLightMap1; + // Render the object's surface maps this.renderer.setRenderTarget( activeMap ); this.uvMat.uniforms.previousShadowMap = { value: inactiveMap.texture @@ -205,27 +208,27 @@ value: inactiveMap.texture }; this.buffer1Active = ! this.buffer1Active; - this.renderer.render( this.scene, camera ); // Restore the object's Real-time Material and add it back to the original world + this.renderer.render( this.scene, camera ); + // Restore the object's Real-time Material and add it back to the original world for ( let l = 0; l < this.lightMapContainers.length; l ++ ) { this.lightMapContainers[ l ].object.frustumCulled = this.lightMapContainers[ l ].object.oldFrustumCulled; this.lightMapContainers[ l ].object.material = this.lightMapContainers[ l ].basicMat; this.lightMapContainers[ l ].object.oldScene.attach( this.lightMapContainers[ l ].object ); - } // Restore the original Render Target - + } + // Restore the original Render Target this.renderer.setRenderTarget( oldTarget ); } + /** DEBUG * Draw the lightmap in the main scene. Call this after adding the objects to it. * @param {boolean} visible Whether the debug plane should be visible * @param {Vector3} position Where the debug plane should be drawn */ - - showDebugLightmap( visible, position = undefined ) { if ( this.lightMapContainers.length == 0 ) { @@ -263,13 +266,12 @@ this.labelMesh.visible = visible; } + /** * INTERNAL Creates the Blurring Plane * @param {number} res The square resolution of this object's lightMap. * @param {WebGLRenderTexture} lightMap The lightmap to initialize the plane with. */ - - _initializeBlurPlane( res, lightMap = null ) { const blurMaterial = new THREE.MeshBasicMaterial(); @@ -284,12 +286,12 @@ polygonOffsetFactor: - 1, polygonOffsetUnits: 3.0 }; - blurMaterial.onBeforeCompile = shader => { // Vertex Shader: Set Vertex Positions to the Unwrapped UV Positions - shader.vertexShader = '#define USE_UV\n' + shader.vertexShader.slice( 0, - 1 ) + ' gl_Position = vec4((uv - 0.5) * 2.0, 1.0, 1.0); }'; // Fragment Shader: Set Pixels to 9-tap box blur the current frame's Shadows + shader.vertexShader = '#define USE_UV\n' + shader.vertexShader.slice( 0, - 1 ) + ' gl_Position = vec4((uv - 0.5) * 2.0, 1.0, 1.0); }'; + // Fragment Shader: Set Pixels to 9-tap box blur the current frame's Shadows const bodyStart = shader.fragmentShader.indexOf( 'void main() {' ); shader.fragmentShader = '#define USE_UV\n' + shader.fragmentShader.slice( 0, bodyStart ) + ' uniform sampler2D previousShadowMap;\n uniform float pixelOffset;\n' + shader.fragmentShader.slice( bodyStart - 1, - 1 ) + ` gl_FragColor.rgb = ( texture2D(previousShadowMap, vUv + vec2( pixelOffset, 0.0 )).rgb + @@ -300,16 +302,18 @@ texture2D(previousShadowMap, vUv + vec2(-pixelOffset, pixelOffset)).rgb + texture2D(previousShadowMap, vUv + vec2( pixelOffset, -pixelOffset)).rgb + texture2D(previousShadowMap, vUv + vec2(-pixelOffset, -pixelOffset)).rgb)/8.0; - }`; // Set the LightMap Accumulation Buffer + }`; + // Set the LightMap Accumulation Buffer shader.uniforms.previousShadowMap = { value: lightMap.texture }; shader.uniforms.pixelOffset = { value: 0.5 / res }; - blurMaterial.uniforms = shader.uniforms; // Set the new Shader to this + blurMaterial.uniforms = shader.uniforms; + // Set the new Shader to this blurMaterial.userData.shader = shader; this.compiled = true; diff --git a/examples/js/misc/RollerCoaster.js b/examples/js/misc/RollerCoaster.js index ff2ea611957902..a23a19ad9f143c 100644 --- a/examples/js/misc/RollerCoaster.js +++ b/examples/js/misc/RollerCoaster.js @@ -18,13 +18,14 @@ prevQuaternion.setFromAxisAngle( up, Math.PI / 2 ); const point = new THREE.Vector3(); const prevPoint = new THREE.Vector3(); - prevPoint.copy( curve.getPointAt( 0 ) ); // shapes + prevPoint.copy( curve.getPointAt( 0 ) ); + + // shapes const step = [ new THREE.Vector3( - 0.225, 0, 0 ), new THREE.Vector3( 0, - 0.050, 0 ), new THREE.Vector3( 0, - 0.175, 0 ), new THREE.Vector3( 0, - 0.050, 0 ), new THREE.Vector3( 0.225, 0, 0 ), new THREE.Vector3( 0, - 0.175, 0 ) ]; const PI2 = Math.PI * 2; let sides = 5; const tube1 = []; - for ( let i = 0; i < sides; i ++ ) { const angle = i / sides * PI2; @@ -34,7 +35,6 @@ sides = 6; const tube2 = []; - for ( let i = 0; i < sides; i ++ ) { const angle = i / sides * PI2; @@ -44,11 +44,9 @@ const vector = new THREE.Vector3(); const normal = new THREE.Vector3(); - function drawShape( shape, color ) { normal.set( 0, 0, - 1 ).applyQuaternion( quaternion ); - for ( let j = 0; j < shape.length; j ++ ) { vector.copy( shape[ j ] ); @@ -61,7 +59,6 @@ } normal.set( 0, 0, 1 ).applyQuaternion( quaternion ); - for ( let j = shape.length - 1; j >= 0; j -- ) { vector.copy( shape[ j ] ); @@ -83,7 +80,6 @@ const normal2 = new THREE.Vector3(); const normal3 = new THREE.Vector3(); const normal4 = new THREE.Vector3(); - function extrudeShape( shape, offset, color ) { for ( let j = 0, jl = shape.length; j < jl; j ++ ) { @@ -107,7 +103,9 @@ vertices.push( vector4.x, vector4.y, vector4.z ); vertices.push( vector2.x, vector2.y, vector2.z ); vertices.push( vector3.x, vector3.y, vector3.z ); - vertices.push( vector4.x, vector4.y, vector4.z ); // + vertices.push( vector4.x, vector4.y, vector4.z ); + + // normal1.copy( point1 ); normal1.applyQuaternion( quaternion ); @@ -139,7 +137,6 @@ } const offset = new THREE.Vector3(); - for ( let i = 1; i <= divisions; i ++ ) { point.copy( curve.getPointAt( i / divisions ) ); @@ -149,7 +146,6 @@ up.crossVectors( forward, right ); const angle = Math.atan2( forward.x, forward.z ); quaternion.setFromAxisAngle( up, angle ); - if ( i % 2 === 0 ) { drawShape( step, color2 ); @@ -162,8 +158,9 @@ prevPoint.copy( point ); prevQuaternion.copy( quaternion ); - } // console.log( vertices.length ); + } + // console.log( vertices.length ); this.setAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) ); this.setAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) ); @@ -172,7 +169,6 @@ } } - class RollerCoasterLiftersGeometry extends THREE.BufferGeometry { constructor( curve, divisions ) { @@ -183,7 +179,9 @@ const quaternion = new THREE.Quaternion(); const up = new THREE.Vector3( 0, 1, 0 ); const point = new THREE.Vector3(); - const tangent = new THREE.Vector3(); // shapes + const tangent = new THREE.Vector3(); + + // shapes const tube1 = [ new THREE.Vector3( 0, 0.05, - 0.05 ), new THREE.Vector3( 0, 0.05, 0.05 ), new THREE.Vector3( 0, - 0.05, 0 ) ]; const tube2 = [ new THREE.Vector3( - 0.05, 0, 0.05 ), new THREE.Vector3( - 0.05, 0, - 0.05 ), new THREE.Vector3( 0.05, 0, 0 ) ]; @@ -196,7 +194,6 @@ const normal2 = new THREE.Vector3(); const normal3 = new THREE.Vector3(); const normal4 = new THREE.Vector3(); - function extrudeShape( shape, fromPoint, toPoint ) { for ( let j = 0, jl = shape.length; j < jl; j ++ ) { @@ -220,7 +217,9 @@ vertices.push( vector4.x, vector4.y, vector4.z ); vertices.push( vector2.x, vector2.y, vector2.z ); vertices.push( vector3.x, vector3.y, vector3.z ); - vertices.push( vector4.x, vector4.y, vector4.z ); // + vertices.push( vector4.x, vector4.y, vector4.z ); + + // normal1.copy( point1 ); normal1.applyQuaternion( quaternion ); @@ -247,13 +246,14 @@ const fromPoint = new THREE.Vector3(); const toPoint = new THREE.Vector3(); - for ( let i = 1; i <= divisions; i ++ ) { point.copy( curve.getPointAt( i / divisions ) ); tangent.copy( curve.getTangentAt( i / divisions ) ); const angle = Math.atan2( tangent.x, tangent.z ); - quaternion.setFromAxisAngle( up, angle ); // + quaternion.setFromAxisAngle( up, angle ); + + // if ( point.y > 10 ) { @@ -299,7 +299,6 @@ } } - class RollerCoasterShadowGeometry extends THREE.BufferGeometry { constructor( curve, divisions ) { @@ -319,7 +318,6 @@ const vector2 = new THREE.Vector3(); const vector3 = new THREE.Vector3(); const vector4 = new THREE.Vector3(); - for ( let i = 1; i <= divisions; i ++ ) { point.copy( curve.getPointAt( i / divisions ) ); @@ -355,14 +353,12 @@ } } - class SkyGeometry extends THREE.BufferGeometry { constructor() { super(); const vertices = []; - for ( let i = 0; i < 100; i ++ ) { const x = Math.random() * 800 - 400; @@ -383,7 +379,6 @@ } } - class TreesGeometry extends THREE.BufferGeometry { constructor( landscape ) { @@ -393,7 +388,6 @@ const colors = []; const raycaster = new THREE.Raycaster(); raycaster.ray.direction.set( 0, - 1, 0 ); - for ( let i = 0; i < 2000; i ++ ) { const x = Math.random() * 500 - 250; @@ -412,7 +406,6 @@ vertices.push( x, y + height, z ); vertices.push( x + Math.sin( angle + Math.PI ), y, z + Math.cos( angle + Math.PI ) ); const random = Math.random() * 0.1; - for ( let j = 0; j < 6; j ++ ) { colors.push( 0.2 + random, 0.4 + random, 0 ); diff --git a/examples/js/misc/TubePainter.js b/examples/js/misc/TubePainter.js index 8047feb3e475a8..718a561aa7e12f 100644 --- a/examples/js/misc/TubePainter.js +++ b/examples/js/misc/TubePainter.js @@ -18,7 +18,9 @@ vertexColors: true } ); const mesh = new THREE.Mesh( geometry, material ); - mesh.frustumCulled = false; // + mesh.frustumCulled = false; + + // function getPoints( size ) { @@ -26,7 +28,6 @@ const sides = 10; const array = []; const radius = 0.01 * size; - for ( let i = 0; i < sides; i ++ ) { const angle = i / sides * PI2; @@ -36,8 +37,9 @@ return array; - } // + } + // const vector1 = new THREE.Vector3(); const vector2 = new THREE.Vector3(); @@ -45,17 +47,17 @@ const vector4 = new THREE.Vector3(); const color = new THREE.Color( 0xffffff ); let size = 1; - function stroke( position1, position2, matrix1, matrix2 ) { if ( position1.distanceToSquared( position2 ) === 0 ) return; let count = geometry.drawRange.count; const points = getPoints( size ); - for ( let i = 0, il = points.length; i < il; i ++ ) { const vertex1 = points[ i ]; - const vertex2 = points[ ( i + 1 ) % il ]; // positions + const vertex2 = points[ ( i + 1 ) % il ]; + + // positions vector1.copy( vertex1 ).applyMatrix4( matrix2 ).add( position2 ); vector2.copy( vertex2 ).applyMatrix4( matrix2 ).add( position2 ); @@ -66,7 +68,9 @@ vector4.toArray( positions.array, ( count + 2 ) * 3 ); vector2.toArray( positions.array, ( count + 3 ) * 3 ); vector3.toArray( positions.array, ( count + 4 ) * 3 ); - vector4.toArray( positions.array, ( count + 5 ) * 3 ); // normals + vector4.toArray( positions.array, ( count + 5 ) * 3 ); + + // normals vector1.copy( vertex1 ).applyMatrix4( matrix2 ).normalize(); vector2.copy( vertex2 ).applyMatrix4( matrix2 ).normalize(); @@ -77,7 +81,9 @@ vector4.toArray( normals.array, ( count + 2 ) * 3 ); vector2.toArray( normals.array, ( count + 3 ) * 3 ); vector3.toArray( normals.array, ( count + 4 ) * 3 ); - vector4.toArray( normals.array, ( count + 5 ) * 3 ); // colors + vector4.toArray( normals.array, ( count + 5 ) * 3 ); + + // colors color.toArray( colors.array, ( count + 0 ) * 3 ); color.toArray( colors.array, ( count + 1 ) * 3 ); @@ -91,15 +97,15 @@ geometry.drawRange.count = count; - } // + } + // const up = new THREE.Vector3( 0, 1, 0 ); const point1 = new THREE.Vector3(); const point2 = new THREE.Vector3(); const matrix1 = new THREE.Matrix4(); const matrix2 = new THREE.Matrix4(); - function moveTo( position ) { point1.copy( position ); @@ -123,11 +129,11 @@ size = value; - } // + } + // let count = 0; - function update() { const start = count; diff --git a/examples/js/misc/Volume.js b/examples/js/misc/Volume.js index c81027f527a0f6..5bf2baae66d522 100644 --- a/examples/js/misc/Volume.js +++ b/examples/js/misc/Volume.js @@ -12,7 +12,6 @@ * @param {string} type The type of data (uint8, uint16, ...) * @param {ArrayBuffer} arrayBuffer The buffer with volume data */ - class Volume { constructor( xLength, yLength, zLength, type, arrayBuffer ) { @@ -26,17 +25,14 @@ /** * @member {number} yLength Height of the volume in the IJK coordinate system */ - this.yLength = Number( yLength ) || 1; /** * @member {number} zLength Depth of the volume in the IJK coordinate system */ - this.zLength = Number( zLength ) || 1; /** * @member {Array} The order of the Axis dictated by the NRRD header */ - this.axisOrder = [ 'x', 'y', 'z' ]; /** * @member {TypedArray} data Data of the volume @@ -51,14 +47,12 @@ case 'uint8_t': this.data = new Uint8Array( arrayBuffer ); break; - case 'Int8': case 'int8': case 'signed char': case 'int8_t': this.data = new Int8Array( arrayBuffer ); break; - case 'Int16': case 'int16': case 'short': @@ -68,7 +62,6 @@ case 'int16_t': this.data = new Int16Array( arrayBuffer ); break; - case 'Uint16': case 'uint16': case 'ushort': @@ -77,7 +70,6 @@ case 'uint16_t': this.data = new Uint16Array( arrayBuffer ); break; - case 'Int32': case 'int32': case 'int': @@ -85,7 +77,6 @@ case 'int32_t': this.data = new Int32Array( arrayBuffer ); break; - case 'Uint32': case 'uint32': case 'uint': @@ -93,7 +84,6 @@ case 'uint32_t': this.data = new Uint32Array( arrayBuffer ); break; - case 'longlong': case 'long long': case 'long long int': @@ -108,19 +98,16 @@ case 'uint64_t': throw new Error( 'Error in Volume constructor : this type is not supported in JavaScript' ); break; - case 'Float32': case 'float32': case 'float': this.data = new Float32Array( arrayBuffer ); break; - case 'Float64': case 'float64': case 'double': this.data = new Float64Array( arrayBuffer ); break; - default: this.data = new Uint8Array( arrayBuffer ); @@ -133,32 +120,27 @@ } } + /** * @member {Array} spacing Spacing to apply to the volume from IJK to RAS coordinate system */ - - this.spacing = [ 1, 1, 1 ]; /** * @member {Array} offset Offset of the volume in the RAS coordinate system */ - this.offset = [ 0, 0, 0 ]; /** * @member {Martrix3} matrix The IJK to RAS matrix */ - this.matrix = new THREE.Matrix3(); this.matrix.identity(); /** * @member {Martrix3} inverseMatrix The RAS to IJK matrix */ - /** * @member {number} lowerThreshold The voxels with values under this threshold won't appear in the slices. * If changed, geometryNeedsUpdate is automatically set to true on all the slices associated to this volume */ - let lowerThreshold = - Infinity; Object.defineProperty( this, 'lowerThreshold', { get: function () { @@ -181,7 +163,6 @@ * @member {number} upperThreshold The voxels with values over this threshold won't appear in the slices. * If changed, geometryNeedsUpdate is automatically set to true on all the slices associated to this volume */ - let upperThreshold = Infinity; Object.defineProperty( this, 'upperThreshold', { get: function () { @@ -200,16 +181,18 @@ } } ); + /** * @member {Array} sliceList The list of all the slices associated to this volume */ - this.sliceList = []; + /** * @member {Array} RASDimensions This array holds the dimensions of the volume in the RAS space */ } + /** * @member {Function} getData Shortcut for data[access(i,j,k)] * @memberof Volume @@ -218,13 +201,12 @@ * @param {number} k Third coordinate * @returns {number} value in the data array */ - - getData( i, j, k ) { return this.data[ k * this.xLength * this.yLength + j * this.xLength + i ]; } + /** * @member {Function} access compute the index in the data array corresponding to the given coordinates in IJK system * @memberof Volume @@ -233,21 +215,18 @@ * @param {number} k Third coordinate * @returns {number} index */ - - access( i, j, k ) { return k * this.xLength * this.yLength + j * this.xLength + i; } + /** * @member {Function} reverseAccess Retrieve the IJK coordinates of the voxel corresponding of the given index in the data * @memberof Volume * @param {number} index index of the voxel * @returns {Array} [x,y,z] */ - - reverseAccess( index ) { const z = Math.floor( index / ( this.yLength * this.xLength ) ); @@ -256,6 +235,7 @@ return [ x, y, z ]; } + /** * @member {Function} map Apply a function to all the voxels, be careful, the value will be replaced * @memberof Volume @@ -266,13 +246,10 @@ * @param {Object} context You can specify a context in which call the function, default if this Volume * @returns {Volume} this */ - - map( functionToMap, context ) { const length = this.data.length; context = context || this; - for ( let i = 0; i < length; i ++ ) { this.data[ i ] = functionToMap.call( context, this.data[ i ], i, this.data ); @@ -282,6 +259,7 @@ return this; } + /** * @member {Function} extractPerpendicularPlane Compute the orientation of the slice and returns all the information relative to the geometry such as sliceAccess, the plane matrix (orientation and position in RAS coordinate) and the dimensions of the plane in both coordinate system. * @memberof Volume @@ -289,8 +267,6 @@ * @param {number} index the index of the slice * @returns {Object} an object containing all the usefull information on the geometry of the slice */ - - extractPerpendicularPlane( axis, RASIndex ) { let firstSpacing, secondSpacing, positionOffset, IJKIndex; @@ -300,7 +276,6 @@ planeMatrix = new THREE.Matrix4().identity(), volume = this; const dimensions = new THREE.Vector3( this.xLength, this.yLength, this.zLength ); - switch ( axis ) { case 'x': @@ -314,7 +289,6 @@ positionOffset = ( volume.RASDimensions[ 0 ] - 1 ) / 2; planeMatrix.setPosition( new THREE.Vector3( RASIndex - positionOffset, 0, 0 ) ); break; - case 'y': axisInIJK.set( 0, 1, 0 ); firstDirection.set( 1, 0, 0 ); @@ -326,7 +300,6 @@ positionOffset = ( volume.RASDimensions[ 1 ] - 1 ) / 2; planeMatrix.setPosition( new THREE.Vector3( 0, RASIndex - positionOffset, 0 ) ); break; - case 'z': default: axisInIJK.set( 0, 0, 1 ); @@ -367,12 +340,13 @@ return Math.abs( x.dot( base[ 2 ] ) ) > 0.9; } ); - function sliceAccess( i, j ) { const si = iDirection === axisInIJK ? IJKIndex : iDirection.arglet === 'i' ? i : j; const sj = jDirection === axisInIJK ? IJKIndex : jDirection.arglet === 'i' ? i : j; - const sk = kDirection === axisInIJK ? IJKIndex : kDirection.arglet === 'i' ? i : j; // invert indices if necessary + const sk = kDirection === axisInIJK ? IJKIndex : kDirection.arglet === 'i' ? i : j; + + // invert indices if necessary const accessI = iDirection.dot( base[ 0 ] ) > 0 ? si : volume.xLength - 1 - si; const accessJ = jDirection.dot( base[ 1 ] ) > 0 ? sj : volume.yLength - 1 - sj; @@ -391,6 +365,7 @@ }; } + /** * @member {Function} extractSlice Returns a slice corresponding to the given axis and index * The coordinate are given in the Right Anterior Superior coordinate format @@ -399,8 +374,6 @@ * @param {number} index the index of the slice * @returns {VolumeSlice} the extracted slice */ - - extractSlice( axis, index ) { const slice = new THREE.VolumeSlice( this, index, axis ); @@ -408,14 +381,13 @@ return slice; } + /** * @member {Function} repaintAllSlices Call repaint on all the slices extracted from this volume * @see THREE.VolumeSlice.repaint * @memberof Volume * @returns {Volume} this */ - - repaintAllSlices() { this.sliceList.forEach( function ( slice ) { @@ -426,21 +398,20 @@ return this; } + /** * @member {Function} computeMinMax Compute the minimum and the maximum of the data in the volume * @memberof Volume * @returns {Array} [min,max] */ - - computeMinMax() { let min = Infinity; - let max = - Infinity; // buffer the length + let max = - Infinity; + // buffer the length const datasize = this.data.length; let i = 0; - for ( i = 0; i < datasize; i ++ ) { if ( ! isNaN( this.data[ i ] ) ) { diff --git a/examples/js/misc/VolumeSlice.js b/examples/js/misc/VolumeSlice.js index 7575b0e5cff896..7c83d35b42e860 100644 --- a/examples/js/misc/VolumeSlice.js +++ b/examples/js/misc/VolumeSlice.js @@ -8,7 +8,6 @@ * @param {string} [axis='z'] For now only 'x', 'y' or 'z' but later it will change to a normal vector * @see Volume */ - class VolumeSlice { constructor( volume, index, axis ) { @@ -17,12 +16,10 @@ /** * @member {Volume} volume The associated volume */ - this.volume = volume; /** * @member {Number} index The index of the slice, if changed, will automatically call updateGeometry at the next repaint */ - index = index || 0; Object.defineProperty( this, 'index', { get: function () { @@ -41,25 +38,21 @@ /** * @member {String} axis The normal axis */ - this.axis = axis || 'z'; + /** * @member {HTMLCanvasElement} canvas The final canvas used for the texture */ - /** * @member {CanvasRenderingContext2D} ctx Context of the canvas */ - this.canvas = document.createElement( 'canvas' ); /** * @member {HTMLCanvasElement} canvasBuffer The intermediary canvas used to paint the data */ - /** * @member {CanvasRenderingContext2D} ctxBuffer Context of the canvas buffer */ - this.canvasBuffer = document.createElement( 'canvas' ); this.updateGeometry(); const canvasMap = new THREE.Texture( this.canvas ); @@ -73,15 +66,14 @@ /** * @member {Mesh} mesh The mesh ready to get used in the scene */ - this.mesh = new THREE.Mesh( this.geometry, material ); this.mesh.matrixAutoUpdate = false; /** * @member {Boolean} geometryNeedsUpdate If set to true, updateGeometry will be triggered at the next repaint */ - this.geometryNeedsUpdate = true; this.repaint(); + /** * @member {Number} iLength Width of slice in the original coordinate system, corresponds to the width of the buffer canvas */ @@ -99,12 +91,11 @@ */ } + /** * @member {Function} repaint Refresh the texture and the geometry if geometryNeedsUpdate is set to true * @memberof VolumeSlice */ - - repaint() { if ( this.geometryNeedsUpdate ) { @@ -118,18 +109,19 @@ sliceAccess = this.sliceAccess, volume = this.volume, canvas = this.canvasBuffer, - ctx = this.ctxBuffer; // get the imageData and pixel array from the canvas + ctx = this.ctxBuffer; + // get the imageData and pixel array from the canvas const imgData = ctx.getImageData( 0, 0, iLength, jLength ); const data = imgData.data; const volumeData = volume.data; const upperThreshold = volume.upperThreshold; const lowerThreshold = volume.lowerThreshold; const windowLow = volume.windowLow; - const windowHigh = volume.windowHigh; // manipulate some pixel elements + const windowHigh = volume.windowHigh; + // manipulate some pixel elements let pixelCount = 0; - if ( volume.dataType === 'label' ) { //this part is currently useless but will be used when colortables will be handled @@ -157,10 +149,10 @@ for ( let i = 0; i < iLength; i ++ ) { let value = volumeData[ sliceAccess( i, j ) ]; - let alpha = 0xff; //apply threshold - - alpha = upperThreshold >= value ? lowerThreshold <= value ? alpha : 0 : 0; //apply window level - + let alpha = 0xff; + //apply threshold + alpha = upperThreshold >= value ? lowerThreshold <= value ? alpha : 0 : 0; + //apply window level value = Math.floor( 255 * ( value - windowLow ) / ( windowHigh - windowLow ) ); value = value > 255 ? 255 : value < 0 ? 0 : value | 0; data[ 4 * pixelCount ] = value; @@ -180,13 +172,12 @@ this.mesh.material.map.needsUpdate = true; } + /** * @member {Function} Refresh the geometry according to axis and index * @see Volume.extractPerpendicularPlane * @memberof VolumeSlice */ - - updateGeometry() { const extracted = this.volume.extractPerpendicularPlane( this.axis, this.index ); @@ -203,11 +194,10 @@ if ( this.geometry ) this.geometry.dispose(); // dispose existing geometry this.geometry = new THREE.PlaneGeometry( extracted.planeWidth, extracted.planeHeight ); - if ( this.mesh ) { - this.mesh.geometry = this.geometry; //reset mesh matrix - + this.mesh.geometry = this.geometry; + //reset mesh matrix this.mesh.matrix.identity(); this.mesh.applyMatrix4( this.matrix ); diff --git a/examples/js/modifiers/CurveModifier.js b/examples/js/modifiers/CurveModifier.js index 92bc319bcb414e..f280f1c01f0e11 100644 --- a/examples/js/modifiers/CurveModifier.js +++ b/examples/js/modifiers/CurveModifier.js @@ -4,12 +4,12 @@ const CHANNELS = 4; const TEXTURE_WIDTH = 1024; const TEXTURE_HEIGHT = 4; + /** * Make a new THREE.DataTexture to store the descriptions of the curves. * * @param { number } numberOfCurves the number of curves needed to be described by this texture. */ - function initSplineTexture( numberOfCurves = 1 ) { const dataArray = new Float32Array( TEXTURE_WIDTH * TEXTURE_HEIGHT * numberOfCurves * CHANNELS ); @@ -21,6 +21,7 @@ return dataTexture; } + /** * Write the curve description to the data texture * @@ -28,7 +29,6 @@ * @param { Curve } splineCurve The curve to describe * @param { number } offset Which curve slot to write to */ - function updateSplineTexture( texture, splineCurve, offset = 0 ) { const numberOfPoints = Math.floor( TEXTURE_WIDTH * ( TEXTURE_HEIGHT / 4 ) ); @@ -36,7 +36,6 @@ splineCurve.updateArcLengths(); const points = splineCurve.getSpacedPoints( numberOfPoints ); const frenetFrames = splineCurve.computeFrenetFrames( numberOfPoints, true ); - for ( let i = 0; i < numberOfPoints; i ++ ) { const rowOffset = Math.floor( i / TEXTURE_WIDTH ); @@ -63,20 +62,18 @@ data } = image; const i = CHANNELS * TEXTURE_WIDTH * o; // Row Offset - data[ index * CHANNELS + i + 0 ] = x; data[ index * CHANNELS + i + 1 ] = y; data[ index * CHANNELS + i + 2 ] = z; data[ index * CHANNELS + i + 3 ] = 1; } + /** * Create a new set of uniforms for describing the curve modifier * * @param { THREE.DataTexture } Texture which holds the curve description */ - - function getUniforms( splineTexture ) { const uniforms = { @@ -114,7 +111,6 @@ if ( material.__ok ) return; material.__ok = true; - material.onBeforeCompile = shader => { if ( shader.__modified ) return; @@ -132,10 +128,17 @@ float textureStacks = ${TEXTURE_HEIGHT / 4}.; ${shader.vertexShader} - ` // chunk import moved in front of modified shader below - .replace( '#include ', '' ) // vec3 transformedNormal declaration overriden below - .replace( '#include ', '' ) // vec3 transformed declaration overriden below - .replace( '#include ', '' ) // shader override + ` + // chunk import moved in front of modified shader below + .replace( '#include ', '' ) + + // vec3 transformedNormal declaration overriden below + .replace( '#include ', '' ) + + // vec3 transformed declaration overriden below + .replace( '#include ', '' ) + + // shader override .replace( /void\s*main\s*\(\)\s*\{/, ` void main() { #include @@ -180,10 +183,10 @@ vec3 transformedNormal = normalMatrix * (basis * objectNormal); }; } + /** * A helper class for making meshes bend aroudn curves */ - class Flow { /** @@ -212,7 +215,6 @@ vec3 transformedNormal = normalMatrix * (basis * objectNormal); this.uniforms = uniforms; } - updateCurve( index, curve ) { if ( index >= this.curveArray.length ) throw Error( 'Index out of range for Flow' ); @@ -223,7 +225,6 @@ vec3 transformedNormal = normalMatrix * (basis * objectNormal); updateSplineTexture( this.splineTexure, curve, index ); } - moveAlongCurve( amount ) { this.uniforms.pathOffset.value += amount; @@ -232,10 +233,10 @@ vec3 transformedNormal = normalMatrix * (basis * objectNormal); } const matrix = new THREE.Matrix4(); + /** * A helper class for creating instanced versions of flow, where the instances are placed on the curve. */ - class InstancedFlow extends Flow { /** @@ -254,14 +255,13 @@ vec3 transformedNormal = normalMatrix * (basis * objectNormal); this.whichCurve = new Array( count ).fill( 0 ); } + /** * The extra information about which curve and curve position is stored in the translation components of the matrix for the instanced objects * This writes that information to the matrix and marks it as needing update. * * @param {number} index of the instanced element to update */ - - writeChanges( index ) { matrix.makeTranslation( this.curveLengthArray[ this.whichCurve[ index ] ], this.whichCurve[ index ], this.offsets[ index ] ); @@ -269,28 +269,26 @@ vec3 transformedNormal = normalMatrix * (basis * objectNormal); this.object3D.instanceMatrix.needsUpdate = true; } + /** * Move an individual element along the curve by a specific amount * * @param {number} index Which element to update * @param {number} offset Move by how much */ - - moveIndividualAlongCurve( index, offset ) { this.offsets[ index ] += offset; this.writeChanges( index ); } + /** * Select which curve to use for an element * * @param {number} index the index of the instanced element to update * @param {number} curveNo the index of the curve it should use */ - - setCurve( index, curveNo ) { if ( isNaN( curveNo ) ) throw Error( 'curve index being set is Not a Number (NaN)' ); diff --git a/examples/js/modifiers/EdgeSplitModifier.js b/examples/js/modifiers/EdgeSplitModifier.js index b147b2b2df50dc..d484e9bfaf4531 100644 --- a/examples/js/modifiers/EdgeSplitModifier.js +++ b/examples/js/modifiers/EdgeSplitModifier.js @@ -1,11 +1,8 @@ ( function () { const _A = new THREE.Vector3(); - const _B = new THREE.Vector3(); - const _C = new THREE.Vector3(); - class EdgeSplitModifier { modify( geometry, cutOffAngle, tryKeepNormals = true ) { @@ -13,27 +10,17 @@ function computeNormals() { normals = new Float32Array( indexes.length * 3 ); - for ( let i = 0; i < indexes.length; i += 3 ) { let index = indexes[ i ]; - _A.set( positions[ 3 * index ], positions[ 3 * index + 1 ], positions[ 3 * index + 2 ] ); - index = indexes[ i + 1 ]; - _B.set( positions[ 3 * index ], positions[ 3 * index + 1 ], positions[ 3 * index + 2 ] ); - index = indexes[ i + 2 ]; - _C.set( positions[ 3 * index ], positions[ 3 * index + 1 ], positions[ 3 * index + 2 ] ); - _C.sub( _B ); - _A.sub( _B ); - const normal = _C.cross( _A ).normalize(); - for ( let j = 0; j < 3; j ++ ) { normals[ 3 * ( i + j ) ] = normal.x; @@ -49,11 +36,9 @@ function mapPositionsToIndexes() { pointToIndexMap = Array( positions.length / 3 ); - for ( let i = 0; i < indexes.length; i ++ ) { const index = indexes[ i ]; - if ( pointToIndexMap[ index ] == null ) { pointToIndexMap[ index ] = []; @@ -69,18 +54,15 @@ function edgeSplitToGroups( indexes, cutOff, firstIndex ) { _A.set( normals[ 3 * firstIndex ], normals[ 3 * firstIndex + 1 ], normals[ 3 * firstIndex + 2 ] ).normalize(); - const result = { splitGroup: [], currentGroup: [ firstIndex ] }; - for ( const j of indexes ) { if ( j !== firstIndex ) { _B.set( normals[ 3 * j ], normals[ 3 * j + 1 ], normals[ 3 * j + 2 ] ).normalize(); - if ( _B.dot( _A ) < cutOff ) { result.splitGroup.push( j ); @@ -103,7 +85,6 @@ if ( indexes.length === 0 ) return; const groupResults = []; - for ( const index of indexes ) { groupResults.push( edgeSplitToGroups( indexes, cutOff, index ) ); @@ -111,7 +92,6 @@ } let result = groupResults[ 0 ]; - for ( const groupResult of groupResults ) { if ( groupResult.currentGroup.length > result.currentGroup.length ) { @@ -141,12 +121,10 @@ let hadNormals = false; let oldNormals = null; - if ( geometry.attributes.normal ) { hadNormals = true; geometry = geometry.clone(); - if ( tryKeepNormals === true && geometry.index !== null ) { oldNormals = geometry.attributes.normal.array; @@ -170,7 +148,6 @@ computeNormals(); mapPositionsToIndexes(); const splitIndexes = []; - for ( const vertexIndexes of pointToIndexMap ) { edgeSplit( vertexIndexes, Math.cos( cutOffAngle ) - 0.001 ); @@ -178,7 +155,6 @@ } const newAttributes = {}; - for ( const name of Object.keys( geometry.attributes ) ) { const oldAttribute = geometry.attributes[ name ]; @@ -190,12 +166,10 @@ const newIndexes = new Uint32Array( indexes.length ); newIndexes.set( indexes ); - for ( let i = 0; i < splitIndexes.length; i ++ ) { const split = splitIndexes[ i ]; const index = indexes[ split.original ]; - for ( const attribute of Object.values( newAttributes ) ) { for ( let j = 0; j < attribute.itemSize; j ++ ) { @@ -216,7 +190,6 @@ geometry = new THREE.BufferGeometry(); geometry.setIndex( new THREE.BufferAttribute( newIndexes, 1 ) ); - for ( const name of Object.keys( newAttributes ) ) { geometry.setAttribute( name, newAttributes[ name ] ); @@ -226,13 +199,10 @@ if ( hadNormals ) { geometry.computeVertexNormals(); - if ( oldNormals !== null ) { const changedNormals = new Array( oldNormals.length / 3 ).fill( false ); - for ( const splitData of splitIndexes ) changedNormals[ splitData.original ] = true; - for ( let i = 0; i < changedNormals.length; i ++ ) { if ( changedNormals[ i ] === false ) { diff --git a/examples/js/modifiers/SimplifyModifier.js b/examples/js/modifiers/SimplifyModifier.js index cf4d2610cfc1aa..2a3b3500166b4e 100644 --- a/examples/js/modifiers/SimplifyModifier.js +++ b/examples/js/modifiers/SimplifyModifier.js @@ -10,13 +10,14 @@ const _cb = new THREE.Vector3(), _ab = new THREE.Vector3(); - class SimplifyModifier { modify( geometry, count ) { geometry = geometry.clone(); - const attributes = geometry.attributes; // this modifier can only process indexed and non-indexed geomtries with a position attribute + const attributes = geometry.attributes; + + // this modifier can only process indexed and non-indexed geomtries with a position attribute for ( const name in attributes ) { @@ -24,26 +25,29 @@ } - geometry = THREE.BufferGeometryUtils.mergeVertices( geometry ); // + geometry = THREE.BufferGeometryUtils.mergeVertices( geometry ); + + // // put data of original geometry in different data structures // const vertices = []; - const faces = []; // add vertices + const faces = []; - const positionAttribute = geometry.getAttribute( 'position' ); + // add vertices + const positionAttribute = geometry.getAttribute( 'position' ); for ( let i = 0; i < positionAttribute.count; i ++ ) { const v = new THREE.Vector3().fromBufferAttribute( positionAttribute, i ); const vertex = new Vertex( v ); vertices.push( vertex ); - } // add faces + } + // add faces let index = geometry.getIndex(); - if ( index !== null ) { for ( let i = 0; i < index.count; i += 3 ) { @@ -68,8 +72,9 @@ } - } // compute all edge collapse costs + } + // compute all edge collapse costs for ( let i = 0, il = vertices.length; i < il; i ++ ) { @@ -79,11 +84,9 @@ let nextVertex; let z = count; - while ( z -- ) { nextVertex = minimumCostEdge( vertices ); - if ( ! nextVertex ) { console.log( 'THREE.SimplifyModifier: No next vertex' ); @@ -93,30 +96,35 @@ collapse( vertices, faces, nextVertex, nextVertex.collapseNeighbor ); - } // + } + // const simplifiedGeometry = new THREE.BufferGeometry(); const position = []; - index = []; // + index = []; + + // for ( let i = 0; i < vertices.length; i ++ ) { const vertex = vertices[ i ].position; - position.push( vertex.x, vertex.y, vertex.z ); // cache final index to GREATLY speed up faces reconstruction - + position.push( vertex.x, vertex.y, vertex.z ); + // cache final index to GREATLY speed up faces reconstruction vertices[ i ].id = i; - } // + } + // for ( let i = 0; i < faces.length; i ++ ) { const face = faces[ i ]; index.push( face.v1.id, face.v2.id, face.v3.id ); - } // + } + // simplifiedGeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) ); simplifiedGeometry.setIndex( index ); @@ -125,7 +133,6 @@ } } - function pushIfUnique( array, object ) { if ( array.indexOf( object ) === - 1 ) array.push( object ); @@ -143,33 +150,33 @@ // if we collapse edge uv by moving u to v then how // much different will the model change, i.e. the "error". + const edgelength = v.position.distanceTo( u.position ); let curvature = 0; - const sideFaces = []; // find the "sides" triangles that are on the edge uv + const sideFaces = []; + // find the "sides" triangles that are on the edge uv for ( let i = 0, il = u.faces.length; i < il; i ++ ) { const face = u.faces[ i ]; - if ( face.hasVertex( v ) ) { sideFaces.push( face ); } - } // use the triangle facing most away from the sides - // to determine our curvature term - + } + // use the triangle facing most away from the sides + // to determine our curvature term for ( let i = 0, il = u.faces.length; i < il; i ++ ) { let minCurvature = 1; const face = u.faces[ i ]; - for ( let j = 0; j < sideFaces.length; j ++ ) { - const sideFace = sideFaces[ j ]; // use dot product of face normals. - + const sideFace = sideFaces[ j ]; + // use dot product of face normals. const dotProd = face.normal.dot( sideFace.normal ); minCurvature = Math.min( minCurvature, ( 1.001 - dotProd ) / 2 ); @@ -177,12 +184,11 @@ curvature = Math.max( curvature, minCurvature ); - } // crude approach in attempt to preserve borders - // though it seems not to be totally correct - + } + // crude approach in attempt to preserve borders + // though it seems not to be totally correct const borders = 0; - if ( sideFaces.length < 2 ) { // we add some arbitrary cost for borders, @@ -204,6 +210,7 @@ // only cache the cost of the least cost edge at this vertex // (in member variable collapse) as well as the value of the // cost (in member variable collapseCost). + if ( v.neighbors.length === 0 ) { // collapse if no neighbors. @@ -214,12 +221,12 @@ } v.collapseCost = 100000; - v.collapseNeighbor = null; // search all neighboring edges for "least cost" edge + v.collapseNeighbor = null; + // search all neighboring edges for "least cost" edge for ( let i = 0; i < v.neighbors.length; i ++ ) { const collapseCost = computeEdgeCollapseCost( v, v.neighbors[ i ] ); - if ( ! v.collapseNeighbor ) { v.collapseNeighbor = v.neighbors[ i ]; @@ -232,7 +239,6 @@ v.costCount ++; v.totalCost += collapseCost; - if ( collapseCost < v.minCost ) { v.collapseNeighbor = v.neighbors[ i ]; @@ -240,17 +246,17 @@ } - } // we average the cost of collapsing at this vertex - + } - v.collapseCost = v.totalCost / v.costCount; // v.collapseCost = v.minCost; + // we average the cost of collapsing at this vertex + v.collapseCost = v.totalCost / v.costCount; + // v.collapseCost = v.minCost; } function removeVertex( v, vertices ) { console.assert( v.faces.length === 0 ); - while ( v.neighbors.length ) { const n = v.neighbors.pop(); @@ -267,10 +273,10 @@ removeFromArray( faces, f ); if ( f.v1 ) removeFromArray( f.v1.faces, f ); if ( f.v2 ) removeFromArray( f.v2.faces, f ); - if ( f.v3 ) removeFromArray( f.v3.faces, f ); // TODO optimize this! + if ( f.v3 ) removeFromArray( f.v3.faces, f ); + // TODO optimize this! const vs = [ f.v1, f.v2, f.v3 ]; - for ( let i = 0; i < 3; i ++ ) { const v1 = vs[ i ]; @@ -286,7 +292,9 @@ function collapse( vertices, faces, u, v ) { // u and v are pointers to vertices of an edge + // Collapse the edge uv by moving vertex u onto v + if ( ! v ) { // u is a vertex all by itself so just delete it.. @@ -296,14 +304,13 @@ } const tmpVertices = []; - for ( let i = 0; i < u.neighbors.length; i ++ ) { tmpVertices.push( u.neighbors[ i ] ); - } // delete triangles on edge uv: - + } + // delete triangles on edge uv: for ( let i = u.faces.length - 1; i >= 0; i -- ) { if ( u.faces[ i ] && u.faces[ i ].hasVertex( v ) ) { @@ -312,17 +319,18 @@ } - } // update remaining triangles to have v instead of u - + } + // update remaining triangles to have v instead of u for ( let i = u.faces.length - 1; i >= 0; i -- ) { u.faces[ i ].replaceVertex( u, v ); } - removeVertex( u, vertices ); // recompute the edge collapse costs in neighborhood + removeVertex( u, vertices ); + // recompute the edge collapse costs in neighborhood for ( let i = 0; i < tmpVertices.length; i ++ ) { computeEdgeCostAtVertex( tmpVertices[ i ] ); @@ -334,8 +342,8 @@ function minimumCostEdge( vertices ) { // O(n * n) approach. TODO optimize this - let least = vertices[ 0 ]; + let least = vertices[ 0 ]; for ( let i = 0; i < vertices.length; i ++ ) { if ( vertices[ i ].collapseCost < least.collapseCost ) { @@ -348,8 +356,9 @@ return least; - } // we use a triangle class to represent structure of face slightly differently + } + // we use a triangle class to represent structure of face slightly differently class Triangle { @@ -374,29 +383,22 @@ v3.addUniqueNeighbor( v2 ); } - computeNormal() { const vA = this.v1.position; const vB = this.v2.position; const vC = this.v3.position; - _cb.subVectors( vC, vB ); - _ab.subVectors( vA, vB ); - _cb.cross( _ab ).normalize(); - this.normal.copy( _cb ); } - hasVertex( v ) { return v === this.v1 || v === this.v2 || v === this.v3; } - replaceVertex( oldv, newv ) { if ( oldv === this.v1 ) this.v1 = newv; else if ( oldv === this.v2 ) this.v2 = newv; else if ( oldv === this.v3 ) this.v3 = newv; @@ -419,7 +421,6 @@ } } - class Vertex { constructor( v ) { @@ -428,12 +429,10 @@ this.id = - 1; // external use position in vertices list (for e.g. face generation) this.faces = []; // faces vertex is connected - this.neighbors = []; // neighbouring vertices aka "adjacentVertices" - // these will be computed in computeEdgeCostAtVertex() + // these will be computed in computeEdgeCostAtVertex() this.collapseCost = 0; // cost of collapsing this vertex, the less the better. aka objdist - this.collapseNeighbor = null; // best candinate for collapsing } @@ -443,14 +442,12 @@ pushIfUnique( this.neighbors, vertex ); } - removeIfNonNeighbor( n ) { const neighbors = this.neighbors; const faces = this.faces; const offset = neighbors.indexOf( n ); if ( offset === - 1 ) return; - for ( let i = 0; i < faces.length; i ++ ) { if ( faces[ i ].hasVertex( n ) ) return; diff --git a/examples/js/modifiers/TessellateModifier.js b/examples/js/modifiers/TessellateModifier.js index 7dfe548b3dfb0c..de0cb6f4ac7ddf 100644 --- a/examples/js/modifiers/TessellateModifier.js +++ b/examples/js/modifiers/TessellateModifier.js @@ -12,15 +12,15 @@ this.maxIterations = maxIterations; } - modify( geometry ) { if ( geometry.index !== null ) { geometry = geometry.toNonIndexed(); - } // + } + // const maxIterations = this.maxIterations; const maxEdgeLengthSquared = this.maxEdgeLength * this.maxEdgeLength; @@ -66,7 +66,6 @@ let uv2s2 = uv2s; let iteration = 0; let tessellating = true; - function addTriangle( a, b, c ) { const v1 = vs[ a ]; @@ -75,7 +74,6 @@ positions2.push( v1.x, v1.y, v1.z ); positions2.push( v2.x, v2.y, v2.z ); positions2.push( v3.x, v3.y, v3.z ); - if ( hasNormals ) { const n1 = ns[ a ]; @@ -128,7 +126,6 @@ tessellating = false; positions = positions2; positions2 = []; - if ( hasNormals ) { normals = normals2; @@ -162,7 +159,6 @@ va.fromArray( positions, i + 0 ); vb.fromArray( positions, i + 3 ); vc.fromArray( positions, i + 6 ); - if ( hasNormals ) { na.fromArray( normals, i + 0 ); @@ -198,11 +194,9 @@ const dab = va.distanceToSquared( vb ); const dbc = vb.distanceToSquared( vc ); const dac = va.distanceToSquared( vc ); - if ( dab > maxEdgeLengthSquared || dbc > maxEdgeLengthSquared || dac > maxEdgeLengthSquared ) { tessellating = true; - if ( dab >= dbc && dab >= dac ) { vm.lerpVectors( va, vb, 0.5 ); @@ -247,7 +241,6 @@ const geometry2 = new THREE.BufferGeometry(); geometry2.setAttribute( 'position', new THREE.Float32BufferAttribute( positions2, 3 ) ); - if ( hasNormals ) { geometry2.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals2, 3 ) ); diff --git a/examples/js/objects/GroundProjectedEnv.js b/examples/js/objects/GroundProjectedEnv.js new file mode 100644 index 00000000000000..5d9fe98c56aa20 --- /dev/null +++ b/examples/js/objects/GroundProjectedEnv.js @@ -0,0 +1,181 @@ +( function () { + + /** + * Ground projected env map adapted from @react-three/drei. + * https://github.com/pmndrs/drei/blob/master/src/core/Environment.tsx + */ + class GroundProjectedEnv extends THREE.Mesh { + + constructor( texture, options ) { + + const isCubeMap = texture.isCubeTexture; + const w = ( isCubeMap ? texture.image[ 0 ]?.width : texture.image.width ) ?? 1024; + const cubeSize = w / 4; + const _lodMax = Math.floor( Math.log2( cubeSize ) ); + const _cubeSize = Math.pow( 2, _lodMax ); + const width = 3 * Math.max( _cubeSize, 16 * 7 ); + const height = 4 * _cubeSize; + const defines = [ isCubeMap ? '#define ENVMAP_TYPE_CUBE' : '', `#define CUBEUV_TEXEL_WIDTH ${1.0 / width}`, `#define CUBEUV_TEXEL_HEIGHT ${1.0 / height}`, `#define CUBEUV_MAX_MIP ${_lodMax}.0` ]; + const vertexShader = /* glsl */` + varying vec3 vWorldPosition; + + void main() + { + + vec4 worldPosition = ( modelMatrix * vec4( position, 1.0 ) ); + vWorldPosition = worldPosition.xyz; + + gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); + + } + `; + const fragmentShader = defines.join( '\n' ) + /* glsl */` + #define ENVMAP_TYPE_CUBE_UV + + varying vec3 vWorldPosition; + + uniform float radius; + uniform float height; + uniform float angle; + + #ifdef ENVMAP_TYPE_CUBE + + uniform samplerCube map; + + #else + + uniform sampler2D map; + + #endif + + // From: https://www.shadertoy.com/view/4tsBD7 + float diskIntersectWithBackFaceCulling( vec3 ro, vec3 rd, vec3 c, vec3 n, float r ) + { + + float d = dot ( rd, n ); + + if( d > 0.0 ) { return 1e6; } + + vec3 o = ro - c; + float t = - dot( n, o ) / d; + vec3 q = o + rd * t; + + return ( dot( q, q ) < r * r ) ? t : 1e6; + + } + + // From: https://www.iquilezles.org/www/articles/intersectors/intersectors.htm + float sphereIntersect( vec3 ro, vec3 rd, vec3 ce, float ra ) + { + + vec3 oc = ro - ce; + float b = dot( oc, rd ); + float c = dot( oc, oc ) - ra * ra; + float h = b * b - c; + + if( h < 0.0 ) { return -1.0; } + + h = sqrt( h ); + + return - b + h; + + } + + vec3 project() + { + + vec3 p = normalize( vWorldPosition ); + vec3 camPos = cameraPosition; + camPos.y -= height; + + float intersection = sphereIntersect( camPos, p, vec3( 0.0 ), radius ); + if( intersection > 0.0 ) { + + vec3 h = vec3( 0.0, - height, 0.0 ); + float intersection2 = diskIntersectWithBackFaceCulling( camPos, p, h, vec3( 0.0, 1.0, 0.0 ), radius ); + p = ( camPos + min( intersection, intersection2 ) * p ) / radius; + + } else { + + p = vec3( 0.0, 1.0, 0.0 ); + + } + + return p; + + } + + #include + #include + + void main() + { + + vec3 projectedWorldPosition = project(); + + #ifdef ENVMAP_TYPE_CUBE + + vec3 outcolor = textureCube( map, projectedWorldPosition ).rgb; + + #else + + vec3 direction = normalize( projectedWorldPosition ); + vec2 uv = equirectUv( direction ); + vec3 outcolor = texture2D( map, uv ).rgb; + + #endif + + gl_FragColor = vec4( outcolor, 1.0 ); + + #include + #include + + } + `; + const uniforms = { + map: { + value: texture + }, + height: { + value: options?.height || 15 + }, + radius: { + value: options?.radius || 100 + } + }; + const geometry = new THREE.IcosahedronGeometry( 1, 16 ); + const material = new THREE.ShaderMaterial( { + uniforms, + fragmentShader, + vertexShader, + side: THREE.DoubleSide + } ); + super( geometry, material ); + + } + set radius( radius ) { + + this.material.uniforms.radius.value = radius; + + } + get radius() { + + return this.material.uniforms.radius.value; + + } + set height( height ) { + + this.material.uniforms.height.value = height; + + } + get height() { + + return this.material.uniforms.height.value; + + } + + } + + THREE.GroundProjectedEnv = GroundProjectedEnv; + +} )(); diff --git a/examples/js/objects/Lensflare.js b/examples/js/objects/Lensflare.js index 19db3488fb1d9c..a27715ec766373 100644 --- a/examples/js/objects/Lensflare.js +++ b/examples/js/objects/Lensflare.js @@ -11,13 +11,19 @@ this.isLensflare = true; this.type = 'Lensflare'; this.frustumCulled = false; - this.renderOrder = Infinity; // + this.renderOrder = Infinity; + + // const positionScreen = new THREE.Vector3(); - const positionView = new THREE.Vector3(); // textures + const positionView = new THREE.Vector3(); + + // textures const tempMap = new THREE.FramebufferTexture( 16, 16, THREE.RGBAFormat ); - const occlusionMap = new THREE.FramebufferTexture( 16, 16, THREE.RGBAFormat ); // material + const occlusionMap = new THREE.FramebufferTexture( 16, 16, THREE.RGBAFormat ); + + // material const geometry = Lensflare.Geometry; const material1a = new THREE.RawShaderMaterial( { @@ -29,9 +35,7 @@ value: null } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` precision highp float; @@ -45,9 +49,7 @@ gl_Position = vec4( position.xy * scale + screenPosition.xy, screenPosition.z, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` precision highp float; @@ -72,9 +74,7 @@ value: null } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` precision highp float; @@ -93,9 +93,7 @@ gl_Position = vec4( position.xy * scale + screenPosition.xy, screenPosition.z, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` precision highp float; @@ -111,9 +109,13 @@ depthTest: false, depthWrite: false, transparent: false - } ); // the following object is used for occlusionMap generation + } ); + + // the following object is used for occlusionMap generation + + const mesh1 = new THREE.Mesh( geometry, material1a ); - const mesh1 = new THREE.Mesh( geometry, material1a ); // + // const elements = []; const shader = LensflareElement.Shader; @@ -142,19 +144,18 @@ depthWrite: false } ); const mesh2 = new THREE.Mesh( geometry, material2 ); - this.addElement = function ( element ) { elements.push( element ); - }; // + }; + // const scale = new THREE.Vector2(); const screenPositionPixels = new THREE.Vector2(); const validArea = new THREE.Box2(); const viewport = new THREE.Vector4(); - this.onBeforeRender = function ( renderer, scene, camera ) { renderer.getCurrentViewport( viewport ); @@ -164,37 +165,51 @@ let size = 16 / viewport.w; scale.set( size * invAspect, size ); validArea.min.set( viewport.x, viewport.y ); - validArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) ); // calculate position in screen space + validArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) ); + + // calculate position in screen space positionView.setFromMatrixPosition( this.matrixWorld ); positionView.applyMatrix4( camera.matrixWorldInverse ); if ( positionView.z > 0 ) return; // lensflare is behind the camera - positionScreen.copy( positionView ).applyMatrix4( camera.projectionMatrix ); // horizontal and vertical coordinate of the lower left corner of the pixels to copy + positionScreen.copy( positionView ).applyMatrix4( camera.projectionMatrix ); + + // horizontal and vertical coordinate of the lower left corner of the pixels to copy screenPositionPixels.x = viewport.x + positionScreen.x * halfViewportWidth + halfViewportWidth - 8; - screenPositionPixels.y = viewport.y + positionScreen.y * halfViewportHeight + halfViewportHeight - 8; // screen cull + screenPositionPixels.y = viewport.y + positionScreen.y * halfViewportHeight + halfViewportHeight - 8; + + // screen cull if ( validArea.containsPoint( screenPositionPixels ) ) { // save current RGB to temp texture - renderer.copyFramebufferToTexture( screenPositionPixels, tempMap ); // render pink quad + + renderer.copyFramebufferToTexture( screenPositionPixels, tempMap ); + + // render pink quad let uniforms = material1a.uniforms; uniforms[ 'scale' ].value = scale; uniforms[ 'screenPosition' ].value = positionScreen; - renderer.renderBufferDirect( camera, null, geometry, material1a, mesh1, null ); // copy result to occlusionMap + renderer.renderBufferDirect( camera, null, geometry, material1a, mesh1, null ); - renderer.copyFramebufferToTexture( screenPositionPixels, occlusionMap ); // restore graphics + // copy result to occlusionMap + + renderer.copyFramebufferToTexture( screenPositionPixels, occlusionMap ); + + // restore graphics uniforms = material1b.uniforms; uniforms[ 'scale' ].value = scale; uniforms[ 'screenPosition' ].value = positionScreen; - renderer.renderBufferDirect( camera, null, geometry, material1b, mesh1, null ); // render elements + renderer.renderBufferDirect( camera, null, geometry, material1b, mesh1, null ); + + // render elements const vecX = - positionScreen.x * 2; const vecY = - positionScreen.y * 2; - for ( let i = 0, l = elements.length; i < l; i ++ ) { const element = elements[ i ]; @@ -222,7 +237,6 @@ material2.dispose(); tempMap.dispose(); occlusionMap.dispose(); - for ( let i = 0, l = elements.length; i < l; i ++ ) { elements[ i ].texture.dispose(); @@ -233,8 +247,9 @@ } - } // + } + // class LensflareElement { @@ -248,7 +263,6 @@ } } - LensflareElement.Shader = { uniforms: { 'map': { @@ -267,9 +281,7 @@ value: null } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` precision highp float; @@ -307,9 +319,7 @@ gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` precision highp float; @@ -328,7 +338,6 @@ }` }; - Lensflare.Geometry = function () { const geometry = new THREE.BufferGeometry(); diff --git a/examples/js/objects/LightningStorm.js b/examples/js/objects/LightningStorm.js index cfb106c14a4ec9..cc04caaabdcb46 100644 --- a/examples/js/objects/LightningStorm.js +++ b/examples/js/objects/LightningStorm.js @@ -51,7 +51,9 @@ constructor( stormParams = {} ) { super(); - this.isLightningStorm = true; // Parameters + this.isLightningStorm = true; + + // Parameters this.stormParams = stormParams; stormParams.size = stormParams.size !== undefined ? stormParams.size : 1000.0; @@ -68,7 +70,6 @@ this.lightningMaterial = stormParams.lightningMaterial !== undefined ? stormParams.lightningMaterial : new THREE.MeshBasicMaterial( { color: 0xB0FFFF } ); - if ( stormParams.onRayPosition !== undefined ) { this.onRayPosition = stormParams.onRayPosition; @@ -85,13 +86,14 @@ } - this.onLightningDown = stormParams.onLightningDown; // Internal state + this.onLightningDown = stormParams.onLightningDown; + + // Internal state this.inited = false; this.nextLightningTime = 0; this.lightningsMeshes = []; this.deadLightningsMeshes = []; - for ( let i = 0; i < this.stormParams.maxLightnings; i ++ ) { const lightning = new THREE.LightningStrike( THREE.LightningStrike.copyParameters( {}, this.lightningParameters ) ); @@ -101,7 +103,6 @@ } } - update( time ) { if ( ! this.inited ) { @@ -114,8 +115,8 @@ if ( time >= this.nextLightningTime ) { // Lightning creation - const lightningMesh = this.deadLightningsMeshes.pop(); + const lightningMesh = this.deadLightningsMeshes.pop(); if ( lightningMesh ) { const lightningParams1 = THREE.LightningStrike.copyParameters( lightningMesh.geometry.rayParameters, this.lightningParameters ); @@ -126,23 +127,21 @@ this.add( lightningMesh ); this.lightningsMeshes.push( lightningMesh ); - } // Schedule next lightning - + } + // Schedule next lightning this.nextLightningTime = this.getNextLightningTime( time ); } let i = 0, il = this.lightningsMeshes.length; - while ( i < il ) { const mesh = this.lightningsMeshes[ i ]; const lightning = mesh.geometry; const prevState = lightning.state; lightning.update( time ); - if ( prevState === THREE.LightningStrike.RAY_PROPAGATING && lightning.state > prevState ) { if ( this.onLightningDown ) { @@ -156,6 +155,7 @@ if ( lightning.state === THREE.LightningStrike.RAY_EXTINGUISHED ) { // Lightning is to be destroyed + this.lightningsMeshes.splice( this.lightningsMeshes.indexOf( mesh ), 1 ); this.deadLightningsMeshes.push( mesh ); this.remove( mesh ); @@ -170,13 +170,11 @@ } } - getNextLightningTime( currentTime ) { return currentTime + THREE.MathUtils.lerp( this.stormParams.lightningMinPeriod, this.stormParams.lightningMaxPeriod, Math.random() ) / ( this.stormParams.maxLightnings + 1 ); } - copy( source, recursive ) { super.copy( source, recursive ); @@ -195,7 +193,6 @@ return this; } - clone() { return new this.constructor( this.stormParams ).copy( this ); diff --git a/examples/js/objects/MarchingCubes.js b/examples/js/objects/MarchingCubes.js index 05925ecdbc6e0c..4cc4c8d52115f4 100644 --- a/examples/js/objects/MarchingCubes.js +++ b/examples/js/objects/MarchingCubes.js @@ -11,33 +11,45 @@ const geometry = new THREE.BufferGeometry(); super( geometry, material ); this.isMarchingCubes = true; - const scope = this; // temp buffers used in polygonize + const scope = this; + + // temp buffers used in polygonize const vlist = new Float32Array( 12 * 3 ); const nlist = new Float32Array( 12 * 3 ); const clist = new Float32Array( 12 * 3 ); this.enableUvs = enableUvs; - this.enableColors = enableColors; // functions have to be object properties + this.enableColors = enableColors; + + // functions have to be object properties // prototype functions kill performance // (tested and it was 4x slower !!!) this.init = function ( resolution ) { - this.resolution = resolution; // parameters + this.resolution = resolution; + + // parameters - this.isolation = 80.0; // size of field, 32 is pushing it in Javascript :) + this.isolation = 80.0; + + // size of field, 32 is pushing it in Javascript :) this.size = resolution; this.size2 = this.size * this.size; this.size3 = this.size2 * this.size; - this.halfsize = this.size / 2.0; // deltas + this.halfsize = this.size / 2.0; + + // deltas this.delta = 2.0 / this.size; this.yd = this.size; this.zd = this.size2; this.field = new Float32Array( this.size3 ); this.normal_cache = new Float32Array( this.size3 * 3 ); - this.palette = new Float32Array( this.size3 * 3 ); // + this.palette = new Float32Array( this.size3 * 3 ); + + // this.count = 0; const maxVertexCount = maxPolyCount * 3; @@ -49,7 +61,6 @@ const normalAttribute = new THREE.BufferAttribute( this.normalArray, 3 ); normalAttribute.setUsage( THREE.DynamicDrawUsage ); geometry.setAttribute( 'normal', normalAttribute ); - if ( this.enableUvs ) { this.uvArray = new Float32Array( maxVertexCount * 2 ); @@ -68,11 +79,12 @@ } - }; /////////////////////// + }; + + /////////////////////// // Polygonization /////////////////////// - function lerp( a, b, t ) { return a + ( b - a ) * t; @@ -132,7 +144,6 @@ function compNorm( q ) { const q3 = q * 3; - if ( scope.normal_cache[ q3 ] === 0.0 ) { scope.normal_cache[ q3 + 0 ] = scope.field[ q - 1 ] - scope.field[ q + 1 ]; @@ -141,9 +152,10 @@ } - } // Returns total number of triangles. Fills triangles. - // (this is where most of time is spent - it's inner work of O(n3) loop ) + } + // Returns total number of triangles. Fills triangles. + // (this is where most of time is spent - it's inner work of O(n3) loop ) function polygonize( fx, fy, fz, q, isol ) { @@ -171,14 +183,18 @@ if ( field4 < isol ) cubeindex |= 16; if ( field5 < isol ) cubeindex |= 32; if ( field6 < isol ) cubeindex |= 128; - if ( field7 < isol ) cubeindex |= 64; // if cube is entirely in/out of the surface - bail, nothing to draw + if ( field7 < isol ) cubeindex |= 64; + + // if cube is entirely in/out of the surface - bail, nothing to draw const bits = edgeTable[ cubeindex ]; if ( bits === 0 ) return 0; const d = scope.delta, fx2 = fx + d, fy2 = fy + d, - fz2 = fz + d; // top of the cube + fz2 = fz + d; + + // top of the cube if ( bits & 1 ) { @@ -210,8 +226,9 @@ compNorm( qy ); VIntY( q * 3, 9, isol, fx, fy, fz, field0, field2, q, qy ); - } // bottom of the cube + } + // bottom of the cube if ( bits & 16 ) { @@ -243,9 +260,9 @@ compNorm( qyz ); VIntY( qz * 3, 21, isol, fx, fy, fz2, field4, field6, qz, qyz ); - } // vertical lines of the cube - + } + // vertical lines of the cube if ( bits & 256 ) { compNorm( q ); @@ -284,7 +301,9 @@ o2, o3, numtris = 0, - i = 0; // here is where triangles are created + i = 0; + + // here is where triangles are created while ( triTable[ cubeindex + i ] != - 1 ) { @@ -303,7 +322,9 @@ function posnormtriv( pos, norm, colors, o1, o2, o3 ) { - const c = scope.count * 3; // positions + const c = scope.count * 3; + + // positions scope.positionArray[ c + 0 ] = pos[ o1 ]; scope.positionArray[ c + 1 ] = pos[ o1 + 1 ]; @@ -313,7 +334,9 @@ scope.positionArray[ c + 5 ] = pos[ o2 + 2 ]; scope.positionArray[ c + 6 ] = pos[ o3 ]; scope.positionArray[ c + 7 ] = pos[ o3 + 1 ]; - scope.positionArray[ c + 8 ] = pos[ o3 + 2 ]; // normals + scope.positionArray[ c + 8 ] = pos[ o3 + 2 ]; + + // normals if ( scope.material.flatShading === true ) { @@ -342,8 +365,9 @@ scope.normalArray[ c + 7 ] = norm[ o3 + 1 ]; scope.normalArray[ c + 8 ] = norm[ o3 + 2 ]; - } // uvs + } + // uvs if ( scope.enableUvs ) { @@ -355,8 +379,9 @@ scope.uvArray[ d + 4 ] = pos[ o3 + 0 ]; scope.uvArray[ d + 5 ] = pos[ o3 + 2 ]; - } // colors + } + // colors if ( scope.enableColors ) { @@ -374,20 +399,21 @@ scope.count += 3; - } ///////////////////////////////////// + } + + ///////////////////////////////////// // Metaballs ///////////////////////////////////// + // Adds a reciprocal ball (nice and blobby) that, to be fast, fades to zero after // a fixed distance, determined by strength and subtract. - this.addBall = function ( ballx, bally, ballz, strength, subtract, colors ) { const sign = Math.sign( strength ); strength = Math.abs( strength ); const userDefineColor = ! ( colors === undefined || colors === null ); let ballColor = new THREE.Color( ballx, bally, ballz ); - if ( userDefineColor ) { try { @@ -400,14 +426,15 @@ } - } // Let's solve the equation to find the radius: + } + + // Let's solve the equation to find the radius: // 1.0 / (0.000001 + radius^2) * strength - subtract = 0 // strength / (radius^2) = subtract // strength = subtract * radius^2 // radius^2 = strength / subtract // radius = sqrt(strength / subtract) - const radius = this.size * Math.sqrt( strength / subtract ), zs = ballz * this.size, ys = bally * this.size, @@ -423,33 +450,32 @@ let min_x = Math.floor( xs - radius ); if ( min_x < 1 ) min_x = 1; let max_x = Math.floor( xs + radius ); - if ( max_x > this.size - 1 ) max_x = this.size - 1; // Don't polygonize in the outer layer because normals aren't + if ( max_x > this.size - 1 ) max_x = this.size - 1; + + // Don't polygonize in the outer layer because normals aren't // well-defined there. let x, y, z, y_offset, z_offset, fx, fy, fz, fz2, fy2, val; - for ( z = min_z; z < max_z; z ++ ) { z_offset = this.size2 * z; fz = z / this.size - ballz; fz2 = fz * fz; - for ( y = min_y; y < max_y; y ++ ) { y_offset = z_offset + this.size * y; fy = y / this.size - bally; fy2 = fy * fy; - for ( x = min_x; x < max_x; x ++ ) { fx = x / this.size - ballx; val = strength / ( 0.000001 + fx * fx + fy2 + fz2 ) - subtract; - if ( val > 0.0 ) { - this.field[ y_offset + x ] += val * sign; // optimization - // http://www.geisswerks.com/ryan/BLOBS/blobs.html + this.field[ y_offset + x ] += val * sign; + // optimization + // http://www.geisswerks.com/ryan/BLOBS/blobs.html const ratio = Math.sqrt( ( x - xs ) * ( x - xs ) + ( y - ys ) * ( y - ys ) + ( z - zs ) * ( z - zs ) ) / radius; const contrib = 1 - ratio * ratio * ratio * ( ratio * ( ratio * 6 - 15 ) + 10 ); this.palette[ ( y_offset + x ) * 3 + 0 ] += ballColor.r * contrib; @@ -482,19 +508,16 @@ cxy, dist = size * Math.sqrt( strength / subtract ); if ( dist > size ) dist = size; - for ( x = 0; x < dist; x ++ ) { xdiv = x / size; xx = xdiv * xdiv; val = strength / ( 0.0001 + xx ) - subtract; - if ( val > 0.0 ) { for ( y = 0; y < size; y ++ ) { cxy = x + y * yd; - for ( z = 0; z < size; z ++ ) { field[ zd * z + cxy ] += val; @@ -526,21 +549,17 @@ cxy, dist = size * Math.sqrt( strength / subtract ); if ( dist > size ) dist = size; - for ( y = 0; y < dist; y ++ ) { ydiv = y / size; yy = ydiv * ydiv; val = strength / ( 0.0001 + yy ) - subtract; - if ( val > 0.0 ) { cy = y * yd; - for ( x = 0; x < size; x ++ ) { cxy = cy + x; - for ( z = 0; z < size; z ++ ) field[ zd * z + cxy ] += val; } @@ -554,6 +573,7 @@ this.addPlaneZ = function ( strength, subtract ) { // cache attribute lookups + const size = this.size, yd = this.yd, zd = this.zd, @@ -568,21 +588,17 @@ cyz, dist = size * Math.sqrt( strength / subtract ); if ( dist > size ) dist = size; - for ( z = 0; z < dist; z ++ ) { zdiv = z / size; zz = zdiv * zdiv; val = strength / ( 0.0001 + zz ) - subtract; - if ( val > 0.0 ) { cz = zd * z; - for ( y = 0; y < size; y ++ ) { cyz = cz + y * yd; - for ( x = 0; x < size; x ++ ) field[ cyz + x ] += val; } @@ -591,11 +607,12 @@ } - }; ///////////////////////////////////// + }; + + ///////////////////////////////////// // Updates ///////////////////////////////////// - this.setCell = function ( x, y, z, value ) { const index = this.size2 * z + this.size * y + x; @@ -616,7 +633,6 @@ const fieldCopy = field.slice(); const size = this.size; const size2 = this.size2; - for ( let x = 0; x < size; x ++ ) { for ( let y = 0; y < size; y ++ ) { @@ -626,17 +642,14 @@ const index = size2 * z + size * y + x; let val = fieldCopy[ index ]; let count = 1; - for ( let x2 = - 1; x2 <= 1; x2 += 2 ) { const x3 = x2 + x; if ( x3 < 0 || x3 >= size ) continue; - for ( let y2 = - 1; y2 <= 1; y2 += 2 ) { const y3 = y2 + y; if ( y3 < 0 || y3 >= size ) continue; - for ( let z2 = - 1; z2 <= 1; z2 += 2 ) { const z3 = z2 + z; @@ -665,6 +678,7 @@ this.reset = function () { // wipe the normal cache + for ( let i = 0; i < this.size3; i ++ ) { this.normal_cache[ i * 3 ] = 0.0; @@ -677,10 +691,11 @@ this.update = function () { - this.count = 0; // Triangulate. Yeah, this is slow. + this.count = 0; - const smin2 = this.size - 2; + // Triangulate. Yeah, this is slow. + const smin2 = this.size - 2; for ( let z = 1; z < smin2; z ++ ) { const z_offset = this.size2 * z; @@ -694,7 +709,6 @@ for ( let x = 1; x < smin2; x ++ ) { const fx = ( x - this.halfsize ) / this.halfsize; //+ 1 - const q = y_offset + x; polygonize( fx, fy, fz, q, this.isolation ); @@ -702,15 +716,20 @@ } - } // set the draw range to only the processed triangles + } + // set the draw range to only the processed triangles - this.geometry.setDrawRange( 0, this.count ); // update geometry data + this.geometry.setDrawRange( 0, this.count ); + + // update geometry data geometry.getAttribute( 'position' ).needsUpdate = true; geometry.getAttribute( 'normal' ).needsUpdate = true; if ( this.enableUvs ) geometry.getAttribute( 'uv' ).needsUpdate = true; - if ( this.enableColors ) geometry.getAttribute( 'color' ).needsUpdate = true; // safety check + if ( this.enableColors ) geometry.getAttribute( 'color' ).needsUpdate = true; + + // safety check if ( this.count / 3 > maxPolyCount ) console.warn( 'THREE.MarchingCubes: Geometry buffers too small for rendering. Please create an instance with a higher poly count.' ); @@ -720,14 +739,16 @@ } - } ///////////////////////////////////// + } + + ///////////////////////////////////// // Marching cubes lookup tables ///////////////////////////////////// + // These tables are straight from Paul Bourke's page: // http://paulbourke.net/geometry/polygonise/ // who in turn got them from Cory Gene Bloyd. - const edgeTable = new Int32Array( [ 0x0, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, 0x190, 0x99, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, 0x230, 0x339, 0x33, 0x13a, 0x636, 0x73f, 0x435, 0x53c, 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, 0x3a0, 0x2a9, 0x1a3, 0xaa, 0x7a6, 0x6af, 0x5a5, 0x4ac, 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, 0x460, 0x569, 0x663, 0x76a, 0x66, 0x16f, 0x265, 0x36c, 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff, 0x3f5, 0x2fc, 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55, 0x15c, 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc, 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, 0xcc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, 0x15c, 0x55, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, 0x2fc, 0x3f5, 0xff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, 0x36c, 0x265, 0x16f, 0x66, 0x76a, 0x663, 0x569, 0x460, 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa, 0x1a3, 0x2a9, 0x3a0, 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33, 0x339, 0x230, 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99, 0x190, 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 ] ); const triTable = new Int32Array( [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 8, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 1, 9, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 8, 3, 9, 8, 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 2, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 8, 3, 1, 2, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 2, 10, 0, 2, 9, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 2, 8, 3, 2, 10, 8, 10, 9, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 3, 11, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 11, 2, 8, 11, 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 9, 0, 2, 3, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 11, 2, 1, 9, 11, 9, 8, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 3, 10, 1, 11, 10, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 10, 1, 0, 8, 10, 8, 11, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 3, 9, 0, 3, 11, 9, 11, 10, 9, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 8, 10, 10, 8, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 4, 7, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 4, 3, 0, 7, 3, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 1, 9, 8, 4, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 4, 1, 9, 4, 7, 1, 7, 3, 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 2, 10, 8, 4, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 3, 4, 7, 3, 0, 4, 1, 2, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 2, 10, 9, 0, 2, 8, 4, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, - 1, - 1, - 1, - 1, 8, 4, 7, 3, 11, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 11, 4, 7, 11, 2, 4, 2, 0, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 0, 1, 8, 4, 7, 2, 3, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, - 1, - 1, - 1, - 1, 3, 10, 1, 3, 11, 10, 7, 8, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, - 1, - 1, - 1, - 1, 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, - 1, - 1, - 1, - 1, 4, 7, 11, 4, 11, 9, 9, 11, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 5, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 5, 4, 0, 8, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 5, 4, 1, 5, 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 8, 5, 4, 8, 3, 5, 3, 1, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 2, 10, 9, 5, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 3, 0, 8, 1, 2, 10, 4, 9, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 5, 2, 10, 5, 4, 2, 4, 0, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, - 1, - 1, - 1, - 1, 9, 5, 4, 2, 3, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 11, 2, 0, 8, 11, 4, 9, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 5, 4, 0, 1, 5, 2, 3, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, - 1, - 1, - 1, - 1, 10, 3, 11, 10, 1, 3, 9, 5, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, - 1, - 1, - 1, - 1, 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, - 1, - 1, - 1, - 1, 5, 4, 8, 5, 8, 10, 10, 8, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 7, 8, 5, 7, 9, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 3, 0, 9, 5, 3, 5, 7, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 7, 8, 0, 1, 7, 1, 5, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 5, 3, 3, 5, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 7, 8, 9, 5, 7, 10, 1, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, - 1, - 1, - 1, - 1, 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, - 1, - 1, - 1, - 1, 2, 10, 5, 2, 5, 3, 3, 5, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 7, 9, 5, 7, 8, 9, 3, 11, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, - 1, - 1, - 1, - 1, 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, - 1, - 1, - 1, - 1, 11, 2, 1, 11, 1, 7, 7, 1, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, - 1, - 1, - 1, - 1, 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, - 1, 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, - 1, 11, 10, 5, 7, 11, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 10, 6, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 8, 3, 5, 10, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 0, 1, 5, 10, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 8, 3, 1, 9, 8, 5, 10, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 6, 5, 2, 6, 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 6, 5, 1, 2, 6, 3, 0, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 6, 5, 9, 0, 6, 0, 2, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, - 1, - 1, - 1, - 1, 2, 3, 11, 10, 6, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 11, 0, 8, 11, 2, 0, 10, 6, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 1, 9, 2, 3, 11, 5, 10, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, - 1, - 1, - 1, - 1, 6, 3, 11, 6, 5, 3, 5, 1, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, - 1, - 1, - 1, - 1, 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, - 1, - 1, - 1, - 1, 6, 5, 9, 6, 9, 11, 11, 9, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 5, 10, 6, 4, 7, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 4, 3, 0, 4, 7, 3, 6, 5, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 9, 0, 5, 10, 6, 8, 4, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, - 1, - 1, - 1, - 1, 6, 1, 2, 6, 5, 1, 4, 7, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, - 1, - 1, - 1, - 1, 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, - 1, - 1, - 1, - 1, 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, - 1, 3, 11, 2, 7, 8, 4, 10, 6, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, - 1, - 1, - 1, - 1, 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, - 1, - 1, - 1, - 1, 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, - 1, 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, - 1, - 1, - 1, - 1, 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, - 1, 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, - 1, 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, - 1, - 1, - 1, - 1, 10, 4, 9, 6, 4, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 4, 10, 6, 4, 9, 10, 0, 8, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 10, 0, 1, 10, 6, 0, 6, 4, 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, - 1, - 1, - 1, - 1, 1, 4, 9, 1, 2, 4, 2, 6, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, - 1, - 1, - 1, - 1, 0, 2, 4, 4, 2, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 8, 3, 2, 8, 2, 4, 4, 2, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 10, 4, 9, 10, 6, 4, 11, 2, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, - 1, - 1, - 1, - 1, 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, - 1, - 1, - 1, - 1, 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, - 1, 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, - 1, - 1, - 1, - 1, 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, - 1, 3, 11, 6, 3, 6, 0, 0, 6, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 6, 4, 8, 11, 6, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 7, 10, 6, 7, 8, 10, 8, 9, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, - 1, - 1, - 1, - 1, 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, - 1, - 1, - 1, - 1, 10, 6, 7, 10, 7, 1, 1, 7, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, - 1, - 1, - 1, - 1, 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, - 1, 7, 8, 0, 7, 0, 6, 6, 0, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 7, 3, 2, 6, 7, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, - 1, - 1, - 1, - 1, 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, - 1, 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, - 1, 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, - 1, - 1, - 1, - 1, 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, - 1, 0, 9, 1, 11, 6, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, - 1, - 1, - 1, - 1, 7, 11, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 7, 6, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 3, 0, 8, 11, 7, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 1, 9, 11, 7, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 8, 1, 9, 8, 3, 1, 11, 7, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 10, 1, 2, 6, 11, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 2, 10, 3, 0, 8, 6, 11, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 2, 9, 0, 2, 10, 9, 6, 11, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, - 1, - 1, - 1, - 1, 7, 2, 3, 6, 2, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 7, 0, 8, 7, 6, 0, 6, 2, 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 2, 7, 6, 2, 3, 7, 0, 1, 9, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, - 1, - 1, - 1, - 1, 10, 7, 6, 10, 1, 7, 1, 3, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, - 1, - 1, - 1, - 1, 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, - 1, - 1, - 1, - 1, 7, 6, 10, 7, 10, 8, 8, 10, 9, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 6, 8, 4, 11, 8, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 3, 6, 11, 3, 0, 6, 0, 4, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 8, 6, 11, 8, 4, 6, 9, 0, 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, - 1, - 1, - 1, - 1, 6, 8, 4, 6, 11, 8, 2, 10, 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, - 1, - 1, - 1, - 1, 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, - 1, - 1, - 1, - 1, 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, - 1, 8, 2, 3, 8, 4, 2, 4, 6, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 4, 2, 4, 6, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, - 1, - 1, - 1, - 1, 1, 9, 4, 1, 4, 2, 2, 4, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, - 1, - 1, - 1, - 1, 10, 1, 0, 10, 0, 6, 6, 0, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, - 1, 10, 9, 4, 6, 10, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 4, 9, 5, 7, 6, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 8, 3, 4, 9, 5, 11, 7, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 5, 0, 1, 5, 4, 0, 7, 6, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, - 1, - 1, - 1, - 1, 9, 5, 4, 10, 1, 2, 7, 6, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, - 1, - 1, - 1, - 1, 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, - 1, - 1, - 1, - 1, 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, - 1, 7, 2, 3, 7, 6, 2, 5, 4, 9, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, - 1, - 1, - 1, - 1, 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, - 1, - 1, - 1, - 1, 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, - 1, 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, - 1, - 1, - 1, - 1, 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, - 1, 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, - 1, 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, - 1, - 1, - 1, - 1, 6, 9, 5, 6, 11, 9, 11, 8, 9, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, - 1, - 1, - 1, - 1, 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, - 1, - 1, - 1, - 1, 6, 11, 3, 6, 3, 5, 5, 3, 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, - 1, - 1, - 1, - 1, 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, - 1, 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, - 1, 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, - 1, - 1, - 1, - 1, 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, - 1, - 1, - 1, - 1, 9, 5, 6, 9, 6, 0, 0, 6, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, - 1, 1, 5, 6, 2, 1, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, - 1, 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, - 1, - 1, - 1, - 1, 0, 3, 8, 5, 6, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 10, 5, 6, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 11, 5, 10, 7, 5, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 11, 5, 10, 11, 7, 5, 8, 3, 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 5, 11, 7, 5, 10, 11, 1, 9, 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, - 1, - 1, - 1, - 1, 11, 1, 2, 11, 7, 1, 7, 5, 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, - 1, - 1, - 1, - 1, 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, - 1, - 1, - 1, - 1, 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, - 1, 2, 5, 10, 2, 3, 5, 3, 7, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, - 1, - 1, - 1, - 1, 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, - 1, - 1, - 1, - 1, 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, - 1, 1, 3, 5, 3, 7, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 8, 7, 0, 7, 1, 1, 7, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 0, 3, 9, 3, 5, 5, 3, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 8, 7, 5, 9, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 5, 8, 4, 5, 10, 8, 10, 11, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, - 1, - 1, - 1, - 1, 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, - 1, - 1, - 1, - 1, 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, - 1, 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, - 1, - 1, - 1, - 1, 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, - 1, 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, - 1, 9, 4, 5, 2, 11, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, - 1, - 1, - 1, - 1, 5, 10, 2, 5, 2, 4, 4, 2, 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, - 1, 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, - 1, - 1, - 1, - 1, 8, 4, 5, 8, 5, 3, 3, 5, 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 4, 5, 1, 0, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, - 1, - 1, - 1, - 1, 9, 4, 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 4, 11, 7, 4, 9, 11, 9, 10, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, - 1, - 1, - 1, - 1, 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, - 1, - 1, - 1, - 1, 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, - 1, 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, - 1, - 1, - 1, - 1, 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, - 1, 11, 7, 4, 11, 4, 2, 2, 4, 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, - 1, - 1, - 1, - 1, 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, - 1, - 1, - 1, - 1, 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, - 1, 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, - 1, 1, 10, 2, 8, 7, 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 4, 9, 1, 4, 1, 7, 7, 1, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, - 1, - 1, - 1, - 1, 4, 0, 3, 7, 4, 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 4, 8, 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 10, 8, 10, 11, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 3, 0, 9, 3, 9, 11, 11, 9, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 1, 10, 0, 10, 8, 8, 10, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 3, 1, 10, 11, 3, 10, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 2, 11, 1, 11, 9, 9, 11, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, - 1, - 1, - 1, - 1, 0, 2, 11, 8, 0, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 3, 2, 11, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 2, 3, 8, 2, 8, 10, 10, 8, 9, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 9, 10, 2, 0, 9, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, - 1, - 1, - 1, - 1, 1, 10, 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 3, 8, 9, 1, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 9, 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 0, 3, 8, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1 ] ); diff --git a/examples/js/objects/Reflector.js b/examples/js/objects/Reflector.js index f38d7e40e69652..0b4967efcb8d5b 100644 --- a/examples/js/objects/Reflector.js +++ b/examples/js/objects/Reflector.js @@ -14,7 +14,9 @@ const textureHeight = options.textureHeight || 512; const clipBias = options.clipBias || 0; const shader = options.shader || Reflector.ReflectorShader; - const multisample = options.multisample !== undefined ? options.multisample : 4; // + const multisample = options.multisample !== undefined ? options.multisample : 4; + + // const reflectorPlane = new THREE.Plane(); const normal = new THREE.Vector3(); @@ -29,7 +31,8 @@ const textureMatrix = new THREE.Matrix4(); const virtualCamera = this.camera; const renderTarget = new THREE.WebGLRenderTarget( textureWidth, textureHeight, { - samples: multisample + samples: multisample, + type: THREE.HalfFloatType } ); const material = new THREE.ShaderMaterial( { uniforms: THREE.UniformsUtils.clone( shader.uniforms ), @@ -40,7 +43,6 @@ material.uniforms[ 'color' ].value = color; material.uniforms[ 'textureMatrix' ].value = textureMatrix; this.material = material; - this.onBeforeRender = function ( renderer, scene, camera ) { reflectorWorldPosition.setFromMatrixPosition( scope.matrixWorld ); @@ -48,7 +50,9 @@ rotationMatrix.extractRotation( scope.matrixWorld ); normal.set( 0, 0, 1 ); normal.applyMatrix4( rotationMatrix ); - view.subVectors( reflectorWorldPosition, cameraWorldPosition ); // Avoid rendering when reflector is facing away + view.subVectors( reflectorWorldPosition, cameraWorldPosition ); + + // Avoid rendering when reflector is facing away if ( view.dot( normal ) > 0 ) return; view.reflect( normal ).negate(); @@ -68,14 +72,16 @@ virtualCamera.far = camera.far; // Used in WebGLBackground virtualCamera.updateMatrixWorld(); - virtualCamera.projectionMatrix.copy( camera.projectionMatrix ); // Update the texture matrix + virtualCamera.projectionMatrix.copy( camera.projectionMatrix ); + // Update the texture matrix textureMatrix.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 ); textureMatrix.multiply( virtualCamera.projectionMatrix ); textureMatrix.multiply( virtualCamera.matrixWorldInverse ); - textureMatrix.multiply( scope.matrixWorld ); // Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html - // Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf + textureMatrix.multiply( scope.matrixWorld ); + // Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html + // Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf reflectorPlane.setFromNormalAndCoplanarPoint( normal, reflectorWorldPosition ); reflectorPlane.applyMatrix4( virtualCamera.matrixWorldInverse ); clipPlane.set( reflectorPlane.normal.x, reflectorPlane.normal.y, reflectorPlane.normal.z, reflectorPlane.constant ); @@ -83,24 +89,28 @@ q.x = ( Math.sign( clipPlane.x ) + projectionMatrix.elements[ 8 ] ) / projectionMatrix.elements[ 0 ]; q.y = ( Math.sign( clipPlane.y ) + projectionMatrix.elements[ 9 ] ) / projectionMatrix.elements[ 5 ]; q.z = - 1.0; - q.w = ( 1.0 + projectionMatrix.elements[ 10 ] ) / projectionMatrix.elements[ 14 ]; // Calculate the scaled plane vector + q.w = ( 1.0 + projectionMatrix.elements[ 10 ] ) / projectionMatrix.elements[ 14 ]; - clipPlane.multiplyScalar( 2.0 / clipPlane.dot( q ) ); // Replacing the third row of the projection matrix + // Calculate the scaled plane vector + clipPlane.multiplyScalar( 2.0 / clipPlane.dot( q ) ); + // Replacing the third row of the projection matrix projectionMatrix.elements[ 2 ] = clipPlane.x; projectionMatrix.elements[ 6 ] = clipPlane.y; projectionMatrix.elements[ 10 ] = clipPlane.z + 1.0 - clipBias; - projectionMatrix.elements[ 14 ] = clipPlane.w; // Render + projectionMatrix.elements[ 14 ] = clipPlane.w; - renderTarget.texture.encoding = renderer.outputEncoding; + // Render scope.visible = false; const currentRenderTarget = renderer.getRenderTarget(); const currentXrEnabled = renderer.xr.enabled; const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate; + const currentOutputEncoding = renderer.outputEncoding; + const currentToneMapping = renderer.toneMapping; renderer.xr.enabled = false; // Avoid camera modification - renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows - + renderer.outputEncoding = THREE.LinearEncoding; + renderer.toneMapping = THREE.NoToneMapping; renderer.setRenderTarget( renderTarget ); renderer.state.buffers.depth.setMask( true ); // make sure the depth buffer is writable so it can be properly cleared, see #18897 @@ -108,10 +118,13 @@ renderer.render( scene, virtualCamera ); renderer.xr.enabled = currentXrEnabled; renderer.shadowMap.autoUpdate = currentShadowAutoUpdate; - renderer.setRenderTarget( currentRenderTarget ); // Restore viewport + renderer.outputEncoding = currentOutputEncoding; + renderer.toneMapping = currentToneMapping; + renderer.setRenderTarget( currentRenderTarget ); - const viewport = camera.viewport; + // Restore viewport + const viewport = camera.viewport; if ( viewport !== undefined ) { renderer.state.viewport( viewport ); @@ -138,7 +151,6 @@ } } - Reflector.ReflectorShader = { uniforms: { 'color': { @@ -151,9 +163,7 @@ value: null } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` uniform mat4 textureMatrix; varying vec4 vUv; @@ -169,9 +179,7 @@ #include }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform vec3 color; uniform sampler2D tDiffuse; varying vec4 vUv; @@ -197,6 +205,7 @@ vec4 base = texture2DProj( tDiffuse, vUv ); gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 ); + #include #include }` diff --git a/examples/js/objects/ReflectorForSSRPass.js b/examples/js/objects/ReflectorForSSRPass.js index da4c33bc0f1e44..21af72f5f577b8 100644 --- a/examples/js/objects/ReflectorForSSRPass.js +++ b/examples/js/objects/ReflectorForSSRPass.js @@ -16,7 +16,9 @@ const useDepthTexture = options.useDepthTexture === true; const yAxis = new THREE.Vector3( 0, 1, 0 ); const vecTemp0 = new THREE.Vector3(); - const vecTemp1 = new THREE.Vector3(); // + const vecTemp1 = new THREE.Vector3(); + + // scope.needsUpdate = false; scope.maxDistance = ReflectorForSSRPass.ReflectorShader.uniforms.maxDistance.value; @@ -30,7 +32,6 @@ return scope._distanceAttenuation; }, - set( val ) { if ( scope._distanceAttenuation === val ) return; @@ -39,7 +40,6 @@ scope.material.needsUpdate = true; } - } ); scope._fresnel = ReflectorForSSRPass.ReflectorShader.defines.FRESNEL; Object.defineProperty( scope, 'fresnel', { @@ -48,7 +48,6 @@ return scope._fresnel; }, - set( val ) { if ( scope._fresnel === val ) return; @@ -57,7 +56,6 @@ scope.material.needsUpdate = true; } - } ); const normal = new THREE.Vector3(); const reflectorWorldPosition = new THREE.Vector3(); @@ -69,7 +67,6 @@ const textureMatrix = new THREE.Matrix4(); const virtualCamera = new THREE.PerspectiveCamera(); let depthTexture; - if ( useDepthTexture ) { depthTexture = new THREE.DepthTexture(); @@ -80,7 +77,8 @@ } const parameters = { - depthTexture: useDepthTexture ? depthTexture : null + depthTexture: useDepthTexture ? depthTexture : null, + type: THREE.HalfFloatType }; const renderTarget = new THREE.WebGLRenderTarget( textureWidth, textureHeight, parameters ); const material = new THREE.ShaderMaterial( { @@ -95,7 +93,6 @@ material.uniforms[ 'tDiffuse' ].value = renderTarget.texture; material.uniforms[ 'color' ].value = scope.color; material.uniforms[ 'textureMatrix' ].value = textureMatrix; - if ( useDepthTexture ) { material.uniforms[ 'tDepth' ].value = renderTarget.depthTexture; @@ -105,7 +102,6 @@ this.material = material; const globalPlane = new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), clipBias ); const globalPlanes = [ globalPlane ]; - this.doRender = function ( renderer, scene, camera ) { material.uniforms[ 'maxDistance' ].value = scope.maxDistance; @@ -120,7 +116,9 @@ rotationMatrix.extractRotation( scope.matrixWorld ); normal.set( 0, 0, 1 ); normal.applyMatrix4( rotationMatrix ); - view.subVectors( reflectorWorldPosition, cameraWorldPosition ); // Avoid rendering when reflector is facing away + view.subVectors( reflectorWorldPosition, cameraWorldPosition ); + + // Avoid rendering when reflector is facing away if ( view.dot( normal ) > 0 ) return; view.reflect( normal ).negate(); @@ -146,23 +144,22 @@ material.uniforms[ 'virtualCameraMatrixWorld' ].value = virtualCamera.matrixWorld; material.uniforms[ 'virtualCameraProjectionMatrix' ].value = camera.projectionMatrix; material.uniforms[ 'virtualCameraProjectionMatrixInverse' ].value = camera.projectionMatrixInverse; - material.uniforms[ 'resolution' ].value = scope.resolution; // Update the texture matrix + material.uniforms[ 'resolution' ].value = scope.resolution; + // Update the texture matrix textureMatrix.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 ); textureMatrix.multiply( virtualCamera.projectionMatrix ); textureMatrix.multiply( virtualCamera.matrixWorldInverse ); - textureMatrix.multiply( scope.matrixWorld ); // Render + textureMatrix.multiply( scope.matrixWorld ); - renderTarget.texture.encoding = renderer.outputEncoding; // scope.visible = false; + // scope.visible = false; const currentRenderTarget = renderer.getRenderTarget(); const currentXrEnabled = renderer.xr.enabled; const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate; const currentClippingPlanes = renderer.clippingPlanes; renderer.xr.enabled = false; // Avoid camera modification - renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows - renderer.clippingPlanes = globalPlanes; renderer.setRenderTarget( renderTarget ); renderer.state.buffers.depth.setMask( true ); // make sure the depth buffer is writable so it can be properly cleared, see #18897 @@ -172,15 +169,18 @@ renderer.xr.enabled = currentXrEnabled; renderer.shadowMap.autoUpdate = currentShadowAutoUpdate; renderer.clippingPlanes = currentClippingPlanes; - renderer.setRenderTarget( currentRenderTarget ); // Restore viewport + renderer.setRenderTarget( currentRenderTarget ); - const viewport = camera.viewport; + // Restore viewport + const viewport = camera.viewport; if ( viewport !== undefined ) { renderer.state.viewport( viewport ); - } // scope.visible = true; + } + + // scope.visible = true; }; @@ -193,7 +193,6 @@ } } - ReflectorForSSRPass.ReflectorShader = { defines: { DISTANCE_ATTENUATION: true, @@ -240,9 +239,7 @@ value: new THREE.Vector2() } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` uniform mat4 textureMatrix; varying vec4 vUv; @@ -253,9 +250,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform vec3 color; uniform sampler2D tDiffuse; uniform sampler2D tDepth; diff --git a/examples/js/objects/Refractor.js b/examples/js/objects/Refractor.js index 1396dd7ce6278e..c51ab97837f669 100644 --- a/examples/js/objects/Refractor.js +++ b/examples/js/objects/Refractor.js @@ -14,29 +14,40 @@ const textureHeight = options.textureHeight || 512; const clipBias = options.clipBias || 0; const shader = options.shader || Refractor.RefractorShader; - const multisample = options.multisample !== undefined ? options.multisample : 4; // + const multisample = options.multisample !== undefined ? options.multisample : 4; + + // const virtualCamera = this.camera; virtualCamera.matrixAutoUpdate = false; - virtualCamera.userData.refractor = true; // + virtualCamera.userData.refractor = true; + + // const refractorPlane = new THREE.Plane(); - const textureMatrix = new THREE.Matrix4(); // render target + const textureMatrix = new THREE.Matrix4(); + + // render target const renderTarget = new THREE.WebGLRenderTarget( textureWidth, textureHeight, { - samples: multisample - } ); // material + samples: multisample, + type: THREE.HalfFloatType + } ); + + // material this.material = new THREE.ShaderMaterial( { uniforms: THREE.UniformsUtils.clone( shader.uniforms ), vertexShader: shader.vertexShader, fragmentShader: shader.fragmentShader, transparent: true // ensures, refractors are drawn from farthest to closest - } ); + this.material.uniforms[ 'color' ].value = color; this.material.uniforms[ 'tDiffuse' ].value = renderTarget.texture; - this.material.uniforms[ 'textureMatrix' ].value = textureMatrix; // functions + this.material.uniforms[ 'textureMatrix' ].value = textureMatrix; + + // functions const visible = function () { @@ -58,7 +69,6 @@ }; }(); - const updateRefractorPlane = function () { const normal = new THREE.Vector3(); @@ -68,7 +78,9 @@ return function updateRefractorPlane() { scope.matrixWorld.decompose( position, quaternion, scale ); - normal.set( 0, 0, 1 ).applyQuaternion( quaternion ).normalize(); // flip the normal because we want to cull everything above the plane + normal.set( 0, 0, 1 ).applyQuaternion( quaternion ).normalize(); + + // flip the normal because we want to cull everything above the plane normal.negate(); refractorPlane.setFromNormalAndCoplanarPoint( normal, position ); @@ -76,7 +88,6 @@ }; }(); - const updateVirtualCamera = function () { const clipPlane = new THREE.Plane(); @@ -88,22 +99,29 @@ virtualCamera.matrixWorldInverse.copy( virtualCamera.matrixWorld ).invert(); virtualCamera.projectionMatrix.copy( camera.projectionMatrix ); virtualCamera.far = camera.far; // used in WebGLBackground + // The following code creates an oblique view frustum for clipping. // see: Lengyel, Eric. “Oblique View Frustum Depth Projection and Clipping”. // Journal of Game Development, Vol. 1, No. 2 (2005), Charles River Media, pp. 5–16 clipPlane.copy( refractorPlane ); clipPlane.applyMatrix4( virtualCamera.matrixWorldInverse ); - clipVector.set( clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.constant ); // calculate the clip-space corner point opposite the clipping plane and + clipVector.set( clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.constant ); + + // calculate the clip-space corner point opposite the clipping plane and // transform it into camera space by multiplying it by the inverse of the projection matrix const projectionMatrix = virtualCamera.projectionMatrix; q.x = ( Math.sign( clipVector.x ) + projectionMatrix.elements[ 8 ] ) / projectionMatrix.elements[ 0 ]; q.y = ( Math.sign( clipVector.y ) + projectionMatrix.elements[ 9 ] ) / projectionMatrix.elements[ 5 ]; q.z = - 1.0; - q.w = ( 1.0 + projectionMatrix.elements[ 10 ] ) / projectionMatrix.elements[ 14 ]; // calculate the scaled plane vector + q.w = ( 1.0 + projectionMatrix.elements[ 10 ] ) / projectionMatrix.elements[ 14 ]; + + // calculate the scaled plane vector + + clipVector.multiplyScalar( 2.0 / clipVector.dot( q ) ); - clipVector.multiplyScalar( 2.0 / clipVector.dot( q ) ); // replacing the third row of the projection matrix + // replacing the third row of the projection matrix projectionMatrix.elements[ 2 ] = clipVector.x; projectionMatrix.elements[ 6 ] = clipVector.y; @@ -112,14 +130,18 @@ }; - }(); // This will update the texture matrix that is used for projective texture mapping in the shader. - // see: http://developer.download.nvidia.com/assets/gamedev/docs/projective_texture_mapping.pdf + }(); + // This will update the texture matrix that is used for projective texture mapping in the shader. + // see: http://developer.download.nvidia.com/assets/gamedev/docs/projective_texture_mapping.pdf function updateTextureMatrix( camera ) { // this matrix does range mapping to [ 0, 1 ] - textureMatrix.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 ); // we use "Object Linear Texgen", so we need to multiply the texture matrix T + + textureMatrix.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 ); + + // we use "Object Linear Texgen", so we need to multiply the texture matrix T // (matrix above) with the projection and view matrix of the virtual camera // and the model matrix of the refractor @@ -127,8 +149,9 @@ textureMatrix.multiply( camera.matrixWorldInverse ); textureMatrix.multiply( scope.matrixWorld ); - } // + } + // function render( renderer, scene, camera ) { @@ -136,19 +159,24 @@ const currentRenderTarget = renderer.getRenderTarget(); const currentXrEnabled = renderer.xr.enabled; const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate; + const currentOutputEncoding = renderer.outputEncoding; + const currentToneMapping = renderer.toneMapping; renderer.xr.enabled = false; // avoid camera modification - renderer.shadowMap.autoUpdate = false; // avoid re-computing shadows - + renderer.outputEncoding = THREE.LinearEncoding; + renderer.toneMapping = THREE.NoToneMapping; renderer.setRenderTarget( renderTarget ); if ( renderer.autoClear === false ) renderer.clear(); renderer.render( scene, virtualCamera ); renderer.xr.enabled = currentXrEnabled; renderer.shadowMap.autoUpdate = currentShadowAutoUpdate; - renderer.setRenderTarget( currentRenderTarget ); // restore viewport + renderer.outputEncoding = currentOutputEncoding; + renderer.toneMapping = currentToneMapping; + renderer.setRenderTarget( currentRenderTarget ); - const viewport = camera.viewport; + // restore viewport + const viewport = camera.viewport; if ( viewport !== undefined ) { renderer.state.viewport( viewport ); @@ -157,17 +185,21 @@ scope.visible = true; - } // + } + // this.onBeforeRender = function ( renderer, scene, camera ) { - // Render - renderTarget.texture.encoding = renderer.outputEncoding; // ensure refractors are rendered only once per frame + // ensure refractors are rendered only once per frame - if ( camera.userData.refractor === true ) return; // avoid rendering when the refractor is viewed from behind + if ( camera.userData.refractor === true ) return; - if ( ! visible( camera ) === true ) return; // update + // avoid rendering when the refractor is viewed from behind + + if ( ! visible( camera ) === true ) return; + + // update updateRefractorPlane(); updateTextureMatrix( camera ); @@ -192,7 +224,6 @@ } } - Refractor.RefractorShader = { uniforms: { 'color': { @@ -205,9 +236,7 @@ value: null } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` uniform mat4 textureMatrix; @@ -219,9 +248,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform vec3 color; uniform sampler2D tDiffuse; @@ -245,6 +272,7 @@ vec4 base = texture2DProj( tDiffuse, vUv ); gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 ); + #include #include }` diff --git a/examples/js/objects/ShadowMesh.js b/examples/js/objects/ShadowMesh.js index 0b37300ec0ed18..2df1048877b0ca 100644 --- a/examples/js/objects/ShadowMesh.js +++ b/examples/js/objects/ShadowMesh.js @@ -5,7 +5,6 @@ */ const _shadowMatrix = new THREE.Matrix4(); - class ShadowMesh extends THREE.Mesh { constructor( mesh ) { @@ -27,10 +26,10 @@ this.matrixAutoUpdate = false; } - update( plane, lightPosition4D ) { // based on https://www.opengl.org/archives/resources/features/StencilTalk/tsld021.htm + const dot = plane.normal.x * lightPosition4D.x + plane.normal.y * lightPosition4D.y + plane.normal.z * lightPosition4D.z + - plane.constant * lightPosition4D.w; const sme = _shadowMatrix.elements; sme[ 0 ] = dot - lightPosition4D.x * plane.normal.x; diff --git a/examples/js/objects/Sky.js b/examples/js/objects/Sky.js index 87deee5cbfcbf9..090394376ed476 100644 --- a/examples/js/objects/Sky.js +++ b/examples/js/objects/Sky.js @@ -33,7 +33,6 @@ } } - Sky.SkyShader = { uniforms: { 'turbidity': { @@ -55,9 +54,7 @@ value: new THREE.Vector3( 0, 1, 0 ) } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` uniform vec3 sunPosition; uniform float rayleigh; uniform float turbidity; @@ -128,9 +125,7 @@ vBetaM = totalMie( turbidity ) * mieCoefficient; }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` varying vec3 vWorldPosition; varying vec3 vSunDirection; varying float vSunfade; diff --git a/examples/js/objects/Water.js b/examples/js/objects/Water.js index b4d77bb2de03d5..049173a04b88c8 100644 --- a/examples/js/objects/Water.js +++ b/examples/js/objects/Water.js @@ -26,7 +26,9 @@ const eye = options.eye !== undefined ? options.eye : new THREE.Vector3( 0, 0, 0 ); const distortionScale = options.distortionScale !== undefined ? options.distortionScale : 20.0; const side = options.side !== undefined ? options.side : THREE.FrontSide; - const fog = options.fog !== undefined ? options.fog : false; // + const fog = options.fog !== undefined ? options.fog : false; + + // const mirrorPlane = new THREE.Plane(); const normal = new THREE.Vector3(); @@ -77,9 +79,7 @@ value: new THREE.Color( 0x555555 ) } } ] ), - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` uniform mat4 textureMatrix; uniform float time; @@ -104,9 +104,7 @@ #include #include }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D mirrorSampler; uniform float alpha; uniform float time; @@ -198,7 +196,6 @@ material.uniforms[ 'distortionScale' ].value = distortionScale; material.uniforms[ 'eye' ].value = eye; scope.material = material; - scope.onBeforeRender = function ( renderer, scene, camera ) { mirrorWorldPosition.setFromMatrixPosition( scope.matrixWorld ); @@ -206,7 +203,9 @@ rotationMatrix.extractRotation( scope.matrixWorld ); normal.set( 0, 0, 1 ); normal.applyMatrix4( rotationMatrix ); - view.subVectors( mirrorWorldPosition, cameraWorldPosition ); // Avoid rendering when mirror is facing away + view.subVectors( mirrorWorldPosition, cameraWorldPosition ); + + // Avoid rendering when mirror is facing away if ( view.dot( normal ) > 0 ) return; view.reflect( normal ).negate(); @@ -226,13 +225,15 @@ mirrorCamera.far = camera.far; // Used in WebGLBackground mirrorCamera.updateMatrixWorld(); - mirrorCamera.projectionMatrix.copy( camera.projectionMatrix ); // Update the texture matrix + mirrorCamera.projectionMatrix.copy( camera.projectionMatrix ); + // Update the texture matrix textureMatrix.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 ); textureMatrix.multiply( mirrorCamera.projectionMatrix ); - textureMatrix.multiply( mirrorCamera.matrixWorldInverse ); // Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html - // Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf + textureMatrix.multiply( mirrorCamera.matrixWorldInverse ); + // Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html + // Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf mirrorPlane.setFromNormalAndCoplanarPoint( normal, mirrorWorldPosition ); mirrorPlane.applyMatrix4( mirrorCamera.matrixWorldInverse ); clipPlane.set( mirrorPlane.normal.x, mirrorPlane.normal.y, mirrorPlane.normal.z, mirrorPlane.constant ); @@ -240,22 +241,25 @@ q.x = ( Math.sign( clipPlane.x ) + projectionMatrix.elements[ 8 ] ) / projectionMatrix.elements[ 0 ]; q.y = ( Math.sign( clipPlane.y ) + projectionMatrix.elements[ 9 ] ) / projectionMatrix.elements[ 5 ]; q.z = - 1.0; - q.w = ( 1.0 + projectionMatrix.elements[ 10 ] ) / projectionMatrix.elements[ 14 ]; // Calculate the scaled plane vector + q.w = ( 1.0 + projectionMatrix.elements[ 10 ] ) / projectionMatrix.elements[ 14 ]; - clipPlane.multiplyScalar( 2.0 / clipPlane.dot( q ) ); // Replacing the third row of the projection matrix + // Calculate the scaled plane vector + clipPlane.multiplyScalar( 2.0 / clipPlane.dot( q ) ); + // Replacing the third row of the projection matrix projectionMatrix.elements[ 2 ] = clipPlane.x; projectionMatrix.elements[ 6 ] = clipPlane.y; projectionMatrix.elements[ 10 ] = clipPlane.z + 1.0 - clipBias; projectionMatrix.elements[ 14 ] = clipPlane.w; - eye.setFromMatrixPosition( camera.matrixWorld ); // Render + eye.setFromMatrixPosition( camera.matrixWorld ); + + // Render const currentRenderTarget = renderer.getRenderTarget(); const currentXrEnabled = renderer.xr.enabled; const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate; scope.visible = false; renderer.xr.enabled = false; // Avoid camera modification and recursion - renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows renderer.setRenderTarget( renderTarget ); @@ -266,10 +270,11 @@ scope.visible = true; renderer.xr.enabled = currentXrEnabled; renderer.shadowMap.autoUpdate = currentShadowAutoUpdate; - renderer.setRenderTarget( currentRenderTarget ); // Restore viewport + renderer.setRenderTarget( currentRenderTarget ); - const viewport = camera.viewport; + // Restore viewport + const viewport = camera.viewport; if ( viewport !== undefined ) { renderer.state.viewport( viewport ); diff --git a/examples/js/objects/Water2.js b/examples/js/objects/Water2.js index 4bc405c146ab14..a156496d1c3c6d 100644 --- a/examples/js/objects/Water2.js +++ b/examples/js/objects/Water2.js @@ -29,10 +29,11 @@ const normalMap0 = options.normalMap0 || textureLoader.load( 'textures/water/Water_1_M_Normal.jpg' ); const normalMap1 = options.normalMap1 || textureLoader.load( 'textures/water/Water_2_M_Normal.jpg' ); const cycle = 0.15; // a cycle of a flow map phase - const halfCycle = cycle * 0.5; const textureMatrix = new THREE.Matrix4(); - const clock = new THREE.Clock(); // internal components + const clock = new THREE.Clock(); + + // internal components if ( THREE.Reflector === undefined ) { @@ -59,7 +60,9 @@ clipBias: clipBias } ); reflector.matrixAutoUpdate = false; - refractor.matrixAutoUpdate = false; // material + refractor.matrixAutoUpdate = false; + + // material this.material = new THREE.ShaderMaterial( { uniforms: THREE.UniformsUtils.merge( [ THREE.UniformsLib[ 'fog' ], shader.uniforms ] ), @@ -68,7 +71,6 @@ transparent: true, fog: true } ); - if ( flowMap !== undefined ) { this.material.defines.USE_FLOWMAP = ''; @@ -84,27 +86,30 @@ value: flowDirection }; - } // maps + } + // maps normalMap0.wrapS = normalMap0.wrapT = THREE.RepeatWrapping; normalMap1.wrapS = normalMap1.wrapT = THREE.RepeatWrapping; this.material.uniforms[ 'tReflectionMap' ].value = reflector.getRenderTarget().texture; this.material.uniforms[ 'tRefractionMap' ].value = refractor.getRenderTarget().texture; this.material.uniforms[ 'tNormalMap0' ].value = normalMap0; - this.material.uniforms[ 'tNormalMap1' ].value = normalMap1; // water + this.material.uniforms[ 'tNormalMap1' ].value = normalMap1; + + // water this.material.uniforms[ 'color' ].value = color; this.material.uniforms[ 'reflectivity' ].value = reflectivity; - this.material.uniforms[ 'textureMatrix' ].value = textureMatrix; // inital values + this.material.uniforms[ 'textureMatrix' ].value = textureMatrix; - this.material.uniforms[ 'config' ].value.x = 0; // flowMapOffset0 + // inital values + this.material.uniforms[ 'config' ].value.x = 0; // flowMapOffset0 this.material.uniforms[ 'config' ].value.y = halfCycle; // flowMapOffset1 - this.material.uniforms[ 'config' ].value.z = halfCycle; // halfCycle - this.material.uniforms[ 'config' ].value.w = scale; // scale + // functions function updateTextureMatrix( camera ) { @@ -121,8 +126,8 @@ const delta = clock.getDelta(); const config = scope.material.uniforms[ 'config' ]; config.value.x += flowSpeed * delta; // flowMapOffset0 - config.value.y = config.value.x + halfCycle; // flowMapOffset1 + // Important: The distance between offsets should be always the value of "halfCycle". // Moreover, both offsets should be in the range of [ 0, cycle ]. // This approach ensures a smooth water flow and avoids "reset" effects. @@ -138,8 +143,9 @@ } - } // + } + // this.onBeforeRender = function ( renderer, scene, camera ) { @@ -157,7 +163,6 @@ } } - Water.WaterShader = { uniforms: { 'color': { @@ -193,9 +198,7 @@ value: new THREE.Vector4() } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` #include #include @@ -222,9 +225,7 @@ #include }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` #include #include diff --git a/examples/js/physics/AmmoPhysics.js b/examples/js/physics/AmmoPhysics.js index ce6fbce1f33b8a..9eb8710a1aa34d 100644 --- a/examples/js/physics/AmmoPhysics.js +++ b/examples/js/physics/AmmoPhysics.js @@ -18,11 +18,15 @@ const solver = new AmmoLib.btSequentialImpulseConstraintSolver(); const world = new AmmoLib.btDiscreteDynamicsWorld( dispatcher, broadphase, solver, collisionConfiguration ); world.setGravity( new AmmoLib.btVector3( 0, - 9.8, 0 ) ); - const worldTransform = new AmmoLib.btTransform(); // + const worldTransform = new AmmoLib.btTransform(); + + // function getShape( geometry ) { - const parameters = geometry.parameters; // TODO change type to is* + const parameters = geometry.parameters; + + // TODO change type to is* if ( geometry.type === 'BoxGeometry' ) { @@ -48,11 +52,9 @@ const meshes = []; const meshMap = new WeakMap(); - function addMesh( mesh, mass = 0 ) { const shape = getShape( mesh.geometry ); - if ( shape !== null ) { if ( mesh.isInstancedMesh ) { @@ -81,10 +83,9 @@ const localInertia = new AmmoLib.btVector3( 0, 0, 0 ); shape.calculateLocalInertia( mass, localInertia ); const rbInfo = new AmmoLib.btRigidBodyConstructionInfo( mass, motionState, shape, localInertia ); - const body = new AmmoLib.btRigidBody( rbInfo ); // body.setFriction( 4 ); - + const body = new AmmoLib.btRigidBody( rbInfo ); + // body.setFriction( 4 ); world.addRigidBody( body ); - if ( mass > 0 ) { meshes.push( mesh ); @@ -98,7 +99,6 @@ const array = mesh.instanceMatrix.array; const bodies = []; - for ( let i = 0; i < mesh.count; i ++ ) { const index = i * 16; @@ -121,8 +121,9 @@ } - } // + } + // function setMeshPosition( mesh, position, index = 0 ) { @@ -147,34 +148,35 @@ } - } // + } + // let lastTime = 0; - function step() { const time = performance.now(); - if ( lastTime > 0 ) { - const delta = ( time - lastTime ) / 1000; // console.time( 'world.step' ); + const delta = ( time - lastTime ) / 1000; - world.stepSimulation( delta, 10 ); // console.timeEnd( 'world.step' ); + // console.time( 'world.step' ); + world.stepSimulation( delta, 10 ); + // console.timeEnd( 'world.step' ); } - lastTime = time; // + lastTime = time; + + // for ( let i = 0, l = meshes.length; i < l; i ++ ) { const mesh = meshes[ i ]; - if ( mesh.isInstancedMesh ) { const array = mesh.instanceMatrix.array; const bodies = meshMap.get( mesh ); - for ( let j = 0; j < bodies.length; j ++ ) { const body = bodies[ j ]; @@ -202,14 +204,15 @@ } - } // animate + } + // animate setInterval( step, 1000 / frameRate ); return { addMesh: addMesh, - setMeshPosition: setMeshPosition // addCompoundMesh - + setMeshPosition: setMeshPosition + // addCompoundMesh }; } diff --git a/examples/js/physics/OimoPhysics.js b/examples/js/physics/OimoPhysics.js index ceed653aa68131..510f5a1c855842 100644 --- a/examples/js/physics/OimoPhysics.js +++ b/examples/js/physics/OimoPhysics.js @@ -3,11 +3,15 @@ async function OimoPhysics() { const frameRate = 60; - const world = new OIMO.World( 2, new OIMO.Vec3( 0, - 9.8, 0 ) ); // + const world = new OIMO.World( 2, new OIMO.Vec3( 0, - 9.8, 0 ) ); + + // function getShape( geometry ) { - const parameters = geometry.parameters; // TODO change type to is* + const parameters = geometry.parameters; + + // TODO change type to is* if ( geometry.type === 'BoxGeometry' ) { @@ -29,11 +33,9 @@ const meshes = []; const meshMap = new WeakMap(); - function addMesh( mesh, mass = 0 ) { const shape = getShape( mesh.geometry ); - if ( shape !== null ) { if ( mesh.isInstancedMesh ) { @@ -60,7 +62,6 @@ const body = new OIMO.RigidBody( bodyConfig ); body.addShape( new OIMO.Shape( shapeConfig ) ); world.addRigidBody( body ); - if ( mass > 0 ) { meshes.push( mesh ); @@ -74,7 +75,6 @@ const array = mesh.instanceMatrix.array; const bodies = []; - for ( let i = 0; i < mesh.count; i ++ ) { const index = i * 16; @@ -97,8 +97,9 @@ } - } // + } + // function setMeshPosition( mesh, position, index = 0 ) { @@ -115,33 +116,33 @@ } - } // + } + // let lastTime = 0; - function step() { const time = performance.now(); - if ( lastTime > 0 ) { // console.time( 'world.step' ); - world.step( 1 / frameRate ); // console.timeEnd( 'world.step' ); + world.step( 1 / frameRate ); + // console.timeEnd( 'world.step' ); } - lastTime = time; // + lastTime = time; + + // for ( let i = 0, l = meshes.length; i < l; i ++ ) { const mesh = meshes[ i ]; - if ( mesh.isInstancedMesh ) { const array = mesh.instanceMatrix.array; const bodies = meshMap.get( mesh ); - for ( let j = 0; j < bodies.length; j ++ ) { const body = bodies[ j ]; @@ -161,14 +162,15 @@ } - } // animate + } + // animate setInterval( step, 1000 / frameRate ); return { addMesh: addMesh, - setMeshPosition: setMeshPosition // addCompoundMesh - + setMeshPosition: setMeshPosition + // addCompoundMesh }; } diff --git a/examples/js/postprocessing/AdaptiveToneMappingPass.js b/examples/js/postprocessing/AdaptiveToneMappingPass.js index 74cb5b7b4080eb..34aaa22ae3e8b6 100644 --- a/examples/js/postprocessing/AdaptiveToneMappingPass.js +++ b/examples/js/postprocessing/AdaptiveToneMappingPass.js @@ -108,10 +108,7 @@ this.fsQuad = new THREE.FullScreenQuad( null ); } - - render( renderer, writeBuffer, readBuffer, deltaTime - /*, maskActive*/ - ) { + render( renderer, writeBuffer, readBuffer, deltaTime /*, maskActive*/ ) { if ( this.needsInit ) { @@ -129,16 +126,18 @@ this.fsQuad.material = this.materialLuminance; this.materialLuminance.uniforms.tDiffuse.value = readBuffer.texture; renderer.setRenderTarget( this.currentLuminanceRT ); - this.fsQuad.render( renderer ); //Use the new luminance values, the previous luminance and the frame delta to - //adapt the luminance over time. + this.fsQuad.render( renderer ); + //Use the new luminance values, the previous luminance and the frame delta to + //adapt the luminance over time. this.fsQuad.material = this.materialAdaptiveLum; this.materialAdaptiveLum.uniforms.delta.value = deltaTime; this.materialAdaptiveLum.uniforms.lastLum.value = this.previousLuminanceRT.texture; this.materialAdaptiveLum.uniforms.currentLum.value = this.currentLuminanceRT.texture; renderer.setRenderTarget( this.luminanceRT ); - this.fsQuad.render( renderer ); //Copy the new adapted luminance value so that it can be used by the next frame. + this.fsQuad.render( renderer ); + //Copy the new adapted luminance value so that it can be used by the next frame. this.fsQuad.material = this.materialCopy; this.copyUniforms.tDiffuse.value = this.luminanceRT.texture; renderer.setRenderTarget( this.previousLuminanceRT ); @@ -148,7 +147,6 @@ this.fsQuad.material = this.materialToneMap; this.materialToneMap.uniforms.tDiffuse.value = readBuffer.texture; - if ( this.renderToScreen ) { renderer.setRenderTarget( null ); @@ -163,7 +161,6 @@ } } - reset() { // render targets @@ -190,7 +187,9 @@ this.luminanceRT.texture.generateMipmaps = false; this.previousLuminanceRT = new THREE.WebGLRenderTarget( this.resolution, this.resolution ); this.previousLuminanceRT.texture.name = 'AdaptiveToneMappingPass.pl'; - this.previousLuminanceRT.texture.generateMipmaps = false; // We only need mipmapping for the current luminosity because we want a down-sampled version to sample in our adaptive shader + this.previousLuminanceRT.texture.generateMipmaps = false; + + // We only need mipmapping for the current luminosity because we want a down-sampled version to sample in our adaptive shader const pars = { minFilter: THREE.LinearMipmapLinearFilter, @@ -198,21 +197,21 @@ }; this.currentLuminanceRT = new THREE.WebGLRenderTarget( this.resolution, this.resolution, pars ); this.currentLuminanceRT.texture.name = 'AdaptiveToneMappingPass.cl'; - if ( this.adaptive ) { this.materialToneMap.defines[ 'ADAPTED_LUMINANCE' ] = ''; this.materialToneMap.uniforms.luminanceMap.value = this.luminanceRT.texture; - } //Put something in the adaptive luminance texture so that the scene can render initially - + } + //Put something in the adaptive luminance texture so that the scene can render initially this.fsQuad.material = new THREE.MeshBasicMaterial( { color: 0x777777 } ); this.materialLuminance.needsUpdate = true; this.materialAdaptiveLum.needsUpdate = true; - this.materialToneMap.needsUpdate = true; // renderer.render( this.scene, this.camera, this.luminanceRT ); + this.materialToneMap.needsUpdate = true; + // renderer.render( this.scene, this.camera, this.luminanceRT ); // renderer.render( this.scene, this.camera, this.previousLuminanceRT ); // renderer.render( this.scene, this.camera, this.currentLuminanceRT ); @@ -237,7 +236,6 @@ this.materialToneMap.needsUpdate = true; } - setAdaptionRate( rate ) { if ( rate ) { @@ -247,7 +245,6 @@ } } - setMinLuminance( minLum ) { if ( minLum ) { @@ -258,7 +255,6 @@ } } - setMaxLuminance( maxLum ) { if ( maxLum ) { @@ -268,7 +264,6 @@ } } - setAverageLuminance( avgLum ) { if ( avgLum ) { @@ -278,7 +273,6 @@ } } - setMiddleGrey( middleGrey ) { if ( middleGrey ) { @@ -288,7 +282,6 @@ } } - dispose() { if ( this.luminanceRT ) { diff --git a/examples/js/postprocessing/AfterimagePass.js b/examples/js/postprocessing/AfterimagePass.js index 0ca8934f56da31..dd1ee3f40e4f73 100644 --- a/examples/js/postprocessing/AfterimagePass.js +++ b/examples/js/postprocessing/AfterimagePass.js @@ -15,27 +15,23 @@ this.textureOld = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, { magFilter: THREE.NearestFilter } ); - this.shaderMaterial = new THREE.ShaderMaterial( { + this.compFsMaterial = new THREE.ShaderMaterial( { uniforms: this.uniforms, vertexShader: this.shader.vertexShader, fragmentShader: this.shader.fragmentShader } ); - this.compFsQuad = new THREE.FullScreenQuad( this.shaderMaterial ); - const material = new THREE.MeshBasicMaterial(); - this.copyFsQuad = new THREE.FullScreenQuad( material ); + this.compFsQuad = new THREE.FullScreenQuad( this.compFsMaterial ); + this.copyFsMaterial = new THREE.MeshBasicMaterial(); + this.copyFsQuad = new THREE.FullScreenQuad( this.copyFsMaterial ); } - - render( renderer, writeBuffer, readBuffer - /*, deltaTime, maskActive*/ - ) { + render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive*/ ) { this.uniforms[ 'tOld' ].value = this.textureOld.texture; this.uniforms[ 'tNew' ].value = readBuffer.texture; renderer.setRenderTarget( this.textureComp ); this.compFsQuad.render( renderer ); this.copyFsQuad.material.map = this.textureComp.texture; - if ( this.renderToScreen ) { renderer.setRenderTarget( null ); @@ -47,12 +43,13 @@ if ( this.clear ) renderer.clear(); this.copyFsQuad.render( renderer ); - } // Swap buffers. - + } + // Swap buffers. const temp = this.textureOld; this.textureOld = this.textureComp; - this.textureComp = temp; // Now textureOld contains the latest image, ready for the next frame. + this.textureComp = temp; + // Now textureOld contains the latest image, ready for the next frame. } @@ -62,6 +59,16 @@ this.textureOld.setSize( width, height ); } + dispose() { + + this.textureComp.dispose(); + this.textureOld.dispose(); + this.compFsMaterial.dispose(); + this.copyFsMaterial.dispose(); + this.compFsQuad.dispose(); + this.copyFsQuad.dispose(); + + } } diff --git a/examples/js/postprocessing/BloomPass.js b/examples/js/postprocessing/BloomPass.js index 423ae87d5de8f7..7fd12b73f70f0e 100644 --- a/examples/js/postprocessing/BloomPass.js +++ b/examples/js/postprocessing/BloomPass.js @@ -2,14 +2,18 @@ class BloomPass extends THREE.Pass { - constructor( strength = 1, kernelSize = 25, sigma = 4, resolution = 256 ) { + constructor( strength = 1, kernelSize = 25, sigma = 4 ) { - super(); // render targets + super(); - this.renderTargetX = new THREE.WebGLRenderTarget( resolution, resolution ); + // render targets + + this.renderTargetX = new THREE.WebGLRenderTarget(); // will be resized later this.renderTargetX.texture.name = 'BloomPass.x'; - this.renderTargetY = new THREE.WebGLRenderTarget( resolution, resolution ); - this.renderTargetY.texture.name = 'BloomPass.y'; // combine material + this.renderTargetY = new THREE.WebGLRenderTarget(); // will be resized later + this.renderTargetY.texture.name = 'BloomPass.y'; + + // combine material this.combineUniforms = THREE.UniformsUtils.clone( CombineShader.uniforms ); this.combineUniforms[ 'strength' ].value = strength; @@ -19,7 +23,9 @@ fragmentShader: CombineShader.fragmentShader, blending: THREE.AdditiveBlending, transparent: true - } ); // convolution material + } ); + + // convolution material if ( THREE.ConvolutionShader === undefined ) console.error( 'THREE.BloomPass relies on THREE.ConvolutionShader' ); const convolutionShader = THREE.ConvolutionShader; @@ -39,23 +45,28 @@ this.fsQuad = new THREE.FullScreenQuad( null ); } - render( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) { - if ( maskActive ) renderer.state.buffers.stencil.setTest( false ); // Render quad with blured scene into texture (convolution pass 1) + if ( maskActive ) renderer.state.buffers.stencil.setTest( false ); + + // Render quad with blured scene into texture (convolution pass 1) this.fsQuad.material = this.materialConvolution; this.convolutionUniforms[ 'tDiffuse' ].value = readBuffer.texture; this.convolutionUniforms[ 'uImageIncrement' ].value = BloomPass.blurX; renderer.setRenderTarget( this.renderTargetX ); renderer.clear(); - this.fsQuad.render( renderer ); // Render quad with blured scene into texture (convolution pass 2) + this.fsQuad.render( renderer ); + + // Render quad with blured scene into texture (convolution pass 2) this.convolutionUniforms[ 'tDiffuse' ].value = this.renderTargetX.texture; this.convolutionUniforms[ 'uImageIncrement' ].value = BloomPass.blurY; renderer.setRenderTarget( this.renderTargetY ); renderer.clear(); - this.fsQuad.render( renderer ); // Render original scene with superimposed blur to texture + this.fsQuad.render( renderer ); + + // Render original scene with superimposed blur to texture this.fsQuad.material = this.materialCombine; this.combineUniforms[ 'tDiffuse' ].value = this.renderTargetY.texture; @@ -65,9 +76,23 @@ this.fsQuad.render( renderer ); } + setSize( width, height ) { - } + this.renderTargetX.setSize( width, height ); + this.renderTargetY.setSize( width, height ); + + } + dispose() { + this.renderTargetX.dispose(); + this.renderTargetY.dispose(); + this.materialCombine.dispose(); + this.materialConvolution.dispose(); + this.fsQuad.dispose(); + + } + + } const CombineShader = { uniforms: { 'tDiffuse': { @@ -77,9 +102,7 @@ value: 1.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -89,9 +112,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform float strength; diff --git a/examples/js/postprocessing/BokehPass.js b/examples/js/postprocessing/BokehPass.js index 8df8d509c5e58a..a85cd42c9bf3c5 100644 --- a/examples/js/postprocessing/BokehPass.js +++ b/examples/js/postprocessing/BokehPass.js @@ -14,19 +14,24 @@ const focus = params.focus !== undefined ? params.focus : 1.0; const aspect = params.aspect !== undefined ? params.aspect : camera.aspect; const aperture = params.aperture !== undefined ? params.aperture : 0.025; - const maxblur = params.maxblur !== undefined ? params.maxblur : 1.0; // render targets + const maxblur = params.maxblur !== undefined ? params.maxblur : 1.0; - const width = params.width || window.innerWidth || 1; - const height = params.height || window.innerHeight || 1; - this.renderTargetDepth = new THREE.WebGLRenderTarget( width, height, { + // render targets + + this.renderTargetDepth = new THREE.WebGLRenderTarget( 1, 1, { + // will be resized later minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter } ); - this.renderTargetDepth.texture.name = 'BokehPass.depth'; // depth material + this.renderTargetDepth.texture.name = 'BokehPass.depth'; + + // depth material this.materialDepth = new THREE.MeshDepthMaterial(); this.materialDepth.depthPacking = THREE.RGBADepthPacking; - this.materialDepth.blending = THREE.NoBlending; // bokeh material + this.materialDepth.blending = THREE.NoBlending; + + // bokeh material if ( THREE.BokehShader === undefined ) { @@ -55,12 +60,10 @@ this._oldClearColor = new THREE.Color(); } - - render( renderer, writeBuffer, readBuffer - /*, deltaTime, maskActive*/ - ) { + render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive*/ ) { // Render depth into texture + this.scene.overrideMaterial = this.materialDepth; renderer.getClearColor( this._oldClearColor ); const oldClearAlpha = renderer.getClearAlpha(); @@ -70,12 +73,13 @@ renderer.setClearAlpha( 1.0 ); renderer.setRenderTarget( this.renderTargetDepth ); renderer.clear(); - renderer.render( this.scene, this.camera ); // Render bokeh composite + renderer.render( this.scene, this.camera ); + + // Render bokeh composite this.uniforms[ 'tColor' ].value = readBuffer.texture; this.uniforms[ 'nearClip' ].value = this.camera.near; this.uniforms[ 'farClip' ].value = this.camera.far; - if ( this.renderToScreen ) { renderer.setRenderTarget( null ); @@ -95,6 +99,19 @@ renderer.autoClear = oldAutoClear; } + setSize( width, height ) { + + this.renderTargetDepth.setSize( width, height ); + + } + dispose() { + + this.renderTargetDepth.dispose(); + this.materialDepth.dispose(); + this.materialBokeh.dispose(); + this.fsQuad.dispose(); + + } } diff --git a/examples/js/postprocessing/ClearPass.js b/examples/js/postprocessing/ClearPass.js index 565bd7efec1614..ad1324e9044752 100644 --- a/examples/js/postprocessing/ClearPass.js +++ b/examples/js/postprocessing/ClearPass.js @@ -11,13 +11,9 @@ this._oldClearColor = new THREE.Color(); } - - render( renderer, writeBuffer, readBuffer - /*, deltaTime, maskActive */ - ) { + render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) { let oldClearAlpha; - if ( this.clearColor ) { renderer.getClearColor( this._oldClearColor ); @@ -28,7 +24,6 @@ renderer.setRenderTarget( this.renderToScreen ? null : readBuffer ); renderer.clear(); - if ( this.clearColor ) { renderer.setClearColor( this._oldClearColor, oldClearAlpha ); diff --git a/examples/js/postprocessing/CubeTexturePass.js b/examples/js/postprocessing/CubeTexturePass.js index 7aabbaf94c337e..a3b9e352e747b2 100644 --- a/examples/js/postprocessing/CubeTexturePass.js +++ b/examples/js/postprocessing/CubeTexturePass.js @@ -2,7 +2,7 @@ class CubeTexturePass extends THREE.Pass { - constructor( camera, envMap, opacity = 1 ) { + constructor( camera, tCube, opacity = 1 ) { super(); this.camera = camera; @@ -19,28 +19,25 @@ Object.defineProperty( this.cubeMesh.material, 'envMap', { get: function () { - return this.uniforms.envMap.value; + return this.uniforms.tCube.value; } } ); - this.envMap = envMap; + this.tCube = tCube; this.opacity = opacity; this.cubeScene = new THREE.Scene(); this.cubeCamera = new THREE.PerspectiveCamera(); this.cubeScene.add( this.cubeMesh ); } - - render( renderer, writeBuffer, readBuffer - /*, deltaTime, maskActive*/ - ) { + render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive*/ ) { const oldAutoClear = renderer.autoClear; renderer.autoClear = false; this.cubeCamera.projectionMatrix.copy( this.camera.projectionMatrix ); this.cubeCamera.quaternion.setFromRotationMatrix( this.camera.matrixWorld ); - this.cubeMesh.material.uniforms.envMap.value = this.envMap; - this.cubeMesh.material.uniforms.flipEnvMap.value = this.envMap.isCubeTexture && this.envMap.isRenderTargetTexture === false ? - 1 : 1; + this.cubeMesh.material.uniforms.tCube.value = this.tCube; + this.cubeMesh.material.uniforms.tFlip.value = this.tCube.isCubeTexture && this.tCube.isRenderTargetTexture === false ? - 1 : 1; this.cubeMesh.material.uniforms.opacity.value = this.opacity; this.cubeMesh.material.transparent = this.opacity < 1.0; renderer.setRenderTarget( this.renderToScreen ? null : readBuffer ); @@ -49,6 +46,12 @@ renderer.autoClear = oldAutoClear; } + dispose() { + + this.cubeMesh.geometry.dispose(); + this.cubeMesh.material.dispose(); + + } } diff --git a/examples/js/postprocessing/DotScreenPass.js b/examples/js/postprocessing/DotScreenPass.js index 63f18e58d431be..044749d959bcc3 100644 --- a/examples/js/postprocessing/DotScreenPass.js +++ b/examples/js/postprocessing/DotScreenPass.js @@ -19,14 +19,10 @@ this.fsQuad = new THREE.FullScreenQuad( this.material ); } - - render( renderer, writeBuffer, readBuffer - /*, deltaTime, maskActive */ - ) { + render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) { this.uniforms[ 'tDiffuse' ].value = readBuffer.texture; this.uniforms[ 'tSize' ].value.set( readBuffer.width, readBuffer.height ); - if ( this.renderToScreen ) { renderer.setRenderTarget( null ); @@ -41,6 +37,12 @@ } } + dispose() { + + this.material.dispose(); + this.fsQuad.dispose(); + + } } diff --git a/examples/js/postprocessing/EffectComposer.js b/examples/js/postprocessing/EffectComposer.js index 3e51437839ef70..5dd2bd2e80cfbd 100644 --- a/examples/js/postprocessing/EffectComposer.js +++ b/examples/js/postprocessing/EffectComposer.js @@ -5,7 +5,6 @@ constructor( renderer, renderTarget ) { this.renderer = renderer; - if ( renderTarget === undefined ) { const size = renderer.getSize( new THREE.Vector2() ); @@ -29,7 +28,9 @@ this.writeBuffer = this.renderTarget1; this.readBuffer = this.renderTarget2; this.renderToScreen = true; - this.passes = []; // dependencies + this.passes = []; + + // dependencies if ( THREE.CopyShader === undefined ) { @@ -47,7 +48,6 @@ this.clock = new THREE.Clock(); } - swapBuffers() { const tmp = this.readBuffer; @@ -55,25 +55,21 @@ this.writeBuffer = tmp; } - addPass( pass ) { this.passes.push( pass ); pass.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio ); } - insertPass( pass, index ) { this.passes.splice( index, 0, pass ); pass.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio ); } - removePass( pass ) { const index = this.passes.indexOf( pass ); - if ( index !== - 1 ) { this.passes.splice( index, 1 ); @@ -81,7 +77,6 @@ } } - isLastEnabledPass( passIndex ) { for ( let i = passIndex + 1; i < this.passes.length; i ++ ) { @@ -97,10 +92,10 @@ return true; } - render( deltaTime ) { // deltaTime value is in seconds + if ( deltaTime === undefined ) { deltaTime = this.clock.getDelta(); @@ -109,24 +104,24 @@ const currentRenderTarget = this.renderer.getRenderTarget(); let maskActive = false; - for ( let i = 0, il = this.passes.length; i < il; i ++ ) { const pass = this.passes[ i ]; if ( pass.enabled === false ) continue; pass.renderToScreen = this.renderToScreen && this.isLastEnabledPass( i ); pass.render( this.renderer, this.writeBuffer, this.readBuffer, deltaTime, maskActive ); - if ( pass.needsSwap ) { if ( maskActive ) { const context = this.renderer.getContext(); - const stencil = this.renderer.state.buffers.stencil; //context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff ); + const stencil = this.renderer.state.buffers.stencil; + //context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff ); stencil.setFunc( context.NOTEQUAL, 1, 0xffffffff ); - this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, deltaTime ); //context.stencilFunc( context.EQUAL, 1, 0xffffffff ); + this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, deltaTime ); + //context.stencilFunc( context.EQUAL, 1, 0xffffffff ); stencil.setFunc( context.EQUAL, 1, 0xffffffff ); } @@ -154,7 +149,6 @@ this.renderer.setRenderTarget( currentRenderTarget ); } - reset( renderTarget ) { if ( renderTarget === undefined ) { @@ -176,7 +170,6 @@ this.readBuffer = this.renderTarget2; } - setSize( width, height ) { this._width = width; @@ -185,7 +178,6 @@ const effectiveHeight = this._height * this._pixelRatio; this.renderTarget1.setSize( effectiveWidth, effectiveHeight ); this.renderTarget2.setSize( effectiveWidth, effectiveHeight ); - for ( let i = 0; i < this.passes.length; i ++ ) { this.passes[ i ].setSize( effectiveWidth, effectiveHeight ); @@ -193,51 +185,56 @@ } } - setPixelRatio( pixelRatio ) { this._pixelRatio = pixelRatio; this.setSize( this._width, this._height ); } + dispose() { - } + this.renderTarget1.dispose(); + this.renderTarget2.dispose(); + this.copyPass.dispose(); + + } + } class Pass { constructor() { // if set to true, the pass is processed by the composer - this.enabled = true; // if set to true, the pass indicates to swap read and write buffer after rendering + this.enabled = true; - this.needsSwap = true; // if set to true, the pass clears its buffer before rendering + // if set to true, the pass indicates to swap read and write buffer after rendering + this.needsSwap = true; - this.clear = false; // if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer. + // if set to true, the pass clears its buffer before rendering + this.clear = false; + // if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer. this.renderToScreen = false; } - setSize() {} - render() { console.error( 'THREE.Pass: .render() must be implemented in derived pass.' ); } - } // Helper for passes that need to fill the viewport with a single quad. + } + // Helper for passes that need to fill the viewport with a single quad. - const _camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); // https://github.com/mrdoob/three.js/pull/21358 + const _camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); + // https://github.com/mrdoob/three.js/pull/21358 const _geometry = new THREE.BufferGeometry(); - _geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ - 1, 3, 0, - 1, - 1, 0, 3, - 1, 0 ], 3 ) ); - _geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( [ 0, 2, 0, 0, 2, 0 ], 2 ) ); - class FullScreenQuad { constructor( material ) { @@ -245,25 +242,21 @@ this._mesh = new THREE.Mesh( _geometry, material ); } - dispose() { this._mesh.geometry.dispose(); } - render( renderer ) { renderer.render( this._mesh, _camera ); } - get material() { return this._mesh.material; } - set material( value ) { this._mesh.material = value; diff --git a/examples/js/postprocessing/FilmPass.js b/examples/js/postprocessing/FilmPass.js index ff0f8cb0098418..351bd8c7c3a1cb 100644 --- a/examples/js/postprocessing/FilmPass.js +++ b/examples/js/postprocessing/FilmPass.js @@ -20,14 +20,10 @@ this.fsQuad = new THREE.FullScreenQuad( this.material ); } - - render( renderer, writeBuffer, readBuffer, deltaTime - /*, maskActive */ - ) { + render( renderer, writeBuffer, readBuffer, deltaTime /*, maskActive */ ) { this.uniforms[ 'tDiffuse' ].value = readBuffer.texture; this.uniforms[ 'time' ].value += deltaTime; - if ( this.renderToScreen ) { renderer.setRenderTarget( null ); @@ -42,6 +38,12 @@ } } + dispose() { + + this.material.dispose(); + this.fsQuad.dispose(); + + } } diff --git a/examples/js/postprocessing/GlitchPass.js b/examples/js/postprocessing/GlitchPass.js index 32a62cb197f2b1..efd4ce579e06ba 100644 --- a/examples/js/postprocessing/GlitchPass.js +++ b/examples/js/postprocessing/GlitchPass.js @@ -8,7 +8,8 @@ if ( THREE.DigitalGlitch === undefined ) console.error( 'THREE.GlitchPass relies on THREE.DigitalGlitch' ); const shader = THREE.DigitalGlitch; this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); - this.uniforms[ 'tDisp' ].value = this.generateHeightmap( dt_size ); + this.heightMap = this.generateHeightmap( dt_size ); + this.uniforms[ 'tDisp' ].value = this.heightMap; this.material = new THREE.ShaderMaterial( { uniforms: this.uniforms, vertexShader: shader.vertexShader, @@ -20,17 +21,12 @@ this.generateTrigger(); } - - render( renderer, writeBuffer, readBuffer - /*, deltaTime, maskActive */ - ) { + render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) { if ( renderer.capabilities.isWebGL2 === false ) this.uniforms[ 'tDisp' ].value.format = THREE.LuminanceFormat; this.uniforms[ 'tDiffuse' ].value = readBuffer.texture; this.uniforms[ 'seed' ].value = Math.random(); //default seeding - this.uniforms[ 'byp' ].value = 0; - if ( this.curF % this.randX == 0 || this.goWild == true ) { this.uniforms[ 'amount' ].value = Math.random() / 30; @@ -58,7 +54,6 @@ } this.curF ++; - if ( this.renderToScreen ) { renderer.setRenderTarget( null ); @@ -73,18 +68,15 @@ } } - generateTrigger() { this.randX = THREE.MathUtils.randInt( 120, 240 ); } - generateHeightmap( dt_size ) { const data_arr = new Float32Array( dt_size * dt_size ); const length = dt_size * dt_size; - for ( let i = 0; i < length; i ++ ) { const val = THREE.MathUtils.randFloat( 0, 1 ); @@ -97,6 +89,13 @@ return texture; } + dispose() { + + this.material.dispose(); + this.heightMap.dispose(); + this.fsQuad.dispose(); + + } } diff --git a/examples/js/postprocessing/HalftonePass.js b/examples/js/postprocessing/HalftonePass.js index 63e698ea73e564..464bb9cf4f9c14 100644 --- a/examples/js/postprocessing/HalftonePass.js +++ b/examples/js/postprocessing/HalftonePass.js @@ -9,7 +9,6 @@ constructor( width, height, params ) { super(); - if ( THREE.HalftoneShader === undefined ) { console.error( 'THREE.HalftonePass requires THREE.HalftoneShader' ); @@ -21,11 +20,11 @@ uniforms: this.uniforms, fragmentShader: THREE.HalftoneShader.fragmentShader, vertexShader: THREE.HalftoneShader.vertexShader - } ); // set params + } ); + // set params this.uniforms.width.value = width; this.uniforms.height.value = height; - for ( const key in params ) { if ( params.hasOwnProperty( key ) && this.uniforms.hasOwnProperty( key ) ) { @@ -39,13 +38,9 @@ this.fsQuad = new THREE.FullScreenQuad( this.material ); } - - render( renderer, writeBuffer, readBuffer - /*, deltaTime, maskActive*/ - ) { + render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive*/ ) { this.material.uniforms[ 'tDiffuse' ].value = readBuffer.texture; - if ( this.renderToScreen ) { renderer.setRenderTarget( null ); @@ -60,13 +55,18 @@ } } - setSize( width, height ) { this.uniforms.width.value = width; this.uniforms.height.value = height; } + dispose() { + + this.material.dispose(); + this.fsQuad.dispose(); + + } } diff --git a/examples/js/postprocessing/LUTPass.js b/examples/js/postprocessing/LUTPass.js index 6dffae6371f5db..690cf79bad54a4 100644 --- a/examples/js/postprocessing/LUTPass.js +++ b/examples/js/postprocessing/LUTPass.js @@ -21,9 +21,7 @@ value: 1.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -35,9 +33,7 @@ } `, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform float lutSize; #if USE_3DTEXTURE @@ -110,22 +106,18 @@ ` }; - class LUTPass extends THREE.ShaderPass { set lut( v ) { const material = this.material; - if ( v !== this.lut ) { material.uniforms.lut3d.value = null; material.uniforms.lut.value = null; - if ( v ) { const is3dTextureDefine = v.isData3DTexture ? 1 : 0; - if ( is3dTextureDefine !== material.defines.USE_3DTEXTURE ) { material.defines.USE_3DTEXTURE = is3dTextureDefine; @@ -134,7 +126,6 @@ } material.uniforms.lutSize.value = v.image.width; - if ( v.isData3DTexture ) { material.uniforms.lut3d.value = v; @@ -150,25 +141,21 @@ } } - get lut() { return this.material.uniforms.lut.value || this.material.uniforms.lut3d.value; } - set intensity( v ) { this.material.uniforms.intensity.value = v; } - get intensity() { return this.material.uniforms.intensity.value; } - constructor( options = {} ) { super( LUTShader ); diff --git a/examples/js/postprocessing/MaskPass.js b/examples/js/postprocessing/MaskPass.js index 830ed521c31533..dffd4bf2c7d0f5 100644 --- a/examples/js/postprocessing/MaskPass.js +++ b/examples/js/postprocessing/MaskPass.js @@ -12,22 +12,24 @@ this.inverse = false; } - - render( renderer, writeBuffer, readBuffer - /*, deltaTime, maskActive */ - ) { + render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) { const context = renderer.getContext(); - const state = renderer.state; // don't update color or depth + const state = renderer.state; + + // don't update color or depth state.buffers.color.setMask( false ); - state.buffers.depth.setMask( false ); // lock buffers + state.buffers.depth.setMask( false ); + + // lock buffers state.buffers.color.setLocked( true ); - state.buffers.depth.setLocked( true ); // set up stencil + state.buffers.depth.setLocked( true ); - let writeValue, clearValue; + // set up stencil + let writeValue, clearValue; if ( this.inverse ) { writeValue = 0; @@ -44,28 +46,32 @@ state.buffers.stencil.setOp( context.REPLACE, context.REPLACE, context.REPLACE ); state.buffers.stencil.setFunc( context.ALWAYS, writeValue, 0xffffffff ); state.buffers.stencil.setClear( clearValue ); - state.buffers.stencil.setLocked( true ); // draw into the stencil buffer + state.buffers.stencil.setLocked( true ); + + // draw into the stencil buffer renderer.setRenderTarget( readBuffer ); if ( this.clear ) renderer.clear(); renderer.render( this.scene, this.camera ); renderer.setRenderTarget( writeBuffer ); if ( this.clear ) renderer.clear(); - renderer.render( this.scene, this.camera ); // unlock color and depth buffer for subsequent rendering + renderer.render( this.scene, this.camera ); + + // unlock color and depth buffer for subsequent rendering state.buffers.color.setLocked( false ); - state.buffers.depth.setLocked( false ); // only render where stencil is set to 1 + state.buffers.depth.setLocked( false ); + + // only render where stencil is set to 1 state.buffers.stencil.setLocked( false ); state.buffers.stencil.setFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1 - state.buffers.stencil.setOp( context.KEEP, context.KEEP, context.KEEP ); state.buffers.stencil.setLocked( true ); } } - class ClearMaskPass extends THREE.Pass { constructor() { @@ -74,10 +80,7 @@ this.needsSwap = false; } - - render( renderer - /*, writeBuffer, readBuffer, deltaTime, maskActive */ - ) { + render( renderer /*, writeBuffer, readBuffer, deltaTime, maskActive */ ) { renderer.state.buffers.stencil.setLocked( false ); renderer.state.buffers.stencil.setTest( false ); diff --git a/examples/js/postprocessing/OutlinePass.js b/examples/js/postprocessing/OutlinePass.js index 7f8fe97077c0f0..fad9ce21bc04a0 100644 --- a/examples/js/postprocessing/OutlinePass.js +++ b/examples/js/postprocessing/OutlinePass.js @@ -56,10 +56,12 @@ this.separableBlurMaterial1.uniforms[ 'kernelRadius' ].value = 1; this.separableBlurMaterial2 = this.getSeperableBlurMaterial( MAX_EDGE_GLOW ); this.separableBlurMaterial2.uniforms[ 'texSize' ].value.set( Math.round( resx / 2 ), Math.round( resy / 2 ) ); - this.separableBlurMaterial2.uniforms[ 'kernelRadius' ].value = MAX_EDGE_GLOW; // Overlay material + this.separableBlurMaterial2.uniforms[ 'kernelRadius' ].value = MAX_EDGE_GLOW; - this.overlayMaterial = this.getOverlayMaterial(); // copy material + // Overlay material + this.overlayMaterial = this.getOverlayMaterial(); + // copy material if ( THREE.CopyShader === undefined ) console.error( 'THREE.OutlinePass relies on THREE.CopyShader' ); const copyShader = THREE.CopyShader; this.copyUniforms = THREE.UniformsUtils.clone( copyShader.uniforms ); @@ -81,7 +83,6 @@ this.tempPulseColor1 = new THREE.Color(); this.tempPulseColor2 = new THREE.Color(); this.textureMatrix = new THREE.Matrix4(); - function replaceDepthToViewZ( string, camera ) { const type = camera.isPerspectiveCamera ? 'perspective' : 'orthographic'; @@ -90,7 +91,6 @@ } } - dispose() { this.renderTargetMaskBuffer.dispose(); @@ -100,9 +100,16 @@ this.renderTargetBlurBuffer2.dispose(); this.renderTargetEdgeBuffer1.dispose(); this.renderTargetEdgeBuffer2.dispose(); + this.depthMaterial.dispose(); + this.prepareMaskMaterial.dispose(); + this.edgeDetectionMaterial.dispose(); + this.separableBlurMaterial1.dispose(); + this.separableBlurMaterial2.dispose(); + this.overlayMaterial.dispose(); + this.materialCopy.dispose(); + this.fsQuad.dispose(); } - setSize( width, height ) { this.renderTargetMaskBuffer.setSize( width, height ); @@ -120,11 +127,9 @@ this.separableBlurMaterial2.uniforms[ 'texSize' ].value.set( resx, resy ); } - changeVisibilityOfSelectedObjects( bVisible ) { const cache = this._visibilityCache; - function gatherSelectedMeshesCallBack( object ) { if ( object.isMesh ) { @@ -152,12 +157,10 @@ } } - changeVisibilityOfNonSelectedObjects( bVisible ) { const cache = this._visibilityCache; const selectedMeshes = []; - function gatherSelectedMeshesCallBack( object ) { if ( object.isMesh ) selectedMeshes.push( object ); @@ -176,12 +179,11 @@ if ( object.isMesh || object.isSprite ) { // only meshes and sprites are supported by OutlinePass - let bFound = false; + let bFound = false; for ( let i = 0; i < selectedMeshes.length; i ++ ) { const selectedObjectId = selectedMeshes[ i ].id; - if ( selectedObjectId === object.id ) { bFound = true; @@ -194,7 +196,6 @@ if ( bFound === false ) { const visibility = object.visible; - if ( bVisible === false || cache.get( object ) === true ) { object.visible = bVisible; @@ -209,6 +210,7 @@ // the visibilty of points and lines is always set to false in order to // not affect the outline computation + if ( bVisible === true ) { object.visible = cache.get( object ); // restore @@ -227,7 +229,6 @@ this.renderScene.traverse( VisibilityChangeCallBack ); } - updateTextureMatrix() { this.textureMatrix.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 ); @@ -235,7 +236,6 @@ this.textureMatrix.multiply( this.renderCamera.matrixWorldInverse ); } - render( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) { if ( this.selectedObjects.length > 0 ) { @@ -245,24 +245,27 @@ const oldAutoClear = renderer.autoClear; renderer.autoClear = false; if ( maskActive ) renderer.state.buffers.stencil.setTest( false ); - renderer.setClearColor( 0xffffff, 1 ); // Make selected objects invisible + renderer.setClearColor( 0xffffff, 1 ); + // Make selected objects invisible this.changeVisibilityOfSelectedObjects( false ); const currentBackground = this.renderScene.background; - this.renderScene.background = null; // 1. Draw Non Selected objects in the depth buffer + this.renderScene.background = null; + // 1. Draw Non Selected objects in the depth buffer this.renderScene.overrideMaterial = this.depthMaterial; renderer.setRenderTarget( this.renderTargetDepthBuffer ); renderer.clear(); - renderer.render( this.renderScene, this.renderCamera ); // Make selected objects visible + renderer.render( this.renderScene, this.renderCamera ); + // Make selected objects visible this.changeVisibilityOfSelectedObjects( true ); + this._visibilityCache.clear(); - this._visibilityCache.clear(); // Update Texture Matrix for Depth compare - - - this.updateTextureMatrix(); // Make non selected objects invisible, and draw only the selected objects, by comparing the depth buffer of non selected objects + // Update Texture Matrix for Depth compare + this.updateTextureMatrix(); + // Make non selected objects invisible, and draw only the selected objects, by comparing the depth buffer of non selected objects this.changeVisibilityOfNonSelectedObjects( false ); this.renderScene.overrideMaterial = this.prepareMaskMaterial; this.prepareMaskMaterial.uniforms[ 'cameraNearFar' ].value.set( this.renderCamera.near, this.renderCamera.far ); @@ -273,11 +276,10 @@ renderer.render( this.renderScene, this.renderCamera ); this.renderScene.overrideMaterial = null; this.changeVisibilityOfNonSelectedObjects( true ); - this._visibilityCache.clear(); + this.renderScene.background = currentBackground; - this.renderScene.background = currentBackground; // 2. Downsample to Half resolution - + // 2. Downsample to Half resolution this.fsQuad.material = this.materialCopy; this.copyUniforms[ 'tDiffuse' ].value = this.renderTargetMaskBuffer.texture; renderer.setRenderTarget( this.renderTargetMaskDownSampleBuffer ); @@ -285,16 +287,15 @@ this.fsQuad.render( renderer ); this.tempPulseColor1.copy( this.visibleEdgeColor ); this.tempPulseColor2.copy( this.hiddenEdgeColor ); - if ( this.pulsePeriod > 0 ) { const scalar = ( 1 + 0.25 ) / 2 + Math.cos( performance.now() * 0.01 / this.pulsePeriod ) * ( 1.0 - 0.25 ) / 2; this.tempPulseColor1.multiplyScalar( scalar ); this.tempPulseColor2.multiplyScalar( scalar ); - } // 3. Apply Edge Detection THREE.Pass - + } + // 3. Apply Edge Detection THREE.Pass this.fsQuad.material = this.edgeDetectionMaterial; this.edgeDetectionMaterial.uniforms[ 'maskTexture' ].value = this.renderTargetMaskDownSampleBuffer.texture; this.edgeDetectionMaterial.uniforms[ 'texSize' ].value.set( this.renderTargetMaskDownSampleBuffer.width, this.renderTargetMaskDownSampleBuffer.height ); @@ -302,8 +303,9 @@ this.edgeDetectionMaterial.uniforms[ 'hiddenEdgeColor' ].value = this.tempPulseColor2; renderer.setRenderTarget( this.renderTargetEdgeBuffer1 ); renderer.clear(); - this.fsQuad.render( renderer ); // 4. Apply Blur on Half res + this.fsQuad.render( renderer ); + // 4. Apply Blur on Half res this.fsQuad.material = this.separableBlurMaterial1; this.separableBlurMaterial1.uniforms[ 'colorTexture' ].value = this.renderTargetEdgeBuffer1.texture; this.separableBlurMaterial1.uniforms[ 'direction' ].value = OutlinePass.BlurDirectionX; @@ -315,8 +317,9 @@ this.separableBlurMaterial1.uniforms[ 'direction' ].value = OutlinePass.BlurDirectionY; renderer.setRenderTarget( this.renderTargetEdgeBuffer1 ); renderer.clear(); - this.fsQuad.render( renderer ); // Apply Blur on quarter res + this.fsQuad.render( renderer ); + // Apply Blur on quarter res this.fsQuad.material = this.separableBlurMaterial2; this.separableBlurMaterial2.uniforms[ 'colorTexture' ].value = this.renderTargetEdgeBuffer1.texture; this.separableBlurMaterial2.uniforms[ 'direction' ].value = OutlinePass.BlurDirectionX; @@ -327,8 +330,9 @@ this.separableBlurMaterial2.uniforms[ 'direction' ].value = OutlinePass.BlurDirectionY; renderer.setRenderTarget( this.renderTargetEdgeBuffer2 ); renderer.clear(); - this.fsQuad.render( renderer ); // Blend it additively over the input texture + this.fsQuad.render( renderer ); + // Blend it additively over the input texture this.fsQuad.material = this.overlayMaterial; this.overlayMaterial.uniforms[ 'maskTexture' ].value = this.renderTargetMaskBuffer.texture; this.overlayMaterial.uniforms[ 'edgeTexture1' ].value = this.renderTargetEdgeBuffer1.texture; @@ -355,7 +359,6 @@ } } - getPrepareMaskMaterial() { return new THREE.ShaderMaterial( { @@ -386,7 +389,17 @@ #include vPosition = mvPosition; - vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 ); + + vec4 worldPosition = vec4( transformed, 1.0 ); + + #ifdef USE_INSTANCING + + worldPosition = instanceMatrix * worldPosition; + + #endif + + worldPosition = modelMatrix * worldPosition; + projTexCoord = textureMatrix * worldPosition; }`, @@ -407,7 +420,6 @@ } ); } - getEdgeDetectionMaterial() { return new THREE.ShaderMaterial( { @@ -457,7 +469,6 @@ } ); } - getSeperableBlurMaterial( maxRadius ) { return new THREE.ShaderMaterial( { @@ -516,7 +527,6 @@ } ); } - getOverlayMaterial() { return new THREE.ShaderMaterial( { @@ -580,7 +590,6 @@ } } - OutlinePass.BlurDirectionX = new THREE.Vector2( 1.0, 0.0 ); OutlinePass.BlurDirectionY = new THREE.Vector2( 0.0, 1.0 ); diff --git a/examples/js/postprocessing/Pass.js b/examples/js/postprocessing/Pass.js index fbedff59ebd69a..5d27f33f7f1beb 100644 --- a/examples/js/postprocessing/Pass.js +++ b/examples/js/postprocessing/Pass.js @@ -5,36 +5,37 @@ constructor() { // if set to true, the pass is processed by the composer - this.enabled = true; // if set to true, the pass indicates to swap read and write buffer after rendering + this.enabled = true; - this.needsSwap = true; // if set to true, the pass clears its buffer before rendering + // if set to true, the pass indicates to swap read and write buffer after rendering + this.needsSwap = true; - this.clear = false; // if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer. + // if set to true, the pass clears its buffer before rendering + this.clear = false; + // if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer. this.renderToScreen = false; } - setSize() {} - render() { console.error( 'THREE.Pass: .render() must be implemented in derived pass.' ); } + dispose() {} - } // Helper for passes that need to fill the viewport with a single quad. + } + // Helper for passes that need to fill the viewport with a single quad. - const _camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); // https://github.com/mrdoob/three.js/pull/21358 + const _camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); + // https://github.com/mrdoob/three.js/pull/21358 const _geometry = new THREE.BufferGeometry(); - _geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ - 1, 3, 0, - 1, - 1, 0, 3, - 1, 0 ], 3 ) ); - _geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( [ 0, 2, 0, 0, 2, 0 ], 2 ) ); - class FullScreenQuad { constructor( material ) { @@ -42,25 +43,21 @@ this._mesh = new THREE.Mesh( _geometry, material ); } - dispose() { this._mesh.geometry.dispose(); } - render( renderer ) { renderer.render( this._mesh, _camera ); } - get material() { return this._mesh.material; } - set material( value ) { this._mesh.material = value; diff --git a/examples/js/postprocessing/RenderPass.js b/examples/js/postprocessing/RenderPass.js index b212e77958e3ee..04936417a7cde6 100644 --- a/examples/js/postprocessing/RenderPass.js +++ b/examples/js/postprocessing/RenderPass.js @@ -16,15 +16,11 @@ this._oldClearColor = new THREE.Color(); } - - render( renderer, writeBuffer, readBuffer - /*, deltaTime, maskActive */ - ) { + render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) { const oldAutoClear = renderer.autoClear; renderer.autoClear = false; let oldClearAlpha, oldOverrideMaterial; - if ( this.overrideMaterial !== undefined ) { oldOverrideMaterial = this.scene.overrideMaterial; @@ -46,11 +42,11 @@ } - renderer.setRenderTarget( this.renderToScreen ? null : readBuffer ); // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600 + renderer.setRenderTarget( this.renderToScreen ? null : readBuffer ); + // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600 if ( this.clear ) renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil ); renderer.render( this.scene, this.camera ); - if ( this.clearColor ) { renderer.setClearColor( this._oldClearColor, oldClearAlpha ); diff --git a/examples/js/postprocessing/RenderPixelatedPass.js b/examples/js/postprocessing/RenderPixelatedPass.js new file mode 100644 index 00000000000000..36876e7e5d037b --- /dev/null +++ b/examples/js/postprocessing/RenderPixelatedPass.js @@ -0,0 +1,215 @@ +( function () { + + class RenderPixelatedPass extends THREE.Pass { + + constructor( pixelSize, scene, camera, options = {} ) { + + super(); + this.pixelSize = pixelSize; + this.resolution = new THREE.Vector2(); + this.renderResolution = new THREE.Vector2(); + this.pixelatedMaterial = this.createPixelatedMaterial(); + this.normalMaterial = new THREE.MeshNormalMaterial(); + this.fsQuad = new THREE.FullScreenQuad( this.pixelatedMaterial ); + this.scene = scene; + this.camera = camera; + this.normalEdgeStrength = options.normalEdgeStrength || 0.3; + this.depthEdgeStrength = options.depthEdgeStrength || 0.4; + this.beautyRenderTarget = new THREE.WebGLRenderTarget(); + this.beautyRenderTarget.texture.minFilter = THREE.NearestFilter; + this.beautyRenderTarget.texture.magFilter = THREE.NearestFilter; + this.beautyRenderTarget.depthTexture = new THREE.DepthTexture(); + this.normalRenderTarget = new THREE.WebGLRenderTarget(); + this.normalRenderTarget.texture.minFilter = THREE.NearestFilter; + this.normalRenderTarget.texture.magFilter = THREE.NearestFilter; + + } + dispose() { + + this.beautyRenderTarget.dispose(); + this.normalRenderTarget.dispose(); + this.pixelatedMaterial.dispose(); + this.normalMaterial.dispose(); + this.fsQuad.dispose(); + + } + setSize( width, height ) { + + this.resolution.set( width, height ); + this.renderResolution.set( width / this.pixelSize | 0, height / this.pixelSize | 0 ); + const { + x, + y + } = this.renderResolution; + this.beautyRenderTarget.setSize( x, y ); + this.normalRenderTarget.setSize( x, y ); + this.fsQuad.material.uniforms.resolution.value.set( x, y, 1 / x, 1 / y ); + + } + setPixelSize( pixelSize ) { + + this.pixelSize = pixelSize; + this.setSize( this.resolution.x, this.resolution.y ); + + } + render( renderer, writeBuffer ) { + + const uniforms = this.fsQuad.material.uniforms; + uniforms.normalEdgeStrength.value = this.normalEdgeStrength; + uniforms.depthEdgeStrength.value = this.depthEdgeStrength; + renderer.setRenderTarget( this.beautyRenderTarget ); + renderer.render( this.scene, this.camera ); + const overrideMaterial_old = this.scene.overrideMaterial; + renderer.setRenderTarget( this.normalRenderTarget ); + this.scene.overrideMaterial = this.normalMaterial; + renderer.render( this.scene, this.camera ); + this.scene.overrideMaterial = overrideMaterial_old; + uniforms.tDiffuse.value = this.beautyRenderTarget.texture; + uniforms.tDepth.value = this.beautyRenderTarget.depthTexture; + uniforms.tNormal.value = this.normalRenderTarget.texture; + if ( this.renderToScreen ) { + + renderer.setRenderTarget( null ); + + } else { + + renderer.setRenderTarget( writeBuffer ); + if ( this.clear ) renderer.clear(); + + } + + this.fsQuad.render( renderer ); + + } + createPixelatedMaterial() { + + return new THREE.ShaderMaterial( { + uniforms: { + tDiffuse: { + value: null + }, + tDepth: { + value: null + }, + tNormal: { + value: null + }, + resolution: { + value: new THREE.Vector4( this.renderResolution.x, this.renderResolution.y, 1 / this.renderResolution.x, 1 / this.renderResolution.y ) + }, + normalEdgeStrength: { + value: 0 + }, + depthEdgeStrength: { + value: 0 + } + }, + vertexShader: /* glsl */` + varying vec2 vUv; + + void main() { + + vUv = uv; + gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); + + } + `, + fragmentShader: /* glsl */` + uniform sampler2D tDiffuse; + uniform sampler2D tDepth; + uniform sampler2D tNormal; + uniform vec4 resolution; + uniform float normalEdgeStrength; + uniform float depthEdgeStrength; + varying vec2 vUv; + + float getDepth(int x, int y) { + + return texture2D( tDepth, vUv + vec2(x, y) * resolution.zw ).r; + + } + + vec3 getNormal(int x, int y) { + + return texture2D( tNormal, vUv + vec2(x, y) * resolution.zw ).rgb * 2.0 - 1.0; + + } + + float depthEdgeIndicator(float depth, vec3 normal) { + + float diff = 0.0; + diff += clamp(getDepth(1, 0) - depth, 0.0, 1.0); + diff += clamp(getDepth(-1, 0) - depth, 0.0, 1.0); + diff += clamp(getDepth(0, 1) - depth, 0.0, 1.0); + diff += clamp(getDepth(0, -1) - depth, 0.0, 1.0); + return floor(smoothstep(0.01, 0.02, diff) * 2.) / 2.; + + } + + float neighborNormalEdgeIndicator(int x, int y, float depth, vec3 normal) { + + float depthDiff = getDepth(x, y) - depth; + vec3 neighborNormal = getNormal(x, y); + + // Edge pixels should yield to faces who's normals are closer to the bias normal. + vec3 normalEdgeBias = vec3(1., 1., 1.); // This should probably be a parameter. + float normalDiff = dot(normal - neighborNormal, normalEdgeBias); + float normalIndicator = clamp(smoothstep(-.01, .01, normalDiff), 0.0, 1.0); + + // Only the shallower pixel should detect the normal edge. + float depthIndicator = clamp(sign(depthDiff * .25 + .0025), 0.0, 1.0); + + return (1.0 - dot(normal, neighborNormal)) * depthIndicator * normalIndicator; + + } + + float normalEdgeIndicator(float depth, vec3 normal) { + + float indicator = 0.0; + + indicator += neighborNormalEdgeIndicator(0, -1, depth, normal); + indicator += neighborNormalEdgeIndicator(0, 1, depth, normal); + indicator += neighborNormalEdgeIndicator(-1, 0, depth, normal); + indicator += neighborNormalEdgeIndicator(1, 0, depth, normal); + + return step(0.1, indicator); + + } + + void main() { + + vec4 texel = texture2D( tDiffuse, vUv ); + + float depth = 0.0; + vec3 normal = vec3(0.0); + + if (depthEdgeStrength > 0.0 || normalEdgeStrength > 0.0) { + + depth = getDepth(0, 0); + normal = getNormal(0, 0); + + } + + float dei = 0.0; + if (depthEdgeStrength > 0.0) + dei = depthEdgeIndicator(depth, normal); + + float nei = 0.0; + if (normalEdgeStrength > 0.0) + nei = normalEdgeIndicator(depth, normal); + + float Strength = dei > 0.0 ? (1.0 - depthEdgeStrength * dei) : (1.0 + normalEdgeStrength * nei); + + gl_FragColor = texel * Strength; + + } + ` + } ); + + } + + } + + THREE.RenderPixelatedPass = RenderPixelatedPass; + +} )(); diff --git a/examples/js/postprocessing/SAOPass.js b/examples/js/postprocessing/SAOPass.js index a6ce3c47c312fd..1922d9c76e640c 100644 --- a/examples/js/postprocessing/SAOPass.js +++ b/examples/js/postprocessing/SAOPass.js @@ -40,7 +40,6 @@ } ); this.depthRenderTarget = this.normalRenderTarget.clone(); let depthTexture; - if ( this.supportsDepthTextureExtension ) { depthTexture = new THREE.DepthTexture(); @@ -55,7 +54,6 @@ this.depthMaterial.blending = THREE.NoBlending; this.normalMaterial = new THREE.MeshNormalMaterial(); this.normalMaterial.blending = THREE.NoBlending; - if ( THREE.SAOShader === undefined ) { console.error( 'THREE.SAOPass relies on THREE.SAOShader' ); @@ -78,7 +76,6 @@ this.saoMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse ); this.saoMaterial.uniforms[ 'cameraProjectionMatrix' ].value = this.camera.projectionMatrix; this.saoMaterial.blending = THREE.NoBlending; - if ( THREE.DepthLimitedBlurShader === undefined ) { console.error( 'THREE.SAOPass relies on THREE.DepthLimitedBlurShader' ); @@ -109,7 +106,6 @@ this.hBlurMaterial.uniforms[ 'tDepth' ].value = this.supportsDepthTextureExtension ? depthTexture : this.depthRenderTarget.texture; this.hBlurMaterial.uniforms[ 'size' ].value.set( this.resolution.x, this.resolution.y ); this.hBlurMaterial.blending = THREE.NoBlending; - if ( THREE.CopyShader === undefined ) { console.error( 'THREE.SAOPass relies on THREE.CopyShader' ); @@ -132,7 +128,6 @@ this.materialCopy.blendSrcAlpha = THREE.DstAlphaFactor; this.materialCopy.blendDstAlpha = THREE.ZeroFactor; this.materialCopy.blendEquationAlpha = THREE.AddEquation; - if ( THREE.UnpackDepthRGBAShader === undefined ) { console.error( 'THREE.SAOPass relies on THREE.UnpackDepthRGBAShader' ); @@ -148,10 +143,7 @@ this.fsQuad = new THREE.FullScreenQuad( null ); } - - render( renderer, writeBuffer, readBuffer - /*, deltaTime, maskActive*/ - ) { + render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive*/ ) { // Rendering readBuffer first when rendering to screen if ( this.renderToScreen ) { @@ -181,7 +173,8 @@ this.saoMaterial.uniforms[ 'kernelRadius' ].value = this.params.saoKernelRadius; this.saoMaterial.uniforms[ 'minResolution' ].value = this.params.saoMinResolution; this.saoMaterial.uniforms[ 'cameraNear' ].value = this.camera.near; - this.saoMaterial.uniforms[ 'cameraFar' ].value = this.camera.far; // this.saoMaterial.uniforms['randomSeed'].value = Math.random(); + this.saoMaterial.uniforms[ 'cameraFar' ].value = this.camera.far; + // this.saoMaterial.uniforms['randomSeed'].value = Math.random(); const depthCutoff = this.params.saoBlurDepthCutoff * ( this.camera.far - this.camera.near ); this.vBlurMaterial.uniforms[ 'depthCutoff' ].value = depthCutoff; @@ -191,7 +184,6 @@ this.hBlurMaterial.uniforms[ 'cameraNear' ].value = this.camera.near; this.hBlurMaterial.uniforms[ 'cameraFar' ].value = this.camera.far; this.params.saoBlurRadius = Math.floor( this.params.saoBlurRadius ); - if ( this.prevStdDev !== this.params.saoBlurStdDev || this.prevNumSamples !== this.params.saoBlurRadius ) { THREE.BlurShaderUtils.configure( this.vBlurMaterial, this.params.saoBlurRadius, this.params.saoBlurStdDev, new THREE.Vector2( 0, 1 ) ); @@ -199,14 +191,15 @@ this.prevStdDev = this.params.saoBlurStdDev; this.prevNumSamples = this.params.saoBlurRadius; - } // Rendering scene to depth texture - + } + // Rendering scene to depth texture renderer.setClearColor( 0x000000 ); renderer.setRenderTarget( this.beautyRenderTarget ); renderer.clear(); - renderer.render( this.scene, this.camera ); // Re-render scene if depth texture extension is not supported + renderer.render( this.scene, this.camera ); + // Re-render scene if depth texture extension is not supported if ( ! this.supportsDepthTextureExtension ) { // Clear rule : far clipping plane in both RGBA and Basic encoding @@ -219,11 +212,12 @@ // Clear rule : default normal is facing the camera this.renderOverride( renderer, this.normalMaterial, this.normalRenderTarget, 0x7777ff, 1.0 ); - } // Rendering SAO texture - + } - this.renderPass( renderer, this.saoMaterial, this.saoRenderTarget, 0xffffff, 1.0 ); // Blurring SAO texture + // Rendering SAO texture + this.renderPass( renderer, this.saoMaterial, this.saoRenderTarget, 0xffffff, 1.0 ); + // Blurring SAO texture if ( this.params.saoBlur ) { this.renderPass( renderer, this.vBlurMaterial, this.blurIntermediateRenderTarget, 0xffffff, 1.0 ); @@ -231,8 +225,8 @@ } - let outputMaterial = this.materialCopy; // Setting up SAO rendering - + let outputMaterial = this.materialCopy; + // Setting up SAO rendering if ( this.params.output === 3 ) { if ( this.supportsDepthTextureExtension ) { @@ -258,9 +252,9 @@ this.materialCopy.uniforms[ 'tDiffuse' ].value = this.saoRenderTarget.texture; this.materialCopy.needsUpdate = true; - } // Blending depends on output, only want a THREE.CustomBlending when showing SAO - + } + // Blending depends on output, only want a THREE.CustomBlending when showing SAO if ( this.params.output === 0 ) { outputMaterial.blending = THREE.CustomBlending; @@ -269,25 +263,24 @@ outputMaterial.blending = THREE.NoBlending; - } // Rendering SAOPass result on top of previous pass - + } + // Rendering SAOPass result on top of previous pass this.renderPass( renderer, outputMaterial, this.renderToScreen ? null : readBuffer ); renderer.setClearColor( this._oldClearColor, this.oldClearAlpha ); renderer.autoClear = oldAutoClear; } - renderPass( renderer, passMaterial, renderTarget, clearColor, clearAlpha ) { // save original state renderer.getClearColor( this.originalClearColor ); const originalClearAlpha = renderer.getClearAlpha(); const originalAutoClear = renderer.autoClear; - renderer.setRenderTarget( renderTarget ); // setup pass state + renderer.setRenderTarget( renderTarget ); + // setup pass state renderer.autoClear = false; - if ( clearColor !== undefined && clearColor !== null ) { renderer.setClearColor( clearColor ); @@ -297,14 +290,14 @@ } this.fsQuad.material = passMaterial; - this.fsQuad.render( renderer ); // restore original state + this.fsQuad.render( renderer ); + // restore original state renderer.autoClear = originalAutoClear; renderer.setClearColor( this.originalClearColor ); renderer.setClearAlpha( originalClearAlpha ); } - renderOverride( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) { renderer.getClearColor( this.originalClearColor ); @@ -314,7 +307,6 @@ renderer.autoClear = false; clearColor = overrideMaterial.clearColor || clearColor; clearAlpha = overrideMaterial.clearAlpha || clearAlpha; - if ( clearColor !== undefined && clearColor !== null ) { renderer.setClearColor( clearColor ); @@ -325,14 +317,14 @@ this.scene.overrideMaterial = overrideMaterial; renderer.render( this.scene, this.camera ); - this.scene.overrideMaterial = null; // restore original state + this.scene.overrideMaterial = null; + // restore original state renderer.autoClear = originalAutoClear; renderer.setClearColor( this.originalClearColor ); renderer.setClearAlpha( originalClearAlpha ); } - setSize( width, height ) { this.beautyRenderTarget.setSize( width, height ); @@ -350,9 +342,25 @@ this.hBlurMaterial.needsUpdate = true; } + dispose() { + + this.saoRenderTarget.dispose(); + this.blurIntermediateRenderTarget.dispose(); + this.beautyRenderTarget.dispose(); + this.normalRenderTarget.dispose(); + this.depthRenderTarget.dispose(); + this.depthMaterial.dispose(); + this.normalMaterial.dispose(); + this.saoMaterial.dispose(); + this.vBlurMaterial.dispose(); + this.hBlurMaterial.dispose(); + this.materialCopy.dispose(); + this.depthCopy.dispose(); + this.fsQuad.dispose(); - } + } + } SAOPass.OUTPUT = { 'Beauty': 1, 'Default': 0, diff --git a/examples/js/postprocessing/SMAAPass.js b/examples/js/postprocessing/SMAAPass.js index d4cd7118583166..97d49f3916d1f4 100644 --- a/examples/js/postprocessing/SMAAPass.js +++ b/examples/js/postprocessing/SMAAPass.js @@ -4,7 +4,9 @@ constructor( width, height ) { - super(); // render targets + super(); + + // render targets this.edgesRT = new THREE.WebGLRenderTarget( width, height, { depthBuffer: false @@ -13,12 +15,12 @@ this.weightsRT = new THREE.WebGLRenderTarget( width, height, { depthBuffer: false } ); - this.weightsRT.texture.name = 'SMAAPass.weights'; // textures + this.weightsRT.texture.name = 'SMAAPass.weights'; + // textures const scope = this; const areaTextureImage = new Image(); areaTextureImage.src = this.getAreaTexture(); - areaTextureImage.onload = function () { // assigning data to HTMLImageElement.src is asynchronous (see #15162) @@ -34,7 +36,6 @@ this.areaTexture.flipY = false; const searchTextureImage = new Image(); searchTextureImage.src = this.getSearchTexture(); - searchTextureImage.onload = function () { // assigning data to HTMLImageElement.src is asynchronous (see #15162) @@ -48,7 +49,9 @@ this.searchTexture.magFilter = THREE.NearestFilter; this.searchTexture.minFilter = THREE.NearestFilter; this.searchTexture.generateMipmaps = false; - this.searchTexture.flipY = false; // materials - pass 1 + this.searchTexture.flipY = false; + + // materials - pass 1 if ( THREE.SMAAEdgesShader === undefined ) { @@ -63,7 +66,9 @@ uniforms: this.uniformsEdges, vertexShader: THREE.SMAAEdgesShader.vertexShader, fragmentShader: THREE.SMAAEdgesShader.fragmentShader - } ); // materials - pass 2 + } ); + + // materials - pass 2 this.uniformsWeights = THREE.UniformsUtils.clone( THREE.SMAAWeightsShader.uniforms ); this.uniformsWeights[ 'resolution' ].value.set( 1 / width, 1 / height ); @@ -75,7 +80,9 @@ uniforms: this.uniformsWeights, vertexShader: THREE.SMAAWeightsShader.vertexShader, fragmentShader: THREE.SMAAWeightsShader.fragmentShader - } ); // materials - pass 3 + } ); + + // materials - pass 3 this.uniformsBlend = THREE.UniformsUtils.clone( THREE.SMAABlendShader.uniforms ); this.uniformsBlend[ 'resolution' ].value.set( 1 / width, 1 / height ); @@ -89,26 +96,27 @@ this.fsQuad = new THREE.FullScreenQuad( null ); } - - render( renderer, writeBuffer, readBuffer - /*, deltaTime, maskActive*/ - ) { + render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive*/ ) { // pass 1 + this.uniformsEdges[ 'tDiffuse' ].value = readBuffer.texture; this.fsQuad.material = this.materialEdges; renderer.setRenderTarget( this.edgesRT ); if ( this.clear ) renderer.clear(); - this.fsQuad.render( renderer ); // pass 2 + this.fsQuad.render( renderer ); + + // pass 2 this.fsQuad.material = this.materialWeights; renderer.setRenderTarget( this.weightsRT ); if ( this.clear ) renderer.clear(); - this.fsQuad.render( renderer ); // pass 3 + this.fsQuad.render( renderer ); + + // pass 3 this.uniformsBlend[ 'tColor' ].value = readBuffer.texture; this.fsQuad.material = this.materialBlend; - if ( this.renderToScreen ) { renderer.setRenderTarget( null ); @@ -123,7 +131,6 @@ } } - setSize( width, height ) { this.edgesRT.setSize( width, height ); @@ -133,18 +140,28 @@ this.materialBlend.uniforms[ 'resolution' ].value.set( 1 / width, 1 / height ); } - getAreaTexture() { return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAAIwCAIAAACOVPcQAACBeklEQVR42u39W4xlWXrnh/3WWvuciIzMrKxrV8/0rWbY0+SQFKcb4owIkSIFCjY9AC1BT/LYBozRi+EX+cV+8IMsYAaCwRcBwjzMiw2jAWtgwC8WR5Q8mDFHZLNHTarZGrLJJllt1W2qKrsumZWZcTvn7L3W54e1vrXX3vuciLPPORFR1XE2EomorB0nVuz//r71re/y/1eMvb4Cb3N11xV/PP/2v4UBAwJG/7H8urx6/25/Gf8O5hypMQ0EEEQwAqLfoN/Z+97f/SW+/NvcgQk4sGBJK6H7N4PFVL+K+e0N11yNfkKvwUdwdlUAXPHHL38oa15f/i/46Ih6SuMSPmLAYAwyRKn7dfMGH97jaMFBYCJUgotIC2YAdu+LyW9vvubxAP8kAL8H/koAuOKP3+q6+xGnd5kdYCeECnGIJViwGJMAkQKfDvB3WZxjLKGh8VSCCzhwEWBpMc5/kBbjawT4HnwJfhr+pPBIu7uu+OOTo9vsmtQcniMBGkKFd4jDWMSCRUpLjJYNJkM+IRzQ+PQvIeAMTrBS2LEiaiR9b/5PuT6Ap/AcfAFO4Y3dA3DFH7/VS+M8k4baEAQfMI4QfbVDDGIRg7GKaIY52qAjTAgTvGBAPGIIghOCYAUrGFNgzA7Q3QhgCwfwAnwe5vDejgG44o/fbm1C5ZlYQvQDARPAIQGxCWBM+wWl37ZQESb4gImexGMDouhGLx1Cst0Saa4b4AqO4Hk4gxo+3DHAV/nx27p3JziPM2pVgoiia5MdEzCGULprIN7gEEeQ5IQxEBBBQnxhsDb5auGmAAYcHMA9eAAz8PBol8/xij9+C4Djlim4gJjWcwZBhCBgMIIYxGAVIkH3ZtcBuLdtRFMWsPGoY9rN+HoBji9VBYdwD2ZQg4cnO7OSq/z4rU5KKdwVbFAjNojCQzTlCLPFSxtamwh2jMUcEgg2Wm/6XgErIBhBckQtGN3CzbVacERgCnfgLswhnvqf7QyAq/z4rRZm1YglYE3affGITaZsdIe2FmMIpnOCap25I6jt2kCwCW0D1uAD9sZctNGXcQIHCkINDQgc78aCr+zjtw3BU/ijdpw3zhCwcaONwBvdeS2YZKkJNJsMPf2JKEvC28RXxxI0ASJyzQCjCEQrO4Q7sFArEzjZhaFc4cdv+/JFdKULM4px0DfUBI2hIsy06BqLhGTQEVdbfAIZXYMPesq6VoCHICzUyjwInO4Y411//LYLs6TDa9wvg2CC2rElgAnpTBziThxaL22MYhzfkghz6GAs2VHbbdM91VZu1MEEpupMMwKyVTb5ij9+u4VJG/5EgEMMmFF01cFai3isRbKbzb+YaU/MQbAm2XSMoUPAmvZzbuKYRIFApbtlrfFuUGd6vq2hXNnH78ZLh/iFhsQG3T4D1ib7k5CC6vY0DCbtrohgLEIClXiGtl10zc0CnEGIhhatLBva7NP58Tvw0qE8yWhARLQ8h4+AhQSP+I4F5xoU+VilGRJs6wnS7ruti/4KvAY/CfdgqjsMy4pf8fodQO8/gnuX3f/3xi3om1/h7THr+co3x93PP9+FBUfbNUjcjEmhcrkT+8K7ml7V10Jo05mpIEFy1NmCJWx9SIKKt+EjAL4Ez8EBVOB6havuT/rByPvHXK+9zUcfcbb254+9fydJknYnRr1oGfdaiAgpxu1Rx/Rek8KISftx3L+DfsLWAANn8Hvw0/AFeAGO9DFV3c6D+CcWbL8Dj9e7f+T1k8AZv/d7+PXWM/Z+VvdCrIvuAKO09RpEEQJM0Ci6+B4xhTWr4cZNOvhktabw0ta0rSJmqz3Yw5/AKXwenod7cAhTmBSPKf6JBdvH8IP17h95pXqw50/+BFnj88fev4NchyaK47OPhhtI8RFSvAfDSNh0Ck0p2gLxGkib5NJj/JWCr90EWQJvwBzO4AHcgztwAFN1evHPUVGwfXON+0debT1YeGON9Yy9/63X+OguiwmhIhQhD7l4sMqlG3D86Suc3qWZ4rWjI1X7u0Ytw6x3rIMeIOPDprfe2XzNgyj6PahhBjO4C3e6puDgXrdg+/5l948vF3bqwZetZ+z9Rx9zdIY5pInPK4Nk0t+l52xdK2B45Qd87nM8fsD5EfUhIcJcERw4RdqqH7Yde5V7m1vhNmtedkz6EDzUMF/2jJYWbC+4fzzA/Y+/8PPH3j9dcBAPIRP8JLXd5BpAu03aziOL3VVHZzz3CXWDPWd+SH2AnxIqQoTZpo9Ckc6HIrFbAbzNmlcg8Ag8NFDDAhbJvTBZXbC94P7t68EXfv6o+21gUtPETU7bbkLxvNKRFG2+KXzvtObonPP4rBvsgmaKj404DlshFole1Glfh02fE7bYR7dZ82oTewIBGn1Md6CG6YUF26X376oevOLzx95vhUmgblI6LBZwTCDY7vMq0op5WVXgsObOXJ+1x3qaBl9j1FeLxbhU9w1F+Wiba6s1X/TBz1LnUfuYDi4r2C69f1f14BWfP+p+W2GFKuC9phcELMYRRLur9DEZTUdEH+iEqWdaM7X4WOoPGI+ZYD2+wcQ+y+ioHUZ9dTDbArzxmi/bJI9BND0Ynd6lBdve/butBw8+f/T9D3ABa3AG8W3VPX4hBin+bj8dMMmSpp5pg7fJ6xrBFE2WQQEWnV8Qg3FbAWzYfM1rREEnmvkN2o1+acG2d/9u68GDzx91v3mAjb1zkpqT21OipPKO0b9TO5W0nTdOmAQm0TObts3aBKgwARtoPDiCT0gHgwnbArzxmtcLc08HgF1asN0C4Ms/fvD5I+7PhfqyXE/b7RbbrGyRQRT9ARZcwAUmgdoz0ehJ9Fn7QAhUjhDAQSw0bV3T3WbNa59jzmiP6GsWbGXDX2ytjy8+f9T97fiBPq9YeLdBmyuizZHaqXITnXiMUEEVcJ7K4j3BFPurtB4bixW8wTpweL8DC95szWMOqucFYGsWbGU7p3TxxxefP+r+oTVktxY0v5hbq3KiOKYnY8ddJVSBxuMMVffNbxwIOERShst73HZ78DZrHpmJmH3K6sGz0fe3UUj0eyRrSCGTTc+rjVNoGzNSv05srAxUBh8IhqChiQgVNIIBH3AVPnrsnXQZbLTm8ammv8eVXn/vWpaTem5IXRlt+U/LA21zhSb9cye6jcOfCnOwhIAYXAMVTUNV0QhVha9xjgA27ODJbLbmitt3tRN80lqG6N/khgot4ZVlOyO4WNg3OIMzhIZQpUEHieg2im6F91hB3I2tubql6BYNN9Hj5S7G0G2tahslBWKDnOiIvuAEDzakDQKDNFQT6gbn8E2y4BBubM230YIpBnDbMa+y3dx0n1S0BtuG62lCCXwcY0F72T1VRR3t2ONcsmDjbmzNt9RFs2LO2hQNyb022JisaI8rAWuw4HI3FuAIhZdOGIcdjLJvvObqlpqvWTJnnQbyi/1M9O8UxWhBs//H42I0q1Yb/XPGONzcmm+ri172mHKvZBpHkJaNJz6v9jxqiklDj3U4CA2ugpAaYMWqNXsdXbmJNd9egCnJEsphXNM+MnK3m0FCJ5S1kmJpa3DgPVbnQnPGWIDspW9ozbcO4K/9LkfaQO2KHuqlfFXSbdNzcEcwoqNEFE9zcIXu9/6n/ym/BC/C3aJLzEKPuYVlbFnfhZ8kcWxV3dbv4bKl28566wD+8C53aw49lTABp9PWbsB+knfc/Li3eVizf5vv/xmvnPKg5ihwKEwlrcHqucuVcVOxEv8aH37E3ZqpZypUulrHEtIWKUr+txHg+ojZDGlwnqmkGlzcVi1dLiNSJiHjfbRNOPwKpx9TVdTn3K05DBx4psIk4Ei8aCkJahRgffk4YnEXe07T4H2RR1u27E6wfQsBDofUgjFUFnwC2AiVtA+05J2zpiDK2Oa0c5fmAecN1iJzmpqFZxqYBCYhFTCsUNEmUnIcZ6aEA5rQVhEywG6w7HSW02XfOoBlQmjwulOFQAg66SvJblrTEX1YtJ3uG15T/BH1OfOQeuR8g/c0gdpT5fx2SKbs9EfHTKdM8A1GaJRHLVIwhcGyydZsbifAFVKl5EMKNU2Hryo+06BeTgqnxzYjThVySDikbtJPieco75lYfKAJOMEZBTjoITuWHXXZVhcUDIS2hpiXHV9Ku4u44bN5OYLDOkJo8w+xJSMbhBRHEdEs9JZUCkQrPMAvaHyLkxgkEHxiNkx/x2YB0mGsQ8EUWj/stW5YLhtS5SMu+/YBbNPDCkGTUybN8krRLBGPlZkVOA0j+a1+rkyQKWGaPHPLZOkJhioQYnVZ2hS3zVxMtgC46KuRwbJNd9nV2PHgb36F194ecf/Yeu2vAFe5nm/bRBFrnY4BauE8ERmZRFUn0k8hbftiVYSKMEme2dJCJSCGYAlNqh87bXOPdUkGy24P6d1ll21MBqqx48Fvv8ZHH8HZFY7j/uAq1xMJUFqCSUlJPmNbIiNsmwuMs/q9CMtsZsFO6SprzCS1Z7QL8xCQClEelpjTduDMsmWD8S1PT152BtvmIGvUeDA/yRn83u/x0/4qxoPHjx+PXY9pqX9bgMvh/Nz9kpP4pOe1/fYf3axUiMdHLlPpZCNjgtNFAhcHEDxTumNONhHrBduW+vOyY++70WWnPXj98eA4kOt/mj/5E05l9+O4o8ePx67HFqyC+qSSnyselqjZGaVK2TadbFLPWAQ4NBhHqDCCV7OTpo34AlSSylPtIdd2AJZlyzYQrDJ5lcWGNceD80CunPLGGzsfD+7wRb95NevJI5docQ3tgCyr5bGnyaPRlmwNsFELViOOx9loebGNq2moDOKpHLVP5al2cymWHbkfzGXL7kfRl44H9wZy33tvt+PB/Xnf93e+nh5ZlU18wCiRUa9m7kib9LYuOk+hudQNbxwm0AQqbfloimaB2lM5fChex+ylMwuTbfmXQtmWlenZljbdXTLuOxjI/fDDHY4Hjx8/Hrse0zXfPFxbUN1kKqSCCSk50m0Ajtx3ub9XHBKHXESb8iO6E+qGytF4nO0OG3SXzbJlhxBnKtKyl0NwybjvYCD30aMdjgePHz8eu56SVTBbgxJMliQ3Oauwg0QHxXE2Ez/EIReLdQj42Gzb4CLS0YJD9xUx7bsi0vJi5mUbW1QzL0h0PFk17rtiIPfJk52MB48fPx67npJJwyrBa2RCCQRTbGZSPCxTPOiND4G2pYyOQ4h4jINIJh5wFU1NFZt+IsZ59LSnDqBjZ2awbOku+yInunLcd8VA7rNnOxkPHj9+PGY9B0MWJJNozOJmlglvDMXDEozdhQWbgs/U6oBanGzLrdSNNnZFjOkmbi5bNt1lX7JLLhn3vXAg9/h4y/Hg8ePHI9dzQMEkWCgdRfYykYKnkP7D4rIujsujaKPBsB54vE2TS00ccvFY/Tth7JXeq1hz+qgVy04sAJawTsvOknHfCwdyT062HA8eP348Zj0vdoXF4pilKa2BROed+9fyw9rWRXeTFXESMOanvDZfJuJaSXouQdMdDJZtekZcLLvEeK04d8m474UDuaenW44Hjx8/Xns9YYqZpszGWB3AN/4VHw+k7WSFtJ3Qicuqb/NlVmgXWsxh570xg2UwxUw3WfO6B5nOuO8aA7lnZxuPB48fPx6znm1i4bsfcbaptF3zNT78eFPtwi1OaCNOqp1x3zUGcs/PN++AGD1+fMXrSVm2baTtPhPahbPhA71wIHd2bXzRa69nG+3CraTtPivahV/55tXWg8fyRY/9AdsY8VbSdp8V7cKrrgdfM//z6ILQFtJ2nxHtwmuoB4/kf74+gLeRtvvMaBdeSz34+vifx0YG20jbfTa0C6+tHrwe//NmOG0L8EbSdp8R7cLrrQe/996O+ai3ujQOskpTNULa7jOjXXj99eCd8lHvoFiwsbTdZ0a78PrrwTvlo966pLuRtB2fFe3Cm6oHP9kNH/W2FryxtN1nTLvwRurBO+Kj3pWXHidtx2dFu/Bm68Fb81HvykuPlrb7LGkX3mw9eGs+6h1Y8MbSdjegXcguQLjmevDpTQLMxtJ2N6NdyBZu9AbrwVvwUW+LbteULUpCdqm0HTelXbhNPe8G68Gb8lFvVfYfSNuxvrTdTWoXbozAzdaDZzfkorOj1oxVxlIMlpSIlpLrt8D4hrQL17z+c3h6hU/wv4Q/utps4+bm+6P/hIcf0JwQ5oQGPBL0eKPTYEXTW+eL/2DKn73J9BTXYANG57hz1cEMviVf/4tf5b/6C5pTQkMIWoAq7hTpOJjtAM4pxKu5vg5vXeUrtI09/Mo/5H+4z+Mp5xULh7cEm2QbRP2tFIKR7WM3fPf/jZ3SWCqLM2l4NxID5zB72HQXv3jj/8mLR5xXNA5v8EbFQEz7PpRfl1+MB/hlAN65qgDn3wTgH13hK7T59bmP+NIx1SHHU84nLOITt3iVz8mNO+lPrjGAnBFqmioNn1mTyk1ta47R6d4MrX7tjrnjYUpdUbv2rVr6YpVfsGG58AG8Ah9eyUN8CX4WfgV+G8LVWPDGb+Zd4cU584CtqSbMKxauxTg+dyn/LkVgA+IR8KHtejeFKRtTmLLpxN6mYVLjYxwXf5x2VofiZcp/lwKk4wGOpYDnoIZPdg/AAbwMfx0+ge9dgZvYjuqKe4HnGnykYo5TvJbG0Vj12JagRhwKa44H95ShkZa5RyLGGdfYvG7aw1TsF6iapPAS29mNS3NmsTQZCmgTzFwgL3upCTgtBTRwvGMAKrgLn4evwin8+afJRcff+8izUGUM63GOOuAs3tJkw7J4kyoNreqrpO6cYLQeFUd7TTpr5YOTLc9RUUogUOVJQ1GYJaFLAW0oTmKyYS46ZooP4S4EON3xQ5zC8/CX4CnM4c1PE8ApexpoYuzqlP3d4S3OJP8ZDK7cKWNaTlqmgDiiHwl1YsE41w1zT4iRTm3DBqxvOUsbMKKDa/EHxagtnta072ejc3DOIh5ojvh8l3tk1JF/AV6FU6jh3U8HwEazLgdCLYSQ+MYiAI2ltomkzttUb0gGHdSUUgsIYjTzLG3mObX4FBRaYtpDVNZrih9TgTeYOBxsEnN1gOCTM8Bsw/ieMc75w9kuAT6A+/AiHGvN/+Gn4KRkiuzpNNDYhDGFndWRpE6SVfm8U5bxnSgVV2jrg6JCKmneqey8VMFgq2+AM/i4L4RUbfSi27lNXZ7R7W9RTcq/q9fk4Xw3AMQd4I5ifAZz8FcVtm9SAom/dyN4lczJQW/kC42ZrHgcCoIf1oVMKkVItmMBi9cOeNHGLqOZk+QqQmrbc5YmYgxELUUN35z2iohstgfLIFmcMV7s4CFmI74L9+EFmGsi+tGnAOD4Yk9gIpo01Y4cA43BWGygMdr4YZekG3OBIUXXNukvJS8tqa06e+lSDCtnqqMFu6hWHXCF+WaYt64m9QBmNxi7Ioy7D+fa1yHw+FMAcPt7SysFLtoG4PXAk7JOA3aAxBRqUiAdU9Yp5lK3HLSRFtOim0sa8euEt08xvKjYjzeJ2GU7YawexrnKI9tmobInjFXCewpwriY9+RR4aaezFhMhGCppKwom0ChrgFlKzyPKkGlTW1YQrE9HJqu8hKGgMc6hVi5QRq0PZxNfrYNgE64utmRv6KKHRpxf6VDUaOvNP5jCEx5q185My/7RKz69UQu2im5k4/eownpxZxNLwiZ1AZTO2ZjWjkU9uaB2HFn6Q3u0JcsSx/qV9hTEApRzeBLDJQXxYmTnq7bdLa3+uqFrxLJ5w1TehnNHx5ECvCh2g2c3hHH5YsfdaSKddztfjQ6imKFGSyFwlLzxEGPp6r5IevVjk1AMx3wMqi1NxDVjLBiPs9tbsCkIY5we5/ML22zrCScFxnNtzsr9Wcc3CnD+pYO+4VXXiDE0oc/vQQ/fDK3oPESJMYXNmJa/DuloJZkcTpcYE8lIH8Dz8DJMiynNC86Mb2lNaaqP/+L7f2fcE/yP7/Lde8xfgSOdMxvOixZf/9p3+M4hT1+F+zApxg9XfUvYjc8qX2lfOOpK2gNRtB4flpFu9FTKCp2XJRgXnX6olp1zyYjTKJSkGmLE2NjUr1bxFM4AeAAHBUFIeSLqXR+NvH/M9fOnfHzOD2vCSyQJKzfgsCh+yi/Mmc35F2fUrw7miW33W9hBD1vpuUojFphIyvg7aTeoymDkIkeW3XLHmguMzbIAJejN6B5MDrhipE2y6SoFRO/AK/AcHHZHNIfiWrEe/C6cr3f/yOvrQKB+zMM55/GQdLDsR+ifr5Fiuu+/y+M78LzOE5dsNuXC3PYvYWd8NXvphLSkJIasrlD2/HOqQ+RjcRdjKTGWYhhVUm4yxlyiGPuMsZR7sMCHUBeTuNWA7if+ifXgc/hovftHXs/DV+Fvwe+f8shzMiMcweFgBly3//vwJfg5AN4450fn1Hd1Rm1aBLu22Dy3y3H2+OqMemkbGZ4jozcDjJf6596xOLpC0eMTHbKnxLxH27uZ/bMTGs2jOaMOY4m87CfQwF0dw53oa1k80JRuz/XgS+8fX3N9Af4qPIMfzKgCp4H5TDGe9GGeFPzSsZz80SlPTxXjgwJmC45njzgt2vbQ4b4OAdUK4/vWhO8d8v6EE8fMUsfakXbPpFJeLs2ubM/qdm/la3WP91uWhxXHjoWhyRUq2iJ/+5mA73zwIIo+LoZ/SgvIRjAd1IMvvn98PfgOvAJfhhm8scAKVWDuaRaK8aQ9f7vuPDH6Bj47ZXau7rqYJ66mTDwEDU6lLbCjCK0qTXyl5mnDoeNRxanj3FJbaksTk0faXxHxLrssgPkWB9LnA/MFleXcJozzjwsUvUG0X/QCve51qkMDXp9mtcyOy3rwBfdvVJK7D6/ACSzg3RoruIq5UDeESfEmVclDxnniU82vxMLtceD0hGZWzBNPMM/jSPne2OVatiTKUpY5vY7gc0LdUAWeWM5tH+O2I66AOWw9xT2BuyRVLGdoDHUsVRXOo/c+ZdRXvFfnxWyIV4upFLCl9eAL7h8Zv0QH8Ry8pA2cHzQpGesctVA37ZtklBTgHjyvdSeKY/RZw/kJMk0Y25cSNRWSigQtlULPTw+kzuJPeYEkXjQRpoGZobYsLF79pyd1dMRHInbgFTZqNLhDqiIsTNpoex2WLcy0/X6rHcdMMQvFSd5dWA++4P7xv89deACnmr36uGlL69bRCL6BSZsS6c0TU2TKK5gtWCzgAOOwQcurqk9j8whvziZSMLcq5hbuwBEsYjopUBkqw1yYBGpLA97SRElEmx5MCInBY5vgLk94iKqSWmhIGmkJ4Bi9m4L645J68LyY4wsFYBfUg5feP/6gWWm58IEmKQM89hq7KsZNaKtP5TxxrUZZVkNmMJtjbKrGxLNEbHPJxhqy7lAmbC32ZqeF6lTaknRWcYaFpfLUBh/rwaQycCCJmW15Kstv6jRHyJFry2C1ahkkIW0LO75s61+owxK1y3XqweX9m5YLM2DPFeOjn/iiqCKJ+yKXF8t5Yl/kNsqaSCryxPq5xWTFIaP8KSW0RYxqupaUf0RcTNSSdJZGcKYdYA6kdtrtmyBckfKXwqk0pHpUHlwWaffjNRBYFPUDWa8e3Lt/o0R0CdisKDM89cX0pvRHEfM8ca4t0s2Xx4kgo91MPQJ/0c9MQYq0co8MBh7bz1fio0UUHLR4aAIOvOmoYO6kwlEVODSSTliWtOtH6sPkrtctF9ZtJ9GIerBskvhdVS5cFNv9s1BU0AbdUgdK4FG+dRnjFmDTzniRMdZO1QhzMK355vigbdkpz9P6qjUGE5J2qAcXmwJ20cZUiAD0z+pGMx6xkzJkmEf40Hr4qZfVg2XzF9YOyoV5BjzVkUJngKf8lgNYwKECEHrCNDrWZzMlflS3yBhr/InyoUgBc/lKT4pxVrrC6g1YwcceK3BmNxZcAtz3j5EIpqguh9H6wc011YN75cKDLpFDxuwkrPQmUwW4KTbj9mZTwBwLq4aQMUZbHm1rylJ46dzR0dua2n3RYCWZsiHROeywyJGR7mXKlpryyCiouY56sFkBWEnkEB/raeh/Sw4162KeuAxMQpEkzy5alMY5wamMsWKKrtW2WpEWNnReZWONKWjrdsKZarpFjqCslq773PLmEhM448Pc3+FKr1+94vv/rfw4tEcu+lKTBe4kZSdijBrykwv9vbCMPcLQTygBjzVckSLPRVGslqdunwJ4oegtFOYb4SwxNgWLCmD7T9kVjTv5YDgpo0XBmN34Z/rEHp0sgyz7lngsrm4lvMm2Mr1zNOJYJ5cuxuQxwMGJq/TP5emlb8fsQBZviK4t8hFL+zbhtlpwaRSxQRWfeETjuauPsdGxsBVdO7nmP4xvzSoT29pRl7kGqz+k26B3Oy0YNV+SXbbQas1ctC/GarskRdFpKczVAF1ZXnLcpaMuzVe6lZ2g/1ndcvOVgRG3sdUAY1bKD6achijMPdMxV4muKVorSpiDHituH7rSTs7n/4y5DhRXo4FVBN4vO/zbAcxhENzGbHCzU/98Mcx5e7a31kWjw9FCe/zNeYyQjZsWb1uc7U33pN4Mji6hCLhivqfa9Ss6xLg031AgfesA/l99m9fgvnaF9JoE6bYKmkGNK3aPbHB96w3+DnxFm4hs0drLsk7U8kf/N/CvwQNtllna0rjq61sH8L80HAuvwH1tvBy2ChqWSCaYTaGN19sTvlfzFD6n+iKTbvtayfrfe9ueWh6GJFoxLdr7V72a5ZpvHcCPDzma0wTO4EgbLyedxstO81n57LYBOBzyfsOhUKsW1J1BB5vr/tz8RyqOFylQP9Tvst2JALsC5lsH8PyQ40DV4ANzYa4dedNiKNR1s+x2wwbR7q4/4cTxqEk4LWDebfisuo36JXLiWFjOtLrlNWh3K1rRS4xvHcDNlFnNmWBBAl5SWaL3oPOfnvbr5pdjVnEaeBJSYjuLEkyLLsWhKccadmOphZkOPgVdalj2QpSmfOsADhMWE2ZBu4+EEJI4wKTAuCoC4xwQbWXBltpxbjkXJtKxxabo9e7tyhlgb6gNlSbUpMh+l/FaqzVwewGu8BW1Zx7pTpQDJUjb8tsUTW6+GDXbMn3mLbXlXJiGdggxFAoUrtPS3wE4Nk02UZG2OOzlk7fRs7i95QCLo3E0jtrjnM7SR3uS1p4qtS2nJ5OwtQVHgOvArLBFijZUV9QtSl8dAY5d0E0hM0w3HS2DpIeB6m/A1+HfhJcGUq4sOxH+x3f5+VO+Ds9rYNI7zPXOYWPrtf8bYMx6fuOAX5jzNR0PdsuON+X1f7EERxMJJoU6GkTEWBvVolVlb5lh3tKCg6Wx1IbaMDdJ+9sUCc5KC46hKGCk3IVOS4TCqdBNfUs7Kd4iXf2RjnT/LLysJy3XDcHLh/vde3x8DoGvwgsa67vBk91G5Pe/HbOe7xwym0NXbtiuuDkGO2IJDh9oQvJ4cY4vdoqLDuoH9Zl2F/ofsekn8lkuhIlhQcffUtSjytFyp++p6NiE7Rqx/lodgKVoceEp/CP4FfjrquZaTtj2AvH5K/ywpn7M34K/SsoYDAdIN448I1/0/wveW289T1/lX5xBzc8N5IaHr0XMOQdHsIkDuJFifj20pBm5jzwUv9e2FhwRsvhAbalCIuIw3bhJihY3p6nTFFIZgiSYjfTf3aXuOjmeGn4bPoGvwl+CFzTRczBIuHBEeImHc37/lGfwZR0cXzVDOvaKfNHvwe+suZ771K/y/XcBlsoN996JpBhoE2toYxOznNEOS5TJc6Id5GEXLjrWo+LEWGNpPDU4WAwsIRROu+1vM+0oW37z/MBN9kqHnSArwPfgFJ7Cq/Ai3Ie7g7ncmI09v8sjzw9mzOAEXoIHxURueaAce5V80f/DOuuZwHM8vsMb5wBzOFWM7wymTXPAEvm4vcFpZ2ut0VZRjkiP2MlmLd6DIpbGSiHOjdnUHN90hRYmhTnmvhzp1iKDNj+b7t5hi79lWGwQ+HN9RsfFMy0FXbEwhfuczKgCbyxYwBmcFhhvo/7a44v+i3XWcwDP86PzpGQYdWh7csP5dBvZ1jNzdxC8pBGuxqSW5vw40nBpj5JhMwvOzN0RWqERHMr4Lv1kWX84xLR830G3j6yqZ1a8UstTlW+qJPOZ+sZ7xZPKTJLhiNOAFd6tk+jrTH31ncLOxid8+nzRb128HhUcru/y0Wn6iT254YPC6FtVSIMoW2sk727AhvTtrWKZTvgsmckfXYZWeNRXx/3YQ2OUxLDrbHtN11IwrgXT6c8dATDwLniYwxzO4RzuQqTKSC5gAofMZ1QBK3zQ4JWobFbcvJm87FK+6JXrKahLn54m3p+McXzzYtP8VF/QpJuh1OwieElEoI1pRxPS09FBrkq2tWCU59+HdhNtTIqKm8EBrw2RTOEDpG3IKo2Y7mFdLm3ZeVjYwVw11o/oznceMve4CgMfNym/utA/d/ILMR7gpXzRy9eDsgLcgbs8O2Va1L0zzIdwGGemTBuwROHeoMShkUc7P+ISY3KH5ZZeWqO8mFTxQYeXTNuzvvK5FGPdQfuu00DwYFY9dyhctEt+OJDdnucfpmyhzUJzfsJjr29l8S0bXBfwRS9ZT26tmMIdZucch5ZboMz3Nio3nIOsYHCGoDT4kUA9MiXEp9Xsui1S8th/kbWIrMBxDGLodWUQIWcvnXy+9M23xPiSMOiRPqM+YMXkUN3gXFrZJwXGzUaMpJfyRS9ZT0lPe8TpScuRlbMHeUmlaKDoNuy62iWNTWNFYjoxFzuJs8oR+RhRx7O4SVNSXpa0ZJQ0K1LAHDQ+D9IepkMXpcsq5EVCvClBUIzDhDoyKwDw1Lc59GbTeORivugw1IcuaEOaGWdNm+Ps5fQ7/tm0DjMegq3yM3vb5j12qUId5UZD2oxDSEWOZMSqFl/W+5oynWDa/aI04tJRQ2eTXusg86SQVu/nwSYwpW6wLjlqIzwLuxGIvoAvul0PS+ZNz0/akp/pniO/8JDnGyaCkzbhl6YcqmK/69prxPqtpx2+Km9al9sjL+rwMgHw4jE/C8/HQ3m1vBuL1fldbzd8mOueVJ92syqdEY4KJjSCde3mcRw2TA6szxedn+zwhZMps0XrqEsiUjnC1hw0TELC2Ek7uAAdzcheXv1BYLagspxpzSAoZZUsIzIq35MnFQ9DOrlNB30jq3L4pkhccKUAA8/ocvN1Rzx9QyOtERs4CVsJRK/DF71kPYrxYsGsm6RMh4cps5g1DOmM54Ly1ii0Hd3Y/BMk8VWFgBVmhqrkJCPBHAolwZaWzLR9Vb7bcWdX9NyUYE+uB2BKfuaeBUcjDljbYVY4DdtsVWvzRZdWnyUzDpjNl1Du3aloAjVJTNDpcIOVVhrHFF66lLfJL1zJr9PQ2nFJSBaKoDe+sAvLufZVHVzYh7W0h/c6AAZ+7Tvj6q9j68G/cTCS/3n1vLKHZwNi+P+pS0WkZNMBMUl+LDLuiE4omZy71r3UFMwNJV+VJ/GC5ixVUkBStsT4gGKh0Gm4Oy3qvq7Lbmq24nPdDuDR9deR11XzP4vFu3TYzfnIyiSVmgizUYGqkIXNdKTY9pgb9D2Ix5t0+NHkVzCdU03suWkkVZAoCONCn0T35gAeW38de43mf97sMOpSvj4aa1KYUm58USI7Wxxes03bAZdRzk6UtbzMaCQ6IxO0dy7X+XsjoD16hpsBeGz9dfzHj+R/Hp8nCxZRqkEDTaCKCSywjiaoMJ1TITE9eg7Jqnq8HL6gDwiZb0u0V0Rr/rmvqjxKuaLCX7ZWXTvAY+uvm3z8CP7nzVpngqrJpZKwWnCUjIviYVlirlGOzPLI3SMVyp/elvBUjjDkNhrtufFFErQ8pmdSlbK16toBHlt/HV8uHMX/vEGALkV3RJREiSlopxwdMXOZPLZ+ix+kAHpMKIk8UtE1ygtquttwxNhphrIZ1IBzjGF3IIGxGcBj6q8bHJBG8T9vdsoWrTFEuebEZuVxhhClH6P5Zo89OG9fwHNjtNQTpD0TG9PJLEYqvEY6Rlxy+ZZGfL0Aj62/bnQCXp//eeM4KzfQVJbgMQbUjlMFIm6TpcfWlZje7NBSV6IsEVmumWIbjiloUzQX9OzYdo8L1wjw2PrrpimONfmfNyzKklrgnEkSzT5QWYQW40YShyzqsRmMXbvVxKtGuYyMKaU1ugenLDm5Ily4iT14fP11Mx+xJv+zZ3MvnfdFqxU3a1W/FTB4m3Qfsyc1XUcdVhDeUDZXSFHHLQj/Y5jtC7ZqM0CXGwB4bP11i3LhOvzPGygYtiUBiwQV/4wFO0majijGsafHyRLu0yG6q35cL1rOpVxr2s5cM2jJYMCdc10Aj6q/blRpWJ//+dmm5psMl0KA2+AFRx9jMe2WbC4jQxnikd4DU8TwUjRVacgdlhmr3bpddzuJ9zXqr2xnxJfzP29RexdtjDVZqzkqa6PyvcojGrfkXiJ8SEtml/nYskicv0ivlxbqjemwUjMw5evdg8fUX9nOiC/lf94Q2i7MURk9nW1MSj5j8eAyV6y5CN2S6qbnw3vdA1Iwq+XOSCl663udN3IzLnrt+us25cI1+Z83SXQUldqQq0b5XOT17bGpLd6ssN1VMPf8c+jG8L3NeCnMdF+Ra3fRa9dft39/LuZ/3vwHoHrqGmQFafmiQw6eyzMxS05K4bL9uA+SKUQzCnSDkqOGokXyJvbgJ/BHI+qvY69//4rl20NsmK2ou2dTsyIALv/91/8n3P2Aao71WFGi8KKv1fRC5+J67Q/507/E/SOshqN5TsmYIjVt+kcjAx98iz/4SaojbIV1rexE7/C29HcYD/DX4a0rBOF5VTu7omsb11L/AWcVlcVZHSsqGuXLLp9ha8I//w3Mv+T4Ew7nTBsmgapoCrNFObIcN4pf/Ob/mrvHTGqqgAupL8qWjWPS9m/31jAe4DjA+4+uCoQoT/zOzlrNd3qd4SdphFxsUvYwGWbTWtISc3wNOWH+kHBMfc6kpmpwPgHWwqaSUG2ZWWheYOGQGaHB+eQ/kn6b3pOgLV+ODSn94wDvr8Bvb70/LLuiPPEr8OGVWfDmr45PZyccEmsVXZGe1pRNX9SU5+AVQkNTIVPCHF/jGmyDC9j4R9LfWcQvfiETmgMMUCMN1uNCakkweZsowdYobiMSlnKA93u7NzTXlSfe+SVbfnPQXmg9LpYAQxpwEtONyEyaueWM4FPjjyjG3uOaFmBTWDNgBXGEiQpsaWhnAqIijB07Dlsy3fUGeP989xbWkyf+FF2SNEtT1E0f4DYYVlxFlbaSMPIRMk/3iMU5pME2SIWJvjckciebkQuIRRyhUvkHg/iUljG5kzVog5hV7vIlCuBrmlhvgPfNHQM8lCf+FEGsYbMIBC0qC9a0uuy2wLXVbLBaP5kjHokCRxapkQyzI4QEcwgYHRZBp+XEFTqXFuNVzMtjXLJgX4gAid24Hjwc4N3dtVSe+NNiwTrzH4WVUOlDobUqr1FuAgYllc8pmzoVrELRHSIW8ViPxNy4xwjBpyR55I6J220qQTZYR4guvUICJiSpr9gFFle4RcF/OMB7BRiX8sSfhpNSO3lvEZCQfLUVTKT78Ek1LRLhWN+yLyTnp8qWUZ46b6vxdRGXfHVqx3eI75YaLa4iNNiK4NOW7wPW6lhbSOF9/M9qw8e/aoB3d156qTzxp8pXx5BKAsYSTOIIiPkp68GmTq7sZtvyzBQaRLNxIZ+paozHWoLFeExIhRBrWitHCAHrCF7/thhD8JhYz84wg93QRV88wLuLY8zF8sQ36qF1J455bOlgnELfshKVxYOXKVuKx0jaj22sczTQqPqtV/XDgpswmGTWWMSDw3ssyUunLLrVPGjYRsH5ggHeHSWiV8kT33ycFSfMgkoOK8apCye0J6VW6GOYvffgU9RWsukEi2kUV2nl4dOYUzRik9p7bcA4ggdJ53LxKcEe17B1R8eqAd7dOepV8sTXf5lhejoL85hUdhDdknPtKHFhljOT+bdq0hxbm35p2nc8+Ja1Iw+tJykgp0EWuAAZYwMVwac5KzYMslhvgHdHRrxKnvhTYcfKsxTxtTETkjHO7rr3zjoV25lAQHrqpV7bTiy2aXMmUhTBnKS91jhtR3GEoF0oLnWhWNnYgtcc4N0FxlcgT7yz3TgNIKkscx9jtV1ZKpWW+Ub1tc1eOv5ucdgpx+FJy9pgbLE7xDyXb/f+hLHVGeitHOi6A7ybo3sF8sS7w7cgdk0nJaOn3hLj3uyD0Zp5pazFIUXUpuTTU18d1EPkDoX8SkmWTnVIozEdbTcZjoqxhNHf1JrSS/AcvHjZ/SMHhL/7i5z+POsTUh/8BvNfYMTA8n+yU/MlTZxSJDRStqvEuLQKWwDctMTQogUDyQRoTQG5Kc6oQRE1yV1jCA7ri7jdZyK0sYTRjCR0Hnnd+y7nHxNgTULqw+8wj0mQKxpYvhjm9uSUxg+TTy7s2GtLUGcywhXSKZN275GsqlclX90J6bRI1aouxmgL7Q0Nen5ziM80SqMIo8cSOo+8XplT/5DHNWsSUr/6lLN/QQ3rDyzLruEW5enpf7KqZoShEduuSFOV7DLX7Ye+GmXb6/hnNNqKsVXuMDFpb9Y9eH3C6NGEzuOuI3gpMH/I6e+zDiH1fXi15t3vA1czsLws0TGEtmPEJdiiFPwlwKbgLHAFk4P6ZyPdymYYHGE0dutsChQBl2JcBFlrEkY/N5bQeXQ18gjunuMfMfsBlxJSx3niO485fwO4fGD5T/+3fPQqkneWVdwnw/3bMPkW9Wbqg+iC765Zk+xcT98ibKZc2EdgHcLoF8cSOo/Oc8fS+OyEULF4g4sJqXVcmfMfsc7A8v1/yfGXmL9I6Fn5pRwZhsPv0TxFNlAfZCvG+Oohi82UC5f/2IsJo0cTOm9YrDoKhFPEUr/LBYTUNht9zelHXDqwfPCIw4owp3mOcIQcLttWXFe3VZ/j5H3cIc0G6oPbCR+6Y2xF2EC5cGUm6wKC5tGEzhsWqw5hNidUiKX5gFWE1GXh4/Qplw4sVzOmx9QxU78g3EF6wnZlEN4FzJ1QPSLEZz1KfXC7vd8ssGdIbNUYpVx4UapyFUHzJoTOo1McSkeNn1M5MDQfs4qQuhhX5vQZFw8suwWTcyYTgioISk2YdmkhehG4PkE7w51inyAGGaU+uCXADabGzJR1fn3lwkty0asIo8cROm9Vy1g0yDxxtPvHDAmpu+PKnM8Ix1wwsGw91YJqhteaWgjYBmmQiebmSpwKKzE19hx7jkzSWOm66oPbzZ8Yj6kxVSpYjVAuvLzYMCRo3oTQecOOjjgi3NQ4l9K5/hOGhNTdcWVOTrlgYNkEXINbpCkBRyqhp+LdRB3g0OU6rMfW2HPCFFMV9nSp+uB2woepdbLBuJQyaw/ZFysXrlXwHxI0b0LovEkiOpXGA1Ijagf+KUNC6rKNa9bQnLFqYNkEnMc1uJrg2u64ELPBHpkgWbmwKpJoDhMwNbbGzAp7Yg31wS2T5rGtzit59PrKhesWG550CZpHEzpv2NGRaxlNjbMqpmEIzygJqQfjypycs2pg2cS2RY9r8HUqkqdEgKTWtWTKoRvOBPDYBltja2SO0RGjy9UHtxwRjA11ujbKF+ti5cIR9eCnxUg6owidtyoU5tK4NLji5Q3HCtiyF2IqLGYsHViOXTXOYxucDqG0HyttqYAKqYo3KTY1ekyDXRAm2AWh9JmsVh/ccg9WJ2E8YjG201sPq5ULxxX8n3XLXuMInbft2mk80rRGjCGctJ8/GFdmEQ9Ug4FlE1ll1Y7jtiraqm5Fe04VV8lvSVBL8hiPrfFVd8+7QH3Qbu2ipTVi8cvSGivc9cj8yvH11YMHdNSERtuOslM97feYFOPKzGcsI4zW0YGAbTAOaxCnxdfiYUmVWslxiIblCeAYr9VYR1gM7GmoPrilunSxxeT3DN/2eBQ9H11+nk1adn6VK71+5+Jfct4/el10/7KBZfNryUunWSCPxPECk1rdOv1WVSrQmpC+Tl46YD3ikQYcpunSQgzVB2VHFhxHVGKDgMEY5GLlQnP7FMDzw7IacAWnO6sBr12u+XanW2AO0wQ8pknnFhsL7KYIqhkEPmEXFkwaN5KQphbkUmG72wgw7WSm9RiL9QT925hkjiVIIhphFS9HKI6/8QAjlpXqg9W2C0apyaVDwKQwrwLY3j6ADR13ZyUNByQXHQu6RY09Hu6zMqXRaNZGS/KEJs0cJEe9VH1QdvBSJv9h09eiRmy0V2uJcqHcShcdvbSNg5fxkenkVprXM9rDVnX24/y9MVtncvbKY706anNl3ASll9a43UiacVquXGhvq4s2FP62NGKfQLIQYu9q1WmdMfmUrDGt8eDS0cXozH/fjmUH6Jruvm50hBDSaEU/2Ru2LEN/dl006TSc/g7tfJERxGMsgDUEr104pfWH9lQaN+M4KWQjwZbVc2rZVNHsyHal23wZtIs2JJqtIc/WLXXRFCpJkfE9jvWlfFbsNQ9pP5ZBS0zKh4R0aMFj1IjTcTnvi0Zz2rt7NdvQb2mgbju1plsH8MmbnEk7KbK0b+wC2iy3aX3szW8xeZvDwET6hWZYwqTXSSG+wMETKum0Dq/q+x62gt2ua2ppAo309TRk9TPazfV3qL9H8z7uhGqGqxNVg/FKx0HBl9OVUORn8Q8Jx9gFttGQUDr3tzcXX9xGgN0EpzN9mdZ3GATtPhL+CjxFDmkeEU6x56kqZRusLzALXVqkCN7zMEcqwjmywDQ6OhyUe0Xao1Qpyncrg6wKp9XfWDsaZplElvQ/b3sdweeghorwBDlHzgk1JmMc/wiERICVy2VJFdMjFuLQSp3S0W3+sngt2njwNgLssFGVQdJ0tu0KH4ky1LW4yrbkuaA6Iy9oz/qEMMXMMDWyIHhsAyFZc2peV9hc7kiKvfULxCl9iddfRK1f8kk9qvbdOoBtOg7ZkOZ5MsGrSHsokgLXUp9y88smniwWyuFSIRVmjplga3yD8Uij5QS1ZiM4U3Qw5QlSm2bXjFe6jzzBFtpg+/YBbLAWG7OPynNjlCw65fukGNdkJRf7yM1fOxVzbxOJVocFoYIaGwH22mIQkrvu1E2nGuebxIgW9U9TSiukPGU+Lt++c3DJPKhyhEEbXCQLUpae2exiKy6tMPe9mDRBFCEMTWrtwxN8qvuGnt6MoihKWS5NSyBhbH8StXoAz8PLOrRgLtOT/+4vcu+7vDLnqNvztOq7fmd8sMmY9Xzn1zj8Dq8+XVdu2Nv0IIySgEdQo3xVHps3Q5i3fLFsV4aiqzAiBhbgMDEd1uh8qZZ+lwhjkgokkOIv4xNJmyncdfUUzgB4oFMBtiu71Xumpz/P+cfUP+SlwFExwWW62r7b+LSPxqxn/gvMZ5z9C16t15UbNlq+jbGJtco7p8wbYlL4alSyfWdeuu0j7JA3JFNuVAwtst7F7FhWBbPFNKIUORndWtLraFLmMu7KFVDDOzqkeaiN33YAW/r76wR4XDN/yN1z7hejPau06EddkS/6XThfcz1fI/4K736fO48vlxt2PXJYFaeUkFS8U15XE3428xdtn2kc8GQlf1vkIaNRRnOMvLTWrZbElEHeLWi1o0dlKPAh1MVgbbVquPJ5+Cr8LU5/H/+I2QlHIU2ClXM9G8v7Rr7oc/hozfUUgsPnb3D+I+7WF8kNO92GY0SNvuxiE+2Bt8prVJTkzE64sfOstxuwfxUUoyk8VjcTlsqe2qITSFoSj6Epd4KsT6BZOWmtgE3hBfir8IzZDwgV4ZTZvD8VvPHERo8v+vL1DASHTz/i9OlKueHDjK5Rnx/JB1Vb1ioXdBra16dmt7dgik10yA/FwJSVY6XjA3oy4SqM2frqDPPSRMex9qs3XQtoWxMj7/Er8GWYsXgjaVz4OYumP2+9kbxvny/6kvWsEBw+fcb5bInc8APdhpOSs01tEqIkoiZjbAqKMruLbJYddHuHFRIyJcbdEdbl2sVLaySygunutBg96Y2/JjKRCdyHV+AEFtTvIpbKIXOamknYSiB6KV/0JetZITgcjjk5ZdaskBtWO86UF0ap6ozGXJk2WNiRUlCPFir66lzdm/SLSuK7EUdPz8f1z29Skq6F1fXg8+5UVR6bszncP4Tn4KUkkdJ8UFCY1zR1i8RmL/qQL3rlei4THG7OODlnKko4oI01kd3CaM08Ia18kC3GNoVaO9iDh+hWxSyTXFABXoau7Q6q9OxYg/OVEMw6jdbtSrJ9cBcewGmaZmg+bvkUnUUaGr+ZfnMH45Ivevl61hMcXsxYLFTu1hTm2zViCp7u0o5l+2PSUh9bDj6FgYypufBDhqK2+oXkiuHFHR3zfj+9PtA8oR0xnqX8qn+sx3bFODSbbF0X8EUvWQ8jBIcjo5bRmLOljDNtcqNtOe756h3l0VhKa9hDd2l1eqmsnh0MNMT/Cqnx6BInumhLT8luljzQ53RiJeA/0dxe5NK0o2fA1+GLXr6eNQWHNUOJssQaTRlGpLHKL9fD+IrQzTOMZS9fNQD4AnRNVxvTdjC+fJdcDDWQcyB00B0t9BDwTxXgaAfzDZ/DBXzRnfWMFRwuNqocOmX6OKNkY63h5n/fFcB28McVHqnXZVI27K0i4rDLNE9lDKV/rT+udVbD8dFFu2GGZ8mOt0kAXcoX3ZkIWVtw+MNf5NjR2FbivROHmhV1/pj2egv/fMGIOWTIWrV3Av8N9imV9IWml36H6cUjqEWNv9aNc+veb2sH46PRaHSuMBxvtW+twxctq0z+QsHhux8Q7rCY4Ct8lqsx7c6Sy0dl5T89rIeEuZKoVctIk1hNpfavER6yyH1Vvm3MbsUHy4ab4hWr/OZPcsRBphnaV65/ZcdYPNNwsjN/djlf9NqCw9U5ExCPcdhKxUgLSmfROpLp4WSUr8ojdwbncbvCf+a/YzRaEc6QOvXcGO256TXc5Lab9POvB+AWY7PigWYjzhifbovuunzRawsO24ZqQQAqguBtmpmPB7ysXJfyDDaV/aPGillgz1MdQg4u5MYaEtBNNHFjkRlSpd65lp4hd2AVPTfbV7FGpyIOfmNc/XVsPfg7vzaS/3nkvLL593ANLvMuRMGpQIhiF7kUEW9QDpAUbTWYBcbp4WpacHHY1aacqQyjGZS9HI3yCBT9kUZJhVOD+zUDvEH9ddR11fzPcTDQ5TlgB0KwqdXSavk9BC0pKp0WmcuowSw07VXmXC5guzSa4p0UvRw2lbDiYUx0ExJJRzWzi6Gm8cnEkfXXsdcG/M/jAJa0+bmCgdmQ9CYlNlSYZOKixmRsgiFxkrmW4l3KdFKv1DM8tk6WxPYJZhUUzcd8Kdtgrw/gkfXXDT7+avmfVak32qhtkg6NVdUS5wgkru1YzIkSduTW1FDwVWV3JQVJVuieTc0y4iDpFwc7/BvSalvKdQM8sv662cevz/+8sQVnjVAT0W2wLllw1JiMhJRxgDjCjLQsOzSFSgZqx7lAW1JW0e03yAD3asC+GD3NbQhbe+mN5GXH1F83KDOM4n/e5JIuH4NpdQARrFPBVptUNcjj4cVMcFSRTE2NpR1LEYbYMmfWpXgP9KejaPsLUhuvLCsVXznAG9dfx9SR1ud/3hZdCLHb1GMdPqRJgqDmm76mHbvOXDtiO2QPUcKo/TWkQ0i2JFXpBoo7vij1i1Lp3ADAo+qvG3V0rM//vFnnTE4hxd5Ka/Cor5YEdsLVJyKtDgVoHgtW11pWSjolPNMnrlrVj9Fv2Qn60twMwKPqr+N/wvr8z5tZcDsDrv06tkqyzESM85Ycv6XBWA2birlNCXrI6VbD2lx2L0vQO0QVTVVLH4SE67fgsfVXv8n7sz7/85Z7cMtbE6f088wSaR4kCkCm10s6pKbJhfqiUNGLq+0gLWC6eUAZFPnLjwqtKd8EwGvWX59t7iPW4X/eAN1svgRVSY990YZg06BD1ohLMtyFTI4pKTJsS9xREq9EOaPWiO2gpms7397x6nQJkbh+Fz2q/rqRROX6/M8bJrqlVW4l6JEptKeUFuMYUbtCQ7CIttpGc6MY93x1r1vgAnRXvY5cvwWPqb9uWQm+lP95QxdNMeWhOq1x0Db55C7GcUv2ZUuN6n8iKzsvOxibC//Yfs9Na8r2Rlz02vXXDT57FP/zJi66/EJSmsJKa8QxnoqW3VLQ+jZVUtJwJ8PNX1NQCwfNgdhhHD9on7PdRdrdGPF28rJr1F+3LBdeyv+8yYfLoMYet1vX4upNAjVvwOUWnlNXJXlkzk5Il6kqeoiL0C07qno+/CYBXq/+utlnsz7/Mzvy0tmI4zm4ag23PRN3t/CWryoUVJGm+5+K8RJ0V8Hc88/XHUX/HfiAq7t+BH+x6v8t438enWmdJwFA6ZINriLGKv/95f8lT9/FnyA1NMVEvQyaXuu+gz36f/DD73E4pwqpLcvm/o0Vle78n//+L/NPvoefp1pTJye6e4A/D082FERa5/opeH9zpvh13cNm19/4v/LDe5xMWTi8I0Ta0qKlK27AS/v3/r+/x/2GO9K2c7kVMonDpq7//jc5PKCxeNPpFVzaRr01wF8C4Pu76hXuX18H4LduTr79guuFD3n5BHfI+ZRFhY8w29TYhbbLi/bvBdqKE4fUgg1pBKnV3FEaCWOWyA+m3WpORZr/j+9TKJtW8yBTF2/ZEODI9/QavHkVdGFp/Pjn4Q+u5hXapsP5sOH+OXXA1LiKuqJxiMNbhTkbdJTCy4llEt6NnqRT4dhg1V3nbdrm6dYMecA1yTOL4PWTE9L5VzPFlLBCvlG58AhehnN4uHsAYinyJ+AZ/NkVvELbfOBUuOO5syBIEtiqHU1k9XeISX5bsimrkUUhnGDxourN8SgUsCZVtKyGbyGzHXdjOhsAvOAswSRyIBddRdEZWP6GZhNK/yjwew9ehBo+3jEADu7Ay2n8mDc+TS7awUHg0OMzR0LABhqLD4hJEh/BEGyBdGlSJoXYXtr+3HS4ijzVpgi0paWXtdruGTknXBz+11qT1Q2inxaTzQCO46P3lfLpyS4fou2PH/PupwZgCxNhGlj4IvUuWEsTkqMWm6i4xCSMc9N1RDQoCVcuGItJ/MRWefais+3synowi/dESgJjkilnWnBTGvRWmaw8oR15257t7CHmCf8HOn7cwI8+NQBXMBEmAa8PMRemrNCEhLGEhDQKcGZWS319BX9PFBEwGTbRBhLbDcaV3drFcDqk5kCTd2JF1Wp0HraqBx8U0wwBTnbpCadwBA/gTH/CDrcCs93LV8E0YlmmcyQRQnjBa8JESmGUfIjK/7fkaDJpmD2QptFNVJU1bbtIAjjWQizepOKptRjbzR9Kag6xZmMLLjHOtcLT3Tx9o/0EcTT1XN3E45u24AiwEypDJXihKjQxjLprEwcmRKclaDNZCVqr/V8mYWyFADbusiY5hvgFoU2vio49RgJLn5OsReRFN6tabeetiiy0V7KFHT3HyZLx491u95sn4K1QQSPKM9hNT0wMVvAWbzDSVdrKw4zRjZMyJIHkfq1VAVCDl/bUhNKlGq0zGr05+YAceXVPCttVk0oqjVwMPt+BBefx4yPtGVkUsqY3CHDPiCM5ngupUwCdbkpd8kbPrCWHhkmtIKLEetF2499eS1jZlIPGYnlcPXeM2KD9vLS0bW3ktYNqUllpKLn5ZrsxlIzxvDu5eHxzGLctkZLEY4PgSOg2IUVVcUONzUDBEpRaMoXNmUc0tFZrTZquiLyKxrSm3DvIW9Fil+AkhXu5PhEPx9mUNwqypDvZWdKlhIJQY7vn2OsnmBeOWnYZ0m1iwbbw1U60by5om47iHRV6fOgzjMf/DAZrlP40Z7syxpLK0lJ0gqaAK1c2KQKu7tabTXkLFz0sCftuwX++MyNeNn68k5Buq23YQhUh0SNTJa1ioQ0p4nUG2y0XilF1JqODqdImloPS4Bp111DEWT0jJjVv95uX9BBV7eB3bUWcu0acSVM23YZdd8R8UbQUxJ9wdu3oMuhdt929ME+mh6JXJ8di2RxbTi6TbrDquqV4aUKR2iwT6aZbyOwEXN3DUsWr8Hn4EhwNyHuXHh7/pdaUjtR7vnDh/d8c9xD/s5f501eQ1+CuDiCvGhk1AN/4Tf74RfxPwD3toLarR0zNtsnPzmS64KIRk861dMWCU8ArasG9T9H0ZBpsDGnjtAOM2+/LuIb2iIUGXNgl5ZmKD/Tw8TlaAuihaFP5yrw18v4x1898zIdP+DDAX1bM3GAMvPgRP/cJn3zCW013nrhHkrITyvYuwOUkcHuKlRSW5C6rzIdY4ppnF7J8aAJbQepgbJYBjCY9usGXDKQxq7RZfh9eg5d1UHMVATRaD/4BHK93/1iAgYZ/+jqPn8Dn4UExmWrpa3+ZOK6MvM3bjwfzxNWA2dhs8+51XHSPJiaAhGSpWevEs5xHLXcEGFXYiCONySH3fPWq93JIsBiSWvWyc3CAN+EcXoT7rCSANloPPoa31rt/5PUA/gp8Q/jDD3hyrjzlR8VkanfOvB1XPubt17vzxAfdSVbD1pzAnfgyF3ycadOTOTXhpEUoLC1HZyNGW3dtmjeXgr2r56JNmRwdNNWaQVBddd6rh4MhviEB9EFRD/7RGvePvCbwAL4Mx/D6M541hHO4D3e7g6PafdcZVw689z7NGTwo5om7A8sPhccT6qKcl9NJl9aM/9kX+e59Hh1yPqGuCCZxuITcsmNaJ5F7d0q6J3H48TO1/+M57085q2icdu2U+W36Ldllz9Agiv4YGljoEN908EzvDOrBF98/vtJwCC/BF2AG75xxEmjmMIcjxbjoaxqOK3/4hPOZzhMPBpYPG44CM0dTVm1LjLtUWWVz1Bcf8tEx0zs8O2A2YVHRxKYOiy/aOVoAaMu0i7ubu43njjmd4ibMHU1sIDHaQNKrZND/FZYdk54oCXetjq7E7IVl9eAL7t+oHnwXXtLx44czzoRFHBztYVwtH1d+NOMkupZ5MTM+gUmq90X+Bh9zjRlmaQ+m7YMqUL/veemcecAtOJ0yq1JnVlN27di2E0+Klp1tAJ4KRw1eMI7aJjsO3R8kPSI3fUFXnIOfdQe86sIIVtWDL7h//Ok6vj8vwDk08NEcI8zz7OhBy+WwalzZeZ4+0XniRfst9pAJqQHDGLzVQ2pheZnnv1OWhwO43/AgcvAEXEVVpa4db9sGvNK8wjaENHkfFQ4Ci5i7dqnQlPoLQrHXZDvO3BIXZbJOBrOaEbML6sFL798I4FhKihjHMsPjBUZYCMFr6nvaArxqXPn4lCa+cHfSa2cP27g3Z3ziYTRrcbQNGLQmGF3F3cBdzzzX7AILx0IB9rbwn9kx2G1FW3Inic+ZLIsVvKR8Zwfj0l1fkqo8LWY1M3IX14OX3r9RKTIO+d9XzAI8qRPGPn/4NC2n6o4rN8XJ82TOIvuVA8zLKUHRFgBCetlDZlqR1gLKjS39xoE7Bt8UvA6BxuEDjU3tFsEijgA+615tmZkXKqiEENrh41iLDDZNq4pKTWR3LZfnos81LOuNa15cD956vLMsJd1rqYp51gDUQqMYm2XsxnUhD2jg1DM7SeuJxxgrmpfISSXVIJIS5qJJSvJPEQ49DQTVIbYWJ9QWa/E2+c/oPK1drmC7WSfJRNKBO5Yjvcp7Gc3dmmI/Xh1kDTEuiSnWqQf37h+fTMhGnDf6dsS8SQfQWlqqwXXGlc/PEZ/SC5mtzIV0nAshlQdM/LvUtYutrEZ/Y+EAFtq1k28zQhOwLr1AIeANzhF8t9qzTdZf2qRKO6MWE9ohBYwibbOmrFtNmg3mcS+tB28xv2uKd/agYCvOP+GkSc+0lr7RXzyufL7QbkUpjLjEWFLqOIkAGu2B0tNlO9Eau2W1qcOUvVRgKzypKIQZ5KI3q0MLzqTNRYqiZOqmtqloIRlmkBHVpHmRYV6/HixbO6UC47KOFJnoMrVyr7wYz+SlW6GUaghYbY1I6kkxA2W1fSJokUdSh2LQ1GAimRGm0MT+uu57H5l7QgOWxERpO9moLRPgTtquWCfFlGlIjQaRly9odmzMOWY+IBO5tB4sW/0+VWGUh32qYk79EidWKrjWuiLpiVNGFWFRJVktyeXWmbgBBzVl8anPuXyNJlBJOlKLTgAbi/EYHVHxWiDaVR06GnHQNpJcWcK2jJtiCfG2sEHLzuI66sGrMK47nPIInPnu799935aOK2cvmvubrE38ZzZjrELCmXM2hM7UcpXD2oC3+ECVp7xtIuxptJ0jUr3sBmBS47TVxlvJ1Sqb/E0uLdvLj0lLr29ypdd/eMX3f6lrxGlKwKQxEGvw0qHbkbwrF3uHKwVENbIV2wZ13kNEF6zD+x24aLNMfDTCbDPnEikZFyTNttxWBXDaBuM8KtI2rmaMdUY7cXcUPstqTGvBGSrFWIpNMfbdea990bvAOC1YX0qbc6smDS1mPxSJoW4fwEXvjMmhlijDRq6qale6aJEuFGoppYDoBELQzLBuh/mZNx7jkinv0EtnUp50lO9hbNK57lZaMAWuWR5Yo9/kYwcYI0t4gWM47Umnl3YmpeBPqSyNp3K7s2DSAS/39KRuEN2bS4xvowV3dFRMx/VFcp2Yp8w2nTO9hCXtHG1kF1L4KlrJr2wKfyq77R7MKpFKzWlY9UkhYxyHWW6nBWPaudvEAl3CGcNpSXPZ6R9BbBtIl6cHL3gIBi+42CYXqCx1gfGWe7Ap0h3luyXdt1MKy4YUT9xSF01G16YEdWsouW9mgDHd3veyA97H+Ya47ZmEbqMY72oPztCGvK0onL44AvgC49saZKkWRz4veWljE1FHjbRJaWv6ZKKtl875h4CziFCZhG5rx7tefsl0aRT1bMHZjm8dwL/6u7wCRysaQblQoG5yAQN5zpatMNY/+yf8z+GLcH/Qn0iX2W2oEfXP4GvwQHuIL9AYGnaO3zqAX6946nkgqZNnUhx43DIdQtMFeOPrgy/y3Yd85HlJWwjLFkU3kFwq28xPnuPhMWeS+tDLV9Otllq7pQCf3uXJDN9wFDiUTgefHaiYbdfi3b3u8+iY6TnzhgehI1LTe8lcd7s1wJSzKbahCRxKKztTLXstGAiu3a6rPuQs5pk9TWAan5f0BZmGf7Ylxzzk/A7PAs4QPPPAHeFQ2hbFHszlgZuKZsJcUmbDC40sEU403cEjczstOEypa+YxevL4QBC8oRYqWdK6b7sK25tfE+oDZgtOQ2Jg8T41HGcBE6fTWHn4JtHcu9S7uYgU5KSCkl/mcnq+5/YBXOEr6lCUCwOTOM1taOI8mSxx1NsCXBEmLKbMAg5MkwbLmpBaFOPrNSlO2HnLiEqW3tHEwd8AeiQLmn+2gxjC3k6AxREqvKcJbTEzlpLiw4rNZK6oJdidbMMGX9FULKr0AkW+2qDEPBNNm5QAt2Ik2nftNWHetubosHLo2nG4vQA7GkcVCgVCgaDixHqo9UUn1A6OshapaNR/LPRYFV8siT1cCtJE0k/3WtaNSuUZYKPnsVIW0xXWnMUxq5+En4Kvw/MqQmVXnAXj9Z+9zM98zM/Agy7F/qqj2Nh67b8HjFnPP3iBn/tkpdzwEJX/whIcQUXOaikeliCRGUk7tiwF0rItwMEhjkZ309hikFoRAmLTpEXWuHS6y+am/KB/fM50aLEhGnSMwkpxzOov4H0AvgovwJ1iGzDLtJn/9BU+fAINfwUe6FHSLhu83viV/+/HrOePX+STT2B9uWGbrMHHLldRBlhS/CJQmcRxJFqZica01XixAZsYiH1uolZxLrR/SgxVIJjkpQP4PE9sE59LKLr7kltSBogS5tyszzH8Fvw8/AS8rNOg0xUS9fIaHwb+6et8Q/gyvKRjf5OusOzGx8evA/BP4IP11uN/grca5O0lcsPLJ5YjwI4QkJBOHa0WdMZYGxPbh2W2nR9v3WxEWqgp/G3+6VZbRLSAAZ3BhdhAaUL33VUSw9yjEsvbaQ9u4A/gGXwZXoEHOuU1GSj2chf+Mo+f8IcfcAxfIKVmyunRbYQVnoevwgfw3TXXcw++xNuP4fhyueEUNttEduRVaDttddoP0eSxLe2LENk6itYxlrxBNBYrNNKSQmeaLcm9c8UsaB5WyO6675yyQIAWSDpBVoA/gxmcwEvwoDv0m58UE7gHn+fJOa8/Ywan8EKRfjsopF83eCglX/Sfr7OeaRoQfvt1CGvIDccH5BCvw1sWIzRGC/66t0VTcLZQZtm6PlAasbOJ9iwWtUo7biktTSIPxnR24jxP1ZKaqq+2RcXM9OrBAm/AAs7hDJ5bNmGb+KIfwCs8a3jnjBrOFeMjHSCdbKr+2uOLfnOd9eiA8Hvvwwq54VbP2OqwkB48Ytc4YEOiH2vTXqodabfWEOzso4qxdbqD5L6tbtNPECqbhnA708DZH4QOJUXqScmUlks7Ot6FBuZw3n2mEbaUX7kDzxHOOQk8nKWMzAzu6ZZ8sOFw4RK+6PcuXo9tB4SbMz58ApfKDXf3szjNIIbGpD5TKTRxGkEMLjLl+K3wlWXBsCUxIDU+jbOiysESqAy1MGUJpXgwbTWzNOVEziIXZrJ+VIztl1PUBxTSo0dwn2bOmfDRPD3TRTGlfbCJvO9KvuhL1hMHhB9wPuPRLGHcdOWG2xc0U+5bQtAJT0nRTewXL1pgk2+rZAdeWmz3jxAqfNQQdzTlbF8uJ5ecEIWvTkevAHpwz7w78QujlD/Lr491bD8/1vhM2yrUQRrWXNQY4fGilfctMWYjL72UL/qS9eiA8EmN88nbNdour+PBbbAjOjIa4iBhfFg6rxeKdEGcL6p3EWR1Qq2Qkhs2DrnkRnmN9tG2EAqmgPw6hoL7Oza7B+3SCrR9tRftko+Lsf2F/mkTndN2LmzuMcKTuj/mX2+4Va3ki16+nnJY+S7MefpkidxwnV+4wkXH8TKnX0tsYzYp29DOOoSW1nf7nTh2akYiWmcJOuTidSaqESrTYpwjJJNVGQr+rLI7WsqerHW6Kp/oM2pKuV7T1QY9gjqlZp41/WfKpl56FV/0kvXQFRyeQ83xaTu5E8p5dNP3dUF34ihyI3GSpeCsywSh22ZJdWto9winhqifb7VRvgktxp13vyjrS0EjvrRfZ62uyqddSWaWYlwTPAtJZ2oZ3j/Sgi/mi+6vpzesfAcWNA0n8xVyw90GVFGuZjTXEQy+6GfLGLMLL523f5E0OmxVjDoOuRiH91RKU+vtoCtH7TgmvBLvtFXWLW15H9GTdVw8ow4IlRLeHECN9ym1e9K0I+Cbnhgv4Yu+aD2HaQJ80XDqOzSGAV4+4yCqBxrsJAX6ZTIoX36QnvzhhzzMfFW2dZVLOJfo0zbce5OvwXMFaZ81mOnlTVXpDZsQNuoYWveketKb5+6JOOsgX+NTm7H49fUTlx+WLuWL7qxnOFh4BxpmJx0p2gDzA/BUARuS6phR+pUsY7MMboAHx5xNsSVfVZcYSwqCKrqon7zM+8ecCkeS4nm3rINuaWvVNnMRI1IRpxTqx8PZUZ0Br/UEduo3B3hNvmgZfs9gQPj8vIOxd2kndir3awvJ6BLvoUuOfFWNYB0LR1OQJoUySKb9IlOBx74q1+ADC2G6rOdmFdJcD8BkfualA+BdjOOzP9uUhGUEX/TwhZsUduwRr8wNuXKurCixLBgpQI0mDbJr9dIqUuV+92ngkJZ7xduCk2yZKbfWrH1VBiTg9VdzsgRjW3CVXCvAwDd+c1z9dWw9+B+8MJL/eY15ZQ/HqvTwVdsZn5WQsgRRnMaWaecu3jFvMBEmgg+FJFZsnSl0zjB9OqPYaBD7qmoVyImFvzi41usesV0julaAR9dfR15Xzv9sEruRDyk1nb+QaLU67T885GTls6YgcY+UiMa25M/pwGrbCfzkvR3e0jjtuaFtnwuagHTSb5y7boBH119HXhvwP487jJLsLJ4XnUkHX5sLbS61dpiAXRoZSCrFJ+EjpeU3puVfitngYNo6PJrAigKktmwjyQdZpfq30mmtulaAx9Zfx15Xzv+cyeuiBFUs9zq8Kq+XB9a4PVvph3GV4E3y8HENJrN55H1X2p8VyqSKwVusJDKzXOZzplWdzBUFK9e+B4+uv468xvI/b5xtSAkBHQaPvtqWzllVvEOxPbuiE6+j2pvjcKsbvI7txnRErgfH7LdXqjq0IokKzga14GzQ23SSbCQvO6r+Or7SMIr/efOkkqSdMnj9mBx2DRsiY29Uj6+qK9ZrssCKaptR6HKURdwUYeUWA2kPzVKQO8ku2nU3Anhs/XWkBx3F/7wJtCTTTIKftthue1ty9xvNYLY/zo5KSbIuKbXpbEdSyeRyYdAIwKY2neyoc3+k1XUaufYga3T9daMUx/r8z1s10ITknIO0kuoMt+TB8jK0lpayqqjsJ2qtXAYwBU932zinimgmd6mTRDnQfr88q36NAI+tv24E8Pr8zxtasBqx0+xHH9HhlrwsxxNUfKOHQaZBITNf0uccj8GXiVmXAuPEAKSdN/4GLHhs/XWj92dN/uetNuBMnVR+XWDc25JLjo5Mg5IZIq226tmCsip2zZliL213YrTlL2hcFjpCduyim3M7/eB16q/blQsv5X/esDRbtJeabLIosWy3ycavwLhtxdWzbMmHiBTiVjJo6lCLjXZsi7p9PEPnsq6X6wd4bP11i0rD5fzPm/0A6brrIsllenZs0lCJlU4abakR59enZKrKe3BZihbTxlyZ2zl1+g0wvgmA166/bhwDrcn/7Ddz0eWZuJvfSESug6NzZsox3Z04FIxz0mUjMwVOOVTq1CQ0AhdbBGVdjG/CgsfUX7esJl3K/7ytWHRv683praW/8iDOCqWLLhpljDY1ZpzK75QiaZoOTpLKl60auHS/97oBXrv+umU9+FL+5+NtLFgjqVLCdbmj7pY5zPCPLOHNCwXGOcLquOhi8CmCWvbcuO73XmMUPab+ug3A6/A/78Bwe0bcS2+tgHn4J5pyS2WbOck0F51Vq3LcjhLvZ67p1ABbaL2H67bg78BfjKi/jr3+T/ABV3ilLmNXTI2SpvxWBtt6/Z//D0z/FXaGbSBgylzlsEGp+5//xrd4/ae4d8DUUjlslfIYS3t06HZpvfQtvv0N7AHWqtjP2pW08QD/FLy//da38vo8PNlKHf5y37Dxdfe/oj4kVIgFq3koLReSR76W/bx//n9k8jonZxzWTANVwEniDsg87sOSd/z7//PvMp3jQiptGVWFX2caezzAXwfgtzYUvbr0iozs32c3Uge7varH+CNE6cvEYmzbPZ9hMaYDdjK4V2iecf6EcEbdUDVUARda2KzO/JtCuDbNQB/iTeL0EG1JSO1jbXS+nLxtPMDPw1fh5+EPrgSEKE/8Gry5A73ui87AmxwdatyMEBCPNOCSKUeRZ2P6Myb5MRvgCHmA9ywsMifU+AYXcB6Xa5GibUC5TSyerxyh0j6QgLVpdyhfArRTTLqQjwe4HOD9s92D4Ap54odXAPBWLAwB02igG5Kkc+piN4lvODIFGAZgT+EO4Si1s7fjSR7vcQETUkRm9O+MXyo9OYhfe4xt9STQ2pcZRLayCV90b4D3jR0DYAfyxJ+eywg2IL7NTMXna7S/RpQ63JhWEM8U41ZyQGjwsVS0QBrEKLu8xwZsbi4wLcCT+OGidPIOCe1PiSc9Qt+go+vYqB7cG+B9d8cAD+WJPz0Am2gxXgU9IneOqDpAAXOsOltVuMzpdakJXrdPCzXiNVUpCeOos5cxnpQT39G+XVLhs1osQVvJKPZyNq8HDwd4d7pNDuWJPxVX7MSzqUDU6gfadKiNlUFTzLeFHHDlzO4kpa7aiKhBPGKwOqxsBAmYkOIpipyXcQSPlRTf+Tii0U3EJGaZsDER2qoB3h2hu0qe+NNwUooYU8y5mILbJe6OuX+2FTKy7bieTDAemaQyQ0CPthljSWO+xmFDIYiESjM5xKd6Ik5lvLq5GrQ3aCMLvmCA9wowLuWJb9xF59hVVP6O0CrBi3ZjZSNOvRy+I6klNVRJYRBaEzdN+imiUXQ8iVF8fsp+W4JXw7WISW7fDh7lptWkCwZ4d7QTXyBPfJMYK7SijjFppGnlIVJBJBYj7eUwtiP1IBXGI1XCsjNpbjENVpSAJ2hq2LTywEly3hUYazt31J8w2+aiLx3g3fohXixPfOMYm6zCGs9LVo9MoW3MCJE7R5u/WsOIjrqBoHUO0bJE9vxBpbhsd3+Nb4/vtPCZ4oZYCitNeYuC/8UDvDvy0qvkiW/cgqNqRyzqSZa/s0mqNGjtKOoTm14zZpUauiQgVfqtQiZjq7Q27JNaSK5ExRcrGCXO1FJYh6jR6CFqK7bZdQZ4t8g0rSlPfP1RdBtqaa9diqtzJkQ9duSryi2brQXbxDwbRUpFMBHjRj8+Nt7GDKgvph9okW7LX47gu0SpGnnFQ1S1lYldOsC7hYteR574ZuKs7Ei1lBsfdz7IZoxzzCVmmVqaSySzQbBVAWDek+N4jh9E/4VqZrJjPwiv9BC1XcvOWgO8275CVyBPvAtTVlDJfZkaZGU7NpqBogAj/xEHkeAuJihWYCxGN6e8+9JtSegFXF1TrhhLGP1fak3pebgPz192/8gB4d/6WT7+GdYnpH7hH/DJzzFiYPn/vjW0SgNpTNuPIZoAEZv8tlGw4+RLxy+ZjnKa5NdFoC7UaW0aduoYse6+bXg1DLg6UfRYwmhGEjqPvF75U558SANrElK/+MdpXvmqBpaXOa/MTZaa1DOcSiLaw9j0NNNst3c+63c7EKTpkvKHzu6bPbP0RkuHAVcbRY8ijP46MIbQeeT1mhA+5PV/inyDdQipf8LTvMXbwvoDy7IruDNVZKTfV4CTSRUYdybUCnGU7KUTDxLgCknqUm5aAW6/1p6eMsOYsphLzsHrE0Y/P5bQedx1F/4yPHnMB3/IOoTU9+BL8PhtjuFKBpZXnYNJxTuv+2XqolKR2UQgHhS5novuxVySJhBNRF3SoKK1XZbbXjVwWNyOjlqWJjrWJIy+P5bQedyldNScP+HZ61xKSK3jyrz+NiHG1hcOLL/+P+PDF2gOkekKGiNWKgJ+8Z/x8Iv4DdQHzcpZyF4v19I27w9/yPGDFQvmEpKtqv/TLiWMfn4sofMm9eAH8Ao0zzh7h4sJqYtxZd5/D7hkYPneDzl5idlzNHcIB0jVlQ+8ULzw/nc5/ojzl2juE0apD7LRnJxe04dMz2iOCFNtGFpTuXA5AhcTRo8mdN4kz30nVjEC4YTZQy4gpC7GlTlrePKhGsKKgeXpCYeO0MAd/GH7yKQUlXPLOasOH3FnSphjHuDvEu4gB8g66oNbtr6eMbFIA4fIBJkgayoXriw2XEDQPJrQeROAlY6aeYOcMf+IVYTU3XFlZufMHinGywaW3YLpObVBAsbjF4QJMsVUSayjk4voPsHJOQfPWDhCgDnmDl6XIRerD24HsGtw86RMHOLvVSHrKBdeVE26gKB5NKHzaIwLOmrqBWJYZDLhASG16c0Tn+CdRhWDgWXnqRZUTnPIHuMJTfLVpkoYy5CzylHVTGZMTwkGAo2HBlkQplrJX6U+uF1wZz2uwS1SQ12IqWaPuO4baZaEFBdukksJmkcTOm+YJSvoqPFzxFA/YUhIvWxcmSdPWTWwbAKVp6rxTtPFUZfKIwpzm4IoMfaYQLWgmlG5FME2gdBgm+J7J+rtS/XBbaVLsR7bpPQnpMFlo2doWaVceHk9+MkyguZNCJ1He+kuHTWyQAzNM5YSUg/GlTk9ZunAsg1qELVOhUSAK0LABIJHLKbqaEbHZLL1VA3VgqoiOKXYiS+HRyaEKgsfIqX64HYWbLRXy/qWoylIV9gudL1OWBNgBgTNmxA6b4txDT4gi3Ri7xFSLxtXpmmYnzAcWDZgY8d503LFogz5sbonDgkKcxGsWsE1OI+rcQtlgBBCSOKD1mtqYpIU8cTvBmAT0yZe+zUzeY92fYjTtGipXLhuR0ePoHk0ofNWBX+lo8Z7pAZDk8mEw5L7dVyZZoE/pTewbI6SNbiAL5xeygW4xPRuLCGbhcO4RIeTMFYHEJkYyEO9HmJfXMDEj/LaH781wHHZEtqSQ/69UnGpzH7LKIAZEDSPJnTesJTUa+rwTepI9dLJEawYV+ZkRn9g+QirD8vF8Mq0jFQ29js6kCS3E1+jZIhgPNanHdHFqFvPJLHqFwQqbIA4jhDxcNsOCCQLDomaL/dr5lyJaJU6FxPFjO3JOh3kVMcROo8u+C+jo05GjMF3P3/FuDLn5x2M04xXULPwaS6hBYki+MrMdZJSgPHlcB7nCR5bJ9Kr5ACUn9jk5kivdd8tk95SOGrtqu9lr2IhK65ZtEl7ZKrp7DrqwZfRUSN1el7+7NJxZbywOC8neNKTch5vsTEMNsoCCqHBCqIPRjIPkm0BjvFODGtto99rCl+d3wmHkW0FPdpZtC7MMcVtGFQjJLX5bdQ2+x9ypdc313uj8xlsrfuLgWXz1cRhZvJYX0iNVBRcVcmCXZs6aEf3RQF2WI/TcCbKmGU3IOoDJGDdDub0+hYckt6PlGu2BcxmhbTdj/klhccLGJMcqRjMJP1jW2ETqLSWJ/29MAoORluJ+6LPffBZbi5gqi5h6catQpmOT7/OFf5UorRpLzCqcMltBLhwd1are3kztrSzXO0LUbXRQcdLh/RdSZ+swRm819REDrtqzC4es6Gw4JCKlSnjYVpo0xeq33PrADbFLL3RuCmObVmPN+24kfa+AojDuM4umKe2QwCf6EN906HwjujaitDs5o0s1y+k3lgbT2W2i7FJdnwbLXhJUBq/9liTctSmFC/0OqUinb0QddTWamtjbHRFuWJJ6NpqZ8vO3fZJ37Db+2GkaPYLGHs7XTTdiFQJ68SkVJFVmY6McR5UycflNCsccHFaV9FNbR4NttLxw4pQ7wJd066Z0ohVbzihaxHVExd/ay04oxUKWt+AsdiQ9OUyZ2krzN19IZIwafSTFgIBnMV73ADj7V/K8u1MaY2sJp2HWm0f41tqwajEvdHWOJs510MaAqN4aoSiPCXtN2KSi46dUxHdaMquar82O1x5jqhDGvqmoE9LfxcY3zqA7/x3HA67r9ZG4O6Cuxu12/+TP+eLP+I+HErqDDCDVmBDO4larujNe7x8om2rMug0MX0rL1+IWwdwfR+p1TNTyNmVJ85ljWzbWuGv8/C7HD/izjkHNZNYlhZcUOKVzKFUxsxxN/kax+8zPWPSFKw80rJr9Tizyj3o1gEsdwgWGoxPezDdZ1TSENE1dLdNvuKL+I84nxKesZgxXVA1VA1OcL49dFlpFV5yJMhzyCmNQ+a4BqusPJ2bB+xo8V9u3x48VVIEPS/mc3DvAbXyoYr6VgDfh5do5hhHOCXMqBZUPhWYbWZECwVJljLgMUWOCB4MUuMaxGNUQDVI50TQ+S3kFgIcu2qKkNSHVoM0SHsgoZxP2d5HH8B9woOk4x5bPkKtAHucZsdykjxuIpbUrSILgrT8G7G5oCW+K0990o7E3T6AdW4TilH5kDjds+H64kS0mz24grtwlzDHBJqI8YJQExotPvoC4JBq0lEjjQkyBZ8oH2LnRsQ4Hu1QsgDTJbO8fQDnllitkxuVskoiKbRF9VwzMDvxHAdwB7mD9yCplhHFEyUWHx3WtwCbSMMTCUCcEmSGlg4gTXkHpZXWQ7kpznK3EmCHiXInqndkQjunG5kxTKEeGye7jWz9cyMR2mGiFQ15ENRBTbCp+Gh86vAyASdgmJq2MC6hoADQ3GosP0QHbnMHjyBQvQqfhy/BUbeHd5WY/G/9LK/8Ka8Jd7UFeNWEZvzPb458Dn8DGLOe3/wGL/4xP+HXlRt+M1PE2iLhR8t+lfgxsuh7AfO2AOf+owWhSZRYQbd622hbpKWKuU+XuvNzP0OseRDa+mObgDHJUSc/pKx31QdKffQ5OIJpt8GWjlgTwMc/w5MPCR/yl1XC2a2Yut54SvOtMev55Of45BOat9aWG27p2ZVORRvnEk1hqWMVUmqa7S2YtvlIpspuF1pt0syuZS2NV14mUidCSfzQzg+KqvIYCMljIx2YK2AO34fX4GWdu5xcIAb8MzTw+j/lyWM+Dw/gjs4GD6ehNgA48kX/AI7XXM/XAN4WHr+9ntywqoCakCqmKP0rmQrJJEErG2Upg1JObr01lKQy4jskWalKYfJ/EDLMpjNSHFEUAde2fltaDgmrNaWQ9+AAb8I5vKjz3L1n1LriB/BXkG/wwR9y/oRX4LlioHA4LzP2inzRx/DWmutRweFjeP3tNeSGlaE1Fde0OS11yOpmbIp2u/jF1n2RRZviJM0yBT3IZl2HWImKjQOxIyeU325b/qWyU9Moj1o07tS0G7qJDoGHg5m8yeCxMoEH8GU45tnrNM84D2l297DQ9t1YP7jki/7RmutRweEA77/HWXOh3HCxkRgldDQkAjNTMl2Iloc1qN5JfJeeTlyTRzxURTdn1Ixv2uKjs12AbdEWlBtmVdk2k7FFwj07PCZ9XAwW3dG+8xKzNFr4EnwBZpy9Qzhh3jDXebBpYcpuo4fQ44u+fD1dweEnHzI7v0xuuOALRUV8rXpFyfSTQYkhd7IHm07jpyhlkCmI0ALYqPTpUxXS+z4jgDj1Pflvmz5ecuItpIBxyTHpSTGWd9g1ApfD/bvwUhL4nT1EzqgX7cxfCcNmb3mPL/qi9SwTHJ49oj5ZLjccbTG3pRmlYi6JCG0mQrAt1+i2UXTZ2dv9IlQpN5naMYtviaXlTrFpoMsl3bOAFEa8sqPj2WCMrx3Yjx99qFwO59Aw/wgx+HlqNz8oZvA3exRDvuhL1jMQHPaOJ0+XyA3fp1OfM3qObEVdhxjvynxNMXQV4+GJyvOEFqeQBaIbbO7i63rpxCltdZShPFxkjM2FPVkn3TG+Rp9pO3l2RzFegGfxGDHIAh8SteR0C4HopXzRF61nheDw6TFN05Ebvq8M3VKKpGjjO6r7nhudTEGMtYM92HTDaR1FDMXJ1eThsbKfywyoWwrzRSXkc51flG3vIid62h29bIcFbTGhfV+faaB+ohj7dPN0C2e2lC96+XouFByen9AsunLDJZ9z7NExiUc0OuoYW6UZkIyx2YUR2z6/TiRjyKMx5GbbjLHvHuf7YmtKghf34LJfx63Yg8vrvN2zC7lY0x0tvKezo4HmGYDU+Gab6dFL+KI761lDcNifcjLrrr9LWZJctG1FfU1uwhoQE22ObjdfkSzY63CbU5hzs21WeTddH2BaL11Gi7lVdlxP1nkxqhnKhVY6knS3EPgVGg1JpN5cP/hivujOelhXcPj8HC/LyI6MkteVjlolBdMmF3a3DbsuAYhL44dxzthWSN065xxUd55Lmf0wRbOYOqH09/o9WbO2VtFdaMb4qBgtFJoT1SqoN8wPXMoXLb3p1PUEhxfnnLzGzBI0Ku7FxrKsNJj/8bn/H8fPIVOd3rfrklUB/DOeO+nkghgSPzrlPxluCMtOnDL4Yml6dK1r3vsgMxgtPOrMFUZbEUbTdIzii5beq72G4PD0DKnwjmBULUVFmy8t+k7fZ3pKc0Q4UC6jpVRqS9Umv8bxw35flZVOU1X7qkjnhZlsMbk24qQ6Hz7QcuL6sDC0iHHki96Uh2UdvmgZnjIvExy2TeJdMDZNSbdZyAHe/Yd1xsQhHiKzjh7GxQ4yqMPaywPkjMamvqrYpmO7Knad+ZQC5msCuAPWUoxrxVhrGv7a+KLXFhyONdTMrZ7ke23qiO40ZJUyzgYyX5XyL0mV7NiUzEs9mjtbMN0dERqwyAJpigad0B3/zRV7s4PIfXSu6YV/MK7+OrYe/JvfGMn/PHJe2fyUdtnFrKRNpXV0Y2559aWPt/G4BlvjTMtXlVIWCnNyA3YQBDmYIodFz41PvXPSa6rq9lWZawZ4dP115HXV/M/tnFkkrBOdzg6aP4pID+MZnTJ1SuuB6iZlyiox4HT2y3YBtkUKWooacBQUDTpjwaDt5poBHl1/HXltwP887lKKXxNUEyPqpGTyA699UqY/lt9yGdlUKra0fFWS+36iylVWrAyd7Uw0CZM0z7xKTOduznLIjG2Hx8cDPLb+OvK6Bv7n1DYci4CxUuRxrjBc0bb4vD3rN5Zz36ntLb83eVJIB8LiIzCmn6SMPjlX+yNlTjvIGjs+QzHPf60Aj62/jrzG8j9vYMFtm1VoRWCJdmw7z9N0t+c8cxZpPeK4aTRicS25QhrVtUp7U578chk4q04Wx4YoQSjFryUlpcQ1AbxZ/XVMknIU//OGl7Q6z9Zpxi0+3yFhSkjUDpnCIUhLWVX23KQ+L9vKvFKI0ZWFQgkDLvBoylrHNVmaw10zwCPrr5tlodfnf94EWnQ0lFRWy8pW9LbkLsyUVDc2NSTHGDtnD1uMtchjbCeb1mpxFP0YbcClhzdLu6lfO8Bj6q+bdT2sz/+8SZCV7VIxtt0DUn9L7r4cLYWDSXnseEpOGFuty0qbOVlS7NNzs5FOGJUqQpl2Q64/yBpZf90sxbE+//PGdZ02HSipCbmD6NItmQ4Lk5XUrGpDMkhbMm2ZVheNYV+VbUWTcv99+2NyX1VoafSuC+AN6q9bFIMv5X/eagNWXZxEa9JjlMwNWb00akGUkSoepp1/yRuuqHGbUn3UdBSTxBU6SEVklzWRUkPndVvw2PrrpjvxOvzPmwHc0hpmq82npi7GRro8dXp0KXnUQmhZbRL7NEVp1uuZmO45vuzKsHrktS3GLWXODVjw+vXXLYx4Hf7njRPd0i3aoAGX6W29GnaV5YdyDj9TFkakje7GHYzDoObfddHtOSpoi2SmzJHrB3hM/XUDDEbxP2/oosszcRlehWXUvzHv4TpBVktHqwenFo8uLVmy4DKLa5d3RtLrmrM3aMFr1183E4sewf+85VWeg1c5ag276NZrM9IJVNcmLEvDNaV62aq+14IAOGFsBt973Ra8Xv11YzXwNfmft7Jg2oS+XOyoC8/cwzi66Dhmgk38kUmP1CUiYWOX1bpD2zWXt2FCp7uq8703APAa9dfNdscR/M/bZLIyouVxqJfeWvG9Je+JVckHQ9+CI9NWxz+blX/KYYvO5n2tAP/vrlZ7+8/h9y+9qeB/Hnt967e5mevX10rALDWK//FaAT5MXdBXdP0C/BAes792c40H+AiAp1e1oH8HgH94g/Lttx1gp63op1eyoM/Bvw5/G/7xFbqJPcCXnmBiwDPb/YKO4FX4OjyCb289db2/Noqicw4i7N6TVtoz8tNwDH+8x/i6Ae7lmaQVENzJFb3Di/BFeAwz+Is9SjeQySpPqbLFlNmyz47z5a/AF+AYFvDmHqibSXTEzoT4Gc3OALaqAP4KPFUJ6n+1x+rGAM6Zd78bgJ0a8QN4GU614vxwD9e1Amy6CcskNrczLx1JIp6HE5UZD/DBHrFr2oNlgG4Odv226BodoryjGJ9q2T/AR3vQrsOCS0ctXZi3ruLlhpFDJYl4HmYtjQCP9rhdn4suySLKDt6wLcC52h8xPlcjju1fn+yhuw4LZsAGUuo2b4Fx2UwQu77uqRHXGtg92aN3tQCbFexc0uk93vhTXbct6y7MulLycoUljx8ngDMBg1tvJjAazpEmOtxlzclvj1vQf1Tx7QlPDpGpqgtdSKz/d9/hdy1vTfFHSmC9dGDZbLiezz7Ac801HirGZsWjydfZyPvHXL/Y8Mjzg8BxTZiuwKz4Eb8sBE9zznszmjvFwHKPIWUnwhqfVRcd4Ck0K6ate48m1oOfrX3/yOtvAsJ8zsPAM89sjnddmuLuDPjX9Bu/L7x7xpMzFk6nWtyQfPg278Gn4Aekz2ZgOmU9eJ37R14vwE/BL8G3aibCiWMWWDQ0ZtkPMnlcGeAu/Ag+8ZyecU5BPuy2ILD+sQqyZhAKmn7XZd+jIMTN9eBL7x95xVLSX4On8EcNlXDqmBlqS13jG4LpmGbkF/0CnOi3H8ETOIXzmnmtb0a16Tzxj1sUvQCBiXZGDtmB3KAefPH94xcUa/6vwRn80GOFyjEXFpba4A1e8KQfFF+259tx5XS4egYn8fQsLGrqGrHbztr+uByTahWuL1NUGbDpsnrwBfePPwHHIf9X4RnM4Z2ABWdxUBlqQ2PwhuDxoS0vvqB1JzS0P4h2nA/QgTrsJFn+Y3AOjs9JFC07CGWX1oNX3T/yHOzgDjwPn1PM3g9Jk9lZrMEpxnlPmBbjyo2+KFXRU52TJM/2ALcY57RUzjObbjqxVw++4P6RAOf58pcVsw9Daje3htriYrpDOonre3CudSe6bfkTEgHBHuDiyu5MCsc7BHhYDx7ePxLjqigXZsw+ijMHFhuwBmtoTPtOxOrTvYJDnC75dnUbhfwu/ZW9AgYd+peL68HD+0emKquiXHhWjJg/UrkJYzuiaL3E9aI/ytrCvAd4GcYZMCkSQxfUg3v3j8c4e90j5ZTPdvmJJGHnOCI2nHS8081X013pHuBlV1gB2MX1YNmWLHqqGN/TWmG0y6clJWthxNUl48q38Bi8vtMKyzzpFdSDhxZ5WBA5ZLt8Jv3895DduBlgbPYAj8C4B8hO68FDkoh5lydC4FiWvBOVqjYdqjiLv92t8yPDjrDaiHdUD15qkSURSGmXJwOMSxWAXYwr3zaAufJ66l+94vv3AO+vPcD7aw/w/toDvL/2AO+vPcD7aw/wHuD9tQd4f+0B3l97gPfXHuD9tQd4f+0B3l97gG8LwP8G/AL8O/A5OCq0Ys2KIdv/qOIXG/4mvFAMF16gZD+2Xvu/B8as5+8bfllWyg0zaNO5bfXj6vfhhwD86/Aq3NfRS9t9WPnhfnvCIw/CT8GLcFTMnpntdF/z9V+PWc/vWoIH+FL3Znv57PitcdGP4R/C34avw5fgRVUInCwbsn1yyA8C8zm/BH8NXoXnVE6wVPjdeCI38kX/3+Ct9dbz1pTmHFRu+Hm4O9Ch3clr99negxfwj+ER/DR8EV6B5+DuQOnTgUw5rnkY+FbNU3gNXh0o/JYTuWOvyBf9FvzX663HH/HejO8LwAl8Hl5YLTd8q7sqA3wbjuExfAFegQdwfyDoSkWY8swzEf6o4Qyewefg+cHNbqMQruSL/u/WWc+E5g7vnnEXgDmcDeSGb/F4cBcCgT+GGRzDU3hZYburAt9TEtHgbM6JoxJ+6NMzzTcf6c2bycv2+KK/f+l6LBzw5IwfqZJhA3M472pWT/ajKxnjv4AFnMEpnBTPND6s2J7qHbPAqcMK74T2mZ4VGB9uJA465It+/eL1WKhYOD7xHOkr1ajK7d0C4+ke4Hy9qXZwpgLr+Znm/uNFw8xQOSy8H9IzjUrd9+BIfenYaylf9FsXr8fBAadnPIEDna8IBcwlxnuA0/Wv6GAWPd7dDIKjMdSWueAsBj4M7TOd06qBbwDwKr7oleuxMOEcTuEZTHWvDYUO7aHqAe0Bbq+HEFRzOz7WVoTDQkVds7A4sIIxfCQdCefFRoIOF/NFL1mPab/nvOakSL/Q1aFtNpUb/nFOVX6gzyg/1nISyDfUhsokIzaBR9Kxm80s5mK+6P56il1jXic7nhQxsxSm3OwBHl4fFdLqi64nDQZvqE2at7cWAp/IVvrN6/BFL1mPhYrGMBfOi4PyjuSGf6wBBh7p/FZTghCNWGgMzlBbrNJoPJX2mW5mwZfyRffXo7OFi5pZcS4qZUrlViptrXtw+GQoyhDPS+ANjcGBNRiLCQDPZPMHuiZfdFpPSTcQwwKYdRNqpkjm7AFeeT0pJzALgo7g8YYGrMHS0iocy+YTm2vyRUvvpXCIpQ5pe666TJrcygnScUf/p0NDs/iAI/nqDHC8TmQT8x3NF91l76oDdQGwu61Z6E0ABv7uO1dbf/37Zlv+Zw/Pbh8f1s4Avur6657/+YYBvur6657/+YYBvur6657/+YYBvur6657/+aYBvuL6657/+VMA8FXWX/f8zzcN8BXXX/f8zzcNMFdbf93zP38KLPiK6697/uebtuArrr/u+Z9vGmCusP6653/+1FjwVdZf9/zPN7oHX339dc//fNMu+irrr3v+50+Bi+Zq6697/uebA/jz8Pudf9ht/fWv517J/XUzAP8C/BAeX9WCDrUpZ3/dEMBxgPcfbtTVvsYV5Yn32u03B3Ac4P3b8I+vxNBKeeL9dRMAlwO83959qGO78sT769oB7g3w/vGVYFzKE++v6wV4OMD7F7tckFkmT7y/rhHgpQO8b+4Y46XyxPvrugBeNcB7BRiX8sT767oAvmCA9woAHsoT76+rBJjLBnh3txOvkifeX1dswZcO8G6N7sXyxPvr6i340gHe3TnqVfLE++uKAb50gHcXLnrX8sR7gNdPRqwzwLu7Y/FO5Yn3AK9jXCMGeHdgxDuVJ75VAI8ljP7PAb3/RfjcZfePHBB+79dpfpH1CanN30d+mT1h9GqAxxJGM5LQeeQ1+Tb+EQJrElLb38VHQ94TRq900aMIo8cSOo+8Dp8QfsB8zpqE1NO3OI9Zrj1h9EV78PqE0WMJnUdeU6E+Jjyk/hbrEFIfeWbvId8H9oTRFwdZaxJGvziW0Hn0gqYB/wyZ0PwRlxJST+BOw9m77Amj14ii1yGM/txYQudN0qDzGe4EqfA/5GJCagsHcPaEPWH0esekSwmjRxM6b5JEcZ4ww50ilvAOFxBSx4yLW+A/YU8YvfY5+ALC6NGEzhtmyZoFZoarwBLeZxUhtY4rc3bKnjB6TKJjFUHzJoTOozF2YBpsjcyxDgzhQ1YRUse8+J4wenwmaylB82hC5w0zoRXUNXaRBmSMQUqiWSWkLsaVqc/ZE0aPTFUuJWgeTei8SfLZQeMxNaZSIzbII4aE1Nmr13P2hNHjc9E9guYNCZ032YlNwESMLcZiLQHkE4aE1BFg0yAR4z1h9AiAGRA0jyZ03tyIxWMajMPWBIsxYJCnlITU5ShiHYdZ94TR4wCmSxg9jtB5KyPGYzymAYexWEMwAPIsAdYdV6aObmNPGD0aYLoEzaMJnTc0Ygs+YDw0GAtqxBjkuP38bMRWCHn73xNGjz75P73WenCEJnhwyVe3AEe8TtKdJcYhBl97wuhNAObK66lvD/9J9NS75v17wuitAN5fe4D31x7g/bUHeH/tAd5fe4D3AO+vPcD7aw/w/toDvL/2AO+vPcD7aw/w/toDvAd4f/24ABzZ8o+KLsSLS+Pv/TqTb3P4hKlQrTGh+fbIBT0Axqznnb+L/V2mb3HkN5Mb/nEHeK7d4IcDld6lmDW/iH9E+AH1MdOw/Jlu2T1xNmY98sv4wHnD7D3uNHu54WUuOsBTbQuvBsPT/UfzNxGYzwkP8c+Yz3C+r/i6DcyRL/rZ+utRwWH5PmfvcvYEt9jLDS/bg0/B64DWKrQM8AL8FPwS9beQCe6EMKNZYJol37jBMy35otdaz0Bw2H/C2Smc7+WGB0HWDELBmOByA3r5QONo4V+DpzR/hFS4U8wMW1PXNB4TOqYz9urxRV++ntWCw/U59Ty9ebdWbrgfRS9AYKKN63ZokZVygr8GZ/gfIhZXIXPsAlNjPOLBby5c1eOLvmQ9lwkOy5x6QV1j5TYqpS05JtUgUHUp5toHGsVfn4NX4RnMCe+AxTpwmApTYxqMxwfCeJGjpXzRF61nbcHhUBPqWze9svwcHJ+S6NPscKrEjug78Dx8Lj3T8D4YxGIdxmJcwhi34fzZUr7olevZCw5vkOhoClq5zBPZAnygD/Tl9EzDh6kl3VhsHYcDEb+hCtJSvuiV69kLDm+WycrOTArHmB5/VYyP6jOVjwgGawk2zQOaTcc1L+aLXrKeveDwZqlKrw8U9Y1p66uK8dEzdYwBeUQAY7DbyYNezBfdWQ97weEtAKYQg2xJIkuveAT3dYeLGH+ShrWNwZgN0b2YL7qznr3g8JYAo5bQBziPjx7BPZ0d9RCQp4UZbnFdzBddor4XHN4KYMrB2qHFRIzzcLAHQZ5the5ovui94PCWAPefaYnxIdzRwdHCbuR4B+tbiy96Lzi8E4D7z7S0mEPd+eqO3cT53Z0Y8SV80XvB4Z0ADJi/f7X113f+7p7/+UYBvur6657/+YYBvur6657/+aYBvuL6657/+aYBvuL6657/+aYBvuL6657/+aYBvuL6657/+VMA8FXWX/f8z58OgK+y/rrnf75RgLna+uue//lTA/CV1V/3/M837aKvvv6653++UQvmauuve/7nTwfAV1N/3fM/fzr24Cuuv+75nz8FFnxl9dc9//MOr/8/glixwRuUfM4AAAAASUVORK5CYII='; } - getSearchTexture() { return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAAAhCAAAAABIXyLAAAAAOElEQVRIx2NgGAWjYBSMglEwEICREYRgFBZBqDCSLA2MGPUIVQETE9iNUAqLR5gIeoQKRgwXjwAAGn4AtaFeYLEAAAAASUVORK5CYII='; } + dispose() { + + this.edgesRT.dispose(); + this.weightsRT.dispose(); + this.areaTexture.dispose(); + this.searchTexture.dispose(); + this.materialEdges.dispose(); + this.materialWeights.dispose(); + this.materialBlend.dispose(); + this.fsQuad.dispose(); + + } } diff --git a/examples/js/postprocessing/SSAARenderPass.js b/examples/js/postprocessing/SSAARenderPass.js index 6d7b8c5e05080a..65290455c851ce 100644 --- a/examples/js/postprocessing/SSAARenderPass.js +++ b/examples/js/postprocessing/SSAARenderPass.js @@ -18,9 +18,9 @@ this.scene = scene; this.camera = camera; this.sampleLevel = 4; // specified as n, where the number of samples is 2^n, so sampleLevel = 4, is 2^4 samples, 16. + this.unbiased = true; - this.unbiased = true; // as we need to clear the buffer in this pass, clearColor must be set to something, defaults to black. - + // as we need to clear the buffer in this pass, clearColor must be set to something, defaults to black. this.clearColor = clearColor !== undefined ? clearColor : 0x000000; this.clearAlpha = clearAlpha !== undefined ? clearAlpha : 0; this._oldClearColor = new THREE.Color(); @@ -39,7 +39,6 @@ this.fsQuad = new THREE.FullScreenQuad( this.copyMaterial ); } - dispose() { if ( this.sampleRenderTarget ) { @@ -49,14 +48,15 @@ } - } + this.copyMaterial.dispose(); + this.fsQuad.dispose(); + } setSize( width, height ) { if ( this.sampleRenderTarget ) this.sampleRenderTarget.setSize( width, height ); } - render( renderer, writeBuffer, readBuffer ) { if ( ! this.sampleRenderTarget ) { @@ -67,7 +67,6 @@ } const jitterOffsets = _JitterVectors[ Math.max( 0, Math.min( this.sampleLevel, 5 ) ) ]; - const autoClear = renderer.autoClear; renderer.autoClear = false; renderer.getClearColor( this._oldClearColor ); @@ -84,26 +83,28 @@ height: readBuffer.height }; const originalViewOffset = Object.assign( {}, this.camera.view ); - if ( originalViewOffset.enabled ) Object.assign( viewOffset, originalViewOffset ); // render the scene multiple times, each slightly jitter offset from the last and accumulate the results. + if ( originalViewOffset.enabled ) Object.assign( viewOffset, originalViewOffset ); + // render the scene multiple times, each slightly jitter offset from the last and accumulate the results. for ( let i = 0; i < jitterOffsets.length; i ++ ) { const jitterOffset = jitterOffsets[ i ]; - if ( this.camera.setViewOffset ) { - this.camera.setViewOffset( viewOffset.fullWidth, viewOffset.fullHeight, viewOffset.offsetX + jitterOffset[ 0 ] * 0.0625, viewOffset.offsetY + jitterOffset[ 1 ] * 0.0625, // 0.0625 = 1 / 16 + this.camera.setViewOffset( viewOffset.fullWidth, viewOffset.fullHeight, viewOffset.offsetX + jitterOffset[ 0 ] * 0.0625, viewOffset.offsetY + jitterOffset[ 1 ] * 0.0625, + // 0.0625 = 1 / 16 + viewOffset.width, viewOffset.height ); } let sampleWeight = baseSampleWeight; - if ( this.unbiased ) { // the theory is that equal weights for each sample lead to an accumulation of rounding errors. // The following equation varies the sampleWeight per sample so that it is uniformly distributed // across a range of values whose rounding errors cancel each other out. + const uniformCenteredDistribution = - 0.5 + ( i + 0.5 ) / jitterOffsets.length; sampleWeight += roundingRange * uniformCenteredDistribution; @@ -115,7 +116,6 @@ renderer.clear(); renderer.render( this.scene, this.camera ); renderer.setRenderTarget( this.renderToScreen ? null : writeBuffer ); - if ( i === 0 ) { renderer.setClearColor( 0x000000, 0.0 ); @@ -142,13 +142,13 @@ } - } // These jitter vectors are specified in integers because it is easier. + } + + // These jitter vectors are specified in integers because it is easier. // I am assuming a [-8,8) integer grid, but it needs to be mapped onto [-0.5,0.5) // before being used, thus these integers need to be scaled by 1/16. // // Sample patterns reference: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476218%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 - - const _JitterVectors = [[[ 0, 0 ]], [[ 4, 4 ], [ - 4, - 4 ]], [[ - 2, - 6 ], [ 6, - 2 ], [ - 6, 2 ], [ 2, 6 ]], [[ 1, - 3 ], [ - 1, 3 ], [ 5, 1 ], [ - 3, - 5 ], [ - 5, 5 ], [ - 7, - 1 ], [ 3, 7 ], [ 7, - 7 ]], [[ 1, 1 ], [ - 1, - 3 ], [ - 3, 2 ], [ 4, - 1 ], [ - 5, - 2 ], [ 2, 5 ], [ 5, 3 ], [ 3, - 5 ], [ - 2, 6 ], [ 0, - 7 ], [ - 4, - 6 ], [ - 6, 4 ], [ - 8, 0 ], [ 7, - 4 ], [ 6, 7 ], [ - 7, - 8 ]], [[ - 4, - 7 ], [ - 7, - 5 ], [ - 3, - 5 ], [ - 5, - 4 ], [ - 1, - 4 ], [ - 2, - 2 ], [ - 6, - 1 ], [ - 4, 0 ], [ - 7, 1 ], [ - 1, 2 ], [ - 6, 3 ], [ - 3, 3 ], [ - 7, 6 ], [ - 3, 6 ], [ - 5, 7 ], [ - 1, 7 ], [ 5, - 7 ], [ 1, - 6 ], [ 6, - 5 ], [ 4, - 4 ], [ 2, - 3 ], [ 7, - 2 ], [ 1, - 1 ], [ 4, - 1 ], [ 2, 1 ], [ 6, 2 ], [ 0, 4 ], [ 4, 4 ], [ 2, 5 ], [ 7, 5 ], [ 5, 6 ], [ 3, 7 ]]]; THREE.SSAARenderPass = SSAARenderPass; diff --git a/examples/js/postprocessing/SSAOPass.js b/examples/js/postprocessing/SSAOPass.js index 9e371df2385365..b3523a244b850e 100644 --- a/examples/js/postprocessing/SSAOPass.js +++ b/examples/js/postprocessing/SSAOPass.js @@ -17,24 +17,34 @@ this.output = 0; this.minDistance = 0.005; this.maxDistance = 0.1; - this._visibilityCache = new Map(); // + this._visibilityCache = new Map(); + + // this.generateSampleKernel(); - this.generateRandomKernelRotations(); // beauty render target + this.generateRandomKernelRotations(); + + // beauty render target const depthTexture = new THREE.DepthTexture(); depthTexture.format = THREE.DepthStencilFormat; depthTexture.type = THREE.UnsignedInt248Type; - this.beautyRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height ); // normal render target with depth buffer + this.beautyRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height ); + + // normal render target with depth buffer this.normalRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, depthTexture: depthTexture - } ); // ssao render target + } ); + + // ssao render target this.ssaoRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height ); - this.blurRenderTarget = this.ssaoRenderTarget.clone(); // ssao material + this.blurRenderTarget = this.ssaoRenderTarget.clone(); + + // ssao material if ( THREE.SSAOShader === undefined ) { @@ -58,10 +68,14 @@ this.ssaoMaterial.uniforms[ 'cameraFar' ].value = this.camera.far; this.ssaoMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height ); this.ssaoMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix ); - this.ssaoMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse ); // normal material + this.ssaoMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse ); + + // normal material this.normalMaterial = new THREE.MeshNormalMaterial(); - this.normalMaterial.blending = THREE.NoBlending; // blur material + this.normalMaterial.blending = THREE.NoBlending; + + // blur material this.blurMaterial = new THREE.ShaderMaterial( { defines: Object.assign( {}, THREE.SSAOBlurShader.defines ), @@ -70,7 +84,9 @@ fragmentShader: THREE.SSAOBlurShader.fragmentShader } ); this.blurMaterial.uniforms[ 'tDiffuse' ].value = this.ssaoRenderTarget.texture; - this.blurMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height ); // material for rendering the depth + this.blurMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height ); + + // material for rendering the depth this.depthRenderMaterial = new THREE.ShaderMaterial( { defines: Object.assign( {}, THREE.SSAODepthShader.defines ), @@ -81,7 +97,9 @@ } ); this.depthRenderMaterial.uniforms[ 'tDepth' ].value = this.normalRenderTarget.depthTexture; this.depthRenderMaterial.uniforms[ 'cameraNear' ].value = this.camera.near; - this.depthRenderMaterial.uniforms[ 'cameraFar' ].value = this.camera.far; // material for rendering the content of a render target + this.depthRenderMaterial.uniforms[ 'cameraFar' ].value = this.camera.far; + + // material for rendering the content of a render target this.copyMaterial = new THREE.ShaderMaterial( { uniforms: THREE.UniformsUtils.clone( THREE.CopyShader.uniforms ), @@ -101,44 +119,55 @@ this.originalClearColor = new THREE.Color(); } - dispose() { // dispose render targets + this.beautyRenderTarget.dispose(); this.normalRenderTarget.dispose(); this.ssaoRenderTarget.dispose(); - this.blurRenderTarget.dispose(); // dispose materials + this.blurRenderTarget.dispose(); + + // dispose materials this.normalMaterial.dispose(); this.blurMaterial.dispose(); this.copyMaterial.dispose(); - this.depthRenderMaterial.dispose(); // dipsose full screen quad + this.depthRenderMaterial.dispose(); + + // dipsose full screen quad this.fsQuad.dispose(); } + render( renderer, writeBuffer /*, readBuffer, deltaTime, maskActive */ ) { - render( renderer, writeBuffer - /*, readBuffer, deltaTime, maskActive */ - ) { + if ( renderer.capabilities.isWebGL2 === false ) this.noiseTexture.format = THREE.LuminanceFormat; - if ( renderer.capabilities.isWebGL2 === false ) this.noiseTexture.format = THREE.LuminanceFormat; // render beauty + // render beauty renderer.setRenderTarget( this.beautyRenderTarget ); renderer.clear(); - renderer.render( this.scene, this.camera ); // render normals and depth (honor only meshes, points and lines do not contribute to SSAO) + renderer.render( this.scene, this.camera ); + + // render normals and depth (honor only meshes, points and lines do not contribute to SSAO) this.overrideVisibility(); this.renderOverride( renderer, this.normalMaterial, this.normalRenderTarget, 0x7777ff, 1.0 ); - this.restoreVisibility(); // render SSAO + this.restoreVisibility(); + + // render SSAO this.ssaoMaterial.uniforms[ 'kernelRadius' ].value = this.kernelRadius; this.ssaoMaterial.uniforms[ 'minDistance' ].value = this.minDistance; this.ssaoMaterial.uniforms[ 'maxDistance' ].value = this.maxDistance; - this.renderPass( renderer, this.ssaoMaterial, this.ssaoRenderTarget ); // render blur + this.renderPass( renderer, this.ssaoMaterial, this.ssaoRenderTarget ); + + // render blur - this.renderPass( renderer, this.blurMaterial, this.blurRenderTarget ); // output result to screen + this.renderPass( renderer, this.blurMaterial, this.blurRenderTarget ); + + // output result to screen switch ( this.output ) { @@ -147,29 +176,24 @@ this.copyMaterial.blending = THREE.NoBlending; this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer ); break; - case SSAOPass.OUTPUT.Blur: this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget.texture; this.copyMaterial.blending = THREE.NoBlending; this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer ); break; - case SSAOPass.OUTPUT.Beauty: this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture; this.copyMaterial.blending = THREE.NoBlending; this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer ); break; - case SSAOPass.OUTPUT.Depth: this.renderPass( renderer, this.depthRenderMaterial, this.renderToScreen ? null : writeBuffer ); break; - case SSAOPass.OUTPUT.Normal: this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.normalRenderTarget.texture; this.copyMaterial.blending = THREE.NoBlending; this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer ); break; - case SSAOPass.OUTPUT.Default: this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture; this.copyMaterial.blending = THREE.NoBlending; @@ -178,24 +202,22 @@ this.copyMaterial.blending = THREE.CustomBlending; this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer ); break; - default: console.warn( 'THREE.SSAOPass: Unknown output type.' ); } } - renderPass( renderer, passMaterial, renderTarget, clearColor, clearAlpha ) { // save original state renderer.getClearColor( this.originalClearColor ); const originalClearAlpha = renderer.getClearAlpha(); const originalAutoClear = renderer.autoClear; - renderer.setRenderTarget( renderTarget ); // setup pass state + renderer.setRenderTarget( renderTarget ); + // setup pass state renderer.autoClear = false; - if ( clearColor !== undefined && clearColor !== null ) { renderer.setClearColor( clearColor ); @@ -205,14 +227,14 @@ } this.fsQuad.material = passMaterial; - this.fsQuad.render( renderer ); // restore original state + this.fsQuad.render( renderer ); + // restore original state renderer.autoClear = originalAutoClear; renderer.setClearColor( this.originalClearColor ); renderer.setClearAlpha( originalClearAlpha ); } - renderOverride( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) { renderer.getClearColor( this.originalClearColor ); @@ -222,7 +244,6 @@ renderer.autoClear = false; clearColor = overrideMaterial.clearColor || clearColor; clearAlpha = overrideMaterial.clearAlpha || clearAlpha; - if ( clearColor !== undefined && clearColor !== null ) { renderer.setClearColor( clearColor ); @@ -233,14 +254,15 @@ this.scene.overrideMaterial = overrideMaterial; renderer.render( this.scene, this.camera ); - this.scene.overrideMaterial = null; // restore original state + this.scene.overrideMaterial = null; + + // restore original state renderer.autoClear = originalAutoClear; renderer.setClearColor( this.originalClearColor ); renderer.setClearAlpha( originalClearAlpha ); } - setSize( width, height ) { this.width = width; @@ -255,12 +277,10 @@ this.blurMaterial.uniforms[ 'resolution' ].value.set( width, height ); } - generateSampleKernel() { const kernelSize = this.kernelSize; const kernel = this.kernel; - for ( let i = 0; i < kernelSize; i ++ ) { const sample = new THREE.Vector3(); @@ -276,12 +296,10 @@ } } - generateRandomKernelRotations() { const width = 4, height = 4; - if ( THREE.SimplexNoise === undefined ) { console.error( 'THREE.SSAOPass: The pass relies on THREE.SimplexNoise.' ); @@ -291,7 +309,6 @@ const simplex = new THREE.SimplexNoise(); const size = width * height; const data = new Float32Array( size ); - for ( let i = 0; i < size; i ++ ) { const x = Math.random() * 2 - 1; @@ -307,7 +324,6 @@ this.noiseTexture.needsUpdate = true; } - overrideVisibility() { const scene = this.scene; @@ -320,7 +336,6 @@ } ); } - restoreVisibility() { const scene = this.scene; @@ -336,7 +351,6 @@ } } - SSAOPass.OUTPUT = { 'Default': 0, 'SSAO': 1, diff --git a/examples/js/postprocessing/SSRPass.js b/examples/js/postprocessing/SSRPass.js index da90479abeb33a..a605e9f00e0622 100644 --- a/examples/js/postprocessing/SSRPass.js +++ b/examples/js/postprocessing/SSRPass.js @@ -34,12 +34,10 @@ return this._selects; }, - set( val ) { if ( this._selects === val ) return; this._selects = val; - if ( Array.isArray( val ) ) { this.selective = true; @@ -55,7 +53,6 @@ } } - } ); this._bouncing = bouncing; Object.defineProperty( this, 'bouncing', { @@ -64,12 +61,10 @@ return this._bouncing; }, - set( val ) { if ( this._bouncing === val ) return; this._bouncing = val; - if ( val ) { this.ssrMaterial.uniforms[ 'tDiffuse' ].value = this.prevRenderTarget.texture; @@ -81,7 +76,6 @@ } } - } ); this.blur = true; this._distanceAttenuation = THREE.SSRShader.defines.DISTANCE_ATTENUATION; @@ -91,7 +85,6 @@ return this._distanceAttenuation; }, - set( val ) { if ( this._distanceAttenuation === val ) return; @@ -100,7 +93,6 @@ this.ssrMaterial.needsUpdate = true; } - } ); this._fresnel = THREE.SSRShader.defines.FRESNEL; Object.defineProperty( this, 'fresnel', { @@ -109,7 +101,6 @@ return this._fresnel; }, - set( val ) { if ( this._fresnel === val ) return; @@ -118,7 +109,6 @@ this.ssrMaterial.needsUpdate = true; } - } ); this._infiniteThick = THREE.SSRShader.defines.INFINITE_THICK; Object.defineProperty( this, 'infiniteThick', { @@ -127,7 +117,6 @@ return this._infiniteThick; }, - set( val ) { if ( this._infiniteThick === val ) return; @@ -136,8 +125,9 @@ this.ssrMaterial.needsUpdate = true; } + } ); - } ); // beauty render target with depth buffer + // beauty render target with depth buffer const depthTexture = new THREE.DepthTexture(); depthTexture.type = THREE.UnsignedShortType; @@ -148,30 +138,39 @@ magFilter: THREE.NearestFilter, depthTexture: depthTexture, depthBuffer: true - } ); //for bouncing + } ); + //for bouncing this.prevRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter - } ); // normal render target + } ); + + // normal render target this.normalRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, type: THREE.HalfFloatType - } ); // metalness render target + } ); + + // metalness render target this.metalnessRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter - } ); // ssr render target + } ); + + // ssr render target this.ssrRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter } ); this.blurRenderTarget = this.ssrRenderTarget.clone(); - this.blurRenderTarget2 = this.ssrRenderTarget.clone(); // this.blurRenderTarget3 = this.ssrRenderTarget.clone(); + this.blurRenderTarget2 = this.ssrRenderTarget.clone(); + // this.blurRenderTarget3 = this.ssrRenderTarget.clone(); + // ssr material if ( THREE.SSRShader === undefined ) { @@ -200,18 +199,26 @@ this.ssrMaterial.uniforms[ 'thickness' ].value = this.thickness; this.ssrMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height ); this.ssrMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix ); - this.ssrMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse ); // normal material + this.ssrMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse ); + + // normal material this.normalMaterial = new THREE.MeshNormalMaterial(); - this.normalMaterial.blending = THREE.NoBlending; // metalnessOn material + this.normalMaterial.blending = THREE.NoBlending; + + // metalnessOn material this.metalnessOnMaterial = new THREE.MeshBasicMaterial( { color: 'white' - } ); // metalnessOff material + } ); + + // metalnessOff material this.metalnessOffMaterial = new THREE.MeshBasicMaterial( { color: 'black' - } ); // blur material + } ); + + // blur material this.blurMaterial = new THREE.ShaderMaterial( { defines: Object.assign( {}, THREE.SSRBlurShader.defines ), @@ -220,7 +227,9 @@ fragmentShader: THREE.SSRBlurShader.fragmentShader } ); this.blurMaterial.uniforms[ 'tDiffuse' ].value = this.ssrRenderTarget.texture; - this.blurMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height ); // blur material 2 + this.blurMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height ); + + // blur material 2 this.blurMaterial2 = new THREE.ShaderMaterial( { defines: Object.assign( {}, THREE.SSRBlurShader.defines ), @@ -229,7 +238,10 @@ fragmentShader: THREE.SSRBlurShader.fragmentShader } ); this.blurMaterial2.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget.texture; - this.blurMaterial2.uniforms[ 'resolution' ].value.set( this.width, this.height ); // // blur material 3 + this.blurMaterial2.uniforms[ 'resolution' ].value.set( this.width, this.height ); + + // // blur material 3 + // this.blurMaterial3 = new THREE.ShaderMaterial({ // defines: Object.assign({}, THREE.SSRBlurShader.defines), // uniforms: THREE.UniformsUtils.clone(THREE.SSRBlurShader.uniforms), @@ -238,6 +250,7 @@ // }); // this.blurMaterial3.uniforms['tDiffuse'].value = this.blurRenderTarget2.texture; // this.blurMaterial3.uniforms['resolution'].value.set(this.width, this.height); + // material for rendering the depth this.depthRenderMaterial = new THREE.ShaderMaterial( { @@ -249,7 +262,9 @@ } ); this.depthRenderMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture; this.depthRenderMaterial.uniforms[ 'cameraNear' ].value = this.camera.near; - this.depthRenderMaterial.uniforms[ 'cameraFar' ].value = this.camera.far; // material for rendering the content of a render target + this.depthRenderMaterial.uniforms[ 'cameraFar' ].value = this.camera.far; + + // material for rendering the content of a render target this.copyMaterial = new THREE.ShaderMaterial( { uniforms: THREE.UniformsUtils.clone( THREE.CopyShader.uniforms ), @@ -263,24 +278,27 @@ blendEquation: THREE.AddEquation, blendSrcAlpha: THREE.SrcAlphaFactor, blendDstAlpha: THREE.OneMinusSrcAlphaFactor, - blendEquationAlpha: THREE.AddEquation // premultipliedAlpha:true, - + blendEquationAlpha: THREE.AddEquation + // premultipliedAlpha:true, } ); + this.fsQuad = new THREE.FullScreenQuad( null ); this.originalClearColor = new THREE.Color(); } - dispose() { // dispose render targets + this.beautyRenderTarget.dispose(); this.prevRenderTarget.dispose(); this.normalRenderTarget.dispose(); this.metalnessRenderTarget.dispose(); this.ssrRenderTarget.dispose(); this.blurRenderTarget.dispose(); - this.blurRenderTarget2.dispose(); // this.blurRenderTarget3.dispose(); + this.blurRenderTarget2.dispose(); + // this.blurRenderTarget3.dispose(); + // dispose materials this.normalMaterial.dispose(); @@ -289,20 +307,19 @@ this.blurMaterial.dispose(); this.blurMaterial2.dispose(); this.copyMaterial.dispose(); - this.depthRenderMaterial.dispose(); // dipsose full screen quad + this.depthRenderMaterial.dispose(); + + // dipsose full screen quad this.fsQuad.dispose(); } - - render( renderer, writeBuffer - /*, readBuffer, deltaTime, maskActive */ - ) { + render( renderer, writeBuffer /*, readBuffer, deltaTime, maskActive */ ) { // render beauty and depth + renderer.setRenderTarget( this.beautyRenderTarget ); renderer.clear(); - if ( this.groundReflector ) { this.groundReflector.visible = false; @@ -312,29 +329,38 @@ } renderer.render( this.scene, this.camera ); - if ( this.groundReflector ) this.groundReflector.visible = false; // render normals + if ( this.groundReflector ) this.groundReflector.visible = false; + + // render normals - this.renderOverride( renderer, this.normalMaterial, this.normalRenderTarget, 0, 0 ); // render metalnesses + this.renderOverride( renderer, this.normalMaterial, this.normalRenderTarget, 0, 0 ); + + // render metalnesses if ( this.selective ) { this.renderMetalness( renderer, this.metalnessOnMaterial, this.metalnessRenderTarget, 0, 0 ); - } // render SSR + } + // render SSR this.ssrMaterial.uniforms[ 'opacity' ].value = this.opacity; this.ssrMaterial.uniforms[ 'maxDistance' ].value = this.maxDistance; this.ssrMaterial.uniforms[ 'thickness' ].value = this.thickness; - this.renderPass( renderer, this.ssrMaterial, this.ssrRenderTarget ); // render blur + this.renderPass( renderer, this.ssrMaterial, this.ssrRenderTarget ); + + // render blur if ( this.blur ) { this.renderPass( renderer, this.blurMaterial, this.blurRenderTarget ); - this.renderPass( renderer, this.blurMaterial2, this.blurRenderTarget2 ); // this.renderPass(renderer, this.blurMaterial3, this.blurRenderTarget3); + this.renderPass( renderer, this.blurMaterial2, this.blurRenderTarget2 ); + // this.renderPass(renderer, this.blurMaterial3, this.blurRenderTarget3); - } // output result to screen + } + // output result to screen switch ( this.output ) { @@ -363,12 +389,10 @@ } break; - case SSRPass.OUTPUT.SSR: if ( this.blur ) this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget2.texture; else this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssrRenderTarget.texture; this.copyMaterial.blending = THREE.NoBlending; this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer ); - if ( this.bouncing ) { if ( this.blur ) this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget2.texture; else this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture; @@ -381,46 +405,40 @@ } break; - case SSRPass.OUTPUT.Beauty: this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture; this.copyMaterial.blending = THREE.NoBlending; this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer ); break; - case SSRPass.OUTPUT.Depth: this.renderPass( renderer, this.depthRenderMaterial, this.renderToScreen ? null : writeBuffer ); break; - case SSRPass.OUTPUT.Normal: this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.normalRenderTarget.texture; this.copyMaterial.blending = THREE.NoBlending; this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer ); break; - case SSRPass.OUTPUT.Metalness: this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.metalnessRenderTarget.texture; this.copyMaterial.blending = THREE.NoBlending; this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer ); break; - default: console.warn( 'THREE.SSRPass: Unknown output type.' ); } } - renderPass( renderer, passMaterial, renderTarget, clearColor, clearAlpha ) { // save original state this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) ); const originalClearAlpha = renderer.getClearAlpha( this.tempColor ); const originalAutoClear = renderer.autoClear; - renderer.setRenderTarget( renderTarget ); // setup pass state + renderer.setRenderTarget( renderTarget ); + // setup pass state renderer.autoClear = false; - if ( clearColor !== undefined && clearColor !== null ) { renderer.setClearColor( clearColor ); @@ -430,14 +448,14 @@ } this.fsQuad.material = passMaterial; - this.fsQuad.render( renderer ); // restore original state + this.fsQuad.render( renderer ); + // restore original state renderer.autoClear = originalAutoClear; renderer.setClearColor( this.originalClearColor ); renderer.setClearAlpha( originalClearAlpha ); } - renderOverride( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) { this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) ); @@ -447,7 +465,6 @@ renderer.autoClear = false; clearColor = overrideMaterial.clearColor || clearColor; clearAlpha = overrideMaterial.clearAlpha || clearAlpha; - if ( clearColor !== undefined && clearColor !== null ) { renderer.setClearColor( clearColor ); @@ -458,14 +475,15 @@ this.scene.overrideMaterial = overrideMaterial; renderer.render( this.scene, this.camera ); - this.scene.overrideMaterial = null; // restore original state + this.scene.overrideMaterial = null; + + // restore original state renderer.autoClear = originalAutoClear; renderer.setClearColor( this.originalClearColor ); renderer.setClearAlpha( originalClearAlpha ); } - renderMetalness( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) { this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) ); @@ -475,7 +493,6 @@ renderer.autoClear = false; clearColor = overrideMaterial.clearColor || clearColor; clearAlpha = overrideMaterial.clearAlpha || clearAlpha; - if ( clearColor !== undefined && clearColor !== null ) { renderer.setClearColor( clearColor ); @@ -487,7 +504,6 @@ this.scene.traverseVisible( child => { child._SSRPassBackupMaterial = child.material; - if ( this._selects.includes( child ) ) { child.material = this.metalnessOnMaterial; @@ -504,14 +520,15 @@ child.material = child._SSRPassBackupMaterial; - } ); // restore original state + } ); + + // restore original state renderer.autoClear = originalAutoClear; renderer.setClearColor( this.originalClearColor ); renderer.setClearAlpha( originalClearAlpha ); } - setSize( width, height ) { this.width = width; @@ -524,7 +541,8 @@ this.normalRenderTarget.setSize( width, height ); this.metalnessRenderTarget.setSize( width, height ); this.blurRenderTarget.setSize( width, height ); - this.blurRenderTarget2.setSize( width, height ); // this.blurRenderTarget3.setSize(width, height); + this.blurRenderTarget2.setSize( width, height ); + // this.blurRenderTarget3.setSize(width, height); this.ssrMaterial.uniforms[ 'resolution' ].value.set( width, height ); this.ssrMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix ); @@ -535,7 +553,6 @@ } } - SSRPass.OUTPUT = { 'Default': 0, 'SSR': 1, diff --git a/examples/js/postprocessing/SavePass.js b/examples/js/postprocessing/SavePass.js index 620974d96d8f53..3b9e870f03bf71 100644 --- a/examples/js/postprocessing/SavePass.js +++ b/examples/js/postprocessing/SavePass.js @@ -15,10 +15,9 @@ fragmentShader: shader.fragmentShader } ); this.renderTarget = renderTarget; - if ( this.renderTarget === undefined ) { - this.renderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight ); + this.renderTarget = new THREE.WebGLRenderTarget(); // will be resized later this.renderTarget.texture.name = 'SavePass.rt'; } @@ -27,10 +26,7 @@ this.fsQuad = new THREE.FullScreenQuad( this.material ); } - - render( renderer, writeBuffer, readBuffer - /*, deltaTime, maskActive */ - ) { + render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) { if ( this.uniforms[ this.textureID ] ) { @@ -43,6 +39,18 @@ this.fsQuad.render( renderer ); } + setSize( width, height ) { + + this.renderTarget.setSize( width, height ); + + } + dispose() { + + this.renderTarget.dispose(); + this.material.dispose(); + this.fsQuad.dispose(); + + } } diff --git a/examples/js/postprocessing/ShaderPass.js b/examples/js/postprocessing/ShaderPass.js index 9c508b36ee8f4f..e5277f55db2ca4 100644 --- a/examples/js/postprocessing/ShaderPass.js +++ b/examples/js/postprocessing/ShaderPass.js @@ -6,7 +6,6 @@ super(); this.textureID = textureID !== undefined ? textureID : 'tDiffuse'; - if ( shader instanceof THREE.ShaderMaterial ) { this.uniforms = shader.uniforms; @@ -27,10 +26,7 @@ this.fsQuad = new THREE.FullScreenQuad( this.material ); } - - render( renderer, writeBuffer, readBuffer - /*, deltaTime, maskActive */ - ) { + render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) { if ( this.uniforms[ this.textureID ] ) { @@ -39,7 +35,6 @@ } this.fsQuad.material = this.material; - if ( this.renderToScreen ) { renderer.setRenderTarget( null ); @@ -47,14 +42,20 @@ } else { - renderer.setRenderTarget( writeBuffer ); // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600 - + renderer.setRenderTarget( writeBuffer ); + // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600 if ( this.clear ) renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil ); this.fsQuad.render( renderer ); } } + dispose() { + + this.material.dispose(); + this.fsQuad.dispose(); + + } } diff --git a/examples/js/postprocessing/TAARenderPass.js b/examples/js/postprocessing/TAARenderPass.js index e1813744bec595..db04ce9706e31c 100644 --- a/examples/js/postprocessing/TAARenderPass.js +++ b/examples/js/postprocessing/TAARenderPass.js @@ -21,7 +21,6 @@ this.accumulate = false; } - render( renderer, writeBuffer, readBuffer, deltaTime ) { if ( this.accumulate === false ) { @@ -33,7 +32,6 @@ } const jitterOffsets = _JitterVectors[ 5 ]; - if ( this.sampleRenderTarget === undefined ) { this.sampleRenderTarget = new THREE.WebGLRenderTarget( readBuffer.width, readBuffer.height, this.params ); @@ -58,22 +56,21 @@ const autoClear = renderer.autoClear; renderer.autoClear = false; const sampleWeight = 1.0 / jitterOffsets.length; - if ( this.accumulateIndex >= 0 && this.accumulateIndex < jitterOffsets.length ) { this.copyUniforms[ 'opacity' ].value = sampleWeight; - this.copyUniforms[ 'tDiffuse' ].value = writeBuffer.texture; // render the scene multiple times, each slightly jitter offset from the last and accumulate the results. + this.copyUniforms[ 'tDiffuse' ].value = writeBuffer.texture; + // render the scene multiple times, each slightly jitter offset from the last and accumulate the results. const numSamplesPerFrame = Math.pow( 2, this.sampleLevel ); - for ( let i = 0; i < numSamplesPerFrame; i ++ ) { const j = this.accumulateIndex; const jitterOffset = jitterOffsets[ j ]; - if ( this.camera.setViewOffset ) { - this.camera.setViewOffset( readBuffer.width, readBuffer.height, jitterOffset[ 0 ] * 0.0625, jitterOffset[ 1 ] * 0.0625, // 0.0625 = 1 / 16 + this.camera.setViewOffset( readBuffer.width, readBuffer.height, jitterOffset[ 0 ] * 0.0625, jitterOffset[ 1 ] * 0.0625, + // 0.0625 = 1 / 16 readBuffer.width, readBuffer.height ); } @@ -94,7 +91,6 @@ } const accumulationWeight = this.accumulateIndex * sampleWeight; - if ( accumulationWeight > 0 ) { this.copyUniforms[ 'opacity' ].value = 1.0; @@ -118,9 +114,15 @@ renderer.autoClear = autoClear; } + dispose() { - } + super.dispose(); + if ( this.sampleRenderTarget !== undefined ) this.sampleRenderTarget.dispose(); + if ( this.holdRenderTarget !== undefined ) this.holdRenderTarget.dispose(); + } + + } const _JitterVectors = [[[ 0, 0 ]], [[ 4, 4 ], [ - 4, - 4 ]], [[ - 2, - 6 ], [ 6, - 2 ], [ - 6, 2 ], [ 2, 6 ]], [[ 1, - 3 ], [ - 1, 3 ], [ 5, 1 ], [ - 3, - 5 ], [ - 5, 5 ], [ - 7, - 1 ], [ 3, 7 ], [ 7, - 7 ]], [[ 1, 1 ], [ - 1, - 3 ], [ - 3, 2 ], [ 4, - 1 ], [ - 5, - 2 ], [ 2, 5 ], [ 5, 3 ], [ 3, - 5 ], [ - 2, 6 ], [ 0, - 7 ], [ - 4, - 6 ], [ - 6, 4 ], [ - 8, 0 ], [ 7, - 4 ], [ 6, 7 ], [ - 7, - 8 ]], [[ - 4, - 7 ], [ - 7, - 5 ], [ - 3, - 5 ], [ - 5, - 4 ], [ - 1, - 4 ], [ - 2, - 2 ], [ - 6, - 1 ], [ - 4, 0 ], [ - 7, 1 ], [ - 1, 2 ], [ - 6, 3 ], [ - 3, 3 ], [ - 7, 6 ], [ - 3, 6 ], [ - 5, 7 ], [ - 1, 7 ], [ 5, - 7 ], [ 1, - 6 ], [ 6, - 5 ], [ 4, - 4 ], [ 2, - 3 ], [ 7, - 2 ], [ 1, - 1 ], [ 4, - 1 ], [ 2, 1 ], [ 6, 2 ], [ 0, 4 ], [ 4, 4 ], [ 2, 5 ], [ 7, 5 ], [ 5, 6 ], [ 3, 7 ]]]; THREE.TAARenderPass = TAARenderPass; diff --git a/examples/js/postprocessing/TexturePass.js b/examples/js/postprocessing/TexturePass.js index 194074728348fb..287958996fb023 100644 --- a/examples/js/postprocessing/TexturePass.js +++ b/examples/js/postprocessing/TexturePass.js @@ -21,10 +21,7 @@ this.fsQuad = new THREE.FullScreenQuad( null ); } - - render( renderer, writeBuffer, readBuffer - /*, deltaTime, maskActive */ - ) { + render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) { const oldAutoClear = renderer.autoClear; renderer.autoClear = false; @@ -38,6 +35,12 @@ renderer.autoClear = oldAutoClear; } + dispose() { + + this.material.dispose(); + this.fsQuad.dispose(); + + } } diff --git a/examples/js/postprocessing/UnrealBloomPass.js b/examples/js/postprocessing/UnrealBloomPass.js index cc68a65dc2f6e0..f6c183b433d44d 100644 --- a/examples/js/postprocessing/UnrealBloomPass.js +++ b/examples/js/postprocessing/UnrealBloomPass.js @@ -9,7 +9,6 @@ * Reference: * - https://docs.unrealengine.com/latest/INT/Engine/Rendering/PostProcessEffects/Bloom/ */ - class UnrealBloomPass extends THREE.Pass { constructor( resolution, strength, radius, threshold ) { @@ -18,10 +17,12 @@ this.strength = strength !== undefined ? strength : 1; this.radius = radius; this.threshold = threshold; - this.resolution = resolution !== undefined ? new THREE.Vector2( resolution.x, resolution.y ) : new THREE.Vector2( 256, 256 ); // create color only once here, reuse it later inside the render function + this.resolution = resolution !== undefined ? new THREE.Vector2( resolution.x, resolution.y ) : new THREE.Vector2( 256, 256 ); - this.clearColor = new THREE.Color( 0, 0, 0 ); // render targets + // create color only once here, reuse it later inside the render function + this.clearColor = new THREE.Color( 0, 0, 0 ); + // render targets this.renderTargetsHorizontal = []; this.renderTargetsVertical = []; this.nMips = 5; @@ -30,7 +31,6 @@ this.renderTargetBright = new THREE.WebGLRenderTarget( resx, resy ); this.renderTargetBright.texture.name = 'UnrealBloomPass.bright'; this.renderTargetBright.texture.generateMipmaps = false; - for ( let i = 0; i < this.nMips; i ++ ) { const renderTargetHorizonal = new THREE.WebGLRenderTarget( resx, resy ); @@ -44,8 +44,9 @@ resx = Math.round( resx / 2 ); resy = Math.round( resy / 2 ); - } // luminosity high pass material + } + // luminosity high pass material if ( THREE.LuminosityHighPassShader === undefined ) console.error( 'THREE.UnrealBloomPass relies on THREE.LuminosityHighPassShader' ); const highPassShader = THREE.LuminosityHighPassShader; @@ -57,13 +58,13 @@ vertexShader: highPassShader.vertexShader, fragmentShader: highPassShader.fragmentShader, defines: {} - } ); // Gaussian Blur Materials + } ); + // Gaussian Blur Materials this.separableBlurMaterials = []; const kernelSizeArray = [ 3, 5, 7, 9, 11 ]; resx = Math.round( this.resolution.x / 2 ); resy = Math.round( this.resolution.y / 2 ); - for ( let i = 0; i < this.nMips; i ++ ) { this.separableBlurMaterials.push( this.getSeperableBlurMaterial( kernelSizeArray[ i ] ) ); @@ -71,9 +72,9 @@ resx = Math.round( resx / 2 ); resy = Math.round( resy / 2 ); - } // Composite material - + } + // Composite material this.compositeMaterial = this.getCompositeMaterial( this.nMips ); this.compositeMaterial.uniforms[ 'blurTexture1' ].value = this.renderTargetsVertical[ 0 ].texture; this.compositeMaterial.uniforms[ 'blurTexture2' ].value = this.renderTargetsVertical[ 1 ].texture; @@ -86,8 +87,9 @@ const bloomFactors = [ 1.0, 0.8, 0.6, 0.4, 0.2 ]; this.compositeMaterial.uniforms[ 'bloomFactors' ].value = bloomFactors; this.bloomTintColors = [ 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.compositeMaterial.uniforms[ 'bloomTintColors' ].value = this.bloomTintColors; // copy material + this.compositeMaterial.uniforms[ 'bloomTintColors' ].value = this.bloomTintColors; + // copy material if ( THREE.CopyShader === undefined ) { console.error( 'THREE.UnrealBloomPass relies on THREE.CopyShader' ); @@ -114,7 +116,6 @@ this.fsQuad = new THREE.FullScreenQuad( null ); } - dispose() { for ( let i = 0; i < this.renderTargetsHorizontal.length; i ++ ) { @@ -131,14 +132,28 @@ this.renderTargetBright.dispose(); - } + // + + for ( let i = 0; i < this.separableBlurMaterials.length; i ++ ) { + + this.separableBlurMaterials[ i ].dispose(); + + } + + this.compositeMaterial.dispose(); + this.materialCopy.dispose(); + this.basic.dispose(); + + // + this.fsQuad.dispose(); + + } setSize( width, height ) { let resx = Math.round( width / 2 ); let resy = Math.round( height / 2 ); this.renderTargetBright.setSize( resx, resy ); - for ( let i = 0; i < this.nMips; i ++ ) { this.renderTargetsHorizontal[ i ].setSize( resx, resy ); @@ -150,7 +165,6 @@ } } - render( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) { renderer.getClearColor( this._oldClearColor ); @@ -158,7 +172,9 @@ const oldAutoClear = renderer.autoClear; renderer.autoClear = false; renderer.setClearColor( this.clearColor, 0 ); - if ( maskActive ) renderer.state.buffers.stencil.setTest( false ); // Render input to screen + if ( maskActive ) renderer.state.buffers.stencil.setTest( false ); + + // Render input to screen if ( this.renderToScreen ) { @@ -168,18 +184,20 @@ renderer.clear(); this.fsQuad.render( renderer ); - } // 1. Extract Bright Areas + } + // 1. Extract Bright Areas this.highPassUniforms[ 'tDiffuse' ].value = readBuffer.texture; this.highPassUniforms[ 'luminosityThreshold' ].value = this.threshold; this.fsQuad.material = this.materialHighPassFilter; renderer.setRenderTarget( this.renderTargetBright ); renderer.clear(); - this.fsQuad.render( renderer ); // 2. Blur All the mips progressively + this.fsQuad.render( renderer ); - let inputRenderTarget = this.renderTargetBright; + // 2. Blur All the mips progressively + let inputRenderTarget = this.renderTargetBright; for ( let i = 0; i < this.nMips; i ++ ) { this.fsQuad.material = this.separableBlurMaterials[ i ]; @@ -195,8 +213,9 @@ this.fsQuad.render( renderer ); inputRenderTarget = this.renderTargetsVertical[ i ]; - } // Composite All the mips + } + // Composite All the mips this.fsQuad.material = this.compositeMaterial; this.compositeMaterial.uniforms[ 'bloomStrength' ].value = this.strength; @@ -204,12 +223,13 @@ this.compositeMaterial.uniforms[ 'bloomTintColors' ].value = this.bloomTintColors; renderer.setRenderTarget( this.renderTargetsHorizontal[ 0 ] ); renderer.clear(); - this.fsQuad.render( renderer ); // Blend it additively over the input texture + this.fsQuad.render( renderer ); + + // Blend it additively over the input texture this.fsQuad.material = this.materialCopy; this.copyUniforms[ 'tDiffuse' ].value = this.renderTargetsHorizontal[ 0 ].texture; if ( maskActive ) renderer.state.buffers.stencil.setTest( true ); - if ( this.renderToScreen ) { renderer.setRenderTarget( null ); @@ -220,14 +240,14 @@ renderer.setRenderTarget( readBuffer ); this.fsQuad.render( renderer ); - } // Restore renderer settings + } + // Restore renderer settings renderer.setClearColor( this._oldClearColor, this.oldClearAlpha ); renderer.autoClear = oldAutoClear; } - getSeperableBlurMaterial( kernelRadius ) { return new THREE.ShaderMaterial( { @@ -279,7 +299,6 @@ } ); } - getCompositeMaterial( nMips ) { return new THREE.ShaderMaterial( { @@ -348,7 +367,6 @@ } } - UnrealBloomPass.BlurDirectionX = new THREE.Vector2( 1.0, 0.0 ); UnrealBloomPass.BlurDirectionY = new THREE.Vector2( 0.0, 1.0 ); diff --git a/examples/js/renderers/CSS2DRenderer.js b/examples/js/renderers/CSS2DRenderer.js index d528f5be660359..641756e9c7b45c 100644 --- a/examples/js/renderers/CSS2DRenderer.js +++ b/examples/js/renderers/CSS2DRenderer.js @@ -25,7 +25,6 @@ } ); } - copy( source, recursive ) { super.copy( source, recursive ); @@ -34,36 +33,28 @@ } - } // + } + // const _vector = new THREE.Vector3(); - const _viewMatrix = new THREE.Matrix4(); - const _viewProjectionMatrix = new THREE.Matrix4(); - const _a = new THREE.Vector3(); - const _b = new THREE.Vector3(); - class CSS2DRenderer { constructor( parameters = {} ) { const _this = this; - let _width, _height; - let _widthHalf, _heightHalf; - const cache = { objects: new WeakMap() }; const domElement = parameters.element !== undefined ? parameters.element : document.createElement( 'div' ); domElement.style.overflow = 'hidden'; this.domElement = domElement; - this.getSize = function () { return { @@ -75,13 +66,10 @@ this.render = function ( scene, camera ) { - if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); - if ( camera.parent === null ) camera.updateMatrixWorld(); - + if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld(); + if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld(); _viewMatrix.copy( camera.matrixWorldInverse ); - _viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, _viewMatrix ); - renderObject( scene, scene, camera ); zOrder( scene ); @@ -103,18 +91,14 @@ if ( object.isCSS2DObject ) { _vector.setFromMatrixPosition( object.matrixWorld ); - _vector.applyMatrix4( _viewProjectionMatrix ); - const visible = object.visible === true && _vector.z >= - 1 && _vector.z <= 1 && object.layers.test( camera.layers ) === true; object.element.style.display = visible === true ? '' : 'none'; - if ( visible === true ) { object.onBeforeRender( _this, scene, camera ); const element = object.element; element.style.transform = 'translate(-50%,-50%) translate(' + ( _vector.x * _widthHalf + _widthHalf ) + 'px,' + ( - _vector.y * _heightHalf + _heightHalf ) + 'px)'; - if ( element.parentNode !== domElement ) { domElement.appendChild( element ); @@ -143,9 +127,7 @@ function getDistanceToSquared( object1, object2 ) { _a.setFromMatrixPosition( object1.matrixWorld ); - _b.setFromMatrixPosition( object2.matrixWorld ); - return _a.distanceToSquared( _b ); } @@ -178,7 +160,6 @@ } ); const zMax = sorted.length; - for ( let i = 0, l = sorted.length; i < l; i ++ ) { sorted[ i ].element.style.zIndex = zMax - i; diff --git a/examples/js/renderers/CSS3DRenderer.js b/examples/js/renderers/CSS3DRenderer.js index b5b35719598ef0..1960e40396679f 100644 --- a/examples/js/renderers/CSS3DRenderer.js +++ b/examples/js/renderers/CSS3DRenderer.js @@ -5,11 +5,8 @@ */ const _position = new THREE.Vector3(); - const _quaternion = new THREE.Quaternion(); - const _scale = new THREE.Vector3(); - class CSS3DObject extends THREE.Object3D { constructor( element = document.createElement( 'div' ) ) { @@ -36,7 +33,6 @@ } ); } - copy( source, recursive ) { super.copy( source, recursive ); @@ -46,7 +42,6 @@ } } - class CSS3DSprite extends CSS3DObject { constructor( element ) { @@ -56,7 +51,6 @@ this.rotation2D = 0; } - copy( source, recursive ) { super.copy( source, recursive ); @@ -65,23 +59,19 @@ } - } // + } + // const _matrix = new THREE.Matrix4(); - const _matrix2 = new THREE.Matrix4(); - class CSS3DRenderer { constructor( parameters = {} ) { const _this = this; - let _width, _height; - let _widthHalf, _heightHalf; - const cache = { camera: { fov: 0, @@ -96,7 +86,6 @@ cameraElement.style.transformStyle = 'preserve-3d'; cameraElement.style.pointerEvents = 'none'; domElement.appendChild( cameraElement ); - this.getSize = function () { return { @@ -109,7 +98,6 @@ this.render = function ( scene, camera ) { const fov = camera.projectionMatrix.elements[ 5 ] * _heightHalf; - if ( cache.camera.fov !== fov ) { domElement.style.perspective = camera.isPerspectiveCamera ? fov + 'px' : ''; @@ -117,10 +105,9 @@ } - if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); - if ( camera.parent === null ) camera.updateMatrixWorld(); + if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld(); + if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld(); let tx, ty; - if ( camera.isOrthographicCamera ) { tx = - ( camera.right + camera.left ) / 2; @@ -130,7 +117,6 @@ const cameraCSSMatrix = camera.isOrthographicCamera ? 'scale(' + fov + ')' + 'translate(' + epsilon( tx ) + 'px,' + epsilon( ty ) + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse ) : 'translateZ(' + fov + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse ); const style = cameraCSSMatrix + 'translate(' + _widthHalf + 'px,' + _heightHalf + 'px)'; - if ( cache.camera.style !== style ) { cameraElement.style.transform = style; @@ -182,26 +168,20 @@ const visible = object.visible === true && object.layers.test( camera.layers ) === true; object.element.style.display = visible === true ? '' : 'none'; - if ( visible === true ) { object.onBeforeRender( _this, scene, camera ); let style; - if ( object.isCSS3DSprite ) { // http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/ - _matrix.copy( camera.matrixWorldInverse ); + _matrix.copy( camera.matrixWorldInverse ); _matrix.transpose(); - if ( object.rotation2D !== 0 ) _matrix.multiply( _matrix2.makeRotationZ( object.rotation2D ) ); object.matrixWorld.decompose( _position, _quaternion, _scale ); - _matrix.setPosition( _position ); - _matrix.scale( _scale ); - _matrix.elements[ 3 ] = 0; _matrix.elements[ 7 ] = 0; _matrix.elements[ 11 ] = 0; @@ -216,7 +196,6 @@ const element = object.element; const cachedObject = cache.objects.get( object ); - if ( cachedObject === undefined || cachedObject.style !== style ) { element.style.transform = style; diff --git a/examples/js/renderers/Projector.js b/examples/js/renderers/Projector.js index bfbaaf6d58e786..8379e101b8a409 100644 --- a/examples/js/renderers/Projector.js +++ b/examples/js/renderers/Projector.js @@ -11,8 +11,9 @@ } - } // + } + // class RenderableFace { @@ -33,8 +34,9 @@ } - } // + } + // class RenderableVertex { @@ -46,7 +48,6 @@ this.visible = true; } - copy( vertex ) { this.positionWorld.copy( vertex.positionWorld ); @@ -54,8 +55,9 @@ } - } // + } + // class RenderableLine { @@ -71,8 +73,9 @@ } - } // + } + // class RenderableSprite { @@ -90,8 +93,9 @@ } - } // + } + // class Projector { @@ -113,7 +117,6 @@ _spriteCount, _spritePoolLength = 0, _modelMatrix; - const _renderData = { objects: [], lights: [], @@ -132,29 +135,9 @@ _vertexPool = [], _facePool = [], _linePool = [], - _spritePool = []; // - - - this.projectVector = function ( vector, camera ) { - - console.warn( 'THREE.Projector: .projectVector() is now vector.project().' ); - vector.project( camera ); - - }; - - this.unprojectVector = function ( vector, camera ) { - - console.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' ); - vector.unproject( camera ); - - }; - - this.pickingRay = function () { - - console.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' ); - - }; // + _spritePool = []; + // function RenderList() { @@ -163,7 +146,6 @@ const uvs = []; let object = null; const normalMatrix = new THREE.Matrix3(); - function setObject( value ) { object = value; @@ -192,9 +174,7 @@ function pushVertex( x, y, z ) { _vertex = getNextVertexInPool(); - _vertex.position.set( x, y, z ); - projectVertex( _vertex ); } @@ -236,11 +216,12 @@ function pushLine( a, b ) { const v1 = _vertexPool[ a ]; - const v2 = _vertexPool[ b ]; // Clip + const v2 = _vertexPool[ b ]; + + // Clip v1.positionScreen.copy( v1.position ).applyMatrix4( _modelViewProjectionMatrix ); v2.positionScreen.copy( v2.position ).applyMatrix4( _modelViewProjectionMatrix ); - if ( clipLine( v1.positionScreen, v2.positionScreen ) === true ) { // Perform the perspective divide @@ -248,19 +229,14 @@ v2.positionScreen.multiplyScalar( 1 / v2.positionScreen.w ); _line = getNextLineInPool(); _line.id = object.id; - _line.v1.copy( v1 ); - _line.v2.copy( v2 ); - _line.z = Math.max( v1.positionScreen.z, v2.positionScreen.z ); _line.renderOrder = object.renderOrder; _line.material = object.material; - if ( object.material.vertexColors ) { _line.vertexColors[ 0 ].fromArray( colors, a * 3 ); - _line.vertexColors[ 1 ].fromArray( colors, b * 3 ); } @@ -277,31 +253,22 @@ const v2 = _vertexPool[ b ]; const v3 = _vertexPool[ c ]; if ( checkTriangleVisibility( v1, v2, v3 ) === false ) return; - if ( material.side === THREE.DoubleSide || checkBackfaceCulling( v1, v2, v3 ) === true ) { _face = getNextFaceInPool(); _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; - _face.renderOrder = object.renderOrder; // face normal + _face.renderOrder = object.renderOrder; + // face normal _vector3.subVectors( v3.position, v2.position ); - _vector4.subVectors( v1.position, v2.position ); - _vector3.cross( _vector4 ); - _face.normalModel.copy( _vector3 ); - _face.normalModel.applyMatrix3( normalMatrix ).normalize(); - for ( let i = 0; i < 3; i ++ ) { const normal = _face.vertexNormalsModel[ i ]; @@ -314,7 +281,6 @@ _face.vertexNormalsLength = 3; _face.material = material; - if ( material.vertexColors ) { _face.color.fromArray( colors, a * 3 ); @@ -343,11 +309,9 @@ } const renderList = new RenderList(); - function projectObject( object ) { if ( object.visible === false ) return; - if ( object.isLight ) { _renderData.lights.push( object ); @@ -367,7 +331,6 @@ } const children = object.children; - for ( let i = 0, l = children.length; i < l; i ++ ) { projectObject( children[ i ] ); @@ -381,14 +344,10 @@ _object = getNextObjectInPool(); _object.id = object.id; _object.object = object; - _vector3.setFromMatrixPosition( object.matrixWorld ); - _vector3.applyMatrix4( _viewProjectionMatrix ); - _object.z = _vector3.z; _object.renderOrder = object.renderOrder; - _renderData.objects.push( _object ); } @@ -399,30 +358,27 @@ _lineCount = 0; _spriteCount = 0; _renderData.elements.length = 0; - if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); - if ( camera.parent === null ) camera.updateMatrixWorld(); - + if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld(); + if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld(); _viewMatrix.copy( camera.matrixWorldInverse ); - _viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, _viewMatrix ); + _frustum.setFromProjectionMatrix( _viewProjectionMatrix ); - _frustum.setFromProjectionMatrix( _viewProjectionMatrix ); // - + // _objectCount = 0; _renderData.objects.length = 0; _renderData.lights.length = 0; projectObject( scene ); - if ( sortObjects === true ) { _renderData.objects.sort( painterSort ); - } // + } + // const objects = _renderData.objects; - for ( let o = 0, ol = objects.length; o < ol; o ++ ) { const object = objects[ o ].object; @@ -430,7 +386,6 @@ renderList.setObject( object ); _modelMatrix = object.matrixWorld; _vertexCount = 0; - if ( object.isMesh ) { let material = object.material; @@ -439,25 +394,21 @@ const groups = geometry.groups; if ( attributes.position === undefined ) continue; const positions = attributes.position.array; - for ( let i = 0, l = positions.length; i < l; i += 3 ) { let x = positions[ i ]; let y = positions[ i + 1 ]; let z = positions[ i + 2 ]; const morphTargets = geometry.morphAttributes.position; - if ( morphTargets !== undefined ) { const morphTargetsRelative = geometry.morphTargetsRelative; const morphInfluences = object.morphTargetInfluences; - for ( let t = 0, tl = morphTargets.length; t < tl; t ++ ) { const influence = morphInfluences[ t ]; if ( influence === 0 ) continue; const target = morphTargets[ t ]; - if ( morphTargetsRelative ) { x += target.getX( i / 3 ) * influence; @@ -483,7 +434,6 @@ if ( attributes.normal !== undefined ) { const normals = attributes.normal.array; - for ( let i = 0, l = normals.length; i < l; i += 3 ) { renderList.pushNormal( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ); @@ -495,7 +445,6 @@ if ( attributes.color !== undefined ) { const colors = attributes.color.array; - for ( let i = 0, l = colors.length; i < l; i += 3 ) { renderList.pushColor( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ); @@ -507,7 +456,6 @@ if ( attributes.uv !== undefined ) { const uvs = attributes.uv.array; - for ( let i = 0, l = uvs.length; i < l; i += 2 ) { renderList.pushUv( uvs[ i ], uvs[ i + 1 ] ); @@ -519,7 +467,6 @@ if ( geometry.index !== null ) { const indices = geometry.index.array; - if ( groups.length > 0 ) { for ( let g = 0; g < groups.length; g ++ ) { @@ -527,7 +474,6 @@ const group = groups[ g ]; material = isMultiMaterial === true ? object.material[ group.materialIndex ] : object.material; if ( material === undefined ) continue; - for ( let i = group.start, l = group.start + group.count; i < l; i += 3 ) { renderList.pushTriangle( indices[ i ], indices[ i + 1 ], indices[ i + 2 ], material ); @@ -555,7 +501,6 @@ const group = groups[ g ]; material = isMultiMaterial === true ? object.material[ group.materialIndex ] : object.material; if ( material === undefined ) continue; - for ( let i = group.start, l = group.start + group.count; i < l; i += 3 ) { renderList.pushTriangle( i, i + 1, i + 2, material ); @@ -579,13 +524,10 @@ } else if ( object.isLine ) { _modelViewProjectionMatrix.multiplyMatrices( _viewProjectionMatrix, _modelMatrix ); - const attributes = geometry.attributes; - if ( attributes.position !== undefined ) { const positions = attributes.position.array; - for ( let i = 0, l = positions.length; i < l; i += 3 ) { renderList.pushVertex( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ); @@ -595,7 +537,6 @@ if ( attributes.color !== undefined ) { const colors = attributes.color.array; - for ( let i = 0, l = colors.length; i < l; i += 3 ) { renderList.pushColor( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ); @@ -607,7 +548,6 @@ if ( geometry.index !== null ) { const indices = geometry.index.array; - for ( let i = 0, l = indices.length; i < l; i += 2 ) { renderList.pushLine( indices[ i ], indices[ i + 1 ] ); @@ -617,7 +557,6 @@ } else { const step = object.isLineSegments ? 2 : 1; - for ( let i = 0, l = positions.length / 3 - 1; i < l; i += step ) { renderList.pushLine( i, i + 1 ); @@ -631,19 +570,14 @@ } else if ( object.isPoints ) { _modelViewProjectionMatrix.multiplyMatrices( _viewProjectionMatrix, _modelMatrix ); - const attributes = geometry.attributes; - if ( attributes.position !== undefined ) { const positions = attributes.position.array; - for ( let i = 0, l = positions.length; i < l; i += 3 ) { _vector4.set( positions[ i ], positions[ i + 1 ], positions[ i + 2 ], 1 ); - _vector4.applyMatrix4( _modelViewProjectionMatrix ); - pushPoint( _vector4, object, camera ); } @@ -653,11 +587,8 @@ } else if ( object.isSprite ) { object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld ); - _vector4.set( _modelMatrix.elements[ 12 ], _modelMatrix.elements[ 13 ], _modelMatrix.elements[ 14 ], 1 ); - _vector4.applyMatrix4( _viewProjectionMatrix ); - pushPoint( _vector4, object, camera ); } @@ -678,7 +609,6 @@ const invW = 1 / _vector4.w; _vector4.z *= invW; - if ( _vector4.z >= - 1 && _vector4.z <= 1 ) { _sprite = getNextSpriteInPool(); @@ -692,22 +622,20 @@ _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 ] ) ); _sprite.material = object.material; - _renderData.elements.push( _sprite ); } - } // Pools + } + // Pools function getNextObjectInPool() { if ( _objectCount === _objectPoolLength ) { const object = new RenderableObject(); - _objectPool.push( object ); - _objectPoolLength ++; _objectCount ++; return object; @@ -723,9 +651,7 @@ if ( _vertexCount === _vertexPoolLength ) { const vertex = new RenderableVertex(); - _vertexPool.push( vertex ); - _vertexPoolLength ++; _vertexCount ++; return vertex; @@ -741,9 +667,7 @@ if ( _faceCount === _facePoolLength ) { const face = new RenderableFace(); - _facePool.push( face ); - _facePoolLength ++; _faceCount ++; return face; @@ -759,9 +683,7 @@ if ( _lineCount === _linePoolLength ) { const line = new RenderableLine(); - _linePool.push( line ); - _linePoolLength ++; _lineCount ++; return line; @@ -777,9 +699,7 @@ if ( _spriteCount === _spritePoolLength ) { const sprite = new RenderableSprite(); - _spritePool.push( sprite ); - _spritePoolLength ++; _spriteCount ++; return sprite; @@ -788,8 +708,9 @@ return _spritePool[ _spriteCount ++ ]; - } // + } + // function painterSort( a, b ) { @@ -816,14 +737,15 @@ function clipLine( s1, s2 ) { let alpha1 = 0, - alpha2 = 1; // Calculate the boundary coordinate of each vertex for the near and far clip planes, + alpha2 = 1; + + // Calculate the boundary coordinate of each vertex for the near and far clip planes, // Z = -1 and Z = +1, respectively. const 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 ) { // Both vertices lie entirely within all clip planes. @@ -837,6 +759,7 @@ } else { // The line segment spans at least one clip plane. + if ( bc1near < 0 ) { // v1 lies outside the near plane, v2 inside diff --git a/examples/js/renderers/SVGRenderer.js b/examples/js/renderers/SVGRenderer.js index fc305c7d7faaa7..1c2ace70ffff82 100644 --- a/examples/js/renderers/SVGRenderer.js +++ b/examples/js/renderers/SVGRenderer.js @@ -11,7 +11,6 @@ } } - class SVGRenderer { constructor() { @@ -32,7 +31,6 @@ _quality = 1, _currentPath, _currentStyle; - const _this = this, _clipBox = new THREE.Box2(), _elemBox = new THREE.Box2(), @@ -52,7 +50,6 @@ _svgPathPool = [], _projector = new THREE.Projector(), _svg = document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' ); - this.domElement = _svg; this.autoClear = true; this.sortObjects = true; @@ -64,7 +61,6 @@ faces: 0 } }; - this.setQuality = function ( quality ) { switch ( quality ) { @@ -72,7 +68,6 @@ case 'high': _quality = 1; break; - case 'low': _quality = 0; break; @@ -95,15 +90,10 @@ _svgHeight = height; _svgWidthHalf = _svgWidth / 2; _svgHeightHalf = _svgHeight / 2; - _svg.setAttribute( 'viewBox', - _svgWidthHalf + ' ' + - _svgHeightHalf + ' ' + _svgWidth + ' ' + _svgHeight ); - _svg.setAttribute( 'width', _svgWidth ); - _svg.setAttribute( 'height', _svgHeight ); - _clipBox.min.set( - _svgWidthHalf, - _svgHeightHalf ); - _clipBox.max.set( _svgWidthHalf, _svgHeightHalf ); }; @@ -126,7 +116,6 @@ function removeChildNodes() { _pathCount = 0; - while ( _svg.childNodes.length > 0 ) { _svg.removeChild( _svg.childNodes[ 0 ] ); @@ -158,7 +147,6 @@ } const background = scene.background; - if ( background && background.isColor ) { removeChildNodes(); @@ -172,30 +160,24 @@ _this.info.render.vertices = 0; _this.info.render.faces = 0; - _viewMatrix.copy( camera.matrixWorldInverse ); - _viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, _viewMatrix ); - _renderData = _projector.projectScene( scene, camera, this.sortObjects, this.sortElements ); _elements = _renderData.elements; _lights = _renderData.lights; - _normalViewMatrix.getNormalMatrix( camera.matrixWorldInverse ); + calculateLights( _lights ); - calculateLights( _lights ); // reset accumulated path + // reset accumulated path _currentPath = ''; _currentStyle = ''; - for ( let e = 0, el = _elements.length; e < el; e ++ ) { const element = _elements[ e ]; const material = element.material; if ( material === undefined || material.opacity === 0 ) continue; - _elemBox.makeEmpty(); - if ( element instanceof THREE.RenderableSprite ) { _v1 = element; @@ -211,9 +193,7 @@ _v1.positionScreen.y *= - _svgHeightHalf; _v2.positionScreen.x *= _svgWidthHalf; _v2.positionScreen.y *= - _svgHeightHalf; - _elemBox.setFromPoints( [ _v1.positionScreen, _v2.positionScreen ] ); - if ( _clipBox.intersectsBox( _elemBox ) === true ) { renderLine( _v1, _v2, material ); @@ -234,7 +214,6 @@ _v2.positionScreen.y *= - _svgHeightHalf; _v3.positionScreen.x *= _svgWidthHalf; _v3.positionScreen.y *= - _svgHeightHalf; - if ( this.overdraw > 0 ) { expand( _v1.positionScreen, _v2.positionScreen, this.overdraw ); @@ -244,7 +223,6 @@ } _elemBox.setFromPoints( [ _v1.positionScreen, _v2.positionScreen, _v3.positionScreen ] ); - if ( _clipBox.intersectsBox( _elemBox ) === true ) { renderFace3( _v1, _v2, _v3, element, material ); @@ -262,15 +240,12 @@ if ( object.isSVGObject ) { _vector3.setFromMatrixPosition( object.matrixWorld ); - _vector3.applyMatrix4( _viewProjectionMatrix ); - if ( _vector3.z < - 1 || _vector3.z > 1 ) return; const x = _vector3.x * _svgWidthHalf; const y = - _vector3.y * _svgHeightHalf; const node = object.node; node.setAttribute( 'transform', 'translate(' + x + ',' + y + ')' ); - _svg.appendChild( node ); } @@ -282,16 +257,12 @@ function calculateLights( lights ) { _ambientLight.setRGB( 0, 0, 0 ); - _directionalLights.setRGB( 0, 0, 0 ); - _pointLights.setRGB( 0, 0, 0 ); - for ( let l = 0, ll = lights.length; l < ll; l ++ ) { const light = lights[ l ]; const lightColor = light.color; - if ( light.isAmbientLight ) { _ambientLight.r += lightColor.r; @@ -322,11 +293,9 @@ const light = lights[ l ]; const lightColor = light.color; - if ( light.isDirectionalLight ) { const lightPosition = _vector3.setFromMatrixPosition( light.matrixWorld ).normalize(); - let amount = normal.dot( lightPosition ); if ( amount <= 0 ) continue; amount *= light.intensity; @@ -337,7 +306,6 @@ } else if ( light.isPointLight ) { const lightPosition = _vector3.setFromMatrixPosition( light.matrixWorld ); - let amount = normal.dot( _vector3.subVectors( lightPosition, position ).normalize() ); if ( amount <= 0 ) continue; amount *= light.distance == 0 ? 1 : 1 - Math.min( position.distanceTo( lightPosition ) / light.distance, 1 ); @@ -357,7 +325,6 @@ let scaleX = element.scale.x * _svgWidthHalf; let scaleY = element.scale.y * _svgHeightHalf; - if ( material.isPointsMaterial ) { scaleX *= material.size; @@ -367,7 +334,6 @@ const path = 'M' + convert( v1.x - scaleX * 0.5 ) + ',' + convert( v1.y - scaleY * 0.5 ) + 'h' + convert( scaleX ) + 'v' + convert( scaleY ) + 'h' + convert( - scaleX ) + 'z'; let style = ''; - if ( material.isSpriteMaterial || material.isPointsMaterial ) { style = 'fill:' + material.color.getStyle() + ';fill-opacity:' + material.opacity; @@ -381,11 +347,9 @@ function renderLine( v1, v2, material ) { const path = 'M' + convert( v1.positionScreen.x ) + ',' + convert( v1.positionScreen.y ) + 'L' + convert( v2.positionScreen.x ) + ',' + convert( v2.positionScreen.y ); - if ( material.isLineBasicMaterial ) { let style = 'fill:none;stroke:' + material.color.getStyle() + ';stroke-opacity:' + material.opacity + ';stroke-width:' + material.linewidth + ';stroke-linecap:' + material.linecap; - if ( material.isLineDashedMaterial ) { style = style + ';stroke-dasharray:' + material.dashSize + ',' + material.gapSize; @@ -404,11 +368,9 @@ _this.info.render.faces ++; const path = 'M' + convert( v1.positionScreen.x ) + ',' + convert( v1.positionScreen.y ) + 'L' + convert( v2.positionScreen.x ) + ',' + convert( v2.positionScreen.y ) + 'L' + convert( v3.positionScreen.x ) + ',' + convert( v3.positionScreen.y ) + 'z'; let style = ''; - if ( material.isMeshBasicMaterial ) { _color.copy( material.color ); - if ( material.vertexColors ) { _color.multiply( element.color ); @@ -418,7 +380,6 @@ } else if ( material.isMeshLambertMaterial || material.isMeshPhongMaterial || material.isMeshStandardMaterial ) { _diffuseColor.copy( material.color ); - if ( material.vertexColors ) { _diffuseColor.multiply( element.color ); @@ -426,17 +387,13 @@ } _color.copy( _ambientLight ); - _centroid.copy( v1.positionWorld ).add( v2.positionWorld ).add( v3.positionWorld ).divideScalar( 3 ); - calculateLight( _lights, _centroid, element.normalModel, _color ); - _color.multiply( _diffuseColor ).add( material.emissive ); } else if ( material.isMeshNormalMaterial ) { _normal.copy( element.normalModel ).applyMatrix3( _normalViewMatrix ).normalize(); - _color.setRGB( _normal.x, _normal.y, _normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 ); } @@ -453,8 +410,9 @@ addPath( style, path ); - } // Hide anti-alias gaps + } + // Hide anti-alias gaps function expand( v1, v2, pixels ) { @@ -493,11 +451,8 @@ if ( _currentPath ) { _svgNode = getPathNode( _pathCount ++ ); - _svgNode.setAttribute( 'd', _currentPath ); - _svgNode.setAttribute( 'style', _currentStyle ); - _svg.appendChild( _svgNode ); } @@ -512,7 +467,6 @@ if ( _svgPathPool[ id ] == null ) { _svgPathPool[ id ] = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' ); - if ( _quality == 0 ) { _svgPathPool[ id ].setAttribute( 'shape-rendering', 'crispEdges' ); //optimizeSpeed diff --git a/examples/js/shaders/ACESFilmicToneMappingShader.js b/examples/js/shaders/ACESFilmicToneMappingShader.js index 940cea73fcd6bf..2b87be52ad35b8 100644 --- a/examples/js/shaders/ACESFilmicToneMappingShader.js +++ b/examples/js/shaders/ACESFilmicToneMappingShader.js @@ -7,6 +7,7 @@ * this implementation of ACES is modified to accommodate a brighter viewing environment. * the scale factor of 1/0.6 is subjective. see discussion in #19621. */ + const ACESFilmicToneMappingShader = { uniforms: { 'tDiffuse': { @@ -16,9 +17,7 @@ value: 1.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -28,9 +27,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` #define saturate(a) clamp( a, 0.0, 1.0 ) diff --git a/examples/js/shaders/AfterimageShader.js b/examples/js/shaders/AfterimageShader.js index fac031829a4458..35eb778aeed8db 100644 --- a/examples/js/shaders/AfterimageShader.js +++ b/examples/js/shaders/AfterimageShader.js @@ -5,6 +5,7 @@ * I created this effect inspired by a demo on codepen: * https://codepen.io/brunoimbrizi/pen/MoRJaN?page=1& */ + const AfterimageShader = { uniforms: { 'damp': { @@ -17,9 +18,7 @@ value: null } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -29,9 +28,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform float damp; diff --git a/examples/js/shaders/BasicShader.js b/examples/js/shaders/BasicShader.js index 42a2e063477097..ddb3473ec1bcb4 100644 --- a/examples/js/shaders/BasicShader.js +++ b/examples/js/shaders/BasicShader.js @@ -3,20 +3,17 @@ /** * Simple test shader */ + const BasicShader = { uniforms: {}, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` void main() { diff --git a/examples/js/shaders/BleachBypassShader.js b/examples/js/shaders/BleachBypassShader.js index 52849731719b79..d117073beb8c66 100644 --- a/examples/js/shaders/BleachBypassShader.js +++ b/examples/js/shaders/BleachBypassShader.js @@ -5,6 +5,7 @@ * - based on Nvidia example * http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html#post_bleach_bypass */ + const BleachBypassShader = { uniforms: { 'tDiffuse': { @@ -14,9 +15,7 @@ value: 1.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -26,9 +25,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform float opacity; diff --git a/examples/js/shaders/BlendShader.js b/examples/js/shaders/BlendShader.js index b0f1b7e051284e..742f8449bbd757 100644 --- a/examples/js/shaders/BlendShader.js +++ b/examples/js/shaders/BlendShader.js @@ -3,6 +3,7 @@ /** * Blend two textures */ + const BlendShader = { uniforms: { 'tDiffuse1': { @@ -18,9 +19,7 @@ value: 1.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -30,9 +29,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform float opacity; uniform float mixRatio; diff --git a/examples/js/shaders/BokehShader.js b/examples/js/shaders/BokehShader.js index bbb75171dec09d..c92f982571123b 100644 --- a/examples/js/shaders/BokehShader.js +++ b/examples/js/shaders/BokehShader.js @@ -5,6 +5,7 @@ * ported from GLSL shader by Martins Upitis * http://artmartinsh.blogspot.com/2010/02/glsl-lens-blur-filter-with-bokeh.html */ + const BokehShader = { defines: { 'DEPTH_PACKING': 1, @@ -36,9 +37,7 @@ value: 1000.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -48,9 +47,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` #include diff --git a/examples/js/shaders/BokehShader2.js b/examples/js/shaders/BokehShader2.js index c1dd221f8efa2b..5c315e67d43615 100644 --- a/examples/js/shaders/BokehShader2.js +++ b/examples/js/shaders/BokehShader2.js @@ -7,7 +7,6 @@ * * Requires #define RINGS and SAMPLES integers */ - const BokehShader = { uniforms: { 'textureWidth': { @@ -80,9 +79,7 @@ value: new THREE.Vector2() } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -92,9 +89,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` #include @@ -391,9 +386,7 @@ value: 1000.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying float vViewZDepth; @@ -405,9 +398,7 @@ vViewZDepth = - mvPosition.z; }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform float mNear; uniform float mFar; diff --git a/examples/js/shaders/BrightnessContrastShader.js b/examples/js/shaders/BrightnessContrastShader.js index 50c514e0ad0a05..f4ea7ef6226f62 100644 --- a/examples/js/shaders/BrightnessContrastShader.js +++ b/examples/js/shaders/BrightnessContrastShader.js @@ -6,6 +6,7 @@ * brightness: -1 to 1 (-1 is solid black, 0 is no change, and 1 is solid white) * contrast: -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast) */ + const BrightnessContrastShader = { uniforms: { 'tDiffuse': { @@ -18,9 +19,7 @@ value: 0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -31,9 +30,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; uniform float brightness; diff --git a/examples/js/shaders/ColorCorrectionShader.js b/examples/js/shaders/ColorCorrectionShader.js index d4740a58feba80..b07dae389b0cf1 100644 --- a/examples/js/shaders/ColorCorrectionShader.js +++ b/examples/js/shaders/ColorCorrectionShader.js @@ -19,9 +19,7 @@ value: new THREE.Vector3( 0, 0, 0 ) } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -32,9 +30,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; uniform vec3 powRGB; diff --git a/examples/js/shaders/ColorifyShader.js b/examples/js/shaders/ColorifyShader.js index 3d8b4bb27c0fce..2e159f0dc2222a 100644 --- a/examples/js/shaders/ColorifyShader.js +++ b/examples/js/shaders/ColorifyShader.js @@ -13,9 +13,7 @@ value: new THREE.Color( 0xffffff ) } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -25,9 +23,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform vec3 color; uniform sampler2D tDiffuse; diff --git a/examples/js/shaders/ConvolutionShader.js b/examples/js/shaders/ConvolutionShader.js index d3ae5d39109d72..8a64cb7935af5f 100644 --- a/examples/js/shaders/ConvolutionShader.js +++ b/examples/js/shaders/ConvolutionShader.js @@ -21,9 +21,7 @@ value: [] } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` uniform vec2 uImageIncrement; @@ -35,9 +33,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform float cKernel[ KERNEL_SIZE_INT ]; @@ -64,28 +60,27 @@ buildKernel: function ( sigma ) { // We lop off the sqrt(2 * pi) * sigma term, since we're going to normalize anyway. + const kMaxKernelSize = 25; let kernelSize = 2 * Math.ceil( sigma * 3.0 ) + 1; if ( kernelSize > kMaxKernelSize ) kernelSize = kMaxKernelSize; const halfWidth = ( kernelSize - 1 ) * 0.5; const values = new Array( kernelSize ); let sum = 0.0; - for ( let i = 0; i < kernelSize; ++ i ) { values[ i ] = gauss( i - halfWidth, sigma ); sum += values[ i ]; - } // normalize the kernel + } + // normalize the kernel for ( let i = 0; i < kernelSize; ++ i ) values[ i ] /= sum; - return values; } }; - function gauss( x, sigma ) { return Math.exp( - ( x * x ) / ( 2.0 * sigma * sigma ) ); diff --git a/examples/js/shaders/CopyShader.js b/examples/js/shaders/CopyShader.js index 91e5ce35536736..a18ef6297cf89c 100644 --- a/examples/js/shaders/CopyShader.js +++ b/examples/js/shaders/CopyShader.js @@ -3,6 +3,7 @@ /** * Full-screen textured quad shader */ + const CopyShader = { uniforms: { 'tDiffuse': { @@ -12,9 +13,7 @@ value: 1.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -24,9 +23,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform float opacity; diff --git a/examples/js/shaders/DOFMipMapShader.js b/examples/js/shaders/DOFMipMapShader.js index 2c37c8ab555c93..120a1e5aa375e3 100644 --- a/examples/js/shaders/DOFMipMapShader.js +++ b/examples/js/shaders/DOFMipMapShader.js @@ -5,6 +5,7 @@ * - from Matt Handley @applmak * - requires power-of-2 sized render target with enabled mipmaps */ + const DOFMipMapShader = { uniforms: { 'tColor': { @@ -20,9 +21,7 @@ value: 1.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -32,9 +31,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform float focus; uniform float maxblur; diff --git a/examples/js/shaders/DepthLimitedBlurShader.js b/examples/js/shaders/DepthLimitedBlurShader.js index 4448782f3075ac..2d077431554b48 100644 --- a/examples/js/shaders/DepthLimitedBlurShader.js +++ b/examples/js/shaders/DepthLimitedBlurShader.js @@ -36,9 +36,7 @@ value: 10 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` #include @@ -53,9 +51,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` #include #include @@ -135,7 +131,6 @@ createSampleWeights: function ( kernelRadius, stdDev ) { const weights = []; - for ( let i = 0; i <= kernelRadius; i ++ ) { weights.push( gaussian( i, stdDev ) ); @@ -148,7 +143,6 @@ createSampleOffsets: function ( kernelRadius, uvIncrement ) { const offsets = []; - for ( let i = 0; i <= kernelRadius; i ++ ) { offsets.push( uvIncrement.clone().multiplyScalar( i ) ); @@ -167,7 +161,6 @@ } }; - function gaussian( x, stdDev ) { return Math.exp( - ( x * x ) / ( 2.0 * ( stdDev * stdDev ) ) ) / ( Math.sqrt( 2.0 * Math.PI ) * stdDev ); diff --git a/examples/js/shaders/DigitalGlitch.js b/examples/js/shaders/DigitalGlitch.js index 4764e65cabba9b..8a93fd06e6528a 100644 --- a/examples/js/shaders/DigitalGlitch.js +++ b/examples/js/shaders/DigitalGlitch.js @@ -9,6 +9,7 @@ * amount: shift distance (1 is width of input) * angle: shift angle in radians */ + const DigitalGlitch = { uniforms: { 'tDiffuse': { @@ -50,18 +51,14 @@ value: 0.05 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform int byp; //should we apply the glitch ? diff --git a/examples/js/shaders/DotScreenShader.js b/examples/js/shaders/DotScreenShader.js index 77d183d480acb6..a037bf7c727ec7 100644 --- a/examples/js/shaders/DotScreenShader.js +++ b/examples/js/shaders/DotScreenShader.js @@ -24,9 +24,7 @@ value: 1.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -36,9 +34,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform vec2 center; uniform float angle; diff --git a/examples/js/shaders/FXAAShader.js b/examples/js/shaders/FXAAShader.js index 937edc1430c073..33778f853df046 100644 --- a/examples/js/shaders/FXAAShader.js +++ b/examples/js/shaders/FXAAShader.js @@ -17,9 +17,7 @@ value: new THREE.Vector2( 1 / 1024, 1 / 512 ) } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; diff --git a/examples/js/shaders/FilmShader.js b/examples/js/shaders/FilmShader.js index f278bb0ca6d801..fea1acaa4c82bd 100644 --- a/examples/js/shaders/FilmShader.js +++ b/examples/js/shaders/FilmShader.js @@ -19,6 +19,7 @@ * This version is provided under a Creative Commons Attribution 3.0 License * http://creativecommons.org/licenses/by/3.0/ */ + const FilmShader = { uniforms: { 'tDiffuse': { @@ -40,9 +41,7 @@ value: 1 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -52,9 +51,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` #include diff --git a/examples/js/shaders/FocusShader.js b/examples/js/shaders/FocusShader.js index 2e32f9ff706a32..aa0d218cb93157 100644 --- a/examples/js/shaders/FocusShader.js +++ b/examples/js/shaders/FocusShader.js @@ -5,6 +5,7 @@ * based on PaintEffect postprocess from ro.me * http://code.google.com/p/3-dreams-of-black/source/browse/deploy/js/effects/PaintEffect.js */ + const FocusShader = { uniforms: { 'tDiffuse': { @@ -23,9 +24,7 @@ value: 0.00125 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -35,9 +34,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform float screenWidth; uniform float screenHeight; diff --git a/examples/js/shaders/FreiChenShader.js b/examples/js/shaders/FreiChenShader.js index 48834819b307c1..9078af012c2979 100644 --- a/examples/js/shaders/FreiChenShader.js +++ b/examples/js/shaders/FreiChenShader.js @@ -16,9 +16,7 @@ value: new THREE.Vector2( 512, 512 ) } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -28,9 +26,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; varying vec2 vUv; diff --git a/examples/js/shaders/GammaCorrectionShader.js b/examples/js/shaders/GammaCorrectionShader.js index 8a579bdf55119e..de943613e15dd8 100644 --- a/examples/js/shaders/GammaCorrectionShader.js +++ b/examples/js/shaders/GammaCorrectionShader.js @@ -4,15 +4,14 @@ * Gamma Correction Shader * http://en.wikipedia.org/wiki/gamma_correction */ + const GammaCorrectionShader = { uniforms: { 'tDiffuse': { value: null } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -22,9 +21,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; diff --git a/examples/js/shaders/GodRaysShader.js b/examples/js/shaders/GodRaysShader.js index 2cace2602173f4..aa0862b48e1d60 100644 --- a/examples/js/shaders/GodRaysShader.js +++ b/examples/js/shaders/GodRaysShader.js @@ -24,9 +24,7 @@ value: null } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -36,9 +34,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` varying vec2 vUv; @@ -50,6 +46,7 @@ }` }; + /** * The god-ray generation shader. * @@ -77,9 +74,7 @@ value: new THREE.Vector3() } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -89,9 +84,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` #define TAPS_PER_PASS 6.0 @@ -177,6 +170,7 @@ }` }; + /** * Additively applies god rays from texture tGodRays to a background (tColors). * fGodRayIntensity attenuates the god rays. @@ -194,9 +188,7 @@ value: 0.69 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -206,9 +198,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` varying vec2 vUv; @@ -228,6 +218,7 @@ }` }; + /** * A dodgy sun/sky shader. Makes a bright spot at the sun location. Would be * cheaper/faster/simpler to implement this as a simple sun sprite. @@ -248,9 +239,7 @@ value: new THREE.Color( 0x000000 ) } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -260,9 +249,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` varying vec2 vUv; diff --git a/examples/js/shaders/HalftoneShader.js b/examples/js/shaders/HalftoneShader.js index 31313be5df3124..ea0a099f8e8e3f 100644 --- a/examples/js/shaders/HalftoneShader.js +++ b/examples/js/shaders/HalftoneShader.js @@ -6,6 +6,7 @@ * Shape (1 = Dot, 2 = Ellipse, 3 = Line, 4 = Square) * Blending Mode (1 = Linear, 2 = Multiply, 3 = Add, 4 = Lighter, 5 = Darker) */ + const HalftoneShader = { uniforms: { 'tDiffuse': { @@ -48,9 +49,7 @@ value: false } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUV; @@ -60,9 +59,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` #define SQRT2_MINUS_ONE 0.41421356 #define SQRT2_HALF_MINUS_ONE 0.20710678 diff --git a/examples/js/shaders/HorizontalBlurShader.js b/examples/js/shaders/HorizontalBlurShader.js index a2e402f13b7861..6f21b58fccc9cc 100644 --- a/examples/js/shaders/HorizontalBlurShader.js +++ b/examples/js/shaders/HorizontalBlurShader.js @@ -8,6 +8,7 @@ * - standard deviation 2.7 * - "h" and "v" parameters should be set to "1 / width" and "1 / height" */ + const HorizontalBlurShader = { uniforms: { 'tDiffuse': { @@ -17,9 +18,7 @@ value: 1.0 / 512.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -29,9 +28,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; uniform float h; diff --git a/examples/js/shaders/HorizontalTiltShiftShader.js b/examples/js/shaders/HorizontalTiltShiftShader.js index a8c1f28587e242..6c401f6830b8eb 100644 --- a/examples/js/shaders/HorizontalTiltShiftShader.js +++ b/examples/js/shaders/HorizontalTiltShiftShader.js @@ -8,6 +8,7 @@ * - "h" and "v" parameters should be set to "1 / width" and "1 / height" * - "r" parameter control where "focused" horizontal line lies */ + const HorizontalTiltShiftShader = { uniforms: { 'tDiffuse': { @@ -20,9 +21,7 @@ value: 0.35 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -32,9 +31,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; uniform float h; diff --git a/examples/js/shaders/HueSaturationShader.js b/examples/js/shaders/HueSaturationShader.js index 60e2f9b3c4a670..d1678b328f792c 100644 --- a/examples/js/shaders/HueSaturationShader.js +++ b/examples/js/shaders/HueSaturationShader.js @@ -6,6 +6,7 @@ * hue: -1 to 1 (-1 is 180 degrees in the negative direction, 0 is no change, etc. * saturation: -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast) */ + const HueSaturationShader = { uniforms: { 'tDiffuse': { @@ -18,9 +19,7 @@ value: 0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -31,9 +30,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; uniform float hue; diff --git a/examples/js/shaders/KaleidoShader.js b/examples/js/shaders/KaleidoShader.js index eacd5eead940a8..29d8961e1aefb0 100644 --- a/examples/js/shaders/KaleidoShader.js +++ b/examples/js/shaders/KaleidoShader.js @@ -9,6 +9,7 @@ * sides: number of reflections * angle: initial angle in radians */ + const KaleidoShader = { uniforms: { 'tDiffuse': { @@ -21,9 +22,7 @@ value: 0.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -33,9 +32,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; uniform float sides; diff --git a/examples/js/shaders/LuminosityHighPassShader.js b/examples/js/shaders/LuminosityHighPassShader.js index a5eab35a5bbf97..4be6ebe07011d8 100644 --- a/examples/js/shaders/LuminosityHighPassShader.js +++ b/examples/js/shaders/LuminosityHighPassShader.js @@ -24,9 +24,7 @@ value: 0.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -37,9 +35,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; uniform vec3 defaultColor; diff --git a/examples/js/shaders/LuminosityShader.js b/examples/js/shaders/LuminosityShader.js index 9367c863e18046..b5a7b31cce8997 100644 --- a/examples/js/shaders/LuminosityShader.js +++ b/examples/js/shaders/LuminosityShader.js @@ -4,15 +4,14 @@ * Luminosity * http://en.wikipedia.org/wiki/Luminosity */ + const LuminosityShader = { uniforms: { 'tDiffuse': { value: null } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -23,9 +22,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` #include @@ -37,7 +34,7 @@ vec4 texel = texture2D( tDiffuse, vUv ); - float l = linearToRelativeLuminance( texel.rgb ); + float l = luminance( texel.rgb ); gl_FragColor = vec4( l, l, l, texel.w ); diff --git a/examples/js/shaders/MMDToonShader.js b/examples/js/shaders/MMDToonShader.js index b688dc5982263e..0453010c8eb038 100644 --- a/examples/js/shaders/MMDToonShader.js +++ b/examples/js/shaders/MMDToonShader.js @@ -14,9 +14,7 @@ * (Replace lights_phong_pars_fragment with lights_mmd_toon_pars_fragment) * * Add mmd_toon_matcap_fragment. */ - const lights_mmd_toon_pars_fragment = -/* glsl */ -` + const lights_mmd_toon_pars_fragment = /* glsl */` varying vec3 vViewPosition; struct BlinnPhongMaterial { @@ -46,12 +44,8 @@ void RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in Geometric #define RE_Direct RE_Direct_BlinnPhong #define RE_IndirectDiffuse RE_IndirectDiffuse_BlinnPhong - -#define Material_LightProbeLOD( material ) (0) `; - const mmd_toon_matcap_fragment = -/* glsl */ -` + const mmd_toon_matcap_fragment = /* glsl */` #ifdef USE_MATCAP vec3 viewDir = normalize( vViewPosition ); diff --git a/examples/js/shaders/MirrorShader.js b/examples/js/shaders/MirrorShader.js index e6796ec09a1957..cef216fadd88ce 100644 --- a/examples/js/shaders/MirrorShader.js +++ b/examples/js/shaders/MirrorShader.js @@ -6,6 +6,7 @@ * * side: side of input to mirror (0 = left, 1 = right, 2 = top, 3 = bottom) */ + const MirrorShader = { uniforms: { 'tDiffuse': { @@ -15,9 +16,7 @@ value: 1 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -27,9 +26,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; uniform int side; diff --git a/examples/js/shaders/NormalMapShader.js b/examples/js/shaders/NormalMapShader.js index 17d2046df2789b..6ee9beff78bfeb 100644 --- a/examples/js/shaders/NormalMapShader.js +++ b/examples/js/shaders/NormalMapShader.js @@ -20,9 +20,7 @@ value: 0.05 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -32,9 +30,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform float height; uniform vec2 resolution; diff --git a/examples/js/shaders/PixelShader.js b/examples/js/shaders/PixelShader.js deleted file mode 100644 index 71037d69ac9db0..00000000000000 --- a/examples/js/shaders/PixelShader.js +++ /dev/null @@ -1,51 +0,0 @@ -( function () { - - /** - * Pixelation shader - */ - const PixelShader = { - uniforms: { - 'tDiffuse': { - value: null - }, - 'resolution': { - value: null - }, - 'pixelSize': { - value: 1 - } - }, - vertexShader: - /* glsl */ - ` - - varying highp vec2 vUv; - - void main() { - - vUv = uv; - gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); - - }`, - fragmentShader: - /* glsl */ - ` - - uniform sampler2D tDiffuse; - uniform float pixelSize; - uniform vec2 resolution; - - varying highp vec2 vUv; - - void main(){ - - vec2 dxy = pixelSize / resolution; - vec2 coord = dxy * floor( vUv / dxy ); - gl_FragColor = texture2D(tDiffuse, coord); - - }` - }; - - THREE.PixelShader = PixelShader; - -} )(); diff --git a/examples/js/shaders/RGBShiftShader.js b/examples/js/shaders/RGBShiftShader.js index 2c7b78a152479d..cf1dc7410cecbe 100644 --- a/examples/js/shaders/RGBShiftShader.js +++ b/examples/js/shaders/RGBShiftShader.js @@ -9,6 +9,7 @@ * amount: shift distance (1 is width of input) * angle: shift angle in radians */ + const RGBShiftShader = { uniforms: { 'tDiffuse': { @@ -21,9 +22,7 @@ value: 0.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -33,9 +32,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; uniform float amount; diff --git a/examples/js/shaders/SAOShader.js b/examples/js/shaders/SAOShader.js index 06083e2d804772..c476dda5691a53 100644 --- a/examples/js/shaders/SAOShader.js +++ b/examples/js/shaders/SAOShader.js @@ -57,9 +57,7 @@ value: 0.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -67,9 +65,7 @@ vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` #include diff --git a/examples/js/shaders/SMAAShader.js b/examples/js/shaders/SMAAShader.js index 31e13dff23965d..df784ec698d8b6 100644 --- a/examples/js/shaders/SMAAShader.js +++ b/examples/js/shaders/SMAAShader.js @@ -18,9 +18,7 @@ value: new THREE.Vector2( 1 / 1024, 1 / 512 ) } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` uniform vec2 resolution; @@ -42,9 +40,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; @@ -130,9 +126,7 @@ value: new THREE.Vector2( 1 / 1024, 1 / 512 ) } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` uniform vec2 resolution; @@ -161,9 +155,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` #define SMAASampleLevelZeroOffset( tex, coord, offset ) texture2D( tex, coord + float( offset ) * resolution, 0.0 ) @@ -377,9 +369,7 @@ value: new THREE.Vector2( 1 / 1024, 1 / 512 ) } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` uniform vec2 resolution; @@ -400,9 +390,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; uniform sampler2D tColor; diff --git a/examples/js/shaders/SSAOShader.js b/examples/js/shaders/SSAOShader.js index 664908e4e50156..42875eb0aad2e5 100644 --- a/examples/js/shaders/SSAOShader.js +++ b/examples/js/shaders/SSAOShader.js @@ -53,9 +53,7 @@ value: 0.05 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -66,9 +64,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; uniform sampler2D tNormal; diff --git a/examples/js/shaders/SSRShader.js b/examples/js/shaders/SSRShader.js index ae9327c29e1393..d614ae58862b1a 100644 --- a/examples/js/shaders/SSRShader.js +++ b/examples/js/shaders/SSRShader.js @@ -55,9 +55,7 @@ value: .018 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -70,9 +68,7 @@ } `, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` // precision highp float; precision highp sampler2D; varying vec2 vUv; @@ -266,9 +262,7 @@ value: null } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -280,9 +274,7 @@ } `, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDepth; @@ -332,9 +324,7 @@ value: .5 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -346,9 +336,7 @@ } `, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; uniform vec2 resolution; diff --git a/examples/js/shaders/SepiaShader.js b/examples/js/shaders/SepiaShader.js index 304476cdb67583..201073cff8b063 100644 --- a/examples/js/shaders/SepiaShader.js +++ b/examples/js/shaders/SepiaShader.js @@ -5,6 +5,7 @@ * based on glfx.js sepia shader * https://github.com/evanw/glfx.js */ + const SepiaShader = { uniforms: { 'tDiffuse': { @@ -14,9 +15,7 @@ value: 1.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -26,9 +25,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform float amount; diff --git a/examples/js/shaders/SobelOperatorShader.js b/examples/js/shaders/SobelOperatorShader.js index 88ba7c1c54af2e..88f19274a91643 100644 --- a/examples/js/shaders/SobelOperatorShader.js +++ b/examples/js/shaders/SobelOperatorShader.js @@ -16,9 +16,7 @@ value: new THREE.Vector2() } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -29,9 +27,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; uniform vec2 resolution; diff --git a/examples/js/shaders/TechnicolorShader.js b/examples/js/shaders/TechnicolorShader.js index 2df35dca86f0a7..b8963c4c8e0abd 100644 --- a/examples/js/shaders/TechnicolorShader.js +++ b/examples/js/shaders/TechnicolorShader.js @@ -6,15 +6,14 @@ * More historical info here: http://www.widescreenmuseum.com/oldcolor/technicolor1.htm * Demo here: http://charliehoey.com/technicolor_shader/shader_test.html */ + const TechnicolorShader = { uniforms: { 'tDiffuse': { value: null } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -24,9 +23,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; varying vec2 vUv; diff --git a/examples/js/shaders/ToneMapShader.js b/examples/js/shaders/ToneMapShader.js index 24d0f4b3659d8e..14929cdc642b7f 100644 --- a/examples/js/shaders/ToneMapShader.js +++ b/examples/js/shaders/ToneMapShader.js @@ -3,6 +3,7 @@ /** * Full-screen tone-mapping shader based on http://www.cis.rit.edu/people/faculty/ferwerda/publications/sig02_paper.pdf */ + const ToneMapShader = { uniforms: { 'tDiffuse': { @@ -24,9 +25,7 @@ value: 0.6 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -36,9 +35,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` #include @@ -64,7 +61,7 @@ #endif // Calculate the luminance of the current pixel - float fLumPixel = linearToRelativeLuminance( vColor ); + float fLumPixel = luminance( vColor ); // Apply the modified operator (Eq. 4) float fLumScaled = (fLumPixel * middleGrey) / max( minLuminance, fLumAvg ); diff --git a/examples/js/shaders/ToonShader.js b/examples/js/shaders/ToonShader.js index fb0d84fcfc8cb6..0bd25650ca05eb 100644 --- a/examples/js/shaders/ToonShader.js +++ b/examples/js/shaders/ToonShader.js @@ -24,9 +24,7 @@ value: new THREE.Color( 0xffffff ) } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec3 vNormal; varying vec3 vRefract; @@ -45,9 +43,7 @@ gl_Position = projectionMatrix * mvPosition; }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform vec3 uBaseColor; @@ -111,9 +107,7 @@ value: new THREE.Color( 0x000000 ) } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec3 vNormal; @@ -123,9 +117,7 @@ vNormal = normalize( normalMatrix * normal ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform vec3 uBaseColor; uniform vec3 uLineColor1; @@ -188,9 +180,7 @@ value: new THREE.Color( 0x000000 ) } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec3 vNormal; @@ -200,9 +190,7 @@ vNormal = normalize( normalMatrix * normal ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform vec3 uBaseColor; uniform vec3 uLineColor1; @@ -284,9 +272,7 @@ value: new THREE.Color( 0x000000 ) } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec3 vNormal; @@ -296,9 +282,7 @@ vNormal = normalize( normalMatrix * normal ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform vec3 uBaseColor; uniform vec3 uLineColor1; diff --git a/examples/js/shaders/TriangleBlurShader.js b/examples/js/shaders/TriangleBlurShader.js index 4b27895724c088..6e2808adb05ec5 100644 --- a/examples/js/shaders/TriangleBlurShader.js +++ b/examples/js/shaders/TriangleBlurShader.js @@ -19,9 +19,7 @@ value: new THREE.Vector2( 1, 1 ) } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -31,9 +29,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` #include diff --git a/examples/js/shaders/UnpackDepthRGBAShader.js b/examples/js/shaders/UnpackDepthRGBAShader.js index 256e08df2c8fb7..c7d503b2e713a7 100644 --- a/examples/js/shaders/UnpackDepthRGBAShader.js +++ b/examples/js/shaders/UnpackDepthRGBAShader.js @@ -4,6 +4,7 @@ * Unpack RGBA depth shader * - show RGBA encoded depth as monochrome color */ + const UnpackDepthRGBAShader = { uniforms: { 'tDiffuse': { @@ -13,9 +14,7 @@ value: 1.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -25,9 +24,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform float opacity; diff --git a/examples/js/shaders/VelocityShader.js b/examples/js/shaders/VelocityShader.js new file mode 100644 index 00000000000000..a6da374b908c2e --- /dev/null +++ b/examples/js/shaders/VelocityShader.js @@ -0,0 +1,126 @@ +( function () { + + /** + * Mesh Velocity Shader @bhouston + */ + + const VelocityShader = { + uniforms: THREE.UniformsUtils.merge( [ THREE.UniformsLib.common, THREE.UniformsLib.displacementmap, { + modelMatrixPrev: { + value: new THREE.Matrix4() + }, + currentProjectionViewMatrix: { + value: new THREE.Matrix4() + }, + previousProjectionViewMatrix: { + value: new THREE.Matrix4() + } + } ] ), + vertexShader: /* glsl */` +#define NORMAL + +#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP ) + + varying vec3 vViewPosition; + +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +uniform mat4 previousProjectionViewMatrix; +uniform mat4 currentProjectionViewMatrix; + +uniform mat4 modelMatrixPrev; + +varying vec4 clipPositionCurrent; +varying vec4 clipPositionPrevious; + +void main() { + + + #include + + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + +#ifdef USE_SKINNING + + vec4 mvPosition = modelViewMatrix * skinned; + clipPositionCurrent = currentProjectionViewMatrix * modelMatrix * skinned; + clipPositionPrevious = previousProjectionViewMatrix * modelMatrixPrev * skinned; + +#else + + vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 ); + clipPositionCurrent = currentProjectionViewMatrix * modelMatrix * vec4( transformed, 1.0 ); + clipPositionPrevious = previousProjectionViewMatrix * modelMatrixPrev * vec4( transformed, 1.0 ); + +#endif + + gl_Position = projectionMatrix * mvPosition; + + #include + #include +} +`, + fragmentShader: /* glsl */` +#define NORMAL + +uniform float opacity; + +#include +#include +#include +#include +#include +#include +#include + +varying vec4 clipPositionCurrent; +varying vec4 clipPositionPrevious; + +void main() { + + vec4 diffuseColor = vec4( 1.0 ); + diffuseColor.a = opacity; + + #include + #include + #include + + vec2 ndcPositionCurrent = clipPositionCurrent.xy/clipPositionCurrent.w; + vec2 ndcPositionPrevious = clipPositionPrevious.xy/clipPositionPrevious.w; + vec2 vel = ( ndcPositionCurrent - ndcPositionPrevious ) * 0.5; + vel = vel * 0.5 + 0.5; + vec2 v1 = packDepthToRG(vel.x); + vec2 v2 = packDepthToRG(vel.y); + gl_FragColor = vec4(v1.x, v1.y, v2.x, v2.y); + + #include + +} + +` + }; + + THREE.VelocityShader = VelocityShader; + +} )(); diff --git a/examples/js/shaders/VerticalBlurShader.js b/examples/js/shaders/VerticalBlurShader.js index 6a7b5f5d7d34f3..4382a2fe290380 100644 --- a/examples/js/shaders/VerticalBlurShader.js +++ b/examples/js/shaders/VerticalBlurShader.js @@ -8,6 +8,7 @@ * - standard deviation 2.7 * - "h" and "v" parameters should be set to "1 / width" and "1 / height" */ + const VerticalBlurShader = { uniforms: { 'tDiffuse': { @@ -17,9 +18,7 @@ value: 1.0 / 512.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -29,9 +28,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; uniform float v; diff --git a/examples/js/shaders/VerticalTiltShiftShader.js b/examples/js/shaders/VerticalTiltShiftShader.js index 95ff8f00295950..c3419a16af7116 100644 --- a/examples/js/shaders/VerticalTiltShiftShader.js +++ b/examples/js/shaders/VerticalTiltShiftShader.js @@ -8,6 +8,7 @@ * - "h" and "v" parameters should be set to "1 / width" and "1 / height" * - "r" parameter control where "focused" horizontal line lies */ + const VerticalTiltShiftShader = { uniforms: { 'tDiffuse': { @@ -20,9 +21,7 @@ value: 0.35 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -32,9 +31,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform sampler2D tDiffuse; uniform float v; diff --git a/examples/js/shaders/VignetteShader.js b/examples/js/shaders/VignetteShader.js index cadb343b978ee1..6b5d84a7b87466 100644 --- a/examples/js/shaders/VignetteShader.js +++ b/examples/js/shaders/VignetteShader.js @@ -5,6 +5,7 @@ * based on PaintEffect postprocess from ro.me * http://code.google.com/p/3-dreams-of-black/source/browse/deploy/js/effects/PaintEffect.js */ + const VignetteShader = { uniforms: { 'tDiffuse': { @@ -17,9 +18,7 @@ value: 1.0 } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec2 vUv; @@ -29,9 +28,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform float offset; uniform float darkness; diff --git a/examples/js/shaders/VolumeShader.js b/examples/js/shaders/VolumeShader.js index 6c8648fe1e5a93..3dece35e7d01c5 100644 --- a/examples/js/shaders/VolumeShader.js +++ b/examples/js/shaders/VolumeShader.js @@ -27,9 +27,7 @@ value: null } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` varying vec4 v_nearpos; varying vec4 v_farpos; @@ -60,9 +58,7 @@ v_position = position; gl_Position = projectionMatrix * viewMatrix * modelMatrix * position4; }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` precision highp float; precision mediump sampler3D; diff --git a/examples/js/shaders/WaterRefractionShader.js b/examples/js/shaders/WaterRefractionShader.js index 5e643d69c30b42..fa1a1d6a2b9d4e 100644 --- a/examples/js/shaders/WaterRefractionShader.js +++ b/examples/js/shaders/WaterRefractionShader.js @@ -18,9 +18,7 @@ value: null } }, - vertexShader: - /* glsl */ - ` + vertexShader: /* glsl */` uniform mat4 textureMatrix; @@ -36,9 +34,7 @@ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, - fragmentShader: - /* glsl */ - ` + fragmentShader: /* glsl */` uniform vec3 color; uniform float time; diff --git a/examples/js/textures/FlakesTexture.js b/examples/js/textures/FlakesTexture.js index 1f93e2ee240edc..1084e2739a75fe 100644 --- a/examples/js/textures/FlakesTexture.js +++ b/examples/js/textures/FlakesTexture.js @@ -10,7 +10,6 @@ const context = canvas.getContext( '2d' ); context.fillStyle = 'rgb(127,127,255)'; context.fillRect( 0, 0, width, height ); - for ( let i = 0; i < 4000; i ++ ) { const x = Math.random() * width; diff --git a/examples/js/utils/BufferGeometryUtils.js b/examples/js/utils/BufferGeometryUtils.js index 8c7f93edec8ed3..7450f63b914d76 100644 --- a/examples/js/utils/BufferGeometryUtils.js +++ b/examples/js/utils/BufferGeometryUtils.js @@ -24,17 +24,14 @@ if ( attribute.normalized || attribute.isInterleavedBufferAttribute ) { - const srcArray = attribute.isInterleavedBufferAttribute ? attribute.data.array : attribute.array; const dstArray = new Float32Array( attribute.getCount() * attribute.itemSize ); - for ( let i = 0, j = 0; i < attribute.getCount(); i ++ ) { - dstArray[ j ++ ] = THREE.MathUtils.denormalize( attribute.getX( i ), srcArray ); - dstArray[ j ++ ] = THREE.MathUtils.denormalize( attribute.getY( i ), srcArray ); - + dstArray[ j ++ ] = attribute.getX( i ); + dstArray[ j ++ ] = attribute.getY( i ); if ( attribute.itemSize > 2 ) { - dstArray[ j ++ ] = THREE.MathUtils.denormalize( attribute.getZ( i ), srcArray ); + dstArray[ j ++ ] = attribute.getZ( i ); } @@ -52,13 +49,17 @@ return new Float32Array( attribute.array ); - } // MikkTSpace algorithm requires non-indexed input. + } + + // MikkTSpace algorithm requires non-indexed input. + const _geometry = geometry.index ? geometry.toNonIndexed() : geometry; - const _geometry = geometry.index ? geometry.toNonIndexed() : geometry; // Compute vertex tangents. + // Compute vertex tangents. + const tangents = MikkTSpace.generateTangents( getAttributeArray( _geometry.attributes.position ), getAttributeArray( _geometry.attributes.normal ), getAttributeArray( _geometry.attributes.uv ) ); - const tangents = MikkTSpace.generateTangents( getAttributeArray( _geometry.attributes.position ), getAttributeArray( _geometry.attributes.normal ), getAttributeArray( _geometry.attributes.uv ) ); // Texture coordinate convention of glTF differs from the apparent + // Texture coordinate convention of glTF differs from the apparent // default of the MikkTSpace library; .w component must be flipped. if ( negateSign ) { @@ -69,11 +70,11 @@ } - } // + } + // _geometry.setAttribute( 'tangent', new THREE.BufferAttribute( tangents, 4 ) ); - if ( geometry !== _geometry ) { geometry.copy( _geometry ); @@ -83,13 +84,12 @@ return geometry; } + /** * @param {Array} geometries * @param {Boolean} useGroups * @return {BufferGeometry} */ - - function mergeBufferGeometries( geometries, useGroups = false ) { const isIndexed = geometries[ 0 ].index !== null; @@ -100,19 +100,21 @@ const morphTargetsRelative = geometries[ 0 ].morphTargetsRelative; const mergedGeometry = new THREE.BufferGeometry(); let offset = 0; - for ( let i = 0; i < geometries.length; ++ i ) { const geometry = geometries[ i ]; - let attributesCount = 0; // ensure that all geometries are indexed, or none + let attributesCount = 0; + + // ensure that all geometries are indexed, or none if ( isIndexed !== ( geometry.index !== null ) ) { console.error( 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' + i + '. All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.' ); return null; - } // gather attributes, exit early if they're different + } + // gather attributes, exit early if they're different for ( const name in geometry.attributes ) { @@ -127,16 +129,18 @@ attributes[ name ].push( geometry.attributes[ name ] ); attributesCount ++; - } // ensure geometries have the same number of attributes + } + // ensure geometries have the same number of attributes if ( attributesCount !== attributesUsed.size ) { console.error( 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' + i + '. Make sure all geometries have the same number of attributes.' ); return null; - } // gather morph attributes, exit early if they're different + } + // gather morph attributes, exit early if they're different if ( morphTargetsRelative !== geometry.morphTargetsRelative ) { @@ -157,16 +161,11 @@ if ( morphAttributes[ name ] === undefined ) morphAttributes[ name ] = []; morphAttributes[ name ].push( geometry.morphAttributes[ name ] ); - } // gather .userData - - - mergedGeometry.userData.mergedUserData = mergedGeometry.userData.mergedUserData || []; - mergedGeometry.userData.mergedUserData.push( geometry.userData ); + } if ( useGroups ) { let count; - if ( isIndexed ) { count = geometry.index.count; @@ -187,18 +186,17 @@ } - } // merge indices + } + // merge indices if ( isIndexed ) { let indexOffset = 0; const mergedIndex = []; - for ( let i = 0; i < geometries.length; ++ i ) { const index = geometries[ i ].index; - for ( let j = 0; j < index.count; ++ j ) { mergedIndex.push( index.getX( j ) + indexOffset ); @@ -211,13 +209,13 @@ mergedGeometry.setIndex( mergedIndex ); - } // merge attributes + } + // merge attributes for ( const name in attributes ) { const mergedAttribute = mergeBufferAttributes( attributes[ name ] ); - if ( ! mergedAttribute ) { console.error( 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed while trying to merge the ' + name + ' attribute.' ); @@ -227,8 +225,9 @@ mergedGeometry.setAttribute( name, mergedAttribute ); - } // merge morph attributes + } + // merge morph attributes for ( const name in morphAttributes ) { @@ -236,11 +235,9 @@ if ( numMorphTargets === 0 ) break; mergedGeometry.morphAttributes = mergedGeometry.morphAttributes || {}; mergedGeometry.morphAttributes[ name ] = []; - for ( let i = 0; i < numMorphTargets; ++ i ) { const morphAttributesToMerge = []; - for ( let j = 0; j < morphAttributes[ name ].length; ++ j ) { morphAttributesToMerge.push( morphAttributes[ name ][ j ][ i ] ); @@ -248,7 +245,6 @@ } const mergedMorphAttribute = mergeBufferAttributes( morphAttributesToMerge ); - if ( ! mergedMorphAttribute ) { console.error( 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed while trying to merge the ' + name + ' morphAttribute.' ); @@ -265,23 +261,20 @@ return mergedGeometry; } + /** * @param {Array} attributes * @return {BufferAttribute} */ - - function mergeBufferAttributes( attributes ) { let TypedArray; let itemSize; let normalized; let arrayLength = 0; - for ( let i = 0; i < attributes.length; ++ i ) { const attribute = attributes[ i ]; - if ( attribute.isInterleavedBufferAttribute ) { console.error( 'THREE.BufferGeometryUtils: .mergeBufferAttributes() failed. InterleavedBufferAttributes are not supported.' ); @@ -290,7 +283,6 @@ } if ( TypedArray === undefined ) TypedArray = attribute.array.constructor; - if ( TypedArray !== attribute.array.constructor ) { console.error( 'THREE.BufferGeometryUtils: .mergeBufferAttributes() failed. THREE.BufferAttribute.array must be of consistent array types across matching attributes.' ); @@ -299,7 +291,6 @@ } if ( itemSize === undefined ) itemSize = attribute.itemSize; - if ( itemSize !== attribute.itemSize ) { console.error( 'THREE.BufferGeometryUtils: .mergeBufferAttributes() failed. THREE.BufferAttribute.itemSize must be consistent across matching attributes.' ); @@ -308,7 +299,6 @@ } if ( normalized === undefined ) normalized = attribute.normalized; - if ( normalized !== attribute.normalized ) { console.error( 'THREE.BufferGeometryUtils: .mergeBufferAttributes() failed. THREE.BufferAttribute.normalized must be consistent across matching attributes.' ); @@ -322,7 +312,6 @@ const array = new TypedArray( arrayLength ); let offset = 0; - for ( let i = 0; i < attributes.length; ++ i ) { array.set( attributes[ i ].array, offset ); @@ -333,25 +322,46 @@ return new THREE.BufferAttribute( array, itemSize, normalized ); } + /** - * @param {Array} attributes - * @return {Array} + * @param {BufferAttribute} + * @return {BufferAttribute} */ + function deepCloneAttribute( attribute ) { + + if ( attribute.isInstancedInterleavedBufferAttribute || attribute.isInterleavedBufferAttribute ) { + return deinterleaveAttribute( attribute ); + + } + if ( attribute.isInstancedBufferAttribute ) { + + return new THREE.InstancedBufferAttribute().copy( attribute ); + + } + + return new THREE.BufferAttribute().copy( attribute ); + + } + + /** + * @param {Array} attributes + * @return {Array} + */ function interleaveAttributes( attributes ) { // Interleaves the provided attributes into an THREE.InterleavedBuffer and returns // a set of InterleavedBufferAttributes for each attribute let TypedArray; let arrayLength = 0; - let stride = 0; // calculate the the length and type of the interleavedBuffer + let stride = 0; + // calculate the length and type of the interleavedBuffer for ( let i = 0, l = attributes.length; i < l; ++ i ) { const attribute = attributes[ i ]; if ( TypedArray === undefined ) TypedArray = attribute.array.constructor; - if ( TypedArray !== attribute.array.constructor ) { console.error( 'AttributeBuffers of different types cannot be interleaved' ); @@ -362,15 +372,14 @@ arrayLength += attribute.array.length; stride += attribute.itemSize; - } // Create the set of buffer attributes - + } + // Create the set of buffer attributes const interleavedBuffer = new THREE.InterleavedBuffer( new TypedArray( arrayLength ), stride ); let offset = 0; const res = []; const getters = [ 'getX', 'getY', 'getZ', 'getW' ]; const setters = [ 'setX', 'setY', 'setZ', 'setW' ]; - for ( let j = 0, l = attributes.length; j < l; j ++ ) { const attribute = attributes[ j ]; @@ -378,9 +387,10 @@ const count = attribute.count; const iba = new THREE.InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, attribute.normalized ); res.push( iba ); - offset += itemSize; // Move the data for each attribute into the new interleavedBuffer - // at the appropriate offset + offset += itemSize; + // Move the data for each attribute into the new interleavedBuffer + // at the appropriate offset for ( let c = 0; c < count; c ++ ) { for ( let k = 0; k < itemSize; k ++ ) { @@ -395,9 +405,9 @@ return res; - } // returns a new, non-interleaved version of the provided attribute - + } + // returns a new, non-interleaved version of the provided attribute function deinterleaveAttribute( attribute ) { const cons = attribute.data.array.constructor; @@ -406,7 +416,6 @@ const normalized = attribute.normalized; const array = new cons( count * itemSize ); let newAttribute; - if ( attribute.isInstancedInterleavedBufferAttribute ) { newAttribute = new THREE.InstancedBufferAttribute( array, itemSize, normalized, attribute.meshPerAttribute ); @@ -420,7 +429,6 @@ for ( let i = 0; i < count; i ++ ) { newAttribute.setX( i, attribute.getX( i ) ); - if ( itemSize >= 2 ) { newAttribute.setY( i, attribute.getY( i ) ); @@ -443,18 +451,17 @@ return newAttribute; - } // deinterleaves all attributes on the geometry + } + // deinterleaves all attributes on the geometry function deinterleaveGeometry( geometry ) { const attributes = geometry.attributes; const morphTargets = geometry.morphTargets; const attrMap = new Map(); - for ( const key in attributes ) { const attr = attributes[ key ]; - if ( attr.isInterleavedBufferAttribute ) { if ( ! attrMap.has( attr ) ) { @@ -472,7 +479,6 @@ for ( const key in morphTargets ) { const attr = morphTargets[ key ]; - if ( attr.isInterleavedBufferAttribute ) { if ( ! attrMap.has( attr ) ) { @@ -488,18 +494,17 @@ } } + /** * @param {Array} geometry * @return {number} */ - function estimateBytesUsed( geometry ) { // Return the estimated memory used by this geometry in bytes // Calculate using itemSize, count, and BYTES_PER_ELEMENT to account // for InterleavedBufferAttributes. let mem = 0; - for ( const name in geometry.attributes ) { const attr = geometry.getAttribute( name ); @@ -512,61 +517,64 @@ return mem; } + /** * @param {BufferGeometry} geometry * @param {number} tolerance - * @return {BufferGeometry>} + * @return {BufferGeometry} */ - - function mergeVertices( geometry, tolerance = 1e-4 ) { - tolerance = Math.max( tolerance, Number.EPSILON ); // Generate an index buffer if the geometry doesn't have one, or optimize it - // if it's already available. + tolerance = Math.max( tolerance, Number.EPSILON ); + // Generate an index buffer if the geometry doesn't have one, or optimize it + // if it's already available. const hashToIndex = {}; const indices = geometry.getIndex(); const positions = geometry.getAttribute( 'position' ); - const vertexCount = indices ? indices.count : positions.count; // next value for triangle indices + const vertexCount = indices ? indices.count : positions.count; - let nextIndex = 0; // attributes and new attribute arrays + // next value for triangle indices + let nextIndex = 0; + // attributes and new attribute arrays const attributeNames = Object.keys( geometry.attributes ); - const attrArrays = {}; - const morphAttrsArrays = {}; + const tmpAttributes = {}; + const tmpMorphAttributes = {}; const newIndices = []; - const getters = [ 'getX', 'getY', 'getZ', 'getW' ]; // initialize the arrays + const getters = [ 'getX', 'getY', 'getZ', 'getW' ]; + const setters = [ 'setX', 'setY', 'setZ', 'setW' ]; + // Initialize the arrays, allocating space conservatively. Extra + // space will be trimmed in the last step. for ( let i = 0, l = attributeNames.length; i < l; i ++ ) { const name = attributeNames[ i ]; - attrArrays[ name ] = []; + const attr = geometry.attributes[ name ]; + tmpAttributes[ name ] = new THREE.BufferAttribute( new attr.array.constructor( attr.count * attr.itemSize ), attr.itemSize, attr.normalized ); const morphAttr = geometry.morphAttributes[ name ]; - if ( morphAttr ) { - morphAttrsArrays[ name ] = new Array( morphAttr.length ).fill().map( () => [] ); + tmpMorphAttributes[ name ] = new THREE.BufferAttribute( new morphAttr.array.constructor( morphAttr.count * morphAttr.itemSize ), morphAttr.itemSize, morphAttr.normalized ); } - } // convert the error tolerance to an amount of decimal places to truncate to - + } + // convert the error tolerance to an amount of decimal places to truncate to const decimalShift = Math.log10( 1 / tolerance ); const shiftMultiplier = Math.pow( 10, decimalShift ); - for ( let i = 0; i < vertexCount; i ++ ) { - const index = indices ? indices.getX( i ) : i; // Generate a hash for the vertex attributes at the current index 'i' + const index = indices ? indices.getX( i ) : i; + // Generate a hash for the vertex attributes at the current index 'i' let hash = ''; - for ( let j = 0, l = attributeNames.length; j < l; j ++ ) { const name = attributeNames[ j ]; const attribute = geometry.getAttribute( name ); const itemSize = attribute.itemSize; - for ( let k = 0; k < itemSize; k ++ ) { // double tilde truncates the decimal value @@ -574,36 +582,35 @@ } - } // Add another reference to the vertex if it's already - // used by another index - + } + // Add another reference to the vertex if it's already + // used by another index if ( hash in hashToIndex ) { newIndices.push( hashToIndex[ hash ] ); } else { - // copy data to the new index in the attribute arrays + // copy data to the new index in the temporary attributes for ( let j = 0, l = attributeNames.length; j < l; j ++ ) { const name = attributeNames[ j ]; const attribute = geometry.getAttribute( name ); const morphAttr = geometry.morphAttributes[ name ]; const itemSize = attribute.itemSize; - const newarray = attrArrays[ name ]; - const newMorphArrays = morphAttrsArrays[ name ]; - + const newarray = tmpAttributes[ name ]; + const newMorphArrays = tmpMorphAttributes[ name ]; for ( let k = 0; k < itemSize; k ++ ) { const getterFunc = getters[ k ]; - newarray.push( attribute[ getterFunc ]( index ) ); - + const setterFunc = setters[ k ]; + newarray[ setterFunc ]( nextIndex, attribute[ getterFunc ]( index ) ); if ( morphAttr ) { for ( let m = 0, ml = morphAttr.length; m < ml; m ++ ) { - newMorphArrays[ m ].push( morphAttr[ m ][ getterFunc ]( index ) ); + newMorphArrays[ m ][ setterFunc ]( nextIndex, morphAttr[ m ][ getterFunc ]( index ) ); } @@ -619,47 +626,36 @@ } - } // Generate typed arrays from new attribute arrays and update - // the attributeBuffers - + } + // generate result THREE.BufferGeometry const result = geometry.clone(); + for ( const name in geometry.attributes ) { - for ( let i = 0, l = attributeNames.length; i < l; i ++ ) { - - const name = attributeNames[ i ]; - const oldAttribute = geometry.getAttribute( name ); - const buffer = new oldAttribute.array.constructor( attrArrays[ name ] ); - const attribute = new THREE.BufferAttribute( buffer, oldAttribute.itemSize, oldAttribute.normalized ); - result.setAttribute( name, attribute ); // Update the attribute arrays - - if ( name in morphAttrsArrays ) { - - for ( let j = 0; j < morphAttrsArrays[ name ].length; j ++ ) { - - const oldMorphAttribute = geometry.morphAttributes[ name ][ j ]; - const buffer = new oldMorphAttribute.array.constructor( morphAttrsArrays[ name ][ j ] ); - const morphAttribute = new THREE.BufferAttribute( buffer, oldMorphAttribute.itemSize, oldMorphAttribute.normalized ); - result.morphAttributes[ name ][ j ] = morphAttribute; + const tmpAttribute = tmpAttributes[ name ]; + result.setAttribute( name, new THREE.BufferAttribute( tmpAttribute.array.slice( 0, nextIndex * tmpAttribute.itemSize ), tmpAttribute.itemSize, tmpAttribute.normalized ) ); + if ( ! ( name in tmpMorphAttributes ) ) continue; + for ( let j = 0; j < tmpMorphAttributes[ name ].length; j ++ ) { - } + const tmpMorphAttribute = tmpMorphAttributes[ name ][ j ]; + result.morphAttributes[ name ][ j ] = new THREE.BufferAttribute( tmpMorphAttribute.array.slice( 0, nextIndex * tmpMorphAttribute.itemSize ), tmpMorphAttribute.itemSize, tmpMorphAttribute.normalized ); } - } // indices + } + // indices result.setIndex( newIndices ); return result; } + /** * @param {BufferGeometry} geometry * @param {number} drawMode - * @return {BufferGeometry>} + * @return {BufferGeometry} */ - - function toTrianglesDrawMode( geometry, drawMode ) { if ( drawMode === THREE.TrianglesDrawMode ) { @@ -671,13 +667,14 @@ if ( drawMode === THREE.TriangleFanDrawMode || drawMode === THREE.TriangleStripDrawMode ) { - let index = geometry.getIndex(); // generate index if not present + let index = geometry.getIndex(); + + // generate index if not present if ( index === null ) { const indices = []; const position = geometry.getAttribute( 'position' ); - if ( position !== undefined ) { for ( let i = 0; i < position.count; i ++ ) { @@ -696,15 +693,16 @@ } - } // + } + // const numberOfTriangles = index.count - 2; const newIndices = []; - if ( drawMode === THREE.TriangleFanDrawMode ) { // gl.TRIANGLE_FAN + for ( let i = 1; i <= numberOfTriangles; i ++ ) { newIndices.push( index.getX( 0 ) ); @@ -716,6 +714,7 @@ } else { // gl.TRIANGLE_STRIP + for ( let i = 0; i < numberOfTriangles; i ++ ) { if ( i % 2 === 0 ) { @@ -740,8 +739,9 @@ console.error( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.' ); - } // build final geometry + } + // build final geometry const newGeometry = geometry.clone(); newGeometry.setIndex( newIndices ); @@ -756,14 +756,13 @@ } } + /** * Calculates the morphed attributes of a morphed/skinned THREE.BufferGeometry. * Helpful for Raytracing or Decals. * @param {Mesh | Line | Points} object An instance of Mesh, Line or Points. * @return {Object} An Object with original position/normal attributes and morphed ones. */ - - function computeMorphedAttributes( object ) { if ( object.geometry.isBufferGeometry !== true ) { @@ -774,67 +773,43 @@ } const _vA = new THREE.Vector3(); - const _vB = new THREE.Vector3(); - const _vC = new THREE.Vector3(); - const _tempA = new THREE.Vector3(); - const _tempB = new THREE.Vector3(); - const _tempC = new THREE.Vector3(); - const _morphA = new THREE.Vector3(); - const _morphB = new THREE.Vector3(); - const _morphC = new THREE.Vector3(); - function _calculateMorphedAttributeData( object, attribute, morphAttribute, morphTargetsRelative, a, b, c, modifiedAttributeArray ) { _vA.fromBufferAttribute( attribute, a ); - _vB.fromBufferAttribute( attribute, b ); - _vC.fromBufferAttribute( attribute, c ); - const morphInfluences = object.morphTargetInfluences; - if ( morphAttribute && morphInfluences ) { _morphA.set( 0, 0, 0 ); - _morphB.set( 0, 0, 0 ); - _morphC.set( 0, 0, 0 ); - for ( let i = 0, il = morphAttribute.length; i < il; i ++ ) { const influence = morphInfluences[ i ]; const morph = morphAttribute[ i ]; if ( influence === 0 ) continue; - _tempA.fromBufferAttribute( morph, a ); - _tempB.fromBufferAttribute( morph, b ); - _tempC.fromBufferAttribute( morph, c ); - if ( morphTargetsRelative ) { _morphA.addScaledVector( _tempA, influence ); - _morphB.addScaledVector( _tempB, influence ); - _morphC.addScaledVector( _tempC, influence ); } else { _morphA.addScaledVector( _tempA.sub( _vA ), influence ); - _morphB.addScaledVector( _tempB.sub( _vB ), influence ); - _morphC.addScaledVector( _tempC.sub( _vC ), influence ); } @@ -842,9 +817,7 @@ } _vA.add( _morphA ); - _vB.add( _morphB ); - _vC.add( _morphC ); } @@ -885,10 +858,10 @@ let start, end; const modifiedPosition = new Float32Array( positionAttribute.count * positionAttribute.itemSize ); const modifiedNormal = new Float32Array( normalAttribute.count * normalAttribute.itemSize ); - if ( index !== null ) { // indexed buffer geometry + if ( Array.isArray( material ) ) { for ( i = 0, il = groups.length; i < il; i ++ ) { @@ -896,15 +869,12 @@ group = groups[ i ]; start = Math.max( group.start, drawRange.start ); end = Math.min( group.start + group.count, drawRange.start + drawRange.count ); - for ( j = start, jl = end; j < jl; j += 3 ) { a = index.getX( j ); b = index.getX( j + 1 ); c = index.getX( j + 2 ); - _calculateMorphedAttributeData( object, positionAttribute, morphPosition, morphTargetsRelative, a, b, c, modifiedPosition ); - _calculateMorphedAttributeData( object, normalAttribute, morphNormal, morphTargetsRelative, a, b, c, modifiedNormal ); } @@ -915,15 +885,12 @@ start = Math.max( 0, drawRange.start ); end = Math.min( index.count, drawRange.start + drawRange.count ); - for ( i = start, il = end; i < il; i += 3 ) { a = index.getX( i ); b = index.getX( i + 1 ); c = index.getX( i + 2 ); - _calculateMorphedAttributeData( object, positionAttribute, morphPosition, morphTargetsRelative, a, b, c, modifiedPosition ); - _calculateMorphedAttributeData( object, normalAttribute, morphNormal, morphTargetsRelative, a, b, c, modifiedNormal ); } @@ -933,6 +900,7 @@ } else { // non-indexed buffer geometry + if ( Array.isArray( material ) ) { for ( i = 0, il = groups.length; i < il; i ++ ) { @@ -940,15 +908,12 @@ group = groups[ i ]; start = Math.max( group.start, drawRange.start ); end = Math.min( group.start + group.count, drawRange.start + drawRange.count ); - for ( j = start, jl = end; j < jl; j += 3 ) { a = j; b = j + 1; c = j + 2; - _calculateMorphedAttributeData( object, positionAttribute, morphPosition, morphTargetsRelative, a, b, c, modifiedPosition ); - _calculateMorphedAttributeData( object, normalAttribute, morphNormal, morphTargetsRelative, a, b, c, modifiedNormal ); } @@ -959,15 +924,12 @@ start = Math.max( 0, drawRange.start ); end = Math.min( positionAttribute.count, drawRange.start + drawRange.count ); - for ( i = start, il = end; i < il; i += 3 ) { a = i; b = i + 1; c = i + 2; - _calculateMorphedAttributeData( object, positionAttribute, morphPosition, morphTargetsRelative, a, b, c, modifiedPosition ); - _calculateMorphedAttributeData( object, normalAttribute, morphNormal, morphTargetsRelative, a, b, c, modifiedNormal ); } @@ -996,20 +958,23 @@ } - let groups = geometry.groups; // sort groups by material index + let groups = geometry.groups; + + // sort groups by material index groups = groups.sort( ( a, b ) => { if ( a.materialIndex !== b.materialIndex ) return a.materialIndex - b.materialIndex; return a.start - b.start; - } ); // create index for non-indexed geometries + } ); + + // create index for non-indexed geometries if ( geometry.getIndex() === null ) { const positionAttribute = geometry.getAttribute( 'position' ); const indices = []; - for ( let i = 0; i < positionAttribute.count; i += 3 ) { indices.push( i, i + 1, i + 2 ); @@ -1018,18 +983,17 @@ geometry.setIndex( indices ); - } // sort index + } + // sort index const index = geometry.getIndex(); const newIndices = []; - for ( let i = 0; i < groups.length; i ++ ) { const group = groups[ i ]; const groupStart = group.start; const groupLength = groupStart + group.count; - for ( let j = groupStart; j < groupLength; j ++ ) { newIndices.push( index.getX( j ) ); @@ -1039,27 +1003,26 @@ } geometry.dispose(); // Required to force buffer recreation + geometry.setIndex( newIndices ); - geometry.setIndex( newIndices ); // update groups indices + // update groups indices let start = 0; - for ( let i = 0; i < groups.length; i ++ ) { const group = groups[ i ]; group.start = start; start += group.count; - } // merge groups + } + // merge groups let currentGroup = groups[ 0 ]; geometry.groups = [ currentGroup ]; - for ( let i = 1; i < groups.length; i ++ ) { const group = groups[ i ]; - if ( currentGroup.materialIndex === group.materialIndex ) { currentGroup.count += group.count; @@ -1077,10 +1040,112 @@ } + // Creates a new, non-indexed geometry with smooth normals everywhere except faces that meet at + // an angle greater than the crease angle. + function toCreasedNormals( geometry, creaseAngle = Math.PI / 3 /* 60 degrees */ ) { + + const creaseDot = Math.cos( creaseAngle ); + const hashMultiplier = ( 1 + 1e-10 ) * 1e2; + + // reusable vertors + const verts = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ]; + const tempVec1 = new THREE.Vector3(); + const tempVec2 = new THREE.Vector3(); + const tempNorm = new THREE.Vector3(); + const tempNorm2 = new THREE.Vector3(); + + // hashes a vector + function hashVertex( v ) { + + const x = ~ ~ ( v.x * hashMultiplier ); + const y = ~ ~ ( v.y * hashMultiplier ); + const z = ~ ~ ( v.z * hashMultiplier ); + return `${x},${y},${z}`; + + } + + const resultGeometry = geometry.toNonIndexed(); + const posAttr = resultGeometry.attributes.position; + const vertexMap = {}; + + // find all the normals shared by commonly located vertices + for ( let i = 0, l = posAttr.count / 3; i < l; i ++ ) { + + const i3 = 3 * i; + const a = verts[ 0 ].fromBufferAttribute( posAttr, i3 + 0 ); + const b = verts[ 1 ].fromBufferAttribute( posAttr, i3 + 1 ); + const c = verts[ 2 ].fromBufferAttribute( posAttr, i3 + 2 ); + tempVec1.subVectors( c, b ); + tempVec2.subVectors( a, b ); + + // add the normal to the map for all vertices + const normal = new THREE.Vector3().crossVectors( tempVec1, tempVec2 ).normalize(); + for ( let n = 0; n < 3; n ++ ) { + + const vert = verts[ n ]; + const hash = hashVertex( vert ); + if ( ! ( hash in vertexMap ) ) { + + vertexMap[ hash ] = []; + + } + + vertexMap[ hash ].push( normal ); + + } + + } + + // average normals from all vertices that share a common location if they are within the + // provided crease threshold + const normalArray = new Float32Array( posAttr.count * 3 ); + const normAttr = new THREE.BufferAttribute( normalArray, 3, false ); + for ( let i = 0, l = posAttr.count / 3; i < l; i ++ ) { + + // get the face normal for this vertex + const i3 = 3 * i; + const a = verts[ 0 ].fromBufferAttribute( posAttr, i3 + 0 ); + const b = verts[ 1 ].fromBufferAttribute( posAttr, i3 + 1 ); + const c = verts[ 2 ].fromBufferAttribute( posAttr, i3 + 2 ); + tempVec1.subVectors( c, b ); + tempVec2.subVectors( a, b ); + tempNorm.crossVectors( tempVec1, tempVec2 ).normalize(); + + // average all normals that meet the threshold and set the normal value + for ( let n = 0; n < 3; n ++ ) { + + const vert = verts[ n ]; + const hash = hashVertex( vert ); + const otherNormals = vertexMap[ hash ]; + tempNorm2.set( 0, 0, 0 ); + for ( let k = 0, lk = otherNormals.length; k < lk; k ++ ) { + + const otherNorm = otherNormals[ k ]; + if ( tempNorm.dot( otherNorm ) > creaseDot ) { + + tempNorm2.add( otherNorm ); + + } + + } + + tempNorm2.normalize(); + normAttr.setXYZ( i3 + n, tempNorm2.x, tempNorm2.y, tempNorm2.z ); + + } + + } + + resultGeometry.setAttribute( 'normal', normAttr ); + return resultGeometry; + + } + THREE.BufferGeometryUtils = {}; THREE.BufferGeometryUtils.computeMikkTSpaceTangents = computeMikkTSpaceTangents; THREE.BufferGeometryUtils.computeMorphedAttributes = computeMorphedAttributes; THREE.BufferGeometryUtils.computeTangents = computeTangents; + THREE.BufferGeometryUtils.deepCloneAttribute = deepCloneAttribute; THREE.BufferGeometryUtils.deinterleaveAttribute = deinterleaveAttribute; THREE.BufferGeometryUtils.deinterleaveGeometry = deinterleaveGeometry; THREE.BufferGeometryUtils.estimateBytesUsed = estimateBytesUsed; @@ -1089,6 +1154,7 @@ THREE.BufferGeometryUtils.mergeBufferGeometries = mergeBufferGeometries; THREE.BufferGeometryUtils.mergeGroups = mergeGroups; THREE.BufferGeometryUtils.mergeVertices = mergeVertices; + THREE.BufferGeometryUtils.toCreasedNormals = toCreasedNormals; THREE.BufferGeometryUtils.toTrianglesDrawMode = toTrianglesDrawMode; } )(); diff --git a/examples/js/utils/CameraUtils.js b/examples/js/utils/CameraUtils.js index 5eaf39b9daf668..53d00b124dbaa6 100644 --- a/examples/js/utils/CameraUtils.js +++ b/examples/js/utils/CameraUtils.js @@ -24,52 +24,37 @@ * @param {Vector3} bottomRightCorner * @param {Vector3} topLeftCorner * @param {boolean} estimateViewFrustum */ - - function frameCorners( camera, bottomLeftCorner, bottomRightCorner, topLeftCorner, estimateViewFrustum = false ) { const pa = bottomLeftCorner, pb = bottomRightCorner, pc = topLeftCorner; const pe = camera.position; // eye position - const n = camera.near; // distance of near clipping plane - const f = camera.far; //distance of far clipping plane _vr.copy( pb ).sub( pa ).normalize(); - _vu.copy( pc ).sub( pa ).normalize(); - _vn.crossVectors( _vr, _vu ).normalize(); - _va.copy( pa ).sub( pe ); // from pe to pa - - _vb.copy( pb ).sub( pe ); // from pe to pb - - _vc.copy( pc ).sub( pe ); // from pe to pc - const d = - _va.dot( _vn ); // distance from eye to screen - const l = _vr.dot( _va ) * n / d; // distance to left screen edge - const r = _vr.dot( _vb ) * n / d; // distance to right screen edge - const b = _vu.dot( _va ) * n / d; // distance to bottom screen edge - const t = _vu.dot( _vc ) * n / d; // distance to top screen edge - // Set the camera rotation to match the focal plane to the corners' plane + // Set the camera rotation to match the focal plane to the corners' plane _quat.setFromUnitVectors( _vec.set( 0, 1, 0 ), _vu ); + camera.quaternion.setFromUnitVectors( _vec.set( 0, 0, 1 ).applyQuaternion( _quat ), _vn ).multiply( _quat ); - camera.quaternion.setFromUnitVectors( _vec.set( 0, 0, 1 ).applyQuaternion( _quat ), _vn ).multiply( _quat ); // Set the off-axis projection matrix to match the corners - + // Set the off-axis projection matrix to match the corners camera.projectionMatrix.set( 2.0 * n / ( r - l ), 0.0, ( r + l ) / ( r - l ), 0.0, 0.0, 2.0 * n / ( t - b ), ( t + b ) / ( t - b ), 0.0, 0.0, 0.0, ( f + n ) / ( n - f ), 2.0 * f * n / ( n - f ), 0.0, 0.0, - 1.0, 0.0 ); - camera.projectionMatrixInverse.copy( camera.projectionMatrix ).invert(); // FoV estimation to fix frustum culling + camera.projectionMatrixInverse.copy( camera.projectionMatrix ).invert(); + // FoV estimation to fix frustum culling if ( estimateViewFrustum ) { // Set fieldOfView to a conservative estimate diff --git a/examples/js/utils/GPUStatsPanel.js b/examples/js/utils/GPUStatsPanel.js index 4746fc5613f3ae..d222a99ca3cbc3 100644 --- a/examples/js/utils/GPUStatsPanel.js +++ b/examples/js/utils/GPUStatsPanel.js @@ -1,7 +1,7 @@ ( function () { + // https://www.khronos.org/registry/webgl/extensions/EXT_disjoint_timer_query/ // https://www.khronos.org/registry/webgl/extensions/EXT_disjoint_timer_query_webgl2/ - class GPUStatsPanel extends Stats.Panel { constructor( context, name = 'GPU MS' ) { @@ -9,12 +9,10 @@ super( name, '#f90', '#210' ); let isWebGL2 = true; let extension = context.getExtension( 'EXT_disjoint_timer_query_webgl2' ); - if ( extension === null ) { isWebGL2 = false; extension = context.getExtension( 'EXT_disjoint_timer_query' ); - if ( extension === null ) { console.warn( 'GPUStatsPanel: disjoint_time_query extension not available.' ); @@ -27,21 +25,18 @@ this.extension = extension; this.maxTime = 30; this.activeQueries = 0; - this.startQuery = function () { const gl = this.context; const ext = this.extension; - if ( ext === null ) { return; - } // create the query object - + } + // create the query object let query; - if ( isWebGL2 ) { query = gl.createQuery(); @@ -55,12 +50,10 @@ } this.activeQueries ++; - const checkQuery = () => { // check if the query is available and valid let available, disjoint, ns; - if ( isWebGL2 ) { available = gl.getQueryParameter( query, gl.QUERY_RESULT_AVAILABLE ); @@ -76,7 +69,6 @@ } const ms = ns * 1e-6; - if ( available ) { // update the display if it is valid @@ -106,7 +98,6 @@ // finish the query measurement const ext = this.extension; const gl = this.context; - if ( ext === null ) { return; diff --git a/examples/js/utils/GeometryCompressionUtils.js b/examples/js/utils/GeometryCompressionUtils.js index 9a9e2c6c1f6f0d..26aaa1edb03ac1 100644 --- a/examples/js/utils/GeometryCompressionUtils.js +++ b/examples/js/utils/GeometryCompressionUtils.js @@ -6,6 +6,7 @@ * @link https://github.com/tsherif/mesh-quantization-example * */ + /** * Make the input mesh.geometry's normal attribute encoded and compressed by 3 different methods. * Also will change the mesh.material to `PackedPhongMaterial` which let the vertex shader program decode the normal data. @@ -14,7 +15,6 @@ * @param {String} encodeMethod "DEFAULT" || "OCT1Byte" || "OCT2Byte" || "ANGLES" * */ - function compressNormals( mesh, encodeMethod ) { if ( ! mesh.geometry ) { @@ -24,7 +24,6 @@ } const normal = mesh.geometry.attributes.normal; - if ( ! normal ) { console.error( 'Geometry must contain normal attribute. ' ); @@ -32,7 +31,6 @@ } if ( normal.isPacked ) return; - if ( normal.itemSize != 3 ) { console.error( 'normal.itemSize is not 3, which cannot be encoded. ' ); @@ -42,12 +40,10 @@ const array = normal.array; const count = normal.count; let result; - if ( encodeMethod == 'DEFAULT' ) { // TODO: Add 1 byte to the result, making the encoded length to be 4 bytes. result = new Uint8Array( count * 3 ); - for ( let idx = 0; idx < array.length; idx += 3 ) { const encoded = defaultEncode( array[ idx ], array[ idx + 1 ], array[ idx + 2 ], 1 ); @@ -67,8 +63,8 @@ * As it makes vertex data not aligned to a 4 byte boundary which may harm some WebGL implementations and sometimes the normal distortion is visible * Please refer to @zeux 's comments in https://github.com/mrdoob/three.js/pull/18208 */ - result = new Int8Array( count * 2 ); + result = new Int8Array( count * 2 ); for ( let idx = 0; idx < array.length; idx += 3 ) { const encoded = octEncodeBest( array[ idx ], array[ idx + 1 ], array[ idx + 2 ], 1 ); @@ -83,7 +79,6 @@ } else if ( encodeMethod == 'OCT2Byte' ) { result = new Int16Array( count * 2 ); - for ( let idx = 0; idx < array.length; idx += 3 ) { const encoded = octEncodeBest( array[ idx ], array[ idx + 1 ], array[ idx + 2 ], 2 ); @@ -98,7 +93,6 @@ } else if ( encodeMethod == 'ANGLES' ) { result = new Uint16Array( count * 2 ); - for ( let idx = 0; idx < array.length; idx += 3 ) { const encoded = anglesEncode( array[ idx ], array[ idx + 1 ], array[ idx + 2 ] ); @@ -118,8 +112,9 @@ mesh.geometry.attributes.normal.needsUpdate = true; mesh.geometry.attributes.normal.isPacked = true; - mesh.geometry.attributes.normal.packingMethod = encodeMethod; // modify material + mesh.geometry.attributes.normal.packingMethod = encodeMethod; + // modify material if ( ! ( mesh.material instanceof THREE.PackedPhongMaterial ) ) { mesh.material = new THREE.PackedPhongMaterial().copy( mesh.material ); @@ -151,6 +146,7 @@ } } + /** * Make the input mesh.geometry's position attribute encoded and compressed. * Also will change the mesh.material to `PackedPhongMaterial` which let the vertex shader program decode the position data. @@ -158,8 +154,6 @@ * @param {THREE.Mesh} mesh * */ - - function compressPositions( mesh ) { if ( ! mesh.geometry ) { @@ -169,7 +163,6 @@ } const position = mesh.geometry.attributes.position; - if ( ! position ) { console.error( 'Geometry must contain position attribute. ' ); @@ -177,7 +170,6 @@ } if ( position.isPacked ) return; - if ( position.itemSize != 3 ) { console.error( 'position.itemSize is not 3, which cannot be packed. ' ); @@ -188,15 +180,17 @@ const encodingBytes = 2; const result = quantizedEncode( array, encodingBytes ); const quantized = result.quantized; - const decodeMat = result.decodeMat; // IMPORTANT: calculate original geometry bounding info first, before updating packed positions + const decodeMat = result.decodeMat; + // IMPORTANT: calculate original geometry bounding info first, before updating packed positions if ( mesh.geometry.boundingBox == null ) mesh.geometry.computeBoundingBox(); if ( mesh.geometry.boundingSphere == null ) mesh.geometry.computeBoundingSphere(); mesh.geometry.setAttribute( 'position', new THREE.BufferAttribute( quantized, 3 ) ); mesh.geometry.attributes.position.isPacked = true; mesh.geometry.attributes.position.needsUpdate = true; - mesh.geometry.attributes.position.bytes = quantized.length * encodingBytes; // modify material + mesh.geometry.attributes.position.bytes = quantized.length * encodingBytes; + // modify material if ( ! ( mesh.material instanceof THREE.PackedPhongMaterial ) ) { mesh.material = new THREE.PackedPhongMaterial().copy( mesh.material ); @@ -208,6 +202,7 @@ mesh.material.uniforms.quantizeMatPos.needsUpdate = true; } + /** * Make the input mesh.geometry's uv attribute encoded and compressed. * Also will change the mesh.material to `PackedPhongMaterial` which let the vertex shader program decode the uv data. @@ -215,8 +210,6 @@ * @param {THREE.Mesh} mesh * */ - - function compressUvs( mesh ) { if ( ! mesh.geometry ) { @@ -226,7 +219,6 @@ } const uvs = mesh.geometry.attributes.uv; - if ( ! uvs ) { console.error( 'Geometry must contain uv attribute. ' ); @@ -239,7 +231,6 @@ max: - Infinity }; const array = uvs.array; - for ( let i = 0; i < array.length; i ++ ) { range.min = Math.min( range.min, array[ i ] ); @@ -248,12 +239,10 @@ } let result; - if ( range.min >= - 1.0 && range.max <= 1.0 ) { // use default encoding method result = new Uint16Array( array.length ); - for ( let i = 0; i < array.length; i += 2 ) { const encoded = defaultEncode( array[ i ], array[ i + 1 ], 0, 2 ); @@ -266,7 +255,6 @@ mesh.geometry.attributes.uv.isPacked = true; mesh.geometry.attributes.uv.needsUpdate = true; mesh.geometry.attributes.uv.bytes = result.length * 2; - if ( ! ( mesh.material instanceof THREE.PackedPhongMaterial ) ) { mesh.material = new THREE.PackedPhongMaterial().copy( mesh.material ); @@ -283,7 +271,6 @@ mesh.geometry.attributes.uv.isPacked = true; mesh.geometry.attributes.uv.needsUpdate = true; mesh.geometry.attributes.uv.bytes = result.quantized.length * 2; - if ( ! ( mesh.material instanceof THREE.PackedPhongMaterial ) ) { mesh.material = new THREE.PackedPhongMaterial().copy( mesh.material ); @@ -296,8 +283,9 @@ } - } // Encoding functions + } + // Encoding functions function defaultEncode( x, y, z, bytes ) { @@ -321,30 +309,30 @@ } - } // for `Angles` encoding - + } + // for `Angles` encoding function anglesEncode( x, y, z ) { const normal0 = parseInt( 0.5 * ( 1.0 + Math.atan2( y, x ) / Math.PI ) * 65535 ); const normal1 = parseInt( 0.5 * ( 1.0 + z ) * 65535 ); return new Uint16Array( [ normal0, normal1 ] ); - } // for `Octahedron` encoding - + } + // for `Octahedron` encoding function octEncodeBest( x, y, z, bytes ) { - let oct, dec, best, currentCos, bestCos; // Test various combinations of ceil and floor - // to minimize rounding errors + let oct, dec, best, currentCos, bestCos; + // Test various combinations of ceil and floor + // to minimize rounding errors best = oct = octEncodeVec3( x, y, z, 'floor', 'floor' ); dec = octDecodeVec2( oct ); bestCos = dot( x, y, z, dec ); oct = octEncodeVec3( x, y, z, 'ceil', 'floor' ); dec = octDecodeVec2( oct ); currentCos = dot( x, y, z, dec ); - if ( currentCos > bestCos ) { best = oct; @@ -355,7 +343,6 @@ oct = octEncodeVec3( x, y, z, 'floor', 'ceil' ); dec = octDecodeVec2( oct ); currentCos = dot( x, y, z, dec ); - if ( currentCos > bestCos ) { best = oct; @@ -366,7 +353,6 @@ oct = octEncodeVec3( x, y, z, 'ceil', 'ceil' ); dec = octDecodeVec2( oct ); currentCos = dot( x, y, z, dec ); - if ( currentCos > bestCos ) { best = oct; @@ -374,12 +360,10 @@ } return best; - function octEncodeVec3( x0, y0, z0, xfunc, yfunc ) { let x = x0 / ( Math.abs( x0 ) + Math.abs( y0 ) + Math.abs( z0 ) ); let y = y0 / ( Math.abs( x0 ) + Math.abs( y0 ) + Math.abs( z0 ) ); - if ( z < 0 ) { const tempx = ( 1 - Math.abs( y ) ) * ( x >= 0 ? 1 : - 1 ); @@ -387,7 +371,6 @@ x = tempx; y = tempy; let diff = 1 - Math.abs( x ) - Math.abs( y ); - if ( diff > 0 ) { diff += 0.001; @@ -416,7 +399,6 @@ let x = oct[ 0 ]; let y = oct[ 1 ]; - if ( bytes == 1 ) { x /= x < 0 ? 127 : 128; @@ -430,7 +412,6 @@ } const z = 1 - Math.abs( x ) - Math.abs( y ); - if ( z < 0 ) { const tmpx = x; @@ -455,7 +436,6 @@ function quantizedEncode( array, bytes ) { let quantized, segments; - if ( bytes == 1 ) { quantized = new Uint8Array( array.length ); @@ -477,7 +457,6 @@ const max = new Float32Array( 3 ); min[ 0 ] = min[ 1 ] = min[ 2 ] = Number.MAX_VALUE; max[ 0 ] = max[ 1 ] = max[ 2 ] = - Number.MAX_VALUE; - for ( let i = 0; i < array.length; i += 3 ) { min[ 0 ] = Math.min( min[ 0 ], array[ i + 0 ] ); @@ -495,7 +474,6 @@ decodeMat.elements[ 14 ] = min[ 2 ]; decodeMat.transpose(); const multiplier = new Float32Array( [ max[ 0 ] !== min[ 0 ] ? segments / ( max[ 0 ] - min[ 0 ] ) : 0, max[ 1 ] !== min[ 1 ] ? segments / ( max[ 1 ] - min[ 1 ] ) : 0, max[ 2 ] !== min[ 2 ] ? segments / ( max[ 2 ] - min[ 2 ] ) : 0 ] ); - for ( let i = 0; i < array.length; i += 3 ) { quantized[ i + 0 ] = Math.floor( ( array[ i + 0 ] - min[ 0 ] ) * multiplier[ 0 ] ); @@ -514,7 +492,6 @@ function quantizedEncodeUV( array, bytes ) { let quantized, segments; - if ( bytes == 1 ) { quantized = new Uint8Array( array.length ); @@ -536,7 +513,6 @@ const max = new Float32Array( 2 ); min[ 0 ] = min[ 1 ] = Number.MAX_VALUE; max[ 0 ] = max[ 1 ] = - Number.MAX_VALUE; - for ( let i = 0; i < array.length; i += 2 ) { min[ 0 ] = Math.min( min[ 0 ], array[ i + 0 ] ); @@ -551,7 +527,6 @@ decodeMat.elements[ 7 ] = min[ 1 ]; decodeMat.transpose(); const multiplier = new Float32Array( [ max[ 0 ] !== min[ 0 ] ? segments / ( max[ 0 ] - min[ 0 ] ) : 0, max[ 1 ] !== min[ 1 ] ? segments / ( max[ 1 ] - min[ 1 ] ) : 0 ] ); - for ( let i = 0; i < array.length; i += 2 ) { quantized[ i + 0 ] = Math.floor( ( array[ i + 0 ] - min[ 0 ] ) * multiplier[ 0 ] ); diff --git a/examples/js/utils/GeometryUtils.js b/examples/js/utils/GeometryUtils.js index a14d65271a43bc..25623c34d1b0a3 100644 --- a/examples/js/utils/GeometryUtils.js +++ b/examples/js/utils/GeometryUtils.js @@ -14,23 +14,24 @@ * @param v2 Corner index +X, +Z. * @param v3 Corner index +X, -Z. */ - function hilbert2D( center = new THREE.Vector3( 0, 0, 0 ), size = 10, iterations = 1, v0 = 0, v1 = 1, v2 = 2, v3 = 3 ) { const half = size / 2; const vec_s = [ new THREE.Vector3( center.x - half, center.y, center.z - half ), new THREE.Vector3( center.x - half, center.y, center.z + half ), new THREE.Vector3( center.x + half, center.y, center.z + half ), new THREE.Vector3( center.x + half, center.y, center.z - half ) ]; - const vec = [ vec_s[ v0 ], vec_s[ v1 ], vec_s[ v2 ], vec_s[ v3 ] ]; // Recurse iterations + const vec = [ vec_s[ v0 ], vec_s[ v1 ], vec_s[ v2 ], vec_s[ v3 ] ]; + // Recurse iterations if ( 0 <= -- iterations ) { return [ ...hilbert2D( vec[ 0 ], half, iterations, v0, v3, v2, v1 ), ...hilbert2D( vec[ 1 ], half, iterations, v0, v1, v2, v3 ), ...hilbert2D( vec[ 2 ], half, iterations, v0, v1, v2, v3 ), ...hilbert2D( vec[ 3 ], half, iterations, v2, v1, v0, v3 ) ]; - } // Return complete Hilbert Curve. - + } + // Return complete Hilbert Curve. return vec; } + /** * Generates 3D-Coordinates in a very fast way. * @@ -49,25 +50,25 @@ * @param v6 Corner index +X, +Y, +Z. * @param v7 Corner index +X, +Y, -Z. */ - - function hilbert3D( center = new THREE.Vector3( 0, 0, 0 ), size = 10, iterations = 1, v0 = 0, v1 = 1, v2 = 2, v3 = 3, v4 = 4, v5 = 5, v6 = 6, v7 = 7 ) { // Default Vars const half = size / 2; const vec_s = [ new THREE.Vector3( center.x - half, center.y + half, center.z - half ), new THREE.Vector3( center.x - half, center.y + half, center.z + half ), new THREE.Vector3( center.x - half, center.y - half, center.z + half ), new THREE.Vector3( center.x - half, center.y - half, center.z - half ), new THREE.Vector3( center.x + half, center.y - half, center.z - half ), new THREE.Vector3( center.x + half, center.y - half, center.z + half ), new THREE.Vector3( center.x + half, center.y + half, center.z + half ), new THREE.Vector3( center.x + half, center.y + half, center.z - half ) ]; - const vec = [ vec_s[ v0 ], vec_s[ v1 ], vec_s[ v2 ], vec_s[ v3 ], vec_s[ v4 ], vec_s[ v5 ], vec_s[ v6 ], vec_s[ v7 ] ]; // Recurse iterations + const vec = [ vec_s[ v0 ], vec_s[ v1 ], vec_s[ v2 ], vec_s[ v3 ], vec_s[ v4 ], vec_s[ v5 ], vec_s[ v6 ], vec_s[ v7 ] ]; + // Recurse iterations if ( -- iterations >= 0 ) { return [ ...hilbert3D( vec[ 0 ], half, iterations, v0, v3, v4, v7, v6, v5, v2, v1 ), ...hilbert3D( vec[ 1 ], half, iterations, v0, v7, v6, v1, v2, v5, v4, v3 ), ...hilbert3D( vec[ 2 ], half, iterations, v0, v7, v6, v1, v2, v5, v4, v3 ), ...hilbert3D( vec[ 3 ], half, iterations, v2, v3, v0, v1, v6, v7, v4, v5 ), ...hilbert3D( vec[ 4 ], half, iterations, v2, v3, v0, v1, v6, v7, v4, v5 ), ...hilbert3D( vec[ 5 ], half, iterations, v4, v3, v2, v5, v6, v1, v0, v7 ), ...hilbert3D( vec[ 6 ], half, iterations, v4, v3, v2, v5, v6, v1, v0, v7 ), ...hilbert3D( vec[ 7 ], half, iterations, v6, v5, v2, v1, v0, v3, v4, v7 ) ]; - } // Return complete Hilbert Curve. - + } + // Return complete Hilbert Curve. return vec; } + /** * Generates a Gosper curve (lying in the XY plane) * @@ -75,23 +76,18 @@ * * @param size The size of a single gosper island. */ - - function gosper( size = 1 ) { function fractalize( config ) { let output; let input = config.axiom; - for ( let i = 0, il = config.steps; 0 <= il ? i < il : i > il; 0 <= il ? i ++ : i -- ) { output = ''; - for ( let j = 0, jl = input.length; j < jl; j ++ ) { const char = input[ j ]; - if ( char in config.rules ) { output += config.rules[ char ]; @@ -119,11 +115,9 @@ let angle = 0; const path = [ 0, 0, 0 ]; const fractal = config.fractal; - for ( let i = 0, l = fractal.length; i < l; i ++ ) { const char = fractal[ i ]; - if ( char === '+' ) { angle += config.angle; @@ -144,8 +138,9 @@ return path; - } // + } + // const gosper = fractalize( { axiom: 'A', @@ -159,8 +154,8 @@ fractal: gosper, size: size, angle: Math.PI / 3 // 60 degrees - } ); + return points; } diff --git a/examples/js/utils/LDrawUtils.js b/examples/js/utils/LDrawUtils.js index 454f919d1f7b83..9d1a1bd9a5cc3c 100644 --- a/examples/js/utils/LDrawUtils.js +++ b/examples/js/utils/LDrawUtils.js @@ -7,9 +7,11 @@ // Merges geometries in object by materials and returns new object. Use on not indexed geometries. // The object buffers reference the old object ones. // Special treatment is done to the conditional lines generated by LDrawLoader. + function extractGroup( geometry, group, elementSize, isConditionalLine ) { // Extracts a group from a geometry as a new geometry (with attribute buffers referencing original buffers) + const newGeometry = new THREE.BufferGeometry(); const originalPositions = geometry.getAttribute( 'position' ).array; const originalNormals = elementSize === 3 ? geometry.getAttribute( 'normal' ).array : null; @@ -20,7 +22,6 @@ const normals = originalNormals !== null ? originalNormals.subarray( vertStart, vertEnd ) : null; newGeometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); if ( normals !== null ) newGeometry.setAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); - if ( isConditionalLine ) { const controlArray0 = geometry.getAttribute( 'control0' ).array.subarray( vertStart, vertEnd ); @@ -39,7 +40,6 @@ function addGeometry( mat, geometry, geometries ) { const geoms = geometries[ mat.uuid ]; - if ( ! geoms ) { geometries[ mat.uuid ] = { @@ -58,11 +58,11 @@ function permuteAttribute( attribute, elemSize ) { // Permutes first two vertices of each attribute element + if ( ! attribute ) return; const verts = attribute.array; const numVerts = Math.floor( verts.length / 3 ); let offset = 0; - for ( let i = 0; i < numVerts; i ++ ) { const x = verts[ offset ]; @@ -78,8 +78,9 @@ } - } // Traverse the object hierarchy collecting geometries and transforming them to world space + } + // Traverse the object hierarchy collecting geometries and transforming them to world space const meshGeometries = {}; const linesGeometries = {}; @@ -93,7 +94,6 @@ const elemSize = c.isMesh ? 3 : 2; const geometry = c.geometry.clone(); const matrixIsInverted = c.matrixWorld.determinant() < 0; - if ( matrixIsInverted ) { permuteAttribute( geometry.attributes.position, elemSize ); @@ -102,7 +102,6 @@ } geometry.applyMatrix4( c.matrixWorld ); - if ( c.isConditionalLine ) { geometry.attributes.control0.applyMatrix4( c.matrixWorld ); @@ -113,7 +112,6 @@ } const geometries = c.isMesh ? meshGeometries : c.isConditionalLine ? condLinesGeometries : linesGeometries; - if ( Array.isArray( c.material ) ) { for ( const groupIndex in geometry.groups ) { @@ -133,11 +131,12 @@ } - } ); // Create object with merged geometries + } ); + + // Create object with merged geometries const mergedObject = new THREE.Group(); const meshMaterialsIds = Object.keys( meshGeometries ); - for ( const meshMaterialsId of meshMaterialsIds ) { const meshGeometry = meshGeometries[ meshMaterialsId ]; @@ -147,7 +146,6 @@ } const linesMaterialsIds = Object.keys( linesGeometries ); - for ( const linesMaterialsId of linesMaterialsIds ) { const lineGeometry = linesGeometries[ linesMaterialsId ]; @@ -157,7 +155,6 @@ } const condLinesMaterialsIds = Object.keys( condLinesGeometries ); - for ( const condLinesMaterialsId of condLinesMaterialsIds ) { const condLineGeometry = condLinesGeometries[ condLinesMaterialsId ]; diff --git a/examples/js/utils/PackedPhongMaterial.js b/examples/js/utils/PackedPhongMaterial.js index 3b7b90e346b5bf..f2ba5b8750479d 100644 --- a/examples/js/utils/PackedPhongMaterial.js +++ b/examples/js/utils/PackedPhongMaterial.js @@ -5,7 +5,6 @@ * * @param {Object} parameters */ - class PackedPhongMaterial extends THREE.MeshPhongMaterial { constructor( parameters ) { @@ -91,10 +90,13 @@ #if USE_PACKED_POSITION == 0 transformed = ( vec4(transformed, 1.0) * quantizeMatPos ).xyz; #endif - #endif`, THREE.ShaderChunk.morphtarget_vertex, THREE.ShaderChunk.skinning_vertex, THREE.ShaderChunk.displacementmap_vertex, THREE.ShaderChunk.project_vertex, THREE.ShaderChunk.logdepthbuf_vertex, THREE.ShaderChunk.clipping_planes_vertex, 'vViewPosition = - mvPosition.xyz;', THREE.ShaderChunk.worldpos_vertex, THREE.ShaderChunk.envmap_vertex, THREE.ShaderChunk.shadowmap_vertex, THREE.ShaderChunk.fog_vertex, '}' ].join( '\n' ); // Use the original THREE.MeshPhongMaterial's fragmentShader. + #endif`, THREE.ShaderChunk.morphtarget_vertex, THREE.ShaderChunk.skinning_vertex, THREE.ShaderChunk.displacementmap_vertex, THREE.ShaderChunk.project_vertex, THREE.ShaderChunk.logdepthbuf_vertex, THREE.ShaderChunk.clipping_planes_vertex, 'vViewPosition = - mvPosition.xyz;', THREE.ShaderChunk.worldpos_vertex, THREE.ShaderChunk.envmap_vertex, THREE.ShaderChunk.shadowmap_vertex, THREE.ShaderChunk.fog_vertex, '}' ].join( '\n' ); - this.fragmentShader = [ '#define PHONG', 'uniform vec3 diffuse;', 'uniform vec3 emissive;', 'uniform vec3 specular;', 'uniform float shininess;', 'uniform float opacity;', THREE.ShaderChunk.common, THREE.ShaderChunk.packing, THREE.ShaderChunk.dithering_pars_fragment, THREE.ShaderChunk.color_pars_fragment, THREE.ShaderChunk.uv_pars_fragment, THREE.ShaderChunk.uv2_pars_fragment, THREE.ShaderChunk.map_pars_fragment, THREE.ShaderChunk.alphamap_pars_fragment, THREE.ShaderChunk.aomap_pars_fragment, THREE.ShaderChunk.lightmap_pars_fragment, THREE.ShaderChunk.emissivemap_pars_fragment, THREE.ShaderChunk.envmap_common_pars_fragment, THREE.ShaderChunk.envmap_pars_fragment, THREE.ShaderChunk.cube_uv_reflection_fragment, THREE.ShaderChunk.fog_pars_fragment, THREE.ShaderChunk.bsdfs, THREE.ShaderChunk.lights_pars_begin, THREE.ShaderChunk.normal_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, THREE.ShaderChunk.clipping_planes_pars_fragment, 'void main() {', THREE.ShaderChunk.clipping_planes_fragment, 'vec4 diffuseColor = vec4( diffuse, opacity );', 'ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );', 'vec3 totalEmissiveRadiance = emissive;', THREE.ShaderChunk.logdepthbuf_fragment, THREE.ShaderChunk.map_fragment, THREE.ShaderChunk.color_fragment, THREE.ShaderChunk.alphamap_fragment, THREE.ShaderChunk.alphatest_fragment, THREE.ShaderChunk.specularmap_fragment, THREE.ShaderChunk.normal_fragment_begin, THREE.ShaderChunk.normal_fragment_maps, THREE.ShaderChunk.emissivemap_fragment, // accumulation - THREE.ShaderChunk.lights_phong_fragment, THREE.ShaderChunk.lights_fragment_begin, THREE.ShaderChunk.lights_fragment_maps, THREE.ShaderChunk.lights_fragment_end, // modulation + // Use the original THREE.MeshPhongMaterial's fragmentShader. + this.fragmentShader = [ '#define PHONG', 'uniform vec3 diffuse;', 'uniform vec3 emissive;', 'uniform vec3 specular;', 'uniform float shininess;', 'uniform float opacity;', THREE.ShaderChunk.common, THREE.ShaderChunk.packing, THREE.ShaderChunk.dithering_pars_fragment, THREE.ShaderChunk.color_pars_fragment, THREE.ShaderChunk.uv_pars_fragment, THREE.ShaderChunk.uv2_pars_fragment, THREE.ShaderChunk.map_pars_fragment, THREE.ShaderChunk.alphamap_pars_fragment, THREE.ShaderChunk.aomap_pars_fragment, THREE.ShaderChunk.lightmap_pars_fragment, THREE.ShaderChunk.emissivemap_pars_fragment, THREE.ShaderChunk.envmap_common_pars_fragment, THREE.ShaderChunk.envmap_pars_fragment, THREE.ShaderChunk.fog_pars_fragment, THREE.ShaderChunk.bsdfs, THREE.ShaderChunk.lights_pars_begin, THREE.ShaderChunk.normal_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, THREE.ShaderChunk.clipping_planes_pars_fragment, 'void main() {', THREE.ShaderChunk.clipping_planes_fragment, 'vec4 diffuseColor = vec4( diffuse, opacity );', 'ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );', 'vec3 totalEmissiveRadiance = emissive;', THREE.ShaderChunk.logdepthbuf_fragment, THREE.ShaderChunk.map_fragment, THREE.ShaderChunk.color_fragment, THREE.ShaderChunk.alphamap_fragment, THREE.ShaderChunk.alphatest_fragment, THREE.ShaderChunk.specularmap_fragment, THREE.ShaderChunk.normal_fragment_begin, THREE.ShaderChunk.normal_fragment_maps, THREE.ShaderChunk.emissivemap_fragment, + // accumulation + THREE.ShaderChunk.lights_phong_fragment, THREE.ShaderChunk.lights_fragment_begin, THREE.ShaderChunk.lights_fragment_maps, THREE.ShaderChunk.lights_fragment_end, + // modulation THREE.ShaderChunk.aomap_fragment, 'vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;', THREE.ShaderChunk.envmap_fragment, 'gl_FragColor = vec4( outgoingLight, diffuseColor.a );', THREE.ShaderChunk.tonemapping_fragment, THREE.ShaderChunk.encodings_fragment, THREE.ShaderChunk.fog_fragment, THREE.ShaderChunk.premultiplied_alpha_fragment, THREE.ShaderChunk.dithering_fragment, '}' ].join( '\n' ); this.setValues( parameters ); diff --git a/examples/js/utils/SceneUtils.js b/examples/js/utils/SceneUtils.js index c32cb19601942e..e6e3c08f2be770 100644 --- a/examples/js/utils/SceneUtils.js +++ b/examples/js/utils/SceneUtils.js @@ -1,12 +1,13 @@ ( function () { + const _color = /*@__PURE__*/new THREE.Color(); + const _matrix = /*@__PURE__*/new THREE.Matrix4(); function createMeshesFromInstancedMesh( instancedMesh ) { const group = new THREE.Group(); const count = instancedMesh.count; const geometry = instancedMesh.geometry; const material = instancedMesh.material; - for ( let i = 0; i < count; i ++ ) { const mesh = new THREE.Mesh( geometry, material ); @@ -33,12 +34,16 @@ } const object = new THREE.Group(); - object.copy( mesh ); // merge groups (which automatically sorts them) + object.copy( mesh ); + + // merge groups (which automatically sorts them) const geometry = THREE.mergeGroups( mesh.geometry ); const index = geometry.index; const groups = geometry.groups; - const attributeNames = Object.keys( geometry.attributes ); // create a mesh for each group by extracting the buffer data into a new geometry + const attributeNames = Object.keys( geometry.attributes ); + + // create a mesh for each group by extracting the buffer data into a new geometry for ( let i = 0; i < groups.length; i ++ ) { @@ -46,7 +51,9 @@ const start = group.start; const end = start + group.count; const newGeometry = new THREE.BufferGeometry(); - const newMaterial = mesh.material[ group.materialIndex ]; // process all buffer attributes + const newMaterial = mesh.material[ group.materialIndex ]; + + // process all buffer attributes for ( let j = 0; j < attributeNames.length; j ++ ) { @@ -57,7 +64,6 @@ const type = attribute.array.constructor; const newArray = new type( newLength ); const newAttribute = new THREE.BufferAttribute( newArray, itemSize ); - for ( let k = start, n = 0; k < end; k ++, n ++ ) { const ind = index.getX( k ); @@ -84,7 +90,6 @@ function createMultiMaterialObject( geometry, materials ) { const group = new THREE.Group(); - for ( let i = 0, l = materials.length; i < l; i ++ ) { group.add( new THREE.Mesh( geometry, materials[ i ] ) ); @@ -95,25 +100,115 @@ } - function detach( child, parent, scene ) { + function reduceVertices( object, func, initialValue ) { + + let value = initialValue; + const vertex = new THREE.Vector3(); + object.updateWorldMatrix( true, true ); + object.traverseVisible( child => { + + const { + geometry + } = child; + if ( geometry !== undefined ) { + + const { + position + } = geometry.attributes; + if ( position !== undefined ) { + + for ( let i = 0, l = position.count; i < l; i ++ ) { + + vertex.fromBufferAttribute( position, i ); + if ( child.isSkinnedMesh ) { + + child.boneTransform( i, vertex ); - console.warn( 'THREE.SceneUtils: detach() has been deprecated. Use scene.attach( child ) instead.' ); - scene.attach( child ); + } else { + + vertex.applyMatrix4( child.matrixWorld ); + + } + + value = func( value, vertex ); + + } + + } + + } + + } ); + return value; } - function attach( child, scene, parent ) { + /** + * @param {InstancedMesh} + * @param {function(int, int):int} + */ + function sortInstancedMesh( mesh, compareFn ) { + + // store copy of instanced attributes for lookups + + const instanceMatrixRef = THREE.deepCloneAttribute( mesh.instanceMatrix ); + const instanceColorRef = mesh.instanceColor ? THREE.deepCloneAttribute( mesh.instanceColor ) : null; + const attributeRefs = new Map(); + for ( const name in mesh.geometry.attributes ) { - console.warn( 'THREE.SceneUtils: attach() has been deprecated. Use parent.attach( child ) instead.' ); - parent.attach( child ); + const attribute = mesh.geometry.attributes[ name ]; + if ( attribute.isInstancedBufferAttribute ) { + + attributeRefs.set( attribute, THREE.deepCloneAttribute( attribute ) ); + + } + + } + + // compute sort order + + const tokens = []; + for ( let i = 0; i < mesh.count; i ++ ) tokens.push( i ); + tokens.sort( compareFn ); + + // apply sort order + + for ( let i = 0; i < tokens.length; i ++ ) { + + const refIndex = tokens[ i ]; + _matrix.fromArray( instanceMatrixRef.array, refIndex * mesh.instanceMatrix.itemSize ); + _matrix.toArray( mesh.instanceMatrix.array, i * mesh.instanceMatrix.itemSize ); + if ( mesh.instanceColor ) { + + _color.fromArray( instanceColorRef.array, refIndex * mesh.instanceColor.itemSize ); + _color.toArray( mesh.instanceColor.array, i * mesh.instanceColor.itemSize ); + + } + + for ( const name in mesh.geometry.attributes ) { + + const attribute = mesh.geometry.attributes[ name ]; + if ( attribute.isInstancedBufferAttribute ) { + + const attributeRef = attributeRefs.get( attribute ); + attribute.setX( i, attributeRef.getX( refIndex ) ); + if ( attribute.itemSize > 1 ) attribute.setY( i, attributeRef.getY( refIndex ) ); + if ( attribute.itemSize > 2 ) attribute.setZ( i, attributeRef.getZ( refIndex ) ); + if ( attribute.itemSize > 3 ) attribute.setW( i, attributeRef.getW( refIndex ) ); + + } + + } + + } } THREE.SceneUtils = {}; - THREE.SceneUtils.attach = attach; THREE.SceneUtils.createMeshesFromInstancedMesh = createMeshesFromInstancedMesh; THREE.SceneUtils.createMeshesFromMultiMaterialMesh = createMeshesFromMultiMaterialMesh; THREE.SceneUtils.createMultiMaterialObject = createMultiMaterialObject; - THREE.SceneUtils.detach = detach; + THREE.SceneUtils.reduceVertices = reduceVertices; + THREE.SceneUtils.sortInstancedMesh = sortInstancedMesh; } )(); diff --git a/examples/js/utils/ShadowMapViewer.js b/examples/js/utils/ShadowMapViewer.js index 2d7e5ddafa8622..fab7b119902a49 100644 --- a/examples/js/utils/ShadowMapViewer.js +++ b/examples/js/utils/ShadowMapViewer.js @@ -34,8 +34,9 @@ //- Internals const scope = this; const doRenderLabel = light.name !== undefined && light.name !== ''; - let userAutoClearSetting; //Holds the initial position and dimension of the HUD + let userAutoClearSetting; + //Holds the initial position and dimension of the HUD const frame = { x: 10, y: 10, @@ -44,8 +45,9 @@ }; const camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, 1, 10 ); camera.position.set( 0, 0, 2 ); - const scene = new THREE.Scene(); //HUD for shadow map + const scene = new THREE.Scene(); + //HUD for shadow map const shader = THREE.UnpackDepthRGBAShader; const uniforms = THREE.UniformsUtils.clone( shader.uniforms ); const material = new THREE.ShaderMaterial( { @@ -55,10 +57,10 @@ } ); const plane = new THREE.PlaneGeometry( frame.width, frame.height ); const mesh = new THREE.Mesh( plane, material ); - scene.add( mesh ); //Label for light's name + scene.add( mesh ); + //Label for light's name let labelCanvas, labelMesh; - if ( doRenderLabel ) { labelCanvas = document.createElement( 'canvas' ); @@ -90,12 +92,13 @@ scope.position.set( scope.position.x, scope.position.y ); - } //- API - // Set to false to disable displaying this shadow map - + } - this.enabled = true; // Set the size of the displayed shadow map on the HUD + //- API + // Set to false to disable displaying this shadow map + this.enabled = true; + // Set the size of the displayed shadow map on the HUD this.size = { width: frame.width, height: frame.height, @@ -103,13 +106,15 @@ this.width = width; this.height = height; - mesh.scale.set( this.width / frame.width, this.height / frame.height, 1 ); //Reset the position as it is off when we scale stuff + mesh.scale.set( this.width / frame.width, this.height / frame.height, 1 ); + //Reset the position as it is off when we scale stuff resetPosition(); } - }; // Set the position of the displayed shadow map on the HUD + }; + // Set the position of the displayed shadow map on the HUD this.position = { x: frame.x, y: frame.y, @@ -124,7 +129,6 @@ } }; - this.render = function ( renderer ) { if ( this.enabled ) { @@ -137,7 +141,6 @@ uniforms.tDiffuse.value = light.shadow.map.texture; userAutoClearSetting = renderer.autoClear; renderer.autoClear = false; // To allow render overlay - renderer.clearDepth(); renderer.render( scene, camera ); renderer.autoClear = userAutoClearSetting; //Restore user's setting @@ -166,9 +169,9 @@ this.position.set( this.position.x, this.position.y ); this.size.set( this.size.width, this.size.height ); - }; //Force an update to set position/size - + }; + //Force an update to set position/size this.update(); } diff --git a/examples/js/utils/SkeletonUtils.js b/examples/js/utils/SkeletonUtils.js index 8d933627224533..364548a38a7d14 100644 --- a/examples/js/utils/SkeletonUtils.js +++ b/examples/js/utils/SkeletonUtils.js @@ -16,7 +16,9 @@ options.names = options.names || {}; const sourceBones = source.isObject3D ? source.skeleton.bones : getBones( source ), bones = target.isObject3D ? target.skeleton.bones : getBones( target ); - let bindBones, bone, name, boneTo, bonesPosition; // reset bones + let bindBones, bone, name, boneTo, bonesPosition; + + // reset bones if ( target.isObject3D ) { @@ -32,7 +34,6 @@ if ( options.preservePosition ) { bonesPosition = []; - for ( let i = 0; i < bones.length; i ++ ) { bonesPosition.push( bones[ i ].position.clone() ); @@ -44,8 +45,11 @@ if ( options.preserveMatrix ) { // reset matrix + target.updateMatrixWorld(); - target.matrixWorld.identity(); // reset children matrix + target.matrixWorld.identity(); + + // reset children matrix for ( let i = 0; i < target.children.length; ++ i ) { @@ -58,12 +62,10 @@ if ( options.offsets ) { bindBones = []; - for ( let i = 0; i < bones.length; ++ i ) { bone = bones[ i ]; name = options.names[ bone.name ] || bone.name; - if ( options.offsets[ name ] ) { bone.matrix.multiply( options.offsets[ name ] ); @@ -84,11 +86,9 @@ name = options.names[ bone.name ] || bone.name; boneTo = getBoneByName( name, sourceBones ); globalMatrix.copy( bone.matrixWorld ); - if ( boneTo ) { boneTo.updateMatrixWorld(); - if ( options.useTargetMatrix ) { relativeMatrix.copy( boneTo.matrixWorld ); @@ -98,14 +98,16 @@ relativeMatrix.copy( target.matrixWorld ).invert(); relativeMatrix.multiply( boneTo.matrixWorld ); - } // ignore scale to extract rotation + } + // ignore scale to extract rotation scale.setFromMatrixScale( relativeMatrix ); - relativeMatrix.scale( scale.set( 1 / scale.x, 1 / scale.y, 1 / scale.z ) ); // apply to global matrix + relativeMatrix.scale( scale.set( 1 / scale.x, 1 / scale.y, 1 / scale.z ) ); - globalMatrix.makeRotationFromQuaternion( quat.setFromRotationMatrix( relativeMatrix ) ); + // apply to global matrix + globalMatrix.makeRotationFromQuaternion( quat.setFromRotationMatrix( relativeMatrix ) ); if ( target.isObject3D ) { const boneIndex = bones.indexOf( bone ), @@ -146,7 +148,6 @@ bone = bones[ i ]; name = options.names[ bone.name ] || bone.name; - if ( name !== options.hip ) { bone.position.copy( bonesPosition[ i ] ); @@ -160,6 +161,7 @@ if ( options.preserveMatrix ) { // restore matrix + target.updateMatrixWorld( true ); } @@ -171,7 +173,6 @@ options.useFirstFramePosition = options.useFirstFramePosition !== undefined ? options.useFirstFramePosition : false; options.fps = options.fps !== undefined ? options.fps : 30; options.names = options.names || []; - if ( ! source.isObject3D ) { source = getHelperFromSkeleton( source ); @@ -188,24 +189,20 @@ mixer.clipAction( clip ).play(); mixer.update( 0 ); source.updateMatrixWorld(); - for ( let i = 0; i < numFrames; ++ i ) { const time = i * delta; retarget( target, source, options ); - for ( let j = 0; j < bones.length; ++ j ) { name = options.names[ bones[ j ].name ] || bones[ j ].name; boneTo = getBoneByName( name, source.skeleton ); - if ( boneTo ) { bone = bones[ j ]; boneData = boneDatas[ j ] = boneDatas[ j ] || { bone: bone }; - if ( options.hip === name ) { if ( ! boneData.pos ) { @@ -258,7 +255,6 @@ for ( let i = 0; i < boneDatas.length; ++ i ) { boneData = boneDatas[ i ]; - if ( boneData ) { if ( boneData.pos ) { @@ -296,7 +292,6 @@ sourceDir = new THREE.Vector2(); options.hip = options.hip !== undefined ? options.hip : 'hip'; options.names = options.names || {}; - if ( ! source.isObject3D ) { source = getHelperFromSkeleton( source ); @@ -310,13 +305,11 @@ offsets = []; let bone, boneTo, name, i; target.skeleton.pose(); - for ( i = 0; i < bones.length; ++ i ) { bone = bones[ i ]; name = options.names[ bone.name ] || bone.name; boneTo = getBoneByName( name, sourceBones ); - if ( boneTo && name !== options.hip ) { const boneParent = getNearestBone( bone.parent, nameKeys ), @@ -347,11 +340,9 @@ function renameBones( skeleton, names ) { const bones = getBones( skeleton ); - for ( let i = 0; i < bones.length; ++ i ) { const bone = bones[ i ]; - if ( names[ bone.name ] ) { bone.name = names[ bone.name ]; @@ -402,13 +393,11 @@ result = { name: name }; - for ( let i = 0; i < tracks.length; ++ i ) { // 1 is track name // 2 is track type const trackData = regexp.exec( tracks[ i ].name ); - if ( trackData && name === trackData[ 1 ] ) { result[ trackData[ 2 ] ] = i; @@ -426,11 +415,9 @@ const sourceBones = getBones( skeleton ), targetBones = getBones( targetSkeleton ), bones = []; - search: for ( let i = 0; i < sourceBones.length; i ++ ) { const boneName = sourceBones[ i ].name; - for ( let j = 0; j < targetBones.length; j ++ ) { if ( boneName === targetBones[ j ].name ) { @@ -482,7 +469,6 @@ function parallelTraverse( a, b, callback ) { callback( a, b ); - for ( let i = 0; i < a.children.length; i ++ ) { parallelTraverse( a.children[ i ], b.children[ i ], callback ); diff --git a/examples/js/utils/UVsDebug.js b/examples/js/utils/UVsDebug.js index 31e7d227f92545..b2bdad7092e119 100644 --- a/examples/js/utils/UVsDebug.js +++ b/examples/js/utils/UVsDebug.js @@ -11,6 +11,7 @@ function UVsDebug( geometry, size = 1024 ) { // handles wrapping of uv.x > 1 only + const abc = 'abc'; const a = new THREE.Vector2(); const b = new THREE.Vector2(); @@ -18,23 +19,24 @@ const face = []; const canvas = document.createElement( 'canvas' ); const width = size; // power of 2 required for wrapping - const height = size; canvas.width = width; canvas.height = height; const ctx = canvas.getContext( '2d' ); ctx.lineWidth = 1; ctx.strokeStyle = 'rgb( 63, 63, 63 )'; - ctx.textAlign = 'center'; // paint background white + ctx.textAlign = 'center'; + + // paint background white ctx.fillStyle = 'rgb( 255, 255, 255 )'; ctx.fillRect( 0, 0, width, height ); const index = geometry.index; const uvAttribute = geometry.attributes.uv; - if ( index ) { // indexed geometry + for ( let i = 0, il = index.count; i < il; i += 3 ) { face[ 0 ] = index.getX( i ); @@ -50,6 +52,7 @@ } else { // non-indexed geometry + for ( let i = 0, il = uvAttribute.count; i < il; i += 3 ) { face[ 0 ] = i; @@ -65,19 +68,17 @@ } return canvas; - function processFace( face, uvs, index ) { // draw contour of face + ctx.beginPath(); a.set( 0, 0 ); - for ( let j = 0, jl = uvs.length; j < jl; j ++ ) { const uv = uvs[ j ]; a.x += uv.x; a.y += uv.y; - if ( j === 0 ) { ctx.moveTo( uv.x * ( width - 2 ) + 0.5, ( 1 - uv.y ) * ( height - 2 ) + 0.5 ); @@ -91,24 +92,31 @@ } ctx.closePath(); - ctx.stroke(); // calculate center of face + ctx.stroke(); + + // calculate center of face + + a.divideScalar( uvs.length ); - a.divideScalar( uvs.length ); // label the face number + // label the face number ctx.font = '18px Arial'; ctx.fillStyle = 'rgb( 63, 63, 63 )'; ctx.fillText( index, a.x * width, ( 1 - a.y ) * height ); - if ( a.x > 0.95 ) { // wrap x // 0.95 is arbitrary + ctx.fillText( index, a.x % 1 * width, ( 1 - a.y ) * height ); - } // + } + // ctx.font = '12px Arial'; - ctx.fillStyle = 'rgb( 191, 191, 191 )'; // label uv edge orders + ctx.fillStyle = 'rgb( 191, 191, 191 )'; + + // label uv edge orders for ( let j = 0, jl = uvs.length; j < jl; j ++ ) { @@ -116,10 +124,10 @@ b.addVectors( a, uv ).divideScalar( 2 ); const vnum = face[ j ]; ctx.fillText( abc[ j ] + vnum, b.x * width, ( 1 - b.y ) * height ); - if ( b.x > 0.95 ) { // wrap x + ctx.fillText( abc[ j ] + vnum, b.x % 1 * width, ( 1 - b.y ) * height ); } diff --git a/examples/js/utils/WorkerPool.js b/examples/js/utils/WorkerPool.js index f3220d3f85d8e8..399a867dcaeeac 100644 --- a/examples/js/utils/WorkerPool.js +++ b/examples/js/utils/WorkerPool.js @@ -3,6 +3,7 @@ /** * @author Deepkolos / https://github.com/deepkolos */ + class WorkerPool { constructor( pool = 4 ) { @@ -14,7 +15,6 @@ this.workerStatus = 0; } - _initWorker( workerId ) { if ( ! this.workers[ workerId ] ) { @@ -26,20 +26,16 @@ } } - _getIdleWorker() { for ( let i = 0; i < this.pool; i ++ ) if ( ! ( this.workerStatus & 1 << i ) ) return i; - return - 1; } - _onMessage( workerId, msg ) { const resolve = this.workersResolve[ workerId ]; resolve && resolve( msg ); - if ( this.queue.length ) { const { @@ -57,29 +53,24 @@ } } - setWorkerCreator( workerCreator ) { this.workerCreator = workerCreator; } - setWorkerLimit( pool ) { this.pool = pool; } - postMessage( msg, transfer ) { return new Promise( resolve => { const workerId = this._getIdleWorker(); - if ( workerId !== - 1 ) { this._initWorker( workerId ); - this.workerStatus |= 1 << workerId; this.workersResolve[ workerId ] = resolve; this.workers[ workerId ].postMessage( msg, transfer ); @@ -97,7 +88,6 @@ } ); } - dispose() { this.workers.forEach( worker => worker.terminate() ); diff --git a/examples/jsm/animation/CCDIKSolver.js b/examples/jsm/animation/CCDIKSolver.js index 7282c767fa8b23..7066c99b7fc240 100644 --- a/examples/jsm/animation/CCDIKSolver.js +++ b/examples/jsm/animation/CCDIKSolver.js @@ -217,7 +217,7 @@ class CCDIKSolver { */ createHelper() { - return new CCDIKHelper( this.mesh, this.mesh.geometry.userData.MMD.iks ); + return new CCDIKHelper( this.mesh, this.iks ); } @@ -283,7 +283,7 @@ function setPositionOfBoneToAttributeArray( array, index, bone, matrixWorldInv ) */ class CCDIKHelper extends Object3D { - constructor( mesh, iks = [] ) { + constructor( mesh, iks = [], sphereSize = 0.25 ) { super(); @@ -293,7 +293,7 @@ class CCDIKHelper extends Object3D { this.matrix.copy( mesh.matrixWorld ); this.matrixAutoUpdate = false; - this.sphereGeometry = new SphereGeometry( 0.25, 16, 8 ); + this.sphereGeometry = new SphereGeometry( sphereSize, 16, 8 ); this.targetSphereMaterial = new MeshBasicMaterial( { color: new Color( 0xff8888 ), @@ -393,6 +393,30 @@ class CCDIKHelper extends Object3D { } + /** + * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. + */ + dispose() { + + this.sphereGeometry.dispose(); + + this.targetSphereMaterial.dispose(); + this.effectorSphereMaterial.dispose(); + this.linkSphereMaterial.dispose(); + this.lineMaterial.dispose(); + + const children = this.children; + + for ( let i = 0; i < children.length; i ++ ) { + + const child = children[ i ]; + + if ( child.isLine ) child.geometry.dispose(); + + } + + } + // private method _init() { diff --git a/examples/jsm/animation/MMDPhysics.js b/examples/jsm/animation/MMDPhysics.js index 447c1d77c60246..057090112e818b 100644 --- a/examples/jsm/animation/MMDPhysics.js +++ b/examples/jsm/animation/MMDPhysics.js @@ -1,8 +1,8 @@ import { Bone, BoxGeometry, + CapsuleGeometry, Color, - CylinderGeometry, Euler, Matrix4, Mesh, @@ -1292,6 +1292,31 @@ class MMDPhysicsHelper extends Object3D { } + + /** + * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. + */ + dispose() { + + const materials = this.materials; + const children = this.children; + + for ( let i = 0; i < materials.length; i ++ ) { + + materials[ i ].dispose(); + + } + + for ( let i = 0; i < children.length; i ++ ) { + + const child = children[ i ]; + + if ( child.isMesh ) child.geometry.dispose(); + + } + + } + /** * Updates Rigid Bodies visualization. */ @@ -1358,7 +1383,7 @@ class MMDPhysicsHelper extends Object3D { return new BoxGeometry( param.width * 2, param.height * 2, param.depth * 2, 8, 8, 8 ); case 2: - return new createCapsuleGeometry( param.width, param.height, 16, 8 ); + return new CapsuleGeometry( param.width, param.height, 8, 16 ); default: return null; @@ -1367,25 +1392,6 @@ class MMDPhysicsHelper extends Object3D { } - function createCapsuleGeometry( radius, cylinderHeight, segmentsRadius, segmentsHeight ) { - - var geometry = new CylinderGeometry( radius, radius, cylinderHeight, segmentsRadius, segmentsHeight, true ); - var upperSphere = new Mesh( new SphereGeometry( radius, segmentsRadius, segmentsHeight, 0, Math.PI * 2, 0, Math.PI / 2 ) ); - var lowerSphere = new Mesh( new SphereGeometry( radius, segmentsRadius, segmentsHeight, 0, Math.PI * 2, Math.PI / 2, Math.PI / 2 ) ); - - upperSphere.position.set( 0, cylinderHeight / 2, 0 ); - lowerSphere.position.set( 0, - cylinderHeight / 2, 0 ); - - upperSphere.updateMatrix(); - lowerSphere.updateMatrix(); - - geometry.merge( upperSphere.geometry, upperSphere.matrix ); - geometry.merge( lowerSphere.geometry, lowerSphere.matrix ); - - return geometry; - - } - for ( var i = 0, il = bodies.length; i < il; i ++ ) { var param = bodies[ i ].params; diff --git a/examples/jsm/capabilities/WebGPU.js b/examples/jsm/capabilities/WebGPU.js index db29174e29ea1f..8b1c8c1b9ac845 100644 --- a/examples/jsm/capabilities/WebGPU.js +++ b/examples/jsm/capabilities/WebGPU.js @@ -14,7 +14,9 @@ class WebGPU { static getErrorMessage() { - const message = 'Your browser does not support WebGPU'; + let message = 'Your browser does not support WebGPU'; + + if ( !! window.chrome ) message += '
    Try: chrome://flags/#enable-unsafe-webgpu'; const element = document.createElement( 'div' ); element.id = 'webgpumessage'; diff --git a/examples/jsm/controls/ArcballControls.js b/examples/jsm/controls/ArcballControls.js index a08d92a2127825..bd24a97985320f 100644 --- a/examples/jsm/controls/ArcballControls.js +++ b/examples/jsm/controls/ArcballControls.js @@ -2296,15 +2296,15 @@ class ArcballControls extends EventDispatcher { // - this._gizmos.traverse( function( object ) { + this._gizmos.traverse( function ( object ) { if ( object.isLine ) { - + object.geometry.dispose(); object.material.dispose(); - + } - + } ); this._gizmos.clear(); diff --git a/examples/jsm/controls/FirstPersonControls.js b/examples/jsm/controls/FirstPersonControls.js index 143e1395259415..0d03421c8b8c54 100644 --- a/examples/jsm/controls/FirstPersonControls.js +++ b/examples/jsm/controls/FirstPersonControls.js @@ -12,13 +12,6 @@ class FirstPersonControls { constructor( object, domElement ) { - if ( domElement === undefined ) { - - console.warn( 'THREE.FirstPersonControls: The second parameter "domElement" is now mandatory.' ); - domElement = document; - - } - this.object = object; this.domElement = domElement; @@ -49,8 +42,8 @@ class FirstPersonControls { this.autoSpeedFactor = 0.0; - this.mouseX = 0; - this.mouseY = 0; + this.pointerX = 0; + this.pointerY = 0; this.moveForward = false; this.moveBackward = false; @@ -83,7 +76,7 @@ class FirstPersonControls { }; - this.onMouseDown = function ( event ) { + this.onPointerDown = function ( event ) { if ( this.domElement !== document ) { @@ -106,7 +99,7 @@ class FirstPersonControls { }; - this.onMouseUp = function ( event ) { + this.onPointerUp = function ( event ) { if ( this.activeLook ) { @@ -123,17 +116,17 @@ class FirstPersonControls { }; - this.onMouseMove = function ( event ) { + this.onPointerMove = function ( event ) { if ( this.domElement === document ) { - this.mouseX = event.pageX - this.viewHalfX; - this.mouseY = event.pageY - this.viewHalfY; + this.pointerX = event.pageX - this.viewHalfX; + this.pointerY = event.pageY - this.viewHalfY; } else { - this.mouseX = event.pageX - this.domElement.offsetLeft - this.viewHalfX; - this.mouseY = event.pageY - this.domElement.offsetTop - this.viewHalfY; + this.pointerX = event.pageX - this.domElement.offsetLeft - this.viewHalfX; + this.pointerY = event.pageY - this.domElement.offsetTop - this.viewHalfY; } @@ -253,8 +246,8 @@ class FirstPersonControls { } - lon -= this.mouseX * actualLookSpeed; - if ( this.lookVertical ) lat -= this.mouseY * actualLookSpeed * verticalLookRatio; + lon -= this.pointerX * actualLookSpeed; + if ( this.lookVertical ) lat -= this.pointerY * actualLookSpeed * verticalLookRatio; lat = Math.max( - 85, Math.min( 85, lat ) ); @@ -280,25 +273,25 @@ class FirstPersonControls { this.dispose = function () { this.domElement.removeEventListener( 'contextmenu', contextmenu ); - this.domElement.removeEventListener( 'mousedown', _onMouseDown ); - this.domElement.removeEventListener( 'mousemove', _onMouseMove ); - this.domElement.removeEventListener( 'mouseup', _onMouseUp ); + this.domElement.removeEventListener( 'pointerdown', _onPointerDown ); + this.domElement.removeEventListener( 'pointermove', _onPointerMove ); + this.domElement.removeEventListener( 'pointerup', _onPointerUp ); window.removeEventListener( 'keydown', _onKeyDown ); window.removeEventListener( 'keyup', _onKeyUp ); }; - const _onMouseMove = this.onMouseMove.bind( this ); - const _onMouseDown = this.onMouseDown.bind( this ); - const _onMouseUp = this.onMouseUp.bind( this ); + const _onPointerMove = this.onPointerMove.bind( this ); + const _onPointerDown = this.onPointerDown.bind( this ); + const _onPointerUp = this.onPointerUp.bind( this ); const _onKeyDown = this.onKeyDown.bind( this ); const _onKeyUp = this.onKeyUp.bind( this ); this.domElement.addEventListener( 'contextmenu', contextmenu ); - this.domElement.addEventListener( 'mousemove', _onMouseMove ); - this.domElement.addEventListener( 'mousedown', _onMouseDown ); - this.domElement.addEventListener( 'mouseup', _onMouseUp ); + this.domElement.addEventListener( 'pointerdown', _onPointerDown ); + this.domElement.addEventListener( 'pointermove', _onPointerMove ); + this.domElement.addEventListener( 'pointerup', _onPointerUp ); window.addEventListener( 'keydown', _onKeyDown ); window.addEventListener( 'keyup', _onKeyUp ); diff --git a/examples/jsm/controls/FlyControls.js b/examples/jsm/controls/FlyControls.js index 69a29a21475444..0c6bb3a5442c30 100644 --- a/examples/jsm/controls/FlyControls.js +++ b/examples/jsm/controls/FlyControls.js @@ -12,13 +12,6 @@ class FlyControls extends EventDispatcher { super(); - if ( domElement === undefined ) { - - console.warn( 'THREE.FlyControls: The second parameter "domElement" is now mandatory.' ); - domElement = document; - - } - this.object = object; this.domElement = domElement; @@ -43,7 +36,7 @@ class FlyControls extends EventDispatcher { this.tmpQuaternion = new Quaternion(); - this.mouseStatus = 0; + this.status = 0; this.moveState = { up: 0, down: 0, left: 0, right: 0, forward: 0, back: 0, pitchUp: 0, pitchDown: 0, yawLeft: 0, yawRight: 0, rollLeft: 0, rollRight: 0 }; this.moveVector = new Vector3( 0, 0, 0 ); @@ -119,11 +112,11 @@ class FlyControls extends EventDispatcher { }; - this.mousedown = function ( event ) { + this.pointerdown = function ( event ) { if ( this.dragToLook ) { - this.mouseStatus ++; + this.status ++; } else { @@ -140,9 +133,9 @@ class FlyControls extends EventDispatcher { }; - this.mousemove = function ( event ) { + this.pointermove = function ( event ) { - if ( ! this.dragToLook || this.mouseStatus > 0 ) { + if ( ! this.dragToLook || this.status > 0 ) { const container = this.getContainerDimensions(); const halfWidth = container.size[ 0 ] / 2; @@ -157,11 +150,11 @@ class FlyControls extends EventDispatcher { }; - this.mouseup = function ( event ) { + this.pointerup = function ( event ) { if ( this.dragToLook ) { - this.mouseStatus --; + this.status --; this.moveState.yawLeft = this.moveState.pitchDown = 0; @@ -252,26 +245,25 @@ class FlyControls extends EventDispatcher { this.dispose = function () { this.domElement.removeEventListener( 'contextmenu', contextmenu ); - this.domElement.removeEventListener( 'mousedown', _mousedown ); - this.domElement.removeEventListener( 'mousemove', _mousemove ); - this.domElement.removeEventListener( 'mouseup', _mouseup ); + this.domElement.removeEventListener( 'pointerdown', _pointerdown ); + this.domElement.removeEventListener( 'pointermove', _pointermove ); + this.domElement.removeEventListener( 'pointerup', _pointerup ); window.removeEventListener( 'keydown', _keydown ); window.removeEventListener( 'keyup', _keyup ); }; - const _mousemove = this.mousemove.bind( this ); - const _mousedown = this.mousedown.bind( this ); - const _mouseup = this.mouseup.bind( this ); + const _pointermove = this.pointermove.bind( this ); + const _pointerdown = this.pointerdown.bind( this ); + const _pointerup = this.pointerup.bind( this ); const _keydown = this.keydown.bind( this ); const _keyup = this.keyup.bind( this ); this.domElement.addEventListener( 'contextmenu', contextmenu ); - - this.domElement.addEventListener( 'mousemove', _mousemove ); - this.domElement.addEventListener( 'mousedown', _mousedown ); - this.domElement.addEventListener( 'mouseup', _mouseup ); + this.domElement.addEventListener( 'pointerdown', _pointerdown ); + this.domElement.addEventListener( 'pointermove', _pointermove ); + this.domElement.addEventListener( 'pointerup', _pointerup ); window.addEventListener( 'keydown', _keydown ); window.addEventListener( 'keyup', _keyup ); diff --git a/examples/jsm/controls/OrbitControls.js b/examples/jsm/controls/OrbitControls.js index 539c734863a066..42eae81034e77d 100644 --- a/examples/jsm/controls/OrbitControls.js +++ b/examples/jsm/controls/OrbitControls.js @@ -25,9 +25,6 @@ class OrbitControls extends EventDispatcher { super(); - if ( domElement === undefined ) console.warn( 'THREE.OrbitControls: The second parameter "domElement" is now mandatory.' ); - if ( domElement === document ) console.error( 'THREE.OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.' ); - this.object = object; this.domElement = domElement; this.domElement.style.touchAction = 'none'; // disable touch scroll @@ -604,22 +601,62 @@ class OrbitControls extends EventDispatcher { switch ( event.code ) { case scope.keys.UP: - pan( 0, scope.keyPanSpeed ); + + if ( event.ctrlKey || event.metaKey || event.shiftKey ) { + + rotateUp( 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight ); + + } else { + + pan( 0, scope.keyPanSpeed ); + + } + needsUpdate = true; break; case scope.keys.BOTTOM: - pan( 0, - scope.keyPanSpeed ); + + if ( event.ctrlKey || event.metaKey || event.shiftKey ) { + + rotateUp( - 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight ); + + } else { + + pan( 0, - scope.keyPanSpeed ); + + } + needsUpdate = true; break; case scope.keys.LEFT: - pan( scope.keyPanSpeed, 0 ); + + if ( event.ctrlKey || event.metaKey || event.shiftKey ) { + + rotateLeft( 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight ); + + } else { + + pan( scope.keyPanSpeed, 0 ); + + } + needsUpdate = true; break; case scope.keys.RIGHT: - pan( - scope.keyPanSpeed, 0 ); + + if ( event.ctrlKey || event.metaKey || event.shiftKey ) { + + rotateLeft( - 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight ); + + } else { + + pan( - scope.keyPanSpeed, 0 ); + + } + needsUpdate = true; break; diff --git a/examples/jsm/controls/PointerLockControls.js b/examples/jsm/controls/PointerLockControls.js index 884a69ced30726..9bdebd28c1156e 100644 --- a/examples/jsm/controls/PointerLockControls.js +++ b/examples/jsm/controls/PointerLockControls.js @@ -19,13 +19,6 @@ class PointerLockControls extends EventDispatcher { super(); - if ( domElement === undefined ) { - - console.warn( 'THREE.PointerLockControls: The second parameter "domElement" is now mandatory.' ); - domElement = document.body; - - } - this.domElement = domElement; this.isLocked = false; diff --git a/examples/jsm/controls/TrackballControls.js b/examples/jsm/controls/TrackballControls.js index 2710f36a66b1ce..77ef51c48e03ee 100644 --- a/examples/jsm/controls/TrackballControls.js +++ b/examples/jsm/controls/TrackballControls.js @@ -16,9 +16,6 @@ class TrackballControls extends EventDispatcher { super(); - if ( domElement === undefined ) console.warn( 'THREE.TrackballControls: The second parameter "domElement" is now mandatory.' ); - if ( domElement === document ) console.error( 'THREE.TrackballControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.' ); - const scope = this; const STATE = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 }; @@ -703,8 +700,20 @@ class TrackballControls extends EventDispatcher { case 2: _state = STATE.TOUCH_ZOOM_PAN; - _moveCurr.copy( getMouseOnCircle( event.pageX - _movePrev.x, event.pageY - _movePrev.y ) ); - _movePrev.copy( _moveCurr ); + + for ( let i = 0; i < _pointers.length; i ++ ) { + + if ( _pointers[ i ].pointerId !== event.pointerId ) { + + const position = _pointerPositions[ _pointers[ i ].pointerId ]; + _moveCurr.copy( getMouseOnCircle( position.x, position.y ) ); + _movePrev.copy( _moveCurr ); + break; + + } + + } + break; } diff --git a/examples/jsm/controls/TransformControls.js b/examples/jsm/controls/TransformControls.js index 2049a451cf3469..839e8b56a2b0b5 100644 --- a/examples/jsm/controls/TransformControls.js +++ b/examples/jsm/controls/TransformControls.js @@ -207,7 +207,7 @@ class TransformControls extends Object3D { if ( this.camera.isOrthographicCamera ) { - this.camera.getWorldDirection( this.eye ); + this.camera.getWorldDirection( this.eye ).negate(); } else { @@ -643,12 +643,6 @@ class TransformControls extends Object3D { } - update() { - - console.warn( 'THREE.TransformControls: update function has no more functionality and therefore has been deprecated.' ); - - } - } // mouse / touch event handlers diff --git a/examples/jsm/csm/CSM.js b/examples/jsm/csm/CSM.js index c96e627f233af0..054b29b94162d7 100644 --- a/examples/jsm/csm/CSM.js +++ b/examples/jsm/csm/CSM.js @@ -343,6 +343,7 @@ export class CSM { for ( let i = 0; i < this.lights.length; i ++ ) { + this.parent.remove( this.lights[ i ].target ); this.parent.remove( this.lights[ i ] ); } diff --git a/examples/jsm/csm/CSMHelper.js b/examples/jsm/csm/CSMHelper.js index 7ea0a81975877d..d1cfed874bb836 100644 --- a/examples/jsm/csm/CSMHelper.js +++ b/examples/jsm/csm/CSMHelper.js @@ -158,6 +158,36 @@ class CSMHelper extends Group { } + dispose() { + + const frustumLines = this.frustumLines; + const cascadeLines = this.cascadeLines; + const cascadePlanes = this.cascadePlanes; + const shadowLines = this.shadowLines; + + frustumLines.geometry.dispose(); + frustumLines.material.dispose(); + + const cascades = this.csm.cascades; + + for ( let i = 0; i < cascades; i ++ ) { + + const cascadeLine = cascadeLines[ i ]; + const cascadePlane = cascadePlanes[ i ]; + const shadowLineGroup = shadowLines[ i ]; + const shadowLine = shadowLineGroup.children[ 0 ]; + + cascadeLine.dispose(); // Box3Helper + + cascadePlane.geometry.dispose(); + cascadePlane.material.dispose(); + + shadowLine.dispose(); // Box3Helper + + } + + } + } export { CSMHelper }; diff --git a/examples/jsm/effects/AnaglyphEffect.js b/examples/jsm/effects/AnaglyphEffect.js index d2b4134f0e7d8b..a3118cbe0c65db 100644 --- a/examples/jsm/effects/AnaglyphEffect.js +++ b/examples/jsm/effects/AnaglyphEffect.js @@ -131,9 +131,9 @@ class AnaglyphEffect { const currentRenderTarget = renderer.getRenderTarget(); - scene.updateMatrixWorld(); + if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld(); - if ( camera.parent === null ) camera.updateMatrixWorld(); + if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld(); _stereo.update( camera ); diff --git a/examples/jsm/effects/OutlineEffect.js b/examples/jsm/effects/OutlineEffect.js index 02c70fa8514b8f..90edbd47cca8d9 100644 --- a/examples/jsm/effects/OutlineEffect.js +++ b/examples/jsm/effects/OutlineEffect.js @@ -55,7 +55,7 @@ import { * // How to set outline parameters for each material * material.userData.outlineParameters = { * thickness: 0.01, - * color: [ 0, 0, 0 ] + * color: [ 0, 0, 0 ], * alpha: 0.8, * visible: true, * keepAlive: true @@ -429,27 +429,6 @@ class OutlineEffect { this.render = function ( scene, camera ) { - let renderTarget; - let forceClear = false; - - if ( arguments[ 2 ] !== undefined ) { - - console.warn( 'THREE.OutlineEffect.render(): the renderTarget argument has been removed. Use .setRenderTarget() instead.' ); - renderTarget = arguments[ 2 ]; - - } - - if ( arguments[ 3 ] !== undefined ) { - - console.warn( 'THREE.OutlineEffect.render(): the forceClear argument has been removed. Use .clear() instead.' ); - forceClear = arguments[ 3 ]; - - } - - if ( renderTarget !== undefined ) renderer.setRenderTarget( renderTarget ); - - if ( forceClear ) renderer.clear(); - if ( this.enabled === false ) { renderer.render( scene, camera ); @@ -471,11 +450,11 @@ class OutlineEffect { this.renderOutline = function ( scene, camera ) { const currentAutoClear = renderer.autoClear; - const currentSceneAutoUpdate = scene.autoUpdate; + const currentSceneAutoUpdate = scene.matrixWorldAutoUpdate; const currentSceneBackground = scene.background; const currentShadowMapEnabled = renderer.shadowMap.enabled; - scene.autoUpdate = false; + scene.matrixWorldAutoUpdate = false; scene.background = null; renderer.autoClear = false; renderer.shadowMap.enabled = false; @@ -488,7 +467,7 @@ class OutlineEffect { cleanupCache(); - scene.autoUpdate = currentSceneAutoUpdate; + scene.matrixWorldAutoUpdate = currentSceneAutoUpdate; scene.background = currentSceneBackground; renderer.autoClear = currentAutoClear; renderer.shadowMap.enabled = currentShadowMapEnabled; diff --git a/examples/jsm/effects/ParallaxBarrierEffect.js b/examples/jsm/effects/ParallaxBarrierEffect.js index 500679353e28a4..3ad41f78fa2ca0 100644 --- a/examples/jsm/effects/ParallaxBarrierEffect.js +++ b/examples/jsm/effects/ParallaxBarrierEffect.js @@ -90,9 +90,9 @@ class ParallaxBarrierEffect { this.render = function ( scene, camera ) { - scene.updateMatrixWorld(); + if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld(); - if ( camera.parent === null ) camera.updateMatrixWorld(); + if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld(); _stereo.update( camera ); diff --git a/examples/jsm/effects/PeppersGhostEffect.js b/examples/jsm/effects/PeppersGhostEffect.js index 5af15996951436..15720964949e3c 100644 --- a/examples/jsm/effects/PeppersGhostEffect.js +++ b/examples/jsm/effects/PeppersGhostEffect.js @@ -53,9 +53,9 @@ class PeppersGhostEffect { this.render = function ( scene, camera ) { - scene.updateMatrixWorld(); + if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld(); - if ( camera.parent === null ) camera.updateMatrixWorld(); + if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld(); camera.matrixWorld.decompose( _position, _quaternion, _scale ); diff --git a/examples/jsm/effects/StereoEffect.js b/examples/jsm/effects/StereoEffect.js index e4c6d922f3777d..e6e1b44767e6a9 100644 --- a/examples/jsm/effects/StereoEffect.js +++ b/examples/jsm/effects/StereoEffect.js @@ -25,9 +25,9 @@ class StereoEffect { this.render = function ( scene, camera ) { - scene.updateMatrixWorld(); + if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld(); - if ( camera.parent === null ) camera.updateMatrixWorld(); + if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld(); _stereo.update( camera ); diff --git a/examples/jsm/environments/RoomEnvironment.js b/examples/jsm/environments/RoomEnvironment.js index eb222c100775bf..1846dfabb79235 100644 --- a/examples/jsm/environments/RoomEnvironment.js +++ b/examples/jsm/environments/RoomEnvironment.js @@ -108,6 +108,29 @@ class RoomEnvironment extends Scene { } + dispose() { + + const resources = new Set(); + + this.traverse( ( object ) => { + + if ( object.isMesh ) { + + resources.add( object.geometry ); + resources.add( object.material ); + + } + + } ); + + for ( const resource of resources ) { + + resource.dispose(); + + } + + } + } function createAreaLightMaterial( intensity ) { diff --git a/examples/jsm/exporters/ColladaExporter.js b/examples/jsm/exporters/ColladaExporter.js index c9cbcbfa412f73..8b1562a2865c5f 100644 --- a/examples/jsm/exporters/ColladaExporter.js +++ b/examples/jsm/exporters/ColladaExporter.js @@ -243,21 +243,12 @@ class ColladaExporter { // Process the given piece of geometry into the geometry library // Returns the mesh id - function processGeometry( g ) { + function processGeometry( bufferGeometry ) { - let info = geometryInfo.get( g ); + let info = geometryInfo.get( bufferGeometry ); if ( ! info ) { - // convert the geometry to bufferGeometry if it isn't already - const bufferGeometry = g; - - if ( bufferGeometry.isBufferGeometry !== true ) { - - throw new Error( 'THREE.ColladaExporter: Geometry is not of type THREE.BufferGeometry.' ); - - } - const meshid = `Mesh${ libraryGeometries.length + 1 }`; const indexCount = @@ -271,7 +262,7 @@ class ColladaExporter { [ { start: 0, count: indexCount, materialIndex: 0 } ]; - const gname = g.name ? ` name="${ g.name }"` : ''; + const gname = bufferGeometry.name ? ` name="${ bufferGeometry.name }"` : ''; let gnode = ``; // define the geometry node and the vertices for the geometry @@ -353,7 +344,7 @@ class ColladaExporter { libraryGeometries.push( gnode ); info = { meshid: meshid, bufferGeometry: bufferGeometry }; - geometryInfo.set( g, info ); + geometryInfo.set( bufferGeometry, info ); } diff --git a/examples/jsm/exporters/DRACOExporter.js b/examples/jsm/exporters/DRACOExporter.js index 6800d86ef0ccc8..b8f5f3f8aa9485 100644 --- a/examples/jsm/exporters/DRACOExporter.js +++ b/examples/jsm/exporters/DRACOExporter.js @@ -26,12 +26,6 @@ class DRACOExporter { exportColor: false, } ) { - if ( object.isBufferGeometry === true ) { - - throw new Error( 'DRACOExporter: The first parameter of parse() is now an instance of Mesh or Points.' ); - - } - if ( DracoEncoderModule === undefined ) { throw new Error( 'THREE.DRACOExporter: required the draco_encoder to work.' ); @@ -45,13 +39,6 @@ class DRACOExporter { let builder; let dracoObject; - - if ( geometry.isBufferGeometry !== true ) { - - throw new Error( 'THREE.DRACOExporter.parse(geometry, options): geometry is not a THREE.BufferGeometry instance.' ); - - } - if ( object.isMesh === true ) { builder = new dracoEncoder.MeshBuilder(); diff --git a/examples/jsm/exporters/GLTFExporter.js b/examples/jsm/exporters/GLTFExporter.js index 10cd6176a3669f..31fc279ac4ef3a 100644 --- a/examples/jsm/exporters/GLTFExporter.js +++ b/examples/jsm/exporters/GLTFExporter.js @@ -23,7 +23,6 @@ import { Vector3 } from 'three'; - class GLTFExporter { constructor() { @@ -42,12 +41,6 @@ class GLTFExporter { } ); - this.register( function ( writer ) { - - return new GLTFMaterialsPBRSpecularGlossiness( writer ); - - } ); - this.register( function ( writer ) { return new GLTFMaterialsTransmissionExtension( writer ); @@ -107,14 +100,6 @@ class GLTFExporter { */ parse( input, onDone, onError, options ) { - if ( typeof onError === 'object' ) { - - console.warn( 'THREE.GLTFExporter: parse() expects options as the fourth argument now.' ); - - options = onError; - - } - const writer = new GLTFWriter(); const plugins = []; @@ -447,7 +432,6 @@ class GLTFWriter { binary: false, trs: false, onlyVisible: true, - truncateDrawRange: true, maxTextureSize: Infinity, animations: [], includeCustomExtensions: false @@ -742,7 +726,7 @@ class GLTFWriter { return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 ); - } + }; } @@ -750,7 +734,7 @@ class GLTFWriter { return c; - } + }; } @@ -996,7 +980,6 @@ class GLTFWriter { */ processAccessor( attribute, geometry, start, count ) { - const options = this.options; const json = this.json; const types = { @@ -1037,21 +1020,6 @@ class GLTFWriter { if ( start === undefined ) start = 0; if ( count === undefined ) count = attribute.count; - // @TODO Indexed buffer geometry with drawRange not supported yet - if ( options.truncateDrawRange && geometry !== undefined && geometry.index === null ) { - - const end = start + count; - const end2 = geometry.drawRange.count === Infinity - ? attribute.count - : geometry.drawRange.start + geometry.drawRange.count; - - start = Math.max( start, geometry.drawRange.start ); - count = Math.min( end, end2 ) - start; - - if ( count < 0 ) count = 0; - - } - // Skip creating an accessor if the attribute doesn't have data to export if ( count === 0 ) return null; @@ -1495,12 +1463,6 @@ class GLTFWriter { } - if ( geometry.isBufferGeometry !== true ) { - - throw new Error( 'THREE.GLTFExporter: Geometry is not of type THREE.BufferGeometry.' ); - - } - const meshDef = {}; const attributes = {}; const primitives = []; @@ -2313,62 +2275,6 @@ class GLTFMaterialsUnlitExtension { } -/** - * Specular-Glossiness Extension - * - * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness - */ -class GLTFMaterialsPBRSpecularGlossiness { - - constructor( writer ) { - - this.writer = writer; - this.name = 'KHR_materials_pbrSpecularGlossiness'; - - } - - writeMaterial( material, materialDef ) { - - if ( ! material.isGLTFSpecularGlossinessMaterial ) return; - - const writer = this.writer; - const extensionsUsed = writer.extensionsUsed; - - const extensionDef = {}; - - if ( materialDef.pbrMetallicRoughness.baseColorFactor ) { - - extensionDef.diffuseFactor = materialDef.pbrMetallicRoughness.baseColorFactor; - - } - - const specularFactor = [ 1, 1, 1 ]; - material.specular.toArray( specularFactor, 0 ); - extensionDef.specularFactor = specularFactor; - extensionDef.glossinessFactor = material.glossiness; - - if ( materialDef.pbrMetallicRoughness.baseColorTexture ) { - - extensionDef.diffuseTexture = materialDef.pbrMetallicRoughness.baseColorTexture; - - } - - if ( material.specularMap ) { - - const specularMapDef = { index: writer.processTexture( material.specularMap ) }; - writer.applyTextureTransform( specularMapDef, material.specularMap ); - extensionDef.specularGlossinessTexture = specularMapDef; - - } - - materialDef.extensions = materialDef.extensions || {}; - materialDef.extensions[ this.name ] = extensionDef; - extensionsUsed[ this.name ] = true; - - } - -} - /** * Clearcoat Materials Extension * diff --git a/examples/jsm/exporters/OBJExporter.js b/examples/jsm/exporters/OBJExporter.js index 0c7265e2729532..63a483e2b7c2e7 100644 --- a/examples/jsm/exporters/OBJExporter.js +++ b/examples/jsm/exporters/OBJExporter.js @@ -32,12 +32,6 @@ class OBJExporter { const normalMatrixWorld = new Matrix3(); - if ( geometry.isBufferGeometry !== true ) { - - throw new Error( 'THREE.OBJExporter: Geometry is not of type THREE.BufferGeometry.' ); - - } - // shortcuts const vertices = geometry.getAttribute( 'position' ); const normals = geometry.getAttribute( 'normal' ); @@ -159,12 +153,6 @@ class OBJExporter { const geometry = line.geometry; const type = line.type; - if ( geometry.isBufferGeometry !== true ) { - - throw new Error( 'THREE.OBJExporter: Geometry is not of type THREE.BufferGeometry.' ); - - } - // shortcuts const vertices = geometry.getAttribute( 'position' ); @@ -222,12 +210,6 @@ class OBJExporter { const geometry = points.geometry; - if ( geometry.isBufferGeometry !== true ) { - - throw new Error( 'THREE.OBJExporter: Geometry is not of type THREE.BufferGeometry.' ); - - } - const vertices = geometry.getAttribute( 'position' ); const colors = geometry.getAttribute( 'color' ); diff --git a/examples/jsm/exporters/PLYExporter.js b/examples/jsm/exporters/PLYExporter.js index a3606586bfcaa5..be26708b655051 100644 --- a/examples/jsm/exporters/PLYExporter.js +++ b/examples/jsm/exporters/PLYExporter.js @@ -21,30 +21,16 @@ class PLYExporter { parse( object, onDone, options ) { - if ( onDone && typeof onDone === 'object' ) { - - console.warn( 'THREE.PLYExporter: The options parameter is now the third argument to the "parse" function. See the documentation for the new API.' ); - options = onDone; - onDone = undefined; - - } - // Iterate over the valid meshes in the object function traverseMeshes( cb ) { object.traverse( function ( child ) { - if ( child.isMesh === true ) { + if ( child.isMesh === true || child.isPoints ) { const mesh = child; const geometry = mesh.geometry; - if ( geometry.isBufferGeometry !== true ) { - - throw new Error( 'THREE.PLYExporter: Geometry is not of type THREE.BufferGeometry.' ); - - } - if ( geometry.hasAttribute( 'position' ) === true ) { cb( mesh, geometry ); @@ -67,6 +53,7 @@ class PLYExporter { options = Object.assign( defaultOptions, options ); const excludeAttributes = options.excludeAttributes; + let includeIndices = true; let includeNormals = false; let includeColors = false; let includeUVs = false; @@ -75,6 +62,7 @@ class PLYExporter { // and cache the BufferGeometry let vertexCount = 0; let faceCount = 0; + object.traverse( function ( child ) { if ( child.isMesh === true ) { @@ -82,12 +70,6 @@ class PLYExporter { const mesh = child; const geometry = mesh.geometry; - if ( geometry.isBufferGeometry !== true ) { - - throw new Error( 'THREE.PLYExporter: Geometry is not of type THREE.BufferGeometry.' ); - - } - const vertices = geometry.getAttribute( 'position' ); const normals = geometry.getAttribute( 'normal' ); const uvs = geometry.getAttribute( 'uv' ); @@ -109,12 +91,22 @@ class PLYExporter { if ( colors !== undefined ) includeColors = true; + } else if ( child.isPoints ) { + + const mesh = child; + const geometry = mesh.geometry; + + const vertices = geometry.getAttribute( 'position' ); + vertexCount += vertices.count; + + includeIndices = false; + } } ); const tempColor = new Color(); - const includeIndices = excludeAttributes.indexOf( 'index' ) === - 1; + includeIndices = includeIndices && excludeAttributes.indexOf( 'index' ) === - 1; includeNormals = includeNormals && excludeAttributes.indexOf( 'normal' ) === - 1; includeColors = includeColors && excludeAttributes.indexOf( 'color' ) === - 1; includeUVs = includeUVs && excludeAttributes.indexOf( 'uv' ) === - 1; diff --git a/examples/jsm/exporters/STLExporter.js b/examples/jsm/exporters/STLExporter.js index ff77e79d9943b5..e60e51068e9cc4 100644 --- a/examples/jsm/exporters/STLExporter.js +++ b/examples/jsm/exporters/STLExporter.js @@ -1,6 +1,4 @@ -import { - Vector3 -} from 'three'; +import { Vector3 } from 'three'; /** * Usage: @@ -28,12 +26,6 @@ class STLExporter { const geometry = object.geometry; - if ( geometry.isBufferGeometry !== true ) { - - throw new Error( 'THREE.STLExporter: Geometry is not of type THREE.BufferGeometry.' ); - - } - const index = geometry.index; const positionAttribute = geometry.getAttribute( 'position' ); diff --git a/examples/jsm/exporters/USDZExporter.js b/examples/jsm/exporters/USDZExporter.js index 8ce5743a165dec..fd47e3b2bfe715 100644 --- a/examples/jsm/exporters/USDZExporter.js +++ b/examples/jsm/exporters/USDZExporter.js @@ -6,7 +6,7 @@ import * as fflate from '../libs/fflate.module.js'; class USDZExporter { - async parse( scene ) { + async parse( scene, options = { ar: { anchoring: { type: 'plane' }, planeAnchoring: { alignment: 'horizontal' } } } ) { const files = {}; const modelFileName = 'model.usda'; @@ -16,6 +16,8 @@ class USDZExporter { let output = buildHeader(); + output += buildSceneStart( options ); + const materials = {}; const textures = {}; @@ -23,10 +25,10 @@ class USDZExporter { if ( object.isMesh ) { - if ( object.material.isMeshStandardMaterial ) { + const geometry = object.geometry; + const material = object.material; - const geometry = object.geometry; - const material = object.material; + if ( material.isMeshStandardMaterial ) { const geometryFileName = 'geometries/Geometry_' + geometry.id + '.usd'; @@ -51,10 +53,17 @@ class USDZExporter { } + } else if ( object.isCamera ) { + + output += buildCamera( object ); + } } ); + + output += buildSceneEnd(); + output += buildMaterials( materials, textures ); files[ modelFileName ] = fflate.strToU8( output ); @@ -170,6 +179,40 @@ function buildHeader() { } +function buildSceneStart( options ) { + + return `def Xform "Root" +{ + def Scope "Scenes" ( + kind = "sceneLibrary" + ) + { + def Xform "Scene" ( + customData = { + bool preliminary_collidesWithEnvironment = 0 + string sceneName = "Scene" + } + sceneName = "Scene" + ) + { + token preliminary:anchoring:type = "${options.ar.anchoring.type}" + token preliminary:planeAnchoring:alignment = "${options.ar.planeAnchoring.alignment}" + +`; + +} + +function buildSceneEnd() { + + return ` + } + } +} + +`; + +} + function buildUSDFileAsString( dataToInsert ) { let output = buildHeader(); @@ -555,4 +598,53 @@ function buildVector2( vector ) { } + +function buildCamera( camera ) { + + const name = camera.name ? camera.name : 'Camera_' + camera.id; + + const transform = buildMatrix( camera.matrixWorld ); + + if ( camera.matrixWorld.determinant() < 0 ) { + + console.warn( 'THREE.USDZExporter: USDZ does not support negative scales', camera ); + + } + + if ( camera.isOrthographicCamera ) { + + return `def Camera "${name}" + { + matrix4d xformOp:transform = ${ transform } + uniform token[] xformOpOrder = ["xformOp:transform"] + + float2 clippingRange = (${ camera.near.toPrecision( PRECISION ) }, ${ camera.far.toPrecision( PRECISION ) }) + float horizontalAperture = ${ ( ( Math.abs( camera.left ) + Math.abs( camera.right ) ) * 10 ).toPrecision( PRECISION ) } + float verticalAperture = ${ ( ( Math.abs( camera.top ) + Math.abs( camera.bottom ) ) * 10 ).toPrecision( PRECISION ) } + token projection = "orthographic" + } + + `; + + } else { + + return `def Camera "${name}" + { + matrix4d xformOp:transform = ${ transform } + uniform token[] xformOpOrder = ["xformOp:transform"] + + float2 clippingRange = (${ camera.near.toPrecision( PRECISION ) }, ${ camera.far.toPrecision( PRECISION ) }) + float focalLength = ${ camera.getFocalLength().toPrecision( PRECISION ) } + float focusDistance = ${ camera.focus.toPrecision( PRECISION ) } + float horizontalAperture = ${ camera.getFilmWidth().toPrecision( PRECISION ) } + token projection = "perspective" + float verticalAperture = ${ camera.getFilmHeight().toPrecision( PRECISION ) } + } + + `; + + } + +} + export { USDZExporter }; diff --git a/examples/jsm/geometries/ParametricGeometry.js b/examples/jsm/geometries/ParametricGeometry.js index 33166f8ec356bf..33ec014efa5fec 100644 --- a/examples/jsm/geometries/ParametricGeometry.js +++ b/examples/jsm/geometries/ParametricGeometry.js @@ -37,12 +37,6 @@ class ParametricGeometry extends BufferGeometry { const p0 = new Vector3(), p1 = new Vector3(); const pu = new Vector3(), pv = new Vector3(); - if ( func.length < 3 ) { - - console.error( 'THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter.' ); - - } - // generate vertices, normals and uvs const sliceCount = slices + 1; diff --git a/examples/jsm/helpers/OctreeHelper.js b/examples/jsm/helpers/OctreeHelper.js index 88c8bd8c61f127..95f597c10671ea 100644 --- a/examples/jsm/helpers/OctreeHelper.js +++ b/examples/jsm/helpers/OctreeHelper.js @@ -9,6 +9,19 @@ class OctreeHelper extends LineSegments { constructor( octree, color = 0xffff00 ) { + super( new BufferGeometry(), new LineBasicMaterial( { color: color, toneMapped: false } ) ); + + this.octree = octree; + this.color = color; + + this.type = 'OctreeHelper'; + + this.update(); + + } + + update() { + const vertices = []; function traverse( tree ) { @@ -39,20 +52,21 @@ class OctreeHelper extends LineSegments { } - traverse( octree.subTrees ); + traverse( this.octree.subTrees ); - const geometry = new BufferGeometry(); - geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.geometry.dispose(); - super( geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) ); + this.geometry = new BufferGeometry(); + this.geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.octree = octree; - this.color = color; + } - this.type = 'OctreeHelper'; + dispose() { - } + this.geometry.dispose(); + this.material.dispose(); + } } export { OctreeHelper }; diff --git a/examples/jsm/helpers/VertexNormalsHelper.js b/examples/jsm/helpers/VertexNormalsHelper.js index 033818378bf85a..bfe41aba8644d1 100644 --- a/examples/jsm/helpers/VertexNormalsHelper.js +++ b/examples/jsm/helpers/VertexNormalsHelper.js @@ -84,7 +84,13 @@ class VertexNormalsHelper extends LineSegments { } -} + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + } + +} export { VertexNormalsHelper }; diff --git a/examples/jsm/helpers/VertexTangentsHelper.js b/examples/jsm/helpers/VertexTangentsHelper.js index 1938d7ad0d73bd..1ad413f65e95c7 100644 --- a/examples/jsm/helpers/VertexTangentsHelper.js +++ b/examples/jsm/helpers/VertexTangentsHelper.js @@ -76,6 +76,13 @@ class VertexTangentsHelper extends LineSegments { } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + + } + } export { VertexTangentsHelper }; diff --git a/examples/jsm/helpers/ViewHelper.js b/examples/jsm/helpers/ViewHelper.js index c2cc90107bcda6..fc196396cf80d2 100644 --- a/examples/jsm/helpers/ViewHelper.js +++ b/examples/jsm/helpers/ViewHelper.js @@ -200,6 +200,30 @@ class ViewHelper extends THREE.Object3D { }; + this.dispose = function () { + + geometry.dispose(); + + xAxis.material.dispose(); + yAxis.material.dispose(); + zAxis.material.dispose(); + + posXAxisHelper.material.map.dispose(); + posYAxisHelper.material.map.dispose(); + posZAxisHelper.material.map.dispose(); + negXAxisHelper.material.map.dispose(); + negYAxisHelper.material.map.dispose(); + negZAxisHelper.material.map.dispose(); + + posXAxisHelper.material.dispose(); + posYAxisHelper.material.dispose(); + posZAxisHelper.material.dispose(); + negXAxisHelper.material.dispose(); + negYAxisHelper.material.dispose(); + negZAxisHelper.material.dispose(); + + }; + function prepareAnimationData( object, focusPoint ) { switch ( object.userData.type ) { diff --git a/examples/jsm/interactive/HTMLMesh.js b/examples/jsm/interactive/HTMLMesh.js index c67fdbd20b7d19..405419b01a2a78 100644 --- a/examples/jsm/interactive/HTMLMesh.js +++ b/examples/jsm/interactive/HTMLMesh.js @@ -36,6 +36,8 @@ class HTMLMesh extends Mesh { material.dispose(); material.map.dispose(); + + canvases.delete( dom ); this.removeEventListener( 'mousedown', onEvent ); this.removeEventListener( 'mousemove', onEvent ); @@ -469,17 +471,14 @@ function html2canvas( element ) { const offset = element.getBoundingClientRect(); - let canvas; + let canvas = canvases.get( element ); - if ( canvases.has( element ) ) { - - canvas = canvases.get( element ); - - } else { + if ( canvas === undefined ) { canvas = document.createElement( 'canvas' ); canvas.width = offset.width; canvas.height = offset.height; + canvases.set( element, canvas ); } diff --git a/examples/jsm/interactive/InteractiveGroup.js b/examples/jsm/interactive/InteractiveGroup.js index 6ae5b82f923ec6..443b007fd83e6b 100644 --- a/examples/jsm/interactive/InteractiveGroup.js +++ b/examples/jsm/interactive/InteractiveGroup.js @@ -27,8 +27,10 @@ class InteractiveGroup extends Group { event.stopPropagation(); - _pointer.x = ( event.clientX / element.clientWidth ) * 2 - 1; - _pointer.y = - ( event.clientY / element.clientHeight ) * 2 + 1; + const rect = renderer.domElement.getBoundingClientRect(); + + _pointer.x = ( event.clientX - rect.left ) / rect.width * 2 - 1; + _pointer.y = - ( event.clientY - rect.top ) / rect.height * 2 + 1; raycaster.setFromCamera( _pointer, camera ); diff --git a/examples/jsm/libs/flow.module.js b/examples/jsm/libs/flow.module.js index 34e3731c85117a..e3721ac6983266 100644 --- a/examples/jsm/libs/flow.module.js +++ b/examples/jsm/libs/flow.module.js @@ -16,7 +16,7 @@ function __flow__addCSS( css ) { } -__flow__addCSS( `@keyframes f-animation-open { 0% { transform: scale(.5); opacity: 0; } 100% { transform: scale(1); opacity: 1; }}f-canvas,f-canvas canvas { position: absolute; top: 0; left: 0; margin: 0; padding: 0; width: 100%; height: 100%; -webkit-touch-callout: none; }f-canvas { overflow: auto; cursor: grab;}f-canvas canvas.front { z-index: 10;}body.dragging *:not(.drag) { pointer-events: none !important;}f-canvas.grabbing * { cursor: grabbing; user-select: none;}f-canvas canvas { position: fixed; overflow: hidden; pointer-events: none;}f-canvas::-webkit-scrollbar { width: 8px; height: 8px;}f-canvas::-webkit-scrollbar-thumb:hover{ background: #014fc5;}f-canvas::-webkit-scrollbar-track { background: #363636;}f-canvas::-webkit-scrollbar-thumb { background-color: #666666; border-radius: 10px; border: 0;}f-canvas f-content,f-canvas f-area { position: absolute; display: block;}f-node { position: absolute; margin: 0; padding: 0; user-select: none; width: 320px; z-index: 1; cursor: auto; filter: drop-shadow(0 0 10px #00000061); backdrop-filter: blur(4px);}f-node.selected { z-index: 2;}f-node.selected,f-canvas.dragging-rio f-node:hover,f-canvas.dragging-lio f-node:hover { filter: drop-shadow(0 0 10px #00000061) drop-shadow(0 0 8px #4444dd);}f-node.closed f-element:not(:first-child) { display: none;}f-node.center { top: 50%; left: 50%; transform: translate( -50%, -50% );}f-node.top-right { top: 0; right: 0;}f-node.top-center { top: 0; left: 50%; transform: translateX( -50% );}f-node.top-left { top: 0; left: 0;}f-node { transition: filter 0.2s ease;}f-node { animation: .2s f-animation-open 1 alternate ease-out;}f-tips,f-drop,f-menu,f-menu input,f-menu button,f-element,f-element input,f-element select,f-element button,f-element textarea { font-family: 'Open Sans', sans-serif; font-size: 13px; text-transform: capitalize; color: #eeeeee; outline: solid 0px #000; margin: 0; padding: 0; border: 0; user-select: none; -webkit-tap-highlight-color: transparent; transition: background 0.2s ease, filter 0.2s ease;}f-element input:read-only { color: #666;}f-element input,f-element textarea { text-transform: initial;}f-element input { transition: background 0.1s ease;}f-element input,f-element select,f-element button,f-element textarea { background-color: #232324d1;}f-element { position: relative; width: calc( 100% - 14px ); background: rgba(45, 45, 48, 0.95); pointer-events: auto; border-bottom: 2px solid #232323; display: flex; padding-left: 7px; padding-right: 7px; padding-top: 2px; padding-bottom: 2px;}f-element:after,f-element:before { transition: opacity .17s; opacity: 0; content: '';}f-element[tooltip]:hover:after,f-element[tooltip]:focus-within:after { font-size: 14px !important; display: flex; justify-content: center; position: fixed; margin-left: -7px; width: calc( 100% ); background: #1d1d1de8; border: 1px solid #444444a1; border-radius: 6px; color: #dadada; content: attr( tooltip ); margin-top: -41px; font-size: 16px; padding-top: 3px; padding-bottom: 3px; z-index: 10; opacity: 1; backdrop-filter: blur(4px); white-space: nowrap; overflow: hidden; text-shadow: 1px 1px 0px #0007;}f-element[tooltip]:hover:before,f-element[tooltip]:focus-within:before { border: solid; border-color: #1d1d1de8 transparent; border-width: 12px 6px 0 6px; left: calc( 50% - 6px ); bottom: 30px; position: absolute; opacity: 1; z-index: 11;}f-element[error] { background-color: #ff0000;}f-element[error]:hover:after,f-element[error]:focus-within:after { border: none; background-color: #ff0000bb; filter: drop-shadow( 2px 2px 5px #000 ); color: #fff;}f-element[error]:hover:before,f-element[error]:focus-within:before { border-color: #ff0000bb transparent;}f-element { height: 24px;}f-element input { margin-top: 2px; margin-bottom: 2px; box-shadow: inset 0px 1px 1px rgb(0 0 0 / 20%), 0px 1px 0px rgb(255 255 255 / 5%); margin-left: 2px; margin-right: 2px; width: 100%; padding-left: 4px; padding-right: 4px;}f-element input.number { cursor: col-resize;}f-element input:focus[type='text'], f-element input:focus[type='range'], f-element input:focus[type='color'] { background: rgba( 0, 0, 0, 0.6 ); outline: solid 1px rgba( 0, 80, 200, 0.98 );}f-element input[type='color'] { appearance: none; padding: 0; margin-left: 2px; margin-right: 2px; height: calc( 100% - 4px ); margin-top: 2px; border: none;}f-element input[type='color']::-webkit-color-swatch-wrapper { padding: 2px;}f-element input[type='color']::-webkit-color-swatch { border: none; cursor: alias;}f-element input[type='range'] { appearance: none; width: 100%; overflow: hidden; padding: 0; cursor: ew-resize;}f-element input[type='range']::-webkit-slider-runnable-track { appearance: none; height: 10px; color: #13bba4; margin: 0;}f-element input[type='range']::-webkit-slider-thumb { appearance: none; width: 0; background: #434343; box-shadow: -500px 0 0 500px rgba( 0, 120, 255, 0.98 ); border-radius: 50%; border: 0 !important;}f-element input[type='range']::-webkit-slider-runnable-track { margin-left: -4px; margin-right: -5px;}f-element input[type='checkbox'] { appearance: none; cursor: pointer;}f-element input[type='checkbox'].toggle { height: 20px; width: 45px; border-radius: 16px; display: inline-block; position: relative; margin: 0; margin-top: 2px; background: linear-gradient( 0deg, #292929 0%, #0a0a0ac2 100% ); transition: all 0.2s ease;}f-element input[type='checkbox'].toggle:after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: white; box-shadow: 0 1px 2px rgba(44, 44, 44, 0.2); transition: all 0.2s cubic-bezier(0.5, 0.1, 0.75, 1.35);}f-element input[type='checkbox'].toggle:checked { background: linear-gradient( 0deg, #0177fb 0%, #0177fb 100% );}f-element input[type='checkbox'].toggle:checked:after { transform: translatex(25px);}f-element.auto-height { display: table;}f-element textarea { width: calc( 100% - 18px ); padding-top: 1px; padding-bottom: 3px; padding-left: 3px; padding-right: 8px; margin-top: 2px; margin-left: 2px; height: calc( 100% - 8px ); max-height: 300px; border-radius: 2px; resize: none; box-shadow: inset 0px 1px 1px rgb(0 0 0 / 20%), 0px 1px 0px rgb(255 255 255 / 5%);}f-element.auto-height textarea { resize: auto;}f-element select { width: 100%; margin-top: 2px; margin-bottom: 2px; margin-left: 2px; margin-right: 2px; cursor: pointer; box-shadow: inset 0px 1px 1px rgb(0 0 0 / 20%), 0px 1px 0px rgb(255 255 255 / 5%);}f-element f-toolbar { position: absolute; display: flex; top: 0; width: 100%; height: 100%; align-content: space-around;}f-element.input-right f-toolbar { right: 7px; float: right; justify-content: end;}f-element f-toolbar { margin-top: auto; margin-bottom: auto; margin-left: 3px; margin-right: 3px; font-size: 18px; line-height: 18px;}f-element f-toolbar button { opacity: .7; cursor: pointer; font-size: 14px; width: unset; height: unset; border-radius: unset; border: unset; outline: 0; background-color: unset; box-shadow: unset;}f-element f-toolbar button:hover,f-element f-toolbar button:active { opacity: 1; border: 0; background-color: unset;}f-element input.range-value { width: 60px; text-align: center;}f-menu.context button,f-element button { width: 100%; height: calc( 100% - 4px ); margin-left: 2px; margin-right: 2px; margin-top: 2px; border-radius: 3px; cursor: pointer;}f-element button { box-shadow: inset 1px 1px 1px 0 rgb(255 255 255 / 17%), inset -2px -2px 2px 0 rgb(0 0 0 / 26%);}f-element button:hover { color: #fff; background-color: #2a2a2a;}f-element button:active { border: 1px solid rgba( 0, 120, 255, 0.98 );}f-element f-inputs,f-element f-subinputs { display: flex; justify-content: flex-end; width: 100%;}f-element f-inputs { left: 100px; top: 50%; transform: translateY(-50%); position: absolute; width: calc( 100% - 106px ); height: calc( 100% - 4px ); z-index: 1;}f-element.inputs-disable f-inputs { filter: grayscale(100%); opacity: .5;}f-element.inputs-disable f-inputs input { pointer-events: none;}f-element f-label,f-element span { margin: auto; text-shadow: 1px 1px 0px #0007;}f-element f-label { padding-left: 4px; white-space: nowrap; position: absolute; top: 50%; transform: translateY(-50%); width: calc( 100% - 20px );}f-element.right f-label { text-align: right;}f-element.center f-label { text-align: center;}f-element f-label i { float: left; font-size: 18px; margin-right: 6px;}f-element f-label.center { width: 100%; text-align: center; display: block;}f-element.title { height: 29px; background-color: #3a3a3ab0; background-color: #3b3b43ed; cursor: all-scroll; border-top-left-radius: 6px; border-top-right-radius: 6px;}f-element.blue { background-color: #014fc5;}f-element.red { background-color: #bd0b0b;}f-element.green { background-color: #148d05;}f-element.yellow { background-color: #d6b100;}f-element.title.left { text-align: left; display: inline-grid; justify-content: start;}f-element.title span { text-align: center; font-size: 15px; padding-top: 2px;}f-element.title i { font-size: 18px; position: absolute; right: 10px; top: 50%; transform: translateY(-50%); opacity: .5;}f-element.title f-toolbar i { font-size: 20px; right: unset; left: 0px;}f-element.input-right.title i { left: 10px; right: unset;}f-element.title.left span { text-align: left;}f-element f-io { border: 2px solid #dadada; width: 7px; height: 7px; position: absolute; background: #242427; border-radius: 8px; float: left; left: -7px; top: calc( 50% - 5px ); cursor: alias; box-shadow: 0 0 3px 2px #0000005e; z-index: 1;}f-element f-io.connect,f-canvas.dragging-rio f-element:hover f-io.lio,f-canvas.dragging-lio f-element:hover f-io.rio { zoom: 1.4;}f-node.io-connect f-io:not(.connect) { border: 2px solid #dadada !important; zoom: 1 !important;}f-element f-io.rio { float: right; right: -7px; left: unset;}f-element f-disconnect { position: absolute; left: -35px; top: 50%; font-size: 22px; transform: translateY( -50% ); filter: drop-shadow(0 0 5px #000); text-shadow: 0px 0px 5px black; cursor: pointer; transition: all .2s;}f-element.input-right f-disconnect { right: -35px; left: unset;}f-element f-disconnect:hover { color: #ff3300;}f-element textarea::-webkit-scrollbar { width: 6px;}f-element textarea::-webkit-scrollbar-track { background: #111; } f-element textarea::-webkit-scrollbar-thumb { background: #0177fb; }f-element textarea::-webkit-scrollbar-thumb:hover { background: #1187ff; }f-element.small { height: 18px;}f-element.large { height: 36px;}body.connecting f-node:not(.io-connect) f-element:hover,f-element.select { background-color: rgba(61, 70, 82, 0.98);}f-element.invalid > f-io { zoom: 1 !important;}f-element.invalid::after { font-size: 14px !important; display: flex; justify-content: center; align-items:center; margin: auto; position: absolute; width: 100%; height: 100%; background: #bd0b0b77; vertical-align: middle; color: #fff; content: 'Not Compatible'; opacity: .95; backdrop-filter: grayscale(100%); white-space: nowrap; overflow: hidden; left: 0; top: 0; text-transform: initial;}f-element.invalid > f-inputs,f-element.invalid > f-label { opacity: .1;}f-drop { width: 100%; height: 100%; position: sticky; left: 0; top: 0; background: #02358417; text-align: center; justify-content: center; align-items: center; display: flex; box-shadow: inset 0 0 20px 10px #464ace17; pointer-events: none; transition: all .07s; opacity: 0; visibility: hidden;}f-drop.visible { visibility: unset; opacity: unset; transition: all .23s;}f-drop span { opacity: .5; font-size: 40px; text-shadow: 0px 0px 5px #000; font-weight: bold;}f-tooltip { pointer-events: none;}f-tooltip { position: absolute; left: 0; top: 0; background: rgba(0,0,0,.8); backdrop-filter: blur(4px); font-size: 14px; padding: 7px; left: 50%; border-radius: 10px; transform: translateX(-50%); visibility: hidden; pointer-events: none; opacity: 0; transition: all 0.3s ease; z-index: 150; white-space: nowrap;}f-menu.context,f-menu.search { position: absolute;}f-menu.context { width: 170px; z-index: 110;}f-menu.search { bottom: 85px; left: 50%; transform: translateX(-50%); z-index: 10; width: 300px;}f-menu.context f-list { display: block; margin: 0; background: #171717e6; font-size: 12px; border-radius: 6px; backdrop-filter: blur(6px); border: 1px solid #7e7e7e45; box-shadow: 3px 3px 6px rgba(0,0,0,.2); transition: opacity 0.2s ease, transform 0.1s ease;}f-menu.search f-list { margin: 0 6px 0 6px; display: flex; flex-direction: column-reverse; margin-bottom: 5px;}f-menu.context.hidden { visibility: hidden; opacity: 0;}f-menu.context f-item,f-menu.search f-item { display: block; position: relative; margin: 0; padding: 0; white-space: nowrap;}f-menu.search f-item { opacity: 0;}f-menu.context f-item.submenu::after { content: ""; position: absolute; right: 6px; top: 50%; -webkit-transform: translateY(-50%); transform: translateY(-50%); border: 5px solid transparent; border-left-color: #808080;}f-menu.context f-item:hover > f-menu,f-menu.context f-item.active > f-menu { visibility: unset; transform: unset; opacity: unset;}f-menu.context f-menu { top: 0px; left: calc( 100% - 4px );}f-menu.context f-item button,f-menu.search f-item button { overflow: visible; display: block; width: calc( 100% - 6px ); text-align: left; cursor: pointer; white-space: nowrap; padding: 6px 8px; border-radius: 3px; background: rgba(45, 45, 48, 0.95); border: 0; color: #ddd; margin: 3px; text-shadow: 1px 1px 0px #0007;}f-menu.context f-item button i,f-menu.search f-item button i { float: left; font-size: 16px;}f-menu.context f-item button span,f-menu.search f-item button span { margin-left: 6px;}f-menu.context f-item:hover > button,f-menu.search f-item:hover > button,f-menu.search f-item.active > button { color: #fff; background-color: rgba(61, 70, 82, 0.98);}f-menu.search f-item:hover,f-menu.search f-item.active { opacity: 1 !important;}f-menu.context f-item button:active { outline: solid 1px rgba( 0, 80, 200, 0.98 );}f-menu.context f-item f-tooltip { margin-left: 85px; top: -50px;}f-menu.search f-item { display: none;}f-menu.search f-item:nth-child(1) { opacity: 1; display: unset;}f-menu.search f-item:nth-child(2) { opacity: .8; display: unset;}f-menu.search f-item:nth-child(3) { opacity: .6; display: unset;}f-menu.search f-item:nth-child(4) { opacity: .4; display: unset;}f-menu.search f-item button { border-radius: 14px;}f-tips { right: 10px; top: 10px; position: absolute; z-index: 100; pointer-events: none; display: flex; flex-direction: column;}f-tips f-tip { width: 450px; font-size: 13px; border-radius: 6px; text-align: center; display: block; height: auto; color: #ffffffe0; margin: 4px; padding: 4px; background: #17171794; border: 1px solid #7e7e7e38; line-height: 100%; backdrop-filter: blur(6px); transition: all 0.2s ease; text-transform: initial; opacity: 0;}f-tips f-tip:nth-child(1) { opacity: 1;}f-tips f-tip:nth-child(2) { opacity: .75;}f-tips f-tip:nth-child(3) { opacity: .25;}f-tips f-tip:nth-child(4) { opacity: .1;}f-tips f-tip.error { background: #b900005e;}f-menu.search input { width: calc( 100% - 28px ); height: 41px; position: absolute; z-index: 10; border-radius: 20px; padding-left: 14px; padding-right: 14px; font-size: 15px; background-color: #17171794; border: 1px solid #7e7e7e45; backdrop-filter: blur(6px); box-shadow: 3px 3px 6px rgb(0 0 0 / 20%); text-transform: initial;}f-menu.circle { position: absolute; left: 40px; bottom: 40px; z-index: 100;}f-menu.circle f-item { align-content: space-around; margin-right: 20px;}f-menu.circle f-item button { width: 47px; height: 47px; font-size: 22px; background: #17171794; border-radius: 50%; backdrop-filter: blur(6px); border: 1px solid #7e7e7e45; line-height: 100%; cursor: pointer; box-shadow: 3px 3px 6px rgba(0,0,0,.2);}f-menu.circle f-item f-tooltip { margin-top: -60px;}.f-rounded f-node f-element,.f-rounded f-node f-element.title.left { border-radius: 10px 5px 10px 5px;}.f-rounded f-node f-element input, .f-rounded f-node f-element select,.f-rounded f-node f-element button,.f-rounded f-node f-element textarea,.f-rounded f-node f-element input[type='checkbox'].toggle,.f-rounded f-node f-element input[type='checkbox'].toggle:after { border-radius: 20px 10px;}.f-rounded f-node f-element input { padding-left: 7px; padding-right: 7px;}.f-rounded f-menu.context,.f-rounded f-menu.context f-item button { border-radius: 20px 10px;}@media (hover: hover) and (pointer: fine) { f-node:not(.selected):hover { filter: drop-shadow(0 0 6px #66666630); } f-element f-toolbar { visibility: hidden; opacity: 0; transition: opacity 0.2s ease; } f-node:hover > f-element f-toolbar { visibility: visible; opacity: 1; } f-element f-io:hover { zoom: 1.4; } f-menu.circle f-item button:hover { background-color: #2a2a2a; } f-menu.search input:hover, f-menu.search input:focus { background-color: #1a1a1a; filter: drop-shadow(0 0 6px #66666630); } f-menu.search input:focus { filter: drop-shadow(0 0 8px #4444dd); } f-menu.circle f-item button:hover > f-tooltip, f-menu.context f-item button:hover > f-tooltip { visibility: visible; opacity: 1; } f-menu.circle f-item button:hover > f-tooltip { margin-top: -50px; } f-menu.context f-item button:hover > f-tooltip { top: -30px; } f-menu.circle f-item button:focus > f-tooltip, f-menu.context f-item button:focus > f-tooltip { visibility: hidden; opacity: 0; }}@media (hover: none) and (pointer: coarse) { body.dragging f-canvas, body.connecting f-canvas { overflow: hidden !important; }}f-canvas { will-change: top, left;}f-node { will-change: transform !important;}` ); +__flow__addCSS( `@keyframes f-animation-open { 0% { transform: scale(.5); opacity: 0; } 100% { transform: scale(1); opacity: 1; }}f-canvas,f-canvas canvas.background,f-canvas canvas.frontground { position: absolute; top: 0; left: 0; margin: 0; padding: 0; width: 100%; height: 100%; -webkit-touch-callout: none; transition: opacity .17s;}f-canvas { cursor: grab;}f-canvas canvas.frontground { z-index: 10;}body.dragging *:not(.drag) { pointer-events: none !important;}f-canvas.grabbing * { cursor: grabbing; user-select: none;}f-canvas canvas.background,f-canvas canvas.frontground { position: fixed; overflow: hidden;}f-canvas canvas.frontground { pointer-events: none;}f-canvas::-webkit-scrollbar { width: 8px; height: 8px;}f-canvas::-webkit-scrollbar-thumb:hover{ background: #014fc5;}f-canvas::-webkit-scrollbar-track { background: #363636;}f-canvas::-webkit-scrollbar-thumb { background-color: #666666; border-radius: 10px; border: 0;}f-canvas f-content { left: 0; top: 0;}f-canvas f-content,f-canvas f-area { position: absolute; display: block;}f-canvas canvas.map { position: absolute; top: 10px; right: 10px; z-index: 50; backdrop-filter: blur( 10px ); background-color: rgba( 45, 45, 48, .8 );}f-node { position: absolute; margin: 0; padding: 0; user-select: none; width: 320px; z-index: 1; cursor: auto; filter: drop-shadow(0 0 10px #00000061); backdrop-filter: blur(4px);}f-node.selected { z-index: 2;}f-canvas.focusing canvas.background,f-canvas.focusing f-node:not(.selected),f-canvas.focusing f-element f-disconnect:not(.selected) { opacity: 0; pointer-events: none;}.dragging f-canvas f-element f-disconnect { opacity: 0;}.dragging.node f-canvas.focusing canvas.background,.dragging.node f-canvas.focusing f-node:not(.selected) { opacity: .5;}f-node.selected,f-canvas.dragging-rio f-node:hover,f-canvas.dragging-lio f-node:hover { filter: drop-shadow(0 0 10px #00000061) drop-shadow(0 0 8px #4444dd);}f-node.closed f-element:not(:first-child) { display: none;}f-node.center { top: 50%; left: 50%; transform: translate( -50%, -50% );}f-node.top-right { top: 0; right: 0;}f-node.top-center { top: 0; left: 50%; transform: translateX( -50% );}f-node.top-left { top: 0; left: 0;}f-node { transition: filter 0.2s ease, opacity 0.12s ease;}f-node { animation: .2s f-animation-open 1 alternate ease-out;}f-tips,f-drop,f-menu,f-menu input,f-menu button,f-element,f-element input,f-element select,f-element button,f-element textarea { font-family: 'Open Sans', sans-serif; font-size: 13px; text-transform: capitalize; color: #eeeeee; outline: solid 0px #000; margin: 0; padding: 0; border: 0; user-select: none; -webkit-tap-highlight-color: transparent; transition: background 0.2s ease, filter 0.2s ease;}f-element input:read-only { color: #666;}f-element input,f-element textarea { text-transform: initial;}f-element input { transition: background 0.1s ease;}f-element input,f-element select,f-element button,f-element textarea { background-color: #232324d1;}f-element { position: relative; width: calc( 100% - 14px ); background: rgba(45, 45, 48, 0.95); pointer-events: auto; border-bottom: 2px solid #232323; display: flex; padding-left: 7px; padding-right: 7px; padding-top: 2px; padding-bottom: 2px;}f-element:after,f-element:before { transition: opacity .17s; opacity: 0; content: '';}f-element[tooltip]:hover:after,f-element[tooltip]:focus-within:after { font-size: 14px !important; display: flex; justify-content: center; position: fixed; margin-left: -7px; width: calc( 100% ); background: #1d1d1de8; border: 1px solid #444444a1; border-radius: 6px; color: #dadada; content: attr( tooltip ); margin-top: -41px; font-size: 16px; padding-top: 3px; padding-bottom: 3px; z-index: 10; opacity: 1; backdrop-filter: blur(4px); white-space: nowrap; overflow: hidden; text-shadow: 1px 1px 0px #0007;}f-element[tooltip]:hover:before,f-element[tooltip]:focus-within:before { border: solid; border-color: #1d1d1de8 transparent; border-width: 12px 6px 0 6px; left: calc( 50% - 6px ); bottom: 30px; position: absolute; opacity: 1; z-index: 11;}f-element[error] { background-color: #ff0000;}f-element[error]:hover:after,f-element[error]:focus-within:after { border: none; background-color: #ff0000bb; filter: drop-shadow( 2px 2px 5px #000 ); color: #fff;}f-element[error]:hover:before,f-element[error]:focus-within:before { border-color: #ff0000bb transparent;}f-element { height: 24px;}f-element input { margin-top: 2px; margin-bottom: 2px; box-shadow: inset 0px 1px 1px rgb(0 0 0 / 20%), 0px 1px 0px rgb(255 255 255 / 5%); margin-left: 2px; margin-right: 2px; width: 100%; padding-left: 4px; padding-right: 4px;}f-element input.number { cursor: col-resize;}f-element input:focus[type='text'], f-element input:focus[type='range'], f-element input:focus[type='color'] { background: rgba( 0, 0, 0, 0.6 ); outline: solid 1px rgba( 0, 80, 200, 0.98 );}f-element input[type='color'] { appearance: none; padding: 0; margin-left: 2px; margin-right: 2px; height: calc( 100% - 4px ); margin-top: 2px; border: none;}f-element input[type='color']::-webkit-color-swatch-wrapper { padding: 2px;}f-element input[type='color']::-webkit-color-swatch { border: none; cursor: alias;}f-element input[type='range'] { appearance: none; width: 100%; overflow: hidden; padding: 0; cursor: ew-resize;}f-element input[type='range']::-webkit-slider-runnable-track { appearance: none; height: 10px; color: #13bba4; margin: 0;}f-element input[type='range']::-webkit-slider-thumb { appearance: none; width: 0; background: #434343; box-shadow: -500px 0 0 500px rgba( 0, 120, 255, 0.98 ); border-radius: 50%; border: 0 !important;}f-element input[type='range']::-webkit-slider-runnable-track { margin-left: -4px; margin-right: -5px;}f-element input[type='checkbox'] { appearance: none; cursor: pointer;}f-element input[type='checkbox'].toggle { height: 20px; width: 45px; border-radius: 16px; display: inline-block; position: relative; margin: 0; margin-top: 2px; background: linear-gradient( 0deg, #292929 0%, #0a0a0ac2 100% ); transition: all 0.2s ease;}f-element input[type='checkbox'].toggle:after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: white; box-shadow: 0 1px 2px rgba(44, 44, 44, 0.2); transition: all 0.2s cubic-bezier(0.5, 0.1, 0.75, 1.35);}f-element input[type='checkbox'].toggle:checked { background: linear-gradient( 0deg, #0177fb 0%, #0177fb 100% );}f-element input[type='checkbox'].toggle:checked:after { transform: translatex(25px);}f-element.auto-height { display: table;}f-element textarea { width: calc( 100% - 18px ); padding-top: 1px; padding-bottom: 3px; padding-left: 3px; padding-right: 8px; margin-top: 2px; margin-left: 2px; height: calc( 100% - 8px ); max-height: 300px; border-radius: 2px; resize: none; box-shadow: inset 0px 1px 1px rgb(0 0 0 / 20%), 0px 1px 0px rgb(255 255 255 / 5%);}f-element.auto-height textarea { resize: auto;}f-element select { width: 100%; margin-top: 2px; margin-bottom: 2px; margin-left: 2px; margin-right: 2px; cursor: pointer; box-shadow: inset 0px 1px 1px rgb(0 0 0 / 20%), 0px 1px 0px rgb(255 255 255 / 5%);}f-element f-toolbar { position: absolute; display: flex; top: 0; width: 100%; height: 100%; align-content: space-around;}f-element.input-right f-toolbar { right: 7px; float: right; justify-content: end;}f-element f-toolbar { margin-top: auto; margin-bottom: auto; margin-left: 3px; margin-right: 3px; font-size: 18px; line-height: 18px;}f-element f-toolbar button { opacity: .7; cursor: pointer; font-size: 14px; width: unset; height: unset; border-radius: unset; border: unset; outline: 0; background-color: unset; box-shadow: unset;}f-element f-toolbar button:hover,f-element f-toolbar button:active { opacity: 1; border: 0; background-color: unset;}f-element input.range-value { width: 60px; text-align: center;}f-menu.context button,f-element button { width: 100%; height: calc( 100% - 4px ); margin-left: 2px; margin-right: 2px; margin-top: 2px; border-radius: 3px; cursor: pointer;}f-element button { box-shadow: inset 1px 1px 1px 0 rgb(255 255 255 / 17%), inset -2px -2px 2px 0 rgb(0 0 0 / 26%);}f-element button:hover { color: #fff; background-color: #2a2a2a;}f-element button:active { border: 1px solid rgba( 0, 120, 255, 0.98 );}f-element f-inputs,f-element f-subinputs { display: flex; justify-content: flex-end; width: 100%;}f-element f-inputs { left: 100px; top: 50%; transform: translateY( -50% ); position: absolute; width: calc( 100% - 106px ); height: calc( 100% - 4px ); z-index: 1;}f-element.inputs-disable f-inputs { filter: grayscale(100%); opacity: .5;}f-element.inputs-disable f-inputs input { pointer-events: none;}f-element f-label,f-element span { margin: auto; text-shadow: 1px 1px 0px #0007;}f-element f-label { padding-left: 4px; white-space: nowrap; position: absolute; top: 50%; transform: translateY( -50% ); width: calc( 100% - 20px );}f-element.right f-label { text-align: right;}f-element.center f-label { text-align: center;}f-element f-label i { font-size: 18px; margin-right: 6px; vertical-align: sub;}f-element f-label.center { width: 100%; text-align: center; display: block;}f-element.title { height: 29px; background-color: #3a3a3ab0; background-color: #3b3b43ed; cursor: all-scroll; border-top-left-radius: 6px; border-top-right-radius: 6px;}f-element.blue { background-color: #014fc5;}f-element.red { background-color: #bd0b0b;}f-element.green { background-color: #148d05;}f-element.yellow { background-color: #d6b100;}f-element.title.left { text-align: left; display: inline-grid; justify-content: start;}f-element.title f-title { text-align: center; font-size: 15px; padding-top: 2px; position: absolute; top: 50%; transform: translateY( -50% ); width: 100%;}f-element.title i { font-size: 18px; position: absolute; right: 10px; top: 50%; transform: translateY( -50% ); opacity: .5;}f-element.title f-toolbar i { font-size: 20px; right: unset; left: 0px;}f-element.input-right.title i { left: 10px; right: unset;}f-element.title.left span { text-align: left;}f-element f-io { border: 2px solid #dadada; width: 7px; height: 7px; position: absolute; background: #242427; border-radius: 8px; float: left; left: -7px; top: calc( 50% - 5px ); cursor: alias; box-shadow: 0 0 3px 2px #0000005e; z-index: 1;}f-element f-io.connect,f-canvas.dragging-rio f-element:hover f-io.lio,f-canvas.dragging-lio f-element:hover f-io.rio { zoom: 1.4;}f-node.io-connect f-io:not(.connect) { border: 2px solid #dadada !important; zoom: 1 !important;}f-element f-io.rio { float: right; right: -7px; left: unset;}f-element f-disconnect { position: absolute; left: -35px; top: 50%; font-size: 22px; transform: translateY( -50% ); filter: drop-shadow(0 0 5px #000); text-shadow: 0px 0px 5px black; cursor: pointer; transition: all .2s;}f-element.input-right f-disconnect { right: -35px; left: unset;}f-element f-disconnect:hover { color: #ff3300;}f-element textarea::-webkit-scrollbar { width: 6px;}f-element textarea::-webkit-scrollbar-track { background: #111; } f-element textarea::-webkit-scrollbar-thumb { background: #0177fb; }f-element textarea::-webkit-scrollbar-thumb:hover { background: #1187ff; }f-element.small { height: 18px;}f-element.large { height: 36px;}f-canvas.dragging-lio f-node:not(.io-connect) f-element.rio:hover,f-canvas.dragging-rio f-node:not(.io-connect) f-element.lio:hover,f-element.select { background-color: rgba(61, 70, 82, 0.98);}f-element.invalid > f-io { zoom: 1 !important;}f-element.invalid::after { font-size: 14px !important; display: flex; justify-content: center; align-items:center; margin: auto; position: absolute; width: 100%; height: 100%; background: #bd0b0b77; vertical-align: middle; color: #fff; content: 'Not Compatible'; opacity: .95; backdrop-filter: grayscale(100%); white-space: nowrap; overflow: hidden; left: 0; top: 0; text-transform: initial;}f-drop { width: 100%; height: 100%; position: sticky; left: 0; top: 0; background: #02358417; text-align: center; justify-content: center; align-items: center; display: flex; box-shadow: inset 0 0 20px 10px #464ace17; pointer-events: none; transition: all .07s; opacity: 0; visibility: hidden;}f-drop.visible { visibility: unset; opacity: unset; transition: all .23s;}f-drop span { opacity: .5; font-size: 40px; text-shadow: 0px 0px 5px #000; font-weight: bold;}f-tooltip { pointer-events: none;}f-tooltip { position: absolute; left: 0; top: 0; background: rgba(0,0,0,.8); backdrop-filter: blur(4px); font-size: 14px; padding: 7px; left: 50%; border-radius: 10px; transform: translateX(-50%); visibility: hidden; pointer-events: none; opacity: 0; transition: all 0.3s ease; z-index: 150; white-space: nowrap;}f-menu.context,f-menu.search { position: absolute;}f-menu.context { width: 170px; z-index: 110;}f-menu.search { bottom: 85px; left: 50%; transform: translateX(-50%); z-index: 10; width: 300px;}f-menu.context f-list { display: block; margin: 0; background: #171717e6; font-size: 12px; border-radius: 6px; backdrop-filter: blur(6px); border: 1px solid #7e7e7e45; box-shadow: 3px 3px 6px rgba(0,0,0,.2); transition: opacity 0.2s ease, transform 0.1s ease;}f-menu.search f-list { margin: 0 6px 0 6px; display: flex; flex-direction: column-reverse; margin-bottom: 5px;}f-menu.context.hidden { visibility: hidden; opacity: 0;}f-menu.context f-item,f-menu.search f-item { display: block; position: relative; margin: 0; padding: 0; white-space: nowrap;}f-menu.search f-item { opacity: 0;}f-menu.context f-item.submenu::after { content: ""; position: absolute; right: 6px; top: 50%; -webkit-transform: translateY( -50% ); transform: translateY( -50% ); border: 5px solid transparent; border-left-color: #808080;}f-menu.context f-item:hover > f-menu,f-menu.context f-item.active > f-menu { visibility: unset; transform: unset; opacity: unset;}f-menu.context f-menu { top: 0px; left: calc( 100% - 4px );}f-menu.context f-item button,f-menu.search f-item button { overflow: visible; display: block; width: calc( 100% - 6px ); text-align: left; cursor: pointer; white-space: nowrap; padding: 6px 8px; border-radius: 3px; background: rgba(45, 45, 48, 0.95); border: 0; color: #ddd; margin: 3px; text-shadow: 1px 1px 0px #0007;}f-menu.context f-item button i,f-menu.search f-item button i { float: left; font-size: 16px;}f-menu.context f-item button span,f-menu.search f-item button span { margin-left: 6px;}f-menu.context f-item:hover > button,f-menu.search f-item:hover > button,f-menu.search f-item.active > button { color: #fff; background-color: rgba(61, 70, 82, 0.98);}f-menu.search f-item:hover,f-menu.search f-item.active { opacity: 1 !important;}f-menu.context f-item button:active { outline: solid 1px rgba( 0, 80, 200, 0.98 );}f-menu.context f-item f-tooltip { margin-left: 85px; top: -50px;}f-menu.search f-item { display: none;}f-menu.search f-item:nth-child(1) { opacity: 1; display: unset;}f-menu.search f-item:nth-child(2) { opacity: .8; display: unset;}f-menu.search f-item:nth-child(3) { opacity: .6; display: unset;}f-menu.search f-item:nth-child(4) { opacity: .4; display: unset;}f-menu.search f-item button { border-radius: 14px;}f-tips { right: 10px; top: 10px; position: absolute; z-index: 100; pointer-events: none; display: flex; flex-direction: column;}f-tips f-tip { width: 450px; font-size: 13px; border-radius: 6px; text-align: center; display: block; height: auto; color: #ffffffe0; margin: 4px; padding: 4px; background: #17171794; border: 1px solid #7e7e7e38; line-height: 100%; backdrop-filter: blur(6px); transition: all 0.2s ease; text-transform: initial; opacity: 0;}f-tips f-tip:nth-child(1) { opacity: 1;}f-tips f-tip:nth-child(2) { opacity: .75;}f-tips f-tip:nth-child(3) { opacity: .25;}f-tips f-tip:nth-child(4) { opacity: .1;}f-tips f-tip.error { background: #b900005e;}f-menu.search input { width: calc( 100% - 28px ); height: 41px; position: absolute; z-index: 10; border-radius: 20px; padding-left: 14px; padding-right: 14px; font-size: 15px; background-color: #17171794; border: 1px solid #7e7e7e45; backdrop-filter: blur(6px); box-shadow: 3px 3px 6px rgb(0 0 0 / 20%); text-transform: initial;}f-menu.circle { position: absolute; z-index: 100;}f-menu.circle.top { top: 40px;}f-menu.circle.left { left: 40px;}f-menu.circle.bottom { bottom: 40px;}f-menu.circle.right { right: 40px;}f-menu.circle f-item { align-content: space-around; margin-right: 20px;}f-menu.circle f-item button { width: 47px; height: 47px; font-size: 22px; background: #17171794; border-radius: 50%; backdrop-filter: blur(6px); border: 1px solid #7e7e7e45; line-height: 100%; cursor: pointer; box-shadow: 3px 3px 6px rgba(0,0,0,.2);}f-menu.circle f-item f-tooltip { margin-top: -60px;}f-menu.circle.top f-item f-tooltip { margin-top: 50px;}.f-rounded f-node f-element,.f-rounded f-node f-element.title.left { border-radius: 10px 5px 10px 5px;}.f-rounded f-node f-element input, .f-rounded f-node f-element select,.f-rounded f-node f-element button,.f-rounded f-node f-element textarea,.f-rounded f-node f-element input[type='checkbox'].toggle,.f-rounded f-node f-element input[type='checkbox'].toggle:after { border-radius: 20px 10px;}.f-rounded f-node f-element input { padding-left: 7px; padding-right: 7px;}.f-rounded f-menu.context,.f-rounded f-menu.context f-item button { border-radius: 20px 10px;}@media (hover: hover) and (pointer: fine) { f-node:not(.selected):hover { filter: drop-shadow(0 0 6px #66666630); } f-element f-toolbar { visibility: hidden; opacity: 0; transition: opacity 0.2s ease; } body:not(.connecting) f-node:hover > f-element f-toolbar { visibility: visible; opacity: 1; } f-element f-io:hover { zoom: 1.4; } f-menu.circle f-item button:hover { background-color: #2a2a2a; } f-menu.search input:hover, f-menu.search input:focus { background-color: #1a1a1a; filter: drop-shadow(0 0 6px #66666630); } f-menu.search input:focus { filter: drop-shadow(0 0 8px #4444dd); } f-menu.circle f-item button:hover > f-tooltip, f-menu.context f-item button:hover > f-tooltip { visibility: visible; opacity: 1; } f-menu.circle f-item button:hover > f-tooltip { margin-top: -50px; } f-menu.circle.top f-item button:hover > f-tooltip { margin-top: 60px; } f-menu.context f-item button:hover > f-tooltip { top: -30px; } f-menu.circle f-item button:focus > f-tooltip, f-menu.context f-item button:focus > f-tooltip { visibility: hidden; opacity: 0; }}@media (hover: none) and (pointer: coarse) { body.dragging f-canvas, body.connecting f-canvas { overflow: hidden !important; }}f-element.invalid > f-inputs,f-element.invalid > f-label,f-element.invalid > f-title,f-element.invalid > f-toolbar,f-element.invalid > input,f-element.invalid > select { opacity: .1 !important;}f-canvas { will-change: top, left;}f-node { will-change: transform !important;}` ); const REVISION = '1'; @@ -127,8 +127,8 @@ class PointerMonitor { const event = e.touches ? e.touches[ 0 ] : e; - this.x = event.x; - this.y = event.y; + this.x = event.clientX; + this.y = event.clientY; }; @@ -158,10 +158,18 @@ class PointerMonitor { const pointer = new PointerMonitor().start(); -const draggableDOM = ( dom, callback = null, className = 'dragging' ) => { +const draggableDOM = ( dom, callback = null, settings = {} ) => { + + settings = Object.assign( { + className: 'dragging', + click: false, + bypass: false + }, settings ); let dragData = null; + const { className, click, bypass } = settings; + const getZoom = () => { let zoomDOM = dom; @@ -188,16 +196,26 @@ const draggableDOM = ( dom, callback = null, className = 'dragging' ) => { const event = e.touches ? e.touches[ 0 ] : e; - e.stopImmediatePropagation(); + if ( bypass === false ) e.stopImmediatePropagation(); dragData = { client: { x: event.clientX, y: event.clientY }, delta: { x: 0, y: 0 }, start: { x: dom.offsetLeft, y: dom.offsetTop }, + frame: 0, + isDown: true, dragging: false, isTouch: !! e.touches }; + if ( click === true ) { + + callback( dragData ); + + dragData.frame ++; + + } + window.addEventListener( 'mousemove', onGlobalMouseMove ); window.addEventListener( 'mouseup', onGlobalMouseUp ); @@ -226,13 +244,15 @@ const draggableDOM = ( dom, callback = null, className = 'dragging' ) => { callback( dragData ); + dragData.frame ++; + } else { dom.style.cssText += `; left: ${ dragData.x }px; top: ${ dragData.y }px;`; } - e.stopImmediatePropagation(); + if ( bypass === false ) e.stopImmediatePropagation(); } else { @@ -242,9 +262,9 @@ const draggableDOM = ( dom, callback = null, className = 'dragging' ) => { dom.classList.add( 'drag' ); - if ( className ) document.body.classList.add( className ); + if ( className ) document.body.classList.add( ...className.split( ' ' ) ); - e.stopImmediatePropagation(); + if ( bypass === false ) e.stopImmediatePropagation(); } @@ -254,11 +274,11 @@ const draggableDOM = ( dom, callback = null, className = 'dragging' ) => { const onGlobalMouseUp = ( e ) => { - e.stopImmediatePropagation(); + if ( bypass === false ) e.stopImmediatePropagation(); dom.classList.remove( 'drag' ); - if ( className ) document.body.classList.remove( className ); + if ( className ) document.body.classList.remove( ...className.split( ' ' ) ); window.removeEventListener( 'mousemove', onGlobalMouseMove ); window.removeEventListener( 'mouseup', onGlobalMouseUp ); @@ -274,11 +294,14 @@ const draggableDOM = ( dom, callback = null, className = 'dragging' ) => { } dragData.dragging = false; + dragData.isDown = false; if ( callback !== null ) { callback( dragData ); + dragData.frame ++; + } }; @@ -315,7 +338,7 @@ const dispatchEventList = ( list, ...params ) => { }; -const toPX = ( val ) => { +const numberToPX = ( val ) => { if ( isNaN( val ) === false ) { @@ -327,7 +350,7 @@ const toPX = ( val ) => { }; -const toHex = ( val ) => { +const numberToHex = ( val ) => { if ( isNaN( val ) === false ) { @@ -339,14 +362,39 @@ const toHex = ( val ) => { }; -var Utils = /*#__PURE__*/Object.freeze( { +const rgbaToArray = ( rgba ) => { + + const values = rgba.substring( rgba.indexOf( '(' ) + 1, rgba.indexOf( ')' ) ) + .split( ',' ) + .map( num => parseInt( num.trim() ) ); + + return values; + +}; + +const removeDOMClass = ( dom, classList ) => { + + if ( classList ) classList.split( ' ' ).forEach( alignClass => dom.classList.remove( alignClass ) ); + +}; + +const addDOMClass = ( dom, classList ) => { + + if ( classList ) classList.split( ' ' ).forEach( alignClass => dom.classList.add( alignClass ) ); + +}; + +var Utils = /*#__PURE__*/Object.freeze({ __proto__: null, pointer: pointer, draggableDOM: draggableDOM, dispatchEventList: dispatchEventList, - toPX: toPX, - toHex: toHex -} ); + numberToPX: numberToPX, + numberToHex: numberToHex, + rgbaToArray: rgbaToArray, + removeDOMClass: removeDOMClass, + addDOMClass: addDOMClass +}); class Link { @@ -398,8 +446,6 @@ class Element extends Serializer { super(); - this.isElement = true; - const dom = document.createElement( 'f-element' ); dom.element = this; @@ -471,7 +517,9 @@ class Element extends Serializer { this.node = null; this.style = ''; + this.color = null; + this.object = null; this.objectCallback = null; this.enabledInputs = true; @@ -487,9 +535,6 @@ class Element extends Serializer { this.dom.classList.add( `input-${ Link.InputDirection }` ); - this.dom.append( this.lioDOM ); - this.dom.append( this.rioDOM ); - this.addEventListener( 'connect', ( ) => { dispatchEventList( this.events.connect, this ); @@ -542,9 +587,17 @@ class Element extends Serializer { } + setObject( value ) { + + this.object = value; + + return this; + + } + getObject( output = null ) { - return this.objectCallback ? this.objectCallback( output ) : null; + return this.objectCallback ? this.objectCallback( output ) : this.object; } @@ -586,12 +639,27 @@ class Element extends Serializer { setColor( color ) { - this.dom.style[ 'background-color' ] = toHex( color ); + this.dom.style[ 'background-color' ] = numberToHex( color ); + this.color = null; return this; } + getColor() { + + if ( this.color === null ) { + + const css = window.getComputedStyle( this.dom ); + + this.color = css.getPropertyValue( 'background-color' ); + + } + + return this.color; + + } + setStyle( style ) { const dom = this.dom; @@ -601,6 +669,7 @@ class Element extends Serializer { if ( style ) dom.classList.add( style ); this.style = style; + this.color = null; return this; @@ -692,7 +761,7 @@ class Element extends Serializer { setLIOColor( color ) { - this.lioDOM.style[ 'border-color' ] = toHex( color ); + this.lioDOM.style[ 'border-color' ] = numberToHex( color ); return this; @@ -704,6 +773,18 @@ class Element extends Serializer { this.lioDOM.style.visibility = length > 0 ? '' : 'hidden'; + if ( length > 0 ) { + + this.dom.classList.add( 'lio' ); + this.dom.prepend( this.lioDOM ); + + } else { + + this.dom.classList.remove( 'lio' ); + this.lioDOM.remove(); + + } + return this; } @@ -716,7 +797,7 @@ class Element extends Serializer { setRIOColor( color ) { - this.rioDOM.style[ 'border-color' ] = toHex( color ); + this.rioDOM.style[ 'border-color' ] = numberToHex( color ); return this; @@ -734,6 +815,18 @@ class Element extends Serializer { this.rioDOM.style.visibility = length > 0 ? '' : 'hidden'; + if ( length > 0 ) { + + this.dom.classList.add( 'rio' ); + this.dom.prepend( this.rioDOM ); + + } else { + + this.dom.classList.remove( 'rio' ); + this.rioDOM.remove(); + + } + return this; } @@ -752,7 +845,7 @@ class Element extends Serializer { setHeight( val ) { - this.dom.style.height = toPX( val ); + this.dom.style.height = numberToPX( val ); return this; @@ -776,6 +869,8 @@ class Element extends Serializer { if ( element !== null ) { + element = element.baseElement || element; + if ( dispatchEventList( this.events.valid, this, element, 'connect' ) === false ) { return false; @@ -1085,7 +1180,7 @@ class Element extends Serializer { } - }, 'connecting' ); + }, { className: 'connecting' } ); }; @@ -1098,14 +1193,14 @@ class Element extends Serializer { } +Element.prototype.isElement = true; + class Input extends Serializer { constructor( dom ) { super(); - this.isInput = true; - this.dom = dom; this.element = null; @@ -1234,14 +1329,14 @@ class Input extends Serializer { } +Input.prototype.isInput = true; + class Node extends Serializer { constructor() { super(); - this.isNode = true; - const dom = document.createElement( 'f-node' ); const onDown = () => { @@ -1308,6 +1403,12 @@ class Node extends Serializer { } + get baseElement() { + + return this.elements[ 0 ]; + + } + onFocus( callback ) { this.events.focus.push( callback ); @@ -1342,8 +1443,8 @@ class Node extends Serializer { const dom = this.dom; - dom.style.left = toPX( x ); - dom.style.top = toPX( y ); + dom.style.left = numberToPX( x ); + dom.style.top = numberToPX( y ); return this; @@ -1362,7 +1463,7 @@ class Node extends Serializer { setWidth( val ) { - this.dom.style.width = toPX( val ); + this.dom.style.width = numberToPX( val ); return this; @@ -1374,6 +1475,22 @@ class Node extends Serializer { } + getHeight() { + + return this.dom.offsetHeight; + + } + + getBound() { + + const { x, y } = this.getPosition(); + const width = this.getWidth(); + const height = this.getHeight(); + + return { x, y, width, height }; + + } + add( element ) { this.elements.push( element ); @@ -1452,6 +1569,12 @@ class Node extends Serializer { } + getColor() { + + return this.elements[ 0 ]?.getColor(); + + } + serialize( data ) { const { x, y } = this.getPosition(); @@ -1514,6 +1637,8 @@ class Node extends Serializer { } +Node.prototype.isNode = true; + class DraggableElement extends Element { constructor( draggable = true ) { @@ -1528,7 +1653,7 @@ class DraggableElement extends Element { if ( this.draggable === true ) { - draggableDOM( this.node.dom ); + draggableDOM( this.node.dom, null, { className: 'dragging node' } ); } @@ -1553,8 +1678,16 @@ class TitleElement extends DraggableElement { dom.className = 'title'; - const spanDOM = document.createElement( 'span' ); - spanDOM.innerText = title; + const dbClick = () => { + + this.node.canvas.focusSelected = ! this.node.canvas.focusSelected; + + }; + + dom.addEventListener( 'dblclick', dbClick ); + + const titleDOM = document.createElement( 'f-title' ); + titleDOM.innerText = title; const iconDOM = document.createElement( 'i' ); @@ -1562,11 +1695,11 @@ class TitleElement extends DraggableElement { this.buttons = []; - this.spanDOM = spanDOM; + this.titleDOM = titleDOM; this.iconDOM = iconDOM; this.toolbarDOM = toolbarDOM; - dom.append( spanDOM ); + dom.append( titleDOM ); dom.append( iconDOM ); dom.append( toolbarDOM ); @@ -1588,7 +1721,7 @@ class TitleElement extends DraggableElement { setTitle( value ) { - this.spanDOM.innerText = value; + this.titleDOM.innerText = value; return this; @@ -1596,7 +1729,7 @@ class TitleElement extends DraggableElement { getTitle() { - return this.spanDOM.innerText; + return this.titleDOM.innerText; } @@ -1699,9 +1832,11 @@ class Canvas extends Serializer { const canvas = document.createElement( 'canvas' ); const frontCanvas = document.createElement( 'canvas' ); + const mapCanvas = document.createElement( 'canvas' ); const context = canvas.getContext( '2d' ); const frontContext = frontCanvas.getContext( '2d' ); + const mapContext = mapCanvas.getContext( '2d' ); this.dom = dom; @@ -1711,12 +1846,11 @@ class Canvas extends Serializer { this.canvas = canvas; this.frontCanvas = frontCanvas; + this.mapCanvas = mapCanvas; this.context = context; this.frontContext = frontContext; - - this.width = 10000; - this.height = 10000; + this.mapContext = mapContext; this.clientX = 0; this.clientY = 0; @@ -1724,8 +1858,6 @@ class Canvas extends Serializer { this.relativeClientX = 0; this.relativeClientY = 0; - this.zoom = 1; - this.nodes = []; this.selected = null; @@ -1738,13 +1870,20 @@ class Canvas extends Serializer { 'drop': [] }; - frontCanvas.className = 'front'; - - contentDOM.style.left = toPX( this.centerX ); - contentDOM.style.top = toPX( this.centerY ); + this._scrollLeft = 0; + this._scrollTop = 0; + this._zoom = 1; + this._width = 0; + this._height = 0; + this._focusSelected = false; + this._mapInfo = { + scale: 1, + screen: {} + }; - areaDOM.style.width = `calc( 100% + ${ this.width }px )`; - areaDOM.style.height = `calc( 100% + ${ this.height }px )`; + canvas.className = 'background'; + frontCanvas.className = 'frontground'; + mapCanvas.className = 'map'; dropDOM.innerHTML = 'drop your file'; @@ -1753,77 +1892,108 @@ class Canvas extends Serializer { dom.append( frontCanvas ); dom.append( contentDOM ); dom.append( areaDOM ); - /* - let zoomTouchData = null; + dom.append( mapCanvas ); + + const zoomTo = ( zoom, clientX = this.clientX, clientY = this.clientY ) => { - const onZoomStart = () => { + zoom = Math.min( Math.max( zoom, .2 ), 1 ); - zoomTouchData = null; + this.scrollLeft -= ( clientX / this.zoom ) - ( clientX / zoom ); + this.scrollTop -= ( clientY / this.zoom ) - ( clientY / zoom ); + this.zoom = zoom; }; -*/ - const onZoom = ( e ) => { - if ( e.touches ) { + let touchData = null; - if ( e.touches.length === 2 ) { + const onTouchStart = () => { - e.preventDefault(); + touchData = null; - e.stopImmediatePropagation(); - /* - const clientX = ( e.touches[ 0 ].clientX + e.touches[ 1 ].clientX ) / 2; - const clientY = ( e.touches[ 0 ].clientY + e.touches[ 1 ].clientY ) / 2; + }; - const distance = Math.hypot( - e.touches[ 0 ].clientX - e.touches[ 1 ].clientX, - e.touches[ 0 ].clientY - e.touches[ 1 ].clientY - ); + const onMouseZoom = ( e ) => { + + e.preventDefault(); - if ( zoomTouchData === null ) { + e.stopImmediatePropagation(); - zoomTouchData = { - distance - }; + const delta = e.deltaY * .003; - } + zoomTo( this.zoom - delta ); + + }; + + const onTouchZoom = ( e ) => { + + if ( e.touches && e.touches.length === 2 ) { + + e.preventDefault(); + + e.stopImmediatePropagation(); - const delta = ( zoomTouchData.distance - distance ); - zoomTouchData.distance = distance; + const clientX = ( e.touches[ 0 ].clientX + e.touches[ 1 ].clientX ) / 2; + const clientY = ( e.touches[ 0 ].clientY + e.touches[ 1 ].clientY ) / 2; - let zoom = Math.min( Math.max( this.zoom - delta * .01, .5 ), 1.2 ); + const distance = Math.hypot( + e.touches[ 0 ].clientX - e.touches[ 1 ].clientX, + e.touches[ 0 ].clientY - e.touches[ 1 ].clientY + ); - if ( zoom < .52 ) zoom = .5; - else if ( zoom > .98 ) zoom = 1; + if ( touchData === null ) { - contentDOM.style.left = toPX( this.centerX / zoom ); - contentDOM.style.top = toPX( this.centerY / zoom ); - contentDOM.style.zoom = this.zoom = zoom; -*/ + touchData = { + distance + }; } - } else { + const delta = ( touchData.distance - distance ) * .003; + touchData.distance = distance; + + zoomTo( this.zoom - delta, clientX, clientY ); + + } + + }; + + const onTouchMove = ( e ) => { + + if ( e.touches && e.touches.length === 1 ) { e.preventDefault(); e.stopImmediatePropagation(); - /* - const delta = e.deltaY / 100; - const zoom = Math.min( Math.max( this.zoom - delta * .1, .5 ), 1 ); - contentDOM.style.left = toPX( this.centerX / zoom ); - contentDOM.style.top = toPX( this.centerY / zoom ); - contentDOM.style.zoom = this.zoom = zoom; -*/ + const clientX = e.touches[ 0 ].clientX; + const clientY = e.touches[ 0 ].clientY; + + if ( touchData === null ) { + + const { scrollLeft, scrollTop } = this; + + touchData = { + scrollLeft, + scrollTop, + clientX, + clientY + }; + + } + + const zoom = this.zoom; + + this.scrollLeft = touchData.scrollLeft + ( ( clientX - touchData.clientX ) / zoom ); + this.scrollTop = touchData.scrollTop + ( ( clientY - touchData.clientY ) / zoom ); } }; - dom.addEventListener( 'wheel', onZoom ); - dom.addEventListener( 'touchmove', onZoom ); - //dom.addEventListener( 'touchstart', onZoomStart ); + dom.addEventListener( 'wheel', onMouseZoom ); + dom.addEventListener( 'touchmove', onTouchZoom ); + dom.addEventListener( 'touchstart', onTouchStart ); + canvas.addEventListener( 'touchmove', onTouchMove ); let dropEnterCount = 0; @@ -1895,13 +2065,15 @@ class Canvas extends Serializer { if ( data.scrollTop === undefined ) { - data.scrollLeft = dom.scrollLeft; - data.scrollTop = dom.scrollTop; + data.scrollLeft = this.scrollLeft; + data.scrollTop = this.scrollTop; } - dom.scrollLeft = data.scrollLeft - delta.x; - dom.scrollTop = data.scrollTop - delta.y; + const zoom = this.zoom; + + this.scrollLeft = data.scrollLeft + ( delta.x / zoom ); + this.scrollTop = data.scrollTop + ( delta.y / zoom ); } @@ -1915,7 +2087,48 @@ class Canvas extends Serializer { } - }, 'dragging-canvas' ); + }, { className: 'dragging-canvas' } ); + + + draggableDOM( mapCanvas, ( data ) => { + + const { scale, screen } = this._mapInfo; + + if ( data.scrollLeft === undefined ) { + + const rect = this.mapCanvas.getBoundingClientRect(); + + const clientMapX = data.client.x - rect.left; + const clientMapY = data.client.y - rect.top; + + const overMapScreen = + clientMapX > screen.x && clientMapY > screen.y && + clientMapX < screen.x + screen.width && clientMapY < screen.y + screen.height; + + if ( overMapScreen === false ) { + + const scaleX = this._mapInfo.width / this.mapCanvas.width; + + let scrollLeft = - this._mapInfo.left - ( clientMapX * scaleX ); + let scrollTop = - this._mapInfo.top - ( clientMapY * ( this._mapInfo.height / this.mapCanvas.height ) ); + + scrollLeft += ( screen.width / 2 ) / scale; + scrollTop += ( screen.height / 2 ) / scale; + + this.scrollLeft = scrollLeft; + this.scrollTop = scrollTop; + + } + + data.scrollLeft = this.scrollLeft; + data.scrollTop = this.scrollTop; + + } + + this.scrollLeft = data.scrollLeft - ( data.delta.x / scale ); + this.scrollTop = data.scrollTop - ( data.delta.y / scale ); + + }, { click: true } ); this._onMoveEvent = ( e ) => { @@ -1925,14 +2138,11 @@ class Canvas extends Serializer { this.clientX = event.clientX; this.clientY = event.clientY; - this.relativeClientX = ( ( ( dom.scrollLeft - this.centerX ) + event.clientX ) - rect.left ) / zoom; - this.relativeClientY = ( ( ( dom.scrollTop - this.centerY ) + event.clientY ) - rect.top ) / zoom; - - }; - - this._onContentLoaded = () => { + const rectClientX = ( this.clientX - rect.left ) / zoom; + const rectClientY = ( this.clientY - rect.top ) / zoom; - this.centralize(); + this.relativeClientX = rectClientX - this.scrollLeft; + this.relativeClientY = rectClientY - this.scrollTop; }; @@ -1946,33 +2156,110 @@ class Canvas extends Serializer { } + getBounds() { + + const bounds = { x: Infinity, y: Infinity, width: - Infinity, height: - Infinity }; + + for ( const node of this.nodes ) { + + const { x, y, width, height } = node.getBound(); + + bounds.x = Math.min( bounds.x, x ); + bounds.y = Math.min( bounds.y, y ); + bounds.width = Math.max( bounds.width, x + width ); + bounds.height = Math.max( bounds.height, y + height ); + + } + + bounds.x = Math.round( bounds.x ); + bounds.y = Math.round( bounds.y ); + bounds.width = Math.round( bounds.width ); + bounds.height = Math.round( bounds.height ); + + return bounds; + + } + + get width() { + + return this._width; + + } + + get height() { + + return this._height; + + } + get rect() { return this.dom.getBoundingClientRect(); } - get relativeX() { + get zoom() { + + return this._zoom; + + } + + set zoom( val ) { + + this._zoom = val; + this.contentDOM.style.zoom = val; + + } + + set scrollLeft( val ) { + + this._scrollLeft = val; + this.contentDOM.style.left = numberToPX( val ); + + } + + get scrollLeft() { + + return this._scrollLeft; + + } + + set scrollTop( val ) { - return this.dom.scrollLeft - this.centerX; + this._scrollTop = val; + this.contentDOM.style.top = numberToPX( val ); } - get relativeY() { + get scrollTop() { - return this.dom.scrollTop - this.centerY; + return this._scrollTop; } - get centerX() { + set focusSelected( value ) { + + if ( this._focusSelected === value ) return; + + const classList = this.dom.classList; + + this._focusSelected = value; - return this.width / 2; + if ( value ) { + + classList.add( 'focusing' ); + + } else { + + classList.remove( 'focusing' ); + + } } - get centerY() { + get focusSelected() { - return this.height / 2; + return this._focusSelected; } @@ -1998,8 +2285,6 @@ class Canvas extends Serializer { document.addEventListener( 'dragover', this._onMoveEvent, true ); - document.addEventListener( 'DOMContentLoaded', this._onContentLoaded ); - requestAnimationFrame( this._onUpdate ); } @@ -2018,8 +2303,6 @@ class Canvas extends Serializer { document.removeEventListener( 'dragover', this._onMoveEvent, true ); - document.removeEventListener( 'DOMContentLoaded', this._onContentLoaded ); - } add( node ) { @@ -2114,7 +2397,21 @@ class Canvas extends Serializer { centralize() { - this.dom.scroll( this.centerX, this.centerY ); + const bounds = this.getBounds(); + + this.scrollLeft = ( this.canvas.width / 2 ) - ( ( - bounds.x + bounds.width ) / 2 ); + this.scrollTop = ( this.canvas.height / 2 ) - ( ( - bounds.y + bounds.height ) / 2 ); + + return this; + + } + + setSize( width, height ) { + + this._width = width; + this._height = height; + + this.update(); return this; @@ -2128,6 +2425,8 @@ class Canvas extends Serializer { if ( previousNode !== null ) { + this.focusSelected = false; + previousNode.dom.classList.remove( 'selected' ); this.selected = null; @@ -2148,31 +2447,116 @@ class Canvas extends Serializer { } - update() { + updateMap() { - if ( this.updating === false ) return; + const { nodes, mapCanvas, mapContext, scrollLeft, scrollTop, canvas, zoom, _mapInfo } = this; - requestAnimationFrame( this._onUpdate ); + const bounds = this.getBounds(); + + mapCanvas.width = 300; + mapCanvas.height = 200; + + mapContext.clearRect( 0, 0, mapCanvas.width, mapCanvas.height ); + + mapContext.fillStyle = 'rgba( 0, 0, 0, 0 )'; + mapContext.fillRect( 0, 0, mapCanvas.width, mapCanvas.height ); + + const boundsWidth = - bounds.x + bounds.width; + const boundsHeight = - bounds.y + bounds.height; + + const mapScale = Math.min( mapCanvas.width / boundsWidth, mapCanvas.height / boundsHeight ) * .5; + + const boundsMapWidth = boundsWidth * mapScale; + const boundsMapHeight = boundsHeight * mapScale; + + const boundsOffsetX = ( mapCanvas.width / 2 ) - ( boundsMapWidth / 2 ); + const boundsOffsetY = ( mapCanvas.height / 2 ) - ( boundsMapHeight / 2 ); + + let selectedNode = null; + + for ( const node of nodes ) { + + const nodeBound = node.getBound(); + const nodeColor = node.getColor(); + + nodeBound.x += - bounds.x; + nodeBound.y += - bounds.y; + + nodeBound.x *= mapScale; + nodeBound.y *= mapScale; + nodeBound.width *= mapScale; + nodeBound.height *= mapScale; + + nodeBound.x += boundsOffsetX; + nodeBound.y += boundsOffsetY; + + if ( node !== this.selected ) { + + mapContext.fillStyle = nodeColor; + mapContext.fillRect( nodeBound.x, nodeBound.y, nodeBound.width, nodeBound.height ); + + } else { + + selectedNode = { + nodeBound, + nodeColor + }; + + } + + } + + if ( selectedNode !== null ) { + + const { nodeBound, nodeColor } = selectedNode; + + mapContext.fillStyle = nodeColor; + mapContext.fillRect( nodeBound.x, nodeBound.y, nodeBound.width, nodeBound.height ); + + } + + const screenMapX = ( - ( scrollLeft + bounds.x ) * mapScale ) + boundsOffsetX; + const screenMapY = ( - ( scrollTop + bounds.y ) * mapScale ) + boundsOffsetY; + const screenMapWidth = ( canvas.width * mapScale ) / zoom; + const screenMapHeight = ( canvas.height * mapScale ) / zoom; - const { dom, zoom, canvas, frontCanvas, frontContext, context } = this; + mapContext.fillStyle = 'rgba( 200, 200, 200, 0.1 )'; + mapContext.fillRect( screenMapX, screenMapY, screenMapWidth, screenMapHeight ); - const width = window.innerWidth; - const height = window.innerHeight; + // + + _mapInfo.scale = mapScale; + _mapInfo.left = ( - boundsOffsetX / mapScale ) + bounds.x; + _mapInfo.top = ( - boundsOffsetY / mapScale ) + bounds.y; + _mapInfo.width = mapCanvas.width / mapScale; + _mapInfo.height = mapCanvas.height / mapScale; + _mapInfo.screen.x = screenMapX; + _mapInfo.screen.y = screenMapY; + _mapInfo.screen.width = screenMapWidth; + _mapInfo.screen.height = screenMapHeight; + + } + + updateLines() { + + const { dom, zoom, canvas, frontCanvas, frontContext, context, _width, _height } = this; const domRect = this.rect; - if ( canvas.width !== width || canvas.height !== height ) { + if ( canvas.width !== _width || canvas.height !== _height ) { - canvas.width = width; - canvas.height = height; + canvas.width = _width; + canvas.height = _height; - frontCanvas.width = width; - frontCanvas.height = height; + frontCanvas.width = _width; + frontCanvas.height = _height; } - context.clearRect( 0, 0, width, height ); - frontContext.clearRect( 0, 0, width, height ); + context.clearRect( 0, 0, _width, _height ); + frontContext.clearRect( 0, 0, _width, _height ); + + // context.globalCompositeOperation = 'lighter'; frontContext.globalCompositeOperation = 'source-over'; @@ -2321,6 +2705,18 @@ class Canvas extends Serializer { } + + update() { + + if ( this.updating === false ) return; + + requestAnimationFrame( this._onUpdate ); + + this.updateLines(); + this.updateMap(); + + } + serialize( data ) { const nodes = []; @@ -2484,7 +2880,7 @@ class ObjectNode extends Node { } -const ENTER_KEY$1 = 13; +const ENTER_KEY$2 = 13; class StringInput extends Input { @@ -2512,7 +2908,7 @@ class StringInput extends Input { dom.onkeyup = ( e ) => { - if ( e.keyCode === ENTER_KEY$1 ) { + if ( e.keyCode === ENTER_KEY$2 ) { e.target.blur(); @@ -2528,7 +2924,7 @@ class StringInput extends Input { } -const ENTER_KEY = 13; +const ENTER_KEY$1 = 13; class NumberInput extends Input { @@ -2565,6 +2961,8 @@ class NumberInput extends Input { dom.onblur = () => { + this.dom.value = this._getString( this.dom.value ); + this.dispatchEvent( new Event( 'blur' ) ); }; @@ -2583,7 +2981,7 @@ class NumberInput extends Input { } - if ( e.keyCode === ENTER_KEY ) { + if ( e.keyCode === ENTER_KEY$1 ) { e.target.blur(); @@ -2597,6 +2995,8 @@ class NumberInput extends Input { const { delta } = data; + if ( dom.readOnly === true ) return; + if ( data.value === undefined ) { data.value = this.getValue(); @@ -2607,7 +3007,7 @@ class NumberInput extends Input { const value = data.value + ( diff * this.step ); - this.dom.value = this._getString( value.toFixed( this.precision ) ); + dom.value = this._getString( value.toFixed( this.precision ) ); this.dispatchEvent( new Event( 'change' ) ); @@ -2737,6 +3137,8 @@ class SliderInput extends Input { rangeDOM.value = field.getValue(); + this.dispatchEvent( new Event( 'change' ) ); + } ); field.addEventListener( 'range', () => { @@ -2776,7 +3178,7 @@ class SliderInput extends Input { this.dispatchEvent( new Event( 'change' ) ); - }, '' ); + }, { className: '' } ); } @@ -2855,7 +3257,7 @@ class ColorInput extends Input { super( dom ); dom.type = 'color'; - dom.value = toHex( value ); + dom.value = numberToHex( value ); dom.oninput = () => { @@ -2867,18 +3269,20 @@ class ColorInput extends Input { setValue( value, dispatch = true ) { - return super.setValue( toHex( value ), dispatch ); + return super.setValue( numberToHex( value ), dispatch ); } getValue() { - return parseInt( super.getValue().slice( 1 ), 16 ); + return parseInt( super.getValue().substr( 1 ), 16 ); } } +const ENTER_KEY = 13; + class TextInput extends Input { constructor( innerText = '' ) { @@ -2888,19 +3292,31 @@ class TextInput extends Input { dom.innerText = innerText; - } + dom.onblur = () => { - setValue( val ) { + this.dispatchEvent( new Event( 'blur' ) ); - this.dom.innerText = val; + }; - return this; + dom.onchange = () => { - } + this.dispatchEvent( new Event( 'change' ) ); - getValue() { + }; - return this.dom.innerText; + dom.onkeyup = ( e ) => { + + if ( e.keyCode === ENTER_KEY ) { + + e.target.blur(); + + } + + e.stopPropagation(); + + this.dispatchEvent( new Event( 'change' ) ); + + }; } @@ -2916,13 +3332,11 @@ class LabelElement extends Element { this.inputsDOM = document.createElement( 'f-inputs' ); const spanDOM = document.createElement( 'span' ); - const iconDOM = document.createElement( 'i' ); this.spanDOM = spanDOM; - this.iconDOM = iconDOM; + this.iconDOM = null; - this.labelDOM.append( this.spanDOM ); - this.labelDOM.append( this.iconDOM ); + this.labelDOM.append( spanDOM ); this.dom.append( this.labelDOM ); this.dom.append( this.inputsDOM ); @@ -2936,15 +3350,19 @@ class LabelElement extends Element { setIcon( value ) { + this.iconDOM = this.iconDOM || document.createElement( 'i' ); this.iconDOM.className = value; + if ( value ) this.labelDOM.prepend( this.iconDOM ); + else this.iconDOM.remove(); + return this; } getIcon() { - return this.iconDOM.className; + return this.iconDOM?.className; } @@ -3135,7 +3553,7 @@ class Menu extends EventTarget { super(); const dom = document.createElement( 'f-menu' ); - dom.className = className + ' hidden'; + dom.className = className + ' bottom left hidden'; const listDOM = document.createElement( 'f-list' ); @@ -3146,6 +3564,8 @@ class Menu extends EventTarget { this.visible = false; + this.align = 'bottom left'; + this.subMenus = new WeakMap(); this.domButtons = new WeakMap(); @@ -3163,6 +3583,25 @@ class Menu extends EventTarget { } + setAlign( align ) { + + const dom = this.dom; + + removeDOMClass( dom, this.align ); + addDOMClass( dom, align ); + + this.align = align; + + return this; + + } + + getAlign() { + + return this.align; + + } + show() { this.dom.classList.remove( 'hidden' ); @@ -3334,8 +3773,8 @@ class ContextMenu extends Menu { const dom = this.dom; - dom.style.left = toPX( x ); - dom.style.top = toPX( y ); + dom.style.left = numberToPX( x ); + dom.style.top = numberToPX( y ); return this; @@ -3481,7 +3920,7 @@ class Tips extends EventTarget { setTimeout( () => { - this.time -= this.duration; + this.time = Math.max( this.time - this.duration, 0 ); dom.style.opacity = 0; @@ -3510,6 +3949,8 @@ class Search extends Menu { this.events.submit = []; this.events.filter = []; + this.tags = new WeakMap(); + const inputDOM = document.createElement( 'input' ); inputDOM.placeholder = 'Type here'; @@ -3741,10 +4182,17 @@ class Search extends Menu { } + setTag( button, tags ) { + + this.tags.set( button, tags ); + + } + filter( text ) { text = filterString( text ); + const tags = this.tags; const filtered = []; for ( const button of this.buttons ) { @@ -3753,7 +4201,9 @@ class Search extends Menu { buttonDOM.remove(); - const label = filterString( button.getValue() ); + const buttonTags = tags.has( button ) ? ' ' + tags.get( button ) : ''; + + const label = filterString( button.getValue() + buttonTags ); if ( text && label.includes( text ) === true ) { @@ -3925,7 +4375,7 @@ class ToggleInput extends Input { } -var Flow = /*#__PURE__*/Object.freeze( { +var Flow = /*#__PURE__*/Object.freeze({ __proto__: null, Element: Element, Input: Input, @@ -3951,7 +4401,7 @@ var Flow = /*#__PURE__*/Object.freeze( { StringInput: StringInput, TextInput: TextInput, ToggleInput: ToggleInput -} ); +}); class Loader extends EventTarget { diff --git a/examples/jsm/libs/lottie_canvas.module.js b/examples/jsm/libs/lottie_canvas.module.js new file mode 100644 index 00000000000000..cbe3a964e5c90d --- /dev/null +++ b/examples/jsm/libs/lottie_canvas.module.js @@ -0,0 +1,14844 @@ +const svgNS = 'http://www.w3.org/2000/svg'; + +let locationHref = ''; +let _useWebWorker = false; + +const initialDefaultFrame = -999999; + +const setWebWorker = (flag) => { _useWebWorker = !!flag; }; +const getWebWorker = () => _useWebWorker; + +const setLocationHref = (value) => { locationHref = value; }; +const getLocationHref = () => locationHref; + +function createTag(type) { + // return {appendChild:function(){},setAttribute:function(){},style:{}} + return document.createElement(type); +} + +function extendPrototype(sources, destination) { + var i; + var len = sources.length; + var sourcePrototype; + for (i = 0; i < len; i += 1) { + sourcePrototype = sources[i].prototype; + for (var attr in sourcePrototype) { + if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr]; + } + } +} + +function getDescriptor(object, prop) { + return Object.getOwnPropertyDescriptor(object, prop); +} + +function createProxyFunction(prototype) { + function ProxyFunction() {} + ProxyFunction.prototype = prototype; + return ProxyFunction; +} + +// import Howl from '../../3rd_party/howler'; + +const audioControllerFactory = (function () { + function AudioController(audioFactory) { + this.audios = []; + this.audioFactory = audioFactory; + this._volume = 1; + this._isMuted = false; + } + + AudioController.prototype = { + addAudio: function (audio) { + this.audios.push(audio); + }, + pause: function () { + var i; + var len = this.audios.length; + for (i = 0; i < len; i += 1) { + this.audios[i].pause(); + } + }, + resume: function () { + var i; + var len = this.audios.length; + for (i = 0; i < len; i += 1) { + this.audios[i].resume(); + } + }, + setRate: function (rateValue) { + var i; + var len = this.audios.length; + for (i = 0; i < len; i += 1) { + this.audios[i].setRate(rateValue); + } + }, + createAudio: function (assetPath) { + if (this.audioFactory) { + return this.audioFactory(assetPath); + } if (window.Howl) { + return new window.Howl({ + src: [assetPath], + }); + } + return { + isPlaying: false, + play: function () { this.isPlaying = true; }, + seek: function () { this.isPlaying = false; }, + playing: function () {}, + rate: function () {}, + setVolume: function () {}, + }; + }, + setAudioFactory: function (audioFactory) { + this.audioFactory = audioFactory; + }, + setVolume: function (value) { + this._volume = value; + this._updateVolume(); + }, + mute: function () { + this._isMuted = true; + this._updateVolume(); + }, + unmute: function () { + this._isMuted = false; + this._updateVolume(); + }, + getVolume: function () { + return this._volume; + }, + _updateVolume: function () { + var i; + var len = this.audios.length; + for (i = 0; i < len; i += 1) { + this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1)); + } + }, + }; + + return function () { + return new AudioController(); + }; +}()); + +const createTypedArray = (function () { + function createRegularArray(type, len) { + var i = 0; + var arr = []; + var value; + switch (type) { + case 'int16': + case 'uint8c': + value = 1; + break; + default: + value = 1.1; + break; + } + for (i = 0; i < len; i += 1) { + arr.push(value); + } + return arr; + } + function createTypedArrayFactory(type, len) { + if (type === 'float32') { + return new Float32Array(len); + } if (type === 'int16') { + return new Int16Array(len); + } if (type === 'uint8c') { + return new Uint8ClampedArray(len); + } + return createRegularArray(type, len); + } + if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') { + return createTypedArrayFactory; + } + return createRegularArray; +}()); + +function createSizedArray(len) { + return Array.apply(null, { length: len }); +} + +let subframeEnabled = true; +let expressionsPlugin = null; +let idPrefix$1 = ''; +const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); +let _shouldRoundValues = false; +const bmPow = Math.pow; +const bmSqrt = Math.sqrt; +const bmFloor = Math.floor; +const bmMax = Math.max; +const bmMin = Math.min; + +const BMMath = {}; +(function () { + var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2']; + var i; + var len = propertyNames.length; + for (i = 0; i < len; i += 1) { + BMMath[propertyNames[i]] = Math[propertyNames[i]]; + } +}()); + +function ProjectInterface$1() { return {}; } +BMMath.random = Math.random; +BMMath.abs = function (val) { + var tOfVal = typeof val; + if (tOfVal === 'object' && val.length) { + var absArr = createSizedArray(val.length); + var i; + var len = val.length; + for (i = 0; i < len; i += 1) { + absArr[i] = Math.abs(val[i]); + } + return absArr; + } + return Math.abs(val); +}; +let defaultCurveSegments = 150; +const degToRads = Math.PI / 180; +const roundCorner = 0.5519; + +function roundValues(flag) { + _shouldRoundValues = !!flag; +} + +function bmRnd(value) { + if (_shouldRoundValues) { + return Math.round(value); + } + return value; +} + +function styleDiv(element) { + element.style.position = 'absolute'; + element.style.top = 0; + element.style.left = 0; + element.style.display = 'block'; + element.style.transformOrigin = '0 0'; + element.style.webkitTransformOrigin = '0 0'; + element.style.backfaceVisibility = 'visible'; + element.style.webkitBackfaceVisibility = 'visible'; + element.style.transformStyle = 'preserve-3d'; + element.style.webkitTransformStyle = 'preserve-3d'; + element.style.mozTransformStyle = 'preserve-3d'; +} + +function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) { + this.type = type; + this.currentTime = currentTime; + this.totalTime = totalTime; + this.direction = frameMultiplier < 0 ? -1 : 1; +} + +function BMCompleteEvent(type, frameMultiplier) { + this.type = type; + this.direction = frameMultiplier < 0 ? -1 : 1; +} + +function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) { + this.type = type; + this.currentLoop = currentLoop; + this.totalLoops = totalLoops; + this.direction = frameMultiplier < 0 ? -1 : 1; +} + +function BMSegmentStartEvent(type, firstFrame, totalFrames) { + this.type = type; + this.firstFrame = firstFrame; + this.totalFrames = totalFrames; +} + +function BMDestroyEvent(type, target) { + this.type = type; + this.target = target; +} + +function BMRenderFrameErrorEvent(nativeError, currentTime) { + this.type = 'renderFrameError'; + this.nativeError = nativeError; + this.currentTime = currentTime; +} + +function BMConfigErrorEvent(nativeError) { + this.type = 'configError'; + this.nativeError = nativeError; +} + +function BMAnimationConfigErrorEvent(type, nativeError) { + this.type = type; + this.nativeError = nativeError; +} + +const createElementID = (function () { + var _count = 0; + return function createID() { + _count += 1; + return idPrefix$1 + '__lottie_element_' + _count; + }; +}()); + +function HSVtoRGB(h, s, v) { + var r; + var g; + var b; + var i; + var f; + var p; + var q; + var t; + i = Math.floor(h * 6); + f = h * 6 - i; + p = v * (1 - s); + q = v * (1 - f * s); + t = v * (1 - (1 - f) * s); + switch (i % 6) { + case 0: r = v; g = t; b = p; break; + case 1: r = q; g = v; b = p; break; + case 2: r = p; g = v; b = t; break; + case 3: r = p; g = q; b = v; break; + case 4: r = t; g = p; b = v; break; + case 5: r = v; g = p; b = q; break; + default: break; + } + return [r, + g, + b]; +} + +function RGBtoHSV(r, g, b) { + var max = Math.max(r, g, b); + var min = Math.min(r, g, b); + var d = max - min; + var h; + var s = (max === 0 ? 0 : d / max); + var v = max / 255; + + switch (max) { + case min: h = 0; break; + case r: h = (g - b) + d * (g < b ? 6 : 0); h /= 6 * d; break; + case g: h = (b - r) + d * 2; h /= 6 * d; break; + case b: h = (r - g) + d * 4; h /= 6 * d; break; + default: break; + } + + return [ + h, + s, + v, + ]; +} + +function addSaturationToRGB(color, offset) { + var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255); + hsv[1] += offset; + if (hsv[1] > 1) { + hsv[1] = 1; + } else if (hsv[1] <= 0) { + hsv[1] = 0; + } + return HSVtoRGB(hsv[0], hsv[1], hsv[2]); +} + +function addBrightnessToRGB(color, offset) { + var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255); + hsv[2] += offset; + if (hsv[2] > 1) { + hsv[2] = 1; + } else if (hsv[2] < 0) { + hsv[2] = 0; + } + return HSVtoRGB(hsv[0], hsv[1], hsv[2]); +} + +function addHueToRGB(color, offset) { + var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255); + hsv[0] += offset / 360; + if (hsv[0] > 1) { + hsv[0] -= 1; + } else if (hsv[0] < 0) { + hsv[0] += 1; + } + return HSVtoRGB(hsv[0], hsv[1], hsv[2]); +} + +const rgbToHex = (function () { + var colorMap = []; + var i; + var hex; + for (i = 0; i < 256; i += 1) { + hex = i.toString(16); + colorMap[i] = hex.length === 1 ? '0' + hex : hex; + } + + return function (r, g, b) { + if (r < 0) { + r = 0; + } + if (g < 0) { + g = 0; + } + if (b < 0) { + b = 0; + } + return '#' + colorMap[r] + colorMap[g] + colorMap[b]; + }; +}()); + +const setSubframeEnabled = (flag) => { subframeEnabled = !!flag; }; +const getSubframeEnabled = () => subframeEnabled; +const setExpressionsPlugin = (value) => { expressionsPlugin = value; }; +const getExpressionsPlugin = () => expressionsPlugin; +const setDefaultCurveSegments = (value) => { defaultCurveSegments = value; }; +const getDefaultCurveSegments = () => defaultCurveSegments; +const setIdPrefix = (value) => { idPrefix$1 = value; }; +const getIdPrefix = () => idPrefix$1; + +function createNS(type) { + // return {appendChild:function(){},setAttribute:function(){},style:{}} + return document.createElementNS(svgNS, type); +} + +const dataManager = (function () { + var _counterId = 1; + var processes = []; + var workerFn; + var workerInstance; + var workerProxy = { + onmessage: function () { + + }, + postMessage: function (path) { + workerFn({ + data: path, + }); + }, + }; + var _workerSelf = { + postMessage: function (data) { + workerProxy.onmessage({ + data: data, + }); + }, + }; + function createWorker(fn) { + if (window.Worker && window.Blob && getWebWorker()) { + var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], { type: 'text/javascript' }); + // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' }); + var url = URL.createObjectURL(blob); + return new Worker(url); + } + workerFn = fn; + return workerProxy; + } + + function setupWorker() { + if (!workerInstance) { + workerInstance = createWorker(function workerStart(e) { + function dataFunctionManager() { + function completeLayers(layers, comps) { + var layerData; + var i; + var len = layers.length; + var j; + var jLen; + var k; + var kLen; + for (i = 0; i < len; i += 1) { + layerData = layers[i]; + if (('ks' in layerData) && !layerData.completed) { + layerData.completed = true; + if (layerData.tt) { + layers[i - 1].td = layerData.tt; + } + if (layerData.hasMask) { + var maskProps = layerData.masksProperties; + jLen = maskProps.length; + for (j = 0; j < jLen; j += 1) { + if (maskProps[j].pt.k.i) { + convertPathsToAbsoluteValues(maskProps[j].pt.k); + } else { + kLen = maskProps[j].pt.k.length; + for (k = 0; k < kLen; k += 1) { + if (maskProps[j].pt.k[k].s) { + convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]); + } + if (maskProps[j].pt.k[k].e) { + convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]); + } + } + } + } + } + if (layerData.ty === 0) { + layerData.layers = findCompLayers(layerData.refId, comps); + completeLayers(layerData.layers, comps); + } else if (layerData.ty === 4) { + completeShapes(layerData.shapes); + } else if (layerData.ty === 5) { + completeText(layerData); + } + } + } + } + + function completeChars(chars, assets) { + if (chars) { + var i = 0; + var len = chars.length; + for (i = 0; i < len; i += 1) { + if (chars[i].t === 1) { + // var compData = findComp(chars[i].data.refId, assets); + chars[i].data.layers = findCompLayers(chars[i].data.refId, assets); + // chars[i].data.ip = 0; + // chars[i].data.op = 99999; + // chars[i].data.st = 0; + // chars[i].data.sr = 1; + // chars[i].w = compData.w; + // chars[i].data.ks = { + // a: { k: [0, 0, 0], a: 0 }, + // p: { k: [0, -compData.h, 0], a: 0 }, + // r: { k: 0, a: 0 }, + // s: { k: [100, 100], a: 0 }, + // o: { k: 100, a: 0 }, + // }; + completeLayers(chars[i].data.layers, assets); + } + } + } + } + + function findComp(id, comps) { + var i = 0; + var len = comps.length; + while (i < len) { + if (comps[i].id === id) { + return comps[i]; + } + i += 1; + } + return null; + } + + function findCompLayers(id, comps) { + var comp = findComp(id, comps); + if (comp) { + if (!comp.layers.__used) { + comp.layers.__used = true; + return comp.layers; + } + return JSON.parse(JSON.stringify(comp.layers)); + } + return null; + } + + function completeShapes(arr) { + var i; + var len = arr.length; + var j; + var jLen; + for (i = len - 1; i >= 0; i -= 1) { + if (arr[i].ty === 'sh') { + if (arr[i].ks.k.i) { + convertPathsToAbsoluteValues(arr[i].ks.k); + } else { + jLen = arr[i].ks.k.length; + for (j = 0; j < jLen; j += 1) { + if (arr[i].ks.k[j].s) { + convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]); + } + if (arr[i].ks.k[j].e) { + convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]); + } + } + } + } else if (arr[i].ty === 'gr') { + completeShapes(arr[i].it); + } + } + } + + function convertPathsToAbsoluteValues(path) { + var i; + var len = path.i.length; + for (i = 0; i < len; i += 1) { + path.i[i][0] += path.v[i][0]; + path.i[i][1] += path.v[i][1]; + path.o[i][0] += path.v[i][0]; + path.o[i][1] += path.v[i][1]; + } + } + + function checkVersion(minimum, animVersionString) { + var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100]; + if (minimum[0] > animVersion[0]) { + return true; + } if (animVersion[0] > minimum[0]) { + return false; + } + if (minimum[1] > animVersion[1]) { + return true; + } if (animVersion[1] > minimum[1]) { + return false; + } + if (minimum[2] > animVersion[2]) { + return true; + } if (animVersion[2] > minimum[2]) { + return false; + } + return null; + } + + var checkText = (function () { + var minimumVersion = [4, 4, 14]; + + function updateTextLayer(textLayer) { + var documentData = textLayer.t.d; + textLayer.t.d = { + k: [ + { + s: documentData, + t: 0, + }, + ], + }; + } + + function iterateLayers(layers) { + var i; + var len = layers.length; + for (i = 0; i < len; i += 1) { + if (layers[i].ty === 5) { + updateTextLayer(layers[i]); + } + } + } + + return function (animationData) { + if (checkVersion(minimumVersion, animationData.v)) { + iterateLayers(animationData.layers); + if (animationData.assets) { + var i; + var len = animationData.assets.length; + for (i = 0; i < len; i += 1) { + if (animationData.assets[i].layers) { + iterateLayers(animationData.assets[i].layers); + } + } + } + } + }; + }()); + + var checkChars = (function () { + var minimumVersion = [4, 7, 99]; + return function (animationData) { + if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) { + var i; + var len = animationData.chars.length; + for (i = 0; i < len; i += 1) { + var charData = animationData.chars[i]; + if (charData.data && charData.data.shapes) { + completeShapes(charData.data.shapes); + charData.data.ip = 0; + charData.data.op = 99999; + charData.data.st = 0; + charData.data.sr = 1; + charData.data.ks = { + p: { k: [0, 0], a: 0 }, + s: { k: [100, 100], a: 0 }, + a: { k: [0, 0], a: 0 }, + r: { k: 0, a: 0 }, + o: { k: 100, a: 0 }, + }; + if (!animationData.chars[i].t) { + charData.data.shapes.push( + { + ty: 'no', + } + ); + charData.data.shapes[0].it.push( + { + p: { k: [0, 0], a: 0 }, + s: { k: [100, 100], a: 0 }, + a: { k: [0, 0], a: 0 }, + r: { k: 0, a: 0 }, + o: { k: 100, a: 0 }, + sk: { k: 0, a: 0 }, + sa: { k: 0, a: 0 }, + ty: 'tr', + } + ); + } + } + } + } + }; + }()); + + var checkPathProperties = (function () { + var minimumVersion = [5, 7, 15]; + + function updateTextLayer(textLayer) { + var pathData = textLayer.t.p; + if (typeof pathData.a === 'number') { + pathData.a = { + a: 0, + k: pathData.a, + }; + } + if (typeof pathData.p === 'number') { + pathData.p = { + a: 0, + k: pathData.p, + }; + } + if (typeof pathData.r === 'number') { + pathData.r = { + a: 0, + k: pathData.r, + }; + } + } + + function iterateLayers(layers) { + var i; + var len = layers.length; + for (i = 0; i < len; i += 1) { + if (layers[i].ty === 5) { + updateTextLayer(layers[i]); + } + } + } + + return function (animationData) { + if (checkVersion(minimumVersion, animationData.v)) { + iterateLayers(animationData.layers); + if (animationData.assets) { + var i; + var len = animationData.assets.length; + for (i = 0; i < len; i += 1) { + if (animationData.assets[i].layers) { + iterateLayers(animationData.assets[i].layers); + } + } + } + } + }; + }()); + + var checkColors = (function () { + var minimumVersion = [4, 1, 9]; + + function iterateShapes(shapes) { + var i; + var len = shapes.length; + var j; + var jLen; + for (i = 0; i < len; i += 1) { + if (shapes[i].ty === 'gr') { + iterateShapes(shapes[i].it); + } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') { + if (shapes[i].c.k && shapes[i].c.k[0].i) { + jLen = shapes[i].c.k.length; + for (j = 0; j < jLen; j += 1) { + if (shapes[i].c.k[j].s) { + shapes[i].c.k[j].s[0] /= 255; + shapes[i].c.k[j].s[1] /= 255; + shapes[i].c.k[j].s[2] /= 255; + shapes[i].c.k[j].s[3] /= 255; + } + if (shapes[i].c.k[j].e) { + shapes[i].c.k[j].e[0] /= 255; + shapes[i].c.k[j].e[1] /= 255; + shapes[i].c.k[j].e[2] /= 255; + shapes[i].c.k[j].e[3] /= 255; + } + } + } else { + shapes[i].c.k[0] /= 255; + shapes[i].c.k[1] /= 255; + shapes[i].c.k[2] /= 255; + shapes[i].c.k[3] /= 255; + } + } + } + } + + function iterateLayers(layers) { + var i; + var len = layers.length; + for (i = 0; i < len; i += 1) { + if (layers[i].ty === 4) { + iterateShapes(layers[i].shapes); + } + } + } + + return function (animationData) { + if (checkVersion(minimumVersion, animationData.v)) { + iterateLayers(animationData.layers); + if (animationData.assets) { + var i; + var len = animationData.assets.length; + for (i = 0; i < len; i += 1) { + if (animationData.assets[i].layers) { + iterateLayers(animationData.assets[i].layers); + } + } + } + } + }; + }()); + + var checkShapes = (function () { + var minimumVersion = [4, 4, 18]; + + function completeClosingShapes(arr) { + var i; + var len = arr.length; + var j; + var jLen; + for (i = len - 1; i >= 0; i -= 1) { + if (arr[i].ty === 'sh') { + if (arr[i].ks.k.i) { + arr[i].ks.k.c = arr[i].closed; + } else { + jLen = arr[i].ks.k.length; + for (j = 0; j < jLen; j += 1) { + if (arr[i].ks.k[j].s) { + arr[i].ks.k[j].s[0].c = arr[i].closed; + } + if (arr[i].ks.k[j].e) { + arr[i].ks.k[j].e[0].c = arr[i].closed; + } + } + } + } else if (arr[i].ty === 'gr') { + completeClosingShapes(arr[i].it); + } + } + } + + function iterateLayers(layers) { + var layerData; + var i; + var len = layers.length; + var j; + var jLen; + var k; + var kLen; + for (i = 0; i < len; i += 1) { + layerData = layers[i]; + if (layerData.hasMask) { + var maskProps = layerData.masksProperties; + jLen = maskProps.length; + for (j = 0; j < jLen; j += 1) { + if (maskProps[j].pt.k.i) { + maskProps[j].pt.k.c = maskProps[j].cl; + } else { + kLen = maskProps[j].pt.k.length; + for (k = 0; k < kLen; k += 1) { + if (maskProps[j].pt.k[k].s) { + maskProps[j].pt.k[k].s[0].c = maskProps[j].cl; + } + if (maskProps[j].pt.k[k].e) { + maskProps[j].pt.k[k].e[0].c = maskProps[j].cl; + } + } + } + } + } + if (layerData.ty === 4) { + completeClosingShapes(layerData.shapes); + } + } + } + + return function (animationData) { + if (checkVersion(minimumVersion, animationData.v)) { + iterateLayers(animationData.layers); + if (animationData.assets) { + var i; + var len = animationData.assets.length; + for (i = 0; i < len; i += 1) { + if (animationData.assets[i].layers) { + iterateLayers(animationData.assets[i].layers); + } + } + } + } + }; + }()); + + function completeData(animationData) { + if (animationData.__complete) { + return; + } + checkColors(animationData); + checkText(animationData); + checkChars(animationData); + checkPathProperties(animationData); + checkShapes(animationData); + completeLayers(animationData.layers, animationData.assets); + completeChars(animationData.chars, animationData.assets); + animationData.__complete = true; + } + + function completeText(data) { + if (data.t.a.length === 0 && !('m' in data.t.p)) { + // data.singleShape = true; + } + } + + var moduleOb = {}; + moduleOb.completeData = completeData; + moduleOb.checkColors = checkColors; + moduleOb.checkChars = checkChars; + moduleOb.checkPathProperties = checkPathProperties; + moduleOb.checkShapes = checkShapes; + moduleOb.completeLayers = completeLayers; + + return moduleOb; + } + if (!_workerSelf.dataManager) { + _workerSelf.dataManager = dataFunctionManager(); + } + + if (!_workerSelf.assetLoader) { + _workerSelf.assetLoader = (function () { + function formatResponse(xhr) { + // using typeof doubles the time of execution of this method, + // so if available, it's better to use the header to validate the type + var contentTypeHeader = xhr.getResponseHeader('content-type'); + if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) { + return xhr.response; + } + if (xhr.response && typeof xhr.response === 'object') { + return xhr.response; + } if (xhr.response && typeof xhr.response === 'string') { + return JSON.parse(xhr.response); + } if (xhr.responseText) { + return JSON.parse(xhr.responseText); + } + return null; + } + + function loadAsset(path, fullPath, callback, errorCallback) { + var response; + var xhr = new XMLHttpRequest(); + // set responseType after calling open or IE will break. + try { + // This crashes on Android WebView prior to KitKat + xhr.responseType = 'json'; + } catch (err) {} // eslint-disable-line no-empty + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + if (xhr.status === 200) { + response = formatResponse(xhr); + callback(response); + } else { + try { + response = formatResponse(xhr); + callback(response); + } catch (err) { + if (errorCallback) { + errorCallback(err); + } + } + } + } + }; + try { + xhr.open('GET', path, true); + } catch (error) { + xhr.open('GET', fullPath + '/' + path, true); + } + xhr.send(); + } + return { + load: loadAsset, + }; + }()); + } + + if (e.data.type === 'loadAnimation') { + _workerSelf.assetLoader.load( + e.data.path, + e.data.fullPath, + function (data) { + _workerSelf.dataManager.completeData(data); + _workerSelf.postMessage({ + id: e.data.id, + payload: data, + status: 'success', + }); + }, + function () { + _workerSelf.postMessage({ + id: e.data.id, + status: 'error', + }); + } + ); + } else if (e.data.type === 'complete') { + var animation = e.data.animation; + _workerSelf.dataManager.completeData(animation); + _workerSelf.postMessage({ + id: e.data.id, + payload: animation, + status: 'success', + }); + } else if (e.data.type === 'loadData') { + _workerSelf.assetLoader.load( + e.data.path, + e.data.fullPath, + function (data) { + _workerSelf.postMessage({ + id: e.data.id, + payload: data, + status: 'success', + }); + }, + function () { + _workerSelf.postMessage({ + id: e.data.id, + status: 'error', + }); + } + ); + } + }); + + workerInstance.onmessage = function (event) { + var data = event.data; + var id = data.id; + var process = processes[id]; + processes[id] = null; + if (data.status === 'success') { + process.onComplete(data.payload); + } else if (process.onError) { + process.onError(); + } + }; + } + } + + function createProcess(onComplete, onError) { + _counterId += 1; + var id = 'processId_' + _counterId; + processes[id] = { + onComplete: onComplete, + onError: onError, + }; + return id; + } + + function loadAnimation(path, onComplete, onError) { + setupWorker(); + var processId = createProcess(onComplete, onError); + workerInstance.postMessage({ + type: 'loadAnimation', + path: path, + fullPath: window.location.origin + window.location.pathname, + id: processId, + }); + } + + function loadData(path, onComplete, onError) { + setupWorker(); + var processId = createProcess(onComplete, onError); + workerInstance.postMessage({ + type: 'loadData', + path: path, + fullPath: window.location.origin + window.location.pathname, + id: processId, + }); + } + + function completeAnimation(anim, onComplete, onError) { + setupWorker(); + var processId = createProcess(onComplete, onError); + workerInstance.postMessage({ + type: 'complete', + animation: anim, + id: processId, + }); + } + + return { + loadAnimation: loadAnimation, + loadData: loadData, + completeAnimation: completeAnimation, + }; +}()); + +const ImagePreloader = (function () { + var proxyImage = (function () { + var canvas = createTag('canvas'); + canvas.width = 1; + canvas.height = 1; + var ctx = canvas.getContext('2d'); + ctx.fillStyle = 'rgba(0,0,0,0)'; + ctx.fillRect(0, 0, 1, 1); + return canvas; + }()); + + function imageLoaded() { + this.loadedAssets += 1; + if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) { + if (this.imagesLoadedCb) { + this.imagesLoadedCb(null); + } + } + } + function footageLoaded() { + this.loadedFootagesCount += 1; + if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) { + if (this.imagesLoadedCb) { + this.imagesLoadedCb(null); + } + } + } + + function getAssetsPath(assetData, assetsPath, originalPath) { + var path = ''; + if (assetData.e) { + path = assetData.p; + } else if (assetsPath) { + var imagePath = assetData.p; + if (imagePath.indexOf('images/') !== -1) { + imagePath = imagePath.split('/')[1]; + } + path = assetsPath + imagePath; + } else { + path = originalPath; + path += assetData.u ? assetData.u : ''; + path += assetData.p; + } + return path; + } + + function testImageLoaded(img) { + var _count = 0; + var intervalId = setInterval(function () { + var box = img.getBBox(); + if (box.width || _count > 500) { + this._imageLoaded(); + clearInterval(intervalId); + } + _count += 1; + }.bind(this), 50); + } + + function createImageData(assetData) { + var path = getAssetsPath(assetData, this.assetsPath, this.path); + var img = createNS('image'); + if (isSafari) { + this.testImageLoaded(img); + } else { + img.addEventListener('load', this._imageLoaded, false); + } + img.addEventListener('error', function () { + ob.img = proxyImage; + this._imageLoaded(); + }.bind(this), false); + img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path); + if (this._elementHelper.append) { + this._elementHelper.append(img); + } else { + this._elementHelper.appendChild(img); + } + var ob = { + img: img, + assetData: assetData, + }; + return ob; + } + + function createImgData(assetData) { + var path = getAssetsPath(assetData, this.assetsPath, this.path); + var img = createTag('img'); + img.crossOrigin = 'anonymous'; + img.addEventListener('load', this._imageLoaded, false); + img.addEventListener('error', function () { + ob.img = proxyImage; + this._imageLoaded(); + }.bind(this), false); + img.src = path; + var ob = { + img: img, + assetData: assetData, + }; + return ob; + } + + function createFootageData(data) { + var ob = { + assetData: data, + }; + var path = getAssetsPath(data, this.assetsPath, this.path); + dataManager.loadData(path, function (footageData) { + ob.img = footageData; + this._footageLoaded(); + }.bind(this), function () { + ob.img = {}; + this._footageLoaded(); + }.bind(this)); + return ob; + } + + function loadAssets(assets, cb) { + this.imagesLoadedCb = cb; + var i; + var len = assets.length; + for (i = 0; i < len; i += 1) { + if (!assets[i].layers) { + if (!assets[i].t || assets[i].t === 'seq') { + this.totalImages += 1; + this.images.push(this._createImageData(assets[i])); + } else if (assets[i].t === 3) { + this.totalFootages += 1; + this.images.push(this.createFootageData(assets[i])); + } + } + } + } + + function setPath(path) { + this.path = path || ''; + } + + function setAssetsPath(path) { + this.assetsPath = path || ''; + } + + function getAsset(assetData) { + var i = 0; + var len = this.images.length; + while (i < len) { + if (this.images[i].assetData === assetData) { + return this.images[i].img; + } + i += 1; + } + return null; + } + + function destroy() { + this.imagesLoadedCb = null; + this.images.length = 0; + } + + function loadedImages() { + return this.totalImages === this.loadedAssets; + } + + function loadedFootages() { + return this.totalFootages === this.loadedFootagesCount; + } + + function setCacheType(type, elementHelper) { + if (type === 'svg') { + this._elementHelper = elementHelper; + this._createImageData = this.createImageData.bind(this); + } else { + this._createImageData = this.createImgData.bind(this); + } + } + + function ImagePreloaderFactory() { + this._imageLoaded = imageLoaded.bind(this); + this._footageLoaded = footageLoaded.bind(this); + this.testImageLoaded = testImageLoaded.bind(this); + this.createFootageData = createFootageData.bind(this); + this.assetsPath = ''; + this.path = ''; + this.totalImages = 0; + this.totalFootages = 0; + this.loadedAssets = 0; + this.loadedFootagesCount = 0; + this.imagesLoadedCb = null; + this.images = []; + } + + ImagePreloaderFactory.prototype = { + loadAssets: loadAssets, + setAssetsPath: setAssetsPath, + setPath: setPath, + loadedImages: loadedImages, + loadedFootages: loadedFootages, + destroy: destroy, + getAsset: getAsset, + createImgData: createImgData, + createImageData: createImageData, + imageLoaded: imageLoaded, + footageLoaded: footageLoaded, + setCacheType: setCacheType, + }; + + return ImagePreloaderFactory; +}()); + +function BaseEvent() {} +BaseEvent.prototype = { + triggerEvent: function (eventName, args) { + if (this._cbs[eventName]) { + var callbacks = this._cbs[eventName]; + for (var i = 0; i < callbacks.length; i += 1) { + callbacks[i](args); + } + } + }, + addEventListener: function (eventName, callback) { + if (!this._cbs[eventName]) { + this._cbs[eventName] = []; + } + this._cbs[eventName].push(callback); + + return function () { + this.removeEventListener(eventName, callback); + }.bind(this); + }, + removeEventListener: function (eventName, callback) { + if (!callback) { + this._cbs[eventName] = null; + } else if (this._cbs[eventName]) { + var i = 0; + var len = this._cbs[eventName].length; + while (i < len) { + if (this._cbs[eventName][i] === callback) { + this._cbs[eventName].splice(i, 1); + i -= 1; + len -= 1; + } + i += 1; + } + if (!this._cbs[eventName].length) { + this._cbs[eventName] = null; + } + } + }, +}; + +const markerParser = ( + + function () { + function parsePayloadLines(payload) { + var lines = payload.split('\r\n'); + var keys = {}; + var line; + var keysCount = 0; + for (var i = 0; i < lines.length; i += 1) { + line = lines[i].split(':'); + if (line.length === 2) { + keys[line[0]] = line[1].trim(); + keysCount += 1; + } + } + if (keysCount === 0) { + throw new Error(); + } + return keys; + } + + return function (_markers) { + var markers = []; + for (var i = 0; i < _markers.length; i += 1) { + var _marker = _markers[i]; + var markerData = { + time: _marker.tm, + duration: _marker.dr, + }; + try { + markerData.payload = JSON.parse(_markers[i].cm); + } catch (_) { + try { + markerData.payload = parsePayloadLines(_markers[i].cm); + } catch (__) { + markerData.payload = { + name: _markers[i].cm, + }; + } + } + markers.push(markerData); + } + return markers; + }; + }()); + +const ProjectInterface = (function () { + function registerComposition(comp) { + this.compositions.push(comp); + } + + return function () { + function _thisProjectFunction(name) { + var i = 0; + var len = this.compositions.length; + while (i < len) { + if (this.compositions[i].data && this.compositions[i].data.nm === name) { + if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) { + this.compositions[i].prepareFrame(this.currentFrame); + } + return this.compositions[i].compInterface; + } + i += 1; + } + return null; + } + + _thisProjectFunction.compositions = []; + _thisProjectFunction.currentFrame = 0; + + _thisProjectFunction.registerComposition = registerComposition; + + return _thisProjectFunction; + }; +}()); + +const renderers = {}; + +const registerRenderer = (key, value) => { + renderers[key] = value; +}; + +function getRenderer(key) { + return renderers[key]; +} + +const AnimationItem = function () { + this._cbs = []; + this.name = ''; + this.path = ''; + this.isLoaded = false; + this.currentFrame = 0; + this.currentRawFrame = 0; + this.firstFrame = 0; + this.totalFrames = 0; + this.frameRate = 0; + this.frameMult = 0; + this.playSpeed = 1; + this.playDirection = 1; + this.playCount = 0; + this.animationData = {}; + this.assets = []; + this.isPaused = true; + this.autoplay = false; + this.loop = true; + this.renderer = null; + this.animationID = createElementID(); + this.assetsPath = ''; + this.timeCompleted = 0; + this.segmentPos = 0; + this.isSubframeEnabled = getSubframeEnabled(); + this.segments = []; + this._idle = true; + this._completedLoop = false; + this.projectInterface = ProjectInterface(); + this.imagePreloader = new ImagePreloader(); + this.audioController = audioControllerFactory(); + this.markers = []; + this.configAnimation = this.configAnimation.bind(this); + this.onSetupError = this.onSetupError.bind(this); + this.onSegmentComplete = this.onSegmentComplete.bind(this); + this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0); +}; + +extendPrototype([BaseEvent], AnimationItem); + +AnimationItem.prototype.setParams = function (params) { + if (params.wrapper || params.container) { + this.wrapper = params.wrapper || params.container; + } + var animType = 'svg'; + if (params.animType) { + animType = params.animType; + } else if (params.renderer) { + animType = params.renderer; + } + const RendererClass = getRenderer(animType); + this.renderer = new RendererClass(this, params.rendererSettings); + this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs); + this.renderer.setProjectInterface(this.projectInterface); + this.animType = animType; + if (params.loop === '' + || params.loop === null + || params.loop === undefined + || params.loop === true) { + this.loop = true; + } else if (params.loop === false) { + this.loop = false; + } else { + this.loop = parseInt(params.loop, 10); + } + this.autoplay = 'autoplay' in params ? params.autoplay : true; + this.name = params.name ? params.name : ''; + this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true; + this.assetsPath = params.assetsPath; + this.initialSegment = params.initialSegment; + if (params.audioFactory) { + this.audioController.setAudioFactory(params.audioFactory); + } + if (params.animationData) { + this.setupAnimation(params.animationData); + } else if (params.path) { + if (params.path.lastIndexOf('\\') !== -1) { + this.path = params.path.substr(0, params.path.lastIndexOf('\\') + 1); + } else { + this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1); + } + this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1); + this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json')); + dataManager.loadAnimation( + params.path, + this.configAnimation, + this.onSetupError + ); + } +}; + +AnimationItem.prototype.onSetupError = function () { + this.trigger('data_failed'); +}; + +AnimationItem.prototype.setupAnimation = function (data) { + dataManager.completeAnimation( + data, + this.configAnimation + ); +}; + +AnimationItem.prototype.setData = function (wrapper, animationData) { + if (animationData) { + if (typeof animationData !== 'object') { + animationData = JSON.parse(animationData); + } + } + var params = { + wrapper: wrapper, + animationData: animationData, + }; + var wrapperAttributes = wrapper.attributes; + + params.path = wrapperAttributes.getNamedItem('data-animation-path') // eslint-disable-line no-nested-ternary + ? wrapperAttributes.getNamedItem('data-animation-path').value + : wrapperAttributes.getNamedItem('data-bm-path') // eslint-disable-line no-nested-ternary + ? wrapperAttributes.getNamedItem('data-bm-path').value + : wrapperAttributes.getNamedItem('bm-path') + ? wrapperAttributes.getNamedItem('bm-path').value + : ''; + params.animType = wrapperAttributes.getNamedItem('data-anim-type') // eslint-disable-line no-nested-ternary + ? wrapperAttributes.getNamedItem('data-anim-type').value + : wrapperAttributes.getNamedItem('data-bm-type') // eslint-disable-line no-nested-ternary + ? wrapperAttributes.getNamedItem('data-bm-type').value + : wrapperAttributes.getNamedItem('bm-type') // eslint-disable-line no-nested-ternary + ? wrapperAttributes.getNamedItem('bm-type').value + : wrapperAttributes.getNamedItem('data-bm-renderer') // eslint-disable-line no-nested-ternary + ? wrapperAttributes.getNamedItem('data-bm-renderer').value + : wrapperAttributes.getNamedItem('bm-renderer') + ? wrapperAttributes.getNamedItem('bm-renderer').value + : 'canvas'; + + var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary + ? wrapperAttributes.getNamedItem('data-anim-loop').value + : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary + ? wrapperAttributes.getNamedItem('data-bm-loop').value + : wrapperAttributes.getNamedItem('bm-loop') + ? wrapperAttributes.getNamedItem('bm-loop').value + : ''; + if (loop === 'false') { + params.loop = false; + } else if (loop === 'true') { + params.loop = true; + } else if (loop !== '') { + params.loop = parseInt(loop, 10); + } + var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary + ? wrapperAttributes.getNamedItem('data-anim-autoplay').value + : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary + ? wrapperAttributes.getNamedItem('data-bm-autoplay').value + : wrapperAttributes.getNamedItem('bm-autoplay') + ? wrapperAttributes.getNamedItem('bm-autoplay').value + : true; + params.autoplay = autoplay !== 'false'; + + params.name = wrapperAttributes.getNamedItem('data-name') // eslint-disable-line no-nested-ternary + ? wrapperAttributes.getNamedItem('data-name').value + : wrapperAttributes.getNamedItem('data-bm-name') // eslint-disable-line no-nested-ternary + ? wrapperAttributes.getNamedItem('data-bm-name').value + : wrapperAttributes.getNamedItem('bm-name') + ? wrapperAttributes.getNamedItem('bm-name').value + : ''; + var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary + ? wrapperAttributes.getNamedItem('data-anim-prerender').value + : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary + ? wrapperAttributes.getNamedItem('data-bm-prerender').value + : wrapperAttributes.getNamedItem('bm-prerender') + ? wrapperAttributes.getNamedItem('bm-prerender').value + : ''; + + if (prerender === 'false') { + params.prerender = false; + } + this.setParams(params); +}; + +AnimationItem.prototype.includeLayers = function (data) { + if (data.op > this.animationData.op) { + this.animationData.op = data.op; + this.totalFrames = Math.floor(data.op - this.animationData.ip); + } + var layers = this.animationData.layers; + var i; + var len = layers.length; + var newLayers = data.layers; + var j; + var jLen = newLayers.length; + for (j = 0; j < jLen; j += 1) { + i = 0; + while (i < len) { + if (layers[i].id === newLayers[j].id) { + layers[i] = newLayers[j]; + break; + } + i += 1; + } + } + if (data.chars || data.fonts) { + this.renderer.globalData.fontManager.addChars(data.chars); + this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs); + } + if (data.assets) { + len = data.assets.length; + for (i = 0; i < len; i += 1) { + this.animationData.assets.push(data.assets[i]); + } + } + this.animationData.__complete = false; + dataManager.completeAnimation( + this.animationData, + this.onSegmentComplete + ); +}; + +AnimationItem.prototype.onSegmentComplete = function (data) { + this.animationData = data; + var expressionsPlugin = getExpressionsPlugin(); + if (expressionsPlugin) { + expressionsPlugin.initExpressions(this); + } + this.loadNextSegment(); +}; + +AnimationItem.prototype.loadNextSegment = function () { + var segments = this.animationData.segments; + if (!segments || segments.length === 0 || !this.autoloadSegments) { + this.trigger('data_ready'); + this.timeCompleted = this.totalFrames; + return; + } + var segment = segments.shift(); + this.timeCompleted = segment.time * this.frameRate; + var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json'; + this.segmentPos += 1; + dataManager.loadData(segmentPath, this.includeLayers.bind(this), function () { + this.trigger('data_failed'); + }.bind(this)); +}; + +AnimationItem.prototype.loadSegments = function () { + var segments = this.animationData.segments; + if (!segments) { + this.timeCompleted = this.totalFrames; + } + this.loadNextSegment(); +}; + +AnimationItem.prototype.imagesLoaded = function () { + this.trigger('loaded_images'); + this.checkLoaded(); +}; + +AnimationItem.prototype.preloadImages = function () { + this.imagePreloader.setAssetsPath(this.assetsPath); + this.imagePreloader.setPath(this.path); + this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this)); +}; + +AnimationItem.prototype.configAnimation = function (animData) { + if (!this.renderer) { + return; + } + try { + this.animationData = animData; + if (this.initialSegment) { + this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]); + this.firstFrame = Math.round(this.initialSegment[0]); + } else { + this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip); + this.firstFrame = Math.round(this.animationData.ip); + } + this.renderer.configAnimation(animData); + if (!animData.assets) { + animData.assets = []; + } + + this.assets = this.animationData.assets; + this.frameRate = this.animationData.fr; + this.frameMult = this.animationData.fr / 1000; + this.renderer.searchExtraCompositions(animData.assets); + this.markers = markerParser(animData.markers || []); + this.trigger('config_ready'); + this.preloadImages(); + this.loadSegments(); + this.updaFrameModifier(); + this.waitForFontsLoaded(); + if (this.isPaused) { + this.audioController.pause(); + } + } catch (error) { + this.triggerConfigError(error); + } +}; + +AnimationItem.prototype.waitForFontsLoaded = function () { + if (!this.renderer) { + return; + } + if (this.renderer.globalData.fontManager.isLoaded) { + this.checkLoaded(); + } else { + setTimeout(this.waitForFontsLoaded.bind(this), 20); + } +}; + +AnimationItem.prototype.checkLoaded = function () { + if (!this.isLoaded + && this.renderer.globalData.fontManager.isLoaded + && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas') + && (this.imagePreloader.loadedFootages()) + ) { + this.isLoaded = true; + var expressionsPlugin = getExpressionsPlugin(); + if (expressionsPlugin) { + expressionsPlugin.initExpressions(this); + } + this.renderer.initItems(); + setTimeout(function () { + this.trigger('DOMLoaded'); + }.bind(this), 0); + this.gotoFrame(); + if (this.autoplay) { + this.play(); + } + } +}; + +AnimationItem.prototype.resize = function () { + this.renderer.updateContainerSize(); +}; + +AnimationItem.prototype.setSubframe = function (flag) { + this.isSubframeEnabled = !!flag; +}; + +AnimationItem.prototype.gotoFrame = function () { + this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise + + if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) { + this.currentFrame = this.timeCompleted; + } + this.trigger('enterFrame'); + this.renderFrame(); + this.trigger('drawnFrame'); +}; + +AnimationItem.prototype.renderFrame = function () { + if (this.isLoaded === false || !this.renderer) { + return; + } + try { + this.renderer.renderFrame(this.currentFrame + this.firstFrame); + } catch (error) { + this.triggerRenderFrameError(error); + } +}; + +AnimationItem.prototype.play = function (name) { + if (name && this.name !== name) { + return; + } + if (this.isPaused === true) { + this.isPaused = false; + this.trigger('_pause'); + this.audioController.resume(); + if (this._idle) { + this._idle = false; + this.trigger('_active'); + } + } +}; + +AnimationItem.prototype.pause = function (name) { + if (name && this.name !== name) { + return; + } + if (this.isPaused === false) { + this.isPaused = true; + this.trigger('_play'); + this._idle = true; + this.trigger('_idle'); + this.audioController.pause(); + } +}; + +AnimationItem.prototype.togglePause = function (name) { + if (name && this.name !== name) { + return; + } + if (this.isPaused === true) { + this.play(); + } else { + this.pause(); + } +}; + +AnimationItem.prototype.stop = function (name) { + if (name && this.name !== name) { + return; + } + this.pause(); + this.playCount = 0; + this._completedLoop = false; + this.setCurrentRawFrameValue(0); +}; + +AnimationItem.prototype.getMarkerData = function (markerName) { + var marker; + for (var i = 0; i < this.markers.length; i += 1) { + marker = this.markers[i]; + if (marker.payload && marker.payload.name === markerName) { + return marker; + } + } + return null; +}; + +AnimationItem.prototype.goToAndStop = function (value, isFrame, name) { + if (name && this.name !== name) { + return; + } + var numValue = Number(value); + if (isNaN(numValue)) { + var marker = this.getMarkerData(value); + if (marker) { + this.goToAndStop(marker.time, true); + } + } else if (isFrame) { + this.setCurrentRawFrameValue(value); + } else { + this.setCurrentRawFrameValue(value * this.frameModifier); + } + this.pause(); +}; + +AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) { + if (name && this.name !== name) { + return; + } + var numValue = Number(value); + if (isNaN(numValue)) { + var marker = this.getMarkerData(value); + if (marker) { + if (!marker.duration) { + this.goToAndStop(marker.time, true); + } else { + this.playSegments([marker.time, marker.time + marker.duration], true); + } + } + } else { + this.goToAndStop(numValue, isFrame, name); + } + this.play(); +}; + +AnimationItem.prototype.advanceTime = function (value) { + if (this.isPaused === true || this.isLoaded === false) { + return; + } + var nextValue = this.currentRawFrame + value * this.frameModifier; + var _isComplete = false; + // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations. + // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop. + if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) { + if (!this.loop || this.playCount === this.loop) { + if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) { + _isComplete = true; + nextValue = this.totalFrames - 1; + } + } else if (nextValue >= this.totalFrames) { + this.playCount += 1; + if (!this.checkSegments(nextValue % this.totalFrames)) { + this.setCurrentRawFrameValue(nextValue % this.totalFrames); + this._completedLoop = true; + this.trigger('loopComplete'); + } + } else { + this.setCurrentRawFrameValue(nextValue); + } + } else if (nextValue < 0) { + if (!this.checkSegments(nextValue % this.totalFrames)) { + if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) { // eslint-disable-line no-plusplus + this.setCurrentRawFrameValue(this.totalFrames + (nextValue % this.totalFrames)); + if (!this._completedLoop) { + this._completedLoop = true; + } else { + this.trigger('loopComplete'); + } + } else { + _isComplete = true; + nextValue = 0; + } + } + } else { + this.setCurrentRawFrameValue(nextValue); + } + if (_isComplete) { + this.setCurrentRawFrameValue(nextValue); + this.pause(); + this.trigger('complete'); + } +}; + +AnimationItem.prototype.adjustSegment = function (arr, offset) { + this.playCount = 0; + if (arr[1] < arr[0]) { + if (this.frameModifier > 0) { + if (this.playSpeed < 0) { + this.setSpeed(-this.playSpeed); + } else { + this.setDirection(-1); + } + } + this.totalFrames = arr[0] - arr[1]; + this.timeCompleted = this.totalFrames; + this.firstFrame = arr[1]; + this.setCurrentRawFrameValue(this.totalFrames - 0.001 - offset); + } else if (arr[1] > arr[0]) { + if (this.frameModifier < 0) { + if (this.playSpeed < 0) { + this.setSpeed(-this.playSpeed); + } else { + this.setDirection(1); + } + } + this.totalFrames = arr[1] - arr[0]; + this.timeCompleted = this.totalFrames; + this.firstFrame = arr[0]; + this.setCurrentRawFrameValue(0.001 + offset); + } + this.trigger('segmentStart'); +}; +AnimationItem.prototype.setSegment = function (init, end) { + var pendingFrame = -1; + if (this.isPaused) { + if (this.currentRawFrame + this.firstFrame < init) { + pendingFrame = init; + } else if (this.currentRawFrame + this.firstFrame > end) { + pendingFrame = end - init; + } + } + + this.firstFrame = init; + this.totalFrames = end - init; + this.timeCompleted = this.totalFrames; + if (pendingFrame !== -1) { + this.goToAndStop(pendingFrame, true); + } +}; + +AnimationItem.prototype.playSegments = function (arr, forceFlag) { + if (forceFlag) { + this.segments.length = 0; + } + if (typeof arr[0] === 'object') { + var i; + var len = arr.length; + for (i = 0; i < len; i += 1) { + this.segments.push(arr[i]); + } + } else { + this.segments.push(arr); + } + if (this.segments.length && forceFlag) { + this.adjustSegment(this.segments.shift(), 0); + } + if (this.isPaused) { + this.play(); + } +}; + +AnimationItem.prototype.resetSegments = function (forceFlag) { + this.segments.length = 0; + this.segments.push([this.animationData.ip, this.animationData.op]); + if (forceFlag) { + this.checkSegments(0); + } +}; +AnimationItem.prototype.checkSegments = function (offset) { + if (this.segments.length) { + this.adjustSegment(this.segments.shift(), offset); + return true; + } + return false; +}; + +AnimationItem.prototype.destroy = function (name) { + if ((name && this.name !== name) || !this.renderer) { + return; + } + this.renderer.destroy(); + this.imagePreloader.destroy(); + this.trigger('destroy'); + this._cbs = null; + this.onEnterFrame = null; + this.onLoopComplete = null; + this.onComplete = null; + this.onSegmentStart = null; + this.onDestroy = null; + this.renderer = null; + this.renderer = null; + this.imagePreloader = null; + this.projectInterface = null; +}; + +AnimationItem.prototype.setCurrentRawFrameValue = function (value) { + this.currentRawFrame = value; + this.gotoFrame(); +}; + +AnimationItem.prototype.setSpeed = function (val) { + this.playSpeed = val; + this.updaFrameModifier(); +}; + +AnimationItem.prototype.setDirection = function (val) { + this.playDirection = val < 0 ? -1 : 1; + this.updaFrameModifier(); +}; + +AnimationItem.prototype.setVolume = function (val, name) { + if (name && this.name !== name) { + return; + } + this.audioController.setVolume(val); +}; + +AnimationItem.prototype.getVolume = function () { + return this.audioController.getVolume(); +}; + +AnimationItem.prototype.mute = function (name) { + if (name && this.name !== name) { + return; + } + this.audioController.mute(); +}; + +AnimationItem.prototype.unmute = function (name) { + if (name && this.name !== name) { + return; + } + this.audioController.unmute(); +}; + +AnimationItem.prototype.updaFrameModifier = function () { + this.frameModifier = this.frameMult * this.playSpeed * this.playDirection; + this.audioController.setRate(this.playSpeed * this.playDirection); +}; + +AnimationItem.prototype.getPath = function () { + return this.path; +}; + +AnimationItem.prototype.getAssetsPath = function (assetData) { + var path = ''; + if (assetData.e) { + path = assetData.p; + } else if (this.assetsPath) { + var imagePath = assetData.p; + if (imagePath.indexOf('images/') !== -1) { + imagePath = imagePath.split('/')[1]; + } + path = this.assetsPath + imagePath; + } else { + path = this.path; + path += assetData.u ? assetData.u : ''; + path += assetData.p; + } + return path; +}; + +AnimationItem.prototype.getAssetData = function (id) { + var i = 0; + var len = this.assets.length; + while (i < len) { + if (id === this.assets[i].id) { + return this.assets[i]; + } + i += 1; + } + return null; +}; + +AnimationItem.prototype.hide = function () { + this.renderer.hide(); +}; + +AnimationItem.prototype.show = function () { + this.renderer.show(); +}; + +AnimationItem.prototype.getDuration = function (isFrame) { + return isFrame ? this.totalFrames : this.totalFrames / this.frameRate; +}; + +AnimationItem.prototype.updateDocumentData = function (path, documentData, index) { + try { + var element = this.renderer.getElementByPath(path); + element.updateDocumentData(documentData, index); + } catch (error) { + // TODO: decide how to handle catch case + } +}; + +AnimationItem.prototype.trigger = function (name) { + if (this._cbs && this._cbs[name]) { + switch (name) { + case 'enterFrame': + this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier)); + break; + case 'drawnFrame': + this.drawnFrameEvent.currentTime = this.currentFrame; + this.drawnFrameEvent.totalTime = this.totalFrames; + this.drawnFrameEvent.direction = this.frameModifier; + this.triggerEvent(name, this.drawnFrameEvent); + break; + case 'loopComplete': + this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult)); + break; + case 'complete': + this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult)); + break; + case 'segmentStart': + this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames)); + break; + case 'destroy': + this.triggerEvent(name, new BMDestroyEvent(name, this)); + break; + default: + this.triggerEvent(name); + } + } + if (name === 'enterFrame' && this.onEnterFrame) { + this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult)); + } + if (name === 'loopComplete' && this.onLoopComplete) { + this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult)); + } + if (name === 'complete' && this.onComplete) { + this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult)); + } + if (name === 'segmentStart' && this.onSegmentStart) { + this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames)); + } + if (name === 'destroy' && this.onDestroy) { + this.onDestroy.call(this, new BMDestroyEvent(name, this)); + } +}; + +AnimationItem.prototype.triggerRenderFrameError = function (nativeError) { + var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame); + this.triggerEvent('error', error); + + if (this.onError) { + this.onError.call(this, error); + } +}; + +AnimationItem.prototype.triggerConfigError = function (nativeError) { + var error = new BMConfigErrorEvent(nativeError, this.currentFrame); + this.triggerEvent('error', error); + + if (this.onError) { + this.onError.call(this, error); + } +}; + +const animationManager = (function () { + var moduleOb = {}; + var registeredAnimations = []; + var initTime = 0; + var len = 0; + var playingAnimationsNum = 0; + var _stopped = true; + var _isFrozen = false; + + function removeElement(ev) { + var i = 0; + var animItem = ev.target; + while (i < len) { + if (registeredAnimations[i].animation === animItem) { + registeredAnimations.splice(i, 1); + i -= 1; + len -= 1; + if (!animItem.isPaused) { + subtractPlayingCount(); + } + } + i += 1; + } + } + + function registerAnimation(element, animationData) { + if (!element) { + return null; + } + var i = 0; + while (i < len) { + if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) { + return registeredAnimations[i].animation; + } + i += 1; + } + var animItem = new AnimationItem(); + setupAnimation(animItem, element); + animItem.setData(element, animationData); + return animItem; + } + + function getRegisteredAnimations() { + var i; + var lenAnims = registeredAnimations.length; + var animations = []; + for (i = 0; i < lenAnims; i += 1) { + animations.push(registeredAnimations[i].animation); + } + return animations; + } + + function addPlayingCount() { + playingAnimationsNum += 1; + activate(); + } + + function subtractPlayingCount() { + playingAnimationsNum -= 1; + } + + function setupAnimation(animItem, element) { + animItem.addEventListener('destroy', removeElement); + animItem.addEventListener('_active', addPlayingCount); + animItem.addEventListener('_idle', subtractPlayingCount); + registeredAnimations.push({ elem: element, animation: animItem }); + len += 1; + } + + function loadAnimation(params) { + var animItem = new AnimationItem(); + setupAnimation(animItem, null); + animItem.setParams(params); + return animItem; + } + + function setSpeed(val, animation) { + var i; + for (i = 0; i < len; i += 1) { + registeredAnimations[i].animation.setSpeed(val, animation); + } + } + + function setDirection(val, animation) { + var i; + for (i = 0; i < len; i += 1) { + registeredAnimations[i].animation.setDirection(val, animation); + } + } + + function play(animation) { + var i; + for (i = 0; i < len; i += 1) { + registeredAnimations[i].animation.play(animation); + } + } + function resume(nowTime) { + var elapsedTime = nowTime - initTime; + var i; + for (i = 0; i < len; i += 1) { + registeredAnimations[i].animation.advanceTime(elapsedTime); + } + initTime = nowTime; + if (playingAnimationsNum && !_isFrozen) { + window.requestAnimationFrame(resume); + } else { + _stopped = true; + } + } + + function first(nowTime) { + initTime = nowTime; + window.requestAnimationFrame(resume); + } + + function pause(animation) { + var i; + for (i = 0; i < len; i += 1) { + registeredAnimations[i].animation.pause(animation); + } + } + + function goToAndStop(value, isFrame, animation) { + var i; + for (i = 0; i < len; i += 1) { + registeredAnimations[i].animation.goToAndStop(value, isFrame, animation); + } + } + + function stop(animation) { + var i; + for (i = 0; i < len; i += 1) { + registeredAnimations[i].animation.stop(animation); + } + } + + function togglePause(animation) { + var i; + for (i = 0; i < len; i += 1) { + registeredAnimations[i].animation.togglePause(animation); + } + } + + function destroy(animation) { + var i; + for (i = (len - 1); i >= 0; i -= 1) { + registeredAnimations[i].animation.destroy(animation); + } + } + + function searchAnimations(animationData, standalone, renderer) { + var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')), + [].slice.call(document.getElementsByClassName('bodymovin'))); + var i; + var lenAnims = animElements.length; + for (i = 0; i < lenAnims; i += 1) { + if (renderer) { + animElements[i].setAttribute('data-bm-type', renderer); + } + registerAnimation(animElements[i], animationData); + } + if (standalone && lenAnims === 0) { + if (!renderer) { + renderer = 'svg'; + } + var body = document.getElementsByTagName('body')[0]; + body.innerText = ''; + var div = createTag('div'); + div.style.width = '100%'; + div.style.height = '100%'; + div.setAttribute('data-bm-type', renderer); + body.appendChild(div); + registerAnimation(div, animationData); + } + } + + function resize() { + var i; + for (i = 0; i < len; i += 1) { + registeredAnimations[i].animation.resize(); + } + } + + function activate() { + if (!_isFrozen && playingAnimationsNum) { + if (_stopped) { + window.requestAnimationFrame(first); + _stopped = false; + } + } + } + + function freeze() { + _isFrozen = true; + } + + function unfreeze() { + _isFrozen = false; + activate(); + } + + function setVolume(val, animation) { + var i; + for (i = 0; i < len; i += 1) { + registeredAnimations[i].animation.setVolume(val, animation); + } + } + + function mute(animation) { + var i; + for (i = 0; i < len; i += 1) { + registeredAnimations[i].animation.mute(animation); + } + } + + function unmute(animation) { + var i; + for (i = 0; i < len; i += 1) { + registeredAnimations[i].animation.unmute(animation); + } + } + + moduleOb.registerAnimation = registerAnimation; + moduleOb.loadAnimation = loadAnimation; + moduleOb.setSpeed = setSpeed; + moduleOb.setDirection = setDirection; + moduleOb.play = play; + moduleOb.pause = pause; + moduleOb.stop = stop; + moduleOb.togglePause = togglePause; + moduleOb.searchAnimations = searchAnimations; + moduleOb.resize = resize; + // moduleOb.start = start; + moduleOb.goToAndStop = goToAndStop; + moduleOb.destroy = destroy; + moduleOb.freeze = freeze; + moduleOb.unfreeze = unfreeze; + moduleOb.setVolume = setVolume; + moduleOb.mute = mute; + moduleOb.unmute = unmute; + moduleOb.getRegisteredAnimations = getRegisteredAnimations; + return moduleOb; +}()); + +/* eslint-disable */ +const BezierFactory = (function () { + /** + * BezierEasing - use bezier curve for transition easing function + * by Gaëtan Renaudeau 2014 - 2015 – MIT License + * + * Credits: is based on Firefox's nsSMILKeySpline.cpp + * Usage: + * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ]) + * spline.get(x) => returns the easing value | x must be in [0, 1] range + * + */ + + var ob = {}; + ob.getBezierEasing = getBezierEasing; + var beziers = {}; + + function getBezierEasing(a, b, c, d, nm) { + var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p'); + if (beziers[str]) { + return beziers[str]; + } + var bezEasing = new BezierEasing([a, b, c, d]); + beziers[str] = bezEasing; + return bezEasing; + } + + // These values are established by empiricism with tests (tradeoff: performance VS precision) + var NEWTON_ITERATIONS = 4; + var NEWTON_MIN_SLOPE = 0.001; + var SUBDIVISION_PRECISION = 0.0000001; + var SUBDIVISION_MAX_ITERATIONS = 10; + + var kSplineTableSize = 11; + var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0); + + var float32ArraySupported = typeof Float32Array === 'function'; + + function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; } + function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; } + function C(aA1) { return 3.0 * aA1; } + + // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2. + function calcBezier(aT, aA1, aA2) { + return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; + } + + // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2. + function getSlope(aT, aA1, aA2) { + return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); + } + + function binarySubdivide(aX, aA, aB, mX1, mX2) { + var currentX, + currentT, + i = 0; + do { + currentT = aA + (aB - aA) / 2.0; + currentX = calcBezier(currentT, mX1, mX2) - aX; + if (currentX > 0.0) { + aB = currentT; + } else { + aA = currentT; + } + } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS); + return currentT; + } + + function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) { + for (var i = 0; i < NEWTON_ITERATIONS; ++i) { + var currentSlope = getSlope(aGuessT, mX1, mX2); + if (currentSlope === 0.0) return aGuessT; + var currentX = calcBezier(aGuessT, mX1, mX2) - aX; + aGuessT -= currentX / currentSlope; + } + return aGuessT; + } + + /** + * points is an array of [ mX1, mY1, mX2, mY2 ] + */ + function BezierEasing(points) { + this._p = points; + this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize); + this._precomputed = false; + + this.get = this.get.bind(this); + } + + BezierEasing.prototype = { + + get: function (x) { + var mX1 = this._p[0], + mY1 = this._p[1], + mX2 = this._p[2], + mY2 = this._p[3]; + if (!this._precomputed) this._precompute(); + if (mX1 === mY1 && mX2 === mY2) return x; // linear + // Because JavaScript number are imprecise, we should guarantee the extremes are right. + if (x === 0) return 0; + if (x === 1) return 1; + return calcBezier(this._getTForX(x), mY1, mY2); + }, + + // Private part + + _precompute: function () { + var mX1 = this._p[0], + mY1 = this._p[1], + mX2 = this._p[2], + mY2 = this._p[3]; + this._precomputed = true; + if (mX1 !== mY1 || mX2 !== mY2) { this._calcSampleValues(); } + }, + + _calcSampleValues: function () { + var mX1 = this._p[0], + mX2 = this._p[2]; + for (var i = 0; i < kSplineTableSize; ++i) { + this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2); + } + }, + + /** + * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection. + */ + _getTForX: function (aX) { + var mX1 = this._p[0], + mX2 = this._p[2], + mSampleValues = this._mSampleValues; + + var intervalStart = 0.0; + var currentSample = 1; + var lastSample = kSplineTableSize - 1; + + for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) { + intervalStart += kSampleStepSize; + } + --currentSample; + + // Interpolate to provide an initial guess for t + var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]); + var guessForT = intervalStart + dist * kSampleStepSize; + + var initialSlope = getSlope(guessForT, mX1, mX2); + if (initialSlope >= NEWTON_MIN_SLOPE) { + return newtonRaphsonIterate(aX, guessForT, mX1, mX2); + } if (initialSlope === 0.0) { + return guessForT; + } + return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2); + }, + }; + + return ob; +}()); + +const pooling = (function () { + function double(arr) { + return arr.concat(createSizedArray(arr.length)); + } + + return { + double: double, + }; +}()); + +const poolFactory = (function () { + return function (initialLength, _create, _release) { + var _length = 0; + var _maxLength = initialLength; + var pool = createSizedArray(_maxLength); + + var ob = { + newElement: newElement, + release: release, + }; + + function newElement() { + var element; + if (_length) { + _length -= 1; + element = pool[_length]; + } else { + element = _create(); + } + return element; + } + + function release(element) { + if (_length === _maxLength) { + pool = pooling.double(pool); + _maxLength *= 2; + } + if (_release) { + _release(element); + } + pool[_length] = element; + _length += 1; + } + + return ob; + }; +}()); + +const bezierLengthPool = (function () { + function create() { + return { + addedLength: 0, + percents: createTypedArray('float32', getDefaultCurveSegments()), + lengths: createTypedArray('float32', getDefaultCurveSegments()), + }; + } + return poolFactory(8, create); +}()); + +const segmentsLengthPool = (function () { + function create() { + return { + lengths: [], + totalLength: 0, + }; + } + + function release(element) { + var i; + var len = element.lengths.length; + for (i = 0; i < len; i += 1) { + bezierLengthPool.release(element.lengths[i]); + } + element.lengths.length = 0; + } + + return poolFactory(8, create, release); +}()); + +function bezFunction() { + var math = Math; + + function pointOnLine2D(x1, y1, x2, y2, x3, y3) { + var det1 = (x1 * y2) + (y1 * x3) + (x2 * y3) - (x3 * y2) - (y3 * x1) - (x2 * y1); + return det1 > -0.001 && det1 < 0.001; + } + + function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) { + if (z1 === 0 && z2 === 0 && z3 === 0) { + return pointOnLine2D(x1, y1, x2, y2, x3, y3); + } + var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2)); + var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2)); + var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2)); + var diffDist; + if (dist1 > dist2) { + if (dist1 > dist3) { + diffDist = dist1 - dist2 - dist3; + } else { + diffDist = dist3 - dist2 - dist1; + } + } else if (dist3 > dist2) { + diffDist = dist3 - dist2 - dist1; + } else { + diffDist = dist2 - dist1 - dist3; + } + return diffDist > -0.0001 && diffDist < 0.0001; + } + + var getBezierLength = (function () { + return function (pt1, pt2, pt3, pt4) { + var curveSegments = getDefaultCurveSegments(); + var k; + var i; + var len; + var ptCoord; + var perc; + var addedLength = 0; + var ptDistance; + var point = []; + var lastPoint = []; + var lengthData = bezierLengthPool.newElement(); + len = pt3.length; + for (k = 0; k < curveSegments; k += 1) { + perc = k / (curveSegments - 1); + ptDistance = 0; + for (i = 0; i < len; i += 1) { + ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i]; + point[i] = ptCoord; + if (lastPoint[i] !== null) { + ptDistance += bmPow(point[i] - lastPoint[i], 2); + } + lastPoint[i] = point[i]; + } + if (ptDistance) { + ptDistance = bmSqrt(ptDistance); + addedLength += ptDistance; + } + lengthData.percents[k] = perc; + lengthData.lengths[k] = addedLength; + } + lengthData.addedLength = addedLength; + return lengthData; + }; + }()); + + function getSegmentsLength(shapeData) { + var segmentsLength = segmentsLengthPool.newElement(); + var closed = shapeData.c; + var pathV = shapeData.v; + var pathO = shapeData.o; + var pathI = shapeData.i; + var i; + var len = shapeData._length; + var lengths = segmentsLength.lengths; + var totalLength = 0; + for (i = 0; i < len - 1; i += 1) { + lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]); + totalLength += lengths[i].addedLength; + } + if (closed && len) { + lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]); + totalLength += lengths[i].addedLength; + } + segmentsLength.totalLength = totalLength; + return segmentsLength; + } + + function BezierData(length) { + this.segmentLength = 0; + this.points = new Array(length); + } + + function PointData(partial, point) { + this.partialLength = partial; + this.point = point; + } + + var buildBezierData = (function () { + var storedData = {}; + + return function (pt1, pt2, pt3, pt4) { + var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p'); + if (!storedData[bezierName]) { + var curveSegments = getDefaultCurveSegments(); + var k; + var i; + var len; + var ptCoord; + var perc; + var addedLength = 0; + var ptDistance; + var point; + var lastPoint = null; + if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) { + curveSegments = 2; + } + var bezierData = new BezierData(curveSegments); + len = pt3.length; + for (k = 0; k < curveSegments; k += 1) { + point = createSizedArray(len); + perc = k / (curveSegments - 1); + ptDistance = 0; + for (i = 0; i < len; i += 1) { + ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i]; + point[i] = ptCoord; + if (lastPoint !== null) { + ptDistance += bmPow(point[i] - lastPoint[i], 2); + } + } + ptDistance = bmSqrt(ptDistance); + addedLength += ptDistance; + bezierData.points[k] = new PointData(ptDistance, point); + lastPoint = point; + } + bezierData.segmentLength = addedLength; + storedData[bezierName] = bezierData; + } + return storedData[bezierName]; + }; + }()); + + function getDistancePerc(perc, bezierData) { + var percents = bezierData.percents; + var lengths = bezierData.lengths; + var len = percents.length; + var initPos = bmFloor((len - 1) * perc); + var lengthPos = perc * bezierData.addedLength; + var lPerc = 0; + if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) { + return percents[initPos]; + } + var dir = lengths[initPos] > lengthPos ? -1 : 1; + var flag = true; + while (flag) { + if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) { + lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]); + flag = false; + } else { + initPos += dir; + } + if (initPos < 0 || initPos >= len - 1) { + // FIX for TypedArrays that don't store floating point values with enough accuracy + if (initPos === len - 1) { + return percents[initPos]; + } + flag = false; + } + } + return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc; + } + + function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) { + var t1 = getDistancePerc(percent, bezierData); + var u1 = 1 - t1; + var ptX = math.round((u1 * u1 * u1 * pt1[0] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[0] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[0] + t1 * t1 * t1 * pt2[0]) * 1000) / 1000; + var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000; + return [ptX, ptY]; + } + + var bezierSegmentPoints = createTypedArray('float32', 8); + + function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) { + if (startPerc < 0) { + startPerc = 0; + } else if (startPerc > 1) { + startPerc = 1; + } + var t0 = getDistancePerc(startPerc, bezierData); + endPerc = endPerc > 1 ? 1 : endPerc; + var t1 = getDistancePerc(endPerc, bezierData); + var i; + var len = pt1.length; + var u0 = 1 - t0; + var u1 = 1 - t1; + var u0u0u0 = u0 * u0 * u0; + var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase + var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase + var t0t0t0 = t0 * t0 * t0; + // + var u0u0u1 = u0 * u0 * u1; + var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase + var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase + var t0t0t1 = t0 * t0 * t1; + // + var u0u1u1 = u0 * u1 * u1; + var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase + var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase + var t0t1t1 = t0 * t1 * t1; + // + var u1u1u1 = u1 * u1 * u1; + var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase + var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase + var t1t1t1 = t1 * t1 * t1; + for (i = 0; i < len; i += 1) { + bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase + bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase + bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase + bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase + } + + return bezierSegmentPoints; + } + + return { + getSegmentsLength: getSegmentsLength, + getNewSegment: getNewSegment, + getPointInSegment: getPointInSegment, + buildBezierData: buildBezierData, + pointOnLine2D: pointOnLine2D, + pointOnLine3D: pointOnLine3D, + }; +} + +const bez = bezFunction(); + +const PropertyFactory = (function () { + var initFrame = initialDefaultFrame; + var mathAbs = Math.abs; + + function interpolateValue(frameNum, caching) { + var offsetTime = this.offsetTime; + var newValue; + if (this.propType === 'multidimensional') { + newValue = createTypedArray('float32', this.pv.length); + } + var iterationIndex = caching.lastIndex; + var i = iterationIndex; + var len = this.keyframes.length - 1; + var flag = true; + var keyData; + var nextKeyData; + var keyframeMetadata; + + while (flag) { + keyData = this.keyframes[i]; + nextKeyData = this.keyframes[i + 1]; + if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) { + if (keyData.h) { + keyData = nextKeyData; + } + iterationIndex = 0; + break; + } + if ((nextKeyData.t - offsetTime) > frameNum) { + iterationIndex = i; + break; + } + if (i < len - 1) { + i += 1; + } else { + iterationIndex = 0; + flag = false; + } + } + keyframeMetadata = this.keyframesMetadata[i] || {}; + + var k; + var kLen; + var perc; + var jLen; + var j; + var fnc; + var nextKeyTime = nextKeyData.t - offsetTime; + var keyTime = keyData.t - offsetTime; + var endValue; + if (keyData.to) { + if (!keyframeMetadata.bezierData) { + keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti); + } + var bezierData = keyframeMetadata.bezierData; + if (frameNum >= nextKeyTime || frameNum < keyTime) { + var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0; + kLen = bezierData.points[ind].point.length; + for (k = 0; k < kLen; k += 1) { + newValue[k] = bezierData.points[ind].point[k]; + } + // caching._lastKeyframeIndex = -1; + } else { + if (keyframeMetadata.__fnct) { + fnc = keyframeMetadata.__fnct; + } else { + fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get; + keyframeMetadata.__fnct = fnc; + } + perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime)); + var distanceInLine = bezierData.segmentLength * perc; + + var segmentPerc; + var addedLength = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastAddedLength : 0; + j = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastPoint : 0; + flag = true; + jLen = bezierData.points.length; + while (flag) { + addedLength += bezierData.points[j].partialLength; + if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) { + kLen = bezierData.points[j].point.length; + for (k = 0; k < kLen; k += 1) { + newValue[k] = bezierData.points[j].point[k]; + } + break; + } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) { + segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength; + kLen = bezierData.points[j].point.length; + for (k = 0; k < kLen; k += 1) { + newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc; + } + break; + } + if (j < jLen - 1) { + j += 1; + } else { + flag = false; + } + } + caching._lastPoint = j; + caching._lastAddedLength = addedLength - bezierData.points[j].partialLength; + caching._lastKeyframeIndex = i; + } + } else { + var outX; + var outY; + var inX; + var inY; + var keyValue; + len = keyData.s.length; + endValue = nextKeyData.s || keyData.e; + if (this.sh && keyData.h !== 1) { + if (frameNum >= nextKeyTime) { + newValue[0] = endValue[0]; + newValue[1] = endValue[1]; + newValue[2] = endValue[2]; + } else if (frameNum <= keyTime) { + newValue[0] = keyData.s[0]; + newValue[1] = keyData.s[1]; + newValue[2] = keyData.s[2]; + } else { + var quatStart = createQuaternion(keyData.s); + var quatEnd = createQuaternion(endValue); + var time = (frameNum - keyTime) / (nextKeyTime - keyTime); + quaternionToEuler(newValue, slerp(quatStart, quatEnd, time)); + } + } else { + for (i = 0; i < len; i += 1) { + if (keyData.h !== 1) { + if (frameNum >= nextKeyTime) { + perc = 1; + } else if (frameNum < keyTime) { + perc = 0; + } else { + if (keyData.o.x.constructor === Array) { + if (!keyframeMetadata.__fnct) { + keyframeMetadata.__fnct = []; + } + if (!keyframeMetadata.__fnct[i]) { + outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i]; + outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i]; + inX = keyData.i.x[i] === undefined ? keyData.i.x[0] : keyData.i.x[i]; + inY = keyData.i.y[i] === undefined ? keyData.i.y[0] : keyData.i.y[i]; + fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get; + keyframeMetadata.__fnct[i] = fnc; + } else { + fnc = keyframeMetadata.__fnct[i]; + } + } else if (!keyframeMetadata.__fnct) { + outX = keyData.o.x; + outY = keyData.o.y; + inX = keyData.i.x; + inY = keyData.i.y; + fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get; + keyData.keyframeMetadata = fnc; + } else { + fnc = keyframeMetadata.__fnct; + } + perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime)); + } + } + + endValue = nextKeyData.s || keyData.e; + keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc; + + if (this.propType === 'multidimensional') { + newValue[i] = keyValue; + } else { + newValue = keyValue; + } + } + } + } + caching.lastIndex = iterationIndex; + return newValue; + } + + // based on @Toji's https://github.com/toji/gl-matrix/ + function slerp(a, b, t) { + var out = []; + var ax = a[0]; + var ay = a[1]; + var az = a[2]; + var aw = a[3]; + var bx = b[0]; + var by = b[1]; + var bz = b[2]; + var bw = b[3]; + + var omega; + var cosom; + var sinom; + var scale0; + var scale1; + + cosom = ax * bx + ay * by + az * bz + aw * bw; + if (cosom < 0.0) { + cosom = -cosom; + bx = -bx; + by = -by; + bz = -bz; + bw = -bw; + } + if ((1.0 - cosom) > 0.000001) { + omega = Math.acos(cosom); + sinom = Math.sin(omega); + scale0 = Math.sin((1.0 - t) * omega) / sinom; + scale1 = Math.sin(t * omega) / sinom; + } else { + scale0 = 1.0 - t; + scale1 = t; + } + out[0] = scale0 * ax + scale1 * bx; + out[1] = scale0 * ay + scale1 * by; + out[2] = scale0 * az + scale1 * bz; + out[3] = scale0 * aw + scale1 * bw; + + return out; + } + + function quaternionToEuler(out, quat) { + var qx = quat[0]; + var qy = quat[1]; + var qz = quat[2]; + var qw = quat[3]; + var heading = Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy * qy - 2 * qz * qz); + var attitude = Math.asin(2 * qx * qy + 2 * qz * qw); + var bank = Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx * qx - 2 * qz * qz); + out[0] = heading / degToRads; + out[1] = attitude / degToRads; + out[2] = bank / degToRads; + } + + function createQuaternion(values) { + var heading = values[0] * degToRads; + var attitude = values[1] * degToRads; + var bank = values[2] * degToRads; + var c1 = Math.cos(heading / 2); + var c2 = Math.cos(attitude / 2); + var c3 = Math.cos(bank / 2); + var s1 = Math.sin(heading / 2); + var s2 = Math.sin(attitude / 2); + var s3 = Math.sin(bank / 2); + var w = c1 * c2 * c3 - s1 * s2 * s3; + var x = s1 * s2 * c3 + c1 * c2 * s3; + var y = s1 * c2 * c3 + c1 * s2 * s3; + var z = c1 * s2 * c3 - s1 * c2 * s3; + + return [x, y, z, w]; + } + + function getValueAtCurrentTime() { + var frameNum = this.comp.renderedFrame - this.offsetTime; + var initTime = this.keyframes[0].t - this.offsetTime; + var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime; + if (!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))) { + if (this._caching.lastFrame >= frameNum) { + this._caching._lastKeyframeIndex = -1; + this._caching.lastIndex = 0; + } + + var renderResult = this.interpolateValue(frameNum, this._caching); + this.pv = renderResult; + } + this._caching.lastFrame = frameNum; + return this.pv; + } + + function setVValue(val) { + var multipliedValue; + if (this.propType === 'unidimensional') { + multipliedValue = val * this.mult; + if (mathAbs(this.v - multipliedValue) > 0.00001) { + this.v = multipliedValue; + this._mdf = true; + } + } else { + var i = 0; + var len = this.v.length; + while (i < len) { + multipliedValue = val[i] * this.mult; + if (mathAbs(this.v[i] - multipliedValue) > 0.00001) { + this.v[i] = multipliedValue; + this._mdf = true; + } + i += 1; + } + } + } + + function processEffectsSequence() { + if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) { + return; + } + if (this.lock) { + this.setVValue(this.pv); + return; + } + this.lock = true; + this._mdf = this._isFirstFrame; + var i; + var len = this.effectsSequence.length; + var finalValue = this.kf ? this.pv : this.data.k; + for (i = 0; i < len; i += 1) { + finalValue = this.effectsSequence[i](finalValue); + } + this.setVValue(finalValue); + this._isFirstFrame = false; + this.lock = false; + this.frameId = this.elem.globalData.frameId; + } + + function addEffect(effectFunction) { + this.effectsSequence.push(effectFunction); + this.container.addDynamicProperty(this); + } + + function ValueProperty(elem, data, mult, container) { + this.propType = 'unidimensional'; + this.mult = mult || 1; + this.data = data; + this.v = mult ? data.k * mult : data.k; + this.pv = data.k; + this._mdf = false; + this.elem = elem; + this.container = container; + this.comp = elem.comp; + this.k = false; + this.kf = false; + this.vel = 0; + this.effectsSequence = []; + this._isFirstFrame = true; + this.getValue = processEffectsSequence; + this.setVValue = setVValue; + this.addEffect = addEffect; + } + + function MultiDimensionalProperty(elem, data, mult, container) { + this.propType = 'multidimensional'; + this.mult = mult || 1; + this.data = data; + this._mdf = false; + this.elem = elem; + this.container = container; + this.comp = elem.comp; + this.k = false; + this.kf = false; + this.frameId = -1; + var i; + var len = data.k.length; + this.v = createTypedArray('float32', len); + this.pv = createTypedArray('float32', len); + this.vel = createTypedArray('float32', len); + for (i = 0; i < len; i += 1) { + this.v[i] = data.k[i] * this.mult; + this.pv[i] = data.k[i]; + } + this._isFirstFrame = true; + this.effectsSequence = []; + this.getValue = processEffectsSequence; + this.setVValue = setVValue; + this.addEffect = addEffect; + } + + function KeyframedValueProperty(elem, data, mult, container) { + this.propType = 'unidimensional'; + this.keyframes = data.k; + this.keyframesMetadata = []; + this.offsetTime = elem.data.st; + this.frameId = -1; + this._caching = { + lastFrame: initFrame, lastIndex: 0, value: 0, _lastKeyframeIndex: -1, + }; + this.k = true; + this.kf = true; + this.data = data; + this.mult = mult || 1; + this.elem = elem; + this.container = container; + this.comp = elem.comp; + this.v = initFrame; + this.pv = initFrame; + this._isFirstFrame = true; + this.getValue = processEffectsSequence; + this.setVValue = setVValue; + this.interpolateValue = interpolateValue; + this.effectsSequence = [getValueAtCurrentTime.bind(this)]; + this.addEffect = addEffect; + } + + function KeyframedMultidimensionalProperty(elem, data, mult, container) { + this.propType = 'multidimensional'; + var i; + var len = data.k.length; + var s; + var e; + var to; + var ti; + for (i = 0; i < len - 1; i += 1) { + if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) { + s = data.k[i].s; + e = data.k[i + 1].s; + to = data.k[i].to; + ti = data.k[i].ti; + if ((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2]))) { + data.k[i].to = null; + data.k[i].ti = null; + } + if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) { + if (s.length === 2 || (s[2] === e[2] && to[2] === 0 && ti[2] === 0)) { + data.k[i].to = null; + data.k[i].ti = null; + } + } + } + } + this.effectsSequence = [getValueAtCurrentTime.bind(this)]; + this.data = data; + this.keyframes = data.k; + this.keyframesMetadata = []; + this.offsetTime = elem.data.st; + this.k = true; + this.kf = true; + this._isFirstFrame = true; + this.mult = mult || 1; + this.elem = elem; + this.container = container; + this.comp = elem.comp; + this.getValue = processEffectsSequence; + this.setVValue = setVValue; + this.interpolateValue = interpolateValue; + this.frameId = -1; + var arrLen = data.k[0].s.length; + this.v = createTypedArray('float32', arrLen); + this.pv = createTypedArray('float32', arrLen); + for (i = 0; i < arrLen; i += 1) { + this.v[i] = initFrame; + this.pv[i] = initFrame; + } + this._caching = { lastFrame: initFrame, lastIndex: 0, value: createTypedArray('float32', arrLen) }; + this.addEffect = addEffect; + } + + function getProp(elem, data, type, mult, container) { + var p; + if (!data.k.length) { + p = new ValueProperty(elem, data, mult, container); + } else if (typeof (data.k[0]) === 'number') { + p = new MultiDimensionalProperty(elem, data, mult, container); + } else { + switch (type) { + case 0: + p = new KeyframedValueProperty(elem, data, mult, container); + break; + case 1: + p = new KeyframedMultidimensionalProperty(elem, data, mult, container); + break; + default: + break; + } + } + if (p.effectsSequence.length) { + container.addDynamicProperty(p); + } + return p; + } + + var ob = { + getProp: getProp, + }; + return ob; +}()); + +function DynamicPropertyContainer() {} +DynamicPropertyContainer.prototype = { + addDynamicProperty: function (prop) { + if (this.dynamicProperties.indexOf(prop) === -1) { + this.dynamicProperties.push(prop); + this.container.addDynamicProperty(this); + this._isAnimated = true; + } + }, + iterateDynamicProperties: function () { + this._mdf = false; + var i; + var len = this.dynamicProperties.length; + for (i = 0; i < len; i += 1) { + this.dynamicProperties[i].getValue(); + if (this.dynamicProperties[i]._mdf) { + this._mdf = true; + } + } + }, + initDynamicPropertyContainer: function (container) { + this.container = container; + this.dynamicProperties = []; + this._mdf = false; + this._isAnimated = false; + }, +}; + +const pointPool = (function () { + function create() { + return createTypedArray('float32', 2); + } + return poolFactory(8, create); +}()); + +function ShapePath() { + this.c = false; + this._length = 0; + this._maxLength = 8; + this.v = createSizedArray(this._maxLength); + this.o = createSizedArray(this._maxLength); + this.i = createSizedArray(this._maxLength); +} + +ShapePath.prototype.setPathData = function (closed, len) { + this.c = closed; + this.setLength(len); + var i = 0; + while (i < len) { + this.v[i] = pointPool.newElement(); + this.o[i] = pointPool.newElement(); + this.i[i] = pointPool.newElement(); + i += 1; + } +}; + +ShapePath.prototype.setLength = function (len) { + while (this._maxLength < len) { + this.doubleArrayLength(); + } + this._length = len; +}; + +ShapePath.prototype.doubleArrayLength = function () { + this.v = this.v.concat(createSizedArray(this._maxLength)); + this.i = this.i.concat(createSizedArray(this._maxLength)); + this.o = this.o.concat(createSizedArray(this._maxLength)); + this._maxLength *= 2; +}; + +ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) { + var arr; + this._length = Math.max(this._length, pos + 1); + if (this._length >= this._maxLength) { + this.doubleArrayLength(); + } + switch (type) { + case 'v': + arr = this.v; + break; + case 'i': + arr = this.i; + break; + case 'o': + arr = this.o; + break; + default: + arr = []; + break; + } + if (!arr[pos] || (arr[pos] && !replace)) { + arr[pos] = pointPool.newElement(); + } + arr[pos][0] = x; + arr[pos][1] = y; +}; + +ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) { + this.setXYAt(vX, vY, 'v', pos, replace); + this.setXYAt(oX, oY, 'o', pos, replace); + this.setXYAt(iX, iY, 'i', pos, replace); +}; + +ShapePath.prototype.reverse = function () { + var newPath = new ShapePath(); + newPath.setPathData(this.c, this._length); + var vertices = this.v; + var outPoints = this.o; + var inPoints = this.i; + var init = 0; + if (this.c) { + newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false); + init = 1; + } + var cnt = this._length - 1; + var len = this._length; + + var i; + for (i = init; i < len; i += 1) { + newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false); + cnt -= 1; + } + return newPath; +}; + +const shapePool = (function () { + function create() { + return new ShapePath(); + } + + function release(shapePath) { + var len = shapePath._length; + var i; + for (i = 0; i < len; i += 1) { + pointPool.release(shapePath.v[i]); + pointPool.release(shapePath.i[i]); + pointPool.release(shapePath.o[i]); + shapePath.v[i] = null; + shapePath.i[i] = null; + shapePath.o[i] = null; + } + shapePath._length = 0; + shapePath.c = false; + } + + function clone(shape) { + var cloned = factory.newElement(); + var i; + var len = shape._length === undefined ? shape.v.length : shape._length; + cloned.setLength(len); + cloned.c = shape.c; + + for (i = 0; i < len; i += 1) { + cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i); + } + return cloned; + } + + var factory = poolFactory(4, create, release); + factory.clone = clone; + + return factory; +}()); + +function ShapeCollection() { + this._length = 0; + this._maxLength = 4; + this.shapes = createSizedArray(this._maxLength); +} + +ShapeCollection.prototype.addShape = function (shapeData) { + if (this._length === this._maxLength) { + this.shapes = this.shapes.concat(createSizedArray(this._maxLength)); + this._maxLength *= 2; + } + this.shapes[this._length] = shapeData; + this._length += 1; +}; + +ShapeCollection.prototype.releaseShapes = function () { + var i; + for (i = 0; i < this._length; i += 1) { + shapePool.release(this.shapes[i]); + } + this._length = 0; +}; + +const shapeCollectionPool = (function () { + var ob = { + newShapeCollection: newShapeCollection, + release: release, + }; + + var _length = 0; + var _maxLength = 4; + var pool = createSizedArray(_maxLength); + + function newShapeCollection() { + var shapeCollection; + if (_length) { + _length -= 1; + shapeCollection = pool[_length]; + } else { + shapeCollection = new ShapeCollection(); + } + return shapeCollection; + } + + function release(shapeCollection) { + var i; + var len = shapeCollection._length; + for (i = 0; i < len; i += 1) { + shapePool.release(shapeCollection.shapes[i]); + } + shapeCollection._length = 0; + + if (_length === _maxLength) { + pool = pooling.double(pool); + _maxLength *= 2; + } + pool[_length] = shapeCollection; + _length += 1; + } + + return ob; +}()); + +const ShapePropertyFactory = (function () { + var initFrame = -999999; + + function interpolateShape(frameNum, previousValue, caching) { + var iterationIndex = caching.lastIndex; + var keyPropS; + var keyPropE; + var isHold; + var j; + var k; + var jLen; + var kLen; + var perc; + var vertexValue; + var kf = this.keyframes; + if (frameNum < kf[0].t - this.offsetTime) { + keyPropS = kf[0].s[0]; + isHold = true; + iterationIndex = 0; + } else if (frameNum >= kf[kf.length - 1].t - this.offsetTime) { + keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0]; + /* if(kf[kf.length - 1].s){ + keyPropS = kf[kf.length - 1].s[0]; + }else{ + keyPropS = kf[kf.length - 2].e[0]; + } */ + isHold = true; + } else { + var i = iterationIndex; + var len = kf.length - 1; + var flag = true; + var keyData; + var nextKeyData; + var keyframeMetadata; + while (flag) { + keyData = kf[i]; + nextKeyData = kf[i + 1]; + if ((nextKeyData.t - this.offsetTime) > frameNum) { + break; + } + if (i < len - 1) { + i += 1; + } else { + flag = false; + } + } + keyframeMetadata = this.keyframesMetadata[i] || {}; + isHold = keyData.h === 1; + iterationIndex = i; + if (!isHold) { + if (frameNum >= nextKeyData.t - this.offsetTime) { + perc = 1; + } else if (frameNum < keyData.t - this.offsetTime) { + perc = 0; + } else { + var fnc; + if (keyframeMetadata.__fnct) { + fnc = keyframeMetadata.__fnct; + } else { + fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get; + keyframeMetadata.__fnct = fnc; + } + perc = fnc((frameNum - (keyData.t - this.offsetTime)) / ((nextKeyData.t - this.offsetTime) - (keyData.t - this.offsetTime))); + } + keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0]; + } + keyPropS = keyData.s[0]; + } + jLen = previousValue._length; + kLen = keyPropS.i[0].length; + caching.lastIndex = iterationIndex; + + for (j = 0; j < jLen; j += 1) { + for (k = 0; k < kLen; k += 1) { + vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc; + previousValue.i[j][k] = vertexValue; + vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k] + (keyPropE.o[j][k] - keyPropS.o[j][k]) * perc; + previousValue.o[j][k] = vertexValue; + vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k] + (keyPropE.v[j][k] - keyPropS.v[j][k]) * perc; + previousValue.v[j][k] = vertexValue; + } + } + } + + function interpolateShapeCurrentTime() { + var frameNum = this.comp.renderedFrame - this.offsetTime; + var initTime = this.keyframes[0].t - this.offsetTime; + var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime; + var lastFrame = this._caching.lastFrame; + if (!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) { + /// / + this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0; + this.interpolateShape(frameNum, this.pv, this._caching); + /// / + } + this._caching.lastFrame = frameNum; + return this.pv; + } + + function resetShape() { + this.paths = this.localShapeCollection; + } + + function shapesEqual(shape1, shape2) { + if (shape1._length !== shape2._length || shape1.c !== shape2.c) { + return false; + } + var i; + var len = shape1._length; + for (i = 0; i < len; i += 1) { + if (shape1.v[i][0] !== shape2.v[i][0] + || shape1.v[i][1] !== shape2.v[i][1] + || shape1.o[i][0] !== shape2.o[i][0] + || shape1.o[i][1] !== shape2.o[i][1] + || shape1.i[i][0] !== shape2.i[i][0] + || shape1.i[i][1] !== shape2.i[i][1]) { + return false; + } + } + return true; + } + + function setVValue(newPath) { + if (!shapesEqual(this.v, newPath)) { + this.v = shapePool.clone(newPath); + this.localShapeCollection.releaseShapes(); + this.localShapeCollection.addShape(this.v); + this._mdf = true; + this.paths = this.localShapeCollection; + } + } + + function processEffectsSequence() { + if (this.elem.globalData.frameId === this.frameId) { + return; + } if (!this.effectsSequence.length) { + this._mdf = false; + return; + } + if (this.lock) { + this.setVValue(this.pv); + return; + } + this.lock = true; + this._mdf = false; + var finalValue; + if (this.kf) { + finalValue = this.pv; + } else if (this.data.ks) { + finalValue = this.data.ks.k; + } else { + finalValue = this.data.pt.k; + } + var i; + var len = this.effectsSequence.length; + for (i = 0; i < len; i += 1) { + finalValue = this.effectsSequence[i](finalValue); + } + this.setVValue(finalValue); + this.lock = false; + this.frameId = this.elem.globalData.frameId; + } + + function ShapeProperty(elem, data, type) { + this.propType = 'shape'; + this.comp = elem.comp; + this.container = elem; + this.elem = elem; + this.data = data; + this.k = false; + this.kf = false; + this._mdf = false; + var pathData = type === 3 ? data.pt.k : data.ks.k; + this.v = shapePool.clone(pathData); + this.pv = shapePool.clone(this.v); + this.localShapeCollection = shapeCollectionPool.newShapeCollection(); + this.paths = this.localShapeCollection; + this.paths.addShape(this.v); + this.reset = resetShape; + this.effectsSequence = []; + } + + function addEffect(effectFunction) { + this.effectsSequence.push(effectFunction); + this.container.addDynamicProperty(this); + } + + ShapeProperty.prototype.interpolateShape = interpolateShape; + ShapeProperty.prototype.getValue = processEffectsSequence; + ShapeProperty.prototype.setVValue = setVValue; + ShapeProperty.prototype.addEffect = addEffect; + + function KeyframedShapeProperty(elem, data, type) { + this.propType = 'shape'; + this.comp = elem.comp; + this.elem = elem; + this.container = elem; + this.offsetTime = elem.data.st; + this.keyframes = type === 3 ? data.pt.k : data.ks.k; + this.keyframesMetadata = []; + this.k = true; + this.kf = true; + var len = this.keyframes[0].s[0].i.length; + this.v = shapePool.newElement(); + this.v.setPathData(this.keyframes[0].s[0].c, len); + this.pv = shapePool.clone(this.v); + this.localShapeCollection = shapeCollectionPool.newShapeCollection(); + this.paths = this.localShapeCollection; + this.paths.addShape(this.v); + this.lastFrame = initFrame; + this.reset = resetShape; + this._caching = { lastFrame: initFrame, lastIndex: 0 }; + this.effectsSequence = [interpolateShapeCurrentTime.bind(this)]; + } + KeyframedShapeProperty.prototype.getValue = processEffectsSequence; + KeyframedShapeProperty.prototype.interpolateShape = interpolateShape; + KeyframedShapeProperty.prototype.setVValue = setVValue; + KeyframedShapeProperty.prototype.addEffect = addEffect; + + var EllShapeProperty = (function () { + var cPoint = roundCorner; + + function EllShapePropertyFactory(elem, data) { + this.v = shapePool.newElement(); + this.v.setPathData(true, 4); + this.localShapeCollection = shapeCollectionPool.newShapeCollection(); + this.paths = this.localShapeCollection; + this.localShapeCollection.addShape(this.v); + this.d = data.d; + this.elem = elem; + this.comp = elem.comp; + this.frameId = -1; + this.initDynamicPropertyContainer(elem); + this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this); + this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this); + if (this.dynamicProperties.length) { + this.k = true; + } else { + this.k = false; + this.convertEllToPath(); + } + } + + EllShapePropertyFactory.prototype = { + reset: resetShape, + getValue: function () { + if (this.elem.globalData.frameId === this.frameId) { + return; + } + this.frameId = this.elem.globalData.frameId; + this.iterateDynamicProperties(); + + if (this._mdf) { + this.convertEllToPath(); + } + }, + convertEllToPath: function () { + var p0 = this.p.v[0]; + var p1 = this.p.v[1]; + var s0 = this.s.v[0] / 2; + var s1 = this.s.v[1] / 2; + var _cw = this.d !== 3; + var _v = this.v; + _v.v[0][0] = p0; + _v.v[0][1] = p1 - s1; + _v.v[1][0] = _cw ? p0 + s0 : p0 - s0; + _v.v[1][1] = p1; + _v.v[2][0] = p0; + _v.v[2][1] = p1 + s1; + _v.v[3][0] = _cw ? p0 - s0 : p0 + s0; + _v.v[3][1] = p1; + _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint; + _v.i[0][1] = p1 - s1; + _v.i[1][0] = _cw ? p0 + s0 : p0 - s0; + _v.i[1][1] = p1 - s1 * cPoint; + _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint; + _v.i[2][1] = p1 + s1; + _v.i[3][0] = _cw ? p0 - s0 : p0 + s0; + _v.i[3][1] = p1 + s1 * cPoint; + _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint; + _v.o[0][1] = p1 - s1; + _v.o[1][0] = _cw ? p0 + s0 : p0 - s0; + _v.o[1][1] = p1 + s1 * cPoint; + _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint; + _v.o[2][1] = p1 + s1; + _v.o[3][0] = _cw ? p0 - s0 : p0 + s0; + _v.o[3][1] = p1 - s1 * cPoint; + }, + }; + + extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory); + + return EllShapePropertyFactory; + }()); + + var StarShapeProperty = (function () { + function StarShapePropertyFactory(elem, data) { + this.v = shapePool.newElement(); + this.v.setPathData(true, 0); + this.elem = elem; + this.comp = elem.comp; + this.data = data; + this.frameId = -1; + this.d = data.d; + this.initDynamicPropertyContainer(elem); + if (data.sy === 1) { + this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this); + this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this); + this.convertToPath = this.convertStarToPath; + } else { + this.convertToPath = this.convertPolygonToPath; + } + this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this); + this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this); + this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this); + this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this); + this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this); + this.localShapeCollection = shapeCollectionPool.newShapeCollection(); + this.localShapeCollection.addShape(this.v); + this.paths = this.localShapeCollection; + if (this.dynamicProperties.length) { + this.k = true; + } else { + this.k = false; + this.convertToPath(); + } + } + + StarShapePropertyFactory.prototype = { + reset: resetShape, + getValue: function () { + if (this.elem.globalData.frameId === this.frameId) { + return; + } + this.frameId = this.elem.globalData.frameId; + this.iterateDynamicProperties(); + if (this._mdf) { + this.convertToPath(); + } + }, + convertStarToPath: function () { + var numPts = Math.floor(this.pt.v) * 2; + var angle = (Math.PI * 2) / numPts; + /* this.v.v.length = numPts; + this.v.i.length = numPts; + this.v.o.length = numPts; */ + var longFlag = true; + var longRad = this.or.v; + var shortRad = this.ir.v; + var longRound = this.os.v; + var shortRound = this.is.v; + var longPerimSegment = (2 * Math.PI * longRad) / (numPts * 2); + var shortPerimSegment = (2 * Math.PI * shortRad) / (numPts * 2); + var i; + var rad; + var roundness; + var perimSegment; + var currentAng = -Math.PI / 2; + currentAng += this.r.v; + var dir = this.data.d === 3 ? -1 : 1; + this.v._length = 0; + for (i = 0; i < numPts; i += 1) { + rad = longFlag ? longRad : shortRad; + roundness = longFlag ? longRound : shortRound; + perimSegment = longFlag ? longPerimSegment : shortPerimSegment; + var x = rad * Math.cos(currentAng); + var y = rad * Math.sin(currentAng); + var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y); + var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y); + x += +this.p.v[0]; + y += +this.p.v[1]; + this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true); + + /* this.v.v[i] = [x,y]; + this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir]; + this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir]; + this.v._length = numPts; */ + longFlag = !longFlag; + currentAng += angle * dir; + } + }, + convertPolygonToPath: function () { + var numPts = Math.floor(this.pt.v); + var angle = (Math.PI * 2) / numPts; + var rad = this.or.v; + var roundness = this.os.v; + var perimSegment = (2 * Math.PI * rad) / (numPts * 4); + var i; + var currentAng = -Math.PI * 0.5; + var dir = this.data.d === 3 ? -1 : 1; + currentAng += this.r.v; + this.v._length = 0; + for (i = 0; i < numPts; i += 1) { + var x = rad * Math.cos(currentAng); + var y = rad * Math.sin(currentAng); + var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y); + var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y); + x += +this.p.v[0]; + y += +this.p.v[1]; + this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true); + currentAng += angle * dir; + } + this.paths.length = 0; + this.paths[0] = this.v; + }, + + }; + extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory); + + return StarShapePropertyFactory; + }()); + + var RectShapeProperty = (function () { + function RectShapePropertyFactory(elem, data) { + this.v = shapePool.newElement(); + this.v.c = true; + this.localShapeCollection = shapeCollectionPool.newShapeCollection(); + this.localShapeCollection.addShape(this.v); + this.paths = this.localShapeCollection; + this.elem = elem; + this.comp = elem.comp; + this.frameId = -1; + this.d = data.d; + this.initDynamicPropertyContainer(elem); + this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this); + this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this); + this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this); + if (this.dynamicProperties.length) { + this.k = true; + } else { + this.k = false; + this.convertRectToPath(); + } + } + + RectShapePropertyFactory.prototype = { + convertRectToPath: function () { + var p0 = this.p.v[0]; + var p1 = this.p.v[1]; + var v0 = this.s.v[0] / 2; + var v1 = this.s.v[1] / 2; + var round = bmMin(v0, v1, this.r.v); + var cPoint = round * (1 - roundCorner); + this.v._length = 0; + + if (this.d === 2 || this.d === 1) { + this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true); + this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true); + if (round !== 0) { + this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true); + this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true); + this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, 4, true); + this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1 + round, 5, true); + this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, 6, true); + this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, p0 + v0 - round, p1 - v1, 7, true); + } else { + this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0, p1 + v1, 2); + this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1, 3); + } + } else { + this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true); + if (round !== 0) { + this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true); + this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true); + this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, 3, true); + this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1 - round, 4, true); + this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, 5, true); + this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0 - round, p1 + v1, 6, true); + this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, 7, true); + } else { + this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0, p1 - v1, 1, true); + this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1, 2, true); + this.v.setTripleAt(p0 + v0, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0, p1 + v1, 3, true); + } + } + }, + getValue: function () { + if (this.elem.globalData.frameId === this.frameId) { + return; + } + this.frameId = this.elem.globalData.frameId; + this.iterateDynamicProperties(); + if (this._mdf) { + this.convertRectToPath(); + } + }, + reset: resetShape, + }; + extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory); + + return RectShapePropertyFactory; + }()); + + function getShapeProp(elem, data, type) { + var prop; + if (type === 3 || type === 4) { + var dataProp = type === 3 ? data.pt : data.ks; + var keys = dataProp.k; + if (keys.length) { + prop = new KeyframedShapeProperty(elem, data, type); + } else { + prop = new ShapeProperty(elem, data, type); + } + } else if (type === 5) { + prop = new RectShapeProperty(elem, data); + } else if (type === 6) { + prop = new EllShapeProperty(elem, data); + } else if (type === 7) { + prop = new StarShapeProperty(elem, data); + } + if (prop.k) { + elem.addDynamicProperty(prop); + } + return prop; + } + + function getConstructorFunction() { + return ShapeProperty; + } + + function getKeyframedConstructorFunction() { + return KeyframedShapeProperty; + } + + var ob = {}; + ob.getShapeProp = getShapeProp; + ob.getConstructorFunction = getConstructorFunction; + ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction; + return ob; +}()); + +/*! + Transformation Matrix v2.0 + (c) Epistemex 2014-2015 + www.epistemex.com + By Ken Fyrstenberg + Contributions by leeoniya. + License: MIT, header required. + */ + +/** + * 2D transformation matrix object initialized with identity matrix. + * + * The matrix can synchronize a canvas context by supplying the context + * as an argument, or later apply current absolute transform to an + * existing context. + * + * All values are handled as floating point values. + * + * @param {CanvasRenderingContext2D} [context] - Optional context to sync with Matrix + * @prop {number} a - scale x + * @prop {number} b - shear y + * @prop {number} c - shear x + * @prop {number} d - scale y + * @prop {number} e - translate x + * @prop {number} f - translate y + * @prop {CanvasRenderingContext2D|null} [context=null] - set or get current canvas context + * @constructor + */ + +const Matrix = (function () { + var _cos = Math.cos; + var _sin = Math.sin; + var _tan = Math.tan; + var _rnd = Math.round; + + function reset() { + this.props[0] = 1; + this.props[1] = 0; + this.props[2] = 0; + this.props[3] = 0; + this.props[4] = 0; + this.props[5] = 1; + this.props[6] = 0; + this.props[7] = 0; + this.props[8] = 0; + this.props[9] = 0; + this.props[10] = 1; + this.props[11] = 0; + this.props[12] = 0; + this.props[13] = 0; + this.props[14] = 0; + this.props[15] = 1; + return this; + } + + function rotate(angle) { + if (angle === 0) { + return this; + } + var mCos = _cos(angle); + var mSin = _sin(angle); + return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } + + function rotateX(angle) { + if (angle === 0) { + return this; + } + var mCos = _cos(angle); + var mSin = _sin(angle); + return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1); + } + + function rotateY(angle) { + if (angle === 0) { + return this; + } + var mCos = _cos(angle); + var mSin = _sin(angle); + return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1); + } + + function rotateZ(angle) { + if (angle === 0) { + return this; + } + var mCos = _cos(angle); + var mSin = _sin(angle); + return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } + + function shear(sx, sy) { + return this._t(1, sy, sx, 1, 0, 0); + } + + function skew(ax, ay) { + return this.shear(_tan(ax), _tan(ay)); + } + + function skewFromAxis(ax, angle) { + var mCos = _cos(angle); + var mSin = _sin(angle); + return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) + ._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) + ._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0); + } + + function scale(sx, sy, sz) { + if (!sz && sz !== 0) { + sz = 1; + } + if (sx === 1 && sy === 1 && sz === 1) { + return this; + } + return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1); + } + + function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) { + this.props[0] = a; + this.props[1] = b; + this.props[2] = c; + this.props[3] = d; + this.props[4] = e; + this.props[5] = f; + this.props[6] = g; + this.props[7] = h; + this.props[8] = i; + this.props[9] = j; + this.props[10] = k; + this.props[11] = l; + this.props[12] = m; + this.props[13] = n; + this.props[14] = o; + this.props[15] = p; + return this; + } + + function translate(tx, ty, tz) { + tz = tz || 0; + if (tx !== 0 || ty !== 0 || tz !== 0) { + return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1); + } + return this; + } + + function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) { + var _p = this.props; + + if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) { + // NOTE: commenting this condition because TurboFan deoptimizes code when present + // if(m2 !== 0 || n2 !== 0 || o2 !== 0){ + _p[12] = _p[12] * a2 + _p[15] * m2; + _p[13] = _p[13] * f2 + _p[15] * n2; + _p[14] = _p[14] * k2 + _p[15] * o2; + _p[15] *= p2; + // } + this._identityCalculated = false; + return this; + } + + var a1 = _p[0]; + var b1 = _p[1]; + var c1 = _p[2]; + var d1 = _p[3]; + var e1 = _p[4]; + var f1 = _p[5]; + var g1 = _p[6]; + var h1 = _p[7]; + var i1 = _p[8]; + var j1 = _p[9]; + var k1 = _p[10]; + var l1 = _p[11]; + var m1 = _p[12]; + var n1 = _p[13]; + var o1 = _p[14]; + var p1 = _p[15]; + + /* matrix order (canvas compatible): + * ace + * bdf + * 001 + */ + _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2; + _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2; + _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2; + _p[3] = a1 * d2 + b1 * h2 + c1 * l2 + d1 * p2; + + _p[4] = e1 * a2 + f1 * e2 + g1 * i2 + h1 * m2; + _p[5] = e1 * b2 + f1 * f2 + g1 * j2 + h1 * n2; + _p[6] = e1 * c2 + f1 * g2 + g1 * k2 + h1 * o2; + _p[7] = e1 * d2 + f1 * h2 + g1 * l2 + h1 * p2; + + _p[8] = i1 * a2 + j1 * e2 + k1 * i2 + l1 * m2; + _p[9] = i1 * b2 + j1 * f2 + k1 * j2 + l1 * n2; + _p[10] = i1 * c2 + j1 * g2 + k1 * k2 + l1 * o2; + _p[11] = i1 * d2 + j1 * h2 + k1 * l2 + l1 * p2; + + _p[12] = m1 * a2 + n1 * e2 + o1 * i2 + p1 * m2; + _p[13] = m1 * b2 + n1 * f2 + o1 * j2 + p1 * n2; + _p[14] = m1 * c2 + n1 * g2 + o1 * k2 + p1 * o2; + _p[15] = m1 * d2 + n1 * h2 + o1 * l2 + p1 * p2; + + this._identityCalculated = false; + return this; + } + + function isIdentity() { + if (!this._identityCalculated) { + this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1); + this._identityCalculated = true; + } + return this._identity; + } + + function equals(matr) { + var i = 0; + while (i < 16) { + if (matr.props[i] !== this.props[i]) { + return false; + } + i += 1; + } + return true; + } + + function clone(matr) { + var i; + for (i = 0; i < 16; i += 1) { + matr.props[i] = this.props[i]; + } + return matr; + } + + function cloneFromProps(props) { + var i; + for (i = 0; i < 16; i += 1) { + this.props[i] = props[i]; + } + } + + function applyToPoint(x, y, z) { + return { + x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12], + y: x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13], + z: x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14], + }; + /* return { + x: x * me.a + y * me.c + me.e, + y: x * me.b + y * me.d + me.f + }; */ + } + function applyToX(x, y, z) { + return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12]; + } + function applyToY(x, y, z) { + return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13]; + } + function applyToZ(x, y, z) { + return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14]; + } + + function getInverseMatrix() { + var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4]; + var a = this.props[5] / determinant; + var b = -this.props[1] / determinant; + var c = -this.props[4] / determinant; + var d = this.props[0] / determinant; + var e = (this.props[4] * this.props[13] - this.props[5] * this.props[12]) / determinant; + var f = -(this.props[0] * this.props[13] - this.props[1] * this.props[12]) / determinant; + var inverseMatrix = new Matrix(); + inverseMatrix.props[0] = a; + inverseMatrix.props[1] = b; + inverseMatrix.props[4] = c; + inverseMatrix.props[5] = d; + inverseMatrix.props[12] = e; + inverseMatrix.props[13] = f; + return inverseMatrix; + } + + function inversePoint(pt) { + var inverseMatrix = this.getInverseMatrix(); + return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0); + } + + function inversePoints(pts) { + var i; + var len = pts.length; + var retPts = []; + for (i = 0; i < len; i += 1) { + retPts[i] = inversePoint(pts[i]); + } + return retPts; + } + + function applyToTriplePoints(pt1, pt2, pt3) { + var arr = createTypedArray('float32', 6); + if (this.isIdentity()) { + arr[0] = pt1[0]; + arr[1] = pt1[1]; + arr[2] = pt2[0]; + arr[3] = pt2[1]; + arr[4] = pt3[0]; + arr[5] = pt3[1]; + } else { + var p0 = this.props[0]; + var p1 = this.props[1]; + var p4 = this.props[4]; + var p5 = this.props[5]; + var p12 = this.props[12]; + var p13 = this.props[13]; + arr[0] = pt1[0] * p0 + pt1[1] * p4 + p12; + arr[1] = pt1[0] * p1 + pt1[1] * p5 + p13; + arr[2] = pt2[0] * p0 + pt2[1] * p4 + p12; + arr[3] = pt2[0] * p1 + pt2[1] * p5 + p13; + arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12; + arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13; + } + return arr; + } + + function applyToPointArray(x, y, z) { + var arr; + if (this.isIdentity()) { + arr = [x, y, z]; + } else { + arr = [ + x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12], + x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13], + x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14], + ]; + } + return arr; + } + + function applyToPointStringified(x, y) { + if (this.isIdentity()) { + return x + ',' + y; + } + var _p = this.props; + return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100; + } + + function toCSS() { + // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed. + /* if(this.isIdentity()) { + return ''; + } */ + var i = 0; + var props = this.props; + var cssValue = 'matrix3d('; + var v = 10000; + while (i < 16) { + cssValue += _rnd(props[i] * v) / v; + cssValue += i === 15 ? ')' : ','; + i += 1; + } + return cssValue; + } + + function roundMatrixProperty(val) { + var v = 10000; + if ((val < 0.000001 && val > 0) || (val > -0.000001 && val < 0)) { + return _rnd(val * v) / v; + } + return val; + } + + function to2dCSS() { + // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed. + /* if(this.isIdentity()) { + return ''; + } */ + var props = this.props; + var _a = roundMatrixProperty(props[0]); + var _b = roundMatrixProperty(props[1]); + var _c = roundMatrixProperty(props[4]); + var _d = roundMatrixProperty(props[5]); + var _e = roundMatrixProperty(props[12]); + var _f = roundMatrixProperty(props[13]); + return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')'; + } + + return function () { + this.reset = reset; + this.rotate = rotate; + this.rotateX = rotateX; + this.rotateY = rotateY; + this.rotateZ = rotateZ; + this.skew = skew; + this.skewFromAxis = skewFromAxis; + this.shear = shear; + this.scale = scale; + this.setTransform = setTransform; + this.translate = translate; + this.transform = transform; + this.applyToPoint = applyToPoint; + this.applyToX = applyToX; + this.applyToY = applyToY; + this.applyToZ = applyToZ; + this.applyToPointArray = applyToPointArray; + this.applyToTriplePoints = applyToTriplePoints; + this.applyToPointStringified = applyToPointStringified; + this.toCSS = toCSS; + this.to2dCSS = to2dCSS; + this.clone = clone; + this.cloneFromProps = cloneFromProps; + this.equals = equals; + this.inversePoints = inversePoints; + this.inversePoint = inversePoint; + this.getInverseMatrix = getInverseMatrix; + this._t = this.transform; + this.isIdentity = isIdentity; + this._identity = true; + this._identityCalculated = false; + + this.props = createTypedArray('float32', 16); + this.reset(); + }; +}()); + +const lottie = {}; +var standalone = '__[STANDALONE]__'; +var animationData = '__[ANIMATIONDATA]__'; +var renderer = ''; + +function setLocation(href) { + setLocationHref(href); +} + +function searchAnimations() { + if (standalone === true) { + animationManager.searchAnimations(animationData, standalone, renderer); + } else { + animationManager.searchAnimations(); + } +} + +function setSubframeRendering(flag) { + setSubframeEnabled(flag); +} + +function setPrefix(prefix) { + setIdPrefix(prefix); +} + +function loadAnimation(params) { + if (standalone === true) { + params.animationData = JSON.parse(animationData); + } + return animationManager.loadAnimation(params); +} + +function setQuality(value) { + if (typeof value === 'string') { + switch (value) { + case 'high': + setDefaultCurveSegments(200); + break; + default: + case 'medium': + setDefaultCurveSegments(50); + break; + case 'low': + setDefaultCurveSegments(10); + break; + } + } else if (!isNaN(value) && value > 1) { + setDefaultCurveSegments(value); + } + if (getDefaultCurveSegments() >= 50) { + roundValues(false); + } else { + roundValues(true); + } +} + +function inBrowser() { + return typeof navigator !== 'undefined'; +} + +function installPlugin(type, plugin) { + if (type === 'expressions') { + setExpressionsPlugin(plugin); + } +} + +function getFactory(name) { + switch (name) { + case 'propertyFactory': + return PropertyFactory; + case 'shapePropertyFactory': + return ShapePropertyFactory; + case 'matrix': + return Matrix; + default: + return null; + } +} + +lottie.play = animationManager.play; +lottie.pause = animationManager.pause; +lottie.setLocationHref = setLocation; +lottie.togglePause = animationManager.togglePause; +lottie.setSpeed = animationManager.setSpeed; +lottie.setDirection = animationManager.setDirection; +lottie.stop = animationManager.stop; +lottie.searchAnimations = searchAnimations; +lottie.registerAnimation = animationManager.registerAnimation; +lottie.loadAnimation = loadAnimation; +lottie.setSubframeRendering = setSubframeRendering; +lottie.resize = animationManager.resize; +// lottie.start = start; +lottie.goToAndStop = animationManager.goToAndStop; +lottie.destroy = animationManager.destroy; +lottie.setQuality = setQuality; +lottie.inBrowser = inBrowser; +lottie.installPlugin = installPlugin; +lottie.freeze = animationManager.freeze; +lottie.unfreeze = animationManager.unfreeze; +lottie.setVolume = animationManager.setVolume; +lottie.mute = animationManager.mute; +lottie.unmute = animationManager.unmute; +lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations; +lottie.useWebWorker = setWebWorker; +lottie.setIDPrefix = setPrefix; +lottie.__getFactory = getFactory; +lottie.version = '[[BM_VERSION]]'; + +function checkReady() { + if (document.readyState === 'complete') { + clearInterval(readyStateCheckInterval); + searchAnimations(); + } +} + +function getQueryVariable(variable) { + var vars = queryString.split('&'); + for (var i = 0; i < vars.length; i += 1) { + var pair = vars[i].split('='); + if (decodeURIComponent(pair[0]) == variable) { // eslint-disable-line eqeqeq + return decodeURIComponent(pair[1]); + } + } + return null; +} +var queryString = ''; +if (standalone) { + var scripts = document.getElementsByTagName('script'); + var index = scripts.length - 1; + var myScript = scripts[index] || { + src: '', + }; + queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape + renderer = getQueryVariable('renderer'); +} +var readyStateCheckInterval = setInterval(checkReady, 100); + +// this adds bodymovin to the window object for backwards compatibility +try { + if (!(typeof exports === 'object' && typeof module !== 'undefined') + && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef + ) { + window.bodymovin = lottie; + } +} catch (err) { + // +} + +const ShapeModifiers = (function () { + var ob = {}; + var modifiers = {}; + ob.registerModifier = registerModifier; + ob.getModifier = getModifier; + + function registerModifier(nm, factory) { + if (!modifiers[nm]) { + modifiers[nm] = factory; + } + } + + function getModifier(nm, elem, data) { + return new modifiers[nm](elem, data); + } + + return ob; +}()); + +function ShapeModifier() {} +ShapeModifier.prototype.initModifierProperties = function () {}; +ShapeModifier.prototype.addShapeToModifier = function () {}; +ShapeModifier.prototype.addShape = function (data) { + if (!this.closed) { + // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick. + data.sh.container.addDynamicProperty(data.sh); + var shapeData = { shape: data.sh, data: data, localShapeCollection: shapeCollectionPool.newShapeCollection() }; + this.shapes.push(shapeData); + this.addShapeToModifier(shapeData); + if (this._isAnimated) { + data.setAsAnimated(); + } + } +}; +ShapeModifier.prototype.init = function (elem, data) { + this.shapes = []; + this.elem = elem; + this.initDynamicPropertyContainer(elem); + this.initModifierProperties(elem, data); + this.frameId = initialDefaultFrame; + this.closed = false; + this.k = false; + if (this.dynamicProperties.length) { + this.k = true; + } else { + this.getValue(true); + } +}; +ShapeModifier.prototype.processKeys = function () { + if (this.elem.globalData.frameId === this.frameId) { + return; + } + this.frameId = this.elem.globalData.frameId; + this.iterateDynamicProperties(); +}; + +extendPrototype([DynamicPropertyContainer], ShapeModifier); + +function TrimModifier() { +} +extendPrototype([ShapeModifier], TrimModifier); +TrimModifier.prototype.initModifierProperties = function (elem, data) { + this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this); + this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this); + this.o = PropertyFactory.getProp(elem, data.o, 0, 0, this); + this.sValue = 0; + this.eValue = 0; + this.getValue = this.processKeys; + this.m = data.m; + this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length; +}; + +TrimModifier.prototype.addShapeToModifier = function (shapeData) { + shapeData.pathsData = []; +}; + +TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) { + var segments = []; + if (e <= 1) { + segments.push({ + s: s, + e: e, + }); + } else if (s >= 1) { + segments.push({ + s: s - 1, + e: e - 1, + }); + } else { + segments.push({ + s: s, + e: 1, + }); + segments.push({ + s: 0, + e: e - 1, + }); + } + var shapeSegments = []; + var i; + var len = segments.length; + var segmentOb; + for (i = 0; i < len; i += 1) { + segmentOb = segments[i]; + if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) { + var shapeS; + var shapeE; + if (segmentOb.s * totalModifierLength <= addedLength) { + shapeS = 0; + } else { + shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength; + } + if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) { + shapeE = 1; + } else { + shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength); + } + shapeSegments.push([shapeS, shapeE]); + } + } + if (!shapeSegments.length) { + shapeSegments.push([0, 0]); + } + return shapeSegments; +}; + +TrimModifier.prototype.releasePathsData = function (pathsData) { + var i; + var len = pathsData.length; + for (i = 0; i < len; i += 1) { + segmentsLengthPool.release(pathsData[i]); + } + pathsData.length = 0; + return pathsData; +}; + +TrimModifier.prototype.processShapes = function (_isFirstFrame) { + var s; + var e; + if (this._mdf || _isFirstFrame) { + var o = (this.o.v % 360) / 360; + if (o < 0) { + o += 1; + } + if (this.s.v > 1) { + s = 1 + o; + } else if (this.s.v < 0) { + s = 0 + o; + } else { + s = this.s.v + o; + } + if (this.e.v > 1) { + e = 1 + o; + } else if (this.e.v < 0) { + e = 0 + o; + } else { + e = this.e.v + o; + } + + if (s > e) { + var _s = s; + s = e; + e = _s; + } + s = Math.round(s * 10000) * 0.0001; + e = Math.round(e * 10000) * 0.0001; + this.sValue = s; + this.eValue = e; + } else { + s = this.sValue; + e = this.eValue; + } + var shapePaths; + var i; + var len = this.shapes.length; + var j; + var jLen; + var pathsData; + var pathData; + var totalShapeLength; + var totalModifierLength = 0; + + if (e === s) { + for (i = 0; i < len; i += 1) { + this.shapes[i].localShapeCollection.releaseShapes(); + this.shapes[i].shape._mdf = true; + this.shapes[i].shape.paths = this.shapes[i].localShapeCollection; + if (this._mdf) { + this.shapes[i].pathsData.length = 0; + } + } + } else if (!((e === 1 && s === 0) || (e === 0 && s === 1))) { + var segments = []; + var shapeData; + var localShapeCollection; + for (i = 0; i < len; i += 1) { + shapeData = this.shapes[i]; + // if shape hasn't changed and trim properties haven't changed, cached previous path can be used + if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) { + shapeData.shape.paths = shapeData.localShapeCollection; + } else { + shapePaths = shapeData.shape.paths; + jLen = shapePaths._length; + totalShapeLength = 0; + if (!shapeData.shape._mdf && shapeData.pathsData.length) { + totalShapeLength = shapeData.totalShapeLength; + } else { + pathsData = this.releasePathsData(shapeData.pathsData); + for (j = 0; j < jLen; j += 1) { + pathData = bez.getSegmentsLength(shapePaths.shapes[j]); + pathsData.push(pathData); + totalShapeLength += pathData.totalLength; + } + shapeData.totalShapeLength = totalShapeLength; + shapeData.pathsData = pathsData; + } + + totalModifierLength += totalShapeLength; + shapeData.shape._mdf = true; + } + } + var shapeS = s; + var shapeE = e; + var addedLength = 0; + var edges; + for (i = len - 1; i >= 0; i -= 1) { + shapeData = this.shapes[i]; + if (shapeData.shape._mdf) { + localShapeCollection = shapeData.localShapeCollection; + localShapeCollection.releaseShapes(); + // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group + if (this.m === 2 && len > 1) { + edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength); + addedLength += shapeData.totalShapeLength; + } else { + edges = [[shapeS, shapeE]]; + } + jLen = edges.length; + for (j = 0; j < jLen; j += 1) { + shapeS = edges[j][0]; + shapeE = edges[j][1]; + segments.length = 0; + if (shapeE <= 1) { + segments.push({ + s: shapeData.totalShapeLength * shapeS, + e: shapeData.totalShapeLength * shapeE, + }); + } else if (shapeS >= 1) { + segments.push({ + s: shapeData.totalShapeLength * (shapeS - 1), + e: shapeData.totalShapeLength * (shapeE - 1), + }); + } else { + segments.push({ + s: shapeData.totalShapeLength * shapeS, + e: shapeData.totalShapeLength, + }); + segments.push({ + s: 0, + e: shapeData.totalShapeLength * (shapeE - 1), + }); + } + var newShapesData = this.addShapes(shapeData, segments[0]); + if (segments[0].s !== segments[0].e) { + if (segments.length > 1) { + var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1]; + if (lastShapeInCollection.c) { + var lastShape = newShapesData.pop(); + this.addPaths(newShapesData, localShapeCollection); + newShapesData = this.addShapes(shapeData, segments[1], lastShape); + } else { + this.addPaths(newShapesData, localShapeCollection); + newShapesData = this.addShapes(shapeData, segments[1]); + } + } + this.addPaths(newShapesData, localShapeCollection); + } + } + shapeData.shape.paths = localShapeCollection; + } + } + } else if (this._mdf) { + for (i = 0; i < len; i += 1) { + // Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween. + // Don't remove this even if it's losing cached info. + this.shapes[i].pathsData.length = 0; + this.shapes[i].shape._mdf = true; + } + } +}; + +TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) { + var i; + var len = newPaths.length; + for (i = 0; i < len; i += 1) { + localShapeCollection.addShape(newPaths[i]); + } +}; + +TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) { + shapePath.setXYAt(pt2[0], pt2[1], 'o', pos); + shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1); + if (newShape) { + shapePath.setXYAt(pt1[0], pt1[1], 'v', pos); + } + shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1); +}; + +TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) { + shapePath.setXYAt(points[1], points[5], 'o', pos); + shapePath.setXYAt(points[2], points[6], 'i', pos + 1); + if (newShape) { + shapePath.setXYAt(points[0], points[4], 'v', pos); + } + shapePath.setXYAt(points[3], points[7], 'v', pos + 1); +}; + +TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) { + var pathsData = shapeData.pathsData; + var shapePaths = shapeData.shape.paths.shapes; + var i; + var len = shapeData.shape.paths._length; + var j; + var jLen; + var addedLength = 0; + var currentLengthData; + var segmentCount; + var lengths; + var segment; + var shapes = []; + var initPos; + var newShape = true; + if (!shapePath) { + shapePath = shapePool.newElement(); + segmentCount = 0; + initPos = 0; + } else { + segmentCount = shapePath._length; + initPos = shapePath._length; + } + shapes.push(shapePath); + for (i = 0; i < len; i += 1) { + lengths = pathsData[i].lengths; + shapePath.c = shapePaths[i].c; + jLen = shapePaths[i].c ? lengths.length : lengths.length + 1; + for (j = 1; j < jLen; j += 1) { + currentLengthData = lengths[j - 1]; + if (addedLength + currentLengthData.addedLength < shapeSegment.s) { + addedLength += currentLengthData.addedLength; + shapePath.c = false; + } else if (addedLength > shapeSegment.e) { + shapePath.c = false; + break; + } else { + if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) { + this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape); + newShape = false; + } else { + segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]); + this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); + // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape); + newShape = false; + shapePath.c = false; + } + addedLength += currentLengthData.addedLength; + segmentCount += 1; + } + } + if (shapePaths[i].c && lengths.length) { + currentLengthData = lengths[j - 1]; + if (addedLength <= shapeSegment.e) { + var segmentLength = lengths[j - 1].addedLength; + if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) { + this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape); + newShape = false; + } else { + segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]); + this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); + // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape); + newShape = false; + shapePath.c = false; + } + } else { + shapePath.c = false; + } + addedLength += currentLengthData.addedLength; + segmentCount += 1; + } + if (shapePath._length) { + shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos); + shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1); + } + if (addedLength > shapeSegment.e) { + break; + } + if (i < len - 1) { + shapePath = shapePool.newElement(); + newShape = true; + shapes.push(shapePath); + segmentCount = 0; + } + } + return shapes; +}; + +function PuckerAndBloatModifier() {} +extendPrototype([ShapeModifier], PuckerAndBloatModifier); +PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) { + this.getValue = this.processKeys; + this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this); + this._isAnimated = !!this.amount.effectsSequence.length; +}; + +PuckerAndBloatModifier.prototype.processPath = function (path, amount) { + var percent = amount / 100; + var centerPoint = [0, 0]; + var pathLength = path._length; + var i = 0; + for (i = 0; i < pathLength; i += 1) { + centerPoint[0] += path.v[i][0]; + centerPoint[1] += path.v[i][1]; + } + centerPoint[0] /= pathLength; + centerPoint[1] /= pathLength; + var clonedPath = shapePool.newElement(); + clonedPath.c = path.c; + var vX; + var vY; + var oX; + var oY; + var iX; + var iY; + for (i = 0; i < pathLength; i += 1) { + vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent; + vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent; + oX = path.o[i][0] + (centerPoint[0] - path.o[i][0]) * -percent; + oY = path.o[i][1] + (centerPoint[1] - path.o[i][1]) * -percent; + iX = path.i[i][0] + (centerPoint[0] - path.i[i][0]) * -percent; + iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent; + clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i); + } + return clonedPath; +}; + +PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) { + var shapePaths; + var i; + var len = this.shapes.length; + var j; + var jLen; + var amount = this.amount.v; + + if (amount !== 0) { + var shapeData; + var localShapeCollection; + for (i = 0; i < len; i += 1) { + shapeData = this.shapes[i]; + localShapeCollection = shapeData.localShapeCollection; + if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) { + localShapeCollection.releaseShapes(); + shapeData.shape._mdf = true; + shapePaths = shapeData.shape.paths.shapes; + jLen = shapeData.shape.paths._length; + for (j = 0; j < jLen; j += 1) { + localShapeCollection.addShape(this.processPath(shapePaths[j], amount)); + } + } + shapeData.shape.paths = shapeData.localShapeCollection; + } + } + if (!this.dynamicProperties.length) { + this._mdf = false; + } +}; + +const TransformPropertyFactory = (function () { + var defaultVector = [0, 0]; + + function applyToMatrix(mat) { + var _mdf = this._mdf; + this.iterateDynamicProperties(); + this._mdf = this._mdf || _mdf; + if (this.a) { + mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]); + } + if (this.s) { + mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]); + } + if (this.sk) { + mat.skewFromAxis(-this.sk.v, this.sa.v); + } + if (this.r) { + mat.rotate(-this.r.v); + } else { + mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]) + .rotateY(this.or.v[1]) + .rotateX(this.or.v[0]); + } + if (this.data.p.s) { + if (this.data.p.z) { + mat.translate(this.px.v, this.py.v, -this.pz.v); + } else { + mat.translate(this.px.v, this.py.v, 0); + } + } else { + mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]); + } + } + function processKeys(forceRender) { + if (this.elem.globalData.frameId === this.frameId) { + return; + } + if (this._isDirty) { + this.precalculateMatrix(); + this._isDirty = false; + } + + this.iterateDynamicProperties(); + + if (this._mdf || forceRender) { + var frameRate; + this.v.cloneFromProps(this.pre.props); + if (this.appliedTransformations < 1) { + this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]); + } + if (this.appliedTransformations < 2) { + this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]); + } + if (this.sk && this.appliedTransformations < 3) { + this.v.skewFromAxis(-this.sk.v, this.sa.v); + } + if (this.r && this.appliedTransformations < 4) { + this.v.rotate(-this.r.v); + } else if (!this.r && this.appliedTransformations < 4) { + this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]) + .rotateY(this.or.v[1]) + .rotateX(this.or.v[0]); + } + if (this.autoOriented) { + var v1; + var v2; + frameRate = this.elem.globalData.frameRate; + if (this.p && this.p.keyframes && this.p.getValueAtTime) { + if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) { + v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0); + v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0); + } else if (this.p._caching.lastFrame + this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) { + v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / frameRate), 0); + v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0); + } else { + v1 = this.p.pv; + v2 = this.p.getValueAtTime((this.p._caching.lastFrame + this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime); + } + } else if (this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) { + v1 = []; + v2 = []; + var px = this.px; + var py = this.py; + if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) { + v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0); + v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0); + v2[0] = px.getValueAtTime((px.keyframes[0].t) / frameRate, 0); + v2[1] = py.getValueAtTime((py.keyframes[0].t) / frameRate, 0); + } else if (px._caching.lastFrame + px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) { + v1[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t / frameRate), 0); + v1[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t / frameRate), 0); + v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate, 0); + v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate, 0); + } else { + v1 = [px.pv, py.pv]; + v2[0] = px.getValueAtTime((px._caching.lastFrame + px.offsetTime - 0.01) / frameRate, px.offsetTime); + v2[1] = py.getValueAtTime((py._caching.lastFrame + py.offsetTime - 0.01) / frameRate, py.offsetTime); + } + } else { + v2 = defaultVector; + v1 = v2; + } + this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0])); + } + if (this.data.p && this.data.p.s) { + if (this.data.p.z) { + this.v.translate(this.px.v, this.py.v, -this.pz.v); + } else { + this.v.translate(this.px.v, this.py.v, 0); + } + } else { + this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]); + } + } + this.frameId = this.elem.globalData.frameId; + } + + function precalculateMatrix() { + if (!this.a.k) { + this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]); + this.appliedTransformations = 1; + } else { + return; + } + if (!this.s.effectsSequence.length) { + this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]); + this.appliedTransformations = 2; + } else { + return; + } + if (this.sk) { + if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) { + this.pre.skewFromAxis(-this.sk.v, this.sa.v); + this.appliedTransformations = 3; + } else { + return; + } + } + if (this.r) { + if (!this.r.effectsSequence.length) { + this.pre.rotate(-this.r.v); + this.appliedTransformations = 4; + } + } else if (!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) { + this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]) + .rotateY(this.or.v[1]) + .rotateX(this.or.v[0]); + this.appliedTransformations = 4; + } + } + + function autoOrient() { + // + // var prevP = this.getValueAtTime(); + } + + function addDynamicProperty(prop) { + this._addDynamicProperty(prop); + this.elem.addDynamicProperty(prop); + this._isDirty = true; + } + + function TransformProperty(elem, data, container) { + this.elem = elem; + this.frameId = -1; + this.propType = 'transform'; + this.data = data; + this.v = new Matrix(); + // Precalculated matrix with non animated properties + this.pre = new Matrix(); + this.appliedTransformations = 0; + this.initDynamicPropertyContainer(container || elem); + if (data.p && data.p.s) { + this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this); + this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this); + if (data.p.z) { + this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this); + } + } else { + this.p = PropertyFactory.getProp(elem, data.p || { k: [0, 0, 0] }, 1, 0, this); + } + if (data.rx) { + this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this); + this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this); + this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this); + if (data.or.k[0].ti) { + var i; + var len = data.or.k.length; + for (i = 0; i < len; i += 1) { + data.or.k[i].to = null; + data.or.k[i].ti = null; + } + } + this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this); + // sh Indicates it needs to be capped between -180 and 180 + this.or.sh = true; + } else { + this.r = PropertyFactory.getProp(elem, data.r || { k: 0 }, 0, degToRads, this); + } + if (data.sk) { + this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this); + this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this); + } + this.a = PropertyFactory.getProp(elem, data.a || { k: [0, 0, 0] }, 1, 0, this); + this.s = PropertyFactory.getProp(elem, data.s || { k: [100, 100, 100] }, 1, 0.01, this); + // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes. + if (data.o) { + this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem); + } else { + this.o = { _mdf: false, v: 1 }; + } + this._isDirty = true; + if (!this.dynamicProperties.length) { + this.getValue(true); + } + } + + TransformProperty.prototype = { + applyToMatrix: applyToMatrix, + getValue: processKeys, + precalculateMatrix: precalculateMatrix, + autoOrient: autoOrient, + }; + + extendPrototype([DynamicPropertyContainer], TransformProperty); + TransformProperty.prototype.addDynamicProperty = addDynamicProperty; + TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty; + + function getTransformProperty(elem, data, container) { + return new TransformProperty(elem, data, container); + } + + return { + getTransformProperty: getTransformProperty, + }; +}()); + +function RepeaterModifier() {} +extendPrototype([ShapeModifier], RepeaterModifier); + +RepeaterModifier.prototype.initModifierProperties = function (elem, data) { + this.getValue = this.processKeys; + this.c = PropertyFactory.getProp(elem, data.c, 0, null, this); + this.o = PropertyFactory.getProp(elem, data.o, 0, null, this); + this.tr = TransformPropertyFactory.getTransformProperty(elem, data.tr, this); + this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this); + this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this); + this.data = data; + if (!this.dynamicProperties.length) { + this.getValue(true); + } + this._isAnimated = !!this.dynamicProperties.length; + this.pMatrix = new Matrix(); + this.rMatrix = new Matrix(); + this.sMatrix = new Matrix(); + this.tMatrix = new Matrix(); + this.matrix = new Matrix(); +}; + +RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) { + var dir = inv ? -1 : 1; + var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc); + var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc); + pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]); + rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]); + rMatrix.rotate(-transform.r.v * dir * perc); + rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]); + sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]); + sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY); + sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]); +}; + +RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) { + this.elem = elem; + this.arr = arr; + this.pos = pos; + this.elemsData = elemsData; + this._currentCopies = 0; + this._elements = []; + this._groups = []; + this.frameId = -1; + this.initDynamicPropertyContainer(elem); + this.initModifierProperties(elem, arr[pos]); + while (pos > 0) { + pos -= 1; + // this._elements.unshift(arr.splice(pos,1)[0]); + this._elements.unshift(arr[pos]); + } + if (this.dynamicProperties.length) { + this.k = true; + } else { + this.getValue(true); + } +}; + +RepeaterModifier.prototype.resetElements = function (elements) { + var i; + var len = elements.length; + for (i = 0; i < len; i += 1) { + elements[i]._processed = false; + if (elements[i].ty === 'gr') { + this.resetElements(elements[i].it); + } + } +}; + +RepeaterModifier.prototype.cloneElements = function (elements) { + var newElements = JSON.parse(JSON.stringify(elements)); + this.resetElements(newElements); + return newElements; +}; + +RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) { + var i; + var len = elements.length; + for (i = 0; i < len; i += 1) { + elements[i]._render = renderFlag; + if (elements[i].ty === 'gr') { + this.changeGroupRender(elements[i].it, renderFlag); + } + } +}; + +RepeaterModifier.prototype.processShapes = function (_isFirstFrame) { + var items; + var itemsTransform; + var i; + var dir; + var cont; + var hasReloaded = false; + if (this._mdf || _isFirstFrame) { + var copies = Math.ceil(this.c.v); + if (this._groups.length < copies) { + while (this._groups.length < copies) { + var group = { + it: this.cloneElements(this._elements), + ty: 'gr', + }; + group.it.push({ + a: { a: 0, ix: 1, k: [0, 0] }, nm: 'Transform', o: { a: 0, ix: 7, k: 100 }, p: { a: 0, ix: 2, k: [0, 0] }, r: { a: 1, ix: 6, k: [{ s: 0, e: 0, t: 0 }, { s: 0, e: 0, t: 1 }] }, s: { a: 0, ix: 3, k: [100, 100] }, sa: { a: 0, ix: 5, k: 0 }, sk: { a: 0, ix: 4, k: 0 }, ty: 'tr', + }); + + this.arr.splice(0, 0, group); + this._groups.splice(0, 0, group); + this._currentCopies += 1; + } + this.elem.reloadShapes(); + hasReloaded = true; + } + cont = 0; + var renderFlag; + for (i = 0; i <= this._groups.length - 1; i += 1) { + renderFlag = cont < copies; + this._groups[i]._render = renderFlag; + this.changeGroupRender(this._groups[i].it, renderFlag); + if (!renderFlag) { + var elems = this.elemsData[i].it; + var transformData = elems[elems.length - 1]; + if (transformData.transform.op.v !== 0) { + transformData.transform.op._mdf = true; + transformData.transform.op.v = 0; + } else { + transformData.transform.op._mdf = false; + } + } + cont += 1; + } + + this._currentCopies = copies; + /// / + + var offset = this.o.v; + var offsetModulo = offset % 1; + var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset); + var pProps = this.pMatrix.props; + var rProps = this.rMatrix.props; + var sProps = this.sMatrix.props; + this.pMatrix.reset(); + this.rMatrix.reset(); + this.sMatrix.reset(); + this.tMatrix.reset(); + this.matrix.reset(); + var iteration = 0; + + if (offset > 0) { + while (iteration < roundOffset) { + this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false); + iteration += 1; + } + if (offsetModulo) { + this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false); + iteration += offsetModulo; + } + } else if (offset < 0) { + while (iteration > roundOffset) { + this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true); + iteration -= 1; + } + if (offsetModulo) { + this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true); + iteration -= offsetModulo; + } + } + i = this.data.m === 1 ? 0 : this._currentCopies - 1; + dir = this.data.m === 1 ? 1 : -1; + cont = this._currentCopies; + var j; + var jLen; + while (cont) { + items = this.elemsData[i].it; + itemsTransform = items[items.length - 1].transform.mProps.v.props; + jLen = itemsTransform.length; + items[items.length - 1].transform.mProps._mdf = true; + items[items.length - 1].transform.op._mdf = true; + items[items.length - 1].transform.op.v = this._currentCopies === 1 + ? this.so.v + : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1)); + + if (iteration !== 0) { + if ((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)) { + this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false); + } + this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]); + this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]); + this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]); + + for (j = 0; j < jLen; j += 1) { + itemsTransform[j] = this.matrix.props[j]; + } + this.matrix.reset(); + } else { + this.matrix.reset(); + for (j = 0; j < jLen; j += 1) { + itemsTransform[j] = this.matrix.props[j]; + } + } + iteration += 1; + cont -= 1; + i += dir; + } + } else { + cont = this._currentCopies; + i = 0; + dir = 1; + while (cont) { + items = this.elemsData[i].it; + itemsTransform = items[items.length - 1].transform.mProps.v.props; + items[items.length - 1].transform.mProps._mdf = false; + items[items.length - 1].transform.op._mdf = false; + cont -= 1; + i += dir; + } + } + return hasReloaded; +}; + +RepeaterModifier.prototype.addShape = function () {}; + +function RoundCornersModifier() {} +extendPrototype([ShapeModifier], RoundCornersModifier); +RoundCornersModifier.prototype.initModifierProperties = function (elem, data) { + this.getValue = this.processKeys; + this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this); + this._isAnimated = !!this.rd.effectsSequence.length; +}; + +RoundCornersModifier.prototype.processPath = function (path, round) { + var clonedPath = shapePool.newElement(); + clonedPath.c = path.c; + var i; + var len = path._length; + var currentV; + var currentI; + var currentO; + var closerV; + var distance; + var newPosPerc; + var index = 0; + var vX; + var vY; + var oX; + var oY; + var iX; + var iY; + for (i = 0; i < len; i += 1) { + currentV = path.v[i]; + currentO = path.o[i]; + currentI = path.i[i]; + if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) { + if ((i === 0 || i === len - 1) && !path.c) { + clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index); + /* clonedPath.v[index] = currentV; + clonedPath.o[index] = currentO; + clonedPath.i[index] = currentI; */ + index += 1; + } else { + if (i === 0) { + closerV = path.v[len - 1]; + } else { + closerV = path.v[i - 1]; + } + distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2)); + newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0; + iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc; + vX = iX; + iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc; + vY = iY; + oX = vX - (vX - currentV[0]) * roundCorner; + oY = vY - (vY - currentV[1]) * roundCorner; + clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index); + index += 1; + + if (i === len - 1) { + closerV = path.v[0]; + } else { + closerV = path.v[i + 1]; + } + distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2)); + newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0; + oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc; + vX = oX; + oY = currentV[1] + (closerV[1] - currentV[1]) * newPosPerc; + vY = oY; + iX = vX - (vX - currentV[0]) * roundCorner; + iY = vY - (vY - currentV[1]) * roundCorner; + clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index); + index += 1; + } + } else { + clonedPath.setTripleAt(path.v[i][0], path.v[i][1], path.o[i][0], path.o[i][1], path.i[i][0], path.i[i][1], index); + index += 1; + } + } + return clonedPath; +}; + +RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) { + var shapePaths; + var i; + var len = this.shapes.length; + var j; + var jLen; + var rd = this.rd.v; + + if (rd !== 0) { + var shapeData; + var localShapeCollection; + for (i = 0; i < len; i += 1) { + shapeData = this.shapes[i]; + localShapeCollection = shapeData.localShapeCollection; + if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) { + localShapeCollection.releaseShapes(); + shapeData.shape._mdf = true; + shapePaths = shapeData.shape.paths.shapes; + jLen = shapeData.shape.paths._length; + for (j = 0; j < jLen; j += 1) { + localShapeCollection.addShape(this.processPath(shapePaths[j], rd)); + } + } + shapeData.shape.paths = shapeData.localShapeCollection; + } + } + if (!this.dynamicProperties.length) { + this._mdf = false; + } +}; + +function getFontProperties(fontData) { + var styles = fontData.fStyle ? fontData.fStyle.split(' ') : []; + + var fWeight = 'normal'; var + fStyle = 'normal'; + var len = styles.length; + var styleName; + for (var i = 0; i < len; i += 1) { + styleName = styles[i].toLowerCase(); + switch (styleName) { + case 'italic': + fStyle = 'italic'; + break; + case 'bold': + fWeight = '700'; + break; + case 'black': + fWeight = '900'; + break; + case 'medium': + fWeight = '500'; + break; + case 'regular': + case 'normal': + fWeight = '400'; + break; + case 'light': + case 'thin': + fWeight = '200'; + break; + default: + break; + } + } + + return { + style: fStyle, + weight: fontData.fWeight || fWeight, + }; +} + +const FontManager = (function () { + var maxWaitingTime = 5000; + var emptyChar = { + w: 0, + size: 0, + shapes: [], + data: { + shapes: [], + }, + }; + var combinedCharacters = []; + // Hindi characters + combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366, + 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, + 2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]); + + var surrogateModifiers = [ + 'd83cdffb', + 'd83cdffc', + 'd83cdffd', + 'd83cdffe', + 'd83cdfff', + ]; + + var zeroWidthJoiner = [65039, 8205]; + + function trimFontOptions(font) { + var familyArray = font.split(','); + var i; + var len = familyArray.length; + var enabledFamilies = []; + for (i = 0; i < len; i += 1) { + if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') { + enabledFamilies.push(familyArray[i]); + } + } + return enabledFamilies.join(','); + } + + function setUpNode(font, family) { + var parentNode = createTag('span'); + // Node is invisible to screen readers. + parentNode.setAttribute('aria-hidden', true); + parentNode.style.fontFamily = family; + var node = createTag('span'); + // Characters that vary significantly among different fonts + node.innerText = 'giItT1WQy@!-/#'; + // Visible - so we can measure it - but not on the screen + parentNode.style.position = 'absolute'; + parentNode.style.left = '-10000px'; + parentNode.style.top = '-10000px'; + // Large font size makes even subtle changes obvious + parentNode.style.fontSize = '300px'; + // Reset any font properties + parentNode.style.fontVariant = 'normal'; + parentNode.style.fontStyle = 'normal'; + parentNode.style.fontWeight = 'normal'; + parentNode.style.letterSpacing = '0'; + parentNode.appendChild(node); + document.body.appendChild(parentNode); + + // Remember width with no applied web font + var width = node.offsetWidth; + node.style.fontFamily = trimFontOptions(font) + ', ' + family; + return { node: node, w: width, parent: parentNode }; + } + + function checkLoadedFonts() { + var i; + var len = this.fonts.length; + var node; + var w; + var loadedCount = len; + for (i = 0; i < len; i += 1) { + if (this.fonts[i].loaded) { + loadedCount -= 1; + } else if (this.fonts[i].fOrigin === 'n' || this.fonts[i].origin === 0) { + this.fonts[i].loaded = true; + } else { + node = this.fonts[i].monoCase.node; + w = this.fonts[i].monoCase.w; + if (node.offsetWidth !== w) { + loadedCount -= 1; + this.fonts[i].loaded = true; + } else { + node = this.fonts[i].sansCase.node; + w = this.fonts[i].sansCase.w; + if (node.offsetWidth !== w) { + loadedCount -= 1; + this.fonts[i].loaded = true; + } + } + if (this.fonts[i].loaded) { + this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent); + this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent); + } + } + } + + if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) { + setTimeout(this.checkLoadedFontsBinded, 20); + } else { + setTimeout(this.setIsLoadedBinded, 10); + } + } + + function createHelper(fontData, def) { + var engine = (document.body && def) ? 'svg' : 'canvas'; + var helper; + var fontProps = getFontProperties(fontData); + if (engine === 'svg') { + var tHelper = createNS('text'); + tHelper.style.fontSize = '100px'; + // tHelper.style.fontFamily = fontData.fFamily; + tHelper.setAttribute('font-family', fontData.fFamily); + tHelper.setAttribute('font-style', fontProps.style); + tHelper.setAttribute('font-weight', fontProps.weight); + tHelper.textContent = '1'; + if (fontData.fClass) { + tHelper.style.fontFamily = 'inherit'; + tHelper.setAttribute('class', fontData.fClass); + } else { + tHelper.style.fontFamily = fontData.fFamily; + } + def.appendChild(tHelper); + helper = tHelper; + } else { + var tCanvasHelper = new OffscreenCanvas(500, 500).getContext('2d'); + tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily; + helper = tCanvasHelper; + } + function measure(text) { + if (engine === 'svg') { + helper.textContent = text; + return helper.getComputedTextLength(); + } + return helper.measureText(text).width; + } + return { + measureText: measure, + }; + } + + function addFonts(fontData, defs) { + if (!fontData) { + this.isLoaded = true; + return; + } + if (this.chars) { + this.isLoaded = true; + this.fonts = fontData.list; + return; + } + if (!document.body) { + this.isLoaded = true; + fontData.list.forEach((data) => { + data.helper = createHelper(data); + data.cache = {}; + }); + this.fonts = fontData.list; + return; + } + + var fontArr = fontData.list; + var i; + var len = fontArr.length; + var _pendingFonts = len; + for (i = 0; i < len; i += 1) { + var shouldLoadFont = true; + var loadedSelector; + var j; + fontArr[i].loaded = false; + fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace'); + fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif'); + if (!fontArr[i].fPath) { + fontArr[i].loaded = true; + _pendingFonts -= 1; + } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) { + loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]'); + + if (loadedSelector.length > 0) { + shouldLoadFont = false; + } + + if (shouldLoadFont) { + var s = createTag('style'); + s.setAttribute('f-forigin', fontArr[i].fOrigin); + s.setAttribute('f-origin', fontArr[i].origin); + s.setAttribute('f-family', fontArr[i].fFamily); + s.type = 'text/css'; + s.innerText = '@font-face {font-family: ' + fontArr[i].fFamily + "; font-style: normal; src: url('" + fontArr[i].fPath + "');}"; + defs.appendChild(s); + } + } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) { + loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'); + + for (j = 0; j < loadedSelector.length; j += 1) { + if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) { + // Font is already loaded + shouldLoadFont = false; + } + } + + if (shouldLoadFont) { + var l = createTag('link'); + l.setAttribute('f-forigin', fontArr[i].fOrigin); + l.setAttribute('f-origin', fontArr[i].origin); + l.type = 'text/css'; + l.rel = 'stylesheet'; + l.href = fontArr[i].fPath; + document.body.appendChild(l); + } + } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) { + loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'); + + for (j = 0; j < loadedSelector.length; j += 1) { + if (fontArr[i].fPath === loadedSelector[j].src) { + // Font is already loaded + shouldLoadFont = false; + } + } + + if (shouldLoadFont) { + var sc = createTag('link'); + sc.setAttribute('f-forigin', fontArr[i].fOrigin); + sc.setAttribute('f-origin', fontArr[i].origin); + sc.setAttribute('rel', 'stylesheet'); + sc.setAttribute('href', fontArr[i].fPath); + defs.appendChild(sc); + } + } + fontArr[i].helper = createHelper(fontArr[i], defs); + fontArr[i].cache = {}; + this.fonts.push(fontArr[i]); + } + if (_pendingFonts === 0) { + this.isLoaded = true; + } else { + // On some cases even if the font is loaded, it won't load correctly when measuring text on canvas. + // Adding this timeout seems to fix it + setTimeout(this.checkLoadedFonts.bind(this), 100); + } + } + + function addChars(chars) { + if (!chars) { + return; + } + if (!this.chars) { + this.chars = []; + } + var i; + var len = chars.length; + var j; + var jLen = this.chars.length; + var found; + for (i = 0; i < len; i += 1) { + j = 0; + found = false; + while (j < jLen) { + if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) { + found = true; + } + j += 1; + } + if (!found) { + this.chars.push(chars[i]); + jLen += 1; + } + } + } + + function getCharData(char, style, font) { + var i = 0; + var len = this.chars.length; + while (i < len) { + if (this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font) { + return this.chars[i]; + } + i += 1; + } + if (((typeof char === 'string' && char.charCodeAt(0) !== 13) || !char) + && console + && console.warn // eslint-disable-line no-console + && !this._warned + ) { + this._warned = true; + console.warn('Missing character from exported characters list: ', char, style, font); // eslint-disable-line no-console + } + return emptyChar; + } + + function measureText(char, fontName, size) { + var fontData = this.getFontByName(fontName); + var index = char.charCodeAt(0); + if (!fontData.cache[index + 1]) { + var tHelper = fontData.helper; + if (char === ' ') { + var doubleSize = tHelper.measureText('|' + char + '|'); + var singleSize = tHelper.measureText('||'); + fontData.cache[index + 1] = (doubleSize - singleSize) / 100; + } else { + fontData.cache[index + 1] = tHelper.measureText(char) / 100; + } + } + return fontData.cache[index + 1] * size; + } + + function getFontByName(name) { + var i = 0; + var len = this.fonts.length; + while (i < len) { + if (this.fonts[i].fName === name) { + return this.fonts[i]; + } + i += 1; + } + return this.fonts[0]; + } + + function isModifier(firstCharCode, secondCharCode) { + var sum = firstCharCode.toString(16) + secondCharCode.toString(16); + return surrogateModifiers.indexOf(sum) !== -1; + } + + function isZeroWidthJoiner(firstCharCode, secondCharCode) { + if (!secondCharCode) { + return firstCharCode === zeroWidthJoiner[1]; + } + return firstCharCode === zeroWidthJoiner[0] && secondCharCode === zeroWidthJoiner[1]; + } + + function isCombinedCharacter(char) { + return combinedCharacters.indexOf(char) !== -1; + } + + function setIsLoaded() { + this.isLoaded = true; + } + + var Font = function () { + this.fonts = []; + this.chars = null; + this.typekitLoaded = 0; + this.isLoaded = false; + this._warned = false; + this.initTime = Date.now(); + this.setIsLoadedBinded = this.setIsLoaded.bind(this); + this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this); + }; + Font.isModifier = isModifier; + Font.isZeroWidthJoiner = isZeroWidthJoiner; + Font.isCombinedCharacter = isCombinedCharacter; + + var fontPrototype = { + addChars: addChars, + addFonts: addFonts, + getCharData: getCharData, + getFontByName: getFontByName, + measureText: measureText, + checkLoadedFonts: checkLoadedFonts, + setIsLoaded: setIsLoaded, + }; + + Font.prototype = fontPrototype; + + return Font; +}()); + +function RenderableElement() { + +} + +RenderableElement.prototype = { + initRenderable: function () { + // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange + this.isInRange = false; + // layer's display state + this.hidden = false; + // If layer's transparency equals 0, it can be hidden + this.isTransparent = false; + // list of animated components + this.renderableComponents = []; + }, + addRenderableComponent: function (component) { + if (this.renderableComponents.indexOf(component) === -1) { + this.renderableComponents.push(component); + } + }, + removeRenderableComponent: function (component) { + if (this.renderableComponents.indexOf(component) !== -1) { + this.renderableComponents.splice(this.renderableComponents.indexOf(component), 1); + } + }, + prepareRenderableFrame: function (num) { + this.checkLayerLimits(num); + }, + checkTransparency: function () { + if (this.finalTransform.mProp.o.v <= 0) { + if (!this.isTransparent && this.globalData.renderConfig.hideOnTransparent) { + this.isTransparent = true; + this.hide(); + } + } else if (this.isTransparent) { + this.isTransparent = false; + this.show(); + } + }, + /** + * @function + * Initializes frame related properties. + * + * @param {number} num + * current frame number in Layer's time + * + */ + checkLayerLimits: function (num) { + if (this.data.ip - this.data.st <= num && this.data.op - this.data.st > num) { + if (this.isInRange !== true) { + this.globalData._mdf = true; + this._mdf = true; + this.isInRange = true; + this.show(); + } + } else if (this.isInRange !== false) { + this.globalData._mdf = true; + this.isInRange = false; + this.hide(); + } + }, + renderRenderable: function () { + var i; + var len = this.renderableComponents.length; + for (i = 0; i < len; i += 1) { + this.renderableComponents[i].renderFrame(this._isFirstFrame); + } + /* this.maskManager.renderFrame(this.finalTransform.mat); + this.renderableEffectsManager.renderFrame(this._isFirstFrame); */ + }, + sourceRectAtTime: function () { + return { + top: 0, + left: 0, + width: 100, + height: 100, + }; + }, + getLayerSize: function () { + if (this.data.ty === 5) { + return { w: this.data.textData.width, h: this.data.textData.height }; + } + return { w: this.data.width, h: this.data.height }; + }, +}; + +const MaskManagerInterface = (function () { + function MaskInterface(mask, data) { + this._mask = mask; + this._data = data; + } + Object.defineProperty(MaskInterface.prototype, 'maskPath', { + get: function () { + if (this._mask.prop.k) { + this._mask.prop.getValue(); + } + return this._mask.prop; + }, + }); + Object.defineProperty(MaskInterface.prototype, 'maskOpacity', { + get: function () { + if (this._mask.op.k) { + this._mask.op.getValue(); + } + return this._mask.op.v * 100; + }, + }); + + var MaskManager = function (maskManager) { + var _masksInterfaces = createSizedArray(maskManager.viewData.length); + var i; + var len = maskManager.viewData.length; + for (i = 0; i < len; i += 1) { + _masksInterfaces[i] = new MaskInterface(maskManager.viewData[i], maskManager.masksProperties[i]); + } + + var maskFunction = function (name) { + i = 0; + while (i < len) { + if (maskManager.masksProperties[i].nm === name) { + return _masksInterfaces[i]; + } + i += 1; + } + return null; + }; + return maskFunction; + }; + return MaskManager; +}()); + +const ExpressionPropertyInterface = (function () { + var defaultUnidimensionalValue = { pv: 0, v: 0, mult: 1 }; + var defaultMultidimensionalValue = { pv: [0, 0, 0], v: [0, 0, 0], mult: 1 }; + + function completeProperty(expressionValue, property, type) { + Object.defineProperty(expressionValue, 'velocity', { + get: function () { + return property.getVelocityAtTime(property.comp.currentFrame); + }, + }); + expressionValue.numKeys = property.keyframes ? property.keyframes.length : 0; + expressionValue.key = function (pos) { + if (!expressionValue.numKeys) { + return 0; + } + var value = ''; + if ('s' in property.keyframes[pos - 1]) { + value = property.keyframes[pos - 1].s; + } else if ('e' in property.keyframes[pos - 2]) { + value = property.keyframes[pos - 2].e; + } else { + value = property.keyframes[pos - 2].s; + } + var valueProp = type === 'unidimensional' ? new Number(value) : Object.assign({}, value); // eslint-disable-line no-new-wrappers + valueProp.time = property.keyframes[pos - 1].t / property.elem.comp.globalData.frameRate; + valueProp.value = type === 'unidimensional' ? value[0] : value; + return valueProp; + }; + expressionValue.valueAtTime = property.getValueAtTime; + expressionValue.speedAtTime = property.getSpeedAtTime; + expressionValue.velocityAtTime = property.getVelocityAtTime; + expressionValue.propertyGroup = property.propertyGroup; + } + + function UnidimensionalPropertyInterface(property) { + if (!property || !('pv' in property)) { + property = defaultUnidimensionalValue; + } + var mult = 1 / property.mult; + var val = property.pv * mult; + var expressionValue = new Number(val); // eslint-disable-line no-new-wrappers + expressionValue.value = val; + completeProperty(expressionValue, property, 'unidimensional'); + + return function () { + if (property.k) { + property.getValue(); + } + val = property.v * mult; + if (expressionValue.value !== val) { + expressionValue = new Number(val); // eslint-disable-line no-new-wrappers + expressionValue.value = val; + completeProperty(expressionValue, property, 'unidimensional'); + } + return expressionValue; + }; + } + + function MultidimensionalPropertyInterface(property) { + if (!property || !('pv' in property)) { + property = defaultMultidimensionalValue; + } + var mult = 1 / property.mult; + var len = (property.data && property.data.l) || property.pv.length; + var expressionValue = createTypedArray('float32', len); + var arrValue = createTypedArray('float32', len); + expressionValue.value = arrValue; + completeProperty(expressionValue, property, 'multidimensional'); + + return function () { + if (property.k) { + property.getValue(); + } + for (var i = 0; i < len; i += 1) { + arrValue[i] = property.v[i] * mult; + expressionValue[i] = arrValue[i]; + } + return expressionValue; + }; + } + + // TODO: try to avoid using this getter + function defaultGetter() { + return defaultUnidimensionalValue; + } + + return function (property) { + if (!property) { + return defaultGetter; + } if (property.propType === 'unidimensional') { + return UnidimensionalPropertyInterface(property); + } + return MultidimensionalPropertyInterface(property); + }; +}()); + +const TransformExpressionInterface = (function () { + return function (transform) { + function _thisFunction(name) { + switch (name) { + case 'scale': + case 'Scale': + case 'ADBE Scale': + case 6: + return _thisFunction.scale; + case 'rotation': + case 'Rotation': + case 'ADBE Rotation': + case 'ADBE Rotate Z': + case 10: + return _thisFunction.rotation; + case 'ADBE Rotate X': + return _thisFunction.xRotation; + case 'ADBE Rotate Y': + return _thisFunction.yRotation; + case 'position': + case 'Position': + case 'ADBE Position': + case 2: + return _thisFunction.position; + case 'ADBE Position_0': + return _thisFunction.xPosition; + case 'ADBE Position_1': + return _thisFunction.yPosition; + case 'ADBE Position_2': + return _thisFunction.zPosition; + case 'anchorPoint': + case 'AnchorPoint': + case 'Anchor Point': + case 'ADBE AnchorPoint': + case 1: + return _thisFunction.anchorPoint; + case 'opacity': + case 'Opacity': + case 11: + return _thisFunction.opacity; + default: + return null; + } + } + Object.defineProperty(_thisFunction, 'rotation', { + get: ExpressionPropertyInterface(transform.r || transform.rz), + }); + + Object.defineProperty(_thisFunction, 'zRotation', { + get: ExpressionPropertyInterface(transform.rz || transform.r), + }); + + Object.defineProperty(_thisFunction, 'xRotation', { + get: ExpressionPropertyInterface(transform.rx), + }); + + Object.defineProperty(_thisFunction, 'yRotation', { + get: ExpressionPropertyInterface(transform.ry), + }); + Object.defineProperty(_thisFunction, 'scale', { + get: ExpressionPropertyInterface(transform.s), + }); + var _px; + var _py; + var _pz; + var _transformFactory; + if (transform.p) { + _transformFactory = ExpressionPropertyInterface(transform.p); + } else { + _px = ExpressionPropertyInterface(transform.px); + _py = ExpressionPropertyInterface(transform.py); + if (transform.pz) { + _pz = ExpressionPropertyInterface(transform.pz); + } + } + Object.defineProperty(_thisFunction, 'position', { + get: function () { + if (transform.p) { + return _transformFactory(); + } + return [ + _px(), + _py(), + _pz ? _pz() : 0]; + }, + }); + + Object.defineProperty(_thisFunction, 'xPosition', { + get: ExpressionPropertyInterface(transform.px), + }); + + Object.defineProperty(_thisFunction, 'yPosition', { + get: ExpressionPropertyInterface(transform.py), + }); + + Object.defineProperty(_thisFunction, 'zPosition', { + get: ExpressionPropertyInterface(transform.pz), + }); + + Object.defineProperty(_thisFunction, 'anchorPoint', { + get: ExpressionPropertyInterface(transform.a), + }); + + Object.defineProperty(_thisFunction, 'opacity', { + get: ExpressionPropertyInterface(transform.o), + }); + + Object.defineProperty(_thisFunction, 'skew', { + get: ExpressionPropertyInterface(transform.sk), + }); + + Object.defineProperty(_thisFunction, 'skewAxis', { + get: ExpressionPropertyInterface(transform.sa), + }); + + Object.defineProperty(_thisFunction, 'orientation', { + get: ExpressionPropertyInterface(transform.or), + }); + + return _thisFunction; + }; +}()); + +const LayerExpressionInterface = (function () { + function getMatrix(time) { + var toWorldMat = new Matrix(); + if (time !== undefined) { + var propMatrix = this._elem.finalTransform.mProp.getValueAtTime(time); + propMatrix.clone(toWorldMat); + } else { + var transformMat = this._elem.finalTransform.mProp; + transformMat.applyToMatrix(toWorldMat); + } + return toWorldMat; + } + + function toWorldVec(arr, time) { + var toWorldMat = this.getMatrix(time); + toWorldMat.props[12] = 0; + toWorldMat.props[13] = 0; + toWorldMat.props[14] = 0; + return this.applyPoint(toWorldMat, arr); + } + + function toWorld(arr, time) { + var toWorldMat = this.getMatrix(time); + return this.applyPoint(toWorldMat, arr); + } + + function fromWorldVec(arr, time) { + var toWorldMat = this.getMatrix(time); + toWorldMat.props[12] = 0; + toWorldMat.props[13] = 0; + toWorldMat.props[14] = 0; + return this.invertPoint(toWorldMat, arr); + } + + function fromWorld(arr, time) { + var toWorldMat = this.getMatrix(time); + return this.invertPoint(toWorldMat, arr); + } + + function applyPoint(matrix, arr) { + if (this._elem.hierarchy && this._elem.hierarchy.length) { + var i; + var len = this._elem.hierarchy.length; + for (i = 0; i < len; i += 1) { + this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix); + } + } + return matrix.applyToPointArray(arr[0], arr[1], arr[2] || 0); + } + + function invertPoint(matrix, arr) { + if (this._elem.hierarchy && this._elem.hierarchy.length) { + var i; + var len = this._elem.hierarchy.length; + for (i = 0; i < len; i += 1) { + this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix); + } + } + return matrix.inversePoint(arr); + } + + function fromComp(arr) { + var toWorldMat = new Matrix(); + toWorldMat.reset(); + this._elem.finalTransform.mProp.applyToMatrix(toWorldMat); + if (this._elem.hierarchy && this._elem.hierarchy.length) { + var i; + var len = this._elem.hierarchy.length; + for (i = 0; i < len; i += 1) { + this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat); + } + return toWorldMat.inversePoint(arr); + } + return toWorldMat.inversePoint(arr); + } + + function sampleImage() { + return [1, 1, 1, 1]; + } + + return function (elem) { + var transformInterface; + + function _registerMaskInterface(maskManager) { + _thisLayerFunction.mask = new MaskManagerInterface(maskManager, elem); + } + function _registerEffectsInterface(effects) { + _thisLayerFunction.effect = effects; + } + + function _thisLayerFunction(name) { + switch (name) { + case 'ADBE Root Vectors Group': + case 'Contents': + case 2: + return _thisLayerFunction.shapeInterface; + case 1: + case 6: + case 'Transform': + case 'transform': + case 'ADBE Transform Group': + return transformInterface; + case 4: + case 'ADBE Effect Parade': + case 'effects': + case 'Effects': + return _thisLayerFunction.effect; + case 'ADBE Text Properties': + return _thisLayerFunction.textInterface; + default: + return null; + } + } + _thisLayerFunction.getMatrix = getMatrix; + _thisLayerFunction.invertPoint = invertPoint; + _thisLayerFunction.applyPoint = applyPoint; + _thisLayerFunction.toWorld = toWorld; + _thisLayerFunction.toWorldVec = toWorldVec; + _thisLayerFunction.fromWorld = fromWorld; + _thisLayerFunction.fromWorldVec = fromWorldVec; + _thisLayerFunction.toComp = toWorld; + _thisLayerFunction.fromComp = fromComp; + _thisLayerFunction.sampleImage = sampleImage; + _thisLayerFunction.sourceRectAtTime = elem.sourceRectAtTime.bind(elem); + _thisLayerFunction._elem = elem; + transformInterface = TransformExpressionInterface(elem.finalTransform.mProp); + var anchorPointDescriptor = getDescriptor(transformInterface, 'anchorPoint'); + Object.defineProperties(_thisLayerFunction, { + hasParent: { + get: function () { + return elem.hierarchy.length; + }, + }, + parent: { + get: function () { + return elem.hierarchy[0].layerInterface; + }, + }, + rotation: getDescriptor(transformInterface, 'rotation'), + scale: getDescriptor(transformInterface, 'scale'), + position: getDescriptor(transformInterface, 'position'), + opacity: getDescriptor(transformInterface, 'opacity'), + anchorPoint: anchorPointDescriptor, + anchor_point: anchorPointDescriptor, + transform: { + get: function () { + return transformInterface; + }, + }, + active: { + get: function () { + return elem.isInRange; + }, + }, + }); + + _thisLayerFunction.startTime = elem.data.st; + _thisLayerFunction.index = elem.data.ind; + _thisLayerFunction.source = elem.data.refId; + _thisLayerFunction.height = elem.data.ty === 0 ? elem.data.h : 100; + _thisLayerFunction.width = elem.data.ty === 0 ? elem.data.w : 100; + _thisLayerFunction.inPoint = elem.data.ip / elem.comp.globalData.frameRate; + _thisLayerFunction.outPoint = elem.data.op / elem.comp.globalData.frameRate; + _thisLayerFunction._name = elem.data.nm; + + _thisLayerFunction.registerMaskInterface = _registerMaskInterface; + _thisLayerFunction.registerEffectsInterface = _registerEffectsInterface; + return _thisLayerFunction; + }; +}()); + +const propertyGroupFactory = (function () { + return function (interfaceFunction, parentPropertyGroup) { + return function (val) { + val = val === undefined ? 1 : val; + if (val <= 0) { + return interfaceFunction; + } + return parentPropertyGroup(val - 1); + }; + }; +}()); + +const PropertyInterface = (function () { + return function (propertyName, propertyGroup) { + var interfaceFunction = { + _name: propertyName, + }; + + function _propertyGroup(val) { + val = val === undefined ? 1 : val; + if (val <= 0) { + return interfaceFunction; + } + return propertyGroup(val - 1); + } + + return _propertyGroup; + }; +}()); + +const EffectsExpressionInterface = (function () { + var ob = { + createEffectsInterface: createEffectsInterface, + }; + + function createEffectsInterface(elem, propertyGroup) { + if (elem.effectsManager) { + var effectElements = []; + var effectsData = elem.data.ef; + var i; + var len = elem.effectsManager.effectElements.length; + for (i = 0; i < len; i += 1) { + effectElements.push(createGroupInterface(effectsData[i], elem.effectsManager.effectElements[i], propertyGroup, elem)); + } + + var effects = elem.data.ef || []; + var groupInterface = function (name) { + i = 0; + len = effects.length; + while (i < len) { + if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) { + return effectElements[i]; + } + i += 1; + } + return null; + }; + Object.defineProperty(groupInterface, 'numProperties', { + get: function () { + return effects.length; + }, + }); + return groupInterface; + } + return null; + } + + function createGroupInterface(data, elements, propertyGroup, elem) { + function groupInterface(name) { + var effects = data.ef; + var i = 0; + var len = effects.length; + while (i < len) { + if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) { + if (effects[i].ty === 5) { + return effectElements[i]; + } + return effectElements[i](); + } + i += 1; + } + throw new Error(); + } + var _propertyGroup = propertyGroupFactory(groupInterface, propertyGroup); + + var effectElements = []; + var i; + var len = data.ef.length; + for (i = 0; i < len; i += 1) { + if (data.ef[i].ty === 5) { + effectElements.push(createGroupInterface(data.ef[i], elements.effectElements[i], elements.effectElements[i].propertyGroup, elem)); + } else { + effectElements.push(createValueInterface(elements.effectElements[i], data.ef[i].ty, elem, _propertyGroup)); + } + } + + if (data.mn === 'ADBE Color Control') { + Object.defineProperty(groupInterface, 'color', { + get: function () { + return effectElements[0](); + }, + }); + } + Object.defineProperties(groupInterface, { + numProperties: { + get: function () { + return data.np; + }, + }, + _name: { value: data.nm }, + propertyGroup: { value: _propertyGroup }, + }); + groupInterface.enabled = data.en !== 0; + groupInterface.active = groupInterface.enabled; + return groupInterface; + } + + function createValueInterface(element, type, elem, propertyGroup) { + var expressionProperty = ExpressionPropertyInterface(element.p); + function interfaceFunction() { + if (type === 10) { + return elem.comp.compInterface(element.p.v); + } + return expressionProperty(); + } + + if (element.p.setGroupProperty) { + element.p.setGroupProperty(PropertyInterface('', propertyGroup)); + } + + return interfaceFunction; + } + + return ob; +}()); + +const CompExpressionInterface = (function () { + return function (comp) { + function _thisLayerFunction(name) { + var i = 0; + var len = comp.layers.length; + while (i < len) { + if (comp.layers[i].nm === name || comp.layers[i].ind === name) { + return comp.elements[i].layerInterface; + } + i += 1; + } + return null; + // return {active:false}; + } + Object.defineProperty(_thisLayerFunction, '_name', { value: comp.data.nm }); + _thisLayerFunction.layer = _thisLayerFunction; + _thisLayerFunction.pixelAspect = 1; + _thisLayerFunction.height = comp.data.h || comp.globalData.compSize.h; + _thisLayerFunction.width = comp.data.w || comp.globalData.compSize.w; + _thisLayerFunction.pixelAspect = 1; + _thisLayerFunction.frameDuration = 1 / comp.globalData.frameRate; + _thisLayerFunction.displayStartTime = 0; + _thisLayerFunction.numLayers = comp.layers.length; + return _thisLayerFunction; + }; +}()); + +const ShapePathInterface = ( + + function () { + return function pathInterfaceFactory(shape, view, propertyGroup) { + var prop = view.sh; + + function interfaceFunction(val) { + if (val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path' || val === 'ADBE Vector Shape' || val === 2) { + return interfaceFunction.path; + } + return null; + } + + var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup); + prop.setGroupProperty(PropertyInterface('Path', _propertyGroup)); + Object.defineProperties(interfaceFunction, { + path: { + get: function () { + if (prop.k) { + prop.getValue(); + } + return prop; + }, + }, + shape: { + get: function () { + if (prop.k) { + prop.getValue(); + } + return prop; + }, + }, + _name: { value: shape.nm }, + ix: { value: shape.ix }, + propertyIndex: { value: shape.ix }, + mn: { value: shape.mn }, + propertyGroup: { value: propertyGroup }, + }); + return interfaceFunction; + }; + }() +); + +const ShapeExpressionInterface = (function () { + function iterateElements(shapes, view, propertyGroup) { + var arr = []; + var i; + var len = shapes ? shapes.length : 0; + for (i = 0; i < len; i += 1) { + if (shapes[i].ty === 'gr') { + arr.push(groupInterfaceFactory(shapes[i], view[i], propertyGroup)); + } else if (shapes[i].ty === 'fl') { + arr.push(fillInterfaceFactory(shapes[i], view[i], propertyGroup)); + } else if (shapes[i].ty === 'st') { + arr.push(strokeInterfaceFactory(shapes[i], view[i], propertyGroup)); + } else if (shapes[i].ty === 'tm') { + arr.push(trimInterfaceFactory(shapes[i], view[i], propertyGroup)); + } else if (shapes[i].ty === 'tr') { + // arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup)); + } else if (shapes[i].ty === 'el') { + arr.push(ellipseInterfaceFactory(shapes[i], view[i], propertyGroup)); + } else if (shapes[i].ty === 'sr') { + arr.push(starInterfaceFactory(shapes[i], view[i], propertyGroup)); + } else if (shapes[i].ty === 'sh') { + arr.push(ShapePathInterface(shapes[i], view[i], propertyGroup)); + } else if (shapes[i].ty === 'rc') { + arr.push(rectInterfaceFactory(shapes[i], view[i], propertyGroup)); + } else if (shapes[i].ty === 'rd') { + arr.push(roundedInterfaceFactory(shapes[i], view[i], propertyGroup)); + } else if (shapes[i].ty === 'rp') { + arr.push(repeaterInterfaceFactory(shapes[i], view[i], propertyGroup)); + } else if (shapes[i].ty === 'gf') { + arr.push(gradientFillInterfaceFactory(shapes[i], view[i], propertyGroup)); + } else { + arr.push(defaultInterfaceFactory(shapes[i], view[i], propertyGroup)); + } + } + return arr; + } + + function contentsInterfaceFactory(shape, view, propertyGroup) { + var interfaces; + var interfaceFunction = function _interfaceFunction(value) { + var i = 0; + var len = interfaces.length; + while (i < len) { + if (interfaces[i]._name === value || interfaces[i].mn === value || interfaces[i].propertyIndex === value || interfaces[i].ix === value || interfaces[i].ind === value) { + return interfaces[i]; + } + i += 1; + } + if (typeof value === 'number') { + return interfaces[value - 1]; + } + return null; + }; + + interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup); + interfaces = iterateElements(shape.it, view.it, interfaceFunction.propertyGroup); + interfaceFunction.numProperties = interfaces.length; + var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup); + interfaceFunction.transform = transformInterface; + interfaceFunction.propertyIndex = shape.cix; + interfaceFunction._name = shape.nm; + + return interfaceFunction; + } + + function groupInterfaceFactory(shape, view, propertyGroup) { + var interfaceFunction = function _interfaceFunction(value) { + switch (value) { + case 'ADBE Vectors Group': + case 'Contents': + case 2: + return interfaceFunction.content; + // Not necessary for now. Keeping them here in case a new case appears + // case 'ADBE Vector Transform Group': + // case 3: + default: + return interfaceFunction.transform; + } + }; + interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup); + var content = contentsInterfaceFactory(shape, view, interfaceFunction.propertyGroup); + var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup); + interfaceFunction.content = content; + interfaceFunction.transform = transformInterface; + Object.defineProperty(interfaceFunction, '_name', { + get: function () { + return shape.nm; + }, + }); + // interfaceFunction.content = interfaceFunction; + interfaceFunction.numProperties = shape.np; + interfaceFunction.propertyIndex = shape.ix; + interfaceFunction.nm = shape.nm; + interfaceFunction.mn = shape.mn; + return interfaceFunction; + } + + function fillInterfaceFactory(shape, view, propertyGroup) { + function interfaceFunction(val) { + if (val === 'Color' || val === 'color') { + return interfaceFunction.color; + } if (val === 'Opacity' || val === 'opacity') { + return interfaceFunction.opacity; + } + return null; + } + Object.defineProperties(interfaceFunction, { + color: { + get: ExpressionPropertyInterface(view.c), + }, + opacity: { + get: ExpressionPropertyInterface(view.o), + }, + _name: { value: shape.nm }, + mn: { value: shape.mn }, + }); + + view.c.setGroupProperty(PropertyInterface('Color', propertyGroup)); + view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup)); + return interfaceFunction; + } + + function gradientFillInterfaceFactory(shape, view, propertyGroup) { + function interfaceFunction(val) { + if (val === 'Start Point' || val === 'start point') { + return interfaceFunction.startPoint; + } + if (val === 'End Point' || val === 'end point') { + return interfaceFunction.endPoint; + } + if (val === 'Opacity' || val === 'opacity') { + return interfaceFunction.opacity; + } + return null; + } + Object.defineProperties(interfaceFunction, { + startPoint: { + get: ExpressionPropertyInterface(view.s), + }, + endPoint: { + get: ExpressionPropertyInterface(view.e), + }, + opacity: { + get: ExpressionPropertyInterface(view.o), + }, + type: { + get: function () { + return 'a'; + }, + }, + _name: { value: shape.nm }, + mn: { value: shape.mn }, + }); + + view.s.setGroupProperty(PropertyInterface('Start Point', propertyGroup)); + view.e.setGroupProperty(PropertyInterface('End Point', propertyGroup)); + view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup)); + return interfaceFunction; + } + function defaultInterfaceFactory() { + function interfaceFunction() { + return null; + } + return interfaceFunction; + } + + function strokeInterfaceFactory(shape, view, propertyGroup) { + var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup); + var _dashPropertyGroup = propertyGroupFactory(dashOb, _propertyGroup); + function addPropertyToDashOb(i) { + Object.defineProperty(dashOb, shape.d[i].nm, { + get: ExpressionPropertyInterface(view.d.dataProps[i].p), + }); + } + var i; + var len = shape.d ? shape.d.length : 0; + var dashOb = {}; + for (i = 0; i < len; i += 1) { + addPropertyToDashOb(i); + view.d.dataProps[i].p.setGroupProperty(_dashPropertyGroup); + } + + function interfaceFunction(val) { + if (val === 'Color' || val === 'color') { + return interfaceFunction.color; + } if (val === 'Opacity' || val === 'opacity') { + return interfaceFunction.opacity; + } if (val === 'Stroke Width' || val === 'stroke width') { + return interfaceFunction.strokeWidth; + } + return null; + } + Object.defineProperties(interfaceFunction, { + color: { + get: ExpressionPropertyInterface(view.c), + }, + opacity: { + get: ExpressionPropertyInterface(view.o), + }, + strokeWidth: { + get: ExpressionPropertyInterface(view.w), + }, + dash: { + get: function () { + return dashOb; + }, + }, + _name: { value: shape.nm }, + mn: { value: shape.mn }, + }); + + view.c.setGroupProperty(PropertyInterface('Color', _propertyGroup)); + view.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup)); + view.w.setGroupProperty(PropertyInterface('Stroke Width', _propertyGroup)); + return interfaceFunction; + } + + function trimInterfaceFactory(shape, view, propertyGroup) { + function interfaceFunction(val) { + if (val === shape.e.ix || val === 'End' || val === 'end') { + return interfaceFunction.end; + } + if (val === shape.s.ix) { + return interfaceFunction.start; + } + if (val === shape.o.ix) { + return interfaceFunction.offset; + } + return null; + } + + var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup); + interfaceFunction.propertyIndex = shape.ix; + + view.s.setGroupProperty(PropertyInterface('Start', _propertyGroup)); + view.e.setGroupProperty(PropertyInterface('End', _propertyGroup)); + view.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup)); + interfaceFunction.propertyIndex = shape.ix; + interfaceFunction.propertyGroup = propertyGroup; + + Object.defineProperties(interfaceFunction, { + start: { + get: ExpressionPropertyInterface(view.s), + }, + end: { + get: ExpressionPropertyInterface(view.e), + }, + offset: { + get: ExpressionPropertyInterface(view.o), + }, + _name: { value: shape.nm }, + }); + interfaceFunction.mn = shape.mn; + return interfaceFunction; + } + + function transformInterfaceFactory(shape, view, propertyGroup) { + function interfaceFunction(value) { + if (shape.a.ix === value || value === 'Anchor Point') { + return interfaceFunction.anchorPoint; + } + if (shape.o.ix === value || value === 'Opacity') { + return interfaceFunction.opacity; + } + if (shape.p.ix === value || value === 'Position') { + return interfaceFunction.position; + } + if (shape.r.ix === value || value === 'Rotation' || value === 'ADBE Vector Rotation') { + return interfaceFunction.rotation; + } + if (shape.s.ix === value || value === 'Scale') { + return interfaceFunction.scale; + } + if ((shape.sk && shape.sk.ix === value) || value === 'Skew') { + return interfaceFunction.skew; + } + if ((shape.sa && shape.sa.ix === value) || value === 'Skew Axis') { + return interfaceFunction.skewAxis; + } + return null; + } + var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup); + view.transform.mProps.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup)); + view.transform.mProps.p.setGroupProperty(PropertyInterface('Position', _propertyGroup)); + view.transform.mProps.a.setGroupProperty(PropertyInterface('Anchor Point', _propertyGroup)); + view.transform.mProps.s.setGroupProperty(PropertyInterface('Scale', _propertyGroup)); + view.transform.mProps.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup)); + if (view.transform.mProps.sk) { + view.transform.mProps.sk.setGroupProperty(PropertyInterface('Skew', _propertyGroup)); + view.transform.mProps.sa.setGroupProperty(PropertyInterface('Skew Angle', _propertyGroup)); + } + view.transform.op.setGroupProperty(PropertyInterface('Opacity', _propertyGroup)); + Object.defineProperties(interfaceFunction, { + opacity: { + get: ExpressionPropertyInterface(view.transform.mProps.o), + }, + position: { + get: ExpressionPropertyInterface(view.transform.mProps.p), + }, + anchorPoint: { + get: ExpressionPropertyInterface(view.transform.mProps.a), + }, + scale: { + get: ExpressionPropertyInterface(view.transform.mProps.s), + }, + rotation: { + get: ExpressionPropertyInterface(view.transform.mProps.r), + }, + skew: { + get: ExpressionPropertyInterface(view.transform.mProps.sk), + }, + skewAxis: { + get: ExpressionPropertyInterface(view.transform.mProps.sa), + }, + _name: { value: shape.nm }, + }); + interfaceFunction.ty = 'tr'; + interfaceFunction.mn = shape.mn; + interfaceFunction.propertyGroup = propertyGroup; + return interfaceFunction; + } + + function ellipseInterfaceFactory(shape, view, propertyGroup) { + function interfaceFunction(value) { + if (shape.p.ix === value) { + return interfaceFunction.position; + } + if (shape.s.ix === value) { + return interfaceFunction.size; + } + return null; + } + var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup); + interfaceFunction.propertyIndex = shape.ix; + var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh; + prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup)); + prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup)); + + Object.defineProperties(interfaceFunction, { + size: { + get: ExpressionPropertyInterface(prop.s), + }, + position: { + get: ExpressionPropertyInterface(prop.p), + }, + _name: { value: shape.nm }, + }); + interfaceFunction.mn = shape.mn; + return interfaceFunction; + } + + function starInterfaceFactory(shape, view, propertyGroup) { + function interfaceFunction(value) { + if (shape.p.ix === value) { + return interfaceFunction.position; + } + if (shape.r.ix === value) { + return interfaceFunction.rotation; + } + if (shape.pt.ix === value) { + return interfaceFunction.points; + } + if (shape.or.ix === value || value === 'ADBE Vector Star Outer Radius') { + return interfaceFunction.outerRadius; + } + if (shape.os.ix === value) { + return interfaceFunction.outerRoundness; + } + if (shape.ir && (shape.ir.ix === value || value === 'ADBE Vector Star Inner Radius')) { + return interfaceFunction.innerRadius; + } + if (shape.is && shape.is.ix === value) { + return interfaceFunction.innerRoundness; + } + return null; + } + + var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup); + var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh; + interfaceFunction.propertyIndex = shape.ix; + prop.or.setGroupProperty(PropertyInterface('Outer Radius', _propertyGroup)); + prop.os.setGroupProperty(PropertyInterface('Outer Roundness', _propertyGroup)); + prop.pt.setGroupProperty(PropertyInterface('Points', _propertyGroup)); + prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup)); + prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup)); + if (shape.ir) { + prop.ir.setGroupProperty(PropertyInterface('Inner Radius', _propertyGroup)); + prop.is.setGroupProperty(PropertyInterface('Inner Roundness', _propertyGroup)); + } + + Object.defineProperties(interfaceFunction, { + position: { + get: ExpressionPropertyInterface(prop.p), + }, + rotation: { + get: ExpressionPropertyInterface(prop.r), + }, + points: { + get: ExpressionPropertyInterface(prop.pt), + }, + outerRadius: { + get: ExpressionPropertyInterface(prop.or), + }, + outerRoundness: { + get: ExpressionPropertyInterface(prop.os), + }, + innerRadius: { + get: ExpressionPropertyInterface(prop.ir), + }, + innerRoundness: { + get: ExpressionPropertyInterface(prop.is), + }, + _name: { value: shape.nm }, + }); + interfaceFunction.mn = shape.mn; + return interfaceFunction; + } + + function rectInterfaceFactory(shape, view, propertyGroup) { + function interfaceFunction(value) { + if (shape.p.ix === value) { + return interfaceFunction.position; + } + if (shape.r.ix === value) { + return interfaceFunction.roundness; + } + if (shape.s.ix === value || value === 'Size' || value === 'ADBE Vector Rect Size') { + return interfaceFunction.size; + } + return null; + } + var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup); + + var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh; + interfaceFunction.propertyIndex = shape.ix; + prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup)); + prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup)); + prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup)); + + Object.defineProperties(interfaceFunction, { + position: { + get: ExpressionPropertyInterface(prop.p), + }, + roundness: { + get: ExpressionPropertyInterface(prop.r), + }, + size: { + get: ExpressionPropertyInterface(prop.s), + }, + _name: { value: shape.nm }, + }); + interfaceFunction.mn = shape.mn; + return interfaceFunction; + } + + function roundedInterfaceFactory(shape, view, propertyGroup) { + function interfaceFunction(value) { + if (shape.r.ix === value || value === 'Round Corners 1') { + return interfaceFunction.radius; + } + return null; + } + + var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup); + var prop = view; + interfaceFunction.propertyIndex = shape.ix; + prop.rd.setGroupProperty(PropertyInterface('Radius', _propertyGroup)); + + Object.defineProperties(interfaceFunction, { + radius: { + get: ExpressionPropertyInterface(prop.rd), + }, + _name: { value: shape.nm }, + }); + interfaceFunction.mn = shape.mn; + return interfaceFunction; + } + + function repeaterInterfaceFactory(shape, view, propertyGroup) { + function interfaceFunction(value) { + if (shape.c.ix === value || value === 'Copies') { + return interfaceFunction.copies; + } if (shape.o.ix === value || value === 'Offset') { + return interfaceFunction.offset; + } + return null; + } + + var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup); + var prop = view; + interfaceFunction.propertyIndex = shape.ix; + prop.c.setGroupProperty(PropertyInterface('Copies', _propertyGroup)); + prop.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup)); + Object.defineProperties(interfaceFunction, { + copies: { + get: ExpressionPropertyInterface(prop.c), + }, + offset: { + get: ExpressionPropertyInterface(prop.o), + }, + _name: { value: shape.nm }, + }); + interfaceFunction.mn = shape.mn; + return interfaceFunction; + } + + return function (shapes, view, propertyGroup) { + var interfaces; + function _interfaceFunction(value) { + if (typeof value === 'number') { + value = value === undefined ? 1 : value; + if (value === 0) { + return propertyGroup; + } + return interfaces[value - 1]; + } + var i = 0; + var len = interfaces.length; + while (i < len) { + if (interfaces[i]._name === value) { + return interfaces[i]; + } + i += 1; + } + return null; + } + function parentGroupWrapper() { + return propertyGroup; + } + _interfaceFunction.propertyGroup = propertyGroupFactory(_interfaceFunction, parentGroupWrapper); + interfaces = iterateElements(shapes, view, _interfaceFunction.propertyGroup); + _interfaceFunction.numProperties = interfaces.length; + _interfaceFunction._name = 'Contents'; + return _interfaceFunction; + }; +}()); + +const TextExpressionInterface = (function () { + return function (elem) { + var _prevValue; + var _sourceText; + function _thisLayerFunction(name) { + switch (name) { + case 'ADBE Text Document': + return _thisLayerFunction.sourceText; + default: + return null; + } + } + Object.defineProperty(_thisLayerFunction, 'sourceText', { + get: function () { + elem.textProperty.getValue(); + var stringValue = elem.textProperty.currentData.t; + if (stringValue !== _prevValue) { + elem.textProperty.currentData.t = _prevValue; + _sourceText = new String(stringValue); // eslint-disable-line no-new-wrappers + // If stringValue is an empty string, eval returns undefined, so it has to be returned as a String primitive + _sourceText.value = stringValue || new String(stringValue); // eslint-disable-line no-new-wrappers + } + return _sourceText; + }, + }); + return _thisLayerFunction; + }; +}()); + +const getBlendMode = (function () { + var blendModeEnums = { + 0: 'source-over', + 1: 'multiply', + 2: 'screen', + 3: 'overlay', + 4: 'darken', + 5: 'lighten', + 6: 'color-dodge', + 7: 'color-burn', + 8: 'hard-light', + 9: 'soft-light', + 10: 'difference', + 11: 'exclusion', + 12: 'hue', + 13: 'saturation', + 14: 'color', + 15: 'luminosity', + }; + + return function (mode) { + return blendModeEnums[mode] || ''; + }; +}()); + +function SliderEffect(data, elem, container) { + this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container); +} +function AngleEffect(data, elem, container) { + this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container); +} +function ColorEffect(data, elem, container) { + this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container); +} +function PointEffect(data, elem, container) { + this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container); +} +function LayerIndexEffect(data, elem, container) { + this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container); +} +function MaskIndexEffect(data, elem, container) { + this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container); +} +function CheckboxEffect(data, elem, container) { + this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container); +} +function NoValueEffect() { + this.p = {}; +} + +function EffectsManager(data, element) { + var effects = data.ef || []; + this.effectElements = []; + var i; + var len = effects.length; + var effectItem; + for (i = 0; i < len; i += 1) { + effectItem = new GroupEffect(effects[i], element); + this.effectElements.push(effectItem); + } +} + +function GroupEffect(data, element) { + this.init(data, element); +} + +extendPrototype([DynamicPropertyContainer], GroupEffect); + +GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties; + +GroupEffect.prototype.init = function (data, element) { + this.data = data; + this.effectElements = []; + this.initDynamicPropertyContainer(element); + var i; + var len = this.data.ef.length; + var eff; + var effects = this.data.ef; + for (i = 0; i < len; i += 1) { + eff = null; + switch (effects[i].ty) { + case 0: + eff = new SliderEffect(effects[i], element, this); + break; + case 1: + eff = new AngleEffect(effects[i], element, this); + break; + case 2: + eff = new ColorEffect(effects[i], element, this); + break; + case 3: + eff = new PointEffect(effects[i], element, this); + break; + case 4: + case 7: + eff = new CheckboxEffect(effects[i], element, this); + break; + case 10: + eff = new LayerIndexEffect(effects[i], element, this); + break; + case 11: + eff = new MaskIndexEffect(effects[i], element, this); + break; + case 5: + eff = new EffectsManager(effects[i], element, this); + break; + // case 6: + default: + eff = new NoValueEffect(effects[i], element, this); + break; + } + if (eff) { + this.effectElements.push(eff); + } + } +}; + +function BaseElement() { +} + +BaseElement.prototype = { + checkMasks: function () { + if (!this.data.hasMask) { + return false; + } + var i = 0; + var len = this.data.masksProperties.length; + while (i < len) { + if ((this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false)) { + return true; + } + i += 1; + } + return false; + }, + initExpressions: function () { + this.layerInterface = LayerExpressionInterface(this); + if (this.data.hasMask && this.maskManager) { + this.layerInterface.registerMaskInterface(this.maskManager); + } + var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface); + this.layerInterface.registerEffectsInterface(effectsInterface); + + if (this.data.ty === 0 || this.data.xt) { + this.compInterface = CompExpressionInterface(this); + } else if (this.data.ty === 4) { + this.layerInterface.shapeInterface = ShapeExpressionInterface(this.shapesData, this.itemsData, this.layerInterface); + this.layerInterface.content = this.layerInterface.shapeInterface; + } else if (this.data.ty === 5) { + this.layerInterface.textInterface = TextExpressionInterface(this); + this.layerInterface.text = this.layerInterface.textInterface; + } + }, + setBlendMode: function () { + var blendModeValue = getBlendMode(this.data.bm); + var elem = this.baseElement || this.layerElement; + + elem.style['mix-blend-mode'] = blendModeValue; + }, + initBaseData: function (data, globalData, comp) { + this.globalData = globalData; + this.comp = comp; + this.data = data; + this.layerId = createElementID(); + + // Stretch factor for old animations missing this property. + if (!this.data.sr) { + this.data.sr = 1; + } + // effects manager + this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties); + }, + getType: function () { + return this.type; + }, + sourceRectAtTime: function () {}, +}; + +/** + * @file + * Handles element's layer frame update. + * Checks layer in point and out point + * + */ + +function FrameElement() {} + +FrameElement.prototype = { + /** + * @function + * Initializes frame related properties. + * + */ + initFrame: function () { + // set to true when inpoint is rendered + this._isFirstFrame = false; + // list of animated properties + this.dynamicProperties = []; + // If layer has been modified in current tick this will be true + this._mdf = false; + }, + /** + * @function + * Calculates all dynamic values + * + * @param {number} num + * current frame number in Layer's time + * @param {boolean} isVisible + * if layers is currently in range + * + */ + prepareProperties: function (num, isVisible) { + var i; + var len = this.dynamicProperties.length; + for (i = 0; i < len; i += 1) { + if (isVisible || (this._isParent && this.dynamicProperties[i].propType === 'transform')) { + this.dynamicProperties[i].getValue(); + if (this.dynamicProperties[i]._mdf) { + this.globalData._mdf = true; + this._mdf = true; + } + } + } + }, + addDynamicProperty: function (prop) { + if (this.dynamicProperties.indexOf(prop) === -1) { + this.dynamicProperties.push(prop); + } + }, +}; + +const FootageInterface = (function () { + var outlineInterfaceFactory = (function (elem) { + var currentPropertyName = ''; + var currentProperty = elem.getFootageData(); + function init() { + currentPropertyName = ''; + currentProperty = elem.getFootageData(); + return searchProperty; + } + function searchProperty(value) { + if (currentProperty[value]) { + currentPropertyName = value; + currentProperty = currentProperty[value]; + if (typeof currentProperty === 'object') { + return searchProperty; + } + return currentProperty; + } + var propertyNameIndex = value.indexOf(currentPropertyName); + if (propertyNameIndex !== -1) { + var index = parseInt(value.substr(propertyNameIndex + currentPropertyName.length), 10); + currentProperty = currentProperty[index]; + if (typeof currentProperty === 'object') { + return searchProperty; + } + return currentProperty; + } + return ''; + } + return init; + }); + + var dataInterfaceFactory = function (elem) { + function interfaceFunction(value) { + if (value === 'Outline') { + return interfaceFunction.outlineInterface(); + } + return null; + } + + interfaceFunction._name = 'Outline'; + interfaceFunction.outlineInterface = outlineInterfaceFactory(elem); + return interfaceFunction; + }; + + return function (elem) { + function _interfaceFunction(value) { + if (value === 'Data') { + return _interfaceFunction.dataInterface; + } + return null; + } + + _interfaceFunction._name = 'Data'; + _interfaceFunction.dataInterface = dataInterfaceFactory(elem); + return _interfaceFunction; + }; +}()); + +function FootageElement(data, globalData, comp) { + this.initFrame(); + this.initRenderable(); + this.assetData = globalData.getAssetData(data.refId); + this.footageData = globalData.imageLoader.getAsset(this.assetData); + this.initBaseData(data, globalData, comp); +} + +FootageElement.prototype.prepareFrame = function () { +}; + +extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement); + +FootageElement.prototype.getBaseElement = function () { + return null; +}; + +FootageElement.prototype.renderFrame = function () { +}; + +FootageElement.prototype.destroy = function () { +}; + +FootageElement.prototype.initExpressions = function () { + this.layerInterface = FootageInterface(this); +}; + +FootageElement.prototype.getFootageData = function () { + return this.footageData; +}; + +function AudioElement(data, globalData, comp) { + this.initFrame(); + this.initRenderable(); + this.assetData = globalData.getAssetData(data.refId); + this.initBaseData(data, globalData, comp); + this._isPlaying = false; + this._canPlay = false; + var assetPath = this.globalData.getAssetsPath(this.assetData); + this.audio = this.globalData.audioController.createAudio(assetPath); + this._currentTime = 0; + this.globalData.audioController.addAudio(this); + this._volumeMultiplier = 1; + this._volume = 1; + this._previousVolume = null; + this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true }; + this.lv = PropertyFactory.getProp(this, data.au && data.au.lv ? data.au.lv : { k: [100] }, 1, 0.01, this); +} + +AudioElement.prototype.prepareFrame = function (num) { + this.prepareRenderableFrame(num, true); + this.prepareProperties(num, true); + if (!this.tm._placeholder) { + var timeRemapped = this.tm.v; + this._currentTime = timeRemapped; + } else { + this._currentTime = num / this.data.sr; + } + this._volume = this.lv.v[0]; + var totalVolume = this._volume * this._volumeMultiplier; + if (this._previousVolume !== totalVolume) { + this._previousVolume = totalVolume; + this.audio.volume(totalVolume); + } +}; + +extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement); + +AudioElement.prototype.renderFrame = function () { + if (this.isInRange && this._canPlay) { + if (!this._isPlaying) { + this.audio.play(); + this.audio.seek(this._currentTime / this.globalData.frameRate); + this._isPlaying = true; + } else if (!this.audio.playing() + || Math.abs(this._currentTime / this.globalData.frameRate - this.audio.seek()) > 0.1 + ) { + this.audio.seek(this._currentTime / this.globalData.frameRate); + } + } +}; + +AudioElement.prototype.show = function () { + // this.audio.play() +}; + +AudioElement.prototype.hide = function () { + this.audio.pause(); + this._isPlaying = false; +}; + +AudioElement.prototype.pause = function () { + this.audio.pause(); + this._isPlaying = false; + this._canPlay = false; +}; + +AudioElement.prototype.resume = function () { + this._canPlay = true; +}; + +AudioElement.prototype.setRate = function (rateValue) { + this.audio.rate(rateValue); +}; + +AudioElement.prototype.volume = function (volumeValue) { + this._volumeMultiplier = volumeValue; + this._previousVolume = volumeValue * this._volume; + this.audio.volume(this._previousVolume); +}; + +AudioElement.prototype.getBaseElement = function () { + return null; +}; + +AudioElement.prototype.destroy = function () { +}; + +AudioElement.prototype.sourceRectAtTime = function () { +}; + +AudioElement.prototype.initExpressions = function () { +}; + +function BaseRenderer() {} +BaseRenderer.prototype.checkLayers = function (num) { + var i; + var len = this.layers.length; + var data; + this.completeLayers = true; + for (i = len - 1; i >= 0; i -= 1) { + if (!this.elements[i]) { + data = this.layers[i]; + if (data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st)) { + this.buildItem(i); + } + } + this.completeLayers = this.elements[i] ? this.completeLayers : false; + } + this.checkPendingElements(); +}; + +BaseRenderer.prototype.createItem = function (layer) { + switch (layer.ty) { + case 2: + return this.createImage(layer); + case 0: + return this.createComp(layer); + case 1: + return this.createSolid(layer); + case 3: + return this.createNull(layer); + case 4: + return this.createShape(layer); + case 5: + return this.createText(layer); + case 6: + return this.createAudio(layer); + case 13: + return this.createCamera(layer); + case 15: + return this.createFootage(layer); + default: + return this.createNull(layer); + } +}; + +BaseRenderer.prototype.createCamera = function () { + throw new Error('You\'re using a 3d camera. Try the html renderer.'); +}; + +BaseRenderer.prototype.createAudio = function (data) { + return new AudioElement(data, this.globalData, this); +}; + +BaseRenderer.prototype.createFootage = function (data) { + return new FootageElement(data, this.globalData, this); +}; + +BaseRenderer.prototype.buildAllItems = function () { + var i; + var len = this.layers.length; + for (i = 0; i < len; i += 1) { + this.buildItem(i); + } + this.checkPendingElements(); +}; + +BaseRenderer.prototype.includeLayers = function (newLayers) { + this.completeLayers = false; + var i; + var len = newLayers.length; + var j; + var jLen = this.layers.length; + for (i = 0; i < len; i += 1) { + j = 0; + while (j < jLen) { + if (this.layers[j].id === newLayers[i].id) { + this.layers[j] = newLayers[i]; + break; + } + j += 1; + } + } +}; + +BaseRenderer.prototype.setProjectInterface = function (pInterface) { + this.globalData.projectInterface = pInterface; +}; + +BaseRenderer.prototype.initItems = function () { + if (!this.globalData.progressiveLoad) { + this.buildAllItems(); + } +}; +BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) { + var elements = this.elements; + var layers = this.layers; + var i = 0; + var len = layers.length; + while (i < len) { + if (layers[i].ind == parentName) { // eslint-disable-line eqeqeq + if (!elements[i] || elements[i] === true) { + this.buildItem(i); + this.addPendingElement(element); + } else { + hierarchy.push(elements[i]); + elements[i].setAsParent(); + if (layers[i].parent !== undefined) { + this.buildElementParenting(element, layers[i].parent, hierarchy); + } else { + element.setHierarchy(hierarchy); + } + } + } + i += 1; + } +}; + +BaseRenderer.prototype.addPendingElement = function (element) { + this.pendingElements.push(element); +}; + +BaseRenderer.prototype.searchExtraCompositions = function (assets) { + var i; + var len = assets.length; + for (i = 0; i < len; i += 1) { + if (assets[i].xt) { + var comp = this.createComp(assets[i]); + comp.initExpressions(); + this.globalData.projectInterface.registerComposition(comp); + } + } +}; + +BaseRenderer.prototype.getElementByPath = function (path) { + var pathValue = path.shift(); + var element; + if (typeof pathValue === 'number') { + element = this.elements[pathValue]; + } else { + var i; + var len = this.elements.length; + for (i = 0; i < len; i += 1) { + if (this.elements[i].data.nm === pathValue) { + element = this.elements[i]; + break; + } + } + } + if (path.length === 0) { + return element; + } + return element.getElementByPath(path); +}; + +BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) { + this.globalData.fontManager = new FontManager(); + this.globalData.fontManager.addChars(animData.chars); + this.globalData.fontManager.addFonts(animData.fonts, fontsContainer); + this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem); + this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem); + this.globalData.imageLoader = this.animationItem.imagePreloader; + this.globalData.audioController = this.animationItem.audioController; + this.globalData.frameId = 0; + this.globalData.frameRate = animData.fr; + this.globalData.nm = animData.nm; + this.globalData.compSize = { + w: animData.w, + h: animData.h, + }; +}; + +function TransformElement() {} + +TransformElement.prototype = { + initTransform: function () { + this.finalTransform = { + mProp: this.data.ks ? TransformPropertyFactory.getTransformProperty(this, this.data.ks, this) : { o: 0 }, + _matMdf: false, + _opMdf: false, + mat: new Matrix(), + }; + if (this.data.ao) { + this.finalTransform.mProp.autoOriented = true; + } + + // TODO: check TYPE 11: Guided elements + if (this.data.ty !== 11) { + // this.createElements(); + } + }, + renderTransform: function () { + this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame; + this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame; + + if (this.hierarchy) { + var mat; + var finalMat = this.finalTransform.mat; + var i = 0; + var len = this.hierarchy.length; + // Checking if any of the transformation matrices in the hierarchy chain has changed. + if (!this.finalTransform._matMdf) { + while (i < len) { + if (this.hierarchy[i].finalTransform.mProp._mdf) { + this.finalTransform._matMdf = true; + break; + } + i += 1; + } + } + + if (this.finalTransform._matMdf) { + mat = this.finalTransform.mProp.v.props; + finalMat.cloneFromProps(mat); + for (i = 0; i < len; i += 1) { + mat = this.hierarchy[i].finalTransform.mProp.v.props; + finalMat.transform(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]); + } + } + } + }, + globalToLocal: function (pt) { + var transforms = []; + transforms.push(this.finalTransform); + var flag = true; + var comp = this.comp; + while (flag) { + if (comp.finalTransform) { + if (comp.data.hasMask) { + transforms.splice(0, 0, comp.finalTransform); + } + comp = comp.comp; + } else { + flag = false; + } + } + var i; + var len = transforms.length; + var ptNew; + for (i = 0; i < len; i += 1) { + ptNew = transforms[i].mat.applyToPointArray(0, 0, 0); + // ptNew = transforms[i].mat.applyToPointArray(pt[0],pt[1],pt[2]); + pt = [pt[0] - ptNew[0], pt[1] - ptNew[1], 0]; + } + return pt; + }, + mHelper: new Matrix(), +}; + +function MaskElement(data, element, globalData) { + this.data = data; + this.element = element; + this.globalData = globalData; + this.storedData = []; + this.masksProperties = this.data.masksProperties || []; + this.maskElement = null; + var defs = this.globalData.defs; + var i; + var len = this.masksProperties ? this.masksProperties.length : 0; + this.viewData = createSizedArray(len); + this.solidPath = ''; + + var path; + var properties = this.masksProperties; + var count = 0; + var currentMasks = []; + var j; + var jLen; + var layerId = createElementID(); + var rect; + var expansor; + var feMorph; + var x; + var maskType = 'clipPath'; + var maskRef = 'clip-path'; + for (i = 0; i < len; i += 1) { + if ((properties[i].mode !== 'a' && properties[i].mode !== 'n') || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) { + maskType = 'mask'; + maskRef = 'mask'; + } + + if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) { + rect = createNS('rect'); + rect.setAttribute('fill', '#ffffff'); + rect.setAttribute('width', this.element.comp.data.w || 0); + rect.setAttribute('height', this.element.comp.data.h || 0); + currentMasks.push(rect); + } else { + rect = null; + } + + path = createNS('path'); + if (properties[i].mode === 'n') { + // TODO move this to a factory or to a constructor + this.viewData[i] = { + op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element), + prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3), + elem: path, + lastPath: '', + }; + defs.appendChild(path); + } else { + count += 1; + + path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff'); + path.setAttribute('clip-rule', 'nonzero'); + var filterID; + + if (properties[i].x.k !== 0) { + maskType = 'mask'; + maskRef = 'mask'; + x = PropertyFactory.getProp(this.element, properties[i].x, 0, null, this.element); + filterID = createElementID(); + expansor = createNS('filter'); + expansor.setAttribute('id', filterID); + feMorph = createNS('feMorphology'); + feMorph.setAttribute('operator', 'erode'); + feMorph.setAttribute('in', 'SourceGraphic'); + feMorph.setAttribute('radius', '0'); + expansor.appendChild(feMorph); + defs.appendChild(expansor); + path.setAttribute('stroke', properties[i].mode === 's' ? '#000000' : '#ffffff'); + } else { + feMorph = null; + x = null; + } + + // TODO move this to a factory or to a constructor + this.storedData[i] = { + elem: path, + x: x, + expan: feMorph, + lastPath: '', + lastOperator: '', + filterId: filterID, + lastRadius: 0, + }; + if (properties[i].mode === 'i') { + jLen = currentMasks.length; + var g = createNS('g'); + for (j = 0; j < jLen; j += 1) { + g.appendChild(currentMasks[j]); + } + var mask = createNS('mask'); + mask.setAttribute('mask-type', 'alpha'); + mask.setAttribute('id', layerId + '_' + count); + mask.appendChild(path); + defs.appendChild(mask); + g.setAttribute('mask', 'url(' + getLocationHref() + '#' + layerId + '_' + count + ')'); + + currentMasks.length = 0; + currentMasks.push(g); + } else { + currentMasks.push(path); + } + if (properties[i].inv && !this.solidPath) { + this.solidPath = this.createLayerSolidPath(); + } + // TODO move this to a factory or to a constructor + this.viewData[i] = { + elem: path, + lastPath: '', + op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element), + prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3), + invRect: rect, + }; + if (!this.viewData[i].prop.k) { + this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]); + } + } + } + + this.maskElement = createNS(maskType); + + len = currentMasks.length; + for (i = 0; i < len; i += 1) { + this.maskElement.appendChild(currentMasks[i]); + } + + if (count > 0) { + this.maskElement.setAttribute('id', layerId); + this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')'); + defs.appendChild(this.maskElement); + } + if (this.viewData.length) { + this.element.addRenderableComponent(this); + } +} + +MaskElement.prototype.getMaskProperty = function (pos) { + return this.viewData[pos].prop; +}; + +MaskElement.prototype.renderFrame = function (isFirstFrame) { + var finalMat = this.element.finalTransform.mat; + var i; + var len = this.masksProperties.length; + for (i = 0; i < len; i += 1) { + if (this.viewData[i].prop._mdf || isFirstFrame) { + this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]); + } + if (this.viewData[i].op._mdf || isFirstFrame) { + this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v); + } + if (this.masksProperties[i].mode !== 'n') { + if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) { + this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS()); + } + if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) { + var feMorph = this.storedData[i].expan; + if (this.storedData[i].x.v < 0) { + if (this.storedData[i].lastOperator !== 'erode') { + this.storedData[i].lastOperator = 'erode'; + this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')'); + } + feMorph.setAttribute('radius', -this.storedData[i].x.v); + } else { + if (this.storedData[i].lastOperator !== 'dilate') { + this.storedData[i].lastOperator = 'dilate'; + this.storedData[i].elem.setAttribute('filter', null); + } + this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2); + } + } + } + } +}; + +MaskElement.prototype.getMaskelement = function () { + return this.maskElement; +}; + +MaskElement.prototype.createLayerSolidPath = function () { + var path = 'M0,0 '; + path += ' h' + this.globalData.compSize.w; + path += ' v' + this.globalData.compSize.h; + path += ' h-' + this.globalData.compSize.w; + path += ' v-' + this.globalData.compSize.h + ' '; + return path; +}; + +MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) { + var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1]; + var i; + var len; + len = pathNodes._length; + for (i = 1; i < len; i += 1) { + // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1]; + pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1]; + } + // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1]; + if (pathNodes.c && len > 1) { + pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1]; + } + // pathNodes.__renderedString = pathString; + + if (viewData.lastPath !== pathString) { + var pathShapeValue = ''; + if (viewData.elem) { + if (pathNodes.c) { + pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString; + } + viewData.elem.setAttribute('d', pathShapeValue); + } + viewData.lastPath = pathString; + } +}; + +MaskElement.prototype.destroy = function () { + this.element = null; + this.globalData = null; + this.maskElement = null; + this.data = null; + this.masksProperties = null; +}; + +const filtersFactory = (function () { + var ob = {}; + ob.createFilter = createFilter; + ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter; + + function createFilter(filId, skipCoordinates) { + var fil = createNS('filter'); + fil.setAttribute('id', filId); + if (skipCoordinates !== true) { + fil.setAttribute('filterUnits', 'objectBoundingBox'); + fil.setAttribute('x', '0%'); + fil.setAttribute('y', '0%'); + fil.setAttribute('width', '100%'); + fil.setAttribute('height', '100%'); + } + return fil; + } + + function createAlphaToLuminanceFilter() { + var feColorMatrix = createNS('feColorMatrix'); + feColorMatrix.setAttribute('type', 'matrix'); + feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB'); + feColorMatrix.setAttribute('values', '0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 1'); + return feColorMatrix; + } + + return ob; +}()); + +const featureSupport = (function () { + var ob = { + maskType: true, + }; + if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) { + ob.maskType = false; + } + return ob; +}()); + +var registeredEffects = {}; +var idPrefix = 'filter_result_'; + +function SVGEffects(elem) { + var i; + var source = 'SourceGraphic'; + var len = elem.data.ef ? elem.data.ef.length : 0; + var filId = createElementID(); + var fil = filtersFactory.createFilter(filId, true); + var count = 0; + this.filters = []; + var filterManager; + for (i = 0; i < len; i += 1) { + filterManager = null; + var type = elem.data.ef[i].ty; + if (registeredEffects[type]) { + var Effect = registeredEffects[type].effect; + filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source); + source = idPrefix + count; + if (registeredEffects[type].countsAsEffect) { + count += 1; + } + } + if (filterManager) { + this.filters.push(filterManager); + } + } + if (count) { + elem.globalData.defs.appendChild(fil); + elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')'); + } + if (this.filters.length) { + elem.addRenderableComponent(this); + } +} + +SVGEffects.prototype.renderFrame = function (_isFirstFrame) { + var i; + var len = this.filters.length; + for (i = 0; i < len; i += 1) { + this.filters[i].renderFrame(_isFirstFrame); + } +}; + +function registerEffect(id, effect, countsAsEffect) { + registeredEffects[id] = { + effect, + countsAsEffect, + }; +} + +function SVGBaseElement() { +} + +SVGBaseElement.prototype = { + initRendererElement: function () { + this.layerElement = createNS('g'); + }, + createContainerElements: function () { + this.matteElement = createNS('g'); + this.transformedElement = this.layerElement; + this.maskedElement = this.layerElement; + this._sizeChanged = false; + var layerElementParent = null; + // If this layer acts as a mask for the following layer + var filId; + var fil; + var gg; + if (this.data.td) { + if (this.data.td == 3 || this.data.td == 1) { // eslint-disable-line eqeqeq + var masker = createNS('mask'); + masker.setAttribute('id', this.layerId); + masker.setAttribute('mask-type', this.data.td == 3 ? 'luminance' : 'alpha'); // eslint-disable-line eqeqeq + masker.appendChild(this.layerElement); + layerElementParent = masker; + this.globalData.defs.appendChild(masker); + // This is only for IE and Edge when mask if of type alpha + if (!featureSupport.maskType && this.data.td == 1) { // eslint-disable-line eqeqeq + masker.setAttribute('mask-type', 'luminance'); + filId = createElementID(); + fil = filtersFactory.createFilter(filId); + this.globalData.defs.appendChild(fil); + fil.appendChild(filtersFactory.createAlphaToLuminanceFilter()); + gg = createNS('g'); + gg.appendChild(this.layerElement); + layerElementParent = gg; + masker.appendChild(gg); + gg.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')'); + } + } else if (this.data.td == 2) { // eslint-disable-line eqeqeq + var maskGroup = createNS('mask'); + maskGroup.setAttribute('id', this.layerId); + maskGroup.setAttribute('mask-type', 'alpha'); + var maskGrouper = createNS('g'); + maskGroup.appendChild(maskGrouper); + filId = createElementID(); + fil = filtersFactory.createFilter(filId); + /// / + + // This solution doesn't work on Android when meta tag with viewport attribute is set + /* var feColorMatrix = createNS('feColorMatrix'); + feColorMatrix.setAttribute('type', 'matrix'); + feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB'); + feColorMatrix.setAttribute('values','1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 -1 1'); + fil.appendChild(feColorMatrix); */ + /// / + var feCTr = createNS('feComponentTransfer'); + feCTr.setAttribute('in', 'SourceGraphic'); + fil.appendChild(feCTr); + var feFunc = createNS('feFuncA'); + feFunc.setAttribute('type', 'table'); + feFunc.setAttribute('tableValues', '1.0 0.0'); + feCTr.appendChild(feFunc); + /// / + this.globalData.defs.appendChild(fil); + var alphaRect = createNS('rect'); + alphaRect.setAttribute('width', this.comp.data.w); + alphaRect.setAttribute('height', this.comp.data.h); + alphaRect.setAttribute('x', '0'); + alphaRect.setAttribute('y', '0'); + alphaRect.setAttribute('fill', '#ffffff'); + alphaRect.setAttribute('opacity', '0'); + maskGrouper.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')'); + maskGrouper.appendChild(alphaRect); + maskGrouper.appendChild(this.layerElement); + layerElementParent = maskGrouper; + if (!featureSupport.maskType) { + maskGroup.setAttribute('mask-type', 'luminance'); + fil.appendChild(filtersFactory.createAlphaToLuminanceFilter()); + gg = createNS('g'); + maskGrouper.appendChild(alphaRect); + gg.appendChild(this.layerElement); + layerElementParent = gg; + maskGrouper.appendChild(gg); + } + this.globalData.defs.appendChild(maskGroup); + } + } else if (this.data.tt) { + this.matteElement.appendChild(this.layerElement); + layerElementParent = this.matteElement; + this.baseElement = this.matteElement; + } else { + this.baseElement = this.layerElement; + } + if (this.data.ln) { + this.layerElement.setAttribute('id', this.data.ln); + } + if (this.data.cl) { + this.layerElement.setAttribute('class', this.data.cl); + } + // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped + if (this.data.ty === 0 && !this.data.hd) { + var cp = createNS('clipPath'); + var pt = createNS('path'); + pt.setAttribute('d', 'M0,0 L' + this.data.w + ',0 L' + this.data.w + ',' + this.data.h + ' L0,' + this.data.h + 'z'); + var clipId = createElementID(); + cp.setAttribute('id', clipId); + cp.appendChild(pt); + this.globalData.defs.appendChild(cp); + + if (this.checkMasks()) { + var cpGroup = createNS('g'); + cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')'); + cpGroup.appendChild(this.layerElement); + this.transformedElement = cpGroup; + if (layerElementParent) { + layerElementParent.appendChild(this.transformedElement); + } else { + this.baseElement = this.transformedElement; + } + } else { + this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')'); + } + } + if (this.data.bm !== 0) { + this.setBlendMode(); + } + }, + renderElement: function () { + if (this.finalTransform._matMdf) { + this.transformedElement.setAttribute('transform', this.finalTransform.mat.to2dCSS()); + } + if (this.finalTransform._opMdf) { + this.transformedElement.setAttribute('opacity', this.finalTransform.mProp.o.v); + } + }, + destroyBaseElement: function () { + this.layerElement = null; + this.matteElement = null; + this.maskManager.destroy(); + }, + getBaseElement: function () { + if (this.data.hd) { + return null; + } + return this.baseElement; + }, + createRenderableComponents: function () { + this.maskManager = new MaskElement(this.data, this, this.globalData); + this.renderableEffectsManager = new SVGEffects(this); + }, + setMatte: function (id) { + if (!this.matteElement) { + return; + } + this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')'); + }, +}; + +/** + * @file + * Handles AE's layer parenting property. + * + */ + +function HierarchyElement() {} + +HierarchyElement.prototype = { + /** + * @function + * Initializes hierarchy properties + * + */ + initHierarchy: function () { + // element's parent list + this.hierarchy = []; + // if element is parent of another layer _isParent will be true + this._isParent = false; + this.checkParenting(); + }, + /** + * @function + * Sets layer's hierarchy. + * @param {array} hierarch + * layer's parent list + * + */ + setHierarchy: function (hierarchy) { + this.hierarchy = hierarchy; + }, + /** + * @function + * Sets layer as parent. + * + */ + setAsParent: function () { + this._isParent = true; + }, + /** + * @function + * Searches layer's parenting chain + * + */ + checkParenting: function () { + if (this.data.parent !== undefined) { + this.comp.buildElementParenting(this, this.data.parent, []); + } + }, +}; + +function RenderableDOMElement() {} + +(function () { + var _prototype = { + initElement: function (data, globalData, comp) { + this.initFrame(); + this.initBaseData(data, globalData, comp); + this.initTransform(data, globalData, comp); + this.initHierarchy(); + this.initRenderable(); + this.initRendererElement(); + this.createContainerElements(); + this.createRenderableComponents(); + this.createContent(); + this.hide(); + }, + hide: function () { + // console.log('HIDE', this); + if (!this.hidden && (!this.isInRange || this.isTransparent)) { + var elem = this.baseElement || this.layerElement; + elem.style.display = 'none'; + this.hidden = true; + } + }, + show: function () { + // console.log('SHOW', this); + if (this.isInRange && !this.isTransparent) { + if (!this.data.hd) { + var elem = this.baseElement || this.layerElement; + elem.style.display = 'block'; + } + this.hidden = false; + this._isFirstFrame = true; + } + }, + renderFrame: function () { + // If it is exported as hidden (data.hd === true) no need to render + // If it is not visible no need to render + if (this.data.hd || this.hidden) { + return; + } + this.renderTransform(); + this.renderRenderable(); + this.renderElement(); + this.renderInnerContent(); + if (this._isFirstFrame) { + this._isFirstFrame = false; + } + }, + renderInnerContent: function () {}, + prepareFrame: function (num) { + this._mdf = false; + this.prepareRenderableFrame(num); + this.prepareProperties(num, this.isInRange); + this.checkTransparency(); + }, + destroy: function () { + this.innerElem = null; + this.destroyBaseElement(); + }, + }; + extendPrototype([RenderableElement, createProxyFunction(_prototype)], RenderableDOMElement); +}()); + +function IImageElement(data, globalData, comp) { + this.assetData = globalData.getAssetData(data.refId); + this.initElement(data, globalData, comp); + this.sourceRect = { + top: 0, left: 0, width: this.assetData.w, height: this.assetData.h, + }; +} + +extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement); + +IImageElement.prototype.createContent = function () { + var assetPath = this.globalData.getAssetsPath(this.assetData); + + this.innerElem = createNS('image'); + this.innerElem.setAttribute('width', this.assetData.w + 'px'); + this.innerElem.setAttribute('height', this.assetData.h + 'px'); + this.innerElem.setAttribute('preserveAspectRatio', this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio); + this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath); + + this.layerElement.appendChild(this.innerElem); +}; + +IImageElement.prototype.sourceRectAtTime = function () { + return this.sourceRect; +}; + +function ProcessedElement(element, position) { + this.elem = element; + this.pos = position; +} + +function IShapeElement() { +} + +IShapeElement.prototype = { + addShapeToModifiers: function (data) { + var i; + var len = this.shapeModifiers.length; + for (i = 0; i < len; i += 1) { + this.shapeModifiers[i].addShape(data); + } + }, + isShapeInAnimatedModifiers: function (data) { + var i = 0; + var len = this.shapeModifiers.length; + while (i < len) { + if (this.shapeModifiers[i].isAnimatedWithShape(data)) { + return true; + } + } + return false; + }, + renderModifiers: function () { + if (!this.shapeModifiers.length) { + return; + } + var i; + var len = this.shapes.length; + for (i = 0; i < len; i += 1) { + this.shapes[i].sh.reset(); + } + + len = this.shapeModifiers.length; + var shouldBreakProcess; + for (i = len - 1; i >= 0; i -= 1) { + shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame); + // workaround to fix cases where a repeater resets the shape so the following processes get called twice + // TODO: find a better solution for this + if (shouldBreakProcess) { + break; + } + } + }, + + searchProcessedElement: function (elem) { + var elements = this.processedElements; + var i = 0; + var len = elements.length; + while (i < len) { + if (elements[i].elem === elem) { + return elements[i].pos; + } + i += 1; + } + return 0; + }, + addProcessedElement: function (elem, pos) { + var elements = this.processedElements; + var i = elements.length; + while (i) { + i -= 1; + if (elements[i].elem === elem) { + elements[i].pos = pos; + return; + } + } + elements.push(new ProcessedElement(elem, pos)); + }, + prepareFrame: function (num) { + this.prepareRenderableFrame(num); + this.prepareProperties(num, this.isInRange); + }, +}; + +const lineCapEnum = { + 1: 'butt', + 2: 'round', + 3: 'square', +}; + +const lineJoinEnum = { + 1: 'miter', + 2: 'round', + 3: 'bevel', +}; + +function SVGShapeData(transformers, level, shape) { + this.caches = []; + this.styles = []; + this.transformers = transformers; + this.lStr = ''; + this.sh = shape; + this.lvl = level; + // TODO find if there are some cases where _isAnimated can be false. + // For now, since shapes add up with other shapes. They have to be calculated every time. + // One way of finding out is checking if all styles associated to this shape depend only of this shape + this._isAnimated = !!shape.k; + // TODO: commenting this for now since all shapes are animated + var i = 0; + var len = transformers.length; + while (i < len) { + if (transformers[i].mProps.dynamicProperties.length) { + this._isAnimated = true; + break; + } + i += 1; + } +} + +SVGShapeData.prototype.setAsAnimated = function () { + this._isAnimated = true; +}; + +function SVGStyleData(data, level) { + this.data = data; + this.type = data.ty; + this.d = ''; + this.lvl = level; + this._mdf = false; + this.closed = data.hd === true; + this.pElem = createNS('path'); + this.msElem = null; +} + +SVGStyleData.prototype.reset = function () { + this.d = ''; + this._mdf = false; +}; + +function DashProperty(elem, data, renderer, container) { + this.elem = elem; + this.frameId = -1; + this.dataProps = createSizedArray(data.length); + this.renderer = renderer; + this.k = false; + this.dashStr = ''; + this.dashArray = createTypedArray('float32', data.length ? data.length - 1 : 0); + this.dashoffset = createTypedArray('float32', 1); + this.initDynamicPropertyContainer(container); + var i; + var len = data.length || 0; + var prop; + for (i = 0; i < len; i += 1) { + prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this); + this.k = prop.k || this.k; + this.dataProps[i] = { n: data[i].n, p: prop }; + } + if (!this.k) { + this.getValue(true); + } + this._isAnimated = this.k; +} + +DashProperty.prototype.getValue = function (forceRender) { + if (this.elem.globalData.frameId === this.frameId && !forceRender) { + return; + } + this.frameId = this.elem.globalData.frameId; + this.iterateDynamicProperties(); + this._mdf = this._mdf || forceRender; + if (this._mdf) { + var i = 0; + var len = this.dataProps.length; + if (this.renderer === 'svg') { + this.dashStr = ''; + } + for (i = 0; i < len; i += 1) { + if (this.dataProps[i].n !== 'o') { + if (this.renderer === 'svg') { + this.dashStr += ' ' + this.dataProps[i].p.v; + } else { + this.dashArray[i] = this.dataProps[i].p.v; + } + } else { + this.dashoffset[0] = this.dataProps[i].p.v; + } + } + } +}; +extendPrototype([DynamicPropertyContainer], DashProperty); + +function SVGStrokeStyleData(elem, data, styleOb) { + this.initDynamicPropertyContainer(elem); + this.getValue = this.iterateDynamicProperties; + this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this); + this.w = PropertyFactory.getProp(elem, data.w, 0, null, this); + this.d = new DashProperty(elem, data.d || {}, 'svg', this); + this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this); + this.style = styleOb; + this._isAnimated = !!this._isAnimated; +} + +extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData); + +function SVGFillStyleData(elem, data, styleOb) { + this.initDynamicPropertyContainer(elem); + this.getValue = this.iterateDynamicProperties; + this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this); + this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this); + this.style = styleOb; +} + +extendPrototype([DynamicPropertyContainer], SVGFillStyleData); + +function SVGNoStyleData(elem, data, styleOb) { + this.initDynamicPropertyContainer(elem); + this.getValue = this.iterateDynamicProperties; + this.style = styleOb; +} + +extendPrototype([DynamicPropertyContainer], SVGNoStyleData); + +function GradientProperty(elem, data, container) { + this.data = data; + this.c = createTypedArray('uint8c', data.p * 4); + var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p * 4) : data.k.k.length - data.p * 4; + this.o = createTypedArray('float32', cLength); + this._cmdf = false; + this._omdf = false; + this._collapsable = this.checkCollapsable(); + this._hasOpacity = cLength; + this.initDynamicPropertyContainer(container); + this.prop = PropertyFactory.getProp(elem, data.k, 1, null, this); + this.k = this.prop.k; + this.getValue(true); +} + +GradientProperty.prototype.comparePoints = function (values, points) { + var i = 0; + var len = this.o.length / 2; + var diff; + while (i < len) { + diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]); + if (diff > 0.01) { + return false; + } + i += 1; + } + return true; +}; + +GradientProperty.prototype.checkCollapsable = function () { + if (this.o.length / 2 !== this.c.length / 4) { + return false; + } + if (this.data.k.k[0].s) { + var i = 0; + var len = this.data.k.k.length; + while (i < len) { + if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) { + return false; + } + i += 1; + } + } else if (!this.comparePoints(this.data.k.k, this.data.p)) { + return false; + } + return true; +}; + +GradientProperty.prototype.getValue = function (forceRender) { + this.prop.getValue(); + this._mdf = false; + this._cmdf = false; + this._omdf = false; + if (this.prop._mdf || forceRender) { + var i; + var len = this.data.p * 4; + var mult; + var val; + for (i = 0; i < len; i += 1) { + mult = i % 4 === 0 ? 100 : 255; + val = Math.round(this.prop.v[i] * mult); + if (this.c[i] !== val) { + this.c[i] = val; + this._cmdf = !forceRender; + } + } + if (this.o.length) { + len = this.prop.v.length; + for (i = this.data.p * 4; i < len; i += 1) { + mult = i % 2 === 0 ? 100 : 1; + val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i]; + if (this.o[i - this.data.p * 4] !== val) { + this.o[i - this.data.p * 4] = val; + this._omdf = !forceRender; + } + } + } + this._mdf = !forceRender; + } +}; + +extendPrototype([DynamicPropertyContainer], GradientProperty); + +function SVGGradientFillStyleData(elem, data, styleOb) { + this.initDynamicPropertyContainer(elem); + this.getValue = this.iterateDynamicProperties; + this.initGradientData(elem, data, styleOb); +} + +SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) { + this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this); + this.s = PropertyFactory.getProp(elem, data.s, 1, null, this); + this.e = PropertyFactory.getProp(elem, data.e, 1, null, this); + this.h = PropertyFactory.getProp(elem, data.h || { k: 0 }, 0, 0.01, this); + this.a = PropertyFactory.getProp(elem, data.a || { k: 0 }, 0, degToRads, this); + this.g = new GradientProperty(elem, data.g, this); + this.style = styleOb; + this.stops = []; + this.setGradientData(styleOb.pElem, data); + this.setGradientOpacity(data, styleOb); + this._isAnimated = !!this._isAnimated; +}; + +SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) { + var gradientId = createElementID(); + var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient'); + gfill.setAttribute('id', gradientId); + gfill.setAttribute('spreadMethod', 'pad'); + gfill.setAttribute('gradientUnits', 'userSpaceOnUse'); + var stops = []; + var stop; + var j; + var jLen; + jLen = data.g.p * 4; + for (j = 0; j < jLen; j += 4) { + stop = createNS('stop'); + gfill.appendChild(stop); + stops.push(stop); + } + pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')'); + this.gf = gfill; + this.cst = stops; +}; + +SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) { + if (this.g._hasOpacity && !this.g._collapsable) { + var stop; + var j; + var jLen; + var mask = createNS('mask'); + var maskElement = createNS('path'); + mask.appendChild(maskElement); + var opacityId = createElementID(); + var maskId = createElementID(); + mask.setAttribute('id', maskId); + var opFill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient'); + opFill.setAttribute('id', opacityId); + opFill.setAttribute('spreadMethod', 'pad'); + opFill.setAttribute('gradientUnits', 'userSpaceOnUse'); + jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length; + var stops = this.stops; + for (j = data.g.p * 4; j < jLen; j += 2) { + stop = createNS('stop'); + stop.setAttribute('stop-color', 'rgb(255,255,255)'); + opFill.appendChild(stop); + stops.push(stop); + } + maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + opacityId + ')'); + if (data.ty === 'gs') { + maskElement.setAttribute('stroke-linecap', lineCapEnum[data.lc || 2]); + maskElement.setAttribute('stroke-linejoin', lineJoinEnum[data.lj || 2]); + if (data.lj === 1) { + maskElement.setAttribute('stroke-miterlimit', data.ml); + } + } + this.of = opFill; + this.ms = mask; + this.ost = stops; + this.maskId = maskId; + styleOb.msElem = maskElement; + } +}; + +extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData); + +function SVGGradientStrokeStyleData(elem, data, styleOb) { + this.initDynamicPropertyContainer(elem); + this.getValue = this.iterateDynamicProperties; + this.w = PropertyFactory.getProp(elem, data.w, 0, null, this); + this.d = new DashProperty(elem, data.d || {}, 'svg', this); + this.initGradientData(elem, data, styleOb); + this._isAnimated = !!this._isAnimated; +} + +extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData); + +function ShapeGroupData() { + this.it = []; + this.prevViewData = []; + this.gr = createNS('g'); +} + +function SVGTransformData(mProps, op, container) { + this.transform = { + mProps: mProps, + op: op, + container: container, + }; + this.elements = []; + this._isAnimated = this.transform.mProps.dynamicProperties.length || this.transform.op.effectsSequence.length; +} + +const buildShapeString = function (pathNodes, length, closed, mat) { + if (length === 0) { + return ''; + } + var _o = pathNodes.o; + var _i = pathNodes.i; + var _v = pathNodes.v; + var i; + var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]); + for (i = 1; i < length; i += 1) { + shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]); + } + if (closed && length) { + shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]); + shapeString += 'z'; + } + return shapeString; +}; + +const SVGElementsRenderer = (function () { + var _identityMatrix = new Matrix(); + var _matrixHelper = new Matrix(); + + var ob = { + createRenderFunction: createRenderFunction, + }; + + function createRenderFunction(data) { + switch (data.ty) { + case 'fl': + return renderFill; + case 'gf': + return renderGradient; + case 'gs': + return renderGradientStroke; + case 'st': + return renderStroke; + case 'sh': + case 'el': + case 'rc': + case 'sr': + return renderPath; + case 'tr': + return renderContentTransform; + case 'no': + return renderNoop; + default: + return null; + } + } + + function renderContentTransform(styleData, itemData, isFirstFrame) { + if (isFirstFrame || itemData.transform.op._mdf) { + itemData.transform.container.setAttribute('opacity', itemData.transform.op.v); + } + if (isFirstFrame || itemData.transform.mProps._mdf) { + itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS()); + } + } + + function renderNoop() { + + } + + function renderPath(styleData, itemData, isFirstFrame) { + var j; + var jLen; + var pathStringTransformed; + var redraw; + var pathNodes; + var l; + var lLen = itemData.styles.length; + var lvl = itemData.lvl; + var paths; + var mat; + var props; + var iterations; + var k; + for (l = 0; l < lLen; l += 1) { + redraw = itemData.sh._mdf || isFirstFrame; + if (itemData.styles[l].lvl < lvl) { + mat = _matrixHelper.reset(); + iterations = lvl - itemData.styles[l].lvl; + k = itemData.transformers.length - 1; + while (!redraw && iterations > 0) { + redraw = itemData.transformers[k].mProps._mdf || redraw; + iterations -= 1; + k -= 1; + } + if (redraw) { + iterations = lvl - itemData.styles[l].lvl; + k = itemData.transformers.length - 1; + while (iterations > 0) { + props = itemData.transformers[k].mProps.v.props; + mat.transform(props[0], props[1], props[2], props[3], props[4], props[5], props[6], props[7], props[8], props[9], props[10], props[11], props[12], props[13], props[14], props[15]); + iterations -= 1; + k -= 1; + } + } + } else { + mat = _identityMatrix; + } + paths = itemData.sh.paths; + jLen = paths._length; + if (redraw) { + pathStringTransformed = ''; + for (j = 0; j < jLen; j += 1) { + pathNodes = paths.shapes[j]; + if (pathNodes && pathNodes._length) { + pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat); + } + } + itemData.caches[l] = pathStringTransformed; + } else { + pathStringTransformed = itemData.caches[l]; + } + itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed; + itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf; + } + } + + function renderFill(styleData, itemData, isFirstFrame) { + var styleElem = itemData.style; + + if (itemData.c._mdf || isFirstFrame) { + styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')'); + } + if (itemData.o._mdf || isFirstFrame) { + styleElem.pElem.setAttribute('fill-opacity', itemData.o.v); + } + } + + function renderGradientStroke(styleData, itemData, isFirstFrame) { + renderGradient(styleData, itemData, isFirstFrame); + renderStroke(styleData, itemData, isFirstFrame); + } + + function renderGradient(styleData, itemData, isFirstFrame) { + var gfill = itemData.gf; + var hasOpacity = itemData.g._hasOpacity; + var pt1 = itemData.s.v; + var pt2 = itemData.e.v; + + if (itemData.o._mdf || isFirstFrame) { + var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity'; + itemData.style.pElem.setAttribute(attr, itemData.o.v); + } + if (itemData.s._mdf || isFirstFrame) { + var attr1 = styleData.t === 1 ? 'x1' : 'cx'; + var attr2 = attr1 === 'x1' ? 'y1' : 'cy'; + gfill.setAttribute(attr1, pt1[0]); + gfill.setAttribute(attr2, pt1[1]); + if (hasOpacity && !itemData.g._collapsable) { + itemData.of.setAttribute(attr1, pt1[0]); + itemData.of.setAttribute(attr2, pt1[1]); + } + } + var stops; + var i; + var len; + var stop; + if (itemData.g._cmdf || isFirstFrame) { + stops = itemData.cst; + var cValues = itemData.g.c; + len = stops.length; + for (i = 0; i < len; i += 1) { + stop = stops[i]; + stop.setAttribute('offset', cValues[i * 4] + '%'); + stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')'); + } + } + if (hasOpacity && (itemData.g._omdf || isFirstFrame)) { + var oValues = itemData.g.o; + if (itemData.g._collapsable) { + stops = itemData.cst; + } else { + stops = itemData.ost; + } + len = stops.length; + for (i = 0; i < len; i += 1) { + stop = stops[i]; + if (!itemData.g._collapsable) { + stop.setAttribute('offset', oValues[i * 2] + '%'); + } + stop.setAttribute('stop-opacity', oValues[i * 2 + 1]); + } + } + if (styleData.t === 1) { + if (itemData.e._mdf || isFirstFrame) { + gfill.setAttribute('x2', pt2[0]); + gfill.setAttribute('y2', pt2[1]); + if (hasOpacity && !itemData.g._collapsable) { + itemData.of.setAttribute('x2', pt2[0]); + itemData.of.setAttribute('y2', pt2[1]); + } + } + } else { + var rad; + if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) { + rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2)); + gfill.setAttribute('r', rad); + if (hasOpacity && !itemData.g._collapsable) { + itemData.of.setAttribute('r', rad); + } + } + if (itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) { + if (!rad) { + rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2)); + } + var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]); + + var percent = itemData.h.v; + if (percent >= 1) { + percent = 0.99; + } else if (percent <= -1) { + percent = -0.99; + } + var dist = rad * percent; + var x = Math.cos(ang + itemData.a.v) * dist + pt1[0]; + var y = Math.sin(ang + itemData.a.v) * dist + pt1[1]; + gfill.setAttribute('fx', x); + gfill.setAttribute('fy', y); + if (hasOpacity && !itemData.g._collapsable) { + itemData.of.setAttribute('fx', x); + itemData.of.setAttribute('fy', y); + } + } + // gfill.setAttribute('fy','200'); + } + } + + function renderStroke(styleData, itemData, isFirstFrame) { + var styleElem = itemData.style; + var d = itemData.d; + if (d && (d._mdf || isFirstFrame) && d.dashStr) { + styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr); + styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]); + } + if (itemData.c && (itemData.c._mdf || isFirstFrame)) { + styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')'); + } + if (itemData.o._mdf || isFirstFrame) { + styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v); + } + if (itemData.w._mdf || isFirstFrame) { + styleElem.pElem.setAttribute('stroke-width', itemData.w.v); + if (styleElem.msElem) { + styleElem.msElem.setAttribute('stroke-width', itemData.w.v); + } + } + } + + return ob; +}()); + +function SVGShapeElement(data, globalData, comp) { + // List of drawable elements + this.shapes = []; + // Full shape data + this.shapesData = data.shapes; + // List of styles that will be applied to shapes + this.stylesList = []; + // List of modifiers that will be applied to shapes + this.shapeModifiers = []; + // List of items in shape tree + this.itemsData = []; + // List of items in previous shape tree + this.processedElements = []; + // List of animated components + this.animatedContents = []; + this.initElement(data, globalData, comp); + // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties. + // List of elements that have been created + this.prevViewData = []; + // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties. +} + +extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement); + +SVGShapeElement.prototype.initSecondaryElement = function () { +}; + +SVGShapeElement.prototype.identityMatrix = new Matrix(); + +SVGShapeElement.prototype.buildExpressionInterface = function () {}; + +SVGShapeElement.prototype.createContent = function () { + this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true); + this.filterUniqueShapes(); +}; + +/* +This method searches for multiple shapes that affect a single element and one of them is animated +*/ +SVGShapeElement.prototype.filterUniqueShapes = function () { + var i; + var len = this.shapes.length; + var shape; + var j; + var jLen = this.stylesList.length; + var style; + var tempShapes = []; + var areAnimated = false; + for (j = 0; j < jLen; j += 1) { + style = this.stylesList[j]; + areAnimated = false; + tempShapes.length = 0; + for (i = 0; i < len; i += 1) { + shape = this.shapes[i]; + if (shape.styles.indexOf(style) !== -1) { + tempShapes.push(shape); + areAnimated = shape._isAnimated || areAnimated; + } + } + if (tempShapes.length > 1 && areAnimated) { + this.setShapesAsAnimated(tempShapes); + } + } +}; + +SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) { + var i; + var len = shapes.length; + for (i = 0; i < len; i += 1) { + shapes[i].setAsAnimated(); + } +}; + +SVGShapeElement.prototype.createStyleElement = function (data, level) { + // TODO: prevent drawing of hidden styles + var elementData; + var styleOb = new SVGStyleData(data, level); + + var pathElement = styleOb.pElem; + if (data.ty === 'st') { + elementData = new SVGStrokeStyleData(this, data, styleOb); + } else if (data.ty === 'fl') { + elementData = new SVGFillStyleData(this, data, styleOb); + } else if (data.ty === 'gf' || data.ty === 'gs') { + var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData; + elementData = new GradientConstructor(this, data, styleOb); + this.globalData.defs.appendChild(elementData.gf); + if (elementData.maskId) { + this.globalData.defs.appendChild(elementData.ms); + this.globalData.defs.appendChild(elementData.of); + pathElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + elementData.maskId + ')'); + } + } else if (data.ty === 'no') { + elementData = new SVGNoStyleData(this, data, styleOb); + } + + if (data.ty === 'st' || data.ty === 'gs') { + pathElement.setAttribute('stroke-linecap', lineCapEnum[data.lc || 2]); + pathElement.setAttribute('stroke-linejoin', lineJoinEnum[data.lj || 2]); + pathElement.setAttribute('fill-opacity', '0'); + if (data.lj === 1) { + pathElement.setAttribute('stroke-miterlimit', data.ml); + } + } + + if (data.r === 2) { + pathElement.setAttribute('fill-rule', 'evenodd'); + } + + if (data.ln) { + pathElement.setAttribute('id', data.ln); + } + if (data.cl) { + pathElement.setAttribute('class', data.cl); + } + if (data.bm) { + pathElement.style['mix-blend-mode'] = getBlendMode(data.bm); + } + this.stylesList.push(styleOb); + this.addToAnimatedContents(data, elementData); + return elementData; +}; + +SVGShapeElement.prototype.createGroupElement = function (data) { + var elementData = new ShapeGroupData(); + if (data.ln) { + elementData.gr.setAttribute('id', data.ln); + } + if (data.cl) { + elementData.gr.setAttribute('class', data.cl); + } + if (data.bm) { + elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm); + } + return elementData; +}; + +SVGShapeElement.prototype.createTransformElement = function (data, container) { + var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this); + var elementData = new SVGTransformData(transformProperty, transformProperty.o, container); + this.addToAnimatedContents(data, elementData); + return elementData; +}; + +SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) { + var ty = 4; + if (data.ty === 'rc') { + ty = 5; + } else if (data.ty === 'el') { + ty = 6; + } else if (data.ty === 'sr') { + ty = 7; + } + var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this); + var elementData = new SVGShapeData(ownTransformers, level, shapeProperty); + this.shapes.push(elementData); + this.addShapeToModifiers(elementData); + this.addToAnimatedContents(data, elementData); + return elementData; +}; + +SVGShapeElement.prototype.addToAnimatedContents = function (data, element) { + var i = 0; + var len = this.animatedContents.length; + while (i < len) { + if (this.animatedContents[i].element === element) { + return; + } + i += 1; + } + this.animatedContents.push({ + fn: SVGElementsRenderer.createRenderFunction(data), + element: element, + data: data, + }); +}; + +SVGShapeElement.prototype.setElementStyles = function (elementData) { + var arr = elementData.styles; + var j; + var jLen = this.stylesList.length; + for (j = 0; j < jLen; j += 1) { + if (!this.stylesList[j].closed) { + arr.push(this.stylesList[j]); + } + } +}; + +SVGShapeElement.prototype.reloadShapes = function () { + this._isFirstFrame = true; + var i; + var len = this.itemsData.length; + for (i = 0; i < len; i += 1) { + this.prevViewData[i] = this.itemsData[i]; + } + this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true); + this.filterUniqueShapes(); + len = this.dynamicProperties.length; + for (i = 0; i < len; i += 1) { + this.dynamicProperties[i].getValue(); + } + this.renderModifiers(); +}; + +SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) { + var ownTransformers = [].concat(transformers); + var i; + var len = arr.length - 1; + var j; + var jLen; + var ownStyles = []; + var ownModifiers = []; + var currentTransform; + var modifier; + var processedPos; + for (i = len; i >= 0; i -= 1) { + processedPos = this.searchProcessedElement(arr[i]); + if (!processedPos) { + arr[i]._render = render; + } else { + itemsData[i] = prevViewData[processedPos - 1]; + } + if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') { + if (!processedPos) { + itemsData[i] = this.createStyleElement(arr[i], level); + } else { + itemsData[i].style.closed = false; + } + if (arr[i]._render) { + if (itemsData[i].style.pElem.parentNode !== container) { + container.appendChild(itemsData[i].style.pElem); + } + } + ownStyles.push(itemsData[i].style); + } else if (arr[i].ty === 'gr') { + if (!processedPos) { + itemsData[i] = this.createGroupElement(arr[i]); + } else { + jLen = itemsData[i].it.length; + for (j = 0; j < jLen; j += 1) { + itemsData[i].prevViewData[j] = itemsData[i].it[j]; + } + } + this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render); + if (arr[i]._render) { + if (itemsData[i].gr.parentNode !== container) { + container.appendChild(itemsData[i].gr); + } + } + } else if (arr[i].ty === 'tr') { + if (!processedPos) { + itemsData[i] = this.createTransformElement(arr[i], container); + } + currentTransform = itemsData[i].transform; + ownTransformers.push(currentTransform); + } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') { + if (!processedPos) { + itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level); + } + this.setElementStyles(itemsData[i]); + } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb') { + if (!processedPos) { + modifier = ShapeModifiers.getModifier(arr[i].ty); + modifier.init(this, arr[i]); + itemsData[i] = modifier; + this.shapeModifiers.push(modifier); + } else { + modifier = itemsData[i]; + modifier.closed = false; + } + ownModifiers.push(modifier); + } else if (arr[i].ty === 'rp') { + if (!processedPos) { + modifier = ShapeModifiers.getModifier(arr[i].ty); + itemsData[i] = modifier; + modifier.init(this, arr, i, itemsData); + this.shapeModifiers.push(modifier); + render = false; + } else { + modifier = itemsData[i]; + modifier.closed = true; + } + ownModifiers.push(modifier); + } + this.addProcessedElement(arr[i], i + 1); + } + len = ownStyles.length; + for (i = 0; i < len; i += 1) { + ownStyles[i].closed = true; + } + len = ownModifiers.length; + for (i = 0; i < len; i += 1) { + ownModifiers[i].closed = true; + } +}; + +SVGShapeElement.prototype.renderInnerContent = function () { + this.renderModifiers(); + var i; + var len = this.stylesList.length; + for (i = 0; i < len; i += 1) { + this.stylesList[i].reset(); + } + this.renderShape(); + for (i = 0; i < len; i += 1) { + if (this.stylesList[i]._mdf || this._isFirstFrame) { + if (this.stylesList[i].msElem) { + this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d); + // Adding M0 0 fixes same mask bug on all browsers + this.stylesList[i].d = 'M0 0' + this.stylesList[i].d; + } + this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0'); + } + } +}; + +SVGShapeElement.prototype.renderShape = function () { + var i; + var len = this.animatedContents.length; + var animatedContent; + for (i = 0; i < len; i += 1) { + animatedContent = this.animatedContents[i]; + if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) { + animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame); + } + } +}; + +SVGShapeElement.prototype.destroy = function () { + this.destroyBaseElement(); + this.shapesData = null; + this.itemsData = null; +}; + +function LetterProps(o, sw, sc, fc, m, p) { + this.o = o; + this.sw = sw; + this.sc = sc; + this.fc = fc; + this.m = m; + this.p = p; + this._mdf = { + o: true, + sw: !!sw, + sc: !!sc, + fc: !!fc, + m: true, + p: true, + }; +} + +LetterProps.prototype.update = function (o, sw, sc, fc, m, p) { + this._mdf.o = false; + this._mdf.sw = false; + this._mdf.sc = false; + this._mdf.fc = false; + this._mdf.m = false; + this._mdf.p = false; + var updated = false; + + if (this.o !== o) { + this.o = o; + this._mdf.o = true; + updated = true; + } + if (this.sw !== sw) { + this.sw = sw; + this._mdf.sw = true; + updated = true; + } + if (this.sc !== sc) { + this.sc = sc; + this._mdf.sc = true; + updated = true; + } + if (this.fc !== fc) { + this.fc = fc; + this._mdf.fc = true; + updated = true; + } + if (this.m !== m) { + this.m = m; + this._mdf.m = true; + updated = true; + } + if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) { + this.p = p; + this._mdf.p = true; + updated = true; + } + return updated; +}; + +function TextProperty(elem, data) { + this._frameId = initialDefaultFrame; + this.pv = ''; + this.v = ''; + this.kf = false; + this._isFirstFrame = true; + this._mdf = false; + this.data = data; + this.elem = elem; + this.comp = this.elem.comp; + this.keysIndex = 0; + this.canResize = false; + this.minimumFontSize = 1; + this.effectsSequence = []; + this.currentData = { + ascent: 0, + boxWidth: this.defaultBoxWidth, + f: '', + fStyle: '', + fWeight: '', + fc: '', + j: '', + justifyOffset: '', + l: [], + lh: 0, + lineWidths: [], + ls: '', + of: '', + s: '', + sc: '', + sw: 0, + t: 0, + tr: 0, + sz: 0, + ps: null, + fillColorAnim: false, + strokeColorAnim: false, + strokeWidthAnim: false, + yOffset: 0, + finalSize: 0, + finalText: [], + finalLineHeight: 0, + __complete: false, + + }; + this.copyData(this.currentData, this.data.d.k[0].s); + + if (!this.searchProperty()) { + this.completeTextData(this.currentData); + } +} + +TextProperty.prototype.defaultBoxWidth = [0, 0]; + +TextProperty.prototype.copyData = function (obj, data) { + for (var s in data) { + if (Object.prototype.hasOwnProperty.call(data, s)) { + obj[s] = data[s]; + } + } + return obj; +}; + +TextProperty.prototype.setCurrentData = function (data) { + if (!data.__complete) { + this.completeTextData(data); + } + this.currentData = data; + this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth; + this._mdf = true; +}; + +TextProperty.prototype.searchProperty = function () { + return this.searchKeyframes(); +}; + +TextProperty.prototype.searchKeyframes = function () { + this.kf = this.data.d.k.length > 1; + if (this.kf) { + this.addEffect(this.getKeyframeValue.bind(this)); + } + return this.kf; +}; + +TextProperty.prototype.addEffect = function (effectFunction) { + this.effectsSequence.push(effectFunction); + this.elem.addDynamicProperty(this); +}; + +TextProperty.prototype.getValue = function (_finalValue) { + if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) { + return; + } + this.currentData.t = this.data.d.k[this.keysIndex].s.t; + var currentValue = this.currentData; + var currentIndex = this.keysIndex; + if (this.lock) { + this.setCurrentData(this.currentData); + return; + } + this.lock = true; + this._mdf = false; + var i; var + len = this.effectsSequence.length; + var finalValue = _finalValue || this.data.d.k[this.keysIndex].s; + for (i = 0; i < len; i += 1) { + // Checking if index changed to prevent creating a new object every time the expression updates. + if (currentIndex !== this.keysIndex) { + finalValue = this.effectsSequence[i](finalValue, finalValue.t); + } else { + finalValue = this.effectsSequence[i](this.currentData, finalValue.t); + } + } + if (currentValue !== finalValue) { + this.setCurrentData(finalValue); + } + this.v = this.currentData; + this.pv = this.v; + this.lock = false; + this.frameId = this.elem.globalData.frameId; +}; + +TextProperty.prototype.getKeyframeValue = function () { + var textKeys = this.data.d.k; + var frameNum = this.elem.comp.renderedFrame; + var i = 0; var + len = textKeys.length; + while (i <= len - 1) { + if (i === len - 1 || textKeys[i + 1].t > frameNum) { + break; + } + i += 1; + } + if (this.keysIndex !== i) { + this.keysIndex = i; + } + return this.data.d.k[this.keysIndex].s; +}; + +TextProperty.prototype.buildFinalText = function (text) { + var charactersArray = []; + var i = 0; + var len = text.length; + var charCode; + var secondCharCode; + var shouldCombine = false; + while (i < len) { + charCode = text.charCodeAt(i); + if (FontManager.isCombinedCharacter(charCode)) { + charactersArray[charactersArray.length - 1] += text.charAt(i); + } else if (charCode >= 0xD800 && charCode <= 0xDBFF) { + secondCharCode = text.charCodeAt(i + 1); + if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) { + if (shouldCombine || FontManager.isModifier(charCode, secondCharCode)) { + charactersArray[charactersArray.length - 1] += text.substr(i, 2); + shouldCombine = false; + } else { + charactersArray.push(text.substr(i, 2)); + } + i += 1; + } else { + charactersArray.push(text.charAt(i)); + } + } else if (charCode > 0xDBFF) { + secondCharCode = text.charCodeAt(i + 1); + if (FontManager.isZeroWidthJoiner(charCode, secondCharCode)) { + shouldCombine = true; + charactersArray[charactersArray.length - 1] += text.substr(i, 2); + i += 1; + } else { + charactersArray.push(text.charAt(i)); + } + } else if (FontManager.isZeroWidthJoiner(charCode)) { + charactersArray[charactersArray.length - 1] += text.charAt(i); + shouldCombine = true; + } else { + charactersArray.push(text.charAt(i)); + } + i += 1; + } + return charactersArray; +}; + +TextProperty.prototype.completeTextData = function (documentData) { + documentData.__complete = true; + var fontManager = this.elem.globalData.fontManager; + var data = this.data; + var letters = []; + var i; var + len; + var newLineFlag; var index = 0; var + val; + var anchorGrouping = data.m.g; + var currentSize = 0; var currentPos = 0; var currentLine = 0; var + lineWidths = []; + var lineWidth = 0; + var maxLineWidth = 0; + var j; var + jLen; + var fontData = fontManager.getFontByName(documentData.f); + var charData; var + cLength = 0; + + var fontProps = getFontProperties(fontData); + documentData.fWeight = fontProps.weight; + documentData.fStyle = fontProps.style; + documentData.finalSize = documentData.s; + documentData.finalText = this.buildFinalText(documentData.t); + len = documentData.finalText.length; + documentData.finalLineHeight = documentData.lh; + var trackingOffset = (documentData.tr / 1000) * documentData.finalSize; + var charCode; + if (documentData.sz) { + var flag = true; + var boxWidth = documentData.sz[0]; + var boxHeight = documentData.sz[1]; + var currentHeight; var + finalText; + while (flag) { + finalText = this.buildFinalText(documentData.t); + currentHeight = 0; + lineWidth = 0; + len = finalText.length; + trackingOffset = (documentData.tr / 1000) * documentData.finalSize; + var lastSpaceIndex = -1; + for (i = 0; i < len; i += 1) { + charCode = finalText[i].charCodeAt(0); + newLineFlag = false; + if (finalText[i] === ' ') { + lastSpaceIndex = i; + } else if (charCode === 13 || charCode === 3) { + lineWidth = 0; + newLineFlag = true; + currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2; + } + if (fontManager.chars) { + charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily); + cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100; + } else { + // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily; + cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize); + } + if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') { + if (lastSpaceIndex === -1) { + len += 1; + } else { + i = lastSpaceIndex; + } + currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2; + finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r'); + // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i); + lastSpaceIndex = -1; + lineWidth = 0; + } else { + lineWidth += cLength; + lineWidth += trackingOffset; + } + } + currentHeight += (fontData.ascent * documentData.finalSize) / 100; + if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) { + documentData.finalSize -= 1; + documentData.finalLineHeight = (documentData.finalSize * documentData.lh) / documentData.s; + } else { + documentData.finalText = finalText; + len = documentData.finalText.length; + flag = false; + } + } + } + lineWidth = -trackingOffset; + cLength = 0; + var uncollapsedSpaces = 0; + var currentChar; + for (i = 0; i < len; i += 1) { + newLineFlag = false; + currentChar = documentData.finalText[i]; + charCode = currentChar.charCodeAt(0); + if (charCode === 13 || charCode === 3) { + uncollapsedSpaces = 0; + lineWidths.push(lineWidth); + maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth; + lineWidth = -2 * trackingOffset; + val = ''; + newLineFlag = true; + currentLine += 1; + } else { + val = currentChar; + } + if (fontManager.chars) { + charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily); + cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100; + } else { + // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize); + // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily; + cLength = fontManager.measureText(val, documentData.f, documentData.finalSize); + } + + // + if (currentChar === ' ') { + uncollapsedSpaces += cLength + trackingOffset; + } else { + lineWidth += cLength + trackingOffset + uncollapsedSpaces; + uncollapsedSpaces = 0; + } + letters.push({ + l: cLength, an: cLength, add: currentSize, n: newLineFlag, anIndexes: [], val: val, line: currentLine, animatorJustifyOffset: 0, + }); + if (anchorGrouping == 2) { // eslint-disable-line eqeqeq + currentSize += cLength; + if (val === '' || val === ' ' || i === len - 1) { + if (val === '' || val === ' ') { + currentSize -= cLength; + } + while (currentPos <= i) { + letters[currentPos].an = currentSize; + letters[currentPos].ind = index; + letters[currentPos].extra = cLength; + currentPos += 1; + } + index += 1; + currentSize = 0; + } + } else if (anchorGrouping == 3) { // eslint-disable-line eqeqeq + currentSize += cLength; + if (val === '' || i === len - 1) { + if (val === '') { + currentSize -= cLength; + } + while (currentPos <= i) { + letters[currentPos].an = currentSize; + letters[currentPos].ind = index; + letters[currentPos].extra = cLength; + currentPos += 1; + } + currentSize = 0; + index += 1; + } + } else { + letters[index].ind = index; + letters[index].extra = 0; + index += 1; + } + } + documentData.l = letters; + maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth; + lineWidths.push(lineWidth); + if (documentData.sz) { + documentData.boxWidth = documentData.sz[0]; + documentData.justifyOffset = 0; + } else { + documentData.boxWidth = maxLineWidth; + switch (documentData.j) { + case 1: + documentData.justifyOffset = -documentData.boxWidth; + break; + case 2: + documentData.justifyOffset = -documentData.boxWidth / 2; + break; + default: + documentData.justifyOffset = 0; + } + } + documentData.lineWidths = lineWidths; + + var animators = data.a; var animatorData; var + letterData; + jLen = animators.length; + var based; var ind; var + indexes = []; + for (j = 0; j < jLen; j += 1) { + animatorData = animators[j]; + if (animatorData.a.sc) { + documentData.strokeColorAnim = true; + } + if (animatorData.a.sw) { + documentData.strokeWidthAnim = true; + } + if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) { + documentData.fillColorAnim = true; + } + ind = 0; + based = animatorData.s.b; + for (i = 0; i < len; i += 1) { + letterData = letters[i]; + letterData.anIndexes[j] = ind; + if ((based == 1 && letterData.val !== '') || (based == 2 && letterData.val !== '' && letterData.val !== ' ') || (based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1)) || (based == 4 && (letterData.n || i == len - 1))) { // eslint-disable-line eqeqeq + if (animatorData.s.rn === 1) { + indexes.push(ind); + } + ind += 1; + } + } + data.a[j].s.totalChars = ind; + var currentInd = -1; var + newInd; + if (animatorData.s.rn === 1) { + for (i = 0; i < len; i += 1) { + letterData = letters[i]; + if (currentInd != letterData.anIndexes[j]) { // eslint-disable-line eqeqeq + currentInd = letterData.anIndexes[j]; + newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0]; + } + letterData.anIndexes[j] = newInd; + } + } + } + documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2; + documentData.ls = documentData.ls || 0; + documentData.ascent = (fontData.ascent * documentData.finalSize) / 100; +}; + +TextProperty.prototype.updateDocumentData = function (newData, index) { + index = index === undefined ? this.keysIndex : index; + var dData = this.copyData({}, this.data.d.k[index].s); + dData = this.copyData(dData, newData); + this.data.d.k[index].s = dData; + this.recalculate(index); + this.elem.addDynamicProperty(this); +}; + +TextProperty.prototype.recalculate = function (index) { + var dData = this.data.d.k[index].s; + dData.__complete = false; + this.keysIndex = 0; + this._isFirstFrame = true; + this.getValue(dData); +}; + +TextProperty.prototype.canResizeFont = function (_canResize) { + this.canResize = _canResize; + this.recalculate(this.keysIndex); + this.elem.addDynamicProperty(this); +}; + +TextProperty.prototype.setMinimumFontSize = function (_fontValue) { + this.minimumFontSize = Math.floor(_fontValue) || 1; + this.recalculate(this.keysIndex); + this.elem.addDynamicProperty(this); +}; + +const TextSelectorProp = (function () { + var max = Math.max; + var min = Math.min; + var floor = Math.floor; + + function TextSelectorPropFactory(elem, data) { + this._currentTextLength = -1; + this.k = false; + this.data = data; + this.elem = elem; + this.comp = elem.comp; + this.finalS = 0; + this.finalE = 0; + this.initDynamicPropertyContainer(elem); + this.s = PropertyFactory.getProp(elem, data.s || { k: 0 }, 0, 0, this); + if ('e' in data) { + this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this); + } else { + this.e = { v: 100 }; + } + this.o = PropertyFactory.getProp(elem, data.o || { k: 0 }, 0, 0, this); + this.xe = PropertyFactory.getProp(elem, data.xe || { k: 0 }, 0, 0, this); + this.ne = PropertyFactory.getProp(elem, data.ne || { k: 0 }, 0, 0, this); + this.sm = PropertyFactory.getProp(elem, data.sm || { k: 100 }, 0, 0, this); + this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this); + if (!this.dynamicProperties.length) { + this.getValue(); + } + } + + TextSelectorPropFactory.prototype = { + getMult: function (ind) { + if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) { + this.getValue(); + } + var x1 = 0; + var y1 = 0; + var x2 = 1; + var y2 = 1; + if (this.ne.v > 0) { + x1 = this.ne.v / 100.0; + } else { + y1 = -this.ne.v / 100.0; + } + if (this.xe.v > 0) { + x2 = 1.0 - this.xe.v / 100.0; + } else { + y2 = 1.0 + this.xe.v / 100.0; + } + var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get; + + var mult = 0; + var s = this.finalS; + var e = this.finalE; + var type = this.data.sh; + if (type === 2) { + if (e === s) { + mult = ind >= e ? 1 : 0; + } else { + mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1)); + } + mult = easer(mult); + } else if (type === 3) { + if (e === s) { + mult = ind >= e ? 0 : 1; + } else { + mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1)); + } + + mult = easer(mult); + } else if (type === 4) { + if (e === s) { + mult = 0; + } else { + mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1)); + if (mult < 0.5) { + mult *= 2; + } else { + mult = 1 - 2 * (mult - 0.5); + } + } + mult = easer(mult); + } else if (type === 5) { + if (e === s) { + mult = 0; + } else { + var tot = e - s; + /* ind += 0.5; + mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */ + ind = min(max(0, ind + 0.5 - s), e - s); + var x = -tot / 2 + ind; + var a = tot / 2; + mult = Math.sqrt(1 - (x * x) / (a * a)); + } + mult = easer(mult); + } else if (type === 6) { + if (e === s) { + mult = 0; + } else { + ind = min(max(0, ind + 0.5 - s), e - s); + mult = (1 + (Math.cos((Math.PI + Math.PI * 2 * (ind) / (e - s))))) / 2; // eslint-disable-line + } + mult = easer(mult); + } else { + if (ind >= floor(s)) { + if (ind - s < 0) { + mult = max(0, min(min(e, 1) - (s - ind), 1)); + } else { + mult = max(0, min(e - ind, 1)); + } + } + mult = easer(mult); + } + // Smoothness implementation. + // The smoothness represents a reduced range of the original [0; 1] range. + // if smoothness is 25%, the new range will be [0.375; 0.625] + // Steps are: + // - find the lower value of the new range (threshold) + // - if multiplier is smaller than that value, floor it to 0 + // - if it is larger, + // - subtract the threshold + // - divide it by the smoothness (this will return the range to [0; 1]) + // Note: If it doesn't work on some scenarios, consider applying it before the easer. + if (this.sm.v !== 100) { + var smoothness = this.sm.v * 0.01; + if (smoothness === 0) { + smoothness = 0.00000001; + } + var threshold = 0.5 - smoothness * 0.5; + if (mult < threshold) { + mult = 0; + } else { + mult = (mult - threshold) / smoothness; + if (mult > 1) { + mult = 1; + } + } + } + return mult * this.a.v; + }, + getValue: function (newCharsFlag) { + this.iterateDynamicProperties(); + this._mdf = newCharsFlag || this._mdf; + this._currentTextLength = this.elem.textProperty.currentData.l.length || 0; + if (newCharsFlag && this.data.r === 2) { + this.e.v = this._currentTextLength; + } + var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars; + var o = this.o.v / divisor; + var s = this.s.v / divisor + o; + var e = (this.e.v / divisor) + o; + if (s > e) { + var _s = s; + s = e; + e = _s; + } + this.finalS = s; + this.finalE = e; + }, + }; + extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory); + + function getTextSelectorProp(elem, data, arr) { + return new TextSelectorPropFactory(elem, data, arr); + } + + return { + getTextSelectorProp: getTextSelectorProp, + }; +}()); + +function TextAnimatorDataProperty(elem, animatorProps, container) { + var defaultData = { propType: false }; + var getProp = PropertyFactory.getProp; + var textAnimatorAnimatables = animatorProps.a; + this.a = { + r: textAnimatorAnimatables.r ? getProp(elem, textAnimatorAnimatables.r, 0, degToRads, container) : defaultData, + rx: textAnimatorAnimatables.rx ? getProp(elem, textAnimatorAnimatables.rx, 0, degToRads, container) : defaultData, + ry: textAnimatorAnimatables.ry ? getProp(elem, textAnimatorAnimatables.ry, 0, degToRads, container) : defaultData, + sk: textAnimatorAnimatables.sk ? getProp(elem, textAnimatorAnimatables.sk, 0, degToRads, container) : defaultData, + sa: textAnimatorAnimatables.sa ? getProp(elem, textAnimatorAnimatables.sa, 0, degToRads, container) : defaultData, + s: textAnimatorAnimatables.s ? getProp(elem, textAnimatorAnimatables.s, 1, 0.01, container) : defaultData, + a: textAnimatorAnimatables.a ? getProp(elem, textAnimatorAnimatables.a, 1, 0, container) : defaultData, + o: textAnimatorAnimatables.o ? getProp(elem, textAnimatorAnimatables.o, 0, 0.01, container) : defaultData, + p: textAnimatorAnimatables.p ? getProp(elem, textAnimatorAnimatables.p, 1, 0, container) : defaultData, + sw: textAnimatorAnimatables.sw ? getProp(elem, textAnimatorAnimatables.sw, 0, 0, container) : defaultData, + sc: textAnimatorAnimatables.sc ? getProp(elem, textAnimatorAnimatables.sc, 1, 0, container) : defaultData, + fc: textAnimatorAnimatables.fc ? getProp(elem, textAnimatorAnimatables.fc, 1, 0, container) : defaultData, + fh: textAnimatorAnimatables.fh ? getProp(elem, textAnimatorAnimatables.fh, 0, 0, container) : defaultData, + fs: textAnimatorAnimatables.fs ? getProp(elem, textAnimatorAnimatables.fs, 0, 0.01, container) : defaultData, + fb: textAnimatorAnimatables.fb ? getProp(elem, textAnimatorAnimatables.fb, 0, 0.01, container) : defaultData, + t: textAnimatorAnimatables.t ? getProp(elem, textAnimatorAnimatables.t, 0, 0, container) : defaultData, + }; + + this.s = TextSelectorProp.getTextSelectorProp(elem, animatorProps.s, container); + this.s.t = animatorProps.s.t; +} + +function TextAnimatorProperty(textData, renderType, elem) { + this._isFirstFrame = true; + this._hasMaskedPath = false; + this._frameId = -1; + this._textData = textData; + this._renderType = renderType; + this._elem = elem; + this._animatorsData = createSizedArray(this._textData.a.length); + this._pathData = {}; + this._moreOptions = { + alignment: {}, + }; + this.renderedLetters = []; + this.lettersChangedFlag = false; + this.initDynamicPropertyContainer(elem); +} + +TextAnimatorProperty.prototype.searchProperties = function () { + var i; + var len = this._textData.a.length; + var animatorProps; + var getProp = PropertyFactory.getProp; + for (i = 0; i < len; i += 1) { + animatorProps = this._textData.a[i]; + this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this); + } + if (this._textData.p && 'm' in this._textData.p) { + this._pathData = { + a: getProp(this._elem, this._textData.p.a, 0, 0, this), + f: getProp(this._elem, this._textData.p.f, 0, 0, this), + l: getProp(this._elem, this._textData.p.l, 0, 0, this), + r: getProp(this._elem, this._textData.p.r, 0, 0, this), + p: getProp(this._elem, this._textData.p.p, 0, 0, this), + m: this._elem.maskManager.getMaskProperty(this._textData.p.m), + }; + this._hasMaskedPath = true; + } else { + this._hasMaskedPath = false; + } + this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this); +}; + +TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) { + this.lettersChangedFlag = lettersChangedFlag; + if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) { + return; + } + this._isFirstFrame = false; + var alignment = this._moreOptions.alignment.v; + var animators = this._animatorsData; + var textData = this._textData; + var matrixHelper = this.mHelper; + var renderType = this._renderType; + var renderedLettersCount = this.renderedLetters.length; + var xPos; + var yPos; + var i; + var len; + var letters = documentData.l; + var pathInfo; + var currentLength; + var currentPoint; + var segmentLength; + var flag; + var pointInd; + var segmentInd; + var prevPoint; + var points; + var segments; + var partialLength; + var totalLength; + var perc; + var tanAngle; + var mask; + if (this._hasMaskedPath) { + mask = this._pathData.m; + if (!this._pathData.n || this._pathData._mdf) { + var paths = mask.v; + if (this._pathData.r.v) { + paths = paths.reverse(); + } + // TODO: release bezier data cached from previous pathInfo: this._pathData.pi + pathInfo = { + tLength: 0, + segments: [], + }; + len = paths._length - 1; + var bezierData; + totalLength = 0; + for (i = 0; i < len; i += 1) { + bezierData = bez.buildBezierData(paths.v[i], + paths.v[i + 1], + [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], + [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]); + pathInfo.tLength += bezierData.segmentLength; + pathInfo.segments.push(bezierData); + totalLength += bezierData.segmentLength; + } + i = len; + if (mask.v.c) { + bezierData = bez.buildBezierData(paths.v[i], + paths.v[0], + [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], + [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]); + pathInfo.tLength += bezierData.segmentLength; + pathInfo.segments.push(bezierData); + totalLength += bezierData.segmentLength; + } + this._pathData.pi = pathInfo; + } + pathInfo = this._pathData.pi; + + currentLength = this._pathData.f.v; + segmentInd = 0; + pointInd = 1; + segmentLength = 0; + flag = true; + segments = pathInfo.segments; + if (currentLength < 0 && mask.v.c) { + if (pathInfo.tLength < Math.abs(currentLength)) { + currentLength = -Math.abs(currentLength) % pathInfo.tLength; + } + segmentInd = segments.length - 1; + points = segments[segmentInd].points; + pointInd = points.length - 1; + while (currentLength < 0) { + currentLength += points[pointInd].partialLength; + pointInd -= 1; + if (pointInd < 0) { + segmentInd -= 1; + points = segments[segmentInd].points; + pointInd = points.length - 1; + } + } + } + points = segments[segmentInd].points; + prevPoint = points[pointInd - 1]; + currentPoint = points[pointInd]; + partialLength = currentPoint.partialLength; + } + + len = letters.length; + xPos = 0; + yPos = 0; + var yOff = documentData.finalSize * 1.2 * 0.714; + var firstLine = true; + var animatorProps; + var animatorSelector; + var j; + var jLen; + var letterValue; + + jLen = animators.length; + + var mult; + var ind = -1; + var offf; + var xPathPos; + var yPathPos; + var initPathPos = currentLength; + var initSegmentInd = segmentInd; + var initPointInd = pointInd; + var currentLine = -1; + var elemOpacity; + var sc; + var sw; + var fc; + var k; + var letterSw; + var letterSc; + var letterFc; + var letterM = ''; + var letterP = this.defaultPropsArray; + var letterO; + + // + if (documentData.j === 2 || documentData.j === 1) { + var animatorJustifyOffset = 0; + var animatorFirstCharOffset = 0; + var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1; + var lastIndex = 0; + var isNewLine = true; + + for (i = 0; i < len; i += 1) { + if (letters[i].n) { + if (animatorJustifyOffset) { + animatorJustifyOffset += animatorFirstCharOffset; + } + while (lastIndex < i) { + letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset; + lastIndex += 1; + } + animatorJustifyOffset = 0; + isNewLine = true; + } else { + for (j = 0; j < jLen; j += 1) { + animatorProps = animators[j].a; + if (animatorProps.t.propType) { + if (isNewLine && documentData.j === 2) { + animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult; + } + animatorSelector = animators[j].s; + mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars); + if (mult.length) { + animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult; + } else { + animatorJustifyOffset += animatorProps.t.v * mult * justifyOffsetMult; + } + } + } + isNewLine = false; + } + } + if (animatorJustifyOffset) { + animatorJustifyOffset += animatorFirstCharOffset; + } + while (lastIndex < i) { + letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset; + lastIndex += 1; + } + } + // + + for (i = 0; i < len; i += 1) { + matrixHelper.reset(); + elemOpacity = 1; + if (letters[i].n) { + xPos = 0; + yPos += documentData.yOffset; + yPos += firstLine ? 1 : 0; + currentLength = initPathPos; + firstLine = false; + if (this._hasMaskedPath) { + segmentInd = initSegmentInd; + pointInd = initPointInd; + points = segments[segmentInd].points; + prevPoint = points[pointInd - 1]; + currentPoint = points[pointInd]; + partialLength = currentPoint.partialLength; + segmentLength = 0; + } + letterM = ''; + letterFc = ''; + letterSw = ''; + letterO = ''; + letterP = this.defaultPropsArray; + } else { + if (this._hasMaskedPath) { + if (currentLine !== letters[i].line) { + switch (documentData.j) { + case 1: + currentLength += totalLength - documentData.lineWidths[letters[i].line]; + break; + case 2: + currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2; + break; + default: + break; + } + currentLine = letters[i].line; + } + if (ind !== letters[i].ind) { + if (letters[ind]) { + currentLength += letters[ind].extra; + } + currentLength += letters[i].an / 2; + ind = letters[i].ind; + } + currentLength += (alignment[0] * letters[i].an) * 0.005; + var animatorOffset = 0; + for (j = 0; j < jLen; j += 1) { + animatorProps = animators[j].a; + if (animatorProps.p.propType) { + animatorSelector = animators[j].s; + mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars); + if (mult.length) { + animatorOffset += animatorProps.p.v[0] * mult[0]; + } else { + animatorOffset += animatorProps.p.v[0] * mult; + } + } + if (animatorProps.a.propType) { + animatorSelector = animators[j].s; + mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars); + if (mult.length) { + animatorOffset += animatorProps.a.v[0] * mult[0]; + } else { + animatorOffset += animatorProps.a.v[0] * mult; + } + } + } + flag = true; + // Force alignment only works with a single line for now + if (this._pathData.a.v) { + currentLength = letters[0].an * 0.5 + ((totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind) / (len - 1); + currentLength += this._pathData.f.v; + } + while (flag) { + if (segmentLength + partialLength >= currentLength + animatorOffset || !points) { + perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength; + xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc; + yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc; + matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, -(alignment[1] * yOff) * 0.01); + flag = false; + } else if (points) { + segmentLength += currentPoint.partialLength; + pointInd += 1; + if (pointInd >= points.length) { + pointInd = 0; + segmentInd += 1; + if (!segments[segmentInd]) { + if (mask.v.c) { + pointInd = 0; + segmentInd = 0; + points = segments[segmentInd].points; + } else { + segmentLength -= currentPoint.partialLength; + points = null; + } + } else { + points = segments[segmentInd].points; + } + } + if (points) { + prevPoint = currentPoint; + currentPoint = points[pointInd]; + partialLength = currentPoint.partialLength; + } + } + } + offf = letters[i].an / 2 - letters[i].add; + matrixHelper.translate(-offf, 0, 0); + } else { + offf = letters[i].an / 2 - letters[i].add; + matrixHelper.translate(-offf, 0, 0); + + // Grouping alignment + matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, (-alignment[1] * yOff) * 0.01, 0); + } + + for (j = 0; j < jLen; j += 1) { + animatorProps = animators[j].a; + if (animatorProps.t.propType) { + animatorSelector = animators[j].s; + mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars); + // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine" + if (xPos !== 0 || documentData.j !== 0) { + if (this._hasMaskedPath) { + if (mult.length) { + currentLength += animatorProps.t.v * mult[0]; + } else { + currentLength += animatorProps.t.v * mult; + } + } else if (mult.length) { + xPos += animatorProps.t.v * mult[0]; + } else { + xPos += animatorProps.t.v * mult; + } + } + } + } + if (documentData.strokeWidthAnim) { + sw = documentData.sw || 0; + } + if (documentData.strokeColorAnim) { + if (documentData.sc) { + sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]]; + } else { + sc = [0, 0, 0]; + } + } + if (documentData.fillColorAnim && documentData.fc) { + fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]]; + } + for (j = 0; j < jLen; j += 1) { + animatorProps = animators[j].a; + if (animatorProps.a.propType) { + animatorSelector = animators[j].s; + mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars); + + if (mult.length) { + matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]); + } else { + matrixHelper.translate(-animatorProps.a.v[0] * mult, -animatorProps.a.v[1] * mult, animatorProps.a.v[2] * mult); + } + } + } + for (j = 0; j < jLen; j += 1) { + animatorProps = animators[j].a; + if (animatorProps.s.propType) { + animatorSelector = animators[j].s; + mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars); + if (mult.length) { + matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult[0]), 1 + ((animatorProps.s.v[1] - 1) * mult[1]), 1); + } else { + matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult), 1 + ((animatorProps.s.v[1] - 1) * mult), 1); + } + } + } + for (j = 0; j < jLen; j += 1) { + animatorProps = animators[j].a; + animatorSelector = animators[j].s; + mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars); + if (animatorProps.sk.propType) { + if (mult.length) { + matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]); + } else { + matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult); + } + } + if (animatorProps.r.propType) { + if (mult.length) { + matrixHelper.rotateZ(-animatorProps.r.v * mult[2]); + } else { + matrixHelper.rotateZ(-animatorProps.r.v * mult); + } + } + if (animatorProps.ry.propType) { + if (mult.length) { + matrixHelper.rotateY(animatorProps.ry.v * mult[1]); + } else { + matrixHelper.rotateY(animatorProps.ry.v * mult); + } + } + if (animatorProps.rx.propType) { + if (mult.length) { + matrixHelper.rotateX(animatorProps.rx.v * mult[0]); + } else { + matrixHelper.rotateX(animatorProps.rx.v * mult); + } + } + if (animatorProps.o.propType) { + if (mult.length) { + elemOpacity += ((animatorProps.o.v) * mult[0] - elemOpacity) * mult[0]; + } else { + elemOpacity += ((animatorProps.o.v) * mult - elemOpacity) * mult; + } + } + if (documentData.strokeWidthAnim && animatorProps.sw.propType) { + if (mult.length) { + sw += animatorProps.sw.v * mult[0]; + } else { + sw += animatorProps.sw.v * mult; + } + } + if (documentData.strokeColorAnim && animatorProps.sc.propType) { + for (k = 0; k < 3; k += 1) { + if (mult.length) { + sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult[0]; + } else { + sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult; + } + } + } + if (documentData.fillColorAnim && documentData.fc) { + if (animatorProps.fc.propType) { + for (k = 0; k < 3; k += 1) { + if (mult.length) { + fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult[0]; + } else { + fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult; + } + } + } + if (animatorProps.fh.propType) { + if (mult.length) { + fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]); + } else { + fc = addHueToRGB(fc, animatorProps.fh.v * mult); + } + } + if (animatorProps.fs.propType) { + if (mult.length) { + fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]); + } else { + fc = addSaturationToRGB(fc, animatorProps.fs.v * mult); + } + } + if (animatorProps.fb.propType) { + if (mult.length) { + fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]); + } else { + fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult); + } + } + } + } + + for (j = 0; j < jLen; j += 1) { + animatorProps = animators[j].a; + + if (animatorProps.p.propType) { + animatorSelector = animators[j].s; + mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars); + if (this._hasMaskedPath) { + if (mult.length) { + matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]); + } else { + matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult); + } + } else if (mult.length) { + matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]); + } else { + matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult); + } + } + } + if (documentData.strokeWidthAnim) { + letterSw = sw < 0 ? 0 : sw; + } + if (documentData.strokeColorAnim) { + letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')'; + } + if (documentData.fillColorAnim && documentData.fc) { + letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')'; + } + + if (this._hasMaskedPath) { + matrixHelper.translate(0, -documentData.ls); + + matrixHelper.translate(0, (alignment[1] * yOff) * 0.01 + yPos, 0); + if (this._pathData.p.v) { + tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]); + var rot = (Math.atan(tanAngle) * 180) / Math.PI; + if (currentPoint.point[0] < prevPoint.point[0]) { + rot += 180; + } + matrixHelper.rotate((-rot * Math.PI) / 180); + } + matrixHelper.translate(xPathPos, yPathPos, 0); + currentLength -= (alignment[0] * letters[i].an) * 0.005; + if (letters[i + 1] && ind !== letters[i + 1].ind) { + currentLength += letters[i].an / 2; + currentLength += (documentData.tr * 0.001) * documentData.finalSize; + } + } else { + matrixHelper.translate(xPos, yPos, 0); + + if (documentData.ps) { + // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0); + matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0); + } + switch (documentData.j) { + case 1: + matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0); + break; + case 2: + matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0); + break; + default: + break; + } + matrixHelper.translate(0, -documentData.ls); + matrixHelper.translate(offf, 0, 0); + matrixHelper.translate((alignment[0] * letters[i].an) * 0.005, (alignment[1] * yOff) * 0.01, 0); + xPos += letters[i].l + (documentData.tr * 0.001) * documentData.finalSize; + } + if (renderType === 'html') { + letterM = matrixHelper.toCSS(); + } else if (renderType === 'svg') { + letterM = matrixHelper.to2dCSS(); + } else { + letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]]; + } + letterO = elemOpacity; + } + + if (renderedLettersCount <= i) { + letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP); + this.renderedLetters.push(letterValue); + renderedLettersCount += 1; + this.lettersChangedFlag = true; + } else { + letterValue = this.renderedLetters[i]; + this.lettersChangedFlag = letterValue.update(letterO, letterSw, letterSc, letterFc, letterM, letterP) || this.lettersChangedFlag; + } + } +}; + +TextAnimatorProperty.prototype.getValue = function () { + if (this._elem.globalData.frameId === this._frameId) { + return; + } + this._frameId = this._elem.globalData.frameId; + this.iterateDynamicProperties(); +}; + +TextAnimatorProperty.prototype.mHelper = new Matrix(); +TextAnimatorProperty.prototype.defaultPropsArray = []; +extendPrototype([DynamicPropertyContainer], TextAnimatorProperty); + +function ITextElement() { +} + +ITextElement.prototype.initElement = function (data, globalData, comp) { + this.lettersChangedFlag = true; + this.initFrame(); + this.initBaseData(data, globalData, comp); + this.textProperty = new TextProperty(this, data.t, this.dynamicProperties); + this.textAnimator = new TextAnimatorProperty(data.t, this.renderType, this); + this.initTransform(data, globalData, comp); + this.initHierarchy(); + this.initRenderable(); + this.initRendererElement(); + this.createContainerElements(); + this.createRenderableComponents(); + this.createContent(); + this.hide(); + this.textAnimator.searchProperties(this.dynamicProperties); +}; + +ITextElement.prototype.prepareFrame = function (num) { + this._mdf = false; + this.prepareRenderableFrame(num); + this.prepareProperties(num, this.isInRange); + if (this.textProperty._mdf || this.textProperty._isFirstFrame) { + this.buildNewText(); + this.textProperty._isFirstFrame = false; + this.textProperty._mdf = false; + } +}; + +ITextElement.prototype.createPathShape = function (matrixHelper, shapes) { + var j; + var jLen = shapes.length; + var pathNodes; + var shapeStr = ''; + for (j = 0; j < jLen; j += 1) { + if (shapes[j].ty === 'sh') { + pathNodes = shapes[j].ks.k; + shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper); + } + } + return shapeStr; +}; + +ITextElement.prototype.updateDocumentData = function (newData, index) { + this.textProperty.updateDocumentData(newData, index); +}; + +ITextElement.prototype.canResizeFont = function (_canResize) { + this.textProperty.canResizeFont(_canResize); +}; + +ITextElement.prototype.setMinimumFontSize = function (_fontSize) { + this.textProperty.setMinimumFontSize(_fontSize); +}; + +ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) { + if (documentData.ps) { + matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0); + } + matrixHelper.translate(0, -documentData.ls, 0); + switch (documentData.j) { + case 1: + matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0); + break; + case 2: + matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0); + break; + default: + break; + } + matrixHelper.translate(xPos, yPos, 0); +}; + +ITextElement.prototype.buildColor = function (colorData) { + return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')'; +}; + +ITextElement.prototype.emptyProp = new LetterProps(); + +ITextElement.prototype.destroy = function () { + +}; + +var emptyShapeData = { + shapes: [], +}; + +function SVGTextLottieElement(data, globalData, comp) { + this.textSpans = []; + this.renderType = 'svg'; + this.initElement(data, globalData, comp); +} + +extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement); + +SVGTextLottieElement.prototype.createContent = function () { + if (this.data.singleShape && !this.globalData.fontManager.chars) { + this.textContainer = createNS('text'); + } +}; + +SVGTextLottieElement.prototype.buildTextContents = function (textArray) { + var i = 0; + var len = textArray.length; + var textContents = []; + var currentTextContent = ''; + while (i < len) { + if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) { + textContents.push(currentTextContent); + currentTextContent = ''; + } else { + currentTextContent += textArray[i]; + } + i += 1; + } + textContents.push(currentTextContent); + return textContents; +}; + +SVGTextLottieElement.prototype.buildShapeData = function (data, scale) { + // data should probably be cloned to apply scale separately to each instance of a text on different layers + // but since text internal content gets only rendered once and then it's never rerendered, + // it's probably safe not to clone data and reuse always the same instance even if the object is mutated. + // Avoiding cloning is preferred since cloning each character shape data is expensive + if (data.shapes && data.shapes.length) { + var shape = data.shapes[0]; + if (shape.it) { + var shapeItem = shape.it[shape.it.length - 1]; + if (shapeItem.s) { + shapeItem.s.k[0] = scale; + shapeItem.s.k[1] = scale; + } + } + } + return data; +}; + +SVGTextLottieElement.prototype.buildNewText = function () { + this.addDynamicProperty(this); + var i; + var len; + + var documentData = this.textProperty.currentData; + this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0); + if (documentData.fc) { + this.layerElement.setAttribute('fill', this.buildColor(documentData.fc)); + } else { + this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)'); + } + if (documentData.sc) { + this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc)); + this.layerElement.setAttribute('stroke-width', documentData.sw); + } + this.layerElement.setAttribute('font-size', documentData.finalSize); + var fontData = this.globalData.fontManager.getFontByName(documentData.f); + if (fontData.fClass) { + this.layerElement.setAttribute('class', fontData.fClass); + } else { + this.layerElement.setAttribute('font-family', fontData.fFamily); + var fWeight = documentData.fWeight; + var fStyle = documentData.fStyle; + this.layerElement.setAttribute('font-style', fStyle); + this.layerElement.setAttribute('font-weight', fWeight); + } + this.layerElement.setAttribute('aria-label', documentData.t); + + var letters = documentData.l || []; + var usesGlyphs = !!this.globalData.fontManager.chars; + len = letters.length; + + var tSpan; + var matrixHelper = this.mHelper; + var shapeStr = ''; + var singleShape = this.data.singleShape; + var xPos = 0; + var yPos = 0; + var firstLine = true; + var trackingOffset = documentData.tr * 0.001 * documentData.finalSize; + if (singleShape && !usesGlyphs && !documentData.sz) { + var tElement = this.textContainer; + var justify = 'start'; + switch (documentData.j) { + case 1: + justify = 'end'; + break; + case 2: + justify = 'middle'; + break; + default: + justify = 'start'; + break; + } + tElement.setAttribute('text-anchor', justify); + tElement.setAttribute('letter-spacing', trackingOffset); + var textContent = this.buildTextContents(documentData.finalText); + len = textContent.length; + yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0; + for (i = 0; i < len; i += 1) { + tSpan = this.textSpans[i].span || createNS('tspan'); + tSpan.textContent = textContent[i]; + tSpan.setAttribute('x', 0); + tSpan.setAttribute('y', yPos); + tSpan.style.display = 'inherit'; + tElement.appendChild(tSpan); + if (!this.textSpans[i]) { + this.textSpans[i] = { + span: null, + glyph: null, + }; + } + this.textSpans[i].span = tSpan; + yPos += documentData.finalLineHeight; + } + + this.layerElement.appendChild(tElement); + } else { + var cachedSpansLength = this.textSpans.length; + var charData; + for (i = 0; i < len; i += 1) { + if (!this.textSpans[i]) { + this.textSpans[i] = { + span: null, + childSpan: null, + glyph: null, + }; + } + if (!usesGlyphs || !singleShape || i === 0) { + tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text'); + if (cachedSpansLength <= i) { + tSpan.setAttribute('stroke-linecap', 'butt'); + tSpan.setAttribute('stroke-linejoin', 'round'); + tSpan.setAttribute('stroke-miterlimit', '4'); + this.textSpans[i].span = tSpan; + if (usesGlyphs) { + var childSpan = createNS('g'); + tSpan.appendChild(childSpan); + this.textSpans[i].childSpan = childSpan; + } + this.textSpans[i].span = tSpan; + this.layerElement.appendChild(tSpan); + } + tSpan.style.display = 'inherit'; + } + + matrixHelper.reset(); + if (singleShape) { + if (letters[i].n) { + xPos = -trackingOffset; + yPos += documentData.yOffset; + yPos += firstLine ? 1 : 0; + firstLine = false; + } + this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos); + xPos += letters[i].l || 0; + // xPos += letters[i].val === ' ' ? 0 : trackingOffset; + xPos += trackingOffset; + } + if (usesGlyphs) { + charData = this.globalData.fontManager.getCharData( + documentData.finalText[i], + fontData.fStyle, + this.globalData.fontManager.getFontByName(documentData.f).fFamily + ); + var glyphElement; + // t === 1 means the character has been replaced with an animated shaped + if (charData.t === 1) { + glyphElement = new SVGCompElement(charData.data, this.globalData, this); + } else { + var data = emptyShapeData; + if (charData.data && charData.data.shapes) { + data = this.buildShapeData(charData.data, documentData.finalSize); + } + glyphElement = new SVGShapeElement(data, this.globalData, this); + } + if (this.textSpans[i].glyph) { + var glyph = this.textSpans[i].glyph; + this.textSpans[i].childSpan.removeChild(glyph.layerElement); + glyph.destroy(); + } + this.textSpans[i].glyph = glyphElement; + glyphElement._debug = true; + glyphElement.prepareFrame(0); + glyphElement.renderFrame(); + this.textSpans[i].childSpan.appendChild(glyphElement.layerElement); + // when using animated shapes, the layer will be scaled instead of replacing the internal scale + // this might have issues with strokes and might need a different solution + if (charData.t === 1) { + this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')'); + } + } else { + if (singleShape) { + tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')'); + } + tSpan.textContent = letters[i].val; + tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve'); + } + // + } + if (singleShape && tSpan) { + tSpan.setAttribute('d', shapeStr); + } + } + while (i < this.textSpans.length) { + this.textSpans[i].span.style.display = 'none'; + i += 1; + } + + this._sizeChanged = true; +}; + +SVGTextLottieElement.prototype.sourceRectAtTime = function () { + this.prepareFrame(this.comp.renderedFrame - this.data.st); + this.renderInnerContent(); + if (this._sizeChanged) { + this._sizeChanged = false; + var textBox = this.layerElement.getBBox(); + this.bbox = { + top: textBox.y, + left: textBox.x, + width: textBox.width, + height: textBox.height, + }; + } + return this.bbox; +}; + +SVGTextLottieElement.prototype.getValue = function () { + var i; + var len = this.textSpans.length; + var glyphElement; + this.renderedFrame = this.comp.renderedFrame; + for (i = 0; i < len; i += 1) { + glyphElement = this.textSpans[i].glyph; + if (glyphElement) { + glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st); + if (glyphElement._mdf) { + this._mdf = true; + } + } + } +}; + +SVGTextLottieElement.prototype.renderInnerContent = function () { + if (!this.data.singleShape || this._mdf) { + this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag); + if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) { + this._sizeChanged = true; + var i; + var len; + var renderedLetters = this.textAnimator.renderedLetters; + + var letters = this.textProperty.currentData.l; + + len = letters.length; + var renderedLetter; + var textSpan; + var glyphElement; + for (i = 0; i < len; i += 1) { + if (!letters[i].n) { + renderedLetter = renderedLetters[i]; + textSpan = this.textSpans[i].span; + glyphElement = this.textSpans[i].glyph; + if (glyphElement) { + glyphElement.renderFrame(); + } + if (renderedLetter._mdf.m) { + textSpan.setAttribute('transform', renderedLetter.m); + } + if (renderedLetter._mdf.o) { + textSpan.setAttribute('opacity', renderedLetter.o); + } + if (renderedLetter._mdf.sw) { + textSpan.setAttribute('stroke-width', renderedLetter.sw); + } + if (renderedLetter._mdf.sc) { + textSpan.setAttribute('stroke', renderedLetter.sc); + } + if (renderedLetter._mdf.fc) { + textSpan.setAttribute('fill', renderedLetter.fc); + } + } + } + } + } +}; + +function ISolidElement(data, globalData, comp) { + this.initElement(data, globalData, comp); +} +extendPrototype([IImageElement], ISolidElement); + +ISolidElement.prototype.createContent = function () { + var rect = createNS('rect'); + /// /rect.style.width = this.data.sw; + /// /rect.style.height = this.data.sh; + /// /rect.style.fill = this.data.sc; + rect.setAttribute('width', this.data.sw); + rect.setAttribute('height', this.data.sh); + rect.setAttribute('fill', this.data.sc); + this.layerElement.appendChild(rect); +}; + +function NullElement(data, globalData, comp) { + this.initFrame(); + this.initBaseData(data, globalData, comp); + this.initFrame(); + this.initTransform(data, globalData, comp); + this.initHierarchy(); +} + +NullElement.prototype.prepareFrame = function (num) { + this.prepareProperties(num, true); +}; + +NullElement.prototype.renderFrame = function () { +}; + +NullElement.prototype.getBaseElement = function () { + return null; +}; + +NullElement.prototype.destroy = function () { +}; + +NullElement.prototype.sourceRectAtTime = function () { +}; + +NullElement.prototype.hide = function () { +}; + +extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement); + +function SVGRendererBase() { +} + +extendPrototype([BaseRenderer], SVGRendererBase); + +SVGRendererBase.prototype.createNull = function (data) { + return new NullElement(data, this.globalData, this); +}; + +SVGRendererBase.prototype.createShape = function (data) { + return new SVGShapeElement(data, this.globalData, this); +}; + +SVGRendererBase.prototype.createText = function (data) { + return new SVGTextLottieElement(data, this.globalData, this); +}; + +SVGRendererBase.prototype.createImage = function (data) { + return new IImageElement(data, this.globalData, this); +}; + +SVGRendererBase.prototype.createSolid = function (data) { + return new ISolidElement(data, this.globalData, this); +}; + +SVGRendererBase.prototype.configAnimation = function (animData) { + this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + if (this.renderConfig.viewBoxSize) { + this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize); + } else { + this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h); + } + + if (!this.renderConfig.viewBoxOnly) { + this.svgElement.setAttribute('width', animData.w); + this.svgElement.setAttribute('height', animData.h); + this.svgElement.style.width = '100%'; + this.svgElement.style.height = '100%'; + this.svgElement.style.transform = 'translate3d(0,0,0)'; + this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility; + } + if (this.renderConfig.width) { + this.svgElement.setAttribute('width', this.renderConfig.width); + } + if (this.renderConfig.height) { + this.svgElement.setAttribute('height', this.renderConfig.height); + } + if (this.renderConfig.className) { + this.svgElement.setAttribute('class', this.renderConfig.className); + } + if (this.renderConfig.id) { + this.svgElement.setAttribute('id', this.renderConfig.id); + } + if (this.renderConfig.focusable !== undefined) { + this.svgElement.setAttribute('focusable', this.renderConfig.focusable); + } + this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio); + // this.layerElement.style.transform = 'translate3d(0,0,0)'; + // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px"; + this.animationItem.wrapper.appendChild(this.svgElement); + // Mask animation + var defs = this.globalData.defs; + + this.setupGlobalData(animData, defs); + this.globalData.progressiveLoad = this.renderConfig.progressiveLoad; + this.data = animData; + + var maskElement = createNS('clipPath'); + var rect = createNS('rect'); + rect.setAttribute('width', animData.w); + rect.setAttribute('height', animData.h); + rect.setAttribute('x', 0); + rect.setAttribute('y', 0); + var maskId = createElementID(); + maskElement.setAttribute('id', maskId); + maskElement.appendChild(rect); + this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + maskId + ')'); + + defs.appendChild(maskElement); + this.layers = animData.layers; + this.elements = createSizedArray(animData.layers.length); +}; + +SVGRendererBase.prototype.destroy = function () { + if (this.animationItem.wrapper) { + this.animationItem.wrapper.innerText = ''; + } + this.layerElement = null; + this.globalData.defs = null; + var i; + var len = this.layers ? this.layers.length : 0; + for (i = 0; i < len; i += 1) { + if (this.elements[i]) { + this.elements[i].destroy(); + } + } + this.elements.length = 0; + this.destroyed = true; + this.animationItem = null; +}; + +SVGRendererBase.prototype.updateContainerSize = function () { +}; + +SVGRendererBase.prototype.buildItem = function (pos) { + var elements = this.elements; + if (elements[pos] || this.layers[pos].ty === 99) { + return; + } + elements[pos] = true; + var element = this.createItem(this.layers[pos]); + + elements[pos] = element; + if (getExpressionsPlugin()) { + if (this.layers[pos].ty === 0) { + this.globalData.projectInterface.registerComposition(element); + } + element.initExpressions(); + } + this.appendElementInPos(element, pos); + if (this.layers[pos].tt) { + if (!this.elements[pos - 1] || this.elements[pos - 1] === true) { + this.buildItem(pos - 1); + this.addPendingElement(element); + } else { + element.setMatte(elements[pos - 1].layerId); + } + } +}; + +SVGRendererBase.prototype.checkPendingElements = function () { + while (this.pendingElements.length) { + var element = this.pendingElements.pop(); + element.checkParenting(); + if (element.data.tt) { + var i = 0; + var len = this.elements.length; + while (i < len) { + if (this.elements[i] === element) { + element.setMatte(this.elements[i - 1].layerId); + break; + } + i += 1; + } + } + } +}; + +SVGRendererBase.prototype.renderFrame = function (num) { + if (this.renderedFrame === num || this.destroyed) { + return; + } + if (num === null) { + num = this.renderedFrame; + } else { + this.renderedFrame = num; + } + // console.log('-------'); + // console.log('FRAME ',num); + this.globalData.frameNum = num; + this.globalData.frameId += 1; + this.globalData.projectInterface.currentFrame = num; + this.globalData._mdf = false; + var i; + var len = this.layers.length; + if (!this.completeLayers) { + this.checkLayers(num); + } + for (i = len - 1; i >= 0; i -= 1) { + if (this.completeLayers || this.elements[i]) { + this.elements[i].prepareFrame(num - this.layers[i].st); + } + } + if (this.globalData._mdf) { + for (i = 0; i < len; i += 1) { + if (this.completeLayers || this.elements[i]) { + this.elements[i].renderFrame(); + } + } + } +}; + +SVGRendererBase.prototype.appendElementInPos = function (element, pos) { + var newElement = element.getBaseElement(); + if (!newElement) { + return; + } + var i = 0; + var nextElement; + while (i < pos) { + if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) { + nextElement = this.elements[i].getBaseElement(); + } + i += 1; + } + if (nextElement) { + this.layerElement.insertBefore(newElement, nextElement); + } else { + this.layerElement.appendChild(newElement); + } +}; + +SVGRendererBase.prototype.hide = function () { + this.layerElement.style.display = 'none'; +}; + +SVGRendererBase.prototype.show = function () { + this.layerElement.style.display = 'block'; +}; + +function ICompElement() {} + +extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement); + +ICompElement.prototype.initElement = function (data, globalData, comp) { + this.initFrame(); + this.initBaseData(data, globalData, comp); + this.initTransform(data, globalData, comp); + this.initRenderable(); + this.initHierarchy(); + this.initRendererElement(); + this.createContainerElements(); + this.createRenderableComponents(); + if (this.data.xt || !globalData.progressiveLoad) { + this.buildAllItems(); + } + this.hide(); +}; + +/* ICompElement.prototype.hide = function(){ + if(!this.hidden){ + this.hideElement(); + var i,len = this.elements.length; + for( i = 0; i < len; i+=1 ){ + if(this.elements[i]){ + this.elements[i].hide(); + } + } + } +}; */ + +ICompElement.prototype.prepareFrame = function (num) { + this._mdf = false; + this.prepareRenderableFrame(num); + this.prepareProperties(num, this.isInRange); + if (!this.isInRange && !this.data.xt) { + return; + } + + if (!this.tm._placeholder) { + var timeRemapped = this.tm.v; + if (timeRemapped === this.data.op) { + timeRemapped = this.data.op - 1; + } + this.renderedFrame = timeRemapped; + } else { + this.renderedFrame = num / this.data.sr; + } + var i; + var len = this.elements.length; + if (!this.completeLayers) { + this.checkLayers(this.renderedFrame); + } + // This iteration needs to be backwards because of how expressions connect between each other + for (i = len - 1; i >= 0; i -= 1) { + if (this.completeLayers || this.elements[i]) { + this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st); + if (this.elements[i]._mdf) { + this._mdf = true; + } + } + } +}; + +ICompElement.prototype.renderInnerContent = function () { + var i; + var len = this.layers.length; + for (i = 0; i < len; i += 1) { + if (this.completeLayers || this.elements[i]) { + this.elements[i].renderFrame(); + } + } +}; + +ICompElement.prototype.setElements = function (elems) { + this.elements = elems; +}; + +ICompElement.prototype.getElements = function () { + return this.elements; +}; + +ICompElement.prototype.destroyElements = function () { + var i; + var len = this.layers.length; + for (i = 0; i < len; i += 1) { + if (this.elements[i]) { + this.elements[i].destroy(); + } + } +}; + +ICompElement.prototype.destroy = function () { + this.destroyElements(); + this.destroyBaseElement(); +}; + +function SVGCompElement(data, globalData, comp) { + this.layers = data.layers; + this.supports3d = true; + this.completeLayers = false; + this.pendingElements = []; + this.elements = this.layers ? createSizedArray(this.layers.length) : []; + this.initElement(data, globalData, comp); + this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true }; +} + +extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement); + +SVGCompElement.prototype.createComp = function (data) { + return new SVGCompElement(data, this.globalData, this); +}; + +function SVGRenderer(animationItem, config) { + this.animationItem = animationItem; + this.layers = null; + this.renderedFrame = -1; + this.svgElement = createNS('svg'); + var ariaLabel = ''; + if (config && config.title) { + var titleElement = createNS('title'); + var titleId = createElementID(); + titleElement.setAttribute('id', titleId); + titleElement.textContent = config.title; + this.svgElement.appendChild(titleElement); + ariaLabel += titleId; + } + if (config && config.description) { + var descElement = createNS('desc'); + var descId = createElementID(); + descElement.setAttribute('id', descId); + descElement.textContent = config.description; + this.svgElement.appendChild(descElement); + ariaLabel += ' ' + descId; + } + if (ariaLabel) { + this.svgElement.setAttribute('aria-labelledby', ariaLabel); + } + var defs = createNS('defs'); + this.svgElement.appendChild(defs); + var maskElement = createNS('g'); + this.svgElement.appendChild(maskElement); + this.layerElement = maskElement; + this.renderConfig = { + preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet', + imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice', + contentVisibility: (config && config.contentVisibility) || 'visible', + progressiveLoad: (config && config.progressiveLoad) || false, + hideOnTransparent: !((config && config.hideOnTransparent === false)), + viewBoxOnly: (config && config.viewBoxOnly) || false, + viewBoxSize: (config && config.viewBoxSize) || false, + className: (config && config.className) || '', + id: (config && config.id) || '', + focusable: config && config.focusable, + filterSize: { + width: (config && config.filterSize && config.filterSize.width) || '100%', + height: (config && config.filterSize && config.filterSize.height) || '100%', + x: (config && config.filterSize && config.filterSize.x) || '0%', + y: (config && config.filterSize && config.filterSize.y) || '0%', + }, + width: (config && config.width), + height: (config && config.height), + }; + + this.globalData = { + _mdf: false, + frameNum: -1, + defs: defs, + renderConfig: this.renderConfig, + }; + this.elements = []; + this.pendingElements = []; + this.destroyed = false; + this.rendererType = 'svg'; +} + +extendPrototype([SVGRendererBase], SVGRenderer); + +SVGRenderer.prototype.createComp = function (data) { + return new SVGCompElement(data, this.globalData, this); +}; + +function CVContextData() { + this.saved = []; + this.cArrPos = 0; + this.cTr = new Matrix(); + this.cO = 1; + var i; + var len = 15; + this.savedOp = createTypedArray('float32', len); + for (i = 0; i < len; i += 1) { + this.saved[i] = createTypedArray('float32', 16); + } + this._length = len; +} + +CVContextData.prototype.duplicate = function () { + var newLength = this._length * 2; + var currentSavedOp = this.savedOp; + this.savedOp = createTypedArray('float32', newLength); + this.savedOp.set(currentSavedOp); + var i = 0; + for (i = this._length; i < newLength; i += 1) { + this.saved[i] = createTypedArray('float32', 16); + } + this._length = newLength; +}; + +CVContextData.prototype.reset = function () { + this.cArrPos = 0; + this.cTr.reset(); + this.cO = 1; +}; + +function ShapeTransformManager() { + this.sequences = {}; + this.sequenceList = []; + this.transform_key_count = 0; +} + +ShapeTransformManager.prototype = { + addTransformSequence: function (transforms) { + var i; + var len = transforms.length; + var key = '_'; + for (i = 0; i < len; i += 1) { + key += transforms[i].transform.key + '_'; + } + var sequence = this.sequences[key]; + if (!sequence) { + sequence = { + transforms: [].concat(transforms), + finalTransform: new Matrix(), + _mdf: false, + }; + this.sequences[key] = sequence; + this.sequenceList.push(sequence); + } + return sequence; + }, + processSequence: function (sequence, isFirstFrame) { + var i = 0; + var len = sequence.transforms.length; + var _mdf = isFirstFrame; + while (i < len && !isFirstFrame) { + if (sequence.transforms[i].transform.mProps._mdf) { + _mdf = true; + break; + } + i += 1; + } + if (_mdf) { + var props; + sequence.finalTransform.reset(); + for (i = len - 1; i >= 0; i -= 1) { + props = sequence.transforms[i].transform.mProps.v.props; + sequence.finalTransform.transform(props[0], props[1], props[2], props[3], props[4], props[5], props[6], props[7], props[8], props[9], props[10], props[11], props[12], props[13], props[14], props[15]); + } + } + sequence._mdf = _mdf; + }, + processSequences: function (isFirstFrame) { + var i; + var len = this.sequenceList.length; + for (i = 0; i < len; i += 1) { + this.processSequence(this.sequenceList[i], isFirstFrame); + } + }, + getNewKey: function () { + this.transform_key_count += 1; + return '_' + this.transform_key_count; + }, +}; + +function CVEffects() { + +} +CVEffects.prototype.renderFrame = function () {}; + +function CVMaskElement(data, element) { + this.data = data; + this.element = element; + this.masksProperties = this.data.masksProperties || []; + this.viewData = createSizedArray(this.masksProperties.length); + var i; + var len = this.masksProperties.length; + var hasMasks = false; + for (i = 0; i < len; i += 1) { + if (this.masksProperties[i].mode !== 'n') { + hasMasks = true; + } + this.viewData[i] = ShapePropertyFactory.getShapeProp(this.element, this.masksProperties[i], 3); + } + this.hasMasks = hasMasks; + if (hasMasks) { + this.element.addRenderableComponent(this); + } +} + +CVMaskElement.prototype.renderFrame = function () { + if (!this.hasMasks) { + return; + } + var transform = this.element.finalTransform.mat; + var ctx = this.element.canvasContext; + var i; + var len = this.masksProperties.length; + var pt; + var pts; + var data; + ctx.beginPath(); + for (i = 0; i < len; i += 1) { + if (this.masksProperties[i].mode !== 'n') { + if (this.masksProperties[i].inv) { + ctx.moveTo(0, 0); + ctx.lineTo(this.element.globalData.compSize.w, 0); + ctx.lineTo(this.element.globalData.compSize.w, this.element.globalData.compSize.h); + ctx.lineTo(0, this.element.globalData.compSize.h); + ctx.lineTo(0, 0); + } + data = this.viewData[i].v; + pt = transform.applyToPointArray(data.v[0][0], data.v[0][1], 0); + ctx.moveTo(pt[0], pt[1]); + var j; + var jLen = data._length; + for (j = 1; j < jLen; j += 1) { + pts = transform.applyToTriplePoints(data.o[j - 1], data.i[j], data.v[j]); + ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]); + } + pts = transform.applyToTriplePoints(data.o[j - 1], data.i[0], data.v[0]); + ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]); + } + } + this.element.globalData.renderer.save(true); + ctx.clip(); +}; + +CVMaskElement.prototype.getMaskProperty = MaskElement.prototype.getMaskProperty; + +CVMaskElement.prototype.destroy = function () { + this.element = null; +}; + +function CVBaseElement() { +} + +CVBaseElement.prototype = { + createElements: function () {}, + initRendererElement: function () {}, + createContainerElements: function () { + this.canvasContext = this.globalData.canvasContext; + this.renderableEffectsManager = new CVEffects(this); + }, + createContent: function () {}, + setBlendMode: function () { + var globalData = this.globalData; + if (globalData.blendMode !== this.data.bm) { + globalData.blendMode = this.data.bm; + var blendModeValue = getBlendMode(this.data.bm); + globalData.canvasContext.globalCompositeOperation = blendModeValue; + } + }, + createRenderableComponents: function () { + this.maskManager = new CVMaskElement(this.data, this); + }, + hideElement: function () { + if (!this.hidden && (!this.isInRange || this.isTransparent)) { + this.hidden = true; + } + }, + showElement: function () { + if (this.isInRange && !this.isTransparent) { + this.hidden = false; + this._isFirstFrame = true; + this.maskManager._isFirstFrame = true; + } + }, + renderFrame: function () { + if (this.hidden || this.data.hd) { + return; + } + this.renderTransform(); + this.renderRenderable(); + this.setBlendMode(); + var forceRealStack = this.data.ty === 0; + this.globalData.renderer.save(forceRealStack); + this.globalData.renderer.ctxTransform(this.finalTransform.mat.props); + this.globalData.renderer.ctxOpacity(this.finalTransform.mProp.o.v); + this.renderInnerContent(); + this.globalData.renderer.restore(forceRealStack); + if (this.maskManager.hasMasks) { + this.globalData.renderer.restore(true); + } + if (this._isFirstFrame) { + this._isFirstFrame = false; + } + }, + destroy: function () { + this.canvasContext = null; + this.data = null; + this.globalData = null; + this.maskManager.destroy(); + }, + mHelper: new Matrix(), +}; +CVBaseElement.prototype.hide = CVBaseElement.prototype.hideElement; +CVBaseElement.prototype.show = CVBaseElement.prototype.showElement; + +function CVShapeData(element, data, styles, transformsManager) { + this.styledShapes = []; + this.tr = [0, 0, 0, 0, 0, 0]; + var ty = 4; + if (data.ty === 'rc') { + ty = 5; + } else if (data.ty === 'el') { + ty = 6; + } else if (data.ty === 'sr') { + ty = 7; + } + this.sh = ShapePropertyFactory.getShapeProp(element, data, ty, element); + var i; + var len = styles.length; + var styledShape; + for (i = 0; i < len; i += 1) { + if (!styles[i].closed) { + styledShape = { + transforms: transformsManager.addTransformSequence(styles[i].transforms), + trNodes: [], + }; + this.styledShapes.push(styledShape); + styles[i].elements.push(styledShape); + } + } +} + +CVShapeData.prototype.setAsAnimated = SVGShapeData.prototype.setAsAnimated; + +function CVShapeElement(data, globalData, comp) { + this.shapes = []; + this.shapesData = data.shapes; + this.stylesList = []; + this.itemsData = []; + this.prevViewData = []; + this.shapeModifiers = []; + this.processedElements = []; + this.transformsManager = new ShapeTransformManager(); + this.initElement(data, globalData, comp); +} + +extendPrototype([BaseElement, TransformElement, CVBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableElement], CVShapeElement); + +CVShapeElement.prototype.initElement = RenderableDOMElement.prototype.initElement; + +CVShapeElement.prototype.transformHelper = { opacity: 1, _opMdf: false }; + +CVShapeElement.prototype.dashResetter = []; + +CVShapeElement.prototype.createContent = function () { + this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []); +}; + +CVShapeElement.prototype.createStyleElement = function (data, transforms) { + var styleElem = { + data: data, + type: data.ty, + preTransforms: this.transformsManager.addTransformSequence(transforms), + transforms: [], + elements: [], + closed: data.hd === true, + }; + var elementData = {}; + if (data.ty === 'fl' || data.ty === 'st') { + elementData.c = PropertyFactory.getProp(this, data.c, 1, 255, this); + if (!elementData.c.k) { + styleElem.co = 'rgb(' + bmFloor(elementData.c.v[0]) + ',' + bmFloor(elementData.c.v[1]) + ',' + bmFloor(elementData.c.v[2]) + ')'; + } + } else if (data.ty === 'gf' || data.ty === 'gs') { + elementData.s = PropertyFactory.getProp(this, data.s, 1, null, this); + elementData.e = PropertyFactory.getProp(this, data.e, 1, null, this); + elementData.h = PropertyFactory.getProp(this, data.h || { k: 0 }, 0, 0.01, this); + elementData.a = PropertyFactory.getProp(this, data.a || { k: 0 }, 0, degToRads, this); + elementData.g = new GradientProperty(this, data.g, this); + } + elementData.o = PropertyFactory.getProp(this, data.o, 0, 0.01, this); + if (data.ty === 'st' || data.ty === 'gs') { + styleElem.lc = lineCapEnum[data.lc || 2]; + styleElem.lj = lineJoinEnum[data.lj || 2]; + if (data.lj == 1) { // eslint-disable-line eqeqeq + styleElem.ml = data.ml; + } + elementData.w = PropertyFactory.getProp(this, data.w, 0, null, this); + if (!elementData.w.k) { + styleElem.wi = elementData.w.v; + } + if (data.d) { + var d = new DashProperty(this, data.d, 'canvas', this); + elementData.d = d; + if (!elementData.d.k) { + styleElem.da = elementData.d.dashArray; + styleElem.do = elementData.d.dashoffset[0]; + } + } + } else { + styleElem.r = data.r === 2 ? 'evenodd' : 'nonzero'; + } + this.stylesList.push(styleElem); + elementData.style = styleElem; + return elementData; +}; + +CVShapeElement.prototype.createGroupElement = function () { + var elementData = { + it: [], + prevViewData: [], + }; + return elementData; +}; + +CVShapeElement.prototype.createTransformElement = function (data) { + var elementData = { + transform: { + opacity: 1, + _opMdf: false, + key: this.transformsManager.getNewKey(), + op: PropertyFactory.getProp(this, data.o, 0, 0.01, this), + mProps: TransformPropertyFactory.getTransformProperty(this, data, this), + }, + }; + return elementData; +}; + +CVShapeElement.prototype.createShapeElement = function (data) { + var elementData = new CVShapeData(this, data, this.stylesList, this.transformsManager); + + this.shapes.push(elementData); + this.addShapeToModifiers(elementData); + return elementData; +}; + +CVShapeElement.prototype.reloadShapes = function () { + this._isFirstFrame = true; + var i; + var len = this.itemsData.length; + for (i = 0; i < len; i += 1) { + this.prevViewData[i] = this.itemsData[i]; + } + this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []); + len = this.dynamicProperties.length; + for (i = 0; i < len; i += 1) { + this.dynamicProperties[i].getValue(); + } + this.renderModifiers(); + this.transformsManager.processSequences(this._isFirstFrame); +}; + +CVShapeElement.prototype.addTransformToStyleList = function (transform) { + var i; + var len = this.stylesList.length; + for (i = 0; i < len; i += 1) { + if (!this.stylesList[i].closed) { + this.stylesList[i].transforms.push(transform); + } + } +}; + +CVShapeElement.prototype.removeTransformFromStyleList = function () { + var i; + var len = this.stylesList.length; + for (i = 0; i < len; i += 1) { + if (!this.stylesList[i].closed) { + this.stylesList[i].transforms.pop(); + } + } +}; + +CVShapeElement.prototype.closeStyles = function (styles) { + var i; + var len = styles.length; + for (i = 0; i < len; i += 1) { + styles[i].closed = true; + } +}; + +CVShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, shouldRender, transforms) { + var i; + var len = arr.length - 1; + var j; + var jLen; + var ownStyles = []; + var ownModifiers = []; + var processedPos; + var modifier; + var currentTransform; + var ownTransforms = [].concat(transforms); + for (i = len; i >= 0; i -= 1) { + processedPos = this.searchProcessedElement(arr[i]); + if (!processedPos) { + arr[i]._shouldRender = shouldRender; + } else { + itemsData[i] = prevViewData[processedPos - 1]; + } + if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs') { + if (!processedPos) { + itemsData[i] = this.createStyleElement(arr[i], ownTransforms); + } else { + itemsData[i].style.closed = false; + } + + ownStyles.push(itemsData[i].style); + } else if (arr[i].ty === 'gr') { + if (!processedPos) { + itemsData[i] = this.createGroupElement(arr[i]); + } else { + jLen = itemsData[i].it.length; + for (j = 0; j < jLen; j += 1) { + itemsData[i].prevViewData[j] = itemsData[i].it[j]; + } + } + this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, shouldRender, ownTransforms); + } else if (arr[i].ty === 'tr') { + if (!processedPos) { + currentTransform = this.createTransformElement(arr[i]); + itemsData[i] = currentTransform; + } + ownTransforms.push(itemsData[i]); + this.addTransformToStyleList(itemsData[i]); + } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') { + if (!processedPos) { + itemsData[i] = this.createShapeElement(arr[i]); + } + } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'pb') { + if (!processedPos) { + modifier = ShapeModifiers.getModifier(arr[i].ty); + modifier.init(this, arr[i]); + itemsData[i] = modifier; + this.shapeModifiers.push(modifier); + } else { + modifier = itemsData[i]; + modifier.closed = false; + } + ownModifiers.push(modifier); + } else if (arr[i].ty === 'rp') { + if (!processedPos) { + modifier = ShapeModifiers.getModifier(arr[i].ty); + itemsData[i] = modifier; + modifier.init(this, arr, i, itemsData); + this.shapeModifiers.push(modifier); + shouldRender = false; + } else { + modifier = itemsData[i]; + modifier.closed = true; + } + ownModifiers.push(modifier); + } + this.addProcessedElement(arr[i], i + 1); + } + this.removeTransformFromStyleList(); + this.closeStyles(ownStyles); + len = ownModifiers.length; + for (i = 0; i < len; i += 1) { + ownModifiers[i].closed = true; + } +}; + +CVShapeElement.prototype.renderInnerContent = function () { + this.transformHelper.opacity = 1; + this.transformHelper._opMdf = false; + this.renderModifiers(); + this.transformsManager.processSequences(this._isFirstFrame); + this.renderShape(this.transformHelper, this.shapesData, this.itemsData, true); +}; + +CVShapeElement.prototype.renderShapeTransform = function (parentTransform, groupTransform) { + if (parentTransform._opMdf || groupTransform.op._mdf || this._isFirstFrame) { + groupTransform.opacity = parentTransform.opacity; + groupTransform.opacity *= groupTransform.op.v; + groupTransform._opMdf = true; + } +}; + +CVShapeElement.prototype.drawLayer = function () { + var i; + var len = this.stylesList.length; + var j; + var jLen; + var k; + var kLen; + var elems; + var nodes; + var renderer = this.globalData.renderer; + var ctx = this.globalData.canvasContext; + var type; + var currentStyle; + for (i = 0; i < len; i += 1) { + currentStyle = this.stylesList[i]; + type = currentStyle.type; + + // Skipping style when + // Stroke width equals 0 + // style should not be rendered (extra unused repeaters) + // current opacity equals 0 + // global opacity equals 0 + if (!(((type === 'st' || type === 'gs') && currentStyle.wi === 0) || !currentStyle.data._shouldRender || currentStyle.coOp === 0 || this.globalData.currentGlobalAlpha === 0)) { + renderer.save(); + elems = currentStyle.elements; + if (type === 'st' || type === 'gs') { + ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd; + ctx.lineWidth = currentStyle.wi; + ctx.lineCap = currentStyle.lc; + ctx.lineJoin = currentStyle.lj; + ctx.miterLimit = currentStyle.ml || 0; + } else { + ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd; + } + renderer.ctxOpacity(currentStyle.coOp); + if (type !== 'st' && type !== 'gs') { + ctx.beginPath(); + } + renderer.ctxTransform(currentStyle.preTransforms.finalTransform.props); + jLen = elems.length; + for (j = 0; j < jLen; j += 1) { + if (type === 'st' || type === 'gs') { + ctx.beginPath(); + if (currentStyle.da) { + ctx.setLineDash(currentStyle.da); + ctx.lineDashOffset = currentStyle.do; + } + } + nodes = elems[j].trNodes; + kLen = nodes.length; + + for (k = 0; k < kLen; k += 1) { + if (nodes[k].t === 'm') { + ctx.moveTo(nodes[k].p[0], nodes[k].p[1]); + } else if (nodes[k].t === 'c') { + ctx.bezierCurveTo(nodes[k].pts[0], nodes[k].pts[1], nodes[k].pts[2], nodes[k].pts[3], nodes[k].pts[4], nodes[k].pts[5]); + } else { + ctx.closePath(); + } + } + if (type === 'st' || type === 'gs') { + ctx.stroke(); + if (currentStyle.da) { + ctx.setLineDash(this.dashResetter); + } + } + } + if (type !== 'st' && type !== 'gs') { + ctx.fill(currentStyle.r); + } + renderer.restore(); + } + } +}; + +CVShapeElement.prototype.renderShape = function (parentTransform, items, data, isMain) { + var i; + var len = items.length - 1; + var groupTransform; + groupTransform = parentTransform; + for (i = len; i >= 0; i -= 1) { + if (items[i].ty === 'tr') { + groupTransform = data[i].transform; + this.renderShapeTransform(parentTransform, groupTransform); + } else if (items[i].ty === 'sh' || items[i].ty === 'el' || items[i].ty === 'rc' || items[i].ty === 'sr') { + this.renderPath(items[i], data[i]); + } else if (items[i].ty === 'fl') { + this.renderFill(items[i], data[i], groupTransform); + } else if (items[i].ty === 'st') { + this.renderStroke(items[i], data[i], groupTransform); + } else if (items[i].ty === 'gf' || items[i].ty === 'gs') { + this.renderGradientFill(items[i], data[i], groupTransform); + } else if (items[i].ty === 'gr') { + this.renderShape(groupTransform, items[i].it, data[i].it); + } else if (items[i].ty === 'tm') { + // + } + } + if (isMain) { + this.drawLayer(); + } +}; + +CVShapeElement.prototype.renderStyledShape = function (styledShape, shape) { + if (this._isFirstFrame || shape._mdf || styledShape.transforms._mdf) { + var shapeNodes = styledShape.trNodes; + var paths = shape.paths; + var i; + var len; + var j; + var jLen = paths._length; + shapeNodes.length = 0; + var groupTransformMat = styledShape.transforms.finalTransform; + for (j = 0; j < jLen; j += 1) { + var pathNodes = paths.shapes[j]; + if (pathNodes && pathNodes.v) { + len = pathNodes._length; + for (i = 1; i < len; i += 1) { + if (i === 1) { + shapeNodes.push({ + t: 'm', + p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0), + }); + } + shapeNodes.push({ + t: 'c', + pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[i], pathNodes.v[i]), + }); + } + if (len === 1) { + shapeNodes.push({ + t: 'm', + p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0), + }); + } + if (pathNodes.c && len) { + shapeNodes.push({ + t: 'c', + pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[0], pathNodes.v[0]), + }); + shapeNodes.push({ + t: 'z', + }); + } + } + } + styledShape.trNodes = shapeNodes; + } +}; + +CVShapeElement.prototype.renderPath = function (pathData, itemData) { + if (pathData.hd !== true && pathData._shouldRender) { + var i; + var len = itemData.styledShapes.length; + for (i = 0; i < len; i += 1) { + this.renderStyledShape(itemData.styledShapes[i], itemData.sh); + } + } +}; + +CVShapeElement.prototype.renderFill = function (styleData, itemData, groupTransform) { + var styleElem = itemData.style; + + if (itemData.c._mdf || this._isFirstFrame) { + styleElem.co = 'rgb(' + + bmFloor(itemData.c.v[0]) + ',' + + bmFloor(itemData.c.v[1]) + ',' + + bmFloor(itemData.c.v[2]) + ')'; + } + if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) { + styleElem.coOp = itemData.o.v * groupTransform.opacity; + } +}; + +CVShapeElement.prototype.renderGradientFill = function (styleData, itemData, groupTransform) { + var styleElem = itemData.style; + var grd; + if (!styleElem.grd || itemData.g._mdf || itemData.s._mdf || itemData.e._mdf || (styleData.t !== 1 && (itemData.h._mdf || itemData.a._mdf))) { + var ctx = this.globalData.canvasContext; + var pt1 = itemData.s.v; + var pt2 = itemData.e.v; + if (styleData.t === 1) { + grd = ctx.createLinearGradient(pt1[0], pt1[1], pt2[0], pt2[1]); + } else { + var rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2)); + var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]); + + var percent = itemData.h.v; + if (percent >= 1) { + percent = 0.99; + } else if (percent <= -1) { + percent = -0.99; + } + var dist = rad * percent; + var x = Math.cos(ang + itemData.a.v) * dist + pt1[0]; + var y = Math.sin(ang + itemData.a.v) * dist + pt1[1]; + grd = ctx.createRadialGradient(x, y, 0, pt1[0], pt1[1], rad); + } + + var i; + var len = styleData.g.p; + var cValues = itemData.g.c; + var opacity = 1; + + for (i = 0; i < len; i += 1) { + if (itemData.g._hasOpacity && itemData.g._collapsable) { + opacity = itemData.g.o[i * 2 + 1]; + } + grd.addColorStop(cValues[i * 4] / 100, 'rgba(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ',' + opacity + ')'); + } + styleElem.grd = grd; + } + styleElem.coOp = itemData.o.v * groupTransform.opacity; +}; + +CVShapeElement.prototype.renderStroke = function (styleData, itemData, groupTransform) { + var styleElem = itemData.style; + var d = itemData.d; + if (d && (d._mdf || this._isFirstFrame)) { + styleElem.da = d.dashArray; + styleElem.do = d.dashoffset[0]; + } + if (itemData.c._mdf || this._isFirstFrame) { + styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')'; + } + if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) { + styleElem.coOp = itemData.o.v * groupTransform.opacity; + } + if (itemData.w._mdf || this._isFirstFrame) { + styleElem.wi = itemData.w.v; + } +}; + +CVShapeElement.prototype.destroy = function () { + this.shapesData = null; + this.globalData = null; + this.canvasContext = null; + this.stylesList.length = 0; + this.itemsData.length = 0; +}; + +function CVTextElement(data, globalData, comp) { + this.textSpans = []; + this.yOffset = 0; + this.fillColorAnim = false; + this.strokeColorAnim = false; + this.strokeWidthAnim = false; + this.stroke = false; + this.fill = false; + this.justifyOffset = 0; + this.currentRender = null; + this.renderType = 'canvas'; + this.values = { + fill: 'rgba(0,0,0,0)', + stroke: 'rgba(0,0,0,0)', + sWidth: 0, + fValue: '', + }; + this.initElement(data, globalData, comp); +} +extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement, ITextElement], CVTextElement); + +CVTextElement.prototype.tHelper = createTag('canvas').getContext('2d'); + +CVTextElement.prototype.buildNewText = function () { + var documentData = this.textProperty.currentData; + this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0); + + var hasFill = false; + if (documentData.fc) { + hasFill = true; + this.values.fill = this.buildColor(documentData.fc); + } else { + this.values.fill = 'rgba(0,0,0,0)'; + } + this.fill = hasFill; + var hasStroke = false; + if (documentData.sc) { + hasStroke = true; + this.values.stroke = this.buildColor(documentData.sc); + this.values.sWidth = documentData.sw; + } + var fontData = this.globalData.fontManager.getFontByName(documentData.f); + var i; + var len; + var letters = documentData.l; + var matrixHelper = this.mHelper; + this.stroke = hasStroke; + this.values.fValue = documentData.finalSize + 'px ' + this.globalData.fontManager.getFontByName(documentData.f).fFamily; + len = documentData.finalText.length; + // this.tHelper.font = this.values.fValue; + var charData; + var shapeData; + var k; + var kLen; + var shapes; + var j; + var jLen; + var pathNodes; + var commands; + var pathArr; + var singleShape = this.data.singleShape; + var trackingOffset = documentData.tr * 0.001 * documentData.finalSize; + var xPos = 0; + var yPos = 0; + var firstLine = true; + var cnt = 0; + for (i = 0; i < len; i += 1) { + charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily); + shapeData = (charData && charData.data) || {}; + matrixHelper.reset(); + if (singleShape && letters[i].n) { + xPos = -trackingOffset; + yPos += documentData.yOffset; + yPos += firstLine ? 1 : 0; + firstLine = false; + } + shapes = shapeData.shapes ? shapeData.shapes[0].it : []; + jLen = shapes.length; + matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100); + if (singleShape) { + this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos); + } + commands = createSizedArray(jLen - 1); + var commandsCounter = 0; + for (j = 0; j < jLen; j += 1) { + if (shapes[j].ty === 'sh') { + kLen = shapes[j].ks.k.i.length; + pathNodes = shapes[j].ks.k; + pathArr = []; + for (k = 1; k < kLen; k += 1) { + if (k === 1) { + pathArr.push(matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0)); + } + pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToY(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToX(pathNodes.v[k][0], pathNodes.v[k][1], 0), matrixHelper.applyToY(pathNodes.v[k][0], pathNodes.v[k][1], 0)); + } + pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToY(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0)); + commands[commandsCounter] = pathArr; + commandsCounter += 1; + } + } + if (singleShape) { + xPos += letters[i].l; + xPos += trackingOffset; + } + if (this.textSpans[cnt]) { + this.textSpans[cnt].elem = commands; + } else { + this.textSpans[cnt] = { elem: commands }; + } + cnt += 1; + } +}; + +CVTextElement.prototype.renderInnerContent = function () { + var ctx = this.canvasContext; + ctx.font = this.values.fValue; + ctx.lineCap = 'butt'; + ctx.lineJoin = 'miter'; + ctx.miterLimit = 4; + + if (!this.data.singleShape) { + this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag); + } + + var i; + var len; + var j; + var jLen; + var k; + var kLen; + var renderedLetters = this.textAnimator.renderedLetters; + + var letters = this.textProperty.currentData.l; + + len = letters.length; + var renderedLetter; + var lastFill = null; + var lastStroke = null; + var lastStrokeW = null; + var commands; + var pathArr; + for (i = 0; i < len; i += 1) { + if (!letters[i].n) { + renderedLetter = renderedLetters[i]; + if (renderedLetter) { + this.globalData.renderer.save(); + this.globalData.renderer.ctxTransform(renderedLetter.p); + this.globalData.renderer.ctxOpacity(renderedLetter.o); + } + if (this.fill) { + if (renderedLetter && renderedLetter.fc) { + if (lastFill !== renderedLetter.fc) { + lastFill = renderedLetter.fc; + ctx.fillStyle = renderedLetter.fc; + } + } else if (lastFill !== this.values.fill) { + lastFill = this.values.fill; + ctx.fillStyle = this.values.fill; + } + commands = this.textSpans[i].elem; + jLen = commands.length; + this.globalData.canvasContext.beginPath(); + for (j = 0; j < jLen; j += 1) { + pathArr = commands[j]; + kLen = pathArr.length; + this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]); + for (k = 2; k < kLen; k += 6) { + this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]); + } + } + this.globalData.canvasContext.closePath(); + this.globalData.canvasContext.fill(); + /// ctx.fillText(this.textSpans[i].val,0,0); + } + if (this.stroke) { + if (renderedLetter && renderedLetter.sw) { + if (lastStrokeW !== renderedLetter.sw) { + lastStrokeW = renderedLetter.sw; + ctx.lineWidth = renderedLetter.sw; + } + } else if (lastStrokeW !== this.values.sWidth) { + lastStrokeW = this.values.sWidth; + ctx.lineWidth = this.values.sWidth; + } + if (renderedLetter && renderedLetter.sc) { + if (lastStroke !== renderedLetter.sc) { + lastStroke = renderedLetter.sc; + ctx.strokeStyle = renderedLetter.sc; + } + } else if (lastStroke !== this.values.stroke) { + lastStroke = this.values.stroke; + ctx.strokeStyle = this.values.stroke; + } + commands = this.textSpans[i].elem; + jLen = commands.length; + this.globalData.canvasContext.beginPath(); + for (j = 0; j < jLen; j += 1) { + pathArr = commands[j]; + kLen = pathArr.length; + this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]); + for (k = 2; k < kLen; k += 6) { + this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]); + } + } + this.globalData.canvasContext.closePath(); + this.globalData.canvasContext.stroke(); + /// ctx.strokeText(letters[i].val,0,0); + } + if (renderedLetter) { + this.globalData.renderer.restore(); + } + } + } +}; + +function CVImageElement(data, globalData, comp) { + this.assetData = globalData.getAssetData(data.refId); + this.img = globalData.imageLoader.getAsset(this.assetData); + this.initElement(data, globalData, comp); +} +extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVImageElement); + +CVImageElement.prototype.initElement = SVGShapeElement.prototype.initElement; +CVImageElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame; + +CVImageElement.prototype.createContent = function () { + if (this.img.width && (this.assetData.w !== this.img.width || this.assetData.h !== this.img.height)) { + var canvas = createTag('canvas'); + canvas.width = this.assetData.w; + canvas.height = this.assetData.h; + var ctx = canvas.getContext('2d'); + + var imgW = this.img.width; + var imgH = this.img.height; + var imgRel = imgW / imgH; + var canvasRel = this.assetData.w / this.assetData.h; + var widthCrop; + var heightCrop; + var par = this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio; + if ((imgRel > canvasRel && par === 'xMidYMid slice') || (imgRel < canvasRel && par !== 'xMidYMid slice')) { + heightCrop = imgH; + widthCrop = heightCrop * canvasRel; + } else { + widthCrop = imgW; + heightCrop = widthCrop / canvasRel; + } + ctx.drawImage(this.img, (imgW - widthCrop) / 2, (imgH - heightCrop) / 2, widthCrop, heightCrop, 0, 0, this.assetData.w, this.assetData.h); + this.img = canvas; + } +}; + +CVImageElement.prototype.renderInnerContent = function () { + this.canvasContext.drawImage(this.img, 0, 0); +}; + +CVImageElement.prototype.destroy = function () { + this.img = null; +}; + +function CVSolidElement(data, globalData, comp) { + this.initElement(data, globalData, comp); +} +extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVSolidElement); + +CVSolidElement.prototype.initElement = SVGShapeElement.prototype.initElement; +CVSolidElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame; + +CVSolidElement.prototype.renderInnerContent = function () { + var ctx = this.canvasContext; + ctx.fillStyle = this.data.sc; + ctx.fillRect(0, 0, this.data.sw, this.data.sh); + // +}; + +function CanvasRendererBase(animationItem, config) { + this.animationItem = animationItem; + this.renderConfig = { + clearCanvas: (config && config.clearCanvas !== undefined) ? config.clearCanvas : true, + context: (config && config.context) || null, + progressiveLoad: (config && config.progressiveLoad) || false, + preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet', + imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice', + contentVisibility: (config && config.contentVisibility) || 'visible', + className: (config && config.className) || '', + id: (config && config.id) || '', + }; + this.renderConfig.dpr = (config && config.dpr) || 1; + if (this.animationItem.wrapper) { + this.renderConfig.dpr = (config && config.dpr) || window.devicePixelRatio || 1; + } + this.renderedFrame = -1; + this.globalData = { + frameNum: -1, + _mdf: false, + renderConfig: this.renderConfig, + currentGlobalAlpha: -1, + }; + this.contextData = new CVContextData(); + this.elements = []; + this.pendingElements = []; + this.transformMat = new Matrix(); + this.completeLayers = false; + this.rendererType = 'canvas'; +} +extendPrototype([BaseRenderer], CanvasRendererBase); + +CanvasRendererBase.prototype.createShape = function (data) { + return new CVShapeElement(data, this.globalData, this); +}; + +CanvasRendererBase.prototype.createText = function (data) { + return new CVTextElement(data, this.globalData, this); +}; + +CanvasRendererBase.prototype.createImage = function (data) { + return new CVImageElement(data, this.globalData, this); +}; + +CanvasRendererBase.prototype.createSolid = function (data) { + return new CVSolidElement(data, this.globalData, this); +}; + +CanvasRendererBase.prototype.createNull = SVGRenderer.prototype.createNull; + +CanvasRendererBase.prototype.ctxTransform = function (props) { + if (props[0] === 1 && props[1] === 0 && props[4] === 0 && props[5] === 1 && props[12] === 0 && props[13] === 0) { + return; + } + if (!this.renderConfig.clearCanvas) { + this.canvasContext.transform(props[0], props[1], props[4], props[5], props[12], props[13]); + return; + } + this.transformMat.cloneFromProps(props); + var cProps = this.contextData.cTr.props; + this.transformMat.transform(cProps[0], cProps[1], cProps[2], cProps[3], cProps[4], cProps[5], cProps[6], cProps[7], cProps[8], cProps[9], cProps[10], cProps[11], cProps[12], cProps[13], cProps[14], cProps[15]); + // this.contextData.cTr.transform(props[0],props[1],props[2],props[3],props[4],props[5],props[6],props[7],props[8],props[9],props[10],props[11],props[12],props[13],props[14],props[15]); + this.contextData.cTr.cloneFromProps(this.transformMat.props); + var trProps = this.contextData.cTr.props; + this.canvasContext.setTransform(trProps[0], trProps[1], trProps[4], trProps[5], trProps[12], trProps[13]); +}; + +CanvasRendererBase.prototype.ctxOpacity = function (op) { + /* if(op === 1){ + return; + } */ + if (!this.renderConfig.clearCanvas) { + this.canvasContext.globalAlpha *= op < 0 ? 0 : op; + this.globalData.currentGlobalAlpha = this.contextData.cO; + return; + } + this.contextData.cO *= op < 0 ? 0 : op; + if (this.globalData.currentGlobalAlpha !== this.contextData.cO) { + this.canvasContext.globalAlpha = this.contextData.cO; + this.globalData.currentGlobalAlpha = this.contextData.cO; + } +}; + +CanvasRendererBase.prototype.reset = function () { + if (!this.renderConfig.clearCanvas) { + this.canvasContext.restore(); + return; + } + this.contextData.reset(); +}; + +CanvasRendererBase.prototype.save = function (actionFlag) { + if (!this.renderConfig.clearCanvas) { + this.canvasContext.save(); + return; + } + if (actionFlag) { + this.canvasContext.save(); + } + var props = this.contextData.cTr.props; + if (this.contextData._length <= this.contextData.cArrPos) { + this.contextData.duplicate(); + } + var i; + var arr = this.contextData.saved[this.contextData.cArrPos]; + for (i = 0; i < 16; i += 1) { + arr[i] = props[i]; + } + this.contextData.savedOp[this.contextData.cArrPos] = this.contextData.cO; + this.contextData.cArrPos += 1; +}; + +CanvasRendererBase.prototype.restore = function (actionFlag) { + if (!this.renderConfig.clearCanvas) { + this.canvasContext.restore(); + return; + } + if (actionFlag) { + this.canvasContext.restore(); + this.globalData.blendMode = 'source-over'; + } + this.contextData.cArrPos -= 1; + var popped = this.contextData.saved[this.contextData.cArrPos]; + var i; + var arr = this.contextData.cTr.props; + for (i = 0; i < 16; i += 1) { + arr[i] = popped[i]; + } + this.canvasContext.setTransform(popped[0], popped[1], popped[4], popped[5], popped[12], popped[13]); + popped = this.contextData.savedOp[this.contextData.cArrPos]; + this.contextData.cO = popped; + if (this.globalData.currentGlobalAlpha !== popped) { + this.canvasContext.globalAlpha = popped; + this.globalData.currentGlobalAlpha = popped; + } +}; + +CanvasRendererBase.prototype.configAnimation = function (animData) { + if (this.animationItem.wrapper) { + this.animationItem.container = createTag('canvas'); + var containerStyle = this.animationItem.container.style; + containerStyle.width = '100%'; + containerStyle.height = '100%'; + var origin = '0px 0px 0px'; + containerStyle.transformOrigin = origin; + containerStyle.mozTransformOrigin = origin; + containerStyle.webkitTransformOrigin = origin; + containerStyle['-webkit-transform'] = origin; + containerStyle.contentVisibility = this.renderConfig.contentVisibility; + this.animationItem.wrapper.appendChild(this.animationItem.container); + this.canvasContext = this.animationItem.container.getContext('2d'); + if (this.renderConfig.className) { + this.animationItem.container.setAttribute('class', this.renderConfig.className); + } + if (this.renderConfig.id) { + this.animationItem.container.setAttribute('id', this.renderConfig.id); + } + } else { + this.canvasContext = this.renderConfig.context; + } + this.data = animData; + this.layers = animData.layers; + this.transformCanvas = { + w: animData.w, + h: animData.h, + sx: 0, + sy: 0, + tx: 0, + ty: 0, + }; + this.setupGlobalData(animData, document.body); + this.globalData.canvasContext = this.canvasContext; + this.globalData.renderer = this; + this.globalData.isDashed = false; + this.globalData.progressiveLoad = this.renderConfig.progressiveLoad; + this.globalData.transformCanvas = this.transformCanvas; + this.elements = createSizedArray(animData.layers.length); + + this.updateContainerSize(); +}; + +CanvasRendererBase.prototype.updateContainerSize = function () { + this.reset(); + var elementWidth; + var elementHeight; + if (this.animationItem.wrapper && this.animationItem.container) { + elementWidth = this.animationItem.wrapper.offsetWidth; + elementHeight = this.animationItem.wrapper.offsetHeight; + this.animationItem.container.setAttribute('width', elementWidth * this.renderConfig.dpr); + this.animationItem.container.setAttribute('height', elementHeight * this.renderConfig.dpr); + } else { + elementWidth = this.canvasContext.canvas.width * this.renderConfig.dpr; + elementHeight = this.canvasContext.canvas.height * this.renderConfig.dpr; + } + var elementRel; + var animationRel; + if (this.renderConfig.preserveAspectRatio.indexOf('meet') !== -1 || this.renderConfig.preserveAspectRatio.indexOf('slice') !== -1) { + var par = this.renderConfig.preserveAspectRatio.split(' '); + var fillType = par[1] || 'meet'; + var pos = par[0] || 'xMidYMid'; + var xPos = pos.substr(0, 4); + var yPos = pos.substr(4); + elementRel = elementWidth / elementHeight; + animationRel = this.transformCanvas.w / this.transformCanvas.h; + if ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice')) { + this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr); + this.transformCanvas.sy = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr); + } else { + this.transformCanvas.sx = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr); + this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr); + } + + if (xPos === 'xMid' && ((animationRel < elementRel && fillType === 'meet') || (animationRel > elementRel && fillType === 'slice'))) { + this.transformCanvas.tx = ((elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) / 2) * this.renderConfig.dpr; + } else if (xPos === 'xMax' && ((animationRel < elementRel && fillType === 'meet') || (animationRel > elementRel && fillType === 'slice'))) { + this.transformCanvas.tx = (elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) * this.renderConfig.dpr; + } else { + this.transformCanvas.tx = 0; + } + if (yPos === 'YMid' && ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice'))) { + this.transformCanvas.ty = ((elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w)) / 2) * this.renderConfig.dpr; + } else if (yPos === 'YMax' && ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice'))) { + this.transformCanvas.ty = ((elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w))) * this.renderConfig.dpr; + } else { + this.transformCanvas.ty = 0; + } + } else if (this.renderConfig.preserveAspectRatio === 'none') { + this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr); + this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr); + this.transformCanvas.tx = 0; + this.transformCanvas.ty = 0; + } else { + this.transformCanvas.sx = this.renderConfig.dpr; + this.transformCanvas.sy = this.renderConfig.dpr; + this.transformCanvas.tx = 0; + this.transformCanvas.ty = 0; + } + this.transformCanvas.props = [this.transformCanvas.sx, 0, 0, 0, 0, this.transformCanvas.sy, 0, 0, 0, 0, 1, 0, this.transformCanvas.tx, this.transformCanvas.ty, 0, 1]; + /* var i, len = this.elements.length; + for(i=0;i= 0; i -= 1) { + if (this.elements[i]) { + this.elements[i].destroy(); + } + } + this.elements.length = 0; + this.globalData.canvasContext = null; + this.animationItem.container = null; + this.destroyed = true; +}; + +CanvasRendererBase.prototype.renderFrame = function (num, forceRender) { + if ((this.renderedFrame === num && this.renderConfig.clearCanvas === true && !forceRender) || this.destroyed || num === -1) { + return; + } + this.renderedFrame = num; + this.globalData.frameNum = num - this.animationItem._isFirstFrame; + this.globalData.frameId += 1; + this.globalData._mdf = !this.renderConfig.clearCanvas || forceRender; + this.globalData.projectInterface.currentFrame = num; + + // console.log('--------'); + // console.log('NEW: ',num); + var i; + var len = this.layers.length; + if (!this.completeLayers) { + this.checkLayers(num); + } + + for (i = 0; i < len; i += 1) { + if (this.completeLayers || this.elements[i]) { + this.elements[i].prepareFrame(num - this.layers[i].st); + } + } + if (this.globalData._mdf) { + if (this.renderConfig.clearCanvas === true) { + this.canvasContext.clearRect(0, 0, this.transformCanvas.w, this.transformCanvas.h); + } else { + this.save(); + } + for (i = len - 1; i >= 0; i -= 1) { + if (this.completeLayers || this.elements[i]) { + this.elements[i].renderFrame(); + } + } + if (this.renderConfig.clearCanvas !== true) { + this.restore(); + } + } +}; + +CanvasRendererBase.prototype.buildItem = function (pos) { + var elements = this.elements; + if (elements[pos] || this.layers[pos].ty === 99) { + return; + } + var element = this.createItem(this.layers[pos], this, this.globalData); + elements[pos] = element; + element.initExpressions(); + /* if(this.layers[pos].ty === 0){ + element.resize(this.globalData.transformCanvas); + } */ +}; + +CanvasRendererBase.prototype.checkPendingElements = function () { + while (this.pendingElements.length) { + var element = this.pendingElements.pop(); + element.checkParenting(); + } +}; + +CanvasRendererBase.prototype.hide = function () { + this.animationItem.container.style.display = 'none'; +}; + +CanvasRendererBase.prototype.show = function () { + this.animationItem.container.style.display = 'block'; +}; + +function CVCompElement(data, globalData, comp) { + this.completeLayers = false; + this.layers = data.layers; + this.pendingElements = []; + this.elements = createSizedArray(this.layers.length); + this.initElement(data, globalData, comp); + this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true }; +} + +extendPrototype([CanvasRendererBase, ICompElement, CVBaseElement], CVCompElement); + +CVCompElement.prototype.renderInnerContent = function () { + var ctx = this.canvasContext; + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.lineTo(this.data.w, 0); + ctx.lineTo(this.data.w, this.data.h); + ctx.lineTo(0, this.data.h); + ctx.lineTo(0, 0); + ctx.clip(); + var i; + var len = this.layers.length; + for (i = len - 1; i >= 0; i -= 1) { + if (this.completeLayers || this.elements[i]) { + this.elements[i].renderFrame(); + } + } +}; + +CVCompElement.prototype.destroy = function () { + var i; + var len = this.layers.length; + for (i = len - 1; i >= 0; i -= 1) { + if (this.elements[i]) { + this.elements[i].destroy(); + } + } + this.layers = null; + this.elements = null; +}; + +CVCompElement.prototype.createComp = function (data) { + return new CVCompElement(data, this.globalData, this); +}; + +function CanvasRenderer(animationItem, config) { + this.animationItem = animationItem; + this.renderConfig = { + clearCanvas: (config && config.clearCanvas !== undefined) ? config.clearCanvas : true, + context: (config && config.context) || null, + progressiveLoad: (config && config.progressiveLoad) || false, + preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet', + imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice', + contentVisibility: (config && config.contentVisibility) || 'visible', + className: (config && config.className) || '', + id: (config && config.id) || '', + }; + this.renderConfig.dpr = (config && config.dpr) || 1; + if (this.animationItem.wrapper) { + this.renderConfig.dpr = (config && config.dpr) || window.devicePixelRatio || 1; + } + this.renderedFrame = -1; + this.globalData = { + frameNum: -1, + _mdf: false, + renderConfig: this.renderConfig, + currentGlobalAlpha: -1, + }; + this.contextData = new CVContextData(); + this.elements = []; + this.pendingElements = []; + this.transformMat = new Matrix(); + this.completeLayers = false; + this.rendererType = 'canvas'; +} +extendPrototype([CanvasRendererBase], CanvasRenderer); + +CanvasRenderer.prototype.createComp = function (data) { + return new CVCompElement(data, this.globalData, this); +}; + +// Registering renderers +registerRenderer('canvas', CanvasRenderer); + +// Registering shape modifiers +ShapeModifiers.registerModifier('tm', TrimModifier); +ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier); +ShapeModifiers.registerModifier('rp', RepeaterModifier); +ShapeModifiers.registerModifier('rd', RoundCornersModifier); + +const Expressions = (function () { + var ob = {}; + ob.initExpressions = initExpressions; + + function initExpressions(animation) { + var stackCount = 0; + var registers = []; + + function pushExpression() { + stackCount += 1; + } + + function popExpression() { + stackCount -= 1; + if (stackCount === 0) { + releaseInstances(); + } + } + + function registerExpressionProperty(expression) { + if (registers.indexOf(expression) === -1) { + registers.push(expression); + } + } + + function releaseInstances() { + var i; + var len = registers.length; + for (i = 0; i < len; i += 1) { + registers[i].release(); + } + registers.length = 0; + } + + animation.renderer.compInterface = CompExpressionInterface(animation.renderer); + animation.renderer.globalData.projectInterface.registerComposition(animation.renderer); + animation.renderer.globalData.pushExpression = pushExpression; + animation.renderer.globalData.popExpression = popExpression; + animation.renderer.globalData.registerExpressionProperty = registerExpressionProperty; + } + return ob; +}()); + +/* eslint-disable */ +/* + Copyright 2014 David Bau. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + */ + +function seedRandom(pool, math) { +// +// The following constants are related to IEEE 754 limits. +// + var global = this, + width = 256, // each RC4 output is 0 <= x < 256 + chunks = 6, // at least six RC4 outputs for each double + digits = 52, // there are 52 significant digits in a double + rngname = 'random', // rngname: name for Math.random and Math.seedrandom + startdenom = math.pow(width, chunks), + significance = math.pow(2, digits), + overflow = significance * 2, + mask = width - 1, + nodecrypto; // node.js crypto module, initialized at the bottom. + +// +// seedrandom() +// This is the seedrandom function described above. +// + function seedrandom(seed, options, callback) { + var key = []; + options = (options === true) ? { entropy: true } : (options || {}); + + // Flatten the seed string or build one from local entropy if needed. + var shortseed = mixkey(flatten( + options.entropy ? [seed, tostring(pool)] : + (seed === null) ? autoseed() : seed, 3), key); + + // Use the seed to initialize an ARC4 generator. + var arc4 = new ARC4(key); + + // This function returns a random double in [0, 1) that contains + // randomness in every bit of the mantissa of the IEEE 754 value. + var prng = function() { + var n = arc4.g(chunks), // Start with a numerator n < 2 ^ 48 + d = startdenom, // and denominator d = 2 ^ 48. + x = 0; // and no 'extra last byte'. + while (n < significance) { // Fill up all significant digits by + n = (n + x) * width; // shifting numerator and + d *= width; // denominator and generating a + x = arc4.g(1); // new least-significant-byte. + } + while (n >= overflow) { // To avoid rounding up, before adding + n /= 2; // last byte, shift everything + d /= 2; // right using integer math until + x >>>= 1; // we have exactly the desired bits. + } + return (n + x) / d; // Form the number within [0, 1). + }; + + prng.int32 = function() { return arc4.g(4) | 0; }; + prng.quick = function() { return arc4.g(4) / 0x100000000; }; + prng.double = prng; + + // Mix the randomness into accumulated entropy. + mixkey(tostring(arc4.S), pool); + + // Calling convention: what to return as a function of prng, seed, is_math. + return (options.pass || callback || + function(prng, seed, is_math_call, state) { + if (state) { + // Load the arc4 state from the given state if it has an S array. + if (state.S) { copy(state, arc4); } + // Only provide the .state method if requested via options.state. + prng.state = function() { return copy(arc4, {}); }; + } + + // If called as a method of Math (Math.seedrandom()), mutate + // Math.random because that is how seedrandom.js has worked since v1.0. + if (is_math_call) { math[rngname] = prng; return seed; } + + // Otherwise, it is a newer calling convention, so return the + // prng directly. + else return prng; + })( + prng, + shortseed, + 'global' in options ? options.global : (this == math), + options.state); + } + math['seed' + rngname] = seedrandom; + +// +// ARC4 +// +// An ARC4 implementation. The constructor takes a key in the form of +// an array of at most (width) integers that should be 0 <= x < (width). +// +// The g(count) method returns a pseudorandom integer that concatenates +// the next (count) outputs from ARC4. Its return value is a number x +// that is in the range 0 <= x < (width ^ count). +// + function ARC4(key) { + var t, keylen = key.length, + me = this, i = 0, j = me.i = me.j = 0, s = me.S = []; + + // The empty key [] is treated as [0]. + if (!keylen) { key = [keylen++]; } + + // Set up S using the standard key scheduling algorithm. + while (i < width) { + s[i] = i++; + } + for (i = 0; i < width; i++) { + s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))]; + s[j] = t; + } + + // The "g" method returns the next (count) outputs as one number. + me.g = function(count) { + // Using instance members instead of closure state nearly doubles speed. + var t, r = 0, + i = me.i, j = me.j, s = me.S; + while (count--) { + t = s[i = mask & (i + 1)]; + r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))]; + } + me.i = i; me.j = j; + return r; + // For robust unpredictability, the function call below automatically + // discards an initial batch of values. This is called RC4-drop[256]. + // See http://google.com/search?q=rsa+fluhrer+response&btnI + }; + } + +// +// copy() +// Copies internal state of ARC4 to or from a plain object. +// + function copy(f, t) { + t.i = f.i; + t.j = f.j; + t.S = f.S.slice(); + return t; + } + +// +// flatten() +// Converts an object tree to nested arrays of strings. +// + function flatten(obj, depth) { + var result = [], typ = (typeof obj), prop; + if (depth && typ == 'object') { + for (prop in obj) { + try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {} + } + } + return (result.length ? result : typ == 'string' ? obj : obj + '\0'); + } + +// +// mixkey() +// Mixes a string seed into a key that is an array of integers, and +// returns a shortened string seed that is equivalent to the result key. +// + function mixkey(seed, key) { + var stringseed = seed + '', smear, j = 0; + while (j < stringseed.length) { + key[mask & j] = + mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++)); + } + return tostring(key); + } + +// +// autoseed() +// Returns an object for autoseeding, using window.crypto and Node crypto +// module if available. +// + function autoseed() { + try { + if (nodecrypto) { return tostring(nodecrypto.randomBytes(width)); } + var out = new Uint8Array(width); + (global.crypto || global.msCrypto).getRandomValues(out); + return tostring(out); + } catch (e) { + var browser = global.navigator, + plugins = browser && browser.plugins; + return [+new Date(), global, plugins, global.screen, tostring(pool)]; + } + } + +// +// tostring() +// Converts an array of charcodes to a string +// + function tostring(a) { + return String.fromCharCode.apply(0, a); + } + +// +// When seedrandom.js is loaded, we immediately mix a few bits +// from the built-in RNG into the entropy pool. Because we do +// not want to interfere with deterministic PRNG state later, +// seedrandom will not call math.random on its own again after +// initialization. +// + mixkey(math.random(), pool); + +// +// Nodejs and AMD support: export the implementation as a module using +// either convention. +// + +// End anonymous scope, and pass initial values. +}; + +function initialize$2(BMMath) { + seedRandom([], BMMath); +} + +var propTypes = { + SHAPE: 'shape', +}; + +/* eslint-disable camelcase */ + +const ExpressionManager = (function () { + 'use strict'; + + var ob = {}; + var Math = BMMath; + var window = null; + var document = null; + var XMLHttpRequest = null; + var fetch = null; + var frames = null; + initialize$2(BMMath); + + function $bm_isInstanceOfArray(arr) { + return arr.constructor === Array || arr.constructor === Float32Array; + } + + function isNumerable(tOfV, v) { + return tOfV === 'number' || tOfV === 'boolean' || tOfV === 'string' || v instanceof Number; + } + + function $bm_neg(a) { + var tOfA = typeof a; + if (tOfA === 'number' || tOfA === 'boolean' || a instanceof Number) { + return -a; + } + if ($bm_isInstanceOfArray(a)) { + var i; + var lenA = a.length; + var retArr = []; + for (i = 0; i < lenA; i += 1) { + retArr[i] = -a[i]; + } + return retArr; + } + if (a.propType) { + return a.v; + } + return -a; + } + + var easeInBez = BezierFactory.getBezierEasing(0.333, 0, 0.833, 0.833, 'easeIn').get; + var easeOutBez = BezierFactory.getBezierEasing(0.167, 0.167, 0.667, 1, 'easeOut').get; + var easeInOutBez = BezierFactory.getBezierEasing(0.33, 0, 0.667, 1, 'easeInOut').get; + + function sum(a, b) { + var tOfA = typeof a; + var tOfB = typeof b; + if (tOfA === 'string' || tOfB === 'string') { + return a + b; + } + if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) { + return a + b; + } + if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) { + a = a.slice(0); + a[0] += b; + return a; + } + if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) { + b = b.slice(0); + b[0] = a + b[0]; + return b; + } + if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) { + var i = 0; + var lenA = a.length; + var lenB = b.length; + var retArr = []; + while (i < lenA || i < lenB) { + if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) { + retArr[i] = a[i] + b[i]; + } else { + retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i]; + } + i += 1; + } + return retArr; + } + return 0; + } + var add = sum; + + function sub(a, b) { + var tOfA = typeof a; + var tOfB = typeof b; + if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) { + if (tOfA === 'string') { + a = parseInt(a, 10); + } + if (tOfB === 'string') { + b = parseInt(b, 10); + } + return a - b; + } + if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) { + a = a.slice(0); + a[0] -= b; + return a; + } + if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) { + b = b.slice(0); + b[0] = a - b[0]; + return b; + } + if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) { + var i = 0; + var lenA = a.length; + var lenB = b.length; + var retArr = []; + while (i < lenA || i < lenB) { + if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) { + retArr[i] = a[i] - b[i]; + } else { + retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i]; + } + i += 1; + } + return retArr; + } + return 0; + } + + function mul(a, b) { + var tOfA = typeof a; + var tOfB = typeof b; + var arr; + if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) { + return a * b; + } + + var i; + var len; + if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) { + len = a.length; + arr = createTypedArray('float32', len); + for (i = 0; i < len; i += 1) { + arr[i] = a[i] * b; + } + return arr; + } + if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) { + len = b.length; + arr = createTypedArray('float32', len); + for (i = 0; i < len; i += 1) { + arr[i] = a * b[i]; + } + return arr; + } + return 0; + } + + function div(a, b) { + var tOfA = typeof a; + var tOfB = typeof b; + var arr; + if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) { + return a / b; + } + var i; + var len; + if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) { + len = a.length; + arr = createTypedArray('float32', len); + for (i = 0; i < len; i += 1) { + arr[i] = a[i] / b; + } + return arr; + } + if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) { + len = b.length; + arr = createTypedArray('float32', len); + for (i = 0; i < len; i += 1) { + arr[i] = a / b[i]; + } + return arr; + } + return 0; + } + function mod(a, b) { + if (typeof a === 'string') { + a = parseInt(a, 10); + } + if (typeof b === 'string') { + b = parseInt(b, 10); + } + return a % b; + } + var $bm_sum = sum; + var $bm_sub = sub; + var $bm_mul = mul; + var $bm_div = div; + var $bm_mod = mod; + + function clamp(num, min, max) { + if (min > max) { + var mm = max; + max = min; + min = mm; + } + return Math.min(Math.max(num, min), max); + } + + function radiansToDegrees(val) { + return val / degToRads; + } + var radians_to_degrees = radiansToDegrees; + + function degreesToRadians(val) { + return val * degToRads; + } + var degrees_to_radians = radiansToDegrees; + + var helperLengthArray = [0, 0, 0, 0, 0, 0]; + + function length(arr1, arr2) { + if (typeof arr1 === 'number' || arr1 instanceof Number) { + arr2 = arr2 || 0; + return Math.abs(arr1 - arr2); + } + if (!arr2) { + arr2 = helperLengthArray; + } + var i; + var len = Math.min(arr1.length, arr2.length); + var addedLength = 0; + for (i = 0; i < len; i += 1) { + addedLength += Math.pow(arr2[i] - arr1[i], 2); + } + return Math.sqrt(addedLength); + } + + function normalize(vec) { + return div(vec, length(vec)); + } + + function rgbToHsl(val) { + var r = val[0]; var g = val[1]; var b = val[2]; + var max = Math.max(r, g, b); + var min = Math.min(r, g, b); + var h; + var s; + var l = (max + min) / 2; + + if (max === min) { + h = 0; // achromatic + s = 0; // achromatic + } else { + var d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch (max) { + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + default: break; + } + h /= 6; + } + + return [h, s, l, val[3]]; + } + + 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) * (2 / 3 - t) * 6; + return p; + } + + function hslToRgb(val) { + var h = val[0]; + var s = val[1]; + var l = val[2]; + + var r; + var g; + var b; + + if (s === 0) { + r = l; // achromatic + b = l; // achromatic + g = l; // achromatic + } else { + var q = l < 0.5 ? l * (1 + s) : l + s - l * s; + var p = 2 * l - q; + r = hue2rgb(p, q, h + 1 / 3); + g = hue2rgb(p, q, h); + b = hue2rgb(p, q, h - 1 / 3); + } + + return [r, g, b, val[3]]; + } + + function linear(t, tMin, tMax, value1, value2) { + if (value1 === undefined || value2 === undefined) { + value1 = tMin; + value2 = tMax; + tMin = 0; + tMax = 1; + } + if (tMax < tMin) { + var _tMin = tMax; + tMax = tMin; + tMin = _tMin; + } + if (t <= tMin) { + return value1; + } if (t >= tMax) { + return value2; + } + var perc = tMax === tMin ? 0 : (t - tMin) / (tMax - tMin); + if (!value1.length) { + return value1 + (value2 - value1) * perc; + } + var i; + var len = value1.length; + var arr = createTypedArray('float32', len); + for (i = 0; i < len; i += 1) { + arr[i] = value1[i] + (value2[i] - value1[i]) * perc; + } + return arr; + } + function random(min, max) { + if (max === undefined) { + if (min === undefined) { + min = 0; + max = 1; + } else { + max = min; + min = undefined; + } + } + if (max.length) { + var i; + var len = max.length; + if (!min) { + min = createTypedArray('float32', len); + } + var arr = createTypedArray('float32', len); + var rnd = BMMath.random(); + for (i = 0; i < len; i += 1) { + arr[i] = min[i] + rnd * (max[i] - min[i]); + } + return arr; + } + if (min === undefined) { + min = 0; + } + var rndm = BMMath.random(); + return min + rndm * (max - min); + } + + function createPath(points, inTangents, outTangents, closed) { + var i; + var len = points.length; + var path = shapePool.newElement(); + path.setPathData(!!closed, len); + var arrPlaceholder = [0, 0]; + var inVertexPoint; + var outVertexPoint; + for (i = 0; i < len; i += 1) { + inVertexPoint = (inTangents && inTangents[i]) ? inTangents[i] : arrPlaceholder; + outVertexPoint = (outTangents && outTangents[i]) ? outTangents[i] : arrPlaceholder; + path.setTripleAt(points[i][0], points[i][1], outVertexPoint[0] + points[i][0], outVertexPoint[1] + points[i][1], inVertexPoint[0] + points[i][0], inVertexPoint[1] + points[i][1], i, true); + } + return path; + } + + function initiateExpression(elem, data, property) { + var val = data.x; + var needsVelocity = /velocity(?![\w\d])/.test(val); + var _needsRandom = val.indexOf('random') !== -1; + var elemType = elem.data.ty; + var transform; + var $bm_transform; + var content; + var effect; + var thisProperty = property; + thisProperty.valueAtTime = thisProperty.getValueAtTime; + Object.defineProperty(thisProperty, 'value', { + get: function () { + return thisProperty.v; + }, + }); + elem.comp.frameDuration = 1 / elem.comp.globalData.frameRate; + elem.comp.displayStartTime = 0; + var inPoint = elem.data.ip / elem.comp.globalData.frameRate; + var outPoint = elem.data.op / elem.comp.globalData.frameRate; + var width = elem.data.sw ? elem.data.sw : 0; + var height = elem.data.sh ? elem.data.sh : 0; + var name = elem.data.nm; + var loopIn; + var loop_in; + var loopOut; + var loop_out; + var smooth; + var toWorld; + var fromWorld; + var fromComp; + var toComp; + var fromCompToSurface; + var position; + var rotation; + var anchorPoint; + var scale; + var thisLayer; + var thisComp; + var mask; + var valueAtTime; + var velocityAtTime; + + var scoped_bm_rt; + // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls + var expression_function = eval('[function _expression_function(){' + val + ';scoped_bm_rt=$bm_rt}]')[0]; // eslint-disable-line no-eval + var numKeys = property.kf ? data.k.length : 0; + + var active = !this.data || this.data.hd !== true; + + var wiggle = function wiggle(freq, amp) { + var iWiggle; + var j; + var lenWiggle = this.pv.length ? this.pv.length : 1; + var addedAmps = createTypedArray('float32', lenWiggle); + freq = 5; + var iterations = Math.floor(time * freq); + iWiggle = 0; + j = 0; + while (iWiggle < iterations) { + // var rnd = BMMath.random(); + for (j = 0; j < lenWiggle; j += 1) { + addedAmps[j] += -amp + amp * 2 * BMMath.random(); + // addedAmps[j] += -amp + amp*2*rnd; + } + iWiggle += 1; + } + // var rnd2 = BMMath.random(); + var periods = time * freq; + var perc = periods - Math.floor(periods); + var arr = createTypedArray('float32', lenWiggle); + if (lenWiggle > 1) { + for (j = 0; j < lenWiggle; j += 1) { + arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc; + // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc; + // arr[i] = this.pv[i] + addedAmp + amp1*perc + amp2*(1-perc); + } + return arr; + } + return this.pv + addedAmps[0] + (-amp + amp * 2 * BMMath.random()) * perc; + }.bind(this); + + if (thisProperty.loopIn) { + loopIn = thisProperty.loopIn.bind(thisProperty); + loop_in = loopIn; + } + + if (thisProperty.loopOut) { + loopOut = thisProperty.loopOut.bind(thisProperty); + loop_out = loopOut; + } + + if (thisProperty.smooth) { + smooth = thisProperty.smooth.bind(thisProperty); + } + + function loopInDuration(type, duration) { + return loopIn(type, duration, true); + } + + function loopOutDuration(type, duration) { + return loopOut(type, duration, true); + } + + if (this.getValueAtTime) { + valueAtTime = this.getValueAtTime.bind(this); + } + + if (this.getVelocityAtTime) { + velocityAtTime = this.getVelocityAtTime.bind(this); + } + + var comp = elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface); + + function lookAt(elem1, elem2) { + var fVec = [elem2[0] - elem1[0], elem2[1] - elem1[1], elem2[2] - elem1[2]]; + var pitch = Math.atan2(fVec[0], Math.sqrt(fVec[1] * fVec[1] + fVec[2] * fVec[2])) / degToRads; + var yaw = -Math.atan2(fVec[1], fVec[2]) / degToRads; + return [yaw, pitch, 0]; + } + + function easeOut(t, tMin, tMax, val1, val2) { + return applyEase(easeOutBez, t, tMin, tMax, val1, val2); + } + + function easeIn(t, tMin, tMax, val1, val2) { + return applyEase(easeInBez, t, tMin, tMax, val1, val2); + } + + function ease(t, tMin, tMax, val1, val2) { + return applyEase(easeInOutBez, t, tMin, tMax, val1, val2); + } + + function applyEase(fn, t, tMin, tMax, val1, val2) { + if (val1 === undefined) { + val1 = tMin; + val2 = tMax; + } else { + t = (t - tMin) / (tMax - tMin); + } + if (t > 1) { + t = 1; + } else if (t < 0) { + t = 0; + } + var mult = fn(t); + if ($bm_isInstanceOfArray(val1)) { + var iKey; + var lenKey = val1.length; + var arr = createTypedArray('float32', lenKey); + for (iKey = 0; iKey < lenKey; iKey += 1) { + arr[iKey] = (val2[iKey] - val1[iKey]) * mult + val1[iKey]; + } + return arr; + } + return (val2 - val1) * mult + val1; + } + + function nearestKey(time) { + var iKey; + var lenKey = data.k.length; + var index; + var keyTime; + if (!data.k.length || typeof (data.k[0]) === 'number') { + index = 0; + keyTime = 0; + } else { + index = -1; + time *= elem.comp.globalData.frameRate; + if (time < data.k[0].t) { + index = 1; + keyTime = data.k[0].t; + } else { + for (iKey = 0; iKey < lenKey - 1; iKey += 1) { + if (time === data.k[iKey].t) { + index = iKey + 1; + keyTime = data.k[iKey].t; + break; + } else if (time > data.k[iKey].t && time < data.k[iKey + 1].t) { + if (time - data.k[iKey].t > data.k[iKey + 1].t - time) { + index = iKey + 2; + keyTime = data.k[iKey + 1].t; + } else { + index = iKey + 1; + keyTime = data.k[iKey].t; + } + break; + } + } + if (index === -1) { + index = iKey + 1; + keyTime = data.k[iKey].t; + } + } + } + var obKey = {}; + obKey.index = index; + obKey.time = keyTime / elem.comp.globalData.frameRate; + return obKey; + } + + function key(ind) { + var obKey; + var iKey; + var lenKey; + if (!data.k.length || typeof (data.k[0]) === 'number') { + throw new Error('The property has no keyframe at index ' + ind); + } + ind -= 1; + obKey = { + time: data.k[ind].t / elem.comp.globalData.frameRate, + value: [], + }; + var arr = Object.prototype.hasOwnProperty.call(data.k[ind], 's') ? data.k[ind].s : data.k[ind - 1].e; + + lenKey = arr.length; + for (iKey = 0; iKey < lenKey; iKey += 1) { + obKey[iKey] = arr[iKey]; + obKey.value[iKey] = arr[iKey]; + } + return obKey; + } + + function framesToTime(fr, fps) { + if (!fps) { + fps = elem.comp.globalData.frameRate; + } + return fr / fps; + } + + function timeToFrames(t, fps) { + if (!t && t !== 0) { + t = time; + } + if (!fps) { + fps = elem.comp.globalData.frameRate; + } + return t * fps; + } + + function seedRandom(seed) { + BMMath.seedrandom(randSeed + seed); + } + + function sourceRectAtTime() { + return elem.sourceRectAtTime(); + } + + function substring(init, end) { + if (typeof value === 'string') { + if (end === undefined) { + return value.substring(init); + } + return value.substring(init, end); + } + return ''; + } + + function substr(init, end) { + if (typeof value === 'string') { + if (end === undefined) { + return value.substr(init); + } + return value.substr(init, end); + } + return ''; + } + + function posterizeTime(framesPerSecond) { + time = framesPerSecond === 0 ? 0 : Math.floor(time * framesPerSecond) / framesPerSecond; + value = valueAtTime(time); + } + + var time; + var velocity; + var value; + var text; + var textIndex; + var textTotal; + var selectorValue; + var index = elem.data.ind; + var hasParent = !!(elem.hierarchy && elem.hierarchy.length); + var parent; + var randSeed = Math.floor(Math.random() * 1000000); + var globalData = elem.globalData; + function executeExpression(_value) { + // globalData.pushExpression(); + value = _value; + if (this.frameExpressionId === elem.globalData.frameId && this.propType !== 'textSelector') { + return value; + } + if (this.propType === 'textSelector') { + textIndex = this.textIndex; + textTotal = this.textTotal; + selectorValue = this.selectorValue; + } + if (!thisLayer) { + text = elem.layerInterface.text; + thisLayer = elem.layerInterface; + thisComp = elem.comp.compInterface; + toWorld = thisLayer.toWorld.bind(thisLayer); + fromWorld = thisLayer.fromWorld.bind(thisLayer); + fromComp = thisLayer.fromComp.bind(thisLayer); + toComp = thisLayer.toComp.bind(thisLayer); + mask = thisLayer.mask ? thisLayer.mask.bind(thisLayer) : null; + fromCompToSurface = fromComp; + } + if (!transform) { + transform = elem.layerInterface('ADBE Transform Group'); + $bm_transform = transform; + if (transform) { + anchorPoint = transform.anchorPoint; + /* position = transform.position; + rotation = transform.rotation; + scale = transform.scale; */ + } + } + + if (elemType === 4 && !content) { + content = thisLayer('ADBE Root Vectors Group'); + } + if (!effect) { + effect = thisLayer(4); + } + hasParent = !!(elem.hierarchy && elem.hierarchy.length); + if (hasParent && !parent) { + parent = elem.hierarchy[0].layerInterface; + } + time = this.comp.renderedFrame / this.comp.globalData.frameRate; + if (_needsRandom) { + seedRandom(randSeed + time); + } + if (needsVelocity) { + velocity = velocityAtTime(time); + } + expression_function(); + this.frameExpressionId = elem.globalData.frameId; + + // TODO: Check if it's possible to return on ShapeInterface the .v value + // Changed this to a ternary operation because Rollup failed compiling it correctly + scoped_bm_rt = scoped_bm_rt.propType === propTypes.SHAPE + ? scoped_bm_rt.v + : scoped_bm_rt; + return scoped_bm_rt; + } + // Bundlers will see these as dead code and unless we reference them + executeExpression.__preventDeadCodeRemoval = [$bm_transform, anchorPoint, time, velocity, inPoint, outPoint, width, height, name, loop_in, loop_out, smooth, toComp, fromCompToSurface, toWorld, fromWorld, mask, position, rotation, scale, thisComp, numKeys, active, wiggle, loopInDuration, loopOutDuration, comp, lookAt, easeOut, easeIn, ease, nearestKey, key, text, textIndex, textTotal, selectorValue, framesToTime, timeToFrames, sourceRectAtTime, substring, substr, posterizeTime, index, globalData]; + return executeExpression; + } + + ob.initiateExpression = initiateExpression; + ob.__preventDeadCodeRemoval = [window, document, XMLHttpRequest, fetch, frames, $bm_neg, add, $bm_sum, $bm_sub, $bm_mul, $bm_div, $bm_mod, clamp, radians_to_degrees, degreesToRadians, degrees_to_radians, normalize, rgbToHsl, hslToRgb, linear, random, createPath]; + return ob; +}()); + +const expressionHelpers = (function () { + function searchExpressions(elem, data, prop) { + if (data.x) { + prop.k = true; + prop.x = true; + prop.initiateExpression = ExpressionManager.initiateExpression; + prop.effectsSequence.push(prop.initiateExpression(elem, data, prop).bind(prop)); + } + } + + function getValueAtTime(frameNum) { + frameNum *= this.elem.globalData.frameRate; + frameNum -= this.offsetTime; + if (frameNum !== this._cachingAtTime.lastFrame) { + this._cachingAtTime.lastIndex = this._cachingAtTime.lastFrame < frameNum ? this._cachingAtTime.lastIndex : 0; + this._cachingAtTime.value = this.interpolateValue(frameNum, this._cachingAtTime); + this._cachingAtTime.lastFrame = frameNum; + } + return this._cachingAtTime.value; + } + + function getSpeedAtTime(frameNum) { + var delta = -0.01; + var v1 = this.getValueAtTime(frameNum); + var v2 = this.getValueAtTime(frameNum + delta); + var speed = 0; + if (v1.length) { + var i; + for (i = 0; i < v1.length; i += 1) { + speed += Math.pow(v2[i] - v1[i], 2); + } + speed = Math.sqrt(speed) * 100; + } else { + speed = 0; + } + return speed; + } + + function getVelocityAtTime(frameNum) { + if (this.vel !== undefined) { + return this.vel; + } + var delta = -0.001; + // frameNum += this.elem.data.st; + var v1 = this.getValueAtTime(frameNum); + var v2 = this.getValueAtTime(frameNum + delta); + var velocity; + if (v1.length) { + velocity = createTypedArray('float32', v1.length); + var i; + for (i = 0; i < v1.length; i += 1) { + // removing frameRate + // if needed, don't add it here + // velocity[i] = this.elem.globalData.frameRate*((v2[i] - v1[i])/delta); + velocity[i] = (v2[i] - v1[i]) / delta; + } + } else { + velocity = (v2 - v1) / delta; + } + return velocity; + } + + function getStaticValueAtTime() { + return this.pv; + } + + function setGroupProperty(propertyGroup) { + this.propertyGroup = propertyGroup; + } + + return { + searchExpressions: searchExpressions, + getSpeedAtTime: getSpeedAtTime, + getVelocityAtTime: getVelocityAtTime, + getValueAtTime: getValueAtTime, + getStaticValueAtTime: getStaticValueAtTime, + setGroupProperty: setGroupProperty, + }; +}()); + +function addPropertyDecorator() { + function loopOut(type, duration, durationFlag) { + if (!this.k || !this.keyframes) { + return this.pv; + } + type = type ? type.toLowerCase() : ''; + var currentFrame = this.comp.renderedFrame; + var keyframes = this.keyframes; + var lastKeyFrame = keyframes[keyframes.length - 1].t; + if (currentFrame <= lastKeyFrame) { + return this.pv; + } + var cycleDuration; + var firstKeyFrame; + if (!durationFlag) { + if (!duration || duration > keyframes.length - 1) { + duration = keyframes.length - 1; + } + firstKeyFrame = keyframes[keyframes.length - 1 - duration].t; + cycleDuration = lastKeyFrame - firstKeyFrame; + } else { + if (!duration) { + cycleDuration = Math.max(0, lastKeyFrame - this.elem.data.ip); + } else { + cycleDuration = Math.abs(lastKeyFrame - this.elem.comp.globalData.frameRate * duration); + } + firstKeyFrame = lastKeyFrame - cycleDuration; + } + var i; + var len; + var ret; + if (type === 'pingpong') { + var iterations = Math.floor((currentFrame - firstKeyFrame) / cycleDuration); + if (iterations % 2 !== 0) { + return this.getValueAtTime(((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line + } + } else if (type === 'offset') { + var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0); + var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0); + var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line + var repeats = Math.floor((currentFrame - firstKeyFrame) / cycleDuration); + if (this.pv.length) { + ret = new Array(initV.length); + len = ret.length; + for (i = 0; i < len; i += 1) { + ret[i] = (endV[i] - initV[i]) * repeats + current[i]; + } + return ret; + } + return (endV - initV) * repeats + current; + } else if (type === 'continue') { + var lastValue = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0); + var nextLastValue = this.getValueAtTime((lastKeyFrame - 0.001) / this.comp.globalData.frameRate, 0); + if (this.pv.length) { + ret = new Array(lastValue.length); + len = ret.length; + for (i = 0; i < len; i += 1) { + ret[i] = lastValue[i] + (lastValue[i] - nextLastValue[i]) * ((currentFrame - lastKeyFrame) / this.comp.globalData.frameRate) / 0.0005; // eslint-disable-line + } + return ret; + } + return lastValue + (lastValue - nextLastValue) * (((currentFrame - lastKeyFrame)) / 0.001); + } + return this.getValueAtTime((((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line + + } + + function loopIn(type, duration, durationFlag) { + if (!this.k) { + return this.pv; + } + type = type ? type.toLowerCase() : ''; + var currentFrame = this.comp.renderedFrame; + var keyframes = this.keyframes; + var firstKeyFrame = keyframes[0].t; + if (currentFrame >= firstKeyFrame) { + return this.pv; + } + var cycleDuration; + var lastKeyFrame; + if (!durationFlag) { + if (!duration || duration > keyframes.length - 1) { + duration = keyframes.length - 1; + } + lastKeyFrame = keyframes[duration].t; + cycleDuration = lastKeyFrame - firstKeyFrame; + } else { + if (!duration) { + cycleDuration = Math.max(0, this.elem.data.op - firstKeyFrame); + } else { + cycleDuration = Math.abs(this.elem.comp.globalData.frameRate * duration); + } + lastKeyFrame = firstKeyFrame + cycleDuration; + } + var i; + var len; + var ret; + if (type === 'pingpong') { + var iterations = Math.floor((firstKeyFrame - currentFrame) / cycleDuration); + if (iterations % 2 === 0) { + return this.getValueAtTime((((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line + } + } else if (type === 'offset') { + var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0); + var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0); + var current = this.getValueAtTime((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration) + firstKeyFrame) / this.comp.globalData.frameRate, 0); + var repeats = Math.floor((firstKeyFrame - currentFrame) / cycleDuration) + 1; + if (this.pv.length) { + ret = new Array(initV.length); + len = ret.length; + for (i = 0; i < len; i += 1) { + ret[i] = current[i] - (endV[i] - initV[i]) * repeats; + } + return ret; + } + return current - (endV - initV) * repeats; + } else if (type === 'continue') { + var firstValue = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0); + var nextFirstValue = this.getValueAtTime((firstKeyFrame + 0.001) / this.comp.globalData.frameRate, 0); + if (this.pv.length) { + ret = new Array(firstValue.length); + len = ret.length; + for (i = 0; i < len; i += 1) { + ret[i] = firstValue[i] + ((firstValue[i] - nextFirstValue[i]) * (firstKeyFrame - currentFrame)) / 0.001; + } + return ret; + } + return firstValue + ((firstValue - nextFirstValue) * (firstKeyFrame - currentFrame)) / 0.001; + } + return this.getValueAtTime(((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame))) / this.comp.globalData.frameRate, 0); // eslint-disable-line + + } + + function smooth(width, samples) { + if (!this.k) { + return this.pv; + } + width = (width || 0.4) * 0.5; + samples = Math.floor(samples || 5); + if (samples <= 1) { + return this.pv; + } + var currentTime = this.comp.renderedFrame / this.comp.globalData.frameRate; + var initFrame = currentTime - width; + var endFrame = currentTime + width; + var sampleFrequency = samples > 1 ? (endFrame - initFrame) / (samples - 1) : 1; + var i = 0; + var j = 0; + var value; + if (this.pv.length) { + value = createTypedArray('float32', this.pv.length); + } else { + value = 0; + } + var sampleValue; + while (i < samples) { + sampleValue = this.getValueAtTime(initFrame + i * sampleFrequency); + if (this.pv.length) { + for (j = 0; j < this.pv.length; j += 1) { + value[j] += sampleValue[j]; + } + } else { + value += sampleValue; + } + i += 1; + } + if (this.pv.length) { + for (j = 0; j < this.pv.length; j += 1) { + value[j] /= samples; + } + } else { + value /= samples; + } + return value; + } + + function getTransformValueAtTime(time) { + if (!this._transformCachingAtTime) { + this._transformCachingAtTime = { + v: new Matrix(), + }; + } + /// / + var matrix = this._transformCachingAtTime.v; + matrix.cloneFromProps(this.pre.props); + if (this.appliedTransformations < 1) { + var anchor = this.a.getValueAtTime(time); + matrix.translate( + -anchor[0] * this.a.mult, + -anchor[1] * this.a.mult, + anchor[2] * this.a.mult + ); + } + if (this.appliedTransformations < 2) { + var scale = this.s.getValueAtTime(time); + matrix.scale( + scale[0] * this.s.mult, + scale[1] * this.s.mult, + scale[2] * this.s.mult + ); + } + if (this.sk && this.appliedTransformations < 3) { + var skew = this.sk.getValueAtTime(time); + var skewAxis = this.sa.getValueAtTime(time); + matrix.skewFromAxis(-skew * this.sk.mult, skewAxis * this.sa.mult); + } + if (this.r && this.appliedTransformations < 4) { + var rotation = this.r.getValueAtTime(time); + matrix.rotate(-rotation * this.r.mult); + } else if (!this.r && this.appliedTransformations < 4) { + var rotationZ = this.rz.getValueAtTime(time); + var rotationY = this.ry.getValueAtTime(time); + var rotationX = this.rx.getValueAtTime(time); + var orientation = this.or.getValueAtTime(time); + matrix.rotateZ(-rotationZ * this.rz.mult) + .rotateY(rotationY * this.ry.mult) + .rotateX(rotationX * this.rx.mult) + .rotateZ(-orientation[2] * this.or.mult) + .rotateY(orientation[1] * this.or.mult) + .rotateX(orientation[0] * this.or.mult); + } + if (this.data.p && this.data.p.s) { + var positionX = this.px.getValueAtTime(time); + var positionY = this.py.getValueAtTime(time); + if (this.data.p.z) { + var positionZ = this.pz.getValueAtTime(time); + matrix.translate( + positionX * this.px.mult, + positionY * this.py.mult, + -positionZ * this.pz.mult + ); + } else { + matrix.translate(positionX * this.px.mult, positionY * this.py.mult, 0); + } + } else { + var position = this.p.getValueAtTime(time); + matrix.translate( + position[0] * this.p.mult, + position[1] * this.p.mult, + -position[2] * this.p.mult + ); + } + return matrix; + /// / + } + + function getTransformStaticValueAtTime() { + return this.v.clone(new Matrix()); + } + + var getTransformProperty = TransformPropertyFactory.getTransformProperty; + TransformPropertyFactory.getTransformProperty = function (elem, data, container) { + var prop = getTransformProperty(elem, data, container); + if (prop.dynamicProperties.length) { + prop.getValueAtTime = getTransformValueAtTime.bind(prop); + } else { + prop.getValueAtTime = getTransformStaticValueAtTime.bind(prop); + } + prop.setGroupProperty = expressionHelpers.setGroupProperty; + return prop; + }; + + var propertyGetProp = PropertyFactory.getProp; + PropertyFactory.getProp = function (elem, data, type, mult, container) { + var prop = propertyGetProp(elem, data, type, mult, container); + // prop.getVelocityAtTime = getVelocityAtTime; + // prop.loopOut = loopOut; + // prop.loopIn = loopIn; + if (prop.kf) { + prop.getValueAtTime = expressionHelpers.getValueAtTime.bind(prop); + } else { + prop.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(prop); + } + prop.setGroupProperty = expressionHelpers.setGroupProperty; + prop.loopOut = loopOut; + prop.loopIn = loopIn; + prop.smooth = smooth; + prop.getVelocityAtTime = expressionHelpers.getVelocityAtTime.bind(prop); + prop.getSpeedAtTime = expressionHelpers.getSpeedAtTime.bind(prop); + prop.numKeys = data.a === 1 ? data.k.length : 0; + prop.propertyIndex = data.ix; + var value = 0; + if (type !== 0) { + value = createTypedArray('float32', data.a === 1 ? data.k[0].s.length : data.k.length); + } + prop._cachingAtTime = { + lastFrame: initialDefaultFrame, + lastIndex: 0, + value: value, + }; + expressionHelpers.searchExpressions(elem, data, prop); + if (prop.k) { + container.addDynamicProperty(prop); + } + + return prop; + }; + + function getShapeValueAtTime(frameNum) { + // For now this caching object is created only when needed instead of creating it when the shape is initialized. + if (!this._cachingAtTime) { + this._cachingAtTime = { + shapeValue: shapePool.clone(this.pv), + lastIndex: 0, + lastTime: initialDefaultFrame, + }; + } + + frameNum *= this.elem.globalData.frameRate; + frameNum -= this.offsetTime; + if (frameNum !== this._cachingAtTime.lastTime) { + this._cachingAtTime.lastIndex = this._cachingAtTime.lastTime < frameNum ? this._caching.lastIndex : 0; + this._cachingAtTime.lastTime = frameNum; + this.interpolateShape(frameNum, this._cachingAtTime.shapeValue, this._cachingAtTime); + } + return this._cachingAtTime.shapeValue; + } + + var ShapePropertyConstructorFunction = ShapePropertyFactory.getConstructorFunction(); + var KeyframedShapePropertyConstructorFunction = ShapePropertyFactory.getKeyframedConstructorFunction(); + + function ShapeExpressions() {} + ShapeExpressions.prototype = { + vertices: function (prop, time) { + if (this.k) { + this.getValue(); + } + var shapePath = this.v; + if (time !== undefined) { + shapePath = this.getValueAtTime(time, 0); + } + var i; + var len = shapePath._length; + var vertices = shapePath[prop]; + var points = shapePath.v; + var arr = createSizedArray(len); + for (i = 0; i < len; i += 1) { + if (prop === 'i' || prop === 'o') { + arr[i] = [vertices[i][0] - points[i][0], vertices[i][1] - points[i][1]]; + } else { + arr[i] = [vertices[i][0], vertices[i][1]]; + } + } + return arr; + }, + points: function (time) { + return this.vertices('v', time); + }, + inTangents: function (time) { + return this.vertices('i', time); + }, + outTangents: function (time) { + return this.vertices('o', time); + }, + isClosed: function () { + return this.v.c; + }, + pointOnPath: function (perc, time) { + var shapePath = this.v; + if (time !== undefined) { + shapePath = this.getValueAtTime(time, 0); + } + if (!this._segmentsLength) { + this._segmentsLength = bez.getSegmentsLength(shapePath); + } + + var segmentsLength = this._segmentsLength; + var lengths = segmentsLength.lengths; + var lengthPos = segmentsLength.totalLength * perc; + var i = 0; + var len = lengths.length; + var accumulatedLength = 0; + var pt; + while (i < len) { + if (accumulatedLength + lengths[i].addedLength > lengthPos) { + var initIndex = i; + var endIndex = (shapePath.c && i === len - 1) ? 0 : i + 1; + var segmentPerc = (lengthPos - accumulatedLength) / lengths[i].addedLength; + pt = bez.getPointInSegment(shapePath.v[initIndex], shapePath.v[endIndex], shapePath.o[initIndex], shapePath.i[endIndex], segmentPerc, lengths[i]); + break; + } else { + accumulatedLength += lengths[i].addedLength; + } + i += 1; + } + if (!pt) { + pt = shapePath.c ? [shapePath.v[0][0], shapePath.v[0][1]] : [shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1]]; + } + return pt; + }, + vectorOnPath: function (perc, time, vectorType) { + // perc doesn't use triple equality because it can be a Number object as well as a primitive. + if (perc == 1) { // eslint-disable-line eqeqeq + perc = this.v.c; + } else if (perc == 0) { // eslint-disable-line eqeqeq + perc = 0.999; + } + var pt1 = this.pointOnPath(perc, time); + var pt2 = this.pointOnPath(perc + 0.001, time); + var xLength = pt2[0] - pt1[0]; + var yLength = pt2[1] - pt1[1]; + var magnitude = Math.sqrt(Math.pow(xLength, 2) + Math.pow(yLength, 2)); + if (magnitude === 0) { + return [0, 0]; + } + var unitVector = vectorType === 'tangent' ? [xLength / magnitude, yLength / magnitude] : [-yLength / magnitude, xLength / magnitude]; + return unitVector; + }, + tangentOnPath: function (perc, time) { + return this.vectorOnPath(perc, time, 'tangent'); + }, + normalOnPath: function (perc, time) { + return this.vectorOnPath(perc, time, 'normal'); + }, + setGroupProperty: expressionHelpers.setGroupProperty, + getValueAtTime: expressionHelpers.getStaticValueAtTime, + }; + extendPrototype([ShapeExpressions], ShapePropertyConstructorFunction); + extendPrototype([ShapeExpressions], KeyframedShapePropertyConstructorFunction); + KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime; + KeyframedShapePropertyConstructorFunction.prototype.initiateExpression = ExpressionManager.initiateExpression; + + var propertyGetShapeProp = ShapePropertyFactory.getShapeProp; + ShapePropertyFactory.getShapeProp = function (elem, data, type, arr, trims) { + var prop = propertyGetShapeProp(elem, data, type, arr, trims); + prop.propertyIndex = data.ix; + prop.lock = false; + if (type === 3) { + expressionHelpers.searchExpressions(elem, data.pt, prop); + } else if (type === 4) { + expressionHelpers.searchExpressions(elem, data.ks, prop); + } + if (prop.k) { + elem.addDynamicProperty(prop); + } + return prop; + }; +} + +function initialize$1() { + addPropertyDecorator(); +} + +function addDecorator() { + function searchExpressions() { + if (this.data.d.x) { + this.calculateExpression = ExpressionManager.initiateExpression.bind(this)(this.elem, this.data.d, this); + this.addEffect(this.getExpressionValue.bind(this)); + return true; + } + return null; + } + + TextProperty.prototype.getExpressionValue = function (currentValue, text) { + var newValue = this.calculateExpression(text); + if (currentValue.t !== newValue) { + var newData = {}; + this.copyData(newData, currentValue); + newData.t = newValue.toString(); + newData.__complete = false; + return newData; + } + return currentValue; + }; + + TextProperty.prototype.searchProperty = function () { + var isKeyframed = this.searchKeyframes(); + var hasExpressions = this.searchExpressions(); + this.kf = isKeyframed || hasExpressions; + return this.kf; + }; + + TextProperty.prototype.searchExpressions = searchExpressions; +} + +function initialize() { + addDecorator(); +} + +// Registering expression plugin +setExpressionsPlugin(Expressions); +initialize$1(); +initialize(); + +export { lottie as default }; diff --git a/examples/jsm/libs/meshopt_decoder.module.js b/examples/jsm/libs/meshopt_decoder.module.js index 1991e05242917d..d0933a9401f74c 100644 --- a/examples/jsm/libs/meshopt_decoder.module.js +++ b/examples/jsm/libs/meshopt_decoder.module.js @@ -1,36 +1,27 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. -// Copyright (C) 2016-2020, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) +// Copyright (C) 2016-2022, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) var MeshoptDecoder = (function() { "use strict"; - // Built with clang version 11.0.0 (https://github.com/llvm/llvm-project.git 0160ad802e899c2922bc9b29564080c22eb0908c) - // Built from meshoptimizer 0.14 - var wasm_base = "B9h9z9tFBBBF8fL9gBB9gLaaaaaFa9gEaaaB9gFaFa9gEaaaFaEMcBFFFGGGEIIILF9wFFFLEFBFKNFaFCx/IFMO/LFVK9tv9t9vq95GBt9f9f939h9z9t9f9j9h9s9s9f9jW9vq9zBBp9tv9z9o9v9wW9f9kv9j9v9kv9WvqWv94h919m9mvqBF8Z9tv9z9o9v9wW9f9kv9j9v9kv9J9u9kv94h919m9mvqBGy9tv9z9o9v9wW9f9kv9j9v9kv9J9u9kv949TvZ91v9u9jvBEn9tv9z9o9v9wW9f9kv9j9v9kv69p9sWvq9P9jWBIi9tv9z9o9v9wW9f9kv9j9v9kv69p9sWvq9R919hWBLn9tv9z9o9v9wW9f9kv9j9v9kv69p9sWvq9F949wBKI9z9iqlBOc+x8ycGBM/qQFTa8jUUUUBCU/EBlHL8kUUUUBC9+RKGXAGCFJAI9LQBCaRKAE2BBC+gF9HQBALAEAIJHOAGlAGTkUUUBRNCUoBAG9uC/wgBZHKCUGAKCUG9JyRVAECFJRICBRcGXEXAcAF9PQFAVAFAclAcAVJAF9JyRMGXGXAG9FQBAMCbJHKC9wZRSAKCIrCEJCGrRQANCUGJRfCBRbAIRTEXGXAOATlAQ9PQBCBRISEMATAQJRIGXAS9FQBCBRtCBREEXGXAOAIlCi9PQBCBRISLMANCU/CBJAEJRKGXGXGXGXGXATAECKrJ2BBAtCKZrCEZfIBFGEBMAKhB83EBAKCNJhB83EBSEMAKAI2BIAI2BBHmCKrHYAYCE6HYy86BBAKCFJAICIJAYJHY2BBAmCIrCEZHPAPCE6HPy86BBAKCGJAYAPJHY2BBAmCGrCEZHPAPCE6HPy86BBAKCEJAYAPJHY2BBAmCEZHmAmCE6Hmy86BBAKCIJAYAmJHY2BBAI2BFHmCKrHPAPCE6HPy86BBAKCLJAYAPJHY2BBAmCIrCEZHPAPCE6HPy86BBAKCKJAYAPJHY2BBAmCGrCEZHPAPCE6HPy86BBAKCOJAYAPJHY2BBAmCEZHmAmCE6Hmy86BBAKCNJAYAmJHY2BBAI2BGHmCKrHPAPCE6HPy86BBAKCVJAYAPJHY2BBAmCIrCEZHPAPCE6HPy86BBAKCcJAYAPJHY2BBAmCGrCEZHPAPCE6HPy86BBAKCMJAYAPJHY2BBAmCEZHmAmCE6Hmy86BBAKCSJAYAmJHm2BBAI2BEHICKrHYAYCE6HYy86BBAKCQJAmAYJHm2BBAICIrCEZHYAYCE6HYy86BBAKCfJAmAYJHm2BBAICGrCEZHYAYCE6HYy86BBAKCbJAmAYJHK2BBAICEZHIAICE6HIy86BBAKAIJRISGMAKAI2BNAI2BBHmCIrHYAYCb6HYy86BBAKCFJAICNJAYJHY2BBAmCbZHmAmCb6Hmy86BBAKCGJAYAmJHm2BBAI2BFHYCIrHPAPCb6HPy86BBAKCEJAmAPJHm2BBAYCbZHYAYCb6HYy86BBAKCIJAmAYJHm2BBAI2BGHYCIrHPAPCb6HPy86BBAKCLJAmAPJHm2BBAYCbZHYAYCb6HYy86BBAKCKJAmAYJHm2BBAI2BEHYCIrHPAPCb6HPy86BBAKCOJAmAPJHm2BBAYCbZHYAYCb6HYy86BBAKCNJAmAYJHm2BBAI2BIHYCIrHPAPCb6HPy86BBAKCVJAmAPJHm2BBAYCbZHYAYCb6HYy86BBAKCcJAmAYJHm2BBAI2BLHYCIrHPAPCb6HPy86BBAKCMJAmAPJHm2BBAYCbZHYAYCb6HYy86BBAKCSJAmAYJHm2BBAI2BKHYCIrHPAPCb6HPy86BBAKCQJAmAPJHm2BBAYCbZHYAYCb6HYy86BBAKCfJAmAYJHm2BBAI2BOHICIrHYAYCb6HYy86BBAKCbJAmAYJHK2BBAICbZHIAICb6HIy86BBAKAIJRISFMAKAI8pBB83BBAKCNJAICNJ8pBB83BBAICTJRIMAtCGJRtAECTJHEAS9JQBMMGXAIQBCBRISEMGXAM9FQBANAbJ2BBRtCBRKAfREEXAEANCU/CBJAKJ2BBHTCFrCBATCFZl9zAtJHt86BBAEAGJREAKCFJHKAM9HQBMMAfCFJRfAIRTAbCFJHbAG9HQBMMABAcAG9sJANCUGJAMAG9sTkUUUBpANANCUGJAMCaJAG9sJAGTkUUUBpMAMCBAIyAcJRcAIQBMC9+RKSFMCBC99AOAIlAGCAAGCA9Ly6yRKMALCU/EBJ8kUUUUBAKM+OmFTa8jUUUUBCoFlHL8kUUUUBC9+RKGXAFCE9uHOCtJAI9LQBCaRKAE2BBHNC/wFZC/gF9HQBANCbZHVCF9LQBALCoBJCgFCUFT+JUUUBpALC84Jha83EBALC8wJha83EBALC8oJha83EBALCAJha83EBALCiJha83EBALCTJha83EBALha83ENALha83EBAEAIJC9wJRcAECFJHNAOJRMGXAF9FQBCQCbAVCF6yRSABRECBRVCBRQCBRfCBRICBRKEXGXAMAcuQBC9+RKSEMGXGXAN2BBHOC/vF9LQBALCoBJAOCIrCa9zAKJCbZCEWJHb8oGIRTAb8oGBRtGXAOCbZHbAS9PQBALAOCa9zAIJCbZCGWJ8oGBAVAbyROAb9FRbGXGXAGCG9HQBABAt87FBABCIJAO87FBABCGJAT87FBSFMAEAtjGBAECNJAOjGBAECIJATjGBMAVAbJRVALCoBJAKCEWJHmAOjGBAmATjGIALAICGWJAOjGBALCoBJAKCFJCbZHKCEWJHTAtjGBATAOjGIAIAbJRIAKCFJRKSGMGXGXAbCb6QBAQAbJAbC989zJCFJRQSFMAM1BBHbCgFZROGXGXAbCa9MQBAMCFJRMSFMAM1BFHbCgBZCOWAOCgBZqROGXAbCa9MQBAMCGJRMSFMAM1BGHbCgBZCfWAOqROGXAbCa9MQBAMCEJRMSFMAM1BEHbCgBZCdWAOqROGXAbCa9MQBAMCIJRMSFMAM2BIC8cWAOqROAMCLJRMMAOCFrCBAOCFZl9zAQJRQMGXGXAGCG9HQBABAt87FBABCIJAQ87FBABCGJAT87FBSFMAEAtjGBAECNJAQjGBAECIJATjGBMALCoBJAKCEWJHOAQjGBAOATjGIALAICGWJAQjGBALCoBJAKCFJCbZHKCEWJHOAtjGBAOAQjGIAICFJRIAKCFJRKSFMGXAOCDF9LQBALAIAcAOCbZJ2BBHbCIrHTlCbZCGWJ8oGBAVCFJHtATyROALAIAblCbZCGWJ8oGBAtAT9FHmJHtAbCbZHTyRbAT9FRTGXGXAGCG9HQBABAV87FBABCIJAb87FBABCGJAO87FBSFMAEAVjGBAECNJAbjGBAECIJAOjGBMALAICGWJAVjGBALCoBJAKCEWJHYAOjGBAYAVjGIALAICFJHICbZCGWJAOjGBALCoBJAKCFJCbZCEWJHYAbjGBAYAOjGIALAIAmJCbZHICGWJAbjGBALCoBJAKCGJCbZHKCEWJHOAVjGBAOAbjGIAKCFJRKAIATJRIAtATJRVSFMAVCBAM2BBHYyHTAOC/+F6HPJROAYCbZRtGXGXAYCIrHmQBAOCFJRbSFMAORbALAIAmlCbZCGWJ8oGBROMGXGXAtQBAbCFJRVSFMAbRVALAIAYlCbZCGWJ8oGBRbMGXGXAP9FQBAMCFJRYSFMAM1BFHYCgFZRTGXGXAYCa9MQBAMCGJRYSFMAM1BGHYCgBZCOWATCgBZqRTGXAYCa9MQBAMCEJRYSFMAM1BEHYCgBZCfWATqRTGXAYCa9MQBAMCIJRYSFMAM1BIHYCgBZCdWATqRTGXAYCa9MQBAMCLJRYSFMAMCKJRYAM2BLC8cWATqRTMATCFrCBATCFZl9zAQJHQRTMGXGXAmCb6QBAYRPSFMAY1BBHMCgFZROGXGXAMCa9MQBAYCFJRPSFMAY1BFHMCgBZCOWAOCgBZqROGXAMCa9MQBAYCGJRPSFMAY1BGHMCgBZCfWAOqROGXAMCa9MQBAYCEJRPSFMAY1BEHMCgBZCdWAOqROGXAMCa9MQBAYCIJRPSFMAYCLJRPAY2BIC8cWAOqROMAOCFrCBAOCFZl9zAQJHQROMGXGXAtCb6QBAPRMSFMAP1BBHMCgFZRbGXGXAMCa9MQBAPCFJRMSFMAP1BFHMCgBZCOWAbCgBZqRbGXAMCa9MQBAPCGJRMSFMAP1BGHMCgBZCfWAbqRbGXAMCa9MQBAPCEJRMSFMAP1BEHMCgBZCdWAbqRbGXAMCa9MQBAPCIJRMSFMAPCLJRMAP2BIC8cWAbqRbMAbCFrCBAbCFZl9zAQJHQRbMGXGXAGCG9HQBABAT87FBABCIJAb87FBABCGJAO87FBSFMAEATjGBAECNJAbjGBAECIJAOjGBMALCoBJAKCEWJHYAOjGBAYATjGIALAICGWJATjGBALCoBJAKCFJCbZCEWJHYAbjGBAYAOjGIALAICFJHICbZCGWJAOjGBALCoBJAKCGJCbZCEWJHOATjGBAOAbjGIALAIAm9FAmCb6qJHICbZCGWJAbjGBAIAt9FAtCb6qJRIAKCEJRKMANCFJRNABCKJRBAECSJREAKCbZRKAICbZRIAfCEJHfAF9JQBMMCBC99AMAc6yRKMALCoFJ8kUUUUBAKM/tIFGa8jUUUUBCTlRLC9+RKGXAFCLJAI9LQBCaRKAE2BBC/+FZC/QF9HQBALhB83ENAECFJRKAEAIJC98JREGXAF9FQBGXAGCG6QBEXGXAKAE9JQBC9+bMAK1BBHGCgFZRIGXGXAGCa9MQBAKCFJRKSFMAK1BFHGCgBZCOWAICgBZqRIGXAGCa9MQBAKCGJRKSFMAK1BGHGCgBZCfWAIqRIGXAGCa9MQBAKCEJRKSFMAK1BEHGCgBZCdWAIqRIGXAGCa9MQBAKCIJRKSFMAK2BIC8cWAIqRIAKCLJRKMALCNJAICFZCGWqHGAICGrCBAICFrCFZl9zAG8oGBJHIjGBABAIjGBABCIJRBAFCaJHFQBSGMMEXGXAKAE9JQBC9+bMAK1BBHGCgFZRIGXGXAGCa9MQBAKCFJRKSFMAK1BFHGCgBZCOWAICgBZqRIGXAGCa9MQBAKCGJRKSFMAK1BGHGCgBZCfWAIqRIGXAGCa9MQBAKCEJRKSFMAK1BEHGCgBZCdWAIqRIGXAGCa9MQBAKCIJRKSFMAK2BIC8cWAIqRIAKCLJRKMABAICGrCBAICFrCFZl9zALCNJAICFZCGWqHI8oGBJHG87FBAIAGjGBABCGJRBAFCaJHFQBMMCBC99AKAE6yRKMAKM+lLKFaF99GaG99FaG99GXGXAGCI9HQBAF9FQFEXGXGX9DBBB8/9DBBB+/ABCGJHG1BB+yAB1BBHE+yHI+L+TABCFJHL1BBHK+yHO+L+THN9DBBBB9gHVyAN9DBB/+hANAN+U9DBBBBANAVyHcAc+MHMAECa3yAI+SHIAI+UAcAMAKCa3yAO+SHcAc+U+S+S+R+VHO+U+SHN+L9DBBB9P9d9FQBAN+oRESFMCUUUU94REMAGAE86BBGXGX9DBBB8/9DBBB+/Ac9DBBBB9gyAcAO+U+SHN+L9DBBB9P9d9FQBAN+oRGSFMCUUUU94RGMALAG86BBGXGX9DBBB8/9DBBB+/AI9DBBBB9gyAIAO+U+SHN+L9DBBB9P9d9FQBAN+oRGSFMCUUUU94RGMABAG86BBABCIJRBAFCaJHFQBSGMMAF9FQBEXGXGX9DBBB8/9DBBB+/ABCIJHG8uFB+yAB8uFBHE+yHI+L+TABCGJHL8uFBHK+yHO+L+THN9DBBBB9gHVyAN9DB/+g6ANAN+U9DBBBBANAVyHcAc+MHMAECa3yAI+SHIAI+UAcAMAKCa3yAO+SHcAc+U+S+S+R+VHO+U+SHN+L9DBBB9P9d9FQBAN+oRESFMCUUUU94REMAGAE87FBGXGX9DBBB8/9DBBB+/Ac9DBBBB9gyAcAO+U+SHN+L9DBBB9P9d9FQBAN+oRGSFMCUUUU94RGMALAG87FBGXGX9DBBB8/9DBBB+/AI9DBBBB9gyAIAO+U+SHN+L9DBBB9P9d9FQBAN+oRGSFMCUUUU94RGMABAG87FBABCNJRBAFCaJHFQBMMM/SEIEaE99EaF99GXAF9FQBCBREABRIEXGXGX9D/zI818/AICKJ8uFBHLCEq+y+VHKAI8uFB+y+UHO9DB/+g6+U9DBBB8/9DBBB+/AO9DBBBB9gy+SHN+L9DBBB9P9d9FQBAN+oRVSFMCUUUU94RVMAICIJ8uFBRcAICGJ8uFBRMABALCFJCEZAEqCFWJAV87FBGXGXAKAM+y+UHN9DB/+g6+U9DBBB8/9DBBB+/AN9DBBBB9gy+SHS+L9DBBB9P9d9FQBAS+oRMSFMCUUUU94RMMABALCGJCEZAEqCFWJAM87FBGXGXAKAc+y+UHK9DB/+g6+U9DBBB8/9DBBB+/AK9DBBBB9gy+SHS+L9DBBB9P9d9FQBAS+oRcSFMCUUUU94RcMABALCaJCEZAEqCFWJAc87FBGXGX9DBBU8/AOAO+U+TANAN+U+TAKAK+U+THO9DBBBBAO9DBBBB9gy+R9DB/+g6+U9DBBB8/+SHO+L9DBBB9P9d9FQBAO+oRcSFMCUUUU94RcMABALCEZAEqCFWJAc87FBAICNJRIAECIJREAFCaJHFQBMMM9JBGXAGCGrAF9sHF9FQBEXABAB8oGBHGCNWCN91+yAGCi91CnWCUUU/8EJ+++U84GBABCIJRBAFCaJHFQBMMM9TFEaCBCB8oGUkUUBHFABCEJC98ZJHBjGUkUUBGXGXAB8/BCTWHGuQBCaREABAGlCggEJCTrXBCa6QFMAFREMAEM/lFFFaGXGXAFABqCEZ9FQBABRESFMGXGXAGCT9PQBABRESFMABREEXAEAF8oGBjGBAECIJAFCIJ8oGBjGBAECNJAFCNJ8oGBjGBAECSJAFCSJ8oGBjGBAECTJREAFCTJRFAGC9wJHGCb9LQBMMAGCI9JQBEXAEAF8oGBjGBAFCIJRFAECIJREAGC98JHGCE9LQBMMGXAG9FQBEXAEAF2BB86BBAECFJREAFCFJRFAGCaJHGQBMMABMoFFGaGXGXABCEZ9FQBABRESFMAFCgFZC+BwsN9sRIGXGXAGCT9PQBABRESFMABREEXAEAIjGBAECSJAIjGBAECNJAIjGBAECIJAIjGBAECTJREAGC9wJHGCb9LQBMMAGCI9JQBEXAEAIjGBAECIJREAGC98JHGCE9LQBMMGXAG9FQBEXAEAF86BBAECFJREAGCaJHGQBMMABMMMFBCUNMIT9kBB"; - var wasm_simd = "B9h9z9tFBBBFiI9gBB9gLaaaaaFa9gEaaaB9gFaFaEMcBBFBFFGGGEILF9wFFFLEFBFKNFaFCx/aFMO/LFVK9tv9t9vq95GBt9f9f939h9z9t9f9j9h9s9s9f9jW9vq9zBBp9tv9z9o9v9wW9f9kv9j9v9kv9WvqWv94h919m9mvqBG8Z9tv9z9o9v9wW9f9kv9j9v9kv9J9u9kv94h919m9mvqBIy9tv9z9o9v9wW9f9kv9j9v9kv9J9u9kv949TvZ91v9u9jvBLn9tv9z9o9v9wW9f9kv9j9v9kv69p9sWvq9P9jWBKi9tv9z9o9v9wW9f9kv9j9v9kv69p9sWvq9R919hWBOn9tv9z9o9v9wW9f9kv9j9v9kv69p9sWvq9F949wBNI9z9iqlBVc+N9IcIBTEM9+FLa8jUUUUBCTlRBCBRFEXCBRGCBREEXABCNJAGJAECUaAFAGrCFZHIy86BBAEAIJREAGCFJHGCN9HQBMAFCx+YUUBJAE86BBAFCEWCxkUUBJAB8pEN83EBAFCFJHFCUG9HQBMMk8lLbaE97F9+FaL978jUUUUBCU/KBlHL8kUUUUBC9+RKGXAGCFJAI9LQBCaRKAE2BBC+gF9HQBALAEAIJHOAGlAG/8cBBCUoBAG9uC/wgBZHKCUGAKCUG9JyRNAECFJRKCBRVGXEXAVAF9PQFANAFAVlAVANJAF9JyRcGXGXAG9FQBAcCbJHIC9wZHMCE9sRSAMCFWRQAICIrCEJCGrRfCBRbEXAKRTCBRtGXEXGXAOATlAf9PQBCBRKSLMALCU/CBJAtAM9sJRmATAfJRKCBREGXAMCoB9JQBAOAKlC/gB9JQBCBRIEXAmAIJREGXGXGXGXGXATAICKrJ2BBHYCEZfIBFGEBMAECBDtDMIBSEMAEAKDBBIAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnHPCGD+MFAPDQBTFtGmEYIPLdKeOnC0+G+MiDtD9OHdCEDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHiCEWCxkUUBJDBEBAiCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHiCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMIBAKCIJAeDeBJAiCx+YUUBJ2BBJRKSGMAEAKDBBNAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnC+P+e+8/4BDtD9OHdCbDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHiCEWCxkUUBJDBEBAiCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHiCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMIBAKCNJAeDeBJAiCx+YUUBJ2BBJRKSFMAEAKDBBBDMIBAKCTJRKMGXGXGXGXGXAYCGrCEZfIBFGEBMAECBDtDMITSEMAEAKDBBIAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnHPCGD+MFAPDQBTFtGmEYIPLdKeOnC0+G+MiDtD9OHdCEDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHiCEWCxkUUBJDBEBAiCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHiCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMITAKCIJAeDeBJAiCx+YUUBJ2BBJRKSGMAEAKDBBNAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnC+P+e+8/4BDtD9OHdCbDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHiCEWCxkUUBJDBEBAiCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHiCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMITAKCNJAeDeBJAiCx+YUUBJ2BBJRKSFMAEAKDBBBDMITAKCTJRKMGXGXGXGXGXAYCIrCEZfIBFGEBMAECBDtDMIASEMAEAKDBBIAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnHPCGD+MFAPDQBTFtGmEYIPLdKeOnC0+G+MiDtD9OHdCEDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHiCEWCxkUUBJDBEBAiCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHiCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMIAAKCIJAeDeBJAiCx+YUUBJ2BBJRKSGMAEAKDBBNAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnC+P+e+8/4BDtD9OHdCbDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHiCEWCxkUUBJDBEBAiCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHiCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMIAAKCNJAeDeBJAiCx+YUUBJ2BBJRKSFMAEAKDBBBDMIAAKCTJRKMGXGXGXGXGXAYCKrfIBFGEBMAECBDtDMI8wSEMAEAKDBBIAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnHPCGD+MFAPDQBTFtGmEYIPLdKeOnC0+G+MiDtD9OHdCEDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHYCEWCxkUUBJDBEBAYCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHYCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMI8wAKCIJAeDeBJAYCx+YUUBJ2BBJRKSGMAEAKDBBNAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnC+P+e+8/4BDtD9OHdCbDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHYCEWCxkUUBJDBEBAYCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHYCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMI8wAKCNJAeDeBJAYCx+YUUBJ2BBJRKSFMAEAKDBBBDMI8wAKCTJRKMAICoBJREAICUFJAM9LQFAERIAOAKlC/fB9LQBMMGXAEAM9PQBAECErRIEXGXAOAKlCi9PQBCBRKSOMAmAEJRYGXGXGXGXGXATAECKrJ2BBAICKZrCEZfIBFGEBMAYCBDtDMIBSEMAYAKDBBIAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnHPCGD+MFAPDQBTFtGmEYIPLdKeOnC0+G+MiDtD9OHdCEDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHiCEWCxkUUBJDBEBAiCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHiCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMIBAKCIJAeDeBJAiCx+YUUBJ2BBJRKSGMAYAKDBBNAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnC+P+e+8/4BDtD9OHdCbDbD8jHPAPDQBFGENVcMILKOSQfbHeD8dBh+BsxoxoUwN0AeD8dFhxoUwkwk+gUa0sHnhTkAnsHnhNkAnsHn7CgFZHiCEWCxkUUBJDBEBAiCx+YUUBJDBBBHeAeDQBBBBBBBBBBBBBBBBAnhAk7CgFZHiCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMIBAKCNJAeDeBJAiCx+YUUBJ2BBJRKSFMAYAKDBBBDMIBAKCTJRKMAICGJRIAECTJHEAM9JQBMMGXAK9FQBAKRTAtCFJHtCI6QGSFMMCBRKSEMGXAM9FQBALCUGJAbJREALAbJDBGBReCBRYEXAEALCU/CBJAYJHIDBIBHdCFD9tAdCFDbHPD9OD9hD9RHdAIAMJDBIBH8ZCFD9tA8ZAPD9OD9hD9RH8ZDQBTFtGmEYIPLdKeOnHpAIAQJDBIBHyCFD9tAyAPD9OD9hD9RHyAIASJDBIBH8cCFD9tA8cAPD9OD9hD9RH8cDQBTFtGmEYIPLdKeOnH8dDQBFTtGEmYILPdKOenHPAPDQBFGEBFGEBFGEBFGEAeD9uHeDyBjGBAEAGJHIAeAPAPDQILKOILKOILKOILKOD9uHeDyBjGBAIAGJHIAeAPAPDQNVcMNVcMNVcMNVcMD9uHeDyBjGBAIAGJHIAeAPAPDQSQfbSQfbSQfbSQfbD9uHeDyBjGBAIAGJHIAeApA8dDQNVi8ZcMpySQ8c8dfb8e8fHPAPDQBFGEBFGEBFGEBFGED9uHeDyBjGBAIAGJHIAeAPAPDQILKOILKOILKOILKOD9uHeDyBjGBAIAGJHIAeAPAPDQNVcMNVcMNVcMNVcMD9uHeDyBjGBAIAGJHIAeAPAPDQSQfbSQfbSQfbSQfbD9uHeDyBjGBAIAGJHIAeAdA8ZDQNiV8ZcpMyS8cQ8df8eb8fHdAyA8cDQNiV8ZcpMyS8cQ8df8eb8fH8ZDQBFTtGEmYILPdKOenHPAPDQBFGEBFGEBFGEBFGED9uHeDyBjGBAIAGJHIAeAPAPDQILKOILKOILKOILKOD9uHeDyBjGBAIAGJHIAeAPAPDQNVcMNVcMNVcMNVcMD9uHeDyBjGBAIAGJHIAeAPAPDQSQfbSQfbSQfbSQfbD9uHeDyBjGBAIAGJHIAeAdA8ZDQNVi8ZcMpySQ8c8dfb8e8fHPAPDQBFGEBFGEBFGEBFGED9uHeDyBjGBAIAGJHIAeAPAPDQILKOILKOILKOILKOD9uHeDyBjGBAIAGJHIAeAPAPDQNVcMNVcMNVcMNVcMD9uHeDyBjGBAIAGJHIAeAPAPDQSQfbSQfbSQfbSQfbD9uHeDyBjGBAIAGJREAYCTJHYAM9JQBMMAbCIJHbAG9JQBMMABAVAG9sJALCUGJAcAG9s/8cBBALALCUGJAcCaJAG9sJAG/8cBBMAcCBAKyAVJRVAKQBMC9+RKSFMCBC99AOAKlAGCAAGCA9Ly6yRKMALCU/KBJ8kUUUUBAKMNBT+BUUUBM+KmFTa8jUUUUBCoFlHL8kUUUUBC9+RKGXAFCE9uHOCtJAI9LQBCaRKAE2BBHNC/wFZC/gF9HQBANCbZHVCF9LQBALCoBJCgFCUF/8MBALC84Jha83EBALC8wJha83EBALC8oJha83EBALCAJha83EBALCiJha83EBALCTJha83EBALha83ENALha83EBAEAIJC9wJRcAECFJHNAOJRMGXAF9FQBCQCbAVCF6yRSABRECBRVCBRQCBRfCBRICBRKEXGXAMAcuQBC9+RKSEMGXGXAN2BBHOC/vF9LQBALCoBJAOCIrCa9zAKJCbZCEWJHb8oGIRTAb8oGBRtGXAOCbZHbAS9PQBALAOCa9zAIJCbZCGWJ8oGBAVAbyROAb9FRbGXGXAGCG9HQBABAt87FBABCIJAO87FBABCGJAT87FBSFMAEAtjGBAECNJAOjGBAECIJATjGBMAVAbJRVALCoBJAKCEWJHmAOjGBAmATjGIALAICGWJAOjGBALCoBJAKCFJCbZHKCEWJHTAtjGBATAOjGIAIAbJRIAKCFJRKSGMGXGXAbCb6QBAQAbJAbC989zJCFJRQSFMAM1BBHbCgFZROGXGXAbCa9MQBAMCFJRMSFMAM1BFHbCgBZCOWAOCgBZqROGXAbCa9MQBAMCGJRMSFMAM1BGHbCgBZCfWAOqROGXAbCa9MQBAMCEJRMSFMAM1BEHbCgBZCdWAOqROGXAbCa9MQBAMCIJRMSFMAM2BIC8cWAOqROAMCLJRMMAOCFrCBAOCFZl9zAQJRQMGXGXAGCG9HQBABAt87FBABCIJAQ87FBABCGJAT87FBSFMAEAtjGBAECNJAQjGBAECIJATjGBMALCoBJAKCEWJHOAQjGBAOATjGIALAICGWJAQjGBALCoBJAKCFJCbZHKCEWJHOAtjGBAOAQjGIAICFJRIAKCFJRKSFMGXAOCDF9LQBALAIAcAOCbZJ2BBHbCIrHTlCbZCGWJ8oGBAVCFJHtATyROALAIAblCbZCGWJ8oGBAtAT9FHmJHtAbCbZHTyRbAT9FRTGXGXAGCG9HQBABAV87FBABCIJAb87FBABCGJAO87FBSFMAEAVjGBAECNJAbjGBAECIJAOjGBMALAICGWJAVjGBALCoBJAKCEWJHYAOjGBAYAVjGIALAICFJHICbZCGWJAOjGBALCoBJAKCFJCbZCEWJHYAbjGBAYAOjGIALAIAmJCbZHICGWJAbjGBALCoBJAKCGJCbZHKCEWJHOAVjGBAOAbjGIAKCFJRKAIATJRIAtATJRVSFMAVCBAM2BBHYyHTAOC/+F6HPJROAYCbZRtGXGXAYCIrHmQBAOCFJRbSFMAORbALAIAmlCbZCGWJ8oGBROMGXGXAtQBAbCFJRVSFMAbRVALAIAYlCbZCGWJ8oGBRbMGXGXAP9FQBAMCFJRYSFMAM1BFHYCgFZRTGXGXAYCa9MQBAMCGJRYSFMAM1BGHYCgBZCOWATCgBZqRTGXAYCa9MQBAMCEJRYSFMAM1BEHYCgBZCfWATqRTGXAYCa9MQBAMCIJRYSFMAM1BIHYCgBZCdWATqRTGXAYCa9MQBAMCLJRYSFMAMCKJRYAM2BLC8cWATqRTMATCFrCBATCFZl9zAQJHQRTMGXGXAmCb6QBAYRPSFMAY1BBHMCgFZROGXGXAMCa9MQBAYCFJRPSFMAY1BFHMCgBZCOWAOCgBZqROGXAMCa9MQBAYCGJRPSFMAY1BGHMCgBZCfWAOqROGXAMCa9MQBAYCEJRPSFMAY1BEHMCgBZCdWAOqROGXAMCa9MQBAYCIJRPSFMAYCLJRPAY2BIC8cWAOqROMAOCFrCBAOCFZl9zAQJHQROMGXGXAtCb6QBAPRMSFMAP1BBHMCgFZRbGXGXAMCa9MQBAPCFJRMSFMAP1BFHMCgBZCOWAbCgBZqRbGXAMCa9MQBAPCGJRMSFMAP1BGHMCgBZCfWAbqRbGXAMCa9MQBAPCEJRMSFMAP1BEHMCgBZCdWAbqRbGXAMCa9MQBAPCIJRMSFMAPCLJRMAP2BIC8cWAbqRbMAbCFrCBAbCFZl9zAQJHQRbMGXGXAGCG9HQBABAT87FBABCIJAb87FBABCGJAO87FBSFMAEATjGBAECNJAbjGBAECIJAOjGBMALCoBJAKCEWJHYAOjGBAYATjGIALAICGWJATjGBALCoBJAKCFJCbZCEWJHYAbjGBAYAOjGIALAICFJHICbZCGWJAOjGBALCoBJAKCGJCbZCEWJHOATjGBAOAbjGIALAIAm9FAmCb6qJHICbZCGWJAbjGBAIAt9FAtCb6qJRIAKCEJRKMANCFJRNABCKJRBAECSJREAKCbZRKAICbZRIAfCEJHfAF9JQBMMCBC99AMAc6yRKMALCoFJ8kUUUUBAKM/tIFGa8jUUUUBCTlRLC9+RKGXAFCLJAI9LQBCaRKAE2BBC/+FZC/QF9HQBALhB83ENAECFJRKAEAIJC98JREGXAF9FQBGXAGCG6QBEXGXAKAE9JQBC9+bMAK1BBHGCgFZRIGXGXAGCa9MQBAKCFJRKSFMAK1BFHGCgBZCOWAICgBZqRIGXAGCa9MQBAKCGJRKSFMAK1BGHGCgBZCfWAIqRIGXAGCa9MQBAKCEJRKSFMAK1BEHGCgBZCdWAIqRIGXAGCa9MQBAKCIJRKSFMAK2BIC8cWAIqRIAKCLJRKMALCNJAICFZCGWqHGAICGrCBAICFrCFZl9zAG8oGBJHIjGBABAIjGBABCIJRBAFCaJHFQBSGMMEXGXAKAE9JQBC9+bMAK1BBHGCgFZRIGXGXAGCa9MQBAKCFJRKSFMAK1BFHGCgBZCOWAICgBZqRIGXAGCa9MQBAKCGJRKSFMAK1BGHGCgBZCfWAIqRIGXAGCa9MQBAKCEJRKSFMAK1BEHGCgBZCdWAIqRIGXAGCa9MQBAKCIJRKSFMAK2BIC8cWAIqRIAKCLJRKMABAICGrCBAICFrCFZl9zALCNJAICFZCGWqHI8oGBJHG87FBAIAGjGBABCGJRBAFCaJHFQBMMCBC99AKAE6yRKMAKM/dLEK97FaF97GXGXAGCI9HQBAF9FQFCBRGEXABABDBBBHECiD+rFCiD+sFD/6FHIAECND+rFCiD+sFD/6FAID/gFAECTD+rFCiD+sFD/6FHLD/gFD/kFD/lFHKCBDtD+2FHOAICUUUU94DtHND9OD9RD/kFHI9DBB/+hDYAIAID/mFAKAKD/mFALAOALAND9OD9RD/kFHIAID/mFD/kFD/kFD/jFD/nFHLD/mF9DBBX9LDYHOD/kFCgFDtD9OAECUUU94DtD9OD9QAIALD/mFAOD/kFCND+rFCU/+EDtD9OD9QAKALD/mFAOD/kFCTD+rFCUU/8ODtD9OD9QDMBBABCTJRBAGCIJHGAF9JQBSGMMAF9FQBCBRGEXABCTJHVAVDBBBHECBDtHOCUU98D8cFCUU98D8cEHND9OABDBBBHKAEDQILKOSQfbPden8c8d8e8fCggFDtD9OD/6FAKAEDQBFGENVcMTtmYi8ZpyHECTD+sFD/6FHID/gFAECTD+rFCTD+sFD/6FHLD/gFD/kFD/lFHE9DB/+g6DYALAEAOD+2FHOALCUUUU94DtHcD9OD9RD/kFHLALD/mFAEAED/mFAIAOAIAcD9OD9RD/kFHEAED/mFD/kFD/kFD/jFD/nFHID/mF9DBBX9LDYHOD/kFCTD+rFALAID/mFAOD/kFCggEDtD9OD9QHLAEAID/mFAOD/kFCaDbCBDnGCBDnECBDnKCBDnOCBDncCBDnMCBDnfCBDnbD9OHEDQNVi8ZcMpySQ8c8dfb8e8fD9QDMBBABAKAND9OALAEDQBFTtGEmYILPdKOenD9QDMBBABCAJRBAGCIJHGAF9JQBMMM/hEIGaF97FaL978jUUUUBCTlREGXAF9FQBCBRIEXAEABDBBBHLABCTJHKDBBBHODQILKOSQfbPden8c8d8e8fHNCTD+sFHVCID+rFDMIBAB9DBBU8/DY9D/zI818/DYAVCEDtD9QD/6FD/nFHVALAODQBFGENVcMTtmYi8ZpyHLCTD+rFCTD+sFD/6FD/mFHOAOD/mFAVALCTD+sFD/6FD/mFHcAcD/mFAVANCTD+rFCTD+sFD/6FD/mFHNAND/mFD/kFD/kFD/lFCBDtD+4FD/jF9DB/+g6DYHVD/mF9DBBX9LDYHLD/kFCggEDtHMD9OAcAVD/mFALD/kFCTD+rFD9QHcANAVD/mFALD/kFCTD+rFAOAVD/mFALD/kFAMD9OD9QHVDQBFTtGEmYILPdKOenHLD8dBAEDBIBDyB+t+J83EBABCNJALD8dFAEDBIBDyF+t+J83EBAKAcAVDQNVi8ZcMpySQ8c8dfb8e8fHVD8dBAEDBIBDyG+t+J83EBABCiJAVD8dFAEDBIBDyE+t+J83EBABCAJRBAICIJHIAF9JQBMMM9jFF97GXAGCGrAF9sHG9FQBCBRFEXABABDBBBHECND+rFCND+sFD/6FAECiD+sFCnD+rFCUUU/8EDtD+uFD/mFDMBBABCTJRBAFCIJHFAG9JQBMMM9TFEaCBCB8oGUkUUBHFABCEJC98ZJHBjGUkUUBGXGXAB8/BCTWHGuQBCaREABAGlCggEJCTrXBCa6QFMAFREMAEMMMFBCUNMIT9tBB"; + // Built with clang version 14.0.4 + // Built from meshoptimizer 0.18 + var wasm_base = "b9H79Tebbbe8Fv9Gbb9Gvuuuuueu9Giuuub9Geueu9Giuuueuikqbeeedddillviebeoweuec:q;iekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbeY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVbdE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbiL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtblK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbol79IV9Rbrq:P8Yqdbk;3sezu8Jjjjjbcj;eb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Radz1jjjbhwcj;abad9UhoaicefhldnadTmbaoc;WFbGgocjdaocjd6EhDcbhqinaqae9pmeaDaeaq9RaqaDfae6Egkcsfgocl4cifcd4hxdndndndnaoc9WGgmTmbcbhPcehsawcjdfhzalhHinaraH9Rax6midnaraHaxfgl9RcK6mbczhoinawcj;cbfaogifgoc9WfhOdndndndndnaHaic9WfgAco4fRbbaAci4coG4ciGPlbedibkaO9cb83ibaOcwf9cb83ibxikaOalRblalRbbgAco4gCaCciSgCE86bbaocGfalclfaCfgORbbaAcl4ciGgCaCciSgCE86bbaocVfaOaCfgORbbaAcd4ciGgCaCciSgCE86bbaoc7faOaCfgORbbaAciGgAaAciSgAE86bbaoctfaOaAfgARbbalRbegOco4gCaCciSgCE86bbaoc91faAaCfgARbbaOcl4ciGgCaCciSgCE86bbaoc4faAaCfgARbbaOcd4ciGgCaCciSgCE86bbaoc93faAaCfgARbbaOciGgOaOciSgOE86bbaoc94faAaOfgARbbalRbdgOco4gCaCciSgCE86bbaoc95faAaCfgARbbaOcl4ciGgCaCciSgCE86bbaoc96faAaCfgARbbaOcd4ciGgCaCciSgCE86bbaoc97faAaCfgARbbaOciGgOaOciSgOE86bbaoc98faAaOfgORbbalRbiglco4gAaAciSgAE86bbaoc99faOaAfgORbbalcl4ciGgAaAciSgAE86bbaoc9:faOaAfgORbbalcd4ciGgAaAciSgAE86bbaocufaOaAfgoRbbalciGglalciSglE86bbaoalfhlxdkaOalRbwalRbbgAcl4gCaCcsSgCE86bbaocGfalcwfaCfgORbbaAcsGgAaAcsSgAE86bbaocVfaOaAfgORbbalRbegAcl4gCaCcsSgCE86bbaoc7faOaCfgORbbaAcsGgAaAcsSgAE86bbaoctfaOaAfgORbbalRbdgAcl4gCaCcsSgCE86bbaoc91faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc4faOaAfgORbbalRbigAcl4gCaCcsSgCE86bbaoc93faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc94faOaAfgORbbalRblgAcl4gCaCcsSgCE86bbaoc95faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc96faOaAfgORbbalRbvgAcl4gCaCcsSgCE86bbaoc97faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc98faOaAfgORbbalRbogAcl4gCaCcsSgCE86bbaoc99faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc9:faOaAfgORbbalRbrglcl4gAaAcsSgAE86bbaocufaOaAfgoRbbalcsGglalcsSglE86bbaoalfhlxekaOal8Pbb83bbaOcwfalcwf8Pbb83bbalczfhlkdnaiam9pmbaiczfhoaral9RcL0mekkaiam6mialTmidnakTmbawaPfRbbhOcbhoazhiinaiawcj;cbfaofRbbgAce4cbaAceG9R7aOfgO86bbaiadfhiaocefgoak9hmbkkazcefhzaPcefgPad6hsalhHaPad9hmexvkkcbhlasceGmdxikalaxad2fhCdnakTmbcbhHcehsawcjdfhminaral9Rax6mialTmdalaxfhlawaHfRbbhOcbhoamhiinaiawcj;cbfaofRbbgAce4cbaAceG9R7aOfgO86bbaiadfhiaocefgoak9hmbkamcefhmaHcefgHad6hsaHad9hmbkaChlxikcbhocehsinaral9Rax6mdalTmealaxfhlaocefgoad6hsadao9hmbkaChlxdkcbhlasceGTmekc9:hoxikabaqad2fawcjdfakad2z1jjjb8Aawawcjdfakcufad2fadz1jjjb8Aakaqfhqalmbkc9:hoxekcbc99aral9Radcaadca0ESEhokavcj;ebf8Kjjjjbaok;yzeHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgDce0mbavc;abfcFecjez:jjjjb8AavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhqaicefgwarfhodnaeTmbcmcsaDceSEhkcbhxcbhmcbhDcbhicbhlindnaoaq9nmbc9:hoxikdndnawRbbgrc;Ve0mbavc;abfalarcl4cu7fcsGcitfgPydlhsaPydbhzdnarcsGgPak9pmbavaiarcu7fcsGcdtfydbaxaPEhraPThPdndnadcd9hmbabaDcetfgHaz87ebaHcdfas87ebaHclfar87ebxekabaDcdtfgHazBdbaHclfasBdbaHcwfarBdbkaxaPfhxavc;abfalcitfgHarBdbaHasBdlavaicdtfarBdbavc;abfalcefcsGglcitfgHazBdbaHarBdlaiaPfhialcefhlxdkdndnaPcsSmbamaPfaPc987fcefhmxekaocefhrao8SbbgPcFeGhHdndnaPcu9mmbarhoxekaocvfhoaHcFbGhHcrhPdninar8SbbgOcFbGaPtaHVhHaOcu9kmearcefhraPcrfgPc8J9hmbxdkkarcefhokaHce4cbaHceG9R7amfhmkdndnadcd9hmbabaDcetfgraz87ebarcdfas87ebarclfam87ebxekabaDcdtfgrazBdbarclfasBdbarcwfamBdbkavc;abfalcitfgramBdbarasBdlavaicdtfamBdbavc;abfalcefcsGglcitfgrazBdbaramBdlaicefhialcefhlxekdnarcpe0mbaxcefgOavaiaqarcsGfRbbgPcl49RcsGcdtfydbaPcz6gHEhravaiaP9RcsGcdtfydbaOaHfgsaPcsGgOEhPaOThOdndnadcd9hmbabaDcetfgzax87ebazcdfar87ebazclfaP87ebxekabaDcdtfgzaxBdbazclfarBdbazcwfaPBdbkavaicdtfaxBdbavc;abfalcitfgzarBdbazaxBdlavaicefgicsGcdtfarBdbavc;abfalcefcsGcitfgzaPBdbazarBdlavaiaHfcsGgicdtfaPBdbavc;abfalcdfcsGglcitfgraxBdbaraPBdlalcefhlaiaOfhiasaOfhxxekaxcbaoRbbgzEgAarc;:eSgrfhsazcsGhCazcl4hXdndnazcs0mbascefhOxekashOavaiaX9RcsGcdtfydbhskdndnaCmbaOcefhxxekaOhxavaiaz9RcsGcdtfydbhOkdndnarTmbaocefhrxekaocdfhrao8SbegHcFeGhPdnaHcu9kmbaocofhAaPcFbGhPcrhodninar8SbbgHcFbGaotaPVhPaHcu9kmearcefhraocrfgoc8J9hmbkaAhrxekarcefhrkaPce4cbaPceG9R7amfgmhAkdndnaXcsSmbarhPxekarcefhPar8SbbgocFeGhHdnaocu9kmbarcvfhsaHcFbGhHcrhodninaP8SbbgrcFbGaotaHVhHarcu9kmeaPcefhPaocrfgoc8J9hmbkashPxekaPcefhPkaHce4cbaHceG9R7amfgmhskdndnaCcsSmbaPhoxekaPcefhoaP8SbbgrcFeGhHdnarcu9kmbaPcvfhOaHcFbGhHcrhrdninao8SbbgPcFbGartaHVhHaPcu9kmeaocefhoarcrfgrc8J9hmbkaOhoxekaocefhokaHce4cbaHceG9R7amfgmhOkdndnadcd9hmbabaDcetfgraA87ebarcdfas87ebarclfaO87ebxekabaDcdtfgraABdbarclfasBdbarcwfaOBdbkavc;abfalcitfgrasBdbaraABdlavaicdtfaABdbavc;abfalcefcsGcitfgraOBdbarasBdlavaicefgicsGcdtfasBdbavc;abfalcdfcsGcitfgraABdbaraOBdlavaiazcz6aXcsSVfgicsGcdtfaOBdbaiaCTaCcsSVfhialcifhlkawcefhwalcsGhlaicsGhiaDcifgDae6mbkkcbc99aoaqSEhokavc;aef8Kjjjjbaok:llevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaicd4cbaice4ceG9R7avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaicd4cbaice4ceG9R7avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:Lvoeue99dud99eud99dndnadcl9hmbaeTmeindndnabcdfgd8Sbb:Yab8Sbbgi:Ygl:l:tabcefgv8Sbbgo:Ygr:l:tgwJbb;:9cawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai86bbdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad86bbdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad86bbabclfhbaecufgembxdkkaeTmbindndnabclfgd8Ueb:Yab8Uebgi:Ygl:l:tabcdfgv8Uebgo:Ygr:l:tgwJb;:FSawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai87ebdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad87ebdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad87ebabcwfhbaecufgembkkk;siliui99iue99dnaeTmbcbhiabhlindndnJ;Zl81Zalcof8UebgvciV:Y:vgoal8Ueb:YNgrJb;:FSNJbbbZJbbb:;arJbbbb9GEMgw:lJbbb9p9DTmbaw:OhDxekcjjjj94hDkalclf8Uebhqalcdf8UebhkabavcefciGaiVcetfaD87ebdndnaoak:YNgwJb;:FSNJbbbZJbbb:;awJbbbb9GEMgx:lJbbb9p9DTmbax:Ohkxekcjjjj94hkkabavcdfciGaiVcetfak87ebdndnaoaq:YNgoJb;:FSNJbbbZJbbb:;aoJbbbb9GEMgx:lJbbb9p9DTmbax:Ohqxekcjjjj94hqkabavcufciGaiVcetfaq87ebdndnJbbjZararN:tawawN:taoaoN:tgrJbbbbarJbbbb9GE:rJb;:FSNJbbbZMgr:lJbbb9p9DTmbar:Ohqxekcjjjj94hqkabavciGaiVcetfaq87ebalcwfhlaiclfhiaecufgembkkk9mbdnadcd4ae2geTmbinababydbgdcwtcw91:Yadce91cjjj;8ifcjjj98G::NUdbabclfhbaecufgembkkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaiczfhiaeczfheadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabkkkebcjwklz9Kbb"; + var wasm_simd = "b9H79TebbbeKl9Gbb9Gvuuuuueu9Giuuub9Geueuikqbbebeedddilve9Weeeviebeoweuec:q;Aekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbdY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVblE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtboK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbrL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbwl79IV9RbDq;t9tqlbzik9:evu8Jjjjjbcz9Rhbcbheincbhdcbhiinabcwfadfaicjuaead4ceGglE86bbaialfhiadcefgdcw9hmbkaec:q:yjjbfai86bbaecitc:q1jjbfab8Piw83ibaecefgecjd9hmbkk;h8JlHud97euo978Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Rad;8qbbcj;abad9UhoaicefhldnadTmbaoc;WFbGgocjdaocjd6EhwcbhDinaDae9pmeawaeaD9RaDawfae6Egqcsfgoc9WGgkci2hxakcethmaocl4cifcd4hPabaDad2fhscbhzdnincehHalhOcbhAdninaraO9RaP6miavcj;cbfaAak2fhCaOaPfhlcbhidnakc;ab6mbaral9Rc;Gb6mbcbhoinaCaofhidndndndndnaOaoco4fRbbgXciGPlbedibkaipxbbbbbbbbbbbbbbbbpklbxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaialpbbbpklbalczfhlkdndndndndnaXcd4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklzxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaialpbbbpklzalczfhlkdndndndndnaXcl4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklaxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaialpbbbpklaalczfhlkdndndndndnaXco4Plbedibkaipxbbbbbbbbbbbbbbbbpkl8WxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WalclfaYpQbfaXc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WalcwfaYpQbfaXc:q:yjjbfRbbfhlxekaialpbbbpkl8Walczfhlkaoc;abfhiaocjefak0meaihoaral9Rc;Fb0mbkkdndnaiak9pmbaici4hoinaral9RcK6mdaCaifhXdndndndndnaOaico4fRbbaocoG4ciGPlbedibkaXpxbbbbbbbbbbbbbbbbpklbxikaXalpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaXalpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaXalpbbbpklbalczfhlkaocdfhoaiczfgiak6mbkkalTmbaAci6hHalhOaAcefgohAaoclSmdxekkcbhlaHceGmdkdnakTmbavcjdfazfhiavazfpbdbhYcbhXinaiavcj;cbfaXfgopblbgLcep9TaLpxeeeeeeeeeeeeeeeegQp9op9Hp9rgLaoakfpblbg8Acep9Ta8AaQp9op9Hp9rg8ApmbzeHdOiAlCvXoQrLgEaoamfpblbg3cep9Ta3aQp9op9Hp9rg3aoaxfpblbg5cep9Ta5aQp9op9Hp9rg5pmbzeHdOiAlCvXoQrLg8EpmbezHdiOAlvCXorQLgQaQpmbedibedibedibediaYp9UgYp9AdbbaiadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfgoaYaEa8EpmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaoadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfgoaYaLa8ApmwKDYq8AkEx3m5P8Es8FgLa3a5pmwKDYq8AkEx3m5P8Es8Fg8ApmbezHdiOAlvCXorQLgQaQpmbedibedibedibedip9UgYp9AdbbaoadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfgoaYaLa8ApmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaoadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfhiaXczfgXak6mbkkazclfgzad6mbkasavcjdfaqad2;8qbbavavcjdfaqcufad2fad;8qbbaqaDfhDc9:hoalmexikkc9:hoxekcbc99aral9Radcaadca0ESEhokavcj;kbf8Kjjjjbaokwbz:bjjjbk;uzeHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgDce0mbavc;abfcFecje;8kbavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhqaicefgwarfhodnaeTmbcmcsaDceSEhkcbhxcbhmcbhDcbhicbhlindnaoaq9nmbc9:hoxikdndnawRbbgrc;Ve0mbavc;abfalarcl4cu7fcsGcitfgPydlhsaPydbhzdnarcsGgPak9pmbavaiarcu7fcsGcdtfydbaxaPEhraPThPdndnadcd9hmbabaDcetfgHaz87ebaHcdfas87ebaHclfar87ebxekabaDcdtfgHazBdbaHclfasBdbaHcwfarBdbkaxaPfhxavc;abfalcitfgHarBdbaHasBdlavaicdtfarBdbavc;abfalcefcsGglcitfgHazBdbaHarBdlaiaPfhialcefhlxdkdndnaPcsSmbamaPfaPc987fcefhmxekaocefhrao8SbbgPcFeGhHdndnaPcu9mmbarhoxekaocvfhoaHcFbGhHcrhPdninar8SbbgOcFbGaPtaHVhHaOcu9kmearcefhraPcrfgPc8J9hmbxdkkarcefhokaHce4cbaHceG9R7amfhmkdndnadcd9hmbabaDcetfgraz87ebarcdfas87ebarclfam87ebxekabaDcdtfgrazBdbarclfasBdbarcwfamBdbkavc;abfalcitfgramBdbarasBdlavaicdtfamBdbavc;abfalcefcsGglcitfgrazBdbaramBdlaicefhialcefhlxekdnarcpe0mbaxcefgOavaiaqarcsGfRbbgPcl49RcsGcdtfydbaPcz6gHEhravaiaP9RcsGcdtfydbaOaHfgsaPcsGgOEhPaOThOdndnadcd9hmbabaDcetfgzax87ebazcdfar87ebazclfaP87ebxekabaDcdtfgzaxBdbazclfarBdbazcwfaPBdbkavaicdtfaxBdbavc;abfalcitfgzarBdbazaxBdlavaicefgicsGcdtfarBdbavc;abfalcefcsGcitfgzaPBdbazarBdlavaiaHfcsGgicdtfaPBdbavc;abfalcdfcsGglcitfgraxBdbaraPBdlalcefhlaiaOfhiasaOfhxxekaxcbaoRbbgzEgAarc;:eSgrfhsazcsGhCazcl4hXdndnazcs0mbascefhOxekashOavaiaX9RcsGcdtfydbhskdndnaCmbaOcefhxxekaOhxavaiaz9RcsGcdtfydbhOkdndnarTmbaocefhrxekaocdfhrao8SbegHcFeGhPdnaHcu9kmbaocofhAaPcFbGhPcrhodninar8SbbgHcFbGaotaPVhPaHcu9kmearcefhraocrfgoc8J9hmbkaAhrxekarcefhrkaPce4cbaPceG9R7amfgmhAkdndnaXcsSmbarhPxekarcefhPar8SbbgocFeGhHdnaocu9kmbarcvfhsaHcFbGhHcrhodninaP8SbbgrcFbGaotaHVhHarcu9kmeaPcefhPaocrfgoc8J9hmbkashPxekaPcefhPkaHce4cbaHceG9R7amfgmhskdndnaCcsSmbaPhoxekaPcefhoaP8SbbgrcFeGhHdnarcu9kmbaPcvfhOaHcFbGhHcrhrdninao8SbbgPcFbGartaHVhHaPcu9kmeaocefhoarcrfgrc8J9hmbkaOhoxekaocefhokaHce4cbaHceG9R7amfgmhOkdndnadcd9hmbabaDcetfgraA87ebarcdfas87ebarclfaO87ebxekabaDcdtfgraABdbarclfasBdbarcwfaOBdbkavc;abfalcitfgrasBdbaraABdlavaicdtfaABdbavc;abfalcefcsGcitfgraOBdbarasBdlavaicefgicsGcdtfasBdbavc;abfalcdfcsGcitfgraABdbaraOBdlavaiazcz6aXcsSVfgicsGcdtfaOBdbaiaCTaCcsSVfhialcifhlkawcefhwalcsGhlaicsGhiaDcifgDae6mbkkcbc99aoaqSEhokavc;aef8Kjjjjbaok:llevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaicd4cbaice4ceG9R7avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaicd4cbaice4ceG9R7avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:EPliuo97eue978Jjjjjbca9Rhidndnadcl9hmbdnaec98GglTmbcbhvabhdinadadpbbbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpkbbadczfhdavclfgval6mbkkalae9pmeaiaeciGgvcdtgdVcbczad9R;8kbaiabalcdtfglad;8qbbdnavTmbaiaipblbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpklbkalaiad;8qbbskdnaec98GgxTmbcbhvabhdinadczfglalpbbbgopxbbbbbbFFbbbbbbFFgkp9oadpbbbgDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eaDaopmbediwDqkzHOAKY8AEgoczp:Sep;6egrp;Geaoczp:Reczp:Sep;6egwp;Gep;Kep;Legopxb;:FSb;:FSb;:FSb;:FSawaopxbbbbbbbbbbbbbbbbp:2egqawpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegwawp;Meaoaop;Mearaqaramp9op9rp;Kegoaop;Mep;Kep;Kep;Jep;Negrp;Mepxbbn0bbn0bbn0bbn0gqp;Keczp:Reawarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9op9qgwaoarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogopmwDKYqk8AExm35Ps8E8Fp9qpkbbadaDakp9oawaopmbezHdiOAlvCXorQLp9qpkbbadcafhdavclfgvax6mbkkaxae9pmbaiaeciGgvcitgdfcbcaad9R;8kbaiabaxcitfglad;8qbbdnavTmbaiaipblzgopxbbbbbbFFbbbbbbFFgkp9oaipblbgDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eaDaopmbediwDqkzHOAKY8AEgoczp:Sep;6egrp;Geaoczp:Reczp:Sep;6egwp;Gep;Kep;Legopxb;:FSb;:FSb;:FSb;:FSawaopxbbbbbbbbbbbbbbbbp:2egqawpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegwawp;Meaoaop;Mearaqaramp9op9rp;Kegoaop;Mep;Kep;Kep;Jep;Negrp;Mepxbbn0bbn0bbn0bbn0gqp;Keczp:Reawarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9op9qgwaoarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogopmwDKYqk8AExm35Ps8E8Fp9qpklzaiaDakp9oawaopmbezHdiOAlvCXorQLp9qpklbkalaiad;8qbbkk;4wllue97euv978Jjjjjbc8W9Rhidnaec98GglTmbcbhvabhoinaiaopbbbgraoczfgwpbbbgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklbaopxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaqakp;Mearp;Keczp:ReaDakp;Mearp;Keamp9op9qgkpmbezHdiOAlvCXorQLgrp5baipblbpEb:T:j83ibaocwfarp5eaipblbpEe:T:j83ibawaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblbpEd:T:j83ibaocKfakp5eaipblbpEi:T:j83ibaocafhoavclfgval6mbkkdnalae9pmbaiaeciGgvcitgofcbcaao9R;8kbaiabalcitfgwao;8qbbdnavTmbaiaipblbgraipblzgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklaaipxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaqakp;Mearp;Keczp:ReaDakp;Mearp;Keamp9op9qgkpmbezHdiOAlvCXorQLgrp5baipblapEb:T:j83ibaiarp5eaipblapEe:T:j83iwaiaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblapEd:T:j83izaiakp5eaipblapEi:T:j83iKkawaiao;8qbbkk:Pddiue978Jjjjjbc;ab9Rhidnadcd4ae2glc98GgvTmbcbhdabheinaeaepbbbgocwp:Recwp:Sep;6eaocep:SepxbbjZbbjZbbjZbbjZp:UepxbbjFbbjFbbjFbbjFp9op;Mepkbbaeczfheadclfgdav6mbkkdnaval9pmbaialciGgdcdtgeVcbc;abae9R;8kbaiabavcdtfgvae;8qbbdnadTmbaiaipblbgocwp:Recwp:Sep;6eaocep:SepxbbjZbbjZbbjZbbjZp:UepxbbjFbbjFbbjFbbjFp9op;Mepklbkavaiae;8qbbkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaikkkebcjwklz9Tbb"; - // Uses bulk-memory and simd extensions var detector = new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,3,2,0,0,5,3,1,0,1,12,1,0,10,22,2,12,0,65,0,65,0,65,0,252,10,0,0,11,7,0,65,0,253,15,26,11]); - - // Used to unpack wasm - var wasmpack = new Uint8Array([32,0,65,253,3,1,2,34,4,106,6,5,11,8,7,20,13,33,12,16,128,9,116,64,19,113,127,15,10,21,22,14,255,66,24,54,136,107,18,23,192,26,114,118,132,17,77,101,130,144,27,87,131,44,45,74,156,154,70,167]); + var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); if (typeof WebAssembly !== 'object') { - // This module requires WebAssembly to function return { supported: false, }; } - var wasm = wasm_base; - - if (WebAssembly.validate(detector)) { - wasm = wasm_simd; - console.log("Warning: meshopt_decoder is using experimental SIMD support"); - } + var wasm = WebAssembly.validate(detector) ? wasm_simd : wasm_base; var instance; - var promise = + var ready = WebAssembly.instantiate(unpack(wasm), {}) .then(function(result) { instance = result.instance; @@ -41,7 +32,7 @@ var MeshoptDecoder = (function() { var result = new Uint8Array(data.length); for (var i = 0; i < data.length; ++i) { var ch = data.charCodeAt(i); - result[i] = ch > 96 ? ch - 71 : ch > 64 ? ch - 65 : ch > 47 ? ch + 4 : ch > 46 ? 63 : 62; + result[i] = ch > 96 ? ch - 97 : ch > 64 ? ch - 39 : ch + 4; } var write = 0; for (var i = 0; i < data.length; ++i) { @@ -52,7 +43,7 @@ var MeshoptDecoder = (function() { function decode(fun, target, count, size, source, filter) { var sbrk = instance.exports.sbrk; - var count4 = (count + 3) & ~3; // pad for SIMD filter + var count4 = (count + 3) & ~3; var tp = sbrk(count4 * size); var sp = sbrk(source.length); var heap = new Uint8Array(instance.exports.memory.buffer); @@ -66,15 +57,9 @@ var MeshoptDecoder = (function() { if (res != 0) { throw new Error("Malformed buffer data: " + res); } - }; + } var filters = { - // legacy index-based enums for glTF - 0: "", - 1: "meshopt_decodeFilterOct", - 2: "meshopt_decodeFilterQuat", - 3: "meshopt_decodeFilterExp", - // string-based enums for glTF NONE: "", OCTAHEDRAL: "meshopt_decodeFilterOct", QUATERNION: "meshopt_decodeFilterQuat", @@ -82,19 +67,88 @@ var MeshoptDecoder = (function() { }; var decoders = { - // legacy index-based enums for glTF - 0: "meshopt_decodeVertexBuffer", - 1: "meshopt_decodeIndexBuffer", - 2: "meshopt_decodeIndexSequence", - // string-based enums for glTF ATTRIBUTES: "meshopt_decodeVertexBuffer", TRIANGLES: "meshopt_decodeIndexBuffer", INDICES: "meshopt_decodeIndexSequence", }; + var workers = []; + var requestId = 0; + + function createWorker(url) { + var worker = { + object: new Worker(url), + pending: 0, + requests: {} + }; + + worker.object.onmessage = function(event) { + var data = event.data; + + worker.pending -= data.count; + worker.requests[data.id][data.action](data.value); + + delete worker.requests[data.id]; + }; + + return worker; + } + + function initWorkers(count) { + var source = + "var instance; var ready = WebAssembly.instantiate(new Uint8Array([" + new Uint8Array(unpack(wasm)) + "]), {})" + + ".then(function(result) { instance = result.instance; instance.exports.__wasm_call_ctors(); });" + + "self.onmessage = workerProcess;" + + decode.toString() + workerProcess.toString(); + + var blob = new Blob([source], {type: 'text/javascript'}); + var url = URL.createObjectURL(blob); + + for (var i = 0; i < count; ++i) { + workers[i] = createWorker(url); + } + + URL.revokeObjectURL(url); + } + + function decodeWorker(count, size, source, mode, filter) { + var worker = workers[0]; + + for (var i = 1; i < workers.length; ++i) { + if (workers[i].pending < worker.pending) { + worker = workers[i]; + } + } + + return new Promise(function (resolve, reject) { + var data = new Uint8Array(source); + var id = requestId++; + + worker.pending += count; + worker.requests[id] = { resolve: resolve, reject: reject }; + worker.object.postMessage({ id: id, count: count, size: size, source: data, mode: mode, filter: filter }, [ data.buffer ]); + }); + } + + function workerProcess(event) { + ready.then(function() { + var data = event.data; + try { + var target = new Uint8Array(data.count * data.size); + decode(instance.exports[data.mode], target, data.count, data.size, data.source, instance.exports[data.filter]); + self.postMessage({ id: data.id, count: data.count, action: "resolve", value: target }, [ target.buffer ]); + } catch (error) { + self.postMessage({ id: data.id, count: data.count, action: "reject", value: error }); + } + }); + } + return { - ready: promise, + ready: ready, supported: true, + useWorkers: function(count) { + initWorkers(count); + }, decodeVertexBuffer: function(target, count, size, source, filter) { decode(instance.exports.meshopt_decodeVertexBuffer, target, count, size, source, instance.exports[filters[filter]]); }, @@ -106,6 +160,17 @@ var MeshoptDecoder = (function() { }, decodeGltfBuffer: function(target, count, size, source, mode, filter) { decode(instance.exports[decoders[mode]], target, count, size, source, instance.exports[filters[filter]]); + }, + decodeGltfBufferAsync: function(count, size, source, mode, filter) { + if (workers.length > 0) { + return decodeWorker(count, size, source, decoders[mode], filters[filter]); + } + + return ready.then(function() { + var target = new Uint8Array(count * size); + decode(instance.exports[decoders[mode]], target, count, size, source, instance.exports[filters[filter]]); + return target; + }); } }; })(); diff --git a/examples/jsm/libs/utif.module.js b/examples/jsm/libs/utif.module.js new file mode 100644 index 00000000000000..7050714f950d23 --- /dev/null +++ b/examples/jsm/libs/utif.module.js @@ -0,0 +1,1579 @@ +;(function(){ + var UTIF = {}; + + // Make available for import by `require()` + if (typeof module == "object") {module.exports = UTIF;} + else {self.UTIF = UTIF;} + + var pako = (typeof require === "function") ? require("pako") : self.pako; + + function log() { if (typeof process=="undefined" || process.env.NODE_ENV=="development") console.log.apply(console, arguments); } + + (function(UTIF, pako){ + + // Following lines add a JPEG decoder to UTIF.JpegDecoder + (function(){"use strict";var W=function a1(){function W(p){this.message="JPEG error: "+p}W.prototype=new Error;W.prototype.name="JpegError";W.constructor=W;return W}(),ak=function ag(){var p=new Uint8Array([0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63]),t=4017,ac=799,ah=3406,ao=2276,ar=1567,ai=3784,s=5793,ad=2896;function ak(Q){if(Q==null)Q={};if(Q.w==null)Q.w=-1;this.V=Q.n;this.N=Q.w}function a5(Q,h){var f=0,G=[],n,E,a=16,F;while(a>0&&!Q[a-1]){a--}G.push({children:[],index:0});var C=G[0];for(n=0;n0){C=G.pop()}C.index++;G.push(C);while(G.length<=n){G.push(F={children:[],index:0});C.children[C.index]=F.children;C=F}f++}if(n+10){V--;return J>>V&1}J=Q[h++];if(J===255){var I=Q[h++];if(I){if(I===220&&d){h+=2;var l=Z(Q,h);h+=2;if(l>0&&l!==f.s){throw new DNLMarkerError("Found DNL marker (0xFFDC) while parsing scan data",l)}}else if(I===217){if(d){var M=q*8; + if(M>0&&M>>7}function u(I){var l=I;while(!0){l=l[Y()];switch(typeof l){case"number":return l;case"object":continue}throw new W("invalid huffman sequence")}}function m(I){var e=0;while(I>0){e=e<<1|Y();I--}return e}function j(I){if(I===1){return Y()===1?1:-1}var e=m(I);if(e>=1<>4;if(i===0){if(A<15){break}N+=16;continue}N+=A;var o=p[N];X.D[I+o]=j(i);N++}}function $(X,I){var l=u(X.J),M=l===0?0:j(l)<0){r--;return}var N=E,l=a;while(N<=l){var M=u(X.i),S=M&15,i=M>>4;if(S===0){if(i<15){r=m(i)+(1<>4;if(S===0){if(M<15){r=m(M)+(1<0){for(O=0;O0?"unexpected":"excessive";h=k.offset}if(k.M>=65488&&k.M<=65495){h+=2}else{break}}return h-z}function al(Q,h,f){var G=Q.$,n=Q.D,E,a,C,F,d,T,U,z,J,V,Y,u,m,j,v,$,b;if(!G){throw new W("missing required Quantization Table.")}for(var r=0;r<64;r+=8){J=n[h+r];V=n[h+r+1];Y=n[h+r+2];u=n[h+r+3];m=n[h+r+4];j=n[h+r+5];v=n[h+r+6];$=n[h+r+7];J*=G[r];if((V|Y|u|m|j|v|$)===0){b=s*J+512>>10;f[r]=b;f[r+1]=b;f[r+2]=b;f[r+3]=b;f[r+4]=b;f[r+5]=b;f[r+6]=b;f[r+7]=b;continue}V*=G[r+1];Y*=G[r+2];u*=G[r+3];m*=G[r+4];j*=G[r+5];v*=G[r+6];$*=G[r+7];E=s*J+128>>8;a=s*m+128>>8;C=Y;F=v;d=ad*(V-$)+128>>8;z=ad*(V+$)+128>>8; + T=u<<4;U=j<<4;E=E+a+1>>1;a=E-a;b=C*ai+F*ar+128>>8;C=C*ar-F*ai+128>>8;F=b;d=d+U+1>>1;U=d-U;z=z+T+1>>1;T=z-T;E=E+F+1>>1;F=E-F;a=a+C+1>>1;C=a-C;b=d*ao+z*ah+2048>>12;d=d*ah-z*ao+2048>>12;z=b;b=T*ac+U*t+2048>>12;T=T*t-U*ac+2048>>12;U=b;f[r]=E+z;f[r+7]=E-z;f[r+1]=a+U;f[r+6]=a-U;f[r+2]=C+T;f[r+5]=C-T;f[r+3]=F+d;f[r+4]=F-d}for(var P=0;P<8;++P){J=f[P];V=f[P+8];Y=f[P+16];u=f[P+24];m=f[P+32];j=f[P+40];v=f[P+48];$=f[P+56];if((V|Y|u|m|j|v|$)===0){b=s*J+8192>>14;if(b<-2040){b=0}else if(b>=2024){b=255}else{b=b+2056>>4}n[h+P]=b;n[h+P+8]=b;n[h+P+16]=b;n[h+P+24]=b;n[h+P+32]=b;n[h+P+40]=b;n[h+P+48]=b;n[h+P+56]=b;continue}E=s*J+2048>>12;a=s*m+2048>>12;C=Y;F=v;d=ad*(V-$)+2048>>12;z=ad*(V+$)+2048>>12;T=u;U=j;E=(E+a+1>>1)+4112;a=E-a;b=C*ai+F*ar+2048>>12;C=C*ar-F*ai+2048>>12;F=b;d=d+U+1>>1;U=d-U;z=z+T+1>>1;T=z-T;E=E+F+1>>1;F=E-F;a=a+C+1>>1;C=a-C;b=d*ao+z*ah+2048>>12;d=d*ah-z*ao+2048>>12;z=b; + b=T*ac+U*t+2048>>12;T=T*t-U*ac+2048>>12;U=b;J=E+z;$=E-z;V=a+U;v=a-U;Y=C+T;j=C-T;u=F+d;m=F-d;if(J<16){J=0}else if(J>=4080){J=255}else{J>>=4}if(V<16){V=0}else if(V>=4080){V=255}else{V>>=4}if(Y<16){Y=0}else if(Y>=4080){Y=255}else{Y>>=4}if(u<16){u=0}else if(u>=4080){u=255}else{u>>=4}if(m<16){m=0}else if(m>=4080){m=255}else{m>>=4}if(j<16){j=0}else if(j>=4080){j=255}else{j>>=4}if(v<16){v=0}else if(v>=4080){v=255}else{v>>=4}if($<16){$=0}else if($>=4080){$=255}else{$>>=4}n[h+P]=J; + n[h+P+8]=V;n[h+P+16]=Y;n[h+P+24]=u;n[h+P+32]=m;n[h+P+40]=j;n[h+P+48]=v;n[h+P+56]=$}}function a0(Q,h){var f=h.P,G=h.c,n=new Int16Array(64);for(var E=0;E=G){return null}var E=Z(Q,h);if(E>=65472&&E<=65534){return{u:null,M:E,offset:h}}var a=Z(Q,n);while(!(a>=65472&&a<=65534)){if(++n>=G){return null}a=Z(Q,n)}return{u:E.toString(16),M:a,offset:n}}ak.prototype={parse(Q,h){if(h==null)h={}; + var f=h.F,E=0,a=null,C=null,F,d,T=0;function G(){var o=Z(Q,E);E+=2;var B=E+o-2,V=an(Q,B,E);if(V&&V.u){B=V.offset}var ab=Q.subarray(E,B);E+=ab.length;return ab}function n(F){var o=Math.ceil(F.o/8/F.X),B=Math.ceil(F.s/8/F.B);for(var Y=0;Y>4===0){for(u=0;u<64;u++){b=p[u];P[b]=Q[E++]}}else if(r>>4===1){for(u=0;u<64;u++){b=p[u];P[b]=Z(Q,E);E+=2}}else{throw new W("DQT - invalid table spec")}U[r&15]=P}break;case 65472:case 65473:case 65474:if(F){throw new W("Only single frame JPEGs supported")}E+=2;F={};F.G=V===65473;F.Z=V===65474;F.precision=Q[E++];var D=Z(Q,E),a4,q=0,H=0;E+=2;F.s=f||D;F.o=Z(Q,E);E+=2;F.W=[];F._={};var a8=Q[E++];for(Y=0;Y>4,y=Q[E+1]&15;if(q>4===0?J:z)[_&15]=a5(N,K)}break;case 65501:E+=2;d=Z(Q,E);E+=2;break;case 65498:var x=++T===1&&!f,R;E+=2;var k=Q[E++],g=[];for(Y=0;Y>4];R.i=z[a6&15];g.push(R)}var I=Q[E++],l=Q[E++],M=Q[E++];try{var S=a7(Q,E,F,g,d,I,l,M>>4,M&15,x);E+=S}catch(ex){if(ex instanceof DNLMarkerError){return this.parse(Q,{F:ex.s})}else if(ex instanceof EOIMarkerError){break markerLoop}throw ex}break;case 65500:E+=4;break;case 65535:if(Q[E]!==255){E--}break;default:var i=an(Q,E-2,E-3);if(i&&i.u){E=i.offset;break}if(E>=Q.length-1){break markerLoop}throw new W("JpegImage.parse - unknown marker: "+V.toString(16))}V=Z(Q,E);E+=2}this.width=F.o;this.height=F.s;this.g=a;this.b=C;this.W=[];for(Y=0;Y>8)+P[J+1]}}}return v},get f(){if(this.b){return!!this.b.a}if(this.p===3){if(this.N===0){return!1}else if(this.W[0].index===82&&this.W[1].index===71&&this.W[2].index===66){return!1}return!0}if(this.N===1){return!0}return!1},z:function aj(Q){var h,f,G; + for(var n=0,E=Q.length;n4){throw new W("Unsupported color mode")}var E=this.Y(h,f,n);if(this.p===1&&G){var a=E.length,C=new Uint8ClampedArray(a*3),F=0;for(var d=0;d>24}function Z(p,t){return p[t]<<8|p[t+1]}function am(p,t){return(p[t]<<24|p[t+1]<<16|p[t+2]<<8|p[t+3])>>>0}UTIF.JpegDecoder=ak}()); + + //UTIF.JpegDecoder = PDFJS.JpegImage; + + + UTIF.encodeImage = function(rgba, w, h, metadata) + { + var idf = { "t256":[w], "t257":[h], "t258":[8,8,8,8], "t259":[1], "t262":[2], "t273":[1000], // strips offset + "t277":[4], "t278":[h], /* rows per strip */ "t279":[w*h*4], // strip byte counts + "t282":[[72,1]], "t283":[[72,1]], "t284":[1], "t286":[[0,1]], "t287":[[0,1]], "t296":[1], "t305": ["Photopea (UTIF.js)"], "t338":[1] + }; + if (metadata) for (var i in metadata) idf[i] = metadata[i]; + + var prfx = new Uint8Array(UTIF.encode([idf])); + var img = new Uint8Array(rgba); + var data = new Uint8Array(1000+w*h*4); + for(var i=0; i probably not an image + img.isLE = id=="II"; + img.width = img["t256"][0]; //delete img["t256"]; + img.height = img["t257"][0]; //delete img["t257"]; + + var cmpr = img["t259"] ? img["t259"][0] : 1; //delete img["t259"]; + var fo = img["t266"] ? img["t266"][0] : 1; //delete img["t266"]; + if(img["t284"] && img["t284"][0]==2) log("PlanarConfiguration 2 should not be used!"); + if(cmpr==7 && img["t258"] && img["t258"].length>3) img["t258"]=img["t258"].slice(0,3); + + var spp = img["t277"]?img["t277"][0]:1; + var bps = img["t258"]?img["t258"][0]:1; + var bipp = bps*spp; // bits per pixel + /* + var bipp; // bits per pixel + if(img["t258"]) bipp = Math.min(32,img["t258"][0])*img["t258"].length; + else bipp = (img["t277"]?img["t277"][0]:1); + */ + // Some .NEF files have t258==14, even though they use 16 bits per pixel + if(cmpr==1 && img["t279"]!=null && img["t278"] && img["t262"][0]==32803) { + bipp = Math.round((img["t279"][0]*8)/(img.width*img["t278"][0])); + } + if(img["t50885"] && img["t50885"][0]==4) bipp = img["t258"][0]*3; // RAW_CANON_40D_SRAW_V103.CR2 + var bipl = Math.ceil(img.width*bipp/8)*8; + var soff = img["t273"]; if(soff==null || img["t322"]) soff = img["t324"]; + var bcnt = img["t279"]; if(cmpr==1 && soff.length==1) bcnt = [img.height*(bipl>>>3)]; if(bcnt==null || img["t322"]) bcnt = img["t325"]; + //bcnt[0] = Math.min(bcnt[0], data.length); // Hasselblad, "RAW_HASSELBLAD_H3D39II.3FR" + var bytes = new Uint8Array(img.height*(bipl>>>3)), bilen = 0; + + if(img["t322"]!=null) // tiled + { + var tw = img["t322"][0], th = img["t323"][0]; + var tx = Math.floor((img.width + tw - 1) / tw); + var ty = Math.floor((img.height + th - 1) / th); + var tbuff = new Uint8Array(Math.ceil(tw*th*bipp/8)|0); + console.log("====", tx,ty); + for(var y=0; y>>3, h = (img["t278"] ? img["t278"][0] : img.height), bpl = Math.ceil(bps*noc*img.width/8); + + // convert to Little Endian /* + if(bps==16 && !img.isLE && img["t33422"]==null) // not DNG + for(var y=0; y>>8)&255; + } + else if(noc==3) for(var j= 3; j> 3 ^ 0x3ff0; + return (buffer[byte] | buffer[byte + 1] << 8) >> (vpos & 7) & ~((-1) << bits); + } + } + // Raw Format 6 + function getBufferDataRW6(i) { + return buffer[vpos + 15 - i]; + } + function readPageRW6() { + bytes[0] = (getBufferDataRW6(0) << 6) | (getBufferDataRW6(1) >> 2); // 14 bit + bytes[1] = (((getBufferDataRW6(1) & 0x3) << 12) | (getBufferDataRW6(2) << 4) | (getBufferDataRW6(3) >> 4)) & 0x3fff; + bytes[2] = (getBufferDataRW6(3) >> 2) & 0x3; + bytes[3] = ((getBufferDataRW6(3) & 0x3) << 8) | getBufferDataRW6(4); + bytes[4] = (getBufferDataRW6(5) << 2) | (getBufferDataRW6(6) >> 6); + bytes[5] = ((getBufferDataRW6(6) & 0x3f) << 4) | (getBufferDataRW6(7) >> 4); + bytes[6] = (getBufferDataRW6(7) >> 2) & 0x3; + bytes[7] = ((getBufferDataRW6(7) & 0x3) << 8) | getBufferDataRW6(8); + bytes[8] = ((getBufferDataRW6(9) << 2) & 0x3fc) | (getBufferDataRW6(10) >> 6); + bytes[9] = ((getBufferDataRW6(10) << 4) | (getBufferDataRW6(11) >> 4)) & 0x3ff; + bytes[10] = (getBufferDataRW6(11) >> 2) & 0x3; + bytes[11] = ((getBufferDataRW6(11) & 0x3) << 8) | getBufferDataRW6(12); + bytes[12] = (((getBufferDataRW6(13) << 2) & 0x3fc) | getBufferDataRW6(14) >> 6) & 0x3ff; + bytes[13] = ((getBufferDataRW6(14) << 4) | (getBufferDataRW6(15) >> 4)) & 0x3ff; + vpos += 16; + byte = 0; + } + // Main loop + function resetPredNonzeros(){ + pred[0]=0; pred[1]=0; + nonz[0]=0; nonz[1]=0; + } + if (RW2_Format == 7) { + throw RW2_Format; + + // Skatch of version 7 + /* + var pixels_per_block = bitsPerSample == 14 ? 9 : 10; + rowbytes = 0|(rawWidth / pixels_per_block * 16); + for (row = 0; row < rawHeight - 15; row += 16) { + var rowstoread = Math.min(16, rawHeight - row); + var readlen = rowbytes*rowstoread; + buffer = new Uint8Array(image.slice(bidx, bidx+readlen)); + vpos = 0; + bidx += readlen; + i = 0; + for (crow = 0; crow < rowstoread; crow++) { + idx = (row + crow) * rawWidth; + for (col = 0; col <= rawWidth - pixels_per_block; col += pixels_per_block) { + for(j=0; j < pixels_per_block; j++) bytes[j] = buffer[i++]; + if (bitsPerSample == 12) { + result[idx ] = ((bytes[1] & 0xF) << 8) + bytes[0]; + result[idx + 1] = 16 * bytes[2] + (bytes[1] >> 4); + result[idx + 2] = ((bytes[4] & 0xF) << 8) + bytes[3]; + result[idx + 3] = 16 * bytes[5] + (bytes[4] >> 4); + result[idx + 4] = ((bytes[7] & 0xF) << 8) + bytes[6]; + result[idx + 5] = 16 * bytes[8] + (bytes[7] >> 4); + result[idx + 6] = ((bytes[10] & 0xF) << 8) + bytes[9]; + result[idx + 7] = 16 * bytes[11] + (bytes[10] >> 4); + result[idx + 8] = ((bytes[13] & 0xF) << 8) + bytes[12]; + result[idx + 9] = 16 * bytes[14] + (bytes[13] >> 4); + } else if (bitsPerSample == 14) { + result[idx] = bytes[0] + ((bytes[1] & 0x3F) << 8); + result[idx + 1] = (bytes[1] >> 6) + 4 * (bytes[2]) + ((bytes[3] & 0xF) << 10); + result[idx + 2] = (bytes[3] >> 4) + 16 * (bytes[4]) + ((bytes[5] & 3) << 12); + result[idx + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6); + result[idx + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8); + result[idx + 5] = (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10); + result[idx + 6] = (bytes[10] >> 4) + 16 * bytes[11] + ((bytes[12] & 3) << 12); + result[idx + 7] = ((bytes[12] & 0xFC) >> 2) + (bytes[13] << 6); + result[idx + 8] = bytes[14] + ((bytes[15] & 0x3F) << 8); + } + } + } + } + */ + } + else if(RW2_Format == 6) { + var blocksperrow = Math.floor(rawWidth / 11), + rowbytes = blocksperrow * 16; + for (row = 0; row < rawHeight - 15; row += 16) { + var rowstoread = Math.min(16, rawHeight - row); + var readlen = rowbytes*rowstoread; + buffer = new Uint8Array(img_buffer, off+bidx, readlen);//new Uint8Array(image.slice(bidx, bidx+readlen)); + vpos = 0; + bidx += readlen; + for (crow = 0, col = 0; crow < rowstoread; crow++, col = 0) { + idx = (row + crow) * rawWidth; + for (var rblock = 0; rblock < blocksperrow; rblock++) { + readPageRW6(); + resetPredNonzeros(); + sh=0; pixel_base=0; + for (i = 0; i < 11; i++){ + isOdd = i & 1; + if (i % 3 == 2) { + var base = byte < 14 ? bytes[byte++] : 0; + if (base == 3) base = 4; + pixel_base = 0x200 << base; + sh = 1 << base; + } + var epixel = byte < 14 ? bytes[byte++] : 0; + if (pred[isOdd]) { + epixel *= sh; + if (pixel_base < 0x2000 && nonz[isOdd] > pixel_base) + epixel += nonz[isOdd] - pixel_base; + nonz[isOdd] = epixel; + } else { + pred[isOdd] = epixel; + if (epixel) + nonz[isOdd] = epixel; + else + epixel = nonz[isOdd]; + } + result[idx + col++] = (epixel - 0xf) <= 0xffff ? (epixel - 0xf) & 0xffff : ((epixel + 0x7ffffff1) >> 0x1f) & 0x3fff; + } + } + } + } + } + else if (RW2_Format == 5) { + var blockSize = bitsPerSample == 12 ? 10 : 9; + for (row = 0; row < rawHeight; row++) { + for (col = 0; col < rawWidth; col+=blockSize) { + getDataRaw(0); + // Tuhle podminku pouziva i RW2_Format 7 + if (bitsPerSample == 12) { + result[idx++] = ((bytes[1] & 0xF) << 8) + bytes[0]; + result[idx++] = 16 * bytes[2] + (bytes[1] >> 4); + result[idx++] = ((bytes[4] & 0xF) << 8) + bytes[3]; + result[idx++] = 16 * bytes[5] + (bytes[4] >> 4); + result[idx++] = ((bytes[7] & 0xF) << 8) + bytes[6]; + result[idx++] = 16 * bytes[8] + (bytes[7] >> 4); + result[idx++] = ((bytes[10] & 0xF) << 8) + bytes[9]; + result[idx++] = 16 * bytes[11] + (bytes[10] >> 4); + result[idx++] = ((bytes[13] & 0xF) << 8) + bytes[12]; + result[idx++] = 16 * bytes[14] + (bytes[13] >> 4); + } else if (bitsPerSample == 14) { + result[idx++] = bytes[0] + ((bytes[1] & 0x3F) << 8); + result[idx++] = (bytes[1] >> 6) + 4 * (bytes[2]) + ((bytes[3] & 0xF) << 10); + result[idx++] = (bytes[3] >> 4) + 16 * (bytes[4]) + ((bytes[5] & 3) << 12); + result[idx++] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6); + result[idx++] = bytes[7] + ((bytes[8] & 0x3F) << 8); + result[idx++] = (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10); + result[idx++] = (bytes[10] >> 4) + 16 * bytes[11] + ((bytes[12] & 3) << 12); + result[idx++] = ((bytes[12] & 0xFC) >> 2) + (bytes[13] << 6); + result[idx++] = bytes[14] + ((bytes[15] & 0x3F) << 8); + } + } + } + //console.log(result[1000000 - 1]) + } else if(RW2_Format == 4) { + for (row = 0; row < rawHeight; row++){ + for(col = 0; col < rawWidth; col++){ + i = col % 14; + isOdd = i & 1; + if (i==0) resetPredNonzeros(); + if (i%3 == 2) + sh = 4 >> (3 - getDataRaw(2)); + if (nonz[isOdd]) { + j = getDataRaw(8); + if(j != 0){ + pred[isOdd] -= 0x80 << sh; + if (pred[isOdd] < 0 || sh == 4) + pred[isOdd] &= ~((-1) << sh); + pred[isOdd] += j << sh; + } + } else { + nonz[isOdd] = getDataRaw(8); + if(nonz[isOdd] || i > 11) + pred[isOdd] = nonz[isOdd] << 4 | getDataRaw(4); + } + result[idx++] = pred[col & 1]; + } + } + } + else throw RW2_Format; + } + + + UTIF.decode._decodeVC5 = UTIF.decode._decodeVC5=function(){var e=[1,0,1,0,2,2,1,1,3,7,1,2,5,25,1,3,6,48,1,4,6,54,1,5,7,111,1,8,7,99,1,6,7,105,12,0,7,107,1,7,8,209,20,0,8,212,1,9,8,220,1,10,9,393,1,11,9,394,32,0,9,416,1,12,9,427,1,13,10,887,1,18,10,784,1,14,10,790,1,15,10,835,60,0,10,852,1,16,10,885,1,17,11,1571,1,19,11,1668,1,20,11,1669,100,0,11,1707,1,21,11,1772,1,22,12,3547,1,29,12,3164,1,24,12,3166,1,25,12,3140,1,23,12,3413,1,26,12,3537,1,27,12,3539,1,28,13,7093,1,35,13,6283,1,30,13,6331,1,31,13,6335,180,0,13,6824,1,32,13,7072,1,33,13,7077,320,0,13,7076,1,34,14,12565,1,36,14,12661,1,37,14,12669,1,38,14,13651,1,39,14,14184,1,40,15,28295,1,46,15,28371,1,47,15,25320,1,42,15,25336,1,43,15,25128,1,41,15,27300,1,44,15,28293,1,45,16,50259,1,48,16,50643,1,49,16,50675,1,50,16,56740,1,53,16,56584,1,51,16,56588,1,52,17,113483,1,61,17,113482,1,60,17,101285,1,55,17,101349,1,56,17,109205,1,57,17,109207,1,58,17,100516,1,54,17,113171,1,59,18,202568,1,62,18,202696,1,63,18,218408,1,64,18,218412,1,65,18,226340,1,66,18,226356,1,67,18,226358,1,68,19,402068,1,69,19,405138,1,70,19,405394,1,71,19,436818,1,72,19,436826,1,73,19,452714,1,75,19,452718,1,76,19,452682,1,74,20,804138,1,77,20,810279,1,78,20,810790,1,79,20,873638,1,80,20,873654,1,81,20,905366,1,82,20,905430,1,83,20,905438,1,84,21,1608278,1,85,21,1620557,1,86,21,1621582,1,87,21,1621583,1,88,21,1747310,1,89,21,1810734,1,90,21,1810735,1,91,21,1810863,1,92,21,1810879,1,93,22,3621725,1,99,22,3621757,1,100,22,3241112,1,94,22,3494556,1,95,22,3494557,1,96,22,3494622,1,97,22,3494623,1,98,23,6482227,1,102,23,6433117,1,101,23,6989117,1,103,23,6989119,1,105,23,6989118,1,104,23,7243449,1,106,23,7243512,1,107,24,13978233,1,111,24,12964453,1,109,24,12866232,1,108,24,14486897,1,113,24,13978232,1,110,24,14486896,1,112,24,14487026,1,114,24,14487027,1,115,25,25732598,1,225,25,25732597,1,189,25,25732596,1,188,25,25732595,1,203,25,25732594,1,202,25,25732593,1,197,25,25732592,1,207,25,25732591,1,169,25,25732590,1,223,25,25732589,1,159,25,25732522,1,235,25,25732579,1,152,25,25732575,1,192,25,25732489,1,179,25,25732573,1,201,25,25732472,1,172,25,25732576,1,149,25,25732488,1,178,25,25732566,1,120,25,25732571,1,219,25,25732577,1,150,25,25732487,1,127,25,25732506,1,211,25,25732548,1,125,25,25732588,1,158,25,25732486,1,247,25,25732467,1,238,25,25732508,1,163,25,25732552,1,228,25,25732603,1,183,25,25732513,1,217,25,25732587,1,168,25,25732520,1,122,25,25732484,1,128,25,25732562,1,249,25,25732505,1,187,25,25732504,1,186,25,25732483,1,136,25,25928905,1,181,25,25732560,1,255,25,25732500,1,230,25,25732482,1,135,25,25732555,1,233,25,25732568,1,222,25,25732583,1,145,25,25732481,1,134,25,25732586,1,167,25,25732521,1,248,25,25732518,1,209,25,25732480,1,243,25,25732512,1,216,25,25732509,1,164,25,25732547,1,140,25,25732479,1,157,25,25732544,1,239,25,25732574,1,191,25,25732564,1,251,25,25732478,1,156,25,25732546,1,139,25,25732498,1,242,25,25732557,1,133,25,25732477,1,162,25,25732515,1,213,25,25732584,1,165,25,25732514,1,212,25,25732476,1,227,25,25732494,1,198,25,25732531,1,236,25,25732530,1,234,25,25732529,1,117,25,25732528,1,215,25,25732527,1,124,25,25732526,1,123,25,25732525,1,254,25,25732524,1,253,25,25732523,1,148,25,25732570,1,218,25,25732580,1,146,25,25732581,1,147,25,25732569,1,224,25,25732533,1,143,25,25732540,1,184,25,25732541,1,185,25,25732585,1,166,25,25732556,1,132,25,25732485,1,129,25,25732563,1,250,25,25732578,1,151,25,25732501,1,119,25,25732502,1,193,25,25732536,1,176,25,25732496,1,245,25,25732553,1,229,25,25732516,1,206,25,25732582,1,144,25,25732517,1,208,25,25732558,1,137,25,25732543,1,241,25,25732466,1,237,25,25732507,1,190,25,25732542,1,240,25,25732551,1,131,25,25732554,1,232,25,25732565,1,252,25,25732475,1,171,25,25732493,1,205,25,25732492,1,204,25,25732491,1,118,25,25732490,1,214,25,25928904,1,180,25,25732549,1,126,25,25732602,1,182,25,25732539,1,175,25,25732545,1,141,25,25732559,1,138,25,25732537,1,177,25,25732534,1,153,25,25732503,1,194,25,25732606,1,160,25,25732567,1,121,25,25732538,1,174,25,25732497,1,246,25,25732550,1,130,25,25732572,1,200,25,25732474,1,170,25,25732511,1,221,25,25732601,1,196,25,25732532,1,142,25,25732519,1,210,25,25732495,1,199,25,25732605,1,155,25,25732535,1,154,25,25732499,1,244,25,25732510,1,220,25,25732600,1,195,25,25732607,1,161,25,25732604,1,231,25,25732473,1,173,25,25732599,1,226,26,51465122,1,116,26,51465123,0,1],x,u,H,d=[3,3,3,3,2,2,2,1,1,1],a=24576,a7=16384,K=8192,ai=a7|K; + function A(B){var P=B[1],D=B[0][P>>>3]>>>7-(P&7)&1;B[1]++;return D}function aj(B,P){if(x==null){x={}; + for(var D=0;D>>1}return B}function c(B,P){return B>>P}function N(B,P,D,U,X,y){P[D]=c(c(11*B[X]-4*B[X+y]+B[X+y+y]+4,3)+B[U],1); + P[D+y]=c(c(5*B[X]+4*B[X+y]-B[X+y+y]+4,3)-B[U],1)}function g(B,P,D,U,X,y){var n=B[X-y]-B[X+y],S=B[X],O=B[U]; + P[D]=c(c(n+4,3)+S+O,1);P[D+y]=c(c(-n+4,3)+S-O,1)}function L(B,P,D,U,X,y){P[D]=c(c(5*B[X]+4*B[X-y]-B[X-y-y]+4,3)+B[U],1); + P[D+y]=c(c(11*B[X]-4*B[X-y]+B[X-y-y]+4,3)-B[U],1)}function t(B){B=B<0?0:B>4095?4095:B;B=H[B]>>>2;return B}function ab(B,P,D,U,X){U=new Uint16Array(U.buffer); + var y=Date.now(),n=UTIF._binBE,S=P+D,O,q,i,M,m,aA,T,a8,a0,am,au,a3,aw,ao,v,ax,p,k;P+=4;while(P>>1)*(i>>>1));k=new Int16Array((q>>>1)*(i>>>1));u=new Int16Array(1024); + for(var f=0;f<1024;f++){var aF=f-512,j=Math.abs(aF),O=Math.floor(768*j*j*j/(255*255*255))+j;u[f]=Math.sign(aF)*O}H=new Uint16Array(4096); + var al=(1<<16)-1;for(var f=0;f<4096;f++){var ad=f,az=al*(Math.pow(113,ad/4095)-1)/112;H[f]=Math.min(az,al)}}var Z=p[T],V=Q(q,1+d[M]),z=Q(i,1+d[M]); + if(M==0){for(var b=0;b>>1)+G]=B[w]<<8|B[w+1]}}else{var aC=[B,P*8],aq=[],a5=0,ae=V*z,I=[0,0],s=0,E=0; + while(a50){aq[a5++]=E;s--}}var $=(M-1)%3,aE=$!=1?V:0,as=$!=0?z:0; + for(var b=0;b>>1)+aE,aa=b*V;for(var G=0;G>>1,an=V*2,at=z*2; + for(var b=0;b>14-r*2&3;var af=a6[aD];if(af!=0)for(var b=0;b>>1)*(q>>>1)+(G>>>1),R=a2[w],ak=ar[w]-2048,aB=ah[w]-2048,av=a1[w]-2048,a4=(ak<<1)+R,a9=(aB<<1)+R,ap=R+av,ag=R-av; + U[J]=t(a4);U[J+1]=t(ap);U[J+q]=t(ag);U[J+q+1]=t(a9)}}P+=o*4}else if(C==16388){P+=o*4}else if(F==8192||F==8448||F==9216){}else throw C.toString(16)}}console.log(Date.now()-y)}return ab}() + + UTIF.decode._decodeLogLuv32 = function(img, data, off, len, tgt, toff) { + var w = img.width, qw=w*4; + var io = 0, out = new Uint8Array(qw); + + while(io>> (tab[i] >>> 8); + for(var c=0; c>>4); tgt[toff+i+1]=(b0<<4)|(b2>>>4); tgt[toff+i+2]=(b2<<4)|(b1>>>4); } + return; + } + + var pix = new Uint16Array(16); + var row, col, val, max, min, imax, imin, sh, bit, i, dp; + + var data = new Uint8Array(raw_width+1); + for (row=0; row < height; row++) { + //fread (data, 1, raw_width, ifp); + for(var j=0; j>> 11); + imax = 0x0f & (val >>> 22); + imin = 0x0f & (val >>> 26); + for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++); + for (bit=30, i=0; i < 16; i++) + if (i == imax) pix[i] = max; + else if (i == imin) pix[i] = min; + else { + pix[i] = ((bin.readUshort(data, dp+(bit >> 3)) >>> (bit & 7) & 0x7f) << sh) + min; + if (pix[i] > 0x7ff) pix[i] = 0x7ff; + bit += 7; + } + for (i=0; i < 16; i++, col+=2) { + //RAW(row,col) = curve[pix[i] << 1] >> 2; + var clr = pix[i]<<1; //clr = 0xffff; + UTIF.decode._putsF(tgt, (row*raw_width+col)*tiff_bps, clr<<(16-tiff_bps)); + } + col -= col & 1 ? 1:31; + } + } + } + + UTIF.decode._decodeNikon = function(img,imgs, data, off, src_length, tgt, toff) + { + var nikon_tree = [ + [ 0, 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */ + 5,4,3,6,2,7,1,0,8,9,11,10,12 ], + [ 0, 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */ + 0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 ], + [ 0, 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */ + 5,4,6,3,7,2,8,1,9,0,10,11,12 ], + [ 0, 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */ + 5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 ], + [ 0, 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */ + 8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 ], + [ 0, 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */ + 7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 ] ]; + + var raw_width = img["t256"][0], height=img["t257"][0], tiff_bps=img["t258"][0]; + + var tree = 0, split = 0; + var make_decoder = UTIF.decode._make_decoder; + var getbithuff = UTIF.decode._getbithuff; + + var mn = imgs[0].exifIFD.makerNote, md = mn["t150"]?mn["t150"]:mn["t140"], mdo=0; //console.log(mn,md); + //console.log(md[0].toString(16), md[1].toString(16), tiff_bps); + var ver0 = md[mdo++], ver1 = md[mdo++]; + if (ver0 == 0x49 || ver1 == 0x58) mdo+=2110; + if (ver0 == 0x46) tree = 2; + if (tiff_bps == 14) tree += 3; + + var vpred = [[0,0],[0,0]], bin=(img.isLE ? UTIF._binLE : UTIF._binBE); + for(var i=0; i<2; i++) for(var j=0; j<2; j++) { vpred[i][j] = bin.readShort(md,mdo); mdo+=2; } // not sure here ... [i][j] or [j][i] + //console.log(vpred); + + + var max = 1 << tiff_bps & 0x7fff, step=0; + var csize = bin.readShort(md,mdo); mdo+=2; + if (csize > 1) step = Math.floor(max / (csize-1)); + if (ver0 == 0x44 && ver1 == 0x20 && step > 0) split = bin.readShort(md,562); + + + var i; + var row, col; + var len, shl, diff; + var min_v = 0; + var hpred = [0,0]; + var huff = make_decoder(nikon_tree[tree]); + + //var g_input_offset=0, bitbuf=0, vbits=0, reset=0; + var prm = [off,0,0,0]; + //console.log(split); split = 170; + + for (min_v=row=0; row < height; row++) { + if (split && row == split) { + //free (huff); + huff = make_decoder (nikon_tree[tree+1]); + //max_v += (min_v = 16) << 1; + } + for (col=0; col < raw_width; col++) { + i = getbithuff(data,prm,huff[0],huff); + len = i & 15; + shl = i >>> 4; + diff = (((getbithuff(data,prm,len-shl,0) << 1) + 1) << shl) >>> 1; + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - (shl==0?1:0); + if (col < 2) hpred[col] = vpred[row & 1][col] += diff; + else hpred[col & 1] += diff; + + var clr = Math.min(Math.max(hpred[col & 1],0),(1<>>3); dt[o]|=val>>>16; dt[o+1]|=val>>>8; dt[o+2]|=val; } + + + UTIF.decode._getbithuff = function(data,prm,nbits, huff) { + var zero_after_ff = 0; + var get_byte = UTIF.decode._get_byte; + var c; + + var off=prm[0], bitbuf=prm[1], vbits=prm[2], reset=prm[3]; + + //if (nbits > 25) return 0; + //if (nbits < 0) return bitbuf = vbits = reset = 0; + if (nbits == 0 || vbits < 0) return 0; + while (!reset && vbits < nbits && (c = data[off++]) != -1 && + !(reset = zero_after_ff && c == 0xff && data[off++])) { + //console.log("byte read into c"); + bitbuf = (bitbuf << 8) + c; + vbits += 8; + } + c = (bitbuf << (32-vbits)) >>> (32-nbits); + if (huff) { + vbits -= huff[c+1] >>> 8; //console.log(c, huff[c]>>8); + c = huff[c+1]&255; + } else + vbits -= nbits; + if (vbits < 0) throw "e"; + + prm[0]=off; prm[1]=bitbuf; prm[2]=vbits; prm[3]=reset; + + return c; + } + + UTIF.decode._make_decoder = function(source) { + var max, len, h, i, j; + var huff = []; + + for (max=16; max!=0 && !source[max]; max--); + var si=17; + + huff[0] = max; + for (h=len=1; len <= max; len++) + for (i=0; i < source[len]; i++, ++si) + for (j=0; j < 1 << (max-len); j++) + if (h <= 1 << max) + huff[h++] = (len << 8) | source[si]; + return huff; + } + + UTIF.decode._decodeNewJPEG = function(img, data, off, len, tgt, toff) + { + len = Math.min(len, data.length-off); + var tables = img["t347"], tlen = tables ? tables.length : 0, buff = new Uint8Array(tlen + len); + + if (tables) { + var SOI = 216, EOI = 217, boff = 0; + for (var i=0; i<(tlen-1); i++) + { + // Skip EOI marker from JPEGTables + if (tables[i]==255 && tables[i+1]==EOI) break; + buff[boff++] = tables[i]; + } + + // Skip SOI marker from data + var byte1 = data[off], byte2 = data[off + 1]; + if (byte1!=255 || byte2!=SOI) + { + buff[boff++] = byte1; + buff[boff++] = byte2; + } + for (var i=2; i>>8); } + else for(var i=0; i>>8); tgt[toff+(i<<1)+1] = (out[i]&255); } + } + else if(bps==14 || bps==12) { // 4 * 14 == 56 == 7 * 8 + var rst = 16-bps; + for(var i=0; i 1); + } + + if(!isTiled) + { + if(data[off]==255 && data[off+1]==SOI) return { jpegOffset: off }; + if(jpgIchgFmt!=null) + { + if(data[off+jifoff]==255 && data[off+jifoff+1]==SOI) joff = off+jifoff; + else log("JPEGInterchangeFormat does not point to SOI"); + + if(jpgIchgFmtLen==null) log("JPEGInterchangeFormatLength field is missing"); + else if(jifoff >= soff || (jifoff+jiflen) <= soff) log("JPEGInterchangeFormatLength field value is invalid"); + + if(joff != null) return { jpegOffset: joff }; + } + } + + if(ycbcrss!=null) { ssx = ycbcrss[0]; ssy = ycbcrss[1]; } + + if(jpgIchgFmt!=null) + if(jpgIchgFmtLen!=null) + if(jiflen >= 2 && (jifoff+jiflen) <= soff) + { + if(data[off+jifoff+jiflen-2]==255 && data[off+jifoff+jiflen-1]==SOI) tables = new Uint8Array(jiflen-2); + else tables = new Uint8Array(jiflen); + + for(i=0; i offset to first strip or tile"); + + if(tables == null) + { + var ooff = 0, out = []; + out[ooff++] = 255; out[ooff++] = SOI; + + var qtables = img["t519"]; + if(qtables==null) throw new Error("JPEGQTables tag is missing"); + for(i=0; i>> 8); out[ooff++] = nc & 255; + out[ooff++] = (i | (k << 4)); + for(j=0; j<16; j++) out[ooff++] = data[off+htables[i]+j]; + for(j=0; j>> 8) & 255; out[ooff++] = img.height & 255; + out[ooff++] = (img.width >>> 8) & 255; out[ooff++] = img.width & 255; + out[ooff++] = spp; + if(spp==1) { out[ooff++] = 1; out[ooff++] = 17; out[ooff++] = 0; } + else for(i=0; i<3; i++) + { + out[ooff++] = i + 1; + out[ooff++] = (i != 0) ? 17 : (((ssx & 15) << 4) | (ssy & 15)); + out[ooff++] = i; + } + + if(jpgresint!=null && jpgresint[0]!=0) + { + out[ooff++] = 255; out[ooff++] = DRI; out[ooff++] = 0; out[ooff++] = 4; + out[ooff++] = (jpgresint[0] >>> 8) & 255; + out[ooff++] = jpgresint[0] & 255; + } + + tables = new Uint8Array(out); + } + + var sofpos = -1; + i = 0; + while(i < (tables.length - 1)) { + if(tables[i]==255 && tables[i+1]==SOF0) { sofpos = i; break; } + i++; + } + + if(sofpos == -1) + { + var tmptab = new Uint8Array(tables.length + 10 + 3*spp); + tmptab.set(tables); + var tmpoff = tables.length; + sofpos = tables.length; + tables = tmptab; + + tables[tmpoff++] = 255; tables[tmpoff++] = SOF0; + tables[tmpoff++] = 0; tables[tmpoff++] = 8 + 3*spp; tables[tmpoff++] = 8; + tables[tmpoff++] = (img.height >>> 8) & 255; tables[tmpoff++] = img.height & 255; + tables[tmpoff++] = (img.width >>> 8) & 255; tables[tmpoff++] = img.width & 255; + tables[tmpoff++] = spp; + if(spp==1) { tables[tmpoff++] = 1; tables[tmpoff++] = 17; tables[tmpoff++] = 0; } + else for(i=0; i<3; i++) + { + tables[tmpoff++] = i + 1; + tables[tmpoff++] = (i != 0) ? 17 : (((ssx & 15) << 4) | (ssy & 15)); + tables[tmpoff++] = i; + } + } + + if(data[soff]==255 && data[soff+1]==SOS) + { + var soslen = (data[soff+2]<<8) | data[soff+3]; + sosMarker = new Uint8Array(soslen+2); + sosMarker[0] = data[soff]; sosMarker[1] = data[soff+1]; sosMarker[2] = data[soff+2]; sosMarker[3] = data[soff+3]; + for(i=0; i<(soslen-2); i++) sosMarker[i+4] = data[soff+i+4]; + } + else + { + sosMarker = new Uint8Array(2 + 6 + 2*spp); + var sosoff = 0; + sosMarker[sosoff++] = 255; sosMarker[sosoff++] = SOS; + sosMarker[sosoff++] = 0; sosMarker[sosoff++] = 6 + 2*spp; sosMarker[sosoff++] = spp; + if(spp==1) { sosMarker[sosoff++] = 1; sosMarker[sosoff++] = 0; } + else for(i=0; i<3; i++) + { + sosMarker[sosoff++] = i+1; sosMarker[sosoff++] = (i << 4) | i; + } + sosMarker[sosoff++] = 0; sosMarker[sosoff++] = 63; sosMarker[sosoff++] = 0; + } + + return { jpegOffset: off, tables: tables, sosMarker: sosMarker, sofPosition: sofpos }; + } + + UTIF.decode._decodeOldJPEG = function(img, data, off, len, tgt, toff) + { + var i, dlen, tlen, buff, buffoff; + var jpegData = UTIF.decode._decodeOldJPEGInit(img, data, off, len); + + if(jpegData.jpegOffset!=null) + { + dlen = off+len-jpegData.jpegOffset; + buff = new Uint8Array(dlen); + for(i=0; i>> 8) & 255; buff[jpegData.sofPosition+6] = img.height & 255; + buff[jpegData.sofPosition+7] = (img.width >>> 8) & 255; buff[jpegData.sofPosition+8] = img.width & 255; + + if(data[off]!=255 || data[off+1]!=SOS) + { + buff.set(jpegData.sosMarker, buffoff); + buffoff += sosMarker.length; + } + for(i=0; i=0 && n<128) for(var i=0; i< n+1; i++) { ta[toff]=sa[off]; toff++; off++; } + if(n>=-127 && n<0) { for(var i=0; i<-n+1; i++) { ta[toff]=sa[off]; toff++; } off++; } + } + return toff; + } + + UTIF.decode._decodeThunder = function(data, off, len, tgt, toff) + { + var d2 = [ 0, 1, 0, -1 ], d3 = [ 0, 1, 2, 3, 0, -3, -2, -1 ]; + var lim = off+len, qoff = toff*2, px = 0; + while(off>>6), n = (b&63); off++; + if(msk==3) { px=(n&15); tgt[qoff>>>1] |= (px<<(4*(1-qoff&1))); qoff++; } + if(msk==0) for(var i=0; i>>1] |= (px<<(4*(1-qoff&1))); qoff++; } + if(msk==2) for(var i=0; i<2; i++) { var d=(n>>>(3*(1-i)))&7; if(d!=4) { px+=d3[d]; tgt[qoff>>>1] |= (px<<(4*(1-qoff&1))); qoff++; } } + if(msk==1) for(var i=0; i<3; i++) { var d=(n>>>(2*(2-i)))&3; if(d!=2) { px+=d2[d]; tgt[qoff>>>1] |= (px<<(4*(1-qoff&1))); qoff++; } } + } + } + + UTIF.decode._dmap = { "1":0,"011":1,"000011":2,"0000011":3, "010":-1,"000010":-2,"0000010":-3 }; + UTIF.decode._lens = ( function() + { + var addKeys = function(lens, arr, i0, inc) { for(var i=0; i>>3)>>3]>>>(7-(boff&7)))&1; + if(fo==2) bit = (data[boff>>>3]>>>( (boff&7)))&1; + boff++; wrd+=bit; + if(mode=="H") + { + if(U._lens[clr][wrd]!=null) + { + var dl=U._lens[clr][wrd]; wrd=""; len+=dl; + if(dl<64) { U._addNtimes(line,len,clr); a0+=len; clr=1-clr; len=0; toRead--; if(toRead==0) mode=""; } + } + } + else + { + if(wrd=="0001") { wrd=""; U._addNtimes(line,b2-a0,clr); a0=b2; } + if(wrd=="001" ) { wrd=""; mode="H"; toRead=2; } + if(U._dmap[wrd]!=null) { a1 = b1+U._dmap[wrd]; U._addNtimes(line, a1-a0, clr); a0=a1; wrd=""; clr=1-clr; } + } + if(line.length==w && mode=="") + { + U._writeBits(line, tgt, toff*8+y*bipl); + clr=0; y++; a0=0; + pline=U._makeDiff(line); line=[]; + } + //if(wrd.length>150) { log(wrd); break; throw "e"; } + } + } + + UTIF.decode._findDiff = function(line, x, clr) { for(var i=0; i=x && line[i+1]==clr) return line[i]; } + + UTIF.decode._makeDiff = function(line) + { + var out = []; if(line[0]==1) out.push(0,1); + for(var i=1; i>>3)>>3]>>>(7-(boff&7)))&1; + if(fo==2) bit = (data[boff>>>3]>>>( (boff&7)))&1; + boff++; wrd+=bit; + + len = U._lens[clr][wrd]; + if(len!=null) { + U._addNtimes(line,len,clr); wrd=""; + if(len<64) clr = 1-clr; + if(line.length==w) { U._writeBits(line, tgt, toff*8+y*bipl); line=[]; y++; clr=0; if((boff&7)!=0) boff+=8-(boff&7); if(len>=64) boff+=8; } + } + } + } + + UTIF.decode._decodeG3 = function(data, off, slen, tgt, toff, w, fo, twoDim) + { + var U = UTIF.decode, boff=off<<3, len=0, wrd=""; + var line=[], pline=[]; for(var i=0; i>>3)>>3]>>>(7-(boff&7)))&1; + if(fo==2) bit = (data[boff>>>3]>>>( (boff&7)))&1; + boff++; wrd+=bit; + + if(is1D) + { + if(U._lens[clr][wrd]!=null) + { + var dl=U._lens[clr][wrd]; wrd=""; len+=dl; + if(dl<64) { U._addNtimes(line,len,clr); clr=1-clr; len=0; } + } + } + else + { + if(mode=="H") + { + if(U._lens[clr][wrd]!=null) + { + var dl=U._lens[clr][wrd]; wrd=""; len+=dl; + if(dl<64) { U._addNtimes(line,len,clr); a0+=len; clr=1-clr; len=0; toRead--; if(toRead==0) mode=""; } + } + } + else + { + if(wrd=="0001") { wrd=""; U._addNtimes(line,b2-a0,clr); a0=b2; } + if(wrd=="001" ) { wrd=""; mode="H"; toRead=2; } + if(U._dmap[wrd]!=null) { a1 = b1+U._dmap[wrd]; U._addNtimes(line, a1-a0, clr); a0=a1; wrd=""; clr=1-clr; } + } + } + if(wrd.endsWith("000000000001")) // needed for some files + { + if(y>=0) U._writeBits(line, tgt, toff*8+y*bipl); + if(twoDim) { + if(fo==1) is1D = ((data[boff>>>3]>>>(7-(boff&7)))&1)==1; + if(fo==2) is1D = ((data[boff>>>3]>>>( (boff&7)))&1)==1; + boff++; + } + //log("EOL",y, "next 1D:", is1D); + wrd=""; clr=0; y++; a0=0; + pline=U._makeDiff(line); line=[]; + } + } + if(line.length==w) U._writeBits(line, tgt, toff*8+y*bipl); + } + + UTIF.decode._addNtimes = function(arr, n, val) { for(var i=0; i>>3] |= (bits[i]<<(7-((boff+i)&7))); + } + + UTIF.decode._decodeLZW=UTIF.decode._decodeLZW=function(){var e,U,Z,u,K=0,V=0,g=0,N=0,O=function(){var S=e>>>3,A=U[S]<<16|U[S+1]<<8|U[S+2],j=A>>>24-(e&7)-V&(1<>>----------------"); + for(var i=0; i4) { bin.writeUint(data, offset, eoff); toff=eoff; } + + if (type== 1 || type==7) { for(var i=0; i4) { dlen += (dlen&1); eoff += dlen; } + offset += 4; + } + return [offset, eoff]; + } + + UTIF.toRGBA8 = function(out, scl) + { + var w = out.width, h = out.height, area = w*h, qarea = area*4, data = out.data; + var img = new Uint8Array(area*4); + //console.log(out); + // 0: WhiteIsZero, 1: BlackIsZero, 2: RGB, 3: Palette color, 4: Transparency mask, 5: CMYK + var intp = (out["t262"] ? out["t262"][0]: 2), bps = (out["t258"]?Math.min(32,out["t258"][0]):1); + if(out["t262"]==null && bps==1) intp=0; + //log("interpretation: ", intp, "bps", bps, out); + + if(false) {} + else if(intp==0) + { + var bpl = Math.ceil(bps*w/8); + for(var y=0; y>3)])>>(7- (i&7)))& 1; img[qi]=img[qi+1]=img[qi+2]=( 1-px)*255; img[qi+3]=255; } + if(bps== 4) for(var i=0; i>1)])>>(4-4*(i&1)))&15; img[qi]=img[qi+1]=img[qi+2]=(15-px)* 17; img[qi+3]=255; } + if(bps== 8) for(var i=0; i>3)])>>(7- (i&7)))&1; img[qi]=img[qi+1]=img[qi+2]=(px)*255; img[qi+3]=255; } + if(bps== 2) for(var i=0; i>2)])>>(6-2*(i&3)))&3; img[qi]=img[qi+1]=img[qi+2]=(px)* 85; img[qi+3]=255; } + if(bps== 8) for(var i=0; i1 && out["t338"] && out["t338"][0]!=0; + + for(var y=0; y>>3)]>>>(7- (x&7)))& 1; + else if(bps==2) mi=(data[dof+(x>>>2)]>>>(6-2*(x&3)))& 3; + else if(bps==4) mi=(data[dof+(x>>>1)]>>>(4-4*(x&1)))&15; + else if(bps==8) mi= data[dof+x*smpls]; + else throw bps; + img[qi]=(map[mi]>>8); img[qi+1]=(map[cn+mi]>>8); img[qi+2]=(map[cn+cn+mi]>>8); img[qi+3]=nexta ? data[dof+x*smpls+1] : 255; + } + } + else if(intp==5) + { + var smpls = out["t258"]?out["t258"].length : 4; + var gotAlpha = smpls>4 ? 1 : 0; + for(var i=0; i>>1); + var Y = data[si+(j&1)], Cb=data[si+2]-128, Cr=data[si+3]-128; + + var r = Y + ( (Cr >> 2) + (Cr >> 3) + (Cr >> 5) ) ; + var g = Y - ( (Cb >> 2) + (Cb >> 4) + (Cb >> 5)) - ( (Cr >> 1) + (Cr >> 3) + (Cr >> 4) + (Cr >> 5)) ; + var b = Y + ( Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6)) ; + + img[qi ]=Math.max(0,Math.min(255,r)); + img[qi+1]=Math.max(0,Math.min(255,g)); + img[qi+2]=Math.max(0,Math.min(255,b)); + img[qi+3]=255; + } + } + } + else if(intp==32845) { + + function gamma(x) { return x < 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1.0 / 2.4) - 0.055; } + + for(var y=0; yma) { ma=ar; page=img; } + } + UTIF.decodeImage(buff, page, ifds); + var rgba = UTIF.toRGBA8(page), w=page.width, h=page.height; + + var cnv = document.createElement("canvas"); cnv.width=w; cnv.height=h; + var ctx = cnv.getContext("2d"); + var imgd = new ImageData(new Uint8ClampedArray(rgba.buffer),w,h); + ctx.putImageData(imgd,0,0); + return cnv.toDataURL(); + } + + + UTIF._binBE = + { + nextZero : function(data, o) { while(data[o]!=0) o++; return o; }, + readUshort : function(buff, p) { return (buff[p]<< 8) | buff[p+1]; }, + readShort : function(buff, p) { var a=UTIF._binBE.ui8; a[0]=buff[p+1]; a[1]=buff[p+0]; return UTIF._binBE. i16[0]; }, + readInt : function(buff, p) { var a=UTIF._binBE.ui8; a[0]=buff[p+3]; a[1]=buff[p+2]; a[2]=buff[p+1]; a[3]=buff[p+0]; return UTIF._binBE. i32[0]; }, + readUint : function(buff, p) { var a=UTIF._binBE.ui8; a[0]=buff[p+3]; a[1]=buff[p+2]; a[2]=buff[p+1]; a[3]=buff[p+0]; return UTIF._binBE.ui32[0]; }, + readASCII : function(buff, p, l) { var s = ""; for(var i=0; i> 8)&255; buff[p+1] = n&255; }, + writeInt : function(buff, p, n) { var a=UTIF._binBE.ui8; UTIF._binBE.i32[0]=n; buff[p+3]=a[0]; buff[p+2]=a[1]; buff[p+1]=a[2]; buff[p+0]=a[3]; }, + writeUint : function(buff, p, n) { buff[p] = (n>>24)&255; buff[p+1] = (n>>16)&255; buff[p+2] = (n>>8)&255; buff[p+3] = (n>>0)&255; }, + writeASCII : function(buff, p, s) { for(var i = 0; i < s.length; i++) buff[p+i] = s.charCodeAt(i); }, + writeDouble: function(buff, p, n) + { + UTIF._binBE.fl64[0] = n; + for (var i = 0; i < 8; i++) buff[p + i] = UTIF._binBE.ui8[7 - i]; + } + } + UTIF._binBE.ui8 = new Uint8Array (8); + UTIF._binBE.i16 = new Int16Array (UTIF._binBE.ui8.buffer); + UTIF._binBE.i32 = new Int32Array (UTIF._binBE.ui8.buffer); + UTIF._binBE.ui32 = new Uint32Array (UTIF._binBE.ui8.buffer); + UTIF._binBE.fl32 = new Float32Array(UTIF._binBE.ui8.buffer); + UTIF._binBE.fl64 = new Float64Array(UTIF._binBE.ui8.buffer); + + UTIF._binLE = + { + nextZero : UTIF._binBE.nextZero, + readUshort : function(buff, p) { return (buff[p+1]<< 8) | buff[p]; }, + readShort : function(buff, p) { var a=UTIF._binBE.ui8; a[0]=buff[p+0]; a[1]=buff[p+1]; return UTIF._binBE. i16[0]; }, + readInt : function(buff, p) { var a=UTIF._binBE.ui8; a[0]=buff[p+0]; a[1]=buff[p+1]; a[2]=buff[p+2]; a[3]=buff[p+3]; return UTIF._binBE. i32[0]; }, + readUint : function(buff, p) { var a=UTIF._binBE.ui8; a[0]=buff[p+0]; a[1]=buff[p+1]; a[2]=buff[p+2]; a[3]=buff[p+3]; return UTIF._binBE.ui32[0]; }, + readASCII : UTIF._binBE.readASCII, + readFloat : function(buff, p) { var a=UTIF._binBE.ui8; for(var i=0;i<4;i++) a[i]=buff[p+ i]; return UTIF._binBE.fl32[0]; }, + readDouble : function(buff, p) { var a=UTIF._binBE.ui8; for(var i=0;i<8;i++) a[i]=buff[p+ i]; return UTIF._binBE.fl64[0]; }, + + writeUshort: function(buff, p, n) { buff[p] = (n)&255; buff[p+1] = (n>>8)&255; }, + writeInt : function(buff, p, n) { var a=UTIF._binBE.ui8; UTIF._binBE.i32[0]=n; buff[p+0]=a[0]; buff[p+1]=a[1]; buff[p+2]=a[2]; buff[p+3]=a[3]; }, + writeUint : function(buff, p, n) { buff[p] = (n>>>0)&255; buff[p+1] = (n>>>8)&255; buff[p+2] = (n>>>16)&255; buff[p+3] = (n>>>24)&255; }, + writeASCII : UTIF._binBE.writeASCII + } + UTIF._copyTile = function(tb, tw, th, b, w, h, xoff, yoff) + { + //log("copyTile", tw, th, w, h, xoff, yoff); + var xlim = Math.min(tw, w-xoff); + var ylim = Math.min(th, h-yoff); + for(var y=0; y>--r&1; + X=g[X+y]}w[t]=X}}function P(l,A,g,K){if(l[A+3]!=255)return 0;if(g==0)return A;for(var t=0;t<2;t++){if(l[A+t]==0){l[A+t]=l.length; + l.push(0,0,K,255)}var F=P(l,l[A+t],g-1,K+1);if(F!=0)return F}return 0}function f(l){var A=l.b,g=l.a; + while(A<25&&l.e>>8;g=g<<8|K;A+=8}if(A<0)throw"e";l.b=A;l.a=g}function O(l,A){if(A.b>(A.b-=l)&65535>>16-l}function B(l,A){var g=l[0],K=0,t=255,F=0;if(A.b<16)f(A);var $=A.a>>A.b-8&255; + K=l[1][$];t=g[K+3];A.b-=g[K+2];while(t==255){F=A.a>>--A.b&1;K=g[K+F];t=g[K+3]}return t}function D(l,A){if(l<32768>>16-A)l+=-(1<>4,q&15]}}else if(M==65476){var m=_+X-2;while(_>>4];t[i[0]]=i.slice(1)}g=u();_+=2;break}else{_+=X-2}}var T=K>8?Uint16Array:Uint8Array,Y=new T(w*r*L),d={b:0,a:0,c:g==8,e:_,data:o,d:o.length}; + if(d.c)b(Y,r*L,d,$[0],w);else{var v=[],Q=0,C=0;for(var y=0;yQ)Q=s; + if(H>C)C=H;v.push(s*H)}if(Q!=1||C!=1){var E=[],c=0;for(var y=0;y>>1);else if(A==6)S=l[n]+(m-l[n-L]>>>1);else if(A==7)S=m+l[n]>>>1;else throw A; + l[q]+=S}}}}return x}(); + + + (function(){var G=0,F=1,i=2,b=3,J=4,N=5,E=6,s=7,c=8,T=9,a3=10,f=11,q=12,M=13,m=14,x=15,L=16,$=17,p=18; + function a5(t){var Z=UTIF._binBE.readUshort,u={b:Z(t,0),i:t[2],C:t[3],u:t[4],q:Z(t,5),k:Z(t,7),e:Z(t,9),l:Z(t,11),s:t[13],d:Z(t,14)}; + if(u.b!=18771||u.i>1||u.q<6||u.q%6||u.e<768||u.e%24||u.l!=768||u.k=u.l||u.s>16||u.s!=u.k/u.l||u.s!=Math.ceil(u.e/u.l)||u.d!=u.q/6||u.u!=12&&u.u!=14&&u.u!=16||u.C!=16&&u.C!=0){throw"Invalid data"}if(u.i==0){throw"Not implemented. We need this file!"}u.h=u.C==16; + u.m=(u.h?u.l*2/3:u.l>>>1)|0;u.A=u.m+2;u.f=64;u.g=(1<>>6);for(var e=0;e<3;e++){for(var Q=0; + Q<41;Q++){Z[e][Q]=[u,1]}}return Z}function a4(t){for(var Z=-1,u=0;!u;Z++){u=t[t.j]>>>7-t.a&1;t.a++;t.a&=7; + if(!t.a)t.j++}return Z}function K(t,Z){var u=0,e=8-t.a,Q=t.j,V=t.a;if(Z){if(Z>=e){do{u<<=e;Z-=e;u|=t[t.j]&(1<=8)}if(Z){u<<=Z;e-=Z;u|=t[t.j]>>>e&(1<n&&C>>2;if(o){w[X]=h;return}l=Z.t*Z.c[t.g+Y-H]+Z.c[t.g+g-Y]}else{h=Y>g&&Y>P||Y>>2:A+v>>>1; + l=Z.t*Z.c[t.g+Y-g]+Z.c[t.g+g-A]}R=y(l);var W=a4(u);if(W>>1):a>>>1; + O[R][0]+=y(a);if(O[R][1]==t.f){O[R][0]>>>=1;O[R][1]>>>=1}O[R][1]++;h=l<0?h-a:h+a;if(t.i){if(h<0)h+=Z.w; + else if(h>t.g)h-=Z.w}w[X]=h>=0?Math.min(h,t.g):0}function U(t,Z,u){var e=t[0].length;for(var Q=Z;Q<=u; + Q++){t[Q][0]=t[Q-1][1];t[Q][e-1]=t[Q-1][e-2]}}function B(t){U(t,s,q);U(t,i,J);U(t,x,$)}function _(t,Z,u,e,Q,V,O,o,X,k,j,I,a){var l=0,R=1,w=QJ; + while(R8){r(t,Z,u,e,Q,R,o[X]);r(t,Z,u,e,V,R,o[X]);R+=2}}B(e)}function a8(t,Z,u,e,Q,V){_(t,Z,u,e,i,s,Q,V,0,0,1,0,8); + _(t,Z,u,e,c,x,Q,V,1,0,1,0,8);_(t,Z,u,e,b,T,Q,V,2,1,0,3,0);_(t,Z,u,e,a3,L,Q,V,0,0,0,3,2);_(t,Z,u,e,J,f,Q,V,1,0,0,3,2); + _(t,Z,u,e,q,$,Q,V,2,1,0,3,0)}function a9(t,Z,u,e,Q,V){var O=V.length,o=t.l;if(Q+1==t.s)o=t.e-Q*t.l;var X=6*t.e*e+Q*t.l; + for(var k=0;k<6;k++){for(var j=0;j>>1)}else if(I==2){a=x+(k>>>1)}else{a=s+k}var l=t.h?(j*2/3&2147483646|j%3&1)+(j%3>>>1):j>>>1; + Z[X+j]=u[a][l+1]}X+=t.e}}UTIF._decompressRAF=function(t,Z){var u=a5(t),e=a7(t,u),Q=a2(u),V=new Int16Array(u.e*u.q); + if(Z==null){Z=u.h?[[1,1,0,1,1,2],[1,1,2,1,1,0],[2,0,1,0,2,1],[1,1,2,1,1,0],[1,1,0,1,1,2],[0,2,1,2,0,1]]:[[0,1],[3,2]]}var O=[[G,b],[F,J],[N,f],[E,q],[M,L],[m,$]],o=[]; + for(var X=0;XA.arrayBuffer()).then(A=>WebAssembly.instantiate(A,g)).then(this._init):WebAssembly.instantiate(Buffer.from(C,"base64"),g).then(this._init),A)}_init(A){I=A.instance,g.env.emscripten_notify_memory_growth(0)}decode(A,g=0){if(!I)throw new Error("ZSTDDecoder: Await .init() before decoding.");const Q=A.byteLength,C=I.exports.malloc(Q);B.set(A,C),g=g||Number(I.exports.ZSTD_findDecompressedSize(C,Q));const E=I.exports.malloc(g),i=I.exports.ZSTD_decompress(E,g,C,Q),D=B.slice(E,E+i);return I.exports.free(C),I.exports.free(E),D}}const C="AGFzbQEAAAABpQEVYAF/AX9gAn9/AGADf39/AX9gBX9/f39/AX9gAX8AYAJ/fwF/YAR/f39/AX9gA39/fwBgBn9/f39/fwF/YAd/f39/f39/AX9gAn9/AX5gAn5+AX5gAABgBX9/f39/AGAGf39/f39/AGAIf39/f39/f38AYAl/f39/f39/f38AYAABf2AIf39/f39/f38Bf2ANf39/f39/f39/f39/fwF/YAF/AX4CJwEDZW52H2Vtc2NyaXB0ZW5fbm90aWZ5X21lbW9yeV9ncm93dGgABANpaAEFAAAFAgEFCwACAQABAgIFBQcAAwABDgsBAQcAEhMHAAUBDAQEAAANBwQCAgYCBAgDAwMDBgEACQkHBgICAAYGAgQUBwYGAwIGAAMCAQgBBwUGCgoEEQAEBAEIAwgDBQgDEA8IAAcABAUBcAECAgUEAQCAAgYJAX8BQaCgwAILB2AHBm1lbW9yeQIABm1hbGxvYwAoBGZyZWUAJgxaU1REX2lzRXJyb3IAaBlaU1REX2ZpbmREZWNvbXByZXNzZWRTaXplAFQPWlNURF9kZWNvbXByZXNzAEoGX3N0YXJ0ACQJBwEAQQELASQKussBaA8AIAAgACgCBCABajYCBAsZACAAKAIAIAAoAgRBH3F0QQAgAWtBH3F2CwgAIABBiH9LC34BBH9BAyEBIAAoAgQiA0EgTQRAIAAoAggiASAAKAIQTwRAIAAQDQ8LIAAoAgwiAiABRgRAQQFBAiADQSBJGw8LIAAgASABIAJrIANBA3YiBCABIARrIAJJIgEbIgJrIgQ2AgggACADIAJBA3RrNgIEIAAgBCgAADYCAAsgAQsUAQF/IAAgARACIQIgACABEAEgAgv3AQECfyACRQRAIABCADcCACAAQQA2AhAgAEIANwIIQbh/DwsgACABNgIMIAAgAUEEajYCECACQQRPBEAgACABIAJqIgFBfGoiAzYCCCAAIAMoAAA2AgAgAUF/ai0AACIBBEAgAEEIIAEQFGs2AgQgAg8LIABBADYCBEF/DwsgACABNgIIIAAgAS0AACIDNgIAIAJBfmoiBEEBTQRAIARBAWtFBEAgACABLQACQRB0IANyIgM2AgALIAAgAS0AAUEIdCADajYCAAsgASACakF/ai0AACIBRQRAIABBADYCBEFsDwsgAEEoIAEQFCACQQN0ams2AgQgAgsWACAAIAEpAAA3AAAgACABKQAINwAICy8BAX8gAUECdEGgHWooAgAgACgCAEEgIAEgACgCBGprQR9xdnEhAiAAIAEQASACCyEAIAFCz9bTvtLHq9lCfiAAfEIfiUKHla+vmLbem55/fgsdAQF/IAAoAgggACgCDEYEfyAAKAIEQSBGBUEACwuCBAEDfyACQYDAAE8EQCAAIAEgAhBnIAAPCyAAIAJqIQMCQCAAIAFzQQNxRQRAAkAgAkEBSARAIAAhAgwBCyAAQQNxRQRAIAAhAgwBCyAAIQIDQCACIAEtAAA6AAAgAUEBaiEBIAJBAWoiAiADTw0BIAJBA3ENAAsLAkAgA0F8cSIEQcAASQ0AIAIgBEFAaiIFSw0AA0AgAiABKAIANgIAIAIgASgCBDYCBCACIAEoAgg2AgggAiABKAIMNgIMIAIgASgCEDYCECACIAEoAhQ2AhQgAiABKAIYNgIYIAIgASgCHDYCHCACIAEoAiA2AiAgAiABKAIkNgIkIAIgASgCKDYCKCACIAEoAiw2AiwgAiABKAIwNgIwIAIgASgCNDYCNCACIAEoAjg2AjggAiABKAI8NgI8IAFBQGshASACQUBrIgIgBU0NAAsLIAIgBE8NAQNAIAIgASgCADYCACABQQRqIQEgAkEEaiICIARJDQALDAELIANBBEkEQCAAIQIMAQsgA0F8aiIEIABJBEAgACECDAELIAAhAgNAIAIgAS0AADoAACACIAEtAAE6AAEgAiABLQACOgACIAIgAS0AAzoAAyABQQRqIQEgAkEEaiICIARNDQALCyACIANJBEADQCACIAEtAAA6AAAgAUEBaiEBIAJBAWoiAiADRw0ACwsgAAsMACAAIAEpAAA3AAALQQECfyAAKAIIIgEgACgCEEkEQEEDDwsgACAAKAIEIgJBB3E2AgQgACABIAJBA3ZrIgE2AgggACABKAAANgIAQQALDAAgACABKAIANgAAC/cCAQJ/AkAgACABRg0AAkAgASACaiAASwRAIAAgAmoiBCABSw0BCyAAIAEgAhALDwsgACABc0EDcSEDAkACQCAAIAFJBEAgAwRAIAAhAwwDCyAAQQNxRQRAIAAhAwwCCyAAIQMDQCACRQ0EIAMgAS0AADoAACABQQFqIQEgAkF/aiECIANBAWoiA0EDcQ0ACwwBCwJAIAMNACAEQQNxBEADQCACRQ0FIAAgAkF/aiICaiIDIAEgAmotAAA6AAAgA0EDcQ0ACwsgAkEDTQ0AA0AgACACQXxqIgJqIAEgAmooAgA2AgAgAkEDSw0ACwsgAkUNAgNAIAAgAkF/aiICaiABIAJqLQAAOgAAIAINAAsMAgsgAkEDTQ0AIAIhBANAIAMgASgCADYCACABQQRqIQEgA0EEaiEDIARBfGoiBEEDSw0ACyACQQNxIQILIAJFDQADQCADIAEtAAA6AAAgA0EBaiEDIAFBAWohASACQX9qIgINAAsLIAAL8wICAn8BfgJAIAJFDQAgACACaiIDQX9qIAE6AAAgACABOgAAIAJBA0kNACADQX5qIAE6AAAgACABOgABIANBfWogAToAACAAIAE6AAIgAkEHSQ0AIANBfGogAToAACAAIAE6AAMgAkEJSQ0AIABBACAAa0EDcSIEaiIDIAFB/wFxQYGChAhsIgE2AgAgAyACIARrQXxxIgRqIgJBfGogATYCACAEQQlJDQAgAyABNgIIIAMgATYCBCACQXhqIAE2AgAgAkF0aiABNgIAIARBGUkNACADIAE2AhggAyABNgIUIAMgATYCECADIAE2AgwgAkFwaiABNgIAIAJBbGogATYCACACQWhqIAE2AgAgAkFkaiABNgIAIAQgA0EEcUEYciIEayICQSBJDQAgAa0iBUIghiAFhCEFIAMgBGohAQNAIAEgBTcDGCABIAU3AxAgASAFNwMIIAEgBTcDACABQSBqIQEgAkFgaiICQR9LDQALCyAACy8BAn8gACgCBCAAKAIAQQJ0aiICLQACIQMgACACLwEAIAEgAi0AAxAIajYCACADCy8BAn8gACgCBCAAKAIAQQJ0aiICLQACIQMgACACLwEAIAEgAi0AAxAFajYCACADCx8AIAAgASACKAIEEAg2AgAgARAEGiAAIAJBCGo2AgQLCAAgAGdBH3MLugUBDX8jAEEQayIKJAACfyAEQQNNBEAgCkEANgIMIApBDGogAyAEEAsaIAAgASACIApBDGpBBBAVIgBBbCAAEAMbIAAgACAESxsMAQsgAEEAIAEoAgBBAXRBAmoQECENQVQgAygAACIGQQ9xIgBBCksNABogAiAAQQVqNgIAIAMgBGoiAkF8aiEMIAJBeWohDiACQXtqIRAgAEEGaiELQQQhBSAGQQR2IQRBICAAdCIAQQFyIQkgASgCACEPQQAhAiADIQYCQANAIAlBAkggAiAPS3JFBEAgAiEHAkAgCARAA0AgBEH//wNxQf//A0YEQCAHQRhqIQcgBiAQSQR/IAZBAmoiBigAACAFdgUgBUEQaiEFIARBEHYLIQQMAQsLA0AgBEEDcSIIQQNGBEAgBUECaiEFIARBAnYhBCAHQQNqIQcMAQsLIAcgCGoiByAPSw0EIAVBAmohBQNAIAIgB0kEQCANIAJBAXRqQQA7AQAgAkEBaiECDAELCyAGIA5LQQAgBiAFQQN1aiIHIAxLG0UEQCAHKAAAIAVBB3EiBXYhBAwCCyAEQQJ2IQQLIAYhBwsCfyALQX9qIAQgAEF/anEiBiAAQQF0QX9qIgggCWsiEUkNABogBCAIcSIEQQAgESAEIABIG2shBiALCyEIIA0gAkEBdGogBkF/aiIEOwEAIAlBASAGayAEIAZBAUgbayEJA0AgCSAASARAIABBAXUhACALQX9qIQsMAQsLAn8gByAOS0EAIAcgBSAIaiIFQQN1aiIGIAxLG0UEQCAFQQdxDAELIAUgDCIGIAdrQQN0awshBSACQQFqIQIgBEUhCCAGKAAAIAVBH3F2IQQMAQsLQWwgCUEBRyAFQSBKcg0BGiABIAJBf2o2AgAgBiAFQQdqQQN1aiADawwBC0FQCyEAIApBEGokACAACwkAQQFBBSAAGwsMACAAIAEoAAA2AAALqgMBCn8jAEHwAGsiCiQAIAJBAWohDiAAQQhqIQtBgIAEIAVBf2p0QRB1IQxBACECQQEhBkEBIAV0IglBf2oiDyEIA0AgAiAORkUEQAJAIAEgAkEBdCINai8BACIHQf//A0YEQCALIAhBA3RqIAI2AgQgCEF/aiEIQQEhBwwBCyAGQQAgDCAHQRB0QRB1ShshBgsgCiANaiAHOwEAIAJBAWohAgwBCwsgACAFNgIEIAAgBjYCACAJQQN2IAlBAXZqQQNqIQxBACEAQQAhBkEAIQIDQCAGIA5GBEADQAJAIAAgCUYNACAKIAsgAEEDdGoiASgCBCIGQQF0aiICIAIvAQAiAkEBajsBACABIAUgAhAUayIIOgADIAEgAiAIQf8BcXQgCWs7AQAgASAEIAZBAnQiAmooAgA6AAIgASACIANqKAIANgIEIABBAWohAAwBCwsFIAEgBkEBdGouAQAhDUEAIQcDQCAHIA1ORQRAIAsgAkEDdGogBjYCBANAIAIgDGogD3EiAiAISw0ACyAHQQFqIQcMAQsLIAZBAWohBgwBCwsgCkHwAGokAAsjAEIAIAEQCSAAhUKHla+vmLbem55/fkLj3MqV/M7y9YV/fAsQACAAQn43AwggACABNgIACyQBAX8gAARAIAEoAgQiAgRAIAEoAgggACACEQEADwsgABAmCwsfACAAIAEgAi8BABAINgIAIAEQBBogACACQQRqNgIEC0oBAX9BoCAoAgAiASAAaiIAQX9MBEBBiCBBMDYCAEF/DwsCQCAAPwBBEHRNDQAgABBmDQBBiCBBMDYCAEF/DwtBoCAgADYCACABC9cBAQh/Qbp/IQoCQCACKAIEIgggAigCACIJaiIOIAEgAGtLDQBBbCEKIAkgBCADKAIAIgtrSw0AIAAgCWoiBCACKAIIIgxrIQ0gACABQWBqIg8gCyAJQQAQKSADIAkgC2o2AgACQAJAIAwgBCAFa00EQCANIQUMAQsgDCAEIAZrSw0CIAcgDSAFayIAaiIBIAhqIAdNBEAgBCABIAgQDxoMAgsgBCABQQAgAGsQDyEBIAIgACAIaiIINgIEIAEgAGshBAsgBCAPIAUgCEEBECkLIA4hCgsgCgubAgEBfyMAQYABayINJAAgDSADNgJ8AkAgAkEDSwRAQX8hCQwBCwJAAkACQAJAIAJBAWsOAwADAgELIAZFBEBBuH8hCQwEC0FsIQkgBS0AACICIANLDQMgACAHIAJBAnQiAmooAgAgAiAIaigCABA7IAEgADYCAEEBIQkMAwsgASAJNgIAQQAhCQwCCyAKRQRAQWwhCQwCC0EAIQkgC0UgDEEZSHINAUEIIAR0QQhqIQBBACECA0AgAiAATw0CIAJBQGshAgwAAAsAC0FsIQkgDSANQfwAaiANQfgAaiAFIAYQFSICEAMNACANKAJ4IgMgBEsNACAAIA0gDSgCfCAHIAggAxAYIAEgADYCACACIQkLIA1BgAFqJAAgCQsLACAAIAEgAhALGgsQACAALwAAIAAtAAJBEHRyCy8AAn9BuH8gAUEISQ0AGkFyIAAoAAQiAEF3Sw0AGkG4fyAAQQhqIgAgACABSxsLCwkAIAAgATsAAAsDAAELigYBBX8gACAAKAIAIgVBfnE2AgBBACAAIAVBAXZqQYQgKAIAIgQgAEYbIQECQAJAIAAoAgQiAkUNACACKAIAIgNBAXENACACQQhqIgUgA0EBdkF4aiIDQQggA0EISxtnQR9zQQJ0QYAfaiIDKAIARgRAIAMgAigCDDYCAAsgAigCCCIDBEAgAyACKAIMNgIECyACKAIMIgMEQCADIAIoAgg2AgALIAIgAigCACAAKAIAQX5xajYCAEGEICEAAkACQCABRQ0AIAEgAjYCBCABKAIAIgNBAXENASADQQF2QXhqIgNBCCADQQhLG2dBH3NBAnRBgB9qIgMoAgAgAUEIakYEQCADIAEoAgw2AgALIAEoAggiAwRAIAMgASgCDDYCBAsgASgCDCIDBEAgAyABKAIINgIAQYQgKAIAIQQLIAIgAigCACABKAIAQX5xajYCACABIARGDQAgASABKAIAQQF2akEEaiEACyAAIAI2AgALIAIoAgBBAXZBeGoiAEEIIABBCEsbZ0Efc0ECdEGAH2oiASgCACEAIAEgBTYCACACIAA2AgwgAkEANgIIIABFDQEgACAFNgIADwsCQCABRQ0AIAEoAgAiAkEBcQ0AIAJBAXZBeGoiAkEIIAJBCEsbZ0Efc0ECdEGAH2oiAigCACABQQhqRgRAIAIgASgCDDYCAAsgASgCCCICBEAgAiABKAIMNgIECyABKAIMIgIEQCACIAEoAgg2AgBBhCAoAgAhBAsgACAAKAIAIAEoAgBBfnFqIgI2AgACQCABIARHBEAgASABKAIAQQF2aiAANgIEIAAoAgAhAgwBC0GEICAANgIACyACQQF2QXhqIgFBCCABQQhLG2dBH3NBAnRBgB9qIgIoAgAhASACIABBCGoiAjYCACAAIAE2AgwgAEEANgIIIAFFDQEgASACNgIADwsgBUEBdkF4aiIBQQggAUEISxtnQR9zQQJ0QYAfaiICKAIAIQEgAiAAQQhqIgI2AgAgACABNgIMIABBADYCCCABRQ0AIAEgAjYCAAsLDgAgAARAIABBeGoQJQsLgAIBA38CQCAAQQ9qQXhxQYQgKAIAKAIAQQF2ayICEB1Bf0YNAAJAQYQgKAIAIgAoAgAiAUEBcQ0AIAFBAXZBeGoiAUEIIAFBCEsbZ0Efc0ECdEGAH2oiASgCACAAQQhqRgRAIAEgACgCDDYCAAsgACgCCCIBBEAgASAAKAIMNgIECyAAKAIMIgFFDQAgASAAKAIINgIAC0EBIQEgACAAKAIAIAJBAXRqIgI2AgAgAkEBcQ0AIAJBAXZBeGoiAkEIIAJBCEsbZ0Efc0ECdEGAH2oiAygCACECIAMgAEEIaiIDNgIAIAAgAjYCDCAAQQA2AgggAkUNACACIAM2AgALIAELtwIBA38CQAJAIABBASAAGyICEDgiAA0AAkACQEGEICgCACIARQ0AIAAoAgAiA0EBcQ0AIAAgA0EBcjYCACADQQF2QXhqIgFBCCABQQhLG2dBH3NBAnRBgB9qIgEoAgAgAEEIakYEQCABIAAoAgw2AgALIAAoAggiAQRAIAEgACgCDDYCBAsgACgCDCIBBEAgASAAKAIINgIACyACECchAkEAIQFBhCAoAgAhACACDQEgACAAKAIAQX5xNgIAQQAPCyACQQ9qQXhxIgMQHSICQX9GDQIgAkEHakF4cSIAIAJHBEAgACACaxAdQX9GDQMLAkBBhCAoAgAiAUUEQEGAICAANgIADAELIAAgATYCBAtBhCAgADYCACAAIANBAXRBAXI2AgAMAQsgAEUNAQsgAEEIaiEBCyABC7kDAQJ/IAAgA2ohBQJAIANBB0wEQANAIAAgBU8NAiAAIAItAAA6AAAgAEEBaiEAIAJBAWohAgwAAAsACyAEQQFGBEACQCAAIAJrIgZBB00EQCAAIAItAAA6AAAgACACLQABOgABIAAgAi0AAjoAAiAAIAItAAM6AAMgAEEEaiACIAZBAnQiBkHAHmooAgBqIgIQFyACIAZB4B5qKAIAayECDAELIAAgAhAMCyACQQhqIQIgAEEIaiEACwJAAkACQAJAIAUgAU0EQCAAIANqIQEgBEEBRyAAIAJrQQ9Kcg0BA0AgACACEAwgAkEIaiECIABBCGoiACABSQ0ACwwFCyAAIAFLBEAgACEBDAQLIARBAUcgACACa0EPSnINASAAIQMgAiEEA0AgAyAEEAwgBEEIaiEEIANBCGoiAyABSQ0ACwwCCwNAIAAgAhAHIAJBEGohAiAAQRBqIgAgAUkNAAsMAwsgACEDIAIhBANAIAMgBBAHIARBEGohBCADQRBqIgMgAUkNAAsLIAIgASAAa2ohAgsDQCABIAVPDQEgASACLQAAOgAAIAFBAWohASACQQFqIQIMAAALAAsLQQECfyAAIAAoArjgASIDNgLE4AEgACgCvOABIQQgACABNgK84AEgACABIAJqNgK44AEgACABIAQgA2tqNgLA4AELpgEBAX8gACAAKALs4QEQFjYCyOABIABCADcD+OABIABCADcDuOABIABBwOABakIANwMAIABBqNAAaiIBQYyAgOAANgIAIABBADYCmOIBIABCADcDiOEBIABCAzcDgOEBIABBrNABakHgEikCADcCACAAQbTQAWpB6BIoAgA2AgAgACABNgIMIAAgAEGYIGo2AgggACAAQaAwajYCBCAAIABBEGo2AgALYQEBf0G4fyEDAkAgAUEDSQ0AIAIgABAhIgFBA3YiADYCCCACIAFBAXE2AgQgAiABQQF2QQNxIgM2AgACQCADQX9qIgFBAksNAAJAIAFBAWsOAgEAAgtBbA8LIAAhAwsgAwsMACAAIAEgAkEAEC4LiAQCA38CfiADEBYhBCAAQQBBKBAQIQAgBCACSwRAIAQPCyABRQRAQX8PCwJAAkAgA0EBRg0AIAEoAAAiBkGo6r5pRg0AQXYhAyAGQXBxQdDUtMIBRw0BQQghAyACQQhJDQEgAEEAQSgQECEAIAEoAAQhASAAQQE2AhQgACABrTcDAEEADwsgASACIAMQLyIDIAJLDQAgACADNgIYQXIhAyABIARqIgVBf2otAAAiAkEIcQ0AIAJBIHEiBkUEQEFwIQMgBS0AACIFQacBSw0BIAVBB3GtQgEgBUEDdkEKaq2GIgdCA4h+IAd8IQggBEEBaiEECyACQQZ2IQMgAkECdiEFAkAgAkEDcUF/aiICQQJLBEBBACECDAELAkACQAJAIAJBAWsOAgECAAsgASAEai0AACECIARBAWohBAwCCyABIARqLwAAIQIgBEECaiEEDAELIAEgBGooAAAhAiAEQQRqIQQLIAVBAXEhBQJ+AkACQAJAIANBf2oiA0ECTQRAIANBAWsOAgIDAQtCfyAGRQ0DGiABIARqMQAADAMLIAEgBGovAACtQoACfAwCCyABIARqKAAArQwBCyABIARqKQAACyEHIAAgBTYCICAAIAI2AhwgACAHNwMAQQAhAyAAQQA2AhQgACAHIAggBhsiBzcDCCAAIAdCgIAIIAdCgIAIVBs+AhALIAMLWwEBf0G4fyEDIAIQFiICIAFNBH8gACACakF/ai0AACIAQQNxQQJ0QaAeaigCACACaiAAQQZ2IgFBAnRBsB5qKAIAaiAAQSBxIgBFaiABRSAAQQV2cWoFQbh/CwsdACAAKAKQ4gEQWiAAQQA2AqDiASAAQgA3A5DiAQu1AwEFfyMAQZACayIKJABBuH8hBgJAIAVFDQAgBCwAACIIQf8BcSEHAkAgCEF/TARAIAdBgn9qQQF2IgggBU8NAkFsIQYgB0GBf2oiBUGAAk8NAiAEQQFqIQdBACEGA0AgBiAFTwRAIAUhBiAIIQcMAwUgACAGaiAHIAZBAXZqIgQtAABBBHY6AAAgACAGQQFyaiAELQAAQQ9xOgAAIAZBAmohBgwBCwAACwALIAcgBU8NASAAIARBAWogByAKEFMiBhADDQELIAYhBEEAIQYgAUEAQTQQECEJQQAhBQNAIAQgBkcEQCAAIAZqIggtAAAiAUELSwRAQWwhBgwDBSAJIAFBAnRqIgEgASgCAEEBajYCACAGQQFqIQZBASAILQAAdEEBdSAFaiEFDAILAAsLQWwhBiAFRQ0AIAUQFEEBaiIBQQxLDQAgAyABNgIAQQFBASABdCAFayIDEBQiAXQgA0cNACAAIARqIAFBAWoiADoAACAJIABBAnRqIgAgACgCAEEBajYCACAJKAIEIgBBAkkgAEEBcXINACACIARBAWo2AgAgB0EBaiEGCyAKQZACaiQAIAYLxhEBDH8jAEHwAGsiBSQAQWwhCwJAIANBCkkNACACLwAAIQogAi8AAiEJIAIvAAQhByAFQQhqIAQQDgJAIAMgByAJIApqakEGaiIMSQ0AIAUtAAohCCAFQdgAaiACQQZqIgIgChAGIgsQAw0BIAVBQGsgAiAKaiICIAkQBiILEAMNASAFQShqIAIgCWoiAiAHEAYiCxADDQEgBUEQaiACIAdqIAMgDGsQBiILEAMNASAAIAFqIg9BfWohECAEQQRqIQZBASELIAAgAUEDakECdiIDaiIMIANqIgIgA2oiDiEDIAIhBCAMIQcDQCALIAMgEElxBEAgACAGIAVB2ABqIAgQAkECdGoiCS8BADsAACAFQdgAaiAJLQACEAEgCS0AAyELIAcgBiAFQUBrIAgQAkECdGoiCS8BADsAACAFQUBrIAktAAIQASAJLQADIQogBCAGIAVBKGogCBACQQJ0aiIJLwEAOwAAIAVBKGogCS0AAhABIAktAAMhCSADIAYgBUEQaiAIEAJBAnRqIg0vAQA7AAAgBUEQaiANLQACEAEgDS0AAyENIAAgC2oiCyAGIAVB2ABqIAgQAkECdGoiAC8BADsAACAFQdgAaiAALQACEAEgAC0AAyEAIAcgCmoiCiAGIAVBQGsgCBACQQJ0aiIHLwEAOwAAIAVBQGsgBy0AAhABIActAAMhByAEIAlqIgkgBiAFQShqIAgQAkECdGoiBC8BADsAACAFQShqIAQtAAIQASAELQADIQQgAyANaiIDIAYgBUEQaiAIEAJBAnRqIg0vAQA7AAAgBUEQaiANLQACEAEgACALaiEAIAcgCmohByAEIAlqIQQgAyANLQADaiEDIAVB2ABqEA0gBUFAaxANciAFQShqEA1yIAVBEGoQDXJFIQsMAQsLIAQgDksgByACS3INAEFsIQsgACAMSw0BIAxBfWohCQNAQQAgACAJSSAFQdgAahAEGwRAIAAgBiAFQdgAaiAIEAJBAnRqIgovAQA7AAAgBUHYAGogCi0AAhABIAAgCi0AA2oiACAGIAVB2ABqIAgQAkECdGoiCi8BADsAACAFQdgAaiAKLQACEAEgACAKLQADaiEADAEFIAxBfmohCgNAIAVB2ABqEAQgACAKS3JFBEAgACAGIAVB2ABqIAgQAkECdGoiCS8BADsAACAFQdgAaiAJLQACEAEgACAJLQADaiEADAELCwNAIAAgCk0EQCAAIAYgBUHYAGogCBACQQJ0aiIJLwEAOwAAIAVB2ABqIAktAAIQASAAIAktAANqIQAMAQsLAkAgACAMTw0AIAAgBiAFQdgAaiAIEAIiAEECdGoiDC0AADoAACAMLQADQQFGBEAgBUHYAGogDC0AAhABDAELIAUoAlxBH0sNACAFQdgAaiAGIABBAnRqLQACEAEgBSgCXEEhSQ0AIAVBIDYCXAsgAkF9aiEMA0BBACAHIAxJIAVBQGsQBBsEQCAHIAYgBUFAayAIEAJBAnRqIgAvAQA7AAAgBUFAayAALQACEAEgByAALQADaiIAIAYgBUFAayAIEAJBAnRqIgcvAQA7AAAgBUFAayAHLQACEAEgACAHLQADaiEHDAEFIAJBfmohDANAIAVBQGsQBCAHIAxLckUEQCAHIAYgBUFAayAIEAJBAnRqIgAvAQA7AAAgBUFAayAALQACEAEgByAALQADaiEHDAELCwNAIAcgDE0EQCAHIAYgBUFAayAIEAJBAnRqIgAvAQA7AAAgBUFAayAALQACEAEgByAALQADaiEHDAELCwJAIAcgAk8NACAHIAYgBUFAayAIEAIiAEECdGoiAi0AADoAACACLQADQQFGBEAgBUFAayACLQACEAEMAQsgBSgCREEfSw0AIAVBQGsgBiAAQQJ0ai0AAhABIAUoAkRBIUkNACAFQSA2AkQLIA5BfWohAgNAQQAgBCACSSAFQShqEAQbBEAgBCAGIAVBKGogCBACQQJ0aiIALwEAOwAAIAVBKGogAC0AAhABIAQgAC0AA2oiACAGIAVBKGogCBACQQJ0aiIELwEAOwAAIAVBKGogBC0AAhABIAAgBC0AA2ohBAwBBSAOQX5qIQIDQCAFQShqEAQgBCACS3JFBEAgBCAGIAVBKGogCBACQQJ0aiIALwEAOwAAIAVBKGogAC0AAhABIAQgAC0AA2ohBAwBCwsDQCAEIAJNBEAgBCAGIAVBKGogCBACQQJ0aiIALwEAOwAAIAVBKGogAC0AAhABIAQgAC0AA2ohBAwBCwsCQCAEIA5PDQAgBCAGIAVBKGogCBACIgBBAnRqIgItAAA6AAAgAi0AA0EBRgRAIAVBKGogAi0AAhABDAELIAUoAixBH0sNACAFQShqIAYgAEECdGotAAIQASAFKAIsQSFJDQAgBUEgNgIsCwNAQQAgAyAQSSAFQRBqEAQbBEAgAyAGIAVBEGogCBACQQJ0aiIALwEAOwAAIAVBEGogAC0AAhABIAMgAC0AA2oiACAGIAVBEGogCBACQQJ0aiICLwEAOwAAIAVBEGogAi0AAhABIAAgAi0AA2ohAwwBBSAPQX5qIQIDQCAFQRBqEAQgAyACS3JFBEAgAyAGIAVBEGogCBACQQJ0aiIALwEAOwAAIAVBEGogAC0AAhABIAMgAC0AA2ohAwwBCwsDQCADIAJNBEAgAyAGIAVBEGogCBACQQJ0aiIALwEAOwAAIAVBEGogAC0AAhABIAMgAC0AA2ohAwwBCwsCQCADIA9PDQAgAyAGIAVBEGogCBACIgBBAnRqIgItAAA6AAAgAi0AA0EBRgRAIAVBEGogAi0AAhABDAELIAUoAhRBH0sNACAFQRBqIAYgAEECdGotAAIQASAFKAIUQSFJDQAgBUEgNgIUCyABQWwgBUHYAGoQCiAFQUBrEApxIAVBKGoQCnEgBUEQahAKcRshCwwJCwAACwALAAALAAsAAAsACwAACwALQWwhCwsgBUHwAGokACALC7UEAQ5/IwBBEGsiBiQAIAZBBGogABAOQVQhBQJAIARB3AtJDQAgBi0ABCEHIANB8ARqQQBB7AAQECEIIAdBDEsNACADQdwJaiIJIAggBkEIaiAGQQxqIAEgAhAxIhAQA0UEQCAGKAIMIgQgB0sNASADQdwFaiEPIANBpAVqIREgAEEEaiESIANBqAVqIQEgBCEFA0AgBSICQX9qIQUgCCACQQJ0aigCAEUNAAsgAkEBaiEOQQEhBQNAIAUgDk9FBEAgCCAFQQJ0IgtqKAIAIQwgASALaiAKNgIAIAVBAWohBSAKIAxqIQoMAQsLIAEgCjYCAEEAIQUgBigCCCELA0AgBSALRkUEQCABIAUgCWotAAAiDEECdGoiDSANKAIAIg1BAWo2AgAgDyANQQF0aiINIAw6AAEgDSAFOgAAIAVBAWohBQwBCwtBACEBIANBADYCqAUgBEF/cyAHaiEJQQEhBQNAIAUgDk9FBEAgCCAFQQJ0IgtqKAIAIQwgAyALaiABNgIAIAwgBSAJanQgAWohASAFQQFqIQUMAQsLIAcgBEEBaiIBIAJrIgRrQQFqIQgDQEEBIQUgBCAIT0UEQANAIAUgDk9FBEAgBUECdCIJIAMgBEE0bGpqIAMgCWooAgAgBHY2AgAgBUEBaiEFDAELCyAEQQFqIQQMAQsLIBIgByAPIAogESADIAIgARBkIAZBAToABSAGIAc6AAYgACAGKAIENgIACyAQIQULIAZBEGokACAFC8ENAQt/IwBB8ABrIgUkAEFsIQkCQCADQQpJDQAgAi8AACEKIAIvAAIhDCACLwAEIQYgBUEIaiAEEA4CQCADIAYgCiAMampBBmoiDUkNACAFLQAKIQcgBUHYAGogAkEGaiICIAoQBiIJEAMNASAFQUBrIAIgCmoiAiAMEAYiCRADDQEgBUEoaiACIAxqIgIgBhAGIgkQAw0BIAVBEGogAiAGaiADIA1rEAYiCRADDQEgACABaiIOQX1qIQ8gBEEEaiEGQQEhCSAAIAFBA2pBAnYiAmoiCiACaiIMIAJqIg0hAyAMIQQgCiECA0AgCSADIA9JcQRAIAYgBUHYAGogBxACQQF0aiIILQAAIQsgBUHYAGogCC0AARABIAAgCzoAACAGIAVBQGsgBxACQQF0aiIILQAAIQsgBUFAayAILQABEAEgAiALOgAAIAYgBUEoaiAHEAJBAXRqIggtAAAhCyAFQShqIAgtAAEQASAEIAs6AAAgBiAFQRBqIAcQAkEBdGoiCC0AACELIAVBEGogCC0AARABIAMgCzoAACAGIAVB2ABqIAcQAkEBdGoiCC0AACELIAVB2ABqIAgtAAEQASAAIAs6AAEgBiAFQUBrIAcQAkEBdGoiCC0AACELIAVBQGsgCC0AARABIAIgCzoAASAGIAVBKGogBxACQQF0aiIILQAAIQsgBUEoaiAILQABEAEgBCALOgABIAYgBUEQaiAHEAJBAXRqIggtAAAhCyAFQRBqIAgtAAEQASADIAs6AAEgA0ECaiEDIARBAmohBCACQQJqIQIgAEECaiEAIAkgBUHYAGoQDUVxIAVBQGsQDUVxIAVBKGoQDUVxIAVBEGoQDUVxIQkMAQsLIAQgDUsgAiAMS3INAEFsIQkgACAKSw0BIApBfWohCQNAIAVB2ABqEAQgACAJT3JFBEAgBiAFQdgAaiAHEAJBAXRqIggtAAAhCyAFQdgAaiAILQABEAEgACALOgAAIAYgBUHYAGogBxACQQF0aiIILQAAIQsgBUHYAGogCC0AARABIAAgCzoAASAAQQJqIQAMAQsLA0AgBUHYAGoQBCAAIApPckUEQCAGIAVB2ABqIAcQAkEBdGoiCS0AACEIIAVB2ABqIAktAAEQASAAIAg6AAAgAEEBaiEADAELCwNAIAAgCkkEQCAGIAVB2ABqIAcQAkEBdGoiCS0AACEIIAVB2ABqIAktAAEQASAAIAg6AAAgAEEBaiEADAELCyAMQX1qIQADQCAFQUBrEAQgAiAAT3JFBEAgBiAFQUBrIAcQAkEBdGoiCi0AACEJIAVBQGsgCi0AARABIAIgCToAACAGIAVBQGsgBxACQQF0aiIKLQAAIQkgBUFAayAKLQABEAEgAiAJOgABIAJBAmohAgwBCwsDQCAFQUBrEAQgAiAMT3JFBEAgBiAFQUBrIAcQAkEBdGoiAC0AACEKIAVBQGsgAC0AARABIAIgCjoAACACQQFqIQIMAQsLA0AgAiAMSQRAIAYgBUFAayAHEAJBAXRqIgAtAAAhCiAFQUBrIAAtAAEQASACIAo6AAAgAkEBaiECDAELCyANQX1qIQADQCAFQShqEAQgBCAAT3JFBEAgBiAFQShqIAcQAkEBdGoiAi0AACEKIAVBKGogAi0AARABIAQgCjoAACAGIAVBKGogBxACQQF0aiICLQAAIQogBUEoaiACLQABEAEgBCAKOgABIARBAmohBAwBCwsDQCAFQShqEAQgBCANT3JFBEAgBiAFQShqIAcQAkEBdGoiAC0AACECIAVBKGogAC0AARABIAQgAjoAACAEQQFqIQQMAQsLA0AgBCANSQRAIAYgBUEoaiAHEAJBAXRqIgAtAAAhAiAFQShqIAAtAAEQASAEIAI6AAAgBEEBaiEEDAELCwNAIAVBEGoQBCADIA9PckUEQCAGIAVBEGogBxACQQF0aiIALQAAIQIgBUEQaiAALQABEAEgAyACOgAAIAYgBUEQaiAHEAJBAXRqIgAtAAAhAiAFQRBqIAAtAAEQASADIAI6AAEgA0ECaiEDDAELCwNAIAVBEGoQBCADIA5PckUEQCAGIAVBEGogBxACQQF0aiIALQAAIQIgBUEQaiAALQABEAEgAyACOgAAIANBAWohAwwBCwsDQCADIA5JBEAgBiAFQRBqIAcQAkEBdGoiAC0AACECIAVBEGogAC0AARABIAMgAjoAACADQQFqIQMMAQsLIAFBbCAFQdgAahAKIAVBQGsQCnEgBUEoahAKcSAFQRBqEApxGyEJDAELQWwhCQsgBUHwAGokACAJC8oCAQR/IwBBIGsiBSQAIAUgBBAOIAUtAAIhByAFQQhqIAIgAxAGIgIQA0UEQCAEQQRqIQIgACABaiIDQX1qIQQDQCAFQQhqEAQgACAET3JFBEAgAiAFQQhqIAcQAkEBdGoiBi0AACEIIAVBCGogBi0AARABIAAgCDoAACACIAVBCGogBxACQQF0aiIGLQAAIQggBUEIaiAGLQABEAEgACAIOgABIABBAmohAAwBCwsDQCAFQQhqEAQgACADT3JFBEAgAiAFQQhqIAcQAkEBdGoiBC0AACEGIAVBCGogBC0AARABIAAgBjoAACAAQQFqIQAMAQsLA0AgACADT0UEQCACIAVBCGogBxACQQF0aiIELQAAIQYgBUEIaiAELQABEAEgACAGOgAAIABBAWohAAwBCwsgAUFsIAVBCGoQChshAgsgBUEgaiQAIAILtgMBCX8jAEEQayIGJAAgBkEANgIMIAZBADYCCEFUIQQCQAJAIANBQGsiDCADIAZBCGogBkEMaiABIAIQMSICEAMNACAGQQRqIAAQDiAGKAIMIgcgBi0ABEEBaksNASAAQQRqIQogBkEAOgAFIAYgBzoABiAAIAYoAgQ2AgAgB0EBaiEJQQEhBANAIAQgCUkEQCADIARBAnRqIgEoAgAhACABIAU2AgAgACAEQX9qdCAFaiEFIARBAWohBAwBCwsgB0EBaiEHQQAhBSAGKAIIIQkDQCAFIAlGDQEgAyAFIAxqLQAAIgRBAnRqIgBBASAEdEEBdSILIAAoAgAiAWoiADYCACAHIARrIQhBACEEAkAgC0EDTQRAA0AgBCALRg0CIAogASAEakEBdGoiACAIOgABIAAgBToAACAEQQFqIQQMAAALAAsDQCABIABPDQEgCiABQQF0aiIEIAg6AAEgBCAFOgAAIAQgCDoAAyAEIAU6AAIgBCAIOgAFIAQgBToABCAEIAg6AAcgBCAFOgAGIAFBBGohAQwAAAsACyAFQQFqIQUMAAALAAsgAiEECyAGQRBqJAAgBAutAQECfwJAQYQgKAIAIABHIAAoAgBBAXYiAyABa0F4aiICQXhxQQhHcgR/IAIFIAMQJ0UNASACQQhqC0EQSQ0AIAAgACgCACICQQFxIAAgAWpBD2pBeHEiASAAa0EBdHI2AgAgASAANgIEIAEgASgCAEEBcSAAIAJBAXZqIAFrIgJBAXRyNgIAQYQgIAEgAkH/////B3FqQQRqQYQgKAIAIABGGyABNgIAIAEQJQsLygIBBX8CQAJAAkAgAEEIIABBCEsbZ0EfcyAAaUEBR2oiAUEESSAAIAF2cg0AIAFBAnRB/B5qKAIAIgJFDQADQCACQXhqIgMoAgBBAXZBeGoiBSAATwRAIAIgBUEIIAVBCEsbZ0Efc0ECdEGAH2oiASgCAEYEQCABIAIoAgQ2AgALDAMLIARBHksNASAEQQFqIQQgAigCBCICDQALC0EAIQMgAUEgTw0BA0AgAUECdEGAH2ooAgAiAkUEQCABQR5LIQIgAUEBaiEBIAJFDQEMAwsLIAIgAkF4aiIDKAIAQQF2QXhqIgFBCCABQQhLG2dBH3NBAnRBgB9qIgEoAgBGBEAgASACKAIENgIACwsgAigCACIBBEAgASACKAIENgIECyACKAIEIgEEQCABIAIoAgA2AgALIAMgAygCAEEBcjYCACADIAAQNwsgAwvhCwINfwV+IwBB8ABrIgckACAHIAAoAvDhASIINgJcIAEgAmohDSAIIAAoAoDiAWohDwJAAkAgBUUEQCABIQQMAQsgACgCxOABIRAgACgCwOABIREgACgCvOABIQ4gAEEBNgKM4QFBACEIA0AgCEEDRwRAIAcgCEECdCICaiAAIAJqQazQAWooAgA2AkQgCEEBaiEIDAELC0FsIQwgB0EYaiADIAQQBhADDQEgB0EsaiAHQRhqIAAoAgAQEyAHQTRqIAdBGGogACgCCBATIAdBPGogB0EYaiAAKAIEEBMgDUFgaiESIAEhBEEAIQwDQCAHKAIwIAcoAixBA3RqKQIAIhRCEIinQf8BcSEIIAcoAkAgBygCPEEDdGopAgAiFUIQiKdB/wFxIQsgBygCOCAHKAI0QQN0aikCACIWQiCIpyEJIBVCIIghFyAUQiCIpyECAkAgFkIQiKdB/wFxIgNBAk8EQAJAIAZFIANBGUlyRQRAIAkgB0EYaiADQSAgBygCHGsiCiAKIANLGyIKEAUgAyAKayIDdGohCSAHQRhqEAQaIANFDQEgB0EYaiADEAUgCWohCQwBCyAHQRhqIAMQBSAJaiEJIAdBGGoQBBoLIAcpAkQhGCAHIAk2AkQgByAYNwNIDAELAkAgA0UEQCACBEAgBygCRCEJDAMLIAcoAkghCQwBCwJAAkAgB0EYakEBEAUgCSACRWpqIgNBA0YEQCAHKAJEQX9qIgMgA0VqIQkMAQsgA0ECdCAHaigCRCIJIAlFaiEJIANBAUYNAQsgByAHKAJINgJMCwsgByAHKAJENgJIIAcgCTYCRAsgF6chAyALBEAgB0EYaiALEAUgA2ohAwsgCCALakEUTwRAIAdBGGoQBBoLIAgEQCAHQRhqIAgQBSACaiECCyAHQRhqEAQaIAcgB0EYaiAUQhiIp0H/AXEQCCAUp0H//wNxajYCLCAHIAdBGGogFUIYiKdB/wFxEAggFadB//8DcWo2AjwgB0EYahAEGiAHIAdBGGogFkIYiKdB/wFxEAggFqdB//8DcWo2AjQgByACNgJgIAcoAlwhCiAHIAk2AmggByADNgJkAkACQAJAIAQgAiADaiILaiASSw0AIAIgCmoiEyAPSw0AIA0gBGsgC0Egak8NAQsgByAHKQNoNwMQIAcgBykDYDcDCCAEIA0gB0EIaiAHQdwAaiAPIA4gESAQEB4hCwwBCyACIARqIQggBCAKEAcgAkERTwRAIARBEGohAgNAIAIgCkEQaiIKEAcgAkEQaiICIAhJDQALCyAIIAlrIQIgByATNgJcIAkgCCAOa0sEQCAJIAggEWtLBEBBbCELDAILIBAgAiAOayICaiIKIANqIBBNBEAgCCAKIAMQDxoMAgsgCCAKQQAgAmsQDyEIIAcgAiADaiIDNgJkIAggAmshCCAOIQILIAlBEE8EQCADIAhqIQMDQCAIIAIQByACQRBqIQIgCEEQaiIIIANJDQALDAELAkAgCUEHTQRAIAggAi0AADoAACAIIAItAAE6AAEgCCACLQACOgACIAggAi0AAzoAAyAIQQRqIAIgCUECdCIDQcAeaigCAGoiAhAXIAIgA0HgHmooAgBrIQIgBygCZCEDDAELIAggAhAMCyADQQlJDQAgAyAIaiEDIAhBCGoiCCACQQhqIgJrQQ9MBEADQCAIIAIQDCACQQhqIQIgCEEIaiIIIANJDQAMAgALAAsDQCAIIAIQByACQRBqIQIgCEEQaiIIIANJDQALCyAHQRhqEAQaIAsgDCALEAMiAhshDCAEIAQgC2ogAhshBCAFQX9qIgUNAAsgDBADDQFBbCEMIAdBGGoQBEECSQ0BQQAhCANAIAhBA0cEQCAAIAhBAnQiAmpBrNABaiACIAdqKAJENgIAIAhBAWohCAwBCwsgBygCXCEIC0G6fyEMIA8gCGsiACANIARrSw0AIAQEfyAEIAggABALIABqBUEACyABayEMCyAHQfAAaiQAIAwLkRcCFn8FfiMAQdABayIHJAAgByAAKALw4QEiCDYCvAEgASACaiESIAggACgCgOIBaiETAkACQCAFRQRAIAEhAwwBCyAAKALE4AEhESAAKALA4AEhFSAAKAK84AEhDyAAQQE2AozhAUEAIQgDQCAIQQNHBEAgByAIQQJ0IgJqIAAgAmpBrNABaigCADYCVCAIQQFqIQgMAQsLIAcgETYCZCAHIA82AmAgByABIA9rNgJoQWwhECAHQShqIAMgBBAGEAMNASAFQQQgBUEESBshFyAHQTxqIAdBKGogACgCABATIAdBxABqIAdBKGogACgCCBATIAdBzABqIAdBKGogACgCBBATQQAhBCAHQeAAaiEMIAdB5ABqIQoDQCAHQShqEARBAksgBCAXTnJFBEAgBygCQCAHKAI8QQN0aikCACIdQhCIp0H/AXEhCyAHKAJQIAcoAkxBA3RqKQIAIh5CEIinQf8BcSEJIAcoAkggBygCREEDdGopAgAiH0IgiKchCCAeQiCIISAgHUIgiKchAgJAIB9CEIinQf8BcSIDQQJPBEACQCAGRSADQRlJckUEQCAIIAdBKGogA0EgIAcoAixrIg0gDSADSxsiDRAFIAMgDWsiA3RqIQggB0EoahAEGiADRQ0BIAdBKGogAxAFIAhqIQgMAQsgB0EoaiADEAUgCGohCCAHQShqEAQaCyAHKQJUISEgByAINgJUIAcgITcDWAwBCwJAIANFBEAgAgRAIAcoAlQhCAwDCyAHKAJYIQgMAQsCQAJAIAdBKGpBARAFIAggAkVqaiIDQQNGBEAgBygCVEF/aiIDIANFaiEIDAELIANBAnQgB2ooAlQiCCAIRWohCCADQQFGDQELIAcgBygCWDYCXAsLIAcgBygCVDYCWCAHIAg2AlQLICCnIQMgCQRAIAdBKGogCRAFIANqIQMLIAkgC2pBFE8EQCAHQShqEAQaCyALBEAgB0EoaiALEAUgAmohAgsgB0EoahAEGiAHIAcoAmggAmoiCSADajYCaCAKIAwgCCAJSxsoAgAhDSAHIAdBKGogHUIYiKdB/wFxEAggHadB//8DcWo2AjwgByAHQShqIB5CGIinQf8BcRAIIB6nQf//A3FqNgJMIAdBKGoQBBogB0EoaiAfQhiIp0H/AXEQCCEOIAdB8ABqIARBBHRqIgsgCSANaiAIazYCDCALIAg2AgggCyADNgIEIAsgAjYCACAHIA4gH6dB//8DcWo2AkQgBEEBaiEEDAELCyAEIBdIDQEgEkFgaiEYIAdB4ABqIRogB0HkAGohGyABIQMDQCAHQShqEARBAksgBCAFTnJFBEAgBygCQCAHKAI8QQN0aikCACIdQhCIp0H/AXEhCyAHKAJQIAcoAkxBA3RqKQIAIh5CEIinQf8BcSEIIAcoAkggBygCREEDdGopAgAiH0IgiKchCSAeQiCIISAgHUIgiKchDAJAIB9CEIinQf8BcSICQQJPBEACQCAGRSACQRlJckUEQCAJIAdBKGogAkEgIAcoAixrIgogCiACSxsiChAFIAIgCmsiAnRqIQkgB0EoahAEGiACRQ0BIAdBKGogAhAFIAlqIQkMAQsgB0EoaiACEAUgCWohCSAHQShqEAQaCyAHKQJUISEgByAJNgJUIAcgITcDWAwBCwJAIAJFBEAgDARAIAcoAlQhCQwDCyAHKAJYIQkMAQsCQAJAIAdBKGpBARAFIAkgDEVqaiICQQNGBEAgBygCVEF/aiICIAJFaiEJDAELIAJBAnQgB2ooAlQiCSAJRWohCSACQQFGDQELIAcgBygCWDYCXAsLIAcgBygCVDYCWCAHIAk2AlQLICCnIRQgCARAIAdBKGogCBAFIBRqIRQLIAggC2pBFE8EQCAHQShqEAQaCyALBEAgB0EoaiALEAUgDGohDAsgB0EoahAEGiAHIAcoAmggDGoiGSAUajYCaCAbIBogCSAZSxsoAgAhHCAHIAdBKGogHUIYiKdB/wFxEAggHadB//8DcWo2AjwgByAHQShqIB5CGIinQf8BcRAIIB6nQf//A3FqNgJMIAdBKGoQBBogByAHQShqIB9CGIinQf8BcRAIIB+nQf//A3FqNgJEIAcgB0HwAGogBEEDcUEEdGoiDSkDCCIdNwPIASAHIA0pAwAiHjcDwAECQAJAAkAgBygCvAEiDiAepyICaiIWIBNLDQAgAyAHKALEASIKIAJqIgtqIBhLDQAgEiADayALQSBqTw0BCyAHIAcpA8gBNwMQIAcgBykDwAE3AwggAyASIAdBCGogB0G8AWogEyAPIBUgERAeIQsMAQsgAiADaiEIIAMgDhAHIAJBEU8EQCADQRBqIQIDQCACIA5BEGoiDhAHIAJBEGoiAiAISQ0ACwsgCCAdpyIOayECIAcgFjYCvAEgDiAIIA9rSwRAIA4gCCAVa0sEQEFsIQsMAgsgESACIA9rIgJqIhYgCmogEU0EQCAIIBYgChAPGgwCCyAIIBZBACACaxAPIQggByACIApqIgo2AsQBIAggAmshCCAPIQILIA5BEE8EQCAIIApqIQoDQCAIIAIQByACQRBqIQIgCEEQaiIIIApJDQALDAELAkAgDkEHTQRAIAggAi0AADoAACAIIAItAAE6AAEgCCACLQACOgACIAggAi0AAzoAAyAIQQRqIAIgDkECdCIKQcAeaigCAGoiAhAXIAIgCkHgHmooAgBrIQIgBygCxAEhCgwBCyAIIAIQDAsgCkEJSQ0AIAggCmohCiAIQQhqIgggAkEIaiICa0EPTARAA0AgCCACEAwgAkEIaiECIAhBCGoiCCAKSQ0ADAIACwALA0AgCCACEAcgAkEQaiECIAhBEGoiCCAKSQ0ACwsgCxADBEAgCyEQDAQFIA0gDDYCACANIBkgHGogCWs2AgwgDSAJNgIIIA0gFDYCBCAEQQFqIQQgAyALaiEDDAILAAsLIAQgBUgNASAEIBdrIQtBACEEA0AgCyAFSARAIAcgB0HwAGogC0EDcUEEdGoiAikDCCIdNwPIASAHIAIpAwAiHjcDwAECQAJAAkAgBygCvAEiDCAepyICaiIKIBNLDQAgAyAHKALEASIJIAJqIhBqIBhLDQAgEiADayAQQSBqTw0BCyAHIAcpA8gBNwMgIAcgBykDwAE3AxggAyASIAdBGGogB0G8AWogEyAPIBUgERAeIRAMAQsgAiADaiEIIAMgDBAHIAJBEU8EQCADQRBqIQIDQCACIAxBEGoiDBAHIAJBEGoiAiAISQ0ACwsgCCAdpyIGayECIAcgCjYCvAEgBiAIIA9rSwRAIAYgCCAVa0sEQEFsIRAMAgsgESACIA9rIgJqIgwgCWogEU0EQCAIIAwgCRAPGgwCCyAIIAxBACACaxAPIQggByACIAlqIgk2AsQBIAggAmshCCAPIQILIAZBEE8EQCAIIAlqIQYDQCAIIAIQByACQRBqIQIgCEEQaiIIIAZJDQALDAELAkAgBkEHTQRAIAggAi0AADoAACAIIAItAAE6AAEgCCACLQACOgACIAggAi0AAzoAAyAIQQRqIAIgBkECdCIGQcAeaigCAGoiAhAXIAIgBkHgHmooAgBrIQIgBygCxAEhCQwBCyAIIAIQDAsgCUEJSQ0AIAggCWohBiAIQQhqIgggAkEIaiICa0EPTARAA0AgCCACEAwgAkEIaiECIAhBCGoiCCAGSQ0ADAIACwALA0AgCCACEAcgAkEQaiECIAhBEGoiCCAGSQ0ACwsgEBADDQMgC0EBaiELIAMgEGohAwwBCwsDQCAEQQNHBEAgACAEQQJ0IgJqQazQAWogAiAHaigCVDYCACAEQQFqIQQMAQsLIAcoArwBIQgLQbp/IRAgEyAIayIAIBIgA2tLDQAgAwR/IAMgCCAAEAsgAGoFQQALIAFrIRALIAdB0AFqJAAgEAslACAAQgA3AgAgAEEAOwEIIABBADoACyAAIAE2AgwgACACOgAKC7QFAQN/IwBBMGsiBCQAIABB/wFqIgVBfWohBgJAIAMvAQIEQCAEQRhqIAEgAhAGIgIQAw0BIARBEGogBEEYaiADEBwgBEEIaiAEQRhqIAMQHCAAIQMDQAJAIARBGGoQBCADIAZPckUEQCADIARBEGogBEEYahASOgAAIAMgBEEIaiAEQRhqEBI6AAEgBEEYahAERQ0BIANBAmohAwsgBUF+aiEFAn8DQEG6fyECIAMiASAFSw0FIAEgBEEQaiAEQRhqEBI6AAAgAUEBaiEDIARBGGoQBEEDRgRAQQIhAiAEQQhqDAILIAMgBUsNBSABIARBCGogBEEYahASOgABIAFBAmohA0EDIQIgBEEYahAEQQNHDQALIARBEGoLIQUgAyAFIARBGGoQEjoAACABIAJqIABrIQIMAwsgAyAEQRBqIARBGGoQEjoAAiADIARBCGogBEEYahASOgADIANBBGohAwwAAAsACyAEQRhqIAEgAhAGIgIQAw0AIARBEGogBEEYaiADEBwgBEEIaiAEQRhqIAMQHCAAIQMDQAJAIARBGGoQBCADIAZPckUEQCADIARBEGogBEEYahAROgAAIAMgBEEIaiAEQRhqEBE6AAEgBEEYahAERQ0BIANBAmohAwsgBUF+aiEFAn8DQEG6fyECIAMiASAFSw0EIAEgBEEQaiAEQRhqEBE6AAAgAUEBaiEDIARBGGoQBEEDRgRAQQIhAiAEQQhqDAILIAMgBUsNBCABIARBCGogBEEYahAROgABIAFBAmohA0EDIQIgBEEYahAEQQNHDQALIARBEGoLIQUgAyAFIARBGGoQEToAACABIAJqIABrIQIMAgsgAyAEQRBqIARBGGoQEToAAiADIARBCGogBEEYahAROgADIANBBGohAwwAAAsACyAEQTBqJAAgAgtpAQF/An8CQAJAIAJBB00NACABKAAAQbfIwuF+Rw0AIAAgASgABDYCmOIBQWIgAEEQaiABIAIQPiIDEAMNAhogAEKBgICAEDcDiOEBIAAgASADaiACIANrECoMAQsgACABIAIQKgtBAAsLrQMBBn8jAEGAAWsiAyQAQWIhCAJAIAJBCUkNACAAQZjQAGogAUEIaiIEIAJBeGogAEGY0AAQMyIFEAMiBg0AIANBHzYCfCADIANB/ABqIANB+ABqIAQgBCAFaiAGGyIEIAEgAmoiAiAEaxAVIgUQAw0AIAMoAnwiBkEfSw0AIAMoAngiB0EJTw0AIABBiCBqIAMgBkGAC0GADCAHEBggA0E0NgJ8IAMgA0H8AGogA0H4AGogBCAFaiIEIAIgBGsQFSIFEAMNACADKAJ8IgZBNEsNACADKAJ4IgdBCk8NACAAQZAwaiADIAZBgA1B4A4gBxAYIANBIzYCfCADIANB/ABqIANB+ABqIAQgBWoiBCACIARrEBUiBRADDQAgAygCfCIGQSNLDQAgAygCeCIHQQpPDQAgACADIAZBwBBB0BEgBxAYIAQgBWoiBEEMaiIFIAJLDQAgAiAFayEFQQAhAgNAIAJBA0cEQCAEKAAAIgZBf2ogBU8NAiAAIAJBAnRqQZzQAWogBjYCACACQQFqIQIgBEEEaiEEDAELCyAEIAFrIQgLIANBgAFqJAAgCAtGAQN/IABBCGohAyAAKAIEIQJBACEAA0AgACACdkUEQCABIAMgAEEDdGotAAJBFktqIQEgAEEBaiEADAELCyABQQggAmt0C4YDAQV/Qbh/IQcCQCADRQ0AIAItAAAiBEUEQCABQQA2AgBBAUG4fyADQQFGGw8LAn8gAkEBaiIFIARBGHRBGHUiBkF/Sg0AGiAGQX9GBEAgA0EDSA0CIAUvAABBgP4BaiEEIAJBA2oMAQsgA0ECSA0BIAItAAEgBEEIdHJBgIB+aiEEIAJBAmoLIQUgASAENgIAIAVBAWoiASACIANqIgNLDQBBbCEHIABBEGogACAFLQAAIgVBBnZBI0EJIAEgAyABa0HAEEHQEUHwEiAAKAKM4QEgACgCnOIBIAQQHyIGEAMiCA0AIABBmCBqIABBCGogBUEEdkEDcUEfQQggASABIAZqIAgbIgEgAyABa0GAC0GADEGAFyAAKAKM4QEgACgCnOIBIAQQHyIGEAMiCA0AIABBoDBqIABBBGogBUECdkEDcUE0QQkgASABIAZqIAgbIgEgAyABa0GADUHgDkGQGSAAKAKM4QEgACgCnOIBIAQQHyIAEAMNACAAIAFqIAJrIQcLIAcLrQMBCn8jAEGABGsiCCQAAn9BUiACQf8BSw0AGkFUIANBDEsNABogAkEBaiELIABBBGohCUGAgAQgA0F/anRBEHUhCkEAIQJBASEEQQEgA3QiB0F/aiIMIQUDQCACIAtGRQRAAkAgASACQQF0Ig1qLwEAIgZB//8DRgRAIAkgBUECdGogAjoAAiAFQX9qIQVBASEGDAELIARBACAKIAZBEHRBEHVKGyEECyAIIA1qIAY7AQAgAkEBaiECDAELCyAAIAQ7AQIgACADOwEAIAdBA3YgB0EBdmpBA2ohBkEAIQRBACECA0AgBCALRkUEQCABIARBAXRqLgEAIQpBACEAA0AgACAKTkUEQCAJIAJBAnRqIAQ6AAIDQCACIAZqIAxxIgIgBUsNAAsgAEEBaiEADAELCyAEQQFqIQQMAQsLQX8gAg0AGkEAIQIDfyACIAdGBH9BAAUgCCAJIAJBAnRqIgAtAAJBAXRqIgEgAS8BACIBQQFqOwEAIAAgAyABEBRrIgU6AAMgACABIAVB/wFxdCAHazsBACACQQFqIQIMAQsLCyEFIAhBgARqJAAgBQvjBgEIf0FsIQcCQCACQQNJDQACQAJAAkACQCABLQAAIgNBA3EiCUEBaw4DAwEAAgsgACgCiOEBDQBBYg8LIAJBBUkNAkEDIQYgASgAACEFAn8CQAJAIANBAnZBA3EiCEF+aiIEQQFNBEAgBEEBaw0BDAILIAVBDnZB/wdxIQQgBUEEdkH/B3EhAyAIRQwCCyAFQRJ2IQRBBCEGIAVBBHZB//8AcSEDQQAMAQsgBUEEdkH//w9xIgNBgIAISw0DIAEtAARBCnQgBUEWdnIhBEEFIQZBAAshBSAEIAZqIgogAksNAgJAIANBgQZJDQAgACgCnOIBRQ0AQQAhAgNAIAJBg4ABSw0BIAJBQGshAgwAAAsACwJ/IAlBA0YEQCABIAZqIQEgAEHw4gFqIQIgACgCDCEGIAUEQCACIAMgASAEIAYQXwwCCyACIAMgASAEIAYQXQwBCyAAQbjQAWohAiABIAZqIQEgAEHw4gFqIQYgAEGo0ABqIQggBQRAIAggBiADIAEgBCACEF4MAQsgCCAGIAMgASAEIAIQXAsQAw0CIAAgAzYCgOIBIABBATYCiOEBIAAgAEHw4gFqNgLw4QEgCUECRgRAIAAgAEGo0ABqNgIMCyAAIANqIgBBiOMBakIANwAAIABBgOMBakIANwAAIABB+OIBakIANwAAIABB8OIBakIANwAAIAoPCwJ/AkACQAJAIANBAnZBA3FBf2oiBEECSw0AIARBAWsOAgACAQtBASEEIANBA3YMAgtBAiEEIAEvAABBBHYMAQtBAyEEIAEQIUEEdgsiAyAEaiIFQSBqIAJLBEAgBSACSw0CIABB8OIBaiABIARqIAMQCyEBIAAgAzYCgOIBIAAgATYC8OEBIAEgA2oiAEIANwAYIABCADcAECAAQgA3AAggAEIANwAAIAUPCyAAIAM2AoDiASAAIAEgBGo2AvDhASAFDwsCfwJAAkACQCADQQJ2QQNxQX9qIgRBAksNACAEQQFrDgIAAgELQQEhByADQQN2DAILQQIhByABLwAAQQR2DAELIAJBBEkgARAhIgJBj4CAAUtyDQFBAyEHIAJBBHYLIQIgAEHw4gFqIAEgB2otAAAgAkEgahAQIQEgACACNgKA4gEgACABNgLw4QEgB0EBaiEHCyAHC0sAIABC+erQ0OfJoeThADcDICAAQgA3AxggAELP1tO+0ser2UI3AxAgAELW64Lu6v2J9eAANwMIIABCADcDACAAQShqQQBBKBAQGgviAgICfwV+IABBKGoiASAAKAJIaiECAn4gACkDACIDQiBaBEAgACkDECIEQgeJIAApAwgiBUIBiXwgACkDGCIGQgyJfCAAKQMgIgdCEol8IAUQGSAEEBkgBhAZIAcQGQwBCyAAKQMYQsXP2bLx5brqJ3wLIAN8IQMDQCABQQhqIgAgAk0EQEIAIAEpAAAQCSADhUIbiUKHla+vmLbem55/fkLj3MqV/M7y9YV/fCEDIAAhAQwBCwsCQCABQQRqIgAgAksEQCABIQAMAQsgASgAAK1Ch5Wvr5i23puef34gA4VCF4lCz9bTvtLHq9lCfkL5893xmfaZqxZ8IQMLA0AgACACSQRAIAAxAABCxc/ZsvHluuonfiADhUILiUKHla+vmLbem55/fiEDIABBAWohAAwBCwsgA0IhiCADhULP1tO+0ser2UJ+IgNCHYggA4VC+fPd8Zn2masWfiIDQiCIIAOFC+8CAgJ/BH4gACAAKQMAIAKtfDcDAAJAAkAgACgCSCIDIAJqIgRBH00EQCABRQ0BIAAgA2pBKGogASACECAgACgCSCACaiEEDAELIAEgAmohAgJ/IAMEQCAAQShqIgQgA2ogAUEgIANrECAgACAAKQMIIAQpAAAQCTcDCCAAIAApAxAgACkAMBAJNwMQIAAgACkDGCAAKQA4EAk3AxggACAAKQMgIABBQGspAAAQCTcDICAAKAJIIQMgAEEANgJIIAEgA2tBIGohAQsgAUEgaiACTQsEQCACQWBqIQMgACkDICEFIAApAxghBiAAKQMQIQcgACkDCCEIA0AgCCABKQAAEAkhCCAHIAEpAAgQCSEHIAYgASkAEBAJIQYgBSABKQAYEAkhBSABQSBqIgEgA00NAAsgACAFNwMgIAAgBjcDGCAAIAc3AxAgACAINwMICyABIAJPDQEgAEEoaiABIAIgAWsiBBAgCyAAIAQ2AkgLCy8BAX8gAEUEQEG2f0EAIAMbDwtBun8hBCADIAFNBH8gACACIAMQEBogAwVBun8LCy8BAX8gAEUEQEG2f0EAIAMbDwtBun8hBCADIAFNBH8gACACIAMQCxogAwVBun8LC6gCAQZ/IwBBEGsiByQAIABB2OABaikDAEKAgIAQViEIQbh/IQUCQCAEQf//B0sNACAAIAMgBBBCIgUQAyIGDQAgACgCnOIBIQkgACAHQQxqIAMgAyAFaiAGGyIKIARBACAFIAYbayIGEEAiAxADBEAgAyEFDAELIAcoAgwhBCABRQRAQbp/IQUgBEEASg0BCyAGIANrIQUgAyAKaiEDAkAgCQRAIABBADYCnOIBDAELAkACQAJAIARBBUgNACAAQdjgAWopAwBCgICACFgNAAwBCyAAQQA2ApziAQwBCyAAKAIIED8hBiAAQQA2ApziASAGQRRPDQELIAAgASACIAMgBSAEIAgQOSEFDAELIAAgASACIAMgBSAEIAgQOiEFCyAHQRBqJAAgBQtnACAAQdDgAWogASACIAAoAuzhARAuIgEQAwRAIAEPC0G4fyECAkAgAQ0AIABB7OABaigCACIBBEBBYCECIAAoApjiASABRw0BC0EAIQIgAEHw4AFqKAIARQ0AIABBkOEBahBDCyACCycBAX8QVyIERQRAQUAPCyAEIAAgASACIAMgBBBLEE8hACAEEFYgAAs/AQF/AkACQAJAIAAoAqDiAUEBaiIBQQJLDQAgAUEBaw4CAAECCyAAEDBBAA8LIABBADYCoOIBCyAAKAKU4gELvAMCB38BfiMAQRBrIgkkAEG4fyEGAkAgBCgCACIIQQVBCSAAKALs4QEiBRtJDQAgAygCACIHQQFBBSAFGyAFEC8iBRADBEAgBSEGDAELIAggBUEDakkNACAAIAcgBRBJIgYQAw0AIAEgAmohCiAAQZDhAWohCyAIIAVrIQIgBSAHaiEHIAEhBQNAIAcgAiAJECwiBhADDQEgAkF9aiICIAZJBEBBuH8hBgwCCyAJKAIAIghBAksEQEFsIQYMAgsgB0EDaiEHAn8CQAJAAkAgCEEBaw4CAgABCyAAIAUgCiAFayAHIAYQSAwCCyAFIAogBWsgByAGEEcMAQsgBSAKIAVrIActAAAgCSgCCBBGCyIIEAMEQCAIIQYMAgsgACgC8OABBEAgCyAFIAgQRQsgAiAGayECIAYgB2ohByAFIAhqIQUgCSgCBEUNAAsgACkD0OABIgxCf1IEQEFsIQYgDCAFIAFrrFINAQsgACgC8OABBEBBaiEGIAJBBEkNASALEEQhDCAHKAAAIAynRw0BIAdBBGohByACQXxqIQILIAMgBzYCACAEIAI2AgAgBSABayEGCyAJQRBqJAAgBgsuACAAECsCf0EAQQAQAw0AGiABRSACRXJFBEBBYiAAIAEgAhA9EAMNARoLQQALCzcAIAEEQCAAIAAoAsTgASABKAIEIAEoAghqRzYCnOIBCyAAECtBABADIAFFckUEQCAAIAEQWwsL0QIBB38jAEEQayIGJAAgBiAENgIIIAYgAzYCDCAFBEAgBSgCBCEKIAUoAgghCQsgASEIAkACQANAIAAoAuzhARAWIQsCQANAIAQgC0kNASADKAAAQXBxQdDUtMIBRgRAIAMgBBAiIgcQAw0EIAQgB2shBCADIAdqIQMMAQsLIAYgAzYCDCAGIAQ2AggCQCAFBEAgACAFEE5BACEHQQAQA0UNAQwFCyAAIAogCRBNIgcQAw0ECyAAIAgQUCAMQQFHQQAgACAIIAIgBkEMaiAGQQhqEEwiByIDa0EAIAMQAxtBCkdyRQRAQbh/IQcMBAsgBxADDQMgAiAHayECIAcgCGohCEEBIQwgBigCDCEDIAYoAgghBAwBCwsgBiADNgIMIAYgBDYCCEG4fyEHIAQNASAIIAFrIQcMAQsgBiADNgIMIAYgBDYCCAsgBkEQaiQAIAcLRgECfyABIAAoArjgASICRwRAIAAgAjYCxOABIAAgATYCuOABIAAoArzgASEDIAAgATYCvOABIAAgASADIAJrajYCwOABCwutAgIEfwF+IwBBQGoiBCQAAkACQCACQQhJDQAgASgAAEFwcUHQ1LTCAUcNACABIAIQIiEBIABCADcDCCAAQQA2AgQgACABNgIADAELIARBGGogASACEC0iAxADBEAgACADEBoMAQsgAwRAIABBuH8QGgwBCyACIAQoAjAiA2shAiABIANqIQMDQAJAIAAgAyACIARBCGoQLCIFEAMEfyAFBSACIAVBA2oiBU8NAUG4fwsQGgwCCyAGQQFqIQYgAiAFayECIAMgBWohAyAEKAIMRQ0ACyAEKAI4BEAgAkEDTQRAIABBuH8QGgwCCyADQQRqIQMLIAQoAighAiAEKQMYIQcgAEEANgIEIAAgAyABazYCACAAIAIgBmytIAcgB0J/URs3AwgLIARBQGskAAslAQF/IwBBEGsiAiQAIAIgACABEFEgAigCACEAIAJBEGokACAAC30BBH8jAEGQBGsiBCQAIARB/wE2AggCQCAEQRBqIARBCGogBEEMaiABIAIQFSIGEAMEQCAGIQUMAQtBVCEFIAQoAgwiB0EGSw0AIAMgBEEQaiAEKAIIIAcQQSIFEAMNACAAIAEgBmogAiAGayADEDwhBQsgBEGQBGokACAFC4cBAgJ/An5BABAWIQMCQANAIAEgA08EQAJAIAAoAABBcHFB0NS0wgFGBEAgACABECIiAhADRQ0BQn4PCyAAIAEQVSIEQn1WDQMgBCAFfCIFIARUIQJCfiEEIAINAyAAIAEQUiICEAMNAwsgASACayEBIAAgAmohAAwBCwtCfiAFIAEbIQQLIAQLPwIBfwF+IwBBMGsiAiQAAn5CfiACQQhqIAAgARAtDQAaQgAgAigCHEEBRg0AGiACKQMICyEDIAJBMGokACADC40BAQJ/IwBBMGsiASQAAkAgAEUNACAAKAKI4gENACABIABB/OEBaigCADYCKCABIAApAvThATcDICAAEDAgACgCqOIBIQIgASABKAIoNgIYIAEgASkDIDcDECACIAFBEGoQGyAAQQA2AqjiASABIAEoAig2AgggASABKQMgNwMAIAAgARAbCyABQTBqJAALKgECfyMAQRBrIgAkACAAQQA2AgggAEIANwMAIAAQWCEBIABBEGokACABC4cBAQN/IwBBEGsiAiQAAkAgACgCAEUgACgCBEVzDQAgAiAAKAIINgIIIAIgACkCADcDAAJ/IAIoAgAiAQRAIAIoAghBqOMJIAERBQAMAQtBqOMJECgLIgFFDQAgASAAKQIANwL04QEgAUH84QFqIAAoAgg2AgAgARBZIAEhAwsgAkEQaiQAIAMLywEBAn8jAEEgayIBJAAgAEGBgIDAADYCtOIBIABBADYCiOIBIABBADYC7OEBIABCADcDkOIBIABBADYCpOMJIABBADYC3OIBIABCADcCzOIBIABBADYCvOIBIABBADYCxOABIABCADcCnOIBIABBpOIBakIANwIAIABBrOIBakEANgIAIAFCADcCECABQgA3AhggASABKQMYNwMIIAEgASkDEDcDACABKAIIQQh2QQFxIQIgAEEANgLg4gEgACACNgKM4gEgAUEgaiQAC3YBA38jAEEwayIBJAAgAARAIAEgAEHE0AFqIgIoAgA2AiggASAAKQK80AE3AyAgACgCACEDIAEgAigCADYCGCABIAApArzQATcDECADIAFBEGoQGyABIAEoAig2AgggASABKQMgNwMAIAAgARAbCyABQTBqJAALzAEBAX8gACABKAK00AE2ApjiASAAIAEoAgQiAjYCwOABIAAgAjYCvOABIAAgAiABKAIIaiICNgK44AEgACACNgLE4AEgASgCuNABBEAgAEKBgICAEDcDiOEBIAAgAUGk0ABqNgIMIAAgAUGUIGo2AgggACABQZwwajYCBCAAIAFBDGo2AgAgAEGs0AFqIAFBqNABaigCADYCACAAQbDQAWogAUGs0AFqKAIANgIAIABBtNABaiABQbDQAWooAgA2AgAPCyAAQgA3A4jhAQs7ACACRQRAQbp/DwsgBEUEQEFsDwsgAiAEEGAEQCAAIAEgAiADIAQgBRBhDwsgACABIAIgAyAEIAUQZQtGAQF/IwBBEGsiBSQAIAVBCGogBBAOAn8gBS0ACQRAIAAgASACIAMgBBAyDAELIAAgASACIAMgBBA0CyEAIAVBEGokACAACzQAIAAgAyAEIAUQNiIFEAMEQCAFDwsgBSAESQR/IAEgAiADIAVqIAQgBWsgABA1BUG4fwsLRgEBfyMAQRBrIgUkACAFQQhqIAQQDgJ/IAUtAAkEQCAAIAEgAiADIAQQYgwBCyAAIAEgAiADIAQQNQshACAFQRBqJAAgAAtZAQF/QQ8hAiABIABJBEAgAUEEdCAAbiECCyAAQQh2IgEgAkEYbCIAQYwIaigCAGwgAEGICGooAgBqIgJBA3YgAmogAEGACGooAgAgAEGECGooAgAgAWxqSQs3ACAAIAMgBCAFQYAQEDMiBRADBEAgBQ8LIAUgBEkEfyABIAIgAyAFaiAEIAVrIAAQMgVBuH8LC78DAQN/IwBBIGsiBSQAIAVBCGogAiADEAYiAhADRQRAIAAgAWoiB0F9aiEGIAUgBBAOIARBBGohAiAFLQACIQMDQEEAIAAgBkkgBUEIahAEGwRAIAAgAiAFQQhqIAMQAkECdGoiBC8BADsAACAFQQhqIAQtAAIQASAAIAQtAANqIgQgAiAFQQhqIAMQAkECdGoiAC8BADsAACAFQQhqIAAtAAIQASAEIAAtAANqIQAMAQUgB0F+aiEEA0AgBUEIahAEIAAgBEtyRQRAIAAgAiAFQQhqIAMQAkECdGoiBi8BADsAACAFQQhqIAYtAAIQASAAIAYtAANqIQAMAQsLA0AgACAES0UEQCAAIAIgBUEIaiADEAJBAnRqIgYvAQA7AAAgBUEIaiAGLQACEAEgACAGLQADaiEADAELCwJAIAAgB08NACAAIAIgBUEIaiADEAIiA0ECdGoiAC0AADoAACAALQADQQFGBEAgBUEIaiAALQACEAEMAQsgBSgCDEEfSw0AIAVBCGogAiADQQJ0ai0AAhABIAUoAgxBIUkNACAFQSA2AgwLIAFBbCAFQQhqEAobIQILCwsgBUEgaiQAIAILkgIBBH8jAEFAaiIJJAAgCSADQTQQCyEDAkAgBEECSA0AIAMgBEECdGooAgAhCSADQTxqIAgQIyADQQE6AD8gAyACOgA+QQAhBCADKAI8IQoDQCAEIAlGDQEgACAEQQJ0aiAKNgEAIARBAWohBAwAAAsAC0EAIQkDQCAGIAlGRQRAIAMgBSAJQQF0aiIKLQABIgtBAnRqIgwoAgAhBCADQTxqIAotAABBCHQgCGpB//8DcRAjIANBAjoAPyADIAcgC2siCiACajoAPiAEQQEgASAKa3RqIQogAygCPCELA0AgACAEQQJ0aiALNgEAIARBAWoiBCAKSQ0ACyAMIAo2AgAgCUEBaiEJDAELCyADQUBrJAALowIBCX8jAEHQAGsiCSQAIAlBEGogBUE0EAsaIAcgBmshDyAHIAFrIRADQAJAIAMgCkcEQEEBIAEgByACIApBAXRqIgYtAAEiDGsiCGsiC3QhDSAGLQAAIQ4gCUEQaiAMQQJ0aiIMKAIAIQYgCyAPTwRAIAAgBkECdGogCyAIIAUgCEE0bGogCCAQaiIIQQEgCEEBShsiCCACIAQgCEECdGooAgAiCEEBdGogAyAIayAHIA4QYyAGIA1qIQgMAgsgCUEMaiAOECMgCUEBOgAPIAkgCDoADiAGIA1qIQggCSgCDCELA0AgBiAITw0CIAAgBkECdGogCzYBACAGQQFqIQYMAAALAAsgCUHQAGokAA8LIAwgCDYCACAKQQFqIQoMAAALAAs0ACAAIAMgBCAFEDYiBRADBEAgBQ8LIAUgBEkEfyABIAIgAyAFaiAEIAVrIAAQNAVBuH8LCyMAIAA/AEEQdGtB//8DakEQdkAAQX9GBEBBAA8LQQAQAEEBCzsBAX8gAgRAA0AgACABIAJBgCAgAkGAIEkbIgMQCyEAIAFBgCBqIQEgAEGAIGohACACIANrIgINAAsLCwYAIAAQAwsLqBUJAEGICAsNAQAAAAEAAAACAAAAAgBBoAgLswYBAAAAAQAAAAIAAAACAAAAJgAAAIIAAAAhBQAASgAAAGcIAAAmAAAAwAEAAIAAAABJBQAASgAAAL4IAAApAAAALAIAAIAAAABJBQAASgAAAL4IAAAvAAAAygIAAIAAAACKBQAASgAAAIQJAAA1AAAAcwMAAIAAAACdBQAASgAAAKAJAAA9AAAAgQMAAIAAAADrBQAASwAAAD4KAABEAAAAngMAAIAAAABNBgAASwAAAKoKAABLAAAAswMAAIAAAADBBgAATQAAAB8NAABNAAAAUwQAAIAAAAAjCAAAUQAAAKYPAABUAAAAmQQAAIAAAABLCQAAVwAAALESAABYAAAA2gQAAIAAAABvCQAAXQAAACMUAABUAAAARQUAAIAAAABUCgAAagAAAIwUAABqAAAArwUAAIAAAAB2CQAAfAAAAE4QAAB8AAAA0gIAAIAAAABjBwAAkQAAAJAHAACSAAAAAAAAAAEAAAABAAAABQAAAA0AAAAdAAAAPQAAAH0AAAD9AAAA/QEAAP0DAAD9BwAA/Q8AAP0fAAD9PwAA/X8AAP3/AAD9/wEA/f8DAP3/BwD9/w8A/f8fAP3/PwD9/38A/f//AP3//wH9//8D/f//B/3//w/9//8f/f//P/3//38AAAAAAQAAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAABEAAAASAAAAEwAAABQAAAAVAAAAFgAAABcAAAAYAAAAGQAAABoAAAAbAAAAHAAAAB0AAAAeAAAAHwAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAABIAAAATAAAAFAAAABUAAAAWAAAAFwAAABgAAAAZAAAAGgAAABsAAAAcAAAAHQAAAB4AAAAfAAAAIAAAACEAAAAiAAAAIwAAACUAAAAnAAAAKQAAACsAAAAvAAAAMwAAADsAAABDAAAAUwAAAGMAAACDAAAAAwEAAAMCAAADBAAAAwgAAAMQAAADIAAAA0AAAAOAAAADAAEAQeAPC1EBAAAAAQAAAAEAAAABAAAAAgAAAAIAAAADAAAAAwAAAAQAAAAEAAAABQAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAAOAAAADwAAABAAQcQQC4sBAQAAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAABIAAAAUAAAAFgAAABgAAAAcAAAAIAAAACgAAAAwAAAAQAAAAIAAAAAAAQAAAAIAAAAEAAAACAAAABAAAAAgAAAAQAAAAIAAAAAAAQBBkBIL5gQBAAAAAQAAAAEAAAABAAAAAgAAAAIAAAADAAAAAwAAAAQAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAAAEAAAAEAAAACAAAAAAAAAABAAEBBgAAAAAAAAQAAAAAEAAABAAAAAAgAAAFAQAAAAAAAAUDAAAAAAAABQQAAAAAAAAFBgAAAAAAAAUHAAAAAAAABQkAAAAAAAAFCgAAAAAAAAUMAAAAAAAABg4AAAAAAAEFEAAAAAAAAQUUAAAAAAABBRYAAAAAAAIFHAAAAAAAAwUgAAAAAAAEBTAAAAAgAAYFQAAAAAAABwWAAAAAAAAIBgABAAAAAAoGAAQAAAAADAYAEAAAIAAABAAAAAAAAAAEAQAAAAAAAAUCAAAAIAAABQQAAAAAAAAFBQAAACAAAAUHAAAAAAAABQgAAAAgAAAFCgAAAAAAAAULAAAAAAAABg0AAAAgAAEFEAAAAAAAAQUSAAAAIAABBRYAAAAAAAIFGAAAACAAAwUgAAAAAAADBSgAAAAAAAYEQAAAABAABgRAAAAAIAAHBYAAAAAAAAkGAAIAAAAACwYACAAAMAAABAAAAAAQAAAEAQAAACAAAAUCAAAAIAAABQMAAAAgAAAFBQAAACAAAAUGAAAAIAAABQgAAAAgAAAFCQAAACAAAAULAAAAIAAABQwAAAAAAAAGDwAAACAAAQUSAAAAIAABBRQAAAAgAAIFGAAAACAAAgUcAAAAIAADBSgAAAAgAAQFMAAAAAAAEAYAAAEAAAAPBgCAAAAAAA4GAEAAAAAADQYAIABBgBcLhwIBAAEBBQAAAAAAAAUAAAAAAAAGBD0AAAAAAAkF/QEAAAAADwX9fwAAAAAVBf3/HwAAAAMFBQAAAAAABwR9AAAAAAAMBf0PAAAAABIF/f8DAAAAFwX9/38AAAAFBR0AAAAAAAgE/QAAAAAADgX9PwAAAAAUBf3/DwAAAAIFAQAAABAABwR9AAAAAAALBf0HAAAAABEF/f8BAAAAFgX9/z8AAAAEBQ0AAAAQAAgE/QAAAAAADQX9HwAAAAATBf3/BwAAAAEFAQAAABAABgQ9AAAAAAAKBf0DAAAAABAF/f8AAAAAHAX9//8PAAAbBf3//wcAABoF/f//AwAAGQX9//8BAAAYBf3//wBBkBkLhgQBAAEBBgAAAAAAAAYDAAAAAAAABAQAAAAgAAAFBQAAAAAAAAUGAAAAAAAABQgAAAAAAAAFCQAAAAAAAAULAAAAAAAABg0AAAAAAAAGEAAAAAAAAAYTAAAAAAAABhYAAAAAAAAGGQAAAAAAAAYcAAAAAAAABh8AAAAAAAAGIgAAAAAAAQYlAAAAAAABBikAAAAAAAIGLwAAAAAAAwY7AAAAAAAEBlMAAAAAAAcGgwAAAAAACQYDAgAAEAAABAQAAAAAAAAEBQAAACAAAAUGAAAAAAAABQcAAAAgAAAFCQAAAAAAAAUKAAAAAAAABgwAAAAAAAAGDwAAAAAAAAYSAAAAAAAABhUAAAAAAAAGGAAAAAAAAAYbAAAAAAAABh4AAAAAAAAGIQAAAAAAAQYjAAAAAAABBicAAAAAAAIGKwAAAAAAAwYzAAAAAAAEBkMAAAAAAAUGYwAAAAAACAYDAQAAIAAABAQAAAAwAAAEBAAAABAAAAQFAAAAIAAABQcAAAAgAAAFCAAAACAAAAUKAAAAIAAABQsAAAAAAAAGDgAAAAAAAAYRAAAAAAAABhQAAAAAAAAGFwAAAAAAAAYaAAAAAAAABh0AAAAAAAAGIAAAAAAAEAYDAAEAAAAPBgOAAAAAAA4GA0AAAAAADQYDIAAAAAAMBgMQAAAAAAsGAwgAAAAACgYDBABBpB0L2QEBAAAAAwAAAAcAAAAPAAAAHwAAAD8AAAB/AAAA/wAAAP8BAAD/AwAA/wcAAP8PAAD/HwAA/z8AAP9/AAD//wAA//8BAP//AwD//wcA//8PAP//HwD//z8A//9/AP///wD///8B////A////wf///8P////H////z////9/AAAAAAEAAAACAAAABAAAAAAAAAACAAAABAAAAAgAAAAAAAAAAQAAAAIAAAABAAAABAAAAAQAAAAEAAAABAAAAAgAAAAIAAAACAAAAAcAAAAIAAAACQAAAAoAAAALAEGgIAsDwBBQ";export{Q as ZSTDDecoder}; diff --git a/examples/jsm/loaders/3DMLoader.js b/examples/jsm/loaders/3DMLoader.js index f2ccf547cd28a1..88a3d183375bab 100644 --- a/examples/jsm/loaders/3DMLoader.js +++ b/examples/jsm/loaders/3DMLoader.js @@ -15,7 +15,6 @@ import { PointLight, SpotLight, RectAreaLight, - Vector3, Sprite, SpriteMaterial, CanvasTexture, @@ -625,7 +624,7 @@ class Rhino3dmLoader extends Loader { light.position.set( geometry.location[ 0 ] - ( height / 2 ), geometry.location[ 1 ], geometry.location[ 2 ] - ( width / 2 ) ); light.height = height; light.width = width; - light.lookAt( new Vector3( geometry.direction[ 0 ], geometry.direction[ 1 ], geometry.direction[ 2 ] ) ); + light.lookAt( geometry.direction[ 0 ], geometry.direction[ 1 ], geometry.direction[ 2 ] ); break; diff --git a/examples/jsm/loaders/ColladaLoader.js b/examples/jsm/loaders/ColladaLoader.js index 77f261303536e0..e87d1954dd3ac7 100644 --- a/examples/jsm/loaders/ColladaLoader.js +++ b/examples/jsm/loaders/ColladaLoader.js @@ -3764,6 +3764,34 @@ class ColladaLoader extends Loader { } + // Collada allows to use phong and lambert materials with lines. Replacing these cases with LineBasicMaterial. + + if ( type === 'lines' || type === 'linestrips' ) { + + for ( let i = 0, l = materials.length; i < l; i ++ ) { + + const material = materials[ i ]; + + if ( material.isMeshPhongMaterial === true || material.isMeshLambertMaterial === true ) { + + const lineMaterial = new LineBasicMaterial(); + + // copy compatible properties + + lineMaterial.color.copy( material.color ); + lineMaterial.opacity = material.opacity; + lineMaterial.transparent = material.transparent; + + // replace material + + materials[ i ] = lineMaterial; + + } + + } + + } + // regard skinning const skinning = ( geometry.data.attributes.skinIndex !== undefined ); diff --git a/examples/jsm/loaders/DRACOLoader.js b/examples/jsm/loaders/DRACOLoader.js index 53afc5b11f204a..8ddb634990046e 100644 --- a/examples/jsm/loaders/DRACOLoader.js +++ b/examples/jsm/loaders/DRACOLoader.js @@ -73,21 +73,12 @@ class DRACOLoader extends Loader { loader.load( url, ( buffer ) => { - const taskConfig = { - attributeIDs: this.defaultAttributeIDs, - attributeTypes: this.defaultAttributeTypes, - useUniqueIDs: false - }; - - this.decodeGeometry( buffer, taskConfig ) - .then( onLoad ) - .catch( onError ); + this.decodeDracoFile( buffer, onLoad ).catch( onError ); }, onProgress, onError ); } - /** @deprecated Kept for backward-compatibility with previous DRACOLoader versions. */ decodeDracoFile( buffer, callback, attributeIDs, attributeTypes ) { const taskConfig = { @@ -96,29 +87,12 @@ class DRACOLoader extends Loader { useUniqueIDs: !! attributeIDs }; - this.decodeGeometry( buffer, taskConfig ).then( callback ); + return this.decodeGeometry( buffer, taskConfig ).then( callback ); } decodeGeometry( buffer, taskConfig ) { - // TODO: For backward-compatibility, support 'attributeTypes' objects containing - // references (rather than names) to typed array constructors. These must be - // serialized before sending them to the worker. - for ( const attribute in taskConfig.attributeTypes ) { - - const type = taskConfig.attributeTypes[ attribute ]; - - if ( type.BYTES_PER_ELEMENT !== undefined ) { - - taskConfig.attributeTypes[ attribute ] = type.name; - - } - - } - - // - const taskKey = JSON.stringify( taskConfig ); // Check for an existing task using this buffer. A transferred buffer cannot be transferred diff --git a/examples/jsm/loaders/FBXLoader.js b/examples/jsm/loaders/FBXLoader.js index fc924604759283..a4f893b40544b3 100644 --- a/examples/jsm/loaders/FBXLoader.js +++ b/examples/jsm/loaders/FBXLoader.js @@ -1483,6 +1483,12 @@ class FBXTreeParser { // parse Geometry data from FBXTree and return map of BufferGeometries class GeometryParser { + constructor() { + + this.negativeMaterialIndices = false; + + } + // Parse nodes in FBXTree.Objects.Geometry parse( deformers ) { @@ -1503,6 +1509,14 @@ class GeometryParser { } + // report warnings + + if ( this.negativeMaterialIndices === true ) { + + console.warn( 'THREE.FBXLoader: The FBX file contains invalid (negative) material indices. The asset might not render as expected.' ); + + } + return geometryMap; } @@ -1897,6 +1911,13 @@ class GeometryParser { materialIndex = getData( polygonVertexIndex, polygonIndex, vertexIndex, geoInfo.material )[ 0 ]; + if ( materialIndex < 0 ) { + + scope.negativeMaterialIndices = true; + materialIndex = 0; // fallback + + } + } if ( geoInfo.uv ) { @@ -1922,6 +1943,8 @@ class GeometryParser { if ( endOfFace ) { + if ( faceLength > 4 ) console.warn( 'THREE.FBXLoader: Polygons with more than four sides are not supported. Make sure to triangulate the geometry during export.' ); + scope.genFace( buffers, geoInfo, facePositionIndexes, materialIndex, faceNormals, faceColors, faceUVs, faceWeights, faceWeightIndices, faceLength ); polygonIndex ++; @@ -3958,7 +3981,7 @@ function generateTransform( transformData ) { if ( transformData.preRotation ) { const array = transformData.preRotation.map( MathUtils.degToRad ); - array.push( transformData.eulerOrder ); + array.push( transformData.eulerOrder || Euler.DefaultOrder ); lPreRotationM.makeRotationFromEuler( tempEuler.fromArray( array ) ); } @@ -3966,7 +3989,7 @@ function generateTransform( transformData ) { if ( transformData.rotation ) { const array = transformData.rotation.map( MathUtils.degToRad ); - array.push( transformData.eulerOrder ); + array.push( transformData.eulerOrder || Euler.DefaultOrder ); lRotationM.makeRotationFromEuler( tempEuler.fromArray( array ) ); } @@ -3974,7 +3997,7 @@ function generateTransform( transformData ) { if ( transformData.postRotation ) { const array = transformData.postRotation.map( MathUtils.degToRad ); - array.push( transformData.eulerOrder ); + array.push( transformData.eulerOrder || Euler.DefaultOrder ); lPostRotationM.makeRotationFromEuler( tempEuler.fromArray( array ) ); lPostRotationM.invert(); diff --git a/examples/jsm/loaders/FontLoader.js b/examples/jsm/loaders/FontLoader.js index e74a16f02b089b..93caeb5bbaad29 100644 --- a/examples/jsm/loaders/FontLoader.js +++ b/examples/jsm/loaders/FontLoader.js @@ -19,23 +19,10 @@ class FontLoader extends Loader { const loader = new FileLoader( this.manager ); loader.setPath( this.path ); loader.setRequestHeader( this.requestHeader ); - loader.setWithCredentials( scope.withCredentials ); + loader.setWithCredentials( this.withCredentials ); loader.load( url, function ( text ) { - let 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 ) ); - - } - - const font = scope.parse( json ); + const font = scope.parse( JSON.parse( text ) ); if ( onLoad ) onLoad( font ); diff --git a/examples/jsm/loaders/GLTFLoader.js b/examples/jsm/loaders/GLTFLoader.js index 2edc9a26cb581c..a5d49f8737bfc4 100644 --- a/examples/jsm/loaders/GLTFLoader.js +++ b/examples/jsm/loaders/GLTFLoader.js @@ -12,6 +12,7 @@ import { FrontSide, Group, ImageBitmapLoader, + InstancedMesh, InterleavedBuffer, InterleavedBufferAttribute, Interpolant, @@ -52,7 +53,6 @@ import { SkinnedMesh, Sphere, SpotLight, - TangentSpaceNormalMap, Texture, TextureLoader, TriangleFanDrawMode, @@ -147,6 +147,12 @@ class GLTFLoader extends Loader { } ); + this.register( function ( parser ) { + + return new GLTFMeshGpuInstancing( parser ); + + } ); + } load( url, onLoad, onProgress, onError ) { @@ -277,15 +283,15 @@ class GLTFLoader extends Loader { parse( data, path, onLoad, onError ) { - let content; + let json; const extensions = {}; const plugins = {}; if ( typeof data === 'string' ) { - content = data; + json = JSON.parse( data ); - } else { + } else if ( data instanceof ArrayBuffer ) { const magic = LoaderUtils.decodeText( new Uint8Array( data, 0, 4 ) ); @@ -302,17 +308,19 @@ class GLTFLoader extends Loader { } - content = extensions[ EXTENSIONS.KHR_BINARY_GLTF ].content; + json = JSON.parse( extensions[ EXTENSIONS.KHR_BINARY_GLTF ].content ); } else { - content = LoaderUtils.decodeText( new Uint8Array( data ) ); + json = JSON.parse( LoaderUtils.decodeText( new Uint8Array( data ) ) ); } - } + } else { - const json = JSON.parse( content ); + json = data; + + } if ( json.asset === undefined || json.asset.version[ 0 ] < 2 ) { @@ -360,10 +368,6 @@ class GLTFLoader extends Loader { extensions[ extensionName ] = new GLTFMaterialsUnlitExtension(); break; - case EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: - extensions[ extensionName ] = new GLTFMaterialsPbrSpecularGlossinessExtension(); - break; - case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION: extensions[ extensionName ] = new GLTFDracoMeshCompressionExtension( json, this.dracoLoader ); break; @@ -456,7 +460,6 @@ const EXTENSIONS = { KHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual', KHR_MATERIALS_CLEARCOAT: 'KHR_materials_clearcoat', KHR_MATERIALS_IOR: 'KHR_materials_ior', - KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness', KHR_MATERIALS_SHEEN: 'KHR_materials_sheen', KHR_MATERIALS_SPECULAR: 'KHR_materials_specular', KHR_MATERIALS_TRANSMISSION: 'KHR_materials_transmission', @@ -468,7 +471,8 @@ const EXTENSIONS = { KHR_MESH_QUANTIZATION: 'KHR_mesh_quantization', KHR_MATERIALS_EMISSIVE_STRENGTH: 'KHR_materials_emissive_strength', EXT_TEXTURE_WEBP: 'EXT_texture_webp', - EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression' + EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression', + EXT_MESH_GPU_INSTANCING: 'EXT_mesh_gpu_instancing' }; /** @@ -566,6 +570,8 @@ class GLTFLightsExtension { lightNode.decay = 2; + assignExtrasToUserData( lightNode, lightDef ); + if ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity; lightNode.name = parser.createUniqueName( lightDef.name || ( 'light_' + lightIndex ) ); @@ -578,6 +584,14 @@ class GLTFLightsExtension { } + getDependency( type, index ) { + + if ( type !== 'light' ) return; + + return this._loadLight( index ); + + } + createNodeAttachment( nodeIndex ) { const self = this; @@ -1044,7 +1058,7 @@ class GLTFMaterialsVolumeExtension { } - materialParams.attenuationDistance = extension.attenuationDistance || 0; + materialParams.attenuationDistance = extension.attenuationDistance || Infinity; const colorArray = extension.attenuationColor || [ 1, 1, 1 ]; materialParams.attenuationColor = new Color( colorArray[ 0 ], colorArray[ 1 ], colorArray[ 2 ] ); @@ -1341,7 +1355,7 @@ class GLTFMeshoptCompression { } - return Promise.all( [ buffer, decoder.ready ] ).then( function ( res ) { + return buffer.then( function ( res ) { const byteOffset = extensionDef.byteOffset || 0; const byteLength = extensionDef.byteLength || 0; @@ -1349,11 +1363,28 @@ class GLTFMeshoptCompression { const count = extensionDef.count; const stride = extensionDef.byteStride; - const result = new ArrayBuffer( count * stride ); - const source = new Uint8Array( res[ 0 ], byteOffset, byteLength ); + const source = new Uint8Array( res, byteOffset, byteLength ); + + if ( decoder.decodeGltfBufferAsync ) { + + return decoder.decodeGltfBufferAsync( count, stride, source, extensionDef.mode, extensionDef.filter ).then( function ( res ) { + + return res.buffer; - decoder.decodeGltfBuffer( new Uint8Array( result ), count, stride, source, extensionDef.mode, extensionDef.filter ); - return result; + } ); + + } else { + + // Support for MeshoptDecoder 0.18 or earlier, without decodeGltfBufferAsync + return decoder.ready.then( function () { + + const result = new ArrayBuffer( count * stride ); + decoder.decodeGltfBuffer( new Uint8Array( result ), count, stride, source, extensionDef.mode, extensionDef.filter ); + return result; + + } ); + + } } ); @@ -1367,6 +1398,160 @@ class GLTFMeshoptCompression { } +/** + * GPU Instancing Extension + * + * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_mesh_gpu_instancing + * + */ +class GLTFMeshGpuInstancing { + + constructor( parser ) { + + this.name = EXTENSIONS.EXT_MESH_GPU_INSTANCING; + this.parser = parser; + + } + + createNodeMesh( nodeIndex ) { + + const json = this.parser.json; + const nodeDef = json.nodes[ nodeIndex ]; + + if ( ! nodeDef.extensions || ! nodeDef.extensions[ this.name ] || + nodeDef.mesh === undefined ) { + + return null; + + } + + const meshDef = json.meshes[ nodeDef.mesh ]; + + // No Points or Lines + Instancing support yet + + for ( const primitive of meshDef.primitives ) { + + if ( primitive.mode !== WEBGL_CONSTANTS.TRIANGLES && + primitive.mode !== WEBGL_CONSTANTS.TRIANGLE_STRIP && + primitive.mode !== WEBGL_CONSTANTS.TRIANGLE_FAN && + primitive.mode !== undefined ) { + + return null; + + } + + } + + const extensionDef = nodeDef.extensions[ this.name ]; + const attributesDef = extensionDef.attributes; + + // @TODO: Can we support InstancedMesh + SkinnedMesh? + + const pending = []; + const attributes = {}; + + for ( const key in attributesDef ) { + + pending.push( this.parser.getDependency( 'accessor', attributesDef[ key ] ).then( accessor => { + + attributes[ key ] = accessor; + return attributes[ key ]; + + } ) ); + + } + + if ( pending.length < 1 ) { + + return null; + + } + + pending.push( this.parser.createNodeMesh( nodeIndex ) ); + + return Promise.all( pending ).then( results => { + + const nodeObject = results.pop(); + const meshes = nodeObject.isGroup ? nodeObject.children : [ nodeObject ]; + const count = results[ 0 ].count; // All attribute counts should be same + const instancedMeshes = []; + + for ( const mesh of meshes ) { + + // Temporal variables + const m = new Matrix4(); + const p = new Vector3(); + const q = new Quaternion(); + const s = new Vector3( 1, 1, 1 ); + + const instancedMesh = new InstancedMesh( mesh.geometry, mesh.material, count ); + + for ( let i = 0; i < count; i ++ ) { + + if ( attributes.TRANSLATION ) { + + p.fromBufferAttribute( attributes.TRANSLATION, i ); + + } + + if ( attributes.ROTATION ) { + + q.fromBufferAttribute( attributes.ROTATION, i ); + + } + + if ( attributes.SCALE ) { + + s.fromBufferAttribute( attributes.SCALE, i ); + + } + + instancedMesh.setMatrixAt( i, m.compose( p, q, s ) ); + + } + + // Add instance attributes to the geometry, excluding TRS. + for ( const attributeName in attributes ) { + + if ( attributeName !== 'TRANSLATION' && + attributeName !== 'ROTATION' && + attributeName !== 'SCALE' ) { + + mesh.geometry.setAttribute( attributeName, attributes[ attributeName ] ); + + } + + } + + // Just in case + Object3D.prototype.copy.call( instancedMesh, mesh ); + + // https://github.com/mrdoob/three.js/issues/18334 + instancedMesh.frustumCulled = false; + this.parser.assignFinalMaterial( instancedMesh ); + + instancedMeshes.push( instancedMesh ); + + } + + if ( nodeObject.isGroup ) { + + nodeObject.clear(); + + nodeObject.add( ... instancedMeshes ); + + return nodeObject; + + } + + return instancedMeshes[ 0 ]; + + } ); + + } + +} + /* BINARY EXTENSION */ const BINARY_EXTENSION_HEADER_MAGIC = 'glTF'; const BINARY_EXTENSION_HEADER_LENGTH = 12; @@ -1487,7 +1672,7 @@ class GLTFDracoMeshCompressionExtension { const accessorDef = json.accessors[ primitive.attributes[ attributeName ] ]; const componentType = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ]; - attributeTypeMap[ threeAttributeName ] = componentType; + attributeTypeMap[ threeAttributeName ] = componentType.name; attributeNormalizedMap[ threeAttributeName ] = accessorDef.normalized === true; } @@ -1577,335 +1762,6 @@ class GLTFTextureTransformExtension { } -/** - * Specular-Glossiness Extension - * - * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness - */ - -/** - * A sub class of StandardMaterial with some of the functionality - * changed via the `onBeforeCompile` callback - * @pailhead - */ -class GLTFMeshStandardSGMaterial extends MeshStandardMaterial { - - constructor( params ) { - - super(); - - this.isGLTFSpecularGlossinessMaterial = true; - - //various chunks that need replacing - const specularMapParsFragmentChunk = [ - '#ifdef USE_SPECULARMAP', - ' uniform sampler2D specularMap;', - '#endif' - ].join( '\n' ); - - const glossinessMapParsFragmentChunk = [ - '#ifdef USE_GLOSSINESSMAP', - ' uniform sampler2D glossinessMap;', - '#endif' - ].join( '\n' ); - - const specularMapFragmentChunk = [ - 'vec3 specularFactor = specular;', - '#ifdef USE_SPECULARMAP', - ' vec4 texelSpecular = texture2D( specularMap, vUv );', - ' // reads channel RGB, compatible with a glTF Specular-Glossiness (RGBA) texture', - ' specularFactor *= texelSpecular.rgb;', - '#endif' - ].join( '\n' ); - - const glossinessMapFragmentChunk = [ - 'float glossinessFactor = glossiness;', - '#ifdef USE_GLOSSINESSMAP', - ' vec4 texelGlossiness = texture2D( glossinessMap, vUv );', - ' // reads channel A, compatible with a glTF Specular-Glossiness (RGBA) texture', - ' glossinessFactor *= texelGlossiness.a;', - '#endif' - ].join( '\n' ); - - const lightPhysicalFragmentChunk = [ - 'PhysicalMaterial material;', - 'material.diffuseColor = diffuseColor.rgb * ( 1. - max( specularFactor.r, max( specularFactor.g, specularFactor.b ) ) );', - 'vec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );', - 'float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );', - 'material.roughness = max( 1.0 - glossinessFactor, 0.0525 ); // 0.0525 corresponds to the base mip of a 256 cubemap.', - 'material.roughness += geometryRoughness;', - 'material.roughness = min( material.roughness, 1.0 );', - 'material.specularColor = specularFactor;', - ].join( '\n' ); - - const uniforms = { - specular: { value: new Color().setHex( 0xffffff ) }, - glossiness: { value: 1 }, - specularMap: { value: null }, - glossinessMap: { value: null } - }; - - this._extraUniforms = uniforms; - - this.onBeforeCompile = function ( shader ) { - - for ( const uniformName in uniforms ) { - - shader.uniforms[ uniformName ] = uniforms[ uniformName ]; - - } - - shader.fragmentShader = shader.fragmentShader - .replace( 'uniform float roughness;', 'uniform vec3 specular;' ) - .replace( 'uniform float metalness;', 'uniform float glossiness;' ) - .replace( '#include ', specularMapParsFragmentChunk ) - .replace( '#include ', glossinessMapParsFragmentChunk ) - .replace( '#include ', specularMapFragmentChunk ) - .replace( '#include ', glossinessMapFragmentChunk ) - .replace( '#include ', lightPhysicalFragmentChunk ); - - }; - - Object.defineProperties( this, { - - specular: { - get: function () { - - return uniforms.specular.value; - - }, - set: function ( v ) { - - uniforms.specular.value = v; - - } - }, - - specularMap: { - get: function () { - - return uniforms.specularMap.value; - - }, - set: function ( v ) { - - uniforms.specularMap.value = v; - - if ( v ) { - - this.defines.USE_SPECULARMAP = ''; // USE_UV is set by the renderer for specular maps - - } else { - - delete this.defines.USE_SPECULARMAP; - - } - - } - }, - - glossiness: { - get: function () { - - return uniforms.glossiness.value; - - }, - set: function ( v ) { - - uniforms.glossiness.value = v; - - } - }, - - glossinessMap: { - get: function () { - - return uniforms.glossinessMap.value; - - }, - set: function ( v ) { - - uniforms.glossinessMap.value = v; - - if ( v ) { - - this.defines.USE_GLOSSINESSMAP = ''; - this.defines.USE_UV = ''; - - } else { - - delete this.defines.USE_GLOSSINESSMAP; - delete this.defines.USE_UV; - - } - - } - } - - } ); - - delete this.metalness; - delete this.roughness; - delete this.metalnessMap; - delete this.roughnessMap; - - this.setValues( params ); - - } - - copy( source ) { - - super.copy( source ); - - this.specularMap = source.specularMap; - this.specular.copy( source.specular ); - this.glossinessMap = source.glossinessMap; - this.glossiness = source.glossiness; - delete this.metalness; - delete this.roughness; - delete this.metalnessMap; - delete this.roughnessMap; - return this; - - } - -} - - -class GLTFMaterialsPbrSpecularGlossinessExtension { - - constructor() { - - this.name = EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS; - - this.specularGlossinessParams = [ - 'color', - 'map', - 'lightMap', - 'lightMapIntensity', - 'aoMap', - 'aoMapIntensity', - 'emissive', - 'emissiveIntensity', - 'emissiveMap', - 'bumpMap', - 'bumpScale', - 'normalMap', - 'normalMapType', - 'displacementMap', - 'displacementScale', - 'displacementBias', - 'specularMap', - 'specular', - 'glossinessMap', - 'glossiness', - 'alphaMap', - 'envMap', - 'envMapIntensity' - ]; - - } - - getMaterialType() { - - return GLTFMeshStandardSGMaterial; - - } - - extendParams( materialParams, materialDef, parser ) { - - const pbrSpecularGlossiness = materialDef.extensions[ this.name ]; - - materialParams.color = new Color( 1.0, 1.0, 1.0 ); - materialParams.opacity = 1.0; - - const pending = []; - - if ( Array.isArray( pbrSpecularGlossiness.diffuseFactor ) ) { - - const array = pbrSpecularGlossiness.diffuseFactor; - - materialParams.color.fromArray( array ); - materialParams.opacity = array[ 3 ]; - - } - - if ( pbrSpecularGlossiness.diffuseTexture !== undefined ) { - - pending.push( parser.assignTexture( materialParams, 'map', pbrSpecularGlossiness.diffuseTexture, sRGBEncoding ) ); - - } - - materialParams.emissive = new Color( 0.0, 0.0, 0.0 ); - materialParams.glossiness = pbrSpecularGlossiness.glossinessFactor !== undefined ? pbrSpecularGlossiness.glossinessFactor : 1.0; - materialParams.specular = new Color( 1.0, 1.0, 1.0 ); - - if ( Array.isArray( pbrSpecularGlossiness.specularFactor ) ) { - - materialParams.specular.fromArray( pbrSpecularGlossiness.specularFactor ); - - } - - if ( pbrSpecularGlossiness.specularGlossinessTexture !== undefined ) { - - const specGlossMapDef = pbrSpecularGlossiness.specularGlossinessTexture; - pending.push( parser.assignTexture( materialParams, 'glossinessMap', specGlossMapDef ) ); - pending.push( parser.assignTexture( materialParams, 'specularMap', specGlossMapDef, sRGBEncoding ) ); - - } - - return Promise.all( pending ); - - } - - createMaterial( materialParams ) { - - const material = new GLTFMeshStandardSGMaterial( materialParams ); - material.fog = true; - - material.color = materialParams.color; - - material.map = materialParams.map === undefined ? null : materialParams.map; - - material.lightMap = null; - material.lightMapIntensity = 1.0; - - material.aoMap = materialParams.aoMap === undefined ? null : materialParams.aoMap; - material.aoMapIntensity = 1.0; - - material.emissive = materialParams.emissive; - material.emissiveIntensity = materialParams.emissiveIntensity === undefined ? 1.0 : materialParams.emissiveIntensity; - material.emissiveMap = materialParams.emissiveMap === undefined ? null : materialParams.emissiveMap; - - material.bumpMap = materialParams.bumpMap === undefined ? null : materialParams.bumpMap; - material.bumpScale = 1; - - material.normalMap = materialParams.normalMap === undefined ? null : materialParams.normalMap; - material.normalMapType = TangentSpaceNormalMap; - - if ( materialParams.normalScale ) material.normalScale = materialParams.normalScale; - - material.displacementMap = null; - material.displacementScale = 1; - material.displacementBias = 0; - - material.specularMap = materialParams.specularMap === undefined ? null : materialParams.specularMap; - material.specular = materialParams.specular; - - material.glossinessMap = materialParams.glossinessMap === undefined ? null : materialParams.glossinessMap; - material.glossiness = materialParams.glossiness; - - material.alphaMap = null; - - material.envMap = materialParams.envMap === undefined ? null : materialParams.envMap; - material.envMapIntensity = 1.0; - - return material; - - } - -} - /** * Mesh Quantization Extension * @@ -2406,10 +2262,18 @@ class GLTFParser { // Use an ImageBitmapLoader if imageBitmaps are supported. Moves much of the // expensive work of uploading a texture to the GPU off the main thread. + + let isSafari = false; + let isFirefox = false; + let firefoxVersion = - 1; - const isSafari = /^((?!chrome|android).)*safari/i.test( navigator.userAgent ) === true; - const isFirefox = navigator.userAgent.indexOf( 'Firefox' ) > - 1; - const firefoxVersion = isFirefox ? navigator.userAgent.match( /Firefox\/([0-9]+)\./ )[ 1 ] : - 1; + if ( typeof navigator !== 'undefined' ) { + + isSafari = /^((?!chrome|android).)*safari/i.test( navigator.userAgent ) === true; + isFirefox = navigator.userAgent.indexOf( 'Firefox' ) > - 1; + firefoxVersion = isFirefox ? navigator.userAgent.match( /Firefox\/([0-9]+)\./ )[ 1 ] : - 1; + + } if ( typeof createImageBitmap === 'undefined' || isSafari || ( isFirefox && firefoxVersion < 98 ) ) { @@ -2734,7 +2598,19 @@ class GLTFParser { break; default: - throw new Error( 'Unknown type: ' + type ); + dependency = this._invokeOne( function ( ext ) { + + return ext != this && ext.getDependency && ext.getDependency( type, index ); + + } ); + + if ( ! dependency ) { + + throw new Error( 'Unknown type: ' + type ); + + } + + break; } @@ -2844,10 +2720,12 @@ class GLTFParser { if ( accessorDef.bufferView === undefined && accessorDef.sparse === undefined ) { - // Ignore empty accessors, which may be used to declare runtime - // information about attributes coming from another source (e.g. Draco - // compression extension). - return Promise.resolve( null ); + const itemSize = WEBGL_TYPE_SIZES[ accessorDef.type ]; + const TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ]; + const normalized = accessorDef.normalized === true; + + const array = new TypedArray( accessorDef.count * itemSize ); + return Promise.resolve( new BufferAttribute( array, itemSize, normalized ) ); } @@ -2965,7 +2843,7 @@ class GLTFParser { /** * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#textures * @param {number} textureIndex - * @return {Promise} + * @return {Promise} */ loadTexture( textureIndex ) { @@ -3009,7 +2887,7 @@ class GLTFParser { texture.flipY = false; - if ( textureDef.name ) texture.name = textureDef.name; + texture.name = textureDef.name || sourceDef.name || ''; const samplers = json.samplers || {}; const sampler = samplers[ textureDef.sampler ] || {}; @@ -3135,6 +3013,8 @@ class GLTFParser { return this.getDependency( 'texture', mapDef.index ).then( function ( texture ) { + if ( ! texture ) return null; + // Materials sample aoMap from UV set 1 and other maps from UV set 0 - this can't be configured // However, we will copy UV set 0 to UV set 1 on demand for aoMap if ( mapDef.texCoord !== undefined && mapDef.texCoord != 0 && ! ( mapName === 'aoMap' && mapDef.texCoord == 1 ) ) { @@ -3233,7 +3113,6 @@ class GLTFParser { let cacheKey = 'ClonedMaterial:' + material.uuid + ':'; - if ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:'; if ( useDerivativeTangents ) cacheKey += 'derivative-tangents:'; if ( useVertexColors ) cacheKey += 'vertex-colors:'; if ( useFlatShading ) cacheKey += 'flat-shading:'; @@ -3301,13 +3180,7 @@ class GLTFParser { const pending = []; - if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ] ) { - - const sgExtension = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ]; - materialType = sgExtension.getMaterialType(); - pending.push( sgExtension.extendParams( materialParams, materialDef, parser ) ); - - } else if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) { + if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) { const kmuExtension = extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ]; materialType = kmuExtension.getMaterialType(); @@ -3431,17 +3304,7 @@ class GLTFParser { return Promise.all( pending ).then( function () { - let material; - - if ( materialType === GLTFMeshStandardSGMaterial ) { - - material = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].createMaterial( materialParams ); - - } else { - - material = new materialType( materialParams ); - - } + const material = new materialType( materialParams ); if ( materialDef.name ) material.name = materialDef.name; @@ -3730,25 +3593,65 @@ class GLTFParser { /** * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins * @param {number} skinIndex - * @return {Promise} + * @return {Promise} */ loadSkin( skinIndex ) { const skinDef = this.json.skins[ skinIndex ]; - const skinEntry = { joints: skinDef.joints }; + const pending = []; - if ( skinDef.inverseBindMatrices === undefined ) { + for ( let i = 0, il = skinDef.joints.length; i < il; i ++ ) { - return Promise.resolve( skinEntry ); + pending.push( this.getDependency( 'node', skinDef.joints[ i ] ) ); } - return this.getDependency( 'accessor', skinDef.inverseBindMatrices ).then( function ( accessor ) { + if ( skinDef.inverseBindMatrices !== undefined ) { + + pending.push( this.getDependency( 'accessor', skinDef.inverseBindMatrices ) ); + + } else { + + pending.push( null ); + + } + + return Promise.all( pending ).then( function ( results ) { + + const inverseBindMatrices = results.pop(); + const jointNodes = results; + + const bones = []; + const boneInverses = []; + + for ( let i = 0, il = jointNodes.length; i < il; i ++ ) { - skinEntry.inverseBindMatrices = accessor; + const jointNode = jointNodes[ i ]; - return skinEntry; + if ( jointNode ) { + + bones.push( jointNode ); + + const mat = new Matrix4(); + + if ( inverseBindMatrices !== null ) { + + mat.fromArray( inverseBindMatrices.array, i * 16 ); + + } + + boneInverses.push( mat ); + + } else { + + console.warn( 'THREE.GLTFLoader: Joint "%s" could not be found.', skinDef.joints[ i ] ); + + } + + } + + return new Skeleton( bones, boneInverses ); } ); @@ -3776,7 +3679,7 @@ class GLTFParser { const channel = animationDef.channels[ i ]; const sampler = animationDef.samplers[ channel.sampler ]; const target = channel.target; - const name = target.node !== undefined ? target.node : target.id; // NOTE: target.id is deprecated. + const name = target.node; const input = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.input ] : sampler.input; const output = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.output ] : sampler.output; @@ -4185,58 +4088,13 @@ function buildNodeHierarchy( nodeId, parentObject, json, parser ) { // build skeleton here as well - let skinEntry; - - return parser.getDependency( 'skin', nodeDef.skin ).then( function ( skin ) { - - skinEntry = skin; - - const pendingJoints = []; - - for ( let i = 0, il = skinEntry.joints.length; i < il; i ++ ) { - - pendingJoints.push( parser.getDependency( 'node', skinEntry.joints[ i ] ) ); - - } - - return Promise.all( pendingJoints ); - - } ).then( function ( jointNodes ) { + return parser.getDependency( 'skin', nodeDef.skin ).then( function ( skeleton ) { node.traverse( function ( mesh ) { - if ( ! mesh.isMesh ) return; - - const bones = []; - const boneInverses = []; - - for ( let j = 0, jl = jointNodes.length; j < jl; j ++ ) { - - const jointNode = jointNodes[ j ]; - - if ( jointNode ) { - - bones.push( jointNode ); - - const mat = new Matrix4(); - - if ( skinEntry.inverseBindMatrices !== undefined ) { - - mat.fromArray( skinEntry.inverseBindMatrices.array, j * 16 ); - - } - - boneInverses.push( mat ); - - } else { - - console.warn( 'THREE.GLTFLoader: Joint "%s" could not be found.', skinEntry.joints[ j ] ); - - } - - } + if ( ! mesh.isSkinnedMesh ) return; - mesh.bind( new Skeleton( bones, boneInverses ), mesh.matrixWorld ); + mesh.bind( skeleton, mesh.matrixWorld ); } ); diff --git a/examples/jsm/loaders/HDRCubeTextureLoader.js b/examples/jsm/loaders/HDRCubeTextureLoader.js index 643f664298f838..2e0f8bd8d09556 100644 --- a/examples/jsm/loaders/HDRCubeTextureLoader.js +++ b/examples/jsm/loaders/HDRCubeTextureLoader.js @@ -23,19 +23,6 @@ class HDRCubeTextureLoader extends Loader { load( urls, onLoad, onProgress, onError ) { - if ( ! Array.isArray( urls ) ) { - - console.warn( 'THREE.HDRCubeTextureLoader signature has changed. Use .setDataType() instead.' ); - - this.setDataType( urls ); - - urls = onLoad; - onLoad = onProgress; - onProgress = onError; - onError = arguments[ 4 ]; - - } - const texture = new CubeTexture(); texture.type = this.type; diff --git a/examples/jsm/loaders/KTX2Loader.js b/examples/jsm/loaders/KTX2Loader.js index c9642625518ab4..38b87cbc3978cf 100644 --- a/examples/jsm/loaders/KTX2Loader.js +++ b/examples/jsm/loaders/KTX2Loader.js @@ -13,6 +13,7 @@ import { CompressedTexture, + CompressedArrayTexture, Data3DTexture, DataTexture, FileLoader, @@ -35,15 +36,15 @@ import { RGBAFormat, RGFormat, sRGBEncoding, - UnsignedByteType + UnsignedByteType, } from 'three'; import { WorkerPool } from '../utils/WorkerPool.js'; -import * as KTX from '../libs/ktx-parse.module.js'; - -const { +import { read, KHR_DF_FLAG_ALPHA_PREMULTIPLIED, KHR_DF_TRANSFER_SRGB, + KHR_SUPERCOMPRESSION_NONE, + KHR_SUPERCOMPRESSION_ZSTD, VK_FORMAT_UNDEFINED, VK_FORMAT_R16_SFLOAT, VK_FORMAT_R16G16_SFLOAT, @@ -57,12 +58,15 @@ const { VK_FORMAT_R8G8_UNORM, VK_FORMAT_R8G8B8A8_SRGB, VK_FORMAT_R8G8B8A8_UNORM, -} = KTX; // eslint-disable-line no-undef +} from '../libs/ktx-parse.module.js'; +import { ZSTDDecoder } from '../libs/zstddec.module.js'; const _taskCache = new WeakMap(); let _activeLoaders = 0; +let _zstd; + class KTX2Loader extends Loader { constructor( manager ) { @@ -233,16 +237,21 @@ class KTX2Loader extends Loader { } - _createTextureFrom( transcodeResult ) { + _createTextureFrom( transcodeResult, container ) { const { mipmaps, width, height, format, type, error, dfdTransferFn, dfdFlags } = transcodeResult; if ( type === 'error' ) return Promise.reject( error ); - const texture = new CompressedTexture( mipmaps, width, height, format, UnsignedByteType ); + const texture = container.layerCount > 1 + ? new CompressedArrayTexture( mipmaps, width, height, container.layerCount, format, UnsignedByteType ) + : new CompressedTexture( mipmaps, width, height, format, UnsignedByteType ); + + texture.minFilter = mipmaps.length === 1 ? LinearFilter : LinearMipmapLinearFilter; texture.magFilter = LinearFilter; texture.generateMipmaps = false; + texture.needsUpdate = true; texture.encoding = dfdTransferFn === KHR_DF_TRANSFER_SRGB ? sRGBEncoding : LinearEncoding; texture.premultiplyAlpha = !! ( dfdFlags & KHR_DF_FLAG_ALPHA_PREMULTIPLIED ); @@ -254,9 +263,9 @@ class KTX2Loader extends Loader { /** * @param {ArrayBuffer} buffer * @param {object?} config - * @return {Promise} + * @return {Promise} */ - _createTexture( buffer, config = {} ) { + async _createTexture( buffer, config = {} ) { const container = read( new Uint8Array( buffer ) ); @@ -267,13 +276,12 @@ class KTX2Loader extends Loader { } // - const taskConfig = config; const texturePending = this.init().then( () => { return this.workerPool.postMessage( { type: 'transcode', buffer, taskConfig: taskConfig }, [ buffer ] ); - } ).then( ( e ) => this._createTextureFrom( e.data ) ); + } ).then( ( e ) => this._createTextureFrom( e.data, container ) ); // Cache the task result. _taskCache.set( buffer, { promise: texturePending } ); @@ -434,6 +442,7 @@ KTX2Loader.BasisWorker = function () { const basisFormat = ktx2File.isUASTC() ? BasisFormat.UASTC_4x4 : BasisFormat.ETC1S; const width = ktx2File.getWidth(); const height = ktx2File.getHeight(); + const layers = ktx2File.getLayers() || 1; const levels = ktx2File.getLevels(); const hasAlpha = ktx2File.getHasAlpha(); const dfdTransferFn = ktx2File.getDFDTransferFunc(); @@ -459,30 +468,39 @@ KTX2Loader.BasisWorker = function () { for ( let mip = 0; mip < levels; mip ++ ) { - const levelInfo = ktx2File.getImageLevelInfo( mip, 0, 0 ); - const mipWidth = levelInfo.origWidth; - const mipHeight = levelInfo.origHeight; - const dst = new Uint8Array( ktx2File.getImageTranscodedSizeInBytes( mip, 0, 0, transcoderFormat ) ); - - const status = ktx2File.transcodeImage( - dst, - mip, - 0, - 0, - transcoderFormat, - 0, - - 1, - - 1, - ); + const layerMips = []; + + let mipWidth, mipHeight; + + for ( let layer = 0; layer < layers; layer ++ ) { + + const levelInfo = ktx2File.getImageLevelInfo( mip, layer, 0 ); + mipWidth = levelInfo.origWidth; + mipHeight = levelInfo.origHeight; + const dst = new Uint8Array( ktx2File.getImageTranscodedSizeInBytes( mip, layer, 0, transcoderFormat ) ); + const status = ktx2File.transcodeImage( + dst, + mip, + layer, + 0, + transcoderFormat, + 0, + - 1, + - 1, + ); + + if ( ! status ) { + + cleanup(); + throw new Error( 'THREE.KTX2Loader: .transcodeImage failed.' ); - if ( ! status ) { + } - cleanup(); - throw new Error( 'THREE.KTX2Loader: .transcodeImage failed.' ); + layerMips.push( dst ); } - mipmaps.push( { data: dst, width: mipWidth, height: mipHeight } ); + mipmaps.push( { data: concat( layerMips ), width: mipWidth, height: mipHeight } ); } @@ -609,6 +627,33 @@ KTX2Loader.BasisWorker = function () { } + /** Concatenates N byte arrays. */ + function concat( arrays ) { + + let totalByteLength = 0; + + for ( const array of arrays ) { + + totalByteLength += array.byteLength; + + } + + const result = new Uint8Array( totalByteLength ); + + let byteOffset = 0; + + for ( const array of arrays ) { + + result.set( array, byteOffset ); + + byteOffset += array.byteLength; + + } + + return result; + + } + }; // @@ -660,7 +705,7 @@ const ENCODING_MAP = { }; -function createDataTexture( container ) { +async function createDataTexture( container ) { const { vkFormat, pixelWidth, pixelHeight, pixelDepth } = container; @@ -670,11 +715,36 @@ function createDataTexture( container ) { } - // + const level = container.levels[ 0 ]; + let levelData; let view; - const levelData = container.levels[ 0 ].levelData; + if ( container.supercompressionScheme === KHR_SUPERCOMPRESSION_NONE ) { + + levelData = level.levelData; + + } else if ( container.supercompressionScheme === KHR_SUPERCOMPRESSION_ZSTD ) { + + if ( ! _zstd ) { + + _zstd = new Promise( async ( resolve ) => { + + const zstd = new ZSTDDecoder(); + await zstd.init(); + resolve( zstd ); + + } ); + + } + + levelData = ( await _zstd ).decode( level.levelData, level.uncompressedByteLength ); + + } else { + + throw new Error( 'THREE.KTX2Loader: Unsupported supercompressionScheme.' ); + + } if ( TYPE_MAP[ vkFormat ] === FloatType ) { @@ -701,7 +771,6 @@ function createDataTexture( container ) { view = levelData; } - // const texture = pixelDepth === 0 diff --git a/examples/jsm/loaders/LDrawLoader.js b/examples/jsm/loaders/LDrawLoader.js index 00c7efcd270f26..9ab6bf0ce72a30 100644 --- a/examples/jsm/loaders/LDrawLoader.js +++ b/examples/jsm/loaders/LDrawLoader.js @@ -692,7 +692,7 @@ class LDrawParsedCache { result.subobjects = original.subobjects; result.fileName = original.fileName; result.totalFaces = original.totalFaces; - result.startingConstructionStep = original.startingConstructionStep; + result.startingBuildingStep = original.startingBuildingStep; result.materials = original.materials; result.group = null; return result; @@ -819,7 +819,7 @@ class LDrawParsedCache { let bfcInverted = false; let bfcCull = true; - let startingConstructionStep = false; + let startingBuildingStep = false; // Parse all line commands for ( let lineIndex = 0; lineIndex < numLines; lineIndex ++ ) { @@ -994,7 +994,7 @@ class LDrawParsedCache { case 'STEP': - startingConstructionStep = true; + startingBuildingStep = true; break; @@ -1068,9 +1068,10 @@ class LDrawParsedCache { matrix: matrix, fileName: fileName, inverted: bfcInverted, - startingConstructionStep: startingConstructionStep + startingBuildingStep: startingBuildingStep } ); + startingBuildingStep = false; bfcInverted = false; break; @@ -1233,7 +1234,7 @@ class LDrawParsedCache { author, subobjects, totalFaces, - startingConstructionStep, + startingBuildingStep, materials, fileName, group: null @@ -1389,7 +1390,7 @@ class LDrawPartsGeometryCache { const subobjectGroup = subobjectInfo; subobject.matrix.decompose( subobjectGroup.position, subobjectGroup.quaternion, subobjectGroup.scale ); - subobjectGroup.userData.startingConstructionStep = subobject.startingConstructionStep; + subobjectGroup.userData.startingBuildingStep = subobject.startingBuildingStep; subobjectGroup.name = subobject.fileName; loader.applyMaterialsToMesh( subobjectGroup, subobject.colorCode, info.materials ); @@ -1958,7 +1959,7 @@ class LDrawLoader extends Loader { .then( group => { this.applyMaterialsToMesh( group, MAIN_COLOUR_CODE, this.materialLibrary, true ); - this.computeConstructionSteps( group ); + this.computeBuildingSteps( group ); group.userData.fileName = url; onLoad( group ); @@ -1976,7 +1977,7 @@ class LDrawLoader extends Loader { .then( group => { this.applyMaterialsToMesh( group, MAIN_COLOUR_CODE, this.materialLibrary, true ); - this.computeConstructionSteps( group ); + this.computeBuildingSteps( group ); group.userData.fileName = ''; onLoad( group ); @@ -2413,8 +2414,7 @@ class LDrawLoader extends Loader { lum = parseInt( token.substring( 9 ) ); - } - else { + } else { lum = parseInt( token ); @@ -2434,9 +2434,9 @@ class LDrawLoader extends Loader { } - computeConstructionSteps( model ) { + computeBuildingSteps( model ) { - // Sets userdata.constructionStep number in Group objects and userData.numConstructionSteps number in the root Group object. + // Sets userdata.buildingStep number in Group objects and userData.numBuildingSteps number in the root Group object. let stepNumber = 0; @@ -2444,19 +2444,19 @@ class LDrawLoader extends Loader { if ( c.isGroup ) { - if ( c.userData.startingConstructionStep ) { + if ( c.userData.startingBuildingStep ) { stepNumber ++; } - c.userData.constructionStep = stepNumber; + c.userData.buildingStep = stepNumber; } } ); - model.userData.numConstructionSteps = stepNumber + 1; + model.userData.numBuildingSteps = stepNumber + 1; } diff --git a/examples/jsm/loaders/LottieLoader.js b/examples/jsm/loaders/LottieLoader.js index d323bf47657fd2..87edfedbb54aef 100644 --- a/examples/jsm/loaders/LottieLoader.js +++ b/examples/jsm/loaders/LottieLoader.js @@ -5,6 +5,8 @@ import { NearestFilter } from 'three'; +import lottie from '../libs/lottie_canvas.module.js'; + class LottieLoader extends Loader { setQuality( value ) { @@ -28,7 +30,7 @@ class LottieLoader extends Loader { const data = JSON.parse( text ); - // bodymoving uses container.offetWidth and offsetHeight + // lottie uses container.offetWidth and offsetHeight // to define width/height const container = document.createElement( 'div' ); @@ -36,7 +38,7 @@ class LottieLoader extends Loader { container.style.height = data.h + 'px'; document.body.appendChild( container ); - const animation = bodymovin.loadAnimation( { + const animation = lottie.loadAnimation( { container: container, animType: 'canvas', loop: true, diff --git a/examples/jsm/loaders/MaterialXLoader.js b/examples/jsm/loaders/MaterialXLoader.js new file mode 100644 index 00000000000000..5111d5335c953a --- /dev/null +++ b/examples/jsm/loaders/MaterialXLoader.js @@ -0,0 +1,728 @@ +import { + FileLoader, + Loader, + TextureLoader, + RepeatWrapping +} from 'three'; + +import { + MeshPhysicalNodeMaterial, + float, bool, int, vec2, vec3, vec4, color, texture, + positionLocal, + add, sub, mul, div, mod, abs, sign, floor, ceil, round, pow, sin, cos, tan, + asin, acos, atan2, sqrt, exp, clamp, min, max, normalize, length, dot, cross, normalMap, + remap, smoothstep, luminance, mx_rgbtohsv, mx_hsvtorgb, + mix, + mx_ramplr, mx_ramptb, mx_splitlr, mx_splittb, + mx_fractal_noise_float, mx_noise_float, mx_cell_noise_float, mx_worley_noise_float, + mx_transform_uv, + mx_safepower, mx_contrast, + mx_srgb_texture_to_lin_rec709, + saturation +} from 'three/nodes'; + +const colorSpaceLib = { + mx_srgb_texture_to_lin_rec709 +}; + +class MtlXElement { + + constructor( name, nodeFunc, params = null ) { + + this.name = name; + this.nodeFunc = nodeFunc; + this.params = params; + + } + +} + +// Ref: https://github.com/mrdoob/three.js/issues/24674 + +const MtlXElements = [ + + // << Math >> + new MtlXElement( 'add', add, [ 'in1', 'in2' ] ), + new MtlXElement( 'subtract', sub, [ 'in1', 'in2' ] ), + new MtlXElement( 'multiply', mul, [ 'in1', 'in2' ] ), + new MtlXElement( 'divide', div, [ 'in1', 'in2' ] ), + new MtlXElement( 'modulo', mod, [ 'in1', 'in2' ] ), + new MtlXElement( 'absval', abs, [ 'in1', 'in2' ] ), + new MtlXElement( 'sign', sign, [ 'in1', 'in2' ] ), + new MtlXElement( 'floor', floor, [ 'in1', 'in2' ] ), + new MtlXElement( 'ceil', ceil, [ 'in1', 'in2' ] ), + new MtlXElement( 'round', round, [ 'in1', 'in2' ] ), + new MtlXElement( 'power', pow, [ 'in1', 'in2' ] ), + new MtlXElement( 'sin', sin, [ 'in' ] ), + new MtlXElement( 'cos', cos, [ 'in' ] ), + new MtlXElement( 'tan', tan, [ 'in' ] ), + new MtlXElement( 'asin', asin, [ 'in' ] ), + new MtlXElement( 'acos', acos, [ 'in' ] ), + new MtlXElement( 'atan2', atan2, [ 'in1', 'in2' ] ), + new MtlXElement( 'sqrt', sqrt, [ 'in' ] ), + //new MtlXElement( 'ln', ... ), + new MtlXElement( 'exp', exp, [ 'in' ] ), + new MtlXElement( 'clamp', clamp, [ 'in', 'low', 'high' ] ), + new MtlXElement( 'min', min, [ 'in1', 'in2' ] ), + new MtlXElement( 'max', max, [ 'in1', 'in2' ] ), + new MtlXElement( 'normalize', normalize, [ 'in' ] ), + new MtlXElement( 'magnitude', length, [ 'in1', 'in2' ] ), + new MtlXElement( 'dotproduct', dot, [ 'in1', 'in2' ] ), + new MtlXElement( 'crossproduct', cross, [ 'in' ] ), + //new MtlXElement( 'transformpoint', ... ), + //new MtlXElement( 'transformvector', ... ), + //new MtlXElement( 'transformnormal', ... ), + //new MtlXElement( 'transformmatrix', ... ), + new MtlXElement( 'normalmap', normalMap, [ 'in', 'scale' ] ), + //new MtlXElement( 'transpose', ... ), + //new MtlXElement( 'determinant', ... ), + //new MtlXElement( 'invertmatrix', ... ), + //new MtlXElement( 'rotate2d', rotateUV, [ 'in', radians( 'amount' )** ] ), + //new MtlXElement( 'rotate3d', ... ), + //new MtlXElement( 'arrayappend', ... ), + //new MtlXElement( 'dot', ... ), + + // << Adjustment >> + new MtlXElement( 'remap', remap, [ 'in', 'inlow', 'inhigh', 'outlow', 'outhigh' ] ), + new MtlXElement( 'smoothstep', smoothstep, [ 'in', 'low', 'high' ] ), + //new MtlXElement( 'curveadjust', ... ), + //new MtlXElement( 'curvelookup', ... ), + new MtlXElement( 'luminance', luminance, [ 'in', 'lumacoeffs' ] ), + new MtlXElement( 'rgbtohsv', mx_rgbtohsv, [ 'in' ] ), + new MtlXElement( 'hsvtorgb', mx_hsvtorgb, [ 'in' ] ), + + // << Mix >> + new MtlXElement( 'mix', mix, [ 'bg', 'fg', 'mix' ] ), + + // << Channel >> + new MtlXElement( 'combine2', vec2, [ 'in1', 'in2' ] ), + new MtlXElement( 'combine3', vec3, [ 'in1', 'in2', 'in3' ] ), + new MtlXElement( 'combine4', vec4, [ 'in1', 'in2', 'in3', 'in4' ] ), + + // << Procedural >> + new MtlXElement( 'ramplr', mx_ramplr, [ 'valuel', 'valuer', 'texcoord' ] ), + new MtlXElement( 'ramptb', mx_ramptb, [ 'valuet', 'valueb', 'texcoord' ] ), + new MtlXElement( 'splitlr', mx_splitlr, [ 'valuel', 'valuer', 'texcoord' ] ), + new MtlXElement( 'splittb', mx_splittb, [ 'valuet', 'valueb', 'texcoord' ] ), + new MtlXElement( 'noise2d', mx_noise_float, [ 'texcoord', 'amplitude', 'pivot' ] ), + new MtlXElement( 'noise3d', mx_noise_float, [ 'texcoord', 'amplitude', 'pivot' ] ), + new MtlXElement( 'fractal3d', mx_fractal_noise_float, [ 'position', 'octaves', 'lacunarity', 'diminish', 'amplitude' ] ), + new MtlXElement( 'cellnoise2d', mx_cell_noise_float, [ 'texcoord' ] ), + new MtlXElement( 'cellnoise3d', mx_cell_noise_float, [ 'texcoord' ] ), + new MtlXElement( 'worleynoise2d', mx_worley_noise_float, [ 'texcoord', 'jitter' ] ), + new MtlXElement( 'worleynoise3d', mx_worley_noise_float, [ 'texcoord', 'jitter' ] ), + + // << Supplemental >> + //new MtlXElement( 'tiledimage', ... ), + //new MtlXElement( 'triplanarprojection', triplanarTextures, [ 'filex', 'filey', 'filez' ] ), + //new MtlXElement( 'ramp4', ... ), + //new MtlXElement( 'place2d', mx_place2d, [ 'texcoord', 'pivot', 'scale', 'rotate', 'offset' ] ), + new MtlXElement( 'safepower', mx_safepower, [ 'in1', 'in2' ] ), + new MtlXElement( 'contrast', mx_contrast, [ 'in', 'amount', 'pivot' ] ), + //new MtlXElement( 'hsvadjust', ... ), + new MtlXElement( 'saturate', saturation, [ 'in', 'amount' ] ), + //new MtlXElement( 'extract', ... ), + //new MtlXElement( 'separate2', ... ), + //new MtlXElement( 'separate3', ... ), + //new MtlXElement( 'separate4', ... ) + +]; + +const MtlXLibrary = {}; +MtlXElements.forEach( element => MtlXLibrary[ element.name ] = element ); + +class MaterialXLoader extends Loader { + + constructor( manager ) { + + super( manager ); + + } + + load( url, onLoad, onProgress, onError ) { + + new FileLoader( this.manager ) + .setPath( this.path ) + .load( url, async ( text ) => { + + try { + + onLoad( this.parse( text ) ); + + } catch ( e ) { + + onError( e ); + + } + + }, onProgress, onError ); + + return this; + + } + + parse( text ) { + + return new MaterialX( this.manager, this.path ).parse( text ); + + } + +} + +class MaterialXNode { + + constructor( materialX, nodeXML, nodePath = '' ) { + + this.materialX = materialX; + this.nodeXML = nodeXML; + this.nodePath = nodePath ? nodePath + '/' + this.name : this.name; + + this.parent = null; + + this.node = null; + + this.children = []; + + } + + get element() { + + return this.nodeXML.nodeName; + + } + + get nodeGraph() { + + return this.getAttribute( 'nodegraph' ); + + } + + get nodeName() { + + return this.getAttribute( 'nodename' ); + + } + + get interfaceName() { + + return this.getAttribute( 'interfacename' ); + + } + + get output() { + + return this.getAttribute( 'output' ); + + } + + get name() { + + return this.getAttribute( 'name' ); + + } + + get type() { + + return this.getAttribute( 'type' ); + + } + + get value() { + + return this.getAttribute( 'value' ); + + } + + getNodeGraph() { + + let nodeX = this; + + while ( nodeX !== null ) { + + if ( nodeX.element === 'nodegraph' ) { + + break; + + } + + nodeX = nodeX.parent; + + } + + return nodeX; + + } + + getRoot() { + + let nodeX = this; + + while ( nodeX.parent !== null ) { + + nodeX = nodeX.parent; + + } + + return nodeX; + + } + + get referencePath() { + + let referencePath = null; + + if ( this.nodeGraph !== null && this.output !== null ) { + + referencePath = this.nodeGraph + '/' + this.output; + + } else if ( this.nodeName !== null || this.interfaceName !== null ) { + + referencePath = this.getNodeGraph().nodePath + '/' + ( this.nodeName || this.interfaceName ); + + } + + return referencePath; + + } + + get hasReference() { + + return this.referencePath !== null; + + } + + get isConst() { + + return this.element === 'input' && this.value !== null && this.type !== 'filename'; + + } + + getColorSpaceNode() { + + const csSource = this.getAttribute( 'colorspace' ); + const csTarget = this.getRoot().getAttribute( 'colorspace' ); + + const nodeName = `mx_${ csSource }_to_${ csTarget }`; + + return colorSpaceLib[ nodeName ]; + + } + + getTexture() { + + const filePrefix = this.getRecursiveAttribute( 'fileprefix' ) || ''; + + const texture = this.materialX.textureLoader.load( filePrefix + this.value ); + texture.wrapS = texture.wrapT = RepeatWrapping; + texture.flipY = false; + + return texture; + + } + + getClassFromType( type ) { + + let nodeClass = null; + + if ( type === 'integer' ) nodeClass = int; + else if ( type === 'float' ) nodeClass = float; + else if ( type === 'vector2' ) nodeClass = vec2; + else if ( type === 'vector3' ) nodeClass = vec3; + else if ( type === 'vector4' || type === 'color4' ) nodeClass = vec4; + else if ( type === 'color3' ) nodeClass = color; + else if ( type === 'boolean' ) nodeClass = bool; + + return nodeClass; + + } + + getNode() { + + let node = this.node; + + if ( node !== null ) { return node; } + + // + + const type = this.type; + + if ( this.isConst ) { + + const nodeClass = this.getClassFromType( type ); + + node = nodeClass( ...this.getVector() ); + + } else if ( this.hasReference ) { + + node = this.materialX.getMaterialXNode( this.referencePath ).getNode(); + + } else { + + const element = this.element; + + if ( element === 'convert' ) { + + const nodeClass = this.getClassFromType( type ); + + node = nodeClass( this.getNodeByName( 'in' ) ); + + } else if ( element === 'constant' ) { + + node = this.getNodeByName( 'value' ); + + } else if ( element === 'position' ) { + + node = positionLocal; + + } else if ( element === 'tiledimage' ) { + + const file = this.getChildByName( 'file' ); + + const textureFile = file.getTexture(); + const uvTiling = mx_transform_uv( ...this.getNodesByNames( [ 'uvtiling', 'uvoffset' ] ) ); + + node = texture( textureFile, uvTiling ); + + const colorSpaceNode = file.getColorSpaceNode(); + + if ( colorSpaceNode ) { + + node = colorSpaceNode( node ); + + } + + } else if ( element === 'image' ) { + + const file = this.getChildByName( 'file' ); + const uvNode = this.getNodeByName( 'texcoord' ); + + const textureFile = file.getTexture(); + + node = texture( textureFile, uvNode ); + + const colorSpaceNode = file.getColorSpaceNode(); + + if ( colorSpaceNode ) { + + node = colorSpaceNode( node ); + + } + + } else if ( MtlXLibrary[ element ] !== undefined ) { + + const nodeElement = MtlXLibrary[ element ]; + + node = nodeElement.nodeFunc( ...this.getNodesByNames( ...nodeElement.params ) ); + + } + + } + + // + + if ( node === null ) { + + console.warn( `THREE.MaterialXLoader: Unexpected node ${ new XMLSerializer().serializeToString( this.nodeXML ) }.` ); + + node = float( 0 ); + + } + + // + + const nodeToTypeClass = this.getClassFromType( type ); + + if ( nodeToTypeClass !== null ) { + + node = nodeToTypeClass( node ); + + } + + node.name = this.name; + + this.node = node; + + return node; + + } + + getChildByName( name ) { + + for ( const input of this.children ) { + + if ( input.name === name ) { + + return input; + + } + + } + + } + + getNodes() { + + const nodes = {}; + + for ( const input of this.children ) { + + const node = input.getNode(); + + nodes[ node.name ] = node; + + } + + return nodes; + + } + + getNodeByName( name ) { + + return this.getChildByName( name )?.getNode(); + + } + + getNodesByNames( ...names ) { + + const nodes = []; + + for ( const name of names ) { + + const node = this.getNodeByName( name ); + + if ( node ) nodes.push( node ); + + } + + return nodes; + + } + + getValue() { + + return this.value.trim(); + + } + + getVector() { + + const vector = []; + + for ( const val of this.getValue().split( /[,|\s]/ ) ) { + + if ( val !== '' ) { + + vector.push( Number( val.trim() ) ); + + } + + } + + return vector; + + } + + getAttribute( name ) { + + return this.nodeXML.getAttribute( name ); + + } + + getRecursiveAttribute( name ) { + + let attribute = this.nodeXML.getAttribute( name ); + + if ( attribute === null && this.parent !== null ) { + + attribute = this.parent.getRecursiveAttribute( name ); + + } + + return attribute; + + } + + setStandardSurfaceToGltfPBR( material ) { + + const inputs = this.getNodes(); + + // + + let colorNode = null; + + if ( inputs.base && inputs.base_color ) colorNode = mul( inputs.base, inputs.base_color ); + else if ( inputs.base ) colorNode = inputs.base; + else if ( inputs.base_color ) colorNode = inputs.base_color; + + // + + let roughnessNode = null; + + if ( inputs.specular_roughness ) roughnessNode = inputs.specular_roughness; + + // + + let metalnessNode = null; + + if ( inputs.metalness ) metalnessNode = inputs.metalness; + + // + + let clearcoatNode = null; + let clearcoatRoughnessNode = null; + + if ( inputs.coat ) clearcoatNode = inputs.coat; + if ( inputs.coat_roughness ) clearcoatRoughnessNode = inputs.coat_roughness; + + if ( inputs.coat_color ) { + + colorNode = colorNode ? mul( colorNode, inputs.coat_color ) : colorNode; + + } + + // + + material.colorNode = colorNode || color( 0.8, 0.8, 0.8 ); + material.roughnessNode = roughnessNode || float( 0.2 ); + material.metalnessNode = metalnessNode || float( 0 ); + material.clearcoatNode = clearcoatNode || float( 0 ); + material.clearcoatRoughnessNode = clearcoatRoughnessNode || float( 0 ); + + } + + /*setGltfPBR( material ) { + + const inputs = this.getNodes(); + + console.log( inputs ); + + }*/ + + setMaterial( material ) { + + const element = this.element; + + if ( element === 'gltf_pbr' ) { + + //this.setGltfPBR( material ); + + } else if ( element === 'standard_surface' ) { + + this.setStandardSurfaceToGltfPBR( material ); + + } + + } + + toMaterial() { + + const material = new MeshPhysicalNodeMaterial(); + material.name = this.name; + + for ( const nodeX of this.children ) { + + const shaderProperties = this.materialX.getMaterialXNode( nodeX.nodeName ); + shaderProperties.setMaterial( material ); + + } + + return material; + + } + + toMaterials() { + + const materials = {}; + + for ( const nodeX of this.children ) { + + if ( nodeX.element === 'surfacematerial' ) { + + const material = nodeX.toMaterial(); + + materials[ material.name ] = material; + + } + + } + + return materials; + + } + + add( materialXNode ) { + + materialXNode.parent = this; + + this.children.push( materialXNode ); + + } + +} + +class MaterialX { + + constructor( manager, path ) { + + this.manager = manager; + this.path = path; + this.resourcePath = ''; + + this.nodesXLib = new Map(); + //this.nodesXRefLib = new WeakMap(); + + this.textureLoader = new TextureLoader( manager ); + + } + + addMaterialXNode( materialXNode ) { + + this.nodesXLib.set( materialXNode.nodePath, materialXNode ); + + } + + /*getMaterialXNodeFromXML( xmlNode ) { + + return this.nodesXRefLib.get( xmlNode ); + + }*/ + + getMaterialXNode( ...names ) { + + return this.nodesXLib.get( names.join( '/' ) ); + + } + + parseNode( nodeXML, nodePath = '' ) { + + const materialXNode = new MaterialXNode( this, nodeXML, nodePath ); + if ( materialXNode.nodePath ) this.addMaterialXNode( materialXNode ); + + for ( const childNodeXML of nodeXML.children ) { + + const childMXNode = this.parseNode( childNodeXML, materialXNode.nodePath ); + materialXNode.add( childMXNode ); + + } + + return materialXNode; + + } + + parse( text ) { + + const rootXML = new DOMParser().parseFromString( text, 'application/xml' ).documentElement; + + this.textureLoader.setPath( this.path ); + + // + + const materials = this.parseNode( rootXML ).toMaterials(); + + return { materials }; + + } + +} + +export { MaterialXLoader }; diff --git a/examples/jsm/loaders/PCDLoader.js b/examples/jsm/loaders/PCDLoader.js index 582e82d387a9b4..4f71a623c3357a 100644 --- a/examples/jsm/loaders/PCDLoader.js +++ b/examples/jsm/loaders/PCDLoader.js @@ -123,7 +123,7 @@ class PCDLoader extends Loader { // remove comments - PCDheader.str = PCDheader.str.replace( /\#.*/gi, '' ); + PCDheader.str = PCDheader.str.replace( /#.*/gi, '' ); // parse diff --git a/examples/jsm/loaders/PLYLoader.js b/examples/jsm/loaders/PLYLoader.js index 3c35e7cc1df2f7..99cf39065eb41d 100644 --- a/examples/jsm/loaders/PLYLoader.js +++ b/examples/jsm/loaders/PLYLoader.js @@ -31,6 +31,16 @@ import { * diffuse_blue: 'blue' * } ); * + * Custom properties outside of the defaults for position, uv, normal + * and color attributes can be added using the setCustomPropertyMapping method. + * For example, the following maps the element properties “custom_property_a” + * and “custom_property_b” to an attribute “customAttribute” with an item size of 2. + * Attribute item sizes are set from the number of element properties in the property array. + * + * loader.setCustomPropertyMapping( { + * customAttribute: ['custom_property_a', 'custom_property_b'], + * } ); + * */ const _color = new Color(); @@ -42,6 +52,7 @@ class PLYLoader extends Loader { super( manager ); this.propertyNameMapping = {}; + this.customPropertyMapping = {}; } @@ -86,6 +97,12 @@ class PLYLoader extends Loader { } + setCustomPropertyNameMapping( mapping ) { + + this.customPropertyMapping = mapping; + + } + parse( data ) { function parseHeader( data ) { @@ -260,18 +277,32 @@ class PLYLoader extends Loader { } + function createBuffer() { + + const buffer = { + indices: [], + vertices: [], + normals: [], + uvs: [], + faceVertexUvs: [], + colors: [], + }; + + for ( const customProperty of Object.keys( scope.customPropertyMapping ) ) { + + buffer[ customProperty ] = []; + + } + + return buffer; + + } + function parseASCII( data, header ) { // PLY ascii format specification, as per http://en.wikipedia.org/wiki/PLY_(file_format) - const buffer = { - indices: [], - vertices: [], - normals: [], - uvs: [], - faceVertexUvs: [], - colors: [] - }; + const buffer = createBuffer(); let result; @@ -357,6 +388,24 @@ class PLYLoader extends Loader { } + // custom buffer data + + for ( const customProperty of Object.keys( scope.customPropertyMapping ) ) { + + if ( buffer[ customProperty ].length > 0 ) { + + geometry.setAttribute( + customProperty, + new Float32BufferAttribute( + buffer[ customProperty ], + scope.customPropertyMapping[ customProperty ].length + ) + ); + + } + + } + geometry.computeBoundingSphere(); return geometry; @@ -419,6 +468,16 @@ class PLYLoader extends Loader { } + for ( const customProperty of Object.keys( scope.customPropertyMapping ) ) { + + for ( const elementProperty of scope.customPropertyMapping[ customProperty ] ) { + + buffer[ customProperty ].push( element[ elementProperty ] ); + + } + + } + } else if ( elementName === 'face' ) { const vertex_indices = element.vertex_indices || element.vertex_index; // issue #9338 @@ -506,14 +565,7 @@ class PLYLoader extends Loader { function parseBinary( data, header ) { - const buffer = { - indices: [], - vertices: [], - normals: [], - uvs: [], - faceVertexUvs: [], - colors: [] - }; + const buffer = createBuffer(); const little_endian = ( header.format === 'binary_little_endian' ); const body = new DataView( data, header.headerLength ); diff --git a/examples/jsm/loaders/SVGLoader.js b/examples/jsm/loaders/SVGLoader.js index fd2aa516b72424..ec9f81fb6652a8 100644 --- a/examples/jsm/loaders/SVGLoader.js +++ b/examples/jsm/loaders/SVGLoader.js @@ -1459,7 +1459,7 @@ class SVGLoader extends Loader { if ( array.length >= 1 ) { const tx = array[ 0 ]; - let ty = tx; + let ty = 0; if ( array.length >= 2 ) { @@ -1482,7 +1482,7 @@ class SVGLoader extends Loader { let cy = 0; // Angle - angle = - array[ 0 ] * Math.PI / 180; + angle = array[ 0 ] * Math.PI / 180; if ( array.length >= 3 ) { @@ -1493,10 +1493,10 @@ class SVGLoader extends Loader { } // Rotate around center (cx, cy) - tempTransform1.identity().translate( - cx, - cy ); - tempTransform2.identity().rotate( angle ); + tempTransform1.makeTranslation( - cx, - cy ); + tempTransform2.makeRotation( angle ); tempTransform3.multiplyMatrices( tempTransform2, tempTransform1 ); - tempTransform1.identity().translate( cx, cy ); + tempTransform1.makeTranslation( cx, cy ); currentTransform.multiplyMatrices( tempTransform1, tempTransform3 ); } @@ -1588,7 +1588,120 @@ class SVGLoader extends Loader { } - const isRotated = isTransformRotated( m ); + function transfEllipseGeneric( curve ) { + + // For math description see: + // https://math.stackexchange.com/questions/4544164 + + const a = curve.xRadius; + const b = curve.yRadius; + + const cosTheta = Math.cos( curve.aRotation ); + const sinTheta = Math.sin( curve.aRotation ); + + const v1 = new Vector3( a * cosTheta, a * sinTheta, 0 ); + const v2 = new Vector3( -b * sinTheta, b * cosTheta, 0 ); + + const f1 = v1.applyMatrix3( m ); + const f2 = v2.applyMatrix3( m ); + + const mF = tempTransform0.set( + f1.x, f2.x, 0, + f1.y, f2.y, 0, + 0, 0, 1, + ); + + const mFInv = tempTransform1.copy( mF ).invert(); + const mFInvT = tempTransform2.copy( mFInv ).transpose(); + const mQ = mFInvT.multiply( mFInv ); + const mQe = mQ.elements; + + const ed = eigenDecomposition( mQe[0], mQe[1], mQe[4] ); + const rt1sqrt = Math.sqrt( ed.rt1 ); + const rt2sqrt = Math.sqrt( ed.rt2 ); + + curve.xRadius = 1 / rt1sqrt; + curve.yRadius = 1 / rt2sqrt; + curve.aRotation = Math.atan2( ed.sn, ed.cs ); + + const isFullEllipse = + ( curve.aEndAngle - curve.aStartAngle ) % ( 2 * Math.PI ) < Number.EPSILON; + + // Do not touch angles of a full ellipse because after transformation they + // would converge to a sinle value effectively removing the whole curve + + if ( !isFullEllipse ) { + + const mDsqrt = tempTransform1.set( + rt1sqrt, 0, 0, + 0, rt2sqrt, 0, + 0, 0, 1, + ); + + const mRT = tempTransform2.set( + ed.cs, ed.sn, 0, + -ed.sn, ed.cs, 0, + 0, 0, 1, + ); + + const mDRF = mDsqrt.multiply( mRT ).multiply( mF ); + + const transformAngle = phi => { + + const { x: cosR, y: sinR } = + new Vector3( Math.cos( phi ), Math.sin( phi ), 0 ).applyMatrix3( mDRF ); + + return Math.atan2( sinR, cosR ); + + } + + curve.aStartAngle = transformAngle( curve.aStartAngle ); + curve.aEndAngle = transformAngle( curve.aEndAngle ); + + if ( isTransformFlipped( m ) ) { + + curve.aClockwise = !curve.aClockwise; + + } + + } + + } + + function transfEllipseNoSkew( curve ) { + + // Faster shortcut if no skew is applied + // (e.g, a euclidean transform of a group containing the ellipse) + + const sx = getTransformScaleX( m ); + const sy = getTransformScaleY( m ); + + curve.xRadius *= sx; + curve.yRadius *= sy; + + // Extract rotation angle from the matrix of form: + // + // | cosθ sx -sinθ sy | + // | sinθ sx cosθ sy | + // + // Remembering that tanθ = sinθ / cosθ; and that + // `sx`, `sy`, or both might be zero. + const theta = + sx > Number.EPSILON + ? Math.atan2( m.elements[ 1 ], m.elements[ 0 ] ) + : Math.atan2( - m.elements[ 3 ], m.elements[ 4 ] ); + + curve.aRotation += theta; + + if ( isTransformFlipped( m ) ) { + + curve.aStartAngle *= -1; + curve.aEndAngle *= -1; + curve.aClockwise = !curve.aClockwise; + + } + + } const subPaths = path.subPaths; @@ -1621,19 +1734,24 @@ class SVGLoader extends Loader { } else if ( curve.isEllipseCurve ) { - if ( isRotated ) { - - console.warn( 'SVGLoader: Elliptic arc or ellipse rotation or skewing is not implemented.' ); - - } + // Transform ellipse center point tempV2.set( curve.aX, curve.aY ); transfVec2( tempV2 ); curve.aX = tempV2.x; curve.aY = tempV2.y; - curve.xRadius *= getTransformScaleX( m ); - curve.yRadius *= getTransformScaleY( m ); + // Transform ellipse shape parameters + + if ( isTransformSkewed( m ) ) { + + transfEllipseGeneric( curve ); + + } else { + + transfEllipseNoSkew( curve ); + + } } @@ -1643,9 +1761,25 @@ class SVGLoader extends Loader { } - function isTransformRotated( m ) { + function isTransformFlipped( m ) { + + const te = m.elements; + return te[ 0 ] * te[ 4 ] - te[ 1 ] * te[ 3 ] < 0; + + } + + function isTransformSkewed( m ) { + + const te = m.elements; + const basisDot = te[ 0 ] * te[ 3 ] + te[ 1 ] * te[ 4 ]; + + // Shortcut for trivial rotations and transformations + if ( basisDot === 0 ) return false; + + const sx = getTransformScaleX( m ); + const sy = getTransformScaleY( m ); - return m.elements[ 1 ] !== 0 || m.elements[ 3 ] !== 0; + return Math.abs( basisDot / ( sx * sy ) ) > Number.EPSILON; } @@ -1663,6 +1797,85 @@ class SVGLoader extends Loader { } + // Calculates the eigensystem of a real symmetric 2x2 matrix + // [ A B ] + // [ B C ] + // in the form + // [ A B ] = [ cs -sn ] [ rt1 0 ] [ cs sn ] + // [ B C ] [ sn cs ] [ 0 rt2 ] [ -sn cs ] + // where rt1 >= rt2. + // + // Adapted from: https://www.mpi-hd.mpg.de/personalhomes/globes/3x3/index.html + // -> Algorithms for real symmetric matrices -> Analytical (2x2 symmetric) + function eigenDecomposition( A, B, C ) { + + let rt1, rt2, cs, sn, t; + const sm = A + C; + const df = A - C; + const rt = Math.sqrt( df * df + 4 * B * B ); + + if ( sm > 0 ) { + + rt1 = 0.5 * ( sm + rt ); + t = 1 / rt1; + rt2 = A * t * C - B * t * B; + + } else if ( sm < 0 ) { + + rt2 = 0.5 * ( sm - rt ); + + } else { + + // This case needs to be treated separately to avoid div by 0 + + rt1 = 0.5 * rt; + rt2 = -0.5 * rt; + + } + + // Calculate eigenvectors + + if ( df > 0 ) { + + cs = df + rt; + + } else { + + cs = df - rt; + + } + + if ( Math.abs( cs ) > 2 * Math.abs( B ) ) { + + t = -2 * B / cs; + sn = 1 / Math.sqrt( 1 + t * t ); + cs = t * sn; + + } else if ( Math.abs( B ) === 0 ) { + + cs = 1; + sn = 0; + + } else { + + t = -0.5 * cs / B; + cs = 1 / Math.sqrt( 1 + t * t ); + sn = t * cs; + + } + + if ( df > 0 ) { + + t = cs; + cs = -sn; + sn = t; + + } + + return { rt1, rt2, cs, sn }; + + } + // const paths = []; diff --git a/examples/jsm/loaders/TIFFLoader.js b/examples/jsm/loaders/TIFFLoader.js new file mode 100644 index 00000000000000..950361f7400da2 --- /dev/null +++ b/examples/jsm/loaders/TIFFLoader.js @@ -0,0 +1,36 @@ +import { + DataTextureLoader, + LinearFilter, + LinearMipmapLinearFilter +} from 'three'; + +import UTIF from '../libs/utif.module.js'; + +class TIFFLoader extends DataTextureLoader { + + constructor( manager ) { + + super( manager ); + + } + + parse( buffer ) { + + const ifds = UTIF.decode( buffer ); + UTIF.decodeImage( buffer, ifds[ 0 ] ); + const rgba = UTIF.toRGBA8( ifds[ 0 ] ); + + return { + width: ifds[ 0 ].width, + height: ifds[ 0 ].height, + data: rgba, + flipY: true, + magFilter: LinearFilter, + minFilter: LinearMipmapLinearFilter + }; + + } + +} + +export { TIFFLoader }; diff --git a/examples/jsm/loaders/USDZLoader.js b/examples/jsm/loaders/USDZLoader.js new file mode 100644 index 00000000000000..82160cf075ab7d --- /dev/null +++ b/examples/jsm/loaders/USDZLoader.js @@ -0,0 +1,633 @@ +import { + BufferAttribute, + BufferGeometry, + ClampToEdgeWrapping, + FileLoader, + Group, + Loader, + Mesh, + MeshStandardMaterial, + MirroredRepeatWrapping, + RepeatWrapping, + sRGBEncoding, + TextureLoader, + Object3D, +} from 'three'; + +import * as fflate from '../libs/fflate.module.js'; + +class USDAParser { + + parse( text ) { + + const data = {}; + + const lines = text.split( '\n' ); + const length = lines.length; + + let current = 0; + let string = null; + let target = data; + + const stack = [ data ]; + + // debugger; + + function parseNextLine() { + + const line = lines[ current ]; + + // console.log( line ); + + if ( line.includes( '=' ) ) { + + const assignment = line.split( '=' ); + + const lhs = assignment[ 0 ].trim(); + const rhs = assignment[ 1 ].trim(); + + if ( rhs.endsWith( '{' ) ) { + + const group = {}; + stack.push( group ); + + target[ lhs ] = group; + target = group; + + } else { + + target[ lhs ] = rhs; + + } + + } else if ( line.endsWith( '{' ) ) { + + const group = target[ string ] || {}; + stack.push( group ); + + target[ string ] = group; + target = group; + + } else if ( line.endsWith( '}' ) ) { + + stack.pop(); + + if ( stack.length === 0 ) return; + + target = stack[ stack.length - 1 ]; + + } else if ( line.endsWith( '(' ) ) { + + const meta = {}; + stack.push( meta ); + + string = line.split( '(' )[ 0 ].trim() || string; + + target[ string ] = meta; + target = meta; + + } else if ( line.endsWith( ')' ) ) { + + stack.pop(); + + target = stack[ stack.length - 1 ]; + + } else { + + string = line.trim(); + + } + + current ++; + + if ( current < length ) { + + parseNextLine(); + + } + + } + + parseNextLine(); + + return data; + + } + +} + +class USDZLoader extends Loader { + + constructor( manager ) { + + super( manager ); + + } + + load( url, onLoad, onProgress, onError ) { + + const scope = this; + + const loader = new FileLoader( scope.manager ); + loader.setPath( scope.path ); + loader.setResponseType( 'arraybuffer' ); + loader.setRequestHeader( scope.requestHeader ); + loader.setWithCredentials( scope.withCredentials ); + loader.load( url, function ( text ) { + + try { + + onLoad( scope.parse( text ) ); + + } catch ( e ) { + + if ( onError ) { + + onError( e ); + + } else { + + console.error( e ); + + } + + scope.manager.itemError( url ); + + } + + }, onProgress, onError ); + + } + + parse( buffer ) { + + const parser = new USDAParser(); + + function parseAssets( zip ) { + + const data = {}; + const loader = new FileLoader(); + loader.setResponseType( 'arraybuffer' ); + + for ( const filename in zip ) { + + if ( filename.endsWith( 'png' ) ) { + + const blob = new Blob( [ zip[ filename ] ], { type: { type: 'image/png' } } ); + data[ filename ] = URL.createObjectURL( blob ); + + } + + if ( filename.endsWith( 'usd' ) ) { + + const text = fflate.strFromU8( zip[ filename ] ); + data[ filename ] = parser.parse( text ); + + } + + } + + return data; + + } + + function findUSD( zip ) { + + for ( const filename in zip ) { + + if ( filename.endsWith( 'usda' ) ) { + + return zip[ filename ]; + + } + + } + + } + + const zip = fflate.unzipSync( new Uint8Array( buffer ) ); // eslint-disable-line no-undef + + // console.log( zip ); + + const assets = parseAssets( zip ); + + // console.log( assets ) + + const file = findUSD( zip ); + + if ( file === undefined ) { + + console.warn( 'THREE.USDZLoader: No usda file found.' ); + + return new Group(); + + } + + + // Parse file + + const text = fflate.strFromU8( file ); + const root = parser.parse( text ); + + // Build scene + + function findMeshGeometry( data ) { + + if ( ! data ) return undefined; + + if ( 'prepend references' in data ) { + + const reference = data[ 'prepend references' ]; + const parts = reference.split( '@' ); + const path = parts[ 1 ].replace( /^.\//, '' ); + const id = parts[ 2 ].replace( /^<\//, '' ).replace( />$/, '' ); + + return findGeometry( assets[ path ], id ); + + } + + return findGeometry( data ); + + } + + function findGeometry( data, id ) { + + if ( id !== undefined ) { + + const def = `def "%{id}"`; + + if ( def in data ) { + + return data[ def ]; + + } + + } + + for ( const name in data ) { + + const object = data[ name ]; + + if ( name.startsWith( 'def Mesh' ) ) { + + // Move points to Mesh + + if ( 'point3f[] points' in data ) { + + object[ 'point3f[] points' ] = data[ 'point3f[] points' ]; + + } + + // Move st to Mesh + + if ( 'float2[] primvars:st' in data ) { + + object[ 'float2[] primvars:st' ] = data[ 'float2[] primvars:st' ]; + + } + + // Move st indices to Mesh + + if ( 'int[] primvars:st:indices' in data ) { + + object[ 'int[] primvars:st:indices' ] = data[ 'int[] primvars:st:indices' ]; + + } + + return object; + + } + + + if ( typeof object === 'object' ) { + + const geometry = findGeometry( object ); + + if ( geometry ) return geometry; + + } + + } + + } + + function buildGeometry( data ) { + + if ( ! data ) return undefined; + + let geometry = new BufferGeometry(); + + if ( 'int[] faceVertexIndices' in data ) { + + const indices = JSON.parse( data[ 'int[] faceVertexIndices' ] ); + geometry.setIndex( new BufferAttribute( new Uint16Array( indices ), 1 ) ); + + } + + if ( 'point3f[] points' in data ) { + + const positions = JSON.parse( data[ 'point3f[] points' ].replace( /[()]*/g, '' ) ); + const attribute = new BufferAttribute( new Float32Array( positions ), 3 ); + geometry.setAttribute( 'position', attribute ); + + } + + if ( 'normal3f[] normals' in data ) { + + const normals = JSON.parse( data[ 'normal3f[] normals' ].replace( /[()]*/g, '' ) ); + const attribute = new BufferAttribute( new Float32Array( normals ), 3 ); + geometry.setAttribute( 'normal', attribute ); + + } else { + + geometry.computeVertexNormals(); + + } + + if ( 'float2[] primvars:st' in data ) { + + data[ 'texCoord2f[] primvars:st' ] = data[ 'float2[] primvars:st' ]; + + } + + if ( 'texCoord2f[] primvars:st' in data ) { + + const uvs = JSON.parse( data[ 'texCoord2f[] primvars:st' ].replace( /[()]*/g, '' ) ); + const attribute = new BufferAttribute( new Float32Array( uvs ), 2 ); + + if ( 'int[] primvars:st:indices' in data ) { + + geometry = geometry.toNonIndexed(); + + const indices = JSON.parse( data[ 'int[] primvars:st:indices' ] ); + geometry.setAttribute( 'uv', toFlatBufferAttribute( attribute, indices ) ); + + } else { + + geometry.setAttribute( 'uv', attribute ); + + } + + } + + return geometry; + + } + + function toFlatBufferAttribute( attribute, indices ) { + + const array = attribute.array; + const itemSize = attribute.itemSize; + + const array2 = new array.constructor( indices.length * itemSize ); + + let index = 0, index2 = 0; + + for ( let i = 0, l = indices.length; i < l; i ++ ) { + + index = indices[ i ] * itemSize; + + for ( let j = 0; j < itemSize; j ++ ) { + + array2[ index2 ++ ] = array[ index ++ ]; + + } + + } + + return new BufferAttribute( array2, itemSize ); + + } + + function findMeshMaterial( data ) { + + if ( ! data ) return undefined; + + if ( 'rel material:binding' in data ) { + + const reference = data[ 'rel material:binding' ]; + const id = reference.replace( /^<\//, '' ).replace( />$/, '' ); + const parts = id.split( '/' ); + + return findMaterial( root, ` "${ parts[ 1 ] }"` ); + + } + + return findMaterial( data ); + + } + + function findMaterial( data, id = '' ) { + + for ( const name in data ) { + + const object = data[ name ]; + + if ( name.startsWith( 'def Material' + id ) ) { + + return object; + + } + + if ( typeof object === 'object' ) { + + const material = findMaterial( object, id ); + + if ( material ) return material; + + } + + } + + } + + function buildMaterial( data ) { + + const material = new MeshStandardMaterial(); + + if ( data !== undefined ) { + + if ( 'def Shader "PreviewSurface"' in data ) { + + const surface = data[ 'def Shader "PreviewSurface"' ]; + + if ( 'color3f inputs:diffuseColor.connect' in surface ) { + + const path = surface[ 'color3f inputs:diffuseColor.connect' ]; + const sampler = findTexture( root, /(\w+).output/.exec( path )[ 1 ] ); + + material.map = buildTexture( sampler ); + material.map.encoding = sRGBEncoding; + + } else if ( 'color3f inputs:diffuseColor' in surface ) { + + const color = surface[ 'color3f inputs:diffuseColor' ].replace( /[()]*/g, '' ); + material.color.fromArray( JSON.parse( '[' + color + ']' ) ); + + } + + if ( 'normal3f inputs:normal.connect' in surface ) { + + const path = surface[ 'normal3f inputs:normal.connect' ]; + const sampler = findTexture( root, /(\w+).output/.exec( path )[ 1 ] ); + + material.normalMap = buildTexture( sampler ); + + } + + if ( 'float inputs:roughness' in surface ) { + + material.roughness = parseFloat( surface[ 'float inputs:roughness' ] ); + + } + + if ( 'float inputs:metallic' in surface ) { + + material.metalness = parseFloat( surface[ 'float inputs:metallic' ] ); + + } + + } + + if ( 'def Shader "diffuseColor_texture"' in data ) { + + const sampler = data[ 'def Shader "diffuseColor_texture"' ]; + + material.map = buildTexture( sampler ); + material.map.encoding = sRGBEncoding; + + } + + if ( 'def Shader "normal_texture"' in data ) { + + const sampler = data[ 'def Shader "normal_texture"' ]; + + material.normalMap = buildTexture( sampler ); + + } + + } + + return material; + + } + + function findTexture( data, id ) { + + for ( const name in data ) { + + const object = data[ name ]; + + if ( name.startsWith( `def Shader "${ id }"` ) ) { + + return object; + + } + + if ( typeof object === 'object' ) { + + const texture = findTexture( object, id ); + + if ( texture ) return texture; + + } + + } + + } + + function buildTexture( data ) { + + if ( 'asset inputs:file' in data ) { + + const path = data[ 'asset inputs:file' ].replace( /@*/g, '' ); + + const loader = new TextureLoader(); + + const texture = loader.load( assets[ path ] ); + + const map = { + '"clamp"': ClampToEdgeWrapping, + '"mirror"': MirroredRepeatWrapping, + '"repeat"': RepeatWrapping + }; + + if ( 'token inputs:wrapS' in data ) { + + texture.wrapS = map[ data[ 'token inputs:wrapS' ] ]; + + } + + if ( 'token inputs:wrapT' in data ) { + + texture.wrapT = map[ data[ 'token inputs:wrapT' ] ]; + + } + + return texture; + + } + + return null; + + } + + function buildObject( data ) { + + const geometry = buildGeometry( findMeshGeometry( data ) ); + const material = buildMaterial( findMeshMaterial( data ) ); + + const mesh = geometry ? new Mesh( geometry, material ) : new Object3D(); + + if ( 'matrix4d xformOp:transform' in data ) { + + const array = JSON.parse( '[' + data[ 'matrix4d xformOp:transform' ].replace( /[()]*/g, '' ) + ']' ); + + mesh.matrix.fromArray( array ); + mesh.matrix.decompose( mesh.position, mesh.quaternion, mesh.scale ); + + } + + return mesh; + + } + + function buildHierarchy( data, group ) { + + for ( const name in data ) { + + if ( name.startsWith( 'def Scope' ) ) { + + buildHierarchy( data[ name ], group ); + + } else if ( name.startsWith( 'def Xform' ) ) { + + const mesh = buildObject( data[ name ] ); + + if ( /def Xform "(\w+)"/.test( name ) ) { + + mesh.name = /def Xform "(\w+)"/.exec( name )[ 1 ]; + + } + + group.add( mesh ); + + buildHierarchy( data[ name ], mesh ); + + } + + } + + } + + const group = new Group(); + + buildHierarchy( root, group ); + + return group; + + } + +} + +export { USDZLoader }; diff --git a/examples/jsm/loaders/VRMLLoader.js b/examples/jsm/loaders/VRMLLoader.js index 9dd0a9a7e0e76c..842c43943b1d49 100644 --- a/examples/jsm/loaders/VRMLLoader.js +++ b/examples/jsm/loaders/VRMLLoader.js @@ -625,6 +625,7 @@ class VRMLLoader extends Loader { switch ( nodeName ) { + case 'Anchor': case 'Group': case 'Transform': case 'Collision': @@ -706,7 +707,6 @@ class VRMLLoader extends Loader { build = buildWorldInfoNode( node ); break; - case 'Anchor': case 'Billboard': case 'Inline': @@ -794,10 +794,18 @@ class VRMLLoader extends Loader { parseFieldChildren( fieldValues, object ); break; + case 'description': + // field not supported + break; + case 'collide': // field not supported break; + case 'parameter': + // field not supported + break; + case 'rotation': const axis = new Vector3( fieldValues[ 0 ], fieldValues[ 1 ], fieldValues[ 2 ] ); const angle = fieldValues[ 3 ]; @@ -820,6 +828,10 @@ class VRMLLoader extends Loader { // field not supported break; + case 'url': + // field not supported + break; + default: console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); break; diff --git a/examples/jsm/materials/MeshGouraudMaterial.js b/examples/jsm/materials/MeshGouraudMaterial.js new file mode 100644 index 00000000000000..033cd0f5df2ca5 --- /dev/null +++ b/examples/jsm/materials/MeshGouraudMaterial.js @@ -0,0 +1,423 @@ +/** + * MeshGouraudMaterial + * + * Lambert illumination model with Gouraud (per-vertex) shading + * + */ + +import { UniformsUtils, UniformsLib, ShaderMaterial, Color, MultiplyOperation } from 'three'; + +const GouraudShader = { + + uniforms: UniformsUtils.merge( [ + UniformsLib.common, + UniformsLib.specularmap, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: new Color( 0x000000 ) } + } + ] ), + + vertexShader: /* glsl */` + + #define GOURAUD + + varying vec3 vLightFront; + varying vec3 vIndirectFront; + + #ifdef DOUBLE_SIDED + varying vec3 vLightBack; + varying vec3 vIndirectBack; + #endif + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + void main() { + + #include + #include + #include + #include + + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + + #include + #include + + // inlining legacy + + vec3 diffuse = vec3( 1.0 ); + + GeometricContext geometry; + geometry.position = mvPosition.xyz; + geometry.normal = normalize( transformedNormal ); + geometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz ); + + GeometricContext backGeometry; + backGeometry.position = geometry.position; + backGeometry.normal = -geometry.normal; + backGeometry.viewDir = geometry.viewDir; + + vLightFront = vec3( 0.0 ); + vIndirectFront = vec3( 0.0 ); + #ifdef DOUBLE_SIDED + vLightBack = vec3( 0.0 ); + vIndirectBack = vec3( 0.0 ); + #endif + + IncidentLight directLight; + float dotNL; + vec3 directLightColor_Diffuse; + + vIndirectFront += getAmbientLightIrradiance( ambientLightColor ); + + vIndirectFront += getLightProbeIrradiance( lightProbe, geometry.normal ); + + #ifdef DOUBLE_SIDED + + vIndirectBack += getAmbientLightIrradiance( ambientLightColor ); + + vIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry.normal ); + + #endif + + #if NUM_POINT_LIGHTS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) { + + getPointLightInfo( pointLights[ i ], geometry, directLight ); + + dotNL = dot( geometry.normal, directLight.direction ); + directLightColor_Diffuse = directLight.color; + + vLightFront += saturate( dotNL ) * directLightColor_Diffuse; + + #ifdef DOUBLE_SIDED + + vLightBack += saturate( - dotNL ) * directLightColor_Diffuse; + + #endif + + } + #pragma unroll_loop_end + + #endif + + #if NUM_SPOT_LIGHTS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) { + + getSpotLightInfo( spotLights[ i ], geometry, directLight ); + + dotNL = dot( geometry.normal, directLight.direction ); + directLightColor_Diffuse = directLight.color; + + vLightFront += saturate( dotNL ) * directLightColor_Diffuse; + + #ifdef DOUBLE_SIDED + + vLightBack += saturate( - dotNL ) * directLightColor_Diffuse; + + #endif + } + #pragma unroll_loop_end + + #endif + + #if NUM_DIR_LIGHTS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) { + + getDirectionalLightInfo( directionalLights[ i ], geometry, directLight ); + + dotNL = dot( geometry.normal, directLight.direction ); + directLightColor_Diffuse = directLight.color; + + vLightFront += saturate( dotNL ) * directLightColor_Diffuse; + + #ifdef DOUBLE_SIDED + + vLightBack += saturate( - dotNL ) * directLightColor_Diffuse; + + #endif + + } + #pragma unroll_loop_end + + #endif + + #if NUM_HEMI_LIGHTS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) { + + vIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal ); + + #ifdef DOUBLE_SIDED + + vIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry.normal ); + + #endif + + } + #pragma unroll_loop_end + + #endif + + #include + #include + + }`, + + fragmentShader: /* glsl */` + + #define GOURAUD + + uniform vec3 diffuse; + uniform vec3 emissive; + uniform float opacity; + + varying vec3 vLightFront; + varying vec3 vIndirectFront; + + #ifdef DOUBLE_SIDED + varying vec3 vLightBack; + varying vec3 vIndirectBack; + #endif + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + void main() { + + #include + + vec4 diffuseColor = vec4( diffuse, opacity ); + ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); + vec3 totalEmissiveRadiance = emissive; + + #include + #include + #include + #include + #include + #include + #include + + // accumulation + + #ifdef DOUBLE_SIDED + + reflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack; + + #else + + reflectedLight.indirectDiffuse += vIndirectFront; + + #endif + + #include + + reflectedLight.indirectDiffuse *= BRDF_Lambert( diffuseColor.rgb ); + + #ifdef DOUBLE_SIDED + + reflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack; + + #else + + reflectedLight.directDiffuse = vLightFront; + + #endif + + reflectedLight.directDiffuse *= BRDF_Lambert( diffuseColor.rgb ) * getShadowMask(); + + // modulation + + #include + + vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance; + + #include + + #include + #include + #include + #include + #include + #include + + }` + +}; + +// + +class MeshGouraudMaterial extends ShaderMaterial { + + constructor( parameters ) { + + super(); + + this.isMeshGouraudMaterial = true; + + this.type = 'MeshGouraudMaterial'; + + //this.color = new THREE.Color( 0xffffff ); // diffuse + + //this.map = null; + + //this.lightMap = null; + //this.lightMapIntensity = 1.0; + + //this.aoMap = null; + //this.aoMapIntensity = 1.0; + + //this.emissive = new THREE.Color( 0x000000 ); + //this.emissiveIntensity = 1.0; + //this.emissiveMap = null; + + //this.specularMap = null; + + //this.alphaMap = null; + + //this.envMap = null; + this.combine = MultiplyOperation; // combine has no uniform + //this.reflectivity = 1; + //this.refractionRatio = 0.98; + + this.fog = false; // set to use scene fog + this.lights = true; // set to use scene lights + this.clipping = false; // set to use user-defined clipping planes + + const shader = GouraudShader; + + this.defines = Object.assign( {}, shader.defines ); + this.uniforms = UniformsUtils.clone( shader.uniforms ); + this.vertexShader = shader.vertexShader; + this.fragmentShader = shader.fragmentShader; + + const exposePropertyNames = [ + 'map', 'lightMap', 'lightMapIntensity', 'aoMap', 'aoMapIntensity', + 'emissive', 'emissiveIntensity', 'emissiveMap', 'specularMap', 'alphaMap', + 'envMap', 'reflectivity', 'refractionRatio', 'opacity', 'diffuse' + ]; + + for ( const propertyName of exposePropertyNames ) { + + Object.defineProperty( this, propertyName, { + + get: function () { + + return this.uniforms[ propertyName ].value; + + }, + + set: function ( value ) { + + this.uniforms[ propertyName ].value = value; + + } + + } ); + + } + + Object.defineProperty( this, 'color', Object.getOwnPropertyDescriptor( this, 'diffuse' ) ); + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( 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.fog = source.fog; + + return this; + + } + +} + +export { MeshGouraudMaterial }; diff --git a/examples/jsm/math/ColorConverter.js b/examples/jsm/math/ColorConverter.js index c604b2d5341ae4..f45b3c7208ceb6 100644 --- a/examples/jsm/math/ColorConverter.js +++ b/examples/jsm/math/ColorConverter.js @@ -1,6 +1,4 @@ -import { - MathUtils -} from 'three'; +import { MathUtils } from 'three'; const _hsl = {}; @@ -20,13 +18,6 @@ class ColorConverter { static getHSV( color, target ) { - if ( target === undefined ) { - - console.warn( 'THREE.ColorConverter: .getHSV() target is now required' ); - target = { h: 0, s: 0, l: 0 }; - - } - color.getHSL( _hsl ); // based on https://gist.github.com/xpansive/1337890#file-index-js @@ -40,45 +31,6 @@ class ColorConverter { } - // where c, m, y, k is between 0 and 1 - - static setCMYK( color, c, m, y, k ) { - - const r = ( 1 - c ) * ( 1 - k ); - const g = ( 1 - m ) * ( 1 - k ); - const b = ( 1 - y ) * ( 1 - k ); - - return color.setRGB( r, g, b ); - - } - - static getCMYK( color, target ) { - - if ( target === undefined ) { - - console.warn( 'THREE.ColorConverter: .getCMYK() target is now required' ); - target = { c: 0, m: 0, y: 0, k: 0 }; - - } - - const r = color.r; - const g = color.g; - const b = color.b; - - const k = 1 - Math.max( r, g, b ); - const c = ( 1 - r - k ) / ( 1 - k ); - const m = ( 1 - g - k ) / ( 1 - k ); - const y = ( 1 - b - k ) / ( 1 - k ); - - target.c = c; - target.m = m; - target.y = y; - target.k = k; - - return target; - - } - } export { ColorConverter }; diff --git a/examples/jsm/math/ConvexHull.js b/examples/jsm/math/ConvexHull.js index 9384bf14611369..b1368a4ed8ea1a 100644 --- a/examples/jsm/math/ConvexHull.js +++ b/examples/jsm/math/ConvexHull.js @@ -122,7 +122,7 @@ class ConvexHull { intersectRay( ray, target ) { - // based on "Fast Ray-Convex Polyhedron Intersection" by Eric Haines, GRAPHICS GEMS II + // based on "Fast Ray-Convex Polyhedron Intersection" by Eric Haines, GRAPHICS GEMS II const faces = this.faces; @@ -156,7 +156,7 @@ class ConvexHull { if ( vD > 0 ) { - // plane faces away from the ray, so this plane is a back-face + // plane faces away from the ray, so this plane is a back-face tFar = Math.min( t, tFar ); @@ -263,7 +263,7 @@ class ConvexHull { } - // Removes all the visible vertices that a given face is able to see which are stored in the 'assigned' vertext list + // Removes all the visible vertices that a given face is able to see which are stored in the 'assigned' vertex list removeAllVerticesFromFace( face ) { @@ -1268,4 +1268,4 @@ class VertexList { } -export { ConvexHull }; +export { ConvexHull, Face, HalfEdge, VertexNode, VertexList }; diff --git a/examples/jsm/math/Octree.js b/examples/jsm/math/Octree.js index db3732cf1f86c4..fda28705cf8488 100644 --- a/examples/jsm/math/Octree.js +++ b/examples/jsm/math/Octree.js @@ -49,7 +49,7 @@ class Octree { this.box = this.bounds.clone(); - // offset small ammount to account for regular grid + // offset small amount to account for regular grid this.box.min.x -= 0.01; this.box.min.y -= 0.01; this.box.min.z -= 0.01; diff --git a/examples/jsm/misc/GPUComputationRenderer.js b/examples/jsm/misc/GPUComputationRenderer.js index 0738e5eaf30f34..43ff60b1a53d5f 100644 --- a/examples/jsm/misc/GPUComputationRenderer.js +++ b/examples/jsm/misc/GPUComputationRenderer.js @@ -3,8 +3,10 @@ import { ClampToEdgeWrapping, DataTexture, FloatType, + LinearEncoding, Mesh, NearestFilter, + NoToneMapping, PlaneGeometry, RGBAFormat, Scene, @@ -288,6 +290,32 @@ class GPUComputationRenderer { }; + this.dispose = function () { + + mesh.geometry.dispose(); + mesh.material.dispose(); + + const variables = this.variables; + + for ( let i = 0; i < variables.length; i ++ ) { + + const variable = variables[ i ]; + + variable.initialValueTexture?.dispose(); + + const renderTargets = variable.renderTargets; + + for ( let j = 0; j < renderTargets.length; j ++ ) { + + const renderTarget = renderTargets[ j ]; + renderTarget.dispose(); + + } + + } + + }; + function addResolutionDefine( materialShader ) { materialShader.defines.resolution = 'vec2( ' + sizeX.toFixed( 1 ) + ', ' + sizeY.toFixed( 1 ) + ' )'; @@ -369,11 +397,26 @@ class GPUComputationRenderer { const currentRenderTarget = renderer.getRenderTarget(); + const currentXrEnabled = renderer.xr.enabled; + const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate; + const currentOutputEncoding = renderer.outputEncoding; + const currentToneMapping = renderer.toneMapping; + + renderer.xr.enabled = false; // Avoid camera modification + renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows + renderer.outputEncoding = LinearEncoding; + renderer.toneMapping = NoToneMapping; + mesh.material = material; renderer.setRenderTarget( output ); renderer.render( scene, camera ); mesh.material = passThruShader; + renderer.xr.enabled = currentXrEnabled; + renderer.shadowMap.autoUpdate = currentShadowAutoUpdate; + renderer.outputEncoding = currentOutputEncoding; + renderer.toneMapping = currentToneMapping; + renderer.setRenderTarget( currentRenderTarget ); }; diff --git a/examples/jsm/node-editor/NodeEditor.js b/examples/jsm/node-editor/NodeEditor.js index 442a9faf224fd9..9cb135ee8a101b 100644 --- a/examples/jsm/node-editor/NodeEditor.js +++ b/examples/jsm/node-editor/NodeEditor.js @@ -45,6 +45,7 @@ export const NodeList = [ { name: 'Slider', icon: 'adjustments-horizontal', + tags: 'number', nodeClass: SliderEditor }, { @@ -117,6 +118,7 @@ export const NodeList = [ { name: 'Blend', icon: 'layers-subtract', + tags: 'mix', nodeClass: BlendEditor }, { @@ -133,6 +135,7 @@ export const NodeList = [ { name: 'Operator', icon: 'math-symbols', + tags: 'addition, subtration, multiplication, division', nodeClass: OperatorEditor }, { @@ -161,12 +164,14 @@ export const NodeList = [ name: 'Trigonometry', icon: 'wave-sine', tip: 'Sin / Cos / Tan / ...', + tags: 'sin, cos, tan, asin, acos, atan, sine, cosine, tangent, arcsine, arccosine, arctangent', nodeClass: TrigonometryEditor }, { name: 'Angle', icon: 'angle', tip: 'Degress / Radians', + tags: 'degress, radians', nodeClass: AngleEditor }, { @@ -303,6 +308,13 @@ export class NodeEditor extends EventDispatcher { this.canvas = canvas; this.domElement = domElement; + this._preview = false; + + this.search = null; + + this.menu = null; + this.previewMenu = null; + this.nodesContext = null; this.examplesContext = null; @@ -315,21 +327,26 @@ export class NodeEditor extends EventDispatcher { } + setSize( width, height ) { + + this.canvas.setSize( width, height ); + + return this; + + } + centralizeNode( node ) { const canvas = this.canvas; - const canvasRect = canvas.rect; - const nodeRect = node.dom.getBoundingClientRect(); - const defaultOffsetX = nodeRect.width; - const defaultOffsetY = nodeRect.height; - node.setPosition( - ( canvas.relativeX + ( canvasRect.width / 2 ) ) - defaultOffsetX, - ( canvas.relativeY + ( canvasRect.height / 2 ) ) - defaultOffsetY + ( ( canvas.width / 2 ) - canvas.scrollLeft ) - nodeRect.width, + ( ( canvas.height / 2 ) - canvas.scrollTop ) - nodeRect.height ); + return this; + } add( node ) { @@ -359,9 +376,47 @@ export class NodeEditor extends EventDispatcher { } + set preview( value ) { + + if ( this._preview === value ) return; + + if ( value ) { + + this.menu.dom.remove(); + this.canvas.dom.remove(); + this.search.dom.remove(); + + this.domElement.append( this.previewMenu.dom ); + + } else { + + this.canvas.focusSelected = false; + + this.domElement.append( this.menu.dom ); + this.domElement.append( this.canvas.dom ); + this.domElement.append( this.search.dom ); + + this.previewMenu.dom.remove(); + + } + + this._preview = value; + + } + + get preview() { + + return this._preview; + + } + newProject() { - this.canvas.clear(); + const canvas = this.canvas; + canvas.clear(); + canvas.scrollLeft = 0; + canvas.scrollTop = 0; + canvas.zoom = 1; this.dispatchEvent( { type: 'new' } ); @@ -426,13 +481,23 @@ export class NodeEditor extends EventDispatcher { _initMenu() { const menu = new CircleMenu(); + const previewMenu = new CircleMenu(); + + menu.setAlign( 'top left' ); + previewMenu.setAlign( 'top left' ); + const previewButton = new ButtonInput().setIcon( 'ti ti-3d-cube-sphere' ).setToolTip( 'Preview' ); const menuButton = new ButtonInput().setIcon( 'ti ti-apps' ).setToolTip( 'Add' ); const examplesButton = new ButtonInput().setIcon( 'ti ti-file-symlink' ).setToolTip( 'Examples' ); const newButton = new ButtonInput().setIcon( 'ti ti-file' ).setToolTip( 'New' ); const openButton = new ButtonInput().setIcon( 'ti ti-upload' ).setToolTip( 'Open' ); const saveButton = new ButtonInput().setIcon( 'ti ti-download' ).setToolTip( 'Save' ); + const editorButton = new ButtonInput().setIcon( 'ti ti-subtask' ).setToolTip( 'Editor' ); + + previewButton.onClick( () => this.preview = true ); + editorButton.onClick( () => this.preview = false ); + menuButton.onClick( () => this.nodesContext.open() ); examplesButton.onClick( () => this.examplesContext.open() ); @@ -486,15 +551,19 @@ export class NodeEditor extends EventDispatcher { } ); - menu.add( examplesButton ) - .add( menuButton ) + menu.add( previewButton ) .add( newButton ) + .add( examplesButton ) .add( openButton ) - .add( saveButton ); + .add( saveButton ) + .add( menuButton ); + + previewMenu.add( editorButton ); this.domElement.append( menu.dom ); this.menu = menu; + this.previewMenu = previewMenu; } @@ -541,7 +610,6 @@ export class NodeEditor extends EventDispatcher { addExample( basicContext, 'Animate UV' ); addExample( basicContext, 'Fake top light' ); addExample( basicContext, 'Oscillator color' ); - addExample( basicContext, 'Matcap' ); addExample( advancedContext, 'Rim' ); @@ -571,11 +639,18 @@ export class NodeEditor extends EventDispatcher { this.add( node ); this.centralizeNode( node ); + this.canvas.select( node ); } ); search.add( button ); + if ( item.tags !== undefined ) { + + search.setTag( button, item.tags ); + + } + } if ( item.children ) { @@ -652,6 +727,7 @@ export class NodeEditor extends EventDispatcher { this.add( node ); this.centralizeNode( node ); + this.canvas.select( node ); } ); @@ -675,6 +751,8 @@ export class NodeEditor extends EventDispatcher { } ); + this.search = search; + this.domElement.append( search.dom ); } @@ -698,6 +776,7 @@ export class NodeEditor extends EventDispatcher { } else { this.centralizeNode( node ); + this.canvas.select( node ); } diff --git a/examples/jsm/node-editor/accessors/MatcapUVEditor.js b/examples/jsm/node-editor/accessors/MatcapUVEditor.js index 558d92fe97d2e8..747d8e41c6e899 100644 --- a/examples/jsm/node-editor/accessors/MatcapUVEditor.js +++ b/examples/jsm/node-editor/accessors/MatcapUVEditor.js @@ -1,5 +1,5 @@ import { BaseNode } from '../core/BaseNode.js'; -import { MatcapUVNode } from 'three-nodes/Nodes.js'; +import { MatcapUVNode } from 'three/nodes'; export class MatcapUVEditor extends BaseNode { diff --git a/examples/jsm/node-editor/accessors/NormalEditor.js b/examples/jsm/node-editor/accessors/NormalEditor.js index 0653378ea8d073..d6d4264557d8e9 100644 --- a/examples/jsm/node-editor/accessors/NormalEditor.js +++ b/examples/jsm/node-editor/accessors/NormalEditor.js @@ -1,6 +1,6 @@ import { SelectInput, Element } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { NormalNode } from 'three-nodes/Nodes.js'; +import { NormalNode } from 'three/nodes'; export class NormalEditor extends BaseNode { diff --git a/examples/jsm/node-editor/accessors/PositionEditor.js b/examples/jsm/node-editor/accessors/PositionEditor.js index 4264fed9ec1049..59b125e4d152b8 100644 --- a/examples/jsm/node-editor/accessors/PositionEditor.js +++ b/examples/jsm/node-editor/accessors/PositionEditor.js @@ -1,6 +1,6 @@ import { SelectInput, Element } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { PositionNode } from 'three-nodes/Nodes.js'; +import { PositionNode } from 'three/nodes'; export class PositionEditor extends BaseNode { diff --git a/examples/jsm/node-editor/accessors/UVEditor.js b/examples/jsm/node-editor/accessors/UVEditor.js index 6d17b4cc78cb9f..c77e302e234a34 100644 --- a/examples/jsm/node-editor/accessors/UVEditor.js +++ b/examples/jsm/node-editor/accessors/UVEditor.js @@ -1,6 +1,6 @@ import { SelectInput, LabelElement } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { UVNode } from 'three-nodes/Nodes.js'; +import { UVNode } from 'three/nodes'; export class UVEditor extends BaseNode { diff --git a/examples/jsm/node-editor/core/BaseNode.js b/examples/jsm/node-editor/core/BaseNode.js index 21ddf1650848b0..d3d3f585b97bf1 100644 --- a/examples/jsm/node-editor/core/BaseNode.js +++ b/examples/jsm/node-editor/core/BaseNode.js @@ -34,6 +34,12 @@ export class BaseNode extends ObjectNode { } + getColor() { + + return ( this.getColorValueFromValue( this.value ) || '#777777' ) + 'BB'; + + } + serialize( data ) { super.serialize( data ); @@ -64,15 +70,16 @@ export class BaseNode extends ObjectNode { if ( value.isMaterial === true ) { - return 'forestgreen'; + //return 'forestgreen'; + return '#228b22'; } else if ( value.isObject3D === true ) { - return 'orange'; + return '#ffa500'; } else if ( value.isDataFile === true ) { - return 'aqua'; + return '#00ffff'; } diff --git a/examples/jsm/node-editor/display/BlendEditor.js b/examples/jsm/node-editor/display/BlendEditor.js index 3dc68ada25e5b5..bafb6ec0ca5168 100644 --- a/examples/jsm/node-editor/display/BlendEditor.js +++ b/examples/jsm/node-editor/display/BlendEditor.js @@ -1,6 +1,6 @@ import { LabelElement } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { MathNode, UniformNode } from 'three-nodes/Nodes.js'; +import { MathNode, UniformNode } from 'three/nodes'; const NULL_VALUE = new UniformNode( 0 ); const ONE_VALUE = new UniformNode( 1 ); diff --git a/examples/jsm/node-editor/display/NormalMapEditor.js b/examples/jsm/node-editor/display/NormalMapEditor.js index 101e08186fcfea..f8835c5e8b140d 100644 --- a/examples/jsm/node-editor/display/NormalMapEditor.js +++ b/examples/jsm/node-editor/display/NormalMapEditor.js @@ -1,6 +1,6 @@ import { SelectInput, Element, LabelElement } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { NormalMapNode, ConstNode } from 'three-nodes/Nodes.js'; +import { NormalMapNode, ConstNode } from 'three/nodes'; import { TangentSpaceNormalMap, ObjectSpaceNormalMap } from 'three'; const nullValue = new ConstNode( 0 ); diff --git a/examples/jsm/node-editor/inputs/ColorEditor.js b/examples/jsm/node-editor/inputs/ColorEditor.js index 2d57bdbaffa032..b0c13c3befd217 100644 --- a/examples/jsm/node-editor/inputs/ColorEditor.js +++ b/examples/jsm/node-editor/inputs/ColorEditor.js @@ -1,7 +1,7 @@ import { ColorInput, StringInput, NumberInput, LabelElement, Element } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; import { Color } from 'three'; -import { UniformNode } from 'three-nodes/Nodes.js'; +import { UniformNode } from 'three/nodes'; export class ColorEditor extends BaseNode { diff --git a/examples/jsm/node-editor/inputs/FloatEditor.js b/examples/jsm/node-editor/inputs/FloatEditor.js index 479a6948fff761..4d3b5f49d2b92e 100644 --- a/examples/jsm/node-editor/inputs/FloatEditor.js +++ b/examples/jsm/node-editor/inputs/FloatEditor.js @@ -1,6 +1,6 @@ import { NumberInput, Element } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { UniformNode } from 'three-nodes/Nodes.js'; +import { UniformNode } from 'three/nodes'; export class FloatEditor extends BaseNode { diff --git a/examples/jsm/node-editor/inputs/SliderEditor.js b/examples/jsm/node-editor/inputs/SliderEditor.js index 24e118e5cf7dc1..2b7685ed5a89a9 100644 --- a/examples/jsm/node-editor/inputs/SliderEditor.js +++ b/examples/jsm/node-editor/inputs/SliderEditor.js @@ -1,6 +1,6 @@ import { ButtonInput, SliderInput, NumberInput, LabelElement, Element } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { UniformNode } from 'three-nodes/Nodes.js'; +import { UniformNode } from 'three/nodes'; export class SliderEditor extends BaseNode { diff --git a/examples/jsm/node-editor/inputs/TextureEditor.js b/examples/jsm/node-editor/inputs/TextureEditor.js index c690b3687ad290..f1caa3059973e0 100644 --- a/examples/jsm/node-editor/inputs/TextureEditor.js +++ b/examples/jsm/node-editor/inputs/TextureEditor.js @@ -1,6 +1,6 @@ import { LabelElement, ToggleInput, SelectInput } from '../../libs/flow.module.js'; import { BaseNode, onNodeValidElement } from '../core/BaseNode.js'; -import { TextureNode, UVNode } from 'three-nodes/Nodes.js'; +import { TextureNode, UVNode } from 'three/nodes'; import { Texture, TextureLoader, RepeatWrapping, ClampToEdgeWrapping, MirroredRepeatWrapping } from 'three'; const fileTexture = new WeakMap(); diff --git a/examples/jsm/node-editor/inputs/Vector2Editor.js b/examples/jsm/node-editor/inputs/Vector2Editor.js index fdda75af666577..b24e4d4f4aadee 100644 --- a/examples/jsm/node-editor/inputs/Vector2Editor.js +++ b/examples/jsm/node-editor/inputs/Vector2Editor.js @@ -1,7 +1,7 @@ import { NumberInput, LabelElement } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; import { Vector2 } from 'three'; -import { UniformNode } from 'three-nodes/Nodes.js'; +import { UniformNode } from 'three/nodes'; export class Vector2Editor extends BaseNode { diff --git a/examples/jsm/node-editor/inputs/Vector3Editor.js b/examples/jsm/node-editor/inputs/Vector3Editor.js index 9c2c129d00fd1c..b0589c7e313851 100644 --- a/examples/jsm/node-editor/inputs/Vector3Editor.js +++ b/examples/jsm/node-editor/inputs/Vector3Editor.js @@ -1,7 +1,7 @@ import { NumberInput, LabelElement } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; import { Vector3 } from 'three'; -import { UniformNode } from 'three-nodes/Nodes.js'; +import { UniformNode } from 'three/nodes'; export class Vector3Editor extends BaseNode { diff --git a/examples/jsm/node-editor/inputs/Vector4Editor.js b/examples/jsm/node-editor/inputs/Vector4Editor.js index aa8a11f15e6606..8cddb3ed952488 100644 --- a/examples/jsm/node-editor/inputs/Vector4Editor.js +++ b/examples/jsm/node-editor/inputs/Vector4Editor.js @@ -1,7 +1,7 @@ import { NumberInput, LabelElement } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; import { Vector4 } from 'three'; -import { UniformNode } from 'three-nodes/Nodes.js'; +import { UniformNode } from 'three/nodes'; export class Vector4Editor extends BaseNode { diff --git a/examples/jsm/node-editor/materials/BasicMaterialEditor.js b/examples/jsm/node-editor/materials/BasicMaterialEditor.js index 337a0af9f3ef39..1bd6ef8f8b5b7e 100644 --- a/examples/jsm/node-editor/materials/BasicMaterialEditor.js +++ b/examples/jsm/node-editor/materials/BasicMaterialEditor.js @@ -1,7 +1,6 @@ import { ColorInput, SliderInput, LabelElement } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { MeshBasicNodeMaterial } from 'three-nodes/Nodes.js'; -import { MathUtils } from 'three'; +import { MeshBasicNodeMaterial } from 'three/nodes'; export class BasicMaterialEditor extends BaseNode { @@ -65,23 +64,21 @@ export class BasicMaterialEditor extends BaseNode { this.updateTransparent(); - // TODO: Fix on NodeMaterial System - material.customProgramCacheKey = () => { - - return MathUtils.generateUUID(); - - }; - } updateTransparent() { const { material, opacity } = this; - material.transparent = opacity.getLinkedObject() || material.opacity < 1 ? true : false; + const transparent = opacity.getLinkedObject() || material.opacity < 1 ? true : false; + const needsUpdate = transparent !== material.transparent; + + material.transparent = transparent; opacity.setIcon( material.transparent ? 'ti ti-layers-intersect' : 'ti ti-layers-subtract' ); + if ( needsUpdate === true ) material.dispose(); + } } diff --git a/examples/jsm/node-editor/materials/PointsMaterialEditor.js b/examples/jsm/node-editor/materials/PointsMaterialEditor.js index 85c9694540f867..eab50af4f3e4ee 100644 --- a/examples/jsm/node-editor/materials/PointsMaterialEditor.js +++ b/examples/jsm/node-editor/materials/PointsMaterialEditor.js @@ -1,6 +1,6 @@ import { ColorInput, ToggleInput, SliderInput, LabelElement } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { PointsNodeMaterial } from 'three-nodes/Nodes.js'; +import { PointsNodeMaterial } from 'three/nodes'; import * as THREE from 'three'; export class PointsMaterialEditor extends BaseNode { diff --git a/examples/jsm/node-editor/materials/StandardMaterialEditor.js b/examples/jsm/node-editor/materials/StandardMaterialEditor.js index 29785e350bea47..2f05c1ab4ff68a 100644 --- a/examples/jsm/node-editor/materials/StandardMaterialEditor.js +++ b/examples/jsm/node-editor/materials/StandardMaterialEditor.js @@ -1,7 +1,6 @@ import { ColorInput, SliderInput, LabelElement } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { MeshStandardNodeMaterial } from 'three-nodes/Nodes.js'; -import * as THREE from 'three'; +import { MeshStandardNodeMaterial } from 'three/nodes'; export class StandardMaterialEditor extends BaseNode { @@ -99,23 +98,21 @@ export class StandardMaterialEditor extends BaseNode { this.updateTransparent(); - // TODO: Fix on NodeMaterial System - material.customProgramCacheKey = () => { - - return THREE.MathUtils.generateUUID(); - - }; - } updateTransparent() { const { material, opacity } = this; - material.transparent = opacity.getLinkedObject() || material.opacity < 1 ? true : false; + const transparent = opacity.getLinkedObject() || material.opacity < 1 ? true : false; + const needsUpdate = transparent !== material.transparent; + + material.transparent = transparent; opacity.setIcon( material.transparent ? 'ti ti-layers-intersect' : 'ti ti-layers-subtract' ); + if ( needsUpdate === true ) material.dispose(); + } } diff --git a/examples/jsm/node-editor/math/AngleEditor.js b/examples/jsm/node-editor/math/AngleEditor.js index 77beda007eaab0..d063c755275713 100644 --- a/examples/jsm/node-editor/math/AngleEditor.js +++ b/examples/jsm/node-editor/math/AngleEditor.js @@ -1,7 +1,7 @@ import { SelectInput, Element, LabelElement } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; import { Vector3 } from 'three'; -import { MathNode, UniformNode } from 'three-nodes/Nodes.js'; +import { MathNode, UniformNode } from 'three/nodes'; const DEFAULT_VALUE = new UniformNode( new Vector3() ); @@ -14,9 +14,9 @@ export class AngleEditor extends BaseNode { super( 'Angle', 1, node, 175 ); const optionsField = new SelectInput( [ - { name: 'Degrees to Radians', value: MathNode.RAD }, - { name: 'Radians to Degrees', value: MathNode.DEG } - ], MathNode.RAD ).onChange( () => { + { name: 'Degrees to Radians', value: MathNode.RADIANS }, + { name: 'Radians to Degrees', value: MathNode.DEGREES } + ], MathNode.RADIANS ).onChange( () => { node.method = optionsField.getValue(); diff --git a/examples/jsm/node-editor/math/DotEditor.js b/examples/jsm/node-editor/math/DotEditor.js index 6251627eefba52..b7514315e9d8e9 100644 --- a/examples/jsm/node-editor/math/DotEditor.js +++ b/examples/jsm/node-editor/math/DotEditor.js @@ -1,6 +1,6 @@ import { LabelElement } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { MathNode, UniformNode } from 'three-nodes/Nodes.js'; +import { MathNode, UniformNode } from 'three/nodes'; const NULL_VALUE = new UniformNode( 0 ); diff --git a/examples/jsm/node-editor/math/InvertEditor.js b/examples/jsm/node-editor/math/InvertEditor.js index 0eddcf15d9c276..6998cfab807732 100644 --- a/examples/jsm/node-editor/math/InvertEditor.js +++ b/examples/jsm/node-editor/math/InvertEditor.js @@ -1,6 +1,6 @@ -import { SelectInput, LabelElement } from '../../libs/flow.module.js'; +import { SelectInput, Element, LabelElement } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { MathNode, UniformNode } from 'three-nodes/Nodes.js'; +import { MathNode, UniformNode } from 'three/nodes'; const DEFAULT_VALUE = new UniformNode( 0 ); @@ -31,7 +31,7 @@ export class InvertEditor extends BaseNode { } ); - this.add( new LabelElement( 'Method' ).add( optionsField ) ) + this.add( new Element().add( optionsField ) ) .add( input ); } diff --git a/examples/jsm/node-editor/math/LimiterEditor.js b/examples/jsm/node-editor/math/LimiterEditor.js index 29a13ea1acb641..96c5ea7015529a 100644 --- a/examples/jsm/node-editor/math/LimiterEditor.js +++ b/examples/jsm/node-editor/math/LimiterEditor.js @@ -1,6 +1,6 @@ import { SelectInput, LabelElement, Element, NumberInput } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { MathNode, UniformNode } from 'three-nodes/Nodes.js'; +import { MathNode, UniformNode } from 'three/nodes'; export class LimiterEditor extends BaseNode { diff --git a/examples/jsm/node-editor/math/NormalizeEditor.js b/examples/jsm/node-editor/math/NormalizeEditor.js index cd6aaeabb13d4e..31b694fb36ad39 100644 --- a/examples/jsm/node-editor/math/NormalizeEditor.js +++ b/examples/jsm/node-editor/math/NormalizeEditor.js @@ -1,7 +1,7 @@ import { LabelElement } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; import { Vector3 } from 'three'; -import { MathNode, UniformNode } from 'three-nodes/Nodes.js'; +import { MathNode, UniformNode } from 'three/nodes'; const DEFAULT_VALUE = new UniformNode( new Vector3() ); diff --git a/examples/jsm/node-editor/math/OperatorEditor.js b/examples/jsm/node-editor/math/OperatorEditor.js index b1b9c044bc0fb2..a72b8bdf30ad15 100644 --- a/examples/jsm/node-editor/math/OperatorEditor.js +++ b/examples/jsm/node-editor/math/OperatorEditor.js @@ -1,5 +1,5 @@ import { Element, LabelElement, NumberInput, SelectInput } from '../../libs/flow.module.js'; -import { UniformNode, OperatorNode } from 'three-nodes/Nodes.js'; +import { UniformNode, OperatorNode } from 'three/nodes'; import { BaseNode } from '../core/BaseNode.js'; export class OperatorEditor extends BaseNode { diff --git a/examples/jsm/node-editor/math/PowerEditor.js b/examples/jsm/node-editor/math/PowerEditor.js index 1436dbbf54b044..a2a0ae573caf98 100644 --- a/examples/jsm/node-editor/math/PowerEditor.js +++ b/examples/jsm/node-editor/math/PowerEditor.js @@ -1,6 +1,6 @@ import { LabelElement, NumberInput } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { MathNode, UniformNode } from 'three-nodes/Nodes.js'; +import { MathNode, UniformNode } from 'three/nodes'; export class PowerEditor extends BaseNode { diff --git a/examples/jsm/node-editor/math/TrigonometryEditor.js b/examples/jsm/node-editor/math/TrigonometryEditor.js index 365d4c40871cc4..83b979d224ca67 100644 --- a/examples/jsm/node-editor/math/TrigonometryEditor.js +++ b/examples/jsm/node-editor/math/TrigonometryEditor.js @@ -1,7 +1,7 @@ import { SelectInput, Element, LabelElement } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; import { Vector3 } from 'three'; -import { MathNode, UniformNode } from 'three-nodes/Nodes.js'; +import { MathNode, UniformNode } from 'three/nodes'; const DEFAULT_VALUE = new UniformNode( new Vector3() ); diff --git a/examples/jsm/node-editor/procedural/CheckerEditor.js b/examples/jsm/node-editor/procedural/CheckerEditor.js index 0c4b7fa6c2062c..fb249c6e221498 100644 --- a/examples/jsm/node-editor/procedural/CheckerEditor.js +++ b/examples/jsm/node-editor/procedural/CheckerEditor.js @@ -1,6 +1,6 @@ import { LabelElement } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { CheckerNode, UVNode } from 'three-nodes/Nodes.js'; +import { CheckerNode, UVNode } from 'three/nodes'; const defaultUV = new UVNode(); diff --git a/examples/jsm/node-editor/scene/MeshEditor.js b/examples/jsm/node-editor/scene/MeshEditor.js index 35e7b472f40166..332ddc0974e89e 100644 --- a/examples/jsm/node-editor/scene/MeshEditor.js +++ b/examples/jsm/node-editor/scene/MeshEditor.js @@ -16,7 +16,8 @@ export class MeshEditor extends Object3DEditor { this.material = null; - this.defaultMaterial = null; + this.meshMaterial = null; + this.defaultMeshMaterial = null; this._initMaterial(); @@ -34,9 +35,9 @@ export class MeshEditor extends Object3DEditor { _initMaterial() { - const materialElement = new LabelElement( 'Material' ).setInputColor( 'forestgreen' ).setInput( 1 ); + const material = new LabelElement( 'Material' ).setInputColor( 'forestgreen' ).setInput( 1 ); - materialElement.onValid( ( source, target, stage ) => { + material.onValid( ( source, target, stage ) => { const object = target.getObject(); @@ -56,13 +57,15 @@ export class MeshEditor extends Object3DEditor { } ).onConnect( () => { - this.material = materialElement.getLinkedObject() || this.defaultMaterial; + this.meshMaterial = material.getLinkedObject() || this.defaultMeshMaterial; this.update(); } ); - this.add( materialElement ); + this.add( material ); + + this.material = material; } @@ -74,7 +77,7 @@ export class MeshEditor extends Object3DEditor { if ( mesh ) { - mesh.material = this.material || this.defaultMaterial; + mesh.material = this.meshMaterial || this.defaultMeshMaterial; } @@ -84,7 +87,7 @@ export class MeshEditor extends Object3DEditor { super.updateDefault(); - this.defaultMaterial = this.mesh.material; + this.defaultMeshMaterial = this.mesh.material; } @@ -92,7 +95,7 @@ export class MeshEditor extends Object3DEditor { super.restoreDefault(); - this.mesh.material = this.defaultMaterial; + this.mesh.material = this.defaultMeshMaterial; } diff --git a/examples/jsm/node-editor/utils/JoinEditor.js b/examples/jsm/node-editor/utils/JoinEditor.js index d7b43b6b57c0d2..ce83e46346fb64 100644 --- a/examples/jsm/node-editor/utils/JoinEditor.js +++ b/examples/jsm/node-editor/utils/JoinEditor.js @@ -1,6 +1,6 @@ import { LabelElement } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { JoinNode, UniformNode } from 'three-nodes/Nodes.js'; +import { JoinNode, UniformNode } from 'three/nodes'; const NULL_VALUE = new UniformNode( 0 ); diff --git a/examples/jsm/node-editor/utils/OscillatorEditor.js b/examples/jsm/node-editor/utils/OscillatorEditor.js index 25552857086762..2c17c546e7942e 100644 --- a/examples/jsm/node-editor/utils/OscillatorEditor.js +++ b/examples/jsm/node-editor/utils/OscillatorEditor.js @@ -1,6 +1,6 @@ import { SelectInput, LabelElement, Element } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { OscNode, UniformNode } from 'three-nodes/Nodes.js'; +import { OscNode, UniformNode } from 'three/nodes'; const NULL_VALUE = new UniformNode( 0 ); diff --git a/examples/jsm/node-editor/utils/PreviewEditor.js b/examples/jsm/node-editor/utils/PreviewEditor.js index 44b77f4e82aeae..0775cdf2ea2ec4 100644 --- a/examples/jsm/node-editor/utils/PreviewEditor.js +++ b/examples/jsm/node-editor/utils/PreviewEditor.js @@ -1,8 +1,8 @@ -import { OrbitControls } from 'three-addons/controls/OrbitControls.js'; -import { ViewHelper } from 'three-addons/helpers/ViewHelper.js'; +import { OrbitControls } from '../../controls/OrbitControls.js'; +import { ViewHelper } from '../../helpers/ViewHelper.js'; import { Element, LabelElement, SelectInput } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { MeshBasicNodeMaterial, ConstNode } from 'three-nodes/Nodes.js'; +import { MeshBasicNodeMaterial, ConstNode } from 'three/nodes'; import { WebGLRenderer, PerspectiveCamera, Scene, Mesh, DoubleSide, SphereGeometry, BoxGeometry, PlaneGeometry, TorusKnotGeometry } from 'three'; const nullValue = new ConstNode( 0 ); @@ -65,6 +65,8 @@ export class PreviewEditor extends BaseNode { const previewElement = new Element(); previewElement.dom.style[ 'padding-top' ] = 0; previewElement.dom.style[ 'padding-bottom' ] = 0; + previewElement.dom.style[ 'padding-left' ] = 0; + previewElement.dom.style[ 'padding-right' ] = '14px'; const sceneInput = new SelectInput( [ { name: 'Box', value: 'box' }, @@ -86,6 +88,8 @@ export class PreviewEditor extends BaseNode { previewElement.dom.append( canvas ); previewElement.setHeight( height ); + previewElement.dom.addEventListener( 'wheel', e => e.stopPropagation() ); + const renderer = new WebGLRenderer( { canvas, alpha: true diff --git a/examples/jsm/node-editor/utils/SplitEditor.js b/examples/jsm/node-editor/utils/SplitEditor.js index 3f21079de27307..316fe4b66a88cf 100644 --- a/examples/jsm/node-editor/utils/SplitEditor.js +++ b/examples/jsm/node-editor/utils/SplitEditor.js @@ -1,6 +1,6 @@ import { SelectInput, Element } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { SplitNode, UniformNode } from 'three-nodes/Nodes.js'; +import { SplitNode, UniformNode } from 'three/nodes'; const NULL_VALUE = new UniformNode( 0 ); diff --git a/examples/jsm/node-editor/utils/TimerEditor.js b/examples/jsm/node-editor/utils/TimerEditor.js index ecfaf3d5b4de8e..4188c68de8dd74 100644 --- a/examples/jsm/node-editor/utils/TimerEditor.js +++ b/examples/jsm/node-editor/utils/TimerEditor.js @@ -1,6 +1,6 @@ import { NumberInput, LabelElement, Element, ButtonInput } from '../../libs/flow.module.js'; import { BaseNode } from '../core/BaseNode.js'; -import { TimerNode } from 'three-nodes/Nodes.js'; +import { TimerNode } from 'three/nodes'; export class TimerEditor extends BaseNode { diff --git a/examples/jsm/nodes/Nodes.js b/examples/jsm/nodes/Nodes.js index dfb3fd48d88760..15a5f6da654e41 100644 --- a/examples/jsm/nodes/Nodes.js +++ b/examples/jsm/nodes/Nodes.js @@ -26,6 +26,7 @@ import VarNode from './core/VarNode.js'; import VaryingNode from './core/VaryingNode.js'; // accessors +import BitangentNode from './accessors/BitangentNode.js'; import BufferNode from './accessors/BufferNode.js'; import CameraNode from './accessors/CameraNode.js'; import CubeTextureNode from './accessors/CubeTextureNode.js'; @@ -41,6 +42,7 @@ import PositionNode from './accessors/PositionNode.js'; import ReferenceNode from './accessors/ReferenceNode.js'; import ReflectVectorNode from './accessors/ReflectVectorNode.js'; import SkinningNode from './accessors/SkinningNode.js'; +import TangentNode from './accessors/TangentNode.js'; import TextureNode from './accessors/TextureNode.js'; import UVNode from './accessors/UVNode.js'; import UserDataNode from './accessors/UserDataNode.js'; @@ -52,11 +54,14 @@ import RangeNode from './geometry/RangeNode.js'; import ComputeNode from './gpgpu/ComputeNode.js'; // display +import BlendModeNode from './display/BlendModeNode.js'; import ColorAdjustmentNode from './display/ColorAdjustmentNode.js'; import ColorSpaceNode from './display/ColorSpaceNode.js'; import FrontFacingNode from './display/FrontFacingNode.js'; import NormalMapNode from './display/NormalMapNode.js'; +import PosterizeNode from './display/PosterizeNode.js'; import ToneMappingNode from './display/ToneMappingNode.js'; +import ViewportNode from './display/ViewportNode.js'; // math import MathNode from './math/MathNode.js'; @@ -76,20 +81,27 @@ import AnalyticLightNode from './lighting/AnalyticLightNode.js'; // utils import ArrayElementNode from './utils/ArrayElementNode.js'; import ConvertNode from './utils/ConvertNode.js'; +import EquirectUVNode from './utils/EquirectUVNode.js'; import JoinNode from './utils/JoinNode.js'; import MatcapUVNode from './utils/MatcapUVNode.js'; import MaxMipLevelNode from './utils/MaxMipLevelNode.js'; import OscNode from './utils/OscNode.js'; -import RotateUVNode from './utils/RotateUVNode.js' +import RemapNode from './utils/RemapNode.js'; +import RotateUVNode from './utils/RotateUVNode.js'; import SplitNode from './utils/SplitNode.js'; import SpriteSheetUVNode from './utils/SpriteSheetUVNode.js'; import TimerNode from './utils/TimerNode.js'; +import TriplanarTexturesNode from './utils/TriplanarTexturesNode.js'; // loaders import NodeLoader from './loaders/NodeLoader.js'; import NodeObjectLoader from './loaders/NodeObjectLoader.js'; import NodeMaterialLoader from './loaders/NodeMaterialLoader.js'; +// parsers +import WGSLNodeParser from './parsers/WGSLNodeParser.js'; +import GLSLNodeParser from './parsers/GLSLNodeParser.js'; + // procedural import CheckerNode from './procedural/CheckerNode.js'; @@ -106,6 +118,12 @@ export * from './materials/Materials.js'; // shader node export * from './shadernode/ShaderNodeElements.js'; +// extensions +export * from './materialx/MaterialXNodes.js'; + +// shader stages +export { defaultShaderStages } from './core/NodeBuilder.js'; + const nodeLib = { // core ArrayUniformNode, @@ -141,6 +159,7 @@ const nodeLib = { ComputeNode, // accessors + BitangentNode, BufferNode, CameraNode, CubeTextureNode, @@ -156,16 +175,20 @@ const nodeLib = { ReferenceNode, ReflectVectorNode, SkinningNode, + TangentNode, TextureNode, UVNode, UserDataNode, // display + BlendModeNode, ColorAdjustmentNode, ColorSpaceNode, FrontFacingNode, NormalMapNode, + PosterizeNode, ToneMappingNode, + ViewportNode, // math MathNode, @@ -185,14 +208,17 @@ const nodeLib = { // utils ArrayElementNode, ConvertNode, + EquirectUVNode, JoinNode, MatcapUVNode, MaxMipLevelNode, OscNode, + RemapNode, RotateUVNode, SplitNode, SpriteSheetUVNode, TimerNode, + TriplanarTexturesNode, // procedural CheckerNode, @@ -204,7 +230,11 @@ const nodeLib = { // loaders NodeLoader, NodeObjectLoader, - NodeMaterialLoader + NodeMaterialLoader, + + // parsers + WGSLNodeParser, + GLSLNodeParser }; @@ -249,6 +279,7 @@ export { ComputeNode, // accessors + BitangentNode, BufferNode, CameraNode, CubeTextureNode, @@ -264,16 +295,20 @@ export { ReferenceNode, ReflectVectorNode, SkinningNode, + TangentNode, TextureNode, UVNode, UserDataNode, // display + BlendModeNode, ColorAdjustmentNode, ColorSpaceNode, FrontFacingNode, NormalMapNode, + PosterizeNode, ToneMappingNode, + ViewportNode, // math MathNode, @@ -293,14 +328,17 @@ export { // utils ArrayElementNode, ConvertNode, + EquirectUVNode, JoinNode, MatcapUVNode, MaxMipLevelNode, OscNode, + RemapNode, RotateUVNode, SplitNode, SpriteSheetUVNode, TimerNode, + TriplanarTexturesNode, // procedural CheckerNode, @@ -312,5 +350,9 @@ export { // loaders NodeLoader, NodeObjectLoader, - NodeMaterialLoader + NodeMaterialLoader, + + // parsers + WGSLNodeParser, + GLSLNodeParser }; diff --git a/examples/jsm/nodes/accessors/BitangentNode.js b/examples/jsm/nodes/accessors/BitangentNode.js new file mode 100644 index 00000000000000..97bef6ce820b1d --- /dev/null +++ b/examples/jsm/nodes/accessors/BitangentNode.js @@ -0,0 +1,62 @@ +import Node from '../core/Node.js'; +import VaryingNode from '../core/VaryingNode.js'; +import OperatorNode from '../math/OperatorNode.js'; +import MathNode from '../math/MathNode.js'; +import SplitNode from '../utils/SplitNode.js'; +import NormalNode from './NormalNode.js'; +import TangentNode from './TangentNode.js'; + +class BitangentNode extends Node { + + static GEOMETRY = 'geometry'; + static LOCAL = 'local'; + static VIEW = 'view'; + static WORLD = 'world'; + + constructor( scope = BitangentNode.LOCAL ) { + + super( 'vec3' ); + + this.scope = scope; + + } + + getHash( /*builder*/ ) { + + return `bitangent-${this.scope}`; + + } + + generate( builder ) { + + const scope = this.scope; + + const crossNormalTangent = new MathNode( MathNode.CROSS, new NormalNode( scope ), new TangentNode( scope ) ); + const tangentW = new SplitNode( new TangentNode( TangentNode.GEOMETRY ), 'w' ); + const vertexNode = new SplitNode( new OperatorNode( '*', crossNormalTangent, tangentW ), 'xyz' ); + + const outputNode = new MathNode( MathNode.NORMALIZE, new VaryingNode( vertexNode ) ); + + return outputNode.build( builder, this.getNodeType( builder ) ); + + } + + serialize( data ) { + + super.serialize( data ); + + data.scope = this.scope; + + } + + deserialize( data ) { + + super.deserialize( data ); + + this.scope = data.scope; + + } + +} + +export default BitangentNode; diff --git a/examples/jsm/nodes/accessors/NormalNode.js b/examples/jsm/nodes/accessors/NormalNode.js index 6c5d32dfe8cee8..6c367ebc748f80 100644 --- a/examples/jsm/nodes/accessors/NormalNode.js +++ b/examples/jsm/nodes/accessors/NormalNode.js @@ -10,8 +10,8 @@ class NormalNode extends Node { static GEOMETRY = 'geometry'; static LOCAL = 'local'; - static WORLD = 'world'; static VIEW = 'view'; + static WORLD = 'world'; constructor( scope = NormalNode.LOCAL ) { @@ -43,18 +43,18 @@ class NormalNode extends Node { } else if ( scope === NormalNode.VIEW ) { - const vertexNormalNode = new OperatorNode( '*', new ModelNode( ModelNode.NORMAL_MATRIX ), new NormalNode( NormalNode.LOCAL ) ); - outputNode = new MathNode( MathNode.NORMALIZE, new VaryingNode( vertexNormalNode ) ); + const vertexNode = new OperatorNode( '*', new ModelNode( ModelNode.NORMAL_MATRIX ), new NormalNode( NormalNode.LOCAL ) ); + outputNode = new MathNode( MathNode.NORMALIZE, new VaryingNode( vertexNode ) ); } else if ( scope === NormalNode.WORLD ) { // To use INVERSE_TRANSFORM_DIRECTION only inverse the param order like this: MathNode( ..., Vector, Matrix ); - const vertexNormalNode = new MathNode( MathNode.TRANSFORM_DIRECTION, new NormalNode( NormalNode.VIEW ), new CameraNode( CameraNode.VIEW_MATRIX ) ); - outputNode = new MathNode( MathNode.NORMALIZE, new VaryingNode( vertexNormalNode ) ); + const vertexNode = new MathNode( MathNode.TRANSFORM_DIRECTION, new NormalNode( NormalNode.VIEW ), new CameraNode( CameraNode.VIEW_MATRIX ) ); + outputNode = new MathNode( MathNode.NORMALIZE, new VaryingNode( vertexNode ) ); } - return outputNode.build( builder ); + return outputNode.build( builder, this.getNodeType( builder ) ); } diff --git a/examples/jsm/nodes/accessors/Object3DNode.js b/examples/jsm/nodes/accessors/Object3DNode.js index fa2aa7e50c9fca..6a25a659af863d 100644 --- a/examples/jsm/nodes/accessors/Object3DNode.js +++ b/examples/jsm/nodes/accessors/Object3DNode.js @@ -18,7 +18,7 @@ class Object3DNode extends Node { this.scope = scope; this.object3d = object3d; - this.updateType = NodeUpdateType.Object; + this.updateType = NodeUpdateType.OBJECT; this._uniformNode = new UniformNode( null ); diff --git a/examples/jsm/nodes/accessors/PositionNode.js b/examples/jsm/nodes/accessors/PositionNode.js index 4b78416251acb6..b070ee3609ae08 100644 --- a/examples/jsm/nodes/accessors/PositionNode.js +++ b/examples/jsm/nodes/accessors/PositionNode.js @@ -10,6 +10,7 @@ class PositionNode extends Node { static GEOMETRY = 'geometry'; static LOCAL = 'local'; static WORLD = 'world'; + static WORLD_DIRECTION = 'worldDirection'; static VIEW = 'view'; static VIEW_DIRECTION = 'viewDirection'; @@ -56,6 +57,11 @@ class PositionNode extends Node { const vertexPositionNode = new MathNode( MathNode.NEGATE, new PositionNode( PositionNode.VIEW ) ); outputNode = new MathNode( MathNode.NORMALIZE, new VaryingNode( vertexPositionNode ) ); + } else if ( scope === PositionNode.WORLD_DIRECTION ) { + + const vertexPositionNode = new MathNode( MathNode.NEGATE, new PositionNode( PositionNode.WORLD ) ); + outputNode = new MathNode( MathNode.NORMALIZE, new VaryingNode( vertexPositionNode ) ); + } return outputNode.build( builder, this.getNodeType( builder ) ); diff --git a/examples/jsm/nodes/accessors/ReferenceNode.js b/examples/jsm/nodes/accessors/ReferenceNode.js index 8ac52c7cc3dfc1..773683a65ce29e 100644 --- a/examples/jsm/nodes/accessors/ReferenceNode.js +++ b/examples/jsm/nodes/accessors/ReferenceNode.js @@ -16,7 +16,7 @@ class ReferenceNode extends Node { this.node = null; - this.updateType = NodeUpdateType.Object; + this.updateType = NodeUpdateType.OBJECT; this.setNodeType( uniformType ); diff --git a/examples/jsm/nodes/accessors/ReflectVectorNode.js b/examples/jsm/nodes/accessors/ReflectVectorNode.js index e13efba225968c..c38814e1d5f1bc 100644 --- a/examples/jsm/nodes/accessors/ReflectVectorNode.js +++ b/examples/jsm/nodes/accessors/ReflectVectorNode.js @@ -14,7 +14,7 @@ class ReflectVectorNode extends Node { getHash( /*builder*/ ) { - return `reflectVector`; + return 'reflectVector'; } diff --git a/examples/jsm/nodes/accessors/SkinningNode.js b/examples/jsm/nodes/accessors/SkinningNode.js index dd471df1b69b36..d8a5725cfbc1ac 100644 --- a/examples/jsm/nodes/accessors/SkinningNode.js +++ b/examples/jsm/nodes/accessors/SkinningNode.js @@ -7,6 +7,7 @@ import { uniform, positionLocal, normalLocal, + tangentLocal, assign, element, add, @@ -56,6 +57,12 @@ const Skinning = new ShaderNode( ( inputs, builder ) => { assign( positionLocal, skinPosition ).build( builder ); assign( normalLocal, skinNormal ).build( builder ); + if ( builder.hasGeometryAttribute( 'tangent' ) ) { + + assign( tangentLocal, skinNormal ).build( builder ); + + } + } ); class SkinningNode extends Node { @@ -66,7 +73,7 @@ class SkinningNode extends Node { this.skinnedMesh = skinnedMesh; - this.updateType = NodeUpdateType.Object; + this.updateType = NodeUpdateType.OBJECT; // diff --git a/examples/jsm/nodes/accessors/TangentNode.js b/examples/jsm/nodes/accessors/TangentNode.js new file mode 100644 index 00000000000000..bea24eb1bb60bd --- /dev/null +++ b/examples/jsm/nodes/accessors/TangentNode.js @@ -0,0 +1,95 @@ +import Node from '../core/Node.js'; +import AttributeNode from '../core/AttributeNode.js'; +import VaryingNode from '../core/VaryingNode.js'; +import ModelNode from '../accessors/ModelNode.js'; +import CameraNode from '../accessors/CameraNode.js'; +import OperatorNode from '../math/OperatorNode.js'; +import MathNode from '../math/MathNode.js'; +import SplitNode from '../utils/SplitNode.js'; + +class TangentNode extends Node { + + static GEOMETRY = 'geometry'; + static LOCAL = 'local'; + static VIEW = 'view'; + static WORLD = 'world'; + + constructor( scope = TangentNode.LOCAL ) { + + super(); + + this.scope = scope; + + } + + getHash( /*builder*/ ) { + + return `tangent-${this.scope}`; + + } + + getNodeType() { + + const scope = this.scope; + + if ( scope === TangentNode.GEOMETRY ) { + + return 'vec4'; + + } + + return 'vec3'; + + } + + + generate( builder ) { + + const scope = this.scope; + + let outputNode = null; + + if ( scope === TangentNode.GEOMETRY ) { + + outputNode = new AttributeNode( 'tangent', 'vec4' ); + + } else if ( scope === TangentNode.LOCAL ) { + + outputNode = new VaryingNode( new SplitNode( new TangentNode( TangentNode.GEOMETRY ), 'xyz' ) ); + + } else if ( scope === TangentNode.VIEW ) { + + const vertexNode = new SplitNode( new OperatorNode( '*', new ModelNode( ModelNode.VIEW_MATRIX ), new TangentNode( TangentNode.LOCAL ) ), 'xyz' ); + + outputNode = new MathNode( MathNode.NORMALIZE, new VaryingNode( vertexNode ) ); + + } else if ( scope === TangentNode.WORLD ) { + + const vertexNode = new MathNode( MathNode.TRANSFORM_DIRECTION, new TangentNode( TangentNode.VIEW ), new CameraNode( CameraNode.VIEW_MATRIX ) ); + outputNode = new MathNode( MathNode.NORMALIZE, new VaryingNode( vertexNode ) ); + + } + + return outputNode.build( builder, this.getNodeType( builder ) ); + + } + + serialize( data ) { + + super.serialize( data ); + + data.scope = this.scope; + + } + + deserialize( data ) { + + super.deserialize( data ); + + this.scope = data.scope; + + } + +} + +export default TangentNode; diff --git a/examples/jsm/nodes/core/AttributeNode.js b/examples/jsm/nodes/core/AttributeNode.js index 11d75d91f837f0..d7a06ec505c776 100644 --- a/examples/jsm/nodes/core/AttributeNode.js +++ b/examples/jsm/nodes/core/AttributeNode.js @@ -19,14 +19,23 @@ class AttributeNode extends Node { getNodeType( builder ) { + const attributeName = this.getAttributeName( builder ); + let nodeType = super.getNodeType( builder ); if ( nodeType === null ) { - const attributeName = this.getAttributeName( builder ); - const attribute = builder.geometry.getAttribute( attributeName ); + if ( builder.hasGeometryAttribute( attributeName ) ) { + + const attribute = builder.geometry.getAttribute( attributeName ); + + nodeType = builder.getTypeFromLength( attribute.itemSize ); - nodeType = builder.getTypeFromLength( attribute.itemSize ); + } else { + + nodeType = 'float'; + + } } @@ -50,17 +59,31 @@ class AttributeNode extends Node { generate( builder ) { - const attribute = builder.getAttribute( this.getAttributeName( builder ), this.getNodeType( builder ) ); + const attributeName = this.getAttributeName( builder ); + const nodeType = this.getNodeType( builder ); + const geometryAttribute = builder.hasGeometryAttribute( attributeName ); + + if ( geometryAttribute === true ) { + + const nodeAttribute = builder.getAttribute( attributeName, nodeType ); + + if ( builder.isShaderStage( 'vertex' ) ) { + + return nodeAttribute.name; + + } else { + + const nodeVarying = new VaryingNode( this ); - if ( builder.isShaderStage( 'vertex' ) ) { + return nodeVarying.build( builder, nodeAttribute.type ); - return attribute.name; + } } else { - const nodeVarying = new VaryingNode( this ); + console.warn( `Attribute "${ attributeName }" not found.` ); - return nodeVarying.build( builder, attribute.type ); + return builder.getConst( nodeType ); } diff --git a/examples/jsm/nodes/core/CodeNode.js b/examples/jsm/nodes/core/CodeNode.js index 0dfb8938463913..bb571a76ac7526 100644 --- a/examples/jsm/nodes/core/CodeNode.js +++ b/examples/jsm/nodes/core/CodeNode.js @@ -2,15 +2,15 @@ import Node from './Node.js'; class CodeNode extends Node { - constructor( code = '', nodeType = 'code' ) { + constructor( code = '', includes = [] ) { - super( nodeType ); + super( 'code' ); this.isCodeNode = true; this.code = code; - this._includes = []; + this._includes = includes; } diff --git a/examples/jsm/nodes/core/FunctionCallNode.js b/examples/jsm/nodes/core/FunctionCallNode.js index e5609168ad7e8d..1d257f9d4b4e89 100644 --- a/examples/jsm/nodes/core/FunctionCallNode.js +++ b/examples/jsm/nodes/core/FunctionCallNode.js @@ -40,17 +40,32 @@ class FunctionCallNode extends TempNode { const inputs = functionNode.getInputs( builder ); const parameters = this.parameters; - for ( const inputNode of inputs ) { + if ( Array.isArray( parameters ) ) { - const node = parameters[ inputNode.name ]; + for ( let i = 0; i < parameters.length; i ++ ) { - if ( node !== undefined ) { + const inputNode = inputs[ i ]; + const node = parameters[ i ]; params.push( node.build( builder, inputNode.type ) ); - } else { + } + + } else { + + for ( const inputNode of inputs ) { + + const node = parameters[ inputNode.name ]; + + if ( node !== undefined ) { + + params.push( node.build( builder, inputNode.type ) ); + + } else { + + throw new Error( `FunctionCallNode: Input '${inputNode.name}' not found in FunctionNode.` ); - throw new Error( `FunctionCallNode: Input '${inputNode.name}' not found in FunctionNode.` ); + } } diff --git a/examples/jsm/nodes/core/FunctionNode.js b/examples/jsm/nodes/core/FunctionNode.js index 175835bf1315c0..a7806ad88a8471 100644 --- a/examples/jsm/nodes/core/FunctionNode.js +++ b/examples/jsm/nodes/core/FunctionNode.js @@ -3,9 +3,9 @@ import FunctionCallNode from './FunctionCallNode.js'; class FunctionNode extends CodeNode { - constructor( code = '' ) { + constructor( code = '', includes = [] ) { - super( code ); + super( code, includes ); this.keywords = {}; diff --git a/examples/jsm/nodes/core/Node.js b/examples/jsm/nodes/core/Node.js index d1980828bf1e3c..9fda8a525bd99f 100644 --- a/examples/jsm/nodes/core/Node.js +++ b/examples/jsm/nodes/core/Node.js @@ -1,5 +1,5 @@ import { NodeUpdateType } from './constants.js'; -import { getNodesKeys } from './NodeUtils.js'; +import { getNodesKeys, getCacheKey } from './NodeUtils.js'; import { MathUtils } from 'three'; let _nodeId = 0; @@ -12,7 +12,7 @@ class Node { this.nodeType = nodeType; - this.updateType = NodeUpdateType.None; + this.updateType = NodeUpdateType.NONE; this.uuid = MathUtils.generateUUID(); @@ -58,6 +58,12 @@ class Node { } + getCacheKey() { + + return getCacheKey( this ); + + } + getHash( /*builder*/ ) { return this.uuid; diff --git a/examples/jsm/nodes/core/NodeBuilder.js b/examples/jsm/nodes/core/NodeBuilder.js index 9980ce2c4c6db5..f7aade71d40ace 100644 --- a/examples/jsm/nodes/core/NodeBuilder.js +++ b/examples/jsm/nodes/core/NodeBuilder.js @@ -6,14 +6,13 @@ import NodeCode from './NodeCode.js'; import NodeKeywords from './NodeKeywords.js'; import { NodeUpdateType } from './constants.js'; -import { REVISION, LinearEncoding } from 'three'; +import { REVISION, LinearEncoding, Color, Vector2, Vector3, Vector4 } from 'three'; export const defaultShaderStages = [ 'fragment', 'vertex' ]; export const shaderStages = [ ...defaultShaderStages, 'compute' ]; export const vector = [ 'x', 'y', 'z', 'w' ]; const typeFromLength = new Map(); -typeFromLength.set( 1, 'float' ); typeFromLength.set( 2, 'vec2' ); typeFromLength.set( 3, 'vec3' ); typeFromLength.set( 4, 'vec4' ); @@ -117,7 +116,7 @@ class NodeBuilder { const updateType = node.getUpdateType( this ); - if ( updateType !== NodeUpdateType.None ) { + if ( updateType !== NodeUpdateType.NONE ) { this.updateNodes.push( node ); @@ -181,6 +180,18 @@ class NodeBuilder { } + getFragCoord() { + + console.warn( 'Abstract function.' ); + + } + + isFlipY() { + + return false; + + } + getTexture( /* textureProperty, uvSnippet */ ) { console.warn( 'Abstract function.' ); @@ -206,7 +217,18 @@ class NodeBuilder { } // @TODO: rename to .generateConst() - getConst( type, value ) { + getConst( type, value = null ) { + + if ( value === null ) { + + if ( type === 'float' || type === 'int' || type === 'uint' ) value = 0; + else if ( type === 'bool' ) value = false; + else if ( type === 'color' ) value = new Color(); + else if ( type === 'vec2' ) value = new Vector2(); + else if ( type === 'vec3' ) value = new Vector3(); + else if ( type === 'vec4' ) value = new Vector4(); + + } if ( type === 'float' ) return toFloat( value ); if ( type === 'int' ) return `${ Math.round( value ) }`; @@ -254,6 +276,12 @@ class NodeBuilder { } + hasGeometryAttribute( name ) { + + return this.geometry?.getAttribute( name ) !== undefined; + + } + getAttribute( name, type ) { const attributes = this.attributes; @@ -336,6 +364,8 @@ class NodeBuilder { type = this.getVectorType( type ); + if ( type === 'float' || type === 'bool' || type === 'int' || type === 'uint' ) return type; + const componentType = /(b|i|u|)(vec|mat)([2-4])/.exec( type ); if ( componentType === null ) return null; @@ -357,9 +387,12 @@ class NodeBuilder { } - getTypeFromLength( length ) { + getTypeFromLength( length, componentType = 'float' ) { - return typeFromLength.get( length ); + if ( length === 1 ) return componentType; + const baseType = typeFromLength.get( length ); + const prefix = componentType === 'float' ? '' : componentType[ 0 ]; + return prefix + baseType; } @@ -383,6 +416,22 @@ class NodeBuilder { } + changeComponentType( type, newComponentType ) { + + return this.getTypeFromLength( this.getTypeLength( type ), newComponentType ); + + } + + getIntegerType( type ) { + + const componentType = this.getComponentType( type ); + + if ( componentType === 'int' || componentType === 'uint' ) return type; + + return this.changeComponentType( type, 'int' ); + + } + getDataFromNode( node, shaderStage = this.shaderStage ) { let nodeData = this.nodesData.get( node ); diff --git a/examples/jsm/nodes/core/NodeFrame.js b/examples/jsm/nodes/core/NodeFrame.js index 9287417e88bf2a..1ab8f5d09f4818 100644 --- a/examples/jsm/nodes/core/NodeFrame.js +++ b/examples/jsm/nodes/core/NodeFrame.js @@ -22,7 +22,7 @@ class NodeFrame { updateNode( node ) { - if ( node.updateType === NodeUpdateType.Frame ) { + if ( node.updateType === NodeUpdateType.FRAME ) { if ( this.updateMap.get( node ) !== this.frameId ) { @@ -32,7 +32,7 @@ class NodeFrame { } - } else if ( node.updateType === NodeUpdateType.Object ) { + } else if ( node.updateType === NodeUpdateType.OBJECT ) { node.update( this ); diff --git a/examples/jsm/nodes/core/NodeUtils.js b/examples/jsm/nodes/core/NodeUtils.js index 42610b7487ce73..bb32e45ac706d9 100644 --- a/examples/jsm/nodes/core/NodeUtils.js +++ b/examples/jsm/nodes/core/NodeUtils.js @@ -1,5 +1,27 @@ import { Color, Matrix3, Matrix4, Vector2, Vector3, Vector4 } from 'three'; +export const getCacheKey = ( object ) => { + + let cacheKey = '{'; + + if ( object.isNode === true ) { + + cacheKey += `uuid:"${ object.uuid }",`; + + } + + for ( const property of getNodesKeys( object ) ) { + + cacheKey += `${ property }:${ object[ property ].getCacheKey() },`; + + } + + cacheKey += '}'; + + return cacheKey; + +}; + export const getNodesKeys = ( object ) => { const props = []; diff --git a/examples/jsm/nodes/core/NodeVarying.js b/examples/jsm/nodes/core/NodeVarying.js index a509ac81f6da38..0a71413bf9969f 100644 --- a/examples/jsm/nodes/core/NodeVarying.js +++ b/examples/jsm/nodes/core/NodeVarying.js @@ -1,11 +1,14 @@ -class NodeVarying { +import NodeVar from './NodeVar.js'; + +class NodeVarying extends NodeVar { constructor( name, type ) { - this.isNodeVarying = true; + super( name, type ); - this.name = name; - this.type = type; + this.needsInterpolation = false; + + this.isNodeVarying = true; } diff --git a/examples/jsm/nodes/core/VaryingNode.js b/examples/jsm/nodes/core/VaryingNode.js index cd583e7e200b55..54714055c2b2d1 100644 --- a/examples/jsm/nodes/core/VaryingNode.js +++ b/examples/jsm/nodes/core/VaryingNode.js @@ -28,22 +28,24 @@ class VaryingNode extends Node { generate( builder ) { + const { name, node } = this; const type = this.getNodeType( builder ); - const node = this.node; - const name = this.name; const nodeVarying = builder.getVaryingFromNode( this, type ); + // this property can be used to check if the varying can be optimized for a var + nodeVarying.needsInterpolation ||= builder.shaderStage === 'fragment'; + if ( name !== null ) { nodeVarying.name = name; } - const propertyName = builder.getPropertyName( nodeVarying, NodeShaderStage.Vertex ); + const propertyName = builder.getPropertyName( nodeVarying, NodeShaderStage.VERTEX ); // force node run in vertex stage - builder.flowNodeFromShaderStage( NodeShaderStage.Vertex, node, type, propertyName ); + builder.flowNodeFromShaderStage( NodeShaderStage.VERTEX, node, type, propertyName ); return builder.getPropertyName( nodeVarying ); diff --git a/examples/jsm/nodes/core/constants.js b/examples/jsm/nodes/core/constants.js index 8becb0f0e9d619..454dca04621a37 100644 --- a/examples/jsm/nodes/core/constants.js +++ b/examples/jsm/nodes/core/constants.js @@ -1,21 +1,21 @@ export const NodeShaderStage = { - Vertex: 'vertex', - Fragment: 'fragment' + VERTEX: 'vertex', + FRAGMENT: 'fragment' }; export const NodeUpdateType = { - None: 'none', - Frame: 'frame', - Object: 'object' + NONE: 'none', + FRAME: 'frame', + OBJECT: 'object' }; export const NodeType = { - Boolean: 'bool', - Integer: 'int', - Float: 'float', - Vector2: 'vec2', - Vector3: 'vec3', - Vector4: 'vec4', - Matrix3: 'mat3', - Matrix4: 'mat4' + BOOLEAN: 'bool', + INTEGER: 'int', + FLOAT: 'float', + VECTOR2: 'vec2', + VECTOR3: 'vec3', + VECTOR4: 'vec4', + MATRIX3: 'mat3', + MATRIX4: 'mat4' }; diff --git a/examples/jsm/nodes/display/BlendModeNode.js b/examples/jsm/nodes/display/BlendModeNode.js new file mode 100644 index 00000000000000..d2d3b30cec3ad2 --- /dev/null +++ b/examples/jsm/nodes/display/BlendModeNode.js @@ -0,0 +1,85 @@ +import TempNode from '../core/Node.js'; +import { ShaderNode, EPSILON, vec3, sub, mul, div, cond, lessThan, equal, max } from '../shadernode/ShaderNodeBaseElements.js'; + +export const BurnNode = new ShaderNode( ( { base, blend } ) => { + + const fn = ( c ) => cond( lessThan( blend[ c ], EPSILON ), blend[ c ], max( sub( 1.0, div( sub( 1.0, base[ c ] ), blend[ c ] ) ), 0 ) ); + + return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) ); + +} ); + +export const DodgeNode = new ShaderNode( ( { base, blend } ) => { + + const fn = ( c ) => cond( equal( blend[ c ], 1.0 ), blend[ c ], max( div( base[ c ], sub( 1.0, blend[ c ] ) ), 0 ) ); + + return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) ); + +} ); + +export const ScreenNode = new ShaderNode( ( { base, blend } ) => { + + const fn = ( c ) => sub( 1.0, mul( sub( 1.0, base[ c ] ), sub( 1.0, blend[ c ] ) ) ); + + return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) ); + +} ); + +export const OverlayNode = new ShaderNode( ( { base, blend } ) => { + + const fn = ( c ) => cond( lessThan( base[ c ], 0.5 ), mul( 2.0, base[ c ], blend[ c ] ), sub( 1.0, mul( sub( 1.0, base[ c ] ), sub( 1.0, blend[ c ] ) ) ) ); + + return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) ); + +} ); + +class BlendModeNode extends TempNode { + + static BURN = 'burn'; + static DODGE = 'dodge'; + static SCREEN = 'screen'; + static OVERLAY = 'overlay'; + + constructor( blendMode, baseNode, blendNode ) { + + super(); + + this.blendMode = blendMode; + + this.baseNode = baseNode; + this.blendNode = blendNode; + + } + + construct() { + + const { blendMode, baseNode, blendNode } = this; + const params = { base: baseNode, blend: blendNode }; + + let outputNode = null; + + if ( blendMode === BlendModeNode.BURN ) { + + outputNode = BurnNode.call( params ); + + } else if ( blendMode === BlendModeNode.DODGE ) { + + outputNode = DodgeNode.call( params ); + + } else if ( blendMode === BlendModeNode.SCREEN ) { + + outputNode = ScreenNode.call( params ); + + } else if ( blendMode === BlendModeNode.OVERLAY ) { + + outputNode = OverlayNode.call( params ); + + } + + return outputNode; + + } + +} + +export default BlendModeNode; diff --git a/examples/jsm/nodes/display/ColorAdjustmentNode.js b/examples/jsm/nodes/display/ColorAdjustmentNode.js index 47b483e83ab06b..1f3e9f20f370d6 100644 --- a/examples/jsm/nodes/display/ColorAdjustmentNode.js +++ b/examples/jsm/nodes/display/ColorAdjustmentNode.js @@ -1,19 +1,9 @@ import TempNode from '../core/TempNode.js'; -import { ShaderNode, vec3, mat3, add, sub, mul, max, div, dot, float, mix, cos, sin, atan2, sqrt } from '../shadernode/ShaderNodeBaseElements.js'; - -const luminanceNode = new ShaderNode( ( { color } ) => { - - const LUMA = vec3( 0.2125, 0.7154, 0.0721 ); - - return dot( color, LUMA ); - -} ); +import { ShaderNode, vec3, mat3, add, sub, mul, max, div, float, mix, cos, sin, atan2, sqrt, luminance } from '../shadernode/ShaderNodeBaseElements.js'; const saturationNode = new ShaderNode( ( { color, adjustment } ) => { - const intensityNode = luminanceNode.call( { color } ); - - return mix( intensityNode, color, adjustment ); + return mix( luminance( color ), color, adjustment ); } ); @@ -22,7 +12,7 @@ const vibranceNode = new ShaderNode( ( { color, adjustment } ) => { const average = div( add( color.r, color.g, color.b ), 3.0 ); const mx = max( color.r, max( color.g, color.b ) ); - const amt = mul( sub( mx, average ), mul( -3.0, adjustment ) ); + const amt = mul( sub( mx, average ), mul( - 3.0, adjustment ) ); return mix( color.rgb, vec3( mx ), amt ); @@ -30,8 +20,8 @@ const vibranceNode = new ShaderNode( ( { color, adjustment } ) => { const hueNode = new ShaderNode( ( { color, adjustment } ) => { - const RGBtoYIQ = mat3( 0.299, 0.587, 0.114, 0.595716, -0.274453, -0.321263, 0.211456, -0.522591, 0.311135 ); - const YIQtoRGB = mat3( 1.0, 0.9563, 0.6210, 1.0, -0.2721, -0.6474, 1.0, -1.107, 1.7046 ); + const RGBtoYIQ = mat3( 0.299, 0.587, 0.114, 0.595716, - 0.274453, - 0.321263, 0.211456, - 0.522591, 0.311135 ); + const YIQtoRGB = mat3( 1.0, 0.9563, 0.6210, 1.0, - 0.2721, - 0.6474, 1.0, - 1.107, 1.7046 ); const yiq = mul( RGBtoYIQ, color ); diff --git a/examples/jsm/nodes/display/NormalMapNode.js b/examples/jsm/nodes/display/NormalMapNode.js index 12fab9d8e0d500..69cb7f6198e084 100644 --- a/examples/jsm/nodes/display/NormalMapNode.js +++ b/examples/jsm/nodes/display/NormalMapNode.js @@ -1,6 +1,5 @@ import TempNode from '../core/TempNode.js'; -import ModelNode from '../accessors/ModelNode.js'; -import { ShaderNode, positionView, normalView, uv, vec3, add, sub, mul, dFdx, dFdy, cross, max, dot, normalize, inversesqrt, faceDirection } from '../shadernode/ShaderNodeBaseElements.js'; +import { ShaderNode, positionView, normalView, uv, vec3, add, sub, mul, dFdx, dFdy, cross, max, dot, normalize, inversesqrt, faceDirection, modelNormalMatrix, TBNViewMatrix } from '../shadernode/ShaderNodeBaseElements.js'; import { TangentSpaceNormalMap, ObjectSpaceNormalMap } from 'three'; @@ -44,7 +43,7 @@ class NormalMapNode extends TempNode { } - construct() { + construct( builder ) { const { normalMapType, scaleNode } = this; @@ -62,18 +61,26 @@ class NormalMapNode extends TempNode { if ( normalMapType === ObjectSpaceNormalMap ) { - const vertexNormalNode = mul( new ModelNode( ModelNode.NORMAL_MATRIX ), normalMap ); - - outputNode = normalize( vertexNormalNode ); + outputNode = normalize( mul( modelNormalMatrix, normalMap ) ); } else if ( normalMapType === TangentSpaceNormalMap ) { - outputNode = perturbNormal2ArbNode.call( { - eye_pos: positionView, - surf_norm: normalView, - mapN: normalMap, - uv: uv() - } ); + const tangent = builder.hasGeometryAttribute( 'tangent' ); + + if ( tangent === true ) { + + outputNode = normalize( mul( TBNViewMatrix, normalMap ) ); + + } else { + + outputNode = perturbNormal2ArbNode.call( { + eye_pos: positionView, + surf_norm: normalView, + mapN: normalMap, + uv: uv() + } ); + + } } diff --git a/examples/jsm/nodes/display/PosterizeNode.js b/examples/jsm/nodes/display/PosterizeNode.js new file mode 100644 index 00000000000000..6c73e0d96d019c --- /dev/null +++ b/examples/jsm/nodes/display/PosterizeNode.js @@ -0,0 +1,25 @@ +import TempNode from '../core/Node.js'; +import { mul, floor, reciprocal } from '../shadernode/ShaderNodeBaseElements.js'; + +class PosterizeNode extends TempNode { + + constructor( sourceNode, stepsNode ) { + + super(); + + this.sourceNode = sourceNode; + this.stepsNode = stepsNode; + + } + + construct() { + + const { sourceNode, stepsNode } = this; + + return mul( floor( mul( sourceNode, stepsNode ) ), reciprocal( stepsNode ) ); + + } + +} + +export default PosterizeNode; diff --git a/examples/jsm/nodes/display/ViewportNode.js b/examples/jsm/nodes/display/ViewportNode.js new file mode 100644 index 00000000000000..e8759a8a18723e --- /dev/null +++ b/examples/jsm/nodes/display/ViewportNode.js @@ -0,0 +1,106 @@ +import Node from '../core/Node.js'; +import { uniform, div, vec2, invert } from '../shadernode/ShaderNodeBaseElements.js'; +import { Vector2 } from 'three'; +import { NodeUpdateType } from '../core/constants.js'; + +let resolution; + +class ViewportNode extends Node { + + static COORDINATE = 'coordinate'; + static RESOLUTION = 'resolution'; + static TOP_LEFT = 'topLeft'; + static BOTTOM_LEFT = 'bottomLeft'; + static TOP_RIGHT = 'topRight'; + static BOTTOM_RIGHT = 'bottomRight'; + + constructor( scope ) { + + super(); + + this.scope = scope; + + this.isViewportNode = true; + + } + + getNodeType() { + + return this.scope === ViewportNode.COORDINATE ? 'vec4' : 'vec2'; + + } + + getUpdateType() { + + let updateType = NodeUpdateType.NONE; + + if ( this.scope === ViewportNode.RESOLUTION ) { + + updateType = NodeUpdateType.FRAME; + + } + + this.updateType = updateType; + + return updateType; + + } + + update( { renderer } ) { + + renderer.getSize( resolution ); + + } + + construct( builder ) { + + const scope = this.scope; + + if ( scope === ViewportNode.COORDINATE ) return; + + let output = null; + + if ( scope === ViewportNode.RESOLUTION ) { + + resolution ||= new Vector2(); + + output = uniform( resolution ); + + } else { + + const coordinateNode = vec2( new ViewportNode( ViewportNode.COORDINATE ) ); + const resolutionNode = new ViewportNode( ViewportNode.RESOLUTION ); + + output = div( coordinateNode, resolutionNode ); + + let outX = output.x; + let outY = output.y; + + if ( /top/i.test( scope ) && builder.isFlipY() ) outY = invert( outY ); + else if ( /bottom/i.test( scope ) && builder.isFlipY() === false ) outY = invert( outY ); + + if ( /right/i.test( scope ) ) outX = invert( outX ); + + output = vec2( outX, outY ); + + } + + return output; + + } + + generate( builder ) { + + if ( this.scope === ViewportNode.COORDINATE ) { + + return builder.getFragCoord(); + + } + + return super.generate( builder ); + + } + +} + +export default ViewportNode; diff --git a/examples/jsm/nodes/functions/BSDF/BRDF_GGX.js b/examples/jsm/nodes/functions/BSDF/BRDF_GGX.js index 056f657d130ae2..145752933bdddd 100644 --- a/examples/jsm/nodes/functions/BSDF/BRDF_GGX.js +++ b/examples/jsm/nodes/functions/BSDF/BRDF_GGX.js @@ -2,7 +2,7 @@ import F_Schlick from './F_Schlick.js'; import V_GGX_SmithCorrelated from './V_GGX_SmithCorrelated.js'; import D_GGX from './D_GGX.js'; import { - ShaderNode, dotNV, add, mul, saturate, dot, pow2, normalize, + ShaderNode, dotNV, add, mul, clamp, dot, pow2, normalize, transformedNormalView, positionViewDirection } from '../../shadernode/ShaderNodeBaseElements.js'; @@ -15,10 +15,10 @@ const BRDF_GGX = new ShaderNode( ( inputs ) => { const halfDir = normalize( add( lightDirection, positionViewDirection ) ); - const dotNL = saturate( dot( transformedNormalView, lightDirection ) ); - //const dotNV = saturate( dot( transformedNormalView, positionViewDirection ) ); - const dotNH = saturate( dot( transformedNormalView, halfDir ) ); - const dotVH = saturate( dot( positionViewDirection, halfDir ) ); + const dotNL = clamp( dot( transformedNormalView, lightDirection ) ); + //const dotNV = clamp( dot( transformedNormalView, positionViewDirection ) ); + const dotNH = clamp( dot( transformedNormalView, halfDir ) ); + const dotVH = clamp( dot( positionViewDirection, halfDir ) ); const F = F_Schlick.call( { f0, f90, dotVH } ); diff --git a/examples/jsm/nodes/functions/PhysicalLightingModel.js b/examples/jsm/nodes/functions/PhysicalLightingModel.js index 634042a46249f0..f140ccfdecee63 100644 --- a/examples/jsm/nodes/functions/PhysicalLightingModel.js +++ b/examples/jsm/nodes/functions/PhysicalLightingModel.js @@ -3,7 +3,7 @@ import BRDF_GGX from './BSDF/BRDF_GGX.js'; import DFGApprox from './BSDF/DFGApprox.js'; import { ShaderNode, - vec3, mul, saturate, add, sub, dot, div, transformedNormalView, + vec3, mul, clamp, add, sub, dot, div, transformedNormalView, pow, exp2, dotNV, diffuseColor, specularColor, roughness, temp } from '../shadernode/ShaderNodeElements.js'; @@ -61,7 +61,7 @@ const RE_Direct_Physical = new ShaderNode( ( inputs ) => { const { lightDirection, lightColor, reflectedLight } = inputs; - const dotNL = saturate( dot( transformedNormalView, lightDirection ) ); + const dotNL = clamp( dot( transformedNormalView, lightDirection ) ); const irradiance = mul( dotNL, lightColor ); reflectedLight.directDiffuse.add( mul( irradiance, BRDF_Lambert.call( { diffuseColor: diffuseColor.rgb } ) ) ); @@ -75,7 +75,7 @@ const RE_AmbientOcclusion_Physical = new ShaderNode( ( { ambientOcclusion, refle const aoNV = add( dotNV, ambientOcclusion ); const aoExp = exp2( sub( mul( - 16.0, roughness ), 1.0 ) ); - const aoNode = saturate( add( sub( pow( aoNV, aoExp ), 1.0 ), ambientOcclusion ) ); + const aoNode = clamp( add( sub( pow( aoNV, aoExp ), 1.0 ), ambientOcclusion ) ); reflectedLight.indirectDiffuse.mul( ambientOcclusion ); diff --git a/examples/jsm/nodes/functions/light/getDistanceAttenuation.js b/examples/jsm/nodes/functions/light/getDistanceAttenuation.js index 199c08f8af3861..b2f4034835bfee 100644 --- a/examples/jsm/nodes/functions/light/getDistanceAttenuation.js +++ b/examples/jsm/nodes/functions/light/getDistanceAttenuation.js @@ -1,5 +1,5 @@ import { - ShaderNode, div, max, sub, mul, saturate, pow, pow2, pow4, cond, greaterThan + ShaderNode, div, max, sub, mul, clamp, pow, pow2, pow4, cond, greaterThan } from '../../shadernode/ShaderNodeBaseElements.js'; const getDistanceAttenuation = new ShaderNode( ( inputs ) => { @@ -13,7 +13,7 @@ const getDistanceAttenuation = new ShaderNode( ( inputs ) => { return cond( greaterThan( cutoffDistance, 0 ), - mul( distanceFalloff, pow2( saturate( sub( 1.0, pow4( div( lightDistance, cutoffDistance ) ) ) ) ) ), + mul( distanceFalloff, pow2( clamp( sub( 1.0, pow4( div( lightDistance, cutoffDistance ) ) ) ) ) ), distanceFalloff ); diff --git a/examples/jsm/nodes/gpgpu/ComputeNode.js b/examples/jsm/nodes/gpgpu/ComputeNode.js index 012f4f517fb9d0..767a1e6c59c514 100644 --- a/examples/jsm/nodes/gpgpu/ComputeNode.js +++ b/examples/jsm/nodes/gpgpu/ComputeNode.js @@ -15,7 +15,7 @@ class ComputeNode extends Node { this.workgroupSize = workgroupSize; this.dispatchCount = 0; - this.updateType = NodeUpdateType.Object; + this.updateType = NodeUpdateType.OBJECT; this.updateDispatchCount(); diff --git a/examples/jsm/nodes/lighting/AnalyticLightNode.js b/examples/jsm/nodes/lighting/AnalyticLightNode.js index 96c46e81d80233..864934440809cb 100644 --- a/examples/jsm/nodes/lighting/AnalyticLightNode.js +++ b/examples/jsm/nodes/lighting/AnalyticLightNode.js @@ -10,7 +10,7 @@ class AnalyticLightNode extends LightingNode { super(); - this.updateType = NodeUpdateType.Object; + this.updateType = NodeUpdateType.OBJECT; this.light = light; diff --git a/examples/jsm/nodes/loaders/NodeMaterialLoader.js b/examples/jsm/nodes/loaders/NodeMaterialLoader.js index e4faf1af9d64d6..d7dbcb0a8e31a5 100644 --- a/examples/jsm/nodes/loaders/NodeMaterialLoader.js +++ b/examples/jsm/nodes/loaders/NodeMaterialLoader.js @@ -4,6 +4,7 @@ import { LineBasicNodeMaterial, MeshBasicNodeMaterial, MeshStandardNodeMaterial, + MeshPhysicalNodeMaterial, PointsNodeMaterial, SpriteNodeMaterial } from '../materials/Materials.js'; @@ -17,8 +18,9 @@ MaterialLoader.createMaterialFromType = function ( type ) { LineBasicNodeMaterial, MeshBasicNodeMaterial, MeshStandardNodeMaterial, + MeshPhysicalNodeMaterial, PointsNodeMaterial, - SpriteNodeMaterial, + SpriteNodeMaterial }; if ( materialLib[ type ] !== undefined ) { diff --git a/examples/jsm/nodes/materials/Materials.js b/examples/jsm/nodes/materials/Materials.js index 853123a6da3167..f6fd5762c6cd26 100644 --- a/examples/jsm/nodes/materials/Materials.js +++ b/examples/jsm/nodes/materials/Materials.js @@ -32,19 +32,21 @@ NodeMaterial.fromMaterial = function ( material ) { if ( materialLib[ type ] === undefined ) { - return material; // is already a node material or cannot be converted + if ( material.isNodeMaterial !== true ) { - } + throw new Error( `NodeMaterial: Material "${ material.type }" is not compatible.` ); - const nodeMaterial = new materialLib[ type ]( material ); + } - for ( const key in material ) { + return material; // is already a node material - if ( nodeMaterial[ key ] === undefined ) { + } - nodeMaterial[ key ] = material[ key ]; // currently this is needed only for material.alphaTest + const nodeMaterial = new materialLib[ type ](); - } + for ( const key in material ) { + + nodeMaterial[ key ] = material[ key ]; } diff --git a/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js b/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js index 5a7dcbc308e4c4..83c201bfb820b0 100644 --- a/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +++ b/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js @@ -19,6 +19,18 @@ export default class MeshPhysicalNodeMaterial extends MeshStandardNodeMaterial { this.sheenNode = null; this.sheenRoughnessNode = null; + this.iridescenceNode = null; + this.iridescenceIORNode = null; + this.iridescenceThicknessNode = null; + + this.specularIntensityNode = null; + this.specularColorNode = null; + + this.transmissionNode = null; + this.thicknessNode = null; + this.attenuationDistanceNode = null; + this.attenuationColorNode = null; + this.sheen = 0; this.clearcoat = 0; this.iridescence = 0; @@ -39,6 +51,18 @@ export default class MeshPhysicalNodeMaterial extends MeshStandardNodeMaterial { this.sheenNode = source.sheenNode; this.sheenRoughnessNode = source.sheenRoughnessNode; + this.iridescenceNode = source.iridescenceNode; + this.iridescenceIORNode = source.iridescenceIORNode; + this.iridescenceThicknessNode = source.iridescenceThicknessNode; + + this.specularIntensityNode = source.specularIntensityNode; + this.specularColorNode = source.specularColorNode; + + this.transmissionNode = source.transmissionNode; + this.thicknessNode = source.thicknessNode; + this.attenuationDistanceNode = source.attenuationDistanceNode; + this.attenuationColorNode = source.attenuationColorNode; + return super.copy( source ); } diff --git a/examples/jsm/nodes/materials/NodeMaterial.js b/examples/jsm/nodes/materials/NodeMaterial.js index 21b40e78caa8eb..f283d5b6e87814 100644 --- a/examples/jsm/nodes/materials/NodeMaterial.js +++ b/examples/jsm/nodes/materials/NodeMaterial.js @@ -1,9 +1,9 @@ import { Material, ShaderMaterial } from 'three'; -import { getNodesKeys } from '../core/NodeUtils.js'; +import { getNodesKeys, getCacheKey } from '../core/NodeUtils.js'; import ExpressionNode from '../core/ExpressionNode.js'; import { float, vec3, vec4, - assign, label, mul, bypass, + assign, label, mul, bypass, attribute, positionLocal, skinning, instance, modelViewProjection, lightingContext, colorSpace, materialAlphaTest, materialColor, materialOpacity } from '../shadernode/ShaderNodeElements.js'; @@ -37,7 +37,7 @@ class NodeMaterial extends ShaderMaterial { customProgramCacheKey() { - return this.uuid + '-' + this.version; + return getCacheKey( this ); } @@ -80,6 +80,14 @@ class NodeMaterial extends ShaderMaterial { let colorNode = vec4( this.colorNode || materialColor ); let opacityNode = this.opacityNode ? float( this.opacityNode ) : materialOpacity; + // VERTEX COLORS + + if ( this.vertexColors === true && builder.geometry.hasAttribute( 'color' ) ) { + + colorNode = vec4( mul( colorNode.xyz, attribute( 'color' ) ), colorNode.a ); + + } + // COLOR colorNode = builder.addFlow( 'fragment', label( colorNode, 'Color' ) ); diff --git a/examples/jsm/nodes/materialx/DISCLAIMER.md b/examples/jsm/nodes/materialx/DISCLAIMER.md new file mode 100644 index 00000000000000..1d619914a4359b --- /dev/null +++ b/examples/jsm/nodes/materialx/DISCLAIMER.md @@ -0,0 +1,199 @@ +## MaterialX + +MaterialX is a project of the +[Academy Software Foundation](https://www.aswf.io/) and relies on the ASWF +governance policies, supported by the Linux Foundation. + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +``` +------------------------------------------------------------------------- + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS +``` diff --git a/examples/jsm/nodes/materialx/MaterialXNodes.js b/examples/jsm/nodes/materialx/MaterialXNodes.js new file mode 100644 index 00000000000000..1016924d417627 --- /dev/null +++ b/examples/jsm/nodes/materialx/MaterialXNodes.js @@ -0,0 +1,59 @@ +import { + mx_perlin_noise_float, mx_perlin_noise_vec2, mx_perlin_noise_vec3, + mx_worley_noise_float as worley_noise_float, mx_worley_noise_vec2 as worley_noise_vec2, mx_worley_noise_vec3 as worley_noise_vec3, + mx_cell_noise_float as cell_noise_float, + mx_fractal_noise_float as fractal_noise_float, mx_fractal_noise_vec2 as fractal_noise_vec2, mx_fractal_noise_vec3 as fractal_noise_vec3, mx_fractal_noise_vec4 as fractal_noise_vec4 +} from './lib/mx_noise.js'; +import { mx_hsvtorgb, mx_rgbtohsv } from './lib/mx_hsv.js'; +import { mx_srgb_texture_to_lin_rec709 } from './lib/mx_transform_color.js'; +import { nodeObject, float, vec2, vec4, add, sub, mul, mix, clamp, uv, length, smoothstep, dFdx, dFdy, sign, pow, abs, convert } from '../shadernode/ShaderNodeElements.js'; + +export const mx_aastep = ( threshold, value ) => { + + threshold = float( threshold ); + value = float( value ); + + const afwidth = mul( length( vec2( dFdx( value ), dFdy( value ) ) ), 0.70710678118654757 ); + + return smoothstep( sub( threshold, afwidth ), add( threshold, afwidth ), value ); + +}; + +const _ramp = ( a, b, uv, p ) => mix( a, b, clamp( nodeObject( uv )[ p ] ) ); +export const mx_ramplr = ( valuel, valuer, texcoord = uv() ) => _ramp( valuel, valuer, texcoord, 'x' ); +export const mx_ramptb = ( valuet, valueb, texcoord = uv() ) => _ramp( valuet, valueb, texcoord, 'y' ); + +const _split = ( a, b, center, uv, p ) => mix( a, b, mx_aastep( center, nodeObject( uv )[ p ] ) ); +export const mx_splitlr = ( valuel, valuer, center, texcoord = uv() ) => _split( valuel, valuer, center, texcoord, 'x' ); +export const mx_splittb = ( valuet, valueb, center, texcoord = uv() ) => _split( valuet, valueb, center, texcoord, 'y' ); + +export const mx_transform_uv = ( uv_scale = 1, uv_offset = 0, uv_geo = uv() ) => add( mul( uv_geo, uv_scale ), uv_offset ); + +export const mx_safepower = ( in1, in2 = 1 ) => mul( sign( in1 ), pow( abs( in1 ), in2 ) ); +export const mx_contrast = ( input, amount = 1, pivot = .5 ) => add( mul( sub( input, pivot ), amount ), pivot ); + +export const mx_noise_float = ( texcoord = uv(), amplitude = 1, pivot = 0 ) => add( mul( amplitude, mx_perlin_noise_float( convert( texcoord, 'vec2|vec3' ) ) ), pivot ); +export const mx_noise_vec2 = ( texcoord = uv(), amplitude = 1, pivot = 0 ) => add( mul( amplitude, mx_perlin_noise_vec2( convert( texcoord, 'vec2|vec3' ) ) ), pivot ); +export const mx_noise_vec3 = ( texcoord = uv(), amplitude = 1, pivot = 0 ) => add( mul( amplitude, mx_perlin_noise_vec3( convert( texcoord, 'vec2|vec3' ) ) ), pivot ); +export const mx_noise_vec4 = ( texcoord = uv(), amplitude = 1, pivot = 0 ) => { + + texcoord = convert( texcoord, 'vec2|vec3' ); // overloading type + + const noise_vec4 = vec4( mx_perlin_noise_vec3( texcoord ), mx_perlin_noise_float( add( texcoord, vec2( 19, 73 ) ) ) ); + + return add( mul( amplitude, noise_vec4 ), pivot ); + +}; + +export const mx_worley_noise_float = ( texcoord = uv(), jitter = 1 ) => worley_noise_float( convert( texcoord, 'vec2|vec3' ), jitter, 1 ); +export const mx_worley_noise_vec2 = ( texcoord = uv(), jitter = 1 ) => worley_noise_vec2( convert( texcoord, 'vec2|vec3' ), jitter, 1 ); +export const mx_worley_noise_vec3 = ( texcoord = uv(), jitter = 1 ) => worley_noise_vec3( convert( texcoord, 'vec2|vec3' ), jitter, 1 ); + +export const mx_cell_noise_float = ( texcoord = uv() ) => cell_noise_float( convert( texcoord, 'vec2|vec3' ) ); + +export const mx_fractal_noise_float = ( position = uv(), octaves = 3, lacunarity = 2, diminish = .5, amplitude = 1 ) => mul( fractal_noise_float( position, octaves, lacunarity, diminish ), amplitude ); +export const mx_fractal_noise_vec2 = ( position = uv(), octaves = 3, lacunarity = 2, diminish = .5, amplitude = 1 ) => mul( fractal_noise_vec2( position, octaves, lacunarity, diminish ), amplitude ); +export const mx_fractal_noise_vec3 = ( position = uv(), octaves = 3, lacunarity = 2, diminish = .5, amplitude = 1 ) => mul( fractal_noise_vec3( position, octaves, lacunarity, diminish ), amplitude ); +export const mx_fractal_noise_vec4 = ( position = uv(), octaves = 3, lacunarity = 2, diminish = .5, amplitude = 1 ) => mul( fractal_noise_vec4( position, octaves, lacunarity, diminish ), amplitude ); + +export { mx_hsvtorgb, mx_rgbtohsv, mx_srgb_texture_to_lin_rec709 }; diff --git a/examples/jsm/nodes/materialx/lib/mx_hsv.js b/examples/jsm/nodes/materialx/lib/mx_hsv.js new file mode 100644 index 00000000000000..0190e600bb8bbc --- /dev/null +++ b/examples/jsm/nodes/materialx/lib/mx_hsv.js @@ -0,0 +1,56 @@ +import { fn } from '../../Nodes.js'; + +// Original shader code from: +// https://github.com/AcademySoftwareFoundation/MaterialX/blob/main/libraries/stdlib/genglsl/lib/mx_hsv.glsl + +export const mx_hsvtorgb = fn( `vec3 mx_hsvtorgb(vec3 hsv) +{ + // Reference for this technique: Foley & van Dam + float h = hsv.x; float s = hsv.y; float v = hsv.z; + if (s < 0.0001f) { + return vec3 (v, v, v); + } else { + h = 6.0f * (h - floor(h)); // expand to [0..6) + int hi = int(trunc(h)); + float f = h - float(hi); + float p = v * (1.0f-s); + float q = v * (1.0f-s*f); + float t = v * (1.0f-s*(1.0f-f)); + if (hi == 0) + return vec3 (v, t, p); + else if (hi == 1) + return vec3 (q, v, p); + else if (hi == 2) + return vec3 (p, v, t); + else if (hi == 3) + return vec3 (p, q, v); + else if (hi == 4) + return vec3 (t, p, v); + return vec3 (v, p, q); + } +}` ); + +export const mx_rgbtohsv = fn( `vec3 mx_rgbtohsv(vec3 c) +{ + // See Foley & van Dam + float r = c.x; float g = c.y; float b = c.z; + float mincomp = min (r, min(g, b)); + float maxcomp = max (r, max(g, b)); + float delta = maxcomp - mincomp; // chroma + float h, s, v; + v = maxcomp; + if (maxcomp > 0.0f) + s = delta / maxcomp; + else s = 0.0f; + if (s <= 0.0f) + h = 0.0f; + else { + if (r >= maxcomp) h = (g-b) / delta; + else if (g >= maxcomp) h = 2.0f + (b-r) / delta; + else h = 4.0f + (r-g) / delta; + h *= (1.0f/6.0f); + if (h < 0.0f) + h += 1.0f; + } + return vec3(h, s, v); +}` ); diff --git a/examples/jsm/nodes/materialx/lib/mx_noise.js b/examples/jsm/nodes/materialx/lib/mx_noise.js new file mode 100644 index 00000000000000..5ca3a415b15935 --- /dev/null +++ b/examples/jsm/nodes/materialx/lib/mx_noise.js @@ -0,0 +1,617 @@ +import { code, fn } from '../../Nodes.js'; + +// Original shader code from: +// https://github.com/AcademySoftwareFoundation/MaterialX/blob/main/libraries/stdlib/genglsl/lib/mx_noise.glsl + +export const mx_noise = code( `float mx_select(bool b, float t, float f) +{ + return b ? t : f; +} + +float mx_negate_if(float val, bool b) +{ + return b ? -val : val; +} + +int mx_floor(float x) +{ + return int(floor(x)); +} + +// return mx_floor as well as the fractional remainder +float mx_floorfrac(float x, out int i) +{ + i = mx_floor(x); + return x - float(i); +} + +float mx_bilerp(float v0, float v1, float v2, float v3, float s, float t) +{ + float s1 = 1.0 - s; + return (1.0 - t) * (v0*s1 + v1*s) + t * (v2*s1 + v3*s); +} +vec3 mx_bilerp(vec3 v0, vec3 v1, vec3 v2, vec3 v3, float s, float t) +{ + float s1 = 1.0 - s; + return (1.0 - t) * (v0*s1 + v1*s) + t * (v2*s1 + v3*s); +} +float mx_trilerp(float v0, float v1, float v2, float v3, float v4, float v5, float v6, float v7, float s, float t, float r) +{ + float s1 = 1.0 - s; + float t1 = 1.0 - t; + float r1 = 1.0 - r; + return (r1*(t1*(v0*s1 + v1*s) + t*(v2*s1 + v3*s)) + + r*(t1*(v4*s1 + v5*s) + t*(v6*s1 + v7*s))); +} +vec3 mx_trilerp(vec3 v0, vec3 v1, vec3 v2, vec3 v3, vec3 v4, vec3 v5, vec3 v6, vec3 v7, float s, float t, float r) +{ + float s1 = 1.0 - s; + float t1 = 1.0 - t; + float r1 = 1.0 - r; + return (r1*(t1*(v0*s1 + v1*s) + t*(v2*s1 + v3*s)) + + r*(t1*(v4*s1 + v5*s) + t*(v6*s1 + v7*s))); +} + +// 2 and 3 dimensional gradient functions - perform a dot product against a +// randomly chosen vector. Note that the gradient vector is not normalized, but +// this only affects the overal "scale" of the result, so we simply account for +// the scale by multiplying in the corresponding "perlin" function. +float mx_gradient_float(uint hash, float x, float y) +{ + // 8 possible directions (+-1,+-2) and (+-2,+-1) + uint h = hash & 7u; + float u = mx_select(h<4u, x, y); + float v = 2.0 * mx_select(h<4u, y, x); + // compute the dot product with (x,y). + return mx_negate_if(u, bool(h&1u)) + mx_negate_if(v, bool(h&2u)); +} +float mx_gradient_float(uint hash, float x, float y, float z) +{ + // use vectors pointing to the edges of the cube + uint h = hash & 15u; + float u = mx_select(h<8u, x, y); + float v = mx_select(h<4u, y, mx_select((h==12u)||(h==14u), x, z)); + return mx_negate_if(u, bool(h&1u)) + mx_negate_if(v, bool(h&2u)); +} +vec3 mx_gradient_vec3(uvec3 hash, float x, float y) +{ + return vec3(mx_gradient_float(hash.x, x, y), mx_gradient_float(hash.y, x, y), mx_gradient_float(hash.z, x, y)); +} +vec3 mx_gradient_vec3(uvec3 hash, float x, float y, float z) +{ + return vec3(mx_gradient_float(hash.x, x, y, z), mx_gradient_float(hash.y, x, y, z), mx_gradient_float(hash.z, x, y, z)); +} +// Scaling factors to normalize the result of gradients above. +// These factors were experimentally calculated to be: +// 2D: 0.6616 +// 3D: 0.9820 +float mx_gradient_scale2d(float v) { return 0.6616 * v; } +float mx_gradient_scale3d(float v) { return 0.9820 * v; } +vec3 mx_gradient_scale2d(vec3 v) { return 0.6616 * v; } +vec3 mx_gradient_scale3d(vec3 v) { return 0.9820 * v; } + +/// Bitwise circular rotation left by k bits (for 32 bit unsigned integers) +uint mx_rotl32(uint x, int k) +{ + return (x<>(32-k)); +} + +void mx_bjmix(inout uint a, inout uint b, inout uint c) +{ + a -= c; a ^= mx_rotl32(c, 4); c += b; + b -= a; b ^= mx_rotl32(a, 6); a += c; + c -= b; c ^= mx_rotl32(b, 8); b += a; + a -= c; a ^= mx_rotl32(c,16); c += b; + b -= a; b ^= mx_rotl32(a,19); a += c; + c -= b; c ^= mx_rotl32(b, 4); b += a; +} + +// Mix up and combine the bits of a, b, and c (doesn't change them, but +// returns a hash of those three original values). +uint mx_bjfinal(uint a, uint b, uint c) +{ + c ^= b; c -= mx_rotl32(b,14); + a ^= c; a -= mx_rotl32(c,11); + b ^= a; b -= mx_rotl32(a,25); + c ^= b; c -= mx_rotl32(b,16); + a ^= c; a -= mx_rotl32(c,4); + b ^= a; b -= mx_rotl32(a,14); + c ^= b; c -= mx_rotl32(b,24); + return c; +} + +// Convert a 32 bit integer into a floating point number in [0,1] +float mx_bits_to_01(uint bits) +{ + return float(bits) / float(uint(0xffffffff)); +} + +float mx_fade(float t) +{ + return t * t * t * (t * (t * 6.0 - 15.0) + 10.0); +} + +uint mx_hash_int(int x) +{ + uint len = 1u; + uint seed = uint(0xdeadbeef) + (len << 2u) + 13u; + return mx_bjfinal(seed+uint(x), seed, seed); +} + +uint mx_hash_int(int x, int y) +{ + uint len = 2u; + uint a, b, c; + a = b = c = uint(0xdeadbeef) + (len << 2u) + 13u; + a += uint(x); + b += uint(y); + return mx_bjfinal(a, b, c); +} + +uint mx_hash_int(int x, int y, int z) +{ + uint len = 3u; + uint a, b, c; + a = b = c = uint(0xdeadbeef) + (len << 2u) + 13u; + a += uint(x); + b += uint(y); + c += uint(z); + return mx_bjfinal(a, b, c); +} + +uint mx_hash_int(int x, int y, int z, int xx) +{ + uint len = 4u; + uint a, b, c; + a = b = c = uint(0xdeadbeef) + (len << 2u) + 13u; + a += uint(x); + b += uint(y); + c += uint(z); + mx_bjmix(a, b, c); + a += uint(xx); + return mx_bjfinal(a, b, c); +} + +uint mx_hash_int(int x, int y, int z, int xx, int yy) +{ + uint len = 5u; + uint a, b, c; + a = b = c = uint(0xdeadbeef) + (len << 2u) + 13u; + a += uint(x); + b += uint(y); + c += uint(z); + mx_bjmix(a, b, c); + a += uint(xx); + b += uint(yy); + return mx_bjfinal(a, b, c); +} + +uvec3 mx_hash_vec3(int x, int y) +{ + uint h = mx_hash_int(x, y); + // we only need the low-order bits to be random, so split out + // the 32 bit result into 3 parts for each channel + uvec3 result; + result.x = (h ) & 0xFFu; + result.y = (h >> 8 ) & 0xFFu; + result.z = (h >> 16) & 0xFFu; + return result; +} + +uvec3 mx_hash_vec3(int x, int y, int z) +{ + uint h = mx_hash_int(x, y, z); + // we only need the low-order bits to be random, so split out + // the 32 bit result into 3 parts for each channel + uvec3 result; + result.x = (h ) & 0xFFu; + result.y = (h >> 8 ) & 0xFFu; + result.z = (h >> 16) & 0xFFu; + return result; +} + +float mx_perlin_noise_float(vec2 p) +{ + int X, Y; + float fx = mx_floorfrac(p.x, X); + float fy = mx_floorfrac(p.y, Y); + float u = mx_fade(fx); + float v = mx_fade(fy); + float result = mx_bilerp( + mx_gradient_float(mx_hash_int(X , Y ), fx , fy ), + mx_gradient_float(mx_hash_int(X+1, Y ), fx-1.0, fy ), + mx_gradient_float(mx_hash_int(X , Y+1), fx , fy-1.0), + mx_gradient_float(mx_hash_int(X+1, Y+1), fx-1.0, fy-1.0), + u, v); + return mx_gradient_scale2d(result); +} + +float mx_perlin_noise_float(vec3 p) +{ + int X, Y, Z; + float fx = mx_floorfrac(p.x, X); + float fy = mx_floorfrac(p.y, Y); + float fz = mx_floorfrac(p.z, Z); + float u = mx_fade(fx); + float v = mx_fade(fy); + float w = mx_fade(fz); + float result = mx_trilerp( + mx_gradient_float(mx_hash_int(X , Y , Z ), fx , fy , fz ), + mx_gradient_float(mx_hash_int(X+1, Y , Z ), fx-1.0, fy , fz ), + mx_gradient_float(mx_hash_int(X , Y+1, Z ), fx , fy-1.0, fz ), + mx_gradient_float(mx_hash_int(X+1, Y+1, Z ), fx-1.0, fy-1.0, fz ), + mx_gradient_float(mx_hash_int(X , Y , Z+1), fx , fy , fz-1.0), + mx_gradient_float(mx_hash_int(X+1, Y , Z+1), fx-1.0, fy , fz-1.0), + mx_gradient_float(mx_hash_int(X , Y+1, Z+1), fx , fy-1.0, fz-1.0), + mx_gradient_float(mx_hash_int(X+1, Y+1, Z+1), fx-1.0, fy-1.0, fz-1.0), + u, v, w); + return mx_gradient_scale3d(result); +} + +vec3 mx_perlin_noise_vec3(vec2 p) +{ + int X, Y; + float fx = mx_floorfrac(p.x, X); + float fy = mx_floorfrac(p.y, Y); + float u = mx_fade(fx); + float v = mx_fade(fy); + vec3 result = mx_bilerp( + mx_gradient_vec3(mx_hash_vec3(X , Y ), fx , fy ), + mx_gradient_vec3(mx_hash_vec3(X+1, Y ), fx-1.0, fy ), + mx_gradient_vec3(mx_hash_vec3(X , Y+1), fx , fy-1.0), + mx_gradient_vec3(mx_hash_vec3(X+1, Y+1), fx-1.0, fy-1.0), + u, v); + return mx_gradient_scale2d(result); +} + +vec3 mx_perlin_noise_vec3(vec3 p) +{ + int X, Y, Z; + float fx = mx_floorfrac(p.x, X); + float fy = mx_floorfrac(p.y, Y); + float fz = mx_floorfrac(p.z, Z); + float u = mx_fade(fx); + float v = mx_fade(fy); + float w = mx_fade(fz); + vec3 result = mx_trilerp( + mx_gradient_vec3(mx_hash_vec3(X , Y , Z ), fx , fy , fz ), + mx_gradient_vec3(mx_hash_vec3(X+1, Y , Z ), fx-1.0, fy , fz ), + mx_gradient_vec3(mx_hash_vec3(X , Y+1, Z ), fx , fy-1.0, fz ), + mx_gradient_vec3(mx_hash_vec3(X+1, Y+1, Z ), fx-1.0, fy-1.0, fz ), + mx_gradient_vec3(mx_hash_vec3(X , Y , Z+1), fx , fy , fz-1.0), + mx_gradient_vec3(mx_hash_vec3(X+1, Y , Z+1), fx-1.0, fy , fz-1.0), + mx_gradient_vec3(mx_hash_vec3(X , Y+1, Z+1), fx , fy-1.0, fz-1.0), + mx_gradient_vec3(mx_hash_vec3(X+1, Y+1, Z+1), fx-1.0, fy-1.0, fz-1.0), + u, v, w); + return mx_gradient_scale3d(result); +} + +float mx_cell_noise_float(float p) +{ + int ix = mx_floor(p); + return mx_bits_to_01(mx_hash_int(ix)); +} + +float mx_cell_noise_float(vec2 p) +{ + int ix = mx_floor(p.x); + int iy = mx_floor(p.y); + return mx_bits_to_01(mx_hash_int(ix, iy)); +} + +float mx_cell_noise_float(vec3 p) +{ + int ix = mx_floor(p.x); + int iy = mx_floor(p.y); + int iz = mx_floor(p.z); + return mx_bits_to_01(mx_hash_int(ix, iy, iz)); +} + +float mx_cell_noise_float(vec4 p) +{ + int ix = mx_floor(p.x); + int iy = mx_floor(p.y); + int iz = mx_floor(p.z); + int iw = mx_floor(p.w); + return mx_bits_to_01(mx_hash_int(ix, iy, iz, iw)); +} + +vec3 mx_cell_noise_vec3(float p) +{ + int ix = mx_floor(p); + return vec3( + mx_bits_to_01(mx_hash_int(ix, 0)), + mx_bits_to_01(mx_hash_int(ix, 1)), + mx_bits_to_01(mx_hash_int(ix, 2)) + ); +} + +vec3 mx_cell_noise_vec3(vec2 p) +{ + int ix = mx_floor(p.x); + int iy = mx_floor(p.y); + return vec3( + mx_bits_to_01(mx_hash_int(ix, iy, 0)), + mx_bits_to_01(mx_hash_int(ix, iy, 1)), + mx_bits_to_01(mx_hash_int(ix, iy, 2)) + ); +} + +vec3 mx_cell_noise_vec3(vec3 p) +{ + int ix = mx_floor(p.x); + int iy = mx_floor(p.y); + int iz = mx_floor(p.z); + return vec3( + mx_bits_to_01(mx_hash_int(ix, iy, iz, 0)), + mx_bits_to_01(mx_hash_int(ix, iy, iz, 1)), + mx_bits_to_01(mx_hash_int(ix, iy, iz, 2)) + ); +} + +vec3 mx_cell_noise_vec3(vec4 p) +{ + int ix = mx_floor(p.x); + int iy = mx_floor(p.y); + int iz = mx_floor(p.z); + int iw = mx_floor(p.w); + return vec3( + mx_bits_to_01(mx_hash_int(ix, iy, iz, iw, 0)), + mx_bits_to_01(mx_hash_int(ix, iy, iz, iw, 1)), + mx_bits_to_01(mx_hash_int(ix, iy, iz, iw, 2)) + ); +} + +float mx_fractal_noise_float(vec3 p, int octaves, float lacunarity, float diminish) +{ + float result = 0.0; + float amplitude = 1.0; + for (int i = 0; i < octaves; ++i) + { + result += amplitude * mx_perlin_noise_float(p); + amplitude *= diminish; + p *= lacunarity; + } + return result; +} + +vec3 mx_fractal_noise_vec3(vec3 p, int octaves, float lacunarity, float diminish) +{ + vec3 result = vec3(0.0); + float amplitude = 1.0; + for (int i = 0; i < octaves; ++i) + { + result += amplitude * mx_perlin_noise_vec3(p); + amplitude *= diminish; + p *= lacunarity; + } + return result; +} + +vec2 mx_fractal_noise_vec2(vec3 p, int octaves, float lacunarity, float diminish) +{ + return vec2(mx_fractal_noise_float(p, octaves, lacunarity, diminish), + mx_fractal_noise_float(p+vec3(19, 193, 17), octaves, lacunarity, diminish)); +} + +vec4 mx_fractal_noise_vec4(vec3 p, int octaves, float lacunarity, float diminish) +{ + vec3 c = mx_fractal_noise_vec3(p, octaves, lacunarity, diminish); + float f = mx_fractal_noise_float(p+vec3(19, 193, 17), octaves, lacunarity, diminish); + return vec4(c, f); +} + +float mx_worley_distance(vec2 p, int x, int y, int xoff, int yoff, float jitter, int metric) +{ + vec3 tmp = mx_cell_noise_vec3(vec2(x+xoff, y+yoff)); + vec2 off = vec2(tmp.x, tmp.y); + + off -= 0.5f; + off *= jitter; + off += 0.5f; + + vec2 cellpos = vec2(float(x), float(y)) + off; + vec2 diff = cellpos - p; + if (metric == 2) + return abs(diff.x) + abs(diff.y); // Manhattan distance + if (metric == 3) + return max(abs(diff.x), abs(diff.y)); // Chebyshev distance + // Either Euclidian or Distance^2 + return dot(diff, diff); +} + +float mx_worley_distance(vec3 p, int x, int y, int z, int xoff, int yoff, int zoff, float jitter, int metric) +{ + vec3 off = mx_cell_noise_vec3(vec3(x+xoff, y+yoff, z+zoff)); + + off -= 0.5f; + off *= jitter; + off += 0.5f; + + vec3 cellpos = vec3(float(x), float(y), float(z)) + off; + vec3 diff = cellpos - p; + if (metric == 2) + return abs(diff.x) + abs(diff.y) + abs(diff.z); // Manhattan distance + if (metric == 3) + return max(max(abs(diff.x), abs(diff.y)), abs(diff.z)); // Chebyshev distance + // Either Euclidian or Distance^2 + return dot(diff, diff); +} + +float mx_worley_noise_float(vec2 p, float jitter, int metric) +{ + int X, Y; + vec2 localpos = vec2(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y)); + float sqdist = 1e6f; // Some big number for jitter > 1 (not all GPUs may be IEEE) + for (int x = -1; x <= 1; ++x) + { + for (int y = -1; y <= 1; ++y) + { + float dist = mx_worley_distance(localpos, x, y, X, Y, jitter, metric); + sqdist = min(sqdist, dist); + } + } + if (metric == 0) + sqdist = sqrt(sqdist); + return sqdist; +} + +vec2 mx_worley_noise_vec2(vec2 p, float jitter, int metric) +{ + int X, Y; + vec2 localpos = vec2(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y)); + vec2 sqdist = vec2(1e6f, 1e6f); + for (int x = -1; x <= 1; ++x) + { + for (int y = -1; y <= 1; ++y) + { + float dist = mx_worley_distance(localpos, x, y, X, Y, jitter, metric); + if (dist < sqdist.x) + { + sqdist.y = sqdist.x; + sqdist.x = dist; + } + else if (dist < sqdist.y) + { + sqdist.y = dist; + } + } + } + if (metric == 0) + sqdist = sqrt(sqdist); + return sqdist; +} + +vec3 mx_worley_noise_vec3(vec2 p, float jitter, int metric) +{ + int X, Y; + vec2 localpos = vec2(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y)); + vec3 sqdist = vec3(1e6f, 1e6f, 1e6f); + for (int x = -1; x <= 1; ++x) + { + for (int y = -1; y <= 1; ++y) + { + float dist = mx_worley_distance(localpos, x, y, X, Y, jitter, metric); + if (dist < sqdist.x) + { + sqdist.z = sqdist.y; + sqdist.y = sqdist.x; + sqdist.x = dist; + } + else if (dist < sqdist.y) + { + sqdist.z = sqdist.y; + sqdist.y = dist; + } + else if (dist < sqdist.z) + { + sqdist.z = dist; + } + } + } + if (metric == 0) + sqdist = sqrt(sqdist); + return sqdist; +} + +float mx_worley_noise_float(vec3 p, float jitter, int metric) +{ + int X, Y, Z; + vec3 localpos = vec3(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y), mx_floorfrac(p.z, Z)); + float sqdist = 1e6f; + for (int x = -1; x <= 1; ++x) + { + for (int y = -1; y <= 1; ++y) + { + for (int z = -1; z <= 1; ++z) + { + float dist = mx_worley_distance(localpos, x, y, z, X, Y, Z, jitter, metric); + sqdist = min(sqdist, dist); + } + } + } + if (metric == 0) + sqdist = sqrt(sqdist); + return sqdist; +} + +vec2 mx_worley_noise_vec2(vec3 p, float jitter, int metric) +{ + int X, Y, Z; + vec3 localpos = vec3(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y), mx_floorfrac(p.z, Z)); + vec2 sqdist = vec2(1e6f, 1e6f); + for (int x = -1; x <= 1; ++x) + { + for (int y = -1; y <= 1; ++y) + { + for (int z = -1; z <= 1; ++z) + { + float dist = mx_worley_distance(localpos, x, y, z, X, Y, Z, jitter, metric); + if (dist < sqdist.x) + { + sqdist.y = sqdist.x; + sqdist.x = dist; + } + else if (dist < sqdist.y) + { + sqdist.y = dist; + } + } + } + } + if (metric == 0) + sqdist = sqrt(sqdist); + return sqdist; +} + +vec3 mx_worley_noise_vec3(vec3 p, float jitter, int metric) +{ + int X, Y, Z; + vec3 localpos = vec3(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y), mx_floorfrac(p.z, Z)); + vec3 sqdist = vec3(1e6f, 1e6f, 1e6f); + for (int x = -1; x <= 1; ++x) + { + for (int y = -1; y <= 1; ++y) + { + for (int z = -1; z <= 1; ++z) + { + float dist = mx_worley_distance(localpos, x, y, z, X, Y, Z, jitter, metric); + if (dist < sqdist.x) + { + sqdist.z = sqdist.y; + sqdist.y = sqdist.x; + sqdist.x = dist; + } + else if (dist < sqdist.y) + { + sqdist.z = sqdist.y; + sqdist.y = dist; + } + else if (dist < sqdist.z) + { + sqdist.z = dist; + } + } + } + } + if (metric == 0) + sqdist = sqrt(sqdist); + return sqdist; +}` ); + +const includes = [ mx_noise ]; + +export const mx_perlin_noise_float = fn( 'float mx_perlin_noise_float( any p )', includes ); +export const mx_perlin_noise_vec2 = fn( 'vec2 mx_perlin_noise_vec2( any p )', includes ); +export const mx_perlin_noise_vec3 = fn( 'vec3 mx_perlin_noise_vec3( any p )', includes ); + +export const mx_cell_noise_float = fn( 'float mx_cell_noise_float( vec3 p )', includes ); + +export const mx_worley_noise_float = fn( 'float mx_worley_noise_float( any p, float jitter, int metric )', includes ); +export const mx_worley_noise_vec2 = fn( 'float mx_worley_noise_vec2( any p, float jitter, int metric )', includes ); +export const mx_worley_noise_vec3 = fn( 'float mx_worley_noise_vec3( any p, float jitter, int metric )', includes ); + +export const mx_fractal_noise_float = fn( 'float mx_fractal_noise_float( vec3 p, int octaves, float lacunarity, float diminish )', includes ); +export const mx_fractal_noise_vec2 = fn( 'float mx_fractal_noise_vec2( vec3 p, int octaves, float lacunarity, float diminish )', includes ); +export const mx_fractal_noise_vec3 = fn( 'float mx_fractal_noise_vec3( vec3 p, int octaves, float lacunarity, float diminish )', includes ); +export const mx_fractal_noise_vec4 = fn( 'float mx_fractal_noise_vec4( vec3 p, int octaves, float lacunarity, float diminish )', includes ); diff --git a/examples/jsm/nodes/materialx/lib/mx_transform_color.js b/examples/jsm/nodes/materialx/lib/mx_transform_color.js new file mode 100644 index 00000000000000..6ca401de9eaa73 --- /dev/null +++ b/examples/jsm/nodes/materialx/lib/mx_transform_color.js @@ -0,0 +1,18 @@ +import { code, fn } from '../../Nodes.js'; + +// Original shader code from: +// https://github.com/AcademySoftwareFoundation/MaterialX/blob/main/libraries/stdlib/genglsl/lib/mx_transform_color.glsl + +export const mx_transform_color = code( `#define M_AP1_TO_REC709 mat3(1.705079555511475, -0.1297005265951157, -0.02416634373366833, -0.6242334842681885, 1.138468623161316, -0.1246141716837883, -0.0808461606502533, -0.008768022060394287, 1.148780584335327) + +vec3 mx_srgb_texture_to_lin_rec709(vec3 color) +{ + bvec3 isAbove = greaterThan(color, vec3(0.04045)); + vec3 linSeg = color / 12.92; + vec3 powSeg = pow(max(color + vec3(0.055), vec3(0.0)) / 1.055, vec3(2.4)); + return mix(linSeg, powSeg, isAbove); +}` ); + +const includes = [ mx_transform_color ]; + +export const mx_srgb_texture_to_lin_rec709 = fn( 'vec3 mx_srgb_texture_to_lin_rec709( vec3 color )', includes ); diff --git a/examples/jsm/nodes/math/MathNode.js b/examples/jsm/nodes/math/MathNode.js index fd281ed7c90d23..f271609668d2f0 100644 --- a/examples/jsm/nodes/math/MathNode.js +++ b/examples/jsm/nodes/math/MathNode.js @@ -32,8 +32,8 @@ class MathNode extends TempNode { static INVERT = 'invert'; static DFDX = 'dFdx'; static DFDY = 'dFdy'; - static SATURATE = 'saturate'; static ROUND = 'round'; + static RECIPROCAL = 'reciprocal'; // 2 inputs @@ -152,10 +152,6 @@ class MathNode extends TempNode { return new MathNode( MathNode.NORMALIZE, mulNode ).build( builder ); - } else if ( method === MathNode.SATURATE ) { - - return builder.format( `clamp( ${ a.build( builder, inputType ) }, 0.0, 1.0 )`, type, output ); - } else if ( method === MathNode.NEGATE ) { return builder.format( '( -' + a.build( builder, inputType ) + ' )', type, output ); @@ -164,6 +160,10 @@ class MathNode extends TempNode { return builder.format( '( 1.0 - ' + a.build( builder, inputType ) + ' )', type, output ); + } else if ( method === MathNode.RECIPROCAL ) { + + return builder.format( '( 1.0 / ' + a.build( builder, inputType ) + ' )', type, output ); + } else { const params = []; diff --git a/examples/jsm/nodes/math/OperatorNode.js b/examples/jsm/nodes/math/OperatorNode.js index 5567b7a7fd46ad..41581f58afbdf6 100644 --- a/examples/jsm/nodes/math/OperatorNode.js +++ b/examples/jsm/nodes/math/OperatorNode.js @@ -47,7 +47,7 @@ class OperatorNode extends TempNode { } else if ( op === '&' || op === '|' || op === '^' || op === '>>' || op === '<<' ) { - return 'int'; + return builder.getIntegerType( typeA ); } else if ( op === '==' || op === '&&' || op === '||' || op === '^^' ) { @@ -124,6 +124,11 @@ class OperatorNode extends TempNode { } + } else if ( op === '>>' || op === '<<' ) { + + typeA = type; + typeB = builder.changeComponentType( typeB, 'uint' ); + } else if ( builder.isMatrix( typeA ) && builder.isVector( typeB ) ) { // matrix x vector @@ -163,14 +168,22 @@ class OperatorNode extends TempNode { return a; - } else if ( op === '>' && outputLength > 1 ) { + } else if ( op === '<' && outputLength > 1 ) { - return builder.format( `${ builder.getMethod( 'greaterThan' ) }( ${a}, ${b} )`, type, output ); + return builder.format( `${ builder.getMethod( 'lessThan' ) }( ${a}, ${b} )`, type, output ); } else if ( op === '<=' && outputLength > 1 ) { return builder.format( `${ builder.getMethod( 'lessThanEqual' ) }( ${a}, ${b} )`, type, output ); + } else if ( op === '>' && outputLength > 1 ) { + + return builder.format( `${ builder.getMethod( 'greaterThan' ) }( ${a}, ${b} )`, type, output ); + + } else if ( op === '>=' && outputLength > 1 ) { + + return builder.format( `${ builder.getMethod( 'greaterThanEqual' ) }( ${a}, ${b} )`, type, output ); + } else { return builder.format( `( ${a} ${this.op} ${b} )`, type, output ); diff --git a/examples/jsm/nodes/parsers/GLSLNodeFunction.js b/examples/jsm/nodes/parsers/GLSLNodeFunction.js index 917b9609e9b8f4..a3b3901f2e2651 100644 --- a/examples/jsm/nodes/parsers/GLSLNodeFunction.js +++ b/examples/jsm/nodes/parsers/GLSLNodeFunction.js @@ -117,18 +117,33 @@ class GLSLNodeFunction extends NodeFunction { getCode( name = this.name ) { - const headerCode = this.headerCode; - const presicion = this.presicion; + let code; - let declarationCode = `${ this.type } ${ name } ( ${ this.inputsCode.trim() } )`; + const blockCode = this.blockCode; - if ( presicion !== '' ) { + if ( blockCode !== '' ) { - declarationCode = `${ presicion } ${ declarationCode }`; + const { type, inputsCode, headerCode, presicion } = this; + + let declarationCode = `${ type } ${ name } ( ${ inputsCode.trim() } )`; + + if ( presicion !== '' ) { + + declarationCode = `${ presicion } ${ declarationCode }`; + + } + + code = headerCode + declarationCode + blockCode; + + } else { + + // interface function + + code = ''; } - return headerCode + declarationCode + this.blockCode; + return code; } diff --git a/examples/jsm/nodes/procedural/CheckerNode.js b/examples/jsm/nodes/procedural/CheckerNode.js index 8c449e83ca3fb5..2ffb73d639342e 100644 --- a/examples/jsm/nodes/procedural/CheckerNode.js +++ b/examples/jsm/nodes/procedural/CheckerNode.js @@ -1,4 +1,4 @@ -import Node from '../core/Node.js'; +import TempNode from '../core/TempNode.js'; import { ShaderNode, uv, add, mul, floor, mod, sign } from '../shadernode/ShaderNodeBaseElements.js'; const checkerShaderNode = new ShaderNode( ( inputs ) => { @@ -13,7 +13,7 @@ const checkerShaderNode = new ShaderNode( ( inputs ) => { } ); -class CheckerNode extends Node { +class CheckerNode extends TempNode { constructor( uvNode = uv() ) { diff --git a/examples/jsm/nodes/shadernode/ShaderNode.js b/examples/jsm/nodes/shadernode/ShaderNode.js index 3636d64ff038bd..30fc68d3e0c6cb 100644 --- a/examples/jsm/nodes/shadernode/ShaderNode.js +++ b/examples/jsm/nodes/shadernode/ShaderNode.js @@ -1,3 +1,4 @@ +import Node from '../core/Node.js'; import ArrayElementNode from '../utils/ArrayElementNode.js'; import ConvertNode from '../utils/ConvertNode.js'; import JoinNode from '../utils/JoinNode.js'; @@ -107,31 +108,33 @@ const ShaderNodeArray = function ( array ) { }; -const ShaderNodeProxy = function ( NodeClass, scope = null, factor = null ) { +const ShaderNodeProxy = function ( NodeClass, scope = null, factor = null, settings = null ) { + + const assignNode = ( node ) => nodeObject( settings !== null ? Object.assign( node, settings ) : node ); if ( scope === null ) { return ( ...params ) => { - return nodeObject( new NodeClass( ...nodeArray( params ) ) ); + return assignNode( new NodeClass( ...nodeArray( params ) ) ); }; - } else if ( factor === null ) { + } else if ( factor !== null ) { + + factor = nodeObject( factor ); return ( ...params ) => { - return nodeObject( new NodeClass( scope, ...nodeArray( params ) ) ); + return assignNode( new NodeClass( scope, ...nodeArray( params ), factor ) ); }; } else { - factor = nodeObject( factor ); - return ( ...params ) => { - return nodeObject( new NodeClass( scope, ...nodeArray( params ), factor ) ); + return assignNode( new NodeClass( scope, ...nodeArray( params ) ) ); }; @@ -145,31 +148,43 @@ const ShaderNodeImmutable = function ( NodeClass, ...params ) { }; -const ShaderNodeScript = function ( jsFunc ) { +class ShaderNodeInternal extends Node { - // @TODO: Move this to Node extended class + constructor( jsFunc ) { - const self = { + super(); - build: ( builder ) => { + this._jsFunc = jsFunc; - self.call( {}, builder ); + } - return ''; + call( inputs, builder ) { - }, + inputs = nodeObjects( inputs ); - call: ( inputs, builder ) => { + return nodeObject( this._jsFunc( inputs, builder ) ); + + } - inputs = nodeObjects( inputs ); + generate( builder, output ) { - return nodeObject( jsFunc( inputs, builder ) ); + const nodeCall = this.call( {}, builder ); + + if ( nodeCall === undefined ) { + + return ''; } - }; + return builder.format( nodeCall.build( builder ), nodeCall.getNodeType( builder ), output ); + + } + +} + +const ShaderNodeScript = function ( jsFunc ) { - return self; + return new ShaderNodeInternal( jsFunc ); }; @@ -251,7 +266,7 @@ export const ConvertType = function ( type, cacheMap = null ) { } - return nodeObject( new ConvertNode( new JoinNode( nodes ), type ) ); + return nodeObject( new JoinNode( nodes, type ) ); } diff --git a/examples/jsm/nodes/shadernode/ShaderNodeBaseElements.js b/examples/jsm/nodes/shadernode/ShaderNodeBaseElements.js index 5d8191b2769b06..845dee19ab3c6f 100644 --- a/examples/jsm/nodes/shadernode/ShaderNodeBaseElements.js +++ b/examples/jsm/nodes/shadernode/ShaderNodeBaseElements.js @@ -14,6 +14,7 @@ import VarNode from '../core/VarNode.js'; import VaryingNode from '../core/VaryingNode.js'; // accessors +import BitangentNode from '../accessors/BitangentNode.js'; import BufferNode from '../accessors/BufferNode.js'; import CameraNode from '../accessors/CameraNode.js'; import MaterialNode from '../accessors/MaterialNode.js'; @@ -25,6 +26,7 @@ import PointUVNode from '../accessors/PointUVNode.js'; import PositionNode from '../accessors/PositionNode.js'; import ReferenceNode from '../accessors/ReferenceNode.js'; import StorageBufferNode from '../accessors/StorageBufferNode.js'; +import TangentNode from '../accessors/TangentNode.js'; import TextureNode from '../accessors/TextureNode.js'; import UserDataNode from '../accessors/UserDataNode.js'; import UVNode from '../accessors/UVNode.js'; @@ -87,12 +89,12 @@ export const bmat4 = new ConvertType( 'bmat4' ); // @TODO: ArrayUniformNode -export const func = ( code ) => { +export const func = ( code, includes ) => { - const node = nodeObject( new FunctionNode( code ) ); + const node = nodeObject( new FunctionNode( code, includes ) ); const call = node.call.bind( node ); - node.call = ( params ) => nodeObject( call( params ) ); + node.call = ( ...params ) => nodeObject( call( params.length > 1 || params[ 0 ]?.isNode === true ? nodeArray( params ) : nodeObjects( params[ 0 ] ) ) ); return node; @@ -109,9 +111,13 @@ export const uniform = ( nodeOrType ) => { }; +export const fn = ( code, includes ) => func( code, includes ).call; + export const attribute = ( name, nodeType ) => nodeObject( new AttributeNode( name, nodeType ) ); export const property = ( name, nodeOrType ) => nodeObject( new PropertyNode( name, getConstNodeType( nodeOrType ) ) ); +export const convert = ( node, types ) => nodeObject( new ConvertNode( nodeObject( node ), types ) ); + export const bypass = nodeProxy( BypassNode ); export const code = nodeProxy( CodeNode ); export const context = nodeProxy( ContextNode ); @@ -122,65 +128,6 @@ export const label = nodeProxy( VarNode ); export const temp = label; export const varying = nodeProxy( VaryingNode ); -// accesors - -export const buffer = ( value, nodeOrType, count ) => nodeObject( new BufferNode( value, getConstNodeType( nodeOrType ), count ) ); -export const storage = ( value, nodeOrType, count ) => nodeObject( new StorageBufferNode( value, getConstNodeType( nodeOrType ), count ) ); - -export const cameraProjectionMatrix = nodeImmutable( CameraNode, CameraNode.PROJECTION_MATRIX ); -export const cameraViewMatrix = nodeImmutable( CameraNode, CameraNode.VIEW_MATRIX ); -export const cameraNormalMatrix = nodeImmutable( CameraNode, CameraNode.NORMAL_MATRIX ); -export const cameraWorldMatrix = nodeImmutable( CameraNode, CameraNode.WORLD_MATRIX ); -export const cameraPosition = nodeImmutable( CameraNode, CameraNode.POSITION ); - -export const materialAlphaTest = nodeImmutable( MaterialNode, MaterialNode.ALPHA_TEST ); -export const materialColor = nodeImmutable( MaterialNode, MaterialNode.COLOR ); -export const materialEmissive = nodeImmutable( MaterialNode, MaterialNode.EMISSIVE ); -export const materialOpacity = nodeImmutable( MaterialNode, MaterialNode.OPACITY ); -//export const materialSpecular = nodeImmutable( MaterialNode, MaterialNode.SPECULAR ); -export const materialRoughness = nodeImmutable( MaterialNode, MaterialNode.ROUGHNESS ); -export const materialMetalness = nodeImmutable( MaterialNode, MaterialNode.METALNESS ); -export const materialRotation = nodeImmutable( MaterialNode, MaterialNode.ROTATION ); - -export const diffuseColor = nodeImmutable( PropertyNode, 'DiffuseColor', 'vec4' ); -export const roughness = nodeImmutable( PropertyNode, 'Roughness', 'float' ); -export const metalness = nodeImmutable( PropertyNode, 'Metalness', 'float' ); -export const alphaTest = nodeImmutable( PropertyNode, 'AlphaTest', 'float' ); -export const specularColor = nodeImmutable( PropertyNode, 'SpecularColor', 'color' ); - -export const reference = ( name, nodeOrType, object ) => nodeObject( new ReferenceNode( name, getConstNodeType( nodeOrType ), object ) ); -export const materialReference = ( name, nodeOrType, material ) => nodeObject( new MaterialReferenceNode( name, getConstNodeType( nodeOrType ), material ) ); -export const userData = ( name, inputType, userData ) => nodeObject( new UserDataNode( name, inputType, userData ) ); - -export const modelViewProjection = nodeProxy( ModelViewProjectionNode ); - -export const normalGeometry = nodeImmutable( NormalNode, NormalNode.GEOMETRY ); -export const normalLocal = nodeImmutable( NormalNode, NormalNode.LOCAL ); -export const normalWorld = nodeImmutable( NormalNode, NormalNode.WORLD ); -export const normalView = nodeImmutable( NormalNode, NormalNode.VIEW ); -export const transformedNormalView = nodeImmutable( VarNode, normalView, 'TransformedNormalView' ); - -export const modelViewMatrix = nodeImmutable( ModelNode, ModelNode.VIEW_MATRIX ); -export const modelNormalMatrix = nodeImmutable( ModelNode, ModelNode.NORMAL_MATRIX ); -export const modelWorldMatrix = nodeImmutable( ModelNode, ModelNode.WORLD_MATRIX ); -export const modelPosition = nodeImmutable( ModelNode, ModelNode.POSITION ); -export const modelViewPosition = nodeImmutable( ModelNode, ModelNode.VIEW_POSITION ); - -export const positionGeometry = nodeImmutable( PositionNode, PositionNode.GEOMETRY ); -export const positionLocal = nodeImmutable( PositionNode, PositionNode.LOCAL ); -export const positionWorld = nodeImmutable( PositionNode, PositionNode.WORLD ); -export const positionView = nodeImmutable( PositionNode, PositionNode.VIEW ); -export const positionViewDirection = nodeImmutable( PositionNode, PositionNode.VIEW_DIRECTION ); - -export const texture = nodeProxy( TextureNode ); -export const sampler = ( texture ) => nodeObject( new ConvertNode( texture.isNode === true ? texture : new TextureNode( texture ), 'sampler' ) ); -export const uv = ( ...params ) => nodeObject( new UVNode( ...params ) ); -export const pointUV = nodeImmutable( PointUVNode ); - -// gpgpu - -export const compute = ( node, count, workgroupSize ) => nodeObject( new ComputeNode( nodeObject( node ), count, workgroupSize ) ); - // math export const EPSILON = float( 1e-6 ); @@ -233,8 +180,8 @@ export const negate = nodeProxy( MathNode, MathNode.NEGATE ); export const invert = nodeProxy( MathNode, MathNode.INVERT ); export const dFdx = nodeProxy( MathNode, MathNode.DFDX ); export const dFdy = nodeProxy( MathNode, MathNode.DFDY ); -export const saturate = nodeProxy( MathNode, MathNode.SATURATE ); export const round = nodeProxy( MathNode, MathNode.ROUND ); +export const reciprocal = nodeProxy( MathNode, MathNode.RECIPROCAL ); export const atan2 = nodeProxy( MathNode, MathNode.ATAN2 ); export const min = nodeProxy( MathNode, MathNode.MIN ); @@ -252,11 +199,86 @@ export const pow4 = nodeProxy( MathNode, MathNode.POW, 4 ); export const transformDirection = nodeProxy( MathNode, MathNode.TRANSFORM_DIRECTION ); export const mix = nodeProxy( MathNode, MathNode.MIX ); -export const clamp = nodeProxy( MathNode, MathNode.CLAMP ); +export const clamp = ( value, low = 0, high = 1 ) => nodeObject( new MathNode( MathNode.CLAMP, nodeObject( value ), nodeObject( low ), nodeObject( high ) ) ); export const refract = nodeProxy( MathNode, MathNode.REFRACT ); export const smoothstep = nodeProxy( MathNode, MathNode.SMOOTHSTEP ); export const faceforward = nodeProxy( MathNode, MathNode.FACEFORWARD ); +// accessors + +export const buffer = ( value, nodeOrType, count ) => nodeObject( new BufferNode( value, getConstNodeType( nodeOrType ), count ) ); +export const storage = ( value, nodeOrType, count ) => nodeObject( new StorageBufferNode( value, getConstNodeType( nodeOrType ), count ) ); + +export const cameraProjectionMatrix = nodeImmutable( CameraNode, CameraNode.PROJECTION_MATRIX ); +export const cameraViewMatrix = nodeImmutable( CameraNode, CameraNode.VIEW_MATRIX ); +export const cameraNormalMatrix = nodeImmutable( CameraNode, CameraNode.NORMAL_MATRIX ); +export const cameraWorldMatrix = nodeImmutable( CameraNode, CameraNode.WORLD_MATRIX ); +export const cameraPosition = nodeImmutable( CameraNode, CameraNode.POSITION ); + +export const materialAlphaTest = nodeImmutable( MaterialNode, MaterialNode.ALPHA_TEST ); +export const materialColor = nodeImmutable( MaterialNode, MaterialNode.COLOR ); +export const materialEmissive = nodeImmutable( MaterialNode, MaterialNode.EMISSIVE ); +export const materialOpacity = nodeImmutable( MaterialNode, MaterialNode.OPACITY ); +//export const materialSpecular = nodeImmutable( MaterialNode, MaterialNode.SPECULAR ); +export const materialRoughness = nodeImmutable( MaterialNode, MaterialNode.ROUGHNESS ); +export const materialMetalness = nodeImmutable( MaterialNode, MaterialNode.METALNESS ); +export const materialRotation = nodeImmutable( MaterialNode, MaterialNode.ROTATION ); + +export const diffuseColor = nodeImmutable( PropertyNode, 'DiffuseColor', 'vec4' ); +export const roughness = nodeImmutable( PropertyNode, 'Roughness', 'float' ); +export const metalness = nodeImmutable( PropertyNode, 'Metalness', 'float' ); +export const alphaTest = nodeImmutable( PropertyNode, 'AlphaTest', 'float' ); +export const specularColor = nodeImmutable( PropertyNode, 'SpecularColor', 'color' ); + +export const reference = ( name, nodeOrType, object ) => nodeObject( new ReferenceNode( name, getConstNodeType( nodeOrType ), object ) ); +export const materialReference = ( name, nodeOrType, material ) => nodeObject( new MaterialReferenceNode( name, getConstNodeType( nodeOrType ), material ) ); +export const userData = ( name, inputType, userData ) => nodeObject( new UserDataNode( name, inputType, userData ) ); + +export const modelViewProjection = nodeProxy( ModelViewProjectionNode ); + +export const normalGeometry = nodeImmutable( NormalNode, NormalNode.GEOMETRY ); +export const normalLocal = nodeImmutable( NormalNode, NormalNode.LOCAL ); +export const normalView = nodeImmutable( NormalNode, NormalNode.VIEW ); +export const normalWorld = nodeImmutable( NormalNode, NormalNode.WORLD ); +export const transformedNormalView = nodeImmutable( VarNode, normalView, 'TransformedNormalView' ); +export const transformedNormalWorld = normalize( transformDirection( transformedNormalView, cameraViewMatrix ) ); + +export const tangentGeometry = nodeImmutable( TangentNode, TangentNode.GEOMETRY ); +export const tangentLocal = nodeImmutable( TangentNode, TangentNode.LOCAL ); +export const tangentView = nodeImmutable( TangentNode, TangentNode.VIEW ); +export const tangentWorld = nodeImmutable( TangentNode, TangentNode.WORLD ); +export const transformedTangentView = nodeImmutable( VarNode, tangentView, 'TransformedTangentView' ); +export const transformedTangentWorld = normalize( transformDirection( transformedTangentView, cameraViewMatrix ) ); + +export const bitangentGeometry = nodeImmutable( BitangentNode, BitangentNode.GEOMETRY ); +export const bitangentLocal = nodeImmutable( BitangentNode, BitangentNode.LOCAL ); +export const bitangentView = nodeImmutable( BitangentNode, BitangentNode.VIEW ); +export const bitangentWorld = nodeImmutable( BitangentNode, BitangentNode.WORLD ); +export const transformedBitangentView = normalize( mul( cross( transformedNormalView, transformedTangentView ), tangentGeometry.w ) ); +export const transformedBitangentWorld = normalize( transformDirection( transformedBitangentView, cameraViewMatrix ) ); + +export const modelViewMatrix = nodeImmutable( ModelNode, ModelNode.VIEW_MATRIX ); +export const modelNormalMatrix = nodeImmutable( ModelNode, ModelNode.NORMAL_MATRIX ); +export const modelWorldMatrix = nodeImmutable( ModelNode, ModelNode.WORLD_MATRIX ); +export const modelPosition = nodeImmutable( ModelNode, ModelNode.POSITION ); +export const modelViewPosition = nodeImmutable( ModelNode, ModelNode.VIEW_POSITION ); + +export const positionGeometry = nodeImmutable( PositionNode, PositionNode.GEOMETRY ); +export const positionLocal = nodeImmutable( PositionNode, PositionNode.LOCAL ); +export const positionWorld = nodeImmutable( PositionNode, PositionNode.WORLD ); +export const positionWorldDirection = nodeImmutable( PositionNode, PositionNode.WORLD_DIRECTION ); +export const positionView = nodeImmutable( PositionNode, PositionNode.VIEW ); +export const positionViewDirection = nodeImmutable( PositionNode, PositionNode.VIEW_DIRECTION ); + +export const texture = nodeProxy( TextureNode ); +export const sampler = ( texture ) => nodeObject( new ConvertNode( texture.isNode === true ? texture : new TextureNode( texture ), 'sampler' ) ); +export const uv = ( ...params ) => nodeObject( new UVNode( ...params ) ); +export const pointUV = nodeImmutable( PointUVNode ); + +// gpgpu + +export const compute = ( node, count, workgroupSize ) => nodeObject( new ComputeNode( nodeObject( node ), count, workgroupSize ) ); + // display export const frontFacing = nodeImmutable( FrontFacingNode ); @@ -271,5 +293,9 @@ export const element = nodeProxy( ArrayElementNode ); // miscellaneous -export const dotNV = saturate( dot( transformedNormalView, positionViewDirection ) ); -export const transformedNormalWorld = normalize( transformDirection( transformedNormalView, cameraViewMatrix ) ); +export const lumaCoeffs = vec3( 0.2125, 0.7154, 0.0721 ); + +export const luminance = ( color, luma = lumaCoeffs ) => dot( color, luma ); +export const difference = ( a, b ) => abs( sub( a, b ) ); +export const dotNV = clamp( dot( transformedNormalView, positionViewDirection ) ); +export const TBNViewMatrix = mat3( tangentView, bitangentView, normalView ); diff --git a/examples/jsm/nodes/shadernode/ShaderNodeElements.js b/examples/jsm/nodes/shadernode/ShaderNodeElements.js index 5b8534ebceb26d..08bcef0afa4f93 100644 --- a/examples/jsm/nodes/shadernode/ShaderNodeElements.js +++ b/examples/jsm/nodes/shadernode/ShaderNodeElements.js @@ -5,10 +5,13 @@ import ReflectVectorNode from '../accessors/ReflectVectorNode.js'; import SkinningNode from '../accessors/SkinningNode.js'; // display +import BlendModeNode from '../display/BlendModeNode.js'; import ColorAdjustmentNode from '../display/ColorAdjustmentNode.js'; import ColorSpaceNode from '../display/ColorSpaceNode.js'; import NormalMapNode from '../display/NormalMapNode.js'; +import PosterizeNode from '../display/PosterizeNode.js'; import ToneMappingNode from '../display/ToneMappingNode.js'; +import ViewportNode from '../display/ViewportNode.js'; // lighting import LightsNode from '../lighting/LightsNode.js'; @@ -16,12 +19,15 @@ import LightsNode from '../lighting/LightsNode.js'; import LightingContextNode from '../lighting/LightingContextNode.js'; // utils +import EquirectUVNode from '../utils/EquirectUVNode.js'; import MatcapUVNode from '../utils/MatcapUVNode.js'; import MaxMipLevelNode from '../utils/MaxMipLevelNode.js'; import OscNode from '../utils/OscNode.js'; +import RemapNode from '../utils/RemapNode.js'; import RotateUVNode from '../utils/RotateUVNode.js'; import SpriteSheetUVNode from '../utils/SpriteSheetUVNode.js'; import TimerNode from '../utils/TimerNode.js'; +import TriplanarTexturesNode from '../utils/TriplanarTexturesNode.js'; // geometry import RangeNode from '../geometry/RangeNode.js'; @@ -72,6 +78,11 @@ export const skinning = nodeProxy( SkinningNode ); // display +export const burn = nodeProxy( BlendModeNode, BlendModeNode.BURN ); +export const dodge = nodeProxy( BlendModeNode, BlendModeNode.DODGE ); +export const overlay = nodeProxy( BlendModeNode, BlendModeNode.OVERLAY ); +export const screen = nodeProxy( BlendModeNode, BlendModeNode.SCREEN ); + export const saturation = nodeProxy( ColorAdjustmentNode, ColorAdjustmentNode.SATURATION ); export const vibrance = nodeProxy( ColorAdjustmentNode, ColorAdjustmentNode.VIBRANCE ); export const hue = nodeProxy( ColorAdjustmentNode, ColorAdjustmentNode.HUE ); @@ -80,6 +91,15 @@ export const colorSpace = ( node, encoding ) => nodeObject( new ColorSpaceNode( export const normalMap = nodeProxy( NormalMapNode ); export const toneMapping = ( mapping, exposure, color ) => nodeObject( new ToneMappingNode( mapping, nodeObject( exposure ), nodeObject( color ) ) ); +export const posterize = nodeProxy( PosterizeNode ); + +export const viewportCoordinate = nodeImmutable( ViewportNode, ViewportNode.COORDINATE ); +export const viewportResolution = nodeImmutable( ViewportNode, ViewportNode.RESOLUTION ); +export const viewportTopLeft = nodeImmutable( ViewportNode, ViewportNode.TOP_LEFT ); +export const viewportBottomLeft = nodeImmutable( ViewportNode, ViewportNode.BOTTOM_LEFT ); +export const viewportTopRight = nodeImmutable( ViewportNode, ViewportNode.TOP_RIGHT ); +export const viewportBottomRight = nodeImmutable( ViewportNode, ViewportNode.BOTTOM_RIGHT ); + // lighting //export const lighting = nodeProxy( LightingNode ); // abstract @@ -90,6 +110,8 @@ export const lightingContext = nodeProxy( LightingContextNode ); // utils export const matcapUV = nodeImmutable( MatcapUVNode ); +export const equirectUV = nodeProxy( EquirectUVNode ); + export const maxMipLevel = nodeProxy( MaxMipLevelNode ); export const oscSine = nodeProxy( OscNode, OscNode.SINE ); @@ -97,6 +119,9 @@ export const oscSquare = nodeProxy( OscNode, OscNode.SQUARE ); export const oscTriangle = nodeProxy( OscNode, OscNode.TRIANGLE ); export const oscSawtooth = nodeProxy( OscNode, OscNode.SAWTOOTH ); +export const remap = nodeProxy( RemapNode, null, null, { doClamp: false } ); +export const remapClamp = nodeProxy( RemapNode ); + export const rotateUV = nodeProxy( RotateUVNode ); export const spritesheetUV = nodeProxy( SpriteSheetUVNode ); @@ -105,6 +130,10 @@ export const spritesheetUV = nodeProxy( SpriteSheetUVNode ); export const timerLocal = ( timeScale, value = 0 ) => nodeObject( new TimerNode( TimerNode.LOCAL, timeScale, value ) ); export const timerGlobal = ( timeScale, value = 0 ) => nodeObject( new TimerNode( TimerNode.GLOBAL, timeScale, value ) ); export const timerDelta = ( timeScale, value = 0 ) => nodeObject( new TimerNode( TimerNode.DELTA, timeScale, value ) ); +export const frameId = nodeImmutable( TimerNode, TimerNode.FRAME ); + +export const triplanarTextures = nodeProxy( TriplanarTexturesNode ); +export const triplanarTexture = ( texture, ...params ) => triplanarTextures( texture, texture, texture, ...params ); // geometry diff --git a/examples/jsm/nodes/utils/ConvertNode.js b/examples/jsm/nodes/utils/ConvertNode.js index 78bcdf68b221c8..e1b85174e97526 100644 --- a/examples/jsm/nodes/utils/ConvertNode.js +++ b/examples/jsm/nodes/utils/ConvertNode.js @@ -11,31 +11,32 @@ class ConvertNode extends Node { } - getNodeType( /*builder*/ ) { + getNodeType( builder ) { - return this.convertTo; + const requestType = this.node.getNodeType( builder ); - } + let convertTo = null; - generate( builder, output ) { + for ( const overloadingType of this.convertTo.split( '|' ) ) { - const convertTo = this.convertTo; - const node = this.node; - const type = this.getNodeType( builder ); + if ( convertTo === null || builder.getTypeLength( requestType ) === builder.getTypeLength( overloadingType ) ) { - let snippet = null; + convertTo = overloadingType; - if ( builder.isReference( convertTo ) === false ) { + } - const nodeSnippet = node.build( builder, convertTo ); + } - snippet = builder.format( nodeSnippet, type, convertTo ); + return convertTo; - } else { + } - snippet = node.build( builder, convertTo ); + generate( builder, output ) { - } + const node = this.node; + const type = this.getNodeType( builder ); + + const snippet = node.build( builder, type ); return builder.format( snippet, type, output ); diff --git a/examples/jsm/nodes/utils/EquirectUVNode.js b/examples/jsm/nodes/utils/EquirectUVNode.js new file mode 100644 index 00000000000000..bf58b33d073de4 --- /dev/null +++ b/examples/jsm/nodes/utils/EquirectUVNode.js @@ -0,0 +1,27 @@ +import TempNode from '../core/TempNode.js'; +import { nodeObject, vec2, add, mul, atan2, asin, clamp, positionWorldDirection } from '../shadernode/ShaderNodeElements.js'; + +class EquirectUVNode extends TempNode { + + constructor( dirNode = positionWorldDirection ) { + + super( 'vec2' ); + + this.dirNode = dirNode; + + } + + construct() { + + const dir = nodeObject( this.dirNode ); + + const u = add( mul( atan2( dir.z, dir.x ), 1 / ( Math.PI * 2 ) ), 0.5 ); + const v = add( mul( asin( clamp( dir.y, - 1.0, 1.0 ) ), 1 / Math.PI ), 0.5 ); + + return vec2( u, v ); + + } + +} + +export default EquirectUVNode; diff --git a/examples/jsm/nodes/utils/JoinNode.js b/examples/jsm/nodes/utils/JoinNode.js index c14685f0c35a0e..1fdca223983a4a 100644 --- a/examples/jsm/nodes/utils/JoinNode.js +++ b/examples/jsm/nodes/utils/JoinNode.js @@ -2,9 +2,9 @@ import TempNode from '../core/Node.js'; class JoinNode extends TempNode { - constructor( nodes = [] ) { + constructor( nodes = [], nodeType = null ) { - super(); + super( nodeType ); this.nodes = nodes; @@ -12,6 +12,12 @@ class JoinNode extends TempNode { getNodeType( builder ) { + if ( this.nodeType !== null ) { + + return builder.getVectorType( this.nodeType ); + + } + return builder.getTypeFromLength( this.nodes.reduce( ( count, cur ) => count + builder.getTypeLength( cur.getNodeType( builder ) ), 0 ) ); } diff --git a/examples/jsm/nodes/utils/MatcapUVNode.js b/examples/jsm/nodes/utils/MatcapUVNode.js index 6fabfed26dd03e..ddc0776db6a960 100644 --- a/examples/jsm/nodes/utils/MatcapUVNode.js +++ b/examples/jsm/nodes/utils/MatcapUVNode.js @@ -9,14 +9,12 @@ class MatcapUVNode extends TempNode { } - generate( builder ) { + construct() { const x = normalize( vec3( positionViewDirection.z, 0, negate( positionViewDirection.x ) ) ); const y = cross( positionViewDirection, x ); - const uv = add( mul( vec2( dot( x, transformedNormalView ), dot( y, transformedNormalView ) ), 0.495 ), 0.5 ); - - return uv.build( builder, this.getNodeType( builder ) ); + return add( mul( vec2( dot( x, transformedNormalView ), dot( y, transformedNormalView ) ), 0.495 ), 0.5 ); } diff --git a/examples/jsm/nodes/utils/MaxMipLevelNode.js b/examples/jsm/nodes/utils/MaxMipLevelNode.js index 239e9d53b723a9..4cb0ed3971dabd 100644 --- a/examples/jsm/nodes/utils/MaxMipLevelNode.js +++ b/examples/jsm/nodes/utils/MaxMipLevelNode.js @@ -9,7 +9,7 @@ class MaxMipLevelNode extends UniformNode { this.texture = texture; - this.updateType = NodeUpdateType.Frame; + this.updateType = NodeUpdateType.FRAME; } diff --git a/examples/jsm/nodes/utils/OscNode.js b/examples/jsm/nodes/utils/OscNode.js index bf2f4eabb863c9..4df097a91c8732 100644 --- a/examples/jsm/nodes/utils/OscNode.js +++ b/examples/jsm/nodes/utils/OscNode.js @@ -24,7 +24,7 @@ class OscNode extends Node { } - generate( builder ) { + construct() { const method = this.method; const timeNode = this.timeNode; @@ -49,7 +49,7 @@ class OscNode extends Node { } - return outputNode.build( builder ); + return outputNode; } diff --git a/examples/jsm/nodes/utils/RemapNode.js b/examples/jsm/nodes/utils/RemapNode.js new file mode 100644 index 00000000000000..c3b806500cb04f --- /dev/null +++ b/examples/jsm/nodes/utils/RemapNode.js @@ -0,0 +1,34 @@ +import Node from '../core/Node.js'; +import { add, sub, div, mul, clamp } from '../shadernode/ShaderNodeBaseElements.js'; + +class RemapNode extends Node { + + constructor( node, inLowNode, inHighNode, outLowNode, outHighNode ) { + + super(); + + this.node = node; + this.inLowNode = inLowNode; + this.inHighNode = inHighNode; + this.outLowNode = outLowNode; + this.outHighNode = outHighNode; + + this.doClamp = true; + + } + + construct() { + + const { node, inLowNode, inHighNode, outLowNode, outHighNode, doClamp } = this; + + let t = div( sub( node, inLowNode ), sub( inHighNode, inLowNode ) ); + + if ( doClamp === true ) t = clamp( t ); + + return add( mul( sub( outHighNode, outLowNode ), t ), outLowNode ); + + } + +} + +export default RemapNode; diff --git a/examples/jsm/nodes/utils/SpriteSheetUVNode.js b/examples/jsm/nodes/utils/SpriteSheetUVNode.js index 26325bdaab509b..0cb177a641b101 100644 --- a/examples/jsm/nodes/utils/SpriteSheetUVNode.js +++ b/examples/jsm/nodes/utils/SpriteSheetUVNode.js @@ -18,20 +18,18 @@ class SpriteSheetUVNode extends Node { } - generate( builder ) { + construct() { - const count = this.countNode; - const uv = this.uvNode; - const frame = this.frameNode; + const { frameNode, uvNode, countNode } = this; const one = new ConstNode( 1 ); - const width = new SplitNode( count, 'x' ); - const height = new SplitNode( count, 'y' ); + const width = new SplitNode( countNode, 'x' ); + const height = new SplitNode( countNode, 'y' ); const total = new OperatorNode( '*', width, height ); - const roundFrame = new MathNode( MathNode.FLOOR, new MathNode( MathNode.MOD, frame, total ) ); + const roundFrame = new MathNode( MathNode.FLOOR, new MathNode( MathNode.MOD, frameNode, total ) ); const frameNum = new OperatorNode( '+', roundFrame, one ); @@ -39,17 +37,17 @@ class SpriteSheetUVNode extends Node { const row = new MathNode( MathNode.CEIL, new OperatorNode( '/', frameNum, width ) ); const rowInv = new OperatorNode( '-', height, row ); - const scale = new OperatorNode( '/', one, count ); + const scale = new OperatorNode( '/', one, countNode ); const uvFrameOffset = new JoinNode( [ new OperatorNode( '*', cell, new SplitNode( scale, 'x' ) ), new OperatorNode( '*', rowInv, new SplitNode( scale, 'y' ) ) ] ); - const uvScale = new OperatorNode( '*', uv, scale ); + const uvScale = new OperatorNode( '*', uvNode, scale ); const uvFrame = new OperatorNode( '+', uvScale, uvFrameOffset ); - return uvFrame.build( builder, this.getNodeType( builder ) ); + return uvFrame; } diff --git a/examples/jsm/nodes/utils/TimerNode.js b/examples/jsm/nodes/utils/TimerNode.js index a9c35f4d6e39a9..a0dc181d977a42 100644 --- a/examples/jsm/nodes/utils/TimerNode.js +++ b/examples/jsm/nodes/utils/TimerNode.js @@ -6,6 +6,7 @@ class TimerNode extends UniformNode { static LOCAL = 'local'; static GLOBAL = 'global'; static DELTA = 'delta'; + static FRAME = 'frame'; constructor( scope = TimerNode.LOCAL, scale = 1, value = 0 ) { @@ -14,10 +15,25 @@ class TimerNode extends UniformNode { this.scope = scope; this.scale = scale; - this.updateType = NodeUpdateType.Frame; + this.updateType = NodeUpdateType.FRAME; } +/* + @TODO: + getNodeType( builder ) { + const scope = this.scope; + + if ( scope === TimerNode.FRAME ) { + + return 'uint'; + + } + + return 'float'; + + } +*/ update( frame ) { const scope = this.scope; @@ -31,6 +47,10 @@ class TimerNode extends UniformNode { this.value = frame.deltaTime * scale; + } else if ( scope === TimerNode.FRAME ) { + + this.value = frame.frameId; + } else { // global diff --git a/examples/jsm/nodes/utils/TriplanarTexturesNode.js b/examples/jsm/nodes/utils/TriplanarTexturesNode.js new file mode 100644 index 00000000000000..da8133ab286183 --- /dev/null +++ b/examples/jsm/nodes/utils/TriplanarTexturesNode.js @@ -0,0 +1,51 @@ +import Node from '../core/Node.js'; +import { float, vec3, add, mul, div, dot, normalize, abs, texture, positionWorld, normalWorld } from '../shadernode/ShaderNodeBaseElements.js'; + +class TriplanarTexturesNode extends Node { + + constructor( textureXNode, textureYNode = null, textureZNode = null, scaleNode = float( 1 ), positionNode = positionWorld, normalNode = normalWorld ) { + + super( 'vec4' ); + + this.textureXNode = textureXNode; + this.textureYNode = textureYNode; + this.textureZNode = textureZNode; + + this.scaleNode = scaleNode; + + this.positionNode = positionNode; + this.normalNode = normalNode; + + } + + construct() { + + const { textureXNode, textureYNode, textureZNode, scaleNode, positionNode, normalNode } = this; + + // Ref: https://github.com/keijiro/StandardTriplanar + + // Blending factor of triplanar mapping + let bf = normalize( abs( normalNode ) ); + bf = div( bf, dot( bf, vec3( 1.0 ) ) ); + + // Triplanar mapping + const tx = mul( positionNode.yz, scaleNode ); + const ty = mul( positionNode.zx, scaleNode ); + const tz = mul( positionNode.xy, scaleNode ); + + // Base color + const textureX = textureXNode.value; + const textureY = textureYNode !== null ? textureYNode.value : textureX; + const textureZ = textureZNode !== null ? textureZNode.value : textureX; + + const cx = mul( texture( textureX, tx ), bf.x ); + const cy = mul( texture( textureY, ty ), bf.y ); + const cz = mul( texture( textureZ, tz ), bf.z ); + + return add( cx, cy, cz ); + + } + +} + +export default TriplanarTexturesNode; diff --git a/examples/jsm/objects/Reflector.js b/examples/jsm/objects/Reflector.js index 6dae121053a568..909d21ee36373f 100644 --- a/examples/jsm/objects/Reflector.js +++ b/examples/jsm/objects/Reflector.js @@ -8,7 +8,10 @@ import { UniformsUtils, Vector3, Vector4, - WebGLRenderTarget + WebGLRenderTarget, + HalfFloatType, + NoToneMapping, + LinearEncoding } from 'three'; class Reflector extends Mesh { @@ -48,7 +51,7 @@ class Reflector extends Mesh { const textureMatrix = new Matrix4(); const virtualCamera = this.camera; - const renderTarget = new WebGLRenderTarget( textureWidth, textureHeight, { samples: multisample } ); + const renderTarget = new WebGLRenderTarget( textureWidth, textureHeight, { samples: multisample, type: HalfFloatType } ); const material = new ShaderMaterial( { uniforms: UniformsUtils.clone( shader.uniforms ), @@ -137,18 +140,19 @@ class Reflector extends Mesh { projectionMatrix.elements[ 14 ] = clipPlane.w; // Render - - renderTarget.texture.encoding = renderer.outputEncoding; - scope.visible = false; const currentRenderTarget = renderer.getRenderTarget(); const currentXrEnabled = renderer.xr.enabled; const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate; + const currentOutputEncoding = renderer.outputEncoding; + const currentToneMapping = renderer.toneMapping; renderer.xr.enabled = false; // Avoid camera modification renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows + renderer.outputEncoding = LinearEncoding; + renderer.toneMapping = NoToneMapping; renderer.setRenderTarget( renderTarget ); @@ -159,6 +163,8 @@ class Reflector extends Mesh { renderer.xr.enabled = currentXrEnabled; renderer.shadowMap.autoUpdate = currentShadowAutoUpdate; + renderer.outputEncoding = currentOutputEncoding; + renderer.toneMapping = currentToneMapping; renderer.setRenderTarget( currentRenderTarget ); @@ -254,6 +260,7 @@ Reflector.ReflectorShader = { vec4 base = texture2DProj( tDiffuse, vUv ); gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 ); + #include #include }` diff --git a/examples/jsm/objects/ReflectorForSSRPass.js b/examples/jsm/objects/ReflectorForSSRPass.js index ea4fa384661f02..fd5fc0b0fcce6f 100644 --- a/examples/jsm/objects/ReflectorForSSRPass.js +++ b/examples/jsm/objects/ReflectorForSSRPass.js @@ -11,7 +11,8 @@ import { DepthTexture, UnsignedShortType, NearestFilter, - Plane + Plane, + HalfFloatType } from 'three'; class ReflectorForSSRPass extends Mesh { @@ -104,6 +105,7 @@ class ReflectorForSSRPass extends Mesh { const parameters = { depthTexture: useDepthTexture ? depthTexture : null, + type: HalfFloatType }; const renderTarget = new WebGLRenderTarget( textureWidth, textureHeight, parameters ); @@ -198,10 +200,6 @@ class ReflectorForSSRPass extends Mesh { textureMatrix.multiply( virtualCamera.matrixWorldInverse ); textureMatrix.multiply( scope.matrixWorld ); - // Render - - renderTarget.texture.encoding = renderer.outputEncoding; - // scope.visible = false; const currentRenderTarget = renderer.getRenderTarget(); diff --git a/examples/jsm/objects/Refractor.js b/examples/jsm/objects/Refractor.js index c31b15b64125b8..1179bf05fed905 100644 --- a/examples/jsm/objects/Refractor.js +++ b/examples/jsm/objects/Refractor.js @@ -9,7 +9,10 @@ import { UniformsUtils, Vector3, Vector4, - WebGLRenderTarget + WebGLRenderTarget, + LinearEncoding, + NoToneMapping, + HalfFloatType } from 'three'; class Refractor extends Mesh { @@ -45,7 +48,7 @@ class Refractor extends Mesh { // render target - const renderTarget = new WebGLRenderTarget( textureWidth, textureHeight, { samples: multisample } ); + const renderTarget = new WebGLRenderTarget( textureWidth, textureHeight, { samples: multisample, type: HalfFloatType } ); // material @@ -191,9 +194,13 @@ class Refractor extends Mesh { const currentRenderTarget = renderer.getRenderTarget(); const currentXrEnabled = renderer.xr.enabled; const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate; + const currentOutputEncoding = renderer.outputEncoding; + const currentToneMapping = renderer.toneMapping; renderer.xr.enabled = false; // avoid camera modification renderer.shadowMap.autoUpdate = false; // avoid re-computing shadows + renderer.outputEncoding = LinearEncoding; + renderer.toneMapping = NoToneMapping; renderer.setRenderTarget( renderTarget ); if ( renderer.autoClear === false ) renderer.clear(); @@ -201,6 +208,8 @@ class Refractor extends Mesh { renderer.xr.enabled = currentXrEnabled; renderer.shadowMap.autoUpdate = currentShadowAutoUpdate; + renderer.outputEncoding = currentOutputEncoding; + renderer.toneMapping = currentToneMapping; renderer.setRenderTarget( currentRenderTarget ); // restore viewport @@ -221,10 +230,6 @@ class Refractor extends Mesh { this.onBeforeRender = function ( renderer, scene, camera ) { - // Render - - renderTarget.texture.encoding = renderer.outputEncoding; - // ensure refractors are rendered only once per frame if ( camera.userData.refractor === true ) return; @@ -317,6 +322,7 @@ Refractor.RefractorShader = { vec4 base = texture2DProj( tDiffuse, vUv ); gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 ); + #include #include }` diff --git a/examples/jsm/package.json b/examples/jsm/package.json deleted file mode 100644 index 472002573ef7ac..00000000000000 --- a/examples/jsm/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} diff --git a/examples/jsm/postprocessing/AfterimagePass.js b/examples/jsm/postprocessing/AfterimagePass.js index f9c5e42ed805b1..e1233b201178e4 100644 --- a/examples/jsm/postprocessing/AfterimagePass.js +++ b/examples/jsm/postprocessing/AfterimagePass.js @@ -30,7 +30,7 @@ class AfterimagePass extends Pass { magFilter: NearestFilter, } ); - this.shaderMaterial = new ShaderMaterial( { + this.compFsMaterial = new ShaderMaterial( { uniforms: this.uniforms, vertexShader: this.shader.vertexShader, @@ -38,10 +38,10 @@ class AfterimagePass extends Pass { } ); - this.compFsQuad = new FullScreenQuad( this.shaderMaterial ); + this.compFsQuad = new FullScreenQuad( this.compFsMaterial ); - const material = new MeshBasicMaterial(); - this.copyFsQuad = new FullScreenQuad( material ); + this.copyFsMaterial = new MeshBasicMaterial(); + this.copyFsQuad = new FullScreenQuad( this.copyFsMaterial ); } @@ -85,6 +85,19 @@ class AfterimagePass extends Pass { } + dispose() { + + this.textureComp.dispose(); + this.textureOld.dispose(); + + this.compFsMaterial.dispose(); + this.copyFsMaterial.dispose(); + + this.compFsQuad.dispose(); + this.copyFsQuad.dispose(); + + } + } export { AfterimagePass }; diff --git a/examples/jsm/postprocessing/BloomPass.js b/examples/jsm/postprocessing/BloomPass.js index 6d03998b4c5127..606a001e89921d 100644 --- a/examples/jsm/postprocessing/BloomPass.js +++ b/examples/jsm/postprocessing/BloomPass.js @@ -10,15 +10,15 @@ import { ConvolutionShader } from '../shaders/ConvolutionShader.js'; class BloomPass extends Pass { - constructor( strength = 1, kernelSize = 25, sigma = 4, resolution = 256 ) { + constructor( strength = 1, kernelSize = 25, sigma = 4 ) { super(); // render targets - this.renderTargetX = new WebGLRenderTarget( resolution, resolution ); + this.renderTargetX = new WebGLRenderTarget(); // will be resized later this.renderTargetX.texture.name = 'BloomPass.x'; - this.renderTargetY = new WebGLRenderTarget( resolution, resolution ); + this.renderTargetY = new WebGLRenderTarget(); // will be resized later this.renderTargetY.texture.name = 'BloomPass.y'; // combine material @@ -105,6 +105,25 @@ class BloomPass extends Pass { } + setSize( width, height ) { + + this.renderTargetX.setSize( width, height ); + this.renderTargetY.setSize( width, height ); + + } + + dispose() { + + this.renderTargetX.dispose(); + this.renderTargetY.dispose(); + + this.materialCombine.dispose(); + this.materialConvolution.dispose(); + + this.fsQuad.dispose(); + + } + } const CombineShader = { diff --git a/examples/jsm/postprocessing/BokehPass.js b/examples/jsm/postprocessing/BokehPass.js index a825f2615b0e85..b51161bbade311 100644 --- a/examples/jsm/postprocessing/BokehPass.js +++ b/examples/jsm/postprocessing/BokehPass.js @@ -31,10 +31,7 @@ class BokehPass extends Pass { // render targets - const width = params.width || window.innerWidth || 1; - const height = params.height || window.innerHeight || 1; - - this.renderTargetDepth = new WebGLRenderTarget( width, height, { + this.renderTargetDepth = new WebGLRenderTarget( 1, 1, { // will be resized later minFilter: NearestFilter, magFilter: NearestFilter } ); @@ -126,6 +123,23 @@ class BokehPass extends Pass { } + setSize( width, height ) { + + this.renderTargetDepth.setSize( width, height ); + + } + + dispose() { + + this.renderTargetDepth.dispose(); + + this.materialDepth.dispose(); + this.materialBokeh.dispose(); + + this.fsQuad.dispose(); + + } + } export { BokehPass }; diff --git a/examples/jsm/postprocessing/CubeTexturePass.js b/examples/jsm/postprocessing/CubeTexturePass.js index 4e7f8f3328d557..ff9b1f6e481cbc 100644 --- a/examples/jsm/postprocessing/CubeTexturePass.js +++ b/examples/jsm/postprocessing/CubeTexturePass.js @@ -12,7 +12,7 @@ import { Pass } from './Pass.js'; class CubeTexturePass extends Pass { - constructor( camera, envMap, opacity = 1 ) { + constructor( camera, tCube, opacity = 1 ) { super(); @@ -37,13 +37,13 @@ class CubeTexturePass extends Pass { get: function () { - return this.uniforms.envMap.value; + return this.uniforms.tCube.value; } } ); - this.envMap = envMap; + this.tCube = tCube; this.opacity = opacity; this.cubeScene = new Scene(); @@ -60,8 +60,8 @@ class CubeTexturePass extends Pass { this.cubeCamera.projectionMatrix.copy( this.camera.projectionMatrix ); this.cubeCamera.quaternion.setFromRotationMatrix( this.camera.matrixWorld ); - this.cubeMesh.material.uniforms.envMap.value = this.envMap; - this.cubeMesh.material.uniforms.flipEnvMap.value = ( this.envMap.isCubeTexture && this.envMap.isRenderTargetTexture === false ) ? - 1 : 1; + this.cubeMesh.material.uniforms.tCube.value = this.tCube; + this.cubeMesh.material.uniforms.tFlip.value = ( this.tCube.isCubeTexture && this.tCube.isRenderTargetTexture === false ) ? - 1 : 1; this.cubeMesh.material.uniforms.opacity.value = this.opacity; this.cubeMesh.material.transparent = ( this.opacity < 1.0 ); @@ -73,6 +73,13 @@ class CubeTexturePass extends Pass { } + dispose() { + + this.cubeMesh.geometry.dispose(); + this.cubeMesh.material.dispose(); + + } + } export { CubeTexturePass }; diff --git a/examples/jsm/postprocessing/DotScreenPass.js b/examples/jsm/postprocessing/DotScreenPass.js index fc357e4abcf70a..561b3343d95422 100644 --- a/examples/jsm/postprocessing/DotScreenPass.js +++ b/examples/jsm/postprocessing/DotScreenPass.js @@ -53,6 +53,14 @@ class DotScreenPass extends Pass { } + dispose() { + + this.material.dispose(); + + this.fsQuad.dispose(); + + } + } export { DotScreenPass }; diff --git a/examples/jsm/postprocessing/EffectComposer.js b/examples/jsm/postprocessing/EffectComposer.js index 962615d8aab190..3f42bbde790005 100644 --- a/examples/jsm/postprocessing/EffectComposer.js +++ b/examples/jsm/postprocessing/EffectComposer.js @@ -232,6 +232,15 @@ class EffectComposer { } + dispose() { + + this.renderTarget1.dispose(); + this.renderTarget2.dispose(); + + this.copyPass.dispose(); + + } + } diff --git a/examples/jsm/postprocessing/FilmPass.js b/examples/jsm/postprocessing/FilmPass.js index ca31652bd5dbe7..8ebde536109a79 100644 --- a/examples/jsm/postprocessing/FilmPass.js +++ b/examples/jsm/postprocessing/FilmPass.js @@ -54,6 +54,14 @@ class FilmPass extends Pass { } + dispose() { + + this.material.dispose(); + + this.fsQuad.dispose(); + + } + } export { FilmPass }; diff --git a/examples/jsm/postprocessing/GlitchPass.js b/examples/jsm/postprocessing/GlitchPass.js index 85e975d73818c0..3ff5631f0c9aeb 100644 --- a/examples/jsm/postprocessing/GlitchPass.js +++ b/examples/jsm/postprocessing/GlitchPass.js @@ -22,7 +22,9 @@ class GlitchPass extends Pass { this.uniforms = UniformsUtils.clone( shader.uniforms ); - this.uniforms[ 'tDisp' ].value = this.generateHeightmap( dt_size ); + this.heightMap = this.generateHeightmap( dt_size ); + + this.uniforms[ 'tDisp' ].value = this.heightMap; this.material = new ShaderMaterial( { uniforms: this.uniforms, @@ -113,6 +115,16 @@ class GlitchPass extends Pass { } + dispose() { + + this.material.dispose(); + + this.heightMap.dispose(); + + this.fsQuad.dispose(); + + } + } export { GlitchPass }; diff --git a/examples/jsm/postprocessing/HalftonePass.js b/examples/jsm/postprocessing/HalftonePass.js index d37bd6755d5a71..6fe6e05347aef2 100644 --- a/examples/jsm/postprocessing/HalftonePass.js +++ b/examples/jsm/postprocessing/HalftonePass.js @@ -72,6 +72,14 @@ class HalftonePass extends Pass { } + dispose() { + + this.material.dispose(); + + this.fsQuad.dispose(); + + } + } export { HalftonePass }; diff --git a/examples/jsm/postprocessing/OutlinePass.js b/examples/jsm/postprocessing/OutlinePass.js index 4a86f7cbe418ec..4a6fcd8431bdd0 100644 --- a/examples/jsm/postprocessing/OutlinePass.js +++ b/examples/jsm/postprocessing/OutlinePass.js @@ -140,6 +140,16 @@ class OutlinePass extends Pass { this.renderTargetEdgeBuffer1.dispose(); this.renderTargetEdgeBuffer2.dispose(); + this.depthMaterial.dispose(); + this.prepareMaskMaterial.dispose(); + this.edgeDetectionMaterial.dispose(); + this.separableBlurMaterial1.dispose(); + this.separableBlurMaterial2.dispose(); + this.overlayMaterial.dispose(); + this.materialCopy.dispose(); + + this.fsQuad.dispose(); + } setSize( width, height ) { @@ -446,7 +456,17 @@ class OutlinePass extends Pass { #include vPosition = mvPosition; - vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 ); + + vec4 worldPosition = vec4( transformed, 1.0 ); + + #ifdef USE_INSTANCING + + worldPosition = instanceMatrix * worldPosition; + + #endif + + worldPosition = modelMatrix * worldPosition; + projTexCoord = textureMatrix * worldPosition; }`, diff --git a/examples/jsm/postprocessing/Pass.js b/examples/jsm/postprocessing/Pass.js index c3bf9d9b84ec46..2a54cd35c10196 100644 --- a/examples/jsm/postprocessing/Pass.js +++ b/examples/jsm/postprocessing/Pass.js @@ -31,6 +31,8 @@ class Pass { } + dispose() {} + } // Helper for passes that need to fill the viewport with a single quad. diff --git a/examples/jsm/postprocessing/RenderPixelatedPass.js b/examples/jsm/postprocessing/RenderPixelatedPass.js new file mode 100644 index 00000000000000..87096539fc0649 --- /dev/null +++ b/examples/jsm/postprocessing/RenderPixelatedPass.js @@ -0,0 +1,234 @@ +import { + WebGLRenderTarget, + MeshNormalMaterial, + ShaderMaterial, + Vector2, + Vector4, + DepthTexture, + NearestFilter +} from 'three'; +import { Pass, FullScreenQuad } from './Pass.js'; + +class RenderPixelatedPass extends Pass { + + constructor( pixelSize, scene, camera, options = {} ) { + + super(); + + this.pixelSize = pixelSize; + this.resolution = new Vector2(); + this.renderResolution = new Vector2(); + + this.pixelatedMaterial = this.createPixelatedMaterial(); + this.normalMaterial = new MeshNormalMaterial(); + + this.fsQuad = new FullScreenQuad( this.pixelatedMaterial ); + this.scene = scene; + this.camera = camera; + + this.normalEdgeStrength = options.normalEdgeStrength || 0.3; + this.depthEdgeStrength = options.depthEdgeStrength || 0.4; + + this.beautyRenderTarget = new WebGLRenderTarget(); + this.beautyRenderTarget.texture.minFilter = NearestFilter; + this.beautyRenderTarget.texture.magFilter = NearestFilter; + this.beautyRenderTarget.depthTexture = new DepthTexture(); + + this.normalRenderTarget = new WebGLRenderTarget(); + this.normalRenderTarget.texture.minFilter = NearestFilter; + this.normalRenderTarget.texture.magFilter = NearestFilter; + + + + } + + dispose() { + + this.beautyRenderTarget.dispose(); + this.normalRenderTarget.dispose(); + + this.pixelatedMaterial.dispose(); + this.normalMaterial.dispose(); + + this.fsQuad.dispose(); + + } + + setSize( width, height ) { + + this.resolution.set( width, height ); + this.renderResolution.set( ( width / this.pixelSize ) | 0, ( height / this.pixelSize ) | 0 ); + const { x, y } = this.renderResolution; + this.beautyRenderTarget.setSize( x, y ); + this.normalRenderTarget.setSize( x, y ); + this.fsQuad.material.uniforms.resolution.value.set( x, y, 1 / x, 1 / y ); + + } + + setPixelSize( pixelSize ) { + + this.pixelSize = pixelSize; + this.setSize( this.resolution.x, this.resolution.y ); + + } + + render( renderer, writeBuffer ) { + + const uniforms = this.fsQuad.material.uniforms; + uniforms.normalEdgeStrength.value = this.normalEdgeStrength; + uniforms.depthEdgeStrength.value = this.depthEdgeStrength; + + renderer.setRenderTarget( this.beautyRenderTarget ); + renderer.render( this.scene, this.camera ); + + const overrideMaterial_old = this.scene.overrideMaterial; + renderer.setRenderTarget( this.normalRenderTarget ); + this.scene.overrideMaterial = this.normalMaterial; + renderer.render( this.scene, this.camera ); + this.scene.overrideMaterial = overrideMaterial_old; + + uniforms.tDiffuse.value = this.beautyRenderTarget.texture; + uniforms.tDepth.value = this.beautyRenderTarget.depthTexture; + uniforms.tNormal.value = this.normalRenderTarget.texture; + + if ( this.renderToScreen ) { + + renderer.setRenderTarget( null ); + + } else { + + renderer.setRenderTarget( writeBuffer ); + + if ( this.clear ) renderer.clear(); + + } + + this.fsQuad.render( renderer ); + + } + + createPixelatedMaterial() { + + return new ShaderMaterial( { + uniforms: { + tDiffuse: { value: null }, + tDepth: { value: null }, + tNormal: { value: null }, + resolution: { + value: new Vector4( + this.renderResolution.x, + this.renderResolution.y, + 1 / this.renderResolution.x, + 1 / this.renderResolution.y, + ) + }, + normalEdgeStrength: { value: 0 }, + depthEdgeStrength: { value: 0 } + }, + vertexShader: /* glsl */` + varying vec2 vUv; + + void main() { + + vUv = uv; + gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); + + } + `, + fragmentShader: /* glsl */` + uniform sampler2D tDiffuse; + uniform sampler2D tDepth; + uniform sampler2D tNormal; + uniform vec4 resolution; + uniform float normalEdgeStrength; + uniform float depthEdgeStrength; + varying vec2 vUv; + + float getDepth(int x, int y) { + + return texture2D( tDepth, vUv + vec2(x, y) * resolution.zw ).r; + + } + + vec3 getNormal(int x, int y) { + + return texture2D( tNormal, vUv + vec2(x, y) * resolution.zw ).rgb * 2.0 - 1.0; + + } + + float depthEdgeIndicator(float depth, vec3 normal) { + + float diff = 0.0; + diff += clamp(getDepth(1, 0) - depth, 0.0, 1.0); + diff += clamp(getDepth(-1, 0) - depth, 0.0, 1.0); + diff += clamp(getDepth(0, 1) - depth, 0.0, 1.0); + diff += clamp(getDepth(0, -1) - depth, 0.0, 1.0); + return floor(smoothstep(0.01, 0.02, diff) * 2.) / 2.; + + } + + float neighborNormalEdgeIndicator(int x, int y, float depth, vec3 normal) { + + float depthDiff = getDepth(x, y) - depth; + vec3 neighborNormal = getNormal(x, y); + + // Edge pixels should yield to faces who's normals are closer to the bias normal. + vec3 normalEdgeBias = vec3(1., 1., 1.); // This should probably be a parameter. + float normalDiff = dot(normal - neighborNormal, normalEdgeBias); + float normalIndicator = clamp(smoothstep(-.01, .01, normalDiff), 0.0, 1.0); + + // Only the shallower pixel should detect the normal edge. + float depthIndicator = clamp(sign(depthDiff * .25 + .0025), 0.0, 1.0); + + return (1.0 - dot(normal, neighborNormal)) * depthIndicator * normalIndicator; + + } + + float normalEdgeIndicator(float depth, vec3 normal) { + + float indicator = 0.0; + + indicator += neighborNormalEdgeIndicator(0, -1, depth, normal); + indicator += neighborNormalEdgeIndicator(0, 1, depth, normal); + indicator += neighborNormalEdgeIndicator(-1, 0, depth, normal); + indicator += neighborNormalEdgeIndicator(1, 0, depth, normal); + + return step(0.1, indicator); + + } + + void main() { + + vec4 texel = texture2D( tDiffuse, vUv ); + + float depth = 0.0; + vec3 normal = vec3(0.0); + + if (depthEdgeStrength > 0.0 || normalEdgeStrength > 0.0) { + + depth = getDepth(0, 0); + normal = getNormal(0, 0); + + } + + float dei = 0.0; + if (depthEdgeStrength > 0.0) + dei = depthEdgeIndicator(depth, normal); + + float nei = 0.0; + if (normalEdgeStrength > 0.0) + nei = normalEdgeIndicator(depth, normal); + + float Strength = dei > 0.0 ? (1.0 - depthEdgeStrength * dei) : (1.0 + normalEdgeStrength * nei); + + gl_FragColor = texel * Strength; + + } + ` + } ); + + } + +} + +export { RenderPixelatedPass }; diff --git a/examples/jsm/postprocessing/SAOPass.js b/examples/jsm/postprocessing/SAOPass.js index e5bd89fd7e3d65..0c7e0a46de500a 100644 --- a/examples/jsm/postprocessing/SAOPass.js +++ b/examples/jsm/postprocessing/SAOPass.js @@ -400,6 +400,26 @@ class SAOPass extends Pass { } + dispose() { + + this.saoRenderTarget.dispose(); + this.blurIntermediateRenderTarget.dispose(); + this.beautyRenderTarget.dispose(); + this.normalRenderTarget.dispose(); + this.depthRenderTarget.dispose(); + + this.depthMaterial.dispose(); + this.normalMaterial.dispose(); + this.saoMaterial.dispose(); + this.vBlurMaterial.dispose(); + this.hBlurMaterial.dispose(); + this.materialCopy.dispose(); + this.depthCopy.dispose(); + + this.fsQuad.dispose(); + + } + } SAOPass.OUTPUT = { diff --git a/examples/jsm/postprocessing/SMAAPass.js b/examples/jsm/postprocessing/SMAAPass.js index 8f62c3941c2027..609ff11f679a1d 100644 --- a/examples/jsm/postprocessing/SMAAPass.js +++ b/examples/jsm/postprocessing/SMAAPass.js @@ -183,6 +183,22 @@ class SMAAPass extends Pass { } + dispose() { + + this.edgesRT.dispose(); + this.weightsRT.dispose(); + + this.areaTexture.dispose(); + this.searchTexture.dispose(); + + this.materialEdges.dispose(); + this.materialWeights.dispose(); + this.materialBlend.dispose(); + + this.fsQuad.dispose(); + + } + } export { SMAAPass }; diff --git a/examples/jsm/postprocessing/SSAARenderPass.js b/examples/jsm/postprocessing/SSAARenderPass.js index 5af6ae047d23d3..2ac75074eb7172 100644 --- a/examples/jsm/postprocessing/SSAARenderPass.js +++ b/examples/jsm/postprocessing/SSAARenderPass.js @@ -63,6 +63,10 @@ class SSAARenderPass extends Pass { } + this.copyMaterial.dispose(); + + this.fsQuad.dispose(); + } setSize( width, height ) { diff --git a/examples/jsm/postprocessing/SavePass.js b/examples/jsm/postprocessing/SavePass.js index ff4d6f32e888a6..c351583eecc749 100644 --- a/examples/jsm/postprocessing/SavePass.js +++ b/examples/jsm/postprocessing/SavePass.js @@ -32,7 +32,7 @@ class SavePass extends Pass { if ( this.renderTarget === undefined ) { - this.renderTarget = new WebGLRenderTarget( window.innerWidth, window.innerHeight ); + this.renderTarget = new WebGLRenderTarget(); // will be resized later this.renderTarget.texture.name = 'SavePass.rt'; } @@ -57,6 +57,22 @@ class SavePass extends Pass { } + setSize( width, height ) { + + this.renderTarget.setSize( width, height ); + + } + + dispose() { + + this.renderTarget.dispose(); + + this.material.dispose(); + + this.fsQuad.dispose(); + + } + } export { SavePass }; diff --git a/examples/jsm/postprocessing/ShaderPass.js b/examples/jsm/postprocessing/ShaderPass.js index 3cc2f5434577ef..0fa61782675bbe 100644 --- a/examples/jsm/postprocessing/ShaderPass.js +++ b/examples/jsm/postprocessing/ShaderPass.js @@ -63,6 +63,14 @@ class ShaderPass extends Pass { } + dispose() { + + this.material.dispose(); + + this.fsQuad.dispose(); + + } + } export { ShaderPass }; diff --git a/examples/jsm/postprocessing/TAARenderPass.js b/examples/jsm/postprocessing/TAARenderPass.js index 05126a1ad28d6c..6a7180ae840de0 100644 --- a/examples/jsm/postprocessing/TAARenderPass.js +++ b/examples/jsm/postprocessing/TAARenderPass.js @@ -130,6 +130,15 @@ class TAARenderPass extends SSAARenderPass { } + dispose() { + + super.dispose(); + + if ( this.sampleRenderTarget !== undefined ) this.sampleRenderTarget.dispose(); + if ( this.holdRenderTarget !== undefined ) this.holdRenderTarget.dispose(); + + } + } const _JitterVectors = [ diff --git a/examples/jsm/postprocessing/TexturePass.js b/examples/jsm/postprocessing/TexturePass.js index aac112b93d05df..3abfcb7a2f67ba 100644 --- a/examples/jsm/postprocessing/TexturePass.js +++ b/examples/jsm/postprocessing/TexturePass.js @@ -55,6 +55,14 @@ class TexturePass extends Pass { } + dispose() { + + this.material.dispose(); + + this.fsQuad.dispose(); + + } + } export { TexturePass }; diff --git a/examples/jsm/postprocessing/UnrealBloomPass.js b/examples/jsm/postprocessing/UnrealBloomPass.js index 35bcc484980240..7572278093ff9f 100644 --- a/examples/jsm/postprocessing/UnrealBloomPass.js +++ b/examples/jsm/postprocessing/UnrealBloomPass.js @@ -170,6 +170,22 @@ class UnrealBloomPass extends Pass { this.renderTargetBright.dispose(); + // + + for ( let i = 0; i < this.separableBlurMaterials.length; i ++ ) { + + this.separableBlurMaterials[ i ].dispose(); + + } + + this.compositeMaterial.dispose(); + this.materialCopy.dispose(); + this.basic.dispose(); + + // + + this.fsQuad.dispose(); + } setSize( width, height ) { diff --git a/examples/jsm/renderers/CSS2DRenderer.js b/examples/jsm/renderers/CSS2DRenderer.js index f50959e3e5efec..a1dfc40f8415f5 100644 --- a/examples/jsm/renderers/CSS2DRenderer.js +++ b/examples/jsm/renderers/CSS2DRenderer.js @@ -85,8 +85,8 @@ class CSS2DRenderer { this.render = function ( scene, camera ) { - if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); - if ( camera.parent === null ) camera.updateMatrixWorld(); + if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld(); + if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld(); _viewMatrix.copy( camera.matrixWorldInverse ); _viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, _viewMatrix ); diff --git a/examples/jsm/renderers/CSS3DRenderer.js b/examples/jsm/renderers/CSS3DRenderer.js index 0a9ea585821069..42ebd1ee7f5927 100644 --- a/examples/jsm/renderers/CSS3DRenderer.js +++ b/examples/jsm/renderers/CSS3DRenderer.js @@ -132,8 +132,8 @@ class CSS3DRenderer { } - if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); - if ( camera.parent === null ) camera.updateMatrixWorld(); + if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld(); + if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld(); let tx, ty; diff --git a/examples/jsm/renderers/Projector.js b/examples/jsm/renderers/Projector.js index 55e899439add98..f80df799d42e66 100644 --- a/examples/jsm/renderers/Projector.js +++ b/examples/jsm/renderers/Projector.js @@ -155,28 +155,6 @@ class Projector { // - this.projectVector = function ( vector, camera ) { - - console.warn( 'THREE.Projector: .projectVector() is now vector.project().' ); - vector.project( camera ); - - }; - - this.unprojectVector = function ( vector, camera ) { - - console.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' ); - vector.unproject( camera ); - - }; - - this.pickingRay = function () { - - console.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' ); - - }; - - // - function RenderList() { const normals = []; @@ -433,8 +411,8 @@ class Projector { _renderData.elements.length = 0; - if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); - if ( camera.parent === null ) camera.updateMatrixWorld(); + if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld(); + if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld(); _viewMatrix.copy( camera.matrixWorldInverse ); _viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, _viewMatrix ); diff --git a/examples/jsm/renderers/webgl/nodes/SlotNode.js b/examples/jsm/renderers/webgl/nodes/SlotNode.js index fbabcd37afcb16..497385cd6b034a 100644 --- a/examples/jsm/renderers/webgl/nodes/SlotNode.js +++ b/examples/jsm/renderers/webgl/nodes/SlotNode.js @@ -1,13 +1,17 @@ -import Node from 'three-nodes/core/Node.js'; +import { Node } from 'three/nodes'; class SlotNode extends Node { - constructor( node, name, nodeType ) { + constructor( params ) { - super( nodeType ); + super( params.nodeType ); - this.node = node; - this.name = name; + this.node = null; + this.source = null; + this.target = null; + this.inclusionType = 'replace'; + + Object.assign( this, params ); } diff --git a/examples/jsm/renderers/webgl/nodes/WebGLNodeBuilder.js b/examples/jsm/renderers/webgl/nodes/WebGLNodeBuilder.js index bde7bd17d9d9a5..403f1aa083ef60 100644 --- a/examples/jsm/renderers/webgl/nodes/WebGLNodeBuilder.js +++ b/examples/jsm/renderers/webgl/nodes/WebGLNodeBuilder.js @@ -1,11 +1,6 @@ -import NodeBuilder, { defaultShaderStages } from 'three-nodes/core/NodeBuilder.js'; -import NodeFrame from 'three-nodes/core/NodeFrame.js'; +import { defaultShaderStages, NodeFrame, MathNode, GLSLNodeParser, NodeBuilder } from 'three/nodes'; import SlotNode from './SlotNode.js'; -import GLSLNodeParser from 'three-nodes/parsers/GLSLNodeParser.js'; -import WebGLPhysicalContextNode from './WebGLPhysicalContextNode.js'; - -import { PerspectiveCamera, ShaderChunk, ShaderLib, UniformsUtils, UniformsLib, - LinearEncoding, RGBAFormat, UnsignedByteType, sRGBEncoding } from 'three'; +import { PerspectiveCamera, ShaderChunk, ShaderLib, UniformsUtils, UniformsLib } from 'three'; const nodeFrame = new NodeFrame(); nodeFrame.camera = new PerspectiveCamera(); @@ -15,7 +10,11 @@ const nodeShaderLib = { MeshBasicNodeMaterial: ShaderLib.basic, PointsNodeMaterial: ShaderLib.points, MeshStandardNodeMaterial: ShaderLib.standard, - MeshPhysicalMaterial: ShaderLib.physical + MeshPhysicalNodeMaterial: ShaderLib.physical +}; + +const glslMethods = { + [ MathNode.ATAN2 ]: 'atan' }; function getIncludeSnippet( name ) { @@ -39,16 +38,24 @@ class WebGLNodeBuilder extends NodeBuilder { this.shader = shader; this.slots = { vertex: [], fragment: [] }; + this._parseShaderLib(); + this._parseInclude( 'fragment', 'lights_physical_fragment', 'clearcoat_normal_fragment_begin', 'transmission_fragment' ); this._parseObject(); + this._sortSlotsToFlow(); + + } + + getMethod( method ) { + + return glslMethods[ method ] || method; + } addSlot( shaderStage, slotNode ) { this.slots[ shaderStage ].push( slotNode ); - return this.addFlow( shaderStage, slotNode ); - } addFlowCode( code ) { @@ -63,20 +70,22 @@ class WebGLNodeBuilder extends NodeBuilder { } - _parseObject() { + _parseShaderLib() { - const { material, renderer } = this; + const material = this.material; let type = material.type; - // shader lib + // see https://github.com/mrdoob/three.js/issues/23707 - if ( material.isMeshPhysicalNodeMaterial ) type = 'MeshPhysicalMaterial'; + if ( material.isMeshPhysicalNodeMaterial ) type = 'MeshPhysicalNodeMaterial'; else if ( material.isMeshStandardNodeMaterial ) type = 'MeshStandardNodeMaterial'; else if ( material.isMeshBasicNodeMaterial ) type = 'MeshBasicNodeMaterial'; else if ( material.isPointsNodeMaterial ) type = 'PointsNodeMaterial'; else if ( material.isLineBasicNodeMaterial ) type = 'LineBasicNodeMaterial'; + // shader lib + if ( nodeShaderLib[ type ] !== undefined ) { const shaderLib = nodeShaderLib[ type ]; @@ -88,9 +97,20 @@ class WebGLNodeBuilder extends NodeBuilder { } + } + + _parseObject() { + + const { material, renderer } = this; + if ( renderer.toneMappingNode?.isNode === true ) { - this.replaceCode( 'fragment', getIncludeSnippet( 'tonemapping_fragment' ), '' ); + this.addSlot( 'fragment', new SlotNode( { + node: material.colorNode, + nodeType: 'vec4', + source: getIncludeSnippet( 'tonemapping_fragment' ), + target: '' + } ) ); } @@ -98,123 +118,311 @@ class WebGLNodeBuilder extends NodeBuilder { if ( material.colorNode && material.colorNode.isNode ) { - this.addSlot( 'fragment', new SlotNode( material.colorNode, 'COLOR', 'vec4' ) ); + this.addSlot( 'fragment', new SlotNode( { + node: material.colorNode, + nodeType: 'vec4', + source: 'vec4 diffuseColor = vec4( diffuse, opacity );', + target: 'vec4 diffuseColor = %RESULT%;' + } ) ); } if ( material.opacityNode && material.opacityNode.isNode ) { - this.addSlot( 'fragment', new SlotNode( material.opacityNode, 'OPACITY', 'float' ) ); + this.addSlot( 'fragment', new SlotNode( { + node: material.opacityNode, + nodeType: 'float', + source: getIncludeSnippet( 'alphatest_fragment' ), + target: 'diffuseColor.a = %RESULT%;', + inclusionType: 'append' + } ) ); + + } else { + + this.addCode( 'fragment', getIncludeSnippet( 'alphatest_fragment' ), 'diffuseColor.a = opacity;', this.shader ); } if ( material.normalNode && material.normalNode.isNode ) { - this.addSlot( 'fragment', new SlotNode( material.normalNode, 'NORMAL', 'vec3' ) ); + this.addSlot( 'fragment', new SlotNode( { + node: material.normalNode, + nodeType: 'vec3', + source: getIncludeSnippet( 'normal_fragment_begin' ), + target: 'normal = %RESULT%;', + inclusionType: 'append' + } ) ); } if ( material.emissiveNode && material.emissiveNode.isNode ) { - this.addSlot( 'fragment', new SlotNode( material.emissiveNode, 'EMISSIVE', 'vec3' ) ); + this.addSlot( 'fragment', new SlotNode( { + node: material.emissiveNode, + nodeType: 'vec3', + source: getIncludeSnippet( 'emissivemap_fragment' ), + target: 'totalEmissiveRadiance = %RESULT%;', + inclusionType: 'append' + } ) ); } - if ( material.metalnessNode && material.metalnessNode.isNode ) { + if ( material.isMeshStandardNodeMaterial ) { - this.addSlot( 'fragment', new SlotNode( material.metalnessNode, 'METALNESS', 'float' ) ); + if ( material.metalnessNode && material.metalnessNode.isNode ) { - } + this.addSlot( 'fragment', new SlotNode( { + node: material.metalnessNode, + nodeType: 'float', + source: getIncludeSnippet( 'metalnessmap_fragment' ), + target: 'metalnessFactor = %RESULT%;', + inclusionType: 'append' + } ) ); - if ( material.roughnessNode && material.roughnessNode.isNode ) { + } - this.addSlot( 'fragment', new SlotNode( material.roughnessNode, 'ROUGHNESS', 'float' ) ); + if ( material.roughnessNode && material.roughnessNode.isNode ) { - } + this.addSlot( 'fragment', new SlotNode( { + node: material.roughnessNode, + nodeType: 'float', + source: getIncludeSnippet( 'roughnessmap_fragment' ), + target: 'roughnessFactor = %RESULT%;', + inclusionType: 'append' + } ) ); + + } + + if ( material.isMeshPhysicalNodeMaterial ) { + + if ( material.clearcoatNode && material.clearcoatNode.isNode ) { + + this.addSlot( 'fragment', new SlotNode( { + node: material.clearcoatNode, + nodeType: 'float', + source: 'material.clearcoat = clearcoat;', + target: 'material.clearcoat = %RESULT%;' + } ) ); + + if ( material.clearcoatRoughnessNode && material.clearcoatRoughnessNode.isNode ) { - if ( material.isMeshPhysicalNodeMaterial ) { + this.addSlot( 'fragment', new SlotNode( { + node: material.clearcoatRoughnessNode, + nodeType: 'float', + source: 'material.clearcoatRoughness = clearcoatRoughness;', + target: 'material.clearcoatRoughness = %RESULT%;' + } ) ); - if ( material.clearcoatNode && material.clearcoatNode.isNode ) { + } - this.addSlot( 'fragment', new SlotNode( material.clearcoatNode, 'CLEARCOAT', 'float' ) ); + if ( material.clearcoatNormalNode && material.clearcoatNormalNode.isNode ) { - if ( material.clearcoatRoughnessNode && material.clearcoatRoughnessNode.isNode ) { + this.addSlot( 'fragment', new SlotNode( { + node: material.clearcoatNormalNode, + nodeType: 'vec3', + source: 'vec3 clearcoatNormal = geometryNormal;', + target: 'vec3 clearcoatNormal = %RESULT%;' + } ) ); - this.addSlot( 'fragment', new SlotNode( material.clearcoatRoughnessNode, 'CLEARCOAT_ROUGHNESS', 'float' ) ); + } + + material.defines.USE_CLEARCOAT = ''; + + } else { + + delete material.defines.USE_CLEARCOAT; } - if ( material.clearcoatNormalNode && material.clearcoatNormalNode.isNode ) { + if ( material.sheenNode && material.sheenNode.isNode ) { + + this.addSlot( 'fragment', new SlotNode( { + node: material.sheenNode, + nodeType: 'vec3', + source: 'material.sheenColor = sheenColor;', + target: 'material.sheenColor = %RESULT%;' + } ) ); + + if ( material.sheenRoughnessNode && material.sheenRoughnessNode.isNode ) { - this.addSlot( 'fragment', new SlotNode( material.clearcoatNormalNode, 'CLEARCOAT_NORMAL', 'vec3' ) ); + this.addSlot( 'fragment', new SlotNode( { + node: material.sheenRoughnessNode, + nodeType: 'float', + source: 'material.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );', + target: 'material.sheenRoughness = clamp( %RESULT%, 0.07, 1.0 );' + } ) ); + + } + + material.defines.USE_SHEEN = ''; + + } else { + + delete material.defines.USE_SHEEN; } - material.defines.USE_CLEARCOAT = ''; + if ( material.iridescenceNode && material.iridescenceNode.isNode ) { - } else { + this.addSlot( 'fragment', new SlotNode( { + node: material.iridescenceNode, + nodeType: 'float', + source: 'material.iridescence = iridescence;', + target: 'material.iridescence = %RESULT%;' + } ) ); - delete material.defines.USE_CLEARCOAT; + if ( material.iridescenceIORNode && material.iridescenceIORNode.isNode ) { - } + this.addSlot( 'fragment', new SlotNode( { + node: material.iridescenceIORNode, + nodeType: 'float', + source: 'material.iridescenceIOR = iridescenceIOR;', + target: 'material.iridescenceIOR = %RESULT%;' + } ) ); + + } + + if ( material.iridescenceThicknessNode && material.iridescenceThicknessNode.isNode ) { - if ( material.sheenNode && material.sheenNode.isNode ) { + this.addSlot( 'fragment', new SlotNode( { + node: material.iridescenceThicknessNode, + nodeType: 'float', + source: 'material.iridescenceThickness = iridescenceThicknessMaximum;', + target: 'material.iridescenceThickness = %RESULT%;' + } ) ); - this.addSlot( 'fragment', new SlotNode( material.sheenNode, 'SHEEN', 'vec3' ) ); + } - if ( material.sheenRoughnessNode && material.sheenRoughnessNode.isNode ) { + material.defines.USE_IRIDESCENCE = ''; - this.addSlot( 'fragment', new SlotNode( material.sheenRoughnessNode, 'SHEEN_ROUGHNESS', 'float' ) ); + } else { + + delete material.defines.USE_IRIDESCENCE; } - material.defines.USE_SHEEN = ''; + if ( material.iorNode && material.iorNode.isNode ) { - } else { + this.addSlot( 'fragment', new SlotNode( { + node: material.iorNode, + nodeType: 'float', + source: 'material.ior = ior;', + target: 'material.ior = %RESULT%;' + } ) ); - delete material.defines.USE_SHEEN; + } - } + if ( material.specularColorNode && material.specularColorNode.isNode ) { - } + this.addSlot( 'fragment', new SlotNode( { + node: material.specularColorNode, + nodeType: 'vec3', + source: 'vec3 specularColorFactor = specularColor;', + target: 'vec3 specularColorFactor = %RESULT%;' + } ) ); - if ( material.iridescenceNode && material.iridescenceNode.isNode ) { + } - this.addSlot( 'fragment', new SlotNode( material.iridescenceNode, 'IRIDESCENCE', 'float' ) ); + if ( material.specularIntensityNode && material.specularIntensityNode.isNode ) { - } + this.addSlot( 'fragment', new SlotNode( { + node: material.specularIntensityNode, + nodeType: 'float', + source: 'float specularIntensityFactor = specularIntensity;', + target: 'float specularIntensityFactor = %RESULT%;' + } ) ); - if ( material.iridescenceIORNode && material.iridescenceIORNode.isNode ) { + } - this.addSlot( 'fragment', new SlotNode( material.iridescenceIORNode, 'IRIDESCENCE_IOR', 'float' ) ); + if ( material.transmissionNode && material.transmissionNode.isNode ) { - } + this.addSlot( 'fragment', new SlotNode( { + node: material.transmissionNode, + nodeType: 'float', + source: 'material.transmission = transmission;', + target: 'material.transmission = %RESULT%;' + } ) ); - if ( material.iridescenceThicknessNode && material.iridescenceThicknessNode.isNode ) { + if ( material.thicknessNode && material.thicknessNode.isNode ) { - this.addSlot( 'fragment', new SlotNode( material.iridescenceThicknessNode, 'IRIDESCENCE_THICKNESS', 'float' ) ); + this.addSlot( 'fragment', new SlotNode( { + node: material.thicknessNode, + nodeType: 'float', + source: 'material.thickness = thickness;', + target: 'material.thickness = %RESULT%;' + } ) ); - } + } + + if ( material.thicknessNode && material.thicknessNode.isNode ) { + + this.addSlot( 'fragment', new SlotNode( { + node: material.thicknessNode, + nodeType: 'float', + source: 'material.thickness = thickness;', + target: 'material.thickness = %RESULT%;' + } ) ); + + } + + if ( material.attenuationDistanceNode && material.attenuationDistanceNode.isNode ) { + + this.addSlot( 'fragment', new SlotNode( { + node: material.attenuationDistanceNode, + nodeType: 'float', + source: 'material.attenuationDistance = attenuationDistance;', + target: 'material.attenuationDistance = %RESULT%;' + } ) ); + + } + + if ( material.attenuationColorNode && material.attenuationColorNode.isNode ) { + + this.addSlot( 'fragment', new SlotNode( { + node: material.attenuationColorNode, + nodeType: 'vec3', + source: 'material.attenuationColor = attenuationColor;', + target: 'material.attenuationColor = %RESULT%;' + } ) ); - if ( material.envNode && material.envNode.isNode ) { + } - const envRadianceNode = new WebGLPhysicalContextNode( WebGLPhysicalContextNode.RADIANCE, material.envNode ); - const envIrradianceNode = new WebGLPhysicalContextNode( WebGLPhysicalContextNode.IRRADIANCE, material.envNode ); + material.transmission = 1; + material.defines.USE_TRANSMISSION = ''; - this.addSlot( 'fragment', new SlotNode( envRadianceNode, 'RADIANCE', 'vec3' ) ); - this.addSlot( 'fragment', new SlotNode( envIrradianceNode, 'IRRADIANCE', 'vec3' ) ); + } else { + + material.transmission = 0; + delete material.defines.USE_TRANSMISSION; + + } + + } } + // + if ( material.positionNode && material.positionNode.isNode ) { - this.addSlot( 'vertex', new SlotNode( material.positionNode, 'POSITION', 'vec3' ) ); + this.addSlot( 'vertex', new SlotNode( { + node: material.positionNode, + nodeType: 'vec3', + source: getIncludeSnippet( 'begin_vertex' ), + target: 'transformed = %RESULT%;', + inclusionType: 'append' + } ) ); } if ( material.sizeNode && material.sizeNode.isNode ) { - this.addSlot( 'vertex', new SlotNode( material.sizeNode, 'SIZE', 'float' ) ); + this.addSlot( 'vertex', new SlotNode( { + node: material.sizeNode, + nodeType: 'float', + source: 'gl_PointSize = size;', + target: 'gl_PointSize = %RESULT%;' + } ) ); } @@ -302,89 +510,82 @@ class WebGLNodeBuilder extends NodeBuilder { } - getVaryings( /* shaderStage */ ) { + getVaryings( shaderStage ) { let snippet = ''; const varyings = this.varyings; - for ( const varying of varyings ) { - - snippet += `varying ${varying.type} ${varying.name}; `; - - } + if ( shaderStage === 'vertex' ) { - return snippet; + for ( const varying of varyings ) { - } + snippet += `${varying.needsInterpolation ? 'varying' : '/*varying*/'} ${varying.type} ${varying.name}; `; - addCodeAfterSnippet( shaderStage, snippet, code ) { + } - const shaderProperty = getShaderStageProperty( shaderStage ); + } else if ( shaderStage === 'fragment' ) { - let source = this[ shaderProperty ]; + for ( const varying of varyings ) { - const index = source.indexOf( snippet ); + if ( varying.needsInterpolation ) { - if ( index !== - 1 ) { + snippet += `varying ${varying.type} ${varying.name}; `; - const start = source.substring( 0, index + snippet.length ); - const end = source.substring( index + snippet.length ); + } - source = `${start}\n${code}\n${end}`; + } } - this[ shaderProperty ] = source; + return snippet; } - addCodeAfterInclude( shaderStage, includeName, code ) { + addCode( shaderStage, source, code, scope = this ) { - const includeSnippet = getIncludeSnippet( includeName ); + const shaderProperty = getShaderStageProperty( shaderStage ); - this.addCodeAfterSnippet( shaderStage, includeSnippet, code ); + let snippet = scope[ shaderProperty ]; - } + const index = snippet.indexOf( source ); - replaceCode( shaderStage, source, target ) { + if ( index !== - 1 ) { - const shaderProperty = getShaderStageProperty( shaderStage ); + const start = snippet.substring( 0, index + source.length ); + const end = snippet.substring( index + source.length ); - this[ shaderProperty ] = this[ shaderProperty ].replaceAll( source, target ); + snippet = `${start}\n${code}\n${end}`; - } + } - parseInclude( shaderStage, ...includes ) { + scope[ shaderProperty ] = snippet; - for ( const name of includes ) { + } - const includeSnippet = getIncludeSnippet( name ); - const code = ShaderChunk[ name ]; + replaceCode( shaderStage, source, target, scope = this ) { - this.replaceCode( shaderStage, includeSnippet, code ); + const shaderProperty = getShaderStageProperty( shaderStage ); - } + scope[ shaderProperty ] = scope[ shaderProperty ].replaceAll( source, target ); } - getTextureEncodingFromMap( map ) { - - const isWebGL2 = this.renderer.capabilities.isWebGL2; + getFrontFacing() { - if ( isWebGL2 && map && map.isTexture && map.format === RGBAFormat && map.type === UnsignedByteType && map.encoding === sRGBEncoding ) { + return 'gl_FrontFacing'; - return LinearEncoding; // disable inline decode for sRGB textures in WebGL 2 + } - } + getFragCoord() { - return super.getTextureEncodingFromMap( map ); + return 'gl_FragCoord'; } - getFrontFacing() { + isFlipY() { - return 'gl_FrontFacing'; + return true; } @@ -446,211 +647,75 @@ ${this.shader[ getShaderStageProperty( shaderStage ) ]} } - getSlot( shaderStage, name ) { + _parseInclude( shaderStage, ...includes ) { - const slots = this.slots[ shaderStage ]; + for ( const name of includes ) { - for ( const node of slots ) { + const includeSnippet = getIncludeSnippet( name ); + const code = ShaderChunk[ name ]; - if ( node.name === name ) { + const shaderProperty = getShaderStageProperty( shaderStage ); - return this.getFlowData( node/*, shaderStage*/ ); - - } + this.shader[ shaderProperty ] = this.shader[ shaderProperty ].replaceAll( includeSnippet, code ); } } - _addSnippets() { - - this.parseInclude( 'fragment', 'lights_physical_fragment' ); - this.parseInclude( 'fragment', 'clearcoat_normal_fragment_begin' ); - - const colorSlot = this.getSlot( 'fragment', 'COLOR' ); - const opacityNode = this.getSlot( 'fragment', 'OPACITY' ); - const normalSlot = this.getSlot( 'fragment', 'NORMAL' ); - const emissiveNode = this.getSlot( 'fragment', 'EMISSIVE' ); - const roughnessNode = this.getSlot( 'fragment', 'ROUGHNESS' ); - const metalnessNode = this.getSlot( 'fragment', 'METALNESS' ); - const clearcoatNode = this.getSlot( 'fragment', 'CLEARCOAT' ); - const clearcoatRoughnessNode = this.getSlot( 'fragment', 'CLEARCOAT_ROUGHNESS' ); - const clearcoatNormalNode = this.getSlot( 'fragment', 'CLEARCOAT_NORMAL' ); - const sheenNode = this.getSlot( 'fragment', 'SHEEN' ); - const sheenRoughnessNode = this.getSlot( 'fragment', 'SHEEN_ROUGHNESS' ); - const iridescenceNode = this.getSlot( 'fragment', 'IRIDESCENCE' ); - const iridescenceIORNode = this.getSlot( 'fragment', 'IRIDESCENCE_IOR' ); - const iridescenceThicknessNode = this.getSlot( 'fragment', 'IRIDESCENCE_THICKNESS' ); - - const positionNode = this.getSlot( 'vertex', 'POSITION' ); - const sizeNode = this.getSlot( 'vertex', 'SIZE' ); - - if ( colorSlot !== undefined ) { - - this.addCodeAfterInclude( - 'fragment', - 'color_fragment', - `${colorSlot.code}\n\tdiffuseColor = ${colorSlot.result};` - ); - - } - - if ( opacityNode !== undefined ) { - - this.addCodeAfterInclude( - 'fragment', - 'alphatest_fragment', - `${opacityNode.code}\n\tdiffuseColor.a = ${opacityNode.result};` - ); - - } - - if ( normalSlot !== undefined ) { - - this.addCodeAfterInclude( - 'fragment', - 'normal_fragment_begin', - `${normalSlot.code}\n\tnormal = ${normalSlot.result};` - ); - - } - - if ( emissiveNode !== undefined ) { - - this.addCodeAfterInclude( - 'fragment', - 'emissivemap_fragment', - `${emissiveNode.code}\n\ttotalEmissiveRadiance = ${emissiveNode.result};` - ); - - } - - if ( roughnessNode !== undefined ) { - - this.addCodeAfterInclude( - 'fragment', - 'roughnessmap_fragment', - `${roughnessNode.code}\n\troughnessFactor = ${roughnessNode.result};` - ); - - } - - if ( metalnessNode !== undefined ) { - - this.addCodeAfterInclude( - 'fragment', - 'metalnessmap_fragment', - `${metalnessNode.code}\n\tmetalnessFactor = ${metalnessNode.result};` - ); - - } + _sortSlotsToFlow() { - if ( clearcoatNode !== undefined ) { + for ( const shaderStage of defaultShaderStages ) { - this.addCodeAfterSnippet( - 'fragment', - 'material.clearcoat = clearcoat;', - `${clearcoatNode.code}\n\tmaterial.clearcoat = ${clearcoatNode.result};` - ); + const sourceCode = this.shader[ getShaderStageProperty( shaderStage ) ]; - if ( clearcoatRoughnessNode !== undefined ) { + const slots = this.slots[ shaderStage ].sort( ( slotA, slotB ) => { - this.addCodeAfterSnippet( - 'fragment', - 'material.clearcoatRoughness = clearcoatRoughness;', - `${clearcoatRoughnessNode.code}\n\tmaterial.clearcoatRoughness = ${clearcoatRoughnessNode.result};` - ); + return sourceCode.indexOf( slotA.source ) > sourceCode.indexOf( slotB.source ) ? 1 : - 1; - } + } ); - if ( clearcoatNormalNode !== undefined ) { + for ( const slotNode of slots ) { - this.addCodeAfterSnippet( - 'fragment', - 'vec3 clearcoatNormal = geometryNormal;', - `${clearcoatNormalNode.code}\n\tclearcoatNormal = ${clearcoatNormalNode.result};` - ); + this.addFlow( shaderStage, slotNode ); } } - if ( sheenNode !== undefined ) { - - this.addCodeAfterSnippet( - 'fragment', - 'material.sheenColor = sheenColor;', - `${sheenNode.code}\n\tmaterial.sheenColor = ${sheenNode.result};` - ); - - if ( sheenRoughnessNode !== undefined ) { - - this.replaceCode( - 'fragment', - 'material.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );', - `${sheenRoughnessNode.code}\n\tmaterial.sheenRoughness = clamp( ${sheenRoughnessNode.result}, 0.07, 1.0 );` - ); - - } - - } - - if ( iridescenceNode !== undefined ) { - - this.addCodeAfterInclude( - 'fragment', - 'iridescence_fragment', - `${iridescenceNode.code}\n\tmaterial.iridescence = ${iridescenceNode.result};` - ); - - } + } - if ( iridescenceIORNode !== undefined ) { + _addSnippets() { - this.addCodeAfterInclude( - 'fragment', - 'iridescence_fragment', - `${iridescenceIORNode.code}\n\tmaterial.iridescenceIOR = ${iridescenceIORNode.result};` - ); + for ( const shaderStage of defaultShaderStages ) { - } + for ( const slotNode of this.slots[ shaderStage ] ) { - if ( iridescenceThicknessNode !== undefined ) { + const flowData = this.getFlowData( slotNode/*, shaderStage*/ ); - this.addCodeAfterInclude( - 'fragment', - 'iridescence_fragment', - `${iridescenceThicknessNode.code}\n\tmaterial.iridescenceThickness = ${iridescenceThicknessNode.result};` - ); + const inclusionType = slotNode.inclusionType; + const source = slotNode.source; + const target = flowData.code + '\n\t' + slotNode.target.replace( '%RESULT%', flowData.result ); - } + if ( inclusionType === 'append' ) { - if ( positionNode !== undefined ) { + this.addCode( shaderStage, source, target ); - this.addCodeAfterInclude( - 'vertex', - 'begin_vertex', - `${positionNode.code}\n\ttransformed = ${positionNode.result};` - ); + } else if ( inclusionType === 'replace' ) { - } + this.replaceCode( shaderStage, source, target ); - if ( sizeNode !== undefined ) { + } else { - this.addCodeAfterSnippet( - 'vertex', - 'gl_PointSize = size;', - `${sizeNode.code}\n\tgl_PointSize = ${sizeNode.result};` - ); + console.warn( `Inclusion type "${ inclusionType }" not compatible.` ); - } + } - for ( const shaderStage of defaultShaderStages ) { + } - this.addCodeAfterSnippet( + this.addCode( shaderStage, 'main() {', - this.flowCode[ shaderStage ] + '\n\t' + this.flowCode[ shaderStage ] ); } diff --git a/examples/jsm/renderers/webgl/nodes/WebGLNodes.js b/examples/jsm/renderers/webgl/nodes/WebGLNodes.js index 830173b24a4e0a..2825b7335103ab 100644 --- a/examples/jsm/renderers/webgl/nodes/WebGLNodes.js +++ b/examples/jsm/renderers/webgl/nodes/WebGLNodes.js @@ -1,5 +1,5 @@ import { WebGLNodeBuilder } from './WebGLNodeBuilder.js'; -import NodeFrame from 'three-nodes/core/NodeFrame.js'; +import { NodeFrame } from 'three/nodes'; import { Material } from 'three'; @@ -8,7 +8,11 @@ export const nodeFrame = new NodeFrame(); Material.prototype.onBuild = function ( object, parameters, renderer ) { - builders.set( this, new WebGLNodeBuilder( object, renderer, parameters ).build() ); + if ( object.material.isNodeMaterial === true ) { + + builders.set( this, new WebGLNodeBuilder( object, renderer, parameters ).build() ); + + } }; diff --git a/examples/jsm/renderers/webgl/nodes/WebGLPhysicalContextNode.js b/examples/jsm/renderers/webgl/nodes/WebGLPhysicalContextNode.js deleted file mode 100644 index 635be8db420f98..00000000000000 --- a/examples/jsm/renderers/webgl/nodes/WebGLPhysicalContextNode.js +++ /dev/null @@ -1,45 +0,0 @@ -import ContextNode from 'three-nodes/core/ContextNode.js'; -import NormalNode from 'three-nodes/accessors/NormalNode.js'; -import ExpressionNode from 'three-nodes/core/ExpressionNode.js'; -import ConstNode from 'three-nodes/core/ConstNode.js'; - -class WebGLPhysicalContextNode extends ContextNode { - - static RADIANCE = 'radiance'; - static IRRADIANCE = 'irradiance'; - - constructor( scope, node ) { - - super( node, 'vec3' ); - - this.scope = scope; - - } - - generate( builder, output ) { - - const scope = this.scope; - - let roughness = null; - - if ( scope === WebGLPhysicalContextNode.RADIANCE ) { - - roughness = new ExpressionNode( 'roughnessFactor', 'float' ); - - } else if ( scope === WebGLPhysicalContextNode.IRRADIANCE ) { - - roughness = new ConstNode( 1 ); - - this.context.uv = new NormalNode( NormalNode.WORLD ); - - } - - this.context.roughness = roughness; - - return super.generate( builder, output ); - - } - -} - -export default WebGLPhysicalContextNode; diff --git a/examples/jsm/renderers/webgpu/WebGPUAnimation.js b/examples/jsm/renderers/webgpu/WebGPUAnimation.js new file mode 100644 index 00000000000000..e8be5cce177830 --- /dev/null +++ b/examples/jsm/renderers/webgpu/WebGPUAnimation.js @@ -0,0 +1,58 @@ +class WebGPUAnimation { + + constructor() { + + this.nodes = null; + + this.animationLoop = null; + this.requestId = null; + + this.isAnimating = false; + + this.context = self; + + } + + start() { + + if ( this.isAnimating === true || this.animationLoop === null || this.nodes === null ) return; + + this.isAnimating = true; + + const update = ( time, frame ) => { + + this.requestId = self.requestAnimationFrame( update ); + + this.animationLoop( time, frame ); + + this.nodes.updateFrame(); + + }; + + this.requestId = self.requestAnimationFrame( update ); + + } + + stop() { + + self.cancelAnimationFrame( this.requestId ); + + this.isAnimating = false; + + } + + setAnimationLoop( callback ) { + + this.animationLoop = callback; + + } + + setNodes( nodes ) { + + this.nodes = nodes; + + } + +} + +export default WebGPUAnimation; diff --git a/examples/jsm/renderers/webgpu/WebGPUAttributes.js b/examples/jsm/renderers/webgpu/WebGPUAttributes.js index 96b4128c66109e..fea8ddd3a1f639 100644 --- a/examples/jsm/renderers/webgpu/WebGPUAttributes.js +++ b/examples/jsm/renderers/webgpu/WebGPUAttributes.js @@ -23,7 +23,7 @@ class WebGPUAttributes { if ( data ) { - data.buffer.destroy(); + this._destroyBuffers( data ); this.buffers.delete( attribute ); @@ -51,7 +51,7 @@ class WebGPUAttributes { } else if ( usage && usage !== data.usage ) { - data.buffer.destroy(); + this._destroyBuffers( data ); data = this._createBuffer( attribute, usage ); @@ -67,6 +67,53 @@ class WebGPUAttributes { } + async getArrayBuffer( attribute ) { + + const data = this.get( attribute ); + const device = this.device; + + const gpuBuffer = data.buffer; + const size = gpuBuffer.size; + + let gpuReadBuffer = data.readBuffer; + let needsUnmap = true; + + if ( gpuReadBuffer === null ) { + + gpuReadBuffer = device.createBuffer( { + size, + usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ + } ); + + needsUnmap = false; + + data.readBuffer = gpuReadBuffer; + + } + + const cmdEncoder = device.createCommandEncoder( {} ); + + cmdEncoder.copyBufferToBuffer( + gpuBuffer, + 0, + gpuReadBuffer, + 0, + size + ); + + if ( needsUnmap ) gpuReadBuffer.unmap(); + + const gpuCommands = cmdEncoder.finish(); + device.queue.submit( [ gpuCommands ] ); + + await gpuReadBuffer.mapAsync( GPUMapMode.READ ); + + const arrayBuffer = gpuReadBuffer.getMappedRange(); + + return new Float32Array( arrayBuffer ); + + } + _createBuffer( attribute, usage ) { const array = attribute.array; @@ -74,7 +121,7 @@ class WebGPUAttributes { const buffer = this.device.createBuffer( { size, - usage: usage | GPUBufferUsage.COPY_DST, + usage: usage | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, mappedAtCreation: true } ); @@ -87,6 +134,7 @@ class WebGPUAttributes { return { version: attribute.version, buffer, + readBuffer: null, usage }; @@ -94,6 +142,8 @@ class WebGPUAttributes { _writeBuffer( buffer, attribute ) { + const device = this.device; + const array = attribute.array; const updateRange = attribute.updateRange; @@ -101,7 +151,7 @@ class WebGPUAttributes { // Not using update ranges - this.device.queue.writeBuffer( + device.queue.writeBuffer( buffer, 0, array, @@ -110,7 +160,7 @@ class WebGPUAttributes { } else { - this.device.queue.writeBuffer( + device.queue.writeBuffer( buffer, 0, array, @@ -124,6 +174,14 @@ class WebGPUAttributes { } + _destroyBuffers( { buffer, readBuffer } ) { + + buffer.destroy(); + + if ( readBuffer !== null ) readBuffer.destroy(); + + } + } export default WebGPUAttributes; diff --git a/examples/jsm/renderers/webgpu/WebGPUBackground.js b/examples/jsm/renderers/webgpu/WebGPUBackground.js index b94e81a162c7af..4e2717c5b5b26a 100644 --- a/examples/jsm/renderers/webgpu/WebGPUBackground.js +++ b/examples/jsm/renderers/webgpu/WebGPUBackground.js @@ -1,7 +1,6 @@ import { GPULoadOp, GPUStoreOp } from './constants.js'; -import { Color, Mesh, BoxGeometry, BackSide } from 'three'; -import { context, transformDirection, positionWorld, modelWorldMatrix } from 'three-nodes/Nodes.js'; -import MeshBasicNodeMaterial from 'three-nodes/materials/MeshBasicNodeMaterial.js'; +import { Color, Mesh, BoxGeometry, BackSide, EquirectangularReflectionMapping, EquirectangularRefractionMapping } from 'three'; +import { context, vec2, invert, texture, cubeTexture, transformDirection, positionWorld, modelWorldMatrix, viewportBottomLeft, equirectUV, MeshBasicNodeMaterial } from 'three/nodes'; let _clearAlpha; const _clearColor = new Color(); @@ -46,7 +45,7 @@ class WebGPUBackground { _clearAlpha = 1; forceClear = true; - } else if ( background.isNode === true ) { + } else if ( background.isNode === true || background.isTexture === true ) { _clearColor.copy( renderer._clearColor ); _clearAlpha = renderer._clearAlpha; @@ -55,12 +54,41 @@ class WebGPUBackground { if ( boxMesh === null ) { - const colorNode = context( background, { - uvNode: transformDirection( positionWorld, modelWorldMatrix ) - } ); + let node = null; + + if ( background.isCubeTexture === true ) { + + node = cubeTexture( background, transformDirection( positionWorld, modelWorldMatrix ) ); + + } else if ( background.isTexture === true ) { + + let nodeUV = null; + + if ( background.mapping === EquirectangularReflectionMapping || background.mapping === EquirectangularRefractionMapping ) { + + const dirNode = transformDirection( positionWorld, modelWorldMatrix ); + + nodeUV = equirectUV( dirNode ); + nodeUV = vec2( nodeUV.x, invert( nodeUV.y ) ); + + } else { + + nodeUV = viewportBottomLeft; + + } + + node = texture( background, nodeUV ); + + } else /*if ( background.isNode === true )*/ { + + node = context( background, { + uvNode: transformDirection( positionWorld, modelWorldMatrix ) + } ); + + } const nodeMaterial = new MeshBasicNodeMaterial(); - nodeMaterial.colorNode = colorNode; + nodeMaterial.colorNode = node; nodeMaterial.side = BackSide; nodeMaterial.depthTest = false; nodeMaterial.depthWrite = false; diff --git a/examples/jsm/renderers/webgpu/WebGPURenderStates.js b/examples/jsm/renderers/webgpu/WebGPURenderStates.js index d4293b0e534c86..7bc6da4699874a 100644 --- a/examples/jsm/renderers/webgpu/WebGPURenderStates.js +++ b/examples/jsm/renderers/webgpu/WebGPURenderStates.js @@ -1,4 +1,4 @@ -import LightsNode from 'three-nodes/lighting/LightsNode.js'; +import { LightsNode } from 'three/nodes'; class WebGPURenderState { diff --git a/examples/jsm/renderers/webgpu/WebGPURenderer.js b/examples/jsm/renderers/webgpu/WebGPURenderer.js index dc5ceea4f7498b..55e629d71717bd 100644 --- a/examples/jsm/renderers/webgpu/WebGPURenderer.js +++ b/examples/jsm/renderers/webgpu/WebGPURenderer.js @@ -1,4 +1,5 @@ import { GPUIndexFormat, GPUTextureFormat, GPUStoreOp } from './constants.js'; +import WebGPUAnimation from './WebGPUAnimation.js'; import WebGPUObjects from './WebGPUObjects.js'; import WebGPUAttributes from './WebGPUAttributes.js'; import WebGPUGeometries from './WebGPUGeometries.js'; @@ -58,7 +59,7 @@ Matrix4.prototype.makeOrthographic = function ( left, right, top, bottom, near, }; -Frustum.prototype.setFromProjectionMatrix = function( m ) { +Frustum.prototype.setFromProjectionMatrix = function ( m ) { const planes = this.planes; const me = m.elements; @@ -132,6 +133,8 @@ class WebGPURenderer { this._textures = null; this._background = null; + this._animation = new WebGPUAnimation(); + this._renderPassDescriptor = null; this._currentRenderState = null; @@ -147,6 +150,8 @@ class WebGPURenderer { this._renderTarget = null; + this._initialized = false; + // some parameters require default values other than "undefined" this._parameters.antialias = ( parameters.antialias === true ); @@ -168,6 +173,12 @@ class WebGPURenderer { async init() { + if ( this._initialized === true ) { + + throw new Error( 'WebGPURenderer: Device has already been initialized.' ); + + } + const parameters = this._parameters; const adapterOptions = { @@ -192,7 +203,7 @@ class WebGPURenderer { const context = ( parameters.context !== undefined ) ? parameters.context : this.domElement.getContext( 'webgpu' ); context.configure( { - device: device, + device, format: GPUTextureFormat.BGRA8Unorm, // this is the only valid context format right now (r121) alphaMode: 'premultiplied' } ); @@ -232,19 +243,24 @@ class WebGPURenderer { this._setupColorBuffer(); this._setupDepthBuffer(); - } + this._animation.setNodes( this._nodes ); + this._animation.start(); + + this._initialized = true; - render( scene, camera ) { + } - // @TODO: move this to animation loop + async render( scene, camera ) { - this._nodes.updateFrame(); + if ( this._initialized === false ) return await this.init(); // - if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); + if ( this._animation.isAnimating === false ) this._nodes.updateFrame(); + + if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld(); - if ( camera.parent === null ) camera.updateMatrixWorld(); + if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld(); if ( this._info.autoReset === true ) this._info.reset(); @@ -276,6 +292,8 @@ class WebGPURenderer { if ( renderTarget !== null ) { + this._textures.initRenderTarget( renderTarget ); + // @TODO: Support RenderTarget with antialiasing. const renderTargetProperties = this._properties.get( renderTarget ); @@ -354,6 +372,24 @@ class WebGPURenderer { } + setAnimationLoop( callback ) { + + if ( this._initialized === false ) this.init(); + + const animation = this._animation; + + animation.setAnimationLoop( callback ); + + ( callback === null ) ? animation.stop() : animation.start(); + + } + + async getArrayFromBuffer( attribute ) { + + return await this._attributes.getArrayBuffer( attribute ); + + } + getContext() { return this._context; @@ -571,21 +607,20 @@ class WebGPURenderer { this._renderStates.dispose(); this._textures.dispose(); + this.setRenderTarget( null ); + this.setAnimationLoop( null ); + } setRenderTarget( renderTarget ) { this._renderTarget = renderTarget; - if ( renderTarget !== null ) { - - this._textures.initRenderTarget( renderTarget ); - - } - } - compute( ...computeNodes ) { + async compute( ...computeNodes ) { + + if ( this._initialized === false ) return await this.init(); const device = this._device; const computePipelines = this._computePipelines; diff --git a/examples/jsm/renderers/webgpu/nodes/WebGPUNodeBuilder.js b/examples/jsm/renderers/webgpu/nodes/WebGPUNodeBuilder.js index 137bf6e018a058..9b4cb13d6a80b2 100644 --- a/examples/jsm/renderers/webgpu/nodes/WebGPUNodeBuilder.js +++ b/examples/jsm/renderers/webgpu/nodes/WebGPUNodeBuilder.js @@ -10,12 +10,7 @@ import WebGPUUniformBuffer from '../WebGPUUniformBuffer.js'; import WebGPUStorageBuffer from '../WebGPUStorageBuffer.js'; import { getVectorLength, getStrideLength } from '../WebGPUBufferUtils.js'; -import NodeBuilder from 'three-nodes/core/NodeBuilder.js'; -import WGSLNodeParser from 'three-nodes/parsers/WGSLNodeParser.js'; - -import CodeNode from 'three-nodes/core/CodeNode.js'; - -import { NodeMaterial } from 'three-nodes/materials/Materials.js'; +import { NodeBuilder, WGSLNodeParser, CodeNode, NodeMaterial } from 'three/nodes'; const gpuShaderStageLib = { 'vertex': GPUShaderStage.VERTEX, @@ -62,28 +57,30 @@ const wgslTypeLib = { const wgslMethods = { dFdx: 'dpdx', dFdy: 'dpdy', + mod: 'threejs_mod', + lessThanEqual: 'threejs_lessThanEqual', inversesqrt: 'inverseSqrt' }; const wgslPolyfill = { lessThanEqual: new CodeNode( ` -fn lessThanEqual( a : vec3, b : vec3 ) -> vec3 { +fn threejs_lessThanEqual( a : vec3, b : vec3 ) -> vec3 { return vec3( a.x <= b.x, a.y <= b.y, a.z <= b.z ); } ` ), mod: new CodeNode( ` -fn mod( x : f32, y : f32 ) -> f32 { +fn threejs_mod( x : f32, y : f32 ) -> f32 { return x - y * floor( x / y ); } ` ), repeatWrapping: new CodeNode( ` -fn repeatWrapping( uv : vec2, dimension : vec2 ) -> vec2 { +fn threejs_repeatWrapping( uv : vec2, dimension : vec2 ) -> vec2 { - let uvScaled = vec2( uv * vec2( dimension ) ); + let uvScaled = vec2( uv * vec2( dimension ) ); return ( ( uvScaled % dimension ) + dimension ) % dimension; @@ -153,7 +150,7 @@ class WebGPUNodeBuilder extends NodeBuilder { const dimension = `textureDimensions( ${textureProperty}, 0 )`; - return `textureLoad( ${textureProperty}, repeatWrapping( ${uvSnippet}, ${dimension} ), 0 )`; + return `textureLoad( ${textureProperty}, threejs_repeatWrapping( ${uvSnippet}, ${dimension} ), 0 )`; } @@ -171,7 +168,7 @@ class WebGPUNodeBuilder extends NodeBuilder { const dimension = `textureDimensions( ${textureProperty}, 0 )`; - return `textureLoad( ${textureProperty}, repeatWrapping( ${uvSnippet}, ${dimension} ), i32( ${biasSnippet} ) )`; + return `textureLoad( ${textureProperty}, threejs_repeatWrapping( ${uvSnippet}, ${dimension} ), i32( ${biasSnippet} ) )`; } @@ -203,7 +200,7 @@ class WebGPUNodeBuilder extends NodeBuilder { getPropertyName( node, shaderStage = this.shaderStage ) { - if ( node.isNodeVarying === true ) { + if ( node.isNodeVarying === true && node.needsInterpolation === true ) { if ( shaderStage === 'vertex' ) { @@ -402,6 +399,18 @@ class WebGPUNodeBuilder extends NodeBuilder { } + getFragCoord() { + + return this.getBuiltin( 'position', 'fragCoord', 'vec4', 'fragment' ); + + } + + isFlipY() { + + return false; + + } + getAttributes( shaderStage ) { const snippets = []; @@ -466,24 +475,42 @@ class WebGPUNodeBuilder extends NodeBuilder { this.getBuiltin( 'position', 'Vertex', 'vec4', 'vertex' ); const varyings = this.varyings; + const vars = this.vars[ shaderStage ]; for ( let index = 0; index < varyings.length; index ++ ) { const varying = varyings[ index ]; - snippets.push( `@location( ${index} ) ${ varying.name } : ${ this.getType( varying.type ) }` ); + if ( varying.needsInterpolation ) { + + snippets.push( `@location( ${index} ) ${ varying.name } : ${ this.getType( varying.type ) }` ); + + } else if ( vars.includes( varying ) === false ) { + + vars.push( varying ); + + } } } else if ( shaderStage === 'fragment' ) { const varyings = this.varyings; + const vars = this.vars[ shaderStage ]; for ( let index = 0; index < varyings.length; index ++ ) { const varying = varyings[ index ]; - snippets.push( `@location( ${index} ) ${ varying.name } : ${ this.getType( varying.type ) }` ); + if ( varying.needsInterpolation ) { + + snippets.push( `@location( ${index} ) ${ varying.name } : ${ this.getType( varying.type ) }` ); + + } else if ( vars.includes( varying ) === false ) { + + vars.push( varying ); + + } } diff --git a/examples/jsm/renderers/webgpu/nodes/WebGPUNodes.js b/examples/jsm/renderers/webgpu/nodes/WebGPUNodes.js index a55244d3404107..5eb8302e2c1bd1 100644 --- a/examples/jsm/renderers/webgpu/nodes/WebGPUNodes.js +++ b/examples/jsm/renderers/webgpu/nodes/WebGPUNodes.js @@ -1,5 +1,5 @@ import WebGPUNodeBuilder from './WebGPUNodeBuilder.js'; -import NodeFrame from 'three-nodes/core/NodeFrame.js'; +import { NodeFrame } from 'three/nodes'; class WebGPUNodes { diff --git a/examples/jsm/shaders/MMDToonShader.js b/examples/jsm/shaders/MMDToonShader.js index e27c269c3a2f6c..6c0054b1f78d75 100644 --- a/examples/jsm/shaders/MMDToonShader.js +++ b/examples/jsm/shaders/MMDToonShader.js @@ -45,8 +45,6 @@ void RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in Geometric #define RE_Direct RE_Direct_BlinnPhong #define RE_IndirectDiffuse RE_IndirectDiffuse_BlinnPhong - -#define Material_LightProbeLOD( material ) (0) `; const mmd_toon_matcap_fragment = /* glsl */` diff --git a/examples/jsm/shaders/PixelShader.js b/examples/jsm/shaders/PixelShader.js deleted file mode 100644 index c4ebaa9aca94bd..00000000000000 --- a/examples/jsm/shaders/PixelShader.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Pixelation shader - */ - -const PixelShader = { - - uniforms: { - - 'tDiffuse': { value: null }, - 'resolution': { value: null }, - 'pixelSize': { value: 1 }, - - }, - - vertexShader: /* glsl */` - - varying highp vec2 vUv; - - void main() { - - vUv = uv; - gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); - - }`, - - fragmentShader: /* glsl */` - - uniform sampler2D tDiffuse; - uniform float pixelSize; - uniform vec2 resolution; - - varying highp vec2 vUv; - - void main(){ - - vec2 dxy = pixelSize / resolution; - vec2 coord = dxy * floor( vUv / dxy ); - gl_FragColor = texture2D(tDiffuse, coord); - - }` - -}; - -export { PixelShader }; diff --git a/examples/jsm/shaders/VelocityShader.js b/examples/jsm/shaders/VelocityShader.js new file mode 100644 index 00000000000000..624ffe634d446c --- /dev/null +++ b/examples/jsm/shaders/VelocityShader.js @@ -0,0 +1,128 @@ +import { + UniformsLib, + UniformsUtils, + Matrix4 +} from 'three'; + +/** + * Mesh Velocity Shader @bhouston + */ + +const VelocityShader = { + + uniforms: UniformsUtils.merge( [ + UniformsLib.common, + UniformsLib.displacementmap, + { + modelMatrixPrev: { value: new Matrix4() }, + currentProjectionViewMatrix: { value: new Matrix4() }, + previousProjectionViewMatrix: { value: new Matrix4() } + } + ] ), + + vertexShader: /* glsl */` +#define NORMAL + +#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP ) + + varying vec3 vViewPosition; + +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +uniform mat4 previousProjectionViewMatrix; +uniform mat4 currentProjectionViewMatrix; + +uniform mat4 modelMatrixPrev; + +varying vec4 clipPositionCurrent; +varying vec4 clipPositionPrevious; + +void main() { + + + #include + + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + +#ifdef USE_SKINNING + + vec4 mvPosition = modelViewMatrix * skinned; + clipPositionCurrent = currentProjectionViewMatrix * modelMatrix * skinned; + clipPositionPrevious = previousProjectionViewMatrix * modelMatrixPrev * skinned; + +#else + + vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 ); + clipPositionCurrent = currentProjectionViewMatrix * modelMatrix * vec4( transformed, 1.0 ); + clipPositionPrevious = previousProjectionViewMatrix * modelMatrixPrev * vec4( transformed, 1.0 ); + +#endif + + gl_Position = projectionMatrix * mvPosition; + + #include + #include +} +`, + fragmentShader: /* glsl */` +#define NORMAL + +uniform float opacity; + +#include +#include +#include +#include +#include +#include +#include + +varying vec4 clipPositionCurrent; +varying vec4 clipPositionPrevious; + +void main() { + + vec4 diffuseColor = vec4( 1.0 ); + diffuseColor.a = opacity; + + #include + #include + #include + + vec2 ndcPositionCurrent = clipPositionCurrent.xy/clipPositionCurrent.w; + vec2 ndcPositionPrevious = clipPositionPrevious.xy/clipPositionPrevious.w; + vec2 vel = ( ndcPositionCurrent - ndcPositionPrevious ) * 0.5; + vel = vel * 0.5 + 0.5; + vec2 v1 = packDepthToRG(vel.x); + vec2 v2 = packDepthToRG(vel.y); + gl_FragColor = vec4(v1.x, v1.y, v2.x, v2.y); + + #include + +} + +` +}; + +export { VelocityShader }; diff --git a/examples/jsm/utils/BufferGeometryUtils.js b/examples/jsm/utils/BufferGeometryUtils.js index 7fc6d9de60f37d..7166648832da5e 100644 --- a/examples/jsm/utils/BufferGeometryUtils.js +++ b/examples/jsm/utils/BufferGeometryUtils.js @@ -5,7 +5,6 @@ import { InstancedBufferAttribute, InterleavedBuffer, InterleavedBufferAttribute, - MathUtils, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, @@ -36,17 +35,16 @@ function computeMikkTSpaceTangents( geometry, MikkTSpace, negateSign = true ) { if ( attribute.normalized || attribute.isInterleavedBufferAttribute ) { - const srcArray = attribute.isInterleavedBufferAttribute ? attribute.data.array : attribute.array; const dstArray = new Float32Array( attribute.getCount() * attribute.itemSize ); for ( let i = 0, j = 0; i < attribute.getCount(); i ++ ) { - dstArray[ j ++ ] = MathUtils.denormalize( attribute.getX( i ), srcArray ); - dstArray[ j ++ ] = MathUtils.denormalize( attribute.getY( i ), srcArray ); + dstArray[ j ++ ] = attribute.getX( i ); + dstArray[ j ++ ] = attribute.getY( i ); if ( attribute.itemSize > 2 ) { - dstArray[ j ++ ] = MathUtils.denormalize( attribute.getZ( i ), srcArray ); + dstArray[ j ++ ] = attribute.getZ( i ); } @@ -194,11 +192,6 @@ function mergeBufferGeometries( geometries, useGroups = false ) { } - // gather .userData - - mergedGeometry.userData.mergedUserData = mergedGeometry.userData.mergedUserData || []; - mergedGeometry.userData.mergedUserData.push( geometry.userData ); - if ( useGroups ) { let count; @@ -373,6 +366,28 @@ function mergeBufferAttributes( attributes ) { } +/** + * @param {BufferAttribute} + * @return {BufferAttribute} + */ +export function deepCloneAttribute( attribute ) { + + if ( attribute.isInstancedInterleavedBufferAttribute || attribute.isInterleavedBufferAttribute ) { + + return deinterleaveAttribute( attribute ); + + } + + if ( attribute.isInstancedBufferAttribute ) { + + return new InstancedBufferAttribute().copy( attribute ); + + } + + return new BufferAttribute().copy( attribute ); + +} + /** * @param {Array} attributes * @return {Array} @@ -385,7 +400,7 @@ function interleaveAttributes( attributes ) { let arrayLength = 0; let stride = 0; - // calculate the the length and type of the interleavedBuffer + // calculate the length and type of the interleavedBuffer for ( let i = 0, l = attributes.length; i < l; ++ i ) { const attribute = attributes[ i ]; @@ -555,7 +570,7 @@ function estimateBytesUsed( geometry ) { /** * @param {BufferGeometry} geometry * @param {number} tolerance - * @return {BufferGeometry>} + * @return {BufferGeometry} */ function mergeVertices( geometry, tolerance = 1e-4 ) { @@ -573,22 +588,33 @@ function mergeVertices( geometry, tolerance = 1e-4 ) { // attributes and new attribute arrays const attributeNames = Object.keys( geometry.attributes ); - const attrArrays = {}; - const morphAttrsArrays = {}; + const tmpAttributes = {}; + const tmpMorphAttributes = {}; const newIndices = []; const getters = [ 'getX', 'getY', 'getZ', 'getW' ]; + const setters = [ 'setX', 'setY', 'setZ', 'setW' ]; - // initialize the arrays + // Initialize the arrays, allocating space conservatively. Extra + // space will be trimmed in the last step. for ( let i = 0, l = attributeNames.length; i < l; i ++ ) { const name = attributeNames[ i ]; + const attr = geometry.attributes[ name ]; - attrArrays[ name ] = []; + tmpAttributes[ name ] = new BufferAttribute( + new attr.array.constructor( attr.count * attr.itemSize ), + attr.itemSize, + attr.normalized + ); const morphAttr = geometry.morphAttributes[ name ]; if ( morphAttr ) { - morphAttrsArrays[ name ] = new Array( morphAttr.length ).fill().map( () => [] ); + tmpMorphAttributes[ name ] = new BufferAttribute( + new morphAttr.array.constructor( morphAttr.count * morphAttr.itemSize ), + morphAttr.itemSize, + morphAttr.normalized + ); } @@ -626,26 +652,27 @@ function mergeVertices( geometry, tolerance = 1e-4 ) { } else { - // copy data to the new index in the attribute arrays + // copy data to the new index in the temporary attributes for ( let j = 0, l = attributeNames.length; j < l; j ++ ) { const name = attributeNames[ j ]; const attribute = geometry.getAttribute( name ); const morphAttr = geometry.morphAttributes[ name ]; const itemSize = attribute.itemSize; - const newarray = attrArrays[ name ]; - const newMorphArrays = morphAttrsArrays[ name ]; + const newarray = tmpAttributes[ name ]; + const newMorphArrays = tmpMorphAttributes[ name ]; for ( let k = 0; k < itemSize; k ++ ) { const getterFunc = getters[ k ]; - newarray.push( attribute[ getterFunc ]( index ) ); + const setterFunc = setters[ k ]; + newarray[ setterFunc ]( nextIndex, attribute[ getterFunc ]( index ) ); if ( morphAttr ) { for ( let m = 0, ml = morphAttr.length; m < ml; m ++ ) { - newMorphArrays[ m ].push( morphAttr[ m ][ getterFunc ]( index ) ); + newMorphArrays[ m ][ setterFunc ]( nextIndex, morphAttr[ m ][ getterFunc ]( index ) ); } @@ -663,31 +690,29 @@ function mergeVertices( geometry, tolerance = 1e-4 ) { } - // Generate typed arrays from new attribute arrays and update - // the attributeBuffers + // generate result BufferGeometry const result = geometry.clone(); - for ( let i = 0, l = attributeNames.length; i < l; i ++ ) { - - const name = attributeNames[ i ]; - const oldAttribute = geometry.getAttribute( name ); - - const buffer = new oldAttribute.array.constructor( attrArrays[ name ] ); - const attribute = new BufferAttribute( buffer, oldAttribute.itemSize, oldAttribute.normalized ); + for ( const name in geometry.attributes ) { - result.setAttribute( name, attribute ); + const tmpAttribute = tmpAttributes[ name ]; - // Update the attribute arrays - if ( name in morphAttrsArrays ) { + result.setAttribute( name, new BufferAttribute( + tmpAttribute.array.slice( 0, nextIndex * tmpAttribute.itemSize ), + tmpAttribute.itemSize, + tmpAttribute.normalized, + ) ); - for ( let j = 0; j < morphAttrsArrays[ name ].length; j ++ ) { + if ( ! ( name in tmpMorphAttributes ) ) continue; - const oldMorphAttribute = geometry.morphAttributes[ name ][ j ]; + for ( let j = 0; j < tmpMorphAttributes[ name ].length; j ++ ) { - const buffer = new oldMorphAttribute.array.constructor( morphAttrsArrays[ name ][ j ] ); - const morphAttribute = new BufferAttribute( buffer, oldMorphAttribute.itemSize, oldMorphAttribute.normalized ); - result.morphAttributes[ name ][ j ] = morphAttribute; + const tmpMorphAttribute = tmpMorphAttributes[ name ][ j ]; - } + result.morphAttributes[ name ][ j ] = new BufferAttribute( + tmpMorphAttribute.array.slice( 0, nextIndex * tmpMorphAttribute.itemSize ), + tmpMorphAttribute.itemSize, + tmpMorphAttribute.normalized, + ); } @@ -704,7 +729,7 @@ function mergeVertices( geometry, tolerance = 1e-4 ) { /** * @param {BufferGeometry} geometry * @param {number} drawMode - * @return {BufferGeometry>} + * @return {BufferGeometry} */ function toTrianglesDrawMode( geometry, drawMode ) { @@ -1200,6 +1225,112 @@ function mergeGroups( geometry ) { } + +// Creates a new, non-indexed geometry with smooth normals everywhere except faces that meet at +// an angle greater than the crease angle. +function toCreasedNormals( geometry, creaseAngle = Math.PI / 3 /* 60 degrees */ ) { + + const creaseDot = Math.cos( creaseAngle ); + const hashMultiplier = ( 1 + 1e-10 ) * 1e2; + + // reusable vertors + const verts = [ new Vector3(), new Vector3(), new Vector3() ]; + const tempVec1 = new Vector3(); + const tempVec2 = new Vector3(); + const tempNorm = new Vector3(); + const tempNorm2 = new Vector3(); + + // hashes a vector + function hashVertex( v ) { + + const x = ~ ~ ( v.x * hashMultiplier ); + const y = ~ ~ ( v.y * hashMultiplier ); + const z = ~ ~ ( v.z * hashMultiplier ); + return `${x},${y},${z}`; + + } + + const resultGeometry = geometry.toNonIndexed(); + const posAttr = resultGeometry.attributes.position; + const vertexMap = {}; + + // find all the normals shared by commonly located vertices + for ( let i = 0, l = posAttr.count / 3; i < l; i ++ ) { + + const i3 = 3 * i; + const a = verts[ 0 ].fromBufferAttribute( posAttr, i3 + 0 ); + const b = verts[ 1 ].fromBufferAttribute( posAttr, i3 + 1 ); + const c = verts[ 2 ].fromBufferAttribute( posAttr, i3 + 2 ); + + tempVec1.subVectors( c, b ); + tempVec2.subVectors( a, b ); + + // add the normal to the map for all vertices + const normal = new Vector3().crossVectors( tempVec1, tempVec2 ).normalize(); + for ( let n = 0; n < 3; n ++ ) { + + const vert = verts[ n ]; + const hash = hashVertex( vert ); + if ( ! ( hash in vertexMap ) ) { + + vertexMap[ hash ] = []; + + } + + vertexMap[ hash ].push( normal ); + + } + + } + + // average normals from all vertices that share a common location if they are within the + // provided crease threshold + const normalArray = new Float32Array( posAttr.count * 3 ); + const normAttr = new BufferAttribute( normalArray, 3, false ); + for ( let i = 0, l = posAttr.count / 3; i < l; i ++ ) { + + // get the face normal for this vertex + const i3 = 3 * i; + const a = verts[ 0 ].fromBufferAttribute( posAttr, i3 + 0 ); + const b = verts[ 1 ].fromBufferAttribute( posAttr, i3 + 1 ); + const c = verts[ 2 ].fromBufferAttribute( posAttr, i3 + 2 ); + + tempVec1.subVectors( c, b ); + tempVec2.subVectors( a, b ); + + tempNorm.crossVectors( tempVec1, tempVec2 ).normalize(); + + // average all normals that meet the threshold and set the normal value + for ( let n = 0; n < 3; n ++ ) { + + const vert = verts[ n ]; + const hash = hashVertex( vert ); + const otherNormals = vertexMap[ hash ]; + tempNorm2.set( 0, 0, 0 ); + + for ( let k = 0, lk = otherNormals.length; k < lk; k ++ ) { + + const otherNorm = otherNormals[ k ]; + if ( tempNorm.dot( otherNorm ) > creaseDot ) { + + tempNorm2.add( otherNorm ); + + } + + } + + tempNorm2.normalize(); + normAttr.setXYZ( i3 + n, tempNorm2.x, tempNorm2.y, tempNorm2.z ); + + } + + } + + resultGeometry.setAttribute( 'normal', normAttr ); + return resultGeometry; + +} + export { computeTangents, computeMikkTSpaceTangents, @@ -1210,5 +1341,6 @@ export { mergeVertices, toTrianglesDrawMode, computeMorphedAttributes, - mergeGroups + mergeGroups, + toCreasedNormals }; diff --git a/examples/jsm/utils/PackedPhongMaterial.js b/examples/jsm/utils/PackedPhongMaterial.js index a06b07a1143076..a64e339aeaab93 100644 --- a/examples/jsm/utils/PackedPhongMaterial.js +++ b/examples/jsm/utils/PackedPhongMaterial.js @@ -189,7 +189,6 @@ class PackedPhongMaterial extends MeshPhongMaterial { ShaderChunk.emissivemap_pars_fragment, ShaderChunk.envmap_common_pars_fragment, ShaderChunk.envmap_pars_fragment, - ShaderChunk.cube_uv_reflection_fragment, ShaderChunk.fog_pars_fragment, ShaderChunk.bsdfs, ShaderChunk.lights_pars_begin, diff --git a/examples/jsm/utils/SceneUtils.js b/examples/jsm/utils/SceneUtils.js index 74c3ecf35bed34..1548ea35b63225 100644 --- a/examples/jsm/utils/SceneUtils.js +++ b/examples/jsm/utils/SceneUtils.js @@ -1,11 +1,17 @@ import { + BufferAttribute, + BufferGeometry, + Color, Group, + Matrix4, Mesh, - BufferAttribute, - BufferGeometry + Vector3 } from 'three'; -import { mergeGroups } from './BufferGeometryUtils.js'; +import { mergeGroups, deepCloneAttribute } from './BufferGeometryUtils.js'; + +const _color = /*@__PURE__*/new Color(); +const _matrix = /*@__PURE__*/new Matrix4(); function createMeshesFromInstancedMesh( instancedMesh ) { @@ -118,28 +124,127 @@ function createMultiMaterialObject( geometry, materials ) { } -function detach( child, parent, scene ) { +function reduceVertices( object, func, initialValue ) { - console.warn( 'THREE.SceneUtils: detach() has been deprecated. Use scene.attach( child ) instead.' ); + let value = initialValue; + const vertex = new Vector3(); - scene.attach( child ); + object.updateWorldMatrix( true, true ); -} + object.traverseVisible( ( child ) => { + + const { geometry } = child; + + if ( geometry !== undefined ) { + + const { position } = geometry.attributes; + + if ( position !== undefined ) { -function attach( child, scene, parent ) { + for ( let i = 0, l = position.count; i < l; i ++ ) { - console.warn( 'THREE.SceneUtils: attach() has been deprecated. Use parent.attach( child ) instead.' ); + vertex.fromBufferAttribute( position, i ); - parent.attach( child ); + if ( child.isSkinnedMesh ) { + + child.boneTransform( i, vertex ); + + } else { + + vertex.applyMatrix4( child.matrixWorld ); + + } + + value = func( value, vertex ); + + } + + } + + } + + } ); + + return value; } +/** + * @param {InstancedMesh} + * @param {function(int, int):int} + */ +function sortInstancedMesh( mesh, compareFn ) { + + // store copy of instanced attributes for lookups + + const instanceMatrixRef = deepCloneAttribute( mesh.instanceMatrix ); + const instanceColorRef = mesh.instanceColor ? deepCloneAttribute( mesh.instanceColor ) : null; + + const attributeRefs = new Map(); + + for ( const name in mesh.geometry.attributes ) { + + const attribute = mesh.geometry.attributes[ name ]; + + if ( attribute.isInstancedBufferAttribute ) { + + attributeRefs.set( attribute, deepCloneAttribute( attribute ) ); + + } + } + + + // compute sort order + + const tokens = []; + + for ( let i = 0; i < mesh.count; i ++ ) tokens.push( i ); + + tokens.sort( compareFn ); + + + // apply sort order + + for ( let i = 0; i < tokens.length; i ++ ) { + + const refIndex = tokens[ i ]; + + _matrix.fromArray( instanceMatrixRef.array, refIndex * mesh.instanceMatrix.itemSize ); + _matrix.toArray( mesh.instanceMatrix.array, i * mesh.instanceMatrix.itemSize ); + + if ( mesh.instanceColor ) { + + _color.fromArray( instanceColorRef.array, refIndex * mesh.instanceColor.itemSize ); + _color.toArray( mesh.instanceColor.array, i * mesh.instanceColor.itemSize ); + + } + + for ( const name in mesh.geometry.attributes ) { + + const attribute = mesh.geometry.attributes[ name ]; + + if ( attribute.isInstancedBufferAttribute ) { + + const attributeRef = attributeRefs.get( attribute ); + + attribute.setX( i, attributeRef.getX( refIndex ) ); + if ( attribute.itemSize > 1 ) attribute.setY( i, attributeRef.getY( refIndex ) ); + if ( attribute.itemSize > 2 ) attribute.setZ( i, attributeRef.getZ( refIndex ) ); + if ( attribute.itemSize > 3 ) attribute.setW( i, attributeRef.getW( refIndex ) ); + + } + + } + + } + +} export { createMeshesFromInstancedMesh, createMeshesFromMultiMaterialMesh, createMultiMaterialObject, - detach, - attach, + reduceVertices, + sortInstancedMesh }; diff --git a/examples/jsm/webxr/OculusHandModel.js b/examples/jsm/webxr/OculusHandModel.js index c56908143ff27b..19589211e8ec89 100644 --- a/examples/jsm/webxr/OculusHandModel.js +++ b/examples/jsm/webxr/OculusHandModel.js @@ -6,13 +6,14 @@ const POINTING_JOINT = 'index-finger-tip'; class OculusHandModel extends Object3D { - constructor( controller ) { + constructor( controller, loader = null ) { super(); this.controller = controller; this.motionController = null; this.envMap = null; + this.loader = loader; this.mesh = null; @@ -24,7 +25,7 @@ class OculusHandModel extends Object3D { this.xrInputSource = xrInputSource; - this.motionController = new XRHandMeshModel( this, controller, this.path, xrInputSource.handedness ); + this.motionController = new XRHandMeshModel( this, controller, this.path, xrInputSource.handedness, this.loader ); } diff --git a/examples/jsm/webxr/VRButton.js b/examples/jsm/webxr/VRButton.js index e495f7e42942a6..6908932b43b697 100644 --- a/examples/jsm/webxr/VRButton.js +++ b/examples/jsm/webxr/VRButton.js @@ -1,12 +1,6 @@ class VRButton { - static createButton( renderer, options ) { - - if ( options ) { - - console.error( 'THREE.VRButton: The "options" parameter has been removed. Please set the reference space type via renderer.xr.setReferenceSpaceType() instead.' ); - - } + static createButton( renderer ) { const button = document.createElement( 'button' ); diff --git a/examples/jsm/webxr/XRHandMeshModel.js b/examples/jsm/webxr/XRHandMeshModel.js index b7956fc463774b..cad8487b211a74 100644 --- a/examples/jsm/webxr/XRHandMeshModel.js +++ b/examples/jsm/webxr/XRHandMeshModel.js @@ -4,15 +4,20 @@ const DEFAULT_HAND_PROFILE_PATH = 'https://cdn.jsdelivr.net/npm/@webxr-input-pro class XRHandMeshModel { - constructor( handModel, controller, path, handedness ) { + constructor( handModel, controller, path, handedness, loader = null ) { this.controller = controller; this.handModel = handModel; this.bones = []; - const loader = new GLTFLoader(); - loader.setPath( path || DEFAULT_HAND_PROFILE_PATH ); + if ( loader === null ) { + + loader = new GLTFLoader(); + loader.setPath( path || DEFAULT_HAND_PROFILE_PATH ); + + } + loader.load( `${handedness}.glb`, gltf => { const object = gltf.scene.children[ 0 ]; diff --git a/examples/misc_animation_groups.html b/examples/misc_animation_groups.html index 0e19bb24b7e316..a4abffe2ccc570 100644 --- a/examples/misc_animation_groups.html +++ b/examples/misc_animation_groups.html @@ -19,7 +19,8 @@ @@ -28,7 +29,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let stats, clock; let scene, camera, renderer, mixer; diff --git a/examples/misc_animation_keys.html b/examples/misc_animation_keys.html index 521be3204d3038..98be9049c8ce4e 100644 --- a/examples/misc_animation_keys.html +++ b/examples/misc_animation_keys.html @@ -19,7 +19,8 @@ @@ -28,7 +29,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let stats, clock; let scene, camera, renderer, mixer; diff --git a/examples/misc_boxselection.html b/examples/misc_boxselection.html index 9b736c7c59b208..d31fa8a5a77e00 100644 --- a/examples/misc_boxselection.html +++ b/examples/misc_boxselection.html @@ -36,7 +36,8 @@ @@ -45,10 +46,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { SelectionBox } from './jsm/interactive/SelectionBox.js'; - import { SelectionHelper } from './jsm/interactive/SelectionHelper.js'; + import { SelectionBox } from 'three/addons/interactive/SelectionBox.js'; + import { SelectionHelper } from 'three/addons/interactive/SelectionHelper.js'; let container, stats; let camera, scene, renderer; diff --git a/examples/misc_controls_arcball.html b/examples/misc_controls_arcball.html index a38596dc152036..6f2308d5d947e1 100644 --- a/examples/misc_controls_arcball.html +++ b/examples/misc_controls_arcball.html @@ -21,7 +21,8 @@ @@ -29,12 +30,12 @@ @@ -39,7 +40,7 @@ import * as THREE from 'three'; - import { DragControls } from './jsm/controls/DragControls.js'; + import { DragControls } from 'three/addons/controls/DragControls.js'; let container; let camera, scene, renderer; diff --git a/examples/misc_controls_fly.html b/examples/misc_controls_fly.html index 01d788ed46f015..72f382be7dee5d 100644 --- a/examples/misc_controls_fly.html +++ b/examples/misc_controls_fly.html @@ -34,7 +34,8 @@ @@ -43,12 +44,12 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { FlyControls } from './jsm/controls/FlyControls.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { FilmPass } from './jsm/postprocessing/FilmPass.js'; + import { FlyControls } from 'three/addons/controls/FlyControls.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { FilmPass } from 'three/addons/postprocessing/FilmPass.js'; const radius = 6371; const tilt = 0.41; @@ -93,9 +94,9 @@ specular: 0x333333, shininess: 15, - map: textureLoader.load( "textures/planets/earth_atmos_2048.jpg" ), - specularMap: textureLoader.load( "textures/planets/earth_specular_2048.jpg" ), - normalMap: textureLoader.load( "textures/planets/earth_normal_2048.jpg" ), + map: textureLoader.load( 'textures/planets/earth_atmos_2048.jpg' ), + specularMap: textureLoader.load( 'textures/planets/earth_specular_2048.jpg' ), + normalMap: textureLoader.load( 'textures/planets/earth_normal_2048.jpg' ), // y scale is negated to compensate for normal map handedness. normalScale: new THREE.Vector2( 0.85, - 0.85 ) @@ -115,7 +116,7 @@ const materialClouds = new THREE.MeshLambertMaterial( { - map: textureLoader.load( "textures/planets/earth_clouds_1024.png" ), + map: textureLoader.load( 'textures/planets/earth_clouds_1024.png' ), transparent: true } ); @@ -129,7 +130,7 @@ const materialMoon = new THREE.MeshPhongMaterial( { - map: textureLoader.load( "textures/planets/moon_1024.jpg" ) + map: textureLoader.load( 'textures/planets/moon_1024.jpg' ) } ); diff --git a/examples/misc_controls_map.html b/examples/misc_controls_map.html index 57bc3a2fb592fb..340c66d42eb2ec 100644 --- a/examples/misc_controls_map.html +++ b/examples/misc_controls_map.html @@ -29,7 +29,8 @@ @@ -38,9 +39,9 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { MapControls } from './jsm/controls/OrbitControls.js'; + import { MapControls } from 'three/addons/controls/OrbitControls.js'; let camera, controls, scene, renderer; diff --git a/examples/misc_controls_orbit.html b/examples/misc_controls_orbit.html index 192369b0d78084..fcd306d163325e 100644 --- a/examples/misc_controls_orbit.html +++ b/examples/misc_controls_orbit.html @@ -29,7 +29,8 @@ @@ -38,7 +39,7 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let camera, controls, scene, renderer; diff --git a/examples/misc_controls_pointerlock.html b/examples/misc_controls_pointerlock.html index 9576318b20b8ad..515290c1dbcacf 100644 --- a/examples/misc_controls_pointerlock.html +++ b/examples/misc_controls_pointerlock.html @@ -49,7 +49,8 @@ @@ -58,7 +59,7 @@ import * as THREE from 'three'; - import { PointerLockControls } from './jsm/controls/PointerLockControls.js'; + import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js'; let camera, scene, renderer, controls; diff --git a/examples/misc_controls_trackball.html b/examples/misc_controls_trackball.html index 9a7955bf961376..8c8b83169c1256 100644 --- a/examples/misc_controls_trackball.html +++ b/examples/misc_controls_trackball.html @@ -29,7 +29,8 @@ @@ -38,10 +39,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { TrackballControls } from './jsm/controls/TrackballControls.js'; + import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; let perspectiveCamera, orthographicCamera, controls, scene, renderer, stats; diff --git a/examples/misc_controls_transform.html b/examples/misc_controls_transform.html index 189bb01cd6761d..e3c4b01c0e052b 100644 --- a/examples/misc_controls_transform.html +++ b/examples/misc_controls_transform.html @@ -23,7 +23,8 @@ @@ -32,8 +33,8 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { TransformControls } from './jsm/controls/TransformControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { TransformControls } from 'three/addons/controls/TransformControls.js'; let cameraPersp, cameraOrtho, currentCamera; let scene, renderer, control, orbit; diff --git a/examples/misc_exporter_collada.html b/examples/misc_exporter_collada.html index 2117e9677ba1d0..c947f5dc983d29 100644 --- a/examples/misc_exporter_collada.html +++ b/examples/misc_exporter_collada.html @@ -18,7 +18,8 @@ @@ -27,11 +28,11 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { ColladaExporter } from './jsm/exporters/ColladaExporter.js'; - import { TeapotGeometry } from './jsm/geometries/TeapotGeometry.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { ColladaExporter } from 'three/addons/exporters/ColladaExporter.js'; + import { TeapotGeometry } from 'three/addons/geometries/TeapotGeometry.js'; //////////////////////////////////////////////////////////////////////////////// // Utah/Newell Teapot demo @@ -381,6 +382,7 @@ colors.push( r * 128, 0, b * 128 ); } + teapot.geometry.setAttribute( 'color', new THREE.Uint8BufferAttribute( colors, 3, true ) ); teapot.material.vertexColors = true; teapot.material.needsUpdate = true; diff --git a/examples/misc_exporter_draco.html b/examples/misc_exporter_draco.html index 8c4ff11186aec4..5210db2e18a841 100644 --- a/examples/misc_exporter_draco.html +++ b/examples/misc_exporter_draco.html @@ -20,7 +20,8 @@ @@ -29,9 +30,9 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { DRACOExporter } from './jsm/exporters/DRACOExporter.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { DRACOExporter } from 'three/addons/exporters/DRACOExporter.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let scene, camera, renderer, exporter, mesh; diff --git a/examples/misc_exporter_gltf.html b/examples/misc_exporter_gltf.html index ab5db4bc671de5..a52fe28d6c884e 100644 --- a/examples/misc_exporter_gltf.html +++ b/examples/misc_exporter_gltf.html @@ -18,7 +18,8 @@ @@ -27,9 +28,9 @@ import * as THREE from 'three'; - import { OBJLoader } from './jsm/loaders/OBJLoader.js'; - import { GLTFExporter } from './jsm/exporters/GLTFExporter.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; + import { GLTFExporter } from 'three/addons/exporters/GLTFExporter.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; function exportGLTF( input ) { @@ -38,7 +39,6 @@ const options = { trs: params.trs, onlyVisible: params.onlyVisible, - truncateDrawRange: params.truncateDrawRange, binary: params.binary, maxTextureSize: params.maxTextureSize }; @@ -104,7 +104,6 @@ const params = { trs: false, onlyVisible: true, - truncateDrawRange: true, binary: false, maxTextureSize: 4096, exportScene1: exportScene1, @@ -344,44 +343,6 @@ scene1.add( object ); - // --------------------------------------------------------------------- - // Buffer geometry truncated (DrawRange) - // --------------------------------------------------------------------- - geometry = new THREE.BufferGeometry(); - const numElements = 6; - const outOfRange = 3; - - positions = new Float32Array( ( numElements + outOfRange ) * 3 ); - const colors = new Float32Array( ( numElements + outOfRange ) * 3 ); - - positions.set( [ - 0, 0, 0, - 0, 80, 0, - 80, 0, 0, - 80, 0, 0, - 0, 80, 0, - 80, 80, 0 - ] ); - - colors.set( [ - 1, 0, 0, - 1, 0, 0, - 1, 1, 0, - 1, 1, 0, - 0, 0, 1, - 0, 0, 1, - ] ); - - geometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); - geometry.setAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) ); - geometry.setDrawRange( 0, numElements ); - - object = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { side: THREE.DoubleSide, vertexColors: true } ) ); - object.name = 'Custom buffered truncated'; - object.position.set( 140, - 40, - 200 ); - - scene1.add( object ); - // --------------------------------------------------------------------- // THREE.Points // --------------------------------------------------------------------- @@ -461,7 +422,7 @@ waltHead = obj; waltHead.scale.multiplyScalar( 1.5 ); - waltHead.position.set( 400, 0, 0 ); + waltHead.position.set( 200, - 40, - 200 ); scene1.add( waltHead ); } ); @@ -494,7 +455,6 @@ let h = gui.addFolder( 'Settings' ); h.add( params, 'trs' ).name( 'Use TRS' ); h.add( params, 'onlyVisible' ).name( 'Only Visible Objects' ); - h.add( params, 'truncateDrawRange' ).name( 'Truncate Draw Range' ); h.add( params, 'binary' ).name( 'Binary (GLB)' ); h.add( params, 'maxTextureSize', 2, 8192 ).name( 'Max Texture Size' ).step( 1 ); diff --git a/examples/misc_exporter_obj.html b/examples/misc_exporter_obj.html index b29b60733fc00e..fc57a30199b6c7 100644 --- a/examples/misc_exporter_obj.html +++ b/examples/misc_exporter_obj.html @@ -18,7 +18,8 @@ @@ -27,9 +28,9 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { OBJExporter } from './jsm/exporters/OBJExporter.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { OBJExporter } from 'three/addons/exporters/OBJExporter.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let camera, scene, renderer; diff --git a/examples/misc_exporter_ply.html b/examples/misc_exporter_ply.html index 72a7e13ee039eb..f661de8cfa6a40 100644 --- a/examples/misc_exporter_ply.html +++ b/examples/misc_exporter_ply.html @@ -18,7 +18,8 @@ @@ -27,9 +28,9 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { PLYExporter } from './jsm/exporters/PLYExporter.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { PLYExporter } from 'three/addons/exporters/PLYExporter.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let scene, camera, renderer, exporter, mesh; diff --git a/examples/misc_exporter_stl.html b/examples/misc_exporter_stl.html index cf1e137ce35d11..128232734bae34 100644 --- a/examples/misc_exporter_stl.html +++ b/examples/misc_exporter_stl.html @@ -18,7 +18,8 @@ @@ -27,9 +28,9 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { STLExporter } from './jsm/exporters/STLExporter.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { STLExporter } from 'three/addons/exporters/STLExporter.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let scene, camera, renderer, exporter, mesh; diff --git a/examples/misc_exporter_usdz.html b/examples/misc_exporter_usdz.html index 5fe999dab99e25..143800e48b37fb 100644 --- a/examples/misc_exporter_usdz.html +++ b/examples/misc_exporter_usdz.html @@ -42,7 +42,8 @@ @@ -51,11 +52,11 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { RoomEnvironment } from './jsm/environments/RoomEnvironment.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import { USDZExporter } from './jsm/exporters/USDZExporter.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { USDZExporter } from 'three/addons/exporters/USDZExporter.js'; let camera, scene, renderer; diff --git a/examples/misc_lookat.html b/examples/misc_lookat.html index fafb56780b0730..dbbac524230fae 100644 --- a/examples/misc_lookat.html +++ b/examples/misc_lookat.html @@ -26,7 +26,8 @@ @@ -35,7 +36,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let camera, scene, renderer, stats; diff --git a/examples/misc_uv_tests.html b/examples/misc_uv_tests.html index baeee1de5d344b..1599b7544323b7 100644 --- a/examples/misc_uv_tests.html +++ b/examples/misc_uv_tests.html @@ -31,7 +31,8 @@ @@ -40,7 +41,7 @@ import * as THREE from 'three'; - import { UVsDebug } from './jsm/utils/UVsDebug.js'; + import { UVsDebug } from 'three/addons/utils/UVsDebug.js'; /* * This is to help debug UVs problems in geometry, diff --git a/examples/models/collada/kawada-hironx.dae b/examples/models/collada/kawada-hironx.dae deleted file mode 100644 index d59d2e949950b8..00000000000000 --- a/examples/models/collada/kawada-hironx.dae +++ /dev/null @@ -1,4680 +0,0 @@ - - - - - OpenRAVE Collada Writer v0.3.5 - - 2014-07-09T17:36:23.000000 - 2014-07-09T17:36:23.000000 - - Z_UP - - - - - 0 0 0 - 1 0 0 0 - - - - - - - - - 0.058085 -0.015039 3.9978e-06 0.053868 -0.026424 3.9978e-06 0.059923 -0.003039 3.9978e-06 0.053868 -0.026424 3.9978e-06 0.047446 -0.036727 3.9978e-06 0.059923 -0.003039 3.9978e-06 0.059923 -0.003039 0.012004 0.058085 -0.015039 3.9978e-06 0.059923 -0.003039 3.9978e-06 0.058085 -0.015039 3.9978e-06 0.058085 -0.015039 0.012004 0.053868 -0.026424 3.9978e-06 0.047446 -0.036727 3.9978e-06 0.039082 -0.045526 3.9978e-06 0.059923 -0.003039 3.9978e-06 0.053868 -0.026424 0.012004 0.047446 -0.036727 3.9978e-06 0.053868 -0.026424 3.9978e-06 0.059923 -0.003039 3.9978e-06 0.059308 0.009084999999999999 0.012004 0.059923 -0.003039 0.012004 0.058085 -0.015039 3.9978e-06 0.059923 -0.003039 0.012004 0.058085 -0.015039 0.012004 0.053868 -0.026424 3.9978e-06 0.058085 -0.015039 0.012004 0.053868 -0.026424 0.012004 0.039082 -0.045526 3.9978e-06 0.029118 -0.052461 3.9978e-06 0.059923 -0.003039 3.9978e-06 0.047446 -0.036727 0.012004 0.039082 -0.045526 3.9978e-06 0.047446 -0.036727 3.9978e-06 0.053868 -0.026424 0.012004 0.047446 -0.036727 0.012004 0.047446 -0.036727 3.9978e-06 0.059308 0.009084999999999999 0.012004 0.059923 -0.003039 3.9978e-06 0.059308 0.009084999999999999 3.9978e-06 0.059308 0.009084999999999999 0.012004 0.056265 0.020838 0.012004 0.059923 -0.003039 0.012004 0.053868 -0.026424 0.012004 0.058085 -0.015039 0.012004 0.059923 -0.003039 0.012004 0.029118 -0.052461 3.9978e-06 0.017962 -0.057249 3.9978e-06 0.059923 -0.003039 3.9978e-06 0.029118 -0.052461 3.9978e-06 0.039082 -0.045526 3.9978e-06 0.039082 -0.045526 0.012004 0.039082 -0.045526 3.9978e-06 0.047446 -0.036727 0.012004 0.039082 -0.045526 0.012004 0.047446 -0.036727 0.012004 0.053868 -0.026424 0.012004 0.059923 -0.003039 0.012004 0.056265 0.020838 3.9978e-06 0.059308 0.009084999999999999 3.9978e-06 0.059923 -0.003039 3.9978e-06 0.056265 0.020838 0.012004 0.059308 0.009084999999999999 0.012004 0.059308 0.009084999999999999 3.9978e-06 0.056265 0.020838 0.012004 0.050919 0.031738 0.012004 0.059923 -0.003039 0.012004 0.017962 -0.057249 3.9978e-06 0.00607 -0.059692 3.9978e-06 0.059923 -0.003039 3.9978e-06 0.029118 -0.052461 0.012004 0.017962 -0.057249 3.9978e-06 0.029118 -0.052461 3.9978e-06 0.029118 -0.052461 0.012004 0.029118 -0.052461 3.9978e-06 0.039082 -0.045526 0.012004 0.039082 -0.045526 0.012004 0.047446 -0.036727 0.012004 0.059923 -0.003039 0.012004 0.050919 0.031738 3.9978e-06 0.056265 0.020838 3.9978e-06 0.059923 -0.003039 3.9978e-06 0.056265 0.020838 3.9978e-06 0.056265 0.020838 0.012004 0.059308 0.009084999999999999 3.9978e-06 0.050919 0.031738 0.012004 0.043488 0.041338 0.012004 0.059923 -0.003039 0.012004 0.056265 0.020838 3.9978e-06 0.050919 0.031738 0.012004 0.056265 0.020838 0.012004 0.00607 -0.059692 3.9978e-06 -0.00607 -0.059692 3.9978e-06 0.059923 -0.003039 3.9978e-06 0.017962 -0.057249 0.012004 0.00607 -0.059692 3.9978e-06 0.017962 -0.057249 3.9978e-06 0.017962 -0.057249 0.012004 0.017962 -0.057249 3.9978e-06 0.029118 -0.052461 0.012004 0.029118 -0.052461 0.012004 0.039082 -0.045526 0.012004 0.059923 -0.003039 0.012004 0.043488 0.041338 3.9978e-06 0.050919 0.031738 3.9978e-06 0.059923 -0.003039 3.9978e-06 0.050919 0.031738 3.9978e-06 0.050919 0.031738 0.012004 0.056265 0.020838 3.9978e-06 0.043488 0.041338 0.012004 0.034276 0.049246 0.012004 0.059923 -0.003039 0.012004 0.050919 0.031738 3.9978e-06 0.043488 0.041338 0.012004 0.050919 0.031738 0.012004 -0.00607 -0.059692 3.9978e-06 -0.017962 -0.057248 3.9978e-06 0.059923 -0.003039 3.9978e-06 -0.00607 -0.059692 3.9978e-06 0.00607 -0.059692 3.9978e-06 0.00607 -0.059692 0.012004 0.00607 -0.059692 0.012004 0.00607 -0.059692 3.9978e-06 0.017962 -0.057249 0.012004 0.017962 -0.057249 0.012004 0.029118 -0.052461 0.012004 0.059923 -0.003039 0.012004 0.034276 0.049246 3.9978e-06 0.043488 0.041338 3.9978e-06 0.059923 -0.003039 3.9978e-06 0.043488 0.041338 0.012004 0.050919 0.031738 3.9978e-06 0.043488 0.041338 3.9978e-06 0.059923 -0.003039 0.012004 0.034276 0.049246 0.012004 0.023662 0.055137 0.012004 0.043488 0.041338 3.9978e-06 0.034276 0.049246 0.012004 0.043488 0.041338 0.012004 -0.017962 -0.057248 3.9978e-06 -0.029118 -0.052461 3.9978e-06 0.059923 -0.003039 3.9978e-06 -0.00607 -0.059692 0.012004 -0.017962 -0.057248 3.9978e-06 -0.00607 -0.059692 3.9978e-06 -0.00607 -0.059692 0.012004 -0.00607 -0.059692 3.9978e-06 0.00607 -0.059692 0.012004 0.00607 -0.059692 0.012004 0.017962 -0.057249 0.012004 0.059923 -0.003039 0.012004 0.059923 -0.003039 3.9978e-06 0.023662 0.055137 3.9978e-06 0.034276 0.049246 3.9978e-06 0.034276 0.049246 0.012004 0.043488 0.041338 3.9978e-06 0.034276 0.049246 3.9978e-06 0.059923 -0.003039 0.012004 0.023662 0.055137 0.012004 0.012078 0.058772 0.012004 0.034276 0.049246 0.012004 0.034276 0.049246 3.9978e-06 0.023662 0.055137 0.012004 -0.029118 -0.052461 3.9978e-06 -0.039082 -0.045525 3.9978e-06 0.059923 -0.003039 3.9978e-06 -0.017962 -0.057248 0.012004 -0.029118 -0.052461 3.9978e-06 -0.017962 -0.057248 3.9978e-06 -0.017962 -0.057248 0.012004 -0.017962 -0.057248 3.9978e-06 -0.00607 -0.059692 0.012004 0.00607 -0.059692 0.012004 0.059923 -0.003039 0.012004 -0.00607 -0.059692 0.012004 0.059923 -0.003039 3.9978e-06 0.012078 0.058772 3.9978e-06 0.023662 0.055137 3.9978e-06 0.023662 0.055137 0.012004 0.034276 0.049246 3.9978e-06 0.023662 0.055137 3.9978e-06 0.059923 -0.003039 0.012004 0.012078 0.058772 0.012004 0 0.06 0.012004 0.023662 0.055137 0.012004 0.023662 0.055137 3.9978e-06 0.012078 0.058772 0.012004 -0.039082 -0.045525 3.9978e-06 -0.047447 -0.036726 3.9978e-06 0.059923 -0.003039 3.9978e-06 -0.029118 -0.052461 0.012004 -0.039082 -0.045525 3.9978e-06 -0.029118 -0.052461 3.9978e-06 -0.029118 -0.052461 0.012004 -0.029118 -0.052461 3.9978e-06 -0.017962 -0.057248 0.012004 0.0287029 -0.0248996 0.012004 0.059923 -0.003039 0.012004 0.02874 -0.0248531 0.012004 0.02874 -0.0248531 0.012004 0.059923 -0.003039 0.012004 0.0288683 -0.0246535 0.012004 -0.00607 -0.059692 0.012004 0.0205718 -0.0319454 0.012004 0.0205227 -0.0319789 0.012004 -0.00607 -0.059692 0.012004 0.0205227 -0.0319789 0.012004 0.0141859 -0.0348726 0.012004 -0.00607 -0.059692 0.012004 0.0141859 -0.0348726 0.012004 -0.017962 -0.057248 0.012004 0.0205718 -0.0319454 0.012004 -0.00607 -0.059692 0.012004 0.059923 -0.003039 0.012004 0.0287029 -0.0248996 0.012004 0.0205718 -0.0319454 0.012004 0.059923 -0.003039 0.012004 0.059923 -0.003039 3.9978e-06 0 0.06 3.9978e-06 0.012078 0.058772 3.9978e-06 0.012078 0.058772 0.012004 0.023662 0.055137 3.9978e-06 0.012078 0.058772 3.9978e-06 0.0303482 0.0223502 0.012004 0.059923 -0.003039 0.012004 0.0287232 0.0248787 0.012004 0.0175543 0.0333335 0.012004 0.0204936 0.0319912 0.012004 0 0.06 0.012004 0.0204936 0.0319912 0.012004 0.0205463 0.0319665 0.012004 0 0.06 0.012004 0.0175543 0.0333335 0.012004 0 0.06 0.012004 -0.012078 0.058772 0.012004 0.0287232 0.0248787 0.012004 0.059923 -0.003039 0.012004 0 0.06 0.012004 0.0286773 0.0249207 0.012004 0.0287232 0.0248787 0.012004 0 0.06 0.012004 0.0205463 0.0319665 0.012004 0.0286773 0.0249207 0.012004 0 0.06 0.012004 0.012078 0.058772 0.012004 0.012078 0.058772 3.9978e-06 0 0.06 0.012004 -0.047447 -0.036726 3.9978e-06 -0.053868 -0.026423 3.9978e-06 0.059923 -0.003039 3.9978e-06 -0.039082 -0.045525 3.9978e-06 -0.039082 -0.045525 0.012004 -0.047447 -0.036726 3.9978e-06 -0.039082 -0.045525 0.012004 -0.039082 -0.045525 3.9978e-06 -0.029118 -0.052461 0.012004 0.0107354 -0.0364483 0.012004 -0.017962 -0.057248 0.012004 0.0141859 -0.0348726 0.012004 0.0106785 -0.0364659 0.012004 -0.017962 -0.057248 0.012004 0.0107354 -0.0364483 0.012004 -0.00243566 -0.037651 0.012004 -0.029118 -0.052461 0.012004 -0.00746604 -0.0460603 0.012004 -0.029118 -0.052461 0.012004 -0.017962 -0.057248 0.012004 -0.00746604 -0.0460603 0.012004 0.0106785 -0.0364659 0.012004 2.8736e-05 -0.0379968 0.012004 -0.00746604 -0.0460603 0.012004 2.8736e-05 -0.0379968 0.012004 -3.07307e-05 -0.0379968 0.012004 -0.00746604 -0.0460603 0.012004 -3.07307e-05 -0.0379968 0.012004 -0.00243566 -0.037651 0.012004 -0.00746604 -0.0460603 0.012004 -0.017962 -0.057248 0.012004 0.0106785 -0.0364659 0.012004 -0.00746604 -0.0460603 0.012004 0.0288683 -0.0246535 0.012004 0.059923 -0.003039 0.012004 0.033241 -0.0178488 0.012004 0.0317922 -0.0204201 0.0483835 0.033241 -0.0178488 0.012004 0.0345563 -0.0158019 0.012004 0.0317922 -0.0204201 0.0483835 0.0288683 -0.0246535 0.012004 0.033241 -0.0178488 0.012004 0.0317922 -0.0204201 0.0483835 0.02874 -0.0248531 0.012004 0.0288683 -0.0246535 0.012004 0.0317922 -0.0204201 0.0483835 0.032909 -0.018999 0.08476300000000001 0.02874 -0.0248531 0.012004 0.0317922 -0.0204201 0.0483835 0.0345563 -0.0158019 0.012004 0.032909 -0.018999 0.08476300000000001 0.0287029 -0.0248996 0.012004 0.02874 -0.0248531 0.012004 0.025846 -0.027856 0.08476300000000001 0.02874 -0.0248531 0.012004 0.032909 -0.018999 0.08476300000000001 0.025846 -0.027856 0.08476300000000001 0.025846 -0.027856 0.08476300000000001 0.0205718 -0.0319454 0.012004 0.0287029 -0.0248996 0.012004 0.0205718 -0.0319454 0.012004 0.025846 -0.027856 0.08476300000000001 0.016487 -0.034236 0.08476300000000001 0.0205227 -0.0319789 0.012004 0.0205718 -0.0319454 0.012004 0.016487 -0.034236 0.08476300000000001 0.0107354 -0.0364483 0.012004 0.0141859 -0.0348726 0.012004 0.0157073 -0.034385 0.0483835 0.0141859 -0.0348726 0.012004 0.0205227 -0.0319789 0.012004 0.0157073 -0.034385 0.0483835 0.0205227 -0.0319789 0.012004 0.016487 -0.034236 0.08476300000000001 0.0157073 -0.034385 0.0483835 0.016487 -0.034236 0.08476300000000001 0.0107354 -0.0364483 0.012004 0.0157073 -0.034385 0.0483835 0.059923 -0.003039 3.9978e-06 -0.012078 0.058772 3.9978e-06 0 0.06 3.9978e-06 0 0.06 0.012004 0.012078 0.058772 3.9978e-06 0 0.06 3.9978e-06 0.0350008 0.0143076 0.012004 0.059923 -0.003039 0.012004 0.0345692 0.015777 0.012004 0.0345395 0.0158285 0.012004 0.059923 -0.003039 0.012004 0.0303482 0.0223502 0.012004 0.0345692 0.015777 0.012004 0.059923 -0.003039 0.012004 0.0345395 0.0158285 0.012004 0 0.06 0.012004 0 0.06 3.9978e-06 -0.012078 0.058772 0.012004 -0.012078 0.058772 0.012004 0.0107063 0.0364606 0.012004 0.0175543 0.0333335 0.012004 0.00121041 0.0378267 0.012004 0.0106488 0.0364691 0.012004 -0.00305337 0.0460527 0.012004 0.0106488 0.0364691 0.012004 0.0107063 0.0364606 0.012004 -0.00305337 0.0460527 0.012004 -0.012078 0.058772 0.012004 -0.023661 0.055138 0.012004 -0.00305337 0.0460527 0.012004 -0.023661 0.055138 0.012004 0.00121041 0.0378267 0.012004 -0.00305337 0.0460527 0.012004 0.0107063 0.0364606 0.012004 -0.012078 0.058772 0.012004 -0.00305337 0.0460527 0.012004 0.0109525 0.0363865 0.08476300000000001 0.0204936 0.0319912 0.012004 0.0175543 0.0333335 0.012004 0.0109525 0.0363865 0.08476300000000001 0.0175543 0.0333335 0.012004 0.0107063 0.0364606 0.012004 0.0109525 0.0363865 0.08476300000000001 0.020975 0.031683 0.08476300000000001 0.0204936 0.0319912 0.012004 0.020975 0.031683 0.08476300000000001 0.0205463 0.0319665 0.012004 0.0204936 0.0319912 0.012004 0.0286773 0.0249207 0.012004 0.0205463 0.0319665 0.012004 0.020975 0.031683 0.08476300000000001 0.0286773 0.0249207 0.012004 0.020975 0.031683 0.08476300000000001 0.029709 0.023693 0.08476300000000001 0.0287232 0.0248787 0.012004 0.0286773 0.0249207 0.012004 0.029709 0.023693 0.08476300000000001 0.0303482 0.0223502 0.012004 0.0287232 0.0248787 0.012004 0.029709 0.023693 0.08476300000000001 0.0345395 0.0158285 0.012004 0.0303482 0.0223502 0.012004 0.029709 0.023693 0.08476300000000001 -0.053868 -0.026423 3.9978e-06 -0.058085 -0.015039 3.9978e-06 0.059923 -0.003039 3.9978e-06 -0.047447 -0.036726 3.9978e-06 -0.047447 -0.036726 0.012004 -0.053868 -0.026423 3.9978e-06 -0.047447 -0.036726 3.9978e-06 -0.039082 -0.045525 0.012004 -0.047447 -0.036726 0.012004 -0.0107364 -0.0364483 0.012004 -0.0142217 -0.0348567 0.012004 -0.0207588 -0.0436589 0.012004 -0.0142217 -0.0348567 0.012004 -0.039082 -0.045525 0.012004 -0.0207588 -0.0436589 0.012004 -0.039082 -0.045525 0.012004 -0.029118 -0.052461 0.012004 -0.0207588 -0.0436589 0.012004 -0.029118 -0.052461 0.012004 -0.00243566 -0.037651 0.012004 -0.0207588 -0.0436589 0.012004 -0.00243566 -0.037651 0.012004 -0.0106795 -0.0364659 0.012004 -0.0207588 -0.0436589 0.012004 -0.0106795 -0.0364659 0.012004 -0.0107364 -0.0364483 0.012004 -0.0207588 -0.0436589 0.012004 0.016487 -0.034236 0.08476300000000001 0.005663 -0.037575 0.08476300000000001 0.0107354 -0.0364483 0.012004 0.005663 -0.037575 0.08476300000000001 0.0106785 -0.0364659 0.012004 0.0107354 -0.0364483 0.012004 2.8736e-05 -0.0379968 0.012004 0.0106785 -0.0364659 0.012004 0.005663 -0.037575 0.08476300000000001 -4.99887e-07 -0.0377859 0.0483835 -3.07307e-05 -0.0379968 0.012004 2.8736e-05 -0.0379968 0.012004 -4.99887e-07 -0.0377859 0.0483835 -0.005664 -0.037575 0.08476300000000001 -3.07307e-05 -0.0379968 0.012004 -4.99887e-07 -0.0377859 0.0483835 0.005663 -0.037575 0.08476300000000001 -0.005664 -0.037575 0.08476300000000001 -4.99887e-07 -0.0377859 0.0483835 2.8736e-05 -0.0379968 0.012004 0.005663 -0.037575 0.08476300000000001 -0.0106795 -0.0364659 0.012004 -0.00243566 -0.037651 0.012004 -0.00538246 -0.0374214 0.0483835 -0.00243566 -0.037651 0.012004 -3.07307e-05 -0.0379968 0.012004 -0.00538246 -0.0374214 0.0483835 -3.07307e-05 -0.0379968 0.012004 -0.005664 -0.037575 0.08476300000000001 -0.00538246 -0.0374214 0.0483835 -0.005664 -0.037575 0.08476300000000001 -0.0106795 -0.0364659 0.012004 -0.00538246 -0.0374214 0.0483835 0.033241 -0.0178488 0.012004 0.059923 -0.003039 0.012004 0.0345563 -0.0158019 0.012004 0.0345563 -0.0158019 0.012004 0.059923 -0.003039 0.012004 0.034578 -0.0157465 0.012004 0.034578 -0.0157465 0.012004 0.059923 -0.003039 0.012004 0.0351934 -0.0136512 0.012004 0.0345563 -0.0158019 0.012004 0.034578 -0.0157465 0.012004 0.032909 -0.018999 0.08476300000000001 0.034578 -0.0157465 0.012004 0.037047 -0.008455000000000001 0.08476300000000001 0.032909 -0.018999 0.08476300000000001 0.045466 -0.02625 0.10962 0.025846 -0.027856 0.08476300000000001 0.032909 -0.018999 0.08476300000000001 0.025846 -0.027856 0.08476300000000001 0.035709 -0.038485 0.10962 0.016487 -0.034236 0.08476300000000001 -0.023661 0.055138 3.9978e-06 -0.012078 0.058772 3.9978e-06 0.059923 -0.003039 3.9978e-06 -0.012078 0.058772 0.012004 0 0.06 3.9978e-06 -0.012078 0.058772 3.9978e-06 0.0361993 0.0106487 0.0483835 0.0350008 0.0143076 0.012004 0.0345692 0.015777 0.012004 0.0361993 0.0106487 0.0483835 0.0362337 0.0101097 0.012004 0.0350008 0.0143076 0.012004 0.0361993 0.0106487 0.0483835 0.0372361 0.00669678 0.012004 0.0362337 0.0101097 0.012004 0.0361993 0.0106487 0.0483835 0.0376012 0.00545349 0.012004 0.0372361 0.00669678 0.012004 0.0361993 0.0106487 0.0483835 0.035373 0.013884 0.08476300000000001 0.0376012 0.00545349 0.012004 0.0361993 0.0106487 0.0483835 0.0345692 0.015777 0.012004 0.035373 0.013884 0.08476300000000001 0.0362337 0.0101097 0.012004 0.059923 -0.003039 0.012004 0.0350008 0.0143076 0.012004 0.0345692 0.015777 0.012004 0.0345395 0.0158285 0.012004 0.035373 0.013884 0.08476300000000001 0.0345395 0.0158285 0.012004 0.029709 0.023693 0.08476300000000001 0.035373 0.013884 0.08476300000000001 -1e-06 0.038 0.08476300000000001 0.0106488 0.0364691 0.012004 0.00121041 0.0378267 0.012004 -1e-06 0.038 0.08476300000000001 0.00121041 0.0378267 0.012004 -1e-06 0.038001 0.012004 -1e-06 0.038 0.08476300000000001 0.0109525 0.0363865 0.08476300000000001 0.0106488 0.0364691 0.012004 0.0109525 0.0363865 0.08476300000000001 0.0107063 0.0364606 0.012004 0.0106488 0.0364691 0.012004 -0.012078 0.058772 0.012004 -0.012078 0.058772 3.9978e-06 -0.023661 0.055138 0.012004 -0.023661 0.055138 0.012004 -1e-06 0.038001 0.012004 0.00121041 0.0378267 0.012004 -5.85005e-05 0.0379925 0.012004 -1e-06 0.038001 0.012004 -0.0165328 0.0457325 0.012004 -0.023661 0.055138 0.012004 -0.034276 0.049246 0.012004 -0.0165328 0.0457325 0.012004 -0.034276 0.049246 0.012004 -0.0110007 0.0363271 0.012004 -0.0165328 0.0457325 0.012004 -0.0110007 0.0363271 0.012004 -0.0107083 0.0364606 0.012004 -0.0165328 0.0457325 0.012004 -0.0107083 0.0364606 0.012004 -5.85005e-05 0.0379925 0.012004 -0.0165328 0.0457325 0.012004 -1e-06 0.038001 0.012004 -0.023661 0.055138 0.012004 -0.0165328 0.0457325 0.012004 0.0109525 0.0363865 0.08476300000000001 0.015474 0.050168 0.10962 0.020975 0.031683 0.08476300000000001 0.029574 0.043378 0.10962 0.029709 0.023693 0.08476300000000001 0.020975 0.031683 0.08476300000000001 -0.058085 -0.015039 3.9978e-06 -0.059923 -0.003039 3.9978e-06 0.059923 -0.003039 3.9978e-06 -0.053868 -0.026423 3.9978e-06 -0.053868 -0.026423 0.012004 -0.058085 -0.015039 3.9978e-06 -0.047447 -0.036726 0.012004 -0.053868 -0.026423 0.012004 -0.053868 -0.026423 3.9978e-06 -0.0236663 -0.0292649 0.012004 -0.047447 -0.036726 0.012004 -0.0308344 -0.0373949 0.012004 -0.047447 -0.036726 0.012004 -0.039082 -0.045525 0.012004 -0.0308344 -0.0373949 0.012004 -0.039082 -0.045525 0.012004 -0.0142217 -0.0348567 0.012004 -0.0308344 -0.0373949 0.012004 -0.0142217 -0.0348567 0.012004 -0.0205237 -0.0319789 0.012004 -0.0308344 -0.0373949 0.012004 -0.0205237 -0.0319789 0.012004 -0.0205728 -0.0319454 0.012004 -0.0308344 -0.0373949 0.012004 -0.0205728 -0.0319454 0.012004 -0.0236663 -0.0292649 0.012004 -0.0308344 -0.0373949 0.012004 -0.0157083 -0.034385 0.0483835 -0.0205237 -0.0319789 0.012004 -0.0142217 -0.0348567 0.012004 -0.0157083 -0.034385 0.0483835 -0.016488 -0.034236 0.08476300000000001 -0.0205237 -0.0319789 0.012004 -0.0157083 -0.034385 0.0483835 -0.0107364 -0.0364483 0.012004 -0.016488 -0.034236 0.08476300000000001 -0.0157083 -0.034385 0.0483835 -0.0142217 -0.0348567 0.012004 -0.0107364 -0.0364483 0.012004 -0.005664 -0.037575 0.08476300000000001 -0.016488 -0.034236 0.08476300000000001 -0.0107364 -0.0364483 0.012004 -0.005664 -0.037575 0.08476300000000001 -0.0107364 -0.0364483 0.012004 -0.0106795 -0.0364659 0.012004 0.005663 -0.037575 0.08476300000000001 0.016487 -0.034236 0.08476300000000001 0.022779 -0.0473 0.10962 0.005663 -0.037575 0.08476300000000001 0.007823999999999999 -0.051913 0.10962 -0.005664 -0.037575 0.08476300000000001 0.0362448 -0.010629 0.0483835 0.036922 -0.0077657 0.012004 0.03761 -0.005423 0.012004 0.0362448 -0.010629 0.0483835 0.0361165 -0.0105082 0.012004 0.036922 -0.0077657 0.012004 0.0362448 -0.010629 0.0483835 0.0351934 -0.0136512 0.012004 0.0361165 -0.0105082 0.012004 0.0362448 -0.010629 0.0483835 0.034578 -0.0157465 0.012004 0.0351934 -0.0136512 0.012004 0.0362448 -0.010629 0.0483835 0.037047 -0.008455000000000001 0.08476300000000001 0.034578 -0.0157465 0.012004 0.0362448 -0.010629 0.0483835 0.03761 -0.005423 0.012004 0.037047 -0.008455000000000001 0.08476300000000001 0.0351934 -0.0136512 0.012004 0.059923 -0.003039 0.012004 0.0361165 -0.0105082 0.012004 0.051183 -0.011682 0.10962 0.032909 -0.018999 0.08476300000000001 0.037047 -0.008455000000000001 0.08476300000000001 0.051183 -0.011682 0.10962 0.045466 -0.02625 0.10962 0.032909 -0.018999 0.08476300000000001 0.045466 -0.02625 0.10962 0.035709 -0.038485 0.10962 0.025846 -0.027856 0.08476300000000001 0.022779 -0.0473 0.10962 0.016487 -0.034236 0.08476300000000001 0.035709 -0.038485 0.10962 -0.034276 0.049246 3.9978e-06 -0.023661 0.055138 3.9978e-06 0.059923 -0.003039 3.9978e-06 -0.012078 0.058772 3.9978e-06 -0.023661 0.055138 3.9978e-06 -0.023661 0.055138 0.012004 0.0372361 0.00669678 0.012004 0.059923 -0.003039 0.012004 0.0362337 0.0101097 0.012004 0.0376145 0.00396037 0.012004 0.059923 -0.003039 0.012004 0.0376145 0.00539551 0.012004 0.0376145 0.00539551 0.012004 0.059923 -0.003039 0.012004 0.0376012 0.00545349 0.012004 0.0376012 0.00545349 0.012004 0.059923 -0.003039 0.012004 0.0372361 0.00669678 0.012004 0.037893 0.00284 0.08476300000000001 0.0376145 0.00539551 0.012004 0.0376012 0.00545349 0.012004 0.035373 0.013884 0.08476300000000001 0.037893 0.00284 0.08476300000000001 0.0376012 0.00545349 0.012004 0.029709 0.023693 0.08476300000000001 0.04993 0.016224 0.10962 0.035373 0.013884 0.08476300000000001 -5.85005e-05 0.0379925 0.012004 -0.0109535 0.0363865 0.08476300000000001 -1e-06 0.038 0.08476300000000001 -1e-06 0.038001 0.012004 -5.85005e-05 0.0379925 0.012004 -1e-06 0.038 0.08476300000000001 -1e-06 0.0525 0.10962 0.0109525 0.0363865 0.08476300000000001 -1e-06 0.038 0.08476300000000001 -0.023661 0.055138 0.012004 -0.023661 0.055138 3.9978e-06 -0.034276 0.049246 0.012004 -0.0204946 0.0319912 0.012004 -0.0110007 0.0363271 0.012004 -0.0272438 0.0404481 0.012004 -0.0110007 0.0363271 0.012004 -0.034276 0.049246 0.012004 -0.0272438 0.0404481 0.012004 -0.034276 0.049246 0.012004 -0.043487 0.041338 0.012004 -0.0272438 0.0404481 0.012004 -0.043487 0.041338 0.012004 -0.0209118 0.0316502 0.012004 -0.0272438 0.0404481 0.012004 -0.0209118 0.0316502 0.012004 -0.020545 0.031968 0.012004 -0.0272438 0.0404481 0.012004 -0.020545 0.031968 0.012004 -0.0204946 0.0319912 0.012004 -0.0272438 0.0404481 0.012004 -0.0110007 0.0363271 0.012004 -0.0204946 0.0319912 0.012004 -0.0109535 0.0363865 0.08476300000000001 -0.0107083 0.0364606 0.012004 -0.0110007 0.0363271 0.012004 -0.0109535 0.0363865 0.08476300000000001 -5.85005e-05 0.0379925 0.012004 -0.0107083 0.0364606 0.012004 -0.0109535 0.0363865 0.08476300000000001 -1e-06 0.0525 0.10962 0.015474 0.050168 0.10962 0.0109525 0.0363865 0.08476300000000001 0.029574 0.043378 0.10962 0.020975 0.031683 0.08476300000000001 0.015474 0.050168 0.10962 0.029709 0.023693 0.08476300000000001 0.029574 0.043378 0.10962 0.044327 0.028131 0.10962 -0.059923 -0.003039 3.9978e-06 -0.059308 0.009086 3.9978e-06 0.059923 -0.003039 3.9978e-06 -0.058085 -0.015039 0.012004 -0.059923 -0.003039 3.9978e-06 -0.058085 -0.015039 3.9978e-06 -0.053868 -0.026423 0.012004 -0.058085 -0.015039 0.012004 -0.058085 -0.015039 3.9978e-06 -0.0287039 -0.0248996 0.012004 -0.0287162 -0.0248871 0.012004 -0.0387671 -0.0292007 0.012004 -0.0287162 -0.0248871 0.012004 -0.0307655 -0.0216754 0.012004 -0.0387671 -0.0292007 0.012004 -0.0307655 -0.0216754 0.012004 -0.053868 -0.026423 0.012004 -0.0387671 -0.0292007 0.012004 -0.053868 -0.026423 0.012004 -0.047447 -0.036726 0.012004 -0.0387671 -0.0292007 0.012004 -0.047447 -0.036726 0.012004 -0.0236663 -0.0292649 0.012004 -0.0387671 -0.0292007 0.012004 -0.0236663 -0.0292649 0.012004 -0.0287039 -0.0248996 0.012004 -0.0387671 -0.0292007 0.012004 -0.0205728 -0.0319454 0.012004 -0.016488 -0.034236 0.08476300000000001 -0.025847 -0.027856 0.08476300000000001 -0.0205728 -0.0319454 0.012004 -0.0205237 -0.0319789 0.012004 -0.016488 -0.034236 0.08476300000000001 -0.0287039 -0.0248996 0.012004 -0.0236663 -0.0292649 0.012004 -0.0247574 -0.0285598 0.0483835 -0.0236663 -0.0292649 0.012004 -0.0205728 -0.0319454 0.012004 -0.0247574 -0.0285598 0.0483835 -0.0205728 -0.0319454 0.012004 -0.025847 -0.027856 0.08476300000000001 -0.0247574 -0.0285598 0.0483835 -0.025847 -0.027856 0.08476300000000001 -0.0287039 -0.0248996 0.012004 -0.0247574 -0.0285598 0.0483835 -0.016488 -0.034236 0.08476300000000001 -0.005664 -0.037575 0.08476300000000001 -0.007825 -0.051913 0.10962 0.007823999999999999 -0.051913 0.10962 0.005663 -0.037575 0.08476300000000001 0.022779 -0.0473 0.10962 -0.007825 -0.051913 0.10962 -0.005664 -0.037575 0.08476300000000001 0.007823999999999999 -0.051913 0.10962 0.036922 -0.0077657 0.012004 0.059923 -0.003039 0.012004 0.03761 -0.005423 0.012004 0.03761 -0.005423 0.012004 0.059923 -0.003039 0.012004 0.0376145 -0.0053637 0.012004 0.0376145 -0.0053637 0.012004 0.059923 -0.003039 0.012004 0.0376145 -0.00530751 0.012004 0.0361165 -0.0105082 0.012004 0.059923 -0.003039 0.012004 0.036922 -0.0077657 0.012004 0.03761 -0.005423 0.012004 0.0376145 -0.0053637 0.012004 0.037047 -0.008455000000000001 0.08476300000000001 0.0376145 -0.0053637 0.012004 0.037893 0.00284 0.08476300000000001 0.037047 -0.008455000000000001 0.08476300000000001 0.051183 -0.011682 0.10962 0.037047 -0.008455000000000001 0.08476300000000001 0.052353 0.003924 0.10962 0.045466 -0.02625 0.10962 0.051183 -0.011682 0.10962 0.047503 -0.022353 0.20862 0.040452 -0.033465 0.20862 0.035709 -0.038485 0.10962 0.045466 -0.02625 0.10962 0.022779 -0.0473 0.10962 0.035709 -0.038485 0.10962 0.030859 -0.042473 0.20862 -0.043487 0.041338 3.9978e-06 -0.034276 0.049246 3.9978e-06 0.059923 -0.003039 3.9978e-06 -0.023661 0.055138 3.9978e-06 -0.034276 0.049246 3.9978e-06 -0.034276 0.049246 0.012004 0.0377537 1.59047e-05 0.0483835 0.0376145 0.00396037 0.012004 0.0376145 0.00539551 0.012004 0.0377537 1.59047e-05 0.0483835 0.0376145 0.00154547 0.012004 0.0376145 0.00396037 0.012004 0.0377537 1.59047e-05 0.0483835 0.0376145 -0.0007703709999999999 0.012004 0.0376145 0.00154547 0.012004 0.0377537 1.59047e-05 0.0483835 0.0376145 -0.003039 0.012004 0.0376145 -0.0007703709999999999 0.012004 0.0377537 1.59047e-05 0.0483835 0.0376145 -0.00530751 0.012004 0.0376145 -0.003039 0.012004 0.0377537 1.59047e-05 0.0483835 0.0376145 -0.0053637 0.012004 0.0376145 -0.00530751 0.012004 0.0377537 1.59047e-05 0.0483835 0.037893 0.00284 0.08476300000000001 0.0376145 -0.0053637 0.012004 0.0377537 1.59047e-05 0.0483835 0.0376145 0.00539551 0.012004 0.037893 0.00284 0.08476300000000001 0.0376145 0.00154547 0.012004 0.059923 -0.003039 0.012004 0.0376145 0.00396037 0.012004 0.035373 0.013884 0.08476300000000001 0.04993 0.016224 0.10962 0.037893 0.00284 0.08476300000000001 0.044327 0.028131 0.10962 0.04993 0.016224 0.10962 0.029709 0.023693 0.08476300000000001 -0.0109535 0.0363865 0.08476300000000001 -0.015475 0.050168 0.10962 -1e-06 0.038 0.08476300000000001 -0.015475 0.050168 0.10962 -1e-06 0.0525 0.10962 -1e-06 0.038 0.08476300000000001 -0.034276 0.049246 0.012004 -0.034276 0.049246 3.9978e-06 -0.043487 0.041338 0.012004 -0.0286761 0.0249222 0.012004 -0.0209118 0.0316502 0.012004 -0.0359154 0.0330646 0.012004 -0.0209118 0.0316502 0.012004 -0.043487 0.041338 0.012004 -0.0359154 0.0330646 0.012004 -0.043487 0.041338 0.012004 -0.050919 0.031738 0.012004 -0.0359154 0.0330646 0.012004 -0.050919 0.031738 0.012004 -0.0287781 0.0247912 0.012004 -0.0359154 0.0330646 0.012004 -0.0287781 0.0247912 0.012004 -0.0287162 0.0248881 0.012004 -0.0359154 0.0330646 0.012004 -0.0287162 0.0248881 0.012004 -0.0286761 0.0249222 0.012004 -0.0359154 0.0330646 0.012004 -0.0209118 0.0316502 0.012004 -0.0286761 0.0249222 0.012004 -0.020545 0.031968 0.08476300000000001 -0.020545 0.031968 0.012004 -0.0209118 0.0316502 0.012004 -0.020545 0.031968 0.08476300000000001 -0.020545 0.031968 0.08476300000000001 -0.0109535 0.0363865 0.08476300000000001 -0.0204946 0.0319912 0.012004 -0.020545 0.031968 0.08476300000000001 -0.0204946 0.0319912 0.012004 -0.020545 0.031968 0.012004 0.015474 0.050168 0.10962 -1e-06 0.0525 0.10962 0 0.0525 0.15342 0.013056 0.050851 0.15342 0.029574 0.043378 0.10962 0.015474 0.050168 0.10962 0.044327 0.028131 0.10962 0.029574 0.043378 0.10962 0.035938 0.038271 0.20862 -0.059308 0.009086 3.9978e-06 -0.056265 0.020838 3.9978e-06 0.059923 -0.003039 3.9978e-06 -0.059923 -0.003039 3.9978e-06 -0.059923 -0.003039 0.012004 -0.059308 0.009086 3.9978e-06 -0.059923 -0.003039 3.9978e-06 -0.058085 -0.015039 0.012004 -0.059923 -0.003039 0.012004 -0.0307655 -0.0216754 0.012004 -0.034635 -0.0156111 0.012004 -0.0347674 -0.0156111 0.012004 -0.0501218 -0.0156111 0.012004 -0.0501369 -0.0155722 0.012004 -0.058085 -0.015039 0.012004 -0.0501369 -0.0155722 0.012004 -0.0501448 -0.0155478 0.012004 -0.058085 -0.015039 0.012004 -0.0501448 -0.0155478 0.012004 -0.0504654 -0.0142642 0.012004 -0.058085 -0.015039 0.012004 -0.053868 -0.026423 0.012004 -0.0501218 -0.0156111 0.012004 -0.058085 -0.015039 0.012004 -0.0347674 -0.0156111 0.012004 -0.0501218 -0.0156111 0.012004 -0.0444253 -0.0203436 0.012004 -0.053868 -0.026423 0.012004 -0.0307655 -0.0216754 0.012004 -0.0444253 -0.0203436 0.012004 -0.0307655 -0.0216754 0.012004 -0.0347674 -0.0156111 0.012004 -0.0444253 -0.0203436 0.012004 -0.0501218 -0.0156111 0.012004 -0.053868 -0.026423 0.012004 -0.0444253 -0.0203436 0.012004 -0.028195 -0.025477 0.08476300000000001 -0.0287162 -0.0248871 0.012004 -0.0287039 -0.0248996 0.012004 -0.025847 -0.027856 0.08476300000000001 -0.028195 -0.025477 0.08476300000000001 -0.0287039 -0.0248996 0.012004 -0.028195 -0.025477 0.08476300000000001 -0.034635 -0.0156111 0.012004 -0.0307655 -0.0216754 0.012004 -0.028195 -0.025477 0.08476300000000001 -0.0307655 -0.0216754 0.012004 -0.0287162 -0.0248871 0.012004 -0.025847 -0.027856 0.08476300000000001 -0.016488 -0.034236 0.08476300000000001 -0.022779 -0.047301 0.10962 -0.016488 -0.034236 0.08476300000000001 -0.007825 -0.051913 0.10962 -0.022779 -0.047301 0.10962 0.007823999999999999 -0.051913 0.10962 0.022779 -0.0473 0.10962 0.017 -0.049671 0.15342 0.007823999999999999 -0.051913 0.10962 0.00658 -0.052086 0.15342 -0.007825 -0.051913 0.10962 0.0376145 -0.00530751 0.012004 0.059923 -0.003039 0.012004 0.0376145 -0.003039 0.012004 0.052353 0.003924 0.10962 0.037047 -0.008455000000000001 0.08476300000000001 0.037893 0.00284 0.08476300000000001 0.051183 -0.011682 0.10962 0.052353 0.003924 0.10962 0.052396 0.003297 0.20862 0.051183 -0.011682 0.10962 0.05157 -0.009837 0.20862 0.047503 -0.022353 0.20862 0.045466 -0.02625 0.10962 0.047503 -0.022353 0.20862 0.040452 -0.033465 0.20862 0.035709 -0.038485 0.10962 0.040452 -0.033465 0.20862 0.030859 -0.042473 0.20862 0.022779 -0.0473 0.10962 0.030859 -0.042473 0.20862 0.019327 -0.048813 0.20862 -0.050919 0.031738 3.9978e-06 -0.043487 0.041338 3.9978e-06 0.059923 -0.003039 3.9978e-06 -0.043487 0.041338 0.012004 -0.034276 0.049246 3.9978e-06 -0.043487 0.041338 3.9978e-06 0.0376145 -0.0007703709999999999 0.012004 0.059923 -0.003039 0.012004 0.0376145 0.00154547 0.012004 0.0376145 -0.003039 0.012004 0.059923 -0.003039 0.012004 0.0376145 -0.0007703709999999999 0.012004 0.04993 0.016224 0.10962 0.052353 0.003924 0.10962 0.037893 0.00284 0.08476300000000001 0.04993 0.016224 0.10962 0.044327 0.028131 0.10962 0.044327 0.028131 0.20862 -0.015475 0.050168 0.10962 -0.0109535 0.0363865 0.08476300000000001 -0.029575 0.043378 0.10962 -1e-06 0.0525 0.10962 -0.015475 0.050168 0.10962 -0.013057 0.050851 0.15342 -0.043487 0.041338 3.9978e-06 -0.050919 0.031738 0.012004 -0.043487 0.041338 0.012004 -0.0287781 0.0247912 0.012004 -0.050919 0.031738 0.012004 -0.0425215 0.0240202 0.012004 -0.050919 0.031738 0.012004 -0.056265 0.020838 0.012004 -0.0425215 0.0240202 0.012004 -0.056265 0.020838 0.012004 -0.0341945 0.0163024 0.012004 -0.0425215 0.0240202 0.012004 -0.0341945 0.0163024 0.012004 -0.0287781 0.0247912 0.012004 -0.0425215 0.0240202 0.012004 -0.0287162 0.0248881 0.012004 -0.0287781 0.0247912 0.012004 -0.028195 0.025477 0.08476300000000001 -0.0287781 0.0247912 0.012004 -0.0341945 0.0163024 0.012004 -0.028195 0.025477 0.08476300000000001 -0.0341945 0.0163024 0.012004 -0.034635 0.0156121 0.012004 -0.028195 0.025477 0.08476300000000001 -0.0286761 0.0249222 0.012004 -0.028195 0.025477 0.08476300000000001 -0.020545 0.031968 0.08476300000000001 -0.0286761 0.0249222 0.012004 -0.0287162 0.0248881 0.012004 -0.028195 0.025477 0.08476300000000001 -0.029575 0.043378 0.10962 -0.0109535 0.0363865 0.08476300000000001 -0.020545 0.031968 0.08476300000000001 -1e-06 0.0525 0.10962 -0.013057 0.050851 0.15342 0 0.0525 0.15342 0.015474 0.050168 0.10962 0 0.0525 0.15342 0.013056 0.050851 0.15342 0.029574 0.043378 0.10962 0.013056 0.050851 0.15342 0.017 0.049672 0.15342 0.025292 0.046006 0.20862 0.035938 0.038271 0.20862 0.029574 0.043378 0.10962 0.044327 0.028131 0.10962 0.035938 0.038271 0.20862 0.044327 0.028131 0.20862 -0.056265 0.020838 3.9978e-06 -0.050919 0.031738 3.9978e-06 0.059923 -0.003039 3.9978e-06 -0.059308 0.009086 3.9978e-06 -0.059308 0.009086 0.012004 -0.056265 0.020838 3.9978e-06 -0.059308 0.009086 3.9978e-06 -0.059923 -0.003039 0.012004 -0.059308 0.009086 0.012004 -0.0519985 -0.003039 0.012004 -0.059923 -0.003039 0.012004 -0.0551942 -0.009039 0.012004 -0.059923 -0.003039 0.012004 -0.058085 -0.015039 0.012004 -0.0551942 -0.009039 0.012004 -0.058085 -0.015039 0.012004 -0.0504654 -0.0142642 0.012004 -0.0551942 -0.009039 0.012004 -0.0504654 -0.0142642 0.012004 -0.051571 -0.009837 0.012004 -0.0551942 -0.009039 0.012004 -0.051571 -0.009837 0.012004 -0.0519985 -0.003039 0.012004 -0.0551942 -0.009039 0.012004 -0.0347674 -0.0156111 0.012004 -0.034635 -0.0156111 0.012004 -0.0378495 -0.0205439 0.0483835 -0.034635 -0.0156111 0.012004 -0.028195 -0.025477 0.08476300000000001 -0.0378495 -0.0205439 0.0483835 -0.028195 -0.025477 0.08476300000000001 -0.047504 -0.022353 0.061726 -0.0378495 -0.0205439 0.0483835 -0.047504 -0.022353 0.061726 -0.0347674 -0.0156111 0.012004 -0.0378495 -0.0205439 0.0483835 -0.0501218 -0.0156111 0.012004 -0.0347674 -0.0156111 0.012004 -0.047504 -0.022353 0.061726 -0.0501369 -0.0155722 0.012004 -0.0501218 -0.0156111 0.012004 -0.047504 -0.022353 0.061726 -0.0501369 -0.0155722 0.012004 -0.047504 -0.022353 0.061726 -0.047503 -0.022353 0.20862 -0.0501448 -0.0155478 0.012004 -0.0501369 -0.0155722 0.012004 -0.05157 -0.009838 0.20862 -0.0501369 -0.0155722 0.012004 -0.047503 -0.022353 0.20862 -0.05157 -0.009838 0.20862 -0.05157 -0.009838 0.20862 -0.051571 -0.009837 0.012004 -0.0504654 -0.0142642 0.012004 -0.05157 -0.009838 0.20862 -0.0504654 -0.0142642 0.012004 -0.0501448 -0.0155478 0.012004 -0.035709 -0.038485 0.10962 -0.028195 -0.025477 0.08476300000000001 -0.025847 -0.027856 0.08476300000000001 -0.025847 -0.027856 0.08476300000000001 -0.022779 -0.047301 0.10962 -0.030859 -0.042473 0.10962 -0.00658 -0.052086 0.15342 -0.022779 -0.047301 0.10962 -0.007825 -0.051913 0.10962 0.019327 -0.048813 0.20862 0.017 -0.049671 0.15342 0.022779 -0.0473 0.10962 0.017 -0.049671 0.15342 0.00658 -0.052086 0.15342 0.007823999999999999 -0.051913 0.10962 -0.007825 -0.051913 0.10962 0.00658 -0.052086 0.15342 -0.00658 -0.052086 0.15342 0.052353 0.003924 0.10962 0.04993 0.016224 0.20862 0.052396 0.003297 0.20862 0.052396 0.003297 0.20862 0.05157 -0.009837 0.20862 0.051183 -0.011682 0.10962 0.05157 -0.009837 0.20862 0.060353 -0.018068 0.22562 0.047503 -0.022353 0.20862 0.047503 -0.022353 0.20862 0.05456 -0.0315 0.22562 0.040452 -0.033465 0.20862 0.030859 -0.042473 0.20862 0.040452 -0.033465 0.20862 0.045825 -0.043233 0.22562 0.019327 -0.048813 0.20862 0.030859 -0.042473 0.20862 0.034619 -0.052636 0.22562 -0.050919 0.031738 0.012004 -0.043487 0.041338 3.9978e-06 -0.050919 0.031738 3.9978e-06 0.052353 0.003924 0.10962 0.04993 0.016224 0.10962 0.04993 0.016224 0.20862 0.044327 0.028131 0.20862 0.04993 0.016224 0.20862 0.04993 0.016224 0.10962 -0.025292 0.046006 0.20862 -0.015475 0.050168 0.10962 -0.029575 0.043378 0.10962 -0.017 0.049672 0.15342 -0.013057 0.050851 0.15342 -0.015475 0.050168 0.10962 -0.056265 0.020838 0.012004 -0.050919 0.031738 0.012004 -0.050919 0.031738 3.9978e-06 -0.034635 0.0156121 0.012004 -0.0341945 0.0163024 0.012004 -0.0500268 0.0156121 0.012004 -0.0514789 0.00828983 0.012004 -0.0501464 0.0155361 0.012004 -0.059308 0.009086 0.012004 -0.0501174 0.0156121 0.012004 -0.0500268 0.0156121 0.012004 -0.056265 0.020838 0.012004 -0.0501464 0.0155361 0.012004 -0.0501416 0.0155613 0.012004 -0.056265 0.020838 0.012004 -0.0501416 0.0155613 0.012004 -0.0501174 0.0156121 0.012004 -0.056265 0.020838 0.012004 -0.059308 0.009086 0.012004 -0.0501464 0.0155361 0.012004 -0.056265 0.020838 0.012004 -0.0500268 0.0156121 0.012004 -0.0341945 0.0163024 0.012004 -0.056265 0.020838 0.012004 -0.028195 0.025477 0.08476300000000001 -0.034635 0.0156121 0.012004 -0.0500268 0.0156121 0.012004 -0.035939 0.038271 0.10962 -0.020545 0.031968 0.08476300000000001 -0.028195 0.025477 0.08476300000000001 -0.020545 0.031968 0.08476300000000001 -0.035939 0.038271 0.10962 -0.029575 0.043378 0.10962 0.029574 0.043378 0.10962 0.017 0.049672 0.15342 0.025292 0.046006 0.20862 0.025292 0.046006 0.20862 0.043126 0.045925 0.22562 0.035938 0.038271 0.20862 0.053193 0.033757 0.22562 0.044327 0.028131 0.20862 0.035938 0.038271 0.20862 -0.056265 0.020838 0.012004 -0.050919 0.031738 3.9978e-06 -0.056265 0.020838 3.9978e-06 -0.056265 0.020838 3.9978e-06 -0.059308 0.009086 0.012004 -0.056265 0.020838 0.012004 -0.0514789 0.00828983 0.012004 -0.059308 0.009086 0.012004 -0.0557009 0.0030235 0.012004 -0.059308 0.009086 0.012004 -0.059923 -0.003039 0.012004 -0.0557009 0.0030235 0.012004 -0.059923 -0.003039 0.012004 -0.0519985 -0.003039 0.012004 -0.0557009 0.0030235 0.012004 -0.0519985 -0.003039 0.012004 -0.0523954 0.0032714 0.012004 -0.0557009 0.0030235 0.012004 -0.0557009 0.0030235 0.012004 -0.052397 0.003297 0.012004 -0.0523954 0.0032714 0.012004 -0.052397 0.003297 0.012004 -0.0514789 0.00828983 0.012004 -0.0557009 0.0030235 0.012004 -0.05157 -0.009838 0.20862 -0.0523954 0.0032714 0.012004 -0.0519985 -0.003039 0.012004 -0.05157 -0.009838 0.20862 -0.0519985 -0.003039 0.012004 -0.051571 -0.009837 0.012004 -0.047504 -0.022353 0.061726 -0.028195 -0.025477 0.08476300000000001 -0.0378495 -0.0256002 0.085673 -0.028195 -0.025477 0.08476300000000001 -0.043865 -0.028847 0.10962 -0.0378495 -0.0256002 0.085673 -0.043865 -0.028847 0.10962 -0.047504 -0.022353 0.061726 -0.0378495 -0.0256002 0.085673 -0.043865 -0.028847 0.10962 -0.047503 -0.022353 0.20862 -0.047504 -0.022353 0.061726 -0.047503 -0.022353 0.20862 -0.061884 -0.011805 0.22562 -0.05157 -0.009838 0.20862 -0.030859 -0.042473 0.10962 -0.035709 -0.038485 0.10962 -0.025847 -0.027856 0.08476300000000001 -0.028195 -0.025477 0.08476300000000001 -0.035709 -0.038485 0.10962 -0.040452 -0.033465 0.10962 -0.030859 -0.042473 0.20862 -0.030859 -0.042473 0.10962 -0.022779 -0.047301 0.10962 -0.00658 -0.052086 0.15342 -0.017 -0.049671 0.15342 -0.022779 -0.047301 0.10962 0.019327 -0.048813 0.20862 0.017 -0.049671 0.20192 0.017 -0.049671 0.15342 0.04993 0.016224 0.20862 0.062876 0.003956 0.22562 0.052396 0.003297 0.20862 0.062876 0.003956 0.22562 0.05157 -0.009837 0.20862 0.052396 0.003297 0.20862 0.061884 -0.011805 0.22562 0.060353 -0.018068 0.22562 0.05157 -0.009837 0.20862 0.05456 -0.0315 0.22562 0.047503 -0.022353 0.20862 0.060353 -0.018068 0.22562 0.040452 -0.033465 0.20862 0.05456 -0.0315 0.22562 0.045825 -0.043233 0.22562 0.045825 -0.043233 0.22562 0.034619 -0.052636 0.22562 0.030859 -0.042473 0.20862 0.021547 -0.059201 0.22562 0.019327 -0.048813 0.20862 0.034619 -0.052636 0.22562 0.059917 0.019468 0.22562 0.04993 0.016224 0.20862 0.044327 0.028131 0.20862 -0.017 0.049672 0.15342 -0.015475 0.050168 0.10962 -0.025292 0.046006 0.20862 -0.029575 0.043378 0.10962 -0.035939 0.038271 0.20862 -0.025292 0.046006 0.20862 -0.043865 0.028848 0.10962 -0.0501174 0.0156121 0.012004 -0.0465854 0.0232502 0.0683371 -0.0500268 0.0156121 0.012004 -0.0501174 0.0156121 0.012004 -0.0391562 0.0222298 0.060812 -0.0501174 0.0156121 0.012004 -0.043865 0.028848 0.10962 -0.0391562 0.0222298 0.060812 -0.043865 0.028848 0.10962 -0.028195 0.025477 0.08476300000000001 -0.0391562 0.0222298 0.060812 -0.028195 0.025477 0.08476300000000001 -0.0500268 0.0156121 0.012004 -0.0391562 0.0222298 0.060812 -0.052397 0.003296 0.20862 -0.0501464 0.0155361 0.012004 -0.0514789 0.00828983 0.012004 -0.052397 0.003296 0.20862 -0.0514789 0.00828983 0.012004 -0.052397 0.003297 0.012004 -0.049931 0.016223 0.20862 -0.0501416 0.0155613 0.012004 -0.0501464 0.0155361 0.012004 -0.052397 0.003296 0.20862 -0.049931 0.016223 0.20862 -0.0501464 0.0155361 0.012004 -0.0465854 0.0232502 0.0683371 -0.0501174 0.0156121 0.012004 -0.0501416 0.0155613 0.012004 -0.049931 0.016223 0.20862 -0.0465854 0.0232502 0.0683371 -0.0501416 0.0155613 0.012004 -0.028195 0.025477 0.08476300000000001 -0.041047 0.032733 0.10962 -0.035939 0.038271 0.10962 -0.035939 0.038271 0.20862 -0.029575 0.043378 0.10962 -0.035939 0.038271 0.10962 0.017 0.049672 0.20192 0.025292 0.046006 0.20862 0.017 0.049672 0.15342 0.043126 0.045925 0.22562 0.025292 0.046006 0.20862 0.03035 0.055207 0.22562 0.035938 0.038271 0.20862 0.043126 0.045925 0.22562 0.053193 0.033757 0.22562 0.059917 0.019468 0.22562 0.044327 0.028131 0.20862 0.053193 0.033757 0.22562 -0.052397 0.003296 0.20862 -0.052397 0.003297 0.012004 -0.0523954 0.0032714 0.012004 -0.05157 -0.009838 0.20862 -0.052397 0.003296 0.20862 -0.0523954 0.0032714 0.012004 -0.028195 -0.025477 0.08476300000000001 -0.040452 -0.033465 0.10962 -0.043865 -0.028847 0.10962 -0.043865 -0.028847 0.10962 -0.040452 -0.033465 0.10962 -0.047503 -0.022353 0.20862 -0.061884 -0.011805 0.22562 -0.047503 -0.022353 0.20862 -0.057004 -0.026824 0.22562 -0.062876 0.003956 0.22562 -0.05157 -0.009838 0.20862 -0.061884 -0.011805 0.22562 -0.030859 -0.042473 0.20862 -0.035709 -0.038485 0.10962 -0.030859 -0.042473 0.10962 -0.040452 -0.033465 0.10962 -0.035709 -0.038485 0.10962 -0.040452 -0.033465 0.20862 -0.022779 -0.047301 0.10962 -0.019326 -0.048813 0.20862 -0.030859 -0.042473 0.20862 -0.019326 -0.048813 0.20862 -0.022779 -0.047301 0.10962 -0.017 -0.049671 0.15342 0.019327 -0.048813 0.20862 0.00658 -0.052086 0.20192 0.017 -0.049671 0.20192 0.062876 0.003956 0.22562 0.04993 0.016224 0.20862 0.059917 0.019468 0.22562 0.062876 0.003956 0.22562 0.061884 -0.011805 0.22562 0.05157 -0.009837 0.20862 0.060353 -0.018068 0.22562 0.061884 -0.011805 0.22562 0.060353 -0.018068 0.22962 0.060353 -0.018068 0.22562 0.060353 -0.018068 0.22962 0.05456 -0.0315 0.22562 0.05456 -0.0315 0.22562 0.05456 -0.0315 0.22962 0.045825 -0.043233 0.22562 0.045825 -0.043233 0.22962 0.034619 -0.052636 0.22562 0.045825 -0.043233 0.22562 0.00658 -0.052086 0.20862 0.019327 -0.048813 0.20862 0.021547 -0.059201 0.22562 0.021547 -0.059201 0.22562 0.034619 -0.052636 0.22562 0.034619 -0.052636 0.22962 -0.017 0.049672 0.15342 -0.025292 0.046006 0.20862 -0.017 0.049671 0.20192 -0.025292 0.046006 0.20862 -0.035939 0.038271 0.20862 -0.040496 0.048261 0.22562 -0.044327 0.028131 0.20862 -0.043865 0.028848 0.10962 -0.0465854 0.0232502 0.0683371 -0.028195 0.025477 0.08476300000000001 -0.043865 0.028848 0.10962 -0.041047 0.032733 0.10962 -0.052397 0.003296 0.20862 -0.059917 0.019468 0.22562 -0.049931 0.016223 0.20862 -0.049931 0.016223 0.20862 -0.044327 0.028131 0.20862 -0.0465854 0.0232502 0.0683371 -0.035939 0.038271 0.10962 -0.041047 0.032733 0.10962 -0.035939 0.038271 0.20862 0.013056 0.050851 0.20862 0.025292 0.046006 0.20862 0.017 0.049672 0.20192 0.013056 0.050851 0.20862 0.03035 0.055207 0.22562 0.025292 0.046006 0.20862 0.040496 0.048261 0.22962 0.043126 0.045925 0.22562 0.03035 0.055207 0.22562 0.043126 0.045925 0.22562 0.050534 0.037621 0.22962 0.053193 0.033757 0.22562 0.053193 0.033757 0.22562 0.057848 0.024953 0.22962 0.059917 0.019468 0.22562 -0.052397 0.003296 0.20862 -0.05157 -0.009838 0.20862 -0.062876 0.003956 0.22562 -0.040452 -0.033465 0.10962 -0.040452 -0.033465 0.20862 -0.047503 -0.022353 0.20862 -0.040452 -0.033465 0.20862 -0.057004 -0.026824 0.22562 -0.047503 -0.022353 0.20862 -0.057004 -0.026824 0.22562 -0.060353 -0.018069 0.22962 -0.061884 -0.011805 0.22562 -0.062893 -0.003663 0.22962 -0.062876 0.003956 0.22562 -0.061884 -0.011805 0.22562 -0.035709 -0.038485 0.10962 -0.030859 -0.042473 0.20862 -0.040452 -0.033465 0.20862 -0.03703 -0.050968 0.22562 -0.030859 -0.042473 0.20862 -0.019326 -0.048813 0.20862 -0.019326 -0.048813 0.20862 -0.017 -0.049671 0.15342 -0.017 -0.049671 0.20192 0.00658 -0.052086 0.20862 0.00658 -0.052086 0.20192 0.019327 -0.048813 0.20862 0.059917 0.019468 0.22562 0.062043 0.01094 0.22962 0.062876 0.003956 0.22562 0.062876 0.003956 0.22562 0.062893 -0.003663 0.22962 0.061884 -0.011805 0.22562 0.061884 -0.011805 0.22562 0.062893 -0.003663 0.22962 0.060353 -0.018068 0.22962 0.060353 -0.018068 0.22962 0.05456 -0.0315 0.22962 0.05456 -0.0315 0.22562 0.045825 -0.043233 0.22562 0.05456 -0.0315 0.22962 0.045825 -0.043233 0.22962 0.034619 -0.052636 0.22562 0.045825 -0.043233 0.22962 0.034619 -0.052636 0.22962 0.00658 -0.052086 0.20862 0.021547 -0.059201 0.22562 0.007314 -0.062574 0.22562 0.021547 -0.059201 0.22562 0.034619 -0.052636 0.22962 0.021548 -0.059201 0.22962 -0.013056 0.050851 0.20192 -0.017 0.049671 0.20192 -0.025292 0.046006 0.20862 -0.050534 0.037621 0.22562 -0.040496 0.048261 0.22562 -0.035939 0.038271 0.20862 -0.040496 0.048261 0.22562 -0.028275 0.056299 0.22562 -0.025292 0.046006 0.20862 -0.044327 0.028131 0.20862 -0.035939 0.038271 0.20862 -0.043865 0.028848 0.10962 -0.035939 0.038271 0.20862 -0.041047 0.032733 0.10962 -0.043865 0.028848 0.10962 -0.059917 0.019468 0.22562 -0.052397 0.003296 0.20862 -0.062876 0.003956 0.22562 -0.057848 0.024953 0.22562 -0.049931 0.016223 0.20862 -0.059917 0.019468 0.22562 -0.049931 0.016223 0.20862 -0.057848 0.024953 0.22562 -0.044327 0.028131 0.20862 0.013056 0.050851 0.20862 0.017 0.049672 0.20192 0.013056 0.050851 0.20192 0.013056 0.050851 0.20862 0.015667 0.061021 0.22562 0.03035 0.055207 0.22562 0.028274 0.056299 0.22962 0.040496 0.048261 0.22962 0.03035 0.055207 0.22562 0.043126 0.045925 0.22562 0.040496 0.048261 0.22962 0.050534 0.037621 0.22962 0.050534 0.037621 0.22962 0.057848 0.024953 0.22962 0.053193 0.033757 0.22562 0.057848 0.024953 0.22962 0.062043 0.01094 0.22962 0.059917 0.019468 0.22562 -0.057004 -0.026824 0.22562 -0.040452 -0.033465 0.20862 -0.048542 -0.040158 0.22562 -0.057004 -0.026824 0.22562 -0.054559 -0.0315 0.22962 -0.060353 -0.018069 0.22962 -0.060353 -0.018069 0.22962 -0.062893 -0.003663 0.22962 -0.061884 -0.011805 0.22562 -0.063 1.2517e-09 0.22962 -0.062876 0.003956 0.22562 -0.062893 -0.003663 0.22962 -0.040452 -0.033465 0.20862 -0.030859 -0.042473 0.20862 -0.048542 -0.040158 0.22562 -0.03703 -0.050968 0.22562 -0.019326 -0.048813 0.20862 -0.023192 -0.058576 0.22562 -0.03703 -0.050968 0.22562 -0.048542 -0.040158 0.22562 -0.030859 -0.042473 0.20862 -0.019326 -0.048813 0.20862 -0.017 -0.049671 0.20192 -0.00658 -0.052086 0.20862 -0.00658 -0.052086 0.20192 0.00658 -0.052086 0.20192 0.00658 -0.052086 0.20862 0.062876 0.003956 0.22562 0.062043 0.01094 0.22962 0.062893 -0.003663 0.22962 0.062893 -0.003663 0.22962 0.062043 0.01094 0.22962 0.060353 -0.018068 0.22962 0.05456 -0.0315 0.22962 0.060353 -0.018068 0.22962 0.014529 0.061302 0.22962 0.045825 -0.043233 0.22962 0.05456 -0.0315 0.22962 0.014529 0.061302 0.22962 0.034619 -0.052636 0.22962 0.045825 -0.043233 0.22962 0.014529 0.061302 0.22962 -0.007314 -0.062574 0.22562 0.00658 -0.052086 0.20862 0.007314 -0.062574 0.22562 0.007314 -0.062574 0.22562 0.021547 -0.059201 0.22562 0.021548 -0.059201 0.22962 0.021548 -0.059201 0.22962 0.034619 -0.052636 0.22962 0 0.063 0.22962 -0.013056 0.050851 0.20862 -0.013056 0.050851 0.20192 -0.025292 0.046006 0.20862 -0.050534 0.037621 0.22562 -0.035939 0.038271 0.20862 -0.044327 0.028131 0.20862 -0.050534 0.037621 0.22962 -0.040496 0.048261 0.22562 -0.050534 0.037621 0.22562 -0.025292 0.046006 0.20862 -0.028275 0.056299 0.22562 -0.013056 0.050851 0.20862 -0.040496 0.048261 0.22962 -0.028275 0.056299 0.22562 -0.040496 0.048261 0.22562 -0.062876 0.003956 0.22562 -0.062043 0.01094 0.22962 -0.059917 0.019468 0.22562 -0.057848 0.024953 0.22562 -0.059917 0.019468 0.22562 -0.057848 0.024953 0.22962 -0.050534 0.037621 0.22562 -0.044327 0.028131 0.20862 -0.057848 0.024953 0.22562 0.013056 0.050851 0.20862 0.013056 0.050851 0.20192 0 0.0525 0.20862 0 0.0525 0.20862 0.015667 0.061021 0.22562 0.013056 0.050851 0.20862 0.028274 0.056299 0.22962 0.03035 0.055207 0.22562 0.015667 0.061021 0.22562 0.060353 -0.018068 0.22962 0.040496 0.048261 0.22962 0.028274 0.056299 0.22962 0.050534 0.037621 0.22962 0.040496 0.048261 0.22962 0.060353 -0.018068 0.22962 0.057848 0.024953 0.22962 0.050534 0.037621 0.22962 0.060353 -0.018068 0.22962 0.062043 0.01094 0.22962 0.057848 0.024953 0.22962 0.060353 -0.018068 0.22962 -0.048542 -0.040158 0.22562 -0.054559 -0.0315 0.22962 -0.057004 -0.026824 0.22562 -0.060353 -0.018069 0.22962 -0.054559 -0.0315 0.22962 -0.062893 -0.003663 0.22962 -0.062893 -0.003663 0.22962 0 0.063 0.22962 -0.063 1.2517e-09 0.22962 -0.062876 0.003956 0.22562 -0.063 1.2517e-09 0.22962 -0.062043 0.01094 0.22962 -0.019326 -0.048813 0.20862 -0.00658 -0.052086 0.20862 -0.023192 -0.058576 0.22562 -0.03703 -0.050968 0.22562 -0.023192 -0.058576 0.22562 -0.034619 -0.052636 0.22962 -0.045824 -0.043233 0.22962 -0.048542 -0.040158 0.22562 -0.03703 -0.050968 0.22562 -0.00658 -0.052086 0.20862 -0.017 -0.049671 0.20192 -0.00658 -0.052086 0.20192 -0.00658 -0.052086 0.20862 -0.00658 -0.052086 0.20192 0.00658 -0.052086 0.20862 0.060353 -0.018068 0.22962 0.028274 0.056299 0.22962 0.014529 0.061302 0.22962 0.034619 -0.052636 0.22962 0.014529 0.061302 0.22962 0 0.063 0.22962 -0.00658 -0.052086 0.20862 0.00658 -0.052086 0.20862 -0.007314 -0.062574 0.22562 -0.007314 -0.062574 0.22562 0.007314 -0.062574 0.22562 0.007314 -0.062574 0.22962 0.007314 -0.062574 0.22962 0.007314 -0.062574 0.22562 0.021548 -0.059201 0.22962 0.021548 -0.059201 0.22962 0 0.063 0.22962 -0.0206725 0.0018995 0.22962 0 0.063 0.22962 -0.062893 -0.003663 0.22962 -0.0206725 0.0018995 0.22962 -0.062893 -0.003663 0.22962 0.021548 -0.059201 0.22962 -0.0206725 0.0018995 0.22962 -0.013056 0.050851 0.20862 0 0.0525 0.20192 -0.013056 0.050851 0.20192 -0.050534 0.037621 0.22562 -0.057848 0.024953 0.22962 -0.050534 0.037621 0.22962 -0.040496 0.048261 0.22562 -0.050534 0.037621 0.22962 -0.040496 0.048261 0.22962 -0.014529 0.061302 0.22562 -0.013056 0.050851 0.20862 -0.028275 0.056299 0.22562 -0.028275 0.056299 0.22562 -0.040496 0.048261 0.22962 -0.028274 0.056299 0.22962 -0.059917 0.019468 0.22562 -0.062043 0.01094 0.22962 -0.057848 0.024953 0.22962 -0.057848 0.024953 0.22962 -0.050534 0.037621 0.22562 -0.057848 0.024953 0.22562 0 0.0525 0.20862 0.013056 0.050851 0.20192 0 0.0525 0.20192 0 0.063 0.22562 0.015667 0.061021 0.22562 0 0.0525 0.20862 0.028274 0.056299 0.22962 0.015667 0.061021 0.22562 0.014529 0.061302 0.22962 -0.045824 -0.043233 0.22962 -0.054559 -0.0315 0.22962 -0.048542 -0.040158 0.22562 -0.054559 -0.0315 0.22962 -0.045824 -0.043233 0.22962 -0.062893 -0.003663 0.22962 -0.063 1.2517e-09 0.22962 0 0.063 0.22962 -0.062043 0.01094 0.22962 -0.00658 -0.052086 0.20862 -0.007314 -0.062574 0.22562 -0.023192 -0.058576 0.22562 -0.034619 -0.052636 0.22962 -0.023192 -0.058576 0.22562 -0.021547 -0.059201 0.22962 -0.034619 -0.052636 0.22962 -0.045824 -0.043233 0.22962 -0.03703 -0.050968 0.22562 0.015667 0.061021 0.22562 0 0.063 0.22962 0.014529 0.061302 0.22962 -0.007314 -0.062574 0.22962 -0.007314 -0.062574 0.22562 0.007314 -0.062574 0.22962 0.007314 -0.062574 0.22962 0.021548 -0.059201 0.22962 -0.021547 -0.059201 0.22962 -0.021547 -0.059201 0.22962 0.021548 -0.059201 0.22962 -0.062893 -0.003663 0.22962 0 0.0525 0.20862 0 0.0525 0.20192 -0.013056 0.050851 0.20862 -0.050534 0.037621 0.22962 -0.057848 0.024953 0.22962 -0.028274 0.056299 0.22962 -0.040496 0.048261 0.22962 -0.050534 0.037621 0.22962 -0.028274 0.056299 0.22962 -0.013056 0.050851 0.20862 -0.014529 0.061302 0.22562 0 0.0525 0.20862 -0.028274 0.056299 0.22962 -0.014529 0.061302 0.22562 -0.028275 0.056299 0.22562 -0.057848 0.024953 0.22962 -0.062043 0.01094 0.22962 -0.028274 0.056299 0.22962 0 0.063 0.22562 0 0.0525 0.20862 -0.014529 0.061302 0.22562 0.015667 0.061021 0.22562 0 0.063 0.22562 0 0.063 0.22962 -0.045824 -0.043233 0.22962 -0.034619 -0.052636 0.22962 -0.062893 -0.003663 0.22962 -0.062043 0.01094 0.22962 0 0.063 0.22962 -0.014529 0.061302 0.22962 -0.021547 -0.059201 0.22962 -0.023192 -0.058576 0.22562 -0.007314 -0.062574 0.22562 -0.034619 -0.052636 0.22962 -0.021547 -0.059201 0.22962 -0.062893 -0.003663 0.22962 -0.007314 -0.062574 0.22962 0.007314 -0.062574 0.22962 -0.021547 -0.059201 0.22962 -0.007314 -0.062574 0.22962 -0.021547 -0.059201 0.22962 -0.007314 -0.062574 0.22562 -0.014529 0.061302 0.22962 -0.014529 0.061302 0.22562 -0.028274 0.056299 0.22962 -0.062043 0.01094 0.22962 -0.014529 0.061302 0.22962 -0.028274 0.056299 0.22962 -0.014529 0.061302 0.22962 0 0.063 0.22562 -0.014529 0.061302 0.22562 0 0.063 0.22962 0 0.063 0.22562 -0.014529 0.061302 0.22962 0 0.0525 0.15342 -0.013057 0.050851 0.15342 0.017 0.0605 0.15342 0.013056 0.050851 0.15342 0 0.0525 0.15342 0.017 0.0605 0.15342 0.017 0.049672 0.15342 0.013056 0.050851 0.15342 0.017 0.0605 0.15342 0.017 -0.0605 0.15342 0.00658 -0.052086 0.15342 0.017 -0.049671 0.15342 -0.00658 -0.052086 0.15342 0.00658 -0.052086 0.15342 0.017 -0.0605 0.15342 -0.013057 0.050851 0.15342 -0.017 0.049672 0.15342 0.017 0.0605 0.15342 0.017 0.0605 0.15342 0.017 0.0605 0.20192 0.017 0.049672 0.15342 -0.017 -0.049671 0.15342 -0.00658 -0.052086 0.15342 0.017 -0.0605 0.15342 0.017 -0.049671 0.15342 0.017 -0.049671 0.20192 0.017 -0.0605 0.15342 -0.017 0.049672 0.15342 -0.017 0.0605 0.15342 0.017 0.0605 0.15342 0.017 0.0605 0.20192 0.017 0.049672 0.20192 0.017 0.049672 0.15342 -0.017 0.0605 0.20192 0.017 0.0605 0.20192 0.017 0.0605 0.15342 -0.017 -0.0605 0.15342 -0.017 -0.049671 0.15342 0.017 -0.0605 0.15342 0.017 -0.049671 0.20192 0.017 -0.0605 0.20192 0.017 -0.0605 0.15342 0.017 -0.0605 0.20192 0.017 -0.049671 0.20192 0.00658 -0.052086 0.20192 -0.017 0.0605 0.15342 -0.017 0.049672 0.15342 -0.017 0.049671 0.20192 -0.017 0.0605 0.15342 -0.017 0.0605 0.20192 0.017 0.0605 0.15342 0.013056 0.050851 0.20192 0.017 0.049672 0.20192 0.017 0.0605 0.20192 -0.013056 0.050851 0.20192 0.017 0.0605 0.20192 -0.017 0.0605 0.20192 -0.017 -0.0605 0.15342 0.017 -0.0605 0.15342 0.017 -0.0605 0.20192 -0.017 -0.049671 0.15342 -0.017 -0.0605 0.15342 -0.017 -0.0605 0.20192 -0.017 -0.049671 0.20192 -0.017 -0.049671 0.15342 -0.017 -0.0605 0.20192 0.017 -0.0605 0.20192 0.00658 -0.052086 0.20192 -0.00658 -0.052086 0.20192 -0.017 0.049671 0.20192 -0.013056 0.050851 0.20192 -0.017 0.0605 0.20192 -0.017 0.0605 0.20192 -0.017 0.0605 0.15342 -0.017 0.049671 0.20192 0.013056 0.050851 0.20192 0.017 0.0605 0.20192 0 0.0525 0.20192 -0.013056 0.050851 0.20192 0 0.0525 0.20192 0.017 0.0605 0.20192 -0.017 -0.0605 0.20192 -0.017 -0.0605 0.15342 0.017 -0.0605 0.20192 -0.017 -0.0605 0.20192 0.017 -0.0605 0.20192 -0.017 -0.049671 0.20192 -0.00658 -0.052086 0.20192 -0.017 -0.049671 0.20192 0.017 -0.0605 0.20192 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853

    -
    -
    - - - 0 0 0 - 1 0 0 0 - - true - - - -
    - - - - -0.0049 0.0065 0.3441 -0.00269581 0.00613292 0.344816 -0.00258237 0.00613292 0.3441 -0.0049 0.0065 0.3441 -0.003025 0.00613292 0.345462 -0.00269581 0.00613292 0.344816 -0.0049 0.0065 0.3441 -0.00353773 0.00613292 0.345975 -0.003025 0.00613292 0.345462 -0.0049 0.0065 0.3441 -0.00418381 0.00613292 0.346304 -0.00353773 0.00613292 0.345975 -0.0049 0.0065 0.3441 -0.0049 0.00613292 0.346418 -0.00418381 0.00613292 0.346304 -0.0049 0.0065 0.3441 -0.00561619 0.00613292 0.346304 -0.0049 0.00613292 0.346418 -0.0049 0.0065 0.3441 -0.00626227 0.00613292 0.345975 -0.00561619 0.00613292 0.346304 -0.0049 0.0065 0.3441 -0.006775 0.00613292 0.345462 -0.00626227 0.00613292 0.345975 -0.0049 0.0065 0.3441 -0.00710419 0.00613292 0.344816 -0.006775 0.00613292 0.345462 -0.0049 0.0065 0.3441 -0.00721763 0.00613292 0.3441 -0.00710419 0.00613292 0.344816 -0.0049 0.0065 0.3441 -0.00710419 0.00613292 0.343384 -0.00721763 0.00613292 0.3441 -0.0049 0.0065 0.3441 -0.006775 0.00613292 0.342738 -0.00710419 0.00613292 0.343384 -0.0049 0.0065 0.3441 -0.00626227 0.00613292 0.342225 -0.006775 0.00613292 0.342738 -0.0049 0.0065 0.3441 -0.00561619 0.00613292 0.341896 -0.00626227 0.00613292 0.342225 -0.0049 0.0065 0.3441 -0.0049 0.00613292 0.341782 -0.00561619 0.00613292 0.341896 -0.0049 0.0065 0.3441 -0.00418381 0.00613292 0.341896 -0.0049 0.00613292 0.341782 -0.0049 0.0065 0.3441 -0.00353773 0.00613292 0.342225 -0.00418381 0.00613292 0.341896 -0.0049 0.0065 0.3441 -0.003025 0.00613292 0.342738 -0.00353773 0.00613292 0.342225 -0.0049 0.0065 0.3441 -0.00269581 0.00613292 0.343384 -0.003025 0.00613292 0.342738 -0.0049 0.0065 0.3441 -0.00258237 0.00613292 0.3441 -0.00269581 0.00613292 0.343384 -0.00258237 0.00613292 0.3441 -0.0007073719999999999 0.00506763 0.345462 -0.000491611 0.00506763 0.3441 -0.00258237 0.00613292 0.3441 -0.00269581 0.00613292 0.344816 -0.0007073719999999999 0.00506763 0.345462 -0.00269581 0.00613292 0.344816 -0.00133354 0.00506763 0.346691 -0.0007073719999999999 0.00506763 0.345462 -0.00269581 0.00613292 0.344816 -0.003025 0.00613292 0.345462 -0.00133354 0.00506763 0.346691 -0.003025 0.00613292 0.345462 -0.00230881 0.00506763 0.347666 -0.00133354 0.00506763 0.346691 -0.003025 0.00613292 0.345462 -0.00353773 0.00613292 0.345975 -0.00230881 0.00506763 0.347666 -0.00353773 0.00613292 0.345975 -0.00353773 0.00506763 0.348293 -0.00230881 0.00506763 0.347666 -0.00353773 0.00613292 0.345975 -0.00418381 0.00613292 0.346304 -0.00353773 0.00506763 0.348293 -0.00418381 0.00613292 0.346304 -0.0049 0.00506763 0.348508 -0.00353773 0.00506763 0.348293 -0.00418381 0.00613292 0.346304 -0.0049 0.00613292 0.346418 -0.0049 0.00506763 0.348508 -0.0049 0.00613292 0.346418 -0.00626227 0.00506763 0.348293 -0.0049 0.00506763 0.348508 -0.0049 0.00613292 0.346418 -0.00561619 0.00613292 0.346304 -0.00626227 0.00506763 0.348293 -0.00561619 0.00613292 0.346304 -0.00749119 0.00506763 0.347666 -0.00626227 0.00506763 0.348293 -0.00561619 0.00613292 0.346304 -0.00626227 0.00613292 0.345975 -0.00749119 0.00506763 0.347666 -0.00626227 0.00613292 0.345975 -0.00846646 0.00506763 0.346691 -0.00749119 0.00506763 0.347666 -0.00626227 0.00613292 0.345975 -0.006775 0.00613292 0.345462 -0.00846646 0.00506763 0.346691 -0.006775 0.00613292 0.345462 -0.009092630000000001 0.00506763 0.345462 -0.00846646 0.00506763 0.346691 -0.006775 0.00613292 0.345462 -0.00710419 0.00613292 0.344816 -0.009092630000000001 0.00506763 0.345462 -0.00710419 0.00613292 0.344816 -0.00930839 0.00506763 0.3441 -0.009092630000000001 0.00506763 0.345462 -0.00710419 0.00613292 0.344816 -0.00721763 0.00613292 0.3441 -0.00930839 0.00506763 0.3441 -0.00721763 0.00613292 0.3441 -0.009092630000000001 0.00506763 0.342738 -0.00930839 0.00506763 0.3441 -0.00721763 0.00613292 0.3441 -0.00710419 0.00613292 0.343384 -0.009092630000000001 0.00506763 0.342738 -0.00710419 0.00613292 0.343384 -0.00846646 0.00506763 0.341509 -0.009092630000000001 0.00506763 0.342738 -0.00710419 0.00613292 0.343384 -0.006775 0.00613292 0.342738 -0.00846646 0.00506763 0.341509 -0.006775 0.00613292 0.342738 -0.00749119 0.00506763 0.340534 -0.00846646 0.00506763 0.341509 -0.006775 0.00613292 0.342738 -0.00626227 0.00613292 0.342225 -0.00749119 0.00506763 0.340534 -0.00626227 0.00613292 0.342225 -0.00626227 0.00506763 0.339907 -0.00749119 0.00506763 0.340534 -0.00626227 0.00613292 0.342225 -0.00561619 0.00613292 0.341896 -0.00626227 0.00506763 0.339907 -0.00561619 0.00613292 0.341896 -0.0049 0.00506763 0.339692 -0.00626227 0.00506763 0.339907 -0.00561619 0.00613292 0.341896 -0.0049 0.00613292 0.341782 -0.0049 0.00506763 0.339692 -0.0049 0.00613292 0.341782 -0.00353773 0.00506763 0.339907 -0.0049 0.00506763 0.339692 -0.0049 0.00613292 0.341782 -0.00418381 0.00613292 0.341896 -0.00353773 0.00506763 0.339907 -0.00418381 0.00613292 0.341896 -0.00230881 0.00506763 0.340534 -0.00353773 0.00506763 0.339907 -0.00418381 0.00613292 0.341896 -0.00353773 0.00613292 0.342225 -0.00230881 0.00506763 0.340534 -0.00353773 0.00613292 0.342225 -0.00133354 0.00506763 0.341509 -0.00230881 0.00506763 0.340534 -0.00353773 0.00613292 0.342225 -0.003025 0.00613292 0.342738 -0.00133354 0.00506763 0.341509 -0.003025 0.00613292 0.342738 -0.0007073719999999999 0.00506763 0.342738 -0.00133354 0.00506763 0.341509 -0.003025 0.00613292 0.342738 -0.00269581 0.00613292 0.343384 -0.0007073719999999999 0.00506763 0.342738 -0.00269581 0.00613292 0.343384 -0.000491611 0.00506763 0.3441 -0.0007073719999999999 0.00506763 0.342738 -0.00269581 0.00613292 0.343384 -0.00258237 0.00613292 0.3441 -0.000491611 0.00506763 0.3441 -0.000491611 0.00506763 0.3441 0.000870657 0.00340839 0.345975 0.00116763 0.00340839 0.3441 -0.000491611 0.00506763 0.3441 -0.0007073719999999999 0.00506763 0.345462 0.000870657 0.00340839 0.345975 -0.0007073719999999999 0.00506763 0.345462 8.81363e-06 0.00340839 0.347666 0.000870657 0.00340839 0.345975 -0.0007073719999999999 0.00506763 0.345462 -0.00133354 0.00506763 0.346691 8.81363e-06 0.00340839 0.347666 -0.00133354 0.00506763 0.346691 -0.00133354 0.00340839 0.349009 8.81363e-06 0.00340839 0.347666 -0.00133354 0.00506763 0.346691 -0.00230881 0.00506763 0.347666 -0.00133354 0.00340839 0.349009 -0.00230881 0.00506763 0.347666 -0.003025 0.00340839 0.349871 -0.00133354 0.00340839 0.349009 -0.00230881 0.00506763 0.347666 -0.00353773 0.00506763 0.348293 -0.003025 0.00340839 0.349871 -0.00353773 0.00506763 0.348293 -0.0049 0.00340839 0.350168 -0.003025 0.00340839 0.349871 -0.00353773 0.00506763 0.348293 -0.0049 0.00506763 0.348508 -0.0049 0.00340839 0.350168 -0.0049 0.00506763 0.348508 -0.006775 0.00340839 0.349871 -0.0049 0.00340839 0.350168 -0.0049 0.00506763 0.348508 -0.00626227 0.00506763 0.348293 -0.006775 0.00340839 0.349871 -0.00626227 0.00506763 0.348293 -0.00846646 0.00340839 0.349009 -0.006775 0.00340839 0.349871 -0.00626227 0.00506763 0.348293 -0.00749119 0.00506763 0.347666 -0.00846646 0.00340839 0.349009 -0.00749119 0.00506763 0.347666 -0.009808809999999999 0.00340839 0.347666 -0.00846646 0.00340839 0.349009 -0.00749119 0.00506763 0.347666 -0.00846646 0.00506763 0.346691 -0.009808809999999999 0.00340839 0.347666 -0.00846646 0.00506763 0.346691 -0.0106707 0.00340839 0.345975 -0.009808809999999999 0.00340839 0.347666 -0.00846646 0.00506763 0.346691 -0.009092630000000001 0.00506763 0.345462 -0.0106707 0.00340839 0.345975 -0.009092630000000001 0.00506763 0.345462 -0.0109676 0.00340839 0.3441 -0.0106707 0.00340839 0.345975 -0.009092630000000001 0.00506763 0.345462 -0.00930839 0.00506763 0.3441 -0.0109676 0.00340839 0.3441 -0.00930839 0.00506763 0.3441 -0.0106707 0.00340839 0.342225 -0.0109676 0.00340839 0.3441 -0.00930839 0.00506763 0.3441 -0.009092630000000001 0.00506763 0.342738 -0.0106707 0.00340839 0.342225 -0.009092630000000001 0.00506763 0.342738 -0.009808809999999999 0.00340839 0.340534 -0.0106707 0.00340839 0.342225 -0.009092630000000001 0.00506763 0.342738 -0.00846646 0.00506763 0.341509 -0.009808809999999999 0.00340839 0.340534 -0.00846646 0.00506763 0.341509 -0.00846646 0.00340839 0.339191 -0.009808809999999999 0.00340839 0.340534 -0.00846646 0.00506763 0.341509 -0.00749119 0.00506763 0.340534 -0.00846646 0.00340839 0.339191 -0.00749119 0.00506763 0.340534 -0.006775 0.00340839 0.338329 -0.00846646 0.00340839 0.339191 -0.00749119 0.00506763 0.340534 -0.00626227 0.00506763 0.339907 -0.006775 0.00340839 0.338329 -0.00626227 0.00506763 0.339907 -0.0049 0.00340839 0.338032 -0.006775 0.00340839 0.338329 -0.00626227 0.00506763 0.339907 -0.0049 0.00506763 0.339692 -0.0049 0.00340839 0.338032 -0.0049 0.00506763 0.339692 -0.003025 0.00340839 0.338329 -0.0049 0.00340839 0.338032 -0.0049 0.00506763 0.339692 -0.00353773 0.00506763 0.339907 -0.003025 0.00340839 0.338329 -0.00353773 0.00506763 0.339907 -0.00133354 0.00340839 0.339191 -0.003025 0.00340839 0.338329 -0.00353773 0.00506763 0.339907 -0.00230881 0.00506763 0.340534 -0.00133354 0.00340839 0.339191 -0.00230881 0.00506763 0.340534 8.81363e-06 0.00340839 0.340534 -0.00133354 0.00340839 0.339191 -0.00230881 0.00506763 0.340534 -0.00133354 0.00506763 0.341509 8.81363e-06 0.00340839 0.340534 -0.00133354 0.00506763 0.341509 0.000870657 0.00340839 0.342225 8.81363e-06 0.00340839 0.340534 -0.00133354 0.00506763 0.341509 -0.0007073719999999999 0.00506763 0.342738 0.000870657 0.00340839 0.342225 -0.0007073719999999999 0.00506763 0.342738 0.00116763 0.00340839 0.3441 0.000870657 0.00340839 0.342225 -0.0007073719999999999 0.00506763 0.342738 -0.000491611 0.00506763 0.3441 0.00116763 0.00340839 0.3441 0.00116763 0.00340839 0.3441 0.00188381 0.00131763 0.346304 0.00223292 0.00131763 0.3441 0.00116763 0.00340839 0.3441 0.000870657 0.00340839 0.345975 0.00188381 0.00131763 0.346304 0.000870657 0.00340839 0.345975 0.000870657 0.00131763 0.348293 0.00188381 0.00131763 0.346304 0.000870657 0.00340839 0.345975 8.81363e-06 0.00340839 0.347666 0.000870657 0.00131763 0.348293 8.81363e-06 0.00340839 0.347666 -0.0007073719999999999 0.00131763 0.349871 0.000870657 0.00131763 0.348293 8.81363e-06 0.00340839 0.347666 -0.00133354 0.00340839 0.349009 -0.0007073719999999999 0.00131763 0.349871 -0.00133354 0.00340839 0.349009 -0.00269581 0.00131763 0.350884 -0.0007073719999999999 0.00131763 0.349871 -0.00133354 0.00340839 0.349009 -0.003025 0.00340839 0.349871 -0.00269581 0.00131763 0.350884 -0.003025 0.00340839 0.349871 -0.0049 0.00131763 0.351233 -0.00269581 0.00131763 0.350884 -0.003025 0.00340839 0.349871 -0.0049 0.00340839 0.350168 -0.0049 0.00131763 0.351233 -0.0049 0.00340839 0.350168 -0.00710419 0.00131763 0.350884 -0.0049 0.00131763 0.351233 -0.0049 0.00340839 0.350168 -0.006775 0.00340839 0.349871 -0.00710419 0.00131763 0.350884 -0.006775 0.00340839 0.349871 -0.009092630000000001 0.00131763 0.349871 -0.00710419 0.00131763 0.350884 -0.006775 0.00340839 0.349871 -0.00846646 0.00340839 0.349009 -0.009092630000000001 0.00131763 0.349871 -0.00846646 0.00340839 0.349009 -0.0106707 0.00131763 0.348293 -0.009092630000000001 0.00131763 0.349871 -0.00846646 0.00340839 0.349009 -0.009808809999999999 0.00340839 0.347666 -0.0106707 0.00131763 0.348293 -0.009808809999999999 0.00340839 0.347666 -0.0116838 0.00131763 0.346304 -0.0106707 0.00131763 0.348293 -0.009808809999999999 0.00340839 0.347666 -0.0106707 0.00340839 0.345975 -0.0116838 0.00131763 0.346304 -0.0106707 0.00340839 0.345975 -0.0120329 0.00131763 0.3441 -0.0116838 0.00131763 0.346304 -0.0106707 0.00340839 0.345975 -0.0109676 0.00340839 0.3441 -0.0120329 0.00131763 0.3441 -0.0109676 0.00340839 0.3441 -0.0116838 0.00131763 0.341896 -0.0120329 0.00131763 0.3441 -0.0109676 0.00340839 0.3441 -0.0106707 0.00340839 0.342225 -0.0116838 0.00131763 0.341896 -0.0106707 0.00340839 0.342225 -0.0106707 0.00131763 0.339907 -0.0116838 0.00131763 0.341896 -0.0106707 0.00340839 0.342225 -0.009808809999999999 0.00340839 0.340534 -0.0106707 0.00131763 0.339907 -0.009808809999999999 0.00340839 0.340534 -0.009092630000000001 0.00131763 0.338329 -0.0106707 0.00131763 0.339907 -0.009808809999999999 0.00340839 0.340534 -0.00846646 0.00340839 0.339191 -0.009092630000000001 0.00131763 0.338329 -0.00846646 0.00340839 0.339191 -0.00710419 0.00131763 0.337316 -0.009092630000000001 0.00131763 0.338329 -0.00846646 0.00340839 0.339191 -0.006775 0.00340839 0.338329 -0.00710419 0.00131763 0.337316 -0.006775 0.00340839 0.338329 -0.0049 0.00131763 0.336967 -0.00710419 0.00131763 0.337316 -0.006775 0.00340839 0.338329 -0.0049 0.00340839 0.338032 -0.0049 0.00131763 0.336967 -0.0049 0.00340839 0.338032 -0.00269581 0.00131763 0.337316 -0.0049 0.00131763 0.336967 -0.0049 0.00340839 0.338032 -0.003025 0.00340839 0.338329 -0.00269581 0.00131763 0.337316 -0.003025 0.00340839 0.338329 -0.0007073719999999999 0.00131763 0.338329 -0.00269581 0.00131763 0.337316 -0.003025 0.00340839 0.338329 -0.00133354 0.00340839 0.339191 -0.0007073719999999999 0.00131763 0.338329 -0.00133354 0.00340839 0.339191 0.000870657 0.00131763 0.339907 -0.0007073719999999999 0.00131763 0.338329 -0.00133354 0.00340839 0.339191 8.81363e-06 0.00340839 0.340534 0.000870657 0.00131763 0.339907 8.81363e-06 0.00340839 0.340534 0.00188381 0.00131763 0.341896 0.000870657 0.00131763 0.339907 8.81363e-06 0.00340839 0.340534 0.000870657 0.00340839 0.342225 0.00188381 0.00131763 0.341896 0.000870657 0.00340839 0.342225 0.00223292 0.00131763 0.3441 0.00188381 0.00131763 0.341896 0.000870657 0.00340839 0.342225 0.00116763 0.00340839 0.3441 0.00223292 0.00131763 0.3441 0.00223292 0.00131763 0.3441 0.00223292 -0.001 0.346418 0.0026 -0.001 0.3441 0.00223292 0.00131763 0.3441 0.00188381 0.00131763 0.346304 0.00223292 -0.001 0.346418 0.00188381 0.00131763 0.346304 0.00116763 -0.001 0.348508 0.00223292 -0.001 0.346418 0.00188381 0.00131763 0.346304 0.000870657 0.00131763 0.348293 0.00116763 -0.001 0.348508 0.000870657 0.00131763 0.348293 -0.000491611 -0.001 0.350168 0.00116763 -0.001 0.348508 0.000870657 0.00131763 0.348293 -0.0007073719999999999 0.00131763 0.349871 -0.000491611 -0.001 0.350168 -0.0007073719999999999 0.00131763 0.349871 -0.00258237 -0.001 0.351233 -0.000491611 -0.001 0.350168 -0.0007073719999999999 0.00131763 0.349871 -0.00269581 0.00131763 0.350884 -0.00258237 -0.001 0.351233 -0.00269581 0.00131763 0.350884 -0.0049 -0.001 0.3516 -0.00258237 -0.001 0.351233 -0.00269581 0.00131763 0.350884 -0.0049 0.00131763 0.351233 -0.0049 -0.001 0.3516 -0.0049 0.00131763 0.351233 -0.00721763 -0.001 0.351233 -0.0049 -0.001 0.3516 -0.0049 0.00131763 0.351233 -0.00710419 0.00131763 0.350884 -0.00721763 -0.001 0.351233 -0.00710419 0.00131763 0.350884 -0.00930839 -0.001 0.350168 -0.00721763 -0.001 0.351233 -0.00710419 0.00131763 0.350884 -0.009092630000000001 0.00131763 0.349871 -0.00930839 -0.001 0.350168 -0.009092630000000001 0.00131763 0.349871 -0.0109676 -0.001 0.348508 -0.00930839 -0.001 0.350168 -0.009092630000000001 0.00131763 0.349871 -0.0106707 0.00131763 0.348293 -0.0109676 -0.001 0.348508 -0.0106707 0.00131763 0.348293 -0.0120329 -0.001 0.346418 -0.0109676 -0.001 0.348508 -0.0106707 0.00131763 0.348293 -0.0116838 0.00131763 0.346304 -0.0120329 -0.001 0.346418 -0.0116838 0.00131763 0.346304 -0.0124 -0.001 0.3441 -0.0120329 -0.001 0.346418 -0.0116838 0.00131763 0.346304 -0.0120329 0.00131763 0.3441 -0.0124 -0.001 0.3441 -0.0120329 0.00131763 0.3441 -0.0120329 -0.001 0.341782 -0.0124 -0.001 0.3441 -0.0120329 0.00131763 0.3441 -0.0116838 0.00131763 0.341896 -0.0120329 -0.001 0.341782 -0.0116838 0.00131763 0.341896 -0.0109676 -0.001 0.339692 -0.0120329 -0.001 0.341782 -0.0116838 0.00131763 0.341896 -0.0106707 0.00131763 0.339907 -0.0109676 -0.001 0.339692 -0.0106707 0.00131763 0.339907 -0.00930839 -0.001 0.338032 -0.0109676 -0.001 0.339692 -0.0106707 0.00131763 0.339907 -0.009092630000000001 0.00131763 0.338329 -0.00930839 -0.001 0.338032 -0.009092630000000001 0.00131763 0.338329 -0.00721763 -0.001 0.336967 -0.00930839 -0.001 0.338032 -0.009092630000000001 0.00131763 0.338329 -0.00710419 0.00131763 0.337316 -0.00721763 -0.001 0.336967 -0.00710419 0.00131763 0.337316 -0.0049 -0.001 0.3366 -0.00721763 -0.001 0.336967 -0.00710419 0.00131763 0.337316 -0.0049 0.00131763 0.336967 -0.0049 -0.001 0.3366 -0.0049 0.00131763 0.336967 -0.00258237 -0.001 0.336967 -0.0049 -0.001 0.3366 -0.0049 0.00131763 0.336967 -0.00269581 0.00131763 0.337316 -0.00258237 -0.001 0.336967 -0.00269581 0.00131763 0.337316 -0.000491611 -0.001 0.338032 -0.00258237 -0.001 0.336967 -0.00269581 0.00131763 0.337316 -0.0007073719999999999 0.00131763 0.338329 -0.000491611 -0.001 0.338032 -0.0007073719999999999 0.00131763 0.338329 0.00116763 -0.001 0.339692 -0.000491611 -0.001 0.338032 -0.0007073719999999999 0.00131763 0.338329 0.000870657 0.00131763 0.339907 0.00116763 -0.001 0.339692 0.000870657 0.00131763 0.339907 0.00223292 -0.001 0.341782 0.00116763 -0.001 0.339692 0.000870657 0.00131763 0.339907 0.00188381 0.00131763 0.341896 0.00223292 -0.001 0.341782 0.00188381 0.00131763 0.341896 0.0026 -0.001 0.3441 0.00223292 -0.001 0.341782 0.00188381 0.00131763 0.341896 0.00223292 0.00131763 0.3441 0.0026 -0.001 0.3441 0.0026 -0.001 0.3441 0.00188381 -0.00331763 0.346304 0.00223292 -0.00331763 0.3441 0.0026 -0.001 0.3441 0.00223292 -0.001 0.346418 0.00188381 -0.00331763 0.346304 0.00223292 -0.001 0.346418 0.000870657 -0.00331763 0.348293 0.00188381 -0.00331763 0.346304 0.00223292 -0.001 0.346418 0.00116763 -0.001 0.348508 0.000870657 -0.00331763 0.348293 0.00116763 -0.001 0.348508 -0.0007073719999999999 -0.00331763 0.349871 0.000870657 -0.00331763 0.348293 0.00116763 -0.001 0.348508 -0.000491611 -0.001 0.350168 -0.0007073719999999999 -0.00331763 0.349871 -0.000491611 -0.001 0.350168 -0.00269581 -0.00331763 0.350884 -0.0007073719999999999 -0.00331763 0.349871 -0.000491611 -0.001 0.350168 -0.00258237 -0.001 0.351233 -0.00269581 -0.00331763 0.350884 -0.00258237 -0.001 0.351233 -0.0049 -0.00331763 0.351233 -0.00269581 -0.00331763 0.350884 -0.00258237 -0.001 0.351233 -0.0049 -0.001 0.3516 -0.0049 -0.00331763 0.351233 -0.0049 -0.001 0.3516 -0.00710419 -0.00331763 0.350884 -0.0049 -0.00331763 0.351233 -0.0049 -0.001 0.3516 -0.00721763 -0.001 0.351233 -0.00710419 -0.00331763 0.350884 -0.00721763 -0.001 0.351233 -0.009092630000000001 -0.00331763 0.349871 -0.00710419 -0.00331763 0.350884 -0.00721763 -0.001 0.351233 -0.00930839 -0.001 0.350168 -0.009092630000000001 -0.00331763 0.349871 -0.00930839 -0.001 0.350168 -0.0106707 -0.00331763 0.348293 -0.009092630000000001 -0.00331763 0.349871 -0.00930839 -0.001 0.350168 -0.0109676 -0.001 0.348508 -0.0106707 -0.00331763 0.348293 -0.0109676 -0.001 0.348508 -0.0116838 -0.00331763 0.346304 -0.0106707 -0.00331763 0.348293 -0.0109676 -0.001 0.348508 -0.0120329 -0.001 0.346418 -0.0116838 -0.00331763 0.346304 -0.0120329 -0.001 0.346418 -0.0120329 -0.00331763 0.3441 -0.0116838 -0.00331763 0.346304 -0.0120329 -0.001 0.346418 -0.0124 -0.001 0.3441 -0.0120329 -0.00331763 0.3441 -0.0124 -0.001 0.3441 -0.0116838 -0.00331763 0.341896 -0.0120329 -0.00331763 0.3441 -0.0124 -0.001 0.3441 -0.0120329 -0.001 0.341782 -0.0116838 -0.00331763 0.341896 -0.0120329 -0.001 0.341782 -0.0106707 -0.00331763 0.339907 -0.0116838 -0.00331763 0.341896 -0.0120329 -0.001 0.341782 -0.0109676 -0.001 0.339692 -0.0106707 -0.00331763 0.339907 -0.0109676 -0.001 0.339692 -0.009092630000000001 -0.00331763 0.338329 -0.0106707 -0.00331763 0.339907 -0.0109676 -0.001 0.339692 -0.00930839 -0.001 0.338032 -0.009092630000000001 -0.00331763 0.338329 -0.00930839 -0.001 0.338032 -0.00710419 -0.00331763 0.337316 -0.009092630000000001 -0.00331763 0.338329 -0.00930839 -0.001 0.338032 -0.00721763 -0.001 0.336967 -0.00710419 -0.00331763 0.337316 -0.00721763 -0.001 0.336967 -0.0049 -0.00331763 0.336967 -0.00710419 -0.00331763 0.337316 -0.00721763 -0.001 0.336967 -0.0049 -0.001 0.3366 -0.0049 -0.00331763 0.336967 -0.0049 -0.001 0.3366 -0.00269581 -0.00331763 0.337316 -0.0049 -0.00331763 0.336967 -0.0049 -0.001 0.3366 -0.00258237 -0.001 0.336967 -0.00269581 -0.00331763 0.337316 -0.00258237 -0.001 0.336967 -0.0007073719999999999 -0.00331763 0.338329 -0.00269581 -0.00331763 0.337316 -0.00258237 -0.001 0.336967 -0.000491611 -0.001 0.338032 -0.0007073719999999999 -0.00331763 0.338329 -0.000491611 -0.001 0.338032 0.000870657 -0.00331763 0.339907 -0.0007073719999999999 -0.00331763 0.338329 -0.000491611 -0.001 0.338032 0.00116763 -0.001 0.339692 0.000870657 -0.00331763 0.339907 0.00116763 -0.001 0.339692 0.00188381 -0.00331763 0.341896 0.000870657 -0.00331763 0.339907 0.00116763 -0.001 0.339692 0.00223292 -0.001 0.341782 0.00188381 -0.00331763 0.341896 0.00223292 -0.001 0.341782 0.00223292 -0.00331763 0.3441 0.00188381 -0.00331763 0.341896 0.00223292 -0.001 0.341782 0.0026 -0.001 0.3441 0.00223292 -0.00331763 0.3441 0.00223292 -0.00331763 0.3441 0.000870657 -0.00540839 0.345975 0.00116763 -0.00540839 0.3441 0.00223292 -0.00331763 0.3441 0.00188381 -0.00331763 0.346304 0.000870657 -0.00540839 0.345975 0.00188381 -0.00331763 0.346304 8.81363e-06 -0.00540839 0.347666 0.000870657 -0.00540839 0.345975 0.00188381 -0.00331763 0.346304 0.000870657 -0.00331763 0.348293 8.81363e-06 -0.00540839 0.347666 0.000870657 -0.00331763 0.348293 -0.00133354 -0.00540839 0.349009 8.81363e-06 -0.00540839 0.347666 0.000870657 -0.00331763 0.348293 -0.0007073719999999999 -0.00331763 0.349871 -0.00133354 -0.00540839 0.349009 -0.0007073719999999999 -0.00331763 0.349871 -0.003025 -0.00540839 0.349871 -0.00133354 -0.00540839 0.349009 -0.0007073719999999999 -0.00331763 0.349871 -0.00269581 -0.00331763 0.350884 -0.003025 -0.00540839 0.349871 -0.00269581 -0.00331763 0.350884 -0.0049 -0.00540839 0.350168 -0.003025 -0.00540839 0.349871 -0.00269581 -0.00331763 0.350884 -0.0049 -0.00331763 0.351233 -0.0049 -0.00540839 0.350168 -0.0049 -0.00331763 0.351233 -0.006775 -0.00540839 0.349871 -0.0049 -0.00540839 0.350168 -0.0049 -0.00331763 0.351233 -0.00710419 -0.00331763 0.350884 -0.006775 -0.00540839 0.349871 -0.00710419 -0.00331763 0.350884 -0.00846646 -0.00540839 0.349009 -0.006775 -0.00540839 0.349871 -0.00710419 -0.00331763 0.350884 -0.009092630000000001 -0.00331763 0.349871 -0.00846646 -0.00540839 0.349009 -0.009092630000000001 -0.00331763 0.349871 -0.009808809999999999 -0.00540839 0.347666 -0.00846646 -0.00540839 0.349009 -0.009092630000000001 -0.00331763 0.349871 -0.0106707 -0.00331763 0.348293 -0.009808809999999999 -0.00540839 0.347666 -0.0106707 -0.00331763 0.348293 -0.0106707 -0.00540839 0.345975 -0.009808809999999999 -0.00540839 0.347666 -0.0106707 -0.00331763 0.348293 -0.0116838 -0.00331763 0.346304 -0.0106707 -0.00540839 0.345975 -0.0116838 -0.00331763 0.346304 -0.0109676 -0.00540839 0.3441 -0.0106707 -0.00540839 0.345975 -0.0116838 -0.00331763 0.346304 -0.0120329 -0.00331763 0.3441 -0.0109676 -0.00540839 0.3441 -0.0120329 -0.00331763 0.3441 -0.0106707 -0.00540839 0.342225 -0.0109676 -0.00540839 0.3441 -0.0120329 -0.00331763 0.3441 -0.0116838 -0.00331763 0.341896 -0.0106707 -0.00540839 0.342225 -0.0116838 -0.00331763 0.341896 -0.009808809999999999 -0.00540839 0.340534 -0.0106707 -0.00540839 0.342225 -0.0116838 -0.00331763 0.341896 -0.0106707 -0.00331763 0.339907 -0.009808809999999999 -0.00540839 0.340534 -0.0106707 -0.00331763 0.339907 -0.00846646 -0.00540839 0.339191 -0.009808809999999999 -0.00540839 0.340534 -0.0106707 -0.00331763 0.339907 -0.009092630000000001 -0.00331763 0.338329 -0.00846646 -0.00540839 0.339191 -0.009092630000000001 -0.00331763 0.338329 -0.006775 -0.00540839 0.338329 -0.00846646 -0.00540839 0.339191 -0.009092630000000001 -0.00331763 0.338329 -0.00710419 -0.00331763 0.337316 -0.006775 -0.00540839 0.338329 -0.00710419 -0.00331763 0.337316 -0.0049 -0.00540839 0.338032 -0.006775 -0.00540839 0.338329 -0.00710419 -0.00331763 0.337316 -0.0049 -0.00331763 0.336967 -0.0049 -0.00540839 0.338032 -0.0049 -0.00331763 0.336967 -0.003025 -0.00540839 0.338329 -0.0049 -0.00540839 0.338032 -0.0049 -0.00331763 0.336967 -0.00269581 -0.00331763 0.337316 -0.003025 -0.00540839 0.338329 -0.00269581 -0.00331763 0.337316 -0.00133354 -0.00540839 0.339191 -0.003025 -0.00540839 0.338329 -0.00269581 -0.00331763 0.337316 -0.0007073719999999999 -0.00331763 0.338329 -0.00133354 -0.00540839 0.339191 -0.0007073719999999999 -0.00331763 0.338329 8.81363e-06 -0.00540839 0.340534 -0.00133354 -0.00540839 0.339191 -0.0007073719999999999 -0.00331763 0.338329 0.000870657 -0.00331763 0.339907 8.81363e-06 -0.00540839 0.340534 0.000870657 -0.00331763 0.339907 0.000870657 -0.00540839 0.342225 8.81363e-06 -0.00540839 0.340534 0.000870657 -0.00331763 0.339907 0.00188381 -0.00331763 0.341896 0.000870657 -0.00540839 0.342225 0.00188381 -0.00331763 0.341896 0.00116763 -0.00540839 0.3441 0.000870657 -0.00540839 0.342225 0.00188381 -0.00331763 0.341896 0.00223292 -0.00331763 0.3441 0.00116763 -0.00540839 0.3441 0.00116763 -0.00540839 0.3441 -0.0007073719999999999 -0.00706763 0.345462 -0.000491611 -0.00706763 0.3441 0.00116763 -0.00540839 0.3441 0.000870657 -0.00540839 0.345975 -0.0007073719999999999 -0.00706763 0.345462 0.000870657 -0.00540839 0.345975 -0.00133354 -0.00706763 0.346691 -0.0007073719999999999 -0.00706763 0.345462 0.000870657 -0.00540839 0.345975 8.81363e-06 -0.00540839 0.347666 -0.00133354 -0.00706763 0.346691 8.81363e-06 -0.00540839 0.347666 -0.00230881 -0.00706763 0.347666 -0.00133354 -0.00706763 0.346691 8.81363e-06 -0.00540839 0.347666 -0.00133354 -0.00540839 0.349009 -0.00230881 -0.00706763 0.347666 -0.00133354 -0.00540839 0.349009 -0.00353773 -0.00706763 0.348293 -0.00230881 -0.00706763 0.347666 -0.00133354 -0.00540839 0.349009 -0.003025 -0.00540839 0.349871 -0.00353773 -0.00706763 0.348293 -0.003025 -0.00540839 0.349871 -0.0049 -0.00706763 0.348508 -0.00353773 -0.00706763 0.348293 -0.003025 -0.00540839 0.349871 -0.0049 -0.00540839 0.350168 -0.0049 -0.00706763 0.348508 -0.0049 -0.00540839 0.350168 -0.00626227 -0.00706763 0.348293 -0.0049 -0.00706763 0.348508 -0.0049 -0.00540839 0.350168 -0.006775 -0.00540839 0.349871 -0.00626227 -0.00706763 0.348293 -0.006775 -0.00540839 0.349871 -0.00749119 -0.00706763 0.347666 -0.00626227 -0.00706763 0.348293 -0.006775 -0.00540839 0.349871 -0.00846646 -0.00540839 0.349009 -0.00749119 -0.00706763 0.347666 -0.00846646 -0.00540839 0.349009 -0.00846646 -0.00706763 0.346691 -0.00749119 -0.00706763 0.347666 -0.00846646 -0.00540839 0.349009 -0.009808809999999999 -0.00540839 0.347666 -0.00846646 -0.00706763 0.346691 -0.009808809999999999 -0.00540839 0.347666 -0.009092630000000001 -0.00706763 0.345462 -0.00846646 -0.00706763 0.346691 -0.009808809999999999 -0.00540839 0.347666 -0.0106707 -0.00540839 0.345975 -0.009092630000000001 -0.00706763 0.345462 -0.0106707 -0.00540839 0.345975 -0.00930839 -0.00706763 0.3441 -0.009092630000000001 -0.00706763 0.345462 -0.0106707 -0.00540839 0.345975 -0.0109676 -0.00540839 0.3441 -0.00930839 -0.00706763 0.3441 -0.0109676 -0.00540839 0.3441 -0.009092630000000001 -0.00706763 0.342738 -0.00930839 -0.00706763 0.3441 -0.0109676 -0.00540839 0.3441 -0.0106707 -0.00540839 0.342225 -0.009092630000000001 -0.00706763 0.342738 -0.0106707 -0.00540839 0.342225 -0.00846646 -0.00706763 0.341509 -0.009092630000000001 -0.00706763 0.342738 -0.0106707 -0.00540839 0.342225 -0.009808809999999999 -0.00540839 0.340534 -0.00846646 -0.00706763 0.341509 -0.009808809999999999 -0.00540839 0.340534 -0.00749119 -0.00706763 0.340534 -0.00846646 -0.00706763 0.341509 -0.009808809999999999 -0.00540839 0.340534 -0.00846646 -0.00540839 0.339191 -0.00749119 -0.00706763 0.340534 -0.00846646 -0.00540839 0.339191 -0.00626227 -0.00706763 0.339907 -0.00749119 -0.00706763 0.340534 -0.00846646 -0.00540839 0.339191 -0.006775 -0.00540839 0.338329 -0.00626227 -0.00706763 0.339907 -0.006775 -0.00540839 0.338329 -0.0049 -0.00706763 0.339692 -0.00626227 -0.00706763 0.339907 -0.006775 -0.00540839 0.338329 -0.0049 -0.00540839 0.338032 -0.0049 -0.00706763 0.339692 -0.0049 -0.00540839 0.338032 -0.00353773 -0.00706763 0.339907 -0.0049 -0.00706763 0.339692 -0.0049 -0.00540839 0.338032 -0.003025 -0.00540839 0.338329 -0.00353773 -0.00706763 0.339907 -0.003025 -0.00540839 0.338329 -0.00230881 -0.00706763 0.340534 -0.00353773 -0.00706763 0.339907 -0.003025 -0.00540839 0.338329 -0.00133354 -0.00540839 0.339191 -0.00230881 -0.00706763 0.340534 -0.00133354 -0.00540839 0.339191 -0.00133354 -0.00706763 0.341509 -0.00230881 -0.00706763 0.340534 -0.00133354 -0.00540839 0.339191 8.81363e-06 -0.00540839 0.340534 -0.00133354 -0.00706763 0.341509 8.81363e-06 -0.00540839 0.340534 -0.0007073719999999999 -0.00706763 0.342738 -0.00133354 -0.00706763 0.341509 8.81363e-06 -0.00540839 0.340534 0.000870657 -0.00540839 0.342225 -0.0007073719999999999 -0.00706763 0.342738 0.000870657 -0.00540839 0.342225 -0.000491611 -0.00706763 0.3441 -0.0007073719999999999 -0.00706763 0.342738 0.000870657 -0.00540839 0.342225 0.00116763 -0.00540839 0.3441 -0.000491611 -0.00706763 0.3441 -0.000491611 -0.00706763 0.3441 -0.00269581 -0.00813292 0.344816 -0.00258237 -0.00813292 0.3441 -0.000491611 -0.00706763 0.3441 -0.0007073719999999999 -0.00706763 0.345462 -0.00269581 -0.00813292 0.344816 -0.0007073719999999999 -0.00706763 0.345462 -0.003025 -0.00813292 0.345462 -0.00269581 -0.00813292 0.344816 -0.0007073719999999999 -0.00706763 0.345462 -0.00133354 -0.00706763 0.346691 -0.003025 -0.00813292 0.345462 -0.00133354 -0.00706763 0.346691 -0.00353773 -0.00813292 0.345975 -0.003025 -0.00813292 0.345462 -0.00133354 -0.00706763 0.346691 -0.00230881 -0.00706763 0.347666 -0.00353773 -0.00813292 0.345975 -0.00230881 -0.00706763 0.347666 -0.00418381 -0.00813292 0.346304 -0.00353773 -0.00813292 0.345975 -0.00230881 -0.00706763 0.347666 -0.00353773 -0.00706763 0.348293 -0.00418381 -0.00813292 0.346304 -0.00353773 -0.00706763 0.348293 -0.0049 -0.00813292 0.346418 -0.00418381 -0.00813292 0.346304 -0.00353773 -0.00706763 0.348293 -0.0049 -0.00706763 0.348508 -0.0049 -0.00813292 0.346418 -0.0049 -0.00706763 0.348508 -0.00561619 -0.00813292 0.346304 -0.0049 -0.00813292 0.346418 -0.0049 -0.00706763 0.348508 -0.00626227 -0.00706763 0.348293 -0.00561619 -0.00813292 0.346304 -0.00626227 -0.00706763 0.348293 -0.00626227 -0.00813292 0.345975 -0.00561619 -0.00813292 0.346304 -0.00626227 -0.00706763 0.348293 -0.00749119 -0.00706763 0.347666 -0.00626227 -0.00813292 0.345975 -0.00749119 -0.00706763 0.347666 -0.006775 -0.00813292 0.345462 -0.00626227 -0.00813292 0.345975 -0.00749119 -0.00706763 0.347666 -0.00846646 -0.00706763 0.346691 -0.006775 -0.00813292 0.345462 -0.00846646 -0.00706763 0.346691 -0.00710419 -0.00813292 0.344816 -0.006775 -0.00813292 0.345462 -0.00846646 -0.00706763 0.346691 -0.009092630000000001 -0.00706763 0.345462 -0.00710419 -0.00813292 0.344816 -0.009092630000000001 -0.00706763 0.345462 -0.00721763 -0.00813292 0.3441 -0.00710419 -0.00813292 0.344816 -0.009092630000000001 -0.00706763 0.345462 -0.00930839 -0.00706763 0.3441 -0.00721763 -0.00813292 0.3441 -0.00930839 -0.00706763 0.3441 -0.00710419 -0.00813292 0.343384 -0.00721763 -0.00813292 0.3441 -0.00930839 -0.00706763 0.3441 -0.009092630000000001 -0.00706763 0.342738 -0.00710419 -0.00813292 0.343384 -0.009092630000000001 -0.00706763 0.342738 -0.006775 -0.00813292 0.342738 -0.00710419 -0.00813292 0.343384 -0.009092630000000001 -0.00706763 0.342738 -0.00846646 -0.00706763 0.341509 -0.006775 -0.00813292 0.342738 -0.00846646 -0.00706763 0.341509 -0.00626227 -0.00813292 0.342225 -0.006775 -0.00813292 0.342738 -0.00846646 -0.00706763 0.341509 -0.00749119 -0.00706763 0.340534 -0.00626227 -0.00813292 0.342225 -0.00749119 -0.00706763 0.340534 -0.00561619 -0.00813292 0.341896 -0.00626227 -0.00813292 0.342225 -0.00749119 -0.00706763 0.340534 -0.00626227 -0.00706763 0.339907 -0.00561619 -0.00813292 0.341896 -0.00626227 -0.00706763 0.339907 -0.0049 -0.00813292 0.341782 -0.00561619 -0.00813292 0.341896 -0.00626227 -0.00706763 0.339907 -0.0049 -0.00706763 0.339692 -0.0049 -0.00813292 0.341782 -0.0049 -0.00706763 0.339692 -0.00418381 -0.00813292 0.341896 -0.0049 -0.00813292 0.341782 -0.0049 -0.00706763 0.339692 -0.00353773 -0.00706763 0.339907 -0.00418381 -0.00813292 0.341896 -0.00353773 -0.00706763 0.339907 -0.00353773 -0.00813292 0.342225 -0.00418381 -0.00813292 0.341896 -0.00353773 -0.00706763 0.339907 -0.00230881 -0.00706763 0.340534 -0.00353773 -0.00813292 0.342225 -0.00230881 -0.00706763 0.340534 -0.003025 -0.00813292 0.342738 -0.00353773 -0.00813292 0.342225 -0.00230881 -0.00706763 0.340534 -0.00133354 -0.00706763 0.341509 -0.003025 -0.00813292 0.342738 -0.00133354 -0.00706763 0.341509 -0.00269581 -0.00813292 0.343384 -0.003025 -0.00813292 0.342738 -0.00133354 -0.00706763 0.341509 -0.0007073719999999999 -0.00706763 0.342738 -0.00269581 -0.00813292 0.343384 -0.0007073719999999999 -0.00706763 0.342738 -0.00258237 -0.00813292 0.3441 -0.00269581 -0.00813292 0.343384 -0.0007073719999999999 -0.00706763 0.342738 -0.000491611 -0.00706763 0.3441 -0.00258237 -0.00813292 0.3441 -0.0049 -0.008500000000000001 0.3441 -0.00258237 -0.00813292 0.3441 -0.00269581 -0.00813292 0.344816 -0.0049 -0.008500000000000001 0.3441 -0.00269581 -0.00813292 0.344816 -0.003025 -0.00813292 0.345462 -0.0049 -0.008500000000000001 0.3441 -0.003025 -0.00813292 0.345462 -0.00353773 -0.00813292 0.345975 -0.0049 -0.008500000000000001 0.3441 -0.00353773 -0.00813292 0.345975 -0.00418381 -0.00813292 0.346304 -0.0049 -0.008500000000000001 0.3441 -0.00418381 -0.00813292 0.346304 -0.0049 -0.00813292 0.346418 -0.0049 -0.008500000000000001 0.3441 -0.0049 -0.00813292 0.346418 -0.00561619 -0.00813292 0.346304 -0.0049 -0.008500000000000001 0.3441 -0.00561619 -0.00813292 0.346304 -0.00626227 -0.00813292 0.345975 -0.0049 -0.008500000000000001 0.3441 -0.00626227 -0.00813292 0.345975 -0.006775 -0.00813292 0.345462 -0.0049 -0.008500000000000001 0.3441 -0.006775 -0.00813292 0.345462 -0.00710419 -0.00813292 0.344816 -0.0049 -0.008500000000000001 0.3441 -0.00710419 -0.00813292 0.344816 -0.00721763 -0.00813292 0.3441 -0.0049 -0.008500000000000001 0.3441 -0.00721763 -0.00813292 0.3441 -0.00710419 -0.00813292 0.343384 -0.0049 -0.008500000000000001 0.3441 -0.00710419 -0.00813292 0.343384 -0.006775 -0.00813292 0.342738 -0.0049 -0.008500000000000001 0.3441 -0.006775 -0.00813292 0.342738 -0.00626227 -0.00813292 0.342225 -0.0049 -0.008500000000000001 0.3441 -0.00626227 -0.00813292 0.342225 -0.00561619 -0.00813292 0.341896 -0.0049 -0.008500000000000001 0.3441 -0.00561619 -0.00813292 0.341896 -0.0049 -0.00813292 0.341782 -0.0049 -0.008500000000000001 0.3441 -0.0049 -0.00813292 0.341782 -0.00418381 -0.00813292 0.341896 -0.0049 -0.008500000000000001 0.3441 -0.00418381 -0.00813292 0.341896 -0.00353773 -0.00813292 0.342225 -0.0049 -0.008500000000000001 0.3441 -0.00353773 -0.00813292 0.342225 -0.003025 -0.00813292 0.342738 -0.0049 -0.008500000000000001 0.3441 -0.003025 -0.00813292 0.342738 -0.00269581 -0.00813292 0.343384 -0.0049 -0.008500000000000001 0.3441 -0.00269581 -0.00813292 0.343384 -0.00258237 -0.00813292 0.3441 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079

    -
    -
    - - - 0 0 0 - 1 0 0 0 - - true - - - -
    - - - - 0.000320995 0.169414 0.322342 0.008331989999999999 0.168542 0.322575 0.008331989999999999 0.16554 0.31137 0.008331989999999999 0.168542 0.322575 0.000320995 0.169414 0.322342 0.036321 0.13464 0.331659 0.0355434 0.125382 0.323788 0.035419 0.124314 0.324074 0.036 0.125074 0.32387 0.035419 0.124314 0.324074 0.0355434 0.125382 0.323788 0.035419 0.126902 0.333733 0.036 0.129298 0.322738 0.0355434 0.125382 0.323788 0.036 0.125074 0.32387 0.0355434 0.125382 0.323788 0.036321 0.13464 0.331659 0.035419 0.126902 0.333733 -0.015298 0.100722 0.330396 -0.0211817 0.104293 0.329439 -0.0268302 0.105148 0.32921 -0.0211817 0.104293 0.329439 -0.015298 0.100722 0.330396 -0.015298 0.10331 0.340054 -0.015298 0.10331 0.340054 -0.022124 0.107453 0.338944 -0.0211817 0.104293 0.329439 -0.0270382 0.109611 0.328014 -0.0239346 0.107863 0.333479 -0.022124 0.107453 0.338944 -0.0270382 0.109611 0.328014 -0.022124 0.107453 0.338944 -0.027825 0.112959 0.337469 -0.0270382 0.109611 0.328014 -0.0256622 0.108282 0.32837 -0.0239346 0.107863 0.333479 -0.0256622 0.108282 0.32837 -0.0270382 0.109611 0.328014 -0.039617 0.112034 0.327365 -0.0270382 0.109611 0.328014 -0.027825 0.110371 0.32781 -0.039617 0.112034 0.327365 -0.0239346 0.107863 0.333479 -0.022124 0.104865 0.329286 -0.022124 0.107453 0.338944 -0.022124 0.107453 0.338944 0.036321 0.13464 0.331659 -0.027825 0.112959 0.337469 -0.022124 0.107453 0.338944 -0.015298 0.10331 0.340054 0.036321 0.13464 0.331659 0.036321 0.13464 0.331659 -0.032114 0.119553 0.335702 -0.027825 0.112959 0.337469 -0.027825 0.110371 0.32781 -0.0270382 0.109611 0.328014 -0.027825 0.112959 0.337469 -0.0193024 0.162013 0.318218 -0.0209336 0.159962 0.314523 -0.022124 0.159239 0.314717 -0.0193024 0.162013 0.318218 -0.022124 0.159239 0.314717 -0.022124 0.161827 0.324375 -0.0348859 0.1388 0.319997 -0.036 0.132054 0.322 -0.0348859 0.138849 0.32018 -0.0347601 0.139374 0.318381 -0.0348859 0.1388 0.319997 -0.0348859 0.138849 0.32018 -0.0347601 0.139374 0.318381 -0.0348859 0.138849 0.32018 -0.034776 0.142378 0.329586 -0.0347601 0.139374 0.318381 -0.0348859 0.138434 0.318633 -0.0348859 0.1388 0.319997 -0.0347601 0.139374 0.318381 -0.034776 0.142378 0.329586 -0.0346947 0.140015 0.319867 -0.0346947 0.139601 0.318321 -0.0347601 0.139374 0.318381 -0.0346947 0.140015 0.319867 -0.0348859 0.138434 0.318633 -0.036 0.132054 0.322 -0.0348859 0.1388 0.319997 -0.034238 0.132706 0.28145 -0.036 0.132054 0.322 -0.0348859 0.138434 0.318633 -0.034776 0.142378 0.329586 -0.0340839 0.142905 0.323908 -0.0346947 0.140015 0.319867 -0.034776 0.124314 0.324075 -0.0348051 0.124564 0.324008 -0.036 0.125074 0.323871 -0.034776 0.126902 0.333733 -0.0348051 0.124564 0.324008 -0.034776 0.124314 0.324075 -0.034776 0.124314 0.324075 -0.0344086 0.1233 0.324346 -0.034776 0.126902 0.333733 -0.0355544 0.130984 0.322287 -0.0348051 0.124564 0.324008 -0.034776 0.126902 0.333733 -0.034776 0.126902 0.333733 -0.035679 0.13464 0.331659 -0.0355544 0.130984 0.322287 -0.0346752 0.12216 0.324651 -0.036 0.125074 0.323871 -0.03641 0.120545 0.325084 -0.0344086 0.1233 0.324346 -0.036 0.125074 0.323871 -0.0346752 0.12216 0.324651 -0.0344086 0.1233 0.324346 -0.0346752 0.12216 0.324651 -0.0329403 0.119246 0.325432 -0.0344086 0.1233 0.324346 -0.0329403 0.119246 0.325432 -0.0328688 0.120265 0.330024 0.036321 0.13464 0.331659 -0.034776 0.142378 0.329586 -0.035679 0.13464 0.331659 -0.035679 0.13464 0.331659 -0.034776 0.142378 0.329586 -0.0349006 0.138722 0.320213 0.036321 0.13464 0.331659 -0.032114 0.149728 0.327617 -0.034776 0.142378 0.329586 -0.034776 0.142378 0.329586 -0.032114 0.149728 0.327617 -0.0324789 0.146133 0.318228 -0.0319658 0.146693 0.316421 -0.032114 0.146726 0.316412 -0.0312391 0.148071 0.316052 -0.0312391 0.148071 0.316052 -0.032114 0.146726 0.316412 -0.0312392 0.148485 0.317598 -0.0288005 0.152234 0.316593 -0.029125 0.152493 0.316524 -0.0312392 0.148485 0.317598 -0.0288005 0.152234 0.316593 -0.0312392 0.148485 0.317598 -0.0309085 0.150165 0.321834 -0.0312392 0.148485 0.317598 -0.032114 0.146726 0.316412 -0.0309085 0.150165 0.321834 -0.0309085 0.150165 0.321834 -0.032114 0.146726 0.316412 -0.032114 0.149728 0.327617 -0.032114 0.146726 0.316412 -0.0324789 0.146133 0.318228 -0.032114 0.149728 0.327617 -0.0324789 0.146133 0.318228 -0.0340839 0.142905 0.323908 -0.034776 0.142378 0.329586 -0.0337899 0.142513 0.319198 -0.034238 0.1428 0.319121 -0.0346947 0.140015 0.319867 -0.0337899 0.142513 0.319198 -0.0333572 0.144326 0.318712 -0.034238 0.1428 0.319121 -0.034238 0.1428 0.319121 -0.0333572 0.144326 0.318712 -0.0324789 0.146133 0.318228 -0.0324789 0.146133 0.318228 -0.034238 0.1428 0.319121 -0.0324765 0.146134 0.318206 -0.032114 0.146726 0.316412 -0.0324765 0.145725 0.31668 -0.0324765 0.146134 0.318206 -0.0324765 0.145725 0.31668 -0.034238 0.1428 0.319121 -0.0324765 0.146134 0.318206 -0.034238 0.1428 0.319121 -0.0324765 0.145725 0.31668 -0.029125 0.142399 0.278853 -0.029125 0.142399 0.278853 -0.034238 0.132706 0.28145 -0.034238 0.1428 0.319121 -0.0324789 0.146133 0.318228 -0.0333572 0.144326 0.318712 -0.0337899 0.142513 0.319198 -0.0324789 0.146133 0.318228 -0.0337899 0.142513 0.319198 -0.0340839 0.142905 0.323908 -0.0319658 0.146693 0.316421 -0.0324765 0.145725 0.31668 -0.032114 0.146726 0.316412 -0.0349006 0.138722 0.320213 -0.035679 0.132052 0.322 -0.035679 0.13464 0.331659 -0.027825 0.156321 0.32585 -0.032114 0.149728 0.327617 0.036321 0.13464 0.331659 -0.039617 0.10194 0.289694 -0.045645 0.095002 0.291553 -0.045645 0.105096 0.329224 -0.053765 0.100567 0.330437 -0.045645 0.105096 0.329224 -0.045645 0.095002 0.291553 -0.053765 0.100567 0.330437 -0.045645 0.095002 0.291553 -0.053765 0.090473 0.292766 -0.053765 0.100567 0.330437 -0.0394457 0.0833752 0.334 -0.045645 0.105096 0.329224 -0.061307 0.09904499999999999 0.330845 -0.053765 0.100567 0.330437 -0.053765 0.090473 0.292766 -0.032114 0.116965 0.326043 -0.03641 0.120545 0.325084 -0.0326396 0.114414 0.326727 -0.0326396 0.114414 0.326727 -0.03641 0.120545 0.325084 -0.039617 0.112034 0.327365 -0.03641 0.110452 0.287413 -0.039617 0.10194 0.289694 -0.039617 0.112034 0.327365 -0.039617 0.112034 0.327365 -0.03641 0.120545 0.325084 -0.03641 0.110452 0.287413 -0.039617 0.10194 0.289694 -0.045645 0.105096 0.329224 -0.039617 0.112034 0.327365 -0.036 0.11498 0.2862 -0.03641 0.110452 0.287413 -0.03641 0.120545 0.325084 -0.0315221 0.116055 0.326287 -0.032114 0.116965 0.326043 -0.0326396 0.114414 0.326727 -0.027825 0.110371 0.32781 -0.0315221 0.116055 0.326287 -0.0326396 0.114414 0.326727 -0.0315221 0.116055 0.326287 -0.027825 0.110371 0.32781 -0.027825 0.112959 0.337469 -0.032114 0.116965 0.326043 -0.0329403 0.119246 0.325432 -0.03641 0.120545 0.325084 -0.0268302 0.105148 0.32921 -0.039617 0.112034 0.327365 -0.045645 0.105096 0.329224 -0.036 0.12196 0.284329 -0.036 0.11498 0.2862 -0.036 0.125074 0.323871 -0.061307 0.088951 0.293174 -0.061307 0.09904499999999999 0.330845 -0.053765 0.090473 0.292766 -0.061307 0.088951 0.293174 -0.061307 0.082135 0.295 -0.061307 0.087269 0.334 -0.036 0.132054 0.322 -0.036 0.12196 0.284329 -0.036 0.125074 0.323871 -0.036 0.132054 0.322 -0.036 0.125074 0.323871 -0.0355544 0.130984 0.322287 -0.036 0.132054 0.322 -0.0355544 0.130984 0.322287 -0.0356591 0.131881 0.322046 -0.035679 0.132052 0.322 -0.0354429 0.135365 0.321113 -0.036 0.132054 0.322 -0.036 0.132054 0.322 -0.0356591 0.131881 0.322046 -0.035679 0.132052 0.322 -0.035679 0.13464 0.331659 -0.0356591 0.131881 0.322046 -0.0355544 0.130984 0.322287 -0.0328688 0.120265 0.330024 -0.0329403 0.119246 0.325432 -0.032114 0.116965 0.326043 -0.0328688 0.120265 0.330024 -0.032114 0.116965 0.326043 -0.032114 0.119553 0.335702 -0.032114 0.149728 0.327617 -0.027825 0.156321 0.32585 -0.028417 0.152823 0.316436 -0.027825 0.153733 0.316192 -0.028417 0.152823 0.316436 -0.027825 0.156321 0.32585 -0.027825 0.153733 0.316192 -0.029125 0.152493 0.316524 -0.028417 0.152823 0.316436 -0.0229109 0.158479 0.31492 -0.029125 0.152493 0.316524 -0.022124 0.159239 0.314717 -0.02116 0.160186 0.314463 -0.029125 0.152493 0.316524 -0.022124 0.159239 0.314717 -0.027825 0.153733 0.316192 -0.029125 0.152493 0.316524 -0.0229109 0.158479 0.31492 -0.0229109 0.158479 0.31492 -0.027825 0.153733 0.316192 -0.027825 0.156321 0.32585 -0.028417 0.152823 0.316436 -0.0288005 0.152234 0.316593 -0.0309085 0.150165 0.321834 -0.029125 0.152493 0.316524 -0.02116 0.160186 0.314463 -0.02116 0.150092 0.276791 -0.0119742 0.165581 0.317317 -0.0132797 0.164065 0.313423 -0.015298 0.162968 0.31206 -0.0132797 0.164065 0.313423 -0.0132796 0.16365 0.311877 -0.015298 0.162968 0.31206 -0.0132797 0.164065 0.313423 -0.011125 0.165125 0.313139 -0.0132796 0.16365 0.311877 -0.0140599 0.158708 0.294966 -0.0132796 0.16365 0.311877 -0.011125 0.165125 0.313139 -0.011125 0.165125 0.313139 -8.407769999999999e-09 0.156733 0.275012 -0.011125 0.155032 0.275468 -0.0140599 0.158708 0.294966 -0.011125 0.165125 0.313139 -0.011125 0.155032 0.275468 -0.011125 0.165125 0.313139 -0.00933056 0.164985 0.311519 -8.407769999999999e-09 0.156733 0.275012 -0.015298 0.162968 0.31206 -0.0150149 0.162796 0.312106 -0.0180094 0.161322 0.312501 -0.0132796 0.16365 0.311877 -0.0150149 0.162796 0.312106 -0.015298 0.162968 0.31206 -0.0140599 0.158708 0.294966 -0.011125 0.155032 0.275468 -0.02116 0.160186 0.314463 -0.011125 0.155032 0.275468 -0.02116 0.150092 0.276791 -0.02116 0.160186 0.314463 -0.02116 0.160186 0.314463 -0.0180094 0.161322 0.312501 -0.0140599 0.158708 0.294966 -0.0180093 0.161737 0.314047 -0.0180094 0.161322 0.312501 -0.02116 0.160186 0.314463 -0.0180094 0.161322 0.312501 -0.0150149 0.162796 0.312106 -0.0140599 0.158708 0.294966 -0.0180093 0.161737 0.314047 -0.02116 0.160186 0.314463 -0.0209336 0.159962 0.314523 -0.0119742 0.165581 0.317317 -0.0109123 0.164865 0.313209 -0.0132797 0.164065 0.313423 -0.028417 0.152823 0.316436 -0.0309085 0.150165 0.321834 -0.032114 0.149728 0.327617 -0.0119742 0.165581 0.317317 -0.0093303 0.1654 0.313065 -0.0109123 0.164865 0.313209 -0.0344086 0.1233 0.324346 -0.0328688 0.120265 0.330024 -0.032114 0.119553 0.335702 -0.015298 0.16597 0.323265 -0.0119742 0.165581 0.317317 -0.015298 0.162968 0.31206 -0.022124 0.161827 0.324375 -0.015298 0.16597 0.323265 -0.015298 0.162968 0.31206 -0.0193024 0.162013 0.318218 -0.022124 0.161827 0.324375 -0.015298 0.162968 0.31206 0.036321 0.13464 0.331659 -0.022124 0.161827 0.324375 -0.027825 0.156321 0.32585 -0.036 0.11498 0.2862 -0.03641 0.120545 0.325084 -0.036 0.125074 0.323871 0.036321 0.13464 0.331659 -0.035679 0.13464 0.331659 -0.034776 0.126902 0.333733 -0.00768901 0.16554 0.31137 -0.0119742 0.165581 0.317317 -0.015298 0.16597 0.323265 0.008331989999999999 0.16554 0.31137 0.008711969999999999 0.16508 0.311493 0.000456574 0.166343 0.311155 0.000456574 0.166343 0.311155 0.000320995 0.166412 0.311137 0.008331989999999999 0.16554 0.31137 0.000320995 0.166412 0.311137 -0.000807269 0.166289 0.31117 0.000456574 0.166343 0.311155 -0.000807269 0.166289 0.31117 -8.407769999999999e-09 0.156733 0.275012 -0.00735999 0.165287 0.311438 -0.000807269 0.166289 0.31117 0.000456574 0.166343 0.311155 -8.407769999999999e-09 0.156733 0.275012 0.000456574 0.166343 0.311155 0.011124 0.155032 0.275468 -8.407769999999999e-09 0.156733 0.275012 -0.000807269 0.166289 0.31117 -0.00735999 0.165287 0.311438 -0.00768901 0.16554 0.31137 -0.00768901 0.16554 0.31137 -0.00735999 0.165287 0.311438 -0.00933056 0.164985 0.311519 -0.0093303 0.1654 0.313065 -0.00768901 0.16554 0.31137 -0.00933056 0.164985 0.311519 -0.015298 0.16597 0.323265 0.036321 0.13464 0.331659 -0.00768901 0.168542 0.322575 0.036321 0.13464 0.331659 0.000320995 0.169414 0.322342 -0.00768901 0.168542 0.322575 -0.00768901 0.168542 0.322575 0.000320995 0.169414 0.322342 -0.000807269 0.166289 0.31117 -0.015298 0.16597 0.323265 -0.00768901 0.168542 0.322575 -0.00768901 0.16554 0.31137 -0.00768901 0.168542 0.322575 -0.000807269 0.166289 0.31117 -0.00768901 0.16554 0.31137 0.0257855 0.155607 0.314032 0.022767 0.158825 0.31317 0.028467 0.153319 0.314645 0.0288041 0.152389 0.314894 0.0257855 0.155607 0.314032 0.028467 0.153319 0.314645 0.029125 0.152079 0.314977 0.0288041 0.152389 0.314894 0.028467 0.153319 0.314645 0.0288041 0.152389 0.314894 0.0233491 0.157657 0.313483 0.0257855 0.155607 0.314032 0.022767 0.158825 0.31317 0.022767 0.161827 0.324375 0.028467 0.153319 0.314645 0.0233491 0.157657 0.313483 0.022767 0.158825 0.31317 0.0257855 0.155607 0.314032 0.029125 0.142399 0.278853 0.0288041 0.152389 0.314894 0.029125 0.152079 0.314977 0.0214868 0.159456 0.313001 0.022767 0.158825 0.31317 0.0233491 0.157657 0.313483 0.02116 0.159772 0.312916 0.0165414 0.162045 0.312307 0.015941 0.162968 0.31206 0.0165414 0.162045 0.312307 0.02116 0.159772 0.312916 0.02116 0.150092 0.276791 0.029125 0.142399 0.278853 0.0214868 0.159456 0.313001 0.0233491 0.157657 0.313483 0.0214868 0.159456 0.313001 0.029125 0.142399 0.278853 0.02116 0.150092 0.276791 0.02116 0.150092 0.276791 0.02116 0.159772 0.312916 0.0214868 0.159456 0.313001 0.02116 0.159772 0.312916 0.022767 0.158825 0.31317 0.0214868 0.159456 0.313001 0.029125 0.142399 0.278853 0.0233491 0.157657 0.313483 0.0288041 0.152389 0.314894 0.0293349 0.151681 0.315084 0.034238 0.132706 0.28145 0.029125 0.142399 0.278853 0.028467 0.153319 0.314645 0.022767 0.161827 0.324375 0.028467 0.156321 0.32585 0.022767 0.161827 0.324375 0.036321 0.13464 0.331659 0.028467 0.156321 0.32585 0.022767 0.161827 0.324375 0.015941 0.16597 0.323265 0.036321 0.13464 0.331659 0.028467 0.156321 0.32585 0.032756 0.146726 0.316412 0.028467 0.153319 0.314645 0.015941 0.162968 0.31206 0.022767 0.158825 0.31317 0.02116 0.159772 0.312916 0.015941 0.162968 0.31206 0.008331989999999999 0.168542 0.322575 0.015941 0.16597 0.323265 0.015941 0.16597 0.323265 0.022767 0.158825 0.31317 0.015941 0.162968 0.31206 0.008711969999999999 0.16508 0.311493 0.0165414 0.162045 0.312307 0.02116 0.150092 0.276791 0.008711969999999999 0.16508 0.311493 0.02116 0.150092 0.276791 0.011124 0.155032 0.275468 -0.0312392 0.148485 0.317598 -0.029125 0.152493 0.316524 -0.0312391 0.148071 0.316052 -0.029125 0.142399 0.278853 -0.0312391 0.148071 0.316052 -0.029125 0.152493 0.316524 -0.0093303 0.1654 0.313065 -0.0119742 0.165581 0.317317 -0.00768901 0.16554 0.31137 0.032756 0.146726 0.316412 0.0334112 0.143953 0.317155 0.029125 0.152079 0.314977 0.034238 0.142386 0.317575 0.0334112 0.143953 0.317155 0.032756 0.146726 0.316412 0.034238 0.132706 0.28145 0.0334112 0.143953 0.317155 0.034238 0.142386 0.317575 0.034238 0.132706 0.28145 0.034238 0.142386 0.317575 0.0343103 0.141945 0.317693 0.035419 0.139376 0.318381 0.034238 0.142386 0.317575 0.032756 0.146726 0.316412 0.035419 0.139376 0.318381 0.0343103 0.141945 0.317693 0.034238 0.142386 0.317575 0.035419 0.139376 0.318381 0.035273 0.136073 0.319266 0.0343103 0.141945 0.317693 0.035419 0.139376 0.318381 0.035419 0.142378 0.329586 0.036321 0.131638 0.320454 0.035419 0.139376 0.318381 0.032756 0.149728 0.327617 0.035419 0.142378 0.329586 0.036321 0.131638 0.320454 0.035419 0.142378 0.329586 0.036321 0.13464 0.331659 0.036321 0.131638 0.320454 0.035273 0.136073 0.319266 0.035419 0.139376 0.318381 0.036321 0.131638 0.320454 0.035735 0.133256 0.320021 0.035273 0.136073 0.319266 0.036 0.13028 0.320818 0.035735 0.133256 0.320021 0.036321 0.131638 0.320454 0.0359802 0.130006 0.326056 0.036321 0.131638 0.320454 0.036321 0.13464 0.331659 0.035735 0.133256 0.320021 0.036 0.13028 0.320818 0.036 0.12196 0.284329 0.032756 0.149728 0.327617 0.035419 0.139376 0.318381 0.032756 0.146726 0.316412 0.0343103 0.141945 0.317693 0.036 0.12196 0.284329 0.034238 0.132706 0.28145 0.036321 0.13464 0.331659 0.0355434 0.125382 0.323788 0.0359802 0.130006 0.326056 0.036 0.128884 0.321192 0.036 0.13028 0.320818 0.036321 0.131638 0.320454 0.036 0.128884 0.321192 0.036321 0.131638 0.320454 0.036 0.129298 0.322738 0.036 0.13028 0.320818 0.036 0.128884 0.321192 0.036 0.123167 0.305034 0.036 0.128884 0.321192 0.036 0.125074 0.32387 0.036 0.123167 0.305034 0.036 0.125074 0.32387 0.036 0.11498 0.286199 0.036 0.123167 0.305034 0.015941 0.16597 0.323265 0.008331989999999999 0.168542 0.322575 0.036321 0.13464 0.331659 0.041858 0.10132 0.28986 0.037522 0.107587 0.28818 0.037523 0.117681 0.325851 0.037522 0.107587 0.28818 0.036 0.125074 0.32387 0.037523 0.117681 0.325851 0.048346 0.107226 0.328653 0.0525 0.09596 0.291296 0.048346 0.097133 0.290982 0.0525 0.09596 0.291296 0.0525 0.08727 0.334 0.0525 0.082135 0.295 0.048346 0.107226 0.328653 0.0525 0.106054 0.328967 0.0525 0.09596 0.291296 0.041858 0.111414 0.327531 0.048346 0.107226 0.328653 0.048346 0.097133 0.290982 0.041858 0.111414 0.327531 0.048346 0.097133 0.290982 0.041858 0.10132 0.28986 0.037523 0.117681 0.325851 0.041858 0.111414 0.327531 0.041858 0.10132 0.28986 0.0416256 0.10219 0.330002 0.048346 0.107226 0.328653 0.0449858 0.106802 0.328767 0.048346 0.107226 0.328653 0.041858 0.111414 0.327531 0.0449858 0.106802 0.328767 0.041858 0.111414 0.327531 0.0416256 0.10219 0.330002 0.0449858 0.106802 0.328767 0.037523 0.117681 0.325851 0.0416256 0.10219 0.330002 0.041858 0.111414 0.327531 0.0525 0.106054 0.328967 0.0525 0.08727 0.334 0.0525 0.09596 0.291296 -0.0256622 0.108282 0.32837 -0.022124 0.104865 0.329286 -0.0239346 0.107863 0.333479 -0.036 0.125074 0.323871 -0.0344086 0.1233 0.324346 -0.034776 0.124314 0.324075 -0.0348859 0.138849 0.32018 -0.0349006 0.138722 0.320213 -0.034776 0.142378 0.329586 -0.0348859 0.138849 0.32018 -0.0354429 0.135365 0.321113 -0.0349006 0.138722 0.320213 0.032756 0.149728 0.327617 0.036321 0.13464 0.331659 0.035419 0.142378 0.329586 0.029125 0.152079 0.314977 0.028467 0.153319 0.314645 0.032756 0.146726 0.316412 0.032756 0.119553 0.335702 0.028467 0.112959 0.337469 0.028467 0.110371 0.32781 0.032756 0.119553 0.335702 0.028467 0.110371 0.32781 0.032756 0.116965 0.326043 0.032756 0.119553 0.335702 0.032756 0.116965 0.326043 0.035419 0.124314 0.324074 0.028467 0.112959 0.337469 0.032756 0.119553 0.335702 0.036321 0.13464 0.331659 0.032756 0.119553 0.335702 0.035419 0.126902 0.333733 0.036321 0.13464 0.331659 0.037523 0.117681 0.325851 0.035419 0.124314 0.324074 0.032756 0.116965 0.326043 0.028467 0.112959 0.337469 0.022767 0.104865 0.329285 0.028467 0.110371 0.32781 0.0416256 0.10219 0.330002 0.028467 0.110371 0.32781 0.022767 0.104865 0.329285 -0.061307 0.082135 0.295 -0.061307 0.08136690000000001 0.3145 -0.061307 0.087269 0.334 0.0312341 0.09406730000000001 0.332179 0.022767 0.104865 0.329285 0.015941 0.100722 0.330396 0.015941 0.100722 0.330396 0.022767 0.104865 0.329285 0.022767 0.107453 0.338944 0.015941 0.100722 0.330396 0.0227564 0.092987 0.332468 0.0312341 0.09406730000000001 0.332179 0.0525 0.08727 0.334 0.0416256 0.10219 0.330002 0.0364882 0.09650060000000001 0.331527 0.015941 0.10331 0.340054 0.015941 0.100722 0.330396 0.022767 0.107453 0.338944 0.015941 0.10331 0.340054 0.00996817 0.0987039 0.330937 0.015941 0.100722 0.330396 0.015941 0.10331 0.340054 0.008331989999999999 0.100739 0.340743 0.00996817 0.0987039 0.330937 0.036321 0.13464 0.331659 0.008331989999999999 0.100739 0.340743 0.015941 0.10331 0.340054 0.000320996 0.099867 0.340978 0.036321 0.13464 0.331659 -0.00768901 0.100739 0.340743 -0.00768901 0.100739 0.340743 -0.00768901 0.09815110000000001 0.331085 0.000320996 0.099867 0.340978 -0.015298 0.100722 0.330396 -0.00768901 0.09815110000000001 0.331085 -0.00768901 0.100739 0.340743 -0.00768901 0.09815110000000001 0.331085 -0.015298 0.100722 0.330396 -0.0158038 0.0837065 0.334 -0.015298 0.100722 0.330396 -0.0273484 0.0834934 0.334 -0.0158038 0.0837065 0.334 -0.00768901 0.09815110000000001 0.331085 0.000320996 0.0972787 0.331318 0.000320996 0.099867 0.340978 0.000320996 0.0972787 0.331318 -0.00768901 0.09815110000000001 0.331085 -0.0112252 0.0836884 0.334 -0.0112252 0.0836884 0.334 -0.00768901 0.09815110000000001 0.331085 -0.0158038 0.0837065 0.334 0.008331989999999999 0.100739 0.340743 0.036321 0.13464 0.331659 0.000320996 0.099867 0.340978 0.0227564 0.092987 0.332468 0.015941 0.100722 0.330396 0.00996817 0.0987039 0.330937 -0.061307 0.082135 0.295 -0.061307 0.0776017 0.305225 -0.061307 0.08136690000000001 0.3145 -0.015298 0.10331 0.340054 -0.00768901 0.100739 0.340743 0.036321 0.13464 0.331659 0.032756 0.149728 0.327617 0.028467 0.156321 0.32585 0.036321 0.13464 0.331659 -0.0349006 0.138722 0.320213 -0.0354429 0.135365 0.321113 -0.035679 0.132052 0.322 0.008331989999999999 0.098151 0.331085 0.00996817 0.0987039 0.330937 0.008331989999999999 0.100739 0.340743 -0.015298 0.100722 0.330396 -0.00768901 0.100739 0.340743 -0.015298 0.10331 0.340054 -0.0193024 0.162013 0.318218 -0.015298 0.162968 0.31206 -0.0180093 0.161737 0.314047 -0.0288005 0.152234 0.316593 -0.028417 0.152823 0.316436 -0.029125 0.152493 0.316524 0.036321 0.13464 0.331659 -0.015298 0.16597 0.323265 -0.022124 0.161827 0.324375 -0.0394457 0.0833752 0.334 -0.053765 0.100567 0.330437 -0.061307 0.087269 0.334 -0.035679 0.132052 0.322 -0.0356591 0.131881 0.322046 -0.035679 0.13464 0.331659 -0.0211817 0.104293 0.329439 -0.022124 0.104865 0.329286 -0.0268302 0.105148 0.32921 -0.0344086 0.1233 0.324346 -0.032114 0.119553 0.335702 -0.034776 0.126902 0.333733 0.022767 0.104865 0.329285 0.028467 0.112959 0.337469 0.022767 0.107453 0.338944 -0.00933056 0.164985 0.311519 -0.00735999 0.165287 0.311438 -8.407769999999999e-09 0.156733 0.275012 0.0364882 0.09650060000000001 0.331527 0.022767 0.104865 0.329285 0.0312341 0.09406730000000001 0.332179 0.034238 0.132706 0.28145 0.0293349 0.151681 0.315084 0.0334112 0.143953 0.317155 0.015941 0.16597 0.323265 0.022767 0.161827 0.324375 0.022767 0.158825 0.31317 -0.0346947 0.139601 0.318321 -0.034238 0.1428 0.319121 -0.034238 0.132706 0.28145 0.0165414 0.162045 0.312307 0.008711969999999999 0.16508 0.311493 0.008331989999999999 0.16554 0.31137 -0.027825 0.110371 0.32781 -0.0326396 0.114414 0.326727 -0.039617 0.112034 0.327365 0.035273 0.136073 0.319266 0.035735 0.133256 0.320021 0.036 0.12196 0.284329 0.048346 0.107226 0.328653 0.0416256 0.10219 0.330002 0.0525 0.08727 0.334 -0.011125 0.165125 0.313139 -0.0093303 0.1654 0.313065 -0.00933056 0.164985 0.311519 -0.022124 0.107453 0.338944 -0.022124 0.104865 0.329286 -0.0211817 0.104293 0.329439 0.0364882 0.09650060000000001 0.331527 0.0416256 0.10219 0.330002 0.022767 0.104865 0.329285 -0.029125 0.142399 0.278853 -0.0324765 0.145725 0.31668 -0.0319658 0.146693 0.316421 -0.061307 0.09904499999999999 0.330845 -0.061307 0.088951 0.293174 -0.061307 0.087269 0.334 -0.0109123 0.164865 0.313209 -0.011125 0.165125 0.313139 -0.0132797 0.164065 0.313423 -0.0324789 0.146133 0.318228 -0.0324765 0.146134 0.318206 -0.032114 0.146726 0.316412 -0.02116 0.150092 0.276791 -0.029125 0.142399 0.278853 -0.029125 0.152493 0.316524 0.036321 0.13464 0.331659 -0.034776 0.126902 0.333733 -0.032114 0.119553 0.335702 -0.053765 0.100567 0.330437 -0.061307 0.09904499999999999 0.330845 -0.061307 0.087269 0.334 0.0343103 0.141945 0.317693 0.035273 0.136073 0.319266 0.036 0.12196 0.284329 -0.022124 0.159239 0.314717 -0.0229109 0.158479 0.31492 -0.022124 0.161827 0.324375 -0.036 0.132054 0.322 -0.0354429 0.135365 0.321113 -0.0348859 0.138849 0.32018 0.015941 0.10331 0.340054 0.022767 0.107453 0.338944 0.036321 0.13464 0.331659 -0.015298 0.100722 0.330396 -0.045645 0.105096 0.329224 -0.0273484 0.0834934 0.334 -0.0346752 0.12216 0.324651 -0.03641 0.120545 0.325084 -0.0346752 0.120703 0.325042 -0.03641 0.120545 0.325084 -0.0329403 0.119246 0.325432 -0.0346752 0.120703 0.325042 -0.0329403 0.119246 0.325432 -0.0346752 0.12216 0.324651 -0.0346752 0.120703 0.325042 -0.0347601 0.139374 0.318381 -0.0346947 0.139601 0.318321 -0.034238 0.132706 0.28145 0.036 0.129298 0.322738 0.0359802 0.130006 0.326056 0.0355434 0.125382 0.323788 -0.045645 0.105096 0.329224 -0.015298 0.100722 0.330396 -0.0268302 0.105148 0.32921 -0.022124 0.104865 0.329286 -0.0256622 0.108282 0.32837 -0.0268302 0.105148 0.32921 -0.0337899 0.142513 0.319198 -0.0346947 0.140015 0.319867 -0.0340839 0.142905 0.323908 0.036 0.125074 0.32387 0.035419 0.124314 0.324074 0.037523 0.117681 0.325851 0.036 0.129298 0.322738 0.036321 0.131638 0.320454 0.0359802 0.130006 0.326056 -0.0150149 0.162796 0.312106 -0.0132796 0.16365 0.311877 -0.0140599 0.158708 0.294966 -0.027825 0.112959 0.337469 -0.032114 0.119553 0.335702 -0.0315221 0.116055 0.326287 0.036 0.13028 0.320818 0.036 0.123167 0.305034 0.036 0.12196 0.284329 0.032756 0.116965 0.326043 0.028467 0.110371 0.32781 0.0416256 0.10219 0.330002 -0.0268302 0.105148 0.32921 -0.0256622 0.108282 0.32837 -0.039617 0.112034 0.327365 0.029125 0.152079 0.314977 0.0334112 0.143953 0.317155 0.0293349 0.151681 0.315084 -0.0180093 0.161737 0.314047 -0.0209336 0.159962 0.314523 -0.0193024 0.162013 0.318218 0.000320995 0.166412 0.311137 0.000320995 0.169414 0.322342 0.008331989999999999 0.16554 0.31137 0.032756 0.116965 0.326043 0.0416256 0.10219 0.330002 0.037523 0.117681 0.325851 0.0227564 0.092987 0.332468 0.00996817 0.0987039 0.330937 0.008331989999999999 0.098151 0.331085 0.036 0.128884 0.321192 0.036 0.129298 0.322738 0.036 0.125074 0.32387 -0.0273484 0.0834934 0.334 -0.045645 0.105096 0.329224 -0.0394457 0.0833752 0.334 0.036321 0.13464 0.331659 0.022767 0.107453 0.338944 0.028467 0.112959 0.337469 -0.034238 0.132706 0.28145 -0.0348859 0.138434 0.318633 -0.0347601 0.139374 0.318381 -0.032114 0.116965 0.326043 -0.0315221 0.116055 0.326287 -0.032114 0.119553 0.335702 -0.036 0.132054 0.322 -0.034238 0.132706 0.28145 -0.036 0.12196 0.284329 0.037522 0.107587 0.28818 0.036 0.11498 0.286199 0.036 0.125074 0.32387 -0.0093303 0.1654 0.313065 -0.011125 0.165125 0.313139 -0.0109123 0.164865 0.313209 -0.0348051 0.124564 0.324008 -0.0355544 0.130984 0.322287 -0.036 0.125074 0.323871 0.015941 0.162968 0.31206 0.0165414 0.162045 0.312307 0.008331989999999999 0.16554 0.31137 0.032756 0.146726 0.316412 0.028467 0.156321 0.32585 0.032756 0.149728 0.327617 -0.0229109 0.158479 0.31492 -0.027825 0.156321 0.32585 -0.022124 0.161827 0.324375 -0.0209336 0.159962 0.314523 -0.02116 0.160186 0.314463 -0.022124 0.159239 0.314717 0.029125 0.142399 0.278853 0.029125 0.152079 0.314977 0.0293349 0.151681 0.315084 0.000456574 0.166343 0.311155 0.008711969999999999 0.16508 0.311493 0.011124 0.155032 0.275468 -0.0346947 0.139601 0.318321 -0.0346947 0.140015 0.319867 -0.034238 0.1428 0.319121 0.008331989999999999 0.168542 0.322575 0.015941 0.162968 0.31206 0.008331989999999999 0.16554 0.31137 -0.029125 0.142399 0.278853 -0.0319658 0.146693 0.316421 -0.0312391 0.148071 0.316052 0.0525 0.106054 0.328967 0.048346 0.107226 0.328653 0.0525 0.08727 0.334 -0.0180093 0.161737 0.314047 -0.015298 0.162968 0.31206 -0.0180094 0.161322 0.312501 -0.000807269 0.166289 0.31117 0.000320995 0.169414 0.322342 0.000320995 0.166412 0.311137 0.035419 0.126902 0.333733 0.032756 0.119553 0.335702 0.035419 0.124314 0.324074 0.0525 0.08727 0.334 0.0364882 0.09650060000000001 0.331527 0.0312341 0.09406730000000001 0.332179 0.0312341 0.09406730000000001 0.332179 0.0227564 0.092987 0.332468 0.0525 0.08727 0.334 0.0227564 0.092987 0.332468 0.0414966 0.084435 0.334 0.0525 0.08727 0.334 0.011392 0.08390549999999999 0.334 0.0414966 0.084435 0.334 0.0227564 0.092987 0.332468 0.0155442 0.091055 0.332676 0.011392 0.08390549999999999 0.334 0.0227564 0.092987 0.332468 0.0155442 0.091055 0.332676 0.008331989999999999 0.098151 0.331085 0.011392 0.08390549999999999 0.334 0.0155442 0.091055 0.332676 0.0227564 0.092987 0.332468 0.008331989999999999 0.098151 0.331085 0.008331989999999999 0.098151 0.331085 0.008331989999999999 0.100739 0.340743 0.000320996 0.0972787 0.331318 0.008331989999999999 0.098151 0.331085 0.000320996 0.0972787 0.331318 0.00106212 0.0839163 0.334 0.000320996 0.099867 0.340978 0.000320996 0.0972787 0.331318 0.008331989999999999 0.100739 0.340743 0.008331989999999999 0.098151 0.331085 0.00106212 0.0839163 0.334 0.011392 0.08390549999999999 0.334 0.00106212 0.0839163 0.334 0.000320996 0.0972787 0.331318 -0.0112252 0.0836884 0.334 -0.053765 0.090473 0.292766 -0.061307 0.082135 0.295 -0.061307 0.088951 0.293174 -0.061307 0.082135 0.295 -0.061307 0.07716339999999999 0.302779 -0.061307 0.0776017 0.305225 -0.061307 0.082135 0.295 -0.061307 0.0754647 0.295 -0.061307 0.07716339999999999 0.302779 -0.0599749 0.0754633 0.295 -0.0601191 0.0754635 0.295 -0.061307 0.082135 0.295 -0.0601191 0.0754635 0.295 -0.061307 0.0754647 0.295 -0.061307 0.082135 0.295 -0.058339 0.0790632 0.295 -0.0599749 0.0754633 0.295 -0.061307 0.082135 0.295 -0.058339 0.0790632 0.295 -0.061307 0.082135 0.295 -0.0582582 0.0792273 0.295 -0.0582582 0.0792273 0.295 -0.061307 0.082135 0.295 -0.0568258 0.082135 0.295 -0.055224 0.08516899999999999 0.294187 -0.0568258 0.082135 0.295 -0.061307 0.082135 0.295 -0.055224 0.08516899999999999 0.294187 -0.061307 0.082135 0.295 -0.053765 0.090473 0.292766 -0.039209 0.099082 0.290459 -0.039617 0.10194 0.289694 -0.035427 0.106378 0.288504 -0.039209 0.099082 0.290459 -0.045645 0.095002 0.291553 -0.039617 0.10194 0.289694 -0.045645 0.095002 0.291553 -0.050447 0.089919 0.292914 -0.053765 0.090473 0.292766 -0.039209 0.099082 0.290459 -0.04514 0.09327100000000001 0.292016 -0.045645 0.095002 0.291553 -0.045645 0.095002 0.291553 -0.047857 0.091569 0.292472 -0.050447 0.089919 0.292914 -0.0589446 0.07546219999999999 0.295 -0.0599749 0.0754633 0.295 -0.058339 0.0790632 0.295 -0.04514 0.09327100000000001 0.292016 -0.047857 0.091569 0.292472 -0.045645 0.095002 0.291553 -0.035427 0.106378 0.288504 -0.039617 0.10194 0.289694 -0.03641 0.110452 0.287413 -0.050447 0.089919 0.292914 -0.055224 0.08516899999999999 0.294187 -0.053765 0.090473 0.292766 -0.032312 0.13418 0.281054 -0.034238 0.132706 0.28145 -0.029125 0.142399 0.278853 -0.02814 0.141635 0.279057 -0.032312 0.13418 0.281054 -0.029125 0.142399 0.278853 -0.034165 0.114446 0.286342 -0.03641 0.110452 0.287413 -0.036 0.11498 0.2862 -0.034433 0.125957 0.283258 -0.036 0.12196 0.284329 -0.034238 0.132706 0.28145 -0.032312 0.13418 0.281054 -0.034433 0.125957 0.283258 -0.034238 0.132706 0.28145 -0.034388 0.117613 0.285493 -0.036 0.12196 0.284329 -0.034433 0.125957 0.283258 -0.034388 0.117613 0.285493 -0.036 0.11498 0.2862 -0.036 0.12196 0.284329 -0.034165 0.114446 0.286342 -0.036 0.11498 0.2862 -0.034388 0.117613 0.285493 -8.407769999999999e-09 0.156733 0.275012 0.00227099 0.155713 0.275285 -0.00648101 0.155121 0.275443 -0.0201217 0.149134 0.277048 -0.022179 0.147853 0.277391 -0.02116 0.150092 0.276791 -0.014805 0.152445 0.27616 -0.0201217 0.149134 0.277048 -0.02116 0.150092 0.276791 -0.022179 0.147853 0.277391 -0.029125 0.142399 0.278853 -0.02116 0.150092 0.276791 -0.011125 0.155032 0.275468 -0.00648101 0.155121 0.275443 -0.014805 0.152445 0.27616 -0.022179 0.147853 0.277391 -0.02814 0.141635 0.279057 -0.029125 0.142399 0.278853 -0.035427 0.106378 0.288504 -0.03641 0.110452 0.287413 -0.034165 0.114446 0.286342 -0.014805 0.152445 0.27616 -0.02116 0.150092 0.276791 -0.011125 0.155032 0.275468 -8.407769999999999e-09 0.156733 0.275012 -0.00648101 0.155121 0.275443 -0.011125 0.155032 0.275468 0.0525 0.082135 0.295 0.0525 0.0813359 0.3145 0.0525 0.0759871 0.297262 0.0525 0.08727 0.334 0.0525 0.0813359 0.3145 0.0525 0.082135 0.295 0.037522 0.107587 0.28818 0.031111 0.105882 0.288637 0.034283 0.113783 0.28652 0.0223278 0.09600980000000001 0.291282 0.0525 0.082135 0.295 0.0200627 0.0941734 0.291775 0.0525 0.082135 0.295 0.026005 0.098991 0.290483 0.0293444 0.103498 0.289276 0.026005 0.098991 0.290483 0.0525 0.082135 0.295 0.0223278 0.09600980000000001 0.291282 0.0192849 0.0935428 0.291944 0.0200627 0.0941734 0.291775 0.0525 0.082135 0.295 0.037522 0.107587 0.28818 0.0293444 0.103498 0.289276 0.031111 0.105882 0.288637 0.0109 0.154184 0.275694 0.00227099 0.155713 0.275285 -8.407769999999999e-09 0.156733 0.275012 0.011124 0.155032 0.275468 0.0109 0.154184 0.275694 -8.407769999999999e-09 0.156733 0.275012 0.018865 0.15063 0.276646 0.0109 0.154184 0.275694 0.011124 0.155032 0.275468 0.029125 0.142399 0.278853 0.025664 0.145275 0.278081 0.02116 0.150092 0.276791 0.030872 0.138455 0.27991 0.025664 0.145275 0.278081 0.029125 0.142399 0.278853 0.034238 0.132706 0.28145 0.030872 0.138455 0.27991 0.029125 0.142399 0.278853 0.03532 0.122198 0.284265 0.034159 0.130598 0.282014 0.034238 0.132706 0.28145 0.034159 0.130598 0.282014 0.030872 0.138455 0.27991 0.034238 0.132706 0.28145 0.036 0.12196 0.284329 0.03532 0.122198 0.284265 0.034238 0.132706 0.28145 0.036 0.11498 0.286199 0.034283 0.113783 0.28652 0.03532 0.122198 0.284265 0.036 0.12196 0.284329 0.036 0.11498 0.286199 0.03532 0.122198 0.284265 0.041858 0.10132 0.28986 0.0525 0.082135 0.295 0.0293444 0.103498 0.289276 0.041858 0.10132 0.28986 0.0356012 0.104453 0.28902 0.037522 0.107587 0.28818 0.0356012 0.104453 0.28902 0.041858 0.10132 0.28986 0.0293444 0.103498 0.289276 0.0525 0.09596 0.291296 0.0525 0.082135 0.295 0.048346 0.097133 0.290982 0.048346 0.097133 0.290982 0.0525 0.082135 0.295 0.041858 0.10132 0.28986 0.036 0.11498 0.286199 0.037522 0.107587 0.28818 0.034283 0.113783 0.28652 0.0525 0.082135 0.295 0.00725699 0.088821 0.293208 0.011373 0.08988 0.292924 0.00725699 0.088821 0.293208 0.0525 0.082135 0.295 -0.00949171 0.0778746 0.295 0.0525 0.082135 0.295 0.0414112 0.076998 0.295 0.0288275 0.0767767 0.295 0.0525 0.082135 0.295 0.0288275 0.0767767 0.295 -0.00949171 0.0778746 0.295 0.0476527 0.07513789999999999 0.295 0.0414112 0.076998 0.295 0.0525 0.082135 0.295 0.049063 0.07511370000000001 0.295 0.0476527 0.07513789999999999 0.295 0.0525 0.082135 0.295 0.0513403 0.0750745 0.295 0.049063 0.07511370000000001 0.295 0.0525 0.082135 0.295 0.0525 0.0754018 0.295 0.0513403 0.0750745 0.295 0.0525 0.082135 0.295 0.0525 0.082135 0.295 0.0525 0.075751 0.296349 0.0525 0.0754018 0.295 0.036 0.12196 0.284329 0.036 0.123167 0.305034 0.036 0.11498 0.286199 0.02116 0.150092 0.276791 0.025664 0.145275 0.278081 0.018865 0.15063 0.276646 0.0525 0.082135 0.295 0.0525 0.0759871 0.297262 0.0525 0.075751 0.296349 0.037522 0.107587 0.28818 0.0356012 0.104453 0.28902 0.0293444 0.103498 0.289276 0.0192849 0.0935428 0.291944 0.0525 0.082135 0.295 0.011373 0.08988 0.292924 0.02116 0.150092 0.276791 0.018865 0.15063 0.276646 0.011124 0.155032 0.275468 -0.00949171 0.0778746 0.295 0.000508551 0.0862144 0.293907 0.00725699 0.088821 0.293208 -0.010356 0.0760875 0.295 -0.00949171 0.0778746 0.295 0.0288275 0.0767767 0.295 -0.061307 0.08136690000000001 0.3145 -0.061307 0.0788237 0.31082 -0.061307 0.0793295 0.31372 -0.061307 0.0776017 0.305225 -0.061307 0.0788237 0.31082 -0.061307 0.08136690000000001 0.3145 -0.061307 0.087269 0.334 -0.061307 0.0828207 0.332976 -0.061307 0.0830142 0.334 -0.061307 0.0830142 0.334 -0.0585424 0.0830288 0.334 -0.061307 0.087269 0.334 -0.061307 0.087269 0.334 -0.061307 0.081329 0.324301 -0.061307 0.08261880000000001 0.331907 -0.061307 0.087269 0.334 -0.061307 0.08261880000000001 0.331907 -0.061307 0.0828207 0.332976 -0.0582031 0.0830306 0.334 -0.0394457 0.0833752 0.334 -0.061307 0.087269 0.334 -0.0585424 0.0830288 0.334 -0.0582031 0.0830306 0.334 -0.061307 0.087269 0.334 -0.061307 0.08136690000000001 0.3145 -0.061307 0.0793295 0.31372 -0.061307 0.081329 0.324301 -0.061307 0.08136690000000001 0.3145 -0.061307 0.081329 0.324301 -0.061307 0.087269 0.334 0.0525 0.082581 0.334 0.0525 0.08727 0.334 0.0457278 0.0835847 0.334 0.0525 0.08727 0.334 0.0414966 0.084435 0.334 0.0457278 0.0835847 0.334 0.0525 0.08727 0.334 0.0525 0.08237899999999999 0.332874 0.0525 0.0813359 0.3145 0.0525 0.08727 0.334 0.0525 0.082581 0.334 0.0525 0.08237899999999999 0.332874 0.0525 0.0813359 0.3145 0.0525 0.08237899999999999 0.332874 0.0525 0.0759871 0.297262 -0.036 -0.11498 0.2862 -0.036 -0.12196 0.284329 -0.036 -0.125074 0.323871 -0.036 -0.11498 0.2862 -0.036 -0.125074 0.323871 -0.03641 -0.120545 0.325084 -0.02116 -0.160186 0.314463 -0.029125 -0.152493 0.316524 -0.02116 -0.150092 0.276791 -0.029125 -0.142399 0.278853 -0.02116 -0.150092 0.276791 -0.029125 -0.152493 0.316524 -0.061307 -0.087269 0.334 -0.061307 -0.088951 0.293174 -0.061307 -0.09904499999999999 0.330845 -0.053765 -0.090473 0.292766 -0.061307 -0.09904499999999999 0.330845 -0.061307 -0.088951 0.293174 -0.061307 -0.09904499999999999 0.330845 -0.053765 -0.090473 0.292766 -0.053765 -0.100567 0.330437 -0.061307 -0.082135 0.295 -0.061307 -0.088951 0.293174 -0.061307 -0.087269 0.334 -0.061307 -0.0776017 0.305225 -0.061307 -0.07716339999999999 0.302779 -0.061307 -0.082135 0.295 -0.061307 -0.08136690000000001 0.3145 -0.061307 -0.0776017 0.305225 -0.061307 -0.082135 0.295 -0.061307 -0.087269 0.334 -0.061307 -0.08136690000000001 0.3145 -0.061307 -0.082135 0.295 -0.061307 -0.0754647 0.295 -0.061307 -0.082135 0.295 -0.061307 -0.07716339999999999 0.302779 -0.061307 -0.082135 0.295 -0.061307 -0.0754647 0.295 -0.0601191 -0.0754635 0.295 -0.058339 -0.0790632 0.295 -0.061307 -0.082135 0.295 -0.0599749 -0.0754633 0.295 -0.0582582 -0.0792273 0.295 -0.061307 -0.082135 0.295 -0.058339 -0.0790632 0.295 0.034238 -0.132706 0.28145 0.036 -0.12196 0.284329 0.0343103 -0.141945 0.317693 0.034238 -0.132706 0.28145 0.0343103 -0.141945 0.317693 0.034238 -0.142386 0.317575 -0.0324765 -0.145725 0.31668 -0.0324765 -0.146134 0.318206 -0.034238 -0.1428 0.319121 -0.029125 -0.142399 0.278853 -0.0324765 -0.145725 0.31668 -0.034238 -0.1428 0.319121 0.032756 -0.119553 0.335702 0.035419 -0.124314 0.324074 0.032756 -0.116965 0.326043 0.037523 -0.117681 0.325851 0.032756 -0.116965 0.326043 0.035419 -0.124314 0.324074 0.037523 -0.117681 0.325851 0.035419 -0.124314 0.324074 0.036 -0.125074 0.32387 0.037523 -0.117681 0.325851 0.036 -0.125074 0.32387 0.037522 -0.107587 0.28818 0.036 -0.129298 0.322738 0.0355434 -0.125382 0.323788 0.0359802 -0.130006 0.326056 0.036321 -0.131638 0.320454 0.036 -0.129298 0.322738 0.0359802 -0.130006 0.326056 0.0355434 -0.125382 0.323788 0.036 -0.129298 0.322738 0.036 -0.125074 0.32387 0.036 -0.128884 0.321192 0.036 -0.129298 0.322738 0.036321 -0.131638 0.320454 0.036 -0.125074 0.32387 0.036 -0.129298 0.322738 0.036 -0.128884 0.321192 0.036 -0.125074 0.32387 0.036 -0.123167 0.305034 0.036 -0.11498 0.286199 0.036 -0.125074 0.32387 0.036 -0.128884 0.321192 0.036 -0.123167 0.305034 0.036 -0.125074 0.32387 0.036 -0.11498 0.286199 0.037522 -0.107587 0.28818 0.036 -0.128884 0.321192 0.036 -0.13028 0.320818 0.036 -0.123167 0.305034 0.035419 -0.124314 0.324074 0.0355434 -0.125382 0.323788 0.036 -0.125074 0.32387 0.037522 -0.107587 0.28818 0.041858 -0.10132 0.28986 0.037523 -0.117681 0.325851 0.0416256 -0.10219 0.330002 0.032756 -0.116965 0.326043 0.037523 -0.117681 0.325851 0.041858 -0.111414 0.327531 0.0416256 -0.10219 0.330002 0.037523 -0.117681 0.325851 0.036 -0.13028 0.320818 0.036 -0.12196 0.284329 0.036 -0.123167 0.305034 -0.0324789 -0.146133 0.318228 -0.0333572 -0.144326 0.318712 -0.034238 -0.1428 0.319121 -0.0337899 -0.142513 0.319198 -0.0333572 -0.144326 0.318712 -0.0324789 -0.146133 0.318228 -0.0337899 -0.142513 0.319198 -0.0324789 -0.146133 0.318228 -0.0340839 -0.142905 0.323908 -0.0337899 -0.142513 0.319198 -0.034238 -0.1428 0.319121 -0.0333572 -0.144326 0.318712 -0.0329403 -0.119246 0.325432 -0.0346752 -0.12216 0.324651 -0.0344086 -0.1233 0.324346 -0.0344086 -0.1233 0.324346 -0.0346752 -0.12216 0.324651 -0.036 -0.125074 0.323871 -0.0346752 -0.12216 0.324651 -0.03641 -0.120545 0.325084 -0.036 -0.125074 0.323871 -0.034776 -0.124314 0.324075 -0.0344086 -0.1233 0.324346 -0.036 -0.125074 0.323871 -0.0355544 -0.130984 0.322287 -0.036 -0.125074 0.323871 -0.036 -0.132054 0.322 -0.0348051 -0.124564 0.324008 -0.036 -0.125074 0.323871 -0.0355544 -0.130984 0.322287 -0.0348051 -0.124564 0.324008 -0.034776 -0.124314 0.324075 -0.036 -0.125074 0.323871 -0.0346752 -0.12216 0.324651 -0.0329403 -0.119246 0.325432 -0.0346752 -0.120703 0.325042 -0.0329403 -0.119246 0.325432 -0.03641 -0.120545 0.325084 -0.0346752 -0.120703 0.325042 -0.03641 -0.120545 0.325084 -0.0346752 -0.12216 0.324651 -0.0346752 -0.120703 0.325042 -0.032114 -0.116965 0.326043 -0.0326396 -0.114414 0.326727 -0.03641 -0.120545 0.325084 -0.0329403 -0.119246 0.325432 -0.032114 -0.116965 0.326043 -0.03641 -0.120545 0.325084 -0.0329403 -0.119246 0.325432 -0.0344086 -0.1233 0.324346 -0.0328688 -0.120265 0.330024 -0.035679 -0.132052 0.322 -0.0354429 -0.135365 0.321113 -0.0349006 -0.138722 0.320213 -0.035679 -0.132052 0.322 -0.036 -0.132054 0.322 -0.0354429 -0.135365 0.321113 -0.0349006 -0.138722 0.320213 -0.0354429 -0.135365 0.321113 -0.0348859 -0.138849 0.32018 -0.0355544 -0.130984 0.322287 -0.0356591 -0.131881 0.322046 -0.035679 -0.13464 0.331659 -0.0355544 -0.130984 0.322287 -0.035679 -0.13464 0.331659 -0.034776 -0.126902 0.333733 0.036321 -0.13464 0.331659 -0.034776 -0.126902 0.333733 -0.035679 -0.13464 0.331659 -0.0348859 -0.138849 0.32018 -0.0347601 -0.139374 0.318381 -0.034776 -0.142378 0.329586 -0.0349006 -0.138722 0.320213 -0.0348859 -0.138849 0.32018 -0.034776 -0.142378 0.329586 -0.0349006 -0.138722 0.320213 -0.034776 -0.142378 0.329586 -0.035679 -0.13464 0.331659 0.036321 -0.13464 0.331659 -0.035679 -0.13464 0.331659 -0.034776 -0.142378 0.329586 -0.0324789 -0.146133 0.318228 -0.032114 -0.146726 0.316412 -0.032114 -0.149728 0.327617 -0.0324789 -0.146133 0.318228 -0.032114 -0.149728 0.327617 -0.034776 -0.142378 0.329586 0.036321 -0.13464 0.331659 -0.034776 -0.142378 0.329586 -0.032114 -0.149728 0.327617 -0.032114 -0.146726 0.316412 -0.0309085 -0.150165 0.321834 -0.032114 -0.149728 0.327617 -0.032114 -0.146726 0.316412 -0.0312392 -0.148485 0.317598 -0.0309085 -0.150165 0.321834 -0.0312391 -0.148071 0.316052 -0.0312392 -0.148485 0.317598 -0.032114 -0.146726 0.316412 -0.0312391 -0.148071 0.316052 -0.029125 -0.152493 0.316524 -0.0312392 -0.148485 0.317598 -0.029125 -0.142399 0.278853 -0.029125 -0.152493 0.316524 -0.0312391 -0.148071 0.316052 -0.029125 -0.142399 0.278853 -0.0312391 -0.148071 0.316052 -0.0319658 -0.146693 0.316421 -0.0312392 -0.148485 0.317598 -0.0288005 -0.152234 0.316593 -0.0309085 -0.150165 0.321834 -0.0288005 -0.152234 0.316593 -0.0312392 -0.148485 0.317598 -0.029125 -0.152493 0.316524 -0.0229109 -0.158479 0.31492 -0.029125 -0.152493 0.316524 -0.027825 -0.153733 0.316192 -0.022124 -0.159239 0.314717 -0.029125 -0.152493 0.316524 -0.0229109 -0.158479 0.31492 -0.028417 -0.152823 0.316436 -0.029125 -0.152493 0.316524 -0.027825 -0.153733 0.316192 -0.028417 -0.152823 0.316436 -0.027825 -0.153733 0.316192 -0.027825 -0.156321 0.32585 -0.0229109 -0.158479 0.31492 -0.022124 -0.159239 0.314717 -0.022124 -0.161827 0.324375 -0.0229109 -0.158479 0.31492 -0.022124 -0.161827 0.324375 -0.027825 -0.156321 0.32585 -0.028417 -0.152823 0.316436 -0.0288005 -0.152234 0.316593 -0.029125 -0.152493 0.316524 -0.034776 -0.126902 0.333733 -0.032114 -0.119553 0.335702 -0.0344086 -0.1233 0.324346 -0.032114 -0.119553 0.335702 -0.0328688 -0.120265 0.330024 -0.0344086 -0.1233 0.324346 0.036321 -0.13464 0.331659 -0.032114 -0.119553 0.335702 -0.034776 -0.126902 0.333733 -0.0319658 -0.146693 0.316421 -0.0312391 -0.148071 0.316052 -0.032114 -0.146726 0.316412 -0.0319658 -0.146693 0.316421 -0.032114 -0.146726 0.316412 -0.0324765 -0.145725 0.31668 -0.035679 -0.132052 0.322 -0.0349006 -0.138722 0.320213 -0.035679 -0.13464 0.331659 0.036321 -0.13464 0.331659 -0.027825 -0.112959 0.337469 -0.032114 -0.119553 0.335702 -0.032114 -0.119553 0.335702 -0.027825 -0.112959 0.337469 -0.0315221 -0.116055 0.326287 -0.027825 -0.112959 0.337469 -0.027825 -0.110371 0.32781 -0.0315221 -0.116055 0.326287 -0.0270382 -0.109611 0.328014 -0.027825 -0.110371 0.32781 -0.027825 -0.112959 0.337469 -0.027825 -0.110371 0.32781 -0.0270382 -0.109611 0.328014 -0.039617 -0.112034 0.327365 -0.0270382 -0.109611 0.328014 -0.0256622 -0.108282 0.32837 -0.039617 -0.112034 0.327365 -0.0256622 -0.108282 0.32837 -0.0270382 -0.109611 0.328014 -0.0239346 -0.107863 0.333479 -0.0326396 -0.114414 0.326727 -0.027825 -0.110371 0.32781 -0.039617 -0.112034 0.327365 -0.0348859 -0.138849 0.32018 -0.0354429 -0.135365 0.321113 -0.036 -0.132054 0.322 -0.061307 -0.087269 0.334 -0.053765 -0.100567 0.330437 -0.0394457 -0.0833752 0.334 -0.039617 -0.10194 0.289694 -0.03641 -0.110452 0.287413 -0.039617 -0.112034 0.327365 -0.03641 -0.120545 0.325084 -0.039617 -0.112034 0.327365 -0.03641 -0.110452 0.287413 -0.039617 -0.10194 0.289694 -0.039617 -0.112034 0.327365 -0.045645 -0.105096 0.329224 -0.045645 -0.095002 0.291553 -0.039617 -0.10194 0.289694 -0.045645 -0.105096 0.329224 -0.03641 -0.110452 0.287413 -0.036 -0.11498 0.2862 -0.03641 -0.120545 0.325084 -0.0268302 -0.105148 0.32921 -0.045645 -0.105096 0.329224 -0.039617 -0.112034 0.327365 -0.022124 -0.107453 0.338944 -0.0211817 -0.104293 0.329439 -0.022124 -0.104865 0.329286 -0.0211817 -0.104293 0.329439 -0.022124 -0.107453 0.338944 -0.015298 -0.10331 0.340054 0.015941 -0.10331 0.340054 0.015941 -0.100722 0.330396 0.00996817 -0.0987039 0.330937 0.008331989999999999 -0.100739 0.340743 0.015941 -0.10331 0.340054 0.00996817 -0.0987039 0.330937 0.00996817 -0.0987039 0.330937 0.015941 -0.100722 0.330396 0.0227564 -0.092987 0.332468 0.0312341 -0.09406730000000001 0.332179 0.0227564 -0.092987 0.332468 0.015941 -0.100722 0.330396 0.036321 -0.13464 0.331659 -0.015298 -0.10331 0.340054 -0.022124 -0.107453 0.338944 -0.00768901 -0.100739 0.340743 0.000320996 -0.099867 0.340978 -0.00768901 -0.09815110000000001 0.331085 -0.00768901 -0.09815110000000001 0.331085 -0.015298 -0.100722 0.330396 -0.00768901 -0.100739 0.340743 -0.00768901 -0.09815110000000001 0.331085 0.000320996 -0.099867 0.340978 0.000320996 -0.0972787 0.331318 0.00106212 -0.0839163 0.334 -0.0112252 -0.0836884 0.334 0.000320996 -0.0972787 0.331318 0.000320996 -0.0972787 0.331318 -0.0112252 -0.0836884 0.334 -0.00768901 -0.09815110000000001 0.331085 -0.0112252 -0.0836884 0.334 -0.0158038 -0.0837065 0.334 -0.00768901 -0.09815110000000001 0.331085 0.011392 -0.08390549999999999 0.334 0.00106212 -0.0839163 0.334 0.008331989999999999 -0.098151 0.331085 0.0155442 -0.091055 0.332676 0.008331989999999999 -0.098151 0.331085 0.0227564 -0.092987 0.332468 0.0155442 -0.091055 0.332676 0.011392 -0.08390549999999999 0.334 0.008331989999999999 -0.098151 0.331085 0.0155442 -0.091055 0.332676 0.0227564 -0.092987 0.332468 0.011392 -0.08390549999999999 0.334 0.0525 -0.08727 0.334 0.0227564 -0.092987 0.332468 0.0312341 -0.09406730000000001 0.332179 0.0525 -0.08727 0.334 0.0414966 -0.084435 0.334 0.0227564 -0.092987 0.332468 0.011392 -0.08390549999999999 0.334 0.0227564 -0.092987 0.332468 0.0414966 -0.084435 0.334 0.00106212 -0.0839163 0.334 0.000320996 -0.0972787 0.331318 0.008331989999999999 -0.098151 0.331085 0.008331989999999999 -0.100739 0.340743 0.008331989999999999 -0.098151 0.331085 0.000320996 -0.0972787 0.331318 -0.015298 -0.100722 0.330396 -0.0273484 -0.0834934 0.334 -0.045645 -0.105096 0.329224 -0.0158038 -0.0837065 0.334 -0.0273484 -0.0834934 0.334 -0.015298 -0.100722 0.330396 -0.0268302 -0.105148 0.32921 -0.015298 -0.100722 0.330396 -0.045645 -0.105096 0.329224 -0.0211817 -0.104293 0.329439 -0.015298 -0.100722 0.330396 -0.0268302 -0.105148 0.32921 -0.015298 -0.10331 0.340054 -0.015298 -0.100722 0.330396 -0.0211817 -0.104293 0.329439 -0.0347601 -0.139374 0.318381 -0.0346947 -0.139601 0.318321 -0.0346947 -0.140015 0.319867 -0.0346947 -0.139601 0.318321 -0.034238 -0.1428 0.319121 -0.0346947 -0.140015 0.319867 -0.0337899 -0.142513 0.319198 -0.0346947 -0.140015 0.319867 -0.034238 -0.1428 0.319121 -0.0346947 -0.139601 0.318321 -0.0347601 -0.139374 0.318381 -0.034238 -0.132706 0.28145 -0.036 -0.12196 0.284329 -0.034238 -0.132706 0.28145 -0.036 -0.132054 0.322 -0.034238 -0.132706 0.28145 -0.0348859 -0.138434 0.318633 -0.036 -0.132054 0.322 -0.0347601 -0.139374 0.318381 -0.0348859 -0.138434 0.318633 -0.034238 -0.132706 0.28145 -0.0348859 -0.138434 0.318633 -0.0347601 -0.139374 0.318381 -0.0348859 -0.1388 0.319997 -0.0348859 -0.138434 0.318633 -0.0348859 -0.1388 0.319997 -0.036 -0.132054 0.322 -0.0348859 -0.1388 0.319997 -0.0348859 -0.138849 0.32018 -0.036 -0.132054 0.322 -0.034238 -0.1428 0.319121 -0.034238 -0.132706 0.28145 -0.029125 -0.142399 0.278853 -0.039209 -0.099082 0.290459 -0.039617 -0.10194 0.289694 -0.045645 -0.095002 0.291553 -0.0288005 -0.152234 0.316593 -0.028417 -0.152823 0.316436 -0.0309085 -0.150165 0.321834 -0.034238 -0.132706 0.28145 -0.034238 -0.1428 0.319121 -0.0346947 -0.139601 0.318321 0.022767 -0.107453 0.338944 0.015941 -0.100722 0.330396 0.015941 -0.10331 0.340054 0.022767 -0.107453 0.338944 0.022767 -0.104865 0.329285 0.015941 -0.100722 0.330396 0.022767 -0.104865 0.329285 0.022767 -0.107453 0.338944 0.028467 -0.112959 0.337469 0.028467 -0.112959 0.337469 0.032756 -0.119553 0.335702 0.028467 -0.110371 0.32781 0.022767 -0.104865 0.329285 0.028467 -0.112959 0.337469 0.028467 -0.110371 0.32781 0.0355434 -0.125382 0.323788 0.035419 -0.126902 0.333733 0.036321 -0.13464 0.331659 0.036 -0.12196 0.284329 0.035735 -0.133256 0.320021 0.035273 -0.136073 0.319266 0.036 -0.12196 0.284329 0.036 -0.13028 0.320818 0.035735 -0.133256 0.320021 0.036321 -0.131638 0.320454 0.035735 -0.133256 0.320021 0.036 -0.13028 0.320818 0.035273 -0.136073 0.319266 0.035735 -0.133256 0.320021 0.036321 -0.131638 0.320454 0.022767 -0.158825 0.31317 0.02116 -0.159772 0.312916 0.0214868 -0.159456 0.313001 0.015941 -0.162968 0.31206 0.02116 -0.159772 0.312916 0.022767 -0.158825 0.31317 0.0214868 -0.159456 0.313001 0.02116 -0.159772 0.312916 0.02116 -0.150092 0.276791 0.02116 -0.150092 0.276791 0.02116 -0.159772 0.312916 0.0165414 -0.162045 0.312307 0.015941 -0.16597 0.323265 0.015941 -0.162968 0.31206 0.022767 -0.158825 0.31317 0.015941 -0.16597 0.323265 0.008331989999999999 -0.168542 0.322575 0.015941 -0.162968 0.31206 0.008331989999999999 -0.16554 0.31137 0.0165414 -0.162045 0.312307 0.015941 -0.162968 0.31206 0.008331989999999999 -0.16554 0.31137 0.015941 -0.162968 0.31206 0.008331989999999999 -0.168542 0.322575 0.000320995 -0.169414 0.322342 0.008331989999999999 -0.16554 0.31137 0.008331989999999999 -0.168542 0.322575 0.000320995 -0.166412 0.311137 0.008331989999999999 -0.16554 0.31137 0.000320995 -0.169414 0.322342 0.008331989999999999 -0.16554 0.31137 0.008711969999999999 -0.16508 0.311493 0.0165414 -0.162045 0.312307 0.000456574 -0.166343 0.311155 0.011124 -0.155032 0.275468 0.008711969999999999 -0.16508 0.311493 0.008711969999999999 -0.16508 0.311493 0.008331989999999999 -0.16554 0.31137 0.000456574 -0.166343 0.311155 0.008711969999999999 -0.16508 0.311493 0.011124 -0.155032 0.275468 0.02116 -0.150092 0.276791 0.008331989999999999 -0.16554 0.31137 0.000320995 -0.166412 0.311137 0.000456574 -0.166343 0.311155 -8.407769999999999e-09 -0.156733 0.275012 0.011124 -0.155032 0.275468 0.000456574 -0.166343 0.311155 -0.000807269 -0.166289 0.31117 0.000320995 -0.166412 0.311137 0.000320995 -0.169414 0.322342 0.000456574 -0.166343 0.311155 -0.000807269 -0.166289 0.31117 0.000320995 -0.166412 0.311137 -0.000807269 -0.166289 0.31117 0.000320995 -0.169414 0.322342 -0.00768901 -0.168542 0.322575 -8.407769999999999e-09 -0.156733 0.275012 -0.011125 -0.165125 0.313139 -0.011125 -0.155032 0.275468 -0.011125 -0.165125 0.313139 -8.407769999999999e-09 -0.156733 0.275012 -0.00933056 -0.164985 0.311519 -0.011125 -0.165125 0.313139 -0.0132796 -0.16365 0.311877 -0.0140599 -0.158708 0.294966 -0.011125 -0.165125 0.313139 -0.0140599 -0.158708 0.294966 -0.011125 -0.155032 0.275468 -0.0132797 -0.164065 0.313423 -0.0132796 -0.16365 0.311877 -0.011125 -0.165125 0.313139 -0.011125 -0.165125 0.313139 -0.0109123 -0.164865 0.313209 -0.0132797 -0.164065 0.313423 -0.0132797 -0.164065 0.313423 -0.015298 -0.162968 0.31206 -0.0132796 -0.16365 0.311877 -0.015298 -0.162968 0.31206 -0.0119742 -0.165581 0.317317 -0.015298 -0.16597 0.323265 -0.0119742 -0.165581 0.317317 -0.015298 -0.162968 0.31206 -0.0132797 -0.164065 0.313423 -0.0150149 -0.162796 0.312106 -0.0132796 -0.16365 0.311877 -0.015298 -0.162968 0.31206 -0.0180093 -0.161737 0.314047 -0.0209336 -0.159962 0.314523 -0.02116 -0.160186 0.314463 -0.0193024 -0.162013 0.318218 -0.0209336 -0.159962 0.314523 -0.0180093 -0.161737 0.314047 -0.0150149 -0.162796 0.312106 -0.015298 -0.162968 0.31206 -0.0180094 -0.161322 0.312501 -0.0150149 -0.162796 0.312106 -0.0180094 -0.161322 0.312501 -0.0140599 -0.158708 0.294966 -0.0180093 -0.161737 0.314047 -0.0180094 -0.161322 0.312501 -0.015298 -0.162968 0.31206 -0.0193024 -0.162013 0.318218 -0.0180093 -0.161737 0.314047 -0.015298 -0.162968 0.31206 -0.0180094 -0.161322 0.312501 -0.02116 -0.160186 0.314463 -0.0140599 -0.158708 0.294966 -0.00933056 -0.164985 0.311519 -8.407769999999999e-09 -0.156733 0.275012 -0.00735999 -0.165287 0.311438 -8.407769999999999e-09 -0.156733 0.275012 -0.000807269 -0.166289 0.31117 -0.00735999 -0.165287 0.311438 -0.00735999 -0.165287 0.311438 -0.000807269 -0.166289 0.31117 -0.00768901 -0.16554 0.31137 -0.000807269 -0.166289 0.31117 -0.00768901 -0.168542 0.322575 -0.00768901 -0.16554 0.31137 -0.00768901 -0.16554 0.31137 -0.00768901 -0.168542 0.322575 -0.015298 -0.16597 0.323265 0.0343103 -0.141945 0.317693 0.035273 -0.136073 0.319266 0.035419 -0.139376 0.318381 0.034238 -0.142386 0.317575 0.0343103 -0.141945 0.317693 0.035419 -0.139376 0.318381 0.035419 -0.139376 0.318381 0.035273 -0.136073 0.319266 0.036321 -0.131638 0.320454 0.032756 -0.146726 0.316412 0.034238 -0.142386 0.317575 0.035419 -0.139376 0.318381 0.0334112 -0.143953 0.317155 0.034238 -0.142386 0.317575 0.032756 -0.146726 0.316412 0.032756 -0.146726 0.316412 0.029125 -0.152079 0.314977 0.0334112 -0.143953 0.317155 0.034238 -0.142386 0.317575 0.0334112 -0.143953 0.317155 0.034238 -0.132706 0.28145 0.0334112 -0.143953 0.317155 0.0293349 -0.151681 0.315084 0.034238 -0.132706 0.28145 0.029125 -0.142399 0.278853 0.034238 -0.132706 0.28145 0.0293349 -0.151681 0.315084 0.0293349 -0.151681 0.315084 0.029125 -0.152079 0.314977 0.0334112 -0.143953 0.317155 -0.000807269 -0.166289 0.31117 -8.407769999999999e-09 -0.156733 0.275012 0.000456574 -0.166343 0.311155 0.0165414 -0.162045 0.312307 0.008711969999999999 -0.16508 0.311493 0.02116 -0.150092 0.276791 -0.0180093 -0.161737 0.314047 -0.02116 -0.160186 0.314463 -0.0180094 -0.161322 0.312501 -0.0209336 -0.159962 0.314523 -0.022124 -0.159239 0.314717 -0.02116 -0.160186 0.314463 0.035419 -0.139376 0.318381 0.032756 -0.149728 0.327617 0.032756 -0.146726 0.316412 0.032756 -0.146726 0.316412 0.032756 -0.149728 0.327617 0.028467 -0.156321 0.32585 0.028467 -0.153319 0.314645 0.032756 -0.146726 0.316412 0.028467 -0.156321 0.32585 0.028467 -0.156321 0.32585 0.022767 -0.161827 0.324375 0.028467 -0.153319 0.314645 0.028467 -0.153319 0.314645 0.0288041 -0.152389 0.314894 0.029125 -0.152079 0.314977 0.028467 -0.153319 0.314645 0.0257855 -0.155607 0.314032 0.0288041 -0.152389 0.314894 0.022767 -0.158825 0.31317 0.0233491 -0.157657 0.313483 0.0257855 -0.155607 0.314032 0.022767 -0.158825 0.31317 0.0257855 -0.155607 0.314032 0.028467 -0.153319 0.314645 0.028467 -0.153319 0.314645 0.022767 -0.161827 0.324375 0.022767 -0.158825 0.31317 0.035419 -0.142378 0.329586 0.032756 -0.149728 0.327617 0.035419 -0.139376 0.318381 0.035419 -0.139376 0.318381 0.036321 -0.131638 0.320454 0.035419 -0.142378 0.329586 0.029125 -0.142399 0.278853 0.029125 -0.152079 0.314977 0.0288041 -0.152389 0.314894 0.029125 -0.142399 0.278853 0.0288041 -0.152389 0.314894 0.0233491 -0.157657 0.313483 0.029125 -0.142399 0.278853 0.0233491 -0.157657 0.313483 0.0214868 -0.159456 0.313001 0.015941 -0.162968 0.31206 0.0165414 -0.162045 0.312307 0.02116 -0.159772 0.312916 -0.036 -0.132054 0.322 -0.0356591 -0.131881 0.322046 -0.035679 -0.132052 0.322 -0.034776 -0.124314 0.324075 -0.0348051 -0.124564 0.324008 -0.034776 -0.126902 0.333733 -0.0119742 -0.165581 0.317317 -0.0132797 -0.164065 0.313423 -0.0109123 -0.164865 0.313209 -0.00768901 -0.16554 0.31137 -0.0119742 -0.165581 0.317317 -0.0093303 -0.1654 0.313065 -0.0119742 -0.165581 0.317317 -0.0109123 -0.164865 0.313209 -0.0093303 -0.1654 0.313065 -0.0093303 -0.1654 0.313065 -0.00933056 -0.164985 0.311519 -0.00768901 -0.16554 0.31137 -0.032114 -0.119553 0.335702 -0.032114 -0.116965 0.326043 -0.0328688 -0.120265 0.330024 -0.015298 -0.16597 0.323265 -0.022124 -0.161827 0.324375 -0.015298 -0.162968 0.31206 -0.022124 -0.161827 0.324375 -0.022124 -0.159239 0.314717 -0.0193024 -0.162013 0.318218 -0.022124 -0.104865 0.329286 -0.0239346 -0.107863 0.333479 -0.022124 -0.107453 0.338944 -0.0256622 -0.108282 0.32837 -0.0268302 -0.105148 0.32921 -0.039617 -0.112034 0.327365 -0.022124 -0.104865 0.329286 -0.0268302 -0.105148 0.32921 -0.0256622 -0.108282 0.32837 -0.0309085 -0.150165 0.321834 -0.028417 -0.152823 0.316436 -0.032114 -0.149728 0.327617 -0.032114 -0.116965 0.326043 -0.0329403 -0.119246 0.325432 -0.0328688 -0.120265 0.330024 -0.0315221 -0.116055 0.326287 -0.0326396 -0.114414 0.326727 -0.032114 -0.116965 0.326043 0.0416256 -0.10219 0.330002 0.028467 -0.110371 0.32781 0.032756 -0.116965 0.326043 -0.0394457 -0.0833752 0.334 -0.045645 -0.105096 0.329224 -0.0273484 -0.0834934 0.334 0.041858 -0.111414 0.327531 0.037523 -0.117681 0.325851 0.041858 -0.10132 0.28986 0.0525 -0.082135 0.295 0.0525 -0.08727 0.334 0.0525 -0.09596 0.291296 0.048346 -0.107226 0.328653 0.048346 -0.097133 0.290982 0.0525 -0.09596 0.291296 0.041858 -0.111414 0.327531 0.041858 -0.10132 0.28986 0.048346 -0.097133 0.290982 -0.0356591 -0.131881 0.322046 -0.0355544 -0.130984 0.322287 -0.036 -0.132054 0.322 0.0416256 -0.10219 0.330002 0.022767 -0.104865 0.329285 0.028467 -0.110371 0.32781 0.0525 -0.08727 0.334 0.0364882 -0.09650060000000001 0.331527 0.0416256 -0.10219 0.330002 0.0416256 -0.10219 0.330002 0.0364882 -0.09650060000000001 0.331527 0.022767 -0.104865 0.329285 0.048346 -0.107226 0.328653 0.0525 -0.08727 0.334 0.0416256 -0.10219 0.330002 0.0525 -0.08727 0.334 0.048346 -0.107226 0.328653 0.0525 -0.106054 0.328967 0.0364882 -0.09650060000000001 0.331527 0.0312341 -0.09406730000000001 0.332179 0.022767 -0.104865 0.329285 0.008331989999999999 -0.098151 0.331085 0.00996817 -0.0987039 0.330937 0.0227564 -0.092987 0.332468 -0.050447 -0.089919 0.292914 -0.053765 -0.090473 0.292766 -0.055224 -0.08516899999999999 0.294187 -0.04514 -0.09327100000000001 0.292016 -0.045645 -0.095002 0.291553 -0.047857 -0.091569 0.292472 -0.050447 -0.089919 0.292914 -0.047857 -0.091569 0.292472 -0.045645 -0.095002 0.291553 -0.050447 -0.089919 0.292914 -0.045645 -0.095002 0.291553 -0.053765 -0.090473 0.292766 -0.0568258 -0.082135 0.295 -0.055224 -0.08516899999999999 0.294187 -0.061307 -0.082135 0.295 -0.055224 -0.08516899999999999 0.294187 -0.053765 -0.090473 0.292766 -0.061307 -0.082135 0.295 -0.032114 -0.146726 0.316412 -0.0324765 -0.146134 0.318206 -0.0324789 -0.146133 0.318228 -0.0093303 -0.1654 0.313065 -0.0109123 -0.164865 0.313209 -0.011125 -0.165125 0.313139 -0.045645 -0.105096 0.329224 -0.053765 -0.100567 0.330437 -0.045645 -0.095002 0.291553 0.0359802 -0.130006 0.326056 0.0355434 -0.125382 0.323788 0.036321 -0.13464 0.331659 -0.00735999 -0.165287 0.311438 -0.00768901 -0.16554 0.31137 -0.00933056 -0.164985 0.311519 0.022767 -0.161827 0.324375 0.015941 -0.16597 0.323265 0.022767 -0.158825 0.31317 -0.039209 -0.099082 0.290459 -0.045645 -0.095002 0.291553 -0.04514 -0.09327100000000001 0.292016 -0.0326396 -0.114414 0.326727 -0.039617 -0.112034 0.327365 -0.03641 -0.120545 0.325084 -0.053765 -0.090473 0.292766 -0.061307 -0.088951 0.293174 -0.061307 -0.082135 0.295 -0.011125 -0.155032 0.275468 -0.0140599 -0.158708 0.294966 -0.02116 -0.160186 0.314463 -0.027825 -0.156321 0.32585 -0.032114 -0.149728 0.327617 -0.028417 -0.152823 0.316436 -0.0347601 -0.139374 0.318381 -0.0346947 -0.140015 0.319867 -0.034776 -0.142378 0.329586 -0.0346947 -0.140015 0.319867 -0.0340839 -0.142905 0.323908 -0.034776 -0.142378 0.329586 0.028467 -0.110371 0.32781 0.032756 -0.119553 0.335702 0.032756 -0.116965 0.326043 -0.022124 -0.104865 0.329286 -0.0256622 -0.108282 0.32837 -0.0239346 -0.107863 0.333479 -0.02116 -0.150092 0.276791 -0.011125 -0.155032 0.275468 -0.02116 -0.160186 0.314463 -0.011125 -0.165125 0.313139 -0.00933056 -0.164985 0.311519 -0.0093303 -0.1654 0.313065 0.0525 -0.08727 0.334 0.0525 -0.106054 0.328967 0.0525 -0.09596 0.291296 -0.0193024 -0.162013 0.318218 -0.022124 -0.159239 0.314717 -0.0209336 -0.159962 0.314523 0.036321 -0.131638 0.320454 0.036 -0.13028 0.320818 0.036 -0.128884 0.321192 -0.0132796 -0.16365 0.311877 -0.0150149 -0.162796 0.312106 -0.0140599 -0.158708 0.294966 0.035273 -0.136073 0.319266 0.0343103 -0.141945 0.317693 0.036 -0.12196 0.284329 0.0214868 -0.159456 0.313001 0.02116 -0.150092 0.276791 0.029125 -0.142399 0.278853 -0.032114 -0.119553 0.335702 -0.0315221 -0.116055 0.326287 -0.032114 -0.116965 0.326043 0.008331989999999999 -0.100739 0.340743 0.000320996 -0.0972787 0.331318 0.000320996 -0.099867 0.340978 -0.0356591 -0.131881 0.322046 -0.035679 -0.132052 0.322 -0.035679 -0.13464 0.331659 0.0257855 -0.155607 0.314032 0.0233491 -0.157657 0.313483 0.0288041 -0.152389 0.314894 -0.027825 -0.153733 0.316192 -0.0229109 -0.158479 0.31492 -0.027825 -0.156321 0.32585 -0.034238 -0.1428 0.319121 -0.0324789 -0.146133 0.318228 -0.0324765 -0.146134 0.318206 0.00996817 -0.0987039 0.330937 0.008331989999999999 -0.098151 0.331085 0.008331989999999999 -0.100739 0.340743 0.028467 -0.153319 0.314645 0.029125 -0.152079 0.314977 0.032756 -0.146726 0.316412 -0.0348859 -0.1388 0.319997 -0.0347601 -0.139374 0.318381 -0.0348859 -0.138849 0.32018 -0.053765 -0.090473 0.292766 -0.045645 -0.095002 0.291553 -0.053765 -0.100567 0.330437 -0.0348051 -0.124564 0.324008 -0.0355544 -0.130984 0.322287 -0.034776 -0.126902 0.333733 -0.0346947 -0.140015 0.319867 -0.0337899 -0.142513 0.319198 -0.0340839 -0.142905 0.323908 0.022767 -0.158825 0.31317 0.0214868 -0.159456 0.313001 0.0233491 -0.157657 0.313483 -0.061307 -0.087269 0.334 -0.061307 -0.09904499999999999 0.330845 -0.053765 -0.100567 0.330437 0.035419 -0.124314 0.324074 0.032756 -0.119553 0.335702 0.035419 -0.126902 0.333733 -0.036 -0.125074 0.323871 -0.036 -0.12196 0.284329 -0.036 -0.132054 0.322 -0.015298 -0.100722 0.330396 -0.015298 -0.10331 0.340054 -0.00768901 -0.100739 0.340743 0.0449858 -0.106802 0.328767 0.0416256 -0.10219 0.330002 0.041858 -0.111414 0.327531 0.0449858 -0.106802 0.328767 0.041858 -0.111414 0.327531 0.048346 -0.107226 0.328653 0.0449858 -0.106802 0.328767 0.048346 -0.107226 0.328653 0.0416256 -0.10219 0.330002 0.029125 -0.142399 0.278853 0.0293349 -0.151681 0.315084 0.029125 -0.152079 0.314977 0.048346 -0.107226 0.328653 0.041858 -0.111414 0.327531 0.048346 -0.097133 0.290982 -0.022124 -0.107453 0.338944 -0.0239346 -0.107863 0.333479 -0.0270382 -0.109611 0.328014 -0.029125 -0.142399 0.278853 -0.0319658 -0.146693 0.316421 -0.0324765 -0.145725 0.31668 -0.0270382 -0.109611 0.328014 -0.027825 -0.112959 0.337469 -0.022124 -0.107453 0.338944 -0.0394457 -0.0833752 0.334 -0.053765 -0.100567 0.330437 -0.045645 -0.105096 0.329224 0.0355434 -0.125382 0.323788 0.035419 -0.124314 0.324074 0.035419 -0.126902 0.333733 0.036321 -0.131638 0.320454 0.036321 -0.13464 0.331659 0.035419 -0.142378 0.329586 0.036321 -0.131638 0.320454 0.0359802 -0.130006 0.326056 0.036321 -0.13464 0.331659 -0.034776 -0.142378 0.329586 -0.0340839 -0.142905 0.323908 -0.0324789 -0.146133 0.318228 -0.0268302 -0.105148 0.32921 -0.022124 -0.104865 0.329286 -0.0211817 -0.104293 0.329439 -0.0344086 -0.1233 0.324346 -0.034776 -0.124314 0.324075 -0.034776 -0.126902 0.333733 -0.027825 -0.110371 0.32781 -0.0326396 -0.114414 0.326727 -0.0315221 -0.116055 0.326287 0.0525 -0.106054 0.328967 0.048346 -0.107226 0.328653 0.0525 -0.09596 0.291296 -0.0193024 -0.162013 0.318218 -0.015298 -0.162968 0.31206 -0.022124 -0.161827 0.324375 0.036 -0.11498 0.286199 0.036 -0.123167 0.305034 0.036 -0.12196 0.284329 0.015941 -0.100722 0.330396 0.022767 -0.104865 0.329285 0.0312341 -0.09406730000000001 0.332179 -0.0324765 -0.145725 0.31668 -0.032114 -0.146726 0.316412 -0.0324765 -0.146134 0.318206 0.0364882 -0.09650060000000001 0.331527 0.0525 -0.08727 0.334 0.0312341 -0.09406730000000001 0.332179 -0.0568258 -0.082135 0.295 -0.061307 -0.082135 0.295 -0.0582582 -0.0792273 0.295 -0.015298 -0.16597 0.323265 -0.0119742 -0.165581 0.317317 -0.00768901 -0.16554 0.31137 -0.061307 -0.082135 0.295 -0.0601191 -0.0754635 0.295 -0.0599749 -0.0754633 0.295 -0.00768901 -0.09815110000000001 0.331085 -0.0158038 -0.0837065 0.334 -0.015298 -0.100722 0.330396 0.036321 -0.13464 0.331659 -0.022124 -0.107453 0.338944 -0.027825 -0.112959 0.337469 -0.055224 -0.08516899999999999 0.294187 -0.0568258 -0.082135 0.295 -0.0582582 -0.0792273 0.295 -0.022124 -0.159239 0.314717 -0.029125 -0.152493 0.316524 -0.02116 -0.160186 0.314463 0.036321 -0.13464 0.331659 -0.032114 -0.149728 0.327617 -0.027825 -0.156321 0.32585 -0.015298 -0.10331 0.340054 0.036321 -0.13464 0.331659 -0.00768901 -0.100739 0.340743 0.008331989999999999 -0.100739 0.340743 0.000320996 -0.099867 0.340978 0.036321 -0.13464 0.331659 0.036321 -0.13464 0.331659 0.000320996 -0.099867 0.340978 -0.00768901 -0.100739 0.340743 0.035419 -0.126902 0.333733 0.032756 -0.119553 0.335702 0.036321 -0.13464 0.331659 0.028467 -0.112959 0.337469 0.036321 -0.13464 0.331659 0.032756 -0.119553 0.335702 0.036321 -0.13464 0.331659 0.008331989999999999 -0.168542 0.322575 0.015941 -0.16597 0.323265 -0.00768901 -0.168542 0.322575 0.000320995 -0.169414 0.322342 0.036321 -0.13464 0.331659 -0.015298 -0.16597 0.323265 -0.00768901 -0.168542 0.322575 0.036321 -0.13464 0.331659 0.036321 -0.13464 0.331659 0.028467 -0.156321 0.32585 0.032756 -0.149728 0.327617 0.035419 -0.142378 0.329586 0.036321 -0.13464 0.331659 0.032756 -0.149728 0.327617 -0.022124 -0.161827 0.324375 -0.015298 -0.16597 0.323265 0.036321 -0.13464 0.331659 0.036321 -0.13464 0.331659 0.015941 -0.16597 0.323265 0.022767 -0.161827 0.324375 0.015941 -0.10331 0.340054 0.036321 -0.13464 0.331659 0.022767 -0.107453 0.338944 0.015941 -0.10331 0.340054 0.008331989999999999 -0.100739 0.340743 0.036321 -0.13464 0.331659 0.008331989999999999 -0.168542 0.322575 0.036321 -0.13464 0.331659 0.000320995 -0.169414 0.322342 0.022767 -0.107453 0.338944 0.036321 -0.13464 0.331659 0.028467 -0.112959 0.337469 0.036321 -0.13464 0.331659 0.022767 -0.161827 0.324375 0.028467 -0.156321 0.32585 -0.022124 -0.161827 0.324375 0.036321 -0.13464 0.331659 -0.027825 -0.156321 0.32585 0.00725699 -0.088821 0.293208 0.004082 -0.088004 0.293427 0.000508551 -0.0862144 0.293907 0.00725699 -0.088821 0.293208 0.000508551 -0.0862144 0.293907 -0.00949171 -0.0778746 0.295 0.0525 -0.08727 0.334 0.0457278 -0.0835847 0.334 0.0414966 -0.084435 0.334 0.0525 -0.082135 0.295 0.0192849 -0.0935428 0.291944 0.011373 -0.08988 0.292924 0.011373 -0.08988 0.292924 0.00725699 -0.088821 0.293208 0.0525 -0.082135 0.295 0.0525 -0.082135 0.295 0.026005 -0.098991 0.290483 0.0223278 -0.09600980000000001 0.291282 0.0525 -0.082135 0.295 0.0293444 -0.103498 0.289276 0.026005 -0.098991 0.290483 0.0525 -0.082135 0.295 0.0223278 -0.09600980000000001 0.291282 0.0200627 -0.0941734 0.291775 0.0525 -0.082135 0.295 0.0200627 -0.0941734 0.291775 0.0192849 -0.0935428 0.291944 0.0525 -0.09596 0.291296 0.048346 -0.097133 0.290982 0.0525 -0.082135 0.295 0.0525 -0.08237899999999999 0.332874 0.0525 -0.08727 0.334 0.0525 -0.0813359 0.3145 0.0525 -0.082135 0.295 0.0525 -0.0813359 0.3145 0.0525 -0.08727 0.334 0.0525 -0.0759871 0.297262 0.0525 -0.0813359 0.3145 0.0525 -0.082135 0.295 0.0525 -0.08237899999999999 0.332874 0.0525 -0.082581 0.334 0.0525 -0.08727 0.334 0.041858 -0.10132 0.28986 0.0525 -0.082135 0.295 0.048346 -0.097133 0.290982 0.0525 -0.08237899999999999 0.332874 0.0525 -0.0813359 0.3145 0.0525 -0.0759871 0.297262 0.0525 -0.082135 0.295 0.0414112 -0.076998 0.295 0.0476527 -0.07513789999999999 0.295 0.0288275 -0.0767767 0.295 0.0414112 -0.076998 0.295 0.0525 -0.082135 0.295 -0.00949171 -0.0778746 0.295 0.0288275 -0.0767767 0.295 0.0525 -0.082135 0.295 -0.00949171 -0.0778746 0.295 0.0525 -0.082135 0.295 0.00725699 -0.088821 0.293208 0.0525 -0.082135 0.295 0.041858 -0.10132 0.28986 0.0293444 -0.103498 0.289276 0.0525 -0.08727 0.334 0.0525 -0.082581 0.334 0.0457278 -0.0835847 0.334 0.0356012 -0.104453 0.28902 0.037522 -0.107587 0.28818 0.0293444 -0.103498 0.289276 0.041858 -0.10132 0.28986 0.0356012 -0.104453 0.28902 0.0293444 -0.103498 0.289276 0.037522 -0.107587 0.28818 0.031111 -0.105882 0.288637 0.0293444 -0.103498 0.289276 0.037522 -0.107587 0.28818 0.034283 -0.113783 0.28652 0.031111 -0.105882 0.288637 0.034238 -0.132706 0.28145 0.034159 -0.130598 0.282014 0.03532 -0.122198 0.284265 0.0525 -0.0754018 0.295 0.0525 -0.075751 0.296349 0.0525 -0.082135 0.295 0.0525 -0.082135 0.295 0.0513403 -0.0750745 0.295 0.0525 -0.0754018 0.295 0.0525 -0.082135 0.295 0.0476527 -0.07513789999999999 0.295 0.049063 -0.07511370000000001 0.295 0.0525 -0.082135 0.295 0.049063 -0.07511370000000001 0.295 0.0513403 -0.0750745 0.295 -0.00949171 -0.0778746 0.295 -0.010356 -0.0760875 0.295 0.0288275 -0.0767767 0.295 0.036 -0.11498 0.286199 0.034283 -0.113783 0.28652 0.037522 -0.107587 0.28818 0.036 -0.12196 0.284329 0.03532 -0.122198 0.284265 0.036 -0.11498 0.286199 0.036 -0.11498 0.286199 0.03532 -0.122198 0.284265 0.034283 -0.113783 0.28652 0.0525 -0.075751 0.296349 0.0525 -0.0759871 0.297262 0.0525 -0.082135 0.295 0.041858 -0.10132 0.28986 0.037522 -0.107587 0.28818 0.0356012 -0.104453 0.28902 0.036 -0.12196 0.284329 0.034238 -0.132706 0.28145 0.03532 -0.122198 0.284265 -0.061307 -0.08136690000000001 0.3145 -0.061307 -0.0788237 0.31082 -0.061307 -0.0776017 0.305225 -0.061307 -0.0793295 0.31372 -0.061307 -0.0788237 0.31082 -0.061307 -0.08136690000000001 0.3145 -0.061307 -0.0793295 0.31372 -0.061307 -0.08136690000000001 0.3145 -0.061307 -0.081329 0.324301 -0.061307 -0.087269 0.334 -0.061307 -0.081329 0.324301 -0.061307 -0.08136690000000001 0.3145 -0.058339 -0.0790632 0.295 -0.0599749 -0.0754633 0.295 -0.0589446 -0.07546219999999999 0.295 -0.061307 -0.0830142 0.334 -0.061307 -0.0828207 0.332976 -0.061307 -0.087269 0.334 -0.061307 -0.087269 0.334 -0.0582031 -0.0830306 0.334 -0.0585424 -0.0830288 0.334 -0.061307 -0.087269 0.334 -0.0394457 -0.0833752 0.334 -0.0582031 -0.0830306 0.334 -0.061307 -0.087269 0.334 -0.0585424 -0.0830288 0.334 -0.061307 -0.0830142 0.334 -0.061307 -0.0828207 0.332976 -0.061307 -0.08261880000000001 0.331907 -0.061307 -0.087269 0.334 -0.061307 -0.08261880000000001 0.331907 -0.061307 -0.081329 0.324301 -0.061307 -0.087269 0.334 -0.034165 -0.114446 0.286342 -0.034388 -0.117613 0.285493 -0.036 -0.11498 0.2862 -0.034165 -0.114446 0.286342 -0.036 -0.11498 0.2862 -0.03641 -0.110452 0.287413 -0.035427 -0.106378 0.288504 -0.03641 -0.110452 0.287413 -0.039617 -0.10194 0.289694 -0.035427 -0.106378 0.288504 -0.039617 -0.10194 0.289694 -0.039209 -0.099082 0.290459 -0.034165 -0.114446 0.286342 -0.03641 -0.110452 0.287413 -0.035427 -0.106378 0.288504 -0.034433 -0.125957 0.283258 -0.036 -0.12196 0.284329 -0.034388 -0.117613 0.285493 -0.034238 -0.132706 0.28145 -0.036 -0.12196 0.284329 -0.034433 -0.125957 0.283258 -0.032312 -0.13418 0.281054 -0.034238 -0.132706 0.28145 -0.034433 -0.125957 0.283258 -0.02814 -0.141635 0.279057 -0.029125 -0.142399 0.278853 -0.032312 -0.13418 0.281054 -0.02814 -0.141635 0.279057 -0.022179 -0.147853 0.277391 -0.029125 -0.142399 0.278853 -0.029125 -0.142399 0.278853 -0.034238 -0.132706 0.28145 -0.032312 -0.13418 0.281054 0.00227099 -0.155713 0.275285 -8.407769999999999e-09 -0.156733 0.275012 -0.00648101 -0.155121 0.275443 0.025664 -0.145275 0.278081 0.02116 -0.150092 0.276791 0.018865 -0.15063 0.276646 0.011124 -0.155032 0.275468 0.018865 -0.15063 0.276646 0.02116 -0.150092 0.276791 0.018865 -0.15063 0.276646 0.011124 -0.155032 0.275468 0.0109 -0.154184 0.275694 0.0109 -0.154184 0.275694 0.011124 -0.155032 0.275468 -8.407769999999999e-09 -0.156733 0.275012 -8.407769999999999e-09 -0.156733 0.275012 0.00227099 -0.155713 0.275285 0.0109 -0.154184 0.275694 0.034238 -0.132706 0.28145 0.030872 -0.138455 0.27991 0.034159 -0.130598 0.282014 -0.0201217 -0.149134 0.277048 -0.02116 -0.150092 0.276791 -0.022179 -0.147853 0.277391 -0.0201217 -0.149134 0.277048 -0.014805 -0.152445 0.27616 -0.02116 -0.150092 0.276791 -0.011125 -0.155032 0.275468 -0.00648101 -0.155121 0.275443 -8.407769999999999e-09 -0.156733 0.275012 -0.00648101 -0.155121 0.275443 -0.011125 -0.155032 0.275468 -0.014805 -0.152445 0.27616 -0.011125 -0.155032 0.275468 -0.02116 -0.150092 0.276791 -0.014805 -0.152445 0.27616 0.029125 -0.142399 0.278853 0.030872 -0.138455 0.27991 0.034238 -0.132706 0.28145 0.02116 -0.150092 0.276791 0.025664 -0.145275 0.278081 0.029125 -0.142399 0.278853 -0.036 -0.12196 0.284329 -0.036 -0.11498 0.2862 -0.034388 -0.117613 0.285493 0.029125 -0.142399 0.278853 0.025664 -0.145275 0.278081 0.030872 -0.138455 0.27991 -0.02116 -0.150092 0.276791 -0.029125 -0.142399 0.278853 -0.022179 -0.147853 0.277391 0.0367757 -0.052617 0.260317 0.03607 -0.051818 0.229616 0.045763 -0.043496 0.229616 0.0367757 -0.052617 0.260317 0.0366821 -0.0526975 0.260318 0.03607 -0.051818 0.229616 0.0139312 0 0.229616 0.00362677 0 0.229616 0.0286049 0.021748 0.229616 0.045763 0.043496 0.229616 0.0286049 0.021748 0.229616 0.00362677 0 0.229616 -0.042663 0.047998 0.260614 -0.036688 0.052706 0.260614 -0.036069 0.051818 0.229616 -0.036688 0.052706 0.260614 -0.024899 0.058018 0.229616 -0.036069 0.051818 0.229616 -0.018354 0 0.229616 0.00327299 -0.030921 0.229616 0.01271 -0.061842 0.229616 0.01271 -0.061842 0.229616 -1.24991e-08 -0.063135 0.229616 -0.018354 0 0.229616 0.025326 0.0590106 0.260541 0.025353 0.0589956 0.260541 0.0249 0.058018 0.229616 0.025353 0.0589956 0.260541 0.03607 0.051818 0.229616 0.0249 0.058018 0.229616 0.0120203 0.029009 0.229616 0.0249 0.058018 0.229616 0.03607 0.051818 0.229616 -0.012928 0.062903 0.260614 -1.24518e-08 0.064217 0.260614 -1.24991e-08 0.063135 0.229616 -1.24518e-08 0.064217 0.260614 0.01271 0.061842 0.229616 -1.24991e-08 0.063135 0.229616 -1.24518e-08 0.064217 0.260614 0.012928 0.062903 0.260614 0.01271 0.061842 0.229616 0.012928 0.062903 0.260614 0.0249 0.058018 0.229616 0.01271 0.061842 0.229616 0.0249 0.058018 0.229616 0.012928 0.062903 0.260614 0.0215282 0.0602048 0.260616 0.00327299 0.030921 0.229616 0.01271 0.061842 0.229616 0.0249 0.058018 0.229616 0.025353 -0.0589956 0.260541 0.0249 -0.058018 0.229616 0.03607 -0.051818 0.229616 0.025353 -0.0589956 0.260541 0.025326 -0.0590106 0.260541 0.0249 -0.058018 0.229616 0.025326 -0.0590106 0.260541 0.0215282 -0.0602048 0.260616 0.0249 -0.058018 0.229616 0.0249 -0.058018 0.229616 0.0215282 -0.0602048 0.260616 0.012928 -0.062903 0.260614 0.01271 -0.061842 0.229616 0.0249 -0.058018 0.229616 0.012928 -0.062903 0.260614 0.012928 -0.062903 0.260614 -1.24518e-08 -0.064217 0.260614 0.01271 -0.061842 0.229616 -1.24518e-08 -0.064217 0.260614 -1.24991e-08 -0.063135 0.229616 0.01271 -0.061842 0.229616 -1.24991e-08 -0.063135 0.229616 -1.24518e-08 -0.064217 0.260614 -0.012928 -0.062903 0.260614 -0.0343496 0 0.229616 -0.036069 0.051818 0.229616 -0.024899 0.058018 0.229616 -0.0293475 -1.37863e-25 0.229616 -0.0343496 0 0.229616 -0.024899 0.058018 0.229616 -0.024899 0.058018 0.229616 -0.036688 0.052706 0.260614 -0.025326 0.059012 0.260614 -0.01271 0.061842 0.229616 -0.024899 0.058018 0.229616 -0.025326 0.059012 0.260614 -0.0293475 -1.37863e-25 0.229616 -0.024899 0.058018 0.229616 -0.01271 0.061842 0.229616 -0.0240639 0 0.229616 -0.0293475 -1.37863e-25 0.229616 -0.01271 0.061842 0.229616 -0.0240639 0 0.229616 -0.01271 0.061842 0.229616 -1.24991e-08 0.063135 0.229616 -0.025326 0.059012 0.260614 -0.012928 0.062903 0.260614 -0.01271 0.061842 0.229616 -0.0343496 0 0.229616 -0.0391887 0 0.229616 -0.036069 0.051818 0.229616 -0.024899 -0.058018 0.229616 -0.0343496 0 0.229616 -0.0293475 -1.37863e-25 0.229616 -0.012928 -0.062903 0.260614 -0.025326 -0.059012 0.260614 -0.01271 -0.061842 0.229616 -0.01271 -0.061842 0.229616 -0.024899 -0.058018 0.229616 -0.0293475 -1.37863e-25 0.229616 -0.025326 -0.059012 0.260614 -0.024899 -0.058018 0.229616 -0.01271 -0.061842 0.229616 -0.0120295 0 0.229616 0.00327299 0.030921 0.229616 0.0249 0.058018 0.229616 -0.0120295 0 0.229616 -0.018354 0 0.229616 0.00327299 0.030921 0.229616 -0.01271 -0.061842 0.229616 -0.0293475 -1.37863e-25 0.229616 -0.0240639 0 0.229616 -0.042663 -0.047998 0.260614 -0.045763 -0.043496 0.229616 -0.036069 -0.051818 0.229616 -0.036688 -0.052706 0.260614 -0.042663 -0.047998 0.260614 -0.036069 -0.051818 0.229616 -0.036069 -0.051818 0.229616 -0.0391887 0 0.229616 -0.0343496 0 0.229616 -0.040916 -0.025909 0.229616 -0.0391887 0 0.229616 -0.036069 -0.051818 0.229616 -0.040916 -0.025909 0.229616 -0.0439693 0 0.229616 -0.0391887 0 0.229616 -0.045763 -0.043496 0.229616 -0.0439693 0 0.229616 -0.040916 -0.025909 0.229616 -0.0487762 -0.021748 0.229616 -0.0439693 0 0.229616 -0.045763 -0.043496 0.229616 -0.046547 0.044242 0.260614 -0.042663 0.047998 0.260614 -0.045763 0.043496 0.229616 -0.045763 -0.043496 0.229616 -0.053583 -0.033394 0.229616 -0.0487762 -0.021748 0.229616 -0.04879 0 0.229616 -0.0487762 -0.021748 0.229616 -0.053583 -0.033394 0.229616 -0.053583 -0.033394 0.229616 -0.0539995 -0.016697 0.229616 -0.04879 0 0.229616 -0.0487762 -0.021748 0.229616 -0.04879 0 0.229616 -0.0439693 0 0.229616 -0.045763 0.043496 0.229616 -0.053583 0.033394 0.229616 -0.046547 0.044242 0.260614 -0.0487762 0.021748 0.229616 -0.053583 0.033394 0.229616 -0.045763 0.043496 0.229616 -0.0439693 0 0.229616 -0.04879 0 0.229616 -0.0487762 0.021748 0.229616 -0.04879 0 0.229616 -0.053583 0.033394 0.229616 -0.0487762 0.021748 0.229616 -0.062411 0.009556 0.229616 -0.063481 0.009719999999999999 0.260614 -0.060224 0.0223 0.260614 -0.060224 0.0223 0.260614 -0.059209 0.021924 0.229616 -0.062411 0.009556 0.229616 -0.062411 0.009556 0.229616 -0.06316280000000001 0 0.237299 -0.063481 0.009719999999999999 0.260614 -0.0628956 0 0.229616 -0.06316280000000001 0 0.237299 -0.062411 0.009556 0.229616 -0.062411 -0.009556 0.229616 -0.0628956 0 0.229616 -0.0589743 0 0.229616 -0.0628956 0 0.229616 -0.062411 -0.009556 0.229616 -0.06316280000000001 0 0.237299 -0.062411 -0.009556 0.229616 -0.0589743 0 0.229616 -0.0537532 0 0.229616 -0.0537532 0 0.229616 -0.0589743 0 0.229616 -0.062411 0.009556 0.229616 -0.059209 -0.021924 0.229616 -0.062411 -0.009556 0.229616 -0.0537532 0 0.229616 -0.0539995 -0.016697 0.229616 -0.059209 -0.021924 0.229616 -0.0537532 0 0.229616 -0.045763 0.043496 0.229616 -0.0439693 0 0.229616 -0.0487762 0.021748 0.229616 -0.040916 0.025909 0.229616 -0.0439693 0 0.229616 -0.045763 0.043496 0.229616 0.0367757 0.052617 0.260317 0.041335 0.0486991 0.260227 0.045763 0.043496 0.229616 0.046548 0.044242 0.260614 0.054502 0.033966 0.260614 0.053583 0.033394 0.229616 0.046548 0.044242 0.260614 0.053583 0.033394 0.229616 0.045763 0.043496 0.229616 0.053583 0.033394 0.229616 0.0286049 0.021748 0.229616 0.045763 0.043496 0.229616 0.045763 0.043496 0.229616 0.041335 0.0486991 0.260227 0.046548 0.044242 0.260614 0.0366821 0.0526975 0.260318 0.0367757 0.052617 0.260317 0.03607 0.051818 0.229616 0.0367757 0.052617 0.260317 0.045763 0.043496 0.229616 0.03607 0.051818 0.229616 -0.045763 -0.043496 0.229616 -0.042663 -0.047998 0.260614 -0.046547 -0.044242 0.260614 0.06316380000000001 0 0.237299 0.0639748 0 0.260614 0.063482 -0.009719999999999999 0.260614 0.063482 -0.009719999999999999 0.260614 0.062412 -0.009556 0.229616 0.06316380000000001 0 0.237299 0.063482 -0.009719999999999999 0.260614 0.060225 -0.0223 0.260614 0.062412 -0.009556 0.229616 0.060225 -0.0223 0.260614 0.05921 -0.021924 0.229616 0.062412 -0.009556 0.229616 0.05921 0.021924 0.229616 0.054502 0.033966 0.260614 0.060225 0.0223 0.260614 0.062412 0.009556 0.229616 0.05921 0.021924 0.229616 0.060225 0.0223 0.260614 0.062412 0.009556 0.229616 0.060225 0.0223 0.260614 0.063482 0.009719999999999999 0.260614 0.0270667 0 0.229616 0.0139312 0 0.229616 0.053583 0.033394 0.229616 0.05921 0.021924 0.229616 0.0270667 0 0.229616 0.053583 0.033394 0.229616 0.062412 0.009556 0.229616 0.0448048 0 0.229616 0.05921 0.021924 0.229616 0.0628966 0 0.229616 0.0448048 0 0.229616 0.062412 0.009556 0.229616 0.0628966 0 0.229616 0.062412 0.009556 0.229616 0.06316380000000001 0 0.237299 0.0448048 0 0.229616 0.0270667 0 0.229616 0.05921 0.021924 0.229616 0.05921 -0.021924 0.229616 0.0270667 0 0.229616 0.0448048 0 0.229616 0.05921 -0.021924 0.229616 0.0448048 0 0.229616 0.062412 -0.009556 0.229616 0.053583 -0.033394 0.229616 0.0270667 0 0.229616 0.05921 -0.021924 0.229616 0.053583 -0.033394 0.229616 0.0139312 0 0.229616 0.0270667 0 0.229616 0.053583 -0.033394 0.229616 0.0286049 -0.021748 0.229616 0.0139312 0 0.229616 0.06316380000000001 0 0.237299 0.062412 0.009556 0.229616 0.063482 0.009719999999999999 0.260614 -0.062411 -0.009556 0.229616 -0.060224 -0.0223 0.260614 -0.063481 -0.009719999999999999 0.260614 -0.059209 -0.021924 0.229616 -0.054501 -0.033966 0.260614 -0.060224 -0.0223 0.260614 -0.059209 -0.021924 0.229616 -0.053583 -0.033394 0.229616 -0.054501 -0.033966 0.260614 -0.053583 -0.033394 0.229616 -0.046547 -0.044242 0.260614 -0.054501 -0.033966 0.260614 0.0366821 -0.0526975 0.260318 0.025353 -0.0589956 0.260541 0.03607 -0.051818 0.229616 -0.024899 -0.058018 0.229616 -0.036069 -0.051818 0.229616 -0.0343496 0 0.229616 -0.012928 0.062903 0.260614 -1.24991e-08 0.063135 0.229616 -0.01271 0.061842 0.229616 0.054502 -0.033966 0.260614 0.046548 -0.044242 0.260614 0.053583 -0.033394 0.229616 0.046548 -0.044242 0.260614 0.045763 -0.043496 0.229616 0.053583 -0.033394 0.229616 0.046548 -0.044242 0.260614 0.041335 -0.0486991 0.260227 0.045763 -0.043496 0.229616 0.06316380000000001 0 0.237299 0.063482 0.009719999999999999 0.260614 0.0639748 0 0.260614 0.00327299 -0.030921 0.229616 -0.018354 0 0.229616 -0.0120295 0 0.229616 0.0249 -0.058018 0.229616 0.00327299 -0.030921 0.229616 -0.0120295 0 0.229616 -0.0120295 0 0.229616 0.0120203 -0.029009 0.229616 0.0249 -0.058018 0.229616 0.0120203 -0.029009 0.229616 -0.0120295 0 0.229616 -0.00482968 0 0.229616 -0.00482968 0 0.229616 -0.0120295 0 0.229616 0.0120203 0.029009 0.229616 -0.00482968 0 0.229616 0.0120203 0.029009 0.229616 0.03607 0.051818 0.229616 0.0204667 -0.025909 0.229616 -0.00482968 0 0.229616 0.00362677 0 0.229616 -0.00482968 0 0.229616 0.0204667 -0.025909 0.229616 0.03607 -0.051818 0.229616 0.00362677 0 0.229616 -0.00482968 0 0.229616 0.0204667 0.025909 0.229616 0.0204667 0.025909 0.229616 -0.00482968 0 0.229616 0.03607 0.051818 0.229616 0.062412 -0.009556 0.229616 0.0448048 0 0.229616 0.0628966 0 0.229616 0.0249 -0.058018 0.229616 0.0120203 -0.029009 0.229616 0.03607 -0.051818 0.229616 0.03607 -0.051818 0.229616 0.0120203 -0.029009 0.229616 -0.00482968 0 0.229616 -0.059209 0.021924 0.229616 -0.060224 0.0223 0.260614 -0.054501 0.033966 0.260614 -0.0539995 0.016697 0.229616 -0.059209 0.021924 0.229616 -0.053583 0.033394 0.229616 -0.0539995 0.016697 0.229616 -0.0537532 0 0.229616 -0.059209 0.021924 0.229616 -0.04879 0 0.229616 -0.0537532 0 0.229616 -0.0539995 0.016697 0.229616 -0.054501 0.033966 0.260614 -0.053583 0.033394 0.229616 -0.059209 0.021924 0.229616 0.054502 0.033966 0.260614 0.05921 0.021924 0.229616 0.053583 0.033394 0.229616 -0.025326 -0.059012 0.260614 -0.036688 -0.052706 0.260614 -0.024899 -0.058018 0.229616 0.05921 -0.021924 0.229616 0.060225 -0.0223 0.260614 0.054502 -0.033966 0.260614 -0.0539995 0.016697 0.229616 -0.053583 0.033394 0.229616 -0.04879 0 0.229616 0.03607 0.051818 0.229616 0.025353 0.0589956 0.260541 0.0366821 0.0526975 0.260318 -0.060224 -0.0223 0.260614 -0.062411 -0.009556 0.229616 -0.059209 -0.021924 0.229616 -0.053583 0.033394 0.229616 -0.054501 0.033966 0.260614 -0.046547 0.044242 0.260614 -0.036069 -0.051818 0.229616 -0.045763 -0.043496 0.229616 -0.040916 -0.025909 0.229616 -0.0589743 0 0.229616 -0.0628956 0 0.229616 -0.062411 0.009556 0.229616 0.045763 -0.043496 0.229616 0.0204667 -0.025909 0.229616 0.00362677 0 0.229616 0.00362677 0 0.229616 0.0286049 -0.021748 0.229616 0.045763 -0.043496 0.229616 -0.018354 0 0.229616 -1.24991e-08 0.063135 0.229616 0.01271 0.061842 0.229616 -0.012928 -0.062903 0.260614 -0.01271 -0.061842 0.229616 -1.24991e-08 -0.063135 0.229616 -0.0391887 0 0.229616 -0.0439693 0 0.229616 -0.040916 0.025909 0.229616 0.03607 -0.051818 0.229616 0.0204667 -0.025909 0.229616 0.045763 -0.043496 0.229616 0.053583 -0.033394 0.229616 0.05921 -0.021924 0.229616 0.054502 -0.033966 0.260614 -0.0539995 -0.016697 0.229616 -0.0537532 0 0.229616 -0.04879 0 0.229616 -1.24991e-08 -0.063135 0.229616 -0.01271 -0.061842 0.229616 -0.0240639 0 0.229616 0.01271 0.061842 0.229616 0.00327299 0.030921 0.229616 -0.018354 0 0.229616 -0.063481 -0.009719999999999999 0.260614 -0.0639738 0 0.260614 -0.06316280000000001 0 0.237299 0.0120203 0.029009 0.229616 -0.0120295 0 0.229616 0.0249 0.058018 0.229616 0.0249 0.058018 0.229616 0.0215282 0.0602048 0.260616 0.025326 0.0590106 0.260541 -0.0537532 0 0.229616 -0.062411 0.009556 0.229616 -0.059209 0.021924 0.229616 0.045763 -0.043496 0.229616 0.0286049 -0.021748 0.229616 0.053583 -0.033394 0.229616 0.06316380000000001 0 0.237299 0.062412 -0.009556 0.229616 0.0628966 0 0.229616 -0.053583 -0.033394 0.229616 -0.059209 -0.021924 0.229616 -0.0539995 -0.016697 0.229616 0.0286049 -0.021748 0.229616 0.00362677 0 0.229616 0.0139312 0 0.229616 -0.063481 -0.009719999999999999 0.260614 -0.06316280000000001 0 0.237299 -0.062411 -0.009556 0.229616 0.0204667 0.025909 0.229616 0.03607 0.051818 0.229616 0.045763 0.043496 0.229616 -0.0391887 0 0.229616 -0.040916 0.025909 0.229616 -0.036069 0.051818 0.229616 0.0139312 0 0.229616 0.0286049 0.021748 0.229616 0.053583 0.033394 0.229616 -0.036069 0.051818 0.229616 -0.045763 0.043496 0.229616 -0.042663 0.047998 0.260614 -0.040916 0.025909 0.229616 -0.045763 0.043496 0.229616 -0.036069 0.051818 0.229616 -1.24991e-08 -0.063135 0.229616 -0.0240639 0 0.229616 -0.018354 0 0.229616 -0.018354 0 0.229616 -0.0240639 0 0.229616 -1.24991e-08 0.063135 0.229616 0.0204667 0.025909 0.229616 0.045763 0.043496 0.229616 0.00362677 0 0.229616 0.0249 -0.058018 0.229616 0.01271 -0.061842 0.229616 0.00327299 -0.030921 0.229616 -0.053583 -0.033394 0.229616 -0.045763 -0.043496 0.229616 -0.046547 -0.044242 0.260614 -0.06316280000000001 0 0.237299 -0.0639738 0 0.260614 -0.063481 0.009719999999999999 0.260614 0.041335 -0.0486991 0.260227 0.0367757 -0.052617 0.260317 0.045763 -0.043496 0.229616 -0.036688 -0.052706 0.260614 -0.036069 -0.051818 0.229616 -0.024899 -0.058018 0.229616 -0.182143 -0.0453111 0.463487 -0.182 -0.0454548 0.462976 -0.181967 -0.0455904 0.463997 -0.182143 -0.0453111 0.463487 -0.181967 -0.0455904 0.463997 -0.182343 -0.0450501 0.463532 -0.182 -0.0454548 0.462976 -0.182 -0.0458 0.46297 -0.181967 -0.0455904 0.463997 -0.18187 -0.043309 0.455483 -0.181731 -0.0432947 0.455465 -0.181833 -0.0446724 0.458122 -0.18187 -0.043309 0.455483 -0.181833 -0.0446724 0.458122 -0.183265 -0.043175 0.459821 -0.18191 -0.041463 0.453145 -0.18187 -0.043309 0.455483 -0.183265 -0.043175 0.459821 -0.18187 -0.043309 0.455483 -0.18191 -0.041463 0.453145 -0.181731 -0.0432947 0.455465 -0.181833 -0.0446724 0.458122 -0.182543 -0.044611 0.461138 -0.183265 -0.043175 0.459821 -0.18277 -0.044549 0.464265 -0.181959 -0.045582 0.46426 -0.182706 -0.044517 0.465835 -0.181967 -0.0455904 0.463997 -0.181959 -0.045582 0.46426 -0.18277 -0.044549 0.464265 -0.18203 -0.035793 0.449824 -0.181778 -0.0373585 0.450476 -0.181964 -0.038924 0.451127 -0.181525 -0.035793 0.449824 -0.181778 -0.0373585 0.450476 -0.18203 -0.035793 0.449824 -0.18203 -0.035793 0.449824 -0.181525 -0.035793 0.449824 -0.181525 -0.0356825 0.449806 -0.181572 -0.0388005 0.451076 -0.181778 -0.0373585 0.450476 -0.181525 -0.035793 0.449824 -0.181572 -0.0388005 0.451076 -0.181964 -0.038924 0.451127 -0.181778 -0.0373585 0.450476 -0.181964 -0.038924 0.451127 -0.181574 -0.038924 0.451127 -0.181572 -0.0388005 0.451076 -0.181574 -0.038924 0.451127 -0.181645 -0.0413955 0.453091 -0.181964 -0.038924 0.451127 -0.181645 -0.0413955 0.453091 -0.18191 -0.041463 0.453145 -0.181964 -0.038924 0.451127 -0.18191 -0.041463 0.453145 -0.181647 -0.041463 0.453145 -0.181645 -0.0413955 0.453091 -0.181502 -0.0204813 0.449445 -0.182292 -0.02114 0.449445 -0.181948 -0.0170155 0.449445 -0.181502 -0.0204813 0.449445 -0.181948 -0.0170155 0.449445 -0.1815 -0.0172285 0.449445 -0.181502 -0.02114 0.449445 -0.182292 -0.02114 0.449445 -0.181502 -0.0204813 0.449445 -0.182078 -0.033616 0.449472 -0.181795 -0.0347045 0.449648 -0.18203 -0.035793 0.449824 -0.185662 -0.021164 0.456439 -0.182078 -0.033616 0.449472 -0.18203 -0.035793 0.449824 -0.181512 -0.033616 0.449472 -0.181795 -0.0347045 0.449648 -0.182078 -0.033616 0.449472 -0.181525 -0.0356825 0.449806 -0.181795 -0.0347045 0.449648 -0.181512 -0.033616 0.449472 -0.185662 -0.021164 0.456439 -0.18224 -0.025265 0.449445 -0.182078 -0.033616 0.449472 -0.182292 -0.02114 0.449445 -0.18224 -0.025265 0.449445 -0.185662 -0.021164 0.456439 -0.181897 -0.0232025 0.449445 -0.18224 -0.025265 0.449445 -0.182292 -0.02114 0.449445 -0.181873 -0.0294405 0.449459 -0.182078 -0.033616 0.449472 -0.18224 -0.025265 0.449445 -0.181511 -0.0331348 0.44947 -0.182078 -0.033616 0.449472 -0.181873 -0.0294405 0.449459 -0.181897 -0.0232025 0.449445 -0.182292 -0.02114 0.449445 -0.181502 -0.02114 0.449445 -0.181505 -0.025265 0.449445 -0.181873 -0.0294405 0.449459 -0.18224 -0.025265 0.449445 -0.181505 -0.025265 0.449445 -0.18224 -0.025265 0.449445 -0.181505 -0.0249602 0.449445 -0.181505 -0.0249602 0.449445 -0.181897 -0.0232025 0.449445 -0.181502 -0.02114 0.449445 -0.181964 0.038924 0.451127 -0.181778 0.0373585 0.450476 -0.18203 0.035793 0.449824 -0.181572 0.0388005 0.451076 -0.181778 0.0373585 0.450476 -0.181964 0.038924 0.451127 -0.181574 0.038924 0.451127 -0.181964 0.038924 0.451127 -0.181645 0.0413955 0.453091 -0.181964 0.038924 0.451127 -0.181572 0.0388005 0.451076 -0.181574 0.038924 0.451127 -0.181964 0.038924 0.451127 -0.18203 0.035793 0.449824 -0.185662 0.021164 0.456439 -0.181645 0.0413955 0.453091 -0.181964 0.038924 0.451127 -0.18191 0.041463 0.453145 -0.181994 0.0454471 0.462799 -0.182352 0.044975 0.462701 -0.18277 0.044549 0.464265 -0.181994 0.0454471 0.462799 -0.182343 0.0450501 0.463532 -0.18277 0.044549 0.464265 -0.18185 -0.042749 0.473146 -0.181824 -0.04438 0.470309 -0.18168 -0.0427767 0.473098 -0.181824 -0.04438 0.470309 -0.181767 -0.04438 0.470309 -0.18168 -0.0427767 0.473098 -0.182664 -0.043739 0.468849 -0.182522 -0.044486 0.467389 -0.181824 -0.04438 0.470309 -0.182522 -0.044486 0.467389 -0.182664 -0.043739 0.468849 -0.183231 -0.042905 0.468936 -0.182522 -0.044486 0.467389 -0.181816 -0.0449778 0.468768 -0.181824 -0.04438 0.470309 -0.181767 -0.04438 0.470309 -0.181768 -0.0443846 0.470297 -0.181824 -0.04438 0.470309 -0.181768 -0.0443846 0.470297 -0.181816 -0.0449778 0.468768 -0.181824 -0.04438 0.470309 -0.182522 -0.044486 0.467389 -0.181835 -0.0451832 0.468155 -0.181816 -0.0449778 0.468768 -0.182059 -0.045473 0.464903 -0.181914 -0.0455268 0.465668 -0.182522 -0.044486 0.467389 -0.181914 -0.0455268 0.465668 -0.181892 -0.0454398 0.466361 -0.182522 -0.044486 0.467389 -0.181892 -0.0454398 0.466361 -0.181835 -0.0451832 0.468155 -0.182522 -0.044486 0.467389 -0.182706 -0.044517 0.465835 -0.182059 -0.045473 0.464903 -0.182522 -0.044486 0.467389 -0.185662 -0.021164 0.456439 -0.183994 -0.041234 0.458639 -0.184498 -0.041145 0.460885 -0.183994 -0.041234 0.458639 -0.18405 -0.0415824 0.459762 -0.184498 -0.041145 0.460885 -0.183785 -0.0421116 0.459762 -0.183265 -0.043175 0.459821 -0.184498 -0.041145 0.460885 -0.183994 -0.041234 0.458639 -0.183265 -0.043175 0.459821 -0.183785 -0.0421116 0.459762 -0.183994 -0.041234 0.458639 -0.183785 -0.0421116 0.459762 -0.18405 -0.0415824 0.459762 -0.184498 -0.041145 0.460885 -0.183265 -0.043175 0.459821 -0.184745 -0.041005 0.464447 -0.183265 -0.043175 0.459821 -0.182543 -0.044611 0.461138 -0.183718 -0.04304 0.464381 -0.183265 -0.043175 0.459821 -0.183718 -0.04304 0.464381 -0.184745 -0.041005 0.464447 -0.182543 -0.044611 0.461138 -0.18277 -0.044549 0.464265 -0.183718 -0.04304 0.464381 -0.182352 -0.044975 0.462701 -0.18277 -0.044549 0.464265 -0.182543 -0.044611 0.461138 -0.182543 -0.044611 0.461138 -0.181971 -0.0454295 0.462175 -0.182352 -0.044975 0.462701 -0.183718 -0.04304 0.464381 -0.18277 -0.044549 0.464265 -0.183684 -0.043006 0.465529 -0.182352 -0.044975 0.462701 -0.181994 -0.0454471 0.462799 -0.18277 -0.044549 0.464265 -0.182343 -0.0450501 0.463532 -0.182 -0.0454548 0.462976 -0.181994 -0.0454471 0.462799 -0.18277 -0.044549 0.464265 -0.182343 -0.0450501 0.463532 -0.181994 -0.0454471 0.462799 -0.183731 -0.041281 0.457465 -0.183265 -0.043175 0.459821 -0.183994 -0.041234 0.458639 -0.181971 -0.0454295 0.462175 -0.181994 -0.0454471 0.462799 -0.182352 -0.044975 0.462701 -0.181952 -0.0456116 0.464491 -0.181967 -0.0455904 0.463997 -0.182 -0.0458 0.46297 -0.181967 -0.0455904 0.463997 -0.181959 -0.045582 0.46426 -0.181952 -0.0456116 0.464491 -0.182 -0.0458 0.46297 -0.181952 -0.0456116 0.464491 -0.181914 -0.0455268 0.465668 -0.182039 -0.0448422 0.45963 -0.182543 -0.044611 0.461138 -0.181833 -0.0446724 0.458122 -0.182039 -0.0448422 0.45963 -0.18193 -0.0453752 0.461 -0.182543 -0.044611 0.461138 -0.182 -0.0458 0.46297 -0.181971 -0.0454295 0.462175 -0.18193 -0.0453752 0.461 -0.181994 -0.0454471 0.462799 -0.181971 -0.0454295 0.462175 -0.182 -0.0458 0.46297 -0.18193 -0.0453752 0.461 -0.182039 -0.0448422 0.45963 -0.181838 -0.0447635 0.45843 -0.181838 -0.0447635 0.45843 -0.182039 -0.0448422 0.45963 -0.181833 -0.0446724 0.458122 -0.182543 0.044611 0.461138 -0.182352 0.044975 0.462701 -0.181971 0.0454295 0.462175 -0.18193 0.0453752 0.461 -0.182543 0.044611 0.461138 -0.181971 0.0454295 0.462175 -0.181512 0.033616 0.449472 -0.181795 0.0347045 0.449648 -0.181525 0.0356825 0.449806 -0.181525 0.0356825 0.449806 -0.181795 0.0347045 0.449648 -0.18203 0.035793 0.449824 -0.181512 0.033616 0.449472 -0.182078 0.033616 0.449472 -0.181795 0.0347045 0.449648 -0.18224 0.025265 0.449445 -0.182078 0.033616 0.449472 -0.181873 0.0294405 0.449459 -0.182078 0.033616 0.449472 -0.18224 0.025265 0.449445 -0.185662 0.021164 0.456439 -0.181505 0.025265 0.449445 -0.18224 0.025265 0.449445 -0.181873 0.0294405 0.449459 -0.181505 0.0249602 0.449445 -0.18224 0.025265 0.449445 -0.181505 0.025265 0.449445 -0.182292 0.02114 0.449445 -0.18224 0.025265 0.449445 -0.181897 0.0232025 0.449445 -0.181897 0.0232025 0.449445 -0.18224 0.025265 0.449445 -0.181505 0.0249602 0.449445 -0.181502 0.02114 0.449445 -0.182292 0.02114 0.449445 -0.181897 0.0232025 0.449445 -0.181505 0.025265 0.449445 -0.181873 0.0294405 0.449459 -0.181511 0.0331348 0.44947 -0.18193 0.0453752 0.461 -0.181971 0.0454295 0.462175 -0.182 0.0458 0.46297 -0.182 0.0458 0.46297 -0.181971 0.0454295 0.462175 -0.181994 0.0454471 0.462799 -0.182396 0.012891 0.449445 -0.182292 0.02114 0.449445 -0.181948 0.0170155 0.449445 -0.181525 0.012891 0.449445 -0.182396 0.012891 0.449445 -0.181948 0.0170155 0.449445 -0.1815 0.0172285 0.449445 -0.181948 0.0170155 0.449445 -0.181502 0.0204813 0.449445 -0.181525 0.012891 0.449445 -0.181948 0.0170155 0.449445 -0.1815 0.0172285 0.449445 -0.181532 0.0117967 0.449445 -0.181558 0.00734142 0.449445 -0.182396 0.012891 0.449445 -0.181532 0.0117967 0.449445 -0.182396 0.012891 0.449445 -0.181525 0.012891 0.449445 -0.181511 0.0331348 0.44947 -0.181873 0.0294405 0.449459 -0.182078 0.033616 0.449472 -0.182059 0.045473 0.464903 -0.182706 0.044517 0.465835 -0.182522 0.044486 0.467389 -0.181914 0.0455268 0.465668 -0.182059 0.045473 0.464903 -0.182522 0.044486 0.467389 -0.181952 0.0456116 0.464491 -0.182059 0.045473 0.464903 -0.181914 0.0455268 0.465668 -0.182059 0.045473 0.464903 -0.181959 0.045582 0.46426 -0.181952 0.0456116 0.464491 -0.181914 0.0455268 0.465668 -0.181952 0.0456116 0.464491 -0.182 0.0458 0.46297 -0.181768 0.0443846 0.470297 -0.181767 0.04438 0.470309 -0.181824 0.04438 0.470309 -0.181816 0.0449778 0.468768 -0.181768 0.0443846 0.470297 -0.181824 0.04438 0.470309 -0.181816 0.0449778 0.468768 -0.182522 0.044486 0.467389 -0.181824 0.04438 0.470309 -0.182522 0.044486 0.467389 -0.182664 0.043739 0.468849 -0.181824 0.04438 0.470309 -0.181892 0.0454398 0.466361 -0.182522 0.044486 0.467389 -0.181835 0.0451832 0.468155 -0.182664 0.043739 0.468849 -0.183231 0.042905 0.468936 -0.181824 0.04438 0.470309 -0.18185 0.042749 0.473146 -0.18168 0.0427767 0.473098 -0.181824 0.04438 0.470309 -0.18168 0.0427767 0.473098 -0.181678 0.042749 0.473146 -0.18185 0.042749 0.473146 -0.181824 0.04438 0.470309 -0.183231 0.042905 0.468936 -0.18185 0.042749 0.473146 -0.182 0.0458 0.46297 -0.181967 0.0455904 0.463997 -0.181952 0.0456116 0.464491 -0.182 0.0458 0.46297 -0.182 0.0454548 0.462976 -0.181967 0.0455904 0.463997 -0.182 0.0454548 0.462976 -0.182143 0.0453111 0.463487 -0.181967 0.0455904 0.463997 -0.182 0.0454548 0.462976 -0.181994 0.0454471 0.462799 -0.182 0.0458 0.46297 -0.181833 0.0446724 0.458122 -0.182039 0.0448422 0.45963 -0.181838 0.0447635 0.45843 -0.183718 0.04304 0.464381 -0.184636 0.040948 0.465911 -0.183684 0.043006 0.465529 -0.184745 0.041005 0.464447 -0.184636 0.040948 0.465911 -0.183718 0.04304 0.464381 -0.183265 0.043175 0.459821 -0.184745 0.041005 0.464447 -0.183718 0.04304 0.464381 -0.182543 0.044611 0.461138 -0.183265 0.043175 0.459821 -0.183718 0.04304 0.464381 -0.182543 0.044611 0.461138 -0.183718 0.04304 0.464381 -0.18277 0.044549 0.464265 -0.181833 0.0446724 0.458122 -0.183265 0.043175 0.459821 -0.182543 0.044611 0.461138 -0.183994 0.041234 0.458639 -0.18405 0.0415824 0.459762 -0.183785 0.0421116 0.459762 -0.18405 0.0415824 0.459762 -0.184498 0.041145 0.460885 -0.183785 0.0421116 0.459762 -0.183785 0.0421116 0.459762 -0.184498 0.041145 0.460885 -0.183265 0.043175 0.459821 -0.183265 0.043175 0.459821 -0.184498 0.041145 0.460885 -0.184745 0.041005 0.464447 -0.185662 0.021164 0.456439 -0.184745 0.041005 0.464447 -0.184498 0.041145 0.460885 -0.184498 0.041145 0.460885 -0.183994 0.041234 0.458639 -0.185662 0.021164 0.456439 -0.183994 0.041234 0.458639 -0.183731 0.041281 0.457465 -0.185662 0.021164 0.456439 -0.183731 0.041281 0.457465 -0.182879 0.0413719 0.455285 -0.185662 0.021164 0.456439 -0.183731 0.041281 0.457465 -0.18191 0.041463 0.453145 -0.182879 0.0413719 0.455285 -0.183731 0.041281 0.457465 -0.183994 0.041234 0.458639 -0.183265 0.043175 0.459821 -0.181833 0.0446724 0.458122 -0.182543 0.044611 0.461138 -0.182039 0.0448422 0.45963 -0.18405 0.0415824 0.459762 -0.183994 0.041234 0.458639 -0.184498 0.041145 0.460885 -0.18185 0.042749 0.473146 -0.181604 0.0406156 0.47553 -0.181678 0.042749 0.473146 -0.181601 0.040554 0.475599 -0.181744 0.038902 0.476593 -0.181543 0.0373822 0.477508 -0.181543 0.0373822 0.477508 -0.181744 0.038902 0.476593 -0.181945 0.03725 0.477588 -0.181601 0.040554 0.475599 -0.181885 0.040554 0.475599 -0.181744 0.038902 0.476593 -0.181604 0.0406156 0.47553 -0.181601 0.040554 0.475599 -0.181885 0.040554 0.475599 -0.181885 0.040554 0.475599 -0.181604 0.0406156 0.47553 -0.18185 0.042749 0.473146 -0.18154 0.03725 0.477588 -0.181767 0.035409 0.478004 -0.181517 0.0337511 0.478379 -0.18154 0.03725 0.477588 -0.181945 0.03725 0.477588 -0.181767 0.035409 0.478004 -0.182018 0.033568 0.47842 -0.181945 0.03725 0.477588 -0.185626 0.021236 0.471465 -0.181945 0.03725 0.477588 -0.181885 0.040554 0.475599 -0.185626 0.021236 0.471465 -0.181945 0.03725 0.477588 -0.182018 0.033568 0.47842 -0.181767 0.035409 0.478004 -0.181517 0.0337511 0.478379 -0.181767 0.035409 0.478004 -0.182018 0.033568 0.47842 -0.181959 0.045582 0.46426 -0.182706 0.044517 0.465835 -0.182059 0.045473 0.464903 -0.185662 0.021164 0.456439 -0.182292 0.02114 0.449445 -0.185622 0.000539009 0.456468 -0.18677 0.0212 0.463955 -0.185662 0.021164 0.456439 -0.185622 0.000539009 0.456468 -0.18677 0.0212 0.463955 -0.185622 0.000539009 0.456468 -0.186667 0.000539009 0.463955 -0.182448 -0.000294009 0.449445 -0.182448 0.000294009 0.449445 -0.181576 0.000441008 0.449445 -0.181576 -0.000441008 0.449445 -0.182448 -0.000294009 0.449445 -0.181576 0.000441008 0.449445 -0.181558 -0.00734142 0.449445 -0.18199 -0.0065925 0.449445 -0.181576 -0.000441008 0.449445 -0.18199 -0.0065925 0.449445 -0.182448 -0.000294009 0.449445 -0.181576 -0.000441008 0.449445 -0.182448 0.000294009 0.449445 -0.182448 -0.000294009 0.449445 -0.185622 -0.000539009 0.456468 -0.185622 -0.000539009 0.456468 -0.182448 -0.000294009 0.449445 -0.182396 -0.012891 0.449445 -0.181558 -0.00734142 0.449445 -0.182396 -0.012891 0.449445 -0.18199 -0.0065925 0.449445 -0.185622 0.000539009 0.456468 -0.182448 0.000294009 0.449445 -0.185622 -0.000539009 0.456468 -0.186667 0.000539009 0.463955 -0.185622 0.000539009 0.456468 -0.186667 -0.000539009 0.463955 -0.185622 0.000539009 0.456468 -0.185622 -0.000539009 0.456468 -0.186667 -0.000539009 0.463955 -0.182396 0.012891 0.449445 -0.182448 0.000294009 0.449445 -0.185622 0.000539009 0.456468 -0.183684 0.043006 0.465529 -0.184489 0.040872 0.46787 -0.183592 0.042972 0.466673 -0.183684 0.043006 0.465529 -0.183592 0.042972 0.466673 -0.182706 0.044517 0.465835 -0.182706 0.044517 0.465835 -0.183592 0.042972 0.466673 -0.183231 0.042905 0.468936 -0.183231 0.042905 0.468936 -0.183592 0.042972 0.466673 -0.183716 0.040736 0.471286 -0.183973 0.040781 0.470148 -0.18677 0.0212 0.463955 -0.185626 0.021236 0.471465 -0.183716 0.040736 0.471286 -0.183973 0.040781 0.470148 -0.185626 0.021236 0.471465 -0.182914 0.040645 0.473486 -0.183716 0.040736 0.471286 -0.185626 0.021236 0.471465 -0.183973 0.040781 0.470148 -0.184489 0.040872 0.46787 -0.18677 0.0212 0.463955 -0.183231 0.042905 0.468936 -0.183716 0.040736 0.471286 -0.182914 0.040645 0.473486 -0.182914 0.040645 0.473486 -0.181885 0.040554 0.475599 -0.183231 0.042905 0.468936 -0.184636 0.040948 0.465911 -0.18677 0.0212 0.463955 -0.184489 0.040872 0.46787 -0.185626 0.021236 0.471465 -0.18677 0.0212 0.463955 -0.186667 0.000539009 0.463955 -0.183592 0.042972 0.466673 -0.183973 0.040781 0.470148 -0.183716 0.040736 0.471286 -0.181967 0.0455904 0.463997 -0.18277 0.044549 0.464265 -0.181959 0.045582 0.46426 -0.182343 0.0450501 0.463532 -0.18277 0.044549 0.464265 -0.181967 0.0455904 0.463997 -0.181959 0.045582 0.46426 -0.18277 0.044549 0.464265 -0.182706 0.044517 0.465835 -0.18277 0.044549 0.464265 -0.183684 0.043006 0.465529 -0.182706 0.044517 0.465835 -0.181576 0.000441008 0.449445 -0.182448 0.000294009 0.449445 -0.18199 0.0065925 0.449445 -0.185622 -0.000539009 0.456468 -0.182396 -0.012891 0.449445 -0.182292 -0.02114 0.449445 -0.181502 0.0204813 0.449445 -0.182292 0.02114 0.449445 -0.181502 0.02114 0.449445 -0.18185 -0.042749 0.473146 -0.181678 -0.042749 0.473146 -0.181604 -0.0406156 0.47553 -0.181527 -0.013635 0.478445 -0.181527 -0.012981 0.478445 -0.182325 -0.012981 0.478445 -0.181924 -0.01712 0.478445 -0.181527 -0.013635 0.478445 -0.182325 -0.012981 0.478445 -0.181522 -0.0215476 0.478445 -0.181522 -0.021259 0.478445 -0.182223 -0.021259 0.478445 -0.182325 -0.012981 0.478445 -0.181527 -0.012981 0.478445 -0.18153 -0.0077485 0.478445 -0.182173 0.025398 0.478445 -0.185626 0.021236 0.471465 -0.182223 0.021259 0.478445 -0.181871 0.0233285 0.478445 -0.182173 0.025398 0.478445 -0.182223 0.021259 0.478445 -0.182223 0.021259 0.478445 -0.181522 0.0215476 0.478445 -0.181871 0.0233285 0.478445 -0.18152 0.025398 0.478445 -0.181871 0.0233285 0.478445 -0.181522 0.0215476 0.478445 -0.181871 0.0233285 0.478445 -0.18152 0.025398 0.478445 -0.182173 0.025398 0.478445 -0.18152 0.025398 0.478445 -0.18152 0.0259237 0.478443 -0.182173 0.025398 0.478445 -0.182173 0.025398 0.478445 -0.181844 0.029483 0.478432 -0.182018 0.033568 0.47842 -0.181516 0.033568 0.47842 -0.182018 0.033568 0.47842 -0.181844 0.029483 0.478432 -0.18152 0.0259237 0.478443 -0.181844 0.029483 0.478432 -0.182173 0.025398 0.478445 -0.182223 0.021259 0.478445 -0.185626 0.021236 0.471465 -0.185585 0.000539009 0.471437 -0.181516 0.033568 0.47842 -0.181844 0.029483 0.478432 -0.18152 0.0259237 0.478443 -0.185585 0.000539009 0.471437 -0.182325 0.012981 0.478445 -0.182223 0.021259 0.478445 -0.181522 -0.0215476 0.478445 -0.181871 -0.0233285 0.478445 -0.18152 -0.025398 0.478445 -0.182173 -0.025398 0.478445 -0.18152 -0.025398 0.478445 -0.181871 -0.0233285 0.478445 -0.182223 -0.021259 0.478445 -0.182173 -0.025398 0.478445 -0.181871 -0.0233285 0.478445 -0.182223 -0.021259 0.478445 -0.185626 -0.021236 0.471465 -0.182173 -0.025398 0.478445 -0.181885 -0.040554 0.475599 -0.18185 -0.042749 0.473146 -0.181604 -0.0406156 0.47553 -0.181601 -0.040554 0.475599 -0.181604 -0.0406156 0.47553 -0.181885 -0.040554 0.475599 -0.183231 -0.042905 0.468936 -0.18185 -0.042749 0.473146 -0.181885 -0.040554 0.475599 -0.181885 -0.040554 0.475599 -0.182914 -0.040645 0.473486 -0.183231 -0.042905 0.468936 -0.185626 -0.021236 0.471465 -0.182914 -0.040645 0.473486 -0.181885 -0.040554 0.475599 -0.185626 -0.021236 0.471465 -0.183716 -0.040736 0.471286 -0.182914 -0.040645 0.473486 -0.183592 -0.042972 0.466673 -0.183231 -0.042905 0.468936 -0.183716 -0.040736 0.471286 -0.183973 -0.040781 0.470148 -0.183592 -0.042972 0.466673 -0.183716 -0.040736 0.471286 -0.182376 -0.00029401 0.478445 -0.185585 -0.000539009 0.471437 -0.182325 -0.012981 0.478445 -0.185585 -0.000539009 0.471437 -0.182376 -0.00029401 0.478445 -0.182376 0.00029401 0.478445 -0.18153 0.00136144 0.478445 -0.182376 0.00029401 0.478445 -0.18153 -0.00136144 0.478445 -0.182376 0.00029401 0.478445 -0.18153 0.00136144 0.478445 -0.181952 0.00663751 0.478445 -0.185585 0.000539009 0.471437 -0.185585 -0.000539009 0.471437 -0.182376 0.00029401 0.478445 -0.185585 0.000539009 0.471437 -0.182376 0.00029401 0.478445 -0.182325 0.012981 0.478445 -0.18153 0.0077485 0.478445 -0.181952 0.00663751 0.478445 -0.18153 0.00136144 0.478445 -0.18153 0.0077485 0.478445 -0.182325 0.012981 0.478445 -0.181952 0.00663751 0.478445 -0.18153 0.0077485 0.478445 -0.181527 0.012981 0.478445 -0.182325 0.012981 0.478445 -0.182325 0.012981 0.478445 -0.182376 0.00029401 0.478445 -0.181952 0.00663751 0.478445 -0.181527 0.012981 0.478445 -0.181527 0.013635 0.478445 -0.182325 0.012981 0.478445 -0.185585 0.000539009 0.471437 -0.186667 -0.000539009 0.463955 -0.185585 -0.000539009 0.471437 -0.185585 -0.000539009 0.471437 -0.185626 -0.021236 0.471465 -0.182223 -0.021259 0.478445 -0.185585 -0.000539009 0.471437 -0.186667 -0.000539009 0.463955 -0.185626 -0.021236 0.471465 -0.18677 -0.0212 0.463955 -0.185626 -0.021236 0.471465 -0.186667 -0.000539009 0.463955 -0.185626 -0.021236 0.471465 -0.18677 -0.0212 0.463955 -0.183973 -0.040781 0.470148 -0.18677 -0.0212 0.463955 -0.184489 -0.040872 0.46787 -0.183973 -0.040781 0.470148 -0.183973 -0.040781 0.470148 -0.183716 -0.040736 0.471286 -0.185626 -0.021236 0.471465 -0.184636 -0.040948 0.465911 -0.184489 -0.040872 0.46787 -0.18677 -0.0212 0.463955 -0.183684 -0.043006 0.465529 -0.183592 -0.042972 0.466673 -0.184489 -0.040872 0.46787 -0.183684 -0.043006 0.465529 -0.182706 -0.044517 0.465835 -0.183592 -0.042972 0.466673 -0.184636 -0.040948 0.465911 -0.183684 -0.043006 0.465529 -0.184489 -0.040872 0.46787 -0.182325 -0.012981 0.478445 -0.185585 -0.000539009 0.471437 -0.182223 -0.021259 0.478445 -0.182173 -0.025398 0.478445 -0.185626 -0.021236 0.471465 -0.182018 -0.033568 0.47842 -0.182018 -0.033568 0.47842 -0.185626 -0.021236 0.471465 -0.181945 -0.03725 0.477588 -0.181601 -0.040554 0.475599 -0.181744 -0.038902 0.476593 -0.181885 -0.040554 0.475599 -0.181767 -0.035409 0.478004 -0.182018 -0.033568 0.47842 -0.181945 -0.03725 0.477588 -0.18154 -0.03725 0.477588 -0.181767 -0.035409 0.478004 -0.181945 -0.03725 0.477588 -0.181517 -0.0337511 0.478379 -0.182018 -0.033568 0.47842 -0.181767 -0.035409 0.478004 -0.182018 -0.033568 0.47842 -0.181516 -0.033568 0.47842 -0.181517 -0.0337511 0.478379 -0.18152 -0.0259237 0.478443 -0.181844 -0.029483 0.478432 -0.181516 -0.033568 0.47842 -0.18152 -0.0259237 0.478443 -0.182173 -0.025398 0.478445 -0.181844 -0.029483 0.478432 -0.181516 -0.033568 0.47842 -0.181844 -0.029483 0.478432 -0.182018 -0.033568 0.47842 -0.181517 -0.0337511 0.478379 -0.181767 -0.035409 0.478004 -0.18154 -0.03725 0.477588 -0.181522 0.021259 0.478445 -0.181522 0.0215476 0.478445 -0.182223 0.021259 0.478445 -0.181527 0.013635 0.478445 -0.181522 0.021259 0.478445 -0.181924 0.01712 0.478445 -0.181924 0.01712 0.478445 -0.181522 0.021259 0.478445 -0.182223 0.021259 0.478445 -0.183716 -0.040736 0.471286 -0.183231 -0.042905 0.468936 -0.182914 -0.040645 0.473486 -0.181945 -0.03725 0.477588 -0.185626 -0.021236 0.471465 -0.181885 -0.040554 0.475599 -0.182018 -0.033568 0.47842 -0.181844 -0.029483 0.478432 -0.182173 -0.025398 0.478445 -0.181952 -0.00663751 0.478445 -0.182376 -0.00029401 0.478445 -0.182325 -0.012981 0.478445 -0.181952 -0.00663751 0.478445 -0.182325 -0.012981 0.478445 -0.18153 -0.0077485 0.478445 -0.18153 -0.00136144 0.478445 -0.181952 -0.00663751 0.478445 -0.18153 -0.0077485 0.478445 -0.181952 -0.00663751 0.478445 -0.18153 -0.00136144 0.478445 -0.182376 -0.00029401 0.478445 -0.184489 -0.040872 0.46787 -0.183592 -0.042972 0.466673 -0.183973 -0.040781 0.470148 -0.182396 -0.012891 0.449445 -0.182448 -0.000294009 0.449445 -0.18199 -0.0065925 0.449445 -0.182522 0.044486 0.467389 -0.183231 0.042905 0.468936 -0.182664 0.043739 0.468849 -0.182543 -0.044611 0.461138 -0.18193 -0.0453752 0.461 -0.181971 -0.0454295 0.462175 -0.183592 -0.042972 0.466673 -0.182706 -0.044517 0.465835 -0.183231 -0.042905 0.468936 -0.181945 -0.03725 0.477588 -0.18154 -0.03725 0.477588 -0.181543 -0.0373822 0.477508 -0.182 0.0454548 0.462976 -0.182343 0.0450501 0.463532 -0.182143 0.0453111 0.463487 -0.181948 0.0170155 0.449445 -0.182292 0.02114 0.449445 -0.181502 0.0204813 0.449445 -0.18199 0.0065925 0.449445 -0.182448 0.000294009 0.449445 -0.182396 0.012891 0.449445 -0.186667 -0.000539009 0.463955 -0.185585 0.000539009 0.471437 -0.186667 0.000539009 0.463955 -0.181871 -0.0233285 0.478445 -0.181522 -0.0215476 0.478445 -0.182223 -0.021259 0.478445 -0.182376 0.00029401 0.478445 -0.182376 -0.00029401 0.478445 -0.18153 -0.00136144 0.478445 -0.182706 0.044517 0.465835 -0.183231 0.042905 0.468936 -0.182522 0.044486 0.467389 -0.18187 0.043309 0.455483 -0.183265 0.043175 0.459821 -0.181833 0.0446724 0.458122 -0.18187 0.043309 0.455483 -0.18191 0.041463 0.453145 -0.183265 0.043175 0.459821 -0.18187 0.043309 0.455483 -0.181731 0.0432947 0.455465 -0.18191 0.041463 0.453145 -0.18187 0.043309 0.455483 -0.181833 0.0446724 0.458122 -0.181731 0.0432947 0.455465 -0.18191 0.041463 0.453145 -0.181731 0.0432947 0.455465 -0.181647 0.041463 0.453145 -0.18185 0.042749 0.473146 -0.183231 0.042905 0.468936 -0.181885 0.040554 0.475599 -0.184498 -0.041145 0.460885 -0.184745 -0.041005 0.464447 -0.185662 -0.021164 0.456439 -0.184745 -0.041005 0.464447 -0.18677 -0.0212 0.463955 -0.185662 -0.021164 0.456439 -0.185622 -0.000539009 0.456468 -0.185662 -0.021164 0.456439 -0.18677 -0.0212 0.463955 -0.181885 0.040554 0.475599 -0.182914 0.040645 0.473486 -0.185626 0.021236 0.471465 -0.183994 0.041234 0.458639 -0.183785 0.0421116 0.459762 -0.183265 0.043175 0.459821 -0.186667 -0.000539009 0.463955 -0.185622 -0.000539009 0.456468 -0.18677 -0.0212 0.463955 -0.182223 -0.021259 0.478445 -0.181522 -0.021259 0.478445 -0.181924 -0.01712 0.478445 -0.181511 -0.0331348 0.44947 -0.181873 -0.0294405 0.449459 -0.181505 -0.025265 0.449445 -0.185662 -0.021164 0.456439 -0.18203 -0.035793 0.449824 -0.181964 -0.038924 0.451127 -0.181678 -0.042749 0.473146 -0.18168 -0.0427767 0.473098 -0.18185 -0.042749 0.473146 -0.181945 0.03725 0.477588 -0.181543 0.0373822 0.477508 -0.18154 0.03725 0.477588 -0.182039 0.0448422 0.45963 -0.182543 0.044611 0.461138 -0.18193 0.0453752 0.461 -0.181948 -0.0170155 0.449445 -0.182292 -0.02114 0.449445 -0.182396 -0.012891 0.449445 -0.181948 -0.0170155 0.449445 -0.182396 -0.012891 0.449445 -0.181525 -0.012891 0.449445 -0.181525 0.035793 0.449824 -0.18203 0.035793 0.449824 -0.181778 0.0373585 0.450476 -0.18191 0.041463 0.453145 -0.181645 0.0413955 0.453091 -0.181647 0.041463 0.453145 -0.182143 0.0453111 0.463487 -0.182343 0.0450501 0.463532 -0.181967 0.0455904 0.463997 -0.181576 0.000441008 0.449445 -0.18199 0.0065925 0.449445 -0.181558 0.00734142 0.449445 -0.185626 0.021236 0.471465 -0.186667 0.000539009 0.463955 -0.185585 0.000539009 0.471437 -0.182018 0.033568 0.47842 -0.185626 0.021236 0.471465 -0.182173 0.025398 0.478445 -0.183718 0.04304 0.464381 -0.183684 0.043006 0.465529 -0.18277 0.044549 0.464265 -0.181952 -0.0456116 0.464491 -0.181959 -0.045582 0.46426 -0.182059 -0.045473 0.464903 -0.182879 0.0413719 0.455285 -0.18191 0.041463 0.453145 -0.185662 0.021164 0.456439 -0.185662 -0.021164 0.456439 -0.181964 -0.038924 0.451127 -0.18191 -0.041463 0.453145 -0.185662 -0.021164 0.456439 -0.18191 -0.041463 0.453145 -0.182879 -0.0413719 0.455285 -0.183731 -0.041281 0.457465 -0.182879 -0.0413719 0.455285 -0.18191 -0.041463 0.453145 -0.185662 -0.021164 0.456439 -0.182879 -0.0413719 0.455285 -0.183731 -0.041281 0.457465 -0.181525 0.035793 0.449824 -0.181778 0.0373585 0.450476 -0.181572 0.0388005 0.451076 -0.184745 -0.041005 0.464447 -0.184636 -0.040948 0.465911 -0.18677 -0.0212 0.463955 -0.181952 0.0456116 0.464491 -0.181959 0.045582 0.46426 -0.181967 0.0455904 0.463997 -0.181512 0.033616 0.449472 -0.181511 0.0331348 0.44947 -0.182078 0.033616 0.449472 -0.181824 0.04438 0.470309 -0.18168 0.0427767 0.473098 -0.181767 0.04438 0.470309 -0.181744 0.038902 0.476593 -0.181885 0.040554 0.475599 -0.181945 0.03725 0.477588 -0.184745 -0.041005 0.464447 -0.183718 -0.04304 0.464381 -0.184636 -0.040948 0.465911 -0.181838 0.0447635 0.45843 -0.182039 0.0448422 0.45963 -0.18193 0.0453752 0.461 -0.181744 -0.038902 0.476593 -0.181945 -0.03725 0.477588 -0.181885 -0.040554 0.475599 -0.185622 -0.000539009 0.456468 -0.182292 -0.02114 0.449445 -0.185662 -0.021164 0.456439 -0.181525 -0.012891 0.449445 -0.182396 -0.012891 0.449445 -0.181532 -0.0117967 0.449445 -0.18191 -0.041463 0.453145 -0.181647 -0.041463 0.453145 -0.181731 -0.0432947 0.455465 -0.182664 -0.043739 0.468849 -0.181824 -0.04438 0.470309 -0.183231 -0.042905 0.468936 -0.1815 -0.0172285 0.449445 -0.181948 -0.0170155 0.449445 -0.181525 -0.012891 0.449445 -0.181914 -0.0455268 0.465668 -0.182059 -0.045473 0.464903 -0.181952 -0.0456116 0.464491 -0.185662 -0.021164 0.456439 -0.183731 -0.041281 0.457465 -0.183994 -0.041234 0.458639 -0.181835 0.0451832 0.468155 -0.182522 0.044486 0.467389 -0.181816 0.0449778 0.468768 -0.181525 -0.0356825 0.449806 -0.18203 -0.035793 0.449824 -0.181795 -0.0347045 0.449648 -0.182 -0.0458 0.46297 -0.181994 -0.0454471 0.462799 -0.182 -0.0454548 0.462976 -0.181959 -0.045582 0.46426 -0.182059 -0.045473 0.464903 -0.182706 -0.044517 0.465835 -0.181505 -0.0249602 0.449445 -0.18224 -0.025265 0.449445 -0.181897 -0.0232025 0.449445 -0.181795 0.0347045 0.449648 -0.182078 0.033616 0.449472 -0.18203 0.035793 0.449824 -0.182396 0.012891 0.449445 -0.185622 0.000539009 0.456468 -0.182292 0.02114 0.449445 -0.183231 -0.042905 0.468936 -0.181824 -0.04438 0.470309 -0.18185 -0.042749 0.473146 -0.183265 -0.043175 0.459821 -0.183731 -0.041281 0.457465 -0.18191 -0.041463 0.453145 -0.184745 0.041005 0.464447 -0.18677 0.0212 0.463955 -0.184636 0.040948 0.465911 -0.181502 0.02114 0.449445 -0.181897 0.0232025 0.449445 -0.181505 0.0249602 0.449445 -0.18224 0.025265 0.449445 -0.182292 0.02114 0.449445 -0.185662 0.021164 0.456439 -0.18152 -0.0259237 0.478443 -0.18152 -0.025398 0.478445 -0.182173 -0.025398 0.478445 -0.18203 0.035793 0.449824 -0.182078 0.033616 0.449472 -0.185662 0.021164 0.456439 -0.181543 -0.0373822 0.477508 -0.181945 -0.03725 0.477588 -0.181744 -0.038902 0.476593 -0.181527 -0.013635 0.478445 -0.181924 -0.01712 0.478445 -0.181522 -0.021259 0.478445 -0.185662 0.021164 0.456439 -0.18677 0.0212 0.463955 -0.184745 0.041005 0.464447 -0.181558 0.00734142 0.449445 -0.18199 0.0065925 0.449445 -0.182396 0.012891 0.449445 -0.181543 -0.0373822 0.477508 -0.181744 -0.038902 0.476593 -0.181601 -0.040554 0.475599 -0.182343 0.0450501 0.463532 -0.181994 0.0454471 0.462799 -0.182 0.0454548 0.462976 -0.18405 -0.0415824 0.459762 -0.183785 -0.0421116 0.459762 -0.184498 -0.041145 0.460885 -0.181914 0.0455268 0.465668 -0.182522 0.044486 0.467389 -0.181892 0.0454398 0.466361 -0.182706 -0.044517 0.465835 -0.182522 -0.044486 0.467389 -0.183231 -0.042905 0.468936 -0.183684 0.043006 0.465529 -0.184636 0.040948 0.465911 -0.184489 0.040872 0.46787 -0.182 -0.0454548 0.462976 -0.182143 -0.0453111 0.463487 -0.182343 -0.0450501 0.463532 -0.182223 0.021259 0.478445 -0.182325 0.012981 0.478445 -0.181924 0.01712 0.478445 -0.182325 0.012981 0.478445 -0.181527 0.013635 0.478445 -0.181924 0.01712 0.478445 -0.18191 0.041463 0.453145 -0.183731 0.041281 0.457465 -0.183265 0.043175 0.459821 -0.182018 0.033568 0.47842 -0.181517 0.0337511 0.478379 -0.181516 0.033568 0.47842 -0.182543 0.044611 0.461138 -0.18277 0.044549 0.464265 -0.182352 0.044975 0.462701 -0.18191 0.041463 0.453145 -0.181964 0.038924 0.451127 -0.185662 0.021164 0.456439 -0.182325 -0.012981 0.478445 -0.182223 -0.021259 0.478445 -0.181924 -0.01712 0.478445 -0.18203 0.035793 0.449824 -0.181525 0.0356825 0.449806 -0.181525 0.035793 0.449824 -0.181511 -0.0331348 0.44947 -0.181512 -0.033616 0.449472 -0.182078 -0.033616 0.449472 -0.181971 0.0454295 0.462175 -0.182352 0.044975 0.462701 -0.181994 0.0454471 0.462799 -0.182343 -0.0450501 0.463532 -0.181967 -0.0455904 0.463997 -0.18277 -0.044549 0.464265 -0.183592 0.042972 0.466673 -0.184489 0.040872 0.46787 -0.183973 0.040781 0.470148 -0.18277 -0.044549 0.464265 -0.182706 -0.044517 0.465835 -0.183684 -0.043006 0.465529 -0.183718 -0.04304 0.464381 -0.183684 -0.043006 0.465529 -0.184636 -0.040948 0.465911 -0.181532 -0.0117967 0.449445 -0.182396 -0.012891 0.449445 -0.181558 -0.00734142 0.449445 0.028865 0.166727 0.529002 0.027898 0.184147 0.525343 -0.017415 0.155075 0.531201 0.027898 0.184147 0.525343 -0.016909 0.16601 0.529141 -0.017415 0.155075 0.531201 0.030251 0.126841 0.535478 0.029966 0.138364 0.53387 -0.018422 0.116231 0.536733 0.029966 0.138364 0.53387 -0.018277 0.12598 0.535587 -0.018422 0.116231 0.536733 -0.018277 0.12598 0.535587 -0.024554 0.137067 0.519905 -0.018422 0.116231 0.536733 -0.017415 0.155075 0.531201 -0.024554 0.137067 0.519905 -0.018 0.13747 0.534 -0.024554 0.137067 0.519905 -0.018277 0.12598 0.535587 -0.018 0.13747 0.534 0.029382 0.155634 0.531104 -0.018 0.13747 0.534 -0.018277 0.12598 0.535587 -0.024554 0.137067 0.519905 -0.02773 0.109432 0.515904 -0.018422 0.116231 0.536733 -0.024554 0.137067 0.519905 -0.0285973 0.12325 0.5094880000000001 -0.02773 0.109432 0.515904 -0.0285973 0.12325 0.5094880000000001 -0.024554 0.137067 0.519905 -0.032289 0.11468 0.498968 0.036496 0.138225 0.519829 0.03888 0.123504 0.516133 0.042614 0.110851 0.509057 0.036496 0.138225 0.519829 0.042782 0.144342 0.505161 0.034765 0.168787 0.517478 0.034765 0.168787 0.517478 0.0327356 0.153506 0.524613 0.036496 0.138225 0.519829 0.029382 0.155634 0.531104 0.0327356 0.153506 0.524613 0.034765 0.168787 0.517478 0.042614 0.110851 0.509057 0.042782 0.144342 0.505161 0.036496 0.138225 0.519829 0.042782 0.144342 0.505161 0.042614 0.110851 0.509057 0.044333 0.113765 0.497681 0.042851 0.146615 0.495161 0.042782 0.144342 0.505161 0.044333 0.113765 0.497681 0.042851 0.146615 0.495161 0.044333 0.113765 0.497681 0.0430399 0.113546 0.495482 0.0418501 0.115831 0.495582 0.042851 0.146615 0.495161 0.0430399 0.113546 0.495482 0.0418501 0.115831 0.495582 0.0389407 0.115743 0.495884 0.042851 0.146615 0.495161 0.0389407 0.115743 0.495884 0.036776 0.207522 0.495162 0.042851 0.146615 0.495161 0.0353254 0.166193 0.495523 0.036776 0.207522 0.495162 0.0389407 0.115743 0.495884 0.036776 0.207522 0.495162 0.04057 0.174052 0.505161 0.042851 0.146615 0.495161 0.0286168 0.115555 0.495963 0.0115814 0.168929 0.495563 0.021304 0.221848 0.495162 0.0286168 0.115555 0.495963 0.0104799 0.115243 0.495969 0.0115814 0.168929 0.495563 0.0104799 0.115243 0.495969 -0.005454 0.222616 0.495162 0.0115814 0.168929 0.495563 0.0104799 0.115243 0.495969 -0.00298356 0.168863 0.495553 -0.005454 0.222616 0.495162 0.0104799 0.115243 0.495969 0.00256593 0.115109 0.495951 -0.00298356 0.168863 0.495553 0.036662 0.207233 0.505162 0.04057 0.174052 0.505161 0.036776 0.207522 0.495162 0.021304 0.221848 0.495162 -0.005454 0.222441 0.505162 0.005425 0.222441 0.505162 0.022799 0.221273 0.505162 0.021304 0.221848 0.495162 0.005425 0.222441 0.505162 0.022799 0.221273 0.505162 0.005425 0.222441 0.505162 0.005415 0.209866 0.513713 0.020683 0.20953 0.513752 0.022799 0.221273 0.505162 0.005415 0.209866 0.513713 0.005415 0.209866 0.513713 -0.015921 0.183938 0.525392 0.020683 0.20953 0.513752 -0.005454 0.222441 0.505162 0.021304 0.221848 0.495162 -0.005454 0.222616 0.495162 -0.005454 0.222616 0.495162 -0.016907 0.218152 0.505162 -0.005454 0.222441 0.505162 0.024948 0.196933 0.5217540000000001 0.020683 0.20953 0.513752 -0.015921 0.183938 0.525392 -0.018406 0.20154 0.514412 -0.022856 0.167634 0.51758 -0.016909 0.16601 0.529141 -0.015921 0.183938 0.525392 -0.018406 0.20154 0.514412 -0.016909 0.16601 0.529141 -0.018406 0.20154 0.514412 -0.015921 0.183938 0.525392 -0.009838 0.209233 0.513783 -0.018406 0.20154 0.514412 -0.024259 0.208573 0.505162 -0.022856 0.167634 0.51758 -0.015921 0.183938 0.525392 -0.016909 0.16601 0.529141 0.024948 0.196933 0.5217540000000001 0.034765 0.168787 0.517478 0.036662 0.207233 0.505162 0.029815 0.202535 0.514327 0.036662 0.207233 0.505162 0.034765 0.168787 0.517478 0.04057 0.174052 0.505161 0.034765 0.168787 0.517478 0.029815 0.202535 0.514327 0.027898 0.184147 0.525343 0.029815 0.202535 0.514327 0.024948 0.196933 0.5217540000000001 0.027898 0.184147 0.525343 0.029815 0.202535 0.514327 0.020683 0.20953 0.513752 0.024948 0.196933 0.5217540000000001 -0.016909 0.16601 0.529141 0.027898 0.184147 0.525343 0.024948 0.196933 0.5217540000000001 -0.016909 0.16601 0.529141 -0.022856 0.167634 0.51758 -0.017415 0.155075 0.531201 -0.016447 0.218894 0.495162 -0.00298356 0.168863 0.495553 0.00256593 0.115109 0.495951 -0.024787 0.207522 0.495162 -0.0111103 0.166942 0.495522 -0.00482529 0.11499 0.49589 0.00256593 0.115109 0.495951 -0.00482529 0.11499 0.49589 -0.0111103 0.166942 0.495522 -0.00482529 0.11499 0.49589 -0.0223878 0.114438 0.49787 -0.024787 0.207522 0.495162 -0.0223878 0.114438 0.49787 -0.032289 0.11468 0.498968 -0.024787 0.207522 0.495162 -0.0111103 0.166942 0.495522 -0.016447 0.218894 0.495162 0.00256593 0.115109 0.495951 -0.016907 0.218152 0.505162 -0.018406 0.20154 0.514412 -0.009838 0.209233 0.513783 0.0284417 0.168702 0.495549 0.0286168 0.115555 0.495963 0.021304 0.221848 0.495162 0.03171 0.216707 0.495162 0.0284417 0.168702 0.495549 0.021304 0.221848 0.495162 0.029815 0.202535 0.514327 0.036662 0.207233 0.505162 0.032177 0.21585 0.505162 0.032177 0.21585 0.505162 0.022799 0.221273 0.505162 0.029815 0.202535 0.514327 0.03171 0.216707 0.495162 0.036776 0.207522 0.495162 0.0353254 0.166193 0.495523 0.03171 0.216707 0.495162 0.0353254 0.166193 0.495523 0.0355793 0.115678 0.495935 -0.005454 0.222441 0.505162 -0.016907 0.218152 0.505162 -0.009838 0.209233 0.513783 0.005415 0.209866 0.513713 -0.005454 0.222441 0.505162 -0.009838 0.209233 0.513783 0.04057 0.174052 0.505161 0.042782 0.144342 0.505161 0.042851 0.146615 0.495161 -0.024259 0.208573 0.505162 -0.018406 0.20154 0.514412 -0.016907 0.218152 0.505162 -0.024787 0.207522 0.495162 -0.016907 0.218152 0.505162 -0.016447 0.218894 0.495162 -0.024259 0.208573 0.505162 -0.016907 0.218152 0.505162 -0.024787 0.207522 0.495162 -0.024787 0.207522 0.495162 -0.028607 0.173621 0.505162 -0.024259 0.208573 0.505162 -0.028607 0.173621 0.505162 -0.024787 0.207522 0.495162 -0.030946 0.141824 0.505162 -0.0111103 0.166942 0.495522 -0.024787 0.207522 0.495162 -0.016447 0.218894 0.495162 0.036776 0.207522 0.495162 0.032177 0.21585 0.505162 0.036662 0.207233 0.505162 -0.005454 0.222441 0.505162 0.005415 0.209866 0.513713 0.005425 0.222441 0.505162 -0.024259 0.208573 0.505162 -0.028607 0.173621 0.505162 -0.022856 0.167634 0.51758 0.021304 0.221848 0.495162 0.0115814 0.168929 0.495563 -0.005454 0.222616 0.495162 0.0355793 0.115678 0.495935 0.0284417 0.168702 0.495549 0.03171 0.216707 0.495162 -0.017415 0.155075 0.531201 -0.022856 0.167634 0.51758 -0.024554 0.137067 0.519905 -0.022856 0.167634 0.51758 -0.030946 0.141824 0.505162 -0.024554 0.137067 0.519905 0.0327356 0.153506 0.524613 0.029382 0.155634 0.531104 0.036496 0.138225 0.519829 0.029382 0.155634 0.531104 0.029966 0.138364 0.53387 0.036496 0.138225 0.519829 -0.009838 0.209233 0.513783 -0.015921 0.183938 0.525392 0.005415 0.209866 0.513713 0.04057 0.174052 0.505161 0.034765 0.168787 0.517478 0.042782 0.144342 0.505161 0.030946 0.11257 0.535923 0.030251 0.126841 0.535478 -0.018422 0.116231 0.536733 0.036496 0.138225 0.519829 0.030251 0.126841 0.535478 0.030946 0.11257 0.535923 0.030946 0.11257 0.535923 0.0350025 0.108396 0.526828 0.036496 0.138225 0.519829 -0.022856 0.167634 0.51758 -0.028607 0.173621 0.505162 -0.030946 0.141824 0.505162 0.029966 0.138364 0.53387 0.029382 0.155634 0.531104 -0.018277 0.12598 0.535587 0.029815 0.202535 0.514327 0.022799 0.221273 0.505162 0.020683 0.20953 0.513752 0.022799 0.221273 0.505162 0.032177 0.21585 0.505162 0.03171 0.216707 0.495162 0.028865 0.166727 0.529002 0.029382 0.155634 0.531104 0.034765 0.168787 0.517478 0.032177 0.21585 0.505162 0.036776 0.207522 0.495162 0.03171 0.216707 0.495162 0.029382 0.155634 0.531104 0.028865 0.166727 0.529002 -0.018 0.13747 0.534 0.028865 0.166727 0.529002 0.034765 0.168787 0.517478 0.027898 0.184147 0.525343 0.0389407 0.115743 0.495884 0.0355793 0.115678 0.495935 0.0353254 0.166193 0.495523 -0.024554 0.137067 0.519905 -0.030946 0.141824 0.505162 -0.032289 0.11468 0.498968 0.0355793 0.115678 0.495935 0.0286168 0.115555 0.495963 0.0284417 0.168702 0.495549 0.03171 0.216707 0.495162 0.021304 0.221848 0.495162 0.022799 0.221273 0.505162 -0.005454 0.222616 0.495162 -0.00298356 0.168863 0.495553 -0.016447 0.218894 0.495162 0.028865 0.166727 0.529002 -0.017415 0.155075 0.531201 -0.018 0.13747 0.534 -0.030946 0.141824 0.505162 -0.024787 0.207522 0.495162 -0.032289 0.11468 0.498968 0.03888 0.123504 0.516133 0.036496 0.138225 0.519829 0.0350025 0.108396 0.526828 -0.016907 0.218152 0.505162 -0.005454 0.222616 0.495162 -0.016447 0.218894 0.495162 0.030251 0.126841 0.535478 0.036496 0.138225 0.519829 0.029966 0.138364 0.53387 -0.0162719 0.106266 0.5367189999999999 -0.0115892 0.106378 0.536641 -0.018422 0.116231 0.536733 0.0205572 0.10715 0.536107 0.00626211 0.111249 0.536335 -0.0115892 0.106378 0.536641 0.030946 0.11257 0.535923 0.00626211 0.111249 0.536335 0.0205572 0.10715 0.536107 0.0309413 0.107333 0.535934 0.030946 0.11257 0.535923 0.0205572 0.10715 0.536107 0.030946 0.11257 0.535923 0.0309413 0.107333 0.535934 0.0314074 0.107658 0.5348889999999999 0.030946 0.11257 0.535923 0.0314074 0.107658 0.5348889999999999 0.0319992 0.107987 0.533562 -0.018422 0.10622 0.536733 -0.0162719 0.106266 0.5367189999999999 -0.018422 0.116231 0.536733 -0.018422 0.116231 0.536733 -0.0197178 0.106887 0.533836 -0.0188102 0.106419 0.535867 -0.018422 0.116231 0.536733 -0.0188102 0.106419 0.535867 -0.018422 0.10622 0.536733 -0.018422 0.116231 0.536733 -0.0201825 0.107125 0.532796 -0.0197178 0.106887 0.533836 -0.018422 0.116231 0.536733 -0.0222245 0.106913 0.528226 -0.0208223 0.10696 0.5313639999999999 -0.018422 0.116231 0.536733 -0.0208223 0.10696 0.5313639999999999 -0.0201825 0.107125 0.532796 -0.02773 0.109432 0.515904 -0.0222245 0.106913 0.528226 -0.018422 0.116231 0.536733 0.030946 0.11257 0.535923 0.0319992 0.107987 0.533562 0.0350025 0.108396 0.526828 -0.0115892 0.106378 0.536641 0.00626211 0.111249 0.536335 -0.018422 0.116231 0.536733 -0.0285973 0.12325 0.5094880000000001 -0.032289 0.11468 0.498968 -0.0315008 0.113773 0.501896 -0.0285973 0.12325 0.5094880000000001 -0.0315008 0.113773 0.501896 -0.0309903 0.113553 0.503701 -0.032289 0.11468 0.498968 -0.032288 0.114128 0.498975 -0.0315008 0.113773 0.501896 -0.02773 0.109432 0.515904 -0.0291 0.110769 0.5108200000000001 -0.0277345 0.108784 0.515893 -0.02773 0.109432 0.515904 -0.0277345 0.108784 0.515893 -0.02729 0.108398 0.516889 -0.0291 0.110769 0.5108200000000001 -0.02773 0.109432 0.515904 -0.0298901 0.111918 0.50788 0.042614 0.110851 0.509057 0.0426141 0.110107 0.509057 0.0434735 0.111936 0.503369 0.0437663 0.112223 0.501431 0.0434735 0.111936 0.503369 0.0426141 0.110107 0.509057 0.044333 0.113765 0.497681 0.0443311 0.113262 0.497694 0.0440203 0.113421 0.497149 0.042614 0.110851 0.509057 0.0418834 0.110609 0.510778 0.0426141 0.110107 0.509057 0.0418834 0.110609 0.510778 0.0418851 0.109429 0.511525 0.0426141 0.110107 0.509057 0.044333 0.113765 0.497681 0.042614 0.110851 0.509057 0.0434735 0.111936 0.503369 0.042614 0.110851 0.509057 0.03888 0.123504 0.516133 0.041883 0.112119 0.510592 0.044333 0.113765 0.497681 0.0437663 0.112223 0.501431 0.0443311 0.113262 0.497694 -0.0321047 0.114133 0.498965 -0.032289 0.11468 0.498968 -0.0223878 0.114438 0.49787 -0.032288 0.114128 0.498975 -0.0321047 0.114133 0.498965 -0.0223878 0.114438 0.49787 0.0350025 0.108396 0.526828 0.0395599 0.109838 0.51625 0.03888 0.123504 0.516133 0.03888 0.123504 0.516133 0.0395599 0.109838 0.51625 0.041883 0.112119 0.510592 -0.0285973 0.12325 0.5094880000000001 -0.0309903 0.113553 0.503701 -0.0298901 0.111918 0.50788 -0.0321047 0.114133 0.498965 -0.032288 0.114128 0.498975 -0.032289 0.11468 0.498968 -0.0285973 0.12325 0.5094880000000001 -0.0298901 0.111918 0.50788 -0.02773 0.109432 0.515904 0.0430399 0.113546 0.495482 0.0418502 0.113562 0.495605 0.0418501 0.115831 0.495582 0.030946 0.11257 0.535923 -0.018422 0.116231 0.536733 0.00626211 0.111249 0.536335 0.044333 0.113765 0.497681 0.0440203 0.113421 0.497149 0.0431633 0.113523 0.495692 0.044333 0.113765 0.497681 0.0434735 0.111936 0.503369 0.0437663 0.112223 0.501431 -0.02729 0.108398 0.516889 -0.0261145 0.106509 0.51952 -0.0222245 0.106913 0.528226 0.041883 0.112119 0.510592 0.0418834 0.110609 0.510778 0.042614 0.110851 0.509057 0.044333 0.113765 0.497681 0.0431633 0.113523 0.495692 0.0430399 0.113546 0.495482 -0.02773 0.109432 0.515904 -0.02729 0.108398 0.516889 -0.0222245 0.106913 0.528226 -0.02773 -0.109432 0.515904 -0.0298901 -0.111918 0.50788 -0.0285973 -0.12325 0.5094880000000001 -0.02773 -0.109432 0.515904 -0.0285973 -0.12325 0.5094880000000001 -0.024554 -0.137067 0.519905 0.029382 -0.155634 0.531104 0.0327356 -0.153506 0.524613 0.036496 -0.138225 0.519829 0.029382 -0.155634 0.531104 0.036496 -0.138225 0.519829 0.029966 -0.138364 0.53387 0.024948 -0.196933 0.5217540000000001 0.029815 -0.202535 0.514327 0.027898 -0.184147 0.525343 0.024948 -0.196933 0.5217540000000001 0.027898 -0.184147 0.525343 -0.016909 -0.16601 0.529141 0.029815 -0.202535 0.514327 0.024948 -0.196933 0.5217540000000001 0.020683 -0.20953 0.513752 0.029815 -0.202535 0.514327 0.034765 -0.168787 0.517478 0.027898 -0.184147 0.525343 -0.015921 -0.183938 0.525392 0.020683 -0.20953 0.513752 0.024948 -0.196933 0.5217540000000001 0.027898 -0.184147 0.525343 0.034765 -0.168787 0.517478 0.028865 -0.166727 0.529002 -0.0277345 -0.108784 0.515893 -0.02773 -0.109432 0.515904 -0.02729 -0.108398 0.516889 -0.0222245 -0.106913 0.528226 -0.02729 -0.108398 0.516889 -0.02773 -0.109432 0.515904 -0.0277345 -0.108784 0.515893 -0.0291 -0.110769 0.5108200000000001 -0.02773 -0.109432 0.515904 -0.016909 -0.16601 0.529141 -0.022856 -0.167634 0.51758 -0.018406 -0.20154 0.514412 -0.022856 -0.167634 0.51758 -0.024259 -0.208573 0.505162 -0.018406 -0.20154 0.514412 -0.024259 -0.208573 0.505162 -0.028607 -0.173621 0.505162 -0.024787 -0.207522 0.495162 -0.022856 -0.167634 0.51758 -0.028607 -0.173621 0.505162 -0.024259 -0.208573 0.505162 -0.016907 -0.218152 0.505162 -0.024259 -0.208573 0.505162 -0.024787 -0.207522 0.495162 -0.016907 -0.218152 0.505162 -0.024787 -0.207522 0.495162 -0.016447 -0.218894 0.495162 -0.016447 -0.218894 0.495162 -0.024787 -0.207522 0.495162 -0.0111103 -0.166942 0.495522 -0.016907 -0.218152 0.505162 -0.016447 -0.218894 0.495162 -0.005454 -0.222616 0.495162 -0.005454 -0.222616 0.495162 -0.016447 -0.218894 0.495162 -0.00298356 -0.168863 0.495553 -0.016907 -0.218152 0.505162 -0.018406 -0.20154 0.514412 -0.024259 -0.208573 0.505162 -0.009838 -0.209233 0.513783 -0.018406 -0.20154 0.514412 -0.016907 -0.218152 0.505162 -0.009838 -0.209233 0.513783 -0.016907 -0.218152 0.505162 -0.005454 -0.222441 0.505162 0.005415 -0.209866 0.513713 -0.009838 -0.209233 0.513783 -0.005454 -0.222441 0.505162 0.021304 -0.221848 0.495162 0.005425 -0.222441 0.505162 -0.005454 -0.222441 0.505162 0.005425 -0.222441 0.505162 0.005415 -0.209866 0.513713 -0.005454 -0.222441 0.505162 -0.00482529 -0.11499 0.49589 -0.0111103 -0.166942 0.495522 -0.024787 -0.207522 0.495162 -0.024787 -0.207522 0.495162 -0.0223878 -0.114438 0.49787 -0.00482529 -0.11499 0.49589 -0.0111103 -0.166942 0.495522 -0.00482529 -0.11499 0.49589 0.00256593 -0.115109 0.495951 -0.024787 -0.207522 0.495162 -0.032289 -0.11468 0.498968 -0.0223878 -0.114438 0.49787 -0.018277 -0.12598 0.535587 -0.018 -0.13747 0.534 0.029382 -0.155634 0.531104 0.028865 -0.166727 0.529002 0.029382 -0.155634 0.531104 -0.018 -0.13747 0.534 -0.017415 -0.155075 0.531201 -0.018 -0.13747 0.534 -0.024554 -0.137067 0.519905 0.028865 -0.166727 0.529002 -0.018 -0.13747 0.534 -0.017415 -0.155075 0.531201 0.027898 -0.184147 0.525343 0.028865 -0.166727 0.529002 -0.017415 -0.155075 0.531201 -0.022856 -0.167634 0.51758 -0.017415 -0.155075 0.531201 -0.024554 -0.137067 0.519905 0.029382 -0.155634 0.531104 0.028865 -0.166727 0.529002 0.034765 -0.168787 0.517478 -0.024554 -0.137067 0.519905 -0.030946 -0.141824 0.505162 -0.022856 -0.167634 0.51758 -0.0315008 -0.113773 0.501896 -0.032289 -0.11468 0.498968 -0.0285973 -0.12325 0.5094880000000001 -0.0285973 -0.12325 0.5094880000000001 -0.032289 -0.11468 0.498968 -0.024554 -0.137067 0.519905 -0.030946 -0.141824 0.505162 -0.024554 -0.137067 0.519905 -0.032289 -0.11468 0.498968 -0.024787 -0.207522 0.495162 -0.030946 -0.141824 0.505162 -0.032289 -0.11468 0.498968 -0.018277 -0.12598 0.535587 -0.024554 -0.137067 0.519905 -0.018 -0.13747 0.534 -0.024787 -0.207522 0.495162 -0.028607 -0.173621 0.505162 -0.030946 -0.141824 0.505162 -0.018422 -0.116231 0.536733 -0.0115892 -0.106378 0.536641 -0.0162719 -0.106266 0.5367189999999999 0.030946 -0.11257 0.535923 0.00626211 -0.111249 0.536335 -0.018422 -0.116231 0.536733 -0.018422 -0.116231 0.536733 0.00626211 -0.111249 0.536335 -0.0115892 -0.106378 0.536641 0.030251 -0.126841 0.535478 0.030946 -0.11257 0.535923 -0.018422 -0.116231 0.536733 0.030946 -0.11257 0.535923 0.0205572 -0.10715 0.536107 0.00626211 -0.111249 0.536335 0.029966 -0.138364 0.53387 0.030251 -0.126841 0.535478 -0.018422 -0.116231 0.536733 0.029966 -0.138364 0.53387 -0.018422 -0.116231 0.536733 -0.018277 -0.12598 0.535587 0.030251 -0.126841 0.535478 0.029966 -0.138364 0.53387 0.036496 -0.138225 0.519829 0.030946 -0.11257 0.535923 0.030251 -0.126841 0.535478 0.036496 -0.138225 0.519829 0.0363704 -0.10879 0.523739 0.0332328 -0.107898 0.530796 0.030946 -0.11257 0.535923 0.0363704 -0.10879 0.523739 0.030946 -0.11257 0.535923 0.036496 -0.138225 0.519829 0.0319992 -0.107987 0.533562 0.030946 -0.11257 0.535923 0.0332328 -0.107898 0.530796 0.030946 -0.11257 0.535923 0.0309413 -0.107333 0.535934 0.0205572 -0.10715 0.536107 0.03888 -0.123504 0.516133 0.0363704 -0.10879 0.523739 0.036496 -0.138225 0.519829 0.0286168 -0.115555 0.495963 0.0115814 -0.168929 0.495563 0.0104799 -0.115243 0.495969 0.022799 -0.221273 0.505162 0.021304 -0.221848 0.495162 0.03171 -0.216707 0.495162 0.03171 -0.216707 0.495162 0.021304 -0.221848 0.495162 0.0284417 -0.168702 0.495549 0.0286168 -0.115555 0.495963 0.0284417 -0.168702 0.495549 0.021304 -0.221848 0.495162 0.03171 -0.216707 0.495162 0.0284417 -0.168702 0.495549 0.0355793 -0.115678 0.495935 0.0389407 -0.115743 0.495884 0.036776 -0.207522 0.495162 0.0353254 -0.166193 0.495523 0.0353254 -0.166193 0.495523 0.0355793 -0.115678 0.495935 0.0389407 -0.115743 0.495884 0.036776 -0.207522 0.495162 0.0389407 -0.115743 0.495884 0.042851 -0.146615 0.495161 0.042851 -0.146615 0.495161 0.04057 -0.174052 0.505161 0.036776 -0.207522 0.495162 0.042782 -0.144342 0.505161 0.04057 -0.174052 0.505161 0.042851 -0.146615 0.495161 0.036662 -0.207233 0.505162 0.04057 -0.174052 0.505161 0.034765 -0.168787 0.517478 0.042782 -0.144342 0.505161 0.034765 -0.168787 0.517478 0.04057 -0.174052 0.505161 0.0353254 -0.166193 0.495523 0.036776 -0.207522 0.495162 0.03171 -0.216707 0.495162 0.0355793 -0.115678 0.495935 0.0353254 -0.166193 0.495523 0.03171 -0.216707 0.495162 0.0355793 -0.115678 0.495935 0.0284417 -0.168702 0.495549 0.0286168 -0.115555 0.495963 0.03171 -0.216707 0.495162 0.032177 -0.21585 0.505162 0.022799 -0.221273 0.505162 0.042851 -0.146615 0.495161 0.0389407 -0.115743 0.495884 0.0418501 -0.115831 0.495582 0.044333 -0.113765 0.497681 0.042614 -0.110851 0.509057 0.042782 -0.144342 0.505161 0.042614 -0.110851 0.509057 0.036496 -0.138225 0.519829 0.042782 -0.144342 0.505161 0.042614 -0.110851 0.509057 0.03888 -0.123504 0.516133 0.036496 -0.138225 0.519829 0.0434735 -0.111936 0.503369 0.042614 -0.110851 0.509057 0.044333 -0.113765 0.497681 0.0426141 -0.110107 0.509057 0.0434735 -0.111936 0.503369 0.0437663 -0.112223 0.501431 0.0426141 -0.110107 0.509057 0.042614 -0.110851 0.509057 0.0434735 -0.111936 0.503369 0.0426141 -0.110107 0.509057 0.0418834 -0.110609 0.510778 0.042614 -0.110851 0.509057 0.0418851 -0.109429 0.511525 0.0418834 -0.110609 0.510778 0.0426141 -0.110107 0.509057 0.0437663 -0.112223 0.501431 0.0434735 -0.111936 0.503369 0.044333 -0.113765 0.497681 0.0430399 -0.113546 0.495482 0.042851 -0.146615 0.495161 0.0418501 -0.115831 0.495582 0.0430399 -0.113546 0.495482 0.044333 -0.113765 0.497681 0.042851 -0.146615 0.495161 0.0431633 -0.113523 0.495692 0.044333 -0.113765 0.497681 0.0430399 -0.113546 0.495482 0.0440203 -0.113421 0.497149 0.044333 -0.113765 0.497681 0.0431633 -0.113523 0.495692 0.0443311 -0.113262 0.497694 0.044333 -0.113765 0.497681 0.0440203 -0.113421 0.497149 0.0443311 -0.113262 0.497694 0.0437663 -0.112223 0.501431 0.044333 -0.113765 0.497681 0.041883 -0.112119 0.510592 0.03888 -0.123504 0.516133 0.042614 -0.110851 0.509057 0.041883 -0.112119 0.510592 0.0395599 -0.109838 0.51625 0.03888 -0.123504 0.516133 0.042782 -0.144342 0.505161 0.036496 -0.138225 0.519829 0.034765 -0.168787 0.517478 0.029815 -0.202535 0.514327 0.022799 -0.221273 0.505162 0.032177 -0.21585 0.505162 0.036662 -0.207233 0.505162 0.029815 -0.202535 0.514327 0.032177 -0.21585 0.505162 0.036662 -0.207233 0.505162 0.032177 -0.21585 0.505162 0.036776 -0.207522 0.495162 0.0104799 -0.115243 0.495969 -0.00298356 -0.168863 0.495553 0.00256593 -0.115109 0.495951 -0.0115892 -0.106378 0.536641 0.00626211 -0.111249 0.536335 0.0205572 -0.10715 0.536107 -0.02773 -0.109432 0.515904 -0.018422 -0.116231 0.536733 -0.0222245 -0.106913 0.528226 -0.018422 -0.116231 0.536733 -0.02773 -0.109432 0.515904 -0.024554 -0.137067 0.519905 -0.015921 -0.183938 0.525392 -0.016909 -0.16601 0.529141 -0.018406 -0.20154 0.514412 0.042851 -0.146615 0.495161 0.044333 -0.113765 0.497681 0.042782 -0.144342 0.505161 0.029382 -0.155634 0.531104 0.034765 -0.168787 0.517478 0.0327356 -0.153506 0.524613 -0.018422 -0.116231 0.536733 -0.024554 -0.137067 0.519905 -0.018277 -0.12598 0.535587 -0.0188102 -0.106419 0.535867 -0.0197178 -0.106887 0.533836 -0.018422 -0.116231 0.536733 -0.0197178 -0.106887 0.533836 -0.0201825 -0.107125 0.532796 -0.018422 -0.116231 0.536733 -0.0201825 -0.107125 0.532796 -0.0208223 -0.10696 0.5313639999999999 -0.018422 -0.116231 0.536733 -0.015921 -0.183938 0.525392 -0.018406 -0.20154 0.514412 -0.009838 -0.209233 0.513783 -0.032289 -0.11468 0.498968 -0.032288 -0.114128 0.498975 -0.0321047 -0.114133 0.498965 -0.017415 -0.155075 0.531201 -0.022856 -0.167634 0.51758 -0.016909 -0.16601 0.529141 0.0319992 -0.107987 0.533562 0.0314074 -0.107658 0.5348889999999999 0.030946 -0.11257 0.535923 -0.032288 -0.114128 0.498975 -0.032289 -0.11468 0.498968 -0.0315008 -0.113773 0.501896 0.0314074 -0.107658 0.5348889999999999 0.0309413 -0.107333 0.535934 0.030946 -0.11257 0.535923 0.034765 -0.168787 0.517478 0.029815 -0.202535 0.514327 0.036662 -0.207233 0.505162 0.022799 -0.221273 0.505162 0.005425 -0.222441 0.505162 0.021304 -0.221848 0.495162 -0.005454 -0.222441 0.505162 -0.016907 -0.218152 0.505162 -0.005454 -0.222616 0.495162 0.0395599 -0.109838 0.51625 0.0393776 -0.109778 0.516679 0.03888 -0.123504 0.516133 0.0393776 -0.109778 0.516679 0.0390585 -0.109678 0.517417 0.03888 -0.123504 0.516133 0.0390585 -0.109678 0.517417 0.0380569 -0.109358 0.519748 0.03888 -0.123504 0.516133 0.0380569 -0.109358 0.519748 0.0372337 -0.109096 0.521663 0.03888 -0.123504 0.516133 0.0372337 -0.109096 0.521663 0.0363704 -0.10879 0.523739 0.03888 -0.123504 0.516133 -0.0222245 -0.106913 0.528226 -0.0261145 -0.106509 0.51952 -0.02729 -0.108398 0.516889 0.005415 -0.209866 0.513713 0.005425 -0.222441 0.505162 0.022799 -0.221273 0.505162 0.005415 -0.209866 0.513713 0.022799 -0.221273 0.505162 0.020683 -0.20953 0.513752 -0.030946 -0.141824 0.505162 -0.028607 -0.173621 0.505162 -0.022856 -0.167634 0.51758 0.0418501 -0.115831 0.495582 0.0418502 -0.113562 0.495605 0.0430399 -0.113546 0.495482 0.00256593 -0.115109 0.495951 -0.00298356 -0.168863 0.495553 -0.016447 -0.218894 0.495162 0.029382 -0.155634 0.531104 0.029966 -0.138364 0.53387 -0.018277 -0.12598 0.535587 -0.0309903 -0.113553 0.503701 -0.0315008 -0.113773 0.501896 -0.0285973 -0.12325 0.5094880000000001 -0.005454 -0.222441 0.505162 -0.005454 -0.222616 0.495162 0.021304 -0.221848 0.495162 0.021304 -0.221848 0.495162 -0.005454 -0.222616 0.495162 0.0115814 -0.168929 0.495563 0.020683 -0.20953 0.513752 -0.015921 -0.183938 0.525392 0.005415 -0.209866 0.513713 -0.018422 -0.116231 0.536733 -0.0162719 -0.106266 0.5367189999999999 -0.018422 -0.10622 0.536733 -0.0208223 -0.10696 0.5313639999999999 -0.0222245 -0.106913 0.528226 -0.018422 -0.116231 0.536733 0.0115814 -0.168929 0.495563 -0.005454 -0.222616 0.495162 0.0104799 -0.115243 0.495969 0.04057 -0.174052 0.505161 0.036662 -0.207233 0.505162 0.036776 -0.207522 0.495162 -0.0298901 -0.111918 0.50788 -0.02773 -0.109432 0.515904 -0.0291 -0.110769 0.5108200000000001 0.036496 -0.138225 0.519829 0.0327356 -0.153506 0.524613 0.034765 -0.168787 0.517478 0.00256593 -0.115109 0.495951 -0.016447 -0.218894 0.495162 -0.0111103 -0.166942 0.495522 -0.018422 -0.10622 0.536733 -0.0188102 -0.106419 0.535867 -0.018422 -0.116231 0.536733 0.027898 -0.184147 0.525343 -0.017415 -0.155075 0.531201 -0.016909 -0.16601 0.529141 -0.032289 -0.11468 0.498968 -0.0321047 -0.114133 0.498965 -0.0223878 -0.114438 0.49787 -0.015921 -0.183938 0.525392 -0.009838 -0.209233 0.513783 0.005415 -0.209866 0.513713 0.029815 -0.202535 0.514327 0.020683 -0.20953 0.513752 0.022799 -0.221273 0.505162 0.03171 -0.216707 0.495162 0.036776 -0.207522 0.495162 0.032177 -0.21585 0.505162 0.024948 -0.196933 0.5217540000000001 -0.016909 -0.16601 0.529141 -0.015921 -0.183938 0.525392 0.021304 -0.221848 0.495162 0.0115814 -0.168929 0.495563 0.0286168 -0.115555 0.495963 -0.0298901 -0.111918 0.50788 -0.0309903 -0.113553 0.503701 -0.0285973 -0.12325 0.5094880000000001 0.0418834 -0.110609 0.510778 0.041883 -0.112119 0.510592 0.042614 -0.110851 0.509057 -0.005454 -0.222616 0.495162 -0.00298356 -0.168863 0.495553 0.0104799 -0.115243 0.495969 0.04402 0.09636599999999999 0.370035 0.0442757 0.0925535 0.368491 0.04402 0.092696 0.366597 0.0442757 0.0925535 0.368491 0.04402 0.09636599999999999 0.370035 0.044958 0.088741 0.370332 0.043693 0.094531 0.366203 0.04402 0.09636599999999999 0.370035 0.04402 0.092696 0.366597 0.042864 0.096243 0.362448 0.04402 0.092696 0.366597 0.04381 0.088032 0.364949 0.043693 0.094531 0.366203 0.04402 0.092696 0.366597 0.042864 0.096243 0.362448 0.04402 0.092696 0.366597 0.0442757 0.0925535 0.368491 0.044958 0.088741 0.370332 0.044958 0.088741 0.370332 0.04381 0.088032 0.364949 0.04402 0.092696 0.366597 0.0447635 0.0925535 0.372123 0.04503 0.09288200000000001 0.374278 0.044958 0.088741 0.370332 0.04503 0.09288200000000001 0.374278 0.045693 0.089558 0.376733 0.044958 0.088741 0.370332 0.04402 0.09636599999999999 0.370035 0.0447635 0.0925535 0.372123 0.044958 0.088741 0.370332 0.042864 0.096243 0.362448 0.04381 0.088032 0.364949 0.042747 0.08745699999999999 0.36068 0.045805 0.090896 0.387693 0.04503 0.093782 0.380054 0.045589 0.092433 0.396825 0.045859 0.090318 0.382877 0.04503 0.093782 0.380054 0.045805 0.090896 0.387693 0.04503 0.09288200000000001 0.374278 0.04503 0.093782 0.380054 0.045859 0.090318 0.382877 0.041933 0.108151 0.533708 0.0418998 0.108605 0.518491 0.041898 0.109456 0.51732 0.041933 0.108151 0.533708 0.0419053 0.10675 0.521044 0.0418998 0.108605 0.518491 0.0419053 0.10675 0.521044 0.041933 0.108151 0.533708 0.0419182 0.09948700000000001 0.526511 0.0418998 0.108605 0.518491 0.0419053 0.10675 0.521044 0.0419182 0.09948700000000001 0.526511 0.0419165 0.100044 0.525991 0.0418998 0.108605 0.518491 0.0419182 0.09948700000000001 0.526511 0.0350025 0.108396 0.526828 0.041933 0.108151 0.533708 0.041898 0.109456 0.51732 0.041563 -0.1039 0.364348 0.0415708 -0.104254 0.367907 0.041559 -0.106091 0.362725 0.0415617 -0.103788 0.363302 0.041563 -0.1039 0.364348 0.041559 -0.106091 0.362725 0.041563 -0.1039 0.364348 0.0421437 -0.102506 0.367604 0.0415708 -0.104254 0.367907 0.0415708 -0.104254 0.367907 0.0421437 -0.102506 0.367604 0.042864 -0.100806 0.371922 0.042864 -0.100806 0.371922 0.0415709 -0.104259 0.36799 0.0415708 -0.104254 0.367907 0.0415617 -0.103788 0.363302 0.0421437 -0.102506 0.367604 0.041563 -0.1039 0.364348 0.042864 -0.100806 0.371922 0.0421437 -0.102506 0.367604 0.0415617 -0.103788 0.363302 -0.119116 0.103874 0.53815 -0.06537 0.104758 0.5389350000000001 -0.065293 0.106381 0.532132 -0.0425439 0.106001 0.535636 -0.065293 0.106381 0.532132 -0.06537 0.104758 0.5389350000000001 -0.119116 0.103874 0.53815 -0.119135 0.09962 0.544378 -0.06537 0.104758 0.5389350000000001 -0.121857 -0.101838 0.361869 -0.149495 -0.09779 0.363495 -0.135472 -0.04726 0.354722 -0.135472 -0.04726 0.354722 -0.124983 -0.072046 0.355864 -0.121857 -0.101838 0.361869 -0.135472 -0.04726 0.354722 -0.148231 -0.049443 0.357251 -0.140007 -0.029219 0.354572 -0.140007 -0.029219 0.354572 -0.148231 -0.049443 0.357251 -0.141477 -0.02304 0.354537 -0.148231 -0.049443 0.357251 -0.145687 -0.000441004 0.355087 -0.141477 -0.02304 0.354537 -0.148231 -0.049443 0.357251 -0.160668 -0.000441005 0.359253 -0.145687 -0.000441004 0.355087 -0.148231 -0.049443 0.357251 -0.160836 -0.049457 0.361253 -0.160668 -0.000441005 0.359253 -0.170673 -0.10336 0.379379 -0.149495 -0.09779 0.363495 -0.121857 -0.101838 0.361869 -0.17939 0.0412 0.378925 -0.175944 0.04437 0.373254 -0.17939 0.000441005 0.375325 -0.175944 0.04437 0.373254 -0.17387 0.000441005 0.366457 -0.17939 0.000441005 0.375325 0.0419129 0.101701 0.524294 0.0419097 0.102618 0.5227850000000001 0.0418998 0.108605 0.518491 0.0418998 0.108605 0.518491 0.0419097 0.102618 0.5227850000000001 0.0418982 0.105879 0.517422 0.04503 -0.09288200000000001 0.374278 0.044958 -0.088741 0.370332 0.045693 -0.089558 0.376733 0.04503 -0.09288200000000001 0.374278 0.045693 -0.089558 0.376733 0.045859 -0.090318 0.382877 -0.14146 -0.102951 0.488977 -0.108691 -0.10404 0.502782 -0.10869 -0.10404 0.503285 -0.108662 -0.104041 0.516104 -0.14146 -0.102951 0.488977 -0.10869 -0.10404 0.503285 -0.14146 -0.102951 0.488977 -0.108662 -0.104041 0.516104 -0.108661 -0.104041 0.516292 -0.119135 -0.09962 0.544378 -0.06537 -0.104758 0.5389350000000001 -0.065389 -0.100507 0.5451549999999999 -0.119116 -0.103874 0.53815 -0.119041 -0.105494 0.531342 -0.065293 -0.106381 0.532132 -0.06537 -0.104758 0.5389350000000001 -0.065293 -0.106381 0.532132 -0.0425439 -0.106001 0.535636 -0.0425439 -0.106001 0.535636 -0.0197178 -0.106887 0.533836 -0.06537 -0.104758 0.5389350000000001 -0.0201825 -0.107125 0.532796 -0.0425439 -0.106001 0.535636 -0.065293 -0.106381 0.532132 -0.119116 -0.103874 0.53815 -0.065293 -0.106381 0.532132 -0.06537 -0.104758 0.5389350000000001 -0.0422016 -0.106249 0.519439 -0.0261145 -0.106509 0.51952 -0.0222245 -0.106913 0.528226 -0.0208223 -0.10696 0.5313639999999999 -0.0422016 -0.106249 0.519439 -0.0222245 -0.106913 0.528226 -0.066859 -0.10543 0.519894 -0.0422016 -0.106249 0.519439 -0.0208223 -0.10696 0.5313639999999999 -0.108653 -0.104426 0.520135 -0.0868767 -0.104765 0.520263 -0.065293 -0.106381 0.532132 -0.119135 -0.09962 0.544378 -0.119116 -0.103874 0.53815 -0.06537 -0.104758 0.5389350000000001 0.0418652 -0.101732 0.362399 0.0415564 -0.100463 0.358989 0.042864 -0.099831 0.365808 0.0418652 -0.101732 0.362399 0.042864 -0.099831 0.365808 0.0415617 -0.103788 0.363302 0.042864 -0.100806 0.371922 0.0415617 -0.103788 0.363302 0.042864 -0.099831 0.365808 0.0424993 -0.098358 0.362349 0.042864 -0.099831 0.365808 0.0415564 -0.100463 0.358989 -0.160836 -0.049457 0.361253 -0.149495 -0.09779 0.363495 -0.162182 -0.097984 0.368515 -0.170673 -0.10336 0.379379 -0.162182 -0.097984 0.368515 -0.149495 -0.09779 0.363495 -0.168221 -0.098103 0.371579 -0.162182 -0.097984 0.368515 -0.170673 -0.10336 0.379379 -0.160836 -0.049457 0.361253 -0.162182 -0.097984 0.368515 -0.168221 -0.098103 0.371579 -0.160836 -0.049457 0.361253 -0.168221 -0.098103 0.371579 -0.174177 -0.095822 0.377275 -0.174177 -0.095822 0.377275 -0.168221 -0.098103 0.371579 -0.170673 -0.10336 0.379379 0.007603 -0.087779 0.354873 0.000980996 -0.099699 0.357935 -0.019615 -0.101439 0.357935 0.021541 -0.102112 0.357935 0.000980996 -0.099699 0.357935 0.007603 -0.087779 0.354873 0.024572 -0.08803900000000001 0.354568 0.021541 -0.102112 0.357935 0.007603 -0.087779 0.354873 0.042864 -0.100806 0.371922 0.044019 -0.098164 0.388927 0.042864 -0.10172 0.385409 0.042864 -0.100806 0.371922 0.04402 -0.097305 0.375981 0.044019 -0.098164 0.388927 0.044019 -0.098164 0.388927 0.04402 -0.097305 0.375981 0.045589 -0.092433 0.396825 0.044019 -0.098887 0.401952 0.042864 -0.10172 0.385409 0.044019 -0.098164 0.388927 0.042864 -0.10172 0.385409 0.044019 -0.098887 0.401952 0.042863 -0.10249 0.398993 0.0423409 -0.103037 0.383491 0.042864 -0.10172 0.385409 0.042863 -0.10249 0.398993 0.0415711 -0.104264 0.368078 0.0423409 -0.103037 0.383491 0.042863 -0.10249 0.398993 0.042864 -0.10172 0.385409 0.0423409 -0.103037 0.383491 0.0415709 -0.104259 0.36799 0.0415709 -0.104259 0.36799 0.0423409 -0.103037 0.383491 0.0415711 -0.104264 0.368078 0.042863 -0.10249 0.398993 0.044019 -0.098887 0.401952 0.043928 -0.100007 0.421527 -0.17939 -0.094905 0.463443 -0.17939 -0.09062199999999999 0.401415 -0.17426 -0.101861 0.393664 -0.17426 -0.101861 0.393664 -0.17426 -0.101861 0.461351 -0.17939 -0.094905 0.463443 -0.108823 -0.104429 0.442579 -0.17426 -0.101861 0.393664 0.0222217 -0.109573 0.454324 -0.17426 -0.101861 0.393664 -0.108823 -0.104429 0.442579 -0.17426 -0.101861 0.461351 -0.108782 -0.104431 0.461051 -0.17426 -0.101861 0.461351 -0.108823 -0.104429 0.442579 -0.17939 -0.08801200000000001 0.388846 -0.17939 -0.09062199999999999 0.401415 -0.17939 -0.094905 0.463443 -0.17939 -0.08801200000000001 0.388846 -0.17426 -0.101861 0.393664 -0.17939 -0.09062199999999999 0.401415 -0.121857 -0.101838 0.361869 -0.101926 -0.100093 0.357935 -0.101896 -0.104076 0.362725 -0.101896 -0.104076 0.362725 -0.170673 -0.10336 0.379379 -0.121857 -0.101838 0.361869 -0.101896 -0.104076 0.362725 -0.101926 -0.100093 0.357935 -0.081347 -0.100429 0.357935 -0.081347 -0.100429 0.357935 -0.101926 -0.100093 0.357935 -0.094212 -0.086218 0.356704 -0.17426 -0.101861 0.393664 -0.170673 -0.10336 0.379379 -0.101896 -0.104076 0.362725 -0.060763 -0.103796 0.362725 -0.17426 -0.101861 0.393664 -0.101896 -0.104076 0.362725 -0.17426 -0.101861 0.393664 -0.17939 -0.08801200000000001 0.388846 -0.170673 -0.10336 0.379379 -0.174177 -0.095822 0.377275 -0.170673 -0.10336 0.379379 -0.17939 -0.08801200000000001 0.388846 -0.17426 -0.101861 0.461351 -0.108743 -0.103892 0.479123 -0.108734 -0.103767 0.483282 -0.108743 -0.103892 0.479123 -0.17426 -0.101861 0.461351 -0.10875 -0.103984 0.476016 -0.060763 -0.103796 0.362725 0.0222217 -0.109573 0.454324 -0.17426 -0.101861 0.393664 0.0361127 -0.109979 0.45497 0.0222217 -0.109573 0.454324 -0.060763 -0.103796 0.362725 0.0417368 -0.106904 0.443818 0.042178 -0.105959 0.446111 0.0417532 -0.107167 0.451436 0.0417368 -0.106904 0.443818 0.042863 -0.10249 0.398993 0.042178 -0.105959 0.446111 0.0417612 -0.110111 0.455091 0.0417368 -0.106904 0.443818 0.0417532 -0.107167 0.451436 0.0415866 -0.104509 0.375111 0.0417368 -0.106904 0.443818 0.0417612 -0.110111 0.455091 0.0415866 -0.104509 0.375111 0.0417612 -0.110111 0.455091 0.041559 -0.106091 0.362725 -0.060273 -0.086738 0.356093 -0.060753 -0.098686 0.357935 -0.07724300000000001 -0.086478 0.356398 -0.040193 -0.101103 0.357935 -0.060753 -0.098686 0.357935 -0.060273 -0.086738 0.356093 -0.060763 -0.103796 0.362725 -0.060753 -0.098686 0.357935 -0.040193 -0.101103 0.357935 -0.019615 -0.101439 0.357935 -0.060763 -0.103796 0.362725 -0.040193 -0.101103 0.357935 -0.060763 -0.103796 0.362725 -0.019615 -0.101439 0.357935 0.021573 -0.106091 0.362725 0.021573 -0.106091 0.362725 0.0361127 -0.109979 0.45497 -0.060763 -0.103796 0.362725 0.0361127 -0.109979 0.45497 0.021573 -0.106091 0.362725 0.040704 -0.110115 0.455193 0.021573 -0.106091 0.362725 0.041559 -0.106091 0.362725 0.040704 -0.110115 0.455193 0.021573 -0.106091 0.362725 0.041549 -0.103334 0.357935 0.041559 -0.106091 0.362725 0.040704 -0.110115 0.455193 0.041559 -0.106091 0.362725 0.0417612 -0.110111 0.455091 0.0415604 -0.103691 0.363161 0.041559 -0.106091 0.362725 0.041549 -0.103334 0.357935 0.0415711 -0.104264 0.368078 0.0415866 -0.104509 0.375111 0.041559 -0.106091 0.362725 0.042859 -0.103849 0.437105 0.042178 -0.105959 0.446111 0.042863 -0.10249 0.398993 0.0420702 -0.097139 0.359908 0.042864 -0.096243 0.362448 0.0415564 -0.100463 0.358989 0.0415602 -0.0882602 0.356609 0.0420702 -0.097139 0.359908 0.0415564 -0.100463 0.358989 0.0420702 -0.097139 0.359908 0.0415602 -0.0882602 0.356609 0.042747 -0.08745699999999999 0.36068 0.042864 -0.096243 0.362448 0.0424993 -0.098358 0.362349 0.0415564 -0.100463 0.358989 0.042864 -0.096243 0.362448 0.042864 -0.099831 0.365808 0.0424993 -0.098358 0.362349 0.042864 -0.096243 0.362448 0.04402 -0.09636599999999999 0.370035 0.042864 -0.099831 0.365808 0.043693 -0.094531 0.366203 0.04402 -0.09636599999999999 0.370035 0.042864 -0.096243 0.362448 0.04402 -0.092696 0.366597 0.04402 -0.09636599999999999 0.370035 0.043693 -0.094531 0.366203 0.0442757 -0.0925535 0.368491 0.044958 -0.088741 0.370332 0.04402 -0.09636599999999999 0.370035 0.04402 -0.092696 0.366597 0.0442757 -0.0925535 0.368491 0.04402 -0.09636599999999999 0.370035 0.044958 -0.088741 0.370332 0.0442757 -0.0925535 0.368491 0.04402 -0.092696 0.366597 0.042864 -0.099831 0.365808 0.04402 -0.09636599999999999 0.370035 0.04402 -0.097305 0.375981 0.043362 -0.102135 0.430031 0.042859 -0.103849 0.437105 0.042863 -0.10249 0.398993 0.04402 -0.097305 0.375981 0.04402 -0.09636599999999999 0.370035 0.04503 -0.093782 0.380054 0.04402 -0.09636599999999999 0.370035 0.04503 -0.09288200000000001 0.374278 0.04503 -0.093782 0.380054 0.0447635 -0.0925535 0.372123 0.04503 -0.09288200000000001 0.374278 0.04402 -0.09636599999999999 0.370035 0.04503 -0.09288200000000001 0.374278 0.045859 -0.090318 0.382877 0.04503 -0.093782 0.380054 0.045589 -0.092433 0.396825 0.04503 -0.093782 0.380054 0.045805 -0.090896 0.387693 0.045589 -0.092433 0.396825 0.044994 -0.09535100000000001 0.404143 0.044019 -0.098887 0.401952 0.044019 -0.098887 0.401952 0.044994 -0.09535100000000001 0.404143 0.043928 -0.100007 0.421527 0.04503 -0.093782 0.380054 0.045859 -0.090318 0.382877 0.045805 -0.090896 0.387693 0.041541 -0.088299 0.354263 0.041549 -0.103334 0.357935 0.024572 -0.08803900000000001 0.354568 0.041541 -0.088299 0.354263 0.0415564 -0.100463 0.358989 0.041549 -0.103334 0.357935 0.041549 -0.103334 0.357935 0.021541 -0.102112 0.357935 0.024572 -0.08803900000000001 0.354568 0.042747 -0.08745699999999999 0.36068 0.04381 -0.088032 0.364949 0.042864 -0.096243 0.362448 -0.174177 -0.095822 0.377275 -0.173537 -0.047617 0.368218 -0.160836 -0.049457 0.361253 -0.108735 -0.08329499999999999 0.35666 -0.101926 -0.100093 0.357935 -0.118275 -0.079184 0.356402 -0.1026 -0.084996 0.356729 -0.101926 -0.100093 0.357935 -0.108735 -0.08329499999999999 0.35666 -0.173537 -0.047617 0.368218 -0.174177 -0.095822 0.377275 -0.17939 -0.08801200000000001 0.388846 0.0419165 -0.100044 0.525991 0.0418998 -0.108605 0.518491 0.0419129 -0.101701 0.524294 0.0419182 -0.09948700000000001 0.526511 0.0418998 -0.108605 0.518491 0.0419165 -0.100044 0.525991 0.041973 -0.092265 0.551797 0.0419393 -0.0878264 0.536362 0.0419503 -0.07822079999999999 0.541342 0.0419393 -0.0878264 0.536362 0.041973 -0.092265 0.551797 0.0419331 -0.0918987 0.533554 0.0419328 -0.0920768 0.533431 0.0419318 -0.0957819 0.532832 0.0419182 -0.09948700000000001 0.526511 0.0419318 -0.0957819 0.532832 0.0419457 -0.0963864 0.539154 0.0419182 -0.09948700000000001 0.526511 0.0419328 -0.0920768 0.533431 0.0419457 -0.0963864 0.539154 0.0419318 -0.0957819 0.532832 0.0419331 -0.0918987 0.533554 0.0419457 -0.0963864 0.539154 0.0419328 -0.0920768 0.533431 0.041973 -0.092265 0.551797 0.0419457 -0.0963864 0.539154 0.0419331 -0.0918987 0.533554 0.041973 -0.092265 0.551797 0.041965 -0.100874 0.547865 0.0419457 -0.0963864 0.539154 0.041965 -0.100874 0.547865 0.041973 -0.092265 0.551797 -0.011602 -0.095148 0.550137 0.041965 -0.100874 0.547865 -0.011602 -0.095148 0.550137 -0.011644 -0.101393 0.545932 0.0419503 -0.07822079999999999 0.541342 0.0419521 -0.07576720000000001 0.542197 0.041973 -0.092265 0.551797 0.0419595 -0.0573276 0.5454830000000001 0.041978 -0.054875 0.553934 0.041958 -0.0628167 0.544822 0.0419521 -0.07576720000000001 0.542197 0.041957 -0.0656022 0.544357 0.041973 -0.092265 0.551797 0.041957 -0.0656022 0.544357 0.041978 -0.054875 0.553934 0.041973 -0.092265 0.551797 0.041957 -0.0656022 0.544357 0.041958 -0.0628167 0.544822 0.041978 -0.054875 0.553934 -0.011602 -0.095148 0.550137 -0.011504 -0.08834 0.551713 -0.065252 -0.08744300000000001 0.550936 -0.065389 -0.100507 0.5451549999999999 -0.011625 -0.105642 0.539718 -0.011644 -0.101393 0.545932 -0.011644 -0.101393 0.545932 -0.011625 -0.105642 0.539718 0.041951 -0.10567 0.541841 0.0314074 -0.107658 0.5348889999999999 0.0319992 -0.107987 0.533562 0.041933 -0.108151 0.533708 0.0314074 -0.107658 0.5348889999999999 0.041933 -0.108151 0.533708 0.041951 -0.10567 0.541841 0.0309413 -0.107333 0.535934 0.0314074 -0.107658 0.5348889999999999 0.041951 -0.10567 0.541841 0.0205572 -0.10715 0.536107 0.0309413 -0.107333 0.535934 0.041951 -0.10567 0.541841 0.0205572 -0.10715 0.536107 0.041951 -0.10567 0.541841 -0.011625 -0.105642 0.539718 -0.011625 -0.105642 0.539718 -0.0115892 -0.106378 0.536641 0.0205572 -0.10715 0.536107 -0.0162719 -0.106266 0.5367189999999999 -0.0115892 -0.106378 0.536641 -0.011625 -0.105642 0.539718 -0.018422 -0.10622 0.536733 -0.0162719 -0.106266 0.5367189999999999 -0.011625 -0.105642 0.539718 0.041898 -0.109456 0.51732 0.0363704 -0.10879 0.523739 0.0372337 -0.109096 0.521663 0.041898 -0.109456 0.51732 0.0372337 -0.109096 0.521663 0.0380569 -0.109358 0.519748 0.041898 -0.109456 0.51732 0.0380569 -0.109358 0.519748 0.0390585 -0.109678 0.517417 0.041898 -0.109456 0.51732 0.0390585 -0.109678 0.517417 0.0393138 -0.109763 0.5168160000000001 0.041898 -0.109456 0.51732 0.0393138 -0.109763 0.5168160000000001 0.0395599 -0.109838 0.51625 0.0332328 -0.107898 0.530796 0.0363704 -0.10879 0.523739 0.041898 -0.109456 0.51732 0.041965 -0.100874 0.547865 0.041951 -0.10567 0.541841 0.041933 -0.108151 0.533708 0.0418998 -0.108605 0.518491 0.041933 -0.108151 0.533708 0.041898 -0.109456 0.51732 0.0418982 -0.105879 0.517422 0.0418998 -0.108605 0.518491 0.041898 -0.109456 0.51732 0.0419053 -0.10675 0.521044 0.041933 -0.108151 0.533708 0.0418998 -0.108605 0.518491 0.0419182 -0.09948700000000001 0.526511 0.0419053 -0.10675 0.521044 0.0418998 -0.108605 0.518491 0.0419182 -0.09948700000000001 0.526511 0.041933 -0.108151 0.533708 0.0419053 -0.10675 0.521044 0.041965 -0.100874 0.547865 0.041933 -0.108151 0.533708 0.0419182 -0.09948700000000001 0.526511 0.045589 0.092433 0.396825 0.044019 0.098887 0.401952 0.044994 0.09535100000000001 0.404143 0.044019 0.098887 0.401952 0.045589 0.092433 0.396825 0.044019 0.098164 0.388927 0.044994 0.09535100000000001 0.404143 0.044019 0.098887 0.401952 0.043928 0.100007 0.421527 0.043362 0.102135 0.430031 0.042863 0.10249 0.398993 0.042859 0.103849 0.437105 0.043928 0.100007 0.421527 0.042863 0.10249 0.398993 0.043362 0.102135 0.430031 0.044019 0.098887 0.401952 0.042863 0.10249 0.398993 0.043928 0.100007 0.421527 0.04402 0.097305 0.375981 0.044019 0.098164 0.388927 0.045589 0.092433 0.396825 0.044019 0.098164 0.388927 0.042864 0.10172 0.385409 0.044019 0.098887 0.401952 0.042864 0.100806 0.371922 0.042864 0.10172 0.385409 0.044019 0.098164 0.388927 0.04402 0.097305 0.375981 0.042864 0.100806 0.371922 0.044019 0.098164 0.388927 0.042864 0.099831 0.365808 0.042864 0.100806 0.371922 0.04402 0.097305 0.375981 0.04503 0.09288200000000001 0.374278 0.04402 0.09636599999999999 0.370035 0.04503 0.093782 0.380054 0.04402 0.09636599999999999 0.370035 0.04402 0.097305 0.375981 0.04503 0.093782 0.380054 0.04402 0.09636599999999999 0.370035 0.042864 0.099831 0.365808 0.04402 0.097305 0.375981 0.042864 0.099831 0.365808 0.04402 0.09636599999999999 0.370035 0.042864 0.096243 0.362448 0.042864 0.099831 0.365808 0.0424993 0.098358 0.362349 0.0415564 0.100463 0.358989 0.0424993 0.098358 0.362349 0.042864 0.099831 0.365808 0.042864 0.096243 0.362448 0.0421437 0.102506 0.367604 0.0415708 0.104254 0.367907 0.042864 0.100806 0.371922 0.0415617 0.103788 0.363302 0.0421437 0.102506 0.367604 0.042864 0.100806 0.371922 0.0418652 0.101732 0.362399 0.0415617 0.103788 0.363302 0.042864 0.099831 0.365808 0.0415564 0.100463 0.358989 0.0415617 0.103788 0.363302 0.0418652 0.101732 0.362399 0.0415564 0.100463 0.358989 0.0415617 0.103788 0.363302 0.0415604 0.103691 0.363161 0.041549 0.103334 0.357935 0.0415564 0.100463 0.358989 0.041541 0.088299 0.354263 0.041549 0.103334 0.357935 0.041541 0.088299 0.354263 0.024572 0.08803900000000001 0.354568 0.041549 0.103334 0.357935 0.0415604 0.103691 0.363161 0.0415564 0.100463 0.358989 0.042864 0.099831 0.365808 0.0415617 0.103788 0.363302 0.042864 0.100806 0.371922 0.0415564 0.100463 0.358989 0.0415602 0.0882602 0.356609 0.041541 0.088299 0.354263 0.024572 0.08803900000000001 0.354568 0.021541 0.102112 0.357935 0.041549 0.103334 0.357935 0.041563 0.1039 0.364348 0.0421437 0.102506 0.367604 0.0415617 0.103788 0.363302 0.041559 0.106091 0.362725 0.0415708 0.104254 0.367907 0.041563 0.1039 0.364348 0.041559 0.106091 0.362725 0.041563 0.1039 0.364348 0.0415617 0.103788 0.363302 0.041559 0.106091 0.362725 0.0415709 0.104259 0.36799 0.0415708 0.104254 0.367907 0.041559 0.106091 0.362725 0.0415617 0.103788 0.363302 0.0415604 0.103691 0.363161 0.0415711 0.104264 0.368078 0.0415709 0.104259 0.36799 0.041559 0.106091 0.362725 0.0423409 0.103037 0.383491 0.0415709 0.104259 0.36799 0.0415711 0.104264 0.368078 0.0415711 0.104264 0.368078 0.042863 0.10249 0.398993 0.0423409 0.103037 0.383491 0.0415709 0.104259 0.36799 0.0423409 0.103037 0.383491 0.042864 0.10172 0.385409 0.0415602 0.0882602 0.356609 0.0415564 0.100463 0.358989 0.0420702 0.097139 0.359908 0.0415564 0.100463 0.358989 0.042864 0.096243 0.362448 0.0420702 0.097139 0.359908 0.0420702 0.097139 0.359908 0.042864 0.096243 0.362448 0.042747 0.08745699999999999 0.36068 0.042864 0.10172 0.385409 0.0423409 0.103037 0.383491 0.042863 0.10249 0.398993 0.024572 0.08803900000000001 0.354568 0.007603 0.087779 0.354873 0.021541 0.102112 0.357935 0.000980996 0.099699 0.357935 0.007603 0.087779 0.354873 -0.019615 0.101439 0.357935 0.007603 0.087779 0.354873 0.000980996 0.099699 0.357935 0.021541 0.102112 0.357935 0.000980996 0.099699 0.357935 0.021573 0.106091 0.362725 0.021541 0.102112 0.357935 0.0415866 0.104509 0.375111 0.0415711 0.104264 0.368078 0.041559 0.106091 0.362725 0.0417612 0.110111 0.455091 0.0415866 0.104509 0.375111 0.041559 0.106091 0.362725 0.0417612 0.110111 0.455091 0.0417368 0.106904 0.443818 0.0415866 0.104509 0.375111 0.0417612 0.110111 0.455091 0.041559 0.106091 0.362725 0.040704 0.110115 0.455193 0.040704 0.110115 0.455193 0.021573 0.106091 0.362725 0.0361127 0.109979 0.45497 -0.0208223 0.10696 0.5313639999999999 -0.066859 0.10543 0.519894 -0.0868767 0.104765 0.520263 -0.065293 0.106381 0.532132 -0.0208223 0.10696 0.5313639999999999 -0.0868767 0.104765 0.520263 -0.065293 0.106381 0.532132 -0.0868767 0.104765 0.520263 -0.108653 0.104426 0.520135 -0.065293 0.106381 0.532132 -0.108653 0.104426 0.520135 -0.17426 0.101861 0.505578 -0.0115892 0.106378 0.536641 -0.011625 0.105642 0.539718 0.0205572 0.10715 0.536107 -0.0162719 0.106266 0.5367189999999999 -0.011625 0.105642 0.539718 -0.0115892 0.106378 0.536641 0.041933 0.108151 0.533708 0.041951 0.10567 0.541841 0.041965 0.100874 0.547865 0.0314074 0.107658 0.5348889999999999 0.041951 0.10567 0.541841 0.041933 0.108151 0.533708 0.0350025 0.108396 0.526828 0.0319992 0.107987 0.533562 0.041933 0.108151 0.533708 0.0319992 0.107987 0.533562 0.0314074 0.107658 0.5348889999999999 0.041933 0.108151 0.533708 0.0314074 0.107658 0.5348889999999999 0.0309413 0.107333 0.535934 0.041951 0.10567 0.541841 0.041951 0.10567 0.541841 0.0205572 0.10715 0.536107 -0.011625 0.105642 0.539718 -0.0222245 0.106913 0.528226 -0.0261145 0.106509 0.51952 -0.0422016 0.106249 0.519439 -0.0208223 0.10696 0.5313639999999999 -0.0222245 0.106913 0.528226 -0.0422016 0.106249 0.519439 -0.0425439 0.106001 0.535636 -0.0197178 0.106887 0.533836 -0.0201825 0.107125 0.532796 -0.06537 0.104758 0.5389350000000001 -0.065389 0.100507 0.5451549999999999 -0.011625 0.105642 0.539718 -0.065389 0.100507 0.5451549999999999 -0.011644 0.101393 0.545932 -0.011625 0.105642 0.539718 -0.17426 0.101861 0.505578 -0.14146 0.102951 0.488977 -0.17426 0.101861 0.461351 -0.108718 0.104039 0.49018 -0.17426 0.101861 0.461351 -0.14146 0.102951 0.488977 -0.17426 0.101861 0.461351 -0.108718 0.104039 0.49018 -0.10872 0.104013 0.489521 -0.17426 0.101861 0.461351 -0.10872 0.104013 0.489521 -0.10872 0.104006 0.489353 -0.108734 0.103767 0.483282 -0.108743 0.103892 0.479123 -0.17426 0.101861 0.461351 -0.17426 0.101861 0.461351 -0.10872 0.104006 0.489353 -0.108734 0.103767 0.483282 -0.065389 0.100507 0.5451549999999999 -0.119135 0.09962 0.544378 -0.119093 0.093364 0.548588 -0.065347 0.09425600000000001 0.549362 -0.065389 0.100507 0.5451549999999999 -0.119093 0.093364 0.548588 -0.119041 0.105494 0.531342 -0.17426 0.101861 0.505578 -0.17426 0.101861 0.527593 -0.011644 0.101393 0.545932 -0.065389 0.100507 0.5451549999999999 -0.065347 0.09425600000000001 0.549362 -0.011602 0.095148 0.550137 -0.011644 0.101393 0.545932 -0.065347 0.09425600000000001 0.549362 0.041965 0.100874 0.547865 -0.011644 0.101393 0.545932 -0.011602 0.095148 0.550137 -0.108718 0.104039 0.49018 -0.14146 0.102951 0.488977 -0.108691 0.10404 0.502782 -0.10869 0.10404 0.503285 -0.108691 0.10404 0.502782 -0.14146 0.102951 0.488977 -0.108661 0.104041 0.516292 -0.108662 0.104041 0.516104 -0.14146 0.102951 0.488977 -0.17426 0.101861 0.505578 -0.108653 0.104426 0.520135 -0.108661 0.104041 0.516602 -0.108661 0.104041 0.516602 -0.14146 0.102951 0.488977 -0.17426 0.101861 0.505578 -0.119135 0.09962 0.544378 -0.065389 0.100507 0.5451549999999999 -0.06537 0.104758 0.5389350000000001 0.041973 0.092265 0.551797 0.041965 0.100874 0.547865 -0.011602 0.095148 0.550137 0.041973 0.092265 0.551797 -0.011602 0.095148 0.550137 -0.011504 0.08834 0.551713 0.041898 0.109456 0.51732 0.0418982 0.105879 0.517422 0.0418978 0.106004 0.517218 0.041898 0.109456 0.51732 0.0418978 0.106004 0.517218 0.0418924 0.107468 0.514809 0.0350025 0.108396 0.526828 0.041898 0.109456 0.51732 0.0395599 0.109838 0.51625 0.0395599 0.109838 0.51625 0.041898 0.109456 0.51732 0.041883 0.112119 0.510592 0.0418905 0.109061 0.513956 0.041898 0.109456 0.51732 0.0418924 0.107468 0.514809 0.0418905 0.109061 0.513956 0.0418924 0.107468 0.514809 0.0418851 0.109429 0.511525 0.041898 0.109456 0.51732 0.0418905 0.109061 0.513956 0.041883 0.112119 0.510592 0.041973 0.092265 0.551797 0.0419331 0.0918987 0.533554 0.0419457 0.0963864 0.539154 0.0419328 0.0920768 0.533431 0.0419457 0.0963864 0.539154 0.0419331 0.0918987 0.533554 0.041965 0.100874 0.547865 0.041973 0.092265 0.551797 0.0419457 0.0963864 0.539154 0.041965 0.100874 0.547865 0.0419457 0.0963864 0.539154 0.0419182 0.09948700000000001 0.526511 0.0419182 0.09948700000000001 0.526511 0.0419318 0.0957819 0.532832 0.0419328 0.0920768 0.533431 0.0419457 0.0963864 0.539154 0.0419318 0.0957819 0.532832 0.0419182 0.09948700000000001 0.526511 0.0419318 0.0957819 0.532832 0.0419457 0.0963864 0.539154 0.0419328 0.0920768 0.533431 0.041973 0.092265 0.551797 0.0419393 0.0878264 0.536362 0.0419331 0.0918987 0.533554 0.041978 0.054875 0.553934 0.0419594 0.0562953 0.545449 0.0419595 0.0573276 0.5454830000000001 0.041958 0.0628167 0.544822 0.041978 0.054875 0.553934 0.0419595 0.0573276 0.5454830000000001 0.041957 0.0656022 0.544357 0.041978 0.054875 0.553934 0.041958 0.0628167 0.544822 0.041957 0.0656022 0.544357 0.041973 0.092265 0.551797 0.041978 0.054875 0.553934 0.0419622 0.0300187 0.546692 0.0419592 0.0534463 0.545358 0.041978 0.054875 0.553934 0.0419503 0.07822079999999999 0.541342 0.041973 0.092265 0.551797 0.0419521 0.07576720000000001 0.542197 0.0419393 0.0878264 0.536362 0.041973 0.092265 0.551797 0.0419503 0.07822079999999999 0.541342 0.0419622 0.0300187 0.546692 0.0419686 0.00115114 0.549646 0.0419608 0 0.546081 0.0419686 -0.00115114 0.549646 0.0419608 0 0.546081 0.0419686 0.00115114 0.549646 0.0419608 0 0.546081 0.0419686 -0.00115114 0.549646 0.0419622 -0.0300187 0.546692 0.0419521 0.07576720000000001 0.542197 0.041973 0.092265 0.551797 0.041957 0.0656022 0.544357 -0.011602 0.095148 0.550137 -0.065347 0.09425600000000001 0.549362 -0.065252 0.08744300000000001 0.550936 0.0419594 0.0562953 0.545449 0.041978 0.054875 0.553934 0.0419592 0.0534463 0.545358 -0.011625 0.105642 0.539718 -0.011644 0.101393 0.545932 0.041951 0.10567 0.541841 0.041883 0.112119 0.510592 0.0418905 0.109061 0.513956 0.0418834 0.110609 0.510778 -0.119116 0.103874 0.53815 -0.119041 0.105494 0.531342 -0.17426 0.101861 0.527593 0.0418851 -0.109429 0.511525 0.0418905 -0.109061 0.513956 0.0418834 -0.110609 0.510778 0.0418978 -0.106004 0.517218 0.041898 -0.109456 0.51732 0.0418924 -0.107468 0.514809 0.0418924 -0.107468 0.514809 0.041898 -0.109456 0.51732 0.0418905 -0.109061 0.513956 0.0418924 -0.107468 0.514809 0.0418905 -0.109061 0.513956 0.0418851 -0.109429 0.511525 0.0418834 -0.110609 0.510778 0.0418905 -0.109061 0.513956 0.041883 -0.112119 0.510592 0.0418905 -0.109061 0.513956 0.041898 -0.109456 0.51732 0.041883 -0.112119 0.510592 -0.081347 0.100429 0.357935 -0.101896 0.104076 0.362725 -0.060763 0.103796 0.362725 -0.060763 0.103796 0.362725 -0.060753 0.098686 0.357935 -0.081347 0.100429 0.357935 -0.040193 0.101103 0.357935 -0.060753 0.098686 0.357935 -0.060763 0.103796 0.362725 -0.07724300000000001 0.086478 0.356398 -0.060753 0.098686 0.357935 -0.060273 0.086738 0.356093 -0.060753 0.098686 0.357935 -0.07724300000000001 0.086478 0.356398 -0.081347 0.100429 0.357935 -0.040193 0.101103 0.357935 -0.060763 0.103796 0.362725 -0.019615 0.101439 0.357935 -0.060763 0.103796 0.362725 0.021573 0.106091 0.362725 -0.019615 0.101439 0.357935 -0.101896 0.104076 0.362725 -0.17426 0.101861 0.393664 -0.060763 0.103796 0.362725 -0.019615 0.101439 0.357935 -0.026335 0.087259 0.355483 -0.040193 0.101103 0.357935 -0.17387 0.000441005 0.366457 -0.17939 -0.000441005 0.375325 -0.17939 0.000441005 0.375325 -0.121857 0.101838 0.361869 -0.170673 0.10336 0.379379 -0.101896 0.104076 0.362725 -0.149495 0.09779 0.363495 -0.170673 0.10336 0.379379 -0.121857 0.101838 0.361869 -0.173537 -0.047617 0.368218 -0.17387 -0.000441005 0.366457 -0.160668 -0.000441005 0.359253 -0.17387 -0.000441005 0.366457 -0.173537 -0.047617 0.368218 -0.175944 -0.04437 0.373254 -0.175944 -0.04437 0.373254 -0.173537 -0.047617 0.368218 -0.17939 -0.08801200000000001 0.388846 -0.160668 -0.000441005 0.359253 -0.17387 -0.000441005 0.366457 -0.160668 0.000441005 0.359253 -0.17387 -0.000441005 0.366457 -0.17939 -0.000441005 0.375325 -0.17387 0.000441005 0.366457 -0.17387 -0.000441005 0.366457 -0.17387 0.000441005 0.366457 -0.160668 0.000441005 0.359253 -0.160668 -0.000441005 0.359253 -0.160668 0.000441005 0.359253 -0.145687 0.000441004 0.355087 -0.148231 0.049443 0.357251 -0.145687 0.000441004 0.355087 -0.160668 0.000441005 0.359253 -0.140007 0.029219 0.354572 -0.148231 0.049443 0.357251 -0.135472 0.04726 0.354722 -0.140007 0.029219 0.354572 -0.141477 0.02304 0.354537 -0.148231 0.049443 0.357251 -0.141477 0.02304 0.354537 -0.145687 0.000441004 0.355087 -0.148231 0.049443 0.357251 -0.141477 0 0.354537 -0.145687 0.000441004 0.355087 -0.141477 0.02304 0.354537 -0.145687 -0.000441004 0.355087 -0.145687 0.000441004 0.355087 -0.141477 0 0.354537 -0.173537 0.047617 0.368218 -0.160668 0.000441005 0.359253 -0.17387 0.000441005 0.366457 -0.175944 0.04437 0.373254 -0.173537 0.047617 0.368218 -0.17387 0.000441005 0.366457 -0.170673 0.10336 0.379379 -0.162182 0.097984 0.368515 -0.168221 0.098103 0.371579 -0.160836 0.049457 0.361253 -0.168221 0.098103 0.371579 -0.162182 0.097984 0.368515 -0.170673 0.10336 0.379379 -0.168221 0.098103 0.371579 -0.174177 0.095822 0.377275 -0.174177 0.095822 0.377275 -0.17939 0.08801200000000001 0.388846 -0.170673 0.10336 0.379379 -0.17939 0.08801200000000001 0.388846 -0.174177 0.095822 0.377275 -0.173537 0.047617 0.368218 -0.174177 0.095822 0.377275 -0.160836 0.049457 0.361253 -0.173537 0.047617 0.368218 -0.174177 0.095822 0.377275 -0.168221 0.098103 0.371579 -0.160836 0.049457 0.361253 -0.160836 0.049457 0.361253 -0.162182 0.097984 0.368515 -0.149495 0.09779 0.363495 -0.149495 0.09779 0.363495 -0.148231 0.049443 0.357251 -0.160836 0.049457 0.361253 -0.160668 0.000441005 0.359253 -0.173537 0.047617 0.368218 -0.160836 0.049457 0.361253 -0.170673 0.10336 0.379379 -0.17939 0.08801200000000001 0.388846 -0.17426 0.101861 0.393664 -0.17939 0.094905 0.463443 -0.17426 0.101861 0.393664 -0.17939 0.09062199999999999 0.401415 -0.17939 0.09062199999999999 0.401415 -0.17426 0.101861 0.393664 -0.17939 0.08801200000000001 0.388846 -0.162182 0.097984 0.368515 -0.170673 0.10336 0.379379 -0.149495 0.09779 0.363495 -0.121857 0.101838 0.361869 -0.101896 0.104076 0.362725 -0.101926 0.100093 0.357935 -0.040193 0.101103 0.357935 -0.026335 0.087259 0.355483 -0.060273 0.086738 0.356093 -0.101926 0.100093 0.357935 -0.118275 0.079184 0.356402 -0.121857 0.101838 0.361869 -0.118275 0.079184 0.356402 -0.101926 0.100093 0.357935 -0.108735 0.08329499999999999 0.35666 -0.118275 0.079184 0.356402 -0.124983 0.072046 0.355864 -0.121857 0.101838 0.361869 -0.121857 0.101838 0.361869 -0.124983 0.072046 0.355864 -0.135472 0.04726 0.354722 -0.081347 0.100429 0.357935 -0.094212 0.086218 0.356704 -0.101926 0.100093 0.357935 -0.094212 0.086218 0.356704 -0.1026 0.084996 0.356729 -0.101926 0.100093 0.357935 -0.170673 0.10336 0.379379 -0.17426 0.101861 0.393664 -0.101896 0.104076 0.362725 0.041559 0.106091 0.362725 0.0415604 0.103691 0.363161 0.041549 0.103334 0.357935 0.021573 0.106091 0.362725 0.041559 0.106091 0.362725 0.041549 0.103334 0.357935 0.007603 -0.087779 0.354873 -0.019615 -0.101439 0.357935 -0.026335 -0.087259 0.355483 0.0415564 0.100463 0.358989 0.0424993 0.098358 0.362349 0.042864 0.096243 0.362448 -0.17939 -0.000441005 0.375325 -0.17387 -0.000441005 0.366457 -0.175944 -0.04437 0.373254 0.042863 -0.10249 0.398993 0.0415866 -0.104509 0.375111 0.0415711 -0.104264 0.368078 0.0419592 -0.0534463 0.545358 0.041978 -0.054875 0.553934 0.0419594 -0.0562953 0.545449 0.044958 -0.088741 0.370332 0.0447635 -0.0925535 0.372123 0.04402 -0.09636599999999999 0.370035 0.041978 0.054875 0.553934 0.041978 0 0.553934 0.0419686 0.00115114 0.549646 0.0419622 0.0300187 0.546692 0.041978 0.054875 0.553934 0.0419686 0.00115114 0.549646 0.04381 -0.088032 0.364949 0.044958 -0.088741 0.370332 0.04402 -0.092696 0.366597 0.0415709 -0.104259 0.36799 0.0415711 -0.104264 0.368078 0.041559 -0.106091 0.362725 0.0419686 -0.00115114 0.549646 0.041978 -0.054875 0.553934 0.0419622 -0.0300187 0.546692 -0.060753 -0.098686 0.357935 -0.081347 -0.100429 0.357935 -0.07724300000000001 -0.086478 0.356398 -0.108662 0.104041 0.516104 -0.10869 0.10404 0.503285 -0.14146 0.102951 0.488977 0.0361127 0.109979 0.45497 -0.060763 0.103796 0.362725 0.0222217 0.109573 0.454324 -0.10875 0.103984 0.476016 -0.17426 0.101861 0.461351 -0.108743 0.103892 0.479123 -0.10875 0.103984 0.476016 -0.108782 0.104431 0.461051 -0.17426 0.101861 0.461351 0.021541 0.102112 0.357935 0.021573 0.106091 0.362725 0.041549 0.103334 0.357935 -0.018422 -0.10622 0.536733 -0.011625 -0.105642 0.539718 -0.0384796 -0.105834 0.536674 -0.06537 -0.104758 0.5389350000000001 -0.0384796 -0.105834 0.536674 -0.011625 -0.105642 0.539718 -0.0384796 -0.105834 0.536674 -0.0197178 -0.106887 0.533836 -0.0188102 -0.106419 0.535867 -0.0384796 -0.105834 0.536674 -0.0188102 -0.106419 0.535867 -0.018422 -0.10622 0.536733 -0.0384796 0.105834 0.536674 -0.0188102 0.106419 0.535867 -0.0197178 0.106887 0.533836 0.04402 -0.092696 0.366597 0.043693 -0.094531 0.366203 0.042864 -0.096243 0.362448 0.04402 -0.097305 0.375981 0.04503 -0.093782 0.380054 0.045589 -0.092433 0.396825 0.0205572 0.10715 0.536107 0.041951 0.10567 0.541841 0.0309413 0.107333 0.535934 0.0395599 -0.109838 0.51625 0.041883 -0.112119 0.510592 0.041898 -0.109456 0.51732 0.0415564 0.100463 0.358989 0.0418652 0.101732 0.362399 0.042864 0.099831 0.365808 -0.108823 0.104429 0.442579 0.0222217 0.109573 0.454324 -0.17426 0.101861 0.393664 -0.0208223 0.10696 0.5313639999999999 -0.0422016 0.106249 0.519439 -0.066859 0.10543 0.519894 0.04381 -0.088032 0.364949 0.04402 -0.092696 0.366597 0.042864 -0.096243 0.362448 -0.108691 -0.10404 0.502782 -0.14146 -0.102951 0.488977 -0.108718 -0.104039 0.49018 -0.10872 -0.104006 0.489353 -0.10872 -0.104013 0.489521 -0.17426 -0.101861 0.461351 -0.17426 -0.101861 0.461351 -0.10872 -0.104013 0.489521 -0.108718 -0.104039 0.49018 0.0418834 0.110609 0.510778 0.0418905 0.109061 0.513956 0.0418851 0.109429 0.511525 -0.101926 0.100093 0.357935 -0.101896 0.104076 0.362725 -0.081347 0.100429 0.357935 0.041549 -0.103334 0.357935 0.021573 -0.106091 0.362725 0.021541 -0.102112 0.357935 -0.0425439 -0.106001 0.535636 -0.0201825 -0.107125 0.532796 -0.0197178 -0.106887 0.533836 -0.065389 -0.100507 0.5451549999999999 -0.06537 -0.104758 0.5389350000000001 -0.011625 -0.105642 0.539718 -0.0425439 0.106001 0.535636 -0.0201825 0.107125 0.532796 -0.065293 0.106381 0.532132 0.0419686 -0.00115114 0.549646 0.041978 0 0.553934 0.041978 -0.054875 0.553934 0.0415709 -0.104259 0.36799 0.042864 -0.100806 0.371922 0.042864 -0.10172 0.385409 0.044958 -0.088741 0.370332 0.04503 -0.09288200000000001 0.374278 0.0447635 -0.0925535 0.372123 0.0415564 -0.100463 0.358989 0.041541 -0.088299 0.354263 0.0415602 -0.0882602 0.356609 0.0419129 0.101701 0.524294 0.0418998 0.108605 0.518491 0.0419165 0.100044 0.525991 -0.07724300000000001 0.086478 0.356398 -0.094212 0.086218 0.356704 -0.081347 0.100429 0.357935 -0.121857 0.101838 0.361869 -0.135472 0.04726 0.354722 -0.149495 0.09779 0.363495 -0.026335 -0.087259 0.355483 -0.040193 -0.101103 0.357935 -0.060273 -0.086738 0.356093 0.0419457 -0.0963864 0.539154 0.041965 -0.100874 0.547865 0.0419182 -0.09948700000000001 0.526511 -0.160668 0.000441005 0.359253 -0.160836 0.049457 0.361253 -0.148231 0.049443 0.357251 0.0415708 0.104254 0.367907 0.0415709 0.104259 0.36799 0.042864 0.100806 0.371922 -0.094212 -0.086218 0.356704 -0.101926 -0.100093 0.357935 -0.1026 -0.084996 0.356729 -0.065293 -0.106381 0.532132 -0.0208223 -0.10696 0.5313639999999999 -0.0201825 -0.107125 0.532796 0.0415564 -0.100463 0.358989 0.0418652 -0.101732 0.362399 0.0415617 -0.103788 0.363302 0.0415604 -0.103691 0.363161 0.0415617 -0.103788 0.363302 0.0415564 -0.100463 0.358989 -0.108661 0.104041 0.516602 -0.108661 0.104041 0.516292 -0.14146 0.102951 0.488977 -0.118275 -0.079184 0.356402 -0.121857 -0.101838 0.361869 -0.124983 -0.072046 0.355864 -0.065347 -0.09425600000000001 0.549362 -0.065389 -0.100507 0.5451549999999999 -0.011644 -0.101393 0.545932 0.042864 0.100806 0.371922 0.0415709 0.104259 0.36799 0.042864 0.10172 0.385409 -0.0384796 0.105834 0.536674 -0.018422 0.10622 0.536733 -0.0188102 0.106419 0.535867 -0.060763 -0.103796 0.362725 -0.101896 -0.104076 0.362725 -0.081347 -0.100429 0.357935 -0.0162719 0.106266 0.5367189999999999 -0.018422 0.10622 0.536733 -0.011625 0.105642 0.539718 -0.160836 -0.049457 0.361253 -0.173537 -0.047617 0.368218 -0.160668 -0.000441005 0.359253 -0.17426 0.101861 0.461351 -0.108823 0.104429 0.442579 -0.17426 0.101861 0.393664 -0.1026 0.084996 0.356729 -0.108735 0.08329499999999999 0.35666 -0.101926 0.100093 0.357935 -0.160668 -0.000441005 0.359253 -0.145687 0.000441004 0.355087 -0.145687 -0.000441004 0.355087 0.000980996 -0.099699 0.357935 0.021573 -0.106091 0.362725 -0.019615 -0.101439 0.357935 -0.17939 0.094905 0.463443 -0.17939 0.09062199999999999 0.401415 -0.17939 0.08801200000000001 0.388846 -0.119041 0.105494 0.531342 -0.119116 0.103874 0.53815 -0.065293 0.106381 0.532132 0.04402 0.09636599999999999 0.370035 0.04503 0.09288200000000001 0.374278 0.0447635 0.0925535 0.372123 0.04402 0.09636599999999999 0.370035 0.043693 0.094531 0.366203 0.042864 0.096243 0.362448 -0.135472 0.04726 0.354722 -0.148231 0.049443 0.357251 -0.149495 0.09779 0.363495 0.042863 -0.10249 0.398993 0.0417368 -0.106904 0.443818 0.0415866 -0.104509 0.375111 -0.065252 0.08744300000000001 0.550936 -0.011504 0.08834 0.551713 -0.011602 0.095148 0.550137 -0.175944 0.04437 0.373254 -0.17939 0.0412 0.378925 -0.17939 0.08801200000000001 0.388846 -0.17939 0.08801200000000001 0.388846 -0.173537 0.047617 0.368218 -0.175944 0.04437 0.373254 0.041898 0.109456 0.51732 0.0418998 0.108605 0.518491 0.0418982 0.105879 0.517422 -0.141477 -0.02304 0.354537 -0.145687 -0.000441004 0.355087 -0.141477 0 0.354537 -0.040193 0.101103 0.357935 -0.060273 0.086738 0.356093 -0.060753 0.098686 0.357935 0.000980996 -0.099699 0.357935 0.021541 -0.102112 0.357935 0.021573 -0.106091 0.362725 -0.011644 -0.101393 0.545932 -0.011602 -0.095148 0.550137 -0.065347 -0.09425600000000001 0.549362 -0.119041 0.105494 0.531342 -0.065293 0.106381 0.532132 -0.17426 0.101861 0.505578 -0.07724300000000001 -0.086478 0.356398 -0.081347 -0.100429 0.357935 -0.094212 -0.086218 0.356704 0.041933 0.108151 0.533708 0.041965 0.100874 0.547865 0.0419182 0.09948700000000001 0.526511 0.042864 -0.100806 0.371922 0.042864 -0.099831 0.365808 0.04402 -0.097305 0.375981 0.0418982 -0.105879 0.517422 0.0419097 -0.102618 0.5227850000000001 0.0418998 -0.108605 0.518491 -0.011625 0.105642 0.539718 -0.018422 0.10622 0.536733 -0.0384796 0.105834 0.536674 0.044019 -0.098164 0.388927 0.045589 -0.092433 0.396825 0.044019 -0.098887 0.401952 0.041563 0.1039 0.364348 0.0415708 0.104254 0.367907 0.0421437 0.102506 0.367604 -0.108661 -0.104041 0.516602 -0.14146 -0.102951 0.488977 -0.108661 -0.104041 0.516292 0.0419594 -0.0562953 0.545449 0.041978 -0.054875 0.553934 0.0419595 -0.0573276 0.5454830000000001 -0.019615 0.101439 0.357935 0.021573 0.106091 0.362725 0.000980996 0.099699 0.357935 0.042864 0.10172 0.385409 0.042863 0.10249 0.398993 0.044019 0.098887 0.401952 -0.065293 0.106381 0.532132 -0.0201825 0.107125 0.532796 -0.0208223 0.10696 0.5313639999999999 0.0332328 -0.107898 0.530796 0.041898 -0.109456 0.51732 0.041933 -0.108151 0.533708 -0.019615 -0.101439 0.357935 -0.040193 -0.101103 0.357935 -0.026335 -0.087259 0.355483 -0.011602 -0.095148 0.550137 -0.065252 -0.08744300000000001 0.550936 -0.065347 -0.09425600000000001 0.549362 0.0417368 0.106904 0.443818 0.042863 0.10249 0.398993 0.0415866 0.104509 0.375111 0.042178 0.105959 0.446111 0.0417368 0.106904 0.443818 0.0417532 0.107167 0.451436 0.042178 0.105959 0.446111 0.042863 0.10249 0.398993 0.0417368 0.106904 0.443818 -0.011644 0.101393 0.545932 0.041965 0.100874 0.547865 0.041951 0.10567 0.541841 -0.108782 0.104431 0.461051 -0.108823 0.104429 0.442579 -0.17426 0.101861 0.461351 -0.060753 -0.098686 0.357935 -0.060763 -0.103796 0.362725 -0.081347 -0.100429 0.357935 -0.0868767 -0.104765 0.520263 -0.0208223 -0.10696 0.5313639999999999 -0.065293 -0.106381 0.532132 0.0419686 0.00115114 0.549646 0.041978 0 0.553934 0.0419686 -0.00115114 0.549646 0.0361127 0.109979 0.45497 0.021573 0.106091 0.362725 -0.060763 0.103796 0.362725 -0.0868767 -0.104765 0.520263 -0.066859 -0.10543 0.519894 -0.0208223 -0.10696 0.5313639999999999 -0.06537 0.104758 0.5389350000000001 -0.0384796 0.105834 0.536674 -0.0197178 0.106887 0.533836 0.0415564 -0.100463 0.358989 0.0415604 -0.103691 0.363161 0.041549 -0.103334 0.357935 -0.10875 -0.103984 0.476016 -0.17426 -0.101861 0.461351 -0.108782 -0.104431 0.461051 0.0415708 -0.104254 0.367907 0.0415709 -0.104259 0.36799 0.041559 -0.106091 0.362725 0.042863 -0.10249 0.398993 0.043928 -0.100007 0.421527 0.043362 -0.102135 0.430031 -0.17939 -0.000441005 0.375325 -0.175944 -0.04437 0.373254 -0.17939 -0.0412 0.378925 0.042747 0.08745699999999999 0.36068 0.0415602 0.0882602 0.356609 0.0420702 0.097139 0.359908 -0.17939 0.094905 0.463443 -0.17426 0.101861 0.461351 -0.17426 0.101861 0.393664 0.007603 0.087779 0.354873 -0.026335 0.087259 0.355483 -0.019615 0.101439 0.357935 0.0418978 -0.106004 0.517218 0.0418982 -0.105879 0.517422 0.041898 -0.109456 0.51732 0.042747 -0.08745699999999999 0.36068 0.042864 -0.096243 0.362448 0.0420702 -0.097139 0.359908 0.0415604 -0.103691 0.363161 0.0415617 -0.103788 0.363302 0.041559 -0.106091 0.362725 0.0419622 -0.0300187 0.546692 0.041978 -0.054875 0.553934 0.0419592 -0.0534463 0.545358 0.042863 0.10249 0.398993 0.0415711 0.104264 0.368078 0.0415866 0.104509 0.375111 0.0319992 -0.107987 0.533562 0.0332328 -0.107898 0.530796 0.041933 -0.108151 0.533708 0.040704 0.110115 0.455193 0.041559 0.106091 0.362725 0.021573 0.106091 0.362725 -0.17426 -0.101861 0.461351 -0.108718 -0.104039 0.49018 -0.14146 -0.102951 0.488977 -0.17426 0.101861 0.393664 0.0222217 0.109573 0.454324 -0.060763 0.103796 0.362725 0.045693 0.089558 0.376733 0.04503 0.09288200000000001 0.374278 0.045859 0.090318 0.382877 -0.148231 -0.049443 0.357251 -0.135472 -0.04726 0.354722 -0.149495 -0.09779 0.363495 0.041973 -0.092265 0.551797 -0.011504 -0.08834 0.551713 -0.011602 -0.095148 0.550137 0.0418998 -0.108605 0.518491 0.0419097 -0.102618 0.5227850000000001 0.0419129 -0.101701 0.524294 0.045589 0.092433 0.396825 0.04503 0.093782 0.380054 0.04402 0.097305 0.375981 0.042863 0.10249 0.398993 0.042178 0.105959 0.446111 0.042859 0.103849 0.437105 -0.17939 -0.0412 0.378925 -0.175944 -0.04437 0.373254 -0.17939 -0.08801200000000001 0.388846 -0.011625 0.105642 0.539718 -0.0384796 0.105834 0.536674 -0.06537 0.104758 0.5389350000000001 -0.160836 -0.049457 0.361253 -0.148231 -0.049443 0.357251 -0.149495 -0.09779 0.363495 -0.121857 -0.101838 0.361869 -0.118275 -0.079184 0.356402 -0.101926 -0.100093 0.357935 -0.011644 -0.101393 0.545932 0.041951 -0.10567 0.541841 0.041965 -0.100874 0.547865 0.0417612 0.110111 0.455091 0.0417532 0.107167 0.451436 0.0417368 0.106904 0.443818 -0.0197178 -0.106887 0.533836 -0.0384796 -0.105834 0.536674 -0.06537 -0.104758 0.5389350000000001 -0.06537 0.104758 0.5389350000000001 -0.0197178 0.106887 0.533836 -0.0425439 0.106001 0.535636 -0.108734 -0.103767 0.483282 -0.10872 -0.104006 0.489353 -0.17426 -0.101861 0.461351 -0.172479 0 0.550621 -0.17939 0.000441013 0.545105 -0.17939 -0.000441013 0.545105 -0.17939 0.000441013 0.545105 -0.18153 0.00136144 0.478445 -0.17939 -0.000441013 0.545105 -0.119093 -0.093364 0.548588 -0.173253 -0.08555699999999999 0.548662 -0.17326 -0.09257899999999999 0.546386 -0.173253 -0.08555699999999999 0.548662 -0.17939 -0.084383 0.542888 -0.17326 -0.09257899999999999 0.546386 -0.17939 -0.078511 0.545105 -0.17939 -0.084383 0.542888 -0.173253 -0.08555699999999999 0.548662 -0.176481 -0.093793 0.53695 -0.17326 -0.09257899999999999 0.546386 -0.17939 -0.084383 0.542888 -0.17939 -0.09594900000000001 0.526394 -0.176481 -0.093793 0.53695 -0.17939 -0.088258 0.535483 -0.176481 -0.093793 0.53695 -0.17939 -0.084383 0.542888 -0.17939 -0.088258 0.535483 -0.17939 -0.094905 0.463443 -0.17939 -0.09594900000000001 0.526394 -0.17939 -0.088258 0.535483 -0.17939 -0.094905 0.463443 -0.17939 -0.088258 0.535483 -0.17939 -0.084383 0.542888 -0.17939 -0.09594900000000001 0.526394 -0.172671 -0.101859 0.538222 -0.176481 -0.093793 0.53695 -0.119116 -0.103874 0.53815 -0.119135 -0.09962 0.544378 -0.172671 -0.101859 0.538222 -0.119135 -0.09962 0.544378 -0.119093 -0.093364 0.548588 -0.172671 -0.101859 0.538222 -0.065389 -0.100507 0.5451549999999999 -0.119093 -0.093364 0.548588 -0.119135 -0.09962 0.544378 -0.17426 -0.101861 0.527593 -0.119116 -0.103874 0.53815 -0.172671 -0.101859 0.538222 -0.119041 -0.105494 0.531342 -0.119116 -0.103874 0.53815 -0.17426 -0.101861 0.527593 -0.065293 -0.106381 0.532132 -0.119041 -0.105494 0.531342 -0.17426 -0.101861 0.505578 -0.108653 -0.104426 0.520135 -0.065293 -0.106381 0.532132 -0.17426 -0.101861 0.505578 -0.17426 -0.101861 0.505578 -0.14146 -0.102951 0.488977 -0.108661 -0.104041 0.516602 -0.108661 -0.104041 0.516602 -0.108653 -0.104426 0.520135 -0.17426 -0.101861 0.505578 -0.17426 -0.101861 0.505578 -0.119041 -0.105494 0.531342 -0.17426 -0.101861 0.527593 -0.17426 -0.101861 0.527593 -0.17939 -0.09594900000000001 0.526394 -0.17426 -0.101861 0.505578 -0.181816 -0.0449778 0.468768 -0.181835 -0.0451832 0.468155 -0.17939 -0.041049 0.545105 -0.181835 -0.0451832 0.468155 -0.181892 -0.0454398 0.466361 -0.17939 -0.041049 0.545105 -0.17939 -0.041049 0.545105 -0.18168 -0.0427767 0.473098 -0.181767 -0.04438 0.470309 -0.18168 -0.0427767 0.473098 -0.17939 -0.041049 0.545105 -0.181678 -0.042749 0.473146 -0.181892 -0.0454398 0.466361 -0.181914 -0.0455268 0.465668 -0.17939 -0.041049 0.545105 -0.181914 -0.0455268 0.465668 -0.182 -0.0458 0.46297 -0.17939 -0.041049 0.545105 -0.17939 -0.041049 0.545105 -0.182 -0.0458 0.46297 -0.17939 -0.063845 0.545105 -0.181767 -0.04438 0.470309 -0.181768 -0.0443846 0.470297 -0.17939 -0.041049 0.545105 0.041973 -0.092265 0.551797 0.041978 -0.054875 0.553934 -0.172479 -0.055882 0.550621 -0.172479 -0.055882 0.550621 -0.17314 -0.067366 0.549746 0.041973 -0.092265 0.551797 -0.011504 -0.08834 0.551713 -0.17314 -0.067366 0.549746 -0.065252 -0.08744300000000001 0.550936 -0.17314 -0.067366 0.549746 -0.011504 -0.08834 0.551713 0.041973 -0.092265 0.551797 -0.119 -0.086545 0.550161 -0.065252 -0.08744300000000001 0.550936 -0.17314 -0.067366 0.549746 -0.119 -0.086545 0.550161 -0.17314 -0.067366 0.549746 -0.173253 -0.08555699999999999 0.548662 -0.17939 0.088258 0.535483 -0.17939 0.084383 0.542888 -0.176481 0.093793 0.53695 -0.17939 0.094905 0.463443 -0.17939 0.084383 0.542888 -0.17939 0.088258 0.535483 -0.17426 0.101861 0.461351 -0.17939 0.094905 0.463443 -0.17426 0.101861 0.505578 -0.17939 0.09594900000000001 0.526394 -0.17426 0.101861 0.505578 -0.17939 0.094905 0.463443 -0.17939 0.094905 0.463443 -0.17939 0.088258 0.535483 -0.17939 0.09594900000000001 0.526394 -0.17426 0.101861 0.505578 -0.17939 0.09594900000000001 0.526394 -0.17426 0.101861 0.527593 -0.119093 0.093364 0.548588 -0.119135 0.09962 0.544378 -0.172671 0.101859 0.538222 -0.119093 0.093364 0.548588 -0.172671 0.101859 0.538222 -0.17326 0.09257899999999999 0.546386 -0.176481 0.093793 0.53695 -0.17326 0.09257899999999999 0.546386 -0.172671 0.101859 0.538222 -0.176481 0.093793 0.53695 -0.172671 0.101859 0.538222 -0.17939 0.09594900000000001 0.526394 -0.17326 0.09257899999999999 0.546386 -0.173253 0.08555699999999999 0.548662 -0.119093 0.093364 0.548588 -0.17326 0.09257899999999999 0.546386 -0.17939 0.084383 0.542888 -0.173253 0.08555699999999999 0.548662 -0.172671 0.101859 0.538222 -0.17426 0.101861 0.527593 -0.17939 0.09594900000000001 0.526394 -0.173253 0.08555699999999999 0.548662 -0.17939 0.084383 0.542888 -0.17939 0.078511 0.545105 -0.119 0.086545 0.550161 -0.119093 0.093364 0.548588 -0.173253 0.08555699999999999 0.548662 -0.119 0.086545 0.550161 -0.173253 0.08555699999999999 0.548662 -0.17314 0.067366 0.549746 -0.181892 0.0454398 0.466361 -0.181835 0.0451832 0.468155 -0.17939 0.041049 0.545105 -0.181835 0.0451832 0.468155 -0.181816 0.0449778 0.468768 -0.17939 0.041049 0.545105 -0.181816 0.0449778 0.468768 -0.181768 0.0443846 0.470297 -0.17939 0.041049 0.545105 -0.181914 0.0455268 0.465668 -0.181892 0.0454398 0.466361 -0.17939 0.041049 0.545105 -0.182 0.0458 0.46297 -0.181914 0.0455268 0.465668 -0.17939 0.041049 0.545105 -0.17939 0.063845 0.545105 -0.182 0.0458 0.46297 -0.17939 0.041049 0.545105 -0.181767 0.04438 0.470309 -0.18168 0.0427767 0.473098 -0.17939 0.041049 0.545105 -0.18168 0.0427767 0.473098 -0.181678 0.042749 0.473146 -0.17939 0.041049 0.545105 -0.065347 0.09425600000000001 0.549362 -0.119093 0.093364 0.548588 -0.119 0.086545 0.550161 -0.011504 0.08834 0.551713 -0.065252 0.08744300000000001 0.550936 -0.17314 0.067366 0.549746 0.041973 0.092265 0.551797 -0.011504 0.08834 0.551713 -0.17314 0.067366 0.549746 -0.17314 0.067366 0.549746 -0.172479 0.055882 0.550621 0.041973 0.092265 0.551797 -0.172479 0.055882 0.550621 -0.17314 0.067366 0.549746 -0.17939 0.063845 0.545105 0.041978 0.054875 0.553934 0.041973 0.092265 0.551797 -0.172479 0.055882 0.550621 -0.0652505 0.027941 0.552278 0.041978 0.054875 0.553934 -0.172479 0.055882 0.550621 -0.06512850000000001 0 0.552279 0.041978 0.054875 0.553934 -0.0652505 0.027941 0.552278 0.041978 0 0.553934 0.041978 0.054875 0.553934 -0.06512850000000001 0 0.552279 0.041978 -0.054875 0.553934 0.041978 0 0.553934 -0.06512850000000001 0 0.552279 0.041978 -0.054875 0.553934 -0.06512850000000001 0 0.552279 -0.0652505 -0.027941 0.552278 -0.06512850000000001 0 0.552279 -0.172479 0 0.550621 -0.0652505 -0.027941 0.552278 -0.0652505 -0.027941 0.552278 -0.172479 0 0.550621 -0.172479 -0.055882 0.550621 -0.119116 0.103874 0.53815 -0.17426 0.101861 0.527593 -0.172671 0.101859 0.538222 -0.17939 0.063845 0.545105 -0.17314 0.067366 0.549746 -0.17939 0.078511 0.545105 -0.172671 0.101859 0.538222 -0.119135 0.09962 0.544378 -0.119116 0.103874 0.53815 -0.181543 0.0373822 0.477508 -0.18154 0.03725 0.477588 -0.180705 0.0267743 0.504038 -0.181601 0.040554 0.475599 -0.181543 0.0373822 0.477508 -0.180705 0.0267743 0.504038 -0.181517 0.0337511 0.478379 -0.180705 0.0267743 0.504038 -0.18154 0.03725 0.477588 -0.181604 0.0406156 0.47553 -0.181601 0.040554 0.475599 -0.17939 0.041049 0.545105 -0.181768 -0.0443846 0.470297 -0.181816 -0.0449778 0.468768 -0.17939 -0.041049 0.545105 -0.181678 -0.042749 0.473146 -0.17939 -0.041049 0.545105 -0.181604 -0.0406156 0.47553 -0.17314 0.067366 0.549746 -0.173253 0.08555699999999999 0.548662 -0.17939 0.078511 0.545105 -0.172671 -0.101859 0.538222 -0.17939 -0.09594900000000001 0.526394 -0.17426 -0.101861 0.527593 -0.181527 -0.013635 0.478445 -0.181522 -0.021259 0.478445 -0.180705 -0.0267743 0.504038 -0.181522 -0.021259 0.478445 -0.181522 -0.0215476 0.478445 -0.180705 -0.0267743 0.504038 -0.181527 -0.012981 0.478445 -0.181527 -0.013635 0.478445 -0.180705 -0.0267743 0.504038 -0.18152 0.025398 0.478445 -0.181522 0.0215476 0.478445 -0.180705 0.0267743 0.504038 -0.18152 0.0259237 0.478443 -0.18152 0.025398 0.478445 -0.180705 0.0267743 0.504038 -0.181516 0.033568 0.47842 -0.18152 0.0259237 0.478443 -0.180705 0.0267743 0.504038 -0.18153 0.00136144 0.478445 -0.18153 -0.00136144 0.478445 -0.17939 -0.000441013 0.545105 -0.180705 0.0267743 0.504038 -0.18153 0.0077485 0.478445 -0.17939 0.041049 0.545105 -0.18153 0.0077485 0.478445 -0.17939 0.000441013 0.545105 -0.17939 0.041049 0.545105 -0.181527 0.012981 0.478445 -0.18153 0.0077485 0.478445 -0.180705 0.0267743 0.504038 -0.181527 0.013635 0.478445 -0.181527 0.012981 0.478445 -0.180705 0.0267743 0.504038 -0.17939 0.041049 0.545105 -0.17939 0.000441013 0.545105 -0.172479 0.055882 0.550621 -0.180705 -0.0267743 0.504038 -0.18154 -0.03725 0.477588 -0.181543 -0.0373822 0.477508 -0.181517 -0.0337511 0.478379 -0.18154 -0.03725 0.477588 -0.180705 -0.0267743 0.504038 -0.181517 -0.0337511 0.478379 -0.180705 -0.0267743 0.504038 -0.181516 -0.033568 0.47842 -0.18152 -0.0259237 0.478443 -0.181516 -0.033568 0.47842 -0.180705 -0.0267743 0.504038 -0.18152 -0.025398 0.478445 -0.18152 -0.0259237 0.478443 -0.180705 -0.0267743 0.504038 -0.17939 0.09594900000000001 0.526394 -0.17939 0.088258 0.535483 -0.176481 0.093793 0.53695 0.041978 -0.054875 0.553934 -0.0652505 -0.027941 0.552278 -0.172479 -0.055882 0.550621 -0.18153 -0.0077485 0.478445 -0.181527 -0.012981 0.478445 -0.180705 -0.0267743 0.504038 -0.181601 -0.040554 0.475599 -0.17939 -0.041049 0.545105 -0.180705 -0.0267743 0.504038 -0.18153 -0.0077485 0.478445 -0.180705 -0.0267743 0.504038 -0.17939 -0.041049 0.545105 -0.18153 -0.0077485 0.478445 -0.17939 -0.041049 0.545105 -0.17939 -0.000441013 0.545105 -0.172479 -0.055882 0.550621 -0.17939 -0.000441013 0.545105 -0.17939 -0.041049 0.545105 -0.172479 0 0.550621 -0.0652505 0.027941 0.552278 -0.172479 0.055882 0.550621 -0.119 -0.086545 0.550161 -0.065347 -0.09425600000000001 0.549362 -0.065252 -0.08744300000000001 0.550936 -0.17314 0.067366 0.549746 -0.065252 0.08744300000000001 0.550936 -0.119 0.086545 0.550161 -0.17939 -0.09594900000000001 0.526394 -0.17939 -0.094905 0.463443 -0.17426 -0.101861 0.505578 -0.176481 0.093793 0.53695 -0.17939 0.084383 0.542888 -0.17326 0.09257899999999999 0.546386 -0.181522 0.021259 0.478445 -0.181527 0.013635 0.478445 -0.180705 0.0267743 0.504038 -0.17939 -0.078511 0.545105 -0.173253 -0.08555699999999999 0.548662 -0.17314 -0.067366 0.549746 -0.17939 -0.078511 0.545105 -0.17314 -0.067366 0.549746 -0.17939 -0.063845 0.545105 -0.18153 -0.0077485 0.478445 -0.17939 -0.000441013 0.545105 -0.18153 -0.00136144 0.478445 -0.181678 0.042749 0.473146 -0.181604 0.0406156 0.47553 -0.17939 0.041049 0.545105 -0.181522 -0.0215476 0.478445 -0.18152 -0.025398 0.478445 -0.180705 -0.0267743 0.504038 -0.181768 0.0443846 0.470297 -0.181767 0.04438 0.470309 -0.17939 0.041049 0.545105 -0.181543 -0.0373822 0.477508 -0.181601 -0.040554 0.475599 -0.180705 -0.0267743 0.504038 -0.17426 -0.101861 0.505578 -0.17939 -0.094905 0.463443 -0.17426 -0.101861 0.461351 -0.06512850000000001 0 0.552279 -0.0652505 0.027941 0.552278 -0.172479 0 0.550621 -0.119093 -0.093364 0.548588 -0.17326 -0.09257899999999999 0.546386 -0.172671 -0.101859 0.538222 -0.17939 0.041049 0.545105 -0.172479 0.055882 0.550621 -0.17939 0.063845 0.545105 -0.065389 -0.100507 0.5451549999999999 -0.065347 -0.09425600000000001 0.549362 -0.119093 -0.093364 0.548588 -0.119093 -0.093364 0.548588 -0.119 -0.086545 0.550161 -0.173253 -0.08555699999999999 0.548662 -0.17939 -0.063845 0.545105 -0.172479 -0.055882 0.550621 -0.17939 -0.041049 0.545105 -0.181522 0.0215476 0.478445 -0.181522 0.021259 0.478445 -0.180705 0.0267743 0.504038 -0.181601 -0.040554 0.475599 -0.181604 -0.0406156 0.47553 -0.17939 -0.041049 0.545105 -0.18153 0.0077485 0.478445 -0.18153 0.00136144 0.478445 -0.17939 0.000441013 0.545105 -0.172479 -0.055882 0.550621 -0.172479 0 0.550621 -0.17939 -0.000441013 0.545105 -0.181601 0.040554 0.475599 -0.180705 0.0267743 0.504038 -0.17939 0.041049 0.545105 -0.17939 0.000441013 0.545105 -0.172479 0 0.550621 -0.172479 0.055882 0.550621 -0.17426 -0.101861 0.505578 -0.17426 -0.101861 0.461351 -0.14146 -0.102951 0.488977 -0.17314 -0.067366 0.549746 -0.172479 -0.055882 0.550621 -0.17939 -0.063845 0.545105 -0.181516 0.033568 0.47842 -0.180705 0.0267743 0.504038 -0.181517 0.0337511 0.478379 -0.065252 0.08744300000000001 0.550936 -0.065347 0.09425600000000001 0.549362 -0.119 0.086545 0.550161 -0.176481 -0.093793 0.53695 -0.172671 -0.101859 0.538222 -0.17326 -0.09257899999999999 0.546386 -0.065347 -0.09425600000000001 0.549362 -0.119 -0.086545 0.550161 -0.119093 -0.093364 0.548588 0.0793606 0.0429314 0.470023 0.07935349999999999 0.043105 0.470231 0.080232 0.043105 0.470231 0.0793606 0.0429314 0.470023 0.080232 0.043105 0.470231 0.07984479999999999 0.0421185 0.46905 0.077801 0.075124 0.452 0.07935349999999999 0.043105 0.470231 0.0793606 0.0429314 0.470023 0.077801 0.075124 0.452 0.0793606 0.0429314 0.470023 0.07943509999999999 0.041132 0.46787 0.07935349999999999 0.043105 0.470231 0.07977480000000001 0.043627 0.471354 0.080232 0.043105 0.470231 0.0793176 0.0440597 0.472285 0.07977480000000001 0.043627 0.471354 0.07935349999999999 0.043105 0.470231 0.0793176 0.0440597 0.472285 0.080167 0.044149 0.472477 0.07977480000000001 0.043627 0.471354 0.080167 0.044149 0.472477 0.080232 0.043105 0.470231 0.07977480000000001 0.043627 0.471354 0.0793176 0.0440597 0.472285 0.0793143 0.044149 0.472477 0.080167 0.044149 0.472477 0.080111 0.045055 0.474428 0.080167 0.044149 0.472477 0.07972509999999999 0.044602 0.473453 0.0792831 0.0449796 0.474266 0.080111 0.045055 0.474428 0.07972509999999999 0.044602 0.473453 0.0793143 0.044149 0.472477 0.07972509999999999 0.044602 0.473453 0.080167 0.044149 0.472477 0.077801 0.075124 0.452 0.07943509999999999 0.041132 0.46787 0.07943890000000001 0.0410435 0.467806 0.080329 0.041132 0.46787 0.079884 0.0408845 0.46769 0.07943890000000001 0.0410435 0.467806 0.07943509999999999 0.041132 0.46787 0.07943890000000001 0.0410435 0.467806 0.080329 0.041132 0.46787 0.07943509999999999 0.041132 0.46787 0.07984479999999999 0.0421185 0.46905 0.080329 0.041132 0.46787 0.080329 0.041132 0.46787 0.07990650000000001 0.040637 0.467511 0.079884 0.0408845 0.46769 0.08014019999999999 0.040637 0.467511 0.07990650000000001 0.040637 0.467511 0.080329 0.041132 0.46787 0.0799289 0.0397628 0.466877 0.0799634 0.0393835 0.466602 0.07948379999999999 0.040006 0.467053 0.0799634 0.0393835 0.466602 0.0799289 0.0397628 0.466877 0.080374 0.040142 0.467152 0.080443 0.038625 0.466051 0.0799634 0.0393835 0.466602 0.080374 0.040142 0.467152 0.080374 0.040142 0.467152 0.082525 0.040197 0.472918 0.080443 0.038625 0.466051 0.080329 0.041132 0.46787 0.082525 0.040197 0.472918 0.080374 0.040142 0.467152 0.080443 0.038625 0.466051 0.07954360000000001 0.038625 0.466051 0.0799634 0.0393835 0.466602 0.080443 0.038625 0.466051 0.0795553 0.0383616 0.465947 0.07954360000000001 0.038625 0.466051 0.080329 0.041132 0.46787 0.080232 0.043105 0.470231 0.082525 0.040197 0.472918 0.080374 0.040142 0.467152 0.0799289 0.0397628 0.466877 0.07948379999999999 0.040006 0.467053 0.07943890000000001 0.0410435 0.467806 0.0796727 0.0405927 0.467479 0.0794779 0.040142 0.467152 0.077801 0.075124 0.452 0.07943890000000001 0.0410435 0.467806 0.0794779 0.040142 0.467152 0.0794779 0.040142 0.467152 0.079926 0.0402658 0.467242 0.080374 0.040142 0.467152 0.079926 0.0403895 0.467332 0.079926 0.0402658 0.467242 0.080374 0.040142 0.467152 0.080374 0.040142 0.467152 0.07948379999999999 0.040006 0.467053 0.0794779 0.040142 0.467152 0.077801 0.075124 0.452 0.0794779 0.040142 0.467152 0.07948379999999999 0.040006 0.467053 0.077801 0.075124 0.452 0.07948379999999999 0.040006 0.467053 0.07954360000000001 0.038625 0.466051 0.080232 0.043105 0.470231 0.080329 0.041132 0.46787 0.07984479999999999 0.0421185 0.46905 0.0792831 0.0449796 0.474266 0.0792803 0.045055 0.474428 0.080111 0.045055 0.474428 0.077801 0.075124 0.452 0.0792803 0.045055 0.474428 0.0792831 0.0449796 0.474266 0.0793143 0.044149 0.472477 0.077801 0.075124 0.452 0.0792831 0.0449796 0.474266 0.0792803 0.045055 0.474428 0.0796762 0.0453885 0.476714 0.080111 0.045055 0.474428 0.0792721 0.0454926 0.477428 0.0796762 0.0453885 0.476714 0.0792803 0.045055 0.474428 0.0792721 0.0454926 0.477428 0.08001900000000001 0.045722 0.479 0.0796762 0.0453885 0.476714 0.0799634 0.0393835 0.466602 0.07954360000000001 0.038625 0.466051 0.07948379999999999 0.040006 0.467053 0.080374 0.040142 0.467152 0.079926 0.0403895 0.467332 0.07990650000000001 0.040637 0.467511 0.079926 0.0403895 0.467332 0.0794779 0.040142 0.467152 0.07990650000000001 0.040637 0.467511 0.0793606 0.0429314 0.470023 0.07984479999999999 0.0421185 0.46905 0.07943509999999999 0.041132 0.46787 0.079884 0.0408845 0.46769 0.07990650000000001 0.040637 0.467511 0.07943890000000001 0.0410435 0.467806 0.080374 0.040142 0.467152 0.08014019999999999 0.040637 0.467511 0.080329 0.041132 0.46787 0.07935349999999999 0.043105 0.470231 0.077801 0.075124 0.452 0.0793176 0.0440597 0.472285 0.077801 0.075124 0.452 0.07954360000000001 0.038625 0.466051 0.0795553 0.0383616 0.465947 0.080443 0.038625 0.466051 0.083757 0.03397 0.471612 0.080567 0.035695 0.464894 0.080567 0.035695 0.464894 0.0800612 0.03716 0.465473 0.080443 0.038625 0.466051 0.080567 0.035695 0.464894 0.08015360000000001 0.034827 0.464783 0.0796743 0.035695 0.464894 0.08015360000000001 0.034827 0.464783 0.0797466 0.0341119 0.464691 0.0796743 0.035695 0.464894 0.080567 0.035695 0.464894 0.0796743 0.035695 0.464894 0.0800612 0.03716 0.465473 0.080633 0.033959 0.464671 0.08015360000000001 0.034827 0.464783 0.080567 0.035695 0.464894 0.077801 0.075124 0.452 0.0796743 0.035695 0.464894 0.0797466 0.0341119 0.464691 0.077801 0.075124 0.452 0.0795553 0.0383616 0.465947 0.0796743 0.035695 0.464894 0.0795553 0.0383616 0.465947 0.0800612 0.03716 0.465473 0.0796743 0.035695 0.464894 0.080633 0.033959 0.464671 0.0797466 0.0341119 0.464691 0.08015360000000001 0.034827 0.464783 0.08024729999999999 0.032951 0.464543 0.07980959999999999 0.032732 0.464515 0.08021929999999999 0.033287 0.464585 0.08024729999999999 0.032951 0.464543 0.08068500000000001 0.032615 0.4645 0.07980959999999999 0.032732 0.464515 0.08021929999999999 0.033287 0.464585 0.07980959999999999 0.032732 0.464515 0.07975359999999999 0.033959 0.464671 0.077801 0.075124 0.452 0.07975359999999999 0.033959 0.464671 0.07980959999999999 0.032732 0.464515 0.077801 0.075124 0.452 0.07980959999999999 0.032732 0.464515 0.079815 0.032615 0.4645 0.08068500000000001 0.032615 0.4645 0.079815 0.032615 0.4645 0.07980959999999999 0.032732 0.464515 0.0801933 0.033623 0.464628 0.08021929999999999 0.033287 0.464585 0.07975359999999999 0.033959 0.464671 0.07975359999999999 0.033959 0.464671 0.0801933 0.033791 0.46465 0.0801933 0.033623 0.464628 0.0801933 0.033791 0.46465 0.0801933 0.033623 0.464628 0.080633 0.033959 0.464671 0.080633 0.033959 0.464671 0.0801933 0.033791 0.46465 0.07975359999999999 0.033959 0.464671 0.080633 0.033959 0.464671 0.07975359999999999 0.033959 0.464671 0.0797466 0.0341119 0.464691 0.080567 0.035695 0.464894 0.083757 0.03397 0.471612 0.080633 0.033959 0.464671 0.0794779 0.040142 0.467152 0.079926 0.0403895 0.467332 0.079926 0.0402658 0.467242 0.08001900000000001 0.045722 0.479 0.080111 0.045055 0.474428 0.0796762 0.0453885 0.476714 0.08068500000000001 0.032615 0.4645 0.08024729999999999 0.032951 0.464543 0.08021929999999999 0.033287 0.464585 0.0804521 0.033287 0.464585 0.08021929999999999 0.033287 0.464585 0.080633 0.033959 0.464671 0.0804521 0.033287 0.464585 0.08068500000000001 0.032615 0.4645 0.08021929999999999 0.033287 0.464585 0.08068500000000001 0.032615 0.4645 0.0804521 0.033287 0.464585 0.080633 0.033959 0.464671 0.07990650000000001 0.040637 0.467511 0.0794779 0.040142 0.467152 0.0796727 0.0405927 0.467479 0.080443 0.038625 0.466051 0.0800612 0.03716 0.465473 0.0795553 0.0383616 0.465947 0.080633 0.033959 0.464671 0.08021929999999999 0.033287 0.464585 0.0801933 0.033623 0.464628 0.077801 0.075124 0.452 0.0797466 0.0341119 0.464691 0.07975359999999999 0.033959 0.464671 0.0793176 0.0440597 0.472285 0.077801 0.075124 0.452 0.0793143 0.044149 0.472477 0.080167 0.044149 0.472477 0.082525 0.040197 0.472918 0.080232 0.043105 0.470231 0.0697535 -0.036353 0.37337 0.06760099999999999 -0.07270600000000001 0.376436 0.0676012 0 0.361701 0.072702 -0.062892 0.38464 0.0697535 -0.036353 0.37337 0.0676012 0 0.361701 0.0697535 -0.036353 0.37337 0.072702 -0.062892 0.38464 0.06760099999999999 -0.07270600000000001 0.376436 0.06760099999999999 -0.07270600000000001 0.376436 0.06760099999999999 -0.063149 0.371934 0.0676012 0 0.361701 0.072702 -0.082625 0.415539 0.06760099999999999 -0.07270600000000001 0.376436 0.072702 -0.062892 0.38464 0.072702 -0.082625 0.415539 0.06760099999999999 -0.07764500000000001 0.379589 0.06760099999999999 -0.07270600000000001 0.376436 0.06760099999999999 -0.063149 0.371934 0.06760099999999999 -0.07270600000000001 0.376436 0.059001 -0.063197 0.371791 0.06420099999999999 0.01856 0.362567 0.06904449999999999 0 0.338789 0.06904490000000001 0 0.338783 0.06420099999999999 0.01856 0.362567 0.065675 0.011034 0.361971 0.06904449999999999 0 0.338789 0.065675 0.011034 0.361971 0.0687214 0 0.341713 0.06904449999999999 0 0.338789 0.065675 0.011034 0.361971 0.066512 3.40047e-05 0.361682 0.0687214 0 0.341713 0.066512 3.40047e-05 0.361682 0.066512 -3.40047e-05 0.361682 0.0687214 0 0.341713 0.066512 3.40047e-05 0.361682 0.065675 0.011034 0.361971 0.06760099999999999 0.024057 0.363637 0.06746149999999999 0 0.361698 0.066512 3.40047e-05 0.361682 0.066512 -3.40047e-05 0.361682 0.065675 -0.011034 0.361971 0.0687214 0 0.341713 0.066512 -3.40047e-05 0.361682 0.06746149999999999 0 0.361698 0.066512 3.40047e-05 0.361682 0.06760099999999999 0.024057 0.363637 0.0676012 0 0.361701 0.06746149999999999 0 0.361698 0.06760099999999999 0.024057 0.363637 0.0676012 0 0.361701 0.06760099999999999 -0.024057 0.363637 0.06746149999999999 0 0.361698 0.06760099999999999 -0.024057 0.363637 0.065675 -0.011034 0.361971 0.066512 -3.40047e-05 0.361682 0.06760099999999999 -0.024057 0.363637 0.06420099999999999 -0.01856 0.362567 0.065675 -0.011034 0.361971 0.06746149999999999 0 0.361698 0.06760099999999999 -0.024057 0.363637 0.066512 -3.40047e-05 0.361682 0.06760099999999999 -0.024057 0.363637 0.063235 -0.022982 0.362966 0.06420099999999999 -0.01856 0.362567 0.060225 0.0223 0.260614 0.0601789 0.0222829 0.262021 0.0603244 0.0217207 0.262023 0.060225 0.0223 0.260614 0.0603244 0.0217207 0.262023 0.0618289 0.0160036 0.261346 0.0603244 0.0217207 0.262023 0.0617553 0.0161906 0.262048 0.0618289 0.0160036 0.261346 0.0618289 0.0160036 0.261346 0.0617553 0.0161906 0.262048 0.0620911 0.0148927 0.262054 0.0622549 0.0142596 0.262057 0.0620911 0.0148927 0.262054 0.067703 0.033854 0.262152 0.06560199999999999 0.0225688 0.262115 0.0622549 0.0142596 0.262057 0.067703 0.033854 0.262152 0.06302489999999999 0.0112835 0.26207 0.0622549 0.0142596 0.262057 0.06560199999999999 0.0225688 0.262115 0.068949 0.028271 0.262174 0.06302489999999999 0.0112835 0.26207 0.06560199999999999 0.0225688 0.262115 0.0618289 0.0160036 0.261346 0.0620911 0.0148927 0.262054 0.0622549 0.0142596 0.262057 0.0618289 0.0160036 0.261346 0.0622549 0.0142596 0.262057 0.063482 0.009719999999999999 0.260614 0.0617553 0.0161906 0.262048 0.0603244 0.0217207 0.262023 0.06376179999999999 0.0304138 0.262083 0.0617553 0.0161906 0.262048 0.06376179999999999 0.0304138 0.262083 0.067703 0.033854 0.262152 0.045859 0.090318 0.382877 0.059001 0.091573 0.395704 0.045693 0.089558 0.376733 0.045693 0.089558 0.376733 0.059001 0.091573 0.395704 0.059001 0.089419 0.377466 0.063235 -0.022982 0.362966 0.06760099999999999 -0.063149 0.371934 0.061536 -0.028942 0.363699 0.066029 -0.022513 0.33935 0.063235 -0.022982 0.362966 0.061536 -0.028942 0.363699 0.06760099999999999 -0.024057 0.363637 0.06760099999999999 -0.063149 0.371934 0.063235 -0.022982 0.362966 0.066029 -0.022513 0.33935 0.06420099999999999 -0.01856 0.362567 0.063235 -0.022982 0.362966 0.0526043 0.0527231 0.261888 0.04813 0.068846 0.26181 0.059 0.06869500000000001 0.262 0.059 0.06869500000000001 0.262 0.0524073 0.0366001 0.261885 0.0526043 0.0527231 0.261888 0.0536743 0.034962 0.261907 0.0524073 0.0366001 0.261885 0.059 0.06869500000000001 0.262 0.0524073 0.0366001 0.261885 0.0536743 0.034962 0.261907 0.054502 0.033966 0.260614 0.054502 0.033966 0.260614 0.0536743 0.034962 0.261907 0.0544633 0.0339419 0.261921 0.079884 -0.0408845 0.46769 0.07943890000000001 -0.0410435 0.467806 0.07990650000000001 -0.040637 0.467511 0.07990650000000001 -0.040637 0.467511 0.07943890000000001 -0.0410435 0.467806 0.0796727 -0.0405927 0.467479 0.042747 0.08745699999999999 0.36068 0.04381 0.088032 0.364949 0.059001 0.089419 0.377466 0.04381 0.088032 0.364949 0.044958 0.088741 0.370332 0.059001 0.089419 0.377466 0.044958 0.088741 0.370332 0.045693 0.089558 0.376733 0.059001 0.089419 0.377466 0.06760099999999999 0.105671 0.446901 0.072702 0.082625 0.415539 0.06760099999999999 0.104222 0.44057 0.042178 0.105959 0.446111 0.06760099999999999 0.105671 0.446901 0.06760099999999999 0.104222 0.44057 0.06760099999999999 0.104222 0.44057 0.042859 0.103849 0.437105 0.042178 0.105959 0.446111 0.059001 0.072436 0.375943 0.059 0.06869500000000001 0.262 0.059001 0.089419 0.377466 0.059001 0.089419 0.377466 0.059001 0.08577799999999999 0.387139 0.059001 0.072436 0.375943 0.059001 0.091573 0.395704 0.059001 0.08577799999999999 0.387139 0.059001 0.089419 0.377466 0.059001 0.052636 0.298752 0.059 0.06869500000000001 0.262 0.059001 0.072436 0.375943 0.07954559999999999 0.000879971 0.4935 0.0799184 0.005431 0.4935 0.0794768 0.010862 0.4935 0.07954559999999999 0.000879971 0.4935 0.0803575 -1.35465e-10 0.4935 0.0799184 0.005431 0.4935 0.07780040000000001 0 0.53 0.07954559999999999 0.000879971 0.4935 0.0794768 0.010862 0.4935 0.081124 0.016307 0.4645 0.0805501 0.0166998 0.4645 0.08053979999999999 0.0169241 0.4645 0.080564 0.016307 0.4645 0.0805501 0.0166998 0.4645 0.081124 0.016307 0.4645 0.081124 0.016307 0.4645 0.08053979999999999 0.0169241 0.4645 0.080595 0.021743 0.4645 0.08053979999999999 0.0169241 0.4645 0.0805501 0.0166998 0.4645 0.08129 0 0.456649 0.08129 0 0.456649 0.0805501 0.0166998 0.4645 0.0812914 0 0.457002 0.0809145 0.008153499999999999 0.4645 0.080564 0.016307 0.4645 0.081124 0.016307 0.4645 0.045805 0.090896 0.387693 0.045589 0.092433 0.396825 0.059001 0.091573 0.395704 -0.063481 -0.009719999999999999 0.260614 -0.0637808 -0.00322952 0.261456 -0.0639738 0 0.260614 -0.063481 -0.009719999999999999 0.260614 -0.06345820000000001 -0.009023339999999999 0.262285 -0.0637808 -0.00322952 0.261456 -0.094407 0.06848799999999999 0.262893 -0.0766416 0.0728245 0.282836 -0.0588761 0.0736657 0.286773 -0.094407 0.06848799999999999 0.262893 -0.0588761 0.0736657 0.286773 -0.0587706 0.07212399999999999 0.278677 0.080029 0.032595 0.4935 0.0796557 0.0345965 0.49317 0.0793268 0.032595 0.4935 0.07932939999999999 0.0322129 0.4935 0.080029 0.032595 0.4935 0.0793268 0.032595 0.4935 0.041335 -0.070367 0.260227 -0.010356 -0.0760875 0.295 -0.009366879999999999 -0.07095220000000001 0.267974 -0.010356 -0.0760875 0.295 -0.00949171 -0.0778746 0.295 -0.009366879999999999 -0.07095220000000001 0.267974 0.08129 0 0.456649 0.0800466 0.0275997 0.4645 0.0800661 0.027179 0.4645 0.079815 0.032615 0.4645 0.0800466 0.0275997 0.4645 0.08129 0 0.456649 0.0800661 0.027179 0.4645 0.0800466 0.0275997 0.4645 0.080832 0.027179 0.4645 0.0800466 0.0275997 0.4645 0.079815 0.032615 0.4645 0.08032350000000001 0.029897 0.4645 0.080832 0.027179 0.4645 0.0800466 0.0275997 0.4645 0.08032350000000001 0.029897 0.4645 0.080595 0.021743 0.4645 0.0800661 0.027179 0.4645 0.080832 0.027179 0.4645 0.08068500000000001 0.032615 0.4645 0.080832 0.027179 0.4645 0.08032350000000001 0.029897 0.4645 -0.124983 -0.072046 0.355864 -0.135472 -0.04726 0.354722 -0.130461 -0.052724 0.33346 -0.130461 -0.052724 0.33346 -0.12413 -0.067466 0.333441 -0.124983 -0.072046 0.355864 -0.139966 0.000441003 0.333462 -0.139966 -0.000441003 0.333462 -0.140721 -0.000441 0.344 -0.140721 -0.000441 0.344 -0.139966 -0.000441003 0.333462 -0.141477 -0.02304 0.354537 -0.141477 -0.02304 0.354537 -0.141477 0 0.354537 -0.140721 -0.000441 0.344 -0.137444 -0.026815 0.333464 -0.141477 -0.02304 0.354537 -0.139966 -0.000441003 0.333462 -0.130461 -0.052724 0.33346 -0.137444 -0.026815 0.333464 -0.128571 -0.04743 0.310033 -0.137444 -0.026815 0.333464 -0.133782 -0.023965 0.310036 -0.128571 -0.04743 0.310033 -0.130815 0.000441001 0.286712 -0.135669 0.000441002 0.310035 -0.12965 0.021038 0.28671 -0.135669 0.000441002 0.310035 -0.130815 0.000441001 0.286712 -0.135669 -0.000441002 0.310035 -0.130815 -0.000441001 0.286712 -0.135669 -0.000441002 0.310035 -0.130815 0.000441001 0.286712 -0.130815 -0.000441001 0.286712 -0.12965 -0.021038 0.28671 -0.135669 -0.000441002 0.310035 -0.125404 -0.000441 0.263502 -0.12965 -0.021038 0.28671 -0.130815 -0.000441001 0.286712 -0.135669 -0.000441002 0.310035 -0.12965 -0.021038 0.28671 -0.133782 -0.023965 0.310036 -0.133782 -0.023965 0.310036 -0.139966 -0.000441003 0.333462 -0.135669 -0.000441002 0.310035 -0.133782 -0.023965 0.310036 -0.137444 -0.026815 0.333464 -0.139966 -0.000441003 0.333462 -0.130461 -0.052724 0.33346 -0.128571 -0.04743 0.310033 -0.123512 -0.061676 0.31001 -0.12965 0.021038 0.28671 -0.125404 0.000441 0.263502 -0.130815 0.000441001 0.286712 -0.094407 0.06848799999999999 0.262893 -0.125404 0.000441 0.263502 -0.124936 0.019788 0.263492 -0.125404 0.000441 0.263502 -0.12965 0.021038 0.28671 -0.124936 0.019788 0.263492 -0.124936 0.019788 0.263492 -0.123796 0.036459 0.26347 -0.094407 0.06848799999999999 0.262893 -0.125404 -0.000441 0.263502 -0.124936 -0.019788 0.263492 -0.12965 -0.021038 0.28671 -0.094407 -0.06848799999999999 0.262893 -0.124936 -0.019788 0.263492 -0.125404 -0.000441 0.263502 -0.12965 -0.021038 0.28671 -0.124936 -0.019788 0.263492 -0.126401 -0.041887 0.286701 -0.123796 -0.036459 0.26347 -0.126401 -0.041887 0.286701 -0.124936 -0.019788 0.263492 -0.122964 -0.045036 0.263453 -0.124024 -0.05266 0.286688 -0.126401 -0.041887 0.286701 -0.123796 -0.036459 0.26347 -0.122964 -0.045036 0.263453 -0.126401 -0.041887 0.286701 -0.094407 -0.06848799999999999 0.262893 -0.122964 -0.045036 0.263453 -0.123796 -0.036459 0.26347 -0.120144 -0.052723 0.263398 -0.122964 -0.045036 0.263453 -0.094407 -0.06848799999999999 0.262893 -0.123512 -0.061676 0.31001 -0.12413 -0.067466 0.333441 -0.130461 -0.052724 0.33346 -0.120144 -0.052723 0.263398 -0.117026 -0.063762 0.286585 -0.121458 -0.058391 0.286654 -0.121458 -0.058391 0.286654 -0.117026 -0.063762 0.286585 -0.123512 -0.061676 0.31001 -0.117026 -0.063762 0.286585 -0.117537 -0.06936199999999999 0.309941 -0.123512 -0.061676 0.31001 -0.123512 -0.061676 0.31001 -0.117537 -0.06936199999999999 0.309941 -0.12413 -0.067466 0.333441 -0.117537 -0.06936199999999999 0.309941 -0.117959 -0.074543 0.333388 -0.12413 -0.067466 0.333441 -0.118275 -0.079184 0.356402 -0.12413 -0.067466 0.333441 -0.117959 -0.074543 0.333388 -0.118275 -0.079184 0.356402 -0.124983 -0.072046 0.355864 -0.12413 -0.067466 0.333441 -0.094407 -0.06848799999999999 0.262893 -0.123796 -0.036459 0.26347 -0.124936 -0.019788 0.263492 -0.122964 -0.045036 0.263453 -0.120144 -0.052723 0.263398 -0.121458 -0.058391 0.286654 -0.121458 -0.058391 0.286654 -0.124024 -0.05266 0.286688 -0.122964 -0.045036 0.263453 -0.135472 -0.04726 0.354722 -0.140007 -0.029219 0.354572 -0.137444 -0.026815 0.333464 -0.140007 -0.029219 0.354572 -0.141477 -0.02304 0.354537 -0.137444 -0.026815 0.333464 -0.130815 0.000441001 0.286712 -0.125404 0.000441 0.263502 -0.130815 -0.000441001 0.286712 -0.123796 0.036459 0.26347 -0.124936 0.019788 0.263492 -0.126401 0.041887 0.286701 -0.135669 0.000441002 0.310035 -0.139966 -0.000441003 0.333462 -0.139966 0.000441003 0.333462 -0.139966 0.000441003 0.333462 -0.141477 0.02304 0.354537 -0.137444 0.026815 0.333464 -0.141477 0.02304 0.354537 -0.139966 0.000441003 0.333462 -0.140721 0.000441 0.344 -0.137444 0.026815 0.333464 -0.133782 0.023965 0.310036 -0.139966 0.000441003 0.333462 -0.137444 0.026815 0.333464 -0.130461 0.052724 0.33346 -0.128571 0.04743 0.310033 -0.128571 0.04743 0.310033 -0.133782 0.023965 0.310036 -0.137444 0.026815 0.333464 -0.128571 0.04743 0.310033 -0.124024 0.05266 0.286688 -0.126401 0.041887 0.286701 -0.126401 0.041887 0.286701 -0.133782 0.023965 0.310036 -0.128571 0.04743 0.310033 -0.126401 0.041887 0.286701 -0.12965 0.021038 0.28671 -0.133782 0.023965 0.310036 -0.135669 0.000441002 0.310035 -0.139966 0.000441003 0.333462 -0.133782 0.023965 0.310036 -0.125404 -0.000441 0.263502 -0.130815 -0.000441001 0.286712 -0.125404 0.000441 0.263502 -0.133782 0.023965 0.310036 -0.12965 0.021038 0.28671 -0.135669 0.000441002 0.310035 0.07992299999999999 -0.04368 0.486819 0.0797379 -0.0439365 0.486183 0.07993500000000001 -0.044193 0.485546 0.080757 -0.044301 0.482372 0.07992299999999999 -0.04368 0.486819 0.07993500000000001 -0.044193 0.485546 0.079911 -0.042146 0.489064 0.07992299999999999 -0.04368 0.486819 0.080757 -0.044301 0.482372 0.080757 -0.044301 0.482372 0.082288 -0.040197 0.485185 0.079911 -0.042146 0.489064 0.06760099999999999 -0.07270600000000001 0.376436 0.059001 -0.072436 0.375943 0.059001 -0.063197 0.371791 0.059001 -0.063197 0.371791 0.059001 -0.072436 0.375943 0.059001 -0.052636 0.298752 -0.058339 -0.07176399999999999 0.267756 -0.0586339 -0.0701278 0.268194 -0.0395053 -0.07044789999999999 0.268076 -0.055224 -0.077663 0.266175 -0.058339 -0.07176399999999999 0.267756 -0.0395053 -0.07044789999999999 0.268076 -0.050447 -0.082413 0.264902 -0.055224 -0.077663 0.266175 -0.0395053 -0.07044789999999999 0.268076 -0.047857 -0.084063 0.26446 -0.050447 -0.082413 0.264902 -0.0395053 -0.07044789999999999 0.268076 -0.047857 -0.084063 0.26446 -0.0395053 -0.07044789999999999 0.268076 -0.04514 -0.08576499999999999 0.264004 -0.039209 -0.091576 0.262447 -0.04514 -0.08576499999999999 0.264004 -0.0395053 -0.07044789999999999 0.268076 0.041335 -0.070367 0.260227 -0.0395053 -0.07044789999999999 0.268076 -0.0586339 -0.0701278 0.268194 -0.0586339 -0.0701278 0.268194 -0.058339 -0.07176399999999999 0.267756 -0.0587533 -0.07187209999999999 0.277354 -0.094357 -0.073585 0.286235 -0.0766416 -0.0728245 0.282836 -0.061307 -0.07716339999999999 0.302779 -0.094357 -0.073585 0.286235 -0.061307 -0.07716339999999999 0.302779 -0.061307 -0.0776017 0.305225 -0.077832 -0.07620440000000001 0.298528 -0.094357 -0.073585 0.286235 -0.061307 -0.0776017 0.305225 -0.077832 -0.07620440000000001 0.298528 -0.061307 -0.0776017 0.305225 -0.061307 -0.0788237 0.31082 -0.09434099999999999 -0.075279 0.293992 -0.094357 -0.073585 0.286235 -0.077832 -0.07620440000000001 0.298528 -0.0588761 -0.0736657 0.286773 -0.0587706 -0.07212399999999999 0.278677 -0.058339 -0.0790632 0.295 -0.0588761 -0.0736657 0.286773 -0.058339 -0.0790632 0.295 -0.0589446 -0.07546219999999999 0.295 -0.0599749 -0.0754633 0.295 -0.0588761 -0.0736657 0.286773 -0.0589446 -0.07546219999999999 0.295 -0.0601191 -0.0754635 0.295 -0.0588761 -0.0736657 0.286773 -0.0599749 -0.0754633 0.295 -0.061307 -0.0754647 0.295 -0.0588761 -0.0736657 0.286773 -0.0601191 -0.0754635 0.295 -0.0766416 -0.0728245 0.282836 -0.0588761 -0.0736657 0.286773 -0.061307 -0.0754647 0.295 -0.094407 -0.06848799999999999 0.262893 -0.0587706 -0.07212399999999999 0.278677 -0.0588761 -0.0736657 0.286773 -0.094357 -0.073585 0.286235 -0.094407 -0.06848799999999999 0.262893 -0.0766416 -0.0728245 0.282836 -0.0587533 -0.07187209999999999 0.277354 -0.058339 -0.07176399999999999 0.267756 -0.0587706 -0.07212399999999999 0.278677 -0.094407 -0.06848799999999999 0.262893 -0.0586339 -0.0701278 0.268194 -0.0587533 -0.07187209999999999 0.277354 -0.094407 -0.06848799999999999 0.262893 0.041335 -0.070367 0.260227 -0.0586339 -0.0701278 0.268194 0.0795347 -0.0438082 0.486501 0.07954070000000001 -0.0439365 0.486183 0.07992299999999999 -0.04368 0.486819 0.07914640000000001 -0.0437199 0.48672 0.0795347 -0.0438082 0.486501 0.07992299999999999 -0.04368 0.486819 0.07972070000000001 0.0298865 0.4935 0.080029 0.032595 0.4935 0.07932939999999999 0.0322129 0.4935 0.07972070000000001 0.0298865 0.4935 0.080112 0.027178 0.4935 0.080029 0.032595 0.4935 0.0793727 0.0259411 0.4935 0.080112 0.027178 0.4935 0.0793642 0.027178 0.4935 0.0793642 0.027178 0.4935 0.080112 0.027178 0.4935 0.07972070000000001 0.0298865 0.4935 0.0798664 0.01902 0.4935 0.080112 0.027178 0.4935 0.0793727 0.0259411 0.4935 0.0798664 0.01902 0.4935 0.08036 0.010862 0.4935 0.080112 0.027178 0.4935 0.0794768 0.010862 0.4935 0.08036 0.010862 0.4935 0.0798664 0.01902 0.4935 0.0793642 0.027178 0.4935 0.0784712 0.031064 0.511558 0.0793727 0.0259411 0.4935 0.07932939999999999 0.0322129 0.4935 0.0784712 0.031064 0.511558 0.0793642 0.027178 0.4935 0.083608 0.027179 0.486575 0.080112 0.027178 0.4935 0.08036 0.010862 0.4935 0.0794768 0.010862 0.4935 0.0793727 0.0259411 0.4935 0.0784712 0.031064 0.511558 0.0784712 0.031064 0.511558 0.07932939999999999 0.0322129 0.4935 0.0793268 0.032595 0.4935 0.0784712 0.031064 0.511558 0.0793268 0.032595 0.4935 0.0793291 0.0348661 0.493126 0.0784712 0.031064 0.511558 0.0793291 0.0348661 0.493126 0.077801 0.062128 0.521061 0.066029 0.022513 0.33935 0.06904490000000001 0 0.338783 0.0710831 8.27181e-26 0.31324 0.0710831 8.27181e-26 0.31324 0.06904490000000001 0 0.338783 0.066029 -0.022513 0.33935 0.066029 -0.022513 0.33935 0.06904490000000001 0 0.338783 0.06420099999999999 -0.01856 0.362567 -0.124024 0.05266 0.286688 -0.121458 0.058391 0.286654 -0.122964 0.045036 0.263453 -0.121458 0.058391 0.286654 -0.124024 0.05266 0.286688 -0.123512 0.061676 0.31001 -0.121458 0.058391 0.286654 -0.120144 0.052723 0.263398 -0.122964 0.045036 0.263453 0.083161 -0.040197 0.479069 0.082525 -0.040197 0.472918 0.083757 -0.03397 0.471612 0.084685 -0.033971 0.479099 0.083161 -0.040197 0.479069 0.083757 -0.03397 0.471612 0.08488999999999999 -0.027179 0.479101 0.083428 -0.03397 0.486536 0.084685 -0.033971 0.479099 0.08488999999999999 -0.027179 0.479101 0.084685 -0.033971 0.479099 0.083757 -0.03397 0.471612 0.083161 -0.040197 0.479069 0.084685 -0.033971 0.479099 0.083428 -0.03397 0.486536 0.083608 -0.027179 0.486575 0.080029 -0.032595 0.4935 0.083428 -0.03397 0.486536 0.080029 -0.032595 0.4935 0.079952 -0.036598 0.492841 0.083428 -0.03397 0.486536 0.079914 -0.040182 0.490935 0.082288 -0.040197 0.485185 0.079952 -0.036598 0.492841 0.079952 -0.036598 0.492841 0.0795689 -0.03839 0.491888 0.079914 -0.040182 0.490935 0.083428 -0.03397 0.486536 0.079952 -0.036598 0.492841 0.082288 -0.040197 0.485185 0.079914 -0.040182 0.490935 0.0795689 -0.03839 0.491888 0.0791859 -0.040182 0.490935 0.0791859 -0.040182 0.490935 0.0795689 -0.03839 0.491888 0.0792677 -0.0368423 0.492711 0.0791859 -0.040182 0.490935 0.0792677 -0.0368423 0.492711 0.0784329 -0.0567469 0.499244 0.079952 -0.036598 0.492841 0.0793291 -0.0348661 0.493126 0.0792823 -0.0363279 0.492885 0.079952 -0.036598 0.492841 0.0792823 -0.0363279 0.492885 0.0792737 -0.036598 0.492841 0.0796557 -0.0345965 0.49317 0.0793291 -0.0348661 0.493126 0.079952 -0.036598 0.492841 0.079952 -0.036598 0.492841 0.0792737 -0.036598 0.492841 0.0792677 -0.0368423 0.492711 0.0784329 -0.0567469 0.499244 0.0792677 -0.0368423 0.492711 0.0792737 -0.036598 0.492841 0.0792737 -0.036598 0.492841 0.0792823 -0.0363279 0.492885 0.077801 -0.062128 0.521061 0.079914 -0.040182 0.490935 0.0791859 -0.040182 0.490935 0.07918360000000001 -0.0403254 0.490798 0.079914 -0.040182 0.490935 0.07918360000000001 -0.0403254 0.490798 0.0795342 -0.041164 0.49 0.0791545 -0.042146 0.489064 0.0795342 -0.041164 0.49 0.07918360000000001 -0.0403254 0.490798 0.0795443 -0.0440647 0.485864 0.0795443 -0.0441289 0.485705 0.0791535 -0.044193 0.485546 0.0795443 -0.0441289 0.485705 0.0791535 -0.044193 0.485546 0.07993500000000001 -0.044193 0.485546 0.0791538 -0.0422623 0.488894 0.07953440000000001 -0.042913 0.487942 0.079911 -0.042146 0.489064 0.0791458 -0.04368 0.486819 0.07953440000000001 -0.042913 0.487942 0.0791538 -0.0422623 0.488894 0.0791458 -0.04368 0.486819 0.0791538 -0.0422623 0.488894 0.0784329 -0.0567469 0.499244 0.0791538 -0.0422623 0.488894 0.0791545 -0.042146 0.489064 0.0784329 -0.0567469 0.499244 0.0791545 -0.042146 0.489064 0.07918360000000001 -0.0403254 0.490798 0.0784329 -0.0567469 0.499244 0.0791458 -0.04368 0.486819 0.07992299999999999 -0.04368 0.486819 0.07953440000000001 -0.042913 0.487942 0.07992299999999999 -0.04368 0.486819 0.07914640000000001 -0.0437199 0.48672 0.0791458 -0.04368 0.486819 0.07914640000000001 -0.0437199 0.48672 0.0791458 -0.04368 0.486819 0.0784329 -0.0567469 0.499244 0.07915469999999999 -0.0442721 0.48535 0.0791535 -0.044193 0.485546 0.0784329 -0.0567469 0.499244 0.0791535 -0.044193 0.485546 0.07914640000000001 -0.0437199 0.48672 0.0784329 -0.0567469 0.499244 0.0791535 -0.044193 0.485546 0.07915469999999999 -0.0442721 0.48535 0.07993500000000001 -0.044193 0.485546 0.07993500000000001 -0.044193 0.485546 0.0795443 -0.0440647 0.485864 0.0795443 -0.0441289 0.485705 0.079911 -0.042146 0.489064 0.0795342 -0.041164 0.49 0.0791545 -0.042146 0.489064 0.083161 -0.040197 0.479069 0.083428 -0.03397 0.486536 0.082288 -0.040197 0.485185 0.083161 -0.040197 0.479069 0.0817947 -0.0421716 0.482127 0.080757 -0.044301 0.482372 0.08107200000000001 -0.044301 0.479023 0.083161 -0.040197 0.479069 0.080757 -0.044301 0.482372 0.083161 -0.040197 0.479069 0.0822992 -0.0411002 0.482127 0.0817947 -0.0421716 0.482127 0.0822992 -0.0411002 0.482127 0.083161 -0.040197 0.479069 0.082288 -0.040197 0.485185 0.079911 -0.042146 0.489064 0.07953440000000001 -0.042913 0.487942 0.07992299999999999 -0.04368 0.486819 0.0784329 -0.0567469 0.499244 0.0792737 -0.036598 0.492841 0.077801 -0.062128 0.521061 0.07918360000000001 -0.0403254 0.490798 0.0791859 -0.040182 0.490935 0.0784329 -0.0567469 0.499244 0.082525 -0.040197 0.472918 0.083161 -0.040197 0.479069 0.08107200000000001 -0.044301 0.479023 0.08107200000000001 -0.044301 0.479023 0.08001900000000001 -0.045722 0.479 0.082525 -0.040197 0.472918 0.0791535 -0.044193 0.485546 0.0795443 -0.0440647 0.485864 0.07954070000000001 -0.0439365 0.486183 0.080029 -0.032595 0.4935 0.0796557 -0.0345965 0.49317 0.079952 -0.036598 0.492841 0.0817947 -0.0421716 0.482127 0.0822992 -0.0411002 0.482127 0.082288 -0.040197 0.485185 0.083757 -0.03397 0.471612 0.082525 -0.040197 0.472918 0.080443 -0.038625 0.466051 0.080167 -0.044149 0.472477 0.082525 -0.040197 0.472918 0.08001900000000001 -0.045722 0.479 0.06760099999999999 0.098633 0.417793 0.06760099999999999 0.101487 0.429166 0.072702 0.082625 0.415539 0.06760099999999999 0.101487 0.429166 0.06760099999999999 0.098633 0.417793 0.042859 0.103849 0.437105 0.0793143 -0.044149 0.472477 0.07972509999999999 -0.044602 0.473453 0.0792831 -0.0449796 0.474266 0.0792831 -0.0449796 0.474266 0.077801 -0.075124 0.452 0.0793143 -0.044149 0.472477 0.034283 0.106278 0.258508 0.03532 0.122198 0.284265 0.0347672 0.114242 0.272514 0.034283 0.113783 0.28652 0.034283 0.106278 0.258508 0.0347672 0.114242 0.272514 0.06760099999999999 0.101744 0.523384 0.0419097 0.102618 0.5227850000000001 0.0419129 0.101701 0.524294 0.0419129 0.101701 0.524294 0.0419165 0.100044 0.525991 0.06760099999999999 0.101744 0.523384 0.0418982 0.105879 0.517422 0.0419097 0.102618 0.5227850000000001 0.06760099999999999 0.101744 0.523384 0.0419165 0.100044 0.525991 0.06760099999999999 0.095751 0.529524 0.06760099999999999 0.101744 0.523384 0.0418978 0.106004 0.517218 0.0418982 0.105879 0.517422 0.06760099999999999 0.101744 0.523384 0.0326038 0.106114 0.274631 0.034283 0.113783 0.28652 0.031111 0.105882 0.288637 -0.014805 0.144939 0.248148 -0.022179 0.140348 0.249379 -0.022179 0.147853 0.277391 -0.022179 0.140348 0.249379 -0.02814 0.141635 0.279057 -0.022179 0.147853 0.277391 -0.02814 0.141635 0.279057 -0.022179 0.140348 0.249379 -0.02814 0.134129 0.251045 0.031111 0.09837600000000001 0.260625 -0.02814 0.134129 0.251045 -0.022179 0.140348 0.249379 0.034283 0.106278 0.258508 0.031111 0.09837600000000001 0.260625 -0.022179 0.140348 0.249379 0.034283 0.113783 0.28652 0.031111 0.09837600000000001 0.260625 0.034283 0.106278 0.258508 0.031111 0.09837600000000001 0.260625 0.026005 0.091485 0.262471 -0.02814 0.134129 0.251045 0.0223278 0.09600980000000001 0.291282 0.0200627 0.0941734 0.291775 0.019285 0.086037 0.263931 0.026005 0.091485 0.262471 0.031111 0.09837600000000001 0.260625 0.031111 0.105882 0.288637 0.026005 0.091485 0.262471 0.031111 0.105882 0.288637 0.0293444 0.103498 0.289276 0.026005 0.091485 0.262471 0.0293444 0.103498 0.289276 0.026005 0.098991 0.290483 0.026005 0.098991 0.290483 0.019285 0.086037 0.263931 0.026005 0.091485 0.262471 0.026005 0.098991 0.290483 0.0223278 0.09600980000000001 0.291282 0.019285 0.086037 0.263931 -0.014805 0.144939 0.248148 0.034283 0.106278 0.258508 -0.022179 0.140348 0.249379 -0.009366879999999999 0.07095220000000001 0.267974 -0.039209 0.091576 0.262447 -0.035427 0.098872 0.260492 -0.0395053 0.07044789999999999 0.268076 -0.039209 0.091576 0.262447 -0.009366879999999999 0.07095220000000001 0.267974 -0.0395053 0.07044789999999999 0.268076 -0.04514 0.08576499999999999 0.264004 -0.039209 0.091576 0.262447 -0.0395053 0.07044789999999999 0.268076 -0.047857 0.084063 0.26446 -0.04514 0.08576499999999999 0.264004 -0.047857 0.091569 0.292472 -0.04514 0.08576499999999999 0.264004 -0.047857 0.084063 0.26446 -0.039209 0.091576 0.262447 -0.04514 0.08576499999999999 0.264004 -0.04514 0.09327100000000001 0.292016 -0.050447 0.089919 0.292914 -0.047857 0.091569 0.292472 -0.047857 0.084063 0.26446 -0.04514 0.09327100000000001 0.292016 -0.039209 0.099082 0.290459 -0.039209 0.091576 0.262447 -0.0395053 0.07044789999999999 0.268076 -0.050447 0.082413 0.264902 -0.047857 0.084063 0.26446 -0.050447 0.089919 0.292914 -0.047857 0.084063 0.26446 -0.050447 0.082413 0.264902 -0.00341801 0.076742 0.266422 -0.009366879999999999 0.07095220000000001 0.267974 -0.035427 0.098872 0.260492 -0.00949171 0.0778746 0.295 -0.009366879999999999 0.07095220000000001 0.267974 -0.00341801 0.076742 0.266422 0.000508551 0.0862144 0.293907 -0.00949171 0.0778746 0.295 -0.00341801 0.076742 0.266422 -0.00341801 0.076742 0.266422 0.004082 0.088004 0.293427 0.000508551 0.0862144 0.293907 -0.035427 0.098872 0.260492 -0.039209 0.091576 0.262447 -0.039209 0.099082 0.290459 -0.032312 0.126674 0.253043 -0.034433 0.125957 0.283258 -0.032312 0.13418 0.281054 -0.032312 0.13418 0.281054 -0.02814 0.134129 0.251045 -0.032312 0.126674 0.253043 -0.034433 0.125957 0.283258 -0.032312 0.126674 0.253043 -0.034433 0.118451 0.255247 -0.034433 0.118451 0.255247 -0.032312 0.126674 0.253043 0.019285 0.086037 0.263931 -0.034433 0.118451 0.255247 0.019285 0.086037 0.263931 0.011373 0.082374 0.264912 0.0192849 0.0935428 0.291944 0.011373 0.082374 0.264912 0.019285 0.086037 0.263931 0.011373 0.082374 0.264912 0.0192849 0.0935428 0.291944 0.011373 0.08988 0.292924 -0.034388 0.110107 0.257482 -0.034165 0.114446 0.286342 -0.034388 0.117613 0.285493 -0.034388 0.110107 0.257482 -0.034165 0.10694 0.25833 -0.034165 0.114446 0.286342 -0.034165 0.10694 0.25833 -0.035427 0.106378 0.288504 -0.034165 0.114446 0.286342 -0.034388 0.117613 0.285493 -0.034433 0.118451 0.255247 -0.034388 0.110107 0.257482 -0.034433 0.118451 0.255247 -0.034388 0.117613 0.285493 -0.034433 0.125957 0.283258 0.004082 0.080498 0.265416 -0.034165 0.10694 0.25833 -0.034388 0.110107 0.257482 -0.034388 0.110107 0.257482 0.00725699 0.081315 0.265196 0.004082 0.080498 0.265416 0.00725699 0.088821 0.293208 0.004082 0.080498 0.265416 0.00725699 0.081315 0.265196 0.00725699 0.088821 0.293208 0.004082 0.088004 0.293427 0.004082 0.080498 0.265416 0.004082 0.080498 0.265416 -0.00341801 0.076742 0.266422 -0.034165 0.10694 0.25833 0.011373 0.08988 0.292924 0.00725699 0.081315 0.265196 0.011373 0.082374 0.264912 -0.034165 0.10694 0.25833 -0.035427 0.098872 0.260492 -0.035427 0.106378 0.288504 -0.00341801 0.076742 0.266422 0.004082 0.080498 0.265416 0.004082 0.088004 0.293427 0.000508551 0.0862144 0.293907 0.004082 0.088004 0.293427 0.00725699 0.088821 0.293208 0.00227099 0.148207 0.247273 0.0109 0.146678 0.247682 0.030872 0.130949 0.251897 0.00227099 0.155713 0.275285 0.0109 0.146678 0.247682 0.00227099 0.148207 0.247273 -0.00648101 0.155121 0.275443 0.00227099 0.155713 0.275285 0.00227099 0.148207 0.247273 -0.00648101 0.147615 0.247431 -0.00648101 0.155121 0.275443 0.00227099 0.148207 0.247273 -0.014805 0.152445 0.27616 -0.00648101 0.155121 0.275443 -0.00648101 0.147615 0.247431 -0.00648101 0.147615 0.247431 0.03532 0.114692 0.256253 -0.014805 0.144939 0.248148 0.034159 0.123092 0.254002 0.03532 0.114692 0.256253 -0.00648101 0.147615 0.247431 0.03532 0.114692 0.256253 0.034159 0.123092 0.254002 0.034159 0.130598 0.282014 -0.014805 0.152445 0.27616 -0.00648101 0.147615 0.247431 -0.014805 0.144939 0.248148 0.00227099 0.148207 0.247273 0.034159 0.123092 0.254002 -0.00648101 0.147615 0.247431 -0.014805 0.144939 0.248148 0.03532 0.114692 0.256253 0.034283 0.106278 0.258508 0.018865 0.143125 0.248635 0.0109 0.154184 0.275694 0.018865 0.15063 0.276646 0.025664 0.13777 0.25007 0.018865 0.143125 0.248635 0.018865 0.15063 0.276646 0.030872 0.130949 0.251897 0.025664 0.13777 0.25007 0.025664 0.145275 0.278081 0.025664 0.13777 0.25007 0.018865 0.15063 0.276646 0.025664 0.145275 0.278081 0.025664 0.145275 0.278081 0.030872 0.138455 0.27991 0.030872 0.130949 0.251897 0.034159 0.123092 0.254002 0.030872 0.130949 0.251897 0.030872 0.138455 0.27991 0.030872 0.138455 0.27991 0.034159 0.130598 0.282014 0.034159 0.123092 0.254002 -0.039209 0.099082 0.290459 -0.035427 0.106378 0.288504 -0.035427 0.098872 0.260492 0.030872 0.130949 0.251897 0.034159 0.123092 0.254002 0.00227099 0.148207 0.247273 0.030872 0.130949 0.251897 0.0109 0.146678 0.247682 0.025664 0.13777 0.25007 -0.032312 0.13418 0.281054 -0.02814 0.141635 0.279057 -0.02814 0.134129 0.251045 0.07990650000000001 -0.040637 0.467511 0.0796727 -0.0405927 0.467479 0.0794779 -0.040142 0.467152 0.079926 -0.0403895 0.467332 0.07990650000000001 -0.040637 0.467511 0.0794779 -0.040142 0.467152 0.080374 -0.040142 0.467152 0.07990650000000001 -0.040637 0.467511 0.079926 -0.0403895 0.467332 0.080329 -0.041132 0.46787 0.08014019999999999 -0.040637 0.467511 0.080374 -0.040142 0.467152 0.08014019999999999 -0.040637 0.467511 0.07990650000000001 -0.040637 0.467511 0.080374 -0.040142 0.467152 0.08014019999999999 -0.040637 0.467511 0.080329 -0.041132 0.46787 0.07990650000000001 -0.040637 0.467511 0.080374 -0.040142 0.467152 0.082525 -0.040197 0.472918 0.080329 -0.041132 0.46787 0.0794779 -0.040142 0.467152 0.0796727 -0.0405927 0.467479 0.07943890000000001 -0.0410435 0.467806 0.079926 -0.0403895 0.467332 0.079926 -0.0402658 0.467242 0.080374 -0.040142 0.467152 0.07948379999999999 -0.040006 0.467053 0.0794779 -0.040142 0.467152 0.077801 -0.075124 0.452 0.080374 -0.040142 0.467152 0.0794779 -0.040142 0.467152 0.07948379999999999 -0.040006 0.467053 0.0799289 -0.0397628 0.466877 0.080374 -0.040142 0.467152 0.07948379999999999 -0.040006 0.467053 0.080374 -0.040142 0.467152 0.0799289 -0.0397628 0.466877 0.0799634 -0.0393835 0.466602 0.080374 -0.040142 0.467152 0.079926 -0.0402658 0.467242 0.0794779 -0.040142 0.467152 0.07954360000000001 -0.038625 0.466051 0.07948379999999999 -0.040006 0.467053 0.077801 -0.075124 0.452 0.0799634 -0.0393835 0.466602 0.07948379999999999 -0.040006 0.467053 0.07954360000000001 -0.038625 0.466051 0.080443 -0.038625 0.466051 0.0799634 -0.0393835 0.466602 0.07954360000000001 -0.038625 0.466051 0.080443 -0.038625 0.466051 0.07954360000000001 -0.038625 0.466051 0.0795553 -0.0383616 0.465947 0.0796743 -0.035695 0.464894 0.0795553 -0.0383616 0.465947 0.077801 -0.075124 0.452 0.0796743 -0.035695 0.464894 0.0800612 -0.03716 0.465473 0.0795553 -0.0383616 0.465947 0.0795553 -0.0383616 0.465947 0.07954360000000001 -0.038625 0.466051 0.077801 -0.075124 0.452 0.080443 -0.038625 0.466051 0.0795553 -0.0383616 0.465947 0.0800612 -0.03716 0.465473 0.0797466 -0.0341119 0.464691 0.0796743 -0.035695 0.464894 0.077801 -0.075124 0.452 0.080567 -0.035695 0.464894 0.0796743 -0.035695 0.464894 0.08015360000000001 -0.034827 0.464783 0.08015360000000001 -0.034827 0.464783 0.0796743 -0.035695 0.464894 0.0797466 -0.0341119 0.464691 0.080567 -0.035695 0.464894 0.08015360000000001 -0.034827 0.464783 0.080633 -0.033959 0.464671 0.080633 -0.033959 0.464671 0.083757 -0.03397 0.471612 0.080567 -0.035695 0.464894 0.08068500000000001 -0.032615 0.4645 0.083757 -0.03397 0.471612 0.080633 -0.033959 0.464671 -0.0423955 0.048153 0.261871 -0.0396619 0.0503348 0.261243 -0.042663 0.047998 0.260614 -0.0366651 0.0526732 0.261759 -0.0396619 0.0503348 0.261243 -0.0423955 0.048153 0.261871 -0.036688 0.052706 0.260614 -0.0396619 0.0503348 0.261243 -0.0366651 0.0526732 0.261759 -0.036688 0.052706 0.260614 -0.042663 0.047998 0.260614 -0.0396619 0.0503348 0.261243 -0.094407 0.06848799999999999 0.262893 -0.0366651 0.0526732 0.261759 -0.0423955 0.048153 0.261871 0.0795347 0.0438082 0.486501 0.07914640000000001 0.0437199 0.48672 0.07992299999999999 0.04368 0.486819 0.07992299999999999 0.04368 0.486819 0.0791458 0.04368 0.486819 0.07914640000000001 0.0437199 0.48672 0.07914640000000001 0.0437199 0.48672 0.0784329 0.0567469 0.499244 0.0791458 0.04368 0.486819 0.0791458 0.04368 0.486819 0.0784329 0.0567469 0.499244 0.0791538 0.0422623 0.488894 0.0791538 0.0422623 0.488894 0.07953440000000001 0.042913 0.487942 0.0791458 0.04368 0.486819 0.0791538 0.0422623 0.488894 0.079911 0.042146 0.489064 0.07953440000000001 0.042913 0.487942 0.082288 0.040197 0.485185 0.080757 0.044301 0.482372 0.079911 0.042146 0.489064 0.0817947 0.0421716 0.482127 0.080757 0.044301 0.482372 0.082288 0.040197 0.485185 0.0822992 0.0411002 0.482127 0.0817947 0.0421716 0.482127 0.082288 0.040197 0.485185 0.080757 0.044301 0.482372 0.07992299999999999 0.04368 0.486819 0.079911 0.042146 0.489064 0.07992299999999999 0.04368 0.486819 0.07953440000000001 0.042913 0.487942 0.079911 0.042146 0.489064 0.083161 0.040197 0.479069 0.0822992 0.0411002 0.482127 0.082288 0.040197 0.485185 0.083161 0.040197 0.479069 0.082288 0.040197 0.485185 0.083428 0.03397 0.486536 0.083161 0.040197 0.479069 0.0817947 0.0421716 0.482127 0.0822992 0.0411002 0.482127 0.083161 0.040197 0.479069 0.080757 0.044301 0.482372 0.0817947 0.0421716 0.482127 0.0791538 0.0422623 0.488894 0.0784329 0.0567469 0.499244 0.0791545 0.042146 0.489064 0.0791538 0.0422623 0.488894 0.0791545 0.042146 0.489064 0.079911 0.042146 0.489064 0.0795347 0.0438082 0.486501 0.07992299999999999 0.04368 0.486819 0.07954070000000001 0.0439365 0.486183 0.07954070000000001 0.0439365 0.486183 0.07992299999999999 0.04368 0.486819 0.0797379 0.0439365 0.486183 0.07954070000000001 0.0439365 0.486183 0.0797379 0.0439365 0.486183 0.07993500000000001 0.044193 0.485546 0.0795443 0.0440647 0.485864 0.07954070000000001 0.0439365 0.486183 0.07993500000000001 0.044193 0.485546 0.07993500000000001 0.044193 0.485546 0.0797379 0.0439365 0.486183 0.07992299999999999 0.04368 0.486819 0.082288 0.040197 0.485185 0.079952 0.036598 0.492841 0.083428 0.03397 0.486536 0.079914 0.040182 0.490935 0.0795342 0.041164 0.49 0.07918360000000001 0.0403254 0.490798 0.07918360000000001 0.0403254 0.490798 0.0795342 0.041164 0.49 0.0791545 0.042146 0.489064 0.079914 0.040182 0.490935 0.07918360000000001 0.0403254 0.490798 0.0791859 0.040182 0.490935 0.07918360000000001 0.0403254 0.490798 0.0784329 0.0567469 0.499244 0.0791859 0.040182 0.490935 0.0792677 0.0368423 0.492711 0.0795689 0.03839 0.491888 0.0791859 0.040182 0.490935 0.079914 0.040182 0.490935 0.0791859 0.040182 0.490935 0.0795689 0.03839 0.491888 0.079914 0.040182 0.490935 0.0795689 0.03839 0.491888 0.079952 0.036598 0.492841 0.079952 0.036598 0.492841 0.0795689 0.03839 0.491888 0.0792677 0.0368423 0.492711 0.079914 0.040182 0.490935 0.079952 0.036598 0.492841 0.082288 0.040197 0.485185 0.0791859 0.040182 0.490935 0.0784329 0.0567469 0.499244 0.0792677 0.0368423 0.492711 0.0792737 0.036598 0.492841 0.0792677 0.0368423 0.492711 0.0784329 0.0567469 0.499244 0.079952 0.036598 0.492841 0.0792677 0.0368423 0.492711 0.0792737 0.036598 0.492841 0.077801 0.062128 0.521061 0.0793291 0.0348661 0.493126 0.0792823 0.0363279 0.492885 0.077801 0.062128 0.521061 0.0792823 0.0363279 0.492885 0.0792737 0.036598 0.492841 0.079952 0.036598 0.492841 0.0792737 0.036598 0.492841 0.0792823 0.0363279 0.492885 0.083428 0.03397 0.486536 0.083608 0.027179 0.486575 0.08488999999999999 0.027179 0.479101 0.084685 0.033971 0.479099 0.083428 0.03397 0.486536 0.08488999999999999 0.027179 0.479101 0.08476590000000001 0 0.479119 0.08488999999999999 0.027179 0.479101 0.083608 0.027179 0.486575 0.080029 0.032595 0.4935 0.083608 0.027179 0.486575 0.083428 0.03397 0.486536 0.079952 0.036598 0.492841 0.080029 0.032595 0.4935 0.083428 0.03397 0.486536 0.0792737 0.036598 0.492841 0.0784329 0.0567469 0.499244 0.077801 0.062128 0.521061 0.007603 -0.087779 0.354873 -0.00138822 -0.0857882 0.34441 0.024572 -0.08803900000000001 0.354568 -0.061307 -0.0793295 0.31372 -0.077824 -0.078304 0.309147 -0.09434099999999999 -0.075279 0.293992 -0.094309 -0.07824 0.30966 -0.09434099999999999 -0.075279 0.293992 -0.077824 -0.078304 0.309147 -0.094309 -0.07824 0.30966 -0.077824 -0.078304 0.309147 -0.061307 -0.081329 0.324301 0.0417532 -0.107167 0.451436 0.042178 -0.105959 0.446111 0.06760099999999999 -0.106838 0.452 0.0417844 -0.110183 0.465616 0.0417532 -0.107167 0.451436 0.06760099999999999 -0.108184 0.458108 0.0417532 -0.107167 0.451436 0.06760099999999999 -0.106838 0.452 0.06760099999999999 -0.108184 0.458108 0.041802 -0.111884 0.47371 0.0417844 -0.110183 0.465616 0.06760099999999999 -0.108184 0.458108 0.06760099999999999 -0.112671 0.480468 0.041812 -0.112814 0.478284 0.0418086 -0.112526 0.476744 0.0418086 -0.112526 0.476744 0.0418052 -0.112203 0.475196 0.06760099999999999 -0.110815 0.470543 0.072714 -0.09668400000000001 0.488844 0.06760099999999999 -0.110815 0.470543 0.06760099999999999 -0.109492 0.4642 0.0418052 -0.112203 0.475196 0.06760099999999999 -0.109492 0.4642 0.06760099999999999 -0.110815 0.470543 0.072714 -0.09668400000000001 0.488844 0.06760099999999999 -0.112671 0.480468 0.06760099999999999 -0.110815 0.470543 0.06760099999999999 -0.112671 0.480468 0.072714 -0.09668400000000001 0.488844 0.06760099999999999 -0.113524 0.488197 0.0418052 -0.112203 0.475196 0.041802 -0.111884 0.47371 0.06760099999999999 -0.109492 0.4642 -0.106214 -0.075188 0.309795 -0.094309 -0.07824 0.30966 -0.106494 -0.079836 0.333273 -0.09434099999999999 -0.075279 0.293992 -0.094309 -0.07824 0.30966 -0.106214 -0.075188 0.309795 -0.094276 -0.08119 0.325271 -0.106494 -0.079836 0.333273 -0.094309 -0.07824 0.30966 -0.09426 -0.082453 0.333163 -0.106494 -0.079836 0.333273 -0.094276 -0.08119 0.325271 -0.094276 -0.08119 0.325271 -0.094309 -0.07824 0.30966 -0.061307 -0.08261880000000001 0.331907 -0.094276 -0.08119 0.325271 -0.061307 -0.08261880000000001 0.331907 -0.061307 -0.0828207 0.332976 -0.094276 -0.08119 0.325271 -0.061307 -0.0828207 0.332976 -0.061307 -0.0830142 0.334 -0.0585424 -0.0830288 0.334 -0.0582031 -0.0830306 0.334 -0.026335 -0.087259 0.355483 -0.026335 -0.087259 0.355483 -0.061307 -0.0830142 0.334 -0.0585424 -0.0830288 0.334 -0.026335 -0.087259 0.355483 -0.094276 -0.08119 0.325271 -0.061307 -0.0830142 0.334 -0.060273 -0.086738 0.356093 -0.09426 -0.082453 0.333163 -0.094276 -0.08119 0.325271 -0.07724300000000001 -0.086478 0.356398 -0.09426 -0.082453 0.333163 -0.060273 -0.086738 0.356093 -0.0394457 -0.0833752 0.334 -0.026335 -0.087259 0.355483 -0.0582031 -0.0830306 0.334 -0.026335 -0.087259 0.355483 -0.0394457 -0.0833752 0.334 0.007603 -0.087779 0.354873 0.007603 -0.087779 0.354873 -0.0394457 -0.0833752 0.334 -0.0273484 -0.0834934 0.334 0.06760099999999999 -0.109492 0.4642 0.06760099999999999 -0.108184 0.458108 0.072714 -0.09668400000000001 0.488844 -0.094212 -0.086218 0.356704 -0.09426 -0.082453 0.333163 -0.07724300000000001 -0.086478 0.356398 0.0418086 -0.112526 0.476744 0.06760099999999999 -0.110815 0.470543 0.06760099999999999 -0.112671 0.480468 0.072702 -0.082625 0.415539 0.06760099999999999 -0.08888500000000001 0.391522 0.06760099999999999 -0.08465 0.386212 0.072702 -0.082625 0.415539 0.06760099999999999 -0.092889 0.398706 0.06760099999999999 -0.08888500000000001 0.391522 0.06760099999999999 -0.098633 0.417793 0.042859 -0.103849 0.437105 0.043362 -0.102135 0.430031 0.06760099999999999 -0.092889 0.398706 0.045589 -0.092433 0.396825 0.059001 -0.091573 0.395704 0.045589 -0.092433 0.396825 0.045805 -0.090896 0.387693 0.059001 -0.091573 0.395704 0.044994 -0.09535100000000001 0.404143 0.045589 -0.092433 0.396825 0.06760099999999999 -0.092889 0.398706 0.044994 -0.09535100000000001 0.404143 0.06760099999999999 -0.092889 0.398706 0.06760099999999999 -0.09418700000000001 0.402331 0.06760099999999999 -0.09418700000000001 0.402331 0.06760099999999999 -0.095661 0.406449 0.044994 -0.09535100000000001 0.404143 0.06760099999999999 -0.095661 0.406449 0.043928 -0.100007 0.421527 0.044994 -0.09535100000000001 0.404143 0.043928 -0.100007 0.421527 0.06760099999999999 -0.095661 0.406449 0.06760099999999999 -0.097194 0.412299 0.06760099999999999 -0.095661 0.406449 0.072702 -0.082625 0.415539 0.06760099999999999 -0.097194 0.412299 0.043362 -0.102135 0.430031 0.06760099999999999 -0.097194 0.412299 0.06760099999999999 -0.098633 0.417793 0.06760099999999999 -0.097194 0.412299 0.072702 -0.082625 0.415539 0.06760099999999999 -0.098633 0.417793 0.06760099999999999 -0.09418700000000001 0.402331 0.06760099999999999 -0.092889 0.398706 0.072702 -0.082625 0.415539 0.06760099999999999 -0.105671 0.446901 0.06760099999999999 -0.104222 0.44057 0.072702 -0.082625 0.415539 0.042178 -0.105959 0.446111 0.06760099999999999 -0.104222 0.44057 0.06760099999999999 -0.105671 0.446901 0.042178 -0.105959 0.446111 0.042859 -0.103849 0.437105 0.06760099999999999 -0.104222 0.44057 0.06760099999999999 -0.101487 0.429166 0.072702 -0.082625 0.415539 0.06760099999999999 -0.104222 0.44057 0.042859 -0.103849 0.437105 0.06760099999999999 -0.101487 0.429166 0.06760099999999999 -0.104222 0.44057 0.042859 -0.103849 0.437105 0.06760099999999999 -0.098633 0.417793 0.06760099999999999 -0.101487 0.429166 0.059001 -0.089419 0.377466 0.042747 -0.08745699999999999 0.36068 0.0415602 -0.0882602 0.356609 -0.00949171 -0.0778746 0.295 0.000508551 -0.0862144 0.293907 -0.00341801 -0.076742 0.266422 -0.00341801 -0.076742 0.266422 0.000508551 -0.0862144 0.293907 0.004082 -0.088004 0.293427 0.004082 -0.088004 0.293427 0.004082 -0.080498 0.265416 -0.00341801 -0.076742 0.266422 0.004082 -0.080498 0.265416 0.004082 -0.088004 0.293427 0.00725699 -0.088821 0.293208 -0.034165 -0.10694 0.25833 -0.00341801 -0.076742 0.266422 0.004082 -0.080498 0.265416 -0.034165 -0.10694 0.25833 -0.034388 -0.110107 0.257482 -0.034165 -0.114446 0.286342 0.004082 -0.080498 0.265416 -0.034388 -0.110107 0.257482 -0.034165 -0.10694 0.25833 -0.00341801 -0.076742 0.266422 -0.034165 -0.10694 0.25833 -0.035427 -0.098872 0.260492 -0.009366879999999999 -0.07095220000000001 0.267974 -0.035427 -0.098872 0.260492 -0.039209 -0.091576 0.262447 -0.035427 -0.098872 0.260492 -0.009366879999999999 -0.07095220000000001 0.267974 -0.00341801 -0.076742 0.266422 -0.039209 -0.099082 0.290459 -0.039209 -0.091576 0.262447 -0.035427 -0.098872 0.260492 -0.035427 -0.106378 0.288504 -0.035427 -0.098872 0.260492 -0.034165 -0.10694 0.25833 -0.035427 -0.098872 0.260492 -0.035427 -0.106378 0.288504 -0.039209 -0.099082 0.290459 -0.0112252 -0.0836884 0.334 0.024572 -0.08803900000000001 0.354568 -0.0158038 -0.0837065 0.334 0.0151579 -0.0860161 0.344257 0.024572 -0.08803900000000001 0.354568 -0.0112252 -0.0836884 0.334 0.041541 -0.088299 0.354263 0.0151579 -0.0860161 0.344257 0.00106212 -0.0839163 0.334 0.041541 -0.088299 0.354263 0.00106212 -0.0839163 0.334 0.011392 -0.08390549999999999 0.334 0.041541 -0.088299 0.354263 0.024572 -0.08803900000000001 0.354568 0.0151579 -0.0860161 0.344257 0.0414966 -0.084435 0.334 0.0457278 -0.0835847 0.334 0.041541 -0.088299 0.354263 0.0415602 -0.0882602 0.356609 0.041541 -0.088299 0.354263 0.0457278 -0.0835847 0.334 0.0457278 -0.0835847 0.334 0.0525 -0.082581 0.334 0.0415602 -0.0882602 0.356609 0.0415602 -0.0882602 0.356609 0.0525 -0.082581 0.334 0.059001 -0.089419 0.377466 -0.00138822 -0.0857882 0.34441 -0.0273484 -0.0834934 0.334 -0.0158038 -0.0837065 0.334 -0.0112252 -0.0836884 0.334 0.00106212 -0.0839163 0.334 0.0151579 -0.0860161 0.344257 0.059001 -0.089419 0.377466 0.04381 -0.088032 0.364949 0.042747 -0.08745699999999999 0.36068 0.044958 -0.088741 0.370332 0.04381 -0.088032 0.364949 0.059001 -0.089419 0.377466 0.00725699 -0.088821 0.293208 0.00725699 -0.081315 0.265196 0.004082 -0.080498 0.265416 0.00725699 -0.088821 0.293208 0.011373 -0.08988 0.292924 0.00725699 -0.081315 0.265196 0.011373 -0.08988 0.292924 0.0192849 -0.0935428 0.291944 0.011373 -0.082374 0.264912 0.011373 -0.082374 0.264912 0.00725699 -0.081315 0.265196 0.011373 -0.08988 0.292924 0.00725699 -0.081315 0.265196 0.011373 -0.082374 0.264912 -0.034433 -0.118451 0.255247 0.00725699 -0.081315 0.265196 -0.034433 -0.118451 0.255247 -0.034388 -0.110107 0.257482 -0.034388 -0.110107 0.257482 -0.034433 -0.118451 0.255247 -0.034388 -0.117613 0.285493 0.0418368 -0.113957 0.489412 0.0418333 -0.11397 0.48782 0.06760099999999999 -0.113524 0.488197 0.0418333 -0.11397 0.48782 0.0418247 -0.113646 0.483969 0.06760099999999999 -0.113524 0.488197 0.0418372 -0.113956 0.489576 0.0418368 -0.113957 0.489412 0.06760099999999999 -0.113524 0.488197 0.0418247 -0.113646 0.483969 0.0418204 -0.113436 0.482065 0.06760099999999999 -0.112671 0.480468 0.06760099999999999 -0.112671 0.480468 0.041814 -0.112979 0.479169 0.0418121 -0.112822 0.47833 0.004082 -0.080498 0.265416 0.00725699 -0.081315 0.265196 -0.034388 -0.110107 0.257482 -0.034433 -0.118451 0.255247 -0.034433 -0.125957 0.283258 -0.034388 -0.117613 0.285493 0.0223278 -0.09600980000000001 0.291282 0.026005 -0.098991 0.290483 0.019285 -0.086037 0.263931 0.019285 -0.086037 0.263931 -0.032312 -0.126674 0.253043 -0.034433 -0.118451 0.255247 0.019285 -0.086037 0.263931 0.026005 -0.091485 0.262471 -0.032312 -0.126674 0.253043 0.026005 -0.091485 0.262471 0.019285 -0.086037 0.263931 0.026005 -0.098991 0.290483 0.026005 -0.091485 0.262471 -0.02814 -0.134129 0.251045 -0.032312 -0.126674 0.253043 -0.032312 -0.13418 0.281054 -0.032312 -0.126674 0.253043 -0.02814 -0.134129 0.251045 -0.02814 -0.134129 0.251045 -0.02814 -0.141635 0.279057 -0.032312 -0.13418 0.281054 -0.02814 -0.134129 0.251045 -0.022179 -0.140348 0.249379 -0.02814 -0.141635 0.279057 -0.032312 -0.126674 0.253043 -0.032312 -0.13418 0.281054 -0.034433 -0.125957 0.283258 0.019285 -0.086037 0.263931 0.0200627 -0.0941734 0.291775 0.0223278 -0.09600980000000001 0.291282 -0.02814 -0.134129 0.251045 0.026005 -0.091485 0.262471 0.031111 -0.09837600000000001 0.260625 0.0192849 -0.0935428 0.291944 0.0200627 -0.0941734 0.291775 0.019285 -0.086037 0.263931 0.06760099999999999 -0.08465 0.386212 0.06760099999999999 -0.08888500000000001 0.391522 0.059001 -0.091573 0.395704 -0.00138822 -0.0857882 0.34441 0.007603 -0.087779 0.354873 -0.0273484 -0.0834934 0.334 0.024572 -0.08803900000000001 0.354568 -0.00138822 -0.0857882 0.34441 -0.0158038 -0.0837065 0.334 0.026005 -0.091485 0.262471 0.026005 -0.098991 0.290483 0.0293444 -0.103498 0.289276 -0.060273 -0.086738 0.356093 -0.094276 -0.08119 0.325271 -0.026335 -0.087259 0.355483 -0.022179 -0.147853 0.277391 -0.02814 -0.141635 0.279057 -0.022179 -0.140348 0.249379 0.0326038 -0.106114 0.274631 0.031111 -0.105882 0.288637 0.034283 -0.113783 0.28652 0.031111 -0.09837600000000001 0.260625 0.0326038 -0.106114 0.274631 0.034283 -0.113783 0.28652 0.034283 -0.106278 0.258508 0.031111 -0.09837600000000001 0.260625 0.034283 -0.113783 0.28652 0.0326038 -0.106114 0.274631 0.031111 -0.09837600000000001 0.260625 0.031111 -0.105882 0.288637 0.0347672 -0.114242 0.272514 0.034283 -0.106278 0.258508 0.034283 -0.113783 0.28652 -0.00648101 -0.155121 0.275443 0.00227099 -0.148207 0.247273 0.00227099 -0.155713 0.275285 0.025664 -0.13777 0.25007 0.030872 -0.130949 0.251897 0.025664 -0.145275 0.278081 0.025664 -0.145275 0.278081 0.018865 -0.15063 0.276646 0.025664 -0.13777 0.25007 0.0109 -0.146678 0.247682 0.018865 -0.143125 0.248635 0.0109 -0.154184 0.275694 0.025664 -0.13777 0.25007 0.018865 -0.143125 0.248635 0.0109 -0.146678 0.247682 0.018865 -0.15063 0.276646 0.018865 -0.143125 0.248635 0.025664 -0.13777 0.25007 0.034283 -0.106278 0.258508 0.03532 -0.114692 0.256253 -0.014805 -0.144939 0.248148 0.03532 -0.114692 0.256253 0.034283 -0.106278 0.258508 0.03532 -0.122198 0.284265 0.034283 -0.106278 0.258508 -0.014805 -0.144939 0.248148 -0.022179 -0.140348 0.249379 0.03532 -0.122198 0.284265 0.034283 -0.106278 0.258508 0.0347672 -0.114242 0.272514 -0.014805 -0.144939 0.248148 0.03532 -0.114692 0.256253 -0.00648101 -0.147615 0.247431 0.034159 -0.123092 0.254002 0.03532 -0.114692 0.256253 0.034159 -0.130598 0.282014 0.03532 -0.114692 0.256253 0.034159 -0.123092 0.254002 -0.00648101 -0.147615 0.247431 0.034159 -0.123092 0.254002 0.00227099 -0.148207 0.247273 -0.00648101 -0.147615 0.247431 0.034159 -0.130598 0.282014 0.030872 -0.138455 0.27991 0.034159 -0.123092 0.254002 0.034159 -0.123092 0.254002 0.030872 -0.130949 0.251897 0.00227099 -0.148207 0.247273 -0.014805 -0.152445 0.27616 -0.014805 -0.144939 0.248148 -0.00648101 -0.147615 0.247431 -0.022179 -0.140348 0.249379 -0.014805 -0.144939 0.248148 -0.022179 -0.147853 0.277391 -0.0201217 -0.149134 0.277048 -0.022179 -0.147853 0.277391 -0.0167591 -0.147553 0.262769 -0.014805 -0.144939 0.248148 -0.0167591 -0.147553 0.262769 -0.022179 -0.147853 0.277391 -0.014805 -0.152445 0.27616 -0.0201217 -0.149134 0.277048 -0.0167591 -0.147553 0.262769 0.030872 -0.138455 0.27991 0.030872 -0.130949 0.251897 0.034159 -0.123092 0.254002 -0.00648101 -0.155121 0.275443 -0.014805 -0.152445 0.27616 -0.00648101 -0.147615 0.247431 0.00227099 -0.155713 0.275285 0.0109 -0.146678 0.247682 0.0109 -0.154184 0.275694 -0.106214 -0.075188 0.309795 -0.106494 -0.079836 0.333273 -0.117959 -0.074543 0.333388 -0.106494 -0.079836 0.333273 -0.1026 -0.084996 0.356729 -0.108735 -0.08329499999999999 0.35666 -0.1026 -0.084996 0.356729 -0.106494 -0.079836 0.333273 -0.094212 -0.086218 0.356704 -0.108735 -0.08329499999999999 0.35666 -0.117959 -0.074543 0.333388 -0.106494 -0.079836 0.333273 -0.094212 -0.086218 0.356704 -0.106494 -0.079836 0.333273 -0.09426 -0.082453 0.333163 0.083757 0.03397 0.471612 0.083161 0.040197 0.479069 0.084685 0.033971 0.479099 0.083161 0.040197 0.479069 0.083757 0.03397 0.471612 0.082525 0.040197 0.472918 0.082525 0.040197 0.472918 0.08107200000000001 0.044301 0.479023 0.083161 0.040197 0.479069 0.08107200000000001 0.044301 0.479023 0.08001900000000001 0.045722 0.479 0.080757 0.044301 0.482372 0.082525 0.040197 0.472918 0.08001900000000001 0.045722 0.479 0.08107200000000001 0.044301 0.479023 0.082525 0.040197 0.472918 0.080167 0.044149 0.472477 0.08001900000000001 0.045722 0.479 0.08001900000000001 0.045722 0.479 0.079994 0.045503 0.480707 0.080757 0.044301 0.482372 0.07780040000000001 0 0.53 0.07954559999999999 -0.000879971 0.4935 0.07954559999999999 0.000879971 0.4935 0.07954559999999999 -0.000879971 0.4935 0.07780040000000001 0 0.53 0.0794768 -0.010862 0.4935 0.0794768 -0.010862 0.4935 0.0799184 -0.005431 0.4935 0.07954559999999999 -0.000879971 0.4935 0.07780040000000001 0 0.53 0.07856929999999999 -0.015532 0.511746 0.0794768 -0.010862 0.4935 0.0419165 -0.100044 0.525991 0.0419129 -0.101701 0.524294 0.06760099999999999 -0.101744 0.523384 0.0547756 -0.07666000000000001 0.54158 0.0419503 -0.07822079999999999 0.541342 0.06760099999999999 -0.080802 0.539832 0.0547756 -0.07666000000000001 0.54158 0.0419521 -0.07576720000000001 0.542197 0.0419503 -0.07822079999999999 0.541342 0.06760099999999999 -0.080802 0.539832 0.06760099999999999 -0.072328 0.542782 0.0547756 -0.07666000000000001 0.54158 0.072714 -0.048196 0.536595 0.06760099999999999 -0.072328 0.542782 0.06760099999999999 -0.080802 0.539832 0.072714 -0.048196 0.536595 0.06760099999999999 -0.062782 0.5443750000000001 0.06760099999999999 -0.072328 0.542782 0.06760099999999999 -0.080802 0.539832 0.0419503 -0.07822079999999999 0.541342 0.0419393 -0.0878264 0.536362 0.0547669 -0.0885975 0.535144 0.06760099999999999 -0.080802 0.539832 0.0419393 -0.0878264 0.536362 0.06760099999999999 -0.095751 0.529524 0.0419328 -0.0920768 0.533431 0.0419182 -0.09948700000000001 0.526511 0.0547669 -0.0885975 0.535144 0.0419331 -0.0918987 0.533554 0.0419328 -0.0920768 0.533431 0.06760099999999999 -0.072328 0.542782 0.0419521 -0.07576720000000001 0.542197 0.0547756 -0.07666000000000001 0.54158 0.06760099999999999 -0.095751 0.529524 0.0419182 -0.09948700000000001 0.526511 0.0419165 -0.100044 0.525991 0.06760099999999999 -0.062782 0.5443750000000001 0.072714 -0.048196 0.536595 0.06840599999999999 -0.043556 0.546675 0.0419595 -0.0573276 0.5454830000000001 0.041958 -0.0628167 0.544822 0.06760099999999999 -0.062782 0.5443750000000001 0.06760099999999999 -0.062782 0.5443750000000001 0.06840599999999999 -0.043556 0.546675 0.0419595 -0.0573276 0.5454830000000001 0.0419595 -0.0573276 0.5454830000000001 0.06840599999999999 -0.043556 0.546675 0.0419594 -0.0562953 0.545449 0.06760099999999999 -0.030676 0.5462129999999999 0.06840599999999999 -0.043556 0.546675 0.072714 -0.048196 0.536595 0.06760099999999999 0.098633 0.417793 0.043362 0.102135 0.430031 0.042859 0.103849 0.437105 0.06760099999999999 0.098633 0.417793 0.06760099999999999 0.097194 0.412299 0.043362 0.102135 0.430031 0.0457278 0.0835847 0.334 0.041541 0.088299 0.354263 0.0415602 0.0882602 0.356609 0.0457278 0.0835847 0.334 0.0415602 0.0882602 0.356609 0.0525 0.082581 0.334 0.041541 0.088299 0.354263 0.011392 0.08390549999999999 0.334 0.00106212 0.0839163 0.334 0.041541 0.088299 0.354263 0.0414966 0.084435 0.334 0.011392 0.08390549999999999 0.334 0.041541 0.088299 0.354263 0.0457278 0.0835847 0.334 0.0414966 0.084435 0.334 0.007603 0.087779 0.354873 -0.00138822 0.0857882 0.34441 -0.0273484 0.0834934 0.334 -0.0158038 0.0837065 0.334 -0.0273484 0.0834934 0.334 -0.00138822 0.0857882 0.34441 -0.00138822 0.0857882 0.34441 0.007603 0.087779 0.354873 0.024572 0.08803900000000001 0.354568 -0.0273484 0.0834934 0.334 -0.0394457 0.0833752 0.334 0.007603 0.087779 0.354873 -0.00138822 0.0857882 0.34441 0.024572 0.08803900000000001 0.354568 -0.0158038 0.0837065 0.334 0.0417532 0.107167 0.451436 0.0417844 0.110183 0.465616 0.06760099999999999 0.108184 0.458108 0.0417532 0.107167 0.451436 0.06760099999999999 0.108184 0.458108 0.06760099999999999 0.106838 0.452 0.0417844 0.110183 0.465616 0.041802 0.111884 0.47371 0.06760099999999999 0.108184 0.458108 0.072714 0.09668400000000001 0.488844 0.06760099999999999 0.106838 0.452 0.06760099999999999 0.108184 0.458108 0.041802 0.111884 0.47371 0.06760099999999999 0.109492 0.4642 0.06760099999999999 0.108184 0.458108 0.00106212 0.0839163 0.334 0.0151579 0.0860161 0.344257 0.041541 0.088299 0.354263 0.00106212 0.0839163 0.334 -0.0112252 0.0836884 0.334 0.0151579 0.0860161 0.344257 -0.0112252 0.0836884 0.334 0.024572 0.08803900000000001 0.354568 0.0151579 0.0860161 0.344257 0.072714 0.09668400000000001 0.488844 0.06760099999999999 0.108184 0.458108 0.06760099999999999 0.109492 0.4642 0.0792075 0.0455203 0.480572 0.079994 0.045503 0.480707 0.0796132 0.0456125 0.479854 0.0796132 0.0456125 0.479854 0.079994 0.045503 0.480707 0.08001900000000001 0.045722 0.479 0.0792322 0.045722 0.479 0.0796132 0.0456125 0.479854 0.08001900000000001 0.045722 0.479 0.0792075 0.0455203 0.480572 0.07920530000000001 0.045503 0.480707 0.079994 0.045503 0.480707 0.07916869999999999 0.045204 0.483037 0.0795574 0.0446985 0.484291 0.07996 0.045204 0.483037 0.07915469999999999 0.0442721 0.48535 0.0795574 0.0446985 0.484291 0.07916869999999999 0.045204 0.483037 0.080757 0.044301 0.482372 0.07996 0.045204 0.483037 0.07993500000000001 0.044193 0.485546 0.079994 0.045503 0.480707 0.07996 0.045204 0.483037 0.080757 0.044301 0.482372 0.0795828 0.0453535 0.481872 0.07996 0.045204 0.483037 0.079994 0.045503 0.480707 0.07917159999999999 0.0452277 0.482853 0.0795828 0.0453535 0.481872 0.07920530000000001 0.045503 0.480707 0.07917159999999999 0.0452277 0.482853 0.07996 0.045204 0.483037 0.0795828 0.0453535 0.481872 0.07917159999999999 0.0452277 0.482853 0.07920530000000001 0.045503 0.480707 0.0784329 0.0567469 0.499244 0.0792075 0.0455203 0.480572 0.077801 0.078637 0.492309 0.0784329 0.0567469 0.499244 0.0792322 0.045722 0.479 0.077801 0.078637 0.492309 0.0792075 0.0455203 0.480572 0.0792413 0.0456696 0.478641 0.077801 0.078637 0.492309 0.0792322 0.045722 0.479 0.077801 0.078637 0.492309 0.0792413 0.0456696 0.478641 0.0792721 0.0454926 0.477428 0.077801 0.075124 0.452 0.077801 0.078637 0.492309 0.0792721 0.0454926 0.477428 0.072714 0.09668400000000001 0.488844 0.077801 0.078637 0.492309 0.077801 0.075124 0.452 0.07920530000000001 0.045503 0.480707 0.0792075 0.0455203 0.480572 0.0784329 0.0567469 0.499244 0.07915469999999999 0.0442721 0.48535 0.07916869999999999 0.045204 0.483037 0.0784329 0.0567469 0.499244 0.0784329 0.0567469 0.499244 0.07916869999999999 0.045204 0.483037 0.07917159999999999 0.0452277 0.482853 0.0791535 0.044193 0.485546 0.07915469999999999 0.0442721 0.48535 0.0784329 0.0567469 0.499244 0.07915469999999999 0.0442721 0.48535 0.07993500000000001 0.044193 0.485546 0.0795574 0.0446985 0.484291 0.07917159999999999 0.0452277 0.482853 0.07916869999999999 0.045204 0.483037 0.07996 0.045204 0.483037 0.0795574 0.0446985 0.484291 0.07993500000000001 0.044193 0.485546 0.07996 0.045204 0.483037 0.0784329 0.0567469 0.499244 0.077801 0.078637 0.492309 0.077801 0.062128 0.521061 0.077801 0.075124 0.452 0.07270799999999999 0.090958 0.452 0.072714 0.09668400000000001 0.488844 0.077801 0.078637 0.492309 0.072714 0.09668400000000001 0.488844 0.077801 0.062128 0.521061 0.0418851 0.109429 0.511525 0.0418924 0.107468 0.514809 0.06760099999999999 0.109104 0.511055 0.0701391 -0.0075135 0.542467 0.06885670000000001 -0.0075135 0.544556 0.06760099999999999 -0.015027 0.546662 0.06760099999999999 0 0.546542 0.06885670000000001 -0.0075135 0.544556 0.0701391 -0.0075135 0.542467 0.06760099999999999 -0.015027 0.546662 0.06885670000000001 -0.0075135 0.544556 0.06760099999999999 0 0.546542 0.0606135 0 0.546342 0.06760099999999999 0 0.546542 0.06760099999999999 0.015027 0.546662 0.06760099999999999 -0.015027 0.546662 0.06760099999999999 0 0.546542 0.0606135 0 0.546342 0.06760099999999999 -0.015027 0.546662 0.0606135 0 0.546342 0.0599825 0 0.546275 0.06760099999999999 -0.015027 0.546662 0.0599825 0 0.546275 0.0557236 -1.03398e-25 0.545817 0.0557236 -1.03398e-25 0.545817 0.0599825 0 0.546275 0.06760099999999999 0.015027 0.546662 0.0547669 0.0885975 0.535144 0.06760099999999999 0.095751 0.529524 0.0419328 0.0920768 0.533431 0.06760099999999999 0.095751 0.529524 0.0419182 0.09948700000000001 0.526511 0.0419328 0.0920768 0.533431 0.0419594 0.0562953 0.545449 0.06840599999999999 0.043556 0.546675 0.0419595 0.0573276 0.5454830000000001 0.06840599999999999 0.043556 0.546675 0.06760099999999999 0.062782 0.5443750000000001 0.0419595 0.0573276 0.5454830000000001 0.06760099999999999 0.062782 0.5443750000000001 0.06840599999999999 0.043556 0.546675 0.072714 0.048196 0.536595 0.06760099999999999 0.030676 0.5462129999999999 0.0419592 0.0534463 0.545358 0.0419622 0.0300187 0.546692 0.0419622 0.0300187 0.546692 0.0547816 0.0268371 0.546381 0.06760099999999999 0.030676 0.5462129999999999 0.0547816 0.0230032 0.546303 0.0547816 0.0268371 0.546381 0.0419622 0.0300187 0.546692 0.06760099999999999 0.030676 0.5462129999999999 0.06840599999999999 0.043556 0.546675 0.0419592 0.0534463 0.545358 0.072714 0.048196 0.536595 0.06840599999999999 0.043556 0.546675 0.06760099999999999 0.030676 0.5462129999999999 0.06760099999999999 0.072328 0.542782 0.06760099999999999 0.062782 0.5443750000000001 0.072714 0.048196 0.536595 0.0418924 0.107468 0.514809 0.06760099999999999 0.101744 0.523384 0.06760099999999999 0.109104 0.511055 0.06760099999999999 0.109104 0.511055 0.06760099999999999 0.101744 0.523384 0.072714 0.0822 0.522573 0.06760099999999999 0.109104 0.511055 0.072714 0.0822 0.522573 0.06760099999999999 0.112983 0.497234 0.0418052 0.112203 0.475196 0.0418086 0.112526 0.476744 0.06760099999999999 0.110815 0.470543 0.0418052 0.112203 0.475196 0.06760099999999999 0.110815 0.470543 0.06760099999999999 0.109492 0.4642 0.06760099999999999 0.109492 0.4642 0.06760099999999999 0.110815 0.470543 0.072714 0.09668400000000001 0.488844 0.06760099999999999 0.113524 0.488197 0.0418247 0.113646 0.483969 0.0418333 0.11397 0.48782 0.06760099999999999 0.112671 0.480468 0.072714 0.09668400000000001 0.488844 0.06760099999999999 0.110815 0.470543 0.06760099999999999 0.113524 0.488197 0.072714 0.09668400000000001 0.488844 0.06760099999999999 0.112671 0.480468 0.06760099999999999 0.113524 0.488197 0.06760099999999999 0.112671 0.480468 0.0418247 0.113646 0.483969 0.06760099999999999 0.113524 0.488197 0.06760099999999999 0.11328 0.492262 0.072714 0.09668400000000001 0.488844 0.072714 0.048196 0.536595 0.06760099999999999 0.095751 0.529524 0.06760099999999999 0.080802 0.539832 0.072714 0.0822 0.522573 0.06760099999999999 0.095751 0.529524 0.072714 0.048196 0.536595 0.072714 0.09668400000000001 0.488844 0.06760099999999999 0.11328 0.492262 0.072714 0.0822 0.522573 0.072714 0.0822 0.522573 0.077801 0.062128 0.521061 0.072714 0.09668400000000001 0.488844 0.072714 0.048196 0.536595 0.077801 0.062128 0.521061 0.072714 0.0822 0.522573 0.06760099999999999 0.112983 0.497234 0.072714 0.0822 0.522573 0.06760099999999999 0.11328 0.492262 0.06760099999999999 0.080802 0.539832 0.06760099999999999 0.072328 0.542782 0.072714 0.048196 0.536595 0.0547756 0.07666000000000001 0.54158 0.0419521 0.07576720000000001 0.542197 0.06760099999999999 0.072328 0.542782 0.06760099999999999 0.072328 0.542782 0.06760099999999999 0.080802 0.539832 0.0547756 0.07666000000000001 0.54158 0.06760099999999999 0.080802 0.539832 0.0419393 0.0878264 0.536362 0.0419503 0.07822079999999999 0.541342 0.06760099999999999 0.080802 0.539832 0.0419503 0.07822079999999999 0.541342 0.0547756 0.07666000000000001 0.54158 0.0437663 0.112223 0.501431 0.0426141 0.110107 0.509057 0.06760099999999999 0.109104 0.511055 0.06760099999999999 0.109104 0.511055 0.06760099999999999 0.112983 0.497234 0.0437663 0.112223 0.501431 0.0443311 0.113262 0.497694 0.0437663 0.112223 0.501431 0.06760099999999999 0.112983 0.497234 0.0440203 0.113421 0.497149 0.0443311 0.113262 0.497694 0.06760099999999999 0.112983 0.497234 0.0553822 0.113355 0.494761 0.0440203 0.113421 0.497149 0.06760099999999999 0.112983 0.497234 0.06760099999999999 0.11328 0.492262 0.0431633 0.113523 0.495692 0.0553822 0.113355 0.494761 0.06760099999999999 0.11328 0.492262 0.0418429 0.113883 0.492218 0.0431633 0.113523 0.495692 0.0418429 0.113883 0.492218 0.0430399 0.113546 0.495482 0.0431633 0.113523 0.495692 0.0418502 0.113562 0.495605 0.0430399 0.113546 0.495482 0.0418429 0.113883 0.492218 0.0418407 0.113944 0.4912 0.06760099999999999 0.113524 0.488197 0.0418372 0.113956 0.489576 0.0418204 0.113436 0.482065 0.0418247 0.113646 0.483969 0.06760099999999999 0.112671 0.480468 0.0418121 0.112822 0.47833 0.041814 0.112979 0.479169 0.06760099999999999 0.112671 0.480468 0.041814 0.112979 0.479169 0.0418204 0.113436 0.482065 0.06760099999999999 0.112671 0.480468 0.06760099999999999 0.062782 0.5443750000000001 0.06760099999999999 0.072328 0.542782 0.041957 0.0656022 0.544357 0.0547816 0.0230032 0.546303 0.0419622 0.0300187 0.546692 0.0547809 0.0153353 0.546147 0.072714 -0.010359 0.538295 0.06760099999999999 -0.030676 0.5462129999999999 0.072714 -0.048196 0.536595 0.072714 -0.010359 0.538295 0.06760099999999999 -0.015027 0.546662 0.06760099999999999 -0.030676 0.5462129999999999 0.072714 -0.010359 0.538295 0.072714 -0.048196 0.536595 0.077801 -0.062128 0.521061 0.06760099999999999 -0.030676 0.5462129999999999 0.06760099999999999 -0.015027 0.546662 0.0557236 -1.03398e-25 0.545817 0.0557236 -1.03398e-25 0.545817 0.0547809 -0.0153353 0.546147 0.06760099999999999 -0.030676 0.5462129999999999 0.06760099999999999 -0.030676 0.5462129999999999 0.0547809 -0.0153353 0.546147 0.0547816 -0.0230032 0.546303 0.0547809 0.0153353 0.546147 0.0419622 0.0300187 0.546692 0.0483709 0.0150118 0.546264 0.0419608 0 0.546081 0.0483709 0.0150118 0.546264 0.0419622 0.0300187 0.546692 0.0419622 -0.0300187 0.546692 0.0483709 -0.0150118 0.546264 0.0419608 0 0.546081 0.0547809 -0.0153353 0.546147 0.0483709 -0.0150118 0.546264 0.0419622 -0.0300187 0.546692 0.0547816 -0.0268371 0.546381 0.0547816 -0.0230032 0.546303 0.0419622 -0.0300187 0.546692 0.0547816 -0.0230032 0.546303 0.0547809 -0.0153353 0.546147 0.0419622 -0.0300187 0.546692 0.06760099999999999 -0.030676 0.5462129999999999 0.0547816 -0.0268371 0.546381 0.0419622 -0.0300187 0.546692 0.06760099999999999 -0.030676 0.5462129999999999 0.0419622 -0.0300187 0.546692 0.0419592 -0.0534463 0.545358 0.06760099999999999 -0.030676 0.5462129999999999 0.0547816 -0.0230032 0.546303 0.0547816 -0.0268371 0.546381 0.0547809 0.0153353 0.546147 0.0483709 0.0150118 0.546264 0.0419608 0 0.546081 0.07780040000000001 0 0.53 0.072714 -0.010359 0.538295 0.077801 -0.062128 0.521061 0.077801 -0.062128 0.521061 0.0784712 -0.031064 0.511558 0.07780040000000001 0 0.53 0.07856929999999999 -0.015532 0.511746 0.07780040000000001 0 0.53 0.0784712 -0.031064 0.511558 0.0793727 -0.0259411 0.4935 0.0798664 -0.01902 0.4935 0.0794768 -0.010862 0.4935 0.0794768 -0.010862 0.4935 0.0784712 -0.031064 0.511558 0.0793727 -0.0259411 0.4935 0.0794768 -0.010862 0.4935 0.07856929999999999 -0.015532 0.511746 0.0784712 -0.031064 0.511558 0.0418407 0.113944 0.4912 0.0418429 0.113883 0.492218 0.06760099999999999 0.11328 0.492262 0.0793727 -0.0259411 0.4935 0.0784712 -0.031064 0.511558 0.0793642 -0.027178 0.4935 0.080029 -0.032595 0.4935 0.080112 -0.027178 0.4935 0.07972070000000001 -0.0298865 0.4935 0.07972070000000001 -0.0298865 0.4935 0.080112 -0.027178 0.4935 0.0793642 -0.027178 0.4935 0.07932939999999999 -0.0322129 0.4935 0.080029 -0.032595 0.4935 0.07972070000000001 -0.0298865 0.4935 0.0793268 -0.032595 0.4935 0.080029 -0.032595 0.4935 0.07932939999999999 -0.0322129 0.4935 0.07932939999999999 -0.0322129 0.4935 0.0784712 -0.031064 0.511558 0.0793268 -0.032595 0.4935 0.0793642 -0.027178 0.4935 0.0784712 -0.031064 0.511558 0.07932939999999999 -0.0322129 0.4935 0.07932939999999999 -0.0322129 0.4935 0.07972070000000001 -0.0298865 0.4935 0.0793642 -0.027178 0.4935 0.06760099999999999 0.062782 0.5443750000000001 0.041958 0.0628167 0.544822 0.0419595 0.0573276 0.5454830000000001 0.0418372 0.113956 0.489576 0.06760099999999999 0.113524 0.488197 0.0418368 0.113957 0.489412 0.06760099999999999 0.112983 0.497234 0.06760099999999999 0.11328 0.492262 0.0553822 0.113355 0.494761 0.06760099999999999 0.030676 0.5462129999999999 0.0547816 0.0268371 0.546381 0.0547816 0.0230032 0.546303 0.06760099999999999 0.062782 0.5443750000000001 0.041957 0.0656022 0.544357 0.041958 0.0628167 0.544822 0.072714 0.010359 0.538295 0.077801 0.062128 0.521061 0.072714 0.048196 0.536595 0.0701391 -0.0075135 0.542467 0.06760099999999999 -0.015027 0.546662 0.072714 -0.010359 0.538295 0.07416590000000001 0 0.53572 0.072714 0 0.5381590000000001 0.072714 -0.010359 0.538295 0.072714 0 0.5381590000000001 0.0712801 0 0.540548 0.072714 -0.010359 0.538295 0.0712801 0 0.540548 0.0701391 -0.0075135 0.542467 0.072714 -0.010359 0.538295 0.072714 0.048196 0.536595 0.06760099999999999 0.030676 0.5462129999999999 0.072714 0.010359 0.538295 0.06760099999999999 0.113524 0.488197 0.0418333 0.11397 0.48782 0.0418368 0.113957 0.489412 0.0798664 -0.01902 0.4935 0.08036 -0.010862 0.4935 0.0794768 -0.010862 0.4935 0.08053979999999999 -0.0169241 0.4645 0.0805501 -0.0166998 0.4645 0.081124 -0.016307 0.4645 0.0805501 -0.0166998 0.4645 0.080564 -0.016307 0.4645 0.081124 -0.016307 0.4645 0.081124 -0.016307 0.4645 0.080564 -0.016307 0.4645 0.0809145 -0.008153499999999999 0.4645 0.08089490000000001 -0.00692969 0.4645 0.0809145 -0.008153499999999999 0.4645 0.080564 -0.016307 0.4645 0.0812649 -1.65569e-10 0.4645 0.0809145 -0.008153499999999999 0.4645 0.08089490000000001 -0.00692969 0.4645 0.081124 -0.016307 0.4645 0.0809145 -0.008153499999999999 0.4645 0.0812649 -1.65569e-10 0.4645 0.08126800000000001 0 0.4645 0.0812649 -1.65569e-10 0.4645 0.081124 -0.016307 0.4645 0.081124 0.016307 0.4645 0.0812649 -1.65569e-10 0.4645 0.08126800000000001 0 0.4645 0.08126800000000001 0 0.4645 0.08400680000000001 0 0.471638 0.081124 -0.016307 0.4645 0.083979 -0.027179 0.471577 0.0825649 -0.0135895 0.468069 0.08400680000000001 0 0.471638 0.08400680000000001 0 0.471638 0.0825649 -0.0135895 0.468069 0.081124 -0.016307 0.4645 0.08488999999999999 -0.027179 0.479101 0.083979 -0.027179 0.471577 0.08400680000000001 0 0.471638 0.080112 -0.027178 0.4935 0.08036 -0.010862 0.4935 0.0798664 -0.01902 0.4935 0.08036 -0.010862 0.4935 0.080112 -0.027178 0.4935 0.083608 -0.027179 0.486575 0.08036 -0.010862 0.4935 0.0803575 -1.35465e-10 0.4935 0.0799184 -0.005431 0.4935 0.08355940000000001 0 0.48654 0.0803575 -1.35465e-10 0.4935 0.08036 -0.010862 0.4935 0.08355940000000001 0 0.48654 0.08036 -0.010862 0.4935 0.083608 -0.027179 0.486575 0.08476590000000001 0 0.479119 0.08355940000000001 0 0.48654 0.083608 -0.027179 0.486575 0.08476590000000001 0 0.479119 0.083608 -0.027179 0.486575 0.08488999999999999 -0.027179 0.479101 0.08400680000000001 0 0.471638 0.08476590000000001 0 0.479119 0.08488999999999999 -0.027179 0.479101 0.06760099999999999 -0.095751 0.529524 0.0547669 -0.0885975 0.535144 0.0419328 -0.0920768 0.533431 0.06760099999999999 -0.095751 0.529524 0.061184 -0.088437 0.534911 0.0547669 -0.0885975 0.535144 0.0418407 -0.113944 0.4912 0.06760099999999999 -0.113524 0.488197 0.06760099999999999 -0.11328 0.492262 0.0418429 -0.113883 0.492218 0.0418407 -0.113944 0.4912 0.06760099999999999 -0.11328 0.492262 0.0418851 -0.109429 0.511525 0.0426141 -0.110107 0.509057 0.06760099999999999 -0.109104 0.511055 0.0418978 -0.106004 0.517218 0.0418924 -0.107468 0.514809 0.06760099999999999 -0.101744 0.523384 0.0418982 -0.105879 0.517422 0.0418978 -0.106004 0.517218 0.06760099999999999 -0.101744 0.523384 0.0419097 -0.102618 0.5227850000000001 0.0418982 -0.105879 0.517422 0.06760099999999999 -0.101744 0.523384 0.0431633 -0.113523 0.495692 0.0430399 -0.113546 0.495482 0.0418429 -0.113883 0.492218 0.0418502 -0.113562 0.495605 0.0418429 -0.113883 0.492218 0.0430399 -0.113546 0.495482 0.0431633 -0.113523 0.495692 0.0418429 -0.113883 0.492218 0.06760099999999999 -0.11328 0.492262 0.0443311 -0.113262 0.497694 0.0440203 -0.113421 0.497149 0.06760099999999999 -0.112983 0.497234 0.0437663 -0.112223 0.501431 0.0443311 -0.113262 0.497694 0.06760099999999999 -0.112983 0.497234 0.0437663 -0.112223 0.501431 0.06760099999999999 -0.112983 0.497234 0.06760099999999999 -0.109104 0.511055 0.06760099999999999 -0.112983 0.497234 0.072714 -0.0822 0.522573 0.06760099999999999 -0.109104 0.511055 0.0553822 -0.113355 0.494761 0.0431633 -0.113523 0.495692 0.06760099999999999 -0.11328 0.492262 0.072714 -0.0822 0.522573 0.06760099999999999 -0.112983 0.497234 0.06760099999999999 -0.11328 0.492262 0.06760099999999999 -0.109104 0.511055 0.072714 -0.0822 0.522573 0.06760099999999999 -0.101744 0.523384 0.072714 -0.0822 0.522573 0.072714 -0.048196 0.536595 0.06760099999999999 -0.095751 0.529524 0.072714 -0.0822 0.522573 0.06760099999999999 -0.095751 0.529524 0.06760099999999999 -0.101744 0.523384 0.0440203 -0.113421 0.497149 0.0431633 -0.113523 0.495692 0.0553822 -0.113355 0.494761 0.0553822 -0.113355 0.494761 0.06760099999999999 -0.11328 0.492262 0.06760099999999999 -0.112983 0.497234 -0.094276 0.08119 0.325271 -0.060273 0.086738 0.356093 -0.026335 0.087259 0.355483 -0.117959 0.074543 0.333388 -0.118275 0.079184 0.356402 -0.108735 0.08329499999999999 0.35666 -0.060273 0.086738 0.356093 -0.094276 0.08119 0.325271 -0.09426 0.082453 0.333163 -0.09426 0.082453 0.333163 -0.094276 0.08119 0.325271 -0.106494 0.079836 0.333273 -0.094276 0.08119 0.325271 -0.061307 0.0828207 0.332976 -0.061307 0.08261880000000001 0.331907 -0.094276 0.08119 0.325271 -0.061307 0.0830142 0.334 -0.061307 0.0828207 0.332976 -0.094309 0.07824 0.30966 -0.094276 0.08119 0.325271 -0.061307 0.08261880000000001 0.331907 -0.094309 0.07824 0.30966 -0.106494 0.079836 0.333273 -0.094276 0.08119 0.325271 -0.106494 0.079836 0.333273 -0.094309 0.07824 0.30966 -0.106214 0.075188 0.309795 -0.106214 0.075188 0.309795 -0.094309 0.07824 0.30966 -0.09434099999999999 0.075279 0.293992 -0.09434099999999999 0.075279 0.293992 -0.094309 0.07824 0.30966 -0.077824 0.078304 0.309147 -0.077824 0.078304 0.309147 -0.094309 0.07824 0.30966 -0.061307 0.081329 0.324301 -0.09434099999999999 0.075279 0.293992 -0.077824 0.078304 0.309147 -0.061307 0.0793295 0.31372 -0.09434099999999999 0.075279 0.293992 -0.061307 0.0793295 0.31372 -0.061307 0.0788237 0.31082 -0.061307 0.0830142 0.334 -0.094276 0.08119 0.325271 -0.026335 0.087259 0.355483 -0.1026 0.084996 0.356729 -0.094212 0.086218 0.356704 -0.106494 0.079836 0.333273 -0.09426 0.082453 0.333163 -0.106494 0.079836 0.333273 -0.094212 0.086218 0.356704 -0.106494 0.079836 0.333273 -0.108735 0.08329499999999999 0.35666 -0.1026 0.084996 0.356729 -0.106494 0.079836 0.333273 -0.117959 0.074543 0.333388 -0.108735 0.08329499999999999 0.35666 -0.094212 0.086218 0.356704 -0.07724300000000001 0.086478 0.356398 -0.09426 0.082453 0.333163 -0.106214 0.075188 0.309795 -0.117959 0.074543 0.333388 -0.106494 0.079836 0.333273 -0.094309 0.07824 0.30966 -0.061307 0.08261880000000001 0.331907 -0.061307 0.081329 0.324301 0.041335 0.070367 0.260227 0.025353 0.0589956 0.260541 0.025326 0.0590106 0.260541 -0.0601191 0.0754635 0.295 -0.0599749 0.0754633 0.295 -0.0588761 0.0736657 0.286773 -0.0599749 0.0754633 0.295 -0.0589446 0.07546219999999999 0.295 -0.0588761 0.0736657 0.286773 -0.0249537 0.0590955 0.261529 -0.0253133 0.0589824 0.261536 -0.094407 0.06848799999999999 0.262893 -0.0129232 0.0628798 0.261293 -0.0249537 0.0590955 0.261529 -0.094407 0.06848799999999999 0.262893 0.000172782 0.0641847 0.261035 -1.24524e-08 0.0642022 0.261039 0.041335 0.070367 0.260227 -1.24524e-08 0.0642022 0.261039 -0.094407 0.06848799999999999 0.262893 0.041335 0.070367 0.260227 -0.0586339 0.0701278 0.268194 0.041335 0.070367 0.260227 -0.094407 0.06848799999999999 0.262893 -1.24518e-08 0.064217 0.260614 0.000172782 0.0641847 0.261035 -1.24524e-08 0.0642022 0.261039 0.000172782 0.0641847 0.261035 0.00646325 0.0635527 0.260825 -1.24518e-08 0.064217 0.260614 -0.012928 0.062903 0.260614 -0.0191222 0.0609423 0.261071 -0.0129232 0.0628798 0.261293 -0.0129232 0.0628798 0.261293 -0.0126472 0.06290800000000001 0.261287 -0.012928 0.062903 0.260614 -0.0129232 0.0628798 0.261293 -0.094407 0.06848799999999999 0.262893 -0.0126472 0.06290800000000001 0.261287 -0.00646282 0.0635484 0.260951 -0.012928 0.062903 0.260614 -0.0126472 0.06290800000000001 0.261287 -0.012928 0.062903 0.260614 -0.00646282 0.0635484 0.260951 -1.24518e-08 0.064217 0.260614 -1.24524e-08 0.0642022 0.261039 -1.24518e-08 0.064217 0.260614 -0.00646282 0.0635484 0.260951 -0.094407 0.06848799999999999 0.262893 -0.0587533 0.07187209999999999 0.277354 -0.0586339 0.0701278 0.268194 -0.0129232 0.0628798 0.261293 -0.0191222 0.0609423 0.261071 -0.0249537 0.0590955 0.261529 0.0129268 0.0628972 0.260785 0.041335 0.070367 0.260227 0.0129935 0.0628763 0.260784 0.012928 0.062903 0.260614 0.0129935 0.0628763 0.260784 0.0129268 0.0628972 0.260785 0.0215282 0.0602048 0.260616 0.012928 0.062903 0.260614 0.0129935 0.0628763 0.260784 0.0129935 0.0628763 0.260784 0.041335 0.070367 0.260227 0.0215282 0.0602048 0.260616 0.025326 0.0590106 0.260541 0.0215282 0.0602048 0.260616 0.041335 0.070367 0.260227 -1.24524e-08 0.0642022 0.261039 -0.00646282 0.0635484 0.260951 -0.0126472 0.06290800000000001 0.261287 0.00646325 0.0635527 0.260825 0.012928 0.062903 0.260614 -1.24518e-08 0.064217 0.260614 -0.094407 0.06848799999999999 0.262893 -0.0587706 0.07212399999999999 0.278677 -0.0587533 0.07187209999999999 0.277354 -0.058339 0.07176399999999999 0.267756 -0.0587706 0.07212399999999999 0.278677 -0.058339 0.0790632 0.295 -0.0587533 0.07187209999999999 0.277354 -0.0587706 0.07212399999999999 0.278677 -0.058339 0.07176399999999999 0.267756 -0.058339 0.0790632 0.295 -0.055224 0.077663 0.266175 -0.058339 0.07176399999999999 0.267756 -0.055224 0.077663 0.266175 -0.058339 0.0790632 0.295 -0.0582582 0.0792273 0.295 -0.058339 0.07176399999999999 0.267756 -0.055224 0.077663 0.266175 -0.0395053 0.07044789999999999 0.268076 -0.0582582 0.0792273 0.295 -0.0568258 0.082135 0.295 -0.055224 0.08516899999999999 0.294187 -0.055224 0.077663 0.266175 -0.0582582 0.0792273 0.295 -0.055224 0.08516899999999999 0.294187 -0.050447 0.082413 0.264902 -0.055224 0.077663 0.266175 -0.055224 0.08516899999999999 0.294187 -0.0249537 0.0590955 0.261529 -0.0191222 0.0609423 0.261071 -0.025326 0.059012 0.260614 -0.025326 0.059012 0.260614 -0.0191222 0.0609423 0.261071 -0.012928 0.062903 0.260614 -1.24518e-08 -0.064217 0.260614 0.00646325 -0.0635527 0.260825 0.000172782 -0.0641847 0.261035 -1.24518e-08 -0.064217 0.260614 -1.24524e-08 -0.0642022 0.261039 0.000172782 -0.0641847 0.261035 0.0129268 -0.0628972 0.260785 0.00646325 -0.0635527 0.260825 0.012928 -0.062903 0.260614 0.012928 -0.062903 0.260614 0.0129935 -0.0628763 0.260784 0.0129268 -0.0628972 0.260785 0.012928 -0.062903 0.260614 0.0215282 -0.0602048 0.260616 0.0129935 -0.0628763 0.260784 -0.012928 -0.062903 0.260614 -1.24518e-08 -0.064217 0.260614 -0.00646282 -0.0635484 0.260951 -0.0126472 -0.06290800000000001 0.261287 -0.00646282 -0.0635484 0.260951 -1.24524e-08 -0.0642022 0.261039 -1.24524e-08 -0.0642022 0.261039 -0.00646282 -0.0635484 0.260951 -1.24518e-08 -0.064217 0.260614 -0.0126472 -0.06290800000000001 0.261287 -0.012928 -0.062903 0.260614 -0.00646282 -0.0635484 0.260951 0.0129935 -0.0628763 0.260784 0.0215282 -0.0602048 0.260616 0.041335 -0.070367 0.260227 -0.094407 -0.06848799999999999 0.262893 -0.0126472 -0.06290800000000001 0.261287 -1.24524e-08 -0.0642022 0.261039 -0.094407 -0.06848799999999999 0.262893 -1.24524e-08 -0.0642022 0.261039 0.041335 -0.070367 0.260227 -1.24524e-08 -0.0642022 0.261039 0.000172782 -0.0641847 0.261035 0.041335 -0.070367 0.260227 -0.094407 -0.06848799999999999 0.262893 -0.0129232 -0.0628798 0.261293 -0.0126472 -0.06290800000000001 0.261287 -0.0253133 0.0589824 0.261536 -0.0309974 0.0558417 0.261182 -0.0362556 0.0529008 0.261751 -0.0309974 0.0558417 0.261182 -0.036688 0.052706 0.260614 -0.0362556 0.0529008 0.261751 -0.036688 0.052706 0.260614 -0.0309974 0.0558417 0.261182 -0.025326 0.059012 0.260614 -0.094407 -0.06848799999999999 0.262893 -0.0253133 -0.0589824 0.261536 -0.0249537 -0.0590955 0.261529 -0.094407 -0.06848799999999999 0.262893 -0.0249537 -0.0590955 0.261529 -0.0129232 -0.0628798 0.261293 -0.094407 -0.06848799999999999 0.262893 -0.0362556 -0.0529008 0.261751 -0.0253133 -0.0589824 0.261536 -0.0249537 -0.0590955 0.261529 -0.0191222 -0.0609423 0.261071 -0.0129232 -0.0628798 0.261293 -0.0191222 -0.0609423 0.261071 -0.025326 -0.059012 0.260614 -0.012928 -0.062903 0.260614 -0.025326 -0.059012 0.260614 -0.0191222 -0.0609423 0.261071 -0.0249537 -0.0590955 0.261529 0.0129268 -0.0628972 0.260785 0.0129935 -0.0628763 0.260784 0.041335 -0.070367 0.260227 -1.24518e-08 -0.064217 0.260614 0.012928 -0.062903 0.260614 0.00646325 -0.0635527 0.260825 0.000172782 -0.0641847 0.261035 0.0129268 -0.0628972 0.260785 0.041335 -0.070367 0.260227 0.0215282 -0.0602048 0.260616 0.025326 -0.0590106 0.260541 0.041335 -0.070367 0.260227 0.012928 0.062903 0.260614 0.00646325 0.0635527 0.260825 0.0129268 0.0628972 0.260785 0.025353 -0.0589956 0.260541 0.041335 -0.070367 0.260227 0.025326 -0.0590106 0.260541 0.041335 -0.070367 0.260227 0.025353 -0.0589956 0.260541 0.0366821 -0.0526975 0.260318 0.041335 -0.070367 0.260227 0.0366821 -0.0526975 0.260318 0.0367757 -0.052617 0.260317 0.0129268 0.0628972 0.260785 0.00646325 0.0635527 0.260825 0.000172782 0.0641847 0.261035 -0.094357 0.073585 0.286235 -0.061307 0.0776017 0.305225 -0.061307 0.07716339999999999 0.302779 -0.135472 0.04726 0.354722 -0.124983 0.072046 0.355864 -0.130461 0.052724 0.33346 -0.12413 0.067466 0.333441 -0.130461 0.052724 0.33346 -0.124983 0.072046 0.355864 -0.123512 0.061676 0.31001 -0.130461 0.052724 0.33346 -0.12413 0.067466 0.333441 -0.117537 0.06936199999999999 0.309941 -0.123512 0.061676 0.31001 -0.12413 0.067466 0.333441 -0.12413 0.067466 0.333441 -0.117959 0.074543 0.333388 -0.117537 0.06936199999999999 0.309941 -0.123512 0.061676 0.31001 -0.117537 0.06936199999999999 0.309941 -0.117026 0.063762 0.286585 -0.105911 0.070065 0.286406 -0.094407 0.06848799999999999 0.262893 -0.106491 0.06393799999999999 0.26313 -0.105911 0.070065 0.286406 -0.094357 0.073585 0.286235 -0.094407 0.06848799999999999 0.262893 -0.106491 0.06393799999999999 0.26313 -0.115974 0.05809 0.263317 -0.105911 0.070065 0.286406 -0.094357 0.073585 0.286235 -0.105911 0.070065 0.286406 -0.106214 0.075188 0.309795 -0.117537 0.06936199999999999 0.309941 -0.106214 0.075188 0.309795 -0.105911 0.070065 0.286406 -0.117537 0.06936199999999999 0.309941 -0.105911 0.070065 0.286406 -0.117026 0.063762 0.286585 -0.117026 0.063762 0.286585 -0.105911 0.070065 0.286406 -0.115974 0.05809 0.263317 -0.115974 0.05809 0.263317 -0.120144 0.052723 0.263398 -0.117026 0.063762 0.286585 -0.120144 0.052723 0.263398 -0.121458 0.058391 0.286654 -0.117026 0.063762 0.286585 -0.120144 0.052723 0.263398 -0.115974 0.05809 0.263317 -0.094407 0.06848799999999999 0.262893 -0.122964 0.045036 0.263453 -0.120144 0.052723 0.263398 -0.094407 0.06848799999999999 0.262893 0.043362 -0.102135 0.430031 0.043928 -0.100007 0.421527 0.06760099999999999 -0.097194 0.412299 0.06760099999999999 -0.112983 0.497234 0.0440203 -0.113421 0.497149 0.0553822 -0.113355 0.494761 0.06760099999999999 0.080802 0.539832 0.0547669 0.0885975 0.535144 0.0419393 0.0878264 0.536362 0.0547669 0.0885975 0.535144 0.06760099999999999 0.080802 0.539832 0.061184 0.088437 0.534911 0.084685 0.033971 0.479099 0.08488999999999999 0.027179 0.479101 0.083757 0.03397 0.471612 0.083757 0.03397 0.471612 0.083979 0.027179 0.471577 0.08068500000000001 0.032615 0.4645 0.08068500000000001 0.032615 0.4645 0.083979 0.027179 0.471577 0.080832 0.027179 0.4645 0.083757 0.03397 0.471612 0.08488999999999999 0.027179 0.479101 0.083979 0.027179 0.471577 -0.0249537 -0.0590955 0.261529 -0.0253133 -0.0589824 0.261536 -0.025326 -0.059012 0.260614 -0.0396619 -0.0503348 0.261243 -0.042663 -0.047998 0.260614 -0.036688 -0.052706 0.260614 -0.0253133 -0.0589824 0.261536 -0.0309974 -0.0558417 0.261182 -0.025326 -0.059012 0.260614 -0.0309974 -0.0558417 0.261182 -0.036688 -0.052706 0.260614 -0.025326 -0.059012 0.260614 -0.036688 -0.052706 0.260614 -0.0309974 -0.0558417 0.261182 -0.0362556 -0.0529008 0.261751 -0.0362556 -0.0529008 0.261751 -0.0366651 -0.0526732 0.261759 -0.036688 -0.052706 0.260614 -0.0366651 -0.0526732 0.261759 -0.0396619 -0.0503348 0.261243 -0.036688 -0.052706 0.260614 -0.0423955 -0.048153 0.261871 -0.0396619 -0.0503348 0.261243 -0.0366651 -0.0526732 0.261759 -0.094407 -0.06848799999999999 0.262893 -0.0423955 -0.048153 0.261871 -0.0366651 -0.0526732 0.261759 -0.0423955 -0.048153 0.261871 -0.042663 -0.047998 0.260614 -0.0396619 -0.0503348 0.261243 -0.034433 -0.125957 0.283258 -0.034433 -0.118451 0.255247 -0.032312 -0.126674 0.253043 0.0419594 -0.0562953 0.545449 0.06840599999999999 -0.043556 0.546675 0.0419592 -0.0534463 0.545358 0.061184 0.088437 0.534911 0.06760099999999999 0.095751 0.529524 0.0547669 0.0885975 0.535144 0.06439250000000001 0.0883568 0.534794 0.06760099999999999 0.095751 0.529524 0.061184 0.088437 0.534911 -0.042663 0.047998 0.260614 -0.046547 0.044242 0.260614 -0.0445888 0.0461032 0.261283 -0.0465132 0.0442098 0.261952 -0.0445888 0.0461032 0.261283 -0.046547 0.044242 0.260614 -0.0427895 0.0478143 0.261879 -0.0445888 0.0461032 0.261283 -0.0465132 0.0442098 0.261952 -0.063481 0.009719999999999999 0.260614 -0.0634233 0.00971116 0.262284 -0.0618244 0.0160027 0.261449 -0.063481 0.009719999999999999 0.260614 -0.0618244 0.0160027 0.261449 -0.060224 0.0223 0.260614 -0.0618244 0.0160027 0.261449 -0.0603376 0.0216382 0.262224 -0.060224 0.0223 0.260614 -0.060224 0.0223 0.260614 -0.0601714 0.0222805 0.262221 -0.0573374 0.0281207 0.261417 -0.060224 0.0223 0.260614 -0.0603376 0.0216382 0.262224 -0.0601714 0.0222805 0.262221 -0.0573374 0.0281207 0.261417 -0.0601714 0.0222805 0.262221 -0.0564385 0.0298955 0.262147 -0.0564385 0.0298955 0.262147 -0.0601714 0.0222805 0.262221 -0.094407 0.06848799999999999 0.262893 -0.0573374 0.0281207 0.261417 -0.0564385 0.0298955 0.262147 -0.054501 0.033966 0.260614 -0.0564385 0.0298955 0.262147 -0.094407 0.06848799999999999 0.262893 -0.0547288 0.0333834 0.262114 -0.0468523 0.0437713 0.261959 -0.094407 0.06848799999999999 0.262893 -0.0465132 0.0442098 0.261952 -0.0544567 0.0339384 0.262108 -0.094407 0.06848799999999999 0.262893 -0.0468523 0.0437713 0.261959 -0.0547288 0.0333834 0.262114 -0.094407 0.06848799999999999 0.262893 -0.0544567 0.0339384 0.262108 -0.0465132 0.0442098 0.261952 -0.094407 0.06848799999999999 0.262893 -0.0427895 0.0478143 0.261879 -0.046547 0.044242 0.260614 -0.0468523 0.0437713 0.261959 -0.0465132 0.0442098 0.261952 -0.054501 0.033966 0.260614 -0.0547288 0.0333834 0.262114 -0.0544567 0.0339384 0.262108 -0.054501 0.033966 0.260614 -0.0505035 0.0390881 0.261361 -0.046547 0.044242 0.260614 -0.054501 0.033966 0.260614 -0.0544567 0.0339384 0.262108 -0.0505035 0.0390881 0.261361 -0.0505035 0.0390881 0.261361 -0.0468523 0.0437713 0.261959 -0.046547 0.044242 0.260614 -0.0468523 0.0437713 0.261959 -0.0505035 0.0390881 0.261361 -0.0544567 0.0339384 0.262108 0.08129 0 0.456649 0.0805501 -0.0166998 0.4645 0.08053979999999999 -0.0169241 0.4645 0.0804521 -0.033287 0.464585 0.080633 -0.033959 0.464671 0.08021929999999999 -0.033287 0.464585 0.0804521 -0.033287 0.464585 0.08021929999999999 -0.033287 0.464585 0.08068500000000001 -0.032615 0.4645 0.08068500000000001 -0.032615 0.4645 0.08021929999999999 -0.033287 0.464585 0.08024729999999999 -0.032951 0.464543 0.080633 -0.033959 0.464671 0.0804521 -0.033287 0.464585 0.08068500000000001 -0.032615 0.4645 0.08024729999999999 -0.032951 0.464543 0.08021929999999999 -0.033287 0.464585 0.07980959999999999 -0.032732 0.464515 0.083979 -0.027179 0.471577 0.080832 -0.027179 0.4645 0.081124 -0.016307 0.4645 0.080832 -0.027179 0.4645 0.083979 -0.027179 0.471577 0.08068500000000001 -0.032615 0.4645 0.080832 -0.027179 0.4645 0.080595 -0.021743 0.4645 0.081124 -0.016307 0.4645 0.08032350000000001 -0.029897 0.4645 0.080832 -0.027179 0.4645 0.08068500000000001 -0.032615 0.4645 0.08032350000000001 -0.029897 0.4645 0.0800466 -0.0275997 0.4645 0.080832 -0.027179 0.4645 0.0800466 -0.0275997 0.4645 0.0800661 -0.027179 0.4645 0.080832 -0.027179 0.4645 0.08129 0 0.456649 0.0800661 -0.027179 0.4645 0.0800466 -0.0275997 0.4645 0.08129 0 0.456649 0.0800466 -0.0275997 0.4645 0.079815 -0.032615 0.4645 0.08129 0 0.456649 0.079815 -0.032615 0.4645 0.077801 -0.075124 0.452 0.08129 0 0.456649 0.077801 -0.075124 0.452 0.0812885 0 0.456498 0.079815 -0.032615 0.4645 0.07980959999999999 -0.032732 0.464515 0.077801 -0.075124 0.452 0.07980959999999999 -0.032732 0.464515 0.07975359999999999 -0.033959 0.464671 0.077801 -0.075124 0.452 0.08068500000000001 -0.032615 0.4645 0.07980959999999999 -0.032732 0.464515 0.079815 -0.032615 0.4645 0.080832 -0.027179 0.4645 0.0800661 -0.027179 0.4645 0.080595 -0.021743 0.4645 0.08053979999999999 -0.0169241 0.4645 0.080595 -0.021743 0.4645 0.0800661 -0.027179 0.4645 0.08021929999999999 -0.033287 0.464585 0.07975359999999999 -0.033959 0.464671 0.07980959999999999 -0.032732 0.464515 0.08129 0 0.456649 0.08053979999999999 -0.0169241 0.4645 0.0800661 -0.027179 0.4645 0.077801 -0.071922 0.436239 0.0812885 0 0.456498 0.077801 -0.075124 0.452 0.072702 -0.082625 0.415539 0.077801 -0.075124 0.452 0.07270799999999999 -0.090958 0.452 0.07270799999999999 -0.090958 0.452 0.06760099999999999 -0.106838 0.452 0.072702 -0.082625 0.415539 0.072702 -0.082625 0.415539 0.077801 -0.071922 0.436239 0.077801 -0.075124 0.452 0.077801 -0.068165 0.419658 0.0812867 0 0.456321 0.077801 -0.071922 0.436239 0.0812885 0 0.456498 0.077801 -0.071922 0.436239 0.0812867 0 0.456321 0.077801 0.071922 0.436239 0.0812885 0 0.456498 0.0812867 0 0.456321 0.077801 -0.071922 0.436239 0.072702 -0.082625 0.415539 0.077801 -0.068165 0.419658 0.0812756 0 0.455844 0.0812867 0 0.456321 0.077801 -0.068165 0.419658 0.077801 0.068165 0.419658 0.0812867 0 0.456321 0.0812756 0 0.455844 0.0812756 0 0.455844 0.077801 -0.068165 0.419658 0.077801 -0.051714 0.39227 0.077801 0 0.381 0.0786414 0 0.389551 0.077801 -0.021838 0.381959 0.0786414 0 0.389551 0.07897800000000001 -0.015835 0.395385 0.077801 -0.021838 0.381959 0.07436810000000001 0 0.374716 0.077801 0 0.381 0.077801 -0.021838 0.381959 0.077801 0.021838 0.381959 0.0786414 0 0.389551 0.077801 0 0.381 0.077801 0.021838 0.381959 0.07897800000000001 0.015835 0.395385 0.0786414 0 0.389551 0.07897800000000001 0.015835 0.395385 0.0786501 0 0.389655 0.0786414 0 0.389551 0.08122409999999999 0 0.454132 0.077801 0.051714 0.39227 0.0812756 0 0.455844 0.0812756 0 0.455844 0.077801 -0.051714 0.39227 0.08122409999999999 0 0.454132 0.07897800000000001 0.015835 0.395385 0.077801 0.051714 0.39227 0.08122409999999999 0 0.454132 0.07897800000000001 0.015835 0.395385 0.07936790000000001 0 0.399119 0.0786501 0 0.389655 0.0786501 0 0.389655 0.07936790000000001 0 0.399119 0.07897800000000001 -0.015835 0.395385 0.07936790000000001 0 0.399119 0.08122409999999999 0 0.454132 0.07897800000000001 -0.015835 0.395385 0.08122409999999999 0 0.454132 0.07936790000000001 0 0.399119 0.07897800000000001 0.015835 0.395385 0.0786414 0 0.389551 0.0786501 0 0.389655 0.07897800000000001 -0.015835 0.395385 0.077801 0.071922 0.436239 0.077801 0.075124 0.452 0.0812885 0 0.456498 0.077801 0.075124 0.452 0.077801 0.071922 0.436239 0.072702 0.082625 0.415539 0.077801 -0.051714 0.39227 0.07897800000000001 -0.015835 0.395385 0.08122409999999999 0 0.454132 0.077801 -0.051714 0.39227 0.077801 -0.021838 0.381959 0.07897800000000001 -0.015835 0.395385 0.072702 -0.027146 0.373149 0.077801 -0.051714 0.39227 0.072702 -0.062892 0.38464 0.072702 -0.027146 0.373149 0.077801 -0.021838 0.381959 0.077801 -0.051714 0.39227 0.072714 -0.09668400000000001 0.488844 0.07270799999999999 -0.090958 0.452 0.077801 -0.075124 0.452 0.0792803 -0.045055 0.474428 0.0792831 -0.0449796 0.474266 0.080111 -0.045055 0.474428 0.0792803 -0.045055 0.474428 0.077801 -0.075124 0.452 0.0792831 -0.0449796 0.474266 0.07916869999999999 -0.045204 0.483037 0.07996 -0.045204 0.483037 0.0795574 -0.0446985 0.484291 0.07996 -0.045204 0.483037 0.07993500000000001 -0.044193 0.485546 0.0795574 -0.0446985 0.484291 0.07916869999999999 -0.045204 0.483037 0.0795574 -0.0446985 0.484291 0.07915469999999999 -0.0442721 0.48535 0.07916869999999999 -0.045204 0.483037 0.07917159999999999 -0.0452277 0.482853 0.07996 -0.045204 0.483037 0.07920530000000001 -0.045503 0.480707 0.07917159999999999 -0.0452277 0.482853 0.0784329 -0.0567469 0.499244 0.07917159999999999 -0.0452277 0.482853 0.07916869999999999 -0.045204 0.483037 0.0784329 -0.0567469 0.499244 0.0792075 -0.0455203 0.480572 0.07920530000000001 -0.045503 0.480707 0.0784329 -0.0567469 0.499244 0.07920530000000001 -0.045503 0.480707 0.0792075 -0.0455203 0.480572 0.079994 -0.045503 0.480707 0.0792075 -0.0455203 0.480572 0.0796132 -0.0456125 0.479854 0.079994 -0.045503 0.480707 0.0792075 -0.0455203 0.480572 0.077801 -0.078637 0.492309 0.0792322 -0.045722 0.479 0.0792322 -0.045722 0.479 0.0796132 -0.0456125 0.479854 0.0792075 -0.0455203 0.480572 0.0792322 -0.045722 0.479 0.08001900000000001 -0.045722 0.479 0.0796132 -0.0456125 0.479854 0.0792413 -0.0456696 0.478641 0.0792721 -0.0454926 0.477428 0.08001900000000001 -0.045722 0.479 0.0792721 -0.0454926 0.477428 0.0796762 -0.0453885 0.476714 0.08001900000000001 -0.045722 0.479 0.080111 -0.045055 0.474428 0.080167 -0.044149 0.472477 0.08001900000000001 -0.045722 0.479 0.0796762 -0.0453885 0.476714 0.080111 -0.045055 0.474428 0.08001900000000001 -0.045722 0.479 0.0792322 -0.045722 0.479 0.0792413 -0.0456696 0.478641 0.08001900000000001 -0.045722 0.479 0.0792721 -0.0454926 0.477428 0.0792413 -0.0456696 0.478641 0.077801 -0.078637 0.492309 0.08001900000000001 -0.045722 0.479 0.079994 -0.045503 0.480707 0.0796132 -0.0456125 0.479854 0.079994 -0.045503 0.480707 0.07996 -0.045204 0.483037 0.0795828 -0.0453535 0.481872 0.079994 -0.045503 0.480707 0.080757 -0.044301 0.482372 0.07996 -0.045204 0.483037 0.079994 -0.045503 0.480707 0.08001900000000001 -0.045722 0.479 0.080757 -0.044301 0.482372 0.0792803 -0.045055 0.474428 0.0796762 -0.0453885 0.476714 0.0792721 -0.0454926 0.477428 0.0792803 -0.045055 0.474428 0.0792721 -0.0454926 0.477428 0.077801 -0.075124 0.452 0.0792413 -0.0456696 0.478641 0.0792322 -0.045722 0.479 0.077801 -0.078637 0.492309 0.077801 -0.075124 0.452 0.0792721 -0.0454926 0.477428 0.077801 -0.078637 0.492309 0.077801 -0.078637 0.492309 0.072714 -0.09668400000000001 0.488844 0.077801 -0.075124 0.452 0.077801 -0.062128 0.521061 0.072714 -0.09668400000000001 0.488844 0.077801 -0.078637 0.492309 0.077801 -0.062128 0.521061 0.072714 -0.0822 0.522573 0.072714 -0.09668400000000001 0.488844 0.08488999999999999 0.027179 0.479101 0.08476590000000001 0 0.479119 0.08400680000000001 0 0.471638 0.06760099999999999 0.072328 0.542782 0.0419521 0.07576720000000001 0.542197 0.041957 0.0656022 0.544357 -0.0587706 0.07212399999999999 0.278677 -0.0588761 0.0736657 0.286773 -0.058339 0.0790632 0.295 -0.061307 0.0754647 0.295 -0.0601191 0.0754635 0.295 -0.0588761 0.0736657 0.286773 0.0418247 -0.113646 0.483969 0.06760099999999999 -0.112671 0.480468 0.06760099999999999 -0.113524 0.488197 0.08089490000000001 -0.00692969 0.4645 0.0809391 -0.000523865 0.4645 0.0812649 -1.65569e-10 0.4645 0.0809391 -0.000523865 0.4645 0.08089490000000001 -0.00692969 0.4645 0.0812833 0 0.457399 0.0809391 0.000523865 0.4645 0.0809391 -0.000523865 0.4645 0.0812833 0 0.457399 0.072714 0.09668400000000001 0.488844 0.07270799999999999 0.090958 0.452 0.06760099999999999 0.106838 0.452 0.072702 0.082625 0.415539 0.06760099999999999 0.106838 0.452 0.07270799999999999 0.090958 0.452 -0.00949171 -0.0778746 0.295 -0.00341801 -0.076742 0.266422 -0.009366879999999999 -0.07095220000000001 0.267974 0.0431633 0.113523 0.495692 0.0440203 0.113421 0.497149 0.0553822 0.113355 0.494761 0.079952 0.036598 0.492841 0.0792823 0.0363279 0.492885 0.0793291 0.0348661 0.493126 0.0796557 0.0345965 0.49317 0.079952 0.036598 0.492841 0.0793291 0.0348661 0.493126 0.0809391 -0.000523865 0.4645 0.0809391 0.000523865 0.4645 0.08110199999999999 -4.33681e-19 0.4645 0.08110199999999999 -4.33681e-19 0.4645 0.0812649 -1.65569e-10 0.4645 0.0809391 0.000523865 0.4645 0.08110199999999999 -4.33681e-19 0.4645 0.0809391 -0.000523865 0.4645 0.0812649 -1.65569e-10 0.4645 0.0809145 0.008153499999999999 0.4645 0.0812649 -1.65569e-10 0.4645 0.08089490000000001 0.00692969 0.4645 0.08089490000000001 0.00692969 0.4645 0.0812649 -1.65569e-10 0.4645 0.0809391 0.000523865 0.4645 0.0792075 -0.0455203 0.480572 0.0784329 -0.0567469 0.499244 0.077801 -0.078637 0.492309 0.00725699 0.081315 0.265196 0.011373 0.08988 0.292924 0.00725699 0.088821 0.293208 -0.124983 0.072046 0.355864 -0.118275 0.079184 0.356402 -0.12413 0.067466 0.333441 0.0419129 -0.101701 0.524294 0.0419097 -0.102618 0.5227850000000001 0.06760099999999999 -0.101744 0.523384 0.081124 0.016307 0.4645 0.0812649 -1.65569e-10 0.4645 0.0809145 0.008153499999999999 0.4645 -0.054501 0.033966 0.260614 -0.0564385 0.0298955 0.262147 -0.0547288 0.0333834 0.262114 0.045805 -0.090896 0.387693 0.045859 -0.090318 0.382877 0.059001 -0.091573 0.395704 0.077801 -0.062128 0.521061 0.0793291 -0.0348661 0.493126 0.0784712 -0.031064 0.511558 0.011373 0.082374 0.264912 0.00725699 0.081315 0.265196 -0.034433 0.118451 0.255247 -0.0587533 0.07187209999999999 0.277354 -0.058339 0.07176399999999999 0.267756 -0.0586339 0.0701278 0.268194 -0.0427895 0.0478143 0.261879 -0.042663 0.047998 0.260614 -0.0445888 0.0461032 0.261283 0.080374 -0.040142 0.467152 0.0799634 -0.0393835 0.466602 0.080443 -0.038625 0.466051 0.080232 -0.043105 0.470231 0.082525 -0.040197 0.472918 0.080167 -0.044149 0.472477 0.07977480000000001 -0.043627 0.471354 0.080232 -0.043105 0.470231 0.080167 -0.044149 0.472477 0.07935349999999999 -0.043105 0.470231 0.080232 -0.043105 0.470231 0.07977480000000001 -0.043627 0.471354 0.07935349999999999 -0.043105 0.470231 0.07977480000000001 -0.043627 0.471354 0.0793176 -0.0440597 0.472285 0.0793176 -0.0440597 0.472285 0.07977480000000001 -0.043627 0.471354 0.080167 -0.044149 0.472477 0.0793143 -0.044149 0.472477 0.0793176 -0.0440597 0.472285 0.080167 -0.044149 0.472477 0.0793143 -0.044149 0.472477 0.077801 -0.075124 0.452 0.0793176 -0.0440597 0.472285 0.0547669 -0.0885975 0.535144 0.0419393 -0.0878264 0.536362 0.0419331 -0.0918987 0.533554 0.06760099999999999 0.104222 0.44057 0.06760099999999999 0.101487 0.429166 0.042859 0.103849 0.437105 0.0524073 0.0366001 0.261885 0.0505071 0.0390901 0.261267 0.0468142 0.0438315 0.261787 0.046548 0.044242 0.260614 0.0468142 0.0438315 0.261787 0.0505071 0.0390901 0.261267 0.046548 0.044242 0.260614 0.0505071 0.0390901 0.261267 0.054502 0.033966 0.260614 0.0414112 0.076998 0.295 0.0476527 0.07513789999999999 0.295 0.04813 0.068846 0.26181 0.0476527 0.07513789999999999 0.295 0.049063 0.07511370000000001 0.295 0.04813 0.068846 0.26181 0.0414112 0.076998 0.295 0.04813 0.068846 0.26181 0.0413382 0.067909 0.261692 0.046548 0.044242 0.260614 0.0413358 0.0487156 0.260603 0.0439287 0.0464637 0.261198 0.0462087 0.04448 0.261776 0.046548 0.044242 0.260614 0.0439287 0.0464637 0.261198 0.0439287 0.0464637 0.261198 0.0413358 0.0487156 0.260603 0.0413382 0.0486648 0.261692 0.0462087 0.04448 0.261776 0.0439287 0.0464637 0.261198 0.0413382 0.0486648 0.261692 0.0462087 0.04448 0.261776 0.0413382 0.0486648 0.261692 0.0447341 0.056663 0.261751 0.0447341 0.056663 0.261751 0.0413382 0.0486648 0.261692 0.0413382 0.067909 0.261692 0.0462087 0.04448 0.261776 0.0447341 0.056663 0.261751 0.04813 0.068846 0.26181 0.0413366 0.0595159 0.260959 0.0413382 0.0486648 0.261692 0.0413358 0.0487156 0.260603 0.041335 0.070367 0.260227 0.0414112 0.076998 0.295 0.0413382 0.067909 0.261692 0.0413366 0.0595159 0.260959 0.041335 0.070367 0.260227 0.0413382 0.067909 0.261692 0.0413358 0.0487156 0.260603 0.041335 0.070367 0.260227 0.0413366 0.0595159 0.260959 0.041335 0.070367 0.260227 0.0413358 0.0487156 0.260603 0.041335 0.0486991 0.260227 0.041335 0.0486991 0.260227 0.0367757 0.052617 0.260317 0.041335 0.070367 0.260227 0.0288275 0.0767767 0.295 0.041335 0.070367 0.260227 -0.010356 0.0760875 0.295 -0.009366879999999999 0.07095220000000001 0.267974 -0.010356 0.0760875 0.295 0.041335 0.070367 0.260227 0.0462087 0.04448 0.261776 0.0465184 0.0442139 0.261782 0.046548 0.044242 0.260614 0.0367757 0.052617 0.260317 0.0366821 0.0526975 0.260318 0.041335 0.070367 0.260227 0.0447341 0.056663 0.261751 0.0413382 0.067909 0.261692 0.04813 0.068846 0.26181 -0.0253133 0.0589824 0.261536 -0.0249537 0.0590955 0.261529 -0.025326 0.059012 0.260614 -0.0445888 -0.0461032 0.261283 -0.046547 -0.044242 0.260614 -0.042663 -0.047998 0.260614 -0.0427895 -0.0478143 0.261879 -0.0445888 -0.0461032 0.261283 -0.042663 -0.047998 0.260614 -0.046547 -0.044242 0.260614 -0.0465132 -0.0442098 0.261952 -0.0468523 -0.0437713 0.261959 -0.0465132 -0.0442098 0.261952 -0.094407 -0.06848799999999999 0.262893 -0.0468523 -0.0437713 0.261959 -0.0465132 -0.0442098 0.261952 -0.0445888 -0.0461032 0.261283 -0.0427895 -0.0478143 0.261879 -0.094407 -0.06848799999999999 0.262893 -0.0465132 -0.0442098 0.261952 -0.0427895 -0.0478143 0.261879 -0.0465132 -0.0442098 0.261952 -0.046547 -0.044242 0.260614 -0.0445888 -0.0461032 0.261283 0.07914640000000001 0.0437199 0.48672 0.0795347 0.0438082 0.486501 0.07954070000000001 0.0439365 0.486183 0.07914640000000001 0.0437199 0.48672 0.07954070000000001 0.0439365 0.486183 0.0791535 0.044193 0.485546 -1.24524e-08 0.0642022 0.261039 -0.0126472 0.06290800000000001 0.261287 -0.094407 0.06848799999999999 0.262893 0.075193 -0.013573 0.376886 0.07436810000000001 0 0.374716 0.077801 -0.021838 0.381959 0.059001 0.035831 0.364784 0.066029 0.022513 0.33935 0.059001 0.039449 0.354901 0.066029 0.022513 0.33935 0.059001 0.035831 0.364784 0.061536 0.028942 0.363699 0.063235 0.022982 0.362966 0.061536 0.028942 0.363699 0.06760099999999999 0.063149 0.371934 0.061536 0.028942 0.363699 0.063235 0.022982 0.362966 0.066029 0.022513 0.33935 0.066029 0.022513 0.33935 0.063235 0.022982 0.362966 0.06420099999999999 0.01856 0.362567 0.061536 0.028942 0.363699 0.059001 0.035831 0.364784 0.06760099999999999 0.063149 0.371934 0.06760099999999999 0.024057 0.363637 0.063235 0.022982 0.362966 0.06760099999999999 0.063149 0.371934 0.06420099999999999 0.01856 0.362567 0.063235 0.022982 0.362966 0.06760099999999999 0.024057 0.363637 0.06760099999999999 0.063149 0.371934 0.059001 0.035831 0.364784 0.059001 0.063197 0.371791 0.06760099999999999 0.063149 0.371934 0.059001 0.063197 0.371791 0.06760099999999999 0.07270600000000001 0.376436 0.059001 -0.039449 0.354901 0.059001 -0.035831 0.364784 0.059001 -0.063197 0.371791 0.059001 -0.039449 0.354901 0.066029 -0.022513 0.33935 0.059001 -0.035831 0.364784 0.06750399999999999 -0.025653 0.313794 0.066029 -0.022513 0.33935 0.059001 -0.044068 0.339895 0.059001 -0.044068 0.339895 0.066029 -0.022513 0.33935 0.059001 -0.042695 0.344901 0.066029 -0.022513 0.33935 0.059001 -0.039449 0.354901 0.059001 -0.042695 0.344901 0.066029 -0.022513 0.33935 0.06750399999999999 -0.025653 0.313794 0.0710831 8.27181e-26 0.31324 0.059001 -0.042695 0.344901 0.059001 -0.063197 0.371791 0.059001 -0.044068 0.339895 0.059001 -0.039449 0.354901 0.059001 -0.063197 0.371791 0.059001 -0.042695 0.344901 0.059001 -0.044068 0.339895 0.059001 -0.046861 0.329708 0.06750399999999999 -0.025653 0.313794 0.059001 -0.050173 0.314333 0.059001 -0.046861 0.329708 0.059001 -0.063197 0.371791 0.06750399999999999 -0.025653 0.313794 0.059001 -0.046861 0.329708 0.059001 -0.050173 0.314333 0.059001 -0.063197 0.371791 0.059001 -0.046861 0.329708 0.059001 -0.044068 0.339895 0.068569 -0.0276 0.28798 0.06750399999999999 -0.025653 0.313794 0.059001 -0.050173 0.314333 0.059 -0.05423 0.283061 0.059 -0.053697 0.288311 0.059 -0.06869500000000001 0.262 0.059 -0.06869500000000001 0.262 0.059 -0.053697 0.288311 0.059001 -0.052636 0.298752 0.059 -0.053697 0.288311 0.068569 -0.0276 0.28798 0.059001 -0.052636 0.298752 0.059 -0.06869500000000001 0.262 0.059001 -0.052636 0.298752 0.059001 -0.072436 0.375943 0.059001 -0.052636 0.298752 0.068569 -0.0276 0.28798 0.059001 -0.050173 0.314333 0.068569 -0.0276 0.28798 0.07230109999999999 0 0.287641 0.06750399999999999 -0.025653 0.313794 0.0723015 0 0.287632 0.07230109999999999 0 0.287641 0.068569 -0.0276 0.28798 0.07144200000000001 -0.017107 0.262217 0.0723015 0 0.287632 0.068569 -0.0276 0.28798 0.059 -0.05423 0.283061 0.068569 -0.0276 0.28798 0.059 -0.053697 0.288311 0.068569 -0.0276 0.28798 0.059 -0.05423 0.283061 0.059 -0.054807 0.272546 0.059001 -0.089419 0.377466 0.059 -0.06869500000000001 0.262 0.059001 -0.072436 0.375943 0.068949 -0.028271 0.262174 0.07144200000000001 -0.017107 0.262217 0.068569 -0.0276 0.28798 0.06376179999999999 -0.0304138 0.262083 0.0603244 -0.0217207 0.262023 0.0617553 -0.0161906 0.262048 0.0618289 -0.0160036 0.261346 0.0617553 -0.0161906 0.262048 0.0603244 -0.0217207 0.262023 0.060225 -0.0223 0.260614 0.0601789 -0.0222829 0.262021 0.0598206 -0.0230138 0.262014 0.060225 -0.0223 0.260614 0.0603244 -0.0217207 0.262023 0.0601789 -0.0222829 0.262021 0.060225 -0.0223 0.260614 0.0618289 -0.0160036 0.261346 0.0603244 -0.0217207 0.262023 0.06376179999999999 -0.0304138 0.262083 0.0598206 -0.0230138 0.262014 0.0601789 -0.0222829 0.262021 0.060225 -0.0223 0.260614 0.0598206 -0.0230138 0.262014 0.059134 -0.0244145 0.262002 0.063869 -0.044637 0.262085 0.059134 -0.0244145 0.262002 0.0598206 -0.0230138 0.262014 0.059 -0.054995 0.262 0.0547011 -0.0334568 0.261925 0.0550112 -0.0328241 0.26193 0.054502 -0.033966 0.260614 0.0550112 -0.0328241 0.26193 0.0547011 -0.0334568 0.261925 0.054502 -0.033966 0.260614 0.0547011 -0.0334568 0.261925 0.0544633 -0.0339419 0.261921 0.054502 -0.033966 0.260614 0.0550862 -0.0326713 0.261932 0.0550112 -0.0328241 0.26193 0.0573416 -0.0281222 0.261317 0.0587619 -0.0251734 0.261996 0.0560778 -0.0306485 0.261949 0.0573416 -0.0281222 0.261317 0.0560778 -0.0306485 0.261949 0.054502 -0.033966 0.260614 0.060225 -0.0223 0.260614 0.0573416 -0.0281222 0.261317 0.054502 -0.033966 0.260614 0.0560778 -0.0306485 0.261949 0.0550862 -0.0326713 0.261932 0.054502 -0.033966 0.260614 0.0599734 -0.0400842 0.262017 0.0560778 -0.0306485 0.261949 0.0587619 -0.0251734 0.261996 0.059 -0.054995 0.262 0.0560778 -0.0306485 0.261949 0.0599734 -0.0400842 0.262017 0.060225 -0.0223 0.260614 0.0587619 -0.0251734 0.261996 0.0573416 -0.0281222 0.261317 0.060225 -0.0223 0.260614 0.059134 -0.0244145 0.262002 0.0587619 -0.0251734 0.261996 0.063869 -0.044637 0.262085 0.0599734 -0.0400842 0.262017 0.0587619 -0.0251734 0.261996 0.059 -0.054995 0.262 0.0550862 -0.0326713 0.261932 0.0560778 -0.0306485 0.261949 0.063869 -0.044637 0.262085 0.0598206 -0.0230138 0.262014 0.06376179999999999 -0.0304138 0.262083 0.068569 -0.0276 0.28798 0.067703 -0.033854 0.262152 0.068949 -0.028271 0.262174 0.063869 -0.044637 0.262085 0.067703 -0.033854 0.262152 0.068569 -0.0276 0.28798 0.063869 -0.044637 0.262085 0.068569 -0.0276 0.28798 0.059 -0.054995 0.262 0.063869 -0.044637 0.262085 0.06376179999999999 -0.0304138 0.262083 0.067703 -0.033854 0.262152 0.072702 0.082625 0.415539 0.06760099999999999 0.07270600000000001 0.376436 0.06760099999999999 0.07764500000000001 0.379589 0.072702 0.082625 0.415539 0.072702 0.062892 0.38464 0.06760099999999999 0.07270600000000001 0.376436 0.06760099999999999 0.07764500000000001 0.379589 0.06760099999999999 0.07270600000000001 0.376436 0.059001 0.072436 0.375943 0.0697535 0.036353 0.37337 0.06760099999999999 0.07270600000000001 0.376436 0.072702 0.062892 0.38464 0.06760099999999999 0.07270600000000001 0.376436 0.059001 0.063197 0.371791 0.059001 0.072436 0.375943 0.059001 0.072436 0.375943 0.059001 0.063197 0.371791 0.059001 0.052636 0.298752 0.07230109999999999 0 0.287641 0.068569 0.0276 0.28798 0.06750399999999999 0.025653 0.313794 0.068569 0.0276 0.28798 0.059001 0.050173 0.314333 0.06750399999999999 0.025653 0.313794 0.059001 0.052636 0.298752 0.068569 0.0276 0.28798 0.059 0.053697 0.288311 0.068569 0.0276 0.28798 0.059001 0.052636 0.298752 0.059001 0.050173 0.314333 0.059001 0.063197 0.371791 0.059001 0.050173 0.314333 0.059001 0.052636 0.298752 0.0697535 0.036353 0.37337 0.072702 0.062892 0.38464 0.0676012 0 0.361701 0.072702 0.027146 0.373149 0.075193 0.013573 0.376886 0.072702 0 0.371747 0.075193 0.013573 0.376886 0.07436810000000001 0 0.374716 0.072702 0 0.371747 0.075193 0.013573 0.376886 0.077801 0.021838 0.381959 0.07436810000000001 0 0.374716 0.072702 0 0.371747 0.07436810000000001 0 0.374716 0.075193 -0.013573 0.376886 0.072702 0 0.371747 0.075193 -0.013573 0.376886 0.072702 -0.027146 0.373149 0.072702 0.027146 0.373149 0.077801 0.021838 0.381959 0.075193 0.013573 0.376886 0.0676012 0 0.361701 0.072702 0 0.371747 0.072702 -0.027146 0.373149 0.077801 0.021838 0.381959 0.072702 0.027146 0.373149 0.077801 0.051714 0.39227 0.072702 0.062892 0.38464 0.077801 0.051714 0.39227 0.072702 0.027146 0.373149 0.072702 0.062892 0.38464 0.072702 0.027146 0.373149 0.0676012 0 0.361701 0.072702 0.062892 0.38464 0.072702 0.082625 0.415539 0.077801 0.068165 0.419658 0.059 0.05423 0.283061 0.059 0.053697 0.288311 0.068569 0.0276 0.28798 0.054502 0.033966 0.260614 0.0550862 0.0326713 0.261932 0.0560778 0.0306485 0.261949 0.054502 0.033966 0.260614 0.0550112 0.0328241 0.26193 0.0550862 0.0326713 0.261932 0.054502 0.033966 0.260614 0.0547011 0.0334568 0.261925 0.0550112 0.0328241 0.26193 0.054502 0.033966 0.260614 0.0544633 0.0339419 0.261921 0.0547011 0.0334568 0.261925 0.0550112 0.0328241 0.26193 0.0547011 0.0334568 0.261925 0.059 0.054995 0.262 0.059 0.054995 0.262 0.0550862 0.0326713 0.261932 0.0550112 0.0328241 0.26193 0.0560778 0.0306485 0.261949 0.0550862 0.0326713 0.261932 0.059 0.054995 0.262 0.063482 0.009719999999999999 0.260614 0.06378540000000001 0.0032297 0.261351 0.0639748 0 0.260614 0.063482 0.009719999999999999 0.260614 0.063462 0.00910969 0.262078 0.06378540000000001 0.0032297 0.261351 0.063482 0.009719999999999999 0.260614 0.0634315 0.00971226 0.262078 0.063462 0.00910969 0.262078 0.063482 0.009719999999999999 0.260614 0.0631977 0.0106159 0.262073 0.0634315 0.00971226 0.262078 0.0673198 -0.0135692 0.262145 0.0634315 -0.00971226 0.262078 0.063462 -0.00910969 0.262078 0.0673198 -0.0135692 0.262145 0.063462 -0.00910969 0.262078 0.0642383 0 0.262091 0.0631977 -0.0106159 0.262073 0.0634315 -0.00971226 0.262078 0.0673198 -0.0135692 0.262145 0.063482 -0.009719999999999999 0.260614 0.0634315 -0.00971226 0.262078 0.0631977 -0.0106159 0.262073 0.06560199999999999 -0.0225688 0.262115 0.06302489999999999 -0.0112835 0.26207 0.068949 -0.028271 0.262174 0.068949 -0.028271 0.262174 0.06302489999999999 -0.0112835 0.26207 0.0631977 -0.0106159 0.262073 0.063482 -0.009719999999999999 0.260614 0.0631977 -0.0106159 0.262073 0.06302489999999999 -0.0112835 0.26207 0.063482 -0.009719999999999999 0.260614 0.06302489999999999 -0.0112835 0.26207 0.0622549 -0.0142596 0.262057 0.063482 -0.009719999999999999 0.260614 0.0622549 -0.0142596 0.262057 0.0618289 -0.0160036 0.261346 0.063482 -0.009719999999999999 0.260614 0.063462 -0.00910969 0.262078 0.0634315 -0.00971226 0.262078 0.063462 -0.00910969 0.262078 0.0639236 0 0.262086 0.0642383 0 0.262091 0.06393020000000001 0 0.261896 0.0639236 0 0.262086 0.06378540000000001 -0.0032297 0.261351 0.0639619 0 0.260984 0.06393020000000001 0 0.261896 0.06378540000000001 -0.0032297 0.261351 0.063462 -0.00910969 0.262078 0.06378540000000001 -0.0032297 0.261351 0.0639236 0 0.262086 0.0727006 0 0.262239 0.0646515 0 0.262098 0.07144200000000001 0.017107 0.262217 0.07144200000000001 -0.017107 0.262217 0.0646515 0 0.262098 0.0727006 0 0.262239 0.07144200000000001 -0.017107 0.262217 0.0644443 0 0.262095 0.0646515 0 0.262098 0.0723015 0 0.287632 0.0727006 0 0.262239 0.07144200000000001 0.017107 0.262217 0.07144200000000001 -0.017107 0.262217 0.0673198 -0.0135692 0.262145 0.0644443 0 0.262095 0.068569 0.0276 0.28798 0.0723015 0 0.287632 0.07144200000000001 0.017107 0.262217 0.068949 -0.028271 0.262174 0.0673198 -0.0135692 0.262145 0.07144200000000001 -0.017107 0.262217 0.0646515 0 0.262098 0.0644443 0 0.262095 0.07144200000000001 0.017107 0.262217 0.0642383 0 0.262091 0.0639236 0 0.262086 0.063462 0.00910969 0.262078 0.0642383 0 0.262091 0.063462 0.00910969 0.262078 0.0673198 0.0135692 0.262145 0.0639236 0 0.262086 0.06378540000000001 0.0032297 0.261351 0.063462 0.00910969 0.262078 0.0644443 0 0.262095 0.0642383 0 0.262091 0.0673198 0.0135692 0.262145 0.0644443 0 0.262095 0.0673198 0.0135692 0.262145 0.07144200000000001 0.017107 0.262217 0.07144200000000001 0.017107 0.262217 0.0673198 0.0135692 0.262145 0.068949 0.028271 0.262174 0.0639619 0 0.260984 0.06378540000000001 0.0032297 0.261351 0.06393020000000001 0 0.261896 0.0673198 -0.0135692 0.262145 0.0642383 0 0.262091 0.0644443 0 0.262095 0.063482 -0.009719999999999999 0.260614 0.06378540000000001 -0.0032297 0.261351 0.063462 -0.00910969 0.262078 0.0639748 0 0.260614 0.06378540000000001 -0.0032297 0.261351 0.063482 -0.009719999999999999 0.260614 0.0587619 0.0251734 0.261996 0.0573416 0.0281222 0.261317 0.0560778 0.0306485 0.261949 0.0573416 0.0281222 0.261317 0.0587619 0.0251734 0.261996 0.060225 0.0223 0.260614 0.0587619 0.0251734 0.261996 0.059134 0.0244145 0.262002 0.060225 0.0223 0.260614 0.059134 0.0244145 0.262002 0.0587619 0.0251734 0.261996 0.063869 0.044637 0.262085 0.0601789 0.0222829 0.262021 0.0598206 0.0230138 0.262014 0.06376179999999999 0.0304138 0.262083 0.06376179999999999 0.0304138 0.262083 0.0598206 0.0230138 0.262014 0.063869 0.044637 0.262085 0.067703 0.033854 0.262152 0.06376179999999999 0.0304138 0.262083 0.063869 0.044637 0.262085 0.068569 0.0276 0.28798 0.067703 0.033854 0.262152 0.063869 0.044637 0.262085 0.063869 0.044637 0.262085 0.0599734 0.0400842 0.262017 0.059 0.054995 0.262 0.0599734 0.0400842 0.262017 0.0560778 0.0306485 0.261949 0.059 0.054995 0.262 0.063869 0.044637 0.262085 0.059 0.054995 0.262 0.068569 0.0276 0.28798 0.059 0.054807 0.272546 0.068569 0.0276 0.28798 0.059 0.054995 0.262 0.059 0.05423 0.283061 0.068569 0.0276 0.28798 0.059 0.054807 0.272546 0.068569 0.0276 0.28798 0.068949 0.028271 0.262174 0.067703 0.033854 0.262152 0.0598206 0.0230138 0.262014 0.059134 0.0244145 0.262002 0.063869 0.044637 0.262085 0.059 0.05423 0.283061 0.059 0.054807 0.272546 0.059 0.06869500000000001 0.262 0.054502 0.033966 0.260614 0.0573416 0.0281222 0.261317 0.060225 0.0223 0.260614 0.0587619 0.0251734 0.261996 0.0599734 0.0400842 0.262017 0.063869 0.044637 0.262085 0.07144200000000001 0.017107 0.262217 0.068949 0.028271 0.262174 0.068569 0.0276 0.28798 0.0673198 0.0135692 0.262145 0.0631977 0.0106159 0.262073 0.068949 0.028271 0.262174 0.063462 0.00910969 0.262078 0.0634315 0.00971226 0.262078 0.0673198 0.0135692 0.262145 0.06760099999999999 0.07270600000000001 0.376436 0.0676012 0 0.361701 0.06760099999999999 0.063149 0.371934 0.063869 -0.044637 0.262085 0.0587619 -0.0251734 0.261996 0.059134 -0.0244145 0.262002 0.068569 -0.0276 0.28798 0.059 -0.054807 0.272546 0.059 -0.054995 0.262 0.0791535 0.044193 0.485546 0.0784329 0.0567469 0.499244 0.07914640000000001 0.0437199 0.48672 0.0723015 0 0.287632 0.068569 0.0276 0.28798 0.07230109999999999 0 0.287641 -0.061307 0.07716339999999999 0.302779 -0.0766416 0.0728245 0.282836 -0.094357 0.073585 0.286235 0.072714 0.010359 0.538295 0.072714 0 0.5381590000000001 0.07416590000000001 0 0.53572 0.07416590000000001 0 0.53572 0.07780040000000001 0 0.53 0.072714 0.010359 0.538295 -0.04514 0.08576499999999999 0.264004 -0.047857 0.091569 0.292472 -0.04514 0.09327100000000001 0.292016 0.0791458 0.04368 0.486819 0.07953440000000001 0.042913 0.487942 0.07992299999999999 0.04368 0.486819 0.0557236 -1.03398e-25 0.545817 0.0419608 0 0.546081 0.0547809 -0.0153353 0.546147 0.0547011 0.0334568 0.261925 0.0544633 0.0339419 0.261921 0.059 0.054995 0.262 0.0544633 0.0339419 0.261921 0.0536743 0.034962 0.261907 0.059 0.054995 0.262 0.059001 0.046861 0.329708 0.06750399999999999 0.025653 0.313794 0.059001 0.050173 0.314333 0.059001 0.063197 0.371791 0.059001 0.039449 0.354901 0.059001 0.042695 0.344901 0.059001 0.063197 0.371791 0.059001 0.042695 0.344901 0.059001 0.044068 0.339895 0.059001 0.042695 0.344901 0.066029 0.022513 0.33935 0.059001 0.044068 0.339895 0.059001 0.044068 0.339895 0.066029 0.022513 0.33935 0.06750399999999999 0.025653 0.313794 0.06750399999999999 0.025653 0.313794 0.059001 0.046861 0.329708 0.059001 0.044068 0.339895 0.07993500000000001 0.044193 0.485546 0.07992299999999999 0.04368 0.486819 0.080757 0.044301 0.482372 0.0557236 -1.03398e-25 0.545817 0.0547809 0.0153353 0.546147 0.0419608 0 0.546081 0.06760099999999999 0.030676 0.5462129999999999 0.0547809 0.0153353 0.546147 0.0557236 -1.03398e-25 0.545817 -0.0618244 0.0160027 0.261449 -0.0634233 0.00971116 0.262284 -0.0603376 0.0216382 0.262224 -0.054501 -0.033966 0.260614 -0.0564385 -0.0298955 0.262147 -0.0573374 -0.0281207 0.261417 -0.054501 -0.033966 0.260614 -0.0573374 -0.0281207 0.261417 -0.060224 -0.0223 0.260614 -0.054501 -0.033966 0.260614 -0.0544567 -0.0339384 0.262108 -0.0547288 -0.0333834 0.262114 -0.0544567 -0.0339384 0.262108 -0.094407 -0.06848799999999999 0.262893 -0.0547288 -0.0333834 0.262114 -0.0547288 -0.0333834 0.262114 -0.094407 -0.06848799999999999 0.262893 -0.0564385 -0.0298955 0.262147 -0.0564385 -0.0298955 0.262147 -0.094407 -0.06848799999999999 0.262893 -0.0601714 -0.0222805 0.262221 -0.0505035 -0.0390881 0.261361 -0.0544567 -0.0339384 0.262108 -0.054501 -0.033966 0.260614 -0.0505035 -0.0390881 0.261361 -0.0468523 -0.0437713 0.261959 -0.0544567 -0.0339384 0.262108 -0.0601714 -0.0222805 0.262221 -0.094407 -0.06848799999999999 0.262893 -0.0603376 -0.0216382 0.262224 -0.060224 -0.0223 0.260614 -0.0601714 -0.0222805 0.262221 -0.0603376 -0.0216382 0.262224 -0.060224 -0.0223 0.260614 -0.0603376 -0.0216382 0.262224 -0.0618244 -0.0160027 0.261449 -0.060224 -0.0223 0.260614 -0.0618244 -0.0160027 0.261449 -0.063481 -0.009719999999999999 0.260614 -0.063481 -0.009719999999999999 0.260614 -0.0618244 -0.0160027 0.261449 -0.0634233 -0.00971116 0.262284 -0.0603376 -0.0216382 0.262224 -0.094407 -0.06848799999999999 0.262893 -0.0634233 -0.00971116 0.262284 -0.0634233 -0.00971116 0.262284 -0.094407 -0.06848799999999999 0.262893 -0.06345820000000001 -0.009023339999999999 0.262285 -0.06345820000000001 -0.009023339999999999 0.262285 -0.094407 -0.06848799999999999 0.262893 -0.06545620000000001 0 0.262324 -0.094407 -0.06848799999999999 0.262893 -0.094407 0 0.262893 -0.06545620000000001 0 0.262324 -0.06345820000000001 -0.009023339999999999 0.262285 -0.06545620000000001 0 0.262324 -0.0639154 0 0.262294 -0.0639154 0 0.262294 -0.06545620000000001 0 0.262324 -0.06345820000000001 0.009023339999999999 0.262285 -0.06345820000000001 0.009023339999999999 0.262285 -0.06545620000000001 0 0.262324 -0.094407 0.06848799999999999 0.262893 -0.0639154 0 0.262294 -0.0637808 -0.00322952 0.261456 -0.06345820000000001 -0.009023339999999999 0.262285 -0.0573374 -0.0281207 0.261417 -0.0601714 -0.0222805 0.262221 -0.060224 -0.0223 0.260614 -0.0634233 0.00971116 0.262284 -0.06345820000000001 0.009023339999999999 0.262285 -0.094407 0.06848799999999999 0.262893 -0.0603376 0.0216382 0.262224 -0.0634233 0.00971116 0.262284 -0.094407 0.06848799999999999 0.262893 -0.0618244 -0.0160027 0.261449 -0.0603376 -0.0216382 0.262224 -0.0634233 -0.00971116 0.262284 -0.0547288 -0.0333834 0.262114 -0.0564385 -0.0298955 0.262147 -0.054501 -0.033966 0.260614 -0.06393 0 0.261875 -0.0637808 -0.00322952 0.261456 -0.0639154 0 0.262294 -0.06393 0 0.261875 -0.0639154 0 0.262294 -0.0637808 0.00322952 0.261456 -0.0639591 0 0.261037 -0.06393 0 0.261875 -0.0637808 0.00322952 0.261456 -0.0639738 0 0.260614 -0.0639591 0 0.261037 -0.0637808 0.00322952 0.261456 -0.0639738 0 0.260614 -0.0637808 0.00322952 0.261456 -0.063481 0.009719999999999999 0.260614 -0.0639591 0 0.261037 -0.0637808 -0.00322952 0.261456 -0.06393 0 0.261875 -0.0637808 0.00322952 0.261456 -0.06345820000000001 0.009023339999999999 0.262285 -0.063481 0.009719999999999999 0.260614 -0.06345820000000001 0.009023339999999999 0.262285 -0.0637808 0.00322952 0.261456 -0.0639154 0 0.262294 -0.06545620000000001 0 0.262324 -0.094407 0 0.262893 -0.094407 0.06848799999999999 0.262893 -0.046547 -0.044242 0.260614 -0.0505035 -0.0390881 0.261361 -0.054501 -0.033966 0.260614 0.045693 -0.089558 0.376733 0.044958 -0.088741 0.370332 0.059001 -0.089419 0.377466 0.045693 -0.089558 0.376733 0.059001 -0.089419 0.377466 0.059001 -0.091573 0.395704 0.059001 -0.08577799999999999 0.387139 0.059001 -0.091573 0.395704 0.059001 -0.089419 0.377466 -0.0582031 0.0830306 0.334 -0.026335 0.087259 0.355483 -0.0394457 0.0833752 0.334 -0.0582031 0.0830306 0.334 -0.0585424 0.0830288 0.334 -0.026335 0.087259 0.355483 -0.094357 0.073585 0.286235 -0.077832 0.07620440000000001 0.298528 -0.061307 0.0776017 0.305225 -0.094357 0.073585 0.286235 -0.09434099999999999 0.075279 0.293992 -0.077832 0.07620440000000001 0.298528 0.077801 0.075124 0.452 0.08129 0 0.456649 0.0812885 0 0.456498 0.026005 0.091485 0.262471 0.019285 0.086037 0.263931 -0.032312 0.126674 0.253043 0.068949 -0.028271 0.262174 0.067703 -0.033854 0.262152 0.06560199999999999 -0.0225688 0.262115 0.067703 -0.033854 0.262152 0.0622549 -0.0142596 0.262057 0.06560199999999999 -0.0225688 0.262115 0.067703 -0.033854 0.262152 0.0620911 -0.0148927 0.262054 0.0622549 -0.0142596 0.262057 0.059 -0.05423 0.283061 0.059 -0.06869500000000001 0.262 0.059 -0.054807 0.272546 0.0791535 -0.044193 0.485546 0.07954070000000001 -0.0439365 0.486183 0.07914640000000001 -0.0437199 0.48672 -0.0167591 0.147553 0.262769 -0.014805 0.152445 0.27616 -0.014805 0.144939 0.248148 0.08107200000000001 0.044301 0.479023 0.080757 0.044301 0.482372 0.083161 0.040197 0.479069 0.07780040000000001 0 0.53 0.0794768 0.010862 0.4935 0.07856929999999999 0.015532 0.511746 0.07780040000000001 0 0.53 0.07856929999999999 0.015532 0.511746 0.0784712 0.031064 0.511558 0.07780040000000001 0 0.53 0.0784712 0.031064 0.511558 0.077801 0.062128 0.521061 0.045693 -0.089558 0.376733 0.059001 -0.091573 0.395704 0.045859 -0.090318 0.382877 0.06760099999999999 0.095751 0.529524 0.06439250000000001 0.0883568 0.534794 0.06760099999999999 0.080802 0.539832 0.07856929999999999 0.015532 0.511746 0.0794768 0.010862 0.4935 0.0784712 0.031064 0.511558 -0.00341801 0.076742 0.266422 -0.035427 0.098872 0.260492 -0.034165 0.10694 0.25833 0.06439250000000001 -0.0883568 0.534794 0.061184 -0.088437 0.534911 0.06760099999999999 -0.095751 0.529524 0.06439250000000001 -0.0883568 0.534794 0.06760099999999999 -0.080802 0.539832 0.061184 -0.088437 0.534911 0.06760099999999999 -0.080802 0.539832 0.06439250000000001 -0.0883568 0.534794 0.06760099999999999 -0.095751 0.529524 0.0622549 -0.0142596 0.262057 0.0620911 -0.0148927 0.262054 0.0618289 -0.0160036 0.261346 0.0525 -0.08237899999999999 0.332874 0.059 -0.06869500000000001 0.262 0.0525 -0.082581 0.334 0.059 -0.06869500000000001 0.262 0.0525 -0.08237899999999999 0.332874 0.0525 -0.0759871 0.297262 0.07993500000000001 0.044193 0.485546 0.0795443 0.0440647 0.485864 0.0795443 0.0441289 0.485705 0.07993500000000001 0.044193 0.485546 0.0791535 0.044193 0.485546 0.0795443 0.0441289 0.485705 0.0795443 0.0440647 0.485864 0.0795443 0.0441289 0.485705 0.0791535 0.044193 0.485546 0.0812914 0 0.457002 0.0812833 0 0.457399 0.08089490000000001 -0.00692969 0.4645 -0.061307 -0.0788237 0.31082 -0.09434099999999999 -0.075279 0.293992 -0.077832 -0.07620440000000001 0.298528 0.0525 0.08237899999999999 0.332874 0.059 0.06869500000000001 0.262 0.0525 0.0759871 0.297262 0.059 0.06869500000000001 0.262 0.0525 0.075751 0.296349 0.0525 0.0759871 0.297262 0.0525 0.0754018 0.295 0.0525 0.075751 0.296349 0.059 0.06869500000000001 0.262 0.059 0.06869500000000001 0.262 0.0513403 0.0750745 0.295 0.0525 0.0754018 0.295 0.049063 0.07511370000000001 0.295 0.0513403 0.0750745 0.295 0.059 0.06869500000000001 0.262 0.0525 0.082581 0.334 0.059 0.06869500000000001 0.262 0.0525 0.08237899999999999 0.332874 0.081124 0.016307 0.4645 0.08400680000000001 0 0.471638 0.08126800000000001 0 0.4645 0.083979 0.027179 0.471577 0.08400680000000001 0 0.471638 0.0825649 0.0135895 0.468069 0.0825649 0.0135895 0.468069 0.081124 0.016307 0.4645 0.083979 0.027179 0.471577 0.081124 0.016307 0.4645 0.0825649 0.0135895 0.468069 0.08400680000000001 0 0.471638 0.0525 -0.075751 0.296349 0.0525 -0.0754018 0.295 0.059 -0.06869500000000001 0.262 0.059 -0.06869500000000001 0.262 0.0525 -0.0754018 0.295 0.0513403 -0.0750745 0.295 0.054502 -0.033966 0.260614 0.0536743 -0.034962 0.261907 0.0524073 -0.0366001 0.261885 0.054502 -0.033966 0.260614 0.0524073 -0.0366001 0.261885 0.0505071 -0.0390901 0.261267 0.0447341 -0.056663 0.261751 0.0413382 -0.067909 0.261692 0.0413382 -0.0486648 0.261692 0.04813 -0.068846 0.26181 0.0413382 -0.067909 0.261692 0.0447341 -0.056663 0.261751 0.0526043 -0.0527231 0.261888 0.0465184 -0.0442139 0.261782 0.0468142 -0.0438315 0.261787 0.0526043 -0.0527231 0.261888 0.0468142 -0.0438315 0.261787 0.0524073 -0.0366001 0.261885 0.0505071 -0.0390901 0.261267 0.0524073 -0.0366001 0.261885 0.0468142 -0.0438315 0.261787 0.0505071 -0.0390901 0.261267 0.0468142 -0.0438315 0.261787 0.046548 -0.044242 0.260614 0.0526043 -0.0527231 0.261888 0.0462087 -0.04448 0.261776 0.0465184 -0.0442139 0.261782 0.0526043 -0.0527231 0.261888 0.04813 -0.068846 0.26181 0.0462087 -0.04448 0.261776 0.041335 -0.0486991 0.260227 0.046548 -0.044242 0.260614 0.0413358 -0.0487156 0.260603 0.041335 -0.0486991 0.260227 0.0413358 -0.0487156 0.260603 0.041335 -0.070367 0.260227 0.0413366 -0.0595159 0.260959 0.041335 -0.070367 0.260227 0.0413358 -0.0487156 0.260603 0.0439287 -0.0464637 0.261198 0.0413358 -0.0487156 0.260603 0.046548 -0.044242 0.260614 0.0465184 -0.0442139 0.261782 0.0462087 -0.04448 0.261776 0.046548 -0.044242 0.260614 0.0462087 -0.04448 0.261776 0.0439287 -0.0464637 0.261198 0.046548 -0.044242 0.260614 0.0413382 -0.0486648 0.261692 0.0439287 -0.0464637 0.261198 0.0462087 -0.04448 0.261776 0.04813 -0.068846 0.26181 0.0447341 -0.056663 0.261751 0.0462087 -0.04448 0.261776 0.0413358 -0.0487156 0.260603 0.0413382 -0.0486648 0.261692 0.0413366 -0.0595159 0.260959 0.0413382 -0.067909 0.261692 0.041335 -0.070367 0.260227 0.0413366 -0.0595159 0.260959 0.0413382 -0.067909 0.261692 0.04813 -0.068846 0.26181 0.0414112 -0.076998 0.295 0.0413382 -0.067909 0.261692 0.0414112 -0.076998 0.295 0.041335 -0.070367 0.260227 0.046548 -0.044242 0.260614 0.0468142 -0.0438315 0.261787 0.0465184 -0.0442139 0.261782 0.0476527 -0.07513789999999999 0.295 0.0414112 -0.076998 0.295 0.04813 -0.068846 0.26181 0.0476527 -0.07513789999999999 0.295 0.04813 -0.068846 0.26181 0.049063 -0.07511370000000001 0.295 0.059 -0.06869500000000001 0.262 0.049063 -0.07511370000000001 0.295 0.04813 -0.068846 0.26181 0.059 -0.06869500000000001 0.262 0.04813 -0.068846 0.26181 0.0526043 -0.0527231 0.261888 0.0413382 -0.0486648 0.261692 0.0413358 -0.0487156 0.260603 0.0439287 -0.0464637 0.261198 0.0288275 -0.0767767 0.295 0.041335 -0.070367 0.260227 0.0414112 -0.076998 0.295 0.0526043 -0.0527231 0.261888 0.0524073 -0.0366001 0.261885 0.059 -0.06869500000000001 0.262 -0.055224 0.077663 0.266175 -0.050447 0.082413 0.264902 -0.0395053 0.07044789999999999 0.268076 0.054502 -0.033966 0.260614 0.0505071 -0.0390901 0.261267 0.046548 -0.044242 0.260614 -0.060224 0.0223 0.260614 -0.0573374 0.0281207 0.261417 -0.054501 0.033966 0.260614 0.0547809 -0.0153353 0.546147 0.0419608 0 0.546081 0.0483709 -0.0150118 0.546264 0.083608 0.027179 0.486575 0.08355940000000001 0 0.48654 0.08476590000000001 0 0.479119 -0.0129232 -0.0628798 0.261293 -0.0191222 -0.0609423 0.261071 -0.012928 -0.062903 0.260614 0.0418086 0.112526 0.476744 0.06760099999999999 0.112671 0.480468 0.06760099999999999 0.110815 0.470543 0.0547756 0.07666000000000001 0.54158 0.0419503 0.07822079999999999 0.541342 0.0419521 0.07576720000000001 0.542197 -0.0253133 0.0589824 0.261536 -0.0362556 0.0529008 0.261751 -0.094407 0.06848799999999999 0.262893 0.07917159999999999 -0.0452277 0.482853 0.0795828 -0.0453535 0.481872 0.07996 -0.045204 0.483037 -0.022179 0.147853 0.277391 -0.0167591 0.147553 0.262769 -0.014805 0.144939 0.248148 -0.022179 0.147853 0.277391 -0.0201217 0.149134 0.277048 -0.0167591 0.147553 0.262769 0.0639748 0 0.260614 0.06378540000000001 0.0032297 0.261351 0.0639619 0 0.260984 -0.0423955 -0.048153 0.261871 -0.0427895 -0.0478143 0.261879 -0.042663 -0.047998 0.260614 -0.106214 0.075188 0.309795 -0.117537 0.06936199999999999 0.309941 -0.117959 0.074543 0.333388 0.0799289 -0.0397628 0.466877 0.07948379999999999 -0.040006 0.467053 0.0799634 -0.0393835 0.466602 0.08068500000000001 -0.032615 0.4645 0.08024729999999999 -0.032951 0.464543 0.07980959999999999 -0.032732 0.464515 0.07972509999999999 -0.044602 0.473453 0.080167 -0.044149 0.472477 0.080111 -0.045055 0.474428 0.00227099 -0.148207 0.247273 0.0109 -0.146678 0.247682 0.00227099 -0.155713 0.275285 0.080567 -0.035695 0.464894 0.083757 -0.03397 0.471612 0.080443 -0.038625 0.466051 -0.125404 -0.000441 0.263502 -0.125404 0.000441 0.263502 -0.094407 0 0.262893 0.0415602 0.0882602 0.356609 0.059001 0.089419 0.377466 0.0525 0.082581 0.334 -0.0573374 -0.0281207 0.261417 -0.0564385 -0.0298955 0.262147 -0.0601714 -0.0222805 0.262221 -0.077832 0.07620440000000001 0.298528 -0.061307 0.0788237 0.31082 -0.061307 0.0776017 0.305225 -0.0766416 -0.0728245 0.282836 -0.094407 -0.06848799999999999 0.262893 -0.0588761 -0.0736657 0.286773 0.072714 0.010359 0.538295 0.0712801 0 0.540548 0.072714 0 0.5381590000000001 0.0701391 0.0075135 0.542467 0.06885670000000001 0.0075135 0.544556 0.06760099999999999 0 0.546542 0.06760099999999999 0.015027 0.546662 0.06885670000000001 0.0075135 0.544556 0.0701391 0.0075135 0.542467 0.06760099999999999 0.015027 0.546662 0.0701391 0.0075135 0.542467 0.072714 0.010359 0.538295 0.0701391 0.0075135 0.542467 0.06760099999999999 0 0.546542 0.0712801 0 0.540548 0.072714 0.010359 0.538295 0.0701391 0.0075135 0.542467 0.0712801 0 0.540548 0.06760099999999999 0.08465 0.386212 0.072702 0.082625 0.415539 0.06760099999999999 0.07764500000000001 0.379589 0.06760099999999999 0.08465 0.386212 0.06760099999999999 0.07764500000000001 0.379589 0.059001 0.08577799999999999 0.387139 0.063482 0.009719999999999999 0.260614 0.06302489999999999 0.0112835 0.26207 0.0631977 0.0106159 0.262073 0.079911 0.042146 0.489064 0.079914 0.040182 0.490935 0.082288 0.040197 0.485185 0.06760099999999999 0.098633 0.417793 0.072702 0.082625 0.415539 0.06760099999999999 0.097194 0.412299 0.043928 0.100007 0.421527 0.06760099999999999 0.097194 0.412299 0.06760099999999999 0.095661 0.406449 0.06760099999999999 0.095661 0.406449 0.06760099999999999 0.097194 0.412299 0.072702 0.082625 0.415539 0.06760099999999999 0.09418700000000001 0.402331 0.06760099999999999 0.095661 0.406449 0.072702 0.082625 0.415539 0.06760099999999999 0.095661 0.406449 0.06760099999999999 0.09418700000000001 0.402331 0.044994 0.09535100000000001 0.404143 0.044994 0.09535100000000001 0.404143 0.06760099999999999 0.09418700000000001 0.402331 0.06760099999999999 0.092889 0.398706 0.06760099999999999 0.092889 0.398706 0.06760099999999999 0.09418700000000001 0.402331 0.072702 0.082625 0.415539 0.077801 0.051714 0.39227 0.07897800000000001 0.015835 0.395385 0.077801 0.021838 0.381959 0.07996 -0.045204 0.483037 0.080757 -0.044301 0.482372 0.07993500000000001 -0.044193 0.485546 -0.0589446 0.07546219999999999 0.295 -0.058339 0.0790632 0.295 -0.0588761 0.0736657 0.286773 0.041812 0.112814 0.478284 0.0418121 0.112822 0.47833 0.06760099999999999 0.112671 0.480468 0.072702 -0.082625 0.415539 0.06760099999999999 -0.095661 0.406449 0.06760099999999999 -0.09418700000000001 0.402331 0.0792075 0.0455203 0.480572 0.0796132 0.0456125 0.479854 0.0792322 0.045722 0.479 0.07144200000000001 -0.017107 0.262217 0.0727006 0 0.262239 0.0723015 0 0.287632 0.080633 -0.033959 0.464671 0.0801933 -0.033623 0.464628 0.08021929999999999 -0.033287 0.464585 0.07975359999999999 -0.033959 0.464671 0.0801933 -0.033791 0.46465 0.0801933 -0.033623 0.464628 0.0801933 -0.033791 0.46465 0.0801933 -0.033623 0.464628 0.080633 -0.033959 0.464671 0.07975359999999999 -0.033959 0.464671 0.0801933 -0.033791 0.46465 0.080633 -0.033959 0.464671 0.080633 -0.033959 0.464671 0.0797466 -0.0341119 0.464691 0.07975359999999999 -0.033959 0.464671 0.0791535 0.044193 0.485546 0.07954070000000001 0.0439365 0.486183 0.0795443 0.0440647 0.485864 0.0413358 0.0487156 0.260603 0.046548 0.044242 0.260614 0.041335 0.0486991 0.260227 -0.126401 -0.041887 0.286701 -0.124024 -0.05266 0.286688 -0.128571 -0.04743 0.310033 0.079914 -0.040182 0.490935 0.079911 -0.042146 0.489064 0.082288 -0.040197 0.485185 0.080329 -0.041132 0.46787 0.082525 -0.040197 0.472918 0.080232 -0.043105 0.470231 0.07943509999999999 -0.041132 0.46787 0.080329 -0.041132 0.46787 0.07984479999999999 -0.0421185 0.46905 0.07943509999999999 -0.041132 0.46787 0.07984479999999999 -0.0421185 0.46905 0.0793606 -0.0429314 0.470023 0.07943890000000001 -0.0410435 0.467806 0.07943509999999999 -0.041132 0.46787 0.080329 -0.041132 0.46787 0.07943890000000001 -0.0410435 0.467806 0.07943509999999999 -0.041132 0.46787 0.077801 -0.075124 0.452 0.07984479999999999 -0.0421185 0.46905 0.080329 -0.041132 0.46787 0.080232 -0.043105 0.470231 0.083608 0.027179 0.486575 0.08036 0.010862 0.4935 0.08355940000000001 0 0.48654 0.067703 -0.033854 0.262152 0.06376179999999999 -0.0304138 0.262083 0.0617553 -0.0161906 0.262048 -0.0253133 0.0589824 0.261536 -0.025326 0.059012 0.260614 -0.0309974 0.0558417 0.261182 0.059001 0.063197 0.371791 0.059001 0.035831 0.364784 0.059001 0.039449 0.354901 0.041802 0.111884 0.47371 0.0418052 0.112203 0.475196 0.06760099999999999 0.109492 0.4642 0.054502 0.033966 0.260614 0.0560778 0.0306485 0.261949 0.0573416 0.0281222 0.261317 0.0791545 -0.042146 0.489064 0.0791538 -0.0422623 0.488894 0.079911 -0.042146 0.489064 0.0793143 -0.044149 0.472477 0.080167 -0.044149 0.472477 0.07972509999999999 -0.044602 0.473453 0.083979 -0.027179 0.471577 0.08488999999999999 -0.027179 0.479101 0.083757 -0.03397 0.471612 -0.124024 -0.05266 0.286688 -0.121458 -0.058391 0.286654 -0.123512 -0.061676 0.31001 -0.123796 0.036459 0.26347 -0.122964 0.045036 0.263453 -0.094407 0.06848799999999999 0.262893 0.0794768 0.010862 0.4935 0.0798664 0.01902 0.4935 0.0793727 0.0259411 0.4935 0.0803575 -1.35465e-10 0.4935 0.07954559999999999 0.000879971 0.4935 0.0799516 1.0842e-19 0.4935 0.07954559999999999 0.000879971 0.4935 0.07954559999999999 -0.000879971 0.4935 0.0799516 1.0842e-19 0.4935 0.07954559999999999 -0.000879971 0.4935 0.0803575 -1.35465e-10 0.4935 0.0799516 1.0842e-19 0.4935 0.0793727 -0.0259411 0.4935 0.080112 -0.027178 0.4935 0.0798664 -0.01902 0.4935 -0.094407 -0.06848799999999999 0.262893 -0.0587533 -0.07187209999999999 0.277354 -0.0587706 -0.07212399999999999 0.278677 0.059 -0.06869500000000001 0.262 0.0525 -0.0759871 0.297262 0.0525 -0.075751 0.296349 -0.034433 -0.118451 0.255247 0.011373 -0.082374 0.264912 0.019285 -0.086037 0.263931 0.07914640000000001 -0.0437199 0.48672 0.07954070000000001 -0.0439365 0.486183 0.0795347 -0.0438082 0.486501 0.0792803 -0.045055 0.474428 0.080111 -0.045055 0.474428 0.0796762 -0.0453885 0.476714 0.07916869999999999 -0.045204 0.483037 0.07915469999999999 -0.0442721 0.48535 0.0784329 -0.0567469 0.499244 0.080564 0.016307 0.4645 0.0809145 0.008153499999999999 0.4645 0.08089490000000001 0.00692969 0.4645 0.0812914 0 0.457002 0.080564 0.016307 0.4645 0.08089490000000001 0.00692969 0.4645 0.059001 -0.08577799999999999 0.387139 0.06760099999999999 -0.08465 0.386212 0.059001 -0.091573 0.395704 0.06760099999999999 -0.08465 0.386212 0.059001 -0.08577799999999999 0.387139 0.06760099999999999 -0.07764500000000001 0.379589 0.059 0.053697 0.288311 0.059 0.05423 0.283061 0.059 0.06869500000000001 0.262 0.0794779 -0.040142 0.467152 0.07943890000000001 -0.0410435 0.467806 0.077801 -0.075124 0.452 0.031111 -0.09837600000000001 0.260625 0.034283 -0.106278 0.258508 -0.022179 -0.140348 0.249379 0.0793176 -0.0440597 0.472285 0.077801 -0.075124 0.452 0.07935349999999999 -0.043105 0.470231 0.07935349999999999 -0.043105 0.470231 0.077801 -0.075124 0.452 0.0793606 -0.0429314 0.470023 0.059 -0.06869500000000001 0.262 0.0524073 -0.0366001 0.261885 0.0536743 -0.034962 0.261907 0.059 -0.054995 0.262 0.0536743 -0.034962 0.261907 0.0544633 -0.0339419 0.261921 0.0536743 -0.034962 0.261907 0.059 -0.054995 0.262 0.059 -0.06869500000000001 0.262 0.079952 0.036598 0.492841 0.0796557 0.0345965 0.49317 0.080029 0.032595 0.4935 0.06760099999999999 -0.106838 0.452 0.07270799999999999 -0.090958 0.452 0.072714 -0.09668400000000001 0.488844 0.0792831 -0.0449796 0.474266 0.07972509999999999 -0.044602 0.473453 0.080111 -0.045055 0.474428 0.072702 0.082625 0.415539 0.07270799999999999 0.090958 0.452 0.077801 0.075124 0.452 0.0447341 -0.056663 0.261751 0.0413382 -0.0486648 0.261692 0.0462087 -0.04448 0.261776 -0.0366651 0.0526732 0.261759 -0.094407 0.06848799999999999 0.262893 -0.0362556 0.0529008 0.261751 -0.117026 -0.063762 0.286585 -0.120144 -0.052723 0.263398 -0.115974 -0.05809 0.263317 -0.105911 -0.070065 0.286406 -0.106491 -0.06393799999999999 0.26313 -0.094407 -0.06848799999999999 0.262893 -0.105911 -0.070065 0.286406 -0.115974 -0.05809 0.263317 -0.106491 -0.06393799999999999 0.26313 -0.105911 -0.070065 0.286406 -0.117026 -0.063762 0.286585 -0.115974 -0.05809 0.263317 -0.106491 -0.06393799999999999 0.26313 -0.115974 -0.05809 0.263317 -0.094407 -0.06848799999999999 0.262893 0.030872 -0.130949 0.251897 0.0109 -0.146678 0.247682 0.00227099 -0.148207 0.247273 0.08089490000000001 0.00692969 0.4645 0.0809391 0.000523865 0.4645 0.0812833 0 0.457399 0.0418121 -0.112822 0.47833 0.041812 -0.112814 0.478284 0.06760099999999999 -0.112671 0.480468 0.059001 0.089419 0.377466 0.059 0.06869500000000001 0.262 0.0525 0.082581 0.334 0.0710831 8.27181e-26 0.31324 0.06750399999999999 0.025653 0.313794 0.066029 0.022513 0.33935 -0.137444 -0.026815 0.333464 -0.130461 -0.052724 0.33346 -0.135472 -0.04726 0.354722 0.0803575 -1.35465e-10 0.4935 0.08036 0.010862 0.4935 0.0799184 0.005431 0.4935 0.0793642 -0.027178 0.4935 0.080112 -0.027178 0.4935 0.0793727 -0.0259411 0.4935 0.083979 -0.027179 0.471577 0.083757 -0.03397 0.471612 0.08068500000000001 -0.032615 0.4645 0.080595 -0.021743 0.4645 0.08053979999999999 -0.0169241 0.4645 0.081124 -0.016307 0.4645 -0.034165 -0.10694 0.25833 -0.034165 -0.114446 0.286342 -0.035427 -0.106378 0.288504 0.0414966 -0.084435 0.334 0.041541 -0.088299 0.354263 0.011392 -0.08390549999999999 0.334 0.0109 0.154184 0.275694 0.018865 0.143125 0.248635 0.0109 0.146678 0.247682 -0.0766416 0.0728245 0.282836 -0.061307 0.07716339999999999 0.302779 -0.061307 0.0754647 0.295 0.06760099999999999 -0.101744 0.523384 0.06760099999999999 -0.095751 0.529524 0.0419165 -0.100044 0.525991 -0.00648101 -0.147615 0.247431 0.00227099 -0.148207 0.247273 -0.00648101 -0.155121 0.275443 0.049063 -0.07511370000000001 0.295 0.059 -0.06869500000000001 0.262 0.0513403 -0.0750745 0.295 0.0413382 -0.067909 0.261692 0.0413366 -0.0595159 0.260959 0.0413382 -0.0486648 0.261692 0.06760099999999999 -0.112671 0.480468 0.0418204 -0.113436 0.482065 0.041814 -0.112979 0.479169 0.0800466 -0.0275997 0.4645 0.08032350000000001 -0.029897 0.4645 0.079815 -0.032615 0.4645 -0.122964 0.045036 0.263453 -0.126401 0.041887 0.286701 -0.124024 0.05266 0.286688 -0.115974 -0.05809 0.263317 -0.120144 -0.052723 0.263398 -0.094407 -0.06848799999999999 0.262893 0.059001 -0.052636 0.298752 0.059001 -0.050173 0.314333 0.059001 -0.063197 0.371791 0.072702 0.082625 0.415539 0.06760099999999999 0.101487 0.429166 0.06760099999999999 0.104222 0.44057 0.059001 0.039449 0.354901 0.066029 0.022513 0.33935 0.059001 0.042695 0.344901 0.0465184 0.0442139 0.261782 0.0462087 0.04448 0.261776 0.0526043 0.0527231 0.261888 0.0468142 0.0438315 0.261787 0.0465184 0.0442139 0.261782 0.0526043 0.0527231 0.261888 -0.094407 -0.06848799999999999 0.262893 -0.0427895 -0.0478143 0.261879 -0.0423955 -0.048153 0.261871 0.08068500000000001 -0.032615 0.4645 0.079815 -0.032615 0.4645 0.08032350000000001 -0.029897 0.4645 0.06760099999999999 0.08888500000000001 0.391522 0.06760099999999999 0.092889 0.398706 0.072702 0.082625 0.415539 0.059001 0.091573 0.395704 0.06760099999999999 0.08888500000000001 0.391522 0.06760099999999999 0.08465 0.386212 0.059001 0.091573 0.395704 0.06760099999999999 0.092889 0.398706 0.06760099999999999 0.08888500000000001 0.391522 0.06760099999999999 0.112671 0.480468 0.0418086 0.112526 0.476744 0.041812 0.112814 0.478284 0.06376179999999999 -0.0304138 0.262083 0.0601789 -0.0222829 0.262021 0.0603244 -0.0217207 0.262023 0.06760099999999999 -0.095751 0.529524 0.072714 -0.048196 0.536595 0.06760099999999999 -0.080802 0.539832 0.080029 -0.032595 0.4935 0.0793268 -0.032595 0.4935 0.0796557 -0.0345965 0.49317 0.06750399999999999 0.025653 0.313794 0.0710831 8.27181e-26 0.31324 0.07230109999999999 0 0.287641 0.0805501 0.0166998 0.4645 0.080564 0.016307 0.4645 0.0812914 0 0.457002 -0.108735 -0.08329499999999999 0.35666 -0.118275 -0.079184 0.356402 -0.117959 -0.074543 0.333388 0.03532 -0.122198 0.284265 0.034159 -0.130598 0.282014 0.03532 -0.114692 0.256253 0.080112 0.027178 0.4935 0.083608 0.027179 0.486575 0.080029 0.032595 0.4935 -0.032312 0.126674 0.253043 -0.02814 0.134129 0.251045 0.026005 0.091485 0.262471 0.059 0.054807 0.272546 0.059 0.054995 0.262 0.059 0.06869500000000001 0.262 0.060225 0.0223 0.260614 0.059134 0.0244145 0.262002 0.0598206 0.0230138 0.262014 0.081124 0.016307 0.4645 0.080595 0.021743 0.4645 0.080832 0.027179 0.4645 0.06760099999999999 0.015027 0.546662 0.06760099999999999 0 0.546542 0.06885670000000001 0.0075135 0.544556 -0.140007 0.029219 0.354572 -0.135472 0.04726 0.354722 -0.137444 0.026815 0.333464 0.077801 0.068165 0.419658 0.077801 0.051714 0.39227 0.072702 0.062892 0.38464 -0.009366879999999999 0.07095220000000001 0.267974 0.041335 0.070367 0.260227 -0.0395053 0.07044789999999999 0.268076 -0.140721 0.000441 0.344 -0.139966 0.000441003 0.333462 -0.140721 -0.000441 0.344 -0.0468523 -0.0437713 0.261959 -0.0505035 -0.0390881 0.261361 -0.046547 -0.044242 0.260614 0.06760099999999999 0.08465 0.386212 0.06760099999999999 0.08888500000000001 0.391522 0.072702 0.082625 0.415539 0.0793606 -0.0429314 0.470023 0.077801 -0.075124 0.452 0.07943509999999999 -0.041132 0.46787 0.080633 -0.033959 0.464671 0.08015360000000001 -0.034827 0.464783 0.0797466 -0.0341119 0.464691 0.0801933 -0.033623 0.464628 0.07975359999999999 -0.033959 0.464671 0.08021929999999999 -0.033287 0.464585 0.059001 0.063197 0.371791 0.059001 0.044068 0.339895 0.059001 0.046861 0.329708 0.0426141 0.110107 0.509057 0.0418851 0.109429 0.511525 0.06760099999999999 0.109104 0.511055 0.059 -0.054995 0.262 0.0550112 -0.0328241 0.26193 0.0550862 -0.0326713 0.261932 0.080329 -0.041132 0.46787 0.079884 -0.0408845 0.46769 0.07990650000000001 -0.040637 0.467511 0.06760099999999999 0.095751 0.529524 0.072714 0.0822 0.522573 0.06760099999999999 0.101744 0.523384 -0.0362556 -0.0529008 0.261751 -0.0309974 -0.0558417 0.261182 -0.0253133 -0.0589824 0.261536 0.0793642 0.027178 0.4935 0.07972070000000001 0.0298865 0.4935 0.07932939999999999 0.0322129 0.4935 0.019285 -0.086037 0.263931 0.011373 -0.082374 0.264912 0.0192849 -0.0935428 0.291944 -0.0394457 0.0833752 0.334 -0.026335 0.087259 0.355483 0.007603 0.087779 0.354873 0.079911 0.042146 0.489064 0.0795342 0.041164 0.49 0.079914 0.040182 0.490935 0.06760099999999999 -0.072328 0.542782 0.06760099999999999 -0.062782 0.5443750000000001 0.041957 -0.0656022 0.544357 -0.117537 -0.06936199999999999 0.309941 -0.117026 -0.063762 0.286585 -0.105911 -0.070065 0.286406 -0.106214 -0.075188 0.309795 -0.117537 -0.06936199999999999 0.309941 -0.105911 -0.070065 0.286406 0.06760099999999999 -0.063149 0.371934 0.059001 -0.035831 0.364784 0.061536 -0.028942 0.363699 0.0347672 0.114242 0.272514 0.03532 0.122198 0.284265 0.034283 0.113783 0.28652 0.06760099999999999 -0.072328 0.542782 0.041957 -0.0656022 0.544357 0.0419521 -0.07576720000000001 0.542197 0.06760099999999999 0.105671 0.446901 0.06760099999999999 0.106838 0.452 0.072702 0.082625 0.415539 -0.130461 0.052724 0.33346 -0.137444 0.026815 0.333464 -0.135472 0.04726 0.354722 -0.094407 -0.06848799999999999 0.262893 -0.094357 -0.073585 0.286235 -0.105911 -0.070065 0.286406 0.0622549 0.0142596 0.262057 0.06302489999999999 0.0112835 0.26207 0.063482 0.009719999999999999 0.260614 0.030872 -0.138455 0.27991 0.025664 -0.145275 0.278081 0.030872 -0.130949 0.251897 -0.106214 0.075188 0.309795 -0.09434099999999999 0.075279 0.293992 -0.094357 0.073585 0.286235 -0.124024 -0.05266 0.286688 -0.123512 -0.061676 0.31001 -0.128571 -0.04743 0.310033 0.0794779 -0.040142 0.467152 0.079926 -0.0403895 0.467332 0.079926 -0.0402658 0.467242 0.079914 -0.040182 0.490935 0.0795342 -0.041164 0.49 0.079911 -0.042146 0.489064 -0.106214 -0.075188 0.309795 -0.105911 -0.070065 0.286406 -0.094357 -0.073585 0.286235 0.0587619 0.0251734 0.261996 0.0560778 0.0306485 0.261949 0.0599734 0.0400842 0.262017 -0.0395053 0.07044789999999999 0.268076 0.041335 0.070367 0.260227 -0.0586339 0.0701278 0.268194 0.08036 0.010862 0.4935 0.0803575 -1.35465e-10 0.4935 0.08355940000000001 0 0.48654 0.07920530000000001 -0.045503 0.480707 0.0795828 -0.0453535 0.481872 0.07917159999999999 -0.0452277 0.482853 -0.0586339 0.0701278 0.268194 -0.058339 0.07176399999999999 0.267756 -0.0395053 0.07044789999999999 0.268076 0.0812914 0 0.457002 0.0805501 -0.0166998 0.4645 0.08129 0 0.456649 -0.050447 0.082413 0.264902 -0.055224 0.08516899999999999 0.294187 -0.050447 0.089919 0.292914 0.043928 0.100007 0.421527 0.043362 0.102135 0.430031 0.06760099999999999 0.097194 0.412299 0.0419592 0.0534463 0.545358 0.06840599999999999 0.043556 0.546675 0.0419594 0.0562953 0.545449 0.06760099999999999 0.07764500000000001 0.379589 0.059001 0.072436 0.375943 0.059001 0.08577799999999999 0.387139 0.018865 -0.15063 0.276646 0.0109 -0.154184 0.275694 0.018865 -0.143125 0.248635 0.06840599999999999 -0.043556 0.546675 0.06760099999999999 -0.030676 0.5462129999999999 0.0419592 -0.0534463 0.545358 -0.060273 0.086738 0.356093 -0.09426 0.082453 0.333163 -0.07724300000000001 0.086478 0.356398 0.067703 0.033854 0.262152 0.0620911 0.0148927 0.262054 0.0617553 0.0161906 0.262048 -0.09434099999999999 -0.075279 0.293992 -0.061307 -0.0788237 0.31082 -0.061307 -0.0793295 0.31372 0.07915469999999999 0.0442721 0.48535 0.0791535 0.044193 0.485546 0.07993500000000001 0.044193 0.485546 0.067703 -0.033854 0.262152 0.0617553 -0.0161906 0.262048 0.0620911 -0.0148927 0.262054 0.045589 0.092433 0.396825 0.044994 0.09535100000000001 0.404143 0.06760099999999999 0.092889 0.398706 0.075193 -0.013573 0.376886 0.077801 -0.021838 0.381959 0.072702 -0.027146 0.373149 0.06760099999999999 -0.098633 0.417793 0.072702 -0.082625 0.415539 0.06760099999999999 -0.101487 0.429166 0.080832 0.027179 0.4645 0.083979 0.027179 0.471577 0.081124 0.016307 0.4645 -0.0427895 0.0478143 0.261879 -0.094407 0.06848799999999999 0.262893 -0.0423955 0.048153 0.261871 0.061184 -0.088437 0.534911 0.06760099999999999 -0.080802 0.539832 0.0547669 -0.0885975 0.535144 0.077801 0.068165 0.419658 0.0812756 0 0.455844 0.077801 0.051714 0.39227 0.0505071 0.0390901 0.261267 0.0524073 0.0366001 0.261885 0.054502 0.033966 0.260614 0.0793606 -0.0429314 0.470023 0.07984479999999999 -0.0421185 0.46905 0.080232 -0.043105 0.470231 0.08001900000000001 -0.045722 0.479 0.08107200000000001 -0.044301 0.479023 0.080757 -0.044301 0.482372 -0.0585424 0.0830288 0.334 -0.061307 0.0830142 0.334 -0.026335 0.087259 0.355483 0.079952 -0.036598 0.492841 0.0792677 -0.0368423 0.492711 0.0795689 -0.03839 0.491888 0.0634315 0.00971226 0.262078 0.0631977 0.0106159 0.262073 0.0673198 0.0135692 0.262145 0.07780040000000001 0 0.53 0.07416590000000001 0 0.53572 0.072714 -0.010359 0.538295 0.03532 0.114692 0.256253 0.034159 0.130598 0.282014 0.03532 0.122198 0.284265 -0.094407 0 0.262893 -0.125404 0.000441 0.263502 -0.094407 0.06848799999999999 0.262893 0.0347672 -0.114242 0.272514 0.034283 -0.113783 0.28652 0.03532 -0.122198 0.284265 0.080029 -0.032595 0.4935 0.083608 -0.027179 0.486575 0.080112 -0.027178 0.4935 0.083608 -0.027179 0.486575 0.083428 -0.03397 0.486536 0.08488999999999999 -0.027179 0.479101 0.06760099999999999 -0.07764500000000001 0.379589 0.059001 -0.08577799999999999 0.387139 0.059001 -0.072436 0.375943 0.059001 -0.091573 0.395704 0.06760099999999999 -0.08888500000000001 0.391522 0.06760099999999999 -0.092889 0.398706 0.0697535 0.036353 0.37337 0.0676012 0 0.361701 0.06760099999999999 0.07270600000000001 0.376436 0.0800661 0.027179 0.4645 0.080595 0.021743 0.4645 0.08053979999999999 0.0169241 0.4645 0.077801 -0.078637 0.492309 0.0784329 -0.0567469 0.499244 0.077801 -0.062128 0.521061 -0.0766416 0.0728245 0.282836 -0.061307 0.0754647 0.295 -0.0588761 0.0736657 0.286773 0.06760099999999999 -0.063149 0.371934 0.059001 -0.063197 0.371791 0.059001 -0.035831 0.364784 -0.122964 0.045036 0.263453 -0.123796 0.036459 0.26347 -0.126401 0.041887 0.286701 0.0413382 0.0486648 0.261692 0.0413366 0.0595159 0.260959 0.0413382 0.067909 0.261692 0.0200627 0.0941734 0.291775 0.0192849 0.0935428 0.291944 0.019285 0.086037 0.263931 0.07954559999999999 -0.000879971 0.4935 0.0799184 -0.005431 0.4935 0.0803575 -1.35465e-10 0.4935 0.06393020000000001 0 0.261896 0.06378540000000001 0.0032297 0.261351 0.0639236 0 0.262086 0.025664 -0.13777 0.25007 0.0109 -0.146678 0.247682 0.030872 -0.130949 0.251897 -0.124936 0.019788 0.263492 -0.12965 0.021038 0.28671 -0.126401 0.041887 0.286701 0.06760099999999999 0.095751 0.529524 0.0419165 0.100044 0.525991 0.0419182 0.09948700000000001 0.526511 0.059001 0.063197 0.371791 0.059001 0.046861 0.329708 0.059001 0.050173 0.314333 0.041802 -0.111884 0.47371 0.06760099999999999 -0.108184 0.458108 0.06760099999999999 -0.109492 0.4642 0.0547669 0.0885975 0.535144 0.0419331 0.0918987 0.533554 0.0419393 0.0878264 0.536362 -0.117959 -0.074543 0.333388 -0.117537 -0.06936199999999999 0.309941 -0.106214 -0.075188 0.309795 -0.140721 0.000441 0.344 -0.140721 -0.000441 0.344 -0.141477 0 0.354537 0.06760099999999999 0.030676 0.5462129999999999 0.06760099999999999 0.015027 0.546662 0.072714 0.010359 0.538295 0.031111 0.105882 0.288637 0.031111 0.09837600000000001 0.260625 0.0326038 0.106114 0.274631 -0.077824 0.078304 0.309147 -0.061307 0.081329 0.324301 -0.061307 0.0793295 0.31372 -0.094407 0.06848799999999999 0.262893 -0.115974 0.05809 0.263317 -0.106491 0.06393799999999999 0.26313 0.0812833 0 0.457399 0.0812914 0 0.457002 0.08089490000000001 0.00692969 0.4645 -0.12965 -0.021038 0.28671 -0.126401 -0.041887 0.286701 -0.133782 -0.023965 0.310036 -0.061307 -0.081329 0.324301 -0.061307 -0.08261880000000001 0.331907 -0.094309 -0.07824 0.30966 0.08400680000000001 0 0.471638 0.083979 0.027179 0.471577 0.08488999999999999 0.027179 0.479101 -0.0601714 0.0222805 0.262221 -0.0603376 0.0216382 0.262224 -0.094407 0.06848799999999999 0.262893 -0.094357 0.073585 0.286235 -0.0766416 0.0728245 0.282836 -0.094407 0.06848799999999999 0.262893 -0.0468523 -0.0437713 0.261959 -0.094407 -0.06848799999999999 0.262893 -0.0544567 -0.0339384 0.262108 0.059 -0.06869500000000001 0.262 0.059001 -0.089419 0.377466 0.0525 -0.082581 0.334 0.07915469999999999 -0.0442721 0.48535 0.0795574 -0.0446985 0.484291 0.07993500000000001 -0.044193 0.485546 0.080443 -0.038625 0.466051 0.082525 -0.040197 0.472918 0.080374 -0.040142 0.467152 0.049063 0.07511370000000001 0.295 0.059 0.06869500000000001 0.262 0.04813 0.068846 0.26181 0.072702 -0.082625 0.415539 0.06760099999999999 -0.08465 0.386212 0.06760099999999999 -0.07764500000000001 0.379589 0.072714 -0.09668400000000001 0.488844 0.06760099999999999 -0.108184 0.458108 0.06760099999999999 -0.106838 0.452 0.077801 0.075124 0.452 0.079815 0.032615 0.4645 0.08129 0 0.456649 -0.137444 0.026815 0.333464 -0.141477 0.02304 0.354537 -0.140007 0.029219 0.354572 0.07935349999999999 -0.043105 0.470231 0.0793606 -0.0429314 0.470023 0.080232 -0.043105 0.470231 -0.077824 -0.078304 0.309147 -0.061307 -0.0793295 0.31372 -0.061307 -0.081329 0.324301 0.0109 0.146678 0.247682 0.018865 0.143125 0.248635 0.025664 0.13777 0.25007 0.0792413 0.0456696 0.478641 0.08001900000000001 0.045722 0.479 0.0792721 0.0454926 0.477428 0.077801 0.068165 0.419658 0.077801 0.071922 0.436239 0.0812867 0 0.456321 0.046548 0.044242 0.260614 0.0465184 0.0442139 0.261782 0.0468142 0.0438315 0.261787 0.0151579 0.0860161 0.344257 0.024572 0.08803900000000001 0.354568 0.041541 0.088299 0.354263 0.059 0.06869500000000001 0.262 0.059 0.054995 0.262 0.0536743 0.034962 0.261907 0.072702 0.027146 0.373149 0.072702 0 0.371747 0.0676012 0 0.361701 0.0524073 0.0366001 0.261885 0.0468142 0.0438315 0.261787 0.0526043 0.0527231 0.261888 0.07920530000000001 -0.045503 0.480707 0.079994 -0.045503 0.480707 0.0795828 -0.0453535 0.481872 0.0792803 0.045055 0.474428 0.077801 0.075124 0.452 0.0792721 0.0454926 0.477428 -0.063481 -0.009719999999999999 0.260614 -0.0634233 -0.00971116 0.262284 -0.06345820000000001 -0.009023339999999999 0.262285 0.06420099999999999 -0.01856 0.362567 0.06904490000000001 0 0.338783 0.06904449999999999 0 0.338789 0.0817947 -0.0421716 0.482127 0.082288 -0.040197 0.485185 0.080757 -0.044301 0.482372 0.045859 0.090318 0.382877 0.045805 0.090896 0.387693 0.059001 0.091573 0.395704 0.042747 0.08745699999999999 0.36068 0.059001 0.089419 0.377466 0.0415602 0.0882602 0.356609 0.0794768 -0.010862 0.4935 0.08036 -0.010862 0.4935 0.0799184 -0.005431 0.4935 0.0418407 0.113944 0.4912 0.06760099999999999 0.11328 0.492262 0.06760099999999999 0.113524 0.488197 0.072702 -0.062892 0.38464 0.077801 -0.068165 0.419658 0.072702 -0.082625 0.415539 0.0792413 0.0456696 0.478641 0.0792322 0.045722 0.479 0.08001900000000001 0.045722 0.479 0.0526043 0.0527231 0.261888 0.0462087 0.04448 0.261776 0.04813 0.068846 0.26181 -0.126401 -0.041887 0.286701 -0.128571 -0.04743 0.310033 -0.133782 -0.023965 0.310036 0.06904490000000001 0 0.338783 0.066029 0.022513 0.33935 0.06420099999999999 0.01856 0.362567 0.0791545 0.042146 0.489064 0.0784329 0.0567469 0.499244 0.07918360000000001 0.0403254 0.490798 0.042178 0.105959 0.446111 0.0417532 0.107167 0.451436 0.06760099999999999 0.106838 0.452 -0.039209 -0.091576 0.262447 -0.0395053 -0.07044789999999999 0.268076 -0.009366879999999999 -0.07095220000000001 0.267974 -0.0126472 -0.06290800000000001 0.261287 -0.0129232 -0.0628798 0.261293 -0.012928 -0.062903 0.260614 0.0547669 0.0885975 0.535144 0.0419328 0.0920768 0.533431 0.0419331 0.0918987 0.533554 0.072714 -0.09668400000000001 0.488844 0.06760099999999999 -0.11328 0.492262 0.06760099999999999 -0.113524 0.488197 0.06560199999999999 -0.0225688 0.262115 0.0622549 -0.0142596 0.262057 0.06302489999999999 -0.0112835 0.26207 0.044994 0.09535100000000001 0.404143 0.043928 0.100007 0.421527 0.06760099999999999 0.095661 0.406449 0.07954070000000001 -0.0439365 0.486183 0.07993500000000001 -0.044193 0.485546 0.0797379 -0.0439365 0.486183 -0.009366879999999999 -0.07095220000000001 0.267974 -0.0395053 -0.07044789999999999 0.268076 0.041335 -0.070367 0.260227 0.059 -0.054995 0.262 0.0544633 -0.0339419 0.261921 0.0547011 -0.0334568 0.261925 0.06760099999999999 0.030676 0.5462129999999999 0.0547816 0.0230032 0.546303 0.0547809 0.0153353 0.546147 0.068949 0.028271 0.262174 0.06560199999999999 0.0225688 0.262115 0.067703 0.033854 0.262152 0.0366821 0.0526975 0.260318 0.025353 0.0589956 0.260541 0.041335 0.070367 0.260227 0.079911 0.042146 0.489064 0.0791545 0.042146 0.489064 0.0795342 0.041164 0.49 0.041335 -0.070367 0.260227 0.0367757 -0.052617 0.260317 0.041335 -0.0486991 0.260227 0.0687214 0 0.341713 0.065675 -0.011034 0.361971 0.06904449999999999 0 0.338789 -0.094407 -0.06848799999999999 0.262893 -0.0366651 -0.0526732 0.261759 -0.0362556 -0.0529008 0.261751 0.08014019999999999 0.040637 0.467511 0.080374 0.040142 0.467152 0.07990650000000001 0.040637 0.467511 0.0639748 0 0.260614 0.0639619 0 0.260984 0.06378540000000001 -0.0032297 0.261351 0.0631977 0.0106159 0.262073 0.06302489999999999 0.0112835 0.26207 0.068949 0.028271 0.262174 0.06760099999999999 -0.105671 0.446901 0.072702 -0.082625 0.415539 0.06760099999999999 -0.106838 0.452 -0.140721 0.000441 0.344 -0.141477 0 0.354537 -0.141477 0.02304 0.354537 0.0795443 -0.0440647 0.485864 0.07993500000000001 -0.044193 0.485546 0.07954070000000001 -0.0439365 0.486183 0.08001900000000001 0.045722 0.479 0.080167 0.044149 0.472477 0.080111 0.045055 0.474428 -0.118275 0.079184 0.356402 -0.117959 0.074543 0.333388 -0.12413 0.067466 0.333441 0.0800661 0.027179 0.4645 0.08053979999999999 0.0169241 0.4645 0.08129 0 0.456649 0.03532 0.122198 0.284265 0.034283 0.106278 0.258508 0.03532 0.114692 0.256253 0.0599825 0 0.546275 0.0606135 0 0.546342 0.06760099999999999 0.015027 0.546662 0.06439250000000001 0.0883568 0.534794 0.061184 0.088437 0.534911 0.06760099999999999 0.080802 0.539832 0.0418924 -0.107468 0.514809 0.0418851 -0.109429 0.511525 0.06760099999999999 -0.109104 0.511055 0.081124 -0.016307 0.4645 0.0825649 -0.0135895 0.468069 0.083979 -0.027179 0.471577 0.06760099999999999 0.106838 0.452 0.06760099999999999 0.105671 0.446901 0.042178 0.105959 0.446111 0.060225 0.0223 0.260614 0.0598206 0.0230138 0.262014 0.0601789 0.0222829 0.262021 0.0676012 0 0.361701 0.06760099999999999 0.024057 0.363637 0.06760099999999999 0.063149 0.371934 0.0799184 0.005431 0.4935 0.08036 0.010862 0.4935 0.0794768 0.010862 0.4935 0.077801 -0.062128 0.521061 0.072714 -0.048196 0.536595 0.072714 -0.0822 0.522573 0.054502 -0.033966 0.260614 0.0544633 -0.0339419 0.261921 0.0536743 -0.034962 0.261907 0.0712801 0 0.540548 0.06760099999999999 0 0.546542 0.0701391 -0.0075135 0.542467 0.0792823 -0.0363279 0.492885 0.0793291 -0.0348661 0.493126 0.077801 -0.062128 0.521061 0.06760099999999999 -0.063149 0.371934 0.06760099999999999 -0.024057 0.363637 0.0676012 0 0.361701 0.059 -0.054995 0.262 0.059 -0.054807 0.272546 0.059 -0.06869500000000001 0.262 -0.128571 0.04743 0.310033 -0.123512 0.061676 0.31001 -0.124024 0.05266 0.286688 -0.0366651 0.0526732 0.261759 -0.0362556 0.0529008 0.261751 -0.036688 0.052706 0.260614 0.059001 0.08577799999999999 0.387139 0.059001 0.091573 0.395704 0.06760099999999999 0.08465 0.386212 0.0418372 -0.113956 0.489576 0.06760099999999999 -0.113524 0.488197 0.0418407 -0.113944 0.4912 0.0792831 0.0449796 0.474266 0.07972509999999999 0.044602 0.473453 0.0793143 0.044149 0.472477 0.0796557 0.0345965 0.49317 0.0793291 0.0348661 0.493126 0.0793268 0.032595 0.4935 0.063482 -0.009719999999999999 0.260614 0.0618289 -0.0160036 0.261346 0.060225 -0.0223 0.260614 0.0414112 0.076998 0.295 0.041335 0.070367 0.260227 0.0288275 0.0767767 0.295 0.0676012 0 0.361701 0.072702 -0.027146 0.373149 0.072702 -0.062892 0.38464 0.080633 0.033959 0.464671 0.083757 0.03397 0.471612 0.08068500000000001 0.032615 0.4645 0.059001 -0.072436 0.375943 0.059001 -0.08577799999999999 0.387139 0.059001 -0.089419 0.377466 -0.0427895 0.0478143 0.261879 -0.0423955 0.048153 0.261871 -0.042663 0.047998 0.260614 -0.00949171 0.0778746 0.295 -0.010356 0.0760875 0.295 -0.009366879999999999 0.07095220000000001 0.267974 0.080567 -0.035695 0.464894 0.0800612 -0.03716 0.465473 0.0796743 -0.035695 0.464894 -0.034388 0.110107 0.257482 -0.034433 0.118451 0.255247 0.00725699 0.081315 0.265196 0.07920530000000001 0.045503 0.480707 0.0795828 0.0453535 0.481872 0.079994 0.045503 0.480707 0.07990650000000001 0.040637 0.467511 0.0796727 0.0405927 0.467479 0.07943890000000001 0.0410435 0.467806 -0.034388 -0.117613 0.285493 -0.034165 -0.114446 0.286342 -0.034388 -0.110107 0.257482 -0.135669 -0.000441002 0.310035 -0.139966 -0.000441003 0.333462 -0.135669 0.000441002 0.310035 0.072714 -0.0822 0.522573 0.06760099999999999 -0.11328 0.492262 0.072714 -0.09668400000000001 0.488844 -0.0158038 0.0837065 0.334 0.024572 0.08803900000000001 0.354568 -0.0112252 0.0836884 0.334 0.06760099999999999 -0.07270600000000001 0.376436 0.06760099999999999 -0.07764500000000001 0.379589 0.059001 -0.072436 0.375943 0.031111 -0.105882 0.288637 0.031111 -0.09837600000000001 0.260625 0.026005 -0.091485 0.262471 -0.09434099999999999 -0.075279 0.293992 -0.106214 -0.075188 0.309795 -0.094357 -0.073585 0.286235 -0.077832 0.07620440000000001 0.298528 -0.09434099999999999 0.075279 0.293992 -0.061307 0.0788237 0.31082 0.000172782 0.0641847 0.261035 0.041335 0.070367 0.260227 0.0129268 0.0628972 0.260785 0.026005 -0.091485 0.262471 0.0293444 -0.103498 0.289276 0.031111 -0.105882 0.288637 0.00227099 0.155713 0.275285 0.0109 0.154184 0.275694 0.0109 0.146678 0.247682 0.059001 0.091573 0.395704 0.045589 0.092433 0.396825 0.06760099999999999 0.092889 0.398706 0.0618289 -0.0160036 0.261346 0.0620911 -0.0148927 0.262054 0.0617553 -0.0161906 0.262048 -0.0766416 -0.0728245 0.282836 -0.061307 -0.0754647 0.295 -0.061307 -0.07716339999999999 0.302779 -0.094407 -0.06848799999999999 0.262893 -0.125404 -0.000441 0.263502 -0.094407 0 0.262893 -0.014805 -0.152445 0.27616 -0.0167591 -0.147553 0.262769 -0.014805 -0.144939 0.248148 0.065675 0.011034 0.361971 0.06420099999999999 0.01856 0.362567 0.06760099999999999 0.024057 0.363637 0.0426141 -0.110107 0.509057 0.0437663 -0.112223 0.501431 0.06760099999999999 -0.109104 0.511055 -0.010356 -0.0760875 0.295 0.041335 -0.070367 0.260227 0.0288275 -0.0767767 0.295 0.06760099999999999 -0.109104 0.511055 0.06760099999999999 -0.101744 0.523384 0.0418924 -0.107468 0.514809 0.000172782 -0.0641847 0.261035 0.00646325 -0.0635527 0.260825 0.0129268 -0.0628972 0.260785 -0.0167591 0.147553 0.262769 -0.0201217 0.149134 0.277048 -0.014805 0.152445 0.27616 0.0812914 0 0.457002 0.08089490000000001 -0.00692969 0.4645 0.080564 -0.016307 0.4645 0.077801 0.068165 0.419658 0.072702 0.082625 0.415539 0.077801 0.071922 0.436239 0.077801 0.021838 0.381959 0.077801 0 0.381 0.07436810000000001 0 0.374716 0.082525 0.040197 0.472918 0.083757 0.03397 0.471612 0.080443 0.038625 0.466051 0.066029 -0.022513 0.33935 0.061536 -0.028942 0.363699 0.059001 -0.035831 0.364784 -0.0587706 -0.07212399999999999 0.278677 -0.058339 -0.07176399999999999 0.267756 -0.058339 -0.0790632 0.295 -0.0639738 0 0.260614 -0.0637808 -0.00322952 0.261456 -0.0639591 0 0.261037 0.07780040000000001 0 0.53 0.077801 0.062128 0.521061 0.072714 0.010359 0.538295 0.042178 -0.105959 0.446111 0.06760099999999999 -0.105671 0.446901 0.06760099999999999 -0.106838 0.452 -0.130461 0.052724 0.33346 -0.123512 0.061676 0.31001 -0.128571 0.04743 0.310033 0.0557236 -1.03398e-25 0.545817 0.06760099999999999 0.015027 0.546662 0.06760099999999999 0.030676 0.5462129999999999 0.08032350000000001 0.029897 0.4645 0.079815 0.032615 0.4645 0.08068500000000001 0.032615 0.4645 0.0796557 -0.0345965 0.49317 0.0793268 -0.032595 0.4935 0.0793291 -0.0348661 0.493126 0.063869 -0.044637 0.262085 0.059 -0.054995 0.262 0.0599734 -0.0400842 0.262017 0.0784712 -0.031064 0.511558 0.0793291 -0.0348661 0.493126 0.0793268 -0.032595 0.4935 -0.123512 0.061676 0.31001 -0.117026 0.063762 0.286585 -0.121458 0.058391 0.286654 0.059 0.053697 0.288311 0.059 0.06869500000000001 0.262 0.059001 0.052636 0.298752 0.0812914 0 0.457002 0.080564 -0.016307 0.4645 0.0805501 -0.0166998 0.4645 0.0603244 0.0217207 0.262023 0.0601789 0.0222829 0.262021 0.06376179999999999 0.0304138 0.262083 0.080443 -0.038625 0.466051 0.0800612 -0.03716 0.465473 0.080567 -0.035695 0.464894 0.077801 -0.068165 0.419658 0.072702 -0.062892 0.38464 0.077801 -0.051714 0.39227 0.031111 0.09837600000000001 0.260625 0.034283 0.113783 0.28652 0.0326038 0.106114 0.274631 0.060225 0.0223 0.260614 0.0618289 0.0160036 0.261346 0.063482 0.009719999999999999 0.260614 0.031111 -0.09837600000000001 0.260625 -0.022179 -0.140348 0.249379 -0.02814 -0.134129 0.251045 0.079884 -0.0408845 0.46769 0.080329 -0.041132 0.46787 0.07943890000000001 -0.0410435 0.467806 0.0418924 0.107468 0.514809 0.0418978 0.106004 0.517218 0.06760099999999999 0.101744 0.523384 0.07954070000000001 -0.0439365 0.486183 0.0797379 -0.0439365 0.486183 0.07992299999999999 -0.04368 0.486819 0.084685 0.033971 0.479099 0.083161 0.040197 0.479069 0.083428 0.03397 0.486536 0.06760099999999999 -0.062782 0.5443750000000001 0.041958 -0.0628167 0.544822 0.041957 -0.0656022 0.544357 0.06904449999999999 0 0.338789 0.065675 -0.011034 0.361971 0.06420099999999999 -0.01856 0.362567 0.07975359999999999 -0.033959 0.464671 0.0797466 -0.0341119 0.464691 0.077801 -0.075124 0.452 0.068949 -0.028271 0.262174 0.0631977 -0.0106159 0.262073 0.0673198 -0.0135692 0.262145 0.07230109999999999 0 0.287641 0.0710831 8.27181e-26 0.31324 0.06750399999999999 -0.025653 0.313794 -0.063481 0.009719999999999999 0.260614 -0.06345820000000001 0.009023339999999999 0.262285 -0.0634233 0.00971116 0.262284 -0.055224 -0.08516899999999999 0.294187 -0.055224 -0.077663 0.266175 -0.050447 -0.082413 0.264902 -0.050447 -0.082413 0.264902 -0.047857 -0.084063 0.26446 -0.050447 -0.089919 0.292914 -0.050447 -0.089919 0.292914 -0.055224 -0.08516899999999999 0.294187 -0.050447 -0.082413 0.264902 -0.055224 -0.08516899999999999 0.294187 -0.0582582 -0.0792273 0.295 -0.055224 -0.077663 0.266175 -0.058339 -0.07176399999999999 0.267756 -0.055224 -0.077663 0.266175 -0.058339 -0.0790632 0.295 -0.047857 -0.091569 0.292472 -0.047857 -0.084063 0.26446 -0.04514 -0.08576499999999999 0.264004 -0.04514 -0.08576499999999999 0.264004 -0.039209 -0.091576 0.262447 -0.04514 -0.09327100000000001 0.292016 -0.0582582 -0.0792273 0.295 -0.058339 -0.0790632 0.295 -0.055224 -0.077663 0.266175 -0.04514 -0.08576499999999999 0.264004 -0.04514 -0.09327100000000001 0.292016 -0.047857 -0.091569 0.292472 -0.039209 -0.091576 0.262447 -0.039209 -0.099082 0.290459 -0.04514 -0.09327100000000001 0.292016 -0.047857 -0.091569 0.292472 -0.050447 -0.089919 0.292914 -0.047857 -0.084063 0.26446 -0.108737 -0.108408 0.481798 -0.108743 -0.112924 0.479123 -0.108731 -0.10887 0.484473 -0.108743 -0.103892 0.479123 -0.108737 -0.108408 0.481798 -0.108731 -0.10887 0.484473 -0.108704 -0.108992 0.496527 -0.108719 -0.113972 0.489824 -0.108689 -0.11224 0.503533 -0.108691 -0.10404 0.502782 -0.108704 -0.108992 0.496527 -0.108689 -0.11224 0.503533 0.0418372 -0.113956 0.489576 0.0418407 -0.113944 0.4912 0.041837 -0.1166 0.489494 0.0418368 -0.113957 0.489412 0.0418372 -0.113956 0.489576 0.041837 -0.1166 0.489494 -0.108661 -0.107153 0.516382 -0.108689 -0.11224 0.503533 -0.0291 -0.110769 0.5108200000000001 -0.108661 -0.107153 0.516382 -0.0291 -0.110769 0.5108200000000001 -0.0277345 -0.108784 0.515893 -0.108689 -0.11224 0.503533 -0.108661 -0.107153 0.516382 -0.10869 -0.10404 0.503285 -0.10869 -0.10404 0.503285 -0.108691 -0.10404 0.502782 -0.108689 -0.11224 0.503533 -0.108689 -0.11224 0.503533 -0.0298901 -0.111918 0.50788 -0.0291 -0.110769 0.5108200000000001 -0.0309903 -0.113553 0.503701 -0.108689 -0.11224 0.503533 -0.0655534 -0.113835 0.496772 -0.108689 -0.11224 0.503533 -0.0309903 -0.113553 0.503701 -0.0298901 -0.111918 0.50788 -0.108661 -0.107153 0.516382 -0.0277345 -0.108784 0.515893 -0.02729 -0.108398 0.516889 -0.108661 -0.107153 0.516382 -0.066859 -0.10543 0.519894 -0.0868767 -0.104765 0.520263 -0.108653 -0.104426 0.520135 -0.108661 -0.107153 0.516382 -0.0868767 -0.104765 0.520263 -0.108661 -0.107153 0.516382 -0.06738769999999999 -0.10665 0.5182 -0.066859 -0.10543 0.519894 -0.06738769999999999 -0.10665 0.5182 -0.02729 -0.108398 0.516889 -0.0422016 -0.106249 0.519439 -0.0422016 -0.106249 0.519439 -0.02729 -0.108398 0.516889 -0.0261145 -0.106509 0.51952 -0.108661 -0.107153 0.516382 -0.02729 -0.108398 0.516889 -0.06738769999999999 -0.10665 0.5182 -0.108661 -0.104041 0.516602 -0.108661 -0.107153 0.516382 -0.108653 -0.104426 0.520135 -0.108661 -0.104041 0.516602 -0.108661 -0.104041 0.516292 -0.108661 -0.107153 0.516382 -0.0315008 -0.113773 0.501896 -0.0309903 -0.113553 0.503701 -0.0655534 -0.113835 0.496772 -0.032288 -0.114128 0.498975 -0.0315008 -0.113773 0.501896 -0.0655534 -0.113835 0.496772 -0.032288 -0.114128 0.498975 -0.0655534 -0.113835 0.496772 -0.0223878 -0.114438 0.49787 -0.108731 -0.10887 0.484473 -0.108731 -0.111421 0.484474 -0.108719 -0.113972 0.489824 -0.108719 -0.113972 0.489824 -0.108731 -0.111421 0.484474 -0.108743 -0.112924 0.479123 -0.108725 -0.108989 0.487149 -0.108731 -0.10887 0.484473 -0.108719 -0.113972 0.489824 0.041837 -0.1166 0.489494 -0.108719 -0.113972 0.489824 -0.108743 -0.112924 0.479123 -0.108734 -0.103767 0.483282 -0.108731 -0.10887 0.484473 -0.10872 -0.104006 0.489353 -0.108734 -0.103767 0.483282 -0.108743 -0.103892 0.479123 -0.108731 -0.10887 0.484473 0.0222217 -0.109573 0.454324 -0.108823 -0.104429 0.442579 -0.0158088 -0.10808 0.450916 -0.108743 -0.112924 0.479123 -0.108782 -0.104431 0.461051 -0.108823 -0.104429 0.442579 -0.10875 -0.103984 0.476016 -0.108782 -0.104431 0.461051 -0.108743 -0.112924 0.479123 -0.108743 -0.103892 0.479123 -0.10875 -0.103984 0.476016 -0.108743 -0.112924 0.479123 0.0417844 -0.110183 0.465616 0.0417612 -0.110111 0.455091 0.0417532 -0.107167 0.451436 0.0418052 -0.112203 0.475196 0.0418086 -0.112526 0.476744 0.041812 -0.115502 0.478284 0.041802 -0.111884 0.47371 0.0418052 -0.112203 0.475196 0.041812 -0.115502 0.478284 0.041812 -0.115502 0.478284 0.0417844 -0.110183 0.465616 0.041802 -0.111884 0.47371 0.0418086 -0.112526 0.476744 0.041812 -0.112814 0.478284 0.041812 -0.115502 0.478284 0.0361127 -0.109979 0.45497 0.040704 -0.110115 0.455193 0.041812 -0.115502 0.478284 0.0222217 -0.109573 0.454324 0.0361127 -0.109979 0.45497 0.041812 -0.115502 0.478284 -0.0158088 -0.10808 0.450916 0.0222217 -0.109573 0.454324 0.041812 -0.115502 0.478284 -0.0335054 -0.109992 0.460546 -0.0158088 -0.10808 0.450916 0.041812 -0.115502 0.478284 0.0418333 -0.11397 0.48782 0.0418368 -0.113957 0.489412 0.041837 -0.1166 0.489494 0.0418247 -0.113646 0.483969 0.0418245 -0.114711 0.483889 0.0418204 -0.113436 0.482065 0.0418247 -0.113646 0.483969 0.0418333 -0.11397 0.48782 0.0418245 -0.114711 0.483889 0.0418204 -0.113436 0.482065 0.0418245 -0.114711 0.483889 0.041812 -0.115502 0.478284 -0.108743 -0.112924 0.479123 0.041812 -0.115502 0.478284 0.041837 -0.1166 0.489494 -0.108743 -0.112924 0.479123 -0.0335054 -0.109992 0.460546 0.041812 -0.115502 0.478284 0.041812 -0.115502 0.478284 0.0418245 -0.114711 0.483889 0.041837 -0.1166 0.489494 0.0418121 -0.112822 0.47833 0.041814 -0.112979 0.479169 0.041812 -0.115502 0.478284 0.041814 -0.112979 0.479169 0.0418204 -0.113436 0.482065 0.041812 -0.115502 0.478284 0.0418333 -0.11397 0.48782 0.041837 -0.1166 0.489494 0.0418245 -0.114711 0.483889 0.041812 -0.112814 0.478284 0.0418121 -0.112822 0.47833 0.041812 -0.115502 0.478284 -0.0334344 -0.114789 0.49359 -0.108719 -0.113972 0.489824 0.041837 -0.1166 0.489494 -0.0334344 -0.114789 0.49359 -0.0223878 -0.114438 0.49787 -0.108719 -0.113972 0.489824 -0.0334344 -0.114789 0.49359 -0.00482529 -0.11499 0.49589 -0.0223878 -0.114438 0.49787 -0.0223878 -0.114438 0.49787 -0.0655534 -0.113835 0.496772 -0.108719 -0.113972 0.489824 0.041837 -0.1166 0.489494 0.0286168 -0.115555 0.495963 0.0104799 -0.115243 0.495969 0.041837 -0.1166 0.489494 0.0104799 -0.115243 0.495969 0.00256593 -0.115109 0.495951 0.0286168 -0.115555 0.495963 0.041837 -0.1166 0.489494 0.0355793 -0.115678 0.495935 0.0418429 -0.113883 0.492218 0.0418502 -0.113562 0.495605 0.0418436 -0.115081 0.49255 0.0418502 -0.113562 0.495605 0.0418501 -0.115831 0.495582 0.0418436 -0.115081 0.49255 0.0389407 -0.115743 0.495884 0.041837 -0.1166 0.489494 0.0418501 -0.115831 0.495582 0.0355793 -0.115678 0.495935 0.041837 -0.1166 0.489494 0.0389407 -0.115743 0.495884 -0.0321047 -0.114133 0.498965 -0.032288 -0.114128 0.498975 -0.0223878 -0.114438 0.49787 -0.066859 -0.10543 0.519894 -0.06738769999999999 -0.10665 0.5182 -0.0422016 -0.106249 0.519439 0.041837 -0.1166 0.489494 -0.00482529 -0.11499 0.49589 -0.0334344 -0.114789 0.49359 0.041837 -0.1166 0.489494 0.00256593 -0.115109 0.495951 -0.00482529 -0.11499 0.49589 -0.108704 -0.106516 0.496481 -0.108718 -0.104039 0.49018 -0.108704 -0.108992 0.496527 -0.108704 -0.106516 0.496481 -0.108704 -0.108992 0.496527 -0.108691 -0.10404 0.502782 -0.108718 -0.104039 0.49018 -0.108704 -0.106516 0.496481 -0.108691 -0.10404 0.502782 -0.108718 -0.104039 0.49018 -0.108712 -0.109005 0.493175 -0.108704 -0.108992 0.496527 -0.108718 -0.104039 0.49018 -0.108715 -0.109005 0.4915 -0.108712 -0.109005 0.493175 -0.108712 -0.109005 0.493175 -0.108715 -0.109005 0.4915 -0.108719 -0.113972 0.489824 -0.108719 -0.113972 0.489824 -0.108715 -0.109005 0.4915 -0.108718 -0.104039 0.49018 -0.108719 -0.113972 0.489824 -0.10872 -0.104013 0.489521 -0.10872 -0.104006 0.489353 -0.108718 -0.104039 0.49018 -0.10872 -0.104013 0.489521 -0.108719 -0.113972 0.489824 -0.108712 -0.109005 0.493175 -0.108719 -0.113972 0.489824 -0.108704 -0.108992 0.496527 0.0418436 -0.115081 0.49255 0.0418501 -0.115831 0.495582 0.041837 -0.1166 0.489494 -0.10872 -0.104006 0.489353 -0.108731 -0.10887 0.484473 -0.108725 -0.108989 0.487149 -0.10872 -0.104006 0.489353 -0.108725 -0.108989 0.487149 -0.108719 -0.113972 0.489824 -0.108743 -0.103892 0.479123 -0.10874 -0.108408 0.480461 -0.108737 -0.108408 0.481798 -0.0655534 -0.113835 0.496772 -0.108689 -0.11224 0.503533 -0.108719 -0.113972 0.489824 -0.0335054 -0.109992 0.460546 -0.108823 -0.104429 0.442579 -0.0158088 -0.10808 0.450916 -0.108743 -0.112924 0.479123 -0.10874 -0.108408 0.480461 -0.108743 -0.103892 0.479123 0.0418407 -0.113944 0.4912 0.0418436 -0.115081 0.49255 0.041837 -0.1166 0.489494 -0.108662 -0.104041 0.516104 -0.10869 -0.10404 0.503285 -0.108661 -0.107153 0.516382 -0.108737 -0.108408 0.481798 -0.10874 -0.108408 0.480461 -0.108743 -0.112924 0.479123 0.0417612 -0.110111 0.455091 0.0417844 -0.110183 0.465616 0.041812 -0.115502 0.478284 -0.108731 -0.10887 0.484473 -0.108743 -0.112924 0.479123 -0.108731 -0.111421 0.484474 -0.108661 -0.104041 0.516292 -0.108662 -0.104041 0.516104 -0.108661 -0.107153 0.516382 0.0418429 -0.113883 0.492218 0.0418436 -0.115081 0.49255 0.0418407 -0.113944 0.4912 -0.108743 -0.112924 0.479123 -0.108823 -0.104429 0.442579 -0.0335054 -0.109992 0.460546 0.040704 -0.110115 0.455193 0.0417612 -0.110111 0.455091 0.041812 -0.115502 0.478284 0.041812 0.115502 0.478284 -0.0158088 0.10808 0.450916 -0.0335054 0.109992 0.460546 -0.108743 0.112924 0.479123 0.041812 0.115502 0.478284 -0.0335054 0.109992 0.460546 -0.108743 0.112924 0.479123 0.041837 0.1166 0.489494 0.041812 0.115502 0.478284 0.041812 0.115502 0.478284 0.0417844 0.110183 0.465616 0.0417612 0.110111 0.455091 0.040704 0.110115 0.455193 0.041812 0.115502 0.478284 0.0417612 0.110111 0.455091 0.0361127 0.109979 0.45497 0.041812 0.115502 0.478284 0.040704 0.110115 0.455193 0.0222217 0.109573 0.454324 0.041812 0.115502 0.478284 0.0361127 0.109979 0.45497 0.0417532 0.107167 0.451436 0.0417612 0.110111 0.455091 0.0417844 0.110183 0.465616 -0.0868767 0.104765 0.520263 -0.066859 0.10543 0.519894 -0.108661 0.107153 0.516382 -0.108661 0.107153 0.516382 -0.066859 0.10543 0.519894 -0.06738769999999999 0.10665 0.5182 -0.0422016 0.106249 0.519439 -0.06738769999999999 0.10665 0.5182 -0.066859 0.10543 0.519894 -0.0422016 0.106249 0.519439 -0.0261145 0.106509 0.51952 -0.02729 0.108398 0.516889 -0.0309903 0.113553 0.503701 -0.0315008 0.113773 0.501896 -0.0655534 0.113835 0.496772 -0.0655534 0.113835 0.496772 -0.0315008 0.113773 0.501896 -0.032288 0.114128 0.498975 -0.108689 0.11224 0.503533 -0.0309903 0.113553 0.503701 -0.0655534 0.113835 0.496772 -0.108719 0.113972 0.489824 -0.10872 0.104013 0.489521 -0.108718 0.104039 0.49018 -0.10872 0.104013 0.489521 -0.108719 0.113972 0.489824 -0.10872 0.104006 0.489353 -0.108743 0.103892 0.479123 -0.10874 0.108408 0.480461 -0.108743 0.112924 0.479123 -0.108737 0.108408 0.481798 -0.10874 0.108408 0.480461 -0.108743 0.103892 0.479123 -0.108743 0.112924 0.479123 -0.10874 0.108408 0.480461 -0.108737 0.108408 0.481798 -0.108737 0.108408 0.481798 -0.108743 0.103892 0.479123 -0.108731 0.10887 0.484473 -0.108731 0.10887 0.484473 -0.108743 0.103892 0.479123 -0.108734 0.103767 0.483282 -0.108743 0.112924 0.479123 -0.10875 0.103984 0.476016 -0.108743 0.103892 0.479123 -0.108718 0.104039 0.49018 -0.108715 0.109005 0.4915 -0.108719 0.113972 0.489824 -0.108712 0.109005 0.493175 -0.108718 0.104039 0.49018 -0.108704 0.108992 0.496527 -0.108712 0.109005 0.493175 -0.108715 0.109005 0.4915 -0.108718 0.104039 0.49018 -0.108719 0.113972 0.489824 -0.108712 0.109005 0.493175 -0.108704 0.108992 0.496527 -0.108719 0.113972 0.489824 -0.108704 0.108992 0.496527 -0.108689 0.11224 0.503533 -0.108704 0.108992 0.496527 -0.108718 0.104039 0.49018 -0.108704 0.106516 0.496481 -0.108704 0.108992 0.496527 -0.108704 0.106516 0.496481 -0.108691 0.10404 0.502782 -0.108719 0.113972 0.489824 -0.108689 0.11224 0.503533 -0.0655534 0.113835 0.496772 -0.108689 0.11224 0.503533 -0.108691 0.10404 0.502782 -0.10869 0.10404 0.503285 -0.108689 0.11224 0.503533 -0.10869 0.10404 0.503285 -0.108661 0.107153 0.516382 -0.108661 0.107153 0.516382 -0.108662 0.104041 0.516104 -0.108661 0.104041 0.516292 -0.108661 0.107153 0.516382 -0.10869 0.10404 0.503285 -0.108662 0.104041 0.516104 -0.108661 0.107153 0.516382 -0.108661 0.104041 0.516292 -0.108661 0.104041 0.516602 -0.108661 0.107153 0.516382 -0.108661 0.104041 0.516602 -0.108653 0.104426 0.520135 -0.0291 0.110769 0.5108200000000001 -0.108689 0.11224 0.503533 -0.108661 0.107153 0.516382 -0.0291 0.110769 0.5108200000000001 -0.0298901 0.111918 0.50788 -0.108689 0.11224 0.503533 -0.108661 0.107153 0.516382 -0.0277345 0.108784 0.515893 -0.0291 0.110769 0.5108200000000001 -0.108661 0.107153 0.516382 -0.02729 0.108398 0.516889 -0.0277345 0.108784 0.515893 -0.108731 0.10887 0.484473 -0.108734 0.103767 0.483282 -0.10872 0.104006 0.489353 0.041812 0.115502 0.478284 0.0418086 0.112526 0.476744 0.0418052 0.112203 0.475196 0.041812 0.115502 0.478284 0.0418052 0.112203 0.475196 0.041802 0.111884 0.47371 0.0418245 0.114711 0.483889 0.0418247 0.113646 0.483969 0.0418204 0.113436 0.482065 0.0418245 0.114711 0.483889 0.0418333 0.11397 0.48782 0.0418247 0.113646 0.483969 0.041837 0.1166 0.489494 0.0418333 0.11397 0.48782 0.0418245 0.114711 0.483889 0.041837 0.1166 0.489494 0.0418372 0.113956 0.489576 0.0418368 0.113957 0.489412 0.041837 0.1166 0.489494 0.0418407 0.113944 0.4912 0.0418372 0.113956 0.489576 0.0389407 0.115743 0.495884 0.0418501 0.115831 0.495582 0.041837 0.1166 0.489494 0.0418436 0.115081 0.49255 0.0418502 0.113562 0.495605 0.0418429 0.113883 0.492218 0.0418501 0.115831 0.495582 0.0418502 0.113562 0.495605 0.0418436 0.115081 0.49255 0.0418501 0.115831 0.495582 0.0418436 0.115081 0.49255 0.041837 0.1166 0.489494 0.0418436 0.115081 0.49255 0.0418429 0.113883 0.492218 0.0418407 0.113944 0.4912 0.041837 0.1166 0.489494 0.0418436 0.115081 0.49255 0.0418407 0.113944 0.4912 0.0355793 0.115678 0.495935 0.0389407 0.115743 0.495884 0.041837 0.1166 0.489494 0.0286168 0.115555 0.495963 0.0355793 0.115678 0.495935 0.041837 0.1166 0.489494 0.0104799 0.115243 0.495969 0.0286168 0.115555 0.495963 0.041837 0.1166 0.489494 -0.108719 0.113972 0.489824 -0.0334344 0.114789 0.49359 0.041837 0.1166 0.489494 -0.0334344 0.114789 0.49359 -0.00482529 0.11499 0.49589 0.041837 0.1166 0.489494 -0.00482529 0.11499 0.49589 -0.0334344 0.114789 0.49359 -0.0223878 0.114438 0.49787 -0.00482529 0.11499 0.49589 0.00256593 0.115109 0.495951 0.041837 0.1166 0.489494 0.00256593 0.115109 0.495951 0.0104799 0.115243 0.495969 0.041837 0.1166 0.489494 0.041837 0.1166 0.489494 0.0418245 0.114711 0.483889 0.041812 0.115502 0.478284 0.041812 0.115502 0.478284 0.041814 0.112979 0.479169 0.0418121 0.112822 0.47833 0.041812 0.115502 0.478284 0.0418204 0.113436 0.482065 0.041814 0.112979 0.479169 -0.06738769999999999 0.10665 0.5182 -0.02729 0.108398 0.516889 -0.108661 0.107153 0.516382 -0.0655534 0.113835 0.496772 -0.032288 0.114128 0.498975 -0.0223878 0.114438 0.49787 0.041837 0.1166 0.489494 0.0418368 0.113957 0.489412 0.0418333 0.11397 0.48782 -0.108743 0.112924 0.479123 -0.108737 0.108408 0.481798 -0.108731 0.10887 0.484473 -0.108731 0.111421 0.484474 -0.108743 0.112924 0.479123 -0.108731 0.10887 0.484473 -0.108743 0.112924 0.479123 -0.108731 0.111421 0.484474 -0.108719 0.113972 0.489824 -0.108731 0.111421 0.484474 -0.108731 0.10887 0.484473 -0.108719 0.113972 0.489824 -0.0158088 0.10808 0.450916 0.041812 0.115502 0.478284 0.0222217 0.109573 0.454324 -0.108823 0.104429 0.442579 -0.0158088 0.10808 0.450916 0.0222217 0.109573 0.454324 0.0418245 0.114711 0.483889 0.0418204 0.113436 0.482065 0.041812 0.115502 0.478284 -0.108743 0.112924 0.479123 -0.108719 0.113972 0.489824 0.041837 0.1166 0.489494 -0.108743 0.112924 0.479123 -0.108782 0.104431 0.461051 -0.10875 0.103984 0.476016 -0.108719 0.113972 0.489824 -0.108715 0.109005 0.4915 -0.108712 0.109005 0.493175 0.041812 0.115502 0.478284 0.0418121 0.112822 0.47833 0.041812 0.112814 0.478284 -0.108689 0.11224 0.503533 -0.0298901 0.111918 0.50788 -0.0309903 0.113553 0.503701 -0.108823 0.104429 0.442579 -0.0335054 0.109992 0.460546 -0.0158088 0.10808 0.450916 -0.0422016 0.106249 0.519439 -0.02729 0.108398 0.516889 -0.06738769999999999 0.10665 0.5182 -0.108823 0.104429 0.442579 -0.108743 0.112924 0.479123 -0.0335054 0.109992 0.460546 -0.108823 0.104429 0.442579 -0.108782 0.104431 0.461051 -0.108743 0.112924 0.479123 -0.108719 0.113972 0.489824 -0.108725 0.108989 0.487149 -0.10872 0.104006 0.489353 0.041812 0.115502 0.478284 0.041802 0.111884 0.47371 0.0417844 0.110183 0.465616 -0.108689 0.11224 0.503533 -0.108704 0.108992 0.496527 -0.108691 0.10404 0.502782 -0.108661 0.107153 0.516382 -0.108653 0.104426 0.520135 -0.0868767 0.104765 0.520263 -0.108719 0.113972 0.489824 -0.108731 0.10887 0.484473 -0.108725 0.108989 0.487149 -0.108725 0.108989 0.487149 -0.108731 0.10887 0.484473 -0.10872 0.104006 0.489353 -0.108719 0.113972 0.489824 -0.0223878 0.114438 0.49787 -0.0334344 0.114789 0.49359 -0.108719 0.113972 0.489824 -0.0655534 0.113835 0.496772 -0.0223878 0.114438 0.49787 -0.108691 0.10404 0.502782 -0.108704 0.106516 0.496481 -0.108718 0.104039 0.49018 0.041812 0.115502 0.478284 0.041812 0.112814 0.478284 0.0418086 0.112526 0.476744 -0.181731 -0.0432947 0.455465 -0.180686 -0.0526202 0.425912 -0.181833 -0.0446724 0.458122 -0.181525 -0.035793 0.449824 -0.180686 -0.0526202 0.425912 -0.181572 -0.0388005 0.451076 -0.181645 -0.0413955 0.453091 -0.180686 -0.0526202 0.425912 -0.181647 -0.041463 0.453145 -0.181574 -0.038924 0.451127 -0.180686 -0.0526202 0.425912 -0.181645 -0.0413955 0.453091 -0.181525 -0.0356825 0.449806 -0.180686 -0.0526202 0.425912 -0.181525 -0.035793 0.449824 -0.17939 -0.078511 0.545105 -0.17939 -0.094905 0.463443 -0.17939 -0.084383 0.542888 -0.17939 0.000441005 0.375325 -0.181576 0.000441008 0.449445 -0.181558 0.00734142 0.449445 -0.17939 0.000441005 0.375325 -0.181558 0.00734142 0.449445 -0.17939 0.0412 0.378925 -0.181502 -0.02114 0.449445 -0.181502 -0.0204813 0.449445 -0.180686 -0.0526202 0.425912 -0.181505 -0.025265 0.449445 -0.181505 -0.0249602 0.449445 -0.180686 -0.0526202 0.425912 -0.180686 -0.0526202 0.425912 -0.181511 -0.0331348 0.44947 -0.181505 -0.025265 0.449445 -0.181512 -0.033616 0.449472 -0.180686 -0.0526202 0.425912 -0.181525 -0.0356825 0.449806 -0.181511 -0.0331348 0.44947 -0.180686 -0.0526202 0.425912 -0.181512 -0.033616 0.449472 -0.180686 -0.0526202 0.425912 -0.181502 -0.0204813 0.449445 -0.1815 -0.0172285 0.449445 -0.181645 0.0413955 0.453091 -0.180686 0.0526202 0.425912 -0.181574 0.038924 0.451127 -0.180686 0.0526202 0.425912 -0.181572 0.0388005 0.451076 -0.181574 0.038924 0.451127 -0.17939 -0.0412 0.378925 -0.1815 -0.0172285 0.449445 -0.181525 -0.012891 0.449445 -0.181532 -0.0117967 0.449445 -0.17939 -0.0412 0.378925 -0.181525 -0.012891 0.449445 -0.1815 -0.0172285 0.449445 -0.17939 -0.0412 0.378925 -0.17939 -0.08801200000000001 0.388846 -0.1815 -0.0172285 0.449445 -0.17939 -0.08801200000000001 0.388846 -0.180686 -0.0526202 0.425912 -0.182 -0.0458 0.46297 -0.17939 -0.094905 0.463443 -0.17939 -0.063845 0.545105 -0.17939 -0.094905 0.463443 -0.182 -0.0458 0.46297 -0.17939 -0.08801200000000001 0.388846 -0.182 -0.0458 0.46297 -0.180686 -0.0526202 0.425912 -0.17939 -0.08801200000000001 0.388846 -0.181838 -0.0447635 0.45843 -0.180686 -0.0526202 0.425912 -0.18193 -0.0453752 0.461 -0.182 -0.0458 0.46297 -0.18193 -0.0453752 0.461 -0.180686 -0.0526202 0.425912 -0.17939 0.084383 0.542888 -0.17939 0.094905 0.463443 -0.17939 0.078511 0.545105 -0.17939 0.078511 0.545105 -0.17939 0.094905 0.463443 -0.17939 0.063845 0.545105 -0.17939 0.063845 0.545105 -0.17939 0.094905 0.463443 -0.182 0.0458 0.46297 -0.181572 0.0388005 0.451076 -0.180686 0.0526202 0.425912 -0.181525 0.035793 0.449824 -0.181525 0.035793 0.449824 -0.180686 0.0526202 0.425912 -0.181525 0.0356825 0.449806 -0.181525 0.0356825 0.449806 -0.180686 0.0526202 0.425912 -0.181512 0.033616 0.449472 -0.181512 0.033616 0.449472 -0.180686 0.0526202 0.425912 -0.181511 0.0331348 0.44947 -0.181505 0.025265 0.449445 -0.181511 0.0331348 0.44947 -0.180686 0.0526202 0.425912 -0.181505 0.025265 0.449445 -0.180686 0.0526202 0.425912 -0.181505 0.0249602 0.449445 -0.181505 0.0249602 0.449445 -0.180686 0.0526202 0.425912 -0.181502 0.02114 0.449445 -0.181502 0.02114 0.449445 -0.180686 0.0526202 0.425912 -0.181502 0.0204813 0.449445 -0.1815 0.0172285 0.449445 -0.181502 0.0204813 0.449445 -0.180686 0.0526202 0.425912 -0.180686 0.0526202 0.425912 -0.18193 0.0453752 0.461 -0.182 0.0458 0.46297 -0.180686 0.0526202 0.425912 -0.181838 0.0447635 0.45843 -0.18193 0.0453752 0.461 -0.180686 0.0526202 0.425912 -0.181833 0.0446724 0.458122 -0.181838 0.0447635 0.45843 -0.17939 0.08801200000000001 0.388846 -0.180686 0.0526202 0.425912 -0.182 0.0458 0.46297 -0.17939 0.08801200000000001 0.388846 -0.1815 0.0172285 0.449445 -0.180686 0.0526202 0.425912 -0.17939 0.08801200000000001 0.388846 -0.182 0.0458 0.46297 -0.17939 0.094905 0.463443 -0.17939 0.0412 0.378925 -0.181532 0.0117967 0.449445 -0.181525 0.012891 0.449445 -0.17939 0.0412 0.378925 -0.181525 0.012891 0.449445 -0.1815 0.0172285 0.449445 -0.17939 0.08801200000000001 0.388846 -0.17939 0.0412 0.378925 -0.1815 0.0172285 0.449445 -0.17939 -0.000441005 0.375325 -0.181558 -0.00734142 0.449445 -0.181576 -0.000441008 0.449445 -0.17939 0.000441005 0.375325 -0.17939 -0.000441005 0.375325 -0.181576 -0.000441008 0.449445 -0.180686 0.0526202 0.425912 -0.181647 0.041463 0.453145 -0.181731 0.0432947 0.455465 -0.17939 -0.063845 0.545105 -0.17939 -0.094905 0.463443 -0.17939 -0.078511 0.545105 -0.181576 0.000441008 0.449445 -0.17939 0.000441005 0.375325 -0.181576 -0.000441008 0.449445 -0.180686 0.0526202 0.425912 -0.181731 0.0432947 0.455465 -0.181833 0.0446724 0.458122 -0.181532 0.0117967 0.449445 -0.17939 0.0412 0.378925 -0.181558 0.00734142 0.449445 -0.181647 -0.041463 0.453145 -0.180686 -0.0526202 0.425912 -0.181731 -0.0432947 0.455465 -0.17939 -0.0412 0.378925 -0.181558 -0.00734142 0.449445 -0.17939 -0.000441005 0.375325 -0.181558 -0.00734142 0.449445 -0.17939 -0.0412 0.378925 -0.181532 -0.0117967 0.449445 -0.181505 -0.0249602 0.449445 -0.181502 -0.02114 0.449445 -0.180686 -0.0526202 0.425912 -0.180686 0.0526202 0.425912 -0.181645 0.0413955 0.453091 -0.181647 0.041463 0.453145 -0.181572 -0.0388005 0.451076 -0.180686 -0.0526202 0.425912 -0.181574 -0.038924 0.451127 -0.181833 -0.0446724 0.458122 -0.180686 -0.0526202 0.425912 -0.181838 -0.0447635 0.45843 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882 6883 6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 6894 6895 6896 6897 6898 6899 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967 6968 6969 6970 6971 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039 7040 7041 7042 7043 7044 7045 7046 7047 7048 7049 7050 7051 7052 7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 7163 7164 7165 7166 7167 7168 7169 7170 7171 7172 7173 7174 7175 7176 7177 7178 7179 7180 7181 7182 7183 7184 7185 7186 7187 7188 7189 7190 7191 7192 7193 7194 7195 7196 7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 7216 7217 7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 7300 7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313 7314 7315 7316 7317 7318 7319 7320 7321 7322 7323 7324 7325 7326 7327 7328 7329 7330 7331 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357 7358 7359 7360 7361 7362 7363 7364 7365 7366 7367 7368 7369 7370 7371 7372 7373 7374 7375 7376 7377 7378 7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 7391 7392 7393 7394 7395 7396 7397 7398 7399 7400 7401 7402 7403 7404 7405 7406 7407 7408 7409 7410 7411 7412 7413 7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467 7468 7469 7470 7471 7472 7473 7474 7475 7476 7477 7478 7479 7480 7481 7482 7483 7484 7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500 7501 7502 7503 7504 7505 7506 7507 7508 7509 7510 7511 7512 7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593 7594 7595 7596 7597 7598 7599 7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631 7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646 7647 7648 7649 7650 7651 7652 7653 7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 7664 7665 7666 7667 7668 7669 7670 7671 7672 7673 7674 7675 7676 7677 7678 7679 7680 7681 7682 7683 7684 7685 7686 7687 7688 7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 7750 7751 7752 7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800 7801 7802 7803 7804 7805 7806 7807 7808 7809 7810 7811 7812 7813 7814 7815 7816 7817 7818 7819 7820 7821 7822 7823 7824 7825 7826 7827 7828 7829 7830 7831 7832 7833 7834 7835 7836 7837 7838 7839 7840 7841 7842 7843 7844 7845 7846 7847 7848 7849 7850 7851 7852 7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 7877 7878 7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 7932 7933 7934 7935 7936 7937 7938 7939 7940 7941 7942 7943 7944 7945 7946 7947 7948 7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 7966 7967 7968 7969 7970 7971 7972 7973 7974 7975 7976 7977 7978 7979 7980 7981 7982 7983 7984 7985 7986 7987 7988 7989 7990 7991 7992 7993 7994 7995 7996 7997 7998 7999 8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 8055 8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090 8091 8092 8093 8094 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 8142 8143 8144 8145 8146 8147 8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 8212 8213 8214 8215 8216 8217 8218 8219 8220 8221 8222 8223 8224 8225 8226 8227 8228 8229 8230 8231 8232 8233 8234 8235 8236 8237 8238 8239 8240 8241 8242 8243 8244 8245 8246 8247 8248 8249 8250 8251 8252 8253 8254 8255 8256 8257 8258 8259 8260 8261 8262 8263 8264 8265 8266 8267 8268 8269 8270 8271 8272 8273 8274 8275 8276 8277 8278 8279 8280 8281 8282 8283 8284 8285 8286 8287 8288 8289 8290 8291 8292 8293 8294 8295 8296 8297 8298 8299 8300 8301 8302 8303 8304 8305 8306 8307 8308 8309 8310 8311 8312 8313 8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8327 8328 8329 8330 8331 8332 8333 8334 8335 8336 8337 8338 8339 8340 8341 8342 8343 8344 8345 8346 8347 8348 8349 8350 8351 8352 8353 8354 8355 8356 8357 8358 8359 8360 8361 8362 8363 8364 8365 8366 8367 8368 8369 8370 8371 8372 8373 8374 8375 8376 8377 8378 8379 8380 8381 8382 8383 8384 8385 8386 8387 8388 8389 8390 8391 8392 8393 8394 8395 8396 8397 8398 8399 8400 8401 8402 8403 8404 8405 8406 8407 8408 8409 8410 8411 8412 8413 8414 8415 8416 8417 8418 8419 8420 8421 8422 8423 8424 8425 8426 8427 8428 8429 8430 8431 8432 8433 8434 8435 8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449 8450 8451 8452 8453 8454 8455 8456 8457 8458 8459 8460 8461 8462 8463 8464 8465 8466 8467 8468 8469 8470 8471 8472 8473 8474 8475 8476 8477 8478 8479 8480 8481 8482 8483 8484 8485 8486 8487 8488 8489 8490 8491 8492 8493 8494 8495 8496 8497 8498 8499 8500 8501 8502 8503 8504 8505 8506 8507 8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 8518 8519 8520 8521 8522 8523 8524 8525 8526 8527 8528 8529 8530 8531 8532 8533 8534 8535 8536 8537 8538 8539 8540 8541 8542 8543 8544 8545 8546 8547 8548 8549 8550 8551 8552 8553 8554 8555 8556 8557 8558 8559 8560 8561 8562 8563 8564 8565 8566 8567 8568 8569 8570 8571 8572 8573 8574 8575 8576 8577 8578 8579 8580 8581 8582 8583 8584 8585 8586 8587 8588 8589 8590 8591 8592 8593 8594 8595 8596 8597 8598 8599 8600 8601 8602 8603 8604 8605 8606 8607 8608 8609 8610 8611 8612 8613 8614 8615 8616 8617 8618 8619 8620 8621 8622 8623 8624 8625 8626 8627 8628 8629 8630 8631 8632 8633 8634 8635 8636 8637 8638 8639 8640 8641 8642 8643 8644 8645 8646 8647 8648 8649 8650 8651 8652 8653 8654 8655 8656 8657 8658 8659 8660 8661 8662 8663 8664 8665 8666 8667 8668 8669 8670 8671 8672 8673 8674 8675 8676 8677 8678 8679 8680 8681 8682 8683 8684 8685 8686 8687 8688 8689 8690 8691 8692 8693 8694 8695 8696 8697 8698 8699 8700 8701 8702 8703 8704 8705 8706 8707 8708 8709 8710 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 8732 8733 8734 8735 8736 8737 8738 8739 8740 8741 8742 8743 8744 8745 8746 8747 8748 8749 8750 8751 8752 8753 8754 8755 8756 8757 8758 8759 8760 8761 8762 8763 8764 8765 8766 8767 8768 8769 8770 8771 8772 8773 8774 8775 8776 8777 8778 8779 8780 8781 8782 8783 8784 8785 8786 8787 8788 8789 8790 8791 8792 8793 8794 8795 8796 8797 8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812 8813 8814 8815 8816 8817 8818 8819 8820 8821 8822 8823 8824 8825 8826 8827 8828 8829 8830 8831 8832 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 8845 8846 8847 8848 8849 8850 8851 8852 8853 8854 8855 8856 8857 8858 8859 8860 8861 8862 8863 8864 8865 8866 8867 8868 8869 8870 8871 8872 8873 8874 8875 8876 8877 8878 8879 8880 8881 8882 8883 8884 8885 8886 8887 8888 8889 8890 8891 8892 8893 8894 8895 8896 8897 8898 8899 8900 8901 8902 8903 8904 8905 8906 8907 8908 8909 8910 8911 8912 8913 8914 8915 8916 8917 8918 8919 8920 8921 8922 8923 8924 8925 8926 8927 8928 8929 8930 8931 8932 8933 8934 8935 8936 8937 8938 8939 8940 8941 8942 8943 8944 8945 8946 8947 8948 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 8965 8966 8967 8968 8969 8970 8971 8972 8973 8974 8975 8976 8977 8978 8979 8980 8981 8982 8983 8984 8985 8986 8987 8988 8989 8990 8991 8992 8993 8994 8995 8996 8997 8998 8999 9000 9001 9002 9003 9004 9005 9006 9007 9008 9009 9010 9011 9012 9013 9014 9015 9016 9017 9018 9019 9020 9021 9022 9023 9024 9025 9026 9027 9028 9029 9030 9031 9032 9033 9034 9035 9036 9037 9038 9039 9040 9041 9042 9043 9044 9045 9046 9047 9048 9049 9050 9051 9052 9053 9054 9055 9056 9057 9058 9059 9060 9061 9062 9063 9064 9065 9066 9067 9068 9069 9070 9071 9072 9073 9074 9075 9076 9077 9078 9079 9080 9081 9082 9083 9084 9085 9086 9087 9088 9089 9090 9091 9092 9093 9094 9095 9096 9097 9098 9099 9100 9101 9102 9103 9104 9105 9106 9107 9108 9109 9110 9111 9112 9113 9114 9115 9116 9117 9118 9119 9120 9121 9122 9123 9124 9125 9126 9127 9128 9129 9130 9131 9132 9133 9134 9135 9136 9137 9138 9139 9140 9141 9142 9143 9144 9145 9146 9147 9148 9149 9150 9151 9152 9153 9154 9155 9156 9157 9158 9159 9160 9161 9162 9163 9164 9165 9166 9167 9168 9169 9170 9171 9172 9173 9174 9175 9176 9177 9178 9179 9180 9181 9182 9183 9184 9185 9186 9187 9188 9189 9190 9191 9192 9193 9194 9195 9196 9197 9198 9199 9200 9201 9202 9203 9204 9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 9215 9216 9217 9218 9219 9220 9221 9222 9223 9224 9225 9226 9227 9228 9229 9230 9231 9232 9233 9234 9235 9236 9237 9238 9239 9240 9241 9242 9243 9244 9245 9246 9247 9248 9249 9250 9251 9252 9253 9254 9255 9256 9257 9258 9259 9260 9261 9262 9263 9264 9265 9266 9267 9268 9269 9270 9271 9272 9273 9274 9275 9276 9277 9278 9279 9280 9281 9282 9283 9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 9294 9295 9296 9297 9298 9299 9300 9301 9302 9303 9304 9305 9306 9307 9308 9309 9310 9311 9312 9313 9314 9315 9316 9317 9318 9319 9320 9321 9322 9323 9324 9325 9326 9327 9328 9329 9330 9331 9332 9333 9334 9335 9336 9337 9338 9339 9340 9341 9342 9343 9344 9345 9346 9347 9348 9349 9350 9351 9352 9353 9354 9355 9356 9357 9358 9359 9360 9361 9362 9363 9364 9365 9366 9367 9368 9369 9370 9371 9372 9373 9374 9375 9376 9377 9378 9379 9380 9381 9382 9383 9384 9385 9386 9387 9388 9389 9390 9391 9392 9393 9394 9395 9396 9397 9398 9399 9400 9401 9402 9403 9404 9405 9406 9407 9408 9409 9410 9411 9412 9413 9414 9415 9416 9417 9418 9419 9420 9421 9422 9423 9424 9425 9426 9427 9428 9429 9430 9431 9432 9433 9434 9435 9436 9437 9438 9439 9440 9441 9442 9443 9444 9445 9446 9447 9448 9449 9450 9451 9452 9453 9454 9455 9456 9457 9458 9459 9460 9461 9462 9463 9464 9465 9466 9467 9468 9469 9470 9471 9472 9473 9474 9475 9476 9477 9478 9479 9480 9481 9482 9483 9484 9485 9486 9487 9488 9489 9490 9491 9492 9493 9494 9495 9496 9497 9498 9499 9500 9501 9502 9503 9504 9505 9506 9507 9508 9509 9510 9511 9512 9513 9514 9515 9516 9517 9518 9519 9520 9521 9522 9523 9524 9525 9526 9527 9528 9529 9530 9531 9532 9533 9534 9535 9536 9537 9538 9539 9540 9541 9542 9543 9544 9545 9546 9547 9548 9549 9550 9551 9552 9553 9554 9555 9556 9557 9558 9559 9560 9561 9562 9563 9564 9565 9566 9567 9568 9569 9570 9571 9572 9573 9574 9575 9576 9577 9578 9579 9580 9581 9582 9583 9584 9585 9586 9587 9588 9589 9590 9591 9592 9593 9594 9595 9596 9597 9598 9599 9600 9601 9602 9603 9604 9605 9606 9607 9608 9609 9610 9611 9612 9613 9614 9615 9616 9617 9618 9619 9620 9621 9622 9623 9624 9625 9626 9627 9628 9629 9630 9631 9632 9633 9634 9635 9636 9637 9638 9639 9640 9641 9642 9643 9644 9645 9646 9647 9648 9649 9650 9651 9652 9653 9654 9655 9656 9657 9658 9659 9660 9661 9662 9663 9664 9665 9666 9667 9668 9669 9670 9671 9672 9673 9674 9675 9676 9677 9678 9679 9680 9681 9682 9683 9684 9685 9686 9687 9688 9689 9690 9691 9692 9693 9694 9695 9696 9697 9698 9699 9700 9701 9702 9703 9704 9705 9706 9707 9708 9709 9710 9711 9712 9713 9714 9715 9716 9717 9718 9719 9720 9721 9722 9723 9724 9725 9726 9727 9728 9729 9730 9731 9732 9733 9734 9735 9736 9737 9738 9739 9740 9741 9742 9743 9744 9745 9746 9747 9748 9749 9750 9751 9752 9753 9754 9755 9756 9757 9758 9759 9760 9761 9762 9763 9764 9765 9766 9767 9768 9769 9770 9771 9772 9773 9774 9775 9776 9777 9778 9779 9780 9781 9782 9783 9784 9785 9786 9787 9788 9789 9790 9791 9792 9793 9794 9795 9796 9797 9798 9799 9800 9801 9802 9803 9804 9805 9806 9807 9808 9809 9810 9811 9812 9813 9814 9815 9816 9817 9818 9819 9820 9821 9822 9823 9824 9825 9826 9827 9828 9829 9830 9831 9832 9833 9834 9835 9836 9837 9838 9839 9840 9841 9842 9843 9844 9845 9846 9847 9848 9849 9850 9851 9852 9853 9854 9855 9856 9857 9858 9859 9860 9861 9862 9863 9864 9865 9866 9867 9868 9869 9870 9871 9872 9873 9874 9875 9876 9877 9878 9879 9880 9881 9882 9883 9884 9885 9886 9887 9888 9889 9890 9891 9892 9893 9894 9895 9896 9897 9898 9899 9900 9901 9902 9903 9904 9905 9906 9907 9908 9909 9910 9911 9912 9913 9914 9915 9916 9917 9918 9919 9920 9921 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935 9936 9937 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9954 9955 9956 9957 9958 9959 9960 9961 9962 9963 9964 9965 9966 9967 9968 9969 9970 9971 9972 9973 9974 9975 9976 9977 9978 9979 9980 9981 9982 9983 9984 9985 9986 9987 9988 9989 9990 9991 9992 9993 9994 9995 9996 9997 9998 9999 10000 10001 10002 10003 10004 10005 10006 10007 10008 10009 10010 10011 10012 10013 10014 10015 10016 10017 10018 10019 10020 10021 10022 10023 10024 10025 10026 10027 10028 10029 10030 10031 10032 10033 10034 10035 10036 10037 10038 10039 10040 10041 10042 10043 10044 10045 10046 10047 10048 10049 10050 10051 10052 10053 10054 10055 10056 10057 10058 10059 10060 10061 10062 10063 10064 10065 10066 10067 10068 10069 10070 10071 10072 10073 10074 10075 10076 10077 10078 10079 10080 10081 10082 10083 10084 10085 10086 10087 10088 10089 10090 10091 10092 10093 10094 10095 10096 10097 10098 10099 10100 10101 10102 10103 10104 10105 10106 10107 10108 10109 10110 10111 10112 10113 10114 10115 10116 10117 10118 10119 10120 10121 10122 10123 10124 10125 10126 10127 10128 10129 10130 10131 10132 10133 10134 10135 10136 10137 10138 10139 10140 10141 10142 10143 10144 10145 10146 10147 10148 10149 10150 10151 10152 10153 10154 10155 10156 10157 10158 10159 10160 10161 10162 10163 10164 10165 10166 10167 10168 10169 10170 10171 10172 10173 10174 10175 10176 10177 10178 10179 10180 10181 10182 10183 10184 10185 10186 10187 10188 10189 10190 10191 10192 10193 10194 10195 10196 10197 10198 10199 10200 10201 10202 10203 10204 10205 10206 10207 10208 10209 10210 10211 10212 10213 10214 10215 10216 10217 10218 10219 10220 10221 10222 10223 10224 10225 10226 10227 10228 10229 10230 10231 10232 10233 10234 10235 10236 10237 10238 10239 10240 10241 10242 10243 10244 10245 10246 10247 10248 10249 10250 10251 10252 10253 10254 10255 10256 10257 10258 10259 10260 10261 10262 10263 10264 10265 10266 10267 10268 10269 10270 10271 10272 10273 10274 10275 10276 10277 10278 10279 10280 10281 10282 10283 10284 10285 10286 10287 10288 10289 10290 10291 10292 10293 10294 10295 10296 10297 10298 10299 10300 10301 10302 10303 10304 10305 10306 10307 10308 10309 10310 10311 10312 10313 10314 10315 10316 10317 10318 10319 10320 10321 10322 10323 10324 10325 10326 10327 10328 10329 10330 10331 10332 10333 10334 10335 10336 10337 10338 10339 10340 10341 10342 10343 10344 10345 10346 10347 10348 10349 10350 10351 10352 10353 10354 10355 10356 10357 10358 10359 10360 10361 10362 10363 10364 10365 10366 10367 10368 10369 10370 10371 10372 10373 10374 10375 10376 10377 10378 10379 10380 10381 10382 10383 10384 10385 10386 10387 10388 10389 10390 10391 10392 10393 10394 10395 10396 10397 10398 10399 10400 10401 10402 10403 10404 10405 10406 10407 10408 10409 10410 10411 10412 10413 10414 10415 10416 10417 10418 10419 10420 10421 10422 10423 10424 10425 10426 10427 10428 10429 10430 10431 10432 10433 10434 10435 10436 10437 10438 10439 10440 10441 10442 10443 10444 10445 10446 10447 10448 10449 10450 10451 10452 10453 10454 10455 10456 10457 10458 10459 10460 10461 10462 10463 10464 10465 10466 10467 10468 10469 10470 10471 10472 10473 10474 10475 10476 10477 10478 10479 10480 10481 10482 10483 10484 10485 10486 10487 10488 10489 10490 10491 10492 10493 10494 10495 10496 10497 10498 10499 10500 10501 10502 10503 10504 10505 10506 10507 10508 10509 10510 10511 10512 10513 10514 10515 10516 10517 10518 10519 10520 10521 10522 10523 10524 10525 10526 10527 10528 10529 10530 10531 10532 10533 10534 10535 10536 10537 10538 10539 10540 10541 10542 10543 10544 10545 10546 10547 10548 10549 10550 10551 10552 10553 10554 10555 10556 10557 10558 10559 10560 10561 10562 10563 10564 10565 10566 10567 10568 10569 10570 10571 10572 10573 10574 10575 10576 10577 10578 10579 10580 10581 10582 10583 10584 10585 10586 10587 10588 10589 10590 10591 10592 10593 10594 10595 10596 10597 10598 10599 10600 10601 10602 10603 10604 10605 10606 10607 10608 10609 10610 10611 10612 10613 10614 10615 10616 10617 10618 10619 10620 10621 10622 10623 10624 10625 10626 10627 10628 10629 10630 10631 10632 10633 10634 10635 10636 10637 10638 10639 10640 10641 10642 10643 10644 10645 10646 10647 10648 10649 10650 10651 10652 10653 10654 10655 10656 10657 10658 10659 10660 10661 10662 10663 10664 10665 10666 10667 10668 10669 10670 10671 10672 10673 10674 10675 10676 10677 10678 10679 10680 10681 10682 10683 10684 10685 10686 10687 10688 10689 10690 10691 10692 10693 10694 10695 10696 10697 10698 10699 10700 10701 10702 10703 10704 10705 10706 10707 10708 10709 10710 10711 10712 10713 10714 10715 10716 10717 10718 10719 10720 10721 10722 10723 10724 10725 10726 10727 10728 10729 10730 10731 10732 10733 10734 10735 10736 10737 10738 10739 10740 10741 10742 10743 10744 10745 10746 10747 10748 10749 10750 10751 10752 10753 10754 10755 10756 10757 10758 10759 10760 10761 10762 10763 10764 10765 10766 10767 10768 10769 10770 10771 10772 10773 10774 10775 10776 10777 10778 10779 10780 10781 10782 10783 10784 10785 10786 10787 10788 10789 10790 10791 10792 10793 10794 10795 10796 10797 10798 10799 10800 10801 10802 10803 10804 10805 10806 10807 10808 10809 10810 10811 10812 10813 10814 10815 10816 10817 10818 10819 10820 10821 10822 10823 10824 10825 10826 10827 10828 10829 10830 10831 10832 10833 10834 10835 10836 10837 10838 10839 10840 10841 10842 10843 10844 10845 10846 10847 10848 10849 10850 10851 10852 10853 10854 10855 10856 10857 10858 10859 10860 10861 10862 10863 10864 10865 10866 10867 10868 10869 10870 10871 10872 10873 10874 10875 10876 10877 10878 10879 10880 10881 10882 10883 10884 10885 10886 10887 10888 10889 10890 10891 10892 10893 10894 10895 10896 10897 10898 10899 10900 10901 10902 10903 10904 10905 10906 10907 10908 10909 10910 10911 10912 10913 10914 10915 10916 10917 10918 10919 10920 10921 10922 10923 10924 10925 10926 10927 10928 10929 10930 10931 10932 10933 10934 10935 10936 10937 10938 10939 10940 10941 10942 10943 10944 10945 10946 10947 10948 10949 10950 10951 10952 10953 10954 10955 10956 10957 10958 10959 10960 10961 10962 10963 10964 10965 10966 10967 10968 10969 10970 10971 10972 10973 10974 10975 10976 10977 10978 10979 10980 10981 10982 10983 10984 10985 10986 10987 10988 10989 10990 10991 10992 10993 10994 10995 10996 10997 10998 10999 11000 11001 11002 11003 11004 11005 11006 11007 11008 11009 11010 11011 11012 11013 11014 11015 11016 11017 11018 11019 11020 11021 11022 11023 11024 11025 11026 11027 11028 11029 11030 11031 11032 11033 11034 11035 11036 11037 11038 11039 11040 11041 11042 11043 11044 11045 11046 11047 11048 11049 11050 11051 11052 11053 11054 11055 11056 11057 11058 11059 11060 11061 11062 11063 11064 11065 11066 11067 11068 11069 11070 11071 11072 11073 11074 11075 11076 11077 11078 11079 11080 11081 11082 11083 11084 11085 11086 11087 11088 11089 11090 11091 11092 11093 11094 11095 11096 11097 11098 11099 11100 11101 11102 11103 11104 11105 11106 11107 11108 11109 11110 11111 11112 11113 11114 11115 11116 11117 11118 11119 11120 11121 11122 11123 11124 11125 11126 11127 11128 11129 11130 11131 11132 11133 11134 11135 11136 11137 11138 11139 11140 11141 11142 11143 11144 11145 11146 11147 11148 11149 11150 11151 11152 11153 11154 11155 11156 11157 11158 11159 11160 11161 11162 11163 11164 11165 11166 11167 11168 11169 11170 11171 11172 11173 11174 11175 11176 11177 11178 11179 11180 11181 11182 11183 11184 11185 11186 11187 11188 11189 11190 11191 11192 11193 11194 11195 11196 11197 11198 11199 11200 11201 11202 11203 11204 11205 11206 11207 11208 11209 11210 11211 11212 11213 11214 11215 11216 11217 11218 11219 11220 11221 11222 11223 11224 11225 11226 11227 11228 11229 11230 11231 11232 11233 11234 11235 11236 11237 11238 11239 11240 11241 11242 11243 11244 11245 11246 11247 11248 11249 11250 11251 11252 11253 11254 11255 11256 11257 11258 11259 11260 11261 11262 11263 11264 11265 11266 11267 11268 11269 11270 11271 11272 11273 11274 11275 11276 11277 11278 11279 11280 11281 11282 11283 11284 11285 11286 11287 11288 11289 11290 11291 11292 11293 11294 11295 11296 11297 11298 11299 11300 11301 11302 11303 11304 11305 11306 11307 11308 11309 11310 11311 11312 11313 11314 11315 11316 11317 11318 11319 11320 11321 11322 11323 11324 11325 11326 11327 11328 11329 11330 11331 11332 11333 11334 11335 11336 11337 11338 11339 11340 11341 11342 11343 11344 11345 11346 11347 11348 11349 11350 11351 11352 11353 11354 11355 11356 11357 11358 11359 11360 11361 11362 11363 11364 11365 11366 11367 11368 11369 11370 11371 11372 11373 11374 11375 11376 11377 11378 11379 11380 11381 11382 11383 11384 11385 11386 11387 11388 11389 11390 11391 11392 11393 11394 11395 11396 11397 11398 11399 11400 11401 11402 11403 11404 11405 11406 11407 11408 11409 11410 11411 11412 11413 11414 11415 11416 11417 11418 11419 11420 11421 11422 11423 11424 11425 11426 11427 11428 11429 11430 11431 11432 11433 11434 11435 11436 11437 11438 11439 11440 11441 11442 11443 11444 11445 11446 11447 11448 11449 11450 11451 11452 11453 11454 11455 11456 11457 11458 11459 11460 11461 11462 11463 11464 11465 11466 11467 11468 11469 11470 11471 11472 11473 11474 11475 11476 11477 11478 11479 11480 11481 11482 11483 11484 11485 11486 11487 11488 11489 11490 11491 11492 11493 11494 11495 11496 11497 11498 11499 11500 11501 11502 11503 11504 11505 11506 11507 11508 11509 11510 11511 11512 11513 11514 11515 11516 11517 11518 11519 11520 11521 11522 11523 11524 11525 11526 11527 11528 11529 11530 11531 11532 11533 11534 11535 11536 11537 11538 11539 11540 11541 11542 11543 11544 11545 11546 11547 11548 11549 11550 11551 11552 11553 11554 11555 11556 11557 11558 11559 11560 11561 11562 11563 11564 11565 11566 11567 11568 11569 11570 11571 11572 11573 11574 11575 11576 11577 11578 11579 11580 11581 11582 11583 11584 11585 11586 11587 11588 11589 11590 11591 11592 11593 11594 11595 11596 11597 11598 11599 11600 11601 11602 11603 11604 11605 11606 11607 11608 11609 11610 11611 11612 11613 11614 11615 11616 11617 11618 11619 11620 11621 11622 11623 11624 11625 11626 11627 11628 11629 11630 11631 11632 11633 11634 11635 11636 11637 11638 11639 11640 11641 11642 11643 11644 11645 11646 11647 11648 11649 11650 11651 11652 11653 11654 11655 11656 11657 11658 11659 11660 11661 11662 11663 11664 11665 11666 11667 11668 11669 11670 11671 11672 11673 11674 11675 11676 11677 11678 11679 11680 11681 11682 11683 11684 11685 11686 11687 11688 11689 11690 11691 11692 11693 11694 11695 11696 11697 11698 11699 11700 11701 11702 11703 11704 11705 11706 11707 11708 11709 11710 11711 11712 11713 11714 11715 11716 11717 11718 11719 11720 11721 11722 11723 11724 11725 11726 11727 11728 11729 11730 11731 11732 11733 11734 11735 11736 11737 11738 11739 11740 11741 11742 11743 11744 11745 11746 11747 11748 11749 11750 11751 11752 11753 11754 11755 11756 11757 11758 11759 11760 11761 11762 11763 11764 11765 11766 11767 11768 11769 11770 11771 11772 11773 11774 11775 11776 11777 11778 11779 11780 11781 11782 11783 11784 11785 11786 11787 11788 11789 11790 11791 11792 11793 11794 11795 11796 11797 11798 11799 11800 11801 11802 11803 11804 11805 11806 11807 11808 11809 11810 11811 11812 11813 11814 11815 11816 11817 11818 11819 11820 11821 11822 11823 11824 11825 11826 11827 11828 11829 11830 11831 11832 11833 11834 11835 11836 11837 11838 11839 11840 11841 11842 11843 11844 11845 11846 11847 11848 11849 11850 11851 11852 11853 11854 11855 11856 11857 11858 11859 11860 11861 11862 11863 11864 11865 11866 11867 11868 11869 11870 11871 11872 11873 11874 11875 11876 11877 11878 11879 11880 11881 11882 11883 11884 11885 11886 11887 11888 11889 11890 11891 11892 11893 11894 11895 11896 11897 11898 11899 11900 11901 11902 11903 11904 11905 11906 11907 11908 11909 11910 11911 11912 11913 11914 11915 11916 11917 11918 11919 11920 11921 11922 11923 11924 11925 11926 11927 11928 11929 11930 11931 11932 11933 11934 11935 11936 11937 11938 11939 11940 11941 11942 11943 11944 11945 11946 11947 11948 11949 11950 11951 11952 11953 11954 11955 11956 11957 11958 11959 11960 11961 11962 11963 11964 11965 11966 11967 11968 11969 11970 11971 11972 11973 11974 11975 11976 11977 11978 11979 11980 11981 11982 11983 11984 11985 11986 11987 11988 11989 11990 11991 11992 11993 11994 11995 11996 11997 11998 11999 12000 12001 12002 12003 12004 12005 12006 12007 12008 12009 12010 12011 12012 12013 12014 12015 12016 12017 12018 12019 12020 12021 12022 12023 12024 12025 12026 12027 12028 12029 12030 12031 12032 12033 12034 12035 12036 12037 12038 12039 12040 12041 12042 12043 12044 12045 12046 12047 12048 12049 12050 12051 12052 12053 12054 12055 12056 12057 12058 12059 12060 12061 12062 12063 12064 12065 12066 12067 12068 12069 12070 12071 12072 12073 12074 12075 12076 12077 12078 12079 12080 12081 12082 12083 12084 12085 12086 12087 12088 12089 12090 12091 12092 12093 12094 12095 12096 12097 12098 12099 12100 12101 12102 12103 12104 12105 12106 12107 12108 12109 12110 12111 12112 12113 12114 12115 12116 12117 12118 12119 12120 12121 12122 12123 12124 12125 12126 12127 12128 12129 12130 12131 12132 12133 12134 12135 12136 12137 12138 12139 12140 12141 12142 12143 12144 12145 12146 12147 12148 12149 12150 12151 12152 12153 12154 12155 12156 12157 12158 12159 12160 12161 12162 12163 12164 12165 12166 12167 12168 12169 12170 12171 12172 12173 12174 12175 12176 12177 12178 12179 12180 12181 12182 12183 12184 12185 12186 12187 12188 12189 12190 12191 12192 12193 12194 12195 12196 12197 12198 12199 12200 12201 12202 12203 12204 12205 12206 12207 12208 12209 12210 12211 12212 12213 12214 12215 12216 12217 12218 12219 12220 12221 12222 12223 12224 12225 12226 12227 12228 12229 12230 12231 12232 12233 12234 12235 12236 12237 12238 12239 12240 12241 12242 12243 12244 12245 12246 12247 12248 12249 12250 12251 12252 12253 12254 12255 12256 12257 12258 12259 12260 12261 12262 12263 12264 12265 12266 12267 12268 12269 12270 12271 12272 12273 12274 12275 12276 12277 12278 12279 12280 12281 12282 12283 12284 12285 12286 12287 12288 12289 12290 12291 12292 12293 12294 12295 12296 12297 12298 12299 12300 12301 12302 12303 12304 12305 12306 12307 12308 12309 12310 12311 12312 12313 12314 12315 12316 12317 12318 12319 12320 12321 12322 12323 12324 12325 12326 12327 12328 12329 12330 12331 12332 12333 12334 12335 12336 12337 12338 12339 12340 12341 12342 12343 12344 12345 12346 12347 12348 12349 12350 12351 12352 12353 12354 12355 12356 12357 12358 12359 12360 12361 12362 12363 12364 12365 12366 12367 12368 12369 12370 12371 12372 12373 12374 12375 12376 12377 12378 12379 12380 12381 12382 12383 12384 12385 12386 12387 12388 12389 12390 12391 12392 12393 12394 12395 12396 12397 12398 12399 12400 12401 12402 12403 12404 12405 12406 12407 12408 12409 12410 12411 12412 12413 12414 12415 12416 12417 12418 12419 12420 12421 12422 12423 12424 12425 12426 12427 12428 12429 12430 12431 12432 12433 12434 12435 12436 12437 12438 12439 12440 12441 12442 12443 12444 12445 12446 12447 12448 12449 12450 12451 12452 12453 12454 12455 12456 12457 12458 12459 12460 12461 12462 12463 12464 12465 12466 12467 12468 12469 12470 12471 12472 12473 12474 12475 12476 12477 12478 12479 12480 12481 12482 12483 12484 12485 12486 12487 12488 12489 12490 12491 12492 12493 12494 12495 12496 12497 12498 12499 12500 12501 12502 12503 12504 12505 12506 12507 12508 12509 12510 12511 12512 12513 12514 12515 12516 12517 12518 12519 12520 12521 12522 12523 12524 12525 12526 12527 12528 12529 12530 12531 12532 12533 12534 12535 12536 12537 12538 12539 12540 12541 12542 12543 12544 12545 12546 12547 12548 12549 12550 12551 12552 12553 12554 12555 12556 12557 12558 12559 12560 12561 12562 12563 12564 12565 12566 12567 12568 12569 12570 12571 12572 12573 12574 12575 12576 12577 12578 12579 12580 12581 12582 12583 12584 12585 12586 12587 12588 12589 12590 12591 12592 12593 12594 12595 12596 12597 12598 12599 12600 12601 12602 12603 12604 12605 12606 12607 12608 12609 12610 12611 12612 12613 12614 12615 12616 12617 12618 12619 12620 12621 12622 12623 12624 12625 12626 12627 12628 12629 12630 12631 12632 12633 12634 12635 12636 12637 12638 12639 12640 12641 12642 12643 12644 12645 12646 12647 12648 12649 12650 12651 12652 12653 12654 12655 12656 12657 12658 12659 12660 12661 12662 12663 12664 12665 12666 12667 12668 12669 12670 12671 12672 12673 12674 12675 12676 12677 12678 12679 12680 12681 12682 12683 12684 12685 12686 12687 12688 12689 12690 12691 12692 12693 12694 12695 12696 12697 12698 12699 12700 12701 12702 12703 12704 12705 12706 12707 12708 12709 12710 12711 12712 12713 12714 12715 12716 12717 12718 12719 12720 12721 12722 12723 12724 12725 12726 12727 12728 12729 12730 12731 12732 12733 12734 12735 12736 12737 12738 12739 12740 12741 12742 12743 12744 12745 12746 12747 12748 12749 12750 12751 12752 12753 12754 12755 12756 12757 12758 12759 12760 12761 12762 12763 12764 12765 12766 12767 12768 12769 12770 12771 12772 12773 12774 12775 12776 12777 12778 12779 12780 12781 12782 12783 12784 12785 12786 12787 12788 12789 12790 12791 12792 12793 12794 12795 12796 12797 12798 12799 12800 12801 12802 12803 12804 12805 12806 12807 12808 12809 12810 12811 12812 12813 12814 12815 12816 12817 12818 12819 12820 12821 12822 12823 12824 12825 12826 12827 12828 12829 12830 12831 12832 12833 12834 12835 12836 12837 12838 12839 12840 12841 12842 12843 12844 12845 12846 12847 12848 12849 12850 12851 12852 12853 12854 12855 12856 12857 12858 12859 12860 12861 12862 12863 12864 12865 12866 12867 12868 12869 12870 12871 12872 12873 12874 12875 12876 12877 12878 12879 12880 12881 12882 12883 12884 12885 12886 12887 12888 12889 12890 12891 12892 12893 12894 12895 12896 12897 12898 12899 12900 12901 12902 12903 12904 12905 12906 12907 12908 12909 12910 12911 12912 12913 12914 12915 12916 12917 12918 12919 12920 12921 12922 12923 12924 12925 12926 12927 12928 12929 12930 12931 12932 12933 12934 12935 12936 12937 12938 12939 12940 12941 12942 12943 12944 12945 12946 12947 12948 12949 12950 12951 12952 12953 12954 12955 12956 12957 12958 12959 12960 12961 12962 12963 12964 12965 12966 12967 12968 12969 12970 12971 12972 12973 12974 12975 12976 12977 12978 12979 12980 12981 12982 12983 12984 12985 12986 12987 12988 12989 12990 12991 12992 12993 12994 12995 12996 12997 12998 12999 13000 13001 13002 13003 13004 13005 13006 13007 13008 13009 13010 13011 13012 13013 13014 13015 13016 13017 13018 13019 13020 13021 13022 13023 13024 13025 13026 13027 13028 13029 13030 13031 13032 13033 13034 13035 13036 13037 13038 13039 13040 13041 13042 13043 13044 13045 13046 13047 13048 13049 13050 13051 13052 13053 13054 13055 13056 13057 13058 13059 13060 13061 13062 13063 13064 13065 13066 13067 13068 13069 13070 13071 13072 13073 13074 13075 13076 13077 13078 13079 13080 13081 13082 13083 13084 13085 13086 13087 13088 13089 13090 13091 13092 13093 13094 13095 13096 13097 13098 13099 13100 13101 13102 13103 13104 13105 13106 13107 13108 13109 13110 13111 13112 13113 13114 13115 13116 13117 13118 13119 13120 13121 13122 13123 13124 13125 13126 13127 13128 13129 13130 13131 13132 13133 13134 13135 13136 13137 13138 13139 13140 13141 13142 13143 13144 13145 13146 13147 13148 13149 13150 13151 13152 13153 13154 13155 13156 13157 13158 13159 13160 13161 13162 13163 13164 13165 13166 13167 13168 13169 13170 13171 13172 13173 13174 13175 13176 13177 13178 13179 13180 13181 13182 13183 13184 13185 13186 13187 13188 13189 13190 13191 13192 13193 13194 13195 13196 13197 13198 13199 13200 13201 13202 13203 13204 13205 13206 13207 13208 13209 13210 13211 13212 13213 13214 13215 13216 13217 13218 13219 13220 13221 13222 13223 13224 13225 13226 13227 13228 13229 13230 13231 13232 13233 13234 13235 13236 13237 13238 13239 13240 13241 13242 13243 13244 13245 13246 13247 13248 13249 13250 13251 13252 13253 13254 13255 13256 13257 13258 13259 13260 13261 13262 13263 13264 13265 13266 13267 13268 13269 13270 13271 13272 13273 13274 13275 13276 13277 13278 13279 13280 13281 13282 13283 13284 13285 13286 13287 13288 13289 13290 13291 13292 13293 13294 13295 13296 13297 13298 13299 13300 13301 13302 13303 13304 13305 13306 13307

    -
    -
    - - - 0 0 0 - 1 0 0 0 - - true - - - -
    - - - - -0.0112133 0.0176989 -0.0200366 -0.0114049 0.0175333 -0.0199573 -0.011495 0.0235 -0.01992 -0.0114049 0.0175333 -0.0199573 -0.0112133 0.0176989 -0.0200366 -0.010915 0.017937 -0.020243 -0.010915 0.017937 -0.020243 -0.0112133 0.0176989 -0.0200366 -0.0108326 0.0178754 -0.0201943 -0.0114049 0.0175333 -0.0199573 -0.011495 0.0174552 -0.01992 -0.011495 0.0235 -0.01992 0.015352 -0.014334 -0.025001 0.0161186 -0.0130884 -0.0163787 0.0152942 -0.0139705 -0.0170115 0.015352 -0.014334 -0.025001 0.016268 -0.0129285 -0.016264 0.0161186 -0.0130884 -0.0163787 0.015352 -0.014334 -0.025001 0.017561 -0.011523 -0.014859 0.016268 -0.0129285 -0.016264 0.017561 -0.011523 -0.014859 0.015352 -0.014334 -0.025001 0.01865 -0.009660999999999999 -0.025001 -0.0058043 -0.0201587 -0.0222359 -0.005661 -0.020221 -0.022292 -0.005948 -0.0200962 -0.022217 -0.0058043 -0.0201587 -0.0222359 -0.005661 -0.020221 -0.022292 -0.000666437 -0.0209033 -0.0229126 -0.005948 -0.0236 -0.022217 -0.0058043 -0.0201587 -0.0222359 -0.00445975 -0.0218794 -0.022413 -0.0058043 -0.0201587 -0.0222359 -0.0029715 -0.0218481 -0.022609 -0.00445975 -0.0218794 -0.022413 -0.0029715 -0.0218481 -0.022609 -0.005948 -0.0236 -0.022217 -0.00445975 -0.0218794 -0.022413 -0.0029715 -0.0218481 -0.022609 -0.0058043 -0.0201587 -0.0222359 -0.000666437 -0.0209033 -0.0229126 -6.42413e-05 -0.0209905 -0.0229919 -0.00286262 -0.0206057 -0.0226419 -0.002803 -0.020811 -0.022829 -6.42413e-05 -0.0209905 -0.0229919 -0.000329676 -0.020952 -0.0229569 -0.00286262 -0.0206057 -0.0226419 -0.00286262 -0.0206057 -0.0226419 -0.000329676 -0.020952 -0.0229569 -0.000666437 -0.0209033 -0.0229126 -0.000666437 -0.0209033 -0.0229126 -0.005661 -0.020221 -0.022292 -0.00286262 -0.0206057 -0.0226419 5.0028e-06 -0.0236 -0.023001 -0.000666437 -0.0209033 -0.0229126 -0.000329676 -0.020952 -0.0229569 -0.002803 -0.020811 -0.022829 -0.00283315 -0.0206189 -0.0239327 -6.42413e-05 -0.0209905 -0.0229919 -5.29691e-06 -0.0209936 -0.0229996 -0.00283315 -0.0206189 -0.0239327 -6.42413e-05 -0.0209905 -0.0229919 -0.00283315 -0.0206189 -0.0239327 -0.005661 -0.020221 -0.025001 -5.29691e-06 -0.0209936 -0.0229996 5.00351e-06 -0.029 -0.025001 5.00281e-06 -0.021 -0.025001 -0.005661 -0.020221 -0.025001 -0.006935 -0.028157 -0.025001 5.00351e-06 -0.029 -0.025001 -0.005661 -0.020221 -0.025001 -0.006935 -0.028157 -0.025001 -0.005661 -0.020221 -0.025001 -0.010907 -0.017943 -0.025001 -0.005661 -0.020221 -0.022292 -0.010907 -0.017943 -0.025001 -0.005661 -0.020221 -0.025001 -0.005661 -0.020221 -0.022292 -0.005661 -0.020221 -0.025001 -0.002803 -0.020811 -0.022829 -0.005661 -0.020221 -0.025001 -0.00283315 -0.0206189 -0.0239327 -0.002803 -0.020811 -0.022829 5.0028e-06 -0.0236 -0.023001 -0.0029715 -0.0218481 -0.022609 -0.000666437 -0.0209033 -0.0229126 -0.005948 -0.0236 -0.022217 -0.005948 -0.0200962 -0.022217 -0.0058043 -0.0201587 -0.0222359 -5.29691e-06 -0.0209936 -0.0229996 -0.005661 -0.020221 -0.025001 5.00281e-06 -0.021 -0.025001 -5.29691e-06 -0.0209936 -0.0229996 -6.42413e-05 -0.0209905 -0.0229919 5.00286e-06 -0.020995 -0.023001 -0.027111 -0.010283 -0.025001 -0.027111 0.010284 -0.025001 -0.028784 0.003496 -0.025001 -0.023862 -0.016474 -0.025001 -0.027111 0.010284 -0.025001 -0.027111 -0.010283 -0.025001 0.0087315 0.0204412 -0.0210685 0.00677476 0.0197631 -0.0218788 0.005958 0.0235 -0.022217 0.0087315 0.0204412 -0.0210685 0.005958 0.0235 -0.022217 0.0087315 0.0219706 -0.0210685 0.005958 0.0235 -0.022217 0.011505 0.0235 -0.01992 0.0087315 0.0219706 -0.0210685 0.011505 0.0235 -0.01992 0.0087315 0.0204412 -0.0210685 0.0087315 0.0219706 -0.0210685 0.021005 -1.0003e-06 -0.009382 0.0208531 -0.0010683 -0.00950222 0.020897 -0.002125 -0.009619000000000001 0.021005 -1.0003e-06 -0.009382 0.020897 -0.002125 -0.009619000000000001 0.020956 0.001433 -0.025001 0.020897 -0.002125 -0.009619000000000001 0.020566 -0.004273 -0.025001 0.020956 0.001433 -0.025001 0.028899 -5.00004e-07 -0.026251 0.028793 0.003495 -0.025001 0.028793 -0.003496 -0.025001 0.028793 0.003495 -0.025001 0.028899 -5.00004e-07 -0.026251 0.029005 -1.51628e-09 -0.027501 0.02712 0.010283 -0.025001 0.028793 -0.003496 -0.025001 0.028793 0.003495 -0.025001 0.0180955 -0.0161854 -0.0138825 0.019923 -0.0236 -0.011501 0.016268 -0.0236 -0.016264 0.019923 -0.0236 -0.011501 0.0180955 -0.0161854 -0.0138825 0.0187722 -0.00877084 -0.0130006 0.0187722 -0.00877084 -0.0130006 0.0196834 -0.00705658 -0.0118133 0.019923 -0.0236 -0.011501 -0.005948 -0.0236 -0.022217 0.016268 -0.0236 -0.016264 0.019923 -0.0236 -0.011501 0.0199914 0.00635278 -0.0113359 0.0199554 0.0064836 -0.0114229 0.020029 0.006329 -0.011317 0.0199989 0.00633044 -0.0113179 0.0199914 0.00635278 -0.0113359 0.020029 0.006329 -0.011317 0.0199554 0.0064836 -0.0114229 0.0199989 0.00633044 -0.0113179 0.0199914 0.00635278 -0.0113359 0.019923 0.0235 -0.011501 0.0199989 0.00633044 -0.0113179 0.0199554 0.0064836 -0.0114229 0.019923 0.0235 -0.011501 0.0199554 0.0064836 -0.0114229 0.019923 0.006552 -0.011501 0.019923 0.0235 -0.011501 0.0207018 0.00212908 -0.00962095 0.0199989 0.00633044 -0.0113179 0.019923 0.0235 -0.011501 0.019923 0.006552 -0.011501 0.0199077 0.00658399 -0.0115209 0.0199989 0.00633044 -0.0113179 0.0207018 0.00212908 -0.00962095 0.0206985 0.00214578 -0.00962908 0.0206985 0.00214578 -0.00962908 0.0207018 0.00212908 -0.00962095 0.020897 0.002123 -0.009619000000000001 0.020029 0.006329 -0.011317 0.0199989 0.00633044 -0.0113179 0.0206968 0.00215332 -0.00963319 0.0207018 0.00212908 -0.00962095 0.020703 0.00211538 -0.009618160000000001 0.020897 0.002123 -0.009619000000000001 0.020458 -0.00425 -0.010478 0.020897 -0.002125 -0.009619000000000001 0.0206029 -0.00324879 -0.0100943 0.020897 -0.002125 -0.009619000000000001 0.020458 -0.00425 -0.010478 0.020566 -0.004273 -0.025001 0.0203088 -0.00437259 -0.0105697 0.020458 -0.00425 -0.010478 0.0206029 -0.00324879 -0.0100943 0.0206029 -0.00324879 -0.0100943 0.0206323 -0.0023645 -0.00978879 0.0203088 -0.00437259 -0.0105697 0.0203088 -0.00437259 -0.0105697 0.0206323 -0.0023645 -0.00978879 0.0206968 -0.0021552 -0.00963312 0.0206968 -0.0021552 -0.00963312 0.0206323 -0.0023645 -0.00978879 0.020897 -0.002125 -0.009619000000000001 0.0206968 -0.0021552 -0.00963312 0.0206989 -0.00214591 -0.009628060000000001 0.020897 -0.002125 -0.009619000000000001 0.0203088 -0.00437259 -0.0105697 0.0206968 -0.0021552 -0.00963312 0.0206989 -0.00214591 -0.009628060000000001 0.0206989 -0.00214591 -0.009628060000000001 0.0207012 -0.0021356 -0.009622449999999999 0.0203088 -0.00437259 -0.0105697 0.0203088 -0.00437259 -0.0105697 0.020027 -0.006334 -0.01132 0.0199887 -0.00636216 -0.0113424 0.0199887 -0.00636216 -0.0113424 0.0199553 -0.00648463 -0.011423 0.020027 -0.006334 -0.01132 0.020027 -0.006334 -0.01132 0.019923 -0.00655046 -0.011501 0.0199553 -0.00648463 -0.011423 0.0202401 -0.00542722 -0.0181605 0.020027 -0.006334 -0.01132 0.019923 -0.00655046 -0.011501 0.0202401 -0.00542722 -0.0181605 0.019923 -0.00655046 -0.011501 0.0199094 -0.00657925 -0.0115188 0.0199887 -0.00636216 -0.0113424 0.0203088 -0.00437259 -0.0105697 0.022221 -0.0236 -0.005954 0.0207349 0.00142527 -0.009541249999999999 0.020703 0.00211538 -0.009618160000000001 0.022221 -0.0236 -0.005954 0.022221 -0.0236 -0.005954 0.0208009 -9.954400000000001e-07 -0.009382 0.0207349 0.00142527 -0.009541249999999999 0.0207012 -0.0021356 -0.009622449999999999 0.0208009 -9.954400000000001e-07 -0.009382 0.022221 -0.0236 -0.005954 0.022221 -0.0236 -0.005954 0.0203088 -0.00437259 -0.0105697 0.0207012 -0.0021356 -0.009622449999999999 0.020932 0.001432 -0.009542 0.0207349 0.00142527 -0.009541249999999999 0.0208009 -9.954400000000001e-07 -0.009382 0.020932 0.001432 -0.009542 0.020897 0.002123 -0.009619000000000001 0.0207349 0.00142527 -0.009541249999999999 0.0207012 -0.0021356 -0.009622449999999999 0.0207989 -2.26701e-05 -0.009386800000000001 0.0208009 -9.954400000000001e-07 -0.009382 0.022221 -0.0236 -0.005954 0.020703 0.00211538 -0.009618160000000001 0.019923 0.0235 -0.011501 0.019923 -0.00655046 -0.011501 0.0199553 -0.00648463 -0.011423 0.022221 -0.0236 -0.005954 0.019923 -0.00655046 -0.011501 0.019923 -0.0236 -0.011501 0.0199049 -0.00659166 -0.0115246 0.019923 -0.00655046 -0.011501 0.022221 -0.0236 -0.005954 0.019923 -0.0236 -0.011501 -0.005948 -0.0236 -0.022217 0.019923 -0.0236 -0.011501 0.022221 -0.0236 -0.005954 0.023005 -0.0236 -1.00182e-06 -0.005948 -0.0236 -0.022217 0.022221 -0.0236 -0.005954 0.020703 0.00211538 -0.009618160000000001 0.0207349 0.00142527 -0.009541249999999999 0.020897 0.002123 -0.009619000000000001 0.0208531 -0.0010683 -0.00950222 0.0207989 -2.26701e-05 -0.009386800000000001 0.0207012 -0.0021356 -0.009622449999999999 0.020956 0.001433 -0.025001 0.020897 0.002123 -0.009619000000000001 0.020932 0.001432 -0.009542 0.0202401 -0.00542722 -0.0181605 0.020566 -0.004273 -0.025001 0.020027 -0.006334 -0.01132 0.0206989 -0.00214591 -0.009628060000000001 0.0207012 -0.0021356 -0.009622449999999999 0.020897 -0.002125 -0.009619000000000001 0.0206029 -0.00324879 -0.0100943 0.020897 -0.002125 -0.009619000000000001 0.0206323 -0.0023645 -0.00978879 0.0199554 0.0064836 -0.0114229 0.020029 0.006329 -0.011317 0.019923 0.006552 -0.011501 0.022221 0.0235 -0.005954 0.023005 -0.0236 -1.00182e-06 0.022221 -0.0236 -0.005954 -0.010907 -0.017943 -0.025001 -0.005948 -0.0200962 -0.022217 -0.00597529 -0.0200844 -0.0222057 -0.00844048 -0.0190122 -0.022622 -0.010907 -0.017943 -0.025001 -0.00597529 -0.0200844 -0.0222057 -0.019322 0.008213 -0.012469 -0.0180009 0.0102068 -0.0139941 -0.017152 0.01211 -0.025001 -0.017152 0.01211 -0.025001 -0.019783 0.007033 -0.025001 -0.019322 0.008213 -0.012469 -0.019783 0.007033 -0.025001 -0.017152 0.01211 -0.025001 -0.019226 0.021707 -0.025001 -0.0187784 0.00886585 -0.0129809 -0.0180009 0.0102068 -0.0139941 -0.019322 0.008213 -0.012469 -0.017152 0.01211 -0.025001 -0.0180009 0.0102068 -0.0139941 -0.0168718 0.0119212 -0.0154655 -0.020946 0.001433 -0.025001 -0.019783 0.007033 -0.025001 -0.019226 0.021707 -0.025001 -0.0168718 0.0119212 -0.0154655 -0.0167445 0.012066 -0.0156314 -0.017152 0.01211 -0.025001 -0.0180865 0.0161829 -0.0138825 -0.0167445 0.012066 -0.0156314 -0.0168718 0.0119212 -0.0154655 -0.016259 0.0127847 -0.016264 -0.013248 0.01629 -0.025001 -0.0167445 0.012066 -0.0156314 -0.013248 0.01629 -0.025001 -0.016259 0.0127847 -0.016264 -0.0160418 0.0131291 -0.0164307 -0.016259 0.0235 -0.016264 -0.0160418 0.0131291 -0.0164307 -0.016259 0.0127847 -0.016264 -0.0155899 0.0138453 -0.0167775 -0.0160418 0.0131291 -0.0164307 -0.016259 0.0235 -0.016264 -0.0167445 0.012066 -0.0156314 -0.013248 0.01629 -0.025001 -0.017152 0.01211 -0.025001 -0.0153085 0.0141028 -0.0169934 -0.0155899 0.0138453 -0.0167775 -0.016259 0.0235 -0.016264 -0.017152 0.01211 -0.025001 -0.013248 0.01629 -0.025001 -0.013472 0.025678 -0.025001 0.002864 0.020804 -0.025001 5.00311e-06 0.029 -0.025001 -0.002855 0.020804 -0.025001 5.00311e-06 0.029 -0.025001 -0.006935 0.028157 -0.025001 -0.002855 0.020804 -0.025001 5.003e-06 0.029 -0.027501 -0.006935 0.028157 -0.025001 5.00311e-06 0.029 -0.025001 -0.010915 0.017937 -0.020243 -0.008281999999999999 0.019078 -0.021267 -0.008362 0.019261 -0.025001 -0.008281999999999999 0.019078 -0.021267 -0.002855 0.020804 -0.025001 -0.008362 0.019261 -0.025001 -0.013248 0.01629 -0.025001 -0.008362 0.019261 -0.025001 -0.006935 0.028157 -0.025001 -0.008362 0.019261 -0.025001 -0.002855 0.020804 -0.025001 -0.006935 0.028157 -0.025001 -0.00763519 0.0193583 -0.0215183 -0.002855 0.020804 -0.025001 -0.008281999999999999 0.019078 -0.021267 -0.008362 0.019261 -0.025001 -0.013248 0.01629 -0.025001 -0.013141 0.016157 -0.018703 -0.008362 0.019261 -0.025001 -0.013141 0.016157 -0.018703 -0.011495 0.0174552 -0.01992 -0.005948 0.0200728 -0.022217 -0.002855 0.020804 -0.025001 -0.00763519 0.0193583 -0.0215183 -0.00763519 0.0193583 -0.0215183 -0.00835148 0.0190244 -0.0212217 -0.0087215 0.0206877 -0.0210685 -0.00763519 0.0193583 -0.0215183 -0.0087215 0.0206877 -0.0210685 -0.005948 0.0200728 -0.022217 -0.00835148 0.0190244 -0.0212217 -0.00842731 0.0189906 -0.0211903 -0.0087215 0.0206877 -0.0210685 -0.00835148 0.0190244 -0.0212217 -0.008281999999999999 0.019078 -0.021267 -0.00842731 0.0189906 -0.0211903 -0.00588438 0.0201067 -0.0222254 -0.002855 0.020804 -0.025001 -0.005948 0.0200728 -0.022217 -0.005611 0.020235 -0.022305 -0.002855 0.020804 -0.025001 -0.00588438 0.0201067 -0.0222254 -0.002855 0.020804 -0.025001 -0.005611 0.020235 -0.022305 -0.002853 0.020798 -0.022816 -0.005948 0.0200728 -0.022217 -0.0087215 0.0206877 -0.0210685 -0.005948 0.0235 -0.022217 -0.015091 0.014598 -0.017353 -0.013141 0.016157 -0.018703 -0.013248 0.01629 -0.025001 -0.0129484 0.0162728 -0.0188046 -0.013681 0.015592 -0.0182424 -0.013877 0.0188014 -0.018092 -0.01253 0.0166459 -0.0191257 -0.0129484 0.0162728 -0.0188046 -0.013877 0.0188014 -0.018092 -0.0129484 0.0162728 -0.0188046 -0.013141 0.016157 -0.018703 -0.01253 0.0166459 -0.0191257 -0.013681 0.015592 -0.0182424 -0.013141 0.016157 -0.018703 -0.0129484 0.0162728 -0.0188046 -0.013681 0.015592 -0.0182424 -0.0153085 0.0141028 -0.0169934 -0.013877 0.0188014 -0.018092 -0.013681 0.015592 -0.0182424 -0.013141 0.016157 -0.018703 -0.015091 0.014598 -0.017353 -0.013248 0.01629 -0.025001 -0.006935 0.028157 -0.025001 -0.013472 0.025678 -0.025001 -0.006935 0.028157 -0.027501 -0.013472 0.025678 -0.025001 -0.006935 0.028157 -0.025001 -0.006935 0.028157 -0.027501 -0.013472 0.025678 -0.027501 -0.013472 0.025678 -0.025001 -0.006935 0.028157 -0.027501 0.028793 -0.003496 -0.027501 -0.013472 0.025678 -0.027501 -0.013472 0.025678 -0.027501 -0.019226 0.021707 -0.025001 -0.013472 0.025678 -0.025001 -0.00763519 0.0193583 -0.0215183 -0.008281999999999999 0.019078 -0.021267 -0.00835148 0.0190244 -0.0212217 -0.011495 0.0174552 -0.01992 -0.0114049 0.0175333 -0.0199573 -0.008362 0.019261 -0.025001 -0.00842731 0.0189906 -0.0211903 -0.008281999999999999 0.019078 -0.021267 -0.00889909 0.018772 -0.020995 5.003e-06 0.029 -0.027501 0.028793 -0.003496 -0.027501 -0.006935 0.028157 -0.027501 -0.00588438 0.0201067 -0.0222254 -0.005948 0.0200728 -0.022217 -0.005948 0.0235 -0.022217 -0.00578059 0.0201617 -0.022239 -0.00588438 0.0201067 -0.0222254 -0.005948 0.0235 -0.022217 -0.013681 0.015592 -0.0182424 -0.015091 0.014598 -0.017353 -0.0153085 0.0141028 -0.0169934 -0.01253 0.0166459 -0.0191257 -0.013141 0.016157 -0.018703 -0.011495 0.0174552 -0.01992 -0.020534 0.004378 -0.010353 -0.019783 0.007033 -0.025001 -0.020946 0.001433 -0.025001 -0.028784 0.003496 -0.025001 -0.028784 0.003496 -0.027501 -0.028784 -0.003496 -0.027501 -0.028784 -0.003496 -0.027501 -0.028784 0.003496 -0.027501 0.028793 -0.003496 -0.027501 0.028793 -0.003496 -0.027501 -0.028784 0.003496 -0.027501 -0.027111 0.010284 -0.027501 -0.019226 -0.021707 -0.027501 -0.023862 -0.016474 -0.027501 0.028793 -0.003496 -0.027501 -0.023862 -0.016474 -0.027501 -0.027111 -0.010283 -0.027501 0.028793 -0.003496 -0.027501 -0.023862 -0.016474 -0.025001 -0.027111 -0.010283 -0.027501 -0.023862 -0.016474 -0.027501 -0.027111 -0.010283 -0.027501 -0.023862 -0.016474 -0.025001 -0.027111 -0.010283 -0.025001 -0.027111 -0.010283 -0.025001 -0.028784 -0.003496 -0.027501 -0.027111 -0.010283 -0.027501 0.028793 -0.003496 -0.027501 -0.027111 -0.010283 -0.027501 -0.028784 -0.003496 -0.027501 -0.028784 -0.003496 -0.027501 -0.027111 -0.010283 -0.025001 -0.028784 -0.003496 -0.025001 -0.019226 -0.021707 -0.025001 -0.023862 -0.016474 -0.025001 -0.023862 -0.016474 -0.027501 -0.027111 0.010284 -0.027501 -0.023862 0.016474 -0.027501 0.028793 -0.003496 -0.027501 -0.027111 0.010284 -0.027501 -0.027111 0.010284 -0.025001 -0.023862 0.016474 -0.027501 -0.019226 -0.021707 -0.027501 -0.019226 -0.021707 -0.025001 -0.023862 -0.016474 -0.027501 -0.0206818 0.00224643 -0.00964687 -0.020875 0.002247 -0.009646999999999999 -0.0207214 0.00143525 -0.00955132 -0.022211 0.0235 -0.005954 -0.0206818 0.00224643 -0.00964687 -0.0207214 0.00143525 -0.00955132 -0.022211 0.0235 -0.005954 -0.0203904 0.00437019 -0.0103505 -0.0206818 0.00224643 -0.00964687 -0.0203904 0.00437019 -0.0103505 -0.0206327 0.00331222 -0.009999930000000001 -0.0206818 0.00224643 -0.00964687 -0.0207911 9.21272e-06 -0.009383030000000001 -0.022211 0.0235 -0.005954 -0.0207214 0.00143525 -0.00955132 0.020566 -0.004273 -0.025001 0.0199094 -0.00657925 -0.0115188 0.0199049 -0.00659166 -0.0115246 0.01865 -0.009660999999999999 -0.025001 0.020566 -0.004273 -0.025001 0.0199049 -0.00659166 -0.0115246 0.01865 -0.009660999999999999 -0.025001 0.019235 -0.021707 -0.025001 0.020566 -0.004273 -0.025001 0.015352 -0.014334 -0.025001 0.019235 -0.021707 -0.025001 0.01865 -0.009660999999999999 -0.025001 0.0138865 -0.0187853 -0.018092 0.0142748 -0.0150613 -0.0177939 0.0150406 -0.01422 -0.0172061 0.0138865 -0.0187853 -0.018092 0.0150406 -0.01422 -0.0172061 0.0151399 -0.0141357 -0.0171299 0.0120827 -0.0170617 -0.0194766 0.0142748 -0.0150613 -0.0177939 0.0131788 -0.0169233 -0.0186353 0.0142748 -0.0150613 -0.0177939 0.0138865 -0.0187853 -0.018092 0.0131788 -0.0169233 -0.0186353 0.0138865 -0.0187853 -0.018092 0.0120827 -0.0170617 -0.0194766 0.0131788 -0.0169233 -0.0186353 0.011505 -0.0173969 -0.01992 0.0120827 -0.0170617 -0.0194766 0.0138865 -0.0187853 -0.018092 0.0120827 -0.0170617 -0.0194766 0.011505 -0.0173969 -0.01992 0.010916 -0.017943 -0.025001 0.010916 -0.017943 -0.025001 0.0150406 -0.01422 -0.0172061 0.0142748 -0.0150613 -0.0177939 0.012791 -0.016659 -0.019119 0.0120827 -0.0170617 -0.0194766 0.010916 -0.017943 -0.025001 0.0150406 -0.01422 -0.0172061 0.010916 -0.017943 -0.025001 0.015352 -0.014334 -0.025001 0.0163585 -0.020006 -0.025001 0.019235 -0.021707 -0.025001 0.015352 -0.014334 -0.025001 0.013482 -0.025678 -0.025001 0.0163585 -0.020006 -0.025001 0.015352 -0.014334 -0.025001 0.013482 -0.025678 -0.025001 0.015352 -0.014334 -0.025001 0.010916 -0.017943 -0.025001 0.013482 -0.025678 -0.025001 0.010916 -0.017943 -0.025001 0.006945 -0.028157 -0.025001 0.0151399 -0.0141357 -0.0171299 0.0150406 -0.01422 -0.0172061 0.015352 -0.014334 -0.025001 0.006945 -0.028157 -0.025001 0.013482 -0.025678 -0.027501 0.013482 -0.025678 -0.025001 0.019235 -0.021707 -0.027501 0.013482 -0.025678 -0.027501 0.028793 -0.003496 -0.027501 0.013482 -0.025678 -0.027501 0.006945 -0.028157 -0.027501 0.028793 -0.003496 -0.027501 0.006945 -0.028157 -0.025001 0.006945 -0.028157 -0.027501 0.013482 -0.025678 -0.027501 5.00351e-06 -0.029 -0.025001 0.006945 -0.028157 -0.027501 0.006945 -0.028157 -0.025001 5.00351e-06 -0.029 -0.025001 5.0034e-06 -0.029 -0.027501 0.006945 -0.028157 -0.027501 5.00351e-06 -0.029 -0.025001 -0.006935 -0.028157 -0.027501 5.0034e-06 -0.029 -0.027501 0.006945 -0.028157 -0.025001 0.00567 -0.020221 -0.025001 5.00351e-06 -0.029 -0.025001 0.0142748 -0.0150613 -0.0177939 0.0120827 -0.0170617 -0.0194766 0.012791 -0.016659 -0.019119 0.028793 -0.003496 -0.027501 5.0034e-06 -0.029 -0.027501 -0.006935 -0.028157 -0.027501 -0.0207214 0.00143525 -0.00955132 -0.020918 0.001432 -0.009551 -0.0207911 9.21272e-06 -0.009383030000000001 -0.0207911 9.21272e-06 -0.009383030000000001 -0.020918 0.001432 -0.009551 -0.020995 -4.46054e-10 -0.009382 -0.020946 0.001433 -0.025001 -0.020995 -4.46054e-10 -0.009382 -0.020918 0.001432 -0.009551 -0.020946 0.001433 -0.025001 -0.020918 0.001432 -0.009551 -0.020875 0.002247 -0.009646999999999999 -0.020536 -0.004368 -0.010349 -0.020556 -0.004273 -0.025001 -0.0202226 -0.00534768 -0.017675 -0.0202226 -0.00534768 -0.017675 -0.0200113 -0.00603244 -0.011266 -0.020536 -0.004368 -0.010349 -0.0203922 -0.00435697 -0.0103461 -0.020536 -0.004368 -0.010349 -0.0200113 -0.00603244 -0.011266 -0.020536 -0.004368 -0.010349 -0.020995 -4.46054e-10 -0.009382 -0.020875 -0.002242 -0.009646 -0.020536 -0.004368 -0.010349 -0.020875 -0.002242 -0.009646 -0.020551 -0.004272 -0.010317 -0.0206937 -0.002184 -0.009865499999999999 -0.020995 -4.46054e-10 -0.009382 -0.020536 -0.004368 -0.010349 -0.0207915 -5.29124e-09 -0.009382 -0.020995 -4.46054e-10 -0.009382 -0.0206937 -0.002184 -0.009865499999999999 -0.0203922 -0.00435697 -0.0103461 -0.0207915 -5.29124e-09 -0.009382 -0.0206937 -0.002184 -0.009865499999999999 -0.020556 -0.004273 -0.025001 -0.020551 -0.004272 -0.010317 -0.020875 -0.002242 -0.009646 -0.0203922 -0.00435697 -0.0103461 -0.0206937 -0.002184 -0.009865499999999999 -0.020536 -0.004368 -0.010349 -0.019914 -0.0236 -0.011501 -0.0203922 -0.00435697 -0.0103461 -0.0200113 -0.00603244 -0.011266 -0.020875 -0.002242 -0.009646 -0.020995 -4.46054e-10 -0.009382 -0.020995 -1.12878e-09 -0.025001 -0.013472 -0.025678 -0.025001 -0.013472 -0.025678 -0.027501 -0.006935 -0.028157 -0.025001 -0.006935 -0.028157 -0.025001 -0.013472 -0.025678 -0.027501 -0.006935 -0.028157 -0.027501 0.028793 -0.003496 -0.027501 -0.006935 -0.028157 -0.027501 -0.013472 -0.025678 -0.027501 -0.013472 -0.025678 -0.025001 -0.019226 -0.021707 -0.027501 -0.013472 -0.025678 -0.027501 -0.020556 -0.004273 -0.025001 -0.019226 -0.021707 -0.025001 -0.018641 -0.009660999999999999 -0.025001 -0.013472 -0.025678 -0.025001 -0.018641 -0.009660999999999999 -0.025001 -0.019226 -0.021707 -0.025001 -0.020995 -1.12878e-09 -0.025001 -0.019226 -0.021707 -0.025001 -0.020556 -0.004273 -0.025001 -0.023862 0.016474 -0.025001 -0.019226 -0.021707 -0.025001 -0.020995 -1.12878e-09 -0.025001 -0.023862 0.016474 -0.025001 -0.020995 -1.12878e-09 -0.025001 -0.020946 0.001433 -0.025001 -0.020946 0.001433 -0.025001 -0.020995 -1.12878e-09 -0.025001 -0.020995 -4.46054e-10 -0.009382 -0.019226 -0.021707 -0.025001 -0.019226 -0.021707 -0.027501 -0.013472 -0.025678 -0.025001 -0.0198805 -0.00644426 -0.0115446 -0.020556 -0.004273 -0.025001 -0.018641 -0.009660999999999999 -0.025001 -0.020556 -0.004273 -0.025001 -0.020536 -0.004368 -0.010349 -0.020551 -0.004272 -0.010317 -0.0197689 -0.0068022 -0.0116901 -0.0198805 -0.00644426 -0.0115446 -0.018641 -0.009660999999999999 -0.025001 -0.0198805 -0.00644426 -0.0115446 -0.0198884 -0.00642213 -0.0115343 -0.0197689 -0.0068022 -0.0116901 -0.0197689 -0.0068022 -0.0116901 -0.0191881 -0.00817245 -0.0124469 -0.0180865 -0.0149705 -0.0138825 -0.0197689 -0.0068022 -0.0116901 -0.0180865 -0.0149705 -0.0138825 -0.019914 -0.0236 -0.011501 -0.019914 -0.0236 -0.011501 -0.0198884 -0.00642213 -0.0115343 -0.0197689 -0.0068022 -0.0116901 -0.019914 -0.00634104 -0.011501 -0.0198884 -0.00642213 -0.0115343 -0.019914 -0.0236 -0.011501 -0.0191881 -0.00817245 -0.0124469 -0.0197689 -0.0068022 -0.0116901 -0.019331 -0.008194 -0.012457 -0.019331 -0.008194 -0.012457 -0.0190721 -0.0083654 -0.0125981 -0.0191881 -0.00817245 -0.0124469 -0.0180865 -0.0149705 -0.0138825 -0.016259 -0.0236 -0.016264 -0.019914 -0.0236 -0.011501 -0.0172047 -0.0114138 -0.0150317 -0.016259 -0.0128496 -0.016264 -0.016259 -0.0236 -0.016264 -0.0180865 -0.0149705 -0.0138825 -0.0172047 -0.0114138 -0.0150317 -0.016259 -0.0236 -0.016264 -0.016259 -0.0128496 -0.016264 -0.0172047 -0.0114138 -0.0150317 -0.0173883 -0.0112959 -0.019243 -0.018641 -0.009660999999999999 -0.025001 -0.0161832 -0.0129632 -0.0163222 -0.0173883 -0.0112959 -0.019243 -0.018441 -0.009539000000000001 -0.013485 -0.018641 -0.009660999999999999 -0.025001 -0.0173883 -0.0112959 -0.019243 -0.0173883 -0.0112959 -0.019243 -0.0180013 -0.0102043 -0.0139936 -0.018441 -0.009539000000000001 -0.013485 -0.0169495 -0.0119675 -0.0206616 -0.0161832 -0.0129632 -0.0163222 -0.018641 -0.009660999999999999 -0.025001 -0.0161151 -0.0130608 -0.0163744 -0.0169495 -0.0119675 -0.0206616 -0.015343 -0.014334 -0.025001 -0.0169495 -0.0119675 -0.0206616 -0.018641 -0.009660999999999999 -0.025001 -0.0169707 -0.0119825 -0.0228313 -0.018641 -0.009660999999999999 -0.025001 -0.015343 -0.014334 -0.025001 -0.0169707 -0.0119825 -0.0228313 -0.015343 -0.014334 -0.025001 -0.0169495 -0.0119675 -0.0206616 -0.0169707 -0.0119825 -0.0228313 -0.018441 -0.009539000000000001 -0.013485 -0.0180013 -0.0102043 -0.0139936 -0.0183591 -0.009589840000000001 -0.0135272 -0.0190721 -0.0083654 -0.0125981 -0.0183591 -0.009589840000000001 -0.0135272 -0.0180865 -0.0149705 -0.0138825 -0.0183591 -0.009589840000000001 -0.0135272 -0.0180013 -0.0102043 -0.0139936 -0.0180865 -0.0149705 -0.0138825 -0.0173883 -0.0112959 -0.019243 -0.0172047 -0.0114138 -0.0150317 -0.0180013 -0.0102043 -0.0139936 -0.0169495 -0.0119675 -0.0206616 -0.0161151 -0.0130608 -0.0163744 -0.0161832 -0.0129632 -0.0163222 -0.0161832 -0.0129632 -0.0163222 -0.0161151 -0.0130608 -0.0163744 -0.016259 -0.0236 -0.016264 -0.0200113 -0.00603244 -0.011266 -0.019914 -0.00634104 -0.011501 -0.019914 -0.0236 -0.011501 -0.016259 -0.0236 -0.016264 -0.016259 -0.0128496 -0.016264 -0.0161832 -0.0129632 -0.0163222 -0.020875 0.002247 -0.009646999999999999 -0.020534 0.004378 -0.010353 -0.020946 0.001433 -0.025001 0.010916 -0.017943 -0.025001 0.00567 -0.020221 -0.025001 0.006945 -0.028157 -0.025001 -0.0207214 0.00143525 -0.00955132 -0.020875 0.002247 -0.009646999999999999 -0.020918 0.001432 -0.009551 -0.0206818 0.00224643 -0.00964687 -0.0206327 0.00331222 -0.009999930000000001 -0.020875 0.002247 -0.009646999999999999 -0.020995 -4.46054e-10 -0.009382 -0.0207915 -5.29124e-09 -0.009382 -0.0207911 9.21272e-06 -0.009383030000000001 -0.018641 -0.009660999999999999 -0.025001 -0.018441 -0.009539000000000001 -0.013485 -0.019331 -0.008194 -0.012457 -0.0202226 -0.00534768 -0.017675 -0.020556 -0.004273 -0.025001 -0.0198884 -0.00642213 -0.0115343 -0.020556 -0.004273 -0.025001 -0.0198805 -0.00644426 -0.0115446 -0.0198884 -0.00642213 -0.0115343 -0.020534 0.004378 -0.010353 -0.020875 0.002247 -0.009646999999999999 -0.0206327 0.00331222 -0.009999930000000001 0.0152942 -0.0139705 -0.0170115 0.0138865 -0.0187853 -0.018092 0.0151399 -0.0141357 -0.0171299 0.00595801 -0.0236 -0.022217 0.00551457 -0.0200915 -0.0222754 0.00563149 -0.0200746 -0.02226 0.00563149 -0.0200746 -0.02226 0.00551457 -0.0200915 -0.0222754 0.00567 -0.020221 -0.025001 0.00534893 -0.0201155 -0.0222972 5.00281e-06 -0.021 -0.025001 0.00567 -0.020221 -0.025001 0.00463037 -0.0203299 -0.0223918 5.00281e-06 -0.021 -0.025001 0.00534893 -0.0201155 -0.0222972 0.00551457 -0.0200915 -0.0222754 0.00534893 -0.0201155 -0.0222972 0.00567 -0.020221 -0.025001 0.016268 -0.0236 -0.016264 0.0138865 -0.0187853 -0.018092 0.0152942 -0.0139705 -0.0170115 0.0138865 -0.0187853 -0.018092 0.016268 -0.0236 -0.016264 0.0138865 -0.0211926 -0.018092 0.016268 -0.0236 -0.016264 0.011505 -0.0236 -0.01992 0.0138865 -0.0211926 -0.018092 0.011505 -0.0236 -0.01992 0.0138865 -0.0187853 -0.018092 0.0138865 -0.0211926 -0.018092 9.689569999999999e-05 -0.020984 -0.0229889 7.70034e-05 -0.021 -0.023001 0.000536158 -0.020923 -0.022931 0.000536158 -0.020923 -0.022931 0.00235369 -0.0206649 -0.0226964 7.70034e-05 -0.021 -0.023001 7.70034e-05 -0.021 -0.023001 0.00276 -0.020818 -0.022835 0.00235369 -0.0206649 -0.0226964 2.98648e-05 -0.0209967 -0.0229977 7.70034e-05 -0.021 -0.023001 9.689569999999999e-05 -0.020984 -0.0229889 5.00286e-06 -0.020995 -0.023001 2.98648e-05 -0.0209967 -0.0229977 7.70034e-05 -0.021 -0.023001 5.00286e-06 -0.020995 -0.023001 2.98648e-05 -0.0209967 -0.0229977 5.0028e-06 -0.0236 -0.023001 7.70034e-05 -0.021 -0.023001 5.00286e-06 -0.020995 -0.023001 5.00281e-06 -0.021 -0.025001 5.0028e-06 -0.0236 -0.023001 2.98648e-05 -0.0209967 -0.0229977 9.689569999999999e-05 -0.020984 -0.0229889 5.0028e-06 -0.0236 -0.023001 9.689569999999999e-05 -0.020984 -0.0229889 0.000536158 -0.020923 -0.022931 0.00298151 -0.0218458 -0.022609 0.000536158 -0.020923 -0.022931 0.00463037 -0.0203299 -0.0223918 0.00595801 -0.0236 -0.022217 0.00298151 -0.0218458 -0.022609 0.00463037 -0.0203299 -0.0223918 0.00595801 -0.0236 -0.022217 0.016268 -0.0236 -0.016264 5.0028e-06 -0.0236 -0.023001 0.00298151 -0.0218458 -0.022609 0.00595801 -0.0236 -0.022217 0.00298151 -0.0227229 -0.022609 0.00595801 -0.0236 -0.022217 5.0028e-06 -0.0236 -0.023001 0.00298151 -0.0227229 -0.022609 5.0028e-06 -0.0236 -0.023001 0.00298151 -0.0218458 -0.022609 0.00298151 -0.0227229 -0.022609 5.0028e-06 -0.0236 -0.023001 0.000536158 -0.020923 -0.022931 0.00298151 -0.0218458 -0.022609 0.00595801 -0.0236 -0.022217 0.011505 -0.0236 -0.01992 0.016268 -0.0236 -0.016264 0.0087315 -0.0206916 -0.0210685 0.011505 -0.0236 -0.01992 0.0087315 -0.0221458 -0.0210685 0.011505 -0.0236 -0.01992 0.00595801 -0.0236 -0.022217 0.0087315 -0.0221458 -0.0210685 0.00595801 -0.0236 -0.022217 0.0087315 -0.0206916 -0.0210685 0.0087315 -0.0221458 -0.0210685 0.00595801 -0.0236 -0.022217 0.00674679 -0.0197765 -0.0218904 0.0087315 -0.0206916 -0.0210685 0.00595801 -0.0236 -0.022217 0.00595801 -0.0199904 -0.022217 0.00674679 -0.0197765 -0.0218904 0.00595801 -0.0236 -0.022217 0.00591295 -0.0200019 -0.0222229 0.00595801 -0.0199904 -0.022217 0.00595801 -0.0199904 -0.022217 0.00591295 -0.0200019 -0.0222229 0.00567 -0.020221 -0.025001 0.00591295 -0.0200019 -0.0222229 0.00563149 -0.0200746 -0.02226 0.00567 -0.020221 -0.025001 -0.027111 0.010284 -0.025001 -0.023862 0.016474 -0.025001 -0.023862 0.016474 -0.027501 -0.023862 0.016474 -0.025001 -0.027111 0.010284 -0.025001 -0.023862 -0.016474 -0.025001 -0.019226 0.021707 -0.027501 -0.023862 0.016474 -0.025001 -0.019226 0.021707 -0.025001 -0.023862 0.016474 -0.027501 -0.023862 0.016474 -0.025001 -0.019226 0.021707 -0.027501 0.00674679 -0.0197765 -0.0218904 0.00595801 -0.0199904 -0.022217 0.00567 -0.020221 -0.025001 0.00778701 -0.019505 -0.021644 0.00674679 -0.0197765 -0.0218904 0.00567 -0.020221 -0.025001 0.009824029999999999 -0.0183462 -0.0206161 0.00674679 -0.0197765 -0.0218904 0.00778701 -0.019505 -0.021644 0.009824029999999999 -0.0183462 -0.0206161 0.00778701 -0.019505 -0.021644 0.0106523 -0.017859 -0.0202731 0.011505 -0.0236 -0.01992 0.009824029999999999 -0.0183462 -0.0206161 0.0106523 -0.017859 -0.0202731 0.0106523 -0.017859 -0.0202731 0.00778701 -0.019505 -0.021644 0.00567 -0.020221 -0.025001 0.011505 -0.0236 -0.01992 0.0106523 -0.017859 -0.0202731 0.01082 -0.0177833 -0.0202037 0.0111625 -0.0204984 -0.0200618 0.0108227 -0.017782 -0.0202025 0.0114266 -0.0174412 -0.0199525 0.0114266 -0.0174412 -0.0199525 0.0108227 -0.017782 -0.0202025 0.010916 -0.017943 -0.025001 0.010916 -0.017943 -0.025001 0.01082 -0.0177833 -0.0202037 0.0108227 -0.017782 -0.0202025 0.01082 -0.0177833 -0.0202037 0.0106523 -0.017859 -0.0202731 0.010916 -0.017943 -0.025001 0.011505 -0.0173969 -0.01992 0.011505 -0.0236 -0.01992 0.0111625 -0.0204984 -0.0200618 0.0111625 -0.0204984 -0.0200618 0.011505 -0.0236 -0.01992 0.01082 -0.0177833 -0.0202037 -0.0190721 -0.0083654 -0.0125981 -0.018441 -0.009539000000000001 -0.013485 -0.0183591 -0.009589840000000001 -0.0135272 0.0108227 -0.017782 -0.0202025 0.01082 -0.0177833 -0.0202037 0.0111625 -0.0204984 -0.0200618 -0.0180013 -0.0102043 -0.0139936 -0.0172047 -0.0114138 -0.0150317 -0.0180865 -0.0149705 -0.0138825 -0.018641 -0.009660999999999999 -0.025001 -0.019331 -0.008194 -0.012457 -0.0197689 -0.0068022 -0.0116901 -0.023862 0.016474 -0.027501 -0.019226 0.021707 -0.027501 0.028793 -0.003496 -0.027501 -0.0114968 -0.0174766 -0.0199187 -0.015343 -0.014334 -0.025001 -0.010951 -0.017916 -0.020224 -0.010951 -0.017916 -0.020224 -0.015343 -0.014334 -0.025001 -0.010903 -0.017936 -0.020243 -0.007553 -0.0193965 -0.0215524 -0.00844048 -0.0190122 -0.022622 -0.00638297 -0.0199066 -0.0220369 -0.007553 -0.0193965 -0.0215524 -0.010903 -0.017936 -0.020243 -0.00844048 -0.0190122 -0.022622 -0.00967294 -0.0184758 -0.022622 -0.010907 -0.017943 -0.025001 -0.00844048 -0.0190122 -0.022622 -0.00967294 -0.0184758 -0.022622 -0.00844048 -0.0190122 -0.022622 -0.010903 -0.017936 -0.020243 -0.00967294 -0.0184758 -0.022622 -0.010903 -0.017936 -0.020243 -0.010907 -0.017943 -0.025001 -0.013472 -0.025678 -0.025001 -0.010907 -0.017943 -0.025001 -0.015343 -0.014334 -0.025001 -0.015343 -0.014334 -0.025001 -0.010907 -0.017943 -0.025001 -0.010903 -0.017936 -0.020243 -0.010903 -0.017936 -0.020243 -0.007553 -0.0193965 -0.0215524 -0.0104216 -0.018071 -0.0203645 -0.0087215 -0.020539 -0.0210685 -0.007553 -0.0193965 -0.0215524 -0.00638297 -0.0199066 -0.0220369 -0.0104216 -0.018071 -0.0203645 -0.010903 -0.017936 -0.020243 -0.0112084 -0.0177006 -0.0200387 -0.00597529 -0.0200844 -0.0222057 -0.00638297 -0.0199066 -0.0220369 -0.00844048 -0.0190122 -0.022622 -0.005948 -0.0236 -0.022217 -0.0087215 -0.020539 -0.0210685 -0.00638297 -0.0199066 -0.0220369 -0.0087215 -0.020539 -0.0210685 -0.0104216 -0.018071 -0.0203645 -0.007553 -0.0193965 -0.0215524 -0.010951 -0.017916 -0.020224 -0.0114968 -0.0174766 -0.0199187 -0.0112316 -0.0176903 -0.0200291 -0.005948 -0.0236 -0.022217 -0.00638297 -0.0199066 -0.0220369 -0.00597529 -0.0200844 -0.0222057 -0.010951 -0.017916 -0.020224 -0.010903 -0.017936 -0.020243 -0.0112084 -0.0177006 -0.0200387 -0.011495 -0.0236 -0.01992 -0.0114968 -0.0174766 -0.0199187 -0.0112316 -0.0176903 -0.0200291 -0.011495 -0.0236 -0.01992 -0.0112316 -0.0176903 -0.0200291 -0.0112084 -0.0177006 -0.0200387 -0.010951 -0.017916 -0.020224 -0.0112084 -0.0177006 -0.0200387 -0.0112316 -0.0176903 -0.0200291 -0.011495 -0.0236 -0.01992 -0.0087215 -0.020539 -0.0210685 -0.0087215 -0.0220695 -0.0210685 -0.0087215 -0.020539 -0.0210685 -0.005948 -0.0236 -0.022217 -0.0087215 -0.0220695 -0.0210685 -0.005948 -0.0236 -0.022217 -0.011495 -0.0236 -0.01992 -0.0087215 -0.0220695 -0.0210685 5.00671e-06 -0.0236 0.022999 -0.005948 -0.0236 -0.022217 0.00595801 -0.0236 0.022215 5.00671e-06 -0.0236 0.022999 0.00595801 -0.0236 0.022215 0.00595801 0.0235 0.022215 -0.005948 -0.0236 -0.022217 5.00671e-06 -0.0236 0.022999 -0.00594799 -0.0236 0.022215 -0.00594799 -0.0236 0.022215 -0.011495 -0.0236 0.019918 -0.005948 -0.0236 -0.022217 0.00373591 0.0204544 -0.0225096 0.00298151 0.0217379 -0.022609 0.00464289 0.020327 -0.0223902 0.00373591 0.0204544 -0.0225096 0.00360236 0.0204715 -0.0225272 0.00298151 0.0217379 -0.022609 0.00333175 0.0205017 -0.0225629 0.00322721 0.0204969 -0.0225766 0.00298151 0.0217379 -0.022609 0.00298151 0.0217379 -0.022609 0.0033465 0.0205001 -0.0225609 0.00333175 0.0205017 -0.0225629 0.002863 0.020798 -0.022817 0.00333175 0.0205017 -0.0225629 0.0033465 0.0205001 -0.0225609 0.002863 0.020798 -0.022817 0.0033465 0.0205001 -0.0225609 0.00338015 0.0204963 -0.0225565 0.002863 0.020798 -0.022817 0.00338015 0.0204963 -0.0225565 0.00360236 0.0204715 -0.0225272 0.00360236 0.0204715 -0.0225272 0.00373591 0.0204544 -0.0225096 0.002863 0.020798 -0.022817 0.00360236 0.0204715 -0.0225272 0.00338015 0.0204963 -0.0225565 0.00298151 0.0217379 -0.022609 0.002863 0.020798 -0.022817 0.00322721 0.0204969 -0.0225766 0.00333175 0.0205017 -0.0225629 0.00298151 0.0217379 -0.022609 0.0033465 0.0205001 -0.0225609 0.00338015 0.0204963 -0.0225565 0.00322721 0.0204969 -0.0225766 0.00136569 0.0208033 -0.0228218 0.00298151 0.0217379 -0.022609 -0.020534 0.004378 -0.010353 -0.019914 0.00634173 -0.011501 -0.019783 0.007033 -0.025001 -0.019783 0.007033 -0.025001 -0.019914 0.00634173 -0.011501 -0.0198856 0.00643137 -0.011538 -0.0193462 0.0149209 -0.0122409 -0.0198856 0.00643137 -0.011538 -0.019914 0.00634173 -0.011501 -0.022211 0.0235 -0.005954 -0.019914 0.00634173 -0.011501 -0.0200112 0.0060328 -0.0112663 -0.022211 0.0235 -0.005954 -0.019914 0.0235 -0.011501 -0.019914 0.00634173 -0.011501 -0.0193462 0.0149209 -0.0122409 -0.019914 0.00634173 -0.011501 -0.019914 0.0235 -0.011501 -0.0197678 0.00680434 -0.0116915 -0.0198856 0.00643137 -0.011538 -0.0193462 0.0149209 -0.0122409 -0.0197678 0.00680434 -0.0116915 -0.0198856 0.00643137 -0.011538 -0.019704 0.007007 -0.011803 -0.0193462 0.0149209 -0.0122409 -0.0196831 0.00700449 -0.0118019 -0.0197678 0.00680434 -0.0116915 -0.019322 0.008213 -0.012469 -0.0196831 0.00700449 -0.0118019 -0.019179 0.00819134 -0.0124589 -0.019179 0.00819134 -0.0124589 -0.0196831 0.00700449 -0.0118019 -0.0191745 0.00820594 -0.0124647 -0.019322 0.008213 -0.012469 -0.0191745 0.00820594 -0.0124647 -0.019179 0.00819134 -0.0124589 -0.0191745 0.00820594 -0.0124647 -0.0196831 0.00700449 -0.0118019 -0.0193462 0.0149209 -0.0122409 -0.019322 0.008213 -0.012469 -0.0191745 0.00820594 -0.0124647 -0.0190308 0.00843554 -0.012652 -0.0193462 0.0149209 -0.0122409 -0.0190308 0.00843554 -0.012652 -0.0191745 0.00820594 -0.0124647 -0.019322 0.008213 -0.012469 -0.019704 0.007007 -0.011803 -0.0196831 0.00700449 -0.0118019 -0.019914 0.0235 -0.011501 -0.016259 0.0235 -0.016264 -0.0180865 0.0161829 -0.0138825 -0.019914 0.0235 -0.011501 -0.0180865 0.0161829 -0.0138825 -0.0187784 0.00886585 -0.0129809 -0.022995 0.0235 -1.00185e-06 -0.022211 0.0235 -0.005954 -0.022211 -0.0236 -0.005954 -0.022995 -0.0236 -9.97793e-07 -0.022211 -0.0236 -0.005954 -0.019914 -0.0236 -0.011501 -0.022211 0.0235 -0.005954 -0.019914 -0.0236 -0.011501 -0.022211 -0.0236 -0.005954 -0.019914 -0.0236 -0.011501 -0.022211 -0.0236 0.005952 -0.022995 -0.0236 -9.97793e-07 -0.022211 0.0235 0.005952 -0.022995 -0.0236 -9.97793e-07 -0.022211 -0.0236 0.005952 -0.022211 -0.0236 0.005952 -0.019914 -0.0236 -0.011501 -0.019914 -0.0236 0.011499 -0.016259 0.0235 0.016263 -0.019914 0.0235 0.011499 -0.019914 -0.0236 0.011499 -0.019914 0.0235 0.011499 -0.022211 -0.0236 0.005952 -0.019914 -0.0236 0.011499 -0.016259 0.0235 0.016263 -0.019914 -0.0236 0.011499 -0.016259 -0.0236 0.016263 -0.011495 -0.0236 0.019918 -0.016259 -0.0236 0.016263 -0.005948 -0.0236 -0.022217 -0.016259 -0.0236 0.016263 -0.011495 -0.0236 0.019918 -0.011495 0.0235 0.019918 -0.016259 -0.0236 0.016263 -0.019914 -0.0236 0.011499 -0.005948 -0.0236 -0.022217 -0.022995 0.0235 -1.00185e-06 -0.022211 -0.0236 -0.005954 -0.022995 -0.0236 -9.97793e-07 -0.016259 -0.0236 0.016263 -0.011495 0.0235 0.019918 -0.016259 0.0235 0.016263 -0.019914 -0.0236 0.011499 -0.011495 -0.0236 -0.01992 -0.005948 -0.0236 -0.022217 0.00136569 0.0208033 -0.0228218 0.00298151 0.0217379 -0.022609 0.00129865 0.0208136 -0.0228306 0.00129865 0.0208136 -0.0228306 5.003e-06 0.0235 -0.023001 0.00298151 0.0217379 -0.022609 0.000326874 0.0209534 -0.0229586 0.000101084 0.0209858 -0.0229883 5.003e-06 0.0235 -0.023001 0.00129865 0.0208136 -0.0228306 0.000326874 0.0209534 -0.0229586 5.003e-06 0.0235 -0.023001 0.000101084 0.0209858 -0.0229883 0.000326874 0.0209534 -0.0229586 0.002809 0.020812 -0.022829 4.21162e-05 0.0209944 -0.0229961 0.000101084 0.0209858 -0.0229883 0.000128003 0.021 -0.023001 0.000128003 0.021 -0.023001 1.33991e-05 0.0209914 -0.0229999 4.21162e-05 0.0209944 -0.0229961 0.000101084 0.0209858 -0.0229883 0.002809 0.020812 -0.022829 0.000128003 0.021 -0.023001 0.002864 0.020804 -0.025001 0.000128003 0.021 -0.023001 0.002809 0.020812 -0.022829 0.000326874 0.0209534 -0.0229586 0.00129865 0.0208136 -0.0228306 0.002809 0.020812 -0.022829 0.002809 0.020812 -0.022829 0.00208082 0.0208058 -0.0228238 0.002863 0.020798 -0.022817 0.002809 0.020812 -0.022829 0.00129865 0.0208136 -0.0228306 0.00208082 0.0208058 -0.0228238 0.014343 0.0149985 -0.0177416 0.013202 0.016233 -0.018765 0.0128091 0.0164065 -0.018919 0.0128091 0.0164065 -0.018919 0.013202 0.016233 -0.018765 0.0123906 0.0167806 -0.0192403 0.0128091 0.0164065 -0.018919 0.0123906 0.0167806 -0.0192403 0.0138865 0.0182098 -0.018092 0.0128091 0.0164065 -0.018919 0.0138865 0.0182098 -0.018092 0.013576 0.0166041 -0.0183303 0.0138865 0.0182098 -0.018092 0.014343 0.0149985 -0.0177416 0.013576 0.0166041 -0.0183303 0.014343 0.0149985 -0.0177416 0.0128091 0.0164065 -0.018919 0.013576 0.0166041 -0.0183303 0.0123906 0.0167806 -0.0192403 0.0121635 0.0169879 -0.0194145 0.0138865 0.0182098 -0.018092 0.0138865 0.0182098 -0.018092 0.0121635 0.0169879 -0.0194145 0.011505 0.0235 -0.01992 0.0121082 0.0170385 -0.019457 0.011505 0.0173824 -0.01992 0.011505 0.0235 -0.01992 0.0121635 0.0169879 -0.0194145 0.0121082 0.0170385 -0.019457 0.011505 0.0235 -0.01992 -0.011495 0.0174552 -0.01992 -0.013877 0.0188014 -0.018092 -0.011495 0.0235 -0.01992 -0.011495 0.0235 -0.01992 -0.013877 0.0188014 -0.018092 -0.013877 0.0211507 -0.018092 -0.013877 0.0188014 -0.018092 -0.016259 0.0235 -0.016264 -0.013877 0.0211507 -0.018092 -0.016259 0.0235 -0.016264 -0.011495 0.0235 -0.01992 -0.013877 0.0211507 -0.018092 0.005958 0.0235 -0.022217 5.003e-06 0.0235 -0.023001 0.001225 0.0235 -0.022685 0.00298151 0.0217379 -0.022609 5.003e-06 0.0235 -0.023001 0.0029815 0.0226189 -0.022609 5.003e-06 0.0235 -0.023001 0.005958 0.0235 -0.022217 0.0029815 0.0226189 -0.022609 0.005958 0.0235 -0.022217 0.00298151 0.0217379 -0.022609 0.0029815 0.0226189 -0.022609 0.001225 0.0235 -0.022685 5.003e-06 0.0235 -0.023001 -0.005948 0.0235 -0.022217 5.00691e-06 0.0235 0.022999 0.00595801 0.0235 0.022215 0.00514601 0.0235 0.022126 5.00691e-06 0.0235 0.022999 0.00514601 0.0235 0.022126 -0.005948 0.0235 0.022215 -0.005948 0.0235 0.022215 -0.008886140000000001 0.0234464 0.0209656 -0.011495 -0.0236 0.019918 0.00514601 0.0235 0.022126 -0.008886140000000001 0.0234464 0.0209656 -0.005948 0.0235 0.022215 0.00595801 0.0235 0.022215 0.011505 0.0235 0.019918 0.00514601 0.0235 0.022126 -0.011495 -0.0236 0.019918 -0.00594799 -0.0236 0.022215 -0.005948 0.0235 0.022215 0.0138865 0.0182098 -0.018092 0.011505 0.0235 -0.01992 0.0138865 0.0208549 -0.018092 0.011505 0.0235 -0.01992 0.016268 0.0235 -0.016264 0.0138865 0.0208549 -0.018092 0.016268 0.0235 -0.016264 0.0138865 0.0182098 -0.018092 0.0138865 0.0208549 -0.018092 0.023005 -0.0236 -1.00182e-06 0.022221 0.0235 -0.005954 0.023005 0.0235 -1.00587e-06 -0.00594799 -0.0236 0.022215 5.00691e-06 0.0235 0.022999 -0.005948 0.0235 0.022215 0.013258 0.01629 -0.025001 0.013202 0.016233 -0.018765 0.014343 0.0149985 -0.0177416 0.0160412 0.0131652 -0.0164381 0.014343 0.0149985 -0.0177416 0.0138865 0.0182098 -0.018092 0.019923 -0.0236 0.011499 0.016268 -0.0236 0.016263 -0.005948 -0.0236 -0.022217 0.011505 -0.0236 0.019918 -0.005948 -0.0236 -0.022217 0.016268 -0.0236 0.016263 0.011505 -0.0236 0.019918 0.016268 0.0235 0.016263 0.011505 0.0235 0.019918 0.011505 -0.0236 0.019918 0.016268 -0.0236 0.016263 0.016268 0.0235 0.016263 0.00595801 -0.0236 0.022215 0.011505 -0.0236 0.019918 0.011505 0.0235 0.019918 0.019923 -0.0236 0.011499 0.022221 0.0235 0.005952 0.019923 0.0235 0.011499 0.019923 0.0235 0.011499 0.016268 -0.0236 0.016263 0.019923 -0.0236 0.011499 -0.0190308 0.00843554 -0.012652 -0.019322 0.008213 -0.012469 -0.0189819 0.008514900000000001 -0.0127157 -0.019783 0.007033 -0.025001 -0.0198856 0.00643137 -0.011538 -0.019704 0.007007 -0.011803 -0.011495 0.0235 -0.01992 0.001225 0.0235 -0.022685 -0.005948 0.0235 -0.022217 0.0121635 0.0169879 -0.0194145 0.0123906 0.0167806 -0.0192403 0.012853 0.016611 -0.019078 0.013258 0.01629 -0.025001 0.012853 0.016611 -0.019078 0.013202 0.016233 -0.018765 0.017161 0.01211 -0.025001 0.0160412 0.0131652 -0.0164381 0.0161666 0.0130293 -0.0163419 0.0160412 0.0131652 -0.0164381 0.017161 0.01211 -0.025001 0.013258 0.01629 -0.025001 0.006945 0.028157 -0.025001 0.006945 0.028157 -0.027501 5.00311e-06 0.029 -0.025001 0.013482 0.025678 -0.027501 0.006945 0.028157 -0.027501 0.006945 0.028157 -0.025001 0.00601617 0.0199606 -0.0221929 0.00719524 0.0196169 -0.02331 0.008371 0.019261 -0.025001 0.00638618 0.0198643 -0.0220397 0.00719524 0.0196169 -0.02331 0.00601617 0.0199606 -0.0221929 0.00638618 0.0198643 -0.0220397 0.00601617 0.0199606 -0.0221929 0.005958 0.0235 -0.022217 0.0114858 0.0173935 -0.019928 0.0123745 0.0168463 -0.0220395 0.013258 0.01629 -0.025001 0.0123745 0.0168463 -0.0220395 0.0114858 0.0173935 -0.019928 0.011505 0.0173824 -0.01992 0.0123745 0.0168463 -0.0220395 0.012853 0.016611 -0.019078 0.013258 0.01629 -0.025001 0.0114858 0.0173935 -0.019928 0.013258 0.01629 -0.025001 0.0108031 0.0177529 -0.0224645 0.007856999999999999 0.019477 -0.021619 0.008338999999999999 0.0192 -0.021374 0.008371 0.019261 -0.025001 0.008338999999999999 0.0192 -0.021374 0.007856999999999999 0.019477 -0.021619 0.00715271 0.0195871 -0.0217223 0.013258 0.01629 -0.025001 0.008371 0.019261 -0.025001 0.008338999999999999 0.0192 -0.021374 0.0108031 0.0177529 -0.0224645 0.013258 0.01629 -0.025001 0.008338999999999999 0.0192 -0.021374 0.007856999999999999 0.019477 -0.021619 0.00677476 0.0197631 -0.0218788 0.00715271 0.0195871 -0.0217223 0.00677476 0.0197631 -0.0218788 0.007856999999999999 0.019477 -0.021619 0.00719524 0.0196169 -0.02331 0.00638618 0.0198643 -0.0220397 0.00677476 0.0197631 -0.0218788 0.00719524 0.0196169 -0.02331 0.013258 0.01629 -0.025001 0.013482 0.025678 -0.025001 0.008371 0.019261 -0.025001 0.017161 0.01211 -0.025001 0.019792 0.007032 -0.025001 0.019235 0.021707 -0.025001 0.019792 0.007032 -0.025001 0.023871 0.016474 -0.025001 0.019235 0.021707 -0.025001 0.020956 0.001433 -0.025001 0.019792 0.007032 -0.025001 0.020029 0.006329 -0.011317 0.019792 0.007032 -0.025001 0.020956 0.001433 -0.025001 0.023871 0.016474 -0.025001 0.017161 0.01211 -0.025001 0.019235 0.021707 -0.025001 0.013482 0.025678 -0.025001 0.019235 0.021707 -0.025001 0.019235 0.021707 -0.027501 0.013482 0.025678 -0.025001 0.019235 0.021707 -0.027501 0.019235 0.021707 -0.025001 0.023871 0.016474 -0.027501 0.019235 0.021707 -0.027501 0.013482 0.025678 -0.027501 0.013482 0.025678 -0.025001 0.013482 0.025678 -0.025001 0.013482 0.025678 -0.027501 0.006945 0.028157 -0.025001 0.013258 0.01629 -0.025001 0.017161 0.01211 -0.025001 0.013482 0.025678 -0.025001 0.0108031 0.0177529 -0.0224645 0.008338999999999999 0.0192 -0.021374 0.009852700000000001 0.0183321 -0.0206042 0.013482 0.025678 -0.027501 0.028793 -0.003496 -0.027501 0.006945 0.028157 -0.027501 0.0121082 0.0170385 -0.019457 0.012853 0.016611 -0.019078 0.0123745 0.0168463 -0.0220395 0.005958 0.0199758 -0.022217 0.00601617 0.0199606 -0.0221929 0.008371 0.019261 -0.025001 0.002864 0.020804 -0.025001 0.008371 0.019261 -0.025001 0.006945 0.028157 -0.025001 0.008371 0.019261 -0.025001 0.002864 0.020804 -0.025001 0.002863 0.020798 -0.022817 0.00464289 0.020327 -0.0223902 0.008371 0.019261 -0.025001 0.002863 0.020798 -0.022817 0.005958 0.0199758 -0.022217 0.00464289 0.020327 -0.0223902 0.005958 0.0235 -0.022217 0.005958 0.0199758 -0.022217 0.008371 0.019261 -0.025001 0.00464289 0.020327 -0.0223902 0.023871 0.016474 -0.027501 0.019235 0.021707 -0.025001 0.023871 0.016474 -0.025001 0.013482 0.025678 -0.025001 0.006945 0.028157 -0.025001 0.008371 0.019261 -0.025001 0.019792 0.007032 -0.025001 0.017161 0.01211 -0.025001 0.017577 0.011498 -0.01484 0.00601617 0.0199606 -0.0221929 0.005958 0.0199758 -0.022217 0.005958 0.0235 -0.022217 0.023871 0.016474 -0.027501 0.028793 -0.003496 -0.027501 0.019235 0.021707 -0.027501 0.02712 0.010283 -0.027501 0.028793 -0.003496 -0.027501 0.023871 0.016474 -0.027501 0.028793 0.003495 -0.027501 0.028793 -0.003496 -0.027501 0.02712 0.010283 -0.027501 0.02712 0.010283 -0.027501 0.02712 0.010283 -0.025001 0.028793 0.003495 -0.027501 0.028793 0.003495 -0.027501 0.02712 0.010283 -0.025001 0.028793 0.003495 -0.025001 0.00567 -0.020221 -0.025001 0.010916 -0.017943 -0.025001 0.0106523 -0.017859 -0.0202731 -0.005611 0.020235 -0.022305 -0.00588438 0.0201067 -0.0222254 -0.00578059 0.0201617 -0.022239 5.00299e-06 0.0209906 -0.023001 -8.95551e-05 0.020986 -0.0229885 5.003e-06 0.0235 -0.023001 0.002864 0.020804 -0.025001 -8.95551e-05 0.020986 -0.0229885 5.00299e-06 0.0209906 -0.023001 -0.002752 0.020818 -0.022835 -8.95551e-05 0.020986 -0.0229885 0.002864 0.020804 -0.025001 -0.002752 0.020818 -0.022835 0.002864 0.020804 -0.025001 -0.002853 0.020798 -0.022816 -0.002853 0.020798 -0.022816 -0.002752 0.020818 -0.022835 -0.00264787 0.0207125 -0.0227497 -0.002752 0.020818 -0.022835 -0.00129102 0.0208128 -0.0228303 -0.00126762 0.0208164 -0.0228334 -0.00126762 0.0208164 -0.0228334 -8.95551e-05 0.020986 -0.0229885 -0.002752 0.020818 -0.022835 -0.00244138 0.0206218 -0.0226788 -0.00129102 0.0208128 -0.0228303 -0.002752 0.020818 -0.022835 0.002864 0.020804 -0.025001 1.33991e-05 0.0209914 -0.0229999 5.00299e-06 0.0209906 -0.023001 -0.002752 0.020818 -0.022835 -0.00244138 0.0206218 -0.0226788 -0.00264787 0.0207125 -0.0227497 -8.95551e-05 0.020986 -0.0229885 -0.00126762 0.0208164 -0.0228334 5.003e-06 0.0235 -0.023001 -0.00126762 0.0208164 -0.0228334 -0.0029715 0.0218489 -0.022609 5.003e-06 0.0235 -0.023001 5.003e-06 0.0235 -0.023001 1.33991e-05 0.0209914 -0.0229999 5.00299e-06 0.0209906 -0.023001 -0.00255123 0.0206072 -0.0226643 -0.00264787 0.0207125 -0.0227497 -0.00244138 0.0206218 -0.0226788 -0.00540541 0.0202158 -0.0222885 -0.00553063 0.0201977 -0.022272 -0.005948 0.0235 -0.022217 -0.0029715 0.0218489 -0.022609 -0.00540541 0.0202158 -0.0222885 -0.00445975 0.0218579 -0.022413 -0.00540541 0.0202158 -0.0222885 -0.005948 0.0235 -0.022217 -0.00445975 0.0218579 -0.022413 -0.005948 0.0235 -0.022217 -0.0029715 0.0218489 -0.022609 -0.00445975 0.0218579 -0.022413 -0.00323843 0.0205035 -0.0225738 -0.00540541 0.0202158 -0.0222885 -0.0029715 0.0218489 -0.022609 -0.00255123 0.0206072 -0.0226643 -0.002853 0.020798 -0.022816 -0.00323843 0.0205035 -0.0225738 -0.00255123 0.0206072 -0.0226643 -0.00323843 0.0205035 -0.0225738 -0.0029715 0.0218489 -0.022609 -0.0029715 0.0218489 -0.022609 -0.00244138 0.0206218 -0.0226788 -0.00255123 0.0206072 -0.0226643 -0.005611 0.020235 -0.022305 -0.00553063 0.0201977 -0.022272 -0.00540541 0.0202158 -0.0222885 -0.00578059 0.0201617 -0.022239 -0.00553063 0.0201977 -0.022272 -0.005611 0.020235 -0.022305 -0.016259 -0.0236 -0.016264 -0.011495 -0.0236 -0.01992 -0.019914 -0.0236 0.011499 -0.0134255 -0.0159104 -0.0211695 -0.0114968 -0.0174766 -0.0199187 -0.0121688 -0.0169379 -0.0194029 -0.0121688 -0.0169379 -0.0194029 -0.0125015 -0.0166713 -0.0191476 -0.0134255 -0.0159104 -0.0211695 -0.013877 -0.0182248 -0.018092 -0.0125015 -0.0166713 -0.0191476 -0.0121688 -0.0169379 -0.0194029 -0.0134255 -0.0159104 -0.0211695 -0.0125015 -0.0166713 -0.0191476 -0.015109 -0.01458 -0.017338 -0.0143912 -0.0151308 -0.0211695 -0.0134255 -0.0159104 -0.0211695 -0.015109 -0.01458 -0.017338 -0.0143912 -0.0151308 -0.0211695 -0.015109 -0.01458 -0.017338 -0.015343 -0.014334 -0.025001 -0.0143912 -0.0151308 -0.0211695 -0.015343 -0.014334 -0.025001 -0.0134255 -0.0159104 -0.0211695 -0.0156018 -0.0138341 -0.0167683 -0.015295 -0.014298 -0.017123 -0.0149842 -0.014434 -0.0172423 -0.015343 -0.014334 -0.025001 -0.015295 -0.014298 -0.017123 -0.0156018 -0.0138341 -0.0167683 -0.015343 -0.014334 -0.025001 -0.015109 -0.01458 -0.017338 -0.015295 -0.014298 -0.017123 -0.015109 -0.01458 -0.017338 -0.015295 -0.014298 -0.017123 -0.0149842 -0.014434 -0.0172423 -0.013877 -0.0182248 -0.018092 -0.0156018 -0.0138341 -0.0167683 -0.0149842 -0.014434 -0.0172423 -0.013877 -0.0182248 -0.018092 -0.016259 -0.0236 -0.016264 -0.0156018 -0.0138341 -0.0167683 -0.011495 -0.0236 -0.01992 -0.016259 -0.0236 -0.016264 -0.013877 -0.0209124 -0.018092 -0.016259 -0.0236 -0.016264 -0.013877 -0.0182248 -0.018092 -0.013877 -0.0209124 -0.018092 -0.013877 -0.0182248 -0.018092 -0.011495 -0.0236 -0.01992 -0.013877 -0.0209124 -0.018092 -0.0146219 -0.0147867 -0.0175203 -0.015109 -0.01458 -0.017338 -0.0125015 -0.0166713 -0.0191476 -0.0149842 -0.014434 -0.0172423 -0.015109 -0.01458 -0.017338 -0.0146219 -0.0147867 -0.0175203 0.023005 0.0235 -1.00587e-06 0.022221 -0.0236 0.005952 0.023005 -0.0236 -1.00182e-06 -0.008886140000000001 0.0234464 0.0209656 -0.011495 0.0235 0.019918 -0.011495 -0.0236 0.019918 -0.019914 -0.0236 -0.011501 -0.0207915 -5.29124e-09 -0.009382 -0.0203922 -0.00435697 -0.0103461 0.017161 0.01211 -0.025001 0.017077 0.012039 -0.015289 0.017577 0.011498 -0.01484 0.0166594 0.0125656 -0.020145 0.0161666 0.0130293 -0.0163419 0.016268 0.0129196 -0.016264 0.016268 0.0129196 -0.016264 0.0161666 0.0130293 -0.0163419 0.016268 0.0235 -0.016264 0.0166594 0.0125656 -0.020145 0.016268 0.0129196 -0.016264 0.0168817 0.0122506 -0.0154642 0.0196792 0.00706412 -0.0118187 0.017577 0.011498 -0.01484 0.0172067 0.0117321 -0.0150408 0.0172067 0.0117321 -0.0150408 0.017577 0.011498 -0.01484 0.0171776 0.0117784 -0.0150787 0.0180955 0.015026 -0.0138825 0.0172067 0.0117321 -0.0150408 0.0171776 0.0117784 -0.0150787 0.017077 0.012039 -0.015289 0.0171776 0.0117784 -0.0150787 0.017577 0.011498 -0.01484 0.0171776 0.0117784 -0.0150787 0.017077 0.012039 -0.015289 0.0169746 0.0121021 -0.0153433 0.016268 0.0235 -0.016264 0.0169746 0.0121021 -0.0153433 0.0168817 0.0122506 -0.0154642 0.0169746 0.0121021 -0.0153433 0.017077 0.012039 -0.015289 0.0168817 0.0122506 -0.0154642 0.0166594 0.0125656 -0.020145 0.0168817 0.0122506 -0.0154642 0.017077 0.012039 -0.015289 0.016268 0.0235 -0.016264 0.0171776 0.0117784 -0.0150787 0.0169746 0.0121021 -0.0153433 0.0166594 0.0125656 -0.020145 0.017077 0.012039 -0.015289 0.017161 0.01211 -0.025001 0.016268 0.0235 -0.016264 0.0180955 0.015026 -0.0138825 0.0171776 0.0117784 -0.0150787 0.019235 0.021707 -0.027501 0.028793 -0.003496 -0.027501 0.013482 0.025678 -0.027501 0.020027 -0.006334 -0.01132 0.020458 -0.00425 -0.010478 0.0203088 -0.00437259 -0.0105697 5.00281e-06 -0.021 -0.025001 0.00276 -0.020818 -0.022835 7.70034e-05 -0.021 -0.023001 0.00276 -0.020818 -0.022835 0.00463037 -0.0203299 -0.0223918 0.00235369 -0.0206649 -0.0226964 -0.0187784 0.00886585 -0.0129809 -0.019322 0.008213 -0.012469 -0.0189819 0.008514900000000001 -0.0127157 -0.0193462 0.0149209 -0.0122409 -0.0187784 0.00886585 -0.0129809 -0.0189819 0.008514900000000001 -0.0127157 0.006945 0.028157 -0.027501 0.028793 -0.003496 -0.027501 5.003e-06 0.029 -0.027501 0.0207989 -2.26701e-05 -0.009386800000000001 0.0208009 -9.954400000000001e-07 -0.009382 0.021005 -1.0003e-06 -0.009382 5.003e-06 0.0235 -0.023001 1.33991e-05 0.0209914 -0.0229999 4.21162e-05 0.0209944 -0.0229961 -0.0202226 -0.00534768 -0.017675 -0.019914 -0.00634104 -0.011501 -0.0200113 -0.00603244 -0.011266 -0.013877 0.0188014 -0.018092 -0.0153085 0.0141028 -0.0169934 -0.016259 0.0235 -0.016264 0.00464289 0.020327 -0.0223902 0.00298151 0.0217379 -0.022609 0.005958 0.0235 -0.022217 0.000536158 -0.020923 -0.022931 0.00235369 -0.0206649 -0.0226964 0.00463037 -0.0203299 -0.0223918 0.006945 0.028157 -0.025001 5.00311e-06 0.029 -0.025001 0.002864 0.020804 -0.025001 0.0199049 -0.00659166 -0.0115246 0.019923 -0.0236 -0.011501 0.0196834 -0.00705658 -0.0118133 0.00276 -0.020818 -0.022835 5.00281e-06 -0.021 -0.025001 0.00463037 -0.0203299 -0.0223918 0.00595801 -0.0236 0.022215 0.011505 0.0235 0.019918 0.00595801 0.0235 0.022215 0.019923 0.0235 0.011499 0.016268 0.0235 0.016263 0.016268 -0.0236 0.016263 -0.017152 0.01211 -0.025001 -0.013472 0.025678 -0.025001 -0.019226 0.021707 -0.025001 0.020566 -0.004273 -0.025001 0.023871 -0.016474 -0.025001 0.020956 0.001433 -0.025001 0.01865 -0.009660999999999999 -0.025001 0.0199049 -0.00659166 -0.0115246 0.0196834 -0.00705658 -0.0118133 0.0196834 -0.00705658 -0.0118133 0.018484 -0.00958 -0.013534 0.01865 -0.009660999999999999 -0.025001 -0.015091 0.014598 -0.017353 -0.0160418 0.0131291 -0.0164307 -0.0155899 0.0138453 -0.0167775 -0.0180865 0.0161829 -0.0138825 -0.016259 0.0127847 -0.016264 -0.0167445 0.012066 -0.0156314 0.022221 -0.0236 0.005952 -0.005948 -0.0236 -0.022217 0.023005 -0.0236 -1.00182e-06 -0.022211 0.0235 0.005952 -0.022995 0.0235 -1.00185e-06 -0.022995 -0.0236 -9.97793e-07 0.000101084 0.0209858 -0.0229883 4.21162e-05 0.0209944 -0.0229961 5.003e-06 0.0235 -0.023001 0.00595801 -0.0236 -0.022217 0.00463037 -0.0203299 -0.0223918 0.00534893 -0.0201155 -0.0222972 5.003e-06 0.029 -0.027501 -0.006935 0.028157 -0.027501 -0.006935 0.028157 -0.025001 0.0161666 0.0130293 -0.0163419 0.0166594 0.0125656 -0.020145 0.017161 0.01211 -0.025001 -6.42413e-05 -0.0209905 -0.0229919 5.00286e-06 -0.020995 -0.023001 5.0028e-06 -0.0236 -0.023001 -0.015091 0.014598 -0.017353 -0.0155899 0.0138453 -0.0167775 -0.0153085 0.0141028 -0.0169934 0.0114858 0.0173935 -0.019928 0.009852700000000001 0.0183321 -0.0206042 0.011505 0.0235 -0.01992 0.009852700000000001 0.0183321 -0.0206042 0.0087315 0.0204412 -0.0210685 0.011505 0.0235 -0.01992 0.009852700000000001 0.0183321 -0.0206042 0.00715271 0.0195871 -0.0217223 0.0087315 0.0204412 -0.0210685 -0.022211 -0.0236 0.005952 -0.019914 0.0235 0.011499 -0.022211 0.0235 0.005952 -0.0121688 -0.0169379 -0.0194029 -0.0114968 -0.0174766 -0.0199187 -0.011495 -0.0236 -0.01992 -0.013248 0.01629 -0.025001 -0.0160418 0.0131291 -0.0164307 -0.015091 0.014598 -0.017353 -0.020875 -0.002242 -0.009646 -0.020995 -1.12878e-09 -0.025001 -0.020556 -0.004273 -0.025001 -0.00553063 0.0201977 -0.022272 -0.00578059 0.0201617 -0.022239 -0.005948 0.0235 -0.022217 -0.0180865 0.0161829 -0.0138825 -0.016259 0.0235 -0.016264 -0.016259 0.0127847 -0.016264 0.016268 0.0235 -0.016264 0.0168817 0.0122506 -0.0154642 0.016268 0.0129196 -0.016264 0.011505 -0.0236 -0.01992 0.0087315 -0.0206916 -0.0210685 0.009824029999999999 -0.0183462 -0.0206161 0.028793 -0.003496 -0.027501 -0.013472 -0.025678 -0.027501 -0.019226 -0.021707 -0.027501 0.02712 0.010283 -0.027501 0.023871 0.016474 -0.025001 0.02712 0.010283 -0.025001 0.023871 -0.016474 -0.025001 0.019235 -0.021707 -0.025001 0.023871 -0.016474 -0.027501 0.02712 -0.010284 -0.027501 0.023871 -0.016474 -0.025001 0.023871 -0.016474 -0.027501 0.023871 0.016474 -0.025001 0.02712 -0.010284 -0.025001 0.02712 0.010283 -0.025001 0.023871 -0.016474 -0.025001 0.02712 -0.010284 -0.025001 0.023871 0.016474 -0.025001 0.02712 -0.010284 -0.027501 0.028793 -0.003496 -0.027501 0.02712 -0.010284 -0.025001 0.02712 -0.010284 -0.025001 0.023871 -0.016474 -0.025001 0.02712 -0.010284 -0.027501 0.023871 -0.016474 -0.027501 0.028793 -0.003496 -0.027501 0.02712 -0.010284 -0.027501 0.028793 -0.003496 -0.027501 0.028793 -0.003496 -0.025001 0.02712 -0.010284 -0.025001 0.029005 -1.51628e-09 -0.027501 0.028793 -0.003496 -0.025001 0.028793 -0.003496 -0.027501 0.023871 -0.016474 -0.027501 0.019235 -0.021707 -0.025001 0.019235 -0.021707 -0.027501 0.019235 -0.021707 -0.025001 0.013482 -0.025678 -0.025001 0.019235 -0.021707 -0.027501 0.011505 0.0173824 -0.01992 0.0121082 0.0170385 -0.019457 0.0123745 0.0168463 -0.0220395 0.019235 -0.021707 -0.025001 0.023871 -0.016474 -0.025001 0.020566 -0.004273 -0.025001 5.00311e-06 0.029 -0.025001 0.006945 0.028157 -0.027501 5.003e-06 0.029 -0.027501 -0.0180865 0.0161829 -0.0138825 -0.0168718 0.0119212 -0.0154655 -0.0180009 0.0102068 -0.0139941 -0.0198884 -0.00642213 -0.0115343 -0.019914 -0.00634104 -0.011501 -0.0202226 -0.00534768 -0.017675 0.010916 -0.017943 -0.025001 0.0142748 -0.0150613 -0.0177939 0.012791 -0.016659 -0.019119 -0.028784 0.003496 -0.025001 -0.027111 0.010284 -0.027501 -0.028784 0.003496 -0.027501 0.0111625 -0.0204984 -0.0200618 0.0114266 -0.0174412 -0.0199525 0.011505 -0.0173969 -0.01992 0.022221 -0.0236 0.005952 0.019923 -0.0236 0.011499 -0.005948 -0.0236 -0.022217 0.00208082 0.0208058 -0.0228238 0.00129865 0.0208136 -0.0228306 0.00136569 0.0208033 -0.0228218 0.013258 0.01629 -0.025001 0.014343 0.0149985 -0.0177416 0.0160412 0.0131652 -0.0164381 0.020897 -0.002125 -0.009619000000000001 0.0208531 -0.0010683 -0.00950222 0.0207012 -0.0021356 -0.009622449999999999 -0.0114968 -0.0174766 -0.0199187 -0.0134255 -0.0159104 -0.0211695 -0.015343 -0.014334 -0.025001 0.011505 -0.0173969 -0.01992 0.0114266 -0.0174412 -0.0199525 0.010916 -0.017943 -0.025001 -0.0207911 9.21272e-06 -0.009383030000000001 -0.0207915 -5.29124e-09 -0.009382 -0.022211 0.0235 -0.005954 -0.0156018 -0.0138341 -0.0167683 -0.016259 -0.0236 -0.016264 -0.0161151 -0.0130608 -0.0163744 -0.022211 0.0235 -0.005954 -0.0207915 -5.29124e-09 -0.009382 -0.019914 -0.0236 -0.011501 -0.0193462 0.0149209 -0.0122409 -0.0189819 0.008514900000000001 -0.0127157 -0.0190308 0.00843554 -0.012652 0.020956 0.001433 -0.025001 0.020932 0.001432 -0.009542 0.021005 -1.0003e-06 -0.009382 0.002864 0.020804 -0.025001 1.33991e-05 0.0209914 -0.0229999 0.000128003 0.021 -0.023001 0.0161666 0.0130293 -0.0163419 0.0160412 0.0131652 -0.0164381 0.016268 0.0235 -0.016264 0.016268 0.0235 -0.016264 0.019923 0.0235 -0.011501 0.0180955 0.015026 -0.0138825 -0.028784 0.003496 -0.025001 -0.028784 -0.003496 -0.027501 -0.028784 -0.003496 -0.025001 -0.0190721 -0.0083654 -0.0125981 -0.019331 -0.008194 -0.012457 -0.018441 -0.009539000000000001 -0.013485 0.019792 0.007032 -0.025001 0.017577 0.011498 -0.01484 0.0196792 0.00706412 -0.0118187 0.019792 0.007032 -0.025001 0.019711 0.00699701 -0.0117772 0.0199077 0.00658399 -0.0115209 0.0199077 0.00658399 -0.0115209 0.019711 0.00699701 -0.0117772 0.0180955 0.015026 -0.0138825 0.0180955 0.015026 -0.0138825 0.019711 0.00699701 -0.0117772 0.0196792 0.00706412 -0.0118187 0.019792 0.007032 -0.025001 0.0196792 0.00706412 -0.0118187 0.019711 0.00699701 -0.0117772 -0.022211 0.0235 -0.005954 -0.0200112 0.0060328 -0.0112663 -0.0203904 0.00437019 -0.0103505 0.029005 -1.51628e-09 -0.027501 0.028793 -0.003496 -0.027501 0.028793 0.003495 -0.027501 0.0206968 0.00215332 -0.00963319 0.0206985 0.00214578 -0.00962908 0.020897 0.002123 -0.009619000000000001 -0.011495 0.0235 -0.01992 -0.005948 0.0235 -0.022217 -0.0087215 0.0220938 -0.0210685 -0.005948 0.0235 -0.022217 -0.0087215 0.0206877 -0.0210685 -0.0087215 0.0220938 -0.0210685 -0.0087215 0.0206877 -0.0210685 -0.011495 0.0235 -0.01992 -0.0087215 0.0220938 -0.0210685 -0.011495 0.0235 -0.01992 -0.0087215 0.0206877 -0.0210685 -0.0101083 0.0206877 -0.0204943 -0.0087215 0.0206877 -0.0210685 -0.0108326 0.0178754 -0.0201943 -0.0101083 0.0206877 -0.0204943 -0.0108326 0.0178754 -0.0201943 -0.011495 0.0235 -0.01992 -0.0101083 0.0206877 -0.0204943 0.006945 -0.028157 -0.027501 5.0034e-06 -0.029 -0.027501 0.028793 -0.003496 -0.027501 -0.002803 -0.020811 -0.022829 -0.00286262 -0.0206057 -0.0226419 -0.005661 -0.020221 -0.022292 -0.019704 0.007007 -0.011803 -0.0197678 0.00680434 -0.0116915 -0.0196831 0.00700449 -0.0118019 0.019792 0.007032 -0.025001 0.0199077 0.00658399 -0.0115209 0.019923 0.006552 -0.011501 -0.00842731 0.0189906 -0.0211903 -0.00889909 0.018772 -0.020995 -0.0087215 0.0206877 -0.0210685 0.011505 0.0173824 -0.01992 0.0114858 0.0173935 -0.019928 0.011505 0.0235 -0.01992 0.0199094 -0.00657925 -0.0115188 0.020566 -0.004273 -0.025001 0.0202401 -0.00542722 -0.0181605 0.0199049 -0.00659166 -0.0115246 0.019923 -0.00655046 -0.011501 0.0199094 -0.00657925 -0.0115188 -0.020534 0.004378 -0.010353 -0.0200112 0.0060328 -0.0112663 -0.019914 0.00634173 -0.011501 -0.002853 0.020798 -0.022816 -0.00264787 0.0207125 -0.0227497 -0.00255123 0.0206072 -0.0226643 0.0138865 0.0182098 -0.018092 0.016268 0.0235 -0.016264 0.0150773 0.0183326 -0.017178 0.016268 0.0235 -0.016264 0.0160412 0.0131652 -0.0164381 0.0150773 0.0183326 -0.017178 0.0160412 0.0131652 -0.0164381 0.0138865 0.0182098 -0.018092 0.0150773 0.0183326 -0.017178 0.020566 -0.004273 -0.025001 0.020458 -0.00425 -0.010478 0.020027 -0.006334 -0.01132 0.019923 0.0235 -0.011501 0.0207018 0.00212908 -0.00962095 0.020703 0.00211538 -0.009618160000000001 -0.002855 0.020804 -0.025001 -0.002853 0.020798 -0.022816 0.002864 0.020804 -0.025001 0.016268 -0.0129285 -0.016264 0.0180955 -0.0161854 -0.0138825 0.016268 -0.0236 -0.016264 0.0168785 -0.0122579 -0.0154685 0.0176812 -0.010919 -0.0145012 0.0176809 -0.0107701 -0.0144228 0.018484 -0.00958 -0.013534 0.0176809 -0.0107701 -0.0144228 0.0176812 -0.010919 -0.0145012 0.0182305 -0.009790180000000001 -0.0137066 0.0176809 -0.0107701 -0.0144228 0.018484 -0.00958 -0.013534 0.0187722 -0.00877084 -0.0130006 0.0182305 -0.009790180000000001 -0.0137066 0.018484 -0.00958 -0.013534 0.0176809 -0.0107701 -0.0144228 0.0182305 -0.009790180000000001 -0.0137066 0.0180955 -0.0161854 -0.0138825 0.017561 -0.011523 -0.014859 0.0176812 -0.010919 -0.0145012 0.0168785 -0.0122579 -0.0154685 0.0180955 -0.0161854 -0.0138825 0.0168785 -0.0122579 -0.0154685 0.0176809 -0.0107701 -0.0144228 0.016268 -0.0129285 -0.016264 0.0168785 -0.0122579 -0.0154685 0.0180955 -0.0161854 -0.0138825 0.00595801 -0.0236 -0.022217 0.00563149 -0.0200746 -0.02226 0.00591295 -0.0200019 -0.0222229 0.022221 0.0235 0.005952 0.019923 -0.0236 0.011499 0.022221 -0.0236 0.005952 0.0106633 0.0178526 -0.0211962 0.009852700000000001 0.0183321 -0.0206042 0.0114858 0.0173935 -0.019928 0.0106633 0.0178526 -0.0211962 0.0114858 0.0173935 -0.019928 0.0108031 0.0177529 -0.0224645 0.0106633 0.0178526 -0.0211962 0.0108031 0.0177529 -0.0224645 0.009852700000000001 0.0183321 -0.0206042 0.021005 -1.0003e-06 -0.009382 0.020932 0.001432 -0.009542 0.0208009 -9.954400000000001e-07 -0.009382 0.00715271 0.0195871 -0.0217223 0.009852700000000001 0.0183321 -0.0206042 0.008338999999999999 0.0192 -0.021374 -0.0187784 0.00886585 -0.0129809 -0.0193462 0.0149209 -0.0122409 -0.019914 0.0235 -0.011501 -0.023862 0.016474 -0.025001 -0.020946 0.001433 -0.025001 -0.019226 0.021707 -0.025001 -0.0180865 0.0161829 -0.0138825 -0.0180009 0.0102068 -0.0139941 -0.0187784 0.00886585 -0.0129809 5.0028e-06 -0.0236 -0.023001 -0.000329676 -0.020952 -0.0229569 -6.42413e-05 -0.0209905 -0.0229919 0.01865 -0.009660999999999999 -0.025001 0.018484 -0.00958 -0.013534 0.017561 -0.011523 -0.014859 0.0121635 0.0169879 -0.0194145 0.012853 0.016611 -0.019078 0.0121082 0.0170385 -0.019457 -0.00540541 0.0202158 -0.0222885 -0.00323843 0.0205035 -0.0225738 -0.002853 0.020798 -0.022816 5.00351e-06 -0.029 -0.025001 0.00567 -0.020221 -0.025001 5.00281e-06 -0.021 -0.025001 -0.006935 -0.028157 -0.025001 -0.006935 -0.028157 -0.027501 5.00351e-06 -0.029 -0.025001 0.016268 -0.0129285 -0.016264 0.017561 -0.011523 -0.014859 0.0168785 -0.0122579 -0.0154685 -0.013472 -0.025678 -0.025001 -0.006935 -0.028157 -0.025001 -0.010907 -0.017943 -0.025001 -0.027111 0.010284 -0.027501 -0.028784 0.003496 -0.025001 -0.027111 0.010284 -0.025001 0.016268 -0.0236 -0.016264 0.0161186 -0.0130884 -0.0163787 0.016268 -0.0129285 -0.016264 -0.00540541 0.0202158 -0.0222885 -0.002853 0.020798 -0.022816 -0.005611 0.020235 -0.022305 0.013482 -0.025678 -0.025001 0.013482 -0.025678 -0.027501 0.019235 -0.021707 -0.027501 -0.011495 -0.0236 -0.01992 -0.0104216 -0.018071 -0.0203645 -0.0101083 -0.0208355 -0.0204943 -0.0104216 -0.018071 -0.0203645 -0.0087215 -0.020539 -0.0210685 -0.0101083 -0.0208355 -0.0204943 -0.0087215 -0.020539 -0.0210685 -0.011495 -0.0236 -0.01992 -0.0101083 -0.0208355 -0.0204943 -0.018641 -0.009660999999999999 -0.025001 -0.013472 -0.025678 -0.025001 -0.015343 -0.014334 -0.025001 0.0182305 -0.009790180000000001 -0.0137066 0.0187722 -0.00877084 -0.0130006 0.0180955 -0.0161854 -0.0138825 -0.0191881 -0.00817245 -0.0124469 -0.0190721 -0.0083654 -0.0125981 -0.0180865 -0.0149705 -0.0138825 0.022221 -0.0236 0.005952 0.023005 0.0235 -1.00587e-06 0.022221 0.0235 0.005952 -0.01253 0.0166459 -0.0191257 -0.013877 0.0188014 -0.018092 -0.011495 0.0174552 -0.01992 -0.028784 0.003496 -0.025001 -0.028784 -0.003496 -0.025001 -0.027111 -0.010283 -0.025001 0.00595801 -0.0236 0.022215 -0.005948 -0.0236 -0.022217 0.011505 -0.0236 0.019918 0.02712 -0.010284 -0.025001 0.028793 -0.003496 -0.025001 0.02712 0.010283 -0.025001 -0.0173883 -0.0112959 -0.019243 -0.0161832 -0.0129632 -0.0163222 -0.016259 -0.0128496 -0.016264 0.0206985 0.00214578 -0.00962908 0.0206968 0.00215332 -0.00963319 0.0199989 0.00633044 -0.0113179 0.019235 -0.021707 -0.025001 0.0163585 -0.020006 -0.025001 0.013482 -0.025678 -0.025001 0.023871 -0.016474 -0.027501 0.019235 -0.021707 -0.027501 0.028793 -0.003496 -0.027501 0.011505 -0.0236 -0.01992 0.011505 -0.0173969 -0.01992 0.0138865 -0.0187853 -0.018092 0.016268 -0.0236 -0.016264 0.0152942 -0.0139705 -0.0170115 0.0161186 -0.0130884 -0.0163787 0.028793 0.003495 -0.025001 0.029005 -1.51628e-09 -0.027501 0.028793 0.003495 -0.027501 0.018484 -0.00958 -0.013534 0.0176812 -0.010919 -0.0145012 0.017561 -0.011523 -0.014859 0.002863 0.020798 -0.022817 0.00373591 0.0204544 -0.0225096 0.00464289 0.020327 -0.0223902 -0.011495 -0.0236 -0.01992 -0.013877 -0.0182248 -0.018092 -0.0121688 -0.0169379 -0.0194029 -0.013877 -0.0182248 -0.018092 -0.0146219 -0.0147867 -0.0175203 -0.0125015 -0.0166713 -0.0191476 -0.005948 -0.0236 -0.022217 -0.00597529 -0.0200844 -0.0222057 -0.005948 -0.0200962 -0.022217 -0.015343 -0.014334 -0.025001 -0.0156018 -0.0138341 -0.0167683 -0.0161151 -0.0130608 -0.0163744 0.00595801 -0.0236 -0.022217 0.00534893 -0.0201155 -0.0222972 0.00551457 -0.0200915 -0.0222754 5.003e-06 0.0235 -0.023001 -0.0029715 0.0218489 -0.022609 -0.0029715 0.0226744 -0.022609 -0.0029715 0.0218489 -0.022609 -0.005948 0.0235 -0.022217 -0.0029715 0.0226744 -0.022609 -0.005948 0.0235 -0.022217 5.003e-06 0.0235 -0.023001 -0.0029715 0.0226744 -0.022609 0.0123906 0.0167806 -0.0192403 0.013202 0.016233 -0.018765 0.012853 0.016611 -0.019078 -0.023862 -0.016474 -0.025001 -0.019226 -0.021707 -0.025001 -0.023862 0.016474 -0.025001 -0.011495 -0.0236 -0.01992 -0.0112084 -0.0177006 -0.0200387 -0.0104216 -0.018071 -0.0203645 -0.00594799 -0.0236 0.022215 5.00671e-06 -0.0236 0.022999 5.00691e-06 0.0235 0.022999 -0.019914 -0.0236 -0.011501 -0.016259 -0.0236 -0.016264 -0.019914 -0.0236 0.011499 -0.00889909 0.018772 -0.020995 -0.008281999999999999 0.019078 -0.021267 -0.010915 0.017937 -0.020243 5.00671e-06 -0.0236 0.022999 0.00595801 0.0235 0.022215 5.00691e-06 0.0235 0.022999 0.029005 -1.51628e-09 -0.027501 0.028899 -5.00004e-07 -0.026251 0.028793 -0.003496 -0.025001 0.020029 0.006329 -0.011317 0.020897 0.002123 -0.009619000000000001 0.020956 0.001433 -0.025001 0.022221 -0.0236 -0.005954 0.019923 0.0235 -0.011501 0.022221 0.0235 -0.005954 0.002809 0.020812 -0.022829 0.002863 0.020798 -0.022817 0.002864 0.020804 -0.025001 0.0180955 0.015026 -0.0138825 0.019923 0.0235 -0.011501 0.0199077 0.00658399 -0.0115209 0.00719524 0.0196169 -0.02331 0.007856999999999999 0.019477 -0.021619 0.008371 0.019261 -0.025001 0.020956 0.001433 -0.025001 0.023871 -0.016474 -0.025001 0.023871 0.016474 -0.025001 -0.0203904 0.00437019 -0.0103505 -0.020534 0.004378 -0.010353 -0.0206327 0.00331222 -0.009999930000000001 -0.0203904 0.00437019 -0.0103505 -0.0200112 0.0060328 -0.0112663 -0.020534 0.004378 -0.010353 0.022221 -0.0236 -0.005954 0.0199553 -0.00648463 -0.011423 0.0199887 -0.00636216 -0.0113424 0.023871 0.016474 -0.025001 0.02712 0.010283 -0.027501 0.023871 0.016474 -0.027501 -0.005948 -0.0236 -0.022217 -0.0029715 -0.0218481 -0.022609 -0.0029715 -0.0227241 -0.022609 -0.0029715 -0.0218481 -0.022609 5.0028e-06 -0.0236 -0.023001 -0.0029715 -0.0227241 -0.022609 5.0028e-06 -0.0236 -0.023001 -0.005948 -0.0236 -0.022217 -0.0029715 -0.0227241 -0.022609 0.019923 0.006552 -0.011501 0.020029 0.006329 -0.011317 0.019792 0.007032 -0.025001 -0.019226 0.021707 -0.025001 -0.013472 0.025678 -0.027501 -0.019226 0.021707 -0.027501 -0.005948 -0.0200962 -0.022217 -0.010907 -0.017943 -0.025001 -0.005661 -0.020221 -0.022292 0.016268 -0.0236 -0.016264 -0.005948 -0.0236 -0.022217 5.0028e-06 -0.0236 -0.023001 0.0087315 -0.0206916 -0.0210685 0.00674679 -0.0197765 -0.0218904 0.009824029999999999 -0.0183462 -0.0206161 0.00136569 0.0208033 -0.0228218 0.00322721 0.0204969 -0.0225766 0.002863 0.020798 -0.022817 -0.00889909 0.018772 -0.020995 -0.0108326 0.0178754 -0.0201943 -0.0087215 0.0206877 -0.0210685 -0.0029715 0.0218489 -0.022609 -0.00129102 0.0208128 -0.0228303 -0.00126762 0.0208164 -0.0228334 0.002863 0.020798 -0.022817 0.00208082 0.0208058 -0.0228238 0.00136569 0.0208033 -0.0228218 -0.013472 0.025678 -0.027501 0.028793 -0.003496 -0.027501 -0.019226 0.021707 -0.027501 -0.0114049 0.0175333 -0.0199573 -0.010915 0.017937 -0.020243 -0.008362 0.019261 -0.025001 0.021005 -1.0003e-06 -0.009382 0.0207989 -2.26701e-05 -0.009386800000000001 0.0208531 -0.0010683 -0.00950222 -0.0108326 0.0178754 -0.0201943 -0.00889909 0.018772 -0.020995 -0.010915 0.017937 -0.020243 0.0172067 0.0117321 -0.0150408 0.0180955 0.015026 -0.0138825 0.0196792 0.00706412 -0.0118187 0.00677476 0.0197631 -0.0218788 0.00638618 0.0198643 -0.0220397 0.005958 0.0235 -0.022217 0.00677476 0.0197631 -0.0218788 0.0087315 0.0204412 -0.0210685 0.00715271 0.0195871 -0.0217223 0.015352 -0.014334 -0.025001 0.0152942 -0.0139705 -0.0170115 0.0151399 -0.0141357 -0.0171299 -0.019783 0.007033 -0.025001 -0.019704 0.007007 -0.011803 -0.019322 0.008213 -0.012469 -0.0108326 0.0178754 -0.0201943 -0.0112133 0.0176989 -0.0200366 -0.011495 0.0235 -0.01992 5.00281e-06 -0.021 -0.025001 -5.29691e-06 -0.0209936 -0.0229996 5.00286e-06 -0.020995 -0.023001 0.0187722 -0.00877084 -0.0130006 0.018484 -0.00958 -0.013534 0.0196834 -0.00705658 -0.0118133 0.020029 0.006329 -0.011317 0.0206968 0.00215332 -0.00963319 0.020897 0.002123 -0.009619000000000001 -0.013877 -0.0182248 -0.018092 -0.0149842 -0.014434 -0.0172423 -0.0146219 -0.0147867 -0.0175203 -0.00244138 0.0206218 -0.0226788 -0.0029715 0.0218489 -0.022609 -0.00129102 0.0208128 -0.0228303 -0.044558 -0.0286 -0.005665 -0.0456382 0.0235 -0.00458525 -0.044558 0.0235 -0.005665 -0.044558 -0.0286 -0.005665 -0.044558 0.0235 -0.005665 -0.0442005 0.0235 -0.00583178 -0.050695 0.0235 -0.00625 -0.0442005 0.0235 -0.00583178 -0.044558 0.0235 -0.005665 -0.0456382 0.0235 -0.00458525 -0.050695 0.0235 -0.00625 -0.044558 0.0235 -0.005665 -0.053137 0.0235 -0.001689 -0.050695 0.0235 -0.00625 -0.0456382 0.0235 -0.00458525 -0.050695 0.0235 -0.00625 -0.041096 0.0235 -0.0072791 -0.0442005 0.0235 -0.00583178 -0.0373685 0.0235 0.0141431 -0.035795 0.0235 0.0140054 -0.0378286 0.0235 0.0160817 -0.0378286 0.0235 0.0160817 -0.035795 0.0235 0.0140054 -0.035402 0.0235 0.013971 -0.035402 -0.0286 0.013971 -0.035402 0.0235 0.013971 -0.035795 0.0235 0.0140054 -0.039208 -0.0286 0.014304 -0.035402 -0.0286 0.013971 -0.035795 0.0235 0.0140054 -0.039208 -0.0286 0.014304 -0.041096 -0.0286 -0.00728 -0.035402 -0.0286 0.013971 -0.042898 -0.0286 0.013315 -0.041096 -0.0286 -0.00728 -0.039208 -0.0286 0.014304 -0.0419056 0.043 0.0108452 -0.0419318 0.0360042 0.0181741 -0.0399489 0.043 0.0112175 -0.0465467 0.0360042 0.0161752 -0.0419318 0.0360042 0.0181741 -0.0419056 0.043 0.0108452 -0.046784 0.0235 0.016542 -0.0419318 0.0360042 0.0181741 -0.0465467 0.0360042 0.0161752 -0.046784 0.0235 0.016542 -0.042037 0.0235 0.018598 -0.0419318 0.0360042 0.0181741 -0.0420762 0.0235 0.0159629 -0.046784 0.0235 0.016542 -0.0428502 0.0235 0.0133278 -0.046784 0.0235 0.016542 -0.0420762 0.0235 0.0159629 -0.042037 0.0235 0.018598 -0.042037 0.0235 0.018598 -0.039342 0.0235 0.019023 -0.0402787 0.0360042 0.0184351 -0.042037 0.0235 0.018598 -0.0402787 0.0360042 0.0184351 -0.0419318 0.0360042 0.0181741 -0.0420762 0.0235 0.0159629 -0.0428502 0.0235 0.0133278 -0.0395891 0.0235 0.0142019 -0.0420762 0.0235 0.0159629 -0.0395891 0.0235 0.0142019 -0.039208 0.0235 0.014304 -0.039208 -0.0286 0.014304 -0.0373685 0.0235 0.0141431 -0.039208 0.0235 0.014304 -0.039208 -0.0286 0.014304 -0.039208 0.0235 0.014304 -0.0395891 0.0235 0.0142019 -0.042898 -0.0286 0.013315 -0.0395891 0.0235 0.0142019 -0.0428502 0.0235 0.0133278 -0.042898 -0.0286 0.013315 -0.046027 -0.0286 0.011124 -0.041096 -0.0286 -0.00728 -0.046027 -0.0286 0.011124 -0.042898 -0.0286 0.013315 -0.0432211 0.0235 0.0130887 -0.042898 -0.0286 0.013315 -0.042898 0.0235 0.013315 -0.0432211 0.0235 0.0130887 -0.042898 -0.0286 0.013315 -0.0428502 0.0235 0.0133278 -0.042898 0.0235 0.013315 -0.050607 0.0235 0.013055 -0.0466064 0.0235 0.0102964 -0.0467286 0.0235 0.0134192 -0.050607 0.0235 0.013055 -0.0467286 0.0235 0.0134192 -0.046784 0.0235 0.016542 -0.0467286 0.0235 0.0134192 -0.046027 0.0235 0.011124 -0.0432211 0.0235 0.0130887 -0.046784 0.0235 0.016542 -0.0467286 0.0235 0.0134192 -0.0432211 0.0235 0.0130887 -0.046784 0.0235 0.016542 -0.0432211 0.0235 0.0130887 -0.042898 0.0235 0.013315 -0.046027 0.0235 0.011124 -0.0467286 0.0235 0.0134192 -0.0462533 0.0235 0.0108008 -0.0419056 0.043 0.0108452 -0.0399489 0.043 0.0112175 -0.0397689 0.0429547 -0.008889970000000001 -0.039208 -0.0286 0.014304 -0.035795 0.0235 0.0140054 -0.0373685 0.0235 0.0141431 -0.0420762 0.0235 0.0159629 -0.039208 0.0235 0.014304 -0.042037 0.0235 0.018598 -0.046027 -0.0286 0.011124 -0.048218 -0.0286 0.007993999999999999 -0.041096 -0.0286 -0.00728 -0.042898 -0.0286 0.013315 -0.039208 -0.0286 0.014304 -0.0395891 0.0235 0.0142019 -0.0462533 0.0235 0.0108008 -0.0467286 0.0235 0.0134192 -0.0466064 0.0235 0.0102964 -0.0498482 0.0235 0.00953849 -0.0482273 0.0235 0.00914567 -0.0466064 0.0235 0.0102964 -0.0466064 0.0235 0.0102964 -0.0482273 0.0235 0.00914567 -0.048218 0.0235 0.007994899999999999 -0.0482273 0.0235 0.00914567 -0.0498482 0.0235 0.00953849 -0.048218 0.0235 0.007994899999999999 -0.0466064 0.0235 0.0102964 -0.048218 0.0235 0.007994899999999999 -0.048218 -0.0286 0.007993999999999999 -0.048218 0.0235 0.007994899999999999 -0.0483201 0.0235 0.00761383 -0.048218 -0.0286 0.007993999999999999 -0.0462533 0.0235 0.0108008 -0.0466064 0.0235 0.0102964 -0.048218 -0.0286 0.007993999999999999 -0.048218 -0.0286 0.007993999999999999 -0.049207 -0.0286 0.004304 -0.041096 -0.0286 -0.00728 -0.049207 0.0235 0.0043049 -0.0491726 0.0235 0.00391195 -0.049207 -0.0286 0.004304 -0.0491726 0.0235 0.00391195 -0.048874 -0.0286 0.000499005 -0.049207 -0.0286 0.004304 -0.0489207 0.0235 0.00103219 -0.048874 0.0235 0.000499 -0.048874 -0.0286 0.000499005 -0.0491726 0.0235 0.00391195 -0.0489207 0.0235 0.00103219 -0.048874 -0.0286 0.000499005 -0.0491726 0.0235 0.00391195 -0.0513559 0.0235 0.0047746 -0.0489207 0.0235 0.00103219 -0.053965 0.0235 0.003418 -0.0489207 0.0235 0.00103219 -0.0513559 0.0235 0.0047746 -0.041096 -0.0286 -0.00728 -0.049207 -0.0286 0.004304 -0.048874 -0.0286 0.000499005 -0.049207 0.0235 0.0043049 -0.0513559 0.0235 0.0047746 -0.0491726 0.0235 0.00391195 -0.0513559 0.0235 0.0047746 -0.049207 0.0235 0.0043049 -0.0487468 0.0235 0.00602198 -0.05309 0.0235 0.008517 -0.0513559 0.0235 0.0047746 -0.0487468 0.0235 0.00602198 -0.05309 0.0235 0.008517 -0.0487468 0.0235 0.00602198 -0.0498482 0.0235 0.00953849 -0.05309 0.0235 0.008517 -0.0498482 0.0235 0.00953849 -0.050607 0.0235 0.013055 -0.048218 0.0235 0.007994899999999999 -0.0498482 0.0235 0.00953849 -0.0483201 0.0235 0.00761383 -0.048874 -0.0286 0.000499005 -0.04726 -0.0286 -0.002964 -0.041096 -0.0286 -0.00728 -0.053965 0.0235 0.003418 -0.053137 0.0235 -0.001689 -0.0498016 0.0235 -0.000583624 -0.0498016 0.0235 -0.000583624 -0.053137 0.0235 -0.001689 -0.04726 0.0235 -0.002964 -0.0487073 0.0235 0.000141374 -0.0498016 0.0235 -0.000583624 -0.04726 0.0235 -0.002964 -0.0487073 0.0235 0.000141374 -0.04726 -0.0286 -0.002964 -0.048874 -0.0286 0.000499005 -0.0487073 0.0235 0.000141374 -0.04726 0.0235 -0.002964 -0.04726 -0.0286 -0.002964 -0.044558 -0.0286 -0.005665 -0.04726 -0.0286 -0.002964 -0.046981 0.0235 -0.00324293 -0.04726 -0.0286 -0.002964 -0.04726 0.0235 -0.002964 -0.046981 0.0235 -0.00324293 -0.048874 0.0235 0.000499 -0.0498016 0.0235 -0.000583624 -0.0487073 0.0235 0.000141374 -0.053965 0.0235 0.003418 -0.0498016 0.0235 -0.000583624 -0.0489207 0.0235 0.00103219 -0.053965 0.0235 0.003418 -0.0513559 0.0235 0.0047746 -0.05309 0.0235 0.008517 -0.0526777 0.0360041 0.00837336 -0.053965 0.0235 0.003418 -0.05309 0.0235 0.008517 -0.0526777 0.0360041 0.00837336 -0.0535283 0.0360042 0.00341608 -0.053965 0.0235 0.003418 -0.0502633 0.0360041 0.0127857 -0.0526777 0.0360041 0.00837336 -0.05309 0.0235 0.008517 -0.0476225 0.043 0.00539422 -0.0526777 0.0360041 0.00837336 -0.0502633 0.0360041 0.0127857 -0.0502633 0.0360041 0.0127857 -0.0452584 0.043 0.00884209 -0.0476225 0.043 0.00539422 -0.0502633 0.0360041 0.0127857 -0.0465467 0.0360042 0.0161752 -0.0452584 0.043 0.00884209 -0.050607 0.0235 0.013055 -0.0465467 0.0360042 0.0161752 -0.0502633 0.0360041 0.0127857 -0.0526777 0.0360041 0.00837336 -0.0476225 0.043 0.00539422 -0.0485013 0.043 0.000921354 -0.046027 0.0235 0.011124 -0.0462533 0.0235 0.0108008 -0.046027 -0.0286 0.011124 -0.0452584 0.043 0.00884209 -0.0419056 0.043 0.0108452 -0.0397689 0.0429547 -0.008889970000000001 -0.0402787 0.0360042 0.0184351 -0.0399489 0.043 0.0112175 -0.0419318 0.0360042 0.0181741 -0.039342 0.0235 0.019023 -0.0378286 0.0235 0.0160817 -0.035402 0.0235 0.013971 -0.019914 0.0235 -0.011501 -0.022211 0.0235 -0.005954 -0.030471 0.0235 -0.0044321 -0.030471 0.0235 -0.0044321 -0.0336 0.0235 -0.006624 -0.019914 0.0235 -0.011501 -0.041096 -0.0286 -0.00728 -0.0442005 0.0235 -0.00583178 -0.041096 0.0235 -0.0072791 -0.041096 0.0235 -0.0072791 -0.03729 -0.0286 -0.007612 -0.041096 -0.0286 -0.00728 -0.03729 0.0235 -0.007612 -0.0336 -0.0286 -0.006624 -0.03729 -0.0286 -0.007612 -0.03729 -0.0286 -0.007612 -0.0336 -0.0286 -0.006624 -0.041096 -0.0286 -0.00728 -0.041096 -0.0286 -0.00728 -0.0336 -0.0286 -0.006624 -0.030471 -0.0286 -0.004433 -0.0336 -0.0286 -0.006624 -0.03729 0.0235 -0.007612 -0.0336 0.0235 -0.006624 -0.016259 0.0235 -0.016264 -0.019914 0.0235 -0.011501 -0.03729 0.0235 -0.007612 -0.019914 0.0235 -0.011501 -0.0336 0.0235 -0.006624 -0.03729 0.0235 -0.007612 -0.041096 0.0235 -0.0072791 -0.03729 0.0235 -0.007612 -0.03729 -0.0286 -0.007612 -0.022995 0.0235 -1.00185e-06 -0.027291 0.0235 0.002387 -0.02828 0.0235 -0.001303 -0.02828 0.0235 -0.001303 -0.027291 0.0235 0.002387 -0.027291 -0.0286 0.002387 -0.022211 0.0235 -0.005954 -0.022995 0.0235 -1.00185e-06 -0.02828 0.0235 -0.001303 -0.011495 0.0235 0.019918 -0.008886140000000001 0.0234464 0.0209656 -0.039342 0.0235 0.019023 -0.039342 0.0235 0.019023 -0.016259 0.0235 0.016263 -0.011495 0.0235 0.019918 -0.0322975 0.0235 0.0125237 -0.03194 0.0235 0.0123569 -0.039342 0.0235 0.019023 -0.039342 0.0235 0.019023 -0.03194 0.0235 0.0123569 -0.016259 0.0235 0.016263 -0.019914 0.0235 0.011499 -0.016259 0.0235 0.016263 -0.03194 0.0235 0.0123569 -0.03194 -0.0286 0.012356 -0.03194 0.0235 0.0123569 -0.0322975 0.0235 0.0125237 -0.0336203 0.0235 0.0131404 -0.0322975 0.0235 0.0125237 -0.039342 0.0235 0.019023 -0.029238 0.0235 0.009655 -0.03194 0.0235 0.0123569 -0.03194 -0.0286 0.012356 -0.022995 0.0235 -1.00185e-06 -0.022211 0.0235 0.005952 -0.027291 0.0235 0.002387 -0.039342 0.0235 0.019023 -0.035402 0.0235 0.013971 -0.0336203 0.0235 0.0131404 -0.027291 -0.0286 0.002387 -0.02828 -0.0286 -0.001303 -0.02828 0.0235 -0.001303 -0.035402 -0.0286 0.013971 -0.03194 -0.0286 0.012356 -0.0322975 0.0235 0.0125237 -0.030471 0.0235 -0.0044321 -0.02828 0.0235 -0.001303 -0.02828 -0.0286 -0.001303 -0.030471 -0.0286 -0.004433 -0.0336 0.0235 -0.006624 -0.030471 0.0235 -0.0044321 -0.02828 -0.0286 -0.001303 -0.030471 -0.0286 -0.004433 -0.030471 0.0235 -0.0044321 -0.029238 0.0235 0.009655 -0.03194 -0.0286 0.012356 -0.029238 -0.0286 0.009655 -0.035402 -0.0286 0.013971 -0.0322975 0.0235 0.0125237 -0.0336203 0.0235 0.0131404 -0.016259 0.0235 -0.016264 -0.03729 0.0235 -0.007612 -0.042177 0.0235 -0.011871 -0.0503494 0.0360041 -0.00598325 -0.0527234 0.0360042 -0.00154921 -0.0474746 0.043 -0.00412013 -0.0466645 0.0360041 -0.00940678 -0.0503494 0.0360041 -0.00598325 -0.0474746 0.043 -0.00412013 0.01805 0.0360042 0.0130661 0.021001 0.0360042 0.0074528 0.0146488 0.043 0.00616896 0.0146488 0.043 0.00616896 0.021001 0.0360042 0.0074528 0.0163593 0.043 0.000719893 0.0146488 0.043 0.00616896 0.0163593 0.043 0.000719893 0.00141629 0.043 -0.0205554 0.019923 0.0235 0.011499 0.021001 0.0360042 0.0074528 0.01805 0.0360042 0.0130661 0.016268 0.0235 0.016263 0.019923 0.0235 0.011499 0.01805 0.0360042 0.0130661 0.0163593 0.043 0.000719893 0.0161782 0.043 -0.00531048 0.00141629 0.043 -0.0205554 0.0113701 0.043 0.0105823 0.01805 0.0360042 0.0130661 0.0146488 0.043 0.00616896 0.0161782 0.043 -0.00531048 0.0163593 0.043 0.000719893 0.02225 0.0360042 0.00123562 -0.016259 0.0235 -0.016264 -0.042177 0.0235 -0.011871 -0.011495 0.0235 -0.01992 0.011505 0.0235 -0.01992 0.0103707 0.0360042 -0.0197223 0.0155071 0.0360042 -0.0160034 0.016268 0.0235 -0.016264 0.011505 0.0235 -0.01992 0.0155071 0.0360042 -0.0160034 0.019923 0.0235 -0.011501 0.0155071 0.0360042 -0.0160034 0.0193874 0.0360042 -0.0109875 0.0155071 0.0360042 -0.0160034 0.019923 0.0235 -0.011501 0.016268 0.0235 -0.016264 0.00923913 0.043 -0.0170513 0.0193874 0.0360042 -0.0109875 0.0155071 0.0360042 -0.0160034 0.0155071 0.0360042 -0.0160034 0.0103707 0.0360042 -0.0197223 0.00923913 0.043 -0.0170513 0.005958 0.0235 -0.022217 0.001225 0.0235 -0.022685 0.00129 0.036 -0.021999 0.001225 0.0235 -0.022685 -0.011495 0.0235 -0.01992 0.00129 0.036 -0.021999 0.005958 0.0235 -0.022217 0.00129 0.036 -0.021999 0.004347 0.036 -0.021604 0.005958 0.0235 -0.022217 0.004347 0.036 -0.021604 0.0103707 0.0360042 -0.0197223 0.0103707 0.0360042 -0.0197223 0.004347 0.036 -0.021604 0.00923913 0.043 -0.0170513 -0.042177 0.0235 -0.011871 0.00129 0.036 -0.021999 -0.011495 0.0235 -0.01992 0.011505 0.0235 -0.01992 0.005958 0.0235 -0.022217 0.0103707 0.0360042 -0.0197223 0.0193874 0.0360042 -0.0109875 0.022221 0.0235 -0.005954 0.019923 0.0235 -0.011501 0.004347 0.036 -0.021604 0.00129 0.036 -0.021999 0.00923913 0.043 -0.0170513 -0.0397689 0.0429547 -0.008889970000000001 -0.0474746 0.043 -0.00412013 -0.0485013 0.043 0.000921354 -0.0474746 0.043 -0.00412013 -0.0535283 0.0360042 0.00341608 -0.0485013 0.043 0.000921354 -0.0397689 0.0429547 -0.008889970000000001 -0.0466645 0.0360041 -0.00940678 -0.0474746 0.043 -0.00412013 0.00511009 0.0360043 0.0216861 -0.0402787 0.0360042 0.0184351 0.00514601 0.0235 0.022126 -0.008886140000000001 0.0234464 0.0209656 0.00514601 0.0235 0.022126 -0.0402787 0.0360042 0.0184351 0.00514601 0.0235 0.022126 0.00812098 0.0360042 0.0207478 0.00511009 0.0360043 0.0216861 0.00812098 0.0360042 0.0207478 0.0136376 0.0360042 0.017621 0.00692399 0.043 0.0135322 0.0136376 0.0360042 0.017621 0.00812098 0.0360042 0.0207478 0.011505 0.0235 0.019918 0.00812098 0.0360042 0.0207478 0.00514601 0.0235 0.022126 0.011505 0.0235 0.019918 0.00812098 0.0360042 0.0207478 0.00692399 0.043 0.0135322 0.00446549 0.043 0.014301 0.00446549 0.043 0.014301 0.00141629 0.043 -0.0205554 -0.0397689 0.0429547 -0.008889970000000001 0.00141629 0.043 -0.0205554 0.00446549 0.043 0.014301 0.00692399 0.043 0.0135322 -0.0397689 0.0429547 -0.008889970000000001 0.00141629 0.043 -0.0205554 0.00129 0.036 -0.021999 0.00141629 0.043 -0.0205554 0.00923913 0.043 -0.0170513 0.00129 0.036 -0.021999 0.00692399 0.043 0.0135322 0.0113701 0.043 0.0105823 0.00141629 0.043 -0.0205554 -0.042068 0.036 -0.0114484 -0.0397689 0.0429547 -0.008889970000000001 0.00129 0.036 -0.021999 -0.0397689 0.0429547 -0.008889970000000001 -0.042068 0.036 -0.0114484 -0.0466645 0.0360041 -0.00940678 0.00141629 0.043 -0.0205554 0.0138756 0.043 -0.0114083 0.00923913 0.043 -0.0170513 0.00692399 0.043 0.0135322 0.0136376 0.0360042 0.017621 0.0113701 0.043 0.0105823 -0.042068 0.036 -0.0114484 0.00129 0.036 -0.021999 -0.042177 0.0235 -0.011871 0.022221 0.0235 -0.005954 0.0193874 0.0360042 -0.0109875 0.0216979 0.0360042 -0.00508161 0.0161782 0.043 -0.00531048 0.02225 0.0360042 0.00123562 0.0216979 0.0360042 -0.00508161 0.023005 0.0235 -1.00587e-06 0.0216979 0.0360042 -0.00508161 0.02225 0.0360042 0.00123562 0.0216979 0.0360042 -0.00508161 0.023005 0.0235 -1.00587e-06 0.022221 0.0235 -0.005954 0.011505 0.0235 0.019918 0.016268 0.0235 0.016263 0.0136376 0.0360042 0.017621 -0.046905 0.0235 -0.009771 -0.042177 0.0235 -0.011871 -0.041096 0.0235 -0.0072791 -0.042177 0.0235 -0.011871 -0.046905 0.0235 -0.009771 -0.0466645 0.0360041 -0.00940678 -0.046905 0.0235 -0.009771 -0.0503494 0.0360041 -0.00598325 -0.0466645 0.0360041 -0.00940678 0.016268 0.0235 0.016263 0.01805 0.0360042 0.0130661 0.0136376 0.0360042 0.017621 0.019923 0.0235 0.011499 0.022221 0.0235 0.005952 0.021001 0.0360042 0.0074528 0.02225 0.0360042 0.00123562 0.021001 0.0360042 0.0074528 0.022221 0.0235 0.005952 -0.0527234 0.0360042 -0.00154921 -0.0503494 0.0360041 -0.00598325 -0.050695 0.0235 -0.00625 -0.041096 -0.0286 -0.00728 -0.02828 -0.0286 -0.001303 -0.027291 -0.0286 0.002387 -0.041096 -0.0286 -0.00728 -0.027291 -0.0286 0.002387 -0.027624 -0.0286 0.006193 -0.041096 -0.0286 -0.00728 -0.027624 -0.0286 0.006193 -0.029238 -0.0286 0.009655 -0.029238 -0.0286 0.009655 -0.027624 -0.0286 0.006193 -0.027624 0.0235 0.006193 -0.027624 -0.0286 0.006193 -0.027291 0.0235 0.002387 -0.027624 0.0235 0.006193 -0.046905 0.0235 -0.009771 -0.050695 0.0235 -0.00625 -0.0503494 0.0360041 -0.00598325 -0.029238 -0.0286 0.009655 -0.027624 0.0235 0.006193 -0.029238 0.0235 0.009655 -0.019914 0.0235 0.011499 -0.029238 0.0235 0.009655 -0.027624 0.0235 0.006193 -0.022211 0.0235 0.005952 -0.019914 0.0235 0.011499 -0.027624 0.0235 0.006193 0.00511009 0.0360043 0.0216861 0.00446549 0.043 0.014301 -0.0402787 0.0360042 0.0184351 -0.0476225 0.043 0.00539422 -0.0452584 0.043 0.00884209 -0.0397689 0.0429547 -0.008889970000000001 -0.050607 0.0235 0.013055 -0.046784 0.0235 0.016542 -0.0465467 0.0360042 0.0161752 0.0161782 0.043 -0.00531048 0.0216979 0.0360042 -0.00508161 0.0138756 0.043 -0.0114083 -0.053137 0.0235 -0.001689 -0.046981 0.0235 -0.00324293 -0.04726 0.0235 -0.002964 0.00446549 0.043 0.014301 -0.0399489 0.043 0.0112175 -0.0402787 0.0360042 0.0184351 -0.044558 -0.0286 -0.005665 -0.046981 0.0235 -0.00324293 -0.0456382 0.0235 -0.00458525 -0.0485013 0.043 0.000921354 -0.0476225 0.043 0.00539422 -0.0397689 0.0429547 -0.008889970000000001 -0.041096 0.0235 -0.0072791 -0.050695 0.0235 -0.00625 -0.046905 0.0235 -0.009771 0.0138756 0.043 -0.0114083 0.00141629 0.043 -0.0205554 0.0161782 0.043 -0.00531048 -0.042037 0.0235 0.018598 -0.0378286 0.0235 0.0160817 -0.039342 0.0235 0.019023 -0.050607 0.0235 0.013055 -0.0498482 0.0235 0.00953849 -0.0466064 0.0235 0.0102964 -0.048874 0.0235 0.000499 -0.0487073 0.0235 0.000141374 -0.048874 -0.0286 0.000499005 -0.035402 -0.0286 0.013971 -0.0336203 0.0235 0.0131404 -0.035402 0.0235 0.013971 -0.0456382 0.0235 -0.00458525 -0.046981 0.0235 -0.00324293 -0.053137 0.0235 -0.001689 -0.0487468 0.0235 0.00602198 -0.049207 0.0235 0.0043049 -0.049207 -0.0286 0.004304 -0.0483201 0.0235 0.00761383 -0.0487468 0.0235 0.00602198 -0.049207 -0.0286 0.004304 -0.0397689 0.0429547 -0.008889970000000001 -0.0399489 0.043 0.0112175 0.00446549 0.043 0.014301 -0.030471 -0.0286 -0.004433 -0.0336 -0.0286 -0.006624 -0.0336 0.0235 -0.006624 0.00511009 0.0360043 0.0216861 0.00812098 0.0360042 0.0207478 0.00446549 0.043 0.014301 -0.03729 0.0235 -0.007612 -0.041096 0.0235 -0.0072791 -0.042177 0.0235 -0.011871 -0.0378286 0.0235 0.0160817 -0.042037 0.0235 0.018598 -0.0373685 0.0235 0.0141431 0.022221 0.0235 0.005952 0.023005 0.0235 -1.00587e-06 0.02225 0.0360042 0.00123562 -0.041096 -0.0286 -0.00728 -0.03194 -0.0286 0.012356 -0.035402 -0.0286 0.013971 0.0136376 0.0360042 0.017621 0.01805 0.0360042 0.0130661 0.0113701 0.043 0.0105823 -0.0527234 0.0360042 -0.00154921 -0.0535283 0.0360042 0.00341608 -0.0474746 0.043 -0.00412013 -0.0535283 0.0360042 0.00341608 -0.0527234 0.0360042 -0.00154921 -0.053137 0.0235 -0.001689 -0.046784 0.0235 0.016542 -0.042898 0.0235 0.013315 -0.0428502 0.0235 0.0133278 0.0138756 0.043 -0.0114083 0.0193874 0.0360042 -0.0109875 0.00923913 0.043 -0.0170513 -0.0502633 0.0360041 0.0127857 -0.05309 0.0235 0.008517 -0.050607 0.0235 0.013055 -0.03194 0.0235 0.0123569 -0.029238 0.0235 0.009655 -0.019914 0.0235 0.011499 -0.022211 0.0235 0.005952 -0.027624 0.0235 0.006193 -0.027291 0.0235 0.002387 -0.0526777 0.0360041 0.00837336 -0.0485013 0.043 0.000921354 -0.0535283 0.0360042 0.00341608 -0.027291 0.0235 0.002387 -0.027624 -0.0286 0.006193 -0.027291 -0.0286 0.002387 0.02225 0.0360042 0.00123562 0.0163593 0.043 0.000719893 0.021001 0.0360042 0.0074528 -0.0462533 0.0235 0.0108008 -0.048218 -0.0286 0.007993999999999999 -0.046027 -0.0286 0.011124 -0.042177 0.0235 -0.011871 -0.0466645 0.0360041 -0.00940678 -0.042068 0.036 -0.0114484 -0.039342 0.0235 0.019023 -0.008886140000000001 0.0234464 0.0209656 -0.0402787 0.0360042 0.0184351 0.0193874 0.0360042 -0.0109875 0.0138756 0.043 -0.0114083 0.0216979 0.0360042 -0.00508161 -0.041096 -0.0286 -0.00728 -0.030471 -0.0286 -0.004433 -0.02828 -0.0286 -0.001303 -0.0527234 0.0360042 -0.00154921 -0.050695 0.0235 -0.00625 -0.053137 0.0235 -0.001689 0.0113701 0.043 0.0105823 0.0146488 0.043 0.00616896 0.00141629 0.043 -0.0205554 -0.0483201 0.0235 0.00761383 -0.049207 -0.0286 0.004304 -0.048218 -0.0286 0.007993999999999999 -0.042037 0.0235 0.018598 -0.039208 0.0235 0.014304 -0.0373685 0.0235 0.0141431 -0.03194 -0.0286 0.012356 -0.041096 -0.0286 -0.00728 -0.029238 -0.0286 0.009655 -0.0483201 0.0235 0.00761383 -0.0498482 0.0235 0.00953849 -0.0487468 0.0235 0.00602198 -0.0535283 0.0360042 0.00341608 -0.053137 0.0235 -0.001689 -0.053965 0.0235 0.003418 -0.046027 -0.0286 0.011124 -0.0432211 0.0235 0.0130887 -0.046027 0.0235 0.011124 -0.041096 -0.0286 -0.00728 -0.044558 -0.0286 -0.005665 -0.0442005 0.0235 -0.00583178 -0.041096 -0.0286 -0.00728 -0.04726 -0.0286 -0.002964 -0.044558 -0.0286 -0.005665 -0.0452584 0.043 0.00884209 -0.0465467 0.0360042 0.0161752 -0.0419056 0.043 0.0108452 -0.022211 0.0235 -0.005954 -0.02828 0.0235 -0.001303 -0.030471 0.0235 -0.0044321 -0.048874 0.0235 0.000499 -0.0489207 0.0235 0.00103219 -0.0498016 0.0235 -0.000583624 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035

    -
    -
    - - - 0 0 0 - 1 0 0 0 - - true - - - -
    - - - - -0.02 -0.0285 0.054671 -0.02 -0.0285 0.045 -0.0155077 -0.0285 0.054671 -0.0155077 -0.0285 0.054671 -0.02 -0.0285 0.045 -0.0126098 -0.0285 0.054671 -0.0126098 -0.0285 0.054671 -0.02 -0.0285 0.045 -0.007975370000000001 -0.0285 0.054671 0.00705375 -0.0285 0.054671 0.00622951 -0.0285 0.045 0.009737000000000001 -0.0285 0.054671 0.009737000000000001 -0.0285 0.054671 0.00622951 -0.0285 0.045 0.0136565 -0.0285 0.054671 0.0136565 -0.0285 0.054671 0.00622951 -0.0285 0.045 0.0158576 -0.0285 0.054671 0.0158576 -0.0285 0.054671 0.00622951 -0.0285 0.045 0.0189128 -0.0285 0.054671 0.00705375 -0.0285 0.054671 0.0022951 -0.0285 0.054671 -0.000543607 -0.0285 0.0498355 0.0022951 -0.0285 0.054671 -0.000476526 -0.0285 0.054671 -0.000543607 -0.0285 0.0498355 -0.000476526 -0.0285 0.054671 -0.0053667 -0.0285 0.054671 -0.000543607 -0.0285 0.0498355 -0.0053667 -0.0285 0.054671 -0.007975370000000001 -0.0285 0.054671 -0.000543607 -0.0285 0.0498355 -0.02 -0.0285 0.045 0.00622951 -0.0285 0.045 -0.000543607 -0.0285 0.0498355 -0.007975370000000001 -0.0285 0.054671 -0.02 -0.0285 0.045 -0.000543607 -0.0285 0.0498355 0.00622951 -0.0285 0.045 0.00705375 -0.0285 0.054671 -0.000543607 -0.0285 0.0498355 0.02 0.0279235 0.054671 0.02 -0.0285 0.054671 0.02 -0.023 0.045 0.02 -0.023 0.045 0.02 -0.0285 0.054671 0.02 -0.0285 0.045 0.02 0.0279235 0.054671 0.02 -0.023 0.045 0.02 -0.023 0.0278922 0.02 0.0279235 0.054671 0.0199992 0.0294999 0.0315 0.02 0.0295 0.054671 0.02 0.0279235 0.054671 0.0199993 0.024 0.0315 0.0199992 0.0294999 0.0315 0.02 -0.023 0.0278922 0.02 -0.023 0.025 0.0199991 0.024 0.025 0.02 -0.023 0.0278922 0.0199991 0.024 0.025 0.0199993 0.024 0.0315 0.02 -0.023 0.0278922 0.0199993 0.024 0.0315 0.02 0.0279235 0.054671 0.0119115 0.0295 0.054671 0.0158576 0.0295 0.054671 0.0114746 0.0295 0.0315 0.0158576 0.0295 0.054671 0.0181113 0.0295 0.054671 0.0199992 0.0294999 0.0315 0.0181113 0.0295 0.054671 0.02 0.0295 0.054671 0.0199992 0.0294999 0.0315 0.0114746 0.0295 0.0315 0.0158576 0.0295 0.054671 0.0199992 0.0294999 0.0315 0.009737000000000001 0.0295 0.054671 0.0119115 0.0295 0.054671 0.000543593 0.0295 0.0430855 0.0114746 0.0295 0.0315 -0.0189128 0.0295 0.054671 0.000543593 0.0295 0.0430855 -0.0189128 0.0295 0.054671 -0.0178954 0.0295 0.054671 0.000543593 0.0295 0.0430855 -0.0178954 0.0295 0.054671 -0.0126098 0.0295 0.054671 0.000543593 0.0295 0.0430855 -0.0126098 0.0295 0.054671 -0.0100853 0.0295 0.054671 0.000543593 0.0295 0.0430855 -0.0100853 0.0295 0.054671 -0.0053667 0.0295 0.054671 0.000543593 0.0295 0.0430855 -0.0053667 0.0295 0.054671 -0.00268018 0.0295 0.054671 0.000543593 0.0295 0.0430855 -0.00268018 0.0295 0.054671 0.0022951 0.0295 0.054671 0.000543593 0.0295 0.0430855 0.0022951 0.0295 0.054671 0.00492983 0.0295 0.054671 0.000543593 0.0295 0.0430855 0.00492983 0.0295 0.054671 0.009737000000000001 0.0295 0.054671 0.000543593 0.0295 0.0430855 0.0119115 0.0295 0.054671 0.0114746 0.0295 0.0315 0.000543593 0.0295 0.0430855 0.00622951 -0.0285 0.045 0.02 -0.0285 0.045 0.0189128 -0.0285 0.054671 0.0189128 -0.0285 0.054671 0.02 -0.0285 0.045 0.0199228 -0.0285 0.054671 0.0199228 -0.0285 0.054671 0.02 -0.0285 0.045 0.02 -0.0285 0.054671 -0.02 0.0279235 0.054671 -0.02 -0.023 0.0278922 -0.02 -0.023 0.045 -0.02 -0.023 0.045 -0.02 -0.0285 0.045 -0.02 -0.0285 0.054671 -0.02 0.0279235 0.054671 -0.02 -0.023 0.045 -0.02 -0.0285 0.054671 -0.02 -0.0285 0.045 -0.0199802 -0.0285 0.0250151 0.00622951 -0.0285 0.045 0.02 -0.023 0.0278922 0.02 -0.023 0.045 0.02 -0.0252346 0.0267172 0.02 -0.0285 0.045 0.02 -0.0285 0.025 0.02 -0.02575 0.035 0.02 -0.0285 0.025 0.02 -0.0252346 0.0267172 0.02 -0.02575 0.035 0.02 -0.0252346 0.0267172 0.02 -0.023 0.045 0.02 -0.02575 0.035 0.02 -0.023 0.045 0.02 -0.0285 0.045 0.02 -0.02575 0.035 0.02 -0.023 0.025 -0.00222222 -0.023 0.025 0.016206 0.024 0.025 -0.00222222 -0.023 0.025 -0.016207 -0.023 0.025 0.016206 0.024 0.025 0.02 -0.023 0.025 0.016206 0.024 0.025 0.0199991 0.024 0.025 0.02 -0.0242222 0.0264461 0.02 -0.023 0.025 0.02 -0.023 0.0278922 0.02 -0.0242222 0.0264461 0.02 -0.0254444 0.025 0.02 -0.023 0.025 0.02 -0.0242222 0.0264461 0.02 -0.0252346 0.0267172 0.02 -0.0254444 0.025 0.02 -0.0242222 0.0264461 0.02 -0.023 0.0278922 0.02 -0.0252346 0.0267172 -0.019319 0.024 -0.005176 0.02 0.024 0 0.0130316 0.024 0.025 0.0130316 0.024 0.025 0.02 0.024 0 0.016206 0.024 0.025 0.016206 0.024 0.025 0.02 0.024 0 0.0199991 0.024 0.025 0.0199993 0.024 0.0315 0.02 0.024 0 0.0199991 0.024 0.025 0.0114746 0.0295 0.0315 0.0199992 0.0294999 0.0315 0.019999 0.0295 0.025 -0.02 0.0295 0.054671 -0.0189128 0.0295 0.054671 -0.02 0.0295 0.0315 -0.02 0.0295 0.025 -0.02 0.0295 0.0315 -0.020001 0.0295 0.025 -0.02 0.0295 0.0315 -0.0189128 0.0295 0.054671 0.0114746 0.0295 0.0315 -0.02 0.0295 0.054671 -0.020001 0.0295 0.025 -0.02 0.0295 0.0315 -0.0199802 -0.0285 0.0250151 -0.0199802 -0.0285 0.025 0.00276545 -0.0285 0.025 -0.0199802 -0.0285 0.0250151 0.00276545 -0.0285 0.025 0.00622951 -0.0285 0.045 0.00622951 -0.0285 0.045 0.00276545 -0.0285 0.025 0.02 -0.0285 0.045 -0.02 0.0295 0.054671 -0.020001 0.0295 0.025 -0.02 0.0279235 0.054671 -0.020001 0.0295 0.025 -0.02 -0.023 0.025 -0.02 -0.023 0.0278922 -0.02 0.0279235 0.054671 -0.020001 0.0295 0.025 -0.02 -0.023 0.0278922 -0.02 -0.0285 0.045 -0.02 -0.023 0.045 -0.02 -0.02575 0.0356039 -0.02 -0.023 0.045 -0.02 -0.023 0.0278922 -0.02 -0.02575 0.0356039 -0.02 -0.023 0.0278922 -0.02 -0.0262032 0.0262078 -0.02 -0.02575 0.0356039 -0.02 -0.0262032 0.0262078 -0.02 -0.0285 0.045 -0.02 -0.02575 0.0356039 -0.02 -0.0285 0.025 -0.0199802 -0.0285 0.0250151 -0.02 -0.0285 0.045 0.00276545 -0.0285 0.025 0.02 -0.0285 0.025 0.02 -0.0285 0.045 0.02 -0.0285 0.025 0.02 -0.0254444 0.025 0.02 -0.0252346 0.0267172 -0.00222222 -0.023 0.025 0.02 -0.023 0.025 0.02 -0.023 0 -0.016207 -0.023 0.025 -0.00222222 -0.023 0.025 -0.02 -0.023 0 -0.02 -0.023 0.025 -0.016207 -0.023 0.025 -0.02 -0.023 0 -0.02 -0.023 0 -0.00222222 -0.023 0.025 0.02 -0.023 0 -0.02 0.0295 0.025 -0.020001 0.0295 0.025 -0.02 0.0251349 0.025 -0.02 0.024 0.025 -0.02 0.0251349 0.025 -0.020001 0.0295 0.025 -0.02 0.024 0.025 -0.020001 0.0295 0.025 -0.02 -0.023 0.025 -0.02 0.024 0.025 -0.0198793 0.024 0.025 -0.0018975 0.00325 0.025 -0.0198793 0.024 0.025 0.0130316 0.024 0.025 -0.0018975 0.00325 0.025 0.0130316 0.024 0.025 0.016206 0.024 0.025 -0.0018975 0.00325 0.025 0.016206 0.024 0.025 -0.016207 -0.023 0.025 -0.0018975 0.00325 0.025 -0.016207 -0.023 0.025 -0.02 -0.023 0.025 -0.0018975 0.00325 0.025 -0.02 -0.023 0.025 -0.02 0.024 0.025 -0.0018975 0.00325 0.025 0.02 -0.023 0.025 0.02 -0.0254444 0.025 0.02 -0.023 0 0.02 -0.023 0 0.02 -0.0254444 0.025 0.02 -0.0285 0 0.0199992 0.0294999 0.0315 0.0199993 0.024 0.0315 0.02 0.024 0 -0.0198793 0.024 0.025 -0.019319 0.024 -0.005176 0.0130316 0.024 0.025 -0.019319 0.024 -0.005176 0.019318 0.024 -0.005176 0.02 0.024 0 -0.011746 0.0295 0.025 0.019999 0.0295 0.025 0.02 0.0295 0 0.02 0.0295 0 0.0199992 0.0294999 0.0315 0.019999 0.0295 0.025 0.0114746 0.0295 0.0315 0.019999 0.0295 0.025 -5.0012e-07 0.0295 0.02825 0.019999 0.0295 0.025 -0.011746 0.0295 0.025 -5.0012e-07 0.0295 0.02825 -0.011746 0.0295 0.025 -0.02 0.0295 0.0315 -5.0012e-07 0.0295 0.02825 -0.02 0.0295 0.0315 0.0114746 0.0295 0.0315 -5.0012e-07 0.0295 0.02825 -0.02 0.0295 0.025 -0.02 0.0295 0.0315 -0.011746 0.0295 0.025 -0.0199802 -0.0285 0.0250151 -0.0199802 -0.0285 0.025 -0.02 -0.0285 0.025 -0.0199802 -0.0285 0.025 -0.019954 -0.0285 -0.001365 0.00276545 -0.0285 0.025 -0.02 -0.023 0.0278922 -0.02 -0.023 0.025 -0.02 -0.0262032 0.0262078 -0.02 -0.023 0.025 -0.02 -0.0260556 0.025 -0.02 -0.0262032 0.0262078 -0.02 -0.0262032 0.0262078 -0.02 -0.0285 0.025 -0.02 -0.0285 0.045 -0.019954 -0.0285 -0.001365 0.02 -0.0285 0 0.00276545 -0.0285 0.025 0.00276545 -0.0285 0.025 0.02 -0.0285 0 0.02 -0.0285 0.025 0.02 -0.0254444 0.025 0.02 -0.0285 0.025 0.02 -0.0285 0 -0.019954 -0.023 -0.001365 -0.02 -0.023 0 0.02 -0.023 0 -0.02 -0.023 0.025 -0.02 -0.023 0 -0.02 -0.0260556 0.025 -0.02 0.0295 0 -0.02 0.024 0 -0.02 0.0251349 0.025 -0.02 0.0251349 0.025 -0.02 0.024 0 -0.02 0.024 0.025 -0.02 0.024 0.025 -0.02 0.024 0 -0.0198793 0.024 0.025 -0.0198793 0.024 0.025 -0.02 0.024 0 -0.019319 0.024 -0.005176 -0.02 0.0295 0.025 -0.02 0.0295 0 -0.02 0.0251349 0.025 0.019953 -0.023 -0.001365 0.02 -0.023 0 0.02 -0.0285 0 0.02 0.0295 0 0.0199992 0.0294999 0.0315 0.02 0.024 0 -0.019319 0.024 -0.005176 0.01732 0.024 -0.01 0.019318 0.024 -0.005176 0.019318 0.0295 -0.005176 0.02 0.024 0 0.019318 0.024 -0.005176 -0.02 0.0295 0.025 -0.011746 0.0295 0.025 -0.02 0.0295 0 -0.02 0.0295 0 -0.011746 0.0295 0.025 0.02 0.0295 0 -0.02 -0.0285 0.025 -0.02 -0.0285 0 -0.0199802 -0.0285 0.025 -0.02 -0.0285 0 -0.019954 -0.0285 -0.001365 -0.0199802 -0.0285 0.025 -0.02 -0.0262032 0.0262078 -0.02 -0.0260556 0.025 -0.02 -0.0285 0.025 -0.019954 -0.0285 -0.001365 0.019953 -0.0285 -0.001365 0.02 -0.0285 0 -0.018846 -0.023 -0.006698 -0.019954 -0.023 -0.001365 0.02 -0.023 0 -0.02 -0.023 0 -0.019954 -0.023 -0.001365 -0.019954 -0.0285 -0.001365 -0.02 -0.023 0 -0.02 -0.0285 0 -0.02 -0.0260556 0.025 -0.02 -0.0260556 0.025 -0.02 -0.0285 0 -0.02 -0.0285 0.025 -0.02 0.0295 0 -0.019319 0.024 -0.005176 -0.02 0.024 0 0.019953 -0.023 -0.001365 0.02 -0.0285 0 0.019953 -0.0285 -0.001365 0.019953 -0.023 -0.001365 0.018845 -0.023 -0.006698 0.02 -0.023 0 0.019318 0.0295 -0.005176 0.02 0.0295 0 0.02 0.024 0 -0.019319 0.024 -0.005176 0.014142 0.024 -0.014142 0.01732 0.024 -0.01 0.01732 0.0295 -0.01 0.019318 0.024 -0.005176 0.01732 0.024 -0.01 0.01732 0.0295 -0.01 0.019318 0.0295 -0.005176 0.019318 0.024 -0.005176 -0.019319 0.0295 -0.005176 -0.02 0.0295 0 0.02 0.0295 0 -0.02 -0.023 0 -0.019954 -0.0285 -0.001365 -0.02 -0.0285 0 -0.019954 -0.0285 -0.001365 0.018845 -0.0285 -0.006698 0.019953 -0.0285 -0.001365 -0.01634 -0.023 -0.011534 -0.018846 -0.023 -0.006698 0.02 -0.023 0 -0.019954 -0.023 -0.001365 -0.018846 -0.023 -0.006698 -0.018846 -0.0285 -0.006698 -0.019954 -0.023 -0.001365 -0.018846 -0.0285 -0.006698 -0.019954 -0.0285 -0.001365 -0.02 0.0295 0 -0.019319 0.0295 -0.005176 -0.019319 0.024 -0.005176 0.018845 -0.023 -0.006698 0.019953 -0.023 -0.001365 0.019953 -0.0285 -0.001365 0.018845 -0.023 -0.006698 0.016339 -0.023 -0.011534 0.02 -0.023 0 0.019318 0.0295 -0.005176 0.01732 0.0295 -0.01 0.02 0.0295 0 -0.019319 0.024 -0.005176 0.009998999999999999 0.024 -0.017321 0.014142 0.024 -0.014142 0.014142 0.0295 -0.014142 0.01732 0.024 -0.01 0.014142 0.024 -0.014142 0.014142 0.0295 -0.014142 0.01732 0.0295 -0.01 0.01732 0.024 -0.01 -0.017321 0.0295 -0.01 -0.019319 0.0295 -0.005176 0.02 0.0295 0 -0.019954 -0.0285 -0.001365 0.016339 -0.0285 -0.011534 0.018845 -0.0285 -0.006698 0.018845 -0.023 -0.006698 0.019953 -0.0285 -0.001365 0.018845 -0.0285 -0.006698 -0.012622 -0.023 -0.015514 -0.01634 -0.023 -0.011534 0.02 -0.023 0 -0.018846 -0.023 -0.006698 -0.01634 -0.023 -0.011534 -0.01634 -0.0285 -0.011534 -0.018846 -0.023 -0.006698 -0.01634 -0.0285 -0.011534 -0.018846 -0.0285 -0.006698 -0.018846 -0.0285 -0.006698 -0.01634 -0.0285 -0.011534 -0.019954 -0.0285 -0.001365 -0.019319 0.0295 -0.005176 -0.017321 0.024 -0.01 -0.019319 0.024 -0.005176 0.02 -0.023 0 0.016339 -0.023 -0.011534 0.012621 -0.023 -0.015514 0.016339 -0.023 -0.011534 0.018845 -0.023 -0.006698 0.018845 -0.0285 -0.006698 0.02 0.0295 0 0.01732 0.0295 -0.01 0.014142 0.0295 -0.014142 -0.019319 0.024 -0.005176 0.005176 0.024 -0.019319 0.009998999999999999 0.024 -0.017321 0.014142 0.024 -0.014142 0.009998999999999999 0.024 -0.017321 0.009998999999999999 0.0295 -0.017321 0.014142 0.024 -0.014142 0.009998999999999999 0.0295 -0.017321 0.014142 0.0295 -0.014142 -0.014143 0.0295 -0.014142 -0.017321 0.0295 -0.01 0.02 0.0295 0 -0.019319 0.0295 -0.005176 -0.017321 0.0295 -0.01 -0.017321 0.024 -0.01 -0.019954 -0.0285 -0.001365 0.012621 -0.0285 -0.015514 0.016339 -0.0285 -0.011534 0.016339 -0.023 -0.011534 0.018845 -0.0285 -0.006698 0.016339 -0.0285 -0.011534 -0.007969 -0.023 -0.018344 -0.012622 -0.023 -0.015514 0.02 -0.023 0 -0.01634 -0.023 -0.011534 -0.012622 -0.023 -0.015514 -0.012622 -0.0285 -0.015514 -0.01634 -0.023 -0.011534 -0.012622 -0.0285 -0.015514 -0.01634 -0.0285 -0.011534 -0.01634 -0.0285 -0.011534 -0.012622 -0.0285 -0.015514 -0.019954 -0.0285 -0.001365 -0.017321 0.024 -0.01 -0.014143 0.024 -0.014142 -0.019319 0.024 -0.005176 0.007967 -0.023 -0.018344 0.02 -0.023 0 0.012621 -0.023 -0.015514 0.012621 -0.023 -0.015514 0.016339 -0.023 -0.011534 0.016339 -0.0285 -0.011534 0.009998999999999999 0.0295 -0.017321 0.02 0.0295 0 0.014142 0.0295 -0.014142 -0.019319 0.024 -0.005176 -1e-06 0.024 -0.02 0.005176 0.024 -0.019319 0.009998999999999999 0.024 -0.017321 0.005176 0.024 -0.019319 0.005176 0.0295 -0.019319 0.009998999999999999 0.024 -0.017321 0.005176 0.0295 -0.019319 0.009998999999999999 0.0295 -0.017321 -0.010001 0.0295 -0.017321 -0.014143 0.0295 -0.014142 0.02 0.0295 0 -0.017321 0.0295 -0.01 -0.014143 0.0295 -0.014142 -0.014143 0.024 -0.014142 -0.017321 0.0295 -0.01 -0.014143 0.024 -0.014142 -0.017321 0.024 -0.01 -0.019954 -0.0285 -0.001365 0.007967 -0.0285 -0.018344 0.012621 -0.0285 -0.015514 0.012621 -0.023 -0.015514 0.016339 -0.0285 -0.011534 0.012621 -0.0285 -0.015514 -0.002724 -0.023 -0.019814 -0.007969 -0.023 -0.018344 0.02 -0.023 0 -0.007969 -0.0285 -0.018344 -0.012622 -0.023 -0.015514 -0.007969 -0.023 -0.018344 -0.007969 -0.0285 -0.018344 -0.012622 -0.0285 -0.015514 -0.012622 -0.023 -0.015514 -0.012622 -0.0285 -0.015514 -0.007969 -0.0285 -0.018344 -0.019954 -0.0285 -0.001365 -0.014143 0.024 -0.014142 -0.010001 0.024 -0.017321 -0.019319 0.024 -0.005176 0.002723 -0.023 -0.019814 0.02 -0.023 0 0.007967 -0.023 -0.018344 0.012621 -0.0285 -0.015514 0.007967 -0.023 -0.018344 0.012621 -0.023 -0.015514 0.005176 0.0295 -0.019319 0.02 0.0295 0 0.009998999999999999 0.0295 -0.017321 -0.019319 0.024 -0.005176 -0.005177 0.024 -0.019319 -1e-06 0.024 -0.02 0.005176 0.024 -0.019319 -1e-06 0.024 -0.02 -1e-06 0.0295 -0.02 0.005176 0.024 -0.019319 -1e-06 0.0295 -0.02 0.005176 0.0295 -0.019319 -0.005177 0.0295 -0.019319 -0.010001 0.0295 -0.017321 0.02 0.0295 0 -0.010001 0.024 -0.017321 -0.014143 0.0295 -0.014142 -0.010001 0.0295 -0.017321 -0.010001 0.024 -0.017321 -0.014143 0.024 -0.014142 -0.014143 0.0295 -0.014142 -0.019954 -0.0285 -0.001365 0.002723 -0.0285 -0.019814 0.007967 -0.0285 -0.018344 0.012621 -0.0285 -0.015514 0.007967 -0.0285 -0.018344 0.007967 -0.023 -0.018344 -0.002724 -0.023 -0.019814 0.02 -0.023 0 0.002723 -0.023 -0.019814 -0.002724 -0.0285 -0.019814 -0.007969 -0.023 -0.018344 -0.002724 -0.023 -0.019814 -0.002724 -0.0285 -0.019814 -0.007969 -0.0285 -0.018344 -0.007969 -0.023 -0.018344 -0.007969 -0.0285 -0.018344 -0.002724 -0.0285 -0.019814 -0.019954 -0.0285 -0.001365 -0.010001 0.024 -0.017321 -0.005177 0.024 -0.019319 -0.019319 0.024 -0.005176 0.007967 -0.0285 -0.018344 0.002723 -0.023 -0.019814 0.007967 -0.023 -0.018344 -1e-06 0.0295 -0.02 0.02 0.0295 0 0.005176 0.0295 -0.019319 -1e-06 0.024 -0.02 -0.005177 0.024 -0.019319 -0.005177 0.0295 -0.019319 -1e-06 0.024 -0.02 -0.005177 0.0295 -0.019319 -1e-06 0.0295 -0.02 -1e-06 0.0295 -0.02 -0.005177 0.0295 -0.019319 0.02 0.0295 0 -0.005177 0.024 -0.019319 -0.010001 0.0295 -0.017321 -0.005177 0.0295 -0.019319 -0.005177 0.024 -0.019319 -0.010001 0.024 -0.017321 -0.010001 0.0295 -0.017321 -0.019954 -0.0285 -0.001365 -0.002724 -0.0285 -0.019814 0.002723 -0.0285 -0.019814 0.007967 -0.0285 -0.018344 0.002723 -0.0285 -0.019814 0.002723 -0.023 -0.019814 0.002723 -0.0285 -0.019814 -0.002724 -0.023 -0.019814 0.002723 -0.023 -0.019814 0.002723 -0.0285 -0.019814 -0.002724 -0.0285 -0.019814 -0.002724 -0.023 -0.019814 0.0648833 -0.0762859 0.052691 0.0648833 0.0762859 0.052691 0.07849399999999999 -0.0351008 0.052691 0.07849399999999999 0.0351008 0.052691 0.07849399999999999 -0.0351008 0.052691 0.0648833 0.0762859 0.052691 0.0648833 0.0762859 0.052691 0.0648833 -0.0762859 0.052691 0.0532069 0.0909377 0.0539902 0.0648833 -0.0762859 0.052691 0.0532069 -0.0909377 0.0539902 0.0532069 0.0909377 0.0539902 0.0532069 -0.0909377 0.0539902 0.0455299 0.09586649999999999 0.0544782 0.0532069 0.0909377 0.0539902 0.0532069 -0.0909377 0.0539902 0.0455299 -0.09586649999999999 0.0544782 0.0455299 0.09586649999999999 0.0544782 0.0455299 -0.09586649999999999 0.0544782 0.033113 0.10193 0.0566797 0.0455299 0.09586649999999999 0.0544782 0.0455299 -0.09586649999999999 0.0544782 0.033113 -0.10193 0.0566797 0.033113 0.10193 0.0566797 0.0185966 -0.104158 0.0586725 0.009737000000000001 -0.101774 0.054671 0.033113 -0.10193 0.0566797 0.033113 -0.10193 0.0566797 0.0222074 0.101649 0.054671 0.033113 0.10193 0.0566797 0.0064448 -0.103479 0.0603882 0.009737000000000001 -0.101774 0.054671 0.0185966 -0.104158 0.0586725 0.033113 -0.10193 0.0566797 0.009737000000000001 -0.101774 0.054671 0.0158576 -0.101661 0.054671 0.033113 -0.10193 0.0566797 0.0222074 -0.101649 0.054671 0.0222074 0.101649 0.054671 0.033113 0.10193 0.0566797 0.0222074 0.101649 0.054671 0.0158576 0.101661 0.054671 0.0022951 -0.101449 0.054671 0.0064448 -0.103479 0.0603882 0.00238245 -0.10235 0.0579913 0.0064448 -0.103479 0.0603882 -0.0016799 -0.102786 0.061436 0.00238245 -0.10235 0.0579913 -0.0016799 -0.102786 0.061436 0.0022951 -0.101449 0.054671 0.00238245 -0.10235 0.0579913 0.0022951 -0.101449 0.054671 0.009737000000000001 -0.101774 0.054671 0.0064448 -0.103479 0.0603882 0.0136565 -0.0285 0.054671 0.0158576 -0.101661 0.054671 0.0127973 -0.065137 0.054671 0.0158576 -0.101661 0.054671 0.009737000000000001 -0.101774 0.054671 0.0127973 -0.065137 0.054671 0.009737000000000001 -0.101774 0.054671 0.009737000000000001 -0.0285 0.054671 0.0127973 -0.065137 0.054671 0.009737000000000001 -0.0285 0.054671 0.0136565 -0.0285 0.054671 0.0127973 -0.065137 0.054671 0.033113 -0.10193 0.0566797 0.0158576 -0.101661 0.054671 0.0222074 -0.101649 0.054671 0.0222074 -0.101649 0.054671 0.0199228 -0.0285 0.054671 0.02 -0.0285 0.054671 0.02 0.0295 0.054671 0.0181113 0.0295 0.054671 0.0222074 0.101649 0.054671 0.0181113 0.0295 0.054671 0.0158576 0.101661 0.054671 0.0222074 0.101649 0.054671 0.0222074 -0.101649 0.054671 0.02 -0.0285 0.054671 0.02 0.0279235 0.054671 0.02 0.0295 0.054671 0.0222074 -0.101649 0.054671 0.02 0.0279235 0.054671 0.0222074 0.101649 0.054671 0.0222074 -0.101649 0.054671 0.02 0.0295 0.054671 0.033113 0.10193 0.0566797 0.0158576 0.101661 0.054671 0.009737000000000001 0.101774 0.054671 0.009737000000000001 0.101774 0.054671 0.0185966 0.104158 0.0586725 0.033113 0.10193 0.0566797 0.0022951 -0.101449 0.054671 -0.0016799 -0.102786 0.061436 -0.0089414 -0.101944 0.0623748 0.00705375 -0.0285 0.054671 0.009737000000000001 -0.101774 0.054671 0.00601605 -0.065137 0.054671 0.009737000000000001 -0.101774 0.054671 0.0022951 -0.101449 0.054671 0.00601605 -0.065137 0.054671 0.0022951 -0.101449 0.054671 0.0022951 -0.0285 0.054671 0.00601605 -0.065137 0.054671 0.0022951 -0.0285 0.054671 0.00705375 -0.0285 0.054671 0.00601605 -0.065137 0.054671 0.0158576 -0.101661 0.054671 0.0136565 -0.0285 0.054671 0.0158576 -0.0285 0.054671 0.009737000000000001 -0.101774 0.054671 0.00705375 -0.0285 0.054671 0.009737000000000001 -0.0285 0.054671 0.0199228 -0.0285 0.054671 0.0222074 -0.101649 0.054671 0.0190325 -0.0650805 0.054671 0.0222074 -0.101649 0.054671 0.0158576 -0.101661 0.054671 0.0190325 -0.0650805 0.054671 0.0158576 -0.101661 0.054671 0.0158576 -0.0285 0.054671 0.0190325 -0.0650805 0.054671 0.0158576 -0.0285 0.054671 0.0189128 -0.0285 0.054671 0.0190325 -0.0650805 0.054671 0.0189128 -0.0285 0.054671 0.0199228 -0.0285 0.054671 0.0190325 -0.0650805 0.054671 0.0181113 0.0295 0.054671 0.0158576 0.0295 0.054671 0.0158576 0.101661 0.054671 0.0158576 0.0295 0.054671 0.0119115 0.0295 0.054671 0.0127973 0.065637 0.054671 0.0119115 0.0295 0.054671 0.009737000000000001 0.101774 0.054671 0.0127973 0.065637 0.054671 0.009737000000000001 0.101774 0.054671 0.0158576 0.101661 0.054671 0.0127973 0.065637 0.054671 0.0158576 0.101661 0.054671 0.0158576 0.0295 0.054671 0.0127973 0.065637 0.054671 0.009737000000000001 0.101774 0.054671 0.0064448 0.103479 0.0603882 0.0185966 0.104158 0.0586725 -0.0053667 -0.100209 0.054671 -0.0089414 -0.101944 0.0623748 -0.0285344 -0.0982736 0.0646608 0.0022951 -0.101449 0.054671 -0.0089414 -0.101944 0.0623748 -0.0053667 -0.100209 0.054671 -0.0582314 -0.0889267 0.054671 -0.0285344 -0.0982736 0.0646608 -0.0465219 -0.0942286 0.06660339999999999 0.0022951 -0.101449 0.054671 -0.000476526 -0.0285 0.054671 0.0022951 -0.0285 0.054671 -0.000476526 -0.0285 0.054671 0.0022951 -0.101449 0.054671 -0.0015358 -0.0649745 0.054671 0.0022951 -0.101449 0.054671 -0.0053667 -0.100209 0.054671 -0.0015358 -0.0649745 0.054671 -0.0053667 -0.100209 0.054671 -0.0053667 -0.0285 0.054671 -0.0015358 -0.0649745 0.054671 -0.0053667 -0.0285 0.054671 -0.000476526 -0.0285 0.054671 -0.0015358 -0.0649745 0.054671 -0.0053667 -0.100209 0.054671 -0.007975370000000001 -0.0285 0.054671 -0.0053667 -0.0285 0.054671 -0.007975370000000001 -0.0285 0.054671 -0.0053667 -0.100209 0.054671 -0.00898825 -0.0643545 0.054671 -0.0053667 -0.100209 0.054671 -0.008522689999999999 -0.0996364 0.054671 -0.00898825 -0.0643545 0.054671 -0.008522689999999999 -0.0996364 0.054671 -0.0126098 -0.0988948 0.054671 -0.00898825 -0.0643545 0.054671 -0.0126098 -0.0988948 0.054671 -0.0126098 -0.0285 0.054671 -0.00898825 -0.0643545 0.054671 -0.0126098 -0.0285 0.054671 -0.007975370000000001 -0.0285 0.054671 -0.00898825 -0.0643545 0.054671 -0.0126098 -0.0988948 0.054671 -0.0155077 -0.0285 0.054671 -0.0126098 -0.0285 0.054671 -0.0126098 -0.0988948 0.054671 -0.0206918 -0.0974283 0.054671 -0.0155077 -0.0285 0.054671 -0.0206918 -0.0974283 0.054671 -0.02 -0.0285 0.054671 -0.0155077 -0.0285 0.054671 -0.0178954 0.0295 0.054671 -0.0189128 0.0295 0.054671 -0.0206918 0.0974283 0.054671 -0.0189128 0.0295 0.054671 -0.02 0.0295 0.054671 -0.0206918 0.0974283 0.054671 -0.02 0.0295 0.054671 -0.0206918 -0.0974283 0.054671 -0.0206918 0.0974283 0.054671 -0.02 0.0279235 0.054671 -0.0206918 -0.0974283 0.054671 -0.02 0.0295 0.054671 -0.02 -0.0285 0.054671 -0.0206918 -0.0974283 0.054671 -0.02 0.0279235 0.054671 0.0119115 0.0295 0.054671 0.009737000000000001 0.0295 0.054671 0.009737000000000001 0.101774 0.054671 -0.0126098 0.0295 0.054671 -0.0178954 0.0295 0.054671 -0.0166508 0.0641974 0.054671 -0.0178954 0.0295 0.054671 -0.0206918 0.0974283 0.054671 -0.0166508 0.0641974 0.054671 -0.0206918 0.0974283 0.054671 -0.0126098 0.0988948 0.054671 -0.0166508 0.0641974 0.054671 -0.0126098 0.0988948 0.054671 -0.0126098 0.0295 0.054671 -0.0166508 0.0641974 0.054671 -0.0100853 0.0295 0.054671 -0.0126098 0.0295 0.054671 -0.0126098 0.0988948 0.054671 -0.0053667 0.0295 0.054671 -0.0100853 0.0295 0.054671 -0.00898825 0.0648545 0.054671 -0.0100853 0.0295 0.054671 -0.0126098 0.0988948 0.054671 -0.00898825 0.0648545 0.054671 -0.0126098 0.0988948 0.054671 -0.008522689999999999 0.0996364 0.054671 -0.00898825 0.0648545 0.054671 -0.008522689999999999 0.0996364 0.054671 -0.0053667 0.100209 0.054671 -0.00898825 0.0648545 0.054671 -0.0053667 0.100209 0.054671 -0.0053667 0.0295 0.054671 -0.00898825 0.0648545 0.054671 -0.00268018 0.0295 0.054671 -0.0053667 0.0295 0.054671 -0.0053667 0.100209 0.054671 0.0022951 0.0295 0.054671 -0.00268018 0.0295 0.054671 -0.0015358 0.0654745 0.054671 -0.00268018 0.0295 0.054671 -0.0053667 0.100209 0.054671 -0.0015358 0.0654745 0.054671 -0.0053667 0.100209 0.054671 0.0022951 0.101449 0.054671 -0.0015358 0.0654745 0.054671 0.0022951 0.101449 0.054671 0.0022951 0.0295 0.054671 -0.0015358 0.0654745 0.054671 0.00492983 0.0295 0.054671 0.0022951 0.0295 0.054671 0.0022951 0.101449 0.054671 0.009737000000000001 0.0295 0.054671 0.00492983 0.0295 0.054671 0.00601605 0.065637 0.054671 0.00492983 0.0295 0.054671 0.0022951 0.101449 0.054671 0.00601605 0.065637 0.054671 0.0022951 0.101449 0.054671 0.009737000000000001 0.101774 0.054671 0.00601605 0.065637 0.054671 0.009737000000000001 0.101774 0.054671 0.009737000000000001 0.0295 0.054671 0.00601605 0.065637 0.054671 0.0022951 0.101449 0.054671 0.0064448 0.103479 0.0603882 0.009737000000000001 0.101774 0.054671 -0.0206918 -0.0974283 0.054671 -0.0285344 -0.0982736 0.0646608 -0.0277822 -0.0961418 0.054671 -0.0169505 -0.0991416 0.0592268 -0.0053667 -0.100209 0.054671 -0.0285344 -0.0982736 0.0646608 -0.0169505 -0.0991416 0.0592268 -0.0206918 -0.0974283 0.054671 -0.0126098 -0.0988948 0.054671 -0.0169505 -0.0991416 0.0592268 -0.0126098 -0.0988948 0.054671 -0.008522689999999999 -0.0996364 0.054671 -0.0169505 -0.0991416 0.0592268 -0.008522689999999999 -0.0996364 0.054671 -0.0053667 -0.100209 0.054671 -0.0169505 -0.0991416 0.0592268 -0.0285344 -0.0982736 0.0646608 -0.0206918 -0.0974283 0.054671 -0.0582314 -0.0889267 0.054671 -0.0403606 -0.093164 0.054671 -0.0285344 -0.0982736 0.0646608 -0.0285344 -0.0982736 0.0646608 -0.0403606 -0.093164 0.054671 -0.0319039 -0.0951651 0.054671 -0.0285344 -0.0982736 0.0646608 -0.0319039 -0.0951651 0.054671 -0.0277822 -0.0961418 0.054671 -0.0582314 -0.0889267 0.054671 -0.0465219 -0.0942286 0.06660339999999999 -0.058904 -0.09046029999999999 0.0677659 -0.0206918 -0.0974283 0.054671 -0.0277822 0.0961418 0.054671 -0.0206918 0.0974283 0.054671 -0.0277822 0.0961418 0.054671 -0.0285344 0.0982736 0.0646608 -0.0206918 0.0974283 0.054671 -0.0285344 0.0982736 0.0646608 -0.0053667 0.100209 0.054671 -0.0169505 0.0991416 0.0592268 -0.0053667 0.100209 0.054671 -0.008522689999999999 0.0996364 0.054671 -0.0169505 0.0991416 0.0592268 -0.008522689999999999 0.0996364 0.054671 -0.0126098 0.0988948 0.054671 -0.0169505 0.0991416 0.0592268 -0.0126098 0.0988948 0.054671 -0.0206918 0.0974283 0.054671 -0.0169505 0.0991416 0.0592268 -0.0206918 0.0974283 0.054671 -0.0285344 0.0982736 0.0646608 -0.0169505 0.0991416 0.0592268 0.0022951 0.101449 0.054671 -0.0053667 0.100209 0.054671 -0.0089414 0.101944 0.0623748 0.0064448 0.103479 0.0603882 0.0022951 0.101449 0.054671 0.00238245 0.10235 0.0579913 0.0022951 0.101449 0.054671 -0.0016799 0.102786 0.061436 0.00238245 0.10235 0.0579913 -0.0016799 0.102786 0.061436 0.0064448 0.103479 0.0603882 0.00238245 0.10235 0.0579913 -0.0206918 -0.0974283 0.054671 -0.0277822 -0.0961418 0.054671 -0.0277822 0.0961418 0.054671 -0.0403606 -0.093164 0.054671 -0.0582314 -0.0889267 0.054671 -0.0582314 0.0889267 0.054671 -0.0277822 -0.0961418 0.054671 -0.0319039 -0.0951651 0.054671 -0.0441411 0.09227349999999999 0.054671 -0.0319039 -0.0951651 0.054671 -0.0403606 -0.093164 0.054671 -0.0441411 0.09227349999999999 0.054671 -0.058904 -0.09046029999999999 0.0677659 -0.0679921 -0.08544300000000001 0.054671 -0.0582314 -0.0889267 0.054671 -0.0285344 0.0982736 0.0646608 -0.0089414 0.101944 0.0623748 -0.0053667 0.100209 0.054671 -0.0285344 0.0982736 0.0646608 -0.0277822 0.0961418 0.054671 -0.0319039 0.0951651 0.054671 -0.0285344 0.0982736 0.0646608 -0.0319039 0.0951651 0.054671 -0.0441411 0.09227349999999999 0.054671 -0.0285344 0.0982736 0.0646608 -0.0441411 0.09227349999999999 0.054671 -0.0582314 0.0889267 0.054671 -0.0016799 0.102786 0.061436 0.0022951 0.101449 0.054671 -0.0089414 0.101944 0.0623748 -0.0277822 -0.0961418 0.054671 -0.0441411 0.09227349999999999 0.054671 -0.0319039 0.0951651 0.054671 -0.0277822 -0.0961418 0.054671 -0.0319039 0.0951651 0.054671 -0.0277822 0.0961418 0.054671 -0.058904 -0.09046029999999999 0.0677659 -0.06490940000000001 -0.08864080000000001 0.0683048 -0.0679921 -0.08544300000000001 0.054671 -0.0403606 -0.093164 0.054671 -0.0582314 0.0889267 0.054671 -0.0441411 0.09227349999999999 0.054671 -0.0582314 -0.0889267 0.054671 -0.0679921 0.08544300000000001 0.054671 -0.0582314 0.0889267 0.054671 -0.0582314 -0.0889267 0.054671 -0.0679921 -0.08544300000000001 0.054671 -0.0679921 0.08544300000000001 0.054671 -0.0285344 0.0982736 0.0646608 -0.0582314 0.0889267 0.054671 -0.0465219 0.0942286 0.06660339999999999 -0.07471609999999999 -0.08267149999999999 0.054671 -0.0764845 -0.08436970000000001 0.0693015 -0.0872566 -0.07937669999999999 0.0680486 -0.06490940000000001 -0.08864080000000001 0.0683048 -0.0764845 -0.08436970000000001 0.0693015 -0.0679921 -0.08544300000000001 0.054671 -0.0582314 0.0889267 0.054671 -0.0679921 0.08544300000000001 0.054671 -0.058904 0.09046029999999999 0.0677659 -0.0679921 -0.08544300000000001 0.054671 -0.07471609999999999 0.08267149999999999 0.054671 -0.0679921 0.08544300000000001 0.054671 -0.0465219 0.0942286 0.06660339999999999 -0.0582314 0.0889267 0.054671 -0.058904 0.09046029999999999 0.0677659 -0.0872566 -0.07937669999999999 0.0680486 -0.100322 -0.0727418 0.07078710000000001 -0.0832456 -0.0799422 0.054671 -0.07471609999999999 -0.08267149999999999 0.054671 -0.0679921 -0.08544300000000001 0.054671 -0.0764845 -0.08436970000000001 0.0693015 -0.0872566 -0.07937669999999999 0.0680486 -0.0832456 -0.0799422 0.054671 -0.07471609999999999 -0.08267149999999999 0.054671 -0.06490940000000001 0.08864080000000001 0.0683048 -0.058904 0.09046029999999999 0.0677659 -0.0679921 0.08544300000000001 0.054671 -0.0679921 -0.08544300000000001 0.054671 -0.07471609999999999 -0.08267149999999999 0.054671 -0.07471609999999999 0.08267149999999999 0.054671 -0.0764845 0.08436970000000001 0.0693015 -0.0679921 0.08544300000000001 0.054671 -0.07471609999999999 0.08267149999999999 0.054671 -0.106402 -0.06835049999999999 0.0714221 -0.108255 -0.060828 0.063975 -0.100322 -0.0727418 0.07078710000000001 -0.100322 -0.0727418 0.07078710000000001 -0.0882015 -0.0767481 0.054671 -0.0832456 -0.0799422 0.054671 -0.07471609999999999 -0.08267149999999999 0.054671 -0.0832456 -0.0799422 0.054671 -0.0832456 0.0799422 0.054671 -0.0764845 0.08436970000000001 0.0693015 -0.06490940000000001 0.08864080000000001 0.0683048 -0.0679921 0.08544300000000001 0.054671 -0.07471609999999999 -0.08267149999999999 0.054671 -0.0832456 0.0799422 0.054671 -0.07471609999999999 0.08267149999999999 0.054671 -0.0872566 0.07937669999999999 0.0680486 -0.0764845 0.08436970000000001 0.0693015 -0.07471609999999999 0.08267149999999999 0.054671 -0.0931486 -0.07392990000000001 0.054671 -0.100322 -0.0727418 0.07078710000000001 -0.108255 -0.060828 0.063975 -0.108255 -0.060828 0.063975 -0.106402 -0.06835049999999999 0.0714221 -0.111276 -0.059601 0.0716055 -0.0931486 -0.07392990000000001 0.054671 -0.0882015 -0.0767481 0.054671 -0.100322 -0.0727418 0.07078710000000001 -0.0832456 -0.0799422 0.054671 -0.0882015 -0.0767481 0.054671 -0.0882015 0.0767481 0.054671 -0.0832456 -0.0799422 0.054671 -0.0882015 0.0767481 0.054671 -0.0832456 0.0799422 0.054671 -0.0872566 0.07937669999999999 0.0680486 -0.07471609999999999 0.08267149999999999 0.054671 -0.0832456 0.0799422 0.054671 -0.108255 -0.060828 0.063975 -0.099638 -0.0681739 0.054671 -0.0931486 -0.07392990000000001 0.054671 -0.108255 -0.060828 0.063975 -0.111276 -0.059601 0.0716055 -0.115412 -0.052719 0.071834 -0.0882015 -0.0767481 0.054671 -0.0931486 -0.07392990000000001 0.054671 -0.0931486 0.07392990000000001 0.054671 -0.0882015 -0.0767481 0.054671 -0.0931486 0.07392990000000001 0.054671 -0.0882015 0.0767481 0.054671 -0.100322 0.0727418 0.07078710000000001 -0.0832456 0.0799422 0.054671 -0.0882015 0.0767481 0.054671 -0.0872566 0.07937669999999999 0.0680486 -0.0832456 0.0799422 0.054671 -0.100322 0.0727418 0.07078710000000001 -0.115412 -0.052719 0.071834 -0.118166 -0.045432 0.07198 -0.112211 -0.0477672 0.054671 -0.105074 -0.0619567 0.054671 -0.099638 -0.0681739 0.054671 -0.108255 -0.060828 0.063975 -0.0931486 -0.07392990000000001 0.054671 -0.099638 -0.0681739 0.054671 -0.099638 0.0681739 0.054671 -0.112211 -0.0477672 0.054671 -0.108255 -0.060828 0.063975 -0.111274 -0.0548688 0.0632525 -0.108255 -0.060828 0.063975 -0.115412 -0.052719 0.071834 -0.111274 -0.0548688 0.0632525 -0.115412 -0.052719 0.071834 -0.112211 -0.0477672 0.054671 -0.111274 -0.0548688 0.0632525 -0.0931486 -0.07392990000000001 0.054671 -0.099638 0.0681739 0.054671 -0.0931486 0.07392990000000001 0.054671 -0.0882015 0.0767481 0.054671 -0.0931486 0.07392990000000001 0.054671 -0.100322 0.0727418 0.07078710000000001 -0.106402 0.06835049999999999 0.0714221 -0.100322 0.0727418 0.07078710000000001 -0.108255 0.060828 0.063975 -0.114707 -0.041379 0.054671 -0.118166 -0.045432 0.07198 -0.119664 -0.038846 0.072058 -0.114707 -0.041379 0.054671 -0.112211 -0.0477672 0.054671 -0.118166 -0.045432 0.07198 -0.109083 -0.0555387 0.054671 -0.105074 -0.0619567 0.054671 -0.108255 -0.060828 0.063975 -0.105074 -0.0619567 0.054671 -0.105074 0.0619567 0.054671 -0.099638 -0.0681739 0.054671 -0.099638 -0.0681739 0.054671 -0.105074 0.0619567 0.054671 -0.099638 0.0681739 0.054671 -0.108255 -0.060828 0.063975 -0.112211 -0.0477672 0.054671 -0.109083 -0.0555387 0.054671 -0.0931486 0.07392990000000001 0.054671 -0.099638 0.0681739 0.054671 -0.108255 0.060828 0.063975 -0.0931486 0.07392990000000001 0.054671 -0.108255 0.060828 0.063975 -0.100322 0.0727418 0.07078710000000001 -0.108255 0.060828 0.063975 -0.111276 0.059601 0.0716055 -0.106402 0.06835049999999999 0.0714221 -0.114707 -0.041379 0.054671 -0.119664 -0.038846 0.072058 -0.119664 0.038846 0.072058 -0.114707 -0.041379 0.054671 -0.114707 0.041379 0.054671 -0.112211 -0.0477672 0.054671 -0.109083 -0.0555387 0.054671 -0.109083 0.0555387 0.054671 -0.105074 -0.0619567 0.054671 -0.105074 0.0619567 0.054671 -0.105074 -0.0619567 0.054671 -0.109083 0.0555387 0.054671 -0.108255 0.060828 0.063975 -0.099638 0.0681739 0.054671 -0.105074 0.0619567 0.054671 -0.112211 -0.0477672 0.054671 -0.112211 0.0477672 0.054671 -0.109083 -0.0555387 0.054671 -0.108255 0.060828 0.063975 -0.115412 0.052719 0.071834 -0.111276 0.059601 0.0716055 -0.118166 0.045432 0.07198 -0.114707 0.041379 0.054671 -0.119664 0.038846 0.072058 -0.119664 0.038846 0.072058 -0.114707 0.041379 0.054671 -0.114707 -0.041379 0.054671 -0.112211 0.0477672 0.054671 -0.112211 -0.0477672 0.054671 -0.114707 0.041379 0.054671 -0.109083 0.0555387 0.054671 -0.109083 -0.0555387 0.054671 -0.112211 0.0477672 0.054671 -0.108255 0.060828 0.063975 -0.105074 0.0619567 0.054671 -0.109083 0.0555387 0.054671 -0.108255 0.060828 0.063975 -0.112211 0.0477672 0.054671 -0.111274 0.0548688 0.0632525 -0.112211 0.0477672 0.054671 -0.115412 0.052719 0.071834 -0.111274 0.0548688 0.0632525 -0.115412 0.052719 0.071834 -0.108255 0.060828 0.063975 -0.111274 0.0548688 0.0632525 -0.118166 0.045432 0.07198 -0.115412 0.052719 0.071834 -0.112211 0.0477672 0.054671 -0.118166 0.045432 0.07198 -0.112211 0.0477672 0.054671 -0.114707 0.041379 0.054671 -0.112211 0.0477672 0.054671 -0.108255 0.060828 0.063975 -0.109083 0.0555387 0.054671 0.0962919 -0.044521 0.09890359999999999 0.0995905 -0.022541 0.101 0.09569370000000001 -0.0475374 0.111111 0.099926 -0.0095 0.0990685 0.09947780000000001 -0.010524 0.111111 0.0995905 -0.022541 0.101 0.0962919 -0.044521 0.09890359999999999 0.09569370000000001 -0.0475374 0.111111 0.091061 -0.063225 0.111111 0.0995905 -0.022541 0.101 0.0994401 -0.0271663 0.111111 0.09569370000000001 -0.0475374 0.111111 0.099926 0.0095 0.0990685 0.09947780000000001 -0.010524 0.111111 0.099926 -0.0095 0.0990685 0.09947780000000001 -0.010524 0.111111 0.0994401 -0.0271663 0.111111 0.0995905 -0.022541 0.101 0.0911151 -0.06285590000000001 0.09950000000000001 0.0962919 -0.044521 0.09890359999999999 0.091061 -0.063225 0.111111 0.091061 -0.063225 0.111111 0.09569370000000001 -0.0475374 0.111111 0.059477 -0.0534642 0.124998 0.0994401 -0.0271663 0.111111 0.059477 -0.0534642 0.124998 0.09569370000000001 -0.0475374 0.111111 0.09947780000000001 -0.010524 0.111111 0.099926 0.0095 0.0990685 0.09947780000000001 0.010524 0.111111 0.09947780000000001 -0.010524 0.111111 0.059477 -0.0534642 0.124998 0.0994401 -0.0271663 0.111111 0.091061 -0.063225 0.111111 0.08676490000000001 -0.0725451 0.111111 0.0911151 -0.06285590000000001 0.09950000000000001 0.091061 -0.063225 0.111111 0.059477 -0.0534642 0.124998 0.0557328 -0.062136 0.124997 0.088891 -0.06880749999999999 0.09950000000000001 0.0911151 -0.06285590000000001 0.09950000000000001 0.08676490000000001 -0.0725451 0.111111 0.09947780000000001 0.010524 0.111111 0.099926 0.0095 0.0990685 0.0995905 0.022541 0.101 0.09947780000000001 0.010524 0.111111 0.06700200000000001 0 0.124999 0.09947780000000001 -0.010524 0.111111 0.059477 -0.0534642 0.124998 0.09947780000000001 -0.010524 0.111111 0.062307 -0.0447345 0.124998 0.08676490000000001 -0.0725451 0.111111 0.091061 -0.063225 0.111111 0.0557328 -0.062136 0.124997 0.0557328 -0.062136 0.124997 0.059477 -0.0534642 0.124998 0.054416 -0.044364 0.125417 0.08676490000000001 -0.0725451 0.111111 0.0858631 -0.07568 0.100202 0.088891 -0.06880749999999999 0.09950000000000001 0.0995905 0.022541 0.101 0.0994401 0.0271663 0.111111 0.09947780000000001 0.010524 0.111111 0.09947780000000001 0.010524 0.111111 0.062307 0.0447345 0.124998 0.06700200000000001 0 0.124999 0.062307 -0.0447345 0.124998 0.09947780000000001 -0.010524 0.111111 0.06700200000000001 0 0.124999 0.059477 -0.0534642 0.124998 0.062307 -0.0447345 0.124998 0.054416 -0.044364 0.125417 0.07020029999999999 -0.07927149999999999 0.11509 0.067894 -0.0964069 0.111115 0.08676490000000001 -0.0725451 0.111111 0.07020029999999999 -0.07927149999999999 0.11509 0.08676490000000001 -0.0725451 0.111111 0.0557328 -0.062136 0.124997 0.07020029999999999 -0.07927149999999999 0.11509 0.0557328 -0.062136 0.124997 0.067894 -0.0964069 0.111115 0.0511683 -0.0683158 0.124997 0.0557328 -0.062136 0.124997 0.054416 -0.044364 0.125417 0.08676490000000001 -0.0725451 0.111111 0.08017199999999999 -0.0852165 0.100992 0.0858631 -0.07568 0.100202 0.09947780000000001 0.010524 0.111111 0.0994401 0.0271663 0.111111 0.059477 0.0534642 0.124998 0.09569370000000001 0.0475374 0.111111 0.0994401 0.0271663 0.111111 0.0995905 0.022541 0.101 0.062307 0.0447345 0.124998 0.09947780000000001 0.010524 0.111111 0.059477 0.0534642 0.124998 0.058251 0 0.125685 0.06700200000000001 0 0.124999 0.062307 0.0447345 0.124998 0.062307 -0.0447345 0.124998 0.06700200000000001 0 0.124999 0.058251 0 0.125685 0.054416 -0.044364 0.125417 0.062307 -0.0447345 0.124998 0.058251 0 0.125685 0.08676490000000001 -0.0725451 0.111111 0.067894 -0.0964069 0.111115 0.080067 -0.0844232 0.11074 0.0511683 -0.0683158 0.124997 0.067894 -0.0964069 0.111115 0.0557328 -0.062136 0.124997 0.047278 -0.064799 0.125186 0.0511683 -0.0683158 0.124997 0.054416 -0.044364 0.125417 0.08676490000000001 -0.0725451 0.111111 0.080067 -0.0844232 0.11074 0.08017199999999999 -0.0852165 0.100992 0.07849399999999999 -0.0351008 0.052691 0.0837318 -0.0401518 0.0570936 0.07482800000000001 -0.06694509999999999 0.0564331 0.0837318 -0.0401518 0.0570936 0.07849399999999999 -0.0351008 0.052691 0.08605599999999999 -0.0095 0.0546884 0.09569370000000001 0.0475374 0.111111 0.059477 0.0534642 0.124998 0.0994401 0.0271663 0.111111 0.09569370000000001 0.0475374 0.111111 0.0995905 0.022541 0.101 0.0962919 0.044521 0.09890359999999999 0.054416 0.044364 0.125417 0.062307 0.0447345 0.124998 0.059477 0.0534642 0.124998 0.058251 0 0.125685 0.062307 0.0447345 0.124998 0.054416 0.044364 0.125417 0.058251 0 0.125685 0.046944 -0.04241 0.125836 0.054416 -0.044364 0.125417 0.0744182 -0.0908571 0.106054 0.074183 -0.091999 0.100992 0.080067 -0.0844232 0.11074 0.0744182 -0.0908571 0.106054 0.080067 -0.0844232 0.11074 0.067894 -0.0964069 0.111115 0.0744182 -0.0908571 0.106054 0.067894 -0.0964069 0.111115 0.074183 -0.091999 0.100992 0.0511683 -0.0683158 0.124997 0.0511137 -0.105412 0.111116 0.067894 -0.0964069 0.111115 0.042185 -0.062366 0.125375 0.047278 -0.064799 0.125186 0.054416 -0.044364 0.125417 0.0511683 -0.0683158 0.124997 0.047278 -0.064799 0.125186 0.0383404 -0.0739716 0.12505 0.074183 -0.091999 0.100992 0.08017199999999999 -0.0852165 0.100992 0.080067 -0.0844232 0.11074 0.07482800000000001 -0.06694509999999999 0.0564331 0.0648833 -0.0762859 0.052691 0.07849399999999999 -0.0351008 0.052691 0.07849399999999999 -0.0351008 0.052691 0.07849399999999999 0.0351008 0.052691 0.08605599999999999 -0.0095 0.0546884 0.09569370000000001 0.0475374 0.111111 0.091061 0.063225 0.111111 0.059477 0.0534642 0.124998 0.091061 0.063225 0.111111 0.09569370000000001 0.0475374 0.111111 0.0962919 0.044521 0.09890359999999999 0.054416 0.044364 0.125417 0.059477 0.0534642 0.124998 0.0557328 0.062136 0.124997 0.058251 0 0.125685 0.054416 0.044364 0.125417 0.046944 0.04241 0.125836 0.042185 -0.062366 0.125375 0.054416 -0.044364 0.125417 0.046944 -0.04241 0.125836 0.046944 -0.04241 0.125836 0.058251 0 0.125685 0.049501 0 0.126371 0.067894 -0.0964069 0.111115 0.06565650000000001 -0.0989867 0.100992 0.074183 -0.091999 0.100992 0.056279 -0.104368 0.100992 0.067894 -0.0964069 0.111115 0.0511137 -0.105412 0.111116 0.0511683 -0.0683158 0.124997 0.046772 -0.07211099999999999 0.124996 0.0511137 -0.105412 0.111116 0.047278 -0.064799 0.125186 0.042185 -0.062366 0.125375 0.0383404 -0.0739716 0.12505 0.046772 -0.07211099999999999 0.124996 0.0511683 -0.0683158 0.124997 0.0383404 -0.0739716 0.12505 0.0674174 -0.0807109 0.0570159 0.0648833 -0.0762859 0.052691 0.07482800000000001 -0.06694509999999999 0.0564331 0.08605599999999999 0.0095 0.0546884 0.08605599999999999 -0.0095 0.0546884 0.07849399999999999 0.0351008 0.052691 0.091061 0.063225 0.111111 0.0557328 0.062136 0.124997 0.059477 0.0534642 0.124998 0.0911151 0.06285590000000001 0.09950000000000001 0.091061 0.063225 0.111111 0.0962919 0.044521 0.09890359999999999 0.054416 0.044364 0.125417 0.0557328 0.062136 0.124997 0.0511683 0.0683158 0.124997 0.046944 0.04241 0.125836 0.054416 0.044364 0.125417 0.042185 0.062366 0.125375 0.049501 0 0.126371 0.058251 0 0.125685 0.046944 0.04241 0.125836 0.042185 -0.062366 0.125375 0.046944 -0.04241 0.125836 0.037092 -0.059934 0.125564 0.039472 -0.040455 0.126255 0.046944 -0.04241 0.125836 0.049501 0 0.126371 0.056279 -0.104368 0.100992 0.06565650000000001 -0.0989867 0.100992 0.067894 -0.0964069 0.111115 0.0511137 -0.105412 0.111116 0.0479835 -0.107211 0.100992 0.056279 -0.104368 0.100992 0.0383404 -0.0739716 0.12505 0.0511137 -0.105412 0.111116 0.046772 -0.07211099999999999 0.124996 0.0320005 -0.0665278 0.12538 0.0383404 -0.0739716 0.12505 0.0370928 -0.0681702 0.125256 0.0383404 -0.0739716 0.12505 0.042185 -0.062366 0.125375 0.0370928 -0.0681702 0.125256 0.042185 -0.062366 0.125375 0.0320005 -0.0665278 0.12538 0.0370928 -0.0681702 0.125256 0.0674174 -0.0807109 0.0570159 0.0532069 -0.0909377 0.0539902 0.0648833 -0.0762859 0.052691 0.08605599999999999 0.0095 0.0546884 0.07849399999999999 0.0351008 0.052691 0.0837318 0.0401518 0.0570936 0.07849399999999999 0.0351008 0.052691 0.0648833 0.0762859 0.052691 0.07482800000000001 0.06694509999999999 0.0564331 0.08676490000000001 0.0725451 0.111111 0.0557328 0.062136 0.124997 0.091061 0.063225 0.111111 0.0911151 0.06285590000000001 0.09950000000000001 0.08676490000000001 0.0725451 0.111111 0.091061 0.063225 0.111111 0.054416 0.044364 0.125417 0.0511683 0.0683158 0.124997 0.047278 0.064799 0.125186 0.067894 0.0964069 0.111115 0.0511683 0.0683158 0.124997 0.0557328 0.062136 0.124997 0.042185 0.062366 0.125375 0.037092 0.059934 0.125564 0.046944 0.04241 0.125836 0.054416 0.044364 0.125417 0.047278 0.064799 0.125186 0.042185 0.062366 0.125375 0.049501 0 0.126371 0.046944 0.04241 0.125836 0.039472 0.040455 0.126255 0.042185 -0.062366 0.125375 0.037092 -0.059934 0.125564 0.0320005 -0.0665278 0.12538 0.037092 -0.059934 0.125564 0.046944 -0.04241 0.125836 0.039472 -0.040455 0.126255 0.039472 -0.040455 0.126255 0.049501 0 0.126371 0.04075 0 0.127057 0.0479835 -0.107211 0.100992 0.0511137 -0.105412 0.111116 0.0319861 -0.109 0.101998 0.0511137 -0.105412 0.111116 0.0383404 -0.0739716 0.12505 0.0319804 -0.109072 0.110612 0.0383404 -0.0739716 0.12505 0.0320005 -0.0665278 0.12538 0.0319954 -0.0746043 0.125071 0.0674174 -0.0807109 0.0570159 0.0586512 -0.09210119999999999 0.0601659 0.0532069 -0.0909377 0.0539902 0.0532069 0.0909377 0.0539902 0.0674174 0.0807109 0.0570159 0.0648833 0.0762859 0.052691 0.0837318 0.0401518 0.0570936 0.07849399999999999 0.0351008 0.052691 0.07482800000000001 0.06694509999999999 0.0564331 0.07482800000000001 0.06694509999999999 0.0564331 0.0648833 0.0762859 0.052691 0.0674174 0.0807109 0.0570159 0.07020029999999999 0.07927149999999999 0.11509 0.08676490000000001 0.0725451 0.111111 0.067894 0.0964069 0.111115 0.07020029999999999 0.07927149999999999 0.11509 0.067894 0.0964069 0.111115 0.0557328 0.062136 0.124997 0.07020029999999999 0.07927149999999999 0.11509 0.0557328 0.062136 0.124997 0.08676490000000001 0.0725451 0.111111 0.08676490000000001 0.0725451 0.111111 0.0911151 0.06285590000000001 0.09950000000000001 0.088891 0.06880749999999999 0.09950000000000001 0.0511683 0.0683158 0.124997 0.0383404 0.0739716 0.12505 0.047278 0.064799 0.125186 0.0511137 0.105412 0.111116 0.0511683 0.0683158 0.124997 0.067894 0.0964069 0.111115 0.042185 0.062366 0.125375 0.0320005 0.0665278 0.12538 0.037092 0.059934 0.125564 0.039472 0.040455 0.126255 0.046944 0.04241 0.125836 0.037092 0.059934 0.125564 0.047278 0.064799 0.125186 0.0383404 0.0739716 0.12505 0.042185 0.062366 0.125375 0.04075 0 0.127057 0.049501 0 0.126371 0.039472 0.040455 0.126255 0.037092 -0.059934 0.125564 0.031999 -0.059401 0.125671 0.0320005 -0.0665278 0.12538 0.039472 -0.040455 0.126255 0.031999 -0.046101 0.126304 0.037092 -0.059934 0.125564 0.032 -0.0233 0.127319 0.039472 -0.040455 0.126255 0.04075 0 0.127057 0.0319804 -0.109072 0.110612 0.0319861 -0.109 0.101998 0.0511137 -0.105412 0.111116 0.0383404 -0.0739716 0.12505 0.0319954 -0.0746043 0.125071 0.0319804 -0.109072 0.110612 0.0320005 -0.0665278 0.12538 -0.037564 0 0.128802 0.0319954 -0.0746043 0.125071 0.0586512 -0.09210119999999999 0.0601659 0.0439882 -0.101818 0.0625549 0.0532069 -0.0909377 0.0539902 0.0532069 0.0909377 0.0539902 0.0586512 0.09210119999999999 0.0601659 0.0674174 0.0807109 0.0570159 0.080067 0.0844232 0.11074 0.067894 0.0964069 0.111115 0.08676490000000001 0.0725451 0.111111 0.08676490000000001 0.0725451 0.111111 0.088891 0.06880749999999999 0.09950000000000001 0.0858631 0.07568 0.100202 0.0511683 0.0683158 0.124997 0.046772 0.07211099999999999 0.124996 0.0383404 0.0739716 0.12505 0.0511137 0.105412 0.111116 0.067894 0.0964069 0.111115 0.056279 0.104368 0.100992 0.0511683 0.0683158 0.124997 0.0511137 0.105412 0.111116 0.046772 0.07211099999999999 0.124996 0.037092 0.059934 0.125564 0.0320005 0.0665278 0.12538 0.031999 0.059401 0.125671 0.0383404 0.0739716 0.12505 0.0320005 0.0665278 0.12538 0.0370928 0.0681702 0.125256 0.0320005 0.0665278 0.12538 0.042185 0.062366 0.125375 0.0370928 0.0681702 0.125256 0.042185 0.062366 0.125375 0.0383404 0.0739716 0.12505 0.0370928 0.0681702 0.125256 0.039472 0.040455 0.126255 0.037092 0.059934 0.125564 0.031999 0.046101 0.126304 0.032 0.0233 0.127319 0.04075 0 0.127057 0.039472 0.040455 0.126255 0.0320005 -0.0665278 0.12538 0.031999 -0.059401 0.125671 -0.037564 0 0.128802 0.037092 -0.059934 0.125564 0.031999 -0.046101 0.126304 0.031999 -0.059401 0.125671 0.039472 -0.040455 0.126255 0.032 -0.0385 0.126643 0.031999 -0.046101 0.126304 0.039472 -0.040455 0.126255 0.032 -0.0233 0.127319 0.032 -0.0385 0.126643 0.032 -0.0233 0.127319 0.04075 0 0.127057 0.032 0 0.127742 0.0319804 -0.109072 0.110612 -0.0123327 -0.105571 0.110741 0.0319861 -0.109 0.101998 0.0319954 -0.0746043 0.125071 0.019698 -0.07620399999999999 0.125 0.0319804 -0.109072 0.110612 0.0319954 -0.0746043 0.125071 -0.037564 0 0.128802 0.019698 -0.07620399999999999 0.125 0.0439882 -0.101818 0.0625549 0.0321408 -0.105105 0.0633421 0.033113 -0.10193 0.0566797 0.0532069 -0.0909377 0.0539902 0.0439882 -0.101818 0.0625549 0.0455299 -0.09586649999999999 0.0544782 0.0439882 0.101818 0.0625549 0.0532069 0.0909377 0.0539902 0.0455299 0.09586649999999999 0.0544782 0.0532069 0.0909377 0.0539902 0.0439882 0.101818 0.0625549 0.0586512 0.09210119999999999 0.0601659 0.0744182 0.0908571 0.106054 0.080067 0.0844232 0.11074 0.074183 0.091999 0.100992 0.0744182 0.0908571 0.106054 0.074183 0.091999 0.100992 0.067894 0.0964069 0.111115 0.0744182 0.0908571 0.106054 0.067894 0.0964069 0.111115 0.080067 0.0844232 0.11074 0.08017199999999999 0.0852165 0.100992 0.080067 0.0844232 0.11074 0.08676490000000001 0.0725451 0.111111 0.0858631 0.07568 0.100202 0.08017199999999999 0.0852165 0.100992 0.08676490000000001 0.0725451 0.111111 0.046772 0.07211099999999999 0.124996 0.0511137 0.105412 0.111116 0.0383404 0.0739716 0.12505 0.06565650000000001 0.0989867 0.100992 0.056279 0.104368 0.100992 0.067894 0.0964069 0.111115 0.0511137 0.105412 0.111116 0.056279 0.104368 0.100992 0.0479835 0.107211 0.100992 0.031999 0.059401 0.125671 0.0320005 0.0665278 0.12538 -0.037564 0 0.128802 0.037092 0.059934 0.125564 0.031999 0.059401 0.125671 0.031999 0.046101 0.126304 0.0383404 0.0739716 0.12505 0.0319954 0.0746043 0.125071 0.0320005 0.0665278 0.12538 0.039472 0.040455 0.126255 0.031999 0.046101 0.126304 0.032 0.0385 0.126643 0.039472 0.040455 0.126255 0.032 0.0385 0.126643 0.032 0.0233 0.127319 0.032 0.0233 0.127319 0.032 0 0.127742 0.04075 0 0.127057 -0.037564 0 0.128802 0.031999 -0.059401 0.125671 0.031999 -0.046101 0.126304 0.031999 -0.046101 0.126304 0.032 -0.0385 0.126643 -0.037564 0 0.128802 0.032 -0.0385 0.126643 0.032 -0.0233 0.127319 -0.037564 0 0.128802 0.032 -0.0233 0.127319 0.032 0 0.127742 -0.037564 0 0.128802 0.005444 -0.0750835 0.125001 -0.0123327 -0.105571 0.110741 0.0319804 -0.109072 0.110612 0.0319861 -0.109 0.101998 -0.0123327 -0.105571 0.110741 -0.034333 -0.101409 0.110741 0.019698 -0.07620399999999999 0.125 0.005444 -0.0750835 0.125001 0.0319804 -0.109072 0.110612 0.019698 -0.07620399999999999 0.125 -0.037564 0 0.128802 0.005444 -0.0750835 0.125001 0.0110499 -0.105577 0.0695487 0.033113 -0.10193 0.0566797 0.0321408 -0.105105 0.0633421 0.033113 -0.10193 0.0566797 0.0455299 -0.09586649999999999 0.0544782 0.0439882 -0.101818 0.0625549 0.033113 0.10193 0.0566797 0.0439882 0.101818 0.0625549 0.0455299 0.09586649999999999 0.0544782 0.080067 0.0844232 0.11074 0.08017199999999999 0.0852165 0.100992 0.074183 0.091999 0.100992 0.074183 0.091999 0.100992 0.06565650000000001 0.0989867 0.100992 0.067894 0.0964069 0.111115 0.0319804 0.109072 0.110612 0.0383404 0.0739716 0.12505 0.0511137 0.105412 0.111116 0.0511137 0.105412 0.111116 0.0479835 0.107211 0.100992 0.0319861 0.109 0.101998 0.0320005 0.0665278 0.12538 0.0319954 0.0746043 0.125071 -0.037564 0 0.128802 0.031999 0.046101 0.126304 0.031999 0.059401 0.125671 -0.037564 0 0.128802 0.0383404 0.0739716 0.12505 0.0319804 0.109072 0.110612 0.0319954 0.0746043 0.125071 0.032 0.0385 0.126643 0.031999 0.046101 0.126304 -0.037564 0 0.128802 0.032 0.0233 0.127319 0.032 0.0385 0.126643 -0.037564 0 0.128802 -0.037564 0 0.128802 0.032 0 0.127742 0.032 0.0233 0.127319 0.005444 -0.0750835 0.125001 -0.010806 -0.07299799999999999 0.125001 -0.0123327 -0.105571 0.110741 -0.034333 -0.101409 0.110741 -0.0123327 -0.105571 0.110741 -0.063108 -0.092641 0.111518 -0.0408953 -0.101299 0.103098 0.0319861 -0.109 0.101998 -0.034333 -0.101409 0.110741 0.005444 -0.0750835 0.125001 -0.037564 0 0.128802 -0.010806 -0.07299799999999999 0.125001 0.0185966 -0.104158 0.0586725 0.033113 -0.10193 0.0566797 0.0110499 -0.105577 0.0695487 0.033113 0.10193 0.0566797 0.0321408 0.105105 0.0633421 0.0439882 0.101818 0.0625549 0.0319804 0.109072 0.110612 0.0511137 0.105412 0.111116 0.0319861 0.109 0.101998 0.0319954 0.0746043 0.125071 0.019698 0.07620399999999999 0.125 -0.037564 0 0.128802 0.0319954 0.0746043 0.125071 0.0319804 0.109072 0.110612 0.019698 0.07620399999999999 0.125 -0.010806 -0.07299799999999999 0.125001 -0.028867 -0.069401 0.125 -0.0123327 -0.105571 0.110741 -0.052913 -0.062385 0.125001 -0.063108 -0.092641 0.111518 -0.0123327 -0.105571 0.110741 -0.063108 -0.092641 0.111518 -0.0770955 -0.0882175 0.110741 -0.034333 -0.101409 0.110741 -0.09939149999999999 -0.07876850000000001 0.103001 -0.0408953 -0.101299 0.103098 -0.034333 -0.101409 0.110741 -0.010806 -0.07299799999999999 0.125001 -0.037564 0 0.128802 -0.028867 -0.069401 0.125 -0.0202878 -0.102352 0.0753364 0.0064448 -0.103479 0.0603882 0.0110499 -0.105577 0.0695487 0.0064448 -0.103479 0.0603882 0.0185966 -0.104158 0.0586725 0.0110499 -0.105577 0.0695487 0.0321408 0.105105 0.0633421 0.033113 0.10193 0.0566797 0.0110499 0.105577 0.0695487 0.0319804 0.109072 0.110612 0.0319861 0.109 0.101998 -0.0123327 0.105571 0.110741 0.005444 0.0750835 0.125001 -0.037564 0 0.128802 0.019698 0.07620399999999999 0.125 0.019698 0.07620399999999999 0.125 0.0319804 0.109072 0.110612 0.005444 0.0750835 0.125001 -0.028867 -0.069401 0.125 -0.037565 -0.067034 0.125001 -0.0123327 -0.105571 0.110741 -0.0123327 -0.105571 0.110741 -0.04664 -0.064565 0.125001 -0.052913 -0.062385 0.125001 -0.052913 -0.062385 0.125001 -0.064015 -0.058525 0.125001 -0.063108 -0.092641 0.111518 -0.063108 -0.092641 0.111518 -0.09924570000000001 -0.0784671 0.110741 -0.0770955 -0.0882175 0.110741 -0.0770955 -0.0882175 0.110741 -0.09939149999999999 -0.07876850000000001 0.103001 -0.034333 -0.101409 0.110741 -0.09939149999999999 -0.07876850000000001 0.103001 -0.07779949999999999 -0.08744399999999999 0.08396000000000001 -0.0408953 -0.101299 0.103098 -0.028867 -0.069401 0.125 -0.037564 0 0.128802 -0.037565 -0.067034 0.125001 0.0064448 -0.103479 0.0603882 -0.0202878 -0.102352 0.0753364 -0.0016799 -0.102786 0.061436 -0.0408953 -0.101299 0.103098 -0.063125 -0.092692 0.083632 -0.0346432 -0.09947110000000001 0.08280899999999999 0.0110499 0.105577 0.0695487 0.033113 0.10193 0.0566797 0.0185966 0.104158 0.0586725 -0.0123327 0.105571 0.110741 0.0319861 0.109 0.101998 -0.034333 0.101409 0.110741 -0.0123327 0.105571 0.110741 0.005444 0.0750835 0.125001 0.0319804 0.109072 0.110612 0.005444 0.0750835 0.125001 -0.010806 0.07299799999999999 0.125001 -0.037564 0 0.128802 -0.037565 -0.067034 0.125001 -0.04664 -0.064565 0.125001 -0.0123327 -0.105571 0.110741 -0.04664 -0.064565 0.125001 -0.037564 0 0.128802 -0.052913 -0.062385 0.125001 -0.052913 -0.062385 0.125001 -0.037564 0 0.128802 -0.064015 -0.058525 0.125001 -0.075351 -0.053839 0.125001 -0.063108 -0.092641 0.111518 -0.064015 -0.058525 0.125001 -0.08645700000000001 -0.048639 0.125001 -0.09924570000000001 -0.0784671 0.110741 -0.063108 -0.092641 0.111518 -0.09939149999999999 -0.07876850000000001 0.103001 -0.0770955 -0.0882175 0.110741 -0.09924570000000001 -0.0784671 0.110741 -0.07779949999999999 -0.08744399999999999 0.08396000000000001 -0.063125 -0.092692 0.083632 -0.0408953 -0.101299 0.103098 -0.09939149999999999 -0.07876850000000001 0.103001 -0.100689 -0.07729900000000001 0.084422 -0.07779949999999999 -0.08744399999999999 0.08396000000000001 -0.037565 -0.067034 0.125001 -0.037564 0 0.128802 -0.04664 -0.064565 0.125001 -0.0016799 -0.102786 0.061436 -0.0202878 -0.102352 0.0753364 -0.0089414 -0.101944 0.0623748 -0.0285344 -0.0982736 0.0646608 -0.0202878 -0.102352 0.0753364 -0.0330929 -0.100183 0.07866239999999999 -0.0346432 -0.09947110000000001 0.08280899999999999 -0.063125 -0.092692 0.083632 -0.0330929 -0.100183 0.07866239999999999 0.0110499 0.105577 0.0695487 0.0185966 0.104158 0.0586725 0.0064448 0.103479 0.0603882 -0.034333 0.101409 0.110741 0.0319861 0.109 0.101998 -0.0408953 0.101299 0.103098 -0.034333 0.101409 0.110741 -0.063108 0.092641 0.111518 -0.0123327 0.105571 0.110741 -0.0123327 0.105571 0.110741 -0.010806 0.07299799999999999 0.125001 0.005444 0.0750835 0.125001 -0.010806 0.07299799999999999 0.125001 -0.028867 0.069401 0.125 -0.037564 0 0.128802 -0.064015 -0.058525 0.125001 -0.037564 0 0.128802 -0.075351 -0.053839 0.125001 -0.075351 -0.053839 0.125001 -0.08645700000000001 -0.048639 0.125001 -0.063108 -0.092641 0.111518 -0.0950235 -0.0427225 0.125001 -0.09924570000000001 -0.0784671 0.110741 -0.08645700000000001 -0.048639 0.125001 -0.09924570000000001 -0.0784671 0.110741 -0.107529 -0.07389519999999999 0.111111 -0.09939149999999999 -0.07876850000000001 0.103001 -0.07779949999999999 -0.08744399999999999 0.08396000000000001 -0.07969900000000001 -0.08581800000000001 0.07814599999999999 -0.063125 -0.092692 0.083632 -0.100689 -0.07729900000000001 0.084422 -0.09939149999999999 -0.07876850000000001 0.103001 -0.107575 -0.0739665 0.103001 -0.07779949999999999 -0.08744399999999999 0.08396000000000001 -0.100689 -0.07729900000000001 0.084422 -0.07969900000000001 -0.08581800000000001 0.07814599999999999 -0.0285344 -0.0982736 0.0646608 -0.0089414 -0.101944 0.0623748 -0.0202878 -0.102352 0.0753364 -0.0465219 -0.0942286 0.06660339999999999 -0.0285344 -0.0982736 0.0646608 -0.0330929 -0.100183 0.07866239999999999 -0.063125 -0.092692 0.083632 -0.07969900000000001 -0.08581800000000001 0.07814599999999999 -0.0330929 -0.100183 0.07866239999999999 -0.0202878 0.102352 0.0753364 0.0110499 0.105577 0.0695487 0.0064448 0.103479 0.0603882 -0.0408953 0.101299 0.103098 -0.09939149999999999 0.07876850000000001 0.103001 -0.034333 0.101409 0.110741 -0.0123327 0.105571 0.110741 -0.063108 0.092641 0.111518 -0.052913 0.062385 0.125001 -0.0770955 0.0882175 0.110741 -0.063108 0.092641 0.111518 -0.034333 0.101409 0.110741 -0.010806 0.07299799999999999 0.125001 -0.0123327 0.105571 0.110741 -0.028867 0.069401 0.125 -0.037565 0.067034 0.125001 -0.037564 0 0.128802 -0.028867 0.069401 0.125 -0.075351 -0.053839 0.125001 -0.037564 0 0.128802 -0.08645700000000001 -0.048639 0.125001 -0.08645700000000001 -0.048639 0.125001 -0.037564 0 0.128802 -0.0950235 -0.0427225 0.125001 -0.09924570000000001 -0.0784671 0.110741 -0.0950235 -0.0427225 0.125001 -0.107529 -0.07389519999999999 0.111111 -0.107529 -0.07389519999999999 0.111111 -0.107575 -0.0739665 0.103001 -0.09939149999999999 -0.07876850000000001 0.103001 -0.108178 -0.07291449999999999 0.08489049999999999 -0.100689 -0.07729900000000001 0.084422 -0.107575 -0.0739665 0.103001 -0.108178 -0.07291449999999999 0.08489049999999999 -0.07969900000000001 -0.08581800000000001 0.07814599999999999 -0.100689 -0.07729900000000001 0.084422 -0.07969900000000001 -0.08581800000000001 0.07814599999999999 -0.0465219 -0.0942286 0.06660339999999999 -0.0330929 -0.100183 0.07866239999999999 0.0064448 0.103479 0.0603882 -0.0016799 0.102786 0.061436 -0.0202878 0.102352 0.0753364 -0.0408953 0.101299 0.103098 -0.07779949999999999 0.08744399999999999 0.08396000000000001 -0.09939149999999999 0.07876850000000001 0.103001 -0.0770955 0.0882175 0.110741 -0.034333 0.101409 0.110741 -0.09939149999999999 0.07876850000000001 0.103001 -0.052913 0.062385 0.125001 -0.04664 0.064565 0.125001 -0.0123327 0.105571 0.110741 -0.052913 0.062385 0.125001 -0.063108 0.092641 0.111518 -0.064015 0.058525 0.125001 -0.09924570000000001 0.0784671 0.110741 -0.063108 0.092641 0.111518 -0.0770955 0.0882175 0.110741 -0.0123327 0.105571 0.110741 -0.037565 0.067034 0.125001 -0.028867 0.069401 0.125 -0.037565 0.067034 0.125001 -0.04664 0.064565 0.125001 -0.037564 0 0.128802 -0.0950235 -0.0427225 0.125001 -0.037564 0 0.128802 -0.101684 -0.034464 0.125 -0.107529 -0.07389519999999999 0.111111 -0.0950235 -0.0427225 0.125001 -0.122461 -0.0609567 0.111111 -0.122461 -0.0609567 0.111111 -0.107575 -0.0739665 0.103001 -0.107529 -0.07389519999999999 0.111111 -0.107575 -0.0739665 0.103001 -0.11354 -0.06902800000000001 0.085162 -0.108178 -0.07291449999999999 0.08489049999999999 -0.108176 -0.071696 0.07814599999999999 -0.07969900000000001 -0.08581800000000001 0.07814599999999999 -0.108178 -0.07291449999999999 0.08489049999999999 -0.07969900000000001 -0.08581800000000001 0.07814599999999999 -0.058904 -0.09046029999999999 0.0677659 -0.0465219 -0.0942286 0.06660339999999999 -0.0089414 0.101944 0.0623748 -0.0202878 0.102352 0.0753364 -0.0016799 0.102786 0.061436 -0.0346432 0.09947110000000001 0.08280899999999999 -0.063125 0.092692 0.083632 -0.0408953 0.101299 0.103098 -0.0408953 0.101299 0.103098 -0.063125 0.092692 0.083632 -0.07779949999999999 0.08744399999999999 0.08396000000000001 -0.09939149999999999 0.07876850000000001 0.103001 -0.07779949999999999 0.08744399999999999 0.08396000000000001 -0.100689 0.07729900000000001 0.084422 -0.0770955 0.0882175 0.110741 -0.09939149999999999 0.07876850000000001 0.103001 -0.09924570000000001 0.0784671 0.110741 -0.037565 0.067034 0.125001 -0.0123327 0.105571 0.110741 -0.04664 0.064565 0.125001 -0.04664 0.064565 0.125001 -0.052913 0.062385 0.125001 -0.037564 0 0.128802 -0.064015 0.058525 0.125001 -0.063108 0.092641 0.111518 -0.075351 0.053839 0.125001 -0.052913 0.062385 0.125001 -0.064015 0.058525 0.125001 -0.037564 0 0.128802 -0.063108 0.092641 0.111518 -0.09924570000000001 0.0784671 0.110741 -0.08645700000000001 0.048639 0.125001 -0.101684 -0.034464 0.125 -0.037564 0 0.128802 -0.105721 -0.024664 0.125001 -0.101684 -0.034464 0.125 -0.122461 -0.0609567 0.111111 -0.0950235 -0.0427225 0.125001 -0.122525 -0.0610125 0.103001 -0.107575 -0.0739665 0.103001 -0.122461 -0.0609567 0.111111 -0.107575 -0.0739665 0.103001 -0.121297 -0.0615358 0.0854115 -0.11354 -0.06902800000000001 0.085162 -0.108178 -0.07291449999999999 0.08489049999999999 -0.11354 -0.06902800000000001 0.085162 -0.108176 -0.071696 0.07814599999999999 -0.108176 -0.071696 0.07814599999999999 -0.0764845 -0.08436970000000001 0.0693015 -0.07969900000000001 -0.08581800000000001 0.07814599999999999 -0.07969900000000001 -0.08581800000000001 0.07814599999999999 -0.06490940000000001 -0.08864080000000001 0.0683048 -0.058904 -0.09046029999999999 0.0677659 -0.0202878 0.102352 0.0753364 -0.0089414 0.101944 0.0623748 -0.0285344 0.0982736 0.0646608 -0.0346432 0.09947110000000001 0.08280899999999999 -0.0330929 0.100183 0.07866239999999999 -0.063125 0.092692 0.083632 -0.07779949999999999 0.08744399999999999 0.08396000000000001 -0.063125 0.092692 0.083632 -0.07969900000000001 0.08581800000000001 0.07814599999999999 -0.07969900000000001 0.08581800000000001 0.07814599999999999 -0.100689 0.07729900000000001 0.084422 -0.07779949999999999 0.08744399999999999 0.08396000000000001 -0.100689 0.07729900000000001 0.084422 -0.107575 0.0739665 0.103001 -0.09939149999999999 0.07876850000000001 0.103001 -0.09924570000000001 0.0784671 0.110741 -0.09939149999999999 0.07876850000000001 0.103001 -0.107529 0.07389519999999999 0.111111 -0.063108 0.092641 0.111518 -0.08645700000000001 0.048639 0.125001 -0.075351 0.053839 0.125001 -0.064015 0.058525 0.125001 -0.075351 0.053839 0.125001 -0.037564 0 0.128802 -0.09924570000000001 0.0784671 0.110741 -0.0950235 0.0427225 0.125001 -0.08645700000000001 0.048639 0.125001 -0.0330929 0.100183 0.07866239999999999 -0.0202878 0.102352 0.0753364 -0.0285344 0.0982736 0.0646608 -0.105721 -0.024664 0.125001 -0.037564 0 0.128802 -0.107001 -0.015499 0.125 -0.101684 -0.034464 0.125 -0.105721 -0.024664 0.125001 -0.131843 -0.0461646 0.111111 -0.101684 -0.034464 0.125 -0.131843 -0.0461646 0.111111 -0.122461 -0.0609567 0.111111 -0.121297 -0.0615358 0.0854115 -0.107575 -0.0739665 0.103001 -0.122525 -0.0610125 0.103001 -0.122525 -0.0610125 0.103001 -0.122461 -0.0609567 0.111111 -0.131843 -0.0461646 0.111111 -0.121297 -0.0615358 0.0854115 -0.119723 -0.061627 0.07814599999999999 -0.11354 -0.06902800000000001 0.085162 -0.11354 -0.06902800000000001 0.085162 -0.119723 -0.061627 0.07814599999999999 -0.108176 -0.071696 0.07814599999999999 -0.108176 -0.071696 0.07814599999999999 -0.0872566 -0.07937669999999999 0.0680486 -0.0764845 -0.08436970000000001 0.0693015 -0.07969900000000001 -0.08581800000000001 0.07814599999999999 -0.0764845 -0.08436970000000001 0.0693015 -0.06490940000000001 -0.08864080000000001 0.0683048 -0.0330929 0.100183 0.07866239999999999 -0.07969900000000001 0.08581800000000001 0.07814599999999999 -0.063125 0.092692 0.083632 -0.100689 0.07729900000000001 0.084422 -0.07969900000000001 0.08581800000000001 0.07814599999999999 -0.108178 0.07291449999999999 0.08489049999999999 -0.100689 0.07729900000000001 0.084422 -0.108178 0.07291449999999999 0.08489049999999999 -0.107575 0.0739665 0.103001 -0.107529 0.07389519999999999 0.111111 -0.09939149999999999 0.07876850000000001 0.103001 -0.107575 0.0739665 0.103001 -0.107529 0.07389519999999999 0.111111 -0.0950235 0.0427225 0.125001 -0.09924570000000001 0.0784671 0.110741 -0.037564 0 0.128802 -0.075351 0.053839 0.125001 -0.08645700000000001 0.048639 0.125001 -0.037564 0 0.128802 -0.08645700000000001 0.048639 0.125001 -0.0950235 0.0427225 0.125001 -0.0330929 0.100183 0.07866239999999999 -0.0285344 0.0982736 0.0646608 -0.0465219 0.0942286 0.06660339999999999 -0.107001 -0.015499 0.125 -0.037564 0 0.128802 -0.107001 0.015499 0.125 -0.107001 -0.015499 0.125 -0.138043 -0.0272352 0.111111 -0.105721 -0.024664 0.125001 -0.131843 -0.0461646 0.111111 -0.105721 -0.024664 0.125001 -0.138043 -0.0272352 0.111111 -0.129091 -0.050982 0.0854665 -0.121297 -0.0615358 0.0854115 -0.122525 -0.0610125 0.103001 -0.122525 -0.0610125 0.103001 -0.131843 -0.0461646 0.111111 -0.13322 -0.0443705 0.103001 -0.121297 -0.0615358 0.0854115 -0.128704 -0.04946 0.07814599999999999 -0.119723 -0.061627 0.07814599999999999 -0.119723 -0.061627 0.07814599999999999 -0.100322 -0.0727418 0.07078710000000001 -0.108176 -0.071696 0.07814599999999999 -0.108176 -0.071696 0.07814599999999999 -0.100322 -0.0727418 0.07078710000000001 -0.0872566 -0.07937669999999999 0.0680486 -0.0330929 0.100183 0.07866239999999999 -0.0465219 0.0942286 0.06660339999999999 -0.07969900000000001 0.08581800000000001 0.07814599999999999 -0.108178 0.07291449999999999 0.08489049999999999 -0.07969900000000001 0.08581800000000001 0.07814599999999999 -0.108176 0.071696 0.07814599999999999 -0.107575 0.0739665 0.103001 -0.108178 0.07291449999999999 0.08489049999999999 -0.11354 0.06902800000000001 0.085162 -0.107529 0.07389519999999999 0.111111 -0.107575 0.0739665 0.103001 -0.122461 0.0609567 0.111111 -0.0950235 0.0427225 0.125001 -0.107529 0.07389519999999999 0.111111 -0.122461 0.0609567 0.111111 -0.101684 0.034464 0.125 -0.037564 0 0.128802 -0.0950235 0.0427225 0.125001 -0.037564 0 0.128802 -0.105721 0.024664 0.125001 -0.107001 0.015499 0.125 -0.107001 -0.015499 0.125 -0.107001 0.015499 0.125 -0.139542 -0.015499 0.111111 -0.107001 -0.015499 0.125 -0.139542 -0.015499 0.111111 -0.138043 -0.0272352 0.111111 -0.131843 -0.0461646 0.111111 -0.138043 -0.0272352 0.111111 -0.13322 -0.0443705 0.103001 -0.128704 -0.04946 0.07814599999999999 -0.121297 -0.0615358 0.0854115 -0.129091 -0.050982 0.0854665 -0.129091 -0.050982 0.0854665 -0.122525 -0.0610125 0.103001 -0.13322 -0.0443705 0.103001 -0.123637 -0.0551181 0.0752428 -0.128704 -0.04946 0.07814599999999999 -0.123153 -0.054568 0.0723395 -0.123637 -0.0551181 0.0752428 -0.123153 -0.054568 0.0723395 -0.119723 -0.061627 0.07814599999999999 -0.123637 -0.0551181 0.0752428 -0.119723 -0.061627 0.07814599999999999 -0.128704 -0.04946 0.07814599999999999 -0.119723 -0.061627 0.07814599999999999 -0.106402 -0.06835049999999999 0.0714221 -0.100322 -0.0727418 0.07078710000000001 -0.0465219 0.0942286 0.06660339999999999 -0.058904 0.09046029999999999 0.0677659 -0.07969900000000001 0.08581800000000001 0.07814599999999999 -0.0764845 0.08436970000000001 0.0693015 -0.108176 0.071696 0.07814599999999999 -0.07969900000000001 0.08581800000000001 0.07814599999999999 -0.11354 0.06902800000000001 0.085162 -0.108178 0.07291449999999999 0.08489049999999999 -0.108176 0.071696 0.07814599999999999 -0.107575 0.0739665 0.103001 -0.11354 0.06902800000000001 0.085162 -0.121297 0.0615358 0.0854115 -0.107575 0.0739665 0.103001 -0.122525 0.0610125 0.103001 -0.122461 0.0609567 0.111111 -0.0950235 0.0427225 0.125001 -0.122461 0.0609567 0.111111 -0.101684 0.034464 0.125 -0.105721 0.024664 0.125001 -0.037564 0 0.128802 -0.101684 0.034464 0.125 -0.107001 0.015499 0.125 -0.105721 0.024664 0.125001 -0.138043 0.0272352 0.111111 -0.107001 0.015499 0.125 -0.139542 0.015499 0.111111 -0.139542 -0.015499 0.111111 -0.138043 -0.0272352 0.111111 -0.139542 -0.015499 0.111111 -0.138794 -0.02539 0.103001 -0.13322 -0.0443705 0.103001 -0.138043 -0.0272352 0.111111 -0.138794 -0.02539 0.103001 -0.129091 -0.050982 0.0854665 -0.133236 -0.042855 0.08531999999999999 -0.128704 -0.04946 0.07814599999999999 -0.133236 -0.042855 0.08531999999999999 -0.129091 -0.050982 0.0854665 -0.13322 -0.0443705 0.103001 -0.127956 -0.0472607 0.0725753 -0.123153 -0.054568 0.0723395 -0.128704 -0.04946 0.07814599999999999 -0.119723 -0.061627 0.07814599999999999 -0.123153 -0.054568 0.0723395 -0.115644 -0.06342879999999999 0.0719914 -0.115644 -0.06342879999999999 0.0719914 -0.106402 -0.06835049999999999 0.0714221 -0.119723 -0.061627 0.07814599999999999 -0.058904 0.09046029999999999 0.0677659 -0.06490940000000001 0.08864080000000001 0.0683048 -0.07969900000000001 0.08581800000000001 0.07814599999999999 -0.0764845 0.08436970000000001 0.0693015 -0.0872566 0.07937669999999999 0.0680486 -0.108176 0.071696 0.07814599999999999 -0.07969900000000001 0.08581800000000001 0.07814599999999999 -0.06490940000000001 0.08864080000000001 0.0683048 -0.0764845 0.08436970000000001 0.0693015 -0.11354 0.06902800000000001 0.085162 -0.108176 0.071696 0.07814599999999999 -0.119723 0.061627 0.07814599999999999 -0.107575 0.0739665 0.103001 -0.121297 0.0615358 0.0854115 -0.122525 0.0610125 0.103001 -0.11354 0.06902800000000001 0.085162 -0.119723 0.061627 0.07814599999999999 -0.121297 0.0615358 0.0854115 -0.122525 0.0610125 0.103001 -0.131843 0.0461646 0.111111 -0.122461 0.0609567 0.111111 -0.122461 0.0609567 0.111111 -0.131843 0.0461646 0.111111 -0.101684 0.034464 0.125 -0.101684 0.034464 0.125 -0.131843 0.0461646 0.111111 -0.105721 0.024664 0.125001 -0.105721 0.024664 0.125001 -0.131843 0.0461646 0.111111 -0.138043 0.0272352 0.111111 -0.107001 0.015499 0.125 -0.138043 0.0272352 0.111111 -0.139542 0.015499 0.111111 -0.139542 0.015499 0.111111 -0.14 -0.008515999999999999 0.101001 -0.139542 -0.015499 0.111111 -0.13975 -0.015499 0.102001 -0.138794 -0.02539 0.103001 -0.139542 -0.015499 0.111111 -0.137311 -0.030674 0.084881 -0.13322 -0.0443705 0.103001 -0.138794 -0.02539 0.103001 -0.132447 -0.0428433 0.081733 -0.134865 -0.035636 0.07814599999999999 -0.128704 -0.04946 0.07814599999999999 -0.132447 -0.0428433 0.081733 -0.128704 -0.04946 0.07814599999999999 -0.133236 -0.042855 0.08531999999999999 -0.132447 -0.0428433 0.081733 -0.133236 -0.042855 0.08531999999999999 -0.134865 -0.035636 0.07814599999999999 -0.135537 -0.036309 0.085096 -0.133236 -0.042855 0.08531999999999999 -0.13322 -0.0443705 0.103001 -0.127956 -0.0472607 0.0725753 -0.128704 -0.04946 0.07814599999999999 -0.134865 -0.035636 0.07814599999999999 -0.127956 -0.0472607 0.0725753 -0.127956 0.0472607 0.0725753 -0.123153 -0.054568 0.0723395 -0.115644 -0.06342879999999999 0.0719914 -0.123153 -0.054568 0.0723395 -0.115412 -0.052719 0.071834 -0.106402 -0.06835049999999999 0.0714221 -0.115644 -0.06342879999999999 0.0719914 -0.111276 -0.059601 0.0716055 -0.0872566 0.07937669999999999 0.0680486 -0.100322 0.0727418 0.07078710000000001 -0.108176 0.071696 0.07814599999999999 -0.108176 0.071696 0.07814599999999999 -0.100322 0.0727418 0.07078710000000001 -0.119723 0.061627 0.07814599999999999 -0.121297 0.0615358 0.0854115 -0.129091 0.050982 0.0854665 -0.122525 0.0610125 0.103001 -0.128704 0.04946 0.07814599999999999 -0.121297 0.0615358 0.0854115 -0.119723 0.061627 0.07814599999999999 -0.131843 0.0461646 0.111111 -0.122525 0.0610125 0.103001 -0.13322 0.0443705 0.103001 -0.138043 0.0272352 0.111111 -0.131843 0.0461646 0.111111 -0.13322 0.0443705 0.103001 -0.138794 0.02539 0.103001 -0.139542 0.015499 0.111111 -0.138043 0.0272352 0.111111 -0.139542 0.015499 0.111111 -0.14 0.008515999999999999 0.101001 -0.14 -0.008515999999999999 0.101001 -0.14 -0.008515999999999999 0.101001 -0.13975 -0.015499 0.102001 -0.139542 -0.015499 0.111111 -0.138423 -0.023706 0.0844642 -0.138794 -0.02539 0.103001 -0.13975 -0.015499 0.102001 -0.138423 -0.023706 0.0844642 -0.137311 -0.030674 0.084881 -0.138794 -0.02539 0.103001 -0.13322 -0.0443705 0.103001 -0.137311 -0.030674 0.084881 -0.135537 -0.036309 0.085096 -0.133236 -0.042855 0.08531999999999999 -0.135537 -0.036309 0.085096 -0.134865 -0.035636 0.07814599999999999 -0.127956 -0.0472607 0.0725753 -0.134865 -0.035636 0.07814599999999999 -0.13141 -0.0399979 0.07272289999999999 -0.123153 0.054568 0.0723395 -0.123153 -0.054568 0.0723395 -0.127956 0.0472607 0.0725753 -0.127956 0.0472607 0.0725753 -0.127956 -0.0472607 0.0725753 -0.13141 0.0399979 0.07272289999999999 -0.111276 -0.059601 0.0716055 -0.115644 -0.06342879999999999 0.0719914 -0.115412 -0.052719 0.071834 -0.115412 -0.052719 0.071834 -0.123153 -0.054568 0.0723395 -0.118166 -0.045432 0.07198 -0.100322 0.0727418 0.07078710000000001 -0.106402 0.06835049999999999 0.0714221 -0.119723 0.061627 0.07814599999999999 -0.128704 0.04946 0.07814599999999999 -0.129091 0.050982 0.0854665 -0.121297 0.0615358 0.0854115 -0.13322 0.0443705 0.103001 -0.122525 0.0610125 0.103001 -0.129091 0.050982 0.0854665 -0.123637 0.0551181 0.0752428 -0.123153 0.054568 0.0723395 -0.128704 0.04946 0.07814599999999999 -0.123637 0.0551181 0.0752428 -0.128704 0.04946 0.07814599999999999 -0.119723 0.061627 0.07814599999999999 -0.123637 0.0551181 0.0752428 -0.119723 0.061627 0.07814599999999999 -0.123153 0.054568 0.0723395 -0.138043 0.0272352 0.111111 -0.13322 0.0443705 0.103001 -0.138794 0.02539 0.103001 -0.13975 0.015499 0.102001 -0.139542 0.015499 0.111111 -0.138794 0.02539 0.103001 -0.13975 0.015499 0.102001 -0.14 0.008515999999999999 0.101001 -0.139542 0.015499 0.111111 -0.14 0.008515999999999999 0.101001 -0.139 -0.015499 0.083858 -0.14 -0.008515999999999999 0.101001 -0.139 -0.015499 0.083858 -0.13975 -0.015499 0.102001 -0.14 -0.008515999999999999 0.101001 -0.139 -0.015499 0.083858 -0.138423 -0.023706 0.0844642 -0.13975 -0.015499 0.102001 -0.137933 -0.020583 0.07814599999999999 -0.137311 -0.030674 0.084881 -0.138423 -0.023706 0.0844642 -0.135537 -0.036309 0.085096 -0.137311 -0.030674 0.084881 -0.134865 -0.035636 0.07814599999999999 -0.134865 -0.035636 0.07814599999999999 -0.134247 -0.0329842 0.07287829999999999 -0.13141 -0.0399979 0.07272289999999999 -0.13141 -0.0399979 0.07272289999999999 -0.13141 0.0399979 0.07272289999999999 -0.127956 -0.0472607 0.0725753 -0.127956 0.0472607 0.0725753 -0.128704 0.04946 0.07814599999999999 -0.123153 0.054568 0.0723395 -0.123153 -0.054568 0.0723395 -0.123153 0.054568 0.0723395 -0.119664 -0.038846 0.072058 -0.127956 0.0472607 0.0725753 -0.13141 0.0399979 0.07272289999999999 -0.134865 0.035636 0.07814599999999999 -0.118166 -0.045432 0.07198 -0.123153 -0.054568 0.0723395 -0.119664 -0.038846 0.072058 -0.106402 0.06835049999999999 0.0714221 -0.115644 0.06342879999999999 0.0719914 -0.119723 0.061627 0.07814599999999999 -0.133236 0.042855 0.08531999999999999 -0.129091 0.050982 0.0854665 -0.128704 0.04946 0.07814599999999999 -0.129091 0.050982 0.0854665 -0.133236 0.042855 0.08531999999999999 -0.13322 0.0443705 0.103001 -0.115644 0.06342879999999999 0.0719914 -0.123153 0.054568 0.0723395 -0.119723 0.061627 0.07814599999999999 -0.138794 0.02539 0.103001 -0.13322 0.0443705 0.103001 -0.137311 0.030674 0.084881 -0.138423 0.023706 0.0844642 -0.13975 0.015499 0.102001 -0.138794 0.02539 0.103001 -0.139 0.015499 0.083858 -0.14 0.008515999999999999 0.101001 -0.13975 0.015499 0.102001 -0.14 0.008515999999999999 0.101001 -0.139 0.015499 0.083858 -0.139 -0.015499 0.083858 -0.137933 -0.020583 0.07814599999999999 -0.138423 -0.023706 0.0844642 -0.139 -0.015499 0.083858 -0.137933 -0.020583 0.07814599999999999 -0.134865 -0.035636 0.07814599999999999 -0.137311 -0.030674 0.084881 -0.137933 -0.020583 0.07814599999999999 -0.134247 -0.0329842 0.07287829999999999 -0.134865 -0.035636 0.07814599999999999 -0.134247 -0.0329842 0.07287829999999999 -0.134247 0.0329842 0.07287829999999999 -0.13141 -0.0399979 0.07272289999999999 -0.13141 0.0399979 0.07272289999999999 -0.13141 -0.0399979 0.07272289999999999 -0.134247 0.0329842 0.07287829999999999 -0.134865 0.035636 0.07814599999999999 -0.128704 0.04946 0.07814599999999999 -0.127956 0.0472607 0.0725753 -0.119664 0.038846 0.072058 -0.119664 -0.038846 0.072058 -0.123153 0.054568 0.0723395 -0.134865 0.035636 0.07814599999999999 -0.13141 0.0399979 0.07272289999999999 -0.134247 0.0329842 0.07287829999999999 -0.111276 0.059601 0.0716055 -0.115644 0.06342879999999999 0.0719914 -0.106402 0.06835049999999999 0.0714221 -0.128704 0.04946 0.07814599999999999 -0.134865 0.035636 0.07814599999999999 -0.132447 0.0428433 0.081733 -0.134865 0.035636 0.07814599999999999 -0.133236 0.042855 0.08531999999999999 -0.132447 0.0428433 0.081733 -0.133236 0.042855 0.08531999999999999 -0.128704 0.04946 0.07814599999999999 -0.132447 0.0428433 0.081733 -0.133236 0.042855 0.08531999999999999 -0.135537 0.036309 0.085096 -0.13322 0.0443705 0.103001 -0.115412 0.052719 0.071834 -0.123153 0.054568 0.0723395 -0.115644 0.06342879999999999 0.0719914 -0.135537 0.036309 0.085096 -0.137311 0.030674 0.084881 -0.13322 0.0443705 0.103001 -0.137311 0.030674 0.084881 -0.138423 0.023706 0.0844642 -0.138794 0.02539 0.103001 -0.138423 0.023706 0.0844642 -0.139 0.015499 0.083858 -0.13975 0.015499 0.102001 -0.139 0.015499 0.083858 -0.137933 -0.020583 0.07814599999999999 -0.139 -0.015499 0.083858 -0.134247 -0.0329842 0.07287829999999999 -0.137933 -0.020583 0.07814599999999999 -0.135649 -0.0271832 0.0729051 -0.134247 0.0329842 0.07287829999999999 -0.134247 -0.0329842 0.07287829999999999 -0.135649 0.0271832 0.0729051 -0.118166 0.045432 0.07198 -0.119664 0.038846 0.072058 -0.123153 0.054568 0.0723395 -0.137933 0.020583 0.07814599999999999 -0.134865 0.035636 0.07814599999999999 -0.134247 0.0329842 0.07287829999999999 -0.115412 0.052719 0.071834 -0.115644 0.06342879999999999 0.0719914 -0.111276 0.059601 0.0716055 -0.134865 0.035636 0.07814599999999999 -0.135537 0.036309 0.085096 -0.133236 0.042855 0.08531999999999999 -0.118166 0.045432 0.07198 -0.123153 0.054568 0.0723395 -0.115412 0.052719 0.071834 -0.134865 0.035636 0.07814599999999999 -0.137311 0.030674 0.084881 -0.135537 0.036309 0.085096 -0.137933 0.020583 0.07814599999999999 -0.138423 0.023706 0.0844642 -0.137311 0.030674 0.084881 -0.137933 0.020583 0.07814599999999999 -0.139 0.015499 0.083858 -0.138423 0.023706 0.0844642 -0.139 0.015499 0.083858 -0.137933 0.020583 0.07814599999999999 -0.137933 -0.020583 0.07814599999999999 -0.137933 -0.020583 0.07814599999999999 -0.136357 -0.0215944 0.0729346 -0.135649 -0.0271832 0.0729051 -0.135649 -0.0271832 0.0729051 -0.135649 0.0271832 0.0729051 -0.134247 -0.0329842 0.07287829999999999 -0.135649 0.0271832 0.0729051 -0.137933 0.020583 0.07814599999999999 -0.134247 0.0329842 0.07287829999999999 -0.137311 0.030674 0.084881 -0.134865 0.035636 0.07814599999999999 -0.137933 0.020583 0.07814599999999999 -0.137933 -0.020583 0.07814599999999999 -0.137933 0.020583 0.07814599999999999 -0.13721 -0.0047312 0.07306799999999999 -0.136693 -0.0164143 0.0729489 -0.136357 -0.0215944 0.0729346 -0.137933 -0.020583 0.07814599999999999 -0.136357 -0.0215944 0.0729346 -0.136357 0.0215944 0.0729346 -0.135649 -0.0271832 0.0729051 -0.135649 0.0271832 0.0729051 -0.135649 -0.0271832 0.0729051 -0.136357 0.0215944 0.0729346 -0.136357 0.0215944 0.0729346 -0.137933 0.020583 0.07814599999999999 -0.135649 0.0271832 0.0729051 -0.13721 0.0047312 0.07306799999999999 -0.13721 -0.0047312 0.07306799999999999 -0.137933 0.020583 0.07814599999999999 -0.13721 -0.0047312 0.07306799999999999 -0.136693 -0.0164143 0.0729489 -0.137933 -0.020583 0.07814599999999999 -0.136693 -0.0164143 0.0729489 -0.136693 0.0164143 0.0729489 -0.136357 -0.0215944 0.0729346 -0.136357 0.0215944 0.0729346 -0.136357 -0.0215944 0.0729346 -0.136693 0.0164143 0.0729489 -0.136357 0.0215944 0.0729346 -0.136693 0.0164143 0.0729489 -0.137933 0.020583 0.07814599999999999 -0.137933 0.020583 0.07814599999999999 -0.136693 0.0164143 0.0729489 -0.13721 0.0047312 0.07306799999999999 -0.13721 -0.0047312 0.07306799999999999 -0.13721 0.0047312 0.07306799999999999 -0.136693 -0.0164143 0.0729489 -0.136693 0.0164143 0.0729489 -0.136693 -0.0164143 0.0729489 -0.13721 0.0047312 0.07306799999999999 0.080654 -0.060045 0.093608 0.08100599999999999 -0.06406299999999999 0.095738 0.08036600000000001 -0.056749 0.09046800000000001 0.08036600000000001 -0.056749 0.09046800000000001 0.080058 -0.053227 0.08215 0.080162 -0.054418 0.086552 0.08036600000000001 -0.056749 0.09046800000000001 0.08100599999999999 -0.06406299999999999 0.095738 0.080058 -0.053227 0.08215 0.081028 -0.06431099999999999 0.06417299999999999 0.08006099999999999 -0.053263 0.077588 0.080058 -0.053227 0.08215 0.08100599999999999 -0.06406299999999999 0.095738 0.081028 -0.06431099999999999 0.06417299999999999 0.080058 -0.053227 0.08215 0.08017100000000001 -0.054523 0.07320599999999999 0.08006099999999999 -0.053263 0.077588 0.08067299999999999 -0.06026 0.06623999999999999 0.08006099999999999 -0.053263 0.077588 0.081028 -0.06431099999999999 0.06417299999999999 0.08067299999999999 -0.06026 0.06623999999999999 0.081028 -0.06431099999999999 0.06417299999999999 0.08100599999999999 -0.06406299999999999 0.095738 0.08139399999999999 -0.068505 0.096701 0.081028 -0.06431099999999999 0.06417299999999999 0.08139399999999999 -0.068505 0.096701 0.081791 -0.07304099999999999 0.096426 0.08017100000000001 -0.054523 0.07320599999999999 0.08067299999999999 -0.06026 0.06623999999999999 0.08037999999999999 -0.056915 0.069327 0.081791 -0.07304099999999999 0.096426 0.082167 -0.077335 0.094932 0.081028 -0.06431099999999999 0.06417299999999999 0.082747 -0.083963 0.08881600000000001 0.082167 -0.077335 0.094932 0.082493 -0.081068 0.092331 0.081417 -0.068768 0.06328 0.081028 -0.06431099999999999 0.06417299999999999 0.081814 -0.073299 0.063628 0.081028 -0.06431099999999999 0.06417299999999999 0.082167 -0.077335 0.094932 0.082747 -0.083963 0.08881600000000001 0.082187 -0.077569 0.065189 0.081814 -0.073299 0.063628 0.08251 -0.08126 0.06784900000000001 0.081814 -0.073299 0.063628 0.081028 -0.06431099999999999 0.06417299999999999 0.082759 -0.08409999999999999 0.07141 0.082747 -0.083963 0.08881600000000001 0.082759 -0.08409999999999999 0.07141 0.081028 -0.06431099999999999 0.06417299999999999 0.082965 -0.086461 0.08013199999999999 0.082759 -0.08409999999999999 0.07141 0.082908 -0.08580699999999999 0.084646 0.082759 -0.08409999999999999 0.07141 0.082747 -0.083963 0.08881600000000001 0.082908 -0.08580699999999999 0.084646 0.081814 -0.073299 0.063628 0.082759 -0.08409999999999999 0.07141 0.08251 -0.08126 0.06784900000000001 0.082914 -0.085878 0.07560799999999999 0.082759 -0.08409999999999999 0.07141 0.082965 -0.086461 0.08013199999999999 0.08018599999999999 0.055698 0.08717800000000001 0.080067 0.054328 0.082828 0.080404 0.058187 0.09099500000000001 0.080148 0.055259 0.073838 0.080067 0.054328 0.082828 0.080053 0.054178 0.07826900000000001 0.08185000000000001 0.074708 0.096278 0.080404 0.058187 0.09099500000000001 0.080067 0.054328 0.082828 0.08185000000000001 0.074708 0.096278 0.080703 0.061608 0.093996 0.080404 0.058187 0.09099500000000001 0.080148 0.055259 0.073838 0.080343 0.05749 0.069865 0.080067 0.054328 0.082828 0.08222 0.07893699999999999 0.094609 0.08185000000000001 0.074708 0.096278 0.080067 0.054328 0.082828 0.08185000000000001 0.074708 0.096278 0.081062 0.06571 0.09596 0.080703 0.061608 0.093996 0.080971 0.06467000000000001 0.064411 0.081358 0.069087 0.063336 0.080625 0.060707 0.06664299999999999 0.080343 0.05749 0.069865 0.080625 0.060707 0.06664299999999999 0.080067 0.054328 0.082828 0.08222 0.07893699999999999 0.094609 0.080067 0.054328 0.082828 0.082924 0.086983 0.083984 0.08185000000000001 0.074708 0.096278 0.081454 0.070187 0.09674000000000001 0.081062 0.06571 0.09596 0.08175499999999999 0.073628 0.063497 0.082134 0.077958 0.06488099999999999 0.081358 0.069087 0.063336 0.080067 0.054328 0.082828 0.080625 0.060707 0.06664299999999999 0.081358 0.069087 0.063336 0.082924 0.086983 0.083984 0.080067 0.054328 0.082828 0.082965 0.087452 0.079446 0.082537 0.082561 0.09185699999999999 0.08222 0.07893699999999999 0.094609 0.082924 0.086983 0.083984 0.082965 0.087452 0.079446 0.081358 0.069087 0.063336 0.082134 0.077958 0.06488099999999999 0.082134 0.077958 0.06488099999999999 0.082466 0.08175499999999999 0.067387 0.082965 0.087452 0.079446 0.082965 0.087452 0.079446 0.080067 0.054328 0.082828 0.0815159 0.07088999999999999 0.07308199999999999 0.080067 0.054328 0.082828 0.081358 0.069087 0.063336 0.0815159 0.07088999999999999 0.07308199999999999 0.081358 0.069087 0.063336 0.082965 0.087452 0.079446 0.0815159 0.07088999999999999 0.07308199999999999 0.082537 0.082561 0.09185699999999999 0.082924 0.086983 0.083984 0.082777 0.085311 0.088225 0.082466 0.08175499999999999 0.067387 0.08272699999999999 0.08473799999999999 0.070829 0.082965 0.087452 0.079446 0.082965 0.087452 0.079446 0.08272699999999999 0.08473799999999999 0.070829 0.082897 0.086685 0.07495 0.051999 -0.058039 0.092728 0.051999 -0.053734 0.08688899999999999 0.0974365 -0.0356108 0.09132750000000001 0.051999 -0.058039 0.092728 0.0974365 -0.0356108 0.09132750000000001 0.096996 -0.040187 0.095039 0.09780460000000001 -0.0330589 0.0872802 0.0974365 -0.0356108 0.09132750000000001 0.051999 -0.053734 0.08688899999999999 0.0974365 -0.0356108 0.09132750000000001 0.0995905 -0.022541 0.101 0.096996 -0.040187 0.095039 0.096996 -0.040187 0.095039 0.051999 -0.064483 0.09662999999999999 0.051999 -0.058039 0.092728 0.0995905 -0.022541 0.101 0.0974365 -0.0356108 0.09132750000000001 0.09780460000000001 -0.0330589 0.0872802 0.051999 -0.053734 0.08688899999999999 0.051999 -0.052222 0.08 0.09780460000000001 -0.0330589 0.0872802 0.096996 -0.040187 0.095039 0.0995905 -0.022541 0.101 0.0962919 -0.044521 0.09890359999999999 0.051999 -0.064483 0.09662999999999999 0.096996 -0.040187 0.095039 0.0962919 -0.044521 0.09890359999999999 0.099926 -0.0095 0.0990685 0.0995905 -0.022541 0.101 0.09780460000000001 -0.0330589 0.0872802 0.051999 -0.052222 0.08 0.09620919999999999 -0.0318839 0.0792235 0.09780460000000001 -0.0330589 0.0872802 0.051999 -0.0737915 0.098 0.051999 -0.064483 0.09662999999999999 0.0962919 -0.044521 0.09890359999999999 0.051999 -0.053734 0.073112 0.09620919999999999 -0.0318839 0.0792235 0.051999 -0.052222 0.08 0.0993237 -0.0095 0.09103899999999999 0.099926 -0.0095 0.0990685 0.09780460000000001 -0.0330589 0.0872802 0.09780460000000001 -0.0330589 0.0872802 0.09620919999999999 -0.0318839 0.0792235 0.0993237 -0.0095 0.09103899999999999 0.0911151 -0.06285590000000001 0.09950000000000001 0.051999 -0.0737915 0.098 0.0962919 -0.044521 0.09890359999999999 0.0925892 -0.0353962 0.07214 0.051999 -0.053734 0.073112 0.051999 -0.058039 0.067272 0.051999 -0.053734 0.073112 0.0925892 -0.0353962 0.07214 0.09620919999999999 -0.0318839 0.0792235 0.0993237 0.0095 0.09103899999999999 0.099926 -0.0095 0.0990685 0.0993237 -0.0095 0.09103899999999999 0.098497 -0.0095 0.084927 0.0993237 -0.0095 0.09103899999999999 0.09620919999999999 -0.0318839 0.0792235 0.088891 -0.06880749999999999 0.09950000000000001 0.051999 -0.0737915 0.098 0.0911151 -0.06285590000000001 0.09950000000000001 0.082298 -0.0818285 0.096766 0.051999 -0.082388 0.09662999999999999 0.051999 -0.0737915 0.098 0.0888383 -0.0420635 0.0666032 0.051999 -0.058039 0.067272 0.051999 -0.064483 0.063371 0.0888383 -0.0420635 0.0666032 0.0925892 -0.0353962 0.07214 0.051999 -0.058039 0.067272 0.09620919999999999 -0.0318839 0.0792235 0.0925892 -0.0353962 0.07214 0.091955 -0.02645 0.067496 0.0993237 0.0095 0.09103899999999999 0.099926 0.0095 0.0990685 0.099926 -0.0095 0.0990685 0.098497 0.0095 0.084927 0.0993237 0.0095 0.09103899999999999 0.0993237 -0.0095 0.09103899999999999 0.0968975 -0.0095 0.078332 0.098497 -0.0095 0.084927 0.09620919999999999 -0.0318839 0.0792235 0.098497 0.0095 0.084927 0.0993237 -0.0095 0.09103899999999999 0.098497 -0.0095 0.084927 0.088891 -0.06880749999999999 0.09950000000000001 0.0858631 -0.07568 0.100202 0.051999 -0.0737915 0.098 0.082298 -0.0818285 0.096766 0.051999 -0.088228 0.092728 0.051999 -0.082388 0.09662999999999999 0.0858631 -0.07568 0.100202 0.082298 -0.0818285 0.096766 0.051999 -0.0737915 0.098 0.051999 -0.088228 0.092728 0.051999 -0.09213 0.08688899999999999 0.051999 -0.08685610000000001 0.0903545 0.051999 -0.09213 0.08688899999999999 0.051999 -0.0866497 0.08881989999999999 0.051999 -0.08685610000000001 0.0903545 0.0852195 -0.0497655 0.06319950000000001 0.051999 -0.064483 0.063371 0.051999 -0.0737915 0.062 0.051999 -0.064483 0.063371 0.0852195 -0.0497655 0.06319950000000001 0.0888383 -0.0420635 0.0666032 0.091955 -0.02645 0.067496 0.0925892 -0.0353962 0.07214 0.0888383 -0.0420635 0.0666032 0.0968975 -0.0095 0.078332 0.09620919999999999 -0.0318839 0.0792235 0.091955 -0.02645 0.067496 0.09780460000000001 0.0330589 0.0872802 0.099926 0.0095 0.0990685 0.0993237 0.0095 0.09103899999999999 0.0993237 0.0095 0.09103899999999999 0.098497 0.0095 0.084927 0.09620919999999999 0.0318839 0.0792235 0.0968975 0.0095 0.078332 0.098497 -0.0095 0.084927 0.0968975 -0.0095 0.078332 0.0968975 0.0095 0.078332 0.098497 0.0095 0.084927 0.098497 -0.0095 0.084927 0.082298 -0.0818285 0.096766 0.0778648 -0.0874693 0.09331780000000001 0.051999 -0.088228 0.092728 0.0858631 -0.07568 0.100202 0.08017199999999999 -0.0852165 0.100992 0.082298 -0.0818285 0.096766 0.051999 -0.09213 0.08688899999999999 0.051999 -0.088228 0.092728 0.0731089 -0.0916759 0.0875478 0.051999 -0.0885111 0.084646 0.051999 -0.08677260000000001 0.0885475 0.051999 -0.09213 0.08688899999999999 0.051999 -0.08677260000000001 0.0885475 0.051999 -0.0866529 0.08881600000000001 0.051999 -0.09213 0.08688899999999999 0.051999 -0.09213 0.08688899999999999 0.051999 -0.0866497 0.08881989999999999 0.051999 -0.0866529 0.08881600000000001 0.051999 -0.09213 0.08688899999999999 0.051999 -0.0935 0.08 0.051999 -0.0900748 0.08441 0.051999 -0.0935 0.08 0.051999 -0.08879579999999999 0.08269609999999999 0.051999 -0.0900748 0.08441 0.051999 -0.0885111 0.084646 0.051999 -0.09213 0.08688899999999999 0.051999 -0.0900748 0.08441 0.051999 -0.0737915 0.062 0.051999 -0.082388 0.063371 0.0805409 -0.06028 0.0611115 0.051999 -0.0737915 0.062 0.0805409 -0.06028 0.0611115 0.0852195 -0.0497655 0.06319950000000001 0.0837318 -0.0401518 0.0570936 0.0888383 -0.0420635 0.0666032 0.0852195 -0.0497655 0.06319950000000001 0.091955 -0.02645 0.067496 0.0888383 -0.0420635 0.0666032 0.0837318 -0.0401518 0.0570936 0.094705 -0.0095 0.071813 0.0968975 -0.0095 0.078332 0.091955 -0.02645 0.067496 0.0993237 0.0095 0.09103899999999999 0.09620919999999999 0.0318839 0.0792235 0.09780460000000001 0.0330589 0.0872802 0.09780460000000001 0.0330589 0.0872802 0.0995905 0.022541 0.101 0.099926 0.0095 0.0990685 0.09620919999999999 0.0318839 0.0792235 0.098497 0.0095 0.084927 0.0968975 0.0095 0.078332 0.094705 0.0095 0.071813 0.0968975 0.0095 0.078332 0.0968975 -0.0095 0.078332 0.051999 -0.088228 0.092728 0.0778648 -0.0874693 0.09331780000000001 0.0731089 -0.0916759 0.0875478 0.08017199999999999 -0.0852165 0.100992 0.0778648 -0.0874693 0.09331780000000001 0.08019850000000001 -0.0847348 0.0971549 0.0778648 -0.0874693 0.09331780000000001 0.082298 -0.0818285 0.096766 0.08019850000000001 -0.0847348 0.0971549 0.082298 -0.0818285 0.096766 0.08017199999999999 -0.0852165 0.100992 0.08019850000000001 -0.0847348 0.0971549 0.051999 -0.09213 0.08688899999999999 0.0731089 -0.0916759 0.0875478 0.068789 -0.09338200000000001 0.0793065 0.051999 -0.0935 0.08 0.051999 -0.09213 0.08688899999999999 0.068789 -0.09338200000000001 0.0793065 0.051999 -0.0891701 0.08013199999999999 0.051999 -0.08879579999999999 0.08269609999999999 0.051999 -0.0935 0.08 0.051999 -0.0935 0.08 0.051999 -0.09213 0.073112 0.051999 -0.09107179999999999 0.077904 0.051999 -0.09213 0.073112 0.051999 -0.0886436 0.0760777 0.051999 -0.09107179999999999 0.077904 0.051999 -0.0886436 0.0760777 0.051999 -0.0891359 0.079869 0.051999 -0.09107179999999999 0.077904 0.051999 -0.0891359 0.079869 0.051999 -0.0891701 0.08013199999999999 0.051999 -0.09107179999999999 0.077904 0.051999 -0.0891701 0.08013199999999999 0.051999 -0.0935 0.08 0.051999 -0.09107179999999999 0.077904 0.051999 -0.08847530000000001 0.0753567 0.051999 -0.0885826 0.07560799999999999 0.051999 -0.09213 0.073112 0.051999 -0.0885826 0.07560799999999999 0.051999 -0.0886436 0.0760777 0.051999 -0.09213 0.073112 0.051999 -0.09213 0.073112 0.051999 -0.088228 0.067272 0.051999 -0.0889846 0.0716749 0.051999 -0.08847530000000001 0.0753567 0.051999 -0.09213 0.073112 0.051999 -0.0889846 0.0716749 0.0712415 -0.08156770000000001 0.06320149999999999 0.051999 -0.082388 0.063371 0.051999 -0.088228 0.067272 0.0732285 -0.0753737 0.0600965 0.0805409 -0.06028 0.0611115 0.051999 -0.082388 0.063371 0.0805409 -0.06028 0.0611115 0.07482800000000001 -0.06694509999999999 0.0564331 0.0852195 -0.0497655 0.06319950000000001 0.0837318 -0.0401518 0.0570936 0.0852195 -0.0497655 0.06319950000000001 0.07482800000000001 -0.06694509999999999 0.0564331 0.08605599999999999 -0.0095 0.0546884 0.091955 -0.02645 0.067496 0.0837318 -0.0401518 0.0570936 0.0925458 -0.0095 0.0665335 0.094705 -0.0095 0.071813 0.091955 -0.02645 0.067496 0.094705 0.0095 0.071813 0.0968975 -0.0095 0.078332 0.094705 -0.0095 0.071813 0.09780460000000001 0.0330589 0.0872802 0.09620919999999999 0.0318839 0.0792235 0.051999 0.052222 0.08 0.0974365 0.0356108 0.09132750000000001 0.0995905 0.022541 0.101 0.09780460000000001 0.0330589 0.0872802 0.091955 0.02645 0.067496 0.09620919999999999 0.0318839 0.0792235 0.0968975 0.0095 0.078332 0.091955 0.02645 0.067496 0.0968975 0.0095 0.078332 0.094705 0.0095 0.071813 0.074183 -0.091999 0.100992 0.0731089 -0.0916759 0.0875478 0.07568800000000001 -0.0897714 0.0942699 0.0731089 -0.0916759 0.0875478 0.0778648 -0.0874693 0.09331780000000001 0.07568800000000001 -0.0897714 0.0942699 0.0778648 -0.0874693 0.09331780000000001 0.074183 -0.091999 0.100992 0.07568800000000001 -0.0897714 0.0942699 0.0778648 -0.0874693 0.09331780000000001 0.08017199999999999 -0.0852165 0.100992 0.074183 -0.091999 0.100992 0.0731089 -0.0916759 0.0875478 0.059371 -0.09991899999999999 0.07831299999999999 0.068789 -0.09338200000000001 0.0793065 0.051999 -0.0935 0.08 0.068789 -0.09338200000000001 0.0793065 0.067412 -0.091832 0.0726098 0.051999 -0.09213 0.073112 0.051999 -0.0935 0.08 0.067412 -0.091832 0.0726098 0.051999 -0.088228 0.067272 0.051999 -0.09213 0.073112 0.0683459 -0.0878439 0.0669984 0.0683459 -0.0878439 0.0669984 0.0712415 -0.08156770000000001 0.06320149999999999 0.051999 -0.088228 0.067272 0.0712415 -0.08156770000000001 0.06320149999999999 0.0732285 -0.0753737 0.0600965 0.051999 -0.082388 0.063371 0.0732285 -0.0753737 0.0600965 0.07482800000000001 -0.06694509999999999 0.0564331 0.0805409 -0.06028 0.0611115 0.08605599999999999 -0.0095 0.0546884 0.090143 -0.0095 0.061425 0.091955 -0.02645 0.067496 0.090143 -0.0095 0.061425 0.0925458 -0.0095 0.0665335 0.091955 -0.02645 0.067496 0.0925458 0.0095 0.0665335 0.094705 -0.0095 0.071813 0.0925458 -0.0095 0.0665335 0.0925458 0.0095 0.0665335 0.094705 0.0095 0.071813 0.094705 -0.0095 0.071813 0.09620919999999999 0.0318839 0.0792235 0.051999 0.053734 0.073112 0.051999 0.052222 0.08 0.051999 0.053734 0.08688899999999999 0.09780460000000001 0.0330589 0.0872802 0.051999 0.052222 0.08 0.051999 0.053734 0.08688899999999999 0.0974365 0.0356108 0.09132750000000001 0.09780460000000001 0.0330589 0.0872802 0.096996 0.040187 0.095039 0.0995905 0.022541 0.101 0.0974365 0.0356108 0.09132750000000001 0.0925892 0.0353962 0.07214 0.09620919999999999 0.0318839 0.0792235 0.091955 0.02645 0.067496 0.091955 0.02645 0.067496 0.094705 0.0095 0.071813 0.0925458 0.0095 0.0665335 0.0731089 -0.0916759 0.0875478 0.074183 -0.091999 0.100992 0.06565650000000001 -0.0989867 0.100992 0.059371 -0.09991899999999999 0.07831299999999999 0.054477 -0.09897 0.067497 0.068789 -0.09338200000000001 0.0793065 0.062246 -0.100546 0.08970400000000001 0.059371 -0.09991899999999999 0.07831299999999999 0.0731089 -0.0916759 0.0875478 0.068789 -0.09338200000000001 0.0793065 0.054477 -0.09897 0.067497 0.067412 -0.091832 0.0726098 0.051999 -0.09213 0.073112 0.067412 -0.091832 0.0726098 0.0683459 -0.0878439 0.0669984 0.0712415 -0.08156770000000001 0.06320149999999999 0.0683459 -0.0878439 0.0669984 0.0683628 -0.0853853 0.0638449 0.0683459 -0.0878439 0.0669984 0.0640305 -0.08794250000000001 0.0606915 0.0683628 -0.0853853 0.0638449 0.0640305 -0.08794250000000001 0.0606915 0.0712415 -0.08156770000000001 0.06320149999999999 0.0683628 -0.0853853 0.0638449 0.0732285 -0.0753737 0.0600965 0.0712415 -0.08156770000000001 0.06320149999999999 0.0674174 -0.0807109 0.0570159 0.0732285 -0.0753737 0.0600965 0.0674174 -0.0807109 0.0570159 0.07482800000000001 -0.06694509999999999 0.0564331 0.08605599999999999 0.0095 0.0546884 0.090143 -0.0095 0.061425 0.08605599999999999 -0.0095 0.0546884 0.090143 0.0095 0.061425 0.0925458 -0.0095 0.0665335 0.090143 -0.0095 0.061425 0.0925458 -0.0095 0.0665335 0.090143 0.0095 0.061425 0.0925458 0.0095 0.0665335 0.09620919999999999 0.0318839 0.0792235 0.0925892 0.0353962 0.07214 0.051999 0.053734 0.073112 0.051999 0.0566747 0.0795459 0.051999 0.0567614 0.0821611 0.051999 0.052222 0.08 0.051999 0.0567614 0.0821611 0.051999 0.0567835 0.082828 0.051999 0.052222 0.08 0.051999 0.0567835 0.082828 0.051999 0.0579673 0.0865547 0.051999 0.052222 0.08 0.051999 0.0579673 0.0865547 0.051999 0.0581648 0.08717709999999999 0.051999 0.052222 0.08 0.051999 0.0566747 0.0795459 0.051999 0.052222 0.08 0.051999 0.053734 0.073112 0.051999 0.052222 0.08 0.051999 0.0603288 0.0904718 0.051999 0.060672 0.09099409999999999 0.051999 0.064483 0.09662999999999999 0.051999 0.052222 0.08 0.051999 0.060672 0.09099409999999999 0.051999 0.0581648 0.08717709999999999 0.051999 0.0603288 0.0904718 0.051999 0.052222 0.08 0.051999 0.064483 0.09662999999999999 0.051999 0.053734 0.08688899999999999 0.051999 0.052222 0.08 0.051999 0.053734 0.08688899999999999 0.051999 0.058039 0.092728 0.0974365 0.0356108 0.09132750000000001 0.096996 0.040187 0.095039 0.0962919 0.044521 0.09890359999999999 0.0995905 0.022541 0.101 0.051999 0.058039 0.092728 0.096996 0.040187 0.095039 0.0974365 0.0356108 0.09132750000000001 0.0888383 0.0420635 0.0666032 0.0925892 0.0353962 0.07214 0.091955 0.02645 0.067496 0.091955 0.02645 0.067496 0.0925458 0.0095 0.0665335 0.090143 0.0095 0.061425 0.062246 -0.100546 0.08970400000000001 0.0731089 -0.0916759 0.0875478 0.06565650000000001 -0.0989867 0.100992 0.059371 -0.09991899999999999 0.07831299999999999 0.044273 -0.106232 0.07831299999999999 0.054477 -0.09897 0.067497 0.047508 -0.106937 0.089703 0.059371 -0.09991899999999999 0.07831299999999999 0.062246 -0.100546 0.08970400000000001 0.067412 -0.091832 0.0726098 0.054477 -0.09897 0.067497 0.0683459 -0.0878439 0.0669984 0.0683459 -0.0878439 0.0669984 0.054477 -0.09897 0.067497 0.0640305 -0.08794250000000001 0.0606915 0.0674174 -0.0807109 0.0570159 0.0712415 -0.08156770000000001 0.06320149999999999 0.0640305 -0.08794250000000001 0.0606915 0.08605599999999999 0.0095 0.0546884 0.090143 0.0095 0.061425 0.090143 -0.0095 0.061425 0.051999 0.058039 0.067272 0.051999 0.053734 0.073112 0.0925892 0.0353962 0.07214 0.051999 0.0567916 0.0776212 0.051999 0.0566323 0.07826900000000001 0.051999 0.053734 0.073112 0.051999 0.0566323 0.07826900000000001 0.051999 0.0566747 0.0795459 0.051999 0.053734 0.073112 0.051999 0.053734 0.073112 0.051999 0.058039 0.067272 0.051999 0.0563613 0.073409 0.051999 0.0567916 0.0776212 0.051999 0.053734 0.073112 0.051999 0.0563613 0.073409 0.051999 0.058039 0.092728 0.051999 0.053734 0.08688899999999999 0.051999 0.064483 0.09662999999999999 0.0962919 0.044521 0.09890359999999999 0.096996 0.040187 0.095039 0.051999 0.064483 0.09662999999999999 0.051999 0.058039 0.092728 0.051999 0.064483 0.09662999999999999 0.096996 0.040187 0.095039 0.0837318 0.0401518 0.0570936 0.0888383 0.0420635 0.0666032 0.091955 0.02645 0.067496 0.051999 0.058039 0.067272 0.0925892 0.0353962 0.07214 0.0888383 0.0420635 0.0666032 0.091955 0.02645 0.067496 0.090143 0.0095 0.061425 0.08605599999999999 0.0095 0.0546884 0.062246 -0.100546 0.08970400000000001 0.06565650000000001 -0.0989867 0.100992 0.056279 -0.104368 0.100992 0.044273 -0.106232 0.07831299999999999 0.059371 -0.09991899999999999 0.07831299999999999 0.047508 -0.106937 0.089703 0.044273 -0.106232 0.07831299999999999 0.0377245 -0.104748 0.06589349999999999 0.054477 -0.09897 0.067497 0.056279 -0.104368 0.100992 0.047508 -0.106937 0.089703 0.062246 -0.100546 0.08970400000000001 0.054477 -0.09897 0.067497 0.0586512 -0.09210119999999999 0.0601659 0.0640305 -0.08794250000000001 0.0606915 0.0640305 -0.08794250000000001 0.0606915 0.0586512 -0.09210119999999999 0.0601659 0.0674174 -0.0807109 0.0570159 0.0962919 0.044521 0.09890359999999999 0.051999 0.064483 0.09662999999999999 0.051999 0.0737915 0.098 0.08605599999999999 0.0095 0.0546884 0.0837318 0.0401518 0.0570936 0.091955 0.02645 0.067496 0.0888383 0.0420635 0.0666032 0.0837318 0.0401518 0.0570936 0.0852195 0.0497655 0.06319950000000001 0.0888383 0.0420635 0.0666032 0.051999 0.064483 0.063371 0.051999 0.058039 0.067272 0.051999 0.0737915 0.098 0.0911151 0.06285590000000001 0.09950000000000001 0.0962919 0.044521 0.09890359999999999 0.056279 -0.104368 0.100992 0.0479835 -0.107211 0.100992 0.047508 -0.106937 0.089703 0.047508 -0.106937 0.089703 0.0319765 -0.108279 0.079364 0.044273 -0.106232 0.07831299999999999 0.0377245 -0.104748 0.06589349999999999 0.0439882 -0.101818 0.0625549 0.054477 -0.09897 0.067497 0.0377245 -0.104748 0.06589349999999999 0.044273 -0.106232 0.07831299999999999 0.031999 -0.106898 0.070579 0.0439882 -0.101818 0.0625549 0.0586512 -0.09210119999999999 0.0601659 0.054477 -0.09897 0.067497 0.07482800000000001 0.06694509999999999 0.0564331 0.0852195 0.0497655 0.06319950000000001 0.0837318 0.0401518 0.0570936 0.051999 0.064483 0.063371 0.0888383 0.0420635 0.0666032 0.0852195 0.0497655 0.06319950000000001 0.0911151 0.06285590000000001 0.09950000000000001 0.051999 0.0737915 0.098 0.088891 0.06880749999999999 0.09950000000000001 0.0319861 -0.109 0.101998 0.047508 -0.106937 0.089703 0.0479835 -0.107211 0.100992 0.0397295 -0.107805 0.090681 0.047508 -0.106937 0.089703 0.0319861 -0.109 0.101998 0.0397295 -0.107805 0.090681 0.0319861 -0.109 0.101998 0.0319765 -0.108279 0.079364 0.0397295 -0.107805 0.090681 0.0319765 -0.108279 0.079364 0.047508 -0.106937 0.089703 0.0319765 -0.108279 0.079364 0.031999 -0.106898 0.070579 0.044273 -0.106232 0.07831299999999999 0.0377245 -0.104748 0.06589349999999999 0.0321408 -0.105105 0.0633421 0.0439882 -0.101818 0.0625549 0.031999 -0.106898 0.070579 0.0321408 -0.105105 0.0633421 0.0377245 -0.104748 0.06589349999999999 0.07482800000000001 0.06694509999999999 0.0564331 0.0674174 0.0807109 0.0570159 0.0732285 0.0753737 0.0600965 0.051999 0.0737915 0.062 0.051999 0.064483 0.063371 0.0852195 0.0497655 0.06319950000000001 0.082298 0.0818285 0.096766 0.051999 0.0737915 0.098 0.051999 0.082388 0.09662999999999999 0.07482800000000001 0.06694509999999999 0.0564331 0.0805409 0.06028 0.0611115 0.0852195 0.0497655 0.06319950000000001 0.0858631 0.07568 0.100202 0.088891 0.06880749999999999 0.09950000000000001 0.051999 0.0737915 0.098 0.0319861 -0.109 0.101998 0.0110499 -0.105577 0.0695487 0.0319765 -0.108279 0.079364 0.0110499 -0.105577 0.0695487 0.031999 -0.106898 0.070579 0.0319765 -0.108279 0.079364 0.0321408 -0.105105 0.0633421 0.031999 -0.106898 0.070579 0.0110499 -0.105577 0.0695487 0.0674174 0.0807109 0.0570159 0.0586512 0.09210119999999999 0.0601659 0.0640305 0.08794250000000001 0.0606915 0.0674174 0.0807109 0.0570159 0.0712415 0.08156770000000001 0.06320149999999999 0.0732285 0.0753737 0.0600965 0.0805409 0.06028 0.0611115 0.07482800000000001 0.06694509999999999 0.0564331 0.0732285 0.0753737 0.0600965 0.0852195 0.0497655 0.06319950000000001 0.0805409 0.06028 0.0611115 0.051999 0.0737915 0.062 0.0805409 0.06028 0.0611115 0.051999 0.082388 0.063371 0.051999 0.0737915 0.062 0.051999 0.082388 0.063371 0.051999 0.088228 0.067272 0.051999 0.08477369999999999 0.06648320000000001 0.051999 0.088228 0.067272 0.051999 0.0846388 0.067637 0.051999 0.08477369999999999 0.06648320000000001 0.051999 0.08788070000000001 0.0883862 0.051999 0.09213 0.08688899999999999 0.051999 0.0875249 0.09024459999999999 0.051999 0.09213 0.08688899999999999 0.051999 0.088228 0.092728 0.051999 0.0875249 0.09024459999999999 0.082298 0.0818285 0.096766 0.051999 0.082388 0.09662999999999999 0.051999 0.088228 0.092728 0.082298 0.0818285 0.096766 0.0858631 0.07568 0.100202 0.051999 0.0737915 0.098 0.00226 -0.106917 0.0816655 0.0110499 -0.105577 0.0695487 0.0319861 -0.109 0.101998 0.0439882 0.101818 0.0625549 0.054477 0.09897 0.067497 0.0586512 0.09210119999999999 0.0601659 0.054477 0.09897 0.067497 0.0640305 0.08794250000000001 0.0606915 0.0586512 0.09210119999999999 0.0601659 0.0640305 0.08794250000000001 0.0606915 0.0712415 0.08156770000000001 0.06320149999999999 0.0674174 0.0807109 0.0570159 0.0732285 0.0753737 0.0600965 0.0712415 0.08156770000000001 0.06320149999999999 0.051999 0.082388 0.063371 0.0732285 0.0753737 0.0600965 0.051999 0.082388 0.063371 0.0805409 0.06028 0.0611115 0.0712415 0.08156770000000001 0.06320149999999999 0.051999 0.088228 0.067272 0.051999 0.082388 0.063371 0.051999 0.09213 0.073112 0.051999 0.08946229999999999 0.0753813 0.051999 0.0894345 0.0752197 0.051999 0.09213 0.073112 0.051999 0.0894345 0.0752197 0.051999 0.0893881 0.07495 0.051999 0.0893881 0.07495 0.051999 0.0875537 0.0710966 0.051999 0.0892394 0.07132670000000001 0.051999 0.088228 0.067272 0.051999 0.09213 0.073112 0.051999 0.0892394 0.07132670000000001 0.051999 0.09213 0.073112 0.051999 0.0893881 0.07495 0.051999 0.0892394 0.07132670000000001 0.051999 0.09213 0.08688899999999999 0.051999 0.08788070000000001 0.0883862 0.051999 0.0880036 0.088225 0.051999 0.09213 0.08688899999999999 0.051999 0.0880036 0.088225 0.051999 0.089588 0.0842357 0.051999 0.0898876 0.0820703 0.051999 0.0935 0.08 0.051999 0.0906903 0.08419310000000001 0.051999 0.0935 0.08 0.051999 0.09213 0.08688899999999999 0.051999 0.0906903 0.08419310000000001 0.051999 0.09213 0.08688899999999999 0.051999 0.089588 0.0842357 0.051999 0.0906903 0.08419310000000001 0.051999 0.088228 0.092728 0.051999 0.09213 0.08688899999999999 0.0731089 0.0916759 0.0875478 0.0778648 0.0874693 0.09331780000000001 0.082298 0.0818285 0.096766 0.051999 0.088228 0.092728 0.082298 0.0818285 0.096766 0.08017199999999999 0.0852165 0.100992 0.0858631 0.07568 0.100202 0.056279 0.104368 0.100992 0.06565650000000001 0.0989867 0.100992 0.062246 0.100546 0.08970400000000001 0.0479835 0.107211 0.100992 0.056279 0.104368 0.100992 0.047508 0.106937 0.089703 -0.0202878 -0.102352 0.0753364 0.0110499 -0.105577 0.0695487 0.00226 -0.106917 0.0816655 -0.0408953 -0.101299 0.103098 0.00226 -0.106917 0.0816655 0.0319861 -0.109 0.101998 0.054477 0.09897 0.067497 0.0439882 0.101818 0.0625549 0.0377245 0.104748 0.06589349999999999 0.0640305 0.08794250000000001 0.0606915 0.054477 0.09897 0.067497 0.0683459 0.0878439 0.0669984 0.0683459 0.0878439 0.0669984 0.0712415 0.08156770000000001 0.06320149999999999 0.0683628 0.0853853 0.0638449 0.0712415 0.08156770000000001 0.06320149999999999 0.0640305 0.08794250000000001 0.0606915 0.0683628 0.0853853 0.0638449 0.0640305 0.08794250000000001 0.0606915 0.0683459 0.0878439 0.0669984 0.0683628 0.0853853 0.0638449 0.0712415 0.08156770000000001 0.06320149999999999 0.0683459 0.0878439 0.0669984 0.051999 0.088228 0.067272 0.051999 0.09213 0.073112 0.051999 0.088228 0.067272 0.0683459 0.0878439 0.0669984 0.051999 0.0935 0.08 0.051999 0.0898876 0.0820703 0.051999 0.09013350000000001 0.0797098 0.051999 0.0935 0.08 0.051999 0.09013350000000001 0.0797098 0.051999 0.09016100000000001 0.079446 0.051999 0.09016100000000001 0.079446 0.051999 0.08946229999999999 0.0753813 0.051999 0.0914811 0.0775911 0.051999 0.08946229999999999 0.0753813 0.051999 0.09213 0.073112 0.051999 0.0914811 0.0775911 0.051999 0.09213 0.073112 0.051999 0.0935 0.08 0.051999 0.0914811 0.0775911 0.051999 0.0935 0.08 0.051999 0.09016100000000001 0.079446 0.051999 0.0914811 0.0775911 0.051999 0.09213 0.08688899999999999 0.051999 0.0935 0.08 0.068789 0.09338200000000001 0.0793065 0.051999 0.088228 0.092728 0.0731089 0.0916759 0.0875478 0.0778648 0.0874693 0.09331780000000001 0.051999 0.09213 0.08688899999999999 0.068789 0.09338200000000001 0.0793065 0.0731089 0.0916759 0.0875478 0.0778648 0.0874693 0.09331780000000001 0.08017199999999999 0.0852165 0.100992 0.08019850000000001 0.0847348 0.0971549 0.08017199999999999 0.0852165 0.100992 0.082298 0.0818285 0.096766 0.08019850000000001 0.0847348 0.0971549 0.082298 0.0818285 0.096766 0.0778648 0.0874693 0.09331780000000001 0.08019850000000001 0.0847348 0.0971549 0.0778648 0.0874693 0.09331780000000001 0.074183 0.091999 0.100992 0.08017199999999999 0.0852165 0.100992 0.06565650000000001 0.0989867 0.100992 0.074183 0.091999 0.100992 0.0731089 0.0916759 0.0875478 0.06565650000000001 0.0989867 0.100992 0.0731089 0.0916759 0.0875478 0.062246 0.100546 0.08970400000000001 0.062246 0.100546 0.08970400000000001 0.047508 0.106937 0.089703 0.056279 0.104368 0.100992 0.047508 0.106937 0.089703 0.0319861 0.109 0.101998 0.0479835 0.107211 0.100992 -0.0346432 -0.09947110000000001 0.08280899999999999 -0.0202878 -0.102352 0.0753364 0.00226 -0.106917 0.0816655 -0.0346432 -0.09947110000000001 0.08280899999999999 0.00226 -0.106917 0.0816655 -0.0408953 -0.101299 0.103098 0.0321408 0.105105 0.0633421 0.0377245 0.104748 0.06589349999999999 0.0439882 0.101818 0.0625549 0.054477 0.09897 0.067497 0.0377245 0.104748 0.06589349999999999 0.044273 0.106232 0.07831299999999999 0.067412 0.091832 0.0726098 0.0683459 0.0878439 0.0669984 0.054477 0.09897 0.067497 0.051999 0.09213 0.073112 0.0683459 0.0878439 0.0669984 0.067412 0.091832 0.0726098 0.051999 0.0935 0.08 0.051999 0.09213 0.073112 0.067412 0.091832 0.0726098 0.051999 0.0935 0.08 0.067412 0.091832 0.0726098 0.068789 0.09338200000000001 0.0793065 0.07568800000000001 0.0897714 0.0942699 0.0731089 0.0916759 0.0875478 0.074183 0.091999 0.100992 0.07568800000000001 0.0897714 0.0942699 0.074183 0.091999 0.100992 0.0778648 0.0874693 0.09331780000000001 0.07568800000000001 0.0897714 0.0942699 0.0778648 0.0874693 0.09331780000000001 0.0731089 0.0916759 0.0875478 0.0731089 0.0916759 0.0875478 0.068789 0.09338200000000001 0.0793065 0.059371 0.09991899999999999 0.07831299999999999 0.062246 0.100546 0.08970400000000001 0.0731089 0.0916759 0.0875478 0.059371 0.09991899999999999 0.07831299999999999 0.059371 0.09991899999999999 0.07831299999999999 0.047508 0.106937 0.089703 0.062246 0.100546 0.08970400000000001 0.0397295 0.107805 0.090681 0.0319861 0.109 0.101998 0.047508 0.106937 0.089703 0.0397295 0.107805 0.090681 0.047508 0.106937 0.089703 0.0319765 0.108279 0.079364 0.0397295 0.107805 0.090681 0.0319765 0.108279 0.079364 0.0319861 0.109 0.101998 -0.0346432 -0.09947110000000001 0.08280899999999999 -0.0330929 -0.100183 0.07866239999999999 -0.0202878 -0.102352 0.0753364 0.0321408 0.105105 0.0633421 0.031999 0.106898 0.070579 0.0377245 0.104748 0.06589349999999999 0.0110499 0.105577 0.0695487 0.031999 0.106898 0.070579 0.0321408 0.105105 0.0633421 0.031999 0.106898 0.070579 0.044273 0.106232 0.07831299999999999 0.0377245 0.104748 0.06589349999999999 0.059371 0.09991899999999999 0.07831299999999999 0.054477 0.09897 0.067497 0.044273 0.106232 0.07831299999999999 0.067412 0.091832 0.0726098 0.054477 0.09897 0.067497 0.068789 0.09338200000000001 0.0793065 0.068789 0.09338200000000001 0.0793065 0.054477 0.09897 0.067497 0.059371 0.09991899999999999 0.07831299999999999 0.059371 0.09991899999999999 0.07831299999999999 0.044273 0.106232 0.07831299999999999 0.047508 0.106937 0.089703 0.044273 0.106232 0.07831299999999999 0.0319765 0.108279 0.079364 0.047508 0.106937 0.089703 0.0319861 0.109 0.101998 0.0319765 0.108279 0.079364 0.0110499 0.105577 0.0695487 0.0319765 0.108279 0.079364 0.031999 0.106898 0.070579 0.0110499 0.105577 0.0695487 0.031999 0.106898 0.070579 0.0319765 0.108279 0.079364 0.044273 0.106232 0.07831299999999999 0.00226 0.106917 0.0816655 0.0319861 0.109 0.101998 0.0110499 0.105577 0.0695487 0.0319861 0.109 0.101998 0.00226 0.106917 0.0816655 -0.0408953 0.101299 0.103098 -0.0202878 0.102352 0.0753364 0.00226 0.106917 0.0816655 0.0110499 0.105577 0.0695487 0.00226 0.106917 0.0816655 -0.0346432 0.09947110000000001 0.08280899999999999 -0.0408953 0.101299 0.103098 0.00226 0.106917 0.0816655 -0.0202878 0.102352 0.0753364 -0.0346432 0.09947110000000001 0.08280899999999999 -0.0346432 0.09947110000000001 0.08280899999999999 -0.0202878 0.102352 0.0753364 -0.0330929 0.100183 0.07866239999999999 0.051999 0.0627234 0.09278 0.051999 0.064483 0.09662999999999999 0.051999 0.060672 0.09099409999999999 0.051999 0.06385399999999999 0.0937644 0.051999 0.064483 0.09662999999999999 0.051999 0.06367879999999999 0.0936118 0.051999 0.064483 0.09662999999999999 0.051999 0.0627234 0.09278 0.051999 0.06367879999999999 0.0936118 0.051999 0.058039 0.067272 0.051999 0.0589886 0.07159840000000001 0.051999 0.0563613 0.073409 0.051999 0.0589886 0.07159840000000001 0.051999 0.0580428 0.0732703 0.051999 0.0563613 0.073409 0.051999 0.0580428 0.0732703 0.051999 0.0577216 0.073838 0.051999 0.0563613 0.073409 0.051999 0.0577216 0.073838 0.051999 0.0567916 0.0776212 0.051999 0.0563613 0.073409 0.051999 0.064483 0.0941685 0.051999 0.064483 0.09662999999999999 0.051999 0.0641201 0.093996 0.051999 0.0641201 0.093996 0.051999 0.064483 0.09662999999999999 0.051999 0.06385399999999999 0.0937644 0.051999 0.0604126 0.0694239 0.051999 0.0599697 0.0698641 0.051999 0.058039 0.067272 0.051999 0.0599697 0.0698641 0.051999 0.0589886 0.07159840000000001 0.051999 0.058039 0.067272 0.051999 0.058039 0.067272 0.051999 0.064483 0.063371 0.051999 0.061261 0.06748469999999999 0.051999 0.0632113 0.0666421 0.051999 0.0604126 0.0694239 0.051999 0.061261 0.06748469999999999 0.051999 0.064483 0.063371 0.051999 0.0632113 0.0666421 0.051999 0.061261 0.06748469999999999 0.051999 0.0604126 0.0694239 0.051999 0.058039 0.067272 0.051999 0.061261 0.06748469999999999 0.051999 0.06506969999999999 0.0944473 0.051999 0.064483 0.09662999999999999 0.051999 0.064483 0.0941685 0.051999 0.082388 0.09662999999999999 0.051999 0.0737915 0.098 0.051999 0.0738485 0.09662999999999999 0.051999 0.07228900000000001 0.0966579 0.051999 0.0737915 0.098 0.051999 0.0721277 0.09662999999999999 0.051999 0.0721277 0.09662999999999999 0.051999 0.0737915 0.098 0.051999 0.064483 0.09662999999999999 0.051999 0.07228900000000001 0.0966579 0.051999 0.07276390000000001 0.09674000000000001 0.051999 0.0734355 0.097315 0.051999 0.07276390000000001 0.09674000000000001 0.051999 0.0738485 0.09662999999999999 0.051999 0.0734355 0.097315 0.051999 0.0738485 0.09662999999999999 0.051999 0.0737915 0.098 0.051999 0.0734355 0.097315 0.051999 0.0737915 0.098 0.051999 0.07228900000000001 0.0966579 0.051999 0.0734355 0.097315 0.051999 0.0677681 0.0957298 0.051999 0.0682526 0.09596 0.051999 0.06644269999999999 0.096106 0.051999 0.06644269999999999 0.096106 0.051999 0.0684025 0.0959859 0.051999 0.0682526 0.09596 0.051999 0.0684025 0.0959859 0.051999 0.064483 0.09662999999999999 0.051999 0.06644269999999999 0.096106 0.051999 0.064483 0.09662999999999999 0.051999 0.0674573 0.0955821 0.051999 0.06644269999999999 0.096106 0.051999 0.0674573 0.0955821 0.051999 0.0677681 0.0957298 0.051999 0.06644269999999999 0.096106 0.051999 0.0668309 0.09528440000000001 0.051999 0.0674573 0.0955821 0.051999 0.064483 0.09662999999999999 0.051999 0.0663395 0.0950508 0.051999 0.0668309 0.09528440000000001 0.051999 0.064483 0.09662999999999999 0.051999 0.0663395 0.0950508 0.051999 0.064483 0.09662999999999999 0.051999 0.0659211 0.09485200000000001 0.051999 0.0659211 0.09485200000000001 0.051999 0.064483 0.09662999999999999 0.051999 0.0655382 0.09467 0.051999 0.0655382 0.09467 0.051999 0.064483 0.09662999999999999 0.051999 0.06506969999999999 0.0944473 0.051999 0.088228 0.092728 0.051999 0.082388 0.09662999999999999 0.051999 0.0829199 0.0936003 0.051999 0.0829199 0.0936003 0.051999 0.082388 0.09662999999999999 0.051999 0.08158169999999999 0.094609 0.051999 0.08158169999999999 0.094609 0.051999 0.082388 0.09662999999999999 0.051999 0.08123379999999999 0.0947453 0.051999 0.08123379999999999 0.0947453 0.051999 0.082388 0.09662999999999999 0.051999 0.0773195 0.096278 0.051999 0.082388 0.09662999999999999 0.051999 0.0738485 0.09662999999999999 0.051999 0.0768953 0.096321 0.051999 0.0773195 0.096278 0.051999 0.082388 0.09662999999999999 0.051999 0.0768953 0.096321 0.051999 0.0684025 0.0959859 0.051999 0.0721277 0.09662999999999999 0.051999 0.064483 0.09662999999999999 0.051999 0.088228 0.067272 0.051999 0.08634890000000001 0.0695953 0.051999 0.0846388 0.067637 0.051999 0.0846388 0.067637 0.051999 0.08442040000000001 0.067387 0.051999 0.08477369999999999 0.06648320000000001 0.051999 0.08442040000000001 0.067387 0.051999 0.0813194 0.06535589999999999 0.051999 0.08477369999999999 0.06648320000000001 0.051999 0.08523260000000001 0.09185699999999999 0.051999 0.088228 0.092728 0.051999 0.0849704 0.0920545 0.051999 0.0849704 0.0920545 0.051999 0.088228 0.092728 0.051999 0.0829199 0.0936003 0.051999 0.08523260000000001 0.09185699999999999 0.051999 0.08782570000000001 0.0884583 0.051999 0.0875249 0.09024459999999999 0.051999 0.0875249 0.09024459999999999 0.051999 0.08788070000000001 0.0883862 0.051999 0.08782570000000001 0.0884583 0.051999 0.088228 0.092728 0.051999 0.08523260000000001 0.09185699999999999 0.051999 0.0875249 0.09024459999999999 0.051999 0.0874263 0.070829 0.051999 0.08634890000000001 0.0695953 0.051999 0.088228 0.067272 0.051999 0.0875537 0.0710966 0.051999 0.0874263 0.070829 0.051999 0.0892394 0.07132670000000001 0.051999 0.0874263 0.070829 0.051999 0.088228 0.067272 0.051999 0.0892394 0.07132670000000001 0.051999 0.089588 0.0842357 0.051999 0.0896884 0.0839831 0.051999 0.0906903 0.08419310000000001 0.051999 0.0896884 0.0839831 0.051999 0.0898876 0.0820703 0.051999 0.0906903 0.08419310000000001 0.051999 0.064483 0.06593160000000001 0.051999 0.063722 0.0663567 0.051999 0.064483 0.063371 0.051999 0.063722 0.0663567 0.051999 0.0632113 0.0666421 0.051999 0.064483 0.063371 0.051999 0.0737915 0.062 0.051999 0.0734157 0.06339789999999999 0.051999 0.07213890000000001 0.06335300000000001 0.051999 0.0737915 0.062 0.051999 0.07213890000000001 0.06335300000000001 0.051999 0.07165539999999999 0.063336 0.051999 0.07165539999999999 0.063336 0.051999 0.0677277 0.06428490000000001 0.051999 0.064483 0.063371 0.051999 0.0677277 0.06428490000000001 0.051999 0.0672055 0.064411 0.051999 0.064483 0.063371 0.051999 0.0672055 0.064411 0.051999 0.064483 0.06593160000000001 0.051999 0.064483 0.063371 0.051999 0.0737915 0.062 0.051999 0.07165539999999999 0.063336 0.051999 0.064483 0.063371 0.051999 0.0813194 0.06535589999999999 0.051999 0.08091 0.0650877 0.051999 0.082388 0.063371 0.051999 0.082388 0.063371 0.051999 0.08091 0.0650877 0.051999 0.0805944 0.06488099999999999 0.051999 0.0762312 0.063497 0.051999 0.0734157 0.06339789999999999 0.051999 0.0737915 0.062 0.051999 0.0805944 0.06488099999999999 0.051999 0.07664029999999999 0.0636268 0.051999 0.0779019 0.0636779 0.051999 0.0737915 0.062 0.051999 0.082388 0.063371 0.051999 0.0779019 0.0636779 0.051999 0.082388 0.063371 0.051999 0.0805944 0.06488099999999999 0.051999 0.0779019 0.0636779 0.051999 0.0762312 0.063497 0.051999 0.0737915 0.062 0.051999 0.0779019 0.0636779 0.051999 0.0813194 0.06535589999999999 0.051999 0.082388 0.063371 0.051999 0.08477369999999999 0.06648320000000001 0.051999 -0.058039 0.092728 0.051999 -0.064483 0.09662999999999999 0.051999 -0.053734 0.08688899999999999 0.051999 -0.0592306 0.09046800000000001 0.051999 -0.053734 0.08688899999999999 0.051999 -0.0596821 0.0908948 0.051999 -0.053734 0.08688899999999999 0.051999 -0.0592306 0.09046800000000001 0.051999 -0.0572172 0.0871097 0.051999 -0.053734 0.08688899999999999 0.051999 -0.0572172 0.0871097 0.051999 -0.0568827 0.086552 0.051999 -0.053734 0.08688899999999999 0.051999 -0.0568827 0.086552 0.051999 -0.0567828 0.086186 0.051999 -0.053734 0.08688899999999999 0.051999 -0.0567828 0.086186 0.051999 -0.052222 0.08 0.051999 -0.064483 0.09662999999999999 0.051999 -0.0615717 0.09268129999999999 0.051999 -0.0596821 0.0908948 0.051999 -0.053734 0.08688899999999999 0.051999 -0.064483 0.09662999999999999 0.051999 -0.0596821 0.0908948 0.051999 -0.052222 0.08 0.051999 -0.0567828 0.086186 0.051999 -0.0558569 0.0827928 0.051999 -0.052222 0.08 0.051999 -0.0558569 0.0827928 0.051999 -0.0556817 0.08215 0.051999 -0.052222 0.08 0.051999 -0.0557179 0.077588 0.051999 -0.0557419 0.0775052 0.051999 -0.052222 0.08 0.051999 -0.0557419 0.0775052 0.051999 -0.053734 0.073112 0.051999 -0.0556817 0.08215 0.051999 -0.0557126 0.07825600000000001 0.051999 -0.0545024 0.079649 0.051999 -0.0557126 0.07825600000000001 0.051999 -0.0557179 0.077588 0.051999 -0.0545024 0.079649 0.051999 -0.052222 0.08 0.051999 -0.0556817 0.08215 0.051999 -0.0545024 0.079649 0.051999 -0.0557179 0.077588 0.051999 -0.052222 0.08 0.051999 -0.0545024 0.079649 0.051999 -0.06255189999999999 0.093608 0.051999 -0.064483 0.09662999999999999 0.051999 -0.063066 0.0938785 0.051999 -0.063066 0.0938785 0.051999 -0.064483 0.09662999999999999 0.051999 -0.06327579999999999 0.0939888 0.051999 -0.064483 0.09662999999999999 0.051999 -0.06255189999999999 0.093608 0.051999 -0.0615717 0.09268129999999999 0.051999 -0.053734 0.073112 0.051999 -0.0557419 0.0775052 0.051999 -0.0568054 0.07383489999999999 0.051999 -0.0587271 0.0704067 0.051999 -0.058039 0.067272 0.051999 -0.0562305 0.0723886 0.051999 -0.058039 0.067272 0.051999 -0.053734 0.073112 0.051999 -0.0562305 0.0723886 0.051999 -0.0568054 0.07383489999999999 0.051999 -0.0569876 0.07320599999999999 0.051999 -0.0562305 0.0723886 0.051999 -0.0569876 0.07320599999999999 0.051999 -0.0587271 0.0704067 0.051999 -0.0562305 0.0723886 0.051999 -0.053734 0.073112 0.051999 -0.0568054 0.07383489999999999 0.051999 -0.0562305 0.0723886 0.051999 -0.06327579999999999 0.0939888 0.051999 -0.064483 0.09662999999999999 0.051999 -0.06398520000000001 0.0943619 0.051999 -0.0715546 0.0966722 0.051999 -0.0710766 0.096701 0.051999 -0.0737915 0.098 0.051999 -0.0710766 0.096701 0.051999 -0.0707467 0.09662999999999999 0.051999 -0.0737915 0.098 0.051999 -0.0737915 0.098 0.051999 -0.0707467 0.09662999999999999 0.051999 -0.064483 0.09662999999999999 0.051999 -0.0737915 0.098 0.051999 -0.082388 0.09662999999999999 0.051999 -0.0734355 0.097315 0.051999 -0.082388 0.09662999999999999 0.051999 -0.0722568 0.09662999999999999 0.051999 -0.0734355 0.097315 0.051999 -0.0722568 0.09662999999999999 0.051999 -0.0715546 0.0966722 0.051999 -0.0734355 0.097315 0.051999 -0.0715546 0.0966722 0.051999 -0.0737915 0.098 0.051999 -0.0734355 0.097315 0.051999 -0.0587271 0.0704067 0.051999 -0.0590664 0.06986050000000001 0.051999 -0.058039 0.067272 0.051999 -0.0590664 0.06986050000000001 0.051999 -0.0593979 0.069327 0.051999 -0.058039 0.067272 0.051999 -0.06276859999999999 0.06623999999999999 0.051999 -0.064483 0.06537179999999999 0.051999 -0.064483 0.063371 0.051999 -0.064483 0.063371 0.051999 -0.058039 0.067272 0.051999 -0.061261 0.0668888 0.051999 -0.0593979 0.069327 0.051999 -0.062334 0.0666379 0.051999 -0.061261 0.0668888 0.051999 -0.062334 0.0666379 0.051999 -0.06276859999999999 0.06623999999999999 0.051999 -0.061261 0.0668888 0.051999 -0.058039 0.067272 0.051999 -0.0593979 0.069327 0.051999 -0.061261 0.0668888 0.051999 -0.06276859999999999 0.06623999999999999 0.051999 -0.064483 0.063371 0.051999 -0.061261 0.0668888 0.051999 -0.06660149999999999 0.095738 0.051999 -0.0663084 0.0955838 0.051999 -0.06567050000000001 0.0961069 0.051999 -0.0663084 0.0955838 0.051999 -0.064483 0.09662999999999999 0.051999 -0.06567050000000001 0.0961069 0.051999 -0.064483 0.09662999999999999 0.051999 -0.066858 0.0957932 0.051999 -0.06567050000000001 0.0961069 0.051999 -0.066858 0.0957932 0.051999 -0.06660149999999999 0.095738 0.051999 -0.06567050000000001 0.0961069 0.051999 -0.0659404 0.0953903 0.051999 -0.064483 0.09662999999999999 0.051999 -0.0663084 0.0955838 0.051999 -0.0656214 0.0952225 0.051999 -0.064483 0.09662999999999999 0.051999 -0.0659404 0.0953903 0.051999 -0.0653247 0.0950665 0.051999 -0.064483 0.09662999999999999 0.051999 -0.0656214 0.0952225 0.051999 -0.0649555 0.09487230000000001 0.051999 -0.064483 0.09662999999999999 0.051999 -0.0653247 0.0950665 0.051999 -0.064483 0.09462379999999999 0.051999 -0.064483 0.09662999999999999 0.051999 -0.0649555 0.09487230000000001 0.051999 -0.06398520000000001 0.0943619 0.051999 -0.064483 0.09662999999999999 0.051999 -0.064483 0.09462379999999999 0.051999 -0.0707467 0.09662999999999999 0.051999 -0.0680346 0.0960464 0.051999 -0.064483 0.09662999999999999 0.051999 -0.0802809 0.0947199 0.051999 -0.0799742 0.094932 0.051999 -0.082388 0.09662999999999999 0.051999 -0.0799742 0.094932 0.051999 -0.0760484 0.0962875 0.051999 -0.082388 0.09662999999999999 0.051999 -0.0760484 0.0962875 0.051999 -0.0756474 0.096426 0.051999 -0.082388 0.09662999999999999 0.051999 -0.0802809 0.0947199 0.051999 -0.082388 0.09662999999999999 0.051999 -0.08158219999999999 0.0938201 0.051999 -0.08158219999999999 0.0938201 0.051999 -0.082388 0.09662999999999999 0.051999 -0.088228 0.092728 0.051999 -0.082388 0.09662999999999999 0.051999 -0.0756474 0.096426 0.051999 -0.0722568 0.09662999999999999 0.051999 -0.0680346 0.0960464 0.051999 -0.067122 0.09585 0.051999 -0.06625880000000001 0.09621159999999999 0.051999 -0.067122 0.09585 0.051999 -0.066858 0.0957932 0.051999 -0.06625880000000001 0.09621159999999999 0.051999 -0.066858 0.0957932 0.051999 -0.064483 0.09662999999999999 0.051999 -0.06625880000000001 0.09621159999999999 0.051999 -0.064483 0.09662999999999999 0.051999 -0.0680346 0.0960464 0.051999 -0.06625880000000001 0.09621159999999999 0.051999 -0.0839454 0.09207849999999999 0.051999 -0.0837358 0.092331 0.051999 -0.088228 0.092728 0.051999 -0.0837358 0.092331 0.051999 -0.08158219999999999 0.0938201 0.051999 -0.088228 0.092728 0.051999 -0.0866497 0.08881989999999999 0.051999 -0.0839454 0.09207849999999999 0.051999 -0.08685610000000001 0.0903545 0.051999 -0.0839454 0.09207849999999999 0.051999 -0.088228 0.092728 0.051999 -0.08685610000000001 0.0903545 0.051999 -0.08021 0.065189 0.051999 -0.08107590000000001 0.0658083 0.051999 -0.082388 0.063371 0.051999 -0.08879579999999999 0.08269609999999999 0.051999 -0.0885504 0.0843766 0.051999 -0.0900748 0.08441 0.051999 -0.0885504 0.0843766 0.051999 -0.0885111 0.084646 0.051999 -0.0900748 0.08441 0.051999 -0.0858391 0.0702256 0.051999 -0.088228 0.067272 0.051999 -0.0846519 0.0667983 0.051999 -0.088228 0.067272 0.051999 -0.082388 0.063371 0.051999 -0.0846519 0.0667983 0.051999 -0.082388 0.063371 0.051999 -0.08107590000000001 0.0658083 0.051999 -0.0846519 0.0667983 0.051999 -0.08107590000000001 0.0658083 0.051999 -0.08365930000000001 0.0676559 0.051999 -0.0846519 0.0667983 0.051999 -0.08365930000000001 0.0676559 0.051999 -0.0839293 0.06784900000000001 0.051999 -0.0846519 0.0667983 0.051999 -0.0839293 0.06784900000000001 0.051999 -0.0858391 0.0702256 0.051999 -0.0846519 0.0667983 0.051999 -0.0858391 0.0702256 0.051999 -0.0866055 0.0711792 0.051999 -0.088228 0.067272 0.051999 -0.0866055 0.0711792 0.051999 -0.08679099999999999 0.07141 0.051999 -0.0889846 0.0716749 0.051999 -0.08679099999999999 0.07141 0.051999 -0.08847530000000001 0.0753567 0.051999 -0.0889846 0.0716749 0.051999 -0.088228 0.067272 0.051999 -0.0866055 0.0711792 0.051999 -0.0889846 0.0716749 0.051999 -0.064483 0.063371 0.051999 -0.064483 0.06537179999999999 0.051999 -0.0663678 0.0644175 0.051999 -0.064483 0.063371 0.051999 -0.0663678 0.0644175 0.051999 -0.06685049999999999 0.06417299999999999 0.051999 -0.064483 0.063371 0.051999 -0.06685049999999999 0.06417299999999999 0.051999 -0.07086389999999999 0.063375 0.051999 -0.07086389999999999 0.063375 0.051999 -0.07134160000000001 0.06328 0.051999 -0.0737915 0.062 0.051999 -0.07134160000000001 0.06328 0.051999 -0.0734052 0.0634373 0.051999 -0.0737915 0.062 0.051999 -0.07086389999999999 0.063375 0.051999 -0.0737915 0.062 0.051999 -0.064483 0.063371 0.051999 -0.0737915 0.062 0.051999 -0.0734052 0.0634373 0.051999 -0.07547710000000001 0.0635952 0.051999 -0.0737915 0.062 0.051999 -0.07547710000000001 0.0635952 0.051999 -0.0759073 0.063628 0.051999 -0.07985440000000001 0.06506000000000001 0.051999 -0.08021 0.065189 0.051999 -0.082388 0.063371 0.051999 -0.082388 0.063371 0.051999 -0.0737915 0.062 0.051999 -0.0778966 0.06390410000000001 0.051999 -0.0759073 0.063628 0.051999 -0.07985440000000001 0.06506000000000001 0.051999 -0.0778966 0.06390410000000001 0.051999 -0.07985440000000001 0.06506000000000001 0.051999 -0.082388 0.063371 0.051999 -0.0778966 0.06390410000000001 0.051999 -0.0737915 0.062 0.051999 -0.0759073 0.063628 0.051999 -0.0778966 0.06390410000000001 0.0663265 -0.0605254 0.09287719999999999 0.051999 -0.0596821 0.0908948 0.051999 -0.0615717 0.09268129999999999 0.0663265 -0.0605254 0.09287719999999999 0.080654 -0.060045 0.093608 0.051999 -0.0596821 0.0908948 0.0663265 -0.0605254 0.09287719999999999 0.051999 -0.06255189999999999 0.093608 0.080654 -0.060045 0.093608 0.0663265 -0.0605254 0.09287719999999999 0.051999 -0.0615717 0.09268129999999999 0.051999 -0.06255189999999999 0.093608 0.0663265 -0.0589826 0.0914186 0.051999 -0.0592306 0.09046800000000001 0.051999 -0.0596821 0.0908948 0.0663265 -0.0589826 0.0914186 0.08036600000000001 -0.056749 0.09046800000000001 0.051999 -0.0592306 0.09046800000000001 0.0663265 -0.0589826 0.0914186 0.080654 -0.060045 0.093608 0.08036600000000001 -0.056749 0.09046800000000001 0.0663265 -0.0589826 0.0914186 0.051999 -0.0596821 0.0908948 0.080654 -0.060045 0.093608 0.08036600000000001 -0.056749 0.09046800000000001 0.051999 -0.0572172 0.0871097 0.051999 -0.0592306 0.09046800000000001 0.051999 -0.0568827 0.086552 0.051999 -0.0572172 0.0871097 0.080162 -0.054418 0.086552 0.051999 -0.0572172 0.0871097 0.08036600000000001 -0.056749 0.09046800000000001 0.080162 -0.054418 0.086552 0.051999 -0.0567828 0.086186 0.051999 -0.0568827 0.086552 0.080162 -0.054418 0.086552 0.051999 -0.0558569 0.0827928 0.051999 -0.0567828 0.086186 0.080162 -0.054418 0.086552 0.051999 -0.06255189999999999 0.093608 0.051999 -0.063066 0.0938785 0.06650250000000001 -0.0623257 0.0941565 0.051999 -0.063066 0.0938785 0.08100599999999999 -0.06406299999999999 0.095738 0.06650250000000001 -0.0623257 0.0941565 0.08100599999999999 -0.06406299999999999 0.095738 0.080654 -0.060045 0.093608 0.06650250000000001 -0.0623257 0.0941565 0.080654 -0.060045 0.093608 0.051999 -0.06255189999999999 0.093608 0.06650250000000001 -0.0623257 0.0941565 0.051999 -0.0556817 0.08215 0.051999 -0.0558569 0.0827928 0.080058 -0.053227 0.08215 0.051999 -0.0558569 0.0827928 0.080162 -0.054418 0.086552 0.080058 -0.053227 0.08215 0.051999 -0.0556817 0.08215 0.080058 -0.053227 0.08215 0.051999 -0.0557126 0.07825600000000001 0.080058 -0.053227 0.08215 0.08006099999999999 -0.053263 0.077588 0.051999 -0.0557126 0.07825600000000001 0.051999 -0.0557126 0.07825600000000001 0.08006099999999999 -0.053263 0.077588 0.051999 -0.0557179 0.077588 0.051999 -0.0557419 0.0775052 0.051999 -0.0557179 0.077588 0.08006099999999999 -0.053263 0.077588 0.051999 -0.0568054 0.07383489999999999 0.051999 -0.0557419 0.0775052 0.08006099999999999 -0.053263 0.077588 0.06650250000000001 -0.0645587 0.0953312 0.051999 -0.063066 0.0938785 0.051999 -0.06327579999999999 0.0939888 0.06650250000000001 -0.0645587 0.0953312 0.08100599999999999 -0.06406299999999999 0.095738 0.051999 -0.063066 0.0938785 0.06650250000000001 -0.0645587 0.0953312 0.051999 -0.06660149999999999 0.095738 0.08100599999999999 -0.06406299999999999 0.095738 0.06650250000000001 -0.0645587 0.0953312 0.051999 -0.0663084 0.0955838 0.051999 -0.06660149999999999 0.095738 0.06650250000000001 -0.0645587 0.0953312 0.051999 -0.0659404 0.0953903 0.051999 -0.0663084 0.0955838 0.06650250000000001 -0.0645587 0.0953312 0.051999 -0.0656214 0.0952225 0.051999 -0.0659404 0.0953903 0.06650250000000001 -0.0645587 0.0953312 0.051999 -0.0653247 0.0950665 0.051999 -0.0656214 0.0952225 0.06650250000000001 -0.0645587 0.0953312 0.051999 -0.0649555 0.09487230000000001 0.051999 -0.0653247 0.0950665 0.06650250000000001 -0.0645587 0.0953312 0.051999 -0.064483 0.09462379999999999 0.051999 -0.0649555 0.09487230000000001 0.06650250000000001 -0.0645587 0.0953312 0.051999 -0.06398520000000001 0.0943619 0.051999 -0.064483 0.09462379999999999 0.06650250000000001 -0.0645587 0.0953312 0.051999 -0.06327579999999999 0.0939888 0.051999 -0.06398520000000001 0.0943619 0.051999 -0.0569876 0.07320599999999999 0.051999 -0.0568054 0.07383489999999999 0.08017100000000001 -0.054523 0.07320599999999999 0.051999 -0.0568054 0.07383489999999999 0.08006099999999999 -0.053263 0.077588 0.08017100000000001 -0.054523 0.07320599999999999 0.051999 -0.0587271 0.0704067 0.051999 -0.0569876 0.07320599999999999 0.08017100000000001 -0.054523 0.07320599999999999 0.051999 -0.0590664 0.06986050000000001 0.051999 -0.0587271 0.0704067 0.08017100000000001 -0.054523 0.07320599999999999 0.051999 -0.066858 0.0957932 0.051999 -0.067122 0.09585 0.06669650000000001 -0.0663401 0.0959585 0.051999 -0.067122 0.09585 0.08139399999999999 -0.068505 0.096701 0.06669650000000001 -0.0663401 0.0959585 0.08139399999999999 -0.068505 0.096701 0.08100599999999999 -0.06406299999999999 0.095738 0.06669650000000001 -0.0663401 0.0959585 0.08100599999999999 -0.06406299999999999 0.095738 0.051999 -0.06660149999999999 0.095738 0.06669650000000001 -0.0663401 0.0959585 0.051999 -0.06660149999999999 0.095738 0.051999 -0.066858 0.0957932 0.06669650000000001 -0.0663401 0.0959585 0.051999 -0.0710766 0.096701 0.051999 -0.0715546 0.0966722 0.066895 -0.0707776 0.09664059999999999 0.051999 -0.0715546 0.0966722 0.081791 -0.07304099999999999 0.096426 0.066895 -0.0707776 0.09664059999999999 0.081791 -0.07304099999999999 0.096426 0.08139399999999999 -0.068505 0.096701 0.066895 -0.0707776 0.09664059999999999 0.08139399999999999 -0.068505 0.096701 0.051999 -0.0710766 0.096701 0.066895 -0.0707776 0.09664059999999999 0.051999 -0.0707467 0.09662999999999999 0.051999 -0.0710766 0.096701 0.06669650000000001 -0.0690424 0.09654 0.051999 -0.0710766 0.096701 0.08139399999999999 -0.068505 0.096701 0.06669650000000001 -0.0690424 0.09654 0.08139399999999999 -0.068505 0.096701 0.051999 -0.067122 0.09585 0.06669650000000001 -0.0690424 0.09654 0.051999 -0.067122 0.09585 0.051999 -0.0680346 0.0960464 0.06669650000000001 -0.0690424 0.09654 0.051999 -0.0680346 0.0960464 0.051999 -0.0707467 0.09662999999999999 0.06669650000000001 -0.0690424 0.09654 0.081791 -0.07304099999999999 0.096426 0.051999 -0.0715546 0.0966722 0.051999 -0.0722568 0.09662999999999999 0.081791 -0.07304099999999999 0.096426 0.051999 -0.0722568 0.09662999999999999 0.051999 -0.0756474 0.096426 0.051999 -0.0593979 0.069327 0.051999 -0.0590664 0.06986050000000001 0.08037999999999999 -0.056915 0.069327 0.051999 -0.0590664 0.06986050000000001 0.08017100000000001 -0.054523 0.07320599999999999 0.08037999999999999 -0.056915 0.069327 0.08037999999999999 -0.056915 0.069327 0.051999 -0.062334 0.0666379 0.051999 -0.0593979 0.069327 0.08037999999999999 -0.056915 0.069327 0.08067299999999999 -0.06026 0.06623999999999999 0.051999 -0.062334 0.0666379 0.08067299999999999 -0.06026 0.06623999999999999 0.051999 -0.06276859999999999 0.06623999999999999 0.051999 -0.062334 0.0666379 0.08067299999999999 -0.06026 0.06623999999999999 0.051999 -0.0663678 0.0644175 0.051999 -0.064483 0.06537179999999999 0.08067299999999999 -0.06026 0.06623999999999999 0.051999 -0.064483 0.06537179999999999 0.051999 -0.06276859999999999 0.06623999999999999 0.067246 -0.0796284 0.09424879999999999 0.051999 -0.0799742 0.094932 0.051999 -0.0802809 0.0947199 0.067246 -0.0796284 0.09424879999999999 0.082167 -0.077335 0.094932 0.051999 -0.0799742 0.094932 0.067246 -0.0796284 0.09424879999999999 0.082493 -0.081068 0.092331 0.082167 -0.077335 0.094932 0.067246 -0.0796284 0.09424879999999999 0.051999 -0.0802809 0.0947199 0.082493 -0.081068 0.092331 0.082167 -0.077335 0.094932 0.051999 -0.0760484 0.0962875 0.051999 -0.0799742 0.094932 0.051999 -0.0756474 0.096426 0.051999 -0.0760484 0.0962875 0.067083 -0.0753268 0.096081 0.051999 -0.0760484 0.0962875 0.082167 -0.077335 0.094932 0.067083 -0.0753268 0.096081 0.082167 -0.077335 0.094932 0.081791 -0.07304099999999999 0.096426 0.067083 -0.0753268 0.096081 0.081791 -0.07304099999999999 0.096426 0.051999 -0.0756474 0.096426 0.067083 -0.0753268 0.096081 0.051999 -0.0802809 0.0947199 0.051999 -0.08158219999999999 0.0938201 0.067246 -0.08157689999999999 0.0929015 0.051999 -0.08158219999999999 0.0938201 0.051999 -0.0837358 0.092331 0.067246 -0.08157689999999999 0.0929015 0.051999 -0.0837358 0.092331 0.082493 -0.081068 0.092331 0.067246 -0.08157689999999999 0.0929015 0.082493 -0.081068 0.092331 0.051999 -0.0802809 0.0947199 0.067246 -0.08157689999999999 0.0929015 0.08067299999999999 -0.06026 0.06623999999999999 0.081028 -0.06431099999999999 0.06417299999999999 0.051999 -0.0663678 0.0644175 0.081028 -0.06431099999999999 0.06417299999999999 0.051999 -0.06685049999999999 0.06417299999999999 0.051999 -0.0663678 0.0644175 0.081028 -0.06431099999999999 0.06417299999999999 0.051999 -0.07086389999999999 0.063375 0.051999 -0.06685049999999999 0.06417299999999999 0.081028 -0.06431099999999999 0.06417299999999999 0.081417 -0.068768 0.06328 0.051999 -0.07086389999999999 0.063375 0.081417 -0.068768 0.06328 0.051999 -0.07134160000000001 0.06328 0.051999 -0.07086389999999999 0.063375 0.081417 -0.068768 0.06328 0.051999 -0.07547710000000001 0.0635952 0.051999 -0.0734052 0.0634373 0.081417 -0.068768 0.06328 0.051999 -0.0734052 0.0634373 0.051999 -0.07134160000000001 0.06328 0.051999 -0.0839454 0.09207849999999999 0.051999 -0.0866497 0.08881989999999999 0.082747 -0.083963 0.08881600000000001 0.051999 -0.0866497 0.08881989999999999 0.051999 -0.0866529 0.08881600000000001 0.082747 -0.083963 0.08881600000000001 0.051999 -0.0837358 0.092331 0.051999 -0.0839454 0.09207849999999999 0.082493 -0.081068 0.092331 0.051999 -0.0839454 0.09207849999999999 0.082747 -0.083963 0.08881600000000001 0.082493 -0.081068 0.092331 0.081417 -0.068768 0.06328 0.081814 -0.073299 0.063628 0.051999 -0.07547710000000001 0.0635952 0.081814 -0.073299 0.063628 0.051999 -0.0759073 0.063628 0.051999 -0.07547710000000001 0.0635952 0.081814 -0.073299 0.063628 0.051999 -0.07985440000000001 0.06506000000000001 0.051999 -0.0759073 0.063628 0.081814 -0.073299 0.063628 0.082187 -0.077569 0.065189 0.051999 -0.07985440000000001 0.06506000000000001 0.082187 -0.077569 0.065189 0.051999 -0.08021 0.065189 0.051999 -0.07985440000000001 0.06506000000000001 0.082187 -0.077569 0.065189 0.051999 -0.08365930000000001 0.0676559 0.051999 -0.08107590000000001 0.0658083 0.082187 -0.077569 0.065189 0.051999 -0.08107590000000001 0.0658083 0.051999 -0.08021 0.065189 0.051999 -0.0885504 0.0843766 0.051999 -0.08879579999999999 0.08269609999999999 0.082965 -0.086461 0.08013199999999999 0.051999 -0.08879579999999999 0.08269609999999999 0.051999 -0.0891701 0.08013199999999999 0.082965 -0.086461 0.08013199999999999 0.082908 -0.08580699999999999 0.084646 0.051999 -0.0885111 0.084646 0.051999 -0.0885504 0.0843766 0.082965 -0.086461 0.08013199999999999 0.082908 -0.08580699999999999 0.084646 0.051999 -0.0885504 0.0843766 0.051999 -0.08677260000000001 0.0885475 0.051999 -0.0885111 0.084646 0.082908 -0.08580699999999999 0.084646 0.051999 -0.0866529 0.08881600000000001 0.051999 -0.08677260000000001 0.0885475 0.082747 -0.083963 0.08881600000000001 0.051999 -0.08677260000000001 0.0885475 0.082908 -0.08580699999999999 0.084646 0.082747 -0.083963 0.08881600000000001 0.082187 -0.077569 0.065189 0.08251 -0.08126 0.06784900000000001 0.051999 -0.08365930000000001 0.0676559 0.08251 -0.08126 0.06784900000000001 0.051999 -0.0839293 0.06784900000000001 0.051999 -0.08365930000000001 0.0676559 0.051999 -0.0858391 0.0702256 0.051999 -0.0839293 0.06784900000000001 0.08251 -0.08126 0.06784900000000001 0.051999 -0.0866055 0.0711792 0.051999 -0.0858391 0.0702256 0.08251 -0.08126 0.06784900000000001 0.051999 -0.0886436 0.0760777 0.051999 -0.0885826 0.07560799999999999 0.082914 -0.085878 0.07560799999999999 0.051999 -0.0891359 0.079869 0.051999 -0.0886436 0.0760777 0.082914 -0.085878 0.07560799999999999 0.051999 -0.0891701 0.08013199999999999 0.051999 -0.0891359 0.079869 0.082965 -0.086461 0.08013199999999999 0.051999 -0.0891359 0.079869 0.082914 -0.085878 0.07560799999999999 0.082965 -0.086461 0.08013199999999999 0.051999 -0.08679099999999999 0.07141 0.051999 -0.0866055 0.0711792 0.082759 -0.08409999999999999 0.07141 0.051999 -0.0866055 0.0711792 0.08251 -0.08126 0.06784900000000001 0.082759 -0.08409999999999999 0.07141 0.051999 -0.08847530000000001 0.0753567 0.051999 -0.08679099999999999 0.07141 0.082759 -0.08409999999999999 0.07141 0.051999 -0.0885826 0.07560799999999999 0.051999 -0.08847530000000001 0.0753567 0.082914 -0.085878 0.07560799999999999 0.051999 -0.08847530000000001 0.0753567 0.082759 -0.08409999999999999 0.07141 0.082914 -0.085878 0.07560799999999999 0.051999 0.060672 0.09099409999999999 0.051999 0.0603288 0.0904718 0.080404 0.058187 0.09099500000000001 0.051999 0.0603288 0.0904718 0.08018599999999999 0.055698 0.08717800000000001 0.080404 0.058187 0.09099500000000001 0.051999 0.0627234 0.09278 0.051999 0.060672 0.09099409999999999 0.080404 0.058187 0.09099500000000001 0.051999 0.06367879999999999 0.0936118 0.051999 0.0627234 0.09278 0.080404 0.058187 0.09099500000000001 0.051999 0.0567614 0.0821611 0.051999 0.0566747 0.0795459 0.080053 0.054178 0.07826900000000001 0.051999 0.0566747 0.0795459 0.051999 0.0566323 0.07826900000000001 0.080053 0.054178 0.07826900000000001 0.051999 0.0567835 0.082828 0.051999 0.0567614 0.0821611 0.080067 0.054328 0.082828 0.080067 0.054328 0.082828 0.051999 0.0567614 0.0821611 0.080053 0.054178 0.07826900000000001 0.080067 0.054328 0.082828 0.051999 0.0579673 0.0865547 0.051999 0.0567835 0.082828 0.051999 0.0581648 0.08717709999999999 0.051999 0.0579673 0.0865547 0.08018599999999999 0.055698 0.08717800000000001 0.051999 0.0579673 0.0865547 0.080067 0.054328 0.082828 0.08018599999999999 0.055698 0.08717800000000001 0.051999 0.0603288 0.0904718 0.051999 0.0581648 0.08717709999999999 0.08018599999999999 0.055698 0.08717800000000001 0.080703 0.061608 0.093996 0.051999 0.0641201 0.093996 0.051999 0.06385399999999999 0.0937644 0.080404 0.058187 0.09099500000000001 0.080703 0.061608 0.093996 0.051999 0.06367879999999999 0.0936118 0.080703 0.061608 0.093996 0.051999 0.06385399999999999 0.0937644 0.051999 0.06367879999999999 0.0936118 0.051999 0.0580428 0.0732703 0.051999 0.0589886 0.07159840000000001 0.06617099999999999 0.0580672 0.071036 0.051999 0.0589886 0.07159840000000001 0.051999 0.0599697 0.0698641 0.06617099999999999 0.0580672 0.071036 0.051999 0.0599697 0.0698641 0.080343 0.05749 0.069865 0.06617099999999999 0.0580672 0.071036 0.080343 0.05749 0.069865 0.051999 0.0580428 0.0732703 0.06617099999999999 0.0580672 0.071036 0.080148 0.055259 0.073838 0.051999 0.0577216 0.073838 0.051999 0.0580428 0.0732703 0.080343 0.05749 0.069865 0.080148 0.055259 0.073838 0.051999 0.0580428 0.0732703 0.051999 0.0567916 0.0776212 0.051999 0.0577216 0.073838 0.080148 0.055259 0.073838 0.080053 0.054178 0.07826900000000001 0.051999 0.0566323 0.07826900000000001 0.051999 0.0567916 0.0776212 0.080148 0.055259 0.073838 0.080053 0.054178 0.07826900000000001 0.051999 0.0567916 0.0776212 0.080703 0.061608 0.093996 0.051999 0.0677681 0.0957298 0.051999 0.0674573 0.0955821 0.080703 0.061608 0.093996 0.051999 0.0674573 0.0955821 0.051999 0.0668309 0.09528440000000001 0.080703 0.061608 0.093996 0.051999 0.0668309 0.09528440000000001 0.051999 0.0663395 0.0950508 0.080703 0.061608 0.093996 0.051999 0.0663395 0.0950508 0.051999 0.0659211 0.09485200000000001 0.080703 0.061608 0.093996 0.051999 0.0659211 0.09485200000000001 0.051999 0.0655382 0.09467 0.080703 0.061608 0.093996 0.051999 0.0655382 0.09467 0.051999 0.06506969999999999 0.0944473 0.080703 0.061608 0.093996 0.051999 0.06506969999999999 0.0944473 0.051999 0.064483 0.0941685 0.080703 0.061608 0.093996 0.051999 0.064483 0.0941685 0.051999 0.0641201 0.093996 0.066485 0.06516230000000001 0.0648441 0.051999 0.063722 0.0663567 0.051999 0.064483 0.06593160000000001 0.066485 0.06516230000000001 0.0648441 0.080971 0.06467000000000001 0.064411 0.051999 0.063722 0.0663567 0.066485 0.06516230000000001 0.0648441 0.051999 0.0672055 0.064411 0.080971 0.06467000000000001 0.064411 0.066485 0.06516230000000001 0.0648441 0.051999 0.064483 0.06593160000000001 0.051999 0.0672055 0.064411 0.066485 0.0629864 0.0660599 0.051999 0.0632113 0.0666421 0.051999 0.063722 0.0663567 0.066485 0.0629864 0.0660599 0.080625 0.060707 0.06664299999999999 0.051999 0.0632113 0.0666421 0.066485 0.0629864 0.0660599 0.080971 0.06467000000000001 0.064411 0.080625 0.060707 0.06664299999999999 0.066485 0.0629864 0.0660599 0.051999 0.063722 0.0663567 0.080971 0.06467000000000001 0.064411 0.051999 0.0604126 0.0694239 0.051999 0.0632113 0.0666421 0.080625 0.060707 0.06664299999999999 0.051999 0.0599697 0.0698641 0.051999 0.0604126 0.0694239 0.066312 0.0597144 0.0688737 0.051999 0.0604126 0.0694239 0.080625 0.060707 0.06664299999999999 0.066312 0.0597144 0.0688737 0.080625 0.060707 0.06664299999999999 0.080343 0.05749 0.069865 0.066312 0.0597144 0.0688737 0.080343 0.05749 0.069865 0.051999 0.0599697 0.0698641 0.066312 0.0597144 0.0688737 0.080703 0.061608 0.093996 0.081062 0.06571 0.09596 0.051999 0.0677681 0.0957298 0.081062 0.06571 0.09596 0.051999 0.0682526 0.09596 0.051999 0.0677681 0.0957298 0.051999 0.0762312 0.063497 0.08175499999999999 0.073628 0.063497 0.06687700000000001 0.0741835 0.0634707 0.08175499999999999 0.073628 0.063497 0.051999 0.07213890000000001 0.06335300000000001 0.06687700000000001 0.0741835 0.0634707 0.051999 0.07213890000000001 0.06335300000000001 0.08175499999999999 0.073628 0.063497 0.06687700000000001 0.07135909999999999 0.06337139999999999 0.08175499999999999 0.073628 0.063497 0.081358 0.069087 0.063336 0.06687700000000001 0.07135909999999999 0.06337139999999999 0.081358 0.069087 0.063336 0.051999 0.07165539999999999 0.063336 0.06687700000000001 0.07135909999999999 0.06337139999999999 0.081358 0.069087 0.063336 0.051999 0.0677277 0.06428490000000001 0.051999 0.07165539999999999 0.063336 0.051999 0.0672055 0.064411 0.051999 0.0677277 0.06428490000000001 0.0666785 0.06694840000000001 0.06416280000000001 0.051999 0.0677277 0.06428490000000001 0.081358 0.069087 0.063336 0.0666785 0.06694840000000001 0.06416280000000001 0.081358 0.069087 0.063336 0.080971 0.06467000000000001 0.064411 0.0666785 0.06694840000000001 0.06416280000000001 0.080971 0.06467000000000001 0.064411 0.051999 0.0672055 0.064411 0.0666785 0.06694840000000001 0.06416280000000001 0.081062 0.06571 0.09596 0.081454 0.070187 0.09674000000000001 0.051999 0.07228900000000001 0.0966579 0.081454 0.070187 0.09674000000000001 0.051999 0.07276390000000001 0.09674000000000001 0.051999 0.07228900000000001 0.0966579 0.081454 0.070187 0.09674000000000001 0.051999 0.0768953 0.096321 0.051999 0.0738485 0.09662999999999999 0.081454 0.070187 0.09674000000000001 0.051999 0.0738485 0.09662999999999999 0.051999 0.07276390000000001 0.09674000000000001 0.081062 0.06571 0.09596 0.051999 0.07228900000000001 0.0966579 0.051999 0.0721277 0.09662999999999999 0.081062 0.06571 0.09596 0.051999 0.0721277 0.09662999999999999 0.051999 0.0684025 0.0959859 0.081062 0.06571 0.09596 0.051999 0.0684025 0.0959859 0.051999 0.0682526 0.09596 0.08185000000000001 0.074708 0.096278 0.08222 0.07893699999999999 0.094609 0.051999 0.08123379999999999 0.0947453 0.08222 0.07893699999999999 0.094609 0.051999 0.08158169999999999 0.094609 0.051999 0.08123379999999999 0.0947453 0.051999 0.07664029999999999 0.0636268 0.082134 0.077958 0.06488099999999999 0.0670665 0.07591199999999999 0.06381390000000001 0.082134 0.077958 0.06488099999999999 0.08175499999999999 0.073628 0.063497 0.0670665 0.07591199999999999 0.06381390000000001 0.08175499999999999 0.073628 0.063497 0.051999 0.0762312 0.063497 0.0670665 0.07591199999999999 0.06381390000000001 0.051999 0.08091 0.0650877 0.051999 0.0813194 0.06535589999999999 0.0672325 0.08226509999999999 0.0668482 0.051999 0.0813194 0.06535589999999999 0.051999 0.08442040000000001 0.067387 0.0672325 0.08226509999999999 0.0668482 0.051999 0.08442040000000001 0.067387 0.082466 0.08175499999999999 0.067387 0.0672325 0.08226509999999999 0.0668482 0.082466 0.08175499999999999 0.067387 0.051999 0.08091 0.0650877 0.0672325 0.08226509999999999 0.0668482 0.051999 0.0805944 0.06488099999999999 0.051999 0.08091 0.0650877 0.0672325 0.0802522 0.0655298 0.051999 0.08091 0.0650877 0.082466 0.08175499999999999 0.067387 0.0672325 0.0802522 0.0655298 0.082466 0.08175499999999999 0.067387 0.082134 0.077958 0.06488099999999999 0.0672325 0.0802522 0.0655298 0.082134 0.077958 0.06488099999999999 0.051999 0.0805944 0.06488099999999999 0.0672325 0.0802522 0.0655298 0.082134 0.077958 0.06488099999999999 0.051999 0.07664029999999999 0.0636268 0.051999 0.0805944 0.06488099999999999 0.081454 0.070187 0.09674000000000001 0.08185000000000001 0.074708 0.096278 0.051999 0.0768953 0.096321 0.08185000000000001 0.074708 0.096278 0.051999 0.0773195 0.096278 0.051999 0.0768953 0.096321 0.08185000000000001 0.074708 0.096278 0.051999 0.08123379999999999 0.0947453 0.051999 0.0773195 0.096278 0.08222 0.07893699999999999 0.094609 0.051999 0.0849704 0.0920545 0.051999 0.0829199 0.0936003 0.08222 0.07893699999999999 0.094609 0.051999 0.0829199 0.0936003 0.051999 0.08158169999999999 0.094609 0.051999 0.08442040000000001 0.067387 0.051999 0.0846388 0.067637 0.082466 0.08175499999999999 0.067387 0.051999 0.0846388 0.067637 0.08272699999999999 0.08473799999999999 0.070829 0.082466 0.08175499999999999 0.067387 0.06736300000000001 0.0852699 0.069899 0.051999 0.0846388 0.067637 0.051999 0.08634890000000001 0.0695953 0.06736300000000001 0.0852699 0.069899 0.08272699999999999 0.08473799999999999 0.070829 0.051999 0.0846388 0.067637 0.06736300000000001 0.0852699 0.069899 0.051999 0.0874263 0.070829 0.08272699999999999 0.08473799999999999 0.070829 0.06736300000000001 0.0852699 0.069899 0.051999 0.08634890000000001 0.0695953 0.051999 0.0874263 0.070829 0.08222 0.07893699999999999 0.094609 0.082537 0.082561 0.09185699999999999 0.051999 0.0849704 0.0920545 0.082537 0.082561 0.09185699999999999 0.051999 0.08523260000000001 0.09185699999999999 0.051999 0.0849704 0.0920545 0.051999 0.08782570000000001 0.0884583 0.051999 0.08523260000000001 0.09185699999999999 0.082537 0.082561 0.09185699999999999 0.051999 0.0880036 0.088225 0.051999 0.08788070000000001 0.0883862 0.082777 0.085311 0.088225 0.051999 0.08788070000000001 0.0883862 0.051999 0.08782570000000001 0.0884583 0.082777 0.085311 0.088225 0.051999 0.08782570000000001 0.0884583 0.082537 0.082561 0.09185699999999999 0.082777 0.085311 0.088225 0.051999 0.09016100000000001 0.079446 0.051999 0.09013350000000001 0.0797098 0.082965 0.087452 0.079446 0.051999 0.09013350000000001 0.0797098 0.082924 0.086983 0.083984 0.082965 0.087452 0.079446 0.051999 0.0874263 0.070829 0.051999 0.0875537 0.0710966 0.08272699999999999 0.08473799999999999 0.070829 0.051999 0.0875537 0.0710966 0.082897 0.086685 0.07495 0.08272699999999999 0.08473799999999999 0.070829 0.067482 0.08848209999999999 0.077559 0.051999 0.0894345 0.0752197 0.051999 0.08946229999999999 0.0753813 0.067482 0.08848209999999999 0.077559 0.082965 0.087452 0.079446 0.051999 0.0894345 0.0752197 0.067482 0.08848209999999999 0.077559 0.051999 0.09016100000000001 0.079446 0.082965 0.087452 0.079446 0.067482 0.08848209999999999 0.077559 0.051999 0.08946229999999999 0.0753813 0.051999 0.09016100000000001 0.079446 0.082897 0.086685 0.07495 0.051999 0.0893881 0.07495 0.051999 0.0894345 0.0752197 0.082965 0.087452 0.079446 0.082897 0.086685 0.07495 0.051999 0.0894345 0.0752197 0.051999 0.0875537 0.0710966 0.051999 0.0893881 0.07495 0.082897 0.086685 0.07495 0.051999 0.089588 0.0842357 0.051999 0.0880036 0.088225 0.082777 0.085311 0.088225 0.051999 0.0896884 0.0839831 0.051999 0.089588 0.0842357 0.082924 0.086983 0.083984 0.051999 0.089588 0.0842357 0.082777 0.085311 0.088225 0.082924 0.086983 0.083984 0.051999 0.09013350000000001 0.0797098 0.051999 0.0898876 0.0820703 0.082924 0.086983 0.083984 0.051999 0.0898876 0.0820703 0.051999 0.0896884 0.0839831 0.082924 0.086983 0.083984 0.051999 0.07213890000000001 0.06335300000000001 0.051999 0.0734157 0.06339789999999999 0.06687700000000001 0.0741835 0.0634707 0.051999 0.0734157 0.06339789999999999 0.051999 0.0762312 0.063497 0.06687700000000001 0.0741835 0.0634707 0.051999 0.07165539999999999 0.063336 0.051999 0.07213890000000001 0.06335300000000001 0.06687700000000001 0.07135909999999999 0.06337139999999999 0.051999 0.07664029999999999 0.0636268 0.051999 0.0762312 0.063497 0.051999 0.0779019 0.0636779 0.051999 0.0762312 0.063497 0.051999 0.07664029999999999 0.0636268 0.0670665 0.07591199999999999 0.06381390000000001 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775

    -
    -
    - - - 0 0 0 - 1 0 0 0 - - true - - - -
    - - - - -0.030236 0.032499 -0.01662 -0.030236 0.024999 -0.01662 -0.033064 0.024999 -0.009476790000000001 -0.030236 0.032499 -0.01662 -0.033064 0.024999 -0.009476790000000001 -0.033419 0.024999 -0.008579989999999999 -0.033419 0.032499 -0.008579989999999999 -0.033419 0.024999 -0.008579989999999999 -0.034503 0.024999 7.76846e-09 -0.0344958 0.024999 7.24318e-05 -0.03383 0.024999 0.00678201 -0.034503 0.032499 8.0963e-09 -0.0284953 0.026257 0.0331192 -0.0312361 0.024999 0.0195879 -0.0284953 0.024999 0.0331192 -0.0312361 0.024999 0.0195879 -0.03383 0.032499 0.00678201 -0.0317601 0.024999 0.0170012 -0.0317601 0.024999 0.0170012 -0.03383 0.032499 0.00678201 -0.0328447 0.024999 0.0116462 -0.0328447 0.024999 0.0116462 -0.03383 0.032499 0.00678201 -0.03383 0.024999 0.00678201 -0.0284953 0.026257 0.0331192 -0.03383 0.032499 0.00678201 -0.0312361 0.024999 0.0195879 -0.0284953 0.026257 0.0331192 -0.021981 0.024999 0.06528 -0.03383 0.032499 0.00678201 -0.0254558 0.0254559 -0.0231989 -0.0258064 0.024999 -0.0227164 -0.025152 0.032499 -0.023617 -0.0258064 0.024999 -0.0227164 -0.0294279 0.024999 -0.0177322 -0.025152 0.032499 -0.023617 -0.025152 0.025689 -0.023617 -0.0254558 0.0254559 -0.0231989 -0.025152 0.032499 -0.023617 -0.025152 0.032499 -0.023617 -0.0294279 0.024999 -0.0177322 -0.030236 0.024999 -0.01662 -0.030236 0.032499 -0.01662 -0.033419 0.024999 -0.008579989999999999 -0.033419 0.032499 -0.008579989999999999 -0.025152 0.032499 -0.023617 -0.030236 0.024999 -0.01662 -0.030236 0.032499 -0.01662 -0.033419 0.032499 -0.008579989999999999 -0.034503 0.024999 7.76846e-09 -0.034503 0.032499 8.0963e-09 -0.034503 0.032499 8.0963e-09 -0.03383 0.024999 0.00678201 -0.03383 0.032499 0.00678201 0.027908 0.024999 -0.020278 0.0254558 0.0254558 -0.0228897 0.027908 0.0325 -0.020278 0.027908 0.0325 -0.020278 0.0254558 0.0254558 -0.0228897 0.0235205 0.0269408 -0.0249508 -0.0277933 0.024999 0.0331192 -0.0284953 0.024999 0.0331192 -0.0295147 0.024999 0.0263536 -0.030743 0.024999 0.0202504 -0.0277933 0.024999 0.0331192 -0.0295147 0.024999 0.0263536 -0.0312361 0.024999 0.0195879 -0.030743 0.024999 0.0202504 -0.0295147 0.024999 0.0263536 -0.0284953 0.024999 0.0331192 -0.0312361 0.024999 0.0195879 -0.0295147 0.024999 0.0263536 -0.021981 0.024999 0.06528 -0.0223204 0.024999 0.0636043 -0.0208059 0.024999 0.0636043 -0.019006 0.024999 0.07145700000000001 -0.021981 0.024999 0.06528 -0.0208059 0.024999 0.0636043 -0.021981 0.032499 0.06528 -0.03383 0.032499 0.00678201 -0.021981 0.024999 0.06528 -0.025152 0.025689 -0.023617 -0.025152 0.032499 -0.023617 -0.0232262 0.0271667 -0.0252101 -0.0232262 0.0271667 -0.0252101 -0.025152 0.032499 -0.023617 -0.018489 0.032499 -0.029129 -0.033419 0.032499 -0.008579989999999999 -0.0265381 0.039499 -0.00700801 -0.030236 0.032499 -0.01662 -0.0235285 0.039499 -0.0141696 -0.025152 0.032499 -0.023617 -0.030236 0.032499 -0.01662 -0.034503 0.032499 8.0963e-09 -0.0274667 0.039499 0.000698417 -0.033419 0.032499 -0.008579989999999999 -0.0274667 0.039499 0.000698417 -0.034503 0.032499 8.0963e-09 -0.03383 0.032499 0.00678201 0.032074 0.024999 -0.0127 0.029004 0.024999 -0.0182843 0.032074 0.0325 -0.0127 0.032074 0.0325 -0.0127 0.029004 0.024999 -0.0182843 0.027908 0.024999 -0.020278 0.032074 0.0325 -0.0127 0.027908 0.024999 -0.020278 0.027908 0.0325 -0.020278 0.027908 0.0325 -0.020278 0.0235205 0.0269408 -0.0249508 0.021988 0.032499 -0.026583 0.0235205 0.0269408 -0.0249508 0.021988 0.0281168 -0.026583 0.021988 0.032499 -0.026583 0.0195459 0.0299907 -0.0281325 0.021988 0.032499 -0.026583 0.0212823 0.0286582 -0.0270307 0.0212823 0.0286582 -0.0270307 0.021988 0.032499 -0.026583 0.021988 0.0281168 -0.026583 -0.0273204 0.024999 0.0331192 -0.0277933 0.024999 0.0331192 -0.0290317 0.024999 0.0266848 -0.0298516 0.024999 0.0214477 -0.0273204 0.024999 0.0331192 -0.0290317 0.024999 0.0266848 -0.030743 0.024999 0.0202504 -0.0298516 0.024999 0.0214477 -0.0290317 0.024999 0.0266848 -0.0277933 0.024999 0.0331192 -0.030743 0.024999 0.0202504 -0.0290317 0.024999 0.0266848 -0.026916 0.024999 0.025391 -0.0259098 0.024999 0.0331192 -0.0274245 0.024999 0.0247079 -0.0214843 0.024999 0.0331193 -0.0259098 0.024999 0.0331192 -0.021701 0.024999 0.0297668 -0.0259098 0.024999 0.0331192 -0.026916 0.024999 0.025391 -0.021701 0.024999 0.0297668 -0.0259098 0.024999 0.0331192 -0.0273204 0.024999 0.0331192 -0.0278807 0.024999 0.0272835 -0.0274245 0.024999 0.0247079 -0.0259098 0.024999 0.0331192 -0.0278807 0.024999 0.0272835 -0.0298516 0.024999 0.0214477 -0.0274245 0.024999 0.0247079 -0.0278807 0.024999 0.0272835 -0.0273204 0.024999 0.0331192 -0.0298516 0.024999 0.0214477 -0.0278807 0.024999 0.0272835 -0.0188089 0.024999 0.0331193 -0.0188016 0.024999 0.0316831 -0.0159418 0.024999 0.0331193 -0.0188089 0.024999 0.0331193 -0.0214843 0.024999 0.0331193 -0.0202513 0.024999 0.031443 -0.0188016 0.024999 0.0316831 -0.0188089 0.024999 0.0331193 -0.0202513 0.024999 0.031443 -0.020335 0.024999 0.030913 -0.0188016 0.024999 0.0316831 -0.0202513 0.024999 0.031443 -0.021701 0.024999 0.0297668 -0.020335 0.024999 0.030913 -0.0202513 0.024999 0.031443 -0.0214843 0.024999 0.0331193 -0.021701 0.024999 0.0297668 -0.0202513 0.024999 0.031443 -0.019006 0.024999 0.07145700000000001 -0.0164292 0.024999 0.06360440000000001 -0.0127796 0.024999 0.06360440000000001 -0.019006 0.024999 0.07145700000000001 -0.0171076 0.024999 0.06360440000000001 -0.0164292 0.024999 0.06360440000000001 -0.019006 0.024999 0.07145700000000001 -0.0177574 0.024999 0.06360440000000001 -0.0171076 0.024999 0.06360440000000001 -0.019006 0.024999 0.07145700000000001 -0.0183777 0.024999 0.06360440000000001 -0.0177574 0.024999 0.06360440000000001 -0.019006 0.024999 0.07145700000000001 -0.0189656 0.024999 0.06360440000000001 -0.0183777 0.024999 0.06360440000000001 -0.019006 0.024999 0.07145700000000001 -0.0195136 0.024999 0.06360440000000001 -0.0189656 0.024999 0.06360440000000001 -0.019006 0.024999 0.07145700000000001 -0.0204201 0.024999 0.06360440000000001 -0.0195136 0.024999 0.06360440000000001 -0.019006 0.024999 0.07145700000000001 -0.020709 0.024999 0.0636043 -0.0204201 0.024999 0.06360440000000001 -0.019006 0.024999 0.07145700000000001 -0.0208059 0.024999 0.0636043 -0.020709 0.024999 0.0636043 -0.019006 0.024999 0.07145700000000001 -0.0127796 0.024999 0.06360440000000001 0.00501562 0.024999 0.0636046 -0.019006 0.024999 0.07145700000000001 0.00501562 0.024999 0.0636046 0.0196769 0.024999 0.0636048 -0.021981 0.024999 0.06528 -0.019006 0.024999 0.07145700000000001 -0.021981 0.032499 0.06528 -0.021981 0.032499 0.06528 -0.0160897 0.039499 0.0591044 -0.03383 0.032499 0.00678201 -0.0223017 0.0278761 -0.025975 -0.018489 0.032499 -0.029129 -0.018489 0.0308017 -0.029129 -0.0232262 0.0271667 -0.0252101 -0.018489 0.032499 -0.029129 -0.0223017 0.0278761 -0.025975 -0.018489 0.032499 -0.029129 -0.025152 0.032499 -0.023617 -0.0188569 0.039499 -0.0203722 -0.030236 0.032499 -0.01662 -0.0265381 0.039499 -0.00700801 -0.0235285 0.039499 -0.0141696 -0.0265381 0.039499 -0.00700801 -0.033419 0.032499 -0.008579989999999999 -0.0274667 0.039499 0.000698417 -0.025152 0.032499 -0.023617 -0.0235285 0.039499 -0.0141696 -0.0188569 0.039499 -0.0203722 -0.0274667 0.039499 0.000698417 -0.03383 0.032499 0.00678201 -0.0267417 0.039499 0.00678201 0.034225 0.024999 -0.004324 0.0326797 0.024999 -0.0103416 0.034225 0.0325 -0.004324 0.034225 0.0325 -0.004324 0.0326797 0.024999 -0.0103416 0.032074 0.024999 -0.0127 0.034225 0.0325 -0.004324 0.032074 0.024999 -0.0127 0.032074 0.0325 -0.0127 0.032074 0.0325 -0.0127 0.027908 0.0325 -0.020278 0.0280786 0.0354482 -0.016489 0.025783 0.039499 -0.015885 0.032074 0.0325 -0.0127 0.0280786 0.0354482 -0.016489 0.027908 0.0325 -0.020278 0.025783 0.039499 -0.015885 0.0280786 0.0354482 -0.016489 0.025783 0.039499 -0.015885 0.027908 0.0325 -0.020278 0.021988 0.032499 -0.026583 0.0195459 0.0299907 -0.0281325 0.018 0.0311769 -0.0291133 0.0183981 0.0312448 -0.0288607 0.021988 0.032499 -0.026583 0.0195459 0.0299907 -0.0281325 0.0183981 0.0312448 -0.0288607 0.0148082 0.032499 -0.0311385 0.021988 0.032499 -0.026583 0.0183981 0.0312448 -0.0288607 0.018 0.0311769 -0.0291133 0.0148082 0.032499 -0.0311385 0.0183981 0.0312448 -0.0288607 0.0223527 0.024999 0.0636048 0.0225423 0.0250224 0.063039 0.020719 0.032499 0.068479 0.020719 0.024999 0.068479 0.0223527 0.024999 0.0636048 0.020719 0.032499 0.068479 0.0225423 0.0250224 0.063039 0.022548 0.0250231 0.06302199999999999 0.022548 0.032499 0.06302199999999999 0.020719 0.032499 0.068479 0.0225423 0.0250224 0.063039 0.022548 0.032499 0.06302199999999999 0.022548 0.0250231 0.06302199999999999 0.0226004 0.0250338 0.06276080000000001 0.022548 0.032499 0.06302199999999999 0.022548 0.032499 0.06302199999999999 0.0226004 0.0250338 0.06276080000000001 0.033824 0.032499 0.006782 0.034225 0.024999 0.004324 0.033824 0.032499 0.006782 0.0334599 0.024999 0.008169940000000001 0.033824 0.032499 0.006782 0.0320738 0.024999 0.0151374 0.0334599 0.024999 0.008169940000000001 0.033824 0.032499 0.006782 0.0312352 0.024999 0.019353 0.0320738 0.024999 0.0151374 0.033824 0.032499 0.006782 0.0311733 0.024999 0.0196642 0.0312352 0.024999 0.019353 0.0311733 0.024999 0.0196642 0.0285113 0.026257 0.0331198 0.0284965 0.024999 0.0331199 0.033824 0.032499 0.006782 0.0285113 0.026257 0.0331198 0.0311733 0.024999 0.0196642 0.0226004 0.0250338 0.06276080000000001 0.0285113 0.026257 0.0331198 0.033824 0.032499 0.006782 0.020719 0.024999 0.068479 -0.019006 0.024999 0.07145700000000001 0.0196769 0.024999 0.0636048 0.020719 0.024999 0.068479 0.0196769 0.024999 0.0636048 0.0223527 0.024999 0.0636048 -0.021981 0.032499 0.06528 -0.019006 0.024999 0.07145700000000001 -0.0167549 0.032499 0.0738829 -0.0160897 0.039499 0.0591044 -0.021981 0.032499 0.06528 -0.0125095 0.0387423 0.072966 -0.03383 0.032499 0.00678201 -0.0160897 0.039499 0.0591044 -0.0267417 0.039499 0.00678201 -0.018489 0.0308017 -0.029129 -0.018489 0.032499 -0.029129 -0.018 0.0311769 -0.0293591 -0.018 0.0311769 -0.0293591 -0.018489 0.032499 -0.029129 -0.0148082 0.032499 -0.030861 -0.018489 0.032499 -0.029129 -0.0188569 0.039499 -0.0203722 -0.0124874 0.039499 -0.0250091 -0.0235285 0.039499 -0.0141696 -0.0265381 0.039499 -0.00700801 0.0247849 0.039499 0.006782 -0.0265381 0.039499 -0.00700801 -0.0274667 0.039499 0.000698417 0.0247849 0.039499 0.006782 -0.0188569 0.039499 -0.0203722 -0.0235285 0.039499 -0.0141696 0.0247849 0.039499 0.006782 -0.0274667 0.039499 0.000698417 -0.0267417 0.039499 0.00678201 0.0247849 0.039499 0.006782 0.034225 0.0325 0.004324 0.034225 0.024999 -0.004324 0.034225 0.0325 -0.004324 0.034225 0.024999 0.004324 0.034225 0.024999 -0.00130163 0.034225 0.0325 0.004324 0.034225 0.0325 0.004324 0.034225 0.024999 -0.00130163 0.034225 0.024999 -0.004324 0.025783 0.039499 -0.015885 0.034225 0.0325 -0.004324 0.032074 0.0325 -0.0127 0.0191188 0.039499 -0.0224148 0.025783 0.039499 -0.015885 0.021988 0.032499 -0.026583 0.021988 0.032499 -0.026583 0.0148082 0.032499 -0.0311385 0.0183497 0.0355645 -0.0262688 0.0191188 0.039499 -0.0224148 0.021988 0.032499 -0.026583 0.0183497 0.0355645 -0.0262688 0.0147114 0.0325391 -0.0311656 0.0191188 0.039499 -0.0224148 0.0183497 0.0355645 -0.0262688 0.0148082 0.032499 -0.0311385 0.0147114 0.0325391 -0.0311656 0.0183497 0.0355645 -0.0262688 0.0113892 0.039499 -0.0265652 0.0191188 0.039499 -0.0224148 0.0147114 0.0325391 -0.0311656 0.0113892 0.039499 -0.0265652 0.0147114 0.0325391 -0.0311656 0.0146564 0.0325619 -0.0311742 0.013724 0.0329481 -0.0311616 0.00931748 0.0347733 -0.0311017 0.0114128 0.0362868 -0.0291834 0.0146564 0.0325619 -0.0311742 0.013724 0.0329481 -0.0311616 0.0114128 0.0362868 -0.0291834 0.0113892 0.039499 -0.0265652 0.0146564 0.0325619 -0.0311742 0.0114128 0.0362868 -0.0291834 0.008169249999999999 0.0349245 -0.0313513 0.0113892 0.039499 -0.0265652 0.0114128 0.0362868 -0.0291834 0.00931748 0.0347733 -0.0311017 0.008169249999999999 0.0349245 -0.0313513 0.0114128 0.0362868 -0.0291834 0.0159356 0.024999 0.0331197 0.020329 0.024999 0.030913 0.0284965 0.024999 0.0331199 0.0284965 0.024999 0.0331199 0.020329 0.024999 0.030913 0.02691 0.024999 0.025391 0.0284965 0.024999 0.0331199 0.02691 0.024999 0.025391 0.0311733 0.024999 0.0196642 0.016857 0.032499 0.074144 0.020719 0.024999 0.068479 0.020719 0.032499 0.068479 0.0153354 0.039499 0.06338779999999999 0.020719 0.032499 0.068479 0.022548 0.032499 0.06302199999999999 0.022548 0.032499 0.06302199999999999 0.033824 0.032499 0.006782 0.0153354 0.039499 0.06338779999999999 0.0312352 0.024999 0.019353 0.0311733 0.024999 0.0196642 0.03204 0.024999 0.0185 0.033824 0.032499 0.006782 0.034225 0.024999 0.004324 0.034225 0.0325 0.004324 -0.014343 0.024999 0.07648199999999999 -0.019006 0.024999 0.07145700000000001 0.020719 0.024999 0.068479 -0.019006 0.024999 0.07145700000000001 -0.014343 0.024999 0.07648199999999999 -0.0167549 0.032499 0.0738829 -0.0167549 0.032499 0.0738829 -0.0125095 0.0387423 0.072966 -0.021981 0.032499 0.06528 -0.0125095 0.0387423 0.072966 -0.009767420000000001 0.039499 0.07502 -0.0160897 0.039499 0.0591044 0.0247849 0.039499 0.006782 -0.0267417 0.039499 0.00678201 -0.0160897 0.039499 0.0591044 -0.018489 0.032499 -0.029129 -0.0124874 0.039499 -0.0250091 -0.0148082 0.032499 -0.030861 -0.013626 0.0329887 -0.0309315 -0.0124874 0.039499 -0.0250091 -0.0110676 0.0340484 -0.0310841 -0.0148082 0.032499 -0.030861 -0.0124874 0.039499 -0.0250091 -0.013626 0.0329887 -0.0309315 -0.0124874 0.039499 -0.0250091 -0.0188569 0.039499 -0.0203722 0.0247849 0.039499 0.006782 0.0247849 0.039499 0.006782 0.034225 0.0325 0.004324 0.034225 0.0325 -0.004324 0.0247849 0.039499 0.006782 0.034225 0.0325 -0.004324 0.0296015 0.036123 -0.0045515 0.025783 0.039499 -0.015885 0.0247849 0.039499 0.006782 0.0296015 0.036123 -0.0045515 0.034225 0.0325 -0.004324 0.025783 0.039499 -0.015885 0.0296015 0.036123 -0.0045515 0.025783 0.039499 -0.015885 0.0191188 0.039499 -0.0224148 0.0247849 0.039499 0.006782 0.0191188 0.039499 -0.0224148 0.0113892 0.039499 -0.0265652 0.0247849 0.039499 0.006782 0.0113892 0.039499 -0.0265652 0.008169249999999999 0.0349245 -0.0313513 0.00727738 0.0374776 -0.0292551 0.00316556 0.039499 -0.0283236 0.0113892 0.039499 -0.0265652 0.00727738 0.0374776 -0.0292551 0.00513146 0.0353244 -0.0316426 0.00316556 0.039499 -0.0283236 0.00727738 0.0374776 -0.0292551 0.008169249999999999 0.0349245 -0.0313513 0.00513146 0.0353244 -0.0316426 0.00727738 0.0374776 -0.0292551 0.016857 0.024999 0.074144 0.020719 0.024999 0.068479 0.016857 0.032499 0.074144 0.020719 0.032499 0.068479 0.0135171 0.039499 0.0679395 0.016857 0.032499 0.074144 0.0153354 0.039499 0.06338779999999999 0.0135171 0.039499 0.0679395 0.020719 0.032499 0.068479 0.0247849 0.039499 0.006782 0.0153354 0.039499 0.06338779999999999 0.033824 0.032499 0.006782 0.0247849 0.039499 0.006782 0.033824 0.032499 0.006782 0.034225 0.0325 0.004324 -0.008406 0.024999 0.07990999999999999 -0.014343 0.024999 0.07648199999999999 0.020719 0.024999 0.068479 -0.0167549 0.032499 0.0738829 -0.014343 0.024999 0.07648199999999999 -0.014343 0.032499 0.07648199999999999 -0.0167549 0.032499 0.0738829 -0.014343 0.032499 0.07648199999999999 -0.0125095 0.0387423 0.072966 -0.008406 0.032499 0.07990999999999999 -0.009767420000000001 0.039499 0.07502 -0.0125095 0.0387423 0.072966 -0.0160897 0.039499 0.0591044 -0.009767420000000001 0.039499 0.07502 -0.00263971 0.039499 0.0764461 0.0247849 0.039499 0.006782 -0.0160897 0.039499 0.0591044 0.0153354 0.039499 0.06338779999999999 -0.00875655 0.0348472 -0.0311134 -0.00931748 0.0347733 -0.0309839 -0.00873257 0.0373293 -0.0285917 -0.00497775 0.039499 -0.0277504 -0.00875655 0.0348472 -0.0311134 -0.00873257 0.0373293 -0.0285917 -0.0124874 0.039499 -0.0250091 -0.00497775 0.039499 -0.0277504 -0.00873257 0.0373293 -0.0285917 -0.0110676 0.0340484 -0.0310841 -0.0124874 0.039499 -0.0250091 -0.00873257 0.0373293 -0.0285917 -0.00931748 0.0347733 -0.0309839 -0.0110676 0.0340484 -0.0310841 -0.00873257 0.0373293 -0.0285917 -0.00497775 0.039499 -0.0277504 -0.00339446 0.0355531 -0.0315168 -0.00454796 0.0354012 -0.03143 -0.00497775 0.039499 -0.0277504 -0.00454796 0.0354012 -0.03143 -0.00875655 0.0348472 -0.0311134 -0.00497775 0.039499 -0.0277504 -0.0124874 0.039499 -0.0250091 0.0247849 0.039499 0.006782 0.0113892 0.039499 -0.0265652 0.00316556 0.039499 -0.0283236 0.0247849 0.039499 0.006782 0.00316556 0.039499 -0.0283236 0.00513146 0.0353244 -0.0316426 0.00479949 0.0353681 -0.0316275 0.00316556 0.039499 -0.0283236 0.00479949 0.0353681 -0.0316275 0.000453537 0.0359403 -0.031429 0.000453537 0.0359403 -0.031429 1.33055e-09 0.036 -0.0313418 -0.000906095 0.0376411 -0.0297579 0.00316556 0.039499 -0.0283236 0.000453537 0.0359403 -0.031429 -0.000906095 0.0376411 -0.0297579 -0.00497775 0.039499 -0.0277504 0.00316556 0.039499 -0.0283236 -0.000906095 0.0376411 -0.0297579 -0.00339446 0.0355531 -0.0315168 -0.00497775 0.039499 -0.0277504 -0.000906095 0.0376411 -0.0297579 1.33055e-09 0.036 -0.0313418 -0.00339446 0.0355531 -0.0315168 -0.000906095 0.0376411 -0.0297579 0.020719 0.024999 0.068479 0.016857 0.024999 0.074144 0.005115 0.024999 0.08092299999999999 0.016857 0.032499 0.074144 0.011497 0.032499 0.078419 0.016857 0.024999 0.074144 0.009525779999999999 0.039499 0.0724708 0.016857 0.032499 0.074144 0.0135171 0.039499 0.0679395 0.0153354 0.039499 0.06338779999999999 -0.0160897 0.039499 0.0591044 0.0135171 0.039499 0.0679395 -0.008406 0.024999 0.07990999999999999 -0.014343 0.032499 0.07648199999999999 -0.014343 0.024999 0.07648199999999999 -0.001722 0.024999 0.08143599999999999 -0.008406 0.024999 0.07990999999999999 0.020719 0.024999 0.068479 -0.0125095 0.0387423 0.072966 -0.014343 0.032499 0.07648199999999999 -0.008406 0.032499 0.07990999999999999 -0.008406 0.032499 0.07990999999999999 -0.001722 0.032499 0.08143599999999999 -0.009767420000000001 0.039499 0.07502 -0.001722 0.032499 0.08143599999999999 -0.00263971 0.039499 0.0764461 -0.009767420000000001 0.039499 0.07502 -0.0160897 0.039499 0.0591044 -0.00263971 0.039499 0.0764461 0.00397308 0.039499 0.07546609999999999 0.00316556 0.039499 -0.0283236 -0.00497775 0.039499 -0.0277504 0.0247849 0.039499 0.006782 0.005115 0.024999 0.08092299999999999 -0.001722 0.024999 0.08143599999999999 0.020719 0.024999 0.068479 0.016857 0.024999 0.074144 0.011497 0.024999 0.078419 0.005115 0.024999 0.08092299999999999 0.011497 0.024999 0.078419 0.016857 0.024999 0.074144 0.011497 0.032499 0.078419 0.009525779999999999 0.039499 0.0724708 0.011497 0.032499 0.078419 0.016857 0.032499 0.074144 0.0135171 0.039499 0.0679395 -0.0160897 0.039499 0.0591044 0.009525779999999999 0.039499 0.0724708 -0.008406 0.032499 0.07990999999999999 -0.014343 0.032499 0.07648199999999999 -0.008406 0.024999 0.07990999999999999 -0.001722 0.024999 0.08143599999999999 -0.008406 0.032499 0.07990999999999999 -0.008406 0.024999 0.07990999999999999 -0.001722 0.032499 0.08143599999999999 -0.008406 0.032499 0.07990999999999999 -0.001722 0.024999 0.08143599999999999 -0.001722 0.032499 0.08143599999999999 0.005115 0.032499 0.08092299999999999 -0.00263971 0.039499 0.0764461 0.005115 0.032499 0.08092299999999999 0.00397308 0.039499 0.07546609999999999 -0.00263971 0.039499 0.0764461 -0.0160897 0.039499 0.0591044 0.00397308 0.039499 0.07546609999999999 0.009525779999999999 0.039499 0.0724708 0.005115 0.024999 0.08092299999999999 -0.001722 0.032499 0.08143599999999999 -0.001722 0.024999 0.08143599999999999 0.011497 0.024999 0.078419 0.005115 0.032499 0.08092299999999999 0.005115 0.024999 0.08092299999999999 0.011497 0.032499 0.078419 0.005115 0.032499 0.08092299999999999 0.011497 0.024999 0.078419 0.009525779999999999 0.039499 0.0724708 0.00397308 0.039499 0.07546609999999999 0.011497 0.032499 0.078419 0.005115 0.032499 0.08092299999999999 -0.001722 0.032499 0.08143599999999999 0.005115 0.024999 0.08092299999999999 0.005115 0.032499 0.08092299999999999 0.011497 0.032499 0.078419 0.00397308 0.039499 0.07546609999999999 -0.0284953 0.026257 0.0331192 -0.0261929 0.0257879 0.044486 -0.021981 0.024999 0.06528 -0.021981 0.024999 0.06528 -0.0261929 0.0257879 0.044486 -0.0223204 0.024999 0.0636043 -0.0284953 0.026257 0.0331192 -0.0284953 0.024999 0.0331192 -0.044748 0.026257 0.033119 -0.0188089 0.024999 0.0331193 -0.0159418 0.024999 0.0331193 -0.0159414 -0.0122008 0.0331198 -0.0214843 0.024999 0.0331193 -0.0188089 0.024999 0.0331193 -0.0159414 -0.0122008 0.0331198 -0.0259098 0.024999 0.0331192 -0.0214843 0.024999 0.0331193 -0.0159414 -0.0122008 0.0331198 -0.0273204 0.024999 0.0331192 -0.0259098 0.024999 0.0331192 -0.0303445 -0.014001 0.0331197 -0.0277933 0.024999 0.0331192 -0.0273204 0.024999 0.0331192 -0.0303445 -0.014001 0.0331197 -0.0284953 0.024999 0.0331192 -0.0277933 0.024999 0.0331192 -0.0303445 -0.014001 0.0331197 -0.044748 -0.054259 0.03312 -0.044748 0.026257 0.033119 -0.0303445 -0.014001 0.0331197 -0.015941 -0.0275117 0.03312 -0.044748 -0.054259 0.03312 -0.0303445 -0.014001 0.0331197 -0.0159414 -0.0122008 0.0331198 -0.015941 -0.0275117 0.03312 -0.0303445 -0.014001 0.0331197 -0.044748 0.026257 0.033119 -0.0284953 0.024999 0.0331192 -0.0303445 -0.014001 0.0331197 -0.0259098 0.024999 0.0331192 -0.0159414 -0.0122008 0.0331198 -0.0303445 -0.014001 0.0331197 -0.0284953 0.026257 0.0331192 -0.044748 0.026257 0.033119 -0.0261929 0.0257879 0.044486 -0.0428306 0.02411 0.08514720000000001 -0.0208059 0.024999 0.0636043 -0.0223204 0.024999 0.0636043 -0.0428306 0.02411 0.08514720000000001 -0.020709 0.024999 0.0636043 -0.0208059 0.024999 0.0636043 -0.0428306 0.02411 0.08514720000000001 -0.0204201 0.024999 0.06360440000000001 -0.020709 0.024999 0.0636043 -0.0428306 0.02411 0.08514720000000001 -0.0195136 0.024999 0.06360440000000001 -0.0204201 0.024999 0.06360440000000001 -0.0428306 0.02411 0.08514720000000001 -0.0189656 0.024999 0.06360440000000001 -0.0195136 0.024999 0.06360440000000001 -0.0428306 0.02411 0.08514720000000001 -0.0183777 0.024999 0.06360440000000001 -0.0189656 0.024999 0.06360440000000001 -0.0428306 0.02411 0.08514720000000001 -0.0177574 0.024999 0.06360440000000001 -0.0183777 0.024999 0.06360440000000001 -0.0428306 0.02411 0.08514720000000001 -0.0171076 0.024999 0.06360440000000001 -0.0177574 0.024999 0.06360440000000001 -0.0428306 0.02411 0.08514720000000001 -0.0164292 0.024999 0.06360440000000001 -0.0171076 0.024999 0.06360440000000001 -0.0223204 0.024999 0.0636043 -0.044748 0.026257 0.033119 -0.0428306 0.02411 0.08514720000000001 -0.0428306 0.02411 0.08514720000000001 -0.0127796 0.024999 0.06360440000000001 -0.0164292 0.024999 0.06360440000000001 -0.0223204 0.024999 0.0636043 -0.0261929 0.0257879 0.044486 -0.044748 0.026257 0.033119 -0.0428306 0.02411 0.08514720000000001 0.00501562 0.024999 0.0636046 -0.0127796 0.024999 0.06360440000000001 -0.0428306 0.02411 0.08514720000000001 0.0402092 0.02411 0.0851792 0.00501562 0.024999 0.0636046 0.015935 0.00208533 0.03312 0.041968 0.026257 0.03312 0.015935 -0.00279795 0.03312 -0.044748 -0.054259 0.03312 -0.015941 -0.0275117 0.03312 -0.015941 -0.040001 0.03312 -0.044748 -0.054259 0.03312 -0.015941 -0.040001 0.03312 -0.012562 -0.040001 0.03312 0.015935 -0.040001 0.03312 0.015935 -0.00279795 0.03312 0.041968 -0.054259 0.03312 0.0121583 -0.040001 0.03312 0.015935 -0.040001 0.03312 0.041968 -0.054259 0.03312 0.00365194 -0.040001 0.03312 0.0121583 -0.040001 0.03312 0.041968 -0.054259 0.03312 0.015935 -0.00279795 0.03312 0.041968 0.026257 0.03312 0.041968 -0.054259 0.03312 -0.044748 -0.054259 0.03312 -0.012562 -0.040001 0.03312 0.041968 -0.054259 0.03312 -0.012562 -0.040001 0.03312 -0.00450946 -0.040001 0.03312 0.041968 -0.054259 0.03312 -0.00450946 -0.040001 0.03312 0.00365194 -0.040001 0.03312 0.041968 -0.054259 0.03312 -0.0428306 0.02411 0.08514720000000001 -0.044748 0.026257 0.033119 -0.044748 -0.054259 0.03312 -0.0428306 0.02411 0.08514720000000001 0.0300294 0.02411 0.09462 0.0402092 0.02411 0.0851792 0.041968 0.026257 0.03312 0.0285113 0.026257 0.0331198 0.0226004 0.0250338 0.06276080000000001 0.0225423 0.0250224 0.063039 0.0223527 0.024999 0.0636048 0.0402092 0.02411 0.0851792 0.022548 0.0250231 0.06302199999999999 0.0225423 0.0250224 0.063039 0.0402092 0.02411 0.0851792 0.0226004 0.0250338 0.06276080000000001 0.022548 0.0250231 0.06302199999999999 0.0402092 0.02411 0.0851792 0.0196769 0.024999 0.0636048 0.00501562 0.024999 0.0636046 0.0402092 0.02411 0.0851792 0.0223527 0.024999 0.0636048 0.0196769 0.024999 0.0636048 0.0402092 0.02411 0.0851792 0.041968 0.026257 0.03312 0.0226004 0.0250338 0.06276080000000001 0.0402092 0.02411 0.0851792 -0.0426476 -0.052111 0.08525099999999999 -0.044748 -0.054259 0.03312 0.041968 -0.054259 0.03312 0.04023 -0.052111 0.0852034 0.041968 -0.054259 0.03312 0.041968 0.026257 0.03312 0.0285113 0.026257 0.0331198 0.041968 0.026257 0.03312 0.0284965 0.024999 0.0331199 0.0159356 0.024999 0.0331197 0.0284965 0.024999 0.0331199 0.015935 0.00208533 0.03312 0.0284965 0.024999 0.0331199 0.041968 0.026257 0.03312 0.015935 0.00208533 0.03312 -0.044748 -0.054259 0.03312 -0.0426476 -0.052111 0.08525099999999999 -0.0428306 0.02411 0.08514720000000001 -0.0428306 0.02411 0.08514720000000001 -0.0337571 0.02411 0.09461899999999999 0.0300294 0.02411 0.09462 0.0402092 0.02411 0.0851792 0.0300294 0.02411 0.09462 0.0300255 -0.052111 0.09462 0.0402092 0.02411 0.0851792 0.04023 -0.052111 0.0852034 0.041968 0.026257 0.03312 0.04023 -0.052111 0.0852034 -0.0426476 -0.052111 0.08525099999999999 0.041968 -0.054259 0.03312 -0.0428306 0.02411 0.08514720000000001 -0.0426476 -0.052111 0.08525099999999999 -0.0337571 0.02411 0.09461899999999999 0.0300294 0.02411 0.09462 -0.0337571 0.02411 0.09461899999999999 0.0300255 -0.052111 0.09462 0.0300255 -0.052111 0.09462 0.04023 -0.052111 0.0852034 0.0402092 0.02411 0.0851792 -0.0337134 -0.052111 0.09462 -0.0426476 -0.052111 0.08525099999999999 0.04023 -0.052111 0.0852034 -0.0426476 -0.052111 0.08525099999999999 -0.0337134 -0.052111 0.09462 -0.0337571 0.02411 0.09461899999999999 -0.0337134 -0.052111 0.09462 0.0300255 -0.052111 0.09462 -0.0337571 0.02411 0.09461899999999999 0.0300255 -0.052111 0.09462 -0.0337134 -0.052111 0.09462 0.04023 -0.052111 0.0852034 -0.023786 -0.040001 -0.028343 -0.016609 -0.040001 -0.033064 -0.00853601 -0.040001 -0.036002 -0.029682 -0.040001 -0.022095 -0.023786 -0.040001 -0.028343 -0.00853601 -0.040001 -0.036002 -0.009317499999999999 -0.0347733 -0.0357177 -0.00853601 -0.0348762 -0.0360021 -0.00853601 -0.040001 -0.036002 -0.0156347 -0.0321566 -0.0334187 -0.0141211 -0.0327836 -0.0339695 -0.0125725 -0.0360788 -0.0345331 -0.016609 -0.040001 -0.033064 -0.0156347 -0.0321566 -0.0334187 -0.0125725 -0.0360788 -0.0345331 -0.00853601 -0.040001 -0.036002 -0.016609 -0.040001 -0.033064 -0.0125725 -0.0360788 -0.0345331 -0.0141211 -0.0327836 -0.0339695 -0.009317499999999999 -0.0347733 -0.0357177 -0.0125725 -0.0360788 -0.0345331 -0.009317499999999999 -0.0347733 -0.0357177 -0.00853601 -0.040001 -0.036002 -0.0125725 -0.0360788 -0.0345331 -0.023786 -0.040001 -0.028343 -0.0224359 -0.0277732 -0.0292311 -0.0201975 -0.0338871 -0.0307035 -0.016609 -0.040001 -0.033064 -0.023786 -0.040001 -0.028343 -0.0201975 -0.0338871 -0.0307035 -0.016609 -0.0317531 -0.033064 -0.016609 -0.040001 -0.033064 -0.0201975 -0.0338871 -0.0307035 -0.018 -0.0311769 -0.032149 -0.016609 -0.0317531 -0.033064 -0.0201975 -0.0338871 -0.0307035 -0.0216151 -0.0284029 -0.029771 -0.018 -0.0311769 -0.032149 -0.0201975 -0.0338871 -0.0307035 -0.0224359 -0.0277732 -0.0292311 -0.0216151 -0.0284029 -0.029771 -0.0201975 -0.0338871 -0.0307035 -0.033977 -0.040001 -0.014655 -0.029682 -0.040001 -0.022095 -0.00853601 -0.040001 -0.036002 -0.029682 -0.040001 -0.022095 -0.0280553 -0.0220681 -0.0238188 -0.026734 -0.0310346 -0.025219 -0.023786 -0.040001 -0.028343 -0.029682 -0.040001 -0.022095 -0.026734 -0.0310346 -0.025219 -0.023786 -0.0267372 -0.028343 -0.023786 -0.040001 -0.028343 -0.026734 -0.0310346 -0.025219 -0.0254559 -0.0254558 -0.0265734 -0.023786 -0.0267372 -0.028343 -0.026734 -0.0310346 -0.025219 -0.0277094 -0.022519 -0.0241854 -0.0254559 -0.0254558 -0.0265734 -0.026734 -0.0310346 -0.025219 -0.0280553 -0.0220681 -0.0238188 -0.0277094 -0.022519 -0.0241854 -0.026734 -0.0310346 -0.025219 -0.016609 -0.0317531 -0.033064 -0.018 -0.0311769 -0.032149 -0.018 -0.0311769 -0.0614 -0.0156347 -0.0321566 -0.0334187 -0.016609 -0.0317531 -0.033064 -0.018 -0.0311769 -0.0614 -0.0141211 -0.0327836 -0.0339695 -0.0156347 -0.0321566 -0.0334187 -0.018 -0.0311769 -0.0614 -0.016609 -0.0317531 -0.033064 -0.0156347 -0.0321566 -0.0334187 -0.016609 -0.040001 -0.033064 -0.00853601 -0.0348762 -0.0360021 -0.00787467 -0.0349633 -0.0360793 -0.00853601 -0.040001 -0.036002 -0.00853601 -0.0348762 -0.0360021 -0.009317499999999999 -0.0347733 -0.0357177 -0.009317499999999999 -0.0347733 -0.0614 -0.00787467 -0.0349633 -0.0360793 -0.00853601 -0.0348762 -0.0360021 -0.009317499999999999 -0.0347733 -0.0614 -0.00551692 -0.0352737 -0.0363551 -0.00787467 -0.0349633 -0.0360793 -0.009317499999999999 -0.0347733 -0.0614 -0.009317499999999999 -0.0347733 -0.0357177 -0.0141211 -0.0327836 -0.0339695 -0.0136587 -0.0329751 -0.0476848 -0.009317499999999999 -0.0347733 -0.0614 -0.009317499999999999 -0.0347733 -0.0357177 -0.0136587 -0.0329751 -0.0476848 -0.018 -0.0311769 -0.0614 -0.009317499999999999 -0.0347733 -0.0614 -0.0136587 -0.0329751 -0.0476848 -0.0141211 -0.0327836 -0.0339695 -0.018 -0.0311769 -0.0614 -0.0136587 -0.0329751 -0.0476848 -0.023786 -0.0267372 -0.028343 -0.0224359 -0.0277732 -0.0292311 -0.023786 -0.040001 -0.028343 -0.0216151 -0.0284029 -0.029771 -0.0217279 -0.0283164 -0.0455855 -0.018 -0.0311769 -0.032149 -0.0254559 -0.0254558 -0.0614 -0.0217279 -0.0283164 -0.0455855 -0.0216151 -0.0284029 -0.029771 -0.018 -0.0311769 -0.0614 -0.0217279 -0.0283164 -0.0455855 -0.0254559 -0.0254558 -0.0614 -0.018 -0.0311769 -0.032149 -0.0217279 -0.0283164 -0.0455855 -0.018 -0.0311769 -0.0614 -0.0224359 -0.0277732 -0.0292311 -0.023786 -0.0267372 -0.028343 -0.0254559 -0.0254558 -0.0614 -0.0216151 -0.0284029 -0.029771 -0.0224359 -0.0277732 -0.0292311 -0.0254559 -0.0254558 -0.0614 -0.023786 -0.0267372 -0.028343 -0.0254559 -0.0254558 -0.0265734 -0.0254559 -0.0254558 -0.0614 -0.036441 -0.040001 -0.00642499 -0.033977 -0.040001 -0.014655 -0.00853601 -0.040001 -0.036002 -0.0311769 -0.018 -0.0195055 -0.029682 -0.0199482 -0.022095 -0.0318295 -0.0275989 -0.018375 -0.0322142 -0.0154958 -0.0177087 -0.0311769 -0.018 -0.0195055 -0.0318295 -0.0275989 -0.018375 -0.032338 -0.0151968 -0.0174941 -0.0322142 -0.0154958 -0.0177087 -0.0318295 -0.0275989 -0.018375 -0.033977 -0.040001 -0.014655 -0.032338 -0.0151968 -0.0174941 -0.0318295 -0.0275989 -0.018375 -0.029682 -0.040001 -0.022095 -0.033977 -0.040001 -0.014655 -0.0318295 -0.0275989 -0.018375 -0.029682 -0.0199482 -0.022095 -0.029682 -0.040001 -0.022095 -0.0318295 -0.0275989 -0.018375 -0.0280553 -0.0220681 -0.0238188 -0.029682 -0.040001 -0.022095 -0.029682 -0.0199482 -0.022095 -0.0277094 -0.022519 -0.0241854 -0.0283164 -0.0217279 -0.0427927 -0.0254559 -0.0254558 -0.0265734 -0.0311769 -0.018 -0.0614 -0.0283164 -0.0217279 -0.0427927 -0.0277094 -0.022519 -0.0241854 -0.0254559 -0.0254558 -0.0614 -0.0283164 -0.0217279 -0.0427927 -0.0311769 -0.018 -0.0614 -0.0254559 -0.0254558 -0.0265734 -0.0283164 -0.0217279 -0.0427927 -0.0254559 -0.0254558 -0.0614 -0.029682 -0.0199482 -0.022095 -0.0311769 -0.018 -0.0195055 -0.0294431 -0.0202595 -0.0404527 -0.0280553 -0.0220681 -0.0238188 -0.029682 -0.0199482 -0.022095 -0.0294431 -0.0202595 -0.0404527 -0.0277094 -0.022519 -0.0241854 -0.0280553 -0.0220681 -0.0238188 -0.0294431 -0.0202595 -0.0404527 -0.0311769 -0.018 -0.0614 -0.0277094 -0.022519 -0.0241854 -0.0294431 -0.0202595 -0.0404527 -0.0311769 -0.018 -0.0195055 -0.0311769 -0.018 -0.0614 -0.0294431 -0.0202595 -0.0404527 -0.00787467 -0.0349633 -0.0360793 -0.00551692 -0.0352737 -0.0363551 -0.00426951 -0.0374821 -0.036501 -0.00853601 -0.040001 -0.036002 -0.00787467 -0.0349633 -0.0360793 -0.00426951 -0.0374821 -0.036501 -3.00519e-06 -0.040001 -0.037 -0.00853601 -0.040001 -0.036002 -0.00426951 -0.0374821 -0.036501 -3.00519e-06 -0.0359996 -0.037 -3.00519e-06 -0.040001 -0.037 -0.00426951 -0.0374821 -0.036501 -0.00551692 -0.0352737 -0.0363551 -3.00519e-06 -0.0359996 -0.037 -0.00426951 -0.0374821 -0.036501 -3.00519e-06 -0.0359996 -0.037 -0.00551692 -0.0352737 -0.0363551 -0.00465876 -0.0353867 -0.0488776 -1.83747e-08 -0.036 -0.0369997 -0.00465876 -0.0353867 -0.0488776 -3.00519e-06 -0.0359996 -0.037 -1.94548e-08 -0.036 -0.0614 -1.83747e-08 -0.036 -0.0369997 -0.00465876 -0.0353867 -0.0488776 -0.009317499999999999 -0.0347733 -0.0614 -1.94548e-08 -0.036 -0.0614 -0.00465876 -0.0353867 -0.0488776 -0.00551692 -0.0352737 -0.0363551 -0.009317499999999999 -0.0347733 -0.0614 -0.00465876 -0.0353867 -0.0488776 -0.009317499999999999 -0.0347733 -0.0614 -0.018 -0.0311769 -0.0614 0.0254558 -0.0254559 -0.0614 -0.018 -0.0311769 -0.0614 -0.0254559 -0.0254558 -0.0614 0.0254558 -0.0254559 -0.0614 -0.036941 -0.040001 0.00215201 -0.036441 -0.040001 -0.00642499 -0.00853601 -0.040001 -0.036002 -0.036441 -0.040001 -0.00642499 -0.0351651 -0.00634185 -0.0106868 -0.035209 -0.0231714 -0.01054 -0.033977 -0.040001 -0.014655 -0.036441 -0.040001 -0.00642499 -0.035209 -0.0231714 -0.01054 -0.033977 -0.0112399 -0.014655 -0.033977 -0.040001 -0.014655 -0.035209 -0.0231714 -0.01054 -0.0347733 -0.00931747 -0.0119953 -0.033977 -0.0112399 -0.014655 -0.035209 -0.0231714 -0.01054 -0.034998 -0.00761105 -0.0112449 -0.0347733 -0.00931747 -0.0119953 -0.035209 -0.0231714 -0.01054 -0.0351651 -0.00634185 -0.0106868 -0.034998 -0.00761105 -0.0112449 -0.035209 -0.0231714 -0.01054 -0.0311769 -0.018 -0.0195055 -0.0322142 -0.0154958 -0.0177087 -0.0329751 -0.0136587 -0.0395543 -0.0311769 -0.018 -0.0614 -0.0311769 -0.018 -0.0195055 -0.0329751 -0.0136587 -0.0395543 -0.0347733 -0.00931747 -0.0614 -0.0311769 -0.018 -0.0614 -0.0329751 -0.0136587 -0.0395543 -0.0322142 -0.0154958 -0.0177087 -0.0347733 -0.00931747 -0.0614 -0.0329751 -0.0136587 -0.0395543 -0.0347733 -0.00931747 -0.0119953 -0.0334937 -0.0124066 -0.0366976 -0.033977 -0.0112399 -0.014655 -0.0347733 -0.00931747 -0.0614 -0.0334937 -0.0124066 -0.0366976 -0.0347733 -0.00931747 -0.0119953 -0.0322142 -0.0154958 -0.0177087 -0.0334937 -0.0124066 -0.0366976 -0.0347733 -0.00931747 -0.0614 -0.032338 -0.0151968 -0.0174941 -0.0334937 -0.0124066 -0.0366976 -0.0322142 -0.0154958 -0.0177087 -0.033977 -0.0112399 -0.014655 -0.0334937 -0.0124066 -0.0366976 -0.032338 -0.0151968 -0.0174941 -0.032338 -0.0151968 -0.0174941 -0.033977 -0.040001 -0.014655 -0.033977 -0.0112399 -0.014655 -0.0254559 -0.0254558 -0.0614 -0.0311769 -0.018 -0.0614 0.0254558 -0.0254559 -0.0614 -3.00519e-06 -0.040001 -0.037 0.008529989999999999 -0.040001 -0.036002 -0.00853601 -0.040001 -0.036002 -3.00519e-06 -0.0359996 -0.037 -3.00519e-06 -0.040001 -0.037 -1.83747e-08 -0.036 -0.0369997 -1.83747e-08 -0.036 -0.0369997 0.000531419 -0.03593 -0.0369376 -3.00519e-06 -0.040001 -0.037 0.00376964 -0.0355037 -0.0365588 0.000531419 -0.03593 -0.0369376 -1.94548e-08 -0.036 -0.0614 0.000531419 -0.03593 -0.0369376 -1.83747e-08 -0.036 -0.0369997 -1.94548e-08 -0.036 -0.0614 -1.94548e-08 -0.036 -0.0614 -0.009317499999999999 -0.0347733 -0.0614 0.00931747 -0.0347733 -0.0614 0.018 -0.0311769 -0.0614 -0.009317499999999999 -0.0347733 -0.0614 0.0254558 -0.0254559 -0.0614 -0.035449 -0.040001 0.010612 -0.036941 -0.040001 0.00215201 -0.00853601 -0.040001 -0.036002 -0.036441 -0.040001 -0.00642499 -0.036941 -0.040001 0.00215201 -0.036441 0.024999 -0.00642499 -0.0351651 -0.00634185 -0.0106868 -0.036441 -0.040001 -0.00642499 -0.036 1.52588e-08 -0.007897970000000001 -0.0345511 0.00985391 -0.0127374 -0.0347733 0.009317499999999999 -0.0119953 -0.036441 0.024999 -0.00642499 -0.033977 0.024999 -0.014655 -0.0345511 0.00985391 -0.0127374 -0.036441 0.024999 -0.00642499 -0.0358309 0.00128423 -0.0084627 -0.036 1.52588e-08 -0.007897970000000001 -0.036441 0.024999 -0.00642499 -0.0347733 0.009317499999999999 -0.0119953 -0.0358309 0.00128423 -0.0084627 -0.036441 0.024999 -0.00642499 -0.036441 0.024999 -0.00642499 -0.036 1.52588e-08 -0.007897970000000001 -0.036441 -0.040001 -0.00642499 -0.034998 -0.00761105 -0.0112449 -0.0353867 -0.00465873 -0.0363224 -0.0347733 -0.00931747 -0.0119953 -0.036 1.52588e-08 -0.0614 -0.0353867 -0.00465873 -0.0363224 -0.034998 -0.00761105 -0.0112449 -0.0347733 -0.00931747 -0.0614 -0.0353867 -0.00465873 -0.0363224 -0.036 1.52588e-08 -0.0614 -0.0347733 -0.00931747 -0.0119953 -0.0353867 -0.00465873 -0.0363224 -0.0347733 -0.00931747 -0.0614 -0.036 1.52588e-08 -0.007897970000000001 -0.036 1.52588e-08 -0.0614 -0.0351651 -0.00634185 -0.0106868 -0.0351651 -0.00634185 -0.0106868 -0.036 1.52588e-08 -0.0614 -0.034998 -0.00761105 -0.0112449 -0.0311769 -0.018 -0.0614 -0.0347733 -0.00931747 -0.0614 0.0254558 0.0254558 -0.0614 -0.0311769 -0.018 -0.0614 0.0311769 -0.018 -0.0614 0.0254558 -0.0254559 -0.0614 0.008529989999999999 -0.040001 -0.036002 0.016602 -0.040001 -0.033064 -0.00853601 -0.040001 -0.036002 0.000531419 -0.03593 -0.0369376 0.00376964 -0.0355037 -0.0365588 0.0042635 -0.037439 -0.036501 -3.00519e-06 -0.040001 -0.037 0.000531419 -0.03593 -0.0369376 0.0042635 -0.037439 -0.036501 0.008529989999999999 -0.040001 -0.036002 -3.00519e-06 -0.040001 -0.037 0.0042635 -0.037439 -0.036501 0.008529989999999999 -0.034877 -0.0360021 0.008529989999999999 -0.040001 -0.036002 0.0042635 -0.037439 -0.036501 0.00376964 -0.0355037 -0.0365588 0.008529989999999999 -0.034877 -0.0360021 0.0042635 -0.037439 -0.036501 0.00917697 -0.0347918 -0.0357665 0.008529989999999999 -0.034877 -0.0360021 0.00465873 -0.0353867 -0.0485577 0.00931747 -0.0347733 -0.0357154 0.00917697 -0.0347918 -0.0357665 0.00465873 -0.0353867 -0.0485577 0.00931747 -0.0347733 -0.0614 0.00931747 -0.0347733 -0.0357154 0.00465873 -0.0353867 -0.0485577 -1.94548e-08 -0.036 -0.0614 0.00931747 -0.0347733 -0.0614 0.00465873 -0.0353867 -0.0485577 0.00376964 -0.0355037 -0.0365588 -1.94548e-08 -0.036 -0.0614 0.00465873 -0.0353867 -0.0485577 0.008529989999999999 -0.034877 -0.0360021 0.00376964 -0.0355037 -0.0365588 0.00465873 -0.0353867 -0.0485577 0.00931747 -0.0347733 -0.0614 -0.009317499999999999 -0.0347733 -0.0614 0.018 -0.0311769 -0.0614 0.0218608 -0.0282144 -0.0296054 0.0254558 -0.0254559 -0.0614 0.02378 -0.0267418 -0.0283432 0.018 -0.0311769 -0.0614 0.0254558 -0.0254559 -0.0614 0.0218608 -0.0282144 -0.0296054 0.0250727 -0.0257499 -0.0269731 0.0254558 -0.0254559 -0.0614 0.0254558 -0.0254559 -0.0265671 0.02378 -0.0267418 -0.0283432 0.0254558 -0.0254559 -0.0614 0.0250727 -0.0257499 -0.0269731 -0.032046 -0.040001 0.0185 -0.035449 -0.040001 0.010612 -0.00853601 -0.040001 -0.036002 -0.036941 -0.040001 0.00215201 -0.035449 -0.040001 0.010612 -0.03694 0.024999 0.00215201 -0.036441 0.024999 -0.00642499 -0.036941 -0.040001 0.00215201 -0.03694 0.024999 0.00215201 -0.0347733 0.009317499999999999 -0.0614 -0.0339079 0.0114068 -0.0147747 -0.0311769 0.018 -0.0614 -0.033977 0.0112399 -0.014655 -0.0339079 0.0114068 -0.0147747 -0.0347733 0.009317499999999999 -0.0614 -0.0347733 0.009317499999999999 -0.0614 -0.0345511 0.00985391 -0.0127374 -0.033977 0.0112399 -0.014655 -0.0347733 0.009317499999999999 -0.0614 -0.0347733 0.009317499999999999 -0.0119953 -0.0345511 0.00985391 -0.0127374 -0.033977 0.0112399 -0.014655 -0.0345511 0.00985391 -0.0127374 -0.033977 0.024999 -0.014655 -0.034503 0.024999 7.76846e-09 -0.0344958 0.024999 7.24318e-05 -0.036441 0.024999 -0.00642499 -0.033064 0.024999 -0.009476790000000001 -0.033977 0.024999 -0.014655 -0.0347525 0.024999 -0.00729128 -0.033419 0.024999 -0.008579989999999999 -0.033064 0.024999 -0.009476790000000001 -0.0347525 0.024999 -0.00729128 -0.034503 0.024999 7.76846e-09 -0.033419 0.024999 -0.008579989999999999 -0.0347525 0.024999 -0.00729128 -0.033977 0.024999 -0.014655 -0.036441 0.024999 -0.00642499 -0.0347525 0.024999 -0.00729128 -0.036441 0.024999 -0.00642499 -0.034503 0.024999 7.76846e-09 -0.0347525 0.024999 -0.00729128 -0.0347733 0.009317499999999999 -0.0614 -0.036 1.52588e-08 -0.0614 -0.0358309 0.00128423 -0.0084627 -0.0358309 0.00128423 -0.0084627 -0.036 1.52588e-08 -0.0614 -0.036 1.52588e-08 -0.007897970000000001 -0.0347733 0.009317499999999999 -0.0119953 -0.0347733 0.009317499999999999 -0.0614 -0.0358309 0.00128423 -0.0084627 -0.0347733 -0.00931747 -0.0614 -0.036 1.52588e-08 -0.0614 0.0254558 0.0254558 -0.0614 -0.0311769 -0.018 -0.0614 0.0254558 0.0254558 -0.0614 0.0311769 0.018 -0.0614 0.0254558 -0.0254559 -0.0614 0.0311769 -0.018 -0.0614 0.0290571 -0.0207626 -0.0227502 0.0290571 -0.0207626 -0.0227502 0.0311769 -0.018 -0.0614 0.0296753 -0.0199569 -0.022095 0.0296753 -0.0199569 -0.022095 0.0311769 -0.018 -0.0614 0.0311246 -0.0180682 -0.0195845 0.0311246 -0.0180682 -0.0195845 0.0311769 -0.018 -0.0614 0.0311769 -0.018 -0.0194939 -0.0311769 -0.018 -0.0614 0.0347733 -0.009317509999999999 -0.0614 0.0311769 -0.018 -0.0614 0.016602 -0.040001 -0.033064 0.02378 -0.040001 -0.028343 -0.00853601 -0.040001 -0.036002 0.00917697 -0.0347918 -0.0357665 0.00931747 -0.0347733 -0.0357154 0.008529989999999999 -0.040001 -0.036002 0.00931747 -0.0347733 -0.0357154 0.0131466 -0.0331872 -0.0343217 0.0125661 -0.0358785 -0.034533 0.016602 -0.040001 -0.033064 0.008529989999999999 -0.040001 -0.036002 0.0125661 -0.0358785 -0.034533 0.0166021 -0.0317559 -0.033064 0.016602 -0.040001 -0.033064 0.0125661 -0.0358785 -0.034533 0.0131466 -0.0331872 -0.0343217 0.0166021 -0.0317559 -0.033064 0.0125661 -0.0358785 -0.034533 0.008529989999999999 -0.040001 -0.036002 0.00931747 -0.0347733 -0.0357154 0.0125661 -0.0358785 -0.034533 0.008529989999999999 -0.034877 -0.0360021 0.00917697 -0.0347918 -0.0357665 0.008529989999999999 -0.040001 -0.036002 0.00931747 -0.0347733 -0.0357154 0.00931747 -0.0347733 -0.0614 0.0131466 -0.0331872 -0.0343217 0.0166021 -0.0317559 -0.033064 0.0131466 -0.0331872 -0.0343217 0.0136587 -0.0329751 -0.0467723 0.0175561 -0.0313607 -0.0324366 0.0166021 -0.0317559 -0.033064 0.0136587 -0.0329751 -0.0467723 0.018 -0.0311769 -0.0321447 0.0175561 -0.0313607 -0.0324366 0.0136587 -0.0329751 -0.0467723 0.018 -0.0311769 -0.0614 0.018 -0.0311769 -0.0321447 0.0136587 -0.0329751 -0.0467723 0.00931747 -0.0347733 -0.0614 0.018 -0.0311769 -0.0614 0.0136587 -0.0329751 -0.0467723 0.0131466 -0.0331872 -0.0343217 0.00931747 -0.0347733 -0.0614 0.0136587 -0.0329751 -0.0467723 0.0175561 -0.0313607 -0.0324366 0.018 -0.0311769 -0.0321447 0.020191 -0.0333714 -0.0307036 0.016602 -0.040001 -0.033064 0.0175561 -0.0313607 -0.0324366 0.020191 -0.0333714 -0.0307036 0.02378 -0.040001 -0.028343 0.016602 -0.040001 -0.033064 0.020191 -0.0333714 -0.0307036 0.02378 -0.0267418 -0.0283432 0.02378 -0.040001 -0.028343 0.020191 -0.0333714 -0.0307036 0.0218608 -0.0282144 -0.0296054 0.02378 -0.0267418 -0.0283432 0.020191 -0.0333714 -0.0307036 0.018 -0.0311769 -0.0321447 0.0218608 -0.0282144 -0.0296054 0.020191 -0.0333714 -0.0307036 0.0218608 -0.0282144 -0.0296054 0.018 -0.0311769 -0.0321447 0.018 -0.0311769 -0.0614 0.0290571 -0.0207626 -0.0227502 0.0254558 -0.0254559 -0.0265671 0.0254558 -0.0254559 -0.0614 0.02378 -0.040001 -0.028343 0.0250727 -0.0257499 -0.0269731 0.0267277 -0.029979 -0.025219 0.029675 -0.040001 -0.022095 0.02378 -0.040001 -0.028343 0.0267277 -0.029979 -0.025219 0.0296753 -0.0199569 -0.022095 0.029675 -0.040001 -0.022095 0.0267277 -0.029979 -0.025219 0.0290571 -0.0207626 -0.0227502 0.0296753 -0.0199569 -0.022095 0.0267277 -0.029979 -0.025219 0.0254558 -0.0254559 -0.0265671 0.0290571 -0.0207626 -0.0227502 0.0267277 -0.029979 -0.025219 0.0250727 -0.0257499 -0.0269731 0.0254558 -0.0254559 -0.0265671 0.0267277 -0.029979 -0.025219 0.0250727 -0.0257499 -0.0269731 0.02378 -0.040001 -0.028343 0.02378 -0.0267418 -0.0283432 -0.026916 -0.040001 0.025391 -0.032046 -0.040001 0.0185 -0.00853601 -0.040001 -0.036002 -0.032046 -0.040001 0.0185 -0.035449 0.024999 0.010612 -0.035449 -0.040001 0.010612 -0.03694 0.024999 0.00215201 -0.035449 -0.040001 0.010612 -0.035449 0.024999 0.010612 -0.036441 0.024999 -0.00642499 -0.03694 0.024999 0.00215201 -0.0344958 0.024999 7.24318e-05 -0.0344958 0.024999 7.24318e-05 -0.03694 0.024999 0.00215201 -0.03383 0.024999 0.00678201 -0.03383 0.024999 0.00678201 -0.03694 0.024999 0.00215201 -0.0328447 0.024999 0.0116462 -0.0339079 0.0114068 -0.0147747 -0.033977 0.0112399 -0.014655 -0.033977 0.024999 -0.014655 -0.029682 0.024999 -0.022095 -0.0300472 0.0194723 -0.0214624 -0.0318295 0.0181195 -0.018375 -0.033977 0.024999 -0.014655 -0.029682 0.024999 -0.022095 -0.0318295 0.0181195 -0.018375 -0.0311769 0.018 -0.0195055 -0.0339079 0.0114068 -0.0147747 -0.0318295 0.0181195 -0.018375 -0.0300472 0.0194723 -0.0214624 -0.0311769 0.018 -0.0195055 -0.0318295 0.0181195 -0.018375 -0.0339079 0.0114068 -0.0147747 -0.033977 0.024999 -0.014655 -0.0318295 0.0181195 -0.018375 -0.0311769 0.018 -0.0195055 -0.0311769 0.018 -0.0614 -0.0339079 0.0114068 -0.0147747 -0.0347733 0.009317499999999999 -0.0614 -0.0311769 0.018 -0.0614 0.0254558 0.0254558 -0.0614 -0.0294279 0.024999 -0.0177322 -0.029682 0.024999 -0.022095 -0.0317024 0.024999 -0.0157859 -0.030236 0.024999 -0.01662 -0.0294279 0.024999 -0.0177322 -0.0317024 0.024999 -0.0157859 -0.033064 0.024999 -0.009476790000000001 -0.030236 0.024999 -0.01662 -0.0317024 0.024999 -0.0157859 -0.033977 0.024999 -0.014655 -0.033064 0.024999 -0.009476790000000001 -0.0317024 0.024999 -0.0157859 -0.029682 0.024999 -0.022095 -0.033977 0.024999 -0.014655 -0.0317024 0.024999 -0.0157859 -0.034503 0.024999 7.76846e-09 -0.0344958 0.024999 7.24318e-05 -0.034503 0.032499 8.0963e-09 -0.036 1.52588e-08 -0.0614 -0.0347733 0.009317499999999999 -0.0614 0.0254558 0.0254558 -0.0614 -0.0311769 -0.018 -0.0614 0.0311769 0.018 -0.0614 0.0347733 0.009317489999999999 -0.0614 0.0258063 0.024999 -0.0225164 0.0258063 0.024999 -0.0261964 0.0254558 0.0254558 -0.0228897 0.0254558 0.0254558 -0.0228897 0.0258063 0.024999 -0.0261964 0.0254558 0.0254558 -0.0614 0.0258063 0.024999 -0.0261964 0.0277088 0.0225196 -0.0241799 0.0283164 0.0217279 -0.0419582 0.0311769 0.018 -0.0614 0.0254558 0.0254558 -0.0614 0.0283164 0.0217279 -0.0419582 0.0277088 0.0225196 -0.0241799 0.0311769 0.018 -0.0614 0.0283164 0.0217279 -0.0419582 0.0254558 0.0254558 -0.0614 0.0258063 0.024999 -0.0261964 0.0283164 0.0217279 -0.0419582 0.0311246 -0.0180682 -0.0195845 0.029675 -0.040001 -0.022095 0.0296753 -0.0199569 -0.022095 0.0339086 -0.0114051 -0.0147631 0.033971 -0.0112544 -0.014655 0.031823 -0.0256277 -0.018375 0.0311769 -0.018 -0.0194939 0.0339086 -0.0114051 -0.0147631 0.031823 -0.0256277 -0.018375 0.0311246 -0.0180682 -0.0195845 0.0311769 -0.018 -0.0194939 0.031823 -0.0256277 -0.018375 0.029675 -0.040001 -0.022095 0.0311246 -0.0180682 -0.0195845 0.031823 -0.0256277 -0.018375 0.033971 -0.040001 -0.014655 0.029675 -0.040001 -0.022095 0.031823 -0.0256277 -0.018375 0.033971 -0.0112544 -0.014655 0.033971 -0.040001 -0.014655 0.031823 -0.0256277 -0.018375 0.0311769 -0.018 -0.0194939 0.0311769 -0.018 -0.0614 0.0339086 -0.0114051 -0.0147631 0.0311769 -0.018 -0.0614 0.0347733 -0.009317509999999999 -0.0614 0.0339086 -0.0114051 -0.0147631 0.0339086 -0.0114051 -0.0147631 0.0347733 -0.009317509999999999 -0.0614 0.033971 -0.0112544 -0.014655 0.033971 -0.0112544 -0.014655 0.0347733 -0.009317509999999999 -0.0614 0.0347733 -0.009317509999999999 -0.0119752 -0.0311769 -0.018 -0.0614 0.036 0 -0.0614 0.0347733 -0.009317509999999999 -0.0614 0.029675 -0.040001 -0.022095 -0.00853601 -0.040001 -0.036002 0.02378 -0.040001 -0.028343 0.0166021 -0.0317559 -0.033064 0.0175561 -0.0313607 -0.0324366 0.016602 -0.040001 -0.033064 -0.020335 -0.040001 0.030913 -0.026916 -0.040001 0.025391 -0.00853601 -0.040001 -0.036002 -0.032046 -0.040001 0.0185 -0.026916 -0.040001 0.025391 -0.032046 0.024999 0.0185 -0.035449 0.024999 0.010612 -0.032046 -0.040001 0.0185 -0.032046 0.024999 0.0185 -0.03694 0.024999 0.00215201 -0.035449 0.024999 0.010612 -0.0328447 0.024999 0.0116462 -0.0328447 0.024999 0.0116462 -0.035449 0.024999 0.010612 -0.0317601 0.024999 0.0170012 -0.029682 0.0199482 -0.022095 -0.0300472 0.0194723 -0.0214624 -0.029682 0.024999 -0.022095 -0.0254558 0.0254559 -0.0614 -0.0311769 0.018 -0.0614 -0.0290564 0.0207635 -0.022758 -0.0290564 0.0207635 -0.022758 -0.0311769 0.018 -0.0614 -0.029682 0.0199482 -0.022095 -0.029682 0.0199482 -0.022095 -0.0311769 0.018 -0.0614 -0.0300472 0.0194723 -0.0214624 -0.0300472 0.0194723 -0.0214624 -0.0311769 0.018 -0.0614 -0.0311769 0.018 -0.0195055 -0.0311769 0.018 -0.0614 -0.0254558 0.0254559 -0.0614 0.0254558 0.0254558 -0.0614 -0.0258064 0.024999 -0.0227164 -0.0258064 0.024999 -0.026202 -0.0277442 0.024999 -0.0219671 -0.0294279 0.024999 -0.0177322 -0.0258064 0.024999 -0.0227164 -0.0277442 0.024999 -0.0219671 -0.029682 0.024999 -0.022095 -0.0294279 0.024999 -0.0177322 -0.0277442 0.024999 -0.0219671 -0.0258064 0.024999 -0.026202 -0.029682 0.024999 -0.022095 -0.0277442 0.024999 -0.0219671 -0.0311769 -0.018 -0.0614 0.0347733 0.009317489999999999 -0.0614 0.036 0 -0.0614 0.0311769 0.018 -0.0194949 0.0322136 0.0154972 -0.017699 0.0329751 0.0136587 -0.0395495 0.0311769 0.018 -0.0614 0.0311769 0.018 -0.0194949 0.0329751 0.0136587 -0.0395495 0.0347733 0.009317489999999999 -0.0614 0.0311769 0.018 -0.0614 0.0329751 0.0136587 -0.0395495 0.0322136 0.0154972 -0.017699 0.0347733 0.009317489999999999 -0.0614 0.0329751 0.0136587 -0.0395495 0.0292669 0.0204891 -0.0225285 0.0277088 0.0225196 -0.0241799 0.0277411 0.0227441 -0.0241457 0.029676 0.024999 -0.022095 0.0292669 0.0204891 -0.0225285 0.0277411 0.0227441 -0.0241457 0.0258063 0.024999 -0.0261964 0.029676 0.024999 -0.022095 0.0277411 0.0227441 -0.0241457 0.0277088 0.0225196 -0.0241799 0.0258063 0.024999 -0.0261964 0.0277411 0.0227441 -0.0241457 0.029676 0.024999 -0.022095 0.027908 0.024999 -0.020278 0.029004 0.024999 -0.0182843 0.029676 0.024999 -0.022095 0.0258063 0.024999 -0.0261964 0.0277412 0.024999 -0.0222403 0.0258063 0.024999 -0.0225164 0.027908 0.024999 -0.020278 0.0277412 0.024999 -0.0222403 0.0258063 0.024999 -0.0261964 0.0258063 0.024999 -0.0225164 0.0277412 0.024999 -0.0222403 0.027908 0.024999 -0.020278 0.029676 0.024999 -0.022095 0.0277412 0.024999 -0.0222403 0.027908 0.024999 -0.020278 0.0258063 0.024999 -0.0225164 0.0254558 0.0254558 -0.0228897 0.0235205 0.0269408 -0.0249508 0.0254558 0.0254558 -0.0228897 0.0233691 0.027057 -0.0421448 0.021988 0.0281168 -0.026583 0.0235205 0.0269408 -0.0249508 0.0233691 0.027057 -0.0421448 0.0212823 0.0286582 -0.0270307 0.021988 0.0281168 -0.026583 0.0233691 0.027057 -0.0421448 0.0254558 0.0254558 -0.0614 0.0212823 0.0286582 -0.0270307 0.0233691 0.027057 -0.0421448 0.0254558 0.0254558 -0.0228897 0.0254558 0.0254558 -0.0614 0.0233691 0.027057 -0.0421448 0.0277088 0.0225196 -0.0241799 0.0292669 0.0204891 -0.0225285 0.0311769 0.018 -0.0614 0.0292669 0.0204891 -0.0225285 0.0296759 0.0199561 -0.022095 0.0311769 0.018 -0.0614 0.0296759 0.0199561 -0.022095 0.0311769 0.018 -0.0194949 0.0311769 0.018 -0.0614 0.033971 -0.040001 -0.014655 -0.00853601 -0.040001 -0.036002 0.029675 -0.040001 -0.022095 0.0347733 -0.009317509999999999 -0.0119752 0.033971 -0.040001 -0.014655 0.033971 -0.0112544 -0.014655 0.033971 -0.040001 -0.014655 0.0347733 -0.009317509999999999 -0.0119752 0.03528 -0.00546845 -0.0102826 0.0347733 -0.009317509999999999 -0.0119752 0.0347733 -0.009317509999999999 -0.0614 0.03528 -0.00546845 -0.0102826 0.03528 -0.00546845 -0.0102826 0.0347733 -0.009317509999999999 -0.0614 0.0358314 -0.00128097 -0.008441239999999999 0.0347733 -0.009317509999999999 -0.0614 0.036 0 -0.0614 0.0358314 -0.00128097 -0.008441239999999999 0.0358314 -0.00128097 -0.008441239999999999 0.036 0 -0.0614 0.036 0 -0.00787795 -0.015941 -0.040001 0.03312 -0.020335 -0.040001 0.030913 -0.012562 -0.040001 0.03312 -0.012562 -0.040001 0.03312 -0.020335 -0.040001 0.030913 -0.00853601 -0.040001 -0.036002 -0.020335 -0.040001 0.030913 -0.026916 0.024999 0.025391 -0.026916 -0.040001 0.025391 -0.032046 0.024999 0.0185 -0.026916 -0.040001 0.025391 -0.0312361 0.024999 0.0195879 -0.0312361 0.024999 0.0195879 -0.026916 -0.040001 0.025391 -0.030743 0.024999 0.0202504 -0.030743 0.024999 0.0202504 -0.026916 -0.040001 0.025391 -0.0298516 0.024999 0.0214477 -0.0298516 0.024999 0.0214477 -0.026916 -0.040001 0.025391 -0.0274245 0.024999 0.0247079 -0.0274245 0.024999 0.0247079 -0.026916 -0.040001 0.025391 -0.026916 0.024999 0.025391 -0.0317601 0.024999 0.0170012 -0.035449 0.024999 0.010612 -0.032046 0.024999 0.0185 -0.0317601 0.024999 0.0170012 -0.032046 0.024999 0.0185 -0.0312361 0.024999 0.0195879 -0.0258064 0.024999 -0.026202 -0.0290564 0.0207635 -0.022758 -0.029682 0.024999 -0.022095 -0.0290564 0.0207635 -0.022758 -0.029682 0.0199482 -0.022095 -0.029682 0.024999 -0.022095 -0.0290564 0.0207635 -0.022758 -0.0258064 0.024999 -0.026202 -0.0254558 0.0254559 -0.0614 -0.0258064 0.024999 -0.0227164 -0.0254558 0.0254559 -0.0231989 -0.0258064 0.024999 -0.026202 -0.0254558 0.0254559 -0.0231989 -0.0254558 0.0254559 -0.0614 -0.0258064 0.024999 -0.026202 -0.0254558 0.0254559 -0.0614 -0.018 0.0311769 -0.0614 0.0254558 0.0254558 -0.0614 -0.0223017 0.0278761 -0.025975 -0.0254558 0.0254559 -0.0614 -0.0232262 0.0271667 -0.0252101 -0.018 0.0311769 -0.0614 -0.0254558 0.0254559 -0.0614 -0.0223017 0.0278761 -0.025975 -0.025152 0.025689 -0.023617 -0.0254558 0.0254559 -0.0614 -0.0254558 0.0254559 -0.0231989 -0.0232262 0.0271667 -0.0252101 -0.0254558 0.0254559 -0.0614 -0.025152 0.025689 -0.023617 0.0347733 0.009317489999999999 -0.0119752 0.0349976 0.00761392 -0.0112261 0.0353867 0.00465875 -0.0363131 0.0347733 0.009317489999999999 -0.0614 0.0347733 0.009317489999999999 -0.0119752 0.0353867 0.00465875 -0.0363131 0.036 0 -0.0614 0.0347733 0.009317489999999999 -0.0614 0.0353867 0.00465875 -0.0363131 0.0349976 0.00761392 -0.0112261 0.036 0 -0.0614 0.0353867 0.00465875 -0.0363131 0.0331876 0.0131457 -0.0160117 0.0322136 0.0154972 -0.017699 0.033971 0.024999 -0.014655 0.0311769 0.018 -0.0194949 0.0296759 0.0199561 -0.022095 0.0318234 0.0190724 -0.018375 0.0322136 0.0154972 -0.017699 0.0311769 0.018 -0.0194949 0.0318234 0.0190724 -0.018375 0.029676 0.024999 -0.022095 0.033971 0.024999 -0.014655 0.0318234 0.0190724 -0.018375 0.0296759 0.0199561 -0.022095 0.029676 0.024999 -0.022095 0.0318234 0.0190724 -0.018375 0.033971 0.024999 -0.014655 0.0322136 0.0154972 -0.017699 0.0318234 0.0190724 -0.018375 0.0347733 0.009317489999999999 -0.0614 0.033971 0.0112544 -0.014655 0.0347733 0.009317489999999999 -0.0119752 0.033971 0.0112544 -0.014655 0.0347733 0.009317489999999999 -0.0614 0.0331876 0.0131457 -0.0160117 0.0331876 0.0131457 -0.0160117 0.0347733 0.009317489999999999 -0.0614 0.0322136 0.0154972 -0.017699 0.0296759 0.0199561 -0.022095 0.0292669 0.0204891 -0.0225285 0.029676 0.024999 -0.022095 0.033971 0.024999 -0.014655 0.032074 0.024999 -0.0127 0.0326797 0.024999 -0.0103416 0.029004 0.024999 -0.0182843 0.032074 0.024999 -0.0127 0.0314875 0.024999 -0.0162183 0.029676 0.024999 -0.022095 0.029004 0.024999 -0.0182843 0.0314875 0.024999 -0.0162183 0.033971 0.024999 -0.014655 0.029676 0.024999 -0.022095 0.0314875 0.024999 -0.0162183 0.032074 0.024999 -0.0127 0.033971 0.024999 -0.014655 0.0314875 0.024999 -0.0162183 0.0195459 0.0299907 -0.0281325 0.0212823 0.0286582 -0.0270307 0.0217279 0.0283164 -0.0442154 0.018 0.0311769 -0.0291133 0.0195459 0.0299907 -0.0281325 0.0217279 0.0283164 -0.0442154 0.018 0.0311769 -0.0614 0.018 0.0311769 -0.0291133 0.0217279 0.0283164 -0.0442154 0.0254558 0.0254558 -0.0614 0.018 0.0311769 -0.0614 0.0217279 0.0283164 -0.0442154 0.0212823 0.0286582 -0.0270307 0.0254558 0.0254558 -0.0614 0.0217279 0.0283164 -0.0442154 0.036435 -0.040001 -0.006425 -0.00853601 -0.040001 -0.036002 0.033971 -0.040001 -0.014655 0.036435 -0.040001 -0.006425 0.033971 -0.040001 -0.014655 0.03528 -0.00546845 -0.0102826 0.036435 -0.040001 -0.006425 0.03528 -0.00546845 -0.0102826 0.0358314 -0.00128097 -0.008441239999999999 0.036435 -0.040001 -0.006425 0.0358314 -0.00128097 -0.008441239999999999 0.036 0 -0.00787795 0.036 0 -0.00787795 0.035602 0.00302337 -0.009207450000000001 0.036435 0.024999 -0.006425 0.036435 -0.040001 -0.006425 0.036 0 -0.00787795 0.036435 0.024999 -0.006425 0.036 0 -0.00787795 0.036 0 -0.0614 0.035602 0.00302337 -0.009207450000000001 0.035602 0.00302337 -0.009207450000000001 0.036 0 -0.0614 0.0349976 0.00761392 -0.0112261 -0.00450946 -0.040001 0.03312 -0.012562 -0.040001 0.03312 -0.00853601 -0.040001 -0.036002 -0.015941 -0.040001 0.03312 -0.015941 -0.0275117 0.03312 -0.020335 -0.040001 0.030913 -0.015941 -0.0275117 0.03312 -0.0159414 -0.0122008 0.0331198 -0.020335 -0.040001 0.030913 -0.020335 -0.040001 0.030913 -0.0159414 -0.0122008 0.0331198 -0.020335 0.024999 0.030913 -0.021701 0.024999 0.0297668 -0.026916 0.024999 0.025391 -0.020335 -0.040001 0.030913 -0.020335 0.024999 0.030913 -0.021701 0.024999 0.0297668 -0.020335 -0.040001 0.030913 -0.0188016 0.024999 0.0316831 -0.020335 0.024999 0.030913 -0.0159414 -0.0122008 0.0331198 -0.0159418 0.024999 0.0331193 -0.0188016 0.024999 0.0316831 -0.0159414 -0.0122008 0.0331198 -0.018 0.0311769 -0.0614 -0.00931748 0.0347733 -0.0614 0.0254558 0.0254558 -0.0614 -0.018489 0.0308017 -0.029129 -0.018 0.0311769 -0.0293591 -0.018 0.0311769 -0.0614 -0.0223017 0.0278761 -0.025975 -0.018489 0.0308017 -0.029129 -0.018 0.0311769 -0.0614 0.0349976 0.00761392 -0.0112261 0.0347733 0.009317489999999999 -0.0119752 0.035203 0.0140112 -0.01054 0.035602 0.00302337 -0.009207450000000001 0.0349976 0.00761392 -0.0112261 0.035203 0.0140112 -0.01054 0.036435 0.024999 -0.006425 0.035602 0.00302337 -0.009207450000000001 0.035203 0.0140112 -0.01054 0.033971 0.024999 -0.014655 0.036435 0.024999 -0.006425 0.035203 0.0140112 -0.01054 0.033971 0.0112544 -0.014655 0.033971 0.024999 -0.014655 0.035203 0.0140112 -0.01054 0.0347733 0.009317489999999999 -0.0119752 0.033971 0.0112544 -0.014655 0.035203 0.0140112 -0.01054 0.033971 0.0112544 -0.014655 0.0331876 0.0131457 -0.0160117 0.033971 0.024999 -0.014655 0.036435 0.024999 -0.006425 0.034225 0.024999 -0.004324 0.034225 0.024999 -0.00130163 0.0326797 0.024999 -0.0103416 0.034225 0.024999 -0.004324 0.0345573 0.024999 -0.007978310000000001 0.033971 0.024999 -0.014655 0.0326797 0.024999 -0.0103416 0.0345573 0.024999 -0.007978310000000001 0.036435 0.024999 -0.006425 0.033971 0.024999 -0.014655 0.0345573 0.024999 -0.007978310000000001 0.034225 0.024999 -0.004324 0.036435 0.024999 -0.006425 0.0345573 0.024999 -0.007978310000000001 0.0148082 0.032499 -0.0311385 0.018 0.0311769 -0.0291133 0.018 0.0311769 -0.0614 0.0147114 0.0325391 -0.0311656 0.0148082 0.032499 -0.0311385 0.018 0.0311769 -0.0614 0.0146564 0.0325619 -0.0311742 0.0147114 0.0325391 -0.0311656 0.018 0.0311769 -0.0614 0.013724 0.0329481 -0.0311616 0.0146564 0.0325619 -0.0311742 0.018 0.0311769 -0.0614 0.00931748 0.0347733 -0.0614 0.018 0.0311769 -0.0614 0.0254558 0.0254558 -0.0614 0.036934 -0.040001 0.002152 -0.00853601 -0.040001 -0.036002 0.036435 -0.040001 -0.006425 0.036935 0.024999 0.002151 0.036435 -0.040001 -0.006425 0.036435 0.024999 -0.006425 0.00365194 -0.040001 0.03312 -0.00450946 -0.040001 0.03312 -0.00853601 -0.040001 -0.036002 0.020329 0.024999 0.030913 0.0159356 0.024999 0.0331197 0.015935 0.00208533 0.03312 0.020329 -0.040001 0.030913 0.020329 0.024999 0.030913 0.018132 -0.007501 0.0320165 0.015935 -0.00279795 0.03312 0.020329 -0.040001 0.030913 0.018132 -0.007501 0.0320165 0.015935 0.00208533 0.03312 0.015935 -0.00279795 0.03312 0.018132 -0.007501 0.0320165 0.020329 0.024999 0.030913 0.015935 0.00208533 0.03312 0.018132 -0.007501 0.0320165 0.020329 -0.040001 0.030913 0.015935 -0.00279795 0.03312 0.015935 -0.040001 0.03312 0.015935 -0.040001 0.03312 0.0121583 -0.040001 0.03312 0.020329 -0.040001 0.030913 0.020329 -0.040001 0.030913 0.0121583 -0.040001 0.03312 -0.00853601 -0.040001 -0.036002 0.0121583 -0.040001 0.03312 0.00365194 -0.040001 0.03312 -0.00853601 -0.040001 -0.036002 -0.00931748 0.0347733 -0.0614 0 0.036 -0.0614 0.0254558 0.0254558 -0.0614 -0.018 0.0311769 -0.0293591 -0.0148082 0.032499 -0.030861 -0.0136587 0.0329751 -0.0453795 -0.018 0.0311769 -0.0614 -0.018 0.0311769 -0.0293591 -0.0136587 0.0329751 -0.0453795 -0.00931748 0.0347733 -0.0614 -0.018 0.0311769 -0.0614 -0.0136587 0.0329751 -0.0453795 -0.013626 0.0329887 -0.0309315 -0.00931748 0.0347733 -0.0614 -0.0136587 0.0329751 -0.0453795 -0.0148082 0.032499 -0.030861 -0.013626 0.0329887 -0.0309315 -0.0136587 0.0329751 -0.0453795 0.036435 0.024999 -0.006425 0.034225 0.024999 -0.00130163 0.036935 0.024999 0.002151 0.036935 0.024999 0.002151 0.034225 0.024999 0.004324 0.0334599 0.024999 0.008169940000000001 0.034225 0.024999 -0.00130163 0.034225 0.024999 0.004324 0.0351975 0.024999 0.000872471 0.036935 0.024999 0.002151 0.034225 0.024999 -0.00130163 0.0351975 0.024999 0.000872471 0.034225 0.024999 0.004324 0.036935 0.024999 0.002151 0.0351975 0.024999 0.000872471 0.00931748 0.0347733 -0.0311017 0.013724 0.0329481 -0.0311616 0.0136587 0.0329751 -0.0462509 0.00931748 0.0347733 -0.0614 0.00931748 0.0347733 -0.0311017 0.0136587 0.0329751 -0.0462509 0.018 0.0311769 -0.0614 0.00931748 0.0347733 -0.0614 0.0136587 0.0329751 -0.0462509 0.013724 0.0329481 -0.0311616 0.018 0.0311769 -0.0614 0.0136587 0.0329751 -0.0462509 0 0.036 -0.0614 0.00931748 0.0347733 -0.0614 0.0254558 0.0254558 -0.0614 0.035443 -0.040001 0.010612 -0.00853601 -0.040001 -0.036002 0.036934 -0.040001 0.002152 0.036934 -0.040001 0.002152 0.036435 -0.040001 -0.006425 0.036935 0.024999 0.002151 0.02691 -0.040001 0.025391 0.020329 0.024999 0.030913 0.020329 -0.040001 0.030913 0.02691 -0.040001 0.025391 0.020329 -0.040001 0.030913 -0.00853601 -0.040001 -0.036002 0.03204 0.024999 0.0185 0.0320738 0.024999 0.0151374 0.0312352 0.024999 0.019353 0.0320738 0.024999 0.0151374 0.03204 0.024999 0.0185 0.035443 0.024999 0.010612 0.035443 0.024999 0.010612 0.0334599 0.024999 0.008169940000000001 0.0320738 0.024999 0.0151374 0.036935 0.024999 0.002151 0.0334599 0.024999 0.008169940000000001 0.0345044 0.024999 0.008644209999999999 0.035443 0.024999 0.010612 0.036935 0.024999 0.002151 0.0345044 0.024999 0.008644209999999999 0.0334599 0.024999 0.008169940000000001 0.035443 0.024999 0.010612 0.0345044 0.024999 0.008644209999999999 -0.00931748 0.0347733 -0.0309839 -0.00875655 0.0348472 -0.0311134 -0.00465874 0.0353867 -0.046192 -0.00931748 0.0347733 -0.0614 -0.00931748 0.0347733 -0.0309839 -0.00465874 0.0353867 -0.046192 0 0.036 -0.0614 -0.00931748 0.0347733 -0.0614 -0.00465874 0.0353867 -0.046192 -0.00454796 0.0354012 -0.03143 0 0.036 -0.0614 -0.00465874 0.0353867 -0.046192 -0.00875655 0.0348472 -0.0311134 -0.00454796 0.0354012 -0.03143 -0.00465874 0.0353867 -0.046192 -0.0110676 0.0340484 -0.0310841 -0.00931748 0.0347733 -0.0309839 -0.00931748 0.0347733 -0.0614 -0.013626 0.0329887 -0.0309315 -0.0110676 0.0340484 -0.0310841 -0.00931748 0.0347733 -0.0614 0.00479949 0.0353681 -0.0316275 0.00513146 0.0353244 -0.0316426 0.00931748 0.0347733 -0.0614 0.008169249999999999 0.0349245 -0.0313513 0.00931748 0.0347733 -0.0311017 0.00931748 0.0347733 -0.0614 0.00513146 0.0353244 -0.0316426 0.008169249999999999 0.0349245 -0.0313513 0.00931748 0.0347733 -0.0614 1.33055e-09 0.036 -0.0313418 0.000453537 0.0359403 -0.031429 0.00465874 0.0353867 -0.0463709 0 0.036 -0.0614 1.33055e-09 0.036 -0.0313418 0.00465874 0.0353867 -0.0463709 0.00931748 0.0347733 -0.0614 0 0.036 -0.0614 0.00465874 0.0353867 -0.0463709 0.00479949 0.0353681 -0.0316275 0.00931748 0.0347733 -0.0614 0.00465874 0.0353867 -0.0463709 0.000453537 0.0359403 -0.031429 0.00479949 0.0353681 -0.0316275 0.00465874 0.0353867 -0.0463709 0.035443 -0.040001 0.010612 0.03204 -0.040001 0.0185 -0.00853601 -0.040001 -0.036002 0.035443 -0.040001 0.010612 0.036934 -0.040001 0.002152 0.035443 0.024999 0.010612 0.036935 0.024999 0.002151 0.035443 0.024999 0.010612 0.036934 -0.040001 0.002152 0.02691 0.024999 0.025391 0.03204 -0.040001 0.0185 0.0311733 0.024999 0.0196642 0.0311733 0.024999 0.0196642 0.03204 -0.040001 0.0185 0.03204 0.024999 0.0185 0.02691 0.024999 0.025391 0.020329 0.024999 0.030913 0.02691 -0.040001 0.025391 0.03204 -0.040001 0.0185 0.02691 -0.040001 0.025391 -0.00853601 -0.040001 -0.036002 0.03204 0.024999 0.0185 0.035443 -0.040001 0.010612 0.035443 0.024999 0.010612 -0.00454796 0.0354012 -0.03143 -0.00339446 0.0355531 -0.0315168 0 0.036 -0.0614 -0.00339446 0.0355531 -0.0315168 1.33055e-09 0.036 -0.0313418 0 0.036 -0.0614 0.03204 -0.040001 0.0185 0.035443 -0.040001 0.010612 0.03204 0.024999 0.0185 0.02691 -0.040001 0.025391 0.03204 -0.040001 0.0185 0.02691 0.024999 0.025391 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069

    -
    -
    - - - 0 0 0 - 1 0 0 0 - - true - - - -
    - - - - -0.001488 -0.108845 -0.164172 0.002111 -0.10942 -0.150588 -0.003402 -0.115569 -0.163868 0.001094 -0.08108700000000001 -0.154548 -0.000148996 -0.095447 -0.16415 -0.003025 -0.08194 -0.169916 -0.028807 -0.0833648 -0.269883 -0.0260095 -0.0726874 -0.273041 -0.0254514 -0.0873768 -0.273671 -0.017612 -0.06343500000000001 -0.16783 -0.031735 -0.06163 -0.165798 -0.029338 -0.061197 -0.149079 -0.068758 -0.118998 -0.233305 -0.059939 -0.107883 -0.232469 -0.056969 -0.113801 -0.232188 -0.041233 -0.049998 -0.177738 -0.057231 -0.049998 -0.190235 -0.047047 -0.049998 -0.178417 -0.035455 -0.094998 -0.268032 -0.042184 -0.094998 -0.262167 -0.03345 -0.080718 -0.265711 -0.057231 -0.049998 -0.190235 -0.044033 -0.049998 -0.223626 -0.051541 -0.049998 -0.221496 -0.003516 -0.066757 -0.136938 -0.0014 -0.074006 -0.1541 -0.006163 -0.067844 -0.153244 0.032223 -0.082122 -0.02238 0.029473 -0.076419 -0.019718 0.03148 -0.079376 -0.016907 0.029473 -0.076419 -0.019718 0.027925 -0.07441300000000001 -0.021615 0.031544 -0.039998 -0.016125 0.020278 -0.123345 -0.028527 0.024691 -0.137998 -0.024464 0.018239 -0.137998 -0.029872 -0.068758 -0.07099800000000001 -0.233304 -0.06231 -0.094998 -0.232694 -0.061713 -0.101573 -0.232638 0.03132 -0.111039 -0.017164 0.029564 -0.113644 -0.019588 0.031539 -0.110116 -0.019935 -0.069103 -0.094998 -0.18211 -0.068483 -0.088411 -0.18205 -0.07356699999999999 -0.118998 -0.182532 -0.022563 -0.065247 -0.201419 -0.023403 -0.049998 -0.197539 -0.023523 -0.064305 -0.197932 -0.022774 -0.137998 -0.02658 -0.013414 -0.13189 -0.032243 -0.013446 -0.137998 -0.032316 0.031876 -0.080175 -0.016158 0.035402 -0.039998 -0.00747301 0.033206 -0.08286200000000001 -0.013636 -0.028931 -0.094998 -0.27299 -0.033653 -0.094998 -0.269585 -0.029842 -0.080358 -0.268227 -0.059939 -0.107883 -0.232469 -0.057071 -0.107012 -0.239238 -0.056969 -0.113801 -0.232188 0.035016 -0.08812399999999999 -0.009014019999999999 0.032223 -0.082122 -0.02238 0.033572 -0.08360099999999999 -0.012943 0.00154202 -0.131335 -0.060324 -0.013414 -0.13189 -0.032243 -0.012814 -0.13337 -0.057215 -0.036792 -0.125578 -0.240488 -0.037126 -0.124813 -0.24216 -0.035081 -0.127396 -0.235407 -0.06231 -0.094998 -0.232694 -0.057071 -0.107012 -0.239238 -0.061713 -0.101573 -0.232638 -0.028807 -0.102997 -0.269883 -0.0291896 -0.102998 -0.269154 -0.0305964 -0.102997 -0.269722 -0.016268 -0.067998 -0.21901 -0.0151932 -0.067998 -0.218602 -0.016268 -0.057998 -0.21901 -0.00468 -0.07505100000000001 -0.169678 -0.003025 -0.08194 -0.169916 -0.007637 -0.082319 -0.18461 0.016263 -0.131398 -0.280992 0.008374009999999999 -0.131398 -0.283984 0.016263 -0.057998 -0.280992 -0.034747 -0.102998 -0.249047 -0.03788 -0.102998 -0.246961 -0.0357192 -0.102998 -0.253002 -0.006163 -0.067844 -0.153244 -0.0014 -0.074006 -0.1541 -0.00468 -0.07505100000000001 -0.169678 -0.0260095 -0.115038 -0.273041 -0.0266445 -0.102997 -0.272324 -0.024783 -0.102997 -0.274717 0.01403 -0.12392 -0.063029 0.00154202 -0.131335 -0.060324 -0.011323 -0.130169 -0.118162 -0.061464 -0.07099800000000001 -0.209841 -0.07356699999999999 -0.07099800000000001 -0.182532 -0.062369 -0.07099800000000001 -0.20209 -0.009834000000000001 -0.077057 -0.213119 -0.012724 -0.076705 -0.209545 -0.009162 -0.08319500000000001 -0.212779 -0.013686 -0.067998 -0.217787 -0.010793 -0.07091600000000001 -0.216706 -0.00884017 -0.067998 -0.216193 -0.054037 -0.08229 -0.091492 -0.048222 -0.07156700000000001 -0.09278500000000001 -0.053559 -0.071121 -0.126929 -0.047047 -0.049998 -0.178417 -0.052157 -0.049998 -0.181269 -0.046303 -0.062916 -0.178326 -0.046949 -0.107107 -0.253978 -0.049442 -0.094998 -0.254344 -0.048554 -0.094998 -0.255301 0.031539 -0.110116 -0.019935 0.033408 -0.106873 -0.013307 0.032042 -0.109598 -0.01583 -0.045891 -0.126901 -0.157101 -0.058648 -0.118944 -0.171066 -0.047993 -0.126464 -0.17232 0.032723 -0.131398 -0.262412 0.034742 -0.057998 -0.25422 0.034742 -0.131398 -0.25422 -0.034747 -0.0608632 -0.250001 -0.034747 -0.057998 -0.245782 -0.034747 -0.057998 -0.25422 -0.011323 -0.130169 -0.118162 0.00154202 -0.131335 -0.060324 -0.025099 -0.132149 -0.115228 -0.0197401 -0.060498 -0.221406 -0.023212 -0.057998 -0.223803 -0.01974 -0.062998 -0.221406 -0.021233 -0.0636 -0.183487 -0.029147 -0.062151 -0.185728 -0.031137 -0.061966 -0.183063 -0.057662 -0.049998 -0.216656 -0.051541 -0.049998 -0.221496 -0.053931 -0.068025 -0.219959 -0.06231 -0.094998 -0.232694 -0.058675 -0.08124099999999999 -0.234455 -0.058828 -0.094998 -0.240143 -0.010793 -0.07091600000000001 -0.216706 -0.012418 -0.071588 -0.214274 -0.010009 -0.07188899999999999 -0.216485 -0.01322 -0.08273999999999999 -0.204899 -0.012316 -0.08247400000000001 -0.198331 -0.012348 -0.09540999999999999 -0.20183 -0.032728 -0.131398 -0.262412 -0.032728 -0.102998 -0.262412 -0.0312109 -0.102998 -0.265303 -0.023212 -0.057998 -0.223803 -2.99964e-06 -0.0579979 -0.285001 -0.028807 -0.057998 -0.230119 0.023357 -0.111167 -0.065049 0.019315 -0.118087 -0.06417299999999999 0.00568601 -0.117233 -0.121784 -0.0344719 -0.067998 -0.244666 -0.0337375 -0.062998 -0.241686 -0.034747 -0.057998 -0.245782 -0.031735 -0.06163 -0.165798 -0.046303 -0.062916 -0.178326 -0.044694 -0.06277199999999999 -0.163934 -0.023212 -0.057998 -0.223803 -0.0197401 -0.060498 -0.221406 -0.016268 -0.057998 -0.21901 -0.06334099999999999 -0.119187 -0.232981 -0.054278 -0.117226 -0.231933 -0.0544271 -0.119498 -0.232738 0.027925 -0.07441300000000001 -0.021615 0.025455 -0.071586 -0.024275 0.031544 -0.039998 -0.016125 0.034742 -0.131398 -0.245782 0.032723 -0.057998 -0.23759 0.032723 -0.131398 -0.23759 -0.035803 -0.108542 -0.00859101 -0.030235 -0.12028 -0.017474 -0.033607 -0.112586 -0.00902201 -0.014746 -0.067998 -0.216628 -0.015557 -0.067998 -0.215638 -0.012418 -0.071588 -0.214274 -0.036966 -0.102998 -0.258815 -0.036911 -0.114414 -0.258801 -0.036116 -0.111791 -0.261823 -0.022497 -0.049998 -0.20529 -0.022563 -0.065247 -0.201419 -0.02251 -0.06550499999999999 -0.20529 -0.0307675 -0.117198 -0.233855 -0.0319859 -0.102998 -0.236176 -0.032728 -0.102998 -0.23759 -0.00370299 -0.062147 -0.102663 -0.0137 -0.060008 -0.065689 0.00428401 -0.062021 -0.069631 -0.019807 -0.102998 -0.21757 -0.021122 -0.12593 -0.218412 -0.022862 -0.12675 -0.219763 -0.009162 -0.08319500000000001 -0.212779 -0.012724 -0.076705 -0.209545 -0.012034 -0.082993 -0.209343 -0.057094 -0.07038999999999999 -0.162155 -0.044694 -0.06277199999999999 -0.163934 -0.058697 -0.07023500000000001 -0.180422 -0.00891 -0.107254 -0.21306 -0.008725 -0.09539 -0.21254 -0.011576 -0.095397 -0.209183 0.003933 -0.09546499999999999 -0.151245 0.002111 -0.10942 -0.150588 0.002275 -0.095455 -0.156935 -0.044547 -0.08257 -0.041831 -0.042229 -0.071954 -0.059438 -0.047727 -0.082469 -0.058234 -0.040037 -0.124841 -0.23872 -0.0423461 -0.119877 -0.245385 -0.042263 -0.117494 -0.250094 -0.0335584 -0.102998 -0.259043 -0.0339658 -0.102998 -0.25739 -0.036966 -0.102998 -0.258815 -0.025578 -0.127553 -0.188988 -0.010933 -0.121115 -0.176687 -0.022363 -0.127685 -0.17534 -0.028807 -0.131398 -0.230119 -0.032728 -0.131398 -0.23759 -0.008378999999999999 -0.131398 -0.283984 0.019976 -0.067373 -0.037929 0.022974 -0.06915499999999999 -0.026468 0.025455 -0.071586 -0.024275 -0.016268 -0.131398 -0.21901 -0.008378999999999999 -0.131398 -0.283984 -0.008378999999999999 -0.131398 -0.216018 -0.017284 -0.094997 -0.280436 -0.021795 -0.094998 -0.277775 -0.025963 -0.094998 -0.2751 -0.046622 -0.126471 -0.220648 -0.0500441 -0.123165 -0.226155 -0.0511948 -0.122623 -0.223052 -0.062692 -0.08193499999999999 -0.143086 -0.067456 -0.094998 -0.160678 -0.06519 -0.094998 -0.142662 -0.0344719 -0.067998 -0.244666 -0.032728 -0.067998 -0.23759 -0.0337375 -0.062998 -0.241686 -0.0204416 -0.067998 -0.221891 -0.022266 -0.067998 -0.22315 -0.024636 -0.067998 -0.221068 -0.029873 -0.039998 -0.018243 -0.034048 -0.039998 -0.008119009999999999 0.024691 -0.039998 -0.024464 -0.012316 -0.08247400000000001 -0.198331 -0.011416 -0.095416 -0.197055 -0.012348 -0.09540999999999999 -0.20183 -0.013686 -0.067998 -0.217787 -0.014746 -0.067998 -0.216628 -0.012418 -0.071588 -0.214274 -0.028807 -0.102997 -0.269883 -0.0307675 -0.117198 -0.266147 -0.0291896 -0.102998 -0.269154 0.016263 -0.057998 -0.21901 0.008373 -0.057998 -0.216018 0.008374009999999999 -0.131398 -0.216018 -0.002018 -0.095441 -0.169715 -0.001488 -0.108845 -0.164172 -0.005313 -0.108449 -0.177352 0.033206 -0.039998 0.014953 0.034981 -0.039998 0.010695 0.024691 -0.039998 -0.024464 -0.032728 -0.0763397 -0.262412 -0.033234 -0.07478029999999999 -0.260359 -0.0331411 -0.07301580000000001 -0.260736 0.018877 -0.137998 0.031087 0.023298 -0.137998 0.028256 0.018876 -0.039998 0.031088 -0.058828 -0.094998 -0.240143 -0.058675 -0.08124099999999999 -0.234455 -0.052093 -0.08112999999999999 -0.246067 -0.013229 -0.075809 -0.19835 -0.012316 -0.08247400000000001 -0.198331 -0.01322 -0.08273999999999999 -0.204899 -0.016268 -0.057998 -0.280992 -0.008378999999999999 -0.131398 -0.283984 -0.017284 -0.094997 -0.280436 -0.014048 -0.114524 -0.201854 -0.013114 -0.108058 -0.201814 -0.009605000000000001 -0.108348 -0.189741 -0.0235251 -0.0995163 -0.275846 -0.024783 -0.102997 -0.274717 -0.028332 -0.102997 -0.27231 -0.03788 -0.102998 -0.246961 -0.034747 -0.102998 -0.247697 -0.034747 -0.102998 -0.247212 -0.022266 -0.067998 -0.22315 -0.023212 -0.067998 -0.223803 -0.024636 -0.067998 -0.221068 -0.008943 -0.068842 -0.169065 -0.008795000000000001 -0.075515 -0.184517 -0.012684 -0.069286 -0.184201 -0.060239 -0.07099800000000001 -0.194583 -0.057231 -0.068227 -0.190235 -0.057231 -0.049998 -0.190235 -0.034747 -0.131398 -0.25422 -0.034747 -0.131398 -0.245782 -0.034747 -0.117198 -0.250001 0.028802 -0.057998 -0.230119 0.023207 -0.057998 -0.223803 0.028802 -0.131398 -0.230119 -0.014243 -0.063067 -0.151789 -0.017612 -0.06343500000000001 -0.16783 -0.029338 -0.061197 -0.149079 -0.0320424 -0.0768882 -0.263718 -0.032728 -0.0763397 -0.262412 -0.0310716 -0.0699446 -0.265568 -0.023523 -0.064305 -0.197932 -0.016665 -0.06974900000000001 -0.198437 -0.017073 -0.070427 -0.205294 -0.032728 -0.067998 -0.23759 -0.033834 -0.067998 -0.232697 -0.0321938 -0.067998 -0.236572 -0.059219 -0.119502 -0.181032 -0.06192 -0.118998 -0.181429 -0.061919 -0.116225 -0.181428 -0.006693 -0.077352 -0.215648 -0.005627 -0.08337899999999999 -0.215459 -0.0047623 -0.07911310000000001 -0.215472 -0.014048 -0.114524 -0.201854 -0.012303 -0.113728 -0.210533 -0.013114 -0.108058 -0.201814 -0.0189548 -0.102998 -0.220865 -0.016268 -0.102998 -0.21901 -0.0180375 -0.102998 -0.219217 -0.0137 -0.060008 -0.065689 -0.020843 -0.060114 -0.098861 -0.031196 -0.062566 -0.061855 0.027792 -0.039998 0.024268 0.031112 -0.039998 0.019976 0.024691 -0.039998 -0.024464 -0.012684 -0.069286 -0.184201 -0.008795000000000001 -0.075515 -0.184517 -0.013229 -0.075809 -0.19835 0.035503 -0.137998 -0.00716101 0.033408 -0.106873 -0.013307 0.034883 -0.102449 -0.00945201 -0.010797 -0.115038 -0.189686 -0.014048 -0.114524 -0.201854 -0.009605000000000001 -0.108348 -0.189741 -0.0337375 -0.06550690000000001 -0.258316 -0.0337375 -0.0617524 -0.258316 -0.032728 -0.057998 -0.262412 -0.0530965 -0.122945 -0.213171 -0.050376 -0.126442 -0.204039 -0.0547976 -0.123013 -0.204317 0.021022 -0.071631 -0.055785 0.019976 -0.067373 -0.037929 0.025148 -0.073194 -0.03896 -0.027461 -0.127109 -0.202655 -0.014708 -0.120982 -0.189504 -0.025578 -0.127553 -0.188988 -0.0439799 -0.120915 -0.241308 -0.040037 -0.124841 -0.23872 -0.0430425 -0.123603 -0.236991 -0.03788 -0.102998 -0.246961 -0.035087 -0.102998 -0.235405 -0.037778 -0.122727 -0.246416 -0.015557 -0.067998 -0.215638 -0.014746 -0.067998 -0.216628 -0.024636 -0.067998 -0.221068 -0.060239 -0.07099800000000001 -0.194583 -0.059517 -0.07099800000000001 -0.181201 -0.058697 -0.07023500000000001 -0.180422 0.025406 -0.118766 -0.024322 0.025371 -0.117444 -0.034582 0.027101 -0.116799 -0.022508 0.033541 -0.095485 -0.031703 0.029084 -0.08015 -0.039744 0.0320145 -0.08767129999999999 -0.031062 0.010922 -0.062035 -0.036126 0.008041009999999999 -0.06154 -0.033737 0.010685 -0.062075 -0.033096 -0.040674 -0.10718 -0.260584 -0.036911 -0.114414 -0.258801 -0.036116 -0.111791 -0.261823 -0.039489 -0.094998 -0.011609 -0.040722 -0.08209 -0.025833 -0.042425 -0.094998 -0.023232 0.024691 -0.039998 -0.024464 0.020278 -0.039998 -0.028527 0.018239 -0.039998 -0.029872 -0.036282 -0.049998 -0.22272 -0.044032 -0.06316099999999999 -0.223615 -0.044033 -0.049998 -0.223626 -0.034039 -0.106035 -0.26681 -0.034606 -0.107636 -0.265703 -0.032964 -0.102998 -0.268909 -0.012303 -0.113728 -0.210533 -0.010007 -0.113411 -0.213347 -0.009391 -0.111495 -0.213179 -0.019536 -0.128174 -0.161298 -0.016895 -0.128882 -0.147054 -0.032859 -0.130041 -0.159176 -0.034606 -0.107636 -0.265703 -0.040674 -0.10718 -0.260584 -0.042184 -0.094998 -0.262167 -0.017612 -0.06343500000000001 -0.16783 -0.014243 -0.063067 -0.151789 -0.008943 -0.068842 -0.169065 0.002111 -0.10942 -0.150588 -0.001488 -0.108845 -0.164172 0.002275 -0.095455 -0.156935 -0.0123235 -0.117198 -0.217514 -0.008378999999999999 -0.131398 -0.216018 -0.0114314 -0.102998 -0.217176 -0.0582432 -0.0883525 -0.108554 -0.060132 -0.08210099999999999 -0.125616 -0.059351 -0.094998 -0.107759 -0.008378999999999999 -0.057998 -0.216018 -2.99964e-06 -0.0579979 -0.285001 -0.016268 -0.057998 -0.21901 -0.037626 -0.123668 -0.244667 -0.037778 -0.122727 -0.246416 -0.042263 -0.117494 -0.250094 -0.00279198 -0.132618 -0.034791 -0.00280198 -0.137998 -0.034889 -0.013446 -0.137998 -0.032316 -0.058675 -0.08124099999999999 -0.234455 -0.051395 -0.069561 -0.231297 -0.045077 -0.06940499999999999 -0.241524 -0.059219 -0.119502 -0.181032 -0.0588453 -0.119509 -0.182979 -0.058413 -0.119945 -0.185262 -0.055771 -0.069714 -0.220433 -0.056496 -0.069824 -0.217583 -0.053931 -0.068025 -0.219959 -0.008725 -0.09539 -0.21254 -0.004855 -0.095383 -0.215339 -0.009162 -0.08319500000000001 -0.212779 -0.029338 -0.061197 -0.149079 -0.031735 -0.06163 -0.165798 -0.043426 -0.062724 -0.146549 -0.046622 -0.126471 -0.220648 -0.038989 -0.129258 -0.203352 -0.050376 -0.126442 -0.204039 -0.033234 -0.07478029999999999 -0.260359 -0.032728 -0.0763397 -0.262412 -0.03345 -0.080718 -0.265711 -0.044694 -0.06277199999999999 -0.163934 -0.052113 -0.06517000000000001 -0.181323 -0.058697 -0.07023500000000001 -0.180422 -0.056918 -0.108547 -0.108453 -0.059351 -0.094998 -0.107759 -0.062363 -0.094998 -0.125247 -0.0280447 -0.067998 -0.229259 -0.028807 -0.067998 -0.230119 -0.0271378 -0.067998 -0.226882 -0.06411 -0.10808 -0.1542 -0.062009 -0.108246 -0.138661 -0.06519 -0.094998 -0.142662 0.026925 -0.09553 -0.064763 0.023357 -0.111167 -0.065049 0.024673 -0.095531 -0.074061 0.031961 -0.095501 -0.040298 0.029418 -0.110682 -0.035372 0.029163 -0.09553 -0.05552 -0.051541 -0.049998 -0.221496 -0.051439 -0.066625 -0.221282 -0.053931 -0.068025 -0.219959 -0.061464 -0.07099800000000001 -0.209841 -0.058172 -0.07099800000000001 -0.216032 -0.056939 -0.07099800000000001 -0.220732 -0.032964 -0.102998 -0.268909 -0.030964 -0.102997 -0.270424 -0.0305964 -0.102997 -0.269722 -0.00891 -0.107254 -0.21306 -0.012303 -0.113728 -0.210533 -0.009391 -0.111495 -0.213179 -0.0271378 -0.067998 -0.226882 -0.033834 -0.067998 -0.232697 -0.024636 -0.067998 -0.221068 -0.058697 -0.07023500000000001 -0.180422 -0.052941 -0.065599 -0.181985 -0.055699 -0.06725100000000001 -0.185688 -0.014708 -0.120982 -0.189504 -0.017449 -0.120256 -0.202053 -0.010797 -0.115038 -0.189686 -0.026485 -0.062779 -0.215759 -0.025205 -0.06349100000000001 -0.213649 -0.024362 -0.063959 -0.21226 -0.056496 -0.069824 -0.217583 -0.058172 -0.07099800000000001 -0.216032 -0.057662 -0.049998 -0.216656 -0.02816 -0.049998 -0.188077 -0.057231 -0.049998 -0.190235 -0.031012 -0.049998 -0.182966 -0.068483 -0.088411 -0.18205 -0.069103 -0.094998 -0.18211 -0.066376 -0.081721 -0.179787 -0.032728 -0.131398 -0.262412 -0.034747 -0.131398 -0.25422 -0.0337375 -0.117198 -0.258316 -0.003516 -0.066757 -0.136938 -0.00370299 -0.062147 -0.102663 0.002578 -0.065321 -0.104062 -0.03489 -0.039998 0.00279899 -0.032318 -0.137998 0.013442 -0.032318 -0.039998 0.013443 -0.028074 -0.06254899999999999 -0.045339 -0.0137 -0.060008 -0.065689 -0.031196 -0.062566 -0.061855 -0.0570217 -0.121279 -0.192606 -0.050376 -0.126442 -0.204039 -0.049958 -0.126383 -0.187824 -0.07356699999999999 -0.07099800000000001 -0.182532 -0.068483 -0.088411 -0.18205 -0.066635 -0.08205900000000001 -0.181875 -0.00812 -0.074265 -0.215957 -0.0090645 -0.0746965 -0.215135 -0.009834000000000001 -0.077057 -0.213119 0.024691 -0.039998 -0.024464 -0.020283 -0.039998 0.028524 -0.009214989999999999 -0.039998 0.034258 -0.019773 -0.124949 -0.217628 -0.019807 -0.102998 -0.21757 -0.00891 -0.107254 -0.21306 -0.034747 -0.067998 -0.24674 -0.034747 -0.0637284 -0.250001 -0.034747 -0.067998 -0.247212 -0.034747 -0.0637284 -0.250001 -0.034747 -0.067998 -0.24674 -0.034747 -0.067998 -0.245782 -0.035565 -0.128969 -0.217398 -0.027461 -0.127109 -0.202655 -0.038989 -0.129258 -0.203352 0.008373 -0.057998 -0.216018 -2.99964e-06 -0.0579979 -0.285001 -2.99582e-06 -0.057998 -0.215001 -0.0204923 -0.09732010000000001 -0.278076 -0.023212 -0.0986773 -0.276199 -0.021795 -0.094998 -0.277775 -0.039228 -0.072168 -0.042965 -0.031196 -0.062566 -0.061855 -0.042229 -0.071954 -0.059438 0.035788 -0.09544 -0.00580301 0.0357 -0.09740500000000001 -0.006256 0.031539 -0.110116 -0.019935 -0.042184 -0.094998 -0.262167 -0.045625 -0.094998 -0.258458 -0.043563 -0.080983 -0.256573 0.018876 -0.039998 0.031088 0.023298 -0.137998 0.028256 0.023298 -0.039998 0.028256 0.024691 -0.039998 -0.024464 -0.03489 -0.039998 0.00279899 -0.032318 -0.039998 0.013443 -0.01322 -0.08273999999999999 -0.204899 -0.012348 -0.09540999999999999 -0.20183 -0.012343 -0.0954 -0.207618 -0.016895 -0.128882 -0.147054 -0.011323 -0.130169 -0.118162 -0.030429 -0.13079 -0.144536 -0.032728 -0.067998 -0.23759 -0.0321938 -0.067998 -0.236572 -0.032728 -0.057998 -0.23759 -0.037904 -0.118998 -0.252736 -0.037626 -0.117517 -0.254781 -0.036911 -0.114414 -0.258801 -0.034747 -0.0637284 -0.250001 -0.034747 -0.0608632 -0.250001 -0.034747 -0.057998 -0.25422 -0.028807 -0.0833648 -0.269883 -0.0254514 -0.0873768 -0.273671 -0.0269275 -0.08767800000000001 -0.272574 -0.0293392 -0.067998 -0.268869 -0.0291173 -0.07068140000000001 -0.269292 -0.0294052 -0.0795941 -0.268743 -0.0151932 -0.067998 -0.218602 -0.0123235 -0.0659771 -0.217514 -0.016268 -0.057998 -0.21901 -0.00415147 -0.0748472 -0.215505 -0.006693 -0.077352 -0.215648 -0.0047623 -0.07911310000000001 -0.215472 0.018239 -0.137998 -0.029872 0.00811601 -0.137998 -0.034047 0.018147 -0.12471 -0.029694 0.011027 -0.065356 -0.071107 0.016863 -0.071426 -0.07238600000000001 0.008484 -0.07136099999999999 -0.105372 -0.0049804 -0.088686 -0.177374 -0.004483 -0.095432 -0.177054 -0.007637 -0.082319 -0.18461 -0.061464 -0.049998 -0.209841 -0.062369 -0.049998 -0.20209 -0.057231 -0.049998 -0.190235 -0.033607 -0.112586 -0.00902201 -0.030235 -0.12028 -0.017474 -0.034048 -0.137998 -0.008119019999999999 0.029418 -0.110682 -0.035372 0.025371 -0.117444 -0.034582 0.019315 -0.118087 -0.06417299999999999 0.00116801 -0.039998 0.036003 0.00116802 -0.137998 0.036003 0.00667102 -0.137998 0.035573 0.019976 -0.067373 -0.037929 0.021022 -0.071631 -0.055785 0.015328 -0.06553 -0.054574 -0.041227 -0.062847 -0.226878 -0.0367172 -0.0626169 -0.228912 -0.034819 -0.062778 -0.23491 0.019976 -0.067373 -0.037929 0.025455 -0.071586 -0.024275 0.027925 -0.07441300000000001 -0.021615 0.028802 -0.131398 -0.269883 0.032723 -0.131398 -0.262412 -0.008378999999999999 -0.131398 -0.283984 -0.0199652 -0.0921587 -0.27844 -0.0182832 -0.0924469 -0.279645 -0.017284 -0.094997 -0.280436 0.034742 -0.131398 -0.245782 0.034742 -0.057998 -0.245782 0.032723 -0.057998 -0.23759 -0.032728 -0.057998 -0.262412 -0.0306243 -0.067998 -0.26642 -0.0310716 -0.0699446 -0.265568 -0.010793 -0.07091600000000001 -0.216706 -0.010009 -0.07188899999999999 -0.216485 -0.00884017 -0.067998 -0.216193 -0.023212 -0.131398 -0.223803 -0.016268 -0.131398 -0.21901 -0.01974 -0.117198 -0.221406 0.034742 -0.057998 -0.25422 0.032723 -0.131398 -0.262412 0.032723 -0.057998 -0.262412 -0.037903 -0.12941 -0.1884 -0.025578 -0.127553 -0.188988 -0.022363 -0.127685 -0.17534 -0.028807 -0.131398 -0.269883 -0.0307675 -0.117198 -0.266147 -0.028807 -0.102997 -0.269883 0.008374009999999999 -0.131398 -0.283984 0.016263 -0.131398 -0.280992 -0.008378999999999999 -0.131398 -0.283984 -0.03788 -0.102998 -0.246961 -0.034747 -0.102998 -0.249047 -0.034747 -0.102998 -0.247697 -0.010127 -0.060008 -0.049157 0.010922 -0.062035 -0.036126 0.008237009999999999 -0.061996 -0.053063 -0.0203629 -0.101282 -0.278166 -0.0204923 -0.09732010000000001 -0.278076 -0.017284 -0.094997 -0.280436 -0.037778 -0.122727 -0.246416 -0.035087 -0.102998 -0.235405 -0.035081 -0.127396 -0.235407 0.028802 -0.057998 -0.269883 0.023207 -0.057998 -0.276199 -2.99964e-06 -0.0579979 -0.285001 -0.028807 -0.0833648 -0.269883 -0.029842 -0.080358 -0.268227 -0.0294276 -0.0808743 -0.268701 -0.021122 -0.12593 -0.218412 -0.019807 -0.102998 -0.21757 -0.019773 -0.124949 -0.217628 -0.0297872 -0.062998 -0.231987 -0.028807 -0.067998 -0.230119 -0.028807 -0.057998 -0.230119 -0.016268 -0.131398 -0.280992 -0.0203629 -0.101282 -0.278166 -0.017284 -0.094997 -0.280436 0.029084 -0.08015 -0.039744 0.032223 -0.082122 -0.02238 0.0320145 -0.08767129999999999 -0.031062 0.017841 -0.137998 0.03175 0.018877 -0.137998 0.031087 0.017841 -0.039998 0.031751 -0.023212 -0.131398 -0.223803 -0.028807 -0.131398 -0.230119 -0.008378999999999999 -0.131398 -0.283984 -0.033607 -0.112586 -0.00902201 -0.03489 -0.137998 0.00279898 -0.034887 -0.098269 0.00279799 0.033541 -0.095485 -0.031703 0.031961 -0.095501 -0.040298 0.029084 -0.08015 -0.039744 -0.049442 -0.094998 -0.254344 -0.052093 -0.08112999999999999 -0.246067 -0.043563 -0.080983 -0.256573 0.018877 -0.137998 0.031087 0.018876 -0.039998 0.031088 0.017841 -0.039998 0.031751 0.03541 -0.090421 -0.00747301 0.036247 -0.039998 0.000979986 0.035596 -0.0915 -0.00674901 -0.012418 -0.071588 -0.214274 -0.0145526 -0.0704231 -0.212954 -0.015534 -0.07106700000000001 -0.210269 -0.037982 -0.12146 -0.248769 -0.037904 -0.118998 -0.252736 -0.036966 -0.102998 -0.258815 -0.066635 -0.08205900000000001 -0.181875 -0.066376 -0.081721 -0.179787 -0.058697 -0.07023500000000001 -0.180422 -0.049958 -0.126383 -0.187824 -0.047993 -0.126464 -0.17232 -0.058413 -0.119945 -0.185262 -0.0337375 -0.117198 -0.241686 -0.0335092 -0.102998 -0.24076 -0.034747 -0.102998 -0.245782 -0.03489 -0.137998 0.00279898 -0.032318 -0.137998 0.013442 -0.034887 -0.098269 0.00279799 -0.0307675 -0.117198 -0.233855 -0.028807 -0.131398 -0.230119 -0.0303241 -0.102998 -0.23301 -0.022563 -0.065247 -0.201419 -0.023523 -0.064305 -0.197932 -0.017073 -0.070427 -0.205294 -0.0588453 -0.119509 -0.182979 -0.058648 -0.118944 -0.171066 -0.059219 -0.119502 -0.181032 -0.047047 -0.049998 -0.178417 -0.057231 -0.049998 -0.190235 -0.052157 -0.049998 -0.181269 -0.021233 -0.0636 -0.183487 -0.024351 -0.063566 -0.195196 -0.025697 -0.062902 -0.19274 -0.00365891 -0.0991905 -0.215317 -0.005196 -0.102998 -0.215389 -0.00240399 -0.102998 -0.215293 0.031112 -0.137998 0.019976 0.033206 -0.137998 0.014953 0.031112 -0.039998 0.019976 -0.034747 -0.057998 -0.245782 -0.0337375 -0.060498 -0.241686 -0.032728 -0.057998 -0.23759 -0.056918 -0.108547 -0.108453 -0.038299 -0.121013 -0.051695 -0.045698 -0.108799 -0.050092 -0.060239 -0.07099800000000001 -0.194583 -0.07356699999999999 -0.07099800000000001 -0.182532 -0.059517 -0.07099800000000001 -0.181201 -0.028807 -0.131398 -0.269883 -0.023212 -0.131398 -0.276199 -0.008378999999999999 -0.131398 -0.283984 -0.037626 -0.117517 -0.254781 -0.042263 -0.117494 -0.250094 -0.037904 -0.118998 -0.252736 -0.043659 -0.127535 -0.142076 -0.045891 -0.126901 -0.157101 -0.030429 -0.13079 -0.144536 -0.01672 -0.061015 -0.030618 -0.022773 -0.062583 -0.026579 -0.013446 -0.039998 -0.032316 -0.026582 -0.039998 0.022771 -0.026582 -0.137998 0.02277 -0.020283 -0.137998 0.028524 -0.041233 -0.049998 -0.177738 -0.035603 -0.049998 -0.179336 -0.057231 -0.049998 -0.190235 -0.037778 -0.122727 -0.246416 -0.037982 -0.12146 -0.248769 -0.042263 -0.117494 -0.250094 -0.011416 -0.095416 -0.197055 -0.013114 -0.108058 -0.201814 -0.012348 -0.09540999999999999 -0.20183 -0.029834 -0.120931 -0.018209 -0.030235 -0.12028 -0.017474 -0.031887 -0.120562 -0.023395 0.032723 -0.057998 -0.23759 0.028802 -0.131398 -0.230119 0.032723 -0.131398 -0.23759 -0.00812 -0.074265 -0.215957 -0.010009 -0.07188899999999999 -0.216485 -0.0090645 -0.0746965 -0.215135 -0.06689290000000001 -0.08831550000000001 -0.170419 -0.066376 -0.081721 -0.179787 -0.068189 -0.094998 -0.170106 0.035786 -0.094414 -0.00581501 0.035752 -0.093403 -0.00599601 0.036247 -0.039998 0.000979986 0.021022 -0.071631 -0.055785 0.025389 -0.079096 -0.056714 0.021367 -0.07895099999999999 -0.07337299999999999 -0.068758 -0.07099800000000001 -0.233304 -0.05443 -0.07099800000000001 -0.227973 -0.052737 -0.07099800000000001 -0.231787 -0.037626 -0.123668 -0.244667 -0.037778 -0.122727 -0.246416 -0.035081 -0.127396 -0.235407 0.012103 -0.095511 -0.123116 0.01049 -0.08722149999999999 -0.12288 0.012978 -0.078932 -0.106368 -0.031735 -0.06163 -0.165798 -0.034101 -0.061824 -0.180269 -0.035656 -0.061843 -0.17945 -0.020283 -0.039998 0.028524 -0.026582 -0.039998 0.022771 -0.020283 -0.137998 0.028524 -0.023212 -0.102998 -0.223803 -0.0189548 -0.102998 -0.220865 -0.0216408 -0.102998 -0.221424 -0.008815999999999999 -0.10605 -0.213038 -0.00891 -0.107254 -0.21306 -0.008725 -0.09539 -0.21254 0.008373 -0.057998 -0.216018 -0.00240399 -0.102998 -0.215293 -1.99507e-06 -0.131398 -0.215001 -0.0249051 -0.102998 -0.225714 -0.0243759 -0.102998 -0.225117 -0.028859 -0.102998 -0.225278 -0.009214989999999999 -0.039998 0.034258 0.00116802 -0.137998 0.036003 0.00116801 -0.039998 0.036003 -0.022773 -0.062583 -0.026579 -0.034356 -0.071198 -0.0271 -0.030053 -0.070437 -0.017043 -0.0246108 -0.062998 -0.225382 -0.023212 -0.057998 -0.223803 -0.0260095 -0.062998 -0.226961 -0.040037 -0.124841 -0.23872 -0.0423461 -0.119877 -0.245385 -0.0439799 -0.120915 -0.241308 -0.012684 -0.069286 -0.184201 -0.013229 -0.075809 -0.19835 -0.016665 -0.06974900000000001 -0.198437 -0.038987 -0.062292 -0.223391 -0.036282 -0.049998 -0.22272 -0.036328 -0.062118 -0.222573 -0.022774 -0.039998 -0.02658 -0.029873 -0.039998 -0.018243 0.024691 -0.039998 -0.024464 -0.033834 -0.067998 -0.232697 -0.037185 -0.065271 -0.242165 -0.034819 -0.062778 -0.23491 -0.023212 -0.0986773 -0.276199 -0.0203629 -0.101282 -0.278166 -0.0235251 -0.0995163 -0.275846 -0.028074 -0.06254899999999999 -0.045339 -0.013388 -0.060519 -0.03217 -0.00653799 -0.060086 -0.034225 -0.068758 -0.07099800000000001 -0.233304 -0.07356699999999999 -0.07099800000000001 -0.182532 -0.05443 -0.07099800000000001 -0.227973 -0.011416 -0.095416 -0.197055 -0.008803 -0.095419 -0.18977 -0.009605000000000001 -0.108348 -0.189741 -0.00281699 -0.060073 -0.034888 0.008115010000000001 -0.039998 -0.034047 0.00358101 -0.060637 -0.034817 -0.054701 -0.119633 -0.140021 -0.043659 -0.127535 -0.142076 -0.038544 -0.128686 -0.112365 0.00667501 -0.039998 0.035572 0.012177 -0.137998 0.0342 0.012176 -0.039998 0.0342 -0.019807 -0.102998 -0.21757 -0.0189548 -0.102998 -0.220865 -0.0180375 -0.102998 -0.219217 -0.032859 -0.130041 -0.159176 -0.047993 -0.126464 -0.17232 -0.035318 -0.129524 -0.173813 -0.032728 -0.131398 -0.23759 -0.032728 -0.102998 -0.23759 -0.0335092 -0.102998 -0.24076 -0.0260095 -0.117198 -0.226961 -0.028807 -0.131398 -0.230119 -0.023212 -0.131398 -0.223803 -0.008378999999999999 -0.131398 -0.283984 0.008374009999999999 -0.131398 -0.216018 -1.99507e-06 -0.131398 -0.215001 -0.023212 -0.057998 -0.223803 -0.023212 -0.067998 -0.223803 -0.022266 -0.067998 -0.22315 -0.008943 -0.068842 -0.169065 -0.00468 -0.07505100000000001 -0.169678 -0.008795000000000001 -0.075515 -0.184517 0.016863 -0.071426 -0.07238600000000001 0.012978 -0.078932 -0.106368 0.008484 -0.07136099999999999 -0.105372 -0.044033 -0.049998 -0.223626 -0.051439 -0.066625 -0.221282 -0.051541 -0.049998 -0.221496 -0.049958 -0.126383 -0.187824 -0.037903 -0.12941 -0.1884 -0.035318 -0.129524 -0.173813 -0.0332327 -0.062998 -0.239638 -0.032728 -0.067998 -0.23759 -0.032728 -0.057998 -0.23759 -0.01974 -0.062998 -0.221406 -0.018004 -0.062998 -0.220208 -0.016268 -0.057998 -0.21901 -0.037126 -0.124813 -0.24216 -0.040037 -0.124841 -0.23872 -0.042263 -0.117494 -0.250094 -0.00365891 -0.0991905 -0.215317 -0.00212134 -0.0981031 -0.215258 -0.004855 -0.095383 -0.215339 -0.060132 -0.08210099999999999 -0.125616 -0.06519 -0.094998 -0.142662 -0.062363 -0.094998 -0.125247 -0.066541 -0.1079 -0.181867 -0.067271 -0.106211 -0.181936 -0.07356699999999999 -0.118998 -0.182532 -0.065009 -0.111448 -0.181721 -0.06192 -0.118998 -0.181429 -0.061919 -0.116225 -0.181428 -0.057231 -0.049998 -0.190235 -0.051541 -0.049998 -0.221496 -0.057662 -0.049998 -0.216656 -0.045891 -0.126901 -0.157101 -0.056819 -0.119225 -0.155361 -0.058648 -0.118944 -0.171066 -0.019536 -0.128174 -0.161298 -0.022363 -0.127685 -0.17534 -0.00780799 -0.12149 -0.163167 -0.036481 -0.067998 -0.249142 -0.034747 -0.067998 -0.250643 -0.034747 -0.0692173 -0.252549 -0.066376 -0.081721 -0.179787 -0.0662321 -0.0849767 -0.170419 -0.064813 -0.081788 -0.16105 -0.044275 -0.124806 -0.232674 -0.037155 -0.128008 -0.229005 -0.044452 -0.126287 -0.226534 -0.025963 -0.094998 -0.2751 -0.021795 -0.094998 -0.277775 -0.028332 -0.102997 -0.27231 -0.0330232 -0.07311429999999999 -0.261214 -0.0331411 -0.07301580000000001 -0.260736 -0.032728 -0.057998 -0.262412 0.036177 -0.039998 0.00428799 0.036247 -0.137998 0.0009799819999999999 0.036247 -0.039998 0.000979986 -0.040674 -0.10718 -0.260584 -0.046949 -0.107107 -0.253978 -0.045625 -0.094998 -0.258458 -2.99964e-06 -0.0579979 -0.285001 0.023207 -0.057998 -0.276199 0.016263 -0.057998 -0.280992 0.023207 -0.057998 -0.276199 0.016263 -0.131398 -0.280992 0.016263 -0.057998 -0.280992 -0.005313 -0.108449 -0.177352 -0.010797 -0.115038 -0.189686 -0.009605000000000001 -0.108348 -0.189741 -0.033653 -0.094998 -0.269585 -0.034039 -0.106035 -0.26681 -0.032964 -0.102998 -0.268909 0.00116802 -0.137998 0.036003 -0.009214989999999999 -0.039998 0.034258 -0.008135979999999999 -0.137998 0.034439 0.032223 -0.082122 -0.02238 0.03148 -0.079376 -0.016907 0.031876 -0.080175 -0.016158 -0.018004 -0.062998 -0.220208 -0.01974 -0.062998 -0.221406 -0.016268 -0.067998 -0.21901 0.034349 -0.095469 -0.02239 0.032223 -0.082122 -0.02238 0.035788 -0.09544 -0.00580301 0.020761 -0.09553200000000001 -0.090212 0.012978 -0.078932 -0.106368 0.0188977 -0.087232 -0.0903089 -0.051972 -0.11736 -0.23662 -0.0423461 -0.119877 -0.245385 -0.0544271 -0.119498 -0.232738 0.025371 -0.117444 -0.034582 0.031539 -0.110116 -0.019935 0.027101 -0.116799 -0.022508 0.012978 -0.078932 -0.106368 0.005089 -0.08015600000000001 -0.138659 0.008484 -0.07136099999999999 -0.105372 -0.029515 -0.062234 -0.218869 -0.026485 -0.062779 -0.215759 -0.022509 -0.06329799999999999 -0.219383 -0.005196 -0.102998 -0.215389 -0.008725 -0.09539 -0.21254 -0.006925 -0.102998 -0.214239 0.036177 -0.137998 0.00428798 0.034981 -0.039998 0.010695 0.034981 -0.137998 0.010695 -0.0337375 -0.0617524 -0.258316 -0.0337375 -0.06550690000000001 -0.258316 -0.034747 -0.057998 -0.25422 -0.00212134 -0.0981031 -0.215258 0.008373 -0.057998 -0.216018 -0.00212157 -0.08560189999999999 -0.215258 -0.030964 -0.102997 -0.270424 -0.0282288 -0.102997 -0.270536 -0.028807 -0.102997 -0.269883 -0.028339 -0.062313 -0.188136 -0.027636 -0.062453 -0.190236 -0.02816 -0.049998 -0.188077 -0.008378999999999999 -0.131398 -0.283984 0.016263 -0.131398 -0.21901 0.008374009999999999 -0.131398 -0.216018 -0.057231 -0.049998 -0.190235 -0.035603 -0.049998 -0.179336 -0.031012 -0.049998 -0.182966 -0.0333971 -0.067998 -0.259697 -0.0337375 -0.06550690000000001 -0.258316 -0.032728 -0.057998 -0.262412 -0.03323 -0.07566299999999999 -0.010959 -0.029873 -0.039998 -0.018243 -0.030053 -0.070437 -0.017043 -0.054764 -0.094998 -0.083718 -0.049463 -0.094998 -0.056063 -0.047727 -0.082469 -0.058234 -0.0041905 -0.117198 -0.21551 -0.005196 -0.102998 -0.215389 -0.008378999999999999 -0.102998 -0.216018 -0.0307675 -0.117198 -0.266147 -0.032728 -0.131398 -0.262412 -0.0312109 -0.102998 -0.265303 -0.030964 -0.102997 -0.270424 -0.028807 -0.102997 -0.269883 -0.0305964 -0.102997 -0.269722 -0.056496 -0.069824 -0.217583 -0.057662 -0.049998 -0.216656 -0.053931 -0.068025 -0.219959 -0.025205 -0.06349100000000001 -0.213649 -0.024362 -0.063959 -0.21226 -0.015534 -0.07106700000000001 -0.210269 -0.046949 -0.107107 -0.253978 -0.052437 -0.107055 -0.246859 -0.049442 -0.094998 -0.254344 -0.036206 -0.081192 -0.010436 -0.03323 -0.07566299999999999 -0.010959 -0.030053 -0.070437 -0.017043 -0.068758 -0.07099800000000001 -0.233304 -0.056871 -0.076153 -0.232179 -0.059887 -0.08204 -0.232464 -0.005196 -0.102998 -0.215389 -0.00365891 -0.0991905 -0.215317 -0.004855 -0.095383 -0.215339 0.029473 -0.076419 -0.019718 0.032223 -0.082122 -0.02238 0.029164 -0.076123 -0.021844 -0.004483 -0.095432 -0.177054 -0.006972 -0.09542399999999999 -0.184465 -0.007637 -0.082319 -0.18461 -0.041496 -0.06280570000000001 -0.225134 -0.038987 -0.062292 -0.223391 -0.041227 -0.062847 -0.226878 -0.059887 -0.08204 -0.232464 -0.058675 -0.08124099999999999 -0.234455 -0.061707 -0.088404 -0.232637 -0.0204416 -0.067998 -0.221891 -0.024636 -0.067998 -0.221068 -0.0196111 -0.067998 -0.221317 0.035402 -0.039998 -0.00747301 0.035016 -0.08812399999999999 -0.009014019999999999 0.033572 -0.08360099999999999 -0.012943 -0.008725 -0.09539 -0.21254 -0.008815999999999999 -0.102998 -0.213038 -0.006925 -0.102998 -0.214239 -0.028807 -0.131398 -0.269883 -0.0260095 -0.115038 -0.273041 -0.023212 -0.131398 -0.276199 0.011027 -0.065356 -0.071107 0.008237009999999999 -0.061996 -0.053063 0.015328 -0.06553 -0.054574 -0.0367172 -0.0626169 -0.228912 -0.032237 -0.061986 -0.222914 -0.034819 -0.062778 -0.23491 -0.034828 -0.094998 0.00348899 -0.035803 -0.108542 -0.00859101 -0.034887 -0.098269 0.00279799 -0.057094 -0.07038999999999999 -0.162155 -0.062692 -0.08193499999999999 -0.143086 -0.05547 -0.07073400000000001 -0.144385 -0.039228 -0.072168 -0.042965 -0.028074 -0.06254899999999999 -0.045339 -0.031196 -0.062566 -0.061855 -0.029834 -0.120931 -0.018209 -0.031887 -0.120562 -0.023395 -0.023427 -0.127181 -0.025713 -0.023403 -0.049998 -0.197539 -0.027205 -0.049998 -0.190725 -0.023523 -0.064305 -0.197932 -0.00516071 -0.085313 -0.177317 -0.0049804 -0.088686 -0.177374 -0.007637 -0.082319 -0.18461 -0.036966 -0.102998 -0.258815 -0.036116 -0.111791 -0.261823 -0.032964 -0.102998 -0.268909 0.029084 -0.08015 -0.039744 0.025389 -0.079096 -0.056714 0.025148 -0.073194 -0.03896 -0.047488 -0.117421 -0.24361 -0.046949 -0.107107 -0.253978 -0.042263 -0.117494 -0.250094 -0.051972 -0.11736 -0.23662 -0.057071 -0.107012 -0.239238 -0.052437 -0.107055 -0.246859 0.0357 -0.09740500000000001 -0.006256 0.035508 -0.099208 -0.00713901 0.031539 -0.110116 -0.019935 -0.061713 -0.101573 -0.232638 -0.057071 -0.107012 -0.239238 -0.059939 -0.107883 -0.232469 0.012103 -0.095511 -0.123116 0.007499 -0.095485 -0.139004 0.005089 -0.08015600000000001 -0.138659 -0.03345 -0.080718 -0.265711 -0.043563 -0.080983 -0.256573 -0.0385065 -0.0764526 -0.256684 -0.034747 -0.102998 -0.25422 -0.0357192 -0.102998 -0.253002 -0.036966 -0.102998 -0.258815 -0.041227 -0.062847 -0.226878 -0.032237 -0.061986 -0.222914 -0.0367172 -0.0626169 -0.228912 -0.026485 -0.062779 -0.215759 -0.025205 -0.06349100000000001 -0.213649 -0.022509 -0.06329799999999999 -0.219383 -0.044032 -0.06316099999999999 -0.223615 -0.036282 -0.049998 -0.22272 -0.038987 -0.062292 -0.223391 -0.029147 -0.062151 -0.185728 -0.028339 -0.062313 -0.188136 -0.02816 -0.049998 -0.188077 -0.008378999999999999 -0.131398 -0.283984 0.034742 -0.131398 -0.245782 0.032723 -0.131398 -0.23759 -0.0028281 -0.0782692 -0.215344 -0.005627 -0.08337899999999999 -0.215459 -0.00212157 -0.08560189999999999 -0.215258 0.008041009999999999 -0.06154 -0.033737 0.008115010000000001 -0.039998 -0.034047 0.018239 -0.039998 -0.029872 -0.034747 -0.131398 -0.245782 -0.034747 -0.102998 -0.245782 -0.034747 -0.102998 -0.247212 -0.062369 -0.07099800000000001 -0.20209 -0.07356699999999999 -0.07099800000000001 -0.182532 -0.060239 -0.07099800000000001 -0.194583 -0.031735 -0.06163 -0.165798 -0.041251 -0.062174 -0.1779 -0.042891 -0.06232 -0.177697 0.01049 -0.08722149999999999 -0.12288 0.005089 -0.08015600000000001 -0.138659 0.012978 -0.078932 -0.106368 -0.033653 -0.094998 -0.269585 -0.03345 -0.080718 -0.265711 -0.029842 -0.080358 -0.268227 -0.041251 -0.062174 -0.1779 -0.031735 -0.06163 -0.165798 -0.038327 -0.061912 -0.178263 -0.068758 -0.07099800000000001 -0.233304 -0.061707 -0.088404 -0.232637 -0.06231 -0.094998 -0.232694 -0.034101 -0.061824 -0.180269 -0.031735 -0.06163 -0.165798 -0.021233 -0.0636 -0.183487 -0.003516 -0.066757 -0.136938 0.00173001 -0.072867 -0.137987 -0.0014 -0.074006 -0.1541 -0.032237 -0.061986 -0.222914 -0.024835 -0.062582 -0.221237 -0.027767 -0.062132 -0.224056 0.022974 -0.06915499999999999 -0.026468 0.019976 -0.067373 -0.037929 0.020278 -0.06684 -0.028527 -0.025378 -0.127937 -0.221716 -0.019807 -0.102998 -0.21757 -0.022862 -0.12675 -0.219763 -0.043563 -0.080983 -0.256573 -0.052093 -0.08112999999999999 -0.246067 -0.037131 -0.06919599999999999 -0.250607 -0.037626 -0.123668 -0.244667 -0.037126 -0.124813 -0.24216 -0.042263 -0.117494 -0.250094 0.00811601 -0.137998 -0.034047 0.0134718 -0.126915 -0.032658 0.018147 -0.12471 -0.029694 -0.054037 -0.08229 -0.091492 -0.060132 -0.08210099999999999 -0.125616 -0.0582432 -0.0883525 -0.108554 -0.042263 -0.117494 -0.250094 -0.046949 -0.107107 -0.253978 -0.037626 -0.117517 -0.254781 0.027792 -0.039998 0.024268 0.031112 -0.137998 0.019976 0.031112 -0.039998 0.019976 0.008237009999999999 -0.061996 -0.053063 0.011027 -0.065356 -0.071107 0.00428401 -0.062021 -0.069631 0.020278 -0.039998 -0.028527 0.020278 -0.06684 -0.028527 0.018239 -0.039998 -0.029872 -0.03489 -0.137998 0.00279898 -0.033607 -0.112586 -0.00902201 -0.034048 -0.137998 -0.008119019999999999 -0.0337503 -0.0725065 -0.258264 -0.033234 -0.07478029999999999 -0.260359 -0.037131 -0.06919599999999999 -0.250607 -0.01974 -0.117198 -0.221406 -0.016268 -0.131398 -0.21901 -0.0189548 -0.102998 -0.220865 0.035752 -0.093403 -0.00599601 0.032223 -0.082122 -0.02238 0.035596 -0.0915 -0.00674901 -0.037261 -0.115569 -0.257471 -0.036911 -0.114414 -0.258801 -0.040674 -0.10718 -0.260584 -0.0260095 -0.115038 -0.273041 -0.028807 -0.131398 -0.269883 -0.0266445 -0.102997 -0.272324 -0.0217294 -0.102997 -0.277222 -0.024783 -0.102997 -0.274717 -0.0235251 -0.0995163 -0.275846 -0.0349329 -0.102998 -0.241309 -0.03788 -0.102998 -0.246961 -0.034747 -0.102998 -0.245782 -0.052737 -0.07099800000000001 -0.231787 -0.055771 -0.069714 -0.220433 -0.051395 -0.069561 -0.231297 -0.028807 -0.067998 -0.230119 -0.0280447 -0.067998 -0.229259 -0.028807 -0.057998 -0.230119 -0.028807 -0.067998 -0.230119 -0.033834 -0.067998 -0.232697 -0.0271378 -0.067998 -0.226882 -0.062369 -0.049998 -0.20209 -0.062369 -0.07099800000000001 -0.20209 -0.060239 -0.049998 -0.194583 -0.032318 -0.137998 0.013442 -0.026582 -0.137998 0.02277 -0.032318 -0.039998 0.013443 0.032723 -0.131398 -0.262412 0.034742 -0.131398 -0.25422 -0.008378999999999999 -0.131398 -0.283984 -0.00812 -0.074265 -0.215957 -0.009834000000000001 -0.077057 -0.213119 -0.006693 -0.077352 -0.215648 -0.014048 -0.114524 -0.201854 -0.017449 -0.120256 -0.202053 -0.01521 -0.119156 -0.211406 0.028802 -0.057998 -0.230119 0.028802 -0.131398 -0.230119 0.032723 -0.057998 -0.23759 -0.068483 -0.088411 -0.18205 -0.066376 -0.081721 -0.179787 -0.066635 -0.08205900000000001 -0.181875 0.028802 -0.131398 -0.230119 -0.008378999999999999 -0.131398 -0.283984 0.032723 -0.131398 -0.23759 -0.041227 -0.062847 -0.226878 -0.038987 -0.062292 -0.223391 -0.036328 -0.062118 -0.222573 -0.003025 -0.08194 -0.169916 -0.002018 -0.095441 -0.169715 -0.004483 -0.095432 -0.177054 0.025406 -0.118766 -0.024322 0.024691 -0.137998 -0.024464 0.022954 -0.121125 -0.026485 -0.002018 -0.095441 -0.169715 -0.005313 -0.108449 -0.177352 -0.004483 -0.095432 -0.177054 -0.013229 -0.075809 -0.19835 -0.008795000000000001 -0.075515 -0.184517 -0.012316 -0.08247400000000001 -0.198331 0.020104 -0.123114 -0.033553 0.00154202 -0.131335 -0.060324 0.01403 -0.12392 -0.063029 -0.053931 -0.068025 -0.219959 -0.051439 -0.066625 -0.221282 -0.051395 -0.069561 -0.231297 -0.016268 -0.057998 -0.280992 -2.99964e-06 -0.0579979 -0.285001 -0.008378999999999999 -0.057998 -0.283984 -0.051439 -0.066625 -0.221282 -0.047715 -0.06462900000000001 -0.222981 -0.051395 -0.069561 -0.231297 -0.037155 -0.128008 -0.229005 -0.040037 -0.124841 -0.23872 -0.032823 -0.128474 -0.230849 -0.003025 -0.08194 -0.169916 -0.00516071 -0.085313 -0.177317 -0.007637 -0.082319 -0.18461 0.033541 -0.095485 -0.031703 0.034349 -0.095469 -0.02239 0.031539 -0.110116 -0.019935 -0.037261 -0.115569 -0.257471 -0.037626 -0.117517 -0.254781 -0.040674 -0.10718 -0.260584 0.024691 -0.039998 -0.024464 0.022974 -0.06915499999999999 -0.026468 0.020278 -0.06684 -0.028527 -0.0137 -0.060008 -0.065689 -0.00370299 -0.062147 -0.102663 -0.020843 -0.060114 -0.098861 -0.044547 -0.08257 -0.041831 -0.039228 -0.072168 -0.042965 -0.042229 -0.071954 -0.059438 -0.044452 -0.126287 -0.226534 -0.031908 -0.128859 -0.223879 -0.035565 -0.128969 -0.217398 -0.028807 -0.102998 -0.230119 -0.0253768 -0.102998 -0.226247 -0.028859 -0.102998 -0.225278 -0.027205 -0.049998 -0.190725 -0.057231 -0.049998 -0.190235 -0.02816 -0.049998 -0.188077 -0.00240399 -0.102998 -0.215293 -0.005196 -0.102998 -0.215389 -0.0041905 -0.117198 -0.21551 -0.035565 -0.128969 -0.217398 -0.031908 -0.128859 -0.223879 -0.021122 -0.12593 -0.218412 -0.037982 -0.12146 -0.248769 -0.03788 -0.102998 -0.246961 -0.037778 -0.122727 -0.246416 -0.00501499 -0.122031 -0.149263 -0.019536 -0.128174 -0.161298 -0.00780799 -0.12149 -0.163167 -0.034048 -0.137998 -0.008119019999999999 -0.029834 -0.120931 -0.018209 -0.029873 -0.137998 -0.018243 -0.06411 -0.10808 -0.1542 -0.056819 -0.119225 -0.155361 -0.054701 -0.119633 -0.140021 -0.02251 -0.06550499999999999 -0.20529 -0.022563 -0.065247 -0.201419 -0.017073 -0.070427 -0.205294 -0.0282288 -0.102997 -0.270536 -0.028807 -0.131398 -0.269883 -0.028807 -0.102997 -0.269883 -0.014048 -0.114524 -0.201854 -0.01521 -0.119156 -0.211406 -0.012303 -0.113728 -0.210533 -0.00415147 -0.0748472 -0.215505 -0.00614141 -0.07561610000000001 -0.215678 -0.006693 -0.077352 -0.215648 -0.034747 -0.102998 -0.245782 -0.03788 -0.102998 -0.246961 -0.034747 -0.102998 -0.247212 -0.035583 -0.06309099999999999 -0.23666 -0.037185 -0.065271 -0.242165 -0.045077 -0.06940499999999999 -0.241524 0.010685 -0.062075 -0.033096 0.008041009999999999 -0.06154 -0.033737 0.018239 -0.039998 -0.029872 -0.01974 -0.062998 -0.221406 -0.0204416 -0.067998 -0.221891 -0.0196111 -0.067998 -0.221317 -0.006693 -0.077352 -0.215648 -0.009834000000000001 -0.077057 -0.213119 -0.009162 -0.08319500000000001 -0.212779 -0.024351 -0.063566 -0.195196 -0.016665 -0.06974900000000001 -0.198437 -0.023523 -0.064305 -0.197932 -0.042229 -0.071954 -0.059438 -0.048222 -0.07156700000000001 -0.09278500000000001 -0.047727 -0.082469 -0.058234 -0.012814 -0.13337 -0.057215 -0.013414 -0.13189 -0.032243 -0.023427 -0.127181 -0.025713 -0.0337375 -0.062998 -0.241686 -0.0332327 -0.062998 -0.239638 -0.032728 -0.057998 -0.23759 -0.025578 -0.127553 -0.188988 -0.014708 -0.120982 -0.189504 -0.010933 -0.121115 -0.176687 -0.027636 -0.062453 -0.190236 -0.025697 -0.062902 -0.19274 -0.027205 -0.049998 -0.190725 -0.054278 -0.117226 -0.231933 -0.051972 -0.11736 -0.23662 -0.0544271 -0.119498 -0.232738 -0.010127 -0.060008 -0.049157 -0.00281699 -0.060073 -0.034888 0.00358101 -0.060637 -0.034817 0.024691 -0.039998 -0.024464 0.035402 -0.039998 -0.00747301 0.033809 -0.039998 -0.012393 -0.023212 -0.057998 -0.223803 -0.0246108 -0.062998 -0.225382 -0.023212 -0.067998 -0.223803 -0.049463 -0.094998 -0.056063 -0.044547 -0.08257 -0.041831 -0.047727 -0.082469 -0.058234 -0.035565 -0.128969 -0.217398 -0.038989 -0.129258 -0.203352 -0.046622 -0.126471 -0.220648 -0.012538 -0.102998 -0.217595 -0.0119847 -0.102998 -0.217043 -0.0120057 -0.102998 -0.216492 -0.067271 -0.106211 -0.181936 -0.06579 -0.107966 -0.170226 -0.06864199999999999 -0.100682 -0.182065 -0.062692 -0.08193499999999999 -0.143086 -0.060132 -0.08210099999999999 -0.125616 -0.05547 -0.07073400000000001 -0.144385 -0.03735 -0.06260599999999999 -0.09519900000000001 -0.048222 -0.07156700000000001 -0.09278500000000001 -0.042229 -0.071954 -0.059438 -0.052437 -0.107055 -0.246859 -0.054341 -0.094998 -0.247534 -0.049442 -0.094998 -0.254344 -0.0253768 -0.102998 -0.226247 -0.0260095 -0.117198 -0.226961 -0.023212 -0.131398 -0.223803 -0.035565 -0.128969 -0.217398 -0.024551 -0.126404 -0.21416 -0.027461 -0.127109 -0.202655 -0.028807 -0.067998 -0.230119 -0.0297872 -0.062998 -0.231987 -0.0307675 -0.062998 -0.233855 -0.032964 -0.102998 -0.268909 -0.033653 -0.094998 -0.269585 -0.028931 -0.094998 -0.27299 -0.0337375 -0.062998 -0.241686 -0.032728 -0.067998 -0.23759 -0.0332327 -0.062998 -0.239638 -0.0312109 -0.102998 -0.265303 -0.032964 -0.102998 -0.268909 -0.0291896 -0.102998 -0.269154 -0.058172 -0.07099800000000001 -0.216032 -0.056496 -0.069824 -0.217583 -0.055771 -0.069714 -0.220433 -0.036116 -0.111791 -0.261823 -0.040674 -0.10718 -0.260584 -0.0370101 -0.109485 -0.262435 -0.034101 -0.061824 -0.180269 -0.021233 -0.0636 -0.183487 -0.031983 -0.061887 -0.18193 -0.0341418 -0.067998 -0.239829 -0.032728 -0.067998 -0.23759 -0.0344719 -0.067998 -0.244666 -0.0196111 -0.067998 -0.221317 -0.0189327 -0.067998 -0.219552 -0.016268 -0.067998 -0.21901 -0.052157 -0.049998 -0.181269 -0.050569 -0.06436799999999999 -0.180088 -0.047357 -0.0631 -0.178521 -0.034747 -0.0703906 -0.25422 -0.037131 -0.06919599999999999 -0.250607 -0.034747 -0.0694588 -0.252902 -0.0497035 -0.123371 -0.227009 -0.047487 -0.124698 -0.226704 -0.046622 -0.126471 -0.220648 0.011027 -0.065356 -0.071107 0.002578 -0.065321 -0.104062 0.00428401 -0.062021 -0.069631 0.009158009999999999 -0.110451 -0.122524 -0.000383994 -0.116163 -0.150124 0.002111 -0.10942 -0.150588 -0.03788 -0.102998 -0.246961 -0.037982 -0.12146 -0.248769 -0.036966 -0.102998 -0.258815 0.0134718 -0.126915 -0.032658 0.020104 -0.123114 -0.033553 0.018147 -0.12471 -0.029694 -0.028807 -0.102998 -0.230119 -0.0299961 -0.102998 -0.230342 -0.0303241 -0.102998 -0.23301 0.00154202 -0.131335 -0.060324 -0.00279198 -0.132618 -0.034791 -0.013414 -0.13189 -0.032243 -0.0123235 -0.0659771 -0.217514 -0.008378999999999999 -0.057998 -0.216018 -0.0123235 -0.0619875 -0.217514 -0.023212 -0.131398 -0.276199 -0.0260095 -0.115038 -0.273041 -0.0217294 -0.102997 -0.277222 -0.032728 -0.057998 -0.23759 -0.0307674 -0.060498 -0.233855 -0.028807 -0.057998 -0.230119 0.001094 -0.08108700000000001 -0.154548 0.00173001 -0.072867 -0.137987 0.005089 -0.08015600000000001 -0.138659 -0.016268 -0.057998 -0.21901 -0.0123235 -0.0659771 -0.217514 -0.0123235 -0.0619875 -0.217514 0.032223 -0.082122 -0.02238 0.029084 -0.08015 -0.039744 0.029164 -0.076123 -0.021844 -2.99964e-06 -0.0579979 -0.285001 -0.023212 -0.057998 -0.276199 -0.028807 -0.057998 -0.269883 0.032223 -0.082122 -0.02238 0.033541 -0.095485 -0.031703 0.0320145 -0.08767129999999999 -0.031062 -0.066376 -0.081721 -0.179787 -0.06689290000000001 -0.08831550000000001 -0.170419 -0.0662321 -0.0849767 -0.170419 -0.044275 -0.124806 -0.232674 -0.040037 -0.124841 -0.23872 -0.037155 -0.128008 -0.229005 -0.00280299 -0.039998 -0.034889 -0.013446 -0.039998 -0.032316 0.024691 -0.039998 -0.024464 0.025371 -0.117444 -0.034582 0.029418 -0.110682 -0.035372 0.031539 -0.110116 -0.019935 -0.032728 -0.0763397 -0.262412 -0.0330232 -0.07311429999999999 -0.261214 -0.032728 -0.057998 -0.262412 -0.0304037 -0.0679979 -0.233161 -0.033834 -0.067998 -0.232697 -0.0301314 -0.067998 -0.232642 0.020761 -0.09553200000000001 -0.090212 0.009158009999999999 -0.110451 -0.122524 0.01636 -0.09552099999999999 -0.106937 -0.034747 -0.102998 -0.249047 -0.034747 -0.131398 -0.245782 -0.034747 -0.102998 -0.247697 0.032223 -0.082122 -0.02238 0.03541 -0.090421 -0.00747301 0.035596 -0.0915 -0.00674901 -0.012303 -0.113728 -0.210533 -0.00891 -0.107254 -0.21306 -0.011532 -0.107588 -0.210271 -0.0337375 -0.06550690000000001 -0.258316 -0.034325 -0.067998 -0.255932 -0.034747 -0.057998 -0.25422 -0.054341 -0.094998 -0.247534 -0.052093 -0.08112999999999999 -0.246067 -0.049442 -0.094998 -0.254344 -0.012538 -0.102998 -0.217595 -0.019807 -0.102998 -0.21757 -0.0144225 -0.102998 -0.21831 0.00071001 -0.123015 -0.120724 0.01403 -0.12392 -0.063029 -0.011323 -0.130169 -0.118162 0.023357 -0.111167 -0.065049 0.00568601 -0.117233 -0.121784 0.009158009999999999 -0.110451 -0.122524 -0.01521 -0.119156 -0.211406 -0.024551 -0.126404 -0.21416 -0.013038 -0.118998 -0.214307 -0.031887 -0.120562 -0.023395 -0.026806 -0.129703 -0.054184 -0.023427 -0.127181 -0.025713 -0.022363 -0.127685 -0.17534 -0.019536 -0.128174 -0.161298 -0.035318 -0.129524 -0.173813 0.029163 -0.09553 -0.05552 0.029418 -0.110682 -0.035372 0.023357 -0.111167 -0.065049 0.032723 -0.131398 -0.262412 0.028802 -0.131398 -0.269883 0.032723 -0.057998 -0.262412 -0.058172 -0.07099800000000001 -0.216032 -0.055771 -0.069714 -0.220433 -0.056939 -0.07099800000000001 -0.220732 -0.023212 -0.057998 -0.276199 -2.99964e-06 -0.0579979 -0.285001 -0.016268 -0.057998 -0.280992 0.008115010000000001 -0.039998 -0.034047 0.008041009999999999 -0.06154 -0.033737 0.00358101 -0.060637 -0.034817 -0.028807 -0.131398 -0.230119 -0.028807 -0.102998 -0.230119 -0.0303241 -0.102998 -0.23301 -0.014243 -0.063067 -0.151789 -0.026849 -0.060719 -0.132272 -0.01083 -0.06265800000000001 -0.135477 -0.025697 -0.062902 -0.19274 -0.024351 -0.063566 -0.195196 -0.023523 -0.064305 -0.197932 -0.034747 -0.067998 -0.24674 -0.03788 -0.067998 -0.246961 -0.034747 -0.067998 -0.245782 -0.033143 -0.062024 -0.221268 -0.032237 -0.061986 -0.222914 -0.041227 -0.062847 -0.226878 0.00154202 -0.131335 -0.060324 -0.012814 -0.13337 -0.057215 -0.025099 -0.132149 -0.115228 -0.034747 -0.0637284 -0.250001 -0.034747 -0.067998 -0.249231 -0.034747 -0.067998 -0.247212 -0.036206 -0.081192 -0.010436 -0.034356 -0.071198 -0.0271 -0.040722 -0.08209 -0.025833 -0.013686 -0.067998 -0.217787 -0.012418 -0.071588 -0.214274 -0.010793 -0.07091600000000001 -0.216706 0.00116801 -0.039998 0.036003 0.00667102 -0.137998 0.035573 0.00667501 -0.039998 0.035572 -0.005313 -0.108449 -0.177352 -0.00675999 -0.115159 -0.17718 -0.010797 -0.115038 -0.189686 -0.039489 -0.094998 -0.011609 -0.042425 -0.094998 -0.023232 -0.039448 -0.108685 -0.021917 -0.033834 -0.067998 -0.232697 -0.03788 -0.067998 -0.246961 -0.037185 -0.065271 -0.242165 -0.0335092 -0.102998 -0.24076 -0.0349329 -0.102998 -0.241309 -0.034747 -0.102998 -0.245782 -0.0028281 -0.0782692 -0.215344 -0.00415147 -0.0748472 -0.215505 -0.0047623 -0.07911310000000001 -0.215472 -0.011576 -0.095397 -0.209183 -0.012343 -0.0954 -0.207618 -0.011532 -0.107588 -0.210271 -0.034048 -0.137998 -0.008119019999999999 -0.030235 -0.12028 -0.017474 -0.029834 -0.120931 -0.018209 -0.016268 -0.102998 -0.21901 -0.019807 -0.102998 -0.21757 -0.0180375 -0.102998 -0.219217 -0.008378999999999999 -0.131398 -0.283984 -1.99507e-06 -0.131398 -0.215001 -0.008378999999999999 -0.131398 -0.216018 -0.032237 -0.061986 -0.222914 -0.029836 -0.06207 -0.226616 -0.034819 -0.062778 -0.23491 -0.029873 -0.039998 -0.018243 -0.034326 -0.08115799999999999 -0.00534201 -0.034048 -0.039998 -0.008119009999999999 -0.026582 -0.039998 0.022771 0.024691 -0.039998 -0.024464 -0.032318 -0.039998 0.013443 -0.045698 -0.108799 -0.050092 -0.039448 -0.108685 -0.021917 -0.046465 -0.094998 -0.04153 -0.034747 -0.067998 -0.247212 -0.034747 -0.067998 -0.249231 -0.0363135 -0.067998 -0.248096 0.002111 -0.10942 -0.150588 -0.000383994 -0.116163 -0.150124 -0.003402 -0.115569 -0.163868 0.036177 -0.039998 0.00428799 0.036247 -0.039998 0.000979986 0.024691 -0.039998 -0.024464 -0.0334227 -0.102998 -0.259593 -0.0337375 -0.117198 -0.258316 -0.0335584 -0.102998 -0.259043 -0.034747 -0.067998 -0.245782 -0.0344719 -0.067998 -0.244666 -0.034747 -0.057998 -0.245782 -0.010009 -0.07188899999999999 -0.216485 -0.012418 -0.071588 -0.214274 -0.009834000000000001 -0.077057 -0.213119 -0.061464 -0.07099800000000001 -0.209841 -0.061464 -0.049998 -0.209841 -0.058172 -0.07099800000000001 -0.216032 -0.00675999 -0.115159 -0.17718 -0.014708 -0.120982 -0.189504 -0.010797 -0.115038 -0.189686 -0.059517 -0.07099800000000001 -0.181201 -0.063614 -0.07618 -0.181589 -0.058697 -0.07023500000000001 -0.180422 0.024691 -0.039998 -0.024464 0.00667501 -0.039998 0.035572 0.012176 -0.039998 0.0342 -0.0530965 -0.122945 -0.213171 -0.046622 -0.126471 -0.220648 -0.0513867 -0.122741 -0.222061 0.024691 -0.039998 -0.024464 0.00116801 -0.039998 0.036003 0.00667501 -0.039998 0.035572 -0.026849 -0.060719 -0.132272 -0.020843 -0.060114 -0.098861 -0.01083 -0.06265800000000001 -0.135477 -0.052737 -0.07099800000000001 -0.231787 -0.051395 -0.069561 -0.231297 -0.058675 -0.08124099999999999 -0.234455 -0.00501499 -0.122031 -0.149263 -0.016895 -0.128882 -0.147054 -0.019536 -0.128174 -0.161298 -0.0282288 -0.102997 -0.270536 -0.030964 -0.102997 -0.270424 -0.028332 -0.102997 -0.27231 -0.040722 -0.08209 -0.025833 -0.039228 -0.072168 -0.042965 -0.044547 -0.08257 -0.041831 -0.032728 -0.057998 -0.23759 -0.0307675 -0.062998 -0.233855 -0.0307674 -0.060498 -0.233855 -0.0337375 -0.117198 -0.241686 -0.032728 -0.131398 -0.23759 -0.0335092 -0.102998 -0.24076 -0.064813 -0.081788 -0.16105 -0.067456 -0.094998 -0.160678 -0.062692 -0.08193499999999999 -0.143086 -0.060132 -0.08210099999999999 -0.125616 -0.053559 -0.071121 -0.126929 -0.05547 -0.07073400000000001 -0.144385 -0.03489 -0.039998 0.00279899 -0.034828 -0.094998 0.00348899 -0.032318 -0.137998 0.013442 -0.047715 -0.06462900000000001 -0.222981 -0.051439 -0.066625 -0.221282 -0.044033 -0.049998 -0.223626 -0.054037 -0.08229 -0.091492 -0.0582432 -0.0883525 -0.108554 -0.059351 -0.094998 -0.107759 0.023207 -0.057998 -0.223803 0.028802 -0.057998 -0.230119 -2.99964e-06 -0.0579979 -0.285001 -0.035087 -0.102998 -0.235405 -0.0319859 -0.102998 -0.236176 -0.0317456 -0.102998 -0.235718 -0.0339658 -0.102998 -0.25739 -0.034747 -0.131398 -0.25422 -0.034747 -0.102998 -0.25422 0.029564 -0.113644 -0.019588 0.03132 -0.111039 -0.017164 0.031545 -0.137998 -0.016125 0.036247 -0.137998 0.0009799819999999999 0.0357 -0.09740500000000001 -0.006256 0.035788 -0.09544 -0.00580301 -0.005313 -0.108449 -0.177352 -0.006972 -0.09542399999999999 -0.184465 -0.004483 -0.095432 -0.177054 0.007499 -0.095485 -0.139004 0.003933 -0.09546499999999999 -0.151245 0.005089 -0.08015600000000001 -0.138659 -0.004855 -0.095383 -0.215339 -0.005627 -0.08337899999999999 -0.215459 -0.009162 -0.08319500000000001 -0.212779 -0.0119847 -0.102998 -0.217043 -0.012538 -0.102998 -0.217595 -0.0114314 -0.102998 -0.217176 -0.022834 -0.065247 -0.207674 -0.024362 -0.063959 -0.21226 -0.02251 -0.06550499999999999 -0.20529 0.034742 -0.057998 -0.25422 0.034742 -0.057998 -0.245782 0.034742 -0.131398 -0.25422 -2.99582e-06 -0.057998 -0.215001 -0.00653584 -0.07414800000000001 -0.215794 -0.00415147 -0.0748472 -0.215505 -0.022509 -0.06329799999999999 -0.219383 -0.025205 -0.06349100000000001 -0.213649 -0.015534 -0.07106700000000001 -0.210269 0.025455 -0.071586 -0.024275 0.024691 -0.039998 -0.024464 0.031544 -0.039998 -0.016125 -0.0203629 -0.101282 -0.278166 -0.023212 -0.131398 -0.276199 -0.0217294 -0.102997 -0.277222 -0.035603 -0.049998 -0.179336 -0.031137 -0.061966 -0.183063 -0.031012 -0.049998 -0.182966 -0.0333971 -0.067998 -0.259697 -0.034325 -0.067998 -0.255932 -0.0337375 -0.06550690000000001 -0.258316 0.034981 -0.039998 0.010695 0.036177 -0.039998 0.00428799 0.024691 -0.039998 -0.024464 -0.064813 -0.081788 -0.16105 -0.057094 -0.07038999999999999 -0.162155 -0.058697 -0.07023500000000001 -0.180422 -0.019807 -0.102998 -0.21757 -0.028859 -0.102998 -0.225278 -0.0216408 -0.102998 -0.221424 -0.029515 -0.062234 -0.218869 -0.033143 -0.062024 -0.221268 -0.029468 -0.049998 -0.218918 -0.031908 -0.128859 -0.223879 -0.028827 -0.128679 -0.225307 -0.025378 -0.127937 -0.221716 -0.001488 -0.108845 -0.164172 -0.000148996 -0.095447 -0.16415 0.002275 -0.095455 -0.156935 -0.034747 -0.0692173 -0.252549 -0.034747 -0.067998 -0.250643 -0.034747 -0.067998 -0.252601 0.019976 -0.067373 -0.037929 0.010922 -0.062035 -0.036126 0.020278 -0.06684 -0.028527 -0.0312109 -0.102998 -0.265303 -0.032728 -0.102998 -0.262412 -0.0330778 -0.102998 -0.263984 -0.028807 -0.102998 -0.230119 -0.0260095 -0.117198 -0.226961 -0.0253768 -0.102998 -0.226247 -0.015557 -0.067998 -0.215638 -0.024835 -0.062582 -0.221237 -0.022509 -0.06329799999999999 -0.219383 -0.037131 -0.06919599999999999 -0.250607 -0.036481 -0.067998 -0.249142 -0.034747 -0.0692173 -0.252549 -0.0199652 -0.0921587 -0.27844 -0.0214921 -0.0925914 -0.277554 -0.0254514 -0.0873768 -0.273671 -0.067271 -0.106211 -0.181936 -0.06864199999999999 -0.100682 -0.182065 -0.07356699999999999 -0.118998 -0.182532 -0.002018 -0.095441 -0.169715 -0.000148996 -0.095447 -0.16415 -0.001488 -0.108845 -0.164172 0.005089 -0.08015600000000001 -0.138659 0.00173001 -0.072867 -0.137987 0.008484 -0.07136099999999999 -0.105372 -0.021122 -0.12593 -0.218412 -0.019773 -0.124949 -0.217628 -0.024551 -0.126404 -0.21416 -0.028807 -0.0833648 -0.269883 -0.028931 -0.094998 -0.27299 -0.029842 -0.080358 -0.268227 -0.06579 -0.107966 -0.170226 -0.056819 -0.119225 -0.155361 -0.06411 -0.10808 -0.1542 -0.0357192 -0.102998 -0.253002 -0.03788 -0.102998 -0.246961 -0.036966 -0.102998 -0.258815 0.034981 -0.039998 0.010695 0.033206 -0.039998 0.014953 0.034981 -0.137998 0.010695 -0.032823 -0.128474 -0.230849 -0.040037 -0.124841 -0.23872 -0.035081 -0.127396 -0.235407 -0.019043 -0.065294 -0.217116 -0.022509 -0.06329799999999999 -0.219383 -0.015534 -0.07106700000000001 -0.210269 -0.019807 -0.102998 -0.21757 -0.025378 -0.127937 -0.221716 -0.028859 -0.102998 -0.225278 -0.058697 -0.07023500000000001 -0.180422 -0.052113 -0.06517000000000001 -0.181323 -0.052941 -0.065599 -0.181985 0.034981 -0.137998 0.010695 0.033206 -0.039998 0.014953 0.033206 -0.137998 0.014953 0.035508 -0.099208 -0.00713901 0.034883 -0.102449 -0.00945201 0.031539 -0.110116 -0.019935 -0.036481 -0.067998 -0.249142 -0.034747 -0.067998 -0.249231 -0.034747 -0.067998 -0.250643 -0.034747 -0.0703906 -0.25422 -0.034325 -0.067998 -0.255932 -0.0337503 -0.0725065 -0.258264 0.023207 -0.057998 -0.223803 -2.99964e-06 -0.0579979 -0.285001 0.016263 -0.057998 -0.21901 -0.0547976 -0.123013 -0.204317 -0.050376 -0.126442 -0.204039 -0.0570217 -0.121279 -0.192606 -0.052093 -0.08112999999999999 -0.246067 -0.045077 -0.06940499999999999 -0.241524 -0.037131 -0.06919599999999999 -0.250607 -0.054701 -0.119633 -0.140021 -0.049668 -0.120374 -0.109996 -0.062009 -0.108246 -0.138661 -0.035603 -0.049998 -0.179336 -0.041233 -0.049998 -0.177738 -0.035656 -0.061843 -0.17945 0.009158009999999999 -0.110451 -0.122524 0.007499 -0.095485 -0.139004 0.012103 -0.095511 -0.123116 -0.015557 -0.067998 -0.215638 -0.0145526 -0.0704231 -0.212954 -0.012418 -0.071588 -0.214274 -0.022563 -0.065247 -0.201419 -0.022497 -0.049998 -0.20529 -0.023403 -0.049998 -0.197539 -0.028807 -0.057998 -0.269883 -0.0291173 -0.07068140000000001 -0.269292 -0.0293392 -0.067998 -0.268869 -0.067456 -0.094998 -0.160678 -0.06411 -0.10808 -0.1542 -0.06519 -0.094998 -0.142662 -0.0151932 -0.067998 -0.218602 -0.013686 -0.067998 -0.217787 -0.0123235 -0.0659771 -0.217514 0.008051020000000001 -0.129972 -0.033797 0.00154202 -0.131335 -0.060324 0.020104 -0.123114 -0.033553 -0.016268 -0.067998 -0.21901 -0.013686 -0.067998 -0.217787 -0.0151932 -0.067998 -0.218602 -0.0319859 -0.102998 -0.236176 -0.0307675 -0.117198 -0.233855 -0.0317456 -0.102998 -0.235718 -0.023212 -0.067998 -0.223803 -0.0271378 -0.067998 -0.226882 -0.024636 -0.067998 -0.221068 -0.036911 -0.114414 -0.258801 -0.037626 -0.117517 -0.254781 -0.037261 -0.115569 -0.257471 -0.064813 -0.081788 -0.16105 -0.062692 -0.08193499999999999 -0.143086 -0.057094 -0.07038999999999999 -0.162155 -0.035603 -0.049998 -0.179336 -0.031983 -0.061887 -0.18193 -0.031137 -0.061966 -0.183063 -0.024362 -0.063959 -0.21226 -0.022834 -0.065247 -0.207674 -0.015534 -0.07106700000000001 -0.210269 -0.051395 -0.069561 -0.231297 -0.042758 -0.0669136 -0.23641 -0.045077 -0.06940499999999999 -0.241524 -0.038989 -0.129258 -0.203352 -0.027461 -0.127109 -0.202655 -0.025578 -0.127553 -0.188988 -0.023212 -0.131398 -0.276199 -0.0203629 -0.101282 -0.278166 -0.016268 -0.131398 -0.280992 -0.034747 -0.067998 -0.250643 -0.034747 -0.0637284 -0.250001 -0.034747 -0.067998 -0.252601 -0.0310716 -0.0699446 -0.265568 -0.0306243 -0.067998 -0.26642 -0.0294052 -0.0795941 -0.268743 -0.0254514 -0.0873768 -0.273671 -0.0214921 -0.0925914 -0.277554 -0.025963 -0.094998 -0.2751 -0.044032 -0.06316099999999999 -0.223615 -0.041227 -0.062847 -0.226878 -0.051395 -0.069561 -0.231297 -0.068483 -0.088411 -0.18205 -0.07356699999999999 -0.07099800000000001 -0.182532 -0.07356699999999999 -0.118998 -0.182532 -0.034606 -0.107636 -0.265703 -0.035455 -0.094998 -0.268032 -0.034039 -0.106035 -0.26681 -0.0500441 -0.123165 -0.226155 -0.0497035 -0.123371 -0.227009 -0.046622 -0.126471 -0.220648 -0.022773 -0.062583 -0.026579 -0.023114 -0.062375 -0.02934 -0.034356 -0.071198 -0.0271 -0.056819 -0.119225 -0.155361 -0.06579 -0.107966 -0.170226 -0.058648 -0.118944 -0.171066 -0.015557 -0.067998 -0.215638 -0.019043 -0.065294 -0.217116 -0.015534 -0.07106700000000001 -0.210269 -0.0217294 -0.0679979 -0.277222 -0.0182832 -0.0924469 -0.279645 -0.0199652 -0.0921587 -0.27844 -0.037903 -0.12941 -0.1884 -0.038989 -0.129258 -0.203352 -0.025578 -0.127553 -0.188988 -0.0304037 -0.0679979 -0.233161 -0.0301314 -0.067998 -0.232642 -0.0307675 -0.062998 -0.233855 0.033541 -0.095485 -0.031703 0.029418 -0.110682 -0.035372 0.031961 -0.095501 -0.040298 -0.041251 -0.062174 -0.1779 -0.041233 -0.049998 -0.177738 -0.047047 -0.049998 -0.178417 0.03132 -0.111039 -0.017164 0.031539 -0.110116 -0.019935 0.032042 -0.109598 -0.01583 -0.029836 -0.06207 -0.226616 -0.024636 -0.067998 -0.221068 -0.0294847 -0.06503399999999999 -0.226685 -0.032728 -0.0763397 -0.262412 -0.0331411 -0.07301580000000001 -0.260736 -0.0330232 -0.07311429999999999 -0.261214 0.023207 -0.057998 -0.276199 0.028802 -0.057998 -0.269883 0.028802 -0.131398 -0.269883 -0.025099 -0.132149 -0.115228 -0.043659 -0.127535 -0.142076 -0.030429 -0.13079 -0.144536 -0.023212 -0.131398 -0.223803 -0.01974 -0.117198 -0.221406 -0.023212 -0.102998 -0.223803 -0.011323 -0.130169 -0.118162 -0.025099 -0.132149 -0.115228 -0.030429 -0.13079 -0.144536 -0.034048 -0.039998 -0.008119009999999999 -0.03489 -0.039998 0.00279899 0.024691 -0.039998 -0.024464 -0.06411 -0.10808 -0.1542 -0.054701 -0.119633 -0.140021 -0.062009 -0.108246 -0.138661 -0.029873 -0.137998 -0.018243 -0.023427 -0.127181 -0.025713 -0.022774 -0.137998 -0.02658 0.031539 -0.110116 -0.019935 0.028642 -0.11501 -0.02086 0.027101 -0.116799 -0.022508 -0.054341 -0.094998 -0.247534 -0.057071 -0.107012 -0.239238 -0.058828 -0.094998 -0.240143 -0.019773 -0.124949 -0.217628 -0.016925 -0.122882 -0.215977 -0.024551 -0.126404 -0.21416 0.023207 -0.057998 -0.276199 0.023207 -0.131398 -0.276199 0.016263 -0.131398 -0.280992 -0.03788 -0.067998 -0.246961 -0.034747 -0.067998 -0.24674 -0.034747 -0.067998 -0.247212 -2.99582e-06 -0.057998 -0.215001 -0.008378999999999999 -0.057998 -0.216018 -0.00653584 -0.07414800000000001 -0.215794 -0.028807 -0.131398 -0.230119 -0.0307675 -0.117198 -0.233855 -0.032728 -0.131398 -0.23759 -2.99964e-06 -0.0579979 -0.285001 -0.028807 -0.057998 -0.269883 -0.032728 -0.057998 -0.262412 0.024691 -0.137998 -0.024464 0.020278 -0.123345 -0.028527 0.022954 -0.121125 -0.026485 -0.07356699999999999 -0.07099800000000001 -0.182532 -0.063614 -0.07618 -0.181589 -0.059517 -0.07099800000000001 -0.181201 -0.023403 -0.049998 -0.197539 -0.057231 -0.049998 -0.190235 -0.027205 -0.049998 -0.190725 -0.042184 -0.094998 -0.262167 -0.043563 -0.080983 -0.256573 -0.03345 -0.080718 -0.265711 0.031961 -0.095501 -0.040298 0.029163 -0.09553 -0.05552 0.029084 -0.08015 -0.039744 -0.033834 -0.067998 -0.232697 -0.032728 -0.067998 -0.23759 -0.0341418 -0.067998 -0.239829 -0.044275 -0.124806 -0.232674 -0.0430425 -0.123603 -0.236991 -0.0456132 -0.12173 -0.237229 -0.021233 -0.0636 -0.183487 -0.017612 -0.06343500000000001 -0.16783 -0.012684 -0.069286 -0.184201 -0.028807 -0.102998 -0.230119 -0.028807 -0.131398 -0.230119 -0.0260095 -0.117198 -0.226961 -0.008378999999999999 -0.057998 -0.216018 -0.016268 -0.057998 -0.21901 -0.0123235 -0.0619875 -0.217514 -0.029147 -0.062151 -0.185728 -0.02816 -0.049998 -0.188077 -0.031012 -0.049998 -0.182966 0.032223 -0.082122 -0.02238 0.031876 -0.080175 -0.016158 0.033206 -0.08286200000000001 -0.013636 -0.0291896 -0.102998 -0.269154 -0.032964 -0.102998 -0.268909 -0.0305964 -0.102997 -0.269722 -0.008378999999999999 -0.131398 -0.283984 -0.008378999999999999 -0.057998 -0.283984 -1.99888e-06 -0.131398 -0.285001 -0.00675999 -0.115159 -0.17718 -0.001488 -0.108845 -0.164172 -0.003402 -0.115569 -0.163868 -0.043563 -0.080983 -0.256573 -0.037131 -0.06919599999999999 -0.250607 -0.0385065 -0.0764526 -0.256684 -0.0334227 -0.102998 -0.259593 -0.0335584 -0.102998 -0.259043 -0.036966 -0.102998 -0.258815 -0.013038 -0.118998 -0.214307 -0.016925 -0.122882 -0.215977 -0.009391 -0.111495 -0.213179 -0.010797 -0.115038 -0.189686 -0.017449 -0.120256 -0.202053 -0.014048 -0.114524 -0.201854 -0.0145526 -0.0704231 -0.212954 -0.015557 -0.067998 -0.215638 -0.015534 -0.07106700000000001 -0.210269 -0.028807 -0.057998 -0.269883 -0.023212 -0.057998 -0.276199 -0.0260095 -0.0726874 -0.273041 0.036177 -0.039998 0.00428799 0.034981 -0.039998 0.010695 0.036177 -0.137998 0.00428798 -0.0306243 -0.067998 -0.26642 -0.028807 -0.057998 -0.269883 -0.0293392 -0.067998 -0.268869 -0.0217294 -0.0679979 -0.277222 -0.0199652 -0.0921587 -0.27844 -0.0254514 -0.0873768 -0.273671 -0.038299 -0.121013 -0.051695 -0.049668 -0.120374 -0.109996 -0.026806 -0.129703 -0.054184 -0.060239 -0.049998 -0.194583 -0.060239 -0.07099800000000001 -0.194583 -0.057231 -0.049998 -0.190235 0.016263 -0.131398 -0.21901 0.016263 -0.057998 -0.21901 0.008374009999999999 -0.131398 -0.216018 0.036177 -0.039998 0.00428799 0.036177 -0.137998 0.00428798 0.036247 -0.137998 0.0009799819999999999 0.019976 -0.067373 -0.037929 0.029164 -0.076123 -0.021844 0.025148 -0.073194 -0.03896 0.012103 -0.095511 -0.123116 0.012978 -0.078932 -0.106368 0.01636 -0.09552099999999999 -0.106937 -0.049958 -0.126383 -0.187824 -0.0570217 -0.121279 -0.192606 -0.0580022 -0.120438 -0.187438 -0.012348 -0.09540999999999999 -0.20183 -0.013114 -0.108058 -0.201814 -0.011532 -0.107588 -0.210271 -0.0321938 -0.067998 -0.236572 -0.033834 -0.067998 -0.232697 -0.0304037 -0.0679979 -0.233161 -0.0337375 -0.060498 -0.241686 -0.0337375 -0.062998 -0.241686 -0.032728 -0.057998 -0.23759 -0.047715 -0.06462900000000001 -0.222981 -0.044032 -0.06316099999999999 -0.223615 -0.051395 -0.069561 -0.231297 0.00071001 -0.123015 -0.120724 -0.016895 -0.128882 -0.147054 -0.00501499 -0.122031 -0.149263 -0.034326 -0.08115799999999999 -0.00534201 -0.034828 -0.094998 0.00348899 -0.034048 -0.039998 -0.008119009999999999 0.016263 -0.131398 -0.21901 0.023207 -0.057998 -0.223803 0.016263 -0.057998 -0.21901 -0.017073 -0.070427 -0.205294 -0.013985 -0.076269 -0.204968 -0.012724 -0.076705 -0.209545 -0.00415147 -0.0748472 -0.215505 -0.00653584 -0.07414800000000001 -0.215794 -0.00614141 -0.07561610000000001 -0.215678 -0.032318 -0.137998 0.013442 -0.034828 -0.094998 0.00348899 -0.034887 -0.098269 0.00279799 -0.023212 -0.057998 -0.223803 -0.0260095 -0.060498 -0.226961 -0.0260095 -0.062998 -0.226961 -0.00468 -0.07505100000000001 -0.169678 -0.0014 -0.074006 -0.1541 -0.003025 -0.08194 -0.169916 -0.021233 -0.0636 -0.183487 -0.016665 -0.06974900000000001 -0.198437 -0.024351 -0.063566 -0.195196 0.023298 -0.039998 0.028256 0.027792 -0.137998 0.024268 0.027792 -0.039998 0.024268 -0.029468 -0.049998 -0.218918 -0.033143 -0.062024 -0.221268 -0.036282 -0.049998 -0.22272 -0.013114 -0.108058 -0.201814 -0.011416 -0.095416 -0.197055 -0.009605000000000001 -0.108348 -0.189741 -0.013985 -0.076269 -0.204968 -0.013229 -0.075809 -0.19835 -0.01322 -0.08273999999999999 -0.204899 -0.054278 -0.117226 -0.231933 -0.057071 -0.107012 -0.239238 -0.051972 -0.11736 -0.23662 -0.024636 -0.067998 -0.221068 -0.033834 -0.067998 -0.232697 -0.0294847 -0.06503399999999999 -0.226685 -0.059351 -0.094998 -0.107759 -0.060132 -0.08210099999999999 -0.125616 -0.062363 -0.094998 -0.125247 -0.054764 -0.094998 -0.083718 -0.047727 -0.082469 -0.058234 -0.054037 -0.08229 -0.091492 -0.019807 -0.102998 -0.21757 -0.012538 -0.102998 -0.217595 -0.0120057 -0.102998 -0.216492 -0.062692 -0.08193499999999999 -0.143086 -0.06519 -0.094998 -0.142662 -0.060132 -0.08210099999999999 -0.125616 -0.07356699999999999 -0.07099800000000001 -0.182532 -0.061464 -0.07099800000000001 -0.209841 -0.056939 -0.07099800000000001 -0.220732 -0.009834000000000001 -0.077057 -0.213119 -0.012418 -0.071588 -0.214274 -0.015534 -0.07106700000000001 -0.210269 0.035752 -0.093403 -0.00599601 0.035786 -0.094414 -0.00581501 0.032223 -0.082122 -0.02238 -0.044032 -0.06316099999999999 -0.223615 -0.047715 -0.06462900000000001 -0.222981 -0.044033 -0.049998 -0.223626 -0.037185 -0.065271 -0.242165 -0.03788 -0.067998 -0.246961 -0.045077 -0.06940499999999999 -0.241524 -0.029147 -0.062151 -0.185728 -0.021233 -0.0636 -0.183487 -0.028339 -0.062313 -0.188136 -0.0307675 -0.062998 -0.233855 -0.0297872 -0.062998 -0.231987 -0.028807 -0.057998 -0.230119 0.03148 -0.079376 -0.016907 0.029473 -0.076419 -0.019718 0.031544 -0.039998 -0.016125 0.031112 -0.039998 0.019976 0.033206 -0.039998 0.014953 0.024691 -0.039998 -0.024464 0.010922 -0.062035 -0.036126 0.019976 -0.067373 -0.037929 0.015328 -0.06553 -0.054574 0.029564 -0.113644 -0.019588 0.028642 -0.11501 -0.02086 0.031539 -0.110116 -0.019935 -0.06689290000000001 -0.08831550000000001 -0.170419 -0.068189 -0.094998 -0.170106 -0.064813 -0.081788 -0.16105 -0.065009 -0.111448 -0.181721 -0.066541 -0.1079 -0.181867 -0.072017 -0.119053 -0.18233 -0.028827 -0.128679 -0.225307 -0.031908 -0.128859 -0.223879 -0.032823 -0.128474 -0.230849 -0.066376 -0.081721 -0.179787 -0.069103 -0.094998 -0.18211 -0.068189 -0.094998 -0.170106 -0.056871 -0.076153 -0.232179 -0.052737 -0.07099800000000001 -0.231787 -0.058675 -0.08124099999999999 -0.234455 0.025371 -0.117444 -0.034582 0.01403 -0.12392 -0.063029 0.019315 -0.118087 -0.06417299999999999 0.031545 -0.137998 -0.016125 0.025406 -0.118766 -0.024322 0.027101 -0.116799 -0.022508 -0.032728 -0.131398 -0.23759 -0.034747 -0.131398 -0.245782 -0.008378999999999999 -0.131398 -0.283984 -0.058648 -0.118944 -0.171066 -0.06579 -0.107966 -0.170226 -0.066541 -0.1079 -0.181867 -0.008803 -0.095419 -0.18977 -0.006972 -0.09542399999999999 -0.184465 -0.009605000000000001 -0.108348 -0.189741 0.031545 -0.137998 -0.016125 0.03132 -0.111039 -0.017164 0.032042 -0.109598 -0.01583 -0.029338 -0.061197 -0.149079 -0.043426 -0.062724 -0.146549 -0.042036 -0.062669 -0.129234 -0.053559 -0.071121 -0.126929 -0.043426 -0.062724 -0.146549 -0.05547 -0.07073400000000001 -0.144385 -0.048222 -0.07156700000000001 -0.09278500000000001 -0.03735 -0.06260599999999999 -0.09519900000000001 -0.042036 -0.062669 -0.129234 0.035508 -0.099208 -0.00713901 0.036247 -0.137998 0.0009799819999999999 0.035503 -0.137998 -0.00716101 -0.057231 -0.068227 -0.190235 -0.060239 -0.07099800000000001 -0.194583 -0.058697 -0.07023500000000001 -0.180422 -0.042263 -0.117494 -0.250094 -0.037982 -0.12146 -0.248769 -0.037904 -0.118998 -0.252736 -0.057071 -0.107012 -0.239238 -0.06231 -0.094998 -0.232694 -0.058828 -0.094998 -0.240143 -0.044452 -0.126287 -0.226534 -0.037155 -0.128008 -0.229005 -0.031908 -0.128859 -0.223879 0.00811601 -0.137998 -0.034047 0.008051020000000001 -0.129972 -0.033797 0.0134718 -0.126915 -0.032658 -0.038544 -0.128686 -0.112365 -0.043659 -0.127535 -0.142076 -0.025099 -0.132149 -0.115228 0.028642 -0.11501 -0.02086 0.029564 -0.113644 -0.019588 0.031545 -0.137998 -0.016125 -0.008378999999999999 -0.102998 -0.216018 -0.005196 -0.102998 -0.215389 -0.0120057 -0.102998 -0.216492 0.032723 -0.057998 -0.23759 0.034742 -0.057998 -0.245782 -2.99964e-06 -0.0579979 -0.285001 -0.049958 -0.126383 -0.187824 -0.050376 -0.126442 -0.204039 -0.037903 -0.12941 -0.1884 -0.005313 -0.108449 -0.177352 -0.001488 -0.108845 -0.164172 -0.00675999 -0.115159 -0.17718 0.00568601 -0.117233 -0.121784 -0.000383994 -0.116163 -0.150124 0.009158009999999999 -0.110451 -0.122524 -0.0014 -0.074006 -0.1541 0.00173001 -0.072867 -0.137987 0.001094 -0.08108700000000001 -0.154548 -0.054341 -0.094998 -0.247534 -0.058828 -0.094998 -0.240143 -0.052093 -0.08112999999999999 -0.246067 -0.057231 -0.068227 -0.190235 -0.058697 -0.07023500000000001 -0.180422 -0.055699 -0.06725100000000001 -0.185688 0.021367 -0.07895099999999999 -0.07337299999999999 0.024673 -0.095531 -0.074061 0.020761 -0.09553200000000001 -0.090212 0.027925 -0.07441300000000001 -0.021615 0.029473 -0.076419 -0.019718 0.029164 -0.076123 -0.021844 -0.056918 -0.108547 -0.108453 -0.045698 -0.108799 -0.050092 -0.054764 -0.094998 -0.083718 -0.032859 -0.130041 -0.159176 -0.016895 -0.128882 -0.147054 -0.030429 -0.13079 -0.144536 -0.027636 -0.062453 -0.190236 -0.021233 -0.0636 -0.183487 -0.025697 -0.062902 -0.19274 -0.059887 -0.08204 -0.232464 -0.056871 -0.076153 -0.232179 -0.058675 -0.08124099999999999 -0.234455 -0.061707 -0.088404 -0.232637 -0.058675 -0.08124099999999999 -0.234455 -0.06231 -0.094998 -0.232694 -0.008803 -0.095419 -0.18977 -0.012316 -0.08247400000000001 -0.198331 -0.007637 -0.082319 -0.18461 -0.03788 -0.067998 -0.246961 -0.034747 -0.067998 -0.247212 -0.0363135 -0.067998 -0.248096 -0.013446 -0.039998 -0.032316 -0.022774 -0.039998 -0.02658 0.024691 -0.039998 -0.024464 -0.029515 -0.062234 -0.218869 -0.022509 -0.06329799999999999 -0.219383 -0.033143 -0.062024 -0.221268 -0.0299961 -0.102998 -0.230342 -0.035087 -0.102998 -0.235405 -0.0303241 -0.102998 -0.23301 -0.054764 -0.094998 -0.083718 -0.054037 -0.08229 -0.091492 -0.059351 -0.094998 -0.107759 -0.0307675 -0.117198 -0.266147 -0.0312109 -0.102998 -0.265303 -0.0291896 -0.102998 -0.269154 -0.003516 -0.066757 -0.136938 -0.006163 -0.067844 -0.153244 -0.01083 -0.06265800000000001 -0.135477 -0.034819 -0.062778 -0.23491 -0.035583 -0.06309099999999999 -0.23666 -0.045077 -0.06940499999999999 -0.241524 0.028802 -0.057998 -0.230119 0.032723 -0.057998 -0.23759 -2.99964e-06 -0.0579979 -0.285001 -0.047357 -0.0631 -0.178521 -0.050569 -0.06436799999999999 -0.180088 -0.044694 -0.06277199999999999 -0.163934 -0.004855 -0.095383 -0.215339 -0.00212134 -0.0981031 -0.215258 -0.00212157 -0.08560189999999999 -0.215258 -0.032728 -0.0763397 -0.262412 -0.0320424 -0.0768882 -0.263718 -0.03345 -0.080718 -0.265711 0.024673 -0.095531 -0.074061 0.023357 -0.111167 -0.065049 0.020761 -0.09553200000000001 -0.090212 0.016263 -0.131398 -0.280992 0.023207 -0.131398 -0.276199 -0.008378999999999999 -0.131398 -0.283984 0.017841 -0.137998 0.03175 0.017841 -0.039998 0.031751 0.012176 -0.039998 0.0342 -0.03323 -0.07566299999999999 -0.010959 -0.036206 -0.081192 -0.010436 -0.034326 -0.08115799999999999 -0.00534201 -0.016665 -0.06974900000000001 -0.198437 -0.013229 -0.075809 -0.19835 -0.013985 -0.076269 -0.204968 -0.019807 -0.102998 -0.21757 -0.005196 -0.102998 -0.215389 -0.008815999999999999 -0.102998 -0.213038 -0.028074 -0.06254899999999999 -0.045339 -0.01672 -0.061015 -0.030618 -0.013388 -0.060519 -0.03217 -0.013038 -0.118998 -0.214307 -0.010007 -0.113411 -0.213347 -0.010689 -0.115532 -0.213535 -0.034747 -0.0637284 -0.250001 -0.034747 -0.067998 -0.245782 -0.034747 -0.057998 -0.245782 -0.068189 -0.094998 -0.170106 -0.067456 -0.094998 -0.160678 -0.064813 -0.081788 -0.16105 -0.06519 -0.094998 -0.142662 -0.062009 -0.108246 -0.138661 -0.062363 -0.094998 -0.125247 0.019315 -0.118087 -0.06417299999999999 0.00071001 -0.123015 -0.120724 0.00568601 -0.117233 -0.121784 -0.029873 -0.039998 -0.018243 -0.03323 -0.07566299999999999 -0.010959 -0.034326 -0.08115799999999999 -0.00534201 -0.008378999999999999 -0.131398 -0.283984 -0.016268 -0.057998 -0.280992 -0.008378999999999999 -0.057998 -0.283984 -0.0028281 -0.0782692 -0.215344 -2.99582e-06 -0.057998 -0.215001 -0.00415147 -0.0748472 -0.215505 -0.0014 -0.074006 -0.1541 0.001094 -0.08108700000000001 -0.154548 -0.003025 -0.08194 -0.169916 -0.034747 -0.131398 -0.25422 -0.032728 -0.131398 -0.262412 -0.008378999999999999 -0.131398 -0.283984 -0.07356699999999999 -0.07099800000000001 -0.182532 -0.056939 -0.07099800000000001 -0.220732 -0.055897 -0.07099800000000001 -0.224066 -0.028807 -0.057998 -0.269883 -0.0260095 -0.0726874 -0.273041 -0.028807 -0.0833648 -0.269883 0.031544 -0.039998 -0.016125 0.035402 -0.039998 -0.00747301 0.033809 -0.039998 -0.012393 0.00811601 -0.137998 -0.034047 -0.00280198 -0.137998 -0.034889 0.008051020000000001 -0.129972 -0.033797 0.020278 -0.06684 -0.028527 0.010685 -0.062075 -0.033096 0.018239 -0.039998 -0.029872 -0.014243 -0.063067 -0.151789 -0.029338 -0.061197 -0.149079 -0.026849 -0.060719 -0.132272 -0.026485 -0.062779 -0.215759 -0.029515 -0.062234 -0.218869 -0.024627 -0.049998 -0.212797 0.025371 -0.117444 -0.034582 0.025406 -0.118766 -0.024322 0.022954 -0.121125 -0.026485 -0.0280447 -0.067998 -0.229259 -0.0260095 -0.062998 -0.226961 -0.028807 -0.057998 -0.230119 -0.005627 -0.08337899999999999 -0.215459 -0.004855 -0.095383 -0.215339 -0.00212157 -0.08560189999999999 -0.215258 -0.034747 -0.102998 -0.25422 -0.034747 -0.102998 -0.249047 -0.0357192 -0.102998 -0.253002 -0.047488 -0.117421 -0.24361 -0.052437 -0.107055 -0.246859 -0.046949 -0.107107 -0.253978 -0.0269275 -0.08767800000000001 -0.272574 -0.0254514 -0.0873768 -0.273671 -0.025963 -0.094998 -0.2751 -0.016895 -0.128882 -0.147054 0.00071001 -0.123015 -0.120724 -0.011323 -0.130169 -0.118162 -0.00516071 -0.085313 -0.177317 -0.003025 -0.08194 -0.169916 -0.0049804 -0.088686 -0.177374 -0.0182832 -0.0924469 -0.279645 -0.016268 -0.057998 -0.280992 -0.017284 -0.094997 -0.280436 -0.021122 -0.12593 -0.218412 -0.031908 -0.128859 -0.223879 -0.022862 -0.12675 -0.219763 0.033206 -0.08286200000000001 -0.013636 0.035402 -0.039998 -0.00747301 0.033572 -0.08360099999999999 -0.012943 -0.034819 -0.062778 -0.23491 -0.042758 -0.0669136 -0.23641 -0.051395 -0.069561 -0.231297 -0.016268 -0.102998 -0.21901 -0.016268 -0.131398 -0.21901 -0.0123235 -0.117198 -0.217514 -0.013388 -0.060519 -0.03217 -0.013446 -0.039998 -0.032316 -0.00280299 -0.039998 -0.034889 0.020278 -0.039998 -0.028527 0.024691 -0.039998 -0.024464 0.020278 -0.06684 -0.028527 -0.01974 -0.062998 -0.221406 -0.0196111 -0.067998 -0.221317 -0.016268 -0.067998 -0.21901 -0.005196 -0.102998 -0.215389 -0.004855 -0.095383 -0.215339 -0.008725 -0.09539 -0.21254 -0.028807 -0.0833648 -0.269883 -0.0294276 -0.0808743 -0.268701 -0.0294052 -0.0795941 -0.268743 -0.013985 -0.076269 -0.204968 -0.01322 -0.08273999999999999 -0.204899 -0.012034 -0.082993 -0.209343 -0.0370101 -0.109485 -0.262435 -0.040674 -0.10718 -0.260584 -0.034606 -0.107636 -0.265703 -0.012814 -0.13337 -0.057215 -0.038544 -0.128686 -0.112365 -0.025099 -0.132149 -0.115228 -0.039448 -0.108685 -0.021917 -0.045698 -0.108799 -0.050092 -0.031887 -0.120562 -0.023395 -0.017449 -0.120256 -0.202053 -0.024551 -0.126404 -0.21416 -0.01521 -0.119156 -0.211406 -0.038299 -0.121013 -0.051695 -0.026806 -0.129703 -0.054184 -0.031887 -0.120562 -0.023395 -0.029836 -0.06207 -0.226616 -0.033834 -0.067998 -0.232697 -0.034819 -0.062778 -0.23491 -0.03788 -0.067998 -0.246961 -0.0363135 -0.067998 -0.248096 -0.036481 -0.067998 -0.249142 -0.0144225 -0.102998 -0.21831 -0.016268 -0.102998 -0.21901 -0.0123235 -0.117198 -0.217514 -0.012343 -0.0954 -0.207618 -0.012348 -0.09540999999999999 -0.20183 -0.011532 -0.107588 -0.210271 -0.034747 -0.102998 -0.25422 -0.034747 -0.131398 -0.25422 -0.034747 -0.117198 -0.250001 0.028642 -0.11501 -0.02086 0.031545 -0.137998 -0.016125 0.027101 -0.116799 -0.022508 -0.023114 -0.062375 -0.02934 -0.028074 -0.06254899999999999 -0.045339 -0.034356 -0.071198 -0.0271 -0.034747 -0.131398 -0.245782 -0.034747 -0.131398 -0.25422 -0.008378999999999999 -0.131398 -0.283984 -0.034325 -0.067998 -0.255932 -0.034747 -0.0703906 -0.25422 -0.034747 -0.057998 -0.25422 -0.026582 -0.137998 0.02277 -0.026582 -0.039998 0.022771 -0.032318 -0.039998 0.013443 -0.0246108 -0.062998 -0.225382 -0.0260095 -0.062998 -0.226961 -0.023212 -0.067998 -0.223803 0.023207 -0.131398 -0.276199 0.028802 -0.131398 -0.269883 -0.008378999999999999 -0.131398 -0.283984 -0.034747 -0.057998 -0.245782 -2.99964e-06 -0.0579979 -0.285001 -0.034747 -0.057998 -0.25422 -0.045891 -0.126901 -0.157101 -0.032859 -0.130041 -0.159176 -0.030429 -0.13079 -0.144536 0.028802 -0.131398 -0.230119 0.023207 -0.057998 -0.223803 0.023207 -0.131398 -0.223803 0.003933 -0.09546499999999999 -0.151245 0.001094 -0.08108700000000001 -0.154548 0.005089 -0.08015600000000001 -0.138659 -0.031908 -0.128859 -0.223879 -0.037155 -0.128008 -0.229005 -0.032823 -0.128474 -0.230849 -0.024835 -0.062582 -0.221237 -0.024636 -0.067998 -0.221068 -0.027767 -0.062132 -0.224056 0.002578 -0.065321 -0.104062 0.011027 -0.065356 -0.071107 0.008484 -0.07136099999999999 -0.105372 -2.99964e-06 -0.0579979 -0.285001 -0.034747 -0.057998 -0.245782 -0.032728 -0.057998 -0.23759 -0.062369 -0.049998 -0.20209 -0.060239 -0.049998 -0.194583 -0.057231 -0.049998 -0.190235 -0.0203629 -0.101282 -0.278166 -0.0217294 -0.102997 -0.277222 -0.0235251 -0.0995163 -0.275846 -0.037131 -0.06919599999999999 -0.250607 -0.03345 -0.080718 -0.265711 -0.0385065 -0.0764526 -0.256684 -0.035087 -0.102998 -0.235405 -0.0349329 -0.102998 -0.241309 -0.032728 -0.102998 -0.23759 -0.0123235 -0.117198 -0.217514 -0.016268 -0.131398 -0.21901 -0.008378999999999999 -0.131398 -0.216018 -0.0260095 -0.062998 -0.226961 -0.0260095 -0.060498 -0.226961 -0.028807 -0.057998 -0.230119 0.032723 -0.057998 -0.262412 0.028802 -0.057998 -0.269883 -2.99964e-06 -0.0579979 -0.285001 -0.043426 -0.062724 -0.146549 -0.044694 -0.06277199999999999 -0.163934 -0.05547 -0.07073400000000001 -0.144385 0.034883 -0.102449 -0.00945201 0.033408 -0.106873 -0.013307 0.031539 -0.110116 -0.019935 -0.031137 -0.061966 -0.183063 -0.029147 -0.062151 -0.185728 -0.031012 -0.049998 -0.182966 -0.031196 -0.062566 -0.061855 -0.03735 -0.06260599999999999 -0.09519900000000001 -0.042229 -0.071954 -0.059438 -0.0120057 -0.102998 -0.216492 -0.0119847 -0.102998 -0.217043 -0.0114314 -0.102998 -0.217176 -0.056819 -0.119225 -0.155361 -0.043659 -0.127535 -0.142076 -0.054701 -0.119633 -0.140021 -0.028827 -0.128679 -0.225307 -0.035087 -0.102998 -0.235405 -0.028859 -0.102998 -0.225278 -0.034747 -0.057998 -0.25422 -0.034747 -0.0703906 -0.25422 -0.034747 -0.0694588 -0.252902 -0.049442 -0.094998 -0.254344 -0.043563 -0.080983 -0.256573 -0.048554 -0.094998 -0.255301 -0.024636 -0.067998 -0.221068 -0.014746 -0.067998 -0.216628 -0.013686 -0.067998 -0.217787 0.034742 -0.057998 -0.245782 0.034742 -0.057998 -0.25422 -2.99964e-06 -0.0579979 -0.285001 0.026925 -0.09553 -0.064763 0.024673 -0.095531 -0.074061 0.021367 -0.07895099999999999 -0.07337299999999999 -0.034747 -0.131398 -0.245782 -0.0337375 -0.117198 -0.241686 -0.034747 -0.102998 -0.245782 0.00071001 -0.123015 -0.120724 -0.00501499 -0.122031 -0.149263 0.00568601 -0.117233 -0.121784 -0.0294276 -0.0808743 -0.268701 -0.029842 -0.080358 -0.268227 -0.0294052 -0.0795941 -0.268743 -0.038299 -0.121013 -0.051695 -0.056918 -0.108547 -0.108453 -0.049668 -0.120374 -0.109996 0.034349 -0.095469 -0.02239 0.035788 -0.09544 -0.00580301 0.031539 -0.110116 -0.019935 -0.036206 -0.081192 -0.010436 -0.034828 -0.094998 0.00348899 -0.034326 -0.08115799999999999 -0.00534201 -0.010127 -0.060008 -0.049157 0.00358101 -0.060637 -0.034817 0.010922 -0.062035 -0.036126 -0.02251 -0.06550499999999999 -0.20529 -0.017073 -0.070427 -0.205294 -0.015534 -0.07106700000000001 -0.210269 -0.009214989999999999 -0.039998 0.034258 -0.020283 -0.039998 0.028524 -0.008135979999999999 -0.137998 0.034439 0.008115010000000001 -0.039998 -0.034047 -0.00280299 -0.039998 -0.034889 0.024691 -0.039998 -0.024464 -0.057231 -0.049998 -0.190235 -0.029468 -0.049998 -0.218918 -0.036282 -0.049998 -0.22272 -0.024783 -0.102997 -0.274717 -0.0266445 -0.102997 -0.272324 -0.028332 -0.102997 -0.27231 0.008051020000000001 -0.129972 -0.033797 0.020104 -0.123114 -0.033553 0.0134718 -0.126915 -0.032658 -0.029834 -0.120931 -0.018209 -0.023427 -0.127181 -0.025713 -0.029873 -0.137998 -0.018243 -0.035803 -0.108542 -0.00859101 -0.039448 -0.108685 -0.021917 -0.030235 -0.12028 -0.017474 -0.010127 -0.060008 -0.049157 0.008237009999999999 -0.061996 -0.053063 0.00428401 -0.062021 -0.069631 -0.0430425 -0.123603 -0.236991 -0.040037 -0.124841 -0.23872 -0.044275 -0.124806 -0.232674 -0.052157 -0.049998 -0.181269 -0.057231 -0.049998 -0.190235 -0.055788 -0.049998 -0.18586 -0.068189 -0.094998 -0.170106 -0.06579 -0.107966 -0.170226 -0.067456 -0.094998 -0.160678 -0.027205 -0.049998 -0.190725 -0.025697 -0.062902 -0.19274 -0.023523 -0.064305 -0.197932 -0.066376 -0.081721 -0.179787 -0.064813 -0.081788 -0.16105 -0.058697 -0.07023500000000001 -0.180422 0.034742 -0.131398 -0.25422 0.034742 -0.131398 -0.245782 -0.008378999999999999 -0.131398 -0.283984 -0.034356 -0.071198 -0.0271 -0.036206 -0.081192 -0.010436 -0.030053 -0.070437 -0.017043 -0.028807 -0.057998 -0.269883 -0.0306243 -0.067998 -0.26642 -0.032728 -0.057998 -0.262412 0.008374009999999999 -0.131398 -0.283984 -0.008378999999999999 -0.131398 -0.283984 -1.99888e-06 -0.131398 -0.285001 -0.057231 -0.049998 -0.190235 -0.022497 -0.049998 -0.20529 -0.024627 -0.049998 -0.212797 -0.008803 -0.095419 -0.18977 -0.011416 -0.095416 -0.197055 -0.012316 -0.08247400000000001 -0.198331 -0.043659 -0.127535 -0.142076 -0.056819 -0.119225 -0.155361 -0.045891 -0.126901 -0.157101 -0.005196 -0.102998 -0.215389 -0.019807 -0.102998 -0.21757 -0.0120057 -0.102998 -0.216492 -0.03788 -0.067998 -0.246961 -0.0341418 -0.067998 -0.239829 -0.0344719 -0.067998 -0.244666 -0.044452 -0.126287 -0.226534 -0.035565 -0.128969 -0.217398 -0.046622 -0.126471 -0.220648 -0.0182832 -0.0924469 -0.279645 -0.0217294 -0.0679979 -0.277222 -0.016268 -0.057998 -0.280992 0.025455 -0.071586 -0.024275 0.022974 -0.06915499999999999 -0.026468 0.024691 -0.039998 -0.024464 -0.031735 -0.06163 -0.165798 -0.042891 -0.06232 -0.177697 -0.046303 -0.062916 -0.178326 -0.0337503 -0.0725065 -0.258264 -0.0333971 -0.067998 -0.259697 -0.0331411 -0.07301580000000001 -0.260736 -0.028074 -0.06254899999999999 -0.045339 -0.00653799 -0.060086 -0.034225 -0.010127 -0.060008 -0.049157 -0.045698 -0.108799 -0.050092 -0.038299 -0.121013 -0.051695 -0.031887 -0.120562 -0.023395 -0.006972 -0.09542399999999999 -0.184465 -0.008803 -0.095419 -0.18977 -0.007637 -0.082319 -0.18461 -0.03345 -0.080718 -0.265711 -0.0320424 -0.0768882 -0.263718 -0.029842 -0.080358 -0.268227 0.001094 -0.08108700000000001 -0.154548 0.003933 -0.09546499999999999 -0.151245 0.002275 -0.095455 -0.156935 -0.033234 -0.07478029999999999 -0.260359 -0.0337503 -0.0725065 -0.258264 -0.0331411 -0.07301580000000001 -0.260736 -0.0217294 -0.0679979 -0.277222 -0.023212 -0.057998 -0.276199 -0.016268 -0.057998 -0.280992 -0.044032 -0.06316099999999999 -0.223615 -0.038987 -0.062292 -0.223391 -0.041496 -0.06280570000000001 -0.225134 0.012978 -0.078932 -0.106368 0.020761 -0.09553200000000001 -0.090212 0.01636 -0.09552099999999999 -0.106937 -0.044032 -0.06316099999999999 -0.223615 -0.041496 -0.06280570000000001 -0.225134 -0.041227 -0.062847 -0.226878 -0.045698 -0.108799 -0.050092 -0.046465 -0.094998 -0.04153 -0.049463 -0.094998 -0.056063 -0.047487 -0.124698 -0.226704 -0.044275 -0.124806 -0.232674 -0.044452 -0.126287 -0.226534 0.009158009999999999 -0.110451 -0.122524 0.012103 -0.095511 -0.123116 0.01636 -0.09552099999999999 -0.106937 -0.006972 -0.09542399999999999 -0.184465 -0.005313 -0.108449 -0.177352 -0.009605000000000001 -0.108348 -0.189741 -0.035087 -0.102998 -0.235405 -0.0317456 -0.102998 -0.235718 -0.0314748 -0.102998 -0.235202 -0.0189327 -0.067998 -0.219552 -0.013686 -0.067998 -0.217787 -0.016268 -0.067998 -0.21901 0.017841 -0.039998 0.031751 0.018876 -0.039998 0.031088 0.024691 -0.039998 -0.024464 -0.06579 -0.107966 -0.170226 -0.067271 -0.106211 -0.181936 -0.066541 -0.1079 -0.181867 -0.008378999999999999 -0.131398 -0.216018 -0.0041905 -0.117198 -0.21551 -0.008378999999999999 -0.102998 -0.216018 -0.052157 -0.049998 -0.181269 -0.055788 -0.049998 -0.18586 -0.052941 -0.065599 -0.181985 -0.00212134 -0.0981031 -0.215258 -0.00365891 -0.0991905 -0.215317 -0.00240399 -0.102998 -0.215293 -0.034606 -0.107636 -0.265703 -0.042184 -0.094998 -0.262167 -0.035455 -0.094998 -0.268032 -0.0291173 -0.07068140000000001 -0.269292 -0.028807 -0.0833648 -0.269883 -0.0294052 -0.0795941 -0.268743 -0.068758 -0.07099800000000001 -0.233304 -0.061713 -0.101573 -0.232638 -0.068758 -0.118998 -0.233305 -2.99582e-06 -0.057998 -0.215001 -2.99964e-06 -0.0579979 -0.285001 -0.008378999999999999 -0.057998 -0.216018 -0.018004 -0.062998 -0.220208 -0.016268 -0.067998 -0.21901 -0.016268 -0.057998 -0.21901 -0.0320424 -0.0768882 -0.263718 -0.0310716 -0.0699446 -0.265568 -0.0294052 -0.0795941 -0.268743 -0.051972 -0.11736 -0.23662 -0.052437 -0.107055 -0.246859 -0.047488 -0.117421 -0.24361 0.012177 -0.137998 0.0342 0.017841 -0.137998 0.03175 0.012176 -0.039998 0.0342 0.034742 -0.057998 -0.245782 0.034742 -0.131398 -0.245782 0.034742 -0.131398 -0.25422 -0.0363135 -0.067998 -0.248096 -0.034747 -0.067998 -0.249231 -0.036481 -0.067998 -0.249142 -0.01521 -0.119156 -0.211406 -0.013038 -0.118998 -0.214307 -0.010689 -0.115532 -0.213535 -0.032728 -0.131398 -0.262412 -0.028807 -0.131398 -0.269883 -0.008378999999999999 -0.131398 -0.283984 -0.06579 -0.107966 -0.170226 -0.06411 -0.10808 -0.1542 -0.067456 -0.094998 -0.160678 0.008051020000000001 -0.129972 -0.033797 -0.00280198 -0.137998 -0.034889 -0.00279198 -0.132618 -0.034791 -0.057231 -0.049998 -0.190235 -0.057231 -0.068227 -0.190235 -0.055699 -0.06725100000000001 -0.185688 0.008374009999999999 -0.131398 -0.283984 0.008373 -0.057998 -0.283984 0.016263 -0.057998 -0.280992 -0.020843 -0.060114 -0.098861 -0.00370299 -0.062147 -0.102663 -0.01083 -0.06265800000000001 -0.135477 -0.0307675 -0.117198 -0.233855 -0.032728 -0.102998 -0.23759 -0.032728 -0.131398 -0.23759 -0.010127 -0.060008 -0.049157 -0.00653799 -0.060086 -0.034225 -0.00281699 -0.060073 -0.034888 -0.054764 -0.094998 -0.083718 -0.045698 -0.108799 -0.050092 -0.049463 -0.094998 -0.056063 -0.00281699 -0.060073 -0.034888 -0.00280299 -0.039998 -0.034889 0.008115010000000001 -0.039998 -0.034047 0.00568601 -0.117233 -0.121784 -0.00501499 -0.122031 -0.149263 -0.000383994 -0.116163 -0.150124 -0.06579 -0.107966 -0.170226 -0.069103 -0.094998 -0.18211 -0.06864199999999999 -0.100682 -0.182065 0.025371 -0.117444 -0.034582 0.020278 -0.123345 -0.028527 0.020104 -0.123114 -0.033553 0.034742 -0.057998 -0.25422 0.032723 -0.057998 -0.262412 -2.99964e-06 -0.0579979 -0.285001 -0.040037 -0.124841 -0.23872 -0.036792 -0.125578 -0.240488 -0.035081 -0.127396 -0.235407 -0.045625 -0.094998 -0.258458 -0.046949 -0.107107 -0.253978 -0.048554 -0.094998 -0.255301 -0.032728 -0.057998 -0.23759 -0.0321938 -0.067998 -0.236572 -0.0307675 -0.062998 -0.233855 -0.042184 -0.094998 -0.262167 -0.040674 -0.10718 -0.260584 -0.045625 -0.094998 -0.258458 0.029084 -0.08015 -0.039744 0.029163 -0.09553 -0.05552 0.025389 -0.079096 -0.056714 -0.032728 -0.102998 -0.262412 -0.0334227 -0.102998 -0.259593 -0.036966 -0.102998 -0.258815 -0.038544 -0.128686 -0.112365 -0.012814 -0.13337 -0.057215 -0.026806 -0.129703 -0.054184 -0.010009 -0.07188899999999999 -0.216485 -0.00812 -0.074265 -0.215957 -0.00653584 -0.07414800000000001 -0.215794 -0.037131 -0.06919599999999999 -0.250607 -0.034747 -0.0692173 -0.252549 -0.034747 -0.0694588 -0.252902 -0.061464 -0.049998 -0.209841 -0.057231 -0.049998 -0.190235 -0.057662 -0.049998 -0.216656 -0.054037 -0.08229 -0.091492 -0.053559 -0.071121 -0.126929 -0.060132 -0.08210099999999999 -0.125616 -0.00891 -0.107254 -0.21306 -0.019807 -0.102998 -0.21757 -0.008815999999999999 -0.10605 -0.213038 -0.012538 -0.102998 -0.217595 -0.0123235 -0.117198 -0.217514 -0.0114314 -0.102998 -0.217176 0.023298 -0.137998 0.028256 0.027792 -0.137998 0.024268 0.023298 -0.039998 0.028256 -2.99964e-06 -0.0579979 -0.285001 -0.032728 -0.057998 -0.23759 -0.028807 -0.057998 -0.230119 0.036247 -0.137998 0.0009799819999999999 0.035786 -0.094414 -0.00581501 0.036247 -0.039998 0.000979986 -0.034101 -0.061824 -0.180269 -0.035603 -0.049998 -0.179336 -0.035656 -0.061843 -0.17945 -0.019536 -0.128174 -0.161298 -0.032859 -0.130041 -0.159176 -0.035318 -0.129524 -0.173813 0.008373 -0.057998 -0.216018 -2.99582e-06 -0.057998 -0.215001 -0.0028281 -0.0782692 -0.215344 -0.027636 -0.062453 -0.190236 -0.027205 -0.049998 -0.190725 -0.02816 -0.049998 -0.188077 -0.0260095 -0.0726874 -0.273041 -0.023212 -0.057998 -0.276199 -0.0254514 -0.0873768 -0.273671 -0.008815999999999999 -0.102998 -0.213038 -0.005196 -0.102998 -0.215389 -0.006925 -0.102998 -0.214239 -0.023212 -0.0986773 -0.276199 -0.0235251 -0.0995163 -0.275846 -0.028332 -0.102997 -0.27231 -0.023212 -0.0986773 -0.276199 -0.0204923 -0.09732010000000001 -0.278076 -0.0203629 -0.101282 -0.278166 -0.034747 -0.0694588 -0.252902 -0.034747 -0.0692173 -0.252549 -0.034747 -0.067998 -0.252601 0.020278 -0.123345 -0.028527 0.018239 -0.137998 -0.029872 0.018147 -0.12471 -0.029694 -0.023212 -0.102998 -0.223803 -0.01974 -0.117198 -0.221406 -0.0189548 -0.102998 -0.220865 -0.0331411 -0.07301580000000001 -0.260736 -0.0333971 -0.067998 -0.259697 -0.032728 -0.057998 -0.262412 -0.01672 -0.061015 -0.030618 -0.023114 -0.062375 -0.02934 -0.022773 -0.062583 -0.026579 -0.013038 -0.118998 -0.214307 -0.010007 -0.113411 -0.213347 -0.009391 -0.111495 -0.213179 -0.0307674 -0.060498 -0.233855 -0.0307675 -0.062998 -0.233855 -0.028807 -0.057998 -0.230119 -0.008795000000000001 -0.075515 -0.184517 -0.00468 -0.07505100000000001 -0.169678 -0.007637 -0.082319 -0.18461 0.025371 -0.117444 -0.034582 0.020104 -0.123114 -0.033553 0.01403 -0.12392 -0.063029 -0.038327 -0.061912 -0.178263 -0.031735 -0.06163 -0.165798 -0.035656 -0.061843 -0.17945 -0.01322 -0.08273999999999999 -0.204899 -0.012343 -0.0954 -0.207618 -0.012034 -0.082993 -0.209343 -0.050569 -0.06436799999999999 -0.180088 -0.052157 -0.049998 -0.181269 -0.052113 -0.06517000000000001 -0.181323 -1.99507e-06 -0.131398 -0.215001 -0.00240399 -0.102998 -0.215293 -0.0041905 -0.117198 -0.21551 -0.0204923 -0.09732010000000001 -0.278076 -0.021795 -0.094998 -0.277775 -0.017284 -0.094997 -0.280436 -0.012303 -0.113728 -0.210533 -0.01521 -0.119156 -0.211406 -0.010007 -0.113411 -0.213347 -0.028807 -0.057998 -0.269883 -0.028807 -0.0833648 -0.269883 -0.0291173 -0.07068140000000001 -0.269292 0.036247 -0.039998 0.000979986 0.03541 -0.090421 -0.00747301 0.036302 -0.039998 -0.001659 -0.032728 -0.102998 -0.262412 -0.036966 -0.102998 -0.258815 -0.0330778 -0.102998 -0.263984 -0.034747 -0.102998 -0.247697 -0.034747 -0.131398 -0.245782 -0.034747 -0.102998 -0.247212 -0.006163 -0.067844 -0.153244 -0.014243 -0.063067 -0.151789 -0.01083 -0.06265800000000001 -0.135477 -0.039489 -0.094998 -0.011609 -0.039448 -0.108685 -0.021917 -0.035803 -0.108542 -0.00859101 -0.032964 -0.102998 -0.268909 -0.0312109 -0.102998 -0.265303 -0.0330778 -0.102998 -0.263984 -0.031735 -0.06163 -0.165798 -0.044694 -0.06277199999999999 -0.163934 -0.043426 -0.062724 -0.146549 0.012103 -0.095511 -0.123116 0.005089 -0.08015600000000001 -0.138659 0.01049 -0.08722149999999999 -0.12288 -0.051972 -0.11736 -0.23662 -0.0423461 -0.119877 -0.245385 -0.047488 -0.117421 -0.24361 -0.008378999999999999 -0.131398 -0.216018 -0.008378999999999999 -0.102998 -0.216018 -0.0114314 -0.102998 -0.217176 -0.034747 -0.0703906 -0.25422 -0.0337503 -0.0725065 -0.258264 -0.037131 -0.06919599999999999 -0.250607 -0.013414 -0.13189 -0.032243 -0.00279198 -0.132618 -0.034791 -0.013446 -0.137998 -0.032316 0.036302 -0.039998 -0.001659 0.03541 -0.090421 -0.00747301 0.035402 -0.039998 -0.00747301 -0.068758 -0.118998 -0.233305 -0.054278 -0.117226 -0.231933 -0.06334099999999999 -0.119187 -0.232981 -0.055771 -0.069714 -0.220433 -0.053931 -0.068025 -0.219959 -0.051395 -0.069561 -0.231297 0.01403 -0.12392 -0.063029 0.00071001 -0.123015 -0.120724 0.019315 -0.118087 -0.06417299999999999 -0.0497035 -0.123371 -0.227009 -0.047487 -0.124698 -0.226704 -0.044275 -0.124806 -0.232674 -0.023212 -0.067998 -0.223803 -0.0280447 -0.067998 -0.229259 -0.0271378 -0.067998 -0.226882 -0.028931 -0.094998 -0.27299 -0.025963 -0.094998 -0.2751 -0.028332 -0.102997 -0.27231 -0.00281699 -0.060073 -0.034888 -0.00653799 -0.060086 -0.034225 -0.00280299 -0.039998 -0.034889 -0.033143 -0.062024 -0.221268 -0.041227 -0.062847 -0.226878 -0.036328 -0.062118 -0.222573 -0.034747 -0.057998 -0.25422 -2.99964e-06 -0.0579979 -0.285001 -0.032728 -0.057998 -0.262412 0.031876 -0.080175 -0.016158 0.03148 -0.079376 -0.016907 0.031544 -0.039998 -0.016125 -0.068758 -0.07099800000000001 -0.233304 -0.059887 -0.08204 -0.232464 -0.061707 -0.088404 -0.232637 -0.033834 -0.067998 -0.232697 -0.029836 -0.06207 -0.226616 -0.0294847 -0.06503399999999999 -0.226685 -0.034039 -0.106035 -0.26681 -0.035455 -0.094998 -0.268032 -0.033653 -0.094998 -0.269585 0.008051020000000001 -0.129972 -0.033797 -0.00279198 -0.132618 -0.034791 0.00154202 -0.131335 -0.060324 0.027792 -0.137998 0.024268 0.031112 -0.137998 0.019976 0.027792 -0.039998 0.024268 -0.058172 -0.07099800000000001 -0.216032 -0.061464 -0.049998 -0.209841 -0.057662 -0.049998 -0.216656 -0.028074 -0.06254899999999999 -0.045339 -0.010127 -0.060008 -0.049157 -0.0137 -0.060008 -0.065689 -0.0580022 -0.120438 -0.187438 -0.049958 -0.126383 -0.187824 -0.058413 -0.119945 -0.185262 -0.0189548 -0.102998 -0.220865 -0.019807 -0.102998 -0.21757 -0.0216408 -0.102998 -0.221424 -0.041233 -0.049998 -0.177738 -0.038327 -0.061912 -0.178263 -0.035656 -0.061843 -0.17945 0.033541 -0.095485 -0.031703 0.032223 -0.082122 -0.02238 0.034349 -0.095469 -0.02239 -0.052941 -0.065599 -0.181985 -0.055788 -0.049998 -0.18586 -0.055699 -0.06725100000000001 -0.185688 -0.068758 -0.07099800000000001 -0.233304 -0.052737 -0.07099800000000001 -0.231787 -0.056871 -0.076153 -0.232179 -0.008725 -0.09539 -0.21254 -0.009162 -0.08319500000000001 -0.212779 -0.011576 -0.095397 -0.209183 -0.0334227 -0.102998 -0.259593 -0.032728 -0.102998 -0.262412 -0.0337375 -0.117198 -0.258316 -0.06192 -0.118998 -0.181429 -0.065009 -0.111448 -0.181721 -0.072017 -0.119053 -0.18233 -0.045077 -0.06940499999999999 -0.241524 -0.036481 -0.067998 -0.249142 -0.037131 -0.06919599999999999 -0.250607 -0.057231 -0.049998 -0.190235 -0.036282 -0.049998 -0.22272 -0.044033 -0.049998 -0.223626 -0.035455 -0.094998 -0.268032 -0.03345 -0.080718 -0.265711 -0.033653 -0.094998 -0.269585 -0.028339 -0.062313 -0.188136 -0.021233 -0.0636 -0.183487 -0.027636 -0.062453 -0.190236 -0.034747 -0.102998 -0.25422 -0.034747 -0.117198 -0.250001 -0.034747 -0.102998 -0.249047 -0.061464 -0.07099800000000001 -0.209841 -0.062369 -0.049998 -0.20209 -0.061464 -0.049998 -0.209841 -0.044275 -0.124806 -0.232674 -0.0497035 -0.123371 -0.227009 -0.0456132 -0.12173 -0.237229 -0.028827 -0.128679 -0.225307 -0.032823 -0.128474 -0.230849 -0.035081 -0.127396 -0.235407 0.036302 -0.039998 -0.001659 0.035402 -0.039998 -0.00747301 0.024691 -0.039998 -0.024464 -0.0513867 -0.122741 -0.222061 -0.046622 -0.126471 -0.220648 -0.0511948 -0.122623 -0.223052 -0.0339658 -0.102998 -0.25739 -0.034747 -0.102998 -0.25422 -0.036966 -0.102998 -0.258815 0.035503 -0.137998 -0.00716101 0.031545 -0.137998 -0.016125 0.032042 -0.109598 -0.01583 -0.023212 -0.131398 -0.223803 -0.008378999999999999 -0.131398 -0.283984 -0.016268 -0.131398 -0.21901 -0.069103 -0.094998 -0.18211 -0.06579 -0.107966 -0.170226 -0.068189 -0.094998 -0.170106 -0.020843 -0.060114 -0.098861 -0.026849 -0.060719 -0.132272 -0.03735 -0.06260599999999999 -0.09519900000000001 0.032223 -0.082122 -0.02238 0.033206 -0.08286200000000001 -0.013636 0.033572 -0.08360099999999999 -0.012943 -0.023427 -0.127181 -0.025713 -0.013414 -0.13189 -0.032243 -0.022774 -0.137998 -0.02658 -0.0189548 -0.102998 -0.220865 -0.016268 -0.131398 -0.21901 -0.016268 -0.102998 -0.21901 0.033206 -0.137998 0.014953 0.033206 -0.039998 0.014953 0.031112 -0.039998 0.019976 -0.034747 -0.0637284 -0.250001 -0.034747 -0.057998 -0.245782 -0.034747 -0.0608632 -0.250001 -0.035565 -0.128969 -0.217398 -0.021122 -0.12593 -0.218412 -0.024551 -0.126404 -0.21416 0.008373 -0.057998 -0.283984 -2.99964e-06 -0.0579979 -0.285001 0.016263 -0.057998 -0.280992 -0.00370299 -0.062147 -0.102663 -0.003516 -0.066757 -0.136938 -0.01083 -0.06265800000000001 -0.135477 -0.030964 -0.102997 -0.270424 -0.028931 -0.094998 -0.27299 -0.028332 -0.102997 -0.27231 -0.03788 -0.067998 -0.246961 -0.0344719 -0.067998 -0.244666 -0.034747 -0.067998 -0.245782 0.035508 -0.099208 -0.00713901 0.035503 -0.137998 -0.00716101 0.034883 -0.102449 -0.00945201 -0.008378999999999999 -0.131398 -0.283984 -0.016268 -0.131398 -0.280992 -0.017284 -0.094997 -0.280436 0.008373 -0.057998 -0.216018 -0.0028281 -0.0782692 -0.215344 -0.00212157 -0.08560189999999999 -0.215258 -0.049668 -0.120374 -0.109996 -0.038544 -0.128686 -0.112365 -0.026806 -0.129703 -0.054184 -0.026806 -0.129703 -0.054184 -0.012814 -0.13337 -0.057215 -0.023427 -0.127181 -0.025713 -0.017073 -0.070427 -0.205294 -0.016665 -0.06974900000000001 -0.198437 -0.013985 -0.076269 -0.204968 -0.009162 -0.08319500000000001 -0.212779 -0.012034 -0.082993 -0.209343 -0.011576 -0.095397 -0.209183 -0.00653799 -0.060086 -0.034225 -0.013388 -0.060519 -0.03217 -0.00280299 -0.039998 -0.034889 -0.022834 -0.065247 -0.207674 -0.02251 -0.06550499999999999 -0.20529 -0.015534 -0.07106700000000001 -0.210269 -0.029873 -0.039998 -0.018243 -0.022774 -0.039998 -0.02658 -0.030053 -0.070437 -0.017043 -0.034356 -0.071198 -0.0271 -0.039228 -0.072168 -0.042965 -0.040722 -0.08209 -0.025833 -0.049668 -0.120374 -0.109996 -0.054701 -0.119633 -0.140021 -0.038544 -0.128686 -0.112365 -0.046465 -0.094998 -0.04153 -0.044547 -0.08257 -0.041831 -0.049463 -0.094998 -0.056063 0.028802 -0.131398 -0.269883 0.028802 -0.057998 -0.269883 0.032723 -0.057998 -0.262412 -0.021233 -0.0636 -0.183487 -0.012684 -0.069286 -0.184201 -0.016665 -0.06974900000000001 -0.198437 0.036247 -0.137998 0.0009799819999999999 0.035508 -0.099208 -0.00713901 0.0357 -0.09740500000000001 -0.006256 -0.0243759 -0.102998 -0.225117 -0.023212 -0.102998 -0.223803 -0.028859 -0.102998 -0.225278 -0.058648 -0.118944 -0.171066 -0.0588453 -0.119509 -0.182979 -0.047993 -0.126464 -0.17232 -0.008815999999999999 -0.10605 -0.213038 -0.008815999999999999 -0.102998 -0.213038 -0.008725 -0.09539 -0.21254 -0.013114 -0.108058 -0.201814 -0.012303 -0.113728 -0.210533 -0.011532 -0.107588 -0.210271 0.008373 -0.057998 -0.283984 0.008374009999999999 -0.131398 -0.283984 -1.99888e-06 -0.131398 -0.285001 -0.031196 -0.062566 -0.061855 -0.020843 -0.060114 -0.098861 -0.03735 -0.06260599999999999 -0.09519900000000001 -0.047993 -0.126464 -0.17232 -0.0588453 -0.119509 -0.182979 -0.058413 -0.119945 -0.185262 -0.000383994 -0.116163 -0.150124 -0.00501499 -0.122031 -0.149263 -0.00780799 -0.12149 -0.163167 0.024691 -0.039998 -0.024464 -0.009214989999999999 -0.039998 0.034258 0.00116801 -0.039998 0.036003 -0.034606 -0.107636 -0.265703 -0.036116 -0.111791 -0.261823 -0.032964 -0.102998 -0.268909 -0.032728 -0.0763397 -0.262412 -0.032728 -0.057998 -0.262412 -0.0310716 -0.0699446 -0.265568 0.029418 -0.110682 -0.035372 0.033541 -0.095485 -0.031703 0.031539 -0.110116 -0.019935 0.032223 -0.082122 -0.02238 0.035016 -0.08812399999999999 -0.009014019999999999 0.03541 -0.090421 -0.00747301 -0.034747 -0.067998 -0.249231 -0.034747 -0.0637284 -0.250001 -0.034747 -0.067998 -0.250643 -0.0217294 -0.102997 -0.277222 -0.0260095 -0.115038 -0.273041 -0.024783 -0.102997 -0.274717 -0.012034 -0.082993 -0.209343 -0.012343 -0.0954 -0.207618 -0.011576 -0.095397 -0.209183 -0.025378 -0.127937 -0.221716 -0.028827 -0.128679 -0.225307 -0.028859 -0.102998 -0.225278 -0.013686 -0.067998 -0.217787 -0.00884017 -0.067998 -0.216193 -0.0123235 -0.0659771 -0.217514 -0.022497 -0.049998 -0.20529 -0.057231 -0.049998 -0.190235 -0.023403 -0.049998 -0.197539 -0.035087 -0.102998 -0.235405 -0.028827 -0.128679 -0.225307 -0.035081 -0.127396 -0.235407 -0.024627 -0.049998 -0.212797 -0.029515 -0.062234 -0.218869 -0.029468 -0.049998 -0.218918 -0.0144225 -0.102998 -0.21831 -0.019807 -0.102998 -0.21757 -0.016268 -0.102998 -0.21901 -0.043563 -0.080983 -0.256573 -0.045625 -0.094998 -0.258458 -0.048554 -0.094998 -0.255301 -0.0321938 -0.067998 -0.236572 -0.0304037 -0.0679979 -0.233161 -0.0307675 -0.062998 -0.233855 -0.032728 -0.102998 -0.23759 -0.0349329 -0.102998 -0.241309 -0.0335092 -0.102998 -0.24076 -0.0243759 -0.102998 -0.225117 -0.023212 -0.131398 -0.223803 -0.023212 -0.102998 -0.223803 0.023298 -0.039998 0.028256 0.027792 -0.039998 0.024268 0.024691 -0.039998 -0.024464 -0.063614 -0.07618 -0.181589 -0.066635 -0.08205900000000001 -0.181875 -0.058697 -0.07023500000000001 -0.180422 -0.014708 -0.120982 -0.189504 -0.00675999 -0.115159 -0.17718 -0.010933 -0.121115 -0.176687 -0.019043 -0.065294 -0.217116 -0.015557 -0.067998 -0.215638 -0.022509 -0.06329799999999999 -0.219383 -0.008378999999999999 -0.131398 -0.283984 0.028802 -0.131398 -0.230119 0.023207 -0.131398 -0.223803 -0.010007 -0.113411 -0.213347 -0.01521 -0.119156 -0.211406 -0.010689 -0.115532 -0.213535 -0.057231 -0.049998 -0.190235 -0.024627 -0.049998 -0.212797 -0.029468 -0.049998 -0.218918 0.024691 -0.039998 -0.024464 -0.026582 -0.039998 0.022771 -0.020283 -0.039998 0.028524 -0.005627 -0.08337899999999999 -0.215459 -0.006693 -0.077352 -0.215648 -0.009162 -0.08319500000000001 -0.212779 -0.0299961 -0.102998 -0.230342 -0.028807 -0.102998 -0.230119 -0.028859 -0.102998 -0.225278 -0.0337375 -0.117198 -0.258316 -0.034747 -0.131398 -0.25422 -0.0339658 -0.102998 -0.25739 -0.022774 -0.039998 -0.02658 -0.022773 -0.062583 -0.026579 -0.030053 -0.070437 -0.017043 -0.041251 -0.062174 -0.1779 -0.047047 -0.049998 -0.178417 -0.042891 -0.06232 -0.177697 0.016863 -0.071426 -0.07238600000000001 0.021367 -0.07895099999999999 -0.07337299999999999 0.012978 -0.078932 -0.106368 -0.0319859 -0.102998 -0.236176 -0.035087 -0.102998 -0.235405 -0.032728 -0.102998 -0.23759 -0.045891 -0.126901 -0.157101 -0.047993 -0.126464 -0.17232 -0.032859 -0.130041 -0.159176 0.016263 -0.131398 -0.21901 -0.008378999999999999 -0.131398 -0.283984 0.023207 -0.131398 -0.223803 -0.0204416 -0.067998 -0.221891 -0.01974 -0.062998 -0.221406 -0.022266 -0.067998 -0.22315 -0.055897 -0.07099800000000001 -0.224066 -0.056939 -0.07099800000000001 -0.220732 -0.052737 -0.07099800000000001 -0.231787 -0.00212134 -0.0981031 -0.215258 -0.00240399 -0.102998 -0.215293 0.008373 -0.057998 -0.216018 -0.021795 -0.094998 -0.277775 -0.023212 -0.0986773 -0.276199 -0.028332 -0.102997 -0.27231 0.035786 -0.094414 -0.00581501 0.036247 -0.137998 0.0009799819999999999 0.035788 -0.09544 -0.00580301 -0.037131 -0.06919599999999999 -0.250607 -0.033234 -0.07478029999999999 -0.260359 -0.03345 -0.080718 -0.265711 -0.037185 -0.065271 -0.242165 -0.035583 -0.06309099999999999 -0.23666 -0.034819 -0.062778 -0.23491 0.018876 -0.039998 0.031088 0.023298 -0.039998 0.028256 0.024691 -0.039998 -0.024464 -0.039448 -0.108685 -0.021917 -0.042425 -0.094998 -0.023232 -0.046465 -0.094998 -0.04153 -0.046303 -0.062916 -0.178326 -0.052157 -0.049998 -0.181269 -0.047357 -0.0631 -0.178521 -0.01974 -0.062998 -0.221406 -0.023212 -0.057998 -0.223803 -0.022266 -0.067998 -0.22315 -0.013446 -0.039998 -0.032316 -0.022773 -0.062583 -0.026579 -0.022774 -0.039998 -0.02658 -0.043426 -0.062724 -0.146549 -0.053559 -0.071121 -0.126929 -0.042036 -0.062669 -0.129234 -0.034828 -0.094998 0.00348899 -0.036206 -0.081192 -0.010436 -0.039489 -0.094998 -0.011609 -0.023114 -0.062375 -0.02934 -0.01672 -0.061015 -0.030618 -0.028074 -0.06254899999999999 -0.045339 -0.022509 -0.06329799999999999 -0.219383 -0.024835 -0.062582 -0.221237 -0.032237 -0.061986 -0.222914 -0.024551 -0.126404 -0.21416 -0.016925 -0.122882 -0.215977 -0.013038 -0.118998 -0.214307 0.029164 -0.076123 -0.021844 0.029084 -0.08015 -0.039744 0.025148 -0.073194 -0.03896 -0.0260095 -0.060498 -0.226961 -0.023212 -0.057998 -0.223803 -0.028807 -0.057998 -0.230119 -0.010009 -0.07188899999999999 -0.216485 -0.00653584 -0.07414800000000001 -0.215794 -0.00884017 -0.067998 -0.216193 -0.00653584 -0.07414800000000001 -0.215794 -0.008378999999999999 -0.057998 -0.216018 -0.00884017 -0.067998 -0.216193 -0.046303 -0.062916 -0.178326 -0.047357 -0.0631 -0.178521 -0.044694 -0.06277199999999999 -0.163934 -0.016925 -0.122882 -0.215977 -0.019773 -0.124949 -0.217628 -0.00891 -0.107254 -0.21306 0.036247 -0.039998 0.000979986 0.036302 -0.039998 -0.001659 0.024691 -0.039998 -0.024464 -0.012724 -0.076705 -0.209545 -0.013985 -0.076269 -0.204968 -0.012034 -0.082993 -0.209343 -0.008378999999999999 -0.057998 -0.283984 -2.99964e-06 -0.0579979 -0.285001 -1.99888e-06 -0.131398 -0.285001 -0.000383994 -0.116163 -0.150124 -0.00780799 -0.12149 -0.163167 -0.003402 -0.115569 -0.163868 -0.052093 -0.08112999999999999 -0.246067 -0.058675 -0.08124099999999999 -0.234455 -0.045077 -0.06940499999999999 -0.241524 -0.03788 -0.067998 -0.246961 -0.033834 -0.067998 -0.232697 -0.0341418 -0.067998 -0.239829 -0.056939 -0.07099800000000001 -0.220732 -0.055771 -0.069714 -0.220433 -0.052737 -0.07099800000000001 -0.231787 0.023207 -0.057998 -0.276199 0.028802 -0.131398 -0.269883 0.023207 -0.131398 -0.276199 -0.0249051 -0.102998 -0.225714 -0.0253768 -0.102998 -0.226247 -0.023212 -0.131398 -0.223803 -0.0337375 -0.117198 -0.258316 -0.0339658 -0.102998 -0.25739 -0.0335584 -0.102998 -0.259043 -0.035803 -0.108542 -0.00859101 -0.033607 -0.112586 -0.00902201 -0.034887 -0.098269 0.00279799 -0.062369 -0.049998 -0.20209 -0.061464 -0.07099800000000001 -0.209841 -0.062369 -0.07099800000000001 -0.20209 0.008237009999999999 -0.061996 -0.053063 0.010922 -0.062035 -0.036126 0.015328 -0.06553 -0.054574 -1.99507e-06 -0.131398 -0.215001 -0.0041905 -0.117198 -0.21551 -0.008378999999999999 -0.131398 -0.216018 -0.054278 -0.117226 -0.231933 -0.068758 -0.118998 -0.233305 -0.056969 -0.113801 -0.232188 -0.0090645 -0.0746965 -0.215135 -0.010009 -0.07188899999999999 -0.216485 -0.009834000000000001 -0.077057 -0.213119 -0.0253768 -0.102998 -0.226247 -0.0249051 -0.102998 -0.225714 -0.028859 -0.102998 -0.225278 -0.012316 -0.08247400000000001 -0.198331 -0.008795000000000001 -0.075515 -0.184517 -0.007637 -0.082319 -0.18461 -0.034747 -0.057998 -0.25422 -0.034747 -0.0694588 -0.252902 -0.034747 -0.067998 -0.252601 -0.012724 -0.076705 -0.209545 -0.009834000000000001 -0.077057 -0.213119 -0.015534 -0.07106700000000001 -0.210269 -0.032728 -0.131398 -0.262412 -0.0307675 -0.117198 -0.266147 -0.028807 -0.131398 -0.269883 -0.035603 -0.049998 -0.179336 -0.034101 -0.061824 -0.180269 -0.031983 -0.061887 -0.18193 0.020278 -0.123345 -0.028527 0.025371 -0.117444 -0.034582 0.022954 -0.121125 -0.026485 0.021022 -0.071631 -0.055785 0.016863 -0.071426 -0.07238600000000001 0.015328 -0.06553 -0.054574 0.032223 -0.082122 -0.02238 0.035786 -0.094414 -0.00581501 0.035788 -0.09544 -0.00580301 -0.047993 -0.126464 -0.17232 -0.049958 -0.126383 -0.187824 -0.035318 -0.129524 -0.173813 -0.003025 -0.08194 -0.169916 -0.000148996 -0.095447 -0.16415 -0.002018 -0.095441 -0.169715 -0.024636 -0.067998 -0.221068 -0.029836 -0.06207 -0.226616 -0.027767 -0.062132 -0.224056 -0.03735 -0.06260599999999999 -0.09519900000000001 -0.026849 -0.060719 -0.132272 -0.042036 -0.062669 -0.129234 -0.034048 -0.039998 -0.008119009999999999 -0.034828 -0.094998 0.00348899 -0.03489 -0.039998 0.00279899 0.00358101 -0.060637 -0.034817 0.008041009999999999 -0.06154 -0.033737 0.010922 -0.062035 -0.036126 -0.057071 -0.107012 -0.239238 -0.054278 -0.117226 -0.231933 -0.056969 -0.113801 -0.232188 -0.035087 -0.102998 -0.235405 -0.0299961 -0.102998 -0.230342 -0.028859 -0.102998 -0.225278 -0.052113 -0.06517000000000001 -0.181323 -0.052157 -0.049998 -0.181269 -0.052941 -0.065599 -0.181985 0.025389 -0.079096 -0.056714 0.026925 -0.09553 -0.064763 0.021367 -0.07895099999999999 -0.07337299999999999 0.008374009999999999 -0.131398 -0.216018 0.008373 -0.057998 -0.216018 -1.99507e-06 -0.131398 -0.215001 -0.024636 -0.067998 -0.221068 -0.013686 -0.067998 -0.217787 -0.0189327 -0.067998 -0.219552 -0.024362 -0.063959 -0.21226 -0.026485 -0.062779 -0.215759 -0.024627 -0.049998 -0.212797 -0.023212 -0.131398 -0.276199 -0.016268 -0.131398 -0.280992 -0.008378999999999999 -0.131398 -0.283984 0.002578 -0.065321 -0.104062 -0.00370299 -0.062147 -0.102663 0.00428401 -0.062021 -0.069631 -0.062009 -0.108246 -0.138661 -0.056918 -0.108547 -0.108453 -0.062363 -0.094998 -0.125247 -0.066541 -0.1079 -0.181867 -0.07356699999999999 -0.118998 -0.182532 -0.072017 -0.119053 -0.18233 0.016863 -0.071426 -0.07238600000000001 0.011027 -0.065356 -0.071107 0.015328 -0.06553 -0.054574 -0.00884017 -0.067998 -0.216193 -0.008378999999999999 -0.057998 -0.216018 -0.0123235 -0.0659771 -0.217514 0.016863 -0.071426 -0.07238600000000001 0.021022 -0.071631 -0.055785 0.021367 -0.07895099999999999 -0.07337299999999999 -0.003025 -0.08194 -0.169916 -0.004483 -0.095432 -0.177054 -0.0049804 -0.088686 -0.177374 -0.027461 -0.127109 -0.202655 -0.024551 -0.126404 -0.21416 -0.017449 -0.120256 -0.202053 -0.060239 -0.049998 -0.194583 -0.062369 -0.07099800000000001 -0.20209 -0.060239 -0.07099800000000001 -0.194583 -0.0370101 -0.109485 -0.262435 -0.036116 -0.111791 -0.261823 -0.034606 -0.107636 -0.265703 -0.055788 -0.049998 -0.18586 -0.057231 -0.049998 -0.190235 -0.055699 -0.06725100000000001 -0.185688 -0.016925 -0.122882 -0.215977 -0.00891 -0.107254 -0.21306 -0.009391 -0.111495 -0.213179 -0.00891 -0.107254 -0.21306 -0.011576 -0.095397 -0.209183 -0.011532 -0.107588 -0.210271 -0.0214921 -0.0925914 -0.277554 -0.0199652 -0.0921587 -0.27844 -0.017284 -0.094997 -0.280436 -0.028807 -0.0833648 -0.269883 -0.0269275 -0.08767800000000001 -0.272574 -0.028931 -0.094998 -0.27299 0.007499 -0.095485 -0.139004 0.009158009999999999 -0.110451 -0.122524 0.002111 -0.10942 -0.150588 -0.063614 -0.07618 -0.181589 -0.07356699999999999 -0.07099800000000001 -0.182532 -0.066635 -0.08205900000000001 -0.181875 -0.037126 -0.124813 -0.24216 -0.036792 -0.125578 -0.240488 -0.040037 -0.124841 -0.23872 -0.037904 -0.118998 -0.252736 -0.036911 -0.114414 -0.258801 -0.036966 -0.102998 -0.258815 -0.049668 -0.120374 -0.109996 -0.056918 -0.108547 -0.108453 -0.062009 -0.108246 -0.138661 -0.0306243 -0.067998 -0.26642 -0.0293392 -0.067998 -0.268869 -0.0294052 -0.0795941 -0.268743 -0.056918 -0.108547 -0.108453 -0.054764 -0.094998 -0.083718 -0.059351 -0.094998 -0.107759 -0.053559 -0.071121 -0.126929 -0.048222 -0.07156700000000001 -0.09278500000000001 -0.042036 -0.062669 -0.129234 0.023357 -0.111167 -0.065049 0.009158009999999999 -0.110451 -0.122524 0.020761 -0.09553200000000001 -0.090212 -0.006163 -0.067844 -0.153244 -0.00468 -0.07505100000000001 -0.169678 -0.008943 -0.068842 -0.169065 -0.031735 -0.06163 -0.165798 -0.017612 -0.06343500000000001 -0.16783 -0.021233 -0.0636 -0.183487 -0.037126 -0.124813 -0.24216 -0.037626 -0.123668 -0.244667 -0.035081 -0.127396 -0.235407 0.025389 -0.079096 -0.056714 0.029163 -0.09553 -0.05552 0.026925 -0.09553 -0.064763 -0.0301314 -0.067998 -0.232642 -0.028807 -0.067998 -0.230119 -0.0307675 -0.062998 -0.233855 -0.0260095 -0.062998 -0.226961 -0.0280447 -0.067998 -0.229259 -0.023212 -0.067998 -0.223803 0.033408 -0.106873 -0.013307 0.035503 -0.137998 -0.00716101 0.032042 -0.109598 -0.01583 -0.000148996 -0.095447 -0.16415 0.001094 -0.08108700000000001 -0.154548 0.002275 -0.095455 -0.156935 -0.0301314 -0.067998 -0.232642 -0.033834 -0.067998 -0.232697 -0.028807 -0.067998 -0.230119 -0.028807 -0.131398 -0.269883 -0.0282288 -0.102997 -0.270536 -0.0266445 -0.102997 -0.272324 0.020104 -0.123114 -0.033553 0.020278 -0.123345 -0.028527 0.018147 -0.12471 -0.029694 -0.052437 -0.107055 -0.246859 -0.057071 -0.107012 -0.239238 -0.054341 -0.094998 -0.247534 0.012978 -0.078932 -0.106368 0.021367 -0.07895099999999999 -0.07337299999999999 0.0188977 -0.087232 -0.0903089 -2.99964e-06 -0.0579979 -0.285001 0.008373 -0.057998 -0.283984 -1.99888e-06 -0.131398 -0.285001 -0.0137 -0.060008 -0.065689 -0.010127 -0.060008 -0.049157 0.00428401 -0.062021 -0.069631 0.00173001 -0.072867 -0.137987 -0.003516 -0.066757 -0.136938 0.002578 -0.065321 -0.104062 -0.0662321 -0.0849767 -0.170419 -0.06689290000000001 -0.08831550000000001 -0.170419 -0.064813 -0.081788 -0.16105 0.023207 -0.057998 -0.223803 0.016263 -0.131398 -0.21901 0.023207 -0.131398 -0.223803 -0.044694 -0.06277199999999999 -0.163934 -0.050569 -0.06436799999999999 -0.180088 -0.052113 -0.06517000000000001 -0.181323 -0.022363 -0.127685 -0.17534 -0.010933 -0.121115 -0.176687 -0.00780799 -0.12149 -0.163167 -0.00653584 -0.07414800000000001 -0.215794 -0.00812 -0.074265 -0.215957 -0.00614141 -0.07561610000000001 -0.215678 0.008115010000000001 -0.039998 -0.034047 0.024691 -0.039998 -0.024464 0.018239 -0.039998 -0.029872 -0.050376 -0.126442 -0.204039 -0.038989 -0.129258 -0.203352 -0.037903 -0.12941 -0.1884 -0.042758 -0.0669136 -0.23641 -0.034819 -0.062778 -0.23491 -0.045077 -0.06940499999999999 -0.241524 -0.034325 -0.067998 -0.255932 -0.0333971 -0.067998 -0.259697 -0.0337503 -0.0725065 -0.258264 -0.05443 -0.07099800000000001 -0.227973 -0.07356699999999999 -0.07099800000000001 -0.182532 -0.055897 -0.07099800000000001 -0.224066 -0.037626 -0.117517 -0.254781 -0.046949 -0.107107 -0.253978 -0.040674 -0.10718 -0.260584 0.019976 -0.067373 -0.037929 0.027925 -0.07441300000000001 -0.021615 0.029164 -0.076123 -0.021844 0.007499 -0.095485 -0.139004 0.002111 -0.10942 -0.150588 0.003933 -0.09546499999999999 -0.151245 0.036247 -0.039998 0.000979986 0.035752 -0.093403 -0.00599601 0.035596 -0.0915 -0.00674901 -0.00780799 -0.12149 -0.163167 -0.010933 -0.121115 -0.176687 -0.003402 -0.115569 -0.163868 -0.036966 -0.102998 -0.258815 -0.032964 -0.102998 -0.268909 -0.0330778 -0.102998 -0.263984 -0.034747 -0.117198 -0.250001 -0.034747 -0.131398 -0.245782 -0.034747 -0.102998 -0.249047 -0.017073 -0.070427 -0.205294 -0.012724 -0.076705 -0.209545 -0.015534 -0.07106700000000001 -0.210269 -0.042425 -0.094998 -0.023232 -0.040722 -0.08209 -0.025833 -0.044547 -0.08257 -0.041831 -0.050376 -0.126442 -0.204039 -0.046622 -0.126471 -0.220648 -0.0530965 -0.122945 -0.213171 -0.017612 -0.06343500000000001 -0.16783 -0.008943 -0.068842 -0.169065 -0.012684 -0.069286 -0.184201 -2.99964e-06 -0.0579979 -0.285001 -0.023212 -0.057998 -0.223803 -0.016268 -0.057998 -0.21901 -0.032728 -0.102998 -0.262412 -0.032728 -0.131398 -0.262412 -0.0337375 -0.117198 -0.258316 -0.0317456 -0.102998 -0.235718 -0.0307675 -0.117198 -0.233855 -0.0314748 -0.102998 -0.235202 -0.0303241 -0.102998 -0.23301 -0.035087 -0.102998 -0.235405 -0.0314748 -0.102998 -0.235202 -0.058648 -0.118944 -0.171066 -0.065009 -0.111448 -0.181721 -0.061919 -0.116225 -0.181428 0.00173001 -0.072867 -0.137987 0.002578 -0.065321 -0.104062 0.008484 -0.07136099999999999 -0.105372 0.00667501 -0.039998 0.035572 0.00667102 -0.137998 0.035573 0.012177 -0.137998 0.0342 -0.058648 -0.118944 -0.171066 -0.066541 -0.1079 -0.181867 -0.065009 -0.111448 -0.181721 0.035402 -0.039998 -0.00747301 0.031876 -0.080175 -0.016158 0.031544 -0.039998 -0.016125 -0.0266445 -0.102997 -0.272324 -0.0282288 -0.102997 -0.270536 -0.028332 -0.102997 -0.27231 -0.012538 -0.102998 -0.217595 -0.0144225 -0.102998 -0.21831 -0.0123235 -0.117198 -0.217514 -0.03788 -0.102998 -0.246961 -0.0349329 -0.102998 -0.241309 -0.035087 -0.102998 -0.235405 -0.0337375 -0.0617524 -0.258316 -0.034747 -0.057998 -0.25422 -0.032728 -0.057998 -0.262412 -0.0307675 -0.117198 -0.233855 -0.0303241 -0.102998 -0.23301 -0.0314748 -0.102998 -0.235202 -0.022497 -0.049998 -0.20529 -0.02251 -0.06550499999999999 -0.20529 -0.024627 -0.049998 -0.212797 -0.05443 -0.07099800000000001 -0.227973 -0.055897 -0.07099800000000001 -0.224066 -0.052737 -0.07099800000000001 -0.231787 -0.014708 -0.120982 -0.189504 -0.027461 -0.127109 -0.202655 -0.017449 -0.120256 -0.202053 -0.0196111 -0.067998 -0.221317 -0.024636 -0.067998 -0.221068 -0.0189327 -0.067998 -0.219552 -0.047488 -0.117421 -0.24361 -0.0423461 -0.119877 -0.245385 -0.042263 -0.117494 -0.250094 -0.034828 -0.094998 0.00348899 -0.039489 -0.094998 -0.011609 -0.035803 -0.108542 -0.00859101 -0.02251 -0.06550499999999999 -0.20529 -0.024362 -0.063959 -0.21226 -0.024627 -0.049998 -0.212797 -0.0197401 -0.060498 -0.221406 -0.01974 -0.062998 -0.221406 -0.016268 -0.057998 -0.21901 -0.047487 -0.124698 -0.226704 -0.044452 -0.126287 -0.226534 -0.046622 -0.126471 -0.220648 -0.008378999999999999 -0.102998 -0.216018 -0.0120057 -0.102998 -0.216492 -0.0114314 -0.102998 -0.217176 -0.01672 -0.061015 -0.030618 -0.013446 -0.039998 -0.032316 -0.013388 -0.060519 -0.03217 0.024691 -0.137998 -0.024464 0.025406 -0.118766 -0.024322 0.031545 -0.137998 -0.016125 0.025389 -0.079096 -0.056714 0.021022 -0.071631 -0.055785 0.025148 -0.073194 -0.03896 -0.026849 -0.060719 -0.132272 -0.029338 -0.061197 -0.149079 -0.042036 -0.062669 -0.129234 -0.041233 -0.049998 -0.177738 -0.041251 -0.062174 -0.1779 -0.038327 -0.061912 -0.178263 -0.010933 -0.121115 -0.176687 -0.00675999 -0.115159 -0.17718 -0.003402 -0.115569 -0.163868 -0.030235 -0.12028 -0.017474 -0.039448 -0.108685 -0.021917 -0.031887 -0.120562 -0.023395 0.017841 -0.039998 0.031751 0.024691 -0.039998 -0.024464 0.012176 -0.039998 0.0342 -0.036206 -0.081192 -0.010436 -0.040722 -0.08209 -0.025833 -0.039489 -0.094998 -0.011609 -0.037903 -0.12941 -0.1884 -0.022363 -0.127685 -0.17534 -0.035318 -0.129524 -0.173813 -0.036282 -0.049998 -0.22272 -0.033143 -0.062024 -0.221268 -0.036328 -0.062118 -0.222573 -0.031983 -0.061887 -0.18193 -0.021233 -0.0636 -0.183487 -0.031137 -0.061966 -0.183063 0.026925 -0.09553 -0.064763 0.029163 -0.09553 -0.05552 0.023357 -0.111167 -0.065049 -0.022509 -0.06329799999999999 -0.219383 -0.032237 -0.061986 -0.222914 -0.033143 -0.062024 -0.221268 -0.0214921 -0.0925914 -0.277554 -0.017284 -0.094997 -0.280436 -0.025963 -0.094998 -0.2751 -0.047727 -0.082469 -0.058234 -0.048222 -0.07156700000000001 -0.09278500000000001 -0.054037 -0.08229 -0.091492 -0.015557 -0.067998 -0.215638 -0.024636 -0.067998 -0.221068 -0.024835 -0.062582 -0.221237 -0.034747 -0.0637284 -0.250001 -0.034747 -0.057998 -0.25422 -0.034747 -0.067998 -0.252601 0.021367 -0.07895099999999999 -0.07337299999999999 0.020761 -0.09553200000000001 -0.090212 0.0188977 -0.087232 -0.0903089 -0.025378 -0.127937 -0.221716 -0.031908 -0.128859 -0.223879 -0.022862 -0.12675 -0.219763 -0.06864199999999999 -0.100682 -0.182065 -0.069103 -0.094998 -0.18211 -0.07356699999999999 -0.118998 -0.182532 -0.042891 -0.06232 -0.177697 -0.047047 -0.049998 -0.178417 -0.046303 -0.062916 -0.178326 -0.030964 -0.102997 -0.270424 -0.032964 -0.102998 -0.268909 -0.028931 -0.094998 -0.27299 -0.042425 -0.094998 -0.023232 -0.044547 -0.08257 -0.041831 -0.046465 -0.094998 -0.04153 -0.023212 -0.057998 -0.276199 -0.0217294 -0.0679979 -0.277222 -0.0254514 -0.0873768 -0.273671 -0.045077 -0.06940499999999999 -0.241524 -0.03788 -0.067998 -0.246961 -0.036481 -0.067998 -0.249142 -0.068758 -0.118998 -0.233305 -0.061713 -0.101573 -0.232638 -0.059939 -0.107883 -0.232469 -0.005627 -0.08337899999999999 -0.215459 -0.0028281 -0.0782692 -0.215344 -0.0047623 -0.07911310000000001 -0.215472 0.010922 -0.062035 -0.036126 0.010685 -0.062075 -0.033096 0.020278 -0.06684 -0.028527 -0.008815999999999999 -0.10605 -0.213038 -0.019807 -0.102998 -0.21757 -0.008815999999999999 -0.102998 -0.213038 -0.028931 -0.094998 -0.27299 -0.0269275 -0.08767800000000001 -0.272574 -0.025963 -0.094998 -0.2751 -0.0337375 -0.062998 -0.241686 -0.0337375 -0.060498 -0.241686 -0.034747 -0.057998 -0.245782 -0.0337375 -0.117198 -0.241686 -0.034747 -0.131398 -0.245782 -0.032728 -0.131398 -0.23759 -0.008135979999999999 -0.137998 0.034439 -0.020283 -0.039998 0.028524 -0.020283 -0.137998 0.028524 -0.029842 -0.080358 -0.268227 -0.0320424 -0.0768882 -0.263718 -0.0294052 -0.0795941 -0.268743 -0.034356 -0.071198 -0.0271 -0.028074 -0.06254899999999999 -0.045339 -0.039228 -0.072168 -0.042965 0.031544 -0.039998 -0.016125 0.024691 -0.039998 -0.024464 0.033809 -0.039998 -0.012393 -0.028859 -0.102998 -0.225278 -0.023212 -0.102998 -0.223803 -0.0216408 -0.102998 -0.221424 -0.059219 -0.119502 -0.181032 -0.058648 -0.118944 -0.171066 -0.061919 -0.116225 -0.181428 -0.041227 -0.062847 -0.226878 -0.034819 -0.062778 -0.23491 -0.051395 -0.069561 -0.231297 -0.00614141 -0.07561610000000001 -0.215678 -0.00812 -0.074265 -0.215957 -0.006693 -0.077352 -0.215648 -0.029836 -0.06207 -0.226616 -0.032237 -0.061986 -0.222914 -0.027767 -0.062132 -0.224056 -2.99964e-06 -0.0579979 -0.285001 0.008373 -0.057998 -0.216018 0.016263 -0.057998 -0.21901 0.023357 -0.111167 -0.065049 0.029418 -0.110682 -0.035372 0.019315 -0.118087 -0.06417299999999999 -0.0430425 -0.123603 -0.236991 -0.0439799 -0.120915 -0.241308 -0.0456132 -0.12173 -0.237229 -0.044694 -0.06277199999999999 -0.163934 -0.057094 -0.07038999999999999 -0.162155 -0.05547 -0.07073400000000001 -0.144385 -0.0243759 -0.102998 -0.225117 -0.0249051 -0.102998 -0.225714 -0.023212 -0.131398 -0.223803 0.03541 -0.090421 -0.00747301 0.035016 -0.08812399999999999 -0.009014019999999999 0.035402 -0.039998 -0.00747301 -0.014243 -0.063067 -0.151789 -0.006163 -0.067844 -0.153244 -0.008943 -0.068842 -0.169065 0.00965825 -0.156998 0.0303153 0.00427813 -0.156998 0.0315094 -0.00119713 -0.156998 0.0311578 -0.013446 -0.137997 -0.282316 -0.0130552 -0.1825 -0.28405 -0.022774 -0.182497 -0.27658 -0.0358064 -0.189498 -0.229342 0.0269129 -0.189497 -0.240452 0.0220503 -0.189497 -0.231162 0.0269129 -0.189497 -0.240452 -0.0358064 -0.189498 -0.229342 0.0277921 -0.189497 -0.252355 0.027792 -0.137998 0.024268 0.023298 -0.137998 0.028256 0.0249496 -0.149998 0.0267196 0.0319824 -0.149998 0.018322 0.0237806 -0.156998 0.0198468 0.0255505 -0.156998 0.0156854 -0.044946 -0.137998 -0.226035 0.034044 -0.137997 -0.241883 0.034886 -0.137997 -0.252801 -0.0477357 -0.189498 -0.184157 -0.0360055 -0.189134 -0.179117 -0.0298779 -0.188468 -0.161935 -0.011002 -0.182498 -0.216775 -0.011002 -0.137998 -0.216775 -0.0156101 -0.182498 -0.203355 -0.056865 -0.137998 -0.17605 -0.044946 -0.137998 -0.226035 -0.044946 -0.182498 -0.226035 0.0171507 -0.15 0.0321037 0.017841 -0.137998 0.03175 0.012177 -0.137998 0.0342 0.018239 -0.182497 -0.279871 0.00982823 -0.189497 -0.277838 -0.00345781 -0.189497 -0.281249 -0.019649 -0.149998 -0.119943 -0.0201871 -0.149998 -0.122778 -0.019649 -0.137998 -0.119943 -0.058044 -0.175225 -0.157039 -0.0578833 -0.182498 -0.162331 -0.050628 -0.177738 -0.148859 -0.0363383 -0.156998 -0.073647 -0.039966 -0.149998 -0.060476 -0.0460505 -0.149998 -0.08283790000000001 -0.0358064 -0.189498 -0.229342 -0.0277696 -0.189498 -0.250156 0.0277921 -0.189497 -0.252355 -0.00326398 -0.15 0.035671 -0.00119713 -0.156998 0.0311578 0.00176102 -0.15 0.036001 -0.0476516 -0.156998 -0.115832 -0.055576 -0.149998 -0.118356 -0.0555759 -0.151393 -0.127995 0.00443301 -0.149998 -0.050197 -0.0169633 -0.156998 -0.0808022 -0.011306 -0.149998 -0.08529399999999999 0.0120559 -0.156998 0.028325 0.0169921 -0.156998 0.0254633 0.0249496 -0.149998 0.0267196 0.029869 -0.182497 -0.23176 0.02277 -0.137997 -0.223422 0.02277 -0.182497 -0.223422 -0.034047 -0.182498 -0.258119 -0.034047 -0.137998 -0.258119 -0.029873 -0.137998 -0.268242 -0.008135979999999999 -0.137998 0.034439 -0.00326398 -0.15 0.035671 0.00176102 -0.15 0.036001 0.034044 -0.182497 -0.241883 0.034886 -0.182497 -0.252801 0.034044 -0.137997 -0.241883 -0.0225231 -0.156998 0.0155764 0.0281997 -0.156998 0.00854457 0.0255505 -0.156998 0.0156854 0.0281997 -0.156998 0.00854457 0.0342069 -0.149998 0.0132172 0.0255505 -0.156998 0.0156854 0.0313327 -0.149998 -0.0171439 0.02797 -0.149998 -0.021651 0.031545 -0.137998 -0.016125 -0.020283 -0.149998 0.028524 -0.0115818 -0.149998 0.0333791 -0.020283 -0.137998 0.028524 -0.0508655 -0.189241 -0.162856 -0.0501208 -0.189241 -0.172523 -0.0298779 -0.188468 -0.161935 -0.019649 -0.137998 -0.119943 -0.0201871 -0.149998 -0.122778 -0.022928 -0.178374 -0.160795 -0.0219334 -0.182498 -0.168339 -0.0242753 -0.189498 -0.196308 -0.0156101 -0.182498 -0.203355 -0.0298721 -0.182497 -0.268242 -0.0220408 -0.189497 -0.268871 -0.0269619 -0.189498 -0.258688 -0.050628 -0.177738 -0.148859 -0.0273992 -0.156998 -0.123236 -0.0493451 -0.156998 -0.124141 -0.0358064 -0.189498 -0.229342 -0.044946 -0.182498 -0.226035 -0.0363225 -0.182498 -0.24537 0.008116 -0.137997 -0.284047 -0.002802 -0.137997 -0.284889 -0.013446 -0.137997 -0.282316 0.034886 -0.182497 -0.252801 0.0244819 -0.189497 -0.262816 0.032313 -0.182497 -0.263445 -0.031163 -0.149998 0.015936 -0.032318 -0.137998 0.013442 -0.0325361 -0.149998 0.011096 0.036247 -0.137998 0.0009799819999999999 0.0363095 -0.149998 0.00153579 0.0361584 -0.149998 -0.00332059 0.00443301 -0.149998 -0.050197 0.0190888 -0.137992 -0.0323898 0.02797 -0.137998 -0.021651 -0.026582 -0.137998 0.02277 -0.022692 -0.149998 0.026648 -0.020283 -0.149998 0.028524 0.032313 -0.182497 -0.263445 0.026577 -0.182497 -0.272773 0.032313 -0.137997 -0.263445 0.0120559 -0.156998 0.028325 0.00965825 -0.156998 0.0303153 -0.00119713 -0.156998 0.0311578 0.035503 -0.137998 -0.00716101 0.0337698 -0.149998 -0.0124852 0.031545 -0.137998 -0.016125 0.0237806 -0.156998 0.0198468 0.0208184 -0.156998 0.0230108 -0.0117197 -0.156998 0.0263204 0.0171507 -0.15 0.0321037 0.00965825 -0.156998 0.0303153 0.0203086 -0.149998 0.0302513 0.026577 -0.137997 -0.272773 0.018239 -0.137997 -0.279871 -0.022774 -0.137997 -0.27658 0.02277 -0.182497 -0.223422 0.013442 -0.182498 -0.217686 0.0117258 -0.189497 -0.221248 0.00965825 -0.156998 0.0303153 0.0120559 -0.156998 0.028325 0.0203086 -0.149998 0.0302513 -0.0273992 -0.156998 -0.123236 -0.0267148 -0.156998 -0.119631 -0.0476516 -0.156998 -0.115832 -0.058044 -0.137998 -0.157039 -0.0570253 -0.182498 -0.173467 -0.0578833 -0.182498 -0.162331 -0.055576 -0.149998 -0.118356 -0.055576 -0.137998 -0.118356 -0.0555759 -0.151393 -0.127995 -0.0363383 -0.156998 -0.073647 -0.0203749 -0.156998 -0.0947291 -0.0169633 -0.156998 -0.0808022 -0.0273992 -0.156998 -0.123236 -0.019649 -0.149998 -0.119943 -0.0267148 -0.156998 -0.119631 -0.0267758 -0.156998 -0.0210155 -0.039966 -0.149998 -0.060476 -0.0324414 -0.156998 -0.0576595 -0.034752 -0.149998 -0.00418302 -0.033792 -0.137998 -0.020934 -0.033792 -0.149998 -0.020934 0.0357745 -0.149998 0.0069537 0.0342069 -0.149998 0.0132172 0.0281997 -0.156998 0.00854457 -0.011002 -0.137998 -0.216775 0.013442 -0.137998 -0.217686 0.02277 -0.137997 -0.223422 0.0337698 -0.149998 -0.0124852 0.0267455 -0.156998 -0.0116438 0.0242157 -0.156998 -0.0156431 -0.0163071 -0.153035 -0.094143 -0.015277 -0.149998 -0.102992 -0.011306 -0.149998 -0.08529399999999999 0.026577 -0.137997 -0.272773 -0.022774 -0.137997 -0.27658 -0.029873 -0.137998 -0.268242 -0.015277 -0.149998 -0.102992 -0.015277 -0.137998 -0.102992 -0.011306 -0.137998 -0.08529399999999999 -0.022928 -0.178374 -0.160795 -0.0201871 -0.149998 -0.122778 -0.0299282 -0.186882 -0.160046 0.00443301 -0.137998 -0.050197 -0.039966 -0.137998 -0.060476 -0.00280198 -0.137998 -0.034889 -0.011306 -0.149998 -0.08529399999999999 -0.011306 -0.137998 -0.08529399999999999 0.00443301 -0.137998 -0.050197 -0.016335 -0.137998 -0.201244 -0.022835 -0.179996 -0.162726 -0.0219334 -0.182498 -0.168339 -0.022774 -0.137997 -0.27658 -0.022774 -0.182497 -0.27658 -0.0298721 -0.182497 -0.268242 0.001314 -0.182498 -0.215228 -0.011002 -0.182498 -0.216775 -0.000783752 -0.189498 -0.217156 -0.00112887 -0.156998 -0.0459391 -0.0267758 -0.156998 -0.0210155 -0.0324414 -0.156998 -0.0576595 0.013442 -0.182498 -0.217686 0.001314 -0.182498 -0.215228 -0.000783752 -0.189498 -0.217156 -0.0460505 -0.149998 -0.08283790000000001 -0.055576 -0.137998 -0.118356 -0.055576 -0.149998 -0.118356 -0.0203749 -0.156998 -0.0947291 -0.0163071 -0.153035 -0.094143 -0.011306 -0.149998 -0.08529399999999999 0.029869 -0.137997 -0.231759 0.02277 -0.137997 -0.223422 0.029869 -0.182497 -0.23176 -0.022774 -0.182497 -0.27658 -0.0130552 -0.1825 -0.28405 -0.0132689 -0.189497 -0.276947 0.0277921 -0.189497 -0.252355 -0.0277696 -0.189498 -0.250156 0.0244819 -0.189497 -0.262816 -0.022692 -0.149998 0.026648 -0.026582 -0.137998 0.02277 -0.031163 -0.149998 0.015936 -0.0144049 -0.1895 -0.218377 0.0165033 -0.189497 -0.22686 0.0117258 -0.189497 -0.221248 0.013442 -0.137998 -0.217686 -0.00812 -0.137998 -0.215956 0.00279801 -0.137998 -0.215114 -0.039966 -0.149998 -0.060476 -0.033792 -0.149998 -0.020934 -0.039966 -0.137998 -0.060476 0.0237806 -0.156998 0.0198468 0.0319824 -0.149998 0.018322 0.0296546 -0.149998 0.0221127 -0.00345781 -0.189497 -0.281249 0.00982823 -0.189497 -0.277838 -0.0132689 -0.189497 -0.276947 -0.0203749 -0.156998 -0.0947291 -0.0238631 -0.156998 -0.108253 -0.0190544 -0.154031 -0.101491 0.0169921 -0.156998 0.0254633 -0.0098446 -0.156998 0.0277807 -0.0117197 -0.156998 0.0263204 -0.0363225 -0.182498 -0.24537 -0.034047 -0.137998 -0.258119 -0.034047 -0.182498 -0.258119 -0.0269619 -0.189498 -0.258688 -0.0277696 -0.189498 -0.250156 -0.034047 -0.182498 -0.258119 -0.050628 -0.177738 -0.148859 -0.0508655 -0.189241 -0.162856 -0.0298779 -0.188468 -0.161935 -0.055576 -0.137998 -0.118356 -0.019649 -0.137998 -0.119943 -0.058044 -0.137998 -0.157039 0.0118795 -0.149998 0.0342979 0.0171507 -0.15 0.0321037 0.012177 -0.137998 0.0342 -0.033792 -0.137998 -0.020934 -0.029873 -0.137998 -0.018243 -0.022774 -0.137998 -0.02658 -0.0567022 -0.153255 -0.130855 -0.058044 -0.175225 -0.157039 -0.0493451 -0.156998 -0.124141 0.0363095 -0.149998 0.00153579 0.0291131 -0.156998 0.00354524 0.0291522 -0.156998 -0.00266303 0.0357745 -0.149998 0.0069537 0.034981 -0.137998 0.010695 0.0342069 -0.149998 0.0132172 0.0165033 -0.189497 -0.22686 0.02277 -0.182497 -0.223422 0.0117258 -0.189497 -0.221248 0.032313 -0.137997 -0.263445 0.026577 -0.137997 -0.272773 -0.029873 -0.137998 -0.268242 -0.00812 -0.137998 -0.215956 -0.011002 -0.137998 -0.216775 -0.011002 -0.182498 -0.216775 -0.044946 -0.137998 -0.226035 0.029869 -0.137997 -0.231759 0.034044 -0.137997 -0.241883 0.0363095 -0.149998 0.00153579 0.0291522 -0.156998 -0.00266303 0.0361584 -0.149998 -0.00332059 -0.016335 -0.137998 -0.201244 -0.022928 -0.137998 -0.160794 -0.022835 -0.179996 -0.162726 -0.033792 -0.149998 -0.020934 -0.033792 -0.137998 -0.020934 -0.039966 -0.137998 -0.060476 0.00116802 -0.137998 0.036003 -0.008135979999999999 -0.137998 0.034439 0.00176102 -0.15 0.036001 0.00443301 -0.149998 -0.050197 0.02797 -0.149998 -0.021651 -0.00112887 -0.156998 -0.0459391 -0.0219334 -0.182498 -0.168339 -0.022835 -0.179996 -0.162726 -0.0298779 -0.188468 -0.161935 -0.011002 -0.137998 -0.216775 -0.016335 -0.137998 -0.201244 -0.0156101 -0.182498 -0.203355 -0.0098446 -0.156998 0.0277807 -0.022692 -0.149998 0.026648 -0.0117197 -0.156998 0.0263204 0.018239 -0.182497 -0.279871 0.0182026 -0.184286 -0.277552 0.00982823 -0.189497 -0.277838 0.00965825 -0.156998 0.0303153 0.0171507 -0.15 0.0321037 0.00427813 -0.156998 0.0315094 -0.0298721 -0.182497 -0.268242 -0.022774 -0.182497 -0.27658 -0.0243837 -0.184358 -0.272411 0.008116 -0.182497 -0.28405 -0.00345781 -0.189497 -0.281249 -0.001318 -0.1825 -0.284775 -0.0273992 -0.156998 -0.123236 -0.0201871 -0.149998 -0.122778 -0.019649 -0.149998 -0.119943 -0.0242753 -0.189498 -0.196308 -0.0219334 -0.182498 -0.168339 -0.0298779 -0.188468 -0.161935 -0.00112887 -0.156998 -0.0459391 -0.0324414 -0.156998 -0.0576595 -0.0363383 -0.156998 -0.073647 -0.0238631 -0.156998 -0.108253 -0.015277 -0.149998 -0.102992 -0.0190544 -0.154031 -0.101491 0.026577 -0.182497 -0.272773 0.018239 -0.182497 -0.279871 0.026577 -0.137997 -0.272773 -0.0570253 -0.182498 -0.173467 -0.0477357 -0.189498 -0.184157 -0.0501208 -0.189241 -0.172523 -0.0299282 -0.186882 -0.160046 -0.050628 -0.177738 -0.148859 -0.0298779 -0.188468 -0.161935 0.02797 -0.149998 -0.021651 0.00443301 -0.149998 -0.050197 0.02797 -0.137998 -0.021651 0.00747002 -0.15 0.035384 0.00116802 -0.137998 0.036003 0.00176102 -0.15 0.036001 0.029869 -0.182497 -0.23176 0.02277 -0.182497 -0.223422 0.0165033 -0.189497 -0.22686 0.0169921 -0.156998 0.0254633 0.0208184 -0.156998 0.0230108 0.0249496 -0.149998 0.0267196 0.018239 -0.137997 -0.279871 -0.013446 -0.137997 -0.282316 -0.022774 -0.137997 -0.27658 -0.0098446 -0.156998 0.0277807 0.0120559 -0.156998 0.028325 -0.00119713 -0.156998 0.0311578 -0.031163 -0.149998 0.015936 -0.0325361 -0.149998 0.011096 -0.0225231 -0.156998 0.0155764 0.00443301 -0.149998 -0.050197 -0.011306 -0.149998 -0.08529399999999999 0.00443301 -0.137998 -0.050197 -0.00812 -0.137998 -0.215956 -0.011002 -0.182498 -0.216775 0.001314 -0.182498 -0.215228 -0.011002 -0.137998 -0.216775 -0.056865 -0.137998 -0.17605 -0.016335 -0.137998 -0.201244 -0.0277409 -0.156998 -0.0046775 -0.0267758 -0.156998 -0.0210155 0.0208539 -0.156998 -0.0194829 -0.0163071 -0.153035 -0.094143 -0.0203749 -0.156998 -0.0947291 -0.015277 -0.149998 -0.102992 -0.011002 -0.137998 -0.216775 -0.044946 -0.137998 -0.226035 -0.056865 -0.137998 -0.17605 0.029869 -0.137997 -0.231759 0.029869 -0.182497 -0.23176 0.034044 -0.182497 -0.241883 -0.011306 -0.137998 -0.08529399999999999 -0.015277 -0.137998 -0.102992 -0.039966 -0.137998 -0.060476 0.034044 -0.182497 -0.241883 0.0277921 -0.189497 -0.252355 0.034886 -0.182497 -0.252801 0.02797 -0.137998 -0.021651 0.024691 -0.137998 -0.024464 0.031545 -0.137998 -0.016125 0.0244819 -0.189497 -0.262816 -0.0269619 -0.189498 -0.258688 0.0167086 -0.189497 -0.271981 -0.0177665 -0.137998 -0.0677455 -0.039966 -0.137998 -0.060476 0.00443301 -0.137998 -0.050197 -0.0216497 -0.1895 -0.20732 -0.0358064 -0.189498 -0.229342 -0.0144049 -0.1895 -0.218377 0.031112 -0.137998 0.019976 0.0342069 -0.149998 0.0132172 0.033206 -0.137998 0.014953 -0.00119713 -0.156998 0.0311578 0.00427813 -0.156998 0.0315094 0.00176102 -0.15 0.036001 0.0361584 -0.149998 -0.00332059 0.0277585 -0.156998 -0.00777409 0.034653 -0.149998 -0.009078019999999999 -0.0501208 -0.189241 -0.172523 -0.0477357 -0.189498 -0.184157 -0.0298779 -0.188468 -0.161935 -0.0267148 -0.156998 -0.119631 -0.019649 -0.149998 -0.119943 -0.0238631 -0.156998 -0.108253 0.0337698 -0.149998 -0.0124852 0.0313327 -0.149998 -0.0171439 0.031545 -0.137998 -0.016125 -0.034047 -0.137998 -0.258119 -0.034966 -0.137998 -0.248412 0.032313 -0.137997 -0.263445 -0.001318 -0.1825 -0.284775 -0.00345781 -0.189497 -0.281249 -0.0130552 -0.1825 -0.28405 -0.0276409 -0.156998 0.00270343 -0.0225231 -0.156998 0.0155764 -0.03489 -0.149998 0.00279898 0.031112 -0.137998 0.019976 0.0319824 -0.149998 0.018322 0.0342069 -0.149998 0.0132172 -0.000783752 -0.189498 -0.217156 -0.0144049 -0.1895 -0.218377 0.0117258 -0.189497 -0.221248 -0.022835 -0.179996 -0.162726 -0.022928 -0.178374 -0.160795 -0.0298779 -0.188468 -0.161935 -0.0363383 -0.156998 -0.073647 -0.055576 -0.149998 -0.118356 -0.0476516 -0.156998 -0.115832 -0.0177665 -0.137998 -0.0677455 -0.011306 -0.137998 -0.08529399999999999 -0.039966 -0.137998 -0.060476 -0.0276409 -0.156998 0.00270343 -0.0277409 -0.156998 -0.0046775 0.0277585 -0.156998 -0.00777409 -0.011002 -0.182498 -0.216775 -0.0144049 -0.1895 -0.218377 -0.000783752 -0.189498 -0.217156 0.0244819 -0.189497 -0.262816 0.0167086 -0.189497 -0.271981 0.032313 -0.182497 -0.263445 0.0190888 -0.137992 -0.0323898 0.024691 -0.137998 -0.024464 0.02797 -0.137998 -0.021651 -0.034047 -0.137998 -0.258119 0.032313 -0.137997 -0.263445 -0.029873 -0.137998 -0.268242 -0.0360055 -0.189134 -0.179117 -0.0242753 -0.189498 -0.196308 -0.0298779 -0.188468 -0.161935 -0.002802 -0.137997 -0.284889 -0.0130552 -0.1825 -0.28405 -0.013446 -0.137997 -0.282316 -0.0389066 -0.189498 -0.221183 -0.044946 -0.182498 -0.226035 -0.0358064 -0.189498 -0.229342 0.035503 -0.137998 -0.00716101 0.036247 -0.137998 0.0009799819999999999 0.0361584 -0.149998 -0.00332059 0.0342069 -0.149998 0.0132172 0.034981 -0.137998 0.010695 0.033206 -0.137998 0.014953 -0.00112887 -0.156998 -0.0459391 0.02797 -0.149998 -0.021651 0.0208539 -0.156998 -0.0194829 0.00279801 -0.137998 -0.215114 -0.00812 -0.137998 -0.215956 0.001314 -0.182498 -0.215228 0.0165033 -0.189497 -0.22686 -0.0358064 -0.189498 -0.229342 0.0220503 -0.189497 -0.231162 -0.0117197 -0.156998 0.0263204 -0.031163 -0.149998 0.015936 -0.0225231 -0.156998 0.0155764 0.0118795 -0.149998 0.0342979 0.00747002 -0.15 0.035384 0.00427813 -0.156998 0.0315094 0.0167086 -0.189497 -0.271981 0.026577 -0.182497 -0.272773 0.032313 -0.182497 -0.263445 -0.034752 -0.137998 -0.00418302 -0.033792 -0.137998 -0.020934 -0.034752 -0.149998 -0.00418302 -0.034966 -0.137998 -0.248412 0.034886 -0.137997 -0.252801 0.032313 -0.137997 -0.263445 0.0182026 -0.184286 -0.277552 0.026577 -0.182497 -0.272773 0.00982823 -0.189497 -0.277838 0.029869 -0.182497 -0.23176 0.0269129 -0.189497 -0.240452 0.034044 -0.182497 -0.241883 -0.011306 -0.137998 -0.08529399999999999 -0.0177665 -0.137998 -0.0677455 0.00443301 -0.137998 -0.050197 0.027792 -0.137998 0.024268 0.0296546 -0.149998 0.0221127 0.031112 -0.137998 0.019976 -0.056865 -0.137998 -0.17605 -0.0570253 -0.182498 -0.173467 -0.058044 -0.137998 -0.157039 -0.0363225 -0.182498 -0.24537 -0.034966 -0.137998 -0.248412 -0.034047 -0.137998 -0.258119 -0.011002 -0.182498 -0.216775 -0.0216497 -0.1895 -0.20732 -0.0144049 -0.1895 -0.218377 0.0242157 -0.156998 -0.0156431 -0.0277409 -0.156998 -0.0046775 0.0208539 -0.156998 -0.0194829 -0.022692 -0.149998 0.026648 -0.031163 -0.149998 0.015936 -0.0117197 -0.156998 0.0263204 -0.0273992 -0.156998 -0.123236 -0.050628 -0.177738 -0.148859 -0.0299282 -0.186882 -0.160046 0.035503 -0.137998 -0.00716101 0.0361584 -0.149998 -0.00332059 0.034653 -0.149998 -0.009078019999999999 -0.022928 -0.178374 -0.160795 -0.0299282 -0.186882 -0.160046 -0.0298779 -0.188468 -0.161935 -0.039966 -0.137998 -0.060476 -0.022774 -0.137998 -0.02658 -0.013446 -0.137998 -0.032316 -0.0169633 -0.156998 -0.0808022 -0.0203749 -0.156998 -0.0947291 -0.011306 -0.149998 -0.08529399999999999 -0.03489 -0.137998 0.00279898 -0.034752 -0.137998 -0.00418302 -0.03489 -0.149998 0.00279898 0.018239 -0.182497 -0.279871 0.026577 -0.182497 -0.272773 0.0182026 -0.184286 -0.277552 -0.0578833 -0.182498 -0.162331 -0.0570253 -0.182498 -0.173467 -0.0508655 -0.189241 -0.162856 0.0296546 -0.149998 0.0221127 0.0319824 -0.149998 0.018322 0.031112 -0.137998 0.019976 -0.015277 -0.149998 -0.102992 -0.0203749 -0.156998 -0.0947291 -0.0190544 -0.154031 -0.101491 -0.0130552 -0.1825 -0.28405 -0.00345781 -0.189497 -0.281249 -0.0132689 -0.189497 -0.276947 -0.0298721 -0.182497 -0.268242 -0.034047 -0.182498 -0.258119 -0.029873 -0.137998 -0.268242 0.00667102 -0.137998 0.035573 0.00747002 -0.15 0.035384 0.0118795 -0.149998 0.0342979 0.029869 -0.137997 -0.231759 0.034044 -0.182497 -0.241883 0.034044 -0.137997 -0.241883 0.0242157 -0.156998 -0.0156431 0.0208539 -0.156998 -0.0194829 0.0313327 -0.149998 -0.0171439 -0.0242753 -0.189498 -0.196308 -0.0216497 -0.1895 -0.20732 -0.0156101 -0.182498 -0.203355 -0.015277 -0.149998 -0.102992 -0.011306 -0.137998 -0.08529399999999999 -0.011306 -0.149998 -0.08529399999999999 -0.0460505 -0.149998 -0.08283790000000001 -0.039966 -0.149998 -0.060476 -0.039966 -0.137998 -0.060476 0.034044 -0.137997 -0.241883 0.034886 -0.182497 -0.252801 0.034886 -0.137997 -0.252801 0.0208184 -0.156998 0.0230108 0.0296546 -0.149998 0.0221127 0.0249496 -0.149998 0.0267196 0.013442 -0.182498 -0.217686 -0.000783752 -0.189498 -0.217156 0.0117258 -0.189497 -0.221248 0.0296546 -0.149998 0.0221127 0.027792 -0.137998 0.024268 0.0249496 -0.149998 0.0267196 0.00982823 -0.189497 -0.277838 0.026577 -0.182497 -0.272773 0.0167086 -0.189497 -0.271981 -0.0389066 -0.189498 -0.221183 -0.0477357 -0.189498 -0.184157 -0.044946 -0.182498 -0.226035 0.0171507 -0.15 0.0321037 0.0203086 -0.149998 0.0302513 0.018877 -0.137998 0.031087 -0.0238631 -0.156998 -0.108253 -0.0363383 -0.156998 -0.073647 -0.0476516 -0.156998 -0.115832 -0.0277409 -0.156998 -0.0046775 0.0267455 -0.156998 -0.0116438 0.0277585 -0.156998 -0.00777409 0.0267455 -0.156998 -0.0116438 0.0337698 -0.149998 -0.0124852 0.034653 -0.149998 -0.009078019999999999 -0.019649 -0.149998 -0.119943 -0.019649 -0.137998 -0.119943 -0.015277 -0.137998 -0.102992 -0.0277696 -0.189498 -0.250156 -0.0269619 -0.189498 -0.258688 0.0244819 -0.189497 -0.262816 -0.0220408 -0.189497 -0.268871 0.00982823 -0.189497 -0.277838 0.0167086 -0.189497 -0.271981 0.0342069 -0.149998 0.0132172 0.0319824 -0.149998 0.018322 0.0255505 -0.156998 0.0156854 -0.0216497 -0.1895 -0.20732 -0.011002 -0.182498 -0.216775 -0.0156101 -0.182498 -0.203355 0.036177 -0.137998 0.00428798 0.0363095 -0.149998 0.00153579 0.036247 -0.137998 0.0009799819999999999 0.00443301 -0.149998 -0.050197 -0.00112887 -0.156998 -0.0459391 -0.0169633 -0.156998 -0.0808022 -0.0225231 -0.156998 0.0155764 0.0291131 -0.156998 0.00354524 0.0281997 -0.156998 0.00854457 -0.00280198 -0.137998 -0.034889 -0.039966 -0.137998 -0.060476 -0.013446 -0.137998 -0.032316 -0.0201871 -0.149998 -0.122778 -0.0273992 -0.156998 -0.123236 -0.0299282 -0.186882 -0.160046 -0.0363225 -0.182498 -0.24537 -0.044946 -0.137998 -0.226035 -0.034966 -0.137998 -0.248412 -0.011002 -0.137998 -0.216775 0.02277 -0.137997 -0.223422 0.029869 -0.137997 -0.231759 0.0208184 -0.156998 0.0230108 0.0169921 -0.156998 0.0254633 -0.0117197 -0.156998 0.0263204 -0.0267758 -0.156998 -0.0210155 -0.00112887 -0.156998 -0.0459391 -0.00296095 -0.156998 -0.032711 -0.0098446 -0.156998 0.0277807 -0.00119713 -0.156998 0.0311578 -0.020283 -0.149998 0.028524 -0.0216497 -0.1895 -0.20732 -0.0477357 -0.189498 -0.184157 -0.0389066 -0.189498 -0.221183 -0.00119713 -0.156998 0.0311578 -0.0115818 -0.149998 0.0333791 -0.020283 -0.149998 0.028524 -0.0269619 -0.189498 -0.258688 -0.0220408 -0.189497 -0.268871 0.0167086 -0.189497 -0.271981 -0.0115818 -0.149998 0.0333791 -0.007896510000000001 -0.149998 0.0343947 -0.008135979999999999 -0.137998 0.034439 -0.0203749 -0.156998 -0.0947291 -0.0363383 -0.156998 -0.073647 -0.0238631 -0.156998 -0.108253 -0.031163 -0.149998 0.015936 -0.026582 -0.137998 0.02277 -0.032318 -0.137998 0.013442 0.0237806 -0.156998 0.0198468 -0.0117197 -0.156998 0.0263204 0.0255505 -0.156998 0.0156854 0.018239 -0.182497 -0.279871 -0.00345781 -0.189497 -0.281249 0.008116 -0.182497 -0.28405 -0.0267758 -0.156998 -0.0210155 -0.00296095 -0.156998 -0.032711 0.0208539 -0.156998 -0.0194829 0.0291131 -0.156998 0.00354524 -0.0276409 -0.156998 0.00270343 0.0291522 -0.156998 -0.00266303 -0.002802 -0.137997 -0.284889 -0.001318 -0.1825 -0.284775 -0.0130552 -0.1825 -0.28405 -0.022928 -0.137998 -0.160794 -0.056865 -0.137998 -0.17605 -0.058044 -0.137998 -0.157039 0.0169921 -0.156998 0.0254633 0.0120559 -0.156998 0.028325 -0.0098446 -0.156998 0.0277807 -0.033792 -0.137998 -0.020934 -0.034048 -0.137998 -0.008119019999999999 -0.029873 -0.137998 -0.018243 0.0291522 -0.156998 -0.00266303 0.0277585 -0.156998 -0.00777409 0.0361584 -0.149998 -0.00332059 0.034886 -0.137997 -0.252801 0.032313 -0.182497 -0.263445 0.032313 -0.137997 -0.263445 -0.022692 -0.149998 0.026648 -0.0098446 -0.156998 0.0277807 -0.020283 -0.149998 0.028524 0.00116802 -0.137998 0.036003 0.00747002 -0.15 0.035384 0.00667102 -0.137998 0.035573 0.0269129 -0.189497 -0.240452 0.029869 -0.182497 -0.23176 0.0220503 -0.189497 -0.231162 0.0291522 -0.156998 -0.00266303 -0.0276409 -0.156998 0.00270343 0.0277585 -0.156998 -0.00777409 -0.0277696 -0.189498 -0.250156 -0.0358064 -0.189498 -0.229342 -0.0363225 -0.182498 -0.24537 0.024691 -0.137998 -0.024464 0.0190888 -0.137992 -0.0323898 0.018239 -0.137998 -0.029872 -0.0363383 -0.156998 -0.073647 -0.0460505 -0.149998 -0.08283790000000001 -0.055576 -0.149998 -0.118356 -0.058044 -0.137998 -0.157039 -0.058044 -0.175225 -0.157039 -0.0567022 -0.153255 -0.130855 -0.034752 -0.149998 -0.00418302 -0.033792 -0.149998 -0.020934 -0.0277409 -0.156998 -0.0046775 0.034044 -0.182497 -0.241883 0.0269129 -0.189497 -0.240452 0.0277921 -0.189497 -0.252355 -0.019649 -0.137998 -0.119943 -0.022928 -0.137998 -0.160794 -0.058044 -0.137998 -0.157039 -0.016335 -0.137998 -0.201244 -0.0219334 -0.182498 -0.168339 -0.0156101 -0.182498 -0.203355 0.0171507 -0.15 0.0321037 0.018877 -0.137998 0.031087 0.017841 -0.137998 0.03175 0.0277585 -0.156998 -0.00777409 0.0267455 -0.156998 -0.0116438 0.034653 -0.149998 -0.009078019999999999 0.029869 -0.182497 -0.23176 0.0165033 -0.189497 -0.22686 0.0220503 -0.189497 -0.231162 0.018239 -0.137998 -0.029872 0.0190888 -0.137992 -0.0323898 0.00443301 -0.137998 -0.050197 0.036177 -0.137998 0.00428798 0.034981 -0.137998 0.010695 0.0357745 -0.149998 0.0069537 -0.019649 -0.149998 -0.119943 -0.015277 -0.149998 -0.102992 -0.0238631 -0.156998 -0.108253 -0.022835 -0.179996 -0.162726 -0.022928 -0.137998 -0.160794 -0.022928 -0.178374 -0.160795 0.0337698 -0.149998 -0.0124852 0.035503 -0.137998 -0.00716101 0.034653 -0.149998 -0.009078019999999999 0.0277921 -0.189497 -0.252355 0.0244819 -0.189497 -0.262816 0.034886 -0.182497 -0.252801 0.02797 -0.149998 -0.021651 0.02797 -0.137998 -0.021651 0.031545 -0.137998 -0.016125 0.0291131 -0.156998 0.00354524 0.0357745 -0.149998 0.0069537 0.0281997 -0.156998 0.00854457 0.02277 -0.182497 -0.223422 0.013442 -0.137998 -0.217686 0.013442 -0.182498 -0.217686 -0.0225231 -0.156998 0.0155764 -0.0325361 -0.149998 0.011096 -0.03489 -0.149998 0.00279898 -0.056865 -0.137998 -0.17605 -0.044946 -0.182498 -0.226035 -0.0570253 -0.182498 -0.173467 -0.034752 -0.137998 -0.00418302 -0.03489 -0.137998 0.00279898 -0.034048 -0.137998 -0.008119019999999999 0.013442 -0.137998 -0.217686 -0.011002 -0.137998 -0.216775 -0.00812 -0.137998 -0.215956 -0.055576 -0.137998 -0.118356 -0.0460505 -0.149998 -0.08283790000000001 -0.039966 -0.137998 -0.060476 -0.0225231 -0.156998 0.0155764 -0.0276409 -0.156998 0.00270343 0.0291131 -0.156998 0.00354524 -0.032318 -0.137998 0.013442 -0.03489 -0.137998 0.00279898 -0.0325361 -0.149998 0.011096 -0.0216497 -0.1895 -0.20732 -0.0389066 -0.189498 -0.221183 -0.0358064 -0.189498 -0.229342 0.0171507 -0.15 0.0321037 0.0118795 -0.149998 0.0342979 0.00427813 -0.156998 0.0315094 0.02277 -0.137997 -0.223422 0.013442 -0.137998 -0.217686 0.02277 -0.182497 -0.223422 -0.0277696 -0.189498 -0.250156 -0.0363225 -0.182498 -0.24537 -0.034047 -0.182498 -0.258119 -0.022774 -0.182497 -0.27658 -0.0220408 -0.189497 -0.268871 -0.0243837 -0.184358 -0.272411 -0.0476516 -0.156998 -0.115832 -0.0567022 -0.153255 -0.130855 -0.0493451 -0.156998 -0.124141 -0.011002 -0.137998 -0.216775 0.029869 -0.137997 -0.231759 -0.044946 -0.137998 -0.226035 -0.058044 -0.137998 -0.157039 -0.0578833 -0.182498 -0.162331 -0.058044 -0.175225 -0.157039 -0.0477357 -0.189498 -0.184157 -0.0216497 -0.1895 -0.20732 -0.0242753 -0.189498 -0.196308 -0.034752 -0.149998 -0.00418302 -0.0277409 -0.156998 -0.0046775 -0.0276409 -0.156998 0.00270343 0.013442 -0.182498 -0.217686 0.013442 -0.137998 -0.217686 0.00279801 -0.137998 -0.215114 -0.00112887 -0.156998 -0.0459391 -0.0363383 -0.156998 -0.073647 -0.0169633 -0.156998 -0.0808022 -0.0325361 -0.149998 0.011096 -0.03489 -0.137998 0.00279898 -0.03489 -0.149998 0.00279898 -0.0220408 -0.189497 -0.268871 -0.0298721 -0.182497 -0.268242 -0.0243837 -0.184358 -0.272411 -0.0298721 -0.182497 -0.268242 -0.0269619 -0.189498 -0.258688 -0.034047 -0.182498 -0.258119 0.00811601 -0.137998 -0.034047 0.018239 -0.137998 -0.029872 0.00443301 -0.137998 -0.050197 -0.0476516 -0.156998 -0.115832 -0.0555759 -0.151393 -0.127995 -0.0567022 -0.153255 -0.130855 0.026577 -0.182497 -0.272773 0.026577 -0.137997 -0.272773 0.032313 -0.137997 -0.263445 -0.034752 -0.149998 -0.00418302 -0.0276409 -0.156998 0.00270343 -0.03489 -0.149998 0.00279898 0.0190888 -0.137992 -0.0323898 0.00443301 -0.149998 -0.050197 0.00443301 -0.137998 -0.050197 -0.039966 -0.137998 -0.060476 -0.033792 -0.137998 -0.020934 -0.022774 -0.137998 -0.02658 -0.0360055 -0.189134 -0.179117 -0.0477357 -0.189498 -0.184157 -0.0242753 -0.189498 -0.196308 -0.050628 -0.177738 -0.148859 -0.0578833 -0.182498 -0.162331 -0.0508655 -0.189241 -0.162856 -0.016335 -0.137998 -0.201244 -0.056865 -0.137998 -0.17605 -0.022928 -0.137998 -0.160794 0.0337698 -0.149998 -0.0124852 0.0242157 -0.156998 -0.0156431 0.0313327 -0.149998 -0.0171439 0.008116 -0.182497 -0.28405 -0.001318 -0.1825 -0.284775 0.008116 -0.137997 -0.284047 -0.033792 -0.149998 -0.020934 -0.0267758 -0.156998 -0.0210155 -0.0277409 -0.156998 -0.0046775 -0.013446 -0.137997 -0.282316 -0.022774 -0.182497 -0.27658 -0.022774 -0.137997 -0.27658 -0.034752 -0.137998 -0.00418302 -0.034752 -0.149998 -0.00418302 -0.03489 -0.149998 0.00279898 -0.033792 -0.137998 -0.020934 -0.034752 -0.137998 -0.00418302 -0.034048 -0.137998 -0.008119019999999999 -0.0273992 -0.156998 -0.123236 -0.0476516 -0.156998 -0.115832 -0.0493451 -0.156998 -0.124141 0.023298 -0.137998 0.028256 0.0203086 -0.149998 0.0302513 0.0249496 -0.149998 0.0267196 0.0363095 -0.149998 0.00153579 0.0357745 -0.149998 0.0069537 0.0291131 -0.156998 0.00354524 0.0363095 -0.149998 0.00153579 0.036177 -0.137998 0.00428798 0.0357745 -0.149998 0.0069537 0.00982823 -0.189497 -0.277838 -0.0220408 -0.189497 -0.268871 -0.0132689 -0.189497 -0.276947 -0.015277 -0.149998 -0.102992 -0.019649 -0.149998 -0.119943 -0.015277 -0.137998 -0.102992 -0.007896510000000001 -0.149998 0.0343947 -0.00119713 -0.156998 0.0311578 -0.00326398 -0.15 0.035671 -0.0117197 -0.156998 0.0263204 -0.0225231 -0.156998 0.0155764 0.0255505 -0.156998 0.0156854 0.026577 -0.137997 -0.272773 0.018239 -0.182497 -0.279871 0.018239 -0.137997 -0.279871 -0.022928 -0.137998 -0.160794 -0.019649 -0.137998 -0.119943 -0.022928 -0.178374 -0.160795 -0.001318 -0.1825 -0.284775 -0.002802 -0.137997 -0.284889 0.008116 -0.137997 -0.284047 0.00811601 -0.137998 -0.034047 0.00443301 -0.137998 -0.050197 -0.00280198 -0.137998 -0.034889 -0.00296095 -0.156998 -0.032711 -0.00112887 -0.156998 -0.0459391 0.0208539 -0.156998 -0.0194829 0.013442 -0.182498 -0.217686 0.00279801 -0.137998 -0.215114 0.001314 -0.182498 -0.215228 -0.008135979999999999 -0.137998 0.034439 -0.007896510000000001 -0.149998 0.0343947 -0.00326398 -0.15 0.035671 -0.0324414 -0.156998 -0.0576595 -0.039966 -0.149998 -0.060476 -0.0363383 -0.156998 -0.073647 0.0208184 -0.156998 0.0230108 0.0237806 -0.156998 0.0198468 0.0296546 -0.149998 0.0221127 0.0267455 -0.156998 -0.0116438 -0.0277409 -0.156998 -0.0046775 0.0242157 -0.156998 -0.0156431 0.0203086 -0.149998 0.0302513 0.023298 -0.137998 0.028256 0.018877 -0.137998 0.031087 -0.0144049 -0.1895 -0.218377 -0.0358064 -0.189498 -0.229342 0.0165033 -0.189497 -0.22686 -0.044946 -0.182498 -0.226035 -0.044946 -0.137998 -0.226035 -0.0363225 -0.182498 -0.24537 -0.022774 -0.137997 -0.27658 -0.0298721 -0.182497 -0.268242 -0.029873 -0.137998 -0.268242 -0.0220408 -0.189497 -0.268871 -0.022774 -0.182497 -0.27658 -0.0132689 -0.189497 -0.276947 -0.033792 -0.149998 -0.020934 -0.039966 -0.149998 -0.060476 -0.0267758 -0.156998 -0.0210155 -0.026582 -0.137998 0.02277 -0.020283 -0.149998 0.028524 -0.020283 -0.137998 0.028524 0.0208539 -0.156998 -0.0194829 0.02797 -0.149998 -0.021651 0.0313327 -0.149998 -0.0171439 0.00667102 -0.137998 0.035573 0.0118795 -0.149998 0.0342979 0.012177 -0.137998 0.0342 0.034886 -0.182497 -0.252801 0.032313 -0.182497 -0.263445 0.034886 -0.137997 -0.252801 -0.0570253 -0.182498 -0.173467 -0.0501208 -0.189241 -0.172523 -0.0508655 -0.189241 -0.162856 0.00427813 -0.156998 0.0315094 0.00747002 -0.15 0.035384 0.00176102 -0.15 0.036001 0.018239 -0.182497 -0.279871 0.008116 -0.182497 -0.28405 0.018239 -0.137997 -0.279871 -0.015277 -0.137998 -0.102992 -0.019649 -0.137998 -0.119943 -0.039966 -0.137998 -0.060476 0.018239 -0.137997 -0.279871 0.008116 -0.137997 -0.284047 -0.013446 -0.137997 -0.282316 -0.0555759 -0.151393 -0.127995 -0.058044 -0.137998 -0.157039 -0.0567022 -0.153255 -0.130855 -0.058044 -0.175225 -0.157039 -0.050628 -0.177738 -0.148859 -0.0493451 -0.156998 -0.124141 -0.019649 -0.137998 -0.119943 -0.055576 -0.137998 -0.118356 -0.039966 -0.137998 -0.060476 -0.044946 -0.137998 -0.226035 0.034886 -0.137997 -0.252801 -0.034966 -0.137998 -0.248412 -0.0115818 -0.149998 0.0333791 -0.008135979999999999 -0.137998 0.034439 -0.020283 -0.137998 0.028524 -0.00119713 -0.156998 0.0311578 -0.007896510000000001 -0.149998 0.0343947 -0.0115818 -0.149998 0.0333791 -0.044946 -0.182498 -0.226035 -0.0477357 -0.189498 -0.184157 -0.0570253 -0.182498 -0.173467 0.018239 -0.137997 -0.279871 0.008116 -0.182497 -0.28405 0.008116 -0.137997 -0.284047 0.0203086 -0.149998 0.0302513 0.0120559 -0.156998 0.028325 0.0249496 -0.149998 0.0267196 -0.055576 -0.137998 -0.118356 -0.058044 -0.137998 -0.157039 -0.0555759 -0.151393 -0.127995 -0.0267148 -0.156998 -0.119631 -0.0238631 -0.156998 -0.108253 -0.0476516 -0.156998 -0.115832 -0.041271 -0.170656 -0.263571 -0.048333 -0.173647 -0.252846 -0.058266 -0.169826 -0.239406 -0.07137400000000001 -0.165998 -0.190116 -0.065137 -0.169826 -0.214993 -0.06900100000000001 -0.169826 -0.189844 -0.037068 -0.119982 -0.269121 -0.0347 -0.146939 -0.269045 -0.037069 -0.137965 -0.269121 -0.072017 -0.119053 -0.18233 -0.08101 -0.126736 -0.1835 -0.072017 -0.127053 -0.18233 -0.050821 -0.173792 -0.239323 -0.058474 -0.173792 -0.213889 -0.062691 -0.173647 -0.215048 -0.058474 -0.173792 -0.213889 -0.050821 -0.173792 -0.239323 -0.046384 -0.173948 -0.237548 -0.061654 -0.159058 -0.15216 -0.061239 -0.152807 -0.149776 -0.062478 -0.152776 -0.150129 -0.037056 -0.155948 -0.269128 -0.037062 -0.146875 -0.269124 -0.0347 -0.146939 -0.269045 -0.036129 -0.171986 -0.261556 -0.0388376 -0.146029 -0.254472 -0.0426034 -0.145931 -0.245045 -0.060208 -0.164248 -0.156288 -0.060054 -0.156129 -0.150442 -0.060108 -0.159156 -0.151942 -0.062295 -0.164126 -0.156456 -0.060181 -0.162713 -0.154553 -0.061654 -0.159058 -0.15216 -0.063567 -0.172356 -0.174442 -0.059687 -0.172139 -0.174114 -0.062933 -0.167688 -0.16204 -0.032631 -0.163595 -0.268277 -0.036085 -0.166836 -0.266902 -0.034742 -0.160427 -0.26898 -0.058266 -0.169826 -0.239406 -0.05466 -0.173647 -0.240858 -0.065137 -0.169826 -0.214993 -0.06659900000000001 -0.119332 -0.154644 -0.06234 -0.119496 -0.149685 -0.059219 -0.119502 -0.181032 -0.06565 -0.167967 -0.163813 -0.062295 -0.164126 -0.156456 -0.06317399999999999 -0.158896 -0.152487 -0.060225 -0.165187 -0.15735 -0.062295 -0.164126 -0.156456 -0.062933 -0.167688 -0.16204 -0.036085 -0.166836 -0.266902 -0.036129 -0.171986 -0.261556 -0.038749 -0.171387 -0.26263 -0.076249 -0.126736 -0.233751 -0.068758 -0.07099800000000001 -0.233304 -0.068758 -0.118998 -0.233305 -0.0530965 -0.122945 -0.213171 -0.0555558 -0.146725 -0.202109 -0.0513867 -0.122741 -0.222061 -0.060208 -0.164248 -0.156288 -0.060181 -0.162713 -0.154553 -0.062295 -0.164126 -0.156456 -0.037068 -0.119982 -0.269121 -0.037069 -0.137965 -0.269121 -0.042476 -0.144627 -0.265799 -0.047899 -0.119627 -0.262467 -0.047899 -0.13613 -0.262467 -0.049676 -0.164207 -0.259772 -0.053742 -0.173948 -0.213554 -0.050522 -0.173948 -0.224055 -0.0511948 -0.122623 -0.223052 -0.063567 -0.172356 -0.174442 -0.062817 -0.173792 -0.187619 -0.058526 -0.173948 -0.187393 -0.059219 -0.119502 -0.181032 -0.06192 -0.118998 -0.181429 -0.071717 -0.119096 -0.172174 -0.0497035 -0.123371 -0.227009 -0.0426034 -0.145931 -0.245045 -0.0456132 -0.12173 -0.237229 -0.061351 -0.119239 -0.238297 -0.0544271 -0.119498 -0.232738 -0.059297 -0.119296 -0.242838 -0.066611 -0.173546 -0.188224 -0.062817 -0.173792 -0.187619 -0.063567 -0.172356 -0.174442 -0.059687 -0.172139 -0.174114 -0.059999 -0.132619 -0.149157 -0.059999 -0.144543 -0.149159 -0.059999 -0.144543 -0.149159 -0.059999 -0.132619 -0.149157 -0.061173 -0.132658 -0.14942 -0.048333 -0.173647 -0.252846 -0.045119 -0.173789 -0.25134 -0.053043 -0.173647 -0.244598 -0.06334099999999999 -0.119187 -0.232981 -0.0544271 -0.119498 -0.232738 -0.061351 -0.119239 -0.238297 -0.058526 -0.173948 -0.187393 -0.063567 -0.172356 -0.174442 -0.059217 -0.173678 -0.181024 -0.06750299999999999 -0.165998 -0.21531 -0.07137400000000001 -0.165998 -0.190116 -0.065717 -0.127134 -0.22427 -0.032631 -0.163595 -0.268277 -0.032244 -0.155144 -0.268988 -0.032294 -0.160522 -0.268895 -0.060212 -0.168388 -0.162797 -0.059687 -0.172139 -0.174114 -0.059999 -0.144543 -0.149159 -0.0426034 -0.145931 -0.245045 -0.0388376 -0.146029 -0.254472 -0.034967 -0.120072 -0.263858 -0.060225 -0.165187 -0.15735 -0.060208 -0.164248 -0.156288 -0.062295 -0.164126 -0.156456 -0.037056 -0.155948 -0.269128 -0.045735 -0.167981 -0.261308 -0.037062 -0.146875 -0.269124 -0.0388376 -0.146029 -0.254472 -0.036129 -0.171986 -0.261556 -0.034967 -0.120072 -0.263858 -0.059297 -0.119296 -0.242838 -0.0570492 -0.165997 -0.246987 -0.061328 -0.165998 -0.238353 -0.072017 -0.127053 -0.18233 -0.08101 -0.126736 -0.1835 -0.07170600000000001 -0.127047 -0.187151 -0.041271 -0.170656 -0.263571 -0.038749 -0.171387 -0.26263 -0.048333 -0.173647 -0.252846 -0.08101 -0.07126 -0.1835 -0.08101 -0.126736 -0.1835 -0.07356699999999999 -0.07099800000000001 -0.182532 -0.06696299999999999 -0.171975 -0.174878 -0.066611 -0.173546 -0.188224 -0.063567 -0.172356 -0.174442 -0.076249 -0.126736 -0.233751 -0.08101 -0.07126 -0.1835 -0.076249 -0.07126 -0.233751 -0.049553 -0.119578 -0.259981 -0.047899 -0.119627 -0.262467 -0.049676 -0.164207 -0.259772 -0.041271 -0.170656 -0.263571 -0.036085 -0.166836 -0.266902 -0.038749 -0.171387 -0.26263 -0.06696299999999999 -0.171975 -0.174878 -0.06565 -0.167967 -0.163813 -0.068435 -0.164632 -0.165306 -0.048333 -0.173647 -0.252846 -0.038749 -0.171387 -0.26263 -0.041948 -0.173561 -0.257175 -0.066611 -0.173546 -0.188224 -0.06537900000000001 -0.173647 -0.19902 -0.062817 -0.173792 -0.187619 -0.06234 -0.119496 -0.149685 -0.06659900000000001 -0.119332 -0.154644 -0.06592099999999999 -0.144184 -0.153854 -0.06592099999999999 -0.144184 -0.153854 -0.062347 -0.146132 -0.149702 -0.062342 -0.143931 -0.149687 -0.058474 -0.173792 -0.213889 -0.06537900000000001 -0.173647 -0.19902 -0.062691 -0.173647 -0.215048 -0.06951599999999999 -0.119219 -0.158041 -0.06659900000000001 -0.119332 -0.154644 -0.059219 -0.119502 -0.181032 -0.08101 -0.07126 -0.1835 -0.07356699999999999 -0.07099800000000001 -0.182532 -0.076249 -0.07126 -0.233751 -0.06537900000000001 -0.173647 -0.19902 -0.065137 -0.169826 -0.214993 -0.062691 -0.173647 -0.215048 -0.047899 -0.119627 -0.262467 -0.0423461 -0.119877 -0.245385 -0.0434993 -0.119771 -0.26517 -0.041271 -0.170656 -0.263571 -0.045735 -0.167981 -0.261308 -0.039049 -0.167503 -0.266575 -0.065137 -0.169826 -0.214993 -0.05466 -0.173647 -0.240858 -0.062691 -0.173647 -0.215048 -0.045735 -0.167981 -0.261308 -0.038497 -0.16615 -0.267291 -0.039049 -0.167503 -0.266575 -0.060054 -0.156129 -0.150442 -0.060225 -0.165187 -0.15735 -0.060011 -0.152342 -0.14942 -0.050522 -0.173948 -0.224055 -0.046384 -0.173948 -0.237548 -0.0511948 -0.122623 -0.223052 -0.0547976 -0.123013 -0.204317 -0.0570217 -0.121279 -0.192606 -0.0555558 -0.146725 -0.202109 -0.05466 -0.173647 -0.240858 -0.050821 -0.173792 -0.239323 -0.062691 -0.173647 -0.215048 -0.06696299999999999 -0.171975 -0.174878 -0.068435 -0.164632 -0.165306 -0.06900100000000001 -0.169826 -0.189844 -0.042476 -0.144627 -0.265799 -0.047899 -0.119627 -0.262467 -0.0434993 -0.119771 -0.26517 -0.060225 -0.165187 -0.15735 -0.062933 -0.167688 -0.16204 -0.060214 -0.167823 -0.161836 -0.06117 -0.119538 -0.14942 -0.06234 -0.119496 -0.149685 -0.061173 -0.132658 -0.14942 -0.08101 -0.126736 -0.1835 -0.076249 -0.126736 -0.233751 -0.07170600000000001 -0.127047 -0.187151 -0.06696299999999999 -0.171975 -0.174878 -0.063567 -0.172356 -0.174442 -0.062933 -0.167688 -0.16204 -0.076249 -0.126736 -0.233751 -0.06334099999999999 -0.127187 -0.232981 -0.065717 -0.127134 -0.22427 -0.062295 -0.164126 -0.156456 -0.061654 -0.159058 -0.15216 -0.06317399999999999 -0.158896 -0.152487 -0.065137 -0.169826 -0.214993 -0.07137400000000001 -0.165998 -0.190116 -0.06750299999999999 -0.165998 -0.21531 -0.058266 -0.169826 -0.239406 -0.053043 -0.173647 -0.244598 -0.05466 -0.173647 -0.240858 -0.045735 -0.167981 -0.261308 -0.041271 -0.170656 -0.263571 -0.058266 -0.169826 -0.239406 -0.038497 -0.16615 -0.267291 -0.036085 -0.166836 -0.266902 -0.039049 -0.167503 -0.266575 -0.036085 -0.166836 -0.266902 -0.034295 -0.169167 -0.265153 -0.033648 -0.167443 -0.266377 -0.0426034 -0.145931 -0.245045 -0.0423461 -0.119877 -0.245385 -0.0439799 -0.120915 -0.241308 -0.0426034 -0.145931 -0.245045 -0.0439799 -0.120915 -0.241308 -0.0456132 -0.12173 -0.237229 -0.06334099999999999 -0.127187 -0.232981 -0.065387 -0.165998 -0.22501 -0.065717 -0.127134 -0.22427 -0.0426034 -0.145931 -0.245045 -0.0497035 -0.123371 -0.227009 -0.0500441 -0.123165 -0.226155 -0.060011 -0.152342 -0.14942 -0.060225 -0.165187 -0.15735 -0.060214 -0.167823 -0.161836 -0.037223 -0.160169 -0.268922 -0.037056 -0.155948 -0.269128 -0.0347 -0.146939 -0.269045 -0.060054 -0.156129 -0.150442 -0.061239 -0.152807 -0.149776 -0.061654 -0.159058 -0.15216 -0.062347 -0.146132 -0.149702 -0.062478 -0.152776 -0.150129 -0.061173 -0.146095 -0.149422 -0.0423461 -0.119877 -0.245385 -0.034967 -0.120072 -0.263858 -0.0434993 -0.119771 -0.26517 -0.059999 -0.11958 -0.149155 -0.06117 -0.119538 -0.14942 -0.061173 -0.132658 -0.14942 -0.036085 -0.166836 -0.266902 -0.038497 -0.16615 -0.267291 -0.034742 -0.160427 -0.26898 -0.036129 -0.171986 -0.261556 -0.0500441 -0.123165 -0.226155 -0.041603 -0.17395 -0.249692 -0.059219 -0.119502 -0.181032 -0.0555558 -0.146725 -0.202109 -0.058413 -0.119945 -0.185262 -0.036085 -0.166836 -0.266902 -0.03331 -0.166543 -0.267016 -0.033648 -0.167443 -0.266377 -0.076249 -0.126736 -0.233751 -0.06334099999999999 -0.119187 -0.232981 -0.06334099999999999 -0.127187 -0.232981 -0.0701 -0.11919 -0.160869 -0.059219 -0.119502 -0.181032 -0.071717 -0.119096 -0.172174 -0.032631 -0.163595 -0.268277 -0.032244 -0.155144 -0.268988 -0.032249 -0.146972 -0.268979 -0.03331 -0.166543 -0.267016 -0.032249 -0.146972 -0.268979 -0.032254 -0.137647 -0.268969 -0.036129 -0.171986 -0.261556 -0.0426034 -0.145931 -0.245045 -0.0500441 -0.123165 -0.226155 -0.061351 -0.119239 -0.238297 -0.059297 -0.119296 -0.242838 -0.061328 -0.165998 -0.238353 -0.059999 -0.144543 -0.149159 -0.060002 -0.146067 -0.14921 -0.061173 -0.146095 -0.149422 -0.07356699999999999 -0.07099800000000001 -0.182532 -0.08101 -0.126736 -0.1835 -0.07356699999999999 -0.118998 -0.182532 -0.060208 -0.164248 -0.156288 -0.060181 -0.162713 -0.154553 -0.060108 -0.159156 -0.151942 -0.059297 -0.119296 -0.242838 -0.0544271 -0.119498 -0.232738 -0.049553 -0.119578 -0.259981 -0.047899 -0.13613 -0.262467 -0.045735 -0.167981 -0.261308 -0.049676 -0.164207 -0.259772 -0.045119 -0.173789 -0.25134 -0.041603 -0.17395 -0.249692 -0.050821 -0.173792 -0.239323 -0.06565 -0.167967 -0.163813 -0.06696299999999999 -0.171975 -0.174878 -0.062933 -0.167688 -0.16204 -0.049676 -0.164207 -0.259772 -0.045735 -0.167981 -0.261308 -0.0570492 -0.165997 -0.246987 -0.071717 -0.119096 -0.172174 -0.072017 -0.119053 -0.18233 -0.072017 -0.127053 -0.18233 -0.059219 -0.119502 -0.181032 -0.06117 -0.119538 -0.14942 -0.059999 -0.11958 -0.149155 -0.048333 -0.173647 -0.252846 -0.041948 -0.173561 -0.257175 -0.045119 -0.173789 -0.25134 -0.0347 -0.146939 -0.269045 -0.037068 -0.119982 -0.269121 -0.034699 -0.120064 -0.269046 -0.062347 -0.146132 -0.149702 -0.061173 -0.146095 -0.149422 -0.062342 -0.143931 -0.149687 -0.03331 -0.166543 -0.267016 -0.032631 -0.163595 -0.268277 -0.036085 -0.166836 -0.266902 -0.059999 -0.11958 -0.149155 -0.059999 -0.132619 -0.149157 -0.061173 -0.132658 -0.14942 -0.069857 -0.154956 -0.159655 -0.06951599999999999 -0.119219 -0.158041 -0.0701 -0.11919 -0.160869 -0.065387 -0.165998 -0.22501 -0.06334099999999999 -0.127187 -0.232981 -0.061351 -0.119239 -0.238297 -0.032294 -0.160522 -0.268895 -0.032631 -0.163595 -0.268277 -0.034742 -0.160427 -0.26898 -0.032249 -0.146972 -0.268979 -0.0347 -0.146939 -0.269045 -0.032254 -0.137647 -0.268969 -0.062817 -0.173792 -0.187619 -0.058474 -0.173792 -0.213889 -0.053742 -0.173948 -0.213554 -0.037062 -0.146875 -0.269124 -0.045735 -0.167981 -0.261308 -0.042476 -0.144627 -0.265799 -0.059999 -0.11958 -0.149155 -0.059999 -0.132619 -0.149157 -0.059217 -0.173678 -0.181024 -0.060002 -0.146067 -0.14921 -0.060011 -0.152342 -0.14942 -0.061173 -0.146095 -0.149422 -0.065137 -0.169826 -0.214993 -0.06537900000000001 -0.173647 -0.19902 -0.06900100000000001 -0.169826 -0.189844 -0.0347 -0.146939 -0.269045 -0.037062 -0.146875 -0.269124 -0.037069 -0.137965 -0.269121 -0.062478 -0.152776 -0.150129 -0.06592099999999999 -0.144184 -0.153854 -0.06317399999999999 -0.158896 -0.152487 -0.034295 -0.169167 -0.265153 -0.036129 -0.171986 -0.261556 -0.036085 -0.166836 -0.266902 -0.059219 -0.119502 -0.181032 -0.059999 -0.11958 -0.149155 -0.059217 -0.173678 -0.181024 -0.058526 -0.173948 -0.187393 -0.059219 -0.119502 -0.181032 -0.059217 -0.173678 -0.181024 -0.061173 -0.146095 -0.149422 -0.059999 -0.144543 -0.149159 -0.061173 -0.132658 -0.14942 -0.0570492 -0.165997 -0.246987 -0.058266 -0.169826 -0.239406 -0.061328 -0.165998 -0.238353 -0.060212 -0.168388 -0.162797 -0.059687 -0.172139 -0.174114 -0.062933 -0.167688 -0.16204 -0.06951599999999999 -0.119219 -0.158041 -0.069857 -0.154956 -0.159655 -0.06951599999999999 -0.144495 -0.15804 -0.06234 -0.119496 -0.149685 -0.06592099999999999 -0.144184 -0.153854 -0.06234 -0.132708 -0.149684 -0.034699 -0.120064 -0.269046 -0.037068 -0.119982 -0.269121 -0.034967 -0.120072 -0.263858 -0.061239 -0.152807 -0.149776 -0.060011 -0.152342 -0.14942 -0.061173 -0.146095 -0.149422 -0.062295 -0.164126 -0.156456 -0.06565 -0.167967 -0.163813 -0.062933 -0.167688 -0.16204 -0.060011 -0.152342 -0.14942 -0.060054 -0.156129 -0.150442 -0.061239 -0.152807 -0.149776 -0.032244 -0.155144 -0.268988 -0.032294 -0.160522 -0.268895 -0.034742 -0.160427 -0.26898 -0.046384 -0.173948 -0.237548 -0.0500441 -0.123165 -0.226155 -0.0511948 -0.122623 -0.223052 -0.033648 -0.167443 -0.266377 -0.03331 -0.166543 -0.267016 -0.032254 -0.137647 -0.268969 -0.062478 -0.152776 -0.150129 -0.061239 -0.152807 -0.149776 -0.061173 -0.146095 -0.149422 -0.045119 -0.173789 -0.25134 -0.050821 -0.173792 -0.239323 -0.053043 -0.173647 -0.244598 -0.032254 -0.12015 -0.268969 -0.034295 -0.169167 -0.265153 -0.033648 -0.167443 -0.266377 -0.036085 -0.166836 -0.266902 -0.041271 -0.170656 -0.263571 -0.039049 -0.167503 -0.266575 -0.034699 -0.120064 -0.269046 -0.0347 -0.146939 -0.269045 -0.032254 -0.12015 -0.268969 -0.059297 -0.119296 -0.242838 -0.049676 -0.164207 -0.259772 -0.0570492 -0.165997 -0.246987 -0.0423461 -0.119877 -0.245385 -0.047899 -0.119627 -0.262467 -0.049553 -0.119578 -0.259981 -0.06234 -0.119496 -0.149685 -0.06117 -0.119538 -0.14942 -0.059219 -0.119502 -0.181032 -0.037295 -0.16198 -0.268834 -0.037223 -0.160169 -0.268922 -0.034742 -0.160427 -0.26898 -0.062342 -0.143931 -0.149687 -0.061173 -0.146095 -0.149422 -0.06234 -0.132708 -0.149684 -0.0530965 -0.122945 -0.213171 -0.0547976 -0.123013 -0.204317 -0.0555558 -0.146725 -0.202109 -0.061654 -0.159058 -0.15216 -0.062478 -0.152776 -0.150129 -0.06317399999999999 -0.158896 -0.152487 -0.037295 -0.16198 -0.268834 -0.038497 -0.16615 -0.267291 -0.045735 -0.167981 -0.261308 -0.03331 -0.166543 -0.267016 -0.032631 -0.163595 -0.268277 -0.032249 -0.146972 -0.268979 -0.066426 -0.156527 -0.15576 -0.069857 -0.154956 -0.159655 -0.068435 -0.164632 -0.165306 -0.07356699999999999 -0.118998 -0.182532 -0.08101 -0.126736 -0.1835 -0.072017 -0.119053 -0.18233 -0.041603 -0.17395 -0.249692 -0.0500441 -0.123165 -0.226155 -0.046384 -0.173948 -0.237548 -0.06659900000000001 -0.119332 -0.154644 -0.06951599999999999 -0.119219 -0.158041 -0.06592099999999999 -0.144184 -0.153854 -0.0555558 -0.146725 -0.202109 -0.053742 -0.173948 -0.213554 -0.0511948 -0.122623 -0.223052 -0.050821 -0.173792 -0.239323 -0.041603 -0.17395 -0.249692 -0.046384 -0.173948 -0.237548 -0.060225 -0.165187 -0.15735 -0.060054 -0.156129 -0.150442 -0.060208 -0.164248 -0.156288 -0.038749 -0.171387 -0.26263 -0.036129 -0.171986 -0.261556 -0.041948 -0.173561 -0.257175 -0.06592099999999999 -0.144184 -0.153854 -0.06951599999999999 -0.144495 -0.15804 -0.066426 -0.156527 -0.15576 -0.06537900000000001 -0.173647 -0.19902 -0.058474 -0.173792 -0.213889 -0.062817 -0.173792 -0.187619 -0.066426 -0.156527 -0.15576 -0.06565 -0.167967 -0.163813 -0.06317399999999999 -0.158896 -0.152487 -0.032254 -0.12015 -0.268969 -0.033648 -0.167443 -0.266377 -0.032254 -0.137647 -0.268969 -0.045735 -0.167981 -0.261308 -0.047899 -0.13613 -0.262467 -0.042476 -0.144627 -0.265799 -0.037069 -0.137965 -0.269121 -0.037062 -0.146875 -0.269124 -0.042476 -0.144627 -0.265799 -0.032254 -0.12015 -0.268969 -0.034699 -0.120064 -0.269046 -0.034967 -0.120072 -0.263858 -0.041948 -0.173561 -0.257175 -0.041603 -0.17395 -0.249692 -0.045119 -0.173789 -0.25134 -0.038497 -0.16615 -0.267291 -0.037295 -0.16198 -0.268834 -0.034742 -0.160427 -0.26898 -0.07170600000000001 -0.127047 -0.187151 -0.076249 -0.126736 -0.233751 -0.065717 -0.127134 -0.22427 -0.06951599999999999 -0.119219 -0.158041 -0.06951599999999999 -0.144495 -0.15804 -0.06592099999999999 -0.144184 -0.153854 -0.06537900000000001 -0.173647 -0.19902 -0.066611 -0.173546 -0.188224 -0.06900100000000001 -0.169826 -0.189844 -0.076249 -0.126736 -0.233751 -0.076249 -0.07126 -0.233751 -0.068758 -0.07099800000000001 -0.233304 -0.053043 -0.173647 -0.244598 -0.050821 -0.173792 -0.239323 -0.05466 -0.173647 -0.240858 -0.048333 -0.173647 -0.252846 -0.053043 -0.173647 -0.244598 -0.058266 -0.169826 -0.239406 -0.036129 -0.171986 -0.261556 -0.034295 -0.169167 -0.265153 -0.034967 -0.120072 -0.263858 -0.0701 -0.11919 -0.160869 -0.06951599999999999 -0.119219 -0.158041 -0.059219 -0.119502 -0.181032 -0.060002 -0.146067 -0.14921 -0.060011 -0.152342 -0.14942 -0.060212 -0.168388 -0.162797 -0.061173 -0.132658 -0.14942 -0.06234 -0.119496 -0.149685 -0.06234 -0.132708 -0.149684 -0.036129 -0.171986 -0.261556 -0.041603 -0.17395 -0.249692 -0.041948 -0.173561 -0.257175 -0.032249 -0.146972 -0.268979 -0.032244 -0.155144 -0.268988 -0.0347 -0.146939 -0.269045 -0.06334099999999999 -0.127187 -0.232981 -0.06334099999999999 -0.119187 -0.232981 -0.061351 -0.119239 -0.238297 -0.071717 -0.119096 -0.172174 -0.06192 -0.118998 -0.181429 -0.072017 -0.119053 -0.18233 -0.0423461 -0.119877 -0.245385 -0.0426034 -0.145931 -0.245045 -0.034967 -0.120072 -0.263858 -0.069857 -0.154956 -0.159655 -0.071061 -0.16086 -0.166615 -0.068435 -0.164632 -0.165306 -0.06951599999999999 -0.144495 -0.15804 -0.069857 -0.154956 -0.159655 -0.066426 -0.156527 -0.15576 -0.053742 -0.173948 -0.213554 -0.058474 -0.173792 -0.213889 -0.050522 -0.173948 -0.224055 -0.032244 -0.155144 -0.268988 -0.034742 -0.160427 -0.26898 -0.0347 -0.146939 -0.269045 -0.058526 -0.173948 -0.187393 -0.062817 -0.173792 -0.187619 -0.053742 -0.173948 -0.213554 -0.032254 -0.12015 -0.268969 -0.0347 -0.146939 -0.269045 -0.032254 -0.137647 -0.268969 -0.060002 -0.146067 -0.14921 -0.060212 -0.168388 -0.162797 -0.059999 -0.144543 -0.149159 -0.050522 -0.173948 -0.224055 -0.058474 -0.173792 -0.213889 -0.046384 -0.173948 -0.237548 -0.076249 -0.126736 -0.233751 -0.068758 -0.118998 -0.233305 -0.06334099999999999 -0.119187 -0.232981 -0.062933 -0.167688 -0.16204 -0.060212 -0.168388 -0.162797 -0.060214 -0.167823 -0.161836 -0.058266 -0.169826 -0.239406 -0.065387 -0.165998 -0.22501 -0.061328 -0.165998 -0.238353 -0.060181 -0.162713 -0.154553 -0.060108 -0.159156 -0.151942 -0.061654 -0.159058 -0.15216 -0.058526 -0.173948 -0.187393 -0.053742 -0.173948 -0.213554 -0.059219 -0.119502 -0.181032 -0.065387 -0.165998 -0.22501 -0.06750299999999999 -0.165998 -0.21531 -0.065717 -0.127134 -0.22427 -0.07137400000000001 -0.165998 -0.190116 -0.071717 -0.119096 -0.172174 -0.072017 -0.127053 -0.18233 -0.045735 -0.167981 -0.261308 -0.058266 -0.169826 -0.239406 -0.0570492 -0.165997 -0.246987 -0.037223 -0.160169 -0.268922 -0.037295 -0.16198 -0.268834 -0.045735 -0.167981 -0.261308 -0.058266 -0.169826 -0.239406 -0.065137 -0.169826 -0.214993 -0.06750299999999999 -0.165998 -0.21531 -0.0555558 -0.146725 -0.202109 -0.0580022 -0.120438 -0.187438 -0.058413 -0.119945 -0.185262 -0.063567 -0.172356 -0.174442 -0.059217 -0.173678 -0.181024 -0.059687 -0.172139 -0.174114 -0.059217 -0.173678 -0.181024 -0.059999 -0.132619 -0.149157 -0.059687 -0.172139 -0.174114 -0.065387 -0.165998 -0.22501 -0.061351 -0.119239 -0.238297 -0.061328 -0.165998 -0.238353 -0.068435 -0.164632 -0.165306 -0.07137400000000001 -0.165998 -0.190116 -0.06900100000000001 -0.169826 -0.189844 -0.0513867 -0.122741 -0.222061 -0.0555558 -0.146725 -0.202109 -0.0511948 -0.122623 -0.223052 -0.037068 -0.119982 -0.269121 -0.042476 -0.144627 -0.265799 -0.0434993 -0.119771 -0.26517 -0.060212 -0.168388 -0.162797 -0.060011 -0.152342 -0.14942 -0.060214 -0.167823 -0.161836 -0.069857 -0.154956 -0.159655 -0.0701 -0.11919 -0.160869 -0.071717 -0.119096 -0.172174 -0.060108 -0.159156 -0.151942 -0.060054 -0.156129 -0.150442 -0.061654 -0.159058 -0.15216 -0.0555558 -0.146725 -0.202109 -0.0570217 -0.121279 -0.192606 -0.0580022 -0.120438 -0.187438 -0.034742 -0.160427 -0.26898 -0.037223 -0.160169 -0.268922 -0.0347 -0.146939 -0.269045 -0.06592099999999999 -0.144184 -0.153854 -0.062342 -0.143931 -0.149687 -0.06234 -0.132708 -0.149684 -0.066611 -0.173546 -0.188224 -0.06696299999999999 -0.171975 -0.174878 -0.06900100000000001 -0.169826 -0.189844 -0.07137400000000001 -0.165998 -0.190116 -0.072017 -0.127053 -0.18233 -0.07170600000000001 -0.127047 -0.187151 -0.07137400000000001 -0.165998 -0.190116 -0.071061 -0.16086 -0.166615 -0.071717 -0.119096 -0.172174 -0.076249 -0.126736 -0.233751 -0.08101 -0.126736 -0.1835 -0.08101 -0.07126 -0.1835 -0.034295 -0.169167 -0.265153 -0.032254 -0.12015 -0.268969 -0.034967 -0.120072 -0.263858 -0.06565 -0.167967 -0.163813 -0.066426 -0.156527 -0.15576 -0.068435 -0.164632 -0.165306 -0.06592099999999999 -0.144184 -0.153854 -0.066426 -0.156527 -0.15576 -0.06317399999999999 -0.158896 -0.152487 -0.076249 -0.07126 -0.233751 -0.07356699999999999 -0.07099800000000001 -0.182532 -0.068758 -0.07099800000000001 -0.233304 -0.068435 -0.164632 -0.165306 -0.071061 -0.16086 -0.166615 -0.07137400000000001 -0.165998 -0.190116 -0.059297 -0.119296 -0.242838 -0.049553 -0.119578 -0.259981 -0.049676 -0.164207 -0.259772 -0.0544271 -0.119498 -0.232738 -0.0423461 -0.119877 -0.245385 -0.049553 -0.119578 -0.259981 -0.034967 -0.120072 -0.263858 -0.037068 -0.119982 -0.269121 -0.0434993 -0.119771 -0.26517 -0.037056 -0.155948 -0.269128 -0.037223 -0.160169 -0.268922 -0.045735 -0.167981 -0.261308 -0.071061 -0.16086 -0.166615 -0.069857 -0.154956 -0.159655 -0.071717 -0.119096 -0.172174 -0.062478 -0.152776 -0.150129 -0.062347 -0.146132 -0.149702 -0.06592099999999999 -0.144184 -0.153854 -0.059219 -0.119502 -0.181032 -0.053742 -0.173948 -0.213554 -0.0555558 -0.146725 -0.202109 -0.07137400000000001 -0.165998 -0.190116 -0.07170600000000001 -0.127047 -0.187151 -0.065717 -0.127134 -0.22427 -0.047899 -0.13613 -0.262467 -0.047899 -0.119627 -0.262467 -0.042476 -0.144627 -0.265799 -0.061173 -0.146095 -0.149422 -0.061173 -0.132658 -0.14942 -0.06234 -0.132708 -0.149684 -0.058266 -0.169826 -0.239406 -0.06750299999999999 -0.165998 -0.21531 -0.065387 -0.165998 -0.22501 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645

    -
    -
    - - - 0 0 0 - 1 0 0 0 - - true - - - -
    - - - - 0.003 -0.0259881 -0.05590170000000005 0.003 -0.032999 -0.05800500000000006 0.003 -0.024999 -0.05800500000000006 -0.032144 0.0362324 -0.05800500000000006 -0.03 0.032001 -0.05800500000000006 -0.0303577 0.0319558 -0.05800500000000006 -0.057019 0.017147 -0.05800500000000006 -0.0571725 0.0168208 -0.05800500000000006 -0.0580713 0.0192372 -0.05800500000000006 -0.0474291 0.0311936 -0.05800500000000006 -0.0457077 0.0278311 -0.05800500000000006 -0.0484936 0.0258071 -0.05800500000000006 -0.050164 -0.0287944 -0.03245900000000006 -0.050164 -0.028795 -0.05800500000000006 -0.050164 -0.032999 -0.05800500000000006 0.032415 -0.024999 -0.006189010000000056 -0.0211946 -0.024999 -0.008272910000000055 -0.028282 -0.024999 0.02061499999999995 -0.002982 0.017147 -0.143005 0.000279519 0.0102152 -0.05800500000000006 0.000432999 0.00988901 -0.143005 0.005929 -0.024999 -0.03392200000000006 0.00300001 -0.024999 -0.03700500000000006 -0.0211946 -0.024999 -0.008272910000000055 -0.050164 -0.032999 -0.009398000000000056 -0.050164 -0.0287944 -0.03245900000000006 -0.050164 -0.032999 -0.05800500000000006 -0.0223997 0.0310412 -0.05800500000000006 -0.03 0.041001 -0.05800500000000006 -0.022042 0.030996 -0.05800500000000006 0.016861 0.041001 -0.03067600000000005 0.008704 0.041001 -0.03390500000000005 -0.03 0.041001 0.01825699999999994 0.015898 -0.032999 0.02891299999999995 0.015898 -0.024999 0.02891299999999995 0.008207010000000001 -0.024999 0.03195799999999994 -0.0308565 -0.024999 -0.008648480000000056 -0.00371071 -0.024999 -0.03700500000000006 -0.039 -0.024999 -0.03700500000000006 -0.045068 0.032779 -0.03700500000000006 -0.048519 -0.022588 -0.03700500000000006 -0.042292 -0.024726 -0.03700500000000006 -0.0596031 0.000297668 -0.02136220000000006 -0.058932 -0.00665 -0.02142500000000006 -0.058388 -8.89978e-05 -0.03700500000000006 -0.053715 -0.018544 -0.03700500000000006 -0.048519 -0.022588 -0.007143010000000055 -0.048519 -0.022588 -0.03700500000000006 0.012148 -0.024999 -0.03068800000000006 0.019397 -0.024999 -0.02670300000000006 0.012148 -0.032999 -0.03068800000000006 -0.045416 0.028043 -0.05800500000000006 -0.045417 0.028042 -0.143005 -0.0457077 0.0278311 -0.05800500000000006 0.008207010000000001 -0.024999 0.03195799999999994 -0.008206990000000001 -0.024999 0.03195799999999994 8.72213e-09 -0.024999 0.03299499999999994 -0.058394 0.013901 -0.03700500000000006 -0.058933 0.006022 -0.03700500000000006 -0.058388 -8.89978e-05 -0.03700500000000006 -0.037824 0.035926 0.007525989999999944 -0.0465 0.03658 -0.004374010000000056 -0.053335 0.031336 -0.01374800000000006 -0.051194 0.027795 -0.03700500000000006 -0.053715 -0.018544 -0.03700500000000006 -0.048519 -0.022588 -0.03700500000000006 -0.050164 -0.0287943 -0.009398550000000056 -0.0463785 -0.026383 -0.004206770000000056 -0.0471991 -0.0260829 -0.005332310000000055 -0.037958 0.030996 -0.05800500000000006 -0.0401397 0.0347307 -0.05800500000000006 -0.0337794 0.0315237 -0.05800500000000006 -0.039 -0.024999 -0.03700500000000006 -0.037824 0.035926 -0.03700500000000006 -0.042292 -0.024726 -0.03700500000000006 -0.03 0.041001 0.01825699999999994 -0.028281 0.037001 0.02061499999999995 -0.028281 0.041001 0.02061499999999995 -0.063 0.008000999999999999 -0.05800500000000006 -0.063 0.008000999999999999 -0.02700500000000006 -0.061876 0.016542 -0.02546300000000006 6.81479e-09 -0.024999 -0.03700500000000006 0.00300001 -0.024999 -0.03700500000000006 0.00300001 0.037001 -0.03700500000000006 -0.0211951 -0.032999 -0.008272280000000055 0.00444089 -0.032999 -0.02063940000000005 0.00541564 -0.032999 -0.01612520000000005 0.032935 -0.024999 0.002066989999999944 0.032415 -0.032999 -0.006189010000000056 0.032415 -0.024999 -0.006189010000000056 -0.057019 0.017147 -0.05800500000000006 -0.0542666 0.0204743 -0.05800500000000006 -0.057019 0.017147 -0.143005 -0.03 0.041001 0.01825699999999994 0.00438701 0.041001 0.03471899999999994 0.012884 0.041001 0.03253699999999995 -0.062933 -0.006978 -0.05800500000000006 -0.062933 -0.006978 -0.02691200000000005 -0.0623139 0.000841381 -0.02690510000000006 0.03438 0.041001 0.006552989999999944 0.031669 0.041001 0.01489699999999995 0.03438 0.037001 0.006552989999999944 0.003 -0.032999 -0.04099300000000006 0.003 -0.0259881 -0.05590170000000005 0.003 -0.024999 -0.04099300000000006 -0.055749 0.021343 -0.03700500000000006 -0.058394 0.013901 -0.03700500000000006 -0.058388 -8.89978e-05 -0.03700500000000006 -0.0465 0.03658 -0.05800500000000006 -0.0415231 0.0295844 -0.05800500000000006 -0.0474291 0.0311936 -0.05800500000000006 -0.0535363 0.0259051 -0.05800500000000006 -0.0542666 0.0204743 -0.05800500000000006 -0.058579 0.024501 -0.05800500000000006 -0.0596031 0.000297668 -0.02136220000000006 -0.058933 0.006022 -0.03700500000000006 -0.058933 0.006022 -0.02142600000000006 -0.062933 -0.006978 -0.02691200000000005 -0.0596031 0.000297668 -0.02136220000000006 -0.0623139 0.000841381 -0.02690510000000006 0.020572 0.037001 0.02830999999999994 -0.03 0.037001 0.01825699999999994 0.026968 0.037001 0.02230499999999994 -0.015898 -0.024999 0.02891299999999995 -0.008206990000000001 -0.032999 0.03195799999999994 -0.008206990000000001 -0.024999 0.03195799999999994 -0.03 0.037001 0.01825699999999994 0.034931 0.037001 -0.002203010000000056 0.03438 0.037001 0.006552989999999944 0.000279519 0.0102152 -0.05800500000000006 -0.002982 0.017147 -0.143005 -0.002982 0.017147 -0.05800500000000006 -0.058933 0.006022 -0.02142600000000006 -0.058394 0.013901 -0.02068700000000006 -0.063 0.008000999999999999 -0.02700500000000006 0.034931 0.041001 -0.002203010000000056 0.033287 0.037001 -0.01082100000000006 0.033287 0.041001 -0.01082100000000006 0.003 0.041001 -0.05800500000000006 0.00300001 0.037001 -0.03700500000000006 0.003 -0.005499 -0.05800500000000006 -0.008095 0.023328 -0.143005 -0.008095 0.023328 -0.05800500000000006 -0.0032118 0.0174248 -0.05800500000000006 -0.0211951 -0.032999 -0.008272280000000055 0.032415 -0.032999 -0.006189010000000056 -0.028282 -0.032999 0.02061499999999995 -0.039 -0.024999 -0.008965040000000056 -0.036226 -0.024999 -0.007533000000000055 -0.039 -0.024999 -0.03700500000000006 -0.028282 -0.024999 0.02061499999999995 -0.050164 -0.024999 -0.009399000000000055 -0.0471991 -0.0260829 -0.005332310000000055 -0.045068 0.032779 -0.002410000000000055 -0.045068 0.032779 -0.03700500000000006 -0.037824 0.035926 -0.03700500000000006 -0.053715 -0.018544 -0.01426900000000006 -0.053715 -0.018544 -0.03700500000000006 -0.057316 -0.013033 -0.03700500000000006 -0.0382932 0.0308632 -0.05800500000000006 -0.037959 0.030995 -0.143005 -0.045417 0.028042 -0.143005 -0.04155 -0.032999 -0.01727360000000006 -0.0343095 -0.032999 -0.02389350000000006 -0.0280051 -0.032999 -0.02256690000000006 0.032415 -0.032999 -0.006189010000000056 0.00560997 -0.032999 -0.01012250000000006 0.029859 -0.032999 -0.01405600000000006 0.00438701 0.037001 0.03471899999999994 -0.00438699 0.037001 0.03471899999999994 -0.03 0.037001 0.01825699999999994 -0.053335 0.031336 -0.05800500000000006 -0.0535363 0.0259051 -0.05800500000000006 -0.058579 0.024501 -0.05800500000000006 -0.036226 -0.024999 -0.007533000000000055 -0.039 -0.024999 -0.008965040000000056 -0.036914 -0.024999 0.002519999999999945 -0.00438699 0.037001 0.03471899999999994 -0.012884 0.037001 0.03253699999999995 -0.03 0.037001 0.01825699999999994 -0.0521358 0.0230502 -0.05800500000000006 -0.051906 0.023328 -0.05800500000000006 -0.051906 0.023328 -0.143005 -0.051194 0.027795 -0.01081200000000006 -0.045068 0.032779 -0.002410000000000055 -0.053335 0.031336 -0.01374800000000006 -0.0211946 -0.024999 -0.008272910000000055 -0.00371071 -0.024999 -0.03700500000000006 -0.0308565 -0.024999 -0.008648480000000056 -0.050164 -0.028795 -0.05800500000000006 -0.052302 -0.027495 -0.05800500000000006 -0.050164 -0.032999 -0.05800500000000006 -0.050164 -0.0287943 -0.009398550000000056 -0.050164 -0.0287943 -0.02680210000000005 -0.050164 -0.032999 -0.009398000000000056 -0.050164 -0.032999 -0.05800500000000006 -0.04155 -0.032999 -0.05800500000000006 -0.045857 -0.032999 -0.03370150000000006 -0.055749 0.021343 -0.03700500000000006 -0.055749 0.021343 -0.01705900000000006 -0.058394 0.013901 -0.02068700000000006 -0.0401397 0.0347307 -0.05800500000000006 -0.038541 0.039877 -0.05800500000000006 -0.0337794 0.0315237 -0.05800500000000006 -0.008095 0.023328 -0.143005 -0.0032118 0.0174248 -0.05800500000000006 -0.002982 0.017147 -0.143005 -0.00776776 -0.00549899 -0.143005 -0.0147987 -0.00549899 -0.143005 -0.037959 0.030995 -0.143005 -0.058933 0.006022 -0.02142600000000006 -0.063 0.008000999999999999 -0.02700500000000006 -0.0623139 0.000841381 -0.02690510000000006 -0.0463785 -0.026383 -0.004206770000000056 -0.028282 -0.024999 0.02061499999999995 -0.0471991 -0.0260829 -0.005332310000000055 0.032935 -0.032999 0.002066989999999944 0.031385 -0.024999 0.01019299999999995 0.031385 -0.032999 0.01019299999999995 -0.028282 -0.032999 0.02061499999999995 0.032935 -0.032999 0.002066989999999944 0.031385 -0.032999 0.01019299999999995 -0.00367516 -0.00549899 -0.143005 -0.00776776 -0.00549899 -0.143005 -0.037959 0.030995 -0.143005 -0.0535363 0.0259051 -0.05800500000000006 -0.053335 0.031336 -0.05800500000000006 -0.0484936 0.0258071 -0.05800500000000006 0.02259 -0.024999 0.02405099999999994 -0.018664 -0.024999 0.02720999999999995 0.015898 -0.024999 0.02891299999999995 -0.0551317 -0.005499 -0.143005 -0.037959 0.030995 -0.143005 -0.0498164 -0.005499 -0.143005 -0.0401397 0.0347307 -0.05800500000000006 -0.0415231 0.0295844 -0.05800500000000006 -0.0465 0.03658 -0.05800500000000006 0.00300001 0.037001 -0.03700500000000006 0.003 -0.024999 -0.05560500000000006 0.003 -0.008739480000000001 -0.05800500000000006 -0.012884 0.037001 0.03253699999999995 -0.020573 0.037001 0.02831099999999994 -0.03 0.037001 0.01825699999999994 0.029551 0.041001 -0.01875900000000006 0.033287 0.041001 -0.01082100000000006 0.029551 0.037001 -0.01875900000000006 -0.0585124 0.0139735 -0.05800500000000006 -0.060434 0.00988996 -0.05800500000000006 -0.0607562 0.011659 -0.05800500000000006 -0.063 0.008000999999999999 -0.05800500000000006 -0.0620423 0.00410213 -0.05798660000000005 -0.0630566 0.000834875 -0.05796500000000006 -0.050164 -0.032999 -0.009398000000000056 -0.035351 -0.032999 0.01091799999999995 -0.0463785 -0.026383 -0.004206770000000056 -0.03 0.037001 0.01825699999999994 -0.020573 0.037001 0.02831099999999994 -0.026968 0.037001 0.02230499999999994 0.02259 -0.024999 0.02405099999999994 0.027863 -0.024999 0.01767699999999994 -0.028282 -0.024999 0.02061499999999995 0.027863 -0.024999 0.01767699999999994 0.031385 -0.024999 0.01019299999999995 -0.028282 -0.024999 0.02061499999999995 -0.03 0.037001 0.01825699999999994 0.023959 0.037001 -0.02551900000000006 0.029551 0.037001 -0.01875900000000006 -0.051906 0.023328 -0.05800500000000006 -0.0535363 0.0259051 -0.05800500000000006 -0.0484936 0.0258071 -0.05800500000000006 -0.061937 0.00201 -0.05797540000000006 -0.061028 0.00677597 -0.05800500000000006 -0.061938 0.00201 -0.143005 0.020572 0.037001 0.02830999999999994 0.012884 0.037001 0.03253699999999995 -0.03 0.037001 0.01825699999999994 -0.0211951 -0.032999 -0.008272280000000055 -0.04155 -0.032999 -0.01727360000000006 -0.0280051 -0.032999 -0.02256690000000006 -0.00371071 -0.024999 -0.03700500000000006 -0.037824 0.035926 -0.03700500000000006 -0.039 -0.024999 -0.03700500000000006 -0.038541 0.039877 -0.05800500000000006 -0.032144 0.0362324 -0.05800500000000006 -0.0337794 0.0315237 -0.05800500000000006 -0.020573 0.037001 0.02831099999999994 -0.012884 0.037001 0.03253699999999995 -0.020573 0.041001 0.02831099999999994 -0.062933 -0.006978 -0.02691200000000005 -0.061326 -0.01471 -0.05800500000000006 -0.061326 -0.01471 -0.02470800000000006 -0.035351 -0.032999 0.01091799999999995 -0.050164 -0.032999 -0.009398000000000056 -0.04155 -0.032999 -0.01727360000000006 0.012884 0.037001 0.03253699999999995 0.020572 0.037001 0.02830999999999994 0.012884 0.041001 0.03253699999999995 -0.061938 0.00201 -0.143005 -0.0614652 -0.005499 -0.143005 -0.0614652 -0.005499 -0.1374900000000001 -0.058394 0.013901 -0.02068700000000006 -0.055749 0.021343 -0.01705900000000006 -0.061876 0.016542 -0.02546300000000006 -0.028282 -0.032999 0.02061499999999995 -0.028282 -0.024999 0.02061499999999995 -0.0463785 -0.026383 -0.004206770000000056 -0.050164 -0.0287943 -0.02680210000000005 -0.050164 -0.0287943 -0.009398550000000056 -0.052302 -0.027494 -0.01233100000000006 -0.03 0.037001 0.01825699999999994 -0.028281 0.037001 0.02061499999999995 -0.038541 0.039877 0.006542989999999945 -0.035351 -0.032999 0.01091799999999995 -0.028282 -0.032999 0.02061499999999995 -0.0463785 -0.026383 -0.004206770000000056 -0.025747 0.0314639 -0.05800500000000006 -0.03 0.032001 -0.05800500000000006 -0.032144 0.0362324 -0.05800500000000006 -0.0412745 -0.032999 -0.05800500000000006 -0.0343095 -0.032999 -0.02389350000000006 -0.04155 -0.032999 -0.05800500000000006 0.023959 0.037001 -0.02551900000000006 0.023959 0.041001 -0.02551900000000006 0.029551 0.041001 -0.01875900000000006 -0.022043 0.030995 -0.143005 -0.014584 0.028042 -0.143005 -0.037959 0.030995 -0.143005 -0.03 0.041001 0.01825699999999994 -0.020573 0.041001 0.02831099999999994 -0.012884 0.041001 0.03253699999999995 -0.03 0.037001 0.01825699999999994 0.016861 0.037001 -0.03067600000000005 0.023959 0.037001 -0.02551900000000006 -0.053335 0.031336 -0.05800500000000006 -0.0474291 0.0311936 -0.05800500000000006 -0.0484936 0.0258071 -0.05800500000000006 0.03438 0.037001 0.006552989999999944 0.031669 0.041001 0.01489699999999995 0.031669 0.037001 0.01489699999999995 0.008704 0.041001 -0.03390500000000005 0.008704 0.037001 -0.03390500000000005 0.00300001 0.037001 -0.03487600000000005 -0.0620423 0.00410213 -0.05798660000000005 -0.061937 0.00201 -0.05797540000000006 -0.0630566 0.000834875 -0.05796500000000006 0.023959 0.041001 -0.02551900000000006 -0.03 0.041001 0.01825699999999994 0.029551 0.041001 -0.01875900000000006 0.003 -0.005499 -0.05800500000000006 0.00300001 0.037001 -0.03700500000000006 0.003 -0.008739480000000001 -0.05800500000000006 -0.0309972 -0.005499 -0.143005 -0.0356626 -0.005499 -0.143005 -0.037959 0.030995 -0.143005 0.023959 0.041001 -0.02551900000000006 0.016861 0.041001 -0.03067600000000005 -0.03 0.041001 0.01825699999999994 0.031669 0.041001 0.01489699999999995 -0.03 0.041001 0.01825699999999994 0.026968 0.041001 0.02230499999999994 0.001936 0.00201 -0.05800500000000006 0.003 0.041001 -0.05800500000000006 0.003 -0.005499 -0.05800500000000006 -0.0542666 0.0204743 -0.05800500000000006 -0.0580713 0.0192372 -0.05800500000000006 -0.058579 0.024501 -0.05800500000000006 -0.0611192 -0.005499 -0.143005 -0.0614652 -0.005499 -0.143005 -0.061938 0.00201 -0.143005 -0.058579 0.024501 -0.05800500000000006 -0.061876 0.016542 -0.05800500000000006 -0.058579 0.024501 -0.02094100000000006 -0.008206990000000001 -0.032999 0.03195799999999994 0.008207010000000001 -0.032999 0.03195799999999994 9.071820000000001e-09 -0.032999 0.03299499999999994 0.012148 -0.032999 -0.03068800000000006 0.019397 -0.024999 -0.02670300000000006 0.019397 -0.032999 -0.02670300000000006 -0.008095 0.023328 -0.143005 -0.008386640000000001 0.0235399 -0.05800500000000006 -0.008095 0.023328 -0.05800500000000006 0.029859 -0.024999 -0.01405600000000006 0.032415 -0.024999 -0.006189010000000056 0.029859 -0.032999 -0.01405600000000006 0.000432999 0.00988901 -0.143005 0.001936 0.00201001 -0.143005 -0.037959 0.030995 -0.143005 -0.0261013 -0.00549899 -0.143005 -0.0309972 -0.005499 -0.143005 -0.037959 0.030995 -0.143005 -0.026968 0.041001 0.02230499999999994 -0.03 0.041001 0.01825699999999994 -0.028281 0.041001 0.02061499999999995 -0.022043 0.030995 -0.143005 -0.0223997 0.0310412 -0.05800500000000006 -0.022042 0.030996 -0.05800500000000006 0.00376101 -0.024999 -0.03716600000000005 0.005929 -0.024999 -0.03392200000000006 0.00376101 -0.032999 -0.03716600000000005 0.034931 0.037001 -0.002203010000000056 0.033287 0.037001 -0.01082100000000006 0.034931 0.041001 -0.002203010000000056 -0.058394 0.013901 -0.03700500000000006 -0.055749 0.021343 -0.03700500000000006 -0.058394 0.013901 -0.02068700000000006 -0.03 0.037001 -0.03700500000000006 -0.03 0.037001 0.01825699999999994 -0.037824 0.035926 0.007525989999999944 -0.026968 0.041001 0.02230499999999994 -0.020573 0.041001 0.02831099999999994 -0.03 0.041001 0.01825699999999994 -0.0596031 0.000297668 -0.02136220000000006 -0.058933 0.006022 -0.02142600000000006 -0.0623139 0.000841381 -0.02690510000000006 -0.0303577 0.0319558 -0.05800500000000006 -0.037959 0.030995 -0.143005 -0.0337794 0.0315237 -0.05800500000000006 -0.03 0.041001 0.01825699999999994 -0.038541 0.039877 -0.05800500000000006 -0.038541 0.039877 0.006542989999999945 0.031385 -0.032999 0.01019299999999995 0.031385 -0.024999 0.01019299999999995 0.027863 -0.024999 0.01767699999999994 -0.036226 -0.024999 -0.007533000000000055 -0.0308565 -0.024999 -0.008648480000000056 -0.039 -0.024999 -0.03700500000000006 -0.042292 -0.024726 0.001397999999999944 -0.0432793 -0.024999 4.394579999994449e-05 -0.039 -0.024999 0.005912989999999944 -0.002982 0.017147 -0.143005 0.000432999 0.00988901 -0.143005 -0.037959 0.030995 -0.143005 -0.026968 0.037001 0.02230499999999994 -0.026968 0.041001 0.02230499999999994 -0.028281 0.041001 0.02061499999999995 -0.0571725 0.0168208 -0.05800500000000006 -0.0585124 0.0139735 -0.05800500000000006 -0.061876 0.016542 -0.05800500000000006 -0.050164 -0.0287943 -0.009398550000000056 -0.050164 -0.032999 -0.009398000000000056 -0.0463785 -0.026383 -0.004206770000000056 -0.03 0.032001 -0.05800500000000006 -0.030001 0.032001 -0.143005 -0.0303577 0.0319558 -0.05800500000000006 0.00438701 0.041001 0.03471899999999994 0.012884 0.037001 0.03253699999999995 0.012884 0.041001 0.03253699999999995 0.00300001 0.041001 -0.03487600000000005 0.00300001 0.037001 -0.03487600000000005 0.00300001 0.037001 -0.03700500000000006 0.00300001 0.041001 -0.03487600000000005 0.008704 0.041001 -0.03390500000000005 0.00300001 0.037001 -0.03487600000000005 -0.045068 0.032779 -0.002410000000000055 -0.051194 0.027795 -0.01081200000000006 -0.045068 0.032779 -0.03700500000000006 -0.03 0.037001 -0.03700500000000006 6.81479e-09 -0.024999 -0.03700500000000006 0.00300001 0.037001 -0.03700500000000006 -0.062933 -0.006978 -0.05800500000000006 -0.0623139 0.000841381 -0.02690510000000006 -0.0629566 -0.00547481 -0.05799990000000006 -0.015898 -0.032999 0.02891299999999995 -0.008206990000000001 -0.032999 0.03195799999999994 -0.015898 -0.024999 0.02891299999999995 0.00376101 -0.032999 -0.03716600000000005 0.00034425 -0.032999 -0.03941470000000005 0.003 -0.032999 -0.04099300000000006 -0.0498164 -0.005499 -0.143005 -0.037959 0.030995 -0.143005 -0.0449206 -0.005499 -0.143005 -0.018664 -0.024999 0.02720999999999995 -0.015898 -0.032999 0.02891299999999995 -0.015898 -0.024999 0.02891299999999995 -0.051194 0.027795 -0.01081200000000006 -0.051194 0.027795 -0.03700500000000006 -0.045068 0.032779 -0.03700500000000006 -0.0619146 0.00165306 -0.05797350000000005 -0.0614652 -0.005499 -0.06771010000000005 -0.0618235 0.000203272 -0.05796570000000006 -0.063 0.008000999999999999 -0.02700500000000006 -0.063 0.008000999999999999 -0.05800500000000006 -0.0630566 0.000834875 -0.05796500000000006 0.029859 -0.032999 -0.01405600000000006 0.00560997 -0.032999 -0.01012250000000006 0.00541564 -0.032999 -0.01612520000000005 -0.060434 0.00988996 -0.05800500000000006 -0.0585124 0.0139735 -0.05800500000000006 -0.060434 0.009889 -0.143005 -0.0629566 -0.00547481 -0.05799990000000006 -0.0630566 0.000834875 -0.05796500000000006 -0.0614652 -0.005499 -0.05800500000000006 0.02259 -0.024999 0.02405099999999994 0.027863 -0.032999 0.01767699999999994 0.027863 -0.024999 0.01767699999999994 -0.0149192 0.0281757 -0.05800500000000006 -0.022043 0.030995 -0.143005 -0.022042 0.030996 -0.05800500000000006 0.003 -0.032999 -0.04099300000000006 0.00034425 -0.032999 -0.03941470000000005 0.003 -0.032999 -0.05800500000000006 -0.0571725 0.0168208 -0.05800500000000006 -0.057019 0.017147 -0.143005 -0.060434 0.009889 -0.143005 -0.03 0.041001 0.01825699999999994 0.020572 0.041001 0.02830999999999994 0.026968 0.041001 0.02230499999999994 0.00034425 -0.032999 -0.03941470000000005 -0.0111428 -0.032999 -0.03258800000000005 0.003 -0.032999 -0.05800500000000006 -0.0211946 -0.024999 -0.008272910000000055 -0.0308565 -0.024999 -0.008648480000000056 -0.035351 -0.024999 0.01091799999999995 -0.0614652 -0.005499 -0.06771010000000005 -0.0619146 0.00165306 -0.05797350000000005 -0.0614652 -0.005499 -0.1374900000000001 -0.0465 0.03658 -0.004374010000000056 -0.03 0.037001 0.01825699999999994 -0.038541 0.039877 0.006542989999999945 9.071820000000001e-09 -0.032999 0.03299499999999994 0.008207010000000001 -0.032999 0.03195799999999994 8.72213e-09 -0.024999 0.03299499999999994 -0.030001 0.032001 -0.143005 -0.025747 0.0314639 -0.05800500000000006 -0.0223997 0.0310412 -0.05800500000000006 0.008704 0.037001 -0.03390500000000005 0.016861 0.041001 -0.03067600000000005 0.016861 0.037001 -0.03067600000000005 0.020572 0.037001 0.02830999999999994 0.020572 0.041001 0.02830999999999994 0.012884 0.041001 0.03253699999999995 0.032415 -0.024999 -0.006189010000000056 0.032415 -0.032999 -0.006189010000000056 0.029859 -0.032999 -0.01405600000000006 -0.037959 0.030995 -0.143005 -0.0611192 -0.005499 -0.143005 -0.061938 0.00201 -0.143005 0.027863 -0.032999 0.01767699999999994 -0.028282 -0.032999 0.02061499999999995 0.031385 -0.032999 0.01019299999999995 -0.053715 -0.018544 -0.01426900000000006 -0.048519 -0.022588 -0.007143010000000055 -0.053715 -0.018544 -0.03700500000000006 -0.014584 0.028042 -0.143005 -0.0149192 0.0281757 -0.05800500000000006 -0.014584 0.028043 -0.05800500000000006 -0.0580713 0.0192372 -0.05800500000000006 -0.061876 0.016542 -0.05800500000000006 -0.058579 0.024501 -0.05800500000000006 0.032935 -0.024999 0.002066989999999944 0.032415 -0.024999 -0.006189010000000056 -0.028282 -0.024999 0.02061499999999995 -0.061028 0.00677597 -0.05800500000000006 -0.061937 0.00201 -0.05797540000000006 -0.0620423 0.00410213 -0.05798660000000005 0.001936 0.00201 -0.05800500000000006 0.00186845 0.00236411 -0.05800500000000006 0.003 0.041001 -0.05800500000000006 0.020572 0.041001 0.02830999999999994 0.026968 0.037001 0.02230499999999994 0.026968 0.041001 0.02230499999999994 0.032935 -0.032999 0.002066989999999944 0.032935 -0.024999 0.002066989999999944 0.031385 -0.024999 0.01019299999999995 -0.008095 0.023328 -0.143005 -0.002982 0.017147 -0.143005 -0.037959 0.030995 -0.143005 -0.051906 0.023328 -0.143005 -0.051906 0.023328 -0.05800500000000006 -0.0484936 0.0258071 -0.05800500000000006 -0.045416 0.028043 -0.05800500000000006 -0.0415231 0.0295844 -0.05800500000000006 -0.045417 0.028042 -0.143005 0.012148 -0.024999 -0.03068800000000006 0.00997601 -0.032999 -0.03146100000000006 0.00997601 -0.024999 -0.03146100000000006 -0.037958 0.030996 -0.05800500000000006 -0.0382932 0.0308632 -0.05800500000000006 -0.0401397 0.0347307 -0.05800500000000006 0.016861 0.041001 -0.03067600000000005 0.023959 0.041001 -0.02551900000000006 0.016861 0.037001 -0.03067600000000005 -0.038541 0.039877 0.006542989999999945 -0.038541 0.039877 -0.05800500000000006 -0.0465 0.03658 -0.05800500000000006 -0.0585124 0.0139735 -0.05800500000000006 -0.0571725 0.0168208 -0.05800500000000006 -0.060434 0.009889 -0.143005 0.00438701 0.037001 0.03471899999999994 0.00438701 0.041001 0.03471899999999994 -0.00438699 0.041001 0.03471899999999994 0.025427 -0.032999 -0.02104000000000006 0.029859 -0.032999 -0.01405600000000006 0.00541564 -0.032999 -0.01612520000000005 -0.028281 0.037001 0.02061499999999995 -0.026968 0.037001 0.02230499999999994 -0.028281 0.041001 0.02061499999999995 0.015898 -0.024999 0.02891299999999995 -0.018664 -0.024999 0.02720999999999995 -0.015898 -0.024999 0.02891299999999995 -0.058932 -0.00665 -0.02142500000000006 -0.058932 -0.00665 -0.03700500000000006 -0.058388 -8.89978e-05 -0.03700500000000006 -0.038541 0.039877 -0.05800500000000006 -0.03 0.041001 0.01825699999999994 -0.03 0.041001 -0.05800500000000006 -0.037959 0.030995 -0.143005 -0.037958 0.030996 -0.05800500000000006 -0.0337794 0.0315237 -0.05800500000000006 -0.037959 0.030995 -0.143005 -0.0402551 -0.005499 -0.143005 -0.0449206 -0.005499 -0.143005 -0.03 0.037001 0.01825699999999994 -0.03 0.037001 -0.03700500000000006 0.00300001 0.037001 -0.03700500000000006 0.032415 -0.032999 -0.006189010000000056 0.032935 -0.032999 0.002066989999999944 -0.028282 -0.032999 0.02061499999999995 0.033287 0.041001 -0.01082100000000006 0.033287 0.037001 -0.01082100000000006 0.029551 0.037001 -0.01875900000000006 -0.051194 0.027795 -0.03700500000000006 -0.055749 0.021343 -0.03700500000000006 -0.053715 -0.018544 -0.03700500000000006 0.008207010000000001 -0.032999 0.03195799999999994 0.008207010000000001 -0.024999 0.03195799999999994 8.72213e-09 -0.024999 0.03299499999999994 -0.057019 0.017147 -0.143005 -0.0542666 0.0204743 -0.05800500000000006 -0.0521358 0.0230502 -0.05800500000000006 -0.037959 0.030995 -0.143005 -0.051906 0.023328 -0.143005 -0.045417 0.028042 -0.143005 0.02259 -0.024999 0.02405099999999994 0.015898 -0.024999 0.02891299999999995 0.02259 -0.032999 0.02405099999999994 -0.022043 0.030995 -0.143005 -0.030001 0.032001 -0.143005 -0.0223997 0.0310412 -0.05800500000000006 -0.008386640000000001 0.0235399 -0.05800500000000006 -0.008095 0.023328 -0.143005 -0.014584 0.028042 -0.143005 -0.0607562 0.011659 -0.05800500000000006 -0.060434 0.00988996 -0.05800500000000006 -0.063 0.008000999999999999 -0.05800500000000006 0.001936 0.00201001 -0.143005 0.000903742 -0.00549899 -0.143005 -0.037959 0.030995 -0.143005 0.000433002 0.009889 -0.05800500000000006 0.000279519 0.0102152 -0.05800500000000006 0.003 0.041001 -0.05800500000000006 -0.032144 0.0362324 -0.05800500000000006 -0.038541 0.039877 -0.05800500000000006 -0.03 0.041001 -0.05800500000000006 0.00300001 0.037001 -0.03700500000000006 0.003 -0.024999 -0.04099300000000006 0.003 -0.024999 -0.05560500000000006 -0.0356626 -0.005499 -0.143005 -0.0402551 -0.005499 -0.143005 -0.037959 0.030995 -0.143005 -0.0382932 0.0308632 -0.05800500000000006 -0.0415231 0.0295844 -0.05800500000000006 -0.0401397 0.0347307 -0.05800500000000006 -0.058394 0.013901 -0.03700500000000006 -0.058394 0.013901 -0.02068700000000006 -0.058933 0.006022 -0.02142600000000006 0.005929 -0.024999 -0.03392200000000006 0.00997601 -0.024999 -0.03146100000000006 0.005929 -0.032999 -0.03392200000000006 -0.045417 0.028042 -0.143005 -0.051906 0.023328 -0.143005 -0.0457077 0.0278311 -0.05800500000000006 -0.063 0.008000999999999999 -0.02700500000000006 -0.0630566 0.000834875 -0.05796500000000006 -0.0623139 0.000841381 -0.02690510000000006 -0.032144 0.0362324 -0.05800500000000006 -0.0303577 0.0319558 -0.05800500000000006 -0.0337794 0.0315237 -0.05800500000000006 -0.0211946 -0.024999 -0.008272910000000055 -0.035351 -0.024999 0.01091799999999995 -0.028282 -0.024999 0.02061499999999995 -0.061937 0.00201 -0.05797540000000006 -0.061938 0.00201 -0.143005 -0.0617011 -0.00174447 -0.1004890000000001 -0.0207863 -0.00549899 -0.143005 -0.0261013 -0.00549899 -0.143005 -0.037959 0.030995 -0.143005 -0.057316 -0.013033 -0.01920800000000005 -0.058932 -0.00665 -0.03700500000000006 -0.058932 -0.00665 -0.02142500000000006 0.02259 -0.032999 0.02405099999999994 0.015898 -0.024999 0.02891299999999995 0.015898 -0.032999 0.02891299999999995 -0.008386640000000001 0.0235399 -0.05800500000000006 -0.014584 0.028042 -0.143005 -0.014584 0.028043 -0.05800500000000006 -0.025747 0.0314639 -0.05800500000000006 -0.030001 0.032001 -0.143005 -0.03 0.032001 -0.05800500000000006 -0.03 0.041001 0.01825699999999994 0.031669 0.041001 0.01489699999999995 0.03438 0.041001 0.006552989999999944 0.00997601 -0.024999 -0.03146100000000006 0.00997601 -0.032999 -0.03146100000000006 0.005929 -0.032999 -0.03392200000000006 -0.058388 -8.89978e-05 -0.03700500000000006 -0.058932 -0.00665 -0.03700500000000006 -0.057316 -0.013033 -0.03700500000000006 -0.008206990000000001 -0.024999 0.03195799999999994 9.071820000000001e-09 -0.032999 0.03299499999999994 8.72213e-09 -0.024999 0.03299499999999994 -0.0542666 0.0204743 -0.05800500000000006 -0.057019 0.017147 -0.05800500000000006 -0.0580713 0.0192372 -0.05800500000000006 0.019397 -0.024999 -0.02670300000000006 0.025427 -0.024999 -0.02104000000000006 0.019397 -0.032999 -0.02670300000000006 -0.0111428 -0.032999 -0.03258800000000005 -0.0211951 -0.032999 -0.008272280000000055 -0.0280051 -0.032999 -0.02256690000000006 -0.03 0.041001 0.01825699999999994 0.03438 0.041001 0.006552989999999944 0.034931 0.041001 -0.002203010000000056 -0.028281 0.037001 0.02061499999999995 -0.03 0.041001 0.01825699999999994 -0.038541 0.039877 0.006542989999999945 0.008704 0.041001 -0.03390500000000005 0.00300001 0.041001 -0.03487600000000005 -0.03 0.041001 0.01825699999999994 -0.058579 0.024501 -0.02094100000000006 -0.061876 0.016542 -0.05800500000000006 -0.061876 0.016542 -0.02546300000000006 -0.057693 -0.021723 -0.05800500000000006 -0.052302 -0.027495 -0.05800500000000006 -0.057692 -0.021723 -0.01972500000000005 0.029859 -0.024999 -0.01405600000000006 0.029859 -0.032999 -0.01405600000000006 0.025427 -0.032999 -0.02104000000000006 -0.053715 -0.018544 -0.01426900000000006 -0.061326 -0.01471 -0.02470800000000006 -0.057692 -0.021723 -0.01972500000000005 -0.0618235 0.000203272 -0.05796570000000006 -0.0614652 -0.005499 -0.06771010000000005 -0.0614652 -0.005499 -0.05800500000000006 -0.002982 0.017147 -0.143005 -0.0032118 0.0174248 -0.05800500000000006 -0.002982 0.017147 -0.05800500000000006 0.001936 0.00201001 -0.143005 0.000432999 0.00988901 -0.143005 0.00186845 0.00236411 -0.05800500000000006 0.015898 -0.032999 0.02891299999999995 -0.015898 -0.032999 0.02891299999999995 -0.018664 -0.032999 0.02720999999999995 -0.045416 0.028043 -0.05800500000000006 -0.0457077 0.0278311 -0.05800500000000006 -0.0474291 0.0311936 -0.05800500000000006 -0.03 0.037001 -0.03700500000000006 -0.037824 0.035926 0.007525989999999944 -0.037824 0.035926 -0.03700500000000006 0.008207010000000001 -0.032999 0.03195799999999994 -0.008206990000000001 -0.032999 0.03195799999999994 -0.015898 -0.032999 0.02891299999999995 0.00376101 -0.024999 -0.03716600000000005 0.003 -0.032999 -0.04099300000000006 0.003 -0.024999 -0.04099300000000006 -0.0211946 -0.024999 -0.008272910000000055 0.00300001 -0.024999 -0.03700500000000006 6.81479e-09 -0.024999 -0.03700500000000006 -0.020573 0.041001 0.02831099999999994 -0.012884 0.037001 0.03253699999999995 -0.012884 0.041001 0.03253699999999995 0.00300001 0.041001 -0.03487600000000005 0.00300001 0.037001 -0.03700500000000006 0.003 0.041001 -0.05800500000000006 -0.04155 -0.032999 -0.01727360000000006 -0.050164 -0.032999 -0.009398000000000056 -0.045857 -0.032999 -0.03370150000000006 -0.03 0.041001 0.01825699999999994 0.00300001 0.041001 -0.03487600000000005 0.003 0.041001 -0.05800500000000006 -0.053335 0.031336 -0.01374800000000006 -0.058579 0.024501 -0.05800500000000006 -0.058579 0.024501 -0.02094100000000006 -0.055749 0.021343 -0.03700500000000006 -0.051194 0.027795 -0.03700500000000006 -0.055749 0.021343 -0.01705900000000006 0.000279519 0.0102152 -0.05800500000000006 -0.002982 0.017147 -0.05800500000000006 0.003 0.041001 -0.05800500000000006 0.008207010000000001 -0.032999 0.03195799999999994 -0.015898 -0.032999 0.02891299999999995 0.015898 -0.032999 0.02891299999999995 -0.012884 0.037001 0.03253699999999995 -0.00438699 0.037001 0.03471899999999994 -0.012884 0.041001 0.03253699999999995 -0.015898 -0.032999 0.02891299999999995 -0.018664 -0.024999 0.02720999999999995 -0.018664 -0.032999 0.02720999999999995 -0.048519 -0.022588 -0.007143010000000055 -0.042292 -0.024726 0.001397999999999944 -0.048519 -0.022588 -0.03700500000000006 -0.0465 0.03658 -0.004374010000000056 -0.053335 0.031336 -0.05800500000000006 -0.053335 0.031336 -0.01374800000000006 0.001936 0.00201 -0.05800500000000006 0.00146417 -0.005499 -0.05800500000000006 0.00146417 -0.005499 -0.05951950000000006 -0.061326 -0.01471 -0.02470800000000006 -0.057693 -0.021723 -0.05800500000000006 -0.057692 -0.021723 -0.01972500000000005 -0.037824 0.035926 -0.03700500000000006 -0.045068 0.032779 -0.03700500000000006 -0.042292 -0.024726 -0.03700500000000006 0.00186845 0.00236411 -0.05800500000000006 0.000433002 0.009889 -0.05800500000000006 0.003 0.041001 -0.05800500000000006 -0.053335 0.031336 -0.05800500000000006 -0.058579 0.024501 -0.05800500000000006 -0.053335 0.031336 -0.01374800000000006 0.000279519 0.0102152 -0.05800500000000006 0.000433002 0.009889 -0.05800500000000006 0.000432999 0.00988901 -0.143005 -0.061028 0.00677597 -0.05800500000000006 -0.0620423 0.00410213 -0.05798660000000005 -0.063 0.008000999999999999 -0.05800500000000006 -0.03 0.041001 0.01825699999999994 -0.012884 0.041001 0.03253699999999995 -0.00438699 0.041001 0.03471899999999994 0.001936 0.00201001 -0.143005 0.00146417 -0.005499 -0.05951950000000006 0.00146423 -0.00549899 -0.143005 -0.035351 -0.024999 0.01091799999999995 -0.036226 -0.024999 -0.007533000000000055 -0.036914 -0.024999 0.002519999999999945 0.016861 0.037001 -0.03067600000000005 0.023959 0.041001 -0.02551900000000006 0.023959 0.037001 -0.02551900000000006 -0.008095 0.023328 -0.05800500000000006 -0.008386640000000001 0.0235399 -0.05800500000000006 0.003 0.041001 -0.05800500000000006 -0.060434 0.009889 -0.143005 -0.037959 0.030995 -0.143005 -0.061938 0.00201 -0.143005 -0.060434 0.00988996 -0.05800500000000006 -0.0605016 0.00953584 -0.05800500000000006 -0.063 0.008000999999999999 -0.05800500000000006 0.031669 0.037001 0.01489699999999995 0.031669 0.041001 0.01489699999999995 0.026968 0.041001 0.02230499999999994 -0.018664 -0.024999 0.02720999999999995 -0.028282 -0.032999 0.02061499999999995 -0.018664 -0.032999 0.02720999999999995 -0.0457077 0.0278311 -0.05800500000000006 -0.051906 0.023328 -0.143005 -0.0484936 0.0258071 -0.05800500000000006 -0.0605016 0.00953584 -0.05800500000000006 -0.060434 0.009889 -0.143005 -0.061938 0.00201 -0.143005 -0.037959 0.030995 -0.143005 -0.057019 0.017147 -0.143005 -0.051906 0.023328 -0.143005 0.008704 0.041001 -0.03390500000000005 0.016861 0.041001 -0.03067600000000005 0.008704 0.037001 -0.03390500000000005 -0.015898 -0.024999 0.02891299999999995 -0.008206990000000001 -0.024999 0.03195799999999994 0.008207010000000001 -0.024999 0.03195799999999994 -0.050164 -0.032999 -0.009398000000000056 -0.050164 -0.032999 -0.05800500000000006 -0.045857 -0.032999 -0.03370150000000006 -0.058933 0.006022 -0.03700500000000006 -0.058394 0.013901 -0.03700500000000006 -0.058933 0.006022 -0.02142600000000006 0.020572 0.041001 0.02830999999999994 0.020572 0.037001 0.02830999999999994 0.026968 0.037001 0.02230499999999994 -0.03 0.041001 -0.05800500000000006 -0.03 0.041001 0.01825699999999994 0.003 0.041001 -0.05800500000000006 -0.022043 0.030995 -0.143005 -0.0149192 0.0281757 -0.05800500000000006 -0.014584 0.028042 -0.143005 0.03438 0.041001 0.006552989999999944 0.034931 0.037001 -0.002203010000000056 0.034931 0.041001 -0.002203010000000056 0.00146417 -0.005499 -0.05800500000000006 0.001936 0.00201 -0.05800500000000006 0.003 -0.005499 -0.05800500000000006 0.02259 -0.032999 0.02405099999999994 0.015898 -0.032999 0.02891299999999995 -0.018664 -0.032999 0.02720999999999995 -0.050164 -0.0287943 -0.02680210000000005 -0.051233 -0.0281445 -0.03516800000000005 -0.050164 -0.0287944 -0.03245900000000006 -0.050164 -0.0287943 -0.009398550000000056 -0.050164 -0.024999 -0.009399000000000055 -0.052302 -0.027494 -0.01233100000000006 -0.00371071 -0.024999 -0.03700500000000006 6.81479e-09 -0.024999 -0.03700500000000006 -0.037824 0.035926 -0.03700500000000006 -0.039 -0.024999 -0.008965040000000056 -0.039 -0.024999 0.005912989999999944 -0.036914 -0.024999 0.002519999999999945 -0.0585124 0.0139735 -0.05800500000000006 -0.0607562 0.011659 -0.05800500000000006 -0.061876 0.016542 -0.05800500000000006 -0.050164 -0.024999 -0.009399000000000055 -0.048519 -0.022588 -0.007143010000000055 -0.052302 -0.027494 -0.01233100000000006 -0.0521358 0.0230502 -0.05800500000000006 -0.0535363 0.0259051 -0.05800500000000006 -0.051906 0.023328 -0.05800500000000006 0.033287 0.037001 -0.01082100000000006 0.034931 0.037001 -0.002203010000000056 -0.03 0.037001 0.01825699999999994 -0.03 0.041001 0.01825699999999994 0.033287 0.041001 -0.01082100000000006 0.029551 0.041001 -0.01875900000000006 0.00997601 -0.032999 -0.03146100000000006 0.012148 -0.024999 -0.03068800000000006 0.012148 -0.032999 -0.03068800000000006 0.026968 0.037001 0.02230499999999994 0.031669 0.037001 0.01489699999999995 0.026968 0.041001 0.02230499999999994 0.027863 -0.032999 0.01767699999999994 0.02259 -0.032999 0.02405099999999994 -0.028282 -0.032999 0.02061499999999995 -0.018664 -0.024999 0.02720999999999995 0.02259 -0.024999 0.02405099999999994 -0.028282 -0.024999 0.02061499999999995 -0.055749 0.021343 -0.01705900000000006 -0.058579 0.024501 -0.02094100000000006 -0.061876 0.016542 -0.02546300000000006 0.020572 0.041001 0.02830999999999994 -0.03 0.041001 0.01825699999999994 0.012884 0.041001 0.03253699999999995 0.00300001 0.037001 -0.03487600000000005 -0.03 0.037001 0.01825699999999994 0.00300001 0.037001 -0.03700500000000006 -0.061028 0.00677597 -0.05800500000000006 -0.0605016 0.00953584 -0.05800500000000006 -0.061938 0.00201 -0.143005 0.00300001 0.037001 -0.03700500000000006 0.00300001 -0.024999 -0.03700500000000006 0.003 -0.024999 -0.04099300000000006 -0.028281 0.037001 0.02061499999999995 -0.03 0.037001 0.01825699999999994 -0.026968 0.037001 0.02230499999999994 -0.0542666 0.0204743 -0.05800500000000006 -0.0535363 0.0259051 -0.05800500000000006 -0.0521358 0.0230502 -0.05800500000000006 0.027863 -0.032999 0.01767699999999994 0.031385 -0.032999 0.01019299999999995 0.027863 -0.024999 0.01767699999999994 -0.0343095 -0.032999 -0.02389350000000006 -0.04155 -0.032999 -0.01727360000000006 -0.04155 -0.032999 -0.05800500000000006 -0.04155 -0.032999 -0.05800500000000006 -0.04155 -0.032999 -0.01727360000000006 -0.045857 -0.032999 -0.03370150000000006 -0.057316 -0.013033 -0.01920800000000005 -0.062933 -0.006978 -0.02691200000000005 -0.061326 -0.01471 -0.02470800000000006 0.001936 0.00201 -0.05800500000000006 0.00146417 -0.005499 -0.05951950000000006 0.001936 0.00201001 -0.143005 0.031385 -0.024999 0.01019299999999995 0.032935 -0.024999 0.002066989999999944 -0.028282 -0.024999 0.02061499999999995 -0.0211946 -0.024999 -0.008272910000000055 0.00541588 -0.024999 -0.01612550000000006 0.00997601 -0.024999 -0.03146100000000006 -0.051233 -0.0281445 -0.03516800000000005 -0.050164 -0.0287943 -0.02680210000000005 -0.052302 -0.027494 -0.01233100000000006 -0.0571725 0.0168208 -0.05800500000000006 -0.057019 0.017147 -0.05800500000000006 -0.057019 0.017147 -0.143005 0.008207010000000001 -0.032999 0.03195799999999994 0.015898 -0.032999 0.02891299999999995 0.008207010000000001 -0.024999 0.03195799999999994 -0.051233 -0.0281445 -0.03516800000000005 -0.050164 -0.028795 -0.05800500000000006 -0.050164 -0.0287944 -0.03245900000000006 -0.0415231 0.0295844 -0.05800500000000006 -0.0382932 0.0308632 -0.05800500000000006 -0.045417 0.028042 -0.143005 -0.055749 0.021343 -0.01705900000000006 -0.051194 0.027795 -0.03700500000000006 -0.051194 0.027795 -0.01081200000000006 -0.0605016 0.00953584 -0.05800500000000006 -0.060434 0.00988996 -0.05800500000000006 -0.060434 0.009889 -0.143005 -0.045068 0.032779 -0.002410000000000055 -0.037824 0.035926 0.007525989999999944 -0.053335 0.031336 -0.01374800000000006 -0.026968 0.041001 0.02230499999999994 -0.020573 0.037001 0.02831099999999994 -0.020573 0.041001 0.02831099999999994 -0.012884 0.041001 0.03253699999999995 -0.00438699 0.037001 0.03471899999999994 -0.00438699 0.041001 0.03471899999999994 -0.063 0.008000999999999999 -0.02700500000000006 -0.058394 0.013901 -0.02068700000000006 -0.061876 0.016542 -0.02546300000000006 -0.050164 -0.032999 -0.009398000000000056 -0.050164 -0.0287943 -0.02680210000000005 -0.050164 -0.0287944 -0.03245900000000006 -0.028282 -0.032999 0.02061499999999995 0.02259 -0.032999 0.02405099999999994 -0.018664 -0.032999 0.02720999999999995 -0.050164 -0.024999 -0.009399000000000055 -0.0432793 -0.024999 4.394579999994449e-05 -0.028282 -0.024999 0.02061499999999995 -0.0111428 -0.032999 -0.03258800000000005 -0.0280051 -0.032999 -0.02256690000000006 0.003 -0.032999 -0.05800500000000006 0.00376101 -0.032999 -0.03716600000000005 0.005929 -0.024999 -0.03392200000000006 0.005929 -0.032999 -0.03392200000000006 -0.053715 -0.018544 -0.03700500000000006 -0.055749 0.021343 -0.03700500000000006 -0.057316 -0.013033 -0.03700500000000006 0.032415 -0.032999 -0.006189010000000056 0.032935 -0.024999 0.002066989999999944 0.032935 -0.032999 0.002066989999999944 0.033287 0.037001 -0.01082100000000006 -0.03 0.037001 0.01825699999999994 0.029551 0.037001 -0.01875900000000006 -0.0571725 0.0168208 -0.05800500000000006 -0.061876 0.016542 -0.05800500000000006 -0.0580713 0.0192372 -0.05800500000000006 -0.025747 0.0314639 -0.05800500000000006 -0.03 0.041001 -0.05800500000000006 -0.0223997 0.0310412 -0.05800500000000006 -0.053335 0.031336 -0.05800500000000006 -0.0465 0.03658 -0.05800500000000006 -0.0474291 0.0311936 -0.05800500000000006 -0.057692 -0.021723 -0.01972500000000005 -0.052302 -0.027495 -0.05800500000000006 -0.052302 -0.027494 -0.01233100000000006 -0.0605016 0.00953584 -0.05800500000000006 -0.061028 0.00677597 -0.05800500000000006 -0.063 0.008000999999999999 -0.05800500000000006 0.023959 0.037001 -0.02551900000000006 0.029551 0.041001 -0.01875900000000006 0.029551 0.037001 -0.01875900000000006 -0.0147987 -0.00549899 -0.143005 -0.0207863 -0.00549899 -0.143005 -0.037959 0.030995 -0.143005 0.025427 -0.024999 -0.02104000000000006 0.019397 -0.024999 -0.02670300000000006 0.00541588 -0.024999 -0.01612550000000006 0.034931 0.037001 -0.002203010000000056 0.03438 0.041001 0.006552989999999944 0.03438 0.037001 0.006552989999999944 0.00438701 0.037001 0.03471899999999994 0.012884 0.037001 0.03253699999999995 0.00438701 0.041001 0.03471899999999994 0.000903742 -0.00549899 -0.143005 0.001936 0.00201001 -0.143005 0.00146423 -0.00549899 -0.143005 -0.03 0.041001 -0.05800500000000006 0.003 0.041001 -0.05800500000000006 -0.022042 0.030996 -0.05800500000000006 -0.037824 0.035926 0.007525989999999944 -0.045068 0.032779 -0.002410000000000055 -0.037824 0.035926 -0.03700500000000006 -0.045068 0.032779 -0.03700500000000006 -0.051194 0.027795 -0.03700500000000006 -0.048519 -0.022588 -0.03700500000000006 0.00376101 -0.024999 -0.03716600000000005 0.00376101 -0.032999 -0.03716600000000005 0.003 -0.032999 -0.04099300000000006 0.015898 -0.024999 0.02891299999999995 -0.015898 -0.024999 0.02891299999999995 0.008207010000000001 -0.024999 0.03195799999999994 -0.014584 0.028042 -0.143005 -0.008095 0.023328 -0.143005 -0.037959 0.030995 -0.143005 -0.03 0.041001 0.01825699999999994 0.034931 0.041001 -0.002203010000000056 0.033287 0.041001 -0.01082100000000006 0.000903742 -0.00549899 -0.143005 -0.00367516 -0.00549899 -0.143005 -0.037959 0.030995 -0.143005 -0.055749 0.021343 -0.01705900000000006 -0.051194 0.027795 -0.01081200000000006 -0.058579 0.024501 -0.02094100000000006 -0.030001 0.032001 -0.143005 -0.037959 0.030995 -0.143005 -0.0303577 0.0319558 -0.05800500000000006 -0.0623139 0.000841381 -0.02690510000000006 -0.0630566 0.000834875 -0.05796500000000006 -0.0629566 -0.00547481 -0.05799990000000006 -0.053335 0.031336 -0.05800500000000006 -0.0465 0.03658 -0.004374010000000056 -0.0465 0.03658 -0.05800500000000006 -0.0032118 0.0174248 -0.05800500000000006 -0.008095 0.023328 -0.05800500000000006 0.003 0.041001 -0.05800500000000006 -0.048519 -0.022588 -0.007143010000000055 -0.053715 -0.018544 -0.01426900000000006 -0.057692 -0.021723 -0.01972500000000005 0.019397 -0.032999 -0.02670300000000006 0.025427 -0.024999 -0.02104000000000006 0.025427 -0.032999 -0.02104000000000006 6.81479e-09 -0.024999 -0.03700500000000006 -0.03 0.037001 -0.03700500000000006 -0.037824 0.035926 -0.03700500000000006 -0.0308565 -0.024999 -0.008648480000000056 -0.036226 -0.024999 -0.007533000000000055 -0.035351 -0.024999 0.01091799999999995 -0.025747 0.0314639 -0.05800500000000006 -0.032144 0.0362324 -0.05800500000000006 -0.03 0.041001 -0.05800500000000006 -0.0343095 -0.032999 -0.02389350000000006 -0.0412745 -0.032999 -0.05800500000000006 0.003 -0.032999 -0.05800500000000006 -0.051194 0.027795 -0.01081200000000006 -0.053335 0.031336 -0.01374800000000006 -0.058579 0.024501 -0.02094100000000006 0.003 -0.0259881 -0.05590170000000005 0.003 -0.024999 -0.05800500000000006 0.003 -0.024999 -0.05560500000000006 -0.030001 0.032001 -0.143005 -0.022043 0.030995 -0.143005 -0.037959 0.030995 -0.143005 -0.0630566 0.000834875 -0.05796500000000006 -0.0618235 0.000203272 -0.05796570000000006 -0.0614652 -0.005499 -0.05800500000000006 -0.035351 -0.024999 0.01091799999999995 -0.039 -0.024999 0.005912989999999944 -0.028282 -0.024999 0.02061499999999995 0.003 -0.0259881 -0.05590170000000005 0.003 -0.032999 -0.04099300000000006 0.003 -0.032999 -0.05800500000000006 -0.050164 -0.024999 -0.009399000000000055 -0.0432793 -0.024999 4.394579999994449e-05 -0.048519 -0.022588 -0.007143010000000055 -0.002982 0.017147 -0.05800500000000006 -0.0032118 0.0174248 -0.05800500000000006 0.003 0.041001 -0.05800500000000006 -0.0465 0.03658 -0.004374010000000056 -0.038541 0.039877 0.006542989999999945 -0.0465 0.03658 -0.05800500000000006 -0.038541 0.039877 -0.05800500000000006 -0.0401397 0.0347307 -0.05800500000000006 -0.0465 0.03658 -0.05800500000000006 -0.020573 0.037001 0.02831099999999994 -0.026968 0.041001 0.02230499999999994 -0.026968 0.037001 0.02230499999999994 -0.061876 0.016542 -0.05800500000000006 -0.063 0.008000999999999999 -0.05800500000000006 -0.061876 0.016542 -0.02546300000000006 -0.061326 -0.01471 -0.05800500000000006 -0.057693 -0.021723 -0.05800500000000006 -0.061326 -0.01471 -0.02470800000000006 -0.058933 0.006022 -0.03700500000000006 -0.0596031 0.000297668 -0.02136220000000006 -0.058388 -8.89978e-05 -0.03700500000000006 -0.052302 -0.027495 -0.05800500000000006 -0.051233 -0.0281445 -0.03516800000000005 -0.052302 -0.027494 -0.01233100000000006 -0.061937 0.00201 -0.05797540000000006 -0.0619146 0.00165306 -0.05797350000000005 -0.0630566 0.000834875 -0.05796500000000006 -0.060434 0.009889 -0.143005 -0.057019 0.017147 -0.143005 -0.037959 0.030995 -0.143005 -0.03 0.037001 0.01825699999999994 0.008704 0.037001 -0.03390500000000005 0.016861 0.037001 -0.03067600000000005 -0.061326 -0.01471 -0.05800500000000006 -0.062933 -0.006978 -0.02691200000000005 -0.062933 -0.006978 -0.05800500000000006 0.027863 -0.032999 0.01767699999999994 0.02259 -0.024999 0.02405099999999994 0.02259 -0.032999 0.02405099999999994 0.008704 0.037001 -0.03390500000000005 -0.03 0.037001 0.01825699999999994 0.00300001 0.037001 -0.03487600000000005 0.00438701 0.041001 0.03471899999999994 -0.03 0.041001 0.01825699999999994 -0.00438699 0.041001 0.03471899999999994 0.00560997 -0.032999 -0.01012250000000006 0.032415 -0.032999 -0.006189010000000056 -0.0211951 -0.032999 -0.008272280000000055 -0.014584 0.028043 -0.05800500000000006 -0.0149192 0.0281757 -0.05800500000000006 0.003 0.041001 -0.05800500000000006 -0.0619146 0.00165306 -0.05797350000000005 -0.0617011 -0.00174447 -0.1004890000000001 -0.0614652 -0.005499 -0.1374900000000001 -0.0617011 -0.00174447 -0.1004890000000001 -0.061938 0.00201 -0.143005 -0.0614652 -0.005499 -0.1374900000000001 -0.039 -0.024999 0.005912989999999944 -0.0432793 -0.024999 4.394579999994449e-05 -0.028282 -0.024999 0.02061499999999995 -0.057019 0.017147 -0.143005 -0.0521358 0.0230502 -0.05800500000000006 -0.051906 0.023328 -0.143005 -0.048519 -0.022588 -0.03700500000000006 -0.042292 -0.024726 0.001397999999999944 -0.042292 -0.024726 -0.03700500000000006 -0.039 -0.024999 0.005912989999999944 -0.039 -0.024999 -0.008965040000000056 -0.042292 -0.024726 -0.03700500000000006 0.012884 0.037001 0.03253699999999995 0.00438701 0.037001 0.03471899999999994 -0.03 0.037001 0.01825699999999994 -0.00371071 -0.024999 -0.03700500000000006 -0.0211946 -0.024999 -0.008272910000000055 6.81479e-09 -0.024999 -0.03700500000000006 -0.008386640000000001 0.0235399 -0.05800500000000006 -0.014584 0.028043 -0.05800500000000006 0.003 0.041001 -0.05800500000000006 0.005929 -0.032999 -0.03392200000000006 0.00444089 -0.032999 -0.02063940000000005 -0.0211951 -0.032999 -0.008272280000000055 0.00560997 -0.032999 -0.01012250000000006 -0.0211951 -0.032999 -0.008272280000000055 0.00541564 -0.032999 -0.01612520000000005 0.003 0.041001 -0.05800500000000006 -0.0149192 0.0281757 -0.05800500000000006 -0.022042 0.030996 -0.05800500000000006 -0.058932 -0.00665 -0.03700500000000006 -0.057316 -0.013033 -0.01920800000000005 -0.057316 -0.013033 -0.03700500000000006 0.000432999 0.00988901 -0.143005 0.000433002 0.009889 -0.05800500000000006 0.00186845 0.00236411 -0.05800500000000006 -0.052302 -0.027495 -0.05800500000000006 -0.050164 -0.028795 -0.05800500000000006 -0.051233 -0.0281445 -0.03516800000000005 0.003 -0.024999 -0.05560500000000006 0.003 -0.024999 -0.05800500000000006 0.003 -0.008739480000000001 -0.05800500000000006 -0.061876 0.016542 -0.05800500000000006 -0.0607562 0.011659 -0.05800500000000006 -0.063 0.008000999999999999 -0.05800500000000006 -0.03 0.037001 0.01825699999999994 0.03438 0.037001 0.006552989999999944 0.031669 0.037001 0.01489699999999995 -0.03 0.037001 0.01825699999999994 0.031669 0.037001 0.01489699999999995 0.026968 0.037001 0.02230499999999994 -0.055749 0.021343 -0.03700500000000006 -0.058388 -8.89978e-05 -0.03700500000000006 -0.057316 -0.013033 -0.03700500000000006 0.025427 -0.024999 -0.02104000000000006 0.029859 -0.024999 -0.01405600000000006 0.025427 -0.032999 -0.02104000000000006 -0.0415231 0.0295844 -0.05800500000000006 -0.045416 0.028043 -0.05800500000000006 -0.0474291 0.0311936 -0.05800500000000006 -0.050164 -0.024999 -0.009399000000000055 -0.050164 -0.0287943 -0.009398550000000056 -0.0471991 -0.0260829 -0.005332310000000055 -0.0280051 -0.032999 -0.02256690000000006 -0.0343095 -0.032999 -0.02389350000000006 0.003 -0.032999 -0.05800500000000006 -0.008206990000000001 -0.032999 0.03195799999999994 9.071820000000001e-09 -0.032999 0.03299499999999994 -0.008206990000000001 -0.024999 0.03195799999999994 -0.0630566 0.000834875 -0.05796500000000006 -0.0619146 0.00165306 -0.05797350000000005 -0.0618235 0.000203272 -0.05796570000000006 -0.03 0.037001 0.01825699999999994 -0.0465 0.03658 -0.004374010000000056 -0.037824 0.035926 0.007525989999999944 -0.039 -0.024999 0.005912989999999944 -0.035351 -0.024999 0.01091799999999995 -0.036914 -0.024999 0.002519999999999945 0.003 -0.024999 -0.04099300000000006 0.003 -0.0259881 -0.05590170000000005 0.003 -0.024999 -0.05560500000000006 -0.0382932 0.0308632 -0.05800500000000006 -0.037958 0.030996 -0.05800500000000006 -0.037959 0.030995 -0.143005 -0.039 -0.024999 -0.008965040000000056 -0.039 -0.024999 -0.03700500000000006 -0.042292 -0.024726 -0.03700500000000006 -0.048519 -0.022588 -0.007143010000000055 -0.057692 -0.021723 -0.01972500000000005 -0.052302 -0.027494 -0.01233100000000006 -0.042292 -0.024726 0.001397999999999944 -0.039 -0.024999 0.005912989999999944 -0.042292 -0.024726 -0.03700500000000006 -0.0619146 0.00165306 -0.05797350000000005 -0.061937 0.00201 -0.05797540000000006 -0.0617011 -0.00174447 -0.1004890000000001 -0.028282 -0.032999 0.02061499999999995 -0.018664 -0.024999 0.02720999999999995 -0.028282 -0.024999 0.02061499999999995 -0.037959 0.030995 -0.143005 -0.0551317 -0.005499 -0.143005 -0.0611192 -0.005499 -0.143005 -0.053715 -0.018544 -0.01426900000000006 -0.057316 -0.013033 -0.01920800000000005 -0.061326 -0.01471 -0.02470800000000006 -0.00438699 0.037001 0.03471899999999994 0.00438701 0.037001 0.03471899999999994 -0.00438699 0.041001 0.03471899999999994 -0.057316 -0.013033 -0.01920800000000005 -0.053715 -0.018544 -0.01426900000000006 -0.057316 -0.013033 -0.03700500000000006 0.001936 0.00201 -0.05800500000000006 0.001936 0.00201001 -0.143005 0.00186845 0.00236411 -0.05800500000000006 0.00541588 -0.024999 -0.01612550000000006 -0.0211946 -0.024999 -0.008272910000000055 0.00561021 -0.024999 -0.01012250000000006 0.00376101 -0.032999 -0.03716600000000005 -0.0211951 -0.032999 -0.008272280000000055 -0.0111428 -0.032999 -0.03258800000000005 0.00541588 -0.024999 -0.01612550000000006 0.019397 -0.024999 -0.02670300000000006 0.012148 -0.024999 -0.03068800000000006 0.00444089 -0.032999 -0.02063940000000005 0.00997601 -0.032999 -0.03146100000000006 0.012148 -0.032999 -0.03068800000000006 0.00444089 -0.032999 -0.02063940000000005 0.025427 -0.032999 -0.02104000000000006 0.00541564 -0.032999 -0.01612520000000005 0.032415 -0.024999 -0.006189010000000056 0.029859 -0.024999 -0.01405600000000006 0.00561021 -0.024999 -0.01012250000000006 0.00444089 -0.032999 -0.02063940000000005 0.019397 -0.032999 -0.02670300000000006 0.025427 -0.032999 -0.02104000000000006 0.025427 -0.024999 -0.02104000000000006 0.00541588 -0.024999 -0.01612550000000006 0.029859 -0.024999 -0.01405600000000006 0.00376101 -0.032999 -0.03716600000000005 0.005929 -0.032999 -0.03392200000000006 -0.0211951 -0.032999 -0.008272280000000055 0.005929 -0.024999 -0.03392200000000006 -0.0211946 -0.024999 -0.008272910000000055 0.00997601 -0.024999 -0.03146100000000006 -0.035351 -0.032999 0.01091799999999995 -0.0211951 -0.032999 -0.008272280000000055 -0.028282 -0.032999 0.02061499999999995 0.00034425 -0.032999 -0.03941470000000005 0.00376101 -0.032999 -0.03716600000000005 -0.0111428 -0.032999 -0.03258800000000005 0.00300001 -0.024999 -0.03700500000000006 0.00376101 -0.024999 -0.03716600000000005 0.003 -0.024999 -0.04099300000000006 0.029859 -0.024999 -0.01405600000000006 0.00541588 -0.024999 -0.01612550000000006 0.00561021 -0.024999 -0.01012250000000006 0.00444089 -0.032999 -0.02063940000000005 0.012148 -0.032999 -0.03068800000000006 0.019397 -0.032999 -0.02670300000000006 -0.0211946 -0.024999 -0.008272910000000055 0.032415 -0.024999 -0.006189010000000056 0.00561021 -0.024999 -0.01012250000000006 -0.035351 -0.032999 0.01091799999999995 -0.04155 -0.032999 -0.01727360000000006 -0.0211951 -0.032999 -0.008272280000000055 0.00300001 -0.024999 -0.03700500000000006 0.005929 -0.024999 -0.03392200000000006 0.00376101 -0.024999 -0.03716600000000005 0.00997601 -0.032999 -0.03146100000000006 0.00444089 -0.032999 -0.02063940000000005 0.005929 -0.032999 -0.03392200000000006 0.00541588 -0.024999 -0.01612550000000006 0.012148 -0.024999 -0.03068800000000006 0.00997601 -0.024999 -0.03146100000000006 -0.062933 -0.006978 -0.02691200000000005 -0.057316 -0.013033 -0.01920800000000005 -0.058932 -0.00665 -0.02142500000000006 -0.0596031 0.000297668 -0.02136220000000006 -0.062933 -0.006978 -0.02691200000000005 -0.058932 -0.00665 -0.02142500000000006 -0.0432793 -0.024999 4.394579999994449e-05 -0.042292 -0.024726 0.001397999999999944 -0.048519 -0.022588 -0.007143010000000055 -0.066942 -0.061999 -0.143005 -0.066942 -0.061999 -0.05800500000000006 -0.068915 -0.005499 -0.1530050000000001 -0.0412745 -0.032999 -0.05800500000000006 -0.065 -0.045999 -0.05800500000000006 0.005 -0.045999 -0.05800500000000006 0.004441 -0.061999 -0.09800500000000005 0.006941 -0.061999 -0.143005 0.006941 -0.061999 -0.05800500000000006 -0.068915 -0.005499 -0.1530050000000001 -0.066942 -0.061999 -0.05800500000000006 -0.068914 -0.005499 -0.05800500000000006 -0.068914 -0.005499 -0.05800500000000006 -0.062933 -0.006978 -0.05800500000000006 -0.0629566 -0.00547481 -0.05799990000000006 0.008914 -0.005499 -0.05800500000000006 0.00146417 -0.005499 -0.05951950000000006 0.003 -0.005499 -0.05800500000000006 0.008914 -0.00549899 -0.1530050000000001 0.008914 -0.005499 -0.05800500000000006 0.006941 -0.061999 -0.05800500000000006 -0.065 -0.045999 -0.05800500000000006 -0.04155 -0.032999 -0.05800500000000006 -0.050164 -0.032999 -0.05800500000000006 0.004441 -0.061999 -0.05800500000000006 0.004441 -0.061999 -0.09800500000000005 0.006941 -0.061999 -0.05800500000000006 -0.068915 -0.005499 -0.1530050000000001 -0.0551317 -0.005499 -0.143005 -0.0498164 -0.005499 -0.143005 -0.065 -0.045999 -0.05800500000000006 -0.0412745 -0.032999 -0.05800500000000006 -0.04155 -0.032999 -0.05800500000000006 -0.0356626 -0.005499 -0.143005 -0.0309972 -0.005499 -0.143005 0.004 -0.00549899 -0.1530050000000001 0.008914 -0.005499 -0.05800500000000006 0.003 -0.032999 -0.05800500000000006 0.005 -0.045999 -0.05800500000000006 -0.066942 -0.061999 -0.05800500000000006 -0.066942 -0.061999 -0.143005 -0.064442 -0.061999 -0.09800500000000005 -0.064442 -0.061999 -0.09800500000000005 -0.066942 -0.061999 -0.143005 0.006941 -0.061999 -0.143005 0.005 -0.045999 -0.05800500000000006 0.004441 -0.061999 -0.05800500000000006 0.006941 -0.061999 -0.05800500000000006 -0.061326 -0.01471 -0.05800500000000006 -0.062933 -0.006978 -0.05800500000000006 -0.068914 -0.005499 -0.05800500000000006 -0.064442 -0.061999 -0.05800500000000006 -0.066942 -0.061999 -0.05800500000000006 -0.064442 -0.061999 -0.09800500000000005 0.004 -0.00549899 -0.1530050000000001 -0.066942 -0.061999 -0.143005 -0.068915 -0.005499 -0.1530050000000001 -0.066942 -0.061999 -0.05800500000000006 -0.065 -0.045999 -0.05800500000000006 -0.068914 -0.005499 -0.05800500000000006 -0.065 -0.045999 -0.05800500000000006 -0.061326 -0.01471 -0.05800500000000006 -0.068914 -0.005499 -0.05800500000000006 -0.0614652 -0.005499 -0.143005 -0.068915 -0.005499 -0.1530050000000001 -0.0614652 -0.005499 -0.1374900000000001 -0.0309972 -0.005499 -0.143005 -0.0261013 -0.00549899 -0.143005 0.004 -0.00549899 -0.1530050000000001 -0.068915 -0.005499 -0.1530050000000001 -0.0498164 -0.005499 -0.143005 -0.0449206 -0.005499 -0.143005 -0.0147987 -0.00549899 -0.143005 -0.00776776 -0.00549899 -0.143005 0.004 -0.00549899 -0.1530050000000001 -0.052302 -0.027495 -0.05800500000000006 -0.065 -0.045999 -0.05800500000000006 -0.050164 -0.032999 -0.05800500000000006 -0.0402551 -0.005499 -0.143005 -0.0356626 -0.005499 -0.143005 0.004 -0.00549899 -0.1530050000000001 -0.064442 -0.061999 -0.05800500000000006 -0.065 -0.045999 -0.05800500000000006 -0.066942 -0.061999 -0.05800500000000006 0.003 -0.024999 -0.05800500000000006 0.008914 -0.005499 -0.05800500000000006 0.003 -0.008739480000000001 -0.05800500000000006 -0.068915 -0.005499 -0.1530050000000001 -0.0614652 -0.005499 -0.143005 -0.0611192 -0.005499 -0.143005 0.003 -0.032999 -0.05800500000000006 0.008914 -0.005499 -0.05800500000000006 0.003 -0.024999 -0.05800500000000006 0.008914 -0.005499 -0.05800500000000006 0.008914 -0.00549899 -0.1530050000000001 0.004 -0.00549899 -0.1530050000000001 0.006941 -0.061999 -0.143005 0.008914 -0.00549899 -0.1530050000000001 0.006941 -0.061999 -0.05800500000000006 0.004441 -0.061999 -0.09800500000000005 -0.064442 -0.061999 -0.09800500000000005 0.006941 -0.061999 -0.143005 0.00146423 -0.00549899 -0.143005 0.00146417 -0.005499 -0.05951950000000006 0.008914 -0.005499 -0.05800500000000006 -0.0551317 -0.005499 -0.143005 -0.068915 -0.005499 -0.1530050000000001 -0.0611192 -0.005499 -0.143005 -0.0402551 -0.005499 -0.143005 0.004 -0.00549899 -0.1530050000000001 -0.068915 -0.005499 -0.1530050000000001 -0.052302 -0.027495 -0.05800500000000006 -0.057693 -0.021723 -0.05800500000000006 -0.065 -0.045999 -0.05800500000000006 -0.00776776 -0.00549899 -0.143005 -0.00367516 -0.00549899 -0.143005 0.004 -0.00549899 -0.1530050000000001 0.003 -0.032999 -0.05800500000000006 -0.0412745 -0.032999 -0.05800500000000006 0.005 -0.045999 -0.05800500000000006 -0.066942 -0.061999 -0.143005 0.004 -0.00549899 -0.1530050000000001 0.006941 -0.061999 -0.143005 -0.00367516 -0.00549899 -0.143005 0.000903742 -0.00549899 -0.143005 0.004 -0.00549899 -0.1530050000000001 -0.0261013 -0.00549899 -0.143005 -0.0207863 -0.00549899 -0.143005 0.004 -0.00549899 -0.1530050000000001 0.000903742 -0.00549899 -0.143005 0.00146423 -0.00549899 -0.143005 0.004 -0.00549899 -0.1530050000000001 0.008914 -0.005499 -0.05800500000000006 0.005 -0.045999 -0.05800500000000006 0.006941 -0.061999 -0.05800500000000006 0.004 -0.00549899 -0.1530050000000001 0.008914 -0.00549899 -0.1530050000000001 0.006941 -0.061999 -0.143005 -0.0402551 -0.005499 -0.143005 -0.068915 -0.005499 -0.1530050000000001 -0.0449206 -0.005499 -0.143005 0.00146423 -0.00549899 -0.143005 0.008914 -0.005499 -0.05800500000000006 0.004 -0.00549899 -0.1530050000000001 0.00146417 -0.005499 -0.05951950000000006 0.00146417 -0.005499 -0.05800500000000006 0.003 -0.005499 -0.05800500000000006 -0.0207863 -0.00549899 -0.143005 -0.0147987 -0.00549899 -0.143005 0.004 -0.00549899 -0.1530050000000001 -0.068915 -0.005499 -0.1530050000000001 -0.068914 -0.005499 -0.05800500000000006 -0.0614652 -0.005499 -0.1374900000000001 -0.065 -0.045999 -0.05800500000000006 -0.057693 -0.021723 -0.05800500000000006 -0.061326 -0.01471 -0.05800500000000006 0.008914 -0.005499 -0.05800500000000006 0.003 -0.005499 -0.05800500000000006 0.003 -0.008739480000000001 -0.05800500000000006 -0.068914 -0.005499 -0.05800500000000006 -0.0614652 -0.005499 -0.06771010000000005 -0.0614652 -0.005499 -0.1374900000000001 -0.068914 -0.005499 -0.05800500000000006 -0.0629566 -0.00547481 -0.05799990000000006 -0.0614652 -0.005499 -0.06771010000000005 -0.0614652 -0.005499 -0.06771010000000005 -0.0629566 -0.00547481 -0.05799990000000006 -0.0614652 -0.005499 -0.05800500000000006 0.004441 -0.061999 -0.09800500000000005 -0.063679 -0.08383699999999999 -0.03800500000000005 -0.064442 -0.061999 -0.09800500000000005 -0.06401999999999999 -0.07407 -0.03445000000000006 0.00401901 -0.07407 -0.03445000000000006 0.005 -0.045999 -0.05800500000000006 0.003678 -0.08383699999999999 -0.03800500000000005 -0.063679 -0.08383699999999999 -0.03800500000000005 0.004441 -0.061999 -0.09800500000000005 -0.063679 -0.08383699999999999 -0.03800500000000005 -0.06401999999999999 -0.07407 -0.03445000000000006 -0.064442 -0.061999 -0.05800500000000006 -0.065 -0.045999 -0.05800500000000006 -0.06401999999999999 -0.07407 -0.03445000000000006 0.005 -0.045999 -0.05800500000000006 0.00401901 -0.07407 -0.03445000000000006 0.003678 -0.08383699999999999 -0.03800500000000005 0.004441 -0.061999 -0.05800500000000006 0.003678 -0.08383699999999999 -0.03800500000000005 0.004441 -0.061999 -0.09800500000000005 0.004441 -0.061999 -0.05800500000000006 -0.06401999999999999 -0.07407 -0.03445000000000006 -0.065 -0.045999 -0.05800500000000006 -0.064442 -0.061999 -0.05800500000000006 0.00401901 -0.07407 -0.03445000000000006 0.004441 -0.061999 -0.05800500000000006 0.005 -0.045999 -0.05800500000000006 -0.063679 -0.08383699999999999 -0.03800500000000005 0.003678 -0.08383699999999999 -0.03800500000000005 0.00401901 -0.07407 -0.03445000000000006 -0.063679 -0.08383699999999999 -0.03800500000000005 -0.064442 -0.061999 -0.05800500000000006 -0.064442 -0.061999 -0.09800500000000005 -0.06401999999999999 -0.07407 -0.03445000000000006 -0.063679 -0.08383699999999999 -0.03800500000000005 0.00401901 -0.07407 -0.03445000000000006 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583

    -
    -
    - - - 0 0 -5.551115123125783e-17 - 1 0 0 0 - - true - - - -
    - - - - 0.016497 -0.023 -0.221995 -0.006485 -0.023 -0.254967 3.99838e-06 -0.023 -0.255995 0.016497 -0.023 -0.221995 -0.012339 -0.023 -0.251984 -0.006485 -0.023 -0.254967 0.016497 -0.023 -0.221995 3.99838e-06 -0.023 -0.255995 0.006493 -0.023 -0.254967 -0.006485 -0.023 -0.254967 -0.000701329 0.018 -0.255883 3.99838e-06 -0.023 -0.255995 -0.000701329 0.018 -0.255883 3.99658e-06 0.018 -0.255995 3.99838e-06 -0.023 -0.255995 0.016497 -0.023 -0.221995 -0.016985 -0.023 -0.247338 -0.012339 -0.023 -0.251984 -0.012339 -0.023 -0.251984 -0.0071213 0.018 -0.254643 -0.006485 -0.023 -0.254967 -0.0071213 0.018 -0.254643 -0.006485 0.018 -0.254967 -0.006485 -0.023 -0.254967 0.016497 -0.023 -0.221995 0.006493 -0.023 -0.254967 0.012348 -0.023 -0.251984 3.99658e-06 0.018 -0.255995 0.000709323 0.018 -0.255883 3.99838e-06 -0.023 -0.255995 3.99838e-06 -0.023 -0.255995 0.000709323 0.018 -0.255883 0.006493 -0.023 -0.254967 -0.006485 0.018 -0.254967 -0.00252937 0.018 -0.255594 -0.006485 -0.023 -0.254967 -0.00252937 0.018 -0.255594 -0.000701329 0.018 -0.255883 -0.006485 -0.023 -0.254967 -0.019968 -0.023 -0.241484 -0.016985 -0.023 -0.247338 0.016497 -0.023 -0.221995 -0.012339 -0.023 -0.251984 -0.016985 -0.023 -0.247338 -0.012844 0.018 -0.251479 -0.012339 0.018 -0.251984 -0.012339 -0.023 -0.251984 -0.012844 0.018 -0.251479 -0.012339 0.018 -0.251984 -0.008449170000000001 0.018 -0.253966 -0.012339 -0.023 -0.251984 -0.008449170000000001 0.018 -0.253966 -0.0071213 0.018 -0.254643 -0.012339 -0.023 -0.251984 0.016994 -0.023 -0.247338 0.016497 -0.023 -0.221995 0.012348 -0.023 -0.251984 0.00649389 0.018 -0.254967 0.0071303 0.018 -0.254643 0.006493 -0.023 -0.254967 0.006493 -0.023 -0.254967 0.0071303 0.018 -0.254643 0.012348 -0.023 -0.251984 0.000709323 0.018 -0.255883 0.0037358 0.018 -0.255404 0.006493 -0.023 -0.254967 0.0037358 0.018 -0.255404 0.00649389 0.018 -0.254967 0.006493 -0.023 -0.254967 -0.020996 -0.023 -0.234995 -0.019968 -0.023 -0.241484 0.016497 -0.023 -0.221995 -0.016985 -0.023 -0.247338 -0.019968 -0.023 -0.241484 -0.0173092 0.018 -0.246702 -0.016985 0.018 -0.247338 -0.016985 -0.023 -0.247338 -0.0173092 0.018 -0.246702 -0.012844 0.018 -0.251479 -0.016985 -0.023 -0.247338 -0.0135884 0.018 -0.250735 -0.0135884 0.018 -0.250735 -0.016985 -0.023 -0.247338 -0.016985 0.018 -0.247338 0.019976 -0.023 -0.241484 0.016497 -0.023 -0.221995 0.016994 -0.023 -0.247338 0.016994 -0.023 -0.247338 0.012348 -0.023 -0.251984 0.012853 0.018 -0.251479 0.012853 0.018 -0.251479 0.012348 -0.023 -0.251984 0.012348 0.018 -0.251984 0.0071303 0.018 -0.254643 0.00988577 0.018 -0.253239 0.012348 -0.023 -0.251984 0.00988577 0.018 -0.253239 0.012348 0.018 -0.251984 0.012348 -0.023 -0.251984 -0.019968 -0.023 -0.228505 -0.020996 -0.023 -0.234995 0.016497 -0.023 -0.221995 -0.019968 -0.023 -0.241484 -0.020996 -0.023 -0.234995 -0.0200797 0.018 -0.240779 -0.019968 0.018 -0.241484 -0.019968 -0.023 -0.241484 -0.0200797 0.018 -0.240779 -0.0173092 0.018 -0.246702 -0.019968 -0.023 -0.241484 -0.0175653 0.018 -0.246199 -0.0175653 0.018 -0.246199 -0.019968 -0.023 -0.241484 -0.019968 0.018 -0.241484 0.021004 -0.023 -0.234995 0.016497 -0.023 -0.221995 0.019976 -0.023 -0.241484 0.019976 -0.023 -0.241484 0.016994 -0.023 -0.247338 0.0173181 0.018 -0.246702 0.0173181 0.018 -0.246702 0.016994 -0.023 -0.247338 0.016994 0.018 -0.247338 0.016994 0.018 -0.247338 0.016994 -0.023 -0.247338 0.0154937 0.018 -0.248838 0.0154937 0.018 -0.248838 0.016994 -0.023 -0.247338 0.012853 0.018 -0.251479 -0.016985 -0.023 -0.222651 -0.019968 -0.023 -0.228505 0.016497 -0.023 -0.221995 -0.020996 -0.023 -0.234995 -0.019968 -0.023 -0.228505 -0.019968 -0.00648999 -0.228506 -0.020996 7.44684e-09 -0.234995 -0.020996 0.00648901 -0.234995 -0.0200797 0.018 -0.240779 -0.020086 0.018 -0.240739 -0.0200797 0.018 -0.240779 -0.020996 0.012343 -0.234995 -0.0200797 0.018 -0.240779 -0.020996 0.00648901 -0.234995 -0.020996 0.012343 -0.234995 -0.020086 0.018 -0.240739 -0.020996 0.012343 -0.234995 -0.020996 0.016989 -0.234995 -0.020086 0.018 -0.240739 -0.020996 0.016989 -0.234995 -0.020996 0.018 -0.234995 -0.020996 7.44684e-09 -0.234995 -0.0200797 0.018 -0.240779 -0.020996 -0.00648999 -0.234995 -0.0200797 0.018 -0.240779 -0.020996 -0.012344 -0.234995 -0.020996 -0.00648999 -0.234995 -0.0200797 0.018 -0.240779 -0.020996 -0.01699 -0.234995 -0.020996 -0.012344 -0.234995 -0.0200797 0.018 -0.240779 -0.020996 -0.019973 -0.234995 -0.020996 -0.01699 -0.234995 -0.0200797 0.018 -0.240779 -0.020996 -0.023 -0.234995 -0.020996 -0.019973 -0.234995 0.019976 -0.023 -0.228506 0.016497 -0.023 -0.221995 0.021004 -0.023 -0.234995 0.019976 -0.023 -0.241484 0.0200886 0.018 -0.240779 0.021004 -0.023 -0.234995 0.0199769 0.018 -0.241484 0.0200886 0.018 -0.240779 0.019976 -0.023 -0.241484 0.0199769 0.018 -0.241484 0.019976 -0.023 -0.241484 0.0173181 0.018 -0.246702 0.021004 0.018 -0.234995 0.021004 0.016989 -0.234995 0.0209 0.018 -0.235652 0.021004 0.00648901 -0.234995 0.021004 9.28272e-09 -0.234995 0.0200886 0.018 -0.240779 0.021004 0.012343 -0.234995 0.021004 0.00648901 -0.234995 0.0200886 0.018 -0.240779 0.021004 0.016989 -0.234995 0.021004 0.012343 -0.234995 0.0200886 0.018 -0.240779 0.0209 0.018 -0.235652 0.021004 0.016989 -0.234995 0.0200886 0.018 -0.240779 0.0200886 0.018 -0.240779 0.021004 -0.019973 -0.234995 0.021004 -0.023 -0.234995 0.0200886 0.018 -0.240779 0.021004 -0.01699 -0.234995 0.021004 -0.019973 -0.234995 0.0200886 0.018 -0.240779 0.021004 -0.012344 -0.234995 0.021004 -0.01699 -0.234995 0.0200886 0.018 -0.240779 0.021004 -0.00648999 -0.234995 0.021004 -0.012344 -0.234995 0.0200886 0.018 -0.240779 0.021004 9.28272e-09 -0.234995 0.021004 -0.00648999 -0.234995 -0.012339 -0.023 -0.218006 -0.016985 -0.023 -0.222651 0.016497 -0.023 -0.221995 -0.019968 -0.023 -0.228505 -0.016985 -0.023 -0.222651 -0.019968 -0.00648999 -0.228506 -0.020996 7.44684e-09 -0.234995 -0.020996 -0.00648999 -0.234995 -0.019968 -0.00648999 -0.228506 -0.020996 -0.023 -0.234995 -0.019968 -0.00648999 -0.228506 -0.020482 -0.0115 -0.23175 -0.020996 -0.019973 -0.234995 -0.020996 -0.023 -0.234995 -0.020482 -0.0115 -0.23175 -0.020996 -0.01699 -0.234995 -0.020996 -0.019973 -0.234995 -0.020482 -0.0115 -0.23175 -0.020996 -0.012344 -0.234995 -0.020996 -0.01699 -0.234995 -0.020482 -0.0115 -0.23175 -0.020996 -0.00648999 -0.234995 -0.020996 -0.012344 -0.234995 -0.020482 -0.0115 -0.23175 -0.019968 -0.00648999 -0.228506 -0.020996 -0.00648999 -0.234995 -0.020482 -0.0115 -0.23175 -0.020996 0.00648901 -0.234995 -0.020996 7.44684e-09 -0.234995 -0.019968 0.00648901 -0.228506 -0.020996 0.018 -0.234995 -0.020996 0.016989 -0.234995 -0.0209643 0.018 -0.234795 -0.020996 0.016989 -0.234995 -0.020996 0.012343 -0.234995 -0.0206847 0.018 -0.23303 -0.0209643 0.018 -0.234795 -0.020996 0.016989 -0.234995 -0.0206847 0.018 -0.23303 -0.019968 0.00648901 -0.228506 -0.0206847 0.018 -0.23303 -0.020482 0.008999999999999999 -0.23175 -0.020996 0.012343 -0.234995 -0.020996 0.00648901 -0.234995 -0.020482 0.008999999999999999 -0.23175 -0.020996 0.00648901 -0.234995 -0.019968 0.00648901 -0.228506 -0.020482 0.008999999999999999 -0.23175 -0.0206847 0.018 -0.23303 -0.020996 0.012343 -0.234995 -0.020482 0.008999999999999999 -0.23175 0.019976 -0.023 -0.228506 0.016994 -0.023 -0.222651 0.016497 -0.023 -0.221995 0.019976 -0.023 -0.228506 0.021004 -0.023 -0.234995 0.019976 -0.00648999 -0.228506 0.019976 -0.00648999 -0.228506 0.021004 -0.00648999 -0.234995 0.021004 9.28272e-09 -0.234995 0.021004 -0.012344 -0.234995 0.021004 -0.00648999 -0.234995 0.02049 -0.0115 -0.23175 0.021004 -0.01699 -0.234995 0.021004 -0.012344 -0.234995 0.02049 -0.0115 -0.23175 0.021004 -0.019973 -0.234995 0.021004 -0.01699 -0.234995 0.02049 -0.0115 -0.23175 0.021004 -0.023 -0.234995 0.021004 -0.019973 -0.234995 0.02049 -0.0115 -0.23175 0.019976 -0.00648999 -0.228506 0.021004 -0.023 -0.234995 0.02049 -0.0115 -0.23175 0.021004 -0.00648999 -0.234995 0.019976 -0.00648999 -0.228506 0.02049 -0.0115 -0.23175 0.021004 0.00648901 -0.234995 0.021004 0.012343 -0.234995 0.0202003 0.018 -0.229917 0.0202003 0.018 -0.229917 0.021004 0.012343 -0.234995 0.0203537 0.018 -0.230886 0.0203537 0.018 -0.230886 0.021004 0.012343 -0.234995 0.0203885 0.018 -0.231106 0.0203885 0.018 -0.231106 0.021004 0.012343 -0.234995 0.0204413 0.018 -0.23144 0.0204413 0.018 -0.23144 0.021004 0.012343 -0.234995 0.0204951 0.018 -0.23178 0.0204951 0.018 -0.23178 0.021004 0.012343 -0.234995 0.0205521 0.018 -0.23214 0.0205521 0.018 -0.23214 0.021004 0.012343 -0.234995 0.020615 0.018 -0.232537 0.0206874 0.018 -0.232995 0.020615 0.018 -0.232537 0.021004 0.016989 -0.234995 0.0207755 0.018 -0.233551 0.0206874 0.018 -0.232995 0.021004 0.016989 -0.234995 0.020615 0.018 -0.232537 0.021004 0.012343 -0.234995 0.021004 0.016989 -0.234995 0.0207755 0.018 -0.233551 0.021004 0.016989 -0.234995 0.0208896 0.018 -0.234272 0.0208896 0.018 -0.234272 0.021004 0.016989 -0.234995 0.021004 0.018 -0.234995 0.021004 0.00648901 -0.234995 0.0202003 0.018 -0.229917 0.021004 9.28272e-09 -0.234995 -0.006485 -0.023 -0.215023 -0.012339 -0.023 -0.218006 0.016497 -0.023 -0.221995 -0.012339 -0.023 -0.218006 -0.016985 -0.012344 -0.222651 -0.016985 -0.023 -0.222651 -0.019968 -0.00648999 -0.228506 -0.016985 -0.023 -0.222651 -0.016985 -0.012344 -0.222651 -0.019968 -0.00648999 -0.228506 -0.020995 8.25938e-09 -0.144495 -0.020996 7.44684e-09 -0.234995 -0.0206847 0.018 -0.23303 -0.019968 0.00648901 -0.228506 -0.020345 0.018 -0.230886 -0.020345 0.018 -0.230886 -0.019968 0.00648901 -0.228506 -0.019968 0.018 -0.228506 -0.019968 0.00648901 -0.228506 -0.020996 7.44684e-09 -0.234995 -0.019968 0.00648901 -0.144495 0.016497 -0.023 -0.221995 0.016994 -0.023 -0.222651 0.016994 -0.012344 -0.222652 0.016994 -0.023 -0.222651 0.019976 -0.023 -0.228506 0.016994 -0.012344 -0.222652 0.016994 -0.012344 -0.222652 0.019976 -0.023 -0.228506 0.019976 -0.00648999 -0.228506 0.021004 9.28272e-09 -0.234995 0.019977 -0.00648999 -0.144495 0.019976 -0.00648999 -0.228506 0.019977 0.00648901 -0.228506 0.021004 9.28272e-09 -0.234995 0.0202003 0.018 -0.229917 0.019977 0.018 -0.228506 0.019977 0.00648901 -0.228506 0.0202003 0.018 -0.229917 4.00022e-06 -0.023 -0.213995 -0.006485 -0.023 -0.215023 0.016497 -0.023 -0.221995 -0.006485 -0.023 -0.215023 -0.012339 -0.01699 -0.218006 -0.012339 -0.023 -0.218006 -0.012339 -0.01699 -0.218006 -0.016985 -0.012344 -0.222651 -0.012339 -0.023 -0.218006 -0.016985 -0.012344 -0.222651 -0.0186889 -0.008999989999999999 -0.21327 -0.019968 -0.00648999 -0.228506 -0.0173466 -0.0116343 -0.213178 -0.0186889 -0.008999989999999999 -0.21327 -0.016985 -0.012344 -0.222651 -0.0186887 -0.008999989999999999 -0.178013 -0.019968 -0.00648899 -0.144495 -0.0186889 -0.008999989999999999 -0.21327 -0.0186889 -0.008999989999999999 -0.21327 -0.019968 -0.00648899 -0.144495 -0.019968 -0.00648999 -0.228506 -0.019968 0.00648901 -0.144495 -0.020996 7.44684e-09 -0.234995 -0.020995 8.25938e-09 -0.144495 -0.020995 8.25938e-09 -0.144495 -0.019968 -0.00648999 -0.228506 -0.019968 -0.00648899 -0.144495 -0.019968 0.00648901 -0.228506 -0.0184765 0.0122445 -0.225579 -0.019968 0.018 -0.228506 -0.016985 0.012343 -0.222652 -0.0184765 0.0122445 -0.225579 -0.019968 0.00648901 -0.228506 -0.0185684 0.018 -0.225759 -0.0184765 0.0122445 -0.225579 -0.016985 0.012343 -0.222652 -0.019968 0.018 -0.228506 -0.0184765 0.0122445 -0.225579 -0.0185684 0.018 -0.225759 -0.016985 0.012343 -0.144495 -0.019968 0.00648901 -0.228506 -0.019968 0.00648901 -0.144495 0.016497 -0.023 -0.221995 0.016994 -0.012344 -0.222652 0.0146947 -0.017672 -0.220305 0.012348 -0.01699 -0.218006 0.016497 -0.023 -0.221995 0.0146947 -0.017672 -0.220305 0.016994 -0.012344 -0.222652 0.012348 -0.01699 -0.218006 0.0146947 -0.017672 -0.220305 0.016994 -0.012344 -0.222652 0.019976 -0.00648999 -0.228506 0.0186974 -0.008999989999999999 -0.21327 0.016994 -0.012344 -0.213153 0.016994 -0.012344 -0.222652 0.0186974 -0.008999989999999999 -0.21327 0.0186974 -0.008999989999999999 -0.206372 0.019976 -0.00648999 -0.228506 0.0186974 -0.008999989999999999 -0.192485 0.0186974 -0.008999989999999999 -0.206372 0.0186974 -0.008999989999999999 -0.21327 0.019976 -0.00648999 -0.228506 0.0171477 -0.0120422 -0.148826 0.0186979 -0.008999989999999999 -0.14872 0.016994 -0.012344 -0.144495 0.0186979 -0.008999989999999999 -0.14872 0.0186974 -0.008999989999999999 -0.192485 0.019977 -0.00648999 -0.144495 0.016994 -0.012344 -0.144495 0.0186979 -0.008999989999999999 -0.14872 0.019977 -0.00648999 -0.144495 0.019977 -0.00648999 -0.144495 0.0186974 -0.008999989999999999 -0.192485 0.019976 -0.00648999 -0.228506 0.021004 1.00952e-08 -0.144495 0.019977 -0.00648999 -0.144495 0.021004 9.28272e-09 -0.234995 0.021004 9.28272e-09 -0.234995 0.019977 0.00648901 -0.228506 0.021004 1.00952e-08 -0.144495 0.0178973 0.018 -0.224425 0.019977 0.00648901 -0.228506 0.018835 0.018 -0.226265 0.018835 0.018 -0.226265 0.019977 0.00648901 -0.228506 0.0191898 0.018 -0.226961 0.0191898 0.018 -0.226961 0.019977 0.00648901 -0.228506 0.019977 0.018 -0.228506 0.006494 -0.023 -0.215023 4.00022e-06 -0.023 -0.213995 0.016497 -0.023 -0.221995 4.00022e-06 -0.023 -0.213995 -0.006485 -0.019973 -0.215023 -0.006485 -0.023 -0.215023 -0.006485 -0.023 -0.215023 -0.006485 -0.019973 -0.215023 -0.012339 -0.01699 -0.218006 -0.0126553 -0.0166737 -0.213002 -0.016985 -0.012344 -0.213153 -0.014662 -0.014667 -0.217826 -0.012339 -0.01699 -0.218006 -0.0126553 -0.0166737 -0.213002 -0.014662 -0.014667 -0.217826 -0.016985 -0.012344 -0.222651 -0.012339 -0.01699 -0.218006 -0.014662 -0.014667 -0.217826 -0.016985 -0.012344 -0.213153 -0.016985 -0.012344 -0.222651 -0.014662 -0.014667 -0.217826 -0.0186887 -0.008999989999999999 -0.155618 -0.0186887 -0.008999989999999999 -0.14872 -0.019968 -0.00648899 -0.144495 -0.0186887 -0.008999989999999999 -0.14872 -0.016985 -0.012344 -0.148837 -0.016985 -0.012344 -0.144495 -0.019968 -0.00648899 -0.144495 -0.0186887 -0.008999989999999999 -0.14872 -0.016985 -0.012344 -0.144495 -0.0186887 -0.008999989999999999 -0.178013 -0.0186887 -0.008999989999999999 -0.155618 -0.019968 -0.00648899 -0.144495 -0.0173466 -0.0116343 -0.213178 -0.016985 -0.012344 -0.222651 -0.016985 -0.012344 -0.213153 -0.019968 0.00648901 -0.144495 -0.020995 8.25938e-09 -0.144495 -0.021156 0.029125 -0.144495 -0.019968 -0.00648899 -0.144495 -0.017339 -0.031547 -0.144495 -0.020995 8.25938e-09 -0.144495 -0.010355 0.018 -0.216995 -0.012339 0.018 -0.218006 -0.012339 0.016989 -0.218006 -0.0131204 0.018 -0.218787 -0.012339 0.016989 -0.218006 -0.012339 0.018 -0.218006 -0.012339 0.016989 -0.218006 -0.0131204 0.018 -0.218787 -0.014662 0.0151715 -0.220329 -0.016985 0.012343 -0.222652 -0.012339 0.016989 -0.218006 -0.014662 0.0151715 -0.220329 -0.016985 0.018 -0.222652 -0.016985 0.012343 -0.222652 -0.014662 0.0151715 -0.220329 -0.0131204 0.018 -0.218787 -0.016985 0.018 -0.222652 -0.014662 0.0151715 -0.220329 -0.0185684 0.018 -0.225759 -0.016985 0.012343 -0.222652 -0.016985 0.018 -0.222652 -0.012339 0.016989 -0.218006 -0.010355 0.018 -0.195314 -0.010355 0.018 -0.216995 -0.010355 0.018 -0.195314 -0.012339 0.016989 -0.218006 -0.010355 0.018 -0.193092 -0.016985 0.012343 -0.222652 -0.019968 0.00648901 -0.228506 -0.016985 0.012343 -0.144495 -0.016985 0.012343 -0.144495 -0.019968 0.00648901 -0.144495 -0.013248 0.033472 -0.144495 0.016497 -0.023 -0.221995 0.012348 -0.01699 -0.218006 0.012348 -0.023 -0.218006 0.0164282 -0.0129098 -0.213133 0.012348 -0.01699 -0.212991 0.014671 -0.014667 -0.217821 0.016994 -0.012344 -0.222652 0.0164282 -0.0129098 -0.213133 0.014671 -0.014667 -0.217821 0.012348 -0.01699 -0.218006 0.016994 -0.012344 -0.222652 0.014671 -0.014667 -0.217821 0.012348 -0.01699 -0.212991 0.012348 -0.01699 -0.218006 0.014671 -0.014667 -0.217821 0.0164282 -0.0129098 -0.213133 0.016994 -0.012344 -0.222652 0.016994 -0.012344 -0.213153 0.016994 -0.012344 -0.148837 0.0171477 -0.0120422 -0.148826 0.016994 -0.012344 -0.144495 0.017347 -0.031547 -0.144495 0.016994 -0.012344 -0.144495 0.019977 -0.00648999 -0.144495 0.021004 1.00952e-08 -0.144495 0.024648 -0.026243 -0.144495 0.019977 -0.00648999 -0.144495 0.021004 1.00952e-08 -0.144495 0.019977 0.00648901 -0.228506 0.019977 0.00648901 -0.144495 0.016994 0.018 -0.222652 0.016994 0.012343 -0.222652 0.0174398 0.018 -0.223527 0.016994 0.012343 -0.222652 0.019977 0.00648901 -0.228506 0.0178973 0.018 -0.224425 0.0174398 0.018 -0.223527 0.016994 0.012343 -0.222652 0.0178973 0.018 -0.224425 0.012348 -0.023 -0.218006 0.006494 -0.023 -0.215023 0.016497 -0.023 -0.221995 0.006494 -0.023 -0.215023 4.00013e-06 -0.021 -0.213995 4.00022e-06 -0.023 -0.213995 4.00022e-06 -0.023 -0.213995 4.00013e-06 -0.021 -0.213995 -0.006485 -0.019973 -0.215023 -0.006485 -0.019973 -0.215023 -0.00666206 -0.0198828 -0.21289 -0.012339 -0.01699 -0.212991 -0.006485 -0.019973 -0.215023 -0.012339 -0.01699 -0.212991 -0.012339 -0.01699 -0.218006 -0.0126553 -0.0166737 -0.213002 -0.012339 -0.01699 -0.218006 -0.012339 -0.01699 -0.212991 -0.017339 -0.031547 -0.144495 -0.019968 -0.00648899 -0.144495 -0.016985 -0.012344 -0.144495 -0.016985 -0.012344 -0.148837 -0.01671 -0.012619 -0.148846 -0.016985 -0.012344 -0.144495 -0.00666206 -0.0198828 -0.21289 -0.006485 -0.019973 -0.215023 -0.006485 -0.019973 -0.212887 0.012348 -0.01699 -0.212991 0.0119481 -0.0171937 -0.212984 0.012348 -0.01699 -0.218006 -0.006485 -0.019973 -0.212887 -0.00324058 -0.0204865 -0.213937 -0.000102773 -0.0209831 -0.212851 -0.006485 -0.019973 -0.215023 -0.00324058 -0.0204865 -0.213937 -0.006485 -0.019973 -0.212887 4.00013e-06 -0.021 -0.213995 -0.00324058 -0.0204865 -0.213937 -0.006485 -0.019973 -0.215023 -0.000102773 -0.0209831 -0.212851 -0.00324058 -0.0204865 -0.213937 4.00013e-06 -0.021 -0.213995 0.006494 -0.019973 -0.215023 0.0119481 -0.0171937 -0.212984 0.006494 -0.019973 -0.212887 0.006494 -0.019973 -0.215023 0.012348 -0.01699 -0.218006 0.0119481 -0.0171937 -0.212984 -0.000102773 -0.0209831 -0.212851 4.00013e-06 -0.021 -0.213995 4.00018e-06 -0.021 -0.212851 0.00629732 -0.0200041 -0.212886 0.006494 -0.019973 -0.215023 0.006494 -0.019973 -0.212887 4.00018e-06 -0.021 -0.212851 0.003249 -0.0204865 -0.213937 0.00629732 -0.0200041 -0.212886 4.00013e-06 -0.021 -0.213995 0.003249 -0.0204865 -0.213937 4.00018e-06 -0.021 -0.212851 0.006494 -0.019973 -0.215023 0.003249 -0.0204865 -0.213937 4.00013e-06 -0.021 -0.213995 0.00629732 -0.0200041 -0.212886 0.003249 -0.0204865 -0.213937 0.006494 -0.019973 -0.215023 -0.021156 0.029125 -0.144495 -0.013248 0.033472 -0.144495 -0.019968 0.00648901 -0.144495 -0.020995 8.25938e-09 -0.144495 -0.024639 -0.026243 -0.144495 -0.021156 0.029125 -0.144495 -0.024639 -0.026243 -0.144495 -0.020995 8.25938e-09 -0.144495 -0.017339 -0.031547 -0.144495 -0.012339 0.016989 -0.218006 -0.016985 0.012343 -0.222652 -0.012339 0.016989 -0.144495 -0.012339 0.016989 -0.144495 -0.006485 0.019972 -0.144495 -0.00932588 0.0185244 -0.180169 -0.010355 0.018 -0.181092 -0.012339 0.016989 -0.144495 -0.00932588 0.0185244 -0.180169 -0.010355 0.018 -0.192702 -0.012339 0.016989 -0.144495 -0.010355 0.018 -0.185748 -0.012339 0.016989 -0.144495 -0.010355 0.018 -0.181092 -0.010355 0.018 -0.185748 -0.010355 0.018 -0.192702 -0.010355 0.018 -0.193092 -0.012339 0.016989 -0.144495 -0.010355 0.018 -0.193092 -0.012339 0.016989 -0.218006 -0.012339 0.016989 -0.144495 -0.012339 0.016989 -0.144495 -0.016985 0.012343 -0.222652 -0.016985 0.012343 -0.144495 -0.013248 0.033472 -0.144495 -0.012339 0.016989 -0.144495 -0.016985 0.012343 -0.144495 0.012348 -0.023 -0.218006 0.012348 -0.01699 -0.218006 0.006494 -0.019973 -0.215023 -0.016985 -0.012344 -0.144495 -0.01671 -0.012619 -0.148846 -0.014662 -0.014667 -0.146747 -0.012339 -0.01699 -0.144495 -0.016985 -0.012344 -0.144495 -0.014662 -0.014667 -0.146747 -0.012339 -0.01699 -0.148999 -0.012339 -0.01699 -0.144495 -0.014662 -0.014667 -0.146747 -0.01671 -0.012619 -0.148846 -0.012339 -0.01699 -0.148999 -0.014662 -0.014667 -0.146747 -0.0119646 -0.0171808 -0.149006 -0.012339 -0.01699 -0.144495 -0.012339 -0.01699 -0.148999 -0.006485 -0.019972 -0.144495 -0.009412 -0.018481 -0.146799 -0.006485 -0.0199721 -0.149103 -0.012339 -0.01699 -0.144495 -0.009412 -0.018481 -0.146799 -0.006485 -0.019972 -0.144495 -0.0119646 -0.0171808 -0.149006 -0.009412 -0.018481 -0.146799 -0.012339 -0.01699 -0.144495 -0.006485 -0.0199721 -0.149103 -0.009412 -0.018481 -0.146799 -0.0119646 -0.0171808 -0.149006 -0.006485 -0.0199721 -0.149103 -0.00605452 -0.0200402 -0.149106 -0.006485 -0.019972 -0.144495 4.00317e-06 -0.021 -0.144495 -0.0032405 -0.020486 -0.146817 4.00297e-06 -0.021 -0.149139 -0.006485 -0.019972 -0.144495 -0.0032405 -0.020486 -0.146817 4.00317e-06 -0.021 -0.144495 -0.00605452 -0.0200402 -0.149106 -0.0032405 -0.020486 -0.146817 -0.006485 -0.019972 -0.144495 4.00297e-06 -0.021 -0.149139 -0.0032405 -0.020486 -0.146817 -0.00605452 -0.0200402 -0.149106 4.00297e-06 -0.021 -0.149139 0.000431144 -0.0209324 -0.149137 4.00317e-06 -0.021 -0.144495 0.006494 -0.019972 -0.144495 0.00324901 -0.020486 -0.146816 0.006494 -0.0199721 -0.149103 4.00317e-06 -0.021 -0.144495 0.00324901 -0.020486 -0.146816 0.006494 -0.019972 -0.144495 0.000431144 -0.0209324 -0.149137 0.00324901 -0.020486 -0.146816 4.00317e-06 -0.021 -0.144495 0.006494 -0.0199721 -0.149103 0.00324901 -0.020486 -0.146816 0.000431144 -0.0209324 -0.149137 0.006494 -0.0199721 -0.149103 0.00686046 -0.0197853 -0.149097 0.006494 -0.019972 -0.144495 0.006494 -0.019972 -0.144495 0.00686046 -0.0197853 -0.149097 0.009421000000000001 -0.018481 -0.146796 0.012348 -0.01699 -0.144495 0.006494 -0.019972 -0.144495 0.009421000000000001 -0.018481 -0.146796 0.012348 -0.01699 -0.148999 0.012348 -0.01699 -0.144495 0.009421000000000001 -0.018481 -0.146796 0.00686046 -0.0197853 -0.149097 0.012348 -0.01699 -0.148999 0.009421000000000001 -0.018481 -0.146796 0.012348 -0.01699 -0.148999 0.0126152 -0.0167228 -0.14899 0.012348 -0.01699 -0.144495 0.012348 -0.01699 -0.144495 0.0126152 -0.0167228 -0.14899 0.014671 -0.014667 -0.146742 0.016994 -0.012344 -0.144495 0.012348 -0.01699 -0.144495 0.014671 -0.014667 -0.146742 0.016994 -0.012344 -0.148837 0.016994 -0.012344 -0.144495 0.014671 -0.014667 -0.146742 0.0126152 -0.0167228 -0.14899 0.016994 -0.012344 -0.148837 0.014671 -0.014667 -0.146742 0.017347 -0.031547 -0.144495 0.019977 -0.00648999 -0.144495 0.024648 -0.026243 -0.144495 0.012348 -0.01699 -0.144495 0.016994 -0.012344 -0.144495 0.017347 -0.031547 -0.144495 0.021004 1.00952e-08 -0.144495 0.021165 0.029124 -0.144495 0.024648 -0.026243 -0.144495 0.019977 0.00648901 -0.144495 0.021165 0.029124 -0.144495 0.021004 1.00952e-08 -0.144495 0.019977 0.00648901 -0.228506 0.016994 0.012343 -0.222652 0.019977 0.00648901 -0.144495 0.016039 0.018 -0.221507 0.016994 0.012343 -0.222652 0.016994 0.018 -0.222652 0.012348 -0.023 -0.218006 0.006494 -0.019973 -0.215023 0.006494 -0.023 -0.215023 0.006494 -0.023 -0.215023 0.006494 -0.019973 -0.215023 4.00013e-06 -0.021 -0.213995 -0.017339 -0.031547 -0.144495 -0.016985 -0.012344 -0.144495 -0.008947999999999999 -0.034869 -0.144495 -0.021156 0.029125 -0.144495 -0.013248 0.033472 -0.139995 -0.013248 0.033472 -0.144495 -0.027734 0.022947 -0.144495 -0.021156 0.029125 -0.144495 -0.024639 -0.026243 -0.144495 -0.017339 -0.031547 -0.144495 -0.024639 -0.026243 -0.139995 -0.024639 -0.026243 -0.144495 -0.00932588 0.0185244 -0.180169 -0.006485 0.019972 -0.144495 -0.00873785 0.018824 -0.179642 -0.00873785 0.018824 -0.179642 -0.006485 0.019972 -0.144495 -0.00857368 0.0189077 -0.179495 -0.00857368 0.0189077 -0.179495 -0.006485 0.019972 -0.144495 -0.006485 0.019972 -0.178618 -0.012339 0.016989 -0.144495 -0.004507 0.035716 -0.144495 -0.006485 0.019972 -0.144495 -0.013248 0.033472 -0.144495 -0.004507 0.035716 -0.144495 -0.012339 0.016989 -0.144495 -0.016985 -0.012344 -0.144495 -0.012339 -0.01699 -0.144495 -0.008947999999999999 -0.034869 -0.144495 -0.012339 -0.01699 -0.144495 -0.006485 -0.019972 -0.144495 -0.008947999999999999 -0.034869 -0.144495 -0.006485 -0.019972 -0.144495 4.00317e-06 -0.021 -0.144495 4.00382e-06 -0.036 -0.144495 4.00317e-06 -0.021 -0.144495 0.006494 -0.019972 -0.144495 4.00382e-06 -0.036 -0.144495 0.006494 -0.019972 -0.144495 0.012348 -0.01699 -0.144495 0.008957 -0.034869 -0.144495 0.024648 -0.026243 -0.144495 0.017347 -0.031547 -0.139995 0.017347 -0.031547 -0.144495 0.008957 -0.034869 -0.144495 0.012348 -0.01699 -0.144495 0.017347 -0.031547 -0.144495 0.021165 0.029124 -0.144495 0.027743 0.022947 -0.144495 0.024648 -0.026243 -0.144495 0.016994 0.012343 -0.144495 0.021165 0.029124 -0.144495 0.019977 0.00648901 -0.144495 0.019977 0.00648901 -0.144495 0.016994 0.012343 -0.222652 0.016994 0.012343 -0.144495 0.016039 0.018 -0.221507 0.0157489 0.018 -0.221229 0.016994 0.012343 -0.222652 0.0157489 0.018 -0.221229 0.0128268 0.018 -0.218425 0.012348 0.016989 -0.218006 0.016994 0.012343 -0.222652 0.0157489 0.018 -0.221229 0.012348 0.016989 -0.218006 0.010364 0.018 -0.180877 0.00937989 0.0185015 -0.180254 0.012348 0.016989 -0.144495 0.010364 0.018 -0.210463 0.012348 0.016989 -0.218006 0.010364 0.018 -0.213909 0.010364 0.018 -0.205869 0.012348 0.016989 -0.218006 0.010364 0.018 -0.210463 0.010364 0.018 -0.199636 0.012348 0.016989 -0.218006 0.010364 0.018 -0.205869 0.012348 0.016989 -0.218006 0.010364 0.018 -0.216525 0.010364 0.018 -0.213909 0.012348 0.016989 -0.218006 0.010364 0.018 -0.216995 0.010364 0.018 -0.216525 0.010364 0.018 -0.199636 0.010364 0.018 -0.191116 0.012348 0.016989 -0.218006 0.012348 0.016989 -0.218006 0.0108639 0.0177452 -0.18125 0.012348 0.016989 -0.144495 0.010364 0.018 -0.191116 0.0108639 0.0177452 -0.18125 0.012348 0.016989 -0.218006 0.012348 0.016989 -0.144495 0.0108639 0.0177452 -0.18125 0.010364 0.018 -0.180877 -0.008947999999999999 -0.034869 -0.144495 -0.017339 -0.031547 -0.139995 -0.017339 -0.031547 -0.144495 -0.013248 0.033472 -0.144495 -0.013248 0.033472 -0.139995 -0.004507 0.035716 -0.139995 -0.021156 0.029125 -0.144495 -0.021156 0.029125 -0.139995 -0.013248 0.033472 -0.139995 -0.027734 0.022947 -0.144495 -0.021156 0.029125 -0.139995 -0.021156 0.029125 -0.144495 -0.030391 -0.01929 -0.144495 -0.027734 0.022947 -0.144495 -0.024639 -0.026243 -0.144495 -0.030391 -0.01929 -0.139995 -0.024639 -0.026243 -0.144495 -0.024639 -0.026243 -0.139995 -0.017339 -0.031547 -0.144495 -0.017339 -0.031547 -0.139995 -0.024639 -0.026243 -0.139995 5.00133e-06 0.021 -0.144495 -0.00302369 0.0205203 -0.177408 -0.00324 0.020486 -0.161557 -0.006485 0.019972 -0.144495 5.00133e-06 0.021 -0.144495 -0.00324 0.020486 -0.161557 -0.006485 0.019972 -0.178618 -0.006485 0.019972 -0.144495 -0.00324 0.020486 -0.161557 -0.00439959 0.0203023 -0.177716 -0.006485 0.019972 -0.178618 -0.00324 0.020486 -0.161557 -0.00383344 0.020392 -0.177471 -0.00439959 0.0203023 -0.177716 -0.00324 0.020486 -0.161557 -0.00302369 0.0205203 -0.177408 -0.00383344 0.020392 -0.177471 -0.00324 0.020486 -0.161557 -0.006485 0.019972 -0.144495 -0.004507 0.035716 -0.144495 5.00133e-06 0.021 -0.144495 -0.013248 0.033472 -0.144495 -0.004507 0.035716 -0.139995 -0.004507 0.035716 -0.144495 -0.008947999999999999 -0.034869 -0.144495 -0.006485 -0.019972 -0.144495 4.00382e-06 -0.036 -0.144495 4.00382e-06 -0.036 -0.144495 0.006494 -0.019972 -0.144495 0.008957 -0.034869 -0.144495 0.008957 -0.034869 -0.139995 0.017347 -0.031547 -0.144495 0.017347 -0.031547 -0.139995 0.024648 -0.026243 -0.144495 0.024648 -0.026243 -0.139995 0.017347 -0.031547 -0.139995 0.017347 -0.031547 -0.144495 0.008957 -0.034869 -0.139995 0.008957 -0.034869 -0.144495 0.027743 0.022947 -0.144495 0.0304 -0.01929 -0.144495 0.024648 -0.026243 -0.144495 0.021165 0.029124 -0.144495 0.027743 0.022947 -0.139995 0.027743 0.022947 -0.144495 0.013257 0.033472 -0.144495 0.021165 0.029124 -0.144495 0.016994 0.012343 -0.144495 0.016994 0.012343 -0.222652 0.012348 0.016989 -0.218006 0.016994 0.012343 -0.144495 0.0128268 0.018 -0.218425 0.012348 0.018 -0.218006 0.012348 0.016989 -0.218006 0.012348 0.016989 -0.218006 0.012348 0.018 -0.218006 0.0113634 0.018 -0.217504 0.012348 0.016989 -0.218006 0.0113634 0.018 -0.217504 0.0110984 0.018 -0.217369 0.012348 0.016989 -0.218006 0.0110984 0.018 -0.217369 0.010364 0.018 -0.216995 0.012348 0.016989 -0.144495 0.00937989 0.0185015 -0.180254 0.009421000000000001 0.0184805 -0.162375 0.006494 0.019972 -0.144495 0.012348 0.016989 -0.144495 0.009421000000000001 0.0184805 -0.162375 0.006494 0.019972 -0.178429 0.006494 0.019972 -0.144495 0.009421000000000001 0.0184805 -0.162375 0.00937989 0.0185015 -0.180254 0.006494 0.019972 -0.178429 0.009421000000000001 0.0184805 -0.162375 0.016994 0.012343 -0.144495 0.012348 0.016989 -0.218006 0.012348 0.016989 -0.144495 -0.008947999999999999 -0.034869 -0.144495 -0.008947999999999999 -0.034869 -0.139995 -0.017339 -0.031547 -0.139995 -0.004507 0.035716 -0.139995 -0.013248 0.033472 -0.139995 -0.035358 0.00674601 -0.139995 -0.013248 0.033472 -0.139995 -0.021156 0.029125 -0.139995 -0.035358 0.00674601 -0.139995 -0.027734 0.022947 -0.144495 -0.027734 0.022947 -0.139995 -0.021156 0.029125 -0.139995 -0.027734 0.022947 -0.144495 -0.030391 -0.01929 -0.144495 -0.032569 0.015328 -0.144495 -0.024639 -0.026243 -0.144495 -0.030391 -0.01929 -0.139995 -0.030391 -0.01929 -0.144495 -0.030391 -0.01929 -0.139995 -0.024639 -0.026243 -0.139995 -0.035358 0.00674601 -0.139995 -0.017339 -0.031547 -0.139995 -0.035358 0.00674601 -0.139995 -0.024639 -0.026243 -0.139995 4.5297e-06 0.021 -0.177174 -0.00302369 0.0205203 -0.177408 5.00133e-06 0.021 -0.144495 -0.004507 0.035716 -0.144495 0.004517 0.035716 -0.144495 5.00133e-06 0.021 -0.144495 -0.004507 0.035716 -0.144495 -0.004507 0.035716 -0.139995 0.004517 0.035716 -0.139995 4.00382e-06 -0.036 -0.144495 -0.008947999999999999 -0.034869 -0.139995 -0.008947999999999999 -0.034869 -0.144495 4.00382e-06 -0.036 -0.144495 0.008957 -0.034869 -0.144495 4.00401e-06 -0.036 -0.139995 0.008957 -0.034869 -0.139995 0.017347 -0.031547 -0.139995 -0.035358 0.00674601 -0.139995 0.017347 -0.031547 -0.139995 0.024648 -0.026243 -0.139995 -0.035358 0.00674601 -0.139995 0.024648 -0.026243 -0.139995 0.024648 -0.026243 -0.144495 0.0304 -0.01929 -0.144495 0.008957 -0.034869 -0.144495 0.008957 -0.034869 -0.139995 4.00401e-06 -0.036 -0.139995 0.027743 0.022947 -0.144495 0.032578 0.015328 -0.144495 0.0304 -0.01929 -0.144495 0.032578 0.015328 -0.139995 0.027743 0.022947 -0.144495 0.027743 0.022947 -0.139995 0.021165 0.029124 -0.144495 0.021165 0.029124 -0.139995 0.027743 0.022947 -0.139995 0.021165 0.029124 -0.144495 0.013257 0.033472 -0.144495 0.021165 0.029124 -0.139995 0.012348 0.016989 -0.144495 0.013257 0.033472 -0.144495 0.016994 0.012343 -0.144495 0.00340422 0.0204614 -0.177583 0.006494 0.019972 -0.144495 0.00574517 0.0200906 -0.178162 0.00574517 0.0200906 -0.178162 0.006494 0.019972 -0.144495 0.00628983 0.0200043 -0.178297 0.00628983 0.0200043 -0.178297 0.006494 0.019972 -0.144495 0.006494 0.019972 -0.178429 0.006494 0.019972 -0.144495 0.013257 0.033472 -0.144495 0.012348 0.016989 -0.144495 -0.008947999999999999 -0.034869 -0.139995 -0.035358 0.00674601 -0.139995 -0.017339 -0.031547 -0.139995 0.004517 0.035716 -0.139995 -0.004507 0.035716 -0.139995 -0.035358 0.00674601 -0.139995 -0.021156 0.029125 -0.139995 -0.027734 0.022947 -0.139995 -0.035358 0.00674601 -0.139995 -0.027734 0.022947 -0.139995 -0.027734 0.022947 -0.144495 -0.032569 0.015328 -0.144495 -0.030391 -0.01929 -0.144495 -0.034233 -0.011125 -0.144495 -0.032569 0.015328 -0.144495 -0.034233 -0.011125 -0.139995 -0.030391 -0.01929 -0.144495 -0.030391 -0.01929 -0.139995 -0.034233 -0.011125 -0.139995 -0.030391 -0.01929 -0.139995 -0.035358 0.00674601 -0.139995 0.000513453 0.0209194 -0.177129 0.00324926 0.020486 -0.161039 0.00129399 0.0207957 -0.17706 4.5297e-06 0.021 -0.177174 0.00324926 0.020486 -0.161039 0.000513453 0.0209194 -0.177129 5.00133e-06 0.021 -0.144495 0.00324926 0.020486 -0.161039 4.5297e-06 0.021 -0.177174 0.006494 0.019972 -0.144495 0.00324926 0.020486 -0.161039 5.00133e-06 0.021 -0.144495 0.00340422 0.0204614 -0.177583 0.00324926 0.020486 -0.161039 0.006494 0.019972 -0.144495 0.00129399 0.0207957 -0.17706 0.00324926 0.020486 -0.161039 0.00340422 0.0204614 -0.177583 0.004517 0.035716 -0.144495 -0.004507 0.035716 -0.144495 0.004517 0.035716 -0.139995 5.00133e-06 0.021 -0.144495 0.004517 0.035716 -0.144495 0.006494 0.019972 -0.144495 4.00382e-06 -0.036 -0.144495 4.00401e-06 -0.036 -0.139995 -0.008947999999999999 -0.034869 -0.139995 0.008957 -0.034869 -0.139995 -0.035358 0.00674601 -0.139995 4.00401e-06 -0.036 -0.139995 0.024648 -0.026243 -0.139995 0.0304 -0.01929 -0.139995 -0.035358 0.00674601 -0.139995 0.0304 -0.01929 -0.139995 0.024648 -0.026243 -0.139995 0.0304 -0.01929 -0.144495 0.0304 -0.01929 -0.144495 0.032578 0.015328 -0.144495 0.034242 -0.011125 -0.144495 0.032578 0.015328 -0.139995 0.032578 0.015328 -0.144495 0.027743 0.022947 -0.144495 0.032578 0.015328 -0.139995 0.027743 0.022947 -0.139995 -0.035358 0.00674601 -0.139995 0.027743 0.022947 -0.139995 0.021165 0.029124 -0.139995 -0.035358 0.00674601 -0.139995 0.013257 0.033472 -0.144495 0.013257 0.033472 -0.139995 0.021165 0.029124 -0.139995 0.004517 0.035716 -0.144495 0.013257 0.033472 -0.144495 0.006494 0.019972 -0.144495 4.00401e-06 -0.036 -0.139995 -0.035358 0.00674601 -0.139995 -0.008947999999999999 -0.034869 -0.139995 0.013257 0.033472 -0.139995 0.004517 0.035716 -0.139995 -0.035358 0.00674601 -0.139995 -0.027734 0.022947 -0.139995 -0.032569 0.015328 -0.139995 -0.035358 0.00674601 -0.139995 -0.027734 0.022947 -0.139995 -0.032569 0.015328 -0.144495 -0.032569 0.015328 -0.139995 -0.032569 0.015328 -0.144495 -0.034233 -0.011125 -0.144495 -0.035358 0.00674601 -0.144495 -0.034233 -0.011125 -0.139995 -0.034233 -0.011125 -0.144495 -0.030391 -0.01929 -0.144495 -0.035924 -0.00226 -0.139995 -0.034233 -0.011125 -0.139995 -0.035358 0.00674601 -0.139995 0.004517 0.035716 -0.144495 0.004517 0.035716 -0.139995 0.013257 0.033472 -0.139995 0.0304 -0.01929 -0.139995 0.034242 -0.011125 -0.139995 -0.035358 0.00674601 -0.139995 0.034242 -0.011125 -0.144495 0.0304 -0.01929 -0.139995 0.0304 -0.01929 -0.144495 0.032578 0.015328 -0.144495 0.035367 0.00674601 -0.144495 0.034242 -0.011125 -0.144495 0.035367 0.00674601 -0.139995 0.032578 0.015328 -0.144495 0.032578 0.015328 -0.139995 0.035367 0.00674601 -0.139995 0.032578 0.015328 -0.139995 -0.035358 0.00674601 -0.139995 0.021165 0.029124 -0.139995 0.013257 0.033472 -0.139995 -0.035358 0.00674601 -0.139995 0.004517 0.035716 -0.144495 0.013257 0.033472 -0.139995 0.013257 0.033472 -0.144495 -0.032569 0.015328 -0.139995 -0.035358 0.00674601 -0.144495 -0.035358 0.00674601 -0.139995 -0.032569 0.015328 -0.139995 -0.032569 0.015328 -0.144495 -0.035358 0.00674601 -0.144495 -0.034233 -0.011125 -0.144495 -0.035924 -0.00226 -0.144495 -0.035358 0.00674601 -0.144495 -0.034233 -0.011125 -0.139995 -0.035924 -0.00226 -0.139995 -0.034233 -0.011125 -0.144495 -0.035995 7.407e-09 -0.139995 -0.035924 -0.00226 -0.139995 -0.035358 0.00674601 -0.139995 0.034242 -0.011125 -0.139995 0.035933 -0.00226099 -0.139995 -0.035358 0.00674601 -0.139995 0.034242 -0.011125 -0.139995 0.0304 -0.01929 -0.139995 0.034242 -0.011125 -0.144495 0.034242 -0.011125 -0.144495 0.035367 0.00674601 -0.144495 0.035933 -0.00226099 -0.144495 0.032578 0.015328 -0.144495 0.035367 0.00674601 -0.139995 0.035367 0.00674601 -0.144495 0.035933 -0.00226099 -0.139995 0.035367 0.00674601 -0.139995 -0.035358 0.00674601 -0.139995 -0.035358 0.00674601 -0.139995 -0.035358 0.00674601 -0.144495 -0.035995 7.60371e-09 -0.144495 -0.035358 0.00674601 -0.144495 -0.035924 -0.00226 -0.144495 -0.035995 7.60371e-09 -0.144495 -0.035924 -0.00226 -0.139995 -0.035924 -0.00226 -0.144495 -0.034233 -0.011125 -0.144495 -0.035358 0.00674601 -0.139995 -0.035995 7.60371e-09 -0.144495 -0.035995 7.407e-09 -0.139995 -0.035995 7.407e-09 -0.139995 -0.035924 -0.00226 -0.144495 -0.035924 -0.00226 -0.139995 0.034242 -0.011125 -0.139995 0.035933 -0.00226099 -0.144495 0.035933 -0.00226099 -0.139995 0.034242 -0.011125 -0.139995 0.034242 -0.011125 -0.144495 0.035933 -0.00226099 -0.144495 0.035933 -0.00226099 -0.139995 0.035933 -0.00226099 -0.144495 0.035367 0.00674601 -0.144495 0.035933 -0.00226099 -0.139995 0.035367 0.00674601 -0.144495 0.035367 0.00674601 -0.139995 -0.035995 7.60371e-09 -0.144495 -0.035924 -0.00226 -0.144495 -0.035995 7.407e-09 -0.139995 -0.02377 -0.008999989999999999 -0.21327 -0.012339 -0.01699 -0.212991 4.49922e-06 -0.02725 -0.212633 0.006494 -0.019973 -0.212887 0.022505 -0.0455 -0.211995 4.49922e-06 -0.02725 -0.212633 0.0186974 -0.008999989999999999 -0.21327 0.023779 -0.008999989999999999 -0.21327 0.016994 -0.012344 -0.213153 0.016994 -0.012344 -0.213153 0.023779 -0.008999989999999999 -0.21327 0.0164282 -0.0129098 -0.213133 0.012348 -0.01699 -0.212991 0.0164282 -0.0129098 -0.213133 0.022505 -0.0455 -0.211995 0.0119481 -0.0171937 -0.212984 0.012348 -0.01699 -0.212991 0.022505 -0.0455 -0.211995 0.006494 -0.019973 -0.212887 0.0119481 -0.0171937 -0.212984 0.022505 -0.0455 -0.211995 0.0164282 -0.0129098 -0.213133 0.023779 -0.008999989999999999 -0.21327 0.022505 -0.0455 -0.211995 -0.0186889 -0.008999989999999999 -0.21327 -0.0173466 -0.0116343 -0.213178 -0.02377 -0.008999989999999999 -0.21327 -0.0173466 -0.0116343 -0.213178 -0.016985 -0.012344 -0.213153 -0.02377 -0.008999989999999999 -0.21327 -0.016985 -0.012344 -0.213153 -0.0126553 -0.0166737 -0.213002 -0.02377 -0.008999989999999999 -0.21327 -0.02377 -0.008999989999999999 -0.21327 -0.0126553 -0.0166737 -0.213002 -0.012339 -0.01699 -0.212991 0.022505 -0.0455 -0.211995 -0.02377 -0.008999989999999999 -0.21327 4.49922e-06 -0.02725 -0.212633 -0.012339 -0.01699 -0.212991 -0.00666206 -0.0198828 -0.21289 4.49922e-06 -0.02725 -0.212633 -0.00666206 -0.0198828 -0.21289 -0.006485 -0.019973 -0.212887 4.49922e-06 -0.02725 -0.212633 -0.006485 -0.019973 -0.212887 -0.000102773 -0.0209831 -0.212851 4.49922e-06 -0.02725 -0.212633 -0.000102773 -0.0209831 -0.212851 4.00018e-06 -0.021 -0.212851 4.49922e-06 -0.02725 -0.212633 0.00629732 -0.0200041 -0.212886 0.006494 -0.019973 -0.212887 4.49922e-06 -0.02725 -0.212633 4.00018e-06 -0.021 -0.212851 0.00629732 -0.0200041 -0.212886 4.49922e-06 -0.02725 -0.212633 -0.0186887 -0.008999989999999999 -0.155618 -0.0186887 -0.008999989999999999 -0.178013 -0.0212294 -0.008999989999999999 -0.180995 -0.02377 -0.008999989999999999 -0.14872 -0.0186887 -0.008999989999999999 -0.155618 -0.0212294 -0.008999989999999999 -0.180995 -0.02377 -0.008999989999999999 -0.21327 -0.02377 -0.008999989999999999 -0.14872 -0.0212294 -0.008999989999999999 -0.180995 -0.0186889 -0.008999989999999999 -0.21327 -0.02377 -0.008999989999999999 -0.21327 -0.0212294 -0.008999989999999999 -0.180995 -0.0186887 -0.008999989999999999 -0.178013 -0.0186889 -0.008999989999999999 -0.21327 -0.0212294 -0.008999989999999999 -0.180995 0.023779 -0.008999989999999999 -0.21327 0.0186974 -0.008999989999999999 -0.206372 0.0186974 -0.008999989999999999 -0.192485 0.023779 -0.008999989999999999 -0.14872 0.023779 -0.008999989999999999 -0.21327 0.0212382 -0.008999989999999999 -0.180995 0.0186979 -0.008999989999999999 -0.14872 0.023779 -0.008999989999999999 -0.14872 0.0212382 -0.008999989999999999 -0.180995 0.0186974 -0.008999989999999999 -0.192485 0.0186979 -0.008999989999999999 -0.14872 0.0212382 -0.008999989999999999 -0.180995 0.023779 -0.008999989999999999 -0.21327 0.0186974 -0.008999989999999999 -0.192485 0.0212382 -0.008999989999999999 -0.180995 0.023779 -0.008999989999999999 -0.21327 0.0186974 -0.008999989999999999 -0.21327 0.0186974 -0.008999989999999999 -0.206372 0.000431144 -0.0209324 -0.149137 4.00297e-06 -0.021 -0.149139 4.49922e-06 -0.02725 -0.149357 0.006494 -0.0199721 -0.149103 0.000431144 -0.0209324 -0.149137 4.49922e-06 -0.02725 -0.149357 0.00686046 -0.0197853 -0.149097 0.006494 -0.0199721 -0.149103 4.49922e-06 -0.02725 -0.149357 0.012348 -0.01699 -0.148999 0.00686046 -0.0197853 -0.149097 4.49922e-06 -0.02725 -0.149357 0.023779 -0.008999989999999999 -0.14872 0.012348 -0.01699 -0.148999 4.49922e-06 -0.02725 -0.149357 -0.006485 -0.0199721 -0.149103 -0.022496 -0.0455 -0.149995 4.49922e-06 -0.02725 -0.149357 0.012348 -0.01699 -0.148999 0.023779 -0.008999989999999999 -0.14872 0.0126152 -0.0167228 -0.14899 0.0126152 -0.0167228 -0.14899 0.023779 -0.008999989999999999 -0.14872 0.016994 -0.012344 -0.148837 0.016994 -0.012344 -0.148837 0.023779 -0.008999989999999999 -0.14872 0.0171477 -0.0120422 -0.148826 0.0171477 -0.0120422 -0.148826 0.023779 -0.008999989999999999 -0.14872 0.0186979 -0.008999989999999999 -0.14872 -0.022496 -0.0455 -0.149995 -0.006485 -0.0199721 -0.149103 -0.0119646 -0.0171808 -0.149006 -0.022496 -0.0455 -0.149995 -0.0119646 -0.0171808 -0.149006 -0.012339 -0.01699 -0.148999 -0.022496 -0.0455 -0.149995 -0.012339 -0.01699 -0.148999 -0.01671 -0.012619 -0.148846 -0.016985 -0.012344 -0.148837 -0.0186887 -0.008999989999999999 -0.14872 -0.02377 -0.008999989999999999 -0.14872 -0.01671 -0.012619 -0.148846 -0.016985 -0.012344 -0.148837 -0.02377 -0.008999989999999999 -0.14872 -0.022496 -0.0455 -0.149995 -0.01671 -0.012619 -0.148846 -0.02377 -0.008999989999999999 -0.14872 -0.022496 -0.0455 -0.149995 0.023779 -0.008999989999999999 -0.14872 4.49922e-06 -0.02725 -0.149357 -0.00605452 -0.0200402 -0.149106 -0.006485 -0.0199721 -0.149103 4.49922e-06 -0.02725 -0.149357 4.00297e-06 -0.021 -0.149139 -0.00605452 -0.0200402 -0.149106 4.49922e-06 -0.02725 -0.149357 -0.0186887 -0.008999989999999999 -0.155618 -0.02377 -0.008999989999999999 -0.14872 -0.0186887 -0.008999989999999999 -0.14872 -0.02377 -0.008999989999999999 -0.21327 0.022505 -0.0455 -0.211995 0.006878 -0.0455 -0.211995 -0.02377 -0.008999989999999999 -0.21327 0.006878 -0.0455 -0.211995 -0.006869 -0.0455 -0.211995 -0.02377 -0.008999989999999999 -0.21327 -0.006869 -0.0455 -0.211995 -0.022495 -0.0455 -0.211995 0.023779 -0.008999989999999999 -0.21327 0.023779 -0.008999989999999999 -0.14872 0.022505 -0.0455 -0.211995 -0.02377 -0.008999989999999999 -0.14872 -0.02377 -0.008999989999999999 -0.21327 -0.022496 -0.0455 -0.149995 0.022505 -0.0455 -0.149995 0.023779 -0.008999989999999999 -0.14872 -0.022496 -0.0455 -0.149995 -0.02377 -0.008999989999999999 -0.21327 -0.022495 -0.0455 -0.211995 -0.022496 -0.0455 -0.149995 0.008137999999999999 -0.0455 -0.198317 0.006878 -0.0455 -0.211995 0.022505 -0.0455 -0.211995 0.00814 -0.0455 -0.198289 0.008137999999999999 -0.0455 -0.198317 0.022505 -0.0455 -0.211995 0.008336 -0.0455 -0.192393 0.00814 -0.0455 -0.198289 0.022505 -0.0455 -0.211995 0.008246 -0.0455 -0.186493 0.008336 -0.0455 -0.192393 0.0146915 -0.0455 -0.180995 0.008133 -0.0455 -0.184585 0.008246 -0.0455 -0.186493 0.0146915 -0.0455 -0.180995 0.007896 -0.0455 -0.180603 0.008133 -0.0455 -0.184585 0.0146915 -0.0455 -0.180995 0.00755 -0.0455 -0.176684 0.007896 -0.0455 -0.180603 0.0146915 -0.0455 -0.180995 0.007137 -0.0455 -0.172772 0.00755 -0.0455 -0.176684 0.0146915 -0.0455 -0.180995 0.00693438 -0.0455 -0.171448 0.007137 -0.0455 -0.172772 0.0146915 -0.0455 -0.180995 0.022505 -0.0455 -0.149995 0.00693438 -0.0455 -0.171448 0.0146915 -0.0455 -0.180995 0.022505 -0.0455 -0.211995 0.022505 -0.0455 -0.149995 0.0146915 -0.0455 -0.180995 0.008336 -0.0455 -0.192393 0.022505 -0.0455 -0.211995 0.0146915 -0.0455 -0.180995 -0.008324349999999999 -0.0455 -0.192471 -0.022495 -0.0455 -0.211995 -0.008132 -0.0455 -0.198288 -0.008132 -0.0455 -0.198288 -0.022495 -0.0455 -0.211995 -0.007698 -0.0455 -0.204172 -0.007698 -0.0455 -0.204172 -0.022495 -0.0455 -0.211995 -0.007311 -0.0455 -0.208087 -0.007311 -0.0455 -0.208087 -0.022495 -0.0455 -0.211995 -0.00725697 -0.0455 -0.208565 -0.00725697 -0.0455 -0.208565 -0.022495 -0.0455 -0.211995 -0.00724647 -0.0455 -0.208658 -0.00724647 -0.0455 -0.208658 -0.022495 -0.0455 -0.211995 -0.00723435 -0.0455 -0.208765 -0.00723435 -0.0455 -0.208765 -0.022495 -0.0455 -0.211995 -0.00720616 -0.0455 -0.209014 -0.00720616 -0.0455 -0.209014 -0.022495 -0.0455 -0.211995 -0.00713998 -0.0455 -0.209599 -0.00713998 -0.0455 -0.209599 -0.022495 -0.0455 -0.211995 -0.00706299 -0.0455 -0.21028 -0.00706299 -0.0455 -0.21028 -0.022495 -0.0455 -0.211995 -0.00705235 -0.0455 -0.210374 -0.00705235 -0.0455 -0.210374 -0.022495 -0.0455 -0.211995 -0.00700771 -0.0455 -0.210769 -0.00700771 -0.0455 -0.210769 -0.022495 -0.0455 -0.211995 -0.006869 -0.0455 -0.211995 -0.006869 -0.0455 -0.211995 0.006878 -0.0455 -0.211995 -0.006822 -0.045919 -0.21198 0.022505 -0.0455 -0.149995 0.022505 -0.0455 -0.211995 0.023779 -0.008999989999999999 -0.14872 0.004866 -0.0455 -0.164357 0.00586 -0.0455 -0.166496 0.022505 -0.0455 -0.149995 0.004003 -0.0455 -0.162498 0.004866 -0.0455 -0.164357 0.022505 -0.0455 -0.149995 0.00289 -0.0455 -0.161151 0.004003 -0.0455 -0.162498 0.022505 -0.0455 -0.149995 0.00176572 -0.0455 -0.160304 0.00289 -0.0455 -0.161151 0.022505 -0.0455 -0.149995 0.000607004 -0.0455 -0.159878 0.00176572 -0.0455 -0.160304 0.022505 -0.0455 -0.149995 3.56653e-09 -0.0455 -0.159822 0.000607004 -0.0455 -0.159878 0.022505 -0.0455 -0.149995 -0.022496 -0.0455 -0.149995 3.56653e-09 -0.0455 -0.159822 0.022505 -0.0455 -0.149995 -0.00290525 -0.0455 -0.161177 -0.022496 -0.0455 -0.149995 -0.004013 -0.0455 -0.162526 -0.00754 -0.0455 -0.176683 -0.022496 -0.0455 -0.149995 -0.007887 -0.0455 -0.180602 -0.022496 -0.0455 -0.149995 -0.00290525 -0.0455 -0.161177 -0.001762 -0.0455 -0.160306 0.022505 -0.0455 -0.149995 0.00586 -0.0455 -0.166496 0.006652 -0.0455 -0.169601 -0.022496 -0.0455 -0.149995 -0.001762 -0.0455 -0.160306 -0.000602996 -0.0455 -0.159879 -0.004013 -0.0455 -0.162526 -0.022496 -0.0455 -0.149995 -0.004759 -0.0455 -0.164141 0.022505 -0.0455 -0.149995 0.006652 -0.0455 -0.169601 0.006851 -0.0455 -0.170903 -0.022496 -0.0455 -0.149995 -0.000602996 -0.0455 -0.159879 3.56653e-09 -0.0455 -0.159822 0.022505 -0.0455 -0.149995 0.006851 -0.0455 -0.170903 0.00693438 -0.0455 -0.171448 -0.004759 -0.0455 -0.164141 -0.022496 -0.0455 -0.149995 -0.005859 -0.0455 -0.166523 -0.008238000000000001 -0.0455 -0.186491 -0.007887 -0.0455 -0.180602 -0.022495 -0.0455 -0.211995 -0.008326999999999999 -0.0455 -0.192391 -0.008238000000000001 -0.0455 -0.186491 -0.022495 -0.0455 -0.211995 -0.008324349999999999 -0.0455 -0.192471 -0.008326999999999999 -0.0455 -0.192391 -0.022495 -0.0455 -0.211995 -0.007887 -0.0455 -0.180602 -0.022496 -0.0455 -0.149995 -0.022495 -0.0455 -0.211995 -0.005859 -0.0455 -0.166523 -0.022496 -0.0455 -0.149995 -0.006647 -0.0455 -0.169617 -0.006647 -0.0455 -0.169617 -0.022496 -0.0455 -0.149995 -0.007127 -0.0455 -0.172772 -0.007127 -0.0455 -0.172772 -0.022496 -0.0455 -0.149995 -0.00754 -0.0455 -0.176683 0.006831 -0.045919 -0.21198 0.006878 -0.0455 -0.211995 0.008137999999999999 -0.0455 -0.198317 0.00814 -0.0455 -0.198289 0.008137999999999999 -0.0455 -0.198317 0.008113 -0.045961 -0.198393 0.008113 -0.045961 -0.198393 0.00814 -0.0455 -0.198289 0.008336 -0.0455 -0.192393 0.008336 -0.0455 -0.192393 0.008246 -0.0455 -0.186493 0.008196999999999999 -0.046021 -0.184803 0.008196999999999999 -0.046021 -0.184803 0.008246 -0.0455 -0.186493 0.008133 -0.0455 -0.184585 0.008196999999999999 -0.046021 -0.184803 0.008133 -0.0455 -0.184585 0.007896 -0.0455 -0.180603 0.007896 -0.0455 -0.180603 0.00755 -0.0455 -0.176684 0.008196999999999999 -0.046021 -0.184803 0.007137 -0.0455 -0.172772 0.007007 -0.046085 -0.171281 0.00755 -0.0455 -0.176684 0.007007 -0.046085 -0.171281 0.007137 -0.0455 -0.172772 0.00693438 -0.0455 -0.171448 0.007007 -0.046085 -0.171281 0.00693438 -0.0455 -0.171448 0.006851 -0.0455 -0.170903 -0.00725697 -0.0455 -0.208565 -0.00716 -0.045965 -0.208648 -0.007311 -0.0455 -0.208087 -0.00725697 -0.0455 -0.208565 -0.00716 -0.045965 -0.208648 -0.00724647 -0.0455 -0.208658 -0.00724647 -0.0455 -0.208658 -0.00716 -0.045965 -0.208648 -0.00723435 -0.0455 -0.208765 -0.00723435 -0.0455 -0.208765 -0.00720616 -0.0455 -0.209014 -0.00716 -0.045965 -0.208648 -0.00720616 -0.0455 -0.209014 -0.00713998 -0.0455 -0.209599 -0.00716 -0.045965 -0.208648 -0.00716 -0.045965 -0.208648 -0.00713998 -0.0455 -0.209599 -0.00706299 -0.0455 -0.21028 -0.00706299 -0.0455 -0.21028 -0.006995 -0.045943 -0.210316 -0.00705235 -0.0455 -0.210374 -0.00705235 -0.0455 -0.210374 -0.00700771 -0.0455 -0.210769 -0.006995 -0.045943 -0.210316 -0.00700771 -0.0455 -0.210769 -0.006869 -0.0455 -0.211995 -0.006995 -0.045943 -0.210316 -0.006869 -0.0455 -0.211995 -0.006822 -0.045919 -0.21198 -0.006995 -0.045943 -0.210316 0.006878 -0.0455 -0.211995 0.006831 -0.045919 -0.21198 -0.006822 -0.045919 -0.21198 0.007007 -0.046085 -0.171281 0.006851 -0.0455 -0.170903 0.006652 -0.0455 -0.169601 0.006652 -0.0455 -0.169601 0.00586 -0.0455 -0.166496 0.007007 -0.046085 -0.171281 0.004866 -0.0455 -0.164357 0.005175 -0.046114 -0.164753 0.00586 -0.0455 -0.166496 0.004003 -0.0455 -0.162498 0.005175 -0.046114 -0.164753 0.004866 -0.0455 -0.164357 0.001976 -0.046132 -0.160814 0.00176572 -0.0455 -0.160304 0.000607004 -0.0455 -0.159878 0.000355004 -0.046138 -0.160347 3.56653e-09 -0.0455 -0.159822 -0.000602996 -0.0455 -0.159879 -0.000602996 -0.0455 -0.159879 -0.001762 -0.0455 -0.160306 0.000355004 -0.046138 -0.160347 -0.001762 -0.0455 -0.160306 -0.00290525 -0.0455 -0.161177 -0.002695 -0.046147 -0.161743 -0.002695 -0.046147 -0.161743 -0.00290525 -0.0455 -0.161177 -0.004013 -0.0455 -0.162526 -0.004759 -0.0455 -0.164141 -0.004628 -0.046155 -0.164618 -0.004013 -0.0455 -0.162526 -0.004759 -0.0455 -0.164141 -0.005859 -0.0455 -0.166523 -0.004628 -0.046155 -0.164618 -0.005859 -0.0455 -0.166523 -0.006647 -0.0455 -0.169617 -0.006553 -0.046164 -0.171254 -0.007127 -0.0455 -0.172772 -0.00754 -0.0455 -0.176683 -0.007325 -0.046161 -0.178096 0.008137999999999999 -0.0455 -0.198317 0.008113 -0.045961 -0.198393 0.006831 -0.045919 -0.21198 0.008113 -0.045961 -0.198393 0.008336 -0.0455 -0.192393 0.008196999999999999 -0.046021 -0.184803 0.008196999999999999 -0.046021 -0.184803 0.00755 -0.0455 -0.176684 0.007007 -0.046085 -0.171281 -0.007311 -0.0455 -0.208087 -0.00716 -0.045965 -0.208648 -0.007463 -0.046006 -0.2053 -0.00706299 -0.0455 -0.21028 -0.006995 -0.045943 -0.210316 -0.00716 -0.045965 -0.208648 -0.006995 -0.045943 -0.210316 -0.006822 -0.045919 -0.21198 -0.00692 -0.046389 -0.210359 0.006831 -0.045919 -0.21198 0.006784 -0.046339 -0.211966 -0.006822 -0.045919 -0.21198 0.007007 -0.046085 -0.171281 0.00586 -0.0455 -0.166496 0.005175 -0.046114 -0.164753 0.004003 -0.0455 -0.162498 0.00332 -0.046126 -0.161881 0.005175 -0.046114 -0.164753 0.000355004 -0.046138 -0.160347 0.001976 -0.046132 -0.160814 0.000607004 -0.0455 -0.159878 0.000355004 -0.046138 -0.160347 0.000133004 -0.0455 -0.159835 3.56653e-09 -0.0455 -0.159822 -0.001762 -0.0455 -0.160306 -0.002695 -0.046147 -0.161743 0.000355004 -0.046138 -0.160347 -0.002695 -0.046147 -0.161743 -0.004013 -0.0455 -0.162526 -0.004628 -0.046155 -0.164618 -0.004628 -0.046155 -0.164618 -0.005859 -0.0455 -0.166523 -0.006553 -0.046164 -0.171254 -0.006813 -0.0455 -0.170709 -0.006553 -0.046164 -0.171254 -0.006647 -0.0455 -0.169617 -0.006553 -0.046164 -0.171254 -0.007127 -0.0455 -0.172772 -0.007325 -0.046161 -0.178096 -0.007618 -0.0455 -0.177565 -0.007325 -0.046161 -0.178096 -0.00754 -0.0455 -0.176683 0.006784 -0.046339 -0.211966 0.006831 -0.045919 -0.21198 0.008113 -0.045961 -0.198393 0.008055 -0.046462 -0.198561 0.008113 -0.045961 -0.198393 0.008196999999999999 -0.046021 -0.184803 0.008196999999999999 -0.046021 -0.184803 0.007007 -0.046085 -0.171281 0.00818 -0.046603 -0.185194 -0.007463 -0.046006 -0.2053 -0.00716 -0.045965 -0.208648 -0.007313 -0.046522 -0.205499 -0.007603 -0.0455 -0.205131 -0.007311 -0.0455 -0.208087 -0.007463 -0.046006 -0.2053 -0.00716 -0.045965 -0.208648 -0.006995 -0.045943 -0.210316 -0.007058 -0.046436 -0.208745 -0.006995 -0.045943 -0.210316 -0.00692 -0.046389 -0.210359 -0.007058 -0.046436 -0.208745 -0.006822 -0.045919 -0.21198 -0.006774 -0.046339 -0.211966 -0.00692 -0.046389 -0.210359 -0.006822 -0.045919 -0.21198 0.006784 -0.046339 -0.211966 -0.006774 -0.046339 -0.211966 0.005175 -0.046114 -0.164753 0.007067 -0.046738 -0.171904 0.007007 -0.046085 -0.171281 0.00332 -0.046126 -0.161881 0.005285 -0.046794 -0.165484 0.005175 -0.046114 -0.164753 0.003103 -0.0455 -0.161409 0.00332 -0.046126 -0.161881 0.004003 -0.0455 -0.162498 0.00289 -0.0455 -0.161151 0.00176572 -0.0455 -0.160304 0.001976 -0.046132 -0.160814 0.001976 -0.046132 -0.160814 0.000355004 -0.046138 -0.160347 0.002139 -0.04683 -0.161613 0.000355004 -0.046138 -0.160347 0.000607004 -0.0455 -0.159878 0.000133004 -0.0455 -0.159835 0.000355004 -0.046138 -0.160347 -0.002695 -0.046147 -0.161743 0.000539004 -0.04684 -0.16116 -0.00247 -0.046857 -0.162563 -0.002695 -0.046147 -0.161743 -0.004628 -0.046155 -0.164618 -0.006553 -0.046164 -0.171254 -0.004375 -0.04687 -0.165428 -0.004628 -0.046155 -0.164618 -0.006813 -0.0455 -0.170709 -0.007127 -0.0455 -0.172772 -0.006553 -0.046164 -0.171254 -0.007325 -0.046161 -0.178096 -0.006265 -0.046882 -0.172025 -0.006553 -0.046164 -0.171254 -0.007618 -0.0455 -0.177565 -0.007887 -0.0455 -0.180602 -0.007325 -0.046161 -0.178096 0.008113 -0.045961 -0.198393 0.008055 -0.046462 -0.198561 0.006784 -0.046339 -0.211966 0.00818 -0.046603 -0.185194 0.008055 -0.046462 -0.198561 0.008196999999999999 -0.046021 -0.184803 0.00818 -0.046603 -0.185194 0.007007 -0.046085 -0.171281 0.007067 -0.046738 -0.171904 -0.007463 -0.046006 -0.2053 -0.007313 -0.046522 -0.205499 -0.007527 -0.046597 -0.202228 -0.00716 -0.045965 -0.208648 -0.007058 -0.046436 -0.208745 -0.007313 -0.046522 -0.205499 -0.007603 -0.0455 -0.205131 -0.007463 -0.046006 -0.2053 -0.007698 -0.0455 -0.204172 -0.007058 -0.046436 -0.208745 -0.00692 -0.046389 -0.210359 -0.006851 -0.047388 -0.208974 -0.00692 -0.046389 -0.210359 -0.006774 -0.046339 -0.211966 -0.006768 -0.047286 -0.210461 0.006784 -0.046339 -0.211966 0.006689 -0.047178 -0.211936 -0.006774 -0.046339 -0.211966 0.007067 -0.046738 -0.171904 0.005175 -0.046114 -0.164753 0.005285 -0.046794 -0.165484 0.005285 -0.046794 -0.165484 0.00332 -0.046126 -0.161881 0.003463 -0.046819 -0.16266 0.00289 -0.0455 -0.161151 0.00332 -0.046126 -0.161881 0.003103 -0.0455 -0.161409 0.001976 -0.046132 -0.160814 0.00332 -0.046126 -0.161881 0.00274241 -0.045816 -0.161229 0.00332 -0.046126 -0.161881 0.00289 -0.0455 -0.161151 0.00274241 -0.045816 -0.161229 0.00289 -0.0455 -0.161151 0.001976 -0.046132 -0.160814 0.00274241 -0.045816 -0.161229 0.002139 -0.04683 -0.161613 0.003463 -0.046819 -0.16266 0.001976 -0.046132 -0.160814 0.000355004 -0.046138 -0.160347 0.000539004 -0.04684 -0.16116 0.002139 -0.04683 -0.161613 -0.002695 -0.046147 -0.161743 -0.00247 -0.046857 -0.162563 0.000539004 -0.04684 -0.16116 -0.00247 -0.046857 -0.162563 -0.004628 -0.046155 -0.164618 -0.004375 -0.04687 -0.165428 -0.006553 -0.046164 -0.171254 -0.006265 -0.046882 -0.172025 -0.004375 -0.04687 -0.165428 -0.007325 -0.046161 -0.178096 -0.007022 -0.046871 -0.178806 -0.006265 -0.046882 -0.172025 -0.007325 -0.046161 -0.178096 -0.007887 -0.0455 -0.180602 -0.007849 -0.046147 -0.184936 0.006689 -0.047178 -0.211936 0.006784 -0.046339 -0.211966 0.008055 -0.046462 -0.198561 0.007854 -0.047555 -0.199136 0.008055 -0.046462 -0.198561 0.00818 -0.046603 -0.185194 0.008007 -0.047907 -0.18642 0.00818 -0.046603 -0.185194 0.007067 -0.046738 -0.171904 -0.007527 -0.046597 -0.202228 -0.007313 -0.046522 -0.205499 -0.007137 -0.047743 -0.202923 -0.007719 -0.046041 -0.201937 -0.007463 -0.046006 -0.2053 -0.007527 -0.046597 -0.202228 -0.007313 -0.046522 -0.205499 -0.007058 -0.046436 -0.208745 -0.007006 -0.047576 -0.205969 -0.007698 -0.0455 -0.204172 -0.007463 -0.046006 -0.2053 -0.007719 -0.046041 -0.201937 -0.007058 -0.046436 -0.208745 -0.006851 -0.047388 -0.208974 -0.007006 -0.047576 -0.205969 -0.00692 -0.046389 -0.210359 -0.006768 -0.047286 -0.210461 -0.006851 -0.047388 -0.208974 -0.006774 -0.046339 -0.211966 -0.00668 -0.047178 -0.211936 -0.006768 -0.047286 -0.210461 -0.006774 -0.046339 -0.211966 0.006689 -0.047178 -0.211936 -0.00668 -0.047178 -0.211936 0.007018 -0.048197 -0.173778 0.007067 -0.046738 -0.171904 0.005285 -0.046794 -0.165484 0.005285 -0.046794 -0.165484 0.003463 -0.046819 -0.16266 0.003464 -0.051719 -0.17186 0.003463 -0.046819 -0.16266 0.00332 -0.046126 -0.161881 0.001976 -0.046132 -0.160814 0.003463 -0.046819 -0.16266 0.002139 -0.04683 -0.161613 0.002361 -0.051749 -0.171009 0.002139 -0.04683 -0.161613 0.000539004 -0.04684 -0.16116 0.001021 -0.051774 -0.17066 0.000539004 -0.04684 -0.16116 -0.00247 -0.046857 -0.162563 -0.001497 -0.051808 -0.171922 -0.00247 -0.046857 -0.162563 -0.004375 -0.04687 -0.165428 -0.003079 -0.051821 -0.174412 -0.006265 -0.046882 -0.172025 -0.005697 -0.048441 -0.17414 -0.004375 -0.04687 -0.165428 -0.007022 -0.046871 -0.178806 -0.005697 -0.048441 -0.17414 -0.006265 -0.046882 -0.172025 -0.007325 -0.046161 -0.178096 -0.007849 -0.046147 -0.184936 -0.007022 -0.046871 -0.178806 -0.008116 -0.0455 -0.184449 -0.007849 -0.046147 -0.184936 -0.007887 -0.0455 -0.180602 0.007854 -0.047555 -0.199136 0.006689 -0.047178 -0.211936 0.008055 -0.046462 -0.198561 0.008007 -0.047907 -0.18642 0.007854 -0.047555 -0.199136 0.00818 -0.046603 -0.185194 0.007018 -0.048197 -0.173778 0.008007 -0.047907 -0.18642 0.007067 -0.046738 -0.171904 -0.005907 -0.051631 -0.203297 -0.007527 -0.046597 -0.202228 -0.007137 -0.047743 -0.202923 -0.007313 -0.046522 -0.205499 -0.007006 -0.047576 -0.205969 -0.007137 -0.047743 -0.202923 -0.007719 -0.046041 -0.201937 -0.007527 -0.046597 -0.202228 -0.007688 -0.046663 -0.198933 -0.007881000000000001 -0.0455 -0.20169 -0.007698 -0.0455 -0.204172 -0.007719 -0.046041 -0.201937 -0.007006 -0.047576 -0.205969 -0.006851 -0.047388 -0.208974 -0.0067 -0.048643 -0.206511 -0.006851 -0.047388 -0.208974 -0.006768 -0.047286 -0.210461 -0.006643 -0.048346 -0.209237 -0.006768 -0.047286 -0.210461 -0.00668 -0.047178 -0.211936 -0.006614 -0.048185 -0.210579 0.006689 -0.047178 -0.211936 0.006594 -0.048017 -0.211907 -0.00668 -0.047178 -0.211936 0.003464 -0.051719 -0.17186 0.007018 -0.048197 -0.173778 0.005285 -0.046794 -0.165484 0.003463 -0.046819 -0.16266 0.002361 -0.051749 -0.171009 0.003464 -0.051719 -0.17186 0.002139 -0.04683 -0.161613 0.001021 -0.051774 -0.17066 0.002361 -0.051749 -0.171009 0.000539004 -0.04684 -0.16116 -0.001497 -0.051808 -0.171922 0.001021 -0.051774 -0.17066 -0.00247 -0.046857 -0.162563 -0.003079 -0.051821 -0.174412 -0.001497 -0.051808 -0.171922 -0.005148 -0.050096 -0.176876 -0.003079 -0.051821 -0.174412 -0.004375 -0.04687 -0.165428 -0.005697 -0.048441 -0.17414 -0.005148 -0.050096 -0.176876 -0.004375 -0.04687 -0.165428 -0.007022 -0.046871 -0.178806 -0.006417 -0.048397 -0.180688 -0.005697 -0.048441 -0.17414 -0.007849 -0.046147 -0.184936 -0.007549 -0.046834 -0.185563 -0.007022 -0.046871 -0.178806 -0.008116 -0.0455 -0.184449 -0.008238000000000001 -0.0455 -0.186491 -0.007849 -0.046147 -0.184936 0.006594 -0.048017 -0.211907 0.006689 -0.047178 -0.211936 0.007854 -0.047555 -0.199136 0.007566 -0.048734 -0.199968 0.007854 -0.047555 -0.199136 0.008007 -0.047907 -0.18642 0.00768 -0.049338 -0.188129 0.008007 -0.047907 -0.18642 0.007018 -0.048197 -0.173778 -0.007137 -0.047743 -0.202923 -0.006747 -0.048911 -0.203733 -0.005907 -0.051631 -0.203297 -0.007688 -0.046663 -0.198933 -0.007527 -0.046597 -0.202228 -0.005907 -0.051631 -0.203297 -0.007137 -0.047743 -0.202923 -0.007006 -0.047576 -0.205969 -0.006747 -0.048911 -0.203733 -0.007913999999999999 -0.046071 -0.198559 -0.007719 -0.046041 -0.201937 -0.007688 -0.046663 -0.198933 -0.007881000000000001 -0.0455 -0.20169 -0.007719 -0.046041 -0.201937 -0.008132 -0.0455 -0.198288 -0.007006 -0.047576 -0.205969 -0.0067 -0.048643 -0.206511 -0.006747 -0.048911 -0.203733 -0.006851 -0.047388 -0.208974 -0.006643 -0.048346 -0.209237 -0.0067 -0.048643 -0.206511 -0.006768 -0.047286 -0.210461 -0.006614 -0.048185 -0.210579 -0.006643 -0.048346 -0.209237 -0.00668 -0.047178 -0.211936 -0.006585 -0.048017 -0.211907 -0.006614 -0.048185 -0.210579 -0.00668 -0.047178 -0.211936 0.006594 -0.048017 -0.211907 -0.006585 -0.048017 -0.211907 0.003464 -0.051719 -0.17186 0.004966 -0.051645 -0.174173 0.007018 -0.048197 -0.173778 0.003464 -0.051719 -0.17186 0.002361 -0.051749 -0.171009 0.001021 -0.051774 -0.17066 -0.000809997 -0.060018 -0.198243 0.001021 -0.051774 -0.17066 -0.001497 -0.051808 -0.171922 -0.001497 -0.051808 -0.171922 -0.003079 -0.051821 -0.174412 -0.001526 -0.059974 -0.199196 -0.005148 -0.050096 -0.176876 -0.004628 -0.051775 -0.180071 -0.003079 -0.051821 -0.174412 -0.006417 -0.048397 -0.180688 -0.005148 -0.050096 -0.176876 -0.005697 -0.048441 -0.17414 -0.007549 -0.046834 -0.185563 -0.006417 -0.048397 -0.180688 -0.007022 -0.046871 -0.178806 -0.007849 -0.046147 -0.184936 -0.008064 -0.046117 -0.191763 -0.007549 -0.046834 -0.185563 -0.007849 -0.046147 -0.184936 -0.008238000000000001 -0.0455 -0.186491 -0.008064 -0.046117 -0.191763 0.007566 -0.048734 -0.199968 0.006594 -0.048017 -0.211907 0.007854 -0.047555 -0.199136 0.00768 -0.049338 -0.188129 0.007566 -0.048734 -0.199968 0.008007 -0.047907 -0.18642 0.00768 -0.049338 -0.188129 0.007018 -0.048197 -0.173778 0.006779 -0.049792 -0.176341 -0.005907 -0.051631 -0.203297 -0.006747 -0.048911 -0.203733 -0.00637 -0.050075 -0.204616 -0.007688 -0.046663 -0.198933 -0.005907 -0.051631 -0.203297 -0.00723 -0.048129 -0.193561 -0.007913999999999999 -0.046071 -0.198559 -0.007688 -0.046663 -0.198933 -0.007789 -0.046765 -0.192279 -0.008132 -0.0455 -0.198288 -0.007719 -0.046041 -0.201937 -0.007913999999999999 -0.046071 -0.198559 -0.006747 -0.048911 -0.203733 -0.0067 -0.048643 -0.206511 -0.00637 -0.050075 -0.204616 -0.0067 -0.048643 -0.206511 -0.006643 -0.048346 -0.209237 -0.006403 -0.049708 -0.207099 -0.006643 -0.048346 -0.209237 -0.006614 -0.048185 -0.210579 -0.006439 -0.049301 -0.20952 -0.006614 -0.048185 -0.210579 -0.006585 -0.048017 -0.211907 -0.006462 -0.049083 -0.210707 0.006594 -0.048017 -0.211907 0.0065 -0.048856 -0.211878 -0.006585 -0.048017 -0.211907 0.004966 -0.051645 -0.174173 0.006779 -0.049792 -0.176341 0.007018 -0.048197 -0.173778 0.004966 -0.051645 -0.174173 0.003464 -0.051719 -0.17186 0.000826003 -0.060006 -0.197849 0.000260003 -0.06002 -0.197738 0.003464 -0.051719 -0.17186 0.001021 -0.051774 -0.17066 -0.000809997 -0.060018 -0.198243 -0.001497 -0.051808 -0.171922 -0.001526 -0.059974 -0.199196 0.001021 -0.051774 -0.17066 -0.000809997 -0.060018 -0.198243 0.000260003 -0.06002 -0.197738 -0.003079 -0.051821 -0.174412 -0.002348 -0.059751 -0.201315 -0.001526 -0.059974 -0.199196 -0.004628 -0.051775 -0.180071 -0.002348 -0.059751 -0.201315 -0.003079 -0.051821 -0.174412 -0.005826 -0.050002 -0.183062 -0.004628 -0.051775 -0.180071 -0.005148 -0.050096 -0.176876 -0.006417 -0.048397 -0.180688 -0.005826 -0.050002 -0.183062 -0.005148 -0.050096 -0.176876 -0.007549 -0.046834 -0.185563 -0.006945 -0.048295 -0.187168 -0.006417 -0.048397 -0.180688 -0.008064 -0.046117 -0.191763 -0.007789 -0.046765 -0.192279 -0.007549 -0.046834 -0.185563 -0.008311000000000001 -0.0455 -0.191347 -0.008064 -0.046117 -0.191763 -0.008238000000000001 -0.0455 -0.186491 0.0065 -0.048856 -0.211878 0.006594 -0.048017 -0.211907 0.007566 -0.048734 -0.199968 0.007216 -0.049958 -0.20099 0.007566 -0.048734 -0.199968 0.00768 -0.049338 -0.188129 0.00768 -0.049338 -0.188129 0.006779 -0.049792 -0.176341 0.00724 -0.05083 -0.190196 -0.00637 -0.050075 -0.204616 -0.006015 -0.051216 -0.205534 -0.005907 -0.051631 -0.203297 -0.00723 -0.048129 -0.193561 -0.007789 -0.046765 -0.192279 -0.007688 -0.046663 -0.198933 -0.005177 -0.053637 -0.200504 -0.00723 -0.048129 -0.193561 -0.005907 -0.051631 -0.203297 -0.008064 -0.046117 -0.191763 -0.007913999999999999 -0.046071 -0.198559 -0.007789 -0.046765 -0.192279 -0.008133 -0.0455 -0.198247 -0.007913999999999999 -0.046071 -0.198559 -0.008132 -0.0455 -0.198288 -0.0067 -0.048643 -0.206511 -0.006403 -0.049708 -0.207099 -0.00637 -0.050075 -0.204616 -0.006643 -0.048346 -0.209237 -0.006439 -0.049301 -0.20952 -0.006403 -0.049708 -0.207099 -0.006614 -0.048185 -0.210579 -0.006462 -0.049083 -0.210707 -0.006439 -0.049301 -0.20952 -0.006585 -0.048017 -0.211907 -0.00649 -0.048856 -0.211878 -0.006462 -0.049083 -0.210707 -0.006585 -0.048017 -0.211907 0.0065 -0.048856 -0.211878 -0.00649 -0.048856 -0.211878 0.004966 -0.051645 -0.174173 0.006391 -0.051443 -0.179421 0.006779 -0.049792 -0.176341 0.004966 -0.051645 -0.174173 0.000826003 -0.060006 -0.197849 0.001305 -0.059981 -0.198144 0.003464 -0.051719 -0.17186 0.000260003 -0.06002 -0.197738 0.000826003 -0.060006 -0.197849 -0.000809997 -0.060018 -0.198243 -0.001526 -0.059974 -0.199196 -0.000722997 -0.061428 -0.205101 0.000260003 -0.06002 -0.197738 -0.000809997 -0.060018 -0.198243 -3.59977e-05 -0.061442 -0.204842 -0.001526 -0.059974 -0.199196 -0.002348 -0.059751 -0.201315 -0.001232 -0.061373 -0.205581 -0.002846 -0.059333 -0.203396 -0.002348 -0.059751 -0.201315 -0.004628 -0.051775 -0.180071 -0.00526 -0.051624 -0.185793 -0.004628 -0.051775 -0.180071 -0.00533186 -0.0509422 -0.182932 -0.005826 -0.050002 -0.183062 -0.00526 -0.051624 -0.185793 -0.00533186 -0.0509422 -0.182932 -0.004628 -0.051775 -0.180071 -0.005826 -0.050002 -0.183062 -0.00533186 -0.0509422 -0.182932 -0.006945 -0.048295 -0.187168 -0.005826 -0.050002 -0.183062 -0.006417 -0.048397 -0.180688 -0.007789 -0.046765 -0.192279 -0.006945 -0.048295 -0.187168 -0.007549 -0.046834 -0.185563 -0.008311000000000001 -0.0455 -0.191347 -0.008326999999999999 -0.0455 -0.192391 -0.008064 -0.046117 -0.191763 0.006398 -0.049694 -0.211849 0.0065 -0.048856 -0.211878 0.007566 -0.048734 -0.199968 0.007216 -0.049958 -0.20099 0.006398 -0.049694 -0.211849 0.007566 -0.048734 -0.199968 0.00724 -0.05083 -0.190196 0.007216 -0.049958 -0.20099 0.00768 -0.049338 -0.188129 0.00724 -0.05083 -0.190196 0.006779 -0.049792 -0.176341 0.006391 -0.051443 -0.179421 -0.005907 -0.051631 -0.203297 -0.00577645 -0.0520142 -0.204416 -0.005527 -0.052809 -0.204533 -0.005527 -0.052809 -0.204533 -0.00577645 -0.0520142 -0.204416 -0.006015 -0.051216 -0.205534 -0.006015 -0.051216 -0.205534 -0.00577645 -0.0520142 -0.204416 -0.005907 -0.051631 -0.203297 -0.00637 -0.050075 -0.204616 -0.006403 -0.049708 -0.207099 -0.006015 -0.051216 -0.205534 -0.007789 -0.046765 -0.192279 -0.00723 -0.048129 -0.193561 -0.006945 -0.048295 -0.187168 -0.005907 -0.051631 -0.203297 -0.005527 -0.052809 -0.204533 -0.005177 -0.053637 -0.200504 -0.00723 -0.048129 -0.193561 -0.005177 -0.053637 -0.200504 -0.006349 -0.04982 -0.189146 -0.008326999999999999 -0.0455 -0.192391 -0.007913999999999999 -0.046071 -0.198559 -0.008064 -0.046117 -0.191763 -0.008133 -0.0455 -0.198247 -0.007913999999999999 -0.046071 -0.198559 -0.008324349999999999 -0.0455 -0.192471 -0.008326999999999999 -0.0455 -0.192391 -0.007913999999999999 -0.046071 -0.198559 -0.008324349999999999 -0.0455 -0.192471 -0.006403 -0.049708 -0.207099 -0.006439 -0.049301 -0.20952 -0.006123 -0.050755 -0.207706 -0.006439 -0.049301 -0.20952 -0.006462 -0.049083 -0.210707 -0.006244 -0.050248 -0.209812 -0.006462 -0.049083 -0.210707 -0.00649 -0.048856 -0.211878 -0.006313 -0.049977 -0.210839 0.0065 -0.048856 -0.211878 0.006398 -0.049694 -0.211849 -0.00649 -0.048856 -0.211878 0.004966 -0.051645 -0.174173 0.001305 -0.059981 -0.198144 0.006391 -0.051443 -0.179421 0.001305 -0.059981 -0.198144 0.000826003 -0.060006 -0.197849 0.000643003 -0.061415 -0.205032 0.000826003 -0.060006 -0.197849 0.000260003 -0.06002 -0.197738 0.000325003 -0.061433 -0.204892 -0.000809997 -0.060018 -0.198243 -0.000722997 -0.061428 -0.205101 -3.59977e-05 -0.061442 -0.204842 -0.000722997 -0.061428 -0.205101 -0.001526 -0.059974 -0.199196 -0.001232 -0.061373 -0.205581 0.000260003 -0.06002 -0.197738 -3.59977e-05 -0.061442 -0.204842 0.000325003 -0.061433 -0.204892 -0.001232 -0.061373 -0.205581 -0.002348 -0.059751 -0.201315 -0.00194 -0.061133 -0.20664 -0.002846 -0.059333 -0.203396 -0.00194 -0.061133 -0.20664 -0.002348 -0.059751 -0.201315 -0.00526 -0.051624 -0.185793 -0.002846 -0.059333 -0.203396 -0.004628 -0.051775 -0.180071 -0.006349 -0.04982 -0.189146 -0.00526 -0.051624 -0.185793 -0.005826 -0.050002 -0.183062 -0.006945 -0.048295 -0.187168 -0.006349 -0.04982 -0.189146 -0.005826 -0.050002 -0.183062 0.006296 -0.050532 -0.211819 0.006398 -0.049694 -0.211849 0.007216 -0.049958 -0.20099 0.007216 -0.049958 -0.20099 0.00724 -0.05083 -0.190196 0.006828 -0.051191 -0.20214 0.00672 -0.052327 -0.192509 0.00724 -0.05083 -0.190196 0.006391 -0.051443 -0.179421 -0.005691 -0.052317 -0.206455 -0.005527 -0.052809 -0.204533 -0.00577448 -0.0520135 -0.205494 -0.006015 -0.051216 -0.205534 -0.005691 -0.052317 -0.206455 -0.00577448 -0.0520135 -0.205494 -0.005527 -0.052809 -0.204533 -0.006015 -0.051216 -0.205534 -0.00577448 -0.0520135 -0.205494 -0.006403 -0.049708 -0.207099 -0.006123 -0.050755 -0.207706 -0.006015 -0.051216 -0.205534 -0.00723 -0.048129 -0.193561 -0.006349 -0.04982 -0.189146 -0.006945 -0.048295 -0.187168 -0.004422 -0.055972 -0.204091 -0.005177 -0.053637 -0.200504 -0.005527 -0.052809 -0.204533 -0.005177 -0.053637 -0.200504 -0.005775 -0.051353 -0.191386 -0.006349 -0.04982 -0.189146 -0.006439 -0.049301 -0.20952 -0.006244 -0.050248 -0.209812 -0.006123 -0.050755 -0.207706 -0.006462 -0.049083 -0.210707 -0.006313 -0.049977 -0.210839 -0.006244 -0.050248 -0.209812 -0.00649 -0.048856 -0.211878 -0.006389 -0.049694 -0.211849 -0.006313 -0.049977 -0.210839 -0.00649 -0.048856 -0.211878 0.006398 -0.049694 -0.211849 -0.006389 -0.049694 -0.211849 0.006391 -0.051443 -0.179421 0.001305 -0.059981 -0.198144 0.002006 -0.059901 -0.198958 0.001154 -0.061348 -0.205423 0.001305 -0.059981 -0.198144 0.000643003 -0.061415 -0.205032 0.000826003 -0.060006 -0.197849 0.000325003 -0.061433 -0.204892 0.000643003 -0.061415 -0.205032 -3.59977e-05 -0.061442 -0.204842 -0.000722997 -0.061428 -0.205101 0.000380002 -0.06293600000000001 -0.211386 -0.000722997 -0.061428 -0.205101 -0.001232 -0.061373 -0.205581 0.000192002 -0.062968 -0.211385 0.000325003 -0.061433 -0.204892 -3.59977e-05 -0.061442 -0.204842 0.000755002 -0.062872 -0.211388 -0.001232 -0.061373 -0.205581 -0.00194 -0.061133 -0.20664 5.00208e-06 -0.063 -0.211384 -0.00248 -0.060709 -0.207675 -0.00194 -0.061133 -0.20664 -0.002846 -0.059333 -0.203396 -0.002846 -0.059333 -0.203396 -0.00526 -0.051624 -0.185793 -0.00393 -0.056761 -0.201101 -0.006349 -0.04982 -0.189146 -0.005775 -0.051353 -0.191386 -0.00526 -0.051624 -0.185793 0.006398 -0.049694 -0.211849 0.006296 -0.050532 -0.211819 -0.006389 -0.049694 -0.211849 0.006828 -0.051191 -0.20214 0.006296 -0.050532 -0.211819 0.007216 -0.049958 -0.20099 0.00672 -0.052327 -0.192509 0.006828 -0.051191 -0.20214 0.00724 -0.05083 -0.190196 0.00672 -0.052327 -0.192509 0.006391 -0.051443 -0.179421 0.002006 -0.059901 -0.198958 -0.004902 -0.05495 -0.206883 -0.005527 -0.052809 -0.204533 -0.005691 -0.052317 -0.206455 -0.005691 -0.052317 -0.206455 -0.006015 -0.051216 -0.205534 -0.006123 -0.050755 -0.207706 -0.005177 -0.053637 -0.200504 -0.004422 -0.055972 -0.204091 -0.00393 -0.056761 -0.201101 -0.005527 -0.052809 -0.204533 -0.004902 -0.05495 -0.206883 -0.004422 -0.055972 -0.204091 -0.005177 -0.053637 -0.200504 -0.005236 -0.052848 -0.193788 -0.005775 -0.051353 -0.191386 -0.006123 -0.050755 -0.207706 -0.006244 -0.050248 -0.209812 -0.005864 -0.051774 -0.208312 -0.006244 -0.050248 -0.209812 -0.006313 -0.049977 -0.210839 -0.00606 -0.051179 -0.210101 -0.006313 -0.049977 -0.210839 -0.006389 -0.049694 -0.211849 -0.00617 -0.050862 -0.210969 0.002006 -0.059901 -0.198958 0.001305 -0.059981 -0.198144 0.001154 -0.061348 -0.205423 0.001154 -0.061348 -0.205423 0.000643003 -0.061415 -0.205032 0.001498 -0.062682 -0.211395 0.000643003 -0.061415 -0.205032 0.000325003 -0.061433 -0.204892 0.001305 -0.062779 -0.211392 -3.59977e-05 -0.061442 -0.204842 0.000380002 -0.06293600000000001 -0.211386 0.000755002 -0.062872 -0.211388 -0.000722997 -0.061428 -0.205101 0.000192002 -0.062968 -0.211385 0.000380002 -0.06293600000000001 -0.211386 -0.001232 -0.061373 -0.205581 5.00208e-06 -0.063 -0.211384 0.000192002 -0.062968 -0.211385 0.000325003 -0.061433 -0.204892 0.000755002 -0.062872 -0.211388 0.001305 -0.062779 -0.211392 -0.00194 -0.061133 -0.20664 -0.000370998 -0.06293600000000001 -0.211386 5.00208e-06 -0.063 -0.211384 -0.00194 -0.061133 -0.20664 -0.00248 -0.060709 -0.207675 -0.000370998 -0.06293600000000001 -0.211386 -0.003364 -0.058702 -0.205361 -0.00248 -0.060709 -0.207675 -0.002846 -0.059333 -0.203396 -0.00393 -0.056761 -0.201101 -0.003364 -0.058702 -0.205361 -0.002846 -0.059333 -0.203396 -0.004744 -0.054266 -0.196261 -0.00393 -0.056761 -0.201101 -0.00526 -0.051624 -0.185793 -0.005775 -0.051353 -0.191386 -0.005236 -0.052848 -0.193788 -0.00526 -0.051624 -0.185793 -0.006389 -0.049694 -0.211849 0.006296 -0.050532 -0.211819 -0.006287 -0.050532 -0.211819 0.006092 -0.052208 -0.211761 0.006296 -0.050532 -0.211819 0.006828 -0.051191 -0.20214 0.006423 -0.052404 -0.203362 0.006828 -0.051191 -0.20214 0.00672 -0.052327 -0.192509 0.002006 -0.059901 -0.198958 0.002854 -0.059619 -0.200787 0.00672 -0.052327 -0.192509 -0.005691 -0.052317 -0.206455 -0.005155 -0.054352 -0.208195 -0.004902 -0.05495 -0.206883 -0.006123 -0.050755 -0.207706 -0.005864 -0.051774 -0.208312 -0.005691 -0.052317 -0.206455 -0.004422 -0.055972 -0.204091 -0.003364 -0.058702 -0.205361 -0.00393 -0.056761 -0.201101 -0.00393 -0.056761 -0.201101 -0.004744 -0.054266 -0.196261 -0.005177 -0.053637 -0.200504 -0.004902 -0.05495 -0.206883 -0.003909 -0.057846 -0.207193 -0.004422 -0.055972 -0.204091 -0.004744 -0.054266 -0.196261 -0.005236 -0.052848 -0.193788 -0.005177 -0.053637 -0.200504 -0.006244 -0.050248 -0.209812 -0.00606 -0.051179 -0.210101 -0.005864 -0.051774 -0.208312 -0.006313 -0.049977 -0.210839 -0.00617 -0.050862 -0.210969 -0.00606 -0.051179 -0.210101 -0.006389 -0.049694 -0.211849 -0.006287 -0.050532 -0.211819 -0.00617 -0.050862 -0.210969 0.002006 -0.059901 -0.198958 0.001154 -0.061348 -0.205423 0.001922 -0.061093 -0.206303 0.002432 -0.062215 -0.211411 0.001154 -0.061348 -0.205423 0.001498 -0.062682 -0.211395 0.001498 -0.062682 -0.211395 0.000643003 -0.061415 -0.205032 0.001305 -0.062779 -0.211392 0.000380002 -0.06293600000000001 -0.211386 0.000755002 -0.062872 -0.211388 -0.000370998 -0.06293600000000001 -0.211386 0.000192002 -0.062968 -0.211385 0.000380002 -0.06293600000000001 -0.211386 5.00208e-06 -0.063 -0.211384 0.000755002 -0.062872 -0.211388 -0.000745998 -0.062872 -0.211388 0.001305 -0.062779 -0.211392 5.00208e-06 -0.063 -0.211384 0.000380002 -0.06293600000000001 -0.211386 -0.000370998 -0.06293600000000001 -0.211386 -0.00248 -0.060709 -0.207675 -0.000745998 -0.062872 -0.211388 -0.000370998 -0.06293600000000001 -0.211386 -0.003043 -0.060087 -0.208643 -0.00248 -0.060709 -0.207675 -0.003364 -0.058702 -0.205361 -0.004744 -0.054266 -0.196261 -0.00526 -0.051624 -0.185793 -0.005236 -0.052848 -0.193788 0.006296 -0.050532 -0.211819 0.006092 -0.052208 -0.211761 -0.006287 -0.050532 -0.211819 0.006423 -0.052404 -0.203362 0.006092 -0.052208 -0.211761 0.006828 -0.051191 -0.20214 0.006423 -0.052404 -0.203362 0.00672 -0.052327 -0.192509 0.006155 -0.05378 -0.194963 0.002854 -0.059619 -0.200787 0.002006 -0.059901 -0.198958 0.001922 -0.061093 -0.206303 0.00672 -0.052327 -0.192509 0.002854 -0.059619 -0.200787 0.006155 -0.05378 -0.194963 -0.005155 -0.054352 -0.208195 -0.004478 -0.056754 -0.208874 -0.004902 -0.05495 -0.206883 -0.005691 -0.052317 -0.206455 -0.005864 -0.051774 -0.208312 -0.005155 -0.054352 -0.208195 -0.004422 -0.055972 -0.204091 -0.003909 -0.057846 -0.207193 -0.003364 -0.058702 -0.205361 -0.004902 -0.05495 -0.206883 -0.004478 -0.056754 -0.208874 -0.003909 -0.057846 -0.207193 -0.005864 -0.051774 -0.208312 -0.00606 -0.051179 -0.210101 -0.005429 -0.053695 -0.209446 -0.00606 -0.051179 -0.210101 -0.00617 -0.050862 -0.210969 -0.005735 -0.05298 -0.210636 -0.00617 -0.050862 -0.210969 -0.006287 -0.050532 -0.211819 -0.005903 -0.052601 -0.211207 0.001922 -0.061093 -0.206303 0.001154 -0.061348 -0.205423 0.002432 -0.062215 -0.211411 -0.002423 -0.062215 -0.211411 0.002432 -0.062215 -0.211411 0.001498 -0.062682 -0.211395 0.001305 -0.062779 -0.211392 -0.002423 -0.062215 -0.211411 0.001498 -0.062682 -0.211395 -0.000370998 -0.06293600000000001 -0.211386 0.000755002 -0.062872 -0.211388 -0.000745998 -0.062872 -0.211388 -0.000745998 -0.062872 -0.211388 -0.001295 -0.062779 -0.211392 0.001305 -0.062779 -0.211392 -0.000745998 -0.062872 -0.211388 -0.00248 -0.060709 -0.207675 -0.003043 -0.060087 -0.208643 -0.003909 -0.057846 -0.207193 -0.003043 -0.060087 -0.208643 -0.003364 -0.058702 -0.205361 -0.006287 -0.050532 -0.211819 0.006092 -0.052208 -0.211761 -0.006083 -0.052208 -0.211761 0.005878 -0.053883 -0.211702 0.006092 -0.052208 -0.211761 0.006423 -0.052404 -0.203362 0.005633 -0.054673 -0.205832 0.006423 -0.052404 -0.203362 0.006155 -0.05378 -0.194963 0.002854 -0.059619 -0.200787 0.001922 -0.061093 -0.206303 0.003232 -0.060051 -0.208075 0.002854 -0.059619 -0.200787 0.005002 -0.056411 -0.199929 0.006155 -0.05378 -0.194963 -0.005155 -0.054352 -0.208195 -0.004784 -0.056121 -0.209651 -0.004478 -0.056754 -0.208874 -0.005864 -0.051774 -0.208312 -0.005429 -0.053695 -0.209446 -0.005155 -0.054352 -0.208195 -0.004478 -0.056754 -0.208874 -0.003633 -0.059259 -0.209536 -0.003909 -0.057846 -0.207193 -0.00606 -0.051179 -0.210101 -0.005735 -0.05298 -0.210636 -0.005429 -0.053695 -0.209446 -0.00617 -0.050862 -0.210969 -0.005903 -0.052601 -0.211207 -0.005735 -0.05298 -0.210636 -0.006083 -0.052208 -0.211761 -0.005903 -0.052601 -0.211207 -0.006287 -0.050532 -0.211819 0.002888 -0.061795 -0.211426 0.001922 -0.061093 -0.206303 0.002432 -0.062215 -0.211411 0.002432 -0.062215 -0.211411 -0.002423 -0.062215 -0.211411 -0.002879 -0.061795 -0.211426 0.001305 -0.062779 -0.211392 -0.001295 -0.062779 -0.211392 -0.002423 -0.062215 -0.211411 -0.003043 -0.060087 -0.208643 -0.001295 -0.062779 -0.211392 -0.000745998 -0.062872 -0.211388 -0.003909 -0.057846 -0.207193 -0.003633 -0.059259 -0.209536 -0.003043 -0.060087 -0.208643 0.006092 -0.052208 -0.211761 0.005878 -0.053883 -0.211702 -0.006083 -0.052208 -0.211761 0.005878 -0.053883 -0.211702 0.006423 -0.052404 -0.203362 0.005633 -0.054673 -0.205832 0.005633 -0.054673 -0.205832 0.006155 -0.05378 -0.194963 0.005002 -0.056411 -0.199929 0.002888 -0.061795 -0.211426 0.003232 -0.060051 -0.208075 0.001922 -0.061093 -0.206303 0.003232 -0.060051 -0.208075 0.003978 -0.058521 -0.20446 0.002854 -0.059619 -0.200787 0.002854 -0.059619 -0.200787 0.003978 -0.058521 -0.20446 0.005002 -0.056411 -0.199929 -0.004784 -0.056121 -0.209651 -0.004248 -0.058222 -0.210342 -0.004478 -0.056754 -0.208874 -0.005155 -0.054352 -0.208195 -0.005429 -0.053695 -0.209446 -0.004784 -0.056121 -0.209651 -0.004478 -0.056754 -0.208874 -0.004248 -0.058222 -0.210342 -0.003633 -0.059259 -0.209536 -0.005429 -0.053695 -0.209446 -0.005735 -0.05298 -0.210636 -0.005114 -0.05543 -0.210383 -0.005735 -0.05298 -0.210636 -0.005903 -0.052601 -0.211207 -0.005473 -0.054684 -0.211067 -0.006083 -0.052208 -0.211761 -0.005667 -0.05429 -0.211391 -0.005903 -0.052601 -0.211207 0.002888 -0.061795 -0.211426 0.002432 -0.062215 -0.211411 -0.002879 -0.061795 -0.211426 -0.004573 -0.057627 -0.210708 -0.002879 -0.061795 -0.211426 -0.002423 -0.062215 -0.211411 -0.002423 -0.062215 -0.211411 -0.001295 -0.062779 -0.211392 -0.003633 -0.059259 -0.209536 -0.003043 -0.060087 -0.208643 -0.003633 -0.059259 -0.209536 -0.001295 -0.062779 -0.211392 -0.006083 -0.052208 -0.211761 0.005878 -0.053883 -0.211702 -0.005868 -0.053883 -0.211702 0.005878 -0.053883 -0.211702 0.005633 -0.054673 -0.205832 0.005663 -0.055557 -0.211644 0.004962 -0.056629 -0.208069 0.005633 -0.054673 -0.205832 0.005002 -0.056411 -0.199929 0.003962 -0.060806 -0.211461 0.003232 -0.060051 -0.208075 0.002888 -0.061795 -0.211426 0.003232 -0.060051 -0.208075 0.004481 -0.058223 -0.209836 0.003978 -0.058521 -0.20446 0.003978 -0.058521 -0.20446 0.004962 -0.056629 -0.208069 0.005002 -0.056411 -0.199929 -0.004784 -0.056121 -0.209651 -0.004573 -0.057627 -0.210708 -0.004248 -0.058222 -0.210342 -0.005429 -0.053695 -0.209446 -0.005114 -0.05543 -0.210383 -0.004784 -0.056121 -0.209651 -0.003633 -0.059259 -0.209536 -0.004248 -0.058222 -0.210342 -0.002423 -0.062215 -0.211411 -0.005473 -0.054684 -0.211067 -0.005114 -0.05543 -0.210383 -0.005735 -0.05298 -0.210636 -0.005667 -0.05429 -0.211391 -0.005473 -0.054684 -0.211067 -0.005903 -0.052601 -0.211207 -0.005868 -0.053883 -0.211702 -0.005667 -0.05429 -0.211391 -0.006083 -0.052208 -0.211761 0.002888 -0.061795 -0.211426 -0.002879 -0.061795 -0.211426 -0.00353 -0.061195 -0.211447 -0.004248 -0.058222 -0.210342 -0.004573 -0.057627 -0.210708 -0.002423 -0.062215 -0.211411 -0.004573 -0.057627 -0.210708 -0.004913 -0.056983 -0.211048 -0.002879 -0.061795 -0.211426 0.005878 -0.053883 -0.211702 0.005663 -0.055557 -0.211644 -0.005868 -0.053883 -0.211702 0.004962 -0.056629 -0.208069 0.005663 -0.055557 -0.211644 0.005633 -0.054673 -0.205832 0.003232 -0.060051 -0.208075 0.003962 -0.060806 -0.211461 0.00399025 -0.059424 -0.209768 0.004481 -0.058223 -0.209836 0.003232 -0.060051 -0.208075 0.00399025 -0.059424 -0.209768 0.003962 -0.060806 -0.211461 0.004481 -0.058223 -0.209836 0.00399025 -0.059424 -0.209768 0.003962 -0.060806 -0.211461 0.002888 -0.061795 -0.211426 -0.00353 -0.061195 -0.211447 0.004481 -0.058223 -0.209836 0.004962 -0.056629 -0.208069 0.003978 -0.058521 -0.20446 -0.004784 -0.056121 -0.209651 -0.005114 -0.05543 -0.210383 -0.004573 -0.057627 -0.210708 -0.004913 -0.056983 -0.211048 -0.005114 -0.05543 -0.210383 -0.005473 -0.054684 -0.211067 -0.005271 -0.056293 -0.21136 -0.005473 -0.054684 -0.211067 -0.005667 -0.05429 -0.211391 -0.005459 -0.05593 -0.211506 -0.005667 -0.05429 -0.211391 -0.005868 -0.053883 -0.211702 -0.004913 -0.056983 -0.211048 -0.00353 -0.061195 -0.211447 -0.002879 -0.061795 -0.211426 -0.004913 -0.056983 -0.211048 -0.004573 -0.057627 -0.210708 -0.005114 -0.05543 -0.210383 -0.005868 -0.053883 -0.211702 0.005663 -0.055557 -0.211644 -0.005654 -0.055557 -0.211644 0.004962 -0.056629 -0.208069 0.005551 -0.056394 -0.211615 0.005663 -0.055557 -0.211644 0.003962 -0.060806 -0.211461 0.004149 -0.060522 -0.211471 0.004481 -0.058223 -0.209836 0.003962 -0.060806 -0.211461 -0.00353 -0.061195 -0.211447 -0.003952 -0.060806 -0.211461 0.005551 -0.056394 -0.211615 0.004962 -0.056629 -0.208069 0.0049162 -0.0572633 -0.209842 0.004481 -0.058223 -0.209836 0.005551 -0.056394 -0.211615 0.0049162 -0.0572633 -0.209842 0.004962 -0.056629 -0.208069 0.004481 -0.058223 -0.209836 0.0049162 -0.0572633 -0.209842 -0.005271 -0.056293 -0.21136 -0.004913 -0.056983 -0.211048 -0.005473 -0.054684 -0.211067 -0.005271 -0.056293 -0.21136 -0.005667 -0.05429 -0.211391 -0.005459 -0.05593 -0.211506 -0.005459 -0.05593 -0.211506 -0.005868 -0.053883 -0.211702 -0.005654 -0.055557 -0.211644 -0.004913 -0.056983 -0.211048 -0.005271 -0.056293 -0.21136 -0.00353 -0.061195 -0.211447 0.005663 -0.055557 -0.211644 0.005551 -0.056394 -0.211615 -0.005654 -0.055557 -0.211644 0.004149 -0.060522 -0.211471 0.004682 -0.059713 -0.211499 0.004481 -0.058223 -0.209836 0.004149 -0.060522 -0.211471 0.003962 -0.060806 -0.211461 -0.004139 -0.060522 -0.211471 -0.004139 -0.060522 -0.211471 0.003962 -0.060806 -0.211461 -0.003952 -0.060806 -0.211461 -0.003952 -0.060806 -0.211461 -0.00353 -0.061195 -0.211447 -0.005271 -0.056293 -0.21136 0.004481 -0.058223 -0.209836 0.005439 -0.057231 -0.211585 0.005551 -0.056394 -0.211615 -0.005271 -0.056293 -0.21136 -0.005459 -0.05593 -0.211506 -0.003952 -0.060806 -0.211461 -0.005459 -0.05593 -0.211506 -0.005654 -0.055557 -0.211644 -0.004139 -0.060522 -0.211471 -0.005654 -0.055557 -0.211644 0.005551 -0.056394 -0.211615 -0.005542 -0.056394 -0.211615 0.004481 -0.058223 -0.209836 0.004682 -0.059713 -0.211499 0.005327 -0.058068 -0.211556 0.004682 -0.059713 -0.211499 0.004149 -0.060522 -0.211471 -0.004673 -0.059713 -0.211499 -0.004406 -0.060118 -0.211485 0.004149 -0.060522 -0.211471 -0.004139 -0.060522 -0.211471 -0.005459 -0.05593 -0.211506 -0.004139 -0.060522 -0.211471 -0.003952 -0.060806 -0.211461 0.004481 -0.058223 -0.209836 0.005327 -0.058068 -0.211556 0.005439 -0.057231 -0.211585 0.005551 -0.056394 -0.211615 0.005439 -0.057231 -0.211585 -0.005542 -0.056394 -0.211615 -0.005654 -0.055557 -0.211644 -0.005542 -0.056394 -0.211615 -0.004139 -0.060522 -0.211471 0.005327 -0.058068 -0.211556 0.004682 -0.059713 -0.211499 -0.005206 -0.058904 -0.211527 -0.004673 -0.059713 -0.211499 0.004149 -0.060522 -0.211471 -0.004406 -0.060118 -0.211485 -0.004939 -0.059309 -0.211513 0.004682 -0.059713 -0.211499 -0.004673 -0.059713 -0.211499 -0.005542 -0.056394 -0.211615 -0.004406 -0.060118 -0.211485 -0.004139 -0.060522 -0.211471 0.005439 -0.057231 -0.211585 0.005327 -0.058068 -0.211556 -0.00543 -0.057231 -0.211586 -0.005542 -0.056394 -0.211615 0.005439 -0.057231 -0.211585 -0.00543 -0.057231 -0.211586 -0.005206 -0.058904 -0.211527 0.004682 -0.059713 -0.211499 -0.005073 -0.059107 -0.21152 -0.005318 -0.058068 -0.211556 0.005327 -0.058068 -0.211556 -0.005206 -0.058904 -0.211527 -0.004673 -0.059713 -0.211499 -0.004406 -0.060118 -0.211485 -0.00543 -0.057231 -0.211586 -0.005073 -0.059107 -0.21152 0.004682 -0.059713 -0.211499 -0.004939 -0.059309 -0.211513 -0.004939 -0.059309 -0.211513 -0.004673 -0.059713 -0.211499 -0.005073 -0.059107 -0.21152 -0.004406 -0.060118 -0.211485 -0.005542 -0.056394 -0.211615 -0.00543 -0.057231 -0.211586 -0.00543 -0.057231 -0.211586 0.005327 -0.058068 -0.211556 -0.005318 -0.058068 -0.211556 -0.005073 -0.059107 -0.21152 -0.005206 -0.058904 -0.211527 -0.004673 -0.059713 -0.211499 -0.005206 -0.058904 -0.211527 -0.004673 -0.059713 -0.211499 -0.005318 -0.058068 -0.211556 -0.00543 -0.057231 -0.211586 -0.005318 -0.058068 -0.211556 -0.004673 -0.059713 -0.211499 0.0037358 0.018 -0.255404 0.000709323 0.018 -0.255883 0.001589 0.018 -0.258157 3.99658e-06 0.018 -0.255995 -0.000701329 0.018 -0.255883 -0.0004916 0.018 -0.25678 0.000709323 0.018 -0.255883 3.99658e-06 0.018 -0.255995 -0.0004916 0.018 -0.25678 -0.004719 0.018 -0.257725 0.001589 0.018 -0.258157 -0.0004916 0.018 -0.25678 -0.00252937 0.018 -0.255594 -0.004719 0.018 -0.257725 -0.0004916 0.018 -0.25678 -0.000701329 0.018 -0.255883 -0.00252937 0.018 -0.255594 -0.0004916 0.018 -0.25678 0.001589 0.018 -0.258157 0.000709323 0.018 -0.255883 -0.0004916 0.018 -0.25678 -0.008449170000000001 0.018 -0.253966 -0.010676 0.018 -0.255608 -0.0071213 0.018 -0.254643 -0.00252937 0.018 -0.255594 -0.006485 0.018 -0.254967 -0.00660269 0.018 -0.255846 -0.004719 0.018 -0.257725 -0.00252937 0.018 -0.255594 -0.00660269 0.018 -0.255846 -0.010676 0.018 -0.255608 -0.004719 0.018 -0.257725 -0.00660269 0.018 -0.255846 -0.006485 0.018 -0.254967 -0.0071213 0.018 -0.254643 -0.00660269 0.018 -0.255846 -0.0071213 0.018 -0.254643 -0.010676 0.018 -0.255608 -0.00660269 0.018 -0.255846 0.0071303 0.018 -0.254643 0.00649389 0.018 -0.254967 0.007779 0.018 -0.25687 0.00988577 0.018 -0.253239 0.0071303 0.018 -0.254643 0.007779 0.018 -0.25687 0.00649389 0.018 -0.254967 0.0037358 0.018 -0.255404 0.00573738 0.018 -0.255698 0.001589 0.018 -0.258157 0.007779 0.018 -0.25687 0.00573738 0.018 -0.255698 0.0037358 0.018 -0.255404 0.001589 0.018 -0.258157 0.00573738 0.018 -0.255698 0.007779 0.018 -0.25687 0.00649389 0.018 -0.254967 0.00573738 0.018 -0.255698 -0.004719 0.018 -0.257725 0.001545 0.0365 -0.257512 0.001589 0.018 -0.258157 -0.0135884 0.018 -0.250735 -0.015842 0.018 -0.251962 -0.012844 0.018 -0.251479 -0.008449170000000001 0.018 -0.253966 -0.012339 0.018 -0.251984 -0.0121456 0.018 -0.253171 -0.010676 0.018 -0.255608 -0.008449170000000001 0.018 -0.253966 -0.0121456 0.018 -0.253171 -0.015842 0.018 -0.251962 -0.010676 0.018 -0.255608 -0.0121456 0.018 -0.253171 -0.012339 0.018 -0.251984 -0.012844 0.018 -0.251479 -0.0121456 0.018 -0.253171 -0.012844 0.018 -0.251479 -0.015842 0.018 -0.251962 -0.0121456 0.018 -0.253171 -0.010676 0.018 -0.255608 -0.004587 0.0365 -0.257093 -0.004719 0.018 -0.257725 0.012348 0.018 -0.251984 0.00988577 0.018 -0.253239 0.013393 0.018 -0.253962 0.012853 0.018 -0.251479 0.012348 0.018 -0.251984 0.013393 0.018 -0.253962 0.0154937 0.018 -0.248838 0.012853 0.018 -0.251479 0.013393 0.018 -0.253962 0.00988577 0.018 -0.253239 0.007779 0.018 -0.25687 0.013393 0.018 -0.253962 0.001589 0.018 -0.258157 0.007563 0.0365 -0.256262 0.007779 0.018 -0.25687 0.001545 0.0365 -0.257512 0.007563 0.0365 -0.256262 0.001589 0.018 -0.258157 -0.004587 0.0365 -0.257093 0.001545 0.0365 -0.257512 -0.004719 0.018 -0.257725 -0.0175653 0.018 -0.246199 -0.019832 0.018 -0.247058 -0.0173092 0.018 -0.246702 -0.0173092 0.018 -0.246702 -0.019832 0.018 -0.247058 -0.016985 0.018 -0.247338 -0.0135884 0.018 -0.250735 -0.016985 0.018 -0.247338 -0.0167102 0.018 -0.249081 -0.015842 0.018 -0.251962 -0.0135884 0.018 -0.250735 -0.0167102 0.018 -0.249081 -0.019832 0.018 -0.247058 -0.015842 0.018 -0.251962 -0.0167102 0.018 -0.249081 -0.016985 0.018 -0.247338 -0.019832 0.018 -0.247058 -0.0167102 0.018 -0.249081 -0.015842 0.018 -0.251962 -0.010379 0.0365 -0.255034 -0.010676 0.018 -0.255608 -0.010379 0.0365 -0.255034 -0.004587 0.0365 -0.257093 -0.010676 0.018 -0.255608 0.0199769 0.018 -0.241484 0.0173181 0.018 -0.246702 0.018013 0.018 -0.249646 0.0154937 0.018 -0.248838 0.013393 0.018 -0.253962 0.018013 0.018 -0.249646 0.016994 0.018 -0.247338 0.0154937 0.018 -0.248838 0.018013 0.018 -0.249646 0.0173181 0.018 -0.246702 0.016994 0.018 -0.247338 0.018013 0.018 -0.249646 0.0199769 0.018 -0.241484 0.022854 0.018 -0.230886 0.0200886 0.018 -0.240779 0.022854 0.018 -0.230886 0.0209 0.018 -0.235652 0.0200886 0.018 -0.240779 0.0199769 0.018 -0.241484 0.018013 0.018 -0.249646 0.022854 0.018 -0.230886 0.007779 0.018 -0.25687 0.01302 0.0365 -0.253434 0.013393 0.018 -0.253962 0.007563 0.0365 -0.256262 0.01302 0.0365 -0.253434 0.007779 0.018 -0.25687 0.007563 0.0365 -0.256262 0.001545 0.0365 -0.257512 0.022218 0.0365 -0.231 0.001545 0.0365 -0.257512 -0.004587 0.0365 -0.257093 0.022218 0.0365 -0.231 -0.020086 0.018 -0.240739 -0.0200797 0.018 -0.240779 -0.02235 0.018 -0.241259 -0.0200797 0.018 -0.240779 -0.02235 0.018 -0.241259 -0.019968 0.018 -0.241484 -0.0175653 0.018 -0.246199 -0.019968 0.018 -0.241484 -0.0199576 0.018 -0.243899 -0.019832 0.018 -0.247058 -0.0175653 0.018 -0.246199 -0.0199576 0.018 -0.243899 -0.02235 0.018 -0.241259 -0.019832 0.018 -0.247058 -0.0199576 0.018 -0.243899 -0.019968 0.018 -0.241484 -0.02235 0.018 -0.241259 -0.0199576 0.018 -0.243899 -0.015842 0.018 -0.251962 -0.019832 0.018 -0.247058 -0.015401 0.0365 -0.25149 -0.015401 0.0365 -0.25149 -0.010379 0.0365 -0.255034 -0.015842 0.018 -0.251962 -0.004587 0.0365 -0.257093 -0.010379 0.0365 -0.255034 0.022218 0.0365 -0.231 0.0208896 0.018 -0.234272 0.021004 0.018 -0.234995 0.022854 0.018 -0.230886 0.021004 0.018 -0.234995 0.0209 0.018 -0.235652 0.022854 0.018 -0.230886 0.021298 0.018 -0.244244 0.022854 0.018 -0.230886 0.018013 0.018 -0.249646 0.013393 0.018 -0.253962 0.017512 0.0365 -0.249239 0.018013 0.018 -0.249646 0.01302 0.0365 -0.253434 0.017512 0.0365 -0.249239 0.013393 0.018 -0.253962 0.01302 0.0365 -0.253434 0.007563 0.0365 -0.256262 0.022218 0.0365 -0.231 -0.0209643 0.018 -0.234795 -0.023211 0.018 -0.234995 -0.020996 0.018 -0.234995 -0.020086 0.018 -0.240739 -0.020996 0.018 -0.234995 -0.0216485 0.018 -0.238027 -0.02235 0.018 -0.241259 -0.020086 0.018 -0.240739 -0.0216485 0.018 -0.238027 -0.023211 0.018 -0.234995 -0.02235 0.018 -0.241259 -0.0216485 0.018 -0.238027 -0.020996 0.018 -0.234995 -0.023211 0.018 -0.234995 -0.0216485 0.018 -0.238027 -0.019832 0.018 -0.247058 -0.02235 0.018 -0.241259 -0.01928 0.0365 -0.246722 -0.015401 0.0365 -0.25149 -0.019832 0.018 -0.247058 -0.01928 0.0365 -0.246722 -0.010379 0.0365 -0.255034 -0.015401 0.0365 -0.25149 0.022218 0.0365 -0.231 0.022854 0.018 -0.230886 0.0207755 0.018 -0.233551 0.0208896 0.018 -0.234272 0.021298 0.018 -0.244244 0.018013 0.018 -0.249646 0.020706 0.0365 -0.243987 0.023004 0.018 -0.238156 0.022854 0.018 -0.230886 0.021298 0.018 -0.244244 0.020706 0.0365 -0.243987 0.018013 0.018 -0.249646 0.017512 0.0365 -0.249239 0.017512 0.0365 -0.249239 0.01302 0.0365 -0.253434 0.022218 0.0365 -0.231 -0.02235 0.018 -0.241259 -0.023211 0.018 -0.234995 -0.021728 0.0365 -0.241084 -0.0209643 0.018 -0.234795 -0.0206847 0.018 -0.23303 -0.021778 0.018 -0.23294 -0.023211 0.018 -0.234995 -0.0209643 0.018 -0.234795 -0.021778 0.018 -0.23294 -0.022845 0.018 -0.230886 -0.023211 0.018 -0.234995 -0.021778 0.018 -0.23294 -0.020345 0.018 -0.230886 -0.022845 0.018 -0.230886 -0.021778 0.018 -0.23294 -0.0206847 0.018 -0.23303 -0.020345 0.018 -0.230886 -0.021778 0.018 -0.23294 -0.01928 0.0365 -0.246722 -0.02235 0.018 -0.241259 -0.021728 0.0365 -0.241084 -0.015401 0.0365 -0.25149 -0.01928 0.0365 -0.246722 0.022218 0.0365 -0.231 0.0202003 0.018 -0.229917 0.0203537 0.018 -0.230886 0.022854 0.018 -0.230886 0.019977 0.018 -0.228506 0.0202003 0.018 -0.229917 0.022854 0.018 -0.230886 0.0191898 0.018 -0.226961 0.019977 0.018 -0.228506 0.022854 0.018 -0.230886 0.0203537 0.018 -0.230886 0.0203885 0.018 -0.231106 0.022854 0.018 -0.230886 0.0203885 0.018 -0.231106 0.0204413 0.018 -0.23144 0.022854 0.018 -0.230886 0.0204413 0.018 -0.23144 0.0204951 0.018 -0.23178 0.022854 0.018 -0.230886 0.0204951 0.018 -0.23178 0.0205521 0.018 -0.23214 0.022854 0.018 -0.230886 0.0205521 0.018 -0.23214 0.020615 0.018 -0.232537 0.022854 0.018 -0.230886 0.020615 0.018 -0.232537 0.0206874 0.018 -0.232995 0.022854 0.018 -0.230886 0.022854 0.018 -0.230886 0.0206874 0.018 -0.232995 0.0207755 0.018 -0.233551 0.022364 0.0365 -0.238068 0.021298 0.018 -0.244244 0.020706 0.0365 -0.243987 0.023004 0.018 -0.231834 0.022854 0.018 -0.230886 0.023004 0.018 -0.238156 0.023004 0.018 -0.238156 0.021298 0.018 -0.244244 0.022364 0.0365 -0.238068 0.020706 0.0365 -0.243987 0.017512 0.0365 -0.249239 0.022218 0.0365 -0.231 -0.021728 0.0365 -0.241084 -0.023211 0.018 -0.234995 -0.022565 0.0365 -0.234995 -0.023211 0.018 -0.234995 -0.022845 0.018 -0.230886 -0.022565 0.0365 -0.234995 -0.0185684 0.018 -0.225759 -0.022845 0.018 -0.230886 -0.019968 0.018 -0.228506 -0.019968 0.018 -0.228506 -0.022845 0.018 -0.230886 -0.020345 0.018 -0.230886 -0.012339 0.018 -0.218006 -0.010355 0.018 -0.216995 -0.0166 0.018 -0.210364 -0.0131204 0.018 -0.218787 -0.012339 0.018 -0.218006 -0.0166 0.018 -0.210364 -0.016985 0.018 -0.222652 -0.0131204 0.018 -0.218787 -0.0166 0.018 -0.210364 -0.0185684 0.018 -0.225759 -0.016985 0.018 -0.222652 -0.0166 0.018 -0.210364 -0.015463 0.018 -0.189843 -0.022845 0.018 -0.230886 -0.0166 0.018 -0.210364 -0.010355 0.018 -0.195314 -0.015463 0.018 -0.189843 -0.0166 0.018 -0.210364 -0.010355 0.018 -0.216995 -0.010355 0.018 -0.195314 -0.0166 0.018 -0.210364 -0.022845 0.018 -0.230886 -0.0185684 0.018 -0.225759 -0.0166 0.018 -0.210364 -0.01928 0.0365 -0.246722 -0.021728 0.0365 -0.241084 0.022218 0.0365 -0.231 0.0191898 0.018 -0.226961 0.022854 0.018 -0.230886 0.018835 0.018 -0.226265 0.022364 0.0365 -0.238068 0.020706 0.0365 -0.243987 0.022218 0.0365 -0.231 0.022854 0.018 -0.230886 0.023004 0.018 -0.231834 0.022218 0.0365 -0.231 0.023004 0.018 -0.231834 0.023004 0.018 -0.238156 0.022364 0.0365 -0.231922 0.023004 0.018 -0.238156 0.022364 0.0365 -0.238068 0.022364 0.0365 -0.231922 -0.021728 0.0365 -0.241084 -0.022565 0.0365 -0.234995 0.022218 0.0365 -0.231 -0.022565 0.0365 -0.234995 -0.022845 0.018 -0.230886 -0.022209 0.0365 -0.231 -0.015463 0.018 -0.189843 -0.022209 0.0365 -0.231 -0.022845 0.018 -0.230886 -0.010355 0.018 -0.195314 -0.010355 0.018 -0.193092 -0.012909 0.018 -0.191418 -0.015463 0.018 -0.189843 -0.010355 0.018 -0.195314 -0.012909 0.018 -0.191418 -0.01486 0.018 -0.187522 -0.015463 0.018 -0.189843 -0.012909 0.018 -0.191418 -0.010355 0.018 -0.192702 -0.01486 0.018 -0.187522 -0.012909 0.018 -0.191418 -0.010355 0.018 -0.193092 -0.010355 0.018 -0.192702 -0.012909 0.018 -0.191418 0.0174398 0.018 -0.223527 0.0178973 0.018 -0.224425 0.022854 0.018 -0.230886 0.0178973 0.018 -0.224425 0.018835 0.018 -0.226265 0.022854 0.018 -0.230886 0.022364 0.0365 -0.231922 0.022364 0.0365 -0.238068 0.022218 0.0365 -0.231 0.014836 0.0365 -0.189957 0.022854 0.018 -0.230886 0.022218 0.0365 -0.231 0.022218 0.0365 -0.231 0.023004 0.018 -0.231834 0.022364 0.0365 -0.231922 -0.022565 0.0365 -0.234995 -0.022209 0.0365 -0.231 0.022218 0.0365 -0.231 -0.014827 0.0365 -0.189957 -0.022209 0.0365 -0.231 -0.015463 0.018 -0.189843 -0.015463 0.018 -0.189843 -0.01486 0.018 -0.187522 -0.014827 0.0365 -0.189957 -0.010355 0.018 -0.192702 -0.010355 0.018 -0.185748 -0.0126075 0.018 -0.187837 -0.01486 0.018 -0.187522 -0.010355 0.018 -0.192702 -0.0126075 0.018 -0.187837 -0.012397 0.018 -0.182972 -0.01486 0.018 -0.187522 -0.0126075 0.018 -0.187837 -0.010355 0.018 -0.185748 -0.012397 0.018 -0.182972 -0.0126075 0.018 -0.187837 0.010364 0.018 -0.210463 0.010364 0.018 -0.213909 0.0157489 0.018 -0.221229 0.010364 0.018 -0.210463 0.0157489 0.018 -0.221229 0.016039 0.018 -0.221507 0.016994 0.018 -0.222652 0.010364 0.018 -0.210463 0.016039 0.018 -0.221507 0.016994 0.018 -0.222652 0.022854 0.018 -0.230886 0.010364 0.018 -0.210463 0.016994 0.018 -0.222652 0.0174398 0.018 -0.223527 0.022854 0.018 -0.230886 0.014836 0.0365 -0.189957 0.015472 0.018 -0.189843 0.022854 0.018 -0.230886 0.013258 0.0365 -0.185453 0.014836 0.0365 -0.189957 0.022218 0.0365 -0.231 0.022218 0.0365 -0.231 -0.022209 0.0365 -0.231 -0.014827 0.0365 -0.189957 -0.014827 0.0365 -0.189957 -0.01486 0.018 -0.187522 -0.014249 0.0365 -0.187732 -0.01486 0.018 -0.187522 -0.012397 0.018 -0.182972 -0.014249 0.0365 -0.187732 -0.010355 0.018 -0.181092 -0.012397 0.018 -0.182972 -0.010355 0.018 -0.185748 -0.00873785 0.018824 -0.179642 -0.011888 0.0365 -0.183369 -0.00932588 0.0185244 -0.180169 -0.010355 0.018 -0.181092 -0.00932588 0.0185244 -0.180169 -0.012397 0.018 -0.182972 -0.00932588 0.0185244 -0.180169 -0.011888 0.0365 -0.183369 -0.012397 0.018 -0.182972 0.010364 0.018 -0.216525 0.0110984 0.018 -0.217369 0.0113634 0.018 -0.217504 0.010364 0.018 -0.213909 0.010364 0.018 -0.216525 0.0113634 0.018 -0.217504 0.010364 0.018 -0.213909 0.0113634 0.018 -0.217504 0.012348 0.018 -0.218006 0.010364 0.018 -0.213909 0.012348 0.018 -0.218006 0.0128268 0.018 -0.218425 0.010364 0.018 -0.213909 0.0128268 0.018 -0.218425 0.0157489 0.018 -0.221229 0.010364 0.018 -0.180877 0.0108639 0.0177452 -0.18125 0.010364 0.018 -0.191116 0.010364 0.018 -0.205869 0.010364 0.018 -0.210463 0.022854 0.018 -0.230886 0.013258 0.0365 -0.185453 0.015472 0.018 -0.189843 0.014836 0.0365 -0.189957 0.015472 0.018 -0.189843 0.013826 0.018 -0.185145 0.022854 0.018 -0.230886 0.013258 0.0365 -0.185453 0.022218 0.0365 -0.231 0.010211 0.0365 -0.181538 0.022218 0.0365 -0.231 -0.014827 0.0365 -0.189957 -0.014249 0.0365 -0.187732 -0.014249 0.0365 -0.187732 -0.012397 0.018 -0.182972 -0.011888 0.0365 -0.183369 -0.00873785 0.018824 -0.179642 -0.00857368 0.0189077 -0.179495 -0.0102318 0.027662 -0.181431 -0.011888 0.0365 -0.183369 -0.00873785 0.018824 -0.179642 -0.0102318 0.027662 -0.181431 -0.008238000000000001 0.0365 -0.180009 -0.011888 0.0365 -0.183369 -0.0102318 0.027662 -0.181431 -0.00857368 0.0189077 -0.179495 -0.008238000000000001 0.0365 -0.180009 -0.0102318 0.027662 -0.181431 -0.00439959 0.0203023 -0.177716 -0.008238000000000001 0.0365 -0.180009 -0.006485 0.019972 -0.178618 -0.006485 0.019972 -0.178618 -0.008238000000000001 0.0365 -0.180009 -0.00857368 0.0189077 -0.179495 0.010364 0.018 -0.216525 0.010364 0.018 -0.216995 0.0110984 0.018 -0.217369 0.010364 0.018 -0.199636 0.010364 0.018 -0.205869 0.022854 0.018 -0.230886 0.010364 0.018 -0.191116 0.010364 0.018 -0.199636 0.022854 0.018 -0.230886 0.010649 0.018 -0.181063 0.010364 0.018 -0.180877 0.010364 0.018 -0.191116 0.010649 0.018 -0.181063 0.010364 0.018 -0.191116 0.022854 0.018 -0.230886 0.010649 0.018 -0.181063 0.006058 0.0365 -0.178824 0.00937989 0.0185015 -0.180254 0.010364 0.018 -0.180877 0.010649 0.018 -0.181063 0.00937989 0.0185015 -0.180254 0.00937989 0.0185015 -0.180254 0.006058 0.0365 -0.178824 0.006494 0.019972 -0.178429 0.006494 0.019972 -0.178429 0.006058 0.0365 -0.178824 0.00628983 0.0200043 -0.178297 0.013826 0.018 -0.185145 0.015472 0.018 -0.189843 0.013258 0.0365 -0.185453 0.013826 0.018 -0.185145 0.010649 0.018 -0.181063 0.022854 0.018 -0.230886 0.022218 0.0365 -0.231 0.006058 0.0365 -0.178824 0.010211 0.0365 -0.181538 0.010211 0.0365 -0.181538 0.013826 0.018 -0.185145 0.013258 0.0365 -0.185453 0.022218 0.0365 -0.231 -0.014249 0.0365 -0.187732 -0.011888 0.0365 -0.183369 0.022218 0.0365 -0.231 -0.011888 0.0365 -0.183369 -0.008238000000000001 0.0365 -0.180009 -0.003695 0.0365 -0.178016 -0.008238000000000001 0.0365 -0.180009 -0.00439959 0.0203023 -0.177716 -0.00383344 0.020392 -0.177471 -0.003695 0.0365 -0.178016 -0.00439959 0.0203023 -0.177716 0.000513453 0.0209194 -0.177129 -0.003695 0.0365 -0.178016 4.5297e-06 0.021 -0.177174 4.5297e-06 0.021 -0.177174 -0.003695 0.0365 -0.178016 -0.00302369 0.0205203 -0.177408 -0.00302369 0.0205203 -0.177408 -0.003695 0.0365 -0.178016 -0.00383344 0.020392 -0.177471 0.006058 0.0365 -0.178824 0.001249 0.0365 -0.177607 0.00574517 0.0200906 -0.178162 0.00628983 0.0200043 -0.178297 0.006058 0.0365 -0.178824 0.00574517 0.0200906 -0.178162 0.010211 0.0365 -0.181538 0.006058 0.0365 -0.178824 0.010649 0.018 -0.181063 0.010649 0.018 -0.181063 0.013826 0.018 -0.185145 0.010211 0.0365 -0.181538 0.022218 0.0365 -0.231 0.001249 0.0365 -0.177607 0.006058 0.0365 -0.178824 0.022218 0.0365 -0.231 -0.008238000000000001 0.0365 -0.180009 -0.003695 0.0365 -0.178016 0.001249 0.0365 -0.177607 -0.003695 0.0365 -0.178016 0.000513453 0.0209194 -0.177129 0.00129399 0.0207957 -0.17706 0.001249 0.0365 -0.177607 0.000513453 0.0209194 -0.177129 0.00574517 0.0200906 -0.178162 0.001249 0.0365 -0.177607 0.00340422 0.0204614 -0.177583 0.00340422 0.0204614 -0.177583 0.001249 0.0365 -0.177607 0.00129399 0.0207957 -0.17706 0.022218 0.0365 -0.231 -0.003695 0.0365 -0.178016 0.001249 0.0365 -0.177607 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464

    -
    -
    - - - 0 0 0 - 1 0 0 0 - - true - - - -
    - - - - 0.014999 -0.021876 -0.09788199999999997 0.014999 -0.0222876 -0.09673899999999998 0.014999 -0.024129 -0.100963 0.014999 -0.024129 -0.100963 0.014999 -0.022294 -0.104332 0.014999 -0.0224298 -0.100535 0.014999 -0.021532 -0.09877999999999998 0.014999 -0.021876 -0.09788199999999997 0.014999 -0.0224298 -0.100535 0.014999 -0.0207306 -0.100168 0.014999 -0.021532 -0.09877999999999998 0.014999 -0.0224298 -0.100535 0.014999 -0.022294 -0.104332 0.014999 -0.0207306 -0.100168 0.014999 -0.0224298 -0.100535 0.014999 -0.021876 -0.09788199999999997 0.014999 -0.024129 -0.100963 0.014999 -0.0224298 -0.100535 0.014999 -0.0368802 -0.05400919999999997 0.014999 -0.045 -0.05500499999999997 0.014999 -0.036005 -0.05864799999999997 0.014999 -0.0222876 -0.09673899999999998 0.014999 -0.036005 -0.05864799999999997 0.014999 -0.0336438 -0.07748609999999997 0.014999 -0.024129 -0.100963 0.014999 -0.0222876 -0.09673899999999998 0.014999 -0.0336438 -0.07748609999999997 0.014999 -0.045 -0.05500499999999997 0.014999 -0.024129 -0.100963 0.014999 -0.0336438 -0.07748609999999997 0.014999 -0.036005 -0.05864799999999997 0.014999 -0.045 -0.05500499999999997 0.014999 -0.0336438 -0.07748609999999997 0.014999 -0.045 -0.05500499999999997 0.014999 -0.0368802 -0.05400919999999997 0.014999 -0.0406849 -0.05235499999999997 0.014999 -0.045 -0.04970499999999997 0.014999 -0.045 -0.05500499999999997 0.014999 -0.0406849 -0.05235499999999997 0.014999 -0.0363698 -0.04970499999999997 0.014999 -0.045 -0.04970499999999997 0.014999 -0.0406849 -0.05235499999999997 0.014999 -0.03693 -0.05374499999999997 0.014999 -0.0363698 -0.04970499999999997 0.014999 -0.0406849 -0.05235499999999997 0.014999 -0.0368802 -0.05400919999999997 0.014999 -0.03693 -0.05374499999999997 0.014999 -0.0406849 -0.05235499999999997 0.0155905 -0.0338603 -0.04399519999999997 0.014999 -0.045 -0.04970499999999997 0.0151152 -0.0362 -0.04858329999999998 0.0151152 -0.0362 -0.04858329999999998 0.014999 -0.045 -0.04970499999999997 0.0151123 -0.0362142 -0.04861119999999997 0.0151123 -0.0362142 -0.04861119999999997 0.014999 -0.045 -0.04970499999999997 0.014999 -0.0363698 -0.04970499999999997 0.0155979 -0.0337867 -0.04392399999999997 0.014999 -0.045 -0.04970499999999997 0.0155905 -0.0338603 -0.04399519999999997 0.014999 -0.024129 -0.100963 -0.015001 -0.022294 -0.104332 0.014999 -0.022294 -0.104332 0.014999 -0.0207306 -0.100168 0.014999 -0.022294 -0.104332 0.014999 -0.018366 -0.104264 0.014999 -0.022294 -0.104332 0.014999 -0.017354 -0.110032 0.014999 -0.0193315 -0.1051 0.014999 -0.016369 -0.106216 0.014999 -0.018366 -0.104264 0.014999 -0.0193315 -0.1051 0.014999 -0.017354 -0.110032 0.014999 -0.016369 -0.106216 0.014999 -0.0193315 -0.1051 0.014999 -0.018366 -0.104264 0.014999 -0.022294 -0.104332 0.014999 -0.0193315 -0.1051 0.014999 -0.024129 -0.100963 0.014999 -0.045 -0.05500499999999997 -0.015001 -0.045 -0.05500499999999997 0.014999 -0.045 -0.04970499999999997 -0.015001 -0.045 -0.05500499999999997 0.014999 -0.045 -0.05500499999999997 0.0155979 -0.0337867 -0.04392399999999997 0.0156022 -0.0337438 -0.04388249999999997 0.014999 -0.045 -0.04970499999999997 0.0156022 -0.0337438 -0.04388249999999997 0.0159634 -0.0301408 -0.04039569999999997 0.014999 -0.045 -0.04970499999999997 0.0159749 -0.0299034 -0.04028399999999997 0.017307 -0.023 -0.02742499999999997 0.0159634 -0.0301408 -0.04039569999999997 0.0161913 -0.0254597 -0.03819499999999997 0.017307 -0.023 -0.02742499999999997 0.0159749 -0.0299034 -0.04028399999999997 0.016195 -0.0251401 -0.03815979999999997 0.017307 -0.023 -0.02742499999999997 0.0161913 -0.0254597 -0.03819499999999997 0.0162152 -0.0233709 -0.03796439999999997 0.017307 -0.023 -0.02742499999999997 0.016195 -0.0251401 -0.03815979999999997 0.0159634 -0.0301408 -0.04039569999999997 0.017307 -0.023 -0.02742499999999997 0.014999 -0.045 -0.04970499999999997 -0.015001 -0.022294 -0.104332 -0.015001 -0.017354 -0.110032 0.014999 -0.022294 -0.104332 -0.015001 -0.024129 -0.100963 -0.015001 -0.022294 -0.104332 0.014999 -0.024129 -0.100963 0.014999 -0.022294 -0.104332 -0.015001 -0.017354 -0.110032 0.014999 -0.017354 -0.110032 0.014999 -0.016369 -0.106216 0.014999 -0.017354 -0.110032 0.014999 -0.013837 -0.10869 0.014999 -0.017354 -0.110032 0.014999 -0.011009 -0.11411 0.014999 -0.0139244 -0.110163 0.014999 -0.0104947 -0.110519 0.014999 -0.013837 -0.10869 0.014999 -0.0139244 -0.110163 0.014999 -0.011009 -0.11411 0.014999 -0.0104947 -0.110519 0.014999 -0.0139244 -0.110163 0.014999 -0.013837 -0.10869 0.014999 -0.017354 -0.110032 0.014999 -0.0139244 -0.110163 -0.015001 -0.045 -0.05500499999999997 -0.015001 -0.024129 -0.100963 0.014999 -0.024129 -0.100963 -0.015001 -0.045 -0.04970499999999997 -0.015001 -0.045 -0.05500499999999997 0.014999 -0.045 -0.04970499999999997 0.0151727 -0.005037 -0.04802789999999997 0.014999 -0.001784 -0.04970499999999997 0.0155745 -0.00833217 -0.04414979999999998 0.0162501 -0.0203204 -0.03762759999999997 0.017307 -0.023 -0.02742499999999997 0.0162152 -0.0233709 -0.03796439999999997 0.0162426 -0.0199942 -0.03770049999999997 0.017307 -0.023 -0.02742499999999997 0.0162501 -0.0203204 -0.03762759999999997 0.0161333 -0.0152729 -0.03875469999999998 0.017307 -0.023 -0.02742499999999997 0.0162426 -0.0199942 -0.03770049999999997 0.0161171 -0.0150167 -0.03891159999999997 0.017307 -0.023 -0.02742499999999997 0.0161333 -0.0152729 -0.03875469999999998 0.0158536 -0.0108606 -0.04145549999999997 0.017307 -0.023 -0.02742499999999997 0.0161171 -0.0150167 -0.03891159999999997 0.014999 -0.001784 -0.04970499999999997 0.017307 -0.023 -0.02742499999999997 0.0156769 -0.009172100000000001 -0.04316129999999997 0.0156769 -0.009172100000000001 -0.04316129999999997 0.017307 -0.023 -0.02742499999999997 0.0158458 -0.0107864 -0.04153049999999997 0.0158458 -0.0107864 -0.04153049999999997 0.017307 -0.023 -0.02742499999999997 0.0158536 -0.0108606 -0.04145549999999997 0.014999 -0.001784 -0.04970499999999997 0.0156769 -0.009172100000000001 -0.04316129999999997 0.0155745 -0.00833217 -0.04414979999999998 0.017307 -0.023 -0.02742499999999997 0.018999 -0.045 -0.01109499999999997 0.014999 -0.045 -0.04970499999999997 -0.015001 -0.018178 -0.100248 -0.015001 -0.022294 -0.104332 -0.015001 -0.019627 -0.09722869999999997 -0.015001 -0.017585 -0.101484 -0.015001 -0.0157113 -0.103667 -0.015001 -0.0190027 -0.10363 -0.015001 -0.018178 -0.100248 -0.015001 -0.017585 -0.101484 -0.015001 -0.0190027 -0.10363 -0.015001 -0.017354 -0.110032 -0.015001 -0.022294 -0.104332 -0.015001 -0.0190027 -0.10363 -0.015001 -0.0157113 -0.103667 -0.015001 -0.017354 -0.110032 -0.015001 -0.0190027 -0.10363 -0.015001 -0.022294 -0.104332 -0.015001 -0.018178 -0.100248 -0.015001 -0.0190027 -0.10363 -0.015001 -0.019957 -0.09654099999999997 -0.015001 -0.019627 -0.09722869999999997 -0.015001 -0.021878 -0.09863749999999998 -0.015001 -0.02021 -0.09519399999999997 -0.015001 -0.019957 -0.09654099999999997 -0.015001 -0.021878 -0.09863749999999998 -0.015001 -0.0206328 -0.09294289999999997 -0.015001 -0.02021 -0.09519399999999997 -0.015001 -0.021878 -0.09863749999999998 -0.015001 -0.024129 -0.100963 -0.015001 -0.0206328 -0.09294289999999997 -0.015001 -0.021878 -0.09863749999999998 -0.015001 -0.022294 -0.104332 -0.015001 -0.024129 -0.100963 -0.015001 -0.021878 -0.09863749999999998 -0.015001 -0.019627 -0.09722869999999997 -0.015001 -0.022294 -0.104332 -0.015001 -0.021878 -0.09863749999999998 -0.015001 -0.011009 -0.11411 0.014999 -0.017354 -0.110032 -0.015001 -0.017354 -0.110032 0.014999 -0.011009 -0.11411 0.014999 -0.017354 -0.110032 -0.015001 -0.011009 -0.11411 0.014999 -0.0104947 -0.110519 0.014999 -0.011009 -0.11411 0.014999 -0.008283 -0.11173 0.014999 -0.011009 -0.11411 0.014999 -0.00377199 -0.116235 0.014999 -0.00733916 -0.113377 0.014999 -0.00366932 -0.112799 0.014999 -0.008283 -0.11173 0.014999 -0.00733916 -0.113377 0.014999 -0.00377199 -0.116235 0.014999 -0.00366932 -0.112799 0.014999 -0.00733916 -0.113377 0.014999 -0.008283 -0.11173 0.014999 -0.011009 -0.11411 0.014999 -0.00733916 -0.113377 -0.015001 -0.036766 -0.05498099999999997 -0.015001 -0.045 -0.05500499999999997 -0.015001 -0.0368311 -0.05400319999999997 -0.015001 -0.028996 -0.08602199999999997 -0.015001 -0.024129 -0.100963 -0.015001 -0.030282 -0.08455499999999998 -0.015001 -0.014599 -0.07509749999999997 -0.015001 -0.015639 -0.07598999999999997 -0.015001 -0.014744 -0.07342099999999997 -0.015001 -0.024129 -0.100963 -0.015001 -0.028996 -0.08602199999999997 -0.015001 -0.027246 -0.08688499999999998 -0.015001 -0.015639 -0.07598999999999997 -0.015001 -0.018629 -0.07798099999999997 -0.015001 -0.014744 -0.07342099999999997 -0.015001 -0.014599 -0.07509749999999997 -0.015001 -0.014744 -0.07342099999999997 -0.015001 -0.01181 -0.07270409999999997 -0.015001 -0.024129 -0.100963 -0.015001 -0.027246 -0.08688499999999998 -0.015001 -0.0206328 -0.09294289999999997 -0.015001 -0.01181 -0.07270409999999997 -0.015001 -0.014744 -0.07342099999999997 -0.015001 -0.0110356 -0.07092759999999997 -0.015001 -0.027246 -0.08688499999999998 -0.015001 -0.025299 -0.08701299999999997 -0.015001 -0.020969 -0.09115299999999997 -0.015001 -0.030282 -0.08455499999999998 -0.015001 -0.024129 -0.100963 -0.015001 -0.030844 -0.08308599999999997 -0.015001 -0.024129 -0.100963 -0.015001 -0.045 -0.05500499999999997 -0.015001 -0.030844 -0.08308599999999997 -0.015001 -0.0206328 -0.09294289999999997 -0.015001 -0.027246 -0.08688499999999998 -0.015001 -0.020969 -0.09115299999999997 -0.015001 -0.020969 -0.09115299999999997 -0.015001 -0.025299 -0.08701299999999997 -0.015001 -0.0208647 -0.08978649999999998 -0.015001 -0.0208647 -0.08978649999999998 -0.015001 -0.025299 -0.08701299999999997 -0.015001 -0.023452 -0.08638599999999998 -0.015001 -0.023452 -0.08638599999999998 -0.015001 -0.021985 -0.08509899999999997 -0.015001 -0.020552 -0.08568699999999997 -0.015001 -0.0208647 -0.08978649999999998 -0.015001 -0.023452 -0.08638599999999998 -0.015001 -0.020552 -0.08568699999999997 -0.015001 -0.021164 -0.08349599999999997 -0.015001 -0.021141 -0.08342099999999997 -0.015001 -0.0200975 -0.08439399999999997 -0.015001 -0.021985 -0.08509899999999997 -0.015001 -0.021164 -0.08349599999999997 -0.015001 -0.0200975 -0.08439399999999997 -0.015001 -0.020552 -0.08568699999999997 -0.015001 -0.021985 -0.08509899999999997 -0.015001 -0.0200975 -0.08439399999999997 -0.015001 -0.0200975 -0.08439399999999997 -0.015001 -0.021141 -0.08342099999999997 -0.015001 -0.018734 -0.08051499999999998 -0.015001 -0.0179603 -0.07938369999999997 -0.015001 -0.018734 -0.08051499999999998 -0.015001 -0.018629 -0.07798099999999997 -0.015001 -0.018734 -0.08051499999999998 -0.015001 -0.021141 -0.08342099999999997 -0.015001 -0.018629 -0.07798099999999997 -0.015001 -0.030844 -0.08308599999999997 -0.015001 -0.045 -0.05500499999999997 -0.015001 -0.036766 -0.05498099999999997 -0.015001 -0.0179603 -0.07938369999999997 -0.015001 -0.018629 -0.07798099999999997 -0.015001 -0.015639 -0.07598999999999997 -0.015001 -0.045 -0.05500499999999997 -0.015001 -0.045 -0.04970499999999997 -0.015001 -0.0409052 -0.05235499999999997 -0.015001 -0.0368311 -0.05400319999999997 -0.015001 -0.045 -0.05500499999999997 -0.015001 -0.0409052 -0.05235499999999997 -0.015001 -0.037048 -0.05074599999999997 -0.015001 -0.0368311 -0.05400319999999997 -0.015001 -0.0409052 -0.05235499999999997 -0.015001 -0.0368104 -0.04970499999999997 -0.015001 -0.037048 -0.05074599999999997 -0.015001 -0.0409052 -0.05235499999999997 -0.015001 -0.045 -0.04970499999999997 -0.015001 -0.0368104 -0.04970499999999997 -0.015001 -0.0409052 -0.05235499999999997 -0.019001 -0.045 -0.01109499999999997 -0.015001 -0.045 -0.04970499999999997 0.014999 -0.045 -0.04970499999999997 0.014999 -0.00344037 -0.04990809999999997 0.0151727 -0.005037 -0.04802789999999997 0.014999 -0.00361201 -0.04970499999999997 0.014999 -0.00240614 -0.05113219999999997 0.014999 -0.00344037 -0.04990809999999997 0.0151727 -0.005037 -0.04802789999999997 0.0155745 -0.00833217 -0.04414979999999998 0.014999 -0.00240614 -0.05113219999999997 0.0151727 -0.005037 -0.04802789999999997 0.0155745 -0.00833217 -0.04414979999999998 0.014999 -0.00240614 -0.05113219999999997 0.014999 -0.00234639 -0.05120289999999997 0.0155745 -0.00833217 -0.04414979999999998 0.014999 -0.00221173 -0.05136229999999997 0.014999 -0.00234639 -0.05120289999999997 0.0155745 -0.00833217 -0.04414979999999998 0.014999 -0.00204897 -0.05155489999999997 0.014999 -0.00221173 -0.05136229999999997 0.0155745 -0.00833217 -0.04414979999999998 0.014999 -0.00184644 -0.05179459999999998 0.014999 -0.00204897 -0.05155489999999997 0.0155745 -0.00833217 -0.04414979999999998 0.014999 -0.00158355 -0.05210569999999997 0.014999 -0.00184644 -0.05179459999999998 0.0155745 -0.00833217 -0.04414979999999998 0.014999 -0.00122225 -0.05253329999999997 0.014999 -0.00158355 -0.05210569999999997 0.0155745 -0.00833217 -0.04414979999999998 0.014999 -0.000685157 -0.05316899999999997 0.014999 -0.00122225 -0.05253329999999997 0.0155745 -0.00833217 -0.04414979999999998 0.014999 0.000209368 -0.05422759999999997 0.014999 -0.000685157 -0.05316899999999997 0.0151727 -0.005037 -0.04802789999999997 0.014999 -0.00361201 -0.04970499999999997 0.014999 -0.001784 -0.04970499999999997 0.014999 -0.001784 -0.04970499999999997 -0.015001 -0.001784 -0.04970499999999997 0.017307 -0.023 -0.02742499999999997 0.018999 -0.045 -0.01109499999999997 -0.019001 -0.045 -0.01109499999999997 0.014999 -0.045 -0.04970499999999997 0.018999 -0.023 -0.01109499999999997 0.018999 -0.045 -0.01109499999999997 0.017307 -0.023 -0.02742499999999997 -0.015001 -0.0157113 -0.103667 -0.015001 -0.017585 -0.101484 -0.020001 -0.0158 -0.103564 -0.015001 -0.0149075 -0.104604 -0.015001 -0.0157113 -0.103667 -0.020001 -0.0158 -0.103564 -0.025001 -0.014015 -0.105644 -0.015001 -0.0149075 -0.104604 -0.020001 -0.0158 -0.103564 -0.025001 -0.017585 -0.101484 -0.025001 -0.014015 -0.105644 -0.020001 -0.0158 -0.103564 -0.015001 -0.017585 -0.101484 -0.025001 -0.017585 -0.101484 -0.020001 -0.0158 -0.103564 -0.015001 -0.018178 -0.100248 -0.025001 -0.017585 -0.101484 -0.015001 -0.017585 -0.101484 -0.015001 -0.019627 -0.09722869999999997 -0.015001 -0.019957 -0.09654099999999997 -0.020001 -0.018771 -0.09901249999999998 -0.015001 -0.018178 -0.100248 -0.015001 -0.019627 -0.09722869999999997 -0.020001 -0.018771 -0.09901249999999998 -0.025001 -0.017585 -0.101484 -0.015001 -0.018178 -0.100248 -0.020001 -0.018771 -0.09901249999999998 -0.025001 -0.019957 -0.09654099999999997 -0.025001 -0.017585 -0.101484 -0.020001 -0.018771 -0.09901249999999998 -0.015001 -0.019957 -0.09654099999999997 -0.025001 -0.019957 -0.09654099999999997 -0.020001 -0.018771 -0.09901249999999998 -0.015001 -0.014015 -0.105644 -0.015001 -0.017354 -0.110032 -0.015001 -0.0149075 -0.104604 -0.015001 -0.0149075 -0.104604 -0.015001 -0.017354 -0.110032 -0.015001 -0.0157113 -0.103667 -0.015001 -0.0106213 -0.107965 -0.015001 -0.0101727 -0.108271 -0.015001 -0.0137633 -0.108889 -0.015001 -0.014015 -0.105644 -0.015001 -0.0106213 -0.107965 -0.015001 -0.0137633 -0.108889 -0.015001 -0.011009 -0.11411 -0.015001 -0.017354 -0.110032 -0.015001 -0.0137633 -0.108889 -0.015001 -0.0101727 -0.108271 -0.015001 -0.011009 -0.11411 -0.015001 -0.0137633 -0.108889 -0.015001 -0.017354 -0.110032 -0.015001 -0.014015 -0.105644 -0.015001 -0.0137633 -0.108889 -0.015001 -0.02021 -0.09519399999999997 -0.025001 -0.019957 -0.09654099999999997 -0.015001 -0.019957 -0.09654099999999997 -0.015001 -0.0206328 -0.09294289999999997 -0.015001 -0.020969 -0.09115299999999997 -0.020001 -0.020463 -0.09384699999999997 -0.015001 -0.02021 -0.09519399999999997 -0.015001 -0.0206328 -0.09294289999999997 -0.020001 -0.020463 -0.09384699999999997 -0.025001 -0.019957 -0.09654099999999997 -0.015001 -0.02021 -0.09519399999999997 -0.020001 -0.020463 -0.09384699999999997 -0.025001 -0.020969 -0.09115299999999997 -0.025001 -0.019957 -0.09654099999999997 -0.020001 -0.020463 -0.09384699999999997 -0.015001 -0.020969 -0.09115299999999997 -0.025001 -0.020969 -0.09115299999999997 -0.020001 -0.020463 -0.09384699999999997 -0.015001 -0.003772 -0.116235 0.014999 -0.011009 -0.11411 -0.015001 -0.011009 -0.11411 0.014999 -0.00377199 -0.116235 0.014999 -0.011009 -0.11411 -0.015001 -0.003772 -0.116235 0.014999 -0.002115 -0.113159 0.014999 -0.00366932 -0.112799 0.014999 -0.00377199 -0.116235 0.014999 -0.00377199 -0.116235 0.014999 0.00377101 -0.116235 0.014999 -4.89992e-07 -0.114517 0.014999 0.00349286 -0.112904 0.014999 -0.002115 -0.113159 0.014999 -4.89992e-07 -0.114517 0.014999 0.00377101 -0.116235 0.014999 0.00349286 -0.112904 0.014999 -4.89992e-07 -0.114517 0.014999 -0.002115 -0.113159 0.014999 -0.00377199 -0.116235 0.014999 -4.89992e-07 -0.114517 -0.015001 -0.011479 -0.07241999999999997 -0.015001 -0.01181 -0.07270409999999997 -0.015001 -0.0110356 -0.07092759999999997 -0.015001 -0.010056 -0.07173699999999997 -0.015001 -0.009771999999999999 -0.07007799999999997 -0.015001 -0.009385249999999999 -0.06995039999999997 -0.015001 -0.0110356 -0.07092759999999997 -0.015001 -0.009771999999999999 -0.07007799999999997 -0.015001 -0.0105976 -0.07132729999999997 -0.015001 -0.0102435 -0.07182699999999997 -0.015001 -0.011479 -0.07241999999999997 -0.015001 -0.0105976 -0.07132729999999997 -0.015001 -0.010056 -0.07173699999999997 -0.015001 -0.0102435 -0.07182699999999997 -0.015001 -0.0105976 -0.07132729999999997 -0.015001 -0.011479 -0.07241999999999997 -0.015001 -0.0110356 -0.07092759999999997 -0.015001 -0.0105976 -0.07132729999999997 -0.015001 -0.009771999999999999 -0.07007799999999997 -0.015001 -0.010056 -0.07173699999999997 -0.015001 -0.0105976 -0.07132729999999997 -0.015001 -0.0208647 -0.08978649999999998 -0.025001 -0.020969 -0.09115299999999997 -0.015001 -0.020969 -0.09115299999999997 -0.015001 -0.0208647 -0.08978649999999998 -0.015001 -0.020552 -0.08568699999999997 -0.020001 -0.0207605 -0.08841999999999997 -0.025001 -0.020969 -0.09115299999999997 -0.015001 -0.0208647 -0.08978649999999998 -0.020001 -0.0207605 -0.08841999999999997 -0.025001 -0.020552 -0.08568699999999997 -0.025001 -0.020969 -0.09115299999999997 -0.020001 -0.0207605 -0.08841999999999997 -0.015001 -0.020552 -0.08568699999999997 -0.025001 -0.020552 -0.08568699999999997 -0.020001 -0.0207605 -0.08841999999999997 -0.015001 -0.0200975 -0.08439399999999997 -0.025001 -0.020552 -0.08568699999999997 -0.015001 -0.020552 -0.08568699999999997 -0.015001 -0.0200975 -0.08439399999999997 -0.015001 -0.018734 -0.08051499999999998 -0.020001 -0.019643 -0.08310099999999997 -0.015001 -0.018734 -0.08051499999999998 -0.025001 -0.018734 -0.08051499999999998 -0.020001 -0.019643 -0.08310099999999997 -0.025001 -0.020552 -0.08568699999999997 -0.015001 -0.0200975 -0.08439399999999997 -0.020001 -0.019643 -0.08310099999999997 -0.025001 -0.018734 -0.08051499999999998 -0.025001 -0.020552 -0.08568699999999997 -0.020001 -0.019643 -0.08310099999999997 -0.015001 -0.0179603 -0.07938369999999997 -0.025001 -0.018734 -0.08051499999999998 -0.015001 -0.018734 -0.08051499999999998 -0.015001 -0.0179603 -0.07938369999999997 -0.015001 -0.015639 -0.07598999999999997 -0.020001 -0.0171865 -0.07825249999999997 -0.015001 -0.015639 -0.07598999999999997 -0.025001 -0.015639 -0.07598999999999997 -0.020001 -0.0171865 -0.07825249999999997 -0.025001 -0.018734 -0.08051499999999998 -0.015001 -0.0179603 -0.07938369999999997 -0.020001 -0.0171865 -0.07825249999999997 -0.025001 -0.015639 -0.07598999999999997 -0.025001 -0.018734 -0.08051499999999998 -0.020001 -0.0171865 -0.07825249999999997 -0.015001 -0.015639 -0.07598999999999997 -0.015001 -0.014599 -0.07509749999999997 -0.025001 -0.015639 -0.07598999999999997 -0.015001 -0.014599 -0.07509749999999997 -0.015001 -0.01181 -0.07270409999999997 -0.020001 -0.013559 -0.07420499999999997 -0.015001 -0.01181 -0.07270409999999997 -0.015001 -0.011479 -0.07241999999999997 -0.020001 -0.013559 -0.07420499999999997 -0.025001 -0.015639 -0.07598999999999997 -0.015001 -0.014599 -0.07509749999999997 -0.020001 -0.013559 -0.07420499999999997 -0.015001 -0.011479 -0.07241999999999997 -0.025001 -0.011479 -0.07241999999999997 -0.020001 -0.013559 -0.07420499999999997 -0.025001 -0.011479 -0.07241999999999997 -0.025001 -0.015639 -0.07598999999999997 -0.020001 -0.013559 -0.07420499999999997 -0.0155351 -0.0350001 -0.04454949999999997 -0.015347 -0.036048 -0.04636499999999998 -0.015001 -0.045 -0.04970499999999997 -0.015347 -0.036048 -0.04636499999999998 -0.0153411 -0.0360611 -0.04642229999999997 -0.015001 -0.045 -0.04970499999999997 -0.0153411 -0.0360611 -0.04642229999999997 -0.015001 -0.0368104 -0.04970499999999997 -0.015001 -0.045 -0.04970499999999997 -0.017309 -0.023 -0.02742499999999997 -0.015001 -0.045 -0.04970499999999997 -0.019001 -0.045 -0.01109499999999997 0.014999 -0.00361201 -0.04970499999999997 0.014999 -0.00344037 -0.04990809999999997 0.014999 -0.001784 -0.04970499999999997 0.014999 -0.001784 -0.04970499999999997 0.014999 -0.00344037 -0.04990809999999997 0.014999 -0.00240614 -0.05113219999999997 0.014999 -0.001784 -0.04970499999999997 0.014999 -0.00240614 -0.05113219999999997 0.014999 -0.00234639 -0.05120289999999997 0.014999 -0.001784 -0.04970499999999997 0.014999 -0.00234639 -0.05120289999999997 0.014999 -0.00221173 -0.05136229999999997 0.014999 -0.001784 -0.04970499999999997 0.014999 -0.00221173 -0.05136229999999997 0.014999 -0.00204897 -0.05155489999999997 0.014999 -0.00184644 -0.05179459999999998 0.014999 -0.001784 -0.04970499999999997 0.014999 -0.00204897 -0.05155489999999997 0.014999 -0.00158355 -0.05210569999999997 0.014999 -0.001784 -0.04970499999999997 0.014999 -0.00184644 -0.05179459999999998 0.014999 -0.00122225 -0.05253329999999997 0.014999 -0.001784 -0.04970499999999997 0.014999 -0.00158355 -0.05210569999999997 0.014999 -0.000685157 -0.05316899999999997 0.014999 -0.001784 -0.04970499999999997 0.014999 -0.00122225 -0.05253329999999997 0.014999 -0.000685157 -0.05316899999999997 0.014999 0.000209368 -0.05422759999999997 0.014999 -0.001784 -0.04970499999999997 0.014999 0.000209368 -0.05422759999999997 0.014999 0.00199864 -0.05634529999999997 0.014999 -0.001784 -0.04970499999999997 0.014999 0.00199864 -0.05634529999999997 0.014999 0.00718103 -0.06247869999999997 0.014999 -0.001784 -0.04970499999999997 0.014999 0.022525 -0.08424299999999997 0.014999 0.0225384 -0.08436039999999997 0.014999 0.025426 -0.08253899999999997 0.014999 0.020135 -0.07837899999999998 0.014999 0.022525 -0.08424299999999997 0.014999 0.025426 -0.08253899999999997 0.014999 0.01776 -0.07499899999999997 0.014999 0.020135 -0.07837899999999998 0.014999 0.025426 -0.08253899999999997 0.014999 0.025426 -0.08253899999999997 0.014999 0.0225384 -0.08436039999999997 0.014999 0.0265 -0.09000499999999997 0.014999 0.01776 -0.07499899999999997 0.014999 0.025426 -0.08253899999999997 0.014999 0.00718103 -0.06247869999999997 0.014999 0.025426 -0.08253899999999997 0.014999 -0.001784 -0.04970499999999997 0.014999 0.00718103 -0.06247869999999997 -0.015001 -0.001784 -0.04970499999999997 -0.017309 -0.023 -0.02742499999999997 0.017307 -0.023 -0.02742499999999997 0.014999 0.01919 -0.07172999999999997 -0.015001 -0.001784 -0.04970499999999997 0.014999 -0.001784 -0.04970499999999997 0.020922 -0.045 -0.006802999999999972 -0.019001 -0.045 -0.01109499999999997 0.018999 -0.045 -0.01109499999999997 0.020922 -0.023 -0.006802999999999972 0.018999 -0.045 -0.01109499999999997 0.018999 -0.023 -0.01109499999999997 0.017307 -0.023 -0.02742499999999997 -0.017309 -0.023 -0.02742499999999997 0.018999 -0.023 -0.01109499999999997 -0.015001 -0.0149075 -0.104604 -0.025001 -0.014015 -0.105644 -0.015001 -0.014015 -0.105644 -0.025001 -0.014015 -0.105644 -0.025001 -0.017585 -0.101484 -0.025001 0.011478 -0.10759 -0.025001 -0.017585 -0.101484 -0.025001 -0.019957 -0.09654099999999997 -0.025001 0.011478 -0.10759 -0.015001 -0.0101727 -0.108271 -0.015001 -0.0106213 -0.107965 -0.025001 -0.00949 -0.108738 -0.015001 -0.00949 -0.108738 -0.015001 -0.0101727 -0.108271 -0.025001 -0.00949 -0.108738 -0.015001 -0.0106213 -0.107965 -0.015001 -0.014015 -0.105644 -0.020001 -0.0117525 -0.107191 -0.025001 -0.00949 -0.108738 -0.015001 -0.0106213 -0.107965 -0.020001 -0.0117525 -0.107191 -0.025001 -0.014015 -0.105644 -0.025001 -0.00949 -0.108738 -0.020001 -0.0117525 -0.107191 -0.015001 -0.014015 -0.105644 -0.025001 -0.014015 -0.105644 -0.020001 -0.0117525 -0.107191 -0.015001 -0.011009 -0.11411 -0.015001 -0.0101727 -0.108271 -0.015001 -0.00949 -0.108738 -0.015001 -0.003772 -0.116235 -0.015001 -0.004318 -0.110556 -0.015001 -0.00360394 -0.110611 -0.015001 -0.005611 -0.110101 -0.015001 -0.004318 -0.110556 -0.015001 -0.00730647 -0.112253 -0.015001 -0.00949 -0.108738 -0.015001 -0.005611 -0.110101 -0.015001 -0.00730647 -0.112253 -0.015001 -0.003772 -0.116235 -0.015001 -0.011009 -0.11411 -0.015001 -0.00730647 -0.112253 -0.015001 -0.011009 -0.11411 -0.015001 -0.00949 -0.108738 -0.015001 -0.00730647 -0.112253 -0.015001 -0.004318 -0.110556 -0.015001 -0.003772 -0.116235 -0.015001 -0.00730647 -0.112253 -0.025001 -0.019957 -0.09654099999999997 -0.025001 -0.020969 -0.09115299999999997 -0.025001 0.011478 -0.10759 -0.015001 -0.003772 -0.116235 -0.015001 0.003771 -0.116235 0.014999 -0.00377199 -0.116235 -0.015001 0.003771 -0.116235 0.014999 0.00377101 -0.116235 0.014999 -0.00377199 -0.116235 0.014999 0.00421101 -0.112871 0.014999 0.00349286 -0.112904 0.014999 0.00377101 -0.116235 0.014999 0.0103509 -0.110802 0.014999 0.010224 -0.110887 0.014999 0.011008 -0.11411 0.014999 0.00377101 -0.116235 0.014999 0.011008 -0.11411 0.014999 0.00725043 -0.113518 0.014999 0.010224 -0.110887 0.014999 0.00421101 -0.112871 0.014999 0.00725043 -0.113518 0.014999 0.011008 -0.11411 0.014999 0.010224 -0.110887 0.014999 0.00725043 -0.113518 0.014999 0.00421101 -0.112871 0.014999 0.00377101 -0.116235 0.014999 0.00725043 -0.113518 -0.015001 -0.00678809 -0.06909369999999997 -0.015001 -0.00710472 -0.07032049999999997 -0.015001 -0.00842207 -0.07041529999999997 -0.015001 -0.009385249999999999 -0.06995039999999997 -0.015001 -0.00678809 -0.06909369999999997 -0.015001 -0.00842207 -0.07041529999999997 -0.015001 -0.010056 -0.07173699999999997 -0.015001 -0.009385249999999999 -0.06995039999999997 -0.015001 -0.00842207 -0.07041529999999997 -0.015001 -0.00710472 -0.07032049999999997 -0.015001 -0.010056 -0.07173699999999997 -0.015001 -0.00842207 -0.07041529999999997 -0.015001 -0.011479 -0.07241999999999997 -0.015001 -0.0102435 -0.07182699999999997 -0.025001 -0.011479 -0.07241999999999997 -0.015001 -0.0102435 -0.07182699999999997 -0.015001 -0.010056 -0.07173699999999997 -0.020001 -0.009008 -0.07123399999999998 -0.015001 -0.010056 -0.07173699999999997 -0.015001 -0.00710472 -0.07032049999999997 -0.020001 -0.009008 -0.07123399999999998 -0.025001 -0.011479 -0.07241999999999997 -0.015001 -0.0102435 -0.07182699999999997 -0.020001 -0.009008 -0.07123399999999998 -0.015001 -0.00710472 -0.07032049999999997 -0.015001 -0.006537 -0.07004799999999997 -0.020001 -0.009008 -0.07123399999999998 -0.025001 -0.006537 -0.07004799999999997 -0.025001 -0.011479 -0.07241999999999997 -0.020001 -0.009008 -0.07123399999999998 -0.015001 -0.006537 -0.07004799999999997 -0.025001 -0.006537 -0.07004799999999997 -0.020001 -0.009008 -0.07123399999999998 -0.025001 -0.020969 -0.09115299999999997 -0.025001 -0.020552 -0.08568699999999997 -0.025001 0.011478 -0.10759 -0.025001 -0.020552 -0.08568699999999997 -0.025001 -0.018734 -0.08051499999999998 -0.025001 0.011478 -0.10759 -0.025001 0.011478 -0.10759 -0.025001 -0.018734 -0.08051499999999998 -0.025001 -0.015639 -0.07598999999999997 -0.025001 0.011478 -0.10759 -0.025001 -0.015639 -0.07598999999999997 -0.025001 -0.011479 -0.07241999999999997 -0.0155351 -0.0350001 -0.04454949999999997 -0.015001 -0.045 -0.04970499999999997 -0.0157386 -0.0338657 -0.04258439999999997 -0.0157386 -0.0338657 -0.04258439999999997 -0.015001 -0.045 -0.04970499999999997 -0.0157501 -0.033802 -0.04247399999999997 -0.0160666 -0.030508 -0.03941799999999997 -0.0160538 -0.0306414 -0.03954169999999997 -0.017309 -0.023 -0.02742499999999997 -0.0162589 -0.0266549 -0.03756229999999997 -0.0160666 -0.030508 -0.03941799999999997 -0.017309 -0.023 -0.02742499999999997 -0.0162686 -0.026459 -0.03746799999999997 -0.0162589 -0.0266549 -0.03756229999999997 -0.017309 -0.023 -0.02742499999999997 -0.0163174 -0.0233368 -0.03699719999999997 -0.0162686 -0.026459 -0.03746799999999997 -0.017309 -0.023 -0.02742499999999997 -0.0157501 -0.033802 -0.04247399999999997 -0.015001 -0.045 -0.04970499999999997 -0.0160538 -0.0306414 -0.03954169999999997 -0.015001 -0.045 -0.04970499999999997 -0.017309 -0.023 -0.02742499999999997 -0.0160538 -0.0306414 -0.03954169999999997 -0.019001 -0.023 -0.01109499999999997 -0.017309 -0.023 -0.02742499999999997 -0.019001 -0.045 -0.01109499999999997 0.014999 0.0225384 -0.08436039999999997 0.014999 0.023244 -0.09053399999999998 0.014999 0.0265 -0.09000499999999997 0.014999 0.0228548 -0.09295739999999997 0.014999 0.025426 -0.09747099999999997 0.014999 0.0245192 -0.09091569999999997 0.014999 0.023244 -0.09053399999999998 0.014999 0.0228548 -0.09295739999999997 0.014999 0.0245192 -0.09091569999999997 0.014999 0.025426 -0.09747099999999997 0.014999 0.0265 -0.09000499999999997 0.014999 0.0245192 -0.09091569999999997 0.014999 0.0265 -0.09000499999999997 0.014999 0.023244 -0.09053399999999998 0.014999 0.0245192 -0.09091569999999997 0.014999 -0.001784 -0.04970499999999997 0.014999 0.025426 -0.08253899999999997 0.014999 0.022293 -0.07567799999999997 0.014999 0.0265 -0.09000499999999997 -0.015001 0.025426 -0.08253899999999997 0.014999 0.025426 -0.08253899999999997 -0.016338 -0.022016 -0.03679799999999997 -0.0163345 -0.0222439 -0.03683239999999997 -0.017309 -0.023 -0.02742499999999997 -0.016272 -0.0177902 -0.03743519999999997 -0.016338 -0.022016 -0.03679799999999997 -0.017309 -0.023 -0.02742499999999997 -0.0162686 -0.017573 -0.03746799999999997 -0.016272 -0.0177902 -0.03743519999999997 -0.017309 -0.023 -0.02742499999999997 -0.0163345 -0.0222439 -0.03683239999999997 -0.0163174 -0.0233368 -0.03699719999999997 -0.017309 -0.023 -0.02742499999999997 -0.016075 -0.0136913 -0.03933749999999997 -0.0162686 -0.017573 -0.03746799999999997 -0.016155 -0.0125604 -0.03856499999999997 -0.0160666 -0.013524 -0.03941799999999997 -0.016075 -0.0136913 -0.03933749999999997 -0.016155 -0.0125604 -0.03856499999999997 -0.0159434 -0.0120061 -0.04060729999999997 -0.0160666 -0.013524 -0.03941799999999997 -0.016155 -0.0125604 -0.03856499999999997 -0.0159388 -0.011949 -0.04065199999999997 -0.016155 -0.0125604 -0.03856499999999997 -0.0159434 -0.0120061 -0.04060729999999997 -0.0150104 -0.00196059 -0.04961399999999997 -0.0159388 -0.011949 -0.04065199999999997 -0.016155 -0.0125604 -0.03856499999999997 -0.015001 -0.001784 -0.04970499999999997 -0.0150104 -0.00196059 -0.04961399999999997 -0.016155 -0.0125604 -0.03856499999999997 -0.017309 -0.023 -0.02742499999999997 -0.015001 -0.001784 -0.04970499999999997 -0.016155 -0.0125604 -0.03856499999999997 -0.0162686 -0.017573 -0.03746799999999997 -0.017309 -0.023 -0.02742499999999997 -0.016155 -0.0125604 -0.03856499999999997 -0.015001 0.01919 -0.07172999999999997 -0.015001 0.0110311 -0.06316229999999998 0.014999 0.01919 -0.07172999999999997 -0.015001 0.0110311 -0.06316229999999998 -0.015001 0.0109901 -0.06311919999999997 0.014999 0.01919 -0.07172999999999997 -0.015001 0.0109901 -0.06311919999999997 -0.015001 0.0109063 -0.06303119999999997 0.014999 0.01919 -0.07172999999999997 -0.015001 0.00839001 -0.06038879999999997 -0.015001 -0.00134311 -0.05016799999999997 0.014999 0.01919 -0.07172999999999997 -0.015001 0.0109063 -0.06303119999999997 -0.015001 0.0108748 -0.06299819999999998 0.014999 0.01919 -0.07172999999999997 -0.015001 0.00844342 -0.06044489999999998 -0.015001 0.00839001 -0.06038879999999997 0.014999 0.01919 -0.07172999999999997 -0.015001 0.0108748 -0.06299819999999998 -0.015001 0.009631229999999999 -0.06169219999999997 0.014999 0.01919 -0.07172999999999997 -0.015001 0.00947042 -0.06152339999999997 -0.015001 0.00844342 -0.06044489999999998 0.014999 0.01919 -0.07172999999999997 -0.015001 0.009631229999999999 -0.06169219999999997 -0.015001 0.00947042 -0.06152339999999997 0.014999 0.01919 -0.07172999999999997 0.014999 0.01919 -0.07172999999999997 -0.015001 -0.00134311 -0.05016799999999997 -0.015001 -0.001784 -0.04970499999999997 0.014999 -0.001784 -0.04970499999999997 0.014999 0.022293 -0.07567799999999997 0.014999 0.01919 -0.07172999999999997 -0.020924 -0.045 -0.006802999999999972 -0.019001 -0.045 -0.01109499999999997 0.020922 -0.045 -0.006802999999999972 0.020922 -0.045 -0.006802999999999972 0.018999 -0.045 -0.01109499999999997 0.020922 -0.023 -0.006802999999999972 0.018999 -0.023 -0.01109499999999997 0.0044 -0.023 -0.01062899999999997 0.020922 -0.023 -0.006802999999999972 -0.017309 -0.023 -0.02742499999999997 -9.982949999999999e-07 -0.023 -0.01150499999999997 0.018999 -0.023 -0.01109499999999997 -0.025001 -0.00949 -0.108738 -0.025001 -0.014015 -0.105644 -0.025001 0.011478 -0.10759 -0.015001 -0.005611 -0.110101 -0.015001 -0.00949 -0.108738 -0.020001 -0.006904 -0.109647 -0.025001 -0.004318 -0.110556 -0.015001 -0.005611 -0.110101 -0.020001 -0.006904 -0.109647 -0.025001 -0.00949 -0.108738 -0.025001 -0.004318 -0.110556 -0.020001 -0.006904 -0.109647 -0.015001 -0.00949 -0.108738 -0.025001 -0.00949 -0.108738 -0.020001 -0.006904 -0.109647 -0.015001 -0.00360394 -0.110611 -0.015001 -0.004318 -0.110556 -0.020001 -0.001585 -0.110765 -0.015001 -0.0002185 -0.110869 -0.015001 -0.00360394 -0.110611 -0.020001 -0.001585 -0.110765 -0.025001 0.001148 -0.110974 -0.015001 -0.0002185 -0.110869 -0.020001 -0.001585 -0.110765 -0.025001 -0.004318 -0.110556 -0.025001 0.001148 -0.110974 -0.020001 -0.001585 -0.110765 -0.015001 -0.004318 -0.110556 -0.025001 -0.004318 -0.110556 -0.020001 -0.001585 -0.110765 -0.015001 -0.004318 -0.110556 -0.015001 -0.005611 -0.110101 -0.025001 -0.004318 -0.110556 -0.015001 0.001148 -0.110974 -0.015001 0.00329801 -0.11057 -0.015001 -5.00004e-07 -0.113403 -0.015001 -0.0002185 -0.110869 -0.015001 0.001148 -0.110974 -0.015001 -5.00004e-07 -0.113403 -0.015001 -0.00360394 -0.110611 -0.015001 -0.0002185 -0.110869 -0.015001 -5.00004e-07 -0.113403 -0.015001 -0.003772 -0.116235 -0.015001 -0.00360394 -0.110611 -0.015001 -5.00004e-07 -0.113403 -0.015001 0.003771 -0.116235 -0.015001 -0.003772 -0.116235 -0.015001 -5.00004e-07 -0.113403 -0.015001 0.00329801 -0.11057 -0.015001 0.003771 -0.116235 -0.015001 -5.00004e-07 -0.113403 -0.015001 0.011008 -0.11411 0.014999 0.00377101 -0.116235 -0.015001 0.003771 -0.116235 0.014999 0.011008 -0.11411 0.014999 0.00377101 -0.116235 -0.015001 0.011008 -0.11411 0.014999 0.0162255 -0.106478 0.014999 0.015479 -0.107354 0.014999 0.017353 -0.110032 0.014999 0.011008 -0.11411 0.014999 0.017353 -0.110032 0.014999 0.013852 -0.110294 0.014999 0.0103509 -0.110802 0.014999 0.011008 -0.11411 0.014999 0.013852 -0.110294 0.014999 0.015479 -0.107354 0.014999 0.0103509 -0.110802 0.014999 0.013852 -0.110294 0.014999 0.017353 -0.110032 0.014999 0.015479 -0.107354 0.014999 0.013852 -0.110294 -0.015001 -0.006537 -0.07004799999999997 -0.015001 -0.00710472 -0.07032049999999997 -0.015001 -0.00678809 -0.06909369999999997 -0.015001 -0.00445068 -0.06832259999999997 -0.015001 -0.00464697 -0.06969299999999998 -0.015001 -0.0057777 -0.06932159999999997 -0.015001 -0.00678809 -0.06909369999999997 -0.015001 -0.00445068 -0.06832259999999997 -0.015001 -0.0057777 -0.06932159999999997 -0.015001 -0.00519 -0.06979499999999997 -0.015001 -0.006537 -0.07004799999999997 -0.015001 -0.0057777 -0.06932159999999997 -0.015001 -0.00464697 -0.06969299999999998 -0.015001 -0.00519 -0.06979499999999997 -0.015001 -0.0057777 -0.06932159999999997 -0.015001 -0.006537 -0.07004799999999997 -0.015001 -0.00678809 -0.06909369999999997 -0.015001 -0.0057777 -0.06932159999999997 -0.015001 -0.0023343 -0.06812129999999997 -0.015001 -0.00236848 -0.06926499999999997 -0.015001 -0.00349063 -0.06890709999999997 -0.015001 -0.004082 -0.06820099999999997 -0.015001 -0.0023343 -0.06812129999999997 -0.015001 -0.00349063 -0.06890709999999997 -0.015001 -0.00445068 -0.06832259999999997 -0.015001 -0.004082 -0.06820099999999997 -0.015001 -0.00349063 -0.06890709999999997 -0.015001 -0.00464697 -0.06969299999999998 -0.015001 -0.00445068 -0.06832259999999997 -0.015001 -0.00349063 -0.06890709999999997 -0.015001 -0.00236848 -0.06926499999999997 -0.015001 -0.00464697 -0.06969299999999998 -0.015001 -0.00349063 -0.06890709999999997 -0.025001 0.011478 -0.10759 -0.025001 -0.011479 -0.07241999999999997 -0.025001 -0.006537 -0.07004799999999997 -0.015001 -0.006537 -0.07004799999999997 -0.015001 -0.00519 -0.06979499999999997 -0.025001 -0.006537 -0.07004799999999997 -0.017309 -0.023 -0.02742499999999997 -0.019001 -0.023 -0.01109499999999997 -9.982949999999999e-07 -0.023 -0.01150499999999997 -0.019001 -0.045 -0.01109499999999997 -0.020924 -0.045 -0.006802999999999972 -0.019001 -0.023 -0.01109499999999997 0.014999 0.0228548 -0.09295739999999997 0.014999 0.02224 -0.09678599999999997 0.014999 0.025426 -0.09747099999999997 0.014999 0.0205653 -0.100412 0.014999 0.022293 -0.104332 0.014999 0.0229957 -0.09864469999999997 0.014999 0.02224 -0.09678599999999997 0.014999 0.0205653 -0.100412 0.014999 0.0229957 -0.09864469999999997 0.014999 0.022293 -0.104332 0.014999 0.025426 -0.09747099999999997 0.014999 0.0229957 -0.09864469999999997 0.014999 0.025426 -0.09747099999999997 0.014999 0.02224 -0.09678599999999997 0.014999 0.0229957 -0.09864469999999997 0.014999 0.025426 -0.09747099999999997 -0.015001 0.0265 -0.09000499999999997 0.014999 0.0265 -0.09000499999999997 0.014999 0.025426 -0.08253899999999997 -0.015001 0.022293 -0.07567799999999997 0.014999 0.022293 -0.07567799999999997 -0.015001 0.025426 -0.08253899999999997 -0.015001 0.022293 -0.07567799999999997 0.014999 0.025426 -0.08253899999999997 -0.015001 0.0265 -0.09000499999999997 -0.015001 0.025426 -0.08253899999999997 0.014999 0.0265 -0.09000499999999997 -0.0150104 -0.00196059 -0.04961399999999997 -0.015001 -0.00185009 -0.04971309999999998 -0.015001 -0.00185912 -0.04970499999999997 -0.0150104 -0.00196059 -0.04961399999999997 -0.015001 -0.00180512 -0.04975339999999998 -0.015001 -0.00185009 -0.04971309999999998 -0.0150104 -0.00196059 -0.04961399999999997 -0.015001 -0.00180293 -0.04975539999999997 -0.015001 -0.00180512 -0.04975339999999998 -0.0150104 -0.00196059 -0.04961399999999997 -0.015001 -0.00179812 -0.04975969999999997 -0.015001 -0.00180293 -0.04975539999999997 -0.0150104 -0.00196059 -0.04961399999999997 -0.015001 -0.00179255 -0.04976469999999997 -0.015001 -0.00179812 -0.04975969999999997 -0.0150104 -0.00196059 -0.04961399999999997 -0.015001 -0.00178596 -0.04977059999999997 -0.015001 -0.00179255 -0.04976469999999997 -0.0150104 -0.00196059 -0.04961399999999997 -0.015001 -0.00177792 -0.04977789999999997 -0.015001 -0.00178596 -0.04977059999999997 -0.0150104 -0.00196059 -0.04961399999999997 -0.015001 -0.00176771 -0.04978699999999997 -0.015001 -0.00177792 -0.04977789999999997 -0.0150104 -0.00196059 -0.04961399999999997 -0.015001 -0.00175411 -0.04979919999999997 -0.015001 -0.00176771 -0.04978699999999997 -0.0150104 -0.00196059 -0.04961399999999997 -0.015001 -0.00173486 -0.04981649999999997 -0.015001 -0.00175411 -0.04979919999999997 -0.0150104 -0.00196059 -0.04961399999999997 -0.015001 -0.00170546 -0.04984289999999997 -0.015001 -0.00173486 -0.04981649999999997 -0.0150104 -0.00196059 -0.04961399999999997 -0.015001 -0.00165625 -0.04988699999999997 -0.015001 -0.00170546 -0.04984289999999997 -0.0150104 -0.00196059 -0.04961399999999997 -0.015001 -0.00156619 -0.04996779999999997 -0.015001 -0.00165625 -0.04988699999999997 -0.0150104 -0.00196059 -0.04961399999999997 -0.015001 -0.001784 -0.04970499999999997 -0.015001 -0.00185912 -0.04970499999999997 0.014999 0.022293 -0.07567799999999997 -0.015001 0.01919 -0.07172999999999997 0.014999 0.01919 -0.07172999999999997 -0.015001 0.01919 -0.07172999999999997 -0.015001 0.0110087 -0.06350509999999997 -0.015001 0.0110311 -0.06316229999999998 -0.015001 0.0110087 -0.06350509999999997 -0.015001 0.01919 -0.07172999999999997 -0.015001 0.022293 -0.07567799999999997 -0.015001 -0.001784 -0.04970499999999997 -0.015001 -0.00141267 -0.05010559999999997 -0.015001 -0.00134311 -0.05016799999999997 0.021999 -0.045 -5.002229999972244e-06 -0.020924 -0.045 -0.006802999999999972 0.020922 -0.045 -0.006802999999999972 0.021999 -0.023 -5.001269999972245e-06 0.020922 -0.045 -0.006802999999999972 0.020922 -0.023 -0.006802999999999972 0.0044 -0.023 -0.01062899999999997 0.008130999999999999 -0.023 -0.008135999999999971 0.020922 -0.023 -0.006802999999999972 -9.982949999999999e-07 -0.023 -0.01150499999999997 0.0044 -0.023 -0.01062899999999997 0.018999 -0.023 -0.01109499999999997 -0.025001 -0.004318 -0.110556 -0.025001 -0.00949 -0.108738 -0.025001 0.011478 -0.10759 -0.015001 0.001148 -0.110974 -0.015001 -0.0002185 -0.110869 -0.025001 0.001148 -0.110974 -0.025001 0.001148 -0.110974 -0.025001 -0.004318 -0.110556 -0.025001 0.011478 -0.10759 -0.015001 0.00329801 -0.11057 -0.015001 0.001148 -0.110974 -0.020001 0.003842 -0.110468 -0.015001 0.005189 -0.110215 -0.015001 0.00329801 -0.11057 -0.020001 0.003842 -0.110468 -0.025001 0.006536 -0.109962 -0.015001 0.005189 -0.110215 -0.020001 0.003842 -0.110468 -0.025001 0.001148 -0.110974 -0.025001 0.006536 -0.109962 -0.020001 0.003842 -0.110468 -0.015001 0.001148 -0.110974 -0.025001 0.001148 -0.110974 -0.020001 0.003842 -0.110468 -0.015001 0.005189 -0.110215 -0.015001 0.006536 -0.109962 -0.015001 0.007153 -0.112299 -0.015001 0.00329801 -0.11057 -0.015001 0.005189 -0.110215 -0.015001 0.007153 -0.112299 -0.015001 0.003771 -0.116235 -0.015001 0.00329801 -0.11057 -0.015001 0.007153 -0.112299 -0.015001 0.011008 -0.11411 -0.015001 0.003771 -0.116235 -0.015001 0.007153 -0.112299 -0.015001 0.00986662 -0.108363 -0.015001 0.011008 -0.11411 -0.015001 0.007153 -0.112299 -0.015001 0.006536 -0.109962 -0.015001 0.00986662 -0.108363 -0.015001 0.007153 -0.112299 -0.015001 0.017353 -0.110032 0.014999 0.011008 -0.11411 -0.015001 0.011008 -0.11411 0.014999 0.017353 -0.110032 0.014999 0.011008 -0.11411 -0.015001 0.017353 -0.110032 0.014999 0.0205653 -0.100412 0.014999 0.019585 -0.102535 0.014999 0.022293 -0.104332 0.014999 0.0162255 -0.106478 0.014999 0.017353 -0.110032 0.014999 0.0192593 -0.105222 0.014999 0.019585 -0.102535 0.014999 0.0162255 -0.106478 0.014999 0.0192593 -0.105222 0.014999 0.017353 -0.110032 0.014999 0.022293 -0.104332 0.014999 0.0192593 -0.105222 0.014999 0.022293 -0.104332 0.014999 0.019585 -0.102535 0.014999 0.0192593 -0.105222 -0.015001 -0.00519 -0.06979499999999997 -0.015001 -0.00464697 -0.06969299999999998 -0.020001 -0.003843 -0.06954199999999998 -0.015001 -0.00464697 -0.06969299999999998 -0.015001 -0.00236848 -0.06926499999999997 -0.020001 -0.003843 -0.06954199999999998 -0.025001 -0.006537 -0.07004799999999997 -0.015001 -0.00519 -0.06979499999999997 -0.020001 -0.003843 -0.06954199999999998 -0.015001 -0.00236848 -0.06926499999999997 -0.015001 -0.001149 -0.06903599999999997 -0.020001 -0.003843 -0.06954199999999998 -0.025001 -0.001149 -0.06903599999999997 -0.025001 -0.006537 -0.07004799999999997 -0.020001 -0.003843 -0.06954199999999998 -0.015001 -0.001149 -0.06903599999999997 -0.025001 -0.001149 -0.06903599999999997 -0.020001 -0.003843 -0.06954199999999998 -0.015001 -0.000254233 -0.06802639999999997 -0.015001 -0.000163659 -0.06911119999999997 -0.015001 -0.00126607 -0.06864569999999998 -0.015001 -0.0023343 -0.06812129999999997 -0.015001 -0.000254233 -0.06802639999999997 -0.015001 -0.00126607 -0.06864569999999998 -0.015001 -0.00236848 -0.06926499999999997 -0.015001 -0.0023343 -0.06812129999999997 -0.015001 -0.00126607 -0.06864569999999998 -0.015001 -0.001149 -0.06903599999999997 -0.015001 -0.00236848 -0.06926499999999997 -0.015001 -0.00126607 -0.06864569999999998 -0.015001 -0.000163659 -0.06911119999999997 -0.015001 -0.001149 -0.06903599999999997 -0.015001 -0.00126607 -0.06864569999999998 -0.025001 0.011478 -0.10759 -0.025001 -0.006537 -0.07004799999999997 -0.025001 -0.001149 -0.06903599999999997 -9.982949999999999e-07 -0.023 -0.01150499999999997 -0.019001 -0.023 -0.01109499999999997 -0.004402 -0.023 -0.01062899999999997 -0.019001 -0.023 -0.01109499999999997 -0.020924 -0.045 -0.006802999999999972 -0.020924 -0.023 -0.006802999999999972 0.014999 0.022293 -0.104332 -0.015001 0.025426 -0.09747099999999997 0.014999 0.025426 -0.09747099999999997 -0.015001 0.025426 -0.09747099999999997 -0.015001 0.0265 -0.09000499999999997 0.014999 0.025426 -0.09747099999999997 -0.015001 0.022293 -0.07567799999999997 -0.015001 0.01919 -0.07172999999999997 0.014999 0.022293 -0.07567799999999997 -0.015001 0.0108635 -0.06496659999999997 -0.015001 0.010921 -0.06484999999999998 -0.015001 0.022293 -0.07567799999999997 -0.015001 0.022293 -0.07567799999999997 -0.015001 0.010921 -0.06484999999999998 -0.015001 0.0110087 -0.06350509999999997 -0.015001 0.0108635 -0.06496659999999997 -0.015001 0.022293 -0.07567799999999997 -0.015001 0.025426 -0.08253899999999997 -0.015001 0.025426 -0.08253899999999997 -0.015001 0.0265 -0.09000499999999997 -0.015001 0.0100641 -0.06658659999999997 -0.015001 0.025426 -0.08253899999999997 -0.015001 0.0100641 -0.06658659999999997 -0.015001 0.0108635 -0.06496659999999997 -0.015001 -0.001784 -0.04970499999999997 -0.015001 -0.00156619 -0.04996779999999997 -0.015001 -0.00141267 -0.05010559999999997 -0.015001 -0.001784 -0.04970499999999997 -0.015001 -0.00165625 -0.04988699999999997 -0.015001 -0.00156619 -0.04996779999999997 -0.015001 -0.00165625 -0.04988699999999997 -0.015001 -0.001784 -0.04970499999999997 -0.015001 -0.00170546 -0.04984289999999997 -0.015001 -0.00173486 -0.04981649999999997 -0.015001 -0.00170546 -0.04984289999999997 -0.015001 -0.001784 -0.04970499999999997 -0.015001 -0.00175411 -0.04979919999999997 -0.015001 -0.00173486 -0.04981649999999997 -0.015001 -0.001784 -0.04970499999999997 -0.015001 -0.001784 -0.04970499999999997 -0.015001 -0.00176771 -0.04978699999999997 -0.015001 -0.00175411 -0.04979919999999997 -0.015001 -0.00176771 -0.04978699999999997 -0.015001 -0.001784 -0.04970499999999997 -0.015001 -0.00177792 -0.04977789999999997 -0.015001 -0.00177792 -0.04977789999999997 -0.015001 -0.001784 -0.04970499999999997 -0.015001 -0.00178596 -0.04977059999999997 -0.015001 -0.00178596 -0.04977059999999997 -0.015001 -0.001784 -0.04970499999999997 -0.015001 -0.00179255 -0.04976469999999997 -0.015001 -0.00179255 -0.04976469999999997 -0.015001 -0.001784 -0.04970499999999997 -0.015001 -0.00179812 -0.04975969999999997 -0.015001 -0.00179812 -0.04975969999999997 -0.015001 -0.001784 -0.04970499999999997 -0.015001 -0.00180293 -0.04975539999999997 -0.015001 -0.00180293 -0.04975539999999997 -0.015001 -0.001784 -0.04970499999999997 -0.015001 -0.00180512 -0.04975339999999998 -0.015001 -0.00180512 -0.04975339999999998 -0.015001 -0.001784 -0.04970499999999997 -0.015001 -0.00185009 -0.04971309999999998 -0.015001 -0.00185009 -0.04971309999999998 -0.015001 -0.001784 -0.04970499999999997 -0.015001 -0.00185912 -0.04970499999999997 -0.022001 -0.045 -5.002229999972244e-06 -0.020924 -0.045 -0.006802999999999972 0.021999 -0.045 -5.002229999972244e-06 0.020922 -0.045 -0.006802999999999972 0.021999 -0.023 -5.001269999972245e-06 0.021999 -0.045 -5.002229999972244e-06 0.020922 -0.023 -0.006802999999999972 0.010624 -0.023 -0.004405999999999972 0.021999 -0.023 -5.001269999972245e-06 0.008130999999999999 -0.023 -0.008135999999999971 0.010624 -0.023 -0.004405999999999972 0.020922 -0.023 -0.006802999999999972 0.0044 -0.023 -0.01062899999999997 0.008130999999999999 -0.007 -0.008135999999999971 0.008130999999999999 -0.023 -0.008135999999999971 -9.982949999999999e-07 -0.023 -0.01150499999999997 0.0044 -0.007 -0.01062899999999997 0.0044 -0.023 -0.01062899999999997 -0.025001 0.006536 -0.109962 -0.025001 0.001148 -0.110974 -0.025001 0.011478 -0.10759 -0.015001 0.006536 -0.109962 -0.015001 0.005189 -0.110215 -0.025001 0.006536 -0.109962 -0.015001 0.017353 -0.110032 -0.015001 0.014599 -0.104912 -0.015001 0.0154872 -0.10415 -0.015001 0.0102425 -0.108183 -0.015001 0.0114782 -0.10759 -0.015001 0.0136098 -0.10913 -0.015001 0.00986662 -0.108363 -0.015001 0.0102425 -0.108183 -0.015001 0.0136098 -0.10913 -0.015001 0.011008 -0.11411 -0.015001 0.00986662 -0.108363 -0.015001 0.0136098 -0.10913 -0.015001 0.017353 -0.110032 -0.015001 0.011008 -0.11411 -0.015001 0.0136098 -0.10913 -0.015001 0.0114782 -0.10759 -0.015001 0.014599 -0.104912 -0.015001 0.0136098 -0.10913 -0.015001 0.014599 -0.104912 -0.015001 0.017353 -0.110032 -0.015001 0.0136098 -0.10913 -0.015001 0.00986662 -0.108363 -0.015001 0.006536 -0.109962 -0.020001 0.009006999999999999 -0.108776 -0.015001 0.0102425 -0.108183 -0.015001 0.00986662 -0.108363 -0.020001 0.009006999999999999 -0.108776 -0.025001 0.011478 -0.10759 -0.015001 0.0102425 -0.108183 -0.020001 0.009006999999999999 -0.108776 -0.025001 0.006536 -0.109962 -0.025001 0.011478 -0.10759 -0.020001 0.009006999999999999 -0.108776 -0.015001 0.006536 -0.109962 -0.025001 0.006536 -0.109962 -0.020001 0.009006999999999999 -0.108776 -0.015001 0.017353 -0.110032 -0.015001 0.022293 -0.104332 0.014999 0.017353 -0.110032 0.014999 0.017353 -0.110032 -0.015001 0.022293 -0.104332 0.014999 0.022293 -0.104332 -0.015001 -0.001149 -0.06903599999999997 -0.015001 -0.000163659 -0.06911119999999997 -0.025001 -0.001149 -0.06903599999999997 -0.015001 -0.000163659 -0.06911119999999997 -0.015001 0.0002175 -0.06914019999999997 -0.025001 -0.001149 -0.06903599999999997 -0.015001 0.00210479 -0.06928419999999998 -0.015001 0.001903 -0.06792799999999997 -0.015001 0.00183603 -0.06793109999999997 -0.015001 0.004501 -0.06951769999999997 -0.015001 0.004317 -0.06945299999999997 -0.015001 0.00411044 -0.06828649999999997 -0.015001 0.004317 -0.06945299999999997 -0.015001 0.00210479 -0.06928419999999998 -0.015001 0.00316851 -0.06872279999999997 -0.015001 0.001903 -0.06792799999999997 -0.015001 0.00411044 -0.06828649999999997 -0.015001 0.00316851 -0.06872279999999997 -0.015001 0.00411044 -0.06828649999999997 -0.015001 0.004317 -0.06945299999999997 -0.015001 0.00316851 -0.06872279999999997 -0.015001 0.00210479 -0.06928419999999998 -0.015001 0.001903 -0.06792799999999997 -0.015001 0.00316851 -0.06872279999999997 -0.015001 0.0002175 -0.06914019999999997 -0.015001 -0.000163659 -0.06911119999999997 -0.015001 -0.000254233 -0.06802639999999997 -0.015001 0.00183603 -0.06793109999999997 -0.015001 0.00210479 -0.06928419999999998 -0.015001 0.000925279 -0.06860759999999998 -0.015001 -0.000254233 -0.06802639999999997 -0.015001 0.00183603 -0.06793109999999997 -0.015001 0.000925279 -0.06860759999999998 -0.015001 0.00210479 -0.06928419999999998 -0.015001 0.0002175 -0.06914019999999997 -0.015001 0.000925279 -0.06860759999999998 -0.015001 0.0002175 -0.06914019999999997 -0.015001 -0.000254233 -0.06802639999999997 -0.015001 0.000925279 -0.06860759999999998 -0.025001 0.011478 -0.10759 -0.025001 -0.001149 -0.06903599999999997 -0.025001 0.004317 -0.06945299999999997 -0.004402 -0.023 -0.01062899999999997 -9.982790000000001e-07 -0.007 -0.01150499999999997 -9.982949999999999e-07 -0.023 -0.01150499999999997 -0.019001 -0.023 -0.01109499999999997 -0.020924 -0.023 -0.006802999999999972 -0.004402 -0.023 -0.01062899999999997 -0.020924 -0.045 -0.006802999999999972 -0.022001 -0.045 -5.002229999972244e-06 -0.020924 -0.023 -0.006802999999999972 -0.015001 0.022293 -0.104332 -0.015001 0.025426 -0.09747099999999997 0.014999 0.022293 -0.104332 -0.015001 0.025426 -0.09747099999999997 -0.015001 0.0209149 -0.08955199999999998 -0.015001 0.0265 -0.09000499999999997 -0.015001 0.0202098 -0.08481499999999997 -0.015001 0.019957 -0.08346799999999997 -0.015001 0.0265 -0.09000499999999997 -0.015001 0.020968 -0.08885599999999998 -0.015001 0.0202098 -0.08481499999999997 -0.015001 0.0265 -0.09000499999999997 -0.015001 0.0209149 -0.08955199999999998 -0.015001 0.020968 -0.08885599999999998 -0.015001 0.0265 -0.09000499999999997 -0.015001 0.0265 -0.09000499999999997 -0.015001 0.019957 -0.08346799999999997 -0.015001 0.018178 -0.07976149999999997 -0.015001 0.011147 -0.07240479999999998 -0.015001 0.008591 -0.06788599999999997 -0.015001 0.00857579 -0.06789119999999997 -0.015001 0.011147 -0.07240479999999998 -0.015001 0.008591 -0.06788599999999997 -0.015001 0.010058 -0.06659899999999998 -0.015001 0.014015 -0.07436599999999997 -0.015001 0.011147 -0.07240479999999998 -0.015001 0.0100641 -0.06658659999999997 -0.015001 0.0149075 -0.07540599999999997 -0.015001 0.014015 -0.07436599999999997 -0.015001 0.0100641 -0.06658659999999997 -0.015001 0.011147 -0.07240479999999998 -0.015001 0.0100641 -0.06658659999999997 -0.015001 0.010058 -0.06659899999999998 -0.015001 0.0265 -0.09000499999999997 -0.015001 0.017585 -0.07852599999999997 -0.015001 0.0100641 -0.06658659999999997 -0.015001 0.017585 -0.07852599999999997 -0.015001 0.0149075 -0.07540599999999997 -0.015001 0.0100641 -0.06658659999999997 -0.015001 0.0265 -0.09000499999999997 -0.015001 0.018178 -0.07976149999999997 -0.015001 0.017585 -0.07852599999999997 0.020922 -0.045 0.006794000000000027 -0.022001 -0.045 -5.002229999972244e-06 0.021999 -0.045 -5.002229999972244e-06 0.020922 -0.023 0.006794000000000027 0.021999 -0.045 -5.002229999972244e-06 0.021999 -0.023 -5.001269999972245e-06 0.010624 -0.023 -0.004405999999999972 0.011499 -0.023 -5.001269999972245e-06 0.021999 -0.023 -5.001269999972245e-06 0.010624 -0.023 -0.004405999999999972 0.008130999999999999 -0.023 -0.008135999999999971 0.010624 -0.007 -0.004405999999999972 0.010624 -0.007 -0.004405999999999972 0.008130999999999999 -0.023 -0.008135999999999971 0.008130999999999999 -0.007 -0.008135999999999971 0.0044 -0.007 -0.01062899999999997 0.008130999999999999 -0.007 -0.008135999999999971 0.0044 -0.023 -0.01062899999999997 -9.982790000000001e-07 -0.007 -0.01150499999999997 0.0044 -0.007 -0.01062899999999997 -9.982949999999999e-07 -0.023 -0.01150499999999997 -0.015001 0.0114782 -0.10759 -0.015001 0.0102425 -0.108183 -0.025001 0.011478 -0.10759 -0.015001 0.022293 -0.104332 -0.015001 0.018733 -0.09949399999999997 -0.015001 0.0193665 -0.09769219999999998 -0.015001 0.0154872 -0.10415 -0.015001 0.015639 -0.10402 -0.015001 0.0188901 -0.103862 -0.015001 0.017353 -0.110032 -0.015001 0.0154872 -0.10415 -0.015001 0.0188901 -0.103862 -0.015001 0.022293 -0.104332 -0.015001 0.017353 -0.110032 -0.015001 0.0188901 -0.103862 -0.015001 0.0179595 -0.100626 -0.015001 0.018733 -0.09949399999999997 -0.015001 0.0188901 -0.103862 -0.015001 0.015639 -0.10402 -0.015001 0.0179595 -0.100626 -0.015001 0.0188901 -0.103862 -0.015001 0.018733 -0.09949399999999997 -0.015001 0.022293 -0.104332 -0.015001 0.0188901 -0.103862 -0.015001 0.015639 -0.10402 -0.015001 0.0154872 -0.10415 -0.025001 0.015639 -0.10402 -0.015001 0.0154872 -0.10415 -0.015001 0.014599 -0.104912 -0.025001 0.015639 -0.10402 -0.015001 0.014599 -0.104912 -0.015001 0.0114782 -0.10759 -0.020001 0.0135586 -0.105805 -0.025001 0.015639 -0.10402 -0.015001 0.014599 -0.104912 -0.020001 0.0135586 -0.105805 -0.025001 0.011478 -0.10759 -0.025001 0.015639 -0.10402 -0.020001 0.0135586 -0.105805 -0.015001 0.0114782 -0.10759 -0.025001 0.011478 -0.10759 -0.020001 0.0135586 -0.105805 -0.015001 0.0002175 -0.06914019999999997 -0.015001 0.00210479 -0.06928419999999998 -0.020001 0.001584 -0.06924449999999997 -0.015001 0.00210479 -0.06928419999999998 -0.015001 0.004317 -0.06945299999999997 -0.020001 0.001584 -0.06924449999999997 -0.025001 -0.001149 -0.06903599999999997 -0.015001 0.0002175 -0.06914019999999997 -0.020001 0.001584 -0.06924449999999997 -0.015001 0.004317 -0.06945299999999997 -0.025001 0.004317 -0.06945299999999997 -0.020001 0.001584 -0.06924449999999997 -0.025001 0.004317 -0.06945299999999997 -0.025001 -0.001149 -0.06903599999999997 -0.020001 0.001584 -0.06924449999999997 -0.015001 0.004501 -0.06951769999999997 -0.015001 0.00561 -0.06990749999999997 -0.025001 0.004317 -0.06945299999999997 -0.015001 0.004317 -0.06945299999999997 -0.015001 0.004501 -0.06951769999999997 -0.025001 0.004317 -0.06945299999999997 -0.015001 0.004501 -0.06951769999999997 -0.015001 0.00411044 -0.06828649999999997 -0.015001 0.004945 -0.06842199999999997 -0.015001 0.0073972 -0.07053569999999998 -0.015001 0.00561 -0.06990749999999997 -0.015001 0.00575382 -0.06941109999999998 -0.015001 0.00650024 -0.06850069999999997 -0.015001 0.0073972 -0.07053569999999998 -0.015001 0.00575382 -0.06941109999999998 -0.015001 0.004945 -0.06842199999999997 -0.015001 0.00650024 -0.06850069999999997 -0.015001 0.00575382 -0.06941109999999998 -0.015001 0.00561 -0.06990749999999997 -0.015001 0.004501 -0.06951769999999997 -0.015001 0.00575382 -0.06941109999999998 -0.015001 0.004501 -0.06951769999999997 -0.015001 0.004945 -0.06842199999999997 -0.015001 0.00575382 -0.06941109999999998 -0.025001 0.011478 -0.10759 -0.025001 0.004317 -0.06945299999999997 -0.025001 0.009488999999999999 -0.07127099999999997 -0.004402 -0.007 -0.01062899999999997 -9.982790000000001e-07 -0.007 -0.01150499999999997 -0.004402 -0.023 -0.01062899999999997 -0.020924 -0.023 -0.006802999999999972 -0.008133 -0.023 -0.008135999999999971 -0.004402 -0.023 -0.01062899999999997 -0.020924 -0.023 -0.006802999999999972 -0.022001 -0.045 -5.002229999972244e-06 -0.022001 -0.023 -5.001269999972245e-06 -0.015001 0.025426 -0.09747099999999997 -0.015001 0.020551 -0.09432299999999998 -0.015001 0.0208637 -0.09022269999999998 -0.015001 0.025426 -0.09747099999999997 -0.015001 0.0208637 -0.09022269999999998 -0.015001 0.0209149 -0.08955199999999998 -0.015001 0.022293 -0.104332 -0.015001 0.0193665 -0.09769219999999998 -0.015001 0.0223962 -0.09694199999999997 -0.015001 0.025426 -0.09747099999999997 -0.015001 0.022293 -0.104332 -0.015001 0.0223962 -0.09694199999999997 -0.015001 0.0200965 -0.09561579999999997 -0.015001 0.020551 -0.09432299999999998 -0.015001 0.0223962 -0.09694199999999997 -0.015001 0.0193665 -0.09769219999999998 -0.015001 0.0200965 -0.09561579999999997 -0.015001 0.0223962 -0.09694199999999997 -0.015001 0.020551 -0.09432299999999998 -0.015001 0.025426 -0.09747099999999997 -0.015001 0.0223962 -0.09694199999999997 -0.015001 0.0073972 -0.07053569999999998 -0.015001 0.00650024 -0.06850069999999997 -0.015001 0.006744 -0.06851299999999998 -0.015001 0.0106205 -0.07204479999999998 -0.015001 0.00857579 -0.06789119999999997 -0.015001 0.011147 -0.07240479999999998 -0.015001 0.0106205 -0.07204479999999998 -0.015001 0.009488999999999999 -0.07127099999999997 -0.015001 0.008823610000000001 -0.07014799999999997 -0.015001 0.006744 -0.06851299999999998 -0.015001 0.00857579 -0.06789119999999997 -0.015001 0.008823610000000001 -0.07014799999999997 -0.015001 0.009488999999999999 -0.07127099999999997 -0.015001 0.0073972 -0.07053569999999998 -0.015001 0.008823610000000001 -0.07014799999999997 -0.015001 0.0073972 -0.07053569999999998 -0.015001 0.006744 -0.06851299999999998 -0.015001 0.008823610000000001 -0.07014799999999997 -0.015001 0.00857579 -0.06789119999999997 -0.015001 0.0106205 -0.07204479999999998 -0.015001 0.008823610000000001 -0.07014799999999997 -0.015001 0.011147 -0.07240479999999998 -0.015001 0.014015 -0.07436599999999997 -0.020001 0.011752 -0.07281849999999997 -0.015001 0.0106205 -0.07204479999999998 -0.015001 0.011147 -0.07240479999999998 -0.020001 0.011752 -0.07281849999999997 -0.025001 0.009488999999999999 -0.07127099999999997 -0.015001 0.0106205 -0.07204479999999998 -0.020001 0.011752 -0.07281849999999997 -0.025001 0.014015 -0.07436599999999997 -0.025001 0.009488999999999999 -0.07127099999999997 -0.020001 0.011752 -0.07281849999999997 -0.015001 0.014015 -0.07436599999999997 -0.025001 0.014015 -0.07436599999999997 -0.020001 0.011752 -0.07281849999999997 -0.015001 0.0149075 -0.07540599999999997 -0.025001 0.014015 -0.07436599999999997 -0.015001 0.014015 -0.07436599999999997 -0.015001 0.0149075 -0.07540599999999997 -0.015001 0.017585 -0.07852599999999997 -0.020001 0.0158 -0.07644599999999997 -0.025001 0.014015 -0.07436599999999997 -0.015001 0.0149075 -0.07540599999999997 -0.020001 0.0158 -0.07644599999999997 -0.025001 0.017585 -0.07852599999999997 -0.025001 0.014015 -0.07436599999999997 -0.020001 0.0158 -0.07644599999999997 -0.015001 0.017585 -0.07852599999999997 -0.025001 0.017585 -0.07852599999999997 -0.020001 0.0158 -0.07644599999999997 -0.015001 0.018178 -0.07976149999999997 -0.025001 0.017585 -0.07852599999999997 -0.015001 0.017585 -0.07852599999999997 -0.015001 0.018178 -0.07976149999999997 -0.015001 0.019957 -0.08346799999999997 -0.020001 0.018771 -0.08099699999999997 -0.025001 0.017585 -0.07852599999999997 -0.015001 0.018178 -0.07976149999999997 -0.020001 0.018771 -0.08099699999999997 -0.025001 0.019957 -0.08346799999999997 -0.025001 0.017585 -0.07852599999999997 -0.020001 0.018771 -0.08099699999999997 -0.015001 0.019957 -0.08346799999999997 -0.025001 0.019957 -0.08346799999999997 -0.020001 0.018771 -0.08099699999999997 -0.015001 0.0202098 -0.08481499999999997 -0.025001 0.019957 -0.08346799999999997 -0.015001 0.019957 -0.08346799999999997 -0.015001 0.0202098 -0.08481499999999997 -0.015001 0.020968 -0.08885599999999998 -0.020001 0.0204625 -0.08616199999999997 -0.025001 0.019957 -0.08346799999999997 -0.015001 0.0202098 -0.08481499999999997 -0.020001 0.0204625 -0.08616199999999997 -0.025001 0.020968 -0.08885599999999998 -0.025001 0.019957 -0.08346799999999997 -0.020001 0.0204625 -0.08616199999999997 -0.015001 0.020968 -0.08885599999999998 -0.025001 0.020968 -0.08885599999999998 -0.020001 0.0204625 -0.08616199999999997 -0.015001 0.0208637 -0.09022269999999998 -0.025001 0.020968 -0.08885599999999998 -0.015001 0.0209149 -0.08955199999999998 -0.015001 0.0209149 -0.08955199999999998 -0.025001 0.020968 -0.08885599999999998 -0.015001 0.020968 -0.08885599999999998 -0.020924 -0.045 0.006794000000000027 -0.022001 -0.045 -5.002229999972244e-06 0.020922 -0.045 0.006794000000000027 0.020922 -0.045 0.006794000000000027 0.021999 -0.045 -5.002229999972244e-06 0.020922 -0.023 0.006794000000000027 0.021999 -0.023 -5.001269999972245e-06 0.011499 -0.023 -5.001269999972245e-06 0.020922 -0.023 0.006794000000000027 0.011499 -0.023 -5.001269999972245e-06 0.010624 -0.023 -0.004405999999999972 0.011499 -0.007 -5.000569999972244e-06 0.011499 -0.007 -5.000569999972244e-06 0.010624 -0.023 -0.004405999999999972 0.010624 -0.007 -0.004405999999999972 0.008130999999999999 -0.007 -0.008135999999999971 -0.010626 -0.007 -0.004405999999999972 0.010624 -0.007 -0.004405999999999972 0.0044 -0.007 -0.01062899999999997 -0.010626 -0.007 -0.004405999999999972 0.008130999999999999 -0.007 -0.008135999999999971 -9.982790000000001e-07 -0.007 -0.01150499999999997 -0.010626 -0.007 -0.004405999999999972 0.0044 -0.007 -0.01062899999999997 -0.015001 0.0200965 -0.09561579999999997 -0.015001 0.0193665 -0.09769219999999998 -0.020001 0.019642 -0.09690849999999997 -0.025001 0.020551 -0.09432299999999998 -0.015001 0.0200965 -0.09561579999999997 -0.020001 0.019642 -0.09690849999999997 -0.025001 0.018733 -0.09949399999999997 -0.025001 0.020551 -0.09432299999999998 -0.020001 0.019642 -0.09690849999999997 -0.015001 0.018733 -0.09949399999999997 -0.025001 0.018733 -0.09949399999999997 -0.020001 0.019642 -0.09690849999999997 -0.015001 0.0193665 -0.09769219999999998 -0.015001 0.018733 -0.09949399999999997 -0.020001 0.019642 -0.09690849999999997 -0.015001 0.0179595 -0.100626 -0.025001 0.018733 -0.09949399999999997 -0.015001 0.018733 -0.09949399999999997 -0.015001 0.0179595 -0.100626 -0.015001 0.015639 -0.10402 -0.020001 0.017186 -0.101757 -0.025001 0.018733 -0.09949399999999997 -0.015001 0.0179595 -0.100626 -0.020001 0.017186 -0.101757 -0.025001 0.015639 -0.10402 -0.025001 0.018733 -0.09949399999999997 -0.020001 0.017186 -0.101757 -0.015001 0.015639 -0.10402 -0.025001 0.015639 -0.10402 -0.020001 0.017186 -0.101757 -0.025001 0.018733 -0.09949399999999997 -0.025001 0.015639 -0.10402 -0.025001 0.011478 -0.10759 -0.015001 0.0073972 -0.07053569999999998 -0.015001 0.009488999999999999 -0.07127099999999997 -0.020001 0.006903 -0.07036199999999997 -0.015001 0.009488999999999999 -0.07127099999999997 -0.025001 0.009488999999999999 -0.07127099999999997 -0.020001 0.006903 -0.07036199999999997 -0.015001 0.00561 -0.06990749999999997 -0.015001 0.0073972 -0.07053569999999998 -0.020001 0.006903 -0.07036199999999997 -0.025001 0.009488999999999999 -0.07127099999999997 -0.025001 0.004317 -0.06945299999999997 -0.020001 0.006903 -0.07036199999999997 -0.025001 0.004317 -0.06945299999999997 -0.015001 0.00561 -0.06990749999999997 -0.020001 0.006903 -0.07036199999999997 -0.025001 0.011478 -0.10759 -0.025001 0.009488999999999999 -0.07127099999999997 -0.025001 0.014015 -0.07436599999999997 -0.004402 -0.007 -0.01062899999999997 -0.010626 -0.007 -0.004405999999999972 -9.982790000000001e-07 -0.007 -0.01150499999999997 -0.008133 -0.023 -0.008135999999999971 -0.004402 -0.007 -0.01062899999999997 -0.004402 -0.023 -0.01062899999999997 -0.008133 -0.023 -0.008135999999999971 -0.020924 -0.023 -0.006802999999999972 -0.010626 -0.023 -0.004405999999999972 -0.022001 -0.045 -5.002229999972244e-06 -0.020924 -0.045 0.006794000000000027 -0.022001 -0.023 -5.001269999972245e-06 -0.020924 -0.023 -0.006802999999999972 -0.022001 -0.023 -5.001269999972245e-06 -0.010626 -0.023 -0.004405999999999972 -0.015001 0.0208637 -0.09022269999999998 -0.015001 0.020551 -0.09432299999999998 -0.020001 0.0207595 -0.09158949999999998 -0.025001 0.020968 -0.08885599999999998 -0.015001 0.0208637 -0.09022269999999998 -0.020001 0.0207595 -0.09158949999999998 -0.025001 0.020551 -0.09432299999999998 -0.025001 0.020968 -0.08885599999999998 -0.020001 0.0207595 -0.09158949999999998 -0.015001 0.020551 -0.09432299999999998 -0.025001 0.020551 -0.09432299999999998 -0.020001 0.0207595 -0.09158949999999998 -0.015001 0.0200965 -0.09561579999999997 -0.025001 0.020551 -0.09432299999999998 -0.015001 0.020551 -0.09432299999999998 -0.015001 0.009488999999999999 -0.07127099999999997 -0.015001 0.0106205 -0.07204479999999998 -0.025001 0.009488999999999999 -0.07127099999999997 -0.025001 0.017585 -0.07852599999999997 -0.025001 0.011478 -0.10759 -0.025001 0.014015 -0.07436599999999997 -0.025001 0.019957 -0.08346799999999997 -0.025001 0.011478 -0.10759 -0.025001 0.017585 -0.07852599999999997 -0.025001 0.020968 -0.08885599999999998 -0.025001 0.011478 -0.10759 -0.025001 0.019957 -0.08346799999999997 0.017797 -0.045 0.01292700000000003 -0.020924 -0.045 0.006794000000000027 0.020922 -0.045 0.006794000000000027 0.017797 -0.023 0.01292700000000003 0.020922 -0.045 0.006794000000000027 0.020922 -0.023 0.006794000000000027 0.011499 -0.023 -5.001269999972245e-06 0.010624 -0.023 0.004396000000000027 0.020922 -0.023 0.006794000000000027 0.010624 -0.007 0.004396000000000027 0.011499 -0.023 -5.001269999972245e-06 0.011499 -0.007 -5.000569999972244e-06 0.010624 -0.007 -0.004405999999999972 -0.010626 -0.007 -0.004405999999999972 0.011499 -0.007 -5.000569999972244e-06 -0.025001 0.020551 -0.09432299999999998 -0.025001 0.018733 -0.09949399999999997 -0.025001 0.011478 -0.10759 -0.010626 -0.007 -0.004405999999999972 -0.004402 -0.007 -0.01062899999999997 -0.008133 -0.007 -0.008135999999999971 -0.008133 -0.007 -0.008135999999999971 -0.004402 -0.007 -0.01062899999999997 -0.008133 -0.023 -0.008135999999999971 -0.008133 -0.023 -0.008135999999999971 -0.010626 -0.023 -0.004405999999999972 -0.008133 -0.007 -0.008135999999999971 -0.022001 -0.023 -5.001269999972245e-06 -0.020924 -0.045 0.006794000000000027 -0.020924 -0.023 0.006794000000000027 -0.010626 -0.023 -0.004405999999999972 -0.022001 -0.023 -5.001269999972245e-06 -0.011501 -0.023 -5.001269999972245e-06 -0.025001 0.020551 -0.09432299999999998 -0.025001 0.011478 -0.10759 -0.025001 0.020968 -0.08885599999999998 -0.017799 -0.045 0.01292700000000003 -0.020924 -0.045 0.006794000000000027 0.017797 -0.045 0.01292700000000003 0.017797 -0.045 0.01292700000000003 0.020922 -0.045 0.006794000000000027 0.017797 -0.023 0.01292700000000003 0.020922 -0.023 0.006794000000000027 0.008130999999999999 -0.023 0.008127000000000028 0.017797 -0.023 0.01292700000000003 0.010624 -0.023 0.004396000000000027 0.008130999999999999 -0.023 0.008127000000000028 0.020922 -0.023 0.006794000000000027 0.010624 -0.023 0.004396000000000027 0.011499 -0.023 -5.001269999972245e-06 0.010624 -0.007 0.004396000000000027 0.011499 -0.007 -5.000569999972244e-06 -0.010626 -0.007 -0.004405999999999972 0.010624 -0.007 0.004396000000000027 -0.008133 -0.007 -0.008135999999999971 -0.010626 -0.023 -0.004405999999999972 -0.010626 -0.007 -0.004405999999999972 -0.020924 -0.045 0.006794000000000027 -0.017799 -0.045 0.01292700000000003 -0.020924 -0.023 0.006794000000000027 -0.022001 -0.023 -5.001269999972245e-06 -0.020924 -0.023 0.006794000000000027 -0.010626 -0.023 0.004396000000000027 -0.011501 -0.023 -5.001269999972245e-06 -0.022001 -0.023 -5.001269999972245e-06 -0.010626 -0.023 0.004396000000000027 -0.010626 -0.023 -0.004405999999999972 -0.011501 -0.023 -5.001269999972245e-06 -0.010626 -0.007 -0.004405999999999972 0.01293 -0.045 0.01779400000000003 -0.017799 -0.045 0.01292700000000003 0.017797 -0.045 0.01292700000000003 0.017797 -0.023 0.01292700000000003 0.01293 -0.023 0.01779400000000003 0.017797 -0.045 0.01292700000000003 0.008130999999999999 -0.023 0.008127000000000028 0.0044 -0.023 0.01062000000000003 0.017797 -0.023 0.01292700000000003 0.008130999999999999 -0.023 0.008127000000000028 0.010624 -0.023 0.004396000000000027 0.008130999999999999 -0.007 0.008127000000000028 0.008130999999999999 -0.007 0.008127000000000028 0.010624 -0.023 0.004396000000000027 0.010624 -0.007 0.004396000000000027 0.010624 -0.007 0.004396000000000027 -0.010626 -0.007 -0.004405999999999972 0.008130999999999999 -0.007 0.008127000000000028 -0.020924 -0.023 0.006794000000000027 -0.017799 -0.045 0.01292700000000003 -0.017799 -0.023 0.01292700000000003 -0.010626 -0.023 0.004396000000000027 -0.020924 -0.023 0.006794000000000027 -0.008133 -0.023 0.008127000000000028 -0.011501 -0.023 -5.001269999972245e-06 -0.010626 -0.023 0.004396000000000027 -0.011501 -0.007 -5.000569999972244e-06 -0.010626 -0.007 -0.004405999999999972 -0.011501 -0.023 -5.001269999972245e-06 -0.011501 -0.007 -5.000569999972244e-06 -0.012932 -0.045 0.01779400000000003 -0.017799 -0.045 0.01292700000000003 0.01293 -0.045 0.01779400000000003 0.017797 -0.045 0.01292700000000003 0.01293 -0.023 0.01779400000000003 0.01293 -0.045 0.01779400000000003 -0.017799 -0.023 0.01292700000000003 0.01293 -0.023 0.01779400000000003 0.017797 -0.023 0.01292700000000003 0.017797 -0.023 0.01292700000000003 0.0044 -0.023 0.01062000000000003 -9.97102e-07 -0.023 0.01149500000000003 0.008130999999999999 -0.023 0.008127000000000028 0.0044 -0.007 0.01062000000000003 0.0044 -0.023 0.01062000000000003 0.008130999999999999 -0.007 0.008127000000000028 0.0044 -0.007 0.01062000000000003 0.008130999999999999 -0.023 0.008127000000000028 -0.010626 -0.007 -0.004405999999999972 0.0044 -0.007 0.01062000000000003 0.008130999999999999 -0.007 0.008127000000000028 -0.012932 -0.045 0.01779400000000003 -0.017799 -0.023 0.01292700000000003 -0.017799 -0.045 0.01292700000000003 -0.020924 -0.023 0.006794000000000027 -0.017799 -0.023 0.01292700000000003 -0.008133 -0.023 0.008127000000000028 -0.010626 -0.023 0.004396000000000027 -0.008133 -0.023 0.008127000000000028 -0.010626 -0.007 0.004396000000000027 -0.011501 -0.007 -5.000569999972244e-06 -0.010626 -0.023 0.004396000000000027 -0.010626 -0.007 0.004396000000000027 -0.010626 -0.007 -0.004405999999999972 -0.011501 -0.007 -5.000569999972244e-06 -0.010626 -0.007 0.004396000000000027 0.01293 -0.045 0.01779400000000003 0.006797 -0.045 0.02091800000000003 -0.012932 -0.045 0.01779400000000003 0.01293 -0.023 0.01779400000000003 0.006797 -0.023 0.02091800000000003 0.01293 -0.045 0.01779400000000003 -0.017799 -0.023 0.01292700000000003 -0.012932 -0.023 0.01779400000000003 0.01293 -0.023 0.01779400000000003 0.017797 -0.023 0.01292700000000003 -9.97102e-07 -0.023 0.01149500000000003 -0.017799 -0.023 0.01292700000000003 0.0044 -0.023 0.01062000000000003 -9.97087e-07 -0.007 0.01149500000000003 -9.97102e-07 -0.023 0.01149500000000003 0.0044 -0.007 0.01062000000000003 -9.97087e-07 -0.007 0.01149500000000003 0.0044 -0.023 0.01062000000000003 -0.010626 -0.007 -0.004405999999999972 -9.97087e-07 -0.007 0.01149500000000003 0.0044 -0.007 0.01062000000000003 -0.012932 -0.023 0.01779400000000003 -0.017799 -0.023 0.01292700000000003 -0.012932 -0.045 0.01779400000000003 -0.008133 -0.023 0.008127000000000028 -0.017799 -0.023 0.01292700000000003 -0.004402 -0.023 0.01062000000000003 -0.010626 -0.007 0.004396000000000027 -0.008133 -0.023 0.008127000000000028 -0.008133 -0.007 0.008127000000000028 -0.010626 -0.007 -0.004405999999999972 -0.010626 -0.007 0.004396000000000027 -0.008133 -0.007 0.008127000000000028 0.006797 -0.045 0.02091800000000003 -0.006799 -0.045 0.02091800000000003 -0.012932 -0.045 0.01779400000000003 0.01293 -0.045 0.01779400000000003 0.006797 -0.023 0.02091800000000003 0.006797 -0.045 0.02091800000000003 0.006797 -0.023 0.02091800000000003 0.01293 -0.023 0.01779400000000003 -0.012932 -0.023 0.01779400000000003 -0.017799 -0.023 0.01292700000000003 -9.97102e-07 -0.023 0.01149500000000003 -0.004402 -0.023 0.01062000000000003 -9.97087e-07 -0.007 0.01149500000000003 -0.004402 -0.007 0.01062000000000003 -9.97102e-07 -0.023 0.01149500000000003 -0.010626 -0.007 -0.004405999999999972 -0.004402 -0.007 0.01062000000000003 -9.97087e-07 -0.007 0.01149500000000003 -0.006799 -0.045 0.02091800000000003 -0.012932 -0.023 0.01779400000000003 -0.012932 -0.045 0.01779400000000003 -0.004402 -0.023 0.01062000000000003 -0.008133 -0.007 0.008127000000000028 -0.008133 -0.023 0.008127000000000028 -0.010626 -0.007 -0.004405999999999972 -0.008133 -0.007 0.008127000000000028 -0.004402 -0.007 0.01062000000000003 0.006797 -0.045 0.02091800000000003 -9.96856e-07 -0.045 0.02199500000000003 -0.006799 -0.045 0.02091800000000003 0.006797 -0.023 0.02091800000000003 -9.96864e-07 -0.023 0.02199500000000003 0.006797 -0.045 0.02091800000000003 0.006797 -0.023 0.02091800000000003 -0.012932 -0.023 0.01779400000000003 -0.006799 -0.023 0.02091800000000003 -9.97102e-07 -0.023 0.01149500000000003 -0.004402 -0.007 0.01062000000000003 -0.004402 -0.023 0.01062000000000003 -0.006799 -0.023 0.02091800000000003 -0.012932 -0.023 0.01779400000000003 -0.006799 -0.045 0.02091800000000003 -0.004402 -0.007 0.01062000000000003 -0.008133 -0.007 0.008127000000000028 -0.004402 -0.023 0.01062000000000003 -9.96856e-07 -0.045 0.02199500000000003 -0.006799 -0.023 0.02091800000000003 -0.006799 -0.045 0.02091800000000003 0.006797 -0.045 0.02091800000000003 -9.96864e-07 -0.023 0.02199500000000003 -9.96856e-07 -0.045 0.02199500000000003 -9.96864e-07 -0.023 0.02199500000000003 0.006797 -0.023 0.02091800000000003 -0.006799 -0.023 0.02091800000000003 -9.96864e-07 -0.023 0.02199500000000003 -0.006799 -0.023 0.02091800000000003 -9.96856e-07 -0.045 0.02199500000000003 0.033499 -0.036284 -0.05372699999999997 0.033499 -0.035397 -0.05842899999999997 0.033499 -0.021268 -0.09766299999999997 0.033499 -0.035601 -0.04880199999999997 0.033499 -0.036284 -0.05372699999999997 0.033499 -0.021268 -0.09766299999999997 0.033499 -0.035397 -0.05842899999999997 0.014999 -0.021876 -0.09788199999999997 0.033499 -0.021268 -0.09766299999999997 0.033499 -0.036284 -0.05372699999999997 0.014999 -0.036005 -0.05864799999999997 0.033499 -0.035397 -0.05842899999999997 0.033499 -0.033356 -0.04436599999999997 0.033499 -0.035601 -0.04880199999999997 0.033499 -0.021268 -0.09766299999999997 0.033499 -0.035601 -0.04880199999999997 0.014999 -0.03693 -0.05374499999999997 0.033499 -0.036284 -0.05372699999999997 0.014999 -0.021876 -0.09788199999999997 0.014999 -0.021532 -0.09877999999999998 0.033499 -0.021268 -0.09766299999999997 0.033499 -0.035397 -0.05842899999999997 0.014999 -0.036005 -0.05864799999999997 0.014999 -0.0222876 -0.09673899999999998 0.033499 -0.035397 -0.05842899999999997 0.014999 -0.0222876 -0.09673899999999998 0.014999 -0.021876 -0.09788199999999997 0.014999 -0.03693 -0.05374499999999997 0.014999 -0.0368802 -0.05400919999999997 0.033499 -0.036284 -0.05372699999999997 0.014999 -0.0368802 -0.05400919999999997 0.014999 -0.036005 -0.05864799999999997 0.033499 -0.036284 -0.05372699999999997 0.033499 -0.029792 -0.04089899999999997 0.033499 -0.033356 -0.04436599999999997 0.033499 -0.021268 -0.09766299999999997 0.033499 -0.033356 -0.04436599999999997 0.0151152 -0.0362 -0.04858329999999998 0.033499 -0.035601 -0.04880199999999997 0.0151152 -0.0362 -0.04858329999999998 0.0151123 -0.0362142 -0.04861119999999997 0.033499 -0.035601 -0.04880199999999997 0.014999 -0.0363698 -0.04970499999999997 0.014999 -0.03693 -0.05374499999999997 0.033499 -0.035601 -0.04880199999999997 0.0151123 -0.0362142 -0.04861119999999997 0.014999 -0.0363698 -0.04970499999999997 0.033499 -0.035601 -0.04880199999999997 0.033499 -0.021268 -0.09766299999999997 0.014999 -0.021532 -0.09877999999999998 0.033499 -0.020933 -0.09853599999999997 0.033499 -0.025296 -0.03877599999999997 0.033499 -0.029792 -0.04089899999999997 0.033499 -0.021268 -0.09766299999999997 0.0155905 -0.0338603 -0.04399519999999997 0.033499 -0.033356 -0.04436599999999997 0.0155979 -0.0337867 -0.04392399999999997 0.033499 -0.033356 -0.04436599999999997 0.033499 -0.029792 -0.04089899999999997 0.0156022 -0.0337438 -0.04388249999999997 0.0155979 -0.0337867 -0.04392399999999997 0.033499 -0.033356 -0.04436599999999997 0.0156022 -0.0337438 -0.04388249999999997 0.0155905 -0.0338603 -0.04399519999999997 0.0151152 -0.0362 -0.04858329999999998 0.033499 -0.033356 -0.04436599999999997 0.014999 -0.021532 -0.09877999999999998 0.014999 -0.0207306 -0.100168 0.033499 -0.020933 -0.09853599999999997 0.014999 -0.0207306 -0.100168 0.014999 -0.018366 -0.104264 0.033499 -0.020933 -0.09853599999999997 0.033499 -0.020933 -0.09853599999999997 0.033499 -0.017855 -0.103868 0.033499 -0.021268 -0.09766299999999997 0.033499 -0.020353 -0.03822899999999997 0.033499 -0.025296 -0.03877599999999997 0.033499 -0.021268 -0.09766299999999997 0.033499 -0.029792 -0.04089899999999997 0.033499 -0.025296 -0.03877599999999997 0.0159749 -0.0299034 -0.04028399999999997 0.0159634 -0.0301408 -0.04039569999999997 0.033499 -0.029792 -0.04089899999999997 0.0159749 -0.0299034 -0.04028399999999997 0.0156022 -0.0337438 -0.04388249999999997 0.033499 -0.029792 -0.04089899999999997 0.0159634 -0.0301408 -0.04039569999999997 0.033499 -0.020933 -0.09853599999999997 0.014999 -0.018366 -0.104264 0.033499 -0.017855 -0.103868 0.014999 -0.013837 -0.10869 0.033499 -0.017855 -0.103868 0.014999 -0.016369 -0.106216 0.014999 -0.016369 -0.106216 0.033499 -0.017855 -0.103868 0.014999 -0.018366 -0.104264 0.033499 -0.017855 -0.103868 0.033499 -0.013453 -0.108171 0.033499 -0.021268 -0.09766299999999997 0.033499 -0.015501 -0.03931699999999997 0.033499 -0.020353 -0.03822899999999997 0.033499 -0.021268 -0.09766299999999997 0.033499 -0.025296 -0.03877599999999997 0.033499 -0.020353 -0.03822899999999997 0.016195 -0.0251401 -0.03815979999999997 0.0161913 -0.0254597 -0.03819499999999997 0.033499 -0.025296 -0.03877599999999997 0.016195 -0.0251401 -0.03815979999999997 0.0159749 -0.0299034 -0.04028399999999997 0.033499 -0.025296 -0.03877599999999997 0.0161913 -0.0254597 -0.03819499999999997 0.016195 -0.0251401 -0.03815979999999997 0.033499 -0.020353 -0.03822899999999997 0.0162152 -0.0233709 -0.03796439999999997 0.0162152 -0.0233709 -0.03796439999999997 0.033499 -0.020353 -0.03822899999999997 0.0162501 -0.0203204 -0.03762759999999997 0.033499 -0.013453 -0.108171 0.033499 -0.017855 -0.103868 0.014999 -0.013837 -0.10869 0.014999 -0.008283 -0.11173 0.033499 -0.013453 -0.108171 0.014999 -0.0104947 -0.110519 0.014999 -0.0104947 -0.110519 0.033499 -0.013453 -0.108171 0.014999 -0.013837 -0.10869 0.033499 -0.013453 -0.108171 0.033499 -0.008052999999999999 -0.111127 0.033499 -0.021268 -0.09766299999999997 0.033499 -0.011265 -0.04192099999999997 0.033499 -0.015501 -0.03931699999999997 0.033499 -0.021268 -0.09766299999999997 0.033499 -0.020353 -0.03822899999999997 0.033499 -0.015501 -0.03931699999999997 0.0162426 -0.0199942 -0.03770049999999997 0.0162501 -0.0203204 -0.03762759999999997 0.033499 -0.020353 -0.03822899999999997 0.0162426 -0.0199942 -0.03770049999999997 0.014999 0.01776 -0.07499899999999997 0.014999 0.00718103 -0.06247869999999997 0.033499 0.017266 -0.07541599999999997 0.033499 0.017266 -0.07541599999999997 0.014999 0.00718103 -0.06247869999999997 0.014999 0.00199864 -0.05634529999999997 0.033499 0.017266 -0.07541599999999997 0.014999 0.00199864 -0.05634529999999997 0.014999 0.000209368 -0.05422759999999997 0.0155745 -0.00833217 -0.04414979999999998 0.033499 0.017266 -0.07541599999999997 0.014999 0.000209368 -0.05422759999999997 0.0162426 -0.0199942 -0.03770049999999997 0.033499 -0.015501 -0.03931699999999997 0.0161333 -0.0152729 -0.03875469999999998 0.033499 -0.015501 -0.03931699999999997 0.033499 -0.011265 -0.04192099999999997 0.0161171 -0.0150167 -0.03891159999999997 0.0161333 -0.0152729 -0.03875469999999998 0.033499 -0.015501 -0.03931699999999997 0.0161171 -0.0150167 -0.03891159999999997 0.0161171 -0.0150167 -0.03891159999999997 0.033499 -0.011265 -0.04192099999999997 0.0158536 -0.0108606 -0.04145549999999997 0.0158536 -0.0108606 -0.04145549999999997 0.033499 -0.011265 -0.04192099999999997 0.0158458 -0.0107864 -0.04153049999999997 0.033499 -0.011265 -0.04192099999999997 0.033499 -0.009648 -0.04356299999999997 0.0158458 -0.0107864 -0.04153049999999997 0.0156769 -0.009172100000000001 -0.04316129999999997 0.0158458 -0.0107864 -0.04153049999999997 0.033499 -0.009648 -0.04356299999999997 0.0155745 -0.00833217 -0.04414979999999998 0.0156769 -0.009172100000000001 -0.04316129999999997 0.033499 -0.009648 -0.04356299999999997 0.033499 0.017266 -0.07541599999999997 0.0155745 -0.00833217 -0.04414979999999998 0.033499 -0.009648 -0.04356299999999997 0.033499 -0.008052999999999999 -0.111127 0.033499 -0.013453 -0.108171 0.014999 -0.008283 -0.11173 0.014999 -0.002115 -0.113159 0.033499 -0.008052999999999999 -0.111127 0.014999 -0.00366932 -0.112799 0.014999 -0.00366932 -0.112799 0.033499 -0.008052999999999999 -0.111127 0.014999 -0.008283 -0.11173 0.033499 -0.021268 -0.09766299999999997 0.033499 -0.008052999999999999 -0.111127 0.033499 -0.00205599 -0.112516 -0.015001 -0.009771999999999999 -0.07007799999999997 -0.015001 -0.0110356 -0.07092759999999997 -0.041001 -0.009771999999999999 -0.07007799999999997 -0.015001 -0.0110356 -0.07092759999999997 -0.015001 -0.014744 -0.07342099999999997 -0.041001 -0.009771999999999999 -0.07007799999999997 -0.015001 -0.018629 -0.07798099999999997 -0.041001 -0.014744 -0.07342099999999997 -0.015001 -0.014744 -0.07342099999999997 -0.015001 -0.021141 -0.08342099999999997 -0.041001 -0.018629 -0.07798099999999997 -0.015001 -0.018629 -0.07798099999999997 -0.015001 -0.021164 -0.08349599999999997 -0.041001 -0.021141 -0.08341999999999997 -0.015001 -0.021141 -0.08342099999999997 -0.015001 -0.021985 -0.08509899999999997 -0.041001 -0.021164 -0.08349599999999997 -0.015001 -0.021164 -0.08349599999999997 -0.015001 -0.021985 -0.08509899999999997 -0.015001 -0.023452 -0.08638599999999998 -0.041001 -0.021985 -0.08509899999999997 -0.015001 -0.023452 -0.08638599999999998 -0.015001 -0.025299 -0.08701299999999997 -0.041001 -0.023452 -0.08638599999999998 -0.015001 -0.025299 -0.08701299999999997 -0.015001 -0.027246 -0.08688499999999998 -0.041001 -0.025299 -0.08701299999999997 -0.015001 -0.027246 -0.08688499999999998 -0.015001 -0.028996 -0.08602199999999997 -0.041001 -0.027246 -0.08688499999999998 -0.015001 -0.030282 -0.08455499999999998 -0.041001 -0.028996 -0.08602199999999997 -0.015001 -0.028996 -0.08602199999999997 -0.015001 -0.030844 -0.08308599999999997 -0.041001 -0.030282 -0.08455499999999998 -0.015001 -0.030282 -0.08455499999999998 -0.015001 -0.036766 -0.05498099999999997 -0.041001 -0.036766 -0.05498099999999997 -0.015001 -0.030844 -0.08308599999999997 -0.015001 -0.037048 -0.05074599999999997 -0.041001 -0.036766 -0.05498099999999997 -0.015001 -0.0368311 -0.05400319999999997 -0.015001 -0.0368311 -0.05400319999999997 -0.041001 -0.036766 -0.05498099999999997 -0.015001 -0.036766 -0.05498099999999997 -0.0153411 -0.0360611 -0.04642229999999997 -0.041001 -0.037048 -0.05074599999999997 -0.015001 -0.0368104 -0.04970499999999997 -0.015001 -0.0368104 -0.04970499999999997 -0.041001 -0.037048 -0.05074599999999997 -0.015001 -0.037048 -0.05074599999999997 0.033499 -0.009648 -0.04356299999999997 0.033499 -0.011265 -0.04192099999999997 0.033499 -0.021268 -0.09766299999999997 0.033499 0.019576 -0.07870199999999997 0.014999 0.01776 -0.07499899999999997 0.033499 0.017266 -0.07541599999999997 0.033499 -0.021268 -0.09766299999999997 0.033499 0.017266 -0.07541599999999997 0.033499 -0.002001 -0.07061299999999997 0.033499 -0.009648 -0.04356299999999997 0.033499 -0.021268 -0.09766299999999997 0.033499 -0.002001 -0.07061299999999997 0.033499 0.017266 -0.07541599999999997 0.033499 -0.009648 -0.04356299999999997 0.033499 -0.002001 -0.07061299999999997 0.033499 -0.00205599 -0.112516 0.033499 -0.008052999999999999 -0.111127 0.014999 -0.002115 -0.113159 0.014999 0.00421101 -0.112871 0.033499 -0.00205599 -0.112516 0.014999 0.00349286 -0.112904 0.014999 0.00349286 -0.112904 0.033499 -0.00205599 -0.112516 0.014999 -0.002115 -0.113159 0.033499 -0.021268 -0.09766299999999997 0.033499 -0.00205599 -0.112516 0.033499 0.004094 -0.112236 -0.015001 -0.004082 -0.06820099999999997 -0.015001 -0.00445068 -0.06832259999999997 -0.041001 -0.004082 -0.06819999999999997 -0.015001 -0.00445068 -0.06832259999999997 -0.015001 -0.00678809 -0.06909369999999997 -0.041001 -0.004082 -0.06819999999999997 -0.015001 -0.009385249999999999 -0.06995039999999997 -0.015001 -0.009771999999999999 -0.07007799999999997 -0.041001 -0.004082 -0.06819999999999997 -0.015001 -0.00678809 -0.06909369999999997 -0.015001 -0.009385249999999999 -0.06995039999999997 -0.041001 -0.004082 -0.06819999999999997 -0.041001 -0.004082 -0.06819999999999997 -0.015001 -0.009771999999999999 -0.07007799999999997 -0.041001 -0.009771999999999999 -0.07007799999999997 -0.041001 -0.009771999999999999 -0.07007799999999997 -0.015001 -0.014744 -0.07342099999999997 -0.041001 -0.014744 -0.07342099999999997 -0.041001 -0.018629 -0.07798099999999997 -0.041001 -0.014744 -0.07342099999999997 -0.015001 -0.018629 -0.07798099999999997 -0.041001 -0.021141 -0.08341999999999997 -0.041001 -0.018629 -0.07798099999999997 -0.015001 -0.021141 -0.08342099999999997 -0.041001 -0.021164 -0.08349599999999997 -0.041001 -0.021141 -0.08341999999999997 -0.015001 -0.021164 -0.08349599999999997 -0.041001 -0.021985 -0.08509899999999997 -0.041001 -0.021164 -0.08349599999999997 -0.015001 -0.021985 -0.08509899999999997 -0.041001 -0.021985 -0.08509899999999997 -0.015001 -0.023452 -0.08638599999999998 -0.041001 -0.023452 -0.08638599999999998 -0.041001 -0.023452 -0.08638599999999998 -0.015001 -0.025299 -0.08701299999999997 -0.041001 -0.025299 -0.08701299999999997 -0.041001 -0.025299 -0.08701299999999997 -0.015001 -0.027246 -0.08688499999999998 -0.041001 -0.027246 -0.08688499999999998 -0.041001 -0.027246 -0.08688499999999998 -0.015001 -0.028996 -0.08602199999999997 -0.041001 -0.028996 -0.08602199999999997 -0.041001 -0.030282 -0.08455499999999998 -0.041001 -0.028996 -0.08602199999999997 -0.015001 -0.030282 -0.08455499999999998 -0.041001 -0.030844 -0.08308599999999997 -0.041001 -0.030282 -0.08455499999999998 -0.015001 -0.030844 -0.08308599999999997 -0.041001 -0.036766 -0.05498099999999997 -0.041001 -0.030844 -0.08308599999999997 -0.015001 -0.030844 -0.08308599999999997 -0.041001 -0.037048 -0.05074599999999997 -0.041001 -0.036766 -0.05498099999999997 -0.015001 -0.037048 -0.05074599999999997 -0.041001 -0.036048 -0.04636499999999998 -0.041001 -0.037048 -0.05074599999999997 -0.0153411 -0.0360611 -0.04642229999999997 -0.015347 -0.036048 -0.04636499999999998 -0.041001 -0.036048 -0.04636499999999998 -0.0153411 -0.0360611 -0.04642229999999997 -0.0157386 -0.0338657 -0.04258439999999997 -0.041001 -0.036048 -0.04636499999999998 -0.0155351 -0.0350001 -0.04454949999999997 -0.0155351 -0.0350001 -0.04454949999999997 -0.041001 -0.036048 -0.04636499999999998 -0.015347 -0.036048 -0.04636499999999998 0.033499 0.022599 -0.09051899999999997 0.014999 0.023244 -0.09053399999999998 0.024249 0.022567 -0.08742479999999997 0.014999 0.023244 -0.09053399999999998 0.014999 0.0225384 -0.08436039999999997 0.024249 0.022567 -0.08742479999999997 0.014999 0.022525 -0.08424299999999997 0.033499 0.022599 -0.09051899999999997 0.024249 0.022567 -0.08742479999999997 0.014999 0.0225384 -0.08436039999999997 0.014999 0.022525 -0.08424299999999997 0.024249 0.022567 -0.08742479999999997 0.014999 0.020135 -0.07837899999999998 0.033499 0.021899 -0.08440299999999998 0.014999 0.022525 -0.08424299999999997 0.014999 0.020135 -0.07837899999999998 0.014999 0.01776 -0.07499899999999997 0.033499 0.019576 -0.07870199999999997 0.033499 0.017266 -0.07541599999999997 0.033499 -0.021268 -0.09766299999999997 0.033499 0.019576 -0.07870199999999997 0.033499 0.004094 -0.112236 0.033499 -0.00205599 -0.112516 0.014999 0.00421101 -0.112871 0.014999 0.010224 -0.110887 0.033499 0.004094 -0.112236 0.014999 0.00421101 -0.112871 0.014999 0.015479 -0.107354 0.033499 0.009940010000000001 -0.110307 0.014999 0.0103509 -0.110802 0.014999 0.0103509 -0.110802 0.033499 0.009940010000000001 -0.110307 0.014999 0.010224 -0.110887 0.033499 -0.021268 -0.09766299999999997 0.033499 0.004094 -0.112236 0.033499 0.009940010000000001 -0.110307 -0.041001 0.001903 -0.06792799999999997 -0.015001 -0.004082 -0.06820099999999997 -0.041001 -0.004082 -0.06819999999999997 -0.041001 -0.004082 -0.06819999999999997 -0.041001 -0.009771999999999999 -0.07007799999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.009771999999999999 -0.07007799999999997 -0.041001 -0.014744 -0.07342099999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.014744 -0.07342099999999997 -0.041001 -0.018629 -0.07798099999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.018629 -0.07798099999999997 -0.041001 -0.021141 -0.08341999999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.021141 -0.08341999999999997 -0.041001 -0.021164 -0.08349599999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.021164 -0.08349599999999997 -0.041001 -0.021985 -0.08509899999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.021985 -0.08509899999999997 -0.041001 -0.023452 -0.08638599999999998 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.023452 -0.08638599999999998 -0.041001 -0.025299 -0.08701299999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.025299 -0.08701299999999997 -0.041001 -0.027246 -0.08688499999999998 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.027246 -0.08688499999999998 -0.041001 -0.028996 -0.08602199999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.028996 -0.08602199999999997 -0.041001 -0.030282 -0.08455499999999998 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.030282 -0.08455499999999998 -0.041001 -0.030844 -0.08308599999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.030844 -0.08308599999999997 -0.041001 -0.036766 -0.05498099999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.036766 -0.05498099999999997 -0.041001 -0.037048 -0.05074599999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.037048 -0.05074599999999997 -0.041001 -0.036048 -0.04636499999999998 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.033802 -0.04247399999999997 -0.041001 -0.036048 -0.04636499999999998 -0.0157386 -0.0338657 -0.04258439999999997 -0.0157501 -0.033802 -0.04247399999999997 -0.041001 -0.033802 -0.04247399999999997 -0.0157386 -0.0338657 -0.04258439999999997 -0.0157501 -0.033802 -0.04247399999999997 -0.0160538 -0.0306414 -0.03954169999999997 -0.041001 -0.033802 -0.04247399999999997 -0.0160538 -0.0306414 -0.03954169999999997 -0.0160666 -0.030508 -0.03941799999999997 -0.041001 -0.030508 -0.03941799999999997 -0.041001 -0.033802 -0.04247399999999997 -0.0160538 -0.0306414 -0.03954169999999997 -0.041001 -0.030508 -0.03941799999999997 -0.0160666 -0.030508 -0.03941799999999997 -0.0162589 -0.0266549 -0.03756229999999997 -0.041001 -0.030508 -0.03941799999999997 -0.0162589 -0.0266549 -0.03756229999999997 -0.0162686 -0.026459 -0.03746799999999997 -0.041001 -0.026459 -0.03746799999999997 -0.041001 -0.030508 -0.03941799999999997 -0.0162589 -0.0266549 -0.03756229999999997 -0.041001 -0.026459 -0.03746799999999997 -0.0162686 -0.026459 -0.03746799999999997 -0.0163174 -0.0233368 -0.03699719999999997 -0.041001 -0.026459 -0.03746799999999997 -0.0163174 -0.0233368 -0.03699719999999997 -0.0163345 -0.0222439 -0.03683239999999997 -0.041001 -0.026459 -0.03746799999999997 0.014999 0.02224 -0.09678599999999997 0.014999 0.0228548 -0.09295739999999997 0.033499 0.021622 -0.09659699999999997 0.014999 0.0228548 -0.09295739999999997 0.014999 0.023244 -0.09053399999999998 0.033499 0.021622 -0.09659699999999997 0.033499 0.021622 -0.09659699999999997 0.014999 0.023244 -0.09053399999999998 0.033499 0.022599 -0.09051899999999997 0.033499 0.022599 -0.09051899999999997 0.014999 0.022525 -0.08424299999999997 0.033499 0.021899 -0.08440299999999998 0.033499 0.019576 -0.07870199999999997 0.033499 0.021899 -0.08440299999999998 0.014999 0.020135 -0.07837899999999998 0.033499 0.019576 -0.07870199999999997 0.033499 -0.021268 -0.09766299999999997 0.033499 0.021899 -0.08440299999999998 -0.0163345 -0.0222439 -0.03683239999999997 -0.016338 -0.022016 -0.03679799999999997 -0.041001 -0.022016 -0.03679799999999997 -0.041001 -0.026459 -0.03746799999999997 -0.0163345 -0.0222439 -0.03683239999999997 -0.041001 -0.022016 -0.03679799999999997 -0.016338 -0.022016 -0.03679799999999997 -0.016272 -0.0177902 -0.03743519999999997 -0.041001 -0.022016 -0.03679799999999997 -0.016272 -0.0177902 -0.03743519999999997 -0.0162686 -0.017573 -0.03746799999999997 -0.041001 -0.017573 -0.03746799999999997 -0.041001 -0.022016 -0.03679799999999997 -0.016272 -0.0177902 -0.03743519999999997 -0.041001 -0.017573 -0.03746799999999997 -0.0162686 -0.017573 -0.03746799999999997 -0.016075 -0.0136913 -0.03933749999999997 -0.041001 -0.017573 -0.03746799999999997 -0.016075 -0.0136913 -0.03933749999999997 -0.0160666 -0.013524 -0.03941799999999997 -0.041001 -0.013524 -0.03941799999999997 -0.041001 -0.017573 -0.03746799999999997 -0.016075 -0.0136913 -0.03933749999999997 -0.041001 -0.013524 -0.03941799999999997 -0.0160666 -0.013524 -0.03941799999999997 -0.0159434 -0.0120061 -0.04060729999999997 -0.041001 -0.013524 -0.03941799999999997 -0.0159434 -0.0120061 -0.04060729999999997 -0.0159388 -0.011949 -0.04065199999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.013524 -0.03941799999999997 -0.0159434 -0.0120061 -0.04060729999999997 -0.041001 -0.011949 -0.04065199999999997 -0.0159388 -0.011949 -0.04065199999999997 -0.0150104 -0.00196059 -0.04961399999999997 -0.041001 -0.011949 -0.04065199999999997 -0.015001 -0.00141267 -0.05010559999999997 -0.015001 -0.00134311 -0.05016799999999997 -0.041001 -0.011949 -0.04065199999999997 -0.015001 -0.00156619 -0.04996779999999997 -0.015001 -0.00141267 -0.05010559999999997 -0.041001 -0.011949 -0.04065199999999997 -0.0150104 -0.00196059 -0.04961399999999997 -0.015001 -0.00156619 -0.04996779999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.011949 -0.04065199999999997 -0.015001 -0.00134311 -0.05016799999999997 -0.015001 0.009429999999999999 -0.05983399999999997 -0.015001 0.011048 -0.06290299999999997 -0.015001 0.0110311 -0.06316229999999998 -0.015001 0.0109901 -0.06311919999999997 -0.015001 0.011048 -0.06290299999999997 -0.015001 0.0109901 -0.06311919999999997 -0.015001 0.0109063 -0.06303119999999997 -0.015001 -0.00134311 -0.05016799999999997 -0.015001 0.00839001 -0.06038879999999997 -0.015001 0.009429999999999999 -0.05983399999999997 -0.015001 0.0108748 -0.06299819999999998 -0.015001 0.011048 -0.06290299999999997 -0.015001 0.0109063 -0.06303119999999997 -0.015001 0.00839001 -0.06038879999999997 -0.015001 0.009429999999999999 -0.05983399999999997 -0.015001 0.00844342 -0.06044489999999998 -0.015001 0.0108748 -0.06299819999999998 -0.015001 0.011048 -0.06290299999999997 -0.015001 0.0103396 -0.06202659999999997 -0.015001 0.009631229999999999 -0.06169219999999997 -0.015001 0.0108748 -0.06299819999999998 -0.015001 0.0103396 -0.06202659999999997 -0.015001 0.010421 -0.06105499999999997 -0.015001 0.009631229999999999 -0.06169219999999997 -0.015001 0.0103396 -0.06202659999999997 -0.015001 0.011048 -0.06290299999999997 -0.015001 0.010421 -0.06105499999999997 -0.015001 0.0103396 -0.06202659999999997 -0.015001 0.00947042 -0.06152339999999997 -0.015001 0.010421 -0.06105499999999997 -0.015001 0.00943221 -0.06067869999999997 -0.015001 0.00844342 -0.06044489999999998 -0.015001 0.00947042 -0.06152339999999997 -0.015001 0.00943221 -0.06067869999999997 -0.015001 0.009429999999999999 -0.05983399999999997 -0.015001 0.00844342 -0.06044489999999998 -0.015001 0.00943221 -0.06067869999999997 -0.015001 0.010421 -0.06105499999999997 -0.015001 0.009429999999999999 -0.05983399999999997 -0.015001 0.00943221 -0.06067869999999997 -0.015001 0.00947042 -0.06152339999999997 -0.015001 0.009631229999999999 -0.06169219999999997 -0.015001 0.010421 -0.06105499999999997 0.033499 0.004094 -0.112236 0.014999 0.010224 -0.110887 0.033499 0.009940010000000001 -0.110307 0.033499 0.015049 -0.106872 0.033499 0.009940010000000001 -0.110307 0.014999 0.015479 -0.107354 0.014999 0.015479 -0.107354 0.014999 0.0162255 -0.106478 0.033499 0.015049 -0.106872 0.014999 0.0162255 -0.106478 0.014999 0.019585 -0.102535 0.033499 0.015049 -0.106872 0.033499 -0.021268 -0.09766299999999997 0.033499 0.009940010000000001 -0.110307 0.033499 0.015049 -0.106872 -0.041001 0.001903 -0.06792799999999997 -0.041001 -0.004082 -0.06819999999999997 -0.041001 -0.011949 -0.04065199999999997 -0.015001 0.001903 -0.06792799999999997 -0.015001 0.00183603 -0.06793109999999997 -0.041001 0.001903 -0.06792799999999997 -0.015001 0.00183603 -0.06793109999999997 -0.015001 -0.000254233 -0.06802639999999997 -0.041001 0.001903 -0.06792799999999997 -0.015001 -0.0023343 -0.06812129999999997 -0.015001 -0.004082 -0.06820099999999997 -0.041001 0.001903 -0.06792799999999997 -0.015001 -0.000254233 -0.06802639999999997 -0.015001 -0.0023343 -0.06812129999999997 -0.041001 0.001903 -0.06792799999999997 -0.041001 -0.036048 -0.04636499999999998 -0.041001 -0.033802 -0.04247399999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.033802 -0.04247399999999997 -0.041001 -0.030508 -0.03941799999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.030508 -0.03941799999999997 -0.041001 -0.026459 -0.03746799999999997 -0.041001 -0.011949 -0.04065199999999997 0.014999 0.019585 -0.102535 0.014999 0.0205653 -0.100412 0.033499 0.019041 -0.102187 0.014999 0.0205653 -0.100412 0.014999 0.02224 -0.09678599999999997 0.033499 0.019041 -0.102187 0.033499 0.019041 -0.102187 0.014999 0.02224 -0.09678599999999997 0.033499 0.021622 -0.09659699999999997 0.033499 0.022599 -0.09051899999999997 0.033499 -0.021268 -0.09766299999999997 0.033499 0.021622 -0.09659699999999997 0.033499 0.021899 -0.08440299999999998 0.033499 -0.021268 -0.09766299999999997 0.033499 0.022599 -0.09051899999999997 -0.041001 -0.026459 -0.03746799999999997 -0.041001 -0.022016 -0.03679799999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.022016 -0.03679799999999997 -0.041001 -0.017573 -0.03746799999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.017573 -0.03746799999999997 -0.041001 -0.013524 -0.03941799999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 -0.011949 -0.04065199999999997 -0.015001 0.009429999999999999 -0.05983399999999997 -0.041001 0.009429999999999999 -0.05983399999999997 -0.015001 0.010921 -0.06484999999999998 -0.041001 0.011048 -0.06290299999999997 -0.015001 0.0110087 -0.06350509999999997 -0.015001 0.0110087 -0.06350509999999997 -0.041001 0.011048 -0.06290299999999997 -0.015001 0.0110311 -0.06316229999999998 -0.015001 0.0110311 -0.06316229999999998 -0.041001 0.011048 -0.06290299999999997 -0.015001 0.011048 -0.06290299999999997 -0.015001 0.011048 -0.06290299999999997 -0.041001 0.010421 -0.06105499999999997 -0.015001 0.010421 -0.06105499999999997 -0.015001 0.010421 -0.06105499999999997 -0.041001 0.009429999999999999 -0.05983399999999997 -0.015001 0.009429999999999999 -0.05983399999999997 0.033499 0.015049 -0.106872 0.014999 0.019585 -0.102535 0.033499 0.019041 -0.102187 0.033499 0.019041 -0.102187 0.033499 -0.021268 -0.09766299999999997 0.033499 0.015049 -0.106872 -0.041001 0.004945 -0.06842199999999997 -0.041001 0.001903 -0.06792799999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 0.004945 -0.06842199999999997 -0.015001 0.001903 -0.06792799999999997 -0.041001 0.001903 -0.06792799999999997 0.033499 0.021622 -0.09659699999999997 0.033499 -0.021268 -0.09766299999999997 0.033499 0.019041 -0.102187 -0.015001 0.010058 -0.06659899999999998 -0.041001 0.010921 -0.06484899999999998 -0.015001 0.0100641 -0.06658659999999997 -0.015001 0.0100641 -0.06658659999999997 -0.041001 0.010921 -0.06484899999999998 -0.015001 0.0108635 -0.06496659999999997 -0.015001 0.0108635 -0.06496659999999997 -0.041001 0.010921 -0.06484899999999998 -0.015001 0.010921 -0.06484999999999998 -0.041001 0.009429999999999999 -0.05983399999999997 -0.041001 0.010421 -0.06105499999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 0.010921 -0.06484899999999998 -0.041001 0.011048 -0.06290299999999997 -0.015001 0.010921 -0.06484999999999998 -0.041001 0.011048 -0.06290299999999997 -0.041001 0.010421 -0.06105499999999997 -0.015001 0.011048 -0.06290299999999997 -0.041001 0.010421 -0.06105499999999997 -0.041001 0.009429999999999999 -0.05983399999999997 -0.015001 0.010421 -0.06105499999999997 -0.041001 0.006744 -0.06851299999999998 -0.041001 0.004945 -0.06842199999999997 -0.041001 -0.011949 -0.04065199999999997 -0.015001 0.004945 -0.06842199999999997 -0.015001 0.00411044 -0.06828649999999997 -0.041001 0.004945 -0.06842199999999997 -0.015001 0.00411044 -0.06828649999999997 -0.015001 0.001903 -0.06792799999999997 -0.041001 0.004945 -0.06842199999999997 -0.015001 0.010058 -0.06659899999999998 -0.015001 0.008591 -0.06788599999999997 -0.041001 0.010058 -0.06659899999999998 -0.015001 0.008591 -0.06788599999999997 -0.015001 0.00857579 -0.06789119999999997 -0.041001 0.008591 -0.06788599999999997 -0.015001 0.00857579 -0.06789119999999997 -0.015001 0.006744 -0.06851299999999998 -0.041001 0.008591 -0.06788599999999997 -0.041001 0.010058 -0.06659899999999998 -0.041001 0.010921 -0.06484899999999998 -0.015001 0.010058 -0.06659899999999998 -0.041001 0.011048 -0.06290299999999997 -0.041001 -0.011949 -0.04065199999999997 -0.041001 0.010421 -0.06105499999999997 -0.041001 0.010921 -0.06484899999999998 -0.041001 -0.011949 -0.04065199999999997 -0.041001 0.011048 -0.06290299999999997 -0.041001 0.008591 -0.06788599999999997 -0.041001 0.006744 -0.06851299999999998 -0.041001 -0.011949 -0.04065199999999997 -0.041001 0.006744 -0.06851299999999998 -0.015001 0.004945 -0.06842199999999997 -0.041001 0.004945 -0.06842199999999997 -0.015001 0.006744 -0.06851299999999998 -0.015001 0.00650024 -0.06850069999999997 -0.041001 0.006744 -0.06851299999999998 -0.015001 0.00650024 -0.06850069999999997 -0.015001 0.004945 -0.06842199999999997 -0.041001 0.006744 -0.06851299999999998 -0.041001 0.010058 -0.06659899999999998 -0.015001 0.008591 -0.06788599999999997 -0.041001 0.008591 -0.06788599999999997 -0.041001 0.008591 -0.06788599999999997 -0.015001 0.006744 -0.06851299999999998 -0.041001 0.006744 -0.06851299999999998 -0.041001 0.010921 -0.06484899999999998 -0.041001 0.010058 -0.06659899999999998 -0.041001 -0.011949 -0.04065199999999997 -0.041001 0.010058 -0.06659899999999998 -0.041001 0.008591 -0.06788599999999997 -0.041001 -0.011949 -0.04065199999999997 0.01685 -0.07126 -0.02537499999999997 -0.016247 -0.07126 -0.02960999999999997 0.016245 -0.07126 -0.02960999999999997 -0.016247 -0.07126 -0.02960999999999997 -0.016062 -0.07013 -0.03208299999999997 0.016245 -0.07126 -0.02960999999999997 -0.019377 -0.07126 -0.01650099999999997 -0.016247 -0.07126 -0.02960999999999997 0.01685 -0.07126 -0.02537499999999997 0.01685 -0.07126 -0.02537499999999997 0.016245 -0.07126 -0.02960999999999997 0.01606 -0.07013 -0.03208299999999997 0.016245 -0.07126 -0.02960999999999997 -0.016062 -0.07013 -0.03208299999999997 0.01606 -0.07013 -0.03208299999999997 -0.016247 -0.07126 -0.02960999999999997 -0.019377 -0.07126 -0.01650099999999997 -0.016062 -0.07013 -0.03208299999999997 0.021704 -0.07126 -0.01136899999999997 -0.019377 -0.07126 -0.01650099999999997 0.01685 -0.07126 -0.02537499999999997 0.01685 -0.07126 -0.02537499999999997 0.01606 -0.07013 -0.03208299999999997 0.015999 -0.068998 -0.03456299999999998 0.01606 -0.07013 -0.03208299999999997 -0.016062 -0.07013 -0.03208299999999997 0.015999 -0.068998 -0.03456299999999998 -0.016062 -0.07013 -0.03208299999999997 -0.019377 -0.07126 -0.01650099999999997 -0.016001 -0.068998 -0.03456299999999998 -0.021706 -0.07126 -0.01136899999999997 -0.019377 -0.07126 -0.01650099999999997 0.021704 -0.07126 -0.01136899999999997 0.01685 -0.07126 -0.02537499999999997 0.021704 -0.05826 -0.01136899999999997 0.021704 -0.07126 -0.01136899999999997 0.01685 -0.07126 -0.02537499999999997 0.015999 -0.068998 -0.03456299999999998 0.01685 -0.05826 -0.02537499999999997 -0.016062 -0.07013 -0.03208299999999997 -0.016001 -0.068998 -0.03456299999999998 0.015999 -0.068998 -0.03456299999999998 -0.016001 -0.054708 -0.03456299999999998 -0.016001 -0.068998 -0.03456299999999998 -0.019377 -0.07126 -0.01650099999999997 -0.019377 -0.07126 -0.01650099999999997 -0.021706 -0.07126 -0.01136899999999997 -0.019377 -0.05826 -0.01650099999999997 0.02341 -0.07126 -0.007225999999999972 -0.021706 -0.07126 -0.01136899999999997 0.021704 -0.07126 -0.01136899999999997 0.02341 -0.05826 -0.007225999999999972 0.021704 -0.07126 -0.01136899999999997 0.021704 -0.05826 -0.01136899999999997 0.021704 -0.05826 -0.01136899999999997 0.01685 -0.07126 -0.02537499999999997 0.01685 -0.05826 -0.02537499999999997 0.01685 -0.05826 -0.02537499999999997 0.015999 -0.068998 -0.03456299999999998 0.016608 -0.05826 -0.02678299999999997 0.015999 -0.041927 -0.09385399999999998 0.015999 -0.068998 -0.03456299999999998 -0.016001 -0.068998 -0.03456299999999998 -0.016001 -0.030102 -0.08845499999999998 -0.016001 -0.068998 -0.03456299999999998 -0.016001 -0.054708 -0.03456299999999998 -0.016153 -0.056489 -0.03066099999999997 -0.016001 -0.054708 -0.03456299999999998 -0.019377 -0.07126 -0.01650099999999997 -0.019377 -0.05826 -0.01650099999999997 -0.021706 -0.07126 -0.01136899999999997 -0.021706 -0.05826 -0.01136899999999997 -0.01661 -0.05826 -0.02678299999999997 -0.019377 -0.07126 -0.01650099999999997 -0.019377 -0.05826 -0.01650099999999997 -0.022075 -0.07126 -0.01063499999999997 -0.021706 -0.07126 -0.01136899999999997 0.02341 -0.07126 -0.007225999999999972 0.02341 -0.07126 -0.007225999999999972 0.021704 -0.07126 -0.01136899999999997 0.02341 -0.05826 -0.007225999999999972 0.021704 -0.05826 -0.01136899999999997 -0.022075 -0.05826 -0.01063499999999997 0.02341 -0.05826 -0.007225999999999972 0.01685 -0.05826 -0.02537499999999997 -0.019377 -0.05826 -0.01650099999999997 0.021704 -0.05826 -0.01136899999999997 0.016608 -0.05826 -0.02678299999999997 0.015999 -0.068998 -0.03456299999999998 0.016151 -0.056489 -0.03066099999999997 0.016608 -0.05826 -0.02678299999999997 -0.019377 -0.05826 -0.01650099999999997 0.01685 -0.05826 -0.02537499999999997 -0.016001 -0.068998 -0.03456299999999998 -0.016001 -0.041927 -0.09385399999999998 0.015999 -0.041927 -0.09385399999999998 0.015999 -0.054708 -0.03456299999999998 0.015999 -0.068998 -0.03456299999999998 0.015999 -0.041927 -0.09385399999999998 -0.016001 -0.030102 -0.08845499999999998 -0.016001 -0.041927 -0.09385399999999998 -0.016001 -0.068998 -0.03456299999999998 0.015999 -0.030102 -0.08845499999999998 -0.016001 -0.030102 -0.08845499999999998 -0.016001 -0.054708 -0.03456299999999998 -0.016001 -0.054708 -0.03456299999999998 -0.016153 -0.056489 -0.03066099999999997 0.016151 -0.056489 -0.03066099999999997 -0.019377 -0.07126 -0.01650099999999997 -0.01661 -0.05826 -0.02678299999999997 -0.016153 -0.056489 -0.03066099999999997 -0.021706 -0.07126 -0.01136899999999997 -0.022075 -0.07126 -0.01063499999999997 -0.021706 -0.05826 -0.01136899999999997 -0.019377 -0.05826 -0.01650099999999997 -0.021706 -0.05826 -0.01136899999999997 0.021704 -0.05826 -0.01136899999999997 -0.01661 -0.05826 -0.02678299999999997 -0.019377 -0.05826 -0.01650099999999997 0.016608 -0.05826 -0.02678299999999997 -0.024227 -0.07126 -0.003655999999999972 -0.022075 -0.07126 -0.01063499999999997 0.02341 -0.07126 -0.007225999999999972 0.024499 -0.05826 -5.002809999972244e-06 0.02341 -0.07126 -0.007225999999999972 0.02341 -0.05826 -0.007225999999999972 -0.022075 -0.05826 -0.01063499999999997 -0.024227 -0.05826 -0.003655999999999972 0.02341 -0.05826 -0.007225999999999972 -0.021706 -0.05826 -0.01136899999999997 -0.022075 -0.05826 -0.01063499999999997 0.021704 -0.05826 -0.01136899999999997 0.016151 -0.056489 -0.03066099999999997 0.015999 -0.068998 -0.03456299999999998 0.015999 -0.054708 -0.03456299999999998 0.016151 -0.056489 -0.03066099999999997 -0.01661 -0.05826 -0.02678299999999997 0.016608 -0.05826 -0.02678299999999997 0.015999 -0.041927 -0.09385399999999998 -0.016001 -0.041927 -0.09385399999999998 0.015756 -0.040773 -0.09638099999999997 0.015999 -0.054708 -0.03456299999999998 0.015999 -0.041927 -0.09385399999999998 0.015999 -0.030102 -0.08845499999999998 -0.015758 -0.028948 -0.09098199999999997 -0.016001 -0.041927 -0.09385399999999998 -0.016001 -0.030102 -0.08845499999999998 0.015999 -0.030102 -0.08845499999999998 -0.016001 -0.054708 -0.03456299999999998 0.015999 -0.054708 -0.03456299999999998 -0.016153 -0.056489 -0.03066099999999997 -0.01661 -0.05826 -0.02678299999999997 0.016151 -0.056489 -0.03066099999999997 0.015999 -0.054708 -0.03456299999999998 -0.016001 -0.054708 -0.03456299999999998 0.016151 -0.056489 -0.03066099999999997 -0.021706 -0.05826 -0.01136899999999997 -0.022075 -0.07126 -0.01063499999999997 -0.022075 -0.05826 -0.01063499999999997 -0.022075 -0.07126 -0.01063499999999997 -0.024227 -0.07126 -0.003655999999999972 -0.022075 -0.05826 -0.01063499999999997 0.024499 -0.07126 -5.003379999972244e-06 -0.024227 -0.07126 -0.003655999999999972 0.02341 -0.07126 -0.007225999999999972 0.024499 -0.07126 -5.003379999972244e-06 0.02341 -0.07126 -0.007225999999999972 0.024499 -0.05826 -5.002809999972244e-06 0.02341 -0.05826 -0.007225999999999972 -0.024227 -0.05826 -0.003655999999999972 0.024499 -0.05826 -5.002809999972244e-06 -0.022075 -0.05826 -0.01063499999999997 -0.024227 -0.07126 -0.003655999999999972 -0.024227 -0.05826 -0.003655999999999972 -0.016001 -0.041927 -0.09385399999999998 -0.015758 -0.040773 -0.09638099999999997 0.015756 -0.040773 -0.09638099999999997 0.015756 -0.040773 -0.09638099999999997 0.015999 -0.030102 -0.08845499999999998 0.015999 -0.041927 -0.09385399999999998 -0.015758 -0.040773 -0.09638099999999997 -0.016001 -0.041927 -0.09385399999999998 -0.015758 -0.028948 -0.09098199999999997 -0.024227 -0.07126 0.003647000000000028 -0.024227 -0.07126 -0.003655999999999972 0.024499 -0.07126 -5.003379999972244e-06 0.02341 -0.05826 0.007217000000000028 0.024499 -0.07126 -5.003379999972244e-06 0.024499 -0.05826 -5.002809999972244e-06 -0.024227 -0.05826 -0.003655999999999972 -0.024227 -0.05826 0.003647000000000028 0.024499 -0.05826 -5.002809999972244e-06 -0.024227 -0.07126 -0.003655999999999972 -0.024227 -0.07126 0.003647000000000028 -0.024227 -0.05826 -0.003655999999999972 0.015756 -0.040773 -0.09638099999999997 -0.015758 -0.040773 -0.09638099999999997 0.013855 -0.038605 -0.101132 0.015999 -0.030102 -0.08845499999999998 0.015756 -0.040773 -0.09638099999999997 0.015756 -0.028948 -0.09098199999999997 -0.013857 -0.026779 -0.09573199999999997 -0.015758 -0.040773 -0.09638099999999997 -0.015758 -0.028948 -0.09098199999999997 0.02341 -0.07126 0.007217000000000028 -0.024227 -0.07126 0.003647000000000028 0.024499 -0.07126 -5.003379999972244e-06 0.02341 -0.07126 0.007217000000000028 0.024499 -0.07126 -5.003379999972244e-06 0.02341 -0.05826 0.007217000000000028 0.024499 -0.05826 -5.002809999972244e-06 -0.024227 -0.05826 0.003647000000000028 0.02341 -0.05826 0.007217000000000028 -0.024227 -0.05826 -0.003655999999999972 -0.024227 -0.07126 0.003647000000000028 -0.024227 -0.05826 0.003647000000000028 -0.015758 -0.040773 -0.09638099999999997 -0.013857 -0.038605 -0.101132 0.013855 -0.038605 -0.101132 0.013855 -0.038605 -0.101132 0.015756 -0.028948 -0.09098199999999997 0.015756 -0.040773 -0.09638099999999997 -0.015758 -0.040773 -0.09638099999999997 -0.013857 -0.026779 -0.09573199999999997 -0.013857 -0.038605 -0.101132 0.015756 -0.028948 -0.09098199999999997 0.013855 -0.038605 -0.101132 0.013855 -0.026779 -0.09573199999999997 -0.022075 -0.07126 0.01062500000000003 -0.024227 -0.07126 0.003647000000000028 0.02341 -0.07126 0.007217000000000028 0.020242 -0.05826 0.01379700000000003 0.02341 -0.07126 0.007217000000000028 0.02341 -0.05826 0.007217000000000028 -0.024227 -0.05826 0.003647000000000028 -0.022075 -0.05826 0.01062500000000003 0.02341 -0.05826 0.007217000000000028 -0.024227 -0.07126 0.003647000000000028 -0.022075 -0.07126 0.01062500000000003 -0.024227 -0.05826 0.003647000000000028 0.013855 -0.038605 -0.101132 -0.013857 -0.038605 -0.101132 0.010284 -0.036837 -0.105004 -0.013857 -0.026779 -0.09573199999999997 -0.010286 -0.025011 -0.09960399999999997 -0.013857 -0.038605 -0.101132 0.013855 -0.026779 -0.09573199999999997 0.010284 -0.036837 -0.105004 0.010284 -0.025011 -0.09960399999999997 0.013855 -0.038605 -0.101132 0.010284 -0.036837 -0.105004 0.013855 -0.026779 -0.09573199999999997 0.020242 -0.07126 0.01379700000000003 -0.022075 -0.07126 0.01062500000000003 0.02341 -0.07126 0.007217000000000028 0.020242 -0.07126 0.01379700000000003 0.02341 -0.07126 0.007217000000000028 0.020242 -0.05826 0.01379700000000003 0.02341 -0.05826 0.007217000000000028 -0.022075 -0.05826 0.01062500000000003 0.020242 -0.05826 0.01379700000000003 -0.024227 -0.05826 0.003647000000000028 -0.022075 -0.07126 0.01062500000000003 -0.022075 -0.05826 0.01062500000000003 -0.013857 -0.038605 -0.101132 -0.010286 -0.036837 -0.105004 0.010284 -0.036837 -0.105004 -0.010286 -0.036837 -0.105004 -0.013857 -0.038605 -0.101132 -0.010286 -0.025011 -0.09960399999999997 0.005471 -0.035683 -0.107531 0.010284 -0.025011 -0.09960399999999997 0.010284 -0.036837 -0.105004 -0.017961 -0.07126 0.01665900000000003 -0.022075 -0.07126 0.01062500000000003 0.020242 -0.07126 0.01379700000000003 0.015274 -0.05826 0.01915000000000003 0.020242 -0.07126 0.01379700000000003 0.020242 -0.05826 0.01379700000000003 -0.022075 -0.05826 0.01062500000000003 -0.017961 -0.05826 0.01665900000000003 0.020242 -0.05826 0.01379700000000003 -0.017961 -0.07126 0.01665900000000003 -0.022075 -0.05826 0.01062500000000003 -0.022075 -0.07126 0.01062500000000003 -0.010286 -0.036837 -0.105004 0.005471 -0.035683 -0.107531 0.010284 -0.036837 -0.105004 -0.010286 -0.025011 -0.09960399999999997 -0.005473 -0.023857 -0.102132 -0.010286 -0.036837 -0.105004 0.005471 -0.023857 -0.102132 0.010284 -0.025011 -0.09960399999999997 0.005471 -0.035683 -0.107531 0.015274 -0.07126 0.01915000000000003 -0.017961 -0.07126 0.01665900000000003 0.020242 -0.07126 0.01379700000000003 0.015274 -0.07126 0.01915000000000003 0.020242 -0.07126 0.01379700000000003 0.015274 -0.05826 0.01915000000000003 0.020242 -0.05826 0.01379700000000003 -0.017961 -0.05826 0.01665900000000003 0.015274 -0.05826 0.01915000000000003 -0.022075 -0.05826 0.01062500000000003 -0.017961 -0.07126 0.01665900000000003 -0.017961 -0.05826 0.01665900000000003 0.005471 -0.035683 -0.107531 -0.010286 -0.036837 -0.105004 -0.005473 -0.035683 -0.107531 -0.010286 -0.036837 -0.105004 -0.005473 -0.023857 -0.102132 -0.005473 -0.035683 -0.107531 -0.005473 -0.023857 -0.102132 -1.00209e-06 -0.023456 -0.10301 -0.005473 -0.035683 -0.107531 -1.00209e-06 -0.023456 -0.10301 0.005471 -0.023857 -0.102132 -1.00229e-06 -0.035282 -0.108409 0.005471 -0.023857 -0.102132 0.005471 -0.035683 -0.107531 -1.00229e-06 -0.035282 -0.108409 -0.012251 -0.07126 0.02121300000000003 -0.017961 -0.07126 0.01665900000000003 0.015274 -0.07126 0.01915000000000003 0.015274 -0.05826 0.01915000000000003 0.00895 -0.05826 0.02280200000000003 0.015274 -0.07126 0.01915000000000003 -0.017961 -0.05826 0.01665900000000003 -0.012251 -0.05826 0.02121300000000003 0.015274 -0.05826 0.01915000000000003 -0.012251 -0.07126 0.02121300000000003 -0.017961 -0.05826 0.01665900000000003 -0.017961 -0.07126 0.01665900000000003 -1.00229e-06 -0.035282 -0.108409 0.005471 -0.035683 -0.107531 -0.005473 -0.035683 -0.107531 -1.00209e-06 -0.023456 -0.10301 -1.00229e-06 -0.035282 -0.108409 -0.005473 -0.035683 -0.107531 0.015274 -0.07126 0.01915000000000003 0.00895 -0.07126 0.02280200000000003 -0.012251 -0.07126 0.02121300000000003 0.015274 -0.07126 0.01915000000000003 0.00895 -0.05826 0.02280200000000003 0.00895 -0.07126 0.02280200000000003 0.00895 -0.05826 0.02280200000000003 0.015274 -0.05826 0.01915000000000003 -0.012251 -0.05826 0.02121300000000003 -0.017961 -0.05826 0.01665900000000003 -0.012251 -0.07126 0.02121300000000003 -0.012251 -0.05826 0.02121300000000003 0.00895 -0.07126 0.02280200000000003 -0.005453 -0.07126 0.02388100000000003 -0.012251 -0.07126 0.02121300000000003 0.00895 -0.05826 0.02280200000000003 0.00183 -0.05826 0.02442700000000003 0.00895 -0.07126 0.02280200000000003 0.00895 -0.05826 0.02280200000000003 -0.012251 -0.05826 0.02121300000000003 -0.005453 -0.05826 0.02388100000000003 -0.005453 -0.07126 0.02388100000000003 -0.012251 -0.05826 0.02121300000000003 -0.012251 -0.07126 0.02121300000000003 0.00895 -0.07126 0.02280200000000003 0.00183 -0.07126 0.02442700000000003 -0.005453 -0.07126 0.02388100000000003 0.00895 -0.07126 0.02280200000000003 0.00183 -0.05826 0.02442700000000003 0.00183 -0.07126 0.02442700000000003 0.00183 -0.05826 0.02442700000000003 0.00895 -0.05826 0.02280200000000003 -0.005453 -0.05826 0.02388100000000003 -0.005453 -0.05826 0.02388100000000003 -0.012251 -0.05826 0.02121300000000003 -0.005453 -0.07126 0.02388100000000003 0.00183 -0.07126 0.02442700000000003 -0.005453 -0.05826 0.02388100000000003 -0.005453 -0.07126 0.02388100000000003 0.00183 -0.05826 0.02442700000000003 -0.005453 -0.05826 0.02388100000000003 0.00183 -0.07126 0.02442700000000003 -0.015758 -0.028948 -0.09098199999999997 -0.016001 -0.030102 -0.08845499999999998 0.015999 -0.030102 -0.08845499999999998 0.015756 -0.028948 -0.09098199999999997 -0.015758 -0.028948 -0.09098199999999997 0.015999 -0.030102 -0.08845499999999998 0.013855 -0.026779 -0.09573199999999997 -0.015758 -0.028948 -0.09098199999999997 0.015756 -0.028948 -0.09098199999999997 -0.013857 -0.026779 -0.09573199999999997 -0.015758 -0.028948 -0.09098199999999997 0.010284 -0.025011 -0.09960399999999997 0.010284 -0.025011 -0.09960399999999997 -0.015758 -0.028948 -0.09098199999999997 0.013855 -0.026779 -0.09573199999999997 -0.010286 -0.025011 -0.09960399999999997 -0.013857 -0.026779 -0.09573199999999997 0.010284 -0.025011 -0.09960399999999997 -1.00209e-06 -0.023456 -0.10301 -0.010286 -0.025011 -0.09960399999999997 0.010284 -0.025011 -0.09960399999999997 -0.010286 -0.025011 -0.09960399999999997 -1.00209e-06 -0.023456 -0.10301 -0.005473 -0.023857 -0.102132 -1.00209e-06 -0.023456 -0.10301 0.010284 -0.025011 -0.09960399999999997 0.005471 -0.023857 -0.102132 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101

    -
    -
    - - - 0 0 2.775557561562891e-17 - 1 0 0 0 - - true - - - -
    - - - - -0.02519999999999999 0.00523391 -0.046608 -0.02519999999999999 0.00497363 -0.0469257 -0.02569999999999999 0.00539113 -0.0464161 -0.02519999999999999 0.00539113 -0.0464161 -0.02519999999999999 0.00523391 -0.046608 -0.02569999999999999 0.00539113 -0.0464161 -0.02619999999999999 0.00580863 -0.0459064 -0.02519999999999999 0.00539113 -0.0464161 -0.02569999999999999 0.00539113 -0.0464161 -0.02619999999999999 0.00497363 -0.0469257 -0.02619999999999999 0.00580863 -0.0459064 -0.02569999999999999 0.00539113 -0.0464161 -0.02519999999999999 0.00497363 -0.0469257 -0.02619999999999999 0.00497363 -0.0469257 -0.02569999999999999 0.00539113 -0.0464161 -0.02519999999999999 0.00497363 -0.0469257 -0.02519999999999999 0.00447758 -0.0473416 -0.02569999999999999 0.00447758 -0.0473416 -0.02619999999999999 0.00497363 -0.0469257 -0.02519999999999999 0.00497363 -0.0469257 -0.02569999999999999 0.00447758 -0.0473416 -0.02619999999999999 0.00398153 -0.0477574 -0.02619999999999999 0.00497363 -0.0469257 -0.02569999999999999 0.00447758 -0.0473416 -0.02519999999999999 0.00447758 -0.0473416 -0.02619999999999999 0.00398153 -0.0477574 -0.02569999999999999 0.00447758 -0.0473416 -0.02519999999999999 0.00447758 -0.0473416 -0.02519999999999999 0.00398153 -0.0477574 -0.02619999999999999 0.00398153 -0.0477574 -0.02519999999999999 0.00398153 -0.0477574 -0.02519999999999999 0.00340985 -0.0480781 -0.02569999999999999 0.00340985 -0.0480781 -0.02619999999999999 0.00398153 -0.0477574 -0.02519999999999999 0.00398153 -0.0477574 -0.02569999999999999 0.00340985 -0.0480781 -0.02619999999999999 0.00283817 -0.0483988 -0.02619999999999999 0.00398153 -0.0477574 -0.02569999999999999 0.00340985 -0.0480781 -0.02519999999999999 0.00340985 -0.0480781 -0.02619999999999999 0.00283817 -0.0483988 -0.02569999999999999 0.00340985 -0.0480781 -0.02519999999999999 0.00340985 -0.0480781 -0.02519999999999999 0.00283817 -0.0483988 -0.02619999999999999 0.00283817 -0.0483988 -0.02519999999999999 0.00283817 -0.0483988 -0.02519999999999999 0.00215518 -0.0486211 -0.02619999999999999 0.00283817 -0.0483988 -0.02519999999999999 0.00215518 -0.0486211 -0.02519999999999999 0.0014722 -0.0488434 -0.02569999999999999 0.00215518 -0.0486211 -0.02619999999999999 0.00283817 -0.0483988 -0.02519999999999999 0.00215518 -0.0486211 -0.02569999999999999 0.00215518 -0.0486211 -0.02619999999999999 0.0014722 -0.0488434 -0.02619999999999999 0.00283817 -0.0483988 -0.02569999999999999 0.00215518 -0.0486211 -0.02519999999999999 0.0014722 -0.0488434 -0.02619999999999999 0.0014722 -0.0488434 -0.02569999999999999 0.00215518 -0.0486211 -0.02519999999999999 0.0014722 -0.0488434 -0.02519999999999999 0.000736101 -0.0489217 -0.02619999999999999 0.0014722 -0.0488434 -0.02519999999999999 0.000736101 -0.0489217 -0.02519999999999999 7.503130000000001e-18 -0.049 -0.02569999999999999 0.000736101 -0.0489217 -0.02619999999999999 0.0014722 -0.0488434 -0.02519999999999999 0.000736101 -0.0489217 -0.02569999999999999 0.000736101 -0.0489217 -0.02619999999999999 7.503130000000001e-18 -0.049 -0.02619999999999999 0.0014722 -0.0488434 -0.02569999999999999 0.000736101 -0.0489217 -0.02519999999999999 7.503130000000001e-18 -0.049 -0.02619999999999999 7.503130000000001e-18 -0.049 -0.02569999999999999 0.000736101 -0.0489217 -0.02519999999999999 7.503130000000001e-18 -0.049 -0.02519999999999999 -0.000664345 -0.048928 -0.02619999999999999 7.503130000000001e-18 -0.049 -0.02519999999999999 -0.000664345 -0.048928 -0.02619999999999999 7.503130000000001e-18 -0.049 -0.02519999999999999 -0.000750082 -0.0489187 -0.02519999999999999 -0.00691868 -0.0412499 -0.02619999999999999 -0.007 -0.042 -0.02519999999999999 -0.007 -0.042 -0.02519999999999999 -0.00691868 -0.0412499 -0.02519999999999999 -0.00683736 -0.0404998 -0.02569999999999999 -0.00691868 -0.0412499 -0.02619999999999999 -0.007 -0.042 -0.02519999999999999 -0.00691868 -0.0412499 -0.02569999999999999 -0.00691868 -0.0412499 -0.02619999999999999 -0.00683736 -0.0404998 -0.02619999999999999 -0.007 -0.042 -0.02569999999999999 -0.00691868 -0.0412499 -0.02519999999999999 -0.00683736 -0.0404998 -0.02619999999999999 -0.00683736 -0.0404998 -0.02569999999999999 -0.00691868 -0.0412499 -0.02519999999999999 -0.00663791 -0.0398764 -0.02619999999999999 -0.00683736 -0.0404998 -0.02519999999999999 -0.00683736 -0.0404998 -0.02519999999999999 -0.00663791 -0.0398764 -0.02519999999999999 -0.00643847 -0.039253 -0.02569999999999999 -0.00663791 -0.0398764 -0.02619999999999999 -0.00683736 -0.0404998 -0.02519999999999999 -0.00663791 -0.0398764 -0.02569999999999999 -0.00663791 -0.0398764 -0.02619999999999999 -0.00643847 -0.039253 -0.02619999999999999 -0.00683736 -0.0404998 -0.02569999999999999 -0.00663791 -0.0398764 -0.02519999999999999 -0.00643847 -0.039253 -0.02619999999999999 -0.00643847 -0.039253 -0.02569999999999999 -0.00663791 -0.0398764 -0.02519999999999999 -0.00643847 -0.039253 -0.02519999999999999 -0.00612355 -0.0386733 -0.02569999999999999 -0.00612355 -0.0386733 -0.02619999999999999 -0.00643847 -0.039253 -0.02519999999999999 -0.00643847 -0.039253 -0.02569999999999999 -0.00612355 -0.0386733 -0.02619999999999999 -0.00580863 -0.0380936 -0.02619999999999999 -0.00643847 -0.039253 -0.02569999999999999 -0.00612355 -0.0386733 -0.02519999999999999 -0.00612355 -0.0386733 -0.02619999999999999 -0.00580863 -0.0380936 -0.02569999999999999 -0.00612355 -0.0386733 -0.02519999999999999 -0.00580863 -0.0380936 -0.02619999999999999 -0.00580863 -0.0380936 -0.02519999999999999 -0.00612355 -0.0386733 -0.02519999999999999 -0.00539113 -0.0375839 -0.02619999999999999 -0.00580863 -0.0380936 -0.02519999999999999 -0.00580863 -0.0380936 -0.02519999999999999 -0.00539113 -0.0375839 -0.02519999999999999 -0.00497363 -0.0370742 -0.02569999999999999 -0.00539113 -0.0375839 -0.02619999999999999 -0.00580863 -0.0380936 -0.02519999999999999 -0.00539113 -0.0375839 -0.02569999999999999 -0.00539113 -0.0375839 -0.02619999999999999 -0.00497363 -0.0370742 -0.02619999999999999 -0.00580863 -0.0380936 -0.02569999999999999 -0.00539113 -0.0375839 -0.02519999999999999 -0.00497363 -0.0370742 -0.02619999999999999 -0.00497363 -0.0370742 -0.02569999999999999 -0.00539113 -0.0375839 -0.02519999999999999 -0.00497363 -0.0370742 -0.02519999999999999 -0.00447758 -0.0366584 -0.02569999999999999 -0.00447758 -0.0366584 -0.02619999999999999 -0.00497363 -0.0370742 -0.02519999999999999 -0.00497363 -0.0370742 -0.02569999999999999 -0.00447758 -0.0366584 -0.02619999999999999 -0.00398153 -0.0362426 -0.02619999999999999 -0.00497363 -0.0370742 -0.02569999999999999 -0.00447758 -0.0366584 -0.02519999999999999 -0.00447758 -0.0366584 -0.02619999999999999 -0.00398153 -0.0362426 -0.02569999999999999 -0.00447758 -0.0366584 -0.02519999999999999 -0.00447758 -0.0366584 -0.02519999999999999 -0.00398153 -0.0362426 -0.02619999999999999 -0.00398153 -0.0362426 -0.02519999999999999 -0.00398153 -0.0362426 -0.02519999999999999 -0.00340985 -0.0359219 -0.02569999999999999 -0.00340985 -0.0359219 -0.02619999999999999 -0.00398153 -0.0362426 -0.02519999999999999 -0.00398153 -0.0362426 -0.02569999999999999 -0.00340985 -0.0359219 -0.02619999999999999 -0.00283817 -0.0356012 -0.02619999999999999 -0.00398153 -0.0362426 -0.02569999999999999 -0.00340985 -0.0359219 -0.02519999999999999 -0.00340985 -0.0359219 -0.02619999999999999 -0.00283817 -0.0356012 -0.02569999999999999 -0.00340985 -0.0359219 -0.02519999999999999 -0.00340985 -0.0359219 -0.02519999999999999 -0.00283817 -0.0356012 -0.02619999999999999 -0.00283817 -0.0356012 -0.02519999999999999 -0.00283817 -0.0356012 -0.02519999999999999 -0.00215518 -0.0353789 -0.02619999999999999 -0.00283817 -0.0356012 -0.02519999999999999 -0.00215518 -0.0353789 -0.02519999999999999 -0.0014722 -0.0351566 -0.02569999999999999 -0.00215518 -0.0353789 -0.02619999999999999 -0.00283817 -0.0356012 -0.02519999999999999 -0.00215518 -0.0353789 -0.02569999999999999 -0.00215518 -0.0353789 -0.02619999999999999 -0.0014722 -0.0351566 -0.02619999999999999 -0.00283817 -0.0356012 -0.02569999999999999 -0.00215518 -0.0353789 -0.02519999999999999 -0.0014722 -0.0351566 -0.02619999999999999 -0.0014722 -0.0351566 -0.02569999999999999 -0.00215518 -0.0353789 -0.02519999999999999 -0.0014722 -0.0351566 -0.02519999999999999 -0.000736102 -0.0350783 -0.02619999999999999 -0.0014722 -0.0351566 -0.02519999999999999 -0.000736102 -0.0350783 -0.02519999999999999 -4.28626e-19 -0.035 -0.02569999999999999 -0.000736101 -0.0350783 -0.02619999999999999 -0.0014722 -0.0351566 -0.02519999999999999 -0.000736102 -0.0350783 -0.02569999999999999 -0.000736101 -0.0350783 -0.02619999999999999 -4.28626e-19 -0.035 -0.02619999999999999 -0.0014722 -0.0351566 -0.02569999999999999 -0.000736101 -0.0350783 -0.02519999999999999 -4.28626e-19 -0.035 -0.02619999999999999 -4.28626e-19 -0.035 -0.02569999999999999 -0.000736101 -0.0350783 -0.02519999999999999 -4.28626e-19 -0.035 -0.02519999999999999 0.000750082 -0.0350813 -0.02619999999999999 -4.28626e-19 -0.035 -0.02519999999999999 0.000750082 -0.0350813 -0.02519999999999999 0.00150016 -0.0351626 -0.02569999999999999 0.000750082 -0.0350813 -0.02619999999999999 -4.28626e-19 -0.035 -0.02519999999999999 0.000750082 -0.0350813 -0.02569999999999999 0.000750082 -0.0350813 -0.02619999999999999 0.00150016 -0.0351626 -0.02619999999999999 -4.28626e-19 -0.035 -0.02569999999999999 0.000750082 -0.0350813 -0.02519999999999999 0.00150016 -0.0351626 -0.02619999999999999 0.00150016 -0.0351626 -0.02569999999999999 0.000750082 -0.0350813 -0.02519999999999999 0.00150016 -0.0351626 -0.02519999999999999 0.00212359 -0.0353621 -0.02569999999999999 0.00212359 -0.0353621 -0.02619999999999999 0.00150016 -0.0351626 -0.02519999999999999 0.00150016 -0.0351626 -0.02569999999999999 0.00212359 -0.0353621 -0.02619999999999999 0.00274702 -0.0355615 -0.02619999999999999 0.00150016 -0.0351626 -0.02569999999999999 0.00212359 -0.0353621 -0.02519999999999999 0.00212359 -0.0353621 -0.02619999999999999 0.00274702 -0.0355615 -0.02569999999999999 0.00212359 -0.0353621 -0.02519999999999999 0.00212359 -0.0353621 -0.02519999999999999 0.00274702 -0.0355615 -0.02619999999999999 0.00274702 -0.0355615 -0.02519999999999999 0.00274702 -0.0355615 -0.02519999999999999 0.0033267 -0.0358764 -0.02619999999999999 0.00274702 -0.0355615 -0.02519999999999999 0.0033267 -0.0358764 -0.02519999999999999 0.00390638 -0.0361914 -0.02569999999999999 0.0033267 -0.0358764 -0.02619999999999999 0.00274702 -0.0355615 -0.02519999999999999 0.0033267 -0.0358764 -0.02569999999999999 0.0033267 -0.0358764 -0.02619999999999999 0.00390638 -0.0361914 -0.02619999999999999 0.00274702 -0.0355615 -0.02569999999999999 0.0033267 -0.0358764 -0.02519999999999999 0.00390638 -0.0361914 -0.02619999999999999 0.00390638 -0.0361914 -0.02569999999999999 0.0033267 -0.0358764 -0.02519999999999999 0.00390638 -0.0361914 -0.02519999999999999 0.00441606 -0.0366089 -0.02619999999999999 0.00390638 -0.0361914 -0.02519999999999999 0.00441606 -0.0366089 -0.02519999999999999 0.00492575 -0.0370264 -0.02569999999999999 0.00441606 -0.0366089 -0.02619999999999999 0.00390638 -0.0361914 -0.02519999999999999 0.00441606 -0.0366089 -0.02569999999999999 0.00441606 -0.0366089 -0.02619999999999999 0.00492575 -0.0370264 -0.02619999999999999 0.00390638 -0.0361914 -0.02569999999999999 0.00441606 -0.0366089 -0.02519999999999999 0.00492575 -0.0370264 -0.02619999999999999 0.00492575 -0.0370264 -0.02569999999999999 0.00441606 -0.0366089 -0.02519999999999999 0.00492575 -0.0370264 -0.02519999999999999 0.00534156 -0.0375224 -0.02569999999999999 0.00534156 -0.0375224 -0.02619999999999999 0.00492575 -0.0370264 -0.02519999999999999 0.00492575 -0.0370264 -0.02569999999999999 0.00534156 -0.0375224 -0.02619999999999999 0.00575738 -0.0380185 -0.02619999999999999 0.00492575 -0.0370264 -0.02569999999999999 0.00534156 -0.0375224 -0.02519999999999999 0.00534156 -0.0375224 -0.02619999999999999 0.00575738 -0.0380185 -0.02569999999999999 0.00534156 -0.0375224 -0.02519999999999999 0.00575738 -0.0380185 -0.02619999999999999 0.00575738 -0.0380185 -0.02519999999999999 0.00534156 -0.0375224 -0.02519999999999999 0.00575738 -0.0380185 -0.02519999999999999 0.0060781 -0.0385901 -0.02569999999999999 0.0060781 -0.0385901 -0.02619999999999999 0.00575738 -0.0380185 -0.02519999999999999 0.00575738 -0.0380185 -0.02569999999999999 0.0060781 -0.0385901 -0.02619999999999999 0.00639881 -0.0391618 -0.02619999999999999 0.00575738 -0.0380185 -0.02569999999999999 0.0060781 -0.0385901 -0.02519999999999999 0.0060781 -0.0385901 -0.02619999999999999 0.00639881 -0.0391618 -0.02569999999999999 0.0060781 -0.0385901 -0.02519999999999999 0.00639881 -0.0391618 -0.02619999999999999 0.00639881 -0.0391618 -0.02519999999999999 0.0060781 -0.0385901 -0.02519999999999999 0.00662112 -0.0398448 -0.02619999999999999 0.00639881 -0.0391618 -0.02519999999999999 0.00639881 -0.0391618 -0.02519999999999999 0.00662112 -0.0398448 -0.02519999999999999 0.00684344 -0.0405278 -0.02569999999999999 0.00662112 -0.0398448 -0.02619999999999999 0.00639881 -0.0391618 -0.02519999999999999 0.00662112 -0.0398448 -0.02569999999999999 0.00662112 -0.0398448 -0.02619999999999999 0.00684344 -0.0405278 -0.02619999999999999 0.00639881 -0.0391618 -0.02569999999999999 0.00662112 -0.0398448 -0.02519999999999999 0.00684344 -0.0405278 -0.02619999999999999 0.00684344 -0.0405278 -0.02569999999999999 0.00662112 -0.0398448 -0.02519999999999999 0.00692172 -0.0412639 -0.02619999999999999 0.00684344 -0.0405278 -0.02519999999999999 0.00684344 -0.0405278 -0.02519999999999999 0.00692172 -0.0412639 -0.02519999999999999 0.007 -0.042 -0.02569999999999999 0.00692172 -0.0412639 -0.02619999999999999 0.00684344 -0.0405278 -0.02519999999999999 0.00692172 -0.0412639 -0.02569999999999999 0.00692172 -0.0412639 -0.02619999999999999 0.007 -0.042 -0.02619999999999999 0.00684344 -0.0405278 -0.02569999999999999 0.00692172 -0.0412639 -0.02519999999999999 0.007 -0.042 -0.02619999999999999 0.007 -0.042 -0.02569999999999999 0.00692172 -0.0412639 -0.02519999999999999 0.00691868 -0.0427501 -0.02619999999999999 0.007 -0.042 -0.02519999999999999 0.007 -0.042 -0.02519999999999999 0.00691868 -0.0427501 -0.02519999999999999 0.00683736 -0.0435002 -0.02569999999999999 0.00691868 -0.0427501 -0.02619999999999999 0.007 -0.042 -0.02519999999999999 0.00691868 -0.0427501 -0.02569999999999999 0.00691868 -0.0427501 -0.02619999999999999 0.00683736 -0.0435002 -0.02619999999999999 0.007 -0.042 -0.02569999999999999 0.00691868 -0.0427501 -0.02519999999999999 0.00683736 -0.0435002 -0.02619999999999999 0.00683736 -0.0435002 -0.02569999999999999 0.00691868 -0.0427501 -0.02519999999999999 0.00663791 -0.0441236 -0.02619999999999999 0.00683736 -0.0435002 -0.02519999999999999 0.00683736 -0.0435002 -0.02519999999999999 0.00663791 -0.0441236 -0.02519999999999999 0.00643847 -0.044747 -0.02569999999999999 0.00663791 -0.0441236 -0.02619999999999999 0.00683736 -0.0435002 -0.02519999999999999 0.00663791 -0.0441236 -0.02569999999999999 0.00663791 -0.0441236 -0.02619999999999999 0.00643847 -0.044747 -0.02619999999999999 0.00683736 -0.0435002 -0.02569999999999999 0.00663791 -0.0441236 -0.02519999999999999 0.00643847 -0.044747 -0.02619999999999999 0.00643847 -0.044747 -0.02569999999999999 0.00663791 -0.0441236 -0.02519999999999999 0.00643847 -0.044747 -0.02519999999999999 0.00612355 -0.0453267 -0.02569999999999999 0.00612355 -0.0453267 -0.02619999999999999 0.00643847 -0.044747 -0.02519999999999999 0.00643847 -0.044747 -0.02569999999999999 0.00612355 -0.0453267 -0.02619999999999999 0.00580863 -0.0459064 -0.02619999999999999 0.00643847 -0.044747 -0.02569999999999999 0.00612355 -0.0453267 -0.02519999999999999 0.00612355 -0.0453267 -0.02619999999999999 0.00580863 -0.0459064 -0.02569999999999999 0.00612355 -0.0453267 -0.02519999999999999 0.00580863 -0.0459064 -0.02619999999999999 0.00580863 -0.0459064 -0.02519999999999999 0.00612355 -0.0453267 -0.02519999999999999 0.00539113 -0.0464161 -0.02619999999999999 0.00580863 -0.0459064 -0.02519999999999999 0.00580863 -0.0459064 -0.02519999999999999 -0.000750082 -0.0489187 -0.02519999999999999 -0.00150016 -0.0488374 -0.02569999999999999 -0.000750082 -0.0489187 -0.02619999999999999 7.503130000000001e-18 -0.049 -0.02519999999999999 -0.000750082 -0.0489187 -0.02569999999999999 -0.000750082 -0.0489187 -0.02619999999999999 -0.00150016 -0.0488374 -0.02619999999999999 7.503130000000001e-18 -0.049 -0.02569999999999999 -0.000750082 -0.0489187 -0.02519999999999999 -0.00150016 -0.0488374 -0.02619999999999999 -0.00150016 -0.0488374 -0.02569999999999999 -0.000750082 -0.0489187 -0.02519999999999999 -0.00150016 -0.0488374 -0.02519999999999999 -0.00212359 -0.0486379 -0.02569999999999999 -0.00212359 -0.0486379 -0.02619999999999999 -0.00150016 -0.0488374 -0.02519999999999999 -0.00150016 -0.0488374 -0.02569999999999999 -0.00212359 -0.0486379 -0.02619999999999999 -0.00274702 -0.0484385 -0.02619999999999999 -0.00150016 -0.0488374 -0.02569999999999999 -0.00212359 -0.0486379 -0.02519999999999999 -0.00212359 -0.0486379 -0.02619999999999999 -0.00274702 -0.0484385 -0.02569999999999999 -0.00212359 -0.0486379 -0.02519999999999999 -0.00212359 -0.0486379 -0.02519999999999999 -0.00274702 -0.0484385 -0.02619999999999999 -0.00274702 -0.0484385 -0.02519999999999999 -0.00274702 -0.0484385 -0.02519999999999999 -0.0033267 -0.0481235 -0.02619999999999999 -0.00274702 -0.0484385 -0.02519999999999999 -0.0033267 -0.0481235 -0.02519999999999999 -0.00390638 -0.0478086 -0.02569999999999999 -0.0033267 -0.0481235 -0.02619999999999999 -0.00274702 -0.0484385 -0.02519999999999999 -0.0033267 -0.0481235 -0.02569999999999999 -0.0033267 -0.0481235 -0.02619999999999999 -0.00390638 -0.0478086 -0.02619999999999999 -0.00274702 -0.0484385 -0.02569999999999999 -0.0033267 -0.0481235 -0.02519999999999999 -0.00390638 -0.0478086 -0.02619999999999999 -0.00390638 -0.0478086 -0.02569999999999999 -0.0033267 -0.0481235 -0.02519999999999999 -0.00390638 -0.0478086 -0.02519999999999999 -0.00441606 -0.0473911 -0.02619999999999999 -0.00390638 -0.0478086 -0.02519999999999999 -0.00441606 -0.0473911 -0.02519999999999999 -0.00492575 -0.0469736 -0.02569999999999999 -0.00441606 -0.0473911 -0.02619999999999999 -0.00390638 -0.0478086 -0.02519999999999999 -0.00441606 -0.0473911 -0.02569999999999999 -0.00441606 -0.0473911 -0.02619999999999999 -0.00492575 -0.0469736 -0.02619999999999999 -0.00390638 -0.0478086 -0.02569999999999999 -0.00441606 -0.0473911 -0.02519999999999999 -0.00492575 -0.0469736 -0.02619999999999999 -0.00492575 -0.0469736 -0.02569999999999999 -0.00441606 -0.0473911 -0.02519999999999999 -0.00492575 -0.0469736 -0.02519999999999999 -0.00534156 -0.0464776 -0.02569999999999999 -0.00534156 -0.0464776 -0.02619999999999999 -0.00492575 -0.0469736 -0.02519999999999999 -0.00492575 -0.0469736 -0.02569999999999999 -0.00534156 -0.0464776 -0.02619999999999999 -0.00575738 -0.0459815 -0.02619999999999999 -0.00492575 -0.0469736 -0.02569999999999999 -0.00534156 -0.0464776 -0.02519999999999999 -0.00534156 -0.0464776 -0.02619999999999999 -0.00575738 -0.0459815 -0.02569999999999999 -0.00534156 -0.0464776 -0.02519999999999999 -0.00575738 -0.0459815 -0.02619999999999999 -0.00575738 -0.0459815 -0.02519999999999999 -0.00534156 -0.0464776 -0.02519999999999999 -0.0060781 -0.0454099 -0.02619999999999999 -0.00575738 -0.0459815 -0.02519999999999999 -0.00575738 -0.0459815 -0.02519999999999999 -0.0060781 -0.0454099 -0.02519999999999999 -0.00639881 -0.0448382 -0.02569999999999999 -0.0060781 -0.0454099 -0.02619999999999999 -0.00575738 -0.0459815 -0.02519999999999999 -0.0060781 -0.0454099 -0.02569999999999999 -0.0060781 -0.0454099 -0.02619999999999999 -0.00639881 -0.0448382 -0.02619999999999999 -0.00575738 -0.0459815 -0.02569999999999999 -0.0060781 -0.0454099 -0.02519999999999999 -0.00639881 -0.0448382 -0.02619999999999999 -0.00639881 -0.0448382 -0.02569999999999999 -0.0060781 -0.0454099 -0.02519999999999999 -0.00662112 -0.0441552 -0.02619999999999999 -0.00639881 -0.0448382 -0.02519999999999999 -0.00639881 -0.0448382 -0.02519999999999999 -0.00662112 -0.0441552 -0.02519999999999999 -0.00684344 -0.0434722 -0.02569999999999999 -0.00662112 -0.0441552 -0.02619999999999999 -0.00639881 -0.0448382 -0.02519999999999999 -0.00662112 -0.0441552 -0.02569999999999999 -0.00662112 -0.0441552 -0.02619999999999999 -0.00684344 -0.0434722 -0.02619999999999999 -0.00639881 -0.0448382 -0.02569999999999999 -0.00662112 -0.0441552 -0.02519999999999999 -0.00684344 -0.0434722 -0.02619999999999999 -0.00684344 -0.0434722 -0.02569999999999999 -0.00662112 -0.0441552 -0.02519999999999999 -0.00692172 -0.0427361 -0.02619999999999999 -0.00684344 -0.0434722 -0.02519999999999999 -0.00684344 -0.0434722 -0.02519999999999999 -0.00692172 -0.0427361 -0.02519999999999999 -0.007 -0.042 -0.02569999999999999 -0.00692172 -0.0427361 -0.02619999999999999 -0.00684344 -0.0434722 -0.02519999999999999 -0.00692172 -0.0427361 -0.02569999999999999 -0.00692172 -0.0427361 -0.02619999999999999 -0.007 -0.042 -0.02619999999999999 -0.00684344 -0.0434722 -0.02569999999999999 -0.00692172 -0.0427361 -0.02519999999999999 -0.007 -0.042 -0.02619999999999999 -0.007 -0.042 -0.02569999999999999 -0.00692172 -0.0427361 -0.02619999999999999 0.00497363 -0.0469257 -0.02619999999999999 0.0035 -0.0455 -0.02619999999999999 0.00580863 -0.0459064 -0.02619999999999999 0.00398153 -0.0477574 -0.02619999999999999 0.0035 -0.0455 -0.02619999999999999 0.00497363 -0.0469257 -0.02619999999999999 0.00398153 -0.0477574 -0.02619999999999999 0.00283817 -0.0483988 -0.02619999999999999 0.0035 -0.0455 -0.02619999999999999 0.00283817 -0.0483988 -0.02619999999999999 0.0014722 -0.0488434 -0.02619999999999999 1.0842e-19 -0.0455 -0.02619999999999999 0.0014722 -0.0488434 -0.02619999999999999 7.503130000000001e-18 -0.049 -0.02619999999999999 1.0842e-19 -0.0455 -0.02619999999999999 -0.007 -0.042 -0.02619999999999999 -0.00683736 -0.0404998 -0.02619999999999999 -0.0035 -0.042 -0.02619999999999999 -0.0035 -0.042 -0.02619999999999999 -0.00683736 -0.0404998 -0.02619999999999999 -0.00643847 -0.039253 -0.02619999999999999 -0.00643847 -0.039253 -0.02619999999999999 -0.00580863 -0.0380936 -0.02619999999999999 -0.0035 -0.0385 -0.02619999999999999 -0.00580863 -0.0380936 -0.02619999999999999 -0.00497363 -0.0370742 -0.02619999999999999 -0.0035 -0.0385 -0.02619999999999999 -0.0035 -0.0385 -0.02619999999999999 -0.00497363 -0.0370742 -0.02619999999999999 -0.00398153 -0.0362426 -0.02619999999999999 -0.0035 -0.0385 -0.02619999999999999 -0.00398153 -0.0362426 -0.02619999999999999 -0.00283817 -0.0356012 -0.02619999999999999 0 -0.0385 -0.02619999999999999 -0.00283817 -0.0356012 -0.02619999999999999 -0.0014722 -0.0351566 -0.02619999999999999 0 -0.0385 -0.02619999999999999 -0.0014722 -0.0351566 -0.02619999999999999 -4.28626e-19 -0.035 -0.02619999999999999 0 -0.0385 -0.02619999999999999 -4.28626e-19 -0.035 -0.02619999999999999 0.00150016 -0.0351626 -0.02619999999999999 0 -0.0385 -0.02619999999999999 0.00150016 -0.0351626 -0.02619999999999999 0.00274702 -0.0355615 -0.02619999999999999 0.0035 -0.0385 -0.02619999999999999 0.00274702 -0.0355615 -0.02619999999999999 0.00390638 -0.0361914 -0.02619999999999999 0.0035 -0.0385 -0.02619999999999999 0.00390638 -0.0361914 -0.02619999999999999 0.00492575 -0.0370264 -0.02619999999999999 0.00575738 -0.0380185 -0.02619999999999999 0.0035 -0.0385 -0.02619999999999999 0.00492575 -0.0370264 -0.02619999999999999 0.00639881 -0.0391618 -0.02619999999999999 0.0035 -0.0385 -0.02619999999999999 0.00575738 -0.0380185 -0.02619999999999999 0.00639881 -0.0391618 -0.02619999999999999 0.00684344 -0.0405278 -0.02619999999999999 0.0035 -0.042 -0.02619999999999999 0.007 -0.042 -0.02619999999999999 0.0035 -0.042 -0.02619999999999999 0.00684344 -0.0405278 -0.02619999999999999 0.00683736 -0.0435002 -0.02619999999999999 0.0035 -0.042 -0.02619999999999999 0.007 -0.042 -0.02619999999999999 0.00683736 -0.0435002 -0.02619999999999999 0.00643847 -0.044747 -0.02619999999999999 0.0035 -0.042 -0.02619999999999999 0.00580863 -0.0459064 -0.02619999999999999 0.0035 -0.0455 -0.02619999999999999 0.00643847 -0.044747 -0.02619999999999999 7.503130000000001e-18 -0.049 -0.02619999999999999 -0.00150016 -0.0488374 -0.02619999999999999 1.0842e-19 -0.0455 -0.02619999999999999 -0.00150016 -0.0488374 -0.02619999999999999 -0.00274702 -0.0484385 -0.02619999999999999 1.0842e-19 -0.0455 -0.02619999999999999 -0.00274702 -0.0484385 -0.02619999999999999 -0.00390638 -0.0478086 -0.02619999999999999 -0.0035 -0.0455 -0.02619999999999999 -0.00390638 -0.0478086 -0.02619999999999999 -0.00492575 -0.0469736 -0.02619999999999999 -0.0035 -0.0455 -0.02619999999999999 -0.00492575 -0.0469736 -0.02619999999999999 -0.00575738 -0.0459815 -0.02619999999999999 -0.0035 -0.0455 -0.02619999999999999 -0.00575738 -0.0459815 -0.02619999999999999 -0.00639881 -0.0448382 -0.02619999999999999 -0.0035 -0.0455 -0.02619999999999999 -0.0035 -0.042 -0.02619999999999999 -0.00639881 -0.0448382 -0.02619999999999999 -0.00684344 -0.0434722 -0.02619999999999999 -0.00684344 -0.0434722 -0.02619999999999999 -0.007 -0.042 -0.02619999999999999 -0.0035 -0.042 -0.02619999999999999 0.00283817 -0.0483988 -0.02619999999999999 1.0842e-19 -0.0455 -0.02619999999999999 0.0035 -0.0455 -0.02619999999999999 -0.0035 -0.042 -0.02619999999999999 -0.00643847 -0.039253 -0.02619999999999999 -0.0035 -0.0385 -0.02619999999999999 0 -0.0385 -0.02619999999999999 -0.0035 -0.0385 -0.02619999999999999 -0.00283817 -0.0356012 -0.02619999999999999 0.0035 -0.0385 -0.02619999999999999 0 -0.0385 -0.02619999999999999 0.00274702 -0.0355615 -0.02619999999999999 0.0035 -0.042 -0.02619999999999999 0.0035 -0.0385 -0.02619999999999999 0.00639881 -0.0391618 -0.02619999999999999 0.0035 -0.0455 -0.02619999999999999 0.0035 -0.042 -0.02619999999999999 0.00643847 -0.044747 -0.02619999999999999 -0.00274702 -0.0484385 -0.02619999999999999 -0.0035 -0.0455 -0.02619999999999999 1.0842e-19 -0.0455 -0.02619999999999999 -0.0035 -0.0455 -0.02619999999999999 -0.00639881 -0.0448382 -0.02619999999999999 -0.0035 -0.042 -0.02619999999999999 0.0035 -0.0455 -0.02619999999999999 1.0842e-19 -0.0455 -0.02619999999999999 0.0035 -0.042 -0.02619999999999999 -0.0035 -0.042 -0.02619999999999999 -0.0035 -0.0385 -0.02619999999999999 0 -0.0385 -0.02619999999999999 0 -0.042 -0.02619999999999999 0 -0.0385 -0.02619999999999999 0.0035 -0.0385 -0.02619999999999999 0.0035 -0.042 -0.02619999999999999 0 -0.042 -0.02619999999999999 0.0035 -0.0385 -0.02619999999999999 1.0842e-19 -0.0455 -0.02619999999999999 -0.0035 -0.0455 -0.02619999999999999 0 -0.042 -0.02619999999999999 -0.0035 -0.0455 -0.02619999999999999 -0.0035 -0.042 -0.02619999999999999 0 -0.042 -0.02619999999999999 1.0842e-19 -0.0455 -0.02619999999999999 0 -0.042 -0.02619999999999999 0.0035 -0.042 -0.02619999999999999 0 -0.042 -0.02619999999999999 -0.0035 -0.042 -0.02619999999999999 0 -0.0385 -0.01629999999999999 0.02 -0.0526 -0.02519999999999999 0.02 -0.0526 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.000664345 -0.048928 -0.02519999999999999 7.503130000000001e-18 -0.049 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 7.503130000000001e-18 -0.049 -0.02519999999999999 0.000736101 -0.0489217 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 0.000736101 -0.0489217 -0.02519999999999999 0.0014722 -0.0488434 -0.02519999999999999 0.00497363 -0.0469257 -0.02519999999999999 0.00523391 -0.046608 -0.02519999999999999 0.02 -0.0526 -0.02519999999999999 0.00447758 -0.0473416 -0.02519999999999999 0.00497363 -0.0469257 -0.02519999999999999 0.02 -0.0526 -0.02519999999999999 0.00398153 -0.0477574 -0.02519999999999999 0.00447758 -0.0473416 -0.02519999999999999 0.02 -0.0526 -0.02519999999999999 0.00340985 -0.0480781 -0.02519999999999999 0.00398153 -0.0477574 -0.02519999999999999 0.02 -0.0526 -0.02519999999999999 0.00283817 -0.0483988 -0.02519999999999999 0.00340985 -0.0480781 -0.02519999999999999 0.02 -0.0526 -0.02519999999999999 0.00215518 -0.0486211 -0.02519999999999999 0.00283817 -0.0483988 -0.02519999999999999 0.02 -0.0526 -0.02519999999999999 0.0014722 -0.0488434 -0.02519999999999999 0.00215518 -0.0486211 -0.02519999999999999 0.02 -0.0526 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 0.0014722 -0.0488434 -0.02519999999999999 0.02 -0.0526 -0.02519999999999999 0.02 -0.0526 -0.02519999999999999 0.00523391 -0.046608 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.02 -0.0526 -0.01629999999999999 0.02 -0.0526 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 0.02 -0.0408 -0.007399999999999993 0.02 -0.0408 -0.01629999999999999 0.02 -0.0467 -0.01629999999999999 0.02 -0.0526 -0.02519999999999999 0.02 -0.0408 -0.01629999999999999 0.02 -0.0467 -0.007399999999999993 0.02 -0.0408 -0.01629999999999999 0.02 -0.0526 -0.01629999999999999 0.02 -0.0467 -0.02519999999999999 -0.00492575 -0.0469736 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.00534156 -0.0464776 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.00492575 -0.0469736 -0.02519999999999999 -0.00441606 -0.0473911 -0.02519999999999999 -0.00534156 -0.0464776 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.00575738 -0.0459815 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.00441606 -0.0473911 -0.02519999999999999 -0.00390638 -0.0478086 -0.02519999999999999 -0.00575738 -0.0459815 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.0060781 -0.0454099 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.00390638 -0.0478086 -0.02519999999999999 -0.0033267 -0.0481235 -0.02519999999999999 -0.0060781 -0.0454099 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.00639881 -0.0448382 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.0033267 -0.0481235 -0.02519999999999999 -0.00274702 -0.0484385 -0.02519999999999999 -0.00639881 -0.0448382 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.00662112 -0.0441552 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.00274702 -0.0484385 -0.02519999999999999 -0.00212359 -0.0486379 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.00212359 -0.0486379 -0.02519999999999999 -0.00150016 -0.0488374 -0.02519999999999999 -0.00662112 -0.0441552 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.00684344 -0.0434722 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.00150016 -0.0488374 -0.02519999999999999 -0.000750082 -0.0489187 -0.02519999999999999 -0.00684344 -0.0434722 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.00692172 -0.0427361 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.000750082 -0.0489187 -0.02519999999999999 -0.000664345 -0.048928 -0.02519999999999999 -0.00692172 -0.0427361 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.007 -0.042 -0.02519999999999999 -0.00691868 -0.0412499 -0.02519999999999999 -0.007 -0.042 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.00683736 -0.0404998 -0.02519999999999999 -0.00691868 -0.0412499 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.00663791 -0.0398764 -0.02519999999999999 -0.00683736 -0.0404998 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.00643847 -0.039253 -0.02519999999999999 -0.00663791 -0.0398764 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.00612355 -0.0386733 -0.02519999999999999 -0.00643847 -0.039253 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.00580863 -0.0380936 -0.02519999999999999 -0.00612355 -0.0386733 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.00539113 -0.0375839 -0.02519999999999999 -0.00580863 -0.0380936 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.00497363 -0.0370742 -0.02519999999999999 -0.00539113 -0.0375839 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.00447758 -0.0366584 -0.02519999999999999 -0.00497363 -0.0370742 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.00398153 -0.0362426 -0.02519999999999999 -0.00447758 -0.0366584 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.00340985 -0.0359219 -0.02519999999999999 -0.00398153 -0.0362426 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.007 -0.042 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.00340985 -0.0359219 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.00283817 -0.0356012 -0.02519999999999999 -0.00283817 -0.0356012 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.00215518 -0.0353789 -0.02519999999999999 -0.00215518 -0.0353789 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.0014722 -0.0351566 -0.02519999999999999 -0.0014722 -0.0351566 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.000736102 -0.0350783 -0.02519999999999999 -0.000736102 -0.0350783 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -4.28626e-19 -0.035 -0.02519999999999999 -4.28626e-19 -0.035 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 0.000750082 -0.0350813 -0.02519999999999999 0.000750082 -0.0350813 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 0.00150016 -0.0351626 -0.02519999999999999 0.00150016 -0.0351626 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 0.00212359 -0.0353621 -0.02519999999999999 0.00212359 -0.0353621 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 0.00274702 -0.0355615 -0.02519999999999999 0.0033267 -0.0358764 -0.02519999999999999 0.00274702 -0.0355615 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.00390638 -0.0361914 -0.02519999999999999 0.0033267 -0.0358764 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.00441606 -0.0366089 -0.02519999999999999 0.00390638 -0.0361914 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.00492575 -0.0370264 -0.02519999999999999 0.00441606 -0.0366089 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.00534156 -0.0375224 -0.02519999999999999 0.00492575 -0.0370264 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.00575738 -0.0380185 -0.02519999999999999 0.00534156 -0.0375224 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.0060781 -0.0385901 -0.02519999999999999 0.00575738 -0.0380185 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.00639881 -0.0391618 -0.02519999999999999 0.0060781 -0.0385901 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.00662112 -0.0398448 -0.02519999999999999 0.00639881 -0.0391618 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.00684344 -0.0405278 -0.02519999999999999 0.00662112 -0.0398448 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.00692172 -0.0412639 -0.02519999999999999 0.00684344 -0.0405278 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.007 -0.042 -0.02519999999999999 0.00692172 -0.0412639 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.00691868 -0.0427501 -0.02519999999999999 0.007 -0.042 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.00683736 -0.0435002 -0.02519999999999999 0.00691868 -0.0427501 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.00663791 -0.0441236 -0.02519999999999999 0.00683736 -0.0435002 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.00643847 -0.044747 -0.02519999999999999 0.00663791 -0.0441236 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.00612355 -0.0453267 -0.02519999999999999 0.00643847 -0.044747 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.00580863 -0.0459064 -0.02519999999999999 0.00612355 -0.0453267 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.00539113 -0.0464161 -0.02519999999999999 0.00580863 -0.0459064 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.00523391 -0.046608 -0.02519999999999999 0.00539113 -0.0464161 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.00274702 -0.0355615 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.01 -0.0526 -0.01629999999999999 0.02 -0.0526 -0.007399999999999993 -0.01 -0.0526 -0.007399999999999993 0.02 -0.0408 -0.02519999999999999 0.02 -0.0408 -0.01629999999999999 0.02 -0.0349 -0.01629999999999999 0.02 -0.029 -0.007399999999999993 0.02 -0.0408 -0.01629999999999999 0.02 -0.0349 -0.02519999999999999 0.02 -0.0408 -0.01629999999999999 0.02 -0.029 -0.01629999999999999 0.02 -0.0349 -0.007399999999999993 0.02 -0.0526 -0.01629999999999999 0.02 -0.0526 -0.007399999999999993 0.02 -0.0408 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 0.02 -0.029 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.04 -0.0408 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.01 -0.0526 -0.007399999999999993 -0.01 -0.0526 -0.01629999999999999 -0.04 -0.0526 -0.01629999999999999 0.02 -0.0526 -0.007399999999999993 0.02 -0.0526 -0.007399999999999993 -0.01 -0.0526 -0.007399999999999993 0.02 -0.0408 -0.01629999999999999 0.02 -0.029 -0.007399999999999993 0.02 -0.029 -0.02519999999999999 0.02 -0.0408 -0.02519999999999999 0.02 -0.029 -0.01629999999999999 0.02 -0.029 -0.007399999999999993 0.02 -0.0408 -0.007399999999999993 -0.01 -0.0526 -0.007399999999999993 0.02 -0.0526 -0.01629999999999999 0.02 -0.029 -0.02519999999999999 0.02 -0.029 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.04 -0.0408 -0.02519999999999999 -0.04 -0.029 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.04 -0.0526 -0.02519999999999999 -0.04 -0.0408 -0.02519999999999999 -0.01 -0.0526 -0.02519999999999999 -0.04 -0.0526 -0.02519999999999999 -0.01 -0.0526 -0.01629999999999999 -0.04 -0.0526 -0.01629999999999999 -0.04 -0.0526 -0.007399999999999993 -0.01 -0.0526 -0.007399999999999993 -0.04 -0.0526 -0.007399999999999993 0.02 -0.029 -0.007399999999999993 -0.01 -0.029 -0.007399999999999993 0.02 -0.0408 -0.007399999999999993 0.02 -0.029 -0.01629999999999999 0.02 -0.029 -0.007399999999999993 -0.01 -0.029 -0.007399999999999993 -0.01 -0.029 -0.007399999999999993 -0.01 -0.0526 -0.007399999999999993 0.02 -0.0408 -0.007399999999999993 -0.01 -0.029 -0.01629999999999999 0.02 -0.029 -0.02519999999999999 -0.01 -0.029 -0.01629999999999999 -0.04 -0.029 -0.02519999999999999 -0.01 -0.029 -0.02519999999999999 -0.04 -0.029 -0.01629999999999999 -0.04 -0.029 -0.02519999999999999 -0.04 -0.029 -0.02519999999999999 -0.04 -0.0408 -0.02519999999999999 -0.04 -0.0408 -0.02519999999999999 -0.04 -0.0526 -0.01629999999999999 -0.04 -0.0526 -0.007399999999999993 -0.04 -0.0408 -0.01629999999999999 -0.04 -0.0526 -0.007399999999999993 -0.04 -0.0526 -0.007399999999999993 -0.04 -0.0408 -0.007399999999999993 -0.04 -0.0526 -0.007399999999999993 -0.01 -0.0526 -0.007399999999999993 -0.01 -0.029 -0.007399999999999993 -0.04 -0.0408 -0.007399999999999993 -0.01 -0.0526 -0.007399999999999993 -0.01 -0.029 -0.02519999999999999 -0.01 -0.029 -0.01629999999999999 -0.04 -0.029 -0.02519999999999999 -0.04 -0.0408 -0.007399999999999993 -0.04 -0.0408 -0.01629999999999999 -0.04 -0.0349 -0.01629999999999999 -0.04 -0.029 -0.02519999999999999 -0.04 -0.0408 -0.01629999999999999 -0.04 -0.0349 -0.007399999999999993 -0.04 -0.0408 -0.01629999999999999 -0.04 -0.029 -0.01629999999999999 -0.04 -0.0349 -0.007399999999999993 -0.04 -0.0408 -0.02519999999999999 -0.04 -0.0408 -0.01629999999999999 -0.04 -0.0467 -0.01629999999999999 -0.04 -0.0526 -0.007399999999999993 -0.04 -0.0408 -0.01629999999999999 -0.04 -0.0467 -0.02519999999999999 -0.04 -0.0408 -0.01629999999999999 -0.04 -0.0526 -0.01629999999999999 -0.04 -0.0467 -0.007399999999999993 -0.04 -0.029 -0.007399999999999993 -0.04 -0.0408 -0.007399999999999993 -0.01 -0.029 -0.007399999999999993 -0.04 -0.029 -0.007399999999999993 -0.01 -0.029 -0.01629999999999999 -0.04 -0.029 -0.007399999999999993 -0.04 -0.029 -0.01629999999999999 -0.04 -0.029 -0.007399999999999993 -0.04 -0.0408 6.938893903907228e-18 -0.022 0.022 6.938893903907228e-18 -0.022 -0.022 6.938893903907228e-18 -0.0152426 1.04083e-17 6.938893903907228e-18 -0.008485299999999999 0.008485299999999999 6.938893903907228e-18 -0.022 0.022 6.938893903907228e-18 -0.0152426 1.04083e-17 6.938893903907228e-18 -0.012 0 6.938893903907228e-18 -0.008485299999999999 0.008485299999999999 6.938893903907228e-18 -0.0152426 1.04083e-17 6.938893903907228e-18 -0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 -0.012 0 6.938893903907228e-18 -0.0152426 1.04083e-17 6.938893903907228e-18 -0.022 -0.022 6.938893903907228e-18 -0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 -0.0152426 1.04083e-17 6.938893903907228e-18 -0.022 0.022 -0.005829549999999993 -0.022 0.0125 -0.002899999999999993 -0.022 0.0125 -0.002899999999999993 -0.022 -0.0125 -0.005829549999999993 -0.022 -0.0125 6.938893903907228e-18 -0.022 -0.022 6.938893903907228e-18 -0.022 0.022 -0.002899999999999993 -0.022 0.0125 6.938893903907228e-18 -0.022 -0.022 -0.002899999999999993 -0.022 0.0125 -0.002899999999999993 -0.022 -0.0125 6.938893903907228e-18 -0.022 -0.022 6.938893903907228e-18 0.022 0.022 6.938893903907228e-18 -0.022 0.022 6.938893903907228e-18 -1.04083e-17 0.0152426 6.938893903907228e-18 0.008485299999999999 0.008485299999999999 6.938893903907228e-18 0.022 0.022 6.938893903907228e-18 -1.04083e-17 0.0152426 6.938893903907228e-18 0 0.012 6.938893903907228e-18 0.008485299999999999 0.008485299999999999 6.938893903907228e-18 -1.04083e-17 0.0152426 6.938893903907228e-18 -0.008485299999999999 0.008485299999999999 6.938893903907228e-18 0 0.012 6.938893903907228e-18 -1.04083e-17 0.0152426 6.938893903907228e-18 -0.022 0.022 6.938893903907228e-18 -0.008485299999999999 0.008485299999999999 6.938893903907228e-18 -1.04083e-17 0.0152426 0.001500000000000007 -0.0102426 0.0042426 6.938893903907228e-18 -0.008485299999999999 0.008485299999999999 6.938893903907228e-18 -0.012 0 0.001500000000000007 -0.0102426 -0.0042426 6.938893903907228e-18 -0.012 0 6.938893903907228e-18 -0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 0.022 -0.022 6.938893903907228e-18 0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 1.21431e-17 -0.0152426 6.938893903907228e-18 -0.022 -0.022 6.938893903907228e-18 0.022 -0.022 6.938893903907228e-18 1.21431e-17 -0.0152426 6.938893903907228e-18 -0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 -0.022 -0.022 6.938893903907228e-18 1.21431e-17 -0.0152426 6.938893903907228e-18 0 -0.012 6.938893903907228e-18 -0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 1.21431e-17 -0.0152426 6.938893903907228e-18 0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 0 -0.012 6.938893903907228e-18 1.21431e-17 -0.0152426 6.938893903907228e-18 -0.022 0.022 -0.02699999999999999 -0.022 0.022 -0.01349999999999999 -0.022 0.01725 -0.005829549999999993 -0.022 0.0125 6.938893903907228e-18 -0.022 0.022 -0.01349999999999999 -0.022 0.01725 -0.02117049999999999 -0.022 0.0125 -0.005829549999999993 -0.022 0.0125 -0.01349999999999999 -0.022 0.01725 -0.02699999999999999 -0.022 0.022 -0.02117049999999999 -0.022 0.0125 -0.01349999999999999 -0.022 0.01725 -0.02699999999999999 -0.022 -0.022 6.938893903907228e-18 -0.022 -0.022 -0.01349999999999999 -0.022 -0.01725 -0.02117049999999999 -0.022 -0.0125 -0.02699999999999999 -0.022 -0.022 -0.01349999999999999 -0.022 -0.01725 -0.005829549999999993 -0.022 -0.0125 -0.02117049999999999 -0.022 -0.0125 -0.01349999999999999 -0.022 -0.01725 6.938893903907228e-18 -0.022 -0.022 -0.005829549999999993 -0.022 -0.0125 -0.01349999999999999 -0.022 -0.01725 -0.03869999999999999 -0.022 -0.0125 -0.02699999999999999 -0.022 -0.0125 -0.02784939999999999 -0.0309494 -0.0125 -0.005829549999999993 -0.022 -0.0125 -0.002899999999999993 -0.022 -0.0125 -0.02079999999999999 -0.0264747 -0.0125 -0.002899999999999993 -0.022 -0.0125 -0.02784939999999999 -0.0309494 -0.0125 -0.02079999999999999 -0.0264747 -0.0125 -0.02117049999999999 -0.022 -0.0125 -0.005829549999999993 -0.022 -0.0125 -0.02079999999999999 -0.0264747 -0.0125 -0.02699999999999999 -0.022 -0.0125 -0.02117049999999999 -0.022 -0.0125 -0.02079999999999999 -0.0264747 -0.0125 -0.02784939999999999 -0.0309494 -0.0125 -0.02699999999999999 -0.022 -0.0125 -0.02079999999999999 -0.0264747 -0.0125 -0.002899999999999993 -0.022 0.0125 -0.002899999999999993 -0.0324 0 -0.002899999999999993 -0.0272 0 -0.002899999999999993 -0.0324 0 -0.002899999999999993 -0.022 -0.0125 -0.002899999999999993 -0.0272 0 -0.002899999999999993 -0.022 -0.0125 -0.002899999999999993 -0.022 0.0125 -0.002899999999999993 -0.0272 0 -0.02777869999999999 -0.0308787 0.0125 -0.02699999999999999 -0.022 0.0125 -0.03869999999999999 -0.022 0.0125 -0.02777869999999999 -0.0308787 0.0125 -0.002899999999999993 -0.022 0.0125 -0.02079999999999999 -0.0264394 0.0125 -0.002899999999999993 -0.022 0.0125 -0.005829549999999993 -0.022 0.0125 -0.02079999999999999 -0.0264394 0.0125 -0.005829549999999993 -0.022 0.0125 -0.02117049999999999 -0.022 0.0125 -0.02079999999999999 -0.0264394 0.0125 -0.02117049999999999 -0.022 0.0125 -0.02699999999999999 -0.022 0.0125 -0.02079999999999999 -0.0264394 0.0125 -0.02699999999999999 -0.022 0.0125 -0.02777869999999999 -0.0308787 0.0125 -0.02079999999999999 -0.0264394 0.0125 6.938893903907228e-18 0.022 0.022 -0.01349999999999999 0 0.022 -0.006749999999999993 1.73472e-18 0.022 6.938893903907228e-18 -0.022 0.022 6.938893903907228e-18 0.022 0.022 -0.006749999999999993 1.73472e-18 0.022 -0.01349999999999999 0 0.022 6.938893903907228e-18 -0.022 0.022 -0.006749999999999993 1.73472e-18 0.022 6.938893903907228e-18 0.022 0.022 6.938893903907228e-18 0.008485299999999999 0.008485299999999999 6.938893903907228e-18 0.0152426 1.73472e-18 6.938893903907228e-18 0.022 -0.022 6.938893903907228e-18 0.022 0.022 6.938893903907228e-18 0.0152426 1.73472e-18 6.938893903907228e-18 0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 0.022 -0.022 6.938893903907228e-18 0.0152426 1.73472e-18 6.938893903907228e-18 0.012 0 6.938893903907228e-18 0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 0.0152426 1.73472e-18 6.938893903907228e-18 0.008485299999999999 0.008485299999999999 6.938893903907228e-18 0.012 0 6.938893903907228e-18 0.0152426 1.73472e-18 0.001500000000000007 0.0042426 0.0102426 6.938893903907228e-18 0.008485299999999999 0.008485299999999999 6.938893903907228e-18 0 0.012 0.001500000000000007 -0.0042426 0.0102426 6.938893903907228e-18 0 0.012 6.938893903907228e-18 -0.008485299999999999 0.008485299999999999 0.001500000000000007 -0.0102426 0.0042426 6.938893903907228e-18 -0.012 0 0.003000000000000007 -0.012 0 0.003000000000000007 -0.008485299999999999 0.008485299999999999 6.938893903907228e-18 -0.008485299999999999 0.008485299999999999 0.001500000000000007 -0.0102426 0.0042426 0.001500000000000007 -0.0102426 -0.0042426 6.938893903907228e-18 -0.008485299999999999 -0.008485299999999999 0.003000000000000007 -0.008485299999999999 -0.008485299999999999 0.003000000000000007 -0.012 0 6.938893903907228e-18 -0.012 0 0.001500000000000007 -0.0102426 -0.0042426 6.938893903907228e-18 -0.022 -0.022 -0.01349999999999999 0 -0.022 -0.006749999999999993 -1.73472e-18 -0.022 6.938893903907228e-18 0.022 -0.022 6.938893903907228e-18 -0.022 -0.022 -0.006749999999999993 -1.73472e-18 -0.022 -0.01349999999999999 0 -0.022 6.938893903907228e-18 0.022 -0.022 -0.006749999999999993 -1.73472e-18 -0.022 0.001500000000000007 -0.0042426 -0.0102426 6.938893903907228e-18 -0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 0 -0.012 0.001500000000000007 0.0042426 -0.0102426 6.938893903907228e-18 0 -0.012 6.938893903907228e-18 0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 -0.022 0.022 -0.01349999999999999 0 0.022 -0.01349999999999999 -0.011 0.022 -0.02699999999999999 -0.022 0.022 6.938893903907228e-18 -0.022 0.022 -0.01349999999999999 -0.011 0.022 -0.01349999999999999 0 0.022 -0.02699999999999999 -0.022 0.022 -0.01349999999999999 -0.011 0.022 -0.02699999999999999 -0.022 0.022 -0.02699999999999999 -0.022 0.0125 -0.02117049999999999 -0.022 0.0125 -0.02699999999999999 -0.022 -0.022 -0.01349999999999999 0 -0.022 -0.01349999999999999 -0.011 -0.022 6.938893903907228e-18 -0.022 -0.022 -0.02699999999999999 -0.022 -0.022 -0.01349999999999999 -0.011 -0.022 -0.01349999999999999 0 -0.022 6.938893903907228e-18 -0.022 -0.022 -0.01349999999999999 -0.011 -0.022 -0.02117049999999999 -0.022 -0.0125 -0.02699999999999999 -0.022 -0.0125 -0.02699999999999999 -0.022 -0.022 -0.02699999999999999 -0.033 -0.0125 -0.02784939999999999 -0.0309494 -0.0125 -0.002899999999999993 -0.022 -0.0125 -0.02784939999999999 -0.0309494 -0.0125 -0.02989999999999999 -0.0301 -0.0125 -0.03869999999999999 -0.022 -0.0125 -0.02699999999999999 -0.022 -0.0125 -0.03869999999999999 -0.022 -0.0125 -0.02699999999999999 -0.022 -0.00432961 -0.002899999999999993 -0.0428 0.0125 -0.002899999999999993 -0.0324 0 -0.002899999999999993 -0.0324 0.00625 -0.002899999999999993 -0.022 0.0125 -0.002899999999999993 -0.0428 0.0125 -0.002899999999999993 -0.0324 0.00625 -0.002899999999999993 -0.0324 0 -0.002899999999999993 -0.022 0.0125 -0.002899999999999993 -0.0324 0.00625 -0.002899999999999993 -0.022 -0.0125 -0.002899999999999993 -0.0324 0 -0.002899999999999993 -0.0324 -0.00625 -0.002899999999999993 -0.0324 0 -0.002899999999999993 -0.0428 -0.0125 -0.002899999999999993 -0.0324 -0.00625 -0.002899999999999993 -0.0428 -0.0125 -0.002899999999999993 -0.022 -0.0125 -0.002899999999999993 -0.0324 -0.00625 -0.002899999999999993 -0.022 0.0125 -0.02777869999999999 -0.0308787 0.0125 -0.02689999999999999 -0.033 0.0125 -0.02777869999999999 -0.0308787 0.0125 -0.03869999999999999 -0.022 0.0125 -0.02989999999999999 -0.03 0.0125 -0.02699999999999999 -0.022 0.00432961 -0.03869999999999999 -0.022 0.0125 -0.02699999999999999 -0.022 0.0125 -0.02699999999999999 0.022 0.022 -0.01349999999999999 0 0.022 -0.01349999999999999 0.011 0.022 6.938893903907228e-18 0.022 0.022 -0.02699999999999999 0.022 0.022 -0.01349999999999999 0.011 0.022 -0.01349999999999999 0 0.022 6.938893903907228e-18 0.022 0.022 -0.01349999999999999 0.011 0.022 6.938893903907228e-18 0.022 -0.022 -0.005829549999999993 0.022 -0.0125 -0.002899999999999993 0.022 -0.0125 -0.002899999999999993 0.022 0.0125 -0.005829549999999993 0.022 0.0125 6.938893903907228e-18 0.022 0.022 6.938893903907228e-18 0.022 -0.022 -0.002899999999999993 0.022 -0.0125 6.938893903907228e-18 0.022 0.022 -0.002899999999999993 0.022 -0.0125 -0.002899999999999993 0.022 0.0125 6.938893903907228e-18 0.022 0.022 0.001500000000000007 0.0102426 -0.0042426 6.938893903907228e-18 0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 0.012 0 0.001500000000000007 0.0102426 0.0042426 6.938893903907228e-18 0.012 0 6.938893903907228e-18 0.008485299999999999 0.008485299999999999 6.938893903907228e-18 0 0.012 0.003000000000000007 0 0.012 0.001500000000000007 0.0042426 0.0102426 0.001500000000000007 0.0042426 0.0102426 0.003000000000000007 0.008485299999999999 0.008485299999999999 6.938893903907228e-18 0.008485299999999999 0.008485299999999999 6.938893903907228e-18 -0.008485299999999999 0.008485299999999999 0.003000000000000007 -0.008485299999999999 0.008485299999999999 0.001500000000000007 -0.0042426 0.0102426 0.001500000000000007 -0.0042426 0.0102426 0.003000000000000007 0 0.012 6.938893903907228e-18 0 0.012 0.003000000000000007 -0.008485299999999999 0.008485299999999999 0.001500000000000007 -0.0102426 0.0042426 0.003000000000000007 -0.012 0 0.001500000000000007 -0.0102426 -0.0042426 0.003000000000000007 -0.008485299999999999 -0.008485299999999999 0.003000000000000007 -0.012 0 0.001500000000000007 -0.0042426 -0.0102426 0.003000000000000007 -0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 -0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 0.022 -0.022 -0.01349999999999999 0 -0.022 -0.01349999999999999 0.011 -0.022 -0.02699999999999999 0.022 -0.022 6.938893903907228e-18 0.022 -0.022 -0.01349999999999999 0.011 -0.022 -0.01349999999999999 0 -0.022 -0.02699999999999999 0.022 -0.022 -0.01349999999999999 0.011 -0.022 6.938893903907228e-18 0 -0.012 0.003000000000000007 0 -0.012 0.001500000000000007 -0.0042426 -0.0102426 6.938893903907228e-18 0.008485299999999999 -0.008485299999999999 0.003000000000000007 0.008485299999999999 -0.008485299999999999 0.001500000000000007 0.0042426 -0.0102426 0.001500000000000007 0.0042426 -0.0102426 0.003000000000000007 0 -0.012 6.938893903907228e-18 0 -0.012 -0.02699999999999999 -0.022 0.022 -0.01349999999999999 0 0.022 -0.02024999999999999 1.21431e-17 0.022 -0.02699999999999999 0.022 0.022 -0.02699999999999999 -0.022 0.022 -0.02024999999999999 1.21431e-17 0.022 -0.01349999999999999 0 0.022 -0.02699999999999999 0.022 0.022 -0.02024999999999999 1.21431e-17 0.022 -0.02699999999999999 -0.022 0.0125 -0.02699999999999999 -0.022 0.022 -0.02699999999999999 0 0 -0.02699999999999999 -0.022 -0.022 -0.02699999999999999 -0.022 -0.0125 -0.02699999999999999 0 0 -0.02699999999999999 -0.022 0.00432961 -0.02699999999999999 -0.022 0.0125 -0.02699999999999999 -0.011 1.73472e-18 -0.02699999999999999 -0.022 -0.0125 -0.02699999999999999 -0.022 -0.00432961 -0.02699999999999999 -0.011 1.73472e-18 -0.02699999999999999 -0.022 -0.00432961 -0.02699999999999999 -0.022 0.00432961 -0.02699999999999999 -0.011 1.73472e-18 -0.02699999999999999 -0.022 0.0125 -0.02699999999999999 0 0 -0.02699999999999999 -0.011 1.73472e-18 -0.02699999999999999 0 0 -0.02699999999999999 -0.022 -0.0125 -0.02699999999999999 -0.011 1.73472e-18 -0.02699999999999999 0.022 -0.022 -0.01349999999999999 0 -0.022 -0.02024999999999999 1.73472e-18 -0.022 -0.02699999999999999 -0.022 -0.022 -0.02699999999999999 0.022 -0.022 -0.02024999999999999 1.73472e-18 -0.022 -0.01349999999999999 0 -0.022 -0.02699999999999999 -0.022 -0.022 -0.02024999999999999 1.73472e-18 -0.022 -0.02742469999999999 -0.0319747 -0.01415 -0.02742469999999999 -0.0319747 -0.013325 -0.02699999999999999 -0.033 -0.0125 -0.02699999999999999 -0.033 -0.0125 -0.02742469999999999 -0.0319747 -0.013325 -0.02784939999999999 -0.0309494 -0.0125 -0.02784939999999999 -0.0309494 -0.0125 -0.02742469999999999 -0.0319747 -0.013325 -0.02742469999999999 -0.0319747 -0.01415 -0.002899999999999993 -0.022 -0.0125 -0.02784939999999999 -0.0350506 -0.0125 -0.02699999999999999 -0.033 -0.0125 -0.0319506 -0.0309494 -0.0125 -0.03869999999999999 -0.022 -0.0125 -0.02989999999999999 -0.0301 -0.0125 -0.02784939999999999 -0.0309494 -0.0125 -0.02887469999999999 -0.0305247 -0.01415 -0.02887469999999999 -0.0305247 -0.013325 -0.02989999999999999 -0.0301 -0.0125 -0.02784939999999999 -0.0309494 -0.0125 -0.02887469999999999 -0.0305247 -0.013325 -0.02887469999999999 -0.0305247 -0.01415 -0.02989999999999999 -0.0301 -0.0125 -0.02887469999999999 -0.0305247 -0.013325 -0.03869999999999999 -0.022 0.0125 -0.02699999999999999 -0.022 0.00432961 -0.03284999999999999 -0.022 2.1684e-17 -0.03869999999999999 -0.022 -0.0125 -0.03869999999999999 -0.022 0.0125 -0.03284999999999999 -0.022 2.1684e-17 -0.02699999999999999 -0.022 -0.00432961 -0.03869999999999999 -0.022 -0.0125 -0.03284999999999999 -0.022 2.1684e-17 -0.02699999999999999 -0.022 0.00432961 -0.02699999999999999 -0.022 -0.00432961 -0.03284999999999999 -0.022 2.1684e-17 -0.002899999999999993 -0.0428 -0.0125 -0.002899999999999993 -0.0324 0 -0.002899999999999993 -0.0376 -1.56125e-17 -0.002899999999999993 -0.0428 0.0125 -0.002899999999999993 -0.0428 -0.0125 -0.002899999999999993 -0.0376 -1.56125e-17 -0.002899999999999993 -0.0324 0 -0.002899999999999993 -0.0428 0.0125 -0.002899999999999993 -0.0376 -1.56125e-17 -0.002899999999999993 -0.0428 0.0125 -0.002899999999999993 -0.022 0.0125 -0.03869999999999999 -0.0428 0.0125 -0.03869999999999999 -0.0428 -0.0125 -0.002899999999999993 -0.022 -0.0125 -0.002899999999999993 -0.0428 -0.0125 -0.002899999999999993 -0.022 0.0125 -0.02689999999999999 -0.033 0.0125 -0.02777869999999999 -0.0351213 0.0125 -0.02733929999999999 -0.0319393 0.01415 -0.02733929999999999 -0.0319393 0.013325 -0.02777869999999999 -0.0308787 0.0125 -0.02777869999999999 -0.0308787 0.0125 -0.02733929999999999 -0.0319393 0.013325 -0.02689999999999999 -0.033 0.0125 -0.02689999999999999 -0.033 0.0125 -0.02733929999999999 -0.0319393 0.013325 -0.02733929999999999 -0.0319393 0.01415 -0.02883929999999999 -0.0304393 0.01415 -0.02883929999999999 -0.0304393 0.013325 -0.02989999999999999 -0.03 0.0125 -0.02989999999999999 -0.03 0.0125 -0.02883929999999999 -0.0304393 0.013325 -0.02777869999999999 -0.0308787 0.0125 -0.02777869999999999 -0.0308787 0.0125 -0.02883929999999999 -0.0304393 0.013325 -0.02883929999999999 -0.0304393 0.01415 -0.02989999999999999 -0.03 0.0125 -0.03869999999999999 -0.022 0.0125 -0.0320213 -0.0308787 0.0125 -0.02699999999999999 0.022 0.022 6.938893903907228e-18 0.022 0.022 -0.01349999999999999 0.022 0.01725 -0.02117049999999999 0.022 0.0125 -0.02699999999999999 0.022 0.022 -0.01349999999999999 0.022 0.01725 -0.005829549999999993 0.022 0.0125 -0.02117049999999999 0.022 0.0125 -0.01349999999999999 0.022 0.01725 6.938893903907228e-18 0.022 0.022 -0.005829549999999993 0.022 0.0125 -0.01349999999999999 0.022 0.01725 -0.002899999999999993 0.022 0.0125 -0.002899999999999993 0.0428 0.0125 -0.005829549999999993 0.022 0.0125 -0.005829549999999993 0.022 0.0125 -0.002899999999999993 0.0428 0.0125 -0.02117049999999999 0.022 0.0125 -0.02117049999999999 0.022 0.0125 -0.002899999999999993 0.0428 0.0125 -0.02699999999999999 0.022 0.0125 -0.02699999999999999 0.022 0.0125 -0.002899999999999993 0.0428 0.0125 -0.03869999999999999 0.022 0.0125 -0.002899999999999993 0.022 -0.0125 -0.002899999999999993 0.0324 0 -0.002899999999999993 0.0272 0 -0.002899999999999993 0.022 0.0125 -0.002899999999999993 0.022 -0.0125 -0.002899999999999993 0.0272 0 -0.002899999999999993 0.0324 0 -0.002899999999999993 0.022 0.0125 -0.002899999999999993 0.0272 0 -0.02699999999999999 0.022 -0.0125 -0.03869999999999999 0.022 -0.0125 -0.002899999999999993 0.0428 -0.0125 -0.02699999999999999 0.022 -0.0125 -0.002899999999999993 0.0428 -0.0125 -0.02117049999999999 0.022 -0.0125 -0.02117049999999999 0.022 -0.0125 -0.002899999999999993 0.0428 -0.0125 -0.005829549999999993 0.022 -0.0125 -0.005829549999999993 0.022 -0.0125 -0.002899999999999993 0.0428 -0.0125 -0.002899999999999993 0.022 -0.0125 -0.02699999999999999 0.022 -0.022 -0.02117049999999999 0.022 -0.0125 -0.01349999999999999 0.022 -0.01725 6.938893903907228e-18 0.022 -0.022 -0.02699999999999999 0.022 -0.022 -0.01349999999999999 0.022 -0.01725 -0.005829549999999993 0.022 -0.0125 6.938893903907228e-18 0.022 -0.022 -0.01349999999999999 0.022 -0.01725 -0.02117049999999999 0.022 -0.0125 -0.005829549999999993 0.022 -0.0125 -0.01349999999999999 0.022 -0.01725 0.001500000000000007 0.0102426 -0.0042426 6.938893903907228e-18 0.012 0 0.003000000000000007 0.012 0 0.003000000000000007 0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 0.008485299999999999 -0.008485299999999999 0.001500000000000007 0.0102426 -0.0042426 0.001500000000000007 0.0102426 0.0042426 6.938893903907228e-18 0.008485299999999999 0.008485299999999999 0.003000000000000007 0.008485299999999999 0.008485299999999999 0.003000000000000007 0.012 0 6.938893903907228e-18 0.012 0 0.001500000000000007 0.0102426 0.0042426 0.001500000000000007 0.0042426 0.0102426 0.003000000000000007 0 0.012 0.003000000000000007 0.008485299999999999 0.008485299999999999 0.001500000000000007 -0.0042426 0.0102426 0.003000000000000007 -0.008485299999999999 0.008485299999999999 0.003000000000000007 0 0.012 0.003000000000000007 -0.008485299999999999 0.008485299999999999 0.003000000000000007 -0.012 0 0.003000000000000007 0 0.012 0.003000000000000007 -0.007 0 0.003000000000000007 -0.012 0 0.003000000000000007 -0.008485299999999999 -0.008485299999999999 0.001500000000000007 -0.0042426 -0.0102426 0.003000000000000007 0 -0.012 0.003000000000000007 -0.008485299999999999 -0.008485299999999999 0.001500000000000007 0.0042426 -0.0102426 0.003000000000000007 0.008485299999999999 -0.008485299999999999 0.003000000000000007 0 -0.012 -0.02699999999999999 0.022 0.022 -0.02699999999999999 0 0 -0.02699999999999999 1.21431e-17 0.011 -0.02699999999999999 -0.022 0.022 -0.02699999999999999 0.022 0.022 -0.02699999999999999 1.21431e-17 0.011 -0.02699999999999999 0 0 -0.02699999999999999 -0.022 0.022 -0.02699999999999999 1.21431e-17 0.011 -0.02699999999999999 -0.022 -0.022 -0.02699999999999999 0 0 -0.02699999999999999 -1.21431e-17 -0.011 -0.02699999999999999 0.022 -0.022 -0.02699999999999999 -0.022 -0.022 -0.02699999999999999 -1.21431e-17 -0.011 -0.02699999999999999 0 0 -0.02699999999999999 0.022 -0.022 -0.02699999999999999 -1.21431e-17 -0.011 -0.02699999999999999 -0.033 -0.0158 -0.02742469999999999 -0.0319747 -0.01415 -0.02721239999999999 -0.0324873 -0.01415 -0.02699999999999999 -0.033 -0.0125 -0.02699999999999999 -0.033 -0.0158 -0.02721239999999999 -0.0324873 -0.01415 -0.02742469999999999 -0.0319747 -0.01415 -0.02699999999999999 -0.033 -0.0125 -0.02721239999999999 -0.0324873 -0.01415 -0.02784939999999999 -0.0309494 -0.0125 -0.02742469999999999 -0.0319747 -0.01415 -0.02763699999999999 -0.0314621 -0.01415 -0.02784939999999999 -0.0309494 -0.0158 -0.02784939999999999 -0.0309494 -0.0125 -0.02763699999999999 -0.0314621 -0.01415 -0.02742469999999999 -0.0319747 -0.01415 -0.02784939999999999 -0.0309494 -0.0158 -0.02763699999999999 -0.0314621 -0.01415 -0.02784939999999999 -0.0350506 -0.0125 -0.02742469999999999 -0.0340253 -0.01415 -0.02742469999999999 -0.0340253 -0.013325 -0.02699999999999999 -0.033 -0.0125 -0.02784939999999999 -0.0350506 -0.0125 -0.02742469999999999 -0.0340253 -0.013325 -0.02742469999999999 -0.0340253 -0.01415 -0.02699999999999999 -0.033 -0.0125 -0.02742469999999999 -0.0340253 -0.013325 -0.002899999999999993 -0.022 -0.0125 -0.03869999999999999 -0.0428 -0.0125 -0.02784939999999999 -0.0350506 -0.0125 -0.03869999999999999 -0.022 -0.0125 -0.0319506 -0.0309494 -0.0125 -0.03869999999999999 -0.0428 -0.0125 -0.02989999999999999 -0.0301 -0.0125 -0.03092529999999999 -0.0305247 -0.01415 -0.03092529999999999 -0.0305247 -0.013325 -0.0319506 -0.0309494 -0.0125 -0.02989999999999999 -0.0301 -0.0125 -0.03092529999999999 -0.0305247 -0.013325 -0.03092529999999999 -0.0305247 -0.01415 -0.0319506 -0.0309494 -0.0125 -0.03092529999999999 -0.0305247 -0.013325 -0.02784939999999999 -0.0309494 -0.0158 -0.02887469999999999 -0.0305247 -0.01415 -0.02836209999999999 -0.030737 -0.01415 -0.02784939999999999 -0.0309494 -0.0125 -0.02784939999999999 -0.0309494 -0.0158 -0.02836209999999999 -0.030737 -0.01415 -0.02887469999999999 -0.0305247 -0.01415 -0.02784939999999999 -0.0309494 -0.0125 -0.02836209999999999 -0.030737 -0.01415 -0.02989999999999999 -0.0301 -0.0125 -0.02887469999999999 -0.0305247 -0.01415 -0.02938739999999999 -0.0303124 -0.01415 -0.02989999999999999 -0.0301 -0.0158 -0.02989999999999999 -0.0301 -0.0125 -0.02938739999999999 -0.0303124 -0.01415 -0.02887469999999999 -0.0305247 -0.01415 -0.02989999999999999 -0.0301 -0.0158 -0.02938739999999999 -0.0303124 -0.01415 -0.03869999999999999 -0.022 -0.0125 -0.03869999999999999 -0.0324 0 -0.03869999999999999 -0.0272 0 -0.03869999999999999 -0.022 0.0125 -0.03869999999999999 -0.022 -0.0125 -0.03869999999999999 -0.0272 0 -0.03869999999999999 -0.0324 0 -0.03869999999999999 -0.022 0.0125 -0.03869999999999999 -0.0272 0 -0.002899999999999993 -0.0428 0.0125 -0.02079999999999999 -0.0428 0 -0.01184999999999999 -0.0428 -2.60209e-18 -0.002899999999999993 -0.0428 -0.0125 -0.002899999999999993 -0.0428 0.0125 -0.01184999999999999 -0.0428 -2.60209e-18 -0.02079999999999999 -0.0428 0 -0.002899999999999993 -0.0428 -0.0125 -0.01184999999999999 -0.0428 -2.60209e-18 -0.03869999999999999 -0.0428 0.0125 -0.02079999999999999 -0.0428 0 -0.02079999999999999 -0.0428 0.00625 -0.002899999999999993 -0.0428 0.0125 -0.03869999999999999 -0.0428 0.0125 -0.02079999999999999 -0.0428 0.00625 -0.02079999999999999 -0.0428 0 -0.002899999999999993 -0.0428 0.0125 -0.02079999999999999 -0.0428 0.00625 -0.002899999999999993 -0.022 0.0125 -0.02777869999999999 -0.0351213 0.0125 -0.03869999999999999 -0.0428 0.0125 -0.002899999999999993 -0.0428 -0.0125 -0.02079999999999999 -0.0428 0 -0.02079999999999999 -0.0428 -0.00625 -0.03869999999999999 -0.0428 -0.0125 -0.002899999999999993 -0.0428 -0.0125 -0.02079999999999999 -0.0428 -0.00625 -0.02079999999999999 -0.0428 0 -0.03869999999999999 -0.0428 -0.0125 -0.02079999999999999 -0.0428 -0.00625 -0.02733929999999999 -0.0340607 0.01415 -0.02733929999999999 -0.0340607 0.013325 -0.02689999999999999 -0.033 0.0125 -0.02689999999999999 -0.033 0.0125 -0.02733929999999999 -0.0340607 0.013325 -0.02777869999999999 -0.0351213 0.0125 -0.02777869999999999 -0.0351213 0.0125 -0.02733929999999999 -0.0340607 0.013325 -0.02733929999999999 -0.0340607 0.01415 -0.02777869999999999 -0.0308787 0.0158 -0.02733929999999999 -0.0319393 0.01415 -0.02755899999999999 -0.031409 0.01415 -0.02777869999999999 -0.0308787 0.0125 -0.02777869999999999 -0.0308787 0.0158 -0.02755899999999999 -0.031409 0.01415 -0.02733929999999999 -0.0319393 0.01415 -0.02777869999999999 -0.0308787 0.0125 -0.02755899999999999 -0.031409 0.01415 -0.02689999999999999 -0.033 0.0125 -0.02733929999999999 -0.0319393 0.01415 -0.02711969999999999 -0.0324697 0.01415 -0.02689999999999999 -0.033 0.0158 -0.02689999999999999 -0.033 0.0125 -0.02711969999999999 -0.0324697 0.01415 -0.02733929999999999 -0.0319393 0.01415 -0.02689999999999999 -0.033 0.0158 -0.02711969999999999 -0.0324697 0.01415 -0.02989999999999999 -0.03 0.0158 -0.02883929999999999 -0.0304393 0.01415 -0.02936959999999999 -0.0302196 0.01415 -0.02989999999999999 -0.03 0.0125 -0.02989999999999999 -0.03 0.0158 -0.02936959999999999 -0.0302196 0.01415 -0.02883929999999999 -0.0304393 0.01415 -0.02989999999999999 -0.03 0.0125 -0.02936959999999999 -0.0302196 0.01415 -0.02777869999999999 -0.0308787 0.0125 -0.02883929999999999 -0.0304393 0.01415 -0.02830899999999999 -0.030659 0.01415 -0.02777869999999999 -0.0308787 0.0158 -0.02777869999999999 -0.0308787 0.0125 -0.02830899999999999 -0.030659 0.01415 -0.02883929999999999 -0.0304393 0.01415 -0.02777869999999999 -0.0308787 0.0158 -0.02830899999999999 -0.030659 0.01415 -0.0320213 -0.0308787 0.0125 -0.03096069999999999 -0.0304393 0.01415 -0.03096069999999999 -0.0304393 0.013325 -0.02989999999999999 -0.03 0.0125 -0.0320213 -0.0308787 0.0125 -0.03096069999999999 -0.0304393 0.013325 -0.03096069999999999 -0.0304393 0.01415 -0.02989999999999999 -0.03 0.0125 -0.03096069999999999 -0.0304393 0.013325 -0.0320213 -0.0308787 0.0125 -0.03869999999999999 -0.022 0.0125 -0.03869999999999999 -0.0428 0.0125 -0.02117049999999999 0.022 0.0125 -0.02699999999999999 0.022 0.0125 -0.02699999999999999 0.022 0.022 -0.02699999999999999 0.022 0.0125 -0.03869999999999999 0.022 0.0125 -0.02699999999999999 0.022 0.00432961 -0.002899999999999993 0.0428 0.0125 -0.02784939999999999 0.0309494 0.0125 -0.03869999999999999 0.022 0.0125 -0.002899999999999993 0.022 0.0125 -0.002899999999999993 0.0324 0 -0.002899999999999993 0.0324 0.00625 -0.002899999999999993 0.0428 0.0125 -0.002899999999999993 0.022 0.0125 -0.002899999999999993 0.0324 0.00625 -0.002899999999999993 0.0324 0 -0.002899999999999993 0.0428 0.0125 -0.002899999999999993 0.0324 0.00625 -0.002899999999999993 0.0428 -0.0125 -0.002899999999999993 0.0324 0 -0.002899999999999993 0.0324 -0.00625 -0.002899999999999993 0.0324 0 -0.002899999999999993 0.022 -0.0125 -0.002899999999999993 0.0324 -0.00625 -0.002899999999999993 0.022 -0.0125 -0.002899999999999993 0.0428 -0.0125 -0.002899999999999993 0.0324 -0.00625 -0.002899999999999993 0.0428 -0.0125 -0.03869999999999999 0.022 -0.0125 -0.02777869999999999 0.0308787 -0.0125 -0.02699999999999999 0.022 -0.00432961 -0.03869999999999999 0.022 -0.0125 -0.02699999999999999 0.022 -0.0125 -0.02699999999999999 0.022 -0.022 -0.02699999999999999 0.022 -0.0125 -0.02117049999999999 0.022 -0.0125 0.003000000000000007 0.008485299999999999 -0.008485299999999999 0.001500000000000007 0.0102426 -0.0042426 0.003000000000000007 0.012 0 0.001500000000000007 0.0102426 0.0042426 0.003000000000000007 0.008485299999999999 0.008485299999999999 0.003000000000000007 0.012 0 0.003000000000000007 0 0.012 0.003000000000000007 0 0.007 0.003000000000000007 0.008485299999999999 0.008485299999999999 0.003000000000000007 0 0.012 0.003000000000000007 -0.012 0 0.003000000000000007 -0.0049497 0.0049497 0.003000000000000007 -0.0049497 0.0049497 0.003000000000000007 -0.012 0 0.003000000000000007 -0.007 0 0.003000000000000007 -0.007 0 0.003000000000000007 -0.008485299999999999 -0.008485299999999999 0.003000000000000007 -0.0049497 -0.0049497 0.003000000000000007 0 -0.007 0.003000000000000007 -0.008485299999999999 -0.008485299999999999 0.003000000000000007 0 -0.012 0.003000000000000007 0.012 0 0.003000000000000007 0 -0.012 0.003000000000000007 0.008485299999999999 -0.008485299999999999 -0.02699999999999999 0.022 -0.022 -0.02699999999999999 0 0 -0.02699999999999999 0.022 -0.0125 -0.02699999999999999 0.022 0.0125 -0.02699999999999999 0 0 -0.02699999999999999 0.022 0.022 -0.02699999999999999 0.022 -0.00432961 -0.02699999999999999 0.022 -0.0125 -0.02699999999999999 0.011 -1.73472e-18 -0.02699999999999999 0.022 0.0125 -0.02699999999999999 0.022 0.00432961 -0.02699999999999999 0.011 -1.73472e-18 -0.02699999999999999 0.022 0.00432961 -0.02699999999999999 0.022 -0.00432961 -0.02699999999999999 0.011 -1.73472e-18 -0.02699999999999999 0.022 -0.0125 -0.02699999999999999 0 0 -0.02699999999999999 0.011 -1.73472e-18 -0.02699999999999999 0 0 -0.02699999999999999 0.022 0.0125 -0.02699999999999999 0.011 -1.73472e-18 -0.02784939999999999 -0.0309494 -0.0158 -0.02742469999999999 -0.0319747 -0.01415 -0.02742469999999999 -0.0319747 -0.014975 -0.02699999999999999 -0.033 -0.0158 -0.02784939999999999 -0.0309494 -0.0158 -0.02742469999999999 -0.0319747 -0.014975 -0.02742469999999999 -0.0319747 -0.01415 -0.02699999999999999 -0.033 -0.0158 -0.02742469999999999 -0.0319747 -0.014975 -0.02699999999999999 -0.033 -0.0125 -0.02742469999999999 -0.0340253 -0.01415 -0.02721239999999999 -0.0335127 -0.01415 -0.02699999999999999 -0.033 -0.0158 -0.02699999999999999 -0.033 -0.0125 -0.02721239999999999 -0.0335127 -0.01415 -0.02742469999999999 -0.0340253 -0.01415 -0.02699999999999999 -0.033 -0.0158 -0.02721239999999999 -0.0335127 -0.01415 -0.02784939999999999 -0.0350506 -0.0158 -0.02742469999999999 -0.0340253 -0.01415 -0.02763699999999999 -0.0345379 -0.01415 -0.02784939999999999 -0.0350506 -0.0125 -0.02784939999999999 -0.0350506 -0.0158 -0.02763699999999999 -0.0345379 -0.01415 -0.02742469999999999 -0.0340253 -0.01415 -0.02784939999999999 -0.0350506 -0.0125 -0.02763699999999999 -0.0345379 -0.01415 -0.02784939999999999 -0.0350506 -0.0125 -0.03869999999999999 -0.0428 -0.0125 -0.02989999999999999 -0.0359 -0.0125 -0.03869999999999999 -0.0428 -0.0125 -0.03869999999999999 -0.0324 0 -0.03869999999999999 -0.0324 -0.00625 -0.03869999999999999 -0.022 -0.0125 -0.03869999999999999 -0.0428 -0.0125 -0.03869999999999999 -0.0324 -0.00625 -0.03869999999999999 -0.0324 0 -0.03869999999999999 -0.022 -0.0125 -0.03869999999999999 -0.0324 -0.00625 -0.0328 -0.033 -0.0125 -0.03869999999999999 -0.0428 -0.0125 -0.0319506 -0.0309494 -0.0125 -0.02989999999999999 -0.0301 -0.0158 -0.03092529999999999 -0.0305247 -0.01415 -0.03041259999999999 -0.0303124 -0.01415 -0.02989999999999999 -0.0301 -0.0125 -0.02989999999999999 -0.0301 -0.0158 -0.03041259999999999 -0.0303124 -0.01415 -0.03092529999999999 -0.0305247 -0.01415 -0.02989999999999999 -0.0301 -0.0125 -0.03041259999999999 -0.0303124 -0.01415 -0.0319506 -0.0309494 -0.0125 -0.03092529999999999 -0.0305247 -0.01415 -0.03143789999999999 -0.030737 -0.01415 -0.0319506 -0.0309494 -0.0158 -0.0319506 -0.0309494 -0.0125 -0.03143789999999999 -0.030737 -0.01415 -0.03092529999999999 -0.0305247 -0.01415 -0.0319506 -0.0309494 -0.0158 -0.03143789999999999 -0.030737 -0.01415 -0.02989999999999999 -0.0301 -0.0158 -0.02887469999999999 -0.0305247 -0.01415 -0.02887469999999999 -0.0305247 -0.014975 -0.02784939999999999 -0.0309494 -0.0158 -0.02989999999999999 -0.0301 -0.0158 -0.02887469999999999 -0.0305247 -0.014975 -0.02887469999999999 -0.0305247 -0.01415 -0.02784939999999999 -0.0309494 -0.0158 -0.02887469999999999 -0.0305247 -0.014975 -0.03869999999999999 -0.022 0.0125 -0.03869999999999999 -0.0324 0 -0.03869999999999999 -0.0324 0.00625 -0.03869999999999999 -0.0428 0.0125 -0.03869999999999999 -0.022 0.0125 -0.03869999999999999 -0.0324 0.00625 -0.03869999999999999 -0.0324 0 -0.03869999999999999 -0.0428 0.0125 -0.03869999999999999 -0.0324 0.00625 -0.03869999999999999 -0.0428 -0.0125 -0.02079999999999999 -0.0428 0 -0.02974999999999999 -0.0428 -1.56125e-17 -0.03869999999999999 -0.0428 0.0125 -0.03869999999999999 -0.0428 -0.0125 -0.02974999999999999 -0.0428 -1.56125e-17 -0.02079999999999999 -0.0428 0 -0.03869999999999999 -0.0428 0.0125 -0.02974999999999999 -0.0428 -1.56125e-17 -0.02777869999999999 -0.0351213 0.0125 -0.02989999999999999 -0.036 0.0125 -0.03869999999999999 -0.0428 0.0125 -0.02689999999999999 -0.033 0.0158 -0.02733929999999999 -0.0340607 0.01415 -0.02711969999999999 -0.0335304 0.01415 -0.02689999999999999 -0.033 0.0125 -0.02689999999999999 -0.033 0.0158 -0.02711969999999999 -0.0335304 0.01415 -0.02733929999999999 -0.0340607 0.01415 -0.02689999999999999 -0.033 0.0125 -0.02711969999999999 -0.0335304 0.01415 -0.02777869999999999 -0.0351213 0.0125 -0.02733929999999999 -0.0340607 0.01415 -0.02755899999999999 -0.034591 0.01415 -0.02777869999999999 -0.0351213 0.0158 -0.02777869999999999 -0.0351213 0.0125 -0.02755899999999999 -0.034591 0.01415 -0.02733929999999999 -0.0340607 0.01415 -0.02777869999999999 -0.0351213 0.0158 -0.02755899999999999 -0.034591 0.01415 -0.02733929999999999 -0.0319393 0.01415 -0.02733929999999999 -0.0319393 0.014975 -0.02689999999999999 -0.033 0.0158 -0.02689999999999999 -0.033 0.0158 -0.02733929999999999 -0.0319393 0.014975 -0.02777869999999999 -0.0308787 0.0158 -0.02777869999999999 -0.0308787 0.0158 -0.02733929999999999 -0.0319393 0.014975 -0.02733929999999999 -0.0319393 0.01415 -0.02777869999999999 -0.0308787 0.0158 -0.02883929999999999 -0.0304393 0.01415 -0.02883929999999999 -0.0304393 0.014975 -0.02989999999999999 -0.03 0.0158 -0.02777869999999999 -0.0308787 0.0158 -0.02883929999999999 -0.0304393 0.014975 -0.02883929999999999 -0.0304393 0.01415 -0.02989999999999999 -0.03 0.0158 -0.02883929999999999 -0.0304393 0.014975 -0.02989999999999999 -0.03 0.0125 -0.03096069999999999 -0.0304393 0.01415 -0.03043039999999999 -0.0302196 0.01415 -0.02989999999999999 -0.03 0.0158 -0.02989999999999999 -0.03 0.0125 -0.03043039999999999 -0.0302196 0.01415 -0.03096069999999999 -0.0304393 0.01415 -0.02989999999999999 -0.03 0.0158 -0.03043039999999999 -0.0302196 0.01415 -0.0320213 -0.0308787 0.0158 -0.03096069999999999 -0.0304393 0.01415 -0.03149099999999999 -0.030659 0.01415 -0.0320213 -0.0308787 0.0125 -0.0320213 -0.0308787 0.0158 -0.03149099999999999 -0.030659 0.01415 -0.03096069999999999 -0.0304393 0.01415 -0.0320213 -0.0308787 0.0125 -0.03149099999999999 -0.030659 0.01415 -0.03289999999999999 -0.033 0.0125 -0.0320213 -0.0308787 0.0125 -0.03869999999999999 -0.0428 0.0125 -0.03869999999999999 0.022 0.0125 -0.03869999999999999 0.022 -0.0125 -0.03284999999999999 0.022 -1.56125e-17 -0.02699999999999999 0.022 0.00432961 -0.03869999999999999 0.022 0.0125 -0.03284999999999999 0.022 -1.56125e-17 -0.02699999999999999 0.022 -0.00432961 -0.02699999999999999 0.022 0.00432961 -0.03284999999999999 0.022 -1.56125e-17 -0.03869999999999999 0.022 -0.0125 -0.02699999999999999 0.022 -0.00432961 -0.03284999999999999 0.022 -1.56125e-17 -0.02784939999999999 0.0309494 0.0125 -0.02989999999999999 0.0301 0.0125 -0.03869999999999999 0.022 0.0125 -0.002899999999999993 0.0428 0.0125 -0.02699999999999999 0.033 0.0125 -0.02784939999999999 0.0309494 0.0125 -0.002899999999999993 0.0428 0.0125 -0.002899999999999993 0.0324 0 -0.002899999999999993 0.0376 7.806259999999999e-18 -0.002899999999999993 0.0428 -0.0125 -0.002899999999999993 0.0428 0.0125 -0.002899999999999993 0.0376 7.806259999999999e-18 -0.002899999999999993 0.0324 0 -0.002899999999999993 0.0428 -0.0125 -0.002899999999999993 0.0376 7.806259999999999e-18 -0.02777869999999999 0.0308787 -0.0125 -0.02689999999999999 0.033 -0.0125 -0.002899999999999993 0.0428 -0.0125 -0.02777869999999999 0.0308787 -0.0125 -0.03869999999999999 0.022 -0.0125 -0.02989999999999999 0.03 -0.0125 0.003000000000000007 0.008485299999999999 0.008485299999999999 0.003000000000000007 0.0049497 0.0049497 0.003000000000000007 0.012 0 0.003000000000000007 0.008485299999999999 0.008485299999999999 0.003000000000000007 0 0.007 0.003000000000000007 0.0049497 0.0049497 0.003000000000000007 0 0.012 0.003000000000000007 -0.0049497 0.0049497 0.003000000000000007 0 0.007 0.003000000000000007 -0.007 0 0.009000000000000006 -0.0059749 0.0024749 0.003000000000000007 -0.0049497 0.0049497 0.003000000000000007 -0.007 0 0.003000000000000007 -0.0049497 -0.0049497 0.009000000000000006 -0.0059749 -0.0024749 0.003000000000000007 -0.0049497 -0.0049497 0.003000000000000007 -0.008485299999999999 -0.008485299999999999 0.003000000000000007 0 -0.007 0.003000000000000007 0.0049497 -0.0049497 0.003000000000000007 0 -0.007 0.003000000000000007 0 -0.012 0.003000000000000007 0.0049497 -0.0049497 0.003000000000000007 0 -0.012 0.003000000000000007 0.012 0 -0.02989999999999999 -0.033 -0.0158 -0.02784939999999999 -0.0309494 -0.0158 -0.02699999999999999 -0.033 -0.0158 -0.02699999999999999 -0.033 -0.0158 -0.02742469999999999 -0.0340253 -0.01415 -0.02742469999999999 -0.0340253 -0.014975 -0.02784939999999999 -0.0350506 -0.0158 -0.02699999999999999 -0.033 -0.0158 -0.02742469999999999 -0.0340253 -0.014975 -0.02742469999999999 -0.0340253 -0.01415 -0.02784939999999999 -0.0350506 -0.0158 -0.02742469999999999 -0.0340253 -0.014975 -0.02784939999999999 -0.0350506 -0.0125 -0.02887469999999999 -0.0354753 -0.01415 -0.02836209999999999 -0.0352629 -0.01415 -0.02784939999999999 -0.0350506 -0.0158 -0.02784939999999999 -0.0350506 -0.0125 -0.02836209999999999 -0.0352629 -0.01415 -0.02887469999999999 -0.0354753 -0.01415 -0.02784939999999999 -0.0350506 -0.0158 -0.02836209999999999 -0.0352629 -0.01415 -0.02887469999999999 -0.0354753 -0.01415 -0.02887469999999999 -0.0354753 -0.013325 -0.02989999999999999 -0.0359 -0.0125 -0.02989999999999999 -0.0359 -0.0125 -0.02887469999999999 -0.0354753 -0.013325 -0.02784939999999999 -0.0350506 -0.0125 -0.02784939999999999 -0.0350506 -0.0125 -0.02887469999999999 -0.0354753 -0.013325 -0.02887469999999999 -0.0354753 -0.01415 -0.03869999999999999 -0.0428 -0.0125 -0.0319506 -0.0350506 -0.0125 -0.02989999999999999 -0.0359 -0.0125 -0.03869999999999999 -0.0428 0.0125 -0.03869999999999999 -0.0324 0 -0.03869999999999999 -0.0376 -7.806259999999999e-18 -0.03869999999999999 -0.0428 -0.0125 -0.03869999999999999 -0.0428 0.0125 -0.03869999999999999 -0.0376 -7.806259999999999e-18 -0.03869999999999999 -0.0324 0 -0.03869999999999999 -0.0428 -0.0125 -0.03869999999999999 -0.0376 -7.806259999999999e-18 -0.0319506 -0.0309494 -0.0125 -0.0323753 -0.0319747 -0.01415 -0.0323753 -0.0319747 -0.013325 -0.0328 -0.033 -0.0125 -0.0319506 -0.0309494 -0.0125 -0.0323753 -0.0319747 -0.013325 -0.0323753 -0.0319747 -0.01415 -0.0328 -0.033 -0.0125 -0.0323753 -0.0319747 -0.013325 -0.0328 -0.033 -0.0125 -0.0319506 -0.0350506 -0.0125 -0.03869999999999999 -0.0428 -0.0125 -0.0319506 -0.0309494 -0.0158 -0.03092529999999999 -0.0305247 -0.01415 -0.03092529999999999 -0.0305247 -0.014975 -0.02989999999999999 -0.0301 -0.0158 -0.0319506 -0.0309494 -0.0158 -0.03092529999999999 -0.0305247 -0.014975 -0.03092529999999999 -0.0305247 -0.01415 -0.02989999999999999 -0.0301 -0.0158 -0.03092529999999999 -0.0305247 -0.014975 -0.0319506 -0.0309494 -0.0158 -0.0323753 -0.0319747 -0.01415 -0.03216289999999999 -0.0314621 -0.01415 -0.0319506 -0.0309494 -0.0125 -0.0319506 -0.0309494 -0.0158 -0.03216289999999999 -0.0314621 -0.01415 -0.0323753 -0.0319747 -0.01415 -0.0319506 -0.0309494 -0.0125 -0.03216289999999999 -0.0314621 -0.01415 -0.02989999999999999 -0.033 -0.0158 -0.02989999999999999 -0.0301 -0.0158 -0.02784939999999999 -0.0309494 -0.0158 -0.02989999999999999 -0.036 0.0125 -0.0320213 -0.0351213 0.0125 -0.03869999999999999 -0.0428 0.0125 -0.02777869999999999 -0.0351213 0.0125 -0.02883929999999999 -0.0355607 0.01415 -0.02883929999999999 -0.0355607 0.013325 -0.02989999999999999 -0.036 0.0125 -0.02777869999999999 -0.0351213 0.0125 -0.02883929999999999 -0.0355607 0.013325 -0.02883929999999999 -0.0355607 0.01415 -0.02989999999999999 -0.036 0.0125 -0.02883929999999999 -0.0355607 0.013325 -0.02777869999999999 -0.0351213 0.0158 -0.02733929999999999 -0.0340607 0.01415 -0.02733929999999999 -0.0340607 0.014975 -0.02689999999999999 -0.033 0.0158 -0.02777869999999999 -0.0351213 0.0158 -0.02733929999999999 -0.0340607 0.014975 -0.02733929999999999 -0.0340607 0.01415 -0.02689999999999999 -0.033 0.0158 -0.02733929999999999 -0.0340607 0.014975 -0.02777869999999999 -0.0351213 0.0158 -0.02883929999999999 -0.0355607 0.01415 -0.02830899999999999 -0.035341 0.01415 -0.02777869999999999 -0.0351213 0.0125 -0.02777869999999999 -0.0351213 0.0158 -0.02830899999999999 -0.035341 0.01415 -0.02883929999999999 -0.0355607 0.01415 -0.02777869999999999 -0.0351213 0.0125 -0.02830899999999999 -0.035341 0.01415 -0.02689999999999999 -0.033 0.0158 -0.02777869999999999 -0.0308787 0.0158 -0.02989999999999999 -0.033 0.0158 -0.02777869999999999 -0.0308787 0.0158 -0.02989999999999999 -0.03 0.0158 -0.02989999999999999 -0.033 0.0158 -0.02989999999999999 -0.03 0.0158 -0.03096069999999999 -0.0304393 0.01415 -0.03096069999999999 -0.0304393 0.014975 -0.0320213 -0.0308787 0.0158 -0.02989999999999999 -0.03 0.0158 -0.03096069999999999 -0.0304393 0.014975 -0.03096069999999999 -0.0304393 0.01415 -0.0320213 -0.0308787 0.0158 -0.03096069999999999 -0.0304393 0.014975 -0.0320213 -0.0308787 0.0125 -0.0324607 -0.0319393 0.01415 -0.03224099999999999 -0.031409 0.01415 -0.0320213 -0.0308787 0.0158 -0.0320213 -0.0308787 0.0125 -0.03224099999999999 -0.031409 0.01415 -0.0324607 -0.0319393 0.01415 -0.0320213 -0.0308787 0.0158 -0.03224099999999999 -0.031409 0.01415 -0.0320213 -0.0351213 0.0125 -0.03289999999999999 -0.033 0.0125 -0.03869999999999999 -0.0428 0.0125 -0.0324607 -0.0319393 0.01415 -0.0324607 -0.0319393 0.013325 -0.03289999999999999 -0.033 0.0125 -0.03289999999999999 -0.033 0.0125 -0.0324607 -0.0319393 0.013325 -0.0320213 -0.0308787 0.0125 -0.0320213 -0.0308787 0.0125 -0.0324607 -0.0319393 0.013325 -0.0324607 -0.0319393 0.01415 -0.03869999999999999 0.022 0.0125 -0.03869999999999999 0.0324 0 -0.03869999999999999 0.0272 -7.806259999999999e-18 -0.03869999999999999 0.022 -0.0125 -0.03869999999999999 0.022 0.0125 -0.03869999999999999 0.0272 -7.806259999999999e-18 -0.03869999999999999 0.0324 0 -0.03869999999999999 0.022 -0.0125 -0.03869999999999999 0.0272 -7.806259999999999e-18 -0.02989999999999999 0.0301 0.0125 -0.0319506 0.0309494 0.0125 -0.03869999999999999 0.022 0.0125 -0.02784939999999999 0.0309494 0.0125 -0.02887469999999999 0.0305247 0.01415 -0.02887469999999999 0.0305247 0.013325 -0.02989999999999999 0.0301 0.0125 -0.02784939999999999 0.0309494 0.0125 -0.02887469999999999 0.0305247 0.013325 -0.02887469999999999 0.0305247 0.01415 -0.02989999999999999 0.0301 0.0125 -0.02887469999999999 0.0305247 0.013325 -0.02742469999999999 0.0319747 0.01415 -0.02742469999999999 0.0319747 0.013325 -0.02699999999999999 0.033 0.0125 -0.02699999999999999 0.033 0.0125 -0.02742469999999999 0.0319747 0.013325 -0.02784939999999999 0.0309494 0.0125 -0.02784939999999999 0.0309494 0.0125 -0.02742469999999999 0.0319747 0.013325 -0.02742469999999999 0.0319747 0.01415 -0.002899999999999993 0.0428 0.0125 -0.02784939999999999 0.0350506 0.0125 -0.02699999999999999 0.033 0.0125 -0.002899999999999993 0.0428 -0.0125 -0.02079999999999999 0.0428 0 -0.01184999999999999 0.0428 8.67362e-19 -0.002899999999999993 0.0428 0.0125 -0.002899999999999993 0.0428 -0.0125 -0.01184999999999999 0.0428 8.67362e-19 -0.02079999999999999 0.0428 0 -0.002899999999999993 0.0428 0.0125 -0.01184999999999999 0.0428 8.67362e-19 -0.02689999999999999 0.033 -0.0125 -0.02777869999999999 0.0351213 -0.0125 -0.002899999999999993 0.0428 -0.0125 -0.02733929999999999 0.0319393 -0.01415 -0.02733929999999999 0.0319393 -0.013325 -0.02777869999999999 0.0308787 -0.0125 -0.02777869999999999 0.0308787 -0.0125 -0.02733929999999999 0.0319393 -0.013325 -0.02689999999999999 0.033 -0.0125 -0.02689999999999999 0.033 -0.0125 -0.02733929999999999 0.0319393 -0.013325 -0.02733929999999999 0.0319393 -0.01415 -0.02883929999999999 0.0304393 -0.01415 -0.02883929999999999 0.0304393 -0.013325 -0.02989999999999999 0.03 -0.0125 -0.02989999999999999 0.03 -0.0125 -0.02883929999999999 0.0304393 -0.013325 -0.02777869999999999 0.0308787 -0.0125 -0.02777869999999999 0.0308787 -0.0125 -0.02883929999999999 0.0304393 -0.013325 -0.02883929999999999 0.0304393 -0.01415 -0.03869999999999999 0.022 -0.0125 -0.0320213 0.0308787 -0.0125 -0.02989999999999999 0.03 -0.0125 0.003000000000000007 0.0049497 0.0049497 0.003000000000000007 0.007 0 0.003000000000000007 0.012 0 0.003000000000000007 0 0.007 0.009000000000000006 0.0024749 0.0059749 0.003000000000000007 0.0049497 0.0049497 0.003000000000000007 -0.0049497 0.0049497 0.009000000000000006 -0.0024749 0.0059749 0.003000000000000007 0 0.007 0.009000000000000006 -0.0059749 0.0024749 0.003000000000000007 -0.007 0 0.01500000000000001 -0.007 0 0.003000000000000007 -0.0049497 0.0049497 0.009000000000000006 -0.0059749 0.0024749 0.01500000000000001 -0.0049497 0.0049497 0.009000000000000006 -0.0059749 -0.0024749 0.003000000000000007 -0.0049497 -0.0049497 0.01500000000000001 -0.0049497 -0.0049497 0.003000000000000007 -0.007 0 0.009000000000000006 -0.0059749 -0.0024749 0.01500000000000001 -0.007 0 0.003000000000000007 0 -0.007 0.009000000000000006 -0.0024749 -0.0059749 0.003000000000000007 -0.0049497 -0.0049497 0.003000000000000007 0.0049497 -0.0049497 0.009000000000000006 0.0024749 -0.0059749 0.003000000000000007 0 -0.007 0.003000000000000007 0.007 0 0.003000000000000007 0.0049497 -0.0049497 0.003000000000000007 0.012 0 -0.02989999999999999 -0.033 -0.0158 -0.02699999999999999 -0.033 -0.0158 -0.02784939999999999 -0.0350506 -0.0158 -0.02784939999999999 -0.0350506 -0.0158 -0.02887469999999999 -0.0354753 -0.01415 -0.02887469999999999 -0.0354753 -0.014975 -0.02989999999999999 -0.0359 -0.0158 -0.02784939999999999 -0.0350506 -0.0158 -0.02887469999999999 -0.0354753 -0.014975 -0.02887469999999999 -0.0354753 -0.01415 -0.02989999999999999 -0.0359 -0.0158 -0.02887469999999999 -0.0354753 -0.014975 -0.02989999999999999 -0.0359 -0.0158 -0.02887469999999999 -0.0354753 -0.01415 -0.02938739999999999 -0.0356876 -0.01415 -0.02989999999999999 -0.0359 -0.0125 -0.02989999999999999 -0.0359 -0.0158 -0.02938739999999999 -0.0356876 -0.01415 -0.02887469999999999 -0.0354753 -0.01415 -0.02989999999999999 -0.0359 -0.0125 -0.02938739999999999 -0.0356876 -0.01415 -0.03092529999999999 -0.0354753 -0.01415 -0.03092529999999999 -0.0354753 -0.013325 -0.0319506 -0.0350506 -0.0125 -0.0319506 -0.0350506 -0.0125 -0.03092529999999999 -0.0354753 -0.013325 -0.02989999999999999 -0.0359 -0.0125 -0.02989999999999999 -0.0359 -0.0125 -0.03092529999999999 -0.0354753 -0.013325 -0.03092529999999999 -0.0354753 -0.01415 -0.0328 -0.033 -0.0125 -0.0323753 -0.0319747 -0.01415 -0.03258759999999999 -0.0324873 -0.01415 -0.0328 -0.033 -0.0158 -0.0328 -0.033 -0.0125 -0.03258759999999999 -0.0324873 -0.01415 -0.0323753 -0.0319747 -0.01415 -0.0328 -0.033 -0.0158 -0.03258759999999999 -0.0324873 -0.01415 -0.0328 -0.033 -0.0125 -0.0323753 -0.0340253 -0.01415 -0.0323753 -0.0340253 -0.013325 -0.0319506 -0.0350506 -0.0125 -0.0328 -0.033 -0.0125 -0.0323753 -0.0340253 -0.013325 -0.0323753 -0.0340253 -0.01415 -0.0319506 -0.0350506 -0.0125 -0.0323753 -0.0340253 -0.013325 -0.0319506 -0.0309494 -0.0158 -0.02989999999999999 -0.0301 -0.0158 -0.02989999999999999 -0.033 -0.0158 -0.0323753 -0.0319747 -0.01415 -0.0323753 -0.0319747 -0.014975 -0.0328 -0.033 -0.0158 -0.0328 -0.033 -0.0158 -0.0323753 -0.0319747 -0.014975 -0.0319506 -0.0309494 -0.0158 -0.0319506 -0.0309494 -0.0158 -0.0323753 -0.0319747 -0.014975 -0.0323753 -0.0319747 -0.01415 -0.02989999999999999 -0.036 0.0125 -0.03096069999999999 -0.0355607 0.01415 -0.03096069999999999 -0.0355607 0.013325 -0.0320213 -0.0351213 0.0125 -0.02989999999999999 -0.036 0.0125 -0.03096069999999999 -0.0355607 0.013325 -0.03096069999999999 -0.0355607 0.01415 -0.0320213 -0.0351213 0.0125 -0.03096069999999999 -0.0355607 0.013325 -0.02989999999999999 -0.036 0.0125 -0.02883929999999999 -0.0355607 0.01415 -0.02936959999999999 -0.0357803 0.01415 -0.02989999999999999 -0.036 0.0158 -0.02989999999999999 -0.036 0.0125 -0.02936959999999999 -0.0357803 0.01415 -0.02883929999999999 -0.0355607 0.01415 -0.02989999999999999 -0.036 0.0158 -0.02936959999999999 -0.0357803 0.01415 -0.02777869999999999 -0.0351213 0.0158 -0.02689999999999999 -0.033 0.0158 -0.02989999999999999 -0.033 0.0158 -0.02883929999999999 -0.0355607 0.01415 -0.02883929999999999 -0.0355607 0.014975 -0.02989999999999999 -0.036 0.0158 -0.02989999999999999 -0.036 0.0158 -0.02883929999999999 -0.0355607 0.014975 -0.02777869999999999 -0.0351213 0.0158 -0.02777869999999999 -0.0351213 0.0158 -0.02883929999999999 -0.0355607 0.014975 -0.02883929999999999 -0.0355607 0.01415 -0.02989999999999999 -0.033 0.0158 -0.02989999999999999 -0.03 0.0158 -0.0320213 -0.0308787 0.0158 -0.0324607 -0.0319393 0.01415 -0.0324607 -0.0319393 0.014975 -0.0320213 -0.0308787 0.0158 -0.0320213 -0.0308787 0.0158 -0.0324607 -0.0319393 0.014975 -0.03289999999999999 -0.033 0.0158 -0.03289999999999999 -0.033 0.0158 -0.0324607 -0.0319393 0.014975 -0.0324607 -0.0319393 0.01415 -0.0324607 -0.0340607 0.01415 -0.0324607 -0.0340607 0.013325 -0.0320213 -0.0351213 0.0125 -0.0320213 -0.0351213 0.0125 -0.0324607 -0.0340607 0.013325 -0.03289999999999999 -0.033 0.0125 -0.03289999999999999 -0.033 0.0125 -0.0324607 -0.0340607 0.013325 -0.0324607 -0.0340607 0.01415 -0.03289999999999999 -0.033 0.0158 -0.0324607 -0.0319393 0.01415 -0.03268039999999999 -0.0324697 0.01415 -0.03289999999999999 -0.033 0.0125 -0.03289999999999999 -0.033 0.0158 -0.03268039999999999 -0.0324697 0.01415 -0.0324607 -0.0319393 0.01415 -0.03289999999999999 -0.033 0.0125 -0.03268039999999999 -0.0324697 0.01415 -0.03869999999999999 0.0428 0.0125 -0.03869999999999999 0.0324 0 -0.03869999999999999 0.0324 0.00625 -0.03869999999999999 0.022 0.0125 -0.03869999999999999 0.0428 0.0125 -0.03869999999999999 0.0324 0.00625 -0.03869999999999999 0.0324 0 -0.03869999999999999 0.022 0.0125 -0.03869999999999999 0.0324 0.00625 -0.03869999999999999 0.022 -0.0125 -0.03869999999999999 0.0324 0 -0.03869999999999999 0.0324 -0.00625 -0.03869999999999999 0.0428 -0.0125 -0.03869999999999999 0.022 -0.0125 -0.03869999999999999 0.0324 -0.00625 -0.03869999999999999 0.0324 0 -0.03869999999999999 0.0428 -0.0125 -0.03869999999999999 0.0324 -0.00625 -0.0319506 0.0309494 0.0125 -0.0328 0.033 0.0125 -0.03869999999999999 0.022 0.0125 -0.02989999999999999 0.0301 0.0125 -0.03092529999999999 0.0305247 0.01415 -0.03092529999999999 0.0305247 0.013325 -0.0319506 0.0309494 0.0125 -0.02989999999999999 0.0301 0.0125 -0.03092529999999999 0.0305247 0.013325 -0.03092529999999999 0.0305247 0.01415 -0.0319506 0.0309494 0.0125 -0.03092529999999999 0.0305247 0.013325 -0.02784939999999999 0.0309494 0.0158 -0.02887469999999999 0.0305247 0.01415 -0.02836209999999999 0.030737 0.01415 -0.02784939999999999 0.0309494 0.0125 -0.02784939999999999 0.0309494 0.0158 -0.02836209999999999 0.030737 0.01415 -0.02887469999999999 0.0305247 0.01415 -0.02784939999999999 0.0309494 0.0125 -0.02836209999999999 0.030737 0.01415 -0.02989999999999999 0.0301 0.0125 -0.02887469999999999 0.0305247 0.01415 -0.02938739999999999 0.0303124 0.01415 -0.02989999999999999 0.0301 0.0158 -0.02989999999999999 0.0301 0.0125 -0.02938739999999999 0.0303124 0.01415 -0.02887469999999999 0.0305247 0.01415 -0.02989999999999999 0.0301 0.0158 -0.02938739999999999 0.0303124 0.01415 -0.02699999999999999 0.033 0.0158 -0.02742469999999999 0.0319747 0.01415 -0.02721239999999999 0.0324873 0.01415 -0.02699999999999999 0.033 0.0125 -0.02699999999999999 0.033 0.0158 -0.02721239999999999 0.0324873 0.01415 -0.02742469999999999 0.0319747 0.01415 -0.02699999999999999 0.033 0.0125 -0.02721239999999999 0.0324873 0.01415 -0.02784939999999999 0.0309494 0.0125 -0.02742469999999999 0.0319747 0.01415 -0.02763699999999999 0.0314621 0.01415 -0.02784939999999999 0.0309494 0.0158 -0.02784939999999999 0.0309494 0.0125 -0.02763699999999999 0.0314621 0.01415 -0.02742469999999999 0.0319747 0.01415 -0.02784939999999999 0.0309494 0.0158 -0.02763699999999999 0.0314621 0.01415 -0.02784939999999999 0.0350506 0.0125 -0.02742469999999999 0.0340253 0.01415 -0.02742469999999999 0.0340253 0.013325 -0.02699999999999999 0.033 0.0125 -0.02784939999999999 0.0350506 0.0125 -0.02742469999999999 0.0340253 0.013325 -0.02742469999999999 0.0340253 0.01415 -0.02699999999999999 0.033 0.0125 -0.02742469999999999 0.0340253 0.013325 -0.02784939999999999 0.0350506 0.0125 -0.002899999999999993 0.0428 0.0125 -0.03869999999999999 0.0428 0.0125 -0.03869999999999999 0.0428 -0.0125 -0.02079999999999999 0.0428 0 -0.02079999999999999 0.0428 -0.00625 -0.002899999999999993 0.0428 -0.0125 -0.03869999999999999 0.0428 -0.0125 -0.02079999999999999 0.0428 -0.00625 -0.02079999999999999 0.0428 0 -0.002899999999999993 0.0428 -0.0125 -0.02079999999999999 0.0428 -0.00625 -0.002899999999999993 0.0428 0.0125 -0.02079999999999999 0.0428 0 -0.02079999999999999 0.0428 0.00625 -0.03869999999999999 0.0428 0.0125 -0.002899999999999993 0.0428 0.0125 -0.02079999999999999 0.0428 0.00625 -0.02079999999999999 0.0428 0 -0.03869999999999999 0.0428 0.0125 -0.02079999999999999 0.0428 0.00625 -0.02777869999999999 0.0351213 -0.0125 -0.03869999999999999 0.0428 -0.0125 -0.002899999999999993 0.0428 -0.0125 -0.02733929999999999 0.0340607 -0.01415 -0.02733929999999999 0.0340607 -0.013325 -0.02689999999999999 0.033 -0.0125 -0.02689999999999999 0.033 -0.0125 -0.02733929999999999 0.0340607 -0.013325 -0.02777869999999999 0.0351213 -0.0125 -0.02777869999999999 0.0351213 -0.0125 -0.02733929999999999 0.0340607 -0.013325 -0.02733929999999999 0.0340607 -0.01415 -0.02777869999999999 0.0308787 -0.0158 -0.02733929999999999 0.0319393 -0.01415 -0.02755899999999999 0.031409 -0.01415 -0.02777869999999999 0.0308787 -0.0125 -0.02777869999999999 0.0308787 -0.0158 -0.02755899999999999 0.031409 -0.01415 -0.02733929999999999 0.0319393 -0.01415 -0.02777869999999999 0.0308787 -0.0125 -0.02755899999999999 0.031409 -0.01415 -0.02689999999999999 0.033 -0.0125 -0.02733929999999999 0.0319393 -0.01415 -0.02711969999999999 0.0324697 -0.01415 -0.02689999999999999 0.033 -0.0158 -0.02689999999999999 0.033 -0.0125 -0.02711969999999999 0.0324697 -0.01415 -0.02733929999999999 0.0319393 -0.01415 -0.02689999999999999 0.033 -0.0158 -0.02711969999999999 0.0324697 -0.01415 -0.02989999999999999 0.03 -0.0158 -0.02883929999999999 0.0304393 -0.01415 -0.02936959999999999 0.0302196 -0.01415 -0.02989999999999999 0.03 -0.0125 -0.02989999999999999 0.03 -0.0158 -0.02936959999999999 0.0302196 -0.01415 -0.02883929999999999 0.0304393 -0.01415 -0.02989999999999999 0.03 -0.0125 -0.02936959999999999 0.0302196 -0.01415 -0.02777869999999999 0.0308787 -0.0125 -0.02883929999999999 0.0304393 -0.01415 -0.02830899999999999 0.030659 -0.01415 -0.02777869999999999 0.0308787 -0.0158 -0.02777869999999999 0.0308787 -0.0125 -0.02830899999999999 0.030659 -0.01415 -0.02883929999999999 0.0304393 -0.01415 -0.02777869999999999 0.0308787 -0.0158 -0.02830899999999999 0.030659 -0.01415 -0.0320213 0.0308787 -0.0125 -0.03096069999999999 0.0304393 -0.01415 -0.03096069999999999 0.0304393 -0.013325 -0.02989999999999999 0.03 -0.0125 -0.0320213 0.0308787 -0.0125 -0.03096069999999999 0.0304393 -0.013325 -0.03096069999999999 0.0304393 -0.01415 -0.02989999999999999 0.03 -0.0125 -0.03096069999999999 0.0304393 -0.013325 -0.03289999999999999 0.033 -0.0125 -0.0320213 0.0308787 -0.0125 -0.03869999999999999 0.022 -0.0125 0.003000000000000007 0.007 0 0.003000000000000007 0.0049497 0.0049497 0.009000000000000006 0.0059749 0.0024749 0.01500000000000001 0 0.007 0.009000000000000006 0.0024749 0.0059749 0.003000000000000007 0 0.007 0.009000000000000006 0.0024749 0.0059749 0.01500000000000001 0.0049497 0.0049497 0.003000000000000007 0.0049497 0.0049497 0.01500000000000001 -0.0049497 0.0049497 0.009000000000000006 -0.0024749 0.0059749 0.003000000000000007 -0.0049497 0.0049497 0.009000000000000006 -0.0024749 0.0059749 0.01500000000000001 0 0.007 0.003000000000000007 0 0.007 0.01500000000000001 -0.0049497 0.0049497 0.009000000000000006 -0.0059749 0.0024749 0.01500000000000001 -0.007 0 0.01500000000000001 -0.007 0 0.009000000000000006 -0.0059749 -0.0024749 0.01500000000000001 -0.0049497 -0.0049497 0.009000000000000006 -0.0024749 -0.0059749 0.01500000000000001 -0.0049497 -0.0049497 0.003000000000000007 -0.0049497 -0.0049497 0.01500000000000001 0 -0.007 0.009000000000000006 -0.0024749 -0.0059749 0.003000000000000007 0 -0.007 0.01500000000000001 0.0049497 -0.0049497 0.009000000000000006 0.0024749 -0.0059749 0.003000000000000007 0.0049497 -0.0049497 0.009000000000000006 0.0024749 -0.0059749 0.01500000000000001 0 -0.007 0.003000000000000007 0 -0.007 0.003000000000000007 0.007 0 0.009000000000000006 0.0059749 -0.0024749 0.003000000000000007 0.0049497 -0.0049497 -0.02989999999999999 -0.0359 -0.0158 -0.02989999999999999 -0.033 -0.0158 -0.02784939999999999 -0.0350506 -0.0158 -0.02989999999999999 -0.0359 -0.0125 -0.03092529999999999 -0.0354753 -0.01415 -0.03041259999999999 -0.0356876 -0.01415 -0.02989999999999999 -0.0359 -0.0158 -0.02989999999999999 -0.0359 -0.0125 -0.03041259999999999 -0.0356876 -0.01415 -0.03092529999999999 -0.0354753 -0.01415 -0.02989999999999999 -0.0359 -0.0158 -0.03041259999999999 -0.0356876 -0.01415 -0.0319506 -0.0350506 -0.0158 -0.03092529999999999 -0.0354753 -0.01415 -0.03143789999999999 -0.0352629 -0.01415 -0.0319506 -0.0350506 -0.0125 -0.0319506 -0.0350506 -0.0158 -0.03143789999999999 -0.0352629 -0.01415 -0.03092529999999999 -0.0354753 -0.01415 -0.0319506 -0.0350506 -0.0125 -0.03143789999999999 -0.0352629 -0.01415 -0.0328 -0.033 -0.0158 -0.0323753 -0.0340253 -0.01415 -0.03258759999999999 -0.0335127 -0.01415 -0.0328 -0.033 -0.0125 -0.0328 -0.033 -0.0158 -0.03258759999999999 -0.0335127 -0.01415 -0.0323753 -0.0340253 -0.01415 -0.0328 -0.033 -0.0125 -0.03258759999999999 -0.0335127 -0.01415 -0.0319506 -0.0350506 -0.0125 -0.0323753 -0.0340253 -0.01415 -0.03216289999999999 -0.0345379 -0.01415 -0.0319506 -0.0350506 -0.0158 -0.0319506 -0.0350506 -0.0125 -0.03216289999999999 -0.0345379 -0.01415 -0.0323753 -0.0340253 -0.01415 -0.0319506 -0.0350506 -0.0158 -0.03216289999999999 -0.0345379 -0.01415 -0.0328 -0.033 -0.0158 -0.0319506 -0.0309494 -0.0158 -0.02989999999999999 -0.033 -0.0158 -0.02989999999999999 -0.036 0.0158 -0.03096069999999999 -0.0355607 0.01415 -0.03043039999999999 -0.0357803 0.01415 -0.02989999999999999 -0.036 0.0125 -0.02989999999999999 -0.036 0.0158 -0.03043039999999999 -0.0357803 0.01415 -0.03096069999999999 -0.0355607 0.01415 -0.02989999999999999 -0.036 0.0125 -0.03043039999999999 -0.0357803 0.01415 -0.0320213 -0.0351213 0.0125 -0.03096069999999999 -0.0355607 0.01415 -0.03149099999999999 -0.035341 0.01415 -0.0320213 -0.0351213 0.0158 -0.0320213 -0.0351213 0.0125 -0.03149099999999999 -0.035341 0.01415 -0.03096069999999999 -0.0355607 0.01415 -0.0320213 -0.0351213 0.0158 -0.03149099999999999 -0.035341 0.01415 -0.02777869999999999 -0.0351213 0.0158 -0.02989999999999999 -0.033 0.0158 -0.02989999999999999 -0.036 0.0158 -0.02989999999999999 -0.033 0.0158 -0.0320213 -0.0308787 0.0158 -0.03289999999999999 -0.033 0.0158 -0.0320213 -0.0351213 0.0158 -0.0324607 -0.0340607 0.01415 -0.03224099999999999 -0.034591 0.01415 -0.0320213 -0.0351213 0.0125 -0.0320213 -0.0351213 0.0158 -0.03224099999999999 -0.034591 0.01415 -0.0324607 -0.0340607 0.01415 -0.0320213 -0.0351213 0.0125 -0.03224099999999999 -0.034591 0.01415 -0.03289999999999999 -0.033 0.0125 -0.0324607 -0.0340607 0.01415 -0.03268039999999999 -0.0335304 0.01415 -0.03289999999999999 -0.033 0.0158 -0.03289999999999999 -0.033 0.0125 -0.03268039999999999 -0.0335304 0.01415 -0.0324607 -0.0340607 0.01415 -0.03289999999999999 -0.033 0.0158 -0.03268039999999999 -0.0335304 0.01415 -0.03869999999999999 0.0428 -0.0125 -0.03869999999999999 0.0324 0 -0.03869999999999999 0.0376 -1.56125e-17 -0.03869999999999999 0.0428 0.0125 -0.03869999999999999 0.0428 -0.0125 -0.03869999999999999 0.0376 -1.56125e-17 -0.03869999999999999 0.0324 0 -0.03869999999999999 0.0428 0.0125 -0.03869999999999999 0.0376 -1.56125e-17 -0.0319506 0.0350506 0.0125 -0.03869999999999999 0.0428 0.0125 -0.03869999999999999 0.022 0.0125 -0.03869999999999999 0.0428 -0.0125 -0.0320213 0.0351213 -0.0125 -0.03869999999999999 0.022 -0.0125 -0.0328 0.033 0.0125 -0.0319506 0.0350506 0.0125 -0.03869999999999999 0.022 0.0125 -0.0319506 0.0309494 0.0125 -0.0323753 0.0319747 0.01415 -0.0323753 0.0319747 0.013325 -0.0328 0.033 0.0125 -0.0319506 0.0309494 0.0125 -0.0323753 0.0319747 0.013325 -0.0323753 0.0319747 0.01415 -0.0328 0.033 0.0125 -0.0323753 0.0319747 0.013325 -0.02989999999999999 0.0301 0.0158 -0.03092529999999999 0.0305247 0.01415 -0.03041259999999999 0.0303124 0.01415 -0.02989999999999999 0.0301 0.0125 -0.02989999999999999 0.0301 0.0158 -0.03041259999999999 0.0303124 0.01415 -0.03092529999999999 0.0305247 0.01415 -0.02989999999999999 0.0301 0.0125 -0.03041259999999999 0.0303124 0.01415 -0.0319506 0.0309494 0.0125 -0.03092529999999999 0.0305247 0.01415 -0.03143789999999999 0.030737 0.01415 -0.0319506 0.0309494 0.0158 -0.0319506 0.0309494 0.0125 -0.03143789999999999 0.030737 0.01415 -0.03092529999999999 0.0305247 0.01415 -0.0319506 0.0309494 0.0158 -0.03143789999999999 0.030737 0.01415 -0.02989999999999999 0.0301 0.0158 -0.02887469999999999 0.0305247 0.01415 -0.02887469999999999 0.0305247 0.014975 -0.02784939999999999 0.0309494 0.0158 -0.02989999999999999 0.0301 0.0158 -0.02887469999999999 0.0305247 0.014975 -0.02887469999999999 0.0305247 0.01415 -0.02784939999999999 0.0309494 0.0158 -0.02887469999999999 0.0305247 0.014975 -0.02784939999999999 0.0309494 0.0158 -0.02742469999999999 0.0319747 0.01415 -0.02742469999999999 0.0319747 0.014975 -0.02699999999999999 0.033 0.0158 -0.02784939999999999 0.0309494 0.0158 -0.02742469999999999 0.0319747 0.014975 -0.02742469999999999 0.0319747 0.01415 -0.02699999999999999 0.033 0.0158 -0.02742469999999999 0.0319747 0.014975 -0.02699999999999999 0.033 0.0125 -0.02742469999999999 0.0340253 0.01415 -0.02721239999999999 0.0335127 0.01415 -0.02699999999999999 0.033 0.0158 -0.02699999999999999 0.033 0.0125 -0.02721239999999999 0.0335127 0.01415 -0.02742469999999999 0.0340253 0.01415 -0.02699999999999999 0.033 0.0158 -0.02721239999999999 0.0335127 0.01415 -0.02784939999999999 0.0350506 0.0158 -0.02742469999999999 0.0340253 0.01415 -0.02763699999999999 0.0345379 0.01415 -0.02784939999999999 0.0350506 0.0125 -0.02784939999999999 0.0350506 0.0158 -0.02763699999999999 0.0345379 0.01415 -0.02742469999999999 0.0340253 0.01415 -0.02784939999999999 0.0350506 0.0125 -0.02763699999999999 0.0345379 0.01415 -0.02784939999999999 0.0350506 0.0125 -0.03869999999999999 0.0428 0.0125 -0.02989999999999999 0.0359 0.0125 -0.03869999999999999 0.0428 0.0125 -0.02079999999999999 0.0428 0 -0.02974999999999999 0.0428 6.07153e-18 -0.03869999999999999 0.0428 -0.0125 -0.03869999999999999 0.0428 0.0125 -0.02974999999999999 0.0428 6.07153e-18 -0.02079999999999999 0.0428 0 -0.03869999999999999 0.0428 -0.0125 -0.02974999999999999 0.0428 6.07153e-18 -0.02777869999999999 0.0351213 -0.0125 -0.02989999999999999 0.036 -0.0125 -0.03869999999999999 0.0428 -0.0125 -0.02689999999999999 0.033 -0.0158 -0.02733929999999999 0.0340607 -0.01415 -0.02711969999999999 0.0335304 -0.01415 -0.02689999999999999 0.033 -0.0125 -0.02689999999999999 0.033 -0.0158 -0.02711969999999999 0.0335304 -0.01415 -0.02733929999999999 0.0340607 -0.01415 -0.02689999999999999 0.033 -0.0125 -0.02711969999999999 0.0335304 -0.01415 -0.02777869999999999 0.0351213 -0.0125 -0.02733929999999999 0.0340607 -0.01415 -0.02755899999999999 0.034591 -0.01415 -0.02777869999999999 0.0351213 -0.0158 -0.02777869999999999 0.0351213 -0.0125 -0.02755899999999999 0.034591 -0.01415 -0.02733929999999999 0.0340607 -0.01415 -0.02777869999999999 0.0351213 -0.0158 -0.02755899999999999 0.034591 -0.01415 -0.02733929999999999 0.0319393 -0.01415 -0.02733929999999999 0.0319393 -0.014975 -0.02689999999999999 0.033 -0.0158 -0.02689999999999999 0.033 -0.0158 -0.02733929999999999 0.0319393 -0.014975 -0.02777869999999999 0.0308787 -0.0158 -0.02777869999999999 0.0308787 -0.0158 -0.02733929999999999 0.0319393 -0.014975 -0.02733929999999999 0.0319393 -0.01415 -0.02777869999999999 0.0308787 -0.0158 -0.02883929999999999 0.0304393 -0.01415 -0.02883929999999999 0.0304393 -0.014975 -0.02989999999999999 0.03 -0.0158 -0.02777869999999999 0.0308787 -0.0158 -0.02883929999999999 0.0304393 -0.014975 -0.02883929999999999 0.0304393 -0.01415 -0.02989999999999999 0.03 -0.0158 -0.02883929999999999 0.0304393 -0.014975 -0.02989999999999999 0.03 -0.0125 -0.03096069999999999 0.0304393 -0.01415 -0.03043039999999999 0.0302196 -0.01415 -0.02989999999999999 0.03 -0.0158 -0.02989999999999999 0.03 -0.0125 -0.03043039999999999 0.0302196 -0.01415 -0.03096069999999999 0.0304393 -0.01415 -0.02989999999999999 0.03 -0.0158 -0.03043039999999999 0.0302196 -0.01415 -0.0320213 0.0308787 -0.0158 -0.03096069999999999 0.0304393 -0.01415 -0.03149099999999999 0.030659 -0.01415 -0.0320213 0.0308787 -0.0125 -0.0320213 0.0308787 -0.0158 -0.03149099999999999 0.030659 -0.01415 -0.03096069999999999 0.0304393 -0.01415 -0.0320213 0.0308787 -0.0125 -0.03149099999999999 0.030659 -0.01415 -0.0324607 0.0319393 -0.01415 -0.0324607 0.0319393 -0.013325 -0.03289999999999999 0.033 -0.0125 -0.03289999999999999 0.033 -0.0125 -0.0324607 0.0319393 -0.013325 -0.0320213 0.0308787 -0.0125 -0.0320213 0.0308787 -0.0125 -0.0324607 0.0319393 -0.013325 -0.0324607 0.0319393 -0.01415 -0.03289999999999999 0.033 -0.0125 -0.03869999999999999 0.022 -0.0125 -0.0320213 0.0351213 -0.0125 0.009000000000000006 0.0059749 0.0024749 0.003000000000000007 0.0049497 0.0049497 0.01500000000000001 0.0049497 0.0049497 0.003000000000000007 0.007 0 0.009000000000000006 0.0059749 0.0024749 0.01500000000000001 0.007 0 0.01500000000000001 0 0.007 0.01500000000000001 0.0049497 0.0049497 0.009000000000000006 0.0024749 0.0059749 0.01500000000000001 -0.0049497 0.0049497 0.01500000000000001 0 0.007 0.009000000000000006 -0.0024749 0.0059749 0.01500000000000001 -0.0049497 0.0049497 0.01500000000000001 -0.007 0 0.01500000000000001 -0.0123744 -0.0123744 0.01500000000000001 -0.0049497 -0.0049497 0.01500000000000001 -0.0123744 -0.0123744 0.01500000000000001 -0.007 0 0.01500000000000001 0 -0.007 0.01500000000000001 -0.0049497 -0.0049497 0.009000000000000006 -0.0024749 -0.0059749 0.01500000000000001 0.0049497 -0.0049497 0.01500000000000001 0 -0.007 0.009000000000000006 0.0024749 -0.0059749 0.003000000000000007 0.0049497 -0.0049497 0.009000000000000006 0.0059749 -0.0024749 0.01500000000000001 0.0049497 -0.0049497 0.009000000000000006 0.0059749 -0.0024749 0.003000000000000007 0.007 0 0.01500000000000001 0.007 0 -0.0319506 -0.0350506 -0.0158 -0.02989999999999999 -0.033 -0.0158 -0.02989999999999999 -0.0359 -0.0158 -0.02989999999999999 -0.0359 -0.0158 -0.03092529999999999 -0.0354753 -0.01415 -0.03092529999999999 -0.0354753 -0.014975 -0.0319506 -0.0350506 -0.0158 -0.02989999999999999 -0.0359 -0.0158 -0.03092529999999999 -0.0354753 -0.014975 -0.03092529999999999 -0.0354753 -0.01415 -0.0319506 -0.0350506 -0.0158 -0.03092529999999999 -0.0354753 -0.014975 -0.0323753 -0.0340253 -0.01415 -0.0323753 -0.0340253 -0.014975 -0.0319506 -0.0350506 -0.0158 -0.0319506 -0.0350506 -0.0158 -0.0323753 -0.0340253 -0.014975 -0.0328 -0.033 -0.0158 -0.0328 -0.033 -0.0158 -0.0323753 -0.0340253 -0.014975 -0.0323753 -0.0340253 -0.01415 -0.0328 -0.033 -0.0158 -0.02989999999999999 -0.033 -0.0158 -0.0319506 -0.0350506 -0.0158 -0.03096069999999999 -0.0355607 0.01415 -0.03096069999999999 -0.0355607 0.014975 -0.0320213 -0.0351213 0.0158 -0.0320213 -0.0351213 0.0158 -0.03096069999999999 -0.0355607 0.014975 -0.02989999999999999 -0.036 0.0158 -0.02989999999999999 -0.036 0.0158 -0.03096069999999999 -0.0355607 0.014975 -0.03096069999999999 -0.0355607 0.01415 -0.02989999999999999 -0.036 0.0158 -0.02989999999999999 -0.033 0.0158 -0.0320213 -0.0351213 0.0158 -0.02989999999999999 -0.033 0.0158 -0.03289999999999999 -0.033 0.0158 -0.0320213 -0.0351213 0.0158 -0.0324607 -0.0340607 0.01415 -0.0324607 -0.0340607 0.014975 -0.03289999999999999 -0.033 0.0158 -0.03289999999999999 -0.033 0.0158 -0.0324607 -0.0340607 0.014975 -0.0320213 -0.0351213 0.0158 -0.0320213 -0.0351213 0.0158 -0.0324607 -0.0340607 0.014975 -0.0324607 -0.0340607 0.01415 -0.02989999999999999 0.0359 0.0125 -0.03869999999999999 0.0428 0.0125 -0.0319506 0.0350506 0.0125 -0.0320213 0.0351213 -0.0125 -0.03869999999999999 0.0428 -0.0125 -0.02989999999999999 0.036 -0.0125 -0.0328 0.033 0.0125 -0.0323753 0.0340253 0.01415 -0.0323753 0.0340253 0.013325 -0.0319506 0.0350506 0.0125 -0.0328 0.033 0.0125 -0.0323753 0.0340253 0.013325 -0.0323753 0.0340253 0.01415 -0.0319506 0.0350506 0.0125 -0.0323753 0.0340253 0.013325 -0.0319506 0.0309494 0.0158 -0.0323753 0.0319747 0.01415 -0.03216289999999999 0.0314621 0.01415 -0.0319506 0.0309494 0.0125 -0.0319506 0.0309494 0.0158 -0.03216289999999999 0.0314621 0.01415 -0.0323753 0.0319747 0.01415 -0.0319506 0.0309494 0.0125 -0.03216289999999999 0.0314621 0.01415 -0.0328 0.033 0.0125 -0.0323753 0.0319747 0.01415 -0.03258759999999999 0.0324873 0.01415 -0.0328 0.033 0.0158 -0.0328 0.033 0.0125 -0.03258759999999999 0.0324873 0.01415 -0.0323753 0.0319747 0.01415 -0.0328 0.033 0.0158 -0.03258759999999999 0.0324873 0.01415 -0.0319506 0.0309494 0.0158 -0.03092529999999999 0.0305247 0.01415 -0.03092529999999999 0.0305247 0.014975 -0.02989999999999999 0.0301 0.0158 -0.0319506 0.0309494 0.0158 -0.03092529999999999 0.0305247 0.014975 -0.03092529999999999 0.0305247 0.01415 -0.02989999999999999 0.0301 0.0158 -0.03092529999999999 0.0305247 0.014975 -0.02784939999999999 0.0309494 0.0158 -0.02989999999999999 0.033 0.0158 -0.02989999999999999 0.0301 0.0158 -0.02784939999999999 0.0309494 0.0158 -0.02699999999999999 0.033 0.0158 -0.02989999999999999 0.033 0.0158 -0.02699999999999999 0.033 0.0158 -0.02742469999999999 0.0340253 0.01415 -0.02742469999999999 0.0340253 0.014975 -0.02784939999999999 0.0350506 0.0158 -0.02699999999999999 0.033 0.0158 -0.02742469999999999 0.0340253 0.014975 -0.02742469999999999 0.0340253 0.01415 -0.02784939999999999 0.0350506 0.0158 -0.02742469999999999 0.0340253 0.014975 -0.02784939999999999 0.0350506 0.0125 -0.02887469999999999 0.0354753 0.01415 -0.02836209999999999 0.0352629 0.01415 -0.02784939999999999 0.0350506 0.0158 -0.02784939999999999 0.0350506 0.0125 -0.02836209999999999 0.0352629 0.01415 -0.02887469999999999 0.0354753 0.01415 -0.02784939999999999 0.0350506 0.0158 -0.02836209999999999 0.0352629 0.01415 -0.02887469999999999 0.0354753 0.01415 -0.02887469999999999 0.0354753 0.013325 -0.02989999999999999 0.0359 0.0125 -0.02989999999999999 0.0359 0.0125 -0.02887469999999999 0.0354753 0.013325 -0.02784939999999999 0.0350506 0.0125 -0.02784939999999999 0.0350506 0.0125 -0.02887469999999999 0.0354753 0.013325 -0.02887469999999999 0.0354753 0.01415 -0.02777869999999999 0.0351213 -0.0125 -0.02883929999999999 0.0355607 -0.01415 -0.02883929999999999 0.0355607 -0.013325 -0.02989999999999999 0.036 -0.0125 -0.02777869999999999 0.0351213 -0.0125 -0.02883929999999999 0.0355607 -0.013325 -0.02883929999999999 0.0355607 -0.01415 -0.02989999999999999 0.036 -0.0125 -0.02883929999999999 0.0355607 -0.013325 -0.02777869999999999 0.0351213 -0.0158 -0.02733929999999999 0.0340607 -0.01415 -0.02733929999999999 0.0340607 -0.014975 -0.02689999999999999 0.033 -0.0158 -0.02777869999999999 0.0351213 -0.0158 -0.02733929999999999 0.0340607 -0.014975 -0.02733929999999999 0.0340607 -0.01415 -0.02689999999999999 0.033 -0.0158 -0.02733929999999999 0.0340607 -0.014975 -0.02777869999999999 0.0351213 -0.0158 -0.02883929999999999 0.0355607 -0.01415 -0.02830899999999999 0.035341 -0.01415 -0.02777869999999999 0.0351213 -0.0125 -0.02777869999999999 0.0351213 -0.0158 -0.02830899999999999 0.035341 -0.01415 -0.02883929999999999 0.0355607 -0.01415 -0.02777869999999999 0.0351213 -0.0125 -0.02830899999999999 0.035341 -0.01415 -0.02989999999999999 0.033 -0.0158 -0.02689999999999999 0.033 -0.0158 -0.02777869999999999 0.0308787 -0.0158 -0.02989999999999999 0.03 -0.0158 -0.02989999999999999 0.033 -0.0158 -0.02777869999999999 0.0308787 -0.0158 -0.02989999999999999 0.03 -0.0158 -0.03096069999999999 0.0304393 -0.01415 -0.03096069999999999 0.0304393 -0.014975 -0.0320213 0.0308787 -0.0158 -0.02989999999999999 0.03 -0.0158 -0.03096069999999999 0.0304393 -0.014975 -0.03096069999999999 0.0304393 -0.01415 -0.0320213 0.0308787 -0.0158 -0.03096069999999999 0.0304393 -0.014975 -0.0320213 0.0308787 -0.0125 -0.0324607 0.0319393 -0.01415 -0.03224099999999999 0.031409 -0.01415 -0.0320213 0.0308787 -0.0158 -0.0320213 0.0308787 -0.0125 -0.03224099999999999 0.031409 -0.01415 -0.0324607 0.0319393 -0.01415 -0.0320213 0.0308787 -0.0158 -0.03224099999999999 0.031409 -0.01415 -0.03289999999999999 0.033 -0.0158 -0.0324607 0.0319393 -0.01415 -0.03268039999999999 0.0324697 -0.01415 -0.03289999999999999 0.033 -0.0125 -0.03289999999999999 0.033 -0.0158 -0.03268039999999999 0.0324697 -0.01415 -0.0324607 0.0319393 -0.01415 -0.03289999999999999 0.033 -0.0125 -0.03268039999999999 0.0324697 -0.01415 -0.0324607 0.0340607 -0.01415 -0.0324607 0.0340607 -0.013325 -0.0320213 0.0351213 -0.0125 -0.0320213 0.0351213 -0.0125 -0.0324607 0.0340607 -0.013325 -0.03289999999999999 0.033 -0.0125 -0.03289999999999999 0.033 -0.0125 -0.0324607 0.0340607 -0.013325 -0.0324607 0.0340607 -0.01415 0.01500000000000001 0.007 0 0.009000000000000006 0.0059749 0.0024749 0.01500000000000001 0.0049497 0.0049497 0.01500000000000001 0.0049497 0.0049497 0.01500000000000001 0 0.007 0.01500000000000001 0.0123744 0.0123744 0.01500000000000001 -0.0049497 0.0049497 0.01500000000000001 0.0123744 0.0123744 0.01500000000000001 0 0.007 0.01500000000000001 -0.0123744 -0.0123744 0.01500000000000001 -0.0175 0 0.01500000000000001 -0.0049497 0.0049497 0.01500000000000001 -0.0123744 -0.0123744 0.01500000000000001 -0.0049497 -0.0049497 0.01500000000000001 0 -0.007 0.01500000000000001 0 -0.0175 0.01500000000000001 0 -0.007 0.01500000000000001 0.0049497 -0.0049497 0.01500000000000001 0.0049497 -0.0049497 0.009000000000000006 0.0059749 -0.0024749 0.01500000000000001 0.007 0 -0.03092529999999999 0.0354753 0.01415 -0.03092529999999999 0.0354753 0.013325 -0.0319506 0.0350506 0.0125 -0.0319506 0.0350506 0.0125 -0.03092529999999999 0.0354753 0.013325 -0.02989999999999999 0.0359 0.0125 -0.02989999999999999 0.0359 0.0125 -0.03092529999999999 0.0354753 0.013325 -0.03092529999999999 0.0354753 0.01415 -0.02989999999999999 0.036 -0.0125 -0.03096069999999999 0.0355607 -0.01415 -0.03096069999999999 0.0355607 -0.013325 -0.0320213 0.0351213 -0.0125 -0.02989999999999999 0.036 -0.0125 -0.03096069999999999 0.0355607 -0.013325 -0.03096069999999999 0.0355607 -0.01415 -0.0320213 0.0351213 -0.0125 -0.03096069999999999 0.0355607 -0.013325 -0.0328 0.033 0.0158 -0.0323753 0.0340253 0.01415 -0.03258759999999999 0.0335127 0.01415 -0.0328 0.033 0.0125 -0.0328 0.033 0.0158 -0.03258759999999999 0.0335127 0.01415 -0.0323753 0.0340253 0.01415 -0.0328 0.033 0.0125 -0.03258759999999999 0.0335127 0.01415 -0.0319506 0.0350506 0.0125 -0.0323753 0.0340253 0.01415 -0.03216289999999999 0.0345379 0.01415 -0.0319506 0.0350506 0.0158 -0.0319506 0.0350506 0.0125 -0.03216289999999999 0.0345379 0.01415 -0.0323753 0.0340253 0.01415 -0.0319506 0.0350506 0.0158 -0.03216289999999999 0.0345379 0.01415 -0.0323753 0.0319747 0.01415 -0.0323753 0.0319747 0.014975 -0.0328 0.033 0.0158 -0.0328 0.033 0.0158 -0.0323753 0.0319747 0.014975 -0.0319506 0.0309494 0.0158 -0.0319506 0.0309494 0.0158 -0.0323753 0.0319747 0.014975 -0.0323753 0.0319747 0.01415 -0.02989999999999999 0.0301 0.0158 -0.02989999999999999 0.033 0.0158 -0.0319506 0.0309494 0.0158 -0.02699999999999999 0.033 0.0158 -0.02784939999999999 0.0350506 0.0158 -0.02989999999999999 0.033 0.0158 -0.02784939999999999 0.0350506 0.0158 -0.02887469999999999 0.0354753 0.01415 -0.02887469999999999 0.0354753 0.014975 -0.02989999999999999 0.0359 0.0158 -0.02784939999999999 0.0350506 0.0158 -0.02887469999999999 0.0354753 0.014975 -0.02887469999999999 0.0354753 0.01415 -0.02989999999999999 0.0359 0.0158 -0.02887469999999999 0.0354753 0.014975 -0.02989999999999999 0.0359 0.0158 -0.02887469999999999 0.0354753 0.01415 -0.02938739999999999 0.0356876 0.01415 -0.02989999999999999 0.0359 0.0125 -0.02989999999999999 0.0359 0.0158 -0.02938739999999999 0.0356876 0.01415 -0.02887469999999999 0.0354753 0.01415 -0.02989999999999999 0.0359 0.0125 -0.02938739999999999 0.0356876 0.01415 -0.02989999999999999 0.036 -0.0125 -0.02883929999999999 0.0355607 -0.01415 -0.02936959999999999 0.0357803 -0.01415 -0.02989999999999999 0.036 -0.0158 -0.02989999999999999 0.036 -0.0125 -0.02936959999999999 0.0357803 -0.01415 -0.02883929999999999 0.0355607 -0.01415 -0.02989999999999999 0.036 -0.0158 -0.02936959999999999 0.0357803 -0.01415 -0.02989999999999999 0.033 -0.0158 -0.02777869999999999 0.0351213 -0.0158 -0.02689999999999999 0.033 -0.0158 -0.02883929999999999 0.0355607 -0.01415 -0.02883929999999999 0.0355607 -0.014975 -0.02989999999999999 0.036 -0.0158 -0.02989999999999999 0.036 -0.0158 -0.02883929999999999 0.0355607 -0.014975 -0.02777869999999999 0.0351213 -0.0158 -0.02777869999999999 0.0351213 -0.0158 -0.02883929999999999 0.0355607 -0.014975 -0.02883929999999999 0.0355607 -0.01415 -0.0320213 0.0308787 -0.0158 -0.02989999999999999 0.033 -0.0158 -0.02989999999999999 0.03 -0.0158 -0.0324607 0.0319393 -0.01415 -0.0324607 0.0319393 -0.014975 -0.0320213 0.0308787 -0.0158 -0.0320213 0.0308787 -0.0158 -0.0324607 0.0319393 -0.014975 -0.03289999999999999 0.033 -0.0158 -0.03289999999999999 0.033 -0.0158 -0.0324607 0.0319393 -0.014975 -0.0324607 0.0319393 -0.01415 -0.03289999999999999 0.033 -0.0125 -0.0324607 0.0340607 -0.01415 -0.03268039999999999 0.0335304 -0.01415 -0.03289999999999999 0.033 -0.0158 -0.03289999999999999 0.033 -0.0125 -0.03268039999999999 0.0335304 -0.01415 -0.0324607 0.0340607 -0.01415 -0.03289999999999999 0.033 -0.0158 -0.03268039999999999 0.0335304 -0.01415 -0.0320213 0.0351213 -0.0158 -0.0324607 0.0340607 -0.01415 -0.03224099999999999 0.034591 -0.01415 -0.0320213 0.0351213 -0.0125 -0.0320213 0.0351213 -0.0158 -0.03224099999999999 0.034591 -0.01415 -0.0324607 0.0340607 -0.01415 -0.0320213 0.0351213 -0.0125 -0.03224099999999999 0.034591 -0.01415 0.01500000000000001 0.007 0 0.01500000000000001 0.0049497 0.0049497 0.01500000000000001 0.0175 0 0.01500000000000001 0.0049497 0.0049497 0.01500000000000001 0.0123744 0.0123744 0.01500000000000001 0.0112249 0.0061872 0.01500000000000001 0.0175 0 0.01500000000000001 0.0049497 0.0049497 0.01500000000000001 0.0112249 0.0061872 0.01500000000000001 0.0123744 0.0123744 0.01500000000000001 0.0175 0 0.01500000000000001 0.0112249 0.0061872 0.01500000000000001 -0.0175 0 0.01500000000000001 0.0123744 0.0123744 0.01500000000000001 -0.0049497 0.0049497 0.01625000000000001 -0.0149372 -0.0061872 0.01500000000000001 -0.0175 0 0.01500000000000001 -0.0123744 -0.0123744 0.01500000000000001 0 -0.0175 0.01500000000000001 -0.0123744 -0.0123744 0.01500000000000001 0 -0.007 0.01500000000000001 0 -0.0175 0.01500000000000001 0.0049497 -0.0049497 0.01500000000000001 0.0175 0 0.01500000000000001 0.0049497 -0.0049497 0.01500000000000001 0.007 0 0.01500000000000001 0.0175 0 -0.0319506 0.0350506 0.0158 -0.03092529999999999 0.0354753 0.01415 -0.03143789999999999 0.0352629 0.01415 -0.0319506 0.0350506 0.0125 -0.0319506 0.0350506 0.0158 -0.03143789999999999 0.0352629 0.01415 -0.03092529999999999 0.0354753 0.01415 -0.0319506 0.0350506 0.0125 -0.03143789999999999 0.0352629 0.01415 -0.02989999999999999 0.0359 0.0125 -0.03092529999999999 0.0354753 0.01415 -0.03041259999999999 0.0356876 0.01415 -0.02989999999999999 0.0359 0.0158 -0.02989999999999999 0.0359 0.0125 -0.03041259999999999 0.0356876 0.01415 -0.03092529999999999 0.0354753 0.01415 -0.02989999999999999 0.0359 0.0158 -0.03041259999999999 0.0356876 0.01415 -0.02989999999999999 0.036 -0.0158 -0.03096069999999999 0.0355607 -0.01415 -0.03043039999999999 0.0357803 -0.01415 -0.02989999999999999 0.036 -0.0125 -0.02989999999999999 0.036 -0.0158 -0.03043039999999999 0.0357803 -0.01415 -0.03096069999999999 0.0355607 -0.01415 -0.02989999999999999 0.036 -0.0125 -0.03043039999999999 0.0357803 -0.01415 -0.0320213 0.0351213 -0.0125 -0.03096069999999999 0.0355607 -0.01415 -0.03149099999999999 0.035341 -0.01415 -0.0320213 0.0351213 -0.0158 -0.0320213 0.0351213 -0.0125 -0.03149099999999999 0.035341 -0.01415 -0.03096069999999999 0.0355607 -0.01415 -0.0320213 0.0351213 -0.0158 -0.03149099999999999 0.035341 -0.01415 -0.0323753 0.0340253 0.01415 -0.0323753 0.0340253 0.014975 -0.0319506 0.0350506 0.0158 -0.0319506 0.0350506 0.0158 -0.0323753 0.0340253 0.014975 -0.0328 0.033 0.0158 -0.0328 0.033 0.0158 -0.0323753 0.0340253 0.014975 -0.0323753 0.0340253 0.01415 -0.02989999999999999 0.033 0.0158 -0.0328 0.033 0.0158 -0.0319506 0.0309494 0.0158 -0.02784939999999999 0.0350506 0.0158 -0.02989999999999999 0.0359 0.0158 -0.02989999999999999 0.033 0.0158 -0.02989999999999999 0.033 -0.0158 -0.02989999999999999 0.036 -0.0158 -0.02777869999999999 0.0351213 -0.0158 -0.0320213 0.0308787 -0.0158 -0.03289999999999999 0.033 -0.0158 -0.02989999999999999 0.033 -0.0158 -0.0324607 0.0340607 -0.01415 -0.0324607 0.0340607 -0.014975 -0.03289999999999999 0.033 -0.0158 -0.03289999999999999 0.033 -0.0158 -0.0324607 0.0340607 -0.014975 -0.0320213 0.0351213 -0.0158 -0.0320213 0.0351213 -0.0158 -0.0324607 0.0340607 -0.014975 -0.0324607 0.0340607 -0.01415 0.01625000000000001 0.0149372 0.0061872 0.01500000000000001 0.0175 0 0.01500000000000001 0.0123744 0.0123744 0.01500000000000001 -0.0175 0 0.01500000000000001 0 0.0175 0.01500000000000001 0.0123744 0.0123744 0.01625000000000001 -0.0149372 -0.0061872 0.01500000000000001 -0.0123744 -0.0123744 0.01750000000000001 -0.0123744 -0.0123744 0.01750000000000001 -0.0175 0 0.01500000000000001 -0.0175 0 0.01625000000000001 -0.0149372 -0.0061872 0.01625000000000001 -0.0061872 -0.0149372 0.01500000000000001 -0.0123744 -0.0123744 0.01500000000000001 0 -0.0175 0.01500000000000001 0.0123744 -0.0123744 0.01500000000000001 0 -0.0175 0.01500000000000001 0.0175 0 -0.02989999999999999 0.0359 0.0158 -0.03092529999999999 0.0354753 0.01415 -0.03092529999999999 0.0354753 0.014975 -0.0319506 0.0350506 0.0158 -0.02989999999999999 0.0359 0.0158 -0.03092529999999999 0.0354753 0.014975 -0.03092529999999999 0.0354753 0.01415 -0.0319506 0.0350506 0.0158 -0.03092529999999999 0.0354753 0.014975 -0.03096069999999999 0.0355607 -0.01415 -0.03096069999999999 0.0355607 -0.014975 -0.0320213 0.0351213 -0.0158 -0.0320213 0.0351213 -0.0158 -0.03096069999999999 0.0355607 -0.014975 -0.02989999999999999 0.036 -0.0158 -0.02989999999999999 0.036 -0.0158 -0.03096069999999999 0.0355607 -0.014975 -0.03096069999999999 0.0355607 -0.01415 -0.02989999999999999 0.033 0.0158 -0.0319506 0.0350506 0.0158 -0.0328 0.033 0.0158 -0.02989999999999999 0.0359 0.0158 -0.0319506 0.0350506 0.0158 -0.02989999999999999 0.033 0.0158 -0.0320213 0.0351213 -0.0158 -0.02989999999999999 0.036 -0.0158 -0.02989999999999999 0.033 -0.0158 -0.03289999999999999 0.033 -0.0158 -0.0320213 0.0351213 -0.0158 -0.02989999999999999 0.033 -0.0158 0.01625000000000001 0.0149372 0.0061872 0.01500000000000001 0.0123744 0.0123744 0.01750000000000001 0.0123744 0.0123744 0.01750000000000001 0.0175 0 0.01500000000000001 0.0175 0 0.01625000000000001 0.0149372 0.0061872 0.01500000000000001 -0.0175 0 0.01500000000000001 -0.0123744 0.0123744 0.01500000000000001 0 0.0175 0.01625000000000001 0.0061872 0.0149372 0.01500000000000001 0.0123744 0.0123744 0.01500000000000001 0 0.0175 0.01625000000000001 -0.0149372 -0.0061872 0.01750000000000001 -0.0123744 -0.0123744 0.01750000000000001 -0.0175 0 0.01625000000000001 -0.0061872 -0.0149372 0.01750000000000001 -0.0123744 -0.0123744 0.01500000000000001 -0.0123744 -0.0123744 0.01625000000000001 -0.0149372 0.0061872 0.01500000000000001 -0.0175 0 0.01750000000000001 -0.0175 0 0.01500000000000001 0 -0.0175 0.01750000000000001 0 -0.0175 0.01625000000000001 -0.0061872 -0.0149372 0.01625000000000001 0.0061872 -0.0149372 0.01500000000000001 0 -0.0175 0.01500000000000001 0.0123744 -0.0123744 0.01625000000000001 0.0149372 -0.0061872 0.01500000000000001 0.0123744 -0.0123744 0.01500000000000001 0.0175 0 0.01625000000000001 0.0149372 0.0061872 0.01750000000000001 0.0123744 0.0123744 0.01750000000000001 0.0175 0 0.01625000000000001 0.0061872 0.0149372 0.01750000000000001 0.0123744 0.0123744 0.01500000000000001 0.0123744 0.0123744 0.01625000000000001 0.0149372 -0.0061872 0.01500000000000001 0.0175 0 0.01750000000000001 0.0175 0 0.01625000000000001 -0.0149372 0.0061872 0.01500000000000001 -0.0123744 0.0123744 0.01500000000000001 -0.0175 0 0.01625000000000001 -0.0061872 0.0149372 0.01500000000000001 0 0.0175 0.01500000000000001 -0.0123744 0.0123744 0.01500000000000001 0 0.0175 0.01750000000000001 0 0.0175 0.01625000000000001 0.0061872 0.0149372 0.01750000000000001 -0.012 0 0.01750000000000001 -0.0175 0 0.01750000000000001 -0.0123744 -0.0123744 0.01625000000000001 -0.0061872 -0.0149372 0.01750000000000001 0 -0.0175 0.01750000000000001 -0.0123744 -0.0123744 0.01625000000000001 -0.0149372 0.0061872 0.01750000000000001 -0.0175 0 0.01750000000000001 -0.0123744 0.0123744 0.01625000000000001 0.0061872 -0.0149372 0.01750000000000001 0 -0.0175 0.01500000000000001 0 -0.0175 0.01500000000000001 0.0123744 -0.0123744 0.01750000000000001 0.0123744 -0.0123744 0.01625000000000001 0.0061872 -0.0149372 0.01750000000000001 0.0123744 -0.0123744 0.01500000000000001 0.0123744 -0.0123744 0.01625000000000001 0.0149372 -0.0061872 0.01750000000000001 0.0123744 0.0123744 0.01750000000000001 0.008485299999999999 0.008485299999999999 0.01750000000000001 0.0175 0 0.01625000000000001 0.0061872 0.0149372 0.01750000000000001 0 0.0175 0.01750000000000001 0.0123744 0.0123744 0.01625000000000001 0.0149372 -0.0061872 0.01750000000000001 0.0175 0 0.01750000000000001 0.0123744 -0.0123744 0.01750000000000001 -0.0123744 0.0123744 0.01500000000000001 -0.0123744 0.0123744 0.01625000000000001 -0.0149372 0.0061872 0.01500000000000001 -0.0123744 0.0123744 0.01750000000000001 -0.0123744 0.0123744 0.01625000000000001 -0.0061872 0.0149372 0.01625000000000001 -0.0061872 0.0149372 0.01750000000000001 0 0.0175 0.01500000000000001 0 0.0175 0.01750000000000001 -0.008485299999999999 0.008485299999999999 0.01750000000000001 -0.0175 0 0.01750000000000001 -0.012 0 0.01750000000000001 -0.008485299999999999 -0.008485299999999999 0.01750000000000001 -0.012 0 0.01750000000000001 -0.0123744 -0.0123744 0.01750000000000001 0 -0.012 0.01750000000000001 -0.0123744 -0.0123744 0.01750000000000001 0 -0.0175 0.01750000000000001 0 0.0175 0.01750000000000001 -0.0123744 0.0123744 0.01750000000000001 -0.0175 0 0.01625000000000001 0.0061872 -0.0149372 0.01750000000000001 0.0123744 -0.0123744 0.01750000000000001 0 -0.0175 0.01750000000000001 0.008485299999999999 0.008485299999999999 0.01750000000000001 0.012 0 0.01750000000000001 0.0175 0 0.01750000000000001 0 0.012 0.01750000000000001 0.008485299999999999 0.008485299999999999 0.01750000000000001 0.0123744 0.0123744 0.01750000000000001 0 0.0175 0.01750000000000001 0 0.012 0.01750000000000001 0.0123744 0.0123744 0.01750000000000001 0.0175 0 0.01750000000000001 0.008485299999999999 -0.008485299999999999 0.01750000000000001 0.0123744 -0.0123744 0.01625000000000001 -0.0061872 0.0149372 0.01750000000000001 -0.0123744 0.0123744 0.01750000000000001 0 0.0175 0.01925000000000001 -0.0102426 0.0042426 0.01750000000000001 -0.008485299999999999 0.008485299999999999 0.01750000000000001 -0.012 0 0.01750000000000001 0 0.0175 0.01750000000000001 -0.0175 0 0.01750000000000001 -0.008485299999999999 0.008485299999999999 0.01925000000000001 -0.0102426 -0.0042426 0.01750000000000001 -0.012 0 0.01750000000000001 -0.008485299999999999 -0.008485299999999999 0.01750000000000001 -0.008485299999999999 -0.008485299999999999 0.01750000000000001 -0.0123744 -0.0123744 0.01750000000000001 0 -0.012 0.01750000000000001 0.008485299999999999 -0.008485299999999999 0.01750000000000001 0 -0.012 0.01750000000000001 0 -0.0175 0.01750000000000001 0.008485299999999999 -0.008485299999999999 0.01750000000000001 0 -0.0175 0.01750000000000001 0.0123744 -0.0123744 0.01750000000000001 0.012 0 0.01750000000000001 0.008485299999999999 -0.008485299999999999 0.01750000000000001 0.0175 0 0.01925000000000001 0.0102426 0.0042426 0.01750000000000001 0.012 0 0.01750000000000001 0.008485299999999999 0.008485299999999999 0.01925000000000001 0.0042426 0.0102426 0.01750000000000001 0.008485299999999999 0.008485299999999999 0.01750000000000001 0 0.012 0.01750000000000001 0 0.0175 0.01750000000000001 -0.008485299999999999 0.008485299999999999 0.01750000000000001 0 0.012 0.01925000000000001 -0.0102426 0.0042426 0.01750000000000001 -0.012 0 0.02100000000000001 -0.012 0 0.02100000000000001 -0.008485299999999999 0.008485299999999999 0.01750000000000001 -0.008485299999999999 0.008485299999999999 0.01925000000000001 -0.0102426 0.0042426 0.01925000000000001 -0.0102426 -0.0042426 0.01750000000000001 -0.008485299999999999 -0.008485299999999999 0.02100000000000001 -0.008485299999999999 -0.008485299999999999 0.02100000000000001 -0.012 0 0.01750000000000001 -0.012 0 0.01925000000000001 -0.0102426 -0.0042426 0.01925000000000001 -0.0042426 -0.0102426 0.01750000000000001 -0.008485299999999999 -0.008485299999999999 0.01750000000000001 0 -0.012 0.01925000000000001 0.0042426 -0.0102426 0.01750000000000001 0 -0.012 0.01750000000000001 0.008485299999999999 -0.008485299999999999 0.01925000000000001 0.0102426 -0.0042426 0.01750000000000001 0.008485299999999999 -0.008485299999999999 0.01750000000000001 0.012 0 0.01925000000000001 0.0102426 0.0042426 0.01750000000000001 0.008485299999999999 0.008485299999999999 0.02100000000000001 0.008485299999999999 0.008485299999999999 0.02100000000000001 0.012 0 0.01750000000000001 0.012 0 0.01925000000000001 0.0102426 0.0042426 0.01750000000000001 0 0.012 0.02100000000000001 0 0.012 0.01925000000000001 0.0042426 0.0102426 0.01925000000000001 0.0042426 0.0102426 0.02100000000000001 0.008485299999999999 0.008485299999999999 0.01750000000000001 0.008485299999999999 0.008485299999999999 0.01925000000000001 -0.0042426 0.0102426 0.01750000000000001 0 0.012 0.01750000000000001 -0.008485299999999999 0.008485299999999999 0.01925000000000001 -0.0102426 0.0042426 0.02100000000000001 -0.012 0 0.02100000000000001 -0.008485299999999999 0.008485299999999999 0.01750000000000001 -0.008485299999999999 0.008485299999999999 0.02100000000000001 -0.008485299999999999 0.008485299999999999 0.01925000000000001 -0.0042426 0.0102426 0.01925000000000001 -0.0102426 -0.0042426 0.02100000000000001 -0.008485299999999999 -0.008485299999999999 0.02100000000000001 -0.012 0 0.01925000000000001 -0.0042426 -0.0102426 0.02100000000000001 -0.008485299999999999 -0.008485299999999999 0.01750000000000001 -0.008485299999999999 -0.008485299999999999 0.01750000000000001 0 -0.012 0.02100000000000001 0 -0.012 0.01925000000000001 -0.0042426 -0.0102426 0.01750000000000001 0.008485299999999999 -0.008485299999999999 0.02100000000000001 0.008485299999999999 -0.008485299999999999 0.01925000000000001 0.0042426 -0.0102426 0.01925000000000001 0.0042426 -0.0102426 0.02100000000000001 0 -0.012 0.01750000000000001 0 -0.012 0.01925000000000001 0.0102426 -0.0042426 0.01750000000000001 0.012 0 0.02100000000000001 0.012 0 0.02100000000000001 0.008485299999999999 -0.008485299999999999 0.01750000000000001 0.008485299999999999 -0.008485299999999999 0.01925000000000001 0.0102426 -0.0042426 0.01925000000000001 0.0102426 0.0042426 0.02100000000000001 0.008485299999999999 0.008485299999999999 0.02100000000000001 0.012 0 0.01925000000000001 0.0042426 0.0102426 0.02100000000000001 0 0.012 0.02100000000000001 0.008485299999999999 0.008485299999999999 0.01925000000000001 -0.0042426 0.0102426 0.02100000000000001 0 0.012 0.01750000000000001 0 0.012 0.02100000000000001 -0.0070711 0.0070711 0.02100000000000001 -0.008485299999999999 0.008485299999999999 0.02100000000000001 -0.012 0 0.01925000000000001 -0.0042426 0.0102426 0.02100000000000001 -0.008485299999999999 0.008485299999999999 0.02100000000000001 0 0.012 0.02100000000000001 -0.01 0 0.02100000000000001 -0.012 0 0.02100000000000001 -0.008485299999999999 -0.008485299999999999 0.01925000000000001 -0.0042426 -0.0102426 0.02100000000000001 0 -0.012 0.02100000000000001 -0.008485299999999999 -0.008485299999999999 0.01925000000000001 0.0042426 -0.0102426 0.02100000000000001 0.008485299999999999 -0.008485299999999999 0.02100000000000001 0 -0.012 0.01925000000000001 0.0102426 -0.0042426 0.02100000000000001 0.012 0 0.02100000000000001 0.008485299999999999 -0.008485299999999999 0.02100000000000001 0.008485299999999999 0.008485299999999999 0.02100000000000001 0.0070711 0.0070711 0.02100000000000001 0.012 0 0.02100000000000001 0 0.012 0.02100000000000001 0 0.01 0.02100000000000001 0.008485299999999999 0.008485299999999999 0.02100000000000001 -0.008485299999999999 0.008485299999999999 0.02100000000000001 -0.0070711 0.0070711 0.02100000000000001 0 0.012 0.02100000000000001 -0.0070711 0.0070711 0.02100000000000001 -0.012 0 0.02100000000000001 -0.01 0 0.02100000000000001 -0.0070711 -0.0070711 0.02100000000000001 -0.01 0 0.02100000000000001 -0.008485299999999999 -0.008485299999999999 0.02100000000000001 0 -0.01 0.02100000000000001 -0.008485299999999999 -0.008485299999999999 0.02100000000000001 0 -0.012 0.02100000000000001 0.0070711 -0.0070711 0.02100000000000001 0 -0.012 0.02100000000000001 0.008485299999999999 -0.008485299999999999 0.02100000000000001 0.012 0 0.02100000000000001 0.0070711 -0.0070711 0.02100000000000001 0.008485299999999999 -0.008485299999999999 0.02100000000000001 0.0070711 0.0070711 0.02100000000000001 0.01 0 0.02100000000000001 0.012 0 0.02100000000000001 0.008485299999999999 0.008485299999999999 0.02100000000000001 0 0.01 0.02100000000000001 0.0070711 0.0070711 0.02100000000000001 0 0.012 0.02100000000000001 -0.0070711 0.0070711 0.02100000000000001 0 0.01 0.02500000000000001 -0.0085355 0.0035355 0.02300000000000001 -0.00853552 0.00353554 0.02100000000000001 -0.01 0 0.02100000000000001 -0.01 0 0.02300000000000001 -0.00853552 0.00353554 0.02100000000000001 -0.0070711 0.0070711 0.02100000000000001 -0.0070711 0.0070711 0.02300000000000001 -0.00853552 0.00353554 0.02500000000000001 -0.0085355 0.0035355 0.02100000000000001 -0.0070711 -0.0070711 0.02500000000000001 -0.0085355 -0.0035355 0.02300000000000001 -0.00853552 -0.00353554 0.02100000000000001 -0.01 0 0.02100000000000001 -0.0070711 -0.0070711 0.02300000000000001 -0.00853552 -0.00353554 0.02500000000000001 -0.0085355 -0.0035355 0.02100000000000001 -0.01 0 0.02300000000000001 -0.00853552 -0.00353554 0.02100000000000001 -0.0070711 -0.0070711 0.02100000000000001 -0.008485299999999999 -0.008485299999999999 0.02100000000000001 0 -0.01 0.02100000000000001 0 -0.01 0.02100000000000001 0 -0.012 0.02100000000000001 0.0070711 -0.0070711 0.02100000000000001 0.012 0 0.02100000000000001 0.01 0 0.02100000000000001 0.0070711 -0.0070711 0.02100000000000001 0.0070711 0.0070711 0.02500000000000001 0.0085355 0.0035355 0.02300000000000001 0.00853552 0.00353554 0.02100000000000001 0.01 0 0.02100000000000001 0.0070711 0.0070711 0.02300000000000001 0.00853552 0.00353554 0.02500000000000001 0.0085355 0.0035355 0.02100000000000001 0.01 0 0.02300000000000001 0.00853552 0.00353554 0.02100000000000001 0 0.01 0.02500000000000001 0.0035355 0.0085355 0.02300000000000001 0.00353554 0.00853552 0.02100000000000001 0.0070711 0.0070711 0.02100000000000001 0 0.01 0.02300000000000001 0.00353554 0.00853552 0.02500000000000001 0.0035355 0.0085355 0.02100000000000001 0.0070711 0.0070711 0.02300000000000001 0.00353554 0.00853552 0.02100000000000001 -0.0070711 0.0070711 0.02500000000000001 -0.0035355 0.0085355 0.02300000000000001 -0.00353554 0.00853552 0.02100000000000001 0 0.01 0.02100000000000001 -0.0070711 0.0070711 0.02300000000000001 -0.00353554 0.00853552 0.02500000000000001 -0.0035355 0.0085355 0.02100000000000001 0 0.01 0.02300000000000001 -0.00353554 0.00853552 0.02900000000000001 -0.01 0 0.02500000000000001 -0.0085355 0.0035355 0.02500000000000001 -0.00926775 0.00176775 0.02100000000000001 -0.01 0 0.02900000000000001 -0.01 0 0.02500000000000001 -0.00926775 0.00176775 0.02500000000000001 -0.0085355 0.0035355 0.02100000000000001 -0.01 0 0.02500000000000001 -0.00926775 0.00176775 0.02100000000000001 -0.0070711 0.0070711 0.02500000000000001 -0.0085355 0.0035355 0.02500000000000001 -0.0078033 0.0053033 0.02900000000000001 -0.0070711 0.0070711 0.02100000000000001 -0.0070711 0.0070711 0.02500000000000001 -0.0078033 0.0053033 0.02500000000000001 -0.0085355 0.0035355 0.02900000000000001 -0.0070711 0.0070711 0.02500000000000001 -0.0078033 0.0053033 0.02900000000000001 -0.0070711 -0.0070711 0.02500000000000001 -0.0085355 -0.0035355 0.02500000000000001 -0.0078033 -0.0053033 0.02100000000000001 -0.0070711 -0.0070711 0.02900000000000001 -0.0070711 -0.0070711 0.02500000000000001 -0.0078033 -0.0053033 0.02500000000000001 -0.0085355 -0.0035355 0.02100000000000001 -0.0070711 -0.0070711 0.02500000000000001 -0.0078033 -0.0053033 0.02100000000000001 -0.01 0 0.02500000000000001 -0.0085355 -0.0035355 0.02500000000000001 -0.00926775 -0.00176775 0.02900000000000001 -0.01 0 0.02100000000000001 -0.01 0 0.02500000000000001 -0.00926775 -0.00176775 0.02500000000000001 -0.0085355 -0.0035355 0.02900000000000001 -0.01 0 0.02500000000000001 -0.00926775 -0.00176775 0.02100000000000001 0 -0.01 0.02500000000000001 -0.0035355 -0.0085355 0.02300000000000001 -0.00353554 -0.00853552 0.02100000000000001 -0.0070711 -0.0070711 0.02100000000000001 0 -0.01 0.02300000000000001 -0.00353554 -0.00853552 0.02500000000000001 -0.0035355 -0.0085355 0.02100000000000001 -0.0070711 -0.0070711 0.02300000000000001 -0.00353554 -0.00853552 0.02100000000000001 0.0070711 -0.0070711 0.02500000000000001 0.0035355 -0.0085355 0.02300000000000001 0.00353554 -0.00853552 0.02100000000000001 0 -0.01 0.02100000000000001 0.0070711 -0.0070711 0.02300000000000001 0.00353554 -0.00853552 0.02500000000000001 0.0035355 -0.0085355 0.02100000000000001 0 -0.01 0.02300000000000001 0.00353554 -0.00853552 0.02500000000000001 0.0085355 -0.0035355 0.02300000000000001 0.00853552 -0.00353554 0.02100000000000001 0.01 0 0.02100000000000001 0.01 0 0.02300000000000001 0.00853552 -0.00353554 0.02100000000000001 0.0070711 -0.0070711 0.02100000000000001 0.0070711 -0.0070711 0.02300000000000001 0.00853552 -0.00353554 0.02500000000000001 0.0085355 -0.0035355 0.02900000000000001 0.0070711 0.0070711 0.02500000000000001 0.0085355 0.0035355 0.02500000000000001 0.0078033 0.0053033 0.02100000000000001 0.0070711 0.0070711 0.02900000000000001 0.0070711 0.0070711 0.02500000000000001 0.0078033 0.0053033 0.02500000000000001 0.0085355 0.0035355 0.02100000000000001 0.0070711 0.0070711 0.02500000000000001 0.0078033 0.0053033 0.02100000000000001 0.01 0 0.02500000000000001 0.0085355 0.0035355 0.02500000000000001 0.00926775 0.00176775 0.02900000000000001 0.01 0 0.02100000000000001 0.01 0 0.02500000000000001 0.00926775 0.00176775 0.02500000000000001 0.0085355 0.0035355 0.02900000000000001 0.01 0 0.02500000000000001 0.00926775 0.00176775 0.02900000000000001 0 0.01 0.02500000000000001 0.0035355 0.0085355 0.02500000000000001 0.00176775 0.00926775 0.02100000000000001 0 0.01 0.02900000000000001 0 0.01 0.02500000000000001 0.00176775 0.00926775 0.02500000000000001 0.0035355 0.0085355 0.02100000000000001 0 0.01 0.02500000000000001 0.00176775 0.00926775 0.02100000000000001 0.0070711 0.0070711 0.02500000000000001 0.0035355 0.0085355 0.02500000000000001 0.0053033 0.0078033 0.02900000000000001 0.0070711 0.0070711 0.02100000000000001 0.0070711 0.0070711 0.02500000000000001 0.0053033 0.0078033 0.02500000000000001 0.0035355 0.0085355 0.02900000000000001 0.0070711 0.0070711 0.02500000000000001 0.0053033 0.0078033 0.02900000000000001 -0.0070711 0.0070711 0.02500000000000001 -0.0035355 0.0085355 0.02500000000000001 -0.0053033 0.0078033 0.02100000000000001 -0.0070711 0.0070711 0.02900000000000001 -0.0070711 0.0070711 0.02500000000000001 -0.0053033 0.0078033 0.02500000000000001 -0.0035355 0.0085355 0.02100000000000001 -0.0070711 0.0070711 0.02500000000000001 -0.0053033 0.0078033 0.02100000000000001 0 0.01 0.02500000000000001 -0.0035355 0.0085355 0.02500000000000001 -0.00176775 0.00926775 0.02900000000000001 0 0.01 0.02100000000000001 0 0.01 0.02500000000000001 -0.00176775 0.00926775 0.02500000000000001 -0.0035355 0.0085355 0.02900000000000001 0 0.01 0.02500000000000001 -0.00176775 0.00926775 0.02900000000000001 -0.0070711 0.0070711 0.02500000000000001 -0.0085355 0.0035355 0.02700000000000001 -0.00853552 0.00353554 0.02900000000000001 -0.01 0 0.02900000000000001 -0.0070711 0.0070711 0.02700000000000001 -0.00853552 0.00353554 0.02500000000000001 -0.0085355 0.0035355 0.02900000000000001 -0.01 0 0.02700000000000001 -0.00853552 0.00353554 0.02900000000000001 -0.01 0 0.02500000000000001 -0.0085355 -0.0035355 0.02700000000000001 -0.00853552 -0.00353554 0.02900000000000001 -0.0070711 -0.0070711 0.02900000000000001 -0.01 0 0.02700000000000001 -0.00853552 -0.00353554 0.02500000000000001 -0.0085355 -0.0035355 0.02900000000000001 -0.0070711 -0.0070711 0.02700000000000001 -0.00853552 -0.00353554 0.02100000000000001 -0.0070711 -0.0070711 0.02500000000000001 -0.0035355 -0.0085355 0.02500000000000001 -0.0053033 -0.0078033 0.02900000000000001 -0.0070711 -0.0070711 0.02100000000000001 -0.0070711 -0.0070711 0.02500000000000001 -0.0053033 -0.0078033 0.02500000000000001 -0.0035355 -0.0085355 0.02900000000000001 -0.0070711 -0.0070711 0.02500000000000001 -0.0053033 -0.0078033 0.02900000000000001 0 -0.01 0.02500000000000001 -0.0035355 -0.0085355 0.02500000000000001 -0.00176775 -0.00926775 0.02100000000000001 0 -0.01 0.02900000000000001 0 -0.01 0.02500000000000001 -0.00176775 -0.00926775 0.02500000000000001 -0.0035355 -0.0085355 0.02100000000000001 0 -0.01 0.02500000000000001 -0.00176775 -0.00926775 0.02900000000000001 0.0070711 -0.0070711 0.02500000000000001 0.0035355 -0.0085355 0.02500000000000001 0.0053033 -0.0078033 0.02100000000000001 0.0070711 -0.0070711 0.02900000000000001 0.0070711 -0.0070711 0.02500000000000001 0.0053033 -0.0078033 0.02500000000000001 0.0035355 -0.0085355 0.02100000000000001 0.0070711 -0.0070711 0.02500000000000001 0.0053033 -0.0078033 0.02100000000000001 0 -0.01 0.02500000000000001 0.0035355 -0.0085355 0.02500000000000001 0.00176775 -0.00926775 0.02900000000000001 0 -0.01 0.02100000000000001 0 -0.01 0.02500000000000001 0.00176775 -0.00926775 0.02500000000000001 0.0035355 -0.0085355 0.02900000000000001 0 -0.01 0.02500000000000001 0.00176775 -0.00926775 0.02900000000000001 0.01 0 0.02500000000000001 0.0085355 -0.0035355 0.02500000000000001 0.00926775 -0.00176775 0.02100000000000001 0.01 0 0.02900000000000001 0.01 0 0.02500000000000001 0.00926775 -0.00176775 0.02500000000000001 0.0085355 -0.0035355 0.02100000000000001 0.01 0 0.02500000000000001 0.00926775 -0.00176775 0.02100000000000001 0.0070711 -0.0070711 0.02500000000000001 0.0085355 -0.0035355 0.02500000000000001 0.0078033 -0.0053033 0.02900000000000001 0.0070711 -0.0070711 0.02100000000000001 0.0070711 -0.0070711 0.02500000000000001 0.0078033 -0.0053033 0.02500000000000001 0.0085355 -0.0035355 0.02900000000000001 0.0070711 -0.0070711 0.02500000000000001 0.0078033 -0.0053033 0.02900000000000001 0.01 0 0.02500000000000001 0.0085355 0.0035355 0.02700000000000001 0.00853552 0.00353554 0.02900000000000001 0.0070711 0.0070711 0.02900000000000001 0.01 0 0.02700000000000001 0.00853552 0.00353554 0.02500000000000001 0.0085355 0.0035355 0.02900000000000001 0.0070711 0.0070711 0.02700000000000001 0.00853552 0.00353554 0.02900000000000001 0.0070711 0.0070711 0.02500000000000001 0.0035355 0.0085355 0.02700000000000001 0.00353554 0.00853552 0.02900000000000001 0 0.01 0.02900000000000001 0.0070711 0.0070711 0.02700000000000001 0.00353554 0.00853552 0.02500000000000001 0.0035355 0.0085355 0.02900000000000001 0 0.01 0.02700000000000001 0.00353554 0.00853552 0.02900000000000001 0 0.01 0.02500000000000001 -0.0035355 0.0085355 0.02700000000000001 -0.00353554 0.00853552 0.02900000000000001 -0.0070711 0.0070711 0.02900000000000001 0 0.01 0.02700000000000001 -0.00353554 0.00853552 0.02500000000000001 -0.0035355 0.0085355 0.02900000000000001 -0.0070711 0.0070711 0.02700000000000001 -0.00353554 0.00853552 0.02900000000000001 -0.0070711 0.0070711 0.02900000000000001 -0.01 0 0.02900000000000001 0 0 0.02900000000000001 0 0 0.02900000000000001 -0.01 0 0.02900000000000001 -0.0070711 -0.0070711 0.02900000000000001 -0.0070711 -0.0070711 0.02500000000000001 -0.0035355 -0.0085355 0.02700000000000001 -0.00353554 -0.00853552 0.02900000000000001 0 -0.01 0.02900000000000001 -0.0070711 -0.0070711 0.02700000000000001 -0.00353554 -0.00853552 0.02500000000000001 -0.0035355 -0.0085355 0.02900000000000001 0 -0.01 0.02700000000000001 -0.00353554 -0.00853552 0.02900000000000001 0 -0.01 0.02500000000000001 0.0035355 -0.0085355 0.02700000000000001 0.00353554 -0.00853552 0.02900000000000001 0.0070711 -0.0070711 0.02900000000000001 0 -0.01 0.02700000000000001 0.00353554 -0.00853552 0.02500000000000001 0.0035355 -0.0085355 0.02900000000000001 0.0070711 -0.0070711 0.02700000000000001 0.00353554 -0.00853552 0.02900000000000001 0.0070711 -0.0070711 0.02500000000000001 0.0085355 -0.0035355 0.02700000000000001 0.00853552 -0.00353554 0.02900000000000001 0.01 0 0.02900000000000001 0.0070711 -0.0070711 0.02700000000000001 0.00853552 -0.00353554 0.02500000000000001 0.0085355 -0.0035355 0.02900000000000001 0.01 0 0.02700000000000001 0.00853552 -0.00353554 0.02900000000000001 0.0070711 0.0070711 0.02900000000000001 0 0 0.02900000000000001 0.01 0 0.02900000000000001 0.0070711 0.0070711 0.02900000000000001 0 0.01 0.02900000000000001 0 0 0.02900000000000001 0 0.01 0.02900000000000001 -0.0070711 0.0070711 0.02900000000000001 0 0 0.02900000000000001 0 0 0.02900000000000001 -0.0070711 -0.0070711 0.02900000000000001 0 -0.01 0.02900000000000001 0 0 0.02900000000000001 0 -0.01 0.02900000000000001 0.0070711 -0.0070711 0.02900000000000001 0.01 0 0.02900000000000001 0 0 0.02900000000000001 0.0070711 -0.0070711 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827

    -
    -
    - - - 6.938893903907228e-18 0 0 - 1 0 0 0 - - true - - - -
    - - - - 0.001999999999999997 0 -0.0153 0.001999999999999997 -0.00835 -0.0148 0.001999999999999997 -0.00835 -0.0158 0.001999999999999997 -0.00835 -0.0148 0.001999999999999997 0 -0.0153 0.001999999999999997 0.00835 -0.0148 0.001999999999999997 -0.00835 -0.0148 -0.006000000000000004 -0.009075 -0.0153 0.001999999999999997 -0.00835 -0.0158 0.001999999999999997 0.00835 -0.0158 0.001999999999999997 0 -0.0153 0.001999999999999997 -0.00835 -0.0158 0.001999999999999997 0.00835 -0.0158 0.001999999999999997 0.00835 -0.0148 0.001999999999999997 0 -0.0153 -0.006000000000000004 0 -0.0148 0.001999999999999997 -0.00835 -0.0148 -0.002000000000000004 0 -0.0148 0.001999999999999997 -0.00835 -0.0148 0.001999999999999997 0.00835 -0.0148 -0.002000000000000004 0 -0.0148 0.001999999999999997 0.00835 -0.0148 -0.006000000000000004 0 -0.0148 -0.002000000000000004 0 -0.0148 -0.006000000000000004 -0.009075 -0.0153 -0.014 -0.0098 -0.0158 0.001999999999999997 -0.00835 -0.0158 -0.014 -0.0098 -0.0148 -0.006000000000000004 -0.009075 -0.0153 0.001999999999999997 -0.00835 -0.0148 -0.009000000000000003 0 -0.0158 0.001999999999999997 0.00835 -0.0158 -0.003500000000000004 -2.60209e-17 -0.0158 0.001999999999999997 0.00835 -0.0158 0.001999999999999997 -0.00835 -0.0158 -0.003500000000000004 -2.60209e-17 -0.0158 0.001999999999999997 -0.00835 -0.0158 -0.009000000000000003 0 -0.0158 -0.003500000000000004 -2.60209e-17 -0.0158 0.001999999999999997 0.00835 -0.0148 0.001999999999999997 0.00835 -0.0158 -0.006000000000000004 0.009075 -0.0153 -0.006000000000000004 0 -0.0148 -0.014 -0.0098 -0.0148 -0.006000000000000004 -0.0049 -0.0148 -0.014 -0.0098 -0.0148 0.001999999999999997 -0.00835 -0.0148 -0.006000000000000004 -0.0049 -0.0148 0.001999999999999997 -0.00835 -0.0148 -0.006000000000000004 0 -0.0148 -0.006000000000000004 -0.0049 -0.0148 -0.006000000000000004 0 -0.0148 0.001999999999999997 0.00835 -0.0148 -0.006000000000000004 0.0049 -0.0148 0.001999999999999997 0.00835 -0.0148 -0.014 0.0098 -0.0148 -0.006000000000000004 0.0049 -0.0148 -0.014 0.0098 -0.0148 -0.006000000000000004 0 -0.0148 -0.006000000000000004 0.0049 -0.0148 -0.014 -0.0098 -0.0148 -0.014 -0.0098 -0.0158 -0.006000000000000004 -0.009075 -0.0153 -0.014 -0.0098 -0.0158 -0.009000000000000003 0 -0.0158 0.001999999999999997 -0.00835 -0.0158 -0.009000000000000003 0 -0.0158 -0.014 0.0098 -0.0158 0.001999999999999997 0.00835 -0.0158 0.001999999999999997 0.00835 -0.0148 -0.006000000000000004 0.009075 -0.0153 -0.014 0.0098 -0.0148 -0.006000000000000004 0.009075 -0.0153 0.001999999999999997 0.00835 -0.0158 -0.014 0.0098 -0.0158 -0.006000000000000004 0 -0.0148 -0.014 0.0098 -0.0148 -0.01 6.93889e-18 -0.0148 -0.014 0.0098 -0.0148 -0.014 -0.0098 -0.0148 -0.01 6.93889e-18 -0.0148 -0.014 -0.0098 -0.0148 -0.006000000000000004 0 -0.0148 -0.01 6.93889e-18 -0.0148 -0.014 -0.0098 -0.0148 -0.0143333 -0.0098 0 -0.014 -0.0098 -0.0158 -0.014 -0.0098 -0.0158 -0.015 -0.0098 -0.0158 -0.009000000000000003 0 -0.0158 -0.009000000000000003 0 -0.0158 -0.015 0.0098 -0.0158 -0.014 0.0098 -0.0158 -0.014 0.0098 -0.0148 -0.006000000000000004 0.009075 -0.0153 -0.014 0.0098 -0.0158 -0.014 0 0 -0.014 -0.0098 -0.0148 -0.014 0 -0.0074 -0.014 -0.0098 -0.0148 -0.014 0.0098 -0.0148 -0.014 0 -0.0074 -0.014 0.0098 -0.0148 -0.014 0 0 -0.014 0 -0.0074 -0.015 -0.0098 -0.0158 -0.014 -0.0098 -0.0158 -0.0143333 -0.0098 0 -0.014 -0.0098 0.0148 -0.0143333 -0.0098 0 -0.014 -0.0098 -0.0148 -0.009000000000000003 0 -0.0158 -0.015 -0.0098 -0.0158 -0.012 -6.93889e-18 -0.0158 -0.015 -0.0098 -0.0158 -0.015 0.0098 -0.0158 -0.012 -6.93889e-18 -0.0158 -0.015 0.0098 -0.0158 -0.009000000000000003 0 -0.0158 -0.012 -6.93889e-18 -0.0158 -0.015 0.0098 -0.0158 -0.0143333 0.0098 0 -0.014 0.0098 -0.0158 -0.014 0.0098 -0.0158 -0.0143333 0.0098 0 -0.014 0.0098 -0.0148 -0.014 0 0 -0.014 -0.0098 0.0148 -0.014 -0.0049 -1.30104e-17 -0.014 -0.0098 0.0148 -0.014 -0.0098 -0.0148 -0.014 -0.0049 -1.30104e-17 -0.014 -0.0098 -0.0148 -0.014 0 0 -0.014 -0.0049 -1.30104e-17 -0.014 0 0 -0.014 0.0098 -0.0148 -0.014 0.0049 0 -0.014 0.0098 -0.0148 -0.014 0.0098 0.0148 -0.014 0.0049 0 -0.014 0.0098 0.0148 -0.014 0 0 -0.014 0.0049 0 -0.015 -0.0098 -0.0125 -0.015 -0.0098 -0.0158 -0.0149 -0.0098 -0.0125 -0.015 -0.0098 0.0158 -0.015 -0.0098 0.0125 -0.0149 -0.0098 0.0125 -0.0143333 -0.0098 0 -0.0149 -0.0098 0.0125 -0.0149 -0.0098 -0.0125 -0.015 -0.0098 -0.0158 -0.0143333 -0.0098 0 -0.0149 -0.0098 -0.0125 -0.015 -0.0098 0.0158 -0.0149 -0.0098 0.0125 -0.0143333 -0.0098 0 -0.014 -0.0098 0.0158 -0.0143333 -0.0098 0 -0.014 -0.0098 0.0148 -0.015 0.00775316 -0.0125 -0.015 0.0098 -0.0158 -0.015 1.73472e-18 -0.01415 -0.015 0.0098 -0.0158 -0.015 -0.0098 -0.0158 -0.015 1.73472e-18 -0.01415 -0.015 -0.0098 -0.0158 -0.015 -0.00775316 -0.0125 -0.015 1.73472e-18 -0.01415 -0.015 -0.00775316 -0.0125 -0.015 0.00775316 -0.0125 -0.015 1.73472e-18 -0.01415 -0.015 0.0098 0.0125 -0.015 0.0098 0.0158 -0.0149 0.0098 0.0125 -0.0149 0.0098 0.0110577 -0.0143333 0.0098 0 -0.0149 0.0098 -0.0110577 -0.015 0.0098 -0.0125 -0.0149 0.0098 -0.0125 -0.015 0.0098 -0.0158 -0.0143333 0.0098 0 -0.0149 0.0098 0.0110577 -0.0149 0.0098 0.0125 -0.015 0.0098 0.0158 -0.0143333 0.0098 0 -0.0149 0.0098 0.0125 -0.0149 0.0098 -0.0125 -0.0143333 0.0098 0 -0.015 0.0098 -0.0158 -0.0149 0.0098 -0.0110577 -0.0143333 0.0098 0 -0.0149 0.0098 -0.0125 -0.014 0.0098 -0.0148 -0.0143333 0.0098 0 -0.014 0.0098 0.0148 -0.014 0 0 -0.014 0.0098 0.0148 -0.014 6.93889e-18 0.0074 -0.014 0.0098 0.0148 -0.014 -0.0098 0.0148 -0.014 6.93889e-18 0.0074 -0.014 -0.0098 0.0148 -0.014 0 0 -0.014 6.93889e-18 0.0074 -0.015 -0.0098 0.0158 -0.0143333 -0.0098 0 -0.014 -0.0098 0.0158 -0.015 -0.00976894 0.0125 -0.015 -0.0098 0.0125 -0.015 -0.0098 0.0158 -0.015 -0.00775316 0.0125 -0.015 -0.0097419 0.0125 -0.015 -0.0098 0.0158 -0.015 -0.0098 0.0158 -0.015 -0.009752500000000001 0.0125 -0.015 -0.0097419 0.0125 -0.015 -0.0098 0.0158 -0.015 -0.00975934 0.0125 -0.015 -0.009752500000000001 0.0125 -0.015 -0.0098 0.0158 -0.015 -0.00976894 0.0125 -0.015 -0.00975934 0.0125 -0.0149 -0.0098 0.0125 -0.015 -0.0098 0.0124302 -0.015 -0.0098 0.0125 -0.015 -0.0098 0.0124302 -0.015 -0.0098 -0.0124302 -0.0149 -0.0098 0.0125 -0.015 -0.0098 -0.0124302 -0.0149 -0.0098 -0.0125 -0.0149 -0.0098 0.0125 -0.0149 -0.0098 -0.0125 -0.015 -0.0098 -0.0125 -0.015 -0.0098 -0.0124302 -0.015 -0.00775316 -0.0125 -0.015 -0.0098 -0.0158 -0.015 -0.0097419 -0.0125 -0.015 -0.00975208 -0.0125 -0.015 -0.0098 -0.0158 -0.015 -0.0097419 -0.0125 -0.015 -0.009759169999999999 -0.0125 -0.015 -0.0098 -0.0158 -0.015 -0.00975208 -0.0125 -0.015 -0.009769140000000001 -0.0125 -0.015 -0.0098 -0.0158 -0.015 -0.009759169999999999 -0.0125 -0.015 -0.009769140000000001 -0.0125 -0.015 -0.0098 -0.0158 -0.015 -0.0098 -0.0125 -0.014 -0.0098 0.0158 -0.014 -0.0098 0.0148 -0.006000000000000004 -0.009075 0.0153 -0.015 0.0098 -0.0125 -0.015 0.0098 -0.0158 -0.015 0.00775316 -0.0125 -0.015 -0.0097419 -0.0125 -0.05070000000000001 0.011 -0.0125 -0.015 -0.00775316 -0.0125 -0.015 -0.00775316 -0.0125 -0.05070000000000001 0.011 -0.0125 -0.015 0.00775316 -0.0125 -0.015 0.00775316 -0.0125 -0.05070000000000001 0.011 -0.0125 -0.015 0.0098 -0.0125 -0.0149 0.0098 -0.0125 -0.015 0.0098 -0.0125 -0.0149 0.011 -0.0125 -0.015 0.0098 -0.0125 -0.05070000000000001 0.011 -0.0125 -0.0149 0.011 -0.0125 -0.0149 0.0098 0.0110577 -0.0149 0.0098 -0.0110577 -0.0149 0.0104 7.806259999999999e-18 -0.0149 0.0098 -0.0110577 -0.0149 0.011 -0.0125 -0.0149 0.0104 7.806259999999999e-18 -0.0149 0.011 -0.0125 -0.0149 0.011 0.0125 -0.0149 0.0104 7.806259999999999e-18 -0.0149 0.011 0.0125 -0.0149 0.0098 0.0110577 -0.0149 0.0104 7.806259999999999e-18 -0.0149 0.011 0.0125 -0.0149 0.0098 0.0125 -0.0149 0.0098 0.0110577 -0.015 0.0098 0.0125 -0.0149 0.0098 0.0125 -0.0149 0.011 0.0125 -0.015 0.00775316 0.0125 -0.015 0.0098 0.0125 -0.05070000000000001 0.011 0.0125 -0.015 -0.0097419 0.0125 -0.015 -0.00775316 0.0125 -0.05070000000000001 0.011 0.0125 -0.015 -0.00775316 0.0125 -0.015 0.00775316 0.0125 -0.05070000000000001 0.011 0.0125 -0.015 0.0098 0.0125 -0.0149 0.011 0.0125 -0.05070000000000001 0.011 0.0125 -0.015 0.0098 0.0125 -0.015 0.00775316 0.0125 -0.015 0.0098 0.0158 -0.015 0.0098 0.0158 -0.014 0.0098 0.0158 -0.0143333 0.0098 0 -0.0149 0.011 -0.0125 -0.0149 0.0098 -0.0110577 -0.0149 0.0098 -0.0125 -0.014 0.0098 0.0148 -0.0143333 0.0098 0 -0.014 0.0098 0.0158 -0.006000000000000004 0 0.0148 -0.014 -0.0098 0.0148 -0.01 -4.33681e-18 0.0148 -0.014 -0.0098 0.0148 -0.014 0.0098 0.0148 -0.01 -4.33681e-18 0.0148 -0.014 0.0098 0.0148 -0.006000000000000004 0 0.0148 -0.01 -4.33681e-18 0.0148 -0.015 -0.0098 0.0158 -0.014 -0.0098 0.0158 -0.009000000000000003 0 0.0158 -0.015 -0.0098 0.0125 -0.015 -0.00976894 0.0125 -0.03285 -0.0059253 0.0125 -0.015 -0.00976894 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.03285 -0.0059253 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.05070000000000001 -0.0098 0.0125 -0.03285 -0.0059253 0.0125 -0.05070000000000001 -0.0098 0.0125 -0.015 -0.0098 0.0125 -0.03285 -0.0059253 0.0125 -0.015 -0.00775316 0.0125 -0.015 -0.0098 0.0158 -0.015 -8.673619999999999e-18 0.01415 -0.015 -0.0098 0.0158 -0.015 0.0098 0.0158 -0.015 -8.673619999999999e-18 0.01415 -0.015 0.0098 0.0158 -0.015 0.00775316 0.0125 -0.015 -8.673619999999999e-18 0.01415 -0.015 0.00775316 0.0125 -0.015 -0.00775316 0.0125 -0.015 -8.673619999999999e-18 0.01415 -0.015 -0.009752500000000001 0.0125 -0.015 -0.0097419 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.015 -0.0097419 0.0125 -0.05070000000000001 0.011 0.0125 -0.015 -0.00975934 0.0125 -0.015 -0.009752500000000001 0.0125 -0.03900000000000001 0 0.0125 -0.03900000000000001 0 0.0125 -0.015 -0.009752500000000001 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.015 -0.00976894 0.0125 -0.015 -0.00975934 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.015 -0.00975934 0.0125 -0.03900000000000001 0 0.0125 -0.015 -0.0098 0.0124302 -0.015 -0.0098 0.0125 -0.03285 -0.0098 0.00625 -0.015 -0.0098 0.0125 -0.05070000000000001 -0.0098 0.0125 -0.03285 -0.0098 0.00625 -0.05070000000000001 -0.0098 0.0125 -0.03280000000000001 -0.0098 0 -0.03285 -0.0098 0.00625 -0.03280000000000001 -0.0098 0 -0.015 -0.0098 0.0124302 -0.03285 -0.0098 0.00625 -0.015 -0.0098 -0.0124302 -0.015 -0.0098 0.0124302 -0.0239 -0.0098 0 -0.015 -0.0098 0.0124302 -0.03280000000000001 -0.0098 0 -0.0239 -0.0098 0 -0.03280000000000001 -0.0098 0 -0.015 -0.0098 -0.0124302 -0.0239 -0.0098 0 -0.03280000000000001 -0.0098 0 -0.05070000000000001 -0.0098 -0.0125 -0.03285 -0.0098 -0.00625 -0.05070000000000001 -0.0098 -0.0125 -0.015 -0.0098 -0.0125 -0.03285 -0.0098 -0.00625 -0.015 -0.0098 -0.0125 -0.015 -0.0098 -0.0124302 -0.03285 -0.0098 -0.00625 -0.015 -0.0098 -0.0124302 -0.03280000000000001 -0.0098 0 -0.03285 -0.0098 -0.00625 -0.015 -0.009769140000000001 -0.0125 -0.015 -0.0098 -0.0125 -0.03285 -0.00596065 -0.0125 -0.015 -0.0098 -0.0125 -0.05070000000000001 -0.0098 -0.0125 -0.03285 -0.00596065 -0.0125 -0.05070000000000001 -0.0098 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.03285 -0.00596065 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.015 -0.009769140000000001 -0.0125 -0.03285 -0.00596065 -0.0125 -0.015 -0.009769140000000001 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.015 -0.009759169999999999 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.0389 0 -0.0125 -0.015 -0.009759169999999999 -0.0125 -0.015 -0.009759169999999999 -0.0125 -0.0389 0 -0.0125 -0.015 -0.00975208 -0.0125 -0.0389 0 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.015 -0.00975208 -0.0125 -0.015 -0.00975208 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.015 -0.0097419 -0.0125 -0.015 -0.0097419 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.05070000000000001 0.011 -0.0125 -0.014 -0.0098 0.0158 -0.006000000000000004 -0.009075 0.0153 0.001999999999999997 -0.00835 0.0158 -0.006000000000000004 -0.009075 0.0153 -0.014 -0.0098 0.0148 0.001999999999999997 -0.00835 0.0148 -0.03280000000000001 0.011 0 -0.0149 0.011 -0.0125 -0.03280000000000001 0.011 -0.00625 -0.0149 0.011 -0.0125 -0.05070000000000001 0.011 -0.0125 -0.03280000000000001 0.011 -0.00625 -0.05070000000000001 0.011 -0.0125 -0.03280000000000001 0.011 0 -0.03280000000000001 0.011 -0.00625 -0.03280000000000001 0.011 0 -0.0149 0.011 0.0125 -0.02385 0.011 1.99493e-17 -0.0149 0.011 0.0125 -0.0149 0.011 -0.0125 -0.02385 0.011 1.99493e-17 -0.0149 0.011 -0.0125 -0.03280000000000001 0.011 0 -0.02385 0.011 1.99493e-17 -0.03280000000000001 0.011 0 -0.05070000000000001 0.011 0.0125 -0.03280000000000001 0.011 0.00625 -0.05070000000000001 0.011 0.0125 -0.0149 0.011 0.0125 -0.03280000000000001 0.011 0.00625 -0.0149 0.011 0.0125 -0.03280000000000001 0.011 0 -0.03280000000000001 0.011 0.00625 -0.009000000000000003 0 0.0158 -0.014 0.0098 0.0158 -0.015 0.0098 0.0158 -0.014 0.0098 0.0158 -0.006000000000000004 0.009075 0.0153 -0.014 0.0098 0.0148 -0.006000000000000004 0 0.0148 0.001999999999999997 -0.00835 0.0148 -0.006000000000000004 -0.0049 0.0148 0.001999999999999997 -0.00835 0.0148 -0.014 -0.0098 0.0148 -0.006000000000000004 -0.0049 0.0148 -0.014 -0.0098 0.0148 -0.006000000000000004 0 0.0148 -0.006000000000000004 -0.0049 0.0148 -0.006000000000000004 0 0.0148 -0.014 0.0098 0.0148 -0.006000000000000004 0.0049 0.0148 -0.014 0.0098 0.0148 0.001999999999999997 0.00835 0.0148 -0.006000000000000004 0.0049 0.0148 0.001999999999999997 0.00835 0.0148 -0.006000000000000004 0 0.0148 -0.006000000000000004 0.0049 0.0148 -0.009000000000000003 0 0.0158 -0.015 0.0098 0.0158 -0.012 0 0.0158 -0.015 0.0098 0.0158 -0.015 -0.0098 0.0158 -0.012 0 0.0158 -0.015 -0.0098 0.0158 -0.009000000000000003 0 0.0158 -0.012 0 0.0158 -0.014 -0.0098 0.0158 0.001999999999999997 -0.00835 0.0158 -0.009000000000000003 0 0.0158 -0.05070000000000001 -0.0098 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.04190000000000001 -0.0029 0.0125 -0.04190000000000001 0.0029 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.05070000000000001 0.011 0.0125 -0.039425 0.0010253 0.01415 -0.03900000000000001 0 0.0125 -0.03942470000000001 0.00102521 0.013325 -0.03900000000000001 0 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.03942470000000001 0.00102521 0.013325 -0.03984900000000001 0.0020506 0.0125 -0.039425 0.0010253 0.01415 -0.03942470000000001 0.00102521 0.013325 -0.03942470000000001 -0.00102521 0.013325 -0.039425 -0.0010253 0.01415 -0.03984900000000001 -0.0020506 0.0125 -0.03942470000000001 -0.00102521 0.013325 -0.03984900000000001 -0.0020506 0.0125 -0.03900000000000001 0 0.0125 -0.03942470000000001 -0.00102521 0.013325 -0.03900000000000001 0 0.0125 -0.039425 -0.0010253 0.01415 -0.03280000000000001 -0.0098 0 -0.05070000000000001 -0.0098 0.0125 -0.04175000000000001 -0.0098 1.47451e-17 -0.05070000000000001 -0.0098 0.0125 -0.05070000000000001 -0.0098 -0.0125 -0.04175000000000001 -0.0098 1.47451e-17 -0.05070000000000001 -0.0098 -0.0125 -0.03280000000000001 -0.0098 0 -0.04175000000000001 -0.0098 1.47451e-17 -0.04190000000000001 -0.003 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.05070000000000001 -0.0098 -0.0125 -0.039339 -0.0010607 -0.01415 -0.0389 0 -0.0125 -0.03933930000000001 -0.00106074 -0.013325 -0.0389 0 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.03933930000000001 -0.00106074 -0.013325 -0.03977900000000001 -0.0021213 -0.0125 -0.039339 -0.0010607 -0.01415 -0.03933930000000001 -0.00106074 -0.013325 -0.039339 0.0010607 -0.01415 -0.03977900000000001 0.0021213 -0.0125 -0.03933930000000001 0.00106074 -0.013325 -0.03977900000000001 0.0021213 -0.0125 -0.0389 0 -0.0125 -0.03933930000000001 0.00106074 -0.013325 -0.0389 0 -0.0125 -0.039339 0.0010607 -0.01415 -0.03933930000000001 0.00106074 -0.013325 -0.05070000000000001 0.011 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.04190000000000001 0.003 -0.0125 0.001999999999999997 -0.00835 0.0158 -0.006000000000000004 -0.009075 0.0153 0.001999999999999997 -0.00835 0.0148 -0.03280000000000001 0.011 0 -0.05070000000000001 0.011 -0.0125 -0.04175000000000001 0.011 -1.56125e-17 -0.05070000000000001 0.011 -0.0125 -0.05070000000000001 0.011 0.0125 -0.04175000000000001 0.011 -1.56125e-17 -0.05070000000000001 0.011 0.0125 -0.03280000000000001 0.011 0 -0.04175000000000001 0.011 -1.56125e-17 -0.009000000000000003 0 0.0158 0.001999999999999997 0.00835 0.0158 -0.014 0.0098 0.0158 -0.014 0.0098 0.0148 -0.006000000000000004 0.009075 0.0153 0.001999999999999997 0.00835 0.0148 0.001999999999999997 0.00835 0.0158 -0.006000000000000004 0.009075 0.0153 -0.014 0.0098 0.0158 -0.006000000000000004 0 0.0148 0.001999999999999997 0.00835 0.0148 -0.002000000000000004 -1.99493e-17 0.0148 0.001999999999999997 0.00835 0.0148 0.001999999999999997 -0.00835 0.0148 -0.002000000000000004 -1.99493e-17 0.0148 0.001999999999999997 -0.00835 0.0148 -0.006000000000000004 0 0.0148 -0.002000000000000004 -1.99493e-17 0.0148 -0.009000000000000003 0 0.0158 0.001999999999999997 -0.00835 0.0158 -0.003500000000000004 0 0.0158 0.001999999999999997 -0.00835 0.0158 0.001999999999999997 0.00835 0.0158 -0.003500000000000004 0 0.0158 0.001999999999999997 0.00835 0.0158 -0.009000000000000003 0 0.0158 -0.003500000000000004 0 0.0158 -0.04087450000000001 -0.00247521 0.013325 -0.04087500000000001 -0.0024753 0.01415 -0.04190000000000001 -0.0029 0.0125 -0.04087450000000001 -0.00247521 0.013325 -0.04190000000000001 -0.0029 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.04087450000000001 -0.00247521 0.013325 -0.03984900000000001 -0.0020506 0.0125 -0.04087500000000001 -0.0024753 0.01415 -0.05070000000000001 -0.0098 0.0125 -0.04190000000000001 -0.0029 0.0125 -0.043951 -0.0020506 0.0125 -0.043951 0.0020506 0.0125 -0.04190000000000001 0.0029 0.0125 -0.05070000000000001 0.011 0.0125 -0.04087500000000001 0.0024753 0.01415 -0.03984900000000001 0.0020506 0.0125 -0.04087450000000001 0.00247521 0.013325 -0.03984900000000001 0.0020506 0.0125 -0.04190000000000001 0.0029 0.0125 -0.04087450000000001 0.00247521 0.013325 -0.04190000000000001 0.0029 0.0125 -0.04087500000000001 0.0024753 0.01415 -0.04087450000000001 0.00247521 0.013325 -0.039425 0.0010253 0.01415 -0.03900000000000001 0 0.0158 -0.0392125 0.00051265 0.01415 -0.03900000000000001 0 0.0158 -0.03900000000000001 0 0.0125 -0.0392125 0.00051265 0.01415 -0.03900000000000001 0 0.0125 -0.039425 0.0010253 0.01415 -0.0392125 0.00051265 0.01415 -0.039425 0.0010253 0.01415 -0.03984900000000001 0.0020506 0.0125 -0.03963700000000001 0.00153795 0.01415 -0.03984900000000001 0.0020506 0.0125 -0.03984900000000001 0.0020506 0.0158 -0.03963700000000001 0.00153795 0.01415 -0.03984900000000001 0.0020506 0.0158 -0.039425 0.0010253 0.01415 -0.03963700000000001 0.00153795 0.01415 -0.039425 -0.0010253 0.01415 -0.03984900000000001 -0.0020506 0.0158 -0.03963700000000001 -0.00153795 0.01415 -0.03984900000000001 -0.0020506 0.0158 -0.03984900000000001 -0.0020506 0.0125 -0.03963700000000001 -0.00153795 0.01415 -0.03984900000000001 -0.0020506 0.0125 -0.039425 -0.0010253 0.01415 -0.03963700000000001 -0.00153795 0.01415 -0.039425 -0.0010253 0.01415 -0.03900000000000001 0 0.0125 -0.0392125 -0.00051265 0.01415 -0.03900000000000001 0 0.0125 -0.03900000000000001 0 0.0158 -0.0392125 -0.00051265 0.01415 -0.03900000000000001 0 0.0158 -0.039425 -0.0010253 0.01415 -0.0392125 -0.00051265 0.01415 -0.05070000000000001 0.000599999 0 -0.05070000000000001 -0.0098 -0.0125 -0.05070000000000001 -0.0046 1.64799e-17 -0.05070000000000001 -0.0098 -0.0125 -0.05070000000000001 -0.0098 0.0125 -0.05070000000000001 -0.0046 1.64799e-17 -0.05070000000000001 -0.0098 0.0125 -0.05070000000000001 0.000599999 0 -0.05070000000000001 -0.0046 1.64799e-17 -0.05070000000000001 -0.0098 -0.0125 -0.044021 -0.0021213 -0.0125 -0.04190000000000001 -0.003 -0.0125 -0.040839 -0.0025607 -0.01415 -0.03977900000000001 -0.0021213 -0.0125 -0.0408395 -0.00256076 -0.013325 -0.03977900000000001 -0.0021213 -0.0125 -0.04190000000000001 -0.003 -0.0125 -0.0408395 -0.00256076 -0.013325 -0.04190000000000001 -0.003 -0.0125 -0.040839 -0.0025607 -0.01415 -0.0408395 -0.00256076 -0.013325 -0.039339 -0.0010607 -0.01415 -0.0389 0 -0.0158 -0.0391195 -0.00053035 -0.01415 -0.0389 0 -0.0158 -0.0389 0 -0.0125 -0.0391195 -0.00053035 -0.01415 -0.0389 0 -0.0125 -0.039339 -0.0010607 -0.01415 -0.0391195 -0.00053035 -0.01415 -0.039339 -0.0010607 -0.01415 -0.03977900000000001 -0.0021213 -0.0125 -0.039559 -0.001591 -0.01415 -0.03977900000000001 -0.0021213 -0.0125 -0.03977900000000001 -0.0021213 -0.0158 -0.039559 -0.001591 -0.01415 -0.03977900000000001 -0.0021213 -0.0158 -0.039339 -0.0010607 -0.01415 -0.039559 -0.001591 -0.01415 -0.039339 0.0010607 -0.01415 -0.03977900000000001 0.0021213 -0.0158 -0.039559 0.001591 -0.01415 -0.03977900000000001 0.0021213 -0.0158 -0.03977900000000001 0.0021213 -0.0125 -0.039559 0.001591 -0.01415 -0.03977900000000001 0.0021213 -0.0125 -0.039339 0.0010607 -0.01415 -0.039559 0.001591 -0.01415 -0.039339 0.0010607 -0.01415 -0.0389 0 -0.0125 -0.0391195 0.00053035 -0.01415 -0.0389 0 -0.0125 -0.0389 0 -0.0158 -0.0391195 0.00053035 -0.01415 -0.0389 0 -0.0158 -0.039339 0.0010607 -0.01415 -0.0391195 0.00053035 -0.01415 -0.0408395 0.00256076 -0.013325 -0.040839 0.0025607 -0.01415 -0.04190000000000001 0.003 -0.0125 -0.0408395 0.00256076 -0.013325 -0.04190000000000001 0.003 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.0408395 0.00256076 -0.013325 -0.03977900000000001 0.0021213 -0.0125 -0.040839 0.0025607 -0.01415 -0.044021 0.0021213 -0.0125 -0.05070000000000001 0.011 -0.0125 -0.04190000000000001 0.003 -0.0125 0.001999999999999997 0 0.0153 0.001999999999999997 -0.00835 0.0158 0.001999999999999997 -0.00835 0.0148 -0.05070000000000001 0.000599999 0 -0.05070000000000001 0.011 0.0125 -0.05070000000000001 0.0058 -7.806259999999999e-18 -0.05070000000000001 0.011 0.0125 -0.05070000000000001 0.011 -0.0125 -0.05070000000000001 0.0058 -7.806259999999999e-18 -0.05070000000000001 0.011 -0.0125 -0.05070000000000001 0.000599999 0 -0.05070000000000001 0.0058 -7.806259999999999e-18 0.001999999999999997 0.00835 0.0158 0.001999999999999997 0.00835 0.0148 -0.006000000000000004 0.009075 0.0153 0.001999999999999997 0.00835 0.0148 0.001999999999999997 0 0.0153 0.001999999999999997 -0.00835 0.0148 0.001999999999999997 -0.00835 0.0158 0.001999999999999997 0 0.0153 0.001999999999999997 0.00835 0.0158 -0.04087500000000001 -0.0024753 0.01415 -0.04190000000000001 -0.0029 0.0158 -0.04138750000000001 -0.00268765 0.01415 -0.04190000000000001 -0.0029 0.0158 -0.04190000000000001 -0.0029 0.0125 -0.04138750000000001 -0.00268765 0.01415 -0.04190000000000001 -0.0029 0.0125 -0.04087500000000001 -0.0024753 0.01415 -0.04138750000000001 -0.00268765 0.01415 -0.04087500000000001 -0.0024753 0.01415 -0.03984900000000001 -0.0020506 0.0125 -0.04036200000000001 -0.00226295 0.01415 -0.03984900000000001 -0.0020506 0.0125 -0.03984900000000001 -0.0020506 0.0158 -0.04036200000000001 -0.00226295 0.01415 -0.03984900000000001 -0.0020506 0.0158 -0.04087500000000001 -0.0024753 0.01415 -0.04036200000000001 -0.00226295 0.01415 -0.042925 -0.0024753 0.01415 -0.043951 -0.0020506 0.0125 -0.04292550000000001 -0.00247521 0.013325 -0.043951 -0.0020506 0.0125 -0.04190000000000001 -0.0029 0.0125 -0.04292550000000001 -0.00247521 0.013325 -0.04190000000000001 -0.0029 0.0125 -0.042925 -0.0024753 0.01415 -0.04292550000000001 -0.00247521 0.013325 -0.05070000000000001 -0.0098 0.0125 -0.043951 -0.0020506 0.0125 -0.05070000000000001 0.011 0.0125 -0.04480000000000001 0 0.0125 -0.043951 0.0020506 0.0125 -0.05070000000000001 0.011 0.0125 -0.042925 0.0024753 0.01415 -0.04190000000000001 0.0029 0.0125 -0.04292550000000001 0.00247521 0.013325 -0.04190000000000001 0.0029 0.0125 -0.043951 0.0020506 0.0125 -0.04292550000000001 0.00247521 0.013325 -0.043951 0.0020506 0.0125 -0.042925 0.0024753 0.01415 -0.04292550000000001 0.00247521 0.013325 -0.04087500000000001 0.0024753 0.01415 -0.03984900000000001 0.0020506 0.0158 -0.04036200000000001 0.00226295 0.01415 -0.03984900000000001 0.0020506 0.0158 -0.03984900000000001 0.0020506 0.0125 -0.04036200000000001 0.00226295 0.01415 -0.03984900000000001 0.0020506 0.0125 -0.04087500000000001 0.0024753 0.01415 -0.04036200000000001 0.00226295 0.01415 -0.04087500000000001 0.0024753 0.01415 -0.04190000000000001 0.0029 0.0125 -0.04138750000000001 0.00268765 0.01415 -0.04190000000000001 0.0029 0.0125 -0.04190000000000001 0.0029 0.0158 -0.04138750000000001 0.00268765 0.01415 -0.04190000000000001 0.0029 0.0158 -0.04087500000000001 0.0024753 0.01415 -0.04138750000000001 0.00268765 0.01415 -0.039425 0.0010253 0.01415 -0.03984900000000001 0.0020506 0.0158 -0.03942470000000001 0.00102521 0.014975 -0.03984900000000001 0.0020506 0.0158 -0.03900000000000001 0 0.0158 -0.03942470000000001 0.00102521 0.014975 -0.03900000000000001 0 0.0158 -0.039425 0.0010253 0.01415 -0.03942470000000001 0.00102521 0.014975 -0.039425 -0.0010253 0.01415 -0.03900000000000001 0 0.0158 -0.03942470000000001 -0.00102521 0.014975 -0.03900000000000001 0 0.0158 -0.03984900000000001 -0.0020506 0.0158 -0.03942470000000001 -0.00102521 0.014975 -0.03984900000000001 -0.0020506 0.0158 -0.039425 -0.0010253 0.01415 -0.03942470000000001 -0.00102521 0.014975 -0.05070000000000001 0.000599999 0 -0.05070000000000001 0.011 -0.0125 -0.05070000000000001 0.0005999999999999999 -0.00625 -0.05070000000000001 0.011 -0.0125 -0.05070000000000001 -0.0098 -0.0125 -0.05070000000000001 0.0005999999999999999 -0.00625 -0.05070000000000001 -0.0098 -0.0125 -0.05070000000000001 0.000599999 0 -0.05070000000000001 0.0005999999999999999 -0.00625 -0.05070000000000001 0.000599999 0 -0.05070000000000001 -0.0098 0.0125 -0.05070000000000001 0.0005999999999999999 0.00625 -0.05070000000000001 -0.0098 0.0125 -0.05070000000000001 0.011 0.0125 -0.05070000000000001 0.0005999999999999999 0.00625 -0.05070000000000001 0.011 0.0125 -0.05070000000000001 0.000599999 0 -0.05070000000000001 0.0005999999999999999 0.00625 -0.044021 -0.0021213 -0.0125 -0.05070000000000001 -0.0098 -0.0125 -0.05070000000000001 0.011 -0.0125 -0.0429605 -0.00256076 -0.013325 -0.042961 -0.0025607 -0.01415 -0.04190000000000001 -0.003 -0.0125 -0.0429605 -0.00256076 -0.013325 -0.04190000000000001 -0.003 -0.0125 -0.044021 -0.0021213 -0.0125 -0.0429605 -0.00256076 -0.013325 -0.044021 -0.0021213 -0.0125 -0.042961 -0.0025607 -0.01415 -0.040839 -0.0025607 -0.01415 -0.03977900000000001 -0.0021213 -0.0158 -0.040309 -0.002341 -0.01415 -0.03977900000000001 -0.0021213 -0.0158 -0.03977900000000001 -0.0021213 -0.0125 -0.040309 -0.002341 -0.01415 -0.03977900000000001 -0.0021213 -0.0125 -0.040839 -0.0025607 -0.01415 -0.040309 -0.002341 -0.01415 -0.040839 -0.0025607 -0.01415 -0.04190000000000001 -0.003 -0.0125 -0.0413695 -0.00278035 -0.01415 -0.04190000000000001 -0.003 -0.0125 -0.04190000000000001 -0.003 -0.0158 -0.0413695 -0.00278035 -0.01415 -0.04190000000000001 -0.003 -0.0158 -0.040839 -0.0025607 -0.01415 -0.0413695 -0.00278035 -0.01415 -0.039339 -0.0010607 -0.01415 -0.03977900000000001 -0.0021213 -0.0158 -0.03933930000000001 -0.00106074 -0.014975 -0.03977900000000001 -0.0021213 -0.0158 -0.0389 0 -0.0158 -0.03933930000000001 -0.00106074 -0.014975 -0.0389 0 -0.0158 -0.039339 -0.0010607 -0.01415 -0.03933930000000001 -0.00106074 -0.014975 -0.039339 0.0010607 -0.01415 -0.0389 0 -0.0158 -0.03933930000000001 0.00106074 -0.014975 -0.0389 0 -0.0158 -0.03977900000000001 0.0021213 -0.0158 -0.03933930000000001 0.00106074 -0.014975 -0.03977900000000001 0.0021213 -0.0158 -0.039339 0.0010607 -0.01415 -0.03933930000000001 0.00106074 -0.014975 -0.040839 0.0025607 -0.01415 -0.03977900000000001 0.0021213 -0.0125 -0.040309 0.002341 -0.01415 -0.03977900000000001 0.0021213 -0.0125 -0.03977900000000001 0.0021213 -0.0158 -0.040309 0.002341 -0.01415 -0.03977900000000001 0.0021213 -0.0158 -0.040839 0.0025607 -0.01415 -0.040309 0.002341 -0.01415 -0.040839 0.0025607 -0.01415 -0.04190000000000001 0.003 -0.0158 -0.0413695 0.00278035 -0.01415 -0.04190000000000001 0.003 -0.0158 -0.04190000000000001 0.003 -0.0125 -0.0413695 0.00278035 -0.01415 -0.04190000000000001 0.003 -0.0125 -0.040839 0.0025607 -0.01415 -0.0413695 0.00278035 -0.01415 -0.042961 0.0025607 -0.01415 -0.044021 0.0021213 -0.0125 -0.0429605 0.00256076 -0.013325 -0.044021 0.0021213 -0.0125 -0.04190000000000001 0.003 -0.0125 -0.0429605 0.00256076 -0.013325 -0.04190000000000001 0.003 -0.0125 -0.042961 0.0025607 -0.01415 -0.0429605 0.00256076 -0.013325 -0.044021 0.0021213 -0.0125 -0.04490000000000001 0 -0.0125 -0.05070000000000001 0.011 -0.0125 0.001999999999999997 0.00835 0.0148 0.001999999999999997 0.00835 0.0158 0.001999999999999997 0 0.0153 -0.04087450000000001 -0.00247521 0.014975 -0.04087500000000001 -0.0024753 0.01415 -0.03984900000000001 -0.0020506 0.0158 -0.04087450000000001 -0.00247521 0.014975 -0.03984900000000001 -0.0020506 0.0158 -0.04190000000000001 -0.0029 0.0158 -0.04087450000000001 -0.00247521 0.014975 -0.04190000000000001 -0.0029 0.0158 -0.04087500000000001 -0.0024753 0.01415 -0.042925 -0.0024753 0.01415 -0.04190000000000001 -0.0029 0.0125 -0.04241250000000001 -0.00268765 0.01415 -0.04190000000000001 -0.0029 0.0125 -0.04190000000000001 -0.0029 0.0158 -0.04241250000000001 -0.00268765 0.01415 -0.04190000000000001 -0.0029 0.0158 -0.042925 -0.0024753 0.01415 -0.04241250000000001 -0.00268765 0.01415 -0.042925 -0.0024753 0.01415 -0.043951 -0.0020506 0.0158 -0.043438 -0.00226295 0.01415 -0.043951 -0.0020506 0.0158 -0.043951 -0.0020506 0.0125 -0.043438 -0.00226295 0.01415 -0.043951 -0.0020506 0.0125 -0.042925 -0.0024753 0.01415 -0.043438 -0.00226295 0.01415 -0.043951 -0.0020506 0.0125 -0.04480000000000001 0 0.0125 -0.05070000000000001 0.011 0.0125 -0.04437530000000001 0.00102521 0.013325 -0.044375 0.0010253 0.01415 -0.043951 0.0020506 0.0125 -0.04437530000000001 0.00102521 0.013325 -0.043951 0.0020506 0.0125 -0.04480000000000001 0 0.0125 -0.04437530000000001 0.00102521 0.013325 -0.04480000000000001 0 0.0125 -0.044375 0.0010253 0.01415 -0.042925 0.0024753 0.01415 -0.04190000000000001 0.0029 0.0158 -0.04241250000000001 0.00268765 0.01415 -0.04190000000000001 0.0029 0.0158 -0.04190000000000001 0.0029 0.0125 -0.04241250000000001 0.00268765 0.01415 -0.04190000000000001 0.0029 0.0125 -0.042925 0.0024753 0.01415 -0.04241250000000001 0.00268765 0.01415 -0.042925 0.0024753 0.01415 -0.043951 0.0020506 0.0125 -0.043438 0.00226295 0.01415 -0.043951 0.0020506 0.0125 -0.043951 0.0020506 0.0158 -0.043438 0.00226295 0.01415 -0.043951 0.0020506 0.0158 -0.042925 0.0024753 0.01415 -0.043438 0.00226295 0.01415 -0.04087500000000001 0.0024753 0.01415 -0.04190000000000001 0.0029 0.0158 -0.04087450000000001 0.00247521 0.014975 -0.04190000000000001 0.0029 0.0158 -0.03984900000000001 0.0020506 0.0158 -0.04087450000000001 0.00247521 0.014975 -0.03984900000000001 0.0020506 0.0158 -0.04087500000000001 0.0024753 0.01415 -0.04087450000000001 0.00247521 0.014975 -0.03900000000000001 0 0.0158 -0.03984900000000001 0.0020506 0.0158 -0.04190000000000001 0 0.0158 -0.03984900000000001 -0.0020506 0.0158 -0.03900000000000001 0 0.0158 -0.04190000000000001 0 0.0158 -0.05070000000000001 0.011 -0.0125 -0.04490000000000001 0 -0.0125 -0.044021 -0.0021213 -0.0125 -0.042961 -0.0025607 -0.01415 -0.04190000000000001 -0.003 -0.0158 -0.04243050000000001 -0.00278035 -0.01415 -0.04190000000000001 -0.003 -0.0158 -0.04190000000000001 -0.003 -0.0125 -0.04243050000000001 -0.00278035 -0.01415 -0.04190000000000001 -0.003 -0.0125 -0.042961 -0.0025607 -0.01415 -0.04243050000000001 -0.00278035 -0.01415 -0.042961 -0.0025607 -0.01415 -0.044021 -0.0021213 -0.0125 -0.043491 -0.002341 -0.01415 -0.044021 -0.0021213 -0.0125 -0.044021 -0.0021213 -0.0158 -0.043491 -0.002341 -0.01415 -0.044021 -0.0021213 -0.0158 -0.042961 -0.0025607 -0.01415 -0.043491 -0.002341 -0.01415 -0.040839 -0.0025607 -0.01415 -0.04190000000000001 -0.003 -0.0158 -0.0408395 -0.00256076 -0.014975 -0.04190000000000001 -0.003 -0.0158 -0.03977900000000001 -0.0021213 -0.0158 -0.0408395 -0.00256076 -0.014975 -0.03977900000000001 -0.0021213 -0.0158 -0.040839 -0.0025607 -0.01415 -0.0408395 -0.00256076 -0.014975 -0.03977900000000001 -0.0021213 -0.0158 -0.04190000000000001 0 -0.0158 -0.0389 0 -0.0158 -0.0389 0 -0.0158 -0.04190000000000001 0 -0.0158 -0.03977900000000001 0.0021213 -0.0158 -0.0408395 0.00256076 -0.014975 -0.040839 0.0025607 -0.01415 -0.03977900000000001 0.0021213 -0.0158 -0.0408395 0.00256076 -0.014975 -0.03977900000000001 0.0021213 -0.0158 -0.04190000000000001 0.003 -0.0158 -0.0408395 0.00256076 -0.014975 -0.04190000000000001 0.003 -0.0158 -0.040839 0.0025607 -0.01415 -0.042961 0.0025607 -0.01415 -0.04190000000000001 0.003 -0.0125 -0.04243050000000001 0.00278035 -0.01415 -0.04190000000000001 0.003 -0.0125 -0.04190000000000001 0.003 -0.0158 -0.04243050000000001 0.00278035 -0.01415 -0.04190000000000001 0.003 -0.0158 -0.042961 0.0025607 -0.01415 -0.04243050000000001 0.00278035 -0.01415 -0.042961 0.0025607 -0.01415 -0.044021 0.0021213 -0.0158 -0.043491 0.002341 -0.01415 -0.044021 0.0021213 -0.0158 -0.044021 0.0021213 -0.0125 -0.043491 0.002341 -0.01415 -0.044021 0.0021213 -0.0125 -0.042961 0.0025607 -0.01415 -0.043491 0.002341 -0.01415 -0.044461 0.0010607 -0.01415 -0.04490000000000001 0 -0.0125 -0.04446070000000001 0.00106074 -0.013325 -0.04490000000000001 0 -0.0125 -0.044021 0.0021213 -0.0125 -0.04446070000000001 0.00106074 -0.013325 -0.044021 0.0021213 -0.0125 -0.044461 0.0010607 -0.01415 -0.04446070000000001 0.00106074 -0.013325 -0.04190000000000001 -0.0029 0.0158 -0.03984900000000001 -0.0020506 0.0158 -0.04190000000000001 0 0.0158 -0.042925 -0.0024753 0.01415 -0.04190000000000001 -0.0029 0.0158 -0.04292550000000001 -0.00247521 0.014975 -0.04190000000000001 -0.0029 0.0158 -0.043951 -0.0020506 0.0158 -0.04292550000000001 -0.00247521 0.014975 -0.043951 -0.0020506 0.0158 -0.042925 -0.0024753 0.01415 -0.04292550000000001 -0.00247521 0.014975 -0.044375 -0.0010253 0.01415 -0.043951 -0.0020506 0.0125 -0.04416300000000001 -0.00153795 0.01415 -0.043951 -0.0020506 0.0125 -0.043951 -0.0020506 0.0158 -0.04416300000000001 -0.00153795 0.01415 -0.043951 -0.0020506 0.0158 -0.044375 -0.0010253 0.01415 -0.04416300000000001 -0.00153795 0.01415 -0.044375 -0.0010253 0.01415 -0.04480000000000001 0 0.0125 -0.04437530000000001 -0.00102521 0.013325 -0.04480000000000001 0 0.0125 -0.043951 -0.0020506 0.0125 -0.04437530000000001 -0.00102521 0.013325 -0.043951 -0.0020506 0.0125 -0.044375 -0.0010253 0.01415 -0.04437530000000001 -0.00102521 0.013325 -0.044375 0.0010253 0.01415 -0.043951 0.0020506 0.0158 -0.04416300000000001 0.00153795 0.01415 -0.043951 0.0020506 0.0158 -0.043951 0.0020506 0.0125 -0.04416300000000001 0.00153795 0.01415 -0.043951 0.0020506 0.0125 -0.044375 0.0010253 0.01415 -0.04416300000000001 0.00153795 0.01415 -0.044375 0.0010253 0.01415 -0.04480000000000001 0 0.0125 -0.0445875 0.00051265 0.01415 -0.04480000000000001 0 0.0125 -0.04480000000000001 0 0.0158 -0.0445875 0.00051265 0.01415 -0.04480000000000001 0 0.0158 -0.044375 0.0010253 0.01415 -0.0445875 0.00051265 0.01415 -0.04292550000000001 0.00247521 0.014975 -0.042925 0.0024753 0.01415 -0.043951 0.0020506 0.0158 -0.04292550000000001 0.00247521 0.014975 -0.043951 0.0020506 0.0158 -0.04190000000000001 0.0029 0.0158 -0.04292550000000001 0.00247521 0.014975 -0.04190000000000001 0.0029 0.0158 -0.042925 0.0024753 0.01415 -0.04190000000000001 0 0.0158 -0.03984900000000001 0.0020506 0.0158 -0.04190000000000001 0.0029 0.0158 -0.044461 -0.0010607 -0.01415 -0.044021 -0.0021213 -0.0125 -0.04446070000000001 -0.00106074 -0.013325 -0.044021 -0.0021213 -0.0125 -0.04490000000000001 0 -0.0125 -0.04446070000000001 -0.00106074 -0.013325 -0.04490000000000001 0 -0.0125 -0.044461 -0.0010607 -0.01415 -0.04446070000000001 -0.00106074 -0.013325 -0.0429605 -0.00256076 -0.014975 -0.042961 -0.0025607 -0.01415 -0.044021 -0.0021213 -0.0158 -0.0429605 -0.00256076 -0.014975 -0.044021 -0.0021213 -0.0158 -0.04190000000000001 -0.003 -0.0158 -0.0429605 -0.00256076 -0.014975 -0.04190000000000001 -0.003 -0.0158 -0.042961 -0.0025607 -0.01415 -0.044461 -0.0010607 -0.01415 -0.044021 -0.0021213 -0.0158 -0.044241 -0.001591 -0.01415 -0.044021 -0.0021213 -0.0158 -0.044021 -0.0021213 -0.0125 -0.044241 -0.001591 -0.01415 -0.044021 -0.0021213 -0.0125 -0.044461 -0.0010607 -0.01415 -0.044241 -0.001591 -0.01415 -0.03977900000000001 -0.0021213 -0.0158 -0.04190000000000001 -0.003 -0.0158 -0.04190000000000001 0 -0.0158 -0.04190000000000001 0 -0.0158 -0.04190000000000001 0.003 -0.0158 -0.03977900000000001 0.0021213 -0.0158 -0.042961 0.0025607 -0.01415 -0.04190000000000001 0.003 -0.0158 -0.0429605 0.00256076 -0.014975 -0.04190000000000001 0.003 -0.0158 -0.044021 0.0021213 -0.0158 -0.0429605 0.00256076 -0.014975 -0.044021 0.0021213 -0.0158 -0.042961 0.0025607 -0.01415 -0.0429605 0.00256076 -0.014975 -0.044461 0.0010607 -0.01415 -0.044021 0.0021213 -0.0125 -0.044241 0.001591 -0.01415 -0.044021 0.0021213 -0.0125 -0.044021 0.0021213 -0.0158 -0.044241 0.001591 -0.01415 -0.044021 0.0021213 -0.0158 -0.044461 0.0010607 -0.01415 -0.044241 0.001591 -0.01415 -0.044461 0.0010607 -0.01415 -0.04490000000000001 0 -0.0158 -0.0446805 0.00053035 -0.01415 -0.04490000000000001 0 -0.0158 -0.04490000000000001 0 -0.0125 -0.0446805 0.00053035 -0.01415 -0.04490000000000001 0 -0.0125 -0.044461 0.0010607 -0.01415 -0.0446805 0.00053035 -0.01415 -0.04190000000000001 -0.0029 0.0158 -0.04190000000000001 0 0.0158 -0.043951 -0.0020506 0.0158 -0.044375 -0.0010253 0.01415 -0.043951 -0.0020506 0.0158 -0.04437530000000001 -0.00102521 0.014975 -0.043951 -0.0020506 0.0158 -0.04480000000000001 0 0.0158 -0.04437530000000001 -0.00102521 0.014975 -0.04480000000000001 0 0.0158 -0.044375 -0.0010253 0.01415 -0.04437530000000001 -0.00102521 0.014975 -0.044375 -0.0010253 0.01415 -0.04480000000000001 0 0.0158 -0.0445875 -0.00051265 0.01415 -0.04480000000000001 0 0.0158 -0.04480000000000001 0 0.0125 -0.0445875 -0.00051265 0.01415 -0.04480000000000001 0 0.0125 -0.044375 -0.0010253 0.01415 -0.0445875 -0.00051265 0.01415 -0.044375 0.0010253 0.01415 -0.04480000000000001 0 0.0158 -0.04437530000000001 0.00102521 0.014975 -0.04480000000000001 0 0.0158 -0.043951 0.0020506 0.0158 -0.04437530000000001 0.00102521 0.014975 -0.043951 0.0020506 0.0158 -0.044375 0.0010253 0.01415 -0.04437530000000001 0.00102521 0.014975 -0.04190000000000001 0 0.0158 -0.04190000000000001 0.0029 0.0158 -0.043951 0.0020506 0.0158 -0.044461 -0.0010607 -0.01415 -0.04490000000000001 0 -0.0125 -0.0446805 -0.00053035 -0.01415 -0.04490000000000001 0 -0.0125 -0.04490000000000001 0 -0.0158 -0.0446805 -0.00053035 -0.01415 -0.04490000000000001 0 -0.0158 -0.044461 -0.0010607 -0.01415 -0.0446805 -0.00053035 -0.01415 -0.04190000000000001 -0.003 -0.0158 -0.044021 -0.0021213 -0.0158 -0.04190000000000001 0 -0.0158 -0.044461 -0.0010607 -0.01415 -0.04490000000000001 0 -0.0158 -0.04446070000000001 -0.00106074 -0.014975 -0.04490000000000001 0 -0.0158 -0.044021 -0.0021213 -0.0158 -0.04446070000000001 -0.00106074 -0.014975 -0.044021 -0.0021213 -0.0158 -0.044461 -0.0010607 -0.01415 -0.04446070000000001 -0.00106074 -0.014975 -0.04190000000000001 0 -0.0158 -0.044021 0.0021213 -0.0158 -0.04190000000000001 0.003 -0.0158 -0.04446070000000001 0.00106074 -0.014975 -0.044461 0.0010607 -0.01415 -0.044021 0.0021213 -0.0158 -0.04446070000000001 0.00106074 -0.014975 -0.044021 0.0021213 -0.0158 -0.04490000000000001 0 -0.0158 -0.04446070000000001 0.00106074 -0.014975 -0.04490000000000001 0 -0.0158 -0.044461 0.0010607 -0.01415 -0.043951 -0.0020506 0.0158 -0.04190000000000001 0 0.0158 -0.04480000000000001 0 0.0158 -0.04480000000000001 0 0.0158 -0.04190000000000001 0 0.0158 -0.043951 0.0020506 0.0158 -0.044021 -0.0021213 -0.0158 -0.04490000000000001 0 -0.0158 -0.04190000000000001 0 -0.0158 -0.04190000000000001 0 -0.0158 -0.04490000000000001 0 -0.0158 -0.044021 0.0021213 -0.0158 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265

    -
    -
    - - - -3.469446951953614e-18 0 0 - 1 0 0 0 - - true - - - -
    - - - - -0.004453999999999993 -0.0072397 0.0148 -0.01722999999999999 0.00062 0.0153 -0.03000599999999999 0.0084797 0.0148 -0.03000599999999999 0.0084797 0.0158 -0.03000599999999999 0.0084797 0.0148 -0.01722999999999999 0.00062 0.0153 -0.03000599999999999 0.0084797 0.0148 -0.03000799999999999 0.0119797 0.0148 -0.004453999999999993 -0.0072397 0.0148 -0.004453999999999993 -0.0072397 0.0158 -0.01722999999999999 0.00062 0.0153 -0.004453999999999993 -0.0072397 0.0148 -0.03000599999999999 0.0084797 0.0158 -0.01722999999999999 0.00062 0.0153 -0.004453999999999993 -0.0072397 0.0158 -0.03000599999999999 0.0084797 0.0148 -0.03000599999999999 0.0084797 0.0158 -0.03000799999999999 0.0119797 0.0148 -0.03000799999999999 0.0119797 0.0148 -0.003496999999999993 -0.0077473 0.0148 -0.004453999999999993 -0.0072397 0.0148 -0.003975989999999993 -0.0074935 0.0153 -0.004453999999999993 -0.0072397 0.0158 -0.004214999999999993 -0.0073666 0.0153 -0.004453999999999993 -0.0072397 0.0158 -0.004453999999999993 -0.0072397 0.0148 -0.004214999999999993 -0.0073666 0.0153 -0.004453999999999993 -0.0072397 0.0148 -0.003975989999999993 -0.0074935 0.0153 -0.004214999999999993 -0.0073666 0.0153 -0.03000599999999999 0.0084797 0.0158 -0.004453999999999993 -0.0072397 0.0158 -0.03000899999999999 0.0129797 0.0158 -0.03000799999999999 0.0119797 0.0148 -0.03000599999999999 0.0084797 0.0158 -0.03000899999999999 0.0129797 0.0158 -0.003975989999999993 -0.0074935 0.0153 -0.004453999999999993 -0.0072397 0.0148 -0.003975549999999993 -0.0074936 0.01505 -0.004453999999999993 -0.0072397 0.0148 -0.003496999999999993 -0.0077473 0.0148 -0.003975549999999993 -0.0074936 0.01505 -0.003496999999999993 -0.0077473 0.0148 -0.003975989999999993 -0.0074935 0.0153 -0.003975549999999993 -0.0074936 0.01505 -0.003496999999999993 -0.0077473 0.0148 -0.03000799999999999 0.0119797 0.0148 -0.01000599999999999 0.008493199999999999 0.0148 -0.003975549999999993 -0.0074936 0.01555 -0.003975989999999993 -0.0074935 0.0153 -0.003496999999999993 -0.0077473 0.0158 -0.003975549999999993 -0.0074936 0.01555 -0.003496999999999993 -0.0077473 0.0158 -0.004453999999999993 -0.0072397 0.0158 -0.003975549999999993 -0.0074936 0.01555 -0.004453999999999993 -0.0072397 0.0158 -0.003975989999999993 -0.0074935 0.0153 -0.004453999999999993 -0.0072397 0.0158 -0.003496999999999993 -0.0077473 0.0158 -0.03000899999999999 0.0129797 0.0158 -0.03000899999999999 0.0129797 -0.0158 -0.03000799999999999 0.0119797 0.0148 -0.03000899999999999 0.0129797 0.0158 -0.003975989999999993 -0.0074935 0.0153 -0.003496999999999993 -0.0077473 0.0148 -0.003736499999999993 -0.0076204 0.0153 -0.003496999999999993 -0.0077473 0.0148 -0.003496999999999993 -0.0077473 0.0158 -0.003736499999999993 -0.0076204 0.0153 -0.003496999999999993 -0.0077473 0.0158 -0.003975989999999993 -0.0074935 0.0153 -0.003736499999999993 -0.0076204 0.0153 -0.003496999999999993 -0.0077473 0.0148 -0.01000599999999999 0.008493199999999999 0.0148 0.01273690000000001 0.0085086 0.0148 -0.01000599999999999 0.008493199999999999 0.0148 -0.03000799999999999 0.0119797 0.0148 -0.01000799999999999 0.0119932 0.0148 -0.003496999999999993 -0.0077473 0.0158 -0.01000599999999999 0.008493199999999999 0.0158 -0.03000899999999999 0.0129797 0.0158 -0.03000899999999999 0.0129797 0.0158 -0.02886979999999999 0.0129805 0.014 -0.02999999999999999 0.0129797 0.014 -0.02999999999999999 0.0129797 -0.014 -0.02886979999999999 0.0129805 -0.014 -0.03000899999999999 0.0129797 -0.0158 -0.02999999999999999 0.0129797 0.014 -0.03000899999999999 0.0129797 -0.0158 -0.03000899999999999 0.0129797 0.0158 -0.02999999999999999 0.0129797 0.00228598 -0.03000899999999999 0.0129797 -0.0158 -0.02999999999999999 0.0129797 0.014 -0.02999999999999999 0.0129797 0.00228598 -0.03000899999999999 0.0129797 -0.0158 -0.02999999999999999 0.0129797 0 -0.02999999999999999 0.0129797 -0.011714 -0.03000899999999999 0.0129797 -0.0158 -0.02999999999999999 0.0129797 0 -0.02999999999999999 0.0129797 -0.011714 -0.03000899999999999 0.0129797 -0.0158 -0.02999999999999999 0.0129797 -0.014 -0.03000899999999999 0.0129797 -0.0158 -0.03000799999999999 0.0119797 -0.0148 -0.03000799999999999 0.0119797 0.0148 -0.003496999999999993 -0.0077473 0.0148 0.004620000000000007 0.000380699 0.0153 -0.003496999999999993 -0.0077473 0.0158 0.01273690000000001 0.0085086 0.0148 0.004620000000000007 0.000380699 0.0153 -0.003496999999999993 -0.0077473 0.0148 -0.01000599999999999 0.008493199999999999 0.0148 0.001366000000000007 0.0085009 0.0153 0.01273690000000001 0.0085086 0.0148 -0.01000599999999999 0.008493199999999999 0.0148 -0.01000799999999999 0.0119932 0.0148 -0.01000599999999999 0.008493199999999999 0.0158 -0.02000799999999999 0.0119865 0 -0.01000799999999999 0.0119932 0.0148 -0.02000799999999999 0.0119865 0.0074 -0.01000799999999999 0.0119932 0.0148 -0.03000799999999999 0.0119797 0.0148 -0.02000799999999999 0.0119865 0.0074 -0.03000799999999999 0.0119797 0.0148 -0.02000799999999999 0.0119865 0 -0.02000799999999999 0.0119865 0.0074 -0.01000599999999999 0.008493199999999999 0.0158 -0.01000899999999999 0.0129932 0.0158 -0.03000899999999999 0.0129797 0.0158 -0.003496999999999993 -0.0077473 0.0158 0.01273690000000001 0.0085086 0.0158 -0.01000599999999999 0.008493199999999999 0.0158 -0.02247719999999999 0.0129848 -0.014 -0.03000899999999999 0.0129797 -0.0158 -0.02886979999999999 0.0129805 -0.014 -0.01000899999999999 0.0129932 -0.0158 -0.01348629999999999 0.0129909 -0.014 -0.01199999999999999 0.0129919 -0.014 -0.01000899999999999 0.0129932 -0.0158 -0.01199999999999999 0.0129919 -0.014 -0.01199999999999999 0.0129919 -0.0126542 -0.02000899999999999 0.0129865 -0.0142271 -0.02099999999999999 0.0129858 -0.014 -0.01348629999999999 0.0129909 -0.014 -0.02000899999999999 0.0129865 -0.0142271 -0.02247719999999999 0.0129848 -0.014 -0.02099999999999999 0.0129858 -0.014 -0.02000899999999999 0.0129865 -0.0142271 -0.01000899999999999 0.0129932 -0.0158 -0.03000899999999999 0.0129797 -0.0158 -0.02000899999999999 0.0129865 -0.0142271 -0.03000899999999999 0.0129797 -0.0158 -0.02247719999999999 0.0129848 -0.014 -0.02000899999999999 0.0129865 -0.0142271 -0.01348629999999999 0.0129909 -0.014 -0.01000899999999999 0.0129932 -0.0158 -0.01199999999999999 0.0129919 0.014 -0.01000899999999999 0.0129932 0.0158 -0.01199999999999999 0.0129919 0.0126542 -0.01000899999999999 0.0129932 0.0158 -0.01199999999999999 0.0129919 0.014 -0.01951979999999999 0.0129868 0.014 -0.03000899999999999 0.0129797 0.0158 -0.02099999999999999 0.0129858 0.014 -0.02852889999999999 0.0129807 0.014 -0.03000899999999999 0.0129797 0.0158 -0.02852889999999999 0.0129807 0.014 -0.02886979999999999 0.0129805 0.014 -0.01951979999999999 0.0129868 0.014 -0.02099999999999999 0.0129858 0.014 -0.02000899999999999 0.0129865 0.0142271 -0.03000899999999999 0.0129797 0.0158 -0.01000899999999999 0.0129932 0.0158 -0.02000899999999999 0.0129865 0.0142271 -0.01000899999999999 0.0129932 0.0158 -0.01951979999999999 0.0129868 0.014 -0.02000899999999999 0.0129865 0.0142271 -0.02099999999999999 0.0129858 0.014 -0.03000899999999999 0.0129797 0.0158 -0.02000899999999999 0.0129865 0.0142271 -0.03000599999999999 0.0084797 -0.0158 -0.03000799999999999 0.0119797 -0.0148 -0.03000899999999999 0.0129797 -0.0158 -0.02000799999999999 0.0119865 0 -0.03000799999999999 0.0119797 0.0148 -0.02500799999999999 0.0119831 8.67362e-19 -0.03000799999999999 0.0119797 0.0148 -0.03000799999999999 0.0119797 -0.0148 -0.02500799999999999 0.0119831 8.67362e-19 -0.03000799999999999 0.0119797 -0.0148 -0.02000799999999999 0.0119865 0 -0.02500799999999999 0.0119831 8.67362e-19 -0.003496999999999993 -0.0077473 0.0158 0.004620000000000007 0.000380699 0.0153 0.01273690000000001 0.0085086 0.0158 0.01273690000000001 0.0085086 0.0148 0.01273690000000001 0.0085086 0.0158 0.004620000000000007 0.000380699 0.0153 0.01273690000000001 0.0085086 0.0158 0.01273690000000001 0.0085086 0.0148 0.001366000000000007 0.0085009 0.0153 -0.01000599999999999 0.008493199999999999 0.0158 0.001366000000000007 0.0085009 0.0153 -0.01000599999999999 0.008493199999999999 0.0148 -0.01000799999999999 0.0119932 0.0148 -0.01000899999999999 0.0129932 0.0158 -0.01000599999999999 0.008493199999999999 0.0158 -0.02000799999999999 0.0119865 0 -0.01000799999999999 0.0119932 -0.0148 -0.01500799999999999 0.0119898 -8.67362e-19 -0.01000799999999999 0.0119932 -0.0148 -0.01000799999999999 0.0119932 0.0148 -0.01500799999999999 0.0119898 -8.67362e-19 -0.01000799999999999 0.0119932 0.0148 -0.02000799999999999 0.0119865 0 -0.01500799999999999 0.0119898 -8.67362e-19 0.01273690000000001 0.0085086 0.0158 0.001366000000000007 0.0085009 0.0153 -0.01000599999999999 0.008493199999999999 0.0158 -0.01000599999999999 0.008493199999999999 -0.0158 -0.03000899999999999 0.0129797 -0.0158 -0.01000899999999999 0.0129932 -0.0158 -0.01199999999999999 0.0129919 0.0126542 -0.01000899999999999 0.0129932 0.0158 -0.01199999999999999 0.0129919 0.0116856 -0.01199999999999999 0.0129919 -0.0126542 -0.01199999999999999 0.0129919 -0.00231435 -0.01000899999999999 0.0129932 -0.0158 -0.01000899999999999 0.0129932 0.0158 -0.01000899999999999 0.0129932 -0.0158 -0.01100449999999999 0.0129925 0 -0.01199999999999999 0.0129919 -0.00231435 -0.01199999999999999 0.0129919 0 -0.01100449999999999 0.0129925 0 -0.01199999999999999 0.0129919 0 -0.01199999999999999 0.0129919 0.0116856 -0.01100449999999999 0.0129925 0 -0.01199999999999999 0.0129919 0.0116856 -0.01000899999999999 0.0129932 0.0158 -0.01100449999999999 0.0129925 0 -0.01000899999999999 0.0129932 -0.0158 -0.01199999999999999 0.0129919 -0.00231435 -0.01100449999999999 0.0129925 0 -0.03000599999999999 0.0084797 -0.0158 -0.03000899999999999 0.0129797 -0.0158 -0.004453999999999993 -0.0072397 -0.0158 -0.03000599999999999 0.0084797 -0.0158 -0.03000599999999999 0.0084797 -0.0148 -0.03000799999999999 0.0119797 -0.0148 -0.02000799999999999 0.0119865 0 -0.03000799999999999 0.0119797 -0.0148 -0.02000799999999999 0.0119865 -0.0074 -0.03000799999999999 0.0119797 -0.0148 -0.01000799999999999 0.0119932 -0.0148 -0.02000799999999999 0.0119865 -0.0074 -0.01000799999999999 0.0119932 -0.0148 -0.02000799999999999 0.0119865 0 -0.02000799999999999 0.0119865 -0.0074 -0.01000899999999999 0.0129932 -0.0158 -0.01000899999999999 0.0129932 0.0158 -0.01000799999999999 0.0119932 0.0148 -0.01000799999999999 0.0119932 -0.0148 -0.01000899999999999 0.0129932 -0.0158 -0.01000799999999999 0.0119932 0.0148 -0.01000599999999999 0.008493199999999999 -0.0158 -0.01000899999999999 0.0129932 -0.0158 -0.01000599999999999 0.008493199999999999 -0.0148 -0.003496999999999993 -0.0077473 -0.0158 -0.03000899999999999 0.0129797 -0.0158 -0.01000599999999999 0.008493199999999999 -0.0158 -0.01722999999999999 0.00062 -0.0153 -0.03000599999999999 0.0084797 -0.0158 -0.004453999999999993 -0.0072397 -0.0158 -0.03000899999999999 0.0129797 -0.0158 -0.003496999999999993 -0.0077473 -0.0158 -0.004453999999999993 -0.0072397 -0.0158 -0.03000599999999999 0.0084797 -0.0148 -0.03000599999999999 0.0084797 -0.0158 -0.01722999999999999 0.00062 -0.0153 -0.03000599999999999 0.0084797 -0.0148 -0.004453999999999993 -0.0072397 -0.0148 -0.03000799999999999 0.0119797 -0.0148 -0.01000599999999999 0.008493199999999999 -0.0148 -0.01000799999999999 0.0119932 -0.0148 -0.03000799999999999 0.0119797 -0.0148 -0.01000899999999999 0.0129932 -0.0158 -0.01000799999999999 0.0119932 -0.0148 -0.01000599999999999 0.008493199999999999 -0.0148 -0.01000599999999999 0.008493199999999999 -0.0148 0.001366000000000007 0.0085009 -0.0153 -0.01000599999999999 0.008493199999999999 -0.0158 -0.003496999999999993 -0.0077473 -0.0158 -0.01000599999999999 0.008493199999999999 -0.0158 0.01273690000000001 0.0085086 -0.0158 -0.004453999999999993 -0.0072397 -0.0148 -0.01722999999999999 0.00062 -0.0153 -0.004453999999999993 -0.0072397 -0.0158 -0.003975549999999993 -0.0074936 -0.01555 -0.003975989999999993 -0.0074935 -0.0153 -0.004453999999999993 -0.0072397 -0.0158 -0.003975549999999993 -0.0074936 -0.01555 -0.004453999999999993 -0.0072397 -0.0158 -0.003496999999999993 -0.0077473 -0.0158 -0.003975549999999993 -0.0074936 -0.01555 -0.003496999999999993 -0.0077473 -0.0158 -0.003975989999999993 -0.0074935 -0.0153 -0.03000599999999999 0.0084797 -0.0148 -0.01722999999999999 0.00062 -0.0153 -0.004453999999999993 -0.0072397 -0.0148 -0.004453999999999993 -0.0072397 -0.0148 -0.003496999999999993 -0.0077473 -0.0148 -0.03000799999999999 0.0119797 -0.0148 -0.003496999999999993 -0.0077473 -0.0148 -0.01000599999999999 0.008493199999999999 -0.0148 -0.03000799999999999 0.0119797 -0.0148 -0.01000599999999999 0.008493199999999999 -0.0158 0.001366000000000007 0.0085009 -0.0153 0.01273690000000001 0.0085086 -0.0158 0.01273690000000001 0.0085086 -0.0148 0.001366000000000007 0.0085009 -0.0153 -0.01000599999999999 0.008493199999999999 -0.0148 0.01273690000000001 0.0085086 -0.0158 0.004620000000000007 0.000380699 -0.0153 -0.003496999999999993 -0.0077473 -0.0158 -0.003975989999999993 -0.0074935 -0.0153 -0.004453999999999993 -0.0072397 -0.0148 -0.004214999999999993 -0.0073666 -0.0153 -0.004453999999999993 -0.0072397 -0.0148 -0.004453999999999993 -0.0072397 -0.0158 -0.004214999999999993 -0.0073666 -0.0153 -0.004453999999999993 -0.0072397 -0.0158 -0.003975989999999993 -0.0074935 -0.0153 -0.004214999999999993 -0.0073666 -0.0153 -0.003975989999999993 -0.0074935 -0.0153 -0.003496999999999993 -0.0077473 -0.0158 -0.003736499999999993 -0.0076204 -0.0153 -0.003496999999999993 -0.0077473 -0.0158 -0.003496999999999993 -0.0077473 -0.0148 -0.003736499999999993 -0.0076204 -0.0153 -0.003496999999999993 -0.0077473 -0.0148 -0.003975989999999993 -0.0074935 -0.0153 -0.003736499999999993 -0.0076204 -0.0153 -0.003975549999999993 -0.0074936 -0.01505 -0.003975989999999993 -0.0074935 -0.0153 -0.003496999999999993 -0.0077473 -0.0148 -0.003975549999999993 -0.0074936 -0.01505 -0.003496999999999993 -0.0077473 -0.0148 -0.004453999999999993 -0.0072397 -0.0148 -0.003975549999999993 -0.0074936 -0.01505 -0.004453999999999993 -0.0072397 -0.0148 -0.003975989999999993 -0.0074935 -0.0153 -0.003496999999999993 -0.0077473 -0.0148 0.01273690000000001 0.0085086 -0.0148 -0.01000599999999999 0.008493199999999999 -0.0148 0.01273690000000001 0.0085086 -0.0148 0.01273690000000001 0.0085086 -0.0158 0.001366000000000007 0.0085009 -0.0153 -0.003496999999999993 -0.0077473 -0.0158 0.004620000000000007 0.000380699 -0.0153 -0.003496999999999993 -0.0077473 -0.0148 0.01273690000000001 0.0085086 -0.0148 0.004620000000000007 0.000380699 -0.0153 0.01273690000000001 0.0085086 -0.0158 0.004620000000000007 0.000380699 -0.0153 0.01273690000000001 0.0085086 -0.0148 -0.003496999999999993 -0.0077473 -0.0148 -0.02886979999999999 0.0129805 -0.014 -0.02999999999999999 0.0129797 -0.014 -0.02999999999999999 0.018 -0.014 -0.02886979999999999 0.0129805 -0.014 -0.02999999999999999 0.018 -0.014 -0.02247719999999999 0.0129848 -0.014 -0.02999999999999999 0.0129797 0.014 -0.02886979999999999 0.0129805 0.014 -0.02999999999999999 0.018 0.014 -0.02886979999999999 0.0129805 0.014 -0.02852889999999999 0.0129807 0.014 -0.02999999999999999 0.018 0.014 -0.02852889999999999 0.0129807 0.014 -0.02099999999999999 0.018 0.014 -0.02999999999999999 0.018 0.014 -0.02999999999999999 0.018 0.014 -0.02999999999999999 0.0129797 0.00228598 -0.02999999999999999 0.0129797 0.014 -0.02999999999999999 0.018 0 -0.02999999999999999 0.0129797 0 -0.02999999999999999 0.0129797 0.00228598 -0.02999999999999999 0.018 0 -0.02999999999999999 0.0129797 0.00228598 -0.02999999999999999 0.018 0.014 -0.02999999999999999 0.018 0 -0.02999999999999999 0.0129797 -0.011714 -0.02999999999999999 0.0129797 0 -0.02999999999999999 0.018 -0.014 -0.02999999999999999 0.0129797 -0.014 -0.02999999999999999 0.0129797 -0.011714 -0.02999999999999999 0.018 -0.014 -0.02999999999999999 0.0129797 -0.011714 -0.02999999999999999 0.018 0 -0.02247719999999999 0.0129848 -0.014 -0.02999999999999999 0.018 -0.014 -0.02099999999999999 0.018 -0.014 -0.02099999999999999 0.0129858 -0.014 -0.02247719999999999 0.0129848 -0.014 -0.02099999999999999 0.018 -0.014 -0.01348629999999999 0.0129909 -0.014 -0.02099999999999999 0.018 -0.014 -0.01199999999999999 0.018 -0.014 -0.01199999999999999 0.0129919 -0.014 -0.01348629999999999 0.0129909 -0.014 -0.01199999999999999 0.018 -0.014 -0.02099999999999999 0.0129858 -0.014 -0.02099999999999999 0.018 -0.014 -0.01348629999999999 0.0129909 -0.014 -0.01199999999999999 0.018 -0.014 -0.01199999999999999 0.0129919 -0.00231435 -0.01199999999999999 0.0129919 -0.0126542 -0.01199999999999999 0.018 -0.014 -0.01199999999999999 0.0129919 -0.0126542 -0.01199999999999999 0.0129919 -0.014 -0.01199999999999999 0.0129919 0.014 -0.01199999999999999 0.018 0.014 -0.01951979999999999 0.0129868 0.014 -0.02099999999999999 0.0129858 0.014 -0.01951979999999999 0.0129868 0.014 -0.02099999999999999 0.018 0.014 -0.01951979999999999 0.0129868 0.014 -0.01199999999999999 0.018 0.014 -0.02099999999999999 0.018 0.014 -0.02099999999999999 0.0129858 0.014 -0.02099999999999999 0.018 0.014 -0.02852889999999999 0.0129807 0.014 -0.01199999999999999 0.018 0.014 -0.01199999999999999 0.0129919 0.014 -0.01199999999999999 0.0129919 0.0126542 -0.01199999999999999 0.018 0.014 -0.01199999999999999 0.0129919 0.0126542 -0.01199999999999999 0.0129919 0.0116856 -0.01199999999999999 0.018 0.014 -0.01199999999999999 0.0129919 0.0116856 -0.01199999999999999 0.018 0 -0.02999999999999999 0.018 0.014 -0.02099999999999999 0.018 0.014 -0.02999999999999999 0.018 0 -0.02999999999999999 0.018 -0.014 -0.02999999999999999 0.018 0 -0.02099999999999999 0.018 -0.014 -0.02099999999999999 0.018 -0.014 -0.01199999999999999 0.018 0 -0.01199999999999999 0.018 -0.014 -0.01199999999999999 0.018 0 -0.01199999999999999 0.0129919 0 -0.01199999999999999 0.0129919 -0.00231435 -0.01199999999999999 0.018 0 -0.01199999999999999 0.0129919 -0.00231435 -0.01199999999999999 0.018 -0.014 -0.01199999999999999 0.018 0 -0.01199999999999999 0.0129919 0.0116856 -0.01199999999999999 0.0129919 0 -0.02099999999999999 0.018 0.014 -0.01199999999999999 0.018 0.014 -0.01199999999999999 0.018 0 -0.01199999999999999 0.018 0 -0.02999999999999999 0.018 0 -0.02099999999999999 0.018 0.007 -0.02999999999999999 0.018 0 -0.02099999999999999 0.018 0.014 -0.02099999999999999 0.018 0.007 -0.02099999999999999 0.018 0.014 -0.01199999999999999 0.018 0 -0.02099999999999999 0.018 0.007 -0.02999999999999999 0.018 0 -0.01199999999999999 0.018 0 -0.02099999999999999 0.018 -0.007 -0.01199999999999999 0.018 0 -0.02099999999999999 0.018 -0.014 -0.02099999999999999 0.018 -0.007 -0.02099999999999999 0.018 -0.014 -0.02999999999999999 0.018 0 -0.02099999999999999 0.018 -0.007 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479

    -
    -
    - - - 6.938893903907228e-18 0 0 - 1 0 0 0 - - true - - - -
    - - - - 0.001999999999999997 0.00835 -0.0148 0.001999999999999997 0 -0.0153 0.001999999999999997 0.00835 -0.0158 0.001999999999999997 0 -0.0153 0.001999999999999997 0.00835 -0.0148 0.001999999999999997 -0.00835 -0.0148 -0.006000000000000004 0.009075 -0.0153 0.001999999999999997 0.00835 -0.0148 0.001999999999999997 0.00835 -0.0158 0.001999999999999997 0 -0.0153 0.001999999999999997 -0.00835 -0.0158 0.001999999999999997 0.00835 -0.0158 0.001999999999999997 -0.00835 -0.0148 0.001999999999999997 -0.00835 -0.0158 0.001999999999999997 0 -0.0153 0.001999999999999997 0.00835 -0.0148 -0.006000000000000004 0 -0.0148 -0.002000000000000004 0 -0.0148 0.001999999999999997 -0.00835 -0.0148 0.001999999999999997 0.00835 -0.0148 -0.002000000000000004 0 -0.0148 -0.006000000000000004 0 -0.0148 0.001999999999999997 -0.00835 -0.0148 -0.002000000000000004 0 -0.0148 -0.014 0.0098 -0.0158 -0.006000000000000004 0.009075 -0.0153 0.001999999999999997 0.00835 -0.0158 -0.006000000000000004 0.009075 -0.0153 -0.014 0.0098 -0.0148 0.001999999999999997 0.00835 -0.0148 0.001999999999999997 -0.00835 -0.0158 -0.009000000000000003 0 -0.0158 -0.003500000000000004 2.60209e-17 -0.0158 0.001999999999999997 0.00835 -0.0158 0.001999999999999997 -0.00835 -0.0158 -0.003500000000000004 2.60209e-17 -0.0158 -0.009000000000000003 0 -0.0158 0.001999999999999997 0.00835 -0.0158 -0.003500000000000004 2.60209e-17 -0.0158 0.001999999999999997 -0.00835 -0.0158 0.001999999999999997 -0.00835 -0.0148 -0.006000000000000004 -0.009075 -0.0153 -0.014 0.0098 -0.0148 -0.006000000000000004 0 -0.0148 -0.006000000000000004 0.0049 -0.0148 0.001999999999999997 0.00835 -0.0148 -0.014 0.0098 -0.0148 -0.006000000000000004 0.0049 -0.0148 -0.006000000000000004 0 -0.0148 0.001999999999999997 0.00835 -0.0148 -0.006000000000000004 0.0049 -0.0148 0.001999999999999997 -0.00835 -0.0148 -0.006000000000000004 0 -0.0148 -0.006000000000000004 -0.0049 -0.0148 -0.014 -0.0098 -0.0148 0.001999999999999997 -0.00835 -0.0148 -0.006000000000000004 -0.0049 -0.0148 -0.006000000000000004 0 -0.0148 -0.014 -0.0098 -0.0148 -0.006000000000000004 -0.0049 -0.0148 -0.014 0.0098 -0.0158 -0.014 0.0098 -0.0148 -0.006000000000000004 0.009075 -0.0153 -0.009000000000000003 0 -0.0158 -0.014 0.0098 -0.0158 0.001999999999999997 0.00835 -0.0158 -0.014 -0.0098 -0.0158 -0.009000000000000003 0 -0.0158 0.001999999999999997 -0.00835 -0.0158 -0.006000000000000004 -0.009075 -0.0153 0.001999999999999997 -0.00835 -0.0148 -0.014 -0.0098 -0.0148 0.001999999999999997 -0.00835 -0.0158 -0.006000000000000004 -0.009075 -0.0153 -0.014 -0.0098 -0.0158 -0.014 -0.0098 -0.0148 -0.006000000000000004 0 -0.0148 -0.01 -6.93889e-18 -0.0148 -0.014 0.0098 -0.0148 -0.014 -0.0098 -0.0148 -0.01 -6.93889e-18 -0.0148 -0.006000000000000004 0 -0.0148 -0.014 0.0098 -0.0148 -0.01 -6.93889e-18 -0.0148 -0.0143333 0.0098 0 -0.014 0.0098 -0.0148 -0.014 0.0098 -0.0158 -0.015 0.0098 -0.0158 -0.014 0.0098 -0.0158 -0.009000000000000003 0 -0.0158 -0.015 -0.0098 -0.0158 -0.009000000000000003 0 -0.0158 -0.014 -0.0098 -0.0158 -0.006000000000000004 -0.009075 -0.0153 -0.014 -0.0098 -0.0148 -0.014 -0.0098 -0.0158 -0.014 0.0098 -0.0148 -0.014 0 0 -0.014 0 -0.0074 -0.014 -0.0098 -0.0148 -0.014 0.0098 -0.0148 -0.014 0 -0.0074 -0.014 0 0 -0.014 -0.0098 -0.0148 -0.014 0 -0.0074 -0.014 0.0098 -0.0158 -0.015 0.0098 -0.0158 -0.0143333 0.0098 0 -0.0143333 0.0098 0 -0.014 0.0098 0.0148 -0.014 0.0098 -0.0148 -0.015 0.0098 -0.0158 -0.009000000000000003 0 -0.0158 -0.012 6.93889e-18 -0.0158 -0.015 -0.0098 -0.0158 -0.015 0.0098 -0.0158 -0.012 6.93889e-18 -0.0158 -0.009000000000000003 0 -0.0158 -0.015 -0.0098 -0.0158 -0.012 6.93889e-18 -0.0158 -0.0143333 -0.0098 0 -0.015 -0.0098 -0.0158 -0.014 -0.0098 -0.0158 -0.0143333 -0.0098 0 -0.014 -0.0098 -0.0158 -0.014 -0.0098 -0.0148 -0.014 0.0098 0.0148 -0.014 0 0 -0.014 0.0049 -1.30104e-17 -0.014 0.0098 -0.0148 -0.014 0.0098 0.0148 -0.014 0.0049 -1.30104e-17 -0.014 0 0 -0.014 0.0098 -0.0148 -0.014 0.0049 -1.30104e-17 -0.014 -0.0098 -0.0148 -0.014 0 0 -0.014 -0.0049 0 -0.014 -0.0098 0.0148 -0.014 -0.0098 -0.0148 -0.014 -0.0049 0 -0.014 0 0 -0.014 -0.0098 0.0148 -0.014 -0.0049 0 -0.015 0.0098 -0.0158 -0.015 0.0098 -0.0125 -0.0149 0.0098 -0.0125 -0.015 0.0098 0.0125 -0.015 0.0098 0.0158 -0.0149 0.0098 0.0125 -0.0149 0.0098 0.0125 -0.0143333 0.0098 0 -0.0149 0.0098 -0.0125 -0.0143333 0.0098 0 -0.015 0.0098 -0.0158 -0.0149 0.0098 -0.0125 -0.0149 0.0098 0.0125 -0.015 0.0098 0.0158 -0.0143333 0.0098 0 -0.0143333 0.0098 0 -0.014 0.0098 0.0158 -0.014 0.0098 0.0148 -0.015 -0.0098 -0.0158 -0.015 -0.00775316 -0.0125 -0.015 -1.73472e-18 -0.01415 -0.015 0.0098 -0.0158 -0.015 -0.0098 -0.0158 -0.015 -1.73472e-18 -0.01415 -0.015 0.00775316 -0.0125 -0.015 0.0098 -0.0158 -0.015 -1.73472e-18 -0.01415 -0.015 -0.00775316 -0.0125 -0.015 0.00775316 -0.0125 -0.015 -1.73472e-18 -0.01415 -0.015 -0.0098 0.0158 -0.015 -0.0098 0.0125 -0.0149 -0.0098 0.0125 -0.0143333 -0.0098 0 -0.0149 -0.0098 0.0110577 -0.0149 -0.0098 -0.0110577 -0.0149 -0.0098 -0.0125 -0.015 -0.0098 -0.0125 -0.015 -0.0098 -0.0158 -0.0149 -0.0098 0.0110577 -0.0143333 -0.0098 0 -0.0149 -0.0098 0.0125 -0.0143333 -0.0098 0 -0.015 -0.0098 0.0158 -0.0149 -0.0098 0.0125 -0.0143333 -0.0098 0 -0.0149 -0.0098 -0.0125 -0.015 -0.0098 -0.0158 -0.0143333 -0.0098 0 -0.0149 -0.0098 -0.0110577 -0.0149 -0.0098 -0.0125 -0.0143333 -0.0098 0 -0.014 -0.0098 -0.0148 -0.014 -0.0098 0.0148 -0.014 -0.0098 0.0148 -0.014 0 0 -0.014 -6.93889e-18 0.0074 -0.014 0.0098 0.0148 -0.014 -0.0098 0.0148 -0.014 -6.93889e-18 0.0074 -0.014 0 0 -0.014 0.0098 0.0148 -0.014 -6.93889e-18 0.0074 -0.0143333 0.0098 0 -0.015 0.0098 0.0158 -0.014 0.0098 0.0158 -0.015 0.0098 0.0125 -0.015 0.00976894 0.0125 -0.015 0.0098 0.0158 -0.015 0.0097419 0.0125 -0.015 0.00775316 0.0125 -0.015 0.0098 0.0158 -0.015 0.009752500000000001 0.0125 -0.015 0.0098 0.0158 -0.015 0.0097419 0.0125 -0.015 0.00975934 0.0125 -0.015 0.0098 0.0158 -0.015 0.009752500000000001 0.0125 -0.015 0.00976894 0.0125 -0.015 0.0098 0.0158 -0.015 0.00975934 0.0125 -0.015 0.0098 0.0124302 -0.0149 0.0098 0.0125 -0.015 0.0098 0.0125 -0.015 0.0098 -0.0124302 -0.015 0.0098 0.0124302 -0.0149 0.0098 0.0125 -0.0149 0.0098 -0.0125 -0.015 0.0098 -0.0124302 -0.0149 0.0098 0.0125 -0.015 0.0098 -0.0125 -0.0149 0.0098 -0.0125 -0.015 0.0098 -0.0124302 -0.015 0.0098 -0.0158 -0.015 0.00775316 -0.0125 -0.015 0.0097419 -0.0125 -0.015 0.0098 -0.0158 -0.015 0.00975208 -0.0125 -0.015 0.0097419 -0.0125 -0.015 0.0098 -0.0158 -0.015 0.009759169999999999 -0.0125 -0.015 0.00975208 -0.0125 -0.015 0.0098 -0.0158 -0.015 0.009769140000000001 -0.0125 -0.015 0.009759169999999999 -0.0125 -0.015 0.0098 -0.0158 -0.015 0.009769140000000001 -0.0125 -0.015 0.0098 -0.0125 -0.014 0.0098 0.0148 -0.014 0.0098 0.0158 -0.006000000000000004 0.009075 0.0153 -0.015 -0.0098 -0.0158 -0.015 -0.0098 -0.0125 -0.015 -0.00775316 -0.0125 -0.05070000000000001 -0.011 -0.0125 -0.015 0.0097419 -0.0125 -0.015 0.00775316 -0.0125 -0.05070000000000001 -0.011 -0.0125 -0.015 0.00775316 -0.0125 -0.015 -0.00775316 -0.0125 -0.05070000000000001 -0.011 -0.0125 -0.015 -0.00775316 -0.0125 -0.015 -0.0098 -0.0125 -0.015 -0.0098 -0.0125 -0.0149 -0.0098 -0.0125 -0.0149 -0.011 -0.0125 -0.05070000000000001 -0.011 -0.0125 -0.015 -0.0098 -0.0125 -0.0149 -0.011 -0.0125 -0.0149 -0.0098 -0.0110577 -0.0149 -0.0098 0.0110577 -0.0149 -0.0104 7.806259999999999e-18 -0.0149 -0.011 -0.0125 -0.0149 -0.0098 -0.0110577 -0.0149 -0.0104 7.806259999999999e-18 -0.0149 -0.011 0.0125 -0.0149 -0.011 -0.0125 -0.0149 -0.0104 7.806259999999999e-18 -0.0149 -0.0098 0.0110577 -0.0149 -0.011 0.0125 -0.0149 -0.0104 7.806259999999999e-18 -0.0149 -0.0098 0.0125 -0.0149 -0.011 0.0125 -0.0149 -0.0098 0.0110577 -0.0149 -0.0098 0.0125 -0.015 -0.0098 0.0125 -0.0149 -0.011 0.0125 -0.015 -0.0098 0.0125 -0.015 -0.00775316 0.0125 -0.05070000000000001 -0.011 0.0125 -0.015 0.00775316 0.0125 -0.015 0.0097419 0.0125 -0.05070000000000001 -0.011 0.0125 -0.015 -0.00775316 0.0125 -0.015 0.00775316 0.0125 -0.05070000000000001 -0.011 0.0125 -0.0149 -0.011 0.0125 -0.015 -0.0098 0.0125 -0.05070000000000001 -0.011 0.0125 -0.015 -0.00775316 0.0125 -0.015 -0.0098 0.0125 -0.015 -0.0098 0.0158 -0.014 -0.0098 0.0158 -0.015 -0.0098 0.0158 -0.0143333 -0.0098 0 -0.0149 -0.0098 -0.0110577 -0.0149 -0.011 -0.0125 -0.0149 -0.0098 -0.0125 -0.0143333 -0.0098 0 -0.014 -0.0098 0.0148 -0.014 -0.0098 0.0158 -0.014 0.0098 0.0148 -0.006000000000000004 0 0.0148 -0.01 4.33681e-18 0.0148 -0.014 -0.0098 0.0148 -0.014 0.0098 0.0148 -0.01 4.33681e-18 0.0148 -0.006000000000000004 0 0.0148 -0.014 -0.0098 0.0148 -0.01 4.33681e-18 0.0148 -0.014 0.0098 0.0158 -0.015 0.0098 0.0158 -0.009000000000000003 0 0.0158 -0.015 0.00976894 0.0125 -0.015 0.0098 0.0125 -0.03285 0.0059253 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.015 0.00976894 0.0125 -0.03285 0.0059253 0.0125 -0.05070000000000001 0.0098 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.03285 0.0059253 0.0125 -0.015 0.0098 0.0125 -0.05070000000000001 0.0098 0.0125 -0.03285 0.0059253 0.0125 -0.015 0.0098 0.0158 -0.015 0.00775316 0.0125 -0.015 8.673619999999999e-18 0.01415 -0.015 -0.0098 0.0158 -0.015 0.0098 0.0158 -0.015 8.673619999999999e-18 0.01415 -0.015 -0.00775316 0.0125 -0.015 -0.0098 0.0158 -0.015 8.673619999999999e-18 0.01415 -0.015 0.00775316 0.0125 -0.015 -0.00775316 0.0125 -0.015 8.673619999999999e-18 0.01415 -0.015 0.0097419 0.0125 -0.015 0.009752500000000001 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.015 0.0097419 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.05070000000000001 -0.011 0.0125 -0.015 0.009752500000000001 0.0125 -0.015 0.00975934 0.0125 -0.03900000000000001 0 0.0125 -0.015 0.009752500000000001 0.0125 -0.03900000000000001 0 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.015 0.00975934 0.0125 -0.015 0.00976894 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.015 0.00975934 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.03900000000000001 0 0.0125 -0.015 0.0098 0.0125 -0.015 0.0098 0.0124302 -0.03285 0.0098 0.00625 -0.05070000000000001 0.0098 0.0125 -0.015 0.0098 0.0125 -0.03285 0.0098 0.00625 -0.03280000000000001 0.0098 0 -0.05070000000000001 0.0098 0.0125 -0.03285 0.0098 0.00625 -0.015 0.0098 0.0124302 -0.03280000000000001 0.0098 0 -0.03285 0.0098 0.00625 -0.015 0.0098 0.0124302 -0.015 0.0098 -0.0124302 -0.0239 0.0098 0 -0.03280000000000001 0.0098 0 -0.015 0.0098 0.0124302 -0.0239 0.0098 0 -0.015 0.0098 -0.0124302 -0.03280000000000001 0.0098 0 -0.0239 0.0098 0 -0.05070000000000001 0.0098 -0.0125 -0.03280000000000001 0.0098 0 -0.03285 0.0098 -0.00625 -0.015 0.0098 -0.0125 -0.05070000000000001 0.0098 -0.0125 -0.03285 0.0098 -0.00625 -0.015 0.0098 -0.0124302 -0.015 0.0098 -0.0125 -0.03285 0.0098 -0.00625 -0.03280000000000001 0.0098 0 -0.015 0.0098 -0.0124302 -0.03285 0.0098 -0.00625 -0.015 0.0098 -0.0125 -0.015 0.009769140000000001 -0.0125 -0.03285 0.00596065 -0.0125 -0.05070000000000001 0.0098 -0.0125 -0.015 0.0098 -0.0125 -0.03285 0.00596065 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.05070000000000001 0.0098 -0.0125 -0.03285 0.00596065 -0.0125 -0.015 0.009769140000000001 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.03285 0.00596065 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.015 0.009769140000000001 -0.0125 -0.015 0.009759169999999999 -0.0125 -0.0389 0 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.015 0.009759169999999999 -0.0125 -0.0389 0 -0.0125 -0.015 0.009759169999999999 -0.0125 -0.015 0.00975208 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.0389 0 -0.0125 -0.015 0.00975208 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.015 0.00975208 -0.0125 -0.015 0.0097419 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.015 0.0097419 -0.0125 -0.05070000000000001 -0.011 -0.0125 -0.006000000000000004 0.009075 0.0153 -0.014 0.0098 0.0158 0.001999999999999997 0.00835 0.0158 -0.014 0.0098 0.0148 -0.006000000000000004 0.009075 0.0153 0.001999999999999997 0.00835 0.0148 -0.0149 -0.011 -0.0125 -0.03280000000000001 -0.011 0 -0.03280000000000001 -0.011 -0.00625 -0.05070000000000001 -0.011 -0.0125 -0.0149 -0.011 -0.0125 -0.03280000000000001 -0.011 -0.00625 -0.03280000000000001 -0.011 0 -0.05070000000000001 -0.011 -0.0125 -0.03280000000000001 -0.011 -0.00625 -0.0149 -0.011 0.0125 -0.03280000000000001 -0.011 0 -0.02385 -0.011 1.99493e-17 -0.0149 -0.011 -0.0125 -0.0149 -0.011 0.0125 -0.02385 -0.011 1.99493e-17 -0.03280000000000001 -0.011 0 -0.0149 -0.011 -0.0125 -0.02385 -0.011 1.99493e-17 -0.05070000000000001 -0.011 0.0125 -0.03280000000000001 -0.011 0 -0.03280000000000001 -0.011 0.00625 -0.0149 -0.011 0.0125 -0.05070000000000001 -0.011 0.0125 -0.03280000000000001 -0.011 0.00625 -0.03280000000000001 -0.011 0 -0.0149 -0.011 0.0125 -0.03280000000000001 -0.011 0.00625 -0.014 -0.0098 0.0158 -0.009000000000000003 0 0.0158 -0.015 -0.0098 0.0158 -0.006000000000000004 -0.009075 0.0153 -0.014 -0.0098 0.0158 -0.014 -0.0098 0.0148 0.001999999999999997 0.00835 0.0148 -0.006000000000000004 0 0.0148 -0.006000000000000004 0.0049 0.0148 -0.014 0.0098 0.0148 0.001999999999999997 0.00835 0.0148 -0.006000000000000004 0.0049 0.0148 -0.006000000000000004 0 0.0148 -0.014 0.0098 0.0148 -0.006000000000000004 0.0049 0.0148 -0.014 -0.0098 0.0148 -0.006000000000000004 0 0.0148 -0.006000000000000004 -0.0049 0.0148 0.001999999999999997 -0.00835 0.0148 -0.014 -0.0098 0.0148 -0.006000000000000004 -0.0049 0.0148 -0.006000000000000004 0 0.0148 0.001999999999999997 -0.00835 0.0148 -0.006000000000000004 -0.0049 0.0148 -0.015 -0.0098 0.0158 -0.009000000000000003 0 0.0158 -0.012 0 0.0158 -0.015 0.0098 0.0158 -0.015 -0.0098 0.0158 -0.012 0 0.0158 -0.009000000000000003 0 0.0158 -0.015 0.0098 0.0158 -0.012 0 0.0158 0.001999999999999997 0.00835 0.0158 -0.014 0.0098 0.0158 -0.009000000000000003 0 0.0158 -0.03984900000000001 0.0020506 0.0125 -0.05070000000000001 0.0098 0.0125 -0.04190000000000001 0.0029 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.04190000000000001 -0.0029 0.0125 -0.05070000000000001 -0.011 0.0125 -0.03900000000000001 0 0.0125 -0.039425 -0.0010253 0.01415 -0.03942470000000001 -0.00102521 0.013325 -0.03984900000000001 -0.0020506 0.0125 -0.03900000000000001 0 0.0125 -0.03942470000000001 -0.00102521 0.013325 -0.039425 -0.0010253 0.01415 -0.03984900000000001 -0.0020506 0.0125 -0.03942470000000001 -0.00102521 0.013325 -0.039425 0.0010253 0.01415 -0.03942470000000001 0.00102521 0.013325 -0.03984900000000001 0.0020506 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.03942470000000001 0.00102521 0.013325 -0.03900000000000001 0 0.0125 -0.03900000000000001 0 0.0125 -0.03942470000000001 0.00102521 0.013325 -0.039425 0.0010253 0.01415 -0.05070000000000001 0.0098 0.0125 -0.03280000000000001 0.0098 0 -0.04175000000000001 0.0098 1.47451e-17 -0.05070000000000001 0.0098 -0.0125 -0.05070000000000001 0.0098 0.0125 -0.04175000000000001 0.0098 1.47451e-17 -0.03280000000000001 0.0098 0 -0.05070000000000001 0.0098 -0.0125 -0.04175000000000001 0.0098 1.47451e-17 -0.03977900000000001 0.0021213 -0.0125 -0.04190000000000001 0.003 -0.0125 -0.05070000000000001 0.0098 -0.0125 -0.0389 0 -0.0125 -0.039339 0.0010607 -0.01415 -0.03933930000000001 0.00106074 -0.013325 -0.03977900000000001 0.0021213 -0.0125 -0.0389 0 -0.0125 -0.03933930000000001 0.00106074 -0.013325 -0.039339 0.0010607 -0.01415 -0.03977900000000001 0.0021213 -0.0125 -0.03933930000000001 0.00106074 -0.013325 -0.03977900000000001 -0.0021213 -0.0125 -0.039339 -0.0010607 -0.01415 -0.03933930000000001 -0.00106074 -0.013325 -0.0389 0 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.03933930000000001 -0.00106074 -0.013325 -0.039339 -0.0010607 -0.01415 -0.0389 0 -0.0125 -0.03933930000000001 -0.00106074 -0.013325 -0.03977900000000001 -0.0021213 -0.0125 -0.05070000000000001 -0.011 -0.0125 -0.04190000000000001 -0.003 -0.0125 -0.006000000000000004 0.009075 0.0153 0.001999999999999997 0.00835 0.0158 0.001999999999999997 0.00835 0.0148 -0.05070000000000001 -0.011 -0.0125 -0.03280000000000001 -0.011 0 -0.04175000000000001 -0.011 -1.56125e-17 -0.05070000000000001 -0.011 0.0125 -0.05070000000000001 -0.011 -0.0125 -0.04175000000000001 -0.011 -1.56125e-17 -0.03280000000000001 -0.011 0 -0.05070000000000001 -0.011 0.0125 -0.04175000000000001 -0.011 -1.56125e-17 0.001999999999999997 -0.00835 0.0158 -0.009000000000000003 0 0.0158 -0.014 -0.0098 0.0158 -0.006000000000000004 -0.009075 0.0153 -0.014 -0.0098 0.0148 0.001999999999999997 -0.00835 0.0148 -0.006000000000000004 -0.009075 0.0153 0.001999999999999997 -0.00835 0.0158 -0.014 -0.0098 0.0158 0.001999999999999997 -0.00835 0.0148 -0.006000000000000004 0 0.0148 -0.002000000000000004 1.99493e-17 0.0148 0.001999999999999997 0.00835 0.0148 0.001999999999999997 -0.00835 0.0148 -0.002000000000000004 1.99493e-17 0.0148 -0.006000000000000004 0 0.0148 0.001999999999999997 0.00835 0.0148 -0.002000000000000004 1.99493e-17 0.0148 0.001999999999999997 0.00835 0.0158 -0.009000000000000003 0 0.0158 -0.003500000000000004 0 0.0158 0.001999999999999997 -0.00835 0.0158 0.001999999999999997 0.00835 0.0158 -0.003500000000000004 0 0.0158 -0.009000000000000003 0 0.0158 0.001999999999999997 -0.00835 0.0158 -0.003500000000000004 0 0.0158 -0.04087500000000001 0.0024753 0.01415 -0.04087450000000001 0.00247521 0.013325 -0.04190000000000001 0.0029 0.0125 -0.04190000000000001 0.0029 0.0125 -0.04087450000000001 0.00247521 0.013325 -0.03984900000000001 0.0020506 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.04087450000000001 0.00247521 0.013325 -0.04087500000000001 0.0024753 0.01415 -0.04190000000000001 0.0029 0.0125 -0.05070000000000001 0.0098 0.0125 -0.043951 0.0020506 0.0125 -0.04190000000000001 -0.0029 0.0125 -0.043951 -0.0020506 0.0125 -0.05070000000000001 -0.011 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.04087500000000001 -0.0024753 0.01415 -0.04087450000000001 -0.00247521 0.013325 -0.04190000000000001 -0.0029 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.04087450000000001 -0.00247521 0.013325 -0.04087500000000001 -0.0024753 0.01415 -0.04190000000000001 -0.0029 0.0125 -0.04087450000000001 -0.00247521 0.013325 -0.03900000000000001 0 0.0158 -0.039425 -0.0010253 0.01415 -0.0392125 -0.00051265 0.01415 -0.03900000000000001 0 0.0125 -0.03900000000000001 0 0.0158 -0.0392125 -0.00051265 0.01415 -0.039425 -0.0010253 0.01415 -0.03900000000000001 0 0.0125 -0.0392125 -0.00051265 0.01415 -0.03984900000000001 -0.0020506 0.0125 -0.039425 -0.0010253 0.01415 -0.03963700000000001 -0.00153795 0.01415 -0.03984900000000001 -0.0020506 0.0158 -0.03984900000000001 -0.0020506 0.0125 -0.03963700000000001 -0.00153795 0.01415 -0.039425 -0.0010253 0.01415 -0.03984900000000001 -0.0020506 0.0158 -0.03963700000000001 -0.00153795 0.01415 -0.03984900000000001 0.0020506 0.0158 -0.039425 0.0010253 0.01415 -0.03963700000000001 0.00153795 0.01415 -0.03984900000000001 0.0020506 0.0125 -0.03984900000000001 0.0020506 0.0158 -0.03963700000000001 0.00153795 0.01415 -0.039425 0.0010253 0.01415 -0.03984900000000001 0.0020506 0.0125 -0.03963700000000001 0.00153795 0.01415 -0.03900000000000001 0 0.0125 -0.039425 0.0010253 0.01415 -0.0392125 0.00051265 0.01415 -0.03900000000000001 0 0.0158 -0.03900000000000001 0 0.0125 -0.0392125 0.00051265 0.01415 -0.039425 0.0010253 0.01415 -0.03900000000000001 0 0.0158 -0.0392125 0.00051265 0.01415 -0.05070000000000001 0.0098 -0.0125 -0.05070000000000001 -0.000599999 0 -0.05070000000000001 0.0046 1.64799e-17 -0.05070000000000001 0.0098 0.0125 -0.05070000000000001 0.0098 -0.0125 -0.05070000000000001 0.0046 1.64799e-17 -0.05070000000000001 -0.000599999 0 -0.05070000000000001 0.0098 0.0125 -0.05070000000000001 0.0046 1.64799e-17 -0.044021 0.0021213 -0.0125 -0.05070000000000001 0.0098 -0.0125 -0.04190000000000001 0.003 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.040839 0.0025607 -0.01415 -0.0408395 0.00256076 -0.013325 -0.04190000000000001 0.003 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.0408395 0.00256076 -0.013325 -0.040839 0.0025607 -0.01415 -0.04190000000000001 0.003 -0.0125 -0.0408395 0.00256076 -0.013325 -0.0389 0 -0.0158 -0.039339 0.0010607 -0.01415 -0.0391195 0.00053035 -0.01415 -0.0389 0 -0.0125 -0.0389 0 -0.0158 -0.0391195 0.00053035 -0.01415 -0.039339 0.0010607 -0.01415 -0.0389 0 -0.0125 -0.0391195 0.00053035 -0.01415 -0.03977900000000001 0.0021213 -0.0125 -0.039339 0.0010607 -0.01415 -0.039559 0.001591 -0.01415 -0.03977900000000001 0.0021213 -0.0158 -0.03977900000000001 0.0021213 -0.0125 -0.039559 0.001591 -0.01415 -0.039339 0.0010607 -0.01415 -0.03977900000000001 0.0021213 -0.0158 -0.039559 0.001591 -0.01415 -0.03977900000000001 -0.0021213 -0.0158 -0.039339 -0.0010607 -0.01415 -0.039559 -0.001591 -0.01415 -0.03977900000000001 -0.0021213 -0.0125 -0.03977900000000001 -0.0021213 -0.0158 -0.039559 -0.001591 -0.01415 -0.039339 -0.0010607 -0.01415 -0.03977900000000001 -0.0021213 -0.0125 -0.039559 -0.001591 -0.01415 -0.0389 0 -0.0125 -0.039339 -0.0010607 -0.01415 -0.0391195 -0.00053035 -0.01415 -0.0389 0 -0.0158 -0.0389 0 -0.0125 -0.0391195 -0.00053035 -0.01415 -0.039339 -0.0010607 -0.01415 -0.0389 0 -0.0158 -0.0391195 -0.00053035 -0.01415 -0.040839 -0.0025607 -0.01415 -0.0408395 -0.00256076 -0.013325 -0.04190000000000001 -0.003 -0.0125 -0.04190000000000001 -0.003 -0.0125 -0.0408395 -0.00256076 -0.013325 -0.03977900000000001 -0.0021213 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.0408395 -0.00256076 -0.013325 -0.040839 -0.0025607 -0.01415 -0.05070000000000001 -0.011 -0.0125 -0.044021 -0.0021213 -0.0125 -0.04190000000000001 -0.003 -0.0125 0.001999999999999997 0.00835 0.0158 0.001999999999999997 0 0.0153 0.001999999999999997 0.00835 0.0148 -0.05070000000000001 -0.011 0.0125 -0.05070000000000001 -0.000599999 0 -0.05070000000000001 -0.0058 -7.806259999999999e-18 -0.05070000000000001 -0.011 -0.0125 -0.05070000000000001 -0.011 0.0125 -0.05070000000000001 -0.0058 -7.806259999999999e-18 -0.05070000000000001 -0.000599999 0 -0.05070000000000001 -0.011 -0.0125 -0.05070000000000001 -0.0058 -7.806259999999999e-18 0.001999999999999997 -0.00835 0.0148 0.001999999999999997 -0.00835 0.0158 -0.006000000000000004 -0.009075 0.0153 0.001999999999999997 0 0.0153 0.001999999999999997 -0.00835 0.0148 0.001999999999999997 0.00835 0.0148 0.001999999999999997 0 0.0153 0.001999999999999997 0.00835 0.0158 0.001999999999999997 -0.00835 0.0158 -0.04190000000000001 0.0029 0.0158 -0.04087500000000001 0.0024753 0.01415 -0.04138750000000001 0.00268765 0.01415 -0.04190000000000001 0.0029 0.0125 -0.04190000000000001 0.0029 0.0158 -0.04138750000000001 0.00268765 0.01415 -0.04087500000000001 0.0024753 0.01415 -0.04190000000000001 0.0029 0.0125 -0.04138750000000001 0.00268765 0.01415 -0.03984900000000001 0.0020506 0.0125 -0.04087500000000001 0.0024753 0.01415 -0.04036200000000001 0.00226295 0.01415 -0.03984900000000001 0.0020506 0.0158 -0.03984900000000001 0.0020506 0.0125 -0.04036200000000001 0.00226295 0.01415 -0.04087500000000001 0.0024753 0.01415 -0.03984900000000001 0.0020506 0.0158 -0.04036200000000001 0.00226295 0.01415 -0.043951 0.0020506 0.0125 -0.042925 0.0024753 0.01415 -0.04292550000000001 0.00247521 0.013325 -0.04190000000000001 0.0029 0.0125 -0.043951 0.0020506 0.0125 -0.04292550000000001 0.00247521 0.013325 -0.042925 0.0024753 0.01415 -0.04190000000000001 0.0029 0.0125 -0.04292550000000001 0.00247521 0.013325 -0.043951 0.0020506 0.0125 -0.05070000000000001 0.0098 0.0125 -0.05070000000000001 -0.011 0.0125 -0.043951 -0.0020506 0.0125 -0.04480000000000001 0 0.0125 -0.05070000000000001 -0.011 0.0125 -0.04190000000000001 -0.0029 0.0125 -0.042925 -0.0024753 0.01415 -0.04292550000000001 -0.00247521 0.013325 -0.043951 -0.0020506 0.0125 -0.04190000000000001 -0.0029 0.0125 -0.04292550000000001 -0.00247521 0.013325 -0.042925 -0.0024753 0.01415 -0.043951 -0.0020506 0.0125 -0.04292550000000001 -0.00247521 0.013325 -0.03984900000000001 -0.0020506 0.0158 -0.04087500000000001 -0.0024753 0.01415 -0.04036200000000001 -0.00226295 0.01415 -0.03984900000000001 -0.0020506 0.0125 -0.03984900000000001 -0.0020506 0.0158 -0.04036200000000001 -0.00226295 0.01415 -0.04087500000000001 -0.0024753 0.01415 -0.03984900000000001 -0.0020506 0.0125 -0.04036200000000001 -0.00226295 0.01415 -0.04190000000000001 -0.0029 0.0125 -0.04087500000000001 -0.0024753 0.01415 -0.04138750000000001 -0.00268765 0.01415 -0.04190000000000001 -0.0029 0.0158 -0.04190000000000001 -0.0029 0.0125 -0.04138750000000001 -0.00268765 0.01415 -0.04087500000000001 -0.0024753 0.01415 -0.04190000000000001 -0.0029 0.0158 -0.04138750000000001 -0.00268765 0.01415 -0.03984900000000001 -0.0020506 0.0158 -0.039425 -0.0010253 0.01415 -0.03942470000000001 -0.00102521 0.014975 -0.03900000000000001 0 0.0158 -0.03984900000000001 -0.0020506 0.0158 -0.03942470000000001 -0.00102521 0.014975 -0.039425 -0.0010253 0.01415 -0.03900000000000001 0 0.0158 -0.03942470000000001 -0.00102521 0.014975 -0.03900000000000001 0 0.0158 -0.039425 0.0010253 0.01415 -0.03942470000000001 0.00102521 0.014975 -0.03984900000000001 0.0020506 0.0158 -0.03900000000000001 0 0.0158 -0.03942470000000001 0.00102521 0.014975 -0.039425 0.0010253 0.01415 -0.03984900000000001 0.0020506 0.0158 -0.03942470000000001 0.00102521 0.014975 -0.05070000000000001 -0.011 -0.0125 -0.05070000000000001 -0.000599999 0 -0.05070000000000001 -0.0005999999999999999 -0.00625 -0.05070000000000001 0.0098 -0.0125 -0.05070000000000001 -0.011 -0.0125 -0.05070000000000001 -0.0005999999999999999 -0.00625 -0.05070000000000001 -0.000599999 0 -0.05070000000000001 0.0098 -0.0125 -0.05070000000000001 -0.0005999999999999999 -0.00625 -0.05070000000000001 0.0098 0.0125 -0.05070000000000001 -0.000599999 0 -0.05070000000000001 -0.0005999999999999999 0.00625 -0.05070000000000001 -0.011 0.0125 -0.05070000000000001 0.0098 0.0125 -0.05070000000000001 -0.0005999999999999999 0.00625 -0.05070000000000001 -0.000599999 0 -0.05070000000000001 -0.011 0.0125 -0.05070000000000001 -0.0005999999999999999 0.00625 -0.05070000000000001 0.0098 -0.0125 -0.044021 0.0021213 -0.0125 -0.05070000000000001 -0.011 -0.0125 -0.042961 0.0025607 -0.01415 -0.0429605 0.00256076 -0.013325 -0.04190000000000001 0.003 -0.0125 -0.04190000000000001 0.003 -0.0125 -0.0429605 0.00256076 -0.013325 -0.044021 0.0021213 -0.0125 -0.044021 0.0021213 -0.0125 -0.0429605 0.00256076 -0.013325 -0.042961 0.0025607 -0.01415 -0.03977900000000001 0.0021213 -0.0158 -0.040839 0.0025607 -0.01415 -0.040309 0.002341 -0.01415 -0.03977900000000001 0.0021213 -0.0125 -0.03977900000000001 0.0021213 -0.0158 -0.040309 0.002341 -0.01415 -0.040839 0.0025607 -0.01415 -0.03977900000000001 0.0021213 -0.0125 -0.040309 0.002341 -0.01415 -0.04190000000000001 0.003 -0.0125 -0.040839 0.0025607 -0.01415 -0.0413695 0.00278035 -0.01415 -0.04190000000000001 0.003 -0.0158 -0.04190000000000001 0.003 -0.0125 -0.0413695 0.00278035 -0.01415 -0.040839 0.0025607 -0.01415 -0.04190000000000001 0.003 -0.0158 -0.0413695 0.00278035 -0.01415 -0.03977900000000001 0.0021213 -0.0158 -0.039339 0.0010607 -0.01415 -0.03933930000000001 0.00106074 -0.014975 -0.0389 0 -0.0158 -0.03977900000000001 0.0021213 -0.0158 -0.03933930000000001 0.00106074 -0.014975 -0.039339 0.0010607 -0.01415 -0.0389 0 -0.0158 -0.03933930000000001 0.00106074 -0.014975 -0.0389 0 -0.0158 -0.039339 -0.0010607 -0.01415 -0.03933930000000001 -0.00106074 -0.014975 -0.03977900000000001 -0.0021213 -0.0158 -0.0389 0 -0.0158 -0.03933930000000001 -0.00106074 -0.014975 -0.039339 -0.0010607 -0.01415 -0.03977900000000001 -0.0021213 -0.0158 -0.03933930000000001 -0.00106074 -0.014975 -0.03977900000000001 -0.0021213 -0.0125 -0.040839 -0.0025607 -0.01415 -0.040309 -0.002341 -0.01415 -0.03977900000000001 -0.0021213 -0.0158 -0.03977900000000001 -0.0021213 -0.0125 -0.040309 -0.002341 -0.01415 -0.040839 -0.0025607 -0.01415 -0.03977900000000001 -0.0021213 -0.0158 -0.040309 -0.002341 -0.01415 -0.04190000000000001 -0.003 -0.0158 -0.040839 -0.0025607 -0.01415 -0.0413695 -0.00278035 -0.01415 -0.04190000000000001 -0.003 -0.0125 -0.04190000000000001 -0.003 -0.0158 -0.0413695 -0.00278035 -0.01415 -0.040839 -0.0025607 -0.01415 -0.04190000000000001 -0.003 -0.0125 -0.0413695 -0.00278035 -0.01415 -0.044021 -0.0021213 -0.0125 -0.042961 -0.0025607 -0.01415 -0.0429605 -0.00256076 -0.013325 -0.04190000000000001 -0.003 -0.0125 -0.044021 -0.0021213 -0.0125 -0.0429605 -0.00256076 -0.013325 -0.042961 -0.0025607 -0.01415 -0.04190000000000001 -0.003 -0.0125 -0.0429605 -0.00256076 -0.013325 -0.04490000000000001 0 -0.0125 -0.044021 -0.0021213 -0.0125 -0.05070000000000001 -0.011 -0.0125 0.001999999999999997 -0.00835 0.0158 0.001999999999999997 -0.00835 0.0148 0.001999999999999997 0 0.0153 -0.04087500000000001 0.0024753 0.01415 -0.04087450000000001 0.00247521 0.014975 -0.03984900000000001 0.0020506 0.0158 -0.03984900000000001 0.0020506 0.0158 -0.04087450000000001 0.00247521 0.014975 -0.04190000000000001 0.0029 0.0158 -0.04190000000000001 0.0029 0.0158 -0.04087450000000001 0.00247521 0.014975 -0.04087500000000001 0.0024753 0.01415 -0.04190000000000001 0.0029 0.0125 -0.042925 0.0024753 0.01415 -0.04241250000000001 0.00268765 0.01415 -0.04190000000000001 0.0029 0.0158 -0.04190000000000001 0.0029 0.0125 -0.04241250000000001 0.00268765 0.01415 -0.042925 0.0024753 0.01415 -0.04190000000000001 0.0029 0.0158 -0.04241250000000001 0.00268765 0.01415 -0.043951 0.0020506 0.0158 -0.042925 0.0024753 0.01415 -0.043438 0.00226295 0.01415 -0.043951 0.0020506 0.0125 -0.043951 0.0020506 0.0158 -0.043438 0.00226295 0.01415 -0.042925 0.0024753 0.01415 -0.043951 0.0020506 0.0125 -0.043438 0.00226295 0.01415 -0.04480000000000001 0 0.0125 -0.043951 0.0020506 0.0125 -0.05070000000000001 -0.011 0.0125 -0.044375 -0.0010253 0.01415 -0.04437530000000001 -0.00102521 0.013325 -0.043951 -0.0020506 0.0125 -0.043951 -0.0020506 0.0125 -0.04437530000000001 -0.00102521 0.013325 -0.04480000000000001 0 0.0125 -0.04480000000000001 0 0.0125 -0.04437530000000001 -0.00102521 0.013325 -0.044375 -0.0010253 0.01415 -0.04190000000000001 -0.0029 0.0158 -0.042925 -0.0024753 0.01415 -0.04241250000000001 -0.00268765 0.01415 -0.04190000000000001 -0.0029 0.0125 -0.04190000000000001 -0.0029 0.0158 -0.04241250000000001 -0.00268765 0.01415 -0.042925 -0.0024753 0.01415 -0.04190000000000001 -0.0029 0.0125 -0.04241250000000001 -0.00268765 0.01415 -0.043951 -0.0020506 0.0125 -0.042925 -0.0024753 0.01415 -0.043438 -0.00226295 0.01415 -0.043951 -0.0020506 0.0158 -0.043951 -0.0020506 0.0125 -0.043438 -0.00226295 0.01415 -0.042925 -0.0024753 0.01415 -0.043951 -0.0020506 0.0158 -0.043438 -0.00226295 0.01415 -0.04190000000000001 -0.0029 0.0158 -0.04087500000000001 -0.0024753 0.01415 -0.04087450000000001 -0.00247521 0.014975 -0.03984900000000001 -0.0020506 0.0158 -0.04190000000000001 -0.0029 0.0158 -0.04087450000000001 -0.00247521 0.014975 -0.04087500000000001 -0.0024753 0.01415 -0.03984900000000001 -0.0020506 0.0158 -0.04087450000000001 -0.00247521 0.014975 -0.03984900000000001 -0.0020506 0.0158 -0.03900000000000001 0 0.0158 -0.04190000000000001 0 0.0158 -0.03900000000000001 0 0.0158 -0.03984900000000001 0.0020506 0.0158 -0.04190000000000001 0 0.0158 -0.04490000000000001 0 -0.0125 -0.05070000000000001 -0.011 -0.0125 -0.044021 0.0021213 -0.0125 -0.04190000000000001 0.003 -0.0158 -0.042961 0.0025607 -0.01415 -0.04243050000000001 0.00278035 -0.01415 -0.04190000000000001 0.003 -0.0125 -0.04190000000000001 0.003 -0.0158 -0.04243050000000001 0.00278035 -0.01415 -0.042961 0.0025607 -0.01415 -0.04190000000000001 0.003 -0.0125 -0.04243050000000001 0.00278035 -0.01415 -0.044021 0.0021213 -0.0125 -0.042961 0.0025607 -0.01415 -0.043491 0.002341 -0.01415 -0.044021 0.0021213 -0.0158 -0.044021 0.0021213 -0.0125 -0.043491 0.002341 -0.01415 -0.042961 0.0025607 -0.01415 -0.044021 0.0021213 -0.0158 -0.043491 0.002341 -0.01415 -0.04190000000000001 0.003 -0.0158 -0.040839 0.0025607 -0.01415 -0.0408395 0.00256076 -0.014975 -0.03977900000000001 0.0021213 -0.0158 -0.04190000000000001 0.003 -0.0158 -0.0408395 0.00256076 -0.014975 -0.040839 0.0025607 -0.01415 -0.03977900000000001 0.0021213 -0.0158 -0.0408395 0.00256076 -0.014975 -0.04190000000000001 0 -0.0158 -0.03977900000000001 0.0021213 -0.0158 -0.0389 0 -0.0158 -0.04190000000000001 0 -0.0158 -0.0389 0 -0.0158 -0.03977900000000001 -0.0021213 -0.0158 -0.040839 -0.0025607 -0.01415 -0.0408395 -0.00256076 -0.014975 -0.03977900000000001 -0.0021213 -0.0158 -0.03977900000000001 -0.0021213 -0.0158 -0.0408395 -0.00256076 -0.014975 -0.04190000000000001 -0.003 -0.0158 -0.04190000000000001 -0.003 -0.0158 -0.0408395 -0.00256076 -0.014975 -0.040839 -0.0025607 -0.01415 -0.04190000000000001 -0.003 -0.0125 -0.042961 -0.0025607 -0.01415 -0.04243050000000001 -0.00278035 -0.01415 -0.04190000000000001 -0.003 -0.0158 -0.04190000000000001 -0.003 -0.0125 -0.04243050000000001 -0.00278035 -0.01415 -0.042961 -0.0025607 -0.01415 -0.04190000000000001 -0.003 -0.0158 -0.04243050000000001 -0.00278035 -0.01415 -0.044021 -0.0021213 -0.0158 -0.042961 -0.0025607 -0.01415 -0.043491 -0.002341 -0.01415 -0.044021 -0.0021213 -0.0125 -0.044021 -0.0021213 -0.0158 -0.043491 -0.002341 -0.01415 -0.042961 -0.0025607 -0.01415 -0.044021 -0.0021213 -0.0125 -0.043491 -0.002341 -0.01415 -0.04490000000000001 0 -0.0125 -0.044461 -0.0010607 -0.01415 -0.04446070000000001 -0.00106074 -0.013325 -0.044021 -0.0021213 -0.0125 -0.04490000000000001 0 -0.0125 -0.04446070000000001 -0.00106074 -0.013325 -0.044461 -0.0010607 -0.01415 -0.044021 -0.0021213 -0.0125 -0.04446070000000001 -0.00106074 -0.013325 -0.03984900000000001 0.0020506 0.0158 -0.04190000000000001 0.0029 0.0158 -0.04190000000000001 0 0.0158 -0.04190000000000001 0.0029 0.0158 -0.042925 0.0024753 0.01415 -0.04292550000000001 0.00247521 0.014975 -0.043951 0.0020506 0.0158 -0.04190000000000001 0.0029 0.0158 -0.04292550000000001 0.00247521 0.014975 -0.042925 0.0024753 0.01415 -0.043951 0.0020506 0.0158 -0.04292550000000001 0.00247521 0.014975 -0.043951 0.0020506 0.0125 -0.044375 0.0010253 0.01415 -0.04416300000000001 0.00153795 0.01415 -0.043951 0.0020506 0.0158 -0.043951 0.0020506 0.0125 -0.04416300000000001 0.00153795 0.01415 -0.044375 0.0010253 0.01415 -0.043951 0.0020506 0.0158 -0.04416300000000001 0.00153795 0.01415 -0.04480000000000001 0 0.0125 -0.044375 0.0010253 0.01415 -0.04437530000000001 0.00102521 0.013325 -0.043951 0.0020506 0.0125 -0.04480000000000001 0 0.0125 -0.04437530000000001 0.00102521 0.013325 -0.044375 0.0010253 0.01415 -0.043951 0.0020506 0.0125 -0.04437530000000001 0.00102521 0.013325 -0.043951 -0.0020506 0.0158 -0.044375 -0.0010253 0.01415 -0.04416300000000001 -0.00153795 0.01415 -0.043951 -0.0020506 0.0125 -0.043951 -0.0020506 0.0158 -0.04416300000000001 -0.00153795 0.01415 -0.044375 -0.0010253 0.01415 -0.043951 -0.0020506 0.0125 -0.04416300000000001 -0.00153795 0.01415 -0.04480000000000001 0 0.0125 -0.044375 -0.0010253 0.01415 -0.0445875 -0.00051265 0.01415 -0.04480000000000001 0 0.0158 -0.04480000000000001 0 0.0125 -0.0445875 -0.00051265 0.01415 -0.044375 -0.0010253 0.01415 -0.04480000000000001 0 0.0158 -0.0445875 -0.00051265 0.01415 -0.042925 -0.0024753 0.01415 -0.04292550000000001 -0.00247521 0.014975 -0.043951 -0.0020506 0.0158 -0.043951 -0.0020506 0.0158 -0.04292550000000001 -0.00247521 0.014975 -0.04190000000000001 -0.0029 0.0158 -0.04190000000000001 -0.0029 0.0158 -0.04292550000000001 -0.00247521 0.014975 -0.042925 -0.0024753 0.01415 -0.03984900000000001 -0.0020506 0.0158 -0.04190000000000001 0 0.0158 -0.04190000000000001 -0.0029 0.0158 -0.044021 0.0021213 -0.0125 -0.044461 0.0010607 -0.01415 -0.04446070000000001 0.00106074 -0.013325 -0.04490000000000001 0 -0.0125 -0.044021 0.0021213 -0.0125 -0.04446070000000001 0.00106074 -0.013325 -0.044461 0.0010607 -0.01415 -0.04490000000000001 0 -0.0125 -0.04446070000000001 0.00106074 -0.013325 -0.042961 0.0025607 -0.01415 -0.0429605 0.00256076 -0.014975 -0.044021 0.0021213 -0.0158 -0.044021 0.0021213 -0.0158 -0.0429605 0.00256076 -0.014975 -0.04190000000000001 0.003 -0.0158 -0.04190000000000001 0.003 -0.0158 -0.0429605 0.00256076 -0.014975 -0.042961 0.0025607 -0.01415 -0.044021 0.0021213 -0.0158 -0.044461 0.0010607 -0.01415 -0.044241 0.001591 -0.01415 -0.044021 0.0021213 -0.0125 -0.044021 0.0021213 -0.0158 -0.044241 0.001591 -0.01415 -0.044461 0.0010607 -0.01415 -0.044021 0.0021213 -0.0125 -0.044241 0.001591 -0.01415 -0.04190000000000001 0.003 -0.0158 -0.03977900000000001 0.0021213 -0.0158 -0.04190000000000001 0 -0.0158 -0.04190000000000001 -0.003 -0.0158 -0.04190000000000001 0 -0.0158 -0.03977900000000001 -0.0021213 -0.0158 -0.04190000000000001 -0.003 -0.0158 -0.042961 -0.0025607 -0.01415 -0.0429605 -0.00256076 -0.014975 -0.044021 -0.0021213 -0.0158 -0.04190000000000001 -0.003 -0.0158 -0.0429605 -0.00256076 -0.014975 -0.042961 -0.0025607 -0.01415 -0.044021 -0.0021213 -0.0158 -0.0429605 -0.00256076 -0.014975 -0.044021 -0.0021213 -0.0125 -0.044461 -0.0010607 -0.01415 -0.044241 -0.001591 -0.01415 -0.044021 -0.0021213 -0.0158 -0.044021 -0.0021213 -0.0125 -0.044241 -0.001591 -0.01415 -0.044461 -0.0010607 -0.01415 -0.044021 -0.0021213 -0.0158 -0.044241 -0.001591 -0.01415 -0.04490000000000001 0 -0.0158 -0.044461 -0.0010607 -0.01415 -0.0446805 -0.00053035 -0.01415 -0.04490000000000001 0 -0.0125 -0.04490000000000001 0 -0.0158 -0.0446805 -0.00053035 -0.01415 -0.044461 -0.0010607 -0.01415 -0.04490000000000001 0 -0.0125 -0.0446805 -0.00053035 -0.01415 -0.04190000000000001 0 0.0158 -0.04190000000000001 0.0029 0.0158 -0.043951 0.0020506 0.0158 -0.043951 0.0020506 0.0158 -0.044375 0.0010253 0.01415 -0.04437530000000001 0.00102521 0.014975 -0.04480000000000001 0 0.0158 -0.043951 0.0020506 0.0158 -0.04437530000000001 0.00102521 0.014975 -0.044375 0.0010253 0.01415 -0.04480000000000001 0 0.0158 -0.04437530000000001 0.00102521 0.014975 -0.04480000000000001 0 0.0158 -0.044375 0.0010253 0.01415 -0.0445875 0.00051265 0.01415 -0.04480000000000001 0 0.0125 -0.04480000000000001 0 0.0158 -0.0445875 0.00051265 0.01415 -0.044375 0.0010253 0.01415 -0.04480000000000001 0 0.0125 -0.0445875 0.00051265 0.01415 -0.04480000000000001 0 0.0158 -0.044375 -0.0010253 0.01415 -0.04437530000000001 -0.00102521 0.014975 -0.043951 -0.0020506 0.0158 -0.04480000000000001 0 0.0158 -0.04437530000000001 -0.00102521 0.014975 -0.044375 -0.0010253 0.01415 -0.043951 -0.0020506 0.0158 -0.04437530000000001 -0.00102521 0.014975 -0.04190000000000001 -0.0029 0.0158 -0.04190000000000001 0 0.0158 -0.043951 -0.0020506 0.0158 -0.04490000000000001 0 -0.0125 -0.044461 0.0010607 -0.01415 -0.0446805 0.00053035 -0.01415 -0.04490000000000001 0 -0.0158 -0.04490000000000001 0 -0.0125 -0.0446805 0.00053035 -0.01415 -0.044461 0.0010607 -0.01415 -0.04490000000000001 0 -0.0158 -0.0446805 0.00053035 -0.01415 -0.044021 0.0021213 -0.0158 -0.04190000000000001 0.003 -0.0158 -0.04190000000000001 0 -0.0158 -0.04490000000000001 0 -0.0158 -0.044461 0.0010607 -0.01415 -0.04446070000000001 0.00106074 -0.014975 -0.044021 0.0021213 -0.0158 -0.04490000000000001 0 -0.0158 -0.04446070000000001 0.00106074 -0.014975 -0.044461 0.0010607 -0.01415 -0.044021 0.0021213 -0.0158 -0.04446070000000001 0.00106074 -0.014975 -0.044021 -0.0021213 -0.0158 -0.04190000000000001 0 -0.0158 -0.04190000000000001 -0.003 -0.0158 -0.044461 -0.0010607 -0.01415 -0.04446070000000001 -0.00106074 -0.014975 -0.044021 -0.0021213 -0.0158 -0.044021 -0.0021213 -0.0158 -0.04446070000000001 -0.00106074 -0.014975 -0.04490000000000001 0 -0.0158 -0.04490000000000001 0 -0.0158 -0.04446070000000001 -0.00106074 -0.014975 -0.044461 -0.0010607 -0.01415 -0.04190000000000001 0 0.0158 -0.043951 0.0020506 0.0158 -0.04480000000000001 0 0.0158 -0.04190000000000001 0 0.0158 -0.04480000000000001 0 0.0158 -0.043951 -0.0020506 0.0158 -0.04490000000000001 0 -0.0158 -0.044021 0.0021213 -0.0158 -0.04190000000000001 0 -0.0158 -0.04490000000000001 0 -0.0158 -0.04190000000000001 0 -0.0158 -0.044021 -0.0021213 -0.0158 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265

    -
    -
    - - - -3.469446951953614e-18 0 0 - 1 0 0 0 - - true - - - -
    - - - - -0.01722999999999999 -0.00062 0.0153 -0.004453999999999993 0.0072397 0.0148 -0.03000599999999999 -0.0084797 0.0148 -0.03000599999999999 -0.0084797 0.0148 -0.03000599999999999 -0.0084797 0.0158 -0.01722999999999999 -0.00062 0.0153 -0.03000799999999999 -0.0119797 0.0148 -0.03000599999999999 -0.0084797 0.0148 -0.004453999999999993 0.0072397 0.0148 -0.01722999999999999 -0.00062 0.0153 -0.004453999999999993 0.0072397 0.0158 -0.004453999999999993 0.0072397 0.0148 -0.01722999999999999 -0.00062 0.0153 -0.03000599999999999 -0.0084797 0.0158 -0.004453999999999993 0.0072397 0.0158 -0.03000599999999999 -0.0084797 0.0158 -0.03000599999999999 -0.0084797 0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.003496999999999993 0.0077473 0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.004453999999999993 0.0072397 0.0148 -0.004453999999999993 0.0072397 0.0158 -0.003975989999999993 0.0074935 0.0153 -0.004214999999999993 0.0073666 0.0153 -0.004453999999999993 0.0072397 0.0148 -0.004453999999999993 0.0072397 0.0158 -0.004214999999999993 0.0073666 0.0153 -0.003975989999999993 0.0074935 0.0153 -0.004453999999999993 0.0072397 0.0148 -0.004214999999999993 0.0073666 0.0153 -0.004453999999999993 0.0072397 0.0158 -0.03000599999999999 -0.0084797 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.03000599999999999 -0.0084797 0.0158 -0.03000799999999999 -0.0119797 0.0148 -0.03000899999999999 -0.0129797 0.0158 -0.004453999999999993 0.0072397 0.0148 -0.003975989999999993 0.0074935 0.0153 -0.003975549999999993 0.0074936 0.01505 -0.003496999999999993 0.0077473 0.0148 -0.004453999999999993 0.0072397 0.0148 -0.003975549999999993 0.0074936 0.01505 -0.003975989999999993 0.0074935 0.0153 -0.003496999999999993 0.0077473 0.0148 -0.003975549999999993 0.0074936 0.01505 -0.03000799999999999 -0.0119797 0.0148 -0.003496999999999993 0.0077473 0.0148 -0.01000599999999999 -0.008493199999999999 0.0148 -0.003975989999999993 0.0074935 0.0153 -0.003975549999999993 0.0074936 0.01555 -0.003496999999999993 0.0077473 0.0158 -0.003496999999999993 0.0077473 0.0158 -0.003975549999999993 0.0074936 0.01555 -0.004453999999999993 0.0072397 0.0158 -0.004453999999999993 0.0072397 0.0158 -0.003975549999999993 0.0074936 0.01555 -0.003975989999999993 0.0074935 0.0153 -0.003496999999999993 0.0077473 0.0158 -0.004453999999999993 0.0072397 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.03000799999999999 -0.0119797 0.0148 -0.03000899999999999 -0.0129797 -0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.003496999999999993 0.0077473 0.0148 -0.003975989999999993 0.0074935 0.0153 -0.003736499999999993 0.0076204 0.0153 -0.003496999999999993 0.0077473 0.0158 -0.003496999999999993 0.0077473 0.0148 -0.003736499999999993 0.0076204 0.0153 -0.003975989999999993 0.0074935 0.0153 -0.003496999999999993 0.0077473 0.0158 -0.003736499999999993 0.0076204 0.0153 -0.01000599999999999 -0.008493199999999999 0.0148 -0.003496999999999993 0.0077473 0.0148 0.01273690000000001 -0.0085086 0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.01000599999999999 -0.008493199999999999 0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.01000599999999999 -0.008493199999999999 0.0158 -0.003496999999999993 0.0077473 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.02886979999999999 -0.0129805 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.02999999999999999 -0.0129797 0.014 -0.02886979999999999 -0.0129805 -0.014 -0.02999999999999999 -0.0129797 -0.014 -0.03000899999999999 -0.0129797 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.0129797 0.014 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.0129797 0 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.0129797 0 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.0129797 -0.014 -0.03000799999999999 -0.0119797 -0.0148 -0.03000899999999999 -0.0129797 -0.0158 -0.03000799999999999 -0.0119797 0.0148 0.004620000000000007 -0.000380699 0.0153 -0.003496999999999993 0.0077473 0.0148 -0.003496999999999993 0.0077473 0.0158 0.004620000000000007 -0.000380699 0.0153 0.01273690000000001 -0.0085086 0.0148 -0.003496999999999993 0.0077473 0.0148 0.001366000000000007 -0.0085009 0.0153 -0.01000599999999999 -0.008493199999999999 0.0148 0.01273690000000001 -0.0085086 0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.01000599999999999 -0.008493199999999999 0.0148 -0.01000599999999999 -0.008493199999999999 0.0158 -0.01000799999999999 -0.0119932 0.0148 -0.02000799999999999 -0.0119865 0 -0.02000799999999999 -0.0119865 0.0074 -0.03000799999999999 -0.0119797 0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.02000799999999999 -0.0119865 0.0074 -0.02000799999999999 -0.0119865 0 -0.03000799999999999 -0.0119797 0.0148 -0.02000799999999999 -0.0119865 0.0074 -0.01000899999999999 -0.0129932 0.0158 -0.01000599999999999 -0.008493199999999999 0.0158 -0.03000899999999999 -0.0129797 0.0158 0.01273690000000001 -0.0085086 0.0158 -0.003496999999999993 0.0077473 0.0158 -0.01000599999999999 -0.008493199999999999 0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02247719999999999 -0.0129848 -0.014 -0.02886979999999999 -0.0129805 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01000899999999999 -0.0129932 -0.0158 -0.01199999999999999 -0.0129919 -0.014 -0.01199999999999999 -0.0129919 -0.014 -0.01000899999999999 -0.0129932 -0.0158 -0.01199999999999999 -0.0129919 -0.0126542 -0.02099999999999999 -0.0129858 -0.014 -0.02000899999999999 -0.0129865 -0.0142271 -0.01348629999999999 -0.0129909 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02000899999999999 -0.0129865 -0.0142271 -0.02099999999999999 -0.0129858 -0.014 -0.01000899999999999 -0.0129932 -0.0158 -0.02000899999999999 -0.0129865 -0.0142271 -0.03000899999999999 -0.0129797 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02000899999999999 -0.0129865 -0.0142271 -0.02247719999999999 -0.0129848 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.02000899999999999 -0.0129865 -0.0142271 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 0.0158 -0.01199999999999999 -0.0129919 0.014 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.0129919 0.014 -0.01000899999999999 -0.0129932 0.0158 -0.01951979999999999 -0.0129868 0.014 -0.02099999999999999 -0.0129858 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.02852889999999999 -0.0129807 0.014 -0.02852889999999999 -0.0129807 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.02886979999999999 -0.0129805 0.014 -0.02099999999999999 -0.0129858 0.014 -0.01951979999999999 -0.0129868 0.014 -0.02000899999999999 -0.0129865 0.0142271 -0.01000899999999999 -0.0129932 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.02000899999999999 -0.0129865 0.0142271 -0.01951979999999999 -0.0129868 0.014 -0.01000899999999999 -0.0129932 0.0158 -0.02000899999999999 -0.0129865 0.0142271 -0.03000899999999999 -0.0129797 0.0158 -0.02099999999999999 -0.0129858 0.014 -0.02000899999999999 -0.0129865 0.0142271 -0.03000799999999999 -0.0119797 -0.0148 -0.03000599999999999 -0.0084797 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.03000799999999999 -0.0119797 0.0148 -0.02000799999999999 -0.0119865 0 -0.02500799999999999 -0.0119831 8.67362e-19 -0.03000799999999999 -0.0119797 -0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.02500799999999999 -0.0119831 8.67362e-19 -0.02000799999999999 -0.0119865 0 -0.03000799999999999 -0.0119797 -0.0148 -0.02500799999999999 -0.0119831 8.67362e-19 0.004620000000000007 -0.000380699 0.0153 -0.003496999999999993 0.0077473 0.0158 0.01273690000000001 -0.0085086 0.0158 0.01273690000000001 -0.0085086 0.0158 0.01273690000000001 -0.0085086 0.0148 0.004620000000000007 -0.000380699 0.0153 0.01273690000000001 -0.0085086 0.0148 0.01273690000000001 -0.0085086 0.0158 0.001366000000000007 -0.0085009 0.0153 0.001366000000000007 -0.0085009 0.0153 -0.01000599999999999 -0.008493199999999999 0.0158 -0.01000599999999999 -0.008493199999999999 0.0148 -0.01000899999999999 -0.0129932 0.0158 -0.01000799999999999 -0.0119932 0.0148 -0.01000599999999999 -0.008493199999999999 0.0158 -0.01000799999999999 -0.0119932 -0.0148 -0.02000799999999999 -0.0119865 0 -0.01500799999999999 -0.0119898 -8.67362e-19 -0.01000799999999999 -0.0119932 0.0148 -0.01000799999999999 -0.0119932 -0.0148 -0.01500799999999999 -0.0119898 -8.67362e-19 -0.02000799999999999 -0.0119865 0 -0.01000799999999999 -0.0119932 0.0148 -0.01500799999999999 -0.0119898 -8.67362e-19 0.001366000000000007 -0.0085009 0.0153 0.01273690000000001 -0.0085086 0.0158 -0.01000599999999999 -0.008493199999999999 0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 0.0158 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.0129919 -0.0126542 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 0.0158 -0.01100449999999999 -0.0129925 0 -0.01199999999999999 -0.0129919 0 -0.01199999999999999 -0.0129919 -0.00231435 -0.01100449999999999 -0.0129925 0 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.0129919 0 -0.01100449999999999 -0.0129925 0 -0.01000899999999999 -0.0129932 0.0158 -0.01199999999999999 -0.0129919 0.0116856 -0.01100449999999999 -0.0129925 0 -0.01199999999999999 -0.0129919 -0.00231435 -0.01000899999999999 -0.0129932 -0.0158 -0.01100449999999999 -0.0129925 0 -0.03000899999999999 -0.0129797 -0.0158 -0.03000599999999999 -0.0084797 -0.0158 -0.004453999999999993 0.0072397 -0.0158 -0.03000599999999999 -0.0084797 -0.0148 -0.03000599999999999 -0.0084797 -0.0158 -0.03000799999999999 -0.0119797 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.02000799999999999 -0.0119865 0 -0.02000799999999999 -0.0119865 -0.0074 -0.01000799999999999 -0.0119932 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.02000799999999999 -0.0119865 -0.0074 -0.02000799999999999 -0.0119865 0 -0.01000799999999999 -0.0119932 -0.0148 -0.02000799999999999 -0.0119865 -0.0074 -0.01000899999999999 -0.0129932 0.0158 -0.01000899999999999 -0.0129932 -0.0158 -0.01000799999999999 -0.0119932 0.0148 -0.01000899999999999 -0.0129932 -0.0158 -0.01000799999999999 -0.0119932 -0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.01000899999999999 -0.0129932 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.03000899999999999 -0.0129797 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.03000599999999999 -0.0084797 -0.0158 -0.01722999999999999 -0.00062 -0.0153 -0.004453999999999993 0.0072397 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.004453999999999993 0.0072397 -0.0158 -0.03000599999999999 -0.0084797 -0.0158 -0.03000599999999999 -0.0084797 -0.0148 -0.01722999999999999 -0.00062 -0.0153 -0.004453999999999993 0.0072397 -0.0148 -0.03000599999999999 -0.0084797 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.01000799999999999 -0.0119932 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.01000799999999999 -0.0119932 -0.0148 -0.01000899999999999 -0.0129932 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0148 0.001366000000000007 -0.0085009 -0.0153 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.003496999999999993 0.0077473 -0.0158 0.01273690000000001 -0.0085086 -0.0158 -0.01722999999999999 -0.00062 -0.0153 -0.004453999999999993 0.0072397 -0.0148 -0.004453999999999993 0.0072397 -0.0158 -0.003975989999999993 0.0074935 -0.0153 -0.003975549999999993 0.0074936 -0.01555 -0.004453999999999993 0.0072397 -0.0158 -0.004453999999999993 0.0072397 -0.0158 -0.003975549999999993 0.0074936 -0.01555 -0.003496999999999993 0.0077473 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.003975549999999993 0.0074936 -0.01555 -0.003975989999999993 0.0074935 -0.0153 -0.01722999999999999 -0.00062 -0.0153 -0.03000599999999999 -0.0084797 -0.0148 -0.004453999999999993 0.0072397 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.004453999999999993 0.0072397 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 0.001366000000000007 -0.0085009 -0.0153 -0.01000599999999999 -0.008493199999999999 -0.0158 0.01273690000000001 -0.0085086 -0.0158 0.001366000000000007 -0.0085009 -0.0153 0.01273690000000001 -0.0085086 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 0.004620000000000007 -0.000380699 -0.0153 0.01273690000000001 -0.0085086 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.004453999999999993 0.0072397 -0.0148 -0.003975989999999993 0.0074935 -0.0153 -0.004214999999999993 0.0073666 -0.0153 -0.004453999999999993 0.0072397 -0.0158 -0.004453999999999993 0.0072397 -0.0148 -0.004214999999999993 0.0073666 -0.0153 -0.003975989999999993 0.0074935 -0.0153 -0.004453999999999993 0.0072397 -0.0158 -0.004214999999999993 0.0073666 -0.0153 -0.003496999999999993 0.0077473 -0.0158 -0.003975989999999993 0.0074935 -0.0153 -0.003736499999999993 0.0076204 -0.0153 -0.003496999999999993 0.0077473 -0.0148 -0.003496999999999993 0.0077473 -0.0158 -0.003736499999999993 0.0076204 -0.0153 -0.003975989999999993 0.0074935 -0.0153 -0.003496999999999993 0.0077473 -0.0148 -0.003736499999999993 0.0076204 -0.0153 -0.003975989999999993 0.0074935 -0.0153 -0.003975549999999993 0.0074936 -0.01505 -0.003496999999999993 0.0077473 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.003975549999999993 0.0074936 -0.01505 -0.004453999999999993 0.0072397 -0.0148 -0.004453999999999993 0.0072397 -0.0148 -0.003975549999999993 0.0074936 -0.01505 -0.003975989999999993 0.0074935 -0.0153 0.01273690000000001 -0.0085086 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 0.01273690000000001 -0.0085086 -0.0158 0.01273690000000001 -0.0085086 -0.0148 0.001366000000000007 -0.0085009 -0.0153 0.004620000000000007 -0.000380699 -0.0153 -0.003496999999999993 0.0077473 -0.0158 -0.003496999999999993 0.0077473 -0.0148 0.004620000000000007 -0.000380699 -0.0153 0.01273690000000001 -0.0085086 -0.0148 0.01273690000000001 -0.0085086 -0.0158 0.01273690000000001 -0.0085086 -0.0148 0.004620000000000007 -0.000380699 -0.0153 -0.003496999999999993 0.0077473 -0.0148 -0.01722999999999999 -0.00062 0.0153 -0.004453999999999993 0.0072397 0.0148 -0.03000599999999999 -0.0084797 0.0148 -0.03000599999999999 -0.0084797 0.0148 -0.03000599999999999 -0.0084797 0.0158 -0.01722999999999999 -0.00062 0.0153 -0.03000799999999999 -0.0119797 0.0148 -0.03000599999999999 -0.0084797 0.0148 -0.004453999999999993 0.0072397 0.0148 -0.01722999999999999 -0.00062 0.0153 -0.004453999999999993 0.0072397 0.0158 -0.004453999999999993 0.0072397 0.0148 -0.01722999999999999 -0.00062 0.0153 -0.03000599999999999 -0.0084797 0.0158 -0.004453999999999993 0.0072397 0.0158 -0.03000599999999999 -0.0084797 0.0158 -0.03000599999999999 -0.0084797 0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.003496999999999993 0.0077473 0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.004453999999999993 0.0072397 0.0148 -0.004453999999999993 0.0072397 0.0158 -0.003975989999999993 0.0074935 0.0153 -0.004214999999999993 0.0073666 0.0153 -0.004453999999999993 0.0072397 0.0148 -0.004453999999999993 0.0072397 0.0158 -0.004214999999999993 0.0073666 0.0153 -0.003975989999999993 0.0074935 0.0153 -0.004453999999999993 0.0072397 0.0148 -0.004214999999999993 0.0073666 0.0153 -0.004453999999999993 0.0072397 0.0158 -0.03000599999999999 -0.0084797 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.03000599999999999 -0.0084797 0.0158 -0.03000799999999999 -0.0119797 0.0148 -0.03000899999999999 -0.0129797 0.0158 -0.004453999999999993 0.0072397 0.0148 -0.003975989999999993 0.0074935 0.0153 -0.003975549999999993 0.0074936 0.01505 -0.003496999999999993 0.0077473 0.0148 -0.004453999999999993 0.0072397 0.0148 -0.003975549999999993 0.0074936 0.01505 -0.003975989999999993 0.0074935 0.0153 -0.003496999999999993 0.0077473 0.0148 -0.003975549999999993 0.0074936 0.01505 -0.03000799999999999 -0.0119797 0.0148 -0.003496999999999993 0.0077473 0.0148 -0.01000599999999999 -0.008493199999999999 0.0148 -0.003975989999999993 0.0074935 0.0153 -0.003975549999999993 0.0074936 0.01555 -0.003496999999999993 0.0077473 0.0158 -0.003496999999999993 0.0077473 0.0158 -0.003975549999999993 0.0074936 0.01555 -0.004453999999999993 0.0072397 0.0158 -0.004453999999999993 0.0072397 0.0158 -0.003975549999999993 0.0074936 0.01555 -0.003975989999999993 0.0074935 0.0153 -0.003496999999999993 0.0077473 0.0158 -0.004453999999999993 0.0072397 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.03000799999999999 -0.0119797 0.0148 -0.03000899999999999 -0.0129797 -0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.003496999999999993 0.0077473 0.0148 -0.003975989999999993 0.0074935 0.0153 -0.003736499999999993 0.0076204 0.0153 -0.003496999999999993 0.0077473 0.0158 -0.003496999999999993 0.0077473 0.0148 -0.003736499999999993 0.0076204 0.0153 -0.003975989999999993 0.0074935 0.0153 -0.003496999999999993 0.0077473 0.0158 -0.003736499999999993 0.0076204 0.0153 -0.01000599999999999 -0.008493199999999999 0.0148 -0.003496999999999993 0.0077473 0.0148 0.01273690000000001 -0.0085086 0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.01000599999999999 -0.008493199999999999 0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.01000599999999999 -0.008493199999999999 0.0158 -0.003496999999999993 0.0077473 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.02886979999999999 -0.0129805 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.02999999999999999 -0.0129797 0.014 -0.02886979999999999 -0.0129805 -0.014 -0.02999999999999999 -0.0129797 -0.014 -0.03000899999999999 -0.0129797 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.0129797 0.014 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.0129797 0 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.0129797 0 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.0129797 -0.014 -0.03000799999999999 -0.0119797 -0.0148 -0.03000899999999999 -0.0129797 -0.0158 -0.03000799999999999 -0.0119797 0.0148 0.004620000000000007 -0.000380699 0.0153 -0.003496999999999993 0.0077473 0.0148 -0.003496999999999993 0.0077473 0.0158 0.004620000000000007 -0.000380699 0.0153 0.01273690000000001 -0.0085086 0.0148 -0.003496999999999993 0.0077473 0.0148 0.001366000000000007 -0.0085009 0.0153 -0.01000599999999999 -0.008493199999999999 0.0148 0.01273690000000001 -0.0085086 0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.01000599999999999 -0.008493199999999999 0.0148 -0.01000599999999999 -0.008493199999999999 0.0158 -0.01000799999999999 -0.0119932 0.0148 -0.02000799999999999 -0.0119865 0 -0.02000799999999999 -0.0119865 0.0074 -0.03000799999999999 -0.0119797 0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.02000799999999999 -0.0119865 0.0074 -0.02000799999999999 -0.0119865 0 -0.03000799999999999 -0.0119797 0.0148 -0.02000799999999999 -0.0119865 0.0074 -0.01000899999999999 -0.0129932 0.0158 -0.01000599999999999 -0.008493199999999999 0.0158 -0.03000899999999999 -0.0129797 0.0158 0.01273690000000001 -0.0085086 0.0158 -0.003496999999999993 0.0077473 0.0158 -0.01000599999999999 -0.008493199999999999 0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02247719999999999 -0.0129848 -0.014 -0.02886979999999999 -0.0129805 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01000899999999999 -0.0129932 -0.0158 -0.01199999999999999 -0.0129919 -0.014 -0.01199999999999999 -0.0129919 -0.014 -0.01000899999999999 -0.0129932 -0.0158 -0.01199999999999999 -0.0129919 -0.0126542 -0.02099999999999999 -0.0129858 -0.014 -0.02000899999999999 -0.0129865 -0.0142271 -0.01348629999999999 -0.0129909 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02000899999999999 -0.0129865 -0.0142271 -0.02099999999999999 -0.0129858 -0.014 -0.01000899999999999 -0.0129932 -0.0158 -0.02000899999999999 -0.0129865 -0.0142271 -0.03000899999999999 -0.0129797 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02000899999999999 -0.0129865 -0.0142271 -0.02247719999999999 -0.0129848 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.02000899999999999 -0.0129865 -0.0142271 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 0.0158 -0.01199999999999999 -0.0129919 0.014 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.0129919 0.014 -0.01000899999999999 -0.0129932 0.0158 -0.01951979999999999 -0.0129868 0.014 -0.02099999999999999 -0.0129858 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.02852889999999999 -0.0129807 0.014 -0.02852889999999999 -0.0129807 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.02886979999999999 -0.0129805 0.014 -0.02099999999999999 -0.0129858 0.014 -0.01951979999999999 -0.0129868 0.014 -0.02000899999999999 -0.0129865 0.0142271 -0.01000899999999999 -0.0129932 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.02000899999999999 -0.0129865 0.0142271 -0.01951979999999999 -0.0129868 0.014 -0.01000899999999999 -0.0129932 0.0158 -0.02000899999999999 -0.0129865 0.0142271 -0.03000899999999999 -0.0129797 0.0158 -0.02099999999999999 -0.0129858 0.014 -0.02000899999999999 -0.0129865 0.0142271 -0.03000799999999999 -0.0119797 -0.0148 -0.03000599999999999 -0.0084797 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.03000799999999999 -0.0119797 0.0148 -0.02000799999999999 -0.0119865 0 -0.02500799999999999 -0.0119831 8.67362e-19 -0.03000799999999999 -0.0119797 -0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.02500799999999999 -0.0119831 8.67362e-19 -0.02000799999999999 -0.0119865 0 -0.03000799999999999 -0.0119797 -0.0148 -0.02500799999999999 -0.0119831 8.67362e-19 0.004620000000000007 -0.000380699 0.0153 -0.003496999999999993 0.0077473 0.0158 0.01273690000000001 -0.0085086 0.0158 0.01273690000000001 -0.0085086 0.0158 0.01273690000000001 -0.0085086 0.0148 0.004620000000000007 -0.000380699 0.0153 0.01273690000000001 -0.0085086 0.0148 0.01273690000000001 -0.0085086 0.0158 0.001366000000000007 -0.0085009 0.0153 0.001366000000000007 -0.0085009 0.0153 -0.01000599999999999 -0.008493199999999999 0.0158 -0.01000599999999999 -0.008493199999999999 0.0148 -0.01000899999999999 -0.0129932 0.0158 -0.01000799999999999 -0.0119932 0.0148 -0.01000599999999999 -0.008493199999999999 0.0158 -0.01000799999999999 -0.0119932 -0.0148 -0.02000799999999999 -0.0119865 0 -0.01500799999999999 -0.0119898 -8.67362e-19 -0.01000799999999999 -0.0119932 0.0148 -0.01000799999999999 -0.0119932 -0.0148 -0.01500799999999999 -0.0119898 -8.67362e-19 -0.02000799999999999 -0.0119865 0 -0.01000799999999999 -0.0119932 0.0148 -0.01500799999999999 -0.0119898 -8.67362e-19 0.001366000000000007 -0.0085009 0.0153 0.01273690000000001 -0.0085086 0.0158 -0.01000599999999999 -0.008493199999999999 0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 0.0158 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.0129919 -0.0126542 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 0.0158 -0.01100449999999999 -0.0129925 0 -0.01199999999999999 -0.0129919 0 -0.01199999999999999 -0.0129919 -0.00231435 -0.01100449999999999 -0.0129925 0 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.0129919 0 -0.01100449999999999 -0.0129925 0 -0.01000899999999999 -0.0129932 0.0158 -0.01199999999999999 -0.0129919 0.0116856 -0.01100449999999999 -0.0129925 0 -0.01199999999999999 -0.0129919 -0.00231435 -0.01000899999999999 -0.0129932 -0.0158 -0.01100449999999999 -0.0129925 0 -0.03000899999999999 -0.0129797 -0.0158 -0.03000599999999999 -0.0084797 -0.0158 -0.004453999999999993 0.0072397 -0.0158 -0.03000599999999999 -0.0084797 -0.0148 -0.03000599999999999 -0.0084797 -0.0158 -0.03000799999999999 -0.0119797 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.02000799999999999 -0.0119865 0 -0.02000799999999999 -0.0119865 -0.0074 -0.01000799999999999 -0.0119932 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.02000799999999999 -0.0119865 -0.0074 -0.02000799999999999 -0.0119865 0 -0.01000799999999999 -0.0119932 -0.0148 -0.02000799999999999 -0.0119865 -0.0074 -0.01000899999999999 -0.0129932 0.0158 -0.01000899999999999 -0.0129932 -0.0158 -0.01000799999999999 -0.0119932 0.0148 -0.01000899999999999 -0.0129932 -0.0158 -0.01000799999999999 -0.0119932 -0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.01000899999999999 -0.0129932 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.03000899999999999 -0.0129797 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.03000599999999999 -0.0084797 -0.0158 -0.01722999999999999 -0.00062 -0.0153 -0.004453999999999993 0.0072397 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.004453999999999993 0.0072397 -0.0158 -0.03000599999999999 -0.0084797 -0.0158 -0.03000599999999999 -0.0084797 -0.0148 -0.01722999999999999 -0.00062 -0.0153 -0.004453999999999993 0.0072397 -0.0148 -0.03000599999999999 -0.0084797 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.01000799999999999 -0.0119932 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.01000799999999999 -0.0119932 -0.0148 -0.01000899999999999 -0.0129932 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0148 0.001366000000000007 -0.0085009 -0.0153 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.003496999999999993 0.0077473 -0.0158 0.01273690000000001 -0.0085086 -0.0158 -0.01722999999999999 -0.00062 -0.0153 -0.004453999999999993 0.0072397 -0.0148 -0.004453999999999993 0.0072397 -0.0158 -0.003975989999999993 0.0074935 -0.0153 -0.003975549999999993 0.0074936 -0.01555 -0.004453999999999993 0.0072397 -0.0158 -0.004453999999999993 0.0072397 -0.0158 -0.003975549999999993 0.0074936 -0.01555 -0.003496999999999993 0.0077473 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.003975549999999993 0.0074936 -0.01555 -0.003975989999999993 0.0074935 -0.0153 -0.01722999999999999 -0.00062 -0.0153 -0.03000599999999999 -0.0084797 -0.0148 -0.004453999999999993 0.0072397 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.004453999999999993 0.0072397 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 0.001366000000000007 -0.0085009 -0.0153 -0.01000599999999999 -0.008493199999999999 -0.0158 0.01273690000000001 -0.0085086 -0.0158 0.001366000000000007 -0.0085009 -0.0153 0.01273690000000001 -0.0085086 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 0.004620000000000007 -0.000380699 -0.0153 0.01273690000000001 -0.0085086 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.004453999999999993 0.0072397 -0.0148 -0.003975989999999993 0.0074935 -0.0153 -0.004214999999999993 0.0073666 -0.0153 -0.004453999999999993 0.0072397 -0.0158 -0.004453999999999993 0.0072397 -0.0148 -0.004214999999999993 0.0073666 -0.0153 -0.003975989999999993 0.0074935 -0.0153 -0.004453999999999993 0.0072397 -0.0158 -0.004214999999999993 0.0073666 -0.0153 -0.003496999999999993 0.0077473 -0.0158 -0.003975989999999993 0.0074935 -0.0153 -0.003736499999999993 0.0076204 -0.0153 -0.003496999999999993 0.0077473 -0.0148 -0.003496999999999993 0.0077473 -0.0158 -0.003736499999999993 0.0076204 -0.0153 -0.003975989999999993 0.0074935 -0.0153 -0.003496999999999993 0.0077473 -0.0148 -0.003736499999999993 0.0076204 -0.0153 -0.003975989999999993 0.0074935 -0.0153 -0.003975549999999993 0.0074936 -0.01505 -0.003496999999999993 0.0077473 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.003975549999999993 0.0074936 -0.01505 -0.004453999999999993 0.0072397 -0.0148 -0.004453999999999993 0.0072397 -0.0148 -0.003975549999999993 0.0074936 -0.01505 -0.003975989999999993 0.0074935 -0.0153 0.01273690000000001 -0.0085086 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 0.01273690000000001 -0.0085086 -0.0158 0.01273690000000001 -0.0085086 -0.0148 0.001366000000000007 -0.0085009 -0.0153 0.004620000000000007 -0.000380699 -0.0153 -0.003496999999999993 0.0077473 -0.0158 -0.003496999999999993 0.0077473 -0.0148 0.004620000000000007 -0.000380699 -0.0153 0.01273690000000001 -0.0085086 -0.0148 0.01273690000000001 -0.0085086 -0.0158 0.01273690000000001 -0.0085086 -0.0148 0.004620000000000007 -0.000380699 -0.0153 -0.003496999999999993 0.0077473 -0.0148 -0.01722999999999999 -0.00062 0.0153 -0.004453999999999993 0.0072397 0.0148 -0.03000599999999999 -0.0084797 0.0148 -0.03000599999999999 -0.0084797 0.0148 -0.03000599999999999 -0.0084797 0.0158 -0.01722999999999999 -0.00062 0.0153 -0.03000799999999999 -0.0119797 0.0148 -0.03000599999999999 -0.0084797 0.0148 -0.004453999999999993 0.0072397 0.0148 -0.01722999999999999 -0.00062 0.0153 -0.004453999999999993 0.0072397 0.0158 -0.004453999999999993 0.0072397 0.0148 -0.01722999999999999 -0.00062 0.0153 -0.03000599999999999 -0.0084797 0.0158 -0.004453999999999993 0.0072397 0.0158 -0.03000599999999999 -0.0084797 0.0158 -0.03000599999999999 -0.0084797 0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.003496999999999993 0.0077473 0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.004453999999999993 0.0072397 0.0148 -0.004453999999999993 0.0072397 0.0158 -0.003975989999999993 0.0074935 0.0153 -0.004214999999999993 0.0073666 0.0153 -0.004453999999999993 0.0072397 0.0148 -0.004453999999999993 0.0072397 0.0158 -0.004214999999999993 0.0073666 0.0153 -0.003975989999999993 0.0074935 0.0153 -0.004453999999999993 0.0072397 0.0148 -0.004214999999999993 0.0073666 0.0153 -0.004453999999999993 0.0072397 0.0158 -0.03000599999999999 -0.0084797 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.03000599999999999 -0.0084797 0.0158 -0.03000799999999999 -0.0119797 0.0148 -0.03000899999999999 -0.0129797 0.0158 -0.004453999999999993 0.0072397 0.0148 -0.003975989999999993 0.0074935 0.0153 -0.003975549999999993 0.0074936 0.01505 -0.003496999999999993 0.0077473 0.0148 -0.004453999999999993 0.0072397 0.0148 -0.003975549999999993 0.0074936 0.01505 -0.003975989999999993 0.0074935 0.0153 -0.003496999999999993 0.0077473 0.0148 -0.003975549999999993 0.0074936 0.01505 -0.03000799999999999 -0.0119797 0.0148 -0.003496999999999993 0.0077473 0.0148 -0.01000599999999999 -0.008493199999999999 0.0148 -0.003975989999999993 0.0074935 0.0153 -0.003975549999999993 0.0074936 0.01555 -0.003496999999999993 0.0077473 0.0158 -0.003496999999999993 0.0077473 0.0158 -0.003975549999999993 0.0074936 0.01555 -0.004453999999999993 0.0072397 0.0158 -0.004453999999999993 0.0072397 0.0158 -0.003975549999999993 0.0074936 0.01555 -0.003975989999999993 0.0074935 0.0153 -0.003496999999999993 0.0077473 0.0158 -0.004453999999999993 0.0072397 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.03000799999999999 -0.0119797 0.0148 -0.03000899999999999 -0.0129797 -0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.003496999999999993 0.0077473 0.0148 -0.003975989999999993 0.0074935 0.0153 -0.003736499999999993 0.0076204 0.0153 -0.003496999999999993 0.0077473 0.0158 -0.003496999999999993 0.0077473 0.0148 -0.003736499999999993 0.0076204 0.0153 -0.003975989999999993 0.0074935 0.0153 -0.003496999999999993 0.0077473 0.0158 -0.003736499999999993 0.0076204 0.0153 -0.01000599999999999 -0.008493199999999999 0.0148 -0.003496999999999993 0.0077473 0.0148 0.01273690000000001 -0.0085086 0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.01000599999999999 -0.008493199999999999 0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.01000599999999999 -0.008493199999999999 0.0158 -0.003496999999999993 0.0077473 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.02886979999999999 -0.0129805 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.02999999999999999 -0.0129797 0.014 -0.02886979999999999 -0.0129805 -0.014 -0.02999999999999999 -0.0129797 -0.014 -0.03000899999999999 -0.0129797 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.0129797 0.014 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.0129797 0 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.0129797 0 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.0129797 -0.014 -0.03000799999999999 -0.0119797 -0.0148 -0.03000899999999999 -0.0129797 -0.0158 -0.03000799999999999 -0.0119797 0.0148 0.004620000000000007 -0.000380699 0.0153 -0.003496999999999993 0.0077473 0.0148 -0.003496999999999993 0.0077473 0.0158 0.004620000000000007 -0.000380699 0.0153 0.01273690000000001 -0.0085086 0.0148 -0.003496999999999993 0.0077473 0.0148 0.001366000000000007 -0.0085009 0.0153 -0.01000599999999999 -0.008493199999999999 0.0148 0.01273690000000001 -0.0085086 0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.01000599999999999 -0.008493199999999999 0.0148 -0.01000599999999999 -0.008493199999999999 0.0158 -0.01000799999999999 -0.0119932 0.0148 -0.02000799999999999 -0.0119865 0 -0.02000799999999999 -0.0119865 0.0074 -0.03000799999999999 -0.0119797 0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.02000799999999999 -0.0119865 0.0074 -0.02000799999999999 -0.0119865 0 -0.03000799999999999 -0.0119797 0.0148 -0.02000799999999999 -0.0119865 0.0074 -0.01000899999999999 -0.0129932 0.0158 -0.01000599999999999 -0.008493199999999999 0.0158 -0.03000899999999999 -0.0129797 0.0158 0.01273690000000001 -0.0085086 0.0158 -0.003496999999999993 0.0077473 0.0158 -0.01000599999999999 -0.008493199999999999 0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02247719999999999 -0.0129848 -0.014 -0.02886979999999999 -0.0129805 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01000899999999999 -0.0129932 -0.0158 -0.01199999999999999 -0.0129919 -0.014 -0.01199999999999999 -0.0129919 -0.014 -0.01000899999999999 -0.0129932 -0.0158 -0.01199999999999999 -0.0129919 -0.0126542 -0.02099999999999999 -0.0129858 -0.014 -0.02000899999999999 -0.0129865 -0.0142271 -0.01348629999999999 -0.0129909 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02000899999999999 -0.0129865 -0.0142271 -0.02099999999999999 -0.0129858 -0.014 -0.01000899999999999 -0.0129932 -0.0158 -0.02000899999999999 -0.0129865 -0.0142271 -0.03000899999999999 -0.0129797 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02000899999999999 -0.0129865 -0.0142271 -0.02247719999999999 -0.0129848 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.02000899999999999 -0.0129865 -0.0142271 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 0.0158 -0.01199999999999999 -0.0129919 0.014 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.0129919 0.014 -0.01000899999999999 -0.0129932 0.0158 -0.01951979999999999 -0.0129868 0.014 -0.02099999999999999 -0.0129858 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.02852889999999999 -0.0129807 0.014 -0.02852889999999999 -0.0129807 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.02886979999999999 -0.0129805 0.014 -0.02099999999999999 -0.0129858 0.014 -0.01951979999999999 -0.0129868 0.014 -0.02000899999999999 -0.0129865 0.0142271 -0.01000899999999999 -0.0129932 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.02000899999999999 -0.0129865 0.0142271 -0.01951979999999999 -0.0129868 0.014 -0.01000899999999999 -0.0129932 0.0158 -0.02000899999999999 -0.0129865 0.0142271 -0.03000899999999999 -0.0129797 0.0158 -0.02099999999999999 -0.0129858 0.014 -0.02000899999999999 -0.0129865 0.0142271 -0.03000799999999999 -0.0119797 -0.0148 -0.03000599999999999 -0.0084797 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.03000799999999999 -0.0119797 0.0148 -0.02000799999999999 -0.0119865 0 -0.02500799999999999 -0.0119831 8.67362e-19 -0.03000799999999999 -0.0119797 -0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.02500799999999999 -0.0119831 8.67362e-19 -0.02000799999999999 -0.0119865 0 -0.03000799999999999 -0.0119797 -0.0148 -0.02500799999999999 -0.0119831 8.67362e-19 0.004620000000000007 -0.000380699 0.0153 -0.003496999999999993 0.0077473 0.0158 0.01273690000000001 -0.0085086 0.0158 0.01273690000000001 -0.0085086 0.0158 0.01273690000000001 -0.0085086 0.0148 0.004620000000000007 -0.000380699 0.0153 0.01273690000000001 -0.0085086 0.0148 0.01273690000000001 -0.0085086 0.0158 0.001366000000000007 -0.0085009 0.0153 0.001366000000000007 -0.0085009 0.0153 -0.01000599999999999 -0.008493199999999999 0.0158 -0.01000599999999999 -0.008493199999999999 0.0148 -0.01000899999999999 -0.0129932 0.0158 -0.01000799999999999 -0.0119932 0.0148 -0.01000599999999999 -0.008493199999999999 0.0158 -0.01000799999999999 -0.0119932 -0.0148 -0.02000799999999999 -0.0119865 0 -0.01500799999999999 -0.0119898 -8.67362e-19 -0.01000799999999999 -0.0119932 0.0148 -0.01000799999999999 -0.0119932 -0.0148 -0.01500799999999999 -0.0119898 -8.67362e-19 -0.02000799999999999 -0.0119865 0 -0.01000799999999999 -0.0119932 0.0148 -0.01500799999999999 -0.0119898 -8.67362e-19 0.001366000000000007 -0.0085009 0.0153 0.01273690000000001 -0.0085086 0.0158 -0.01000599999999999 -0.008493199999999999 0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 0.0158 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.0129919 -0.0126542 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 0.0158 -0.01100449999999999 -0.0129925 0 -0.01199999999999999 -0.0129919 0 -0.01199999999999999 -0.0129919 -0.00231435 -0.01100449999999999 -0.0129925 0 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.0129919 0 -0.01100449999999999 -0.0129925 0 -0.01000899999999999 -0.0129932 0.0158 -0.01199999999999999 -0.0129919 0.0116856 -0.01100449999999999 -0.0129925 0 -0.01199999999999999 -0.0129919 -0.00231435 -0.01000899999999999 -0.0129932 -0.0158 -0.01100449999999999 -0.0129925 0 -0.03000899999999999 -0.0129797 -0.0158 -0.03000599999999999 -0.0084797 -0.0158 -0.004453999999999993 0.0072397 -0.0158 -0.03000599999999999 -0.0084797 -0.0148 -0.03000599999999999 -0.0084797 -0.0158 -0.03000799999999999 -0.0119797 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.02000799999999999 -0.0119865 0 -0.02000799999999999 -0.0119865 -0.0074 -0.01000799999999999 -0.0119932 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.02000799999999999 -0.0119865 -0.0074 -0.02000799999999999 -0.0119865 0 -0.01000799999999999 -0.0119932 -0.0148 -0.02000799999999999 -0.0119865 -0.0074 -0.01000899999999999 -0.0129932 0.0158 -0.01000899999999999 -0.0129932 -0.0158 -0.01000799999999999 -0.0119932 0.0148 -0.01000899999999999 -0.0129932 -0.0158 -0.01000799999999999 -0.0119932 -0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.01000899999999999 -0.0129932 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.03000899999999999 -0.0129797 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.03000599999999999 -0.0084797 -0.0158 -0.01722999999999999 -0.00062 -0.0153 -0.004453999999999993 0.0072397 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.004453999999999993 0.0072397 -0.0158 -0.03000599999999999 -0.0084797 -0.0158 -0.03000599999999999 -0.0084797 -0.0148 -0.01722999999999999 -0.00062 -0.0153 -0.004453999999999993 0.0072397 -0.0148 -0.03000599999999999 -0.0084797 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.01000799999999999 -0.0119932 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.01000799999999999 -0.0119932 -0.0148 -0.01000899999999999 -0.0129932 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0148 0.001366000000000007 -0.0085009 -0.0153 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.003496999999999993 0.0077473 -0.0158 0.01273690000000001 -0.0085086 -0.0158 -0.01722999999999999 -0.00062 -0.0153 -0.004453999999999993 0.0072397 -0.0148 -0.004453999999999993 0.0072397 -0.0158 -0.003975989999999993 0.0074935 -0.0153 -0.003975549999999993 0.0074936 -0.01555 -0.004453999999999993 0.0072397 -0.0158 -0.004453999999999993 0.0072397 -0.0158 -0.003975549999999993 0.0074936 -0.01555 -0.003496999999999993 0.0077473 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.003975549999999993 0.0074936 -0.01555 -0.003975989999999993 0.0074935 -0.0153 -0.01722999999999999 -0.00062 -0.0153 -0.03000599999999999 -0.0084797 -0.0148 -0.004453999999999993 0.0072397 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.004453999999999993 0.0072397 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 0.001366000000000007 -0.0085009 -0.0153 -0.01000599999999999 -0.008493199999999999 -0.0158 0.01273690000000001 -0.0085086 -0.0158 0.001366000000000007 -0.0085009 -0.0153 0.01273690000000001 -0.0085086 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 0.004620000000000007 -0.000380699 -0.0153 0.01273690000000001 -0.0085086 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.004453999999999993 0.0072397 -0.0148 -0.003975989999999993 0.0074935 -0.0153 -0.004214999999999993 0.0073666 -0.0153 -0.004453999999999993 0.0072397 -0.0158 -0.004453999999999993 0.0072397 -0.0148 -0.004214999999999993 0.0073666 -0.0153 -0.003975989999999993 0.0074935 -0.0153 -0.004453999999999993 0.0072397 -0.0158 -0.004214999999999993 0.0073666 -0.0153 -0.003496999999999993 0.0077473 -0.0158 -0.003975989999999993 0.0074935 -0.0153 -0.003736499999999993 0.0076204 -0.0153 -0.003496999999999993 0.0077473 -0.0148 -0.003496999999999993 0.0077473 -0.0158 -0.003736499999999993 0.0076204 -0.0153 -0.003975989999999993 0.0074935 -0.0153 -0.003496999999999993 0.0077473 -0.0148 -0.003736499999999993 0.0076204 -0.0153 -0.003975989999999993 0.0074935 -0.0153 -0.003975549999999993 0.0074936 -0.01505 -0.003496999999999993 0.0077473 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.003975549999999993 0.0074936 -0.01505 -0.004453999999999993 0.0072397 -0.0148 -0.004453999999999993 0.0072397 -0.0148 -0.003975549999999993 0.0074936 -0.01505 -0.003975989999999993 0.0074935 -0.0153 0.01273690000000001 -0.0085086 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 0.01273690000000001 -0.0085086 -0.0158 0.01273690000000001 -0.0085086 -0.0148 0.001366000000000007 -0.0085009 -0.0153 0.004620000000000007 -0.000380699 -0.0153 -0.003496999999999993 0.0077473 -0.0158 -0.003496999999999993 0.0077473 -0.0148 0.004620000000000007 -0.000380699 -0.0153 0.01273690000000001 -0.0085086 -0.0148 0.01273690000000001 -0.0085086 -0.0158 0.01273690000000001 -0.0085086 -0.0148 0.004620000000000007 -0.000380699 -0.0153 -0.003496999999999993 0.0077473 -0.0148 -0.02999999999999999 -0.0129797 -0.014 -0.02886979999999999 -0.0129805 -0.014 -0.02999999999999999 -0.018 -0.014 -0.02999999999999999 -0.018 -0.014 -0.02886979999999999 -0.0129805 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02886979999999999 -0.0129805 0.014 -0.02999999999999999 -0.0129797 0.014 -0.02999999999999999 -0.018 0.014 -0.02852889999999999 -0.0129807 0.014 -0.02886979999999999 -0.0129805 0.014 -0.02999999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.014 -0.02852889999999999 -0.0129807 0.014 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.0129797 0.014 -0.02999999999999999 -0.0129797 0 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.0129797 0 -0.02999999999999999 -0.0129797 -0.014 -0.02999999999999999 -0.018 -0.014 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.018 -0.014 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02099999999999999 -0.018 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02099999999999999 -0.0129858 -0.014 -0.02099999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01199999999999999 -0.018 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01199999999999999 -0.0129919 -0.014 -0.01199999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.014 -0.02099999999999999 -0.0129858 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 -0.0126542 -0.01199999999999999 -0.0129919 -0.0126542 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 -0.014 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.0129919 0.014 -0.01951979999999999 -0.0129868 0.014 -0.01951979999999999 -0.0129868 0.014 -0.02099999999999999 -0.0129858 0.014 -0.02099999999999999 -0.018 0.014 -0.01199999999999999 -0.018 0.014 -0.01951979999999999 -0.0129868 0.014 -0.02099999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.014 -0.02099999999999999 -0.0129858 0.014 -0.02852889999999999 -0.0129807 0.014 -0.01199999999999999 -0.0129919 0.014 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 0.014 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.014 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.014 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 0 -0.01199999999999999 -0.018 0 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.018 0 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.018 0 -0.01199999999999999 -0.0129919 0 -0.01199999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.014 -0.01199999999999999 -0.018 0 -0.02999999999999999 -0.018 0 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 0.007 -0.02099999999999999 -0.018 0.014 -0.02999999999999999 -0.018 0 -0.02099999999999999 -0.018 0.007 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.007 -0.01199999999999999 -0.018 0 -0.02999999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.007 -0.02099999999999999 -0.018 -0.014 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.007 -0.02999999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.007 -0.02999999999999999 -0.0129797 -0.014 -0.02886979999999999 -0.0129805 -0.014 -0.02999999999999999 -0.018 -0.014 -0.02999999999999999 -0.018 -0.014 -0.02886979999999999 -0.0129805 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02886979999999999 -0.0129805 0.014 -0.02999999999999999 -0.0129797 0.014 -0.02999999999999999 -0.018 0.014 -0.02852889999999999 -0.0129807 0.014 -0.02886979999999999 -0.0129805 0.014 -0.02999999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.014 -0.02852889999999999 -0.0129807 0.014 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.0129797 0.014 -0.02999999999999999 -0.0129797 0 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.0129797 0 -0.02999999999999999 -0.0129797 -0.014 -0.02999999999999999 -0.018 -0.014 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.018 -0.014 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02099999999999999 -0.018 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02099999999999999 -0.0129858 -0.014 -0.02099999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01199999999999999 -0.018 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01199999999999999 -0.0129919 -0.014 -0.01199999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.014 -0.02099999999999999 -0.0129858 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 -0.0126542 -0.01199999999999999 -0.0129919 -0.0126542 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 -0.014 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.0129919 0.014 -0.01951979999999999 -0.0129868 0.014 -0.01951979999999999 -0.0129868 0.014 -0.02099999999999999 -0.0129858 0.014 -0.02099999999999999 -0.018 0.014 -0.01199999999999999 -0.018 0.014 -0.01951979999999999 -0.0129868 0.014 -0.02099999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.014 -0.02099999999999999 -0.0129858 0.014 -0.02852889999999999 -0.0129807 0.014 -0.01199999999999999 -0.0129919 0.014 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 0.014 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.014 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.014 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 0 -0.01199999999999999 -0.018 0 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.018 0 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.018 0 -0.01199999999999999 -0.0129919 0 -0.01199999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.014 -0.01199999999999999 -0.018 0 -0.02999999999999999 -0.018 0 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 0.007 -0.02099999999999999 -0.018 0.014 -0.02999999999999999 -0.018 0 -0.02099999999999999 -0.018 0.007 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.007 -0.01199999999999999 -0.018 0 -0.02999999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.007 -0.02099999999999999 -0.018 -0.014 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.007 -0.02999999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.007 -0.02999999999999999 -0.0129797 -0.014 -0.02886979999999999 -0.0129805 -0.014 -0.02999999999999999 -0.018 -0.014 -0.02999999999999999 -0.018 -0.014 -0.02886979999999999 -0.0129805 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02886979999999999 -0.0129805 0.014 -0.02999999999999999 -0.0129797 0.014 -0.02999999999999999 -0.018 0.014 -0.02852889999999999 -0.0129807 0.014 -0.02886979999999999 -0.0129805 0.014 -0.02999999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.014 -0.02852889999999999 -0.0129807 0.014 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.0129797 0.014 -0.02999999999999999 -0.0129797 0 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.0129797 0 -0.02999999999999999 -0.0129797 -0.014 -0.02999999999999999 -0.018 -0.014 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.018 -0.014 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02099999999999999 -0.018 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02099999999999999 -0.0129858 -0.014 -0.02099999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01199999999999999 -0.018 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01199999999999999 -0.0129919 -0.014 -0.01199999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.014 -0.02099999999999999 -0.0129858 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 -0.0126542 -0.01199999999999999 -0.0129919 -0.0126542 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 -0.014 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.0129919 0.014 -0.01951979999999999 -0.0129868 0.014 -0.01951979999999999 -0.0129868 0.014 -0.02099999999999999 -0.0129858 0.014 -0.02099999999999999 -0.018 0.014 -0.01199999999999999 -0.018 0.014 -0.01951979999999999 -0.0129868 0.014 -0.02099999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.014 -0.02099999999999999 -0.0129858 0.014 -0.02852889999999999 -0.0129807 0.014 -0.01199999999999999 -0.0129919 0.014 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 0.014 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.014 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.014 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 0 -0.01199999999999999 -0.018 0 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.018 0 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.018 0 -0.01199999999999999 -0.0129919 0 -0.01199999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.014 -0.01199999999999999 -0.018 0 -0.02999999999999999 -0.018 0 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 0.007 -0.02099999999999999 -0.018 0.014 -0.02999999999999999 -0.018 0 -0.02099999999999999 -0.018 0.007 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.007 -0.01199999999999999 -0.018 0 -0.02999999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.007 -0.02099999999999999 -0.018 -0.014 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.007 -0.02999999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.007 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439

    -
    -
    - - - 6.938893903907228e-18 0 0 - 1 0 0 0 - - true - - - -
    - - - - -0.030236 -0.024999 -0.01662 -0.030236 -0.032499 -0.01662 -0.033064 -0.024999 -0.009476790000000001 -0.033064 -0.024999 -0.009476790000000001 -0.030236 -0.032499 -0.01662 -0.033419 -0.024999 -0.008579989999999999 -0.033419 -0.024999 -0.008579989999999999 -0.033419 -0.032499 -0.008579989999999999 -0.034503 -0.024999 7.76846e-09 -0.03383 -0.024999 0.00678201 -0.0344958 -0.024999 7.24318e-05 -0.034503 -0.032499 8.0963e-09 -0.0312361 -0.024999 0.0195879 -0.0284953 -0.026257 0.0331192 -0.0284953 -0.024999 0.0331192 -0.03383 -0.032499 0.00678201 -0.0312361 -0.024999 0.0195879 -0.0317601 -0.024999 0.0170012 -0.03383 -0.032499 0.00678201 -0.0317601 -0.024999 0.0170012 -0.0328447 -0.024999 0.0116462 -0.03383 -0.032499 0.00678201 -0.0328447 -0.024999 0.0116462 -0.03383 -0.024999 0.00678201 -0.03383 -0.032499 0.00678201 -0.0284953 -0.026257 0.0331192 -0.0312361 -0.024999 0.0195879 -0.021981 -0.024999 0.06528 -0.0284953 -0.026257 0.0331192 -0.03383 -0.032499 0.00678201 -0.0258064 -0.024999 -0.0227164 -0.0254558 -0.0254559 -0.0231989 -0.025152 -0.032499 -0.023617 -0.0294279 -0.024999 -0.0177322 -0.0258064 -0.024999 -0.0227164 -0.025152 -0.032499 -0.023617 -0.0254558 -0.0254559 -0.0231989 -0.025152 -0.025689 -0.023617 -0.025152 -0.032499 -0.023617 -0.0294279 -0.024999 -0.0177322 -0.025152 -0.032499 -0.023617 -0.030236 -0.024999 -0.01662 -0.033419 -0.024999 -0.008579989999999999 -0.030236 -0.032499 -0.01662 -0.033419 -0.032499 -0.008579989999999999 -0.030236 -0.024999 -0.01662 -0.025152 -0.032499 -0.023617 -0.030236 -0.032499 -0.01662 -0.034503 -0.024999 7.76846e-09 -0.033419 -0.032499 -0.008579989999999999 -0.034503 -0.032499 8.0963e-09 -0.03383 -0.024999 0.00678201 -0.034503 -0.032499 8.0963e-09 -0.03383 -0.032499 0.00678201 0.0254558 -0.0254558 -0.0228897 0.027908 -0.024999 -0.020278 0.027908 -0.0325 -0.020278 0.0254558 -0.0254558 -0.0228897 0.027908 -0.0325 -0.020278 0.0235205 -0.0269408 -0.0249508 -0.0284953 -0.024999 0.0331192 -0.0277933 -0.024999 0.0331192 -0.0295147 -0.024999 0.0263536 -0.0277933 -0.024999 0.0331192 -0.030743 -0.024999 0.0202504 -0.0295147 -0.024999 0.0263536 -0.030743 -0.024999 0.0202504 -0.0312361 -0.024999 0.0195879 -0.0295147 -0.024999 0.0263536 -0.0312361 -0.024999 0.0195879 -0.0284953 -0.024999 0.0331192 -0.0295147 -0.024999 0.0263536 -0.0223204 -0.024999 0.0636043 -0.021981 -0.024999 0.06528 -0.0208059 -0.024999 0.0636043 -0.021981 -0.024999 0.06528 -0.019006 -0.024999 0.07145700000000001 -0.0208059 -0.024999 0.0636043 -0.03383 -0.032499 0.00678201 -0.021981 -0.032499 0.06528 -0.021981 -0.024999 0.06528 -0.025152 -0.032499 -0.023617 -0.025152 -0.025689 -0.023617 -0.0232262 -0.0271667 -0.0252101 -0.025152 -0.032499 -0.023617 -0.0232262 -0.0271667 -0.0252101 -0.018489 -0.032499 -0.029129 -0.0265381 -0.039499 -0.00700801 -0.033419 -0.032499 -0.008579989999999999 -0.030236 -0.032499 -0.01662 -0.025152 -0.032499 -0.023617 -0.0235285 -0.039499 -0.0141696 -0.030236 -0.032499 -0.01662 -0.0274667 -0.039499 0.000698417 -0.034503 -0.032499 8.0963e-09 -0.033419 -0.032499 -0.008579989999999999 -0.034503 -0.032499 8.0963e-09 -0.0274667 -0.039499 0.000698417 -0.03383 -0.032499 0.00678201 0.029004 -0.024999 -0.0182843 0.032074 -0.024999 -0.0127 0.032074 -0.0325 -0.0127 0.029004 -0.024999 -0.0182843 0.032074 -0.0325 -0.0127 0.027908 -0.024999 -0.020278 0.027908 -0.024999 -0.020278 0.032074 -0.0325 -0.0127 0.027908 -0.0325 -0.020278 0.0235205 -0.0269408 -0.0249508 0.027908 -0.0325 -0.020278 0.021988 -0.032499 -0.026583 0.021988 -0.0281168 -0.026583 0.0235205 -0.0269408 -0.0249508 0.021988 -0.032499 -0.026583 0.021988 -0.032499 -0.026583 0.0195459 -0.0299907 -0.0281325 0.0212823 -0.0286582 -0.0270307 0.021988 -0.032499 -0.026583 0.0212823 -0.0286582 -0.0270307 0.021988 -0.0281168 -0.026583 -0.0277933 -0.024999 0.0331192 -0.0273204 -0.024999 0.0331192 -0.0290317 -0.024999 0.0266848 -0.0273204 -0.024999 0.0331192 -0.0298516 -0.024999 0.0214477 -0.0290317 -0.024999 0.0266848 -0.0298516 -0.024999 0.0214477 -0.030743 -0.024999 0.0202504 -0.0290317 -0.024999 0.0266848 -0.030743 -0.024999 0.0202504 -0.0277933 -0.024999 0.0331192 -0.0290317 -0.024999 0.0266848 -0.0259098 -0.024999 0.0331192 -0.026916 -0.024999 0.025391 -0.0274245 -0.024999 0.0247079 -0.0259098 -0.024999 0.0331192 -0.0214843 -0.024999 0.0331193 -0.021701 -0.024999 0.0297668 -0.026916 -0.024999 0.025391 -0.0259098 -0.024999 0.0331192 -0.021701 -0.024999 0.0297668 -0.0273204 -0.024999 0.0331192 -0.0259098 -0.024999 0.0331192 -0.0278807 -0.024999 0.0272835 -0.0259098 -0.024999 0.0331192 -0.0274245 -0.024999 0.0247079 -0.0278807 -0.024999 0.0272835 -0.0274245 -0.024999 0.0247079 -0.0298516 -0.024999 0.0214477 -0.0278807 -0.024999 0.0272835 -0.0298516 -0.024999 0.0214477 -0.0273204 -0.024999 0.0331192 -0.0278807 -0.024999 0.0272835 -0.0188016 -0.024999 0.0316831 -0.0188089 -0.024999 0.0331193 -0.0159418 -0.024999 0.0331193 -0.0214843 -0.024999 0.0331193 -0.0188089 -0.024999 0.0331193 -0.0202513 -0.024999 0.031443 -0.0188089 -0.024999 0.0331193 -0.0188016 -0.024999 0.0316831 -0.0202513 -0.024999 0.031443 -0.0188016 -0.024999 0.0316831 -0.020335 -0.024999 0.030913 -0.0202513 -0.024999 0.031443 -0.020335 -0.024999 0.030913 -0.021701 -0.024999 0.0297668 -0.0202513 -0.024999 0.031443 -0.021701 -0.024999 0.0297668 -0.0214843 -0.024999 0.0331193 -0.0202513 -0.024999 0.031443 -0.0164292 -0.024999 0.06360440000000001 -0.019006 -0.024999 0.07145700000000001 -0.0127796 -0.024999 0.06360440000000001 -0.0171076 -0.024999 0.06360440000000001 -0.019006 -0.024999 0.07145700000000001 -0.0164292 -0.024999 0.06360440000000001 -0.0177574 -0.024999 0.06360440000000001 -0.019006 -0.024999 0.07145700000000001 -0.0171076 -0.024999 0.06360440000000001 -0.0183777 -0.024999 0.06360440000000001 -0.019006 -0.024999 0.07145700000000001 -0.0177574 -0.024999 0.06360440000000001 -0.0189656 -0.024999 0.06360440000000001 -0.019006 -0.024999 0.07145700000000001 -0.0183777 -0.024999 0.06360440000000001 -0.0195136 -0.024999 0.06360440000000001 -0.019006 -0.024999 0.07145700000000001 -0.0189656 -0.024999 0.06360440000000001 -0.0204201 -0.024999 0.06360440000000001 -0.019006 -0.024999 0.07145700000000001 -0.0195136 -0.024999 0.06360440000000001 -0.020709 -0.024999 0.0636043 -0.019006 -0.024999 0.07145700000000001 -0.0204201 -0.024999 0.06360440000000001 -0.0208059 -0.024999 0.0636043 -0.019006 -0.024999 0.07145700000000001 -0.020709 -0.024999 0.0636043 -0.0127796 -0.024999 0.06360440000000001 -0.019006 -0.024999 0.07145700000000001 0.00501562 -0.024999 0.0636046 0.00501562 -0.024999 0.0636046 -0.019006 -0.024999 0.07145700000000001 0.0196769 -0.024999 0.0636048 -0.019006 -0.024999 0.07145700000000001 -0.021981 -0.024999 0.06528 -0.021981 -0.032499 0.06528 -0.0160897 -0.039499 0.0591044 -0.021981 -0.032499 0.06528 -0.03383 -0.032499 0.00678201 -0.018489 -0.032499 -0.029129 -0.0223017 -0.0278761 -0.025975 -0.018489 -0.0308017 -0.029129 -0.018489 -0.032499 -0.029129 -0.0232262 -0.0271667 -0.0252101 -0.0223017 -0.0278761 -0.025975 -0.025152 -0.032499 -0.023617 -0.018489 -0.032499 -0.029129 -0.0188569 -0.039499 -0.0203722 -0.0265381 -0.039499 -0.00700801 -0.030236 -0.032499 -0.01662 -0.0235285 -0.039499 -0.0141696 -0.033419 -0.032499 -0.008579989999999999 -0.0265381 -0.039499 -0.00700801 -0.0274667 -0.039499 0.000698417 -0.0235285 -0.039499 -0.0141696 -0.025152 -0.032499 -0.023617 -0.0188569 -0.039499 -0.0203722 -0.03383 -0.032499 0.00678201 -0.0274667 -0.039499 0.000698417 -0.0267417 -0.039499 0.00678201 0.0326797 -0.024999 -0.0103416 0.034225 -0.024999 -0.004324 0.034225 -0.0325 -0.004324 0.0326797 -0.024999 -0.0103416 0.034225 -0.0325 -0.004324 0.032074 -0.024999 -0.0127 0.032074 -0.024999 -0.0127 0.034225 -0.0325 -0.004324 0.032074 -0.0325 -0.0127 0.027908 -0.0325 -0.020278 0.032074 -0.0325 -0.0127 0.0280786 -0.0354482 -0.016489 0.032074 -0.0325 -0.0127 0.025783 -0.039499 -0.015885 0.0280786 -0.0354482 -0.016489 0.025783 -0.039499 -0.015885 0.027908 -0.0325 -0.020278 0.0280786 -0.0354482 -0.016489 0.027908 -0.0325 -0.020278 0.025783 -0.039499 -0.015885 0.021988 -0.032499 -0.026583 0.018 -0.0311769 -0.0291133 0.0195459 -0.0299907 -0.0281325 0.0183981 -0.0312448 -0.0288607 0.0195459 -0.0299907 -0.0281325 0.021988 -0.032499 -0.026583 0.0183981 -0.0312448 -0.0288607 0.021988 -0.032499 -0.026583 0.0148082 -0.032499 -0.0311385 0.0183981 -0.0312448 -0.0288607 0.0148082 -0.032499 -0.0311385 0.018 -0.0311769 -0.0291133 0.0183981 -0.0312448 -0.0288607 0.0225423 -0.0250224 0.063039 0.0223527 -0.024999 0.0636048 0.020719 -0.032499 0.068479 0.0223527 -0.024999 0.0636048 0.020719 -0.024999 0.068479 0.020719 -0.032499 0.068479 0.022548 -0.0250231 0.06302199999999999 0.0225423 -0.0250224 0.063039 0.022548 -0.032499 0.06302199999999999 0.0225423 -0.0250224 0.063039 0.020719 -0.032499 0.068479 0.022548 -0.032499 0.06302199999999999 0.0226004 -0.0250338 0.06276080000000001 0.022548 -0.0250231 0.06302199999999999 0.022548 -0.032499 0.06302199999999999 0.0226004 -0.0250338 0.06276080000000001 0.022548 -0.032499 0.06302199999999999 0.033824 -0.032499 0.006782 0.033824 -0.032499 0.006782 0.034225 -0.024999 0.004324 0.0334599 -0.024999 0.008169940000000001 0.0320738 -0.024999 0.0151374 0.033824 -0.032499 0.006782 0.0334599 -0.024999 0.008169940000000001 0.0312352 -0.024999 0.019353 0.033824 -0.032499 0.006782 0.0320738 -0.024999 0.0151374 0.0311733 -0.024999 0.0196642 0.033824 -0.032499 0.006782 0.0312352 -0.024999 0.019353 0.0285113 -0.026257 0.0331198 0.0311733 -0.024999 0.0196642 0.0284965 -0.024999 0.0331199 0.0285113 -0.026257 0.0331198 0.033824 -0.032499 0.006782 0.0311733 -0.024999 0.0196642 0.0285113 -0.026257 0.0331198 0.0226004 -0.0250338 0.06276080000000001 0.033824 -0.032499 0.006782 -0.019006 -0.024999 0.07145700000000001 0.020719 -0.024999 0.068479 0.0196769 -0.024999 0.0636048 0.0196769 -0.024999 0.0636048 0.020719 -0.024999 0.068479 0.0223527 -0.024999 0.0636048 -0.019006 -0.024999 0.07145700000000001 -0.021981 -0.032499 0.06528 -0.0167549 -0.032499 0.0738829 -0.021981 -0.032499 0.06528 -0.0160897 -0.039499 0.0591044 -0.0125095 -0.0387423 0.072966 -0.0160897 -0.039499 0.0591044 -0.03383 -0.032499 0.00678201 -0.0267417 -0.039499 0.00678201 -0.018489 -0.032499 -0.029129 -0.018489 -0.0308017 -0.029129 -0.018 -0.0311769 -0.0293591 -0.018489 -0.032499 -0.029129 -0.018 -0.0311769 -0.0293591 -0.0148082 -0.032499 -0.030861 -0.0188569 -0.039499 -0.0203722 -0.018489 -0.032499 -0.029129 -0.0124874 -0.039499 -0.0250091 -0.0265381 -0.039499 -0.00700801 -0.0235285 -0.039499 -0.0141696 0.0247849 -0.039499 0.006782 -0.0274667 -0.039499 0.000698417 -0.0265381 -0.039499 -0.00700801 0.0247849 -0.039499 0.006782 -0.0235285 -0.039499 -0.0141696 -0.0188569 -0.039499 -0.0203722 0.0247849 -0.039499 0.006782 -0.0267417 -0.039499 0.00678201 -0.0274667 -0.039499 0.000698417 0.0247849 -0.039499 0.006782 0.034225 -0.024999 -0.004324 0.034225 -0.0325 0.004324 0.034225 -0.0325 -0.004324 0.034225 -0.024999 -0.00130163 0.034225 -0.024999 0.004324 0.034225 -0.0325 0.004324 0.034225 -0.024999 -0.00130163 0.034225 -0.0325 0.004324 0.034225 -0.024999 -0.004324 0.034225 -0.0325 -0.004324 0.025783 -0.039499 -0.015885 0.032074 -0.0325 -0.0127 0.025783 -0.039499 -0.015885 0.0191188 -0.039499 -0.0224148 0.021988 -0.032499 -0.026583 0.0148082 -0.032499 -0.0311385 0.021988 -0.032499 -0.026583 0.0183497 -0.0355645 -0.0262688 0.021988 -0.032499 -0.026583 0.0191188 -0.039499 -0.0224148 0.0183497 -0.0355645 -0.0262688 0.0191188 -0.039499 -0.0224148 0.0147114 -0.0325391 -0.0311656 0.0183497 -0.0355645 -0.0262688 0.0147114 -0.0325391 -0.0311656 0.0148082 -0.032499 -0.0311385 0.0183497 -0.0355645 -0.0262688 0.0191188 -0.039499 -0.0224148 0.0113892 -0.039499 -0.0265652 0.0147114 -0.0325391 -0.0311656 0.0147114 -0.0325391 -0.0311656 0.0113892 -0.039499 -0.0265652 0.0146564 -0.0325619 -0.0311742 0.00931748 -0.0347733 -0.0311017 0.013724 -0.0329481 -0.0311616 0.0114128 -0.0362868 -0.0291834 0.013724 -0.0329481 -0.0311616 0.0146564 -0.0325619 -0.0311742 0.0114128 -0.0362868 -0.0291834 0.0146564 -0.0325619 -0.0311742 0.0113892 -0.039499 -0.0265652 0.0114128 -0.0362868 -0.0291834 0.0113892 -0.039499 -0.0265652 0.008169249999999999 -0.0349245 -0.0313513 0.0114128 -0.0362868 -0.0291834 0.008169249999999999 -0.0349245 -0.0313513 0.00931748 -0.0347733 -0.0311017 0.0114128 -0.0362868 -0.0291834 0.020329 -0.024999 0.030913 0.0159356 -0.024999 0.0331197 0.0284965 -0.024999 0.0331199 0.020329 -0.024999 0.030913 0.0284965 -0.024999 0.0331199 0.02691 -0.024999 0.025391 0.02691 -0.024999 0.025391 0.0284965 -0.024999 0.0331199 0.0311733 -0.024999 0.0196642 0.020719 -0.024999 0.068479 0.016857 -0.032499 0.074144 0.020719 -0.032499 0.068479 0.020719 -0.032499 0.068479 0.0153354 -0.039499 0.06338779999999999 0.022548 -0.032499 0.06302199999999999 0.033824 -0.032499 0.006782 0.022548 -0.032499 0.06302199999999999 0.0153354 -0.039499 0.06338779999999999 0.0311733 -0.024999 0.0196642 0.0312352 -0.024999 0.019353 0.03204 -0.024999 0.0185 0.034225 -0.024999 0.004324 0.033824 -0.032499 0.006782 0.034225 -0.0325 0.004324 -0.019006 -0.024999 0.07145700000000001 -0.014343 -0.024999 0.07648199999999999 0.020719 -0.024999 0.068479 -0.014343 -0.024999 0.07648199999999999 -0.019006 -0.024999 0.07145700000000001 -0.0167549 -0.032499 0.0738829 -0.0125095 -0.0387423 0.072966 -0.0167549 -0.032499 0.0738829 -0.021981 -0.032499 0.06528 -0.009767420000000001 -0.039499 0.07502 -0.0125095 -0.0387423 0.072966 -0.0160897 -0.039499 0.0591044 -0.0267417 -0.039499 0.00678201 0.0247849 -0.039499 0.006782 -0.0160897 -0.039499 0.0591044 -0.0124874 -0.039499 -0.0250091 -0.018489 -0.032499 -0.029129 -0.0148082 -0.032499 -0.030861 -0.0124874 -0.039499 -0.0250091 -0.013626 -0.0329887 -0.0309315 -0.0110676 -0.0340484 -0.0310841 -0.0124874 -0.039499 -0.0250091 -0.0148082 -0.032499 -0.030861 -0.013626 -0.0329887 -0.0309315 -0.0188569 -0.039499 -0.0203722 -0.0124874 -0.039499 -0.0250091 0.0247849 -0.039499 0.006782 0.034225 -0.0325 0.004324 0.0247849 -0.039499 0.006782 0.034225 -0.0325 -0.004324 0.034225 -0.0325 -0.004324 0.0247849 -0.039499 0.006782 0.0296015 -0.036123 -0.0045515 0.0247849 -0.039499 0.006782 0.025783 -0.039499 -0.015885 0.0296015 -0.036123 -0.0045515 0.025783 -0.039499 -0.015885 0.034225 -0.0325 -0.004324 0.0296015 -0.036123 -0.0045515 0.0191188 -0.039499 -0.0224148 0.025783 -0.039499 -0.015885 0.0247849 -0.039499 0.006782 0.0113892 -0.039499 -0.0265652 0.0191188 -0.039499 -0.0224148 0.0247849 -0.039499 0.006782 0.008169249999999999 -0.0349245 -0.0313513 0.0113892 -0.039499 -0.0265652 0.00727738 -0.0374776 -0.0292551 0.0113892 -0.039499 -0.0265652 0.00316556 -0.039499 -0.0283236 0.00727738 -0.0374776 -0.0292551 0.00316556 -0.039499 -0.0283236 0.00513146 -0.0353244 -0.0316426 0.00727738 -0.0374776 -0.0292551 0.00513146 -0.0353244 -0.0316426 0.008169249999999999 -0.0349245 -0.0313513 0.00727738 -0.0374776 -0.0292551 0.020719 -0.024999 0.068479 0.016857 -0.024999 0.074144 0.016857 -0.032499 0.074144 0.0135171 -0.039499 0.0679395 0.020719 -0.032499 0.068479 0.016857 -0.032499 0.074144 0.0135171 -0.039499 0.0679395 0.0153354 -0.039499 0.06338779999999999 0.020719 -0.032499 0.068479 0.0153354 -0.039499 0.06338779999999999 0.0247849 -0.039499 0.006782 0.033824 -0.032499 0.006782 0.033824 -0.032499 0.006782 0.0247849 -0.039499 0.006782 0.034225 -0.0325 0.004324 -0.014343 -0.024999 0.07648199999999999 -0.008406 -0.024999 0.07990999999999999 0.020719 -0.024999 0.068479 -0.014343 -0.024999 0.07648199999999999 -0.0167549 -0.032499 0.0738829 -0.014343 -0.032499 0.07648199999999999 -0.014343 -0.032499 0.07648199999999999 -0.0167549 -0.032499 0.0738829 -0.0125095 -0.0387423 0.072966 -0.009767420000000001 -0.039499 0.07502 -0.008406 -0.032499 0.07990999999999999 -0.0125095 -0.0387423 0.072966 -0.009767420000000001 -0.039499 0.07502 -0.0160897 -0.039499 0.0591044 -0.00263971 -0.039499 0.0764461 -0.0160897 -0.039499 0.0591044 0.0247849 -0.039499 0.006782 0.0153354 -0.039499 0.06338779999999999 -0.00931748 -0.0347733 -0.0309839 -0.00875655 -0.0348472 -0.0311134 -0.00873257 -0.0373293 -0.0285917 -0.00875655 -0.0348472 -0.0311134 -0.00497775 -0.039499 -0.0277504 -0.00873257 -0.0373293 -0.0285917 -0.00497775 -0.039499 -0.0277504 -0.0124874 -0.039499 -0.0250091 -0.00873257 -0.0373293 -0.0285917 -0.0124874 -0.039499 -0.0250091 -0.0110676 -0.0340484 -0.0310841 -0.00873257 -0.0373293 -0.0285917 -0.0110676 -0.0340484 -0.0310841 -0.00931748 -0.0347733 -0.0309839 -0.00873257 -0.0373293 -0.0285917 -0.00339446 -0.0355531 -0.0315168 -0.00497775 -0.039499 -0.0277504 -0.00454796 -0.0354012 -0.03143 -0.00454796 -0.0354012 -0.03143 -0.00497775 -0.039499 -0.0277504 -0.00875655 -0.0348472 -0.0311134 -0.0124874 -0.039499 -0.0250091 -0.00497775 -0.039499 -0.0277504 0.0247849 -0.039499 0.006782 0.00316556 -0.039499 -0.0283236 0.0113892 -0.039499 -0.0265652 0.0247849 -0.039499 0.006782 0.00513146 -0.0353244 -0.0316426 0.00316556 -0.039499 -0.0283236 0.00479949 -0.0353681 -0.0316275 0.00479949 -0.0353681 -0.0316275 0.00316556 -0.039499 -0.0283236 0.000453537 -0.0359403 -0.031429 1.33055e-09 -0.036 -0.0313418 0.000453537 -0.0359403 -0.031429 -0.000906095 -0.0376411 -0.0297579 0.000453537 -0.0359403 -0.031429 0.00316556 -0.039499 -0.0283236 -0.000906095 -0.0376411 -0.0297579 0.00316556 -0.039499 -0.0283236 -0.00497775 -0.039499 -0.0277504 -0.000906095 -0.0376411 -0.0297579 -0.00497775 -0.039499 -0.0277504 -0.00339446 -0.0355531 -0.0315168 -0.000906095 -0.0376411 -0.0297579 -0.00339446 -0.0355531 -0.0315168 1.33055e-09 -0.036 -0.0313418 -0.000906095 -0.0376411 -0.0297579 0.016857 -0.024999 0.074144 0.020719 -0.024999 0.068479 0.005115 -0.024999 0.08092299999999999 0.011497 -0.032499 0.078419 0.016857 -0.032499 0.074144 0.016857 -0.024999 0.074144 0.016857 -0.032499 0.074144 0.009525779999999999 -0.039499 0.0724708 0.0135171 -0.039499 0.0679395 -0.0160897 -0.039499 0.0591044 0.0153354 -0.039499 0.06338779999999999 0.0135171 -0.039499 0.0679395 -0.014343 -0.032499 0.07648199999999999 -0.008406 -0.024999 0.07990999999999999 -0.014343 -0.024999 0.07648199999999999 -0.008406 -0.024999 0.07990999999999999 -0.001722 -0.024999 0.08143599999999999 0.020719 -0.024999 0.068479 -0.014343 -0.032499 0.07648199999999999 -0.0125095 -0.0387423 0.072966 -0.008406 -0.032499 0.07990999999999999 -0.001722 -0.032499 0.08143599999999999 -0.008406 -0.032499 0.07990999999999999 -0.009767420000000001 -0.039499 0.07502 -0.00263971 -0.039499 0.0764461 -0.001722 -0.032499 0.08143599999999999 -0.009767420000000001 -0.039499 0.07502 -0.00263971 -0.039499 0.0764461 -0.0160897 -0.039499 0.0591044 0.00397308 -0.039499 0.07546609999999999 -0.00497775 -0.039499 -0.0277504 0.00316556 -0.039499 -0.0283236 0.0247849 -0.039499 0.006782 -0.001722 -0.024999 0.08143599999999999 0.005115 -0.024999 0.08092299999999999 0.020719 -0.024999 0.068479 0.011497 -0.024999 0.078419 0.016857 -0.024999 0.074144 0.005115 -0.024999 0.08092299999999999 0.016857 -0.024999 0.074144 0.011497 -0.024999 0.078419 0.011497 -0.032499 0.078419 0.011497 -0.032499 0.078419 0.009525779999999999 -0.039499 0.0724708 0.016857 -0.032499 0.074144 -0.0160897 -0.039499 0.0591044 0.0135171 -0.039499 0.0679395 0.009525779999999999 -0.039499 0.0724708 -0.014343 -0.032499 0.07648199999999999 -0.008406 -0.032499 0.07990999999999999 -0.008406 -0.024999 0.07990999999999999 -0.008406 -0.032499 0.07990999999999999 -0.001722 -0.024999 0.08143599999999999 -0.008406 -0.024999 0.07990999999999999 -0.008406 -0.032499 0.07990999999999999 -0.001722 -0.032499 0.08143599999999999 -0.001722 -0.024999 0.08143599999999999 0.005115 -0.032499 0.08092299999999999 -0.001722 -0.032499 0.08143599999999999 -0.00263971 -0.039499 0.0764461 0.00397308 -0.039499 0.07546609999999999 0.005115 -0.032499 0.08092299999999999 -0.00263971 -0.039499 0.0764461 0.00397308 -0.039499 0.07546609999999999 -0.0160897 -0.039499 0.0591044 0.009525779999999999 -0.039499 0.0724708 -0.001722 -0.032499 0.08143599999999999 0.005115 -0.024999 0.08092299999999999 -0.001722 -0.024999 0.08143599999999999 0.005115 -0.032499 0.08092299999999999 0.011497 -0.024999 0.078419 0.005115 -0.024999 0.08092299999999999 0.005115 -0.032499 0.08092299999999999 0.011497 -0.032499 0.078419 0.011497 -0.024999 0.078419 0.00397308 -0.039499 0.07546609999999999 0.009525779999999999 -0.039499 0.0724708 0.011497 -0.032499 0.078419 -0.001722 -0.032499 0.08143599999999999 0.005115 -0.032499 0.08092299999999999 0.005115 -0.024999 0.08092299999999999 0.011497 -0.032499 0.078419 0.005115 -0.032499 0.08092299999999999 0.00397308 -0.039499 0.07546609999999999 -0.0261929 -0.0257879 0.044486 -0.0284953 -0.026257 0.0331192 -0.021981 -0.024999 0.06528 -0.0261929 -0.0257879 0.044486 -0.021981 -0.024999 0.06528 -0.0223204 -0.024999 0.0636043 -0.0284953 -0.024999 0.0331192 -0.0284953 -0.026257 0.0331192 -0.044748 -0.026257 0.033119 -0.0159418 -0.024999 0.0331193 -0.0188089 -0.024999 0.0331193 -0.0159414 0.0122008 0.0331198 -0.0188089 -0.024999 0.0331193 -0.0214843 -0.024999 0.0331193 -0.0159414 0.0122008 0.0331198 -0.0214843 -0.024999 0.0331193 -0.0259098 -0.024999 0.0331192 -0.0159414 0.0122008 0.0331198 -0.0259098 -0.024999 0.0331192 -0.0273204 -0.024999 0.0331192 -0.0303445 0.014001 0.0331197 -0.0273204 -0.024999 0.0331192 -0.0277933 -0.024999 0.0331192 -0.0303445 0.014001 0.0331197 -0.0277933 -0.024999 0.0331192 -0.0284953 -0.024999 0.0331192 -0.0303445 0.014001 0.0331197 -0.044748 -0.026257 0.033119 -0.044748 0.054259 0.03312 -0.0303445 0.014001 0.0331197 -0.044748 0.054259 0.03312 -0.015941 0.0275117 0.03312 -0.0303445 0.014001 0.0331197 -0.015941 0.0275117 0.03312 -0.0159414 0.0122008 0.0331198 -0.0303445 0.014001 0.0331197 -0.0284953 -0.024999 0.0331192 -0.044748 -0.026257 0.033119 -0.0303445 0.014001 0.0331197 -0.0159414 0.0122008 0.0331198 -0.0259098 -0.024999 0.0331192 -0.0303445 0.014001 0.0331197 -0.044748 -0.026257 0.033119 -0.0284953 -0.026257 0.0331192 -0.0261929 -0.0257879 0.044486 -0.0208059 -0.024999 0.0636043 -0.0428306 -0.02411 0.08514720000000001 -0.0223204 -0.024999 0.0636043 -0.020709 -0.024999 0.0636043 -0.0428306 -0.02411 0.08514720000000001 -0.0208059 -0.024999 0.0636043 -0.0204201 -0.024999 0.06360440000000001 -0.0428306 -0.02411 0.08514720000000001 -0.020709 -0.024999 0.0636043 -0.0195136 -0.024999 0.06360440000000001 -0.0428306 -0.02411 0.08514720000000001 -0.0204201 -0.024999 0.06360440000000001 -0.0189656 -0.024999 0.06360440000000001 -0.0428306 -0.02411 0.08514720000000001 -0.0195136 -0.024999 0.06360440000000001 -0.0183777 -0.024999 0.06360440000000001 -0.0428306 -0.02411 0.08514720000000001 -0.0189656 -0.024999 0.06360440000000001 -0.0177574 -0.024999 0.06360440000000001 -0.0428306 -0.02411 0.08514720000000001 -0.0183777 -0.024999 0.06360440000000001 -0.0171076 -0.024999 0.06360440000000001 -0.0428306 -0.02411 0.08514720000000001 -0.0177574 -0.024999 0.06360440000000001 -0.0164292 -0.024999 0.06360440000000001 -0.0428306 -0.02411 0.08514720000000001 -0.0171076 -0.024999 0.06360440000000001 -0.044748 -0.026257 0.033119 -0.0223204 -0.024999 0.0636043 -0.0428306 -0.02411 0.08514720000000001 -0.0127796 -0.024999 0.06360440000000001 -0.0428306 -0.02411 0.08514720000000001 -0.0164292 -0.024999 0.06360440000000001 -0.0261929 -0.0257879 0.044486 -0.0223204 -0.024999 0.0636043 -0.044748 -0.026257 0.033119 0.00501562 -0.024999 0.0636046 -0.0428306 -0.02411 0.08514720000000001 -0.0127796 -0.024999 0.06360440000000001 0.0402092 -0.02411 0.0851792 -0.0428306 -0.02411 0.08514720000000001 0.00501562 -0.024999 0.0636046 0.041968 -0.026257 0.03312 0.015935 -0.00208533 0.03312 0.015935 0.00279795 0.03312 -0.015941 0.0275117 0.03312 -0.044748 0.054259 0.03312 -0.015941 0.040001 0.03312 -0.015941 0.040001 0.03312 -0.044748 0.054259 0.03312 -0.012562 0.040001 0.03312 0.015935 0.00279795 0.03312 0.015935 0.040001 0.03312 0.041968 0.054259 0.03312 0.015935 0.040001 0.03312 0.0121583 0.040001 0.03312 0.041968 0.054259 0.03312 0.0121583 0.040001 0.03312 0.00365194 0.040001 0.03312 0.041968 0.054259 0.03312 0.041968 -0.026257 0.03312 0.015935 0.00279795 0.03312 0.041968 0.054259 0.03312 -0.012562 0.040001 0.03312 -0.044748 0.054259 0.03312 0.041968 0.054259 0.03312 -0.00450946 0.040001 0.03312 -0.012562 0.040001 0.03312 0.041968 0.054259 0.03312 0.00365194 0.040001 0.03312 -0.00450946 0.040001 0.03312 0.041968 0.054259 0.03312 -0.044748 -0.026257 0.033119 -0.0428306 -0.02411 0.08514720000000001 -0.044748 0.054259 0.03312 0.0300294 -0.02411 0.09462 -0.0428306 -0.02411 0.08514720000000001 0.0402092 -0.02411 0.0851792 0.0285113 -0.026257 0.0331198 0.041968 -0.026257 0.03312 0.0226004 -0.0250338 0.06276080000000001 0.0223527 -0.024999 0.0636048 0.0225423 -0.0250224 0.063039 0.0402092 -0.02411 0.0851792 0.0225423 -0.0250224 0.063039 0.022548 -0.0250231 0.06302199999999999 0.0402092 -0.02411 0.0851792 0.022548 -0.0250231 0.06302199999999999 0.0226004 -0.0250338 0.06276080000000001 0.0402092 -0.02411 0.0851792 0.00501562 -0.024999 0.0636046 0.0196769 -0.024999 0.0636048 0.0402092 -0.02411 0.0851792 0.0196769 -0.024999 0.0636048 0.0223527 -0.024999 0.0636048 0.0402092 -0.02411 0.0851792 0.0226004 -0.0250338 0.06276080000000001 0.041968 -0.026257 0.03312 0.0402092 -0.02411 0.0851792 -0.044748 0.054259 0.03312 -0.0426476 0.052111 0.08525099999999999 0.041968 0.054259 0.03312 0.041968 0.054259 0.03312 0.04023 0.052111 0.0852034 0.041968 -0.026257 0.03312 0.041968 -0.026257 0.03312 0.0285113 -0.026257 0.0331198 0.0284965 -0.024999 0.0331199 0.0284965 -0.024999 0.0331199 0.0159356 -0.024999 0.0331197 0.015935 -0.00208533 0.03312 0.041968 -0.026257 0.03312 0.0284965 -0.024999 0.0331199 0.015935 -0.00208533 0.03312 -0.0426476 0.052111 0.08525099999999999 -0.044748 0.054259 0.03312 -0.0428306 -0.02411 0.08514720000000001 -0.0337571 -0.02411 0.09461899999999999 -0.0428306 -0.02411 0.08514720000000001 0.0300294 -0.02411 0.09462 0.0300294 -0.02411 0.09462 0.0402092 -0.02411 0.0851792 0.0300255 0.052111 0.09462 0.04023 0.052111 0.0852034 0.0402092 -0.02411 0.0851792 0.041968 -0.026257 0.03312 -0.0426476 0.052111 0.08525099999999999 0.04023 0.052111 0.0852034 0.041968 0.054259 0.03312 -0.0426476 0.052111 0.08525099999999999 -0.0428306 -0.02411 0.08514720000000001 -0.0337571 -0.02411 0.09461899999999999 -0.0337571 -0.02411 0.09461899999999999 0.0300294 -0.02411 0.09462 0.0300255 0.052111 0.09462 0.04023 0.052111 0.0852034 0.0300255 0.052111 0.09462 0.0402092 -0.02411 0.0851792 -0.0426476 0.052111 0.08525099999999999 -0.0337134 0.052111 0.09462 0.04023 0.052111 0.0852034 -0.0337134 0.052111 0.09462 -0.0426476 0.052111 0.08525099999999999 -0.0337571 -0.02411 0.09461899999999999 0.0300255 0.052111 0.09462 -0.0337134 0.052111 0.09462 -0.0337571 -0.02411 0.09461899999999999 -0.0337134 0.052111 0.09462 0.0300255 0.052111 0.09462 0.04023 0.052111 0.0852034 -0.016609 0.040001 -0.033064 -0.023786 0.040001 -0.028343 -0.00853601 0.040001 -0.036002 -0.023786 0.040001 -0.028343 -0.029682 0.040001 -0.022095 -0.00853601 0.040001 -0.036002 -0.00853601 0.0348762 -0.0360021 -0.009317499999999999 0.0347733 -0.0357177 -0.00853601 0.040001 -0.036002 -0.0141211 0.0327836 -0.0339695 -0.0156347 0.0321566 -0.0334187 -0.0125725 0.0360788 -0.0345331 -0.0156347 0.0321566 -0.0334187 -0.016609 0.040001 -0.033064 -0.0125725 0.0360788 -0.0345331 -0.016609 0.040001 -0.033064 -0.00853601 0.040001 -0.036002 -0.0125725 0.0360788 -0.0345331 -0.009317499999999999 0.0347733 -0.0357177 -0.0141211 0.0327836 -0.0339695 -0.0125725 0.0360788 -0.0345331 -0.00853601 0.040001 -0.036002 -0.009317499999999999 0.0347733 -0.0357177 -0.0125725 0.0360788 -0.0345331 -0.0224359 0.0277732 -0.0292311 -0.023786 0.040001 -0.028343 -0.0201975 0.0338871 -0.0307035 -0.023786 0.040001 -0.028343 -0.016609 0.040001 -0.033064 -0.0201975 0.0338871 -0.0307035 -0.016609 0.040001 -0.033064 -0.016609 0.0317531 -0.033064 -0.0201975 0.0338871 -0.0307035 -0.016609 0.0317531 -0.033064 -0.018 0.0311769 -0.032149 -0.0201975 0.0338871 -0.0307035 -0.018 0.0311769 -0.032149 -0.0216151 0.0284029 -0.029771 -0.0201975 0.0338871 -0.0307035 -0.0216151 0.0284029 -0.029771 -0.0224359 0.0277732 -0.0292311 -0.0201975 0.0338871 -0.0307035 -0.029682 0.040001 -0.022095 -0.033977 0.040001 -0.014655 -0.00853601 0.040001 -0.036002 -0.0280553 0.0220681 -0.0238188 -0.029682 0.040001 -0.022095 -0.026734 0.0310346 -0.025219 -0.029682 0.040001 -0.022095 -0.023786 0.040001 -0.028343 -0.026734 0.0310346 -0.025219 -0.023786 0.040001 -0.028343 -0.023786 0.0267372 -0.028343 -0.026734 0.0310346 -0.025219 -0.023786 0.0267372 -0.028343 -0.0254559 0.0254558 -0.0265734 -0.026734 0.0310346 -0.025219 -0.0254559 0.0254558 -0.0265734 -0.0277094 0.022519 -0.0241854 -0.026734 0.0310346 -0.025219 -0.0277094 0.022519 -0.0241854 -0.0280553 0.0220681 -0.0238188 -0.026734 0.0310346 -0.025219 -0.018 0.0311769 -0.032149 -0.016609 0.0317531 -0.033064 -0.018 0.0311769 -0.0614 -0.016609 0.0317531 -0.033064 -0.0156347 0.0321566 -0.0334187 -0.018 0.0311769 -0.0614 -0.0156347 0.0321566 -0.0334187 -0.0141211 0.0327836 -0.0339695 -0.018 0.0311769 -0.0614 -0.0156347 0.0321566 -0.0334187 -0.016609 0.0317531 -0.033064 -0.016609 0.040001 -0.033064 -0.00787467 0.0349633 -0.0360793 -0.00853601 0.0348762 -0.0360021 -0.00853601 0.040001 -0.036002 -0.009317499999999999 0.0347733 -0.0357177 -0.00853601 0.0348762 -0.0360021 -0.009317499999999999 0.0347733 -0.0614 -0.00853601 0.0348762 -0.0360021 -0.00787467 0.0349633 -0.0360793 -0.009317499999999999 0.0347733 -0.0614 -0.00787467 0.0349633 -0.0360793 -0.00551692 0.0352737 -0.0363551 -0.009317499999999999 0.0347733 -0.0614 -0.0141211 0.0327836 -0.0339695 -0.009317499999999999 0.0347733 -0.0357177 -0.0136587 0.0329751 -0.0476848 -0.009317499999999999 0.0347733 -0.0357177 -0.009317499999999999 0.0347733 -0.0614 -0.0136587 0.0329751 -0.0476848 -0.009317499999999999 0.0347733 -0.0614 -0.018 0.0311769 -0.0614 -0.0136587 0.0329751 -0.0476848 -0.018 0.0311769 -0.0614 -0.0141211 0.0327836 -0.0339695 -0.0136587 0.0329751 -0.0476848 -0.0224359 0.0277732 -0.0292311 -0.023786 0.0267372 -0.028343 -0.023786 0.040001 -0.028343 -0.0217279 0.0283164 -0.0455855 -0.0216151 0.0284029 -0.029771 -0.018 0.0311769 -0.032149 -0.0217279 0.0283164 -0.0455855 -0.0254559 0.0254558 -0.0614 -0.0216151 0.0284029 -0.029771 -0.0217279 0.0283164 -0.0455855 -0.018 0.0311769 -0.0614 -0.0254559 0.0254558 -0.0614 -0.0217279 0.0283164 -0.0455855 -0.018 0.0311769 -0.032149 -0.018 0.0311769 -0.0614 -0.023786 0.0267372 -0.028343 -0.0224359 0.0277732 -0.0292311 -0.0254559 0.0254558 -0.0614 -0.0224359 0.0277732 -0.0292311 -0.0216151 0.0284029 -0.029771 -0.0254559 0.0254558 -0.0614 -0.0254559 0.0254558 -0.0265734 -0.023786 0.0267372 -0.028343 -0.0254559 0.0254558 -0.0614 -0.033977 0.040001 -0.014655 -0.036441 0.040001 -0.00642499 -0.00853601 0.040001 -0.036002 -0.029682 0.0199482 -0.022095 -0.0311769 0.018 -0.0195055 -0.0318295 0.0275989 -0.018375 -0.0311769 0.018 -0.0195055 -0.0322142 0.0154958 -0.0177087 -0.0318295 0.0275989 -0.018375 -0.0322142 0.0154958 -0.0177087 -0.032338 0.0151968 -0.0174941 -0.0318295 0.0275989 -0.018375 -0.032338 0.0151968 -0.0174941 -0.033977 0.040001 -0.014655 -0.0318295 0.0275989 -0.018375 -0.033977 0.040001 -0.014655 -0.029682 0.040001 -0.022095 -0.0318295 0.0275989 -0.018375 -0.029682 0.040001 -0.022095 -0.029682 0.0199482 -0.022095 -0.0318295 0.0275989 -0.018375 -0.029682 0.040001 -0.022095 -0.0280553 0.0220681 -0.0238188 -0.029682 0.0199482 -0.022095 -0.0283164 0.0217279 -0.0427927 -0.0277094 0.022519 -0.0241854 -0.0254559 0.0254558 -0.0265734 -0.0283164 0.0217279 -0.0427927 -0.0311769 0.018 -0.0614 -0.0277094 0.022519 -0.0241854 -0.0283164 0.0217279 -0.0427927 -0.0254559 0.0254558 -0.0614 -0.0311769 0.018 -0.0614 -0.0283164 0.0217279 -0.0427927 -0.0254559 0.0254558 -0.0265734 -0.0254559 0.0254558 -0.0614 -0.0311769 0.018 -0.0195055 -0.029682 0.0199482 -0.022095 -0.0294431 0.0202595 -0.0404527 -0.029682 0.0199482 -0.022095 -0.0280553 0.0220681 -0.0238188 -0.0294431 0.0202595 -0.0404527 -0.0280553 0.0220681 -0.0238188 -0.0277094 0.022519 -0.0241854 -0.0294431 0.0202595 -0.0404527 -0.0277094 0.022519 -0.0241854 -0.0311769 0.018 -0.0614 -0.0294431 0.0202595 -0.0404527 -0.0311769 0.018 -0.0614 -0.0311769 0.018 -0.0195055 -0.0294431 0.0202595 -0.0404527 -0.00551692 0.0352737 -0.0363551 -0.00787467 0.0349633 -0.0360793 -0.00426951 0.0374821 -0.036501 -0.00787467 0.0349633 -0.0360793 -0.00853601 0.040001 -0.036002 -0.00426951 0.0374821 -0.036501 -0.00853601 0.040001 -0.036002 -3.00519e-06 0.040001 -0.037 -0.00426951 0.0374821 -0.036501 -3.00519e-06 0.040001 -0.037 -3.00519e-06 0.0359996 -0.037 -0.00426951 0.0374821 -0.036501 -3.00519e-06 0.0359996 -0.037 -0.00551692 0.0352737 -0.0363551 -0.00426951 0.0374821 -0.036501 -0.00551692 0.0352737 -0.0363551 -3.00519e-06 0.0359996 -0.037 -0.00465876 0.0353867 -0.0488776 -0.00465876 0.0353867 -0.0488776 -1.83747e-08 0.036 -0.0369997 -3.00519e-06 0.0359996 -0.037 -1.83747e-08 0.036 -0.0369997 -1.94548e-08 0.036 -0.0614 -0.00465876 0.0353867 -0.0488776 -1.94548e-08 0.036 -0.0614 -0.009317499999999999 0.0347733 -0.0614 -0.00465876 0.0353867 -0.0488776 -0.009317499999999999 0.0347733 -0.0614 -0.00551692 0.0352737 -0.0363551 -0.00465876 0.0353867 -0.0488776 -0.018 0.0311769 -0.0614 -0.009317499999999999 0.0347733 -0.0614 0.0254558 0.0254559 -0.0614 -0.0254559 0.0254558 -0.0614 -0.018 0.0311769 -0.0614 0.0254558 0.0254559 -0.0614 -0.036441 0.040001 -0.00642499 -0.036941 0.040001 0.00215201 -0.00853601 0.040001 -0.036002 -0.0351651 0.00634185 -0.0106868 -0.036441 0.040001 -0.00642499 -0.035209 0.0231714 -0.01054 -0.036441 0.040001 -0.00642499 -0.033977 0.040001 -0.014655 -0.035209 0.0231714 -0.01054 -0.033977 0.040001 -0.014655 -0.033977 0.0112399 -0.014655 -0.035209 0.0231714 -0.01054 -0.033977 0.0112399 -0.014655 -0.0347733 0.00931747 -0.0119953 -0.035209 0.0231714 -0.01054 -0.0347733 0.00931747 -0.0119953 -0.034998 0.00761105 -0.0112449 -0.035209 0.0231714 -0.01054 -0.034998 0.00761105 -0.0112449 -0.0351651 0.00634185 -0.0106868 -0.035209 0.0231714 -0.01054 -0.0322142 0.0154958 -0.0177087 -0.0311769 0.018 -0.0195055 -0.0329751 0.0136587 -0.0395543 -0.0311769 0.018 -0.0195055 -0.0311769 0.018 -0.0614 -0.0329751 0.0136587 -0.0395543 -0.0311769 0.018 -0.0614 -0.0347733 0.00931747 -0.0614 -0.0329751 0.0136587 -0.0395543 -0.0347733 0.00931747 -0.0614 -0.0322142 0.0154958 -0.0177087 -0.0329751 0.0136587 -0.0395543 -0.0334937 0.0124066 -0.0366976 -0.0347733 0.00931747 -0.0119953 -0.033977 0.0112399 -0.014655 -0.0334937 0.0124066 -0.0366976 -0.0347733 0.00931747 -0.0614 -0.0347733 0.00931747 -0.0119953 -0.0334937 0.0124066 -0.0366976 -0.0322142 0.0154958 -0.0177087 -0.0347733 0.00931747 -0.0614 -0.0334937 0.0124066 -0.0366976 -0.032338 0.0151968 -0.0174941 -0.0322142 0.0154958 -0.0177087 -0.0334937 0.0124066 -0.0366976 -0.033977 0.0112399 -0.014655 -0.032338 0.0151968 -0.0174941 -0.033977 0.040001 -0.014655 -0.032338 0.0151968 -0.0174941 -0.033977 0.0112399 -0.014655 -0.0311769 0.018 -0.0614 -0.0254559 0.0254558 -0.0614 0.0254558 0.0254559 -0.0614 0.008529989999999999 0.040001 -0.036002 -3.00519e-06 0.040001 -0.037 -0.00853601 0.040001 -0.036002 -3.00519e-06 0.040001 -0.037 -3.00519e-06 0.0359996 -0.037 -1.83747e-08 0.036 -0.0369997 0.000531419 0.03593 -0.0369376 -1.83747e-08 0.036 -0.0369997 -3.00519e-06 0.040001 -0.037 0.000531419 0.03593 -0.0369376 0.00376964 0.0355037 -0.0365588 -1.94548e-08 0.036 -0.0614 -1.83747e-08 0.036 -0.0369997 0.000531419 0.03593 -0.0369376 -1.94548e-08 0.036 -0.0614 -0.009317499999999999 0.0347733 -0.0614 -1.94548e-08 0.036 -0.0614 0.00931747 0.0347733 -0.0614 -0.009317499999999999 0.0347733 -0.0614 0.018 0.0311769 -0.0614 0.0254558 0.0254559 -0.0614 -0.036941 0.040001 0.00215201 -0.035449 0.040001 0.010612 -0.00853601 0.040001 -0.036002 -0.036941 0.040001 0.00215201 -0.036441 0.040001 -0.00642499 -0.036441 -0.024999 -0.00642499 -0.036441 0.040001 -0.00642499 -0.0351651 0.00634185 -0.0106868 -0.036 -1.52588e-08 -0.007897970000000001 -0.0347733 -0.009317499999999999 -0.0119953 -0.0345511 -0.00985391 -0.0127374 -0.036441 -0.024999 -0.00642499 -0.0345511 -0.00985391 -0.0127374 -0.033977 -0.024999 -0.014655 -0.036441 -0.024999 -0.00642499 -0.036 -1.52588e-08 -0.007897970000000001 -0.0358309 -0.00128423 -0.0084627 -0.036441 -0.024999 -0.00642499 -0.0358309 -0.00128423 -0.0084627 -0.0347733 -0.009317499999999999 -0.0119953 -0.036441 -0.024999 -0.00642499 -0.036 -1.52588e-08 -0.007897970000000001 -0.036441 -0.024999 -0.00642499 -0.036441 0.040001 -0.00642499 -0.0353867 0.00465873 -0.0363224 -0.034998 0.00761105 -0.0112449 -0.0347733 0.00931747 -0.0119953 -0.0353867 0.00465873 -0.0363224 -0.036 -1.52588e-08 -0.0614 -0.034998 0.00761105 -0.0112449 -0.0353867 0.00465873 -0.0363224 -0.0347733 0.00931747 -0.0614 -0.036 -1.52588e-08 -0.0614 -0.0353867 0.00465873 -0.0363224 -0.0347733 0.00931747 -0.0119953 -0.0347733 0.00931747 -0.0614 -0.036 -1.52588e-08 -0.0614 -0.036 -1.52588e-08 -0.007897970000000001 -0.0351651 0.00634185 -0.0106868 -0.036 -1.52588e-08 -0.0614 -0.0351651 0.00634185 -0.0106868 -0.034998 0.00761105 -0.0112449 -0.0347733 0.00931747 -0.0614 -0.0311769 0.018 -0.0614 0.0254558 -0.0254558 -0.0614 0.0311769 0.018 -0.0614 -0.0311769 0.018 -0.0614 0.0254558 0.0254559 -0.0614 0.016602 0.040001 -0.033064 0.008529989999999999 0.040001 -0.036002 -0.00853601 0.040001 -0.036002 0.00376964 0.0355037 -0.0365588 0.000531419 0.03593 -0.0369376 0.0042635 0.037439 -0.036501 0.000531419 0.03593 -0.0369376 -3.00519e-06 0.040001 -0.037 0.0042635 0.037439 -0.036501 -3.00519e-06 0.040001 -0.037 0.008529989999999999 0.040001 -0.036002 0.0042635 0.037439 -0.036501 0.008529989999999999 0.040001 -0.036002 0.008529989999999999 0.034877 -0.0360021 0.0042635 0.037439 -0.036501 0.008529989999999999 0.034877 -0.0360021 0.00376964 0.0355037 -0.0365588 0.0042635 0.037439 -0.036501 0.008529989999999999 0.034877 -0.0360021 0.00917697 0.0347918 -0.0357665 0.00465873 0.0353867 -0.0485577 0.00917697 0.0347918 -0.0357665 0.00931747 0.0347733 -0.0357154 0.00465873 0.0353867 -0.0485577 0.00931747 0.0347733 -0.0357154 0.00931747 0.0347733 -0.0614 0.00465873 0.0353867 -0.0485577 0.00931747 0.0347733 -0.0614 -1.94548e-08 0.036 -0.0614 0.00465873 0.0353867 -0.0485577 -1.94548e-08 0.036 -0.0614 0.00376964 0.0355037 -0.0365588 0.00465873 0.0353867 -0.0485577 0.00376964 0.0355037 -0.0365588 0.008529989999999999 0.034877 -0.0360021 0.00465873 0.0353867 -0.0485577 -0.009317499999999999 0.0347733 -0.0614 0.00931747 0.0347733 -0.0614 0.018 0.0311769 -0.0614 0.0254558 0.0254559 -0.0614 0.0218608 0.0282144 -0.0296054 0.02378 0.0267418 -0.0283432 0.0254558 0.0254559 -0.0614 0.018 0.0311769 -0.0614 0.0218608 0.0282144 -0.0296054 0.0254558 0.0254559 -0.0614 0.0250727 0.0257499 -0.0269731 0.0254558 0.0254559 -0.0265671 0.0254558 0.0254559 -0.0614 0.02378 0.0267418 -0.0283432 0.0250727 0.0257499 -0.0269731 -0.035449 0.040001 0.010612 -0.032046 0.040001 0.0185 -0.00853601 0.040001 -0.036002 -0.035449 0.040001 0.010612 -0.036941 0.040001 0.00215201 -0.03694 -0.024999 0.00215201 -0.036941 0.040001 0.00215201 -0.036441 -0.024999 -0.00642499 -0.03694 -0.024999 0.00215201 -0.0339079 -0.0114068 -0.0147747 -0.0347733 -0.009317499999999999 -0.0614 -0.0311769 -0.018 -0.0614 -0.0339079 -0.0114068 -0.0147747 -0.033977 -0.0112399 -0.014655 -0.0347733 -0.009317499999999999 -0.0614 -0.0345511 -0.00985391 -0.0127374 -0.0347733 -0.009317499999999999 -0.0614 -0.033977 -0.0112399 -0.014655 -0.0347733 -0.009317499999999999 -0.0119953 -0.0347733 -0.009317499999999999 -0.0614 -0.0345511 -0.00985391 -0.0127374 -0.0345511 -0.00985391 -0.0127374 -0.033977 -0.0112399 -0.014655 -0.033977 -0.024999 -0.014655 -0.0344958 -0.024999 7.24318e-05 -0.034503 -0.024999 7.76846e-09 -0.036441 -0.024999 -0.00642499 -0.033977 -0.024999 -0.014655 -0.033064 -0.024999 -0.009476790000000001 -0.0347525 -0.024999 -0.00729128 -0.033064 -0.024999 -0.009476790000000001 -0.033419 -0.024999 -0.008579989999999999 -0.0347525 -0.024999 -0.00729128 -0.033419 -0.024999 -0.008579989999999999 -0.034503 -0.024999 7.76846e-09 -0.0347525 -0.024999 -0.00729128 -0.036441 -0.024999 -0.00642499 -0.033977 -0.024999 -0.014655 -0.0347525 -0.024999 -0.00729128 -0.034503 -0.024999 7.76846e-09 -0.036441 -0.024999 -0.00642499 -0.0347525 -0.024999 -0.00729128 -0.036 -1.52588e-08 -0.0614 -0.0347733 -0.009317499999999999 -0.0614 -0.0358309 -0.00128423 -0.0084627 -0.036 -1.52588e-08 -0.0614 -0.0358309 -0.00128423 -0.0084627 -0.036 -1.52588e-08 -0.007897970000000001 -0.0347733 -0.009317499999999999 -0.0614 -0.0347733 -0.009317499999999999 -0.0119953 -0.0358309 -0.00128423 -0.0084627 -0.036 -1.52588e-08 -0.0614 -0.0347733 0.00931747 -0.0614 0.0254558 -0.0254558 -0.0614 0.0254558 -0.0254558 -0.0614 -0.0311769 0.018 -0.0614 0.0311769 -0.018 -0.0614 0.0311769 0.018 -0.0614 0.0254558 0.0254559 -0.0614 0.0290571 0.0207626 -0.0227502 0.0311769 0.018 -0.0614 0.0290571 0.0207626 -0.0227502 0.0296753 0.0199569 -0.022095 0.0311769 0.018 -0.0614 0.0296753 0.0199569 -0.022095 0.0311246 0.0180682 -0.0195845 0.0311769 0.018 -0.0614 0.0311246 0.0180682 -0.0195845 0.0311769 0.018 -0.0194939 0.0347733 0.009317509999999999 -0.0614 -0.0311769 0.018 -0.0614 0.0311769 0.018 -0.0614 0.02378 0.040001 -0.028343 0.016602 0.040001 -0.033064 -0.00853601 0.040001 -0.036002 0.00931747 0.0347733 -0.0357154 0.00917697 0.0347918 -0.0357665 0.008529989999999999 0.040001 -0.036002 0.0131466 0.0331872 -0.0343217 0.00931747 0.0347733 -0.0357154 0.0125661 0.0358785 -0.034533 0.008529989999999999 0.040001 -0.036002 0.016602 0.040001 -0.033064 0.0125661 0.0358785 -0.034533 0.016602 0.040001 -0.033064 0.0166021 0.0317559 -0.033064 0.0125661 0.0358785 -0.034533 0.0166021 0.0317559 -0.033064 0.0131466 0.0331872 -0.0343217 0.0125661 0.0358785 -0.034533 0.00931747 0.0347733 -0.0357154 0.008529989999999999 0.040001 -0.036002 0.0125661 0.0358785 -0.034533 0.00917697 0.0347918 -0.0357665 0.008529989999999999 0.034877 -0.0360021 0.008529989999999999 0.040001 -0.036002 0.00931747 0.0347733 -0.0614 0.00931747 0.0347733 -0.0357154 0.0131466 0.0331872 -0.0343217 0.0131466 0.0331872 -0.0343217 0.0166021 0.0317559 -0.033064 0.0136587 0.0329751 -0.0467723 0.0166021 0.0317559 -0.033064 0.0175561 0.0313607 -0.0324366 0.0136587 0.0329751 -0.0467723 0.0175561 0.0313607 -0.0324366 0.018 0.0311769 -0.0321447 0.0136587 0.0329751 -0.0467723 0.018 0.0311769 -0.0321447 0.018 0.0311769 -0.0614 0.0136587 0.0329751 -0.0467723 0.018 0.0311769 -0.0614 0.00931747 0.0347733 -0.0614 0.0136587 0.0329751 -0.0467723 0.00931747 0.0347733 -0.0614 0.0131466 0.0331872 -0.0343217 0.0136587 0.0329751 -0.0467723 0.018 0.0311769 -0.0321447 0.0175561 0.0313607 -0.0324366 0.020191 0.0333714 -0.0307036 0.0175561 0.0313607 -0.0324366 0.016602 0.040001 -0.033064 0.020191 0.0333714 -0.0307036 0.016602 0.040001 -0.033064 0.02378 0.040001 -0.028343 0.020191 0.0333714 -0.0307036 0.02378 0.040001 -0.028343 0.02378 0.0267418 -0.0283432 0.020191 0.0333714 -0.0307036 0.02378 0.0267418 -0.0283432 0.0218608 0.0282144 -0.0296054 0.020191 0.0333714 -0.0307036 0.0218608 0.0282144 -0.0296054 0.018 0.0311769 -0.0321447 0.020191 0.0333714 -0.0307036 0.018 0.0311769 -0.0321447 0.0218608 0.0282144 -0.0296054 0.018 0.0311769 -0.0614 0.0254558 0.0254559 -0.0265671 0.0290571 0.0207626 -0.0227502 0.0254558 0.0254559 -0.0614 0.0250727 0.0257499 -0.0269731 0.02378 0.040001 -0.028343 0.0267277 0.029979 -0.025219 0.02378 0.040001 -0.028343 0.029675 0.040001 -0.022095 0.0267277 0.029979 -0.025219 0.029675 0.040001 -0.022095 0.0296753 0.0199569 -0.022095 0.0267277 0.029979 -0.025219 0.0296753 0.0199569 -0.022095 0.0290571 0.0207626 -0.0227502 0.0267277 0.029979 -0.025219 0.0290571 0.0207626 -0.0227502 0.0254558 0.0254559 -0.0265671 0.0267277 0.029979 -0.025219 0.0254558 0.0254559 -0.0265671 0.0250727 0.0257499 -0.0269731 0.0267277 0.029979 -0.025219 0.02378 0.040001 -0.028343 0.0250727 0.0257499 -0.0269731 0.02378 0.0267418 -0.0283432 -0.032046 0.040001 0.0185 -0.026916 0.040001 0.025391 -0.00853601 0.040001 -0.036002 -0.035449 -0.024999 0.010612 -0.032046 0.040001 0.0185 -0.035449 0.040001 0.010612 -0.035449 0.040001 0.010612 -0.03694 -0.024999 0.00215201 -0.035449 -0.024999 0.010612 -0.03694 -0.024999 0.00215201 -0.036441 -0.024999 -0.00642499 -0.0344958 -0.024999 7.24318e-05 -0.03694 -0.024999 0.00215201 -0.0344958 -0.024999 7.24318e-05 -0.03383 -0.024999 0.00678201 -0.03694 -0.024999 0.00215201 -0.03383 -0.024999 0.00678201 -0.0328447 -0.024999 0.0116462 -0.033977 -0.0112399 -0.014655 -0.0339079 -0.0114068 -0.0147747 -0.033977 -0.024999 -0.014655 -0.0300472 -0.0194723 -0.0214624 -0.029682 -0.024999 -0.022095 -0.0318295 -0.0181195 -0.018375 -0.029682 -0.024999 -0.022095 -0.033977 -0.024999 -0.014655 -0.0318295 -0.0181195 -0.018375 -0.0339079 -0.0114068 -0.0147747 -0.0311769 -0.018 -0.0195055 -0.0318295 -0.0181195 -0.018375 -0.0311769 -0.018 -0.0195055 -0.0300472 -0.0194723 -0.0214624 -0.0318295 -0.0181195 -0.018375 -0.033977 -0.024999 -0.014655 -0.0339079 -0.0114068 -0.0147747 -0.0318295 -0.0181195 -0.018375 -0.0311769 -0.018 -0.0614 -0.0311769 -0.018 -0.0195055 -0.0339079 -0.0114068 -0.0147747 -0.0311769 -0.018 -0.0614 -0.0347733 -0.009317499999999999 -0.0614 0.0254558 -0.0254558 -0.0614 -0.029682 -0.024999 -0.022095 -0.0294279 -0.024999 -0.0177322 -0.0317024 -0.024999 -0.0157859 -0.0294279 -0.024999 -0.0177322 -0.030236 -0.024999 -0.01662 -0.0317024 -0.024999 -0.0157859 -0.030236 -0.024999 -0.01662 -0.033064 -0.024999 -0.009476790000000001 -0.0317024 -0.024999 -0.0157859 -0.033064 -0.024999 -0.009476790000000001 -0.033977 -0.024999 -0.014655 -0.0317024 -0.024999 -0.0157859 -0.033977 -0.024999 -0.014655 -0.029682 -0.024999 -0.022095 -0.0317024 -0.024999 -0.0157859 -0.0344958 -0.024999 7.24318e-05 -0.034503 -0.024999 7.76846e-09 -0.034503 -0.032499 8.0963e-09 -0.0347733 -0.009317499999999999 -0.0614 -0.036 -1.52588e-08 -0.0614 0.0254558 -0.0254558 -0.0614 0.0311769 -0.018 -0.0614 -0.0311769 0.018 -0.0614 0.0347733 -0.009317489999999999 -0.0614 0.0258063 -0.024999 -0.0261964 0.0258063 -0.024999 -0.0225164 0.0254558 -0.0254558 -0.0228897 0.0258063 -0.024999 -0.0261964 0.0254558 -0.0254558 -0.0228897 0.0254558 -0.0254558 -0.0614 0.0277088 -0.0225196 -0.0241799 0.0258063 -0.024999 -0.0261964 0.0283164 -0.0217279 -0.0419582 0.0254558 -0.0254558 -0.0614 0.0311769 -0.018 -0.0614 0.0283164 -0.0217279 -0.0419582 0.0311769 -0.018 -0.0614 0.0277088 -0.0225196 -0.0241799 0.0283164 -0.0217279 -0.0419582 0.0258063 -0.024999 -0.0261964 0.0254558 -0.0254558 -0.0614 0.0283164 -0.0217279 -0.0419582 0.029675 0.040001 -0.022095 0.0311246 0.0180682 -0.0195845 0.0296753 0.0199569 -0.022095 0.033971 0.0112544 -0.014655 0.0339086 0.0114051 -0.0147631 0.031823 0.0256277 -0.018375 0.0339086 0.0114051 -0.0147631 0.0311769 0.018 -0.0194939 0.031823 0.0256277 -0.018375 0.0311769 0.018 -0.0194939 0.0311246 0.0180682 -0.0195845 0.031823 0.0256277 -0.018375 0.0311246 0.0180682 -0.0195845 0.029675 0.040001 -0.022095 0.031823 0.0256277 -0.018375 0.029675 0.040001 -0.022095 0.033971 0.040001 -0.014655 0.031823 0.0256277 -0.018375 0.033971 0.040001 -0.014655 0.033971 0.0112544 -0.014655 0.031823 0.0256277 -0.018375 0.0311769 0.018 -0.0614 0.0311769 0.018 -0.0194939 0.0339086 0.0114051 -0.0147631 0.0347733 0.009317509999999999 -0.0614 0.0311769 0.018 -0.0614 0.0339086 0.0114051 -0.0147631 0.0347733 0.009317509999999999 -0.0614 0.0339086 0.0114051 -0.0147631 0.033971 0.0112544 -0.014655 0.0347733 0.009317509999999999 -0.0614 0.033971 0.0112544 -0.014655 0.0347733 0.009317509999999999 -0.0119752 0.036 0 -0.0614 -0.0311769 0.018 -0.0614 0.0347733 0.009317509999999999 -0.0614 -0.00853601 0.040001 -0.036002 0.029675 0.040001 -0.022095 0.02378 0.040001 -0.028343 0.0175561 0.0313607 -0.0324366 0.0166021 0.0317559 -0.033064 0.016602 0.040001 -0.033064 -0.026916 0.040001 0.025391 -0.020335 0.040001 0.030913 -0.00853601 0.040001 -0.036002 -0.026916 0.040001 0.025391 -0.032046 0.040001 0.0185 -0.032046 -0.024999 0.0185 -0.032046 0.040001 0.0185 -0.035449 -0.024999 0.010612 -0.032046 -0.024999 0.0185 -0.035449 -0.024999 0.010612 -0.03694 -0.024999 0.00215201 -0.0328447 -0.024999 0.0116462 -0.035449 -0.024999 0.010612 -0.0328447 -0.024999 0.0116462 -0.0317601 -0.024999 0.0170012 -0.0300472 -0.0194723 -0.0214624 -0.029682 -0.0199482 -0.022095 -0.029682 -0.024999 -0.022095 -0.0311769 -0.018 -0.0614 -0.0254558 -0.0254559 -0.0614 -0.0290564 -0.0207635 -0.022758 -0.0311769 -0.018 -0.0614 -0.0290564 -0.0207635 -0.022758 -0.029682 -0.0199482 -0.022095 -0.0311769 -0.018 -0.0614 -0.029682 -0.0199482 -0.022095 -0.0300472 -0.0194723 -0.0214624 -0.0311769 -0.018 -0.0614 -0.0300472 -0.0194723 -0.0214624 -0.0311769 -0.018 -0.0195055 -0.0254558 -0.0254559 -0.0614 -0.0311769 -0.018 -0.0614 0.0254558 -0.0254558 -0.0614 -0.0258064 -0.024999 -0.026202 -0.0258064 -0.024999 -0.0227164 -0.0277442 -0.024999 -0.0219671 -0.0258064 -0.024999 -0.0227164 -0.0294279 -0.024999 -0.0177322 -0.0277442 -0.024999 -0.0219671 -0.0294279 -0.024999 -0.0177322 -0.029682 -0.024999 -0.022095 -0.0277442 -0.024999 -0.0219671 -0.029682 -0.024999 -0.022095 -0.0258064 -0.024999 -0.026202 -0.0277442 -0.024999 -0.0219671 0.0347733 -0.009317489999999999 -0.0614 -0.0311769 0.018 -0.0614 0.036 0 -0.0614 0.0322136 -0.0154972 -0.017699 0.0311769 -0.018 -0.0194949 0.0329751 -0.0136587 -0.0395495 0.0311769 -0.018 -0.0194949 0.0311769 -0.018 -0.0614 0.0329751 -0.0136587 -0.0395495 0.0311769 -0.018 -0.0614 0.0347733 -0.009317489999999999 -0.0614 0.0329751 -0.0136587 -0.0395495 0.0347733 -0.009317489999999999 -0.0614 0.0322136 -0.0154972 -0.017699 0.0329751 -0.0136587 -0.0395495 0.0277088 -0.0225196 -0.0241799 0.0292669 -0.0204891 -0.0225285 0.0277411 -0.0227441 -0.0241457 0.0292669 -0.0204891 -0.0225285 0.029676 -0.024999 -0.022095 0.0277411 -0.0227441 -0.0241457 0.029676 -0.024999 -0.022095 0.0258063 -0.024999 -0.0261964 0.0277411 -0.0227441 -0.0241457 0.0258063 -0.024999 -0.0261964 0.0277088 -0.0225196 -0.0241799 0.0277411 -0.0227441 -0.0241457 0.027908 -0.024999 -0.020278 0.029676 -0.024999 -0.022095 0.029004 -0.024999 -0.0182843 0.0258063 -0.024999 -0.0261964 0.029676 -0.024999 -0.022095 0.0277412 -0.024999 -0.0222403 0.027908 -0.024999 -0.020278 0.0258063 -0.024999 -0.0225164 0.0277412 -0.024999 -0.0222403 0.0258063 -0.024999 -0.0225164 0.0258063 -0.024999 -0.0261964 0.0277412 -0.024999 -0.0222403 0.029676 -0.024999 -0.022095 0.027908 -0.024999 -0.020278 0.0277412 -0.024999 -0.0222403 0.0258063 -0.024999 -0.0225164 0.027908 -0.024999 -0.020278 0.0254558 -0.0254558 -0.0228897 0.0254558 -0.0254558 -0.0228897 0.0235205 -0.0269408 -0.0249508 0.0233691 -0.027057 -0.0421448 0.0235205 -0.0269408 -0.0249508 0.021988 -0.0281168 -0.026583 0.0233691 -0.027057 -0.0421448 0.021988 -0.0281168 -0.026583 0.0212823 -0.0286582 -0.0270307 0.0233691 -0.027057 -0.0421448 0.0212823 -0.0286582 -0.0270307 0.0254558 -0.0254558 -0.0614 0.0233691 -0.027057 -0.0421448 0.0254558 -0.0254558 -0.0614 0.0254558 -0.0254558 -0.0228897 0.0233691 -0.027057 -0.0421448 0.0292669 -0.0204891 -0.0225285 0.0277088 -0.0225196 -0.0241799 0.0311769 -0.018 -0.0614 0.0296759 -0.0199561 -0.022095 0.0292669 -0.0204891 -0.0225285 0.0311769 -0.018 -0.0614 0.0311769 -0.018 -0.0194949 0.0296759 -0.0199561 -0.022095 0.0311769 -0.018 -0.0614 -0.00853601 0.040001 -0.036002 0.033971 0.040001 -0.014655 0.029675 0.040001 -0.022095 0.033971 0.040001 -0.014655 0.0347733 0.009317509999999999 -0.0119752 0.033971 0.0112544 -0.014655 0.0347733 0.009317509999999999 -0.0119752 0.033971 0.040001 -0.014655 0.03528 0.00546845 -0.0102826 0.0347733 0.009317509999999999 -0.0614 0.0347733 0.009317509999999999 -0.0119752 0.03528 0.00546845 -0.0102826 0.0347733 0.009317509999999999 -0.0614 0.03528 0.00546845 -0.0102826 0.0358314 0.00128097 -0.008441239999999999 0.036 0 -0.0614 0.0347733 0.009317509999999999 -0.0614 0.0358314 0.00128097 -0.008441239999999999 0.036 0 -0.0614 0.0358314 0.00128097 -0.008441239999999999 0.036 0 -0.00787795 -0.020335 0.040001 0.030913 -0.015941 0.040001 0.03312 -0.012562 0.040001 0.03312 -0.020335 0.040001 0.030913 -0.012562 0.040001 0.03312 -0.00853601 0.040001 -0.036002 -0.026916 -0.024999 0.025391 -0.020335 0.040001 0.030913 -0.026916 0.040001 0.025391 -0.026916 0.040001 0.025391 -0.032046 -0.024999 0.0185 -0.0312361 -0.024999 0.0195879 -0.026916 0.040001 0.025391 -0.0312361 -0.024999 0.0195879 -0.030743 -0.024999 0.0202504 -0.026916 0.040001 0.025391 -0.030743 -0.024999 0.0202504 -0.0298516 -0.024999 0.0214477 -0.026916 0.040001 0.025391 -0.0298516 -0.024999 0.0214477 -0.0274245 -0.024999 0.0247079 -0.026916 0.040001 0.025391 -0.0274245 -0.024999 0.0247079 -0.026916 -0.024999 0.025391 -0.035449 -0.024999 0.010612 -0.0317601 -0.024999 0.0170012 -0.032046 -0.024999 0.0185 -0.032046 -0.024999 0.0185 -0.0317601 -0.024999 0.0170012 -0.0312361 -0.024999 0.0195879 -0.0290564 -0.0207635 -0.022758 -0.0258064 -0.024999 -0.026202 -0.029682 -0.024999 -0.022095 -0.029682 -0.0199482 -0.022095 -0.0290564 -0.0207635 -0.022758 -0.029682 -0.024999 -0.022095 -0.0258064 -0.024999 -0.026202 -0.0290564 -0.0207635 -0.022758 -0.0254558 -0.0254559 -0.0614 -0.0254558 -0.0254559 -0.0231989 -0.0258064 -0.024999 -0.0227164 -0.0258064 -0.024999 -0.026202 -0.0254558 -0.0254559 -0.0614 -0.0254558 -0.0254559 -0.0231989 -0.0258064 -0.024999 -0.026202 -0.018 -0.0311769 -0.0614 -0.0254558 -0.0254559 -0.0614 0.0254558 -0.0254558 -0.0614 -0.0254558 -0.0254559 -0.0614 -0.0223017 -0.0278761 -0.025975 -0.0232262 -0.0271667 -0.0252101 -0.0254558 -0.0254559 -0.0614 -0.018 -0.0311769 -0.0614 -0.0223017 -0.0278761 -0.025975 -0.0254558 -0.0254559 -0.0614 -0.025152 -0.025689 -0.023617 -0.0254558 -0.0254559 -0.0231989 -0.0254558 -0.0254559 -0.0614 -0.0232262 -0.0271667 -0.0252101 -0.025152 -0.025689 -0.023617 0.0349976 -0.00761392 -0.0112261 0.0347733 -0.009317489999999999 -0.0119752 0.0353867 -0.00465875 -0.0363131 0.0347733 -0.009317489999999999 -0.0119752 0.0347733 -0.009317489999999999 -0.0614 0.0353867 -0.00465875 -0.0363131 0.0347733 -0.009317489999999999 -0.0614 0.036 0 -0.0614 0.0353867 -0.00465875 -0.0363131 0.036 0 -0.0614 0.0349976 -0.00761392 -0.0112261 0.0353867 -0.00465875 -0.0363131 0.0322136 -0.0154972 -0.017699 0.0331876 -0.0131457 -0.0160117 0.033971 -0.024999 -0.014655 0.0296759 -0.0199561 -0.022095 0.0311769 -0.018 -0.0194949 0.0318234 -0.0190724 -0.018375 0.0311769 -0.018 -0.0194949 0.0322136 -0.0154972 -0.017699 0.0318234 -0.0190724 -0.018375 0.033971 -0.024999 -0.014655 0.029676 -0.024999 -0.022095 0.0318234 -0.0190724 -0.018375 0.029676 -0.024999 -0.022095 0.0296759 -0.0199561 -0.022095 0.0318234 -0.0190724 -0.018375 0.0322136 -0.0154972 -0.017699 0.033971 -0.024999 -0.014655 0.0318234 -0.0190724 -0.018375 0.033971 -0.0112544 -0.014655 0.0347733 -0.009317489999999999 -0.0614 0.0347733 -0.009317489999999999 -0.0119752 0.0347733 -0.009317489999999999 -0.0614 0.033971 -0.0112544 -0.014655 0.0331876 -0.0131457 -0.0160117 0.0347733 -0.009317489999999999 -0.0614 0.0331876 -0.0131457 -0.0160117 0.0322136 -0.0154972 -0.017699 0.0292669 -0.0204891 -0.0225285 0.0296759 -0.0199561 -0.022095 0.029676 -0.024999 -0.022095 0.032074 -0.024999 -0.0127 0.033971 -0.024999 -0.014655 0.0326797 -0.024999 -0.0103416 0.032074 -0.024999 -0.0127 0.029004 -0.024999 -0.0182843 0.0314875 -0.024999 -0.0162183 0.029004 -0.024999 -0.0182843 0.029676 -0.024999 -0.022095 0.0314875 -0.024999 -0.0162183 0.029676 -0.024999 -0.022095 0.033971 -0.024999 -0.014655 0.0314875 -0.024999 -0.0162183 0.033971 -0.024999 -0.014655 0.032074 -0.024999 -0.0127 0.0314875 -0.024999 -0.0162183 0.0212823 -0.0286582 -0.0270307 0.0195459 -0.0299907 -0.0281325 0.0217279 -0.0283164 -0.0442154 0.0195459 -0.0299907 -0.0281325 0.018 -0.0311769 -0.0291133 0.0217279 -0.0283164 -0.0442154 0.018 -0.0311769 -0.0291133 0.018 -0.0311769 -0.0614 0.0217279 -0.0283164 -0.0442154 0.018 -0.0311769 -0.0614 0.0254558 -0.0254558 -0.0614 0.0217279 -0.0283164 -0.0442154 0.0254558 -0.0254558 -0.0614 0.0212823 -0.0286582 -0.0270307 0.0217279 -0.0283164 -0.0442154 -0.00853601 0.040001 -0.036002 0.036435 0.040001 -0.006425 0.033971 0.040001 -0.014655 0.033971 0.040001 -0.014655 0.036435 0.040001 -0.006425 0.03528 0.00546845 -0.0102826 0.03528 0.00546845 -0.0102826 0.036435 0.040001 -0.006425 0.0358314 0.00128097 -0.008441239999999999 0.0358314 0.00128097 -0.008441239999999999 0.036435 0.040001 -0.006425 0.036 0 -0.00787795 0.035602 -0.00302337 -0.009207450000000001 0.036 0 -0.00787795 0.036435 -0.024999 -0.006425 0.036 0 -0.00787795 0.036435 0.040001 -0.006425 0.036435 -0.024999 -0.006425 0.036 0 -0.0614 0.036 0 -0.00787795 0.035602 -0.00302337 -0.009207450000000001 0.036 0 -0.0614 0.035602 -0.00302337 -0.009207450000000001 0.0349976 -0.00761392 -0.0112261 -0.012562 0.040001 0.03312 -0.00450946 0.040001 0.03312 -0.00853601 0.040001 -0.036002 -0.015941 0.0275117 0.03312 -0.015941 0.040001 0.03312 -0.020335 0.040001 0.030913 -0.0159414 0.0122008 0.0331198 -0.015941 0.0275117 0.03312 -0.020335 0.040001 0.030913 -0.0159414 0.0122008 0.0331198 -0.020335 0.040001 0.030913 -0.020335 -0.024999 0.030913 -0.026916 -0.024999 0.025391 -0.021701 -0.024999 0.0297668 -0.020335 0.040001 0.030913 -0.021701 -0.024999 0.0297668 -0.020335 -0.024999 0.030913 -0.020335 0.040001 0.030913 -0.020335 -0.024999 0.030913 -0.0188016 -0.024999 0.0316831 -0.0159414 0.0122008 0.0331198 -0.0188016 -0.024999 0.0316831 -0.0159418 -0.024999 0.0331193 -0.0159414 0.0122008 0.0331198 -0.00931748 -0.0347733 -0.0614 -0.018 -0.0311769 -0.0614 0.0254558 -0.0254558 -0.0614 -0.018 -0.0311769 -0.0293591 -0.018489 -0.0308017 -0.029129 -0.018 -0.0311769 -0.0614 -0.018489 -0.0308017 -0.029129 -0.0223017 -0.0278761 -0.025975 -0.018 -0.0311769 -0.0614 0.0347733 -0.009317489999999999 -0.0119752 0.0349976 -0.00761392 -0.0112261 0.035203 -0.0140112 -0.01054 0.0349976 -0.00761392 -0.0112261 0.035602 -0.00302337 -0.009207450000000001 0.035203 -0.0140112 -0.01054 0.035602 -0.00302337 -0.009207450000000001 0.036435 -0.024999 -0.006425 0.035203 -0.0140112 -0.01054 0.036435 -0.024999 -0.006425 0.033971 -0.024999 -0.014655 0.035203 -0.0140112 -0.01054 0.033971 -0.024999 -0.014655 0.033971 -0.0112544 -0.014655 0.035203 -0.0140112 -0.01054 0.033971 -0.0112544 -0.014655 0.0347733 -0.009317489999999999 -0.0119752 0.035203 -0.0140112 -0.01054 0.0331876 -0.0131457 -0.0160117 0.033971 -0.0112544 -0.014655 0.033971 -0.024999 -0.014655 0.034225 -0.024999 -0.004324 0.036435 -0.024999 -0.006425 0.034225 -0.024999 -0.00130163 0.034225 -0.024999 -0.004324 0.0326797 -0.024999 -0.0103416 0.0345573 -0.024999 -0.007978310000000001 0.0326797 -0.024999 -0.0103416 0.033971 -0.024999 -0.014655 0.0345573 -0.024999 -0.007978310000000001 0.033971 -0.024999 -0.014655 0.036435 -0.024999 -0.006425 0.0345573 -0.024999 -0.007978310000000001 0.036435 -0.024999 -0.006425 0.034225 -0.024999 -0.004324 0.0345573 -0.024999 -0.007978310000000001 0.018 -0.0311769 -0.0291133 0.0148082 -0.032499 -0.0311385 0.018 -0.0311769 -0.0614 0.0148082 -0.032499 -0.0311385 0.0147114 -0.0325391 -0.0311656 0.018 -0.0311769 -0.0614 0.0147114 -0.0325391 -0.0311656 0.0146564 -0.0325619 -0.0311742 0.018 -0.0311769 -0.0614 0.0146564 -0.0325619 -0.0311742 0.013724 -0.0329481 -0.0311616 0.018 -0.0311769 -0.0614 0.018 -0.0311769 -0.0614 0.00931748 -0.0347733 -0.0614 0.0254558 -0.0254558 -0.0614 -0.00853601 0.040001 -0.036002 0.036934 0.040001 0.002152 0.036435 0.040001 -0.006425 0.036435 0.040001 -0.006425 0.036935 -0.024999 0.002151 0.036435 -0.024999 -0.006425 -0.00450946 0.040001 0.03312 0.00365194 0.040001 0.03312 -0.00853601 0.040001 -0.036002 0.0159356 -0.024999 0.0331197 0.020329 -0.024999 0.030913 0.015935 -0.00208533 0.03312 0.020329 -0.024999 0.030913 0.020329 0.040001 0.030913 0.018132 0.007501 0.0320165 0.020329 0.040001 0.030913 0.015935 0.00279795 0.03312 0.018132 0.007501 0.0320165 0.015935 0.00279795 0.03312 0.015935 -0.00208533 0.03312 0.018132 0.007501 0.0320165 0.015935 -0.00208533 0.03312 0.020329 -0.024999 0.030913 0.018132 0.007501 0.0320165 0.015935 0.00279795 0.03312 0.020329 0.040001 0.030913 0.015935 0.040001 0.03312 0.0121583 0.040001 0.03312 0.015935 0.040001 0.03312 0.020329 0.040001 0.030913 0.0121583 0.040001 0.03312 0.020329 0.040001 0.030913 -0.00853601 0.040001 -0.036002 0.00365194 0.040001 0.03312 0.0121583 0.040001 0.03312 -0.00853601 0.040001 -0.036002 0 -0.036 -0.0614 -0.00931748 -0.0347733 -0.0614 0.0254558 -0.0254558 -0.0614 -0.0148082 -0.032499 -0.030861 -0.018 -0.0311769 -0.0293591 -0.0136587 -0.0329751 -0.0453795 -0.018 -0.0311769 -0.0293591 -0.018 -0.0311769 -0.0614 -0.0136587 -0.0329751 -0.0453795 -0.018 -0.0311769 -0.0614 -0.00931748 -0.0347733 -0.0614 -0.0136587 -0.0329751 -0.0453795 -0.00931748 -0.0347733 -0.0614 -0.013626 -0.0329887 -0.0309315 -0.0136587 -0.0329751 -0.0453795 -0.013626 -0.0329887 -0.0309315 -0.0148082 -0.032499 -0.030861 -0.0136587 -0.0329751 -0.0453795 0.034225 -0.024999 -0.00130163 0.036435 -0.024999 -0.006425 0.036935 -0.024999 0.002151 0.034225 -0.024999 0.004324 0.036935 -0.024999 0.002151 0.0334599 -0.024999 0.008169940000000001 0.034225 -0.024999 0.004324 0.034225 -0.024999 -0.00130163 0.0351975 -0.024999 0.000872471 0.034225 -0.024999 -0.00130163 0.036935 -0.024999 0.002151 0.0351975 -0.024999 0.000872471 0.036935 -0.024999 0.002151 0.034225 -0.024999 0.004324 0.0351975 -0.024999 0.000872471 0.013724 -0.0329481 -0.0311616 0.00931748 -0.0347733 -0.0311017 0.0136587 -0.0329751 -0.0462509 0.00931748 -0.0347733 -0.0311017 0.00931748 -0.0347733 -0.0614 0.0136587 -0.0329751 -0.0462509 0.00931748 -0.0347733 -0.0614 0.018 -0.0311769 -0.0614 0.0136587 -0.0329751 -0.0462509 0.018 -0.0311769 -0.0614 0.013724 -0.0329481 -0.0311616 0.0136587 -0.0329751 -0.0462509 0.00931748 -0.0347733 -0.0614 0 -0.036 -0.0614 0.0254558 -0.0254558 -0.0614 -0.00853601 0.040001 -0.036002 0.035443 0.040001 0.010612 0.036934 0.040001 0.002152 0.036435 0.040001 -0.006425 0.036934 0.040001 0.002152 0.036935 -0.024999 0.002151 0.020329 -0.024999 0.030913 0.02691 0.040001 0.025391 0.020329 0.040001 0.030913 0.020329 0.040001 0.030913 0.02691 0.040001 0.025391 -0.00853601 0.040001 -0.036002 0.0320738 -0.024999 0.0151374 0.03204 -0.024999 0.0185 0.0312352 -0.024999 0.019353 0.03204 -0.024999 0.0185 0.0320738 -0.024999 0.0151374 0.035443 -0.024999 0.010612 0.0334599 -0.024999 0.008169940000000001 0.035443 -0.024999 0.010612 0.0320738 -0.024999 0.0151374 0.0334599 -0.024999 0.008169940000000001 0.036935 -0.024999 0.002151 0.0345044 -0.024999 0.008644209999999999 0.036935 -0.024999 0.002151 0.035443 -0.024999 0.010612 0.0345044 -0.024999 0.008644209999999999 0.035443 -0.024999 0.010612 0.0334599 -0.024999 0.008169940000000001 0.0345044 -0.024999 0.008644209999999999 -0.00875655 -0.0348472 -0.0311134 -0.00931748 -0.0347733 -0.0309839 -0.00465874 -0.0353867 -0.046192 -0.00931748 -0.0347733 -0.0309839 -0.00931748 -0.0347733 -0.0614 -0.00465874 -0.0353867 -0.046192 -0.00931748 -0.0347733 -0.0614 0 -0.036 -0.0614 -0.00465874 -0.0353867 -0.046192 0 -0.036 -0.0614 -0.00454796 -0.0354012 -0.03143 -0.00465874 -0.0353867 -0.046192 -0.00454796 -0.0354012 -0.03143 -0.00875655 -0.0348472 -0.0311134 -0.00465874 -0.0353867 -0.046192 -0.00931748 -0.0347733 -0.0309839 -0.0110676 -0.0340484 -0.0310841 -0.00931748 -0.0347733 -0.0614 -0.0110676 -0.0340484 -0.0310841 -0.013626 -0.0329887 -0.0309315 -0.00931748 -0.0347733 -0.0614 0.00513146 -0.0353244 -0.0316426 0.00479949 -0.0353681 -0.0316275 0.00931748 -0.0347733 -0.0614 0.00931748 -0.0347733 -0.0311017 0.008169249999999999 -0.0349245 -0.0313513 0.00931748 -0.0347733 -0.0614 0.008169249999999999 -0.0349245 -0.0313513 0.00513146 -0.0353244 -0.0316426 0.00931748 -0.0347733 -0.0614 0.000453537 -0.0359403 -0.031429 1.33055e-09 -0.036 -0.0313418 0.00465874 -0.0353867 -0.0463709 1.33055e-09 -0.036 -0.0313418 0 -0.036 -0.0614 0.00465874 -0.0353867 -0.0463709 0 -0.036 -0.0614 0.00931748 -0.0347733 -0.0614 0.00465874 -0.0353867 -0.0463709 0.00931748 -0.0347733 -0.0614 0.00479949 -0.0353681 -0.0316275 0.00465874 -0.0353867 -0.0463709 0.00479949 -0.0353681 -0.0316275 0.000453537 -0.0359403 -0.031429 0.00465874 -0.0353867 -0.0463709 0.03204 0.040001 0.0185 0.035443 0.040001 0.010612 -0.00853601 0.040001 -0.036002 0.036934 0.040001 0.002152 0.035443 0.040001 0.010612 0.035443 -0.024999 0.010612 0.035443 -0.024999 0.010612 0.036935 -0.024999 0.002151 0.036934 0.040001 0.002152 0.03204 0.040001 0.0185 0.02691 -0.024999 0.025391 0.0311733 -0.024999 0.0196642 0.03204 0.040001 0.0185 0.0311733 -0.024999 0.0196642 0.03204 -0.024999 0.0185 0.020329 -0.024999 0.030913 0.02691 -0.024999 0.025391 0.02691 0.040001 0.025391 0.02691 0.040001 0.025391 0.03204 0.040001 0.0185 -0.00853601 0.040001 -0.036002 0.035443 0.040001 0.010612 0.03204 -0.024999 0.0185 0.035443 -0.024999 0.010612 -0.00339446 -0.0355531 -0.0315168 -0.00454796 -0.0354012 -0.03143 0 -0.036 -0.0614 1.33055e-09 -0.036 -0.0313418 -0.00339446 -0.0355531 -0.0315168 0 -0.036 -0.0614 0.035443 0.040001 0.010612 0.03204 0.040001 0.0185 0.03204 -0.024999 0.0185 0.03204 0.040001 0.0185 0.02691 0.040001 0.025391 0.02691 -0.024999 0.025391 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069

    -
    -
    - - - 0 0 0 - 1 0 0 0 - - true - - - -
    - - - - 0.002111 0.10942 -0.150588 -0.001488 0.108845 -0.164172 -0.003402 0.115569 -0.163868 -0.000148996 0.095447 -0.16415 0.001094 0.08108700000000001 -0.154548 -0.003025 0.08194 -0.169916 -0.0260095 0.0726874 -0.273041 -0.028807 0.0833648 -0.269883 -0.0254514 0.0873768 -0.273671 -0.031735 0.06163 -0.165798 -0.017612 0.06343500000000001 -0.16783 -0.029338 0.061197 -0.149079 -0.059939 0.107883 -0.232469 -0.068758 0.118998 -0.233305 -0.056969 0.113801 -0.232188 -0.057231 0.049998 -0.190235 -0.041233 0.049998 -0.177738 -0.047047 0.049998 -0.178417 -0.042184 0.094998 -0.262167 -0.035455 0.094998 -0.268032 -0.03345 0.080718 -0.265711 -0.044033 0.049998 -0.223626 -0.057231 0.049998 -0.190235 -0.051541 0.049998 -0.221496 -0.0014 0.074006 -0.1541 -0.003516 0.066757 -0.136938 -0.006163 0.067844 -0.153244 0.029473 0.076419 -0.019718 0.032223 0.082122 -0.02238 0.03148 0.079376 -0.016907 0.027925 0.07441300000000001 -0.021615 0.029473 0.076419 -0.019718 0.031544 0.039998 -0.016125 0.024691 0.137998 -0.024464 0.020278 0.123345 -0.028527 0.018239 0.137998 -0.029872 -0.06231 0.094998 -0.232694 -0.068758 0.07099800000000001 -0.233304 -0.061713 0.101573 -0.232638 0.029564 0.113644 -0.019588 0.03132 0.111039 -0.017164 0.031539 0.110116 -0.019935 -0.068483 0.088411 -0.18205 -0.069103 0.094998 -0.18211 -0.07356699999999999 0.118998 -0.182532 -0.023403 0.049998 -0.197539 -0.022563 0.065247 -0.201419 -0.023523 0.064305 -0.197932 -0.013414 0.13189 -0.032243 -0.022774 0.137998 -0.02658 -0.013446 0.137998 -0.032316 0.035402 0.039998 -0.00747301 0.031876 0.080175 -0.016158 0.033206 0.08286200000000001 -0.013636 -0.033653 0.094998 -0.269585 -0.028931 0.094998 -0.27299 -0.029842 0.080358 -0.268227 -0.057071 0.107012 -0.239238 -0.059939 0.107883 -0.232469 -0.056969 0.113801 -0.232188 0.032223 0.082122 -0.02238 0.035016 0.08812399999999999 -0.009014019999999999 0.033572 0.08360099999999999 -0.012943 -0.013414 0.13189 -0.032243 0.00154202 0.131335 -0.060324 -0.012814 0.13337 -0.057215 -0.037126 0.124813 -0.24216 -0.036792 0.125578 -0.240488 -0.035081 0.127396 -0.235407 -0.057071 0.107012 -0.239238 -0.06231 0.094998 -0.232694 -0.061713 0.101573 -0.232638 -0.0291896 0.102998 -0.269154 -0.028807 0.102997 -0.269883 -0.0305964 0.102997 -0.269722 -0.0151932 0.067998 -0.218602 -0.016268 0.067998 -0.21901 -0.016268 0.057998 -0.21901 -0.003025 0.08194 -0.169916 -0.00468 0.07505100000000001 -0.169678 -0.007637 0.082319 -0.18461 0.008374009999999999 0.131398 -0.283984 0.016263 0.131398 -0.280992 0.016263 0.057998 -0.280992 -0.03788 0.102998 -0.246961 -0.034747 0.102998 -0.249047 -0.0357192 0.102998 -0.253002 -0.0014 0.074006 -0.1541 -0.006163 0.067844 -0.153244 -0.00468 0.07505100000000001 -0.169678 -0.0266445 0.102997 -0.272324 -0.0260095 0.115038 -0.273041 -0.024783 0.102997 -0.274717 0.00154202 0.131335 -0.060324 0.01403 0.12392 -0.063029 -0.011323 0.130169 -0.118162 -0.07356699999999999 0.07099800000000001 -0.182532 -0.061464 0.07099800000000001 -0.209841 -0.062369 0.07099800000000001 -0.20209 -0.012724 0.076705 -0.209545 -0.009834000000000001 0.077057 -0.213119 -0.009162 0.08319500000000001 -0.212779 -0.010793 0.07091600000000001 -0.216706 -0.013686 0.067998 -0.217787 -0.00884017 0.067998 -0.216193 -0.048222 0.07156700000000001 -0.09278500000000001 -0.054037 0.08229 -0.091492 -0.053559 0.071121 -0.126929 -0.052157 0.049998 -0.181269 -0.047047 0.049998 -0.178417 -0.046303 0.062916 -0.178326 -0.049442 0.094998 -0.254344 -0.046949 0.107107 -0.253978 -0.048554 0.094998 -0.255301 0.033408 0.106873 -0.013307 0.031539 0.110116 -0.019935 0.032042 0.109598 -0.01583 -0.058648 0.118944 -0.171066 -0.045891 0.126901 -0.157101 -0.047993 0.126464 -0.17232 0.034742 0.057998 -0.25422 0.032723 0.131398 -0.262412 0.034742 0.131398 -0.25422 -0.034747 0.057998 -0.245782 -0.034747 0.0608632 -0.250001 -0.034747 0.057998 -0.25422 0.00154202 0.131335 -0.060324 -0.011323 0.130169 -0.118162 -0.025099 0.132149 -0.115228 -0.023212 0.057998 -0.223803 -0.0197401 0.060498 -0.221406 -0.01974 0.062998 -0.221406 -0.029147 0.062151 -0.185728 -0.021233 0.0636 -0.183487 -0.031137 0.061966 -0.183063 -0.051541 0.049998 -0.221496 -0.057662 0.049998 -0.216656 -0.053931 0.068025 -0.219959 -0.058675 0.08124099999999999 -0.234455 -0.06231 0.094998 -0.232694 -0.058828 0.094998 -0.240143 -0.012418 0.071588 -0.214274 -0.010793 0.07091600000000001 -0.216706 -0.010009 0.07188899999999999 -0.216485 -0.012316 0.08247400000000001 -0.198331 -0.01322 0.08273999999999999 -0.204899 -0.012348 0.09540999999999999 -0.20183 -0.032728 0.102998 -0.262412 -0.032728 0.131398 -0.262412 -0.0312109 0.102998 -0.265303 -2.99964e-06 0.0579979 -0.285001 -0.023212 0.057998 -0.223803 -0.028807 0.057998 -0.230119 0.019315 0.118087 -0.06417299999999999 0.023357 0.111167 -0.065049 0.00568601 0.117233 -0.121784 -0.0337375 0.062998 -0.241686 -0.0344719 0.067998 -0.244666 -0.034747 0.057998 -0.245782 -0.046303 0.062916 -0.178326 -0.031735 0.06163 -0.165798 -0.044694 0.06277199999999999 -0.163934 -0.0197401 0.060498 -0.221406 -0.023212 0.057998 -0.223803 -0.016268 0.057998 -0.21901 -0.054278 0.117226 -0.231933 -0.06334099999999999 0.119187 -0.232981 -0.0544271 0.119498 -0.232738 0.025455 0.071586 -0.024275 0.027925 0.07441300000000001 -0.021615 0.031544 0.039998 -0.016125 0.032723 0.057998 -0.23759 0.034742 0.131398 -0.245782 0.032723 0.131398 -0.23759 -0.030235 0.12028 -0.017474 -0.035803 0.108542 -0.00859101 -0.033607 0.112586 -0.00902201 -0.015557 0.067998 -0.215638 -0.014746 0.067998 -0.216628 -0.012418 0.071588 -0.214274 -0.036911 0.114414 -0.258801 -0.036966 0.102998 -0.258815 -0.036116 0.111791 -0.261823 -0.022563 0.065247 -0.201419 -0.022497 0.049998 -0.20529 -0.02251 0.06550499999999999 -0.20529 -0.0319859 0.102998 -0.236176 -0.0307675 0.117198 -0.233855 -0.032728 0.102998 -0.23759 -0.0137 0.060008 -0.065689 -0.00370299 0.062147 -0.102663 0.00428401 0.062021 -0.069631 -0.021122 0.12593 -0.218412 -0.019807 0.102998 -0.21757 -0.022862 0.12675 -0.219763 -0.012724 0.076705 -0.209545 -0.009162 0.08319500000000001 -0.212779 -0.012034 0.082993 -0.209343 -0.044694 0.06277199999999999 -0.163934 -0.057094 0.07038999999999999 -0.162155 -0.058697 0.07023500000000001 -0.180422 -0.008725 0.09539 -0.21254 -0.00891 0.107254 -0.21306 -0.011576 0.095397 -0.209183 0.002111 0.10942 -0.150588 0.003933 0.09546499999999999 -0.151245 0.002275 0.095455 -0.156935 -0.042229 0.071954 -0.059438 -0.044547 0.08257 -0.041831 -0.047727 0.082469 -0.058234 -0.0423461 0.119877 -0.245385 -0.040037 0.124841 -0.23872 -0.042263 0.117494 -0.250094 -0.0339658 0.102998 -0.25739 -0.0335584 0.102998 -0.259043 -0.036966 0.102998 -0.258815 -0.010933 0.121115 -0.176687 -0.025578 0.127553 -0.188988 -0.022363 0.127685 -0.17534 -0.032728 0.131398 -0.23759 -0.028807 0.131398 -0.230119 -0.008378999999999999 0.131398 -0.283984 0.022974 0.06915499999999999 -0.026468 0.019976 0.067373 -0.037929 0.025455 0.071586 -0.024275 -0.008378999999999999 0.131398 -0.283984 -0.016268 0.131398 -0.21901 -0.008378999999999999 0.131398 -0.216018 -0.021795 0.094998 -0.277775 -0.017284 0.094997 -0.280436 -0.025963 0.094998 -0.2751 -0.0500441 0.123165 -0.226155 -0.046622 0.126471 -0.220648 -0.0511948 0.122623 -0.223052 -0.067456 0.094998 -0.160678 -0.062692 0.08193499999999999 -0.143086 -0.06519 0.094998 -0.142662 -0.032728 0.067998 -0.23759 -0.0344719 0.067998 -0.244666 -0.0337375 0.062998 -0.241686 -0.022266 0.067998 -0.22315 -0.0204416 0.067998 -0.221891 -0.024636 0.067998 -0.221068 -0.034048 0.039998 -0.008119009999999999 -0.029873 0.039998 -0.018243 0.024691 0.039998 -0.024464 -0.011416 0.095416 -0.197055 -0.012316 0.08247400000000001 -0.198331 -0.012348 0.09540999999999999 -0.20183 -0.014746 0.067998 -0.216628 -0.013686 0.067998 -0.217787 -0.012418 0.071588 -0.214274 -0.0307675 0.117198 -0.266147 -0.028807 0.102997 -0.269883 -0.0291896 0.102998 -0.269154 0.008373 0.057998 -0.216018 0.016263 0.057998 -0.21901 0.008374009999999999 0.131398 -0.216018 -0.001488 0.108845 -0.164172 -0.002018 0.095441 -0.169715 -0.005313 0.108449 -0.177352 0.034981 0.039998 0.010695 0.033206 0.039998 0.014953 0.024691 0.039998 -0.024464 -0.033234 0.07478029999999999 -0.260359 -0.032728 0.0763397 -0.262412 -0.0331411 0.07301580000000001 -0.260736 0.023298 0.137998 0.028256 0.018877 0.137998 0.031087 0.018876 0.039998 0.031088 -0.058675 0.08124099999999999 -0.234455 -0.058828 0.094998 -0.240143 -0.052093 0.08112999999999999 -0.246067 -0.012316 0.08247400000000001 -0.198331 -0.013229 0.075809 -0.19835 -0.01322 0.08273999999999999 -0.204899 -0.008378999999999999 0.131398 -0.283984 -0.016268 0.057998 -0.280992 -0.017284 0.094997 -0.280436 -0.013114 0.108058 -0.201814 -0.014048 0.114524 -0.201854 -0.009605000000000001 0.108348 -0.189741 -0.024783 0.102997 -0.274717 -0.0235251 0.0995163 -0.275846 -0.028332 0.102997 -0.27231 -0.034747 0.102998 -0.247697 -0.03788 0.102998 -0.246961 -0.034747 0.102998 -0.247212 -0.023212 0.067998 -0.223803 -0.022266 0.067998 -0.22315 -0.024636 0.067998 -0.221068 -0.008795000000000001 0.075515 -0.184517 -0.008943 0.068842 -0.169065 -0.012684 0.069286 -0.184201 -0.057231 0.068227 -0.190235 -0.060239 0.07099800000000001 -0.194583 -0.057231 0.049998 -0.190235 -0.034747 0.131398 -0.245782 -0.034747 0.131398 -0.25422 -0.034747 0.117198 -0.250001 0.023207 0.057998 -0.223803 0.028802 0.057998 -0.230119 0.028802 0.131398 -0.230119 -0.017612 0.06343500000000001 -0.16783 -0.014243 0.063067 -0.151789 -0.029338 0.061197 -0.149079 -0.032728 0.0763397 -0.262412 -0.0320424 0.0768882 -0.263718 -0.0310716 0.0699446 -0.265568 -0.016665 0.06974900000000001 -0.198437 -0.023523 0.064305 -0.197932 -0.017073 0.070427 -0.205294 -0.033834 0.067998 -0.232697 -0.032728 0.067998 -0.23759 -0.0321938 0.067998 -0.236572 -0.06192 0.118998 -0.181429 -0.059219 0.119502 -0.181032 -0.061919 0.116225 -0.181428 -0.005627 0.08337899999999999 -0.215459 -0.006693 0.077352 -0.215648 -0.0047623 0.07911310000000001 -0.215472 -0.012303 0.113728 -0.210533 -0.014048 0.114524 -0.201854 -0.013114 0.108058 -0.201814 -0.016268 0.102998 -0.21901 -0.0189548 0.102998 -0.220865 -0.0180375 0.102998 -0.219217 -0.020843 0.060114 -0.098861 -0.0137 0.060008 -0.065689 -0.031196 0.062566 -0.061855 0.031112 0.039998 0.019976 0.027792 0.039998 0.024268 0.024691 0.039998 -0.024464 -0.008795000000000001 0.075515 -0.184517 -0.012684 0.069286 -0.184201 -0.013229 0.075809 -0.19835 0.033408 0.106873 -0.013307 0.035503 0.137998 -0.00716101 0.034883 0.102449 -0.00945201 -0.014048 0.114524 -0.201854 -0.010797 0.115038 -0.189686 -0.009605000000000001 0.108348 -0.189741 -0.0337375 0.0617524 -0.258316 -0.0337375 0.06550690000000001 -0.258316 -0.032728 0.057998 -0.262412 -0.050376 0.126442 -0.204039 -0.0530965 0.122945 -0.213171 -0.0547976 0.123013 -0.204317 0.019976 0.067373 -0.037929 0.021022 0.071631 -0.055785 0.025148 0.073194 -0.03896 -0.014708 0.120982 -0.189504 -0.027461 0.127109 -0.202655 -0.025578 0.127553 -0.188988 -0.040037 0.124841 -0.23872 -0.0439799 0.120915 -0.241308 -0.0430425 0.123603 -0.236991 -0.035087 0.102998 -0.235405 -0.03788 0.102998 -0.246961 -0.037778 0.122727 -0.246416 -0.014746 0.067998 -0.216628 -0.015557 0.067998 -0.215638 -0.024636 0.067998 -0.221068 -0.059517 0.07099800000000001 -0.181201 -0.060239 0.07099800000000001 -0.194583 -0.058697 0.07023500000000001 -0.180422 0.025371 0.117444 -0.034582 0.025406 0.118766 -0.024322 0.027101 0.116799 -0.022508 0.029084 0.08015 -0.039744 0.033541 0.095485 -0.031703 0.0320145 0.08767129999999999 -0.031062 0.008041009999999999 0.06154 -0.033737 0.010922 0.062035 -0.036126 0.010685 0.062075 -0.033096 -0.036911 0.114414 -0.258801 -0.040674 0.10718 -0.260584 -0.036116 0.111791 -0.261823 -0.040722 0.08209 -0.025833 -0.039489 0.094998 -0.011609 -0.042425 0.094998 -0.023232 0.020278 0.039998 -0.028527 0.024691 0.039998 -0.024464 0.018239 0.039998 -0.029872 -0.044032 0.06316099999999999 -0.223615 -0.036282 0.049998 -0.22272 -0.044033 0.049998 -0.223626 -0.034606 0.107636 -0.265703 -0.034039 0.106035 -0.26681 -0.032964 0.102998 -0.268909 -0.010007 0.113411 -0.213347 -0.012303 0.113728 -0.210533 -0.009391 0.111495 -0.213179 -0.016895 0.128882 -0.147054 -0.019536 0.128174 -0.161298 -0.032859 0.130041 -0.159176 -0.040674 0.10718 -0.260584 -0.034606 0.107636 -0.265703 -0.042184 0.094998 -0.262167 -0.014243 0.063067 -0.151789 -0.017612 0.06343500000000001 -0.16783 -0.008943 0.068842 -0.169065 -0.001488 0.108845 -0.164172 0.002111 0.10942 -0.150588 0.002275 0.095455 -0.156935 -0.008378999999999999 0.131398 -0.216018 -0.0123235 0.117198 -0.217514 -0.0114314 0.102998 -0.217176 -0.060132 0.08210099999999999 -0.125616 -0.0582432 0.0883525 -0.108554 -0.059351 0.094998 -0.107759 -2.99964e-06 0.0579979 -0.285001 -0.008378999999999999 0.057998 -0.216018 -0.016268 0.057998 -0.21901 -0.037778 0.122727 -0.246416 -0.037626 0.123668 -0.244667 -0.042263 0.117494 -0.250094 -0.00280198 0.137998 -0.034889 -0.00279198 0.132618 -0.034791 -0.013446 0.137998 -0.032316 -0.051395 0.069561 -0.231297 -0.058675 0.08124099999999999 -0.234455 -0.045077 0.06940499999999999 -0.241524 -0.0588453 0.119509 -0.182979 -0.059219 0.119502 -0.181032 -0.058413 0.119945 -0.185262 -0.056496 0.069824 -0.217583 -0.055771 0.069714 -0.220433 -0.053931 0.068025 -0.219959 -0.004855 0.095383 -0.215339 -0.008725 0.09539 -0.21254 -0.009162 0.08319500000000001 -0.212779 -0.031735 0.06163 -0.165798 -0.029338 0.061197 -0.149079 -0.043426 0.062724 -0.146549 -0.038989 0.129258 -0.203352 -0.046622 0.126471 -0.220648 -0.050376 0.126442 -0.204039 -0.032728 0.0763397 -0.262412 -0.033234 0.07478029999999999 -0.260359 -0.03345 0.080718 -0.265711 -0.052113 0.06517000000000001 -0.181323 -0.044694 0.06277199999999999 -0.163934 -0.058697 0.07023500000000001 -0.180422 -0.059351 0.094998 -0.107759 -0.056918 0.108547 -0.108453 -0.062363 0.094998 -0.125247 -0.028807 0.067998 -0.230119 -0.0280447 0.067998 -0.229259 -0.0271378 0.067998 -0.226882 -0.062009 0.108246 -0.138661 -0.06411 0.10808 -0.1542 -0.06519 0.094998 -0.142662 0.023357 0.111167 -0.065049 0.026925 0.09553 -0.064763 0.024673 0.095531 -0.074061 0.029418 0.110682 -0.035372 0.031961 0.095501 -0.040298 0.029163 0.09553 -0.05552 -0.051439 0.066625 -0.221282 -0.051541 0.049998 -0.221496 -0.053931 0.068025 -0.219959 -0.058172 0.07099800000000001 -0.216032 -0.061464 0.07099800000000001 -0.209841 -0.056939 0.07099800000000001 -0.220732 -0.030964 0.102997 -0.270424 -0.032964 0.102998 -0.268909 -0.0305964 0.102997 -0.269722 -0.012303 0.113728 -0.210533 -0.00891 0.107254 -0.21306 -0.009391 0.111495 -0.213179 -0.033834 0.067998 -0.232697 -0.0271378 0.067998 -0.226882 -0.024636 0.067998 -0.221068 -0.052941 0.065599 -0.181985 -0.058697 0.07023500000000001 -0.180422 -0.055699 0.06725100000000001 -0.185688 -0.017449 0.120256 -0.202053 -0.014708 0.120982 -0.189504 -0.010797 0.115038 -0.189686 -0.025205 0.06349100000000001 -0.213649 -0.026485 0.062779 -0.215759 -0.024362 0.063959 -0.21226 -0.058172 0.07099800000000001 -0.216032 -0.056496 0.069824 -0.217583 -0.057662 0.049998 -0.216656 -0.057231 0.049998 -0.190235 -0.02816 0.049998 -0.188077 -0.031012 0.049998 -0.182966 -0.069103 0.094998 -0.18211 -0.068483 0.088411 -0.18205 -0.066376 0.081721 -0.179787 -0.034747 0.131398 -0.25422 -0.032728 0.131398 -0.262412 -0.0337375 0.117198 -0.258316 -0.00370299 0.062147 -0.102663 -0.003516 0.066757 -0.136938 0.002578 0.065321 -0.104062 -0.032318 0.137998 0.013442 -0.03489 0.039998 0.00279899 -0.032318 0.039998 0.013443 -0.0137 0.060008 -0.065689 -0.028074 0.06254899999999999 -0.045339 -0.031196 0.062566 -0.061855 -0.050376 0.126442 -0.204039 -0.0570217 0.121279 -0.192606 -0.049958 0.126383 -0.187824 -0.068483 0.088411 -0.18205 -0.07356699999999999 0.07099800000000001 -0.182532 -0.066635 0.08205900000000001 -0.181875 -0.0090645 0.0746965 -0.215135 -0.00812 0.074265 -0.215957 -0.009834000000000001 0.077057 -0.213119 -0.020283 0.039998 0.028524 0.024691 0.039998 -0.024464 -0.009214989999999999 0.039998 0.034258 -0.019807 0.102998 -0.21757 -0.019773 0.124949 -0.217628 -0.00891 0.107254 -0.21306 -0.034747 0.0637284 -0.250001 -0.034747 0.067998 -0.24674 -0.034747 0.067998 -0.247212 -0.034747 0.067998 -0.24674 -0.034747 0.0637284 -0.250001 -0.034747 0.067998 -0.245782 -0.027461 0.127109 -0.202655 -0.035565 0.128969 -0.217398 -0.038989 0.129258 -0.203352 -2.99964e-06 0.0579979 -0.285001 0.008373 0.057998 -0.216018 -2.99582e-06 0.057998 -0.215001 -0.023212 0.0986773 -0.276199 -0.0204923 0.09732010000000001 -0.278076 -0.021795 0.094998 -0.277775 -0.031196 0.062566 -0.061855 -0.039228 0.072168 -0.042965 -0.042229 0.071954 -0.059438 0.0357 0.09740500000000001 -0.006256 0.035788 0.09544 -0.00580301 0.031539 0.110116 -0.019935 -0.045625 0.094998 -0.258458 -0.042184 0.094998 -0.262167 -0.043563 0.080983 -0.256573 0.023298 0.137998 0.028256 0.018876 0.039998 0.031088 0.023298 0.039998 0.028256 -0.03489 0.039998 0.00279899 0.024691 0.039998 -0.024464 -0.032318 0.039998 0.013443 -0.012348 0.09540999999999999 -0.20183 -0.01322 0.08273999999999999 -0.204899 -0.012343 0.0954 -0.207618 -0.011323 0.130169 -0.118162 -0.016895 0.128882 -0.147054 -0.030429 0.13079 -0.144536 -0.0321938 0.067998 -0.236572 -0.032728 0.067998 -0.23759 -0.032728 0.057998 -0.23759 -0.037626 0.117517 -0.254781 -0.037904 0.118998 -0.252736 -0.036911 0.114414 -0.258801 -0.034747 0.0608632 -0.250001 -0.034747 0.0637284 -0.250001 -0.034747 0.057998 -0.25422 -0.0254514 0.0873768 -0.273671 -0.028807 0.0833648 -0.269883 -0.0269275 0.08767800000000001 -0.272574 -0.0291173 0.07068140000000001 -0.269292 -0.0293392 0.067998 -0.268869 -0.0294052 0.0795941 -0.268743 -0.0123235 0.0659771 -0.217514 -0.0151932 0.067998 -0.218602 -0.016268 0.057998 -0.21901 -0.006693 0.077352 -0.215648 -0.00415147 0.0748472 -0.215505 -0.0047623 0.07911310000000001 -0.215472 0.00811601 0.137998 -0.034047 0.018239 0.137998 -0.029872 0.018147 0.12471 -0.029694 0.016863 0.071426 -0.07238600000000001 0.011027 0.065356 -0.071107 0.008484 0.07136099999999999 -0.105372 -0.004483 0.095432 -0.177054 -0.0049804 0.088686 -0.177374 -0.007637 0.082319 -0.18461 -0.062369 0.049998 -0.20209 -0.061464 0.049998 -0.209841 -0.057231 0.049998 -0.190235 -0.030235 0.12028 -0.017474 -0.033607 0.112586 -0.00902201 -0.034048 0.137998 -0.008119019999999999 0.025371 0.117444 -0.034582 0.029418 0.110682 -0.035372 0.019315 0.118087 -0.06417299999999999 0.00116802 0.137998 0.036003 0.00116801 0.039998 0.036003 0.00667102 0.137998 0.035573 0.021022 0.071631 -0.055785 0.019976 0.067373 -0.037929 0.015328 0.06553 -0.054574 -0.0367172 0.0626169 -0.228912 -0.041227 0.062847 -0.226878 -0.034819 0.062778 -0.23491 0.025455 0.071586 -0.024275 0.019976 0.067373 -0.037929 0.027925 0.07441300000000001 -0.021615 0.032723 0.131398 -0.262412 0.028802 0.131398 -0.269883 -0.008378999999999999 0.131398 -0.283984 -0.0182832 0.0924469 -0.279645 -0.0199652 0.0921587 -0.27844 -0.017284 0.094997 -0.280436 0.034742 0.057998 -0.245782 0.034742 0.131398 -0.245782 0.032723 0.057998 -0.23759 -0.0306243 0.067998 -0.26642 -0.032728 0.057998 -0.262412 -0.0310716 0.0699446 -0.265568 -0.010009 0.07188899999999999 -0.216485 -0.010793 0.07091600000000001 -0.216706 -0.00884017 0.067998 -0.216193 -0.016268 0.131398 -0.21901 -0.023212 0.131398 -0.223803 -0.01974 0.117198 -0.221406 0.032723 0.131398 -0.262412 0.034742 0.057998 -0.25422 0.032723 0.057998 -0.262412 -0.025578 0.127553 -0.188988 -0.037903 0.12941 -0.1884 -0.022363 0.127685 -0.17534 -0.0307675 0.117198 -0.266147 -0.028807 0.131398 -0.269883 -0.028807 0.102997 -0.269883 0.016263 0.131398 -0.280992 0.008374009999999999 0.131398 -0.283984 -0.008378999999999999 0.131398 -0.283984 -0.034747 0.102998 -0.249047 -0.03788 0.102998 -0.246961 -0.034747 0.102998 -0.247697 0.010922 0.062035 -0.036126 -0.010127 0.060008 -0.049157 0.008237009999999999 0.061996 -0.053063 -0.0204923 0.09732010000000001 -0.278076 -0.0203629 0.101282 -0.278166 -0.017284 0.094997 -0.280436 -0.035087 0.102998 -0.235405 -0.037778 0.122727 -0.246416 -0.035081 0.127396 -0.235407 0.023207 0.057998 -0.276199 0.028802 0.057998 -0.269883 -2.99964e-06 0.0579979 -0.285001 -0.029842 0.080358 -0.268227 -0.028807 0.0833648 -0.269883 -0.0294276 0.0808743 -0.268701 -0.019807 0.102998 -0.21757 -0.021122 0.12593 -0.218412 -0.019773 0.124949 -0.217628 -0.028807 0.067998 -0.230119 -0.0297872 0.062998 -0.231987 -0.028807 0.057998 -0.230119 -0.0203629 0.101282 -0.278166 -0.016268 0.131398 -0.280992 -0.017284 0.094997 -0.280436 0.032223 0.082122 -0.02238 0.029084 0.08015 -0.039744 0.0320145 0.08767129999999999 -0.031062 0.018877 0.137998 0.031087 0.017841 0.137998 0.03175 0.017841 0.039998 0.031751 -0.028807 0.131398 -0.230119 -0.023212 0.131398 -0.223803 -0.008378999999999999 0.131398 -0.283984 -0.03489 0.137998 0.00279898 -0.033607 0.112586 -0.00902201 -0.034887 0.098269 0.00279799 0.031961 0.095501 -0.040298 0.033541 0.095485 -0.031703 0.029084 0.08015 -0.039744 -0.052093 0.08112999999999999 -0.246067 -0.049442 0.094998 -0.254344 -0.043563 0.080983 -0.256573 0.018876 0.039998 0.031088 0.018877 0.137998 0.031087 0.017841 0.039998 0.031751 0.036247 0.039998 0.000979986 0.03541 0.090421 -0.00747301 0.035596 0.0915 -0.00674901 -0.0145526 0.0704231 -0.212954 -0.012418 0.071588 -0.214274 -0.015534 0.07106700000000001 -0.210269 -0.037904 0.118998 -0.252736 -0.037982 0.12146 -0.248769 -0.036966 0.102998 -0.258815 -0.066376 0.081721 -0.179787 -0.066635 0.08205900000000001 -0.181875 -0.058697 0.07023500000000001 -0.180422 -0.047993 0.126464 -0.17232 -0.049958 0.126383 -0.187824 -0.058413 0.119945 -0.185262 -0.0335092 0.102998 -0.24076 -0.0337375 0.117198 -0.241686 -0.034747 0.102998 -0.245782 -0.032318 0.137998 0.013442 -0.03489 0.137998 0.00279898 -0.034887 0.098269 0.00279799 -0.028807 0.131398 -0.230119 -0.0307675 0.117198 -0.233855 -0.0303241 0.102998 -0.23301 -0.023523 0.064305 -0.197932 -0.022563 0.065247 -0.201419 -0.017073 0.070427 -0.205294 -0.058648 0.118944 -0.171066 -0.0588453 0.119509 -0.182979 -0.059219 0.119502 -0.181032 -0.057231 0.049998 -0.190235 -0.047047 0.049998 -0.178417 -0.052157 0.049998 -0.181269 -0.024351 0.063566 -0.195196 -0.021233 0.0636 -0.183487 -0.025697 0.062902 -0.19274 -0.005196 0.102998 -0.215389 -0.00365891 0.0991905 -0.215317 -0.00240399 0.102998 -0.215293 0.033206 0.137998 0.014953 0.031112 0.137998 0.019976 0.031112 0.039998 0.019976 -0.0337375 0.060498 -0.241686 -0.034747 0.057998 -0.245782 -0.032728 0.057998 -0.23759 -0.038299 0.121013 -0.051695 -0.056918 0.108547 -0.108453 -0.045698 0.108799 -0.050092 -0.07356699999999999 0.07099800000000001 -0.182532 -0.060239 0.07099800000000001 -0.194583 -0.059517 0.07099800000000001 -0.181201 -0.023212 0.131398 -0.276199 -0.028807 0.131398 -0.269883 -0.008378999999999999 0.131398 -0.283984 -0.042263 0.117494 -0.250094 -0.037626 0.117517 -0.254781 -0.037904 0.118998 -0.252736 -0.045891 0.126901 -0.157101 -0.043659 0.127535 -0.142076 -0.030429 0.13079 -0.144536 -0.022773 0.062583 -0.026579 -0.01672 0.061015 -0.030618 -0.013446 0.039998 -0.032316 -0.026582 0.137998 0.02277 -0.026582 0.039998 0.022771 -0.020283 0.137998 0.028524 -0.035603 0.049998 -0.179336 -0.041233 0.049998 -0.177738 -0.057231 0.049998 -0.190235 -0.037982 0.12146 -0.248769 -0.037778 0.122727 -0.246416 -0.042263 0.117494 -0.250094 -0.013114 0.108058 -0.201814 -0.011416 0.095416 -0.197055 -0.012348 0.09540999999999999 -0.20183 -0.030235 0.12028 -0.017474 -0.029834 0.120931 -0.018209 -0.031887 0.120562 -0.023395 0.028802 0.131398 -0.230119 0.032723 0.057998 -0.23759 0.032723 0.131398 -0.23759 -0.010009 0.07188899999999999 -0.216485 -0.00812 0.074265 -0.215957 -0.0090645 0.0746965 -0.215135 -0.066376 0.081721 -0.179787 -0.06689290000000001 0.08831550000000001 -0.170419 -0.068189 0.094998 -0.170106 0.035752 0.093403 -0.00599601 0.035786 0.094414 -0.00581501 0.036247 0.039998 0.000979986 0.025389 0.079096 -0.056714 0.021022 0.071631 -0.055785 0.021367 0.07895099999999999 -0.07337299999999999 -0.05443 0.07099800000000001 -0.227973 -0.068758 0.07099800000000001 -0.233304 -0.052737 0.07099800000000001 -0.231787 -0.037778 0.122727 -0.246416 -0.037626 0.123668 -0.244667 -0.035081 0.127396 -0.235407 0.01049 0.08722149999999999 -0.12288 0.012103 0.095511 -0.123116 0.012978 0.078932 -0.106368 -0.034101 0.061824 -0.180269 -0.031735 0.06163 -0.165798 -0.035656 0.061843 -0.17945 -0.026582 0.039998 0.022771 -0.020283 0.039998 0.028524 -0.020283 0.137998 0.028524 -0.0189548 0.102998 -0.220865 -0.023212 0.102998 -0.223803 -0.0216408 0.102998 -0.221424 -0.00891 0.107254 -0.21306 -0.008815999999999999 0.10605 -0.213038 -0.008725 0.09539 -0.21254 -0.00240399 0.102998 -0.215293 0.008373 0.057998 -0.216018 -1.99507e-06 0.131398 -0.215001 -0.0243759 0.102998 -0.225117 -0.0249051 0.102998 -0.225714 -0.028859 0.102998 -0.225278 0.00116802 0.137998 0.036003 -0.009214989999999999 0.039998 0.034258 0.00116801 0.039998 0.036003 -0.034356 0.071198 -0.0271 -0.022773 0.062583 -0.026579 -0.030053 0.070437 -0.017043 -0.023212 0.057998 -0.223803 -0.0246108 0.062998 -0.225382 -0.0260095 0.062998 -0.226961 -0.0423461 0.119877 -0.245385 -0.040037 0.124841 -0.23872 -0.0439799 0.120915 -0.241308 -0.013229 0.075809 -0.19835 -0.012684 0.069286 -0.184201 -0.016665 0.06974900000000001 -0.198437 -0.036282 0.049998 -0.22272 -0.038987 0.062292 -0.223391 -0.036328 0.062118 -0.222573 -0.029873 0.039998 -0.018243 -0.022774 0.039998 -0.02658 0.024691 0.039998 -0.024464 -0.037185 0.065271 -0.242165 -0.033834 0.067998 -0.232697 -0.034819 0.062778 -0.23491 -0.0203629 0.101282 -0.278166 -0.023212 0.0986773 -0.276199 -0.0235251 0.0995163 -0.275846 -0.013388 0.060519 -0.03217 -0.028074 0.06254899999999999 -0.045339 -0.00653799 0.060086 -0.034225 -0.07356699999999999 0.07099800000000001 -0.182532 -0.068758 0.07099800000000001 -0.233304 -0.05443 0.07099800000000001 -0.227973 -0.008803 0.095419 -0.18977 -0.011416 0.095416 -0.197055 -0.009605000000000001 0.108348 -0.189741 0.008115010000000001 0.039998 -0.034047 -0.00281699 0.060073 -0.034888 0.00358101 0.060637 -0.034817 -0.043659 0.127535 -0.142076 -0.054701 0.119633 -0.140021 -0.038544 0.128686 -0.112365 0.012177 0.137998 0.0342 0.00667501 0.039998 0.035572 0.012176 0.039998 0.0342 -0.0189548 0.102998 -0.220865 -0.019807 0.102998 -0.21757 -0.0180375 0.102998 -0.219217 -0.047993 0.126464 -0.17232 -0.032859 0.130041 -0.159176 -0.035318 0.129524 -0.173813 -0.032728 0.102998 -0.23759 -0.032728 0.131398 -0.23759 -0.0335092 0.102998 -0.24076 -0.028807 0.131398 -0.230119 -0.0260095 0.117198 -0.226961 -0.023212 0.131398 -0.223803 0.008374009999999999 0.131398 -0.216018 -0.008378999999999999 0.131398 -0.283984 -1.99507e-06 0.131398 -0.215001 -0.023212 0.067998 -0.223803 -0.023212 0.057998 -0.223803 -0.022266 0.067998 -0.22315 -0.00468 0.07505100000000001 -0.169678 -0.008943 0.068842 -0.169065 -0.008795000000000001 0.075515 -0.184517 0.012978 0.078932 -0.106368 0.016863 0.071426 -0.07238600000000001 0.008484 0.07136099999999999 -0.105372 -0.051439 0.066625 -0.221282 -0.044033 0.049998 -0.223626 -0.051541 0.049998 -0.221496 -0.037903 0.12941 -0.1884 -0.049958 0.126383 -0.187824 -0.035318 0.129524 -0.173813 -0.032728 0.067998 -0.23759 -0.0332327 0.062998 -0.239638 -0.032728 0.057998 -0.23759 -0.018004 0.062998 -0.220208 -0.01974 0.062998 -0.221406 -0.016268 0.057998 -0.21901 -0.040037 0.124841 -0.23872 -0.037126 0.124813 -0.24216 -0.042263 0.117494 -0.250094 -0.00212134 0.0981031 -0.215258 -0.00365891 0.0991905 -0.215317 -0.004855 0.095383 -0.215339 -0.06519 0.094998 -0.142662 -0.060132 0.08210099999999999 -0.125616 -0.062363 0.094998 -0.125247 -0.067271 0.106211 -0.181936 -0.066541 0.1079 -0.181867 -0.07356699999999999 0.118998 -0.182532 -0.06192 0.118998 -0.181429 -0.065009 0.111448 -0.181721 -0.061919 0.116225 -0.181428 -0.051541 0.049998 -0.221496 -0.057231 0.049998 -0.190235 -0.057662 0.049998 -0.216656 -0.056819 0.119225 -0.155361 -0.045891 0.126901 -0.157101 -0.058648 0.118944 -0.171066 -0.022363 0.127685 -0.17534 -0.019536 0.128174 -0.161298 -0.00780799 0.12149 -0.163167 -0.034747 0.067998 -0.250643 -0.036481 0.067998 -0.249142 -0.034747 0.0692173 -0.252549 -0.0662321 0.0849767 -0.170419 -0.066376 0.081721 -0.179787 -0.064813 0.081788 -0.16105 -0.037155 0.128008 -0.229005 -0.044275 0.124806 -0.232674 -0.044452 0.126287 -0.226534 -0.021795 0.094998 -0.277775 -0.025963 0.094998 -0.2751 -0.028332 0.102997 -0.27231 -0.0331411 0.07301580000000001 -0.260736 -0.0330232 0.07311429999999999 -0.261214 -0.032728 0.057998 -0.262412 0.036247 0.137998 0.0009799819999999999 0.036177 0.039998 0.00428799 0.036247 0.039998 0.000979986 -0.046949 0.107107 -0.253978 -0.040674 0.10718 -0.260584 -0.045625 0.094998 -0.258458 0.023207 0.057998 -0.276199 -2.99964e-06 0.0579979 -0.285001 0.016263 0.057998 -0.280992 0.016263 0.131398 -0.280992 0.023207 0.057998 -0.276199 0.016263 0.057998 -0.280992 -0.010797 0.115038 -0.189686 -0.005313 0.108449 -0.177352 -0.009605000000000001 0.108348 -0.189741 -0.034039 0.106035 -0.26681 -0.033653 0.094998 -0.269585 -0.032964 0.102998 -0.268909 -0.009214989999999999 0.039998 0.034258 0.00116802 0.137998 0.036003 -0.008135979999999999 0.137998 0.034439 0.03148 0.079376 -0.016907 0.032223 0.082122 -0.02238 0.031876 0.080175 -0.016158 -0.01974 0.062998 -0.221406 -0.018004 0.062998 -0.220208 -0.016268 0.067998 -0.21901 0.032223 0.082122 -0.02238 0.034349 0.095469 -0.02239 0.035788 0.09544 -0.00580301 0.012978 0.078932 -0.106368 0.020761 0.09553200000000001 -0.090212 0.0188977 0.087232 -0.0903089 -0.0423461 0.119877 -0.245385 -0.051972 0.11736 -0.23662 -0.0544271 0.119498 -0.232738 0.031539 0.110116 -0.019935 0.025371 0.117444 -0.034582 0.027101 0.116799 -0.022508 0.005089 0.08015600000000001 -0.138659 0.012978 0.078932 -0.106368 0.008484 0.07136099999999999 -0.105372 -0.026485 0.062779 -0.215759 -0.029515 0.062234 -0.218869 -0.022509 0.06329799999999999 -0.219383 -0.008725 0.09539 -0.21254 -0.005196 0.102998 -0.215389 -0.006925 0.102998 -0.214239 0.034981 0.039998 0.010695 0.036177 0.137998 0.00428798 0.034981 0.137998 0.010695 -0.0337375 0.06550690000000001 -0.258316 -0.0337375 0.0617524 -0.258316 -0.034747 0.057998 -0.25422 0.008373 0.057998 -0.216018 -0.00212134 0.0981031 -0.215258 -0.00212157 0.08560189999999999 -0.215258 -0.0282288 0.102997 -0.270536 -0.030964 0.102997 -0.270424 -0.028807 0.102997 -0.269883 -0.027636 0.062453 -0.190236 -0.028339 0.062313 -0.188136 -0.02816 0.049998 -0.188077 0.016263 0.131398 -0.21901 -0.008378999999999999 0.131398 -0.283984 0.008374009999999999 0.131398 -0.216018 -0.035603 0.049998 -0.179336 -0.057231 0.049998 -0.190235 -0.031012 0.049998 -0.182966 -0.0337375 0.06550690000000001 -0.258316 -0.0333971 0.067998 -0.259697 -0.032728 0.057998 -0.262412 -0.029873 0.039998 -0.018243 -0.03323 0.07566299999999999 -0.010959 -0.030053 0.070437 -0.017043 -0.049463 0.094998 -0.056063 -0.054764 0.094998 -0.083718 -0.047727 0.082469 -0.058234 -0.005196 0.102998 -0.215389 -0.0041905 0.117198 -0.21551 -0.008378999999999999 0.102998 -0.216018 -0.032728 0.131398 -0.262412 -0.0307675 0.117198 -0.266147 -0.0312109 0.102998 -0.265303 -0.028807 0.102997 -0.269883 -0.030964 0.102997 -0.270424 -0.0305964 0.102997 -0.269722 -0.057662 0.049998 -0.216656 -0.056496 0.069824 -0.217583 -0.053931 0.068025 -0.219959 -0.024362 0.063959 -0.21226 -0.025205 0.06349100000000001 -0.213649 -0.015534 0.07106700000000001 -0.210269 -0.052437 0.107055 -0.246859 -0.046949 0.107107 -0.253978 -0.049442 0.094998 -0.254344 -0.03323 0.07566299999999999 -0.010959 -0.036206 0.081192 -0.010436 -0.030053 0.070437 -0.017043 -0.056871 0.076153 -0.232179 -0.068758 0.07099800000000001 -0.233304 -0.059887 0.08204 -0.232464 -0.00365891 0.0991905 -0.215317 -0.005196 0.102998 -0.215389 -0.004855 0.095383 -0.215339 0.032223 0.082122 -0.02238 0.029473 0.076419 -0.019718 0.029164 0.076123 -0.021844 -0.006972 0.09542399999999999 -0.184465 -0.004483 0.095432 -0.177054 -0.007637 0.082319 -0.18461 -0.038987 0.062292 -0.223391 -0.041496 0.06280570000000001 -0.225134 -0.041227 0.062847 -0.226878 -0.058675 0.08124099999999999 -0.234455 -0.059887 0.08204 -0.232464 -0.061707 0.088404 -0.232637 -0.024636 0.067998 -0.221068 -0.0204416 0.067998 -0.221891 -0.0196111 0.067998 -0.221317 0.035016 0.08812399999999999 -0.009014019999999999 0.035402 0.039998 -0.00747301 0.033572 0.08360099999999999 -0.012943 -0.008815999999999999 0.102998 -0.213038 -0.008725 0.09539 -0.21254 -0.006925 0.102998 -0.214239 -0.0260095 0.115038 -0.273041 -0.028807 0.131398 -0.269883 -0.023212 0.131398 -0.276199 0.008237009999999999 0.061996 -0.053063 0.011027 0.065356 -0.071107 0.015328 0.06553 -0.054574 -0.032237 0.061986 -0.222914 -0.0367172 0.0626169 -0.228912 -0.034819 0.062778 -0.23491 -0.035803 0.108542 -0.00859101 -0.034828 0.094998 0.00348899 -0.034887 0.098269 0.00279799 -0.062692 0.08193499999999999 -0.143086 -0.057094 0.07038999999999999 -0.162155 -0.05547 0.07073400000000001 -0.144385 -0.028074 0.06254899999999999 -0.045339 -0.039228 0.072168 -0.042965 -0.031196 0.062566 -0.061855 -0.031887 0.120562 -0.023395 -0.029834 0.120931 -0.018209 -0.023427 0.127181 -0.025713 -0.027205 0.049998 -0.190725 -0.023403 0.049998 -0.197539 -0.023523 0.064305 -0.197932 -0.0049804 0.088686 -0.177374 -0.00516071 0.085313 -0.177317 -0.007637 0.082319 -0.18461 -0.036116 0.111791 -0.261823 -0.036966 0.102998 -0.258815 -0.032964 0.102998 -0.268909 0.025389 0.079096 -0.056714 0.029084 0.08015 -0.039744 0.025148 0.073194 -0.03896 -0.046949 0.107107 -0.253978 -0.047488 0.117421 -0.24361 -0.042263 0.117494 -0.250094 -0.057071 0.107012 -0.239238 -0.051972 0.11736 -0.23662 -0.052437 0.107055 -0.246859 0.035508 0.099208 -0.00713901 0.0357 0.09740500000000001 -0.006256 0.031539 0.110116 -0.019935 -0.057071 0.107012 -0.239238 -0.061713 0.101573 -0.232638 -0.059939 0.107883 -0.232469 0.007499 0.095485 -0.139004 0.012103 0.095511 -0.123116 0.005089 0.08015600000000001 -0.138659 -0.043563 0.080983 -0.256573 -0.03345 0.080718 -0.265711 -0.0385065 0.0764526 -0.256684 -0.0357192 0.102998 -0.253002 -0.034747 0.102998 -0.25422 -0.036966 0.102998 -0.258815 -0.032237 0.061986 -0.222914 -0.041227 0.062847 -0.226878 -0.0367172 0.0626169 -0.228912 -0.025205 0.06349100000000001 -0.213649 -0.026485 0.062779 -0.215759 -0.022509 0.06329799999999999 -0.219383 -0.036282 0.049998 -0.22272 -0.044032 0.06316099999999999 -0.223615 -0.038987 0.062292 -0.223391 -0.028339 0.062313 -0.188136 -0.029147 0.062151 -0.185728 -0.02816 0.049998 -0.188077 0.034742 0.131398 -0.245782 -0.008378999999999999 0.131398 -0.283984 0.032723 0.131398 -0.23759 -0.005627 0.08337899999999999 -0.215459 -0.0028281 0.0782692 -0.215344 -0.00212157 0.08560189999999999 -0.215258 0.008115010000000001 0.039998 -0.034047 0.008041009999999999 0.06154 -0.033737 0.018239 0.039998 -0.029872 -0.034747 0.102998 -0.245782 -0.034747 0.131398 -0.245782 -0.034747 0.102998 -0.247212 -0.07356699999999999 0.07099800000000001 -0.182532 -0.062369 0.07099800000000001 -0.20209 -0.060239 0.07099800000000001 -0.194583 -0.041251 0.062174 -0.1779 -0.031735 0.06163 -0.165798 -0.042891 0.06232 -0.177697 0.005089 0.08015600000000001 -0.138659 0.01049 0.08722149999999999 -0.12288 0.012978 0.078932 -0.106368 -0.03345 0.080718 -0.265711 -0.033653 0.094998 -0.269585 -0.029842 0.080358 -0.268227 -0.031735 0.06163 -0.165798 -0.041251 0.062174 -0.1779 -0.038327 0.061912 -0.178263 -0.061707 0.088404 -0.232637 -0.068758 0.07099800000000001 -0.233304 -0.06231 0.094998 -0.232694 -0.031735 0.06163 -0.165798 -0.034101 0.061824 -0.180269 -0.021233 0.0636 -0.183487 0.00173001 0.072867 -0.137987 -0.003516 0.066757 -0.136938 -0.0014 0.074006 -0.1541 -0.024835 0.062582 -0.221237 -0.032237 0.061986 -0.222914 -0.027767 0.062132 -0.224056 0.019976 0.067373 -0.037929 0.022974 0.06915499999999999 -0.026468 0.020278 0.06684 -0.028527 -0.019807 0.102998 -0.21757 -0.025378 0.127937 -0.221716 -0.022862 0.12675 -0.219763 -0.052093 0.08112999999999999 -0.246067 -0.043563 0.080983 -0.256573 -0.037131 0.06919599999999999 -0.250607 -0.037126 0.124813 -0.24216 -0.037626 0.123668 -0.244667 -0.042263 0.117494 -0.250094 0.0134718 0.126915 -0.032658 0.00811601 0.137998 -0.034047 0.018147 0.12471 -0.029694 -0.060132 0.08210099999999999 -0.125616 -0.054037 0.08229 -0.091492 -0.0582432 0.0883525 -0.108554 -0.046949 0.107107 -0.253978 -0.042263 0.117494 -0.250094 -0.037626 0.117517 -0.254781 0.031112 0.137998 0.019976 0.027792 0.039998 0.024268 0.031112 0.039998 0.019976 0.011027 0.065356 -0.071107 0.008237009999999999 0.061996 -0.053063 0.00428401 0.062021 -0.069631 0.020278 0.06684 -0.028527 0.020278 0.039998 -0.028527 0.018239 0.039998 -0.029872 -0.033607 0.112586 -0.00902201 -0.03489 0.137998 0.00279898 -0.034048 0.137998 -0.008119019999999999 -0.033234 0.07478029999999999 -0.260359 -0.0337503 0.0725065 -0.258264 -0.037131 0.06919599999999999 -0.250607 -0.016268 0.131398 -0.21901 -0.01974 0.117198 -0.221406 -0.0189548 0.102998 -0.220865 0.032223 0.082122 -0.02238 0.035752 0.093403 -0.00599601 0.035596 0.0915 -0.00674901 -0.036911 0.114414 -0.258801 -0.037261 0.115569 -0.257471 -0.040674 0.10718 -0.260584 -0.028807 0.131398 -0.269883 -0.0260095 0.115038 -0.273041 -0.0266445 0.102997 -0.272324 -0.024783 0.102997 -0.274717 -0.0217294 0.102997 -0.277222 -0.0235251 0.0995163 -0.275846 -0.03788 0.102998 -0.246961 -0.0349329 0.102998 -0.241309 -0.034747 0.102998 -0.245782 -0.055771 0.069714 -0.220433 -0.052737 0.07099800000000001 -0.231787 -0.051395 0.069561 -0.231297 -0.0280447 0.067998 -0.229259 -0.028807 0.067998 -0.230119 -0.028807 0.057998 -0.230119 -0.033834 0.067998 -0.232697 -0.028807 0.067998 -0.230119 -0.0271378 0.067998 -0.226882 -0.062369 0.07099800000000001 -0.20209 -0.062369 0.049998 -0.20209 -0.060239 0.049998 -0.194583 -0.026582 0.137998 0.02277 -0.032318 0.137998 0.013442 -0.032318 0.039998 0.013443 0.034742 0.131398 -0.25422 0.032723 0.131398 -0.262412 -0.008378999999999999 0.131398 -0.283984 -0.009834000000000001 0.077057 -0.213119 -0.00812 0.074265 -0.215957 -0.006693 0.077352 -0.215648 -0.017449 0.120256 -0.202053 -0.014048 0.114524 -0.201854 -0.01521 0.119156 -0.211406 0.028802 0.131398 -0.230119 0.028802 0.057998 -0.230119 0.032723 0.057998 -0.23759 -0.066376 0.081721 -0.179787 -0.068483 0.088411 -0.18205 -0.066635 0.08205900000000001 -0.181875 -0.008378999999999999 0.131398 -0.283984 0.028802 0.131398 -0.230119 0.032723 0.131398 -0.23759 -0.038987 0.062292 -0.223391 -0.041227 0.062847 -0.226878 -0.036328 0.062118 -0.222573 -0.002018 0.095441 -0.169715 -0.003025 0.08194 -0.169916 -0.004483 0.095432 -0.177054 0.024691 0.137998 -0.024464 0.025406 0.118766 -0.024322 0.022954 0.121125 -0.026485 -0.005313 0.108449 -0.177352 -0.002018 0.095441 -0.169715 -0.004483 0.095432 -0.177054 -0.008795000000000001 0.075515 -0.184517 -0.013229 0.075809 -0.19835 -0.012316 0.08247400000000001 -0.198331 0.00154202 0.131335 -0.060324 0.020104 0.123114 -0.033553 0.01403 0.12392 -0.063029 -0.051439 0.066625 -0.221282 -0.053931 0.068025 -0.219959 -0.051395 0.069561 -0.231297 -2.99964e-06 0.0579979 -0.285001 -0.016268 0.057998 -0.280992 -0.008378999999999999 0.057998 -0.283984 -0.047715 0.06462900000000001 -0.222981 -0.051439 0.066625 -0.221282 -0.051395 0.069561 -0.231297 -0.040037 0.124841 -0.23872 -0.037155 0.128008 -0.229005 -0.032823 0.128474 -0.230849 -0.00516071 0.085313 -0.177317 -0.003025 0.08194 -0.169916 -0.007637 0.082319 -0.18461 0.034349 0.095469 -0.02239 0.033541 0.095485 -0.031703 0.031539 0.110116 -0.019935 -0.037626 0.117517 -0.254781 -0.037261 0.115569 -0.257471 -0.040674 0.10718 -0.260584 0.022974 0.06915499999999999 -0.026468 0.024691 0.039998 -0.024464 0.020278 0.06684 -0.028527 -0.00370299 0.062147 -0.102663 -0.0137 0.060008 -0.065689 -0.020843 0.060114 -0.098861 -0.039228 0.072168 -0.042965 -0.044547 0.08257 -0.041831 -0.042229 0.071954 -0.059438 -0.031908 0.128859 -0.223879 -0.044452 0.126287 -0.226534 -0.035565 0.128969 -0.217398 -0.0253768 0.102998 -0.226247 -0.028807 0.102998 -0.230119 -0.028859 0.102998 -0.225278 -0.057231 0.049998 -0.190235 -0.027205 0.049998 -0.190725 -0.02816 0.049998 -0.188077 -0.005196 0.102998 -0.215389 -0.00240399 0.102998 -0.215293 -0.0041905 0.117198 -0.21551 -0.031908 0.128859 -0.223879 -0.035565 0.128969 -0.217398 -0.021122 0.12593 -0.218412 -0.03788 0.102998 -0.246961 -0.037982 0.12146 -0.248769 -0.037778 0.122727 -0.246416 -0.019536 0.128174 -0.161298 -0.00501499 0.122031 -0.149263 -0.00780799 0.12149 -0.163167 -0.029834 0.120931 -0.018209 -0.034048 0.137998 -0.008119019999999999 -0.029873 0.137998 -0.018243 -0.056819 0.119225 -0.155361 -0.06411 0.10808 -0.1542 -0.054701 0.119633 -0.140021 -0.022563 0.065247 -0.201419 -0.02251 0.06550499999999999 -0.20529 -0.017073 0.070427 -0.205294 -0.028807 0.131398 -0.269883 -0.0282288 0.102997 -0.270536 -0.028807 0.102997 -0.269883 -0.01521 0.119156 -0.211406 -0.014048 0.114524 -0.201854 -0.012303 0.113728 -0.210533 -0.00614141 0.07561610000000001 -0.215678 -0.00415147 0.0748472 -0.215505 -0.006693 0.077352 -0.215648 -0.03788 0.102998 -0.246961 -0.034747 0.102998 -0.245782 -0.034747 0.102998 -0.247212 -0.037185 0.065271 -0.242165 -0.035583 0.06309099999999999 -0.23666 -0.045077 0.06940499999999999 -0.241524 0.008041009999999999 0.06154 -0.033737 0.010685 0.062075 -0.033096 0.018239 0.039998 -0.029872 -0.0204416 0.067998 -0.221891 -0.01974 0.062998 -0.221406 -0.0196111 0.067998 -0.221317 -0.009834000000000001 0.077057 -0.213119 -0.006693 0.077352 -0.215648 -0.009162 0.08319500000000001 -0.212779 -0.016665 0.06974900000000001 -0.198437 -0.024351 0.063566 -0.195196 -0.023523 0.064305 -0.197932 -0.048222 0.07156700000000001 -0.09278500000000001 -0.042229 0.071954 -0.059438 -0.047727 0.082469 -0.058234 -0.013414 0.13189 -0.032243 -0.012814 0.13337 -0.057215 -0.023427 0.127181 -0.025713 -0.0332327 0.062998 -0.239638 -0.0337375 0.062998 -0.241686 -0.032728 0.057998 -0.23759 -0.014708 0.120982 -0.189504 -0.025578 0.127553 -0.188988 -0.010933 0.121115 -0.176687 -0.025697 0.062902 -0.19274 -0.027636 0.062453 -0.190236 -0.027205 0.049998 -0.190725 -0.051972 0.11736 -0.23662 -0.054278 0.117226 -0.231933 -0.0544271 0.119498 -0.232738 -0.00281699 0.060073 -0.034888 -0.010127 0.060008 -0.049157 0.00358101 0.060637 -0.034817 0.035402 0.039998 -0.00747301 0.024691 0.039998 -0.024464 0.033809 0.039998 -0.012393 -0.0246108 0.062998 -0.225382 -0.023212 0.057998 -0.223803 -0.023212 0.067998 -0.223803 -0.044547 0.08257 -0.041831 -0.049463 0.094998 -0.056063 -0.047727 0.082469 -0.058234 -0.038989 0.129258 -0.203352 -0.035565 0.128969 -0.217398 -0.046622 0.126471 -0.220648 -0.0119847 0.102998 -0.217043 -0.012538 0.102998 -0.217595 -0.0120057 0.102998 -0.216492 -0.06579 0.107966 -0.170226 -0.067271 0.106211 -0.181936 -0.06864199999999999 0.100682 -0.182065 -0.060132 0.08210099999999999 -0.125616 -0.062692 0.08193499999999999 -0.143086 -0.05547 0.07073400000000001 -0.144385 -0.048222 0.07156700000000001 -0.09278500000000001 -0.03735 0.06260599999999999 -0.09519900000000001 -0.042229 0.071954 -0.059438 -0.054341 0.094998 -0.247534 -0.052437 0.107055 -0.246859 -0.049442 0.094998 -0.254344 -0.0260095 0.117198 -0.226961 -0.0253768 0.102998 -0.226247 -0.023212 0.131398 -0.223803 -0.024551 0.126404 -0.21416 -0.035565 0.128969 -0.217398 -0.027461 0.127109 -0.202655 -0.0297872 0.062998 -0.231987 -0.028807 0.067998 -0.230119 -0.0307675 0.062998 -0.233855 -0.033653 0.094998 -0.269585 -0.032964 0.102998 -0.268909 -0.028931 0.094998 -0.27299 -0.032728 0.067998 -0.23759 -0.0337375 0.062998 -0.241686 -0.0332327 0.062998 -0.239638 -0.032964 0.102998 -0.268909 -0.0312109 0.102998 -0.265303 -0.0291896 0.102998 -0.269154 -0.056496 0.069824 -0.217583 -0.058172 0.07099800000000001 -0.216032 -0.055771 0.069714 -0.220433 -0.040674 0.10718 -0.260584 -0.036116 0.111791 -0.261823 -0.0370101 0.109485 -0.262435 -0.021233 0.0636 -0.183487 -0.034101 0.061824 -0.180269 -0.031983 0.061887 -0.18193 -0.032728 0.067998 -0.23759 -0.0341418 0.067998 -0.239829 -0.0344719 0.067998 -0.244666 -0.0189327 0.067998 -0.219552 -0.0196111 0.067998 -0.221317 -0.016268 0.067998 -0.21901 -0.050569 0.06436799999999999 -0.180088 -0.052157 0.049998 -0.181269 -0.047357 0.0631 -0.178521 -0.037131 0.06919599999999999 -0.250607 -0.034747 0.0703906 -0.25422 -0.034747 0.0694588 -0.252902 -0.047487 0.124698 -0.226704 -0.0497035 0.123371 -0.227009 -0.046622 0.126471 -0.220648 0.002578 0.065321 -0.104062 0.011027 0.065356 -0.071107 0.00428401 0.062021 -0.069631 -0.000383994 0.116163 -0.150124 0.009158009999999999 0.110451 -0.122524 0.002111 0.10942 -0.150588 -0.037982 0.12146 -0.248769 -0.03788 0.102998 -0.246961 -0.036966 0.102998 -0.258815 0.020104 0.123114 -0.033553 0.0134718 0.126915 -0.032658 0.018147 0.12471 -0.029694 -0.0299961 0.102998 -0.230342 -0.028807 0.102998 -0.230119 -0.0303241 0.102998 -0.23301 -0.00279198 0.132618 -0.034791 0.00154202 0.131335 -0.060324 -0.013414 0.13189 -0.032243 -0.008378999999999999 0.057998 -0.216018 -0.0123235 0.0659771 -0.217514 -0.0123235 0.0619875 -0.217514 -0.0260095 0.115038 -0.273041 -0.023212 0.131398 -0.276199 -0.0217294 0.102997 -0.277222 -0.0307674 0.060498 -0.233855 -0.032728 0.057998 -0.23759 -0.028807 0.057998 -0.230119 0.00173001 0.072867 -0.137987 0.001094 0.08108700000000001 -0.154548 0.005089 0.08015600000000001 -0.138659 -0.0123235 0.0659771 -0.217514 -0.016268 0.057998 -0.21901 -0.0123235 0.0619875 -0.217514 0.029084 0.08015 -0.039744 0.032223 0.082122 -0.02238 0.029164 0.076123 -0.021844 -0.023212 0.057998 -0.276199 -2.99964e-06 0.0579979 -0.285001 -0.028807 0.057998 -0.269883 0.033541 0.095485 -0.031703 0.032223 0.082122 -0.02238 0.0320145 0.08767129999999999 -0.031062 -0.06689290000000001 0.08831550000000001 -0.170419 -0.066376 0.081721 -0.179787 -0.0662321 0.0849767 -0.170419 -0.040037 0.124841 -0.23872 -0.044275 0.124806 -0.232674 -0.037155 0.128008 -0.229005 -0.013446 0.039998 -0.032316 -0.00280299 0.039998 -0.034889 0.024691 0.039998 -0.024464 0.029418 0.110682 -0.035372 0.025371 0.117444 -0.034582 0.031539 0.110116 -0.019935 -0.0330232 0.07311429999999999 -0.261214 -0.032728 0.0763397 -0.262412 -0.032728 0.057998 -0.262412 -0.033834 0.067998 -0.232697 -0.0304037 0.0679979 -0.233161 -0.0301314 0.067998 -0.232642 0.009158009999999999 0.110451 -0.122524 0.020761 0.09553200000000001 -0.090212 0.01636 0.09552099999999999 -0.106937 -0.034747 0.131398 -0.245782 -0.034747 0.102998 -0.249047 -0.034747 0.102998 -0.247697 0.03541 0.090421 -0.00747301 0.032223 0.082122 -0.02238 0.035596 0.0915 -0.00674901 -0.00891 0.107254 -0.21306 -0.012303 0.113728 -0.210533 -0.011532 0.107588 -0.210271 -0.034325 0.067998 -0.255932 -0.0337375 0.06550690000000001 -0.258316 -0.034747 0.057998 -0.25422 -0.052093 0.08112999999999999 -0.246067 -0.054341 0.094998 -0.247534 -0.049442 0.094998 -0.254344 -0.019807 0.102998 -0.21757 -0.012538 0.102998 -0.217595 -0.0144225 0.102998 -0.21831 0.01403 0.12392 -0.063029 0.00071001 0.123015 -0.120724 -0.011323 0.130169 -0.118162 0.00568601 0.117233 -0.121784 0.023357 0.111167 -0.065049 0.009158009999999999 0.110451 -0.122524 -0.024551 0.126404 -0.21416 -0.01521 0.119156 -0.211406 -0.013038 0.118998 -0.214307 -0.026806 0.129703 -0.054184 -0.031887 0.120562 -0.023395 -0.023427 0.127181 -0.025713 -0.019536 0.128174 -0.161298 -0.022363 0.127685 -0.17534 -0.035318 0.129524 -0.173813 0.029418 0.110682 -0.035372 0.029163 0.09553 -0.05552 0.023357 0.111167 -0.065049 0.028802 0.131398 -0.269883 0.032723 0.131398 -0.262412 0.032723 0.057998 -0.262412 -0.055771 0.069714 -0.220433 -0.058172 0.07099800000000001 -0.216032 -0.056939 0.07099800000000001 -0.220732 -2.99964e-06 0.0579979 -0.285001 -0.023212 0.057998 -0.276199 -0.016268 0.057998 -0.280992 0.008041009999999999 0.06154 -0.033737 0.008115010000000001 0.039998 -0.034047 0.00358101 0.060637 -0.034817 -0.028807 0.102998 -0.230119 -0.028807 0.131398 -0.230119 -0.0303241 0.102998 -0.23301 -0.026849 0.060719 -0.132272 -0.014243 0.063067 -0.151789 -0.01083 0.06265800000000001 -0.135477 -0.024351 0.063566 -0.195196 -0.025697 0.062902 -0.19274 -0.023523 0.064305 -0.197932 -0.03788 0.067998 -0.246961 -0.034747 0.067998 -0.24674 -0.034747 0.067998 -0.245782 -0.032237 0.061986 -0.222914 -0.033143 0.062024 -0.221268 -0.041227 0.062847 -0.226878 -0.012814 0.13337 -0.057215 0.00154202 0.131335 -0.060324 -0.025099 0.132149 -0.115228 -0.034747 0.067998 -0.249231 -0.034747 0.0637284 -0.250001 -0.034747 0.067998 -0.247212 -0.034356 0.071198 -0.0271 -0.036206 0.081192 -0.010436 -0.040722 0.08209 -0.025833 -0.012418 0.071588 -0.214274 -0.013686 0.067998 -0.217787 -0.010793 0.07091600000000001 -0.216706 0.00667102 0.137998 0.035573 0.00116801 0.039998 0.036003 0.00667501 0.039998 0.035572 -0.00675999 0.115159 -0.17718 -0.005313 0.108449 -0.177352 -0.010797 0.115038 -0.189686 -0.042425 0.094998 -0.023232 -0.039489 0.094998 -0.011609 -0.039448 0.108685 -0.021917 -0.03788 0.067998 -0.246961 -0.033834 0.067998 -0.232697 -0.037185 0.065271 -0.242165 -0.0349329 0.102998 -0.241309 -0.0335092 0.102998 -0.24076 -0.034747 0.102998 -0.245782 -0.00415147 0.0748472 -0.215505 -0.0028281 0.0782692 -0.215344 -0.0047623 0.07911310000000001 -0.215472 -0.012343 0.0954 -0.207618 -0.011576 0.095397 -0.209183 -0.011532 0.107588 -0.210271 -0.030235 0.12028 -0.017474 -0.034048 0.137998 -0.008119019999999999 -0.029834 0.120931 -0.018209 -0.019807 0.102998 -0.21757 -0.016268 0.102998 -0.21901 -0.0180375 0.102998 -0.219217 -1.99507e-06 0.131398 -0.215001 -0.008378999999999999 0.131398 -0.283984 -0.008378999999999999 0.131398 -0.216018 -0.029836 0.06207 -0.226616 -0.032237 0.061986 -0.222914 -0.034819 0.062778 -0.23491 -0.034326 0.08115799999999999 -0.00534201 -0.029873 0.039998 -0.018243 -0.034048 0.039998 -0.008119009999999999 0.024691 0.039998 -0.024464 -0.026582 0.039998 0.022771 -0.032318 0.039998 0.013443 -0.039448 0.108685 -0.021917 -0.045698 0.108799 -0.050092 -0.046465 0.094998 -0.04153 -0.034747 0.067998 -0.249231 -0.034747 0.067998 -0.247212 -0.0363135 0.067998 -0.248096 -0.000383994 0.116163 -0.150124 0.002111 0.10942 -0.150588 -0.003402 0.115569 -0.163868 0.036247 0.039998 0.000979986 0.036177 0.039998 0.00428799 0.024691 0.039998 -0.024464 -0.0337375 0.117198 -0.258316 -0.0334227 0.102998 -0.259593 -0.0335584 0.102998 -0.259043 -0.0344719 0.067998 -0.244666 -0.034747 0.067998 -0.245782 -0.034747 0.057998 -0.245782 -0.012418 0.071588 -0.214274 -0.010009 0.07188899999999999 -0.216485 -0.009834000000000001 0.077057 -0.213119 -0.061464 0.049998 -0.209841 -0.061464 0.07099800000000001 -0.209841 -0.058172 0.07099800000000001 -0.216032 -0.014708 0.120982 -0.189504 -0.00675999 0.115159 -0.17718 -0.010797 0.115038 -0.189686 -0.063614 0.07618 -0.181589 -0.059517 0.07099800000000001 -0.181201 -0.058697 0.07023500000000001 -0.180422 0.00667501 0.039998 0.035572 0.024691 0.039998 -0.024464 0.012176 0.039998 0.0342 -0.046622 0.126471 -0.220648 -0.0530965 0.122945 -0.213171 -0.0513867 0.122741 -0.222061 0.00116801 0.039998 0.036003 0.024691 0.039998 -0.024464 0.00667501 0.039998 0.035572 -0.020843 0.060114 -0.098861 -0.026849 0.060719 -0.132272 -0.01083 0.06265800000000001 -0.135477 -0.051395 0.069561 -0.231297 -0.052737 0.07099800000000001 -0.231787 -0.058675 0.08124099999999999 -0.234455 -0.016895 0.128882 -0.147054 -0.00501499 0.122031 -0.149263 -0.019536 0.128174 -0.161298 -0.030964 0.102997 -0.270424 -0.0282288 0.102997 -0.270536 -0.028332 0.102997 -0.27231 -0.039228 0.072168 -0.042965 -0.040722 0.08209 -0.025833 -0.044547 0.08257 -0.041831 -0.0307675 0.062998 -0.233855 -0.032728 0.057998 -0.23759 -0.0307674 0.060498 -0.233855 -0.032728 0.131398 -0.23759 -0.0337375 0.117198 -0.241686 -0.0335092 0.102998 -0.24076 -0.067456 0.094998 -0.160678 -0.064813 0.081788 -0.16105 -0.062692 0.08193499999999999 -0.143086 -0.053559 0.071121 -0.126929 -0.060132 0.08210099999999999 -0.125616 -0.05547 0.07073400000000001 -0.144385 -0.034828 0.094998 0.00348899 -0.03489 0.039998 0.00279899 -0.032318 0.137998 0.013442 -0.051439 0.066625 -0.221282 -0.047715 0.06462900000000001 -0.222981 -0.044033 0.049998 -0.223626 -0.0582432 0.0883525 -0.108554 -0.054037 0.08229 -0.091492 -0.059351 0.094998 -0.107759 0.028802 0.057998 -0.230119 0.023207 0.057998 -0.223803 -2.99964e-06 0.0579979 -0.285001 -0.0319859 0.102998 -0.236176 -0.035087 0.102998 -0.235405 -0.0317456 0.102998 -0.235718 -0.034747 0.131398 -0.25422 -0.0339658 0.102998 -0.25739 -0.034747 0.102998 -0.25422 0.03132 0.111039 -0.017164 0.029564 0.113644 -0.019588 0.031545 0.137998 -0.016125 0.0357 0.09740500000000001 -0.006256 0.036247 0.137998 0.0009799819999999999 0.035788 0.09544 -0.00580301 -0.006972 0.09542399999999999 -0.184465 -0.005313 0.108449 -0.177352 -0.004483 0.095432 -0.177054 0.003933 0.09546499999999999 -0.151245 0.007499 0.095485 -0.139004 0.005089 0.08015600000000001 -0.138659 -0.005627 0.08337899999999999 -0.215459 -0.004855 0.095383 -0.215339 -0.009162 0.08319500000000001 -0.212779 -0.012538 0.102998 -0.217595 -0.0119847 0.102998 -0.217043 -0.0114314 0.102998 -0.217176 -0.024362 0.063959 -0.21226 -0.022834 0.065247 -0.207674 -0.02251 0.06550499999999999 -0.20529 0.034742 0.057998 -0.245782 0.034742 0.057998 -0.25422 0.034742 0.131398 -0.25422 -0.00653584 0.07414800000000001 -0.215794 -2.99582e-06 0.057998 -0.215001 -0.00415147 0.0748472 -0.215505 -0.025205 0.06349100000000001 -0.213649 -0.022509 0.06329799999999999 -0.219383 -0.015534 0.07106700000000001 -0.210269 0.024691 0.039998 -0.024464 0.025455 0.071586 -0.024275 0.031544 0.039998 -0.016125 -0.023212 0.131398 -0.276199 -0.0203629 0.101282 -0.278166 -0.0217294 0.102997 -0.277222 -0.031137 0.061966 -0.183063 -0.035603 0.049998 -0.179336 -0.031012 0.049998 -0.182966 -0.034325 0.067998 -0.255932 -0.0333971 0.067998 -0.259697 -0.0337375 0.06550690000000001 -0.258316 0.036177 0.039998 0.00428799 0.034981 0.039998 0.010695 0.024691 0.039998 -0.024464 -0.057094 0.07038999999999999 -0.162155 -0.064813 0.081788 -0.16105 -0.058697 0.07023500000000001 -0.180422 -0.028859 0.102998 -0.225278 -0.019807 0.102998 -0.21757 -0.0216408 0.102998 -0.221424 -0.033143 0.062024 -0.221268 -0.029515 0.062234 -0.218869 -0.029468 0.049998 -0.218918 -0.028827 0.128679 -0.225307 -0.031908 0.128859 -0.223879 -0.025378 0.127937 -0.221716 -0.000148996 0.095447 -0.16415 -0.001488 0.108845 -0.164172 0.002275 0.095455 -0.156935 -0.034747 0.067998 -0.250643 -0.034747 0.0692173 -0.252549 -0.034747 0.067998 -0.252601 0.010922 0.062035 -0.036126 0.019976 0.067373 -0.037929 0.020278 0.06684 -0.028527 -0.032728 0.102998 -0.262412 -0.0312109 0.102998 -0.265303 -0.0330778 0.102998 -0.263984 -0.0260095 0.117198 -0.226961 -0.028807 0.102998 -0.230119 -0.0253768 0.102998 -0.226247 -0.024835 0.062582 -0.221237 -0.015557 0.067998 -0.215638 -0.022509 0.06329799999999999 -0.219383 -0.036481 0.067998 -0.249142 -0.037131 0.06919599999999999 -0.250607 -0.034747 0.0692173 -0.252549 -0.0214921 0.0925914 -0.277554 -0.0199652 0.0921587 -0.27844 -0.0254514 0.0873768 -0.273671 -0.06864199999999999 0.100682 -0.182065 -0.067271 0.106211 -0.181936 -0.07356699999999999 0.118998 -0.182532 -0.000148996 0.095447 -0.16415 -0.002018 0.095441 -0.169715 -0.001488 0.108845 -0.164172 0.00173001 0.072867 -0.137987 0.005089 0.08015600000000001 -0.138659 0.008484 0.07136099999999999 -0.105372 -0.019773 0.124949 -0.217628 -0.021122 0.12593 -0.218412 -0.024551 0.126404 -0.21416 -0.028931 0.094998 -0.27299 -0.028807 0.0833648 -0.269883 -0.029842 0.080358 -0.268227 -0.056819 0.119225 -0.155361 -0.06579 0.107966 -0.170226 -0.06411 0.10808 -0.1542 -0.03788 0.102998 -0.246961 -0.0357192 0.102998 -0.253002 -0.036966 0.102998 -0.258815 0.033206 0.039998 0.014953 0.034981 0.039998 0.010695 0.034981 0.137998 0.010695 -0.040037 0.124841 -0.23872 -0.032823 0.128474 -0.230849 -0.035081 0.127396 -0.235407 -0.022509 0.06329799999999999 -0.219383 -0.019043 0.065294 -0.217116 -0.015534 0.07106700000000001 -0.210269 -0.025378 0.127937 -0.221716 -0.019807 0.102998 -0.21757 -0.028859 0.102998 -0.225278 -0.052113 0.06517000000000001 -0.181323 -0.058697 0.07023500000000001 -0.180422 -0.052941 0.065599 -0.181985 0.033206 0.039998 0.014953 0.034981 0.137998 0.010695 0.033206 0.137998 0.014953 0.034883 0.102449 -0.00945201 0.035508 0.099208 -0.00713901 0.031539 0.110116 -0.019935 -0.034747 0.067998 -0.249231 -0.036481 0.067998 -0.249142 -0.034747 0.067998 -0.250643 -0.034325 0.067998 -0.255932 -0.034747 0.0703906 -0.25422 -0.0337503 0.0725065 -0.258264 -2.99964e-06 0.0579979 -0.285001 0.023207 0.057998 -0.223803 0.016263 0.057998 -0.21901 -0.050376 0.126442 -0.204039 -0.0547976 0.123013 -0.204317 -0.0570217 0.121279 -0.192606 -0.045077 0.06940499999999999 -0.241524 -0.052093 0.08112999999999999 -0.246067 -0.037131 0.06919599999999999 -0.250607 -0.049668 0.120374 -0.109996 -0.054701 0.119633 -0.140021 -0.062009 0.108246 -0.138661 -0.041233 0.049998 -0.177738 -0.035603 0.049998 -0.179336 -0.035656 0.061843 -0.17945 0.007499 0.095485 -0.139004 0.009158009999999999 0.110451 -0.122524 0.012103 0.095511 -0.123116 -0.0145526 0.0704231 -0.212954 -0.015557 0.067998 -0.215638 -0.012418 0.071588 -0.214274 -0.022497 0.049998 -0.20529 -0.022563 0.065247 -0.201419 -0.023403 0.049998 -0.197539 -0.0291173 0.07068140000000001 -0.269292 -0.028807 0.057998 -0.269883 -0.0293392 0.067998 -0.268869 -0.06411 0.10808 -0.1542 -0.067456 0.094998 -0.160678 -0.06519 0.094998 -0.142662 -0.013686 0.067998 -0.217787 -0.0151932 0.067998 -0.218602 -0.0123235 0.0659771 -0.217514 0.00154202 0.131335 -0.060324 0.008051020000000001 0.129972 -0.033797 0.020104 0.123114 -0.033553 -0.013686 0.067998 -0.217787 -0.016268 0.067998 -0.21901 -0.0151932 0.067998 -0.218602 -0.0307675 0.117198 -0.233855 -0.0319859 0.102998 -0.236176 -0.0317456 0.102998 -0.235718 -0.0271378 0.067998 -0.226882 -0.023212 0.067998 -0.223803 -0.024636 0.067998 -0.221068 -0.037626 0.117517 -0.254781 -0.036911 0.114414 -0.258801 -0.037261 0.115569 -0.257471 -0.062692 0.08193499999999999 -0.143086 -0.064813 0.081788 -0.16105 -0.057094 0.07038999999999999 -0.162155 -0.031983 0.061887 -0.18193 -0.035603 0.049998 -0.179336 -0.031137 0.061966 -0.183063 -0.022834 0.065247 -0.207674 -0.024362 0.063959 -0.21226 -0.015534 0.07106700000000001 -0.210269 -0.042758 0.0669136 -0.23641 -0.051395 0.069561 -0.231297 -0.045077 0.06940499999999999 -0.241524 -0.027461 0.127109 -0.202655 -0.038989 0.129258 -0.203352 -0.025578 0.127553 -0.188988 -0.0203629 0.101282 -0.278166 -0.023212 0.131398 -0.276199 -0.016268 0.131398 -0.280992 -0.034747 0.0637284 -0.250001 -0.034747 0.067998 -0.250643 -0.034747 0.067998 -0.252601 -0.0306243 0.067998 -0.26642 -0.0310716 0.0699446 -0.265568 -0.0294052 0.0795941 -0.268743 -0.0214921 0.0925914 -0.277554 -0.0254514 0.0873768 -0.273671 -0.025963 0.094998 -0.2751 -0.041227 0.062847 -0.226878 -0.044032 0.06316099999999999 -0.223615 -0.051395 0.069561 -0.231297 -0.07356699999999999 0.07099800000000001 -0.182532 -0.068483 0.088411 -0.18205 -0.07356699999999999 0.118998 -0.182532 -0.035455 0.094998 -0.268032 -0.034606 0.107636 -0.265703 -0.034039 0.106035 -0.26681 -0.0497035 0.123371 -0.227009 -0.0500441 0.123165 -0.226155 -0.046622 0.126471 -0.220648 -0.023114 0.062375 -0.02934 -0.022773 0.062583 -0.026579 -0.034356 0.071198 -0.0271 -0.06579 0.107966 -0.170226 -0.056819 0.119225 -0.155361 -0.058648 0.118944 -0.171066 -0.019043 0.065294 -0.217116 -0.015557 0.067998 -0.215638 -0.015534 0.07106700000000001 -0.210269 -0.0182832 0.0924469 -0.279645 -0.0217294 0.0679979 -0.277222 -0.0199652 0.0921587 -0.27844 -0.038989 0.129258 -0.203352 -0.037903 0.12941 -0.1884 -0.025578 0.127553 -0.188988 -0.0301314 0.067998 -0.232642 -0.0304037 0.0679979 -0.233161 -0.0307675 0.062998 -0.233855 0.029418 0.110682 -0.035372 0.033541 0.095485 -0.031703 0.031961 0.095501 -0.040298 -0.041233 0.049998 -0.177738 -0.041251 0.062174 -0.1779 -0.047047 0.049998 -0.178417 0.031539 0.110116 -0.019935 0.03132 0.111039 -0.017164 0.032042 0.109598 -0.01583 -0.024636 0.067998 -0.221068 -0.029836 0.06207 -0.226616 -0.0294847 0.06503399999999999 -0.226685 -0.0331411 0.07301580000000001 -0.260736 -0.032728 0.0763397 -0.262412 -0.0330232 0.07311429999999999 -0.261214 0.028802 0.057998 -0.269883 0.023207 0.057998 -0.276199 0.028802 0.131398 -0.269883 -0.043659 0.127535 -0.142076 -0.025099 0.132149 -0.115228 -0.030429 0.13079 -0.144536 -0.01974 0.117198 -0.221406 -0.023212 0.131398 -0.223803 -0.023212 0.102998 -0.223803 -0.025099 0.132149 -0.115228 -0.011323 0.130169 -0.118162 -0.030429 0.13079 -0.144536 -0.03489 0.039998 0.00279899 -0.034048 0.039998 -0.008119009999999999 0.024691 0.039998 -0.024464 -0.054701 0.119633 -0.140021 -0.06411 0.10808 -0.1542 -0.062009 0.108246 -0.138661 -0.023427 0.127181 -0.025713 -0.029873 0.137998 -0.018243 -0.022774 0.137998 -0.02658 0.028642 0.11501 -0.02086 0.031539 0.110116 -0.019935 0.027101 0.116799 -0.022508 -0.057071 0.107012 -0.239238 -0.054341 0.094998 -0.247534 -0.058828 0.094998 -0.240143 -0.016925 0.122882 -0.215977 -0.019773 0.124949 -0.217628 -0.024551 0.126404 -0.21416 0.023207 0.131398 -0.276199 0.023207 0.057998 -0.276199 0.016263 0.131398 -0.280992 -0.034747 0.067998 -0.24674 -0.03788 0.067998 -0.246961 -0.034747 0.067998 -0.247212 -0.008378999999999999 0.057998 -0.216018 -2.99582e-06 0.057998 -0.215001 -0.00653584 0.07414800000000001 -0.215794 -0.0307675 0.117198 -0.233855 -0.028807 0.131398 -0.230119 -0.032728 0.131398 -0.23759 -0.028807 0.057998 -0.269883 -2.99964e-06 0.0579979 -0.285001 -0.032728 0.057998 -0.262412 0.020278 0.123345 -0.028527 0.024691 0.137998 -0.024464 0.022954 0.121125 -0.026485 -0.063614 0.07618 -0.181589 -0.07356699999999999 0.07099800000000001 -0.182532 -0.059517 0.07099800000000001 -0.181201 -0.057231 0.049998 -0.190235 -0.023403 0.049998 -0.197539 -0.027205 0.049998 -0.190725 -0.043563 0.080983 -0.256573 -0.042184 0.094998 -0.262167 -0.03345 0.080718 -0.265711 0.029163 0.09553 -0.05552 0.031961 0.095501 -0.040298 0.029084 0.08015 -0.039744 -0.032728 0.067998 -0.23759 -0.033834 0.067998 -0.232697 -0.0341418 0.067998 -0.239829 -0.0430425 0.123603 -0.236991 -0.044275 0.124806 -0.232674 -0.0456132 0.12173 -0.237229 -0.017612 0.06343500000000001 -0.16783 -0.021233 0.0636 -0.183487 -0.012684 0.069286 -0.184201 -0.028807 0.131398 -0.230119 -0.028807 0.102998 -0.230119 -0.0260095 0.117198 -0.226961 -0.016268 0.057998 -0.21901 -0.008378999999999999 0.057998 -0.216018 -0.0123235 0.0619875 -0.217514 -0.02816 0.049998 -0.188077 -0.029147 0.062151 -0.185728 -0.031012 0.049998 -0.182966 0.031876 0.080175 -0.016158 0.032223 0.082122 -0.02238 0.033206 0.08286200000000001 -0.013636 -0.032964 0.102998 -0.268909 -0.0291896 0.102998 -0.269154 -0.0305964 0.102997 -0.269722 -0.008378999999999999 0.057998 -0.283984 -0.008378999999999999 0.131398 -0.283984 -1.99888e-06 0.131398 -0.285001 -0.001488 0.108845 -0.164172 -0.00675999 0.115159 -0.17718 -0.003402 0.115569 -0.163868 -0.037131 0.06919599999999999 -0.250607 -0.043563 0.080983 -0.256573 -0.0385065 0.0764526 -0.256684 -0.0335584 0.102998 -0.259043 -0.0334227 0.102998 -0.259593 -0.036966 0.102998 -0.258815 -0.016925 0.122882 -0.215977 -0.013038 0.118998 -0.214307 -0.009391 0.111495 -0.213179 -0.017449 0.120256 -0.202053 -0.010797 0.115038 -0.189686 -0.014048 0.114524 -0.201854 -0.015557 0.067998 -0.215638 -0.0145526 0.0704231 -0.212954 -0.015534 0.07106700000000001 -0.210269 -0.023212 0.057998 -0.276199 -0.028807 0.057998 -0.269883 -0.0260095 0.0726874 -0.273041 0.034981 0.039998 0.010695 0.036177 0.039998 0.00428799 0.036177 0.137998 0.00428798 -0.028807 0.057998 -0.269883 -0.0306243 0.067998 -0.26642 -0.0293392 0.067998 -0.268869 -0.0199652 0.0921587 -0.27844 -0.0217294 0.0679979 -0.277222 -0.0254514 0.0873768 -0.273671 -0.049668 0.120374 -0.109996 -0.038299 0.121013 -0.051695 -0.026806 0.129703 -0.054184 -0.060239 0.07099800000000001 -0.194583 -0.060239 0.049998 -0.194583 -0.057231 0.049998 -0.190235 0.016263 0.057998 -0.21901 0.016263 0.131398 -0.21901 0.008374009999999999 0.131398 -0.216018 0.036177 0.137998 0.00428798 0.036177 0.039998 0.00428799 0.036247 0.137998 0.0009799819999999999 0.029164 0.076123 -0.021844 0.019976 0.067373 -0.037929 0.025148 0.073194 -0.03896 0.012978 0.078932 -0.106368 0.012103 0.095511 -0.123116 0.01636 0.09552099999999999 -0.106937 -0.0570217 0.121279 -0.192606 -0.049958 0.126383 -0.187824 -0.0580022 0.120438 -0.187438 -0.013114 0.108058 -0.201814 -0.012348 0.09540999999999999 -0.20183 -0.011532 0.107588 -0.210271 -0.033834 0.067998 -0.232697 -0.0321938 0.067998 -0.236572 -0.0304037 0.0679979 -0.233161 -0.0337375 0.062998 -0.241686 -0.0337375 0.060498 -0.241686 -0.032728 0.057998 -0.23759 -0.044032 0.06316099999999999 -0.223615 -0.047715 0.06462900000000001 -0.222981 -0.051395 0.069561 -0.231297 -0.016895 0.128882 -0.147054 0.00071001 0.123015 -0.120724 -0.00501499 0.122031 -0.149263 -0.034828 0.094998 0.00348899 -0.034326 0.08115799999999999 -0.00534201 -0.034048 0.039998 -0.008119009999999999 0.023207 0.057998 -0.223803 0.016263 0.131398 -0.21901 0.016263 0.057998 -0.21901 -0.013985 0.076269 -0.204968 -0.017073 0.070427 -0.205294 -0.012724 0.076705 -0.209545 -0.00653584 0.07414800000000001 -0.215794 -0.00415147 0.0748472 -0.215505 -0.00614141 0.07561610000000001 -0.215678 -0.034828 0.094998 0.00348899 -0.032318 0.137998 0.013442 -0.034887 0.098269 0.00279799 -0.0260095 0.060498 -0.226961 -0.023212 0.057998 -0.223803 -0.0260095 0.062998 -0.226961 -0.0014 0.074006 -0.1541 -0.00468 0.07505100000000001 -0.169678 -0.003025 0.08194 -0.169916 -0.016665 0.06974900000000001 -0.198437 -0.021233 0.0636 -0.183487 -0.024351 0.063566 -0.195196 0.027792 0.137998 0.024268 0.023298 0.039998 0.028256 0.027792 0.039998 0.024268 -0.033143 0.062024 -0.221268 -0.029468 0.049998 -0.218918 -0.036282 0.049998 -0.22272 -0.011416 0.095416 -0.197055 -0.013114 0.108058 -0.201814 -0.009605000000000001 0.108348 -0.189741 -0.013229 0.075809 -0.19835 -0.013985 0.076269 -0.204968 -0.01322 0.08273999999999999 -0.204899 -0.057071 0.107012 -0.239238 -0.054278 0.117226 -0.231933 -0.051972 0.11736 -0.23662 -0.033834 0.067998 -0.232697 -0.024636 0.067998 -0.221068 -0.0294847 0.06503399999999999 -0.226685 -0.060132 0.08210099999999999 -0.125616 -0.059351 0.094998 -0.107759 -0.062363 0.094998 -0.125247 -0.047727 0.082469 -0.058234 -0.054764 0.094998 -0.083718 -0.054037 0.08229 -0.091492 -0.012538 0.102998 -0.217595 -0.019807 0.102998 -0.21757 -0.0120057 0.102998 -0.216492 -0.06519 0.094998 -0.142662 -0.062692 0.08193499999999999 -0.143086 -0.060132 0.08210099999999999 -0.125616 -0.061464 0.07099800000000001 -0.209841 -0.07356699999999999 0.07099800000000001 -0.182532 -0.056939 0.07099800000000001 -0.220732 -0.012418 0.071588 -0.214274 -0.009834000000000001 0.077057 -0.213119 -0.015534 0.07106700000000001 -0.210269 0.035786 0.094414 -0.00581501 0.035752 0.093403 -0.00599601 0.032223 0.082122 -0.02238 -0.047715 0.06462900000000001 -0.222981 -0.044032 0.06316099999999999 -0.223615 -0.044033 0.049998 -0.223626 -0.03788 0.067998 -0.246961 -0.037185 0.065271 -0.242165 -0.045077 0.06940499999999999 -0.241524 -0.021233 0.0636 -0.183487 -0.029147 0.062151 -0.185728 -0.028339 0.062313 -0.188136 -0.0297872 0.062998 -0.231987 -0.0307675 0.062998 -0.233855 -0.028807 0.057998 -0.230119 0.029473 0.076419 -0.019718 0.03148 0.079376 -0.016907 0.031544 0.039998 -0.016125 0.033206 0.039998 0.014953 0.031112 0.039998 0.019976 0.024691 0.039998 -0.024464 0.019976 0.067373 -0.037929 0.010922 0.062035 -0.036126 0.015328 0.06553 -0.054574 0.028642 0.11501 -0.02086 0.029564 0.113644 -0.019588 0.031539 0.110116 -0.019935 -0.068189 0.094998 -0.170106 -0.06689290000000001 0.08831550000000001 -0.170419 -0.064813 0.081788 -0.16105 -0.066541 0.1079 -0.181867 -0.065009 0.111448 -0.181721 -0.072017 0.119053 -0.18233 -0.031908 0.128859 -0.223879 -0.028827 0.128679 -0.225307 -0.032823 0.128474 -0.230849 -0.069103 0.094998 -0.18211 -0.066376 0.081721 -0.179787 -0.068189 0.094998 -0.170106 -0.052737 0.07099800000000001 -0.231787 -0.056871 0.076153 -0.232179 -0.058675 0.08124099999999999 -0.234455 0.01403 0.12392 -0.063029 0.025371 0.117444 -0.034582 0.019315 0.118087 -0.06417299999999999 0.025406 0.118766 -0.024322 0.031545 0.137998 -0.016125 0.027101 0.116799 -0.022508 -0.034747 0.131398 -0.245782 -0.032728 0.131398 -0.23759 -0.008378999999999999 0.131398 -0.283984 -0.06579 0.107966 -0.170226 -0.058648 0.118944 -0.171066 -0.066541 0.1079 -0.181867 -0.006972 0.09542399999999999 -0.184465 -0.008803 0.095419 -0.18977 -0.009605000000000001 0.108348 -0.189741 0.03132 0.111039 -0.017164 0.031545 0.137998 -0.016125 0.032042 0.109598 -0.01583 -0.043426 0.062724 -0.146549 -0.029338 0.061197 -0.149079 -0.042036 0.062669 -0.129234 -0.043426 0.062724 -0.146549 -0.053559 0.071121 -0.126929 -0.05547 0.07073400000000001 -0.144385 -0.03735 0.06260599999999999 -0.09519900000000001 -0.048222 0.07156700000000001 -0.09278500000000001 -0.042036 0.062669 -0.129234 0.036247 0.137998 0.0009799819999999999 0.035508 0.099208 -0.00713901 0.035503 0.137998 -0.00716101 -0.060239 0.07099800000000001 -0.194583 -0.057231 0.068227 -0.190235 -0.058697 0.07023500000000001 -0.180422 -0.037982 0.12146 -0.248769 -0.042263 0.117494 -0.250094 -0.037904 0.118998 -0.252736 -0.06231 0.094998 -0.232694 -0.057071 0.107012 -0.239238 -0.058828 0.094998 -0.240143 -0.037155 0.128008 -0.229005 -0.044452 0.126287 -0.226534 -0.031908 0.128859 -0.223879 0.008051020000000001 0.129972 -0.033797 0.00811601 0.137998 -0.034047 0.0134718 0.126915 -0.032658 -0.043659 0.127535 -0.142076 -0.038544 0.128686 -0.112365 -0.025099 0.132149 -0.115228 0.029564 0.113644 -0.019588 0.028642 0.11501 -0.02086 0.031545 0.137998 -0.016125 -0.005196 0.102998 -0.215389 -0.008378999999999999 0.102998 -0.216018 -0.0120057 0.102998 -0.216492 0.034742 0.057998 -0.245782 0.032723 0.057998 -0.23759 -2.99964e-06 0.0579979 -0.285001 -0.050376 0.126442 -0.204039 -0.049958 0.126383 -0.187824 -0.037903 0.12941 -0.1884 -0.001488 0.108845 -0.164172 -0.005313 0.108449 -0.177352 -0.00675999 0.115159 -0.17718 -0.000383994 0.116163 -0.150124 0.00568601 0.117233 -0.121784 0.009158009999999999 0.110451 -0.122524 0.00173001 0.072867 -0.137987 -0.0014 0.074006 -0.1541 0.001094 0.08108700000000001 -0.154548 -0.058828 0.094998 -0.240143 -0.054341 0.094998 -0.247534 -0.052093 0.08112999999999999 -0.246067 -0.058697 0.07023500000000001 -0.180422 -0.057231 0.068227 -0.190235 -0.055699 0.06725100000000001 -0.185688 0.024673 0.095531 -0.074061 0.021367 0.07895099999999999 -0.07337299999999999 0.020761 0.09553200000000001 -0.090212 0.029473 0.076419 -0.019718 0.027925 0.07441300000000001 -0.021615 0.029164 0.076123 -0.021844 -0.045698 0.108799 -0.050092 -0.056918 0.108547 -0.108453 -0.054764 0.094998 -0.083718 -0.016895 0.128882 -0.147054 -0.032859 0.130041 -0.159176 -0.030429 0.13079 -0.144536 -0.021233 0.0636 -0.183487 -0.027636 0.062453 -0.190236 -0.025697 0.062902 -0.19274 -0.056871 0.076153 -0.232179 -0.059887 0.08204 -0.232464 -0.058675 0.08124099999999999 -0.234455 -0.058675 0.08124099999999999 -0.234455 -0.061707 0.088404 -0.232637 -0.06231 0.094998 -0.232694 -0.012316 0.08247400000000001 -0.198331 -0.008803 0.095419 -0.18977 -0.007637 0.082319 -0.18461 -0.034747 0.067998 -0.247212 -0.03788 0.067998 -0.246961 -0.0363135 0.067998 -0.248096 -0.022774 0.039998 -0.02658 -0.013446 0.039998 -0.032316 0.024691 0.039998 -0.024464 -0.022509 0.06329799999999999 -0.219383 -0.029515 0.062234 -0.218869 -0.033143 0.062024 -0.221268 -0.035087 0.102998 -0.235405 -0.0299961 0.102998 -0.230342 -0.0303241 0.102998 -0.23301 -0.054037 0.08229 -0.091492 -0.054764 0.094998 -0.083718 -0.059351 0.094998 -0.107759 -0.0312109 0.102998 -0.265303 -0.0307675 0.117198 -0.266147 -0.0291896 0.102998 -0.269154 -0.006163 0.067844 -0.153244 -0.003516 0.066757 -0.136938 -0.01083 0.06265800000000001 -0.135477 -0.035583 0.06309099999999999 -0.23666 -0.034819 0.062778 -0.23491 -0.045077 0.06940499999999999 -0.241524 0.032723 0.057998 -0.23759 0.028802 0.057998 -0.230119 -2.99964e-06 0.0579979 -0.285001 -0.050569 0.06436799999999999 -0.180088 -0.047357 0.0631 -0.178521 -0.044694 0.06277199999999999 -0.163934 -0.00212134 0.0981031 -0.215258 -0.004855 0.095383 -0.215339 -0.00212157 0.08560189999999999 -0.215258 -0.0320424 0.0768882 -0.263718 -0.032728 0.0763397 -0.262412 -0.03345 0.080718 -0.265711 0.023357 0.111167 -0.065049 0.024673 0.095531 -0.074061 0.020761 0.09553200000000001 -0.090212 0.023207 0.131398 -0.276199 0.016263 0.131398 -0.280992 -0.008378999999999999 0.131398 -0.283984 0.017841 0.039998 0.031751 0.017841 0.137998 0.03175 0.012176 0.039998 0.0342 -0.036206 0.081192 -0.010436 -0.03323 0.07566299999999999 -0.010959 -0.034326 0.08115799999999999 -0.00534201 -0.013229 0.075809 -0.19835 -0.016665 0.06974900000000001 -0.198437 -0.013985 0.076269 -0.204968 -0.005196 0.102998 -0.215389 -0.019807 0.102998 -0.21757 -0.008815999999999999 0.102998 -0.213038 -0.01672 0.061015 -0.030618 -0.028074 0.06254899999999999 -0.045339 -0.013388 0.060519 -0.03217 -0.010007 0.113411 -0.213347 -0.013038 0.118998 -0.214307 -0.010689 0.115532 -0.213535 -0.034747 0.067998 -0.245782 -0.034747 0.0637284 -0.250001 -0.034747 0.057998 -0.245782 -0.067456 0.094998 -0.160678 -0.068189 0.094998 -0.170106 -0.064813 0.081788 -0.16105 -0.062009 0.108246 -0.138661 -0.06519 0.094998 -0.142662 -0.062363 0.094998 -0.125247 0.00071001 0.123015 -0.120724 0.019315 0.118087 -0.06417299999999999 0.00568601 0.117233 -0.121784 -0.03323 0.07566299999999999 -0.010959 -0.029873 0.039998 -0.018243 -0.034326 0.08115799999999999 -0.00534201 -0.016268 0.057998 -0.280992 -0.008378999999999999 0.131398 -0.283984 -0.008378999999999999 0.057998 -0.283984 -2.99582e-06 0.057998 -0.215001 -0.0028281 0.0782692 -0.215344 -0.00415147 0.0748472 -0.215505 0.001094 0.08108700000000001 -0.154548 -0.0014 0.074006 -0.1541 -0.003025 0.08194 -0.169916 -0.032728 0.131398 -0.262412 -0.034747 0.131398 -0.25422 -0.008378999999999999 0.131398 -0.283984 -0.056939 0.07099800000000001 -0.220732 -0.07356699999999999 0.07099800000000001 -0.182532 -0.055897 0.07099800000000001 -0.224066 -0.0260095 0.0726874 -0.273041 -0.028807 0.057998 -0.269883 -0.028807 0.0833648 -0.269883 0.035402 0.039998 -0.00747301 0.031544 0.039998 -0.016125 0.033809 0.039998 -0.012393 -0.00280198 0.137998 -0.034889 0.00811601 0.137998 -0.034047 0.008051020000000001 0.129972 -0.033797 0.010685 0.062075 -0.033096 0.020278 0.06684 -0.028527 0.018239 0.039998 -0.029872 -0.029338 0.061197 -0.149079 -0.014243 0.063067 -0.151789 -0.026849 0.060719 -0.132272 -0.029515 0.062234 -0.218869 -0.026485 0.062779 -0.215759 -0.024627 0.049998 -0.212797 0.025406 0.118766 -0.024322 0.025371 0.117444 -0.034582 0.022954 0.121125 -0.026485 -0.0260095 0.062998 -0.226961 -0.0280447 0.067998 -0.229259 -0.028807 0.057998 -0.230119 -0.004855 0.095383 -0.215339 -0.005627 0.08337899999999999 -0.215459 -0.00212157 0.08560189999999999 -0.215258 -0.034747 0.102998 -0.249047 -0.034747 0.102998 -0.25422 -0.0357192 0.102998 -0.253002 -0.052437 0.107055 -0.246859 -0.047488 0.117421 -0.24361 -0.046949 0.107107 -0.253978 -0.0254514 0.0873768 -0.273671 -0.0269275 0.08767800000000001 -0.272574 -0.025963 0.094998 -0.2751 0.00071001 0.123015 -0.120724 -0.016895 0.128882 -0.147054 -0.011323 0.130169 -0.118162 -0.003025 0.08194 -0.169916 -0.00516071 0.085313 -0.177317 -0.0049804 0.088686 -0.177374 -0.016268 0.057998 -0.280992 -0.0182832 0.0924469 -0.279645 -0.017284 0.094997 -0.280436 -0.031908 0.128859 -0.223879 -0.021122 0.12593 -0.218412 -0.022862 0.12675 -0.219763 0.035402 0.039998 -0.00747301 0.033206 0.08286200000000001 -0.013636 0.033572 0.08360099999999999 -0.012943 -0.042758 0.0669136 -0.23641 -0.034819 0.062778 -0.23491 -0.051395 0.069561 -0.231297 -0.016268 0.131398 -0.21901 -0.016268 0.102998 -0.21901 -0.0123235 0.117198 -0.217514 -0.013446 0.039998 -0.032316 -0.013388 0.060519 -0.03217 -0.00280299 0.039998 -0.034889 0.024691 0.039998 -0.024464 0.020278 0.039998 -0.028527 0.020278 0.06684 -0.028527 -0.0196111 0.067998 -0.221317 -0.01974 0.062998 -0.221406 -0.016268 0.067998 -0.21901 -0.004855 0.095383 -0.215339 -0.005196 0.102998 -0.215389 -0.008725 0.09539 -0.21254 -0.0294276 0.0808743 -0.268701 -0.028807 0.0833648 -0.269883 -0.0294052 0.0795941 -0.268743 -0.01322 0.08273999999999999 -0.204899 -0.013985 0.076269 -0.204968 -0.012034 0.082993 -0.209343 -0.040674 0.10718 -0.260584 -0.0370101 0.109485 -0.262435 -0.034606 0.107636 -0.265703 -0.038544 0.128686 -0.112365 -0.012814 0.13337 -0.057215 -0.025099 0.132149 -0.115228 -0.045698 0.108799 -0.050092 -0.039448 0.108685 -0.021917 -0.031887 0.120562 -0.023395 -0.024551 0.126404 -0.21416 -0.017449 0.120256 -0.202053 -0.01521 0.119156 -0.211406 -0.026806 0.129703 -0.054184 -0.038299 0.121013 -0.051695 -0.031887 0.120562 -0.023395 -0.033834 0.067998 -0.232697 -0.029836 0.06207 -0.226616 -0.034819 0.062778 -0.23491 -0.0363135 0.067998 -0.248096 -0.03788 0.067998 -0.246961 -0.036481 0.067998 -0.249142 -0.016268 0.102998 -0.21901 -0.0144225 0.102998 -0.21831 -0.0123235 0.117198 -0.217514 -0.012348 0.09540999999999999 -0.20183 -0.012343 0.0954 -0.207618 -0.011532 0.107588 -0.210271 -0.034747 0.131398 -0.25422 -0.034747 0.102998 -0.25422 -0.034747 0.117198 -0.250001 0.031545 0.137998 -0.016125 0.028642 0.11501 -0.02086 0.027101 0.116799 -0.022508 -0.028074 0.06254899999999999 -0.045339 -0.023114 0.062375 -0.02934 -0.034356 0.071198 -0.0271 -0.034747 0.131398 -0.25422 -0.034747 0.131398 -0.245782 -0.008378999999999999 0.131398 -0.283984 -0.034747 0.0703906 -0.25422 -0.034325 0.067998 -0.255932 -0.034747 0.057998 -0.25422 -0.026582 0.039998 0.022771 -0.026582 0.137998 0.02277 -0.032318 0.039998 0.013443 -0.0260095 0.062998 -0.226961 -0.0246108 0.062998 -0.225382 -0.023212 0.067998 -0.223803 0.028802 0.131398 -0.269883 0.023207 0.131398 -0.276199 -0.008378999999999999 0.131398 -0.283984 -2.99964e-06 0.0579979 -0.285001 -0.034747 0.057998 -0.245782 -0.034747 0.057998 -0.25422 -0.032859 0.130041 -0.159176 -0.045891 0.126901 -0.157101 -0.030429 0.13079 -0.144536 0.023207 0.057998 -0.223803 0.028802 0.131398 -0.230119 0.023207 0.131398 -0.223803 0.001094 0.08108700000000001 -0.154548 0.003933 0.09546499999999999 -0.151245 0.005089 0.08015600000000001 -0.138659 -0.037155 0.128008 -0.229005 -0.031908 0.128859 -0.223879 -0.032823 0.128474 -0.230849 -0.024636 0.067998 -0.221068 -0.024835 0.062582 -0.221237 -0.027767 0.062132 -0.224056 0.011027 0.065356 -0.071107 0.002578 0.065321 -0.104062 0.008484 0.07136099999999999 -0.105372 -0.034747 0.057998 -0.245782 -2.99964e-06 0.0579979 -0.285001 -0.032728 0.057998 -0.23759 -0.060239 0.049998 -0.194583 -0.062369 0.049998 -0.20209 -0.057231 0.049998 -0.190235 -0.0217294 0.102997 -0.277222 -0.0203629 0.101282 -0.278166 -0.0235251 0.0995163 -0.275846 -0.03345 0.080718 -0.265711 -0.037131 0.06919599999999999 -0.250607 -0.0385065 0.0764526 -0.256684 -0.0349329 0.102998 -0.241309 -0.035087 0.102998 -0.235405 -0.032728 0.102998 -0.23759 -0.016268 0.131398 -0.21901 -0.0123235 0.117198 -0.217514 -0.008378999999999999 0.131398 -0.216018 -0.0260095 0.060498 -0.226961 -0.0260095 0.062998 -0.226961 -0.028807 0.057998 -0.230119 0.028802 0.057998 -0.269883 0.032723 0.057998 -0.262412 -2.99964e-06 0.0579979 -0.285001 -0.044694 0.06277199999999999 -0.163934 -0.043426 0.062724 -0.146549 -0.05547 0.07073400000000001 -0.144385 0.033408 0.106873 -0.013307 0.034883 0.102449 -0.00945201 0.031539 0.110116 -0.019935 -0.029147 0.062151 -0.185728 -0.031137 0.061966 -0.183063 -0.031012 0.049998 -0.182966 -0.03735 0.06260599999999999 -0.09519900000000001 -0.031196 0.062566 -0.061855 -0.042229 0.071954 -0.059438 -0.0119847 0.102998 -0.217043 -0.0120057 0.102998 -0.216492 -0.0114314 0.102998 -0.217176 -0.043659 0.127535 -0.142076 -0.056819 0.119225 -0.155361 -0.054701 0.119633 -0.140021 -0.035087 0.102998 -0.235405 -0.028827 0.128679 -0.225307 -0.028859 0.102998 -0.225278 -0.034747 0.0703906 -0.25422 -0.034747 0.057998 -0.25422 -0.034747 0.0694588 -0.252902 -0.043563 0.080983 -0.256573 -0.049442 0.094998 -0.254344 -0.048554 0.094998 -0.255301 -0.014746 0.067998 -0.216628 -0.024636 0.067998 -0.221068 -0.013686 0.067998 -0.217787 0.034742 0.057998 -0.25422 0.034742 0.057998 -0.245782 -2.99964e-06 0.0579979 -0.285001 0.024673 0.095531 -0.074061 0.026925 0.09553 -0.064763 0.021367 0.07895099999999999 -0.07337299999999999 -0.0337375 0.117198 -0.241686 -0.034747 0.131398 -0.245782 -0.034747 0.102998 -0.245782 -0.00501499 0.122031 -0.149263 0.00071001 0.123015 -0.120724 0.00568601 0.117233 -0.121784 -0.029842 0.080358 -0.268227 -0.0294276 0.0808743 -0.268701 -0.0294052 0.0795941 -0.268743 -0.056918 0.108547 -0.108453 -0.038299 0.121013 -0.051695 -0.049668 0.120374 -0.109996 0.035788 0.09544 -0.00580301 0.034349 0.095469 -0.02239 0.031539 0.110116 -0.019935 -0.034828 0.094998 0.00348899 -0.036206 0.081192 -0.010436 -0.034326 0.08115799999999999 -0.00534201 0.00358101 0.060637 -0.034817 -0.010127 0.060008 -0.049157 0.010922 0.062035 -0.036126 -0.017073 0.070427 -0.205294 -0.02251 0.06550499999999999 -0.20529 -0.015534 0.07106700000000001 -0.210269 -0.020283 0.039998 0.028524 -0.009214989999999999 0.039998 0.034258 -0.008135979999999999 0.137998 0.034439 -0.00280299 0.039998 -0.034889 0.008115010000000001 0.039998 -0.034047 0.024691 0.039998 -0.024464 -0.029468 0.049998 -0.218918 -0.057231 0.049998 -0.190235 -0.036282 0.049998 -0.22272 -0.0266445 0.102997 -0.272324 -0.024783 0.102997 -0.274717 -0.028332 0.102997 -0.27231 0.020104 0.123114 -0.033553 0.008051020000000001 0.129972 -0.033797 0.0134718 0.126915 -0.032658 -0.023427 0.127181 -0.025713 -0.029834 0.120931 -0.018209 -0.029873 0.137998 -0.018243 -0.039448 0.108685 -0.021917 -0.035803 0.108542 -0.00859101 -0.030235 0.12028 -0.017474 0.008237009999999999 0.061996 -0.053063 -0.010127 0.060008 -0.049157 0.00428401 0.062021 -0.069631 -0.040037 0.124841 -0.23872 -0.0430425 0.123603 -0.236991 -0.044275 0.124806 -0.232674 -0.057231 0.049998 -0.190235 -0.052157 0.049998 -0.181269 -0.055788 0.049998 -0.18586 -0.06579 0.107966 -0.170226 -0.068189 0.094998 -0.170106 -0.067456 0.094998 -0.160678 -0.025697 0.062902 -0.19274 -0.027205 0.049998 -0.190725 -0.023523 0.064305 -0.197932 -0.064813 0.081788 -0.16105 -0.066376 0.081721 -0.179787 -0.058697 0.07023500000000001 -0.180422 0.034742 0.131398 -0.245782 0.034742 0.131398 -0.25422 -0.008378999999999999 0.131398 -0.283984 -0.036206 0.081192 -0.010436 -0.034356 0.071198 -0.0271 -0.030053 0.070437 -0.017043 -0.0306243 0.067998 -0.26642 -0.028807 0.057998 -0.269883 -0.032728 0.057998 -0.262412 -0.008378999999999999 0.131398 -0.283984 0.008374009999999999 0.131398 -0.283984 -1.99888e-06 0.131398 -0.285001 -0.022497 0.049998 -0.20529 -0.057231 0.049998 -0.190235 -0.024627 0.049998 -0.212797 -0.011416 0.095416 -0.197055 -0.008803 0.095419 -0.18977 -0.012316 0.08247400000000001 -0.198331 -0.056819 0.119225 -0.155361 -0.043659 0.127535 -0.142076 -0.045891 0.126901 -0.157101 -0.019807 0.102998 -0.21757 -0.005196 0.102998 -0.215389 -0.0120057 0.102998 -0.216492 -0.0341418 0.067998 -0.239829 -0.03788 0.067998 -0.246961 -0.0344719 0.067998 -0.244666 -0.035565 0.128969 -0.217398 -0.044452 0.126287 -0.226534 -0.046622 0.126471 -0.220648 -0.0217294 0.0679979 -0.277222 -0.0182832 0.0924469 -0.279645 -0.016268 0.057998 -0.280992 0.022974 0.06915499999999999 -0.026468 0.025455 0.071586 -0.024275 0.024691 0.039998 -0.024464 -0.042891 0.06232 -0.177697 -0.031735 0.06163 -0.165798 -0.046303 0.062916 -0.178326 -0.0333971 0.067998 -0.259697 -0.0337503 0.0725065 -0.258264 -0.0331411 0.07301580000000001 -0.260736 -0.00653799 0.060086 -0.034225 -0.028074 0.06254899999999999 -0.045339 -0.010127 0.060008 -0.049157 -0.038299 0.121013 -0.051695 -0.045698 0.108799 -0.050092 -0.031887 0.120562 -0.023395 -0.008803 0.095419 -0.18977 -0.006972 0.09542399999999999 -0.184465 -0.007637 0.082319 -0.18461 -0.0320424 0.0768882 -0.263718 -0.03345 0.080718 -0.265711 -0.029842 0.080358 -0.268227 0.003933 0.09546499999999999 -0.151245 0.001094 0.08108700000000001 -0.154548 0.002275 0.095455 -0.156935 -0.0337503 0.0725065 -0.258264 -0.033234 0.07478029999999999 -0.260359 -0.0331411 0.07301580000000001 -0.260736 -0.023212 0.057998 -0.276199 -0.0217294 0.0679979 -0.277222 -0.016268 0.057998 -0.280992 -0.038987 0.062292 -0.223391 -0.044032 0.06316099999999999 -0.223615 -0.041496 0.06280570000000001 -0.225134 0.020761 0.09553200000000001 -0.090212 0.012978 0.078932 -0.106368 0.01636 0.09552099999999999 -0.106937 -0.041496 0.06280570000000001 -0.225134 -0.044032 0.06316099999999999 -0.223615 -0.041227 0.062847 -0.226878 -0.046465 0.094998 -0.04153 -0.045698 0.108799 -0.050092 -0.049463 0.094998 -0.056063 -0.044275 0.124806 -0.232674 -0.047487 0.124698 -0.226704 -0.044452 0.126287 -0.226534 0.012103 0.095511 -0.123116 0.009158009999999999 0.110451 -0.122524 0.01636 0.09552099999999999 -0.106937 -0.005313 0.108449 -0.177352 -0.006972 0.09542399999999999 -0.184465 -0.009605000000000001 0.108348 -0.189741 -0.0317456 0.102998 -0.235718 -0.035087 0.102998 -0.235405 -0.0314748 0.102998 -0.235202 -0.013686 0.067998 -0.217787 -0.0189327 0.067998 -0.219552 -0.016268 0.067998 -0.21901 0.018876 0.039998 0.031088 0.017841 0.039998 0.031751 0.024691 0.039998 -0.024464 -0.067271 0.106211 -0.181936 -0.06579 0.107966 -0.170226 -0.066541 0.1079 -0.181867 -0.0041905 0.117198 -0.21551 -0.008378999999999999 0.131398 -0.216018 -0.008378999999999999 0.102998 -0.216018 -0.055788 0.049998 -0.18586 -0.052157 0.049998 -0.181269 -0.052941 0.065599 -0.181985 -0.00365891 0.0991905 -0.215317 -0.00212134 0.0981031 -0.215258 -0.00240399 0.102998 -0.215293 -0.042184 0.094998 -0.262167 -0.034606 0.107636 -0.265703 -0.035455 0.094998 -0.268032 -0.028807 0.0833648 -0.269883 -0.0291173 0.07068140000000001 -0.269292 -0.0294052 0.0795941 -0.268743 -0.061713 0.101573 -0.232638 -0.068758 0.07099800000000001 -0.233304 -0.068758 0.118998 -0.233305 -2.99964e-06 0.0579979 -0.285001 -2.99582e-06 0.057998 -0.215001 -0.008378999999999999 0.057998 -0.216018 -0.016268 0.067998 -0.21901 -0.018004 0.062998 -0.220208 -0.016268 0.057998 -0.21901 -0.0310716 0.0699446 -0.265568 -0.0320424 0.0768882 -0.263718 -0.0294052 0.0795941 -0.268743 -0.052437 0.107055 -0.246859 -0.051972 0.11736 -0.23662 -0.047488 0.117421 -0.24361 0.017841 0.137998 0.03175 0.012177 0.137998 0.0342 0.012176 0.039998 0.0342 0.034742 0.131398 -0.245782 0.034742 0.057998 -0.245782 0.034742 0.131398 -0.25422 -0.034747 0.067998 -0.249231 -0.0363135 0.067998 -0.248096 -0.036481 0.067998 -0.249142 -0.013038 0.118998 -0.214307 -0.01521 0.119156 -0.211406 -0.010689 0.115532 -0.213535 -0.028807 0.131398 -0.269883 -0.032728 0.131398 -0.262412 -0.008378999999999999 0.131398 -0.283984 -0.06411 0.10808 -0.1542 -0.06579 0.107966 -0.170226 -0.067456 0.094998 -0.160678 -0.00280198 0.137998 -0.034889 0.008051020000000001 0.129972 -0.033797 -0.00279198 0.132618 -0.034791 -0.057231 0.068227 -0.190235 -0.057231 0.049998 -0.190235 -0.055699 0.06725100000000001 -0.185688 0.008373 0.057998 -0.283984 0.008374009999999999 0.131398 -0.283984 0.016263 0.057998 -0.280992 -0.00370299 0.062147 -0.102663 -0.020843 0.060114 -0.098861 -0.01083 0.06265800000000001 -0.135477 -0.032728 0.102998 -0.23759 -0.0307675 0.117198 -0.233855 -0.032728 0.131398 -0.23759 -0.00653799 0.060086 -0.034225 -0.010127 0.060008 -0.049157 -0.00281699 0.060073 -0.034888 -0.045698 0.108799 -0.050092 -0.054764 0.094998 -0.083718 -0.049463 0.094998 -0.056063 -0.00280299 0.039998 -0.034889 -0.00281699 0.060073 -0.034888 0.008115010000000001 0.039998 -0.034047 -0.00501499 0.122031 -0.149263 0.00568601 0.117233 -0.121784 -0.000383994 0.116163 -0.150124 -0.069103 0.094998 -0.18211 -0.06579 0.107966 -0.170226 -0.06864199999999999 0.100682 -0.182065 0.020278 0.123345 -0.028527 0.025371 0.117444 -0.034582 0.020104 0.123114 -0.033553 0.032723 0.057998 -0.262412 0.034742 0.057998 -0.25422 -2.99964e-06 0.0579979 -0.285001 -0.036792 0.125578 -0.240488 -0.040037 0.124841 -0.23872 -0.035081 0.127396 -0.235407 -0.046949 0.107107 -0.253978 -0.045625 0.094998 -0.258458 -0.048554 0.094998 -0.255301 -0.0321938 0.067998 -0.236572 -0.032728 0.057998 -0.23759 -0.0307675 0.062998 -0.233855 -0.040674 0.10718 -0.260584 -0.042184 0.094998 -0.262167 -0.045625 0.094998 -0.258458 0.029163 0.09553 -0.05552 0.029084 0.08015 -0.039744 0.025389 0.079096 -0.056714 -0.0334227 0.102998 -0.259593 -0.032728 0.102998 -0.262412 -0.036966 0.102998 -0.258815 -0.012814 0.13337 -0.057215 -0.038544 0.128686 -0.112365 -0.026806 0.129703 -0.054184 -0.00812 0.074265 -0.215957 -0.010009 0.07188899999999999 -0.216485 -0.00653584 0.07414800000000001 -0.215794 -0.034747 0.0692173 -0.252549 -0.037131 0.06919599999999999 -0.250607 -0.034747 0.0694588 -0.252902 -0.057231 0.049998 -0.190235 -0.061464 0.049998 -0.209841 -0.057662 0.049998 -0.216656 -0.053559 0.071121 -0.126929 -0.054037 0.08229 -0.091492 -0.060132 0.08210099999999999 -0.125616 -0.019807 0.102998 -0.21757 -0.00891 0.107254 -0.21306 -0.008815999999999999 0.10605 -0.213038 -0.0123235 0.117198 -0.217514 -0.012538 0.102998 -0.217595 -0.0114314 0.102998 -0.217176 0.027792 0.137998 0.024268 0.023298 0.137998 0.028256 0.023298 0.039998 0.028256 -0.032728 0.057998 -0.23759 -2.99964e-06 0.0579979 -0.285001 -0.028807 0.057998 -0.230119 0.035786 0.094414 -0.00581501 0.036247 0.137998 0.0009799819999999999 0.036247 0.039998 0.000979986 -0.035603 0.049998 -0.179336 -0.034101 0.061824 -0.180269 -0.035656 0.061843 -0.17945 -0.032859 0.130041 -0.159176 -0.019536 0.128174 -0.161298 -0.035318 0.129524 -0.173813 -2.99582e-06 0.057998 -0.215001 0.008373 0.057998 -0.216018 -0.0028281 0.0782692 -0.215344 -0.027205 0.049998 -0.190725 -0.027636 0.062453 -0.190236 -0.02816 0.049998 -0.188077 -0.023212 0.057998 -0.276199 -0.0260095 0.0726874 -0.273041 -0.0254514 0.0873768 -0.273671 -0.005196 0.102998 -0.215389 -0.008815999999999999 0.102998 -0.213038 -0.006925 0.102998 -0.214239 -0.0235251 0.0995163 -0.275846 -0.023212 0.0986773 -0.276199 -0.028332 0.102997 -0.27231 -0.0204923 0.09732010000000001 -0.278076 -0.023212 0.0986773 -0.276199 -0.0203629 0.101282 -0.278166 -0.034747 0.0692173 -0.252549 -0.034747 0.0694588 -0.252902 -0.034747 0.067998 -0.252601 0.018239 0.137998 -0.029872 0.020278 0.123345 -0.028527 0.018147 0.12471 -0.029694 -0.01974 0.117198 -0.221406 -0.023212 0.102998 -0.223803 -0.0189548 0.102998 -0.220865 -0.0333971 0.067998 -0.259697 -0.0331411 0.07301580000000001 -0.260736 -0.032728 0.057998 -0.262412 -0.023114 0.062375 -0.02934 -0.01672 0.061015 -0.030618 -0.022773 0.062583 -0.026579 -0.010007 0.113411 -0.213347 -0.013038 0.118998 -0.214307 -0.009391 0.111495 -0.213179 -0.0307675 0.062998 -0.233855 -0.0307674 0.060498 -0.233855 -0.028807 0.057998 -0.230119 -0.00468 0.07505100000000001 -0.169678 -0.008795000000000001 0.075515 -0.184517 -0.007637 0.082319 -0.18461 0.020104 0.123114 -0.033553 0.025371 0.117444 -0.034582 0.01403 0.12392 -0.063029 -0.031735 0.06163 -0.165798 -0.038327 0.061912 -0.178263 -0.035656 0.061843 -0.17945 -0.012343 0.0954 -0.207618 -0.01322 0.08273999999999999 -0.204899 -0.012034 0.082993 -0.209343 -0.052157 0.049998 -0.181269 -0.050569 0.06436799999999999 -0.180088 -0.052113 0.06517000000000001 -0.181323 -0.00240399 0.102998 -0.215293 -1.99507e-06 0.131398 -0.215001 -0.0041905 0.117198 -0.21551 -0.021795 0.094998 -0.277775 -0.0204923 0.09732010000000001 -0.278076 -0.017284 0.094997 -0.280436 -0.01521 0.119156 -0.211406 -0.012303 0.113728 -0.210533 -0.010007 0.113411 -0.213347 -0.028807 0.0833648 -0.269883 -0.028807 0.057998 -0.269883 -0.0291173 0.07068140000000001 -0.269292 0.03541 0.090421 -0.00747301 0.036247 0.039998 0.000979986 0.036302 0.039998 -0.001659 -0.036966 0.102998 -0.258815 -0.032728 0.102998 -0.262412 -0.0330778 0.102998 -0.263984 -0.034747 0.131398 -0.245782 -0.034747 0.102998 -0.247697 -0.034747 0.102998 -0.247212 -0.014243 0.063067 -0.151789 -0.006163 0.067844 -0.153244 -0.01083 0.06265800000000001 -0.135477 -0.039448 0.108685 -0.021917 -0.039489 0.094998 -0.011609 -0.035803 0.108542 -0.00859101 -0.0312109 0.102998 -0.265303 -0.032964 0.102998 -0.268909 -0.0330778 0.102998 -0.263984 -0.044694 0.06277199999999999 -0.163934 -0.031735 0.06163 -0.165798 -0.043426 0.062724 -0.146549 0.005089 0.08015600000000001 -0.138659 0.012103 0.095511 -0.123116 0.01049 0.08722149999999999 -0.12288 -0.0423461 0.119877 -0.245385 -0.051972 0.11736 -0.23662 -0.047488 0.117421 -0.24361 -0.008378999999999999 0.102998 -0.216018 -0.008378999999999999 0.131398 -0.216018 -0.0114314 0.102998 -0.217176 -0.0337503 0.0725065 -0.258264 -0.034747 0.0703906 -0.25422 -0.037131 0.06919599999999999 -0.250607 -0.00279198 0.132618 -0.034791 -0.013414 0.13189 -0.032243 -0.013446 0.137998 -0.032316 0.03541 0.090421 -0.00747301 0.036302 0.039998 -0.001659 0.035402 0.039998 -0.00747301 -0.054278 0.117226 -0.231933 -0.068758 0.118998 -0.233305 -0.06334099999999999 0.119187 -0.232981 -0.053931 0.068025 -0.219959 -0.055771 0.069714 -0.220433 -0.051395 0.069561 -0.231297 0.00071001 0.123015 -0.120724 0.01403 0.12392 -0.063029 0.019315 0.118087 -0.06417299999999999 -0.047487 0.124698 -0.226704 -0.0497035 0.123371 -0.227009 -0.044275 0.124806 -0.232674 -0.0280447 0.067998 -0.229259 -0.023212 0.067998 -0.223803 -0.0271378 0.067998 -0.226882 -0.025963 0.094998 -0.2751 -0.028931 0.094998 -0.27299 -0.028332 0.102997 -0.27231 -0.00653799 0.060086 -0.034225 -0.00281699 0.060073 -0.034888 -0.00280299 0.039998 -0.034889 -0.041227 0.062847 -0.226878 -0.033143 0.062024 -0.221268 -0.036328 0.062118 -0.222573 -2.99964e-06 0.0579979 -0.285001 -0.034747 0.057998 -0.25422 -0.032728 0.057998 -0.262412 0.03148 0.079376 -0.016907 0.031876 0.080175 -0.016158 0.031544 0.039998 -0.016125 -0.059887 0.08204 -0.232464 -0.068758 0.07099800000000001 -0.233304 -0.061707 0.088404 -0.232637 -0.029836 0.06207 -0.226616 -0.033834 0.067998 -0.232697 -0.0294847 0.06503399999999999 -0.226685 -0.035455 0.094998 -0.268032 -0.034039 0.106035 -0.26681 -0.033653 0.094998 -0.269585 -0.00279198 0.132618 -0.034791 0.008051020000000001 0.129972 -0.033797 0.00154202 0.131335 -0.060324 0.031112 0.137998 0.019976 0.027792 0.137998 0.024268 0.027792 0.039998 0.024268 -0.061464 0.049998 -0.209841 -0.058172 0.07099800000000001 -0.216032 -0.057662 0.049998 -0.216656 -0.010127 0.060008 -0.049157 -0.028074 0.06254899999999999 -0.045339 -0.0137 0.060008 -0.065689 -0.049958 0.126383 -0.187824 -0.0580022 0.120438 -0.187438 -0.058413 0.119945 -0.185262 -0.019807 0.102998 -0.21757 -0.0189548 0.102998 -0.220865 -0.0216408 0.102998 -0.221424 -0.038327 0.061912 -0.178263 -0.041233 0.049998 -0.177738 -0.035656 0.061843 -0.17945 0.032223 0.082122 -0.02238 0.033541 0.095485 -0.031703 0.034349 0.095469 -0.02239 -0.055788 0.049998 -0.18586 -0.052941 0.065599 -0.181985 -0.055699 0.06725100000000001 -0.185688 -0.052737 0.07099800000000001 -0.231787 -0.068758 0.07099800000000001 -0.233304 -0.056871 0.076153 -0.232179 -0.009162 0.08319500000000001 -0.212779 -0.008725 0.09539 -0.21254 -0.011576 0.095397 -0.209183 -0.032728 0.102998 -0.262412 -0.0334227 0.102998 -0.259593 -0.0337375 0.117198 -0.258316 -0.065009 0.111448 -0.181721 -0.06192 0.118998 -0.181429 -0.072017 0.119053 -0.18233 -0.036481 0.067998 -0.249142 -0.045077 0.06940499999999999 -0.241524 -0.037131 0.06919599999999999 -0.250607 -0.036282 0.049998 -0.22272 -0.057231 0.049998 -0.190235 -0.044033 0.049998 -0.223626 -0.03345 0.080718 -0.265711 -0.035455 0.094998 -0.268032 -0.033653 0.094998 -0.269585 -0.021233 0.0636 -0.183487 -0.028339 0.062313 -0.188136 -0.027636 0.062453 -0.190236 -0.034747 0.117198 -0.250001 -0.034747 0.102998 -0.25422 -0.034747 0.102998 -0.249047 -0.062369 0.049998 -0.20209 -0.061464 0.07099800000000001 -0.209841 -0.061464 0.049998 -0.209841 -0.0497035 0.123371 -0.227009 -0.044275 0.124806 -0.232674 -0.0456132 0.12173 -0.237229 -0.032823 0.128474 -0.230849 -0.028827 0.128679 -0.225307 -0.035081 0.127396 -0.235407 0.035402 0.039998 -0.00747301 0.036302 0.039998 -0.001659 0.024691 0.039998 -0.024464 -0.046622 0.126471 -0.220648 -0.0513867 0.122741 -0.222061 -0.0511948 0.122623 -0.223052 -0.034747 0.102998 -0.25422 -0.0339658 0.102998 -0.25739 -0.036966 0.102998 -0.258815 0.031545 0.137998 -0.016125 0.035503 0.137998 -0.00716101 0.032042 0.109598 -0.01583 -0.008378999999999999 0.131398 -0.283984 -0.023212 0.131398 -0.223803 -0.016268 0.131398 -0.21901 -0.06579 0.107966 -0.170226 -0.069103 0.094998 -0.18211 -0.068189 0.094998 -0.170106 -0.026849 0.060719 -0.132272 -0.020843 0.060114 -0.098861 -0.03735 0.06260599999999999 -0.09519900000000001 0.033206 0.08286200000000001 -0.013636 0.032223 0.082122 -0.02238 0.033572 0.08360099999999999 -0.012943 -0.013414 0.13189 -0.032243 -0.023427 0.127181 -0.025713 -0.022774 0.137998 -0.02658 -0.016268 0.131398 -0.21901 -0.0189548 0.102998 -0.220865 -0.016268 0.102998 -0.21901 0.033206 0.039998 0.014953 0.033206 0.137998 0.014953 0.031112 0.039998 0.019976 -0.034747 0.057998 -0.245782 -0.034747 0.0637284 -0.250001 -0.034747 0.0608632 -0.250001 -0.021122 0.12593 -0.218412 -0.035565 0.128969 -0.217398 -0.024551 0.126404 -0.21416 -2.99964e-06 0.0579979 -0.285001 0.008373 0.057998 -0.283984 0.016263 0.057998 -0.280992 -0.003516 0.066757 -0.136938 -0.00370299 0.062147 -0.102663 -0.01083 0.06265800000000001 -0.135477 -0.028931 0.094998 -0.27299 -0.030964 0.102997 -0.270424 -0.028332 0.102997 -0.27231 -0.0344719 0.067998 -0.244666 -0.03788 0.067998 -0.246961 -0.034747 0.067998 -0.245782 0.035503 0.137998 -0.00716101 0.035508 0.099208 -0.00713901 0.034883 0.102449 -0.00945201 -0.016268 0.131398 -0.280992 -0.008378999999999999 0.131398 -0.283984 -0.017284 0.094997 -0.280436 -0.0028281 0.0782692 -0.215344 0.008373 0.057998 -0.216018 -0.00212157 0.08560189999999999 -0.215258 -0.038544 0.128686 -0.112365 -0.049668 0.120374 -0.109996 -0.026806 0.129703 -0.054184 -0.012814 0.13337 -0.057215 -0.026806 0.129703 -0.054184 -0.023427 0.127181 -0.025713 -0.016665 0.06974900000000001 -0.198437 -0.017073 0.070427 -0.205294 -0.013985 0.076269 -0.204968 -0.012034 0.082993 -0.209343 -0.009162 0.08319500000000001 -0.212779 -0.011576 0.095397 -0.209183 -0.013388 0.060519 -0.03217 -0.00653799 0.060086 -0.034225 -0.00280299 0.039998 -0.034889 -0.02251 0.06550499999999999 -0.20529 -0.022834 0.065247 -0.207674 -0.015534 0.07106700000000001 -0.210269 -0.022774 0.039998 -0.02658 -0.029873 0.039998 -0.018243 -0.030053 0.070437 -0.017043 -0.039228 0.072168 -0.042965 -0.034356 0.071198 -0.0271 -0.040722 0.08209 -0.025833 -0.054701 0.119633 -0.140021 -0.049668 0.120374 -0.109996 -0.038544 0.128686 -0.112365 -0.044547 0.08257 -0.041831 -0.046465 0.094998 -0.04153 -0.049463 0.094998 -0.056063 0.028802 0.057998 -0.269883 0.028802 0.131398 -0.269883 0.032723 0.057998 -0.262412 -0.012684 0.069286 -0.184201 -0.021233 0.0636 -0.183487 -0.016665 0.06974900000000001 -0.198437 0.035508 0.099208 -0.00713901 0.036247 0.137998 0.0009799819999999999 0.0357 0.09740500000000001 -0.006256 -0.023212 0.102998 -0.223803 -0.0243759 0.102998 -0.225117 -0.028859 0.102998 -0.225278 -0.0588453 0.119509 -0.182979 -0.058648 0.118944 -0.171066 -0.047993 0.126464 -0.17232 -0.008815999999999999 0.102998 -0.213038 -0.008815999999999999 0.10605 -0.213038 -0.008725 0.09539 -0.21254 -0.012303 0.113728 -0.210533 -0.013114 0.108058 -0.201814 -0.011532 0.107588 -0.210271 0.008374009999999999 0.131398 -0.283984 0.008373 0.057998 -0.283984 -1.99888e-06 0.131398 -0.285001 -0.020843 0.060114 -0.098861 -0.031196 0.062566 -0.061855 -0.03735 0.06260599999999999 -0.09519900000000001 -0.0588453 0.119509 -0.182979 -0.047993 0.126464 -0.17232 -0.058413 0.119945 -0.185262 -0.00501499 0.122031 -0.149263 -0.000383994 0.116163 -0.150124 -0.00780799 0.12149 -0.163167 -0.009214989999999999 0.039998 0.034258 0.024691 0.039998 -0.024464 0.00116801 0.039998 0.036003 -0.036116 0.111791 -0.261823 -0.034606 0.107636 -0.265703 -0.032964 0.102998 -0.268909 -0.032728 0.057998 -0.262412 -0.032728 0.0763397 -0.262412 -0.0310716 0.0699446 -0.265568 0.033541 0.095485 -0.031703 0.029418 0.110682 -0.035372 0.031539 0.110116 -0.019935 0.035016 0.08812399999999999 -0.009014019999999999 0.032223 0.082122 -0.02238 0.03541 0.090421 -0.00747301 -0.034747 0.0637284 -0.250001 -0.034747 0.067998 -0.249231 -0.034747 0.067998 -0.250643 -0.0260095 0.115038 -0.273041 -0.0217294 0.102997 -0.277222 -0.024783 0.102997 -0.274717 -0.012343 0.0954 -0.207618 -0.012034 0.082993 -0.209343 -0.011576 0.095397 -0.209183 -0.028827 0.128679 -0.225307 -0.025378 0.127937 -0.221716 -0.028859 0.102998 -0.225278 -0.00884017 0.067998 -0.216193 -0.013686 0.067998 -0.217787 -0.0123235 0.0659771 -0.217514 -0.057231 0.049998 -0.190235 -0.022497 0.049998 -0.20529 -0.023403 0.049998 -0.197539 -0.028827 0.128679 -0.225307 -0.035087 0.102998 -0.235405 -0.035081 0.127396 -0.235407 -0.029515 0.062234 -0.218869 -0.024627 0.049998 -0.212797 -0.029468 0.049998 -0.218918 -0.019807 0.102998 -0.21757 -0.0144225 0.102998 -0.21831 -0.016268 0.102998 -0.21901 -0.045625 0.094998 -0.258458 -0.043563 0.080983 -0.256573 -0.048554 0.094998 -0.255301 -0.0304037 0.0679979 -0.233161 -0.0321938 0.067998 -0.236572 -0.0307675 0.062998 -0.233855 -0.0349329 0.102998 -0.241309 -0.032728 0.102998 -0.23759 -0.0335092 0.102998 -0.24076 -0.023212 0.131398 -0.223803 -0.0243759 0.102998 -0.225117 -0.023212 0.102998 -0.223803 0.027792 0.039998 0.024268 0.023298 0.039998 0.028256 0.024691 0.039998 -0.024464 -0.066635 0.08205900000000001 -0.181875 -0.063614 0.07618 -0.181589 -0.058697 0.07023500000000001 -0.180422 -0.00675999 0.115159 -0.17718 -0.014708 0.120982 -0.189504 -0.010933 0.121115 -0.176687 -0.015557 0.067998 -0.215638 -0.019043 0.065294 -0.217116 -0.022509 0.06329799999999999 -0.219383 0.028802 0.131398 -0.230119 -0.008378999999999999 0.131398 -0.283984 0.023207 0.131398 -0.223803 -0.01521 0.119156 -0.211406 -0.010007 0.113411 -0.213347 -0.010689 0.115532 -0.213535 -0.024627 0.049998 -0.212797 -0.057231 0.049998 -0.190235 -0.029468 0.049998 -0.218918 -0.026582 0.039998 0.022771 0.024691 0.039998 -0.024464 -0.020283 0.039998 0.028524 -0.006693 0.077352 -0.215648 -0.005627 0.08337899999999999 -0.215459 -0.009162 0.08319500000000001 -0.212779 -0.028807 0.102998 -0.230119 -0.0299961 0.102998 -0.230342 -0.028859 0.102998 -0.225278 -0.034747 0.131398 -0.25422 -0.0337375 0.117198 -0.258316 -0.0339658 0.102998 -0.25739 -0.022773 0.062583 -0.026579 -0.022774 0.039998 -0.02658 -0.030053 0.070437 -0.017043 -0.047047 0.049998 -0.178417 -0.041251 0.062174 -0.1779 -0.042891 0.06232 -0.177697 0.021367 0.07895099999999999 -0.07337299999999999 0.016863 0.071426 -0.07238600000000001 0.012978 0.078932 -0.106368 -0.035087 0.102998 -0.235405 -0.0319859 0.102998 -0.236176 -0.032728 0.102998 -0.23759 -0.047993 0.126464 -0.17232 -0.045891 0.126901 -0.157101 -0.032859 0.130041 -0.159176 -0.008378999999999999 0.131398 -0.283984 0.016263 0.131398 -0.21901 0.023207 0.131398 -0.223803 -0.01974 0.062998 -0.221406 -0.0204416 0.067998 -0.221891 -0.022266 0.067998 -0.22315 -0.056939 0.07099800000000001 -0.220732 -0.055897 0.07099800000000001 -0.224066 -0.052737 0.07099800000000001 -0.231787 -0.00240399 0.102998 -0.215293 -0.00212134 0.0981031 -0.215258 0.008373 0.057998 -0.216018 -0.023212 0.0986773 -0.276199 -0.021795 0.094998 -0.277775 -0.028332 0.102997 -0.27231 0.036247 0.137998 0.0009799819999999999 0.035786 0.094414 -0.00581501 0.035788 0.09544 -0.00580301 -0.033234 0.07478029999999999 -0.260359 -0.037131 0.06919599999999999 -0.250607 -0.03345 0.080718 -0.265711 -0.035583 0.06309099999999999 -0.23666 -0.037185 0.065271 -0.242165 -0.034819 0.062778 -0.23491 0.023298 0.039998 0.028256 0.018876 0.039998 0.031088 0.024691 0.039998 -0.024464 -0.042425 0.094998 -0.023232 -0.039448 0.108685 -0.021917 -0.046465 0.094998 -0.04153 -0.052157 0.049998 -0.181269 -0.046303 0.062916 -0.178326 -0.047357 0.0631 -0.178521 -0.023212 0.057998 -0.223803 -0.01974 0.062998 -0.221406 -0.022266 0.067998 -0.22315 -0.022773 0.062583 -0.026579 -0.013446 0.039998 -0.032316 -0.022774 0.039998 -0.02658 -0.053559 0.071121 -0.126929 -0.043426 0.062724 -0.146549 -0.042036 0.062669 -0.129234 -0.036206 0.081192 -0.010436 -0.034828 0.094998 0.00348899 -0.039489 0.094998 -0.011609 -0.01672 0.061015 -0.030618 -0.023114 0.062375 -0.02934 -0.028074 0.06254899999999999 -0.045339 -0.024835 0.062582 -0.221237 -0.022509 0.06329799999999999 -0.219383 -0.032237 0.061986 -0.222914 -0.016925 0.122882 -0.215977 -0.024551 0.126404 -0.21416 -0.013038 0.118998 -0.214307 0.029084 0.08015 -0.039744 0.029164 0.076123 -0.021844 0.025148 0.073194 -0.03896 -0.023212 0.057998 -0.223803 -0.0260095 0.060498 -0.226961 -0.028807 0.057998 -0.230119 -0.00653584 0.07414800000000001 -0.215794 -0.010009 0.07188899999999999 -0.216485 -0.00884017 0.067998 -0.216193 -0.008378999999999999 0.057998 -0.216018 -0.00653584 0.07414800000000001 -0.215794 -0.00884017 0.067998 -0.216193 -0.047357 0.0631 -0.178521 -0.046303 0.062916 -0.178326 -0.044694 0.06277199999999999 -0.163934 -0.019773 0.124949 -0.217628 -0.016925 0.122882 -0.215977 -0.00891 0.107254 -0.21306 0.036302 0.039998 -0.001659 0.036247 0.039998 0.000979986 0.024691 0.039998 -0.024464 -0.013985 0.076269 -0.204968 -0.012724 0.076705 -0.209545 -0.012034 0.082993 -0.209343 -2.99964e-06 0.0579979 -0.285001 -0.008378999999999999 0.057998 -0.283984 -1.99888e-06 0.131398 -0.285001 -0.00780799 0.12149 -0.163167 -0.000383994 0.116163 -0.150124 -0.003402 0.115569 -0.163868 -0.058675 0.08124099999999999 -0.234455 -0.052093 0.08112999999999999 -0.246067 -0.045077 0.06940499999999999 -0.241524 -0.033834 0.067998 -0.232697 -0.03788 0.067998 -0.246961 -0.0341418 0.067998 -0.239829 -0.055771 0.069714 -0.220433 -0.056939 0.07099800000000001 -0.220732 -0.052737 0.07099800000000001 -0.231787 0.028802 0.131398 -0.269883 0.023207 0.057998 -0.276199 0.023207 0.131398 -0.276199 -0.0253768 0.102998 -0.226247 -0.0249051 0.102998 -0.225714 -0.023212 0.131398 -0.223803 -0.0339658 0.102998 -0.25739 -0.0337375 0.117198 -0.258316 -0.0335584 0.102998 -0.259043 -0.033607 0.112586 -0.00902201 -0.035803 0.108542 -0.00859101 -0.034887 0.098269 0.00279799 -0.061464 0.07099800000000001 -0.209841 -0.062369 0.049998 -0.20209 -0.062369 0.07099800000000001 -0.20209 0.010922 0.062035 -0.036126 0.008237009999999999 0.061996 -0.053063 0.015328 0.06553 -0.054574 -0.0041905 0.117198 -0.21551 -1.99507e-06 0.131398 -0.215001 -0.008378999999999999 0.131398 -0.216018 -0.068758 0.118998 -0.233305 -0.054278 0.117226 -0.231933 -0.056969 0.113801 -0.232188 -0.010009 0.07188899999999999 -0.216485 -0.0090645 0.0746965 -0.215135 -0.009834000000000001 0.077057 -0.213119 -0.0249051 0.102998 -0.225714 -0.0253768 0.102998 -0.226247 -0.028859 0.102998 -0.225278 -0.008795000000000001 0.075515 -0.184517 -0.012316 0.08247400000000001 -0.198331 -0.007637 0.082319 -0.18461 -0.034747 0.0694588 -0.252902 -0.034747 0.057998 -0.25422 -0.034747 0.067998 -0.252601 -0.009834000000000001 0.077057 -0.213119 -0.012724 0.076705 -0.209545 -0.015534 0.07106700000000001 -0.210269 -0.0307675 0.117198 -0.266147 -0.032728 0.131398 -0.262412 -0.028807 0.131398 -0.269883 -0.034101 0.061824 -0.180269 -0.035603 0.049998 -0.179336 -0.031983 0.061887 -0.18193 0.025371 0.117444 -0.034582 0.020278 0.123345 -0.028527 0.022954 0.121125 -0.026485 0.016863 0.071426 -0.07238600000000001 0.021022 0.071631 -0.055785 0.015328 0.06553 -0.054574 0.035786 0.094414 -0.00581501 0.032223 0.082122 -0.02238 0.035788 0.09544 -0.00580301 -0.049958 0.126383 -0.187824 -0.047993 0.126464 -0.17232 -0.035318 0.129524 -0.173813 -0.000148996 0.095447 -0.16415 -0.003025 0.08194 -0.169916 -0.002018 0.095441 -0.169715 -0.029836 0.06207 -0.226616 -0.024636 0.067998 -0.221068 -0.027767 0.062132 -0.224056 -0.026849 0.060719 -0.132272 -0.03735 0.06260599999999999 -0.09519900000000001 -0.042036 0.062669 -0.129234 -0.034828 0.094998 0.00348899 -0.034048 0.039998 -0.008119009999999999 -0.03489 0.039998 0.00279899 0.008041009999999999 0.06154 -0.033737 0.00358101 0.060637 -0.034817 0.010922 0.062035 -0.036126 -0.054278 0.117226 -0.231933 -0.057071 0.107012 -0.239238 -0.056969 0.113801 -0.232188 -0.0299961 0.102998 -0.230342 -0.035087 0.102998 -0.235405 -0.028859 0.102998 -0.225278 -0.052157 0.049998 -0.181269 -0.052113 0.06517000000000001 -0.181323 -0.052941 0.065599 -0.181985 0.026925 0.09553 -0.064763 0.025389 0.079096 -0.056714 0.021367 0.07895099999999999 -0.07337299999999999 0.008373 0.057998 -0.216018 0.008374009999999999 0.131398 -0.216018 -1.99507e-06 0.131398 -0.215001 -0.013686 0.067998 -0.217787 -0.024636 0.067998 -0.221068 -0.0189327 0.067998 -0.219552 -0.026485 0.062779 -0.215759 -0.024362 0.063959 -0.21226 -0.024627 0.049998 -0.212797 -0.016268 0.131398 -0.280992 -0.023212 0.131398 -0.276199 -0.008378999999999999 0.131398 -0.283984 -0.00370299 0.062147 -0.102663 0.002578 0.065321 -0.104062 0.00428401 0.062021 -0.069631 -0.056918 0.108547 -0.108453 -0.062009 0.108246 -0.138661 -0.062363 0.094998 -0.125247 -0.07356699999999999 0.118998 -0.182532 -0.066541 0.1079 -0.181867 -0.072017 0.119053 -0.18233 0.011027 0.065356 -0.071107 0.016863 0.071426 -0.07238600000000001 0.015328 0.06553 -0.054574 -0.008378999999999999 0.057998 -0.216018 -0.00884017 0.067998 -0.216193 -0.0123235 0.0659771 -0.217514 0.021022 0.071631 -0.055785 0.016863 0.071426 -0.07238600000000001 0.021367 0.07895099999999999 -0.07337299999999999 -0.004483 0.095432 -0.177054 -0.003025 0.08194 -0.169916 -0.0049804 0.088686 -0.177374 -0.024551 0.126404 -0.21416 -0.027461 0.127109 -0.202655 -0.017449 0.120256 -0.202053 -0.062369 0.07099800000000001 -0.20209 -0.060239 0.049998 -0.194583 -0.060239 0.07099800000000001 -0.194583 -0.036116 0.111791 -0.261823 -0.0370101 0.109485 -0.262435 -0.034606 0.107636 -0.265703 -0.057231 0.049998 -0.190235 -0.055788 0.049998 -0.18586 -0.055699 0.06725100000000001 -0.185688 -0.00891 0.107254 -0.21306 -0.016925 0.122882 -0.215977 -0.009391 0.111495 -0.213179 -0.011576 0.095397 -0.209183 -0.00891 0.107254 -0.21306 -0.011532 0.107588 -0.210271 -0.0199652 0.0921587 -0.27844 -0.0214921 0.0925914 -0.277554 -0.017284 0.094997 -0.280436 -0.0269275 0.08767800000000001 -0.272574 -0.028807 0.0833648 -0.269883 -0.028931 0.094998 -0.27299 0.009158009999999999 0.110451 -0.122524 0.007499 0.095485 -0.139004 0.002111 0.10942 -0.150588 -0.07356699999999999 0.07099800000000001 -0.182532 -0.063614 0.07618 -0.181589 -0.066635 0.08205900000000001 -0.181875 -0.036792 0.125578 -0.240488 -0.037126 0.124813 -0.24216 -0.040037 0.124841 -0.23872 -0.036911 0.114414 -0.258801 -0.037904 0.118998 -0.252736 -0.036966 0.102998 -0.258815 -0.056918 0.108547 -0.108453 -0.049668 0.120374 -0.109996 -0.062009 0.108246 -0.138661 -0.0293392 0.067998 -0.268869 -0.0306243 0.067998 -0.26642 -0.0294052 0.0795941 -0.268743 -0.054764 0.094998 -0.083718 -0.056918 0.108547 -0.108453 -0.059351 0.094998 -0.107759 -0.048222 0.07156700000000001 -0.09278500000000001 -0.053559 0.071121 -0.126929 -0.042036 0.062669 -0.129234 0.009158009999999999 0.110451 -0.122524 0.023357 0.111167 -0.065049 0.020761 0.09553200000000001 -0.090212 -0.00468 0.07505100000000001 -0.169678 -0.006163 0.067844 -0.153244 -0.008943 0.068842 -0.169065 -0.017612 0.06343500000000001 -0.16783 -0.031735 0.06163 -0.165798 -0.021233 0.0636 -0.183487 -0.037626 0.123668 -0.244667 -0.037126 0.124813 -0.24216 -0.035081 0.127396 -0.235407 0.029163 0.09553 -0.05552 0.025389 0.079096 -0.056714 0.026925 0.09553 -0.064763 -0.028807 0.067998 -0.230119 -0.0301314 0.067998 -0.232642 -0.0307675 0.062998 -0.233855 -0.0280447 0.067998 -0.229259 -0.0260095 0.062998 -0.226961 -0.023212 0.067998 -0.223803 0.035503 0.137998 -0.00716101 0.033408 0.106873 -0.013307 0.032042 0.109598 -0.01583 0.001094 0.08108700000000001 -0.154548 -0.000148996 0.095447 -0.16415 0.002275 0.095455 -0.156935 -0.033834 0.067998 -0.232697 -0.0301314 0.067998 -0.232642 -0.028807 0.067998 -0.230119 -0.0282288 0.102997 -0.270536 -0.028807 0.131398 -0.269883 -0.0266445 0.102997 -0.272324 0.020278 0.123345 -0.028527 0.020104 0.123114 -0.033553 0.018147 0.12471 -0.029694 -0.057071 0.107012 -0.239238 -0.052437 0.107055 -0.246859 -0.054341 0.094998 -0.247534 0.021367 0.07895099999999999 -0.07337299999999999 0.012978 0.078932 -0.106368 0.0188977 0.087232 -0.0903089 0.008373 0.057998 -0.283984 -2.99964e-06 0.0579979 -0.285001 -1.99888e-06 0.131398 -0.285001 -0.010127 0.060008 -0.049157 -0.0137 0.060008 -0.065689 0.00428401 0.062021 -0.069631 -0.003516 0.066757 -0.136938 0.00173001 0.072867 -0.137987 0.002578 0.065321 -0.104062 -0.06689290000000001 0.08831550000000001 -0.170419 -0.0662321 0.0849767 -0.170419 -0.064813 0.081788 -0.16105 0.016263 0.131398 -0.21901 0.023207 0.057998 -0.223803 0.023207 0.131398 -0.223803 -0.050569 0.06436799999999999 -0.180088 -0.044694 0.06277199999999999 -0.163934 -0.052113 0.06517000000000001 -0.181323 -0.010933 0.121115 -0.176687 -0.022363 0.127685 -0.17534 -0.00780799 0.12149 -0.163167 -0.00812 0.074265 -0.215957 -0.00653584 0.07414800000000001 -0.215794 -0.00614141 0.07561610000000001 -0.215678 0.024691 0.039998 -0.024464 0.008115010000000001 0.039998 -0.034047 0.018239 0.039998 -0.029872 -0.038989 0.129258 -0.203352 -0.050376 0.126442 -0.204039 -0.037903 0.12941 -0.1884 -0.034819 0.062778 -0.23491 -0.042758 0.0669136 -0.23641 -0.045077 0.06940499999999999 -0.241524 -0.0333971 0.067998 -0.259697 -0.034325 0.067998 -0.255932 -0.0337503 0.0725065 -0.258264 -0.07356699999999999 0.07099800000000001 -0.182532 -0.05443 0.07099800000000001 -0.227973 -0.055897 0.07099800000000001 -0.224066 -0.046949 0.107107 -0.253978 -0.037626 0.117517 -0.254781 -0.040674 0.10718 -0.260584 0.027925 0.07441300000000001 -0.021615 0.019976 0.067373 -0.037929 0.029164 0.076123 -0.021844 0.002111 0.10942 -0.150588 0.007499 0.095485 -0.139004 0.003933 0.09546499999999999 -0.151245 0.035752 0.093403 -0.00599601 0.036247 0.039998 0.000979986 0.035596 0.0915 -0.00674901 -0.010933 0.121115 -0.176687 -0.00780799 0.12149 -0.163167 -0.003402 0.115569 -0.163868 -0.032964 0.102998 -0.268909 -0.036966 0.102998 -0.258815 -0.0330778 0.102998 -0.263984 -0.034747 0.131398 -0.245782 -0.034747 0.117198 -0.250001 -0.034747 0.102998 -0.249047 -0.012724 0.076705 -0.209545 -0.017073 0.070427 -0.205294 -0.015534 0.07106700000000001 -0.210269 -0.040722 0.08209 -0.025833 -0.042425 0.094998 -0.023232 -0.044547 0.08257 -0.041831 -0.046622 0.126471 -0.220648 -0.050376 0.126442 -0.204039 -0.0530965 0.122945 -0.213171 -0.008943 0.068842 -0.169065 -0.017612 0.06343500000000001 -0.16783 -0.012684 0.069286 -0.184201 -0.023212 0.057998 -0.223803 -2.99964e-06 0.0579979 -0.285001 -0.016268 0.057998 -0.21901 -0.032728 0.131398 -0.262412 -0.032728 0.102998 -0.262412 -0.0337375 0.117198 -0.258316 -0.0307675 0.117198 -0.233855 -0.0317456 0.102998 -0.235718 -0.0314748 0.102998 -0.235202 -0.035087 0.102998 -0.235405 -0.0303241 0.102998 -0.23301 -0.0314748 0.102998 -0.235202 -0.065009 0.111448 -0.181721 -0.058648 0.118944 -0.171066 -0.061919 0.116225 -0.181428 0.002578 0.065321 -0.104062 0.00173001 0.072867 -0.137987 0.008484 0.07136099999999999 -0.105372 0.00667102 0.137998 0.035573 0.00667501 0.039998 0.035572 0.012177 0.137998 0.0342 -0.066541 0.1079 -0.181867 -0.058648 0.118944 -0.171066 -0.065009 0.111448 -0.181721 0.031876 0.080175 -0.016158 0.035402 0.039998 -0.00747301 0.031544 0.039998 -0.016125 -0.0282288 0.102997 -0.270536 -0.0266445 0.102997 -0.272324 -0.028332 0.102997 -0.27231 -0.0144225 0.102998 -0.21831 -0.012538 0.102998 -0.217595 -0.0123235 0.117198 -0.217514 -0.0349329 0.102998 -0.241309 -0.03788 0.102998 -0.246961 -0.035087 0.102998 -0.235405 -0.034747 0.057998 -0.25422 -0.0337375 0.0617524 -0.258316 -0.032728 0.057998 -0.262412 -0.0303241 0.102998 -0.23301 -0.0307675 0.117198 -0.233855 -0.0314748 0.102998 -0.235202 -0.02251 0.06550499999999999 -0.20529 -0.022497 0.049998 -0.20529 -0.024627 0.049998 -0.212797 -0.055897 0.07099800000000001 -0.224066 -0.05443 0.07099800000000001 -0.227973 -0.052737 0.07099800000000001 -0.231787 -0.027461 0.127109 -0.202655 -0.014708 0.120982 -0.189504 -0.017449 0.120256 -0.202053 -0.024636 0.067998 -0.221068 -0.0196111 0.067998 -0.221317 -0.0189327 0.067998 -0.219552 -0.0423461 0.119877 -0.245385 -0.047488 0.117421 -0.24361 -0.042263 0.117494 -0.250094 -0.039489 0.094998 -0.011609 -0.034828 0.094998 0.00348899 -0.035803 0.108542 -0.00859101 -0.024362 0.063959 -0.21226 -0.02251 0.06550499999999999 -0.20529 -0.024627 0.049998 -0.212797 -0.01974 0.062998 -0.221406 -0.0197401 0.060498 -0.221406 -0.016268 0.057998 -0.21901 -0.044452 0.126287 -0.226534 -0.047487 0.124698 -0.226704 -0.046622 0.126471 -0.220648 -0.0120057 0.102998 -0.216492 -0.008378999999999999 0.102998 -0.216018 -0.0114314 0.102998 -0.217176 -0.013446 0.039998 -0.032316 -0.01672 0.061015 -0.030618 -0.013388 0.060519 -0.03217 0.025406 0.118766 -0.024322 0.024691 0.137998 -0.024464 0.031545 0.137998 -0.016125 0.021022 0.071631 -0.055785 0.025389 0.079096 -0.056714 0.025148 0.073194 -0.03896 -0.029338 0.061197 -0.149079 -0.026849 0.060719 -0.132272 -0.042036 0.062669 -0.129234 -0.041251 0.062174 -0.1779 -0.041233 0.049998 -0.177738 -0.038327 0.061912 -0.178263 -0.00675999 0.115159 -0.17718 -0.010933 0.121115 -0.176687 -0.003402 0.115569 -0.163868 -0.039448 0.108685 -0.021917 -0.030235 0.12028 -0.017474 -0.031887 0.120562 -0.023395 0.024691 0.039998 -0.024464 0.017841 0.039998 0.031751 0.012176 0.039998 0.0342 -0.040722 0.08209 -0.025833 -0.036206 0.081192 -0.010436 -0.039489 0.094998 -0.011609 -0.022363 0.127685 -0.17534 -0.037903 0.12941 -0.1884 -0.035318 0.129524 -0.173813 -0.033143 0.062024 -0.221268 -0.036282 0.049998 -0.22272 -0.036328 0.062118 -0.222573 -0.021233 0.0636 -0.183487 -0.031983 0.061887 -0.18193 -0.031137 0.061966 -0.183063 0.029163 0.09553 -0.05552 0.026925 0.09553 -0.064763 0.023357 0.111167 -0.065049 -0.032237 0.061986 -0.222914 -0.022509 0.06329799999999999 -0.219383 -0.033143 0.062024 -0.221268 -0.017284 0.094997 -0.280436 -0.0214921 0.0925914 -0.277554 -0.025963 0.094998 -0.2751 -0.048222 0.07156700000000001 -0.09278500000000001 -0.047727 0.082469 -0.058234 -0.054037 0.08229 -0.091492 -0.024636 0.067998 -0.221068 -0.015557 0.067998 -0.215638 -0.024835 0.062582 -0.221237 -0.034747 0.057998 -0.25422 -0.034747 0.0637284 -0.250001 -0.034747 0.067998 -0.252601 0.020761 0.09553200000000001 -0.090212 0.021367 0.07895099999999999 -0.07337299999999999 0.0188977 0.087232 -0.0903089 -0.031908 0.128859 -0.223879 -0.025378 0.127937 -0.221716 -0.022862 0.12675 -0.219763 -0.069103 0.094998 -0.18211 -0.06864199999999999 0.100682 -0.182065 -0.07356699999999999 0.118998 -0.182532 -0.047047 0.049998 -0.178417 -0.042891 0.06232 -0.177697 -0.046303 0.062916 -0.178326 -0.032964 0.102998 -0.268909 -0.030964 0.102997 -0.270424 -0.028931 0.094998 -0.27299 -0.044547 0.08257 -0.041831 -0.042425 0.094998 -0.023232 -0.046465 0.094998 -0.04153 -0.0217294 0.0679979 -0.277222 -0.023212 0.057998 -0.276199 -0.0254514 0.0873768 -0.273671 -0.03788 0.067998 -0.246961 -0.045077 0.06940499999999999 -0.241524 -0.036481 0.067998 -0.249142 -0.061713 0.101573 -0.232638 -0.068758 0.118998 -0.233305 -0.059939 0.107883 -0.232469 -0.0028281 0.0782692 -0.215344 -0.005627 0.08337899999999999 -0.215459 -0.0047623 0.07911310000000001 -0.215472 0.010685 0.062075 -0.033096 0.010922 0.062035 -0.036126 0.020278 0.06684 -0.028527 -0.019807 0.102998 -0.21757 -0.008815999999999999 0.10605 -0.213038 -0.008815999999999999 0.102998 -0.213038 -0.0269275 0.08767800000000001 -0.272574 -0.028931 0.094998 -0.27299 -0.025963 0.094998 -0.2751 -0.0337375 0.060498 -0.241686 -0.0337375 0.062998 -0.241686 -0.034747 0.057998 -0.245782 -0.034747 0.131398 -0.245782 -0.0337375 0.117198 -0.241686 -0.032728 0.131398 -0.23759 -0.020283 0.039998 0.028524 -0.008135979999999999 0.137998 0.034439 -0.020283 0.137998 0.028524 -0.0320424 0.0768882 -0.263718 -0.029842 0.080358 -0.268227 -0.0294052 0.0795941 -0.268743 -0.028074 0.06254899999999999 -0.045339 -0.034356 0.071198 -0.0271 -0.039228 0.072168 -0.042965 0.024691 0.039998 -0.024464 0.031544 0.039998 -0.016125 0.033809 0.039998 -0.012393 -0.023212 0.102998 -0.223803 -0.028859 0.102998 -0.225278 -0.0216408 0.102998 -0.221424 -0.058648 0.118944 -0.171066 -0.059219 0.119502 -0.181032 -0.061919 0.116225 -0.181428 -0.034819 0.062778 -0.23491 -0.041227 0.062847 -0.226878 -0.051395 0.069561 -0.231297 -0.00812 0.074265 -0.215957 -0.00614141 0.07561610000000001 -0.215678 -0.006693 0.077352 -0.215648 -0.032237 0.061986 -0.222914 -0.029836 0.06207 -0.226616 -0.027767 0.062132 -0.224056 0.008373 0.057998 -0.216018 -2.99964e-06 0.0579979 -0.285001 0.016263 0.057998 -0.21901 0.029418 0.110682 -0.035372 0.023357 0.111167 -0.065049 0.019315 0.118087 -0.06417299999999999 -0.0439799 0.120915 -0.241308 -0.0430425 0.123603 -0.236991 -0.0456132 0.12173 -0.237229 -0.057094 0.07038999999999999 -0.162155 -0.044694 0.06277199999999999 -0.163934 -0.05547 0.07073400000000001 -0.144385 -0.0249051 0.102998 -0.225714 -0.0243759 0.102998 -0.225117 -0.023212 0.131398 -0.223803 0.035016 0.08812399999999999 -0.009014019999999999 0.03541 0.090421 -0.00747301 0.035402 0.039998 -0.00747301 -0.006163 0.067844 -0.153244 -0.014243 0.063067 -0.151789 -0.008943 0.068842 -0.169065 0.00427813 0.156998 0.0315094 0.00965825 0.156998 0.0303153 -0.00119713 0.156998 0.0311578 -0.0130552 0.1825 -0.28405 -0.013446 0.137997 -0.282316 -0.022774 0.182497 -0.27658 0.0269129 0.189497 -0.240452 -0.0358064 0.189498 -0.229342 0.0220503 0.189497 -0.231162 -0.0358064 0.189498 -0.229342 0.0269129 0.189497 -0.240452 0.0277921 0.189497 -0.252355 0.023298 0.137998 0.028256 0.027792 0.137998 0.024268 0.0249496 0.149998 0.0267196 0.0237806 0.156998 0.0198468 0.0319824 0.149998 0.018322 0.0255505 0.156998 0.0156854 0.034044 0.137997 -0.241883 -0.044946 0.137998 -0.226035 0.034886 0.137997 -0.252801 -0.0360055 0.189134 -0.179117 -0.0477357 0.189498 -0.184157 -0.0298779 0.188468 -0.161935 -0.011002 0.137998 -0.216775 -0.011002 0.182498 -0.216775 -0.0156101 0.182498 -0.203355 -0.044946 0.137998 -0.226035 -0.056865 0.137998 -0.17605 -0.044946 0.182498 -0.226035 0.017841 0.137998 0.03175 0.0171507 0.15 0.0321037 0.012177 0.137998 0.0342 0.00982823 0.189497 -0.277838 0.018239 0.182497 -0.279871 -0.00345781 0.189497 -0.281249 -0.0201871 0.149998 -0.122778 -0.019649 0.149998 -0.119943 -0.019649 0.137998 -0.119943 -0.0578833 0.182498 -0.162331 -0.058044 0.175225 -0.157039 -0.050628 0.177738 -0.148859 -0.039966 0.149998 -0.060476 -0.0363383 0.156998 -0.073647 -0.0460505 0.149998 -0.08283790000000001 -0.0277696 0.189498 -0.250156 -0.0358064 0.189498 -0.229342 0.0277921 0.189497 -0.252355 -0.00119713 0.156998 0.0311578 -0.00326398 0.15 0.035671 0.00176102 0.15 0.036001 -0.055576 0.149998 -0.118356 -0.0476516 0.156998 -0.115832 -0.0555759 0.151393 -0.127995 -0.0169633 0.156998 -0.0808022 0.00443301 0.149998 -0.050197 -0.011306 0.149998 -0.08529399999999999 0.0169921 0.156998 0.0254633 0.0120559 0.156998 0.028325 0.0249496 0.149998 0.0267196 0.02277 0.137997 -0.223422 0.029869 0.182497 -0.23176 0.02277 0.182497 -0.223422 -0.034047 0.137998 -0.258119 -0.034047 0.182498 -0.258119 -0.029873 0.137998 -0.268242 -0.00326398 0.15 0.035671 -0.008135979999999999 0.137998 0.034439 0.00176102 0.15 0.036001 0.034886 0.182497 -0.252801 0.034044 0.182497 -0.241883 0.034044 0.137997 -0.241883 0.0281997 0.156998 0.00854457 -0.0225231 0.156998 0.0155764 0.0255505 0.156998 0.0156854 0.0342069 0.149998 0.0132172 0.0281997 0.156998 0.00854457 0.0255505 0.156998 0.0156854 0.02797 0.149998 -0.021651 0.0313327 0.149998 -0.0171439 0.031545 0.137998 -0.016125 -0.0115818 0.149998 0.0333791 -0.020283 0.149998 0.028524 -0.020283 0.137998 0.028524 -0.0501208 0.189241 -0.172523 -0.0508655 0.189241 -0.162856 -0.0298779 0.188468 -0.161935 -0.0201871 0.149998 -0.122778 -0.019649 0.137998 -0.119943 -0.022928 0.178374 -0.160795 -0.0242753 0.189498 -0.196308 -0.0219334 0.182498 -0.168339 -0.0156101 0.182498 -0.203355 -0.0220408 0.189497 -0.268871 -0.0298721 0.182497 -0.268242 -0.0269619 0.189498 -0.258688 -0.0273992 0.156998 -0.123236 -0.050628 0.177738 -0.148859 -0.0493451 0.156998 -0.124141 -0.044946 0.182498 -0.226035 -0.0358064 0.189498 -0.229342 -0.0363225 0.182498 -0.24537 -0.002802 0.137997 -0.284889 0.008116 0.137997 -0.284047 -0.013446 0.137997 -0.282316 0.0244819 0.189497 -0.262816 0.034886 0.182497 -0.252801 0.032313 0.182497 -0.263445 -0.032318 0.137998 0.013442 -0.031163 0.149998 0.015936 -0.0325361 0.149998 0.011096 0.0363095 0.149998 0.00153579 0.036247 0.137998 0.0009799819999999999 0.0361584 0.149998 -0.00332059 0.0190888 0.137992 -0.0323898 0.00443301 0.149998 -0.050197 0.02797 0.137998 -0.021651 -0.022692 0.149998 0.026648 -0.026582 0.137998 0.02277 -0.020283 0.149998 0.028524 0.026577 0.182497 -0.272773 0.032313 0.182497 -0.263445 0.032313 0.137997 -0.263445 0.00965825 0.156998 0.0303153 0.0120559 0.156998 0.028325 -0.00119713 0.156998 0.0311578 0.0337698 0.149998 -0.0124852 0.035503 0.137998 -0.00716101 0.031545 0.137998 -0.016125 0.0208184 0.156998 0.0230108 0.0237806 0.156998 0.0198468 -0.0117197 0.156998 0.0263204 0.00965825 0.156998 0.0303153 0.0171507 0.15 0.0321037 0.0203086 0.149998 0.0302513 0.018239 0.137997 -0.279871 0.026577 0.137997 -0.272773 -0.022774 0.137997 -0.27658 0.013442 0.182498 -0.217686 0.02277 0.182497 -0.223422 0.0117258 0.189497 -0.221248 0.0120559 0.156998 0.028325 0.00965825 0.156998 0.0303153 0.0203086 0.149998 0.0302513 -0.0267148 0.156998 -0.119631 -0.0273992 0.156998 -0.123236 -0.0476516 0.156998 -0.115832 -0.0570253 0.182498 -0.173467 -0.058044 0.137998 -0.157039 -0.0578833 0.182498 -0.162331 -0.055576 0.137998 -0.118356 -0.055576 0.149998 -0.118356 -0.0555759 0.151393 -0.127995 -0.0203749 0.156998 -0.0947291 -0.0363383 0.156998 -0.073647 -0.0169633 0.156998 -0.0808022 -0.019649 0.149998 -0.119943 -0.0273992 0.156998 -0.123236 -0.0267148 0.156998 -0.119631 -0.039966 0.149998 -0.060476 -0.0267758 0.156998 -0.0210155 -0.0324414 0.156998 -0.0576595 -0.033792 0.137998 -0.020934 -0.034752 0.149998 -0.00418302 -0.033792 0.149998 -0.020934 0.0342069 0.149998 0.0132172 0.0357745 0.149998 0.0069537 0.0281997 0.156998 0.00854457 0.013442 0.137998 -0.217686 -0.011002 0.137998 -0.216775 0.02277 0.137997 -0.223422 0.0267455 0.156998 -0.0116438 0.0337698 0.149998 -0.0124852 0.0242157 0.156998 -0.0156431 -0.015277 0.149998 -0.102992 -0.0163071 0.153035 -0.094143 -0.011306 0.149998 -0.08529399999999999 -0.022774 0.137997 -0.27658 0.026577 0.137997 -0.272773 -0.029873 0.137998 -0.268242 -0.015277 0.137998 -0.102992 -0.015277 0.149998 -0.102992 -0.011306 0.137998 -0.08529399999999999 -0.0201871 0.149998 -0.122778 -0.022928 0.178374 -0.160795 -0.0299282 0.186882 -0.160046 -0.039966 0.137998 -0.060476 0.00443301 0.137998 -0.050197 -0.00280198 0.137998 -0.034889 -0.011306 0.137998 -0.08529399999999999 -0.011306 0.149998 -0.08529399999999999 0.00443301 0.137998 -0.050197 -0.022835 0.179996 -0.162726 -0.016335 0.137998 -0.201244 -0.0219334 0.182498 -0.168339 -0.022774 0.182497 -0.27658 -0.022774 0.137997 -0.27658 -0.0298721 0.182497 -0.268242 -0.011002 0.182498 -0.216775 0.001314 0.182498 -0.215228 -0.000783752 0.189498 -0.217156 -0.0267758 0.156998 -0.0210155 -0.00112887 0.156998 -0.0459391 -0.0324414 0.156998 -0.0576595 0.001314 0.182498 -0.215228 0.013442 0.182498 -0.217686 -0.000783752 0.189498 -0.217156 -0.055576 0.137998 -0.118356 -0.0460505 0.149998 -0.08283790000000001 -0.055576 0.149998 -0.118356 -0.0163071 0.153035 -0.094143 -0.0203749 0.156998 -0.0947291 -0.011306 0.149998 -0.08529399999999999 0.02277 0.137997 -0.223422 0.029869 0.137997 -0.231759 0.029869 0.182497 -0.23176 -0.0130552 0.1825 -0.28405 -0.022774 0.182497 -0.27658 -0.0132689 0.189497 -0.276947 -0.0277696 0.189498 -0.250156 0.0277921 0.189497 -0.252355 0.0244819 0.189497 -0.262816 -0.026582 0.137998 0.02277 -0.022692 0.149998 0.026648 -0.031163 0.149998 0.015936 0.0165033 0.189497 -0.22686 -0.0144049 0.1895 -0.218377 0.0117258 0.189497 -0.221248 -0.00812 0.137998 -0.215956 0.013442 0.137998 -0.217686 0.00279801 0.137998 -0.215114 -0.033792 0.149998 -0.020934 -0.039966 0.149998 -0.060476 -0.039966 0.137998 -0.060476 0.0319824 0.149998 0.018322 0.0237806 0.156998 0.0198468 0.0296546 0.149998 0.0221127 0.00982823 0.189497 -0.277838 -0.00345781 0.189497 -0.281249 -0.0132689 0.189497 -0.276947 -0.0238631 0.156998 -0.108253 -0.0203749 0.156998 -0.0947291 -0.0190544 0.154031 -0.101491 -0.0098446 0.156998 0.0277807 0.0169921 0.156998 0.0254633 -0.0117197 0.156998 0.0263204 -0.034047 0.137998 -0.258119 -0.0363225 0.182498 -0.24537 -0.034047 0.182498 -0.258119 -0.0277696 0.189498 -0.250156 -0.0269619 0.189498 -0.258688 -0.034047 0.182498 -0.258119 -0.0508655 0.189241 -0.162856 -0.050628 0.177738 -0.148859 -0.0298779 0.188468 -0.161935 -0.019649 0.137998 -0.119943 -0.055576 0.137998 -0.118356 -0.058044 0.137998 -0.157039 0.0171507 0.15 0.0321037 0.0118795 0.149998 0.0342979 0.012177 0.137998 0.0342 -0.029873 0.137998 -0.018243 -0.033792 0.137998 -0.020934 -0.022774 0.137998 -0.02658 -0.058044 0.175225 -0.157039 -0.0567022 0.153255 -0.130855 -0.0493451 0.156998 -0.124141 0.0291131 0.156998 0.00354524 0.0363095 0.149998 0.00153579 0.0291522 0.156998 -0.00266303 0.034981 0.137998 0.010695 0.0357745 0.149998 0.0069537 0.0342069 0.149998 0.0132172 0.02277 0.182497 -0.223422 0.0165033 0.189497 -0.22686 0.0117258 0.189497 -0.221248 0.026577 0.137997 -0.272773 0.032313 0.137997 -0.263445 -0.029873 0.137998 -0.268242 -0.011002 0.137998 -0.216775 -0.00812 0.137998 -0.215956 -0.011002 0.182498 -0.216775 0.029869 0.137997 -0.231759 -0.044946 0.137998 -0.226035 0.034044 0.137997 -0.241883 0.0291522 0.156998 -0.00266303 0.0363095 0.149998 0.00153579 0.0361584 0.149998 -0.00332059 -0.022928 0.137998 -0.160794 -0.016335 0.137998 -0.201244 -0.022835 0.179996 -0.162726 -0.033792 0.137998 -0.020934 -0.033792 0.149998 -0.020934 -0.039966 0.137998 -0.060476 -0.008135979999999999 0.137998 0.034439 0.00116802 0.137998 0.036003 0.00176102 0.15 0.036001 0.02797 0.149998 -0.021651 0.00443301 0.149998 -0.050197 -0.00112887 0.156998 -0.0459391 -0.022835 0.179996 -0.162726 -0.0219334 0.182498 -0.168339 -0.0298779 0.188468 -0.161935 -0.016335 0.137998 -0.201244 -0.011002 0.137998 -0.216775 -0.0156101 0.182498 -0.203355 -0.022692 0.149998 0.026648 -0.0098446 0.156998 0.0277807 -0.0117197 0.156998 0.0263204 0.0182026 0.184286 -0.277552 0.018239 0.182497 -0.279871 0.00982823 0.189497 -0.277838 0.0171507 0.15 0.0321037 0.00965825 0.156998 0.0303153 0.00427813 0.156998 0.0315094 -0.022774 0.182497 -0.27658 -0.0298721 0.182497 -0.268242 -0.0243837 0.184358 -0.272411 -0.00345781 0.189497 -0.281249 0.008116 0.182497 -0.28405 -0.001318 0.1825 -0.284775 -0.0201871 0.149998 -0.122778 -0.0273992 0.156998 -0.123236 -0.019649 0.149998 -0.119943 -0.0219334 0.182498 -0.168339 -0.0242753 0.189498 -0.196308 -0.0298779 0.188468 -0.161935 -0.0324414 0.156998 -0.0576595 -0.00112887 0.156998 -0.0459391 -0.0363383 0.156998 -0.073647 -0.015277 0.149998 -0.102992 -0.0238631 0.156998 -0.108253 -0.0190544 0.154031 -0.101491 0.018239 0.182497 -0.279871 0.026577 0.182497 -0.272773 0.026577 0.137997 -0.272773 -0.0477357 0.189498 -0.184157 -0.0570253 0.182498 -0.173467 -0.0501208 0.189241 -0.172523 -0.050628 0.177738 -0.148859 -0.0299282 0.186882 -0.160046 -0.0298779 0.188468 -0.161935 0.00443301 0.149998 -0.050197 0.02797 0.149998 -0.021651 0.02797 0.137998 -0.021651 0.00116802 0.137998 0.036003 0.00747002 0.15 0.035384 0.00176102 0.15 0.036001 0.02277 0.182497 -0.223422 0.029869 0.182497 -0.23176 0.0165033 0.189497 -0.22686 0.0208184 0.156998 0.0230108 0.0169921 0.156998 0.0254633 0.0249496 0.149998 0.0267196 -0.013446 0.137997 -0.282316 0.018239 0.137997 -0.279871 -0.022774 0.137997 -0.27658 0.0120559 0.156998 0.028325 -0.0098446 0.156998 0.0277807 -0.00119713 0.156998 0.0311578 -0.0325361 0.149998 0.011096 -0.031163 0.149998 0.015936 -0.0225231 0.156998 0.0155764 -0.011306 0.149998 -0.08529399999999999 0.00443301 0.149998 -0.050197 0.00443301 0.137998 -0.050197 -0.011002 0.182498 -0.216775 -0.00812 0.137998 -0.215956 0.001314 0.182498 -0.215228 -0.056865 0.137998 -0.17605 -0.011002 0.137998 -0.216775 -0.016335 0.137998 -0.201244 -0.0267758 0.156998 -0.0210155 -0.0277409 0.156998 -0.0046775 0.0208539 0.156998 -0.0194829 -0.0203749 0.156998 -0.0947291 -0.0163071 0.153035 -0.094143 -0.015277 0.149998 -0.102992 -0.044946 0.137998 -0.226035 -0.011002 0.137998 -0.216775 -0.056865 0.137998 -0.17605 0.029869 0.182497 -0.23176 0.029869 0.137997 -0.231759 0.034044 0.182497 -0.241883 -0.015277 0.137998 -0.102992 -0.011306 0.137998 -0.08529399999999999 -0.039966 0.137998 -0.060476 0.0277921 0.189497 -0.252355 0.034044 0.182497 -0.241883 0.034886 0.182497 -0.252801 0.024691 0.137998 -0.024464 0.02797 0.137998 -0.021651 0.031545 0.137998 -0.016125 -0.0269619 0.189498 -0.258688 0.0244819 0.189497 -0.262816 0.0167086 0.189497 -0.271981 -0.039966 0.137998 -0.060476 -0.0177665 0.137998 -0.0677455 0.00443301 0.137998 -0.050197 -0.0358064 0.189498 -0.229342 -0.0216497 0.1895 -0.20732 -0.0144049 0.1895 -0.218377 0.0342069 0.149998 0.0132172 0.031112 0.137998 0.019976 0.033206 0.137998 0.014953 0.00427813 0.156998 0.0315094 -0.00119713 0.156998 0.0311578 0.00176102 0.15 0.036001 0.0277585 0.156998 -0.00777409 0.0361584 0.149998 -0.00332059 0.034653 0.149998 -0.009078019999999999 -0.0477357 0.189498 -0.184157 -0.0501208 0.189241 -0.172523 -0.0298779 0.188468 -0.161935 -0.019649 0.149998 -0.119943 -0.0267148 0.156998 -0.119631 -0.0238631 0.156998 -0.108253 0.0313327 0.149998 -0.0171439 0.0337698 0.149998 -0.0124852 0.031545 0.137998 -0.016125 -0.034966 0.137998 -0.248412 -0.034047 0.137998 -0.258119 0.032313 0.137997 -0.263445 -0.00345781 0.189497 -0.281249 -0.001318 0.1825 -0.284775 -0.0130552 0.1825 -0.28405 -0.0225231 0.156998 0.0155764 -0.0276409 0.156998 0.00270343 -0.03489 0.149998 0.00279898 0.0319824 0.149998 0.018322 0.031112 0.137998 0.019976 0.0342069 0.149998 0.0132172 -0.0144049 0.1895 -0.218377 -0.000783752 0.189498 -0.217156 0.0117258 0.189497 -0.221248 -0.022928 0.178374 -0.160795 -0.022835 0.179996 -0.162726 -0.0298779 0.188468 -0.161935 -0.055576 0.149998 -0.118356 -0.0363383 0.156998 -0.073647 -0.0476516 0.156998 -0.115832 -0.011306 0.137998 -0.08529399999999999 -0.0177665 0.137998 -0.0677455 -0.039966 0.137998 -0.060476 -0.0277409 0.156998 -0.0046775 -0.0276409 0.156998 0.00270343 0.0277585 0.156998 -0.00777409 -0.0144049 0.1895 -0.218377 -0.011002 0.182498 -0.216775 -0.000783752 0.189498 -0.217156 0.0167086 0.189497 -0.271981 0.0244819 0.189497 -0.262816 0.032313 0.182497 -0.263445 0.024691 0.137998 -0.024464 0.0190888 0.137992 -0.0323898 0.02797 0.137998 -0.021651 0.032313 0.137997 -0.263445 -0.034047 0.137998 -0.258119 -0.029873 0.137998 -0.268242 -0.0242753 0.189498 -0.196308 -0.0360055 0.189134 -0.179117 -0.0298779 0.188468 -0.161935 -0.0130552 0.1825 -0.28405 -0.002802 0.137997 -0.284889 -0.013446 0.137997 -0.282316 -0.044946 0.182498 -0.226035 -0.0389066 0.189498 -0.221183 -0.0358064 0.189498 -0.229342 0.036247 0.137998 0.0009799819999999999 0.035503 0.137998 -0.00716101 0.0361584 0.149998 -0.00332059 0.034981 0.137998 0.010695 0.0342069 0.149998 0.0132172 0.033206 0.137998 0.014953 0.02797 0.149998 -0.021651 -0.00112887 0.156998 -0.0459391 0.0208539 0.156998 -0.0194829 -0.00812 0.137998 -0.215956 0.00279801 0.137998 -0.215114 0.001314 0.182498 -0.215228 -0.0358064 0.189498 -0.229342 0.0165033 0.189497 -0.22686 0.0220503 0.189497 -0.231162 -0.031163 0.149998 0.015936 -0.0117197 0.156998 0.0263204 -0.0225231 0.156998 0.0155764 0.00747002 0.15 0.035384 0.0118795 0.149998 0.0342979 0.00427813 0.156998 0.0315094 0.026577 0.182497 -0.272773 0.0167086 0.189497 -0.271981 0.032313 0.182497 -0.263445 -0.033792 0.137998 -0.020934 -0.034752 0.137998 -0.00418302 -0.034752 0.149998 -0.00418302 0.034886 0.137997 -0.252801 -0.034966 0.137998 -0.248412 0.032313 0.137997 -0.263445 0.026577 0.182497 -0.272773 0.0182026 0.184286 -0.277552 0.00982823 0.189497 -0.277838 0.0269129 0.189497 -0.240452 0.029869 0.182497 -0.23176 0.034044 0.182497 -0.241883 -0.0177665 0.137998 -0.0677455 -0.011306 0.137998 -0.08529399999999999 0.00443301 0.137998 -0.050197 0.0296546 0.149998 0.0221127 0.027792 0.137998 0.024268 0.031112 0.137998 0.019976 -0.0570253 0.182498 -0.173467 -0.056865 0.137998 -0.17605 -0.058044 0.137998 -0.157039 -0.034966 0.137998 -0.248412 -0.0363225 0.182498 -0.24537 -0.034047 0.137998 -0.258119 -0.0216497 0.1895 -0.20732 -0.011002 0.182498 -0.216775 -0.0144049 0.1895 -0.218377 -0.0277409 0.156998 -0.0046775 0.0242157 0.156998 -0.0156431 0.0208539 0.156998 -0.0194829 -0.031163 0.149998 0.015936 -0.022692 0.149998 0.026648 -0.0117197 0.156998 0.0263204 -0.050628 0.177738 -0.148859 -0.0273992 0.156998 -0.123236 -0.0299282 0.186882 -0.160046 0.0361584 0.149998 -0.00332059 0.035503 0.137998 -0.00716101 0.034653 0.149998 -0.009078019999999999 -0.0299282 0.186882 -0.160046 -0.022928 0.178374 -0.160795 -0.0298779 0.188468 -0.161935 -0.022774 0.137998 -0.02658 -0.039966 0.137998 -0.060476 -0.013446 0.137998 -0.032316 -0.0203749 0.156998 -0.0947291 -0.0169633 0.156998 -0.0808022 -0.011306 0.149998 -0.08529399999999999 -0.034752 0.137998 -0.00418302 -0.03489 0.137998 0.00279898 -0.03489 0.149998 0.00279898 0.026577 0.182497 -0.272773 0.018239 0.182497 -0.279871 0.0182026 0.184286 -0.277552 -0.0570253 0.182498 -0.173467 -0.0578833 0.182498 -0.162331 -0.0508655 0.189241 -0.162856 0.0319824 0.149998 0.018322 0.0296546 0.149998 0.0221127 0.031112 0.137998 0.019976 -0.0203749 0.156998 -0.0947291 -0.015277 0.149998 -0.102992 -0.0190544 0.154031 -0.101491 -0.00345781 0.189497 -0.281249 -0.0130552 0.1825 -0.28405 -0.0132689 0.189497 -0.276947 -0.034047 0.182498 -0.258119 -0.0298721 0.182497 -0.268242 -0.029873 0.137998 -0.268242 0.00747002 0.15 0.035384 0.00667102 0.137998 0.035573 0.0118795 0.149998 0.0342979 0.034044 0.182497 -0.241883 0.029869 0.137997 -0.231759 0.034044 0.137997 -0.241883 0.0208539 0.156998 -0.0194829 0.0242157 0.156998 -0.0156431 0.0313327 0.149998 -0.0171439 -0.0216497 0.1895 -0.20732 -0.0242753 0.189498 -0.196308 -0.0156101 0.182498 -0.203355 -0.011306 0.137998 -0.08529399999999999 -0.015277 0.149998 -0.102992 -0.011306 0.149998 -0.08529399999999999 -0.039966 0.149998 -0.060476 -0.0460505 0.149998 -0.08283790000000001 -0.039966 0.137998 -0.060476 0.034886 0.182497 -0.252801 0.034044 0.137997 -0.241883 0.034886 0.137997 -0.252801 0.0296546 0.149998 0.0221127 0.0208184 0.156998 0.0230108 0.0249496 0.149998 0.0267196 -0.000783752 0.189498 -0.217156 0.013442 0.182498 -0.217686 0.0117258 0.189497 -0.221248 0.027792 0.137998 0.024268 0.0296546 0.149998 0.0221127 0.0249496 0.149998 0.0267196 0.026577 0.182497 -0.272773 0.00982823 0.189497 -0.277838 0.0167086 0.189497 -0.271981 -0.0477357 0.189498 -0.184157 -0.0389066 0.189498 -0.221183 -0.044946 0.182498 -0.226035 0.0203086 0.149998 0.0302513 0.0171507 0.15 0.0321037 0.018877 0.137998 0.031087 -0.0363383 0.156998 -0.073647 -0.0238631 0.156998 -0.108253 -0.0476516 0.156998 -0.115832 0.0267455 0.156998 -0.0116438 -0.0277409 0.156998 -0.0046775 0.0277585 0.156998 -0.00777409 0.0337698 0.149998 -0.0124852 0.0267455 0.156998 -0.0116438 0.034653 0.149998 -0.009078019999999999 -0.019649 0.137998 -0.119943 -0.019649 0.149998 -0.119943 -0.015277 0.137998 -0.102992 -0.0269619 0.189498 -0.258688 -0.0277696 0.189498 -0.250156 0.0244819 0.189497 -0.262816 0.00982823 0.189497 -0.277838 -0.0220408 0.189497 -0.268871 0.0167086 0.189497 -0.271981 0.0319824 0.149998 0.018322 0.0342069 0.149998 0.0132172 0.0255505 0.156998 0.0156854 -0.011002 0.182498 -0.216775 -0.0216497 0.1895 -0.20732 -0.0156101 0.182498 -0.203355 0.0363095 0.149998 0.00153579 0.036177 0.137998 0.00428798 0.036247 0.137998 0.0009799819999999999 -0.00112887 0.156998 -0.0459391 0.00443301 0.149998 -0.050197 -0.0169633 0.156998 -0.0808022 0.0291131 0.156998 0.00354524 -0.0225231 0.156998 0.0155764 0.0281997 0.156998 0.00854457 -0.039966 0.137998 -0.060476 -0.00280198 0.137998 -0.034889 -0.013446 0.137998 -0.032316 -0.0273992 0.156998 -0.123236 -0.0201871 0.149998 -0.122778 -0.0299282 0.186882 -0.160046 -0.044946 0.137998 -0.226035 -0.0363225 0.182498 -0.24537 -0.034966 0.137998 -0.248412 0.02277 0.137997 -0.223422 -0.011002 0.137998 -0.216775 0.029869 0.137997 -0.231759 0.0169921 0.156998 0.0254633 0.0208184 0.156998 0.0230108 -0.0117197 0.156998 0.0263204 -0.00112887 0.156998 -0.0459391 -0.0267758 0.156998 -0.0210155 -0.00296095 0.156998 -0.032711 -0.00119713 0.156998 0.0311578 -0.0098446 0.156998 0.0277807 -0.020283 0.149998 0.028524 -0.0477357 0.189498 -0.184157 -0.0216497 0.1895 -0.20732 -0.0389066 0.189498 -0.221183 -0.0115818 0.149998 0.0333791 -0.00119713 0.156998 0.0311578 -0.020283 0.149998 0.028524 -0.0220408 0.189497 -0.268871 -0.0269619 0.189498 -0.258688 0.0167086 0.189497 -0.271981 -0.007896510000000001 0.149998 0.0343947 -0.0115818 0.149998 0.0333791 -0.008135979999999999 0.137998 0.034439 -0.0363383 0.156998 -0.073647 -0.0203749 0.156998 -0.0947291 -0.0238631 0.156998 -0.108253 -0.026582 0.137998 0.02277 -0.031163 0.149998 0.015936 -0.032318 0.137998 0.013442 -0.0117197 0.156998 0.0263204 0.0237806 0.156998 0.0198468 0.0255505 0.156998 0.0156854 -0.00345781 0.189497 -0.281249 0.018239 0.182497 -0.279871 0.008116 0.182497 -0.28405 -0.00296095 0.156998 -0.032711 -0.0267758 0.156998 -0.0210155 0.0208539 0.156998 -0.0194829 -0.0276409 0.156998 0.00270343 0.0291131 0.156998 0.00354524 0.0291522 0.156998 -0.00266303 -0.001318 0.1825 -0.284775 -0.002802 0.137997 -0.284889 -0.0130552 0.1825 -0.28405 -0.056865 0.137998 -0.17605 -0.022928 0.137998 -0.160794 -0.058044 0.137998 -0.157039 0.0120559 0.156998 0.028325 0.0169921 0.156998 0.0254633 -0.0098446 0.156998 0.0277807 -0.034048 0.137998 -0.008119019999999999 -0.033792 0.137998 -0.020934 -0.029873 0.137998 -0.018243 0.0277585 0.156998 -0.00777409 0.0291522 0.156998 -0.00266303 0.0361584 0.149998 -0.00332059 0.032313 0.182497 -0.263445 0.034886 0.137997 -0.252801 0.032313 0.137997 -0.263445 -0.0098446 0.156998 0.0277807 -0.022692 0.149998 0.026648 -0.020283 0.149998 0.028524 0.00747002 0.15 0.035384 0.00116802 0.137998 0.036003 0.00667102 0.137998 0.035573 0.029869 0.182497 -0.23176 0.0269129 0.189497 -0.240452 0.0220503 0.189497 -0.231162 -0.0276409 0.156998 0.00270343 0.0291522 0.156998 -0.00266303 0.0277585 0.156998 -0.00777409 -0.0358064 0.189498 -0.229342 -0.0277696 0.189498 -0.250156 -0.0363225 0.182498 -0.24537 0.0190888 0.137992 -0.0323898 0.024691 0.137998 -0.024464 0.018239 0.137998 -0.029872 -0.0460505 0.149998 -0.08283790000000001 -0.0363383 0.156998 -0.073647 -0.055576 0.149998 -0.118356 -0.058044 0.175225 -0.157039 -0.058044 0.137998 -0.157039 -0.0567022 0.153255 -0.130855 -0.033792 0.149998 -0.020934 -0.034752 0.149998 -0.00418302 -0.0277409 0.156998 -0.0046775 0.0269129 0.189497 -0.240452 0.034044 0.182497 -0.241883 0.0277921 0.189497 -0.252355 -0.022928 0.137998 -0.160794 -0.019649 0.137998 -0.119943 -0.058044 0.137998 -0.157039 -0.0219334 0.182498 -0.168339 -0.016335 0.137998 -0.201244 -0.0156101 0.182498 -0.203355 0.018877 0.137998 0.031087 0.0171507 0.15 0.0321037 0.017841 0.137998 0.03175 0.0267455 0.156998 -0.0116438 0.0277585 0.156998 -0.00777409 0.034653 0.149998 -0.009078019999999999 0.0165033 0.189497 -0.22686 0.029869 0.182497 -0.23176 0.0220503 0.189497 -0.231162 0.0190888 0.137992 -0.0323898 0.018239 0.137998 -0.029872 0.00443301 0.137998 -0.050197 0.034981 0.137998 0.010695 0.036177 0.137998 0.00428798 0.0357745 0.149998 0.0069537 -0.015277 0.149998 -0.102992 -0.019649 0.149998 -0.119943 -0.0238631 0.156998 -0.108253 -0.022928 0.137998 -0.160794 -0.022835 0.179996 -0.162726 -0.022928 0.178374 -0.160795 0.035503 0.137998 -0.00716101 0.0337698 0.149998 -0.0124852 0.034653 0.149998 -0.009078019999999999 0.0244819 0.189497 -0.262816 0.0277921 0.189497 -0.252355 0.034886 0.182497 -0.252801 0.02797 0.137998 -0.021651 0.02797 0.149998 -0.021651 0.031545 0.137998 -0.016125 0.0357745 0.149998 0.0069537 0.0291131 0.156998 0.00354524 0.0281997 0.156998 0.00854457 0.013442 0.137998 -0.217686 0.02277 0.182497 -0.223422 0.013442 0.182498 -0.217686 -0.0325361 0.149998 0.011096 -0.0225231 0.156998 0.0155764 -0.03489 0.149998 0.00279898 -0.044946 0.182498 -0.226035 -0.056865 0.137998 -0.17605 -0.0570253 0.182498 -0.173467 -0.03489 0.137998 0.00279898 -0.034752 0.137998 -0.00418302 -0.034048 0.137998 -0.008119019999999999 -0.011002 0.137998 -0.216775 0.013442 0.137998 -0.217686 -0.00812 0.137998 -0.215956 -0.0460505 0.149998 -0.08283790000000001 -0.055576 0.137998 -0.118356 -0.039966 0.137998 -0.060476 -0.0276409 0.156998 0.00270343 -0.0225231 0.156998 0.0155764 0.0291131 0.156998 0.00354524 -0.03489 0.137998 0.00279898 -0.032318 0.137998 0.013442 -0.0325361 0.149998 0.011096 -0.0389066 0.189498 -0.221183 -0.0216497 0.1895 -0.20732 -0.0358064 0.189498 -0.229342 0.0118795 0.149998 0.0342979 0.0171507 0.15 0.0321037 0.00427813 0.156998 0.0315094 0.013442 0.137998 -0.217686 0.02277 0.137997 -0.223422 0.02277 0.182497 -0.223422 -0.0363225 0.182498 -0.24537 -0.0277696 0.189498 -0.250156 -0.034047 0.182498 -0.258119 -0.0220408 0.189497 -0.268871 -0.022774 0.182497 -0.27658 -0.0243837 0.184358 -0.272411 -0.0567022 0.153255 -0.130855 -0.0476516 0.156998 -0.115832 -0.0493451 0.156998 -0.124141 0.029869 0.137997 -0.231759 -0.011002 0.137998 -0.216775 -0.044946 0.137998 -0.226035 -0.0578833 0.182498 -0.162331 -0.058044 0.137998 -0.157039 -0.058044 0.175225 -0.157039 -0.0216497 0.1895 -0.20732 -0.0477357 0.189498 -0.184157 -0.0242753 0.189498 -0.196308 -0.0277409 0.156998 -0.0046775 -0.034752 0.149998 -0.00418302 -0.0276409 0.156998 0.00270343 0.013442 0.137998 -0.217686 0.013442 0.182498 -0.217686 0.00279801 0.137998 -0.215114 -0.0363383 0.156998 -0.073647 -0.00112887 0.156998 -0.0459391 -0.0169633 0.156998 -0.0808022 -0.03489 0.137998 0.00279898 -0.0325361 0.149998 0.011096 -0.03489 0.149998 0.00279898 -0.0298721 0.182497 -0.268242 -0.0220408 0.189497 -0.268871 -0.0243837 0.184358 -0.272411 -0.0269619 0.189498 -0.258688 -0.0298721 0.182497 -0.268242 -0.034047 0.182498 -0.258119 0.018239 0.137998 -0.029872 0.00811601 0.137998 -0.034047 0.00443301 0.137998 -0.050197 -0.0555759 0.151393 -0.127995 -0.0476516 0.156998 -0.115832 -0.0567022 0.153255 -0.130855 0.026577 0.137997 -0.272773 0.026577 0.182497 -0.272773 0.032313 0.137997 -0.263445 -0.0276409 0.156998 0.00270343 -0.034752 0.149998 -0.00418302 -0.03489 0.149998 0.00279898 0.00443301 0.149998 -0.050197 0.0190888 0.137992 -0.0323898 0.00443301 0.137998 -0.050197 -0.033792 0.137998 -0.020934 -0.039966 0.137998 -0.060476 -0.022774 0.137998 -0.02658 -0.0477357 0.189498 -0.184157 -0.0360055 0.189134 -0.179117 -0.0242753 0.189498 -0.196308 -0.0578833 0.182498 -0.162331 -0.050628 0.177738 -0.148859 -0.0508655 0.189241 -0.162856 -0.056865 0.137998 -0.17605 -0.016335 0.137998 -0.201244 -0.022928 0.137998 -0.160794 0.0242157 0.156998 -0.0156431 0.0337698 0.149998 -0.0124852 0.0313327 0.149998 -0.0171439 -0.001318 0.1825 -0.284775 0.008116 0.182497 -0.28405 0.008116 0.137997 -0.284047 -0.0267758 0.156998 -0.0210155 -0.033792 0.149998 -0.020934 -0.0277409 0.156998 -0.0046775 -0.022774 0.182497 -0.27658 -0.013446 0.137997 -0.282316 -0.022774 0.137997 -0.27658 -0.034752 0.149998 -0.00418302 -0.034752 0.137998 -0.00418302 -0.03489 0.149998 0.00279898 -0.034752 0.137998 -0.00418302 -0.033792 0.137998 -0.020934 -0.034048 0.137998 -0.008119019999999999 -0.0476516 0.156998 -0.115832 -0.0273992 0.156998 -0.123236 -0.0493451 0.156998 -0.124141 0.0203086 0.149998 0.0302513 0.023298 0.137998 0.028256 0.0249496 0.149998 0.0267196 0.0357745 0.149998 0.0069537 0.0363095 0.149998 0.00153579 0.0291131 0.156998 0.00354524 0.036177 0.137998 0.00428798 0.0363095 0.149998 0.00153579 0.0357745 0.149998 0.0069537 -0.0220408 0.189497 -0.268871 0.00982823 0.189497 -0.277838 -0.0132689 0.189497 -0.276947 -0.019649 0.149998 -0.119943 -0.015277 0.149998 -0.102992 -0.015277 0.137998 -0.102992 -0.00119713 0.156998 0.0311578 -0.007896510000000001 0.149998 0.0343947 -0.00326398 0.15 0.035671 -0.0225231 0.156998 0.0155764 -0.0117197 0.156998 0.0263204 0.0255505 0.156998 0.0156854 0.018239 0.182497 -0.279871 0.026577 0.137997 -0.272773 0.018239 0.137997 -0.279871 -0.019649 0.137998 -0.119943 -0.022928 0.137998 -0.160794 -0.022928 0.178374 -0.160795 -0.002802 0.137997 -0.284889 -0.001318 0.1825 -0.284775 0.008116 0.137997 -0.284047 0.00443301 0.137998 -0.050197 0.00811601 0.137998 -0.034047 -0.00280198 0.137998 -0.034889 -0.00112887 0.156998 -0.0459391 -0.00296095 0.156998 -0.032711 0.0208539 0.156998 -0.0194829 0.00279801 0.137998 -0.215114 0.013442 0.182498 -0.217686 0.001314 0.182498 -0.215228 -0.007896510000000001 0.149998 0.0343947 -0.008135979999999999 0.137998 0.034439 -0.00326398 0.15 0.035671 -0.039966 0.149998 -0.060476 -0.0324414 0.156998 -0.0576595 -0.0363383 0.156998 -0.073647 0.0237806 0.156998 0.0198468 0.0208184 0.156998 0.0230108 0.0296546 0.149998 0.0221127 -0.0277409 0.156998 -0.0046775 0.0267455 0.156998 -0.0116438 0.0242157 0.156998 -0.0156431 0.023298 0.137998 0.028256 0.0203086 0.149998 0.0302513 0.018877 0.137998 0.031087 -0.0358064 0.189498 -0.229342 -0.0144049 0.1895 -0.218377 0.0165033 0.189497 -0.22686 -0.044946 0.137998 -0.226035 -0.044946 0.182498 -0.226035 -0.0363225 0.182498 -0.24537 -0.0298721 0.182497 -0.268242 -0.022774 0.137997 -0.27658 -0.029873 0.137998 -0.268242 -0.022774 0.182497 -0.27658 -0.0220408 0.189497 -0.268871 -0.0132689 0.189497 -0.276947 -0.039966 0.149998 -0.060476 -0.033792 0.149998 -0.020934 -0.0267758 0.156998 -0.0210155 -0.020283 0.149998 0.028524 -0.026582 0.137998 0.02277 -0.020283 0.137998 0.028524 0.02797 0.149998 -0.021651 0.0208539 0.156998 -0.0194829 0.0313327 0.149998 -0.0171439 0.0118795 0.149998 0.0342979 0.00667102 0.137998 0.035573 0.012177 0.137998 0.0342 0.032313 0.182497 -0.263445 0.034886 0.182497 -0.252801 0.034886 0.137997 -0.252801 -0.0501208 0.189241 -0.172523 -0.0570253 0.182498 -0.173467 -0.0508655 0.189241 -0.162856 0.00747002 0.15 0.035384 0.00427813 0.156998 0.0315094 0.00176102 0.15 0.036001 0.008116 0.182497 -0.28405 0.018239 0.182497 -0.279871 0.018239 0.137997 -0.279871 -0.019649 0.137998 -0.119943 -0.015277 0.137998 -0.102992 -0.039966 0.137998 -0.060476 0.008116 0.137997 -0.284047 0.018239 0.137997 -0.279871 -0.013446 0.137997 -0.282316 -0.058044 0.137998 -0.157039 -0.0555759 0.151393 -0.127995 -0.0567022 0.153255 -0.130855 -0.050628 0.177738 -0.148859 -0.058044 0.175225 -0.157039 -0.0493451 0.156998 -0.124141 -0.055576 0.137998 -0.118356 -0.019649 0.137998 -0.119943 -0.039966 0.137998 -0.060476 0.034886 0.137997 -0.252801 -0.044946 0.137998 -0.226035 -0.034966 0.137998 -0.248412 -0.008135979999999999 0.137998 0.034439 -0.0115818 0.149998 0.0333791 -0.020283 0.137998 0.028524 -0.007896510000000001 0.149998 0.0343947 -0.00119713 0.156998 0.0311578 -0.0115818 0.149998 0.0333791 -0.0477357 0.189498 -0.184157 -0.044946 0.182498 -0.226035 -0.0570253 0.182498 -0.173467 0.008116 0.182497 -0.28405 0.018239 0.137997 -0.279871 0.008116 0.137997 -0.284047 0.0120559 0.156998 0.028325 0.0203086 0.149998 0.0302513 0.0249496 0.149998 0.0267196 -0.058044 0.137998 -0.157039 -0.055576 0.137998 -0.118356 -0.0555759 0.151393 -0.127995 -0.0238631 0.156998 -0.108253 -0.0267148 0.156998 -0.119631 -0.0476516 0.156998 -0.115832 -0.048333 0.173647 -0.252846 -0.041271 0.170656 -0.263571 -0.058266 0.169826 -0.239406 -0.065137 0.169826 -0.214993 -0.07137400000000001 0.165998 -0.190116 -0.06900100000000001 0.169826 -0.189844 -0.0347 0.146939 -0.269045 -0.037068 0.119982 -0.269121 -0.037069 0.137965 -0.269121 -0.08101 0.126736 -0.1835 -0.072017 0.119053 -0.18233 -0.072017 0.127053 -0.18233 -0.058474 0.173792 -0.213889 -0.050821 0.173792 -0.239323 -0.062691 0.173647 -0.215048 -0.050821 0.173792 -0.239323 -0.058474 0.173792 -0.213889 -0.046384 0.173948 -0.237548 -0.061239 0.152807 -0.149776 -0.061654 0.159058 -0.15216 -0.062478 0.152776 -0.150129 -0.037062 0.146875 -0.269124 -0.037056 0.155948 -0.269128 -0.0347 0.146939 -0.269045 -0.0388376 0.146029 -0.254472 -0.036129 0.171986 -0.261556 -0.0426034 0.145931 -0.245045 -0.060054 0.156129 -0.150442 -0.060208 0.164248 -0.156288 -0.060108 0.159156 -0.151942 -0.060181 0.162713 -0.154553 -0.062295 0.164126 -0.156456 -0.061654 0.159058 -0.15216 -0.059687 0.172139 -0.174114 -0.063567 0.172356 -0.174442 -0.062933 0.167688 -0.16204 -0.036085 0.166836 -0.266902 -0.032631 0.163595 -0.268277 -0.034742 0.160427 -0.26898 -0.05466 0.173647 -0.240858 -0.058266 0.169826 -0.239406 -0.065137 0.169826 -0.214993 -0.06234 0.119496 -0.149685 -0.06659900000000001 0.119332 -0.154644 -0.059219 0.119502 -0.181032 -0.062295 0.164126 -0.156456 -0.06565 0.167967 -0.163813 -0.06317399999999999 0.158896 -0.152487 -0.062295 0.164126 -0.156456 -0.060225 0.165187 -0.15735 -0.062933 0.167688 -0.16204 -0.036129 0.171986 -0.261556 -0.036085 0.166836 -0.266902 -0.038749 0.171387 -0.26263 -0.068758 0.07099800000000001 -0.233304 -0.076249 0.126736 -0.233751 -0.068758 0.118998 -0.233305 -0.0555558 0.146725 -0.202109 -0.0530965 0.122945 -0.213171 -0.0513867 0.122741 -0.222061 -0.060181 0.162713 -0.154553 -0.060208 0.164248 -0.156288 -0.062295 0.164126 -0.156456 -0.037069 0.137965 -0.269121 -0.037068 0.119982 -0.269121 -0.042476 0.144627 -0.265799 -0.047899 0.13613 -0.262467 -0.047899 0.119627 -0.262467 -0.049676 0.164207 -0.259772 -0.050522 0.173948 -0.224055 -0.053742 0.173948 -0.213554 -0.0511948 0.122623 -0.223052 -0.062817 0.173792 -0.187619 -0.063567 0.172356 -0.174442 -0.058526 0.173948 -0.187393 -0.06192 0.118998 -0.181429 -0.059219 0.119502 -0.181032 -0.071717 0.119096 -0.172174 -0.0426034 0.145931 -0.245045 -0.0497035 0.123371 -0.227009 -0.0456132 0.12173 -0.237229 -0.0544271 0.119498 -0.232738 -0.061351 0.119239 -0.238297 -0.059297 0.119296 -0.242838 -0.062817 0.173792 -0.187619 -0.066611 0.173546 -0.188224 -0.063567 0.172356 -0.174442 -0.059999 0.132619 -0.149157 -0.059687 0.172139 -0.174114 -0.059999 0.144543 -0.149159 -0.059999 0.132619 -0.149157 -0.059999 0.144543 -0.149159 -0.061173 0.132658 -0.14942 -0.045119 0.173789 -0.25134 -0.048333 0.173647 -0.252846 -0.053043 0.173647 -0.244598 -0.0544271 0.119498 -0.232738 -0.06334099999999999 0.119187 -0.232981 -0.061351 0.119239 -0.238297 -0.063567 0.172356 -0.174442 -0.058526 0.173948 -0.187393 -0.059217 0.173678 -0.181024 -0.07137400000000001 0.165998 -0.190116 -0.06750299999999999 0.165998 -0.21531 -0.065717 0.127134 -0.22427 -0.032244 0.155144 -0.268988 -0.032631 0.163595 -0.268277 -0.032294 0.160522 -0.268895 -0.059687 0.172139 -0.174114 -0.060212 0.168388 -0.162797 -0.059999 0.144543 -0.149159 -0.0388376 0.146029 -0.254472 -0.0426034 0.145931 -0.245045 -0.034967 0.120072 -0.263858 -0.060208 0.164248 -0.156288 -0.060225 0.165187 -0.15735 -0.062295 0.164126 -0.156456 -0.045735 0.167981 -0.261308 -0.037056 0.155948 -0.269128 -0.037062 0.146875 -0.269124 -0.036129 0.171986 -0.261556 -0.0388376 0.146029 -0.254472 -0.034967 0.120072 -0.263858 -0.0570492 0.165997 -0.246987 -0.059297 0.119296 -0.242838 -0.061328 0.165998 -0.238353 -0.08101 0.126736 -0.1835 -0.072017 0.127053 -0.18233 -0.07170600000000001 0.127047 -0.187151 -0.038749 0.171387 -0.26263 -0.041271 0.170656 -0.263571 -0.048333 0.173647 -0.252846 -0.08101 0.126736 -0.1835 -0.08101 0.07126 -0.1835 -0.07356699999999999 0.07099800000000001 -0.182532 -0.066611 0.173546 -0.188224 -0.06696299999999999 0.171975 -0.174878 -0.063567 0.172356 -0.174442 -0.08101 0.07126 -0.1835 -0.076249 0.126736 -0.233751 -0.076249 0.07126 -0.233751 -0.047899 0.119627 -0.262467 -0.049553 0.119578 -0.259981 -0.049676 0.164207 -0.259772 -0.036085 0.166836 -0.266902 -0.041271 0.170656 -0.263571 -0.038749 0.171387 -0.26263 -0.06565 0.167967 -0.163813 -0.06696299999999999 0.171975 -0.174878 -0.068435 0.164632 -0.165306 -0.038749 0.171387 -0.26263 -0.048333 0.173647 -0.252846 -0.041948 0.173561 -0.257175 -0.06537900000000001 0.173647 -0.19902 -0.066611 0.173546 -0.188224 -0.062817 0.173792 -0.187619 -0.06659900000000001 0.119332 -0.154644 -0.06234 0.119496 -0.149685 -0.06592099999999999 0.144184 -0.153854 -0.062347 0.146132 -0.149702 -0.06592099999999999 0.144184 -0.153854 -0.062342 0.143931 -0.149687 -0.06537900000000001 0.173647 -0.19902 -0.058474 0.173792 -0.213889 -0.062691 0.173647 -0.215048 -0.06659900000000001 0.119332 -0.154644 -0.06951599999999999 0.119219 -0.158041 -0.059219 0.119502 -0.181032 -0.07356699999999999 0.07099800000000001 -0.182532 -0.08101 0.07126 -0.1835 -0.076249 0.07126 -0.233751 -0.065137 0.169826 -0.214993 -0.06537900000000001 0.173647 -0.19902 -0.062691 0.173647 -0.215048 -0.0423461 0.119877 -0.245385 -0.047899 0.119627 -0.262467 -0.0434993 0.119771 -0.26517 -0.045735 0.167981 -0.261308 -0.041271 0.170656 -0.263571 -0.039049 0.167503 -0.266575 -0.05466 0.173647 -0.240858 -0.065137 0.169826 -0.214993 -0.062691 0.173647 -0.215048 -0.038497 0.16615 -0.267291 -0.045735 0.167981 -0.261308 -0.039049 0.167503 -0.266575 -0.060225 0.165187 -0.15735 -0.060054 0.156129 -0.150442 -0.060011 0.152342 -0.14942 -0.046384 0.173948 -0.237548 -0.050522 0.173948 -0.224055 -0.0511948 0.122623 -0.223052 -0.0570217 0.121279 -0.192606 -0.0547976 0.123013 -0.204317 -0.0555558 0.146725 -0.202109 -0.050821 0.173792 -0.239323 -0.05466 0.173647 -0.240858 -0.062691 0.173647 -0.215048 -0.068435 0.164632 -0.165306 -0.06696299999999999 0.171975 -0.174878 -0.06900100000000001 0.169826 -0.189844 -0.047899 0.119627 -0.262467 -0.042476 0.144627 -0.265799 -0.0434993 0.119771 -0.26517 -0.062933 0.167688 -0.16204 -0.060225 0.165187 -0.15735 -0.060214 0.167823 -0.161836 -0.06234 0.119496 -0.149685 -0.06117 0.119538 -0.14942 -0.061173 0.132658 -0.14942 -0.076249 0.126736 -0.233751 -0.08101 0.126736 -0.1835 -0.07170600000000001 0.127047 -0.187151 -0.063567 0.172356 -0.174442 -0.06696299999999999 0.171975 -0.174878 -0.062933 0.167688 -0.16204 -0.06334099999999999 0.127187 -0.232981 -0.076249 0.126736 -0.233751 -0.065717 0.127134 -0.22427 -0.061654 0.159058 -0.15216 -0.062295 0.164126 -0.156456 -0.06317399999999999 0.158896 -0.152487 -0.07137400000000001 0.165998 -0.190116 -0.065137 0.169826 -0.214993 -0.06750299999999999 0.165998 -0.21531 -0.053043 0.173647 -0.244598 -0.058266 0.169826 -0.239406 -0.05466 0.173647 -0.240858 -0.041271 0.170656 -0.263571 -0.045735 0.167981 -0.261308 -0.058266 0.169826 -0.239406 -0.036085 0.166836 -0.266902 -0.038497 0.16615 -0.267291 -0.039049 0.167503 -0.266575 -0.034295 0.169167 -0.265153 -0.036085 0.166836 -0.266902 -0.033648 0.167443 -0.266377 -0.0423461 0.119877 -0.245385 -0.0426034 0.145931 -0.245045 -0.0439799 0.120915 -0.241308 -0.0439799 0.120915 -0.241308 -0.0426034 0.145931 -0.245045 -0.0456132 0.12173 -0.237229 -0.065387 0.165998 -0.22501 -0.06334099999999999 0.127187 -0.232981 -0.065717 0.127134 -0.22427 -0.0497035 0.123371 -0.227009 -0.0426034 0.145931 -0.245045 -0.0500441 0.123165 -0.226155 -0.060225 0.165187 -0.15735 -0.060011 0.152342 -0.14942 -0.060214 0.167823 -0.161836 -0.037056 0.155948 -0.269128 -0.037223 0.160169 -0.268922 -0.0347 0.146939 -0.269045 -0.061239 0.152807 -0.149776 -0.060054 0.156129 -0.150442 -0.061654 0.159058 -0.15216 -0.062478 0.152776 -0.150129 -0.062347 0.146132 -0.149702 -0.061173 0.146095 -0.149422 -0.034967 0.120072 -0.263858 -0.0423461 0.119877 -0.245385 -0.0434993 0.119771 -0.26517 -0.06117 0.119538 -0.14942 -0.059999 0.11958 -0.149155 -0.061173 0.132658 -0.14942 -0.038497 0.16615 -0.267291 -0.036085 0.166836 -0.266902 -0.034742 0.160427 -0.26898 -0.0500441 0.123165 -0.226155 -0.036129 0.171986 -0.261556 -0.041603 0.17395 -0.249692 -0.0555558 0.146725 -0.202109 -0.059219 0.119502 -0.181032 -0.058413 0.119945 -0.185262 -0.03331 0.166543 -0.267016 -0.036085 0.166836 -0.266902 -0.033648 0.167443 -0.266377 -0.06334099999999999 0.119187 -0.232981 -0.076249 0.126736 -0.233751 -0.06334099999999999 0.127187 -0.232981 -0.059219 0.119502 -0.181032 -0.0701 0.11919 -0.160869 -0.071717 0.119096 -0.172174 -0.032244 0.155144 -0.268988 -0.032631 0.163595 -0.268277 -0.032249 0.146972 -0.268979 -0.032249 0.146972 -0.268979 -0.03331 0.166543 -0.267016 -0.032254 0.137647 -0.268969 -0.0426034 0.145931 -0.245045 -0.036129 0.171986 -0.261556 -0.0500441 0.123165 -0.226155 -0.059297 0.119296 -0.242838 -0.061351 0.119239 -0.238297 -0.061328 0.165998 -0.238353 -0.060002 0.146067 -0.14921 -0.059999 0.144543 -0.149159 -0.061173 0.146095 -0.149422 -0.08101 0.126736 -0.1835 -0.07356699999999999 0.07099800000000001 -0.182532 -0.07356699999999999 0.118998 -0.182532 -0.060181 0.162713 -0.154553 -0.060208 0.164248 -0.156288 -0.060108 0.159156 -0.151942 -0.0544271 0.119498 -0.232738 -0.059297 0.119296 -0.242838 -0.049553 0.119578 -0.259981 -0.045735 0.167981 -0.261308 -0.047899 0.13613 -0.262467 -0.049676 0.164207 -0.259772 -0.041603 0.17395 -0.249692 -0.045119 0.173789 -0.25134 -0.050821 0.173792 -0.239323 -0.06696299999999999 0.171975 -0.174878 -0.06565 0.167967 -0.163813 -0.062933 0.167688 -0.16204 -0.045735 0.167981 -0.261308 -0.049676 0.164207 -0.259772 -0.0570492 0.165997 -0.246987 -0.072017 0.119053 -0.18233 -0.071717 0.119096 -0.172174 -0.072017 0.127053 -0.18233 -0.06117 0.119538 -0.14942 -0.059219 0.119502 -0.181032 -0.059999 0.11958 -0.149155 -0.041948 0.173561 -0.257175 -0.048333 0.173647 -0.252846 -0.045119 0.173789 -0.25134 -0.037068 0.119982 -0.269121 -0.0347 0.146939 -0.269045 -0.034699 0.120064 -0.269046 -0.061173 0.146095 -0.149422 -0.062347 0.146132 -0.149702 -0.062342 0.143931 -0.149687 -0.032631 0.163595 -0.268277 -0.03331 0.166543 -0.267016 -0.036085 0.166836 -0.266902 -0.059999 0.132619 -0.149157 -0.059999 0.11958 -0.149155 -0.061173 0.132658 -0.14942 -0.06951599999999999 0.119219 -0.158041 -0.069857 0.154956 -0.159655 -0.0701 0.11919 -0.160869 -0.06334099999999999 0.127187 -0.232981 -0.065387 0.165998 -0.22501 -0.061351 0.119239 -0.238297 -0.032631 0.163595 -0.268277 -0.032294 0.160522 -0.268895 -0.034742 0.160427 -0.26898 -0.0347 0.146939 -0.269045 -0.032249 0.146972 -0.268979 -0.032254 0.137647 -0.268969 -0.058474 0.173792 -0.213889 -0.062817 0.173792 -0.187619 -0.053742 0.173948 -0.213554 -0.045735 0.167981 -0.261308 -0.037062 0.146875 -0.269124 -0.042476 0.144627 -0.265799 -0.059999 0.132619 -0.149157 -0.059999 0.11958 -0.149155 -0.059217 0.173678 -0.181024 -0.060011 0.152342 -0.14942 -0.060002 0.146067 -0.14921 -0.061173 0.146095 -0.149422 -0.06537900000000001 0.173647 -0.19902 -0.065137 0.169826 -0.214993 -0.06900100000000001 0.169826 -0.189844 -0.037062 0.146875 -0.269124 -0.0347 0.146939 -0.269045 -0.037069 0.137965 -0.269121 -0.06592099999999999 0.144184 -0.153854 -0.062478 0.152776 -0.150129 -0.06317399999999999 0.158896 -0.152487 -0.036129 0.171986 -0.261556 -0.034295 0.169167 -0.265153 -0.036085 0.166836 -0.266902 -0.059999 0.11958 -0.149155 -0.059219 0.119502 -0.181032 -0.059217 0.173678 -0.181024 -0.059219 0.119502 -0.181032 -0.058526 0.173948 -0.187393 -0.059217 0.173678 -0.181024 -0.059999 0.144543 -0.149159 -0.061173 0.146095 -0.149422 -0.061173 0.132658 -0.14942 -0.058266 0.169826 -0.239406 -0.0570492 0.165997 -0.246987 -0.061328 0.165998 -0.238353 -0.059687 0.172139 -0.174114 -0.060212 0.168388 -0.162797 -0.062933 0.167688 -0.16204 -0.069857 0.154956 -0.159655 -0.06951599999999999 0.119219 -0.158041 -0.06951599999999999 0.144495 -0.15804 -0.06592099999999999 0.144184 -0.153854 -0.06234 0.119496 -0.149685 -0.06234 0.132708 -0.149684 -0.037068 0.119982 -0.269121 -0.034699 0.120064 -0.269046 -0.034967 0.120072 -0.263858 -0.060011 0.152342 -0.14942 -0.061239 0.152807 -0.149776 -0.061173 0.146095 -0.149422 -0.06565 0.167967 -0.163813 -0.062295 0.164126 -0.156456 -0.062933 0.167688 -0.16204 -0.060054 0.156129 -0.150442 -0.060011 0.152342 -0.14942 -0.061239 0.152807 -0.149776 -0.032294 0.160522 -0.268895 -0.032244 0.155144 -0.268988 -0.034742 0.160427 -0.26898 -0.0500441 0.123165 -0.226155 -0.046384 0.173948 -0.237548 -0.0511948 0.122623 -0.223052 -0.03331 0.166543 -0.267016 -0.033648 0.167443 -0.266377 -0.032254 0.137647 -0.268969 -0.061239 0.152807 -0.149776 -0.062478 0.152776 -0.150129 -0.061173 0.146095 -0.149422 -0.050821 0.173792 -0.239323 -0.045119 0.173789 -0.25134 -0.053043 0.173647 -0.244598 -0.034295 0.169167 -0.265153 -0.032254 0.12015 -0.268969 -0.033648 0.167443 -0.266377 -0.041271 0.170656 -0.263571 -0.036085 0.166836 -0.266902 -0.039049 0.167503 -0.266575 -0.0347 0.146939 -0.269045 -0.034699 0.120064 -0.269046 -0.032254 0.12015 -0.268969 -0.049676 0.164207 -0.259772 -0.059297 0.119296 -0.242838 -0.0570492 0.165997 -0.246987 -0.047899 0.119627 -0.262467 -0.0423461 0.119877 -0.245385 -0.049553 0.119578 -0.259981 -0.06117 0.119538 -0.14942 -0.06234 0.119496 -0.149685 -0.059219 0.119502 -0.181032 -0.037223 0.160169 -0.268922 -0.037295 0.16198 -0.268834 -0.034742 0.160427 -0.26898 -0.061173 0.146095 -0.149422 -0.062342 0.143931 -0.149687 -0.06234 0.132708 -0.149684 -0.0547976 0.123013 -0.204317 -0.0530965 0.122945 -0.213171 -0.0555558 0.146725 -0.202109 -0.062478 0.152776 -0.150129 -0.061654 0.159058 -0.15216 -0.06317399999999999 0.158896 -0.152487 -0.038497 0.16615 -0.267291 -0.037295 0.16198 -0.268834 -0.045735 0.167981 -0.261308 -0.032631 0.163595 -0.268277 -0.03331 0.166543 -0.267016 -0.032249 0.146972 -0.268979 -0.069857 0.154956 -0.159655 -0.066426 0.156527 -0.15576 -0.068435 0.164632 -0.165306 -0.08101 0.126736 -0.1835 -0.07356699999999999 0.118998 -0.182532 -0.072017 0.119053 -0.18233 -0.0500441 0.123165 -0.226155 -0.041603 0.17395 -0.249692 -0.046384 0.173948 -0.237548 -0.06951599999999999 0.119219 -0.158041 -0.06659900000000001 0.119332 -0.154644 -0.06592099999999999 0.144184 -0.153854 -0.053742 0.173948 -0.213554 -0.0555558 0.146725 -0.202109 -0.0511948 0.122623 -0.223052 -0.041603 0.17395 -0.249692 -0.050821 0.173792 -0.239323 -0.046384 0.173948 -0.237548 -0.060054 0.156129 -0.150442 -0.060225 0.165187 -0.15735 -0.060208 0.164248 -0.156288 -0.036129 0.171986 -0.261556 -0.038749 0.171387 -0.26263 -0.041948 0.173561 -0.257175 -0.06951599999999999 0.144495 -0.15804 -0.06592099999999999 0.144184 -0.153854 -0.066426 0.156527 -0.15576 -0.058474 0.173792 -0.213889 -0.06537900000000001 0.173647 -0.19902 -0.062817 0.173792 -0.187619 -0.06565 0.167967 -0.163813 -0.066426 0.156527 -0.15576 -0.06317399999999999 0.158896 -0.152487 -0.033648 0.167443 -0.266377 -0.032254 0.12015 -0.268969 -0.032254 0.137647 -0.268969 -0.047899 0.13613 -0.262467 -0.045735 0.167981 -0.261308 -0.042476 0.144627 -0.265799 -0.037062 0.146875 -0.269124 -0.037069 0.137965 -0.269121 -0.042476 0.144627 -0.265799 -0.034699 0.120064 -0.269046 -0.032254 0.12015 -0.268969 -0.034967 0.120072 -0.263858 -0.041603 0.17395 -0.249692 -0.041948 0.173561 -0.257175 -0.045119 0.173789 -0.25134 -0.037295 0.16198 -0.268834 -0.038497 0.16615 -0.267291 -0.034742 0.160427 -0.26898 -0.076249 0.126736 -0.233751 -0.07170600000000001 0.127047 -0.187151 -0.065717 0.127134 -0.22427 -0.06951599999999999 0.144495 -0.15804 -0.06951599999999999 0.119219 -0.158041 -0.06592099999999999 0.144184 -0.153854 -0.066611 0.173546 -0.188224 -0.06537900000000001 0.173647 -0.19902 -0.06900100000000001 0.169826 -0.189844 -0.076249 0.07126 -0.233751 -0.076249 0.126736 -0.233751 -0.068758 0.07099800000000001 -0.233304 -0.050821 0.173792 -0.239323 -0.053043 0.173647 -0.244598 -0.05466 0.173647 -0.240858 -0.053043 0.173647 -0.244598 -0.048333 0.173647 -0.252846 -0.058266 0.169826 -0.239406 -0.034295 0.169167 -0.265153 -0.036129 0.171986 -0.261556 -0.034967 0.120072 -0.263858 -0.06951599999999999 0.119219 -0.158041 -0.0701 0.11919 -0.160869 -0.059219 0.119502 -0.181032 -0.060011 0.152342 -0.14942 -0.060002 0.146067 -0.14921 -0.060212 0.168388 -0.162797 -0.06234 0.119496 -0.149685 -0.061173 0.132658 -0.14942 -0.06234 0.132708 -0.149684 -0.041603 0.17395 -0.249692 -0.036129 0.171986 -0.261556 -0.041948 0.173561 -0.257175 -0.032244 0.155144 -0.268988 -0.032249 0.146972 -0.268979 -0.0347 0.146939 -0.269045 -0.06334099999999999 0.119187 -0.232981 -0.06334099999999999 0.127187 -0.232981 -0.061351 0.119239 -0.238297 -0.06192 0.118998 -0.181429 -0.071717 0.119096 -0.172174 -0.072017 0.119053 -0.18233 -0.0426034 0.145931 -0.245045 -0.0423461 0.119877 -0.245385 -0.034967 0.120072 -0.263858 -0.071061 0.16086 -0.166615 -0.069857 0.154956 -0.159655 -0.068435 0.164632 -0.165306 -0.069857 0.154956 -0.159655 -0.06951599999999999 0.144495 -0.15804 -0.066426 0.156527 -0.15576 -0.058474 0.173792 -0.213889 -0.053742 0.173948 -0.213554 -0.050522 0.173948 -0.224055 -0.034742 0.160427 -0.26898 -0.032244 0.155144 -0.268988 -0.0347 0.146939 -0.269045 -0.062817 0.173792 -0.187619 -0.058526 0.173948 -0.187393 -0.053742 0.173948 -0.213554 -0.0347 0.146939 -0.269045 -0.032254 0.12015 -0.268969 -0.032254 0.137647 -0.268969 -0.060212 0.168388 -0.162797 -0.060002 0.146067 -0.14921 -0.059999 0.144543 -0.149159 -0.058474 0.173792 -0.213889 -0.050522 0.173948 -0.224055 -0.046384 0.173948 -0.237548 -0.068758 0.118998 -0.233305 -0.076249 0.126736 -0.233751 -0.06334099999999999 0.119187 -0.232981 -0.060212 0.168388 -0.162797 -0.062933 0.167688 -0.16204 -0.060214 0.167823 -0.161836 -0.065387 0.165998 -0.22501 -0.058266 0.169826 -0.239406 -0.061328 0.165998 -0.238353 -0.060108 0.159156 -0.151942 -0.060181 0.162713 -0.154553 -0.061654 0.159058 -0.15216 -0.053742 0.173948 -0.213554 -0.058526 0.173948 -0.187393 -0.059219 0.119502 -0.181032 -0.06750299999999999 0.165998 -0.21531 -0.065387 0.165998 -0.22501 -0.065717 0.127134 -0.22427 -0.071717 0.119096 -0.172174 -0.07137400000000001 0.165998 -0.190116 -0.072017 0.127053 -0.18233 -0.058266 0.169826 -0.239406 -0.045735 0.167981 -0.261308 -0.0570492 0.165997 -0.246987 -0.037295 0.16198 -0.268834 -0.037223 0.160169 -0.268922 -0.045735 0.167981 -0.261308 -0.065137 0.169826 -0.214993 -0.058266 0.169826 -0.239406 -0.06750299999999999 0.165998 -0.21531 -0.0580022 0.120438 -0.187438 -0.0555558 0.146725 -0.202109 -0.058413 0.119945 -0.185262 -0.059217 0.173678 -0.181024 -0.063567 0.172356 -0.174442 -0.059687 0.172139 -0.174114 -0.059999 0.132619 -0.149157 -0.059217 0.173678 -0.181024 -0.059687 0.172139 -0.174114 -0.061351 0.119239 -0.238297 -0.065387 0.165998 -0.22501 -0.061328 0.165998 -0.238353 -0.07137400000000001 0.165998 -0.190116 -0.068435 0.164632 -0.165306 -0.06900100000000001 0.169826 -0.189844 -0.0555558 0.146725 -0.202109 -0.0513867 0.122741 -0.222061 -0.0511948 0.122623 -0.223052 -0.042476 0.144627 -0.265799 -0.037068 0.119982 -0.269121 -0.0434993 0.119771 -0.26517 -0.060011 0.152342 -0.14942 -0.060212 0.168388 -0.162797 -0.060214 0.167823 -0.161836 -0.0701 0.11919 -0.160869 -0.069857 0.154956 -0.159655 -0.071717 0.119096 -0.172174 -0.060054 0.156129 -0.150442 -0.060108 0.159156 -0.151942 -0.061654 0.159058 -0.15216 -0.0570217 0.121279 -0.192606 -0.0555558 0.146725 -0.202109 -0.0580022 0.120438 -0.187438 -0.037223 0.160169 -0.268922 -0.034742 0.160427 -0.26898 -0.0347 0.146939 -0.269045 -0.062342 0.143931 -0.149687 -0.06592099999999999 0.144184 -0.153854 -0.06234 0.132708 -0.149684 -0.06696299999999999 0.171975 -0.174878 -0.066611 0.173546 -0.188224 -0.06900100000000001 0.169826 -0.189844 -0.072017 0.127053 -0.18233 -0.07137400000000001 0.165998 -0.190116 -0.07170600000000001 0.127047 -0.187151 -0.071061 0.16086 -0.166615 -0.07137400000000001 0.165998 -0.190116 -0.071717 0.119096 -0.172174 -0.08101 0.126736 -0.1835 -0.076249 0.126736 -0.233751 -0.08101 0.07126 -0.1835 -0.032254 0.12015 -0.268969 -0.034295 0.169167 -0.265153 -0.034967 0.120072 -0.263858 -0.066426 0.156527 -0.15576 -0.06565 0.167967 -0.163813 -0.068435 0.164632 -0.165306 -0.066426 0.156527 -0.15576 -0.06592099999999999 0.144184 -0.153854 -0.06317399999999999 0.158896 -0.152487 -0.07356699999999999 0.07099800000000001 -0.182532 -0.076249 0.07126 -0.233751 -0.068758 0.07099800000000001 -0.233304 -0.071061 0.16086 -0.166615 -0.068435 0.164632 -0.165306 -0.07137400000000001 0.165998 -0.190116 -0.049553 0.119578 -0.259981 -0.059297 0.119296 -0.242838 -0.049676 0.164207 -0.259772 -0.0423461 0.119877 -0.245385 -0.0544271 0.119498 -0.232738 -0.049553 0.119578 -0.259981 -0.037068 0.119982 -0.269121 -0.034967 0.120072 -0.263858 -0.0434993 0.119771 -0.26517 -0.037223 0.160169 -0.268922 -0.037056 0.155948 -0.269128 -0.045735 0.167981 -0.261308 -0.069857 0.154956 -0.159655 -0.071061 0.16086 -0.166615 -0.071717 0.119096 -0.172174 -0.062347 0.146132 -0.149702 -0.062478 0.152776 -0.150129 -0.06592099999999999 0.144184 -0.153854 -0.053742 0.173948 -0.213554 -0.059219 0.119502 -0.181032 -0.0555558 0.146725 -0.202109 -0.07170600000000001 0.127047 -0.187151 -0.07137400000000001 0.165998 -0.190116 -0.065717 0.127134 -0.22427 -0.047899 0.119627 -0.262467 -0.047899 0.13613 -0.262467 -0.042476 0.144627 -0.265799 -0.061173 0.132658 -0.14942 -0.061173 0.146095 -0.149422 -0.06234 0.132708 -0.149684 -0.06750299999999999 0.165998 -0.21531 -0.058266 0.169826 -0.239406 -0.065387 0.165998 -0.22501 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645

    -
    -
    - - - 0 0 0 - 1 0 0 0 - - true - - - -
    - - - - 0.003 0.032999 -0.05800500000000006 0.003 0.0259881 -0.05590170000000005 0.003 0.024999 -0.05800500000000006 -0.03 -0.032001 -0.05800500000000006 -0.032144 -0.0362324 -0.05800500000000006 -0.0303577 -0.0319558 -0.05800500000000006 -0.0571725 -0.0168208 -0.05800500000000006 -0.057019 -0.017147 -0.05800500000000006 -0.0580713 -0.0192372 -0.05800500000000006 -0.0457077 -0.0278311 -0.05800500000000006 -0.0474291 -0.0311936 -0.05800500000000006 -0.0484936 -0.0258071 -0.05800500000000006 -0.050164 0.028795 -0.05800500000000006 -0.050164 0.0287944 -0.03245900000000006 -0.050164 0.032999 -0.05800500000000006 -0.0211946 0.024999 -0.008272910000000055 0.032415 0.024999 -0.006189010000000056 -0.028282 0.024999 0.02061499999999995 0.000279519 -0.0102152 -0.05800500000000006 -0.002982 -0.017147 -0.143005 0.000432999 -0.00988901 -0.143005 0.00300001 0.024999 -0.03700500000000006 0.005929 0.024999 -0.03392200000000006 -0.0211946 0.024999 -0.008272910000000055 -0.050164 0.0287944 -0.03245900000000006 -0.050164 0.032999 -0.009398000000000056 -0.050164 0.032999 -0.05800500000000006 -0.03 -0.041001 -0.05800500000000006 -0.0223997 -0.0310412 -0.05800500000000006 -0.022042 -0.030996 -0.05800500000000006 0.008704 -0.041001 -0.03390500000000005 0.016861 -0.041001 -0.03067600000000005 -0.03 -0.041001 0.01825699999999994 0.015898 0.024999 0.02891299999999995 0.015898 0.032999 0.02891299999999995 0.008207010000000001 0.024999 0.03195799999999994 -0.00371071 0.024999 -0.03700500000000006 -0.0308565 0.024999 -0.008648480000000056 -0.039 0.024999 -0.03700500000000006 -0.048519 0.022588 -0.03700500000000006 -0.045068 -0.032779 -0.03700500000000006 -0.042292 0.024726 -0.03700500000000006 -0.058932 0.00665 -0.02142500000000006 -0.0596031 -0.000297668 -0.02136220000000006 -0.058388 8.89978e-05 -0.03700500000000006 -0.048519 0.022588 -0.007143010000000055 -0.053715 0.018544 -0.03700500000000006 -0.048519 0.022588 -0.03700500000000006 0.019397 0.024999 -0.02670300000000006 0.012148 0.024999 -0.03068800000000006 0.012148 0.032999 -0.03068800000000006 -0.045417 -0.028042 -0.143005 -0.045416 -0.028043 -0.05800500000000006 -0.0457077 -0.0278311 -0.05800500000000006 -0.008206990000000001 0.024999 0.03195799999999994 0.008207010000000001 0.024999 0.03195799999999994 8.72213e-09 0.024999 0.03299499999999994 -0.058933 -0.006022 -0.03700500000000006 -0.058394 -0.013901 -0.03700500000000006 -0.058388 8.89978e-05 -0.03700500000000006 -0.0465 -0.03658 -0.004374010000000056 -0.037824 -0.035926 0.007525989999999944 -0.053335 -0.031336 -0.01374800000000006 -0.053715 0.018544 -0.03700500000000006 -0.051194 -0.027795 -0.03700500000000006 -0.048519 0.022588 -0.03700500000000006 -0.0463785 0.026383 -0.004206770000000056 -0.050164 0.0287943 -0.009398550000000056 -0.0471991 0.0260829 -0.005332310000000055 -0.0401397 -0.0347307 -0.05800500000000006 -0.037958 -0.030996 -0.05800500000000006 -0.0337794 -0.0315237 -0.05800500000000006 -0.037824 -0.035926 -0.03700500000000006 -0.039 0.024999 -0.03700500000000006 -0.042292 0.024726 -0.03700500000000006 -0.028281 -0.037001 0.02061499999999995 -0.03 -0.041001 0.01825699999999994 -0.028281 -0.041001 0.02061499999999995 -0.063 -0.008000999999999999 -0.02700500000000006 -0.063 -0.008000999999999999 -0.05800500000000006 -0.061876 -0.016542 -0.02546300000000006 0.00300001 0.024999 -0.03700500000000006 6.81479e-09 0.024999 -0.03700500000000006 0.00300001 -0.037001 -0.03700500000000006 0.00444089 0.032999 -0.02063940000000005 -0.0211951 0.032999 -0.008272280000000055 0.00541564 0.032999 -0.01612520000000005 0.032415 0.032999 -0.006189010000000056 0.032935 0.024999 0.002066989999999944 0.032415 0.024999 -0.006189010000000056 -0.0542666 -0.0204743 -0.05800500000000006 -0.057019 -0.017147 -0.05800500000000006 -0.057019 -0.017147 -0.143005 0.00438701 -0.041001 0.03471899999999994 -0.03 -0.041001 0.01825699999999994 0.012884 -0.041001 0.03253699999999995 -0.062933 0.006978 -0.02691200000000005 -0.062933 0.006978 -0.05800500000000006 -0.0623139 -0.000841381 -0.02690510000000006 0.031669 -0.041001 0.01489699999999995 0.03438 -0.041001 0.006552989999999944 0.03438 -0.037001 0.006552989999999944 0.003 0.0259881 -0.05590170000000005 0.003 0.032999 -0.04099300000000006 0.003 0.024999 -0.04099300000000006 -0.058394 -0.013901 -0.03700500000000006 -0.055749 -0.021343 -0.03700500000000006 -0.058388 8.89978e-05 -0.03700500000000006 -0.0415231 -0.0295844 -0.05800500000000006 -0.0465 -0.03658 -0.05800500000000006 -0.0474291 -0.0311936 -0.05800500000000006 -0.0542666 -0.0204743 -0.05800500000000006 -0.0535363 -0.0259051 -0.05800500000000006 -0.058579 -0.024501 -0.05800500000000006 -0.058933 -0.006022 -0.03700500000000006 -0.0596031 -0.000297668 -0.02136220000000006 -0.058933 -0.006022 -0.02142600000000006 -0.0596031 -0.000297668 -0.02136220000000006 -0.062933 0.006978 -0.02691200000000005 -0.0623139 -0.000841381 -0.02690510000000006 -0.03 -0.037001 0.01825699999999994 0.020572 -0.037001 0.02830999999999994 0.026968 -0.037001 0.02230499999999994 -0.008206990000000001 0.032999 0.03195799999999994 -0.015898 0.024999 0.02891299999999995 -0.008206990000000001 0.024999 0.03195799999999994 0.034931 -0.037001 -0.002203010000000056 -0.03 -0.037001 0.01825699999999994 0.03438 -0.037001 0.006552989999999944 -0.002982 -0.017147 -0.143005 0.000279519 -0.0102152 -0.05800500000000006 -0.002982 -0.017147 -0.05800500000000006 -0.058394 -0.013901 -0.02068700000000006 -0.058933 -0.006022 -0.02142600000000006 -0.063 -0.008000999999999999 -0.02700500000000006 0.033287 -0.037001 -0.01082100000000006 0.034931 -0.041001 -0.002203010000000056 0.033287 -0.041001 -0.01082100000000006 0.00300001 -0.037001 -0.03700500000000006 0.003 -0.041001 -0.05800500000000006 0.003 0.005499 -0.05800500000000006 -0.008095 -0.023328 -0.05800500000000006 -0.008095 -0.023328 -0.143005 -0.0032118 -0.0174248 -0.05800500000000006 0.032415 0.032999 -0.006189010000000056 -0.0211951 0.032999 -0.008272280000000055 -0.028282 0.032999 0.02061499999999995 -0.036226 0.024999 -0.007533000000000055 -0.039 0.024999 -0.008965040000000056 -0.039 0.024999 -0.03700500000000006 -0.050164 0.024999 -0.009399000000000055 -0.028282 0.024999 0.02061499999999995 -0.0471991 0.0260829 -0.005332310000000055 -0.045068 -0.032779 -0.03700500000000006 -0.045068 -0.032779 -0.002410000000000055 -0.037824 -0.035926 -0.03700500000000006 -0.053715 0.018544 -0.03700500000000006 -0.053715 0.018544 -0.01426900000000006 -0.057316 0.013033 -0.03700500000000006 -0.037959 -0.030995 -0.143005 -0.0382932 -0.0308632 -0.05800500000000006 -0.045417 -0.028042 -0.143005 -0.0343095 0.032999 -0.02389350000000006 -0.04155 0.032999 -0.01727360000000006 -0.0280051 0.032999 -0.02256690000000006 0.00560997 0.032999 -0.01012250000000006 0.032415 0.032999 -0.006189010000000056 0.029859 0.032999 -0.01405600000000006 -0.00438699 -0.037001 0.03471899999999994 0.00438701 -0.037001 0.03471899999999994 -0.03 -0.037001 0.01825699999999994 -0.0535363 -0.0259051 -0.05800500000000006 -0.053335 -0.031336 -0.05800500000000006 -0.058579 -0.024501 -0.05800500000000006 -0.039 0.024999 -0.008965040000000056 -0.036226 0.024999 -0.007533000000000055 -0.036914 0.024999 0.002519999999999945 -0.012884 -0.037001 0.03253699999999995 -0.00438699 -0.037001 0.03471899999999994 -0.03 -0.037001 0.01825699999999994 -0.051906 -0.023328 -0.05800500000000006 -0.0521358 -0.0230502 -0.05800500000000006 -0.051906 -0.023328 -0.143005 -0.045068 -0.032779 -0.002410000000000055 -0.051194 -0.027795 -0.01081200000000006 -0.053335 -0.031336 -0.01374800000000006 -0.00371071 0.024999 -0.03700500000000006 -0.0211946 0.024999 -0.008272910000000055 -0.0308565 0.024999 -0.008648480000000056 -0.052302 0.027495 -0.05800500000000006 -0.050164 0.028795 -0.05800500000000006 -0.050164 0.032999 -0.05800500000000006 -0.050164 0.0287943 -0.02680210000000005 -0.050164 0.0287943 -0.009398550000000056 -0.050164 0.032999 -0.009398000000000056 -0.04155 0.032999 -0.05800500000000006 -0.050164 0.032999 -0.05800500000000006 -0.045857 0.032999 -0.03370150000000006 -0.055749 -0.021343 -0.01705900000000006 -0.055749 -0.021343 -0.03700500000000006 -0.058394 -0.013901 -0.02068700000000006 -0.038541 -0.039877 -0.05800500000000006 -0.0401397 -0.0347307 -0.05800500000000006 -0.0337794 -0.0315237 -0.05800500000000006 -0.0032118 -0.0174248 -0.05800500000000006 -0.008095 -0.023328 -0.143005 -0.002982 -0.017147 -0.143005 -0.0147987 0.00549899 -0.143005 -0.00776776 0.00549899 -0.143005 -0.037959 -0.030995 -0.143005 -0.063 -0.008000999999999999 -0.02700500000000006 -0.058933 -0.006022 -0.02142600000000006 -0.0623139 -0.000841381 -0.02690510000000006 -0.028282 0.024999 0.02061499999999995 -0.0463785 0.026383 -0.004206770000000056 -0.0471991 0.0260829 -0.005332310000000055 0.031385 0.024999 0.01019299999999995 0.032935 0.032999 0.002066989999999944 0.031385 0.032999 0.01019299999999995 0.032935 0.032999 0.002066989999999944 -0.028282 0.032999 0.02061499999999995 0.031385 0.032999 0.01019299999999995 -0.00776776 0.00549899 -0.143005 -0.00367516 0.00549899 -0.143005 -0.037959 -0.030995 -0.143005 -0.053335 -0.031336 -0.05800500000000006 -0.0535363 -0.0259051 -0.05800500000000006 -0.0484936 -0.0258071 -0.05800500000000006 -0.018664 0.024999 0.02720999999999995 0.02259 0.024999 0.02405099999999994 0.015898 0.024999 0.02891299999999995 -0.037959 -0.030995 -0.143005 -0.0551317 0.005499 -0.143005 -0.0498164 0.005499 -0.143005 -0.0415231 -0.0295844 -0.05800500000000006 -0.0401397 -0.0347307 -0.05800500000000006 -0.0465 -0.03658 -0.05800500000000006 0.003 0.024999 -0.05560500000000006 0.00300001 -0.037001 -0.03700500000000006 0.003 0.008739480000000001 -0.05800500000000006 -0.020573 -0.037001 0.02831099999999994 -0.012884 -0.037001 0.03253699999999995 -0.03 -0.037001 0.01825699999999994 0.033287 -0.041001 -0.01082100000000006 0.029551 -0.041001 -0.01875900000000006 0.029551 -0.037001 -0.01875900000000006 -0.060434 -0.00988996 -0.05800500000000006 -0.0585124 -0.0139735 -0.05800500000000006 -0.0607562 -0.011659 -0.05800500000000006 -0.0620423 -0.00410213 -0.05798660000000005 -0.063 -0.008000999999999999 -0.05800500000000006 -0.0630566 -0.000834875 -0.05796500000000006 -0.035351 0.032999 0.01091799999999995 -0.050164 0.032999 -0.009398000000000056 -0.0463785 0.026383 -0.004206770000000056 -0.020573 -0.037001 0.02831099999999994 -0.03 -0.037001 0.01825699999999994 -0.026968 -0.037001 0.02230499999999994 0.027863 0.024999 0.01767699999999994 0.02259 0.024999 0.02405099999999994 -0.028282 0.024999 0.02061499999999995 0.031385 0.024999 0.01019299999999995 0.027863 0.024999 0.01767699999999994 -0.028282 0.024999 0.02061499999999995 0.023959 -0.037001 -0.02551900000000006 -0.03 -0.037001 0.01825699999999994 0.029551 -0.037001 -0.01875900000000006 -0.0535363 -0.0259051 -0.05800500000000006 -0.051906 -0.023328 -0.05800500000000006 -0.0484936 -0.0258071 -0.05800500000000006 -0.061028 -0.00677597 -0.05800500000000006 -0.061937 -0.00201 -0.05797540000000006 -0.061938 -0.00201 -0.143005 0.012884 -0.037001 0.03253699999999995 0.020572 -0.037001 0.02830999999999994 -0.03 -0.037001 0.01825699999999994 -0.04155 0.032999 -0.01727360000000006 -0.0211951 0.032999 -0.008272280000000055 -0.0280051 0.032999 -0.02256690000000006 -0.037824 -0.035926 -0.03700500000000006 -0.00371071 0.024999 -0.03700500000000006 -0.039 0.024999 -0.03700500000000006 -0.032144 -0.0362324 -0.05800500000000006 -0.038541 -0.039877 -0.05800500000000006 -0.0337794 -0.0315237 -0.05800500000000006 -0.012884 -0.037001 0.03253699999999995 -0.020573 -0.037001 0.02831099999999994 -0.020573 -0.041001 0.02831099999999994 -0.061326 0.01471 -0.05800500000000006 -0.062933 0.006978 -0.02691200000000005 -0.061326 0.01471 -0.02470800000000006 -0.050164 0.032999 -0.009398000000000056 -0.035351 0.032999 0.01091799999999995 -0.04155 0.032999 -0.01727360000000006 0.020572 -0.037001 0.02830999999999994 0.012884 -0.037001 0.03253699999999995 0.012884 -0.041001 0.03253699999999995 -0.0614652 0.005499 -0.143005 -0.061938 -0.00201 -0.143005 -0.0614652 0.005499 -0.1374900000000001 -0.055749 -0.021343 -0.01705900000000006 -0.058394 -0.013901 -0.02068700000000006 -0.061876 -0.016542 -0.02546300000000006 -0.028282 0.024999 0.02061499999999995 -0.028282 0.032999 0.02061499999999995 -0.0463785 0.026383 -0.004206770000000056 -0.050164 0.0287943 -0.009398550000000056 -0.050164 0.0287943 -0.02680210000000005 -0.052302 0.027494 -0.01233100000000006 -0.028281 -0.037001 0.02061499999999995 -0.03 -0.037001 0.01825699999999994 -0.038541 -0.039877 0.006542989999999945 -0.028282 0.032999 0.02061499999999995 -0.035351 0.032999 0.01091799999999995 -0.0463785 0.026383 -0.004206770000000056 -0.03 -0.032001 -0.05800500000000006 -0.025747 -0.0314639 -0.05800500000000006 -0.032144 -0.0362324 -0.05800500000000006 -0.0343095 0.032999 -0.02389350000000006 -0.0412745 0.032999 -0.05800500000000006 -0.04155 0.032999 -0.05800500000000006 0.023959 -0.041001 -0.02551900000000006 0.023959 -0.037001 -0.02551900000000006 0.029551 -0.041001 -0.01875900000000006 -0.014584 -0.028042 -0.143005 -0.022043 -0.030995 -0.143005 -0.037959 -0.030995 -0.143005 -0.020573 -0.041001 0.02831099999999994 -0.03 -0.041001 0.01825699999999994 -0.012884 -0.041001 0.03253699999999995 0.016861 -0.037001 -0.03067600000000005 -0.03 -0.037001 0.01825699999999994 0.023959 -0.037001 -0.02551900000000006 -0.0474291 -0.0311936 -0.05800500000000006 -0.053335 -0.031336 -0.05800500000000006 -0.0484936 -0.0258071 -0.05800500000000006 0.031669 -0.041001 0.01489699999999995 0.03438 -0.037001 0.006552989999999944 0.031669 -0.037001 0.01489699999999995 0.008704 -0.037001 -0.03390500000000005 0.008704 -0.041001 -0.03390500000000005 0.00300001 -0.037001 -0.03487600000000005 -0.061937 -0.00201 -0.05797540000000006 -0.0620423 -0.00410213 -0.05798660000000005 -0.0630566 -0.000834875 -0.05796500000000006 -0.03 -0.041001 0.01825699999999994 0.023959 -0.041001 -0.02551900000000006 0.029551 -0.041001 -0.01875900000000006 0.00300001 -0.037001 -0.03700500000000006 0.003 0.005499 -0.05800500000000006 0.003 0.008739480000000001 -0.05800500000000006 -0.0356626 0.005499 -0.143005 -0.0309972 0.005499 -0.143005 -0.037959 -0.030995 -0.143005 0.016861 -0.041001 -0.03067600000000005 0.023959 -0.041001 -0.02551900000000006 -0.03 -0.041001 0.01825699999999994 -0.03 -0.041001 0.01825699999999994 0.031669 -0.041001 0.01489699999999995 0.026968 -0.041001 0.02230499999999994 0.003 -0.041001 -0.05800500000000006 0.001936 -0.00201 -0.05800500000000006 0.003 0.005499 -0.05800500000000006 -0.0580713 -0.0192372 -0.05800500000000006 -0.0542666 -0.0204743 -0.05800500000000006 -0.058579 -0.024501 -0.05800500000000006 -0.0614652 0.005499 -0.143005 -0.0611192 0.005499 -0.143005 -0.061938 -0.00201 -0.143005 -0.061876 -0.016542 -0.05800500000000006 -0.058579 -0.024501 -0.05800500000000006 -0.058579 -0.024501 -0.02094100000000006 0.008207010000000001 0.032999 0.03195799999999994 -0.008206990000000001 0.032999 0.03195799999999994 9.071820000000001e-09 0.032999 0.03299499999999994 0.019397 0.024999 -0.02670300000000006 0.012148 0.032999 -0.03068800000000006 0.019397 0.032999 -0.02670300000000006 -0.008386640000000001 -0.0235399 -0.05800500000000006 -0.008095 -0.023328 -0.143005 -0.008095 -0.023328 -0.05800500000000006 0.032415 0.024999 -0.006189010000000056 0.029859 0.024999 -0.01405600000000006 0.029859 0.032999 -0.01405600000000006 0.001936 -0.00201001 -0.143005 0.000432999 -0.00988901 -0.143005 -0.037959 -0.030995 -0.143005 -0.0309972 0.005499 -0.143005 -0.0261013 0.00549899 -0.143005 -0.037959 -0.030995 -0.143005 -0.03 -0.041001 0.01825699999999994 -0.026968 -0.041001 0.02230499999999994 -0.028281 -0.041001 0.02061499999999995 -0.0223997 -0.0310412 -0.05800500000000006 -0.022043 -0.030995 -0.143005 -0.022042 -0.030996 -0.05800500000000006 0.005929 0.024999 -0.03392200000000006 0.00376101 0.024999 -0.03716600000000005 0.00376101 0.032999 -0.03716600000000005 0.033287 -0.037001 -0.01082100000000006 0.034931 -0.037001 -0.002203010000000056 0.034931 -0.041001 -0.002203010000000056 -0.055749 -0.021343 -0.03700500000000006 -0.058394 -0.013901 -0.03700500000000006 -0.058394 -0.013901 -0.02068700000000006 -0.03 -0.037001 0.01825699999999994 -0.03 -0.037001 -0.03700500000000006 -0.037824 -0.035926 0.007525989999999944 -0.020573 -0.041001 0.02831099999999994 -0.026968 -0.041001 0.02230499999999994 -0.03 -0.041001 0.01825699999999994 -0.058933 -0.006022 -0.02142600000000006 -0.0596031 -0.000297668 -0.02136220000000006 -0.0623139 -0.000841381 -0.02690510000000006 -0.037959 -0.030995 -0.143005 -0.0303577 -0.0319558 -0.05800500000000006 -0.0337794 -0.0315237 -0.05800500000000006 -0.038541 -0.039877 -0.05800500000000006 -0.03 -0.041001 0.01825699999999994 -0.038541 -0.039877 0.006542989999999945 0.031385 0.024999 0.01019299999999995 0.031385 0.032999 0.01019299999999995 0.027863 0.024999 0.01767699999999994 -0.0308565 0.024999 -0.008648480000000056 -0.036226 0.024999 -0.007533000000000055 -0.039 0.024999 -0.03700500000000006 -0.0432793 0.024999 4.394579999994449e-05 -0.042292 0.024726 0.001397999999999944 -0.039 0.024999 0.005912989999999944 0.000432999 -0.00988901 -0.143005 -0.002982 -0.017147 -0.143005 -0.037959 -0.030995 -0.143005 -0.026968 -0.041001 0.02230499999999994 -0.026968 -0.037001 0.02230499999999994 -0.028281 -0.041001 0.02061499999999995 -0.0585124 -0.0139735 -0.05800500000000006 -0.0571725 -0.0168208 -0.05800500000000006 -0.061876 -0.016542 -0.05800500000000006 -0.050164 0.032999 -0.009398000000000056 -0.050164 0.0287943 -0.009398550000000056 -0.0463785 0.026383 -0.004206770000000056 -0.030001 -0.032001 -0.143005 -0.03 -0.032001 -0.05800500000000006 -0.0303577 -0.0319558 -0.05800500000000006 0.012884 -0.037001 0.03253699999999995 0.00438701 -0.041001 0.03471899999999994 0.012884 -0.041001 0.03253699999999995 0.00300001 -0.037001 -0.03487600000000005 0.00300001 -0.041001 -0.03487600000000005 0.00300001 -0.037001 -0.03700500000000006 0.008704 -0.041001 -0.03390500000000005 0.00300001 -0.041001 -0.03487600000000005 0.00300001 -0.037001 -0.03487600000000005 -0.051194 -0.027795 -0.01081200000000006 -0.045068 -0.032779 -0.002410000000000055 -0.045068 -0.032779 -0.03700500000000006 6.81479e-09 0.024999 -0.03700500000000006 -0.03 -0.037001 -0.03700500000000006 0.00300001 -0.037001 -0.03700500000000006 -0.0623139 -0.000841381 -0.02690510000000006 -0.062933 0.006978 -0.05800500000000006 -0.0629566 0.00547481 -0.05799990000000006 -0.008206990000000001 0.032999 0.03195799999999994 -0.015898 0.032999 0.02891299999999995 -0.015898 0.024999 0.02891299999999995 0.00034425 0.032999 -0.03941470000000005 0.00376101 0.032999 -0.03716600000000005 0.003 0.032999 -0.04099300000000006 -0.037959 -0.030995 -0.143005 -0.0498164 0.005499 -0.143005 -0.0449206 0.005499 -0.143005 -0.015898 0.032999 0.02891299999999995 -0.018664 0.024999 0.02720999999999995 -0.015898 0.024999 0.02891299999999995 -0.051194 -0.027795 -0.03700500000000006 -0.051194 -0.027795 -0.01081200000000006 -0.045068 -0.032779 -0.03700500000000006 -0.0614652 0.005499 -0.06771010000000005 -0.0619146 -0.00165306 -0.05797350000000005 -0.0618235 -0.000203272 -0.05796570000000006 -0.063 -0.008000999999999999 -0.05800500000000006 -0.063 -0.008000999999999999 -0.02700500000000006 -0.0630566 -0.000834875 -0.05796500000000006 0.00560997 0.032999 -0.01012250000000006 0.029859 0.032999 -0.01405600000000006 0.00541564 0.032999 -0.01612520000000005 -0.0585124 -0.0139735 -0.05800500000000006 -0.060434 -0.00988996 -0.05800500000000006 -0.060434 -0.009889 -0.143005 -0.0630566 -0.000834875 -0.05796500000000006 -0.0629566 0.00547481 -0.05799990000000006 -0.0614652 0.005499 -0.05800500000000006 0.027863 0.032999 0.01767699999999994 0.02259 0.024999 0.02405099999999994 0.027863 0.024999 0.01767699999999994 -0.022043 -0.030995 -0.143005 -0.0149192 -0.0281757 -0.05800500000000006 -0.022042 -0.030996 -0.05800500000000006 0.00034425 0.032999 -0.03941470000000005 0.003 0.032999 -0.04099300000000006 0.003 0.032999 -0.05800500000000006 -0.057019 -0.017147 -0.143005 -0.0571725 -0.0168208 -0.05800500000000006 -0.060434 -0.009889 -0.143005 0.020572 -0.041001 0.02830999999999994 -0.03 -0.041001 0.01825699999999994 0.026968 -0.041001 0.02230499999999994 -0.0111428 0.032999 -0.03258800000000005 0.00034425 0.032999 -0.03941470000000005 0.003 0.032999 -0.05800500000000006 -0.0308565 0.024999 -0.008648480000000056 -0.0211946 0.024999 -0.008272910000000055 -0.035351 0.024999 0.01091799999999995 -0.0619146 -0.00165306 -0.05797350000000005 -0.0614652 0.005499 -0.06771010000000005 -0.0614652 0.005499 -0.1374900000000001 -0.03 -0.037001 0.01825699999999994 -0.0465 -0.03658 -0.004374010000000056 -0.038541 -0.039877 0.006542989999999945 0.008207010000000001 0.032999 0.03195799999999994 9.071820000000001e-09 0.032999 0.03299499999999994 8.72213e-09 0.024999 0.03299499999999994 -0.025747 -0.0314639 -0.05800500000000006 -0.030001 -0.032001 -0.143005 -0.0223997 -0.0310412 -0.05800500000000006 0.016861 -0.041001 -0.03067600000000005 0.008704 -0.037001 -0.03390500000000005 0.016861 -0.037001 -0.03067600000000005 0.020572 -0.041001 0.02830999999999994 0.020572 -0.037001 0.02830999999999994 0.012884 -0.041001 0.03253699999999995 0.032415 0.032999 -0.006189010000000056 0.032415 0.024999 -0.006189010000000056 0.029859 0.032999 -0.01405600000000006 -0.0611192 0.005499 -0.143005 -0.037959 -0.030995 -0.143005 -0.061938 -0.00201 -0.143005 -0.028282 0.032999 0.02061499999999995 0.027863 0.032999 0.01767699999999994 0.031385 0.032999 0.01019299999999995 -0.048519 0.022588 -0.007143010000000055 -0.053715 0.018544 -0.01426900000000006 -0.053715 0.018544 -0.03700500000000006 -0.0149192 -0.0281757 -0.05800500000000006 -0.014584 -0.028042 -0.143005 -0.014584 -0.028043 -0.05800500000000006 -0.061876 -0.016542 -0.05800500000000006 -0.0580713 -0.0192372 -0.05800500000000006 -0.058579 -0.024501 -0.05800500000000006 0.032415 0.024999 -0.006189010000000056 0.032935 0.024999 0.002066989999999944 -0.028282 0.024999 0.02061499999999995 -0.061937 -0.00201 -0.05797540000000006 -0.061028 -0.00677597 -0.05800500000000006 -0.0620423 -0.00410213 -0.05798660000000005 0.00186845 -0.00236411 -0.05800500000000006 0.001936 -0.00201 -0.05800500000000006 0.003 -0.041001 -0.05800500000000006 0.026968 -0.037001 0.02230499999999994 0.020572 -0.041001 0.02830999999999994 0.026968 -0.041001 0.02230499999999994 0.032935 0.024999 0.002066989999999944 0.032935 0.032999 0.002066989999999944 0.031385 0.024999 0.01019299999999995 -0.002982 -0.017147 -0.143005 -0.008095 -0.023328 -0.143005 -0.037959 -0.030995 -0.143005 -0.051906 -0.023328 -0.05800500000000006 -0.051906 -0.023328 -0.143005 -0.0484936 -0.0258071 -0.05800500000000006 -0.0415231 -0.0295844 -0.05800500000000006 -0.045416 -0.028043 -0.05800500000000006 -0.045417 -0.028042 -0.143005 0.00997601 0.032999 -0.03146100000000006 0.012148 0.024999 -0.03068800000000006 0.00997601 0.024999 -0.03146100000000006 -0.0382932 -0.0308632 -0.05800500000000006 -0.037958 -0.030996 -0.05800500000000006 -0.0401397 -0.0347307 -0.05800500000000006 0.023959 -0.041001 -0.02551900000000006 0.016861 -0.041001 -0.03067600000000005 0.016861 -0.037001 -0.03067600000000005 -0.038541 -0.039877 -0.05800500000000006 -0.038541 -0.039877 0.006542989999999945 -0.0465 -0.03658 -0.05800500000000006 -0.0571725 -0.0168208 -0.05800500000000006 -0.0585124 -0.0139735 -0.05800500000000006 -0.060434 -0.009889 -0.143005 0.00438701 -0.041001 0.03471899999999994 0.00438701 -0.037001 0.03471899999999994 -0.00438699 -0.041001 0.03471899999999994 0.029859 0.032999 -0.01405600000000006 0.025427 0.032999 -0.02104000000000006 0.00541564 0.032999 -0.01612520000000005 -0.026968 -0.037001 0.02230499999999994 -0.028281 -0.037001 0.02061499999999995 -0.028281 -0.041001 0.02061499999999995 -0.018664 0.024999 0.02720999999999995 0.015898 0.024999 0.02891299999999995 -0.015898 0.024999 0.02891299999999995 -0.058932 0.00665 -0.03700500000000006 -0.058932 0.00665 -0.02142500000000006 -0.058388 8.89978e-05 -0.03700500000000006 -0.03 -0.041001 0.01825699999999994 -0.038541 -0.039877 -0.05800500000000006 -0.03 -0.041001 -0.05800500000000006 -0.037958 -0.030996 -0.05800500000000006 -0.037959 -0.030995 -0.143005 -0.0337794 -0.0315237 -0.05800500000000006 -0.0402551 0.005499 -0.143005 -0.037959 -0.030995 -0.143005 -0.0449206 0.005499 -0.143005 -0.03 -0.037001 -0.03700500000000006 -0.03 -0.037001 0.01825699999999994 0.00300001 -0.037001 -0.03700500000000006 0.032935 0.032999 0.002066989999999944 0.032415 0.032999 -0.006189010000000056 -0.028282 0.032999 0.02061499999999995 0.033287 -0.037001 -0.01082100000000006 0.033287 -0.041001 -0.01082100000000006 0.029551 -0.037001 -0.01875900000000006 -0.055749 -0.021343 -0.03700500000000006 -0.051194 -0.027795 -0.03700500000000006 -0.053715 0.018544 -0.03700500000000006 0.008207010000000001 0.024999 0.03195799999999994 0.008207010000000001 0.032999 0.03195799999999994 8.72213e-09 0.024999 0.03299499999999994 -0.0542666 -0.0204743 -0.05800500000000006 -0.057019 -0.017147 -0.143005 -0.0521358 -0.0230502 -0.05800500000000006 -0.051906 -0.023328 -0.143005 -0.037959 -0.030995 -0.143005 -0.045417 -0.028042 -0.143005 0.015898 0.024999 0.02891299999999995 0.02259 0.024999 0.02405099999999994 0.02259 0.032999 0.02405099999999994 -0.030001 -0.032001 -0.143005 -0.022043 -0.030995 -0.143005 -0.0223997 -0.0310412 -0.05800500000000006 -0.008095 -0.023328 -0.143005 -0.008386640000000001 -0.0235399 -0.05800500000000006 -0.014584 -0.028042 -0.143005 -0.060434 -0.00988996 -0.05800500000000006 -0.0607562 -0.011659 -0.05800500000000006 -0.063 -0.008000999999999999 -0.05800500000000006 0.000903742 0.00549899 -0.143005 0.001936 -0.00201001 -0.143005 -0.037959 -0.030995 -0.143005 0.000279519 -0.0102152 -0.05800500000000006 0.000433002 -0.009889 -0.05800500000000006 0.003 -0.041001 -0.05800500000000006 -0.038541 -0.039877 -0.05800500000000006 -0.032144 -0.0362324 -0.05800500000000006 -0.03 -0.041001 -0.05800500000000006 0.003 0.024999 -0.04099300000000006 0.00300001 -0.037001 -0.03700500000000006 0.003 0.024999 -0.05560500000000006 -0.0402551 0.005499 -0.143005 -0.0356626 0.005499 -0.143005 -0.037959 -0.030995 -0.143005 -0.0415231 -0.0295844 -0.05800500000000006 -0.0382932 -0.0308632 -0.05800500000000006 -0.0401397 -0.0347307 -0.05800500000000006 -0.058394 -0.013901 -0.02068700000000006 -0.058394 -0.013901 -0.03700500000000006 -0.058933 -0.006022 -0.02142600000000006 0.00997601 0.024999 -0.03146100000000006 0.005929 0.024999 -0.03392200000000006 0.005929 0.032999 -0.03392200000000006 -0.051906 -0.023328 -0.143005 -0.045417 -0.028042 -0.143005 -0.0457077 -0.0278311 -0.05800500000000006 -0.0630566 -0.000834875 -0.05796500000000006 -0.063 -0.008000999999999999 -0.02700500000000006 -0.0623139 -0.000841381 -0.02690510000000006 -0.0303577 -0.0319558 -0.05800500000000006 -0.032144 -0.0362324 -0.05800500000000006 -0.0337794 -0.0315237 -0.05800500000000006 -0.035351 0.024999 0.01091799999999995 -0.0211946 0.024999 -0.008272910000000055 -0.028282 0.024999 0.02061499999999995 -0.061938 -0.00201 -0.143005 -0.061937 -0.00201 -0.05797540000000006 -0.0617011 0.00174447 -0.1004890000000001 -0.0261013 0.00549899 -0.143005 -0.0207863 0.00549899 -0.143005 -0.037959 -0.030995 -0.143005 -0.058932 0.00665 -0.03700500000000006 -0.057316 0.013033 -0.01920800000000005 -0.058932 0.00665 -0.02142500000000006 0.015898 0.024999 0.02891299999999995 0.02259 0.032999 0.02405099999999994 0.015898 0.032999 0.02891299999999995 -0.014584 -0.028042 -0.143005 -0.008386640000000001 -0.0235399 -0.05800500000000006 -0.014584 -0.028043 -0.05800500000000006 -0.030001 -0.032001 -0.143005 -0.025747 -0.0314639 -0.05800500000000006 -0.03 -0.032001 -0.05800500000000006 0.031669 -0.041001 0.01489699999999995 -0.03 -0.041001 0.01825699999999994 0.03438 -0.041001 0.006552989999999944 0.00997601 0.032999 -0.03146100000000006 0.00997601 0.024999 -0.03146100000000006 0.005929 0.032999 -0.03392200000000006 -0.058932 0.00665 -0.03700500000000006 -0.058388 8.89978e-05 -0.03700500000000006 -0.057316 0.013033 -0.03700500000000006 9.071820000000001e-09 0.032999 0.03299499999999994 -0.008206990000000001 0.024999 0.03195799999999994 8.72213e-09 0.024999 0.03299499999999994 -0.057019 -0.017147 -0.05800500000000006 -0.0542666 -0.0204743 -0.05800500000000006 -0.0580713 -0.0192372 -0.05800500000000006 0.025427 0.024999 -0.02104000000000006 0.019397 0.024999 -0.02670300000000006 0.019397 0.032999 -0.02670300000000006 -0.0211951 0.032999 -0.008272280000000055 -0.0111428 0.032999 -0.03258800000000005 -0.0280051 0.032999 -0.02256690000000006 0.03438 -0.041001 0.006552989999999944 -0.03 -0.041001 0.01825699999999994 0.034931 -0.041001 -0.002203010000000056 -0.03 -0.041001 0.01825699999999994 -0.028281 -0.037001 0.02061499999999995 -0.038541 -0.039877 0.006542989999999945 0.00300001 -0.041001 -0.03487600000000005 0.008704 -0.041001 -0.03390500000000005 -0.03 -0.041001 0.01825699999999994 -0.061876 -0.016542 -0.05800500000000006 -0.058579 -0.024501 -0.02094100000000006 -0.061876 -0.016542 -0.02546300000000006 -0.052302 0.027495 -0.05800500000000006 -0.057693 0.021723 -0.05800500000000006 -0.057692 0.021723 -0.01972500000000005 0.029859 0.032999 -0.01405600000000006 0.029859 0.024999 -0.01405600000000006 0.025427 0.032999 -0.02104000000000006 -0.061326 0.01471 -0.02470800000000006 -0.053715 0.018544 -0.01426900000000006 -0.057692 0.021723 -0.01972500000000005 -0.0614652 0.005499 -0.06771010000000005 -0.0618235 -0.000203272 -0.05796570000000006 -0.0614652 0.005499 -0.05800500000000006 -0.0032118 -0.0174248 -0.05800500000000006 -0.002982 -0.017147 -0.143005 -0.002982 -0.017147 -0.05800500000000006 0.000432999 -0.00988901 -0.143005 0.001936 -0.00201001 -0.143005 0.00186845 -0.00236411 -0.05800500000000006 -0.015898 0.032999 0.02891299999999995 0.015898 0.032999 0.02891299999999995 -0.018664 0.032999 0.02720999999999995 -0.0457077 -0.0278311 -0.05800500000000006 -0.045416 -0.028043 -0.05800500000000006 -0.0474291 -0.0311936 -0.05800500000000006 -0.037824 -0.035926 0.007525989999999944 -0.03 -0.037001 -0.03700500000000006 -0.037824 -0.035926 -0.03700500000000006 -0.008206990000000001 0.032999 0.03195799999999994 0.008207010000000001 0.032999 0.03195799999999994 -0.015898 0.032999 0.02891299999999995 0.003 0.032999 -0.04099300000000006 0.00376101 0.024999 -0.03716600000000005 0.003 0.024999 -0.04099300000000006 0.00300001 0.024999 -0.03700500000000006 -0.0211946 0.024999 -0.008272910000000055 6.81479e-09 0.024999 -0.03700500000000006 -0.012884 -0.037001 0.03253699999999995 -0.020573 -0.041001 0.02831099999999994 -0.012884 -0.041001 0.03253699999999995 0.00300001 -0.037001 -0.03700500000000006 0.00300001 -0.041001 -0.03487600000000005 0.003 -0.041001 -0.05800500000000006 -0.050164 0.032999 -0.009398000000000056 -0.04155 0.032999 -0.01727360000000006 -0.045857 0.032999 -0.03370150000000006 0.00300001 -0.041001 -0.03487600000000005 -0.03 -0.041001 0.01825699999999994 0.003 -0.041001 -0.05800500000000006 -0.058579 -0.024501 -0.05800500000000006 -0.053335 -0.031336 -0.01374800000000006 -0.058579 -0.024501 -0.02094100000000006 -0.051194 -0.027795 -0.03700500000000006 -0.055749 -0.021343 -0.03700500000000006 -0.055749 -0.021343 -0.01705900000000006 -0.002982 -0.017147 -0.05800500000000006 0.000279519 -0.0102152 -0.05800500000000006 0.003 -0.041001 -0.05800500000000006 -0.015898 0.032999 0.02891299999999995 0.008207010000000001 0.032999 0.03195799999999994 0.015898 0.032999 0.02891299999999995 -0.00438699 -0.037001 0.03471899999999994 -0.012884 -0.037001 0.03253699999999995 -0.012884 -0.041001 0.03253699999999995 -0.018664 0.024999 0.02720999999999995 -0.015898 0.032999 0.02891299999999995 -0.018664 0.032999 0.02720999999999995 -0.042292 0.024726 0.001397999999999944 -0.048519 0.022588 -0.007143010000000055 -0.048519 0.022588 -0.03700500000000006 -0.053335 -0.031336 -0.05800500000000006 -0.0465 -0.03658 -0.004374010000000056 -0.053335 -0.031336 -0.01374800000000006 0.00146417 0.005499 -0.05800500000000006 0.001936 -0.00201 -0.05800500000000006 0.00146417 0.005499 -0.05951950000000006 -0.057693 0.021723 -0.05800500000000006 -0.061326 0.01471 -0.02470800000000006 -0.057692 0.021723 -0.01972500000000005 -0.045068 -0.032779 -0.03700500000000006 -0.037824 -0.035926 -0.03700500000000006 -0.042292 0.024726 -0.03700500000000006 0.000433002 -0.009889 -0.05800500000000006 0.00186845 -0.00236411 -0.05800500000000006 0.003 -0.041001 -0.05800500000000006 -0.058579 -0.024501 -0.05800500000000006 -0.053335 -0.031336 -0.05800500000000006 -0.053335 -0.031336 -0.01374800000000006 0.000433002 -0.009889 -0.05800500000000006 0.000279519 -0.0102152 -0.05800500000000006 0.000432999 -0.00988901 -0.143005 -0.0620423 -0.00410213 -0.05798660000000005 -0.061028 -0.00677597 -0.05800500000000006 -0.063 -0.008000999999999999 -0.05800500000000006 -0.012884 -0.041001 0.03253699999999995 -0.03 -0.041001 0.01825699999999994 -0.00438699 -0.041001 0.03471899999999994 0.00146417 0.005499 -0.05951950000000006 0.001936 -0.00201001 -0.143005 0.00146423 0.00549899 -0.143005 -0.036226 0.024999 -0.007533000000000055 -0.035351 0.024999 0.01091799999999995 -0.036914 0.024999 0.002519999999999945 0.023959 -0.041001 -0.02551900000000006 0.016861 -0.037001 -0.03067600000000005 0.023959 -0.037001 -0.02551900000000006 -0.008386640000000001 -0.0235399 -0.05800500000000006 -0.008095 -0.023328 -0.05800500000000006 0.003 -0.041001 -0.05800500000000006 -0.037959 -0.030995 -0.143005 -0.060434 -0.009889 -0.143005 -0.061938 -0.00201 -0.143005 -0.0605016 -0.00953584 -0.05800500000000006 -0.060434 -0.00988996 -0.05800500000000006 -0.063 -0.008000999999999999 -0.05800500000000006 0.031669 -0.041001 0.01489699999999995 0.031669 -0.037001 0.01489699999999995 0.026968 -0.041001 0.02230499999999994 -0.028282 0.032999 0.02061499999999995 -0.018664 0.024999 0.02720999999999995 -0.018664 0.032999 0.02720999999999995 -0.051906 -0.023328 -0.143005 -0.0457077 -0.0278311 -0.05800500000000006 -0.0484936 -0.0258071 -0.05800500000000006 -0.060434 -0.009889 -0.143005 -0.0605016 -0.00953584 -0.05800500000000006 -0.061938 -0.00201 -0.143005 -0.057019 -0.017147 -0.143005 -0.037959 -0.030995 -0.143005 -0.051906 -0.023328 -0.143005 0.016861 -0.041001 -0.03067600000000005 0.008704 -0.041001 -0.03390500000000005 0.008704 -0.037001 -0.03390500000000005 -0.008206990000000001 0.024999 0.03195799999999994 -0.015898 0.024999 0.02891299999999995 0.008207010000000001 0.024999 0.03195799999999994 -0.050164 0.032999 -0.05800500000000006 -0.050164 0.032999 -0.009398000000000056 -0.045857 0.032999 -0.03370150000000006 -0.058394 -0.013901 -0.03700500000000006 -0.058933 -0.006022 -0.03700500000000006 -0.058933 -0.006022 -0.02142600000000006 0.020572 -0.037001 0.02830999999999994 0.020572 -0.041001 0.02830999999999994 0.026968 -0.037001 0.02230499999999994 -0.03 -0.041001 0.01825699999999994 -0.03 -0.041001 -0.05800500000000006 0.003 -0.041001 -0.05800500000000006 -0.0149192 -0.0281757 -0.05800500000000006 -0.022043 -0.030995 -0.143005 -0.014584 -0.028042 -0.143005 0.034931 -0.037001 -0.002203010000000056 0.03438 -0.041001 0.006552989999999944 0.034931 -0.041001 -0.002203010000000056 0.001936 -0.00201 -0.05800500000000006 0.00146417 0.005499 -0.05800500000000006 0.003 0.005499 -0.05800500000000006 0.015898 0.032999 0.02891299999999995 0.02259 0.032999 0.02405099999999994 -0.018664 0.032999 0.02720999999999995 -0.051233 0.0281445 -0.03516800000000005 -0.050164 0.0287943 -0.02680210000000005 -0.050164 0.0287944 -0.03245900000000006 -0.050164 0.024999 -0.009399000000000055 -0.050164 0.0287943 -0.009398550000000056 -0.052302 0.027494 -0.01233100000000006 6.81479e-09 0.024999 -0.03700500000000006 -0.00371071 0.024999 -0.03700500000000006 -0.037824 -0.035926 -0.03700500000000006 -0.039 0.024999 0.005912989999999944 -0.039 0.024999 -0.008965040000000056 -0.036914 0.024999 0.002519999999999945 -0.0607562 -0.011659 -0.05800500000000006 -0.0585124 -0.0139735 -0.05800500000000006 -0.061876 -0.016542 -0.05800500000000006 -0.048519 0.022588 -0.007143010000000055 -0.050164 0.024999 -0.009399000000000055 -0.052302 0.027494 -0.01233100000000006 -0.0535363 -0.0259051 -0.05800500000000006 -0.0521358 -0.0230502 -0.05800500000000006 -0.051906 -0.023328 -0.05800500000000006 0.034931 -0.037001 -0.002203010000000056 0.033287 -0.037001 -0.01082100000000006 -0.03 -0.037001 0.01825699999999994 0.033287 -0.041001 -0.01082100000000006 -0.03 -0.041001 0.01825699999999994 0.029551 -0.041001 -0.01875900000000006 0.012148 0.024999 -0.03068800000000006 0.00997601 0.032999 -0.03146100000000006 0.012148 0.032999 -0.03068800000000006 0.031669 -0.037001 0.01489699999999995 0.026968 -0.037001 0.02230499999999994 0.026968 -0.041001 0.02230499999999994 0.02259 0.032999 0.02405099999999994 0.027863 0.032999 0.01767699999999994 -0.028282 0.032999 0.02061499999999995 0.02259 0.024999 0.02405099999999994 -0.018664 0.024999 0.02720999999999995 -0.028282 0.024999 0.02061499999999995 -0.058579 -0.024501 -0.02094100000000006 -0.055749 -0.021343 -0.01705900000000006 -0.061876 -0.016542 -0.02546300000000006 -0.03 -0.041001 0.01825699999999994 0.020572 -0.041001 0.02830999999999994 0.012884 -0.041001 0.03253699999999995 -0.03 -0.037001 0.01825699999999994 0.00300001 -0.037001 -0.03487600000000005 0.00300001 -0.037001 -0.03700500000000006 -0.0605016 -0.00953584 -0.05800500000000006 -0.061028 -0.00677597 -0.05800500000000006 -0.061938 -0.00201 -0.143005 0.00300001 0.024999 -0.03700500000000006 0.00300001 -0.037001 -0.03700500000000006 0.003 0.024999 -0.04099300000000006 -0.03 -0.037001 0.01825699999999994 -0.028281 -0.037001 0.02061499999999995 -0.026968 -0.037001 0.02230499999999994 -0.0535363 -0.0259051 -0.05800500000000006 -0.0542666 -0.0204743 -0.05800500000000006 -0.0521358 -0.0230502 -0.05800500000000006 0.031385 0.032999 0.01019299999999995 0.027863 0.032999 0.01767699999999994 0.027863 0.024999 0.01767699999999994 -0.04155 0.032999 -0.01727360000000006 -0.0343095 0.032999 -0.02389350000000006 -0.04155 0.032999 -0.05800500000000006 -0.04155 0.032999 -0.01727360000000006 -0.04155 0.032999 -0.05800500000000006 -0.045857 0.032999 -0.03370150000000006 -0.062933 0.006978 -0.02691200000000005 -0.057316 0.013033 -0.01920800000000005 -0.061326 0.01471 -0.02470800000000006 0.00146417 0.005499 -0.05951950000000006 0.001936 -0.00201 -0.05800500000000006 0.001936 -0.00201001 -0.143005 0.032935 0.024999 0.002066989999999944 0.031385 0.024999 0.01019299999999995 -0.028282 0.024999 0.02061499999999995 0.00541588 0.024999 -0.01612550000000006 -0.0211946 0.024999 -0.008272910000000055 0.00997601 0.024999 -0.03146100000000006 -0.050164 0.0287943 -0.02680210000000005 -0.051233 0.0281445 -0.03516800000000005 -0.052302 0.027494 -0.01233100000000006 -0.057019 -0.017147 -0.05800500000000006 -0.0571725 -0.0168208 -0.05800500000000006 -0.057019 -0.017147 -0.143005 0.015898 0.032999 0.02891299999999995 0.008207010000000001 0.032999 0.03195799999999994 0.008207010000000001 0.024999 0.03195799999999994 -0.050164 0.028795 -0.05800500000000006 -0.051233 0.0281445 -0.03516800000000005 -0.050164 0.0287944 -0.03245900000000006 -0.0382932 -0.0308632 -0.05800500000000006 -0.0415231 -0.0295844 -0.05800500000000006 -0.045417 -0.028042 -0.143005 -0.051194 -0.027795 -0.03700500000000006 -0.055749 -0.021343 -0.01705900000000006 -0.051194 -0.027795 -0.01081200000000006 -0.060434 -0.00988996 -0.05800500000000006 -0.0605016 -0.00953584 -0.05800500000000006 -0.060434 -0.009889 -0.143005 -0.037824 -0.035926 0.007525989999999944 -0.045068 -0.032779 -0.002410000000000055 -0.053335 -0.031336 -0.01374800000000006 -0.020573 -0.037001 0.02831099999999994 -0.026968 -0.041001 0.02230499999999994 -0.020573 -0.041001 0.02831099999999994 -0.00438699 -0.037001 0.03471899999999994 -0.012884 -0.041001 0.03253699999999995 -0.00438699 -0.041001 0.03471899999999994 -0.058394 -0.013901 -0.02068700000000006 -0.063 -0.008000999999999999 -0.02700500000000006 -0.061876 -0.016542 -0.02546300000000006 -0.050164 0.0287943 -0.02680210000000005 -0.050164 0.032999 -0.009398000000000056 -0.050164 0.0287944 -0.03245900000000006 0.02259 0.032999 0.02405099999999994 -0.028282 0.032999 0.02061499999999995 -0.018664 0.032999 0.02720999999999995 -0.0432793 0.024999 4.394579999994449e-05 -0.050164 0.024999 -0.009399000000000055 -0.028282 0.024999 0.02061499999999995 -0.0280051 0.032999 -0.02256690000000006 -0.0111428 0.032999 -0.03258800000000005 0.003 0.032999 -0.05800500000000006 0.005929 0.024999 -0.03392200000000006 0.00376101 0.032999 -0.03716600000000005 0.005929 0.032999 -0.03392200000000006 -0.055749 -0.021343 -0.03700500000000006 -0.053715 0.018544 -0.03700500000000006 -0.057316 0.013033 -0.03700500000000006 0.032935 0.024999 0.002066989999999944 0.032415 0.032999 -0.006189010000000056 0.032935 0.032999 0.002066989999999944 -0.03 -0.037001 0.01825699999999994 0.033287 -0.037001 -0.01082100000000006 0.029551 -0.037001 -0.01875900000000006 -0.061876 -0.016542 -0.05800500000000006 -0.0571725 -0.0168208 -0.05800500000000006 -0.0580713 -0.0192372 -0.05800500000000006 -0.03 -0.041001 -0.05800500000000006 -0.025747 -0.0314639 -0.05800500000000006 -0.0223997 -0.0310412 -0.05800500000000006 -0.0465 -0.03658 -0.05800500000000006 -0.053335 -0.031336 -0.05800500000000006 -0.0474291 -0.0311936 -0.05800500000000006 -0.052302 0.027495 -0.05800500000000006 -0.057692 0.021723 -0.01972500000000005 -0.052302 0.027494 -0.01233100000000006 -0.061028 -0.00677597 -0.05800500000000006 -0.0605016 -0.00953584 -0.05800500000000006 -0.063 -0.008000999999999999 -0.05800500000000006 0.029551 -0.041001 -0.01875900000000006 0.023959 -0.037001 -0.02551900000000006 0.029551 -0.037001 -0.01875900000000006 -0.0207863 0.00549899 -0.143005 -0.0147987 0.00549899 -0.143005 -0.037959 -0.030995 -0.143005 0.019397 0.024999 -0.02670300000000006 0.025427 0.024999 -0.02104000000000006 0.00541588 0.024999 -0.01612550000000006 0.03438 -0.041001 0.006552989999999944 0.034931 -0.037001 -0.002203010000000056 0.03438 -0.037001 0.006552989999999944 0.012884 -0.037001 0.03253699999999995 0.00438701 -0.037001 0.03471899999999994 0.00438701 -0.041001 0.03471899999999994 0.001936 -0.00201001 -0.143005 0.000903742 0.00549899 -0.143005 0.00146423 0.00549899 -0.143005 0.003 -0.041001 -0.05800500000000006 -0.03 -0.041001 -0.05800500000000006 -0.022042 -0.030996 -0.05800500000000006 -0.045068 -0.032779 -0.002410000000000055 -0.037824 -0.035926 0.007525989999999944 -0.037824 -0.035926 -0.03700500000000006 -0.051194 -0.027795 -0.03700500000000006 -0.045068 -0.032779 -0.03700500000000006 -0.048519 0.022588 -0.03700500000000006 0.00376101 0.032999 -0.03716600000000005 0.00376101 0.024999 -0.03716600000000005 0.003 0.032999 -0.04099300000000006 -0.015898 0.024999 0.02891299999999995 0.015898 0.024999 0.02891299999999995 0.008207010000000001 0.024999 0.03195799999999994 -0.008095 -0.023328 -0.143005 -0.014584 -0.028042 -0.143005 -0.037959 -0.030995 -0.143005 0.034931 -0.041001 -0.002203010000000056 -0.03 -0.041001 0.01825699999999994 0.033287 -0.041001 -0.01082100000000006 -0.00367516 0.00549899 -0.143005 0.000903742 0.00549899 -0.143005 -0.037959 -0.030995 -0.143005 -0.051194 -0.027795 -0.01081200000000006 -0.055749 -0.021343 -0.01705900000000006 -0.058579 -0.024501 -0.02094100000000006 -0.037959 -0.030995 -0.143005 -0.030001 -0.032001 -0.143005 -0.0303577 -0.0319558 -0.05800500000000006 -0.0630566 -0.000834875 -0.05796500000000006 -0.0623139 -0.000841381 -0.02690510000000006 -0.0629566 0.00547481 -0.05799990000000006 -0.0465 -0.03658 -0.004374010000000056 -0.053335 -0.031336 -0.05800500000000006 -0.0465 -0.03658 -0.05800500000000006 -0.008095 -0.023328 -0.05800500000000006 -0.0032118 -0.0174248 -0.05800500000000006 0.003 -0.041001 -0.05800500000000006 -0.053715 0.018544 -0.01426900000000006 -0.048519 0.022588 -0.007143010000000055 -0.057692 0.021723 -0.01972500000000005 0.025427 0.024999 -0.02104000000000006 0.019397 0.032999 -0.02670300000000006 0.025427 0.032999 -0.02104000000000006 -0.03 -0.037001 -0.03700500000000006 6.81479e-09 0.024999 -0.03700500000000006 -0.037824 -0.035926 -0.03700500000000006 -0.036226 0.024999 -0.007533000000000055 -0.0308565 0.024999 -0.008648480000000056 -0.035351 0.024999 0.01091799999999995 -0.032144 -0.0362324 -0.05800500000000006 -0.025747 -0.0314639 -0.05800500000000006 -0.03 -0.041001 -0.05800500000000006 -0.0412745 0.032999 -0.05800500000000006 -0.0343095 0.032999 -0.02389350000000006 0.003 0.032999 -0.05800500000000006 -0.053335 -0.031336 -0.01374800000000006 -0.051194 -0.027795 -0.01081200000000006 -0.058579 -0.024501 -0.02094100000000006 0.003 0.024999 -0.05800500000000006 0.003 0.0259881 -0.05590170000000005 0.003 0.024999 -0.05560500000000006 -0.022043 -0.030995 -0.143005 -0.030001 -0.032001 -0.143005 -0.037959 -0.030995 -0.143005 -0.0618235 -0.000203272 -0.05796570000000006 -0.0630566 -0.000834875 -0.05796500000000006 -0.0614652 0.005499 -0.05800500000000006 -0.039 0.024999 0.005912989999999944 -0.035351 0.024999 0.01091799999999995 -0.028282 0.024999 0.02061499999999995 0.003 0.032999 -0.04099300000000006 0.003 0.0259881 -0.05590170000000005 0.003 0.032999 -0.05800500000000006 -0.0432793 0.024999 4.394579999994449e-05 -0.050164 0.024999 -0.009399000000000055 -0.048519 0.022588 -0.007143010000000055 -0.0032118 -0.0174248 -0.05800500000000006 -0.002982 -0.017147 -0.05800500000000006 0.003 -0.041001 -0.05800500000000006 -0.038541 -0.039877 0.006542989999999945 -0.0465 -0.03658 -0.004374010000000056 -0.0465 -0.03658 -0.05800500000000006 -0.0401397 -0.0347307 -0.05800500000000006 -0.038541 -0.039877 -0.05800500000000006 -0.0465 -0.03658 -0.05800500000000006 -0.026968 -0.041001 0.02230499999999994 -0.020573 -0.037001 0.02831099999999994 -0.026968 -0.037001 0.02230499999999994 -0.063 -0.008000999999999999 -0.05800500000000006 -0.061876 -0.016542 -0.05800500000000006 -0.061876 -0.016542 -0.02546300000000006 -0.057693 0.021723 -0.05800500000000006 -0.061326 0.01471 -0.05800500000000006 -0.061326 0.01471 -0.02470800000000006 -0.0596031 -0.000297668 -0.02136220000000006 -0.058933 -0.006022 -0.03700500000000006 -0.058388 8.89978e-05 -0.03700500000000006 -0.051233 0.0281445 -0.03516800000000005 -0.052302 0.027495 -0.05800500000000006 -0.052302 0.027494 -0.01233100000000006 -0.0619146 -0.00165306 -0.05797350000000005 -0.061937 -0.00201 -0.05797540000000006 -0.0630566 -0.000834875 -0.05796500000000006 -0.057019 -0.017147 -0.143005 -0.060434 -0.009889 -0.143005 -0.037959 -0.030995 -0.143005 0.008704 -0.037001 -0.03390500000000005 -0.03 -0.037001 0.01825699999999994 0.016861 -0.037001 -0.03067600000000005 -0.062933 0.006978 -0.02691200000000005 -0.061326 0.01471 -0.05800500000000006 -0.062933 0.006978 -0.05800500000000006 0.02259 0.024999 0.02405099999999994 0.027863 0.032999 0.01767699999999994 0.02259 0.032999 0.02405099999999994 -0.03 -0.037001 0.01825699999999994 0.008704 -0.037001 -0.03390500000000005 0.00300001 -0.037001 -0.03487600000000005 -0.03 -0.041001 0.01825699999999994 0.00438701 -0.041001 0.03471899999999994 -0.00438699 -0.041001 0.03471899999999994 0.032415 0.032999 -0.006189010000000056 0.00560997 0.032999 -0.01012250000000006 -0.0211951 0.032999 -0.008272280000000055 -0.0149192 -0.0281757 -0.05800500000000006 -0.014584 -0.028043 -0.05800500000000006 0.003 -0.041001 -0.05800500000000006 -0.0617011 0.00174447 -0.1004890000000001 -0.0619146 -0.00165306 -0.05797350000000005 -0.0614652 0.005499 -0.1374900000000001 -0.061938 -0.00201 -0.143005 -0.0617011 0.00174447 -0.1004890000000001 -0.0614652 0.005499 -0.1374900000000001 -0.0432793 0.024999 4.394579999994449e-05 -0.039 0.024999 0.005912989999999944 -0.028282 0.024999 0.02061499999999995 -0.0521358 -0.0230502 -0.05800500000000006 -0.057019 -0.017147 -0.143005 -0.051906 -0.023328 -0.143005 -0.042292 0.024726 0.001397999999999944 -0.048519 0.022588 -0.03700500000000006 -0.042292 0.024726 -0.03700500000000006 -0.039 0.024999 -0.008965040000000056 -0.039 0.024999 0.005912989999999944 -0.042292 0.024726 -0.03700500000000006 0.00438701 -0.037001 0.03471899999999994 0.012884 -0.037001 0.03253699999999995 -0.03 -0.037001 0.01825699999999994 -0.0211946 0.024999 -0.008272910000000055 -0.00371071 0.024999 -0.03700500000000006 6.81479e-09 0.024999 -0.03700500000000006 -0.014584 -0.028043 -0.05800500000000006 -0.008386640000000001 -0.0235399 -0.05800500000000006 0.003 -0.041001 -0.05800500000000006 0.00444089 0.032999 -0.02063940000000005 0.005929 0.032999 -0.03392200000000006 -0.0211951 0.032999 -0.008272280000000055 -0.0211951 0.032999 -0.008272280000000055 0.00560997 0.032999 -0.01012250000000006 0.00541564 0.032999 -0.01612520000000005 -0.0149192 -0.0281757 -0.05800500000000006 0.003 -0.041001 -0.05800500000000006 -0.022042 -0.030996 -0.05800500000000006 -0.057316 0.013033 -0.01920800000000005 -0.058932 0.00665 -0.03700500000000006 -0.057316 0.013033 -0.03700500000000006 0.000433002 -0.009889 -0.05800500000000006 0.000432999 -0.00988901 -0.143005 0.00186845 -0.00236411 -0.05800500000000006 -0.050164 0.028795 -0.05800500000000006 -0.052302 0.027495 -0.05800500000000006 -0.051233 0.0281445 -0.03516800000000005 0.003 0.024999 -0.05800500000000006 0.003 0.024999 -0.05560500000000006 0.003 0.008739480000000001 -0.05800500000000006 -0.0607562 -0.011659 -0.05800500000000006 -0.061876 -0.016542 -0.05800500000000006 -0.063 -0.008000999999999999 -0.05800500000000006 0.03438 -0.037001 0.006552989999999944 -0.03 -0.037001 0.01825699999999994 0.031669 -0.037001 0.01489699999999995 0.031669 -0.037001 0.01489699999999995 -0.03 -0.037001 0.01825699999999994 0.026968 -0.037001 0.02230499999999994 -0.058388 8.89978e-05 -0.03700500000000006 -0.055749 -0.021343 -0.03700500000000006 -0.057316 0.013033 -0.03700500000000006 0.029859 0.024999 -0.01405600000000006 0.025427 0.024999 -0.02104000000000006 0.025427 0.032999 -0.02104000000000006 -0.045416 -0.028043 -0.05800500000000006 -0.0415231 -0.0295844 -0.05800500000000006 -0.0474291 -0.0311936 -0.05800500000000006 -0.050164 0.0287943 -0.009398550000000056 -0.050164 0.024999 -0.009399000000000055 -0.0471991 0.0260829 -0.005332310000000055 -0.0343095 0.032999 -0.02389350000000006 -0.0280051 0.032999 -0.02256690000000006 0.003 0.032999 -0.05800500000000006 9.071820000000001e-09 0.032999 0.03299499999999994 -0.008206990000000001 0.032999 0.03195799999999994 -0.008206990000000001 0.024999 0.03195799999999994 -0.0619146 -0.00165306 -0.05797350000000005 -0.0630566 -0.000834875 -0.05796500000000006 -0.0618235 -0.000203272 -0.05796570000000006 -0.0465 -0.03658 -0.004374010000000056 -0.03 -0.037001 0.01825699999999994 -0.037824 -0.035926 0.007525989999999944 -0.035351 0.024999 0.01091799999999995 -0.039 0.024999 0.005912989999999944 -0.036914 0.024999 0.002519999999999945 0.003 0.0259881 -0.05590170000000005 0.003 0.024999 -0.04099300000000006 0.003 0.024999 -0.05560500000000006 -0.037958 -0.030996 -0.05800500000000006 -0.0382932 -0.0308632 -0.05800500000000006 -0.037959 -0.030995 -0.143005 -0.039 0.024999 -0.03700500000000006 -0.039 0.024999 -0.008965040000000056 -0.042292 0.024726 -0.03700500000000006 -0.057692 0.021723 -0.01972500000000005 -0.048519 0.022588 -0.007143010000000055 -0.052302 0.027494 -0.01233100000000006 -0.039 0.024999 0.005912989999999944 -0.042292 0.024726 0.001397999999999944 -0.042292 0.024726 -0.03700500000000006 -0.061937 -0.00201 -0.05797540000000006 -0.0619146 -0.00165306 -0.05797350000000005 -0.0617011 0.00174447 -0.1004890000000001 -0.018664 0.024999 0.02720999999999995 -0.028282 0.032999 0.02061499999999995 -0.028282 0.024999 0.02061499999999995 -0.0551317 0.005499 -0.143005 -0.037959 -0.030995 -0.143005 -0.0611192 0.005499 -0.143005 -0.057316 0.013033 -0.01920800000000005 -0.053715 0.018544 -0.01426900000000006 -0.061326 0.01471 -0.02470800000000006 0.00438701 -0.037001 0.03471899999999994 -0.00438699 -0.037001 0.03471899999999994 -0.00438699 -0.041001 0.03471899999999994 -0.053715 0.018544 -0.01426900000000006 -0.057316 0.013033 -0.01920800000000005 -0.057316 0.013033 -0.03700500000000006 0.001936 -0.00201001 -0.143005 0.001936 -0.00201 -0.05800500000000006 0.00186845 -0.00236411 -0.05800500000000006 -0.0211946 0.024999 -0.008272910000000055 0.00541588 0.024999 -0.01612550000000006 0.00561021 0.024999 -0.01012250000000006 -0.0211951 0.032999 -0.008272280000000055 0.00376101 0.032999 -0.03716600000000005 -0.0111428 0.032999 -0.03258800000000005 0.019397 0.024999 -0.02670300000000006 0.00541588 0.024999 -0.01612550000000006 0.012148 0.024999 -0.03068800000000006 0.00997601 0.032999 -0.03146100000000006 0.00444089 0.032999 -0.02063940000000005 0.012148 0.032999 -0.03068800000000006 0.025427 0.032999 -0.02104000000000006 0.00444089 0.032999 -0.02063940000000005 0.00541564 0.032999 -0.01612520000000005 0.029859 0.024999 -0.01405600000000006 0.032415 0.024999 -0.006189010000000056 0.00561021 0.024999 -0.01012250000000006 0.019397 0.032999 -0.02670300000000006 0.00444089 0.032999 -0.02063940000000005 0.025427 0.032999 -0.02104000000000006 0.00541588 0.024999 -0.01612550000000006 0.025427 0.024999 -0.02104000000000006 0.029859 0.024999 -0.01405600000000006 0.005929 0.032999 -0.03392200000000006 0.00376101 0.032999 -0.03716600000000005 -0.0211951 0.032999 -0.008272280000000055 -0.0211946 0.024999 -0.008272910000000055 0.005929 0.024999 -0.03392200000000006 0.00997601 0.024999 -0.03146100000000006 -0.0211951 0.032999 -0.008272280000000055 -0.035351 0.032999 0.01091799999999995 -0.028282 0.032999 0.02061499999999995 0.00376101 0.032999 -0.03716600000000005 0.00034425 0.032999 -0.03941470000000005 -0.0111428 0.032999 -0.03258800000000005 0.00376101 0.024999 -0.03716600000000005 0.00300001 0.024999 -0.03700500000000006 0.003 0.024999 -0.04099300000000006 0.00541588 0.024999 -0.01612550000000006 0.029859 0.024999 -0.01405600000000006 0.00561021 0.024999 -0.01012250000000006 0.012148 0.032999 -0.03068800000000006 0.00444089 0.032999 -0.02063940000000005 0.019397 0.032999 -0.02670300000000006 0.032415 0.024999 -0.006189010000000056 -0.0211946 0.024999 -0.008272910000000055 0.00561021 0.024999 -0.01012250000000006 -0.04155 0.032999 -0.01727360000000006 -0.035351 0.032999 0.01091799999999995 -0.0211951 0.032999 -0.008272280000000055 0.005929 0.024999 -0.03392200000000006 0.00300001 0.024999 -0.03700500000000006 0.00376101 0.024999 -0.03716600000000005 0.00444089 0.032999 -0.02063940000000005 0.00997601 0.032999 -0.03146100000000006 0.005929 0.032999 -0.03392200000000006 0.012148 0.024999 -0.03068800000000006 0.00541588 0.024999 -0.01612550000000006 0.00997601 0.024999 -0.03146100000000006 -0.057316 0.013033 -0.01920800000000005 -0.062933 0.006978 -0.02691200000000005 -0.058932 0.00665 -0.02142500000000006 -0.062933 0.006978 -0.02691200000000005 -0.0596031 -0.000297668 -0.02136220000000006 -0.058932 0.00665 -0.02142500000000006 -0.042292 0.024726 0.001397999999999944 -0.0432793 0.024999 4.394579999994449e-05 -0.048519 0.022588 -0.007143010000000055 -0.066942 0.061999 -0.05800500000000006 -0.066942 0.061999 -0.143005 -0.068915 0.005499 -0.1530050000000001 -0.065 0.045999 -0.05800500000000006 -0.0412745 0.032999 -0.05800500000000006 0.005 0.045999 -0.05800500000000006 0.006941 0.061999 -0.143005 0.004441 0.061999 -0.09800500000000005 0.006941 0.061999 -0.05800500000000006 -0.066942 0.061999 -0.05800500000000006 -0.068915 0.005499 -0.1530050000000001 -0.068914 0.005499 -0.05800500000000006 -0.062933 0.006978 -0.05800500000000006 -0.068914 0.005499 -0.05800500000000006 -0.0629566 0.00547481 -0.05799990000000006 0.00146417 0.005499 -0.05951950000000006 0.008914 0.005499 -0.05800500000000006 0.003 0.005499 -0.05800500000000006 0.008914 0.005499 -0.05800500000000006 0.008914 0.00549899 -0.1530050000000001 0.006941 0.061999 -0.05800500000000006 -0.04155 0.032999 -0.05800500000000006 -0.065 0.045999 -0.05800500000000006 -0.050164 0.032999 -0.05800500000000006 0.004441 0.061999 -0.09800500000000005 0.004441 0.061999 -0.05800500000000006 0.006941 0.061999 -0.05800500000000006 -0.0551317 0.005499 -0.143005 -0.068915 0.005499 -0.1530050000000001 -0.0498164 0.005499 -0.143005 -0.0412745 0.032999 -0.05800500000000006 -0.065 0.045999 -0.05800500000000006 -0.04155 0.032999 -0.05800500000000006 -0.0309972 0.005499 -0.143005 -0.0356626 0.005499 -0.143005 0.004 0.00549899 -0.1530050000000001 0.003 0.032999 -0.05800500000000006 0.008914 0.005499 -0.05800500000000006 0.005 0.045999 -0.05800500000000006 -0.066942 0.061999 -0.143005 -0.066942 0.061999 -0.05800500000000006 -0.064442 0.061999 -0.09800500000000005 -0.066942 0.061999 -0.143005 -0.064442 0.061999 -0.09800500000000005 0.006941 0.061999 -0.143005 0.004441 0.061999 -0.05800500000000006 0.005 0.045999 -0.05800500000000006 0.006941 0.061999 -0.05800500000000006 -0.062933 0.006978 -0.05800500000000006 -0.061326 0.01471 -0.05800500000000006 -0.068914 0.005499 -0.05800500000000006 -0.066942 0.061999 -0.05800500000000006 -0.064442 0.061999 -0.05800500000000006 -0.064442 0.061999 -0.09800500000000005 -0.066942 0.061999 -0.143005 0.004 0.00549899 -0.1530050000000001 -0.068915 0.005499 -0.1530050000000001 -0.065 0.045999 -0.05800500000000006 -0.066942 0.061999 -0.05800500000000006 -0.068914 0.005499 -0.05800500000000006 -0.061326 0.01471 -0.05800500000000006 -0.065 0.045999 -0.05800500000000006 -0.068914 0.005499 -0.05800500000000006 -0.068915 0.005499 -0.1530050000000001 -0.0614652 0.005499 -0.143005 -0.0614652 0.005499 -0.1374900000000001 -0.0261013 0.00549899 -0.143005 -0.0309972 0.005499 -0.143005 0.004 0.00549899 -0.1530050000000001 -0.0498164 0.005499 -0.143005 -0.068915 0.005499 -0.1530050000000001 -0.0449206 0.005499 -0.143005 -0.00776776 0.00549899 -0.143005 -0.0147987 0.00549899 -0.143005 0.004 0.00549899 -0.1530050000000001 -0.065 0.045999 -0.05800500000000006 -0.052302 0.027495 -0.05800500000000006 -0.050164 0.032999 -0.05800500000000006 -0.0356626 0.005499 -0.143005 -0.0402551 0.005499 -0.143005 0.004 0.00549899 -0.1530050000000001 -0.065 0.045999 -0.05800500000000006 -0.064442 0.061999 -0.05800500000000006 -0.066942 0.061999 -0.05800500000000006 0.008914 0.005499 -0.05800500000000006 0.003 0.024999 -0.05800500000000006 0.003 0.008739480000000001 -0.05800500000000006 -0.0614652 0.005499 -0.143005 -0.068915 0.005499 -0.1530050000000001 -0.0611192 0.005499 -0.143005 0.008914 0.005499 -0.05800500000000006 0.003 0.032999 -0.05800500000000006 0.003 0.024999 -0.05800500000000006 0.008914 0.00549899 -0.1530050000000001 0.008914 0.005499 -0.05800500000000006 0.004 0.00549899 -0.1530050000000001 0.008914 0.00549899 -0.1530050000000001 0.006941 0.061999 -0.143005 0.006941 0.061999 -0.05800500000000006 -0.064442 0.061999 -0.09800500000000005 0.004441 0.061999 -0.09800500000000005 0.006941 0.061999 -0.143005 0.00146417 0.005499 -0.05951950000000006 0.00146423 0.00549899 -0.143005 0.008914 0.005499 -0.05800500000000006 -0.068915 0.005499 -0.1530050000000001 -0.0551317 0.005499 -0.143005 -0.0611192 0.005499 -0.143005 0.004 0.00549899 -0.1530050000000001 -0.0402551 0.005499 -0.143005 -0.068915 0.005499 -0.1530050000000001 -0.057693 0.021723 -0.05800500000000006 -0.052302 0.027495 -0.05800500000000006 -0.065 0.045999 -0.05800500000000006 -0.00367516 0.00549899 -0.143005 -0.00776776 0.00549899 -0.143005 0.004 0.00549899 -0.1530050000000001 -0.0412745 0.032999 -0.05800500000000006 0.003 0.032999 -0.05800500000000006 0.005 0.045999 -0.05800500000000006 0.004 0.00549899 -0.1530050000000001 -0.066942 0.061999 -0.143005 0.006941 0.061999 -0.143005 0.000903742 0.00549899 -0.143005 -0.00367516 0.00549899 -0.143005 0.004 0.00549899 -0.1530050000000001 -0.0207863 0.00549899 -0.143005 -0.0261013 0.00549899 -0.143005 0.004 0.00549899 -0.1530050000000001 0.00146423 0.00549899 -0.143005 0.000903742 0.00549899 -0.143005 0.004 0.00549899 -0.1530050000000001 0.005 0.045999 -0.05800500000000006 0.008914 0.005499 -0.05800500000000006 0.006941 0.061999 -0.05800500000000006 0.008914 0.00549899 -0.1530050000000001 0.004 0.00549899 -0.1530050000000001 0.006941 0.061999 -0.143005 -0.068915 0.005499 -0.1530050000000001 -0.0402551 0.005499 -0.143005 -0.0449206 0.005499 -0.143005 0.008914 0.005499 -0.05800500000000006 0.00146423 0.00549899 -0.143005 0.004 0.00549899 -0.1530050000000001 0.00146417 0.005499 -0.05800500000000006 0.00146417 0.005499 -0.05951950000000006 0.003 0.005499 -0.05800500000000006 -0.0147987 0.00549899 -0.143005 -0.0207863 0.00549899 -0.143005 0.004 0.00549899 -0.1530050000000001 -0.068914 0.005499 -0.05800500000000006 -0.068915 0.005499 -0.1530050000000001 -0.0614652 0.005499 -0.1374900000000001 -0.057693 0.021723 -0.05800500000000006 -0.065 0.045999 -0.05800500000000006 -0.061326 0.01471 -0.05800500000000006 0.003 0.005499 -0.05800500000000006 0.008914 0.005499 -0.05800500000000006 0.003 0.008739480000000001 -0.05800500000000006 -0.0614652 0.005499 -0.06771010000000005 -0.068914 0.005499 -0.05800500000000006 -0.0614652 0.005499 -0.1374900000000001 -0.0629566 0.00547481 -0.05799990000000006 -0.068914 0.005499 -0.05800500000000006 -0.0614652 0.005499 -0.06771010000000005 -0.0629566 0.00547481 -0.05799990000000006 -0.0614652 0.005499 -0.06771010000000005 -0.0614652 0.005499 -0.05800500000000006 -0.063679 0.08383699999999999 -0.03800500000000005 0.004441 0.061999 -0.09800500000000005 -0.064442 0.061999 -0.09800500000000005 0.00401901 0.07407 -0.03445000000000006 -0.06401999999999999 0.07407 -0.03445000000000006 0.005 0.045999 -0.05800500000000006 -0.063679 0.08383699999999999 -0.03800500000000005 0.003678 0.08383699999999999 -0.03800500000000005 0.004441 0.061999 -0.09800500000000005 -0.06401999999999999 0.07407 -0.03445000000000006 -0.063679 0.08383699999999999 -0.03800500000000005 -0.064442 0.061999 -0.05800500000000006 -0.06401999999999999 0.07407 -0.03445000000000006 -0.065 0.045999 -0.05800500000000006 0.005 0.045999 -0.05800500000000006 0.003678 0.08383699999999999 -0.03800500000000005 0.00401901 0.07407 -0.03445000000000006 0.004441 0.061999 -0.05800500000000006 0.004441 0.061999 -0.09800500000000005 0.003678 0.08383699999999999 -0.03800500000000005 0.004441 0.061999 -0.05800500000000006 -0.065 0.045999 -0.05800500000000006 -0.06401999999999999 0.07407 -0.03445000000000006 -0.064442 0.061999 -0.05800500000000006 0.004441 0.061999 -0.05800500000000006 0.00401901 0.07407 -0.03445000000000006 0.005 0.045999 -0.05800500000000006 0.003678 0.08383699999999999 -0.03800500000000005 -0.063679 0.08383699999999999 -0.03800500000000005 0.00401901 0.07407 -0.03445000000000006 -0.064442 0.061999 -0.05800500000000006 -0.063679 0.08383699999999999 -0.03800500000000005 -0.064442 0.061999 -0.09800500000000005 -0.063679 0.08383699999999999 -0.03800500000000005 -0.06401999999999999 0.07407 -0.03445000000000006 0.00401901 0.07407 -0.03445000000000006 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583

    -
    -
    - - - 0 0 -5.551115123125783e-17 - 1 0 0 0 - - true - - - -
    - - - - -0.006485 0.023 -0.254967 0.016497 0.023 -0.221995 3.99838e-06 0.023 -0.255995 -0.012339 0.023 -0.251984 0.016497 0.023 -0.221995 -0.006485 0.023 -0.254967 3.99838e-06 0.023 -0.255995 0.016497 0.023 -0.221995 0.006493 0.023 -0.254967 -0.000701329 -0.018 -0.255883 -0.006485 0.023 -0.254967 3.99838e-06 0.023 -0.255995 3.99658e-06 -0.018 -0.255995 -0.000701329 -0.018 -0.255883 3.99838e-06 0.023 -0.255995 -0.016985 0.023 -0.247338 0.016497 0.023 -0.221995 -0.012339 0.023 -0.251984 -0.0071213 -0.018 -0.254643 -0.012339 0.023 -0.251984 -0.006485 0.023 -0.254967 -0.006485 -0.018 -0.254967 -0.0071213 -0.018 -0.254643 -0.006485 0.023 -0.254967 0.006493 0.023 -0.254967 0.016497 0.023 -0.221995 0.012348 0.023 -0.251984 0.000709323 -0.018 -0.255883 3.99658e-06 -0.018 -0.255995 3.99838e-06 0.023 -0.255995 0.000709323 -0.018 -0.255883 3.99838e-06 0.023 -0.255995 0.006493 0.023 -0.254967 -0.00252937 -0.018 -0.255594 -0.006485 -0.018 -0.254967 -0.006485 0.023 -0.254967 -0.000701329 -0.018 -0.255883 -0.00252937 -0.018 -0.255594 -0.006485 0.023 -0.254967 -0.016985 0.023 -0.247338 -0.019968 0.023 -0.241484 0.016497 0.023 -0.221995 -0.016985 0.023 -0.247338 -0.012339 0.023 -0.251984 -0.012844 -0.018 -0.251479 -0.012339 0.023 -0.251984 -0.012339 -0.018 -0.251984 -0.012844 -0.018 -0.251479 -0.008449170000000001 -0.018 -0.253966 -0.012339 -0.018 -0.251984 -0.012339 0.023 -0.251984 -0.0071213 -0.018 -0.254643 -0.008449170000000001 -0.018 -0.253966 -0.012339 0.023 -0.251984 0.016497 0.023 -0.221995 0.016994 0.023 -0.247338 0.012348 0.023 -0.251984 0.0071303 -0.018 -0.254643 0.00649389 -0.018 -0.254967 0.006493 0.023 -0.254967 0.0071303 -0.018 -0.254643 0.006493 0.023 -0.254967 0.012348 0.023 -0.251984 0.0037358 -0.018 -0.255404 0.000709323 -0.018 -0.255883 0.006493 0.023 -0.254967 0.00649389 -0.018 -0.254967 0.0037358 -0.018 -0.255404 0.006493 0.023 -0.254967 -0.019968 0.023 -0.241484 -0.020996 0.023 -0.234995 0.016497 0.023 -0.221995 -0.019968 0.023 -0.241484 -0.016985 0.023 -0.247338 -0.0173092 -0.018 -0.246702 -0.016985 0.023 -0.247338 -0.016985 -0.018 -0.247338 -0.0173092 -0.018 -0.246702 -0.016985 0.023 -0.247338 -0.012844 -0.018 -0.251479 -0.0135884 -0.018 -0.250735 -0.016985 0.023 -0.247338 -0.0135884 -0.018 -0.250735 -0.016985 -0.018 -0.247338 0.016497 0.023 -0.221995 0.019976 0.023 -0.241484 0.016994 0.023 -0.247338 0.012348 0.023 -0.251984 0.016994 0.023 -0.247338 0.012853 -0.018 -0.251479 0.012348 0.023 -0.251984 0.012853 -0.018 -0.251479 0.012348 -0.018 -0.251984 0.00988577 -0.018 -0.253239 0.0071303 -0.018 -0.254643 0.012348 0.023 -0.251984 0.012348 -0.018 -0.251984 0.00988577 -0.018 -0.253239 0.012348 0.023 -0.251984 -0.020996 0.023 -0.234995 -0.019968 0.023 -0.228505 0.016497 0.023 -0.221995 -0.020996 0.023 -0.234995 -0.019968 0.023 -0.241484 -0.0200797 -0.018 -0.240779 -0.019968 0.023 -0.241484 -0.019968 -0.018 -0.241484 -0.0200797 -0.018 -0.240779 -0.019968 0.023 -0.241484 -0.0173092 -0.018 -0.246702 -0.0175653 -0.018 -0.246199 -0.019968 0.023 -0.241484 -0.0175653 -0.018 -0.246199 -0.019968 -0.018 -0.241484 0.016497 0.023 -0.221995 0.021004 0.023 -0.234995 0.019976 0.023 -0.241484 0.016994 0.023 -0.247338 0.019976 0.023 -0.241484 0.0173181 -0.018 -0.246702 0.016994 0.023 -0.247338 0.0173181 -0.018 -0.246702 0.016994 -0.018 -0.247338 0.016994 0.023 -0.247338 0.016994 -0.018 -0.247338 0.0154937 -0.018 -0.248838 0.016994 0.023 -0.247338 0.0154937 -0.018 -0.248838 0.012853 -0.018 -0.251479 -0.019968 0.023 -0.228505 -0.016985 0.023 -0.222651 0.016497 0.023 -0.221995 -0.019968 0.023 -0.228505 -0.020996 0.023 -0.234995 -0.019968 0.00648999 -0.228506 -0.020996 -0.00648901 -0.234995 -0.020996 -7.44684e-09 -0.234995 -0.0200797 -0.018 -0.240779 -0.0200797 -0.018 -0.240779 -0.020086 -0.018 -0.240739 -0.020996 -0.012343 -0.234995 -0.020996 -0.00648901 -0.234995 -0.0200797 -0.018 -0.240779 -0.020996 -0.012343 -0.234995 -0.020996 -0.012343 -0.234995 -0.020086 -0.018 -0.240739 -0.020996 -0.016989 -0.234995 -0.020996 -0.016989 -0.234995 -0.020086 -0.018 -0.240739 -0.020996 -0.018 -0.234995 -0.0200797 -0.018 -0.240779 -0.020996 -7.44684e-09 -0.234995 -0.020996 0.00648999 -0.234995 -0.020996 0.012344 -0.234995 -0.0200797 -0.018 -0.240779 -0.020996 0.00648999 -0.234995 -0.020996 0.01699 -0.234995 -0.0200797 -0.018 -0.240779 -0.020996 0.012344 -0.234995 -0.020996 0.019973 -0.234995 -0.0200797 -0.018 -0.240779 -0.020996 0.01699 -0.234995 -0.020996 0.023 -0.234995 -0.0200797 -0.018 -0.240779 -0.020996 0.019973 -0.234995 0.016497 0.023 -0.221995 0.019976 0.023 -0.228506 0.021004 0.023 -0.234995 0.0200886 -0.018 -0.240779 0.019976 0.023 -0.241484 0.021004 0.023 -0.234995 0.0200886 -0.018 -0.240779 0.0199769 -0.018 -0.241484 0.019976 0.023 -0.241484 0.019976 0.023 -0.241484 0.0199769 -0.018 -0.241484 0.0173181 -0.018 -0.246702 0.021004 -0.016989 -0.234995 0.021004 -0.018 -0.234995 0.0209 -0.018 -0.235652 0.021004 -9.28272e-09 -0.234995 0.021004 -0.00648901 -0.234995 0.0200886 -0.018 -0.240779 0.021004 -0.00648901 -0.234995 0.021004 -0.012343 -0.234995 0.0200886 -0.018 -0.240779 0.021004 -0.012343 -0.234995 0.021004 -0.016989 -0.234995 0.0200886 -0.018 -0.240779 0.021004 -0.016989 -0.234995 0.0209 -0.018 -0.235652 0.0200886 -0.018 -0.240779 0.021004 0.019973 -0.234995 0.0200886 -0.018 -0.240779 0.021004 0.023 -0.234995 0.021004 0.01699 -0.234995 0.0200886 -0.018 -0.240779 0.021004 0.019973 -0.234995 0.021004 0.012344 -0.234995 0.0200886 -0.018 -0.240779 0.021004 0.01699 -0.234995 0.021004 0.00648999 -0.234995 0.0200886 -0.018 -0.240779 0.021004 0.012344 -0.234995 0.021004 -9.28272e-09 -0.234995 0.0200886 -0.018 -0.240779 0.021004 0.00648999 -0.234995 -0.016985 0.023 -0.222651 -0.012339 0.023 -0.218006 0.016497 0.023 -0.221995 -0.016985 0.023 -0.222651 -0.019968 0.023 -0.228505 -0.019968 0.00648999 -0.228506 -0.020996 0.00648999 -0.234995 -0.020996 -7.44684e-09 -0.234995 -0.019968 0.00648999 -0.228506 -0.019968 0.00648999 -0.228506 -0.020996 0.023 -0.234995 -0.020482 0.0115 -0.23175 -0.020996 0.023 -0.234995 -0.020996 0.019973 -0.234995 -0.020482 0.0115 -0.23175 -0.020996 0.019973 -0.234995 -0.020996 0.01699 -0.234995 -0.020482 0.0115 -0.23175 -0.020996 0.01699 -0.234995 -0.020996 0.012344 -0.234995 -0.020482 0.0115 -0.23175 -0.020996 0.012344 -0.234995 -0.020996 0.00648999 -0.234995 -0.020482 0.0115 -0.23175 -0.020996 0.00648999 -0.234995 -0.019968 0.00648999 -0.228506 -0.020482 0.0115 -0.23175 -0.020996 -7.44684e-09 -0.234995 -0.020996 -0.00648901 -0.234995 -0.019968 -0.00648901 -0.228506 -0.020996 -0.016989 -0.234995 -0.020996 -0.018 -0.234995 -0.0209643 -0.018 -0.234795 -0.020996 -0.012343 -0.234995 -0.020996 -0.016989 -0.234995 -0.0206847 -0.018 -0.23303 -0.020996 -0.016989 -0.234995 -0.0209643 -0.018 -0.234795 -0.0206847 -0.018 -0.23303 -0.0206847 -0.018 -0.23303 -0.019968 -0.00648901 -0.228506 -0.020482 -0.008999999999999999 -0.23175 -0.020996 -0.00648901 -0.234995 -0.020996 -0.012343 -0.234995 -0.020482 -0.008999999999999999 -0.23175 -0.019968 -0.00648901 -0.228506 -0.020996 -0.00648901 -0.234995 -0.020482 -0.008999999999999999 -0.23175 -0.020996 -0.012343 -0.234995 -0.0206847 -0.018 -0.23303 -0.020482 -0.008999999999999999 -0.23175 0.016994 0.023 -0.222651 0.019976 0.023 -0.228506 0.016497 0.023 -0.221995 0.021004 0.023 -0.234995 0.019976 0.023 -0.228506 0.019976 0.00648999 -0.228506 0.021004 0.00648999 -0.234995 0.019976 0.00648999 -0.228506 0.021004 -9.28272e-09 -0.234995 0.021004 0.00648999 -0.234995 0.021004 0.012344 -0.234995 0.02049 0.0115 -0.23175 0.021004 0.012344 -0.234995 0.021004 0.01699 -0.234995 0.02049 0.0115 -0.23175 0.021004 0.01699 -0.234995 0.021004 0.019973 -0.234995 0.02049 0.0115 -0.23175 0.021004 0.019973 -0.234995 0.021004 0.023 -0.234995 0.02049 0.0115 -0.23175 0.021004 0.023 -0.234995 0.019976 0.00648999 -0.228506 0.02049 0.0115 -0.23175 0.019976 0.00648999 -0.228506 0.021004 0.00648999 -0.234995 0.02049 0.0115 -0.23175 0.021004 -0.012343 -0.234995 0.021004 -0.00648901 -0.234995 0.0202003 -0.018 -0.229917 0.021004 -0.012343 -0.234995 0.0202003 -0.018 -0.229917 0.0203537 -0.018 -0.230886 0.021004 -0.012343 -0.234995 0.0203537 -0.018 -0.230886 0.0203885 -0.018 -0.231106 0.021004 -0.012343 -0.234995 0.0203885 -0.018 -0.231106 0.0204413 -0.018 -0.23144 0.021004 -0.012343 -0.234995 0.0204413 -0.018 -0.23144 0.0204951 -0.018 -0.23178 0.021004 -0.012343 -0.234995 0.0204951 -0.018 -0.23178 0.0205521 -0.018 -0.23214 0.021004 -0.012343 -0.234995 0.0205521 -0.018 -0.23214 0.020615 -0.018 -0.232537 0.020615 -0.018 -0.232537 0.0206874 -0.018 -0.232995 0.021004 -0.016989 -0.234995 0.0206874 -0.018 -0.232995 0.0207755 -0.018 -0.233551 0.021004 -0.016989 -0.234995 0.021004 -0.012343 -0.234995 0.020615 -0.018 -0.232537 0.021004 -0.016989 -0.234995 0.021004 -0.016989 -0.234995 0.0207755 -0.018 -0.233551 0.0208896 -0.018 -0.234272 0.021004 -0.016989 -0.234995 0.0208896 -0.018 -0.234272 0.021004 -0.018 -0.234995 0.0202003 -0.018 -0.229917 0.021004 -0.00648901 -0.234995 0.021004 -9.28272e-09 -0.234995 -0.012339 0.023 -0.218006 -0.006485 0.023 -0.215023 0.016497 0.023 -0.221995 -0.016985 0.012344 -0.222651 -0.012339 0.023 -0.218006 -0.016985 0.023 -0.222651 -0.016985 0.023 -0.222651 -0.019968 0.00648999 -0.228506 -0.016985 0.012344 -0.222651 -0.020995 -8.25938e-09 -0.144495 -0.019968 0.00648999 -0.228506 -0.020996 -7.44684e-09 -0.234995 -0.019968 -0.00648901 -0.228506 -0.0206847 -0.018 -0.23303 -0.020345 -0.018 -0.230886 -0.019968 -0.00648901 -0.228506 -0.020345 -0.018 -0.230886 -0.019968 -0.018 -0.228506 -0.020996 -7.44684e-09 -0.234995 -0.019968 -0.00648901 -0.228506 -0.019968 -0.00648901 -0.144495 0.016994 0.023 -0.222651 0.016497 0.023 -0.221995 0.016994 0.012344 -0.222652 0.019976 0.023 -0.228506 0.016994 0.023 -0.222651 0.016994 0.012344 -0.222652 0.019976 0.023 -0.228506 0.016994 0.012344 -0.222652 0.019976 0.00648999 -0.228506 0.019977 0.00648999 -0.144495 0.021004 -9.28272e-09 -0.234995 0.019976 0.00648999 -0.228506 0.021004 -9.28272e-09 -0.234995 0.019977 -0.00648901 -0.228506 0.0202003 -0.018 -0.229917 0.019977 -0.00648901 -0.228506 0.019977 -0.018 -0.228506 0.0202003 -0.018 -0.229917 -0.006485 0.023 -0.215023 4.00022e-06 0.023 -0.213995 0.016497 0.023 -0.221995 -0.012339 0.01699 -0.218006 -0.006485 0.023 -0.215023 -0.012339 0.023 -0.218006 -0.016985 0.012344 -0.222651 -0.012339 0.01699 -0.218006 -0.012339 0.023 -0.218006 -0.0186889 0.008999989999999999 -0.21327 -0.016985 0.012344 -0.222651 -0.019968 0.00648999 -0.228506 -0.0186889 0.008999989999999999 -0.21327 -0.0173466 0.0116343 -0.213178 -0.016985 0.012344 -0.222651 -0.019968 0.00648899 -0.144495 -0.0186887 0.008999989999999999 -0.178013 -0.0186889 0.008999989999999999 -0.21327 -0.019968 0.00648899 -0.144495 -0.0186889 0.008999989999999999 -0.21327 -0.019968 0.00648999 -0.228506 -0.020996 -7.44684e-09 -0.234995 -0.019968 -0.00648901 -0.144495 -0.020995 -8.25938e-09 -0.144495 -0.019968 0.00648999 -0.228506 -0.020995 -8.25938e-09 -0.144495 -0.019968 0.00648899 -0.144495 -0.0184765 -0.0122445 -0.225579 -0.019968 -0.00648901 -0.228506 -0.019968 -0.018 -0.228506 -0.0184765 -0.0122445 -0.225579 -0.016985 -0.012343 -0.222652 -0.019968 -0.00648901 -0.228506 -0.0184765 -0.0122445 -0.225579 -0.0185684 -0.018 -0.225759 -0.016985 -0.012343 -0.222652 -0.0184765 -0.0122445 -0.225579 -0.019968 -0.018 -0.228506 -0.0185684 -0.018 -0.225759 -0.019968 -0.00648901 -0.228506 -0.016985 -0.012343 -0.144495 -0.019968 -0.00648901 -0.144495 0.016994 0.012344 -0.222652 0.016497 0.023 -0.221995 0.0146947 0.017672 -0.220305 0.016497 0.023 -0.221995 0.012348 0.01699 -0.218006 0.0146947 0.017672 -0.220305 0.012348 0.01699 -0.218006 0.016994 0.012344 -0.222652 0.0146947 0.017672 -0.220305 0.019976 0.00648999 -0.228506 0.016994 0.012344 -0.222652 0.0186974 0.008999989999999999 -0.21327 0.016994 0.012344 -0.222652 0.016994 0.012344 -0.213153 0.0186974 0.008999989999999999 -0.21327 0.019976 0.00648999 -0.228506 0.0186974 0.008999989999999999 -0.206372 0.0186974 0.008999989999999999 -0.192485 0.0186974 0.008999989999999999 -0.21327 0.0186974 0.008999989999999999 -0.206372 0.019976 0.00648999 -0.228506 0.0186979 0.008999989999999999 -0.14872 0.0171477 0.0120422 -0.148826 0.016994 0.012344 -0.144495 0.0186974 0.008999989999999999 -0.192485 0.0186979 0.008999989999999999 -0.14872 0.019977 0.00648999 -0.144495 0.0186979 0.008999989999999999 -0.14872 0.016994 0.012344 -0.144495 0.019977 0.00648999 -0.144495 0.0186974 0.008999989999999999 -0.192485 0.019977 0.00648999 -0.144495 0.019976 0.00648999 -0.228506 0.019977 0.00648999 -0.144495 0.021004 -1.00952e-08 -0.144495 0.021004 -9.28272e-09 -0.234995 0.019977 -0.00648901 -0.228506 0.021004 -9.28272e-09 -0.234995 0.021004 -1.00952e-08 -0.144495 0.019977 -0.00648901 -0.228506 0.0178973 -0.018 -0.224425 0.018835 -0.018 -0.226265 0.019977 -0.00648901 -0.228506 0.018835 -0.018 -0.226265 0.0191898 -0.018 -0.226961 0.019977 -0.00648901 -0.228506 0.0191898 -0.018 -0.226961 0.019977 -0.018 -0.228506 4.00022e-06 0.023 -0.213995 0.006494 0.023 -0.215023 0.016497 0.023 -0.221995 -0.006485 0.019973 -0.215023 4.00022e-06 0.023 -0.213995 -0.006485 0.023 -0.215023 -0.006485 0.019973 -0.215023 -0.006485 0.023 -0.215023 -0.012339 0.01699 -0.218006 -0.016985 0.012344 -0.213153 -0.0126553 0.0166737 -0.213002 -0.014662 0.014667 -0.217826 -0.0126553 0.0166737 -0.213002 -0.012339 0.01699 -0.218006 -0.014662 0.014667 -0.217826 -0.012339 0.01699 -0.218006 -0.016985 0.012344 -0.222651 -0.014662 0.014667 -0.217826 -0.016985 0.012344 -0.222651 -0.016985 0.012344 -0.213153 -0.014662 0.014667 -0.217826 -0.0186887 0.008999989999999999 -0.14872 -0.0186887 0.008999989999999999 -0.155618 -0.019968 0.00648899 -0.144495 -0.016985 0.012344 -0.148837 -0.0186887 0.008999989999999999 -0.14872 -0.016985 0.012344 -0.144495 -0.0186887 0.008999989999999999 -0.14872 -0.019968 0.00648899 -0.144495 -0.016985 0.012344 -0.144495 -0.0186887 0.008999989999999999 -0.155618 -0.0186887 0.008999989999999999 -0.178013 -0.019968 0.00648899 -0.144495 -0.016985 0.012344 -0.222651 -0.0173466 0.0116343 -0.213178 -0.016985 0.012344 -0.213153 -0.020995 -8.25938e-09 -0.144495 -0.019968 -0.00648901 -0.144495 -0.021156 -0.029125 -0.144495 -0.017339 0.031547 -0.144495 -0.019968 0.00648899 -0.144495 -0.020995 -8.25938e-09 -0.144495 -0.012339 -0.018 -0.218006 -0.010355 -0.018 -0.216995 -0.012339 -0.016989 -0.218006 -0.012339 -0.016989 -0.218006 -0.0131204 -0.018 -0.218787 -0.012339 -0.018 -0.218006 -0.0131204 -0.018 -0.218787 -0.012339 -0.016989 -0.218006 -0.014662 -0.0151715 -0.220329 -0.012339 -0.016989 -0.218006 -0.016985 -0.012343 -0.222652 -0.014662 -0.0151715 -0.220329 -0.016985 -0.012343 -0.222652 -0.016985 -0.018 -0.222652 -0.014662 -0.0151715 -0.220329 -0.016985 -0.018 -0.222652 -0.0131204 -0.018 -0.218787 -0.014662 -0.0151715 -0.220329 -0.016985 -0.012343 -0.222652 -0.0185684 -0.018 -0.225759 -0.016985 -0.018 -0.222652 -0.010355 -0.018 -0.195314 -0.012339 -0.016989 -0.218006 -0.010355 -0.018 -0.216995 -0.012339 -0.016989 -0.218006 -0.010355 -0.018 -0.195314 -0.010355 -0.018 -0.193092 -0.019968 -0.00648901 -0.228506 -0.016985 -0.012343 -0.222652 -0.016985 -0.012343 -0.144495 -0.019968 -0.00648901 -0.144495 -0.016985 -0.012343 -0.144495 -0.013248 -0.033472 -0.144495 0.012348 0.01699 -0.218006 0.016497 0.023 -0.221995 0.012348 0.023 -0.218006 0.012348 0.01699 -0.212991 0.0164282 0.0129098 -0.213133 0.014671 0.014667 -0.217821 0.0164282 0.0129098 -0.213133 0.016994 0.012344 -0.222652 0.014671 0.014667 -0.217821 0.016994 0.012344 -0.222652 0.012348 0.01699 -0.218006 0.014671 0.014667 -0.217821 0.012348 0.01699 -0.218006 0.012348 0.01699 -0.212991 0.014671 0.014667 -0.217821 0.016994 0.012344 -0.222652 0.0164282 0.0129098 -0.213133 0.016994 0.012344 -0.213153 0.0171477 0.0120422 -0.148826 0.016994 0.012344 -0.148837 0.016994 0.012344 -0.144495 0.016994 0.012344 -0.144495 0.017347 0.031547 -0.144495 0.019977 0.00648999 -0.144495 0.024648 0.026243 -0.144495 0.021004 -1.00952e-08 -0.144495 0.019977 0.00648999 -0.144495 0.019977 -0.00648901 -0.228506 0.021004 -1.00952e-08 -0.144495 0.019977 -0.00648901 -0.144495 0.016994 -0.012343 -0.222652 0.016994 -0.018 -0.222652 0.0174398 -0.018 -0.223527 0.019977 -0.00648901 -0.228506 0.016994 -0.012343 -0.222652 0.0178973 -0.018 -0.224425 0.016994 -0.012343 -0.222652 0.0174398 -0.018 -0.223527 0.0178973 -0.018 -0.224425 0.006494 0.023 -0.215023 0.012348 0.023 -0.218006 0.016497 0.023 -0.221995 4.00013e-06 0.021 -0.213995 0.006494 0.023 -0.215023 4.00022e-06 0.023 -0.213995 4.00013e-06 0.021 -0.213995 4.00022e-06 0.023 -0.213995 -0.006485 0.019973 -0.215023 -0.00666206 0.0198828 -0.21289 -0.006485 0.019973 -0.215023 -0.012339 0.01699 -0.212991 -0.012339 0.01699 -0.212991 -0.006485 0.019973 -0.215023 -0.012339 0.01699 -0.218006 -0.012339 0.01699 -0.218006 -0.0126553 0.0166737 -0.213002 -0.012339 0.01699 -0.212991 -0.019968 0.00648899 -0.144495 -0.017339 0.031547 -0.144495 -0.016985 0.012344 -0.144495 -0.01671 0.012619 -0.148846 -0.016985 0.012344 -0.148837 -0.016985 0.012344 -0.144495 -0.006485 0.019973 -0.215023 -0.00666206 0.0198828 -0.21289 -0.006485 0.019973 -0.212887 0.0119481 0.0171937 -0.212984 0.012348 0.01699 -0.212991 0.012348 0.01699 -0.218006 -0.00324058 0.0204865 -0.213937 -0.006485 0.019973 -0.212887 -0.000102773 0.0209831 -0.212851 -0.00324058 0.0204865 -0.213937 -0.006485 0.019973 -0.215023 -0.006485 0.019973 -0.212887 -0.00324058 0.0204865 -0.213937 4.00013e-06 0.021 -0.213995 -0.006485 0.019973 -0.215023 -0.00324058 0.0204865 -0.213937 -0.000102773 0.0209831 -0.212851 4.00013e-06 0.021 -0.213995 0.0119481 0.0171937 -0.212984 0.006494 0.019973 -0.215023 0.006494 0.019973 -0.212887 0.012348 0.01699 -0.218006 0.006494 0.019973 -0.215023 0.0119481 0.0171937 -0.212984 4.00013e-06 0.021 -0.213995 -0.000102773 0.0209831 -0.212851 4.00018e-06 0.021 -0.212851 0.006494 0.019973 -0.215023 0.00629732 0.0200041 -0.212886 0.006494 0.019973 -0.212887 0.003249 0.0204865 -0.213937 4.00018e-06 0.021 -0.212851 0.00629732 0.0200041 -0.212886 0.003249 0.0204865 -0.213937 4.00013e-06 0.021 -0.213995 4.00018e-06 0.021 -0.212851 0.003249 0.0204865 -0.213937 0.006494 0.019973 -0.215023 4.00013e-06 0.021 -0.213995 0.003249 0.0204865 -0.213937 0.00629732 0.0200041 -0.212886 0.006494 0.019973 -0.215023 -0.013248 -0.033472 -0.144495 -0.021156 -0.029125 -0.144495 -0.019968 -0.00648901 -0.144495 -0.024639 0.026243 -0.144495 -0.020995 -8.25938e-09 -0.144495 -0.021156 -0.029125 -0.144495 -0.020995 -8.25938e-09 -0.144495 -0.024639 0.026243 -0.144495 -0.017339 0.031547 -0.144495 -0.016985 -0.012343 -0.222652 -0.012339 -0.016989 -0.218006 -0.012339 -0.016989 -0.144495 -0.006485 -0.019972 -0.144495 -0.012339 -0.016989 -0.144495 -0.00932588 -0.0185244 -0.180169 -0.012339 -0.016989 -0.144495 -0.010355 -0.018 -0.181092 -0.00932588 -0.0185244 -0.180169 -0.012339 -0.016989 -0.144495 -0.010355 -0.018 -0.192702 -0.010355 -0.018 -0.185748 -0.010355 -0.018 -0.181092 -0.012339 -0.016989 -0.144495 -0.010355 -0.018 -0.185748 -0.010355 -0.018 -0.193092 -0.010355 -0.018 -0.192702 -0.012339 -0.016989 -0.144495 -0.012339 -0.016989 -0.218006 -0.010355 -0.018 -0.193092 -0.012339 -0.016989 -0.144495 -0.016985 -0.012343 -0.222652 -0.012339 -0.016989 -0.144495 -0.016985 -0.012343 -0.144495 -0.012339 -0.016989 -0.144495 -0.013248 -0.033472 -0.144495 -0.016985 -0.012343 -0.144495 0.012348 0.01699 -0.218006 0.012348 0.023 -0.218006 0.006494 0.019973 -0.215023 -0.01671 0.012619 -0.148846 -0.016985 0.012344 -0.144495 -0.014662 0.014667 -0.146747 -0.016985 0.012344 -0.144495 -0.012339 0.01699 -0.144495 -0.014662 0.014667 -0.146747 -0.012339 0.01699 -0.144495 -0.012339 0.01699 -0.148999 -0.014662 0.014667 -0.146747 -0.012339 0.01699 -0.148999 -0.01671 0.012619 -0.148846 -0.014662 0.014667 -0.146747 -0.012339 0.01699 -0.144495 -0.0119646 0.0171808 -0.149006 -0.012339 0.01699 -0.148999 -0.009412 0.018481 -0.146799 -0.006485 0.019972 -0.144495 -0.006485 0.0199721 -0.149103 -0.009412 0.018481 -0.146799 -0.012339 0.01699 -0.144495 -0.006485 0.019972 -0.144495 -0.009412 0.018481 -0.146799 -0.0119646 0.0171808 -0.149006 -0.012339 0.01699 -0.144495 -0.009412 0.018481 -0.146799 -0.006485 0.0199721 -0.149103 -0.0119646 0.0171808 -0.149006 -0.00605452 0.0200402 -0.149106 -0.006485 0.0199721 -0.149103 -0.006485 0.019972 -0.144495 -0.0032405 0.020486 -0.146817 4.00317e-06 0.021 -0.144495 4.00297e-06 0.021 -0.149139 -0.0032405 0.020486 -0.146817 -0.006485 0.019972 -0.144495 4.00317e-06 0.021 -0.144495 -0.0032405 0.020486 -0.146817 -0.00605452 0.0200402 -0.149106 -0.006485 0.019972 -0.144495 -0.0032405 0.020486 -0.146817 4.00297e-06 0.021 -0.149139 -0.00605452 0.0200402 -0.149106 0.000431144 0.0209324 -0.149137 4.00297e-06 0.021 -0.149139 4.00317e-06 0.021 -0.144495 0.00324901 0.020486 -0.146816 0.006494 0.019972 -0.144495 0.006494 0.0199721 -0.149103 0.00324901 0.020486 -0.146816 4.00317e-06 0.021 -0.144495 0.006494 0.019972 -0.144495 0.00324901 0.020486 -0.146816 0.000431144 0.0209324 -0.149137 4.00317e-06 0.021 -0.144495 0.00324901 0.020486 -0.146816 0.006494 0.0199721 -0.149103 0.000431144 0.0209324 -0.149137 0.00686046 0.0197853 -0.149097 0.006494 0.0199721 -0.149103 0.006494 0.019972 -0.144495 0.00686046 0.0197853 -0.149097 0.006494 0.019972 -0.144495 0.009421000000000001 0.018481 -0.146796 0.006494 0.019972 -0.144495 0.012348 0.01699 -0.144495 0.009421000000000001 0.018481 -0.146796 0.012348 0.01699 -0.144495 0.012348 0.01699 -0.148999 0.009421000000000001 0.018481 -0.146796 0.012348 0.01699 -0.148999 0.00686046 0.0197853 -0.149097 0.009421000000000001 0.018481 -0.146796 0.0126152 0.0167228 -0.14899 0.012348 0.01699 -0.148999 0.012348 0.01699 -0.144495 0.0126152 0.0167228 -0.14899 0.012348 0.01699 -0.144495 0.014671 0.014667 -0.146742 0.012348 0.01699 -0.144495 0.016994 0.012344 -0.144495 0.014671 0.014667 -0.146742 0.016994 0.012344 -0.144495 0.016994 0.012344 -0.148837 0.014671 0.014667 -0.146742 0.016994 0.012344 -0.148837 0.0126152 0.0167228 -0.14899 0.014671 0.014667 -0.146742 0.019977 0.00648999 -0.144495 0.017347 0.031547 -0.144495 0.024648 0.026243 -0.144495 0.016994 0.012344 -0.144495 0.012348 0.01699 -0.144495 0.017347 0.031547 -0.144495 0.021165 -0.029124 -0.144495 0.021004 -1.00952e-08 -0.144495 0.024648 0.026243 -0.144495 0.021165 -0.029124 -0.144495 0.019977 -0.00648901 -0.144495 0.021004 -1.00952e-08 -0.144495 0.016994 -0.012343 -0.222652 0.019977 -0.00648901 -0.228506 0.019977 -0.00648901 -0.144495 0.016994 -0.012343 -0.222652 0.016039 -0.018 -0.221507 0.016994 -0.018 -0.222652 0.006494 0.019973 -0.215023 0.012348 0.023 -0.218006 0.006494 0.023 -0.215023 0.006494 0.019973 -0.215023 0.006494 0.023 -0.215023 4.00013e-06 0.021 -0.213995 -0.016985 0.012344 -0.144495 -0.017339 0.031547 -0.144495 -0.008947999999999999 0.034869 -0.144495 -0.013248 -0.033472 -0.139995 -0.021156 -0.029125 -0.144495 -0.013248 -0.033472 -0.144495 -0.021156 -0.029125 -0.144495 -0.027734 -0.022947 -0.144495 -0.024639 0.026243 -0.144495 -0.024639 0.026243 -0.139995 -0.017339 0.031547 -0.144495 -0.024639 0.026243 -0.144495 -0.006485 -0.019972 -0.144495 -0.00932588 -0.0185244 -0.180169 -0.00873785 -0.018824 -0.179642 -0.006485 -0.019972 -0.144495 -0.00873785 -0.018824 -0.179642 -0.00857368 -0.0189077 -0.179495 -0.006485 -0.019972 -0.144495 -0.00857368 -0.0189077 -0.179495 -0.006485 -0.019972 -0.178618 -0.004507 -0.035716 -0.144495 -0.012339 -0.016989 -0.144495 -0.006485 -0.019972 -0.144495 -0.004507 -0.035716 -0.144495 -0.013248 -0.033472 -0.144495 -0.012339 -0.016989 -0.144495 -0.012339 0.01699 -0.144495 -0.016985 0.012344 -0.144495 -0.008947999999999999 0.034869 -0.144495 -0.006485 0.019972 -0.144495 -0.012339 0.01699 -0.144495 -0.008947999999999999 0.034869 -0.144495 4.00317e-06 0.021 -0.144495 -0.006485 0.019972 -0.144495 4.00382e-06 0.036 -0.144495 0.006494 0.019972 -0.144495 4.00317e-06 0.021 -0.144495 4.00382e-06 0.036 -0.144495 0.012348 0.01699 -0.144495 0.006494 0.019972 -0.144495 0.008957 0.034869 -0.144495 0.017347 0.031547 -0.139995 0.024648 0.026243 -0.144495 0.017347 0.031547 -0.144495 0.012348 0.01699 -0.144495 0.008957 0.034869 -0.144495 0.017347 0.031547 -0.144495 0.027743 -0.022947 -0.144495 0.021165 -0.029124 -0.144495 0.024648 0.026243 -0.144495 0.021165 -0.029124 -0.144495 0.016994 -0.012343 -0.144495 0.019977 -0.00648901 -0.144495 0.016994 -0.012343 -0.222652 0.019977 -0.00648901 -0.144495 0.016994 -0.012343 -0.144495 0.0157489 -0.018 -0.221229 0.016039 -0.018 -0.221507 0.016994 -0.012343 -0.222652 0.0128268 -0.018 -0.218425 0.0157489 -0.018 -0.221229 0.012348 -0.016989 -0.218006 0.0157489 -0.018 -0.221229 0.016994 -0.012343 -0.222652 0.012348 -0.016989 -0.218006 0.00937989 -0.0185015 -0.180254 0.010364 -0.018 -0.180877 0.012348 -0.016989 -0.144495 0.012348 -0.016989 -0.218006 0.010364 -0.018 -0.210463 0.010364 -0.018 -0.213909 0.012348 -0.016989 -0.218006 0.010364 -0.018 -0.205869 0.010364 -0.018 -0.210463 0.012348 -0.016989 -0.218006 0.010364 -0.018 -0.199636 0.010364 -0.018 -0.205869 0.010364 -0.018 -0.216525 0.012348 -0.016989 -0.218006 0.010364 -0.018 -0.213909 0.010364 -0.018 -0.216995 0.012348 -0.016989 -0.218006 0.010364 -0.018 -0.216525 0.010364 -0.018 -0.191116 0.010364 -0.018 -0.199636 0.012348 -0.016989 -0.218006 0.0108639 -0.0177452 -0.18125 0.012348 -0.016989 -0.218006 0.012348 -0.016989 -0.144495 0.0108639 -0.0177452 -0.18125 0.010364 -0.018 -0.191116 0.012348 -0.016989 -0.218006 0.0108639 -0.0177452 -0.18125 0.012348 -0.016989 -0.144495 0.010364 -0.018 -0.180877 -0.017339 0.031547 -0.139995 -0.008947999999999999 0.034869 -0.144495 -0.017339 0.031547 -0.144495 -0.013248 -0.033472 -0.139995 -0.013248 -0.033472 -0.144495 -0.004507 -0.035716 -0.139995 -0.021156 -0.029125 -0.139995 -0.021156 -0.029125 -0.144495 -0.013248 -0.033472 -0.139995 -0.021156 -0.029125 -0.139995 -0.027734 -0.022947 -0.144495 -0.021156 -0.029125 -0.144495 -0.027734 -0.022947 -0.144495 -0.030391 0.01929 -0.144495 -0.024639 0.026243 -0.144495 -0.024639 0.026243 -0.144495 -0.030391 0.01929 -0.139995 -0.024639 0.026243 -0.139995 -0.017339 0.031547 -0.139995 -0.017339 0.031547 -0.144495 -0.024639 0.026243 -0.139995 -0.00302369 -0.0205203 -0.177408 5.00133e-06 -0.021 -0.144495 -0.00324 -0.020486 -0.161557 5.00133e-06 -0.021 -0.144495 -0.006485 -0.019972 -0.144495 -0.00324 -0.020486 -0.161557 -0.006485 -0.019972 -0.144495 -0.006485 -0.019972 -0.178618 -0.00324 -0.020486 -0.161557 -0.006485 -0.019972 -0.178618 -0.00439959 -0.0203023 -0.177716 -0.00324 -0.020486 -0.161557 -0.00439959 -0.0203023 -0.177716 -0.00383344 -0.020392 -0.177471 -0.00324 -0.020486 -0.161557 -0.00383344 -0.020392 -0.177471 -0.00302369 -0.0205203 -0.177408 -0.00324 -0.020486 -0.161557 -0.004507 -0.035716 -0.144495 -0.006485 -0.019972 -0.144495 5.00133e-06 -0.021 -0.144495 -0.004507 -0.035716 -0.139995 -0.013248 -0.033472 -0.144495 -0.004507 -0.035716 -0.144495 -0.006485 0.019972 -0.144495 -0.008947999999999999 0.034869 -0.144495 4.00382e-06 0.036 -0.144495 0.006494 0.019972 -0.144495 4.00382e-06 0.036 -0.144495 0.008957 0.034869 -0.144495 0.017347 0.031547 -0.144495 0.008957 0.034869 -0.139995 0.017347 0.031547 -0.139995 0.024648 0.026243 -0.139995 0.024648 0.026243 -0.144495 0.017347 0.031547 -0.139995 0.008957 0.034869 -0.139995 0.017347 0.031547 -0.144495 0.008957 0.034869 -0.144495 0.0304 0.01929 -0.144495 0.027743 -0.022947 -0.144495 0.024648 0.026243 -0.144495 0.027743 -0.022947 -0.139995 0.021165 -0.029124 -0.144495 0.027743 -0.022947 -0.144495 0.021165 -0.029124 -0.144495 0.013257 -0.033472 -0.144495 0.016994 -0.012343 -0.144495 0.012348 -0.016989 -0.218006 0.016994 -0.012343 -0.222652 0.016994 -0.012343 -0.144495 0.012348 -0.018 -0.218006 0.0128268 -0.018 -0.218425 0.012348 -0.016989 -0.218006 0.012348 -0.018 -0.218006 0.012348 -0.016989 -0.218006 0.0113634 -0.018 -0.217504 0.0113634 -0.018 -0.217504 0.012348 -0.016989 -0.218006 0.0110984 -0.018 -0.217369 0.0110984 -0.018 -0.217369 0.012348 -0.016989 -0.218006 0.010364 -0.018 -0.216995 0.00937989 -0.0185015 -0.180254 0.012348 -0.016989 -0.144495 0.009421000000000001 -0.0184805 -0.162375 0.012348 -0.016989 -0.144495 0.006494 -0.019972 -0.144495 0.009421000000000001 -0.0184805 -0.162375 0.006494 -0.019972 -0.144495 0.006494 -0.019972 -0.178429 0.009421000000000001 -0.0184805 -0.162375 0.006494 -0.019972 -0.178429 0.00937989 -0.0185015 -0.180254 0.009421000000000001 -0.0184805 -0.162375 0.012348 -0.016989 -0.218006 0.016994 -0.012343 -0.144495 0.012348 -0.016989 -0.144495 -0.008947999999999999 0.034869 -0.139995 -0.008947999999999999 0.034869 -0.144495 -0.017339 0.031547 -0.139995 -0.013248 -0.033472 -0.139995 -0.004507 -0.035716 -0.139995 -0.035358 -0.00674601 -0.139995 -0.021156 -0.029125 -0.139995 -0.013248 -0.033472 -0.139995 -0.035358 -0.00674601 -0.139995 -0.027734 -0.022947 -0.139995 -0.027734 -0.022947 -0.144495 -0.021156 -0.029125 -0.139995 -0.030391 0.01929 -0.144495 -0.027734 -0.022947 -0.144495 -0.032569 -0.015328 -0.144495 -0.030391 0.01929 -0.139995 -0.024639 0.026243 -0.144495 -0.030391 0.01929 -0.144495 -0.024639 0.026243 -0.139995 -0.030391 0.01929 -0.139995 -0.035358 -0.00674601 -0.139995 -0.035358 -0.00674601 -0.139995 -0.017339 0.031547 -0.139995 -0.024639 0.026243 -0.139995 -0.00302369 -0.0205203 -0.177408 4.5297e-06 -0.021 -0.177174 5.00133e-06 -0.021 -0.144495 0.004517 -0.035716 -0.144495 -0.004507 -0.035716 -0.144495 5.00133e-06 -0.021 -0.144495 -0.004507 -0.035716 -0.139995 -0.004507 -0.035716 -0.144495 0.004517 -0.035716 -0.139995 -0.008947999999999999 0.034869 -0.139995 4.00382e-06 0.036 -0.144495 -0.008947999999999999 0.034869 -0.144495 0.008957 0.034869 -0.144495 4.00382e-06 0.036 -0.144495 4.00401e-06 0.036 -0.139995 0.017347 0.031547 -0.139995 0.008957 0.034869 -0.139995 -0.035358 -0.00674601 -0.139995 0.024648 0.026243 -0.139995 0.017347 0.031547 -0.139995 -0.035358 -0.00674601 -0.139995 0.024648 0.026243 -0.144495 0.024648 0.026243 -0.139995 0.0304 0.01929 -0.144495 0.008957 0.034869 -0.139995 0.008957 0.034869 -0.144495 4.00401e-06 0.036 -0.139995 0.032578 -0.015328 -0.144495 0.027743 -0.022947 -0.144495 0.0304 0.01929 -0.144495 0.027743 -0.022947 -0.144495 0.032578 -0.015328 -0.139995 0.027743 -0.022947 -0.139995 0.021165 -0.029124 -0.139995 0.021165 -0.029124 -0.144495 0.027743 -0.022947 -0.139995 0.013257 -0.033472 -0.144495 0.021165 -0.029124 -0.144495 0.021165 -0.029124 -0.139995 0.013257 -0.033472 -0.144495 0.012348 -0.016989 -0.144495 0.016994 -0.012343 -0.144495 0.006494 -0.019972 -0.144495 0.00340422 -0.0204614 -0.177583 0.00574517 -0.0200906 -0.178162 0.006494 -0.019972 -0.144495 0.00574517 -0.0200906 -0.178162 0.00628983 -0.0200043 -0.178297 0.006494 -0.019972 -0.144495 0.00628983 -0.0200043 -0.178297 0.006494 -0.019972 -0.178429 0.013257 -0.033472 -0.144495 0.006494 -0.019972 -0.144495 0.012348 -0.016989 -0.144495 -0.035358 -0.00674601 -0.139995 -0.008947999999999999 0.034869 -0.139995 -0.017339 0.031547 -0.139995 -0.004507 -0.035716 -0.139995 0.004517 -0.035716 -0.139995 -0.035358 -0.00674601 -0.139995 -0.027734 -0.022947 -0.139995 -0.021156 -0.029125 -0.139995 -0.035358 -0.00674601 -0.139995 -0.027734 -0.022947 -0.144495 -0.027734 -0.022947 -0.139995 -0.032569 -0.015328 -0.144495 -0.034233 0.011125 -0.144495 -0.030391 0.01929 -0.144495 -0.032569 -0.015328 -0.144495 -0.030391 0.01929 -0.144495 -0.034233 0.011125 -0.139995 -0.030391 0.01929 -0.139995 -0.030391 0.01929 -0.139995 -0.034233 0.011125 -0.139995 -0.035358 -0.00674601 -0.139995 0.00324926 -0.020486 -0.161039 0.000513453 -0.0209194 -0.177129 0.00129399 -0.0207957 -0.17706 0.00324926 -0.020486 -0.161039 4.5297e-06 -0.021 -0.177174 0.000513453 -0.0209194 -0.177129 0.00324926 -0.020486 -0.161039 5.00133e-06 -0.021 -0.144495 4.5297e-06 -0.021 -0.177174 0.00324926 -0.020486 -0.161039 0.006494 -0.019972 -0.144495 5.00133e-06 -0.021 -0.144495 0.00324926 -0.020486 -0.161039 0.00340422 -0.0204614 -0.177583 0.006494 -0.019972 -0.144495 0.00324926 -0.020486 -0.161039 0.00129399 -0.0207957 -0.17706 0.00340422 -0.0204614 -0.177583 -0.004507 -0.035716 -0.144495 0.004517 -0.035716 -0.144495 0.004517 -0.035716 -0.139995 0.004517 -0.035716 -0.144495 5.00133e-06 -0.021 -0.144495 0.006494 -0.019972 -0.144495 4.00401e-06 0.036 -0.139995 4.00382e-06 0.036 -0.144495 -0.008947999999999999 0.034869 -0.139995 -0.035358 -0.00674601 -0.139995 0.008957 0.034869 -0.139995 4.00401e-06 0.036 -0.139995 0.0304 0.01929 -0.139995 0.024648 0.026243 -0.139995 -0.035358 -0.00674601 -0.139995 0.024648 0.026243 -0.139995 0.0304 0.01929 -0.139995 0.0304 0.01929 -0.144495 0.032578 -0.015328 -0.144495 0.0304 0.01929 -0.144495 0.034242 0.011125 -0.144495 0.032578 -0.015328 -0.144495 0.032578 -0.015328 -0.139995 0.027743 -0.022947 -0.144495 0.027743 -0.022947 -0.139995 0.032578 -0.015328 -0.139995 -0.035358 -0.00674601 -0.139995 0.021165 -0.029124 -0.139995 0.027743 -0.022947 -0.139995 -0.035358 -0.00674601 -0.139995 0.013257 -0.033472 -0.139995 0.013257 -0.033472 -0.144495 0.021165 -0.029124 -0.139995 0.013257 -0.033472 -0.144495 0.004517 -0.035716 -0.144495 0.006494 -0.019972 -0.144495 -0.035358 -0.00674601 -0.139995 4.00401e-06 0.036 -0.139995 -0.008947999999999999 0.034869 -0.139995 0.004517 -0.035716 -0.139995 0.013257 -0.033472 -0.139995 -0.035358 -0.00674601 -0.139995 -0.032569 -0.015328 -0.139995 -0.027734 -0.022947 -0.139995 -0.035358 -0.00674601 -0.139995 -0.032569 -0.015328 -0.144495 -0.027734 -0.022947 -0.139995 -0.032569 -0.015328 -0.139995 -0.034233 0.011125 -0.144495 -0.032569 -0.015328 -0.144495 -0.035358 -0.00674601 -0.144495 -0.034233 0.011125 -0.144495 -0.034233 0.011125 -0.139995 -0.030391 0.01929 -0.144495 -0.034233 0.011125 -0.139995 -0.035924 0.00226 -0.139995 -0.035358 -0.00674601 -0.139995 0.004517 -0.035716 -0.139995 0.004517 -0.035716 -0.144495 0.013257 -0.033472 -0.139995 0.034242 0.011125 -0.139995 0.0304 0.01929 -0.139995 -0.035358 -0.00674601 -0.139995 0.0304 0.01929 -0.139995 0.034242 0.011125 -0.144495 0.0304 0.01929 -0.144495 0.035367 -0.00674601 -0.144495 0.032578 -0.015328 -0.144495 0.034242 0.011125 -0.144495 0.032578 -0.015328 -0.144495 0.035367 -0.00674601 -0.139995 0.032578 -0.015328 -0.139995 0.032578 -0.015328 -0.139995 0.035367 -0.00674601 -0.139995 -0.035358 -0.00674601 -0.139995 0.013257 -0.033472 -0.139995 0.021165 -0.029124 -0.139995 -0.035358 -0.00674601 -0.139995 0.013257 -0.033472 -0.139995 0.004517 -0.035716 -0.144495 0.013257 -0.033472 -0.144495 -0.035358 -0.00674601 -0.144495 -0.032569 -0.015328 -0.139995 -0.035358 -0.00674601 -0.139995 -0.032569 -0.015328 -0.144495 -0.032569 -0.015328 -0.139995 -0.035358 -0.00674601 -0.144495 -0.035924 0.00226 -0.144495 -0.034233 0.011125 -0.144495 -0.035358 -0.00674601 -0.144495 -0.035924 0.00226 -0.139995 -0.034233 0.011125 -0.139995 -0.034233 0.011125 -0.144495 -0.035924 0.00226 -0.139995 -0.035995 -7.407e-09 -0.139995 -0.035358 -0.00674601 -0.139995 0.035933 0.00226099 -0.139995 0.034242 0.011125 -0.139995 -0.035358 -0.00674601 -0.139995 0.0304 0.01929 -0.139995 0.034242 0.011125 -0.139995 0.034242 0.011125 -0.144495 0.035367 -0.00674601 -0.144495 0.034242 0.011125 -0.144495 0.035933 0.00226099 -0.144495 0.035367 -0.00674601 -0.139995 0.032578 -0.015328 -0.144495 0.035367 -0.00674601 -0.144495 0.035367 -0.00674601 -0.139995 0.035933 0.00226099 -0.139995 -0.035358 -0.00674601 -0.139995 -0.035358 -0.00674601 -0.144495 -0.035358 -0.00674601 -0.139995 -0.035995 -7.60371e-09 -0.144495 -0.035924 0.00226 -0.144495 -0.035358 -0.00674601 -0.144495 -0.035995 -7.60371e-09 -0.144495 -0.035924 0.00226 -0.144495 -0.035924 0.00226 -0.139995 -0.034233 0.011125 -0.144495 -0.035995 -7.60371e-09 -0.144495 -0.035358 -0.00674601 -0.139995 -0.035995 -7.407e-09 -0.139995 -0.035924 0.00226 -0.144495 -0.035995 -7.407e-09 -0.139995 -0.035924 0.00226 -0.139995 0.035933 0.00226099 -0.144495 0.034242 0.011125 -0.139995 0.035933 0.00226099 -0.139995 0.034242 0.011125 -0.144495 0.034242 0.011125 -0.139995 0.035933 0.00226099 -0.144495 0.035933 0.00226099 -0.144495 0.035933 0.00226099 -0.139995 0.035367 -0.00674601 -0.144495 0.035367 -0.00674601 -0.144495 0.035933 0.00226099 -0.139995 0.035367 -0.00674601 -0.139995 -0.035924 0.00226 -0.144495 -0.035995 -7.60371e-09 -0.144495 -0.035995 -7.407e-09 -0.139995 -0.012339 0.01699 -0.212991 -0.02377 0.008999989999999999 -0.21327 4.49922e-06 0.02725 -0.212633 0.022505 0.0455 -0.211995 0.006494 0.019973 -0.212887 4.49922e-06 0.02725 -0.212633 0.023779 0.008999989999999999 -0.21327 0.0186974 0.008999989999999999 -0.21327 0.016994 0.012344 -0.213153 0.023779 0.008999989999999999 -0.21327 0.016994 0.012344 -0.213153 0.0164282 0.0129098 -0.213133 0.0164282 0.0129098 -0.213133 0.012348 0.01699 -0.212991 0.022505 0.0455 -0.211995 0.012348 0.01699 -0.212991 0.0119481 0.0171937 -0.212984 0.022505 0.0455 -0.211995 0.0119481 0.0171937 -0.212984 0.006494 0.019973 -0.212887 0.022505 0.0455 -0.211995 0.023779 0.008999989999999999 -0.21327 0.0164282 0.0129098 -0.213133 0.022505 0.0455 -0.211995 -0.0173466 0.0116343 -0.213178 -0.0186889 0.008999989999999999 -0.21327 -0.02377 0.008999989999999999 -0.21327 -0.016985 0.012344 -0.213153 -0.0173466 0.0116343 -0.213178 -0.02377 0.008999989999999999 -0.21327 -0.0126553 0.0166737 -0.213002 -0.016985 0.012344 -0.213153 -0.02377 0.008999989999999999 -0.21327 -0.0126553 0.0166737 -0.213002 -0.02377 0.008999989999999999 -0.21327 -0.012339 0.01699 -0.212991 -0.02377 0.008999989999999999 -0.21327 0.022505 0.0455 -0.211995 4.49922e-06 0.02725 -0.212633 -0.00666206 0.0198828 -0.21289 -0.012339 0.01699 -0.212991 4.49922e-06 0.02725 -0.212633 -0.006485 0.019973 -0.212887 -0.00666206 0.0198828 -0.21289 4.49922e-06 0.02725 -0.212633 -0.000102773 0.0209831 -0.212851 -0.006485 0.019973 -0.212887 4.49922e-06 0.02725 -0.212633 4.00018e-06 0.021 -0.212851 -0.000102773 0.0209831 -0.212851 4.49922e-06 0.02725 -0.212633 0.006494 0.019973 -0.212887 0.00629732 0.0200041 -0.212886 4.49922e-06 0.02725 -0.212633 0.00629732 0.0200041 -0.212886 4.00018e-06 0.021 -0.212851 4.49922e-06 0.02725 -0.212633 -0.0186887 0.008999989999999999 -0.178013 -0.0186887 0.008999989999999999 -0.155618 -0.0212294 0.008999989999999999 -0.180995 -0.0186887 0.008999989999999999 -0.155618 -0.02377 0.008999989999999999 -0.14872 -0.0212294 0.008999989999999999 -0.180995 -0.02377 0.008999989999999999 -0.14872 -0.02377 0.008999989999999999 -0.21327 -0.0212294 0.008999989999999999 -0.180995 -0.02377 0.008999989999999999 -0.21327 -0.0186889 0.008999989999999999 -0.21327 -0.0212294 0.008999989999999999 -0.180995 -0.0186889 0.008999989999999999 -0.21327 -0.0186887 0.008999989999999999 -0.178013 -0.0212294 0.008999989999999999 -0.180995 0.0186974 0.008999989999999999 -0.206372 0.023779 0.008999989999999999 -0.21327 0.0186974 0.008999989999999999 -0.192485 0.023779 0.008999989999999999 -0.21327 0.023779 0.008999989999999999 -0.14872 0.0212382 0.008999989999999999 -0.180995 0.023779 0.008999989999999999 -0.14872 0.0186979 0.008999989999999999 -0.14872 0.0212382 0.008999989999999999 -0.180995 0.0186979 0.008999989999999999 -0.14872 0.0186974 0.008999989999999999 -0.192485 0.0212382 0.008999989999999999 -0.180995 0.0186974 0.008999989999999999 -0.192485 0.023779 0.008999989999999999 -0.21327 0.0212382 0.008999989999999999 -0.180995 0.0186974 0.008999989999999999 -0.21327 0.023779 0.008999989999999999 -0.21327 0.0186974 0.008999989999999999 -0.206372 4.00297e-06 0.021 -0.149139 0.000431144 0.0209324 -0.149137 4.49922e-06 0.02725 -0.149357 0.000431144 0.0209324 -0.149137 0.006494 0.0199721 -0.149103 4.49922e-06 0.02725 -0.149357 0.006494 0.0199721 -0.149103 0.00686046 0.0197853 -0.149097 4.49922e-06 0.02725 -0.149357 0.00686046 0.0197853 -0.149097 0.012348 0.01699 -0.148999 4.49922e-06 0.02725 -0.149357 0.012348 0.01699 -0.148999 0.023779 0.008999989999999999 -0.14872 4.49922e-06 0.02725 -0.149357 -0.022496 0.0455 -0.149995 -0.006485 0.0199721 -0.149103 4.49922e-06 0.02725 -0.149357 0.023779 0.008999989999999999 -0.14872 0.012348 0.01699 -0.148999 0.0126152 0.0167228 -0.14899 0.023779 0.008999989999999999 -0.14872 0.0126152 0.0167228 -0.14899 0.016994 0.012344 -0.148837 0.023779 0.008999989999999999 -0.14872 0.016994 0.012344 -0.148837 0.0171477 0.0120422 -0.148826 0.023779 0.008999989999999999 -0.14872 0.0171477 0.0120422 -0.148826 0.0186979 0.008999989999999999 -0.14872 -0.006485 0.0199721 -0.149103 -0.022496 0.0455 -0.149995 -0.0119646 0.0171808 -0.149006 -0.0119646 0.0171808 -0.149006 -0.022496 0.0455 -0.149995 -0.012339 0.01699 -0.148999 -0.012339 0.01699 -0.148999 -0.022496 0.0455 -0.149995 -0.01671 0.012619 -0.148846 -0.0186887 0.008999989999999999 -0.14872 -0.016985 0.012344 -0.148837 -0.02377 0.008999989999999999 -0.14872 -0.016985 0.012344 -0.148837 -0.01671 0.012619 -0.148846 -0.02377 0.008999989999999999 -0.14872 -0.01671 0.012619 -0.148846 -0.022496 0.0455 -0.149995 -0.02377 0.008999989999999999 -0.14872 0.023779 0.008999989999999999 -0.14872 -0.022496 0.0455 -0.149995 4.49922e-06 0.02725 -0.149357 -0.006485 0.0199721 -0.149103 -0.00605452 0.0200402 -0.149106 4.49922e-06 0.02725 -0.149357 -0.00605452 0.0200402 -0.149106 4.00297e-06 0.021 -0.149139 4.49922e-06 0.02725 -0.149357 -0.02377 0.008999989999999999 -0.14872 -0.0186887 0.008999989999999999 -0.155618 -0.0186887 0.008999989999999999 -0.14872 0.022505 0.0455 -0.211995 -0.02377 0.008999989999999999 -0.21327 0.006878 0.0455 -0.211995 0.006878 0.0455 -0.211995 -0.02377 0.008999989999999999 -0.21327 -0.006869 0.0455 -0.211995 -0.006869 0.0455 -0.211995 -0.02377 0.008999989999999999 -0.21327 -0.022495 0.0455 -0.211995 0.023779 0.008999989999999999 -0.14872 0.023779 0.008999989999999999 -0.21327 0.022505 0.0455 -0.211995 -0.02377 0.008999989999999999 -0.21327 -0.02377 0.008999989999999999 -0.14872 -0.022496 0.0455 -0.149995 0.023779 0.008999989999999999 -0.14872 0.022505 0.0455 -0.149995 -0.022496 0.0455 -0.149995 -0.022495 0.0455 -0.211995 -0.02377 0.008999989999999999 -0.21327 -0.022496 0.0455 -0.149995 0.006878 0.0455 -0.211995 0.008137999999999999 0.0455 -0.198317 0.022505 0.0455 -0.211995 0.008137999999999999 0.0455 -0.198317 0.00814 0.0455 -0.198289 0.022505 0.0455 -0.211995 0.00814 0.0455 -0.198289 0.008336 0.0455 -0.192393 0.022505 0.0455 -0.211995 0.008336 0.0455 -0.192393 0.008246 0.0455 -0.186493 0.0146915 0.0455 -0.180995 0.008246 0.0455 -0.186493 0.008133 0.0455 -0.184585 0.0146915 0.0455 -0.180995 0.008133 0.0455 -0.184585 0.007896 0.0455 -0.180603 0.0146915 0.0455 -0.180995 0.007896 0.0455 -0.180603 0.00755 0.0455 -0.176684 0.0146915 0.0455 -0.180995 0.00755 0.0455 -0.176684 0.007137 0.0455 -0.172772 0.0146915 0.0455 -0.180995 0.007137 0.0455 -0.172772 0.00693438 0.0455 -0.171448 0.0146915 0.0455 -0.180995 0.00693438 0.0455 -0.171448 0.022505 0.0455 -0.149995 0.0146915 0.0455 -0.180995 0.022505 0.0455 -0.149995 0.022505 0.0455 -0.211995 0.0146915 0.0455 -0.180995 0.022505 0.0455 -0.211995 0.008336 0.0455 -0.192393 0.0146915 0.0455 -0.180995 -0.022495 0.0455 -0.211995 -0.008324349999999999 0.0455 -0.192471 -0.008132 0.0455 -0.198288 -0.022495 0.0455 -0.211995 -0.008132 0.0455 -0.198288 -0.007698 0.0455 -0.204172 -0.022495 0.0455 -0.211995 -0.007698 0.0455 -0.204172 -0.007311 0.0455 -0.208087 -0.022495 0.0455 -0.211995 -0.007311 0.0455 -0.208087 -0.00725697 0.0455 -0.208565 -0.022495 0.0455 -0.211995 -0.00725697 0.0455 -0.208565 -0.00724647 0.0455 -0.208658 -0.022495 0.0455 -0.211995 -0.00724647 0.0455 -0.208658 -0.00723435 0.0455 -0.208765 -0.022495 0.0455 -0.211995 -0.00723435 0.0455 -0.208765 -0.00720616 0.0455 -0.209014 -0.022495 0.0455 -0.211995 -0.00720616 0.0455 -0.209014 -0.00713998 0.0455 -0.209599 -0.022495 0.0455 -0.211995 -0.00713998 0.0455 -0.209599 -0.00706299 0.0455 -0.21028 -0.022495 0.0455 -0.211995 -0.00706299 0.0455 -0.21028 -0.00705235 0.0455 -0.210374 -0.022495 0.0455 -0.211995 -0.00705235 0.0455 -0.210374 -0.00700771 0.0455 -0.210769 -0.022495 0.0455 -0.211995 -0.00700771 0.0455 -0.210769 -0.006869 0.0455 -0.211995 0.006878 0.0455 -0.211995 -0.006869 0.0455 -0.211995 -0.006822 0.045919 -0.21198 0.022505 0.0455 -0.211995 0.022505 0.0455 -0.149995 0.023779 0.008999989999999999 -0.14872 0.00586 0.0455 -0.166496 0.004866 0.0455 -0.164357 0.022505 0.0455 -0.149995 0.004866 0.0455 -0.164357 0.004003 0.0455 -0.162498 0.022505 0.0455 -0.149995 0.004003 0.0455 -0.162498 0.00289 0.0455 -0.161151 0.022505 0.0455 -0.149995 0.00289 0.0455 -0.161151 0.00176572 0.0455 -0.160304 0.022505 0.0455 -0.149995 0.00176572 0.0455 -0.160304 0.000607004 0.0455 -0.159878 0.022505 0.0455 -0.149995 0.000607004 0.0455 -0.159878 3.56653e-09 0.0455 -0.159822 0.022505 0.0455 -0.149995 3.56653e-09 0.0455 -0.159822 -0.022496 0.0455 -0.149995 0.022505 0.0455 -0.149995 -0.022496 0.0455 -0.149995 -0.00290525 0.0455 -0.161177 -0.004013 0.0455 -0.162526 -0.022496 0.0455 -0.149995 -0.00754 0.0455 -0.176683 -0.007887 0.0455 -0.180602 -0.00290525 0.0455 -0.161177 -0.022496 0.0455 -0.149995 -0.001762 0.0455 -0.160306 0.00586 0.0455 -0.166496 0.022505 0.0455 -0.149995 0.006652 0.0455 -0.169601 -0.001762 0.0455 -0.160306 -0.022496 0.0455 -0.149995 -0.000602996 0.0455 -0.159879 -0.022496 0.0455 -0.149995 -0.004013 0.0455 -0.162526 -0.004759 0.0455 -0.164141 0.006652 0.0455 -0.169601 0.022505 0.0455 -0.149995 0.006851 0.0455 -0.170903 -0.000602996 0.0455 -0.159879 -0.022496 0.0455 -0.149995 3.56653e-09 0.0455 -0.159822 0.006851 0.0455 -0.170903 0.022505 0.0455 -0.149995 0.00693438 0.0455 -0.171448 -0.022496 0.0455 -0.149995 -0.004759 0.0455 -0.164141 -0.005859 0.0455 -0.166523 -0.007887 0.0455 -0.180602 -0.008238000000000001 0.0455 -0.186491 -0.022495 0.0455 -0.211995 -0.008238000000000001 0.0455 -0.186491 -0.008326999999999999 0.0455 -0.192391 -0.022495 0.0455 -0.211995 -0.008326999999999999 0.0455 -0.192391 -0.008324349999999999 0.0455 -0.192471 -0.022495 0.0455 -0.211995 -0.022496 0.0455 -0.149995 -0.007887 0.0455 -0.180602 -0.022495 0.0455 -0.211995 -0.022496 0.0455 -0.149995 -0.005859 0.0455 -0.166523 -0.006647 0.0455 -0.169617 -0.022496 0.0455 -0.149995 -0.006647 0.0455 -0.169617 -0.007127 0.0455 -0.172772 -0.022496 0.0455 -0.149995 -0.007127 0.0455 -0.172772 -0.00754 0.0455 -0.176683 0.006878 0.0455 -0.211995 0.006831 0.045919 -0.21198 0.008137999999999999 0.0455 -0.198317 0.008137999999999999 0.0455 -0.198317 0.00814 0.0455 -0.198289 0.008113 0.045961 -0.198393 0.00814 0.0455 -0.198289 0.008113 0.045961 -0.198393 0.008336 0.0455 -0.192393 0.008246 0.0455 -0.186493 0.008336 0.0455 -0.192393 0.008196999999999999 0.046021 -0.184803 0.008246 0.0455 -0.186493 0.008196999999999999 0.046021 -0.184803 0.008133 0.0455 -0.184585 0.008133 0.0455 -0.184585 0.008196999999999999 0.046021 -0.184803 0.007896 0.0455 -0.180603 0.00755 0.0455 -0.176684 0.007896 0.0455 -0.180603 0.008196999999999999 0.046021 -0.184803 0.007007 0.046085 -0.171281 0.007137 0.0455 -0.172772 0.00755 0.0455 -0.176684 0.007137 0.0455 -0.172772 0.007007 0.046085 -0.171281 0.00693438 0.0455 -0.171448 0.00693438 0.0455 -0.171448 0.007007 0.046085 -0.171281 0.006851 0.0455 -0.170903 -0.00716 0.045965 -0.208648 -0.00725697 0.0455 -0.208565 -0.007311 0.0455 -0.208087 -0.00716 0.045965 -0.208648 -0.00725697 0.0455 -0.208565 -0.00724647 0.0455 -0.208658 -0.00716 0.045965 -0.208648 -0.00724647 0.0455 -0.208658 -0.00723435 0.0455 -0.208765 -0.00720616 0.0455 -0.209014 -0.00723435 0.0455 -0.208765 -0.00716 0.045965 -0.208648 -0.00713998 0.0455 -0.209599 -0.00720616 0.0455 -0.209014 -0.00716 0.045965 -0.208648 -0.00713998 0.0455 -0.209599 -0.00716 0.045965 -0.208648 -0.00706299 0.0455 -0.21028 -0.006995 0.045943 -0.210316 -0.00706299 0.0455 -0.21028 -0.00705235 0.0455 -0.210374 -0.00700771 0.0455 -0.210769 -0.00705235 0.0455 -0.210374 -0.006995 0.045943 -0.210316 -0.006869 0.0455 -0.211995 -0.00700771 0.0455 -0.210769 -0.006995 0.045943 -0.210316 -0.006822 0.045919 -0.21198 -0.006869 0.0455 -0.211995 -0.006995 0.045943 -0.210316 0.006831 0.045919 -0.21198 0.006878 0.0455 -0.211995 -0.006822 0.045919 -0.21198 0.006851 0.0455 -0.170903 0.007007 0.046085 -0.171281 0.006652 0.0455 -0.169601 0.00586 0.0455 -0.166496 0.006652 0.0455 -0.169601 0.007007 0.046085 -0.171281 0.005175 0.046114 -0.164753 0.004866 0.0455 -0.164357 0.00586 0.0455 -0.166496 0.005175 0.046114 -0.164753 0.004003 0.0455 -0.162498 0.004866 0.0455 -0.164357 0.00176572 0.0455 -0.160304 0.001976 0.046132 -0.160814 0.000607004 0.0455 -0.159878 3.56653e-09 0.0455 -0.159822 0.000355004 0.046138 -0.160347 -0.000602996 0.0455 -0.159879 -0.001762 0.0455 -0.160306 -0.000602996 0.0455 -0.159879 0.000355004 0.046138 -0.160347 -0.00290525 0.0455 -0.161177 -0.001762 0.0455 -0.160306 -0.002695 0.046147 -0.161743 -0.00290525 0.0455 -0.161177 -0.002695 0.046147 -0.161743 -0.004013 0.0455 -0.162526 -0.004628 0.046155 -0.164618 -0.004759 0.0455 -0.164141 -0.004013 0.0455 -0.162526 -0.005859 0.0455 -0.166523 -0.004759 0.0455 -0.164141 -0.004628 0.046155 -0.164618 -0.006647 0.0455 -0.169617 -0.005859 0.0455 -0.166523 -0.006553 0.046164 -0.171254 -0.00754 0.0455 -0.176683 -0.007127 0.0455 -0.172772 -0.007325 0.046161 -0.178096 0.008113 0.045961 -0.198393 0.008137999999999999 0.0455 -0.198317 0.006831 0.045919 -0.21198 0.008336 0.0455 -0.192393 0.008113 0.045961 -0.198393 0.008196999999999999 0.046021 -0.184803 0.00755 0.0455 -0.176684 0.008196999999999999 0.046021 -0.184803 0.007007 0.046085 -0.171281 -0.00716 0.045965 -0.208648 -0.007311 0.0455 -0.208087 -0.007463 0.046006 -0.2053 -0.006995 0.045943 -0.210316 -0.00706299 0.0455 -0.21028 -0.00716 0.045965 -0.208648 -0.006822 0.045919 -0.21198 -0.006995 0.045943 -0.210316 -0.00692 0.046389 -0.210359 0.006784 0.046339 -0.211966 0.006831 0.045919 -0.21198 -0.006822 0.045919 -0.21198 0.00586 0.0455 -0.166496 0.007007 0.046085 -0.171281 0.005175 0.046114 -0.164753 0.00332 0.046126 -0.161881 0.004003 0.0455 -0.162498 0.005175 0.046114 -0.164753 0.001976 0.046132 -0.160814 0.000355004 0.046138 -0.160347 0.000607004 0.0455 -0.159878 0.000133004 0.0455 -0.159835 0.000355004 0.046138 -0.160347 3.56653e-09 0.0455 -0.159822 -0.002695 0.046147 -0.161743 -0.001762 0.0455 -0.160306 0.000355004 0.046138 -0.160347 -0.004013 0.0455 -0.162526 -0.002695 0.046147 -0.161743 -0.004628 0.046155 -0.164618 -0.005859 0.0455 -0.166523 -0.004628 0.046155 -0.164618 -0.006553 0.046164 -0.171254 -0.006553 0.046164 -0.171254 -0.006813 0.0455 -0.170709 -0.006647 0.0455 -0.169617 -0.007127 0.0455 -0.172772 -0.006553 0.046164 -0.171254 -0.007325 0.046161 -0.178096 -0.007325 0.046161 -0.178096 -0.007618 0.0455 -0.177565 -0.00754 0.0455 -0.176683 0.006831 0.045919 -0.21198 0.006784 0.046339 -0.211966 0.008113 0.045961 -0.198393 0.008113 0.045961 -0.198393 0.008055 0.046462 -0.198561 0.008196999999999999 0.046021 -0.184803 0.007007 0.046085 -0.171281 0.008196999999999999 0.046021 -0.184803 0.00818 0.046603 -0.185194 -0.00716 0.045965 -0.208648 -0.007463 0.046006 -0.2053 -0.007313 0.046522 -0.205499 -0.007311 0.0455 -0.208087 -0.007603 0.0455 -0.205131 -0.007463 0.046006 -0.2053 -0.006995 0.045943 -0.210316 -0.00716 0.045965 -0.208648 -0.007058 0.046436 -0.208745 -0.00692 0.046389 -0.210359 -0.006995 0.045943 -0.210316 -0.007058 0.046436 -0.208745 -0.006774 0.046339 -0.211966 -0.006822 0.045919 -0.21198 -0.00692 0.046389 -0.210359 0.006784 0.046339 -0.211966 -0.006822 0.045919 -0.21198 -0.006774 0.046339 -0.211966 0.007067 0.046738 -0.171904 0.005175 0.046114 -0.164753 0.007007 0.046085 -0.171281 0.005285 0.046794 -0.165484 0.00332 0.046126 -0.161881 0.005175 0.046114 -0.164753 0.00332 0.046126 -0.161881 0.003103 0.0455 -0.161409 0.004003 0.0455 -0.162498 0.00176572 0.0455 -0.160304 0.00289 0.0455 -0.161151 0.001976 0.046132 -0.160814 0.000355004 0.046138 -0.160347 0.001976 0.046132 -0.160814 0.002139 0.04683 -0.161613 0.000607004 0.0455 -0.159878 0.000355004 0.046138 -0.160347 0.000133004 0.0455 -0.159835 -0.002695 0.046147 -0.161743 0.000355004 0.046138 -0.160347 0.000539004 0.04684 -0.16116 -0.002695 0.046147 -0.161743 -0.00247 0.046857 -0.162563 -0.004628 0.046155 -0.164618 -0.004375 0.04687 -0.165428 -0.006553 0.046164 -0.171254 -0.004628 0.046155 -0.164618 -0.007127 0.0455 -0.172772 -0.006813 0.0455 -0.170709 -0.006553 0.046164 -0.171254 -0.006265 0.046882 -0.172025 -0.007325 0.046161 -0.178096 -0.006553 0.046164 -0.171254 -0.007887 0.0455 -0.180602 -0.007618 0.0455 -0.177565 -0.007325 0.046161 -0.178096 0.008055 0.046462 -0.198561 0.008113 0.045961 -0.198393 0.006784 0.046339 -0.211966 0.008055 0.046462 -0.198561 0.00818 0.046603 -0.185194 0.008196999999999999 0.046021 -0.184803 0.007007 0.046085 -0.171281 0.00818 0.046603 -0.185194 0.007067 0.046738 -0.171904 -0.007313 0.046522 -0.205499 -0.007463 0.046006 -0.2053 -0.007527 0.046597 -0.202228 -0.007058 0.046436 -0.208745 -0.00716 0.045965 -0.208648 -0.007313 0.046522 -0.205499 -0.007463 0.046006 -0.2053 -0.007603 0.0455 -0.205131 -0.007698 0.0455 -0.204172 -0.00692 0.046389 -0.210359 -0.007058 0.046436 -0.208745 -0.006851 0.047388 -0.208974 -0.006774 0.046339 -0.211966 -0.00692 0.046389 -0.210359 -0.006768 0.047286 -0.210461 0.006689 0.047178 -0.211936 0.006784 0.046339 -0.211966 -0.006774 0.046339 -0.211966 0.005175 0.046114 -0.164753 0.007067 0.046738 -0.171904 0.005285 0.046794 -0.165484 0.00332 0.046126 -0.161881 0.005285 0.046794 -0.165484 0.003463 0.046819 -0.16266 0.00332 0.046126 -0.161881 0.00289 0.0455 -0.161151 0.003103 0.0455 -0.161409 0.00332 0.046126 -0.161881 0.001976 0.046132 -0.160814 0.00274241 0.045816 -0.161229 0.00289 0.0455 -0.161151 0.00332 0.046126 -0.161881 0.00274241 0.045816 -0.161229 0.001976 0.046132 -0.160814 0.00289 0.0455 -0.161151 0.00274241 0.045816 -0.161229 0.003463 0.046819 -0.16266 0.002139 0.04683 -0.161613 0.001976 0.046132 -0.160814 0.000539004 0.04684 -0.16116 0.000355004 0.046138 -0.160347 0.002139 0.04683 -0.161613 -0.00247 0.046857 -0.162563 -0.002695 0.046147 -0.161743 0.000539004 0.04684 -0.16116 -0.004628 0.046155 -0.164618 -0.00247 0.046857 -0.162563 -0.004375 0.04687 -0.165428 -0.006265 0.046882 -0.172025 -0.006553 0.046164 -0.171254 -0.004375 0.04687 -0.165428 -0.007022 0.046871 -0.178806 -0.007325 0.046161 -0.178096 -0.006265 0.046882 -0.172025 -0.007887 0.0455 -0.180602 -0.007325 0.046161 -0.178096 -0.007849 0.046147 -0.184936 0.006784 0.046339 -0.211966 0.006689 0.047178 -0.211936 0.008055 0.046462 -0.198561 0.008055 0.046462 -0.198561 0.007854 0.047555 -0.199136 0.00818 0.046603 -0.185194 0.00818 0.046603 -0.185194 0.008007 0.047907 -0.18642 0.007067 0.046738 -0.171904 -0.007313 0.046522 -0.205499 -0.007527 0.046597 -0.202228 -0.007137 0.047743 -0.202923 -0.007463 0.046006 -0.2053 -0.007719 0.046041 -0.201937 -0.007527 0.046597 -0.202228 -0.007058 0.046436 -0.208745 -0.007313 0.046522 -0.205499 -0.007006 0.047576 -0.205969 -0.007463 0.046006 -0.2053 -0.007698 0.0455 -0.204172 -0.007719 0.046041 -0.201937 -0.006851 0.047388 -0.208974 -0.007058 0.046436 -0.208745 -0.007006 0.047576 -0.205969 -0.006768 0.047286 -0.210461 -0.00692 0.046389 -0.210359 -0.006851 0.047388 -0.208974 -0.00668 0.047178 -0.211936 -0.006774 0.046339 -0.211966 -0.006768 0.047286 -0.210461 0.006689 0.047178 -0.211936 -0.006774 0.046339 -0.211966 -0.00668 0.047178 -0.211936 0.007067 0.046738 -0.171904 0.007018 0.048197 -0.173778 0.005285 0.046794 -0.165484 0.003463 0.046819 -0.16266 0.005285 0.046794 -0.165484 0.003464 0.051719 -0.17186 0.00332 0.046126 -0.161881 0.003463 0.046819 -0.16266 0.001976 0.046132 -0.160814 0.002139 0.04683 -0.161613 0.003463 0.046819 -0.16266 0.002361 0.051749 -0.171009 0.000539004 0.04684 -0.16116 0.002139 0.04683 -0.161613 0.001021 0.051774 -0.17066 -0.00247 0.046857 -0.162563 0.000539004 0.04684 -0.16116 -0.001497 0.051808 -0.171922 -0.004375 0.04687 -0.165428 -0.00247 0.046857 -0.162563 -0.003079 0.051821 -0.174412 -0.005697 0.048441 -0.17414 -0.006265 0.046882 -0.172025 -0.004375 0.04687 -0.165428 -0.005697 0.048441 -0.17414 -0.007022 0.046871 -0.178806 -0.006265 0.046882 -0.172025 -0.007849 0.046147 -0.184936 -0.007325 0.046161 -0.178096 -0.007022 0.046871 -0.178806 -0.007849 0.046147 -0.184936 -0.008116 0.0455 -0.184449 -0.007887 0.0455 -0.180602 0.006689 0.047178 -0.211936 0.007854 0.047555 -0.199136 0.008055 0.046462 -0.198561 0.007854 0.047555 -0.199136 0.008007 0.047907 -0.18642 0.00818 0.046603 -0.185194 0.008007 0.047907 -0.18642 0.007018 0.048197 -0.173778 0.007067 0.046738 -0.171904 -0.007527 0.046597 -0.202228 -0.005907 0.051631 -0.203297 -0.007137 0.047743 -0.202923 -0.007006 0.047576 -0.205969 -0.007313 0.046522 -0.205499 -0.007137 0.047743 -0.202923 -0.007527 0.046597 -0.202228 -0.007719 0.046041 -0.201937 -0.007688 0.046663 -0.198933 -0.007698 0.0455 -0.204172 -0.007881000000000001 0.0455 -0.20169 -0.007719 0.046041 -0.201937 -0.006851 0.047388 -0.208974 -0.007006 0.047576 -0.205969 -0.0067 0.048643 -0.206511 -0.006768 0.047286 -0.210461 -0.006851 0.047388 -0.208974 -0.006643 0.048346 -0.209237 -0.00668 0.047178 -0.211936 -0.006768 0.047286 -0.210461 -0.006614 0.048185 -0.210579 0.006594 0.048017 -0.211907 0.006689 0.047178 -0.211936 -0.00668 0.047178 -0.211936 0.007018 0.048197 -0.173778 0.003464 0.051719 -0.17186 0.005285 0.046794 -0.165484 0.002361 0.051749 -0.171009 0.003463 0.046819 -0.16266 0.003464 0.051719 -0.17186 0.001021 0.051774 -0.17066 0.002139 0.04683 -0.161613 0.002361 0.051749 -0.171009 -0.001497 0.051808 -0.171922 0.000539004 0.04684 -0.16116 0.001021 0.051774 -0.17066 -0.003079 0.051821 -0.174412 -0.00247 0.046857 -0.162563 -0.001497 0.051808 -0.171922 -0.003079 0.051821 -0.174412 -0.005148 0.050096 -0.176876 -0.004375 0.04687 -0.165428 -0.005148 0.050096 -0.176876 -0.005697 0.048441 -0.17414 -0.004375 0.04687 -0.165428 -0.006417 0.048397 -0.180688 -0.007022 0.046871 -0.178806 -0.005697 0.048441 -0.17414 -0.007549 0.046834 -0.185563 -0.007849 0.046147 -0.184936 -0.007022 0.046871 -0.178806 -0.008238000000000001 0.0455 -0.186491 -0.008116 0.0455 -0.184449 -0.007849 0.046147 -0.184936 0.006689 0.047178 -0.211936 0.006594 0.048017 -0.211907 0.007854 0.047555 -0.199136 0.007854 0.047555 -0.199136 0.007566 0.048734 -0.199968 0.008007 0.047907 -0.18642 0.008007 0.047907 -0.18642 0.00768 0.049338 -0.188129 0.007018 0.048197 -0.173778 -0.006747 0.048911 -0.203733 -0.007137 0.047743 -0.202923 -0.005907 0.051631 -0.203297 -0.007527 0.046597 -0.202228 -0.007688 0.046663 -0.198933 -0.005907 0.051631 -0.203297 -0.007006 0.047576 -0.205969 -0.007137 0.047743 -0.202923 -0.006747 0.048911 -0.203733 -0.007719 0.046041 -0.201937 -0.007913999999999999 0.046071 -0.198559 -0.007688 0.046663 -0.198933 -0.007719 0.046041 -0.201937 -0.007881000000000001 0.0455 -0.20169 -0.008132 0.0455 -0.198288 -0.0067 0.048643 -0.206511 -0.007006 0.047576 -0.205969 -0.006747 0.048911 -0.203733 -0.006643 0.048346 -0.209237 -0.006851 0.047388 -0.208974 -0.0067 0.048643 -0.206511 -0.006614 0.048185 -0.210579 -0.006768 0.047286 -0.210461 -0.006643 0.048346 -0.209237 -0.006585 0.048017 -0.211907 -0.00668 0.047178 -0.211936 -0.006614 0.048185 -0.210579 0.006594 0.048017 -0.211907 -0.00668 0.047178 -0.211936 -0.006585 0.048017 -0.211907 0.004966 0.051645 -0.174173 0.003464 0.051719 -0.17186 0.007018 0.048197 -0.173778 0.002361 0.051749 -0.171009 0.003464 0.051719 -0.17186 0.001021 0.051774 -0.17066 0.001021 0.051774 -0.17066 -0.000809997 0.060018 -0.198243 -0.001497 0.051808 -0.171922 -0.003079 0.051821 -0.174412 -0.001497 0.051808 -0.171922 -0.001526 0.059974 -0.199196 -0.004628 0.051775 -0.180071 -0.005148 0.050096 -0.176876 -0.003079 0.051821 -0.174412 -0.005148 0.050096 -0.176876 -0.006417 0.048397 -0.180688 -0.005697 0.048441 -0.17414 -0.006417 0.048397 -0.180688 -0.007549 0.046834 -0.185563 -0.007022 0.046871 -0.178806 -0.008064 0.046117 -0.191763 -0.007849 0.046147 -0.184936 -0.007549 0.046834 -0.185563 -0.008238000000000001 0.0455 -0.186491 -0.007849 0.046147 -0.184936 -0.008064 0.046117 -0.191763 0.006594 0.048017 -0.211907 0.007566 0.048734 -0.199968 0.007854 0.047555 -0.199136 0.007566 0.048734 -0.199968 0.00768 0.049338 -0.188129 0.008007 0.047907 -0.18642 0.007018 0.048197 -0.173778 0.00768 0.049338 -0.188129 0.006779 0.049792 -0.176341 -0.006747 0.048911 -0.203733 -0.005907 0.051631 -0.203297 -0.00637 0.050075 -0.204616 -0.005907 0.051631 -0.203297 -0.007688 0.046663 -0.198933 -0.00723 0.048129 -0.193561 -0.007688 0.046663 -0.198933 -0.007913999999999999 0.046071 -0.198559 -0.007789 0.046765 -0.192279 -0.007719 0.046041 -0.201937 -0.008132 0.0455 -0.198288 -0.007913999999999999 0.046071 -0.198559 -0.0067 0.048643 -0.206511 -0.006747 0.048911 -0.203733 -0.00637 0.050075 -0.204616 -0.006643 0.048346 -0.209237 -0.0067 0.048643 -0.206511 -0.006403 0.049708 -0.207099 -0.006614 0.048185 -0.210579 -0.006643 0.048346 -0.209237 -0.006439 0.049301 -0.20952 -0.006585 0.048017 -0.211907 -0.006614 0.048185 -0.210579 -0.006462 0.049083 -0.210707 0.0065 0.048856 -0.211878 0.006594 0.048017 -0.211907 -0.006585 0.048017 -0.211907 0.006779 0.049792 -0.176341 0.004966 0.051645 -0.174173 0.007018 0.048197 -0.173778 0.003464 0.051719 -0.17186 0.004966 0.051645 -0.174173 0.000826003 0.060006 -0.197849 0.003464 0.051719 -0.17186 0.000260003 0.06002 -0.197738 0.001021 0.051774 -0.17066 -0.001497 0.051808 -0.171922 -0.000809997 0.060018 -0.198243 -0.001526 0.059974 -0.199196 -0.000809997 0.060018 -0.198243 0.001021 0.051774 -0.17066 0.000260003 0.06002 -0.197738 -0.002348 0.059751 -0.201315 -0.003079 0.051821 -0.174412 -0.001526 0.059974 -0.199196 -0.002348 0.059751 -0.201315 -0.004628 0.051775 -0.180071 -0.003079 0.051821 -0.174412 -0.004628 0.051775 -0.180071 -0.005826 0.050002 -0.183062 -0.005148 0.050096 -0.176876 -0.005826 0.050002 -0.183062 -0.006417 0.048397 -0.180688 -0.005148 0.050096 -0.176876 -0.006945 0.048295 -0.187168 -0.007549 0.046834 -0.185563 -0.006417 0.048397 -0.180688 -0.007789 0.046765 -0.192279 -0.008064 0.046117 -0.191763 -0.007549 0.046834 -0.185563 -0.008064 0.046117 -0.191763 -0.008311000000000001 0.0455 -0.191347 -0.008238000000000001 0.0455 -0.186491 0.006594 0.048017 -0.211907 0.0065 0.048856 -0.211878 0.007566 0.048734 -0.199968 0.007566 0.048734 -0.199968 0.007216 0.049958 -0.20099 0.00768 0.049338 -0.188129 0.006779 0.049792 -0.176341 0.00768 0.049338 -0.188129 0.00724 0.05083 -0.190196 -0.006015 0.051216 -0.205534 -0.00637 0.050075 -0.204616 -0.005907 0.051631 -0.203297 -0.007789 0.046765 -0.192279 -0.00723 0.048129 -0.193561 -0.007688 0.046663 -0.198933 -0.00723 0.048129 -0.193561 -0.005177 0.053637 -0.200504 -0.005907 0.051631 -0.203297 -0.007913999999999999 0.046071 -0.198559 -0.008064 0.046117 -0.191763 -0.007789 0.046765 -0.192279 -0.007913999999999999 0.046071 -0.198559 -0.008133 0.0455 -0.198247 -0.008132 0.0455 -0.198288 -0.006403 0.049708 -0.207099 -0.0067 0.048643 -0.206511 -0.00637 0.050075 -0.204616 -0.006439 0.049301 -0.20952 -0.006643 0.048346 -0.209237 -0.006403 0.049708 -0.207099 -0.006462 0.049083 -0.210707 -0.006614 0.048185 -0.210579 -0.006439 0.049301 -0.20952 -0.00649 0.048856 -0.211878 -0.006585 0.048017 -0.211907 -0.006462 0.049083 -0.210707 0.0065 0.048856 -0.211878 -0.006585 0.048017 -0.211907 -0.00649 0.048856 -0.211878 0.006391 0.051443 -0.179421 0.004966 0.051645 -0.174173 0.006779 0.049792 -0.176341 0.000826003 0.060006 -0.197849 0.004966 0.051645 -0.174173 0.001305 0.059981 -0.198144 0.000260003 0.06002 -0.197738 0.003464 0.051719 -0.17186 0.000826003 0.060006 -0.197849 -0.001526 0.059974 -0.199196 -0.000809997 0.060018 -0.198243 -0.000722997 0.061428 -0.205101 -0.000809997 0.060018 -0.198243 0.000260003 0.06002 -0.197738 -3.59977e-05 0.061442 -0.204842 -0.002348 0.059751 -0.201315 -0.001526 0.059974 -0.199196 -0.001232 0.061373 -0.205581 -0.002348 0.059751 -0.201315 -0.002846 0.059333 -0.203396 -0.004628 0.051775 -0.180071 -0.004628 0.051775 -0.180071 -0.00526 0.051624 -0.185793 -0.00533186 0.0509422 -0.182932 -0.00526 0.051624 -0.185793 -0.005826 0.050002 -0.183062 -0.00533186 0.0509422 -0.182932 -0.005826 0.050002 -0.183062 -0.004628 0.051775 -0.180071 -0.00533186 0.0509422 -0.182932 -0.005826 0.050002 -0.183062 -0.006945 0.048295 -0.187168 -0.006417 0.048397 -0.180688 -0.006945 0.048295 -0.187168 -0.007789 0.046765 -0.192279 -0.007549 0.046834 -0.185563 -0.008326999999999999 0.0455 -0.192391 -0.008311000000000001 0.0455 -0.191347 -0.008064 0.046117 -0.191763 0.0065 0.048856 -0.211878 0.006398 0.049694 -0.211849 0.007566 0.048734 -0.199968 0.006398 0.049694 -0.211849 0.007216 0.049958 -0.20099 0.007566 0.048734 -0.199968 0.007216 0.049958 -0.20099 0.00724 0.05083 -0.190196 0.00768 0.049338 -0.188129 0.006779 0.049792 -0.176341 0.00724 0.05083 -0.190196 0.006391 0.051443 -0.179421 -0.00577645 0.0520142 -0.204416 -0.005907 0.051631 -0.203297 -0.005527 0.052809 -0.204533 -0.00577645 0.0520142 -0.204416 -0.005527 0.052809 -0.204533 -0.006015 0.051216 -0.205534 -0.00577645 0.0520142 -0.204416 -0.006015 0.051216 -0.205534 -0.005907 0.051631 -0.203297 -0.006403 0.049708 -0.207099 -0.00637 0.050075 -0.204616 -0.006015 0.051216 -0.205534 -0.00723 0.048129 -0.193561 -0.007789 0.046765 -0.192279 -0.006945 0.048295 -0.187168 -0.005527 0.052809 -0.204533 -0.005907 0.051631 -0.203297 -0.005177 0.053637 -0.200504 -0.005177 0.053637 -0.200504 -0.00723 0.048129 -0.193561 -0.006349 0.04982 -0.189146 -0.007913999999999999 0.046071 -0.198559 -0.008326999999999999 0.0455 -0.192391 -0.008064 0.046117 -0.191763 -0.007913999999999999 0.046071 -0.198559 -0.008133 0.0455 -0.198247 -0.008324349999999999 0.0455 -0.192471 -0.007913999999999999 0.046071 -0.198559 -0.008326999999999999 0.0455 -0.192391 -0.008324349999999999 0.0455 -0.192471 -0.006439 0.049301 -0.20952 -0.006403 0.049708 -0.207099 -0.006123 0.050755 -0.207706 -0.006462 0.049083 -0.210707 -0.006439 0.049301 -0.20952 -0.006244 0.050248 -0.209812 -0.00649 0.048856 -0.211878 -0.006462 0.049083 -0.210707 -0.006313 0.049977 -0.210839 0.006398 0.049694 -0.211849 0.0065 0.048856 -0.211878 -0.00649 0.048856 -0.211878 0.001305 0.059981 -0.198144 0.004966 0.051645 -0.174173 0.006391 0.051443 -0.179421 0.000826003 0.060006 -0.197849 0.001305 0.059981 -0.198144 0.000643003 0.061415 -0.205032 0.000260003 0.06002 -0.197738 0.000826003 0.060006 -0.197849 0.000325003 0.061433 -0.204892 -0.000722997 0.061428 -0.205101 -0.000809997 0.060018 -0.198243 -3.59977e-05 0.061442 -0.204842 -0.001526 0.059974 -0.199196 -0.000722997 0.061428 -0.205101 -0.001232 0.061373 -0.205581 -3.59977e-05 0.061442 -0.204842 0.000260003 0.06002 -0.197738 0.000325003 0.061433 -0.204892 -0.002348 0.059751 -0.201315 -0.001232 0.061373 -0.205581 -0.00194 0.061133 -0.20664 -0.00194 0.061133 -0.20664 -0.002846 0.059333 -0.203396 -0.002348 0.059751 -0.201315 -0.002846 0.059333 -0.203396 -0.00526 0.051624 -0.185793 -0.004628 0.051775 -0.180071 -0.00526 0.051624 -0.185793 -0.006349 0.04982 -0.189146 -0.005826 0.050002 -0.183062 -0.006349 0.04982 -0.189146 -0.006945 0.048295 -0.187168 -0.005826 0.050002 -0.183062 0.006398 0.049694 -0.211849 0.006296 0.050532 -0.211819 0.007216 0.049958 -0.20099 0.00724 0.05083 -0.190196 0.007216 0.049958 -0.20099 0.006828 0.051191 -0.20214 0.00724 0.05083 -0.190196 0.00672 0.052327 -0.192509 0.006391 0.051443 -0.179421 -0.005527 0.052809 -0.204533 -0.005691 0.052317 -0.206455 -0.00577448 0.0520135 -0.205494 -0.005691 0.052317 -0.206455 -0.006015 0.051216 -0.205534 -0.00577448 0.0520135 -0.205494 -0.006015 0.051216 -0.205534 -0.005527 0.052809 -0.204533 -0.00577448 0.0520135 -0.205494 -0.006123 0.050755 -0.207706 -0.006403 0.049708 -0.207099 -0.006015 0.051216 -0.205534 -0.006349 0.04982 -0.189146 -0.00723 0.048129 -0.193561 -0.006945 0.048295 -0.187168 -0.005177 0.053637 -0.200504 -0.004422 0.055972 -0.204091 -0.005527 0.052809 -0.204533 -0.005775 0.051353 -0.191386 -0.005177 0.053637 -0.200504 -0.006349 0.04982 -0.189146 -0.006244 0.050248 -0.209812 -0.006439 0.049301 -0.20952 -0.006123 0.050755 -0.207706 -0.006313 0.049977 -0.210839 -0.006462 0.049083 -0.210707 -0.006244 0.050248 -0.209812 -0.006389 0.049694 -0.211849 -0.00649 0.048856 -0.211878 -0.006313 0.049977 -0.210839 0.006398 0.049694 -0.211849 -0.00649 0.048856 -0.211878 -0.006389 0.049694 -0.211849 0.001305 0.059981 -0.198144 0.006391 0.051443 -0.179421 0.002006 0.059901 -0.198958 0.001305 0.059981 -0.198144 0.001154 0.061348 -0.205423 0.000643003 0.061415 -0.205032 0.000325003 0.061433 -0.204892 0.000826003 0.060006 -0.197849 0.000643003 0.061415 -0.205032 -0.000722997 0.061428 -0.205101 -3.59977e-05 0.061442 -0.204842 0.000380002 0.06293600000000001 -0.211386 -0.001232 0.061373 -0.205581 -0.000722997 0.061428 -0.205101 0.000192002 0.062968 -0.211385 -3.59977e-05 0.061442 -0.204842 0.000325003 0.061433 -0.204892 0.000755002 0.062872 -0.211388 -0.00194 0.061133 -0.20664 -0.001232 0.061373 -0.205581 5.00208e-06 0.063 -0.211384 -0.00194 0.061133 -0.20664 -0.00248 0.060709 -0.207675 -0.002846 0.059333 -0.203396 -0.00526 0.051624 -0.185793 -0.002846 0.059333 -0.203396 -0.00393 0.056761 -0.201101 -0.005775 0.051353 -0.191386 -0.006349 0.04982 -0.189146 -0.00526 0.051624 -0.185793 0.006296 0.050532 -0.211819 0.006398 0.049694 -0.211849 -0.006389 0.049694 -0.211849 0.006296 0.050532 -0.211819 0.006828 0.051191 -0.20214 0.007216 0.049958 -0.20099 0.006828 0.051191 -0.20214 0.00672 0.052327 -0.192509 0.00724 0.05083 -0.190196 0.006391 0.051443 -0.179421 0.00672 0.052327 -0.192509 0.002006 0.059901 -0.198958 -0.005527 0.052809 -0.204533 -0.004902 0.05495 -0.206883 -0.005691 0.052317 -0.206455 -0.006015 0.051216 -0.205534 -0.005691 0.052317 -0.206455 -0.006123 0.050755 -0.207706 -0.004422 0.055972 -0.204091 -0.005177 0.053637 -0.200504 -0.00393 0.056761 -0.201101 -0.004902 0.05495 -0.206883 -0.005527 0.052809 -0.204533 -0.004422 0.055972 -0.204091 -0.005236 0.052848 -0.193788 -0.005177 0.053637 -0.200504 -0.005775 0.051353 -0.191386 -0.006244 0.050248 -0.209812 -0.006123 0.050755 -0.207706 -0.005864 0.051774 -0.208312 -0.006313 0.049977 -0.210839 -0.006244 0.050248 -0.209812 -0.00606 0.051179 -0.210101 -0.006389 0.049694 -0.211849 -0.006313 0.049977 -0.210839 -0.00617 0.050862 -0.210969 0.001305 0.059981 -0.198144 0.002006 0.059901 -0.198958 0.001154 0.061348 -0.205423 0.000643003 0.061415 -0.205032 0.001154 0.061348 -0.205423 0.001498 0.062682 -0.211395 0.000325003 0.061433 -0.204892 0.000643003 0.061415 -0.205032 0.001305 0.062779 -0.211392 0.000380002 0.06293600000000001 -0.211386 -3.59977e-05 0.061442 -0.204842 0.000755002 0.062872 -0.211388 0.000192002 0.062968 -0.211385 -0.000722997 0.061428 -0.205101 0.000380002 0.06293600000000001 -0.211386 5.00208e-06 0.063 -0.211384 -0.001232 0.061373 -0.205581 0.000192002 0.062968 -0.211385 0.000755002 0.062872 -0.211388 0.000325003 0.061433 -0.204892 0.001305 0.062779 -0.211392 -0.000370998 0.06293600000000001 -0.211386 -0.00194 0.061133 -0.20664 5.00208e-06 0.063 -0.211384 -0.00248 0.060709 -0.207675 -0.00194 0.061133 -0.20664 -0.000370998 0.06293600000000001 -0.211386 -0.00248 0.060709 -0.207675 -0.003364 0.058702 -0.205361 -0.002846 0.059333 -0.203396 -0.003364 0.058702 -0.205361 -0.00393 0.056761 -0.201101 -0.002846 0.059333 -0.203396 -0.00393 0.056761 -0.201101 -0.004744 0.054266 -0.196261 -0.00526 0.051624 -0.185793 -0.005236 0.052848 -0.193788 -0.005775 0.051353 -0.191386 -0.00526 0.051624 -0.185793 0.006296 0.050532 -0.211819 -0.006389 0.049694 -0.211849 -0.006287 0.050532 -0.211819 0.006296 0.050532 -0.211819 0.006092 0.052208 -0.211761 0.006828 0.051191 -0.20214 0.006828 0.051191 -0.20214 0.006423 0.052404 -0.203362 0.00672 0.052327 -0.192509 0.002854 0.059619 -0.200787 0.002006 0.059901 -0.198958 0.00672 0.052327 -0.192509 -0.005155 0.054352 -0.208195 -0.005691 0.052317 -0.206455 -0.004902 0.05495 -0.206883 -0.005864 0.051774 -0.208312 -0.006123 0.050755 -0.207706 -0.005691 0.052317 -0.206455 -0.003364 0.058702 -0.205361 -0.004422 0.055972 -0.204091 -0.00393 0.056761 -0.201101 -0.004744 0.054266 -0.196261 -0.00393 0.056761 -0.201101 -0.005177 0.053637 -0.200504 -0.003909 0.057846 -0.207193 -0.004902 0.05495 -0.206883 -0.004422 0.055972 -0.204091 -0.005236 0.052848 -0.193788 -0.004744 0.054266 -0.196261 -0.005177 0.053637 -0.200504 -0.00606 0.051179 -0.210101 -0.006244 0.050248 -0.209812 -0.005864 0.051774 -0.208312 -0.00617 0.050862 -0.210969 -0.006313 0.049977 -0.210839 -0.00606 0.051179 -0.210101 -0.006287 0.050532 -0.211819 -0.006389 0.049694 -0.211849 -0.00617 0.050862 -0.210969 0.001154 0.061348 -0.205423 0.002006 0.059901 -0.198958 0.001922 0.061093 -0.206303 0.001154 0.061348 -0.205423 0.002432 0.062215 -0.211411 0.001498 0.062682 -0.211395 0.000643003 0.061415 -0.205032 0.001498 0.062682 -0.211395 0.001305 0.062779 -0.211392 0.000755002 0.062872 -0.211388 0.000380002 0.06293600000000001 -0.211386 -0.000370998 0.06293600000000001 -0.211386 0.000380002 0.06293600000000001 -0.211386 0.000192002 0.062968 -0.211385 5.00208e-06 0.063 -0.211384 -0.000745998 0.062872 -0.211388 0.000755002 0.062872 -0.211388 0.001305 0.062779 -0.211392 0.000380002 0.06293600000000001 -0.211386 5.00208e-06 0.063 -0.211384 -0.000370998 0.06293600000000001 -0.211386 -0.000745998 0.062872 -0.211388 -0.00248 0.060709 -0.207675 -0.000370998 0.06293600000000001 -0.211386 -0.00248 0.060709 -0.207675 -0.003043 0.060087 -0.208643 -0.003364 0.058702 -0.205361 -0.00526 0.051624 -0.185793 -0.004744 0.054266 -0.196261 -0.005236 0.052848 -0.193788 0.006092 0.052208 -0.211761 0.006296 0.050532 -0.211819 -0.006287 0.050532 -0.211819 0.006092 0.052208 -0.211761 0.006423 0.052404 -0.203362 0.006828 0.051191 -0.20214 0.00672 0.052327 -0.192509 0.006423 0.052404 -0.203362 0.006155 0.05378 -0.194963 0.002006 0.059901 -0.198958 0.002854 0.059619 -0.200787 0.001922 0.061093 -0.206303 0.002854 0.059619 -0.200787 0.00672 0.052327 -0.192509 0.006155 0.05378 -0.194963 -0.004478 0.056754 -0.208874 -0.005155 0.054352 -0.208195 -0.004902 0.05495 -0.206883 -0.005864 0.051774 -0.208312 -0.005691 0.052317 -0.206455 -0.005155 0.054352 -0.208195 -0.003909 0.057846 -0.207193 -0.004422 0.055972 -0.204091 -0.003364 0.058702 -0.205361 -0.004478 0.056754 -0.208874 -0.004902 0.05495 -0.206883 -0.003909 0.057846 -0.207193 -0.00606 0.051179 -0.210101 -0.005864 0.051774 -0.208312 -0.005429 0.053695 -0.209446 -0.00617 0.050862 -0.210969 -0.00606 0.051179 -0.210101 -0.005735 0.05298 -0.210636 -0.006287 0.050532 -0.211819 -0.00617 0.050862 -0.210969 -0.005903 0.052601 -0.211207 0.001154 0.061348 -0.205423 0.001922 0.061093 -0.206303 0.002432 0.062215 -0.211411 0.002432 0.062215 -0.211411 -0.002423 0.062215 -0.211411 0.001498 0.062682 -0.211395 -0.002423 0.062215 -0.211411 0.001305 0.062779 -0.211392 0.001498 0.062682 -0.211395 0.000755002 0.062872 -0.211388 -0.000370998 0.06293600000000001 -0.211386 -0.000745998 0.062872 -0.211388 -0.001295 0.062779 -0.211392 -0.000745998 0.062872 -0.211388 0.001305 0.062779 -0.211392 -0.00248 0.060709 -0.207675 -0.000745998 0.062872 -0.211388 -0.003043 0.060087 -0.208643 -0.003043 0.060087 -0.208643 -0.003909 0.057846 -0.207193 -0.003364 0.058702 -0.205361 0.006092 0.052208 -0.211761 -0.006287 0.050532 -0.211819 -0.006083 0.052208 -0.211761 0.006092 0.052208 -0.211761 0.005878 0.053883 -0.211702 0.006423 0.052404 -0.203362 0.006423 0.052404 -0.203362 0.005633 0.054673 -0.205832 0.006155 0.05378 -0.194963 0.001922 0.061093 -0.206303 0.002854 0.059619 -0.200787 0.003232 0.060051 -0.208075 0.005002 0.056411 -0.199929 0.002854 0.059619 -0.200787 0.006155 0.05378 -0.194963 -0.004784 0.056121 -0.209651 -0.005155 0.054352 -0.208195 -0.004478 0.056754 -0.208874 -0.005429 0.053695 -0.209446 -0.005864 0.051774 -0.208312 -0.005155 0.054352 -0.208195 -0.003633 0.059259 -0.209536 -0.004478 0.056754 -0.208874 -0.003909 0.057846 -0.207193 -0.005735 0.05298 -0.210636 -0.00606 0.051179 -0.210101 -0.005429 0.053695 -0.209446 -0.005903 0.052601 -0.211207 -0.00617 0.050862 -0.210969 -0.005735 0.05298 -0.210636 -0.005903 0.052601 -0.211207 -0.006083 0.052208 -0.211761 -0.006287 0.050532 -0.211819 0.001922 0.061093 -0.206303 0.002888 0.061795 -0.211426 0.002432 0.062215 -0.211411 -0.002423 0.062215 -0.211411 0.002432 0.062215 -0.211411 -0.002879 0.061795 -0.211426 -0.001295 0.062779 -0.211392 0.001305 0.062779 -0.211392 -0.002423 0.062215 -0.211411 -0.001295 0.062779 -0.211392 -0.003043 0.060087 -0.208643 -0.000745998 0.062872 -0.211388 -0.003633 0.059259 -0.209536 -0.003909 0.057846 -0.207193 -0.003043 0.060087 -0.208643 0.005878 0.053883 -0.211702 0.006092 0.052208 -0.211761 -0.006083 0.052208 -0.211761 0.006423 0.052404 -0.203362 0.005878 0.053883 -0.211702 0.005633 0.054673 -0.205832 0.006155 0.05378 -0.194963 0.005633 0.054673 -0.205832 0.005002 0.056411 -0.199929 0.003232 0.060051 -0.208075 0.002888 0.061795 -0.211426 0.001922 0.061093 -0.206303 0.003978 0.058521 -0.20446 0.003232 0.060051 -0.208075 0.002854 0.059619 -0.200787 0.003978 0.058521 -0.20446 0.002854 0.059619 -0.200787 0.005002 0.056411 -0.199929 -0.004248 0.058222 -0.210342 -0.004784 0.056121 -0.209651 -0.004478 0.056754 -0.208874 -0.005429 0.053695 -0.209446 -0.005155 0.054352 -0.208195 -0.004784 0.056121 -0.209651 -0.004248 0.058222 -0.210342 -0.004478 0.056754 -0.208874 -0.003633 0.059259 -0.209536 -0.005735 0.05298 -0.210636 -0.005429 0.053695 -0.209446 -0.005114 0.05543 -0.210383 -0.005903 0.052601 -0.211207 -0.005735 0.05298 -0.210636 -0.005473 0.054684 -0.211067 -0.005667 0.05429 -0.211391 -0.006083 0.052208 -0.211761 -0.005903 0.052601 -0.211207 0.002432 0.062215 -0.211411 0.002888 0.061795 -0.211426 -0.002879 0.061795 -0.211426 -0.002879 0.061795 -0.211426 -0.004573 0.057627 -0.210708 -0.002423 0.062215 -0.211411 -0.001295 0.062779 -0.211392 -0.002423 0.062215 -0.211411 -0.003633 0.059259 -0.209536 -0.003633 0.059259 -0.209536 -0.003043 0.060087 -0.208643 -0.001295 0.062779 -0.211392 0.005878 0.053883 -0.211702 -0.006083 0.052208 -0.211761 -0.005868 0.053883 -0.211702 0.005633 0.054673 -0.205832 0.005878 0.053883 -0.211702 0.005663 0.055557 -0.211644 0.005633 0.054673 -0.205832 0.004962 0.056629 -0.208069 0.005002 0.056411 -0.199929 0.003232 0.060051 -0.208075 0.003962 0.060806 -0.211461 0.002888 0.061795 -0.211426 0.004481 0.058223 -0.209836 0.003232 0.060051 -0.208075 0.003978 0.058521 -0.20446 0.004962 0.056629 -0.208069 0.003978 0.058521 -0.20446 0.005002 0.056411 -0.199929 -0.004573 0.057627 -0.210708 -0.004784 0.056121 -0.209651 -0.004248 0.058222 -0.210342 -0.005114 0.05543 -0.210383 -0.005429 0.053695 -0.209446 -0.004784 0.056121 -0.209651 -0.004248 0.058222 -0.210342 -0.003633 0.059259 -0.209536 -0.002423 0.062215 -0.211411 -0.005114 0.05543 -0.210383 -0.005473 0.054684 -0.211067 -0.005735 0.05298 -0.210636 -0.005473 0.054684 -0.211067 -0.005667 0.05429 -0.211391 -0.005903 0.052601 -0.211207 -0.005667 0.05429 -0.211391 -0.005868 0.053883 -0.211702 -0.006083 0.052208 -0.211761 -0.002879 0.061795 -0.211426 0.002888 0.061795 -0.211426 -0.00353 0.061195 -0.211447 -0.004573 0.057627 -0.210708 -0.004248 0.058222 -0.210342 -0.002423 0.062215 -0.211411 -0.004913 0.056983 -0.211048 -0.004573 0.057627 -0.210708 -0.002879 0.061795 -0.211426 0.005663 0.055557 -0.211644 0.005878 0.053883 -0.211702 -0.005868 0.053883 -0.211702 0.005663 0.055557 -0.211644 0.004962 0.056629 -0.208069 0.005633 0.054673 -0.205832 0.003962 0.060806 -0.211461 0.003232 0.060051 -0.208075 0.00399025 0.059424 -0.209768 0.003232 0.060051 -0.208075 0.004481 0.058223 -0.209836 0.00399025 0.059424 -0.209768 0.004481 0.058223 -0.209836 0.003962 0.060806 -0.211461 0.00399025 0.059424 -0.209768 0.002888 0.061795 -0.211426 0.003962 0.060806 -0.211461 -0.00353 0.061195 -0.211447 0.004962 0.056629 -0.208069 0.004481 0.058223 -0.209836 0.003978 0.058521 -0.20446 -0.005114 0.05543 -0.210383 -0.004784 0.056121 -0.209651 -0.004573 0.057627 -0.210708 -0.005114 0.05543 -0.210383 -0.004913 0.056983 -0.211048 -0.005473 0.054684 -0.211067 -0.005473 0.054684 -0.211067 -0.005271 0.056293 -0.21136 -0.005667 0.05429 -0.211391 -0.005667 0.05429 -0.211391 -0.005459 0.05593 -0.211506 -0.005868 0.053883 -0.211702 -0.00353 0.061195 -0.211447 -0.004913 0.056983 -0.211048 -0.002879 0.061795 -0.211426 -0.004573 0.057627 -0.210708 -0.004913 0.056983 -0.211048 -0.005114 0.05543 -0.210383 0.005663 0.055557 -0.211644 -0.005868 0.053883 -0.211702 -0.005654 0.055557 -0.211644 0.005551 0.056394 -0.211615 0.004962 0.056629 -0.208069 0.005663 0.055557 -0.211644 0.004149 0.060522 -0.211471 0.003962 0.060806 -0.211461 0.004481 0.058223 -0.209836 -0.00353 0.061195 -0.211447 0.003962 0.060806 -0.211461 -0.003952 0.060806 -0.211461 0.004962 0.056629 -0.208069 0.005551 0.056394 -0.211615 0.0049162 0.0572633 -0.209842 0.005551 0.056394 -0.211615 0.004481 0.058223 -0.209836 0.0049162 0.0572633 -0.209842 0.004481 0.058223 -0.209836 0.004962 0.056629 -0.208069 0.0049162 0.0572633 -0.209842 -0.004913 0.056983 -0.211048 -0.005271 0.056293 -0.21136 -0.005473 0.054684 -0.211067 -0.005667 0.05429 -0.211391 -0.005271 0.056293 -0.21136 -0.005459 0.05593 -0.211506 -0.005868 0.053883 -0.211702 -0.005459 0.05593 -0.211506 -0.005654 0.055557 -0.211644 -0.005271 0.056293 -0.21136 -0.004913 0.056983 -0.211048 -0.00353 0.061195 -0.211447 0.005551 0.056394 -0.211615 0.005663 0.055557 -0.211644 -0.005654 0.055557 -0.211644 0.004682 0.059713 -0.211499 0.004149 0.060522 -0.211471 0.004481 0.058223 -0.209836 0.003962 0.060806 -0.211461 0.004149 0.060522 -0.211471 -0.004139 0.060522 -0.211471 0.003962 0.060806 -0.211461 -0.004139 0.060522 -0.211471 -0.003952 0.060806 -0.211461 -0.00353 0.061195 -0.211447 -0.003952 0.060806 -0.211461 -0.005271 0.056293 -0.21136 0.005439 0.057231 -0.211585 0.004481 0.058223 -0.209836 0.005551 0.056394 -0.211615 -0.005459 0.05593 -0.211506 -0.005271 0.056293 -0.21136 -0.003952 0.060806 -0.211461 -0.005654 0.055557 -0.211644 -0.005459 0.05593 -0.211506 -0.004139 0.060522 -0.211471 0.005551 0.056394 -0.211615 -0.005654 0.055557 -0.211644 -0.005542 0.056394 -0.211615 0.004682 0.059713 -0.211499 0.004481 0.058223 -0.209836 0.005327 0.058068 -0.211556 0.004149 0.060522 -0.211471 0.004682 0.059713 -0.211499 -0.004673 0.059713 -0.211499 0.004149 0.060522 -0.211471 -0.004406 0.060118 -0.211485 -0.004139 0.060522 -0.211471 -0.004139 0.060522 -0.211471 -0.005459 0.05593 -0.211506 -0.003952 0.060806 -0.211461 0.005327 0.058068 -0.211556 0.004481 0.058223 -0.209836 0.005439 0.057231 -0.211585 0.005439 0.057231 -0.211585 0.005551 0.056394 -0.211615 -0.005542 0.056394 -0.211615 -0.005542 0.056394 -0.211615 -0.005654 0.055557 -0.211644 -0.004139 0.060522 -0.211471 0.004682 0.059713 -0.211499 0.005327 0.058068 -0.211556 -0.005206 0.058904 -0.211527 0.004149 0.060522 -0.211471 -0.004673 0.059713 -0.211499 -0.004406 0.060118 -0.211485 0.004682 0.059713 -0.211499 -0.004939 0.059309 -0.211513 -0.004673 0.059713 -0.211499 -0.004406 0.060118 -0.211485 -0.005542 0.056394 -0.211615 -0.004139 0.060522 -0.211471 0.005327 0.058068 -0.211556 0.005439 0.057231 -0.211585 -0.00543 0.057231 -0.211586 0.005439 0.057231 -0.211585 -0.005542 0.056394 -0.211615 -0.00543 0.057231 -0.211586 0.004682 0.059713 -0.211499 -0.005206 0.058904 -0.211527 -0.005073 0.059107 -0.21152 0.005327 0.058068 -0.211556 -0.005318 0.058068 -0.211556 -0.005206 0.058904 -0.211527 -0.004406 0.060118 -0.211485 -0.004673 0.059713 -0.211499 -0.00543 0.057231 -0.211586 0.004682 0.059713 -0.211499 -0.005073 0.059107 -0.21152 -0.004939 0.059309 -0.211513 -0.004673 0.059713 -0.211499 -0.004939 0.059309 -0.211513 -0.005073 0.059107 -0.21152 -0.005542 0.056394 -0.211615 -0.004406 0.060118 -0.211485 -0.00543 0.057231 -0.211586 0.005327 0.058068 -0.211556 -0.00543 0.057231 -0.211586 -0.005318 0.058068 -0.211556 -0.005206 0.058904 -0.211527 -0.005073 0.059107 -0.21152 -0.004673 0.059713 -0.211499 -0.004673 0.059713 -0.211499 -0.005206 0.058904 -0.211527 -0.005318 0.058068 -0.211556 -0.005318 0.058068 -0.211556 -0.00543 0.057231 -0.211586 -0.004673 0.059713 -0.211499 0.000709323 -0.018 -0.255883 0.0037358 -0.018 -0.255404 0.001589 -0.018 -0.258157 -0.000701329 -0.018 -0.255883 3.99658e-06 -0.018 -0.255995 -0.0004916 -0.018 -0.25678 3.99658e-06 -0.018 -0.255995 0.000709323 -0.018 -0.255883 -0.0004916 -0.018 -0.25678 0.001589 -0.018 -0.258157 -0.004719 -0.018 -0.257725 -0.0004916 -0.018 -0.25678 -0.004719 -0.018 -0.257725 -0.00252937 -0.018 -0.255594 -0.0004916 -0.018 -0.25678 -0.00252937 -0.018 -0.255594 -0.000701329 -0.018 -0.255883 -0.0004916 -0.018 -0.25678 0.000709323 -0.018 -0.255883 0.001589 -0.018 -0.258157 -0.0004916 -0.018 -0.25678 -0.010676 -0.018 -0.255608 -0.008449170000000001 -0.018 -0.253966 -0.0071213 -0.018 -0.254643 -0.006485 -0.018 -0.254967 -0.00252937 -0.018 -0.255594 -0.00660269 -0.018 -0.255846 -0.00252937 -0.018 -0.255594 -0.004719 -0.018 -0.257725 -0.00660269 -0.018 -0.255846 -0.004719 -0.018 -0.257725 -0.010676 -0.018 -0.255608 -0.00660269 -0.018 -0.255846 -0.0071213 -0.018 -0.254643 -0.006485 -0.018 -0.254967 -0.00660269 -0.018 -0.255846 -0.010676 -0.018 -0.255608 -0.0071213 -0.018 -0.254643 -0.00660269 -0.018 -0.255846 0.00649389 -0.018 -0.254967 0.0071303 -0.018 -0.254643 0.007779 -0.018 -0.25687 0.0071303 -0.018 -0.254643 0.00988577 -0.018 -0.253239 0.007779 -0.018 -0.25687 0.0037358 -0.018 -0.255404 0.00649389 -0.018 -0.254967 0.00573738 -0.018 -0.255698 0.007779 -0.018 -0.25687 0.001589 -0.018 -0.258157 0.00573738 -0.018 -0.255698 0.001589 -0.018 -0.258157 0.0037358 -0.018 -0.255404 0.00573738 -0.018 -0.255698 0.00649389 -0.018 -0.254967 0.007779 -0.018 -0.25687 0.00573738 -0.018 -0.255698 0.001545 -0.0365 -0.257512 -0.004719 -0.018 -0.257725 0.001589 -0.018 -0.258157 -0.015842 -0.018 -0.251962 -0.0135884 -0.018 -0.250735 -0.012844 -0.018 -0.251479 -0.012339 -0.018 -0.251984 -0.008449170000000001 -0.018 -0.253966 -0.0121456 -0.018 -0.253171 -0.008449170000000001 -0.018 -0.253966 -0.010676 -0.018 -0.255608 -0.0121456 -0.018 -0.253171 -0.010676 -0.018 -0.255608 -0.015842 -0.018 -0.251962 -0.0121456 -0.018 -0.253171 -0.012844 -0.018 -0.251479 -0.012339 -0.018 -0.251984 -0.0121456 -0.018 -0.253171 -0.015842 -0.018 -0.251962 -0.012844 -0.018 -0.251479 -0.0121456 -0.018 -0.253171 -0.004587 -0.0365 -0.257093 -0.010676 -0.018 -0.255608 -0.004719 -0.018 -0.257725 0.00988577 -0.018 -0.253239 0.012348 -0.018 -0.251984 0.013393 -0.018 -0.253962 0.012348 -0.018 -0.251984 0.012853 -0.018 -0.251479 0.013393 -0.018 -0.253962 0.012853 -0.018 -0.251479 0.0154937 -0.018 -0.248838 0.013393 -0.018 -0.253962 0.007779 -0.018 -0.25687 0.00988577 -0.018 -0.253239 0.013393 -0.018 -0.253962 0.007563 -0.0365 -0.256262 0.001589 -0.018 -0.258157 0.007779 -0.018 -0.25687 0.007563 -0.0365 -0.256262 0.001545 -0.0365 -0.257512 0.001589 -0.018 -0.258157 0.001545 -0.0365 -0.257512 -0.004587 -0.0365 -0.257093 -0.004719 -0.018 -0.257725 -0.019832 -0.018 -0.247058 -0.0175653 -0.018 -0.246199 -0.0173092 -0.018 -0.246702 -0.019832 -0.018 -0.247058 -0.0173092 -0.018 -0.246702 -0.016985 -0.018 -0.247338 -0.016985 -0.018 -0.247338 -0.0135884 -0.018 -0.250735 -0.0167102 -0.018 -0.249081 -0.0135884 -0.018 -0.250735 -0.015842 -0.018 -0.251962 -0.0167102 -0.018 -0.249081 -0.015842 -0.018 -0.251962 -0.019832 -0.018 -0.247058 -0.0167102 -0.018 -0.249081 -0.019832 -0.018 -0.247058 -0.016985 -0.018 -0.247338 -0.0167102 -0.018 -0.249081 -0.010379 -0.0365 -0.255034 -0.015842 -0.018 -0.251962 -0.010676 -0.018 -0.255608 -0.004587 -0.0365 -0.257093 -0.010379 -0.0365 -0.255034 -0.010676 -0.018 -0.255608 0.0173181 -0.018 -0.246702 0.0199769 -0.018 -0.241484 0.018013 -0.018 -0.249646 0.013393 -0.018 -0.253962 0.0154937 -0.018 -0.248838 0.018013 -0.018 -0.249646 0.0154937 -0.018 -0.248838 0.016994 -0.018 -0.247338 0.018013 -0.018 -0.249646 0.016994 -0.018 -0.247338 0.0173181 -0.018 -0.246702 0.018013 -0.018 -0.249646 0.022854 -0.018 -0.230886 0.0199769 -0.018 -0.241484 0.0200886 -0.018 -0.240779 0.0209 -0.018 -0.235652 0.022854 -0.018 -0.230886 0.0200886 -0.018 -0.240779 0.018013 -0.018 -0.249646 0.0199769 -0.018 -0.241484 0.022854 -0.018 -0.230886 0.01302 -0.0365 -0.253434 0.007779 -0.018 -0.25687 0.013393 -0.018 -0.253962 0.01302 -0.0365 -0.253434 0.007563 -0.0365 -0.256262 0.007779 -0.018 -0.25687 0.001545 -0.0365 -0.257512 0.007563 -0.0365 -0.256262 0.022218 -0.0365 -0.231 -0.004587 -0.0365 -0.257093 0.001545 -0.0365 -0.257512 0.022218 -0.0365 -0.231 -0.0200797 -0.018 -0.240779 -0.020086 -0.018 -0.240739 -0.02235 -0.018 -0.241259 -0.02235 -0.018 -0.241259 -0.0200797 -0.018 -0.240779 -0.019968 -0.018 -0.241484 -0.019968 -0.018 -0.241484 -0.0175653 -0.018 -0.246199 -0.0199576 -0.018 -0.243899 -0.0175653 -0.018 -0.246199 -0.019832 -0.018 -0.247058 -0.0199576 -0.018 -0.243899 -0.019832 -0.018 -0.247058 -0.02235 -0.018 -0.241259 -0.0199576 -0.018 -0.243899 -0.02235 -0.018 -0.241259 -0.019968 -0.018 -0.241484 -0.0199576 -0.018 -0.243899 -0.019832 -0.018 -0.247058 -0.015842 -0.018 -0.251962 -0.015401 -0.0365 -0.25149 -0.010379 -0.0365 -0.255034 -0.015401 -0.0365 -0.25149 -0.015842 -0.018 -0.251962 -0.010379 -0.0365 -0.255034 -0.004587 -0.0365 -0.257093 0.022218 -0.0365 -0.231 0.021004 -0.018 -0.234995 0.0208896 -0.018 -0.234272 0.022854 -0.018 -0.230886 0.0209 -0.018 -0.235652 0.021004 -0.018 -0.234995 0.022854 -0.018 -0.230886 0.022854 -0.018 -0.230886 0.021298 -0.018 -0.244244 0.018013 -0.018 -0.249646 0.017512 -0.0365 -0.249239 0.013393 -0.018 -0.253962 0.018013 -0.018 -0.249646 0.017512 -0.0365 -0.249239 0.01302 -0.0365 -0.253434 0.013393 -0.018 -0.253962 0.007563 -0.0365 -0.256262 0.01302 -0.0365 -0.253434 0.022218 -0.0365 -0.231 -0.023211 -0.018 -0.234995 -0.0209643 -0.018 -0.234795 -0.020996 -0.018 -0.234995 -0.020996 -0.018 -0.234995 -0.020086 -0.018 -0.240739 -0.0216485 -0.018 -0.238027 -0.020086 -0.018 -0.240739 -0.02235 -0.018 -0.241259 -0.0216485 -0.018 -0.238027 -0.02235 -0.018 -0.241259 -0.023211 -0.018 -0.234995 -0.0216485 -0.018 -0.238027 -0.023211 -0.018 -0.234995 -0.020996 -0.018 -0.234995 -0.0216485 -0.018 -0.238027 -0.02235 -0.018 -0.241259 -0.019832 -0.018 -0.247058 -0.01928 -0.0365 -0.246722 -0.019832 -0.018 -0.247058 -0.015401 -0.0365 -0.25149 -0.01928 -0.0365 -0.246722 -0.015401 -0.0365 -0.25149 -0.010379 -0.0365 -0.255034 0.022218 -0.0365 -0.231 0.0207755 -0.018 -0.233551 0.022854 -0.018 -0.230886 0.0208896 -0.018 -0.234272 0.018013 -0.018 -0.249646 0.021298 -0.018 -0.244244 0.020706 -0.0365 -0.243987 0.022854 -0.018 -0.230886 0.023004 -0.018 -0.238156 0.021298 -0.018 -0.244244 0.018013 -0.018 -0.249646 0.020706 -0.0365 -0.243987 0.017512 -0.0365 -0.249239 0.01302 -0.0365 -0.253434 0.017512 -0.0365 -0.249239 0.022218 -0.0365 -0.231 -0.023211 -0.018 -0.234995 -0.02235 -0.018 -0.241259 -0.021728 -0.0365 -0.241084 -0.0206847 -0.018 -0.23303 -0.0209643 -0.018 -0.234795 -0.021778 -0.018 -0.23294 -0.0209643 -0.018 -0.234795 -0.023211 -0.018 -0.234995 -0.021778 -0.018 -0.23294 -0.023211 -0.018 -0.234995 -0.022845 -0.018 -0.230886 -0.021778 -0.018 -0.23294 -0.022845 -0.018 -0.230886 -0.020345 -0.018 -0.230886 -0.021778 -0.018 -0.23294 -0.020345 -0.018 -0.230886 -0.0206847 -0.018 -0.23303 -0.021778 -0.018 -0.23294 -0.02235 -0.018 -0.241259 -0.01928 -0.0365 -0.246722 -0.021728 -0.0365 -0.241084 -0.01928 -0.0365 -0.246722 -0.015401 -0.0365 -0.25149 0.022218 -0.0365 -0.231 0.0203537 -0.018 -0.230886 0.0202003 -0.018 -0.229917 0.022854 -0.018 -0.230886 0.0202003 -0.018 -0.229917 0.019977 -0.018 -0.228506 0.022854 -0.018 -0.230886 0.019977 -0.018 -0.228506 0.0191898 -0.018 -0.226961 0.022854 -0.018 -0.230886 0.0203885 -0.018 -0.231106 0.0203537 -0.018 -0.230886 0.022854 -0.018 -0.230886 0.0204413 -0.018 -0.23144 0.0203885 -0.018 -0.231106 0.022854 -0.018 -0.230886 0.0204951 -0.018 -0.23178 0.0204413 -0.018 -0.23144 0.022854 -0.018 -0.230886 0.0205521 -0.018 -0.23214 0.0204951 -0.018 -0.23178 0.022854 -0.018 -0.230886 0.020615 -0.018 -0.232537 0.0205521 -0.018 -0.23214 0.022854 -0.018 -0.230886 0.0206874 -0.018 -0.232995 0.020615 -0.018 -0.232537 0.022854 -0.018 -0.230886 0.0206874 -0.018 -0.232995 0.022854 -0.018 -0.230886 0.0207755 -0.018 -0.233551 0.021298 -0.018 -0.244244 0.022364 -0.0365 -0.238068 0.020706 -0.0365 -0.243987 0.022854 -0.018 -0.230886 0.023004 -0.018 -0.231834 0.023004 -0.018 -0.238156 0.021298 -0.018 -0.244244 0.023004 -0.018 -0.238156 0.022364 -0.0365 -0.238068 0.017512 -0.0365 -0.249239 0.020706 -0.0365 -0.243987 0.022218 -0.0365 -0.231 -0.023211 -0.018 -0.234995 -0.021728 -0.0365 -0.241084 -0.022565 -0.0365 -0.234995 -0.022845 -0.018 -0.230886 -0.023211 -0.018 -0.234995 -0.022565 -0.0365 -0.234995 -0.022845 -0.018 -0.230886 -0.0185684 -0.018 -0.225759 -0.019968 -0.018 -0.228506 -0.022845 -0.018 -0.230886 -0.019968 -0.018 -0.228506 -0.020345 -0.018 -0.230886 -0.010355 -0.018 -0.216995 -0.012339 -0.018 -0.218006 -0.0166 -0.018 -0.210364 -0.012339 -0.018 -0.218006 -0.0131204 -0.018 -0.218787 -0.0166 -0.018 -0.210364 -0.0131204 -0.018 -0.218787 -0.016985 -0.018 -0.222652 -0.0166 -0.018 -0.210364 -0.016985 -0.018 -0.222652 -0.0185684 -0.018 -0.225759 -0.0166 -0.018 -0.210364 -0.022845 -0.018 -0.230886 -0.015463 -0.018 -0.189843 -0.0166 -0.018 -0.210364 -0.015463 -0.018 -0.189843 -0.010355 -0.018 -0.195314 -0.0166 -0.018 -0.210364 -0.010355 -0.018 -0.195314 -0.010355 -0.018 -0.216995 -0.0166 -0.018 -0.210364 -0.0185684 -0.018 -0.225759 -0.022845 -0.018 -0.230886 -0.0166 -0.018 -0.210364 -0.021728 -0.0365 -0.241084 -0.01928 -0.0365 -0.246722 0.022218 -0.0365 -0.231 0.022854 -0.018 -0.230886 0.0191898 -0.018 -0.226961 0.018835 -0.018 -0.226265 0.020706 -0.0365 -0.243987 0.022364 -0.0365 -0.238068 0.022218 -0.0365 -0.231 0.023004 -0.018 -0.231834 0.022854 -0.018 -0.230886 0.022218 -0.0365 -0.231 0.023004 -0.018 -0.238156 0.023004 -0.018 -0.231834 0.022364 -0.0365 -0.231922 0.022364 -0.0365 -0.238068 0.023004 -0.018 -0.238156 0.022364 -0.0365 -0.231922 -0.022565 -0.0365 -0.234995 -0.021728 -0.0365 -0.241084 0.022218 -0.0365 -0.231 -0.022845 -0.018 -0.230886 -0.022565 -0.0365 -0.234995 -0.022209 -0.0365 -0.231 -0.022209 -0.0365 -0.231 -0.015463 -0.018 -0.189843 -0.022845 -0.018 -0.230886 -0.010355 -0.018 -0.193092 -0.010355 -0.018 -0.195314 -0.012909 -0.018 -0.191418 -0.010355 -0.018 -0.195314 -0.015463 -0.018 -0.189843 -0.012909 -0.018 -0.191418 -0.015463 -0.018 -0.189843 -0.01486 -0.018 -0.187522 -0.012909 -0.018 -0.191418 -0.01486 -0.018 -0.187522 -0.010355 -0.018 -0.192702 -0.012909 -0.018 -0.191418 -0.010355 -0.018 -0.192702 -0.010355 -0.018 -0.193092 -0.012909 -0.018 -0.191418 0.0178973 -0.018 -0.224425 0.0174398 -0.018 -0.223527 0.022854 -0.018 -0.230886 0.018835 -0.018 -0.226265 0.0178973 -0.018 -0.224425 0.022854 -0.018 -0.230886 0.022364 -0.0365 -0.238068 0.022364 -0.0365 -0.231922 0.022218 -0.0365 -0.231 0.022854 -0.018 -0.230886 0.014836 -0.0365 -0.189957 0.022218 -0.0365 -0.231 0.023004 -0.018 -0.231834 0.022218 -0.0365 -0.231 0.022364 -0.0365 -0.231922 -0.022209 -0.0365 -0.231 -0.022565 -0.0365 -0.234995 0.022218 -0.0365 -0.231 -0.022209 -0.0365 -0.231 -0.014827 -0.0365 -0.189957 -0.015463 -0.018 -0.189843 -0.01486 -0.018 -0.187522 -0.015463 -0.018 -0.189843 -0.014827 -0.0365 -0.189957 -0.010355 -0.018 -0.185748 -0.010355 -0.018 -0.192702 -0.0126075 -0.018 -0.187837 -0.010355 -0.018 -0.192702 -0.01486 -0.018 -0.187522 -0.0126075 -0.018 -0.187837 -0.01486 -0.018 -0.187522 -0.012397 -0.018 -0.182972 -0.0126075 -0.018 -0.187837 -0.012397 -0.018 -0.182972 -0.010355 -0.018 -0.185748 -0.0126075 -0.018 -0.187837 0.010364 -0.018 -0.213909 0.010364 -0.018 -0.210463 0.0157489 -0.018 -0.221229 0.0157489 -0.018 -0.221229 0.010364 -0.018 -0.210463 0.016039 -0.018 -0.221507 0.010364 -0.018 -0.210463 0.016994 -0.018 -0.222652 0.016039 -0.018 -0.221507 0.022854 -0.018 -0.230886 0.016994 -0.018 -0.222652 0.010364 -0.018 -0.210463 0.0174398 -0.018 -0.223527 0.016994 -0.018 -0.222652 0.022854 -0.018 -0.230886 0.015472 -0.018 -0.189843 0.014836 -0.0365 -0.189957 0.022854 -0.018 -0.230886 0.014836 -0.0365 -0.189957 0.013258 -0.0365 -0.185453 0.022218 -0.0365 -0.231 -0.022209 -0.0365 -0.231 0.022218 -0.0365 -0.231 -0.014827 -0.0365 -0.189957 -0.01486 -0.018 -0.187522 -0.014827 -0.0365 -0.189957 -0.014249 -0.0365 -0.187732 -0.012397 -0.018 -0.182972 -0.01486 -0.018 -0.187522 -0.014249 -0.0365 -0.187732 -0.012397 -0.018 -0.182972 -0.010355 -0.018 -0.181092 -0.010355 -0.018 -0.185748 -0.011888 -0.0365 -0.183369 -0.00873785 -0.018824 -0.179642 -0.00932588 -0.0185244 -0.180169 -0.00932588 -0.0185244 -0.180169 -0.010355 -0.018 -0.181092 -0.012397 -0.018 -0.182972 -0.011888 -0.0365 -0.183369 -0.00932588 -0.0185244 -0.180169 -0.012397 -0.018 -0.182972 0.0110984 -0.018 -0.217369 0.010364 -0.018 -0.216525 0.0113634 -0.018 -0.217504 0.010364 -0.018 -0.216525 0.010364 -0.018 -0.213909 0.0113634 -0.018 -0.217504 0.0113634 -0.018 -0.217504 0.010364 -0.018 -0.213909 0.012348 -0.018 -0.218006 0.012348 -0.018 -0.218006 0.010364 -0.018 -0.213909 0.0128268 -0.018 -0.218425 0.0128268 -0.018 -0.218425 0.010364 -0.018 -0.213909 0.0157489 -0.018 -0.221229 0.0108639 -0.0177452 -0.18125 0.010364 -0.018 -0.180877 0.010364 -0.018 -0.191116 0.010364 -0.018 -0.210463 0.010364 -0.018 -0.205869 0.022854 -0.018 -0.230886 0.015472 -0.018 -0.189843 0.013258 -0.0365 -0.185453 0.014836 -0.0365 -0.189957 0.013826 -0.018 -0.185145 0.015472 -0.018 -0.189843 0.022854 -0.018 -0.230886 0.022218 -0.0365 -0.231 0.013258 -0.0365 -0.185453 0.010211 -0.0365 -0.181538 -0.014827 -0.0365 -0.189957 0.022218 -0.0365 -0.231 -0.014249 -0.0365 -0.187732 -0.012397 -0.018 -0.182972 -0.014249 -0.0365 -0.187732 -0.011888 -0.0365 -0.183369 -0.00857368 -0.0189077 -0.179495 -0.00873785 -0.018824 -0.179642 -0.0102318 -0.027662 -0.181431 -0.00873785 -0.018824 -0.179642 -0.011888 -0.0365 -0.183369 -0.0102318 -0.027662 -0.181431 -0.011888 -0.0365 -0.183369 -0.008238000000000001 -0.0365 -0.180009 -0.0102318 -0.027662 -0.181431 -0.008238000000000001 -0.0365 -0.180009 -0.00857368 -0.0189077 -0.179495 -0.0102318 -0.027662 -0.181431 -0.008238000000000001 -0.0365 -0.180009 -0.00439959 -0.0203023 -0.177716 -0.006485 -0.019972 -0.178618 -0.008238000000000001 -0.0365 -0.180009 -0.006485 -0.019972 -0.178618 -0.00857368 -0.0189077 -0.179495 0.010364 -0.018 -0.216995 0.010364 -0.018 -0.216525 0.0110984 -0.018 -0.217369 0.010364 -0.018 -0.205869 0.010364 -0.018 -0.199636 0.022854 -0.018 -0.230886 0.010364 -0.018 -0.199636 0.010364 -0.018 -0.191116 0.022854 -0.018 -0.230886 0.010364 -0.018 -0.180877 0.010649 -0.018 -0.181063 0.010364 -0.018 -0.191116 0.010364 -0.018 -0.191116 0.010649 -0.018 -0.181063 0.022854 -0.018 -0.230886 0.006058 -0.0365 -0.178824 0.010649 -0.018 -0.181063 0.00937989 -0.0185015 -0.180254 0.010649 -0.018 -0.181063 0.010364 -0.018 -0.180877 0.00937989 -0.0185015 -0.180254 0.006058 -0.0365 -0.178824 0.00937989 -0.0185015 -0.180254 0.006494 -0.019972 -0.178429 0.006058 -0.0365 -0.178824 0.006494 -0.019972 -0.178429 0.00628983 -0.0200043 -0.178297 0.015472 -0.018 -0.189843 0.013826 -0.018 -0.185145 0.013258 -0.0365 -0.185453 0.010649 -0.018 -0.181063 0.013826 -0.018 -0.185145 0.022854 -0.018 -0.230886 0.006058 -0.0365 -0.178824 0.022218 -0.0365 -0.231 0.010211 -0.0365 -0.181538 0.013826 -0.018 -0.185145 0.010211 -0.0365 -0.181538 0.013258 -0.0365 -0.185453 -0.014249 -0.0365 -0.187732 0.022218 -0.0365 -0.231 -0.011888 -0.0365 -0.183369 -0.011888 -0.0365 -0.183369 0.022218 -0.0365 -0.231 -0.008238000000000001 -0.0365 -0.180009 -0.008238000000000001 -0.0365 -0.180009 -0.003695 -0.0365 -0.178016 -0.00439959 -0.0203023 -0.177716 -0.003695 -0.0365 -0.178016 -0.00383344 -0.020392 -0.177471 -0.00439959 -0.0203023 -0.177716 -0.003695 -0.0365 -0.178016 0.000513453 -0.0209194 -0.177129 4.5297e-06 -0.021 -0.177174 -0.003695 -0.0365 -0.178016 4.5297e-06 -0.021 -0.177174 -0.00302369 -0.0205203 -0.177408 -0.003695 -0.0365 -0.178016 -0.00302369 -0.0205203 -0.177408 -0.00383344 -0.020392 -0.177471 0.001249 -0.0365 -0.177607 0.006058 -0.0365 -0.178824 0.00574517 -0.0200906 -0.178162 0.006058 -0.0365 -0.178824 0.00628983 -0.0200043 -0.178297 0.00574517 -0.0200906 -0.178162 0.006058 -0.0365 -0.178824 0.010211 -0.0365 -0.181538 0.010649 -0.018 -0.181063 0.013826 -0.018 -0.185145 0.010649 -0.018 -0.181063 0.010211 -0.0365 -0.181538 0.001249 -0.0365 -0.177607 0.022218 -0.0365 -0.231 0.006058 -0.0365 -0.178824 -0.008238000000000001 -0.0365 -0.180009 0.022218 -0.0365 -0.231 -0.003695 -0.0365 -0.178016 -0.003695 -0.0365 -0.178016 0.001249 -0.0365 -0.177607 0.000513453 -0.0209194 -0.177129 0.001249 -0.0365 -0.177607 0.00129399 -0.0207957 -0.17706 0.000513453 -0.0209194 -0.177129 0.001249 -0.0365 -0.177607 0.00574517 -0.0200906 -0.178162 0.00340422 -0.0204614 -0.177583 0.001249 -0.0365 -0.177607 0.00340422 -0.0204614 -0.177583 0.00129399 -0.0207957 -0.17706 -0.003695 -0.0365 -0.178016 0.022218 -0.0365 -0.231 0.001249 -0.0365 -0.177607 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464

    -
    -
    - - - 0 0 0 - 1 0 0 0 - - true - - - -
    - - - - 0.014999 0.0222876 -0.09673899999999998 0.014999 0.021876 -0.09788199999999997 0.014999 0.024129 -0.100963 0.014999 0.022294 -0.104332 0.014999 0.024129 -0.100963 0.014999 0.0224298 -0.100535 0.014999 0.021876 -0.09788199999999997 0.014999 0.021532 -0.09877999999999998 0.014999 0.0224298 -0.100535 0.014999 0.021532 -0.09877999999999998 0.014999 0.0207306 -0.100168 0.014999 0.0224298 -0.100535 0.014999 0.0207306 -0.100168 0.014999 0.022294 -0.104332 0.014999 0.0224298 -0.100535 0.014999 0.024129 -0.100963 0.014999 0.021876 -0.09788199999999997 0.014999 0.0224298 -0.100535 0.014999 0.045 -0.05500499999999997 0.014999 0.0368802 -0.05400919999999997 0.014999 0.036005 -0.05864799999999997 0.014999 0.036005 -0.05864799999999997 0.014999 0.0222876 -0.09673899999999998 0.014999 0.0336438 -0.07748609999999997 0.014999 0.0222876 -0.09673899999999998 0.014999 0.024129 -0.100963 0.014999 0.0336438 -0.07748609999999997 0.014999 0.024129 -0.100963 0.014999 0.045 -0.05500499999999997 0.014999 0.0336438 -0.07748609999999997 0.014999 0.045 -0.05500499999999997 0.014999 0.036005 -0.05864799999999997 0.014999 0.0336438 -0.07748609999999997 0.014999 0.0368802 -0.05400919999999997 0.014999 0.045 -0.05500499999999997 0.014999 0.0406849 -0.05235499999999997 0.014999 0.045 -0.05500499999999997 0.014999 0.045 -0.04970499999999997 0.014999 0.0406849 -0.05235499999999997 0.014999 0.045 -0.04970499999999997 0.014999 0.0363698 -0.04970499999999997 0.014999 0.0406849 -0.05235499999999997 0.014999 0.0363698 -0.04970499999999997 0.014999 0.03693 -0.05374499999999997 0.014999 0.0406849 -0.05235499999999997 0.014999 0.03693 -0.05374499999999997 0.014999 0.0368802 -0.05400919999999997 0.014999 0.0406849 -0.05235499999999997 0.014999 0.045 -0.04970499999999997 0.0155905 0.0338603 -0.04399519999999997 0.0151152 0.0362 -0.04858329999999998 0.014999 0.045 -0.04970499999999997 0.0151152 0.0362 -0.04858329999999998 0.0151123 0.0362142 -0.04861119999999997 0.014999 0.045 -0.04970499999999997 0.0151123 0.0362142 -0.04861119999999997 0.014999 0.0363698 -0.04970499999999997 0.014999 0.045 -0.04970499999999997 0.0155979 0.0337867 -0.04392399999999997 0.0155905 0.0338603 -0.04399519999999997 -0.015001 0.022294 -0.104332 0.014999 0.024129 -0.100963 0.014999 0.022294 -0.104332 0.014999 0.022294 -0.104332 0.014999 0.0207306 -0.100168 0.014999 0.018366 -0.104264 0.014999 0.017354 -0.110032 0.014999 0.022294 -0.104332 0.014999 0.0193315 -0.1051 0.014999 0.018366 -0.104264 0.014999 0.016369 -0.106216 0.014999 0.0193315 -0.1051 0.014999 0.016369 -0.106216 0.014999 0.017354 -0.110032 0.014999 0.0193315 -0.1051 0.014999 0.022294 -0.104332 0.014999 0.018366 -0.104264 0.014999 0.0193315 -0.1051 0.014999 0.045 -0.05500499999999997 0.014999 0.024129 -0.100963 -0.015001 0.045 -0.05500499999999997 -0.015001 0.045 -0.05500499999999997 0.014999 0.045 -0.04970499999999997 0.014999 0.045 -0.05500499999999997 0.0156022 0.0337438 -0.04388249999999997 0.0155979 0.0337867 -0.04392399999999997 0.014999 0.045 -0.04970499999999997 0.0159634 0.0301408 -0.04039569999999997 0.0156022 0.0337438 -0.04388249999999997 0.014999 0.045 -0.04970499999999997 0.017307 0.023 -0.02742499999999997 0.0159749 0.0299034 -0.04028399999999997 0.0159634 0.0301408 -0.04039569999999997 0.017307 0.023 -0.02742499999999997 0.0161913 0.0254597 -0.03819499999999997 0.0159749 0.0299034 -0.04028399999999997 0.017307 0.023 -0.02742499999999997 0.016195 0.0251401 -0.03815979999999997 0.0161913 0.0254597 -0.03819499999999997 0.017307 0.023 -0.02742499999999997 0.0162152 0.0233709 -0.03796439999999997 0.016195 0.0251401 -0.03815979999999997 0.017307 0.023 -0.02742499999999997 0.0159634 0.0301408 -0.04039569999999997 0.014999 0.045 -0.04970499999999997 -0.015001 0.017354 -0.110032 -0.015001 0.022294 -0.104332 0.014999 0.022294 -0.104332 -0.015001 0.022294 -0.104332 -0.015001 0.024129 -0.100963 0.014999 0.024129 -0.100963 -0.015001 0.017354 -0.110032 0.014999 0.022294 -0.104332 0.014999 0.017354 -0.110032 0.014999 0.017354 -0.110032 0.014999 0.016369 -0.106216 0.014999 0.013837 -0.10869 0.014999 0.011009 -0.11411 0.014999 0.017354 -0.110032 0.014999 0.0139244 -0.110163 0.014999 0.013837 -0.10869 0.014999 0.0104947 -0.110519 0.014999 0.0139244 -0.110163 0.014999 0.0104947 -0.110519 0.014999 0.011009 -0.11411 0.014999 0.0139244 -0.110163 0.014999 0.017354 -0.110032 0.014999 0.013837 -0.10869 0.014999 0.0139244 -0.110163 -0.015001 0.024129 -0.100963 -0.015001 0.045 -0.05500499999999997 0.014999 0.024129 -0.100963 -0.015001 0.045 -0.05500499999999997 -0.015001 0.045 -0.04970499999999997 0.014999 0.045 -0.04970499999999997 0.014999 0.001784 -0.04970499999999997 0.0151727 0.005037 -0.04802789999999997 0.0155745 0.00833217 -0.04414979999999998 0.017307 0.023 -0.02742499999999997 0.0162501 0.0203204 -0.03762759999999997 0.0162152 0.0233709 -0.03796439999999997 0.017307 0.023 -0.02742499999999997 0.0162426 0.0199942 -0.03770049999999997 0.0162501 0.0203204 -0.03762759999999997 0.017307 0.023 -0.02742499999999997 0.0161333 0.0152729 -0.03875469999999998 0.0162426 0.0199942 -0.03770049999999997 0.017307 0.023 -0.02742499999999997 0.0161171 0.0150167 -0.03891159999999997 0.0161333 0.0152729 -0.03875469999999998 0.017307 0.023 -0.02742499999999997 0.0158536 0.0108606 -0.04145549999999997 0.0161171 0.0150167 -0.03891159999999997 0.017307 0.023 -0.02742499999999997 0.014999 0.001784 -0.04970499999999997 0.0156769 0.009172100000000001 -0.04316129999999997 0.017307 0.023 -0.02742499999999997 0.0156769 0.009172100000000001 -0.04316129999999997 0.0158458 0.0107864 -0.04153049999999997 0.017307 0.023 -0.02742499999999997 0.0158458 0.0107864 -0.04153049999999997 0.0158536 0.0108606 -0.04145549999999997 0.0156769 0.009172100000000001 -0.04316129999999997 0.014999 0.001784 -0.04970499999999997 0.0155745 0.00833217 -0.04414979999999998 0.018999 0.045 -0.01109499999999997 0.017307 0.023 -0.02742499999999997 0.014999 0.045 -0.04970499999999997 -0.015001 0.022294 -0.104332 -0.015001 0.018178 -0.100248 -0.015001 0.019627 -0.09722869999999997 -0.015001 0.0157113 -0.103667 -0.015001 0.017585 -0.101484 -0.015001 0.0190027 -0.10363 -0.015001 0.017585 -0.101484 -0.015001 0.018178 -0.100248 -0.015001 0.0190027 -0.10363 -0.015001 0.022294 -0.104332 -0.015001 0.017354 -0.110032 -0.015001 0.0190027 -0.10363 -0.015001 0.017354 -0.110032 -0.015001 0.0157113 -0.103667 -0.015001 0.0190027 -0.10363 -0.015001 0.018178 -0.100248 -0.015001 0.022294 -0.104332 -0.015001 0.0190027 -0.10363 -0.015001 0.019627 -0.09722869999999997 -0.015001 0.019957 -0.09654099999999997 -0.015001 0.021878 -0.09863749999999998 -0.015001 0.019957 -0.09654099999999997 -0.015001 0.02021 -0.09519399999999997 -0.015001 0.021878 -0.09863749999999998 -0.015001 0.02021 -0.09519399999999997 -0.015001 0.0206328 -0.09294289999999997 -0.015001 0.021878 -0.09863749999999998 -0.015001 0.0206328 -0.09294289999999997 -0.015001 0.024129 -0.100963 -0.015001 0.021878 -0.09863749999999998 -0.015001 0.024129 -0.100963 -0.015001 0.022294 -0.104332 -0.015001 0.021878 -0.09863749999999998 -0.015001 0.022294 -0.104332 -0.015001 0.019627 -0.09722869999999997 -0.015001 0.021878 -0.09863749999999998 0.014999 0.017354 -0.110032 -0.015001 0.011009 -0.11411 -0.015001 0.017354 -0.110032 0.014999 0.017354 -0.110032 0.014999 0.011009 -0.11411 -0.015001 0.011009 -0.11411 0.014999 0.011009 -0.11411 0.014999 0.0104947 -0.110519 0.014999 0.008283 -0.11173 0.014999 0.00377199 -0.116235 0.014999 0.011009 -0.11411 0.014999 0.00733916 -0.113377 0.014999 0.008283 -0.11173 0.014999 0.00366932 -0.112799 0.014999 0.00733916 -0.113377 0.014999 0.00366932 -0.112799 0.014999 0.00377199 -0.116235 0.014999 0.00733916 -0.113377 0.014999 0.011009 -0.11411 0.014999 0.008283 -0.11173 0.014999 0.00733916 -0.113377 -0.015001 0.045 -0.05500499999999997 -0.015001 0.036766 -0.05498099999999997 -0.015001 0.0368311 -0.05400319999999997 -0.015001 0.024129 -0.100963 -0.015001 0.028996 -0.08602199999999997 -0.015001 0.030282 -0.08455499999999998 -0.015001 0.015639 -0.07598999999999997 -0.015001 0.014599 -0.07509749999999997 -0.015001 0.014744 -0.07342099999999997 -0.015001 0.028996 -0.08602199999999997 -0.015001 0.024129 -0.100963 -0.015001 0.027246 -0.08688499999999998 -0.015001 0.018629 -0.07798099999999997 -0.015001 0.015639 -0.07598999999999997 -0.015001 0.014744 -0.07342099999999997 -0.015001 0.014744 -0.07342099999999997 -0.015001 0.014599 -0.07509749999999997 -0.015001 0.01181 -0.07270409999999997 -0.015001 0.027246 -0.08688499999999998 -0.015001 0.024129 -0.100963 -0.015001 0.0206328 -0.09294289999999997 -0.015001 0.014744 -0.07342099999999997 -0.015001 0.01181 -0.07270409999999997 -0.015001 0.0110356 -0.07092759999999997 -0.015001 0.025299 -0.08701299999999997 -0.015001 0.027246 -0.08688499999999998 -0.015001 0.020969 -0.09115299999999997 -0.015001 0.024129 -0.100963 -0.015001 0.030282 -0.08455499999999998 -0.015001 0.030844 -0.08308599999999997 -0.015001 0.045 -0.05500499999999997 -0.015001 0.024129 -0.100963 -0.015001 0.030844 -0.08308599999999997 -0.015001 0.027246 -0.08688499999999998 -0.015001 0.0206328 -0.09294289999999997 -0.015001 0.020969 -0.09115299999999997 -0.015001 0.025299 -0.08701299999999997 -0.015001 0.020969 -0.09115299999999997 -0.015001 0.0208647 -0.08978649999999998 -0.015001 0.025299 -0.08701299999999997 -0.015001 0.0208647 -0.08978649999999998 -0.015001 0.023452 -0.08638599999999998 -0.015001 0.021985 -0.08509899999999997 -0.015001 0.023452 -0.08638599999999998 -0.015001 0.020552 -0.08568699999999997 -0.015001 0.023452 -0.08638599999999998 -0.015001 0.0208647 -0.08978649999999998 -0.015001 0.020552 -0.08568699999999997 -0.015001 0.021141 -0.08342099999999997 -0.015001 0.021164 -0.08349599999999997 -0.015001 0.0200975 -0.08439399999999997 -0.015001 0.021164 -0.08349599999999997 -0.015001 0.021985 -0.08509899999999997 -0.015001 0.0200975 -0.08439399999999997 -0.015001 0.021985 -0.08509899999999997 -0.015001 0.020552 -0.08568699999999997 -0.015001 0.0200975 -0.08439399999999997 -0.015001 0.021141 -0.08342099999999997 -0.015001 0.0200975 -0.08439399999999997 -0.015001 0.018734 -0.08051499999999998 -0.015001 0.018734 -0.08051499999999998 -0.015001 0.0179603 -0.07938369999999997 -0.015001 0.018629 -0.07798099999999997 -0.015001 0.021141 -0.08342099999999997 -0.015001 0.018734 -0.08051499999999998 -0.015001 0.018629 -0.07798099999999997 -0.015001 0.045 -0.05500499999999997 -0.015001 0.030844 -0.08308599999999997 -0.015001 0.036766 -0.05498099999999997 -0.015001 0.018629 -0.07798099999999997 -0.015001 0.0179603 -0.07938369999999997 -0.015001 0.015639 -0.07598999999999997 -0.015001 0.045 -0.04970499999999997 -0.015001 0.045 -0.05500499999999997 -0.015001 0.0409052 -0.05235499999999997 -0.015001 0.045 -0.05500499999999997 -0.015001 0.0368311 -0.05400319999999997 -0.015001 0.0409052 -0.05235499999999997 -0.015001 0.0368311 -0.05400319999999997 -0.015001 0.037048 -0.05074599999999997 -0.015001 0.0409052 -0.05235499999999997 -0.015001 0.037048 -0.05074599999999997 -0.015001 0.0368104 -0.04970499999999997 -0.015001 0.0409052 -0.05235499999999997 -0.015001 0.0368104 -0.04970499999999997 -0.015001 0.045 -0.04970499999999997 -0.015001 0.0409052 -0.05235499999999997 -0.015001 0.045 -0.04970499999999997 -0.019001 0.045 -0.01109499999999997 0.014999 0.045 -0.04970499999999997 0.0151727 0.005037 -0.04802789999999997 0.014999 0.00344037 -0.04990809999999997 0.014999 0.00361201 -0.04970499999999997 0.014999 0.00344037 -0.04990809999999997 0.014999 0.00240614 -0.05113219999999997 0.0151727 0.005037 -0.04802789999999997 0.014999 0.00240614 -0.05113219999999997 0.0155745 0.00833217 -0.04414979999999998 0.0151727 0.005037 -0.04802789999999997 0.014999 0.00240614 -0.05113219999999997 0.0155745 0.00833217 -0.04414979999999998 0.014999 0.00234639 -0.05120289999999997 0.014999 0.00221173 -0.05136229999999997 0.0155745 0.00833217 -0.04414979999999998 0.014999 0.00234639 -0.05120289999999997 0.014999 0.00204897 -0.05155489999999997 0.0155745 0.00833217 -0.04414979999999998 0.014999 0.00221173 -0.05136229999999997 0.014999 0.00184644 -0.05179459999999998 0.0155745 0.00833217 -0.04414979999999998 0.014999 0.00204897 -0.05155489999999997 0.014999 0.00158355 -0.05210569999999997 0.0155745 0.00833217 -0.04414979999999998 0.014999 0.00184644 -0.05179459999999998 0.014999 0.00122225 -0.05253329999999997 0.0155745 0.00833217 -0.04414979999999998 0.014999 0.00158355 -0.05210569999999997 0.014999 0.000685157 -0.05316899999999997 0.0155745 0.00833217 -0.04414979999999998 0.014999 0.00122225 -0.05253329999999997 0.014999 -0.000209368 -0.05422759999999997 0.0155745 0.00833217 -0.04414979999999998 0.014999 0.000685157 -0.05316899999999997 0.014999 0.00361201 -0.04970499999999997 0.0151727 0.005037 -0.04802789999999997 0.014999 0.001784 -0.04970499999999997 -0.015001 0.001784 -0.04970499999999997 0.014999 0.001784 -0.04970499999999997 0.017307 0.023 -0.02742499999999997 -0.019001 0.045 -0.01109499999999997 0.018999 0.045 -0.01109499999999997 0.014999 0.045 -0.04970499999999997 0.018999 0.045 -0.01109499999999997 0.018999 0.023 -0.01109499999999997 0.017307 0.023 -0.02742499999999997 -0.015001 0.017585 -0.101484 -0.015001 0.0157113 -0.103667 -0.020001 0.0158 -0.103564 -0.015001 0.0157113 -0.103667 -0.015001 0.0149075 -0.104604 -0.020001 0.0158 -0.103564 -0.015001 0.0149075 -0.104604 -0.025001 0.014015 -0.105644 -0.020001 0.0158 -0.103564 -0.025001 0.014015 -0.105644 -0.025001 0.017585 -0.101484 -0.020001 0.0158 -0.103564 -0.025001 0.017585 -0.101484 -0.015001 0.017585 -0.101484 -0.020001 0.0158 -0.103564 -0.025001 0.017585 -0.101484 -0.015001 0.018178 -0.100248 -0.015001 0.017585 -0.101484 -0.015001 0.019957 -0.09654099999999997 -0.015001 0.019627 -0.09722869999999997 -0.020001 0.018771 -0.09901249999999998 -0.015001 0.019627 -0.09722869999999997 -0.015001 0.018178 -0.100248 -0.020001 0.018771 -0.09901249999999998 -0.015001 0.018178 -0.100248 -0.025001 0.017585 -0.101484 -0.020001 0.018771 -0.09901249999999998 -0.025001 0.017585 -0.101484 -0.025001 0.019957 -0.09654099999999997 -0.020001 0.018771 -0.09901249999999998 -0.025001 0.019957 -0.09654099999999997 -0.015001 0.019957 -0.09654099999999997 -0.020001 0.018771 -0.09901249999999998 -0.015001 0.017354 -0.110032 -0.015001 0.014015 -0.105644 -0.015001 0.0149075 -0.104604 -0.015001 0.017354 -0.110032 -0.015001 0.0149075 -0.104604 -0.015001 0.0157113 -0.103667 -0.015001 0.0101727 -0.108271 -0.015001 0.0106213 -0.107965 -0.015001 0.0137633 -0.108889 -0.015001 0.0106213 -0.107965 -0.015001 0.014015 -0.105644 -0.015001 0.0137633 -0.108889 -0.015001 0.017354 -0.110032 -0.015001 0.011009 -0.11411 -0.015001 0.0137633 -0.108889 -0.015001 0.011009 -0.11411 -0.015001 0.0101727 -0.108271 -0.015001 0.0137633 -0.108889 -0.015001 0.014015 -0.105644 -0.015001 0.017354 -0.110032 -0.015001 0.0137633 -0.108889 -0.025001 0.019957 -0.09654099999999997 -0.015001 0.02021 -0.09519399999999997 -0.015001 0.019957 -0.09654099999999997 -0.015001 0.020969 -0.09115299999999997 -0.015001 0.0206328 -0.09294289999999997 -0.020001 0.020463 -0.09384699999999997 -0.015001 0.0206328 -0.09294289999999997 -0.015001 0.02021 -0.09519399999999997 -0.020001 0.020463 -0.09384699999999997 -0.015001 0.02021 -0.09519399999999997 -0.025001 0.019957 -0.09654099999999997 -0.020001 0.020463 -0.09384699999999997 -0.025001 0.019957 -0.09654099999999997 -0.025001 0.020969 -0.09115299999999997 -0.020001 0.020463 -0.09384699999999997 -0.025001 0.020969 -0.09115299999999997 -0.015001 0.020969 -0.09115299999999997 -0.020001 0.020463 -0.09384699999999997 0.014999 0.011009 -0.11411 -0.015001 0.003772 -0.116235 -0.015001 0.011009 -0.11411 0.014999 0.011009 -0.11411 0.014999 0.00377199 -0.116235 -0.015001 0.003772 -0.116235 0.014999 0.00366932 -0.112799 0.014999 0.002115 -0.113159 0.014999 0.00377199 -0.116235 0.014999 -0.00377101 -0.116235 0.014999 0.00377199 -0.116235 0.014999 4.89992e-07 -0.114517 0.014999 0.002115 -0.113159 0.014999 -0.00349286 -0.112904 0.014999 4.89992e-07 -0.114517 0.014999 -0.00349286 -0.112904 0.014999 -0.00377101 -0.116235 0.014999 4.89992e-07 -0.114517 0.014999 0.00377199 -0.116235 0.014999 0.002115 -0.113159 0.014999 4.89992e-07 -0.114517 -0.015001 0.01181 -0.07270409999999997 -0.015001 0.011479 -0.07241999999999997 -0.015001 0.0110356 -0.07092759999999997 -0.015001 0.009771999999999999 -0.07007799999999997 -0.015001 0.010056 -0.07173699999999997 -0.015001 0.009385249999999999 -0.06995039999999997 -0.015001 0.009771999999999999 -0.07007799999999997 -0.015001 0.0110356 -0.07092759999999997 -0.015001 0.0105976 -0.07132729999999997 -0.015001 0.011479 -0.07241999999999997 -0.015001 0.0102435 -0.07182699999999997 -0.015001 0.0105976 -0.07132729999999997 -0.015001 0.0102435 -0.07182699999999997 -0.015001 0.010056 -0.07173699999999997 -0.015001 0.0105976 -0.07132729999999997 -0.015001 0.0110356 -0.07092759999999997 -0.015001 0.011479 -0.07241999999999997 -0.015001 0.0105976 -0.07132729999999997 -0.015001 0.010056 -0.07173699999999997 -0.015001 0.009771999999999999 -0.07007799999999997 -0.015001 0.0105976 -0.07132729999999997 -0.025001 0.020969 -0.09115299999999997 -0.015001 0.0208647 -0.08978649999999998 -0.015001 0.020969 -0.09115299999999997 -0.015001 0.020552 -0.08568699999999997 -0.015001 0.0208647 -0.08978649999999998 -0.020001 0.0207605 -0.08841999999999997 -0.015001 0.0208647 -0.08978649999999998 -0.025001 0.020969 -0.09115299999999997 -0.020001 0.0207605 -0.08841999999999997 -0.025001 0.020969 -0.09115299999999997 -0.025001 0.020552 -0.08568699999999997 -0.020001 0.0207605 -0.08841999999999997 -0.025001 0.020552 -0.08568699999999997 -0.015001 0.020552 -0.08568699999999997 -0.020001 0.0207605 -0.08841999999999997 -0.025001 0.020552 -0.08568699999999997 -0.015001 0.0200975 -0.08439399999999997 -0.015001 0.020552 -0.08568699999999997 -0.015001 0.018734 -0.08051499999999998 -0.015001 0.0200975 -0.08439399999999997 -0.020001 0.019643 -0.08310099999999997 -0.025001 0.018734 -0.08051499999999998 -0.015001 0.018734 -0.08051499999999998 -0.020001 0.019643 -0.08310099999999997 -0.015001 0.0200975 -0.08439399999999997 -0.025001 0.020552 -0.08568699999999997 -0.020001 0.019643 -0.08310099999999997 -0.025001 0.020552 -0.08568699999999997 -0.025001 0.018734 -0.08051499999999998 -0.020001 0.019643 -0.08310099999999997 -0.025001 0.018734 -0.08051499999999998 -0.015001 0.0179603 -0.07938369999999997 -0.015001 0.018734 -0.08051499999999998 -0.015001 0.015639 -0.07598999999999997 -0.015001 0.0179603 -0.07938369999999997 -0.020001 0.0171865 -0.07825249999999997 -0.025001 0.015639 -0.07598999999999997 -0.015001 0.015639 -0.07598999999999997 -0.020001 0.0171865 -0.07825249999999997 -0.015001 0.0179603 -0.07938369999999997 -0.025001 0.018734 -0.08051499999999998 -0.020001 0.0171865 -0.07825249999999997 -0.025001 0.018734 -0.08051499999999998 -0.025001 0.015639 -0.07598999999999997 -0.020001 0.0171865 -0.07825249999999997 -0.015001 0.014599 -0.07509749999999997 -0.015001 0.015639 -0.07598999999999997 -0.025001 0.015639 -0.07598999999999997 -0.015001 0.01181 -0.07270409999999997 -0.015001 0.014599 -0.07509749999999997 -0.020001 0.013559 -0.07420499999999997 -0.015001 0.011479 -0.07241999999999997 -0.015001 0.01181 -0.07270409999999997 -0.020001 0.013559 -0.07420499999999997 -0.015001 0.014599 -0.07509749999999997 -0.025001 0.015639 -0.07598999999999997 -0.020001 0.013559 -0.07420499999999997 -0.025001 0.011479 -0.07241999999999997 -0.015001 0.011479 -0.07241999999999997 -0.020001 0.013559 -0.07420499999999997 -0.025001 0.015639 -0.07598999999999997 -0.025001 0.011479 -0.07241999999999997 -0.020001 0.013559 -0.07420499999999997 -0.015347 0.036048 -0.04636499999999998 -0.0155351 0.0350001 -0.04454949999999997 -0.015001 0.045 -0.04970499999999997 -0.0153411 0.0360611 -0.04642229999999997 -0.015347 0.036048 -0.04636499999999998 -0.015001 0.045 -0.04970499999999997 -0.015001 0.0368104 -0.04970499999999997 -0.0153411 0.0360611 -0.04642229999999997 -0.015001 0.045 -0.04970499999999997 -0.015001 0.045 -0.04970499999999997 -0.017309 0.023 -0.02742499999999997 -0.019001 0.045 -0.01109499999999997 0.014999 0.00344037 -0.04990809999999997 0.014999 0.00361201 -0.04970499999999997 0.014999 0.001784 -0.04970499999999997 0.014999 0.00344037 -0.04990809999999997 0.014999 0.001784 -0.04970499999999997 0.014999 0.00240614 -0.05113219999999997 0.014999 0.00240614 -0.05113219999999997 0.014999 0.001784 -0.04970499999999997 0.014999 0.00234639 -0.05120289999999997 0.014999 0.00234639 -0.05120289999999997 0.014999 0.001784 -0.04970499999999997 0.014999 0.00221173 -0.05136229999999997 0.014999 0.00221173 -0.05136229999999997 0.014999 0.001784 -0.04970499999999997 0.014999 0.00204897 -0.05155489999999997 0.014999 0.001784 -0.04970499999999997 0.014999 0.00184644 -0.05179459999999998 0.014999 0.00204897 -0.05155489999999997 0.014999 0.001784 -0.04970499999999997 0.014999 0.00158355 -0.05210569999999997 0.014999 0.00184644 -0.05179459999999998 0.014999 0.001784 -0.04970499999999997 0.014999 0.00122225 -0.05253329999999997 0.014999 0.00158355 -0.05210569999999997 0.014999 0.001784 -0.04970499999999997 0.014999 0.000685157 -0.05316899999999997 0.014999 0.00122225 -0.05253329999999997 0.014999 -0.000209368 -0.05422759999999997 0.014999 0.000685157 -0.05316899999999997 0.014999 0.001784 -0.04970499999999997 0.014999 -0.00199864 -0.05634529999999997 0.014999 -0.000209368 -0.05422759999999997 0.014999 0.001784 -0.04970499999999997 0.014999 -0.00718103 -0.06247869999999997 0.014999 -0.00199864 -0.05634529999999997 0.014999 0.001784 -0.04970499999999997 0.014999 -0.0225384 -0.08436039999999997 0.014999 -0.022525 -0.08424299999999997 0.014999 -0.025426 -0.08253899999999997 0.014999 -0.022525 -0.08424299999999997 0.014999 -0.020135 -0.07837899999999998 0.014999 -0.025426 -0.08253899999999997 0.014999 -0.020135 -0.07837899999999998 0.014999 -0.01776 -0.07499899999999997 0.014999 -0.025426 -0.08253899999999997 0.014999 -0.0225384 -0.08436039999999997 0.014999 -0.025426 -0.08253899999999997 0.014999 -0.0265 -0.09000499999999997 0.014999 -0.025426 -0.08253899999999997 0.014999 -0.01776 -0.07499899999999997 0.014999 -0.00718103 -0.06247869999999997 0.014999 0.001784 -0.04970499999999997 0.014999 -0.025426 -0.08253899999999997 0.014999 -0.00718103 -0.06247869999999997 -0.017309 0.023 -0.02742499999999997 -0.015001 0.001784 -0.04970499999999997 0.017307 0.023 -0.02742499999999997 -0.015001 0.001784 -0.04970499999999997 0.014999 -0.01919 -0.07172999999999997 0.014999 0.001784 -0.04970499999999997 -0.019001 0.045 -0.01109499999999997 0.020922 0.045 -0.006802999999999972 0.018999 0.045 -0.01109499999999997 0.018999 0.045 -0.01109499999999997 0.020922 0.023 -0.006802999999999972 0.018999 0.023 -0.01109499999999997 -0.017309 0.023 -0.02742499999999997 0.017307 0.023 -0.02742499999999997 0.018999 0.023 -0.01109499999999997 -0.025001 0.014015 -0.105644 -0.015001 0.0149075 -0.104604 -0.015001 0.014015 -0.105644 -0.025001 0.017585 -0.101484 -0.025001 0.014015 -0.105644 -0.025001 -0.011478 -0.10759 -0.025001 0.019957 -0.09654099999999997 -0.025001 0.017585 -0.101484 -0.025001 -0.011478 -0.10759 -0.015001 0.0106213 -0.107965 -0.015001 0.0101727 -0.108271 -0.025001 0.00949 -0.108738 -0.015001 0.0101727 -0.108271 -0.015001 0.00949 -0.108738 -0.025001 0.00949 -0.108738 -0.015001 0.014015 -0.105644 -0.015001 0.0106213 -0.107965 -0.020001 0.0117525 -0.107191 -0.015001 0.0106213 -0.107965 -0.025001 0.00949 -0.108738 -0.020001 0.0117525 -0.107191 -0.025001 0.00949 -0.108738 -0.025001 0.014015 -0.105644 -0.020001 0.0117525 -0.107191 -0.025001 0.014015 -0.105644 -0.015001 0.014015 -0.105644 -0.020001 0.0117525 -0.107191 -0.015001 0.0101727 -0.108271 -0.015001 0.011009 -0.11411 -0.015001 0.00949 -0.108738 -0.015001 0.004318 -0.110556 -0.015001 0.003772 -0.116235 -0.015001 0.00360394 -0.110611 -0.015001 0.004318 -0.110556 -0.015001 0.005611 -0.110101 -0.015001 0.00730647 -0.112253 -0.015001 0.005611 -0.110101 -0.015001 0.00949 -0.108738 -0.015001 0.00730647 -0.112253 -0.015001 0.011009 -0.11411 -0.015001 0.003772 -0.116235 -0.015001 0.00730647 -0.112253 -0.015001 0.00949 -0.108738 -0.015001 0.011009 -0.11411 -0.015001 0.00730647 -0.112253 -0.015001 0.003772 -0.116235 -0.015001 0.004318 -0.110556 -0.015001 0.00730647 -0.112253 -0.025001 0.020969 -0.09115299999999997 -0.025001 0.019957 -0.09654099999999997 -0.025001 -0.011478 -0.10759 -0.015001 -0.003771 -0.116235 -0.015001 0.003772 -0.116235 0.014999 0.00377199 -0.116235 0.014999 -0.00377101 -0.116235 -0.015001 -0.003771 -0.116235 0.014999 0.00377199 -0.116235 0.014999 -0.00349286 -0.112904 0.014999 -0.00421101 -0.112871 0.014999 -0.00377101 -0.116235 0.014999 -0.010224 -0.110887 0.014999 -0.0103509 -0.110802 0.014999 -0.011008 -0.11411 0.014999 -0.011008 -0.11411 0.014999 -0.00377101 -0.116235 0.014999 -0.00725043 -0.113518 0.014999 -0.00421101 -0.112871 0.014999 -0.010224 -0.110887 0.014999 -0.00725043 -0.113518 0.014999 -0.010224 -0.110887 0.014999 -0.011008 -0.11411 0.014999 -0.00725043 -0.113518 0.014999 -0.00377101 -0.116235 0.014999 -0.00421101 -0.112871 0.014999 -0.00725043 -0.113518 -0.015001 0.00710472 -0.07032049999999997 -0.015001 0.00678809 -0.06909369999999997 -0.015001 0.00842207 -0.07041529999999997 -0.015001 0.00678809 -0.06909369999999997 -0.015001 0.009385249999999999 -0.06995039999999997 -0.015001 0.00842207 -0.07041529999999997 -0.015001 0.009385249999999999 -0.06995039999999997 -0.015001 0.010056 -0.07173699999999997 -0.015001 0.00842207 -0.07041529999999997 -0.015001 0.010056 -0.07173699999999997 -0.015001 0.00710472 -0.07032049999999997 -0.015001 0.00842207 -0.07041529999999997 -0.015001 0.0102435 -0.07182699999999997 -0.015001 0.011479 -0.07241999999999997 -0.025001 0.011479 -0.07241999999999997 -0.015001 0.010056 -0.07173699999999997 -0.015001 0.0102435 -0.07182699999999997 -0.020001 0.009008 -0.07123399999999998 -0.015001 0.00710472 -0.07032049999999997 -0.015001 0.010056 -0.07173699999999997 -0.020001 0.009008 -0.07123399999999998 -0.015001 0.0102435 -0.07182699999999997 -0.025001 0.011479 -0.07241999999999997 -0.020001 0.009008 -0.07123399999999998 -0.015001 0.006537 -0.07004799999999997 -0.015001 0.00710472 -0.07032049999999997 -0.020001 0.009008 -0.07123399999999998 -0.025001 0.011479 -0.07241999999999997 -0.025001 0.006537 -0.07004799999999997 -0.020001 0.009008 -0.07123399999999998 -0.025001 0.006537 -0.07004799999999997 -0.015001 0.006537 -0.07004799999999997 -0.020001 0.009008 -0.07123399999999998 -0.025001 0.020552 -0.08568699999999997 -0.025001 0.020969 -0.09115299999999997 -0.025001 -0.011478 -0.10759 -0.025001 0.018734 -0.08051499999999998 -0.025001 0.020552 -0.08568699999999997 -0.025001 -0.011478 -0.10759 -0.025001 0.018734 -0.08051499999999998 -0.025001 -0.011478 -0.10759 -0.025001 0.015639 -0.07598999999999997 -0.025001 0.015639 -0.07598999999999997 -0.025001 -0.011478 -0.10759 -0.025001 0.011479 -0.07241999999999997 -0.015001 0.045 -0.04970499999999997 -0.0155351 0.0350001 -0.04454949999999997 -0.0157386 0.0338657 -0.04258439999999997 -0.015001 0.045 -0.04970499999999997 -0.0157386 0.0338657 -0.04258439999999997 -0.0157501 0.033802 -0.04247399999999997 -0.0160538 0.0306414 -0.03954169999999997 -0.0160666 0.030508 -0.03941799999999997 -0.017309 0.023 -0.02742499999999997 -0.0160666 0.030508 -0.03941799999999997 -0.0162589 0.0266549 -0.03756229999999997 -0.017309 0.023 -0.02742499999999997 -0.0162589 0.0266549 -0.03756229999999997 -0.0162686 0.026459 -0.03746799999999997 -0.017309 0.023 -0.02742499999999997 -0.0162686 0.026459 -0.03746799999999997 -0.0163174 0.0233368 -0.03699719999999997 -0.017309 0.023 -0.02742499999999997 -0.015001 0.045 -0.04970499999999997 -0.0157501 0.033802 -0.04247399999999997 -0.0160538 0.0306414 -0.03954169999999997 -0.017309 0.023 -0.02742499999999997 -0.015001 0.045 -0.04970499999999997 -0.0160538 0.0306414 -0.03954169999999997 -0.017309 0.023 -0.02742499999999997 -0.019001 0.023 -0.01109499999999997 -0.019001 0.045 -0.01109499999999997 0.014999 -0.023244 -0.09053399999999998 0.014999 -0.0225384 -0.08436039999999997 0.014999 -0.0265 -0.09000499999999997 0.014999 -0.025426 -0.09747099999999997 0.014999 -0.0228548 -0.09295739999999997 0.014999 -0.0245192 -0.09091569999999997 0.014999 -0.0228548 -0.09295739999999997 0.014999 -0.023244 -0.09053399999999998 0.014999 -0.0245192 -0.09091569999999997 0.014999 -0.0265 -0.09000499999999997 0.014999 -0.025426 -0.09747099999999997 0.014999 -0.0245192 -0.09091569999999997 0.014999 -0.023244 -0.09053399999999998 0.014999 -0.0265 -0.09000499999999997 0.014999 -0.0245192 -0.09091569999999997 0.014999 -0.025426 -0.08253899999999997 0.014999 0.001784 -0.04970499999999997 0.014999 -0.022293 -0.07567799999999997 -0.015001 -0.025426 -0.08253899999999997 0.014999 -0.0265 -0.09000499999999997 0.014999 -0.025426 -0.08253899999999997 -0.0163345 0.0222439 -0.03683239999999997 -0.016338 0.022016 -0.03679799999999997 -0.017309 0.023 -0.02742499999999997 -0.016338 0.022016 -0.03679799999999997 -0.016272 0.0177902 -0.03743519999999997 -0.017309 0.023 -0.02742499999999997 -0.016272 0.0177902 -0.03743519999999997 -0.0162686 0.017573 -0.03746799999999997 -0.017309 0.023 -0.02742499999999997 -0.0163174 0.0233368 -0.03699719999999997 -0.0163345 0.0222439 -0.03683239999999997 -0.017309 0.023 -0.02742499999999997 -0.0162686 0.017573 -0.03746799999999997 -0.016075 0.0136913 -0.03933749999999997 -0.016155 0.0125604 -0.03856499999999997 -0.016075 0.0136913 -0.03933749999999997 -0.0160666 0.013524 -0.03941799999999997 -0.016155 0.0125604 -0.03856499999999997 -0.0160666 0.013524 -0.03941799999999997 -0.0159434 0.0120061 -0.04060729999999997 -0.016155 0.0125604 -0.03856499999999997 -0.016155 0.0125604 -0.03856499999999997 -0.0159388 0.011949 -0.04065199999999997 -0.0159434 0.0120061 -0.04060729999999997 -0.0159388 0.011949 -0.04065199999999997 -0.0150104 0.00196059 -0.04961399999999997 -0.016155 0.0125604 -0.03856499999999997 -0.0150104 0.00196059 -0.04961399999999997 -0.015001 0.001784 -0.04970499999999997 -0.016155 0.0125604 -0.03856499999999997 -0.015001 0.001784 -0.04970499999999997 -0.017309 0.023 -0.02742499999999997 -0.016155 0.0125604 -0.03856499999999997 -0.017309 0.023 -0.02742499999999997 -0.0162686 0.017573 -0.03746799999999997 -0.016155 0.0125604 -0.03856499999999997 -0.015001 -0.0110311 -0.06316229999999998 -0.015001 -0.01919 -0.07172999999999997 0.014999 -0.01919 -0.07172999999999997 -0.015001 -0.0109901 -0.06311919999999997 -0.015001 -0.0110311 -0.06316229999999998 0.014999 -0.01919 -0.07172999999999997 -0.015001 -0.0109063 -0.06303119999999997 -0.015001 -0.0109901 -0.06311919999999997 0.014999 -0.01919 -0.07172999999999997 -0.015001 0.00134311 -0.05016799999999997 -0.015001 -0.00839001 -0.06038879999999997 0.014999 -0.01919 -0.07172999999999997 -0.015001 -0.0108748 -0.06299819999999998 -0.015001 -0.0109063 -0.06303119999999997 0.014999 -0.01919 -0.07172999999999997 -0.015001 -0.00839001 -0.06038879999999997 -0.015001 -0.00844342 -0.06044489999999998 0.014999 -0.01919 -0.07172999999999997 -0.015001 -0.009631229999999999 -0.06169219999999997 -0.015001 -0.0108748 -0.06299819999999998 0.014999 -0.01919 -0.07172999999999997 -0.015001 -0.00844342 -0.06044489999999998 -0.015001 -0.00947042 -0.06152339999999997 0.014999 -0.01919 -0.07172999999999997 -0.015001 -0.00947042 -0.06152339999999997 -0.015001 -0.009631229999999999 -0.06169219999999997 0.014999 -0.01919 -0.07172999999999997 -0.015001 0.00134311 -0.05016799999999997 0.014999 -0.01919 -0.07172999999999997 -0.015001 0.001784 -0.04970499999999997 0.014999 -0.022293 -0.07567799999999997 0.014999 0.001784 -0.04970499999999997 0.014999 -0.01919 -0.07172999999999997 -0.019001 0.045 -0.01109499999999997 -0.020924 0.045 -0.006802999999999972 0.020922 0.045 -0.006802999999999972 0.018999 0.045 -0.01109499999999997 0.020922 0.045 -0.006802999999999972 0.020922 0.023 -0.006802999999999972 0.0044 0.023 -0.01062899999999997 0.018999 0.023 -0.01109499999999997 0.020922 0.023 -0.006802999999999972 -9.982949999999999e-07 0.023 -0.01150499999999997 -0.017309 0.023 -0.02742499999999997 0.018999 0.023 -0.01109499999999997 -0.025001 0.014015 -0.105644 -0.025001 0.00949 -0.108738 -0.025001 -0.011478 -0.10759 -0.015001 0.00949 -0.108738 -0.015001 0.005611 -0.110101 -0.020001 0.006904 -0.109647 -0.015001 0.005611 -0.110101 -0.025001 0.004318 -0.110556 -0.020001 0.006904 -0.109647 -0.025001 0.004318 -0.110556 -0.025001 0.00949 -0.108738 -0.020001 0.006904 -0.109647 -0.025001 0.00949 -0.108738 -0.015001 0.00949 -0.108738 -0.020001 0.006904 -0.109647 -0.015001 0.004318 -0.110556 -0.015001 0.00360394 -0.110611 -0.020001 0.001585 -0.110765 -0.015001 0.00360394 -0.110611 -0.015001 0.0002185 -0.110869 -0.020001 0.001585 -0.110765 -0.015001 0.0002185 -0.110869 -0.025001 -0.001148 -0.110974 -0.020001 0.001585 -0.110765 -0.025001 -0.001148 -0.110974 -0.025001 0.004318 -0.110556 -0.020001 0.001585 -0.110765 -0.025001 0.004318 -0.110556 -0.015001 0.004318 -0.110556 -0.020001 0.001585 -0.110765 -0.015001 0.005611 -0.110101 -0.015001 0.004318 -0.110556 -0.025001 0.004318 -0.110556 -0.015001 -0.00329801 -0.11057 -0.015001 -0.001148 -0.110974 -0.015001 5.00004e-07 -0.113403 -0.015001 -0.001148 -0.110974 -0.015001 0.0002185 -0.110869 -0.015001 5.00004e-07 -0.113403 -0.015001 0.0002185 -0.110869 -0.015001 0.00360394 -0.110611 -0.015001 5.00004e-07 -0.113403 -0.015001 0.00360394 -0.110611 -0.015001 0.003772 -0.116235 -0.015001 5.00004e-07 -0.113403 -0.015001 0.003772 -0.116235 -0.015001 -0.003771 -0.116235 -0.015001 5.00004e-07 -0.113403 -0.015001 -0.003771 -0.116235 -0.015001 -0.00329801 -0.11057 -0.015001 5.00004e-07 -0.113403 0.014999 -0.00377101 -0.116235 -0.015001 -0.011008 -0.11411 -0.015001 -0.003771 -0.116235 0.014999 -0.00377101 -0.116235 0.014999 -0.011008 -0.11411 -0.015001 -0.011008 -0.11411 0.014999 -0.015479 -0.107354 0.014999 -0.0162255 -0.106478 0.014999 -0.017353 -0.110032 0.014999 -0.017353 -0.110032 0.014999 -0.011008 -0.11411 0.014999 -0.013852 -0.110294 0.014999 -0.011008 -0.11411 0.014999 -0.0103509 -0.110802 0.014999 -0.013852 -0.110294 0.014999 -0.0103509 -0.110802 0.014999 -0.015479 -0.107354 0.014999 -0.013852 -0.110294 0.014999 -0.015479 -0.107354 0.014999 -0.017353 -0.110032 0.014999 -0.013852 -0.110294 -0.015001 0.00710472 -0.07032049999999997 -0.015001 0.006537 -0.07004799999999997 -0.015001 0.00678809 -0.06909369999999997 -0.015001 0.00464697 -0.06969299999999998 -0.015001 0.00445068 -0.06832259999999997 -0.015001 0.0057777 -0.06932159999999997 -0.015001 0.00445068 -0.06832259999999997 -0.015001 0.00678809 -0.06909369999999997 -0.015001 0.0057777 -0.06932159999999997 -0.015001 0.006537 -0.07004799999999997 -0.015001 0.00519 -0.06979499999999997 -0.015001 0.0057777 -0.06932159999999997 -0.015001 0.00519 -0.06979499999999997 -0.015001 0.00464697 -0.06969299999999998 -0.015001 0.0057777 -0.06932159999999997 -0.015001 0.00678809 -0.06909369999999997 -0.015001 0.006537 -0.07004799999999997 -0.015001 0.0057777 -0.06932159999999997 -0.015001 0.00236848 -0.06926499999999997 -0.015001 0.0023343 -0.06812129999999997 -0.015001 0.00349063 -0.06890709999999997 -0.015001 0.0023343 -0.06812129999999997 -0.015001 0.004082 -0.06820099999999997 -0.015001 0.00349063 -0.06890709999999997 -0.015001 0.004082 -0.06820099999999997 -0.015001 0.00445068 -0.06832259999999997 -0.015001 0.00349063 -0.06890709999999997 -0.015001 0.00445068 -0.06832259999999997 -0.015001 0.00464697 -0.06969299999999998 -0.015001 0.00349063 -0.06890709999999997 -0.015001 0.00464697 -0.06969299999999998 -0.015001 0.00236848 -0.06926499999999997 -0.015001 0.00349063 -0.06890709999999997 -0.025001 0.011479 -0.07241999999999997 -0.025001 -0.011478 -0.10759 -0.025001 0.006537 -0.07004799999999997 -0.015001 0.00519 -0.06979499999999997 -0.015001 0.006537 -0.07004799999999997 -0.025001 0.006537 -0.07004799999999997 -0.019001 0.023 -0.01109499999999997 -0.017309 0.023 -0.02742499999999997 -9.982949999999999e-07 0.023 -0.01150499999999997 -0.020924 0.045 -0.006802999999999972 -0.019001 0.045 -0.01109499999999997 -0.019001 0.023 -0.01109499999999997 0.014999 -0.02224 -0.09678599999999997 0.014999 -0.0228548 -0.09295739999999997 0.014999 -0.025426 -0.09747099999999997 0.014999 -0.022293 -0.104332 0.014999 -0.0205653 -0.100412 0.014999 -0.0229957 -0.09864469999999997 0.014999 -0.0205653 -0.100412 0.014999 -0.02224 -0.09678599999999997 0.014999 -0.0229957 -0.09864469999999997 0.014999 -0.025426 -0.09747099999999997 0.014999 -0.022293 -0.104332 0.014999 -0.0229957 -0.09864469999999997 0.014999 -0.02224 -0.09678599999999997 0.014999 -0.025426 -0.09747099999999997 0.014999 -0.0229957 -0.09864469999999997 -0.015001 -0.0265 -0.09000499999999997 0.014999 -0.025426 -0.09747099999999997 0.014999 -0.0265 -0.09000499999999997 -0.015001 -0.022293 -0.07567799999999997 0.014999 -0.025426 -0.08253899999999997 0.014999 -0.022293 -0.07567799999999997 -0.015001 -0.022293 -0.07567799999999997 -0.015001 -0.025426 -0.08253899999999997 0.014999 -0.025426 -0.08253899999999997 -0.015001 -0.025426 -0.08253899999999997 -0.015001 -0.0265 -0.09000499999999997 0.014999 -0.0265 -0.09000499999999997 -0.015001 0.00185009 -0.04971309999999998 -0.0150104 0.00196059 -0.04961399999999997 -0.015001 0.00185912 -0.04970499999999997 -0.015001 0.00180512 -0.04975339999999998 -0.0150104 0.00196059 -0.04961399999999997 -0.015001 0.00185009 -0.04971309999999998 -0.015001 0.00180293 -0.04975539999999997 -0.0150104 0.00196059 -0.04961399999999997 -0.015001 0.00180512 -0.04975339999999998 -0.015001 0.00179812 -0.04975969999999997 -0.0150104 0.00196059 -0.04961399999999997 -0.015001 0.00180293 -0.04975539999999997 -0.015001 0.00179255 -0.04976469999999997 -0.0150104 0.00196059 -0.04961399999999997 -0.015001 0.00179812 -0.04975969999999997 -0.015001 0.00178596 -0.04977059999999997 -0.0150104 0.00196059 -0.04961399999999997 -0.015001 0.00179255 -0.04976469999999997 -0.015001 0.00177792 -0.04977789999999997 -0.0150104 0.00196059 -0.04961399999999997 -0.015001 0.00178596 -0.04977059999999997 -0.015001 0.00176771 -0.04978699999999997 -0.0150104 0.00196059 -0.04961399999999997 -0.015001 0.00177792 -0.04977789999999997 -0.015001 0.00175411 -0.04979919999999997 -0.0150104 0.00196059 -0.04961399999999997 -0.015001 0.00176771 -0.04978699999999997 -0.015001 0.00173486 -0.04981649999999997 -0.0150104 0.00196059 -0.04961399999999997 -0.015001 0.00175411 -0.04979919999999997 -0.015001 0.00170546 -0.04984289999999997 -0.0150104 0.00196059 -0.04961399999999997 -0.015001 0.00173486 -0.04981649999999997 -0.015001 0.00165625 -0.04988699999999997 -0.0150104 0.00196059 -0.04961399999999997 -0.015001 0.00170546 -0.04984289999999997 -0.015001 0.00156619 -0.04996779999999997 -0.0150104 0.00196059 -0.04961399999999997 -0.015001 0.00165625 -0.04988699999999997 -0.015001 0.001784 -0.04970499999999997 -0.0150104 0.00196059 -0.04961399999999997 -0.015001 0.00185912 -0.04970499999999997 -0.015001 -0.01919 -0.07172999999999997 0.014999 -0.022293 -0.07567799999999997 0.014999 -0.01919 -0.07172999999999997 -0.015001 -0.0110087 -0.06350509999999997 -0.015001 -0.01919 -0.07172999999999997 -0.015001 -0.0110311 -0.06316229999999998 -0.015001 -0.01919 -0.07172999999999997 -0.015001 -0.0110087 -0.06350509999999997 -0.015001 -0.022293 -0.07567799999999997 -0.015001 0.00141267 -0.05010559999999997 -0.015001 0.001784 -0.04970499999999997 -0.015001 0.00134311 -0.05016799999999997 -0.020924 0.045 -0.006802999999999972 0.021999 0.045 -5.002229999972244e-06 0.020922 0.045 -0.006802999999999972 0.020922 0.045 -0.006802999999999972 0.021999 0.023 -5.001269999972245e-06 0.020922 0.023 -0.006802999999999972 0.008130999999999999 0.023 -0.008135999999999971 0.0044 0.023 -0.01062899999999997 0.020922 0.023 -0.006802999999999972 0.0044 0.023 -0.01062899999999997 -9.982949999999999e-07 0.023 -0.01150499999999997 0.018999 0.023 -0.01109499999999997 -0.025001 0.00949 -0.108738 -0.025001 0.004318 -0.110556 -0.025001 -0.011478 -0.10759 -0.015001 0.0002185 -0.110869 -0.015001 -0.001148 -0.110974 -0.025001 -0.001148 -0.110974 -0.025001 0.004318 -0.110556 -0.025001 -0.001148 -0.110974 -0.025001 -0.011478 -0.10759 -0.015001 -0.001148 -0.110974 -0.015001 -0.00329801 -0.11057 -0.020001 -0.003842 -0.110468 -0.015001 -0.00329801 -0.11057 -0.015001 -0.005189 -0.110215 -0.020001 -0.003842 -0.110468 -0.015001 -0.005189 -0.110215 -0.025001 -0.006536 -0.109962 -0.020001 -0.003842 -0.110468 -0.025001 -0.006536 -0.109962 -0.025001 -0.001148 -0.110974 -0.020001 -0.003842 -0.110468 -0.025001 -0.001148 -0.110974 -0.015001 -0.001148 -0.110974 -0.020001 -0.003842 -0.110468 -0.015001 -0.006536 -0.109962 -0.015001 -0.005189 -0.110215 -0.015001 -0.007153 -0.112299 -0.015001 -0.005189 -0.110215 -0.015001 -0.00329801 -0.11057 -0.015001 -0.007153 -0.112299 -0.015001 -0.00329801 -0.11057 -0.015001 -0.003771 -0.116235 -0.015001 -0.007153 -0.112299 -0.015001 -0.003771 -0.116235 -0.015001 -0.011008 -0.11411 -0.015001 -0.007153 -0.112299 -0.015001 -0.011008 -0.11411 -0.015001 -0.00986662 -0.108363 -0.015001 -0.007153 -0.112299 -0.015001 -0.00986662 -0.108363 -0.015001 -0.006536 -0.109962 -0.015001 -0.007153 -0.112299 0.014999 -0.011008 -0.11411 -0.015001 -0.017353 -0.110032 -0.015001 -0.011008 -0.11411 0.014999 -0.011008 -0.11411 0.014999 -0.017353 -0.110032 -0.015001 -0.017353 -0.110032 0.014999 -0.019585 -0.102535 0.014999 -0.0205653 -0.100412 0.014999 -0.022293 -0.104332 0.014999 -0.017353 -0.110032 0.014999 -0.0162255 -0.106478 0.014999 -0.0192593 -0.105222 0.014999 -0.0162255 -0.106478 0.014999 -0.019585 -0.102535 0.014999 -0.0192593 -0.105222 0.014999 -0.022293 -0.104332 0.014999 -0.017353 -0.110032 0.014999 -0.0192593 -0.105222 0.014999 -0.019585 -0.102535 0.014999 -0.022293 -0.104332 0.014999 -0.0192593 -0.105222 -0.015001 0.00464697 -0.06969299999999998 -0.015001 0.00519 -0.06979499999999997 -0.020001 0.003843 -0.06954199999999998 -0.015001 0.00236848 -0.06926499999999997 -0.015001 0.00464697 -0.06969299999999998 -0.020001 0.003843 -0.06954199999999998 -0.015001 0.00519 -0.06979499999999997 -0.025001 0.006537 -0.07004799999999997 -0.020001 0.003843 -0.06954199999999998 -0.015001 0.001149 -0.06903599999999997 -0.015001 0.00236848 -0.06926499999999997 -0.020001 0.003843 -0.06954199999999998 -0.025001 0.006537 -0.07004799999999997 -0.025001 0.001149 -0.06903599999999997 -0.020001 0.003843 -0.06954199999999998 -0.025001 0.001149 -0.06903599999999997 -0.015001 0.001149 -0.06903599999999997 -0.020001 0.003843 -0.06954199999999998 -0.015001 0.000163659 -0.06911119999999997 -0.015001 0.000254233 -0.06802639999999997 -0.015001 0.00126607 -0.06864569999999998 -0.015001 0.000254233 -0.06802639999999997 -0.015001 0.0023343 -0.06812129999999997 -0.015001 0.00126607 -0.06864569999999998 -0.015001 0.0023343 -0.06812129999999997 -0.015001 0.00236848 -0.06926499999999997 -0.015001 0.00126607 -0.06864569999999998 -0.015001 0.00236848 -0.06926499999999997 -0.015001 0.001149 -0.06903599999999997 -0.015001 0.00126607 -0.06864569999999998 -0.015001 0.001149 -0.06903599999999997 -0.015001 0.000163659 -0.06911119999999997 -0.015001 0.00126607 -0.06864569999999998 -0.025001 0.006537 -0.07004799999999997 -0.025001 -0.011478 -0.10759 -0.025001 0.001149 -0.06903599999999997 -0.019001 0.023 -0.01109499999999997 -9.982949999999999e-07 0.023 -0.01150499999999997 -0.004402 0.023 -0.01062899999999997 -0.020924 0.045 -0.006802999999999972 -0.019001 0.023 -0.01109499999999997 -0.020924 0.023 -0.006802999999999972 -0.015001 -0.025426 -0.09747099999999997 0.014999 -0.022293 -0.104332 0.014999 -0.025426 -0.09747099999999997 -0.015001 -0.0265 -0.09000499999999997 -0.015001 -0.025426 -0.09747099999999997 0.014999 -0.025426 -0.09747099999999997 -0.015001 -0.01919 -0.07172999999999997 -0.015001 -0.022293 -0.07567799999999997 0.014999 -0.022293 -0.07567799999999997 -0.015001 -0.010921 -0.06484999999999998 -0.015001 -0.0108635 -0.06496659999999997 -0.015001 -0.022293 -0.07567799999999997 -0.015001 -0.010921 -0.06484999999999998 -0.015001 -0.022293 -0.07567799999999997 -0.015001 -0.0110087 -0.06350509999999997 -0.015001 -0.022293 -0.07567799999999997 -0.015001 -0.0108635 -0.06496659999999997 -0.015001 -0.025426 -0.08253899999999997 -0.015001 -0.0265 -0.09000499999999997 -0.015001 -0.025426 -0.08253899999999997 -0.015001 -0.0100641 -0.06658659999999997 -0.015001 -0.0100641 -0.06658659999999997 -0.015001 -0.025426 -0.08253899999999997 -0.015001 -0.0108635 -0.06496659999999997 -0.015001 0.00156619 -0.04996779999999997 -0.015001 0.001784 -0.04970499999999997 -0.015001 0.00141267 -0.05010559999999997 -0.015001 0.00165625 -0.04988699999999997 -0.015001 0.001784 -0.04970499999999997 -0.015001 0.00156619 -0.04996779999999997 -0.015001 0.001784 -0.04970499999999997 -0.015001 0.00165625 -0.04988699999999997 -0.015001 0.00170546 -0.04984289999999997 -0.015001 0.00170546 -0.04984289999999997 -0.015001 0.00173486 -0.04981649999999997 -0.015001 0.001784 -0.04970499999999997 -0.015001 0.00173486 -0.04981649999999997 -0.015001 0.00175411 -0.04979919999999997 -0.015001 0.001784 -0.04970499999999997 -0.015001 0.00176771 -0.04978699999999997 -0.015001 0.001784 -0.04970499999999997 -0.015001 0.00175411 -0.04979919999999997 -0.015001 0.001784 -0.04970499999999997 -0.015001 0.00176771 -0.04978699999999997 -0.015001 0.00177792 -0.04977789999999997 -0.015001 0.001784 -0.04970499999999997 -0.015001 0.00177792 -0.04977789999999997 -0.015001 0.00178596 -0.04977059999999997 -0.015001 0.001784 -0.04970499999999997 -0.015001 0.00178596 -0.04977059999999997 -0.015001 0.00179255 -0.04976469999999997 -0.015001 0.001784 -0.04970499999999997 -0.015001 0.00179255 -0.04976469999999997 -0.015001 0.00179812 -0.04975969999999997 -0.015001 0.001784 -0.04970499999999997 -0.015001 0.00179812 -0.04975969999999997 -0.015001 0.00180293 -0.04975539999999997 -0.015001 0.001784 -0.04970499999999997 -0.015001 0.00180293 -0.04975539999999997 -0.015001 0.00180512 -0.04975339999999998 -0.015001 0.001784 -0.04970499999999997 -0.015001 0.00180512 -0.04975339999999998 -0.015001 0.00185009 -0.04971309999999998 -0.015001 0.001784 -0.04970499999999997 -0.015001 0.00185009 -0.04971309999999998 -0.015001 0.00185912 -0.04970499999999997 -0.020924 0.045 -0.006802999999999972 -0.022001 0.045 -5.002229999972244e-06 0.021999 0.045 -5.002229999972244e-06 0.021999 0.023 -5.001269999972245e-06 0.020922 0.045 -0.006802999999999972 0.021999 0.045 -5.002229999972244e-06 0.010624 0.023 -0.004405999999999972 0.020922 0.023 -0.006802999999999972 0.021999 0.023 -5.001269999972245e-06 0.010624 0.023 -0.004405999999999972 0.008130999999999999 0.023 -0.008135999999999971 0.020922 0.023 -0.006802999999999972 0.008130999999999999 0.007 -0.008135999999999971 0.0044 0.023 -0.01062899999999997 0.008130999999999999 0.023 -0.008135999999999971 0.0044 0.007 -0.01062899999999997 -9.982949999999999e-07 0.023 -0.01150499999999997 0.0044 0.023 -0.01062899999999997 -0.025001 -0.001148 -0.110974 -0.025001 -0.006536 -0.109962 -0.025001 -0.011478 -0.10759 -0.015001 -0.005189 -0.110215 -0.015001 -0.006536 -0.109962 -0.025001 -0.006536 -0.109962 -0.015001 -0.014599 -0.104912 -0.015001 -0.017353 -0.110032 -0.015001 -0.0154872 -0.10415 -0.015001 -0.0114782 -0.10759 -0.015001 -0.0102425 -0.108183 -0.015001 -0.0136098 -0.10913 -0.015001 -0.0102425 -0.108183 -0.015001 -0.00986662 -0.108363 -0.015001 -0.0136098 -0.10913 -0.015001 -0.00986662 -0.108363 -0.015001 -0.011008 -0.11411 -0.015001 -0.0136098 -0.10913 -0.015001 -0.011008 -0.11411 -0.015001 -0.017353 -0.110032 -0.015001 -0.0136098 -0.10913 -0.015001 -0.014599 -0.104912 -0.015001 -0.0114782 -0.10759 -0.015001 -0.0136098 -0.10913 -0.015001 -0.017353 -0.110032 -0.015001 -0.014599 -0.104912 -0.015001 -0.0136098 -0.10913 -0.015001 -0.006536 -0.109962 -0.015001 -0.00986662 -0.108363 -0.020001 -0.009006999999999999 -0.108776 -0.015001 -0.00986662 -0.108363 -0.015001 -0.0102425 -0.108183 -0.020001 -0.009006999999999999 -0.108776 -0.015001 -0.0102425 -0.108183 -0.025001 -0.011478 -0.10759 -0.020001 -0.009006999999999999 -0.108776 -0.025001 -0.011478 -0.10759 -0.025001 -0.006536 -0.109962 -0.020001 -0.009006999999999999 -0.108776 -0.025001 -0.006536 -0.109962 -0.015001 -0.006536 -0.109962 -0.020001 -0.009006999999999999 -0.108776 -0.015001 -0.022293 -0.104332 -0.015001 -0.017353 -0.110032 0.014999 -0.017353 -0.110032 -0.015001 -0.022293 -0.104332 0.014999 -0.017353 -0.110032 0.014999 -0.022293 -0.104332 -0.015001 0.000163659 -0.06911119999999997 -0.015001 0.001149 -0.06903599999999997 -0.025001 0.001149 -0.06903599999999997 -0.015001 -0.0002175 -0.06914019999999997 -0.015001 0.000163659 -0.06911119999999997 -0.025001 0.001149 -0.06903599999999997 -0.015001 -0.001903 -0.06792799999999997 -0.015001 -0.00210479 -0.06928419999999998 -0.015001 -0.00183603 -0.06793109999999997 -0.015001 -0.004317 -0.06945299999999997 -0.015001 -0.004501 -0.06951769999999997 -0.015001 -0.00411044 -0.06828649999999997 -0.015001 -0.00210479 -0.06928419999999998 -0.015001 -0.004317 -0.06945299999999997 -0.015001 -0.00316851 -0.06872279999999997 -0.015001 -0.00411044 -0.06828649999999997 -0.015001 -0.001903 -0.06792799999999997 -0.015001 -0.00316851 -0.06872279999999997 -0.015001 -0.004317 -0.06945299999999997 -0.015001 -0.00411044 -0.06828649999999997 -0.015001 -0.00316851 -0.06872279999999997 -0.015001 -0.001903 -0.06792799999999997 -0.015001 -0.00210479 -0.06928419999999998 -0.015001 -0.00316851 -0.06872279999999997 -0.015001 0.000163659 -0.06911119999999997 -0.015001 -0.0002175 -0.06914019999999997 -0.015001 0.000254233 -0.06802639999999997 -0.015001 -0.00210479 -0.06928419999999998 -0.015001 -0.00183603 -0.06793109999999997 -0.015001 -0.000925279 -0.06860759999999998 -0.015001 -0.00183603 -0.06793109999999997 -0.015001 0.000254233 -0.06802639999999997 -0.015001 -0.000925279 -0.06860759999999998 -0.015001 -0.0002175 -0.06914019999999997 -0.015001 -0.00210479 -0.06928419999999998 -0.015001 -0.000925279 -0.06860759999999998 -0.015001 0.000254233 -0.06802639999999997 -0.015001 -0.0002175 -0.06914019999999997 -0.015001 -0.000925279 -0.06860759999999998 -0.025001 0.001149 -0.06903599999999997 -0.025001 -0.011478 -0.10759 -0.025001 -0.004317 -0.06945299999999997 -9.982790000000001e-07 0.007 -0.01150499999999997 -0.004402 0.023 -0.01062899999999997 -9.982949999999999e-07 0.023 -0.01150499999999997 -0.020924 0.023 -0.006802999999999972 -0.019001 0.023 -0.01109499999999997 -0.004402 0.023 -0.01062899999999997 -0.022001 0.045 -5.002229999972244e-06 -0.020924 0.045 -0.006802999999999972 -0.020924 0.023 -0.006802999999999972 -0.015001 -0.025426 -0.09747099999999997 -0.015001 -0.022293 -0.104332 0.014999 -0.022293 -0.104332 -0.015001 -0.0209149 -0.08955199999999998 -0.015001 -0.025426 -0.09747099999999997 -0.015001 -0.0265 -0.09000499999999997 -0.015001 -0.019957 -0.08346799999999997 -0.015001 -0.0202098 -0.08481499999999997 -0.015001 -0.0265 -0.09000499999999997 -0.015001 -0.0202098 -0.08481499999999997 -0.015001 -0.020968 -0.08885599999999998 -0.015001 -0.0265 -0.09000499999999997 -0.015001 -0.020968 -0.08885599999999998 -0.015001 -0.0209149 -0.08955199999999998 -0.015001 -0.0265 -0.09000499999999997 -0.015001 -0.019957 -0.08346799999999997 -0.015001 -0.0265 -0.09000499999999997 -0.015001 -0.018178 -0.07976149999999997 -0.015001 -0.008591 -0.06788599999999997 -0.015001 -0.011147 -0.07240479999999998 -0.015001 -0.00857579 -0.06789119999999997 -0.015001 -0.008591 -0.06788599999999997 -0.015001 -0.011147 -0.07240479999999998 -0.015001 -0.010058 -0.06659899999999998 -0.015001 -0.011147 -0.07240479999999998 -0.015001 -0.014015 -0.07436599999999997 -0.015001 -0.0100641 -0.06658659999999997 -0.015001 -0.014015 -0.07436599999999997 -0.015001 -0.0149075 -0.07540599999999997 -0.015001 -0.0100641 -0.06658659999999997 -0.015001 -0.0100641 -0.06658659999999997 -0.015001 -0.011147 -0.07240479999999998 -0.015001 -0.010058 -0.06659899999999998 -0.015001 -0.017585 -0.07852599999999997 -0.015001 -0.0265 -0.09000499999999997 -0.015001 -0.0100641 -0.06658659999999997 -0.015001 -0.0149075 -0.07540599999999997 -0.015001 -0.017585 -0.07852599999999997 -0.015001 -0.0100641 -0.06658659999999997 -0.015001 -0.018178 -0.07976149999999997 -0.015001 -0.0265 -0.09000499999999997 -0.015001 -0.017585 -0.07852599999999997 -0.022001 0.045 -5.002229999972244e-06 0.020922 0.045 0.006794000000000027 0.021999 0.045 -5.002229999972244e-06 0.021999 0.045 -5.002229999972244e-06 0.020922 0.023 0.006794000000000027 0.021999 0.023 -5.001269999972245e-06 0.011499 0.023 -5.001269999972245e-06 0.010624 0.023 -0.004405999999999972 0.021999 0.023 -5.001269999972245e-06 0.008130999999999999 0.023 -0.008135999999999971 0.010624 0.023 -0.004405999999999972 0.010624 0.007 -0.004405999999999972 0.008130999999999999 0.023 -0.008135999999999971 0.010624 0.007 -0.004405999999999972 0.008130999999999999 0.007 -0.008135999999999971 0.008130999999999999 0.007 -0.008135999999999971 0.0044 0.007 -0.01062899999999997 0.0044 0.023 -0.01062899999999997 0.0044 0.007 -0.01062899999999997 -9.982790000000001e-07 0.007 -0.01150499999999997 -9.982949999999999e-07 0.023 -0.01150499999999997 -0.015001 -0.0102425 -0.108183 -0.015001 -0.0114782 -0.10759 -0.025001 -0.011478 -0.10759 -0.015001 -0.018733 -0.09949399999999997 -0.015001 -0.022293 -0.104332 -0.015001 -0.0193665 -0.09769219999999998 -0.015001 -0.015639 -0.10402 -0.015001 -0.0154872 -0.10415 -0.015001 -0.0188901 -0.103862 -0.015001 -0.0154872 -0.10415 -0.015001 -0.017353 -0.110032 -0.015001 -0.0188901 -0.103862 -0.015001 -0.017353 -0.110032 -0.015001 -0.022293 -0.104332 -0.015001 -0.0188901 -0.103862 -0.015001 -0.018733 -0.09949399999999997 -0.015001 -0.0179595 -0.100626 -0.015001 -0.0188901 -0.103862 -0.015001 -0.0179595 -0.100626 -0.015001 -0.015639 -0.10402 -0.015001 -0.0188901 -0.103862 -0.015001 -0.022293 -0.104332 -0.015001 -0.018733 -0.09949399999999997 -0.015001 -0.0188901 -0.103862 -0.015001 -0.0154872 -0.10415 -0.015001 -0.015639 -0.10402 -0.025001 -0.015639 -0.10402 -0.015001 -0.014599 -0.104912 -0.015001 -0.0154872 -0.10415 -0.025001 -0.015639 -0.10402 -0.015001 -0.0114782 -0.10759 -0.015001 -0.014599 -0.104912 -0.020001 -0.0135586 -0.105805 -0.015001 -0.014599 -0.104912 -0.025001 -0.015639 -0.10402 -0.020001 -0.0135586 -0.105805 -0.025001 -0.015639 -0.10402 -0.025001 -0.011478 -0.10759 -0.020001 -0.0135586 -0.105805 -0.025001 -0.011478 -0.10759 -0.015001 -0.0114782 -0.10759 -0.020001 -0.0135586 -0.105805 -0.015001 -0.00210479 -0.06928419999999998 -0.015001 -0.0002175 -0.06914019999999997 -0.020001 -0.001584 -0.06924449999999997 -0.015001 -0.004317 -0.06945299999999997 -0.015001 -0.00210479 -0.06928419999999998 -0.020001 -0.001584 -0.06924449999999997 -0.015001 -0.0002175 -0.06914019999999997 -0.025001 0.001149 -0.06903599999999997 -0.020001 -0.001584 -0.06924449999999997 -0.025001 -0.004317 -0.06945299999999997 -0.015001 -0.004317 -0.06945299999999997 -0.020001 -0.001584 -0.06924449999999997 -0.025001 0.001149 -0.06903599999999997 -0.025001 -0.004317 -0.06945299999999997 -0.020001 -0.001584 -0.06924449999999997 -0.015001 -0.00561 -0.06990749999999997 -0.015001 -0.004501 -0.06951769999999997 -0.025001 -0.004317 -0.06945299999999997 -0.015001 -0.004501 -0.06951769999999997 -0.015001 -0.004317 -0.06945299999999997 -0.025001 -0.004317 -0.06945299999999997 -0.015001 -0.00411044 -0.06828649999999997 -0.015001 -0.004501 -0.06951769999999997 -0.015001 -0.004945 -0.06842199999999997 -0.015001 -0.00561 -0.06990749999999997 -0.015001 -0.0073972 -0.07053569999999998 -0.015001 -0.00575382 -0.06941109999999998 -0.015001 -0.0073972 -0.07053569999999998 -0.015001 -0.00650024 -0.06850069999999997 -0.015001 -0.00575382 -0.06941109999999998 -0.015001 -0.00650024 -0.06850069999999997 -0.015001 -0.004945 -0.06842199999999997 -0.015001 -0.00575382 -0.06941109999999998 -0.015001 -0.004501 -0.06951769999999997 -0.015001 -0.00561 -0.06990749999999997 -0.015001 -0.00575382 -0.06941109999999998 -0.015001 -0.004945 -0.06842199999999997 -0.015001 -0.004501 -0.06951769999999997 -0.015001 -0.00575382 -0.06941109999999998 -0.025001 -0.004317 -0.06945299999999997 -0.025001 -0.011478 -0.10759 -0.025001 -0.009488999999999999 -0.07127099999999997 -9.982790000000001e-07 0.007 -0.01150499999999997 -0.004402 0.007 -0.01062899999999997 -0.004402 0.023 -0.01062899999999997 -0.008133 0.023 -0.008135999999999971 -0.020924 0.023 -0.006802999999999972 -0.004402 0.023 -0.01062899999999997 -0.022001 0.045 -5.002229999972244e-06 -0.020924 0.023 -0.006802999999999972 -0.022001 0.023 -5.001269999972245e-06 -0.015001 -0.020551 -0.09432299999999998 -0.015001 -0.025426 -0.09747099999999997 -0.015001 -0.0208637 -0.09022269999999998 -0.015001 -0.0208637 -0.09022269999999998 -0.015001 -0.025426 -0.09747099999999997 -0.015001 -0.0209149 -0.08955199999999998 -0.015001 -0.0193665 -0.09769219999999998 -0.015001 -0.022293 -0.104332 -0.015001 -0.0223962 -0.09694199999999997 -0.015001 -0.022293 -0.104332 -0.015001 -0.025426 -0.09747099999999997 -0.015001 -0.0223962 -0.09694199999999997 -0.015001 -0.020551 -0.09432299999999998 -0.015001 -0.0200965 -0.09561579999999997 -0.015001 -0.0223962 -0.09694199999999997 -0.015001 -0.0200965 -0.09561579999999997 -0.015001 -0.0193665 -0.09769219999999998 -0.015001 -0.0223962 -0.09694199999999997 -0.015001 -0.025426 -0.09747099999999997 -0.015001 -0.020551 -0.09432299999999998 -0.015001 -0.0223962 -0.09694199999999997 -0.015001 -0.00650024 -0.06850069999999997 -0.015001 -0.0073972 -0.07053569999999998 -0.015001 -0.006744 -0.06851299999999998 -0.015001 -0.00857579 -0.06789119999999997 -0.015001 -0.0106205 -0.07204479999999998 -0.015001 -0.011147 -0.07240479999999998 -0.015001 -0.009488999999999999 -0.07127099999999997 -0.015001 -0.0106205 -0.07204479999999998 -0.015001 -0.008823610000000001 -0.07014799999999997 -0.015001 -0.00857579 -0.06789119999999997 -0.015001 -0.006744 -0.06851299999999998 -0.015001 -0.008823610000000001 -0.07014799999999997 -0.015001 -0.0073972 -0.07053569999999998 -0.015001 -0.009488999999999999 -0.07127099999999997 -0.015001 -0.008823610000000001 -0.07014799999999997 -0.015001 -0.006744 -0.06851299999999998 -0.015001 -0.0073972 -0.07053569999999998 -0.015001 -0.008823610000000001 -0.07014799999999997 -0.015001 -0.0106205 -0.07204479999999998 -0.015001 -0.00857579 -0.06789119999999997 -0.015001 -0.008823610000000001 -0.07014799999999997 -0.015001 -0.014015 -0.07436599999999997 -0.015001 -0.011147 -0.07240479999999998 -0.020001 -0.011752 -0.07281849999999997 -0.015001 -0.011147 -0.07240479999999998 -0.015001 -0.0106205 -0.07204479999999998 -0.020001 -0.011752 -0.07281849999999997 -0.015001 -0.0106205 -0.07204479999999998 -0.025001 -0.009488999999999999 -0.07127099999999997 -0.020001 -0.011752 -0.07281849999999997 -0.025001 -0.009488999999999999 -0.07127099999999997 -0.025001 -0.014015 -0.07436599999999997 -0.020001 -0.011752 -0.07281849999999997 -0.025001 -0.014015 -0.07436599999999997 -0.015001 -0.014015 -0.07436599999999997 -0.020001 -0.011752 -0.07281849999999997 -0.025001 -0.014015 -0.07436599999999997 -0.015001 -0.0149075 -0.07540599999999997 -0.015001 -0.014015 -0.07436599999999997 -0.015001 -0.017585 -0.07852599999999997 -0.015001 -0.0149075 -0.07540599999999997 -0.020001 -0.0158 -0.07644599999999997 -0.015001 -0.0149075 -0.07540599999999997 -0.025001 -0.014015 -0.07436599999999997 -0.020001 -0.0158 -0.07644599999999997 -0.025001 -0.014015 -0.07436599999999997 -0.025001 -0.017585 -0.07852599999999997 -0.020001 -0.0158 -0.07644599999999997 -0.025001 -0.017585 -0.07852599999999997 -0.015001 -0.017585 -0.07852599999999997 -0.020001 -0.0158 -0.07644599999999997 -0.025001 -0.017585 -0.07852599999999997 -0.015001 -0.018178 -0.07976149999999997 -0.015001 -0.017585 -0.07852599999999997 -0.015001 -0.019957 -0.08346799999999997 -0.015001 -0.018178 -0.07976149999999997 -0.020001 -0.018771 -0.08099699999999997 -0.015001 -0.018178 -0.07976149999999997 -0.025001 -0.017585 -0.07852599999999997 -0.020001 -0.018771 -0.08099699999999997 -0.025001 -0.017585 -0.07852599999999997 -0.025001 -0.019957 -0.08346799999999997 -0.020001 -0.018771 -0.08099699999999997 -0.025001 -0.019957 -0.08346799999999997 -0.015001 -0.019957 -0.08346799999999997 -0.020001 -0.018771 -0.08099699999999997 -0.025001 -0.019957 -0.08346799999999997 -0.015001 -0.0202098 -0.08481499999999997 -0.015001 -0.019957 -0.08346799999999997 -0.015001 -0.020968 -0.08885599999999998 -0.015001 -0.0202098 -0.08481499999999997 -0.020001 -0.0204625 -0.08616199999999997 -0.015001 -0.0202098 -0.08481499999999997 -0.025001 -0.019957 -0.08346799999999997 -0.020001 -0.0204625 -0.08616199999999997 -0.025001 -0.019957 -0.08346799999999997 -0.025001 -0.020968 -0.08885599999999998 -0.020001 -0.0204625 -0.08616199999999997 -0.025001 -0.020968 -0.08885599999999998 -0.015001 -0.020968 -0.08885599999999998 -0.020001 -0.0204625 -0.08616199999999997 -0.025001 -0.020968 -0.08885599999999998 -0.015001 -0.0208637 -0.09022269999999998 -0.015001 -0.0209149 -0.08955199999999998 -0.025001 -0.020968 -0.08885599999999998 -0.015001 -0.0209149 -0.08955199999999998 -0.015001 -0.020968 -0.08885599999999998 -0.022001 0.045 -5.002229999972244e-06 -0.020924 0.045 0.006794000000000027 0.020922 0.045 0.006794000000000027 0.021999 0.045 -5.002229999972244e-06 0.020922 0.045 0.006794000000000027 0.020922 0.023 0.006794000000000027 0.011499 0.023 -5.001269999972245e-06 0.021999 0.023 -5.001269999972245e-06 0.020922 0.023 0.006794000000000027 0.010624 0.023 -0.004405999999999972 0.011499 0.023 -5.001269999972245e-06 0.011499 0.007 -5.000569999972244e-06 0.010624 0.023 -0.004405999999999972 0.011499 0.007 -5.000569999972244e-06 0.010624 0.007 -0.004405999999999972 -0.010626 0.007 -0.004405999999999972 0.008130999999999999 0.007 -0.008135999999999971 0.010624 0.007 -0.004405999999999972 -0.010626 0.007 -0.004405999999999972 0.0044 0.007 -0.01062899999999997 0.008130999999999999 0.007 -0.008135999999999971 -0.010626 0.007 -0.004405999999999972 -9.982790000000001e-07 0.007 -0.01150499999999997 0.0044 0.007 -0.01062899999999997 -0.015001 -0.0193665 -0.09769219999999998 -0.015001 -0.0200965 -0.09561579999999997 -0.020001 -0.019642 -0.09690849999999997 -0.015001 -0.0200965 -0.09561579999999997 -0.025001 -0.020551 -0.09432299999999998 -0.020001 -0.019642 -0.09690849999999997 -0.025001 -0.020551 -0.09432299999999998 -0.025001 -0.018733 -0.09949399999999997 -0.020001 -0.019642 -0.09690849999999997 -0.025001 -0.018733 -0.09949399999999997 -0.015001 -0.018733 -0.09949399999999997 -0.020001 -0.019642 -0.09690849999999997 -0.015001 -0.018733 -0.09949399999999997 -0.015001 -0.0193665 -0.09769219999999998 -0.020001 -0.019642 -0.09690849999999997 -0.025001 -0.018733 -0.09949399999999997 -0.015001 -0.0179595 -0.100626 -0.015001 -0.018733 -0.09949399999999997 -0.015001 -0.015639 -0.10402 -0.015001 -0.0179595 -0.100626 -0.020001 -0.017186 -0.101757 -0.015001 -0.0179595 -0.100626 -0.025001 -0.018733 -0.09949399999999997 -0.020001 -0.017186 -0.101757 -0.025001 -0.018733 -0.09949399999999997 -0.025001 -0.015639 -0.10402 -0.020001 -0.017186 -0.101757 -0.025001 -0.015639 -0.10402 -0.015001 -0.015639 -0.10402 -0.020001 -0.017186 -0.101757 -0.025001 -0.015639 -0.10402 -0.025001 -0.018733 -0.09949399999999997 -0.025001 -0.011478 -0.10759 -0.015001 -0.009488999999999999 -0.07127099999999997 -0.015001 -0.0073972 -0.07053569999999998 -0.020001 -0.006903 -0.07036199999999997 -0.025001 -0.009488999999999999 -0.07127099999999997 -0.015001 -0.009488999999999999 -0.07127099999999997 -0.020001 -0.006903 -0.07036199999999997 -0.015001 -0.0073972 -0.07053569999999998 -0.015001 -0.00561 -0.06990749999999997 -0.020001 -0.006903 -0.07036199999999997 -0.025001 -0.004317 -0.06945299999999997 -0.025001 -0.009488999999999999 -0.07127099999999997 -0.020001 -0.006903 -0.07036199999999997 -0.015001 -0.00561 -0.06990749999999997 -0.025001 -0.004317 -0.06945299999999997 -0.020001 -0.006903 -0.07036199999999997 -0.025001 -0.009488999999999999 -0.07127099999999997 -0.025001 -0.011478 -0.10759 -0.025001 -0.014015 -0.07436599999999997 -0.010626 0.007 -0.004405999999999972 -0.004402 0.007 -0.01062899999999997 -9.982790000000001e-07 0.007 -0.01150499999999997 -0.004402 0.007 -0.01062899999999997 -0.008133 0.023 -0.008135999999999971 -0.004402 0.023 -0.01062899999999997 -0.020924 0.023 -0.006802999999999972 -0.008133 0.023 -0.008135999999999971 -0.010626 0.023 -0.004405999999999972 -0.020924 0.045 0.006794000000000027 -0.022001 0.045 -5.002229999972244e-06 -0.022001 0.023 -5.001269999972245e-06 -0.022001 0.023 -5.001269999972245e-06 -0.020924 0.023 -0.006802999999999972 -0.010626 0.023 -0.004405999999999972 -0.015001 -0.020551 -0.09432299999999998 -0.015001 -0.0208637 -0.09022269999999998 -0.020001 -0.0207595 -0.09158949999999998 -0.015001 -0.0208637 -0.09022269999999998 -0.025001 -0.020968 -0.08885599999999998 -0.020001 -0.0207595 -0.09158949999999998 -0.025001 -0.020968 -0.08885599999999998 -0.025001 -0.020551 -0.09432299999999998 -0.020001 -0.0207595 -0.09158949999999998 -0.025001 -0.020551 -0.09432299999999998 -0.015001 -0.020551 -0.09432299999999998 -0.020001 -0.0207595 -0.09158949999999998 -0.025001 -0.020551 -0.09432299999999998 -0.015001 -0.0200965 -0.09561579999999997 -0.015001 -0.020551 -0.09432299999999998 -0.015001 -0.0106205 -0.07204479999999998 -0.015001 -0.009488999999999999 -0.07127099999999997 -0.025001 -0.009488999999999999 -0.07127099999999997 -0.025001 -0.011478 -0.10759 -0.025001 -0.017585 -0.07852599999999997 -0.025001 -0.014015 -0.07436599999999997 -0.025001 -0.011478 -0.10759 -0.025001 -0.019957 -0.08346799999999997 -0.025001 -0.017585 -0.07852599999999997 -0.025001 -0.011478 -0.10759 -0.025001 -0.020968 -0.08885599999999998 -0.025001 -0.019957 -0.08346799999999997 -0.020924 0.045 0.006794000000000027 0.017797 0.045 0.01292700000000003 0.020922 0.045 0.006794000000000027 0.020922 0.045 0.006794000000000027 0.017797 0.023 0.01292700000000003 0.020922 0.023 0.006794000000000027 0.010624 0.023 0.004396000000000027 0.011499 0.023 -5.001269999972245e-06 0.020922 0.023 0.006794000000000027 0.011499 0.023 -5.001269999972245e-06 0.010624 0.007 0.004396000000000027 0.011499 0.007 -5.000569999972244e-06 -0.010626 0.007 -0.004405999999999972 0.010624 0.007 -0.004405999999999972 0.011499 0.007 -5.000569999972244e-06 -0.025001 -0.018733 -0.09949399999999997 -0.025001 -0.020551 -0.09432299999999998 -0.025001 -0.011478 -0.10759 -0.004402 0.007 -0.01062899999999997 -0.010626 0.007 -0.004405999999999972 -0.008133 0.007 -0.008135999999999971 -0.004402 0.007 -0.01062899999999997 -0.008133 0.007 -0.008135999999999971 -0.008133 0.023 -0.008135999999999971 -0.010626 0.023 -0.004405999999999972 -0.008133 0.023 -0.008135999999999971 -0.008133 0.007 -0.008135999999999971 -0.020924 0.045 0.006794000000000027 -0.022001 0.023 -5.001269999972245e-06 -0.020924 0.023 0.006794000000000027 -0.022001 0.023 -5.001269999972245e-06 -0.010626 0.023 -0.004405999999999972 -0.011501 0.023 -5.001269999972245e-06 -0.025001 -0.011478 -0.10759 -0.025001 -0.020551 -0.09432299999999998 -0.025001 -0.020968 -0.08885599999999998 -0.020924 0.045 0.006794000000000027 -0.017799 0.045 0.01292700000000003 0.017797 0.045 0.01292700000000003 0.020922 0.045 0.006794000000000027 0.017797 0.045 0.01292700000000003 0.017797 0.023 0.01292700000000003 0.008130999999999999 0.023 0.008127000000000028 0.020922 0.023 0.006794000000000027 0.017797 0.023 0.01292700000000003 0.008130999999999999 0.023 0.008127000000000028 0.010624 0.023 0.004396000000000027 0.020922 0.023 0.006794000000000027 0.011499 0.023 -5.001269999972245e-06 0.010624 0.023 0.004396000000000027 0.010624 0.007 0.004396000000000027 -0.010626 0.007 -0.004405999999999972 0.011499 0.007 -5.000569999972244e-06 0.010624 0.007 0.004396000000000027 -0.010626 0.023 -0.004405999999999972 -0.008133 0.007 -0.008135999999999971 -0.010626 0.007 -0.004405999999999972 -0.017799 0.045 0.01292700000000003 -0.020924 0.045 0.006794000000000027 -0.020924 0.023 0.006794000000000027 -0.020924 0.023 0.006794000000000027 -0.022001 0.023 -5.001269999972245e-06 -0.010626 0.023 0.004396000000000027 -0.022001 0.023 -5.001269999972245e-06 -0.011501 0.023 -5.001269999972245e-06 -0.010626 0.023 0.004396000000000027 -0.011501 0.023 -5.001269999972245e-06 -0.010626 0.023 -0.004405999999999972 -0.010626 0.007 -0.004405999999999972 -0.017799 0.045 0.01292700000000003 0.01293 0.045 0.01779400000000003 0.017797 0.045 0.01292700000000003 0.01293 0.023 0.01779400000000003 0.017797 0.023 0.01292700000000003 0.017797 0.045 0.01292700000000003 0.0044 0.023 0.01062000000000003 0.008130999999999999 0.023 0.008127000000000028 0.017797 0.023 0.01292700000000003 0.010624 0.023 0.004396000000000027 0.008130999999999999 0.023 0.008127000000000028 0.008130999999999999 0.007 0.008127000000000028 0.010624 0.023 0.004396000000000027 0.008130999999999999 0.007 0.008127000000000028 0.010624 0.007 0.004396000000000027 -0.010626 0.007 -0.004405999999999972 0.010624 0.007 0.004396000000000027 0.008130999999999999 0.007 0.008127000000000028 -0.017799 0.045 0.01292700000000003 -0.020924 0.023 0.006794000000000027 -0.017799 0.023 0.01292700000000003 -0.020924 0.023 0.006794000000000027 -0.010626 0.023 0.004396000000000027 -0.008133 0.023 0.008127000000000028 -0.010626 0.023 0.004396000000000027 -0.011501 0.023 -5.001269999972245e-06 -0.011501 0.007 -5.000569999972244e-06 -0.011501 0.023 -5.001269999972245e-06 -0.010626 0.007 -0.004405999999999972 -0.011501 0.007 -5.000569999972244e-06 -0.017799 0.045 0.01292700000000003 -0.012932 0.045 0.01779400000000003 0.01293 0.045 0.01779400000000003 0.01293 0.023 0.01779400000000003 0.017797 0.045 0.01292700000000003 0.01293 0.045 0.01779400000000003 0.01293 0.023 0.01779400000000003 -0.017799 0.023 0.01292700000000003 0.017797 0.023 0.01292700000000003 0.0044 0.023 0.01062000000000003 0.017797 0.023 0.01292700000000003 -9.97102e-07 0.023 0.01149500000000003 0.0044 0.007 0.01062000000000003 0.008130999999999999 0.023 0.008127000000000028 0.0044 0.023 0.01062000000000003 0.0044 0.007 0.01062000000000003 0.008130999999999999 0.007 0.008127000000000028 0.008130999999999999 0.023 0.008127000000000028 0.0044 0.007 0.01062000000000003 -0.010626 0.007 -0.004405999999999972 0.008130999999999999 0.007 0.008127000000000028 -0.017799 0.023 0.01292700000000003 -0.012932 0.045 0.01779400000000003 -0.017799 0.045 0.01292700000000003 -0.017799 0.023 0.01292700000000003 -0.020924 0.023 0.006794000000000027 -0.008133 0.023 0.008127000000000028 -0.008133 0.023 0.008127000000000028 -0.010626 0.023 0.004396000000000027 -0.010626 0.007 0.004396000000000027 -0.010626 0.023 0.004396000000000027 -0.011501 0.007 -5.000569999972244e-06 -0.010626 0.007 0.004396000000000027 -0.011501 0.007 -5.000569999972244e-06 -0.010626 0.007 -0.004405999999999972 -0.010626 0.007 0.004396000000000027 0.006797 0.045 0.02091800000000003 0.01293 0.045 0.01779400000000003 -0.012932 0.045 0.01779400000000003 0.006797 0.023 0.02091800000000003 0.01293 0.023 0.01779400000000003 0.01293 0.045 0.01779400000000003 -0.012932 0.023 0.01779400000000003 -0.017799 0.023 0.01292700000000003 0.01293 0.023 0.01779400000000003 -9.97102e-07 0.023 0.01149500000000003 0.017797 0.023 0.01292700000000003 -0.017799 0.023 0.01292700000000003 -9.97087e-07 0.007 0.01149500000000003 0.0044 0.023 0.01062000000000003 -9.97102e-07 0.023 0.01149500000000003 -9.97087e-07 0.007 0.01149500000000003 0.0044 0.007 0.01062000000000003 0.0044 0.023 0.01062000000000003 -9.97087e-07 0.007 0.01149500000000003 -0.010626 0.007 -0.004405999999999972 0.0044 0.007 0.01062000000000003 -0.017799 0.023 0.01292700000000003 -0.012932 0.023 0.01779400000000003 -0.012932 0.045 0.01779400000000003 -0.017799 0.023 0.01292700000000003 -0.008133 0.023 0.008127000000000028 -0.004402 0.023 0.01062000000000003 -0.008133 0.023 0.008127000000000028 -0.010626 0.007 0.004396000000000027 -0.008133 0.007 0.008127000000000028 -0.010626 0.007 0.004396000000000027 -0.010626 0.007 -0.004405999999999972 -0.008133 0.007 0.008127000000000028 -0.006799 0.045 0.02091800000000003 0.006797 0.045 0.02091800000000003 -0.012932 0.045 0.01779400000000003 0.006797 0.023 0.02091800000000003 0.01293 0.045 0.01779400000000003 0.006797 0.045 0.02091800000000003 0.01293 0.023 0.01779400000000003 0.006797 0.023 0.02091800000000003 -0.012932 0.023 0.01779400000000003 -9.97102e-07 0.023 0.01149500000000003 -0.017799 0.023 0.01292700000000003 -0.004402 0.023 0.01062000000000003 -0.004402 0.007 0.01062000000000003 -9.97087e-07 0.007 0.01149500000000003 -9.97102e-07 0.023 0.01149500000000003 -0.004402 0.007 0.01062000000000003 -0.010626 0.007 -0.004405999999999972 -9.97087e-07 0.007 0.01149500000000003 -0.012932 0.023 0.01779400000000003 -0.006799 0.045 0.02091800000000003 -0.012932 0.045 0.01779400000000003 -0.008133 0.007 0.008127000000000028 -0.004402 0.023 0.01062000000000003 -0.008133 0.023 0.008127000000000028 -0.008133 0.007 0.008127000000000028 -0.010626 0.007 -0.004405999999999972 -0.004402 0.007 0.01062000000000003 -9.96856e-07 0.045 0.02199500000000003 0.006797 0.045 0.02091800000000003 -0.006799 0.045 0.02091800000000003 -9.96864e-07 0.023 0.02199500000000003 0.006797 0.023 0.02091800000000003 0.006797 0.045 0.02091800000000003 -0.012932 0.023 0.01779400000000003 0.006797 0.023 0.02091800000000003 -0.006799 0.023 0.02091800000000003 -0.004402 0.007 0.01062000000000003 -9.97102e-07 0.023 0.01149500000000003 -0.004402 0.023 0.01062000000000003 -0.012932 0.023 0.01779400000000003 -0.006799 0.023 0.02091800000000003 -0.006799 0.045 0.02091800000000003 -0.008133 0.007 0.008127000000000028 -0.004402 0.007 0.01062000000000003 -0.004402 0.023 0.01062000000000003 -0.006799 0.023 0.02091800000000003 -9.96856e-07 0.045 0.02199500000000003 -0.006799 0.045 0.02091800000000003 -9.96864e-07 0.023 0.02199500000000003 0.006797 0.045 0.02091800000000003 -9.96856e-07 0.045 0.02199500000000003 0.006797 0.023 0.02091800000000003 -9.96864e-07 0.023 0.02199500000000003 -0.006799 0.023 0.02091800000000003 -0.006799 0.023 0.02091800000000003 -9.96864e-07 0.023 0.02199500000000003 -9.96856e-07 0.045 0.02199500000000003 0.033499 0.035397 -0.05842899999999997 0.033499 0.036284 -0.05372699999999997 0.033499 0.021268 -0.09766299999999997 0.033499 0.036284 -0.05372699999999997 0.033499 0.035601 -0.04880199999999997 0.033499 0.021268 -0.09766299999999997 0.014999 0.021876 -0.09788199999999997 0.033499 0.035397 -0.05842899999999997 0.033499 0.021268 -0.09766299999999997 0.014999 0.036005 -0.05864799999999997 0.033499 0.036284 -0.05372699999999997 0.033499 0.035397 -0.05842899999999997 0.033499 0.035601 -0.04880199999999997 0.033499 0.033356 -0.04436599999999997 0.033499 0.021268 -0.09766299999999997 0.014999 0.03693 -0.05374499999999997 0.033499 0.035601 -0.04880199999999997 0.033499 0.036284 -0.05372699999999997 0.014999 0.021532 -0.09877999999999998 0.014999 0.021876 -0.09788199999999997 0.033499 0.021268 -0.09766299999999997 0.014999 0.036005 -0.05864799999999997 0.033499 0.035397 -0.05842899999999997 0.014999 0.0222876 -0.09673899999999998 0.014999 0.0222876 -0.09673899999999998 0.033499 0.035397 -0.05842899999999997 0.014999 0.021876 -0.09788199999999997 0.014999 0.0368802 -0.05400919999999997 0.014999 0.03693 -0.05374499999999997 0.033499 0.036284 -0.05372699999999997 0.014999 0.036005 -0.05864799999999997 0.014999 0.0368802 -0.05400919999999997 0.033499 0.036284 -0.05372699999999997 0.033499 0.033356 -0.04436599999999997 0.033499 0.029792 -0.04089899999999997 0.033499 0.021268 -0.09766299999999997 0.0151152 0.0362 -0.04858329999999998 0.033499 0.033356 -0.04436599999999997 0.033499 0.035601 -0.04880199999999997 0.0151123 0.0362142 -0.04861119999999997 0.0151152 0.0362 -0.04858329999999998 0.033499 0.035601 -0.04880199999999997 0.014999 0.03693 -0.05374499999999997 0.014999 0.0363698 -0.04970499999999997 0.033499 0.035601 -0.04880199999999997 0.014999 0.0363698 -0.04970499999999997 0.0151123 0.0362142 -0.04861119999999997 0.033499 0.035601 -0.04880199999999997 0.014999 0.021532 -0.09877999999999998 0.033499 0.021268 -0.09766299999999997 0.033499 0.020933 -0.09853599999999997 0.033499 0.029792 -0.04089899999999997 0.033499 0.025296 -0.03877599999999997 0.033499 0.021268 -0.09766299999999997 0.033499 0.033356 -0.04436599999999997 0.0155905 0.0338603 -0.04399519999999997 0.0155979 0.0337867 -0.04392399999999997 0.033499 0.029792 -0.04089899999999997 0.033499 0.033356 -0.04436599999999997 0.0156022 0.0337438 -0.04388249999999997 0.033499 0.033356 -0.04436599999999997 0.0155979 0.0337867 -0.04392399999999997 0.0156022 0.0337438 -0.04388249999999997 0.0151152 0.0362 -0.04858329999999998 0.0155905 0.0338603 -0.04399519999999997 0.033499 0.033356 -0.04436599999999997 0.014999 0.0207306 -0.100168 0.014999 0.021532 -0.09877999999999998 0.033499 0.020933 -0.09853599999999997 0.014999 0.018366 -0.104264 0.014999 0.0207306 -0.100168 0.033499 0.020933 -0.09853599999999997 0.033499 0.017855 -0.103868 0.033499 0.020933 -0.09853599999999997 0.033499 0.021268 -0.09766299999999997 0.033499 0.025296 -0.03877599999999997 0.033499 0.020353 -0.03822899999999997 0.033499 0.021268 -0.09766299999999997 0.033499 0.025296 -0.03877599999999997 0.033499 0.029792 -0.04089899999999997 0.0159749 0.0299034 -0.04028399999999997 0.033499 0.029792 -0.04089899999999997 0.0159634 0.0301408 -0.04039569999999997 0.0159749 0.0299034 -0.04028399999999997 0.033499 0.029792 -0.04089899999999997 0.0156022 0.0337438 -0.04388249999999997 0.0159634 0.0301408 -0.04039569999999997 0.014999 0.018366 -0.104264 0.033499 0.020933 -0.09853599999999997 0.033499 0.017855 -0.103868 0.033499 0.017855 -0.103868 0.014999 0.013837 -0.10869 0.014999 0.016369 -0.106216 0.033499 0.017855 -0.103868 0.014999 0.016369 -0.106216 0.014999 0.018366 -0.104264 0.033499 0.013453 -0.108171 0.033499 0.017855 -0.103868 0.033499 0.021268 -0.09766299999999997 0.033499 0.020353 -0.03822899999999997 0.033499 0.015501 -0.03931699999999997 0.033499 0.021268 -0.09766299999999997 0.033499 0.020353 -0.03822899999999997 0.033499 0.025296 -0.03877599999999997 0.016195 0.0251401 -0.03815979999999997 0.033499 0.025296 -0.03877599999999997 0.0161913 0.0254597 -0.03819499999999997 0.016195 0.0251401 -0.03815979999999997 0.033499 0.025296 -0.03877599999999997 0.0159749 0.0299034 -0.04028399999999997 0.0161913 0.0254597 -0.03819499999999997 0.033499 0.020353 -0.03822899999999997 0.016195 0.0251401 -0.03815979999999997 0.0162152 0.0233709 -0.03796439999999997 0.033499 0.020353 -0.03822899999999997 0.0162152 0.0233709 -0.03796439999999997 0.0162501 0.0203204 -0.03762759999999997 0.033499 0.017855 -0.103868 0.033499 0.013453 -0.108171 0.014999 0.013837 -0.10869 0.033499 0.013453 -0.108171 0.014999 0.008283 -0.11173 0.014999 0.0104947 -0.110519 0.033499 0.013453 -0.108171 0.014999 0.0104947 -0.110519 0.014999 0.013837 -0.10869 0.033499 0.008052999999999999 -0.111127 0.033499 0.013453 -0.108171 0.033499 0.021268 -0.09766299999999997 0.033499 0.015501 -0.03931699999999997 0.033499 0.011265 -0.04192099999999997 0.033499 0.021268 -0.09766299999999997 0.033499 0.015501 -0.03931699999999997 0.033499 0.020353 -0.03822899999999997 0.0162426 0.0199942 -0.03770049999999997 0.033499 0.020353 -0.03822899999999997 0.0162501 0.0203204 -0.03762759999999997 0.0162426 0.0199942 -0.03770049999999997 0.014999 -0.00718103 -0.06247869999999997 0.014999 -0.01776 -0.07499899999999997 0.033499 -0.017266 -0.07541599999999997 0.014999 -0.00718103 -0.06247869999999997 0.033499 -0.017266 -0.07541599999999997 0.014999 -0.00199864 -0.05634529999999997 0.014999 -0.00199864 -0.05634529999999997 0.033499 -0.017266 -0.07541599999999997 0.014999 -0.000209368 -0.05422759999999997 0.033499 -0.017266 -0.07541599999999997 0.0155745 0.00833217 -0.04414979999999998 0.014999 -0.000209368 -0.05422759999999997 0.033499 0.015501 -0.03931699999999997 0.0162426 0.0199942 -0.03770049999999997 0.0161333 0.0152729 -0.03875469999999998 0.033499 0.011265 -0.04192099999999997 0.033499 0.015501 -0.03931699999999997 0.0161171 0.0150167 -0.03891159999999997 0.033499 0.015501 -0.03931699999999997 0.0161333 0.0152729 -0.03875469999999998 0.0161171 0.0150167 -0.03891159999999997 0.033499 0.011265 -0.04192099999999997 0.0161171 0.0150167 -0.03891159999999997 0.0158536 0.0108606 -0.04145549999999997 0.033499 0.011265 -0.04192099999999997 0.0158536 0.0108606 -0.04145549999999997 0.0158458 0.0107864 -0.04153049999999997 0.033499 0.009648 -0.04356299999999997 0.033499 0.011265 -0.04192099999999997 0.0158458 0.0107864 -0.04153049999999997 0.0158458 0.0107864 -0.04153049999999997 0.0156769 0.009172100000000001 -0.04316129999999997 0.033499 0.009648 -0.04356299999999997 0.0156769 0.009172100000000001 -0.04316129999999997 0.0155745 0.00833217 -0.04414979999999998 0.033499 0.009648 -0.04356299999999997 0.0155745 0.00833217 -0.04414979999999998 0.033499 -0.017266 -0.07541599999999997 0.033499 0.009648 -0.04356299999999997 0.033499 0.013453 -0.108171 0.033499 0.008052999999999999 -0.111127 0.014999 0.008283 -0.11173 0.033499 0.008052999999999999 -0.111127 0.014999 0.002115 -0.113159 0.014999 0.00366932 -0.112799 0.033499 0.008052999999999999 -0.111127 0.014999 0.00366932 -0.112799 0.014999 0.008283 -0.11173 0.033499 0.008052999999999999 -0.111127 0.033499 0.021268 -0.09766299999999997 0.033499 0.00205599 -0.112516 -0.015001 0.0110356 -0.07092759999999997 -0.015001 0.009771999999999999 -0.07007799999999997 -0.041001 0.009771999999999999 -0.07007799999999997 -0.015001 0.014744 -0.07342099999999997 -0.015001 0.0110356 -0.07092759999999997 -0.041001 0.009771999999999999 -0.07007799999999997 -0.041001 0.014744 -0.07342099999999997 -0.015001 0.018629 -0.07798099999999997 -0.015001 0.014744 -0.07342099999999997 -0.041001 0.018629 -0.07798099999999997 -0.015001 0.021141 -0.08342099999999997 -0.015001 0.018629 -0.07798099999999997 -0.041001 0.021141 -0.08341999999999997 -0.015001 0.021164 -0.08349599999999997 -0.015001 0.021141 -0.08342099999999997 -0.041001 0.021164 -0.08349599999999997 -0.015001 0.021985 -0.08509899999999997 -0.015001 0.021164 -0.08349599999999997 -0.015001 0.023452 -0.08638599999999998 -0.015001 0.021985 -0.08509899999999997 -0.041001 0.021985 -0.08509899999999997 -0.015001 0.025299 -0.08701299999999997 -0.015001 0.023452 -0.08638599999999998 -0.041001 0.023452 -0.08638599999999998 -0.015001 0.027246 -0.08688499999999998 -0.015001 0.025299 -0.08701299999999997 -0.041001 0.025299 -0.08701299999999997 -0.015001 0.028996 -0.08602199999999997 -0.015001 0.027246 -0.08688499999999998 -0.041001 0.027246 -0.08688499999999998 -0.041001 0.028996 -0.08602199999999997 -0.015001 0.030282 -0.08455499999999998 -0.015001 0.028996 -0.08602199999999997 -0.041001 0.030282 -0.08455499999999998 -0.015001 0.030844 -0.08308599999999997 -0.015001 0.030282 -0.08455499999999998 -0.041001 0.036766 -0.05498099999999997 -0.015001 0.036766 -0.05498099999999997 -0.015001 0.030844 -0.08308599999999997 -0.041001 0.036766 -0.05498099999999997 -0.015001 0.037048 -0.05074599999999997 -0.015001 0.0368311 -0.05400319999999997 -0.041001 0.036766 -0.05498099999999997 -0.015001 0.0368311 -0.05400319999999997 -0.015001 0.036766 -0.05498099999999997 -0.041001 0.037048 -0.05074599999999997 -0.0153411 0.0360611 -0.04642229999999997 -0.015001 0.0368104 -0.04970499999999997 -0.041001 0.037048 -0.05074599999999997 -0.015001 0.0368104 -0.04970499999999997 -0.015001 0.037048 -0.05074599999999997 0.033499 0.011265 -0.04192099999999997 0.033499 0.009648 -0.04356299999999997 0.033499 0.021268 -0.09766299999999997 0.014999 -0.01776 -0.07499899999999997 0.033499 -0.019576 -0.07870199999999997 0.033499 -0.017266 -0.07541599999999997 0.033499 -0.017266 -0.07541599999999997 0.033499 0.021268 -0.09766299999999997 0.033499 0.002001 -0.07061299999999997 0.033499 0.021268 -0.09766299999999997 0.033499 0.009648 -0.04356299999999997 0.033499 0.002001 -0.07061299999999997 0.033499 0.009648 -0.04356299999999997 0.033499 -0.017266 -0.07541599999999997 0.033499 0.002001 -0.07061299999999997 0.033499 0.008052999999999999 -0.111127 0.033499 0.00205599 -0.112516 0.014999 0.002115 -0.113159 0.033499 0.00205599 -0.112516 0.014999 -0.00421101 -0.112871 0.014999 -0.00349286 -0.112904 0.033499 0.00205599 -0.112516 0.014999 -0.00349286 -0.112904 0.014999 0.002115 -0.113159 0.033499 0.00205599 -0.112516 0.033499 0.021268 -0.09766299999999997 0.033499 -0.004094 -0.112236 -0.015001 0.00445068 -0.06832259999999997 -0.015001 0.004082 -0.06820099999999997 -0.041001 0.004082 -0.06819999999999997 -0.015001 0.00678809 -0.06909369999999997 -0.015001 0.00445068 -0.06832259999999997 -0.041001 0.004082 -0.06819999999999997 -0.015001 0.009771999999999999 -0.07007799999999997 -0.015001 0.009385249999999999 -0.06995039999999997 -0.041001 0.004082 -0.06819999999999997 -0.015001 0.009385249999999999 -0.06995039999999997 -0.015001 0.00678809 -0.06909369999999997 -0.041001 0.004082 -0.06819999999999997 -0.015001 0.009771999999999999 -0.07007799999999997 -0.041001 0.004082 -0.06819999999999997 -0.041001 0.009771999999999999 -0.07007799999999997 -0.015001 0.014744 -0.07342099999999997 -0.041001 0.009771999999999999 -0.07007799999999997 -0.041001 0.014744 -0.07342099999999997 -0.041001 0.014744 -0.07342099999999997 -0.041001 0.018629 -0.07798099999999997 -0.015001 0.018629 -0.07798099999999997 -0.041001 0.018629 -0.07798099999999997 -0.041001 0.021141 -0.08341999999999997 -0.015001 0.021141 -0.08342099999999997 -0.041001 0.021141 -0.08341999999999997 -0.041001 0.021164 -0.08349599999999997 -0.015001 0.021164 -0.08349599999999997 -0.041001 0.021164 -0.08349599999999997 -0.041001 0.021985 -0.08509899999999997 -0.015001 0.021985 -0.08509899999999997 -0.015001 0.023452 -0.08638599999999998 -0.041001 0.021985 -0.08509899999999997 -0.041001 0.023452 -0.08638599999999998 -0.015001 0.025299 -0.08701299999999997 -0.041001 0.023452 -0.08638599999999998 -0.041001 0.025299 -0.08701299999999997 -0.015001 0.027246 -0.08688499999999998 -0.041001 0.025299 -0.08701299999999997 -0.041001 0.027246 -0.08688499999999998 -0.015001 0.028996 -0.08602199999999997 -0.041001 0.027246 -0.08688499999999998 -0.041001 0.028996 -0.08602199999999997 -0.041001 0.028996 -0.08602199999999997 -0.041001 0.030282 -0.08455499999999998 -0.015001 0.030282 -0.08455499999999998 -0.041001 0.030282 -0.08455499999999998 -0.041001 0.030844 -0.08308599999999997 -0.015001 0.030844 -0.08308599999999997 -0.041001 0.030844 -0.08308599999999997 -0.041001 0.036766 -0.05498099999999997 -0.015001 0.030844 -0.08308599999999997 -0.041001 0.036766 -0.05498099999999997 -0.041001 0.037048 -0.05074599999999997 -0.015001 0.037048 -0.05074599999999997 -0.041001 0.037048 -0.05074599999999997 -0.041001 0.036048 -0.04636499999999998 -0.0153411 0.0360611 -0.04642229999999997 -0.041001 0.036048 -0.04636499999999998 -0.015347 0.036048 -0.04636499999999998 -0.0153411 0.0360611 -0.04642229999999997 -0.041001 0.036048 -0.04636499999999998 -0.0157386 0.0338657 -0.04258439999999997 -0.0155351 0.0350001 -0.04454949999999997 -0.041001 0.036048 -0.04636499999999998 -0.0155351 0.0350001 -0.04454949999999997 -0.015347 0.036048 -0.04636499999999998 0.014999 -0.023244 -0.09053399999999998 0.033499 -0.022599 -0.09051899999999997 0.024249 -0.022567 -0.08742479999999997 0.014999 -0.0225384 -0.08436039999999997 0.014999 -0.023244 -0.09053399999999998 0.024249 -0.022567 -0.08742479999999997 0.033499 -0.022599 -0.09051899999999997 0.014999 -0.022525 -0.08424299999999997 0.024249 -0.022567 -0.08742479999999997 0.014999 -0.022525 -0.08424299999999997 0.014999 -0.0225384 -0.08436039999999997 0.024249 -0.022567 -0.08742479999999997 0.033499 -0.021899 -0.08440299999999998 0.014999 -0.020135 -0.07837899999999998 0.014999 -0.022525 -0.08424299999999997 0.014999 -0.01776 -0.07499899999999997 0.014999 -0.020135 -0.07837899999999998 0.033499 -0.019576 -0.07870199999999997 0.033499 0.021268 -0.09766299999999997 0.033499 -0.017266 -0.07541599999999997 0.033499 -0.019576 -0.07870199999999997 0.033499 0.00205599 -0.112516 0.033499 -0.004094 -0.112236 0.014999 -0.00421101 -0.112871 0.033499 -0.004094 -0.112236 0.014999 -0.010224 -0.110887 0.014999 -0.00421101 -0.112871 0.033499 -0.009940010000000001 -0.110307 0.014999 -0.015479 -0.107354 0.014999 -0.0103509 -0.110802 0.033499 -0.009940010000000001 -0.110307 0.014999 -0.0103509 -0.110802 0.014999 -0.010224 -0.110887 0.033499 -0.004094 -0.112236 0.033499 0.021268 -0.09766299999999997 0.033499 -0.009940010000000001 -0.110307 -0.015001 0.004082 -0.06820099999999997 -0.041001 -0.001903 -0.06792799999999997 -0.041001 0.004082 -0.06819999999999997 -0.041001 0.009771999999999999 -0.07007799999999997 -0.041001 0.004082 -0.06819999999999997 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.014744 -0.07342099999999997 -0.041001 0.009771999999999999 -0.07007799999999997 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.018629 -0.07798099999999997 -0.041001 0.014744 -0.07342099999999997 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.021141 -0.08341999999999997 -0.041001 0.018629 -0.07798099999999997 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.021164 -0.08349599999999997 -0.041001 0.021141 -0.08341999999999997 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.021985 -0.08509899999999997 -0.041001 0.021164 -0.08349599999999997 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.023452 -0.08638599999999998 -0.041001 0.021985 -0.08509899999999997 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.025299 -0.08701299999999997 -0.041001 0.023452 -0.08638599999999998 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.027246 -0.08688499999999998 -0.041001 0.025299 -0.08701299999999997 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.028996 -0.08602199999999997 -0.041001 0.027246 -0.08688499999999998 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.030282 -0.08455499999999998 -0.041001 0.028996 -0.08602199999999997 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.030844 -0.08308599999999997 -0.041001 0.030282 -0.08455499999999998 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.036766 -0.05498099999999997 -0.041001 0.030844 -0.08308599999999997 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.037048 -0.05074599999999997 -0.041001 0.036766 -0.05498099999999997 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.036048 -0.04636499999999998 -0.041001 0.037048 -0.05074599999999997 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.036048 -0.04636499999999998 -0.041001 0.033802 -0.04247399999999997 -0.0157386 0.0338657 -0.04258439999999997 -0.041001 0.033802 -0.04247399999999997 -0.0157501 0.033802 -0.04247399999999997 -0.0157386 0.0338657 -0.04258439999999997 -0.0160538 0.0306414 -0.03954169999999997 -0.0157501 0.033802 -0.04247399999999997 -0.041001 0.033802 -0.04247399999999997 -0.0160666 0.030508 -0.03941799999999997 -0.0160538 0.0306414 -0.03954169999999997 -0.041001 0.030508 -0.03941799999999997 -0.0160538 0.0306414 -0.03954169999999997 -0.041001 0.033802 -0.04247399999999997 -0.041001 0.030508 -0.03941799999999997 -0.0162589 0.0266549 -0.03756229999999997 -0.0160666 0.030508 -0.03941799999999997 -0.041001 0.030508 -0.03941799999999997 -0.0162686 0.026459 -0.03746799999999997 -0.0162589 0.0266549 -0.03756229999999997 -0.041001 0.026459 -0.03746799999999997 -0.0162589 0.0266549 -0.03756229999999997 -0.041001 0.030508 -0.03941799999999997 -0.041001 0.026459 -0.03746799999999997 -0.0163174 0.0233368 -0.03699719999999997 -0.0162686 0.026459 -0.03746799999999997 -0.041001 0.026459 -0.03746799999999997 -0.0163345 0.0222439 -0.03683239999999997 -0.0163174 0.0233368 -0.03699719999999997 -0.041001 0.026459 -0.03746799999999997 0.014999 -0.0228548 -0.09295739999999997 0.014999 -0.02224 -0.09678599999999997 0.033499 -0.021622 -0.09659699999999997 0.014999 -0.023244 -0.09053399999999998 0.014999 -0.0228548 -0.09295739999999997 0.033499 -0.021622 -0.09659699999999997 0.014999 -0.023244 -0.09053399999999998 0.033499 -0.021622 -0.09659699999999997 0.033499 -0.022599 -0.09051899999999997 0.014999 -0.022525 -0.08424299999999997 0.033499 -0.022599 -0.09051899999999997 0.033499 -0.021899 -0.08440299999999998 0.033499 -0.021899 -0.08440299999999998 0.033499 -0.019576 -0.07870199999999997 0.014999 -0.020135 -0.07837899999999998 0.033499 0.021268 -0.09766299999999997 0.033499 -0.019576 -0.07870199999999997 0.033499 -0.021899 -0.08440299999999998 -0.016338 0.022016 -0.03679799999999997 -0.0163345 0.0222439 -0.03683239999999997 -0.041001 0.022016 -0.03679799999999997 -0.0163345 0.0222439 -0.03683239999999997 -0.041001 0.026459 -0.03746799999999997 -0.041001 0.022016 -0.03679799999999997 -0.016272 0.0177902 -0.03743519999999997 -0.016338 0.022016 -0.03679799999999997 -0.041001 0.022016 -0.03679799999999997 -0.0162686 0.017573 -0.03746799999999997 -0.016272 0.0177902 -0.03743519999999997 -0.041001 0.017573 -0.03746799999999997 -0.016272 0.0177902 -0.03743519999999997 -0.041001 0.022016 -0.03679799999999997 -0.041001 0.017573 -0.03746799999999997 -0.016075 0.0136913 -0.03933749999999997 -0.0162686 0.017573 -0.03746799999999997 -0.041001 0.017573 -0.03746799999999997 -0.0160666 0.013524 -0.03941799999999997 -0.016075 0.0136913 -0.03933749999999997 -0.041001 0.013524 -0.03941799999999997 -0.016075 0.0136913 -0.03933749999999997 -0.041001 0.017573 -0.03746799999999997 -0.041001 0.013524 -0.03941799999999997 -0.0159434 0.0120061 -0.04060729999999997 -0.0160666 0.013524 -0.03941799999999997 -0.041001 0.013524 -0.03941799999999997 -0.0159388 0.011949 -0.04065199999999997 -0.0159434 0.0120061 -0.04060729999999997 -0.041001 0.011949 -0.04065199999999997 -0.0159434 0.0120061 -0.04060729999999997 -0.041001 0.013524 -0.03941799999999997 -0.041001 0.011949 -0.04065199999999997 -0.0150104 0.00196059 -0.04961399999999997 -0.0159388 0.011949 -0.04065199999999997 -0.041001 0.011949 -0.04065199999999997 -0.015001 0.00134311 -0.05016799999999997 -0.015001 0.00141267 -0.05010559999999997 -0.041001 0.011949 -0.04065199999999997 -0.015001 0.00141267 -0.05010559999999997 -0.015001 0.00156619 -0.04996779999999997 -0.041001 0.011949 -0.04065199999999997 -0.015001 0.00156619 -0.04996779999999997 -0.0150104 0.00196059 -0.04961399999999997 -0.041001 0.011949 -0.04065199999999997 -0.015001 0.00134311 -0.05016799999999997 -0.041001 0.011949 -0.04065199999999997 -0.015001 -0.009429999999999999 -0.05983399999999997 -0.015001 -0.0110311 -0.06316229999999998 -0.015001 -0.011048 -0.06290299999999997 -0.015001 -0.0109901 -0.06311919999999997 -0.015001 -0.0109901 -0.06311919999999997 -0.015001 -0.011048 -0.06290299999999997 -0.015001 -0.0109063 -0.06303119999999997 -0.015001 -0.00839001 -0.06038879999999997 -0.015001 0.00134311 -0.05016799999999997 -0.015001 -0.009429999999999999 -0.05983399999999997 -0.015001 -0.011048 -0.06290299999999997 -0.015001 -0.0108748 -0.06299819999999998 -0.015001 -0.0109063 -0.06303119999999997 -0.015001 -0.009429999999999999 -0.05983399999999997 -0.015001 -0.00839001 -0.06038879999999997 -0.015001 -0.00844342 -0.06044489999999998 -0.015001 -0.011048 -0.06290299999999997 -0.015001 -0.0108748 -0.06299819999999998 -0.015001 -0.0103396 -0.06202659999999997 -0.015001 -0.0108748 -0.06299819999999998 -0.015001 -0.009631229999999999 -0.06169219999999997 -0.015001 -0.0103396 -0.06202659999999997 -0.015001 -0.009631229999999999 -0.06169219999999997 -0.015001 -0.010421 -0.06105499999999997 -0.015001 -0.0103396 -0.06202659999999997 -0.015001 -0.010421 -0.06105499999999997 -0.015001 -0.011048 -0.06290299999999997 -0.015001 -0.0103396 -0.06202659999999997 -0.015001 -0.010421 -0.06105499999999997 -0.015001 -0.00947042 -0.06152339999999997 -0.015001 -0.00943221 -0.06067869999999997 -0.015001 -0.00947042 -0.06152339999999997 -0.015001 -0.00844342 -0.06044489999999998 -0.015001 -0.00943221 -0.06067869999999997 -0.015001 -0.00844342 -0.06044489999999998 -0.015001 -0.009429999999999999 -0.05983399999999997 -0.015001 -0.00943221 -0.06067869999999997 -0.015001 -0.009429999999999999 -0.05983399999999997 -0.015001 -0.010421 -0.06105499999999997 -0.015001 -0.00943221 -0.06067869999999997 -0.015001 -0.009631229999999999 -0.06169219999999997 -0.015001 -0.00947042 -0.06152339999999997 -0.015001 -0.010421 -0.06105499999999997 0.014999 -0.010224 -0.110887 0.033499 -0.004094 -0.112236 0.033499 -0.009940010000000001 -0.110307 0.033499 -0.009940010000000001 -0.110307 0.033499 -0.015049 -0.106872 0.014999 -0.015479 -0.107354 0.014999 -0.0162255 -0.106478 0.014999 -0.015479 -0.107354 0.033499 -0.015049 -0.106872 0.014999 -0.019585 -0.102535 0.014999 -0.0162255 -0.106478 0.033499 -0.015049 -0.106872 0.033499 -0.009940010000000001 -0.110307 0.033499 0.021268 -0.09766299999999997 0.033499 -0.015049 -0.106872 -0.041001 0.004082 -0.06819999999999997 -0.041001 -0.001903 -0.06792799999999997 -0.041001 0.011949 -0.04065199999999997 -0.015001 -0.00183603 -0.06793109999999997 -0.015001 -0.001903 -0.06792799999999997 -0.041001 -0.001903 -0.06792799999999997 -0.015001 0.000254233 -0.06802639999999997 -0.015001 -0.00183603 -0.06793109999999997 -0.041001 -0.001903 -0.06792799999999997 -0.015001 0.004082 -0.06820099999999997 -0.015001 0.0023343 -0.06812129999999997 -0.041001 -0.001903 -0.06792799999999997 -0.015001 0.0023343 -0.06812129999999997 -0.015001 0.000254233 -0.06802639999999997 -0.041001 -0.001903 -0.06792799999999997 -0.041001 0.033802 -0.04247399999999997 -0.041001 0.036048 -0.04636499999999998 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.030508 -0.03941799999999997 -0.041001 0.033802 -0.04247399999999997 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.026459 -0.03746799999999997 -0.041001 0.030508 -0.03941799999999997 -0.041001 0.011949 -0.04065199999999997 0.014999 -0.0205653 -0.100412 0.014999 -0.019585 -0.102535 0.033499 -0.019041 -0.102187 0.014999 -0.02224 -0.09678599999999997 0.014999 -0.0205653 -0.100412 0.033499 -0.019041 -0.102187 0.014999 -0.02224 -0.09678599999999997 0.033499 -0.019041 -0.102187 0.033499 -0.021622 -0.09659699999999997 0.033499 0.021268 -0.09766299999999997 0.033499 -0.022599 -0.09051899999999997 0.033499 -0.021622 -0.09659699999999997 0.033499 0.021268 -0.09766299999999997 0.033499 -0.021899 -0.08440299999999998 0.033499 -0.022599 -0.09051899999999997 -0.041001 0.022016 -0.03679799999999997 -0.041001 0.026459 -0.03746799999999997 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.017573 -0.03746799999999997 -0.041001 0.022016 -0.03679799999999997 -0.041001 0.011949 -0.04065199999999997 -0.041001 0.013524 -0.03941799999999997 -0.041001 0.017573 -0.03746799999999997 -0.041001 0.011949 -0.04065199999999997 -0.015001 -0.009429999999999999 -0.05983399999999997 -0.041001 0.011949 -0.04065199999999997 -0.041001 -0.009429999999999999 -0.05983399999999997 -0.041001 -0.011048 -0.06290299999999997 -0.015001 -0.010921 -0.06484999999999998 -0.015001 -0.0110087 -0.06350509999999997 -0.041001 -0.011048 -0.06290299999999997 -0.015001 -0.0110087 -0.06350509999999997 -0.015001 -0.0110311 -0.06316229999999998 -0.041001 -0.011048 -0.06290299999999997 -0.015001 -0.0110311 -0.06316229999999998 -0.015001 -0.011048 -0.06290299999999997 -0.041001 -0.010421 -0.06105499999999997 -0.015001 -0.011048 -0.06290299999999997 -0.015001 -0.010421 -0.06105499999999997 -0.041001 -0.009429999999999999 -0.05983399999999997 -0.015001 -0.010421 -0.06105499999999997 -0.015001 -0.009429999999999999 -0.05983399999999997 0.014999 -0.019585 -0.102535 0.033499 -0.015049 -0.106872 0.033499 -0.019041 -0.102187 0.033499 0.021268 -0.09766299999999997 0.033499 -0.019041 -0.102187 0.033499 -0.015049 -0.106872 -0.041001 -0.001903 -0.06792799999999997 -0.041001 -0.004945 -0.06842199999999997 -0.041001 0.011949 -0.04065199999999997 -0.015001 -0.001903 -0.06792799999999997 -0.041001 -0.004945 -0.06842199999999997 -0.041001 -0.001903 -0.06792799999999997 0.033499 0.021268 -0.09766299999999997 0.033499 -0.021622 -0.09659699999999997 0.033499 -0.019041 -0.102187 -0.041001 -0.010921 -0.06484899999999998 -0.015001 -0.010058 -0.06659899999999998 -0.015001 -0.0100641 -0.06658659999999997 -0.041001 -0.010921 -0.06484899999999998 -0.015001 -0.0100641 -0.06658659999999997 -0.015001 -0.0108635 -0.06496659999999997 -0.041001 -0.010921 -0.06484899999999998 -0.015001 -0.0108635 -0.06496659999999997 -0.015001 -0.010921 -0.06484999999999998 -0.041001 -0.010421 -0.06105499999999997 -0.041001 -0.009429999999999999 -0.05983399999999997 -0.041001 0.011949 -0.04065199999999997 -0.041001 -0.011048 -0.06290299999999997 -0.041001 -0.010921 -0.06484899999999998 -0.015001 -0.010921 -0.06484999999999998 -0.041001 -0.010421 -0.06105499999999997 -0.041001 -0.011048 -0.06290299999999997 -0.015001 -0.011048 -0.06290299999999997 -0.041001 -0.009429999999999999 -0.05983399999999997 -0.041001 -0.010421 -0.06105499999999997 -0.015001 -0.010421 -0.06105499999999997 -0.041001 -0.004945 -0.06842199999999997 -0.041001 -0.006744 -0.06851299999999998 -0.041001 0.011949 -0.04065199999999997 -0.015001 -0.00411044 -0.06828649999999997 -0.015001 -0.004945 -0.06842199999999997 -0.041001 -0.004945 -0.06842199999999997 -0.015001 -0.001903 -0.06792799999999997 -0.015001 -0.00411044 -0.06828649999999997 -0.041001 -0.004945 -0.06842199999999997 -0.015001 -0.008591 -0.06788599999999997 -0.015001 -0.010058 -0.06659899999999998 -0.041001 -0.010058 -0.06659899999999998 -0.015001 -0.00857579 -0.06789119999999997 -0.015001 -0.008591 -0.06788599999999997 -0.041001 -0.008591 -0.06788599999999997 -0.015001 -0.006744 -0.06851299999999998 -0.015001 -0.00857579 -0.06789119999999997 -0.041001 -0.008591 -0.06788599999999997 -0.041001 -0.010921 -0.06484899999999998 -0.041001 -0.010058 -0.06659899999999998 -0.015001 -0.010058 -0.06659899999999998 -0.041001 0.011949 -0.04065199999999997 -0.041001 -0.011048 -0.06290299999999997 -0.041001 -0.010421 -0.06105499999999997 -0.041001 0.011949 -0.04065199999999997 -0.041001 -0.010921 -0.06484899999999998 -0.041001 -0.011048 -0.06290299999999997 -0.041001 -0.006744 -0.06851299999999998 -0.041001 -0.008591 -0.06788599999999997 -0.041001 0.011949 -0.04065199999999997 -0.015001 -0.004945 -0.06842199999999997 -0.041001 -0.006744 -0.06851299999999998 -0.041001 -0.004945 -0.06842199999999997 -0.015001 -0.00650024 -0.06850069999999997 -0.015001 -0.006744 -0.06851299999999998 -0.041001 -0.006744 -0.06851299999999998 -0.015001 -0.004945 -0.06842199999999997 -0.015001 -0.00650024 -0.06850069999999997 -0.041001 -0.006744 -0.06851299999999998 -0.015001 -0.008591 -0.06788599999999997 -0.041001 -0.010058 -0.06659899999999998 -0.041001 -0.008591 -0.06788599999999997 -0.015001 -0.006744 -0.06851299999999998 -0.041001 -0.008591 -0.06788599999999997 -0.041001 -0.006744 -0.06851299999999998 -0.041001 -0.010058 -0.06659899999999998 -0.041001 -0.010921 -0.06484899999999998 -0.041001 0.011949 -0.04065199999999997 -0.041001 -0.008591 -0.06788599999999997 -0.041001 -0.010058 -0.06659899999999998 -0.041001 0.011949 -0.04065199999999997 -0.016247 0.07126 -0.02960999999999997 0.01685 0.07126 -0.02537499999999997 0.016245 0.07126 -0.02960999999999997 -0.016062 0.07013 -0.03208299999999997 -0.016247 0.07126 -0.02960999999999997 0.016245 0.07126 -0.02960999999999997 -0.016247 0.07126 -0.02960999999999997 -0.019377 0.07126 -0.01650099999999997 0.01685 0.07126 -0.02537499999999997 0.016245 0.07126 -0.02960999999999997 0.01685 0.07126 -0.02537499999999997 0.01606 0.07013 -0.03208299999999997 -0.016062 0.07013 -0.03208299999999997 0.016245 0.07126 -0.02960999999999997 0.01606 0.07013 -0.03208299999999997 -0.019377 0.07126 -0.01650099999999997 -0.016247 0.07126 -0.02960999999999997 -0.016062 0.07013 -0.03208299999999997 -0.019377 0.07126 -0.01650099999999997 0.021704 0.07126 -0.01136899999999997 0.01685 0.07126 -0.02537499999999997 0.01606 0.07013 -0.03208299999999997 0.01685 0.07126 -0.02537499999999997 0.015999 0.068998 -0.03456299999999998 -0.016062 0.07013 -0.03208299999999997 0.01606 0.07013 -0.03208299999999997 0.015999 0.068998 -0.03456299999999998 -0.019377 0.07126 -0.01650099999999997 -0.016062 0.07013 -0.03208299999999997 -0.016001 0.068998 -0.03456299999999998 -0.019377 0.07126 -0.01650099999999997 -0.021706 0.07126 -0.01136899999999997 0.021704 0.07126 -0.01136899999999997 0.021704 0.05826 -0.01136899999999997 0.01685 0.07126 -0.02537499999999997 0.021704 0.07126 -0.01136899999999997 0.015999 0.068998 -0.03456299999999998 0.01685 0.07126 -0.02537499999999997 0.01685 0.05826 -0.02537499999999997 -0.016001 0.068998 -0.03456299999999998 -0.016062 0.07013 -0.03208299999999997 0.015999 0.068998 -0.03456299999999998 -0.016001 0.068998 -0.03456299999999998 -0.016001 0.054708 -0.03456299999999998 -0.019377 0.07126 -0.01650099999999997 -0.021706 0.07126 -0.01136899999999997 -0.019377 0.07126 -0.01650099999999997 -0.019377 0.05826 -0.01650099999999997 -0.021706 0.07126 -0.01136899999999997 0.02341 0.07126 -0.007225999999999972 0.021704 0.07126 -0.01136899999999997 0.021704 0.07126 -0.01136899999999997 0.02341 0.05826 -0.007225999999999972 0.021704 0.05826 -0.01136899999999997 0.01685 0.07126 -0.02537499999999997 0.021704 0.05826 -0.01136899999999997 0.01685 0.05826 -0.02537499999999997 0.015999 0.068998 -0.03456299999999998 0.01685 0.05826 -0.02537499999999997 0.016608 0.05826 -0.02678299999999997 0.015999 0.068998 -0.03456299999999998 0.015999 0.041927 -0.09385399999999998 -0.016001 0.068998 -0.03456299999999998 -0.016001 0.068998 -0.03456299999999998 -0.016001 0.030102 -0.08845499999999998 -0.016001 0.054708 -0.03456299999999998 -0.016001 0.054708 -0.03456299999999998 -0.016153 0.056489 -0.03066099999999997 -0.019377 0.07126 -0.01650099999999997 -0.021706 0.07126 -0.01136899999999997 -0.019377 0.05826 -0.01650099999999997 -0.021706 0.05826 -0.01136899999999997 -0.019377 0.07126 -0.01650099999999997 -0.01661 0.05826 -0.02678299999999997 -0.019377 0.05826 -0.01650099999999997 -0.021706 0.07126 -0.01136899999999997 -0.022075 0.07126 -0.01063499999999997 0.02341 0.07126 -0.007225999999999972 0.021704 0.07126 -0.01136899999999997 0.02341 0.07126 -0.007225999999999972 0.02341 0.05826 -0.007225999999999972 -0.022075 0.05826 -0.01063499999999997 0.021704 0.05826 -0.01136899999999997 0.02341 0.05826 -0.007225999999999972 -0.019377 0.05826 -0.01650099999999997 0.01685 0.05826 -0.02537499999999997 0.021704 0.05826 -0.01136899999999997 0.015999 0.068998 -0.03456299999999998 0.016608 0.05826 -0.02678299999999997 0.016151 0.056489 -0.03066099999999997 -0.019377 0.05826 -0.01650099999999997 0.016608 0.05826 -0.02678299999999997 0.01685 0.05826 -0.02537499999999997 -0.016001 0.041927 -0.09385399999999998 -0.016001 0.068998 -0.03456299999999998 0.015999 0.041927 -0.09385399999999998 0.015999 0.068998 -0.03456299999999998 0.015999 0.054708 -0.03456299999999998 0.015999 0.041927 -0.09385399999999998 -0.016001 0.041927 -0.09385399999999998 -0.016001 0.030102 -0.08845499999999998 -0.016001 0.068998 -0.03456299999999998 -0.016001 0.030102 -0.08845499999999998 0.015999 0.030102 -0.08845499999999998 -0.016001 0.054708 -0.03456299999999998 -0.016153 0.056489 -0.03066099999999997 -0.016001 0.054708 -0.03456299999999998 0.016151 0.056489 -0.03066099999999997 -0.01661 0.05826 -0.02678299999999997 -0.019377 0.07126 -0.01650099999999997 -0.016153 0.056489 -0.03066099999999997 -0.022075 0.07126 -0.01063499999999997 -0.021706 0.07126 -0.01136899999999997 -0.021706 0.05826 -0.01136899999999997 -0.021706 0.05826 -0.01136899999999997 -0.019377 0.05826 -0.01650099999999997 0.021704 0.05826 -0.01136899999999997 -0.019377 0.05826 -0.01650099999999997 -0.01661 0.05826 -0.02678299999999997 0.016608 0.05826 -0.02678299999999997 -0.022075 0.07126 -0.01063499999999997 -0.024227 0.07126 -0.003655999999999972 0.02341 0.07126 -0.007225999999999972 0.02341 0.07126 -0.007225999999999972 0.024499 0.05826 -5.002809999972244e-06 0.02341 0.05826 -0.007225999999999972 -0.024227 0.05826 -0.003655999999999972 -0.022075 0.05826 -0.01063499999999997 0.02341 0.05826 -0.007225999999999972 -0.022075 0.05826 -0.01063499999999997 -0.021706 0.05826 -0.01136899999999997 0.021704 0.05826 -0.01136899999999997 0.015999 0.068998 -0.03456299999999998 0.016151 0.056489 -0.03066099999999997 0.015999 0.054708 -0.03456299999999998 -0.01661 0.05826 -0.02678299999999997 0.016151 0.056489 -0.03066099999999997 0.016608 0.05826 -0.02678299999999997 -0.016001 0.041927 -0.09385399999999998 0.015999 0.041927 -0.09385399999999998 0.015756 0.040773 -0.09638099999999997 0.015999 0.041927 -0.09385399999999998 0.015999 0.054708 -0.03456299999999998 0.015999 0.030102 -0.08845499999999998 -0.016001 0.041927 -0.09385399999999998 -0.015758 0.028948 -0.09098199999999997 -0.016001 0.030102 -0.08845499999999998 -0.016001 0.054708 -0.03456299999999998 0.015999 0.030102 -0.08845499999999998 0.015999 0.054708 -0.03456299999999998 -0.01661 0.05826 -0.02678299999999997 -0.016153 0.056489 -0.03066099999999997 0.016151 0.056489 -0.03066099999999997 -0.016001 0.054708 -0.03456299999999998 0.015999 0.054708 -0.03456299999999998 0.016151 0.056489 -0.03066099999999997 -0.022075 0.07126 -0.01063499999999997 -0.021706 0.05826 -0.01136899999999997 -0.022075 0.05826 -0.01063499999999997 -0.024227 0.07126 -0.003655999999999972 -0.022075 0.07126 -0.01063499999999997 -0.022075 0.05826 -0.01063499999999997 -0.024227 0.07126 -0.003655999999999972 0.024499 0.07126 -5.003379999972244e-06 0.02341 0.07126 -0.007225999999999972 0.02341 0.07126 -0.007225999999999972 0.024499 0.07126 -5.003379999972244e-06 0.024499 0.05826 -5.002809999972244e-06 -0.024227 0.05826 -0.003655999999999972 0.02341 0.05826 -0.007225999999999972 0.024499 0.05826 -5.002809999972244e-06 -0.024227 0.07126 -0.003655999999999972 -0.022075 0.05826 -0.01063499999999997 -0.024227 0.05826 -0.003655999999999972 -0.015758 0.040773 -0.09638099999999997 -0.016001 0.041927 -0.09385399999999998 0.015756 0.040773 -0.09638099999999997 0.015999 0.030102 -0.08845499999999998 0.015756 0.040773 -0.09638099999999997 0.015999 0.041927 -0.09385399999999998 -0.016001 0.041927 -0.09385399999999998 -0.015758 0.040773 -0.09638099999999997 -0.015758 0.028948 -0.09098199999999997 -0.024227 0.07126 -0.003655999999999972 -0.024227 0.07126 0.003647000000000028 0.024499 0.07126 -5.003379999972244e-06 0.024499 0.07126 -5.003379999972244e-06 0.02341 0.05826 0.007217000000000028 0.024499 0.05826 -5.002809999972244e-06 -0.024227 0.05826 0.003647000000000028 -0.024227 0.05826 -0.003655999999999972 0.024499 0.05826 -5.002809999972244e-06 -0.024227 0.07126 0.003647000000000028 -0.024227 0.07126 -0.003655999999999972 -0.024227 0.05826 -0.003655999999999972 -0.015758 0.040773 -0.09638099999999997 0.015756 0.040773 -0.09638099999999997 0.013855 0.038605 -0.101132 0.015756 0.040773 -0.09638099999999997 0.015999 0.030102 -0.08845499999999998 0.015756 0.028948 -0.09098199999999997 -0.015758 0.040773 -0.09638099999999997 -0.013857 0.026779 -0.09573199999999997 -0.015758 0.028948 -0.09098199999999997 -0.024227 0.07126 0.003647000000000028 0.02341 0.07126 0.007217000000000028 0.024499 0.07126 -5.003379999972244e-06 0.024499 0.07126 -5.003379999972244e-06 0.02341 0.07126 0.007217000000000028 0.02341 0.05826 0.007217000000000028 -0.024227 0.05826 0.003647000000000028 0.024499 0.05826 -5.002809999972244e-06 0.02341 0.05826 0.007217000000000028 -0.024227 0.07126 0.003647000000000028 -0.024227 0.05826 -0.003655999999999972 -0.024227 0.05826 0.003647000000000028 -0.013857 0.038605 -0.101132 -0.015758 0.040773 -0.09638099999999997 0.013855 0.038605 -0.101132 0.015756 0.028948 -0.09098199999999997 0.013855 0.038605 -0.101132 0.015756 0.040773 -0.09638099999999997 -0.013857 0.026779 -0.09573199999999997 -0.015758 0.040773 -0.09638099999999997 -0.013857 0.038605 -0.101132 0.013855 0.038605 -0.101132 0.015756 0.028948 -0.09098199999999997 0.013855 0.026779 -0.09573199999999997 -0.024227 0.07126 0.003647000000000028 -0.022075 0.07126 0.01062500000000003 0.02341 0.07126 0.007217000000000028 0.02341 0.07126 0.007217000000000028 0.020242 0.05826 0.01379700000000003 0.02341 0.05826 0.007217000000000028 -0.022075 0.05826 0.01062500000000003 -0.024227 0.05826 0.003647000000000028 0.02341 0.05826 0.007217000000000028 -0.022075 0.07126 0.01062500000000003 -0.024227 0.07126 0.003647000000000028 -0.024227 0.05826 0.003647000000000028 -0.013857 0.038605 -0.101132 0.013855 0.038605 -0.101132 0.010284 0.036837 -0.105004 -0.010286 0.025011 -0.09960399999999997 -0.013857 0.026779 -0.09573199999999997 -0.013857 0.038605 -0.101132 0.010284 0.036837 -0.105004 0.013855 0.026779 -0.09573199999999997 0.010284 0.025011 -0.09960399999999997 0.010284 0.036837 -0.105004 0.013855 0.038605 -0.101132 0.013855 0.026779 -0.09573199999999997 -0.022075 0.07126 0.01062500000000003 0.020242 0.07126 0.01379700000000003 0.02341 0.07126 0.007217000000000028 0.02341 0.07126 0.007217000000000028 0.020242 0.07126 0.01379700000000003 0.020242 0.05826 0.01379700000000003 -0.022075 0.05826 0.01062500000000003 0.02341 0.05826 0.007217000000000028 0.020242 0.05826 0.01379700000000003 -0.022075 0.07126 0.01062500000000003 -0.024227 0.05826 0.003647000000000028 -0.022075 0.05826 0.01062500000000003 -0.010286 0.036837 -0.105004 -0.013857 0.038605 -0.101132 0.010284 0.036837 -0.105004 -0.013857 0.038605 -0.101132 -0.010286 0.036837 -0.105004 -0.010286 0.025011 -0.09960399999999997 0.010284 0.025011 -0.09960399999999997 0.005471 0.035683 -0.107531 0.010284 0.036837 -0.105004 -0.022075 0.07126 0.01062500000000003 -0.017961 0.07126 0.01665900000000003 0.020242 0.07126 0.01379700000000003 0.020242 0.07126 0.01379700000000003 0.015274 0.05826 0.01915000000000003 0.020242 0.05826 0.01379700000000003 -0.017961 0.05826 0.01665900000000003 -0.022075 0.05826 0.01062500000000003 0.020242 0.05826 0.01379700000000003 -0.022075 0.05826 0.01062500000000003 -0.017961 0.07126 0.01665900000000003 -0.022075 0.07126 0.01062500000000003 0.005471 0.035683 -0.107531 -0.010286 0.036837 -0.105004 0.010284 0.036837 -0.105004 -0.005473 0.023857 -0.102132 -0.010286 0.025011 -0.09960399999999997 -0.010286 0.036837 -0.105004 0.010284 0.025011 -0.09960399999999997 0.005471 0.023857 -0.102132 0.005471 0.035683 -0.107531 -0.017961 0.07126 0.01665900000000003 0.015274 0.07126 0.01915000000000003 0.020242 0.07126 0.01379700000000003 0.020242 0.07126 0.01379700000000003 0.015274 0.07126 0.01915000000000003 0.015274 0.05826 0.01915000000000003 -0.017961 0.05826 0.01665900000000003 0.020242 0.05826 0.01379700000000003 0.015274 0.05826 0.01915000000000003 -0.017961 0.07126 0.01665900000000003 -0.022075 0.05826 0.01062500000000003 -0.017961 0.05826 0.01665900000000003 -0.010286 0.036837 -0.105004 0.005471 0.035683 -0.107531 -0.005473 0.035683 -0.107531 -0.005473 0.023857 -0.102132 -0.010286 0.036837 -0.105004 -0.005473 0.035683 -0.107531 -1.00209e-06 0.023456 -0.10301 -0.005473 0.023857 -0.102132 -0.005473 0.035683 -0.107531 0.005471 0.023857 -0.102132 -1.00209e-06 0.023456 -0.10301 -1.00229e-06 0.035282 -0.108409 0.005471 0.035683 -0.107531 0.005471 0.023857 -0.102132 -1.00229e-06 0.035282 -0.108409 -0.017961 0.07126 0.01665900000000003 -0.012251 0.07126 0.02121300000000003 0.015274 0.07126 0.01915000000000003 0.00895 0.05826 0.02280200000000003 0.015274 0.05826 0.01915000000000003 0.015274 0.07126 0.01915000000000003 -0.012251 0.05826 0.02121300000000003 -0.017961 0.05826 0.01665900000000003 0.015274 0.05826 0.01915000000000003 -0.017961 0.05826 0.01665900000000003 -0.012251 0.07126 0.02121300000000003 -0.017961 0.07126 0.01665900000000003 0.005471 0.035683 -0.107531 -1.00229e-06 0.035282 -0.108409 -0.005473 0.035683 -0.107531 -1.00229e-06 0.035282 -0.108409 -1.00209e-06 0.023456 -0.10301 -0.005473 0.035683 -0.107531 0.00895 0.07126 0.02280200000000003 0.015274 0.07126 0.01915000000000003 -0.012251 0.07126 0.02121300000000003 0.00895 0.05826 0.02280200000000003 0.015274 0.07126 0.01915000000000003 0.00895 0.07126 0.02280200000000003 0.015274 0.05826 0.01915000000000003 0.00895 0.05826 0.02280200000000003 -0.012251 0.05826 0.02121300000000003 -0.012251 0.07126 0.02121300000000003 -0.017961 0.05826 0.01665900000000003 -0.012251 0.05826 0.02121300000000003 -0.005453 0.07126 0.02388100000000003 0.00895 0.07126 0.02280200000000003 -0.012251 0.07126 0.02121300000000003 0.00183 0.05826 0.02442700000000003 0.00895 0.05826 0.02280200000000003 0.00895 0.07126 0.02280200000000003 -0.012251 0.05826 0.02121300000000003 0.00895 0.05826 0.02280200000000003 -0.005453 0.05826 0.02388100000000003 -0.012251 0.05826 0.02121300000000003 -0.005453 0.07126 0.02388100000000003 -0.012251 0.07126 0.02121300000000003 0.00183 0.07126 0.02442700000000003 0.00895 0.07126 0.02280200000000003 -0.005453 0.07126 0.02388100000000003 0.00183 0.05826 0.02442700000000003 0.00895 0.07126 0.02280200000000003 0.00183 0.07126 0.02442700000000003 0.00895 0.05826 0.02280200000000003 0.00183 0.05826 0.02442700000000003 -0.005453 0.05826 0.02388100000000003 -0.012251 0.05826 0.02121300000000003 -0.005453 0.05826 0.02388100000000003 -0.005453 0.07126 0.02388100000000003 -0.005453 0.05826 0.02388100000000003 0.00183 0.07126 0.02442700000000003 -0.005453 0.07126 0.02388100000000003 -0.005453 0.05826 0.02388100000000003 0.00183 0.05826 0.02442700000000003 0.00183 0.07126 0.02442700000000003 -0.016001 0.030102 -0.08845499999999998 -0.015758 0.028948 -0.09098199999999997 0.015999 0.030102 -0.08845499999999998 -0.015758 0.028948 -0.09098199999999997 0.015756 0.028948 -0.09098199999999997 0.015999 0.030102 -0.08845499999999998 -0.015758 0.028948 -0.09098199999999997 0.013855 0.026779 -0.09573199999999997 0.015756 0.028948 -0.09098199999999997 -0.015758 0.028948 -0.09098199999999997 -0.013857 0.026779 -0.09573199999999997 0.010284 0.025011 -0.09960399999999997 -0.015758 0.028948 -0.09098199999999997 0.010284 0.025011 -0.09960399999999997 0.013855 0.026779 -0.09573199999999997 -0.013857 0.026779 -0.09573199999999997 -0.010286 0.025011 -0.09960399999999997 0.010284 0.025011 -0.09960399999999997 -0.010286 0.025011 -0.09960399999999997 -1.00209e-06 0.023456 -0.10301 0.010284 0.025011 -0.09960399999999997 -1.00209e-06 0.023456 -0.10301 -0.010286 0.025011 -0.09960399999999997 -0.005473 0.023857 -0.102132 0.010284 0.025011 -0.09960399999999997 -1.00209e-06 0.023456 -0.10301 0.005471 0.023857 -0.102132 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101

    -
    -
    - - - 0 0 2.775557561562891e-17 - 1 0 0 0 - - true - - - -
    - - - - -0.02519999999999999 -0.00497363 -0.0469257 -0.02519999999999999 -0.00523391 -0.046608 -0.02569999999999999 -0.00539113 -0.0464161 -0.02519999999999999 -0.00523391 -0.046608 -0.02519999999999999 -0.00539113 -0.0464161 -0.02569999999999999 -0.00539113 -0.0464161 -0.02519999999999999 -0.00539113 -0.0464161 -0.02619999999999999 -0.00580863 -0.0459064 -0.02569999999999999 -0.00539113 -0.0464161 -0.02619999999999999 -0.00580863 -0.0459064 -0.02619999999999999 -0.00497363 -0.0469257 -0.02569999999999999 -0.00539113 -0.0464161 -0.02619999999999999 -0.00497363 -0.0469257 -0.02519999999999999 -0.00497363 -0.0469257 -0.02569999999999999 -0.00539113 -0.0464161 -0.02519999999999999 -0.00447758 -0.0473416 -0.02519999999999999 -0.00497363 -0.0469257 -0.02569999999999999 -0.00447758 -0.0473416 -0.02519999999999999 -0.00497363 -0.0469257 -0.02619999999999999 -0.00497363 -0.0469257 -0.02569999999999999 -0.00447758 -0.0473416 -0.02619999999999999 -0.00497363 -0.0469257 -0.02619999999999999 -0.00398153 -0.0477574 -0.02569999999999999 -0.00447758 -0.0473416 -0.02619999999999999 -0.00398153 -0.0477574 -0.02519999999999999 -0.00447758 -0.0473416 -0.02569999999999999 -0.00447758 -0.0473416 -0.02519999999999999 -0.00398153 -0.0477574 -0.02519999999999999 -0.00447758 -0.0473416 -0.02619999999999999 -0.00398153 -0.0477574 -0.02519999999999999 -0.00340985 -0.0480781 -0.02519999999999999 -0.00398153 -0.0477574 -0.02569999999999999 -0.00340985 -0.0480781 -0.02519999999999999 -0.00398153 -0.0477574 -0.02619999999999999 -0.00398153 -0.0477574 -0.02569999999999999 -0.00340985 -0.0480781 -0.02619999999999999 -0.00398153 -0.0477574 -0.02619999999999999 -0.00283817 -0.0483988 -0.02569999999999999 -0.00340985 -0.0480781 -0.02619999999999999 -0.00283817 -0.0483988 -0.02519999999999999 -0.00340985 -0.0480781 -0.02569999999999999 -0.00340985 -0.0480781 -0.02519999999999999 -0.00283817 -0.0483988 -0.02519999999999999 -0.00340985 -0.0480781 -0.02619999999999999 -0.00283817 -0.0483988 -0.02519999999999999 -0.00215518 -0.0486211 -0.02519999999999999 -0.00283817 -0.0483988 -0.02619999999999999 -0.00283817 -0.0483988 -0.02519999999999999 -0.0014722 -0.0488434 -0.02519999999999999 -0.00215518 -0.0486211 -0.02569999999999999 -0.00215518 -0.0486211 -0.02519999999999999 -0.00215518 -0.0486211 -0.02619999999999999 -0.00283817 -0.0483988 -0.02569999999999999 -0.00215518 -0.0486211 -0.02619999999999999 -0.00283817 -0.0483988 -0.02619999999999999 -0.0014722 -0.0488434 -0.02569999999999999 -0.00215518 -0.0486211 -0.02619999999999999 -0.0014722 -0.0488434 -0.02519999999999999 -0.0014722 -0.0488434 -0.02569999999999999 -0.00215518 -0.0486211 -0.02519999999999999 -0.000736101 -0.0489217 -0.02519999999999999 -0.0014722 -0.0488434 -0.02619999999999999 -0.0014722 -0.0488434 -0.02519999999999999 -7.503130000000001e-18 -0.049 -0.02519999999999999 -0.000736101 -0.0489217 -0.02569999999999999 -0.000736101 -0.0489217 -0.02519999999999999 -0.000736101 -0.0489217 -0.02619999999999999 -0.0014722 -0.0488434 -0.02569999999999999 -0.000736101 -0.0489217 -0.02619999999999999 -0.0014722 -0.0488434 -0.02619999999999999 -7.503130000000001e-18 -0.049 -0.02569999999999999 -0.000736101 -0.0489217 -0.02619999999999999 -7.503130000000001e-18 -0.049 -0.02519999999999999 -7.503130000000001e-18 -0.049 -0.02569999999999999 -0.000736101 -0.0489217 -0.02519999999999999 0.000664345 -0.048928 -0.02519999999999999 -7.503130000000001e-18 -0.049 -0.02619999999999999 -7.503130000000001e-18 -0.049 -0.02619999999999999 -7.503130000000001e-18 -0.049 -0.02519999999999999 0.000664345 -0.048928 -0.02519999999999999 0.000750082 -0.0489187 -0.02619999999999999 0.007 -0.042 -0.02519999999999999 0.00691868 -0.0412499 -0.02519999999999999 0.007 -0.042 -0.02519999999999999 0.00683736 -0.0404998 -0.02519999999999999 0.00691868 -0.0412499 -0.02569999999999999 0.00691868 -0.0412499 -0.02519999999999999 0.00691868 -0.0412499 -0.02619999999999999 0.007 -0.042 -0.02569999999999999 0.00691868 -0.0412499 -0.02619999999999999 0.007 -0.042 -0.02619999999999999 0.00683736 -0.0404998 -0.02569999999999999 0.00691868 -0.0412499 -0.02619999999999999 0.00683736 -0.0404998 -0.02519999999999999 0.00683736 -0.0404998 -0.02569999999999999 0.00691868 -0.0412499 -0.02619999999999999 0.00683736 -0.0404998 -0.02519999999999999 0.00663791 -0.0398764 -0.02519999999999999 0.00683736 -0.0404998 -0.02519999999999999 0.00643847 -0.039253 -0.02519999999999999 0.00663791 -0.0398764 -0.02569999999999999 0.00663791 -0.0398764 -0.02519999999999999 0.00663791 -0.0398764 -0.02619999999999999 0.00683736 -0.0404998 -0.02569999999999999 0.00663791 -0.0398764 -0.02619999999999999 0.00683736 -0.0404998 -0.02619999999999999 0.00643847 -0.039253 -0.02569999999999999 0.00663791 -0.0398764 -0.02619999999999999 0.00643847 -0.039253 -0.02519999999999999 0.00643847 -0.039253 -0.02569999999999999 0.00663791 -0.0398764 -0.02519999999999999 0.00612355 -0.0386733 -0.02519999999999999 0.00643847 -0.039253 -0.02569999999999999 0.00612355 -0.0386733 -0.02519999999999999 0.00643847 -0.039253 -0.02619999999999999 0.00643847 -0.039253 -0.02569999999999999 0.00612355 -0.0386733 -0.02619999999999999 0.00643847 -0.039253 -0.02619999999999999 0.00580863 -0.0380936 -0.02569999999999999 0.00612355 -0.0386733 -0.02619999999999999 0.00580863 -0.0380936 -0.02519999999999999 0.00612355 -0.0386733 -0.02569999999999999 0.00612355 -0.0386733 -0.02619999999999999 0.00580863 -0.0380936 -0.02519999999999999 0.00580863 -0.0380936 -0.02519999999999999 0.00612355 -0.0386733 -0.02619999999999999 0.00580863 -0.0380936 -0.02519999999999999 0.00539113 -0.0375839 -0.02519999999999999 0.00580863 -0.0380936 -0.02519999999999999 0.00497363 -0.0370742 -0.02519999999999999 0.00539113 -0.0375839 -0.02569999999999999 0.00539113 -0.0375839 -0.02519999999999999 0.00539113 -0.0375839 -0.02619999999999999 0.00580863 -0.0380936 -0.02569999999999999 0.00539113 -0.0375839 -0.02619999999999999 0.00580863 -0.0380936 -0.02619999999999999 0.00497363 -0.0370742 -0.02569999999999999 0.00539113 -0.0375839 -0.02619999999999999 0.00497363 -0.0370742 -0.02519999999999999 0.00497363 -0.0370742 -0.02569999999999999 0.00539113 -0.0375839 -0.02519999999999999 0.00447758 -0.0366584 -0.02519999999999999 0.00497363 -0.0370742 -0.02569999999999999 0.00447758 -0.0366584 -0.02519999999999999 0.00497363 -0.0370742 -0.02619999999999999 0.00497363 -0.0370742 -0.02569999999999999 0.00447758 -0.0366584 -0.02619999999999999 0.00497363 -0.0370742 -0.02619999999999999 0.00398153 -0.0362426 -0.02569999999999999 0.00447758 -0.0366584 -0.02619999999999999 0.00398153 -0.0362426 -0.02519999999999999 0.00447758 -0.0366584 -0.02569999999999999 0.00447758 -0.0366584 -0.02519999999999999 0.00398153 -0.0362426 -0.02519999999999999 0.00447758 -0.0366584 -0.02619999999999999 0.00398153 -0.0362426 -0.02519999999999999 0.00340985 -0.0359219 -0.02519999999999999 0.00398153 -0.0362426 -0.02569999999999999 0.00340985 -0.0359219 -0.02519999999999999 0.00398153 -0.0362426 -0.02619999999999999 0.00398153 -0.0362426 -0.02569999999999999 0.00340985 -0.0359219 -0.02619999999999999 0.00398153 -0.0362426 -0.02619999999999999 0.00283817 -0.0356012 -0.02569999999999999 0.00340985 -0.0359219 -0.02619999999999999 0.00283817 -0.0356012 -0.02519999999999999 0.00340985 -0.0359219 -0.02569999999999999 0.00340985 -0.0359219 -0.02519999999999999 0.00283817 -0.0356012 -0.02519999999999999 0.00340985 -0.0359219 -0.02619999999999999 0.00283817 -0.0356012 -0.02519999999999999 0.00215518 -0.0353789 -0.02519999999999999 0.00283817 -0.0356012 -0.02619999999999999 0.00283817 -0.0356012 -0.02519999999999999 0.0014722 -0.0351566 -0.02519999999999999 0.00215518 -0.0353789 -0.02569999999999999 0.00215518 -0.0353789 -0.02519999999999999 0.00215518 -0.0353789 -0.02619999999999999 0.00283817 -0.0356012 -0.02569999999999999 0.00215518 -0.0353789 -0.02619999999999999 0.00283817 -0.0356012 -0.02619999999999999 0.0014722 -0.0351566 -0.02569999999999999 0.00215518 -0.0353789 -0.02619999999999999 0.0014722 -0.0351566 -0.02519999999999999 0.0014722 -0.0351566 -0.02569999999999999 0.00215518 -0.0353789 -0.02519999999999999 0.000736102 -0.0350783 -0.02519999999999999 0.0014722 -0.0351566 -0.02619999999999999 0.0014722 -0.0351566 -0.02519999999999999 4.28626e-19 -0.035 -0.02519999999999999 0.000736102 -0.0350783 -0.02569999999999999 0.000736101 -0.0350783 -0.02519999999999999 0.000736102 -0.0350783 -0.02619999999999999 0.0014722 -0.0351566 -0.02569999999999999 0.000736101 -0.0350783 -0.02619999999999999 0.0014722 -0.0351566 -0.02619999999999999 4.28626e-19 -0.035 -0.02569999999999999 0.000736101 -0.0350783 -0.02619999999999999 4.28626e-19 -0.035 -0.02519999999999999 4.28626e-19 -0.035 -0.02569999999999999 0.000736101 -0.0350783 -0.02519999999999999 -0.000750082 -0.0350813 -0.02519999999999999 4.28626e-19 -0.035 -0.02619999999999999 4.28626e-19 -0.035 -0.02519999999999999 -0.00150016 -0.0351626 -0.02519999999999999 -0.000750082 -0.0350813 -0.02569999999999999 -0.000750082 -0.0350813 -0.02519999999999999 -0.000750082 -0.0350813 -0.02619999999999999 4.28626e-19 -0.035 -0.02569999999999999 -0.000750082 -0.0350813 -0.02619999999999999 4.28626e-19 -0.035 -0.02619999999999999 -0.00150016 -0.0351626 -0.02569999999999999 -0.000750082 -0.0350813 -0.02619999999999999 -0.00150016 -0.0351626 -0.02519999999999999 -0.00150016 -0.0351626 -0.02569999999999999 -0.000750082 -0.0350813 -0.02519999999999999 -0.00212359 -0.0353621 -0.02519999999999999 -0.00150016 -0.0351626 -0.02569999999999999 -0.00212359 -0.0353621 -0.02519999999999999 -0.00150016 -0.0351626 -0.02619999999999999 -0.00150016 -0.0351626 -0.02569999999999999 -0.00212359 -0.0353621 -0.02619999999999999 -0.00150016 -0.0351626 -0.02619999999999999 -0.00274702 -0.0355615 -0.02569999999999999 -0.00212359 -0.0353621 -0.02619999999999999 -0.00274702 -0.0355615 -0.02519999999999999 -0.00212359 -0.0353621 -0.02569999999999999 -0.00212359 -0.0353621 -0.02519999999999999 -0.00274702 -0.0355615 -0.02519999999999999 -0.00212359 -0.0353621 -0.02619999999999999 -0.00274702 -0.0355615 -0.02519999999999999 -0.0033267 -0.0358764 -0.02519999999999999 -0.00274702 -0.0355615 -0.02619999999999999 -0.00274702 -0.0355615 -0.02519999999999999 -0.00390638 -0.0361914 -0.02519999999999999 -0.0033267 -0.0358764 -0.02569999999999999 -0.0033267 -0.0358764 -0.02519999999999999 -0.0033267 -0.0358764 -0.02619999999999999 -0.00274702 -0.0355615 -0.02569999999999999 -0.0033267 -0.0358764 -0.02619999999999999 -0.00274702 -0.0355615 -0.02619999999999999 -0.00390638 -0.0361914 -0.02569999999999999 -0.0033267 -0.0358764 -0.02619999999999999 -0.00390638 -0.0361914 -0.02519999999999999 -0.00390638 -0.0361914 -0.02569999999999999 -0.0033267 -0.0358764 -0.02519999999999999 -0.00441606 -0.0366089 -0.02519999999999999 -0.00390638 -0.0361914 -0.02619999999999999 -0.00390638 -0.0361914 -0.02519999999999999 -0.00492575 -0.0370264 -0.02519999999999999 -0.00441606 -0.0366089 -0.02569999999999999 -0.00441606 -0.0366089 -0.02519999999999999 -0.00441606 -0.0366089 -0.02619999999999999 -0.00390638 -0.0361914 -0.02569999999999999 -0.00441606 -0.0366089 -0.02619999999999999 -0.00390638 -0.0361914 -0.02619999999999999 -0.00492575 -0.0370264 -0.02569999999999999 -0.00441606 -0.0366089 -0.02619999999999999 -0.00492575 -0.0370264 -0.02519999999999999 -0.00492575 -0.0370264 -0.02569999999999999 -0.00441606 -0.0366089 -0.02519999999999999 -0.00534156 -0.0375224 -0.02519999999999999 -0.00492575 -0.0370264 -0.02569999999999999 -0.00534156 -0.0375224 -0.02519999999999999 -0.00492575 -0.0370264 -0.02619999999999999 -0.00492575 -0.0370264 -0.02569999999999999 -0.00534156 -0.0375224 -0.02619999999999999 -0.00492575 -0.0370264 -0.02619999999999999 -0.00575738 -0.0380185 -0.02569999999999999 -0.00534156 -0.0375224 -0.02619999999999999 -0.00575738 -0.0380185 -0.02519999999999999 -0.00534156 -0.0375224 -0.02569999999999999 -0.00534156 -0.0375224 -0.02619999999999999 -0.00575738 -0.0380185 -0.02519999999999999 -0.00575738 -0.0380185 -0.02519999999999999 -0.00534156 -0.0375224 -0.02519999999999999 -0.0060781 -0.0385901 -0.02519999999999999 -0.00575738 -0.0380185 -0.02569999999999999 -0.0060781 -0.0385901 -0.02519999999999999 -0.00575738 -0.0380185 -0.02619999999999999 -0.00575738 -0.0380185 -0.02569999999999999 -0.0060781 -0.0385901 -0.02619999999999999 -0.00575738 -0.0380185 -0.02619999999999999 -0.00639881 -0.0391618 -0.02569999999999999 -0.0060781 -0.0385901 -0.02619999999999999 -0.00639881 -0.0391618 -0.02519999999999999 -0.0060781 -0.0385901 -0.02569999999999999 -0.0060781 -0.0385901 -0.02619999999999999 -0.00639881 -0.0391618 -0.02519999999999999 -0.00639881 -0.0391618 -0.02519999999999999 -0.0060781 -0.0385901 -0.02619999999999999 -0.00639881 -0.0391618 -0.02519999999999999 -0.00662112 -0.0398448 -0.02519999999999999 -0.00639881 -0.0391618 -0.02519999999999999 -0.00684344 -0.0405278 -0.02519999999999999 -0.00662112 -0.0398448 -0.02569999999999999 -0.00662112 -0.0398448 -0.02519999999999999 -0.00662112 -0.0398448 -0.02619999999999999 -0.00639881 -0.0391618 -0.02569999999999999 -0.00662112 -0.0398448 -0.02619999999999999 -0.00639881 -0.0391618 -0.02619999999999999 -0.00684344 -0.0405278 -0.02569999999999999 -0.00662112 -0.0398448 -0.02619999999999999 -0.00684344 -0.0405278 -0.02519999999999999 -0.00684344 -0.0405278 -0.02569999999999999 -0.00662112 -0.0398448 -0.02619999999999999 -0.00684344 -0.0405278 -0.02519999999999999 -0.00692172 -0.0412639 -0.02519999999999999 -0.00684344 -0.0405278 -0.02519999999999999 -0.007 -0.042 -0.02519999999999999 -0.00692172 -0.0412639 -0.02569999999999999 -0.00692172 -0.0412639 -0.02519999999999999 -0.00692172 -0.0412639 -0.02619999999999999 -0.00684344 -0.0405278 -0.02569999999999999 -0.00692172 -0.0412639 -0.02619999999999999 -0.00684344 -0.0405278 -0.02619999999999999 -0.007 -0.042 -0.02569999999999999 -0.00692172 -0.0412639 -0.02619999999999999 -0.007 -0.042 -0.02519999999999999 -0.007 -0.042 -0.02569999999999999 -0.00692172 -0.0412639 -0.02619999999999999 -0.007 -0.042 -0.02519999999999999 -0.00691868 -0.0427501 -0.02519999999999999 -0.007 -0.042 -0.02519999999999999 -0.00683736 -0.0435002 -0.02519999999999999 -0.00691868 -0.0427501 -0.02569999999999999 -0.00691868 -0.0427501 -0.02519999999999999 -0.00691868 -0.0427501 -0.02619999999999999 -0.007 -0.042 -0.02569999999999999 -0.00691868 -0.0427501 -0.02619999999999999 -0.007 -0.042 -0.02619999999999999 -0.00683736 -0.0435002 -0.02569999999999999 -0.00691868 -0.0427501 -0.02619999999999999 -0.00683736 -0.0435002 -0.02519999999999999 -0.00683736 -0.0435002 -0.02569999999999999 -0.00691868 -0.0427501 -0.02619999999999999 -0.00683736 -0.0435002 -0.02519999999999999 -0.00663791 -0.0441236 -0.02519999999999999 -0.00683736 -0.0435002 -0.02519999999999999 -0.00643847 -0.044747 -0.02519999999999999 -0.00663791 -0.0441236 -0.02569999999999999 -0.00663791 -0.0441236 -0.02519999999999999 -0.00663791 -0.0441236 -0.02619999999999999 -0.00683736 -0.0435002 -0.02569999999999999 -0.00663791 -0.0441236 -0.02619999999999999 -0.00683736 -0.0435002 -0.02619999999999999 -0.00643847 -0.044747 -0.02569999999999999 -0.00663791 -0.0441236 -0.02619999999999999 -0.00643847 -0.044747 -0.02519999999999999 -0.00643847 -0.044747 -0.02569999999999999 -0.00663791 -0.0441236 -0.02519999999999999 -0.00612355 -0.0453267 -0.02519999999999999 -0.00643847 -0.044747 -0.02569999999999999 -0.00612355 -0.0453267 -0.02519999999999999 -0.00643847 -0.044747 -0.02619999999999999 -0.00643847 -0.044747 -0.02569999999999999 -0.00612355 -0.0453267 -0.02619999999999999 -0.00643847 -0.044747 -0.02619999999999999 -0.00580863 -0.0459064 -0.02569999999999999 -0.00612355 -0.0453267 -0.02619999999999999 -0.00580863 -0.0459064 -0.02519999999999999 -0.00612355 -0.0453267 -0.02569999999999999 -0.00612355 -0.0453267 -0.02619999999999999 -0.00580863 -0.0459064 -0.02519999999999999 -0.00580863 -0.0459064 -0.02519999999999999 -0.00612355 -0.0453267 -0.02619999999999999 -0.00580863 -0.0459064 -0.02519999999999999 -0.00539113 -0.0464161 -0.02519999999999999 -0.00580863 -0.0459064 -0.02519999999999999 0.00150016 -0.0488374 -0.02519999999999999 0.000750082 -0.0489187 -0.02569999999999999 0.000750082 -0.0489187 -0.02519999999999999 0.000750082 -0.0489187 -0.02619999999999999 -7.503130000000001e-18 -0.049 -0.02569999999999999 0.000750082 -0.0489187 -0.02619999999999999 -7.503130000000001e-18 -0.049 -0.02619999999999999 0.00150016 -0.0488374 -0.02569999999999999 0.000750082 -0.0489187 -0.02619999999999999 0.00150016 -0.0488374 -0.02519999999999999 0.00150016 -0.0488374 -0.02569999999999999 0.000750082 -0.0489187 -0.02519999999999999 0.00212359 -0.0486379 -0.02519999999999999 0.00150016 -0.0488374 -0.02569999999999999 0.00212359 -0.0486379 -0.02519999999999999 0.00150016 -0.0488374 -0.02619999999999999 0.00150016 -0.0488374 -0.02569999999999999 0.00212359 -0.0486379 -0.02619999999999999 0.00150016 -0.0488374 -0.02619999999999999 0.00274702 -0.0484385 -0.02569999999999999 0.00212359 -0.0486379 -0.02619999999999999 0.00274702 -0.0484385 -0.02519999999999999 0.00212359 -0.0486379 -0.02569999999999999 0.00212359 -0.0486379 -0.02519999999999999 0.00274702 -0.0484385 -0.02519999999999999 0.00212359 -0.0486379 -0.02619999999999999 0.00274702 -0.0484385 -0.02519999999999999 0.0033267 -0.0481235 -0.02519999999999999 0.00274702 -0.0484385 -0.02619999999999999 0.00274702 -0.0484385 -0.02519999999999999 0.00390638 -0.0478086 -0.02519999999999999 0.0033267 -0.0481235 -0.02569999999999999 0.0033267 -0.0481235 -0.02519999999999999 0.0033267 -0.0481235 -0.02619999999999999 0.00274702 -0.0484385 -0.02569999999999999 0.0033267 -0.0481235 -0.02619999999999999 0.00274702 -0.0484385 -0.02619999999999999 0.00390638 -0.0478086 -0.02569999999999999 0.0033267 -0.0481235 -0.02619999999999999 0.00390638 -0.0478086 -0.02519999999999999 0.00390638 -0.0478086 -0.02569999999999999 0.0033267 -0.0481235 -0.02519999999999999 0.00441606 -0.0473911 -0.02519999999999999 0.00390638 -0.0478086 -0.02619999999999999 0.00390638 -0.0478086 -0.02519999999999999 0.00492575 -0.0469736 -0.02519999999999999 0.00441606 -0.0473911 -0.02569999999999999 0.00441606 -0.0473911 -0.02519999999999999 0.00441606 -0.0473911 -0.02619999999999999 0.00390638 -0.0478086 -0.02569999999999999 0.00441606 -0.0473911 -0.02619999999999999 0.00390638 -0.0478086 -0.02619999999999999 0.00492575 -0.0469736 -0.02569999999999999 0.00441606 -0.0473911 -0.02619999999999999 0.00492575 -0.0469736 -0.02519999999999999 0.00492575 -0.0469736 -0.02569999999999999 0.00441606 -0.0473911 -0.02519999999999999 0.00534156 -0.0464776 -0.02519999999999999 0.00492575 -0.0469736 -0.02569999999999999 0.00534156 -0.0464776 -0.02519999999999999 0.00492575 -0.0469736 -0.02619999999999999 0.00492575 -0.0469736 -0.02569999999999999 0.00534156 -0.0464776 -0.02619999999999999 0.00492575 -0.0469736 -0.02619999999999999 0.00575738 -0.0459815 -0.02569999999999999 0.00534156 -0.0464776 -0.02619999999999999 0.00575738 -0.0459815 -0.02519999999999999 0.00534156 -0.0464776 -0.02569999999999999 0.00534156 -0.0464776 -0.02619999999999999 0.00575738 -0.0459815 -0.02519999999999999 0.00575738 -0.0459815 -0.02519999999999999 0.00534156 -0.0464776 -0.02619999999999999 0.00575738 -0.0459815 -0.02519999999999999 0.0060781 -0.0454099 -0.02519999999999999 0.00575738 -0.0459815 -0.02519999999999999 0.00639881 -0.0448382 -0.02519999999999999 0.0060781 -0.0454099 -0.02569999999999999 0.0060781 -0.0454099 -0.02519999999999999 0.0060781 -0.0454099 -0.02619999999999999 0.00575738 -0.0459815 -0.02569999999999999 0.0060781 -0.0454099 -0.02619999999999999 0.00575738 -0.0459815 -0.02619999999999999 0.00639881 -0.0448382 -0.02569999999999999 0.0060781 -0.0454099 -0.02619999999999999 0.00639881 -0.0448382 -0.02519999999999999 0.00639881 -0.0448382 -0.02569999999999999 0.0060781 -0.0454099 -0.02619999999999999 0.00639881 -0.0448382 -0.02519999999999999 0.00662112 -0.0441552 -0.02519999999999999 0.00639881 -0.0448382 -0.02519999999999999 0.00684344 -0.0434722 -0.02519999999999999 0.00662112 -0.0441552 -0.02569999999999999 0.00662112 -0.0441552 -0.02519999999999999 0.00662112 -0.0441552 -0.02619999999999999 0.00639881 -0.0448382 -0.02569999999999999 0.00662112 -0.0441552 -0.02619999999999999 0.00639881 -0.0448382 -0.02619999999999999 0.00684344 -0.0434722 -0.02569999999999999 0.00662112 -0.0441552 -0.02619999999999999 0.00684344 -0.0434722 -0.02519999999999999 0.00684344 -0.0434722 -0.02569999999999999 0.00662112 -0.0441552 -0.02619999999999999 0.00684344 -0.0434722 -0.02519999999999999 0.00692172 -0.0427361 -0.02519999999999999 0.00684344 -0.0434722 -0.02519999999999999 0.007 -0.042 -0.02519999999999999 0.00692172 -0.0427361 -0.02569999999999999 0.00692172 -0.0427361 -0.02519999999999999 0.00692172 -0.0427361 -0.02619999999999999 0.00684344 -0.0434722 -0.02569999999999999 0.00692172 -0.0427361 -0.02619999999999999 0.00684344 -0.0434722 -0.02619999999999999 0.007 -0.042 -0.02569999999999999 0.00692172 -0.0427361 -0.02619999999999999 0.007 -0.042 -0.02519999999999999 0.007 -0.042 -0.02569999999999999 0.00692172 -0.0427361 -0.02619999999999999 -0.0035 -0.0455 -0.02619999999999999 -0.00497363 -0.0469257 -0.02619999999999999 -0.00580863 -0.0459064 -0.02619999999999999 -0.0035 -0.0455 -0.02619999999999999 -0.00398153 -0.0477574 -0.02619999999999999 -0.00497363 -0.0469257 -0.02619999999999999 -0.00283817 -0.0483988 -0.02619999999999999 -0.00398153 -0.0477574 -0.02619999999999999 -0.0035 -0.0455 -0.02619999999999999 -0.0014722 -0.0488434 -0.02619999999999999 -0.00283817 -0.0483988 -0.02619999999999999 -1.0842e-19 -0.0455 -0.02619999999999999 -7.503130000000001e-18 -0.049 -0.02619999999999999 -0.0014722 -0.0488434 -0.02619999999999999 -1.0842e-19 -0.0455 -0.02619999999999999 0.00683736 -0.0404998 -0.02619999999999999 0.007 -0.042 -0.02619999999999999 0.0035 -0.042 -0.02619999999999999 0.00683736 -0.0404998 -0.02619999999999999 0.0035 -0.042 -0.02619999999999999 0.00643847 -0.039253 -0.02619999999999999 0.00580863 -0.0380936 -0.02619999999999999 0.00643847 -0.039253 -0.02619999999999999 0.0035 -0.0385 -0.02619999999999999 0.00497363 -0.0370742 -0.02619999999999999 0.00580863 -0.0380936 -0.02619999999999999 0.0035 -0.0385 -0.02619999999999999 0.00497363 -0.0370742 -0.02619999999999999 0.0035 -0.0385 -0.02619999999999999 0.00398153 -0.0362426 -0.02619999999999999 0.00398153 -0.0362426 -0.02619999999999999 0.0035 -0.0385 -0.02619999999999999 0.00283817 -0.0356012 -0.02619999999999999 0.00283817 -0.0356012 -0.02619999999999999 0 -0.0385 -0.02619999999999999 0.0014722 -0.0351566 -0.02619999999999999 0.0014722 -0.0351566 -0.02619999999999999 0 -0.0385 -0.02619999999999999 4.28626e-19 -0.035 -0.02619999999999999 4.28626e-19 -0.035 -0.02619999999999999 0 -0.0385 -0.02619999999999999 -0.00150016 -0.0351626 -0.02619999999999999 -0.00150016 -0.0351626 -0.02619999999999999 0 -0.0385 -0.02619999999999999 -0.00274702 -0.0355615 -0.02619999999999999 -0.00274702 -0.0355615 -0.02619999999999999 -0.0035 -0.0385 -0.02619999999999999 -0.00390638 -0.0361914 -0.02619999999999999 -0.00390638 -0.0361914 -0.02619999999999999 -0.0035 -0.0385 -0.02619999999999999 -0.00492575 -0.0370264 -0.02619999999999999 -0.0035 -0.0385 -0.02619999999999999 -0.00575738 -0.0380185 -0.02619999999999999 -0.00492575 -0.0370264 -0.02619999999999999 -0.0035 -0.0385 -0.02619999999999999 -0.00639881 -0.0391618 -0.02619999999999999 -0.00575738 -0.0380185 -0.02619999999999999 -0.00684344 -0.0405278 -0.02619999999999999 -0.00639881 -0.0391618 -0.02619999999999999 -0.0035 -0.042 -0.02619999999999999 -0.0035 -0.042 -0.02619999999999999 -0.007 -0.042 -0.02619999999999999 -0.00684344 -0.0405278 -0.02619999999999999 -0.0035 -0.042 -0.02619999999999999 -0.00683736 -0.0435002 -0.02619999999999999 -0.007 -0.042 -0.02619999999999999 -0.00643847 -0.044747 -0.02619999999999999 -0.00683736 -0.0435002 -0.02619999999999999 -0.0035 -0.042 -0.02619999999999999 -0.0035 -0.0455 -0.02619999999999999 -0.00580863 -0.0459064 -0.02619999999999999 -0.00643847 -0.044747 -0.02619999999999999 0.00150016 -0.0488374 -0.02619999999999999 -7.503130000000001e-18 -0.049 -0.02619999999999999 -1.0842e-19 -0.0455 -0.02619999999999999 0.00274702 -0.0484385 -0.02619999999999999 0.00150016 -0.0488374 -0.02619999999999999 -1.0842e-19 -0.0455 -0.02619999999999999 0.00390638 -0.0478086 -0.02619999999999999 0.00274702 -0.0484385 -0.02619999999999999 0.0035 -0.0455 -0.02619999999999999 0.00492575 -0.0469736 -0.02619999999999999 0.00390638 -0.0478086 -0.02619999999999999 0.0035 -0.0455 -0.02619999999999999 0.00575738 -0.0459815 -0.02619999999999999 0.00492575 -0.0469736 -0.02619999999999999 0.0035 -0.0455 -0.02619999999999999 0.00639881 -0.0448382 -0.02619999999999999 0.00575738 -0.0459815 -0.02619999999999999 0.0035 -0.0455 -0.02619999999999999 0.00639881 -0.0448382 -0.02619999999999999 0.0035 -0.042 -0.02619999999999999 0.00684344 -0.0434722 -0.02619999999999999 0.007 -0.042 -0.02619999999999999 0.00684344 -0.0434722 -0.02619999999999999 0.0035 -0.042 -0.02619999999999999 -1.0842e-19 -0.0455 -0.02619999999999999 -0.00283817 -0.0483988 -0.02619999999999999 -0.0035 -0.0455 -0.02619999999999999 0.00643847 -0.039253 -0.02619999999999999 0.0035 -0.042 -0.02619999999999999 0.0035 -0.0385 -0.02619999999999999 0.0035 -0.0385 -0.02619999999999999 0 -0.0385 -0.02619999999999999 0.00283817 -0.0356012 -0.02619999999999999 0 -0.0385 -0.02619999999999999 -0.0035 -0.0385 -0.02619999999999999 -0.00274702 -0.0355615 -0.02619999999999999 -0.0035 -0.0385 -0.02619999999999999 -0.0035 -0.042 -0.02619999999999999 -0.00639881 -0.0391618 -0.02619999999999999 -0.0035 -0.042 -0.02619999999999999 -0.0035 -0.0455 -0.02619999999999999 -0.00643847 -0.044747 -0.02619999999999999 0.0035 -0.0455 -0.02619999999999999 0.00274702 -0.0484385 -0.02619999999999999 -1.0842e-19 -0.0455 -0.02619999999999999 0.00639881 -0.0448382 -0.02619999999999999 0.0035 -0.0455 -0.02619999999999999 0.0035 -0.042 -0.02619999999999999 -1.0842e-19 -0.0455 -0.02619999999999999 -0.0035 -0.0455 -0.02619999999999999 -0.0035 -0.042 -0.02619999999999999 0.0035 -0.0385 -0.02619999999999999 0.0035 -0.042 -0.02619999999999999 0 -0.0385 -0.02619999999999999 0 -0.0385 -0.02619999999999999 0 -0.042 -0.02619999999999999 -0.0035 -0.0385 -0.02619999999999999 0 -0.042 -0.02619999999999999 -0.0035 -0.042 -0.02619999999999999 -0.0035 -0.0385 -0.02619999999999999 0.0035 -0.0455 -0.02619999999999999 -1.0842e-19 -0.0455 -0.02619999999999999 0 -0.042 -0.02619999999999999 0.0035 -0.042 -0.02619999999999999 0.0035 -0.0455 -0.02619999999999999 0 -0.042 -0.02619999999999999 0 -0.042 -0.02619999999999999 -1.0842e-19 -0.0455 -0.02619999999999999 -0.0035 -0.042 -0.02619999999999999 0.0035 -0.042 -0.02619999999999999 0 -0.042 -0.02619999999999999 0 -0.0385 -0.02519999999999999 -0.02 -0.0526 -0.01629999999999999 -0.02 -0.0526 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 0.000664345 -0.048928 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 -7.503130000000001e-18 -0.049 -0.02519999999999999 -7.503130000000001e-18 -0.049 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 -0.000736101 -0.0489217 -0.02519999999999999 -0.000736101 -0.0489217 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 -0.0014722 -0.0488434 -0.02519999999999999 -0.00523391 -0.046608 -0.02519999999999999 -0.00497363 -0.0469257 -0.02519999999999999 -0.02 -0.0526 -0.02519999999999999 -0.00497363 -0.0469257 -0.02519999999999999 -0.00447758 -0.0473416 -0.02519999999999999 -0.02 -0.0526 -0.02519999999999999 -0.00447758 -0.0473416 -0.02519999999999999 -0.00398153 -0.0477574 -0.02519999999999999 -0.02 -0.0526 -0.02519999999999999 -0.00398153 -0.0477574 -0.02519999999999999 -0.00340985 -0.0480781 -0.02519999999999999 -0.02 -0.0526 -0.02519999999999999 -0.00340985 -0.0480781 -0.02519999999999999 -0.00283817 -0.0483988 -0.02519999999999999 -0.02 -0.0526 -0.02519999999999999 -0.00283817 -0.0483988 -0.02519999999999999 -0.00215518 -0.0486211 -0.02519999999999999 -0.02 -0.0526 -0.02519999999999999 -0.00215518 -0.0486211 -0.02519999999999999 -0.0014722 -0.0488434 -0.02519999999999999 -0.02 -0.0526 -0.02519999999999999 -0.0014722 -0.0488434 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 -0.02 -0.0526 -0.02519999999999999 -0.00523391 -0.046608 -0.02519999999999999 -0.02 -0.0526 -0.02519999999999999 -0.02 -0.0408 -0.01629999999999999 -0.02 -0.0526 -0.02519999999999999 -0.02 -0.0526 -0.02519999999999999 0.01 -0.0526 -0.007399999999999993 -0.02 -0.0408 -0.02519999999999999 -0.02 -0.0408 -0.01629999999999999 -0.02 -0.0467 -0.02519999999999999 -0.02 -0.0408 -0.01629999999999999 -0.02 -0.0526 -0.01629999999999999 -0.02 -0.0467 -0.01629999999999999 -0.02 -0.0526 -0.007399999999999993 -0.02 -0.0408 -0.01629999999999999 -0.02 -0.0467 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.00492575 -0.0469736 -0.02519999999999999 0.00534156 -0.0464776 -0.02519999999999999 0.00492575 -0.0469736 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.00441606 -0.0473911 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.00534156 -0.0464776 -0.02519999999999999 0.00575738 -0.0459815 -0.02519999999999999 0.00441606 -0.0473911 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.00390638 -0.0478086 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.00575738 -0.0459815 -0.02519999999999999 0.0060781 -0.0454099 -0.02519999999999999 0.00390638 -0.0478086 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.0033267 -0.0481235 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.0060781 -0.0454099 -0.02519999999999999 0.00639881 -0.0448382 -0.02519999999999999 0.0033267 -0.0481235 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.00274702 -0.0484385 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.00639881 -0.0448382 -0.02519999999999999 0.00662112 -0.0441552 -0.02519999999999999 0.00274702 -0.0484385 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.00212359 -0.0486379 -0.02519999999999999 0.00212359 -0.0486379 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.00150016 -0.0488374 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.00662112 -0.0441552 -0.02519999999999999 0.00684344 -0.0434722 -0.02519999999999999 0.00150016 -0.0488374 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.000750082 -0.0489187 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.00684344 -0.0434722 -0.02519999999999999 0.00692172 -0.0427361 -0.02519999999999999 0.000750082 -0.0489187 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.000664345 -0.048928 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.00692172 -0.0427361 -0.02519999999999999 0.007 -0.042 -0.02519999999999999 0.007 -0.042 -0.02519999999999999 0.00691868 -0.0412499 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.00691868 -0.0412499 -0.02519999999999999 0.00683736 -0.0404998 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.00683736 -0.0404998 -0.02519999999999999 0.00663791 -0.0398764 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.00663791 -0.0398764 -0.02519999999999999 0.00643847 -0.039253 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.00643847 -0.039253 -0.02519999999999999 0.00612355 -0.0386733 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.00612355 -0.0386733 -0.02519999999999999 0.00580863 -0.0380936 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.00580863 -0.0380936 -0.02519999999999999 0.00539113 -0.0375839 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.00539113 -0.0375839 -0.02519999999999999 0.00497363 -0.0370742 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.00497363 -0.0370742 -0.02519999999999999 0.00447758 -0.0366584 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.00447758 -0.0366584 -0.02519999999999999 0.00398153 -0.0362426 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.00398153 -0.0362426 -0.02519999999999999 0.00340985 -0.0359219 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.007 -0.042 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.00340985 -0.0359219 -0.02519999999999999 0.00283817 -0.0356012 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.00283817 -0.0356012 -0.02519999999999999 0.00215518 -0.0353789 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.00215518 -0.0353789 -0.02519999999999999 0.0014722 -0.0351566 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.0014722 -0.0351566 -0.02519999999999999 0.000736102 -0.0350783 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.000736102 -0.0350783 -0.02519999999999999 4.28626e-19 -0.035 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 4.28626e-19 -0.035 -0.02519999999999999 -0.000750082 -0.0350813 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 -0.000750082 -0.0350813 -0.02519999999999999 -0.00150016 -0.0351626 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 -0.00150016 -0.0351626 -0.02519999999999999 -0.00212359 -0.0353621 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 -0.00212359 -0.0353621 -0.02519999999999999 -0.00274702 -0.0355615 -0.02519999999999999 -0.00274702 -0.0355615 -0.02519999999999999 -0.0033267 -0.0358764 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.0033267 -0.0358764 -0.02519999999999999 -0.00390638 -0.0361914 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.00390638 -0.0361914 -0.02519999999999999 -0.00441606 -0.0366089 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.00441606 -0.0366089 -0.02519999999999999 -0.00492575 -0.0370264 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.00492575 -0.0370264 -0.02519999999999999 -0.00534156 -0.0375224 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.00534156 -0.0375224 -0.02519999999999999 -0.00575738 -0.0380185 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.00575738 -0.0380185 -0.02519999999999999 -0.0060781 -0.0385901 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.0060781 -0.0385901 -0.02519999999999999 -0.00639881 -0.0391618 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.00639881 -0.0391618 -0.02519999999999999 -0.00662112 -0.0398448 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.00662112 -0.0398448 -0.02519999999999999 -0.00684344 -0.0405278 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.00684344 -0.0405278 -0.02519999999999999 -0.00692172 -0.0412639 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.00692172 -0.0412639 -0.02519999999999999 -0.007 -0.042 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.007 -0.042 -0.02519999999999999 -0.00691868 -0.0427501 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.00691868 -0.0427501 -0.02519999999999999 -0.00683736 -0.0435002 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.00683736 -0.0435002 -0.02519999999999999 -0.00663791 -0.0441236 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.00663791 -0.0441236 -0.02519999999999999 -0.00643847 -0.044747 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.00643847 -0.044747 -0.02519999999999999 -0.00612355 -0.0453267 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.00612355 -0.0453267 -0.02519999999999999 -0.00580863 -0.0459064 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.00580863 -0.0459064 -0.02519999999999999 -0.00539113 -0.0464161 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.00539113 -0.0464161 -0.02519999999999999 -0.00523391 -0.046608 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.00274702 -0.0355615 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 0.01 -0.029 -0.01629999999999999 -0.02 -0.0526 -0.02519999999999999 0.01 -0.0526 -0.007399999999999993 0.01 -0.0526 -0.02519999999999999 -0.02 -0.0408 -0.007399999999999993 -0.02 -0.0408 -0.01629999999999999 -0.02 -0.0349 -0.007399999999999993 -0.02 -0.0408 -0.01629999999999999 -0.02 -0.029 -0.01629999999999999 -0.02 -0.0349 -0.01629999999999999 -0.02 -0.029 -0.02519999999999999 -0.02 -0.0408 -0.01629999999999999 -0.02 -0.0349 -0.01629999999999999 -0.02 -0.0526 -0.007399999999999993 -0.02 -0.0526 -0.007399999999999993 -0.02 -0.0408 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 -0.02 -0.0408 -0.02519999999999999 -0.02 -0.029 -0.02519999999999999 0.04 -0.0408 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.01 -0.029 -0.007399999999999993 0.01 -0.0526 -0.02519999999999999 0.01 -0.0526 -0.01629999999999999 0.04 -0.0526 -0.007399999999999993 -0.02 -0.0526 -0.01629999999999999 -0.02 -0.0526 -0.007399999999999993 0.01 -0.0526 -0.01629999999999999 -0.02 -0.029 -0.007399999999999993 -0.02 -0.0408 -0.007399999999999993 -0.02 -0.029 -0.02519999999999999 -0.02 -0.029 -0.02519999999999999 -0.02 -0.0408 -0.01629999999999999 -0.02 -0.029 -0.007399999999999993 0.01 -0.0526 -0.007399999999999993 -0.02 -0.0408 -0.007399999999999993 -0.02 -0.0526 -0.02519999999999999 -0.02 -0.029 -0.01629999999999999 -0.02 -0.029 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.04 -0.029 -0.02519999999999999 0.04 -0.0408 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.04 -0.0408 -0.02519999999999999 0.04 -0.0526 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.01 -0.0526 -0.02519999999999999 0.04 -0.0526 -0.01629999999999999 0.04 -0.0526 -0.007399999999999993 0.01 -0.0526 -0.01629999999999999 0.04 -0.0526 -0.007399999999999993 0.04 -0.0526 -0.007399999999999993 0.01 -0.029 -0.007399999999999993 -0.02 -0.029 -0.007399999999999993 -0.02 -0.0408 -0.01629999999999999 -0.02 -0.029 -0.007399999999999993 -0.02 -0.029 -0.007399999999999993 0.01 -0.029 -0.007399999999999993 0.01 -0.0526 -0.007399999999999993 0.01 -0.029 -0.007399999999999993 -0.02 -0.0408 -0.01629999999999999 -0.02 -0.029 -0.007399999999999993 0.01 -0.029 -0.02519999999999999 0.01 -0.029 -0.02519999999999999 0.01 -0.029 -0.01629999999999999 0.04 -0.029 -0.02519999999999999 0.04 -0.029 -0.02519999999999999 0.04 -0.029 -0.01629999999999999 0.04 -0.029 -0.02519999999999999 0.04 -0.0408 -0.02519999999999999 0.04 -0.0526 -0.02519999999999999 0.04 -0.0408 -0.01629999999999999 0.04 -0.0526 -0.01629999999999999 0.04 -0.0526 -0.007399999999999993 0.04 -0.0408 -0.007399999999999993 0.04 -0.0526 -0.007399999999999993 0.04 -0.0526 -0.007399999999999993 0.04 -0.0408 -0.007399999999999993 0.01 -0.0526 -0.007399999999999993 0.04 -0.0408 -0.007399999999999993 0.01 -0.029 -0.007399999999999993 0.01 -0.0526 -0.02519999999999999 0.01 -0.029 -0.007399999999999993 0.01 -0.029 -0.01629999999999999 0.04 -0.029 -0.007399999999999993 0.04 -0.0408 -0.02519999999999999 0.04 -0.0408 -0.01629999999999999 0.04 -0.0349 -0.02519999999999999 0.04 -0.0408 -0.01629999999999999 0.04 -0.029 -0.01629999999999999 0.04 -0.0349 -0.01629999999999999 0.04 -0.029 -0.007399999999999993 0.04 -0.0408 -0.01629999999999999 0.04 -0.0349 -0.02519999999999999 0.04 -0.0408 -0.007399999999999993 0.04 -0.0408 -0.01629999999999999 0.04 -0.0467 -0.007399999999999993 0.04 -0.0408 -0.01629999999999999 0.04 -0.0526 -0.01629999999999999 0.04 -0.0467 -0.01629999999999999 0.04 -0.0526 -0.02519999999999999 0.04 -0.0408 -0.01629999999999999 0.04 -0.0467 -0.007399999999999993 0.04 -0.0408 -0.007399999999999993 0.04 -0.029 -0.007399999999999993 0.01 -0.029 -0.007399999999999993 0.01 -0.029 -0.007399999999999993 0.04 -0.029 -0.01629999999999999 0.04 -0.029 -0.01629999999999999 0.04 -0.029 -0.007399999999999993 0.04 -0.029 -0.007399999999999993 0.04 -0.0408 6.938893903907228e-18 0.022 -0.022 6.938893903907228e-18 0.022 0.022 6.938893903907228e-18 0.0152426 1.04083e-17 6.938893903907228e-18 0.022 0.022 6.938893903907228e-18 0.008485299999999999 0.008485299999999999 6.938893903907228e-18 0.0152426 1.04083e-17 6.938893903907228e-18 0.008485299999999999 0.008485299999999999 6.938893903907228e-18 0.012 0 6.938893903907228e-18 0.0152426 1.04083e-17 6.938893903907228e-18 0.012 0 6.938893903907228e-18 0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 0.0152426 1.04083e-17 6.938893903907228e-18 0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 0.022 -0.022 6.938893903907228e-18 0.0152426 1.04083e-17 -0.005829549999999993 0.022 0.0125 6.938893903907228e-18 0.022 0.022 -0.002899999999999993 0.022 0.0125 -0.005829549999999993 0.022 -0.0125 -0.002899999999999993 0.022 -0.0125 6.938893903907228e-18 0.022 -0.022 -0.002899999999999993 0.022 0.0125 6.938893903907228e-18 0.022 0.022 6.938893903907228e-18 0.022 -0.022 -0.002899999999999993 0.022 -0.0125 -0.002899999999999993 0.022 0.0125 6.938893903907228e-18 0.022 -0.022 6.938893903907228e-18 0.022 0.022 6.938893903907228e-18 -0.022 0.022 6.938893903907228e-18 1.04083e-17 0.0152426 6.938893903907228e-18 -0.022 0.022 6.938893903907228e-18 -0.008485299999999999 0.008485299999999999 6.938893903907228e-18 1.04083e-17 0.0152426 6.938893903907228e-18 -0.008485299999999999 0.008485299999999999 6.938893903907228e-18 0 0.012 6.938893903907228e-18 1.04083e-17 0.0152426 6.938893903907228e-18 0 0.012 6.938893903907228e-18 0.008485299999999999 0.008485299999999999 6.938893903907228e-18 1.04083e-17 0.0152426 6.938893903907228e-18 0.008485299999999999 0.008485299999999999 6.938893903907228e-18 0.022 0.022 6.938893903907228e-18 1.04083e-17 0.0152426 6.938893903907228e-18 0.008485299999999999 0.008485299999999999 0.001500000000000007 0.0102426 0.0042426 6.938893903907228e-18 0.012 0 6.938893903907228e-18 0.012 0 0.001500000000000007 0.0102426 -0.0042426 6.938893903907228e-18 0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 -0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 -0.022 -0.022 6.938893903907228e-18 -1.21431e-17 -0.0152426 6.938893903907228e-18 -0.022 -0.022 6.938893903907228e-18 0.022 -0.022 6.938893903907228e-18 -1.21431e-17 -0.0152426 6.938893903907228e-18 0.022 -0.022 6.938893903907228e-18 0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 -1.21431e-17 -0.0152426 6.938893903907228e-18 0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 0 -0.012 6.938893903907228e-18 -1.21431e-17 -0.0152426 6.938893903907228e-18 0 -0.012 6.938893903907228e-18 -0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 -1.21431e-17 -0.0152426 -0.02699999999999999 0.022 0.022 6.938893903907228e-18 0.022 0.022 -0.01349999999999999 0.022 0.01725 6.938893903907228e-18 0.022 0.022 -0.005829549999999993 0.022 0.0125 -0.01349999999999999 0.022 0.01725 -0.005829549999999993 0.022 0.0125 -0.02117049999999999 0.022 0.0125 -0.01349999999999999 0.022 0.01725 -0.02117049999999999 0.022 0.0125 -0.02699999999999999 0.022 0.022 -0.01349999999999999 0.022 0.01725 6.938893903907228e-18 0.022 -0.022 -0.02699999999999999 0.022 -0.022 -0.01349999999999999 0.022 -0.01725 -0.02699999999999999 0.022 -0.022 -0.02117049999999999 0.022 -0.0125 -0.01349999999999999 0.022 -0.01725 -0.02117049999999999 0.022 -0.0125 -0.005829549999999993 0.022 -0.0125 -0.01349999999999999 0.022 -0.01725 -0.005829549999999993 0.022 -0.0125 6.938893903907228e-18 0.022 -0.022 -0.01349999999999999 0.022 -0.01725 -0.02699999999999999 0.022 -0.0125 -0.03869999999999999 0.022 -0.0125 -0.02784939999999999 0.0309494 -0.0125 -0.002899999999999993 0.022 -0.0125 -0.005829549999999993 0.022 -0.0125 -0.02079999999999999 0.0264747 -0.0125 -0.02784939999999999 0.0309494 -0.0125 -0.002899999999999993 0.022 -0.0125 -0.02079999999999999 0.0264747 -0.0125 -0.005829549999999993 0.022 -0.0125 -0.02117049999999999 0.022 -0.0125 -0.02079999999999999 0.0264747 -0.0125 -0.02117049999999999 0.022 -0.0125 -0.02699999999999999 0.022 -0.0125 -0.02079999999999999 0.0264747 -0.0125 -0.02699999999999999 0.022 -0.0125 -0.02784939999999999 0.0309494 -0.0125 -0.02079999999999999 0.0264747 -0.0125 -0.002899999999999993 0.0324 0 -0.002899999999999993 0.022 0.0125 -0.002899999999999993 0.0272 0 -0.002899999999999993 0.022 -0.0125 -0.002899999999999993 0.0324 0 -0.002899999999999993 0.0272 0 -0.002899999999999993 0.022 0.0125 -0.002899999999999993 0.022 -0.0125 -0.002899999999999993 0.0272 0 -0.02699999999999999 0.022 0.0125 -0.02777869999999999 0.0308787 0.0125 -0.03869999999999999 0.022 0.0125 -0.002899999999999993 0.022 0.0125 -0.02777869999999999 0.0308787 0.0125 -0.02079999999999999 0.0264394 0.0125 -0.005829549999999993 0.022 0.0125 -0.002899999999999993 0.022 0.0125 -0.02079999999999999 0.0264394 0.0125 -0.02117049999999999 0.022 0.0125 -0.005829549999999993 0.022 0.0125 -0.02079999999999999 0.0264394 0.0125 -0.02699999999999999 0.022 0.0125 -0.02117049999999999 0.022 0.0125 -0.02079999999999999 0.0264394 0.0125 -0.02777869999999999 0.0308787 0.0125 -0.02699999999999999 0.022 0.0125 -0.02079999999999999 0.0264394 0.0125 -0.01349999999999999 0 0.022 6.938893903907228e-18 -0.022 0.022 -0.006749999999999993 -1.73472e-18 0.022 6.938893903907228e-18 -0.022 0.022 6.938893903907228e-18 0.022 0.022 -0.006749999999999993 -1.73472e-18 0.022 6.938893903907228e-18 0.022 0.022 -0.01349999999999999 0 0.022 -0.006749999999999993 -1.73472e-18 0.022 6.938893903907228e-18 -0.008485299999999999 0.008485299999999999 6.938893903907228e-18 -0.022 0.022 6.938893903907228e-18 -0.0152426 1.73472e-18 6.938893903907228e-18 -0.022 0.022 6.938893903907228e-18 -0.022 -0.022 6.938893903907228e-18 -0.0152426 1.73472e-18 6.938893903907228e-18 -0.022 -0.022 6.938893903907228e-18 -0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 -0.0152426 1.73472e-18 6.938893903907228e-18 -0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 -0.012 0 6.938893903907228e-18 -0.0152426 1.73472e-18 6.938893903907228e-18 -0.012 0 6.938893903907228e-18 -0.008485299999999999 0.008485299999999999 6.938893903907228e-18 -0.0152426 1.73472e-18 6.938893903907228e-18 -0.008485299999999999 0.008485299999999999 0.001500000000000007 -0.0042426 0.0102426 6.938893903907228e-18 0 0.012 6.938893903907228e-18 0 0.012 0.001500000000000007 0.0042426 0.0102426 6.938893903907228e-18 0.008485299999999999 0.008485299999999999 6.938893903907228e-18 0.012 0 0.001500000000000007 0.0102426 0.0042426 0.003000000000000007 0.012 0 6.938893903907228e-18 0.008485299999999999 0.008485299999999999 0.003000000000000007 0.008485299999999999 0.008485299999999999 0.001500000000000007 0.0102426 0.0042426 6.938893903907228e-18 0.008485299999999999 -0.008485299999999999 0.001500000000000007 0.0102426 -0.0042426 0.003000000000000007 0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 0.012 0 0.003000000000000007 0.012 0 0.001500000000000007 0.0102426 -0.0042426 -0.01349999999999999 0 -0.022 6.938893903907228e-18 0.022 -0.022 -0.006749999999999993 1.73472e-18 -0.022 6.938893903907228e-18 0.022 -0.022 6.938893903907228e-18 -0.022 -0.022 -0.006749999999999993 1.73472e-18 -0.022 6.938893903907228e-18 -0.022 -0.022 -0.01349999999999999 0 -0.022 -0.006749999999999993 1.73472e-18 -0.022 6.938893903907228e-18 0.008485299999999999 -0.008485299999999999 0.001500000000000007 0.0042426 -0.0102426 6.938893903907228e-18 0 -0.012 6.938893903907228e-18 0 -0.012 0.001500000000000007 -0.0042426 -0.0102426 6.938893903907228e-18 -0.008485299999999999 -0.008485299999999999 -0.01349999999999999 0 0.022 6.938893903907228e-18 0.022 0.022 -0.01349999999999999 0.011 0.022 6.938893903907228e-18 0.022 0.022 -0.02699999999999999 0.022 0.022 -0.01349999999999999 0.011 0.022 -0.02699999999999999 0.022 0.022 -0.01349999999999999 0 0.022 -0.01349999999999999 0.011 0.022 -0.02699999999999999 0.022 0.0125 -0.02699999999999999 0.022 0.022 -0.02117049999999999 0.022 0.0125 -0.01349999999999999 0 -0.022 -0.02699999999999999 0.022 -0.022 -0.01349999999999999 0.011 -0.022 -0.02699999999999999 0.022 -0.022 6.938893903907228e-18 0.022 -0.022 -0.01349999999999999 0.011 -0.022 6.938893903907228e-18 0.022 -0.022 -0.01349999999999999 0 -0.022 -0.01349999999999999 0.011 -0.022 -0.02699999999999999 0.022 -0.0125 -0.02117049999999999 0.022 -0.0125 -0.02699999999999999 0.022 -0.022 -0.02784939999999999 0.0309494 -0.0125 -0.02699999999999999 0.033 -0.0125 -0.002899999999999993 0.022 -0.0125 -0.02989999999999999 0.0301 -0.0125 -0.02784939999999999 0.0309494 -0.0125 -0.03869999999999999 0.022 -0.0125 -0.03869999999999999 0.022 -0.0125 -0.02699999999999999 0.022 -0.0125 -0.02699999999999999 0.022 -0.00432961 -0.002899999999999993 0.0324 0 -0.002899999999999993 0.0428 0.0125 -0.002899999999999993 0.0324 0.00625 -0.002899999999999993 0.0428 0.0125 -0.002899999999999993 0.022 0.0125 -0.002899999999999993 0.0324 0.00625 -0.002899999999999993 0.022 0.0125 -0.002899999999999993 0.0324 0 -0.002899999999999993 0.0324 0.00625 -0.002899999999999993 0.0324 0 -0.002899999999999993 0.022 -0.0125 -0.002899999999999993 0.0324 -0.00625 -0.002899999999999993 0.0428 -0.0125 -0.002899999999999993 0.0324 0 -0.002899999999999993 0.0324 -0.00625 -0.002899999999999993 0.022 -0.0125 -0.002899999999999993 0.0428 -0.0125 -0.002899999999999993 0.0324 -0.00625 -0.02777869999999999 0.0308787 0.0125 -0.002899999999999993 0.022 0.0125 -0.02689999999999999 0.033 0.0125 -0.03869999999999999 0.022 0.0125 -0.02777869999999999 0.0308787 0.0125 -0.02989999999999999 0.03 0.0125 -0.03869999999999999 0.022 0.0125 -0.02699999999999999 0.022 0.00432961 -0.02699999999999999 0.022 0.0125 -0.01349999999999999 0 0.022 -0.02699999999999999 -0.022 0.022 -0.01349999999999999 -0.011 0.022 -0.02699999999999999 -0.022 0.022 6.938893903907228e-18 -0.022 0.022 -0.01349999999999999 -0.011 0.022 6.938893903907228e-18 -0.022 0.022 -0.01349999999999999 0 0.022 -0.01349999999999999 -0.011 0.022 -0.005829549999999993 -0.022 -0.0125 6.938893903907228e-18 -0.022 -0.022 -0.002899999999999993 -0.022 -0.0125 -0.005829549999999993 -0.022 0.0125 -0.002899999999999993 -0.022 0.0125 6.938893903907228e-18 -0.022 0.022 -0.002899999999999993 -0.022 -0.0125 6.938893903907228e-18 -0.022 -0.022 6.938893903907228e-18 -0.022 0.022 -0.002899999999999993 -0.022 0.0125 -0.002899999999999993 -0.022 -0.0125 6.938893903907228e-18 -0.022 0.022 6.938893903907228e-18 -0.008485299999999999 -0.008485299999999999 0.001500000000000007 -0.0102426 -0.0042426 6.938893903907228e-18 -0.012 0 6.938893903907228e-18 -0.012 0 0.001500000000000007 -0.0102426 0.0042426 6.938893903907228e-18 -0.008485299999999999 0.008485299999999999 0.003000000000000007 0 0.012 6.938893903907228e-18 0 0.012 0.001500000000000007 -0.0042426 0.0102426 0.003000000000000007 -0.008485299999999999 0.008485299999999999 0.001500000000000007 -0.0042426 0.0102426 6.938893903907228e-18 -0.008485299999999999 0.008485299999999999 0.003000000000000007 0.008485299999999999 0.008485299999999999 6.938893903907228e-18 0.008485299999999999 0.008485299999999999 0.001500000000000007 0.0042426 0.0102426 0.003000000000000007 0 0.012 0.001500000000000007 0.0042426 0.0102426 6.938893903907228e-18 0 0.012 0.001500000000000007 0.0102426 0.0042426 0.003000000000000007 0.008485299999999999 0.008485299999999999 0.003000000000000007 0.012 0 0.003000000000000007 0.008485299999999999 -0.008485299999999999 0.001500000000000007 0.0102426 -0.0042426 0.003000000000000007 0.012 0 0.003000000000000007 0.008485299999999999 -0.008485299999999999 0.001500000000000007 0.0042426 -0.0102426 6.938893903907228e-18 0.008485299999999999 -0.008485299999999999 -0.01349999999999999 0 -0.022 6.938893903907228e-18 -0.022 -0.022 -0.01349999999999999 -0.011 -0.022 6.938893903907228e-18 -0.022 -0.022 -0.02699999999999999 -0.022 -0.022 -0.01349999999999999 -0.011 -0.022 -0.02699999999999999 -0.022 -0.022 -0.01349999999999999 0 -0.022 -0.01349999999999999 -0.011 -0.022 0.003000000000000007 0 -0.012 6.938893903907228e-18 0 -0.012 0.001500000000000007 0.0042426 -0.0102426 0.003000000000000007 -0.008485299999999999 -0.008485299999999999 6.938893903907228e-18 -0.008485299999999999 -0.008485299999999999 0.001500000000000007 -0.0042426 -0.0102426 0.003000000000000007 0 -0.012 0.001500000000000007 -0.0042426 -0.0102426 6.938893903907228e-18 0 -0.012 -0.01349999999999999 0 0.022 -0.02699999999999999 0.022 0.022 -0.02024999999999999 -1.21431e-17 0.022 -0.02699999999999999 0.022 0.022 -0.02699999999999999 -0.022 0.022 -0.02024999999999999 -1.21431e-17 0.022 -0.02699999999999999 -0.022 0.022 -0.01349999999999999 0 0.022 -0.02024999999999999 -1.21431e-17 0.022 -0.02699999999999999 0.022 0.022 -0.02699999999999999 0.022 0.0125 -0.02699999999999999 0 0 -0.02699999999999999 0.022 -0.0125 -0.02699999999999999 0.022 -0.022 -0.02699999999999999 0 0 -0.02699999999999999 0.022 0.0125 -0.02699999999999999 0.022 0.00432961 -0.02699999999999999 0.011 1.73472e-18 -0.02699999999999999 0.022 -0.00432961 -0.02699999999999999 0.022 -0.0125 -0.02699999999999999 0.011 1.73472e-18 -0.02699999999999999 0.022 0.00432961 -0.02699999999999999 0.022 -0.00432961 -0.02699999999999999 0.011 1.73472e-18 -0.02699999999999999 0 0 -0.02699999999999999 0.022 0.0125 -0.02699999999999999 0.011 1.73472e-18 -0.02699999999999999 0.022 -0.0125 -0.02699999999999999 0 0 -0.02699999999999999 0.011 1.73472e-18 -0.01349999999999999 0 -0.022 -0.02699999999999999 -0.022 -0.022 -0.02024999999999999 -1.73472e-18 -0.022 -0.02699999999999999 -0.022 -0.022 -0.02699999999999999 0.022 -0.022 -0.02024999999999999 -1.73472e-18 -0.022 -0.02699999999999999 0.022 -0.022 -0.01349999999999999 0 -0.022 -0.02024999999999999 -1.73472e-18 -0.022 -0.02742469999999999 0.0319747 -0.013325 -0.02742469999999999 0.0319747 -0.01415 -0.02699999999999999 0.033 -0.0125 -0.02742469999999999 0.0319747 -0.013325 -0.02699999999999999 0.033 -0.0125 -0.02784939999999999 0.0309494 -0.0125 -0.02742469999999999 0.0319747 -0.013325 -0.02784939999999999 0.0309494 -0.0125 -0.02742469999999999 0.0319747 -0.01415 -0.02784939999999999 0.0350506 -0.0125 -0.002899999999999993 0.022 -0.0125 -0.02699999999999999 0.033 -0.0125 -0.03869999999999999 0.022 -0.0125 -0.0319506 0.0309494 -0.0125 -0.02989999999999999 0.0301 -0.0125 -0.02887469999999999 0.0305247 -0.01415 -0.02784939999999999 0.0309494 -0.0125 -0.02887469999999999 0.0305247 -0.013325 -0.02784939999999999 0.0309494 -0.0125 -0.02989999999999999 0.0301 -0.0125 -0.02887469999999999 0.0305247 -0.013325 -0.02989999999999999 0.0301 -0.0125 -0.02887469999999999 0.0305247 -0.01415 -0.02887469999999999 0.0305247 -0.013325 -0.02699999999999999 0.022 0.00432961 -0.03869999999999999 0.022 0.0125 -0.03284999999999999 0.022 2.1684e-17 -0.03869999999999999 0.022 0.0125 -0.03869999999999999 0.022 -0.0125 -0.03284999999999999 0.022 2.1684e-17 -0.03869999999999999 0.022 -0.0125 -0.02699999999999999 0.022 -0.00432961 -0.03284999999999999 0.022 2.1684e-17 -0.02699999999999999 0.022 -0.00432961 -0.02699999999999999 0.022 0.00432961 -0.03284999999999999 0.022 2.1684e-17 -0.002899999999999993 0.0324 0 -0.002899999999999993 0.0428 -0.0125 -0.002899999999999993 0.0376 -1.56125e-17 -0.002899999999999993 0.0428 -0.0125 -0.002899999999999993 0.0428 0.0125 -0.002899999999999993 0.0376 -1.56125e-17 -0.002899999999999993 0.0428 0.0125 -0.002899999999999993 0.0324 0 -0.002899999999999993 0.0376 -1.56125e-17 -0.002899999999999993 0.022 0.0125 -0.002899999999999993 0.0428 0.0125 -0.03869999999999999 0.0428 0.0125 -0.002899999999999993 0.022 -0.0125 -0.03869999999999999 0.0428 -0.0125 -0.002899999999999993 0.0428 -0.0125 -0.02689999999999999 0.033 0.0125 -0.002899999999999993 0.022 0.0125 -0.02777869999999999 0.0351213 0.0125 -0.02733929999999999 0.0319393 0.013325 -0.02733929999999999 0.0319393 0.01415 -0.02777869999999999 0.0308787 0.0125 -0.02733929999999999 0.0319393 0.013325 -0.02777869999999999 0.0308787 0.0125 -0.02689999999999999 0.033 0.0125 -0.02733929999999999 0.0319393 0.013325 -0.02689999999999999 0.033 0.0125 -0.02733929999999999 0.0319393 0.01415 -0.02883929999999999 0.0304393 0.013325 -0.02883929999999999 0.0304393 0.01415 -0.02989999999999999 0.03 0.0125 -0.02883929999999999 0.0304393 0.013325 -0.02989999999999999 0.03 0.0125 -0.02777869999999999 0.0308787 0.0125 -0.02883929999999999 0.0304393 0.013325 -0.02777869999999999 0.0308787 0.0125 -0.02883929999999999 0.0304393 0.01415 -0.03869999999999999 0.022 0.0125 -0.02989999999999999 0.03 0.0125 -0.0320213 0.0308787 0.0125 6.938893903907228e-18 -0.022 0.022 -0.02699999999999999 -0.022 0.022 -0.01349999999999999 -0.022 0.01725 -0.02699999999999999 -0.022 0.022 -0.02117049999999999 -0.022 0.0125 -0.01349999999999999 -0.022 0.01725 -0.02117049999999999 -0.022 0.0125 -0.005829549999999993 -0.022 0.0125 -0.01349999999999999 -0.022 0.01725 -0.005829549999999993 -0.022 0.0125 6.938893903907228e-18 -0.022 0.022 -0.01349999999999999 -0.022 0.01725 -0.002899999999999993 -0.0428 0.0125 -0.002899999999999993 -0.022 0.0125 -0.005829549999999993 -0.022 0.0125 -0.002899999999999993 -0.0428 0.0125 -0.005829549999999993 -0.022 0.0125 -0.02117049999999999 -0.022 0.0125 -0.002899999999999993 -0.0428 0.0125 -0.02117049999999999 -0.022 0.0125 -0.02699999999999999 -0.022 0.0125 -0.002899999999999993 -0.0428 0.0125 -0.02699999999999999 -0.022 0.0125 -0.03869999999999999 -0.022 0.0125 -0.002899999999999993 -0.0324 0 -0.002899999999999993 -0.022 -0.0125 -0.002899999999999993 -0.0272 0 -0.002899999999999993 -0.022 -0.0125 -0.002899999999999993 -0.022 0.0125 -0.002899999999999993 -0.0272 0 -0.002899999999999993 -0.022 0.0125 -0.002899999999999993 -0.0324 0 -0.002899999999999993 -0.0272 0 -0.03869999999999999 -0.022 -0.0125 -0.02699999999999999 -0.022 -0.0125 -0.002899999999999993 -0.0428 -0.0125 -0.002899999999999993 -0.0428 -0.0125 -0.02699999999999999 -0.022 -0.0125 -0.02117049999999999 -0.022 -0.0125 -0.002899999999999993 -0.0428 -0.0125 -0.02117049999999999 -0.022 -0.0125 -0.005829549999999993 -0.022 -0.0125 -0.002899999999999993 -0.0428 -0.0125 -0.005829549999999993 -0.022 -0.0125 -0.002899999999999993 -0.022 -0.0125 -0.02117049999999999 -0.022 -0.0125 -0.02699999999999999 -0.022 -0.022 -0.01349999999999999 -0.022 -0.01725 -0.02699999999999999 -0.022 -0.022 6.938893903907228e-18 -0.022 -0.022 -0.01349999999999999 -0.022 -0.01725 6.938893903907228e-18 -0.022 -0.022 -0.005829549999999993 -0.022 -0.0125 -0.01349999999999999 -0.022 -0.01725 -0.005829549999999993 -0.022 -0.0125 -0.02117049999999999 -0.022 -0.0125 -0.01349999999999999 -0.022 -0.01725 6.938893903907228e-18 -0.012 0 0.001500000000000007 -0.0102426 -0.0042426 0.003000000000000007 -0.012 0 6.938893903907228e-18 -0.008485299999999999 -0.008485299999999999 0.003000000000000007 -0.008485299999999999 -0.008485299999999999 0.001500000000000007 -0.0102426 -0.0042426 6.938893903907228e-18 -0.008485299999999999 0.008485299999999999 0.001500000000000007 -0.0102426 0.0042426 0.003000000000000007 -0.008485299999999999 0.008485299999999999 6.938893903907228e-18 -0.012 0 0.003000000000000007 -0.012 0 0.001500000000000007 -0.0102426 0.0042426 0.003000000000000007 0 0.012 0.001500000000000007 -0.0042426 0.0102426 0.003000000000000007 -0.008485299999999999 0.008485299999999999 0.003000000000000007 0.008485299999999999 0.008485299999999999 0.001500000000000007 0.0042426 0.0102426 0.003000000000000007 0 0.012 0.003000000000000007 0.012 0 0.003000000000000007 0.008485299999999999 0.008485299999999999 0.003000000000000007 0 0.012 0.003000000000000007 0.012 0 0.003000000000000007 0.007 0 0.003000000000000007 0.008485299999999999 -0.008485299999999999 0.003000000000000007 0 -0.012 0.001500000000000007 0.0042426 -0.0102426 0.003000000000000007 0.008485299999999999 -0.008485299999999999 0.003000000000000007 -0.008485299999999999 -0.008485299999999999 0.001500000000000007 -0.0042426 -0.0102426 0.003000000000000007 0 -0.012 -0.02699999999999999 0 0 -0.02699999999999999 -0.022 0.022 -0.02699999999999999 -1.21431e-17 0.011 -0.02699999999999999 -0.022 0.022 -0.02699999999999999 0.022 0.022 -0.02699999999999999 -1.21431e-17 0.011 -0.02699999999999999 0.022 0.022 -0.02699999999999999 0 0 -0.02699999999999999 -1.21431e-17 0.011 -0.02699999999999999 0 0 -0.02699999999999999 0.022 -0.022 -0.02699999999999999 1.21431e-17 -0.011 -0.02699999999999999 0.022 -0.022 -0.02699999999999999 -0.022 -0.022 -0.02699999999999999 1.21431e-17 -0.011 -0.02699999999999999 -0.022 -0.022 -0.02699999999999999 0 0 -0.02699999999999999 1.21431e-17 -0.011 -0.02742469999999999 0.0319747 -0.01415 -0.02699999999999999 0.033 -0.0158 -0.02721239999999999 0.0324873 -0.01415 -0.02699999999999999 0.033 -0.0158 -0.02699999999999999 0.033 -0.0125 -0.02721239999999999 0.0324873 -0.01415 -0.02699999999999999 0.033 -0.0125 -0.02742469999999999 0.0319747 -0.01415 -0.02721239999999999 0.0324873 -0.01415 -0.02742469999999999 0.0319747 -0.01415 -0.02784939999999999 0.0309494 -0.0125 -0.02763699999999999 0.0314621 -0.01415 -0.02784939999999999 0.0309494 -0.0125 -0.02784939999999999 0.0309494 -0.0158 -0.02763699999999999 0.0314621 -0.01415 -0.02784939999999999 0.0309494 -0.0158 -0.02742469999999999 0.0319747 -0.01415 -0.02763699999999999 0.0314621 -0.01415 -0.02742469999999999 0.0340253 -0.01415 -0.02784939999999999 0.0350506 -0.0125 -0.02742469999999999 0.0340253 -0.013325 -0.02784939999999999 0.0350506 -0.0125 -0.02699999999999999 0.033 -0.0125 -0.02742469999999999 0.0340253 -0.013325 -0.02699999999999999 0.033 -0.0125 -0.02742469999999999 0.0340253 -0.01415 -0.02742469999999999 0.0340253 -0.013325 -0.03869999999999999 0.0428 -0.0125 -0.002899999999999993 0.022 -0.0125 -0.02784939999999999 0.0350506 -0.0125 -0.0319506 0.0309494 -0.0125 -0.03869999999999999 0.022 -0.0125 -0.03869999999999999 0.0428 -0.0125 -0.03092529999999999 0.0305247 -0.01415 -0.02989999999999999 0.0301 -0.0125 -0.03092529999999999 0.0305247 -0.013325 -0.02989999999999999 0.0301 -0.0125 -0.0319506 0.0309494 -0.0125 -0.03092529999999999 0.0305247 -0.013325 -0.0319506 0.0309494 -0.0125 -0.03092529999999999 0.0305247 -0.01415 -0.03092529999999999 0.0305247 -0.013325 -0.02887469999999999 0.0305247 -0.01415 -0.02784939999999999 0.0309494 -0.0158 -0.02836209999999999 0.030737 -0.01415 -0.02784939999999999 0.0309494 -0.0158 -0.02784939999999999 0.0309494 -0.0125 -0.02836209999999999 0.030737 -0.01415 -0.02784939999999999 0.0309494 -0.0125 -0.02887469999999999 0.0305247 -0.01415 -0.02836209999999999 0.030737 -0.01415 -0.02887469999999999 0.0305247 -0.01415 -0.02989999999999999 0.0301 -0.0125 -0.02938739999999999 0.0303124 -0.01415 -0.02989999999999999 0.0301 -0.0125 -0.02989999999999999 0.0301 -0.0158 -0.02938739999999999 0.0303124 -0.01415 -0.02989999999999999 0.0301 -0.0158 -0.02887469999999999 0.0305247 -0.01415 -0.02938739999999999 0.0303124 -0.01415 -0.03869999999999999 0.0324 0 -0.03869999999999999 0.022 -0.0125 -0.03869999999999999 0.0272 0 -0.03869999999999999 0.022 -0.0125 -0.03869999999999999 0.022 0.0125 -0.03869999999999999 0.0272 0 -0.03869999999999999 0.022 0.0125 -0.03869999999999999 0.0324 0 -0.03869999999999999 0.0272 0 -0.02079999999999999 0.0428 0 -0.002899999999999993 0.0428 0.0125 -0.01184999999999999 0.0428 -2.60209e-18 -0.002899999999999993 0.0428 0.0125 -0.002899999999999993 0.0428 -0.0125 -0.01184999999999999 0.0428 -2.60209e-18 -0.002899999999999993 0.0428 -0.0125 -0.02079999999999999 0.0428 0 -0.01184999999999999 0.0428 -2.60209e-18 -0.02079999999999999 0.0428 0 -0.03869999999999999 0.0428 0.0125 -0.02079999999999999 0.0428 0.00625 -0.03869999999999999 0.0428 0.0125 -0.002899999999999993 0.0428 0.0125 -0.02079999999999999 0.0428 0.00625 -0.002899999999999993 0.0428 0.0125 -0.02079999999999999 0.0428 0 -0.02079999999999999 0.0428 0.00625 -0.02777869999999999 0.0351213 0.0125 -0.002899999999999993 0.022 0.0125 -0.03869999999999999 0.0428 0.0125 -0.02079999999999999 0.0428 0 -0.002899999999999993 0.0428 -0.0125 -0.02079999999999999 0.0428 -0.00625 -0.002899999999999993 0.0428 -0.0125 -0.03869999999999999 0.0428 -0.0125 -0.02079999999999999 0.0428 -0.00625 -0.03869999999999999 0.0428 -0.0125 -0.02079999999999999 0.0428 0 -0.02079999999999999 0.0428 -0.00625 -0.02733929999999999 0.0340607 0.013325 -0.02733929999999999 0.0340607 0.01415 -0.02689999999999999 0.033 0.0125 -0.02733929999999999 0.0340607 0.013325 -0.02689999999999999 0.033 0.0125 -0.02777869999999999 0.0351213 0.0125 -0.02733929999999999 0.0340607 0.013325 -0.02777869999999999 0.0351213 0.0125 -0.02733929999999999 0.0340607 0.01415 -0.02733929999999999 0.0319393 0.01415 -0.02777869999999999 0.0308787 0.0158 -0.02755899999999999 0.031409 0.01415 -0.02777869999999999 0.0308787 0.0158 -0.02777869999999999 0.0308787 0.0125 -0.02755899999999999 0.031409 0.01415 -0.02777869999999999 0.0308787 0.0125 -0.02733929999999999 0.0319393 0.01415 -0.02755899999999999 0.031409 0.01415 -0.02733929999999999 0.0319393 0.01415 -0.02689999999999999 0.033 0.0125 -0.02711969999999999 0.0324697 0.01415 -0.02689999999999999 0.033 0.0125 -0.02689999999999999 0.033 0.0158 -0.02711969999999999 0.0324697 0.01415 -0.02689999999999999 0.033 0.0158 -0.02733929999999999 0.0319393 0.01415 -0.02711969999999999 0.0324697 0.01415 -0.02883929999999999 0.0304393 0.01415 -0.02989999999999999 0.03 0.0158 -0.02936959999999999 0.0302196 0.01415 -0.02989999999999999 0.03 0.0158 -0.02989999999999999 0.03 0.0125 -0.02936959999999999 0.0302196 0.01415 -0.02989999999999999 0.03 0.0125 -0.02883929999999999 0.0304393 0.01415 -0.02936959999999999 0.0302196 0.01415 -0.02883929999999999 0.0304393 0.01415 -0.02777869999999999 0.0308787 0.0125 -0.02830899999999999 0.030659 0.01415 -0.02777869999999999 0.0308787 0.0125 -0.02777869999999999 0.0308787 0.0158 -0.02830899999999999 0.030659 0.01415 -0.02777869999999999 0.0308787 0.0158 -0.02883929999999999 0.0304393 0.01415 -0.02830899999999999 0.030659 0.01415 -0.03096069999999999 0.0304393 0.01415 -0.0320213 0.0308787 0.0125 -0.03096069999999999 0.0304393 0.013325 -0.0320213 0.0308787 0.0125 -0.02989999999999999 0.03 0.0125 -0.03096069999999999 0.0304393 0.013325 -0.02989999999999999 0.03 0.0125 -0.03096069999999999 0.0304393 0.01415 -0.03096069999999999 0.0304393 0.013325 -0.03869999999999999 0.022 0.0125 -0.0320213 0.0308787 0.0125 -0.03869999999999999 0.0428 0.0125 -0.02699999999999999 -0.022 0.0125 -0.02117049999999999 -0.022 0.0125 -0.02699999999999999 -0.022 0.022 -0.03869999999999999 -0.022 0.0125 -0.02699999999999999 -0.022 0.0125 -0.02699999999999999 -0.022 0.00432961 -0.02784939999999999 -0.0309494 0.0125 -0.002899999999999993 -0.0428 0.0125 -0.03869999999999999 -0.022 0.0125 -0.002899999999999993 -0.0324 0 -0.002899999999999993 -0.022 0.0125 -0.002899999999999993 -0.0324 0.00625 -0.002899999999999993 -0.022 0.0125 -0.002899999999999993 -0.0428 0.0125 -0.002899999999999993 -0.0324 0.00625 -0.002899999999999993 -0.0428 0.0125 -0.002899999999999993 -0.0324 0 -0.002899999999999993 -0.0324 0.00625 -0.002899999999999993 -0.0324 0 -0.002899999999999993 -0.0428 -0.0125 -0.002899999999999993 -0.0324 -0.00625 -0.002899999999999993 -0.022 -0.0125 -0.002899999999999993 -0.0324 0 -0.002899999999999993 -0.0324 -0.00625 -0.002899999999999993 -0.0428 -0.0125 -0.002899999999999993 -0.022 -0.0125 -0.002899999999999993 -0.0324 -0.00625 -0.03869999999999999 -0.022 -0.0125 -0.002899999999999993 -0.0428 -0.0125 -0.02777869999999999 -0.0308787 -0.0125 -0.03869999999999999 -0.022 -0.0125 -0.02699999999999999 -0.022 -0.00432961 -0.02699999999999999 -0.022 -0.0125 -0.02699999999999999 -0.022 -0.0125 -0.02699999999999999 -0.022 -0.022 -0.02117049999999999 -0.022 -0.0125 0.001500000000000007 -0.0102426 -0.0042426 0.003000000000000007 -0.008485299999999999 -0.008485299999999999 0.003000000000000007 -0.012 0 0.003000000000000007 -0.008485299999999999 0.008485299999999999 0.001500000000000007 -0.0102426 0.0042426 0.003000000000000007 -0.012 0 0.003000000000000007 0 0.007 0.003000000000000007 0 0.012 0.003000000000000007 -0.008485299999999999 0.008485299999999999 0.003000000000000007 0.012 0 0.003000000000000007 0 0.012 0.003000000000000007 0.0049497 0.0049497 0.003000000000000007 0.012 0 0.003000000000000007 0.0049497 0.0049497 0.003000000000000007 0.007 0 0.003000000000000007 0.008485299999999999 -0.008485299999999999 0.003000000000000007 0.007 0 0.003000000000000007 0.0049497 -0.0049497 0.003000000000000007 0.008485299999999999 -0.008485299999999999 0.003000000000000007 0 -0.007 0.003000000000000007 0 -0.012 0.003000000000000007 0 -0.012 0.003000000000000007 -0.012 0 0.003000000000000007 -0.008485299999999999 -0.008485299999999999 -0.02699999999999999 0 0 -0.02699999999999999 -0.022 -0.022 -0.02699999999999999 -0.022 -0.0125 -0.02699999999999999 0 0 -0.02699999999999999 -0.022 0.0125 -0.02699999999999999 -0.022 0.022 -0.02699999999999999 -0.022 -0.0125 -0.02699999999999999 -0.022 -0.00432961 -0.02699999999999999 -0.011 -1.73472e-18 -0.02699999999999999 -0.022 0.00432961 -0.02699999999999999 -0.022 0.0125 -0.02699999999999999 -0.011 -1.73472e-18 -0.02699999999999999 -0.022 -0.00432961 -0.02699999999999999 -0.022 0.00432961 -0.02699999999999999 -0.011 -1.73472e-18 -0.02699999999999999 0 0 -0.02699999999999999 -0.022 -0.0125 -0.02699999999999999 -0.011 -1.73472e-18 -0.02699999999999999 -0.022 0.0125 -0.02699999999999999 0 0 -0.02699999999999999 -0.011 -1.73472e-18 -0.02742469999999999 0.0319747 -0.01415 -0.02784939999999999 0.0309494 -0.0158 -0.02742469999999999 0.0319747 -0.014975 -0.02784939999999999 0.0309494 -0.0158 -0.02699999999999999 0.033 -0.0158 -0.02742469999999999 0.0319747 -0.014975 -0.02699999999999999 0.033 -0.0158 -0.02742469999999999 0.0319747 -0.01415 -0.02742469999999999 0.0319747 -0.014975 -0.02742469999999999 0.0340253 -0.01415 -0.02699999999999999 0.033 -0.0125 -0.02721239999999999 0.0335127 -0.01415 -0.02699999999999999 0.033 -0.0125 -0.02699999999999999 0.033 -0.0158 -0.02721239999999999 0.0335127 -0.01415 -0.02699999999999999 0.033 -0.0158 -0.02742469999999999 0.0340253 -0.01415 -0.02721239999999999 0.0335127 -0.01415 -0.02742469999999999 0.0340253 -0.01415 -0.02784939999999999 0.0350506 -0.0158 -0.02763699999999999 0.0345379 -0.01415 -0.02784939999999999 0.0350506 -0.0158 -0.02784939999999999 0.0350506 -0.0125 -0.02763699999999999 0.0345379 -0.01415 -0.02784939999999999 0.0350506 -0.0125 -0.02742469999999999 0.0340253 -0.01415 -0.02763699999999999 0.0345379 -0.01415 -0.03869999999999999 0.0428 -0.0125 -0.02784939999999999 0.0350506 -0.0125 -0.02989999999999999 0.0359 -0.0125 -0.03869999999999999 0.0324 0 -0.03869999999999999 0.0428 -0.0125 -0.03869999999999999 0.0324 -0.00625 -0.03869999999999999 0.0428 -0.0125 -0.03869999999999999 0.022 -0.0125 -0.03869999999999999 0.0324 -0.00625 -0.03869999999999999 0.022 -0.0125 -0.03869999999999999 0.0324 0 -0.03869999999999999 0.0324 -0.00625 -0.03869999999999999 0.0428 -0.0125 -0.0328 0.033 -0.0125 -0.0319506 0.0309494 -0.0125 -0.03092529999999999 0.0305247 -0.01415 -0.02989999999999999 0.0301 -0.0158 -0.03041259999999999 0.0303124 -0.01415 -0.02989999999999999 0.0301 -0.0158 -0.02989999999999999 0.0301 -0.0125 -0.03041259999999999 0.0303124 -0.01415 -0.02989999999999999 0.0301 -0.0125 -0.03092529999999999 0.0305247 -0.01415 -0.03041259999999999 0.0303124 -0.01415 -0.03092529999999999 0.0305247 -0.01415 -0.0319506 0.0309494 -0.0125 -0.03143789999999999 0.030737 -0.01415 -0.0319506 0.0309494 -0.0125 -0.0319506 0.0309494 -0.0158 -0.03143789999999999 0.030737 -0.01415 -0.0319506 0.0309494 -0.0158 -0.03092529999999999 0.0305247 -0.01415 -0.03143789999999999 0.030737 -0.01415 -0.02887469999999999 0.0305247 -0.01415 -0.02989999999999999 0.0301 -0.0158 -0.02887469999999999 0.0305247 -0.014975 -0.02989999999999999 0.0301 -0.0158 -0.02784939999999999 0.0309494 -0.0158 -0.02887469999999999 0.0305247 -0.014975 -0.02784939999999999 0.0309494 -0.0158 -0.02887469999999999 0.0305247 -0.01415 -0.02887469999999999 0.0305247 -0.014975 -0.03869999999999999 0.0324 0 -0.03869999999999999 0.022 0.0125 -0.03869999999999999 0.0324 0.00625 -0.03869999999999999 0.022 0.0125 -0.03869999999999999 0.0428 0.0125 -0.03869999999999999 0.0324 0.00625 -0.03869999999999999 0.0428 0.0125 -0.03869999999999999 0.0324 0 -0.03869999999999999 0.0324 0.00625 -0.02079999999999999 0.0428 0 -0.03869999999999999 0.0428 -0.0125 -0.02974999999999999 0.0428 -1.56125e-17 -0.03869999999999999 0.0428 -0.0125 -0.03869999999999999 0.0428 0.0125 -0.02974999999999999 0.0428 -1.56125e-17 -0.03869999999999999 0.0428 0.0125 -0.02079999999999999 0.0428 0 -0.02974999999999999 0.0428 -1.56125e-17 -0.02989999999999999 0.036 0.0125 -0.02777869999999999 0.0351213 0.0125 -0.03869999999999999 0.0428 0.0125 -0.02733929999999999 0.0340607 0.01415 -0.02689999999999999 0.033 0.0158 -0.02711969999999999 0.0335304 0.01415 -0.02689999999999999 0.033 0.0158 -0.02689999999999999 0.033 0.0125 -0.02711969999999999 0.0335304 0.01415 -0.02689999999999999 0.033 0.0125 -0.02733929999999999 0.0340607 0.01415 -0.02711969999999999 0.0335304 0.01415 -0.02733929999999999 0.0340607 0.01415 -0.02777869999999999 0.0351213 0.0125 -0.02755899999999999 0.034591 0.01415 -0.02777869999999999 0.0351213 0.0125 -0.02777869999999999 0.0351213 0.0158 -0.02755899999999999 0.034591 0.01415 -0.02777869999999999 0.0351213 0.0158 -0.02733929999999999 0.0340607 0.01415 -0.02755899999999999 0.034591 0.01415 -0.02733929999999999 0.0319393 0.014975 -0.02733929999999999 0.0319393 0.01415 -0.02689999999999999 0.033 0.0158 -0.02733929999999999 0.0319393 0.014975 -0.02689999999999999 0.033 0.0158 -0.02777869999999999 0.0308787 0.0158 -0.02733929999999999 0.0319393 0.014975 -0.02777869999999999 0.0308787 0.0158 -0.02733929999999999 0.0319393 0.01415 -0.02883929999999999 0.0304393 0.01415 -0.02777869999999999 0.0308787 0.0158 -0.02883929999999999 0.0304393 0.014975 -0.02777869999999999 0.0308787 0.0158 -0.02989999999999999 0.03 0.0158 -0.02883929999999999 0.0304393 0.014975 -0.02989999999999999 0.03 0.0158 -0.02883929999999999 0.0304393 0.01415 -0.02883929999999999 0.0304393 0.014975 -0.03096069999999999 0.0304393 0.01415 -0.02989999999999999 0.03 0.0125 -0.03043039999999999 0.0302196 0.01415 -0.02989999999999999 0.03 0.0125 -0.02989999999999999 0.03 0.0158 -0.03043039999999999 0.0302196 0.01415 -0.02989999999999999 0.03 0.0158 -0.03096069999999999 0.0304393 0.01415 -0.03043039999999999 0.0302196 0.01415 -0.03096069999999999 0.0304393 0.01415 -0.0320213 0.0308787 0.0158 -0.03149099999999999 0.030659 0.01415 -0.0320213 0.0308787 0.0158 -0.0320213 0.0308787 0.0125 -0.03149099999999999 0.030659 0.01415 -0.0320213 0.0308787 0.0125 -0.03096069999999999 0.0304393 0.01415 -0.03149099999999999 0.030659 0.01415 -0.0320213 0.0308787 0.0125 -0.03289999999999999 0.033 0.0125 -0.03869999999999999 0.0428 0.0125 -0.03869999999999999 -0.022 -0.0125 -0.03869999999999999 -0.022 0.0125 -0.03284999999999999 -0.022 -1.56125e-17 -0.03869999999999999 -0.022 0.0125 -0.02699999999999999 -0.022 0.00432961 -0.03284999999999999 -0.022 -1.56125e-17 -0.02699999999999999 -0.022 0.00432961 -0.02699999999999999 -0.022 -0.00432961 -0.03284999999999999 -0.022 -1.56125e-17 -0.02699999999999999 -0.022 -0.00432961 -0.03869999999999999 -0.022 -0.0125 -0.03284999999999999 -0.022 -1.56125e-17 -0.02989999999999999 -0.0301 0.0125 -0.02784939999999999 -0.0309494 0.0125 -0.03869999999999999 -0.022 0.0125 -0.02699999999999999 -0.033 0.0125 -0.002899999999999993 -0.0428 0.0125 -0.02784939999999999 -0.0309494 0.0125 -0.002899999999999993 -0.0324 0 -0.002899999999999993 -0.0428 0.0125 -0.002899999999999993 -0.0376 7.806259999999999e-18 -0.002899999999999993 -0.0428 0.0125 -0.002899999999999993 -0.0428 -0.0125 -0.002899999999999993 -0.0376 7.806259999999999e-18 -0.002899999999999993 -0.0428 -0.0125 -0.002899999999999993 -0.0324 0 -0.002899999999999993 -0.0376 7.806259999999999e-18 -0.02689999999999999 -0.033 -0.0125 -0.02777869999999999 -0.0308787 -0.0125 -0.002899999999999993 -0.0428 -0.0125 -0.03869999999999999 -0.022 -0.0125 -0.02777869999999999 -0.0308787 -0.0125 -0.02989999999999999 -0.03 -0.0125 0.003000000000000007 -0.0049497 0.0049497 0.003000000000000007 -0.008485299999999999 0.008485299999999999 0.003000000000000007 -0.012 0 0.003000000000000007 0 0.007 0.003000000000000007 -0.008485299999999999 0.008485299999999999 0.003000000000000007 -0.0049497 0.0049497 0.003000000000000007 0.0049497 0.0049497 0.003000000000000007 0 0.012 0.003000000000000007 0 0.007 0.009000000000000006 0.0059749 0.0024749 0.003000000000000007 0.007 0 0.003000000000000007 0.0049497 0.0049497 0.003000000000000007 0.0049497 -0.0049497 0.003000000000000007 0.007 0 0.009000000000000006 0.0059749 -0.0024749 0.003000000000000007 0.008485299999999999 -0.008485299999999999 0.003000000000000007 0.0049497 -0.0049497 0.003000000000000007 0 -0.007 0.003000000000000007 0 -0.007 0.003000000000000007 -0.0049497 -0.0049497 0.003000000000000007 0 -0.012 0.003000000000000007 0 -0.012 0.003000000000000007 -0.0049497 -0.0049497 0.003000000000000007 -0.012 0 -0.02784939999999999 0.0309494 -0.0158 -0.02989999999999999 0.033 -0.0158 -0.02699999999999999 0.033 -0.0158 -0.02742469999999999 0.0340253 -0.01415 -0.02699999999999999 0.033 -0.0158 -0.02742469999999999 0.0340253 -0.014975 -0.02699999999999999 0.033 -0.0158 -0.02784939999999999 0.0350506 -0.0158 -0.02742469999999999 0.0340253 -0.014975 -0.02784939999999999 0.0350506 -0.0158 -0.02742469999999999 0.0340253 -0.01415 -0.02742469999999999 0.0340253 -0.014975 -0.02887469999999999 0.0354753 -0.01415 -0.02784939999999999 0.0350506 -0.0125 -0.02836209999999999 0.0352629 -0.01415 -0.02784939999999999 0.0350506 -0.0125 -0.02784939999999999 0.0350506 -0.0158 -0.02836209999999999 0.0352629 -0.01415 -0.02784939999999999 0.0350506 -0.0158 -0.02887469999999999 0.0354753 -0.01415 -0.02836209999999999 0.0352629 -0.01415 -0.02887469999999999 0.0354753 -0.013325 -0.02887469999999999 0.0354753 -0.01415 -0.02989999999999999 0.0359 -0.0125 -0.02887469999999999 0.0354753 -0.013325 -0.02989999999999999 0.0359 -0.0125 -0.02784939999999999 0.0350506 -0.0125 -0.02887469999999999 0.0354753 -0.013325 -0.02784939999999999 0.0350506 -0.0125 -0.02887469999999999 0.0354753 -0.01415 -0.0319506 0.0350506 -0.0125 -0.03869999999999999 0.0428 -0.0125 -0.02989999999999999 0.0359 -0.0125 -0.03869999999999999 0.0324 0 -0.03869999999999999 0.0428 0.0125 -0.03869999999999999 0.0376 -7.806259999999999e-18 -0.03869999999999999 0.0428 0.0125 -0.03869999999999999 0.0428 -0.0125 -0.03869999999999999 0.0376 -7.806259999999999e-18 -0.03869999999999999 0.0428 -0.0125 -0.03869999999999999 0.0324 0 -0.03869999999999999 0.0376 -7.806259999999999e-18 -0.0323753 0.0319747 -0.01415 -0.0319506 0.0309494 -0.0125 -0.0323753 0.0319747 -0.013325 -0.0319506 0.0309494 -0.0125 -0.0328 0.033 -0.0125 -0.0323753 0.0319747 -0.013325 -0.0328 0.033 -0.0125 -0.0323753 0.0319747 -0.01415 -0.0323753 0.0319747 -0.013325 -0.0319506 0.0350506 -0.0125 -0.0328 0.033 -0.0125 -0.03869999999999999 0.0428 -0.0125 -0.03092529999999999 0.0305247 -0.01415 -0.0319506 0.0309494 -0.0158 -0.03092529999999999 0.0305247 -0.014975 -0.0319506 0.0309494 -0.0158 -0.02989999999999999 0.0301 -0.0158 -0.03092529999999999 0.0305247 -0.014975 -0.02989999999999999 0.0301 -0.0158 -0.03092529999999999 0.0305247 -0.01415 -0.03092529999999999 0.0305247 -0.014975 -0.0323753 0.0319747 -0.01415 -0.0319506 0.0309494 -0.0158 -0.03216289999999999 0.0314621 -0.01415 -0.0319506 0.0309494 -0.0158 -0.0319506 0.0309494 -0.0125 -0.03216289999999999 0.0314621 -0.01415 -0.0319506 0.0309494 -0.0125 -0.0323753 0.0319747 -0.01415 -0.03216289999999999 0.0314621 -0.01415 -0.02989999999999999 0.0301 -0.0158 -0.02989999999999999 0.033 -0.0158 -0.02784939999999999 0.0309494 -0.0158 -0.0320213 0.0351213 0.0125 -0.02989999999999999 0.036 0.0125 -0.03869999999999999 0.0428 0.0125 -0.02883929999999999 0.0355607 0.01415 -0.02777869999999999 0.0351213 0.0125 -0.02883929999999999 0.0355607 0.013325 -0.02777869999999999 0.0351213 0.0125 -0.02989999999999999 0.036 0.0125 -0.02883929999999999 0.0355607 0.013325 -0.02989999999999999 0.036 0.0125 -0.02883929999999999 0.0355607 0.01415 -0.02883929999999999 0.0355607 0.013325 -0.02733929999999999 0.0340607 0.01415 -0.02777869999999999 0.0351213 0.0158 -0.02733929999999999 0.0340607 0.014975 -0.02777869999999999 0.0351213 0.0158 -0.02689999999999999 0.033 0.0158 -0.02733929999999999 0.0340607 0.014975 -0.02689999999999999 0.033 0.0158 -0.02733929999999999 0.0340607 0.01415 -0.02733929999999999 0.0340607 0.014975 -0.02883929999999999 0.0355607 0.01415 -0.02777869999999999 0.0351213 0.0158 -0.02830899999999999 0.035341 0.01415 -0.02777869999999999 0.0351213 0.0158 -0.02777869999999999 0.0351213 0.0125 -0.02830899999999999 0.035341 0.01415 -0.02777869999999999 0.0351213 0.0125 -0.02883929999999999 0.0355607 0.01415 -0.02830899999999999 0.035341 0.01415 -0.02777869999999999 0.0308787 0.0158 -0.02689999999999999 0.033 0.0158 -0.02989999999999999 0.033 0.0158 -0.02989999999999999 0.03 0.0158 -0.02777869999999999 0.0308787 0.0158 -0.02989999999999999 0.033 0.0158 -0.03096069999999999 0.0304393 0.01415 -0.02989999999999999 0.03 0.0158 -0.03096069999999999 0.0304393 0.014975 -0.02989999999999999 0.03 0.0158 -0.0320213 0.0308787 0.0158 -0.03096069999999999 0.0304393 0.014975 -0.0320213 0.0308787 0.0158 -0.03096069999999999 0.0304393 0.01415 -0.03096069999999999 0.0304393 0.014975 -0.0324607 0.0319393 0.01415 -0.0320213 0.0308787 0.0125 -0.03224099999999999 0.031409 0.01415 -0.0320213 0.0308787 0.0125 -0.0320213 0.0308787 0.0158 -0.03224099999999999 0.031409 0.01415 -0.0320213 0.0308787 0.0158 -0.0324607 0.0319393 0.01415 -0.03224099999999999 0.031409 0.01415 -0.03289999999999999 0.033 0.0125 -0.0320213 0.0351213 0.0125 -0.03869999999999999 0.0428 0.0125 -0.0324607 0.0319393 0.013325 -0.0324607 0.0319393 0.01415 -0.03289999999999999 0.033 0.0125 -0.0324607 0.0319393 0.013325 -0.03289999999999999 0.033 0.0125 -0.0320213 0.0308787 0.0125 -0.0324607 0.0319393 0.013325 -0.0320213 0.0308787 0.0125 -0.0324607 0.0319393 0.01415 -0.03869999999999999 -0.0324 0 -0.03869999999999999 -0.022 0.0125 -0.03869999999999999 -0.0272 -7.806259999999999e-18 -0.03869999999999999 -0.022 0.0125 -0.03869999999999999 -0.022 -0.0125 -0.03869999999999999 -0.0272 -7.806259999999999e-18 -0.03869999999999999 -0.022 -0.0125 -0.03869999999999999 -0.0324 0 -0.03869999999999999 -0.0272 -7.806259999999999e-18 -0.0319506 -0.0309494 0.0125 -0.02989999999999999 -0.0301 0.0125 -0.03869999999999999 -0.022 0.0125 -0.02887469999999999 -0.0305247 0.01415 -0.02784939999999999 -0.0309494 0.0125 -0.02887469999999999 -0.0305247 0.013325 -0.02784939999999999 -0.0309494 0.0125 -0.02989999999999999 -0.0301 0.0125 -0.02887469999999999 -0.0305247 0.013325 -0.02989999999999999 -0.0301 0.0125 -0.02887469999999999 -0.0305247 0.01415 -0.02887469999999999 -0.0305247 0.013325 -0.02742469999999999 -0.0319747 0.013325 -0.02742469999999999 -0.0319747 0.01415 -0.02699999999999999 -0.033 0.0125 -0.02742469999999999 -0.0319747 0.013325 -0.02699999999999999 -0.033 0.0125 -0.02784939999999999 -0.0309494 0.0125 -0.02742469999999999 -0.0319747 0.013325 -0.02784939999999999 -0.0309494 0.0125 -0.02742469999999999 -0.0319747 0.01415 -0.02784939999999999 -0.0350506 0.0125 -0.002899999999999993 -0.0428 0.0125 -0.02699999999999999 -0.033 0.0125 -0.02079999999999999 -0.0428 0 -0.002899999999999993 -0.0428 -0.0125 -0.01184999999999999 -0.0428 8.67362e-19 -0.002899999999999993 -0.0428 -0.0125 -0.002899999999999993 -0.0428 0.0125 -0.01184999999999999 -0.0428 8.67362e-19 -0.002899999999999993 -0.0428 0.0125 -0.02079999999999999 -0.0428 0 -0.01184999999999999 -0.0428 8.67362e-19 -0.02777869999999999 -0.0351213 -0.0125 -0.02689999999999999 -0.033 -0.0125 -0.002899999999999993 -0.0428 -0.0125 -0.02733929999999999 -0.0319393 -0.013325 -0.02733929999999999 -0.0319393 -0.01415 -0.02777869999999999 -0.0308787 -0.0125 -0.02733929999999999 -0.0319393 -0.013325 -0.02777869999999999 -0.0308787 -0.0125 -0.02689999999999999 -0.033 -0.0125 -0.02733929999999999 -0.0319393 -0.013325 -0.02689999999999999 -0.033 -0.0125 -0.02733929999999999 -0.0319393 -0.01415 -0.02883929999999999 -0.0304393 -0.013325 -0.02883929999999999 -0.0304393 -0.01415 -0.02989999999999999 -0.03 -0.0125 -0.02883929999999999 -0.0304393 -0.013325 -0.02989999999999999 -0.03 -0.0125 -0.02777869999999999 -0.0308787 -0.0125 -0.02883929999999999 -0.0304393 -0.013325 -0.02777869999999999 -0.0308787 -0.0125 -0.02883929999999999 -0.0304393 -0.01415 -0.0320213 -0.0308787 -0.0125 -0.03869999999999999 -0.022 -0.0125 -0.02989999999999999 -0.03 -0.0125 0.003000000000000007 -0.007 0 0.003000000000000007 -0.0049497 0.0049497 0.003000000000000007 -0.012 0 0.009000000000000006 -0.0024749 0.0059749 0.003000000000000007 0 0.007 0.003000000000000007 -0.0049497 0.0049497 0.009000000000000006 0.0024749 0.0059749 0.003000000000000007 0.0049497 0.0049497 0.003000000000000007 0 0.007 0.003000000000000007 0.007 0 0.009000000000000006 0.0059749 0.0024749 0.01500000000000001 0.007 0 0.009000000000000006 0.0059749 0.0024749 0.003000000000000007 0.0049497 0.0049497 0.01500000000000001 0.0049497 0.0049497 0.003000000000000007 0.0049497 -0.0049497 0.009000000000000006 0.0059749 -0.0024749 0.01500000000000001 0.0049497 -0.0049497 0.009000000000000006 0.0059749 -0.0024749 0.003000000000000007 0.007 0 0.01500000000000001 0.007 0 0.009000000000000006 0.0024749 -0.0059749 0.003000000000000007 0 -0.007 0.003000000000000007 0.0049497 -0.0049497 0.009000000000000006 -0.0024749 -0.0059749 0.003000000000000007 -0.0049497 -0.0049497 0.003000000000000007 0 -0.007 0.003000000000000007 -0.0049497 -0.0049497 0.003000000000000007 -0.007 0 0.003000000000000007 -0.012 0 -0.02699999999999999 0.033 -0.0158 -0.02989999999999999 0.033 -0.0158 -0.02784939999999999 0.0350506 -0.0158 -0.02887469999999999 0.0354753 -0.01415 -0.02784939999999999 0.0350506 -0.0158 -0.02887469999999999 0.0354753 -0.014975 -0.02784939999999999 0.0350506 -0.0158 -0.02989999999999999 0.0359 -0.0158 -0.02887469999999999 0.0354753 -0.014975 -0.02989999999999999 0.0359 -0.0158 -0.02887469999999999 0.0354753 -0.01415 -0.02887469999999999 0.0354753 -0.014975 -0.02887469999999999 0.0354753 -0.01415 -0.02989999999999999 0.0359 -0.0158 -0.02938739999999999 0.0356876 -0.01415 -0.02989999999999999 0.0359 -0.0158 -0.02989999999999999 0.0359 -0.0125 -0.02938739999999999 0.0356876 -0.01415 -0.02989999999999999 0.0359 -0.0125 -0.02887469999999999 0.0354753 -0.01415 -0.02938739999999999 0.0356876 -0.01415 -0.03092529999999999 0.0354753 -0.013325 -0.03092529999999999 0.0354753 -0.01415 -0.0319506 0.0350506 -0.0125 -0.03092529999999999 0.0354753 -0.013325 -0.0319506 0.0350506 -0.0125 -0.02989999999999999 0.0359 -0.0125 -0.03092529999999999 0.0354753 -0.013325 -0.02989999999999999 0.0359 -0.0125 -0.03092529999999999 0.0354753 -0.01415 -0.0323753 0.0319747 -0.01415 -0.0328 0.033 -0.0125 -0.03258759999999999 0.0324873 -0.01415 -0.0328 0.033 -0.0125 -0.0328 0.033 -0.0158 -0.03258759999999999 0.0324873 -0.01415 -0.0328 0.033 -0.0158 -0.0323753 0.0319747 -0.01415 -0.03258759999999999 0.0324873 -0.01415 -0.0323753 0.0340253 -0.01415 -0.0328 0.033 -0.0125 -0.0323753 0.0340253 -0.013325 -0.0328 0.033 -0.0125 -0.0319506 0.0350506 -0.0125 -0.0323753 0.0340253 -0.013325 -0.0319506 0.0350506 -0.0125 -0.0323753 0.0340253 -0.01415 -0.0323753 0.0340253 -0.013325 -0.02989999999999999 0.0301 -0.0158 -0.0319506 0.0309494 -0.0158 -0.02989999999999999 0.033 -0.0158 -0.0323753 0.0319747 -0.014975 -0.0323753 0.0319747 -0.01415 -0.0328 0.033 -0.0158 -0.0323753 0.0319747 -0.014975 -0.0328 0.033 -0.0158 -0.0319506 0.0309494 -0.0158 -0.0323753 0.0319747 -0.014975 -0.0319506 0.0309494 -0.0158 -0.0323753 0.0319747 -0.01415 -0.03096069999999999 0.0355607 0.01415 -0.02989999999999999 0.036 0.0125 -0.03096069999999999 0.0355607 0.013325 -0.02989999999999999 0.036 0.0125 -0.0320213 0.0351213 0.0125 -0.03096069999999999 0.0355607 0.013325 -0.0320213 0.0351213 0.0125 -0.03096069999999999 0.0355607 0.01415 -0.03096069999999999 0.0355607 0.013325 -0.02883929999999999 0.0355607 0.01415 -0.02989999999999999 0.036 0.0125 -0.02936959999999999 0.0357803 0.01415 -0.02989999999999999 0.036 0.0125 -0.02989999999999999 0.036 0.0158 -0.02936959999999999 0.0357803 0.01415 -0.02989999999999999 0.036 0.0158 -0.02883929999999999 0.0355607 0.01415 -0.02936959999999999 0.0357803 0.01415 -0.02689999999999999 0.033 0.0158 -0.02777869999999999 0.0351213 0.0158 -0.02989999999999999 0.033 0.0158 -0.02883929999999999 0.0355607 0.014975 -0.02883929999999999 0.0355607 0.01415 -0.02989999999999999 0.036 0.0158 -0.02883929999999999 0.0355607 0.014975 -0.02989999999999999 0.036 0.0158 -0.02777869999999999 0.0351213 0.0158 -0.02883929999999999 0.0355607 0.014975 -0.02777869999999999 0.0351213 0.0158 -0.02883929999999999 0.0355607 0.01415 -0.02989999999999999 0.03 0.0158 -0.02989999999999999 0.033 0.0158 -0.0320213 0.0308787 0.0158 -0.0324607 0.0319393 0.014975 -0.0324607 0.0319393 0.01415 -0.0320213 0.0308787 0.0158 -0.0324607 0.0319393 0.014975 -0.0320213 0.0308787 0.0158 -0.03289999999999999 0.033 0.0158 -0.0324607 0.0319393 0.014975 -0.03289999999999999 0.033 0.0158 -0.0324607 0.0319393 0.01415 -0.0324607 0.0340607 0.013325 -0.0324607 0.0340607 0.01415 -0.0320213 0.0351213 0.0125 -0.0324607 0.0340607 0.013325 -0.0320213 0.0351213 0.0125 -0.03289999999999999 0.033 0.0125 -0.0324607 0.0340607 0.013325 -0.03289999999999999 0.033 0.0125 -0.0324607 0.0340607 0.01415 -0.0324607 0.0319393 0.01415 -0.03289999999999999 0.033 0.0158 -0.03268039999999999 0.0324697 0.01415 -0.03289999999999999 0.033 0.0158 -0.03289999999999999 0.033 0.0125 -0.03268039999999999 0.0324697 0.01415 -0.03289999999999999 0.033 0.0125 -0.0324607 0.0319393 0.01415 -0.03268039999999999 0.0324697 0.01415 -0.03869999999999999 -0.0324 0 -0.03869999999999999 -0.0428 0.0125 -0.03869999999999999 -0.0324 0.00625 -0.03869999999999999 -0.0428 0.0125 -0.03869999999999999 -0.022 0.0125 -0.03869999999999999 -0.0324 0.00625 -0.03869999999999999 -0.022 0.0125 -0.03869999999999999 -0.0324 0 -0.03869999999999999 -0.0324 0.00625 -0.03869999999999999 -0.0324 0 -0.03869999999999999 -0.022 -0.0125 -0.03869999999999999 -0.0324 -0.00625 -0.03869999999999999 -0.022 -0.0125 -0.03869999999999999 -0.0428 -0.0125 -0.03869999999999999 -0.0324 -0.00625 -0.03869999999999999 -0.0428 -0.0125 -0.03869999999999999 -0.0324 0 -0.03869999999999999 -0.0324 -0.00625 -0.0328 -0.033 0.0125 -0.0319506 -0.0309494 0.0125 -0.03869999999999999 -0.022 0.0125 -0.03092529999999999 -0.0305247 0.01415 -0.02989999999999999 -0.0301 0.0125 -0.03092529999999999 -0.0305247 0.013325 -0.02989999999999999 -0.0301 0.0125 -0.0319506 -0.0309494 0.0125 -0.03092529999999999 -0.0305247 0.013325 -0.0319506 -0.0309494 0.0125 -0.03092529999999999 -0.0305247 0.01415 -0.03092529999999999 -0.0305247 0.013325 -0.02887469999999999 -0.0305247 0.01415 -0.02784939999999999 -0.0309494 0.0158 -0.02836209999999999 -0.030737 0.01415 -0.02784939999999999 -0.0309494 0.0158 -0.02784939999999999 -0.0309494 0.0125 -0.02836209999999999 -0.030737 0.01415 -0.02784939999999999 -0.0309494 0.0125 -0.02887469999999999 -0.0305247 0.01415 -0.02836209999999999 -0.030737 0.01415 -0.02887469999999999 -0.0305247 0.01415 -0.02989999999999999 -0.0301 0.0125 -0.02938739999999999 -0.0303124 0.01415 -0.02989999999999999 -0.0301 0.0125 -0.02989999999999999 -0.0301 0.0158 -0.02938739999999999 -0.0303124 0.01415 -0.02989999999999999 -0.0301 0.0158 -0.02887469999999999 -0.0305247 0.01415 -0.02938739999999999 -0.0303124 0.01415 -0.02742469999999999 -0.0319747 0.01415 -0.02699999999999999 -0.033 0.0158 -0.02721239999999999 -0.0324873 0.01415 -0.02699999999999999 -0.033 0.0158 -0.02699999999999999 -0.033 0.0125 -0.02721239999999999 -0.0324873 0.01415 -0.02699999999999999 -0.033 0.0125 -0.02742469999999999 -0.0319747 0.01415 -0.02721239999999999 -0.0324873 0.01415 -0.02742469999999999 -0.0319747 0.01415 -0.02784939999999999 -0.0309494 0.0125 -0.02763699999999999 -0.0314621 0.01415 -0.02784939999999999 -0.0309494 0.0125 -0.02784939999999999 -0.0309494 0.0158 -0.02763699999999999 -0.0314621 0.01415 -0.02784939999999999 -0.0309494 0.0158 -0.02742469999999999 -0.0319747 0.01415 -0.02763699999999999 -0.0314621 0.01415 -0.02742469999999999 -0.0340253 0.01415 -0.02784939999999999 -0.0350506 0.0125 -0.02742469999999999 -0.0340253 0.013325 -0.02784939999999999 -0.0350506 0.0125 -0.02699999999999999 -0.033 0.0125 -0.02742469999999999 -0.0340253 0.013325 -0.02699999999999999 -0.033 0.0125 -0.02742469999999999 -0.0340253 0.01415 -0.02742469999999999 -0.0340253 0.013325 -0.002899999999999993 -0.0428 0.0125 -0.02784939999999999 -0.0350506 0.0125 -0.03869999999999999 -0.0428 0.0125 -0.02079999999999999 -0.0428 0 -0.03869999999999999 -0.0428 -0.0125 -0.02079999999999999 -0.0428 -0.00625 -0.03869999999999999 -0.0428 -0.0125 -0.002899999999999993 -0.0428 -0.0125 -0.02079999999999999 -0.0428 -0.00625 -0.002899999999999993 -0.0428 -0.0125 -0.02079999999999999 -0.0428 0 -0.02079999999999999 -0.0428 -0.00625 -0.02079999999999999 -0.0428 0 -0.002899999999999993 -0.0428 0.0125 -0.02079999999999999 -0.0428 0.00625 -0.002899999999999993 -0.0428 0.0125 -0.03869999999999999 -0.0428 0.0125 -0.02079999999999999 -0.0428 0.00625 -0.03869999999999999 -0.0428 0.0125 -0.02079999999999999 -0.0428 0 -0.02079999999999999 -0.0428 0.00625 -0.03869999999999999 -0.0428 -0.0125 -0.02777869999999999 -0.0351213 -0.0125 -0.002899999999999993 -0.0428 -0.0125 -0.02733929999999999 -0.0340607 -0.013325 -0.02733929999999999 -0.0340607 -0.01415 -0.02689999999999999 -0.033 -0.0125 -0.02733929999999999 -0.0340607 -0.013325 -0.02689999999999999 -0.033 -0.0125 -0.02777869999999999 -0.0351213 -0.0125 -0.02733929999999999 -0.0340607 -0.013325 -0.02777869999999999 -0.0351213 -0.0125 -0.02733929999999999 -0.0340607 -0.01415 -0.02733929999999999 -0.0319393 -0.01415 -0.02777869999999999 -0.0308787 -0.0158 -0.02755899999999999 -0.031409 -0.01415 -0.02777869999999999 -0.0308787 -0.0158 -0.02777869999999999 -0.0308787 -0.0125 -0.02755899999999999 -0.031409 -0.01415 -0.02777869999999999 -0.0308787 -0.0125 -0.02733929999999999 -0.0319393 -0.01415 -0.02755899999999999 -0.031409 -0.01415 -0.02733929999999999 -0.0319393 -0.01415 -0.02689999999999999 -0.033 -0.0125 -0.02711969999999999 -0.0324697 -0.01415 -0.02689999999999999 -0.033 -0.0125 -0.02689999999999999 -0.033 -0.0158 -0.02711969999999999 -0.0324697 -0.01415 -0.02689999999999999 -0.033 -0.0158 -0.02733929999999999 -0.0319393 -0.01415 -0.02711969999999999 -0.0324697 -0.01415 -0.02883929999999999 -0.0304393 -0.01415 -0.02989999999999999 -0.03 -0.0158 -0.02936959999999999 -0.0302196 -0.01415 -0.02989999999999999 -0.03 -0.0158 -0.02989999999999999 -0.03 -0.0125 -0.02936959999999999 -0.0302196 -0.01415 -0.02989999999999999 -0.03 -0.0125 -0.02883929999999999 -0.0304393 -0.01415 -0.02936959999999999 -0.0302196 -0.01415 -0.02883929999999999 -0.0304393 -0.01415 -0.02777869999999999 -0.0308787 -0.0125 -0.02830899999999999 -0.030659 -0.01415 -0.02777869999999999 -0.0308787 -0.0125 -0.02777869999999999 -0.0308787 -0.0158 -0.02830899999999999 -0.030659 -0.01415 -0.02777869999999999 -0.0308787 -0.0158 -0.02883929999999999 -0.0304393 -0.01415 -0.02830899999999999 -0.030659 -0.01415 -0.03096069999999999 -0.0304393 -0.01415 -0.0320213 -0.0308787 -0.0125 -0.03096069999999999 -0.0304393 -0.013325 -0.0320213 -0.0308787 -0.0125 -0.02989999999999999 -0.03 -0.0125 -0.03096069999999999 -0.0304393 -0.013325 -0.02989999999999999 -0.03 -0.0125 -0.03096069999999999 -0.0304393 -0.01415 -0.03096069999999999 -0.0304393 -0.013325 -0.0320213 -0.0308787 -0.0125 -0.03289999999999999 -0.033 -0.0125 -0.03869999999999999 -0.022 -0.0125 0.003000000000000007 -0.0049497 0.0049497 0.003000000000000007 -0.007 0 0.009000000000000006 -0.0059749 0.0024749 0.009000000000000006 -0.0024749 0.0059749 0.01500000000000001 0 0.007 0.003000000000000007 0 0.007 0.01500000000000001 -0.0049497 0.0049497 0.009000000000000006 -0.0024749 0.0059749 0.003000000000000007 -0.0049497 0.0049497 0.009000000000000006 0.0024749 0.0059749 0.01500000000000001 0.0049497 0.0049497 0.003000000000000007 0.0049497 0.0049497 0.01500000000000001 0 0.007 0.009000000000000006 0.0024749 0.0059749 0.003000000000000007 0 0.007 0.009000000000000006 0.0059749 0.0024749 0.01500000000000001 0.0049497 0.0049497 0.01500000000000001 0.007 0 0.009000000000000006 0.0059749 -0.0024749 0.01500000000000001 0.007 0 0.01500000000000001 0.0049497 -0.0049497 0.01500000000000001 0.0049497 -0.0049497 0.009000000000000006 0.0024749 -0.0059749 0.003000000000000007 0.0049497 -0.0049497 0.009000000000000006 0.0024749 -0.0059749 0.01500000000000001 0 -0.007 0.003000000000000007 0 -0.007 0.009000000000000006 -0.0024749 -0.0059749 0.01500000000000001 -0.0049497 -0.0049497 0.003000000000000007 -0.0049497 -0.0049497 0.01500000000000001 0 -0.007 0.009000000000000006 -0.0024749 -0.0059749 0.003000000000000007 0 -0.007 0.009000000000000006 -0.0059749 -0.0024749 0.003000000000000007 -0.007 0 0.003000000000000007 -0.0049497 -0.0049497 -0.02989999999999999 0.033 -0.0158 -0.02989999999999999 0.0359 -0.0158 -0.02784939999999999 0.0350506 -0.0158 -0.03092529999999999 0.0354753 -0.01415 -0.02989999999999999 0.0359 -0.0125 -0.03041259999999999 0.0356876 -0.01415 -0.02989999999999999 0.0359 -0.0125 -0.02989999999999999 0.0359 -0.0158 -0.03041259999999999 0.0356876 -0.01415 -0.02989999999999999 0.0359 -0.0158 -0.03092529999999999 0.0354753 -0.01415 -0.03041259999999999 0.0356876 -0.01415 -0.03092529999999999 0.0354753 -0.01415 -0.0319506 0.0350506 -0.0158 -0.03143789999999999 0.0352629 -0.01415 -0.0319506 0.0350506 -0.0158 -0.0319506 0.0350506 -0.0125 -0.03143789999999999 0.0352629 -0.01415 -0.0319506 0.0350506 -0.0125 -0.03092529999999999 0.0354753 -0.01415 -0.03143789999999999 0.0352629 -0.01415 -0.0323753 0.0340253 -0.01415 -0.0328 0.033 -0.0158 -0.03258759999999999 0.0335127 -0.01415 -0.0328 0.033 -0.0158 -0.0328 0.033 -0.0125 -0.03258759999999999 0.0335127 -0.01415 -0.0328 0.033 -0.0125 -0.0323753 0.0340253 -0.01415 -0.03258759999999999 0.0335127 -0.01415 -0.0323753 0.0340253 -0.01415 -0.0319506 0.0350506 -0.0125 -0.03216289999999999 0.0345379 -0.01415 -0.0319506 0.0350506 -0.0125 -0.0319506 0.0350506 -0.0158 -0.03216289999999999 0.0345379 -0.01415 -0.0319506 0.0350506 -0.0158 -0.0323753 0.0340253 -0.01415 -0.03216289999999999 0.0345379 -0.01415 -0.0319506 0.0309494 -0.0158 -0.0328 0.033 -0.0158 -0.02989999999999999 0.033 -0.0158 -0.03096069999999999 0.0355607 0.01415 -0.02989999999999999 0.036 0.0158 -0.03043039999999999 0.0357803 0.01415 -0.02989999999999999 0.036 0.0158 -0.02989999999999999 0.036 0.0125 -0.03043039999999999 0.0357803 0.01415 -0.02989999999999999 0.036 0.0125 -0.03096069999999999 0.0355607 0.01415 -0.03043039999999999 0.0357803 0.01415 -0.03096069999999999 0.0355607 0.01415 -0.0320213 0.0351213 0.0125 -0.03149099999999999 0.035341 0.01415 -0.0320213 0.0351213 0.0125 -0.0320213 0.0351213 0.0158 -0.03149099999999999 0.035341 0.01415 -0.0320213 0.0351213 0.0158 -0.03096069999999999 0.0355607 0.01415 -0.03149099999999999 0.035341 0.01415 -0.02989999999999999 0.033 0.0158 -0.02777869999999999 0.0351213 0.0158 -0.02989999999999999 0.036 0.0158 -0.0320213 0.0308787 0.0158 -0.02989999999999999 0.033 0.0158 -0.03289999999999999 0.033 0.0158 -0.0324607 0.0340607 0.01415 -0.0320213 0.0351213 0.0158 -0.03224099999999999 0.034591 0.01415 -0.0320213 0.0351213 0.0158 -0.0320213 0.0351213 0.0125 -0.03224099999999999 0.034591 0.01415 -0.0320213 0.0351213 0.0125 -0.0324607 0.0340607 0.01415 -0.03224099999999999 0.034591 0.01415 -0.0324607 0.0340607 0.01415 -0.03289999999999999 0.033 0.0125 -0.03268039999999999 0.0335304 0.01415 -0.03289999999999999 0.033 0.0125 -0.03289999999999999 0.033 0.0158 -0.03268039999999999 0.0335304 0.01415 -0.03289999999999999 0.033 0.0158 -0.0324607 0.0340607 0.01415 -0.03268039999999999 0.0335304 0.01415 -0.03869999999999999 -0.0324 0 -0.03869999999999999 -0.0428 -0.0125 -0.03869999999999999 -0.0376 -1.56125e-17 -0.03869999999999999 -0.0428 -0.0125 -0.03869999999999999 -0.0428 0.0125 -0.03869999999999999 -0.0376 -1.56125e-17 -0.03869999999999999 -0.0428 0.0125 -0.03869999999999999 -0.0324 0 -0.03869999999999999 -0.0376 -1.56125e-17 -0.03869999999999999 -0.0428 0.0125 -0.0319506 -0.0350506 0.0125 -0.03869999999999999 -0.022 0.0125 -0.0320213 -0.0351213 -0.0125 -0.03869999999999999 -0.0428 -0.0125 -0.03869999999999999 -0.022 -0.0125 -0.0319506 -0.0350506 0.0125 -0.0328 -0.033 0.0125 -0.03869999999999999 -0.022 0.0125 -0.0323753 -0.0319747 0.01415 -0.0319506 -0.0309494 0.0125 -0.0323753 -0.0319747 0.013325 -0.0319506 -0.0309494 0.0125 -0.0328 -0.033 0.0125 -0.0323753 -0.0319747 0.013325 -0.0328 -0.033 0.0125 -0.0323753 -0.0319747 0.01415 -0.0323753 -0.0319747 0.013325 -0.03092529999999999 -0.0305247 0.01415 -0.02989999999999999 -0.0301 0.0158 -0.03041259999999999 -0.0303124 0.01415 -0.02989999999999999 -0.0301 0.0158 -0.02989999999999999 -0.0301 0.0125 -0.03041259999999999 -0.0303124 0.01415 -0.02989999999999999 -0.0301 0.0125 -0.03092529999999999 -0.0305247 0.01415 -0.03041259999999999 -0.0303124 0.01415 -0.03092529999999999 -0.0305247 0.01415 -0.0319506 -0.0309494 0.0125 -0.03143789999999999 -0.030737 0.01415 -0.0319506 -0.0309494 0.0125 -0.0319506 -0.0309494 0.0158 -0.03143789999999999 -0.030737 0.01415 -0.0319506 -0.0309494 0.0158 -0.03092529999999999 -0.0305247 0.01415 -0.03143789999999999 -0.030737 0.01415 -0.02887469999999999 -0.0305247 0.01415 -0.02989999999999999 -0.0301 0.0158 -0.02887469999999999 -0.0305247 0.014975 -0.02989999999999999 -0.0301 0.0158 -0.02784939999999999 -0.0309494 0.0158 -0.02887469999999999 -0.0305247 0.014975 -0.02784939999999999 -0.0309494 0.0158 -0.02887469999999999 -0.0305247 0.01415 -0.02887469999999999 -0.0305247 0.014975 -0.02742469999999999 -0.0319747 0.01415 -0.02784939999999999 -0.0309494 0.0158 -0.02742469999999999 -0.0319747 0.014975 -0.02784939999999999 -0.0309494 0.0158 -0.02699999999999999 -0.033 0.0158 -0.02742469999999999 -0.0319747 0.014975 -0.02699999999999999 -0.033 0.0158 -0.02742469999999999 -0.0319747 0.01415 -0.02742469999999999 -0.0319747 0.014975 -0.02742469999999999 -0.0340253 0.01415 -0.02699999999999999 -0.033 0.0125 -0.02721239999999999 -0.0335127 0.01415 -0.02699999999999999 -0.033 0.0125 -0.02699999999999999 -0.033 0.0158 -0.02721239999999999 -0.0335127 0.01415 -0.02699999999999999 -0.033 0.0158 -0.02742469999999999 -0.0340253 0.01415 -0.02721239999999999 -0.0335127 0.01415 -0.02742469999999999 -0.0340253 0.01415 -0.02784939999999999 -0.0350506 0.0158 -0.02763699999999999 -0.0345379 0.01415 -0.02784939999999999 -0.0350506 0.0158 -0.02784939999999999 -0.0350506 0.0125 -0.02763699999999999 -0.0345379 0.01415 -0.02784939999999999 -0.0350506 0.0125 -0.02742469999999999 -0.0340253 0.01415 -0.02763699999999999 -0.0345379 0.01415 -0.03869999999999999 -0.0428 0.0125 -0.02784939999999999 -0.0350506 0.0125 -0.02989999999999999 -0.0359 0.0125 -0.02079999999999999 -0.0428 0 -0.03869999999999999 -0.0428 0.0125 -0.02974999999999999 -0.0428 6.07153e-18 -0.03869999999999999 -0.0428 0.0125 -0.03869999999999999 -0.0428 -0.0125 -0.02974999999999999 -0.0428 6.07153e-18 -0.03869999999999999 -0.0428 -0.0125 -0.02079999999999999 -0.0428 0 -0.02974999999999999 -0.0428 6.07153e-18 -0.02989999999999999 -0.036 -0.0125 -0.02777869999999999 -0.0351213 -0.0125 -0.03869999999999999 -0.0428 -0.0125 -0.02733929999999999 -0.0340607 -0.01415 -0.02689999999999999 -0.033 -0.0158 -0.02711969999999999 -0.0335304 -0.01415 -0.02689999999999999 -0.033 -0.0158 -0.02689999999999999 -0.033 -0.0125 -0.02711969999999999 -0.0335304 -0.01415 -0.02689999999999999 -0.033 -0.0125 -0.02733929999999999 -0.0340607 -0.01415 -0.02711969999999999 -0.0335304 -0.01415 -0.02733929999999999 -0.0340607 -0.01415 -0.02777869999999999 -0.0351213 -0.0125 -0.02755899999999999 -0.034591 -0.01415 -0.02777869999999999 -0.0351213 -0.0125 -0.02777869999999999 -0.0351213 -0.0158 -0.02755899999999999 -0.034591 -0.01415 -0.02777869999999999 -0.0351213 -0.0158 -0.02733929999999999 -0.0340607 -0.01415 -0.02755899999999999 -0.034591 -0.01415 -0.02733929999999999 -0.0319393 -0.014975 -0.02733929999999999 -0.0319393 -0.01415 -0.02689999999999999 -0.033 -0.0158 -0.02733929999999999 -0.0319393 -0.014975 -0.02689999999999999 -0.033 -0.0158 -0.02777869999999999 -0.0308787 -0.0158 -0.02733929999999999 -0.0319393 -0.014975 -0.02777869999999999 -0.0308787 -0.0158 -0.02733929999999999 -0.0319393 -0.01415 -0.02883929999999999 -0.0304393 -0.01415 -0.02777869999999999 -0.0308787 -0.0158 -0.02883929999999999 -0.0304393 -0.014975 -0.02777869999999999 -0.0308787 -0.0158 -0.02989999999999999 -0.03 -0.0158 -0.02883929999999999 -0.0304393 -0.014975 -0.02989999999999999 -0.03 -0.0158 -0.02883929999999999 -0.0304393 -0.01415 -0.02883929999999999 -0.0304393 -0.014975 -0.03096069999999999 -0.0304393 -0.01415 -0.02989999999999999 -0.03 -0.0125 -0.03043039999999999 -0.0302196 -0.01415 -0.02989999999999999 -0.03 -0.0125 -0.02989999999999999 -0.03 -0.0158 -0.03043039999999999 -0.0302196 -0.01415 -0.02989999999999999 -0.03 -0.0158 -0.03096069999999999 -0.0304393 -0.01415 -0.03043039999999999 -0.0302196 -0.01415 -0.03096069999999999 -0.0304393 -0.01415 -0.0320213 -0.0308787 -0.0158 -0.03149099999999999 -0.030659 -0.01415 -0.0320213 -0.0308787 -0.0158 -0.0320213 -0.0308787 -0.0125 -0.03149099999999999 -0.030659 -0.01415 -0.0320213 -0.0308787 -0.0125 -0.03096069999999999 -0.0304393 -0.01415 -0.03149099999999999 -0.030659 -0.01415 -0.0324607 -0.0319393 -0.013325 -0.0324607 -0.0319393 -0.01415 -0.03289999999999999 -0.033 -0.0125 -0.0324607 -0.0319393 -0.013325 -0.03289999999999999 -0.033 -0.0125 -0.0320213 -0.0308787 -0.0125 -0.0324607 -0.0319393 -0.013325 -0.0320213 -0.0308787 -0.0125 -0.0324607 -0.0319393 -0.01415 -0.03869999999999999 -0.022 -0.0125 -0.03289999999999999 -0.033 -0.0125 -0.0320213 -0.0351213 -0.0125 0.003000000000000007 -0.0049497 0.0049497 0.009000000000000006 -0.0059749 0.0024749 0.01500000000000001 -0.0049497 0.0049497 0.009000000000000006 -0.0059749 0.0024749 0.003000000000000007 -0.007 0 0.01500000000000001 -0.007 0 0.01500000000000001 -0.0049497 0.0049497 0.01500000000000001 0 0.007 0.009000000000000006 -0.0024749 0.0059749 0.01500000000000001 0 0.007 0.01500000000000001 0.0049497 0.0049497 0.009000000000000006 0.0024749 0.0059749 0.01500000000000001 0.007 0 0.01500000000000001 0.0049497 0.0049497 0.01500000000000001 0.0123744 -0.0123744 0.01500000000000001 0.0123744 -0.0123744 0.01500000000000001 0.0049497 -0.0049497 0.01500000000000001 0.007 0 0.01500000000000001 0.0049497 -0.0049497 0.01500000000000001 0 -0.007 0.009000000000000006 0.0024749 -0.0059749 0.01500000000000001 0 -0.007 0.01500000000000001 -0.0049497 -0.0049497 0.009000000000000006 -0.0024749 -0.0059749 0.009000000000000006 -0.0059749 -0.0024749 0.003000000000000007 -0.0049497 -0.0049497 0.01500000000000001 -0.0049497 -0.0049497 0.003000000000000007 -0.007 0 0.009000000000000006 -0.0059749 -0.0024749 0.01500000000000001 -0.007 0 -0.02989999999999999 0.033 -0.0158 -0.0319506 0.0350506 -0.0158 -0.02989999999999999 0.0359 -0.0158 -0.03092529999999999 0.0354753 -0.01415 -0.02989999999999999 0.0359 -0.0158 -0.03092529999999999 0.0354753 -0.014975 -0.02989999999999999 0.0359 -0.0158 -0.0319506 0.0350506 -0.0158 -0.03092529999999999 0.0354753 -0.014975 -0.0319506 0.0350506 -0.0158 -0.03092529999999999 0.0354753 -0.01415 -0.03092529999999999 0.0354753 -0.014975 -0.0323753 0.0340253 -0.014975 -0.0323753 0.0340253 -0.01415 -0.0319506 0.0350506 -0.0158 -0.0323753 0.0340253 -0.014975 -0.0319506 0.0350506 -0.0158 -0.0328 0.033 -0.0158 -0.0323753 0.0340253 -0.014975 -0.0328 0.033 -0.0158 -0.0323753 0.0340253 -0.01415 -0.02989999999999999 0.033 -0.0158 -0.0328 0.033 -0.0158 -0.0319506 0.0350506 -0.0158 -0.03096069999999999 0.0355607 0.014975 -0.03096069999999999 0.0355607 0.01415 -0.0320213 0.0351213 0.0158 -0.03096069999999999 0.0355607 0.014975 -0.0320213 0.0351213 0.0158 -0.02989999999999999 0.036 0.0158 -0.03096069999999999 0.0355607 0.014975 -0.02989999999999999 0.036 0.0158 -0.03096069999999999 0.0355607 0.01415 -0.02989999999999999 0.033 0.0158 -0.02989999999999999 0.036 0.0158 -0.0320213 0.0351213 0.0158 -0.03289999999999999 0.033 0.0158 -0.02989999999999999 0.033 0.0158 -0.0320213 0.0351213 0.0158 -0.0324607 0.0340607 0.014975 -0.0324607 0.0340607 0.01415 -0.03289999999999999 0.033 0.0158 -0.0324607 0.0340607 0.014975 -0.03289999999999999 0.033 0.0158 -0.0320213 0.0351213 0.0158 -0.0324607 0.0340607 0.014975 -0.0320213 0.0351213 0.0158 -0.0324607 0.0340607 0.01415 -0.03869999999999999 -0.0428 0.0125 -0.02989999999999999 -0.0359 0.0125 -0.0319506 -0.0350506 0.0125 -0.03869999999999999 -0.0428 -0.0125 -0.0320213 -0.0351213 -0.0125 -0.02989999999999999 -0.036 -0.0125 -0.0323753 -0.0340253 0.01415 -0.0328 -0.033 0.0125 -0.0323753 -0.0340253 0.013325 -0.0328 -0.033 0.0125 -0.0319506 -0.0350506 0.0125 -0.0323753 -0.0340253 0.013325 -0.0319506 -0.0350506 0.0125 -0.0323753 -0.0340253 0.01415 -0.0323753 -0.0340253 0.013325 -0.0323753 -0.0319747 0.01415 -0.0319506 -0.0309494 0.0158 -0.03216289999999999 -0.0314621 0.01415 -0.0319506 -0.0309494 0.0158 -0.0319506 -0.0309494 0.0125 -0.03216289999999999 -0.0314621 0.01415 -0.0319506 -0.0309494 0.0125 -0.0323753 -0.0319747 0.01415 -0.03216289999999999 -0.0314621 0.01415 -0.0323753 -0.0319747 0.01415 -0.0328 -0.033 0.0125 -0.03258759999999999 -0.0324873 0.01415 -0.0328 -0.033 0.0125 -0.0328 -0.033 0.0158 -0.03258759999999999 -0.0324873 0.01415 -0.0328 -0.033 0.0158 -0.0323753 -0.0319747 0.01415 -0.03258759999999999 -0.0324873 0.01415 -0.03092529999999999 -0.0305247 0.01415 -0.0319506 -0.0309494 0.0158 -0.03092529999999999 -0.0305247 0.014975 -0.0319506 -0.0309494 0.0158 -0.02989999999999999 -0.0301 0.0158 -0.03092529999999999 -0.0305247 0.014975 -0.02989999999999999 -0.0301 0.0158 -0.03092529999999999 -0.0305247 0.01415 -0.03092529999999999 -0.0305247 0.014975 -0.02989999999999999 -0.033 0.0158 -0.02784939999999999 -0.0309494 0.0158 -0.02989999999999999 -0.0301 0.0158 -0.02699999999999999 -0.033 0.0158 -0.02784939999999999 -0.0309494 0.0158 -0.02989999999999999 -0.033 0.0158 -0.02742469999999999 -0.0340253 0.01415 -0.02699999999999999 -0.033 0.0158 -0.02742469999999999 -0.0340253 0.014975 -0.02699999999999999 -0.033 0.0158 -0.02784939999999999 -0.0350506 0.0158 -0.02742469999999999 -0.0340253 0.014975 -0.02784939999999999 -0.0350506 0.0158 -0.02742469999999999 -0.0340253 0.01415 -0.02742469999999999 -0.0340253 0.014975 -0.02887469999999999 -0.0354753 0.01415 -0.02784939999999999 -0.0350506 0.0125 -0.02836209999999999 -0.0352629 0.01415 -0.02784939999999999 -0.0350506 0.0125 -0.02784939999999999 -0.0350506 0.0158 -0.02836209999999999 -0.0352629 0.01415 -0.02784939999999999 -0.0350506 0.0158 -0.02887469999999999 -0.0354753 0.01415 -0.02836209999999999 -0.0352629 0.01415 -0.02887469999999999 -0.0354753 0.013325 -0.02887469999999999 -0.0354753 0.01415 -0.02989999999999999 -0.0359 0.0125 -0.02887469999999999 -0.0354753 0.013325 -0.02989999999999999 -0.0359 0.0125 -0.02784939999999999 -0.0350506 0.0125 -0.02887469999999999 -0.0354753 0.013325 -0.02784939999999999 -0.0350506 0.0125 -0.02887469999999999 -0.0354753 0.01415 -0.02883929999999999 -0.0355607 -0.01415 -0.02777869999999999 -0.0351213 -0.0125 -0.02883929999999999 -0.0355607 -0.013325 -0.02777869999999999 -0.0351213 -0.0125 -0.02989999999999999 -0.036 -0.0125 -0.02883929999999999 -0.0355607 -0.013325 -0.02989999999999999 -0.036 -0.0125 -0.02883929999999999 -0.0355607 -0.01415 -0.02883929999999999 -0.0355607 -0.013325 -0.02733929999999999 -0.0340607 -0.01415 -0.02777869999999999 -0.0351213 -0.0158 -0.02733929999999999 -0.0340607 -0.014975 -0.02777869999999999 -0.0351213 -0.0158 -0.02689999999999999 -0.033 -0.0158 -0.02733929999999999 -0.0340607 -0.014975 -0.02689999999999999 -0.033 -0.0158 -0.02733929999999999 -0.0340607 -0.01415 -0.02733929999999999 -0.0340607 -0.014975 -0.02883929999999999 -0.0355607 -0.01415 -0.02777869999999999 -0.0351213 -0.0158 -0.02830899999999999 -0.035341 -0.01415 -0.02777869999999999 -0.0351213 -0.0158 -0.02777869999999999 -0.0351213 -0.0125 -0.02830899999999999 -0.035341 -0.01415 -0.02777869999999999 -0.0351213 -0.0125 -0.02883929999999999 -0.0355607 -0.01415 -0.02830899999999999 -0.035341 -0.01415 -0.02689999999999999 -0.033 -0.0158 -0.02989999999999999 -0.033 -0.0158 -0.02777869999999999 -0.0308787 -0.0158 -0.02989999999999999 -0.033 -0.0158 -0.02989999999999999 -0.03 -0.0158 -0.02777869999999999 -0.0308787 -0.0158 -0.03096069999999999 -0.0304393 -0.01415 -0.02989999999999999 -0.03 -0.0158 -0.03096069999999999 -0.0304393 -0.014975 -0.02989999999999999 -0.03 -0.0158 -0.0320213 -0.0308787 -0.0158 -0.03096069999999999 -0.0304393 -0.014975 -0.0320213 -0.0308787 -0.0158 -0.03096069999999999 -0.0304393 -0.01415 -0.03096069999999999 -0.0304393 -0.014975 -0.0324607 -0.0319393 -0.01415 -0.0320213 -0.0308787 -0.0125 -0.03224099999999999 -0.031409 -0.01415 -0.0320213 -0.0308787 -0.0125 -0.0320213 -0.0308787 -0.0158 -0.03224099999999999 -0.031409 -0.01415 -0.0320213 -0.0308787 -0.0158 -0.0324607 -0.0319393 -0.01415 -0.03224099999999999 -0.031409 -0.01415 -0.0324607 -0.0319393 -0.01415 -0.03289999999999999 -0.033 -0.0158 -0.03268039999999999 -0.0324697 -0.01415 -0.03289999999999999 -0.033 -0.0158 -0.03289999999999999 -0.033 -0.0125 -0.03268039999999999 -0.0324697 -0.01415 -0.03289999999999999 -0.033 -0.0125 -0.0324607 -0.0319393 -0.01415 -0.03268039999999999 -0.0324697 -0.01415 -0.0324607 -0.0340607 -0.013325 -0.0324607 -0.0340607 -0.01415 -0.0320213 -0.0351213 -0.0125 -0.0324607 -0.0340607 -0.013325 -0.0320213 -0.0351213 -0.0125 -0.03289999999999999 -0.033 -0.0125 -0.0324607 -0.0340607 -0.013325 -0.03289999999999999 -0.033 -0.0125 -0.0324607 -0.0340607 -0.01415 0.009000000000000006 -0.0059749 0.0024749 0.01500000000000001 -0.007 0 0.01500000000000001 -0.0049497 0.0049497 0.01500000000000001 0 0.007 0.01500000000000001 -0.0049497 0.0049497 0.01500000000000001 -0.0123744 0.0123744 0.01500000000000001 -0.0123744 0.0123744 0.01500000000000001 0.0049497 0.0049497 0.01500000000000001 0 0.007 0.01500000000000001 0.0175 0 0.01500000000000001 0.0123744 -0.0123744 0.01500000000000001 0.0049497 0.0049497 0.01500000000000001 0.0049497 -0.0049497 0.01500000000000001 0.0123744 -0.0123744 0.01500000000000001 0 -0.007 0.01500000000000001 0 -0.007 0.01500000000000001 0 -0.0175 0.01500000000000001 -0.0049497 -0.0049497 0.009000000000000006 -0.0059749 -0.0024749 0.01500000000000001 -0.0049497 -0.0049497 0.01500000000000001 -0.007 0 -0.03092529999999999 -0.0354753 0.013325 -0.03092529999999999 -0.0354753 0.01415 -0.0319506 -0.0350506 0.0125 -0.03092529999999999 -0.0354753 0.013325 -0.0319506 -0.0350506 0.0125 -0.02989999999999999 -0.0359 0.0125 -0.03092529999999999 -0.0354753 0.013325 -0.02989999999999999 -0.0359 0.0125 -0.03092529999999999 -0.0354753 0.01415 -0.03096069999999999 -0.0355607 -0.01415 -0.02989999999999999 -0.036 -0.0125 -0.03096069999999999 -0.0355607 -0.013325 -0.02989999999999999 -0.036 -0.0125 -0.0320213 -0.0351213 -0.0125 -0.03096069999999999 -0.0355607 -0.013325 -0.0320213 -0.0351213 -0.0125 -0.03096069999999999 -0.0355607 -0.01415 -0.03096069999999999 -0.0355607 -0.013325 -0.0323753 -0.0340253 0.01415 -0.0328 -0.033 0.0158 -0.03258759999999999 -0.0335127 0.01415 -0.0328 -0.033 0.0158 -0.0328 -0.033 0.0125 -0.03258759999999999 -0.0335127 0.01415 -0.0328 -0.033 0.0125 -0.0323753 -0.0340253 0.01415 -0.03258759999999999 -0.0335127 0.01415 -0.0323753 -0.0340253 0.01415 -0.0319506 -0.0350506 0.0125 -0.03216289999999999 -0.0345379 0.01415 -0.0319506 -0.0350506 0.0125 -0.0319506 -0.0350506 0.0158 -0.03216289999999999 -0.0345379 0.01415 -0.0319506 -0.0350506 0.0158 -0.0323753 -0.0340253 0.01415 -0.03216289999999999 -0.0345379 0.01415 -0.0323753 -0.0319747 0.014975 -0.0323753 -0.0319747 0.01415 -0.0328 -0.033 0.0158 -0.0323753 -0.0319747 0.014975 -0.0328 -0.033 0.0158 -0.0319506 -0.0309494 0.0158 -0.0323753 -0.0319747 0.014975 -0.0319506 -0.0309494 0.0158 -0.0323753 -0.0319747 0.01415 -0.02989999999999999 -0.033 0.0158 -0.02989999999999999 -0.0301 0.0158 -0.0319506 -0.0309494 0.0158 -0.02784939999999999 -0.0350506 0.0158 -0.02699999999999999 -0.033 0.0158 -0.02989999999999999 -0.033 0.0158 -0.02887469999999999 -0.0354753 0.01415 -0.02784939999999999 -0.0350506 0.0158 -0.02887469999999999 -0.0354753 0.014975 -0.02784939999999999 -0.0350506 0.0158 -0.02989999999999999 -0.0359 0.0158 -0.02887469999999999 -0.0354753 0.014975 -0.02989999999999999 -0.0359 0.0158 -0.02887469999999999 -0.0354753 0.01415 -0.02887469999999999 -0.0354753 0.014975 -0.02887469999999999 -0.0354753 0.01415 -0.02989999999999999 -0.0359 0.0158 -0.02938739999999999 -0.0356876 0.01415 -0.02989999999999999 -0.0359 0.0158 -0.02989999999999999 -0.0359 0.0125 -0.02938739999999999 -0.0356876 0.01415 -0.02989999999999999 -0.0359 0.0125 -0.02887469999999999 -0.0354753 0.01415 -0.02938739999999999 -0.0356876 0.01415 -0.02883929999999999 -0.0355607 -0.01415 -0.02989999999999999 -0.036 -0.0125 -0.02936959999999999 -0.0357803 -0.01415 -0.02989999999999999 -0.036 -0.0125 -0.02989999999999999 -0.036 -0.0158 -0.02936959999999999 -0.0357803 -0.01415 -0.02989999999999999 -0.036 -0.0158 -0.02883929999999999 -0.0355607 -0.01415 -0.02936959999999999 -0.0357803 -0.01415 -0.02777869999999999 -0.0351213 -0.0158 -0.02989999999999999 -0.033 -0.0158 -0.02689999999999999 -0.033 -0.0158 -0.02883929999999999 -0.0355607 -0.014975 -0.02883929999999999 -0.0355607 -0.01415 -0.02989999999999999 -0.036 -0.0158 -0.02883929999999999 -0.0355607 -0.014975 -0.02989999999999999 -0.036 -0.0158 -0.02777869999999999 -0.0351213 -0.0158 -0.02883929999999999 -0.0355607 -0.014975 -0.02777869999999999 -0.0351213 -0.0158 -0.02883929999999999 -0.0355607 -0.01415 -0.02989999999999999 -0.033 -0.0158 -0.0320213 -0.0308787 -0.0158 -0.02989999999999999 -0.03 -0.0158 -0.0324607 -0.0319393 -0.014975 -0.0324607 -0.0319393 -0.01415 -0.0320213 -0.0308787 -0.0158 -0.0324607 -0.0319393 -0.014975 -0.0320213 -0.0308787 -0.0158 -0.03289999999999999 -0.033 -0.0158 -0.0324607 -0.0319393 -0.014975 -0.03289999999999999 -0.033 -0.0158 -0.0324607 -0.0319393 -0.01415 -0.0324607 -0.0340607 -0.01415 -0.03289999999999999 -0.033 -0.0125 -0.03268039999999999 -0.0335304 -0.01415 -0.03289999999999999 -0.033 -0.0125 -0.03289999999999999 -0.033 -0.0158 -0.03268039999999999 -0.0335304 -0.01415 -0.03289999999999999 -0.033 -0.0158 -0.0324607 -0.0340607 -0.01415 -0.03268039999999999 -0.0335304 -0.01415 -0.0324607 -0.0340607 -0.01415 -0.0320213 -0.0351213 -0.0158 -0.03224099999999999 -0.034591 -0.01415 -0.0320213 -0.0351213 -0.0158 -0.0320213 -0.0351213 -0.0125 -0.03224099999999999 -0.034591 -0.01415 -0.0320213 -0.0351213 -0.0125 -0.0324607 -0.0340607 -0.01415 -0.03224099999999999 -0.034591 -0.01415 0.01500000000000001 -0.0049497 0.0049497 0.01500000000000001 -0.007 0 0.01500000000000001 -0.0175 0 0.01500000000000001 -0.0123744 0.0123744 0.01500000000000001 -0.0049497 0.0049497 0.01500000000000001 -0.0112249 0.0061872 0.01500000000000001 -0.0049497 0.0049497 0.01500000000000001 -0.0175 0 0.01500000000000001 -0.0112249 0.0061872 0.01500000000000001 -0.0175 0 0.01500000000000001 -0.0123744 0.0123744 0.01500000000000001 -0.0112249 0.0061872 0.01500000000000001 -0.0123744 0.0123744 0.01500000000000001 0.0175 0 0.01500000000000001 0.0049497 0.0049497 0.01500000000000001 0.0175 0 0.01625000000000001 0.0149372 -0.0061872 0.01500000000000001 0.0123744 -0.0123744 0.01500000000000001 0.0123744 -0.0123744 0.01500000000000001 0 -0.0175 0.01500000000000001 0 -0.007 0.01500000000000001 -0.0049497 -0.0049497 0.01500000000000001 0 -0.0175 0.01500000000000001 -0.0175 0 0.01500000000000001 -0.007 0 0.01500000000000001 -0.0049497 -0.0049497 0.01500000000000001 -0.0175 0 -0.03092529999999999 -0.0354753 0.01415 -0.0319506 -0.0350506 0.0158 -0.03143789999999999 -0.0352629 0.01415 -0.0319506 -0.0350506 0.0158 -0.0319506 -0.0350506 0.0125 -0.03143789999999999 -0.0352629 0.01415 -0.0319506 -0.0350506 0.0125 -0.03092529999999999 -0.0354753 0.01415 -0.03143789999999999 -0.0352629 0.01415 -0.03092529999999999 -0.0354753 0.01415 -0.02989999999999999 -0.0359 0.0125 -0.03041259999999999 -0.0356876 0.01415 -0.02989999999999999 -0.0359 0.0125 -0.02989999999999999 -0.0359 0.0158 -0.03041259999999999 -0.0356876 0.01415 -0.02989999999999999 -0.0359 0.0158 -0.03092529999999999 -0.0354753 0.01415 -0.03041259999999999 -0.0356876 0.01415 -0.03096069999999999 -0.0355607 -0.01415 -0.02989999999999999 -0.036 -0.0158 -0.03043039999999999 -0.0357803 -0.01415 -0.02989999999999999 -0.036 -0.0158 -0.02989999999999999 -0.036 -0.0125 -0.03043039999999999 -0.0357803 -0.01415 -0.02989999999999999 -0.036 -0.0125 -0.03096069999999999 -0.0355607 -0.01415 -0.03043039999999999 -0.0357803 -0.01415 -0.03096069999999999 -0.0355607 -0.01415 -0.0320213 -0.0351213 -0.0125 -0.03149099999999999 -0.035341 -0.01415 -0.0320213 -0.0351213 -0.0125 -0.0320213 -0.0351213 -0.0158 -0.03149099999999999 -0.035341 -0.01415 -0.0320213 -0.0351213 -0.0158 -0.03096069999999999 -0.0355607 -0.01415 -0.03149099999999999 -0.035341 -0.01415 -0.0323753 -0.0340253 0.014975 -0.0323753 -0.0340253 0.01415 -0.0319506 -0.0350506 0.0158 -0.0323753 -0.0340253 0.014975 -0.0319506 -0.0350506 0.0158 -0.0328 -0.033 0.0158 -0.0323753 -0.0340253 0.014975 -0.0328 -0.033 0.0158 -0.0323753 -0.0340253 0.01415 -0.0328 -0.033 0.0158 -0.02989999999999999 -0.033 0.0158 -0.0319506 -0.0309494 0.0158 -0.02989999999999999 -0.0359 0.0158 -0.02784939999999999 -0.0350506 0.0158 -0.02989999999999999 -0.033 0.0158 -0.02989999999999999 -0.036 -0.0158 -0.02989999999999999 -0.033 -0.0158 -0.02777869999999999 -0.0351213 -0.0158 -0.03289999999999999 -0.033 -0.0158 -0.0320213 -0.0308787 -0.0158 -0.02989999999999999 -0.033 -0.0158 -0.0324607 -0.0340607 -0.014975 -0.0324607 -0.0340607 -0.01415 -0.03289999999999999 -0.033 -0.0158 -0.0324607 -0.0340607 -0.014975 -0.03289999999999999 -0.033 -0.0158 -0.0320213 -0.0351213 -0.0158 -0.0324607 -0.0340607 -0.014975 -0.0320213 -0.0351213 -0.0158 -0.0324607 -0.0340607 -0.01415 0.01500000000000001 -0.0175 0 0.01625000000000001 -0.0149372 0.0061872 0.01500000000000001 -0.0123744 0.0123744 0.01500000000000001 0 0.0175 0.01500000000000001 0.0175 0 0.01500000000000001 -0.0123744 0.0123744 0.01500000000000001 0.0123744 -0.0123744 0.01625000000000001 0.0149372 -0.0061872 0.01750000000000001 0.0123744 -0.0123744 0.01500000000000001 0.0175 0 0.01750000000000001 0.0175 0 0.01625000000000001 0.0149372 -0.0061872 0.01500000000000001 0.0123744 -0.0123744 0.01625000000000001 0.0061872 -0.0149372 0.01500000000000001 0 -0.0175 0.01500000000000001 0 -0.0175 0.01500000000000001 -0.0123744 -0.0123744 0.01500000000000001 -0.0175 0 -0.03092529999999999 -0.0354753 0.01415 -0.02989999999999999 -0.0359 0.0158 -0.03092529999999999 -0.0354753 0.014975 -0.02989999999999999 -0.0359 0.0158 -0.0319506 -0.0350506 0.0158 -0.03092529999999999 -0.0354753 0.014975 -0.0319506 -0.0350506 0.0158 -0.03092529999999999 -0.0354753 0.01415 -0.03092529999999999 -0.0354753 0.014975 -0.03096069999999999 -0.0355607 -0.014975 -0.03096069999999999 -0.0355607 -0.01415 -0.0320213 -0.0351213 -0.0158 -0.03096069999999999 -0.0355607 -0.014975 -0.0320213 -0.0351213 -0.0158 -0.02989999999999999 -0.036 -0.0158 -0.03096069999999999 -0.0355607 -0.014975 -0.02989999999999999 -0.036 -0.0158 -0.03096069999999999 -0.0355607 -0.01415 -0.0319506 -0.0350506 0.0158 -0.02989999999999999 -0.033 0.0158 -0.0328 -0.033 0.0158 -0.0319506 -0.0350506 0.0158 -0.02989999999999999 -0.0359 0.0158 -0.02989999999999999 -0.033 0.0158 -0.02989999999999999 -0.036 -0.0158 -0.0320213 -0.0351213 -0.0158 -0.02989999999999999 -0.033 -0.0158 -0.0320213 -0.0351213 -0.0158 -0.03289999999999999 -0.033 -0.0158 -0.02989999999999999 -0.033 -0.0158 0.01500000000000001 -0.0123744 0.0123744 0.01625000000000001 -0.0149372 0.0061872 0.01750000000000001 -0.0123744 0.0123744 0.01500000000000001 -0.0175 0 0.01750000000000001 -0.0175 0 0.01625000000000001 -0.0149372 0.0061872 0.01500000000000001 0.0123744 0.0123744 0.01500000000000001 0.0175 0 0.01500000000000001 0 0.0175 0.01500000000000001 -0.0123744 0.0123744 0.01625000000000001 -0.0061872 0.0149372 0.01500000000000001 0 0.0175 0.01750000000000001 0.0123744 -0.0123744 0.01625000000000001 0.0149372 -0.0061872 0.01750000000000001 0.0175 0 0.01750000000000001 0.0123744 -0.0123744 0.01625000000000001 0.0061872 -0.0149372 0.01500000000000001 0.0123744 -0.0123744 0.01500000000000001 0.0175 0 0.01625000000000001 0.0149372 0.0061872 0.01750000000000001 0.0175 0 0.01750000000000001 0 -0.0175 0.01500000000000001 0 -0.0175 0.01625000000000001 0.0061872 -0.0149372 0.01500000000000001 0 -0.0175 0.01625000000000001 -0.0061872 -0.0149372 0.01500000000000001 -0.0123744 -0.0123744 0.01500000000000001 -0.0123744 -0.0123744 0.01625000000000001 -0.0149372 -0.0061872 0.01500000000000001 -0.0175 0 0.01750000000000001 -0.0123744 0.0123744 0.01625000000000001 -0.0149372 0.0061872 0.01750000000000001 -0.0175 0 0.01750000000000001 -0.0123744 0.0123744 0.01625000000000001 -0.0061872 0.0149372 0.01500000000000001 -0.0123744 0.0123744 0.01500000000000001 -0.0175 0 0.01625000000000001 -0.0149372 -0.0061872 0.01750000000000001 -0.0175 0 0.01500000000000001 0.0123744 0.0123744 0.01625000000000001 0.0149372 0.0061872 0.01500000000000001 0.0175 0 0.01500000000000001 0 0.0175 0.01625000000000001 0.0061872 0.0149372 0.01500000000000001 0.0123744 0.0123744 0.01750000000000001 0 0.0175 0.01500000000000001 0 0.0175 0.01625000000000001 -0.0061872 0.0149372 0.01750000000000001 0.0175 0 0.01750000000000001 0.012 0 0.01750000000000001 0.0123744 -0.0123744 0.01750000000000001 0 -0.0175 0.01625000000000001 0.0061872 -0.0149372 0.01750000000000001 0.0123744 -0.0123744 0.01750000000000001 0.0175 0 0.01625000000000001 0.0149372 0.0061872 0.01750000000000001 0.0123744 0.0123744 0.01750000000000001 0 -0.0175 0.01625000000000001 -0.0061872 -0.0149372 0.01500000000000001 0 -0.0175 0.01750000000000001 -0.0123744 -0.0123744 0.01500000000000001 -0.0123744 -0.0123744 0.01625000000000001 -0.0061872 -0.0149372 0.01500000000000001 -0.0123744 -0.0123744 0.01750000000000001 -0.0123744 -0.0123744 0.01625000000000001 -0.0149372 -0.0061872 0.01750000000000001 -0.008485299999999999 0.008485299999999999 0.01750000000000001 -0.0123744 0.0123744 0.01750000000000001 -0.0175 0 0.01750000000000001 0 0.0175 0.01625000000000001 -0.0061872 0.0149372 0.01750000000000001 -0.0123744 0.0123744 0.01750000000000001 -0.0175 0 0.01625000000000001 -0.0149372 -0.0061872 0.01750000000000001 -0.0123744 -0.0123744 0.01500000000000001 0.0123744 0.0123744 0.01750000000000001 0.0123744 0.0123744 0.01625000000000001 0.0149372 0.0061872 0.01750000000000001 0.0123744 0.0123744 0.01500000000000001 0.0123744 0.0123744 0.01625000000000001 0.0061872 0.0149372 0.01750000000000001 0 0.0175 0.01625000000000001 0.0061872 0.0149372 0.01500000000000001 0 0.0175 0.01750000000000001 0.0175 0 0.01750000000000001 0.008485299999999999 0.008485299999999999 0.01750000000000001 0.012 0 0.01750000000000001 0.012 0 0.01750000000000001 0.008485299999999999 -0.008485299999999999 0.01750000000000001 0.0123744 -0.0123744 0.01750000000000001 0.0123744 -0.0123744 0.01750000000000001 0 -0.012 0.01750000000000001 0 -0.0175 0.01750000000000001 0.0123744 0.0123744 0.01750000000000001 0 0.0175 0.01750000000000001 0.0175 0 0.01750000000000001 -0.0123744 -0.0123744 0.01625000000000001 -0.0061872 -0.0149372 0.01750000000000001 0 -0.0175 0.01750000000000001 -0.012 0 0.01750000000000001 -0.008485299999999999 0.008485299999999999 0.01750000000000001 -0.0175 0 0.01750000000000001 -0.008485299999999999 0.008485299999999999 0.01750000000000001 0 0.012 0.01750000000000001 -0.0123744 0.0123744 0.01750000000000001 0 0.012 0.01750000000000001 0 0.0175 0.01750000000000001 -0.0123744 0.0123744 0.01750000000000001 -0.008485299999999999 -0.008485299999999999 0.01750000000000001 -0.0175 0 0.01750000000000001 -0.0123744 -0.0123744 0.01750000000000001 0.0123744 0.0123744 0.01625000000000001 0.0061872 0.0149372 0.01750000000000001 0 0.0175 0.01750000000000001 0.008485299999999999 0.008485299999999999 0.01925000000000001 0.0102426 0.0042426 0.01750000000000001 0.012 0 0.01750000000000001 0.0175 0 0.01750000000000001 0 0.0175 0.01750000000000001 0.008485299999999999 0.008485299999999999 0.01750000000000001 0.012 0 0.01925000000000001 0.0102426 -0.0042426 0.01750000000000001 0.008485299999999999 -0.008485299999999999 0.01750000000000001 0.0123744 -0.0123744 0.01750000000000001 0.008485299999999999 -0.008485299999999999 0.01750000000000001 0 -0.012 0.01750000000000001 0 -0.012 0.01750000000000001 -0.008485299999999999 -0.008485299999999999 0.01750000000000001 0 -0.0175 0.01750000000000001 0 -0.0175 0.01750000000000001 -0.008485299999999999 -0.008485299999999999 0.01750000000000001 -0.0123744 -0.0123744 0.01750000000000001 -0.008485299999999999 -0.008485299999999999 0.01750000000000001 -0.012 0 0.01750000000000001 -0.0175 0 0.01750000000000001 -0.012 0 0.01925000000000001 -0.0102426 0.0042426 0.01750000000000001 -0.008485299999999999 0.008485299999999999 0.01750000000000001 -0.008485299999999999 0.008485299999999999 0.01925000000000001 -0.0042426 0.0102426 0.01750000000000001 0 0.012 0.01750000000000001 0.008485299999999999 0.008485299999999999 0.01750000000000001 0 0.0175 0.01750000000000001 0 0.012 0.01750000000000001 0.012 0 0.01925000000000001 0.0102426 0.0042426 0.02100000000000001 0.012 0 0.01750000000000001 0.008485299999999999 0.008485299999999999 0.02100000000000001 0.008485299999999999 0.008485299999999999 0.01925000000000001 0.0102426 0.0042426 0.01750000000000001 0.008485299999999999 -0.008485299999999999 0.01925000000000001 0.0102426 -0.0042426 0.02100000000000001 0.008485299999999999 -0.008485299999999999 0.01750000000000001 0.012 0 0.02100000000000001 0.012 0 0.01925000000000001 0.0102426 -0.0042426 0.01750000000000001 0.008485299999999999 -0.008485299999999999 0.01925000000000001 0.0042426 -0.0102426 0.01750000000000001 0 -0.012 0.01750000000000001 0 -0.012 0.01925000000000001 -0.0042426 -0.0102426 0.01750000000000001 -0.008485299999999999 -0.008485299999999999 0.01750000000000001 -0.008485299999999999 -0.008485299999999999 0.01925000000000001 -0.0102426 -0.0042426 0.01750000000000001 -0.012 0 0.01750000000000001 -0.008485299999999999 0.008485299999999999 0.01925000000000001 -0.0102426 0.0042426 0.02100000000000001 -0.008485299999999999 0.008485299999999999 0.01750000000000001 -0.012 0 0.02100000000000001 -0.012 0 0.01925000000000001 -0.0102426 0.0042426 0.02100000000000001 0 0.012 0.01750000000000001 0 0.012 0.01925000000000001 -0.0042426 0.0102426 0.02100000000000001 -0.008485299999999999 0.008485299999999999 0.01925000000000001 -0.0042426 0.0102426 0.01750000000000001 -0.008485299999999999 0.008485299999999999 0.01750000000000001 0 0.012 0.01925000000000001 0.0042426 0.0102426 0.01750000000000001 0.008485299999999999 0.008485299999999999 0.02100000000000001 0.012 0 0.01925000000000001 0.0102426 0.0042426 0.02100000000000001 0.008485299999999999 0.008485299999999999 0.02100000000000001 0.008485299999999999 0.008485299999999999 0.01750000000000001 0.008485299999999999 0.008485299999999999 0.01925000000000001 0.0042426 0.0102426 0.02100000000000001 0.008485299999999999 -0.008485299999999999 0.01925000000000001 0.0102426 -0.0042426 0.02100000000000001 0.012 0 0.02100000000000001 0.008485299999999999 -0.008485299999999999 0.01925000000000001 0.0042426 -0.0102426 0.01750000000000001 0.008485299999999999 -0.008485299999999999 0.02100000000000001 0 -0.012 0.01750000000000001 0 -0.012 0.01925000000000001 0.0042426 -0.0102426 0.02100000000000001 -0.008485299999999999 -0.008485299999999999 0.01750000000000001 -0.008485299999999999 -0.008485299999999999 0.01925000000000001 -0.0042426 -0.0102426 0.02100000000000001 0 -0.012 0.01925000000000001 -0.0042426 -0.0102426 0.01750000000000001 0 -0.012 0.01750000000000001 -0.012 0 0.01925000000000001 -0.0102426 -0.0042426 0.02100000000000001 -0.012 0 0.01750000000000001 -0.008485299999999999 -0.008485299999999999 0.02100000000000001 -0.008485299999999999 -0.008485299999999999 0.01925000000000001 -0.0102426 -0.0042426 0.02100000000000001 -0.008485299999999999 0.008485299999999999 0.01925000000000001 -0.0102426 0.0042426 0.02100000000000001 -0.012 0 0.02100000000000001 0 0.012 0.01925000000000001 -0.0042426 0.0102426 0.02100000000000001 -0.008485299999999999 0.008485299999999999 0.02100000000000001 0 0.012 0.01925000000000001 0.0042426 0.0102426 0.01750000000000001 0 0.012 0.02100000000000001 0.008485299999999999 0.008485299999999999 0.02100000000000001 0.0070711 0.0070711 0.02100000000000001 0.012 0 0.02100000000000001 0.008485299999999999 0.008485299999999999 0.01925000000000001 0.0042426 0.0102426 0.02100000000000001 0 0.012 0.02100000000000001 0.012 0 0.02100000000000001 0.01 0 0.02100000000000001 0.008485299999999999 -0.008485299999999999 0.02100000000000001 0 -0.012 0.01925000000000001 0.0042426 -0.0102426 0.02100000000000001 0.008485299999999999 -0.008485299999999999 0.02100000000000001 -0.008485299999999999 -0.008485299999999999 0.01925000000000001 -0.0042426 -0.0102426 0.02100000000000001 0 -0.012 0.02100000000000001 -0.012 0 0.01925000000000001 -0.0102426 -0.0042426 0.02100000000000001 -0.008485299999999999 -0.008485299999999999 0.02100000000000001 -0.0070711 0.0070711 0.02100000000000001 -0.008485299999999999 0.008485299999999999 0.02100000000000001 -0.012 0 0.02100000000000001 0 0.01 0.02100000000000001 0 0.012 0.02100000000000001 -0.008485299999999999 0.008485299999999999 0.02100000000000001 0.0070711 0.0070711 0.02100000000000001 0.008485299999999999 0.008485299999999999 0.02100000000000001 0 0.012 0.02100000000000001 0.012 0 0.02100000000000001 0.0070711 0.0070711 0.02100000000000001 0.01 0 0.02100000000000001 0.01 0 0.02100000000000001 0.0070711 -0.0070711 0.02100000000000001 0.008485299999999999 -0.008485299999999999 0.02100000000000001 0.008485299999999999 -0.008485299999999999 0.02100000000000001 0 -0.01 0.02100000000000001 0 -0.012 0.02100000000000001 0 -0.012 0.02100000000000001 -0.0070711 -0.0070711 0.02100000000000001 -0.008485299999999999 -0.008485299999999999 0.02100000000000001 -0.0070711 -0.0070711 0.02100000000000001 -0.012 0 0.02100000000000001 -0.008485299999999999 -0.008485299999999999 0.02100000000000001 -0.01 0 0.02100000000000001 -0.0070711 0.0070711 0.02100000000000001 -0.012 0 0.02100000000000001 0 0.01 0.02100000000000001 -0.008485299999999999 0.008485299999999999 0.02100000000000001 -0.0070711 0.0070711 0.02100000000000001 0.0070711 0.0070711 0.02100000000000001 0 0.012 0.02100000000000001 0 0.01 0.02300000000000001 0.00853552 0.00353554 0.02500000000000001 0.0085355 0.0035355 0.02100000000000001 0.01 0 0.02300000000000001 0.00853552 0.00353554 0.02100000000000001 0.01 0 0.02100000000000001 0.0070711 0.0070711 0.02300000000000001 0.00853552 0.00353554 0.02100000000000001 0.0070711 0.0070711 0.02500000000000001 0.0085355 0.0035355 0.02500000000000001 0.0085355 -0.0035355 0.02100000000000001 0.0070711 -0.0070711 0.02300000000000001 0.00853552 -0.00353554 0.02100000000000001 0.0070711 -0.0070711 0.02100000000000001 0.01 0 0.02300000000000001 0.00853552 -0.00353554 0.02100000000000001 0.01 0 0.02500000000000001 0.0085355 -0.0035355 0.02300000000000001 0.00853552 -0.00353554 0.02100000000000001 0.008485299999999999 -0.008485299999999999 0.02100000000000001 0.0070711 -0.0070711 0.02100000000000001 0 -0.01 0.02100000000000001 0 -0.012 0.02100000000000001 0 -0.01 0.02100000000000001 -0.0070711 -0.0070711 0.02100000000000001 -0.01 0 0.02100000000000001 -0.012 0 0.02100000000000001 -0.0070711 -0.0070711 0.02500000000000001 -0.0085355 0.0035355 0.02100000000000001 -0.0070711 0.0070711 0.02300000000000001 -0.00853552 0.00353554 0.02100000000000001 -0.0070711 0.0070711 0.02100000000000001 -0.01 0 0.02300000000000001 -0.00853552 0.00353554 0.02100000000000001 -0.01 0 0.02500000000000001 -0.0085355 0.0035355 0.02300000000000001 -0.00853552 0.00353554 0.02500000000000001 -0.0035355 0.0085355 0.02100000000000001 0 0.01 0.02300000000000001 -0.00353554 0.00853552 0.02100000000000001 0 0.01 0.02100000000000001 -0.0070711 0.0070711 0.02300000000000001 -0.00353554 0.00853552 0.02100000000000001 -0.0070711 0.0070711 0.02500000000000001 -0.0035355 0.0085355 0.02300000000000001 -0.00353554 0.00853552 0.02500000000000001 0.0035355 0.0085355 0.02100000000000001 0.0070711 0.0070711 0.02300000000000001 0.00353554 0.00853552 0.02100000000000001 0.0070711 0.0070711 0.02100000000000001 0 0.01 0.02300000000000001 0.00353554 0.00853552 0.02100000000000001 0 0.01 0.02500000000000001 0.0035355 0.0085355 0.02300000000000001 0.00353554 0.00853552 0.02500000000000001 0.0085355 0.0035355 0.02900000000000001 0.01 0 0.02500000000000001 0.00926775 0.00176775 0.02900000000000001 0.01 0 0.02100000000000001 0.01 0 0.02500000000000001 0.00926775 0.00176775 0.02100000000000001 0.01 0 0.02500000000000001 0.0085355 0.0035355 0.02500000000000001 0.00926775 0.00176775 0.02500000000000001 0.0085355 0.0035355 0.02100000000000001 0.0070711 0.0070711 0.02500000000000001 0.0078033 0.0053033 0.02100000000000001 0.0070711 0.0070711 0.02900000000000001 0.0070711 0.0070711 0.02500000000000001 0.0078033 0.0053033 0.02900000000000001 0.0070711 0.0070711 0.02500000000000001 0.0085355 0.0035355 0.02500000000000001 0.0078033 0.0053033 0.02500000000000001 0.0085355 -0.0035355 0.02900000000000001 0.0070711 -0.0070711 0.02500000000000001 0.0078033 -0.0053033 0.02900000000000001 0.0070711 -0.0070711 0.02100000000000001 0.0070711 -0.0070711 0.02500000000000001 0.0078033 -0.0053033 0.02100000000000001 0.0070711 -0.0070711 0.02500000000000001 0.0085355 -0.0035355 0.02500000000000001 0.0078033 -0.0053033 0.02500000000000001 0.0085355 -0.0035355 0.02100000000000001 0.01 0 0.02500000000000001 0.00926775 -0.00176775 0.02100000000000001 0.01 0 0.02900000000000001 0.01 0 0.02500000000000001 0.00926775 -0.00176775 0.02900000000000001 0.01 0 0.02500000000000001 0.0085355 -0.0035355 0.02500000000000001 0.00926775 -0.00176775 0.02500000000000001 0.0035355 -0.0085355 0.02100000000000001 0 -0.01 0.02300000000000001 0.00353554 -0.00853552 0.02100000000000001 0 -0.01 0.02100000000000001 0.0070711 -0.0070711 0.02300000000000001 0.00353554 -0.00853552 0.02100000000000001 0.0070711 -0.0070711 0.02500000000000001 0.0035355 -0.0085355 0.02300000000000001 0.00353554 -0.00853552 0.02500000000000001 -0.0035355 -0.0085355 0.02100000000000001 -0.0070711 -0.0070711 0.02300000000000001 -0.00353554 -0.00853552 0.02100000000000001 -0.0070711 -0.0070711 0.02100000000000001 0 -0.01 0.02300000000000001 -0.00353554 -0.00853552 0.02100000000000001 0 -0.01 0.02500000000000001 -0.0035355 -0.0085355 0.02300000000000001 -0.00353554 -0.00853552 0.02300000000000001 -0.00853552 -0.00353554 0.02500000000000001 -0.0085355 -0.0035355 0.02100000000000001 -0.01 0 0.02300000000000001 -0.00853552 -0.00353554 0.02100000000000001 -0.01 0 0.02100000000000001 -0.0070711 -0.0070711 0.02300000000000001 -0.00853552 -0.00353554 0.02100000000000001 -0.0070711 -0.0070711 0.02500000000000001 -0.0085355 -0.0035355 0.02500000000000001 -0.0085355 0.0035355 0.02900000000000001 -0.0070711 0.0070711 0.02500000000000001 -0.0078033 0.0053033 0.02900000000000001 -0.0070711 0.0070711 0.02100000000000001 -0.0070711 0.0070711 0.02500000000000001 -0.0078033 0.0053033 0.02100000000000001 -0.0070711 0.0070711 0.02500000000000001 -0.0085355 0.0035355 0.02500000000000001 -0.0078033 0.0053033 0.02500000000000001 -0.0085355 0.0035355 0.02100000000000001 -0.01 0 0.02500000000000001 -0.00926775 0.00176775 0.02100000000000001 -0.01 0 0.02900000000000001 -0.01 0 0.02500000000000001 -0.00926775 0.00176775 0.02900000000000001 -0.01 0 0.02500000000000001 -0.0085355 0.0035355 0.02500000000000001 -0.00926775 0.00176775 0.02500000000000001 -0.0035355 0.0085355 0.02900000000000001 0 0.01 0.02500000000000001 -0.00176775 0.00926775 0.02900000000000001 0 0.01 0.02100000000000001 0 0.01 0.02500000000000001 -0.00176775 0.00926775 0.02100000000000001 0 0.01 0.02500000000000001 -0.0035355 0.0085355 0.02500000000000001 -0.00176775 0.00926775 0.02500000000000001 -0.0035355 0.0085355 0.02100000000000001 -0.0070711 0.0070711 0.02500000000000001 -0.0053033 0.0078033 0.02100000000000001 -0.0070711 0.0070711 0.02900000000000001 -0.0070711 0.0070711 0.02500000000000001 -0.0053033 0.0078033 0.02900000000000001 -0.0070711 0.0070711 0.02500000000000001 -0.0035355 0.0085355 0.02500000000000001 -0.0053033 0.0078033 0.02500000000000001 0.0035355 0.0085355 0.02900000000000001 0.0070711 0.0070711 0.02500000000000001 0.0053033 0.0078033 0.02900000000000001 0.0070711 0.0070711 0.02100000000000001 0.0070711 0.0070711 0.02500000000000001 0.0053033 0.0078033 0.02100000000000001 0.0070711 0.0070711 0.02500000000000001 0.0035355 0.0085355 0.02500000000000001 0.0053033 0.0078033 0.02500000000000001 0.0035355 0.0085355 0.02100000000000001 0 0.01 0.02500000000000001 0.00176775 0.00926775 0.02100000000000001 0 0.01 0.02900000000000001 0 0.01 0.02500000000000001 0.00176775 0.00926775 0.02900000000000001 0 0.01 0.02500000000000001 0.0035355 0.0085355 0.02500000000000001 0.00176775 0.00926775 0.02500000000000001 0.0085355 0.0035355 0.02900000000000001 0.0070711 0.0070711 0.02700000000000001 0.00853552 0.00353554 0.02900000000000001 0.0070711 0.0070711 0.02900000000000001 0.01 0 0.02700000000000001 0.00853552 0.00353554 0.02900000000000001 0.01 0 0.02500000000000001 0.0085355 0.0035355 0.02700000000000001 0.00853552 0.00353554 0.02500000000000001 0.0085355 -0.0035355 0.02900000000000001 0.01 0 0.02700000000000001 0.00853552 -0.00353554 0.02900000000000001 0.01 0 0.02900000000000001 0.0070711 -0.0070711 0.02700000000000001 0.00853552 -0.00353554 0.02900000000000001 0.0070711 -0.0070711 0.02500000000000001 0.0085355 -0.0035355 0.02700000000000001 0.00853552 -0.00353554 0.02500000000000001 0.0035355 -0.0085355 0.02100000000000001 0.0070711 -0.0070711 0.02500000000000001 0.0053033 -0.0078033 0.02100000000000001 0.0070711 -0.0070711 0.02900000000000001 0.0070711 -0.0070711 0.02500000000000001 0.0053033 -0.0078033 0.02900000000000001 0.0070711 -0.0070711 0.02500000000000001 0.0035355 -0.0085355 0.02500000000000001 0.0053033 -0.0078033 0.02500000000000001 0.0035355 -0.0085355 0.02900000000000001 0 -0.01 0.02500000000000001 0.00176775 -0.00926775 0.02900000000000001 0 -0.01 0.02100000000000001 0 -0.01 0.02500000000000001 0.00176775 -0.00926775 0.02100000000000001 0 -0.01 0.02500000000000001 0.0035355 -0.0085355 0.02500000000000001 0.00176775 -0.00926775 0.02500000000000001 -0.0035355 -0.0085355 0.02900000000000001 -0.0070711 -0.0070711 0.02500000000000001 -0.0053033 -0.0078033 0.02900000000000001 -0.0070711 -0.0070711 0.02100000000000001 -0.0070711 -0.0070711 0.02500000000000001 -0.0053033 -0.0078033 0.02100000000000001 -0.0070711 -0.0070711 0.02500000000000001 -0.0035355 -0.0085355 0.02500000000000001 -0.0053033 -0.0078033 0.02500000000000001 -0.0035355 -0.0085355 0.02100000000000001 0 -0.01 0.02500000000000001 -0.00176775 -0.00926775 0.02100000000000001 0 -0.01 0.02900000000000001 0 -0.01 0.02500000000000001 -0.00176775 -0.00926775 0.02900000000000001 0 -0.01 0.02500000000000001 -0.0035355 -0.0085355 0.02500000000000001 -0.00176775 -0.00926775 0.02500000000000001 -0.0085355 -0.0035355 0.02900000000000001 -0.01 0 0.02500000000000001 -0.00926775 -0.00176775 0.02900000000000001 -0.01 0 0.02100000000000001 -0.01 0 0.02500000000000001 -0.00926775 -0.00176775 0.02100000000000001 -0.01 0 0.02500000000000001 -0.0085355 -0.0035355 0.02500000000000001 -0.00926775 -0.00176775 0.02500000000000001 -0.0085355 -0.0035355 0.02100000000000001 -0.0070711 -0.0070711 0.02500000000000001 -0.0078033 -0.0053033 0.02100000000000001 -0.0070711 -0.0070711 0.02900000000000001 -0.0070711 -0.0070711 0.02500000000000001 -0.0078033 -0.0053033 0.02900000000000001 -0.0070711 -0.0070711 0.02500000000000001 -0.0085355 -0.0035355 0.02500000000000001 -0.0078033 -0.0053033 0.02500000000000001 -0.0085355 0.0035355 0.02900000000000001 -0.01 0 0.02700000000000001 -0.00853552 0.00353554 0.02900000000000001 -0.01 0 0.02900000000000001 -0.0070711 0.0070711 0.02700000000000001 -0.00853552 0.00353554 0.02900000000000001 -0.0070711 0.0070711 0.02500000000000001 -0.0085355 0.0035355 0.02700000000000001 -0.00853552 0.00353554 0.02500000000000001 -0.0035355 0.0085355 0.02900000000000001 -0.0070711 0.0070711 0.02700000000000001 -0.00353554 0.00853552 0.02900000000000001 -0.0070711 0.0070711 0.02900000000000001 0 0.01 0.02700000000000001 -0.00353554 0.00853552 0.02900000000000001 0 0.01 0.02500000000000001 -0.0035355 0.0085355 0.02700000000000001 -0.00353554 0.00853552 0.02500000000000001 0.0035355 0.0085355 0.02900000000000001 0 0.01 0.02700000000000001 0.00353554 0.00853552 0.02900000000000001 0 0.01 0.02900000000000001 0.0070711 0.0070711 0.02700000000000001 0.00353554 0.00853552 0.02900000000000001 0.0070711 0.0070711 0.02500000000000001 0.0035355 0.0085355 0.02700000000000001 0.00353554 0.00853552 0.02900000000000001 0.01 0 0.02900000000000001 0.0070711 0.0070711 0.02900000000000001 0 0 0.02900000000000001 0.01 0 0.02900000000000001 0 0 0.02900000000000001 0.0070711 -0.0070711 0.02500000000000001 0.0035355 -0.0085355 0.02900000000000001 0.0070711 -0.0070711 0.02700000000000001 0.00353554 -0.00853552 0.02900000000000001 0.0070711 -0.0070711 0.02900000000000001 0 -0.01 0.02700000000000001 0.00353554 -0.00853552 0.02900000000000001 0 -0.01 0.02500000000000001 0.0035355 -0.0085355 0.02700000000000001 0.00353554 -0.00853552 0.02500000000000001 -0.0035355 -0.0085355 0.02900000000000001 0 -0.01 0.02700000000000001 -0.00353554 -0.00853552 0.02900000000000001 0 -0.01 0.02900000000000001 -0.0070711 -0.0070711 0.02700000000000001 -0.00353554 -0.00853552 0.02900000000000001 -0.0070711 -0.0070711 0.02500000000000001 -0.0035355 -0.0085355 0.02700000000000001 -0.00353554 -0.00853552 0.02500000000000001 -0.0085355 -0.0035355 0.02900000000000001 -0.0070711 -0.0070711 0.02700000000000001 -0.00853552 -0.00353554 0.02900000000000001 -0.0070711 -0.0070711 0.02900000000000001 -0.01 0 0.02700000000000001 -0.00853552 -0.00353554 0.02900000000000001 -0.01 0 0.02500000000000001 -0.0085355 -0.0035355 0.02700000000000001 -0.00853552 -0.00353554 0.02900000000000001 0 0 0.02900000000000001 -0.0070711 0.0070711 0.02900000000000001 -0.01 0 0.02900000000000001 0 0.01 0.02900000000000001 -0.0070711 0.0070711 0.02900000000000001 0 0 0.02900000000000001 0.0070711 0.0070711 0.02900000000000001 0 0.01 0.02900000000000001 0 0 0.02900000000000001 0.0070711 -0.0070711 0.02900000000000001 0 0 0.02900000000000001 0 -0.01 0.02900000000000001 0 -0.01 0.02900000000000001 0 0 0.02900000000000001 -0.0070711 -0.0070711 0.02900000000000001 0 0 0.02900000000000001 -0.01 0 0.02900000000000001 -0.0070711 -0.0070711 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827

    -
    -
    - - - 6.938893903907228e-18 0 0 - 1 0 0 0 - - true - - - -
    - - - - 0.001999999999999997 0 -0.0153 0.001999999999999997 -0.00835 -0.0148 0.001999999999999997 -0.00835 -0.0158 0.001999999999999997 -0.00835 -0.0148 0.001999999999999997 0 -0.0153 0.001999999999999997 0.00835 -0.0148 0.001999999999999997 -0.00835 -0.0148 -0.006000000000000004 -0.009075 -0.0153 0.001999999999999997 -0.00835 -0.0158 0.001999999999999997 0.00835 -0.0158 0.001999999999999997 0 -0.0153 0.001999999999999997 -0.00835 -0.0158 0.001999999999999997 0.00835 -0.0158 0.001999999999999997 0.00835 -0.0148 0.001999999999999997 0 -0.0153 -0.006000000000000004 0 -0.0148 0.001999999999999997 -0.00835 -0.0148 -0.002000000000000004 0 -0.0148 0.001999999999999997 -0.00835 -0.0148 0.001999999999999997 0.00835 -0.0148 -0.002000000000000004 0 -0.0148 0.001999999999999997 0.00835 -0.0148 -0.006000000000000004 0 -0.0148 -0.002000000000000004 0 -0.0148 -0.006000000000000004 -0.009075 -0.0153 -0.014 -0.0098 -0.0158 0.001999999999999997 -0.00835 -0.0158 -0.014 -0.0098 -0.0148 -0.006000000000000004 -0.009075 -0.0153 0.001999999999999997 -0.00835 -0.0148 -0.009000000000000003 0 -0.0158 0.001999999999999997 0.00835 -0.0158 -0.003500000000000004 -2.60209e-17 -0.0158 0.001999999999999997 0.00835 -0.0158 0.001999999999999997 -0.00835 -0.0158 -0.003500000000000004 -2.60209e-17 -0.0158 0.001999999999999997 -0.00835 -0.0158 -0.009000000000000003 0 -0.0158 -0.003500000000000004 -2.60209e-17 -0.0158 0.001999999999999997 0.00835 -0.0148 0.001999999999999997 0.00835 -0.0158 -0.006000000000000004 0.009075 -0.0153 -0.006000000000000004 0 -0.0148 -0.014 -0.0098 -0.0148 -0.006000000000000004 -0.0049 -0.0148 -0.014 -0.0098 -0.0148 0.001999999999999997 -0.00835 -0.0148 -0.006000000000000004 -0.0049 -0.0148 0.001999999999999997 -0.00835 -0.0148 -0.006000000000000004 0 -0.0148 -0.006000000000000004 -0.0049 -0.0148 -0.006000000000000004 0 -0.0148 0.001999999999999997 0.00835 -0.0148 -0.006000000000000004 0.0049 -0.0148 0.001999999999999997 0.00835 -0.0148 -0.014 0.0098 -0.0148 -0.006000000000000004 0.0049 -0.0148 -0.014 0.0098 -0.0148 -0.006000000000000004 0 -0.0148 -0.006000000000000004 0.0049 -0.0148 -0.014 -0.0098 -0.0148 -0.014 -0.0098 -0.0158 -0.006000000000000004 -0.009075 -0.0153 -0.014 -0.0098 -0.0158 -0.009000000000000003 0 -0.0158 0.001999999999999997 -0.00835 -0.0158 -0.009000000000000003 0 -0.0158 -0.014 0.0098 -0.0158 0.001999999999999997 0.00835 -0.0158 0.001999999999999997 0.00835 -0.0148 -0.006000000000000004 0.009075 -0.0153 -0.014 0.0098 -0.0148 -0.006000000000000004 0.009075 -0.0153 0.001999999999999997 0.00835 -0.0158 -0.014 0.0098 -0.0158 -0.006000000000000004 0 -0.0148 -0.014 0.0098 -0.0148 -0.01 6.93889e-18 -0.0148 -0.014 0.0098 -0.0148 -0.014 -0.0098 -0.0148 -0.01 6.93889e-18 -0.0148 -0.014 -0.0098 -0.0148 -0.006000000000000004 0 -0.0148 -0.01 6.93889e-18 -0.0148 -0.014 -0.0098 -0.0148 -0.0143333 -0.0098 0 -0.014 -0.0098 -0.0158 -0.014 -0.0098 -0.0158 -0.015 -0.0098 -0.0158 -0.009000000000000003 0 -0.0158 -0.009000000000000003 0 -0.0158 -0.015 0.0098 -0.0158 -0.014 0.0098 -0.0158 -0.014 0.0098 -0.0148 -0.006000000000000004 0.009075 -0.0153 -0.014 0.0098 -0.0158 -0.014 0 0 -0.014 -0.0098 -0.0148 -0.014 0 -0.0074 -0.014 -0.0098 -0.0148 -0.014 0.0098 -0.0148 -0.014 0 -0.0074 -0.014 0.0098 -0.0148 -0.014 0 0 -0.014 0 -0.0074 -0.015 -0.0098 -0.0158 -0.014 -0.0098 -0.0158 -0.0143333 -0.0098 0 -0.014 -0.0098 0.0148 -0.0143333 -0.0098 0 -0.014 -0.0098 -0.0148 -0.009000000000000003 0 -0.0158 -0.015 -0.0098 -0.0158 -0.012 -6.93889e-18 -0.0158 -0.015 -0.0098 -0.0158 -0.015 0.0098 -0.0158 -0.012 -6.93889e-18 -0.0158 -0.015 0.0098 -0.0158 -0.009000000000000003 0 -0.0158 -0.012 -6.93889e-18 -0.0158 -0.015 0.0098 -0.0158 -0.0143333 0.0098 0 -0.014 0.0098 -0.0158 -0.014 0.0098 -0.0158 -0.0143333 0.0098 0 -0.014 0.0098 -0.0148 -0.014 0 0 -0.014 -0.0098 0.0148 -0.014 -0.0049 -1.30104e-17 -0.014 -0.0098 0.0148 -0.014 -0.0098 -0.0148 -0.014 -0.0049 -1.30104e-17 -0.014 -0.0098 -0.0148 -0.014 0 0 -0.014 -0.0049 -1.30104e-17 -0.014 0 0 -0.014 0.0098 -0.0148 -0.014 0.0049 0 -0.014 0.0098 -0.0148 -0.014 0.0098 0.0148 -0.014 0.0049 0 -0.014 0.0098 0.0148 -0.014 0 0 -0.014 0.0049 0 -0.015 -0.0098 -0.0125 -0.015 -0.0098 -0.0158 -0.0149 -0.0098 -0.0125 -0.015 -0.0098 0.0158 -0.015 -0.0098 0.0125 -0.0149 -0.0098 0.0125 -0.0143333 -0.0098 0 -0.0149 -0.0098 0.0125 -0.0149 -0.0098 -0.0125 -0.015 -0.0098 -0.0158 -0.0143333 -0.0098 0 -0.0149 -0.0098 -0.0125 -0.015 -0.0098 0.0158 -0.0149 -0.0098 0.0125 -0.0143333 -0.0098 0 -0.014 -0.0098 0.0158 -0.0143333 -0.0098 0 -0.014 -0.0098 0.0148 -0.015 0.00775316 -0.0125 -0.015 0.0098 -0.0158 -0.015 1.73472e-18 -0.01415 -0.015 0.0098 -0.0158 -0.015 -0.0098 -0.0158 -0.015 1.73472e-18 -0.01415 -0.015 -0.0098 -0.0158 -0.015 -0.00775316 -0.0125 -0.015 1.73472e-18 -0.01415 -0.015 -0.00775316 -0.0125 -0.015 0.00775316 -0.0125 -0.015 1.73472e-18 -0.01415 -0.015 0.0098 0.0125 -0.015 0.0098 0.0158 -0.0149 0.0098 0.0125 -0.0149 0.0098 0.0110577 -0.0143333 0.0098 0 -0.0149 0.0098 -0.0110577 -0.015 0.0098 -0.0125 -0.0149 0.0098 -0.0125 -0.015 0.0098 -0.0158 -0.0143333 0.0098 0 -0.0149 0.0098 0.0110577 -0.0149 0.0098 0.0125 -0.015 0.0098 0.0158 -0.0143333 0.0098 0 -0.0149 0.0098 0.0125 -0.0149 0.0098 -0.0125 -0.0143333 0.0098 0 -0.015 0.0098 -0.0158 -0.0149 0.0098 -0.0110577 -0.0143333 0.0098 0 -0.0149 0.0098 -0.0125 -0.014 0.0098 -0.0148 -0.0143333 0.0098 0 -0.014 0.0098 0.0148 -0.014 0 0 -0.014 0.0098 0.0148 -0.014 6.93889e-18 0.0074 -0.014 0.0098 0.0148 -0.014 -0.0098 0.0148 -0.014 6.93889e-18 0.0074 -0.014 -0.0098 0.0148 -0.014 0 0 -0.014 6.93889e-18 0.0074 -0.015 -0.0098 0.0158 -0.0143333 -0.0098 0 -0.014 -0.0098 0.0158 -0.015 -0.00976894 0.0125 -0.015 -0.0098 0.0125 -0.015 -0.0098 0.0158 -0.015 -0.00775316 0.0125 -0.015 -0.0097419 0.0125 -0.015 -0.0098 0.0158 -0.015 -0.0098 0.0158 -0.015 -0.009752500000000001 0.0125 -0.015 -0.0097419 0.0125 -0.015 -0.0098 0.0158 -0.015 -0.00975934 0.0125 -0.015 -0.009752500000000001 0.0125 -0.015 -0.0098 0.0158 -0.015 -0.00976894 0.0125 -0.015 -0.00975934 0.0125 -0.0149 -0.0098 0.0125 -0.015 -0.0098 0.0124302 -0.015 -0.0098 0.0125 -0.015 -0.0098 0.0124302 -0.015 -0.0098 -0.0124302 -0.0149 -0.0098 0.0125 -0.015 -0.0098 -0.0124302 -0.0149 -0.0098 -0.0125 -0.0149 -0.0098 0.0125 -0.0149 -0.0098 -0.0125 -0.015 -0.0098 -0.0125 -0.015 -0.0098 -0.0124302 -0.015 -0.00775316 -0.0125 -0.015 -0.0098 -0.0158 -0.015 -0.0097419 -0.0125 -0.015 -0.00975208 -0.0125 -0.015 -0.0098 -0.0158 -0.015 -0.0097419 -0.0125 -0.015 -0.009759169999999999 -0.0125 -0.015 -0.0098 -0.0158 -0.015 -0.00975208 -0.0125 -0.015 -0.009769140000000001 -0.0125 -0.015 -0.0098 -0.0158 -0.015 -0.009759169999999999 -0.0125 -0.015 -0.009769140000000001 -0.0125 -0.015 -0.0098 -0.0158 -0.015 -0.0098 -0.0125 -0.014 -0.0098 0.0158 -0.014 -0.0098 0.0148 -0.006000000000000004 -0.009075 0.0153 -0.015 0.0098 -0.0125 -0.015 0.0098 -0.0158 -0.015 0.00775316 -0.0125 -0.015 -0.0097419 -0.0125 -0.05070000000000001 0.011 -0.0125 -0.015 -0.00775316 -0.0125 -0.015 -0.00775316 -0.0125 -0.05070000000000001 0.011 -0.0125 -0.015 0.00775316 -0.0125 -0.015 0.00775316 -0.0125 -0.05070000000000001 0.011 -0.0125 -0.015 0.0098 -0.0125 -0.0149 0.0098 -0.0125 -0.015 0.0098 -0.0125 -0.0149 0.011 -0.0125 -0.015 0.0098 -0.0125 -0.05070000000000001 0.011 -0.0125 -0.0149 0.011 -0.0125 -0.0149 0.0098 0.0110577 -0.0149 0.0098 -0.0110577 -0.0149 0.0104 7.806259999999999e-18 -0.0149 0.0098 -0.0110577 -0.0149 0.011 -0.0125 -0.0149 0.0104 7.806259999999999e-18 -0.0149 0.011 -0.0125 -0.0149 0.011 0.0125 -0.0149 0.0104 7.806259999999999e-18 -0.0149 0.011 0.0125 -0.0149 0.0098 0.0110577 -0.0149 0.0104 7.806259999999999e-18 -0.0149 0.011 0.0125 -0.0149 0.0098 0.0125 -0.0149 0.0098 0.0110577 -0.015 0.0098 0.0125 -0.0149 0.0098 0.0125 -0.0149 0.011 0.0125 -0.015 0.00775316 0.0125 -0.015 0.0098 0.0125 -0.05070000000000001 0.011 0.0125 -0.015 -0.0097419 0.0125 -0.015 -0.00775316 0.0125 -0.05070000000000001 0.011 0.0125 -0.015 -0.00775316 0.0125 -0.015 0.00775316 0.0125 -0.05070000000000001 0.011 0.0125 -0.015 0.0098 0.0125 -0.0149 0.011 0.0125 -0.05070000000000001 0.011 0.0125 -0.015 0.0098 0.0125 -0.015 0.00775316 0.0125 -0.015 0.0098 0.0158 -0.015 0.0098 0.0158 -0.014 0.0098 0.0158 -0.0143333 0.0098 0 -0.0149 0.011 -0.0125 -0.0149 0.0098 -0.0110577 -0.0149 0.0098 -0.0125 -0.014 0.0098 0.0148 -0.0143333 0.0098 0 -0.014 0.0098 0.0158 -0.006000000000000004 0 0.0148 -0.014 -0.0098 0.0148 -0.01 -4.33681e-18 0.0148 -0.014 -0.0098 0.0148 -0.014 0.0098 0.0148 -0.01 -4.33681e-18 0.0148 -0.014 0.0098 0.0148 -0.006000000000000004 0 0.0148 -0.01 -4.33681e-18 0.0148 -0.015 -0.0098 0.0158 -0.014 -0.0098 0.0158 -0.009000000000000003 0 0.0158 -0.015 -0.0098 0.0125 -0.015 -0.00976894 0.0125 -0.03285 -0.0059253 0.0125 -0.015 -0.00976894 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.03285 -0.0059253 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.05070000000000001 -0.0098 0.0125 -0.03285 -0.0059253 0.0125 -0.05070000000000001 -0.0098 0.0125 -0.015 -0.0098 0.0125 -0.03285 -0.0059253 0.0125 -0.015 -0.00775316 0.0125 -0.015 -0.0098 0.0158 -0.015 -8.673619999999999e-18 0.01415 -0.015 -0.0098 0.0158 -0.015 0.0098 0.0158 -0.015 -8.673619999999999e-18 0.01415 -0.015 0.0098 0.0158 -0.015 0.00775316 0.0125 -0.015 -8.673619999999999e-18 0.01415 -0.015 0.00775316 0.0125 -0.015 -0.00775316 0.0125 -0.015 -8.673619999999999e-18 0.01415 -0.015 -0.009752500000000001 0.0125 -0.015 -0.0097419 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.015 -0.0097419 0.0125 -0.05070000000000001 0.011 0.0125 -0.015 -0.00975934 0.0125 -0.015 -0.009752500000000001 0.0125 -0.03900000000000001 0 0.0125 -0.03900000000000001 0 0.0125 -0.015 -0.009752500000000001 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.015 -0.00976894 0.0125 -0.015 -0.00975934 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.015 -0.00975934 0.0125 -0.03900000000000001 0 0.0125 -0.015 -0.0098 0.0124302 -0.015 -0.0098 0.0125 -0.03285 -0.0098 0.00625 -0.015 -0.0098 0.0125 -0.05070000000000001 -0.0098 0.0125 -0.03285 -0.0098 0.00625 -0.05070000000000001 -0.0098 0.0125 -0.03280000000000001 -0.0098 0 -0.03285 -0.0098 0.00625 -0.03280000000000001 -0.0098 0 -0.015 -0.0098 0.0124302 -0.03285 -0.0098 0.00625 -0.015 -0.0098 -0.0124302 -0.015 -0.0098 0.0124302 -0.0239 -0.0098 0 -0.015 -0.0098 0.0124302 -0.03280000000000001 -0.0098 0 -0.0239 -0.0098 0 -0.03280000000000001 -0.0098 0 -0.015 -0.0098 -0.0124302 -0.0239 -0.0098 0 -0.03280000000000001 -0.0098 0 -0.05070000000000001 -0.0098 -0.0125 -0.03285 -0.0098 -0.00625 -0.05070000000000001 -0.0098 -0.0125 -0.015 -0.0098 -0.0125 -0.03285 -0.0098 -0.00625 -0.015 -0.0098 -0.0125 -0.015 -0.0098 -0.0124302 -0.03285 -0.0098 -0.00625 -0.015 -0.0098 -0.0124302 -0.03280000000000001 -0.0098 0 -0.03285 -0.0098 -0.00625 -0.015 -0.009769140000000001 -0.0125 -0.015 -0.0098 -0.0125 -0.03285 -0.00596065 -0.0125 -0.015 -0.0098 -0.0125 -0.05070000000000001 -0.0098 -0.0125 -0.03285 -0.00596065 -0.0125 -0.05070000000000001 -0.0098 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.03285 -0.00596065 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.015 -0.009769140000000001 -0.0125 -0.03285 -0.00596065 -0.0125 -0.015 -0.009769140000000001 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.015 -0.009759169999999999 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.0389 0 -0.0125 -0.015 -0.009759169999999999 -0.0125 -0.015 -0.009759169999999999 -0.0125 -0.0389 0 -0.0125 -0.015 -0.00975208 -0.0125 -0.0389 0 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.015 -0.00975208 -0.0125 -0.015 -0.00975208 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.015 -0.0097419 -0.0125 -0.015 -0.0097419 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.05070000000000001 0.011 -0.0125 -0.014 -0.0098 0.0158 -0.006000000000000004 -0.009075 0.0153 0.001999999999999997 -0.00835 0.0158 -0.006000000000000004 -0.009075 0.0153 -0.014 -0.0098 0.0148 0.001999999999999997 -0.00835 0.0148 -0.03280000000000001 0.011 0 -0.0149 0.011 -0.0125 -0.03280000000000001 0.011 -0.00625 -0.0149 0.011 -0.0125 -0.05070000000000001 0.011 -0.0125 -0.03280000000000001 0.011 -0.00625 -0.05070000000000001 0.011 -0.0125 -0.03280000000000001 0.011 0 -0.03280000000000001 0.011 -0.00625 -0.03280000000000001 0.011 0 -0.0149 0.011 0.0125 -0.02385 0.011 1.99493e-17 -0.0149 0.011 0.0125 -0.0149 0.011 -0.0125 -0.02385 0.011 1.99493e-17 -0.0149 0.011 -0.0125 -0.03280000000000001 0.011 0 -0.02385 0.011 1.99493e-17 -0.03280000000000001 0.011 0 -0.05070000000000001 0.011 0.0125 -0.03280000000000001 0.011 0.00625 -0.05070000000000001 0.011 0.0125 -0.0149 0.011 0.0125 -0.03280000000000001 0.011 0.00625 -0.0149 0.011 0.0125 -0.03280000000000001 0.011 0 -0.03280000000000001 0.011 0.00625 -0.009000000000000003 0 0.0158 -0.014 0.0098 0.0158 -0.015 0.0098 0.0158 -0.014 0.0098 0.0158 -0.006000000000000004 0.009075 0.0153 -0.014 0.0098 0.0148 -0.006000000000000004 0 0.0148 0.001999999999999997 -0.00835 0.0148 -0.006000000000000004 -0.0049 0.0148 0.001999999999999997 -0.00835 0.0148 -0.014 -0.0098 0.0148 -0.006000000000000004 -0.0049 0.0148 -0.014 -0.0098 0.0148 -0.006000000000000004 0 0.0148 -0.006000000000000004 -0.0049 0.0148 -0.006000000000000004 0 0.0148 -0.014 0.0098 0.0148 -0.006000000000000004 0.0049 0.0148 -0.014 0.0098 0.0148 0.001999999999999997 0.00835 0.0148 -0.006000000000000004 0.0049 0.0148 0.001999999999999997 0.00835 0.0148 -0.006000000000000004 0 0.0148 -0.006000000000000004 0.0049 0.0148 -0.009000000000000003 0 0.0158 -0.015 0.0098 0.0158 -0.012 0 0.0158 -0.015 0.0098 0.0158 -0.015 -0.0098 0.0158 -0.012 0 0.0158 -0.015 -0.0098 0.0158 -0.009000000000000003 0 0.0158 -0.012 0 0.0158 -0.014 -0.0098 0.0158 0.001999999999999997 -0.00835 0.0158 -0.009000000000000003 0 0.0158 -0.05070000000000001 -0.0098 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.04190000000000001 -0.0029 0.0125 -0.04190000000000001 0.0029 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.05070000000000001 0.011 0.0125 -0.039425 0.0010253 0.01415 -0.03900000000000001 0 0.0125 -0.03942470000000001 0.00102521 0.013325 -0.03900000000000001 0 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.03942470000000001 0.00102521 0.013325 -0.03984900000000001 0.0020506 0.0125 -0.039425 0.0010253 0.01415 -0.03942470000000001 0.00102521 0.013325 -0.03942470000000001 -0.00102521 0.013325 -0.039425 -0.0010253 0.01415 -0.03984900000000001 -0.0020506 0.0125 -0.03942470000000001 -0.00102521 0.013325 -0.03984900000000001 -0.0020506 0.0125 -0.03900000000000001 0 0.0125 -0.03942470000000001 -0.00102521 0.013325 -0.03900000000000001 0 0.0125 -0.039425 -0.0010253 0.01415 -0.03280000000000001 -0.0098 0 -0.05070000000000001 -0.0098 0.0125 -0.04175000000000001 -0.0098 1.47451e-17 -0.05070000000000001 -0.0098 0.0125 -0.05070000000000001 -0.0098 -0.0125 -0.04175000000000001 -0.0098 1.47451e-17 -0.05070000000000001 -0.0098 -0.0125 -0.03280000000000001 -0.0098 0 -0.04175000000000001 -0.0098 1.47451e-17 -0.04190000000000001 -0.003 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.05070000000000001 -0.0098 -0.0125 -0.039339 -0.0010607 -0.01415 -0.0389 0 -0.0125 -0.03933930000000001 -0.00106074 -0.013325 -0.0389 0 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.03933930000000001 -0.00106074 -0.013325 -0.03977900000000001 -0.0021213 -0.0125 -0.039339 -0.0010607 -0.01415 -0.03933930000000001 -0.00106074 -0.013325 -0.039339 0.0010607 -0.01415 -0.03977900000000001 0.0021213 -0.0125 -0.03933930000000001 0.00106074 -0.013325 -0.03977900000000001 0.0021213 -0.0125 -0.0389 0 -0.0125 -0.03933930000000001 0.00106074 -0.013325 -0.0389 0 -0.0125 -0.039339 0.0010607 -0.01415 -0.03933930000000001 0.00106074 -0.013325 -0.05070000000000001 0.011 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.04190000000000001 0.003 -0.0125 0.001999999999999997 -0.00835 0.0158 -0.006000000000000004 -0.009075 0.0153 0.001999999999999997 -0.00835 0.0148 -0.03280000000000001 0.011 0 -0.05070000000000001 0.011 -0.0125 -0.04175000000000001 0.011 -1.56125e-17 -0.05070000000000001 0.011 -0.0125 -0.05070000000000001 0.011 0.0125 -0.04175000000000001 0.011 -1.56125e-17 -0.05070000000000001 0.011 0.0125 -0.03280000000000001 0.011 0 -0.04175000000000001 0.011 -1.56125e-17 -0.009000000000000003 0 0.0158 0.001999999999999997 0.00835 0.0158 -0.014 0.0098 0.0158 -0.014 0.0098 0.0148 -0.006000000000000004 0.009075 0.0153 0.001999999999999997 0.00835 0.0148 0.001999999999999997 0.00835 0.0158 -0.006000000000000004 0.009075 0.0153 -0.014 0.0098 0.0158 -0.006000000000000004 0 0.0148 0.001999999999999997 0.00835 0.0148 -0.002000000000000004 -1.99493e-17 0.0148 0.001999999999999997 0.00835 0.0148 0.001999999999999997 -0.00835 0.0148 -0.002000000000000004 -1.99493e-17 0.0148 0.001999999999999997 -0.00835 0.0148 -0.006000000000000004 0 0.0148 -0.002000000000000004 -1.99493e-17 0.0148 -0.009000000000000003 0 0.0158 0.001999999999999997 -0.00835 0.0158 -0.003500000000000004 0 0.0158 0.001999999999999997 -0.00835 0.0158 0.001999999999999997 0.00835 0.0158 -0.003500000000000004 0 0.0158 0.001999999999999997 0.00835 0.0158 -0.009000000000000003 0 0.0158 -0.003500000000000004 0 0.0158 -0.04087450000000001 -0.00247521 0.013325 -0.04087500000000001 -0.0024753 0.01415 -0.04190000000000001 -0.0029 0.0125 -0.04087450000000001 -0.00247521 0.013325 -0.04190000000000001 -0.0029 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.04087450000000001 -0.00247521 0.013325 -0.03984900000000001 -0.0020506 0.0125 -0.04087500000000001 -0.0024753 0.01415 -0.05070000000000001 -0.0098 0.0125 -0.04190000000000001 -0.0029 0.0125 -0.043951 -0.0020506 0.0125 -0.043951 0.0020506 0.0125 -0.04190000000000001 0.0029 0.0125 -0.05070000000000001 0.011 0.0125 -0.04087500000000001 0.0024753 0.01415 -0.03984900000000001 0.0020506 0.0125 -0.04087450000000001 0.00247521 0.013325 -0.03984900000000001 0.0020506 0.0125 -0.04190000000000001 0.0029 0.0125 -0.04087450000000001 0.00247521 0.013325 -0.04190000000000001 0.0029 0.0125 -0.04087500000000001 0.0024753 0.01415 -0.04087450000000001 0.00247521 0.013325 -0.039425 0.0010253 0.01415 -0.03900000000000001 0 0.0158 -0.0392125 0.00051265 0.01415 -0.03900000000000001 0 0.0158 -0.03900000000000001 0 0.0125 -0.0392125 0.00051265 0.01415 -0.03900000000000001 0 0.0125 -0.039425 0.0010253 0.01415 -0.0392125 0.00051265 0.01415 -0.039425 0.0010253 0.01415 -0.03984900000000001 0.0020506 0.0125 -0.03963700000000001 0.00153795 0.01415 -0.03984900000000001 0.0020506 0.0125 -0.03984900000000001 0.0020506 0.0158 -0.03963700000000001 0.00153795 0.01415 -0.03984900000000001 0.0020506 0.0158 -0.039425 0.0010253 0.01415 -0.03963700000000001 0.00153795 0.01415 -0.039425 -0.0010253 0.01415 -0.03984900000000001 -0.0020506 0.0158 -0.03963700000000001 -0.00153795 0.01415 -0.03984900000000001 -0.0020506 0.0158 -0.03984900000000001 -0.0020506 0.0125 -0.03963700000000001 -0.00153795 0.01415 -0.03984900000000001 -0.0020506 0.0125 -0.039425 -0.0010253 0.01415 -0.03963700000000001 -0.00153795 0.01415 -0.039425 -0.0010253 0.01415 -0.03900000000000001 0 0.0125 -0.0392125 -0.00051265 0.01415 -0.03900000000000001 0 0.0125 -0.03900000000000001 0 0.0158 -0.0392125 -0.00051265 0.01415 -0.03900000000000001 0 0.0158 -0.039425 -0.0010253 0.01415 -0.0392125 -0.00051265 0.01415 -0.05070000000000001 0.000599999 0 -0.05070000000000001 -0.0098 -0.0125 -0.05070000000000001 -0.0046 1.64799e-17 -0.05070000000000001 -0.0098 -0.0125 -0.05070000000000001 -0.0098 0.0125 -0.05070000000000001 -0.0046 1.64799e-17 -0.05070000000000001 -0.0098 0.0125 -0.05070000000000001 0.000599999 0 -0.05070000000000001 -0.0046 1.64799e-17 -0.05070000000000001 -0.0098 -0.0125 -0.044021 -0.0021213 -0.0125 -0.04190000000000001 -0.003 -0.0125 -0.040839 -0.0025607 -0.01415 -0.03977900000000001 -0.0021213 -0.0125 -0.0408395 -0.00256076 -0.013325 -0.03977900000000001 -0.0021213 -0.0125 -0.04190000000000001 -0.003 -0.0125 -0.0408395 -0.00256076 -0.013325 -0.04190000000000001 -0.003 -0.0125 -0.040839 -0.0025607 -0.01415 -0.0408395 -0.00256076 -0.013325 -0.039339 -0.0010607 -0.01415 -0.0389 0 -0.0158 -0.0391195 -0.00053035 -0.01415 -0.0389 0 -0.0158 -0.0389 0 -0.0125 -0.0391195 -0.00053035 -0.01415 -0.0389 0 -0.0125 -0.039339 -0.0010607 -0.01415 -0.0391195 -0.00053035 -0.01415 -0.039339 -0.0010607 -0.01415 -0.03977900000000001 -0.0021213 -0.0125 -0.039559 -0.001591 -0.01415 -0.03977900000000001 -0.0021213 -0.0125 -0.03977900000000001 -0.0021213 -0.0158 -0.039559 -0.001591 -0.01415 -0.03977900000000001 -0.0021213 -0.0158 -0.039339 -0.0010607 -0.01415 -0.039559 -0.001591 -0.01415 -0.039339 0.0010607 -0.01415 -0.03977900000000001 0.0021213 -0.0158 -0.039559 0.001591 -0.01415 -0.03977900000000001 0.0021213 -0.0158 -0.03977900000000001 0.0021213 -0.0125 -0.039559 0.001591 -0.01415 -0.03977900000000001 0.0021213 -0.0125 -0.039339 0.0010607 -0.01415 -0.039559 0.001591 -0.01415 -0.039339 0.0010607 -0.01415 -0.0389 0 -0.0125 -0.0391195 0.00053035 -0.01415 -0.0389 0 -0.0125 -0.0389 0 -0.0158 -0.0391195 0.00053035 -0.01415 -0.0389 0 -0.0158 -0.039339 0.0010607 -0.01415 -0.0391195 0.00053035 -0.01415 -0.0408395 0.00256076 -0.013325 -0.040839 0.0025607 -0.01415 -0.04190000000000001 0.003 -0.0125 -0.0408395 0.00256076 -0.013325 -0.04190000000000001 0.003 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.0408395 0.00256076 -0.013325 -0.03977900000000001 0.0021213 -0.0125 -0.040839 0.0025607 -0.01415 -0.044021 0.0021213 -0.0125 -0.05070000000000001 0.011 -0.0125 -0.04190000000000001 0.003 -0.0125 0.001999999999999997 0 0.0153 0.001999999999999997 -0.00835 0.0158 0.001999999999999997 -0.00835 0.0148 -0.05070000000000001 0.000599999 0 -0.05070000000000001 0.011 0.0125 -0.05070000000000001 0.0058 -7.806259999999999e-18 -0.05070000000000001 0.011 0.0125 -0.05070000000000001 0.011 -0.0125 -0.05070000000000001 0.0058 -7.806259999999999e-18 -0.05070000000000001 0.011 -0.0125 -0.05070000000000001 0.000599999 0 -0.05070000000000001 0.0058 -7.806259999999999e-18 0.001999999999999997 0.00835 0.0158 0.001999999999999997 0.00835 0.0148 -0.006000000000000004 0.009075 0.0153 0.001999999999999997 0.00835 0.0148 0.001999999999999997 0 0.0153 0.001999999999999997 -0.00835 0.0148 0.001999999999999997 -0.00835 0.0158 0.001999999999999997 0 0.0153 0.001999999999999997 0.00835 0.0158 -0.04087500000000001 -0.0024753 0.01415 -0.04190000000000001 -0.0029 0.0158 -0.04138750000000001 -0.00268765 0.01415 -0.04190000000000001 -0.0029 0.0158 -0.04190000000000001 -0.0029 0.0125 -0.04138750000000001 -0.00268765 0.01415 -0.04190000000000001 -0.0029 0.0125 -0.04087500000000001 -0.0024753 0.01415 -0.04138750000000001 -0.00268765 0.01415 -0.04087500000000001 -0.0024753 0.01415 -0.03984900000000001 -0.0020506 0.0125 -0.04036200000000001 -0.00226295 0.01415 -0.03984900000000001 -0.0020506 0.0125 -0.03984900000000001 -0.0020506 0.0158 -0.04036200000000001 -0.00226295 0.01415 -0.03984900000000001 -0.0020506 0.0158 -0.04087500000000001 -0.0024753 0.01415 -0.04036200000000001 -0.00226295 0.01415 -0.042925 -0.0024753 0.01415 -0.043951 -0.0020506 0.0125 -0.04292550000000001 -0.00247521 0.013325 -0.043951 -0.0020506 0.0125 -0.04190000000000001 -0.0029 0.0125 -0.04292550000000001 -0.00247521 0.013325 -0.04190000000000001 -0.0029 0.0125 -0.042925 -0.0024753 0.01415 -0.04292550000000001 -0.00247521 0.013325 -0.05070000000000001 -0.0098 0.0125 -0.043951 -0.0020506 0.0125 -0.05070000000000001 0.011 0.0125 -0.04480000000000001 0 0.0125 -0.043951 0.0020506 0.0125 -0.05070000000000001 0.011 0.0125 -0.042925 0.0024753 0.01415 -0.04190000000000001 0.0029 0.0125 -0.04292550000000001 0.00247521 0.013325 -0.04190000000000001 0.0029 0.0125 -0.043951 0.0020506 0.0125 -0.04292550000000001 0.00247521 0.013325 -0.043951 0.0020506 0.0125 -0.042925 0.0024753 0.01415 -0.04292550000000001 0.00247521 0.013325 -0.04087500000000001 0.0024753 0.01415 -0.03984900000000001 0.0020506 0.0158 -0.04036200000000001 0.00226295 0.01415 -0.03984900000000001 0.0020506 0.0158 -0.03984900000000001 0.0020506 0.0125 -0.04036200000000001 0.00226295 0.01415 -0.03984900000000001 0.0020506 0.0125 -0.04087500000000001 0.0024753 0.01415 -0.04036200000000001 0.00226295 0.01415 -0.04087500000000001 0.0024753 0.01415 -0.04190000000000001 0.0029 0.0125 -0.04138750000000001 0.00268765 0.01415 -0.04190000000000001 0.0029 0.0125 -0.04190000000000001 0.0029 0.0158 -0.04138750000000001 0.00268765 0.01415 -0.04190000000000001 0.0029 0.0158 -0.04087500000000001 0.0024753 0.01415 -0.04138750000000001 0.00268765 0.01415 -0.039425 0.0010253 0.01415 -0.03984900000000001 0.0020506 0.0158 -0.03942470000000001 0.00102521 0.014975 -0.03984900000000001 0.0020506 0.0158 -0.03900000000000001 0 0.0158 -0.03942470000000001 0.00102521 0.014975 -0.03900000000000001 0 0.0158 -0.039425 0.0010253 0.01415 -0.03942470000000001 0.00102521 0.014975 -0.039425 -0.0010253 0.01415 -0.03900000000000001 0 0.0158 -0.03942470000000001 -0.00102521 0.014975 -0.03900000000000001 0 0.0158 -0.03984900000000001 -0.0020506 0.0158 -0.03942470000000001 -0.00102521 0.014975 -0.03984900000000001 -0.0020506 0.0158 -0.039425 -0.0010253 0.01415 -0.03942470000000001 -0.00102521 0.014975 -0.05070000000000001 0.000599999 0 -0.05070000000000001 0.011 -0.0125 -0.05070000000000001 0.0005999999999999999 -0.00625 -0.05070000000000001 0.011 -0.0125 -0.05070000000000001 -0.0098 -0.0125 -0.05070000000000001 0.0005999999999999999 -0.00625 -0.05070000000000001 -0.0098 -0.0125 -0.05070000000000001 0.000599999 0 -0.05070000000000001 0.0005999999999999999 -0.00625 -0.05070000000000001 0.000599999 0 -0.05070000000000001 -0.0098 0.0125 -0.05070000000000001 0.0005999999999999999 0.00625 -0.05070000000000001 -0.0098 0.0125 -0.05070000000000001 0.011 0.0125 -0.05070000000000001 0.0005999999999999999 0.00625 -0.05070000000000001 0.011 0.0125 -0.05070000000000001 0.000599999 0 -0.05070000000000001 0.0005999999999999999 0.00625 -0.044021 -0.0021213 -0.0125 -0.05070000000000001 -0.0098 -0.0125 -0.05070000000000001 0.011 -0.0125 -0.0429605 -0.00256076 -0.013325 -0.042961 -0.0025607 -0.01415 -0.04190000000000001 -0.003 -0.0125 -0.0429605 -0.00256076 -0.013325 -0.04190000000000001 -0.003 -0.0125 -0.044021 -0.0021213 -0.0125 -0.0429605 -0.00256076 -0.013325 -0.044021 -0.0021213 -0.0125 -0.042961 -0.0025607 -0.01415 -0.040839 -0.0025607 -0.01415 -0.03977900000000001 -0.0021213 -0.0158 -0.040309 -0.002341 -0.01415 -0.03977900000000001 -0.0021213 -0.0158 -0.03977900000000001 -0.0021213 -0.0125 -0.040309 -0.002341 -0.01415 -0.03977900000000001 -0.0021213 -0.0125 -0.040839 -0.0025607 -0.01415 -0.040309 -0.002341 -0.01415 -0.040839 -0.0025607 -0.01415 -0.04190000000000001 -0.003 -0.0125 -0.0413695 -0.00278035 -0.01415 -0.04190000000000001 -0.003 -0.0125 -0.04190000000000001 -0.003 -0.0158 -0.0413695 -0.00278035 -0.01415 -0.04190000000000001 -0.003 -0.0158 -0.040839 -0.0025607 -0.01415 -0.0413695 -0.00278035 -0.01415 -0.039339 -0.0010607 -0.01415 -0.03977900000000001 -0.0021213 -0.0158 -0.03933930000000001 -0.00106074 -0.014975 -0.03977900000000001 -0.0021213 -0.0158 -0.0389 0 -0.0158 -0.03933930000000001 -0.00106074 -0.014975 -0.0389 0 -0.0158 -0.039339 -0.0010607 -0.01415 -0.03933930000000001 -0.00106074 -0.014975 -0.039339 0.0010607 -0.01415 -0.0389 0 -0.0158 -0.03933930000000001 0.00106074 -0.014975 -0.0389 0 -0.0158 -0.03977900000000001 0.0021213 -0.0158 -0.03933930000000001 0.00106074 -0.014975 -0.03977900000000001 0.0021213 -0.0158 -0.039339 0.0010607 -0.01415 -0.03933930000000001 0.00106074 -0.014975 -0.040839 0.0025607 -0.01415 -0.03977900000000001 0.0021213 -0.0125 -0.040309 0.002341 -0.01415 -0.03977900000000001 0.0021213 -0.0125 -0.03977900000000001 0.0021213 -0.0158 -0.040309 0.002341 -0.01415 -0.03977900000000001 0.0021213 -0.0158 -0.040839 0.0025607 -0.01415 -0.040309 0.002341 -0.01415 -0.040839 0.0025607 -0.01415 -0.04190000000000001 0.003 -0.0158 -0.0413695 0.00278035 -0.01415 -0.04190000000000001 0.003 -0.0158 -0.04190000000000001 0.003 -0.0125 -0.0413695 0.00278035 -0.01415 -0.04190000000000001 0.003 -0.0125 -0.040839 0.0025607 -0.01415 -0.0413695 0.00278035 -0.01415 -0.042961 0.0025607 -0.01415 -0.044021 0.0021213 -0.0125 -0.0429605 0.00256076 -0.013325 -0.044021 0.0021213 -0.0125 -0.04190000000000001 0.003 -0.0125 -0.0429605 0.00256076 -0.013325 -0.04190000000000001 0.003 -0.0125 -0.042961 0.0025607 -0.01415 -0.0429605 0.00256076 -0.013325 -0.044021 0.0021213 -0.0125 -0.04490000000000001 0 -0.0125 -0.05070000000000001 0.011 -0.0125 0.001999999999999997 0.00835 0.0148 0.001999999999999997 0.00835 0.0158 0.001999999999999997 0 0.0153 -0.04087450000000001 -0.00247521 0.014975 -0.04087500000000001 -0.0024753 0.01415 -0.03984900000000001 -0.0020506 0.0158 -0.04087450000000001 -0.00247521 0.014975 -0.03984900000000001 -0.0020506 0.0158 -0.04190000000000001 -0.0029 0.0158 -0.04087450000000001 -0.00247521 0.014975 -0.04190000000000001 -0.0029 0.0158 -0.04087500000000001 -0.0024753 0.01415 -0.042925 -0.0024753 0.01415 -0.04190000000000001 -0.0029 0.0125 -0.04241250000000001 -0.00268765 0.01415 -0.04190000000000001 -0.0029 0.0125 -0.04190000000000001 -0.0029 0.0158 -0.04241250000000001 -0.00268765 0.01415 -0.04190000000000001 -0.0029 0.0158 -0.042925 -0.0024753 0.01415 -0.04241250000000001 -0.00268765 0.01415 -0.042925 -0.0024753 0.01415 -0.043951 -0.0020506 0.0158 -0.043438 -0.00226295 0.01415 -0.043951 -0.0020506 0.0158 -0.043951 -0.0020506 0.0125 -0.043438 -0.00226295 0.01415 -0.043951 -0.0020506 0.0125 -0.042925 -0.0024753 0.01415 -0.043438 -0.00226295 0.01415 -0.043951 -0.0020506 0.0125 -0.04480000000000001 0 0.0125 -0.05070000000000001 0.011 0.0125 -0.04437530000000001 0.00102521 0.013325 -0.044375 0.0010253 0.01415 -0.043951 0.0020506 0.0125 -0.04437530000000001 0.00102521 0.013325 -0.043951 0.0020506 0.0125 -0.04480000000000001 0 0.0125 -0.04437530000000001 0.00102521 0.013325 -0.04480000000000001 0 0.0125 -0.044375 0.0010253 0.01415 -0.042925 0.0024753 0.01415 -0.04190000000000001 0.0029 0.0158 -0.04241250000000001 0.00268765 0.01415 -0.04190000000000001 0.0029 0.0158 -0.04190000000000001 0.0029 0.0125 -0.04241250000000001 0.00268765 0.01415 -0.04190000000000001 0.0029 0.0125 -0.042925 0.0024753 0.01415 -0.04241250000000001 0.00268765 0.01415 -0.042925 0.0024753 0.01415 -0.043951 0.0020506 0.0125 -0.043438 0.00226295 0.01415 -0.043951 0.0020506 0.0125 -0.043951 0.0020506 0.0158 -0.043438 0.00226295 0.01415 -0.043951 0.0020506 0.0158 -0.042925 0.0024753 0.01415 -0.043438 0.00226295 0.01415 -0.04087500000000001 0.0024753 0.01415 -0.04190000000000001 0.0029 0.0158 -0.04087450000000001 0.00247521 0.014975 -0.04190000000000001 0.0029 0.0158 -0.03984900000000001 0.0020506 0.0158 -0.04087450000000001 0.00247521 0.014975 -0.03984900000000001 0.0020506 0.0158 -0.04087500000000001 0.0024753 0.01415 -0.04087450000000001 0.00247521 0.014975 -0.03900000000000001 0 0.0158 -0.03984900000000001 0.0020506 0.0158 -0.04190000000000001 0 0.0158 -0.03984900000000001 -0.0020506 0.0158 -0.03900000000000001 0 0.0158 -0.04190000000000001 0 0.0158 -0.05070000000000001 0.011 -0.0125 -0.04490000000000001 0 -0.0125 -0.044021 -0.0021213 -0.0125 -0.042961 -0.0025607 -0.01415 -0.04190000000000001 -0.003 -0.0158 -0.04243050000000001 -0.00278035 -0.01415 -0.04190000000000001 -0.003 -0.0158 -0.04190000000000001 -0.003 -0.0125 -0.04243050000000001 -0.00278035 -0.01415 -0.04190000000000001 -0.003 -0.0125 -0.042961 -0.0025607 -0.01415 -0.04243050000000001 -0.00278035 -0.01415 -0.042961 -0.0025607 -0.01415 -0.044021 -0.0021213 -0.0125 -0.043491 -0.002341 -0.01415 -0.044021 -0.0021213 -0.0125 -0.044021 -0.0021213 -0.0158 -0.043491 -0.002341 -0.01415 -0.044021 -0.0021213 -0.0158 -0.042961 -0.0025607 -0.01415 -0.043491 -0.002341 -0.01415 -0.040839 -0.0025607 -0.01415 -0.04190000000000001 -0.003 -0.0158 -0.0408395 -0.00256076 -0.014975 -0.04190000000000001 -0.003 -0.0158 -0.03977900000000001 -0.0021213 -0.0158 -0.0408395 -0.00256076 -0.014975 -0.03977900000000001 -0.0021213 -0.0158 -0.040839 -0.0025607 -0.01415 -0.0408395 -0.00256076 -0.014975 -0.03977900000000001 -0.0021213 -0.0158 -0.04190000000000001 0 -0.0158 -0.0389 0 -0.0158 -0.0389 0 -0.0158 -0.04190000000000001 0 -0.0158 -0.03977900000000001 0.0021213 -0.0158 -0.0408395 0.00256076 -0.014975 -0.040839 0.0025607 -0.01415 -0.03977900000000001 0.0021213 -0.0158 -0.0408395 0.00256076 -0.014975 -0.03977900000000001 0.0021213 -0.0158 -0.04190000000000001 0.003 -0.0158 -0.0408395 0.00256076 -0.014975 -0.04190000000000001 0.003 -0.0158 -0.040839 0.0025607 -0.01415 -0.042961 0.0025607 -0.01415 -0.04190000000000001 0.003 -0.0125 -0.04243050000000001 0.00278035 -0.01415 -0.04190000000000001 0.003 -0.0125 -0.04190000000000001 0.003 -0.0158 -0.04243050000000001 0.00278035 -0.01415 -0.04190000000000001 0.003 -0.0158 -0.042961 0.0025607 -0.01415 -0.04243050000000001 0.00278035 -0.01415 -0.042961 0.0025607 -0.01415 -0.044021 0.0021213 -0.0158 -0.043491 0.002341 -0.01415 -0.044021 0.0021213 -0.0158 -0.044021 0.0021213 -0.0125 -0.043491 0.002341 -0.01415 -0.044021 0.0021213 -0.0125 -0.042961 0.0025607 -0.01415 -0.043491 0.002341 -0.01415 -0.044461 0.0010607 -0.01415 -0.04490000000000001 0 -0.0125 -0.04446070000000001 0.00106074 -0.013325 -0.04490000000000001 0 -0.0125 -0.044021 0.0021213 -0.0125 -0.04446070000000001 0.00106074 -0.013325 -0.044021 0.0021213 -0.0125 -0.044461 0.0010607 -0.01415 -0.04446070000000001 0.00106074 -0.013325 -0.04190000000000001 -0.0029 0.0158 -0.03984900000000001 -0.0020506 0.0158 -0.04190000000000001 0 0.0158 -0.042925 -0.0024753 0.01415 -0.04190000000000001 -0.0029 0.0158 -0.04292550000000001 -0.00247521 0.014975 -0.04190000000000001 -0.0029 0.0158 -0.043951 -0.0020506 0.0158 -0.04292550000000001 -0.00247521 0.014975 -0.043951 -0.0020506 0.0158 -0.042925 -0.0024753 0.01415 -0.04292550000000001 -0.00247521 0.014975 -0.044375 -0.0010253 0.01415 -0.043951 -0.0020506 0.0125 -0.04416300000000001 -0.00153795 0.01415 -0.043951 -0.0020506 0.0125 -0.043951 -0.0020506 0.0158 -0.04416300000000001 -0.00153795 0.01415 -0.043951 -0.0020506 0.0158 -0.044375 -0.0010253 0.01415 -0.04416300000000001 -0.00153795 0.01415 -0.044375 -0.0010253 0.01415 -0.04480000000000001 0 0.0125 -0.04437530000000001 -0.00102521 0.013325 -0.04480000000000001 0 0.0125 -0.043951 -0.0020506 0.0125 -0.04437530000000001 -0.00102521 0.013325 -0.043951 -0.0020506 0.0125 -0.044375 -0.0010253 0.01415 -0.04437530000000001 -0.00102521 0.013325 -0.044375 0.0010253 0.01415 -0.043951 0.0020506 0.0158 -0.04416300000000001 0.00153795 0.01415 -0.043951 0.0020506 0.0158 -0.043951 0.0020506 0.0125 -0.04416300000000001 0.00153795 0.01415 -0.043951 0.0020506 0.0125 -0.044375 0.0010253 0.01415 -0.04416300000000001 0.00153795 0.01415 -0.044375 0.0010253 0.01415 -0.04480000000000001 0 0.0125 -0.0445875 0.00051265 0.01415 -0.04480000000000001 0 0.0125 -0.04480000000000001 0 0.0158 -0.0445875 0.00051265 0.01415 -0.04480000000000001 0 0.0158 -0.044375 0.0010253 0.01415 -0.0445875 0.00051265 0.01415 -0.04292550000000001 0.00247521 0.014975 -0.042925 0.0024753 0.01415 -0.043951 0.0020506 0.0158 -0.04292550000000001 0.00247521 0.014975 -0.043951 0.0020506 0.0158 -0.04190000000000001 0.0029 0.0158 -0.04292550000000001 0.00247521 0.014975 -0.04190000000000001 0.0029 0.0158 -0.042925 0.0024753 0.01415 -0.04190000000000001 0 0.0158 -0.03984900000000001 0.0020506 0.0158 -0.04190000000000001 0.0029 0.0158 -0.044461 -0.0010607 -0.01415 -0.044021 -0.0021213 -0.0125 -0.04446070000000001 -0.00106074 -0.013325 -0.044021 -0.0021213 -0.0125 -0.04490000000000001 0 -0.0125 -0.04446070000000001 -0.00106074 -0.013325 -0.04490000000000001 0 -0.0125 -0.044461 -0.0010607 -0.01415 -0.04446070000000001 -0.00106074 -0.013325 -0.0429605 -0.00256076 -0.014975 -0.042961 -0.0025607 -0.01415 -0.044021 -0.0021213 -0.0158 -0.0429605 -0.00256076 -0.014975 -0.044021 -0.0021213 -0.0158 -0.04190000000000001 -0.003 -0.0158 -0.0429605 -0.00256076 -0.014975 -0.04190000000000001 -0.003 -0.0158 -0.042961 -0.0025607 -0.01415 -0.044461 -0.0010607 -0.01415 -0.044021 -0.0021213 -0.0158 -0.044241 -0.001591 -0.01415 -0.044021 -0.0021213 -0.0158 -0.044021 -0.0021213 -0.0125 -0.044241 -0.001591 -0.01415 -0.044021 -0.0021213 -0.0125 -0.044461 -0.0010607 -0.01415 -0.044241 -0.001591 -0.01415 -0.03977900000000001 -0.0021213 -0.0158 -0.04190000000000001 -0.003 -0.0158 -0.04190000000000001 0 -0.0158 -0.04190000000000001 0 -0.0158 -0.04190000000000001 0.003 -0.0158 -0.03977900000000001 0.0021213 -0.0158 -0.042961 0.0025607 -0.01415 -0.04190000000000001 0.003 -0.0158 -0.0429605 0.00256076 -0.014975 -0.04190000000000001 0.003 -0.0158 -0.044021 0.0021213 -0.0158 -0.0429605 0.00256076 -0.014975 -0.044021 0.0021213 -0.0158 -0.042961 0.0025607 -0.01415 -0.0429605 0.00256076 -0.014975 -0.044461 0.0010607 -0.01415 -0.044021 0.0021213 -0.0125 -0.044241 0.001591 -0.01415 -0.044021 0.0021213 -0.0125 -0.044021 0.0021213 -0.0158 -0.044241 0.001591 -0.01415 -0.044021 0.0021213 -0.0158 -0.044461 0.0010607 -0.01415 -0.044241 0.001591 -0.01415 -0.044461 0.0010607 -0.01415 -0.04490000000000001 0 -0.0158 -0.0446805 0.00053035 -0.01415 -0.04490000000000001 0 -0.0158 -0.04490000000000001 0 -0.0125 -0.0446805 0.00053035 -0.01415 -0.04490000000000001 0 -0.0125 -0.044461 0.0010607 -0.01415 -0.0446805 0.00053035 -0.01415 -0.04190000000000001 -0.0029 0.0158 -0.04190000000000001 0 0.0158 -0.043951 -0.0020506 0.0158 -0.044375 -0.0010253 0.01415 -0.043951 -0.0020506 0.0158 -0.04437530000000001 -0.00102521 0.014975 -0.043951 -0.0020506 0.0158 -0.04480000000000001 0 0.0158 -0.04437530000000001 -0.00102521 0.014975 -0.04480000000000001 0 0.0158 -0.044375 -0.0010253 0.01415 -0.04437530000000001 -0.00102521 0.014975 -0.044375 -0.0010253 0.01415 -0.04480000000000001 0 0.0158 -0.0445875 -0.00051265 0.01415 -0.04480000000000001 0 0.0158 -0.04480000000000001 0 0.0125 -0.0445875 -0.00051265 0.01415 -0.04480000000000001 0 0.0125 -0.044375 -0.0010253 0.01415 -0.0445875 -0.00051265 0.01415 -0.044375 0.0010253 0.01415 -0.04480000000000001 0 0.0158 -0.04437530000000001 0.00102521 0.014975 -0.04480000000000001 0 0.0158 -0.043951 0.0020506 0.0158 -0.04437530000000001 0.00102521 0.014975 -0.043951 0.0020506 0.0158 -0.044375 0.0010253 0.01415 -0.04437530000000001 0.00102521 0.014975 -0.04190000000000001 0 0.0158 -0.04190000000000001 0.0029 0.0158 -0.043951 0.0020506 0.0158 -0.044461 -0.0010607 -0.01415 -0.04490000000000001 0 -0.0125 -0.0446805 -0.00053035 -0.01415 -0.04490000000000001 0 -0.0125 -0.04490000000000001 0 -0.0158 -0.0446805 -0.00053035 -0.01415 -0.04490000000000001 0 -0.0158 -0.044461 -0.0010607 -0.01415 -0.0446805 -0.00053035 -0.01415 -0.04190000000000001 -0.003 -0.0158 -0.044021 -0.0021213 -0.0158 -0.04190000000000001 0 -0.0158 -0.044461 -0.0010607 -0.01415 -0.04490000000000001 0 -0.0158 -0.04446070000000001 -0.00106074 -0.014975 -0.04490000000000001 0 -0.0158 -0.044021 -0.0021213 -0.0158 -0.04446070000000001 -0.00106074 -0.014975 -0.044021 -0.0021213 -0.0158 -0.044461 -0.0010607 -0.01415 -0.04446070000000001 -0.00106074 -0.014975 -0.04190000000000001 0 -0.0158 -0.044021 0.0021213 -0.0158 -0.04190000000000001 0.003 -0.0158 -0.04446070000000001 0.00106074 -0.014975 -0.044461 0.0010607 -0.01415 -0.044021 0.0021213 -0.0158 -0.04446070000000001 0.00106074 -0.014975 -0.044021 0.0021213 -0.0158 -0.04490000000000001 0 -0.0158 -0.04446070000000001 0.00106074 -0.014975 -0.04490000000000001 0 -0.0158 -0.044461 0.0010607 -0.01415 -0.043951 -0.0020506 0.0158 -0.04190000000000001 0 0.0158 -0.04480000000000001 0 0.0158 -0.04480000000000001 0 0.0158 -0.04190000000000001 0 0.0158 -0.043951 0.0020506 0.0158 -0.044021 -0.0021213 -0.0158 -0.04490000000000001 0 -0.0158 -0.04190000000000001 0 -0.0158 -0.04190000000000001 0 -0.0158 -0.04490000000000001 0 -0.0158 -0.044021 0.0021213 -0.0158 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265

    -
    -
    - - - -3.469446951953614e-18 0 0 - 1 0 0 0 - - true - - - -
    - - - - -0.004453999999999993 -0.0072397 0.0148 -0.01722999999999999 0.00062 0.0153 -0.03000599999999999 0.0084797 0.0148 -0.03000599999999999 0.0084797 0.0158 -0.03000599999999999 0.0084797 0.0148 -0.01722999999999999 0.00062 0.0153 -0.03000599999999999 0.0084797 0.0148 -0.03000799999999999 0.0119797 0.0148 -0.004453999999999993 -0.0072397 0.0148 -0.004453999999999993 -0.0072397 0.0158 -0.01722999999999999 0.00062 0.0153 -0.004453999999999993 -0.0072397 0.0148 -0.03000599999999999 0.0084797 0.0158 -0.01722999999999999 0.00062 0.0153 -0.004453999999999993 -0.0072397 0.0158 -0.03000599999999999 0.0084797 0.0148 -0.03000599999999999 0.0084797 0.0158 -0.03000799999999999 0.0119797 0.0148 -0.03000799999999999 0.0119797 0.0148 -0.003496999999999993 -0.0077473 0.0148 -0.004453999999999993 -0.0072397 0.0148 -0.003975989999999993 -0.0074935 0.0153 -0.004453999999999993 -0.0072397 0.0158 -0.004214999999999993 -0.0073666 0.0153 -0.004453999999999993 -0.0072397 0.0158 -0.004453999999999993 -0.0072397 0.0148 -0.004214999999999993 -0.0073666 0.0153 -0.004453999999999993 -0.0072397 0.0148 -0.003975989999999993 -0.0074935 0.0153 -0.004214999999999993 -0.0073666 0.0153 -0.03000599999999999 0.0084797 0.0158 -0.004453999999999993 -0.0072397 0.0158 -0.03000899999999999 0.0129797 0.0158 -0.03000799999999999 0.0119797 0.0148 -0.03000599999999999 0.0084797 0.0158 -0.03000899999999999 0.0129797 0.0158 -0.003975989999999993 -0.0074935 0.0153 -0.004453999999999993 -0.0072397 0.0148 -0.003975549999999993 -0.0074936 0.01505 -0.004453999999999993 -0.0072397 0.0148 -0.003496999999999993 -0.0077473 0.0148 -0.003975549999999993 -0.0074936 0.01505 -0.003496999999999993 -0.0077473 0.0148 -0.003975989999999993 -0.0074935 0.0153 -0.003975549999999993 -0.0074936 0.01505 -0.003496999999999993 -0.0077473 0.0148 -0.03000799999999999 0.0119797 0.0148 -0.01000599999999999 0.008493199999999999 0.0148 -0.003975549999999993 -0.0074936 0.01555 -0.003975989999999993 -0.0074935 0.0153 -0.003496999999999993 -0.0077473 0.0158 -0.003975549999999993 -0.0074936 0.01555 -0.003496999999999993 -0.0077473 0.0158 -0.004453999999999993 -0.0072397 0.0158 -0.003975549999999993 -0.0074936 0.01555 -0.004453999999999993 -0.0072397 0.0158 -0.003975989999999993 -0.0074935 0.0153 -0.004453999999999993 -0.0072397 0.0158 -0.003496999999999993 -0.0077473 0.0158 -0.03000899999999999 0.0129797 0.0158 -0.03000899999999999 0.0129797 -0.0158 -0.03000799999999999 0.0119797 0.0148 -0.03000899999999999 0.0129797 0.0158 -0.003975989999999993 -0.0074935 0.0153 -0.003496999999999993 -0.0077473 0.0148 -0.003736499999999993 -0.0076204 0.0153 -0.003496999999999993 -0.0077473 0.0148 -0.003496999999999993 -0.0077473 0.0158 -0.003736499999999993 -0.0076204 0.0153 -0.003496999999999993 -0.0077473 0.0158 -0.003975989999999993 -0.0074935 0.0153 -0.003736499999999993 -0.0076204 0.0153 -0.003496999999999993 -0.0077473 0.0148 -0.01000599999999999 0.008493199999999999 0.0148 0.01273690000000001 0.0085086 0.0148 -0.01000599999999999 0.008493199999999999 0.0148 -0.03000799999999999 0.0119797 0.0148 -0.01000799999999999 0.0119932 0.0148 -0.003496999999999993 -0.0077473 0.0158 -0.01000599999999999 0.008493199999999999 0.0158 -0.03000899999999999 0.0129797 0.0158 -0.03000899999999999 0.0129797 0.0158 -0.02886979999999999 0.0129805 0.014 -0.02999999999999999 0.0129797 0.014 -0.02999999999999999 0.0129797 -0.014 -0.02886979999999999 0.0129805 -0.014 -0.03000899999999999 0.0129797 -0.0158 -0.02999999999999999 0.0129797 0.014 -0.03000899999999999 0.0129797 -0.0158 -0.03000899999999999 0.0129797 0.0158 -0.02999999999999999 0.0129797 0.00228598 -0.03000899999999999 0.0129797 -0.0158 -0.02999999999999999 0.0129797 0.014 -0.02999999999999999 0.0129797 0.00228598 -0.03000899999999999 0.0129797 -0.0158 -0.02999999999999999 0.0129797 0 -0.02999999999999999 0.0129797 -0.011714 -0.03000899999999999 0.0129797 -0.0158 -0.02999999999999999 0.0129797 0 -0.02999999999999999 0.0129797 -0.011714 -0.03000899999999999 0.0129797 -0.0158 -0.02999999999999999 0.0129797 -0.014 -0.03000899999999999 0.0129797 -0.0158 -0.03000799999999999 0.0119797 -0.0148 -0.03000799999999999 0.0119797 0.0148 -0.003496999999999993 -0.0077473 0.0148 0.004620000000000007 0.000380699 0.0153 -0.003496999999999993 -0.0077473 0.0158 0.01273690000000001 0.0085086 0.0148 0.004620000000000007 0.000380699 0.0153 -0.003496999999999993 -0.0077473 0.0148 -0.01000599999999999 0.008493199999999999 0.0148 0.001366000000000007 0.0085009 0.0153 0.01273690000000001 0.0085086 0.0148 -0.01000599999999999 0.008493199999999999 0.0148 -0.01000799999999999 0.0119932 0.0148 -0.01000599999999999 0.008493199999999999 0.0158 -0.02000799999999999 0.0119865 0 -0.01000799999999999 0.0119932 0.0148 -0.02000799999999999 0.0119865 0.0074 -0.01000799999999999 0.0119932 0.0148 -0.03000799999999999 0.0119797 0.0148 -0.02000799999999999 0.0119865 0.0074 -0.03000799999999999 0.0119797 0.0148 -0.02000799999999999 0.0119865 0 -0.02000799999999999 0.0119865 0.0074 -0.01000599999999999 0.008493199999999999 0.0158 -0.01000899999999999 0.0129932 0.0158 -0.03000899999999999 0.0129797 0.0158 -0.003496999999999993 -0.0077473 0.0158 0.01273690000000001 0.0085086 0.0158 -0.01000599999999999 0.008493199999999999 0.0158 -0.02247719999999999 0.0129848 -0.014 -0.03000899999999999 0.0129797 -0.0158 -0.02886979999999999 0.0129805 -0.014 -0.01000899999999999 0.0129932 -0.0158 -0.01348629999999999 0.0129909 -0.014 -0.01199999999999999 0.0129919 -0.014 -0.01000899999999999 0.0129932 -0.0158 -0.01199999999999999 0.0129919 -0.014 -0.01199999999999999 0.0129919 -0.0126542 -0.02000899999999999 0.0129865 -0.0142271 -0.02099999999999999 0.0129858 -0.014 -0.01348629999999999 0.0129909 -0.014 -0.02000899999999999 0.0129865 -0.0142271 -0.02247719999999999 0.0129848 -0.014 -0.02099999999999999 0.0129858 -0.014 -0.02000899999999999 0.0129865 -0.0142271 -0.01000899999999999 0.0129932 -0.0158 -0.03000899999999999 0.0129797 -0.0158 -0.02000899999999999 0.0129865 -0.0142271 -0.03000899999999999 0.0129797 -0.0158 -0.02247719999999999 0.0129848 -0.014 -0.02000899999999999 0.0129865 -0.0142271 -0.01348629999999999 0.0129909 -0.014 -0.01000899999999999 0.0129932 -0.0158 -0.01199999999999999 0.0129919 0.014 -0.01000899999999999 0.0129932 0.0158 -0.01199999999999999 0.0129919 0.0126542 -0.01000899999999999 0.0129932 0.0158 -0.01199999999999999 0.0129919 0.014 -0.01951979999999999 0.0129868 0.014 -0.03000899999999999 0.0129797 0.0158 -0.02099999999999999 0.0129858 0.014 -0.02852889999999999 0.0129807 0.014 -0.03000899999999999 0.0129797 0.0158 -0.02852889999999999 0.0129807 0.014 -0.02886979999999999 0.0129805 0.014 -0.01951979999999999 0.0129868 0.014 -0.02099999999999999 0.0129858 0.014 -0.02000899999999999 0.0129865 0.0142271 -0.03000899999999999 0.0129797 0.0158 -0.01000899999999999 0.0129932 0.0158 -0.02000899999999999 0.0129865 0.0142271 -0.01000899999999999 0.0129932 0.0158 -0.01951979999999999 0.0129868 0.014 -0.02000899999999999 0.0129865 0.0142271 -0.02099999999999999 0.0129858 0.014 -0.03000899999999999 0.0129797 0.0158 -0.02000899999999999 0.0129865 0.0142271 -0.03000599999999999 0.0084797 -0.0158 -0.03000799999999999 0.0119797 -0.0148 -0.03000899999999999 0.0129797 -0.0158 -0.02000799999999999 0.0119865 0 -0.03000799999999999 0.0119797 0.0148 -0.02500799999999999 0.0119831 8.67362e-19 -0.03000799999999999 0.0119797 0.0148 -0.03000799999999999 0.0119797 -0.0148 -0.02500799999999999 0.0119831 8.67362e-19 -0.03000799999999999 0.0119797 -0.0148 -0.02000799999999999 0.0119865 0 -0.02500799999999999 0.0119831 8.67362e-19 -0.003496999999999993 -0.0077473 0.0158 0.004620000000000007 0.000380699 0.0153 0.01273690000000001 0.0085086 0.0158 0.01273690000000001 0.0085086 0.0148 0.01273690000000001 0.0085086 0.0158 0.004620000000000007 0.000380699 0.0153 0.01273690000000001 0.0085086 0.0158 0.01273690000000001 0.0085086 0.0148 0.001366000000000007 0.0085009 0.0153 -0.01000599999999999 0.008493199999999999 0.0158 0.001366000000000007 0.0085009 0.0153 -0.01000599999999999 0.008493199999999999 0.0148 -0.01000799999999999 0.0119932 0.0148 -0.01000899999999999 0.0129932 0.0158 -0.01000599999999999 0.008493199999999999 0.0158 -0.02000799999999999 0.0119865 0 -0.01000799999999999 0.0119932 -0.0148 -0.01500799999999999 0.0119898 -8.67362e-19 -0.01000799999999999 0.0119932 -0.0148 -0.01000799999999999 0.0119932 0.0148 -0.01500799999999999 0.0119898 -8.67362e-19 -0.01000799999999999 0.0119932 0.0148 -0.02000799999999999 0.0119865 0 -0.01500799999999999 0.0119898 -8.67362e-19 0.01273690000000001 0.0085086 0.0158 0.001366000000000007 0.0085009 0.0153 -0.01000599999999999 0.008493199999999999 0.0158 -0.01000599999999999 0.008493199999999999 -0.0158 -0.03000899999999999 0.0129797 -0.0158 -0.01000899999999999 0.0129932 -0.0158 -0.01199999999999999 0.0129919 0.0126542 -0.01000899999999999 0.0129932 0.0158 -0.01199999999999999 0.0129919 0.0116856 -0.01199999999999999 0.0129919 -0.0126542 -0.01199999999999999 0.0129919 -0.00231435 -0.01000899999999999 0.0129932 -0.0158 -0.01000899999999999 0.0129932 0.0158 -0.01000899999999999 0.0129932 -0.0158 -0.01100449999999999 0.0129925 0 -0.01199999999999999 0.0129919 -0.00231435 -0.01199999999999999 0.0129919 0 -0.01100449999999999 0.0129925 0 -0.01199999999999999 0.0129919 0 -0.01199999999999999 0.0129919 0.0116856 -0.01100449999999999 0.0129925 0 -0.01199999999999999 0.0129919 0.0116856 -0.01000899999999999 0.0129932 0.0158 -0.01100449999999999 0.0129925 0 -0.01000899999999999 0.0129932 -0.0158 -0.01199999999999999 0.0129919 -0.00231435 -0.01100449999999999 0.0129925 0 -0.03000599999999999 0.0084797 -0.0158 -0.03000899999999999 0.0129797 -0.0158 -0.004453999999999993 -0.0072397 -0.0158 -0.03000599999999999 0.0084797 -0.0158 -0.03000599999999999 0.0084797 -0.0148 -0.03000799999999999 0.0119797 -0.0148 -0.02000799999999999 0.0119865 0 -0.03000799999999999 0.0119797 -0.0148 -0.02000799999999999 0.0119865 -0.0074 -0.03000799999999999 0.0119797 -0.0148 -0.01000799999999999 0.0119932 -0.0148 -0.02000799999999999 0.0119865 -0.0074 -0.01000799999999999 0.0119932 -0.0148 -0.02000799999999999 0.0119865 0 -0.02000799999999999 0.0119865 -0.0074 -0.01000899999999999 0.0129932 -0.0158 -0.01000899999999999 0.0129932 0.0158 -0.01000799999999999 0.0119932 0.0148 -0.01000799999999999 0.0119932 -0.0148 -0.01000899999999999 0.0129932 -0.0158 -0.01000799999999999 0.0119932 0.0148 -0.01000599999999999 0.008493199999999999 -0.0158 -0.01000899999999999 0.0129932 -0.0158 -0.01000599999999999 0.008493199999999999 -0.0148 -0.003496999999999993 -0.0077473 -0.0158 -0.03000899999999999 0.0129797 -0.0158 -0.01000599999999999 0.008493199999999999 -0.0158 -0.01722999999999999 0.00062 -0.0153 -0.03000599999999999 0.0084797 -0.0158 -0.004453999999999993 -0.0072397 -0.0158 -0.03000899999999999 0.0129797 -0.0158 -0.003496999999999993 -0.0077473 -0.0158 -0.004453999999999993 -0.0072397 -0.0158 -0.03000599999999999 0.0084797 -0.0148 -0.03000599999999999 0.0084797 -0.0158 -0.01722999999999999 0.00062 -0.0153 -0.03000599999999999 0.0084797 -0.0148 -0.004453999999999993 -0.0072397 -0.0148 -0.03000799999999999 0.0119797 -0.0148 -0.01000599999999999 0.008493199999999999 -0.0148 -0.01000799999999999 0.0119932 -0.0148 -0.03000799999999999 0.0119797 -0.0148 -0.01000899999999999 0.0129932 -0.0158 -0.01000799999999999 0.0119932 -0.0148 -0.01000599999999999 0.008493199999999999 -0.0148 -0.01000599999999999 0.008493199999999999 -0.0148 0.001366000000000007 0.0085009 -0.0153 -0.01000599999999999 0.008493199999999999 -0.0158 -0.003496999999999993 -0.0077473 -0.0158 -0.01000599999999999 0.008493199999999999 -0.0158 0.01273690000000001 0.0085086 -0.0158 -0.004453999999999993 -0.0072397 -0.0148 -0.01722999999999999 0.00062 -0.0153 -0.004453999999999993 -0.0072397 -0.0158 -0.003975549999999993 -0.0074936 -0.01555 -0.003975989999999993 -0.0074935 -0.0153 -0.004453999999999993 -0.0072397 -0.0158 -0.003975549999999993 -0.0074936 -0.01555 -0.004453999999999993 -0.0072397 -0.0158 -0.003496999999999993 -0.0077473 -0.0158 -0.003975549999999993 -0.0074936 -0.01555 -0.003496999999999993 -0.0077473 -0.0158 -0.003975989999999993 -0.0074935 -0.0153 -0.03000599999999999 0.0084797 -0.0148 -0.01722999999999999 0.00062 -0.0153 -0.004453999999999993 -0.0072397 -0.0148 -0.004453999999999993 -0.0072397 -0.0148 -0.003496999999999993 -0.0077473 -0.0148 -0.03000799999999999 0.0119797 -0.0148 -0.003496999999999993 -0.0077473 -0.0148 -0.01000599999999999 0.008493199999999999 -0.0148 -0.03000799999999999 0.0119797 -0.0148 -0.01000599999999999 0.008493199999999999 -0.0158 0.001366000000000007 0.0085009 -0.0153 0.01273690000000001 0.0085086 -0.0158 0.01273690000000001 0.0085086 -0.0148 0.001366000000000007 0.0085009 -0.0153 -0.01000599999999999 0.008493199999999999 -0.0148 0.01273690000000001 0.0085086 -0.0158 0.004620000000000007 0.000380699 -0.0153 -0.003496999999999993 -0.0077473 -0.0158 -0.003975989999999993 -0.0074935 -0.0153 -0.004453999999999993 -0.0072397 -0.0148 -0.004214999999999993 -0.0073666 -0.0153 -0.004453999999999993 -0.0072397 -0.0148 -0.004453999999999993 -0.0072397 -0.0158 -0.004214999999999993 -0.0073666 -0.0153 -0.004453999999999993 -0.0072397 -0.0158 -0.003975989999999993 -0.0074935 -0.0153 -0.004214999999999993 -0.0073666 -0.0153 -0.003975989999999993 -0.0074935 -0.0153 -0.003496999999999993 -0.0077473 -0.0158 -0.003736499999999993 -0.0076204 -0.0153 -0.003496999999999993 -0.0077473 -0.0158 -0.003496999999999993 -0.0077473 -0.0148 -0.003736499999999993 -0.0076204 -0.0153 -0.003496999999999993 -0.0077473 -0.0148 -0.003975989999999993 -0.0074935 -0.0153 -0.003736499999999993 -0.0076204 -0.0153 -0.003975549999999993 -0.0074936 -0.01505 -0.003975989999999993 -0.0074935 -0.0153 -0.003496999999999993 -0.0077473 -0.0148 -0.003975549999999993 -0.0074936 -0.01505 -0.003496999999999993 -0.0077473 -0.0148 -0.004453999999999993 -0.0072397 -0.0148 -0.003975549999999993 -0.0074936 -0.01505 -0.004453999999999993 -0.0072397 -0.0148 -0.003975989999999993 -0.0074935 -0.0153 -0.003496999999999993 -0.0077473 -0.0148 0.01273690000000001 0.0085086 -0.0148 -0.01000599999999999 0.008493199999999999 -0.0148 0.01273690000000001 0.0085086 -0.0148 0.01273690000000001 0.0085086 -0.0158 0.001366000000000007 0.0085009 -0.0153 -0.003496999999999993 -0.0077473 -0.0158 0.004620000000000007 0.000380699 -0.0153 -0.003496999999999993 -0.0077473 -0.0148 0.01273690000000001 0.0085086 -0.0148 0.004620000000000007 0.000380699 -0.0153 0.01273690000000001 0.0085086 -0.0158 0.004620000000000007 0.000380699 -0.0153 0.01273690000000001 0.0085086 -0.0148 -0.003496999999999993 -0.0077473 -0.0148 -0.02886979999999999 0.0129805 -0.014 -0.02999999999999999 0.0129797 -0.014 -0.02999999999999999 0.018 -0.014 -0.02886979999999999 0.0129805 -0.014 -0.02999999999999999 0.018 -0.014 -0.02247719999999999 0.0129848 -0.014 -0.02999999999999999 0.0129797 0.014 -0.02886979999999999 0.0129805 0.014 -0.02999999999999999 0.018 0.014 -0.02886979999999999 0.0129805 0.014 -0.02852889999999999 0.0129807 0.014 -0.02999999999999999 0.018 0.014 -0.02852889999999999 0.0129807 0.014 -0.02099999999999999 0.018 0.014 -0.02999999999999999 0.018 0.014 -0.02999999999999999 0.018 0.014 -0.02999999999999999 0.0129797 0.00228598 -0.02999999999999999 0.0129797 0.014 -0.02999999999999999 0.018 0 -0.02999999999999999 0.0129797 0 -0.02999999999999999 0.0129797 0.00228598 -0.02999999999999999 0.018 0 -0.02999999999999999 0.0129797 0.00228598 -0.02999999999999999 0.018 0.014 -0.02999999999999999 0.018 0 -0.02999999999999999 0.0129797 -0.011714 -0.02999999999999999 0.0129797 0 -0.02999999999999999 0.018 -0.014 -0.02999999999999999 0.0129797 -0.014 -0.02999999999999999 0.0129797 -0.011714 -0.02999999999999999 0.018 -0.014 -0.02999999999999999 0.0129797 -0.011714 -0.02999999999999999 0.018 0 -0.02247719999999999 0.0129848 -0.014 -0.02999999999999999 0.018 -0.014 -0.02099999999999999 0.018 -0.014 -0.02099999999999999 0.0129858 -0.014 -0.02247719999999999 0.0129848 -0.014 -0.02099999999999999 0.018 -0.014 -0.01348629999999999 0.0129909 -0.014 -0.02099999999999999 0.018 -0.014 -0.01199999999999999 0.018 -0.014 -0.01199999999999999 0.0129919 -0.014 -0.01348629999999999 0.0129909 -0.014 -0.01199999999999999 0.018 -0.014 -0.02099999999999999 0.0129858 -0.014 -0.02099999999999999 0.018 -0.014 -0.01348629999999999 0.0129909 -0.014 -0.01199999999999999 0.018 -0.014 -0.01199999999999999 0.0129919 -0.00231435 -0.01199999999999999 0.0129919 -0.0126542 -0.01199999999999999 0.018 -0.014 -0.01199999999999999 0.0129919 -0.0126542 -0.01199999999999999 0.0129919 -0.014 -0.01199999999999999 0.0129919 0.014 -0.01199999999999999 0.018 0.014 -0.01951979999999999 0.0129868 0.014 -0.02099999999999999 0.0129858 0.014 -0.01951979999999999 0.0129868 0.014 -0.02099999999999999 0.018 0.014 -0.01951979999999999 0.0129868 0.014 -0.01199999999999999 0.018 0.014 -0.02099999999999999 0.018 0.014 -0.02099999999999999 0.0129858 0.014 -0.02099999999999999 0.018 0.014 -0.02852889999999999 0.0129807 0.014 -0.01199999999999999 0.018 0.014 -0.01199999999999999 0.0129919 0.014 -0.01199999999999999 0.0129919 0.0126542 -0.01199999999999999 0.018 0.014 -0.01199999999999999 0.0129919 0.0126542 -0.01199999999999999 0.0129919 0.0116856 -0.01199999999999999 0.018 0.014 -0.01199999999999999 0.0129919 0.0116856 -0.01199999999999999 0.018 0 -0.02999999999999999 0.018 0.014 -0.02099999999999999 0.018 0.014 -0.02999999999999999 0.018 0 -0.02999999999999999 0.018 -0.014 -0.02999999999999999 0.018 0 -0.02099999999999999 0.018 -0.014 -0.02099999999999999 0.018 -0.014 -0.01199999999999999 0.018 0 -0.01199999999999999 0.018 -0.014 -0.01199999999999999 0.018 0 -0.01199999999999999 0.0129919 0 -0.01199999999999999 0.0129919 -0.00231435 -0.01199999999999999 0.018 0 -0.01199999999999999 0.0129919 -0.00231435 -0.01199999999999999 0.018 -0.014 -0.01199999999999999 0.018 0 -0.01199999999999999 0.0129919 0.0116856 -0.01199999999999999 0.0129919 0 -0.02099999999999999 0.018 0.014 -0.01199999999999999 0.018 0.014 -0.01199999999999999 0.018 0 -0.01199999999999999 0.018 0 -0.02999999999999999 0.018 0 -0.02099999999999999 0.018 0.007 -0.02999999999999999 0.018 0 -0.02099999999999999 0.018 0.014 -0.02099999999999999 0.018 0.007 -0.02099999999999999 0.018 0.014 -0.01199999999999999 0.018 0 -0.02099999999999999 0.018 0.007 -0.02999999999999999 0.018 0 -0.01199999999999999 0.018 0 -0.02099999999999999 0.018 -0.007 -0.01199999999999999 0.018 0 -0.02099999999999999 0.018 -0.014 -0.02099999999999999 0.018 -0.007 -0.02099999999999999 0.018 -0.014 -0.02999999999999999 0.018 0 -0.02099999999999999 0.018 -0.007 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479

    -
    -
    - - - 6.938893903907228e-18 0 0 - 1 0 0 0 - - true - - - -
    - - - - 0.001999999999999997 0.00835 -0.0148 0.001999999999999997 0 -0.0153 0.001999999999999997 0.00835 -0.0158 0.001999999999999997 0 -0.0153 0.001999999999999997 0.00835 -0.0148 0.001999999999999997 -0.00835 -0.0148 -0.006000000000000004 0.009075 -0.0153 0.001999999999999997 0.00835 -0.0148 0.001999999999999997 0.00835 -0.0158 0.001999999999999997 0 -0.0153 0.001999999999999997 -0.00835 -0.0158 0.001999999999999997 0.00835 -0.0158 0.001999999999999997 -0.00835 -0.0148 0.001999999999999997 -0.00835 -0.0158 0.001999999999999997 0 -0.0153 0.001999999999999997 0.00835 -0.0148 -0.006000000000000004 0 -0.0148 -0.002000000000000004 0 -0.0148 0.001999999999999997 -0.00835 -0.0148 0.001999999999999997 0.00835 -0.0148 -0.002000000000000004 0 -0.0148 -0.006000000000000004 0 -0.0148 0.001999999999999997 -0.00835 -0.0148 -0.002000000000000004 0 -0.0148 -0.014 0.0098 -0.0158 -0.006000000000000004 0.009075 -0.0153 0.001999999999999997 0.00835 -0.0158 -0.006000000000000004 0.009075 -0.0153 -0.014 0.0098 -0.0148 0.001999999999999997 0.00835 -0.0148 0.001999999999999997 -0.00835 -0.0158 -0.009000000000000003 0 -0.0158 -0.003500000000000004 2.60209e-17 -0.0158 0.001999999999999997 0.00835 -0.0158 0.001999999999999997 -0.00835 -0.0158 -0.003500000000000004 2.60209e-17 -0.0158 -0.009000000000000003 0 -0.0158 0.001999999999999997 0.00835 -0.0158 -0.003500000000000004 2.60209e-17 -0.0158 0.001999999999999997 -0.00835 -0.0158 0.001999999999999997 -0.00835 -0.0148 -0.006000000000000004 -0.009075 -0.0153 -0.014 0.0098 -0.0148 -0.006000000000000004 0 -0.0148 -0.006000000000000004 0.0049 -0.0148 0.001999999999999997 0.00835 -0.0148 -0.014 0.0098 -0.0148 -0.006000000000000004 0.0049 -0.0148 -0.006000000000000004 0 -0.0148 0.001999999999999997 0.00835 -0.0148 -0.006000000000000004 0.0049 -0.0148 0.001999999999999997 -0.00835 -0.0148 -0.006000000000000004 0 -0.0148 -0.006000000000000004 -0.0049 -0.0148 -0.014 -0.0098 -0.0148 0.001999999999999997 -0.00835 -0.0148 -0.006000000000000004 -0.0049 -0.0148 -0.006000000000000004 0 -0.0148 -0.014 -0.0098 -0.0148 -0.006000000000000004 -0.0049 -0.0148 -0.014 0.0098 -0.0158 -0.014 0.0098 -0.0148 -0.006000000000000004 0.009075 -0.0153 -0.009000000000000003 0 -0.0158 -0.014 0.0098 -0.0158 0.001999999999999997 0.00835 -0.0158 -0.014 -0.0098 -0.0158 -0.009000000000000003 0 -0.0158 0.001999999999999997 -0.00835 -0.0158 -0.006000000000000004 -0.009075 -0.0153 0.001999999999999997 -0.00835 -0.0148 -0.014 -0.0098 -0.0148 0.001999999999999997 -0.00835 -0.0158 -0.006000000000000004 -0.009075 -0.0153 -0.014 -0.0098 -0.0158 -0.014 -0.0098 -0.0148 -0.006000000000000004 0 -0.0148 -0.01 -6.93889e-18 -0.0148 -0.014 0.0098 -0.0148 -0.014 -0.0098 -0.0148 -0.01 -6.93889e-18 -0.0148 -0.006000000000000004 0 -0.0148 -0.014 0.0098 -0.0148 -0.01 -6.93889e-18 -0.0148 -0.0143333 0.0098 0 -0.014 0.0098 -0.0148 -0.014 0.0098 -0.0158 -0.015 0.0098 -0.0158 -0.014 0.0098 -0.0158 -0.009000000000000003 0 -0.0158 -0.015 -0.0098 -0.0158 -0.009000000000000003 0 -0.0158 -0.014 -0.0098 -0.0158 -0.006000000000000004 -0.009075 -0.0153 -0.014 -0.0098 -0.0148 -0.014 -0.0098 -0.0158 -0.014 0.0098 -0.0148 -0.014 0 0 -0.014 0 -0.0074 -0.014 -0.0098 -0.0148 -0.014 0.0098 -0.0148 -0.014 0 -0.0074 -0.014 0 0 -0.014 -0.0098 -0.0148 -0.014 0 -0.0074 -0.014 0.0098 -0.0158 -0.015 0.0098 -0.0158 -0.0143333 0.0098 0 -0.0143333 0.0098 0 -0.014 0.0098 0.0148 -0.014 0.0098 -0.0148 -0.015 0.0098 -0.0158 -0.009000000000000003 0 -0.0158 -0.012 6.93889e-18 -0.0158 -0.015 -0.0098 -0.0158 -0.015 0.0098 -0.0158 -0.012 6.93889e-18 -0.0158 -0.009000000000000003 0 -0.0158 -0.015 -0.0098 -0.0158 -0.012 6.93889e-18 -0.0158 -0.0143333 -0.0098 0 -0.015 -0.0098 -0.0158 -0.014 -0.0098 -0.0158 -0.0143333 -0.0098 0 -0.014 -0.0098 -0.0158 -0.014 -0.0098 -0.0148 -0.014 0.0098 0.0148 -0.014 0 0 -0.014 0.0049 -1.30104e-17 -0.014 0.0098 -0.0148 -0.014 0.0098 0.0148 -0.014 0.0049 -1.30104e-17 -0.014 0 0 -0.014 0.0098 -0.0148 -0.014 0.0049 -1.30104e-17 -0.014 -0.0098 -0.0148 -0.014 0 0 -0.014 -0.0049 0 -0.014 -0.0098 0.0148 -0.014 -0.0098 -0.0148 -0.014 -0.0049 0 -0.014 0 0 -0.014 -0.0098 0.0148 -0.014 -0.0049 0 -0.015 0.0098 -0.0158 -0.015 0.0098 -0.0125 -0.0149 0.0098 -0.0125 -0.015 0.0098 0.0125 -0.015 0.0098 0.0158 -0.0149 0.0098 0.0125 -0.0149 0.0098 0.0125 -0.0143333 0.0098 0 -0.0149 0.0098 -0.0125 -0.0143333 0.0098 0 -0.015 0.0098 -0.0158 -0.0149 0.0098 -0.0125 -0.0149 0.0098 0.0125 -0.015 0.0098 0.0158 -0.0143333 0.0098 0 -0.0143333 0.0098 0 -0.014 0.0098 0.0158 -0.014 0.0098 0.0148 -0.015 -0.0098 -0.0158 -0.015 -0.00775316 -0.0125 -0.015 -1.73472e-18 -0.01415 -0.015 0.0098 -0.0158 -0.015 -0.0098 -0.0158 -0.015 -1.73472e-18 -0.01415 -0.015 0.00775316 -0.0125 -0.015 0.0098 -0.0158 -0.015 -1.73472e-18 -0.01415 -0.015 -0.00775316 -0.0125 -0.015 0.00775316 -0.0125 -0.015 -1.73472e-18 -0.01415 -0.015 -0.0098 0.0158 -0.015 -0.0098 0.0125 -0.0149 -0.0098 0.0125 -0.0143333 -0.0098 0 -0.0149 -0.0098 0.0110577 -0.0149 -0.0098 -0.0110577 -0.0149 -0.0098 -0.0125 -0.015 -0.0098 -0.0125 -0.015 -0.0098 -0.0158 -0.0149 -0.0098 0.0110577 -0.0143333 -0.0098 0 -0.0149 -0.0098 0.0125 -0.0143333 -0.0098 0 -0.015 -0.0098 0.0158 -0.0149 -0.0098 0.0125 -0.0143333 -0.0098 0 -0.0149 -0.0098 -0.0125 -0.015 -0.0098 -0.0158 -0.0143333 -0.0098 0 -0.0149 -0.0098 -0.0110577 -0.0149 -0.0098 -0.0125 -0.0143333 -0.0098 0 -0.014 -0.0098 -0.0148 -0.014 -0.0098 0.0148 -0.014 -0.0098 0.0148 -0.014 0 0 -0.014 -6.93889e-18 0.0074 -0.014 0.0098 0.0148 -0.014 -0.0098 0.0148 -0.014 -6.93889e-18 0.0074 -0.014 0 0 -0.014 0.0098 0.0148 -0.014 -6.93889e-18 0.0074 -0.0143333 0.0098 0 -0.015 0.0098 0.0158 -0.014 0.0098 0.0158 -0.015 0.0098 0.0125 -0.015 0.00976894 0.0125 -0.015 0.0098 0.0158 -0.015 0.0097419 0.0125 -0.015 0.00775316 0.0125 -0.015 0.0098 0.0158 -0.015 0.009752500000000001 0.0125 -0.015 0.0098 0.0158 -0.015 0.0097419 0.0125 -0.015 0.00975934 0.0125 -0.015 0.0098 0.0158 -0.015 0.009752500000000001 0.0125 -0.015 0.00976894 0.0125 -0.015 0.0098 0.0158 -0.015 0.00975934 0.0125 -0.015 0.0098 0.0124302 -0.0149 0.0098 0.0125 -0.015 0.0098 0.0125 -0.015 0.0098 -0.0124302 -0.015 0.0098 0.0124302 -0.0149 0.0098 0.0125 -0.0149 0.0098 -0.0125 -0.015 0.0098 -0.0124302 -0.0149 0.0098 0.0125 -0.015 0.0098 -0.0125 -0.0149 0.0098 -0.0125 -0.015 0.0098 -0.0124302 -0.015 0.0098 -0.0158 -0.015 0.00775316 -0.0125 -0.015 0.0097419 -0.0125 -0.015 0.0098 -0.0158 -0.015 0.00975208 -0.0125 -0.015 0.0097419 -0.0125 -0.015 0.0098 -0.0158 -0.015 0.009759169999999999 -0.0125 -0.015 0.00975208 -0.0125 -0.015 0.0098 -0.0158 -0.015 0.009769140000000001 -0.0125 -0.015 0.009759169999999999 -0.0125 -0.015 0.0098 -0.0158 -0.015 0.009769140000000001 -0.0125 -0.015 0.0098 -0.0125 -0.014 0.0098 0.0148 -0.014 0.0098 0.0158 -0.006000000000000004 0.009075 0.0153 -0.015 -0.0098 -0.0158 -0.015 -0.0098 -0.0125 -0.015 -0.00775316 -0.0125 -0.05070000000000001 -0.011 -0.0125 -0.015 0.0097419 -0.0125 -0.015 0.00775316 -0.0125 -0.05070000000000001 -0.011 -0.0125 -0.015 0.00775316 -0.0125 -0.015 -0.00775316 -0.0125 -0.05070000000000001 -0.011 -0.0125 -0.015 -0.00775316 -0.0125 -0.015 -0.0098 -0.0125 -0.015 -0.0098 -0.0125 -0.0149 -0.0098 -0.0125 -0.0149 -0.011 -0.0125 -0.05070000000000001 -0.011 -0.0125 -0.015 -0.0098 -0.0125 -0.0149 -0.011 -0.0125 -0.0149 -0.0098 -0.0110577 -0.0149 -0.0098 0.0110577 -0.0149 -0.0104 7.806259999999999e-18 -0.0149 -0.011 -0.0125 -0.0149 -0.0098 -0.0110577 -0.0149 -0.0104 7.806259999999999e-18 -0.0149 -0.011 0.0125 -0.0149 -0.011 -0.0125 -0.0149 -0.0104 7.806259999999999e-18 -0.0149 -0.0098 0.0110577 -0.0149 -0.011 0.0125 -0.0149 -0.0104 7.806259999999999e-18 -0.0149 -0.0098 0.0125 -0.0149 -0.011 0.0125 -0.0149 -0.0098 0.0110577 -0.0149 -0.0098 0.0125 -0.015 -0.0098 0.0125 -0.0149 -0.011 0.0125 -0.015 -0.0098 0.0125 -0.015 -0.00775316 0.0125 -0.05070000000000001 -0.011 0.0125 -0.015 0.00775316 0.0125 -0.015 0.0097419 0.0125 -0.05070000000000001 -0.011 0.0125 -0.015 -0.00775316 0.0125 -0.015 0.00775316 0.0125 -0.05070000000000001 -0.011 0.0125 -0.0149 -0.011 0.0125 -0.015 -0.0098 0.0125 -0.05070000000000001 -0.011 0.0125 -0.015 -0.00775316 0.0125 -0.015 -0.0098 0.0125 -0.015 -0.0098 0.0158 -0.014 -0.0098 0.0158 -0.015 -0.0098 0.0158 -0.0143333 -0.0098 0 -0.0149 -0.0098 -0.0110577 -0.0149 -0.011 -0.0125 -0.0149 -0.0098 -0.0125 -0.0143333 -0.0098 0 -0.014 -0.0098 0.0148 -0.014 -0.0098 0.0158 -0.014 0.0098 0.0148 -0.006000000000000004 0 0.0148 -0.01 4.33681e-18 0.0148 -0.014 -0.0098 0.0148 -0.014 0.0098 0.0148 -0.01 4.33681e-18 0.0148 -0.006000000000000004 0 0.0148 -0.014 -0.0098 0.0148 -0.01 4.33681e-18 0.0148 -0.014 0.0098 0.0158 -0.015 0.0098 0.0158 -0.009000000000000003 0 0.0158 -0.015 0.00976894 0.0125 -0.015 0.0098 0.0125 -0.03285 0.0059253 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.015 0.00976894 0.0125 -0.03285 0.0059253 0.0125 -0.05070000000000001 0.0098 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.03285 0.0059253 0.0125 -0.015 0.0098 0.0125 -0.05070000000000001 0.0098 0.0125 -0.03285 0.0059253 0.0125 -0.015 0.0098 0.0158 -0.015 0.00775316 0.0125 -0.015 8.673619999999999e-18 0.01415 -0.015 -0.0098 0.0158 -0.015 0.0098 0.0158 -0.015 8.673619999999999e-18 0.01415 -0.015 -0.00775316 0.0125 -0.015 -0.0098 0.0158 -0.015 8.673619999999999e-18 0.01415 -0.015 0.00775316 0.0125 -0.015 -0.00775316 0.0125 -0.015 8.673619999999999e-18 0.01415 -0.015 0.0097419 0.0125 -0.015 0.009752500000000001 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.015 0.0097419 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.05070000000000001 -0.011 0.0125 -0.015 0.009752500000000001 0.0125 -0.015 0.00975934 0.0125 -0.03900000000000001 0 0.0125 -0.015 0.009752500000000001 0.0125 -0.03900000000000001 0 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.015 0.00975934 0.0125 -0.015 0.00976894 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.015 0.00975934 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.03900000000000001 0 0.0125 -0.015 0.0098 0.0125 -0.015 0.0098 0.0124302 -0.03285 0.0098 0.00625 -0.05070000000000001 0.0098 0.0125 -0.015 0.0098 0.0125 -0.03285 0.0098 0.00625 -0.03280000000000001 0.0098 0 -0.05070000000000001 0.0098 0.0125 -0.03285 0.0098 0.00625 -0.015 0.0098 0.0124302 -0.03280000000000001 0.0098 0 -0.03285 0.0098 0.00625 -0.015 0.0098 0.0124302 -0.015 0.0098 -0.0124302 -0.0239 0.0098 0 -0.03280000000000001 0.0098 0 -0.015 0.0098 0.0124302 -0.0239 0.0098 0 -0.015 0.0098 -0.0124302 -0.03280000000000001 0.0098 0 -0.0239 0.0098 0 -0.05070000000000001 0.0098 -0.0125 -0.03280000000000001 0.0098 0 -0.03285 0.0098 -0.00625 -0.015 0.0098 -0.0125 -0.05070000000000001 0.0098 -0.0125 -0.03285 0.0098 -0.00625 -0.015 0.0098 -0.0124302 -0.015 0.0098 -0.0125 -0.03285 0.0098 -0.00625 -0.03280000000000001 0.0098 0 -0.015 0.0098 -0.0124302 -0.03285 0.0098 -0.00625 -0.015 0.0098 -0.0125 -0.015 0.009769140000000001 -0.0125 -0.03285 0.00596065 -0.0125 -0.05070000000000001 0.0098 -0.0125 -0.015 0.0098 -0.0125 -0.03285 0.00596065 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.05070000000000001 0.0098 -0.0125 -0.03285 0.00596065 -0.0125 -0.015 0.009769140000000001 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.03285 0.00596065 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.015 0.009769140000000001 -0.0125 -0.015 0.009759169999999999 -0.0125 -0.0389 0 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.015 0.009759169999999999 -0.0125 -0.0389 0 -0.0125 -0.015 0.009759169999999999 -0.0125 -0.015 0.00975208 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.0389 0 -0.0125 -0.015 0.00975208 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.015 0.00975208 -0.0125 -0.015 0.0097419 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.015 0.0097419 -0.0125 -0.05070000000000001 -0.011 -0.0125 -0.006000000000000004 0.009075 0.0153 -0.014 0.0098 0.0158 0.001999999999999997 0.00835 0.0158 -0.014 0.0098 0.0148 -0.006000000000000004 0.009075 0.0153 0.001999999999999997 0.00835 0.0148 -0.0149 -0.011 -0.0125 -0.03280000000000001 -0.011 0 -0.03280000000000001 -0.011 -0.00625 -0.05070000000000001 -0.011 -0.0125 -0.0149 -0.011 -0.0125 -0.03280000000000001 -0.011 -0.00625 -0.03280000000000001 -0.011 0 -0.05070000000000001 -0.011 -0.0125 -0.03280000000000001 -0.011 -0.00625 -0.0149 -0.011 0.0125 -0.03280000000000001 -0.011 0 -0.02385 -0.011 1.99493e-17 -0.0149 -0.011 -0.0125 -0.0149 -0.011 0.0125 -0.02385 -0.011 1.99493e-17 -0.03280000000000001 -0.011 0 -0.0149 -0.011 -0.0125 -0.02385 -0.011 1.99493e-17 -0.05070000000000001 -0.011 0.0125 -0.03280000000000001 -0.011 0 -0.03280000000000001 -0.011 0.00625 -0.0149 -0.011 0.0125 -0.05070000000000001 -0.011 0.0125 -0.03280000000000001 -0.011 0.00625 -0.03280000000000001 -0.011 0 -0.0149 -0.011 0.0125 -0.03280000000000001 -0.011 0.00625 -0.014 -0.0098 0.0158 -0.009000000000000003 0 0.0158 -0.015 -0.0098 0.0158 -0.006000000000000004 -0.009075 0.0153 -0.014 -0.0098 0.0158 -0.014 -0.0098 0.0148 0.001999999999999997 0.00835 0.0148 -0.006000000000000004 0 0.0148 -0.006000000000000004 0.0049 0.0148 -0.014 0.0098 0.0148 0.001999999999999997 0.00835 0.0148 -0.006000000000000004 0.0049 0.0148 -0.006000000000000004 0 0.0148 -0.014 0.0098 0.0148 -0.006000000000000004 0.0049 0.0148 -0.014 -0.0098 0.0148 -0.006000000000000004 0 0.0148 -0.006000000000000004 -0.0049 0.0148 0.001999999999999997 -0.00835 0.0148 -0.014 -0.0098 0.0148 -0.006000000000000004 -0.0049 0.0148 -0.006000000000000004 0 0.0148 0.001999999999999997 -0.00835 0.0148 -0.006000000000000004 -0.0049 0.0148 -0.015 -0.0098 0.0158 -0.009000000000000003 0 0.0158 -0.012 0 0.0158 -0.015 0.0098 0.0158 -0.015 -0.0098 0.0158 -0.012 0 0.0158 -0.009000000000000003 0 0.0158 -0.015 0.0098 0.0158 -0.012 0 0.0158 0.001999999999999997 0.00835 0.0158 -0.014 0.0098 0.0158 -0.009000000000000003 0 0.0158 -0.03984900000000001 0.0020506 0.0125 -0.05070000000000001 0.0098 0.0125 -0.04190000000000001 0.0029 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.04190000000000001 -0.0029 0.0125 -0.05070000000000001 -0.011 0.0125 -0.03900000000000001 0 0.0125 -0.039425 -0.0010253 0.01415 -0.03942470000000001 -0.00102521 0.013325 -0.03984900000000001 -0.0020506 0.0125 -0.03900000000000001 0 0.0125 -0.03942470000000001 -0.00102521 0.013325 -0.039425 -0.0010253 0.01415 -0.03984900000000001 -0.0020506 0.0125 -0.03942470000000001 -0.00102521 0.013325 -0.039425 0.0010253 0.01415 -0.03942470000000001 0.00102521 0.013325 -0.03984900000000001 0.0020506 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.03942470000000001 0.00102521 0.013325 -0.03900000000000001 0 0.0125 -0.03900000000000001 0 0.0125 -0.03942470000000001 0.00102521 0.013325 -0.039425 0.0010253 0.01415 -0.05070000000000001 0.0098 0.0125 -0.03280000000000001 0.0098 0 -0.04175000000000001 0.0098 1.47451e-17 -0.05070000000000001 0.0098 -0.0125 -0.05070000000000001 0.0098 0.0125 -0.04175000000000001 0.0098 1.47451e-17 -0.03280000000000001 0.0098 0 -0.05070000000000001 0.0098 -0.0125 -0.04175000000000001 0.0098 1.47451e-17 -0.03977900000000001 0.0021213 -0.0125 -0.04190000000000001 0.003 -0.0125 -0.05070000000000001 0.0098 -0.0125 -0.0389 0 -0.0125 -0.039339 0.0010607 -0.01415 -0.03933930000000001 0.00106074 -0.013325 -0.03977900000000001 0.0021213 -0.0125 -0.0389 0 -0.0125 -0.03933930000000001 0.00106074 -0.013325 -0.039339 0.0010607 -0.01415 -0.03977900000000001 0.0021213 -0.0125 -0.03933930000000001 0.00106074 -0.013325 -0.03977900000000001 -0.0021213 -0.0125 -0.039339 -0.0010607 -0.01415 -0.03933930000000001 -0.00106074 -0.013325 -0.0389 0 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.03933930000000001 -0.00106074 -0.013325 -0.039339 -0.0010607 -0.01415 -0.0389 0 -0.0125 -0.03933930000000001 -0.00106074 -0.013325 -0.03977900000000001 -0.0021213 -0.0125 -0.05070000000000001 -0.011 -0.0125 -0.04190000000000001 -0.003 -0.0125 -0.006000000000000004 0.009075 0.0153 0.001999999999999997 0.00835 0.0158 0.001999999999999997 0.00835 0.0148 -0.05070000000000001 -0.011 -0.0125 -0.03280000000000001 -0.011 0 -0.04175000000000001 -0.011 -1.56125e-17 -0.05070000000000001 -0.011 0.0125 -0.05070000000000001 -0.011 -0.0125 -0.04175000000000001 -0.011 -1.56125e-17 -0.03280000000000001 -0.011 0 -0.05070000000000001 -0.011 0.0125 -0.04175000000000001 -0.011 -1.56125e-17 0.001999999999999997 -0.00835 0.0158 -0.009000000000000003 0 0.0158 -0.014 -0.0098 0.0158 -0.006000000000000004 -0.009075 0.0153 -0.014 -0.0098 0.0148 0.001999999999999997 -0.00835 0.0148 -0.006000000000000004 -0.009075 0.0153 0.001999999999999997 -0.00835 0.0158 -0.014 -0.0098 0.0158 0.001999999999999997 -0.00835 0.0148 -0.006000000000000004 0 0.0148 -0.002000000000000004 1.99493e-17 0.0148 0.001999999999999997 0.00835 0.0148 0.001999999999999997 -0.00835 0.0148 -0.002000000000000004 1.99493e-17 0.0148 -0.006000000000000004 0 0.0148 0.001999999999999997 0.00835 0.0148 -0.002000000000000004 1.99493e-17 0.0148 0.001999999999999997 0.00835 0.0158 -0.009000000000000003 0 0.0158 -0.003500000000000004 0 0.0158 0.001999999999999997 -0.00835 0.0158 0.001999999999999997 0.00835 0.0158 -0.003500000000000004 0 0.0158 -0.009000000000000003 0 0.0158 0.001999999999999997 -0.00835 0.0158 -0.003500000000000004 0 0.0158 -0.04087500000000001 0.0024753 0.01415 -0.04087450000000001 0.00247521 0.013325 -0.04190000000000001 0.0029 0.0125 -0.04190000000000001 0.0029 0.0125 -0.04087450000000001 0.00247521 0.013325 -0.03984900000000001 0.0020506 0.0125 -0.03984900000000001 0.0020506 0.0125 -0.04087450000000001 0.00247521 0.013325 -0.04087500000000001 0.0024753 0.01415 -0.04190000000000001 0.0029 0.0125 -0.05070000000000001 0.0098 0.0125 -0.043951 0.0020506 0.0125 -0.04190000000000001 -0.0029 0.0125 -0.043951 -0.0020506 0.0125 -0.05070000000000001 -0.011 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.04087500000000001 -0.0024753 0.01415 -0.04087450000000001 -0.00247521 0.013325 -0.04190000000000001 -0.0029 0.0125 -0.03984900000000001 -0.0020506 0.0125 -0.04087450000000001 -0.00247521 0.013325 -0.04087500000000001 -0.0024753 0.01415 -0.04190000000000001 -0.0029 0.0125 -0.04087450000000001 -0.00247521 0.013325 -0.03900000000000001 0 0.0158 -0.039425 -0.0010253 0.01415 -0.0392125 -0.00051265 0.01415 -0.03900000000000001 0 0.0125 -0.03900000000000001 0 0.0158 -0.0392125 -0.00051265 0.01415 -0.039425 -0.0010253 0.01415 -0.03900000000000001 0 0.0125 -0.0392125 -0.00051265 0.01415 -0.03984900000000001 -0.0020506 0.0125 -0.039425 -0.0010253 0.01415 -0.03963700000000001 -0.00153795 0.01415 -0.03984900000000001 -0.0020506 0.0158 -0.03984900000000001 -0.0020506 0.0125 -0.03963700000000001 -0.00153795 0.01415 -0.039425 -0.0010253 0.01415 -0.03984900000000001 -0.0020506 0.0158 -0.03963700000000001 -0.00153795 0.01415 -0.03984900000000001 0.0020506 0.0158 -0.039425 0.0010253 0.01415 -0.03963700000000001 0.00153795 0.01415 -0.03984900000000001 0.0020506 0.0125 -0.03984900000000001 0.0020506 0.0158 -0.03963700000000001 0.00153795 0.01415 -0.039425 0.0010253 0.01415 -0.03984900000000001 0.0020506 0.0125 -0.03963700000000001 0.00153795 0.01415 -0.03900000000000001 0 0.0125 -0.039425 0.0010253 0.01415 -0.0392125 0.00051265 0.01415 -0.03900000000000001 0 0.0158 -0.03900000000000001 0 0.0125 -0.0392125 0.00051265 0.01415 -0.039425 0.0010253 0.01415 -0.03900000000000001 0 0.0158 -0.0392125 0.00051265 0.01415 -0.05070000000000001 0.0098 -0.0125 -0.05070000000000001 -0.000599999 0 -0.05070000000000001 0.0046 1.64799e-17 -0.05070000000000001 0.0098 0.0125 -0.05070000000000001 0.0098 -0.0125 -0.05070000000000001 0.0046 1.64799e-17 -0.05070000000000001 -0.000599999 0 -0.05070000000000001 0.0098 0.0125 -0.05070000000000001 0.0046 1.64799e-17 -0.044021 0.0021213 -0.0125 -0.05070000000000001 0.0098 -0.0125 -0.04190000000000001 0.003 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.040839 0.0025607 -0.01415 -0.0408395 0.00256076 -0.013325 -0.04190000000000001 0.003 -0.0125 -0.03977900000000001 0.0021213 -0.0125 -0.0408395 0.00256076 -0.013325 -0.040839 0.0025607 -0.01415 -0.04190000000000001 0.003 -0.0125 -0.0408395 0.00256076 -0.013325 -0.0389 0 -0.0158 -0.039339 0.0010607 -0.01415 -0.0391195 0.00053035 -0.01415 -0.0389 0 -0.0125 -0.0389 0 -0.0158 -0.0391195 0.00053035 -0.01415 -0.039339 0.0010607 -0.01415 -0.0389 0 -0.0125 -0.0391195 0.00053035 -0.01415 -0.03977900000000001 0.0021213 -0.0125 -0.039339 0.0010607 -0.01415 -0.039559 0.001591 -0.01415 -0.03977900000000001 0.0021213 -0.0158 -0.03977900000000001 0.0021213 -0.0125 -0.039559 0.001591 -0.01415 -0.039339 0.0010607 -0.01415 -0.03977900000000001 0.0021213 -0.0158 -0.039559 0.001591 -0.01415 -0.03977900000000001 -0.0021213 -0.0158 -0.039339 -0.0010607 -0.01415 -0.039559 -0.001591 -0.01415 -0.03977900000000001 -0.0021213 -0.0125 -0.03977900000000001 -0.0021213 -0.0158 -0.039559 -0.001591 -0.01415 -0.039339 -0.0010607 -0.01415 -0.03977900000000001 -0.0021213 -0.0125 -0.039559 -0.001591 -0.01415 -0.0389 0 -0.0125 -0.039339 -0.0010607 -0.01415 -0.0391195 -0.00053035 -0.01415 -0.0389 0 -0.0158 -0.0389 0 -0.0125 -0.0391195 -0.00053035 -0.01415 -0.039339 -0.0010607 -0.01415 -0.0389 0 -0.0158 -0.0391195 -0.00053035 -0.01415 -0.040839 -0.0025607 -0.01415 -0.0408395 -0.00256076 -0.013325 -0.04190000000000001 -0.003 -0.0125 -0.04190000000000001 -0.003 -0.0125 -0.0408395 -0.00256076 -0.013325 -0.03977900000000001 -0.0021213 -0.0125 -0.03977900000000001 -0.0021213 -0.0125 -0.0408395 -0.00256076 -0.013325 -0.040839 -0.0025607 -0.01415 -0.05070000000000001 -0.011 -0.0125 -0.044021 -0.0021213 -0.0125 -0.04190000000000001 -0.003 -0.0125 0.001999999999999997 0.00835 0.0158 0.001999999999999997 0 0.0153 0.001999999999999997 0.00835 0.0148 -0.05070000000000001 -0.011 0.0125 -0.05070000000000001 -0.000599999 0 -0.05070000000000001 -0.0058 -7.806259999999999e-18 -0.05070000000000001 -0.011 -0.0125 -0.05070000000000001 -0.011 0.0125 -0.05070000000000001 -0.0058 -7.806259999999999e-18 -0.05070000000000001 -0.000599999 0 -0.05070000000000001 -0.011 -0.0125 -0.05070000000000001 -0.0058 -7.806259999999999e-18 0.001999999999999997 -0.00835 0.0148 0.001999999999999997 -0.00835 0.0158 -0.006000000000000004 -0.009075 0.0153 0.001999999999999997 0 0.0153 0.001999999999999997 -0.00835 0.0148 0.001999999999999997 0.00835 0.0148 0.001999999999999997 0 0.0153 0.001999999999999997 0.00835 0.0158 0.001999999999999997 -0.00835 0.0158 -0.04190000000000001 0.0029 0.0158 -0.04087500000000001 0.0024753 0.01415 -0.04138750000000001 0.00268765 0.01415 -0.04190000000000001 0.0029 0.0125 -0.04190000000000001 0.0029 0.0158 -0.04138750000000001 0.00268765 0.01415 -0.04087500000000001 0.0024753 0.01415 -0.04190000000000001 0.0029 0.0125 -0.04138750000000001 0.00268765 0.01415 -0.03984900000000001 0.0020506 0.0125 -0.04087500000000001 0.0024753 0.01415 -0.04036200000000001 0.00226295 0.01415 -0.03984900000000001 0.0020506 0.0158 -0.03984900000000001 0.0020506 0.0125 -0.04036200000000001 0.00226295 0.01415 -0.04087500000000001 0.0024753 0.01415 -0.03984900000000001 0.0020506 0.0158 -0.04036200000000001 0.00226295 0.01415 -0.043951 0.0020506 0.0125 -0.042925 0.0024753 0.01415 -0.04292550000000001 0.00247521 0.013325 -0.04190000000000001 0.0029 0.0125 -0.043951 0.0020506 0.0125 -0.04292550000000001 0.00247521 0.013325 -0.042925 0.0024753 0.01415 -0.04190000000000001 0.0029 0.0125 -0.04292550000000001 0.00247521 0.013325 -0.043951 0.0020506 0.0125 -0.05070000000000001 0.0098 0.0125 -0.05070000000000001 -0.011 0.0125 -0.043951 -0.0020506 0.0125 -0.04480000000000001 0 0.0125 -0.05070000000000001 -0.011 0.0125 -0.04190000000000001 -0.0029 0.0125 -0.042925 -0.0024753 0.01415 -0.04292550000000001 -0.00247521 0.013325 -0.043951 -0.0020506 0.0125 -0.04190000000000001 -0.0029 0.0125 -0.04292550000000001 -0.00247521 0.013325 -0.042925 -0.0024753 0.01415 -0.043951 -0.0020506 0.0125 -0.04292550000000001 -0.00247521 0.013325 -0.03984900000000001 -0.0020506 0.0158 -0.04087500000000001 -0.0024753 0.01415 -0.04036200000000001 -0.00226295 0.01415 -0.03984900000000001 -0.0020506 0.0125 -0.03984900000000001 -0.0020506 0.0158 -0.04036200000000001 -0.00226295 0.01415 -0.04087500000000001 -0.0024753 0.01415 -0.03984900000000001 -0.0020506 0.0125 -0.04036200000000001 -0.00226295 0.01415 -0.04190000000000001 -0.0029 0.0125 -0.04087500000000001 -0.0024753 0.01415 -0.04138750000000001 -0.00268765 0.01415 -0.04190000000000001 -0.0029 0.0158 -0.04190000000000001 -0.0029 0.0125 -0.04138750000000001 -0.00268765 0.01415 -0.04087500000000001 -0.0024753 0.01415 -0.04190000000000001 -0.0029 0.0158 -0.04138750000000001 -0.00268765 0.01415 -0.03984900000000001 -0.0020506 0.0158 -0.039425 -0.0010253 0.01415 -0.03942470000000001 -0.00102521 0.014975 -0.03900000000000001 0 0.0158 -0.03984900000000001 -0.0020506 0.0158 -0.03942470000000001 -0.00102521 0.014975 -0.039425 -0.0010253 0.01415 -0.03900000000000001 0 0.0158 -0.03942470000000001 -0.00102521 0.014975 -0.03900000000000001 0 0.0158 -0.039425 0.0010253 0.01415 -0.03942470000000001 0.00102521 0.014975 -0.03984900000000001 0.0020506 0.0158 -0.03900000000000001 0 0.0158 -0.03942470000000001 0.00102521 0.014975 -0.039425 0.0010253 0.01415 -0.03984900000000001 0.0020506 0.0158 -0.03942470000000001 0.00102521 0.014975 -0.05070000000000001 -0.011 -0.0125 -0.05070000000000001 -0.000599999 0 -0.05070000000000001 -0.0005999999999999999 -0.00625 -0.05070000000000001 0.0098 -0.0125 -0.05070000000000001 -0.011 -0.0125 -0.05070000000000001 -0.0005999999999999999 -0.00625 -0.05070000000000001 -0.000599999 0 -0.05070000000000001 0.0098 -0.0125 -0.05070000000000001 -0.0005999999999999999 -0.00625 -0.05070000000000001 0.0098 0.0125 -0.05070000000000001 -0.000599999 0 -0.05070000000000001 -0.0005999999999999999 0.00625 -0.05070000000000001 -0.011 0.0125 -0.05070000000000001 0.0098 0.0125 -0.05070000000000001 -0.0005999999999999999 0.00625 -0.05070000000000001 -0.000599999 0 -0.05070000000000001 -0.011 0.0125 -0.05070000000000001 -0.0005999999999999999 0.00625 -0.05070000000000001 0.0098 -0.0125 -0.044021 0.0021213 -0.0125 -0.05070000000000001 -0.011 -0.0125 -0.042961 0.0025607 -0.01415 -0.0429605 0.00256076 -0.013325 -0.04190000000000001 0.003 -0.0125 -0.04190000000000001 0.003 -0.0125 -0.0429605 0.00256076 -0.013325 -0.044021 0.0021213 -0.0125 -0.044021 0.0021213 -0.0125 -0.0429605 0.00256076 -0.013325 -0.042961 0.0025607 -0.01415 -0.03977900000000001 0.0021213 -0.0158 -0.040839 0.0025607 -0.01415 -0.040309 0.002341 -0.01415 -0.03977900000000001 0.0021213 -0.0125 -0.03977900000000001 0.0021213 -0.0158 -0.040309 0.002341 -0.01415 -0.040839 0.0025607 -0.01415 -0.03977900000000001 0.0021213 -0.0125 -0.040309 0.002341 -0.01415 -0.04190000000000001 0.003 -0.0125 -0.040839 0.0025607 -0.01415 -0.0413695 0.00278035 -0.01415 -0.04190000000000001 0.003 -0.0158 -0.04190000000000001 0.003 -0.0125 -0.0413695 0.00278035 -0.01415 -0.040839 0.0025607 -0.01415 -0.04190000000000001 0.003 -0.0158 -0.0413695 0.00278035 -0.01415 -0.03977900000000001 0.0021213 -0.0158 -0.039339 0.0010607 -0.01415 -0.03933930000000001 0.00106074 -0.014975 -0.0389 0 -0.0158 -0.03977900000000001 0.0021213 -0.0158 -0.03933930000000001 0.00106074 -0.014975 -0.039339 0.0010607 -0.01415 -0.0389 0 -0.0158 -0.03933930000000001 0.00106074 -0.014975 -0.0389 0 -0.0158 -0.039339 -0.0010607 -0.01415 -0.03933930000000001 -0.00106074 -0.014975 -0.03977900000000001 -0.0021213 -0.0158 -0.0389 0 -0.0158 -0.03933930000000001 -0.00106074 -0.014975 -0.039339 -0.0010607 -0.01415 -0.03977900000000001 -0.0021213 -0.0158 -0.03933930000000001 -0.00106074 -0.014975 -0.03977900000000001 -0.0021213 -0.0125 -0.040839 -0.0025607 -0.01415 -0.040309 -0.002341 -0.01415 -0.03977900000000001 -0.0021213 -0.0158 -0.03977900000000001 -0.0021213 -0.0125 -0.040309 -0.002341 -0.01415 -0.040839 -0.0025607 -0.01415 -0.03977900000000001 -0.0021213 -0.0158 -0.040309 -0.002341 -0.01415 -0.04190000000000001 -0.003 -0.0158 -0.040839 -0.0025607 -0.01415 -0.0413695 -0.00278035 -0.01415 -0.04190000000000001 -0.003 -0.0125 -0.04190000000000001 -0.003 -0.0158 -0.0413695 -0.00278035 -0.01415 -0.040839 -0.0025607 -0.01415 -0.04190000000000001 -0.003 -0.0125 -0.0413695 -0.00278035 -0.01415 -0.044021 -0.0021213 -0.0125 -0.042961 -0.0025607 -0.01415 -0.0429605 -0.00256076 -0.013325 -0.04190000000000001 -0.003 -0.0125 -0.044021 -0.0021213 -0.0125 -0.0429605 -0.00256076 -0.013325 -0.042961 -0.0025607 -0.01415 -0.04190000000000001 -0.003 -0.0125 -0.0429605 -0.00256076 -0.013325 -0.04490000000000001 0 -0.0125 -0.044021 -0.0021213 -0.0125 -0.05070000000000001 -0.011 -0.0125 0.001999999999999997 -0.00835 0.0158 0.001999999999999997 -0.00835 0.0148 0.001999999999999997 0 0.0153 -0.04087500000000001 0.0024753 0.01415 -0.04087450000000001 0.00247521 0.014975 -0.03984900000000001 0.0020506 0.0158 -0.03984900000000001 0.0020506 0.0158 -0.04087450000000001 0.00247521 0.014975 -0.04190000000000001 0.0029 0.0158 -0.04190000000000001 0.0029 0.0158 -0.04087450000000001 0.00247521 0.014975 -0.04087500000000001 0.0024753 0.01415 -0.04190000000000001 0.0029 0.0125 -0.042925 0.0024753 0.01415 -0.04241250000000001 0.00268765 0.01415 -0.04190000000000001 0.0029 0.0158 -0.04190000000000001 0.0029 0.0125 -0.04241250000000001 0.00268765 0.01415 -0.042925 0.0024753 0.01415 -0.04190000000000001 0.0029 0.0158 -0.04241250000000001 0.00268765 0.01415 -0.043951 0.0020506 0.0158 -0.042925 0.0024753 0.01415 -0.043438 0.00226295 0.01415 -0.043951 0.0020506 0.0125 -0.043951 0.0020506 0.0158 -0.043438 0.00226295 0.01415 -0.042925 0.0024753 0.01415 -0.043951 0.0020506 0.0125 -0.043438 0.00226295 0.01415 -0.04480000000000001 0 0.0125 -0.043951 0.0020506 0.0125 -0.05070000000000001 -0.011 0.0125 -0.044375 -0.0010253 0.01415 -0.04437530000000001 -0.00102521 0.013325 -0.043951 -0.0020506 0.0125 -0.043951 -0.0020506 0.0125 -0.04437530000000001 -0.00102521 0.013325 -0.04480000000000001 0 0.0125 -0.04480000000000001 0 0.0125 -0.04437530000000001 -0.00102521 0.013325 -0.044375 -0.0010253 0.01415 -0.04190000000000001 -0.0029 0.0158 -0.042925 -0.0024753 0.01415 -0.04241250000000001 -0.00268765 0.01415 -0.04190000000000001 -0.0029 0.0125 -0.04190000000000001 -0.0029 0.0158 -0.04241250000000001 -0.00268765 0.01415 -0.042925 -0.0024753 0.01415 -0.04190000000000001 -0.0029 0.0125 -0.04241250000000001 -0.00268765 0.01415 -0.043951 -0.0020506 0.0125 -0.042925 -0.0024753 0.01415 -0.043438 -0.00226295 0.01415 -0.043951 -0.0020506 0.0158 -0.043951 -0.0020506 0.0125 -0.043438 -0.00226295 0.01415 -0.042925 -0.0024753 0.01415 -0.043951 -0.0020506 0.0158 -0.043438 -0.00226295 0.01415 -0.04190000000000001 -0.0029 0.0158 -0.04087500000000001 -0.0024753 0.01415 -0.04087450000000001 -0.00247521 0.014975 -0.03984900000000001 -0.0020506 0.0158 -0.04190000000000001 -0.0029 0.0158 -0.04087450000000001 -0.00247521 0.014975 -0.04087500000000001 -0.0024753 0.01415 -0.03984900000000001 -0.0020506 0.0158 -0.04087450000000001 -0.00247521 0.014975 -0.03984900000000001 -0.0020506 0.0158 -0.03900000000000001 0 0.0158 -0.04190000000000001 0 0.0158 -0.03900000000000001 0 0.0158 -0.03984900000000001 0.0020506 0.0158 -0.04190000000000001 0 0.0158 -0.04490000000000001 0 -0.0125 -0.05070000000000001 -0.011 -0.0125 -0.044021 0.0021213 -0.0125 -0.04190000000000001 0.003 -0.0158 -0.042961 0.0025607 -0.01415 -0.04243050000000001 0.00278035 -0.01415 -0.04190000000000001 0.003 -0.0125 -0.04190000000000001 0.003 -0.0158 -0.04243050000000001 0.00278035 -0.01415 -0.042961 0.0025607 -0.01415 -0.04190000000000001 0.003 -0.0125 -0.04243050000000001 0.00278035 -0.01415 -0.044021 0.0021213 -0.0125 -0.042961 0.0025607 -0.01415 -0.043491 0.002341 -0.01415 -0.044021 0.0021213 -0.0158 -0.044021 0.0021213 -0.0125 -0.043491 0.002341 -0.01415 -0.042961 0.0025607 -0.01415 -0.044021 0.0021213 -0.0158 -0.043491 0.002341 -0.01415 -0.04190000000000001 0.003 -0.0158 -0.040839 0.0025607 -0.01415 -0.0408395 0.00256076 -0.014975 -0.03977900000000001 0.0021213 -0.0158 -0.04190000000000001 0.003 -0.0158 -0.0408395 0.00256076 -0.014975 -0.040839 0.0025607 -0.01415 -0.03977900000000001 0.0021213 -0.0158 -0.0408395 0.00256076 -0.014975 -0.04190000000000001 0 -0.0158 -0.03977900000000001 0.0021213 -0.0158 -0.0389 0 -0.0158 -0.04190000000000001 0 -0.0158 -0.0389 0 -0.0158 -0.03977900000000001 -0.0021213 -0.0158 -0.040839 -0.0025607 -0.01415 -0.0408395 -0.00256076 -0.014975 -0.03977900000000001 -0.0021213 -0.0158 -0.03977900000000001 -0.0021213 -0.0158 -0.0408395 -0.00256076 -0.014975 -0.04190000000000001 -0.003 -0.0158 -0.04190000000000001 -0.003 -0.0158 -0.0408395 -0.00256076 -0.014975 -0.040839 -0.0025607 -0.01415 -0.04190000000000001 -0.003 -0.0125 -0.042961 -0.0025607 -0.01415 -0.04243050000000001 -0.00278035 -0.01415 -0.04190000000000001 -0.003 -0.0158 -0.04190000000000001 -0.003 -0.0125 -0.04243050000000001 -0.00278035 -0.01415 -0.042961 -0.0025607 -0.01415 -0.04190000000000001 -0.003 -0.0158 -0.04243050000000001 -0.00278035 -0.01415 -0.044021 -0.0021213 -0.0158 -0.042961 -0.0025607 -0.01415 -0.043491 -0.002341 -0.01415 -0.044021 -0.0021213 -0.0125 -0.044021 -0.0021213 -0.0158 -0.043491 -0.002341 -0.01415 -0.042961 -0.0025607 -0.01415 -0.044021 -0.0021213 -0.0125 -0.043491 -0.002341 -0.01415 -0.04490000000000001 0 -0.0125 -0.044461 -0.0010607 -0.01415 -0.04446070000000001 -0.00106074 -0.013325 -0.044021 -0.0021213 -0.0125 -0.04490000000000001 0 -0.0125 -0.04446070000000001 -0.00106074 -0.013325 -0.044461 -0.0010607 -0.01415 -0.044021 -0.0021213 -0.0125 -0.04446070000000001 -0.00106074 -0.013325 -0.03984900000000001 0.0020506 0.0158 -0.04190000000000001 0.0029 0.0158 -0.04190000000000001 0 0.0158 -0.04190000000000001 0.0029 0.0158 -0.042925 0.0024753 0.01415 -0.04292550000000001 0.00247521 0.014975 -0.043951 0.0020506 0.0158 -0.04190000000000001 0.0029 0.0158 -0.04292550000000001 0.00247521 0.014975 -0.042925 0.0024753 0.01415 -0.043951 0.0020506 0.0158 -0.04292550000000001 0.00247521 0.014975 -0.043951 0.0020506 0.0125 -0.044375 0.0010253 0.01415 -0.04416300000000001 0.00153795 0.01415 -0.043951 0.0020506 0.0158 -0.043951 0.0020506 0.0125 -0.04416300000000001 0.00153795 0.01415 -0.044375 0.0010253 0.01415 -0.043951 0.0020506 0.0158 -0.04416300000000001 0.00153795 0.01415 -0.04480000000000001 0 0.0125 -0.044375 0.0010253 0.01415 -0.04437530000000001 0.00102521 0.013325 -0.043951 0.0020506 0.0125 -0.04480000000000001 0 0.0125 -0.04437530000000001 0.00102521 0.013325 -0.044375 0.0010253 0.01415 -0.043951 0.0020506 0.0125 -0.04437530000000001 0.00102521 0.013325 -0.043951 -0.0020506 0.0158 -0.044375 -0.0010253 0.01415 -0.04416300000000001 -0.00153795 0.01415 -0.043951 -0.0020506 0.0125 -0.043951 -0.0020506 0.0158 -0.04416300000000001 -0.00153795 0.01415 -0.044375 -0.0010253 0.01415 -0.043951 -0.0020506 0.0125 -0.04416300000000001 -0.00153795 0.01415 -0.04480000000000001 0 0.0125 -0.044375 -0.0010253 0.01415 -0.0445875 -0.00051265 0.01415 -0.04480000000000001 0 0.0158 -0.04480000000000001 0 0.0125 -0.0445875 -0.00051265 0.01415 -0.044375 -0.0010253 0.01415 -0.04480000000000001 0 0.0158 -0.0445875 -0.00051265 0.01415 -0.042925 -0.0024753 0.01415 -0.04292550000000001 -0.00247521 0.014975 -0.043951 -0.0020506 0.0158 -0.043951 -0.0020506 0.0158 -0.04292550000000001 -0.00247521 0.014975 -0.04190000000000001 -0.0029 0.0158 -0.04190000000000001 -0.0029 0.0158 -0.04292550000000001 -0.00247521 0.014975 -0.042925 -0.0024753 0.01415 -0.03984900000000001 -0.0020506 0.0158 -0.04190000000000001 0 0.0158 -0.04190000000000001 -0.0029 0.0158 -0.044021 0.0021213 -0.0125 -0.044461 0.0010607 -0.01415 -0.04446070000000001 0.00106074 -0.013325 -0.04490000000000001 0 -0.0125 -0.044021 0.0021213 -0.0125 -0.04446070000000001 0.00106074 -0.013325 -0.044461 0.0010607 -0.01415 -0.04490000000000001 0 -0.0125 -0.04446070000000001 0.00106074 -0.013325 -0.042961 0.0025607 -0.01415 -0.0429605 0.00256076 -0.014975 -0.044021 0.0021213 -0.0158 -0.044021 0.0021213 -0.0158 -0.0429605 0.00256076 -0.014975 -0.04190000000000001 0.003 -0.0158 -0.04190000000000001 0.003 -0.0158 -0.0429605 0.00256076 -0.014975 -0.042961 0.0025607 -0.01415 -0.044021 0.0021213 -0.0158 -0.044461 0.0010607 -0.01415 -0.044241 0.001591 -0.01415 -0.044021 0.0021213 -0.0125 -0.044021 0.0021213 -0.0158 -0.044241 0.001591 -0.01415 -0.044461 0.0010607 -0.01415 -0.044021 0.0021213 -0.0125 -0.044241 0.001591 -0.01415 -0.04190000000000001 0.003 -0.0158 -0.03977900000000001 0.0021213 -0.0158 -0.04190000000000001 0 -0.0158 -0.04190000000000001 -0.003 -0.0158 -0.04190000000000001 0 -0.0158 -0.03977900000000001 -0.0021213 -0.0158 -0.04190000000000001 -0.003 -0.0158 -0.042961 -0.0025607 -0.01415 -0.0429605 -0.00256076 -0.014975 -0.044021 -0.0021213 -0.0158 -0.04190000000000001 -0.003 -0.0158 -0.0429605 -0.00256076 -0.014975 -0.042961 -0.0025607 -0.01415 -0.044021 -0.0021213 -0.0158 -0.0429605 -0.00256076 -0.014975 -0.044021 -0.0021213 -0.0125 -0.044461 -0.0010607 -0.01415 -0.044241 -0.001591 -0.01415 -0.044021 -0.0021213 -0.0158 -0.044021 -0.0021213 -0.0125 -0.044241 -0.001591 -0.01415 -0.044461 -0.0010607 -0.01415 -0.044021 -0.0021213 -0.0158 -0.044241 -0.001591 -0.01415 -0.04490000000000001 0 -0.0158 -0.044461 -0.0010607 -0.01415 -0.0446805 -0.00053035 -0.01415 -0.04490000000000001 0 -0.0125 -0.04490000000000001 0 -0.0158 -0.0446805 -0.00053035 -0.01415 -0.044461 -0.0010607 -0.01415 -0.04490000000000001 0 -0.0125 -0.0446805 -0.00053035 -0.01415 -0.04190000000000001 0 0.0158 -0.04190000000000001 0.0029 0.0158 -0.043951 0.0020506 0.0158 -0.043951 0.0020506 0.0158 -0.044375 0.0010253 0.01415 -0.04437530000000001 0.00102521 0.014975 -0.04480000000000001 0 0.0158 -0.043951 0.0020506 0.0158 -0.04437530000000001 0.00102521 0.014975 -0.044375 0.0010253 0.01415 -0.04480000000000001 0 0.0158 -0.04437530000000001 0.00102521 0.014975 -0.04480000000000001 0 0.0158 -0.044375 0.0010253 0.01415 -0.0445875 0.00051265 0.01415 -0.04480000000000001 0 0.0125 -0.04480000000000001 0 0.0158 -0.0445875 0.00051265 0.01415 -0.044375 0.0010253 0.01415 -0.04480000000000001 0 0.0125 -0.0445875 0.00051265 0.01415 -0.04480000000000001 0 0.0158 -0.044375 -0.0010253 0.01415 -0.04437530000000001 -0.00102521 0.014975 -0.043951 -0.0020506 0.0158 -0.04480000000000001 0 0.0158 -0.04437530000000001 -0.00102521 0.014975 -0.044375 -0.0010253 0.01415 -0.043951 -0.0020506 0.0158 -0.04437530000000001 -0.00102521 0.014975 -0.04190000000000001 -0.0029 0.0158 -0.04190000000000001 0 0.0158 -0.043951 -0.0020506 0.0158 -0.04490000000000001 0 -0.0125 -0.044461 0.0010607 -0.01415 -0.0446805 0.00053035 -0.01415 -0.04490000000000001 0 -0.0158 -0.04490000000000001 0 -0.0125 -0.0446805 0.00053035 -0.01415 -0.044461 0.0010607 -0.01415 -0.04490000000000001 0 -0.0158 -0.0446805 0.00053035 -0.01415 -0.044021 0.0021213 -0.0158 -0.04190000000000001 0.003 -0.0158 -0.04190000000000001 0 -0.0158 -0.04490000000000001 0 -0.0158 -0.044461 0.0010607 -0.01415 -0.04446070000000001 0.00106074 -0.014975 -0.044021 0.0021213 -0.0158 -0.04490000000000001 0 -0.0158 -0.04446070000000001 0.00106074 -0.014975 -0.044461 0.0010607 -0.01415 -0.044021 0.0021213 -0.0158 -0.04446070000000001 0.00106074 -0.014975 -0.044021 -0.0021213 -0.0158 -0.04190000000000001 0 -0.0158 -0.04190000000000001 -0.003 -0.0158 -0.044461 -0.0010607 -0.01415 -0.04446070000000001 -0.00106074 -0.014975 -0.044021 -0.0021213 -0.0158 -0.044021 -0.0021213 -0.0158 -0.04446070000000001 -0.00106074 -0.014975 -0.04490000000000001 0 -0.0158 -0.04490000000000001 0 -0.0158 -0.04446070000000001 -0.00106074 -0.014975 -0.044461 -0.0010607 -0.01415 -0.04190000000000001 0 0.0158 -0.043951 0.0020506 0.0158 -0.04480000000000001 0 0.0158 -0.04190000000000001 0 0.0158 -0.04480000000000001 0 0.0158 -0.043951 -0.0020506 0.0158 -0.04490000000000001 0 -0.0158 -0.044021 0.0021213 -0.0158 -0.04190000000000001 0 -0.0158 -0.04490000000000001 0 -0.0158 -0.04190000000000001 0 -0.0158 -0.044021 -0.0021213 -0.0158 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265

    -
    -
    - - - -3.469446951953614e-18 0 0 - 1 0 0 0 - - true - - - -
    - - - - -0.01722999999999999 -0.00062 0.0153 -0.004453999999999993 0.0072397 0.0148 -0.03000599999999999 -0.0084797 0.0148 -0.03000599999999999 -0.0084797 0.0148 -0.03000599999999999 -0.0084797 0.0158 -0.01722999999999999 -0.00062 0.0153 -0.03000799999999999 -0.0119797 0.0148 -0.03000599999999999 -0.0084797 0.0148 -0.004453999999999993 0.0072397 0.0148 -0.01722999999999999 -0.00062 0.0153 -0.004453999999999993 0.0072397 0.0158 -0.004453999999999993 0.0072397 0.0148 -0.01722999999999999 -0.00062 0.0153 -0.03000599999999999 -0.0084797 0.0158 -0.004453999999999993 0.0072397 0.0158 -0.03000599999999999 -0.0084797 0.0158 -0.03000599999999999 -0.0084797 0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.003496999999999993 0.0077473 0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.004453999999999993 0.0072397 0.0148 -0.004453999999999993 0.0072397 0.0158 -0.003975989999999993 0.0074935 0.0153 -0.004214999999999993 0.0073666 0.0153 -0.004453999999999993 0.0072397 0.0148 -0.004453999999999993 0.0072397 0.0158 -0.004214999999999993 0.0073666 0.0153 -0.003975989999999993 0.0074935 0.0153 -0.004453999999999993 0.0072397 0.0148 -0.004214999999999993 0.0073666 0.0153 -0.004453999999999993 0.0072397 0.0158 -0.03000599999999999 -0.0084797 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.03000599999999999 -0.0084797 0.0158 -0.03000799999999999 -0.0119797 0.0148 -0.03000899999999999 -0.0129797 0.0158 -0.004453999999999993 0.0072397 0.0148 -0.003975989999999993 0.0074935 0.0153 -0.003975549999999993 0.0074936 0.01505 -0.003496999999999993 0.0077473 0.0148 -0.004453999999999993 0.0072397 0.0148 -0.003975549999999993 0.0074936 0.01505 -0.003975989999999993 0.0074935 0.0153 -0.003496999999999993 0.0077473 0.0148 -0.003975549999999993 0.0074936 0.01505 -0.03000799999999999 -0.0119797 0.0148 -0.003496999999999993 0.0077473 0.0148 -0.01000599999999999 -0.008493199999999999 0.0148 -0.003975989999999993 0.0074935 0.0153 -0.003975549999999993 0.0074936 0.01555 -0.003496999999999993 0.0077473 0.0158 -0.003496999999999993 0.0077473 0.0158 -0.003975549999999993 0.0074936 0.01555 -0.004453999999999993 0.0072397 0.0158 -0.004453999999999993 0.0072397 0.0158 -0.003975549999999993 0.0074936 0.01555 -0.003975989999999993 0.0074935 0.0153 -0.003496999999999993 0.0077473 0.0158 -0.004453999999999993 0.0072397 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.03000799999999999 -0.0119797 0.0148 -0.03000899999999999 -0.0129797 -0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.003496999999999993 0.0077473 0.0148 -0.003975989999999993 0.0074935 0.0153 -0.003736499999999993 0.0076204 0.0153 -0.003496999999999993 0.0077473 0.0158 -0.003496999999999993 0.0077473 0.0148 -0.003736499999999993 0.0076204 0.0153 -0.003975989999999993 0.0074935 0.0153 -0.003496999999999993 0.0077473 0.0158 -0.003736499999999993 0.0076204 0.0153 -0.01000599999999999 -0.008493199999999999 0.0148 -0.003496999999999993 0.0077473 0.0148 0.01273690000000001 -0.0085086 0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.01000599999999999 -0.008493199999999999 0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.01000599999999999 -0.008493199999999999 0.0158 -0.003496999999999993 0.0077473 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.02886979999999999 -0.0129805 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.02999999999999999 -0.0129797 0.014 -0.02886979999999999 -0.0129805 -0.014 -0.02999999999999999 -0.0129797 -0.014 -0.03000899999999999 -0.0129797 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.0129797 0.014 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.0129797 0 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.0129797 0 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.0129797 -0.014 -0.03000799999999999 -0.0119797 -0.0148 -0.03000899999999999 -0.0129797 -0.0158 -0.03000799999999999 -0.0119797 0.0148 0.004620000000000007 -0.000380699 0.0153 -0.003496999999999993 0.0077473 0.0148 -0.003496999999999993 0.0077473 0.0158 0.004620000000000007 -0.000380699 0.0153 0.01273690000000001 -0.0085086 0.0148 -0.003496999999999993 0.0077473 0.0148 0.001366000000000007 -0.0085009 0.0153 -0.01000599999999999 -0.008493199999999999 0.0148 0.01273690000000001 -0.0085086 0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.01000599999999999 -0.008493199999999999 0.0148 -0.01000599999999999 -0.008493199999999999 0.0158 -0.01000799999999999 -0.0119932 0.0148 -0.02000799999999999 -0.0119865 0 -0.02000799999999999 -0.0119865 0.0074 -0.03000799999999999 -0.0119797 0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.02000799999999999 -0.0119865 0.0074 -0.02000799999999999 -0.0119865 0 -0.03000799999999999 -0.0119797 0.0148 -0.02000799999999999 -0.0119865 0.0074 -0.01000899999999999 -0.0129932 0.0158 -0.01000599999999999 -0.008493199999999999 0.0158 -0.03000899999999999 -0.0129797 0.0158 0.01273690000000001 -0.0085086 0.0158 -0.003496999999999993 0.0077473 0.0158 -0.01000599999999999 -0.008493199999999999 0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02247719999999999 -0.0129848 -0.014 -0.02886979999999999 -0.0129805 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01000899999999999 -0.0129932 -0.0158 -0.01199999999999999 -0.0129919 -0.014 -0.01199999999999999 -0.0129919 -0.014 -0.01000899999999999 -0.0129932 -0.0158 -0.01199999999999999 -0.0129919 -0.0126542 -0.02099999999999999 -0.0129858 -0.014 -0.02000899999999999 -0.0129865 -0.0142271 -0.01348629999999999 -0.0129909 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02000899999999999 -0.0129865 -0.0142271 -0.02099999999999999 -0.0129858 -0.014 -0.01000899999999999 -0.0129932 -0.0158 -0.02000899999999999 -0.0129865 -0.0142271 -0.03000899999999999 -0.0129797 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02000899999999999 -0.0129865 -0.0142271 -0.02247719999999999 -0.0129848 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.02000899999999999 -0.0129865 -0.0142271 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 0.0158 -0.01199999999999999 -0.0129919 0.014 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.0129919 0.014 -0.01000899999999999 -0.0129932 0.0158 -0.01951979999999999 -0.0129868 0.014 -0.02099999999999999 -0.0129858 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.02852889999999999 -0.0129807 0.014 -0.02852889999999999 -0.0129807 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.02886979999999999 -0.0129805 0.014 -0.02099999999999999 -0.0129858 0.014 -0.01951979999999999 -0.0129868 0.014 -0.02000899999999999 -0.0129865 0.0142271 -0.01000899999999999 -0.0129932 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.02000899999999999 -0.0129865 0.0142271 -0.01951979999999999 -0.0129868 0.014 -0.01000899999999999 -0.0129932 0.0158 -0.02000899999999999 -0.0129865 0.0142271 -0.03000899999999999 -0.0129797 0.0158 -0.02099999999999999 -0.0129858 0.014 -0.02000899999999999 -0.0129865 0.0142271 -0.03000799999999999 -0.0119797 -0.0148 -0.03000599999999999 -0.0084797 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.03000799999999999 -0.0119797 0.0148 -0.02000799999999999 -0.0119865 0 -0.02500799999999999 -0.0119831 8.67362e-19 -0.03000799999999999 -0.0119797 -0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.02500799999999999 -0.0119831 8.67362e-19 -0.02000799999999999 -0.0119865 0 -0.03000799999999999 -0.0119797 -0.0148 -0.02500799999999999 -0.0119831 8.67362e-19 0.004620000000000007 -0.000380699 0.0153 -0.003496999999999993 0.0077473 0.0158 0.01273690000000001 -0.0085086 0.0158 0.01273690000000001 -0.0085086 0.0158 0.01273690000000001 -0.0085086 0.0148 0.004620000000000007 -0.000380699 0.0153 0.01273690000000001 -0.0085086 0.0148 0.01273690000000001 -0.0085086 0.0158 0.001366000000000007 -0.0085009 0.0153 0.001366000000000007 -0.0085009 0.0153 -0.01000599999999999 -0.008493199999999999 0.0158 -0.01000599999999999 -0.008493199999999999 0.0148 -0.01000899999999999 -0.0129932 0.0158 -0.01000799999999999 -0.0119932 0.0148 -0.01000599999999999 -0.008493199999999999 0.0158 -0.01000799999999999 -0.0119932 -0.0148 -0.02000799999999999 -0.0119865 0 -0.01500799999999999 -0.0119898 -8.67362e-19 -0.01000799999999999 -0.0119932 0.0148 -0.01000799999999999 -0.0119932 -0.0148 -0.01500799999999999 -0.0119898 -8.67362e-19 -0.02000799999999999 -0.0119865 0 -0.01000799999999999 -0.0119932 0.0148 -0.01500799999999999 -0.0119898 -8.67362e-19 0.001366000000000007 -0.0085009 0.0153 0.01273690000000001 -0.0085086 0.0158 -0.01000599999999999 -0.008493199999999999 0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 0.0158 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.0129919 -0.0126542 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 0.0158 -0.01100449999999999 -0.0129925 0 -0.01199999999999999 -0.0129919 0 -0.01199999999999999 -0.0129919 -0.00231435 -0.01100449999999999 -0.0129925 0 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.0129919 0 -0.01100449999999999 -0.0129925 0 -0.01000899999999999 -0.0129932 0.0158 -0.01199999999999999 -0.0129919 0.0116856 -0.01100449999999999 -0.0129925 0 -0.01199999999999999 -0.0129919 -0.00231435 -0.01000899999999999 -0.0129932 -0.0158 -0.01100449999999999 -0.0129925 0 -0.03000899999999999 -0.0129797 -0.0158 -0.03000599999999999 -0.0084797 -0.0158 -0.004453999999999993 0.0072397 -0.0158 -0.03000599999999999 -0.0084797 -0.0148 -0.03000599999999999 -0.0084797 -0.0158 -0.03000799999999999 -0.0119797 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.02000799999999999 -0.0119865 0 -0.02000799999999999 -0.0119865 -0.0074 -0.01000799999999999 -0.0119932 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.02000799999999999 -0.0119865 -0.0074 -0.02000799999999999 -0.0119865 0 -0.01000799999999999 -0.0119932 -0.0148 -0.02000799999999999 -0.0119865 -0.0074 -0.01000899999999999 -0.0129932 0.0158 -0.01000899999999999 -0.0129932 -0.0158 -0.01000799999999999 -0.0119932 0.0148 -0.01000899999999999 -0.0129932 -0.0158 -0.01000799999999999 -0.0119932 -0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.01000899999999999 -0.0129932 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.03000899999999999 -0.0129797 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.03000599999999999 -0.0084797 -0.0158 -0.01722999999999999 -0.00062 -0.0153 -0.004453999999999993 0.0072397 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.004453999999999993 0.0072397 -0.0158 -0.03000599999999999 -0.0084797 -0.0158 -0.03000599999999999 -0.0084797 -0.0148 -0.01722999999999999 -0.00062 -0.0153 -0.004453999999999993 0.0072397 -0.0148 -0.03000599999999999 -0.0084797 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.01000799999999999 -0.0119932 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.01000799999999999 -0.0119932 -0.0148 -0.01000899999999999 -0.0129932 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0148 0.001366000000000007 -0.0085009 -0.0153 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.003496999999999993 0.0077473 -0.0158 0.01273690000000001 -0.0085086 -0.0158 -0.01722999999999999 -0.00062 -0.0153 -0.004453999999999993 0.0072397 -0.0148 -0.004453999999999993 0.0072397 -0.0158 -0.003975989999999993 0.0074935 -0.0153 -0.003975549999999993 0.0074936 -0.01555 -0.004453999999999993 0.0072397 -0.0158 -0.004453999999999993 0.0072397 -0.0158 -0.003975549999999993 0.0074936 -0.01555 -0.003496999999999993 0.0077473 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.003975549999999993 0.0074936 -0.01555 -0.003975989999999993 0.0074935 -0.0153 -0.01722999999999999 -0.00062 -0.0153 -0.03000599999999999 -0.0084797 -0.0148 -0.004453999999999993 0.0072397 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.004453999999999993 0.0072397 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 0.001366000000000007 -0.0085009 -0.0153 -0.01000599999999999 -0.008493199999999999 -0.0158 0.01273690000000001 -0.0085086 -0.0158 0.001366000000000007 -0.0085009 -0.0153 0.01273690000000001 -0.0085086 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 0.004620000000000007 -0.000380699 -0.0153 0.01273690000000001 -0.0085086 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.004453999999999993 0.0072397 -0.0148 -0.003975989999999993 0.0074935 -0.0153 -0.004214999999999993 0.0073666 -0.0153 -0.004453999999999993 0.0072397 -0.0158 -0.004453999999999993 0.0072397 -0.0148 -0.004214999999999993 0.0073666 -0.0153 -0.003975989999999993 0.0074935 -0.0153 -0.004453999999999993 0.0072397 -0.0158 -0.004214999999999993 0.0073666 -0.0153 -0.003496999999999993 0.0077473 -0.0158 -0.003975989999999993 0.0074935 -0.0153 -0.003736499999999993 0.0076204 -0.0153 -0.003496999999999993 0.0077473 -0.0148 -0.003496999999999993 0.0077473 -0.0158 -0.003736499999999993 0.0076204 -0.0153 -0.003975989999999993 0.0074935 -0.0153 -0.003496999999999993 0.0077473 -0.0148 -0.003736499999999993 0.0076204 -0.0153 -0.003975989999999993 0.0074935 -0.0153 -0.003975549999999993 0.0074936 -0.01505 -0.003496999999999993 0.0077473 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.003975549999999993 0.0074936 -0.01505 -0.004453999999999993 0.0072397 -0.0148 -0.004453999999999993 0.0072397 -0.0148 -0.003975549999999993 0.0074936 -0.01505 -0.003975989999999993 0.0074935 -0.0153 0.01273690000000001 -0.0085086 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 0.01273690000000001 -0.0085086 -0.0158 0.01273690000000001 -0.0085086 -0.0148 0.001366000000000007 -0.0085009 -0.0153 0.004620000000000007 -0.000380699 -0.0153 -0.003496999999999993 0.0077473 -0.0158 -0.003496999999999993 0.0077473 -0.0148 0.004620000000000007 -0.000380699 -0.0153 0.01273690000000001 -0.0085086 -0.0148 0.01273690000000001 -0.0085086 -0.0158 0.01273690000000001 -0.0085086 -0.0148 0.004620000000000007 -0.000380699 -0.0153 -0.003496999999999993 0.0077473 -0.0148 -0.01722999999999999 -0.00062 0.0153 -0.004453999999999993 0.0072397 0.0148 -0.03000599999999999 -0.0084797 0.0148 -0.03000599999999999 -0.0084797 0.0148 -0.03000599999999999 -0.0084797 0.0158 -0.01722999999999999 -0.00062 0.0153 -0.03000799999999999 -0.0119797 0.0148 -0.03000599999999999 -0.0084797 0.0148 -0.004453999999999993 0.0072397 0.0148 -0.01722999999999999 -0.00062 0.0153 -0.004453999999999993 0.0072397 0.0158 -0.004453999999999993 0.0072397 0.0148 -0.01722999999999999 -0.00062 0.0153 -0.03000599999999999 -0.0084797 0.0158 -0.004453999999999993 0.0072397 0.0158 -0.03000599999999999 -0.0084797 0.0158 -0.03000599999999999 -0.0084797 0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.003496999999999993 0.0077473 0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.004453999999999993 0.0072397 0.0148 -0.004453999999999993 0.0072397 0.0158 -0.003975989999999993 0.0074935 0.0153 -0.004214999999999993 0.0073666 0.0153 -0.004453999999999993 0.0072397 0.0148 -0.004453999999999993 0.0072397 0.0158 -0.004214999999999993 0.0073666 0.0153 -0.003975989999999993 0.0074935 0.0153 -0.004453999999999993 0.0072397 0.0148 -0.004214999999999993 0.0073666 0.0153 -0.004453999999999993 0.0072397 0.0158 -0.03000599999999999 -0.0084797 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.03000599999999999 -0.0084797 0.0158 -0.03000799999999999 -0.0119797 0.0148 -0.03000899999999999 -0.0129797 0.0158 -0.004453999999999993 0.0072397 0.0148 -0.003975989999999993 0.0074935 0.0153 -0.003975549999999993 0.0074936 0.01505 -0.003496999999999993 0.0077473 0.0148 -0.004453999999999993 0.0072397 0.0148 -0.003975549999999993 0.0074936 0.01505 -0.003975989999999993 0.0074935 0.0153 -0.003496999999999993 0.0077473 0.0148 -0.003975549999999993 0.0074936 0.01505 -0.03000799999999999 -0.0119797 0.0148 -0.003496999999999993 0.0077473 0.0148 -0.01000599999999999 -0.008493199999999999 0.0148 -0.003975989999999993 0.0074935 0.0153 -0.003975549999999993 0.0074936 0.01555 -0.003496999999999993 0.0077473 0.0158 -0.003496999999999993 0.0077473 0.0158 -0.003975549999999993 0.0074936 0.01555 -0.004453999999999993 0.0072397 0.0158 -0.004453999999999993 0.0072397 0.0158 -0.003975549999999993 0.0074936 0.01555 -0.003975989999999993 0.0074935 0.0153 -0.003496999999999993 0.0077473 0.0158 -0.004453999999999993 0.0072397 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.03000799999999999 -0.0119797 0.0148 -0.03000899999999999 -0.0129797 -0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.003496999999999993 0.0077473 0.0148 -0.003975989999999993 0.0074935 0.0153 -0.003736499999999993 0.0076204 0.0153 -0.003496999999999993 0.0077473 0.0158 -0.003496999999999993 0.0077473 0.0148 -0.003736499999999993 0.0076204 0.0153 -0.003975989999999993 0.0074935 0.0153 -0.003496999999999993 0.0077473 0.0158 -0.003736499999999993 0.0076204 0.0153 -0.01000599999999999 -0.008493199999999999 0.0148 -0.003496999999999993 0.0077473 0.0148 0.01273690000000001 -0.0085086 0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.01000599999999999 -0.008493199999999999 0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.01000599999999999 -0.008493199999999999 0.0158 -0.003496999999999993 0.0077473 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.02886979999999999 -0.0129805 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.02999999999999999 -0.0129797 0.014 -0.02886979999999999 -0.0129805 -0.014 -0.02999999999999999 -0.0129797 -0.014 -0.03000899999999999 -0.0129797 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.0129797 0.014 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.0129797 0 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.0129797 0 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.0129797 -0.014 -0.03000799999999999 -0.0119797 -0.0148 -0.03000899999999999 -0.0129797 -0.0158 -0.03000799999999999 -0.0119797 0.0148 0.004620000000000007 -0.000380699 0.0153 -0.003496999999999993 0.0077473 0.0148 -0.003496999999999993 0.0077473 0.0158 0.004620000000000007 -0.000380699 0.0153 0.01273690000000001 -0.0085086 0.0148 -0.003496999999999993 0.0077473 0.0148 0.001366000000000007 -0.0085009 0.0153 -0.01000599999999999 -0.008493199999999999 0.0148 0.01273690000000001 -0.0085086 0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.01000599999999999 -0.008493199999999999 0.0148 -0.01000599999999999 -0.008493199999999999 0.0158 -0.01000799999999999 -0.0119932 0.0148 -0.02000799999999999 -0.0119865 0 -0.02000799999999999 -0.0119865 0.0074 -0.03000799999999999 -0.0119797 0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.02000799999999999 -0.0119865 0.0074 -0.02000799999999999 -0.0119865 0 -0.03000799999999999 -0.0119797 0.0148 -0.02000799999999999 -0.0119865 0.0074 -0.01000899999999999 -0.0129932 0.0158 -0.01000599999999999 -0.008493199999999999 0.0158 -0.03000899999999999 -0.0129797 0.0158 0.01273690000000001 -0.0085086 0.0158 -0.003496999999999993 0.0077473 0.0158 -0.01000599999999999 -0.008493199999999999 0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02247719999999999 -0.0129848 -0.014 -0.02886979999999999 -0.0129805 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01000899999999999 -0.0129932 -0.0158 -0.01199999999999999 -0.0129919 -0.014 -0.01199999999999999 -0.0129919 -0.014 -0.01000899999999999 -0.0129932 -0.0158 -0.01199999999999999 -0.0129919 -0.0126542 -0.02099999999999999 -0.0129858 -0.014 -0.02000899999999999 -0.0129865 -0.0142271 -0.01348629999999999 -0.0129909 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02000899999999999 -0.0129865 -0.0142271 -0.02099999999999999 -0.0129858 -0.014 -0.01000899999999999 -0.0129932 -0.0158 -0.02000899999999999 -0.0129865 -0.0142271 -0.03000899999999999 -0.0129797 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02000899999999999 -0.0129865 -0.0142271 -0.02247719999999999 -0.0129848 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.02000899999999999 -0.0129865 -0.0142271 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 0.0158 -0.01199999999999999 -0.0129919 0.014 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.0129919 0.014 -0.01000899999999999 -0.0129932 0.0158 -0.01951979999999999 -0.0129868 0.014 -0.02099999999999999 -0.0129858 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.02852889999999999 -0.0129807 0.014 -0.02852889999999999 -0.0129807 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.02886979999999999 -0.0129805 0.014 -0.02099999999999999 -0.0129858 0.014 -0.01951979999999999 -0.0129868 0.014 -0.02000899999999999 -0.0129865 0.0142271 -0.01000899999999999 -0.0129932 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.02000899999999999 -0.0129865 0.0142271 -0.01951979999999999 -0.0129868 0.014 -0.01000899999999999 -0.0129932 0.0158 -0.02000899999999999 -0.0129865 0.0142271 -0.03000899999999999 -0.0129797 0.0158 -0.02099999999999999 -0.0129858 0.014 -0.02000899999999999 -0.0129865 0.0142271 -0.03000799999999999 -0.0119797 -0.0148 -0.03000599999999999 -0.0084797 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.03000799999999999 -0.0119797 0.0148 -0.02000799999999999 -0.0119865 0 -0.02500799999999999 -0.0119831 8.67362e-19 -0.03000799999999999 -0.0119797 -0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.02500799999999999 -0.0119831 8.67362e-19 -0.02000799999999999 -0.0119865 0 -0.03000799999999999 -0.0119797 -0.0148 -0.02500799999999999 -0.0119831 8.67362e-19 0.004620000000000007 -0.000380699 0.0153 -0.003496999999999993 0.0077473 0.0158 0.01273690000000001 -0.0085086 0.0158 0.01273690000000001 -0.0085086 0.0158 0.01273690000000001 -0.0085086 0.0148 0.004620000000000007 -0.000380699 0.0153 0.01273690000000001 -0.0085086 0.0148 0.01273690000000001 -0.0085086 0.0158 0.001366000000000007 -0.0085009 0.0153 0.001366000000000007 -0.0085009 0.0153 -0.01000599999999999 -0.008493199999999999 0.0158 -0.01000599999999999 -0.008493199999999999 0.0148 -0.01000899999999999 -0.0129932 0.0158 -0.01000799999999999 -0.0119932 0.0148 -0.01000599999999999 -0.008493199999999999 0.0158 -0.01000799999999999 -0.0119932 -0.0148 -0.02000799999999999 -0.0119865 0 -0.01500799999999999 -0.0119898 -8.67362e-19 -0.01000799999999999 -0.0119932 0.0148 -0.01000799999999999 -0.0119932 -0.0148 -0.01500799999999999 -0.0119898 -8.67362e-19 -0.02000799999999999 -0.0119865 0 -0.01000799999999999 -0.0119932 0.0148 -0.01500799999999999 -0.0119898 -8.67362e-19 0.001366000000000007 -0.0085009 0.0153 0.01273690000000001 -0.0085086 0.0158 -0.01000599999999999 -0.008493199999999999 0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 0.0158 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.0129919 -0.0126542 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 0.0158 -0.01100449999999999 -0.0129925 0 -0.01199999999999999 -0.0129919 0 -0.01199999999999999 -0.0129919 -0.00231435 -0.01100449999999999 -0.0129925 0 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.0129919 0 -0.01100449999999999 -0.0129925 0 -0.01000899999999999 -0.0129932 0.0158 -0.01199999999999999 -0.0129919 0.0116856 -0.01100449999999999 -0.0129925 0 -0.01199999999999999 -0.0129919 -0.00231435 -0.01000899999999999 -0.0129932 -0.0158 -0.01100449999999999 -0.0129925 0 -0.03000899999999999 -0.0129797 -0.0158 -0.03000599999999999 -0.0084797 -0.0158 -0.004453999999999993 0.0072397 -0.0158 -0.03000599999999999 -0.0084797 -0.0148 -0.03000599999999999 -0.0084797 -0.0158 -0.03000799999999999 -0.0119797 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.02000799999999999 -0.0119865 0 -0.02000799999999999 -0.0119865 -0.0074 -0.01000799999999999 -0.0119932 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.02000799999999999 -0.0119865 -0.0074 -0.02000799999999999 -0.0119865 0 -0.01000799999999999 -0.0119932 -0.0148 -0.02000799999999999 -0.0119865 -0.0074 -0.01000899999999999 -0.0129932 0.0158 -0.01000899999999999 -0.0129932 -0.0158 -0.01000799999999999 -0.0119932 0.0148 -0.01000899999999999 -0.0129932 -0.0158 -0.01000799999999999 -0.0119932 -0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.01000899999999999 -0.0129932 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.03000899999999999 -0.0129797 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.03000599999999999 -0.0084797 -0.0158 -0.01722999999999999 -0.00062 -0.0153 -0.004453999999999993 0.0072397 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.004453999999999993 0.0072397 -0.0158 -0.03000599999999999 -0.0084797 -0.0158 -0.03000599999999999 -0.0084797 -0.0148 -0.01722999999999999 -0.00062 -0.0153 -0.004453999999999993 0.0072397 -0.0148 -0.03000599999999999 -0.0084797 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.01000799999999999 -0.0119932 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.01000799999999999 -0.0119932 -0.0148 -0.01000899999999999 -0.0129932 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0148 0.001366000000000007 -0.0085009 -0.0153 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.003496999999999993 0.0077473 -0.0158 0.01273690000000001 -0.0085086 -0.0158 -0.01722999999999999 -0.00062 -0.0153 -0.004453999999999993 0.0072397 -0.0148 -0.004453999999999993 0.0072397 -0.0158 -0.003975989999999993 0.0074935 -0.0153 -0.003975549999999993 0.0074936 -0.01555 -0.004453999999999993 0.0072397 -0.0158 -0.004453999999999993 0.0072397 -0.0158 -0.003975549999999993 0.0074936 -0.01555 -0.003496999999999993 0.0077473 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.003975549999999993 0.0074936 -0.01555 -0.003975989999999993 0.0074935 -0.0153 -0.01722999999999999 -0.00062 -0.0153 -0.03000599999999999 -0.0084797 -0.0148 -0.004453999999999993 0.0072397 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.004453999999999993 0.0072397 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 0.001366000000000007 -0.0085009 -0.0153 -0.01000599999999999 -0.008493199999999999 -0.0158 0.01273690000000001 -0.0085086 -0.0158 0.001366000000000007 -0.0085009 -0.0153 0.01273690000000001 -0.0085086 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 0.004620000000000007 -0.000380699 -0.0153 0.01273690000000001 -0.0085086 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.004453999999999993 0.0072397 -0.0148 -0.003975989999999993 0.0074935 -0.0153 -0.004214999999999993 0.0073666 -0.0153 -0.004453999999999993 0.0072397 -0.0158 -0.004453999999999993 0.0072397 -0.0148 -0.004214999999999993 0.0073666 -0.0153 -0.003975989999999993 0.0074935 -0.0153 -0.004453999999999993 0.0072397 -0.0158 -0.004214999999999993 0.0073666 -0.0153 -0.003496999999999993 0.0077473 -0.0158 -0.003975989999999993 0.0074935 -0.0153 -0.003736499999999993 0.0076204 -0.0153 -0.003496999999999993 0.0077473 -0.0148 -0.003496999999999993 0.0077473 -0.0158 -0.003736499999999993 0.0076204 -0.0153 -0.003975989999999993 0.0074935 -0.0153 -0.003496999999999993 0.0077473 -0.0148 -0.003736499999999993 0.0076204 -0.0153 -0.003975989999999993 0.0074935 -0.0153 -0.003975549999999993 0.0074936 -0.01505 -0.003496999999999993 0.0077473 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.003975549999999993 0.0074936 -0.01505 -0.004453999999999993 0.0072397 -0.0148 -0.004453999999999993 0.0072397 -0.0148 -0.003975549999999993 0.0074936 -0.01505 -0.003975989999999993 0.0074935 -0.0153 0.01273690000000001 -0.0085086 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 0.01273690000000001 -0.0085086 -0.0158 0.01273690000000001 -0.0085086 -0.0148 0.001366000000000007 -0.0085009 -0.0153 0.004620000000000007 -0.000380699 -0.0153 -0.003496999999999993 0.0077473 -0.0158 -0.003496999999999993 0.0077473 -0.0148 0.004620000000000007 -0.000380699 -0.0153 0.01273690000000001 -0.0085086 -0.0148 0.01273690000000001 -0.0085086 -0.0158 0.01273690000000001 -0.0085086 -0.0148 0.004620000000000007 -0.000380699 -0.0153 -0.003496999999999993 0.0077473 -0.0148 -0.01722999999999999 -0.00062 0.0153 -0.004453999999999993 0.0072397 0.0148 -0.03000599999999999 -0.0084797 0.0148 -0.03000599999999999 -0.0084797 0.0148 -0.03000599999999999 -0.0084797 0.0158 -0.01722999999999999 -0.00062 0.0153 -0.03000799999999999 -0.0119797 0.0148 -0.03000599999999999 -0.0084797 0.0148 -0.004453999999999993 0.0072397 0.0148 -0.01722999999999999 -0.00062 0.0153 -0.004453999999999993 0.0072397 0.0158 -0.004453999999999993 0.0072397 0.0148 -0.01722999999999999 -0.00062 0.0153 -0.03000599999999999 -0.0084797 0.0158 -0.004453999999999993 0.0072397 0.0158 -0.03000599999999999 -0.0084797 0.0158 -0.03000599999999999 -0.0084797 0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.003496999999999993 0.0077473 0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.004453999999999993 0.0072397 0.0148 -0.004453999999999993 0.0072397 0.0158 -0.003975989999999993 0.0074935 0.0153 -0.004214999999999993 0.0073666 0.0153 -0.004453999999999993 0.0072397 0.0148 -0.004453999999999993 0.0072397 0.0158 -0.004214999999999993 0.0073666 0.0153 -0.003975989999999993 0.0074935 0.0153 -0.004453999999999993 0.0072397 0.0148 -0.004214999999999993 0.0073666 0.0153 -0.004453999999999993 0.0072397 0.0158 -0.03000599999999999 -0.0084797 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.03000599999999999 -0.0084797 0.0158 -0.03000799999999999 -0.0119797 0.0148 -0.03000899999999999 -0.0129797 0.0158 -0.004453999999999993 0.0072397 0.0148 -0.003975989999999993 0.0074935 0.0153 -0.003975549999999993 0.0074936 0.01505 -0.003496999999999993 0.0077473 0.0148 -0.004453999999999993 0.0072397 0.0148 -0.003975549999999993 0.0074936 0.01505 -0.003975989999999993 0.0074935 0.0153 -0.003496999999999993 0.0077473 0.0148 -0.003975549999999993 0.0074936 0.01505 -0.03000799999999999 -0.0119797 0.0148 -0.003496999999999993 0.0077473 0.0148 -0.01000599999999999 -0.008493199999999999 0.0148 -0.003975989999999993 0.0074935 0.0153 -0.003975549999999993 0.0074936 0.01555 -0.003496999999999993 0.0077473 0.0158 -0.003496999999999993 0.0077473 0.0158 -0.003975549999999993 0.0074936 0.01555 -0.004453999999999993 0.0072397 0.0158 -0.004453999999999993 0.0072397 0.0158 -0.003975549999999993 0.0074936 0.01555 -0.003975989999999993 0.0074935 0.0153 -0.003496999999999993 0.0077473 0.0158 -0.004453999999999993 0.0072397 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.03000799999999999 -0.0119797 0.0148 -0.03000899999999999 -0.0129797 -0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.003496999999999993 0.0077473 0.0148 -0.003975989999999993 0.0074935 0.0153 -0.003736499999999993 0.0076204 0.0153 -0.003496999999999993 0.0077473 0.0158 -0.003496999999999993 0.0077473 0.0148 -0.003736499999999993 0.0076204 0.0153 -0.003975989999999993 0.0074935 0.0153 -0.003496999999999993 0.0077473 0.0158 -0.003736499999999993 0.0076204 0.0153 -0.01000599999999999 -0.008493199999999999 0.0148 -0.003496999999999993 0.0077473 0.0148 0.01273690000000001 -0.0085086 0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.01000599999999999 -0.008493199999999999 0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.01000599999999999 -0.008493199999999999 0.0158 -0.003496999999999993 0.0077473 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.02886979999999999 -0.0129805 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.02999999999999999 -0.0129797 0.014 -0.02886979999999999 -0.0129805 -0.014 -0.02999999999999999 -0.0129797 -0.014 -0.03000899999999999 -0.0129797 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.0129797 0.014 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.0129797 0 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.0129797 0 -0.03000899999999999 -0.0129797 -0.0158 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.0129797 -0.014 -0.03000799999999999 -0.0119797 -0.0148 -0.03000899999999999 -0.0129797 -0.0158 -0.03000799999999999 -0.0119797 0.0148 0.004620000000000007 -0.000380699 0.0153 -0.003496999999999993 0.0077473 0.0148 -0.003496999999999993 0.0077473 0.0158 0.004620000000000007 -0.000380699 0.0153 0.01273690000000001 -0.0085086 0.0148 -0.003496999999999993 0.0077473 0.0148 0.001366000000000007 -0.0085009 0.0153 -0.01000599999999999 -0.008493199999999999 0.0148 0.01273690000000001 -0.0085086 0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.01000599999999999 -0.008493199999999999 0.0148 -0.01000599999999999 -0.008493199999999999 0.0158 -0.01000799999999999 -0.0119932 0.0148 -0.02000799999999999 -0.0119865 0 -0.02000799999999999 -0.0119865 0.0074 -0.03000799999999999 -0.0119797 0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.02000799999999999 -0.0119865 0.0074 -0.02000799999999999 -0.0119865 0 -0.03000799999999999 -0.0119797 0.0148 -0.02000799999999999 -0.0119865 0.0074 -0.01000899999999999 -0.0129932 0.0158 -0.01000599999999999 -0.008493199999999999 0.0158 -0.03000899999999999 -0.0129797 0.0158 0.01273690000000001 -0.0085086 0.0158 -0.003496999999999993 0.0077473 0.0158 -0.01000599999999999 -0.008493199999999999 0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02247719999999999 -0.0129848 -0.014 -0.02886979999999999 -0.0129805 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01000899999999999 -0.0129932 -0.0158 -0.01199999999999999 -0.0129919 -0.014 -0.01199999999999999 -0.0129919 -0.014 -0.01000899999999999 -0.0129932 -0.0158 -0.01199999999999999 -0.0129919 -0.0126542 -0.02099999999999999 -0.0129858 -0.014 -0.02000899999999999 -0.0129865 -0.0142271 -0.01348629999999999 -0.0129909 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02000899999999999 -0.0129865 -0.0142271 -0.02099999999999999 -0.0129858 -0.014 -0.01000899999999999 -0.0129932 -0.0158 -0.02000899999999999 -0.0129865 -0.0142271 -0.03000899999999999 -0.0129797 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.02000899999999999 -0.0129865 -0.0142271 -0.02247719999999999 -0.0129848 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.02000899999999999 -0.0129865 -0.0142271 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 0.0158 -0.01199999999999999 -0.0129919 0.014 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.0129919 0.014 -0.01000899999999999 -0.0129932 0.0158 -0.01951979999999999 -0.0129868 0.014 -0.02099999999999999 -0.0129858 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.02852889999999999 -0.0129807 0.014 -0.02852889999999999 -0.0129807 0.014 -0.03000899999999999 -0.0129797 0.0158 -0.02886979999999999 -0.0129805 0.014 -0.02099999999999999 -0.0129858 0.014 -0.01951979999999999 -0.0129868 0.014 -0.02000899999999999 -0.0129865 0.0142271 -0.01000899999999999 -0.0129932 0.0158 -0.03000899999999999 -0.0129797 0.0158 -0.02000899999999999 -0.0129865 0.0142271 -0.01951979999999999 -0.0129868 0.014 -0.01000899999999999 -0.0129932 0.0158 -0.02000899999999999 -0.0129865 0.0142271 -0.03000899999999999 -0.0129797 0.0158 -0.02099999999999999 -0.0129858 0.014 -0.02000899999999999 -0.0129865 0.0142271 -0.03000799999999999 -0.0119797 -0.0148 -0.03000599999999999 -0.0084797 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.03000799999999999 -0.0119797 0.0148 -0.02000799999999999 -0.0119865 0 -0.02500799999999999 -0.0119831 8.67362e-19 -0.03000799999999999 -0.0119797 -0.0148 -0.03000799999999999 -0.0119797 0.0148 -0.02500799999999999 -0.0119831 8.67362e-19 -0.02000799999999999 -0.0119865 0 -0.03000799999999999 -0.0119797 -0.0148 -0.02500799999999999 -0.0119831 8.67362e-19 0.004620000000000007 -0.000380699 0.0153 -0.003496999999999993 0.0077473 0.0158 0.01273690000000001 -0.0085086 0.0158 0.01273690000000001 -0.0085086 0.0158 0.01273690000000001 -0.0085086 0.0148 0.004620000000000007 -0.000380699 0.0153 0.01273690000000001 -0.0085086 0.0148 0.01273690000000001 -0.0085086 0.0158 0.001366000000000007 -0.0085009 0.0153 0.001366000000000007 -0.0085009 0.0153 -0.01000599999999999 -0.008493199999999999 0.0158 -0.01000599999999999 -0.008493199999999999 0.0148 -0.01000899999999999 -0.0129932 0.0158 -0.01000799999999999 -0.0119932 0.0148 -0.01000599999999999 -0.008493199999999999 0.0158 -0.01000799999999999 -0.0119932 -0.0148 -0.02000799999999999 -0.0119865 0 -0.01500799999999999 -0.0119898 -8.67362e-19 -0.01000799999999999 -0.0119932 0.0148 -0.01000799999999999 -0.0119932 -0.0148 -0.01500799999999999 -0.0119898 -8.67362e-19 -0.02000799999999999 -0.0119865 0 -0.01000799999999999 -0.0119932 0.0148 -0.01500799999999999 -0.0119898 -8.67362e-19 0.001366000000000007 -0.0085009 0.0153 0.01273690000000001 -0.0085086 0.0158 -0.01000599999999999 -0.008493199999999999 0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 0.0158 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.0129919 -0.0126542 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 -0.0158 -0.01000899999999999 -0.0129932 0.0158 -0.01100449999999999 -0.0129925 0 -0.01199999999999999 -0.0129919 0 -0.01199999999999999 -0.0129919 -0.00231435 -0.01100449999999999 -0.0129925 0 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.0129919 0 -0.01100449999999999 -0.0129925 0 -0.01000899999999999 -0.0129932 0.0158 -0.01199999999999999 -0.0129919 0.0116856 -0.01100449999999999 -0.0129925 0 -0.01199999999999999 -0.0129919 -0.00231435 -0.01000899999999999 -0.0129932 -0.0158 -0.01100449999999999 -0.0129925 0 -0.03000899999999999 -0.0129797 -0.0158 -0.03000599999999999 -0.0084797 -0.0158 -0.004453999999999993 0.0072397 -0.0158 -0.03000599999999999 -0.0084797 -0.0148 -0.03000599999999999 -0.0084797 -0.0158 -0.03000799999999999 -0.0119797 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.02000799999999999 -0.0119865 0 -0.02000799999999999 -0.0119865 -0.0074 -0.01000799999999999 -0.0119932 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.02000799999999999 -0.0119865 -0.0074 -0.02000799999999999 -0.0119865 0 -0.01000799999999999 -0.0119932 -0.0148 -0.02000799999999999 -0.0119865 -0.0074 -0.01000899999999999 -0.0129932 0.0158 -0.01000899999999999 -0.0129932 -0.0158 -0.01000799999999999 -0.0119932 0.0148 -0.01000899999999999 -0.0129932 -0.0158 -0.01000799999999999 -0.0119932 -0.0148 -0.01000799999999999 -0.0119932 0.0148 -0.01000899999999999 -0.0129932 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.03000899999999999 -0.0129797 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.03000599999999999 -0.0084797 -0.0158 -0.01722999999999999 -0.00062 -0.0153 -0.004453999999999993 0.0072397 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.03000899999999999 -0.0129797 -0.0158 -0.004453999999999993 0.0072397 -0.0158 -0.03000599999999999 -0.0084797 -0.0158 -0.03000599999999999 -0.0084797 -0.0148 -0.01722999999999999 -0.00062 -0.0153 -0.004453999999999993 0.0072397 -0.0148 -0.03000599999999999 -0.0084797 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.01000799999999999 -0.0119932 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.01000799999999999 -0.0119932 -0.0148 -0.01000899999999999 -0.0129932 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0148 0.001366000000000007 -0.0085009 -0.0153 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.01000599999999999 -0.008493199999999999 -0.0158 -0.003496999999999993 0.0077473 -0.0158 0.01273690000000001 -0.0085086 -0.0158 -0.01722999999999999 -0.00062 -0.0153 -0.004453999999999993 0.0072397 -0.0148 -0.004453999999999993 0.0072397 -0.0158 -0.003975989999999993 0.0074935 -0.0153 -0.003975549999999993 0.0074936 -0.01555 -0.004453999999999993 0.0072397 -0.0158 -0.004453999999999993 0.0072397 -0.0158 -0.003975549999999993 0.0074936 -0.01555 -0.003496999999999993 0.0077473 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.003975549999999993 0.0074936 -0.01555 -0.003975989999999993 0.0074935 -0.0153 -0.01722999999999999 -0.00062 -0.0153 -0.03000599999999999 -0.0084797 -0.0148 -0.004453999999999993 0.0072397 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.004453999999999993 0.0072397 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.03000799999999999 -0.0119797 -0.0148 0.001366000000000007 -0.0085009 -0.0153 -0.01000599999999999 -0.008493199999999999 -0.0158 0.01273690000000001 -0.0085086 -0.0158 0.001366000000000007 -0.0085009 -0.0153 0.01273690000000001 -0.0085086 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 0.004620000000000007 -0.000380699 -0.0153 0.01273690000000001 -0.0085086 -0.0158 -0.003496999999999993 0.0077473 -0.0158 -0.004453999999999993 0.0072397 -0.0148 -0.003975989999999993 0.0074935 -0.0153 -0.004214999999999993 0.0073666 -0.0153 -0.004453999999999993 0.0072397 -0.0158 -0.004453999999999993 0.0072397 -0.0148 -0.004214999999999993 0.0073666 -0.0153 -0.003975989999999993 0.0074935 -0.0153 -0.004453999999999993 0.0072397 -0.0158 -0.004214999999999993 0.0073666 -0.0153 -0.003496999999999993 0.0077473 -0.0158 -0.003975989999999993 0.0074935 -0.0153 -0.003736499999999993 0.0076204 -0.0153 -0.003496999999999993 0.0077473 -0.0148 -0.003496999999999993 0.0077473 -0.0158 -0.003736499999999993 0.0076204 -0.0153 -0.003975989999999993 0.0074935 -0.0153 -0.003496999999999993 0.0077473 -0.0148 -0.003736499999999993 0.0076204 -0.0153 -0.003975989999999993 0.0074935 -0.0153 -0.003975549999999993 0.0074936 -0.01505 -0.003496999999999993 0.0077473 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.003975549999999993 0.0074936 -0.01505 -0.004453999999999993 0.0072397 -0.0148 -0.004453999999999993 0.0072397 -0.0148 -0.003975549999999993 0.0074936 -0.01505 -0.003975989999999993 0.0074935 -0.0153 0.01273690000000001 -0.0085086 -0.0148 -0.003496999999999993 0.0077473 -0.0148 -0.01000599999999999 -0.008493199999999999 -0.0148 0.01273690000000001 -0.0085086 -0.0158 0.01273690000000001 -0.0085086 -0.0148 0.001366000000000007 -0.0085009 -0.0153 0.004620000000000007 -0.000380699 -0.0153 -0.003496999999999993 0.0077473 -0.0158 -0.003496999999999993 0.0077473 -0.0148 0.004620000000000007 -0.000380699 -0.0153 0.01273690000000001 -0.0085086 -0.0148 0.01273690000000001 -0.0085086 -0.0158 0.01273690000000001 -0.0085086 -0.0148 0.004620000000000007 -0.000380699 -0.0153 -0.003496999999999993 0.0077473 -0.0148 -0.02999999999999999 -0.0129797 -0.014 -0.02886979999999999 -0.0129805 -0.014 -0.02999999999999999 -0.018 -0.014 -0.02999999999999999 -0.018 -0.014 -0.02886979999999999 -0.0129805 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02886979999999999 -0.0129805 0.014 -0.02999999999999999 -0.0129797 0.014 -0.02999999999999999 -0.018 0.014 -0.02852889999999999 -0.0129807 0.014 -0.02886979999999999 -0.0129805 0.014 -0.02999999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.014 -0.02852889999999999 -0.0129807 0.014 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.0129797 0.014 -0.02999999999999999 -0.0129797 0 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.0129797 0 -0.02999999999999999 -0.0129797 -0.014 -0.02999999999999999 -0.018 -0.014 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.018 -0.014 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02099999999999999 -0.018 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02099999999999999 -0.0129858 -0.014 -0.02099999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01199999999999999 -0.018 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01199999999999999 -0.0129919 -0.014 -0.01199999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.014 -0.02099999999999999 -0.0129858 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 -0.0126542 -0.01199999999999999 -0.0129919 -0.0126542 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 -0.014 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.0129919 0.014 -0.01951979999999999 -0.0129868 0.014 -0.01951979999999999 -0.0129868 0.014 -0.02099999999999999 -0.0129858 0.014 -0.02099999999999999 -0.018 0.014 -0.01199999999999999 -0.018 0.014 -0.01951979999999999 -0.0129868 0.014 -0.02099999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.014 -0.02099999999999999 -0.0129858 0.014 -0.02852889999999999 -0.0129807 0.014 -0.01199999999999999 -0.0129919 0.014 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 0.014 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.014 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.014 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 0 -0.01199999999999999 -0.018 0 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.018 0 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.018 0 -0.01199999999999999 -0.0129919 0 -0.01199999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.014 -0.01199999999999999 -0.018 0 -0.02999999999999999 -0.018 0 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 0.007 -0.02099999999999999 -0.018 0.014 -0.02999999999999999 -0.018 0 -0.02099999999999999 -0.018 0.007 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.007 -0.01199999999999999 -0.018 0 -0.02999999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.007 -0.02099999999999999 -0.018 -0.014 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.007 -0.02999999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.007 -0.02999999999999999 -0.0129797 -0.014 -0.02886979999999999 -0.0129805 -0.014 -0.02999999999999999 -0.018 -0.014 -0.02999999999999999 -0.018 -0.014 -0.02886979999999999 -0.0129805 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02886979999999999 -0.0129805 0.014 -0.02999999999999999 -0.0129797 0.014 -0.02999999999999999 -0.018 0.014 -0.02852889999999999 -0.0129807 0.014 -0.02886979999999999 -0.0129805 0.014 -0.02999999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.014 -0.02852889999999999 -0.0129807 0.014 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.0129797 0.014 -0.02999999999999999 -0.0129797 0 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.0129797 0 -0.02999999999999999 -0.0129797 -0.014 -0.02999999999999999 -0.018 -0.014 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.018 -0.014 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02099999999999999 -0.018 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02099999999999999 -0.0129858 -0.014 -0.02099999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01199999999999999 -0.018 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01199999999999999 -0.0129919 -0.014 -0.01199999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.014 -0.02099999999999999 -0.0129858 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 -0.0126542 -0.01199999999999999 -0.0129919 -0.0126542 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 -0.014 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.0129919 0.014 -0.01951979999999999 -0.0129868 0.014 -0.01951979999999999 -0.0129868 0.014 -0.02099999999999999 -0.0129858 0.014 -0.02099999999999999 -0.018 0.014 -0.01199999999999999 -0.018 0.014 -0.01951979999999999 -0.0129868 0.014 -0.02099999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.014 -0.02099999999999999 -0.0129858 0.014 -0.02852889999999999 -0.0129807 0.014 -0.01199999999999999 -0.0129919 0.014 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 0.014 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.014 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.014 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 0 -0.01199999999999999 -0.018 0 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.018 0 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.018 0 -0.01199999999999999 -0.0129919 0 -0.01199999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.014 -0.01199999999999999 -0.018 0 -0.02999999999999999 -0.018 0 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 0.007 -0.02099999999999999 -0.018 0.014 -0.02999999999999999 -0.018 0 -0.02099999999999999 -0.018 0.007 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.007 -0.01199999999999999 -0.018 0 -0.02999999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.007 -0.02099999999999999 -0.018 -0.014 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.007 -0.02999999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.007 -0.02999999999999999 -0.0129797 -0.014 -0.02886979999999999 -0.0129805 -0.014 -0.02999999999999999 -0.018 -0.014 -0.02999999999999999 -0.018 -0.014 -0.02886979999999999 -0.0129805 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02886979999999999 -0.0129805 0.014 -0.02999999999999999 -0.0129797 0.014 -0.02999999999999999 -0.018 0.014 -0.02852889999999999 -0.0129807 0.014 -0.02886979999999999 -0.0129805 0.014 -0.02999999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.014 -0.02852889999999999 -0.0129807 0.014 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.0129797 0.014 -0.02999999999999999 -0.0129797 0 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.0129797 0.00228598 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.0129797 0 -0.02999999999999999 -0.0129797 -0.014 -0.02999999999999999 -0.018 -0.014 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.0129797 -0.011714 -0.02999999999999999 -0.018 -0.014 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02099999999999999 -0.018 -0.014 -0.02247719999999999 -0.0129848 -0.014 -0.02099999999999999 -0.0129858 -0.014 -0.02099999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01199999999999999 -0.018 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01199999999999999 -0.0129919 -0.014 -0.01199999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.014 -0.02099999999999999 -0.0129858 -0.014 -0.01348629999999999 -0.0129909 -0.014 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 -0.0126542 -0.01199999999999999 -0.0129919 -0.0126542 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 -0.014 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.0129919 0.014 -0.01951979999999999 -0.0129868 0.014 -0.01951979999999999 -0.0129868 0.014 -0.02099999999999999 -0.0129858 0.014 -0.02099999999999999 -0.018 0.014 -0.01199999999999999 -0.018 0.014 -0.01951979999999999 -0.0129868 0.014 -0.02099999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.014 -0.02099999999999999 -0.0129858 0.014 -0.02852889999999999 -0.0129807 0.014 -0.01199999999999999 -0.0129919 0.014 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.0129919 0.0126542 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.018 0.014 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 0.014 -0.02999999999999999 -0.018 0.014 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 0 -0.02999999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.014 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.014 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 0 -0.01199999999999999 -0.018 0 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.0129919 -0.00231435 -0.01199999999999999 -0.018 0 -0.01199999999999999 -0.018 -0.014 -0.01199999999999999 -0.0129919 0.0116856 -0.01199999999999999 -0.018 0 -0.01199999999999999 -0.0129919 0 -0.01199999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.014 -0.01199999999999999 -0.018 0 -0.02999999999999999 -0.018 0 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 0.007 -0.02099999999999999 -0.018 0.014 -0.02999999999999999 -0.018 0 -0.02099999999999999 -0.018 0.007 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 0.014 -0.02099999999999999 -0.018 0.007 -0.01199999999999999 -0.018 0 -0.02999999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.007 -0.02099999999999999 -0.018 -0.014 -0.01199999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.007 -0.02999999999999999 -0.018 0 -0.02099999999999999 -0.018 -0.014 -0.02099999999999999 -0.018 -0.007 - - - - - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439

    -
    -
    - - - 6.938893903907228e-18 0 0 - 1 0 0 0 - - true - - - -
    -
    - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0 2 2 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - 0.2000000029802322 0.2000000029802322 0.2000000029802322 1 - - - 0.8999999761581421 0.8999999761581421 0.8999999761581421 1 - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 - 1 0 0 0 - - - - - - - - - 0 0 0 - 1 0 0 0 - 0 0 1 0 - 0 0 0 - 1 0 0 0 - - - - - - - - - - - - - - - - 0 0 0.5695 - 1 0 0 0 - 0 0 1 0 - 0 0 0 - 1 0 0 0 - - - - - - - - - 0 0 0 - -1 0 0 89.99999999999999 - 0 0 1 0 - 0 0 0 - 1 0 0 89.99999999999999 - - - - - - - - - - - 0 -0.145 0.370296 - 1 0 0 15 - 0 0 1 0 - 0 0 0 - 1 0 0 0 - - - - - - - - - 0 0 0 - -1 0 0 89.99999999999999 - 0 0 1 0 - 0 0 0 - 1 0 0 89.99999999999999 - - - - - - - - - 0 -0.095 -0.25 - -1 0 0 89.99999999999999 - 0 0 1 0 - 0 -5.551115123125783e-17 1.232595164407831e-32 - 1 0 0 89.99999999999999 - - - - - - - - - -0.03 0 0 - 1 0 0 0 - 0 0 1 0 - 0 0 0 - 1 0 0 0 - - - - - - - - - 0 0 -0.235 - -1 0 0 89.99999999999999 - 0 0 1 0 - 0 2.775557561562891e-17 -6.162975822039155e-33 - 1 0 0 89.99999999999999 - - - - - - - - - -0.04 0 -0.09 - 0 1 0 89.99999999999999 - 0 0 1 0 - -1.540743955509789e-33 0 -6.938893903907228e-18 - 0 -1 0 89.99999999999999 - - - - - - - - - -0.0299 -0.033 0 - 1 0 0 0 - 0 0 1 0 - 3.469446951953614e-18 0 0 - 1 0 0 0 - - - - - - - - - -0.0419 0 0 - 1 0 0 0 - 0 0 1 0 - -6.938893903907228e-18 0 0 - 1 0 0 0 - - - - - - - - - - - -0.0299 0.033 0 - 1 0 0 0 - 0 0 1 0 - 3.469446951953614e-18 0 0 - 1 0 0 0 - - - - - - - - - -0.0419 0 0 - 1 0 0 0 - 0 0 1 0 - -6.938893903907228e-18 0 0 - 1 0 0 0 - - - - - - - - - - - - - - - - - 0 0.145 0.370296 - -1 0 0 15 - 0 0 1 0 - 0 0 0 - 1 0 0 0 - - - - - - - - - 0 0 0 - -1 0 0 89.99999999999999 - 0 0 1 0 - 0 0 0 - 1 0 0 89.99999999999999 - - - - - - - - - 0 0.095 -0.25 - -1 0 0 89.99999999999999 - 0 0 1 0 - 0 -5.551115123125783e-17 1.232595164407831e-32 - 1 0 0 89.99999999999999 - - - - - - - - - -0.03 0 0 - 1 0 0 0 - 0 0 1 0 - 0 0 0 - 1 0 0 0 - - - - - - - - - 0 0 -0.235 - -1 0 0 89.99999999999999 - 0 0 1 0 - 0 2.775557561562891e-17 -6.162975822039155e-33 - 1 0 0 89.99999999999999 - - - - - - - - - -0.04 0 -0.09 - 0 1 0 89.99999999999999 - 0 0 1 0 - -1.540743955509789e-33 0 -6.938893903907228e-18 - 0 -1 0 89.99999999999999 - - - - - - - - - -0.0299 -0.033 0 - 1 0 0 0 - 0 0 1 0 - 3.469446951953614e-18 0 0 - 1 0 0 0 - - - - - - - - - -0.0419 0 0 - 1 0 0 0 - 0 0 1 0 - -6.938893903907228e-18 0 0 - 1 0 0 0 - - - - - - - - - - - -0.0299 0.033 0 - 1 0 0 0 - 0 0 1 0 - 3.469446951953614e-18 0 0 - 1 0 0 0 - - - - - - - - - -0.0419 0 0 - 1 0 0 0 - 0 0 1 0 - -6.938893903907228e-18 0 0 - 1 0 0 0 - - - - - - - - - - - - - - - - - - - - - - :Interface Author: Rosen Diankov - -Simplest robot possible that just passes the trajectories to the controller - - - - - 0 0 1 - - -162.949 - 162.949 - - - - - - 0 0 1 - - -70 - 70 - - - - - - 0 0 1 - - -20 - 70 - - - - - - 0 0 1 - - -88 - 88 - - - - - - 0 0 1 - - -140 - 59.99999999999999 - - - - - - 0 0 1 - - -158 - 0 - - - - - - 0 0 1 - - -165 - 105 - - - - - - 0 0 1 - - -100 - 100 - - - - - - 0 0 1 - - -163 - 163 - - - - - - 0 0 1 - - -30 - 30 - - - - - - 0 0 1 - - -30 - 30 - - - - - - 0 0 1 - - -30 - 30 - - - - - - 0 0 1 - - -30 - 30 - - - - - - 0 0 1 - - -88 - 88 - - - - - - 0 0 1 - - -140 - 59.99999999999999 - - - - - - 0 0 1 - - -158 - 0 - - - - - - 0 0 1 - - -165 - 105 - - - - - - 0 0 1 - - -100 - 100 - - - - - - 0 0 1 - - -163 - 163 - - - - - - 0 0 1 - - -30 - 30 - - - - - - 0 0 1 - - -30 - 30 - - - - - - 0 0 1 - - -30 - 30 - - - - - - 0 0 1 - - -30 - 30 - - - - - 0 0 0 - 1 0 0 0 - - 0 0 0 - 1 0 0 0 - - 0 0 0 - 1 0 0 0 - - 0 0 0.5695 - 1 0 0 0 - - 0 0 0 - 1 0 0 0 - - 0 0 0 - -1 0 0 89.99999999999999 - - 0 0 0 - 1 0 0 89.99999999999999 - - - - - - 0 -0.145 0.370296 - 1 0 0 15 - - 0 0 0 - 1 0 0 0 - - 0 0 0 - -1 0 0 89.99999999999999 - - 0 0 0 - 1 0 0 89.99999999999999 - - 0 -0.095 -0.25 - -1 0 0 89.99999999999999 - - 0 -5.551115123125783e-17 1.232595164407831e-32 - 1 0 0 89.99999999999999 - - -0.03 0 0 - 1 0 0 0 - - 0 0 0 - 1 0 0 0 - - 0 0 -0.235 - -1 0 0 89.99999999999999 - - 0 2.775557561562891e-17 -6.162975822039155e-33 - 1 0 0 89.99999999999999 - - -0.04 0 -0.09 - 0 1 0 89.99999999999999 - - -1.540743955509789e-33 0 -6.938893903907228e-18 - 0 -1 0 89.99999999999999 - - -0.0299 -0.033 0 - 1 0 0 0 - - 3.469446951953614e-18 0 0 - 1 0 0 0 - - -0.0419 0 0 - 1 0 0 0 - - -6.938893903907228e-18 0 0 - 1 0 0 0 - - - - - - -0.0299 0.033 0 - 1 0 0 0 - - 3.469446951953614e-18 0 0 - 1 0 0 0 - - -0.0419 0 0 - 1 0 0 0 - - -6.938893903907228e-18 0 0 - 1 0 0 0 - - - - - - - - - - - - - - - - - - 0 0.145 0.370296 - -1 0 0 15 - - 0 0 0 - 1 0 0 0 - - 0 0 0 - -1 0 0 89.99999999999999 - - 0 0 0 - 1 0 0 89.99999999999999 - - 0 0.095 -0.25 - -1 0 0 89.99999999999999 - - 0 -5.551115123125783e-17 1.232595164407831e-32 - 1 0 0 89.99999999999999 - - -0.03 0 0 - 1 0 0 0 - - 0 0 0 - 1 0 0 0 - - 0 0 -0.235 - -1 0 0 89.99999999999999 - - 0 2.775557561562891e-17 -6.162975822039155e-33 - 1 0 0 89.99999999999999 - - -0.04 0 -0.09 - 0 1 0 89.99999999999999 - - -1.540743955509789e-33 0 -6.938893903907228e-18 - 0 -1 0 89.99999999999999 - - -0.0299 -0.033 0 - 1 0 0 0 - - 3.469446951953614e-18 0 0 - 1 0 0 0 - - -0.0419 0 0 - 1 0 0 0 - - -6.938893903907228e-18 0 0 - 1 0 0 0 - - - - - - -0.0299 0.033 0 - 1 0 0 0 - - 3.469446951953614e-18 0 0 - 1 0 0 0 - - -0.0419 0 0 - 1 0 0 0 - - -6.938893903907228e-18 0 0 - 1 0 0 0 - - - - - - - - - - - - - - - - - - - - - - - GenericRobot - - - - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - - - - - - - - - body1_kinematics/kmodel1_inst - - - body1_kinematics/kmodel1_inst/joint0/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint1/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint2/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint3/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint4/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint5/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint6/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint7/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint8/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint9/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint10/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint11/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint12/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint13/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint14/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint15/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint16/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint17/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint18/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint19/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint20/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint21/axis0 - - - 0 - - - body1_kinematics/kmodel1_inst/joint22/axis0 - - - 0 - - - - - - true - - - false - - - -162.949 - - - 162.949 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 0 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -70 - - - 70 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 1 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -20 - - - 70 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 2 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -88 - - - 88 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 3 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -140 - - - 59.99999999999999 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 4 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -158 - - - 0 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 5 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -165 - - - 105 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 6 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -100 - - - 100 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 7 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -163 - - - 163 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 8 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -30 - - - 30 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 9 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -30 - - - 30 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 10 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -30 - - - 30 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 11 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -30 - - - 30 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 12 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -88 - - - 88 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 13 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -140 - - - 59.99999999999999 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 14 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -158 - - - 0 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 15 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -165 - - - 105 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 16 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -100 - - - 100 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 17 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -163 - - - 163 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 18 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -30 - - - 30 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 19 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -30 - - - 30 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 20 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -30 - - - 30 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 21 - - - - positionmin - - - positionmax - - - - - - true - - - false - - - -30 - - - 30 - - - false - - - 1 - - - 0.02 - - - active - - - locked - - - 22 - - - - positionmin - - - positionmax - - - - - - - - - - - body1_kinematics/body1_kinematics_kmodel1_inst - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint0.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint0.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint1.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint1.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint2.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint2.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint3.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint3.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint4.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint4.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint5.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint5.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint6.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint6.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint7.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint7.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint8.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint8.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint9.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint9.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint10.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint10.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint11.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint11.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint12.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint12.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint13.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint13.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint14.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint14.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint15.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint15.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint16.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint16.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint17.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint17.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint18.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint18.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint19.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint19.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint20.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint20.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint21.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint21.axis0_value - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint22.axis0 - - - body1_kinematics/body1_kinematics_kmodel1_inst_joint22.axis0_value - - - - - - 129.9468279356707 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 149.9997778074544 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 249.9998206650224 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 172.0002112248877 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 133.0001200259229 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 228.9997715578874 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 149.9997778074544 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 249.9998206650224 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 300.0001285727039 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 28.64788975654116 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 28.64788975654116 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 28.64788975654116 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 28.64788975654116 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 172.0002112248877 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 133.0001200259229 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 228.9997715578874 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 149.9997778074544 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 249.9998206650224 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 300.0001285727039 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 28.64788975654116 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 28.64788975654116 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 28.64788975654116 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - 28.64788975654116 - - - 2864.788975654116 - - - speed - - - acceleration - - - - - - - GenericRobot - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -0.05 0 0 - 0 -1 0 89.99999999999999 - 0 0 1 - - - - -1 - - - - - -1 - - - - - 1 - - - - - 1 - - - - - - - - - -0.05 0 0 - 0 -1 0 89.99999999999999 - 0 0 1 - - - - -1 - - - - - -1 - - - - - 1 - - - - - 1 - - - - - - - - - -0.05 0 0 - 0 -1 0 89.99999999999999 - 0 0 1 - - - - -1 - - - - - -1 - - - - - 1 - - - - - 1 - - - - - - - - - -0.05 0 0 - 0 -1 0 89.99999999999999 - 0 0 1 - - - - -1 - - - - - -1 - - - - - 1 - - - - - 1 - - - - - - - - - 0.09 0.07000000000000001 0.08500000000000001 - 0.5773502691896257 0.5773502691896257 0.5773502691896257 120 - 0 0 1 - - - - - - - - 0.09 0.07000000000000001 0.08500000000000001 - 0.5773502691896257 0.5773502691896257 0.5773502691896257 120 - 0 0 1 - - - - - - - - - - body1_motion/body1_motion_kmodel1_inst - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint0.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint1.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint2.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint3.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint4.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint5.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint6.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint7.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint8.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint9.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint10.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint11.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint12.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint13.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint14.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint15.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint16.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint17.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint18.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint19.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint20.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint21.axis0 - - - 0 - - - body1_motion/body1_motion_body1_kinematics_kmodel1_inst_joint22.axis0 - - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 -9.797930195020351 - - - - - - - - true - 0 - - 0 0 0 - 1 0 0 0 - - 0 0 0 - - - 0 0 0 - 1 0 0 0 - - - - - - true - 0 - - 0 0 0 - 1 0 0 0 - - 0 0 0 - - - 0 0 0 - 1 0 0 0 - - - - 0 0 0 - 1 0 0 0 - - - - - - true - 0.317929 - - -2.292e-05 0.00547848 0.56165984 - 1 0 0 0 - - 0 0 0 - - - 0 0 0.5695 - 1 0 0 0 - - - - - - true - 0.0808593 - - 5.02e-06 -0.0166777 0.5858153 - 1 0 0 0 - - 0 0 0 - - - 0 0 0.5695 - 1 0 0 0 - - - - - - true - 1.32626 - - -0.00226388 -0.1440035004869839 0.3867217053912293 - 1 0 0 15 - - 0 0 0 - - - 0 -0.145 0.370296 - 1 0 0 15 - - - - - - true - 1.14898 - - -5.236e-05 -0.173616993291004 0.2517903966069848 - 1 0 0 15 - - 0 0 0 - - - 0 -0.145 0.370296 - 1 0 0 15 - - - - - - true - 0.577518 - - -2.254e-05 -0.1551637578666148 0.03471932808204067 - 1 0 0 15 - - 0 0 0 - - - 0 -0.1720581922218313 0.1042267341429934 - 1 0 0 15 - - - - - - true - 0.457418 - - -0.03001788 -0.1157642980576009 -0.09057193770761446 - 1 0 0 15 - - 0 0 0 - - - -0.03 -0.1720581922218313 0.1042267341429935 - 1 0 0 15 - - - - - - true - 0.418434 - - -0.02756869 -0.09996886508970339 -0.1794860538693306 - 1 0 0 15 - - 0 0 0 - - - -0.03 -0.111235716622739 -0.1227658350349375 - 1 0 0 15 - - - - - - true - 1.05156 - - -0.118476 -0.07787116132923402 -0.2472716867116626 - 1 0 0 15 - - 0 0 0 - - - -0.07000000000000001 -0.08794200256351209 -0.2096991594009537 - 1 0 0 15 - - - - - - true - 0.01 - - -0.0999 -0.1198175548310513 -0.2182401878893369 - 1 0 0 15 - - 0 0 0 - - - -0.0999 -0.1198175548310513 -0.2182401878893369 - 1 0 0 15 - - - - - - true - 0.01 - - -0.1418 -0.1198175548310513 -0.2182401878893369 - 1 0 0 15 - - 0 0 0 - - - -0.1418 -0.1198175548310513 -0.2182401878893369 - 1 0 0 15 - - - - - - true - 0.01 - - -0.0999 -0.05606645029597283 -0.2011581309125705 - 1 0 0 15 - - 0 0 0 - - - -0.0999 -0.05606645029597283 -0.2011581309125705 - 1 0 0 15 - - - - - - true - 0.01 - - -0.1418 -0.05606645029597283 -0.2011581309125705 - 1 0 0 15 - - 0 0 0 - - - -0.1418 -0.05606645029597283 -0.2011581309125705 - 1 0 0 15 - - - - - - true - 1.32626 - - -0.00226388 0.1440035004869839 0.3867217053912293 - -1 0 0 15 - - 0 0 0 - - - 0 0.145 0.370296 - -1 0 0 15 - - - - - - true - 1.14898 - - -5.236e-05 0.173616993291004 0.2517903966069848 - -1 0 0 15 - - 0 0 0 - - - 0 0.145 0.370296 - -1 0 0 15 - - - - - - true - 0.577518 - - -2.254e-05 0.1551637578666148 0.03471932808204067 - -1 0 0 15 - - 0 0 0 - - - 0 0.1720581922218313 0.1042267341429934 - -1 0 0 15 - - - - - - true - 0.457418 - - -0.03001788 0.1157642980576009 -0.09057193770761446 - -1 0 0 15 - - 0 0 0 - - - -0.03 0.1720581922218313 0.1042267341429935 - -1 0 0 15 - - - - - - true - 0.418434 - - -0.02756869 0.09996886508970339 -0.1794860538693306 - -1 0 0 15 - - 0 0 0 - - - -0.03 0.111235716622739 -0.1227658350349375 - -1 0 0 15 - - - - - - true - 1.05156 - - -0.118476 0.07787116132923402 -0.2472716867116626 - -1 0 0 15 - - 0 0 0 - - - -0.07000000000000001 0.08794200256351209 -0.2096991594009537 - -1 0 0 15 - - - - - - true - 0.01 - - -0.0999 0.05606645029597283 -0.2011581309125705 - -1 0 0 15 - - 0 0 0 - - - -0.0999 0.05606645029597283 -0.2011581309125705 - -1 0 0 15 - - - - - - true - 0.01 - - -0.1418 0.05606645029597283 -0.2011581309125705 - -1 0 0 15 - - 0 0 0 - - - -0.1418 0.05606645029597283 -0.2011581309125705 - -1 0 0 15 - - - - - - true - 0.01 - - -0.0999 0.1198175548310513 -0.2182401878893369 - -1 0 0 15 - - 0 0 0 - - - -0.0999 0.1198175548310513 -0.2182401878893369 - -1 0 0 15 - - - - - - true - 0.01 - - -0.1418 0.1198175548310513 -0.2182401878893369 - -1 0 0 15 - - 0 0 0 - - - -0.1418 0.1198175548310513 -0.2182401878893369 - -1 0 0 15 - - - - - - - - - - - kscene_kmodel1_inst - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint0.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint0.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint1.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint1.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint2.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint2.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint3.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint3.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint4.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint4.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint5.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint5.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint6.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint6.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint7.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint7.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint8.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint8.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint9.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint9.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint10.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint10.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint11.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint11.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint12.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint12.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint13.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint13.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint14.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint14.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint15.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint15.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint16.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint16.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint17.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint17.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint18.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint18.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint19.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint19.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint20.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint20.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint21.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint21.axis0_value - - - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint22.axis0 - - - kscene_kmodel1_inst_body1_kinematics_kmodel1_inst_joint22.axis0_value - - - - - - - - - - -
    diff --git a/examples/models/fbx/README.md b/examples/models/fbx/README.md new file mode 100644 index 00000000000000..edb6df04936ff0 --- /dev/null +++ b/examples/models/fbx/README.md @@ -0,0 +1,5 @@ +## License of the files in this directory + +### nurbs.fbx + +License: Public domain ([CC0](https://creativecommons.org/publicdomain/zero/1.0/)) diff --git a/examples/models/gltf/DamagedHelmet/glTF-instancing/DamagedHelmetGpuInstancing.gltf b/examples/models/gltf/DamagedHelmet/glTF-instancing/DamagedHelmetGpuInstancing.gltf new file mode 100644 index 00000000000000..ad7f1e2baecf3e --- /dev/null +++ b/examples/models/gltf/DamagedHelmet/glTF-instancing/DamagedHelmetGpuInstancing.gltf @@ -0,0 +1,287 @@ +{ + "extensionsUsed" : [ + "EXT_mesh_gpu_instancing" + ], + "extensionsRequired" : [ + "EXT_mesh_gpu_instancing" + ], + "accessors" : [ + { + "bufferView" : 0, + "componentType" : 5123, + "count" : 46356, + "max" : [ + 14555 + ], + "min" : [ + 0 + ], + "type" : "SCALAR" + }, + { + "bufferView" : 1, + "componentType" : 5126, + "count" : 14556, + "max" : [ + 0.9424954056739807, + 0.8128451108932495, + 0.900973916053772 + ], + "min" : [ + -0.9474585652351379, + -1.18715500831604, + -0.9009949564933777 + ], + "type" : "VEC3" + }, + { + "bufferView" : 2, + "componentType" : 5126, + "count" : 14556, + "max" : [ + 1.0, + 1.0, + 1.0 + ], + "min" : [ + -1.0, + -1.0, + -1.0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 3, + "componentType" : 5126, + "count" : 14556, + "max" : [ + 0.9999759793281555, + 1.998665988445282 + ], + "min" : [ + 0.002448640065267682, + 1.0005531199858524 + ], + "type" : "VEC2" + }, + { + "bufferView" : 4, + "componentType" : 5126, + "count" : 64, + "type" : "VEC3", + "max" : [ + 8.0, + 8.0, + 0.0 + ], + "min" : [ + 0.0, + 0.0, + 0.0 + ] + }, + { + "bufferView" : 5, + "componentType" : 5126, + "count" : 64, + "type" : "VEC4" + }, + { + "bufferView" : 6, + "componentType" : 5126, + "count" : 64, + "type" : "VEC3", + "max" : [ + 0.125, + 0.125, + 0.125 + ], + "min" : [ + 0.0, + 0.0, + 0.0 + ] + } + ], + "asset" : { + "generator" : "Khronos Blender glTF 2.0 exporter", + "version" : "2.0" + }, + "bufferViews" : [ + { + "buffer" : 0, + "byteLength" : 92712, + "byteOffset" : 0, + "target" : 34963 + }, + { + "buffer" : 0, + "byteLength" : 174672, + "byteOffset" : 92712, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 174672, + "byteOffset" : 267384, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 116448, + "byteOffset" : 442056, + "target" : 34962 + }, + { + "buffer": 1, + "byteOffset": 0, + "byteLength": 768, + "name": "gpuInstancingTranslation" + }, + { + "buffer": 2, + "byteOffset": 0, + "byteLength": 1024, + "name": "gpuInstancingRotation" + }, + { + "buffer": 3, + "byteOffset": 0, + "byteLength": 768, + "name": "gpuInstancingScale" + } + ], + "buffers" : [ + { + "byteLength" : 558504, + "uri" : "../glTF/DamagedHelmet.bin" + }, + { + "uri": "GpuInstancingTranslation.bin", + "byteLength": 768 + }, + { + "uri": "GpuInstancingRotation.bin", + "byteLength": 1024 + }, + { + "uri": "GpuInstancingScale.bin", + "byteLength": 768 + } + ], + "images" : [ + { + "uri" : "../glTF/Default_albedo.jpg" + }, + { + "uri" : "../glTF/Default_metalRoughness.jpg" + }, + { + "uri" : "../glTF/Default_emissive.jpg" + }, + { + "uri" : "../glTF/Default_AO.jpg" + }, + { + "uri" : "../glTF/Default_normal.jpg" + } + ], + "materials" : [ + { + "emissiveFactor" : [ + 1.0, + 1.0, + 1.0 + ], + "emissiveTexture" : { + "index" : 2 + }, + "name" : "Material_MR", + "normalTexture" : { + "index" : 4 + }, + "occlusionTexture" : { + "index" : 3 + }, + "pbrMetallicRoughness" : { + "baseColorTexture" : { + "index" : 0 + }, + "metallicRoughnessTexture" : { + "index" : 1 + } + } + } + ], + "meshes" : [ + { + "name" : "mesh_helmet_LP_13930damagedHelmet", + "primitives" : [ + { + "attributes" : { + "NORMAL" : 2, + "POSITION" : 1, + "TEXCOORD_0" : 3 + }, + "indices" : 0, + "material" : 0 + } + ] + } + ], + "nodes" : [ + { + "extensions" : { + "EXT_mesh_gpu_instancing" : { + "attributes" : { + "TRANSLATION" : 4, + "ROTATION" : 5, + "SCALE" : 6 + } + } + }, + "mesh" : 0, + "name" : "node_damagedHelmet_-6514", + "rotation" : [ + 0.7071068286895752, + 0.0, + -0.0, + 0.7071068286895752 + ] + } + ], + "samplers" : [ + {} + ], + "scene" : 0, + "scenes" : [ + { + "name" : "Scene", + "nodes" : [ + 0 + ] + } + ], + "textures" : [ + { + "sampler" : 0, + "source" : 0 + }, + { + "sampler" : 0, + "source" : 1 + }, + { + "sampler" : 0, + "source" : 2 + }, + { + "sampler" : 0, + "source" : 3 + }, + { + "sampler" : 0, + "source" : 4 + } + ] +} diff --git a/examples/models/gltf/DamagedHelmet/glTF-instancing/GpuInstancingRotation.bin b/examples/models/gltf/DamagedHelmet/glTF-instancing/GpuInstancingRotation.bin new file mode 100644 index 00000000000000..36642dd9c103af Binary files /dev/null and b/examples/models/gltf/DamagedHelmet/glTF-instancing/GpuInstancingRotation.bin differ diff --git a/examples/models/gltf/DamagedHelmet/glTF-instancing/GpuInstancingScale.bin b/examples/models/gltf/DamagedHelmet/glTF-instancing/GpuInstancingScale.bin new file mode 100644 index 00000000000000..04cff186df19c0 Binary files /dev/null and b/examples/models/gltf/DamagedHelmet/glTF-instancing/GpuInstancingScale.bin differ diff --git a/examples/models/gltf/DamagedHelmet/glTF-instancing/GpuInstancingTranslation.bin b/examples/models/gltf/DamagedHelmet/glTF-instancing/GpuInstancingTranslation.bin new file mode 100644 index 00000000000000..29dc94b885353d Binary files /dev/null and b/examples/models/gltf/DamagedHelmet/glTF-instancing/GpuInstancingTranslation.bin differ diff --git a/examples/models/gltf/MaterialX/shaderball.glb b/examples/models/gltf/MaterialX/shaderball.glb new file mode 100644 index 00000000000000..ce6d5a3cf71ead Binary files /dev/null and b/examples/models/gltf/MaterialX/shaderball.glb differ diff --git a/examples/models/gltf/kira.glb b/examples/models/gltf/kira.glb new file mode 100644 index 00000000000000..2ce9e76631a12f Binary files /dev/null and b/examples/models/gltf/kira.glb differ diff --git a/examples/models/svg/tests/ellipseTransform.svg b/examples/models/svg/tests/ellipseTransform.svg new file mode 100644 index 00000000000000..686a5c17be63e5 --- /dev/null +++ b/examples/models/svg/tests/ellipseTransform.svg @@ -0,0 +1,888 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/models/usdz/saeukkang.usdz b/examples/models/usdz/saeukkang.usdz new file mode 100644 index 00000000000000..1d00aa1bc7be4a Binary files /dev/null and b/examples/models/usdz/saeukkang.usdz differ diff --git a/examples/physics_ammo_break.html b/examples/physics_ammo_break.html index 78ed17195a7393..5eccc88f7eb73a 100644 --- a/examples/physics_ammo_break.html +++ b/examples/physics_ammo_break.html @@ -24,7 +24,8 @@ @@ -32,11 +33,11 @@ @@ -32,9 +33,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; // Graphics variables let container, stats; diff --git a/examples/physics_ammo_instancing.html b/examples/physics_ammo_instancing.html index fec4e2e2ff0730..5b3900aad0e436 100644 --- a/examples/physics_ammo_instancing.html +++ b/examples/physics_ammo_instancing.html @@ -21,7 +21,8 @@ @@ -29,9 +30,9 @@ @@ -31,9 +32,9 @@ @@ -33,9 +34,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; // Heightfield parameters const terrainWidthExtents = 100; diff --git a/examples/physics_ammo_volume.html b/examples/physics_ammo_volume.html index ac2d500ec50170..158ddc15aa3543 100644 --- a/examples/physics_ammo_volume.html +++ b/examples/physics_ammo_volume.html @@ -26,7 +26,8 @@ @@ -35,10 +36,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import * as BufferGeometryUtils from './jsm/utils/BufferGeometryUtils.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; // Graphics variables let container, stats; diff --git a/examples/physics_oimo_instancing.html b/examples/physics_oimo_instancing.html index 0840bea75a4fbc..575dd510762764 100644 --- a/examples/physics_oimo_instancing.html +++ b/examples/physics_oimo_instancing.html @@ -20,7 +20,8 @@ @@ -28,9 +29,9 @@ @@ -33,7 +34,7 @@ import * as THREE from 'three'; - import { SVGRenderer } from './jsm/renderers/SVGRenderer.js'; + import { SVGRenderer } from 'three/addons/renderers/SVGRenderer.js'; let camera, scene, renderer; diff --git a/examples/svg_sandbox.html b/examples/svg_sandbox.html index af95596be92ed6..2a608d3d617f70 100644 --- a/examples/svg_sandbox.html +++ b/examples/svg_sandbox.html @@ -20,7 +20,8 @@ @@ -29,9 +30,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { SVGRenderer, SVGObject } from './jsm/renderers/SVGRenderer.js'; + import { SVGRenderer, SVGObject } from 'three/addons/renderers/SVGRenderer.js'; let camera, scene, renderer, stats; diff --git a/examples/tags.json b/examples/tags.json index 97364db4ad9469..c78055ff979869 100644 --- a/examples/tags.json +++ b/examples/tags.json @@ -53,6 +53,7 @@ "webgl_math_orientation_transform": [ "rotation" ], "webgl_mirror": [ "reflection" ], "webgl_portal": [ "frameCorners", "renderTarget" ], + "webgl_modifier_subdivision" : [ "external", "community", "smooth" ], "webgl_morphtargets_horse": [ "animation" ], "webgl_multiple_elements": [ "differential equations", "physics" ], "webgl_multiple_elements_text": [ "font" ], @@ -89,6 +90,7 @@ "webgl_postprocessing_3dlut": [ "color grading" ], "webgl_materials_modified": [ "onBeforeCompile" ], "webgl_raycaster_bvh": [ "external", "query", "bounds", "tree", "accelerate", "performance", "community", "extension", "plugin", "library", "three-mesh-bvh" ], + "webgl_renderer_pathtracer": [ "external", "raytracing", "pathtracing", "library", "plugin", "extension", "community", "three-gpu-pathtracer", "three-mesh-bvh" ], "webgl_shadowmap_csm": [ "cascade" ], "webgl_shadowmap_pcss": [ "soft" ], "webgl_simple_gi": [ "global illumination" ], diff --git a/examples/textures/checker.png b/examples/textures/checker.png new file mode 100644 index 00000000000000..92d2c0e0b73c88 Binary files /dev/null and b/examples/textures/checker.png differ diff --git a/examples/textures/equirectangular/san_giuseppe_bridge_2k.hdr b/examples/textures/equirectangular/san_giuseppe_bridge_2k.hdr new file mode 100644 index 00000000000000..2ba5302cd76380 Binary files /dev/null and b/examples/textures/equirectangular/san_giuseppe_bridge_2k.hdr differ diff --git a/examples/textures/spiritedaway.ktx2 b/examples/textures/spiritedaway.ktx2 new file mode 100644 index 00000000000000..1ddf71745b1616 Binary files /dev/null and b/examples/textures/spiritedaway.ktx2 differ diff --git a/examples/textures/tiff/crate_jpeg.tif b/examples/textures/tiff/crate_jpeg.tif new file mode 100644 index 00000000000000..1f0cfe2665fcf7 Binary files /dev/null and b/examples/textures/tiff/crate_jpeg.tif differ diff --git a/examples/textures/tiff/crate_lzw.tif b/examples/textures/tiff/crate_lzw.tif new file mode 100644 index 00000000000000..f9ea2b58a028b1 Binary files /dev/null and b/examples/textures/tiff/crate_lzw.tif differ diff --git a/examples/textures/tiff/crate_uncompressed.tif b/examples/textures/tiff/crate_uncompressed.tif new file mode 100644 index 00000000000000..6ef09b02de64fe Binary files /dev/null and b/examples/textures/tiff/crate_uncompressed.tif differ diff --git a/examples/webaudio_orientation.html b/examples/webaudio_orientation.html index bde6a68314efc5..280ddd8e8c67d6 100644 --- a/examples/webaudio_orientation.html +++ b/examples/webaudio_orientation.html @@ -29,7 +29,8 @@ @@ -37,9 +38,9 @@ @@ -46,9 +47,9 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { FirstPersonControls } from './jsm/controls/FirstPersonControls.js'; + import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js'; let camera, controls, scene, renderer, light; diff --git a/examples/webaudio_timing.html b/examples/webaudio_timing.html index 321c61b2aa91a2..0297770d447c81 100644 --- a/examples/webaudio_timing.html +++ b/examples/webaudio_timing.html @@ -24,7 +24,8 @@ @@ -32,7 +33,7 @@ diff --git a/examples/webgl2_buffergeometry_attributes_integer.html b/examples/webgl2_buffergeometry_attributes_integer.html index 02e134b780eba4..f47cfd9a261ddf 100644 --- a/examples/webgl2_buffergeometry_attributes_integer.html +++ b/examples/webgl2_buffergeometry_attributes_integer.html @@ -51,7 +51,8 @@ @@ -60,7 +61,7 @@ import * as THREE from 'three'; - import WebGL from './jsm/capabilities/WebGL.js'; + import WebGL from 'three/addons/capabilities/WebGL.js'; if ( WebGL.isWebGL2Available() === false ) { @@ -166,6 +167,7 @@ // renderer renderer = new THREE.WebGLRenderer( { antialias: true } ); + renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); diff --git a/examples/webgl2_buffergeometry_attributes_none.html b/examples/webgl2_buffergeometry_attributes_none.html new file mode 100644 index 00000000000000..1e71c255b2b1bb --- /dev/null +++ b/examples/webgl2_buffergeometry_attributes_none.html @@ -0,0 +1,172 @@ + + + + three.js WebGL 2 - buffergeometry - attributes - none + + + + + + +
    three.js WebGL 2 - buffergeometry - attributes - none
    + + + + + + + + + + + + + + + diff --git a/examples/webgl2_materials_texture2darray.html b/examples/webgl2_materials_texture2darray.html index 9ac6b15210189f..bf913c7f94a8d8 100644 --- a/examples/webgl2_materials_texture2darray.html +++ b/examples/webgl2_materials_texture2darray.html @@ -58,7 +58,8 @@ @@ -67,10 +68,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { unzipSync } from './jsm/libs/fflate.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { unzipSync } from 'three/addons/libs/fflate.module.js'; - import WebGL from './jsm/capabilities/WebGL.js'; + import WebGL from 'three/addons/capabilities/WebGL.js'; if ( WebGL.isWebGL2Available() === false ) { @@ -159,7 +160,7 @@ if ( mesh ) { - let value = mesh.material.uniforms[ "depth" ].value; + let value = mesh.material.uniforms[ 'depth' ].value; value += depthStep; @@ -172,7 +173,7 @@ } - mesh.material.uniforms[ "depth" ].value = value; + mesh.material.uniforms[ 'depth' ].value = value; } diff --git a/examples/webgl2_materials_texture3d.html b/examples/webgl2_materials_texture3d.html index e7e2be719f9b29..1f8611a89cec2f 100644 --- a/examples/webgl2_materials_texture3d.html +++ b/examples/webgl2_materials_texture3d.html @@ -20,7 +20,8 @@ @@ -28,11 +29,11 @@ @@ -118,9 +119,9 @@ import * as THREE from 'three'; - import WebGL from './jsm/capabilities/WebGL.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import WebGL from 'three/addons/capabilities/WebGL.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let camera, scene, renderer, controls; let renderTarget; diff --git a/examples/webgl2_multisampled_renderbuffers.html b/examples/webgl2_multisampled_renderbuffers.html index 698e680a374864..223a25ded67e03 100644 --- a/examples/webgl2_multisampled_renderbuffers.html +++ b/examples/webgl2_multisampled_renderbuffers.html @@ -40,7 +40,8 @@ @@ -49,11 +50,11 @@ import * as THREE from 'three'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { ShaderPass } from './jsm/postprocessing/ShaderPass.js'; - import { CopyShader } from './jsm/shaders/CopyShader.js'; - import WebGL from './jsm/capabilities/WebGL.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { CopyShader } from 'three/addons/shaders/CopyShader.js'; + import WebGL from 'three/addons/capabilities/WebGL.js'; let camera, renderer, clock, group, container; diff --git a/examples/webgl2_rendertarget_texture2darray.html b/examples/webgl2_rendertarget_texture2darray.html index 920a857b58fed3..1f9df4304f5ae3 100644 --- a/examples/webgl2_rendertarget_texture2darray.html +++ b/examples/webgl2_rendertarget_texture2darray.html @@ -102,7 +102,8 @@ @@ -111,11 +112,11 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { unzipSync } from './jsm/libs/fflate.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { unzipSync } from 'three/addons/libs/fflate.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import WebGL from './jsm/capabilities/WebGL.js'; + import WebGL from 'three/addons/capabilities/WebGL.js'; if ( WebGL.isWebGL2Available() === false ) { diff --git a/examples/webgl2_texture2darray_compressed.html b/examples/webgl2_texture2darray_compressed.html new file mode 100644 index 00000000000000..62233494421b51 --- /dev/null +++ b/examples/webgl2_texture2darray_compressed.html @@ -0,0 +1,181 @@ + + + + three.js webgl - 2D compressed texture array + + + + + + + + +
    + three.js - 2D Compressed Texture Array
    + Loop from the movie Spirited away + by the Studio Ghibli
    +
    + + + + + + + + + + diff --git a/examples/webgl2_ubo.html b/examples/webgl2_ubo.html index 0cfd54f092ba2f..1ad04d8ddc7fe3 100644 --- a/examples/webgl2_ubo.html +++ b/examples/webgl2_ubo.html @@ -135,7 +135,8 @@ @@ -146,7 +147,7 @@ import * as THREE from 'three'; - import WebGL from './jsm/capabilities/WebGL.js'; + import WebGL from 'three/addons/capabilities/WebGL.js'; let camera, scene, renderer, clock; diff --git a/examples/webgl2_volume_cloud.html b/examples/webgl2_volume_cloud.html index 44ba7b38fa4e63..3275272dab902c 100644 --- a/examples/webgl2_volume_cloud.html +++ b/examples/webgl2_volume_cloud.html @@ -19,18 +19,19 @@ @@ -43,13 +44,13 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { RoomEnvironment } from './jsm/environments/RoomEnvironment.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import { DRACOLoader } from './jsm/loaders/DRACOLoader.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; let mixer; diff --git a/examples/webgl_animation_multiple.html b/examples/webgl_animation_multiple.html index 41fe7082c4bb0a..ec70e0f2614b17 100644 --- a/examples/webgl_animation_multiple.html +++ b/examples/webgl_animation_multiple.html @@ -19,7 +19,8 @@ @@ -28,8 +29,8 @@ import * as THREE from 'three'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import * as SkeletonUtils from './jsm/utils/SkeletonUtils.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import * as SkeletonUtils from 'three/addons/utils/SkeletonUtils.js'; let camera, scene, renderer; let clock; diff --git a/examples/webgl_animation_skinning_additive_blending.html b/examples/webgl_animation_skinning_additive_blending.html index d70e8ed5b7d6dc..88ec4a48b6375b 100644 --- a/examples/webgl_animation_skinning_additive_blending.html +++ b/examples/webgl_animation_skinning_additive_blending.html @@ -28,7 +28,8 @@ @@ -37,10 +38,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; let scene, renderer, camera, stats; let model, skeleton, mixer, clock; @@ -203,10 +204,10 @@ const currentAction = currentSettings ? currentSettings.action : null; const action = settings ? settings.action : null; - if ( currentAction !== action ) { - + if ( currentAction !== action ) { + prepareCrossFade( currentAction, action, 0.35 ); - + } }; diff --git a/examples/webgl_animation_skinning_blending.html b/examples/webgl_animation_skinning_blending.html index 140d598bf04249..f076ad2a5471ad 100644 --- a/examples/webgl_animation_skinning_blending.html +++ b/examples/webgl_animation_skinning_blending.html @@ -26,7 +26,8 @@ @@ -35,10 +36,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; let scene, renderer, camera, stats; let model, skeleton, mixer, clock; diff --git a/examples/webgl_animation_skinning_ik.html b/examples/webgl_animation_skinning_ik.html new file mode 100644 index 00000000000000..ec47b5a549fa54 --- /dev/null +++ b/examples/webgl_animation_skinning_ik.html @@ -0,0 +1,220 @@ + + + + three.js webgl - animation - skinning - ik + + + + + + + +
    + three.js - webgl - inverse kinematics
    + Character model by Aki, furnitures from poly.pizza, scene by abernier. CC0. +
    + + + + + + + + + + diff --git a/examples/webgl_animation_skinning_morph.html b/examples/webgl_animation_skinning_morph.html index 5fd0193529c538..990cb22e792349 100644 --- a/examples/webgl_animation_skinning_morph.html +++ b/examples/webgl_animation_skinning_morph.html @@ -41,7 +41,8 @@ @@ -50,10 +51,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; let container, stats, clock, gui, mixer, actions, activeAction, previousAction; let camera, scene, renderer, model, face; @@ -70,7 +71,7 @@ camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 100 ); camera.position.set( - 5, 3, 10 ); - camera.lookAt( new THREE.Vector3( 0, 2, 0 ) ); + camera.lookAt( 0, 2, 0 ); scene = new THREE.Scene(); scene.background = new THREE.Color( 0xe0e0e0 ); diff --git a/examples/webgl_buffergeometry.html b/examples/webgl_buffergeometry.html index 48dec5916e86ca..88eb3d57d685ea 100644 --- a/examples/webgl_buffergeometry.html +++ b/examples/webgl_buffergeometry.html @@ -18,7 +18,8 @@ @@ -27,7 +28,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let container, stats; diff --git a/examples/webgl_buffergeometry_compression.html b/examples/webgl_buffergeometry_compression.html index 64a7a1508eb1c0..d7f6019dcdf5d6 100644 --- a/examples/webgl_buffergeometry_compression.html +++ b/examples/webgl_buffergeometry_compression.html @@ -19,7 +19,8 @@ @@ -28,12 +29,12 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import * as GeometryCompressionUtils from './jsm/utils/GeometryCompressionUtils.js'; - import * as BufferGeometryUtils from './jsm/utils/BufferGeometryUtils.js'; - import { TeapotGeometry } from './jsm/geometries/TeapotGeometry.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import * as GeometryCompressionUtils from 'three/addons/utils/GeometryCompressionUtils.js'; + import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; + import { TeapotGeometry } from 'three/addons/geometries/TeapotGeometry.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; const statsEnabled = true; @@ -45,17 +46,17 @@ // options const data = { - "model": "Icosahedron", - "wireframe": false, - "texture": false, - "detail": 4, - "rotationSpeed": 0.1, + 'model': 'Icosahedron', + 'wireframe': false, + 'texture': false, + 'detail': 4, + 'rotationSpeed': 0.1, - "QuantizePosEncoding": false, - "NormEncodingMethods": "None", // for normal encodings - "DefaultUVEncoding": false, + 'QuantizePosEncoding': false, + 'NormEncodingMethods': 'None', // for normal encodings + 'DefaultUVEncoding': false, - "totalGPUMemory": "0 bytes" + 'totalGPUMemory': '0 bytes' }; let memoryDisplay; @@ -136,13 +137,13 @@ switch ( data.model ) { - case "Icosahedron": + case 'Icosahedron': return new THREE.IcosahedronGeometry( radius, data.detail ); - case "Cylinder": + case 'Cylinder': return new THREE.CylinderGeometry( radius, radius, radius * 2, data.detail * 6 ); - case "Teapot": + case 'Teapot': return new TeapotGeometry( radius, data.detail * 3, true, true, true, true, true ); - case "TorusKnot": + case 'TorusKnot': return new THREE.TorusKnotGeometry( radius, 10, data.detail * 20, data.detail * 6, 3, 4 ); } @@ -169,7 +170,7 @@ } let folder = gui.addFolder( 'Scene' ); - folder.add( data, 'model', [ "Icosahedron", "Cylinder", "TorusKnot", "Teapot" ] ).onChange( generateGeometry ); + folder.add( data, 'model', [ 'Icosahedron', 'Cylinder', 'TorusKnot', 'Teapot' ] ).onChange( generateGeometry ); folder.add( data, 'wireframe', false ).onChange( updateLineSegments ); folder.add( data, 'texture', false ).onChange( generateGeometry ); folder.add( data, 'detail', 1, 8, 1 ).onChange( generateGeometry ); @@ -181,7 +182,7 @@ folder.open(); folder = gui.addFolder( 'Normal Compression' ); - folder.add( data, 'NormEncodingMethods', [ "None", "DEFAULT", "OCT1Byte", "OCT2Byte", "ANGLES" ] ).onChange( generateGeometry ); + folder.add( data, 'NormEncodingMethods', [ 'None', 'DEFAULT', 'OCT1Byte', 'OCT2Byte', 'ANGLES' ] ).onChange( generateGeometry ); folder.open(); folder = gui.addFolder( 'UV Compression' ); @@ -190,7 +191,7 @@ folder = gui.addFolder( 'Memory Info' ); folder.open(); - memoryDisplay = folder.add( data, 'totalGPUMemory', "0 bytes" ); + memoryDisplay = folder.add( data, 'totalGPUMemory', '0 bytes' ); computeGPUMemory( mesh ); // @@ -258,19 +259,19 @@ mesh.material = new THREE.MeshPhongMaterial( { color: 0xffffff, emissive: 0x111111 } ); mesh.material.map = data.texture ? texture : null; - if ( data[ "QuantizePosEncoding" ] ) { + if ( data[ 'QuantizePosEncoding' ] ) { GeometryCompressionUtils.compressPositions( mesh ); } - if ( data[ "NormEncodingMethods" ] !== "None" ) { + if ( data[ 'NormEncodingMethods' ] !== 'None' ) { - GeometryCompressionUtils.compressNormals( mesh, data[ "NormEncodingMethods" ] ); + GeometryCompressionUtils.compressNormals( mesh, data[ 'NormEncodingMethods' ] ); } - if ( data[ "DefaultUVEncoding" ] ) { + if ( data[ 'DefaultUVEncoding' ] ) { GeometryCompressionUtils.compressUvs( mesh ); @@ -284,7 +285,7 @@ function computeGPUMemory( mesh ) { // Use BufferGeometryUtils to do memory calculation - memoryDisplay.setValue( BufferGeometryUtils.estimateBytesUsed( mesh.geometry ) + " bytes" ); + memoryDisplay.setValue( BufferGeometryUtils.estimateBytesUsed( mesh.geometry ) + ' bytes' ); } diff --git a/examples/webgl_buffergeometry_custom_attributes_particles.html b/examples/webgl_buffergeometry_custom_attributes_particles.html index 1a80b4cad72b8d..730eb98e4980f4 100644 --- a/examples/webgl_buffergeometry_custom_attributes_particles.html +++ b/examples/webgl_buffergeometry_custom_attributes_particles.html @@ -53,7 +53,8 @@ @@ -62,7 +63,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let renderer, scene, camera, stats; diff --git a/examples/webgl_buffergeometry_drawrange.html b/examples/webgl_buffergeometry_drawrange.html index 332c4679ddb0da..e702be7eeefda9 100644 --- a/examples/webgl_buffergeometry_drawrange.html +++ b/examples/webgl_buffergeometry_drawrange.html @@ -21,7 +21,8 @@ @@ -30,10 +31,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let group; let container, stats; diff --git a/examples/webgl_buffergeometry_glbufferattribute.html b/examples/webgl_buffergeometry_glbufferattribute.html index b20cd59c9eb34f..630d526b6533b2 100644 --- a/examples/webgl_buffergeometry_glbufferattribute.html +++ b/examples/webgl_buffergeometry_glbufferattribute.html @@ -18,7 +18,8 @@ @@ -27,7 +28,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let container, stats; diff --git a/examples/webgl_buffergeometry_indexed.html b/examples/webgl_buffergeometry_indexed.html index 663e7c56f78c2a..9cbe57ce35158b 100644 --- a/examples/webgl_buffergeometry_indexed.html +++ b/examples/webgl_buffergeometry_indexed.html @@ -18,7 +18,8 @@ @@ -27,8 +28,8 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let camera, scene, renderer, stats; diff --git a/examples/webgl_buffergeometry_instancing.html b/examples/webgl_buffergeometry_instancing.html index cf67ce24dbc886..58a30fe66ad8cf 100644 --- a/examples/webgl_buffergeometry_instancing.html +++ b/examples/webgl_buffergeometry_instancing.html @@ -73,7 +73,8 @@ @@ -81,8 +82,8 @@ @@ -85,7 +86,7 @@ @@ -29,7 +30,7 @@ @@ -27,7 +28,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let container, stats, clock; diff --git a/examples/webgl_buffergeometry_lines_indexed.html b/examples/webgl_buffergeometry_lines_indexed.html index 086bc8477ff1bb..3f7ca1a276b5b8 100644 --- a/examples/webgl_buffergeometry_lines_indexed.html +++ b/examples/webgl_buffergeometry_lines_indexed.html @@ -19,7 +19,8 @@ @@ -28,7 +29,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let container, stats; diff --git a/examples/webgl_buffergeometry_points.html b/examples/webgl_buffergeometry_points.html index eb1b3aeaf96139..e3ac6129639e4f 100644 --- a/examples/webgl_buffergeometry_points.html +++ b/examples/webgl_buffergeometry_points.html @@ -18,7 +18,8 @@ @@ -27,7 +28,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let container, stats; diff --git a/examples/webgl_buffergeometry_points_interleaved.html b/examples/webgl_buffergeometry_points_interleaved.html index 7ccdceb9c83e8a..5ec99b9bbd16a5 100644 --- a/examples/webgl_buffergeometry_points_interleaved.html +++ b/examples/webgl_buffergeometry_points_interleaved.html @@ -18,7 +18,8 @@ @@ -27,7 +28,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let container, stats; diff --git a/examples/webgl_buffergeometry_rawshader.html b/examples/webgl_buffergeometry_rawshader.html index 5e170ac04b0d5f..c055767d973b3b 100644 --- a/examples/webgl_buffergeometry_rawshader.html +++ b/examples/webgl_buffergeometry_rawshader.html @@ -64,7 +64,8 @@ @@ -73,7 +74,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let container, stats; diff --git a/examples/webgl_buffergeometry_selective_draw.html b/examples/webgl_buffergeometry_selective_draw.html index 6d8cb99af50c37..528c1fec9e18e2 100644 --- a/examples/webgl_buffergeometry_selective_draw.html +++ b/examples/webgl_buffergeometry_selective_draw.html @@ -53,7 +53,8 @@ @@ -62,7 +63,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let camera, scene, renderer, stats; let geometry, mesh; diff --git a/examples/webgl_buffergeometry_uint.html b/examples/webgl_buffergeometry_uint.html index 2b92b8559db7d7..48a9509e944224 100644 --- a/examples/webgl_buffergeometry_uint.html +++ b/examples/webgl_buffergeometry_uint.html @@ -18,7 +18,8 @@ @@ -27,7 +28,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let container, stats; diff --git a/examples/webgl_camera.html b/examples/webgl_camera.html index f6baa0cbac1bcd..a63ba46267c355 100644 --- a/examples/webgl_camera.html +++ b/examples/webgl_camera.html @@ -23,7 +23,8 @@ @@ -32,7 +33,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let SCREEN_WIDTH = window.innerWidth; let SCREEN_HEIGHT = window.innerHeight; diff --git a/examples/webgl_camera_array.html b/examples/webgl_camera_array.html index 2c8ffc32bca4d6..6d4ef142ae1fae 100644 --- a/examples/webgl_camera_array.html +++ b/examples/webgl_camera_array.html @@ -15,7 +15,8 @@ diff --git a/examples/webgl_camera_cinematic.html b/examples/webgl_camera_cinematic.html index 912a55179f4ba3..5c5d485a3127d0 100644 --- a/examples/webgl_camera_cinematic.html +++ b/examples/webgl_camera_cinematic.html @@ -28,7 +28,8 @@ @@ -37,10 +38,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { CinematicCamera } from './jsm/cameras/CinematicCamera.js'; + import { CinematicCamera } from 'three/addons/cameras/CinematicCamera.js'; let camera, scene, raycaster, renderer, stats; diff --git a/examples/webgl_camera_logarithmicdepthbuffer.html b/examples/webgl_camera_logarithmicdepthbuffer.html index 7ed7c6032a8508..dad57de068e805 100644 --- a/examples/webgl_camera_logarithmicdepthbuffer.html +++ b/examples/webgl_camera_logarithmicdepthbuffer.html @@ -69,7 +69,8 @@ @@ -78,10 +79,10 @@ import * as THREE from 'three'; - import { FontLoader } from './jsm/loaders/FontLoader.js'; - import { TextGeometry } from './jsm/geometries/TextGeometry.js'; + import { FontLoader } from 'three/addons/loaders/FontLoader.js'; + import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; // 1 micrometer to 100 billion light years in one scene, with 1 unit = 1 meter? preposterous! and yet... const NEAR = 1e-6, FAR = 1e27; diff --git a/examples/webgl_clipping.html b/examples/webgl_clipping.html index c8df4382a4c17d..a974eadc3ce129 100644 --- a/examples/webgl_clipping.html +++ b/examples/webgl_clipping.html @@ -15,7 +15,8 @@ @@ -24,10 +25,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let camera, scene, renderer, startTime, object, stats; diff --git a/examples/webgl_clipping_advanced.html b/examples/webgl_clipping_advanced.html index 6de47a2f8dd497..8c015bbe0ea680 100644 --- a/examples/webgl_clipping_advanced.html +++ b/examples/webgl_clipping_advanced.html @@ -15,7 +15,8 @@ @@ -24,10 +25,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; function planesFromMesh( vertices, indices ) { diff --git a/examples/webgl_clipping_intersection.html b/examples/webgl_clipping_intersection.html index b09700337a3b65..2ac4e34275bcf5 100644 --- a/examples/webgl_clipping_intersection.html +++ b/examples/webgl_clipping_intersection.html @@ -15,7 +15,8 @@ @@ -24,9 +25,9 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let camera, scene, renderer; diff --git a/examples/webgl_clipping_stencil.html b/examples/webgl_clipping_stencil.html index d0fa2e690fcdc0..383f8b0bd8989b 100644 --- a/examples/webgl_clipping_stencil.html +++ b/examples/webgl_clipping_stencil.html @@ -17,16 +17,17 @@ @@ -72,7 +73,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let renderer, scene, camera, stats; diff --git a/examples/webgl_custom_attributes_lines.html b/examples/webgl_custom_attributes_lines.html index e9dd5ae80d2cf1..c031e08a7ba427 100644 --- a/examples/webgl_custom_attributes_lines.html +++ b/examples/webgl_custom_attributes_lines.html @@ -54,7 +54,8 @@ @@ -63,10 +64,10 @@ import * as THREE from 'three'; - import { FontLoader } from './jsm/loaders/FontLoader.js'; - import { TextGeometry } from './jsm/geometries/TextGeometry.js'; + import { FontLoader } from 'three/addons/loaders/FontLoader.js'; + import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let renderer, scene, camera, stats; diff --git a/examples/webgl_custom_attributes_points.html b/examples/webgl_custom_attributes_points.html index 130094bc3a1827..e1eaef1b59f9a7 100644 --- a/examples/webgl_custom_attributes_points.html +++ b/examples/webgl_custom_attributes_points.html @@ -55,7 +55,8 @@ @@ -64,7 +65,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let renderer, scene, camera, stats; diff --git a/examples/webgl_custom_attributes_points2.html b/examples/webgl_custom_attributes_points2.html index 4e2912be759663..3d7154ed20b69f 100644 --- a/examples/webgl_custom_attributes_points2.html +++ b/examples/webgl_custom_attributes_points2.html @@ -56,7 +56,8 @@ @@ -65,9 +66,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import * as BufferGeometryUtils from './jsm/utils/BufferGeometryUtils.js'; + import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; let renderer, scene, camera, stats; let sphere, length1; diff --git a/examples/webgl_custom_attributes_points3.html b/examples/webgl_custom_attributes_points3.html index 72adcf8792b563..d5a8615f3e49dd 100644 --- a/examples/webgl_custom_attributes_points3.html +++ b/examples/webgl_custom_attributes_points3.html @@ -64,7 +64,8 @@ @@ -73,9 +74,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import * as BufferGeometryUtils from './jsm/utils/BufferGeometryUtils.js'; + import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; let renderer, scene, camera, stats; diff --git a/examples/webgl_decals.html b/examples/webgl_decals.html index 09cb881b3050cd..bfbce2b5869d28 100644 --- a/examples/webgl_decals.html +++ b/examples/webgl_decals.html @@ -21,7 +21,8 @@ @@ -30,12 +31,12 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import { DecalGeometry } from './jsm/geometries/DecalGeometry.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { DecalGeometry } from 'three/addons/geometries/DecalGeometry.js'; const container = document.getElementById( 'container' ); @@ -87,7 +88,8 @@ } }; - window.addEventListener( 'load', init ); + init(); + animate(); function init() { @@ -221,9 +223,6 @@ gui.add( params, 'clear' ); gui.open(); - onWindowResize(); - animate(); - } function loadLeePerrySmith() { diff --git a/examples/webgl_depth_texture.html b/examples/webgl_depth_texture.html index ce805d4443515d..0689dc990585c3 100644 --- a/examples/webgl_depth_texture.html +++ b/examples/webgl_depth_texture.html @@ -69,7 +69,8 @@ @@ -78,10 +79,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let camera, scene, renderer, controls, stats; let target; diff --git a/examples/webgl_effects_anaglyph.html b/examples/webgl_effects_anaglyph.html index 30fd94ec8263f6..d0cbb2fb7ce15d 100644 --- a/examples/webgl_effects_anaglyph.html +++ b/examples/webgl_effects_anaglyph.html @@ -19,7 +19,8 @@ @@ -28,7 +29,7 @@ import * as THREE from 'three'; - import { AnaglyphEffect } from './jsm/effects/AnaglyphEffect.js'; + import { AnaglyphEffect } from 'three/addons/effects/AnaglyphEffect.js'; let container, camera, scene, renderer, effect; diff --git a/examples/webgl_effects_ascii.html b/examples/webgl_effects_ascii.html index 3227a421e40217..0155fb59fc0502 100644 --- a/examples/webgl_effects_ascii.html +++ b/examples/webgl_effects_ascii.html @@ -17,7 +17,8 @@ @@ -26,8 +27,8 @@ import * as THREE from 'three'; - import { AsciiEffect } from './jsm/effects/AsciiEffect.js'; - import { TrackballControls } from './jsm/controls/TrackballControls.js'; + import { AsciiEffect } from 'three/addons/effects/AsciiEffect.js'; + import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; let camera, controls, scene, renderer, effect; diff --git a/examples/webgl_effects_parallaxbarrier.html b/examples/webgl_effects_parallaxbarrier.html index 8f8bd79bd63613..15fc74b0306524 100644 --- a/examples/webgl_effects_parallaxbarrier.html +++ b/examples/webgl_effects_parallaxbarrier.html @@ -20,7 +20,8 @@ @@ -29,7 +30,7 @@ import * as THREE from 'three'; - import { ParallaxBarrierEffect } from './jsm/effects/ParallaxBarrierEffect.js'; + import { ParallaxBarrierEffect } from 'three/addons/effects/ParallaxBarrierEffect.js'; let container, camera, scene, renderer, effect; diff --git a/examples/webgl_effects_peppersghost.html b/examples/webgl_effects_peppersghost.html index 54b1b655444299..f4aaee57bacf96 100644 --- a/examples/webgl_effects_peppersghost.html +++ b/examples/webgl_effects_peppersghost.html @@ -20,7 +20,8 @@ @@ -29,7 +30,7 @@ import * as THREE from 'three'; - import { PeppersGhostEffect } from './jsm/effects/PeppersGhostEffect.js'; + import { PeppersGhostEffect } from 'three/addons/effects/PeppersGhostEffect.js'; let container; diff --git a/examples/webgl_effects_stereo.html b/examples/webgl_effects_stereo.html index be8d566cf46036..d1bbe5f85953b5 100644 --- a/examples/webgl_effects_stereo.html +++ b/examples/webgl_effects_stereo.html @@ -19,7 +19,8 @@ @@ -28,7 +29,7 @@ import * as THREE from 'three'; - import { StereoEffect } from './jsm/effects/StereoEffect.js'; + import { StereoEffect } from 'three/addons/effects/StereoEffect.js'; let container, camera, scene, renderer, effect; diff --git a/examples/webgl_framebuffer_texture.html b/examples/webgl_framebuffer_texture.html index 3d50638cd3abd6..9867f02fdfb42a 100644 --- a/examples/webgl_framebuffer_texture.html +++ b/examples/webgl_framebuffer_texture.html @@ -42,7 +42,8 @@ @@ -51,8 +52,8 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import * as GeometryUtils from './jsm/utils/GeometryUtils.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import * as GeometryUtils from 'three/addons/utils/GeometryUtils.js'; let camera, scene, renderer; let line, sprite, texture; diff --git a/examples/webgl_furnace_test.html b/examples/webgl_furnace_test.html index dac34e14168d02..bf3f6ef51ada7e 100644 --- a/examples/webgl_furnace_test.html +++ b/examples/webgl_furnace_test.html @@ -24,7 +24,8 @@ @@ -127,7 +128,7 @@ radianceMap = pmremGenerator.fromScene( envScene ).texture; pmremGenerator.dispose(); - scene.background = radianceMap; + scene.background = envScene.background; } diff --git a/examples/webgl_geometries.html b/examples/webgl_geometries.html index a8243454264f19..b30e131bfe371c 100644 --- a/examples/webgl_geometries.html +++ b/examples/webgl_geometries.html @@ -17,7 +17,8 @@ @@ -26,7 +27,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let camera, scene, renderer, stats; diff --git a/examples/webgl_geometries_parametric.html b/examples/webgl_geometries_parametric.html index 9e1a4eecc6d2a1..753bd24a0f4b11 100644 --- a/examples/webgl_geometries_parametric.html +++ b/examples/webgl_geometries_parametric.html @@ -18,7 +18,8 @@ @@ -27,11 +28,11 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import * as Curves from './jsm/curves/CurveExtras.js'; - import { ParametricGeometry } from './jsm/geometries/ParametricGeometry.js'; - import { ParametricGeometries } from './jsm/geometries/ParametricGeometries.js'; + import * as Curves from 'three/addons/curves/CurveExtras.js'; + import { ParametricGeometry } from 'three/addons/geometries/ParametricGeometry.js'; + import { ParametricGeometries } from 'three/addons/geometries/ParametricGeometries.js'; let camera, scene, renderer, stats; diff --git a/examples/webgl_geometry_colors.html b/examples/webgl_geometry_colors.html index cd0b7cf83ab66b..db8daacb75507d 100644 --- a/examples/webgl_geometry_colors.html +++ b/examples/webgl_geometry_colors.html @@ -27,7 +27,8 @@ @@ -36,7 +37,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let container, stats; diff --git a/examples/webgl_geometry_colors_lookuptable.html b/examples/webgl_geometry_colors_lookuptable.html index fca354d212bdfc..5bff2b2d42f2c9 100644 --- a/examples/webgl_geometry_colors_lookuptable.html +++ b/examples/webgl_geometry_colors_lookuptable.html @@ -31,7 +31,8 @@ @@ -40,10 +41,10 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { Lut } from './jsm/math/Lut.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { Lut } from 'three/addons/math/Lut.js'; let container; diff --git a/examples/webgl_geometry_convex.html b/examples/webgl_geometry_convex.html index 87aedaaf263ef0..5d523462b28271 100644 --- a/examples/webgl_geometry_convex.html +++ b/examples/webgl_geometry_convex.html @@ -17,7 +17,8 @@ @@ -26,9 +27,9 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { ConvexGeometry } from './jsm/geometries/ConvexGeometry.js'; - import * as BufferGeometryUtils from './jsm/utils/BufferGeometryUtils.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { ConvexGeometry } from 'three/addons/geometries/ConvexGeometry.js'; + import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; let group, camera, scene, renderer; diff --git a/examples/webgl_geometry_cube.html b/examples/webgl_geometry_cube.html index 58056f4d42cb05..1f6e11e6ba5f27 100644 --- a/examples/webgl_geometry_cube.html +++ b/examples/webgl_geometry_cube.html @@ -15,7 +15,8 @@ diff --git a/examples/webgl_geometry_dynamic.html b/examples/webgl_geometry_dynamic.html index 805734b872bfee..cbd23588796b2b 100644 --- a/examples/webgl_geometry_dynamic.html +++ b/examples/webgl_geometry_dynamic.html @@ -25,7 +25,8 @@ @@ -34,9 +35,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { FirstPersonControls } from './jsm/controls/FirstPersonControls.js'; + import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js'; let camera, controls, scene, renderer, stats; diff --git a/examples/webgl_geometry_extrude_shapes.html b/examples/webgl_geometry_extrude_shapes.html index da3700eea963a4..0667c25e2c6f90 100644 --- a/examples/webgl_geometry_extrude_shapes.html +++ b/examples/webgl_geometry_extrude_shapes.html @@ -24,7 +24,8 @@ @@ -33,7 +34,7 @@ import * as THREE from 'three'; - import { TrackballControls } from './jsm/controls/TrackballControls.js'; + import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; let camera, scene, renderer, controls; diff --git a/examples/webgl_geometry_extrude_shapes2.html b/examples/webgl_geometry_extrude_shapes2.html index dee0b53461f58e..8d65d4defa2cf2 100644 --- a/examples/webgl_geometry_extrude_shapes2.html +++ b/examples/webgl_geometry_extrude_shapes2.html @@ -24,7 +24,8 @@ @@ -33,9 +34,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; // From d3-threeD.js /* This Source Code Form is subject to the terms of the Mozilla Public diff --git a/examples/webgl_geometry_extrude_splines.html b/examples/webgl_geometry_extrude_splines.html index b65d801e210eba..53244ce3a78758 100644 --- a/examples/webgl_geometry_extrude_splines.html +++ b/examples/webgl_geometry_extrude_splines.html @@ -29,7 +29,8 @@ @@ -38,11 +39,11 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import * as Curves from './jsm/curves/CurveExtras.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import * as Curves from 'three/addons/curves/CurveExtras.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let container, stats; diff --git a/examples/webgl_geometry_minecraft.html b/examples/webgl_geometry_minecraft.html index d41eb841492d34..58e7fa6731c273 100644 --- a/examples/webgl_geometry_minecraft.html +++ b/examples/webgl_geometry_minecraft.html @@ -27,7 +27,8 @@ @@ -36,11 +37,11 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { FirstPersonControls } from './jsm/controls/FirstPersonControls.js'; - import { ImprovedNoise } from './jsm/math/ImprovedNoise.js'; - import * as BufferGeometryUtils from './jsm/utils/BufferGeometryUtils.js'; + import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js'; + import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js'; + import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; let container, stats; diff --git a/examples/webgl_geometry_nurbs.html b/examples/webgl_geometry_nurbs.html index 16ac91ffa08e4b..894f8cf6098b85 100644 --- a/examples/webgl_geometry_nurbs.html +++ b/examples/webgl_geometry_nurbs.html @@ -27,7 +27,8 @@ @@ -36,11 +37,11 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { NURBSCurve } from './jsm/curves/NURBSCurve.js'; - import { NURBSSurface } from './jsm/curves/NURBSSurface.js'; - import { ParametricGeometry } from './jsm/geometries/ParametricGeometry.js'; + import { NURBSCurve } from 'three/addons/curves/NURBSCurve.js'; + import { NURBSSurface } from 'three/addons/curves/NURBSSurface.js'; + import { ParametricGeometry } from 'three/addons/geometries/ParametricGeometry.js'; let container, stats; diff --git a/examples/webgl_geometry_shapes.html b/examples/webgl_geometry_shapes.html index 363d9812bfb346..df7da2b5e770de 100644 --- a/examples/webgl_geometry_shapes.html +++ b/examples/webgl_geometry_shapes.html @@ -23,7 +23,8 @@ @@ -32,7 +33,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let container, stats; @@ -71,7 +72,7 @@ scene.add( group ); const loader = new THREE.TextureLoader(); - const texture = loader.load( "textures/uv_grid_opengl.jpg" ); + const texture = loader.load( 'textures/uv_grid_opengl.jpg' ); // it's necessary to apply these settings in order to correctly display the texture on a shape geometry diff --git a/examples/webgl_geometry_spline_editor.html b/examples/webgl_geometry_spline_editor.html index f550c7f4f6283d..f9d76018f066cb 100644 --- a/examples/webgl_geometry_spline_editor.html +++ b/examples/webgl_geometry_spline_editor.html @@ -29,7 +29,8 @@ @@ -38,10 +39,10 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { TransformControls } from './jsm/controls/TransformControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { TransformControls } from 'three/addons/controls/TransformControls.js'; let container; let camera, scene, renderer; @@ -362,7 +363,7 @@ } - function onPointerUp() { + function onPointerUp( event ) { onUpPosition.x = event.clientX; onUpPosition.y = event.clientY; diff --git a/examples/webgl_geometry_teapot.html b/examples/webgl_geometry_teapot.html index b16f185c10436d..5ed03a812fcddd 100644 --- a/examples/webgl_geometry_teapot.html +++ b/examples/webgl_geometry_teapot.html @@ -19,7 +19,8 @@ @@ -28,10 +29,10 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { TeapotGeometry } from './jsm/geometries/TeapotGeometry.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { TeapotGeometry } from 'three/addons/geometries/TeapotGeometry.js'; let camera, scene, renderer; let cameraControls; diff --git a/examples/webgl_geometry_terrain.html b/examples/webgl_geometry_terrain.html index 9b6969cdf4f786..0d1279259ca626 100644 --- a/examples/webgl_geometry_terrain.html +++ b/examples/webgl_geometry_terrain.html @@ -27,7 +27,8 @@ @@ -36,10 +37,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { FirstPersonControls } from './jsm/controls/FirstPersonControls.js'; - import { ImprovedNoise } from './jsm/math/ImprovedNoise.js'; + import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js'; + import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js'; let container, stats; let camera, controls, scene, renderer; diff --git a/examples/webgl_geometry_terrain_raycast.html b/examples/webgl_geometry_terrain_raycast.html index ccae69a13976f4..ec0a2776a0e0b6 100644 --- a/examples/webgl_geometry_terrain_raycast.html +++ b/examples/webgl_geometry_terrain_raycast.html @@ -27,7 +27,8 @@ @@ -36,10 +37,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { ImprovedNoise } from './jsm/math/ImprovedNoise.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js'; let container, stats; diff --git a/examples/webgl_geometry_text.html b/examples/webgl_geometry_text.html index e98a9e79297c72..1c131c1dec7dc9 100644 --- a/examples/webgl_geometry_text.html +++ b/examples/webgl_geometry_text.html @@ -25,7 +25,8 @@ @@ -34,10 +35,10 @@ import * as THREE from 'three'; - import { FontLoader } from './jsm/loaders/FontLoader.js'; - import { TextGeometry } from './jsm/geometries/TextGeometry.js'; + import { FontLoader } from 'three/addons/loaders/FontLoader.js'; + import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; THREE.Cache.enabled = true; diff --git a/examples/webgl_geometry_text_shapes.html b/examples/webgl_geometry_text_shapes.html index 044758d836a418..c6288daeafeaa7 100644 --- a/examples/webgl_geometry_text_shapes.html +++ b/examples/webgl_geometry_text_shapes.html @@ -27,7 +27,8 @@ @@ -36,8 +37,8 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { FontLoader } from './jsm/loaders/FontLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { FontLoader } from 'three/addons/loaders/FontLoader.js'; let camera, scene, renderer; diff --git a/examples/webgl_geometry_text_stroke.html b/examples/webgl_geometry_text_stroke.html index 0a9e8497d73e72..06a381306b7409 100644 --- a/examples/webgl_geometry_text_stroke.html +++ b/examples/webgl_geometry_text_stroke.html @@ -27,7 +27,8 @@ @@ -36,9 +37,9 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { SVGLoader } from './jsm/loaders/SVGLoader.js'; - import { FontLoader } from './jsm/loaders/FontLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { SVGLoader } from 'three/addons/loaders/SVGLoader.js'; + import { FontLoader } from 'three/addons/loaders/FontLoader.js'; let camera, scene, renderer; diff --git a/examples/webgl_gpgpu_birds.html b/examples/webgl_gpgpu_birds.html index e6d1bdede966dc..17bf8eee37643f 100644 --- a/examples/webgl_gpgpu_birds.html +++ b/examples/webgl_gpgpu_birds.html @@ -304,7 +304,8 @@ @@ -313,10 +314,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { GPUComputationRenderer } from './jsm/misc/GPUComputationRenderer.js'; + import { GPUComputationRenderer } from 'three/addons/misc/GPUComputationRenderer.js'; /* TEXTURE WIDTH FOR SIMULATION */ const WIDTH = 32; diff --git a/examples/webgl_gpgpu_birds_gltf.html b/examples/webgl_gpgpu_birds_gltf.html index fd64fef652cf13..d44a1dfc3c1ee7 100644 --- a/examples/webgl_gpgpu_birds_gltf.html +++ b/examples/webgl_gpgpu_birds_gltf.html @@ -214,7 +214,8 @@ @@ -222,10 +223,10 @@ @@ -244,11 +245,11 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GPUComputationRenderer } from './jsm/misc/GPUComputationRenderer.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GPUComputationRenderer } from 'three/addons/misc/GPUComputationRenderer.js'; // Texture width for simulation (each texel is a debris particle) const WIDTH = 64; diff --git a/examples/webgl_gpgpu_water.html b/examples/webgl_gpgpu_water.html index 782b49e299fcb7..feacfe1f52b993 100644 --- a/examples/webgl_gpgpu_water.html +++ b/examples/webgl_gpgpu_water.html @@ -253,7 +253,8 @@ @@ -262,11 +263,11 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { GPUComputationRenderer } from './jsm/misc/GPUComputationRenderer.js'; - import { SimplexNoise } from './jsm/math/SimplexNoise.js'; + import { GPUComputationRenderer } from 'three/addons/misc/GPUComputationRenderer.js'; + import { SimplexNoise } from 'three/addons/math/SimplexNoise.js'; // Texture width for simulation const WIDTH = 128; diff --git a/examples/webgl_helpers.html b/examples/webgl_helpers.html index 1279383cbc5bcb..d98ff59ce71c15 100644 --- a/examples/webgl_helpers.html +++ b/examples/webgl_helpers.html @@ -18,7 +18,8 @@ @@ -27,10 +28,10 @@ import * as THREE from 'three'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { VertexNormalsHelper } from './jsm/helpers/VertexNormalsHelper.js'; - import { VertexTangentsHelper } from './jsm/helpers/VertexTangentsHelper.js'; + import { VertexNormalsHelper } from 'three/addons/helpers/VertexNormalsHelper.js'; + import { VertexTangentsHelper } from 'three/addons/helpers/VertexTangentsHelper.js'; let scene, renderer; let camera, light; diff --git a/examples/webgl_instancing_dynamic.html b/examples/webgl_instancing_dynamic.html index e4b71cdaeadf3e..b910ac749bc2cb 100644 --- a/examples/webgl_instancing_dynamic.html +++ b/examples/webgl_instancing_dynamic.html @@ -15,7 +15,8 @@ @@ -24,8 +25,8 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let camera, scene, renderer, stats; diff --git a/examples/webgl_instancing_performance.html b/examples/webgl_instancing_performance.html index 095e96d6ce32c3..9db79be1abf583 100644 --- a/examples/webgl_instancing_performance.html +++ b/examples/webgl_instancing_performance.html @@ -33,7 +33,8 @@ @@ -41,11 +42,11 @@ @@ -23,9 +24,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let camera, scene, renderer, controls, stats; diff --git a/examples/webgl_instancing_scatter.html b/examples/webgl_instancing_scatter.html index fb3ba0d6c8c495..705694807abf7e 100644 --- a/examples/webgl_instancing_scatter.html +++ b/examples/webgl_instancing_scatter.html @@ -15,7 +15,8 @@ @@ -24,10 +25,10 @@ import * as THREE from 'three'; - import { MeshSurfaceSampler } from './jsm/math/MeshSurfaceSampler.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { MeshSurfaceSampler } from 'three/addons/math/MeshSurfaceSampler.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let camera, scene, renderer, stats; diff --git a/examples/webgl_interactive_buffergeometry.html b/examples/webgl_interactive_buffergeometry.html index bb154dd896f75f..7b5289e3114b42 100644 --- a/examples/webgl_interactive_buffergeometry.html +++ b/examples/webgl_interactive_buffergeometry.html @@ -18,7 +18,8 @@ @@ -27,7 +28,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let container, stats; diff --git a/examples/webgl_interactive_cubes.html b/examples/webgl_interactive_cubes.html index b835b81b98d317..263a257c6d7491 100644 --- a/examples/webgl_interactive_cubes.html +++ b/examples/webgl_interactive_cubes.html @@ -28,7 +28,8 @@ @@ -37,7 +38,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let container, stats; let camera, scene, raycaster, renderer; diff --git a/examples/webgl_interactive_cubes_gpu.html b/examples/webgl_interactive_cubes_gpu.html index 20a0a00b1f25dc..46e7580e2949f5 100644 --- a/examples/webgl_interactive_cubes_gpu.html +++ b/examples/webgl_interactive_cubes_gpu.html @@ -30,7 +30,8 @@ @@ -39,10 +40,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { TrackballControls } from './jsm/controls/TrackballControls.js'; - import * as BufferGeometryUtils from './jsm/utils/BufferGeometryUtils.js'; + import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; + import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; let container, stats; let camera, controls, scene, renderer; diff --git a/examples/webgl_interactive_cubes_ortho.html b/examples/webgl_interactive_cubes_ortho.html index f0cffa7598f9f3..caf6842f7580e1 100644 --- a/examples/webgl_interactive_cubes_ortho.html +++ b/examples/webgl_interactive_cubes_ortho.html @@ -28,7 +28,8 @@ @@ -37,7 +38,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let container, stats; let camera, scene, raycaster, renderer; diff --git a/examples/webgl_interactive_lines.html b/examples/webgl_interactive_lines.html index 637f54c375f9a1..d834403d69b9f6 100644 --- a/examples/webgl_interactive_lines.html +++ b/examples/webgl_interactive_lines.html @@ -24,7 +24,8 @@ @@ -33,7 +34,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let container, stats; let camera, scene, raycaster, renderer, parentTransform, sphereInter; diff --git a/examples/webgl_interactive_points.html b/examples/webgl_interactive_points.html index a727e7d0913b9f..1dcdf50d9658f1 100644 --- a/examples/webgl_interactive_points.html +++ b/examples/webgl_interactive_points.html @@ -59,7 +59,8 @@ @@ -68,9 +69,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import * as BufferGeometryUtils from './jsm/utils/BufferGeometryUtils.js'; + import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; let renderer, scene, camera, stats; diff --git a/examples/webgl_interactive_raycasting_points.html b/examples/webgl_interactive_raycasting_points.html index 27369c18c2406e..c8c42c5e2476f5 100644 --- a/examples/webgl_interactive_raycasting_points.html +++ b/examples/webgl_interactive_raycasting_points.html @@ -18,7 +18,8 @@ @@ -27,7 +28,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let renderer, scene, camera, stats; let pointclouds; diff --git a/examples/webgl_interactive_voxelpainter.html b/examples/webgl_interactive_voxelpainter.html index 8a4bcfff63f744..2dcbbf040be437 100644 --- a/examples/webgl_interactive_voxelpainter.html +++ b/examples/webgl_interactive_voxelpainter.html @@ -29,7 +29,8 @@ diff --git a/examples/webgl_layers.html b/examples/webgl_layers.html index ca8c61e01afb81..0e712704f2e4b6 100644 --- a/examples/webgl_layers.html +++ b/examples/webgl_layers.html @@ -28,7 +28,8 @@ @@ -37,8 +38,8 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let container, stats; let camera, scene, renderer; diff --git a/examples/webgl_lensflares.html b/examples/webgl_lensflares.html index a33552a15f34db..c6ec1c90b6ccb3 100644 --- a/examples/webgl_lensflares.html +++ b/examples/webgl_lensflares.html @@ -21,7 +21,8 @@ @@ -30,10 +31,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { FlyControls } from './jsm/controls/FlyControls.js'; - import { Lensflare, LensflareElement } from './jsm/objects/Lensflare.js'; + import { FlyControls } from 'three/addons/controls/FlyControls.js'; + import { Lensflare, LensflareElement } from 'three/addons/objects/Lensflare.js'; let container, stats; diff --git a/examples/webgl_lightningstrike.html b/examples/webgl_lightningstrike.html index 2446231315e80a..1f01773bc61cc4 100644 --- a/examples/webgl_lightningstrike.html +++ b/examples/webgl_lightningstrike.html @@ -18,7 +18,8 @@ @@ -27,15 +28,15 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { LightningStrike } from './jsm/geometries/LightningStrike.js'; - import { LightningStorm } from './jsm/objects/LightningStorm.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { OutlinePass } from './jsm/postprocessing/OutlinePass.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { LightningStrike } from 'three/addons/geometries/LightningStrike.js'; + import { LightningStorm } from 'three/addons/objects/LightningStorm.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { OutlinePass } from 'three/addons/postprocessing/OutlinePass.js'; let container, stats; diff --git a/examples/webgl_lightprobe.html b/examples/webgl_lightprobe.html index e1fc6888b6174e..a801995bed08f0 100644 --- a/examples/webgl_lightprobe.html +++ b/examples/webgl_lightprobe.html @@ -19,7 +19,8 @@ @@ -28,10 +29,10 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { LightProbeGenerator } from './jsm/lights/LightProbeGenerator.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { LightProbeGenerator } from 'three/addons/lights/LightProbeGenerator.js'; let mesh, renderer, scene, camera; diff --git a/examples/webgl_lightprobe_cubecamera.html b/examples/webgl_lightprobe_cubecamera.html index e9c2ed3d1bd1cb..5676e831608555 100644 --- a/examples/webgl_lightprobe_cubecamera.html +++ b/examples/webgl_lightprobe_cubecamera.html @@ -19,7 +19,8 @@ @@ -28,9 +29,9 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { LightProbeHelper } from './jsm/helpers/LightProbeHelper.js'; - import { LightProbeGenerator } from './jsm/lights/LightProbeGenerator.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { LightProbeHelper } from 'three/addons/helpers/LightProbeHelper.js'; + import { LightProbeGenerator } from 'three/addons/lights/LightProbeGenerator.js'; let renderer, scene, camera, cubeCamera; diff --git a/examples/webgl_lights_hemisphere.html b/examples/webgl_lights_hemisphere.html index 08207312d16ad0..9913af85133287 100644 --- a/examples/webgl_lights_hemisphere.html +++ b/examples/webgl_lights_hemisphere.html @@ -64,7 +64,8 @@ @@ -73,9 +74,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; let camera, scene, renderer; diff --git a/examples/webgl_lights_physical.html b/examples/webgl_lights_physical.html index fbf957d146f39a..113f755a9ca423 100644 --- a/examples/webgl_lights_physical.html +++ b/examples/webgl_lights_physical.html @@ -22,7 +22,8 @@ @@ -31,10 +32,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let camera, scene, renderer, bulbLight, bulbMat, hemiLight, stats; let ballMat, cubeMat, floorMat; @@ -44,29 +45,29 @@ // ref for lumens: http://www.power-sure.com/lumens.htm const bulbLuminousPowers = { - "110000 lm (1000W)": 110000, - "3500 lm (300W)": 3500, - "1700 lm (100W)": 1700, - "800 lm (60W)": 800, - "400 lm (40W)": 400, - "180 lm (25W)": 180, - "20 lm (4W)": 20, - "Off": 0 + '110000 lm (1000W)': 110000, + '3500 lm (300W)': 3500, + '1700 lm (100W)': 1700, + '800 lm (60W)': 800, + '400 lm (40W)': 400, + '180 lm (25W)': 180, + '20 lm (4W)': 20, + 'Off': 0 }; // ref for solar irradiances: https://en.wikipedia.org/wiki/Lux const hemiLuminousIrradiances = { - "0.0001 lx (Moonless Night)": 0.0001, - "0.002 lx (Night Airglow)": 0.002, - "0.5 lx (Full Moon)": 0.5, - "3.4 lx (City Twilight)": 3.4, - "50 lx (Living Room)": 50, - "100 lx (Very Overcast)": 100, - "350 lx (Office Room)": 350, - "400 lx (Sunrise/Sunset)": 400, - "1000 lx (Overcast)": 1000, - "18000 lx (Daylight)": 18000, - "50000 lx (Direct Sun)": 50000 + '0.0001 lx (Moonless Night)': 0.0001, + '0.002 lx (Night Airglow)': 0.002, + '0.5 lx (Full Moon)': 0.5, + '3.4 lx (City Twilight)': 3.4, + '50 lx (Living Room)': 50, + '100 lx (Very Overcast)': 100, + '350 lx (Office Room)': 350, + '400 lx (Sunrise/Sunset)': 400, + '1000 lx (Overcast)': 1000, + '18000 lx (Daylight)': 18000, + '50000 lx (Direct Sun)': 50000 }; const params = { @@ -117,7 +118,7 @@ bumpScale: 0.0005 } ); const textureLoader = new THREE.TextureLoader(); - textureLoader.load( "textures/hardwood2_diffuse.jpg", function ( map ) { + textureLoader.load( 'textures/hardwood2_diffuse.jpg', function ( map ) { map.wrapS = THREE.RepeatWrapping; map.wrapT = THREE.RepeatWrapping; @@ -128,7 +129,7 @@ floorMat.needsUpdate = true; } ); - textureLoader.load( "textures/hardwood2_bump.jpg", function ( map ) { + textureLoader.load( 'textures/hardwood2_bump.jpg', function ( map ) { map.wrapS = THREE.RepeatWrapping; map.wrapT = THREE.RepeatWrapping; @@ -138,7 +139,7 @@ floorMat.needsUpdate = true; } ); - textureLoader.load( "textures/hardwood2_roughness.jpg", function ( map ) { + textureLoader.load( 'textures/hardwood2_roughness.jpg', function ( map ) { map.wrapS = THREE.RepeatWrapping; map.wrapT = THREE.RepeatWrapping; @@ -155,7 +156,7 @@ bumpScale: 0.002, metalness: 0.2 } ); - textureLoader.load( "textures/brick_diffuse.jpg", function ( map ) { + textureLoader.load( 'textures/brick_diffuse.jpg', function ( map ) { map.wrapS = THREE.RepeatWrapping; map.wrapT = THREE.RepeatWrapping; @@ -166,7 +167,7 @@ cubeMat.needsUpdate = true; } ); - textureLoader.load( "textures/brick_bump.jpg", function ( map ) { + textureLoader.load( 'textures/brick_bump.jpg', function ( map ) { map.wrapS = THREE.RepeatWrapping; map.wrapT = THREE.RepeatWrapping; @@ -182,7 +183,7 @@ roughness: 0.5, metalness: 1.0 } ); - textureLoader.load( "textures/planets/earth_atmos_2048.jpg", function ( map ) { + textureLoader.load( 'textures/planets/earth_atmos_2048.jpg', function ( map ) { map.anisotropy = 4; map.encoding = THREE.sRGBEncoding; @@ -190,7 +191,7 @@ ballMat.needsUpdate = true; } ); - textureLoader.load( "textures/planets/earth_specular_2048.jpg", function ( map ) { + textureLoader.load( 'textures/planets/earth_specular_2048.jpg', function ( map ) { map.anisotropy = 4; map.encoding = THREE.sRGBEncoding; diff --git a/examples/webgl_lights_pointlights.html b/examples/webgl_lights_pointlights.html index d12c3f6f9ca6b3..43487bdae1aca3 100644 --- a/examples/webgl_lights_pointlights.html +++ b/examples/webgl_lights_pointlights.html @@ -20,7 +20,8 @@ @@ -29,9 +30,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OBJLoader } from './jsm/loaders/OBJLoader.js'; + import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; let camera, scene, renderer, light1, light2, light3, light4, diff --git a/examples/webgl_lights_rectarealight.html b/examples/webgl_lights_rectarealight.html index 3a7b13863de344..cc2c2e999a0227 100644 --- a/examples/webgl_lights_rectarealight.html +++ b/examples/webgl_lights_rectarealight.html @@ -20,7 +20,8 @@ @@ -29,11 +30,11 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { RectAreaLightHelper } from './jsm/helpers/RectAreaLightHelper.js'; - import { RectAreaLightUniformsLib } from './jsm/lights/RectAreaLightUniformsLib.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { RectAreaLightHelper } from 'three/addons/helpers/RectAreaLightHelper.js'; + import { RectAreaLightUniformsLib } from 'three/addons/lights/RectAreaLightUniformsLib.js'; let renderer, scene, camera; let stats; diff --git a/examples/webgl_lights_spotlight.html b/examples/webgl_lights_spotlight.html index 98bf7f54f8e07e..43dbb19f1a5f3f 100644 --- a/examples/webgl_lights_spotlight.html +++ b/examples/webgl_lights_spotlight.html @@ -9,7 +9,7 @@
    - three.js webgl - spotlight by Master James
    + three.js webgl - spotlight
    @@ -19,7 +19,8 @@ @@ -28,52 +29,78 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { PLYLoader } from 'three/addons/loaders/PLYLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let renderer, scene, camera; - let spotLight, lightHelper, shadowCameraHelper; + let spotLight, lightHelper; - let gui; + init(); function init() { - renderer = new THREE.WebGLRenderer(); + renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.PCFSoftShadowMap; + renderer.outputEncoding = THREE.sRGBEncoding; + renderer.toneMapping = THREE.ACESFilmicToneMapping; + renderer.toneMappingExposure = 1; + + renderer.setAnimationLoop( render ); + scene = new THREE.Scene(); - camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 1000 ); - camera.position.set( 160, 40, 10 ); + camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 1000 ); + camera.position.set( 70, 50, 10 ); const controls = new OrbitControls( camera, renderer.domElement ); - controls.addEventListener( 'change', render ); controls.minDistance = 20; - controls.maxDistance = 500; - controls.enablePan = false; + controls.maxDistance = 100; + controls.maxPolarAngle = Math.PI / 2; + controls.target.set( 0, 18, 0 ); + controls.update(); - const ambient = new THREE.AmbientLight( 0xffffff, 0.1 ); + const ambient = new THREE.HemisphereLight( 0xffffff, 0x444444, 0.05 ); scene.add( ambient ); - spotLight = new THREE.SpotLight( 0xffffff, 1 ); - spotLight.position.set( 15, 40, 35 ); - spotLight.angle = Math.PI / 4; - spotLight.penumbra = 0.1; + const loader = new THREE.TextureLoader().setPath( 'textures/' ); + const filenames = [ 'disturb.jpg', 'colors.png', 'uv_grid_opengl.jpg' ]; + + const textures = { none: null }; + + for ( let i = 0; i < filenames.length; i ++ ) { + + const filename = filenames[ i ]; + + const texture = loader.load( filename ); + texture.minFilter = THREE.LinearFilter; + texture.magFilter = THREE.LinearFilter; + texture.encoding = THREE.sRGBEncoding; + + textures[ filename ] = texture; + + } + + spotLight = new THREE.SpotLight( 0xffffff, 5 ); + spotLight.position.set( 25, 50, 25 ); + spotLight.angle = Math.PI / 6; + spotLight.penumbra = 1; spotLight.decay = 2; - spotLight.distance = 200; + spotLight.distance = 100; + spotLight.map = textures[ 'disturb.jpg' ]; spotLight.castShadow = true; - spotLight.shadow.mapSize.width = 512; - spotLight.shadow.mapSize.height = 512; + spotLight.shadow.mapSize.width = 1024; + spotLight.shadow.mapSize.height = 1024; spotLight.shadow.camera.near = 10; spotLight.shadow.camera.far = 200; spotLight.shadow.focus = 1; @@ -82,82 +109,68 @@ lightHelper = new THREE.SpotLightHelper( spotLight ); scene.add( lightHelper ); - shadowCameraHelper = new THREE.CameraHelper( spotLight.shadow.camera ); - scene.add( shadowCameraHelper ); - // - let material = new THREE.MeshPhongMaterial( { color: 0x808080, dithering: true } ); + const geometry = new THREE.PlaneGeometry( 1000, 1000 ); + const material = new THREE.MeshLambertMaterial( { color: 0x808080 } ); - let geometry = new THREE.PlaneGeometry( 2000, 2000 ); - - let mesh = new THREE.Mesh( geometry, material ); + const mesh = new THREE.Mesh( geometry, material ); mesh.position.set( 0, - 1, 0 ); - mesh.rotation.x = - Math.PI * 0.5; + mesh.rotation.x = - Math.PI / 2; mesh.receiveShadow = true; scene.add( mesh ); // - material = new THREE.MeshPhongMaterial( { color: 0x4080ff, dithering: true } ); - - geometry = new THREE.CylinderGeometry( 5, 5, 2, 32, 1, false ); + new PLYLoader().load( 'models/ply/binary/Lucy100k.ply', function ( geometry ) { - mesh = new THREE.Mesh( geometry, material ); - mesh.position.set( 0, 5, 0 ); - mesh.castShadow = true; - scene.add( mesh ); + geometry.scale( 0.024, 0.024, 0.024 ); + geometry.computeVertexNormals(); - render(); + const material = new THREE.MeshLambertMaterial(); - window.addEventListener( 'resize', onWindowResize ); + const mesh = new THREE.Mesh( geometry, material ); + mesh.rotation.y = - Math.PI / 2; + mesh.position.y = 18; + mesh.castShadow = true; + mesh.receiveShadow = true; + scene.add( mesh ); - } - - function onWindowResize() { - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize( window.innerWidth, window.innerHeight ); - - } - - function render() { - - lightHelper.update(); - - shadowCameraHelper.update(); - - renderer.render( scene, camera ); + } ); - } + window.addEventListener( 'resize', onWindowResize ); - function buildGui() { + // GUI - gui = new GUI(); + const gui = new GUI(); const params = { - 'light color': spotLight.color.getHex(), + map: textures[ 'disturb.jpg' ], + color: spotLight.color.getHex(), intensity: spotLight.intensity, distance: spotLight.distance, angle: spotLight.angle, penumbra: spotLight.penumbra, decay: spotLight.decay, - focus: spotLight.shadow.focus + focus: spotLight.shadow.focus, + shadows: true }; - gui.addColor( params, 'light color' ).onChange( function ( val ) { + gui.add( params, 'map', textures ).onChange( function ( val ) { + + spotLight.map = val; + + } ); + + gui.addColor( params, 'color' ).onChange( function ( val ) { spotLight.color.setHex( val ); - render(); } ); - gui.add( params, 'intensity', 0, 2 ).onChange( function ( val ) { + gui.add( params, 'intensity', 0, 10 ).onChange( function ( val ) { spotLight.intensity = val; - render(); } ); @@ -165,35 +178,47 @@ gui.add( params, 'distance', 50, 200 ).onChange( function ( val ) { spotLight.distance = val; - render(); } ); gui.add( params, 'angle', 0, Math.PI / 3 ).onChange( function ( val ) { spotLight.angle = val; - render(); } ); gui.add( params, 'penumbra', 0, 1 ).onChange( function ( val ) { spotLight.penumbra = val; - render(); } ); gui.add( params, 'decay', 1, 2 ).onChange( function ( val ) { spotLight.decay = val; - render(); } ); gui.add( params, 'focus', 0, 1 ).onChange( function ( val ) { spotLight.shadow.focus = val; - render(); + + } ); + + + gui.add( params, 'shadows' ).onChange( function ( val ) { + + renderer.shadowMap.enabled = val; + + scene.traverse( function ( child ) { + + if ( child.material ) { + + child.material.needsUpdate = true; + + } + + } ); } ); @@ -201,11 +226,27 @@ } - init(); + function onWindowResize() { - buildGui(); + camera.aspect = window.innerWidth / window.innerHeight; + camera.updateProjectionMatrix(); - render(); + renderer.setSize( window.innerWidth, window.innerHeight ); + + } + + function render() { + + const time = performance.now() / 3000; + + spotLight.position.x = Math.cos( time ) * 25; + spotLight.position.z = Math.sin( time ) * 25; + + lightHelper.update(); + + renderer.render( scene, camera ); + + } diff --git a/examples/webgl_lights_spotlights.html b/examples/webgl_lights_spotlights.html index 865379ab904d85..febd609fe24739 100644 --- a/examples/webgl_lights_spotlights.html +++ b/examples/webgl_lights_spotlights.html @@ -20,21 +20,20 @@ @@ -29,7 +30,7 @@ import * as THREE from 'three'; - import * as GeometryUtils from './jsm/utils/GeometryUtils.js'; + import * as GeometryUtils from 'three/addons/utils/GeometryUtils.js'; let mouseX = 0, mouseY = 0; diff --git a/examples/webgl_lines_dashed.html b/examples/webgl_lines_dashed.html index 40cb7561d56aa4..ea02a3a4834a96 100644 --- a/examples/webgl_lines_dashed.html +++ b/examples/webgl_lines_dashed.html @@ -18,7 +18,8 @@ @@ -27,9 +28,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import * as GeometryUtils from './jsm/utils/GeometryUtils.js'; + import * as GeometryUtils from 'three/addons/utils/GeometryUtils.js'; let renderer, scene, camera, stats; const objects = []; diff --git a/examples/webgl_lines_fat.html b/examples/webgl_lines_fat.html index bbe62c459abada..2083dbebc43fca 100644 --- a/examples/webgl_lines_fat.html +++ b/examples/webgl_lines_fat.html @@ -20,7 +20,8 @@ @@ -29,15 +30,15 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GPUStatsPanel } from './jsm/utils/GPUStatsPanel.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GPUStatsPanel } from 'three/addons/utils/GPUStatsPanel.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { Line2 } from './jsm/lines/Line2.js'; - import { LineMaterial } from './jsm/lines/LineMaterial.js'; - import { LineGeometry } from './jsm/lines/LineGeometry.js'; - import * as GeometryUtils from './jsm/utils/GeometryUtils.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { Line2 } from 'three/addons/lines/Line2.js'; + import { LineMaterial } from 'three/addons/lines/LineMaterial.js'; + import { LineGeometry } from 'three/addons/lines/LineGeometry.js'; + import * as GeometryUtils from 'three/addons/utils/GeometryUtils.js'; let line, renderer, scene, camera, camera2, controls; let line1; diff --git a/examples/webgl_lines_fat_raycasting.html b/examples/webgl_lines_fat_raycasting.html index f923378abdffd6..bc9946aaa71fe8 100644 --- a/examples/webgl_lines_fat_raycasting.html +++ b/examples/webgl_lines_fat_raycasting.html @@ -20,7 +20,8 @@ @@ -29,23 +30,23 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GPUStatsPanel } from './jsm/utils/GPUStatsPanel.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GPUStatsPanel } from 'three/addons/utils/GPUStatsPanel.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { LineMaterial } from './jsm/lines/LineMaterial.js'; - import { LineSegments2 } from './jsm/lines/LineSegments2.js'; - import { LineSegmentsGeometry } from './jsm/lines/LineSegmentsGeometry.js'; - import { Line2 } from './jsm/lines/Line2.js'; - import { LineGeometry } from './jsm/lines/LineGeometry.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { LineMaterial } from 'three/addons/lines/LineMaterial.js'; + import { LineSegments2 } from 'three/addons/lines/LineSegments2.js'; + import { LineSegmentsGeometry } from 'three/addons/lines/LineSegmentsGeometry.js'; + import { Line2 } from 'three/addons/lines/Line2.js'; + import { LineGeometry } from 'three/addons/lines/LineGeometry.js'; let line, thresholdLine, segments, thresholdSegments; let renderer, scene, camera, camera2, controls; - let raycaster, sphereInter, sphereOnLine; - let matLine, matThresholdLine; + let sphereInter, sphereOnLine; let stats, gpuPanel; let gui; + let clock; // viewport let insetWidth; @@ -53,11 +54,57 @@ const pointer = new THREE.Vector2( Infinity, Infinity ); + const raycaster = new THREE.Raycaster(); + + raycaster.params.Line2 = {}; + raycaster.params.Line2.threshold = 0; + + const matLine = new LineMaterial( { + + color: 0xffffff, + linewidth: 1, // in world units with size attenuation, pixels otherwise + worldUnits: true, + vertexColors: true, + + //resolution: // to be set by renderer, eventually + alphaToCoverage: true, + + } ); + + const matThresholdLine = new LineMaterial( { + + color: 0xffffff, + linewidth: matLine.linewidth, // in world units with size attenuation, pixels otherwise + worldUnits: true, + // vertexColors: true, + transparent: true, + opacity: 0.2, + depthTest: false, + visible: false, + //resolution: // to be set by renderer, eventually + + } ); + + const params = { + + 'line type': 0, + 'world units': matLine.worldUnits, + 'visualize threshold': matThresholdLine.visible, + 'width': matLine.linewidth, + 'alphaToCoverage': matLine.alphaToCoverage, + 'threshold': raycaster.params.Line2.threshold, + 'translation': raycaster.params.Line2.threshold, + 'animate': true + + }; + init(); animate(); function init() { + clock = new THREE.Clock(); + renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setClearColor( 0x000000, 0.0 ); @@ -76,10 +123,6 @@ controls.minDistance = 10; controls.maxDistance = 500; - raycaster = new THREE.Raycaster(); - raycaster.params.Line2 = {}; - raycaster.params.Line2.threshold = 0; - const sphereGeometry = new THREE.SphereGeometry( 0.25 ); const sphereInterMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, depthTest: false } ); const sphereOnLineMaterial = new THREE.MeshBasicMaterial( { color: 0x00ff00, depthTest: false } ); @@ -130,32 +173,6 @@ segmentsGeometry.setPositions( positions ); segmentsGeometry.setColors( colors ); - matLine = new LineMaterial( { - - color: 0xffffff, - linewidth: 1, // in world units with size attenuation, pixels otherwise - worldUnits: true, - vertexColors: true, - - //resolution: // to be set by renderer, eventually - alphaToCoverage: true, - - } ); - - matThresholdLine = new LineMaterial( { - - color: 0xffffff, - linewidth: matLine.linewidth, // in world units with size attenuation, pixels otherwise - worldUnits: true, - // vertexColors: true, - transparent: true, - opacity: 0.2, - depthTest: false, - visible: false, - //resolution: // to be set by renderer, eventually - - } ); - segments = new LineSegments2( segmentsGeometry, matLine ); segments.computeLineDistances(); segments.scale.set( 1, 1, 1 ); @@ -227,13 +244,32 @@ // main scene + const delta = clock.getDelta(); + + const obj = line.visible ? line : segments; + thresholdLine.position.copy( line.position ); + thresholdLine.quaternion.copy( line.quaternion ); + thresholdSegments.position.copy( segments.position ); + thresholdSegments.quaternion.copy( segments.quaternion ); + + if ( params.animate ) { + + line.rotation.y += delta * 0.5; + segments.rotation.y += delta * 0.5; + + } + renderer.setClearColor( 0x000000, 0 ); renderer.setViewport( 0, 0, window.innerWidth, window.innerHeight ); raycaster.setFromCamera( pointer, camera ); - const obj = line.visible ? line : segments; + // renderer will set this eventually + // set the new resolution before raycasting so it is set correctly + matLine.resolution.set( window.innerWidth, window.innerHeight ); // resolution of the viewport + matThresholdLine.resolution.set( window.innerWidth, window.innerHeight ); // resolution of the viewport + const intersects = raycaster.intersectObject( obj, true ); if ( intersects.length > 0 ) { @@ -257,10 +293,6 @@ } - // renderer will set this eventually - matLine.resolution.set( window.innerWidth, window.innerHeight ); // resolution of the viewport - matThresholdLine.resolution.set( window.innerWidth, window.innerHeight ); // resolution of the viewport - gpuPanel.startQuery(); renderer.render( scene, camera ); gpuPanel.endQuery(); @@ -321,22 +353,13 @@ gui = new GUI(); - const param = { - 'line type': 0, - 'world units': matLine.worldUnits, - 'visualize threshold': matThresholdLine.visible, - 'width': matLine.linewidth, - 'alphaToCoverage': matLine.alphaToCoverage, - 'threshold': raycaster.params.Line2.threshold - }; - - gui.add( param, 'line type', { 'LineGeometry': 0, 'LineSegmentsGeometry': 1 } ).onChange( function ( val ) { + gui.add( params, 'line type', { 'LineGeometry': 0, 'LineSegmentsGeometry': 1 } ).onChange( function ( val ) { switchLine( val ); } ).setValue( 1 ); - gui.add( param, 'world units' ).onChange( function ( val ) { + gui.add( params, 'world units' ).onChange( function ( val ) { matLine.worldUnits = val; matLine.needsUpdate = true; @@ -345,32 +368,41 @@ } ); - gui.add( param, 'visualize threshold' ).onChange( function ( val ) { + gui.add( params, 'visualize threshold' ).onChange( function ( val ) { matThresholdLine.visible = val; } ); - gui.add( param, 'width', 1, 10 ).onChange( function ( val ) { + gui.add( params, 'width', 1, 10 ).onChange( function ( val ) { matLine.linewidth = val; matThresholdLine.linewidth = matLine.linewidth + raycaster.params.Line2.threshold; } ); - gui.add( param, 'alphaToCoverage' ).onChange( function ( val ) { + gui.add( params, 'alphaToCoverage' ).onChange( function ( val ) { matLine.alphaToCoverage = val; } ); - gui.add( param, 'threshold', 0, 10 ).onChange( function ( val ) { + gui.add( params, 'threshold', 0, 10 ).onChange( function ( val ) { raycaster.params.Line2.threshold = val; matThresholdLine.linewidth = matLine.linewidth + raycaster.params.Line2.threshold; } ); + gui.add( params, 'translation', 0, 10 ).onChange( function ( val ) { + + line.position.x = val; + segments.position.x = val; + + } ); + + gui.add( params, 'animate' ); + } diff --git a/examples/webgl_lines_fat_wireframe.html b/examples/webgl_lines_fat_wireframe.html index 8cf7d3dc49280b..ba877f63b8fa5c 100644 --- a/examples/webgl_lines_fat_wireframe.html +++ b/examples/webgl_lines_fat_wireframe.html @@ -20,7 +20,8 @@ @@ -29,13 +30,13 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { LineMaterial } from './jsm/lines/LineMaterial.js'; - import { Wireframe } from './jsm/lines/Wireframe.js'; - import { WireframeGeometry2 } from './jsm/lines/WireframeGeometry2.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { LineMaterial } from 'three/addons/lines/LineMaterial.js'; + import { Wireframe } from 'three/addons/lines/Wireframe.js'; + import { WireframeGeometry2 } from 'three/addons/lines/WireframeGeometry2.js'; let wireframe, renderer, scene, camera, camera2, controls; let wireframe1; @@ -222,7 +223,7 @@ // dashed is implemented as a defines -- not as a uniform. this could be changed. // ... or THREE.LineDashedMaterial could be implemented as a separate material // temporary hack - renderer should do this eventually - if ( val ) matLine.defines.USE_DASH = ""; else delete matLine.defines.USE_DASH; + if ( val ) matLine.defines.USE_DASH = ''; else delete matLine.defines.USE_DASH; matLine.needsUpdate = true; wireframe1.material = val ? matLineDashed : matLineBasic; diff --git a/examples/webgl_lines_sphere.html b/examples/webgl_lines_sphere.html index f520d3e9a6f239..c3ca27f723fc43 100644 --- a/examples/webgl_lines_sphere.html +++ b/examples/webgl_lines_sphere.html @@ -19,7 +19,8 @@ diff --git a/examples/webgl_loader_3dm.html b/examples/webgl_loader_3dm.html index 65e383f57cc653..7684027872c689 100644 --- a/examples/webgl_loader_3dm.html +++ b/examples/webgl_loader_3dm.html @@ -39,7 +39,8 @@ @@ -48,10 +49,10 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { Rhino3dmLoader } from './jsm/loaders/3DMLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { Rhino3dmLoader } from 'three/addons/loaders/3DMLoader.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let camera, scene, renderer; let controls, gui; diff --git a/examples/webgl_loader_3ds.html b/examples/webgl_loader_3ds.html index 64d4788a273395..b4145803c10afb 100644 --- a/examples/webgl_loader_3ds.html +++ b/examples/webgl_loader_3ds.html @@ -19,7 +19,8 @@ @@ -28,8 +29,8 @@ import * as THREE from 'three'; - import { TrackballControls } from './jsm/controls/TrackballControls.js'; - import { TDSLoader } from './jsm/loaders/TDSLoader.js'; + import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; + import { TDSLoader } from 'three/addons/loaders/TDSLoader.js'; let container, controls; let camera, scene, renderer; diff --git a/examples/webgl_loader_3mf.html b/examples/webgl_loader_3mf.html index 1bbae449d1671c..079f4bcc296642 100644 --- a/examples/webgl_loader_3mf.html +++ b/examples/webgl_loader_3mf.html @@ -26,7 +26,8 @@ @@ -35,9 +36,9 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { ThreeMFLoader } from './jsm/loaders/3MFLoader.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { ThreeMFLoader } from 'three/addons/loaders/3MFLoader.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let camera, scene, renderer, object, loader, controls; diff --git a/examples/webgl_loader_3mf_materials.html b/examples/webgl_loader_3mf_materials.html index a4a083a6b0139e..a89259714283dc 100644 --- a/examples/webgl_loader_3mf_materials.html +++ b/examples/webgl_loader_3mf_materials.html @@ -24,7 +24,8 @@ @@ -33,8 +34,8 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { ThreeMFLoader } from './jsm/loaders/3MFLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { ThreeMFLoader } from 'three/addons/loaders/3MFLoader.js'; let camera, scene, renderer; diff --git a/examples/webgl_loader_amf.html b/examples/webgl_loader_amf.html index e3e00d96a180a0..8eb95582c51df3 100644 --- a/examples/webgl_loader_amf.html +++ b/examples/webgl_loader_amf.html @@ -23,7 +23,8 @@ @@ -32,8 +33,8 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { AMFLoader } from './jsm/loaders/AMFLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { AMFLoader } from 'three/addons/loaders/AMFLoader.js'; let camera, scene, renderer; diff --git a/examples/webgl_loader_bvh.html b/examples/webgl_loader_bvh.html index e8ef7569b8e50e..09729582d01585 100644 --- a/examples/webgl_loader_bvh.html +++ b/examples/webgl_loader_bvh.html @@ -28,7 +28,8 @@ @@ -37,8 +38,8 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { BVHLoader } from './jsm/loaders/BVHLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { BVHLoader } from 'three/addons/loaders/BVHLoader.js'; const clock = new THREE.Clock(); @@ -49,7 +50,7 @@ animate(); const loader = new BVHLoader(); - loader.load( "models/bvh/pirouette.bvh", function ( result ) { + loader.load( 'models/bvh/pirouette.bvh', function ( result ) { skeletonHelper = new THREE.SkeletonHelper( result.skeleton.bones[ 0 ] ); skeletonHelper.skeleton = result.skeleton; // allow animation mixer to bind to THREE.SkeletonHelper directly diff --git a/examples/webgl_loader_collada.html b/examples/webgl_loader_collada.html index ed24ecb288c028..9b352719f9def8 100644 --- a/examples/webgl_loader_collada.html +++ b/examples/webgl_loader_collada.html @@ -21,7 +21,8 @@ @@ -30,9 +31,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { ColladaLoader } from './jsm/loaders/ColladaLoader.js'; + import { ColladaLoader } from 'three/addons/loaders/ColladaLoader.js'; let container, stats, clock; let camera, scene, renderer, elf; diff --git a/examples/webgl_loader_collada_kinematics.html b/examples/webgl_loader_collada_kinematics.html index 4bc8c18dfa753d..a64a29f8d6c4af 100644 --- a/examples/webgl_loader_collada_kinematics.html +++ b/examples/webgl_loader_collada_kinematics.html @@ -19,7 +19,8 @@ @@ -28,10 +29,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { TWEEN } from './jsm/libs/tween.module.min.js'; - import { ColladaLoader } from './jsm/loaders/ColladaLoader.js'; + import { TWEEN } from 'three/addons/libs/tween.module.min.js'; + import { ColladaLoader } from 'three/addons/loaders/ColladaLoader.js'; let container, stats; @@ -44,7 +45,6 @@ const tweenParameters = {}; const loader = new ColladaLoader(); - // loader.load( './models/collada/kawada-hironx.dae', function ( collada ) { loader.load( './models/collada/abb_irb52_7_120.dae', function ( collada ) { dae = collada.scene; diff --git a/examples/webgl_loader_collada_skinning.html b/examples/webgl_loader_collada_skinning.html index 4cb67da0118225..8d454291f37ffa 100644 --- a/examples/webgl_loader_collada_skinning.html +++ b/examples/webgl_loader_collada_skinning.html @@ -21,7 +21,8 @@ @@ -30,10 +31,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { ColladaLoader } from './jsm/loaders/ColladaLoader.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { ColladaLoader } from 'three/addons/loaders/ColladaLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let container, stats, clock, controls; let camera, scene, renderer, mixer; diff --git a/examples/webgl_loader_draco.html b/examples/webgl_loader_draco.html index 6c65664c2e4fef..87782a1a5e1afb 100644 --- a/examples/webgl_loader_draco.html +++ b/examples/webgl_loader_draco.html @@ -21,7 +21,8 @@ @@ -29,7 +30,7 @@ @@ -29,10 +30,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { FBXLoader } from './jsm/loaders/FBXLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { FBXLoader } from 'three/addons/loaders/FBXLoader.js'; let camera, scene, renderer, stats; diff --git a/examples/webgl_loader_fbx_nurbs.html b/examples/webgl_loader_fbx_nurbs.html index 019b0de95952d5..edfa2e866c1a2d 100644 --- a/examples/webgl_loader_fbx_nurbs.html +++ b/examples/webgl_loader_fbx_nurbs.html @@ -19,7 +19,8 @@ @@ -28,10 +29,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { FBXLoader } from './jsm/loaders/FBXLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { FBXLoader } from 'three/addons/loaders/FBXLoader.js'; let camera, scene, renderer, stats; diff --git a/examples/webgl_loader_gcode.html b/examples/webgl_loader_gcode.html index 6587d46201e12c..6e8d2c1082a9b0 100644 --- a/examples/webgl_loader_gcode.html +++ b/examples/webgl_loader_gcode.html @@ -19,7 +19,8 @@ @@ -28,8 +29,8 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GCodeLoader } from './jsm/loaders/GCodeLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GCodeLoader } from 'three/addons/loaders/GCodeLoader.js'; let camera, scene, renderer; diff --git a/examples/webgl_loader_gltf.html b/examples/webgl_loader_gltf.html index 9380fa08113766..97e1f45f9b0c52 100644 --- a/examples/webgl_loader_gltf.html +++ b/examples/webgl_loader_gltf.html @@ -22,7 +22,8 @@ @@ -31,9 +32,9 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import { RGBELoader } from './jsm/loaders/RGBELoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; let camera, scene, renderer; diff --git a/examples/webgl_loader_gltf_compressed.html b/examples/webgl_loader_gltf_compressed.html index 02bdc03c34f6d4..d37e24caaa94cd 100644 --- a/examples/webgl_loader_gltf_compressed.html +++ b/examples/webgl_loader_gltf_compressed.html @@ -21,7 +21,8 @@ @@ -30,12 +31,12 @@ import * as THREE from 'three'; - import { RoomEnvironment } from './jsm/environments/RoomEnvironment.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; + import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { KTX2Loader } from './jsm/loaders/KTX2Loader.js'; - import { MeshoptDecoder } from './jsm/libs/meshopt_decoder.module.js'; + import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; + import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js'; let camera, scene, renderer; @@ -64,6 +65,7 @@ scene = new THREE.Scene(); scene.background = new THREE.Color( 0xbbbbbb ); scene.environment = pmremGenerator.fromScene( environment ).texture; + environment.dispose(); const grid = new THREE.GridHelper( 500, 10, 0xffffff, 0xffffff ); grid.material.opacity = 0.5; diff --git a/examples/webgl_loader_gltf_instancing.html b/examples/webgl_loader_gltf_instancing.html new file mode 100644 index 00000000000000..0121991a00b36f --- /dev/null +++ b/examples/webgl_loader_gltf_instancing.html @@ -0,0 +1,119 @@ + + + + three.js webgl - GLTFloader + Instancing + + + + + + +
    + three.js - GLTFLoader + EXT_mesh_gpu_instancing
    + Battle Damaged Sci-fi Helmet by + theblueturtle_
    + Royal Esplanade by HDRI Haven +
    + + + + + + + + + + + diff --git a/examples/webgl_loader_gltf_iridescence.html b/examples/webgl_loader_gltf_iridescence.html index c56b17d366d4eb..090b724d2f8630 100644 --- a/examples/webgl_loader_gltf_iridescence.html +++ b/examples/webgl_loader_gltf_iridescence.html @@ -21,7 +21,8 @@ @@ -30,9 +31,9 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import { RGBELoader } from './jsm/loaders/RGBELoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; let renderer, scene, camera, controls; diff --git a/examples/webgl_loader_gltf_sheen.html b/examples/webgl_loader_gltf_sheen.html index 9514cc1eaf6012..ec443eb5f37183 100644 --- a/examples/webgl_loader_gltf_sheen.html +++ b/examples/webgl_loader_gltf_sheen.html @@ -25,7 +25,8 @@ @@ -34,11 +35,11 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import { RoomEnvironment } from './jsm/environments/RoomEnvironment.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let camera, scene, renderer, controls; diff --git a/examples/webgl_loader_gltf_transmission.html b/examples/webgl_loader_gltf_transmission.html index b87da7c0327ab1..c0a8139244dbe8 100644 --- a/examples/webgl_loader_gltf_transmission.html +++ b/examples/webgl_loader_gltf_transmission.html @@ -21,7 +21,8 @@ @@ -30,11 +31,11 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import { RGBELoader } from './jsm/loaders/RGBELoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - import { DRACOLoader } from './jsm/loaders/DRACOLoader.js'; + import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; let camera, scene, renderer, controls, clock, mixer; diff --git a/examples/webgl_loader_gltf_variants.html b/examples/webgl_loader_gltf_variants.html index b28b064bd44b52..bd3051fbfe702c 100644 --- a/examples/webgl_loader_gltf_variants.html +++ b/examples/webgl_loader_gltf_variants.html @@ -22,7 +22,8 @@ @@ -31,10 +32,10 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import { RGBELoader } from './jsm/loaders/RGBELoader.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; let camera, scene, renderer; let gui; diff --git a/examples/webgl_loader_ifc.html b/examples/webgl_loader_ifc.html index 71eca630b37adb..f83b20c8223746 100644 --- a/examples/webgl_loader_ifc.html +++ b/examples/webgl_loader_ifc.html @@ -24,7 +24,8 @@ @@ -32,9 +33,9 @@ @@ -36,7 +37,6 @@ function addImageBitmap() { new THREE.ImageBitmapLoader() - .setOptions( { imageOrientation: 'none' } ) .load( 'textures/planets/earth_atmos_2048.jpg?' + performance.now(), function ( imageBitmap ) { const texture = new THREE.CanvasTexture( imageBitmap ); diff --git a/examples/webgl_loader_kmz.html b/examples/webgl_loader_kmz.html index 4b13a61ce2aae5..eeee681ddcf7a9 100644 --- a/examples/webgl_loader_kmz.html +++ b/examples/webgl_loader_kmz.html @@ -19,7 +19,8 @@ @@ -28,8 +29,8 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { KMZLoader } from './jsm/loaders/KMZLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { KMZLoader } from 'three/addons/loaders/KMZLoader.js'; let camera, scene, renderer; diff --git a/examples/webgl_loader_ldraw.html b/examples/webgl_loader_ldraw.html index 7f4def486d2b13..aa341990d7f3de 100644 --- a/examples/webgl_loader_ldraw.html +++ b/examples/webgl_loader_ldraw.html @@ -27,7 +27,8 @@ @@ -36,13 +37,13 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { RoomEnvironment } from './jsm/environments/RoomEnvironment.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; - import { LDrawLoader } from './jsm/loaders/LDrawLoader.js'; - import { LDrawUtils } from './jsm/utils/LDrawUtils.js'; + import { LDrawLoader } from 'three/addons/loaders/LDrawLoader.js'; + import { LDrawUtils } from 'three/addons/utils/LDrawUtils.js'; let container, progressBarDiv; @@ -109,8 +110,8 @@ displayLines: true, conditionalLines: true, smoothNormals: true, - constructionStep: 0, - noConstructionSteps: 'No steps.', + buildingStep: 0, + noBuildingSteps: 'No steps.', flatColors: false, mergeModel: false }; @@ -152,8 +153,8 @@ } else if ( c.isGroup ) { - // Hide objects with construction step > gui setting - c.visible = c.userData.constructionStep <= guiData.constructionStep; + // Hide objects with building step > gui setting + c.visible = c.userData.buildingStep <= guiData.buildingStep; } @@ -236,7 +237,7 @@ scene.add( model ); - guiData.constructionStep = model.userData.numConstructionSteps - 1; + guiData.buildingStep = model.userData.numBuildingSteps - 1; updateObjectsVisibility(); @@ -299,13 +300,13 @@ } ); - if ( model.userData.numConstructionSteps > 1 ) { + if ( model.userData.numBuildingSteps > 1 ) { - gui.add( guiData, 'constructionStep', 0, model.userData.numConstructionSteps - 1 ).step( 1 ).name( 'Construction step' ).onChange( updateObjectsVisibility ); + gui.add( guiData, 'buildingStep', 0, model.userData.numBuildingSteps - 1 ).step( 1 ).name( 'Building step' ).onChange( updateObjectsVisibility ); } else { - gui.add( guiData, 'noConstructionSteps' ).name( 'Construction step' ).onChange( updateObjectsVisibility ); + gui.add( guiData, 'noBuildingSteps' ).name( 'Building step' ).onChange( updateObjectsVisibility ); } diff --git a/examples/webgl_loader_lwo.html b/examples/webgl_loader_lwo.html index 34fc9ad08e6009..dcdc5a9ae539ef 100644 --- a/examples/webgl_loader_lwo.html +++ b/examples/webgl_loader_lwo.html @@ -22,7 +22,8 @@ @@ -31,8 +32,8 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { LWOLoader } from './jsm/loaders/LWOLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { LWOLoader } from 'three/addons/loaders/LWOLoader.js'; let camera, scene, renderer; diff --git a/examples/webgl_loader_md2.html b/examples/webgl_loader_md2.html index 73c22ab780de3d..e1bbcbf2eb76ac 100644 --- a/examples/webgl_loader_md2.html +++ b/examples/webgl_loader_md2.html @@ -19,7 +19,8 @@ @@ -28,12 +29,12 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { MD2Character } from './jsm/misc/MD2Character.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { MD2Character } from 'three/addons/misc/MD2Character.js'; let SCREEN_WIDTH = window.innerWidth; let SCREEN_HEIGHT = window.innerHeight; @@ -106,7 +107,7 @@ // GROUND - const gt = new THREE.TextureLoader().load( "textures/terrain/grasslight-big.jpg" ); + const gt = new THREE.TextureLoader().load( 'textures/terrain/grasslight-big.jpg' ); const gg = new THREE.PlaneGeometry( 2000, 2000 ); const gm = new THREE.MeshPhongMaterial( { color: 0xffffff, map: gt } ); @@ -166,21 +167,21 @@ const config = { - baseUrl: "models/md2/ratamahatta/", - - body: "ratamahatta.md2", - skins: [ "ratamahatta.png", "ctf_b.png", "ctf_r.png", "dead.png", "gearwhore.png" ], - weapons: [[ "weapon.md2", "weapon.png" ], - [ "w_bfg.md2", "w_bfg.png" ], - [ "w_blaster.md2", "w_blaster.png" ], - [ "w_chaingun.md2", "w_chaingun.png" ], - [ "w_glauncher.md2", "w_glauncher.png" ], - [ "w_hyperblaster.md2", "w_hyperblaster.png" ], - [ "w_machinegun.md2", "w_machinegun.png" ], - [ "w_railgun.md2", "w_railgun.png" ], - [ "w_rlauncher.md2", "w_rlauncher.png" ], - [ "w_shotgun.md2", "w_shotgun.png" ], - [ "w_sshotgun.md2", "w_sshotgun.png" ] + baseUrl: 'models/md2/ratamahatta/', + + body: 'ratamahatta.md2', + skins: [ 'ratamahatta.png', 'ctf_b.png', 'ctf_r.png', 'dead.png', 'gearwhore.png' ], + weapons: [[ 'weapon.md2', 'weapon.png' ], + [ 'w_bfg.md2', 'w_bfg.png' ], + [ 'w_blaster.md2', 'w_blaster.png' ], + [ 'w_chaingun.md2', 'w_chaingun.png' ], + [ 'w_glauncher.md2', 'w_glauncher.png' ], + [ 'w_hyperblaster.md2', 'w_hyperblaster.png' ], + [ 'w_machinegun.md2', 'w_machinegun.png' ], + [ 'w_railgun.md2', 'w_railgun.png' ], + [ 'w_rlauncher.md2', 'w_rlauncher.png' ], + [ 'w_shotgun.md2', 'w_shotgun.png' ], + [ 'w_sshotgun.md2', 'w_sshotgun.png' ] ] }; @@ -222,12 +223,12 @@ function labelize( text ) { - const parts = text.split( "." ); + const parts = text.split( '.' ); if ( parts.length > 1 ) { parts.length -= 1; - return parts.join( "." ); + return parts.join( '.' ); } @@ -239,7 +240,7 @@ function setupWeaponsGUI( character ) { - const folder = gui.addFolder( "Weapons" ); + const folder = gui.addFolder( 'Weapons' ); const generateCallback = function ( index ) { @@ -268,7 +269,7 @@ function setupSkinsGUI( character ) { - const folder = gui.addFolder( "Skins" ); + const folder = gui.addFolder( 'Skins' ); const generateCallback = function ( index ) { @@ -297,7 +298,7 @@ function setupGUIAnimations( character ) { - const folder = gui.addFolder( "Animations" ); + const folder = gui.addFolder( 'Animations' ); const generateCallback = function ( animationClip ) { diff --git a/examples/webgl_loader_md2_control.html b/examples/webgl_loader_md2_control.html index 0134acce2a3a19..5aea4c1f4a8c3b 100644 --- a/examples/webgl_loader_md2_control.html +++ b/examples/webgl_loader_md2_control.html @@ -29,7 +29,8 @@ @@ -38,11 +39,11 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { MD2CharacterComplex } from './jsm/misc/MD2CharacterComplex.js'; - import { Gyroscope } from './jsm/misc/Gyroscope.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { MD2CharacterComplex } from 'three/addons/misc/MD2CharacterComplex.js'; + import { Gyroscope } from 'three/addons/misc/Gyroscope.js'; let SCREEN_WIDTH = window.innerWidth; let SCREEN_HEIGHT = window.innerHeight; diff --git a/examples/webgl_loader_mdd.html b/examples/webgl_loader_mdd.html index 12f29ab0b974cb..00aa110e0a6a26 100644 --- a/examples/webgl_loader_mdd.html +++ b/examples/webgl_loader_mdd.html @@ -19,7 +19,8 @@ @@ -28,7 +29,7 @@ import * as THREE from 'three'; - import { MDDLoader } from './jsm/loaders/MDDLoader.js'; + import { MDDLoader } from 'three/addons/loaders/MDDLoader.js'; let camera, scene, renderer, mixer, clock; diff --git a/examples/webgl_loader_mmd.html b/examples/webgl_loader_mmd.html index db04cde65d9ed3..9d650642d62d4e 100644 --- a/examples/webgl_loader_mmd.html +++ b/examples/webgl_loader_mmd.html @@ -34,7 +34,8 @@ @@ -43,13 +44,13 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { OutlineEffect } from './jsm/effects/OutlineEffect.js'; - import { MMDLoader } from './jsm/loaders/MMDLoader.js'; - import { MMDAnimationHelper } from './jsm/animation/MMDAnimationHelper.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { OutlineEffect } from 'three/addons/effects/OutlineEffect.js'; + import { MMDLoader } from 'three/addons/loaders/MMDLoader.js'; + import { MMDAnimationHelper } from 'three/addons/animation/MMDAnimationHelper.js'; let stats; @@ -81,7 +82,7 @@ scene = new THREE.Scene(); scene.background = new THREE.Color( 0xffffff ); - const gridHelper = new THREE.PolarGridHelper( 30, 10 ); + const gridHelper = new THREE.PolarGridHelper( 30, 0 ); gridHelper.position.y = - 10; scene.add( gridHelper ); diff --git a/examples/webgl_loader_mmd_audio.html b/examples/webgl_loader_mmd_audio.html index 67d6daec15ea9e..64a66eb28b7e27 100644 --- a/examples/webgl_loader_mmd_audio.html +++ b/examples/webgl_loader_mmd_audio.html @@ -8,6 +8,7 @@ + + +
    + three.js - USDZLoader +
    + + + + + + + + + + diff --git a/examples/webgl_loader_vox.html b/examples/webgl_loader_vox.html index 19891233b751e8..2d63453f7ae0aa 100644 --- a/examples/webgl_loader_vox.html +++ b/examples/webgl_loader_vox.html @@ -19,7 +19,8 @@ @@ -28,8 +29,8 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { VOXLoader, VOXMesh } from './jsm/loaders/VOXLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { VOXLoader, VOXMesh } from 'three/addons/loaders/VOXLoader.js'; let camera, controls, scene, renderer; diff --git a/examples/webgl_loader_vrml.html b/examples/webgl_loader_vrml.html index 551e761b17c3b1..9662f4c29e199e 100644 --- a/examples/webgl_loader_vrml.html +++ b/examples/webgl_loader_vrml.html @@ -19,7 +19,8 @@ @@ -28,11 +29,11 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { VRMLLoader } from './jsm/loaders/VRMLLoader.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { VRMLLoader } from 'three/addons/loaders/VRMLLoader.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let camera, scene, renderer, stats, controls, loader; diff --git a/examples/webgl_loader_vtk.html b/examples/webgl_loader_vtk.html index 4a412dfd50b119..9374eedaf40d83 100644 --- a/examples/webgl_loader_vtk.html +++ b/examples/webgl_loader_vtk.html @@ -21,7 +21,8 @@ @@ -30,10 +31,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { TrackballControls } from './jsm/controls/TrackballControls.js'; - import { VTKLoader } from './jsm/loaders/VTKLoader.js'; + import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; + import { VTKLoader } from 'three/addons/loaders/VTKLoader.js'; let container, stats; diff --git a/examples/webgl_loader_xyz.html b/examples/webgl_loader_xyz.html index 4f3c17adfb5a97..d8625036596c05 100644 --- a/examples/webgl_loader_xyz.html +++ b/examples/webgl_loader_xyz.html @@ -20,7 +20,8 @@ @@ -29,7 +30,7 @@ import * as THREE from 'three'; - import { XYZLoader } from './jsm/loaders/XYZLoader.js'; + import { XYZLoader } from 'three/addons/loaders/XYZLoader.js'; let camera, scene, renderer, clock; diff --git a/examples/webgl_lod.html b/examples/webgl_lod.html index b1358d04f29dbd..ae014088f23df4 100644 --- a/examples/webgl_lod.html +++ b/examples/webgl_lod.html @@ -19,7 +19,8 @@ @@ -28,7 +29,7 @@ import * as THREE from 'three'; - import { FlyControls } from './jsm/controls/FlyControls.js'; + import { FlyControls } from 'three/addons/controls/FlyControls.js'; let container; diff --git a/examples/webgl_marchingcubes.html b/examples/webgl_marchingcubes.html index 40193968c9297c..5e52701b1ecac7 100644 --- a/examples/webgl_marchingcubes.html +++ b/examples/webgl_marchingcubes.html @@ -23,7 +23,8 @@ @@ -31,12 +32,12 @@ @@ -27,7 +28,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let stats; diff --git a/examples/webgl_materials_blending.html b/examples/webgl_materials_blending.html index 3db91b7d26a559..284780d319a5f1 100644 --- a/examples/webgl_materials_blending.html +++ b/examples/webgl_materials_blending.html @@ -15,7 +15,8 @@ diff --git a/examples/webgl_materials_blending_custom.html b/examples/webgl_materials_blending_custom.html index 93f1c0d3918f69..fccd40d44440d8 100644 --- a/examples/webgl_materials_blending_custom.html +++ b/examples/webgl_materials_blending_custom.html @@ -15,7 +15,8 @@ @@ -24,7 +25,7 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let camera, scene, renderer; diff --git a/examples/webgl_materials_bumpmap.html b/examples/webgl_materials_bumpmap.html index bb52aebfe73011..53c4823e9d6b0d 100644 --- a/examples/webgl_materials_bumpmap.html +++ b/examples/webgl_materials_bumpmap.html @@ -20,7 +20,8 @@ @@ -29,9 +30,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; const statsEnabled = true; diff --git a/examples/webgl_materials_car.html b/examples/webgl_materials_car.html index a1e8c7a241e6b2..5c1742a9c3cfa4 100644 --- a/examples/webgl_materials_car.html +++ b/examples/webgl_materials_car.html @@ -39,7 +39,8 @@ @@ -48,13 +49,13 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import { DRACOLoader } from './jsm/loaders/DRACOLoader.js'; - import { RGBELoader } from './jsm/loaders/RGBELoader.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; + import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; let camera, scene, renderer; let stats; diff --git a/examples/webgl_materials_channels.html b/examples/webgl_materials_channels.html index 4cc3d9607d7d6e..b29688e4d42188 100644 --- a/examples/webgl_materials_channels.html +++ b/examples/webgl_materials_channels.html @@ -9,7 +9,7 @@
    - three.js - Normal, Depth, DepthRGBA, DepthRGBAUnpacked, Materials
    + three.js - Normal, Velocity, Depth, DepthRGBA, DepthRGBAUnpacked, Materials
    by Ben Houston. ninja head from AMD GPU MeshMapper
    @@ -20,7 +20,8 @@ @@ -29,11 +30,13 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; + + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { VelocityShader } from 'three/addons/shaders/VelocityShader.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OBJLoader } from './jsm/loaders/OBJLoader.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; let stats; @@ -54,7 +57,7 @@ let cameraOrtho, cameraPerspective; let controlsOrtho, controlsPerspective; - let mesh, materialStandard, materialDepthBasic, materialDepthRGBA, materialNormal; + let mesh, materialStandard, materialDepthBasic, materialDepthRGBA, materialNormal, materialVelocity; const SCALE = 2.436143; // from original model const BIAS = - 0.428408; // from original model @@ -67,7 +70,7 @@ function initGui() { const gui = new GUI(); - gui.add( params, 'material', [ 'standard', 'normal', 'depthBasic', 'depthRGBA' ] ); + gui.add( params, 'material', [ 'standard', 'normal', 'velocity', 'depthBasic', 'depthRGBA' ] ); gui.add( params, 'camera', [ 'perspective', 'ortho' ] ); gui.add( params, 'side', [ 'front', 'back', 'double' ] ); @@ -190,6 +193,17 @@ side: THREE.DoubleSide } ); + materialVelocity = new THREE.ShaderMaterial( { + uniforms: THREE.UniformsUtils.clone( VelocityShader.uniforms ), + vertexShader: VelocityShader.vertexShader, + fragmentShader: VelocityShader.fragmentShader, + side: THREE.DoubleSide + } ); + materialVelocity.uniforms.displacementMap.value = displacementMap; + materialVelocity.uniforms.displacementScale.value = SCALE; + materialVelocity.uniforms.displacementBias.value = BIAS; + materialVelocity.extensions.derivatives = true; + // const loader = new OBJLoader(); @@ -201,6 +215,7 @@ mesh = new THREE.Mesh( geometry, materialNormal ); mesh.scale.multiplyScalar( 25 ); + mesh.userData.matrixWorldPrevious = new THREE.Matrix4(); // for velocity scene.add( mesh ); } ); @@ -260,6 +275,7 @@ case 'depthBasic': material = materialDepthBasic; break; case 'depthRGBA': material = materialDepthRGBA; break; case 'normal': material = materialNormal; break; + case 'velocity': material = materialVelocity; break; } @@ -295,8 +311,29 @@ controlsPerspective.update(); controlsOrtho.update(); // must update both controls for damping to complete + // remember camera projection changes + + materialVelocity.uniforms.previousProjectionViewMatrix.value.copy( materialVelocity.uniforms.currentProjectionViewMatrix.value ); + materialVelocity.uniforms.currentProjectionViewMatrix.value.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); + + if ( mesh && mesh.userData.matrixWorldPrevious ) { + + materialVelocity.uniforms.modelMatrixPrev.value.copy( mesh.userData.matrixWorldPrevious ); + + } + renderer.render( scene, camera ); + scene.traverse( function ( object ) { + + if ( object.isMesh ) { + + object.userData.matrixWorldPrevious.copy( object.matrixWorld ); + + } + + } ); + } diff --git a/examples/webgl_materials_cubemap.html b/examples/webgl_materials_cubemap.html index 6980af019e80ea..6f8100970eed01 100644 --- a/examples/webgl_materials_cubemap.html +++ b/examples/webgl_materials_cubemap.html @@ -21,7 +21,8 @@ @@ -30,10 +31,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { OBJLoader } from './jsm/loaders/OBJLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; let container, stats; diff --git a/examples/webgl_materials_cubemap_dynamic.html b/examples/webgl_materials_cubemap_dynamic.html index d94b73fd46cf89..8d164a913a65df 100644 --- a/examples/webgl_materials_cubemap_dynamic.html +++ b/examples/webgl_materials_cubemap_dynamic.html @@ -22,7 +22,8 @@ @@ -31,11 +32,11 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { RGBELoader } from './jsm/loaders/RGBELoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import Stats from './jsm/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; let camera, scene, renderer, stats; let cube, sphere, torus, material; diff --git a/examples/webgl_materials_cubemap_mipmaps.html b/examples/webgl_materials_cubemap_mipmaps.html index a27624f2dc818b..282551df5e6594 100644 --- a/examples/webgl_materials_cubemap_mipmaps.html +++ b/examples/webgl_materials_cubemap_mipmaps.html @@ -22,7 +22,8 @@ @@ -31,7 +32,7 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let container; diff --git a/examples/webgl_materials_cubemap_refraction.html b/examples/webgl_materials_cubemap_refraction.html index 5225a56124779f..b8a2796b42a039 100644 --- a/examples/webgl_materials_cubemap_refraction.html +++ b/examples/webgl_materials_cubemap_refraction.html @@ -21,7 +21,8 @@ @@ -30,9 +31,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { PLYLoader } from './jsm/loaders/PLYLoader.js'; + import { PLYLoader } from 'three/addons/loaders/PLYLoader.js'; let container, stats; diff --git a/examples/webgl_materials_curvature.html b/examples/webgl_materials_curvature.html index 8848fa13fa4856..6209f0517d9bdd 100644 --- a/examples/webgl_materials_curvature.html +++ b/examples/webgl_materials_curvature.html @@ -49,7 +49,8 @@ @@ -58,9 +59,9 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { OBJLoader } from './jsm/loaders/OBJLoader.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; let camera, scene, renderer; diff --git a/examples/webgl_materials_displacementmap.html b/examples/webgl_materials_displacementmap.html index 682ab8d84c7fda..5b6c855307a9b4 100644 --- a/examples/webgl_materials_displacementmap.html +++ b/examples/webgl_materials_displacementmap.html @@ -21,7 +21,8 @@ @@ -30,11 +31,11 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { OBJLoader } from './jsm/loaders/OBJLoader.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; let stats; let camera, scene, renderer, controls; diff --git a/examples/webgl_materials_envmaps.html b/examples/webgl_materials_envmaps.html index c0f81f65f02a3d..393d4666d01013 100644 --- a/examples/webgl_materials_envmaps.html +++ b/examples/webgl_materials_envmaps.html @@ -20,7 +20,8 @@ @@ -29,8 +30,8 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let controls, camera, scene, renderer; let textureEquirec, textureCube; @@ -50,11 +51,6 @@ scene = new THREE.Scene(); - // Lights - - const ambient = new THREE.AmbientLight( 0xffffff ); - scene.add( ambient ); - // Textures const loader = new THREE.CubeTextureLoader(); @@ -74,7 +70,7 @@ // const geometry = new THREE.IcosahedronGeometry( 400, 15 ); - sphereMaterial = new THREE.MeshLambertMaterial( { envMap: textureCube } ); + sphereMaterial = new THREE.MeshBasicMaterial( { envMap: textureCube } ); sphereMesh = new THREE.Mesh( geometry, sphereMaterial ); scene.add( sphereMesh ); diff --git a/examples/webgl_materials_envmaps_exr.html b/examples/webgl_materials_envmaps_exr.html index a41a46dc394abe..56b0bd737b5ed4 100644 --- a/examples/webgl_materials_envmaps_exr.html +++ b/examples/webgl_materials_envmaps_exr.html @@ -18,7 +18,8 @@ @@ -27,11 +28,11 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { EXRLoader } from './jsm/loaders/EXRLoader.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { EXRLoader } from 'three/addons/loaders/EXRLoader.js'; const params = { envMap: 'EXR', @@ -61,6 +62,13 @@ scene = new THREE.Scene(); renderer = new THREE.WebGLRenderer(); + renderer.setPixelRatio( window.devicePixelRatio ); + renderer.setSize( window.innerWidth, window.innerHeight ); + + container.appendChild( renderer.domElement ); + + renderer.toneMapping = THREE.ACESFilmicToneMapping; + renderer.outputEncoding = THREE.sRGBEncoding; // @@ -88,39 +96,28 @@ }; - new EXRLoader() - .load( 'textures/piz_compressed.exr', function ( texture ) { + new EXRLoader().load( 'textures/piz_compressed.exr', function ( texture ) { - exrCubeRenderTarget = pmremGenerator.fromEquirectangular( texture ); - exrBackground = exrCubeRenderTarget.texture; + texture.mapping = THREE.EquirectangularReflectionMapping; - texture.dispose(); + exrCubeRenderTarget = pmremGenerator.fromEquirectangular( texture ); + exrBackground = texture; - } ); + } ); new THREE.TextureLoader().load( 'textures/equirectangular.png', function ( texture ) { + texture.mapping = THREE.EquirectangularReflectionMapping; texture.encoding = THREE.sRGBEncoding; pngCubeRenderTarget = pmremGenerator.fromEquirectangular( texture ); - - pngBackground = pngCubeRenderTarget.texture; - - texture.dispose(); + pngBackground = texture; } ); const pmremGenerator = new THREE.PMREMGenerator( renderer ); pmremGenerator.compileEquirectangularShader(); - renderer.setPixelRatio( window.devicePixelRatio ); - renderer.setSize( window.innerWidth, window.innerHeight ); - - container.appendChild( renderer.domElement ); - - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.outputEncoding = THREE.sRGBEncoding; - stats = new Stats(); container.appendChild( stats.dom ); diff --git a/examples/webgl_materials_envmaps_groundprojected.html b/examples/webgl_materials_envmaps_groundprojected.html index f91d087ff20b57..9235a5b73f3558 100644 --- a/examples/webgl_materials_envmaps_groundprojected.html +++ b/examples/webgl_materials_envmaps_groundprojected.html @@ -29,7 +29,8 @@ @@ -37,14 +38,12 @@ @@ -30,13 +31,13 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { HDRCubeTextureLoader } from './jsm/loaders/HDRCubeTextureLoader.js'; - import { RGBMLoader } from './jsm/loaders/RGBMLoader.js'; - import { DebugEnvironment } from './jsm/environments/DebugEnvironment.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { HDRCubeTextureLoader } from 'three/addons/loaders/HDRCubeTextureLoader.js'; + import { RGBMLoader } from 'three/addons/loaders/RGBMLoader.js'; + import { DebugEnvironment } from 'three/addons/environments/DebugEnvironment.js'; const params = { envMap: 'HDR', diff --git a/examples/webgl_materials_lightmap.html b/examples/webgl_materials_lightmap.html index 8169e4728d0fa9..0d7c40b39a0a96 100644 --- a/examples/webgl_materials_lightmap.html +++ b/examples/webgl_materials_lightmap.html @@ -49,7 +49,8 @@ @@ -58,9 +59,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; const SCREEN_WIDTH = window.innerWidth; const SCREEN_HEIGHT = window.innerHeight; diff --git a/examples/webgl_materials_matcap.html b/examples/webgl_materials_matcap.html index 07de9b99191ec0..a71df145a96e73 100644 --- a/examples/webgl_materials_matcap.html +++ b/examples/webgl_materials_matcap.html @@ -10,7 +10,7 @@
    three.js - webgl materials matcap
    - Drag-and-drop JPG, PNG, or EXR MatCap image files
    + Drag-and-drop JPG, PNG, WebP, or EXR MatCap image files
    @@ -20,7 +20,8 @@ @@ -29,10 +30,10 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import { EXRLoader } from './jsm/loaders/EXRLoader.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { EXRLoader } from 'three/addons/loaders/EXRLoader.js'; let mesh, renderer, scene, camera; @@ -168,7 +169,7 @@ } - function handleJPG( event ) { // PNG, too + function handleJPG( event ) { // PNG, WebP, too function imgCallback( event ) { diff --git a/examples/webgl_materials_modified.html b/examples/webgl_materials_modified.html index 4493d7a68f1b01..d3653dfec1c52c 100644 --- a/examples/webgl_materials_modified.html +++ b/examples/webgl_materials_modified.html @@ -20,7 +20,8 @@ @@ -29,10 +30,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; let camera, scene, renderer, stats; diff --git a/examples/webgl_materials_normalmap.html b/examples/webgl_materials_normalmap.html index 4f070fdbcc5f42..e1ffd564f0bab9 100644 --- a/examples/webgl_materials_normalmap.html +++ b/examples/webgl_materials_normalmap.html @@ -20,7 +20,8 @@ @@ -29,16 +30,16 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { ShaderPass } from './jsm/postprocessing/ShaderPass.js'; - import { BleachBypassShader } from './jsm/shaders/BleachBypassShader.js'; - import { ColorCorrectionShader } from './jsm/shaders/ColorCorrectionShader.js'; - import { FXAAShader } from './jsm/shaders/FXAAShader.js'; - import { GammaCorrectionShader } from './jsm/shaders/GammaCorrectionShader.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { BleachBypassShader } from 'three/addons/shaders/BleachBypassShader.js'; + import { ColorCorrectionShader } from 'three/addons/shaders/ColorCorrectionShader.js'; + import { FXAAShader } from 'three/addons/shaders/FXAAShader.js'; + import { GammaCorrectionShader } from 'three/addons/shaders/GammaCorrectionShader.js'; let container, stats, loader; @@ -78,7 +79,7 @@ ambientLight = new THREE.AmbientLight( 0x444444 ); scene.add( ambientLight ); - pointLight = new THREE.PointLight( 0xffffff, 1.25, 1000 ); + pointLight = new THREE.PointLight( 0xffffff, 2, 1000 ); pointLight.position.set( 0, 0, 600 ); scene.add( pointLight ); @@ -142,7 +143,9 @@ effectColor.uniforms[ 'powRGB' ].value.set( 1.4, 1.45, 1.45 ); effectColor.uniforms[ 'mulRGB' ].value.set( 1.1, 1.1, 1.1 ); - composer = new EffectComposer( renderer ); + const renderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, { type: THREE.HalfFloatType, depthTexture: new THREE.DepthTexture() } ); + + composer = new EffectComposer( renderer, renderTarget ); composer.addPass( renderModel ); composer.addPass( effectFXAA ); diff --git a/examples/webgl_materials_normalmap_object_space.html b/examples/webgl_materials_normalmap_object_space.html index e81e3ac9a34817..a04a7b02dd9a73 100644 --- a/examples/webgl_materials_normalmap_object_space.html +++ b/examples/webgl_materials_normalmap_object_space.html @@ -22,7 +22,8 @@ @@ -31,8 +32,8 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; let renderer, scene, camera; diff --git a/examples/webgl_materials_physical_clearcoat.html b/examples/webgl_materials_physical_clearcoat.html index efd6a0641d6c6e..edc318a06718a0 100644 --- a/examples/webgl_materials_physical_clearcoat.html +++ b/examples/webgl_materials_physical_clearcoat.html @@ -18,7 +18,8 @@ @@ -27,12 +28,12 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { HDRCubeTextureLoader } from './jsm/loaders/HDRCubeTextureLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { HDRCubeTextureLoader } from 'three/addons/loaders/HDRCubeTextureLoader.js'; - import { FlakesTexture } from './jsm/textures/FlakesTexture.js'; + import { FlakesTexture } from 'three/addons/textures/FlakesTexture.js'; let container, stats; diff --git a/examples/webgl_materials_physical_reflectivity.html b/examples/webgl_materials_physical_reflectivity.html index 6b2e908c2b5111..bca485595b27fc 100644 --- a/examples/webgl_materials_physical_reflectivity.html +++ b/examples/webgl_materials_physical_reflectivity.html @@ -21,7 +21,8 @@ @@ -30,12 +31,12 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { OBJLoader } from './jsm/loaders/OBJLoader.js'; - import { RGBELoader } from './jsm/loaders/RGBELoader.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; + import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; let container, stats; const params = { diff --git a/examples/webgl_materials_physical_transmission.html b/examples/webgl_materials_physical_transmission.html index f1263d7ddfac42..0d244307400b5a 100644 --- a/examples/webgl_materials_physical_transmission.html +++ b/examples/webgl_materials_physical_transmission.html @@ -18,7 +18,8 @@ @@ -27,9 +28,9 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { RGBELoader } from './jsm/loaders/RGBELoader.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; const params = { color: 0xffffff, diff --git a/examples/webgl_materials_standard.html b/examples/webgl_materials_standard.html index b52802ea70c301..f72c35e2f7958d 100644 --- a/examples/webgl_materials_standard.html +++ b/examples/webgl_materials_standard.html @@ -20,7 +20,8 @@ @@ -29,12 +30,12 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { TrackballControls } from './jsm/controls/TrackballControls.js'; - import { OBJLoader } from './jsm/loaders/OBJLoader.js'; - import { RGBELoader } from './jsm/loaders/RGBELoader.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; + import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; + import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; const statsEnabled = true; diff --git a/examples/webgl_materials_subsurface_scattering.html b/examples/webgl_materials_subsurface_scattering.html index 6f8bb3691255dc..d061d49c54b600 100644 --- a/examples/webgl_materials_subsurface_scattering.html +++ b/examples/webgl_materials_subsurface_scattering.html @@ -21,7 +21,8 @@ @@ -29,12 +30,12 @@ @@ -69,7 +70,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; const SCREEN_WIDTH = window.innerWidth; const SCREEN_HEIGHT = window.innerHeight; diff --git a/examples/webgl_materials_texture_canvas.html b/examples/webgl_materials_texture_canvas.html index f91159ba1c98b3..9aef95689104a2 100755 --- a/examples/webgl_materials_texture_canvas.html +++ b/examples/webgl_materials_texture_canvas.html @@ -32,7 +32,8 @@ diff --git a/examples/webgl_materials_texture_filters.html b/examples/webgl_materials_texture_filters.html index 001290fedc3d35..d77c8ddef25e81 100644 --- a/examples/webgl_materials_texture_filters.html +++ b/examples/webgl_materials_texture_filters.html @@ -50,7 +50,8 @@ @@ -93,15 +94,15 @@ // GROUND - const imageCanvas = document.createElement( "canvas" ); - const context = imageCanvas.getContext( "2d" ); + const imageCanvas = document.createElement( 'canvas' ); + const context = imageCanvas.getContext( '2d' ); imageCanvas.width = imageCanvas.height = 128; - context.fillStyle = "#444"; + context.fillStyle = '#444'; context.fillRect( 0, 0, 128, 128 ); - context.fillStyle = "#fff"; + context.fillStyle = '#fff'; context.fillRect( 0, 0, 64, 64 ); context.fillRect( 64, 64, 64, 64 ); @@ -176,7 +177,7 @@ }; - const texturePainting = new THREE.TextureLoader().load( "textures/758px-Canestra_di_frutta_(Caravaggio).jpg", callbackPainting ); + const texturePainting = new THREE.TextureLoader().load( 'textures/758px-Canestra_di_frutta_(Caravaggio).jpg', callbackPainting ); const texturePainting2 = new THREE.Texture(); const materialPainting = new THREE.MeshBasicMaterial( { color: 0xffffff, map: texturePainting } ); const materialPainting2 = new THREE.MeshBasicMaterial( { color: 0xffccaa, map: texturePainting2 } ); @@ -191,7 +192,7 @@ renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT ); renderer.autoClear = false; - renderer.domElement.style.position = "relative"; + renderer.domElement.style.position = 'relative'; container.appendChild( renderer.domElement ); document.addEventListener( 'mousemove', onDocumentMouseMove ); diff --git a/examples/webgl_materials_texture_manualmipmap.html b/examples/webgl_materials_texture_manualmipmap.html index b090679284714f..6beb9ccf2414d5 100644 --- a/examples/webgl_materials_texture_manualmipmap.html +++ b/examples/webgl_materials_texture_manualmipmap.html @@ -50,7 +50,8 @@ diff --git a/examples/webgl_materials_texture_partialupdate.html b/examples/webgl_materials_texture_partialupdate.html index 5b85fba0b5d1a0..dc0406a1b3a384 100644 --- a/examples/webgl_materials_texture_partialupdate.html +++ b/examples/webgl_materials_texture_partialupdate.html @@ -20,7 +20,8 @@ diff --git a/examples/webgl_materials_texture_rotation.html b/examples/webgl_materials_texture_rotation.html index 63c017240f7dc6..bc599dd2c79b0c 100644 --- a/examples/webgl_materials_texture_rotation.html +++ b/examples/webgl_materials_texture_rotation.html @@ -19,7 +19,8 @@ @@ -28,8 +29,8 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let mesh, renderer, scene, camera; diff --git a/examples/webgl_materials_variations_basic.html b/examples/webgl_materials_variations_basic.html index cbfa9b4e9f1d8e..164d06263c41f0 100644 --- a/examples/webgl_materials_variations_basic.html +++ b/examples/webgl_materials_variations_basic.html @@ -18,7 +18,8 @@ @@ -27,11 +28,11 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { FontLoader } from './jsm/loaders/FontLoader.js'; - import { TextGeometry } from './jsm/geometries/TextGeometry.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { FontLoader } from 'three/addons/loaders/FontLoader.js'; + import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; let container, stats; @@ -66,7 +67,7 @@ // Materials - let imgTexture = new THREE.TextureLoader().load( "textures/planets/moon_1024.jpg" ); + let imgTexture = new THREE.TextureLoader().load( 'textures/planets/moon_1024.jpg' ); imgTexture.wrapS = imgTexture.wrapT = THREE.RepeatWrapping; imgTexture.encoding = THREE.sRGBEncoding; imgTexture.anisotropy = 16; @@ -127,17 +128,17 @@ } - addLabel( "+hue", new THREE.Vector3( - 350, 0, 0 ) ); - addLabel( "-hue", new THREE.Vector3( 350, 0, 0 ) ); + addLabel( '+hue', new THREE.Vector3( - 350, 0, 0 ) ); + addLabel( '-hue', new THREE.Vector3( 350, 0, 0 ) ); - addLabel( "-reflectivity", new THREE.Vector3( 0, - 300, 0 ) ); - addLabel( "+reflectivity", new THREE.Vector3( 0, 300, 0 ) ); + addLabel( '-reflectivity', new THREE.Vector3( 0, - 300, 0 ) ); + addLabel( '+reflectivity', new THREE.Vector3( 0, 300, 0 ) ); - addLabel( "-diffuse", new THREE.Vector3( 0, 0, - 300 ) ); - addLabel( "+diffuse", new THREE.Vector3( 0, 0, 300 ) ); + addLabel( '-diffuse', new THREE.Vector3( 0, 0, - 300 ) ); + addLabel( '+diffuse', new THREE.Vector3( 0, 0, 300 ) ); - addLabel( "envMap", new THREE.Vector3( - 350, 300, 0 ) ); - addLabel( "no envMap", new THREE.Vector3( 350, 300, 0 ) ); + addLabel( 'envMap', new THREE.Vector3( - 350, 300, 0 ) ); + addLabel( 'no envMap', new THREE.Vector3( 350, 300, 0 ) ); particleLight = new THREE.Mesh( new THREE.SphereGeometry( 4, 8, 8 ), new THREE.MeshBasicMaterial( { color: 0xffffff } ) ); scene.add( particleLight ); diff --git a/examples/webgl_materials_variations_lambert.html b/examples/webgl_materials_variations_lambert.html index f41add18479b2d..b341e1ca32de14 100644 --- a/examples/webgl_materials_variations_lambert.html +++ b/examples/webgl_materials_variations_lambert.html @@ -18,7 +18,8 @@ @@ -27,11 +28,11 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { FontLoader } from './jsm/loaders/FontLoader.js'; - import { TextGeometry } from './jsm/geometries/TextGeometry.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { FontLoader } from 'three/addons/loaders/FontLoader.js'; + import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; let container, stats; diff --git a/examples/webgl_materials_variations_phong.html b/examples/webgl_materials_variations_phong.html index dd9fc242c8517a..c49b6f336f48c2 100644 --- a/examples/webgl_materials_variations_phong.html +++ b/examples/webgl_materials_variations_phong.html @@ -18,7 +18,8 @@ @@ -27,11 +28,11 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { FontLoader } from './jsm/loaders/FontLoader.js'; - import { TextGeometry } from './jsm/geometries/TextGeometry.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { FontLoader } from 'three/addons/loaders/FontLoader.js'; + import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; let container, stats; diff --git a/examples/webgl_materials_variations_physical.html b/examples/webgl_materials_variations_physical.html index 9e9b7d22636798..24dd9deff19650 100644 --- a/examples/webgl_materials_variations_physical.html +++ b/examples/webgl_materials_variations_physical.html @@ -19,7 +19,8 @@ @@ -28,12 +29,12 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { RGBELoader } from './jsm/loaders/RGBELoader.js'; - import { FontLoader } from './jsm/loaders/FontLoader.js'; - import { TextGeometry } from './jsm/geometries/TextGeometry.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; + import { FontLoader } from 'three/addons/loaders/FontLoader.js'; + import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; let container, stats; diff --git a/examples/webgl_materials_variations_standard.html b/examples/webgl_materials_variations_standard.html index 72dc2870568b84..c1ce3fdf5f7cf1 100644 --- a/examples/webgl_materials_variations_standard.html +++ b/examples/webgl_materials_variations_standard.html @@ -19,7 +19,8 @@ @@ -28,12 +29,12 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { RGBELoader } from './jsm/loaders/RGBELoader.js'; - import { FontLoader } from './jsm/loaders/FontLoader.js'; - import { TextGeometry } from './jsm/geometries/TextGeometry.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; + import { FontLoader } from 'three/addons/loaders/FontLoader.js'; + import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; let container, stats; diff --git a/examples/webgl_materials_variations_toon.html b/examples/webgl_materials_variations_toon.html index 94379d27592d41..09c3566b664c4e 100644 --- a/examples/webgl_materials_variations_toon.html +++ b/examples/webgl_materials_variations_toon.html @@ -18,7 +18,8 @@ @@ -27,12 +28,12 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { OutlineEffect } from './jsm/effects/OutlineEffect.js'; - import { FontLoader } from './jsm/loaders/FontLoader.js'; - import { TextGeometry } from './jsm/geometries/TextGeometry.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { OutlineEffect } from 'three/addons/effects/OutlineEffect.js'; + import { FontLoader } from 'three/addons/loaders/FontLoader.js'; + import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; let container, stats; @@ -136,11 +137,11 @@ } - addLabel( "-gradientMap", new THREE.Vector3( - 350, 0, 0 ) ); - addLabel( "+gradientMap", new THREE.Vector3( 350, 0, 0 ) ); + addLabel( '-gradientMap', new THREE.Vector3( - 350, 0, 0 ) ); + addLabel( '+gradientMap', new THREE.Vector3( 350, 0, 0 ) ); - addLabel( "-diffuse", new THREE.Vector3( 0, 0, - 300 ) ); - addLabel( "+diffuse", new THREE.Vector3( 0, 0, 300 ) ); + addLabel( '-diffuse', new THREE.Vector3( 0, 0, - 300 ) ); + addLabel( '+diffuse', new THREE.Vector3( 0, 0, 300 ) ); particleLight = new THREE.Mesh( new THREE.SphereGeometry( 4, 8, 8 ), diff --git a/examples/webgl_materials_video.html b/examples/webgl_materials_video.html index b2c91156c307e4..7cd5380ea6b553 100644 --- a/examples/webgl_materials_video.html +++ b/examples/webgl_materials_video.html @@ -30,7 +30,8 @@ @@ -39,11 +40,11 @@ import * as THREE from 'three'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { ShaderPass } from './jsm/postprocessing/ShaderPass.js'; - import { BloomPass } from './jsm/postprocessing/BloomPass.js'; - import { CopyShader } from './jsm/shaders/CopyShader.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { BloomPass } from 'three/addons/postprocessing/BloomPass.js'; + import { CopyShader } from 'three/addons/shaders/CopyShader.js'; let container; diff --git a/examples/webgl_materials_video_webcam.html b/examples/webgl_materials_video_webcam.html index f9a9808e37bec1..e6ccaefb7ed238 100644 --- a/examples/webgl_materials_video_webcam.html +++ b/examples/webgl_materials_video_webcam.html @@ -21,7 +21,8 @@ @@ -30,7 +31,7 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let camera, scene, renderer, video; diff --git a/examples/webgl_materials_wireframe.html b/examples/webgl_materials_wireframe.html index ff28eb310a0dcf..039ce04cfa3f2f 100644 --- a/examples/webgl_materials_wireframe.html +++ b/examples/webgl_materials_wireframe.html @@ -54,7 +54,8 @@ @@ -63,9 +64,9 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; const API = { thickness: 1 @@ -88,6 +89,7 @@ camera.position.z = 200; const controls = new OrbitControls( camera, renderer.domElement ); + controls.addEventListener( 'change', render ); // use if there is no animation loop controls.enablePan = false; controls.enableZoom = false; @@ -132,7 +134,7 @@ // - animate(); + render(); } ); @@ -143,6 +145,7 @@ gui.add( API, 'thickness', 0, 4 ).onChange( function () { mesh2.material.uniforms.thickness.value = API.thickness; + render(); } ); @@ -184,9 +187,7 @@ } - function animate() { - - requestAnimationFrame( animate ); + function render() { renderer.render( scene, camera ); diff --git a/examples/webgl_math_obb.html b/examples/webgl_math_obb.html index 82c6d88332c990..abb63fe260cbbe 100644 --- a/examples/webgl_math_obb.html +++ b/examples/webgl_math_obb.html @@ -28,7 +28,8 @@ @@ -37,10 +38,10 @@ import * as THREE from 'three'; - import { OBB } from './jsm/math/OBB.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OBB } from 'three/addons/math/OBB.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let camera, scene, renderer, clock, controls, stats, raycaster, hitbox; diff --git a/examples/webgl_math_orientation_transform.html b/examples/webgl_math_orientation_transform.html index 327a6b72cafc6e..ac6c08479f7045 100644 --- a/examples/webgl_math_orientation_transform.html +++ b/examples/webgl_math_orientation_transform.html @@ -20,7 +20,8 @@ diff --git a/examples/webgl_mirror.html b/examples/webgl_mirror.html index 62af5fc3107f25..f95bb3a6c146f6 100644 --- a/examples/webgl_mirror.html +++ b/examples/webgl_mirror.html @@ -27,7 +27,8 @@ @@ -36,8 +37,8 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { Reflector } from './jsm/objects/Reflector.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { Reflector } from 'three/addons/objects/Reflector.js'; let camera, scene, renderer; diff --git a/examples/webgl_modifier_curve.html b/examples/webgl_modifier_curve.html index 77638edecb35f8..61545e0f2e3b77 100644 --- a/examples/webgl_modifier_curve.html +++ b/examples/webgl_modifier_curve.html @@ -21,18 +21,19 @@ @@ -24,12 +25,12 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { OBJLoader } from './jsm/loaders/OBJLoader.js'; - import { EdgeSplitModifier } from './jsm/modifiers/EdgeSplitModifier.js'; - import * as BufferGeometryUtils from './jsm/utils/BufferGeometryUtils.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; + import { EdgeSplitModifier } from 'three/addons/modifiers/EdgeSplitModifier.js'; + import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let renderer, scene, camera; let modifier, mesh, baseGeometry; diff --git a/examples/webgl_modifier_simplifier.html b/examples/webgl_modifier_simplifier.html index d50653a9ea501a..a8f0a02b67fc0a 100644 --- a/examples/webgl_modifier_simplifier.html +++ b/examples/webgl_modifier_simplifier.html @@ -15,7 +15,8 @@ @@ -24,9 +25,9 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import { SimplifyModifier } from './jsm/modifiers/SimplifyModifier.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { SimplifyModifier } from 'three/addons/modifiers/SimplifyModifier.js'; let renderer, scene, camera; diff --git a/examples/webgl_modifier_subdivision.html b/examples/webgl_modifier_subdivision.html new file mode 100644 index 00000000000000..87f6bf28d849a2 --- /dev/null +++ b/examples/webgl_modifier_subdivision.html @@ -0,0 +1,330 @@ + + + + three.js webgl - modifier - subdivision + + + + + + +
    + three.js webgl - modifier - subdivision
    + See external three-subdivide for more information on subdivision surfaces. +
    + + + + + + + + + + + \ No newline at end of file diff --git a/examples/webgl_modifier_tessellation.html b/examples/webgl_modifier_tessellation.html index a3069706ab5bf8..8bd20dec1ab5af 100644 --- a/examples/webgl_modifier_tessellation.html +++ b/examples/webgl_modifier_tessellation.html @@ -60,7 +60,8 @@ @@ -69,12 +70,12 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { TrackballControls } from './jsm/controls/TrackballControls.js'; - import { TessellateModifier } from './jsm/modifiers/TessellateModifier.js'; - import { FontLoader } from './jsm/loaders/FontLoader.js'; - import { TextGeometry } from './jsm/geometries/TextGeometry.js'; + import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; + import { TessellateModifier } from 'three/addons/modifiers/TessellateModifier.js'; + import { FontLoader } from 'three/addons/loaders/FontLoader.js'; + import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; let renderer, scene, camera, stats; diff --git a/examples/webgl_morphtargets.html b/examples/webgl_morphtargets.html index 1bb7b5fc531fa9..d91a74b1c23d27 100644 --- a/examples/webgl_morphtargets.html +++ b/examples/webgl_morphtargets.html @@ -21,7 +21,8 @@ @@ -30,8 +31,8 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let container, camera, scene, renderer, mesh; diff --git a/examples/webgl_morphtargets_face.html b/examples/webgl_morphtargets_face.html index d19070c23582a0..6c77bee0da612a 100644 --- a/examples/webgl_morphtargets_face.html +++ b/examples/webgl_morphtargets_face.html @@ -25,7 +25,8 @@ @@ -34,17 +35,17 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import { KTX2Loader } from './jsm/loaders/KTX2Loader.js'; - import { MeshoptDecoder } from './jsm/libs/meshopt_decoder.module.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; + import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js'; - import { RoomEnvironment } from './jsm/environments/RoomEnvironment.js'; + import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; init(); diff --git a/examples/webgl_morphtargets_horse.html b/examples/webgl_morphtargets_horse.html index 4608ed92cd8849..1ea8976373358e 100644 --- a/examples/webgl_morphtargets_horse.html +++ b/examples/webgl_morphtargets_horse.html @@ -29,7 +29,8 @@ @@ -38,9 +39,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; let container, stats; let camera, scene, renderer; diff --git a/examples/webgl_morphtargets_sphere.html b/examples/webgl_morphtargets_sphere.html index bdc83c91e6582e..8b51a1d31ebb1a 100644 --- a/examples/webgl_morphtargets_sphere.html +++ b/examples/webgl_morphtargets_sphere.html @@ -20,7 +20,8 @@ @@ -29,8 +30,8 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; let camera, scene, renderer, clock; diff --git a/examples/webgl_multiple_canvases_circle.html b/examples/webgl_multiple_canvases_circle.html index f1389487bed643..8a7c8b296d5519 100644 --- a/examples/webgl_multiple_canvases_circle.html +++ b/examples/webgl_multiple_canvases_circle.html @@ -138,7 +138,8 @@ diff --git a/examples/webgl_multiple_canvases_complex.html b/examples/webgl_multiple_canvases_complex.html index a0ce1492659fc9..1004c0edfc3aaf 100644 --- a/examples/webgl_multiple_canvases_complex.html +++ b/examples/webgl_multiple_canvases_complex.html @@ -55,7 +55,8 @@ diff --git a/examples/webgl_multiple_canvases_grid.html b/examples/webgl_multiple_canvases_grid.html index 2b929edb4cffc2..7eea712e2da57f 100644 --- a/examples/webgl_multiple_canvases_grid.html +++ b/examples/webgl_multiple_canvases_grid.html @@ -72,7 +72,8 @@ diff --git a/examples/webgl_multiple_elements.html b/examples/webgl_multiple_elements.html index 23dd678769296c..12febc1fc86a98 100644 --- a/examples/webgl_multiple_elements.html +++ b/examples/webgl_multiple_elements.html @@ -70,7 +70,8 @@ @@ -79,7 +80,7 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let canvas, renderer; @@ -90,7 +91,7 @@ function init() { - canvas = document.getElementById( "c" ); + canvas = document.getElementById( 'c' ); const geometries = [ new THREE.BoxGeometry( 1, 1, 1 ), diff --git a/examples/webgl_multiple_elements_text.html b/examples/webgl_multiple_elements_text.html index 6651c0428f4d60..e75191d9cc9861 100644 --- a/examples/webgl_multiple_elements_text.html +++ b/examples/webgl_multiple_elements_text.html @@ -86,7 +86,8 @@ @@ -95,10 +96,12 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; const scenes = []; + const clock = new THREE.Clock(); + let views, t, canvas, renderer; window.onload = init; @@ -274,7 +277,7 @@ } ); - t ++; + t += clock.getDelta() * 60; } diff --git a/examples/webgl_multiple_renderers.html b/examples/webgl_multiple_renderers.html index 0a533539577187..ad658b566b7fc2 100644 --- a/examples/webgl_multiple_renderers.html +++ b/examples/webgl_multiple_renderers.html @@ -26,7 +26,8 @@ diff --git a/examples/webgl_multiple_scenes_comparison.html b/examples/webgl_multiple_scenes_comparison.html index 057f715dd91a94..07830aeefa2acf 100644 --- a/examples/webgl_multiple_scenes_comparison.html +++ b/examples/webgl_multiple_scenes_comparison.html @@ -45,7 +45,8 @@ @@ -54,7 +55,7 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let container, camera, renderer, controls; let sceneL, sceneR; @@ -139,7 +140,7 @@ sliderPos = Math.max( 0, Math.min( window.innerWidth, e.pageX ) ); - slider.style.left = sliderPos - ( slider.offsetWidth / 2 ) + "px"; + slider.style.left = sliderPos - ( slider.offsetWidth / 2 ) + 'px'; } diff --git a/examples/webgl_multiple_views.html b/examples/webgl_multiple_views.html index e029e2ad059c51..c596b88af59d73 100644 --- a/examples/webgl_multiple_views.html +++ b/examples/webgl_multiple_views.html @@ -18,7 +18,8 @@ @@ -27,7 +28,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let stats; diff --git a/examples/webgl_nodes_loader_gltf_iridescence.html b/examples/webgl_nodes_loader_gltf_iridescence.html new file mode 100644 index 00000000000000..48d63c648fb537 --- /dev/null +++ b/examples/webgl_nodes_loader_gltf_iridescence.html @@ -0,0 +1,138 @@ + + + + three.js webgl - GLTFloader + Iridescence + Nodes + + + + + + +
    + three.js - GLTFLoader + KHR_materials_iridescence + Nodes
    + Iridescence Lamp from glTF-Sample-Models
    + Venice Sunset by HDRI Haven +
    + + + + + + + + + + + diff --git a/examples/webgl_nodes_loader_gltf_sheen.html b/examples/webgl_nodes_loader_gltf_sheen.html index a94cba97196f7f..b5e50e20bce0e5 100644 --- a/examples/webgl_nodes_loader_gltf_sheen.html +++ b/examples/webgl_nodes_loader_gltf_sheen.html @@ -26,7 +26,8 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } @@ -35,13 +36,13 @@ import * as THREE from 'three'; - import { NodeMaterial, color, uv, mix, mul, checker } from 'three-nodes/Nodes.js'; + import { NodeMaterial, color, uv, mix, mul, checker } from 'three/nodes'; - import { nodeFrame } from './jsm/renderers/webgl/nodes/WebGLNodes.js'; + import { nodeFrame } from 'three/addons/renderers/webgl/nodes/WebGLNodes.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import { RoomEnvironment } from './jsm/environments/RoomEnvironment.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; let camera, scene, renderer, controls; @@ -66,18 +67,6 @@ scene.add( gltf.scene ); - const object = gltf.scene.getObjectByName( 'SheenChair_fabric' ); - - // Convert to NodeMaterial - const material = NodeMaterial.fromMaterial( object.material ); - - const checkerNode = checker( mul( uv(), 5 ) ); - - material.sheenNode = mix( color( 0x00ffff ), color( 0xffff00 ), checkerNode ); - material.sheenRoughnessNode = checkerNode; - - object.material = material; - } ); renderer = new THREE.WebGLRenderer( { antialias: true } ); diff --git a/examples/webgl_nodes_loader_gltf_transmission.html b/examples/webgl_nodes_loader_gltf_transmission.html new file mode 100644 index 00000000000000..8049dd50695fcb --- /dev/null +++ b/examples/webgl_nodes_loader_gltf_transmission.html @@ -0,0 +1,162 @@ + + + + three.js webgl - GLTFloader + transmission + nodes + + + + + + +
    + three.js - GLTFLoader + KHR_materials_transmission + Nodes
    + Iridescent Dish With Olives by Eric Chadwick
    + Royal Esplanade by HDRI Haven +
    + + + + + + + + + + + diff --git a/examples/webgl_nodes_loader_materialx.html b/examples/webgl_nodes_loader_materialx.html new file mode 100644 index 00000000000000..4839c99203afef --- /dev/null +++ b/examples/webgl_nodes_loader_materialx.html @@ -0,0 +1,195 @@ + + + + three.js webgl - MaterialX loader + + + + + + + +
    + three.js - MaterialXLoader
    +
    + + + + + + + + + + + diff --git a/examples/webgl_nodes_materials_instance_uniform.html b/examples/webgl_nodes_materials_instance_uniform.html index 9f9d58438c4fb0..769f0b78c6c088 100644 --- a/examples/webgl_nodes_materials_instance_uniform.html +++ b/examples/webgl_nodes_materials_instance_uniform.html @@ -19,7 +19,8 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } @@ -27,24 +28,23 @@ @@ -27,18 +28,18 @@ @@ -29,16 +30,16 @@ + + + + + + diff --git a/examples/webgl_nodes_playground.html b/examples/webgl_nodes_playground.html index 182e71c6b38e14..a0b4fb3d59aaae 100644 --- a/examples/webgl_nodes_playground.html +++ b/examples/webgl_nodes_playground.html @@ -1,7 +1,7 @@ - - three.js webgl - node-editor playground + + three.js webgl - node playground @@ -17,193 +17,202 @@ position: absolute; top: 0; left: 0; - height: 50%; + height: 100%; width: 100%; } flow { position: absolute; - top: 50%; + top: 0; left: 0; - height: 50%; + height: 100%; width: 100%; - background: #222; box-shadow: inset 0 0 20px 0px #000000; + pointer-events: none; + } + flow f-canvas { + pointer-events: auto; + } + flow f-canvas:not(.focusing) { + background: #191919ed; } - - - -
    - three.js - WebGL - Node Editor ( Playground version )
    -
    - - - - + + + - + - + diff --git a/examples/webgl_nodes_points.html b/examples/webgl_nodes_points.html index 7dbec8794cc449..be1cdd3686c094 100644 --- a/examples/webgl_nodes_points.html +++ b/examples/webgl_nodes_points.html @@ -20,7 +20,8 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } @@ -28,17 +29,17 @@ @@ -28,7 +29,7 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let camera, controls; let renderer; diff --git a/examples/webgl_panorama_equirectangular.html b/examples/webgl_panorama_equirectangular.html index de9b12d3c8d24f..18afc8eeed100e 100644 --- a/examples/webgl_panorama_equirectangular.html +++ b/examples/webgl_panorama_equirectangular.html @@ -21,7 +21,8 @@ diff --git a/examples/webgl_performance.html b/examples/webgl_performance.html index ce0aa6cf31177b..539f31a634e4b7 100644 --- a/examples/webgl_performance.html +++ b/examples/webgl_performance.html @@ -20,7 +20,8 @@ @@ -29,7 +30,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let stats; diff --git a/examples/webgl_performance_shader.html b/examples/webgl_performance_shader.html index e552e99517fa8f..4913b4542ecf35 100644 --- a/examples/webgl_performance_shader.html +++ b/examples/webgl_performance_shader.html @@ -81,7 +81,8 @@ @@ -89,7 +90,7 @@ @@ -29,7 +30,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let stats; diff --git a/examples/webgl_pmrem_test.html b/examples/webgl_pmrem_test.html index 0532b46f894370..fac8cc025a3fcc 100644 --- a/examples/webgl_pmrem_test.html +++ b/examples/webgl_pmrem_test.html @@ -26,7 +26,8 @@ @@ -35,10 +36,10 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { RGBELoader } from './jsm/loaders/RGBELoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let scene, camera, controls, renderer; diff --git a/examples/webgl_points_billboards.html b/examples/webgl_points_billboards.html index 44c7017d88f0f9..86e6d05b935e42 100644 --- a/examples/webgl_points_billboards.html +++ b/examples/webgl_points_billboards.html @@ -19,7 +19,8 @@ @@ -28,9 +29,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let camera, scene, renderer, stats, material; let mouseX = 0, mouseY = 0; diff --git a/examples/webgl_points_dynamic.html b/examples/webgl_points_dynamic.html index 6b93d49cecbfbf..96ff641a8c0c2f 100644 --- a/examples/webgl_points_dynamic.html +++ b/examples/webgl_points_dynamic.html @@ -22,7 +22,8 @@ @@ -31,15 +32,15 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { ShaderPass } from './jsm/postprocessing/ShaderPass.js'; - import { BloomPass } from './jsm/postprocessing/BloomPass.js'; - import { FilmPass } from './jsm/postprocessing/FilmPass.js'; - import { FocusShader } from './jsm/shaders/FocusShader.js'; - import { OBJLoader } from './jsm/loaders/OBJLoader.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { BloomPass } from 'three/addons/postprocessing/BloomPass.js'; + import { FilmPass } from 'three/addons/postprocessing/FilmPass.js'; + import { FocusShader } from 'three/addons/shaders/FocusShader.js'; + import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; let camera, scene, renderer, mesh; @@ -117,8 +118,8 @@ effectFocus = new ShaderPass( FocusShader ); - effectFocus.uniforms[ "screenWidth" ].value = window.innerWidth * window.devicePixelRatio; - effectFocus.uniforms[ "screenHeight" ].value = window.innerHeight * window.devicePixelRatio; + effectFocus.uniforms[ 'screenWidth' ].value = window.innerWidth * window.devicePixelRatio; + effectFocus.uniforms[ 'screenHeight' ].value = window.innerHeight * window.devicePixelRatio; composer = new EffectComposer( renderer ); @@ -146,8 +147,8 @@ renderer.setSize( window.innerWidth, window.innerHeight ); composer.setSize( window.innerWidth, window.innerHeight ); - effectFocus.uniforms[ "screenWidth" ].value = window.innerWidth * window.devicePixelRatio; - effectFocus.uniforms[ "screenHeight" ].value = window.innerHeight * window.devicePixelRatio; + effectFocus.uniforms[ 'screenWidth' ].value = window.innerWidth * window.devicePixelRatio; + effectFocus.uniforms[ 'screenHeight' ].value = window.innerHeight * window.devicePixelRatio; } diff --git a/examples/webgl_points_sprites.html b/examples/webgl_points_sprites.html index 48e4eee659bba6..79559354869554 100644 --- a/examples/webgl_points_sprites.html +++ b/examples/webgl_points_sprites.html @@ -20,7 +20,8 @@ @@ -29,9 +30,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let camera, scene, renderer, stats, parameters; let mouseX = 0, mouseY = 0; diff --git a/examples/webgl_points_waves.html b/examples/webgl_points_waves.html index 76ebf6c67d9970..eb66550a7f2d48 100644 --- a/examples/webgl_points_waves.html +++ b/examples/webgl_points_waves.html @@ -49,7 +49,8 @@ @@ -58,7 +59,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; const SEPARATION = 100, AMOUNTX = 50, AMOUNTY = 50; diff --git a/examples/webgl_portal.html b/examples/webgl_portal.html index f91123be7685d4..b28063a1ea9565 100644 --- a/examples/webgl_portal.html +++ b/examples/webgl_portal.html @@ -27,7 +27,8 @@ @@ -36,8 +37,8 @@ import * as THREE from 'three'; - import * as CameraUtils from './jsm/utils/CameraUtils.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import * as CameraUtils from 'three/addons/utils/CameraUtils.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let camera, scene, renderer; diff --git a/examples/webgl_postprocessing.html b/examples/webgl_postprocessing.html index 6b2fe51444262c..67d276c96bbc19 100644 --- a/examples/webgl_postprocessing.html +++ b/examples/webgl_postprocessing.html @@ -15,7 +15,8 @@ @@ -24,12 +25,12 @@ import * as THREE from 'three'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { ShaderPass } from './jsm/postprocessing/ShaderPass.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; - import { RGBShiftShader } from './jsm/shaders/RGBShiftShader.js'; - import { DotScreenShader } from './jsm/shaders/DotScreenShader.js'; + import { RGBShiftShader } from 'three/addons/shaders/RGBShiftShader.js'; + import { DotScreenShader } from 'three/addons/shaders/DotScreenShader.js'; let camera, renderer, composer; let object; diff --git a/examples/webgl_postprocessing_3dlut.html b/examples/webgl_postprocessing_3dlut.html index 37741bce73c4a0..b38b17ba9f6930 100644 --- a/examples/webgl_postprocessing_3dlut.html +++ b/examples/webgl_postprocessing_3dlut.html @@ -23,7 +23,8 @@ @@ -31,17 +32,17 @@ @@ -31,26 +32,26 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { ShaderPass } from './jsm/postprocessing/ShaderPass.js'; - import { BloomPass } from './jsm/postprocessing/BloomPass.js'; - import { FilmPass } from './jsm/postprocessing/FilmPass.js'; - import { DotScreenPass } from './jsm/postprocessing/DotScreenPass.js'; - import { MaskPass, ClearMaskPass } from './jsm/postprocessing/MaskPass.js'; - import { TexturePass } from './jsm/postprocessing/TexturePass.js'; - - import { BleachBypassShader } from './jsm/shaders/BleachBypassShader.js'; - import { ColorifyShader } from './jsm/shaders/ColorifyShader.js'; - import { HorizontalBlurShader } from './jsm/shaders/HorizontalBlurShader.js'; - import { VerticalBlurShader } from './jsm/shaders/VerticalBlurShader.js'; - import { SepiaShader } from './jsm/shaders/SepiaShader.js'; - import { VignetteShader } from './jsm/shaders/VignetteShader.js'; - import { GammaCorrectionShader } from './jsm/shaders/GammaCorrectionShader.js'; - - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; + import Stats from 'three/addons/libs/stats.module.js'; + + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { BloomPass } from 'three/addons/postprocessing/BloomPass.js'; + import { FilmPass } from 'three/addons/postprocessing/FilmPass.js'; + import { DotScreenPass } from 'three/addons/postprocessing/DotScreenPass.js'; + import { MaskPass, ClearMaskPass } from 'three/addons/postprocessing/MaskPass.js'; + import { TexturePass } from 'three/addons/postprocessing/TexturePass.js'; + + import { BleachBypassShader } from 'three/addons/shaders/BleachBypassShader.js'; + import { ColorifyShader } from 'three/addons/shaders/ColorifyShader.js'; + import { HorizontalBlurShader } from 'three/addons/shaders/HorizontalBlurShader.js'; + import { VerticalBlurShader } from 'three/addons/shaders/VerticalBlurShader.js'; + import { SepiaShader } from 'three/addons/shaders/SepiaShader.js'; + import { VignetteShader } from 'three/addons/shaders/VignetteShader.js'; + import { GammaCorrectionShader } from 'three/addons/shaders/GammaCorrectionShader.js'; + + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; let container, stats; diff --git a/examples/webgl_postprocessing_afterimage.html b/examples/webgl_postprocessing_afterimage.html index 04cc43d51a63ae..dc712351750693 100644 --- a/examples/webgl_postprocessing_afterimage.html +++ b/examples/webgl_postprocessing_afterimage.html @@ -15,7 +15,8 @@ @@ -24,11 +25,11 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { AfterimagePass } from './jsm/postprocessing/AfterimagePass.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { AfterimagePass } from 'three/addons/postprocessing/AfterimagePass.js'; let camera, scene, renderer, composer; let mesh; @@ -75,17 +76,17 @@ if ( typeof TESTING !== 'undefined' ) { - for ( let i = 0; i < 45; i ++ ) { + for ( let i = 0; i < 45; i ++ ) { - render(); + render(); - } + } - } + } -} + } function createGUI() { diff --git a/examples/webgl_postprocessing_backgrounds.html b/examples/webgl_postprocessing_backgrounds.html index c6f8f13031f351..d49457f1998d3c 100644 --- a/examples/webgl_postprocessing_backgrounds.html +++ b/examples/webgl_postprocessing_backgrounds.html @@ -21,7 +21,8 @@ @@ -30,17 +31,17 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { TexturePass } from './jsm/postprocessing/TexturePass.js'; - import { CubeTexturePass } from './jsm/postprocessing/CubeTexturePass.js'; - import { ShaderPass } from './jsm/postprocessing/ShaderPass.js'; - import { ClearPass } from './jsm/postprocessing/ClearPass.js'; - import { CopyShader } from './jsm/shaders/CopyShader.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import Stats from 'three/addons/libs/stats.module.js'; + + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { TexturePass } from 'three/addons/postprocessing/TexturePass.js'; + import { CubeTexturePass } from 'three/addons/postprocessing/CubeTexturePass.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { ClearPass } from 'three/addons/postprocessing/ClearPass.js'; + import { CopyShader } from 'three/addons/shaders/CopyShader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let scene, renderer, composer; let clearPass, texturePass, renderPass; diff --git a/examples/webgl_postprocessing_crossfade.html b/examples/webgl_postprocessing_crossfade.html index d28a2986cfc2b5..4a652b7f63e3bc 100644 --- a/examples/webgl_postprocessing_crossfade.html +++ b/examples/webgl_postprocessing_crossfade.html @@ -22,7 +22,8 @@ @@ -31,9 +32,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { TWEEN } from './jsm/libs/tween.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { TWEEN } from 'three/addons/libs/tween.module.min.js'; let container, stats; let renderer; diff --git a/examples/webgl_postprocessing_dof.html b/examples/webgl_postprocessing_dof.html index 0076db278062d6..c073ff2571ed80 100644 --- a/examples/webgl_postprocessing_dof.html +++ b/examples/webgl_postprocessing_dof.html @@ -20,7 +20,8 @@ @@ -29,12 +30,12 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { BokehPass } from './jsm/postprocessing/BokehPass.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { BokehPass } from 'three/addons/postprocessing/BokehPass.js'; let camera, scene, renderer, stats, singleMaterial, zmaterial, @@ -206,10 +207,7 @@ const bokehPass = new BokehPass( scene, camera, { focus: 1.0, aperture: 0.025, - maxblur: 0.01, - - width: width, - height: height + maxblur: 0.01 } ); const composer = new EffectComposer( renderer ); diff --git a/examples/webgl_postprocessing_dof2.html b/examples/webgl_postprocessing_dof2.html index 3b4ac4b6bfaaa5..c2a1f38644bec8 100644 --- a/examples/webgl_postprocessing_dof2.html +++ b/examples/webgl_postprocessing_dof2.html @@ -19,7 +19,8 @@ @@ -28,10 +29,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { BokehShader, BokehDepthShader } from './jsm/shaders/BokehShader2.js'; + import { BokehShader, BokehDepthShader } from 'three/addons/shaders/BokehShader2.js'; let container, stats; let camera, scene, renderer, materialDepth; diff --git a/examples/webgl_postprocessing_fxaa.html b/examples/webgl_postprocessing_fxaa.html index 97539bf541109d..33d0d5eee5dbdc 100644 --- a/examples/webgl_postprocessing_fxaa.html +++ b/examples/webgl_postprocessing_fxaa.html @@ -40,7 +40,8 @@ @@ -49,11 +50,11 @@ import * as THREE from 'three'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { ShaderPass } from './jsm/postprocessing/ShaderPass.js'; - import { CopyShader } from './jsm/shaders/CopyShader.js'; - import { FXAAShader } from './jsm/shaders/FXAAShader.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { CopyShader } from 'three/addons/shaders/CopyShader.js'; + import { FXAAShader } from 'three/addons/shaders/FXAAShader.js'; let camera, scene, renderer, clock, group, container; diff --git a/examples/webgl_postprocessing_glitch.html b/examples/webgl_postprocessing_glitch.html index b027bf36b884e6..29883964c65913 100644 --- a/examples/webgl_postprocessing_glitch.html +++ b/examples/webgl_postprocessing_glitch.html @@ -27,7 +27,8 @@

    WARNING

    @@ -36,9 +37,9 @@

    WARNING

    import * as THREE from 'three'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { GlitchPass } from './jsm/postprocessing/GlitchPass.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { GlitchPass } from 'three/addons/postprocessing/GlitchPass.js'; let camera, scene, renderer, composer; let object, light; diff --git a/examples/webgl_postprocessing_godrays.html b/examples/webgl_postprocessing_godrays.html index c85743e9b3e1b7..8c2a982c2509ea 100644 --- a/examples/webgl_postprocessing_godrays.html +++ b/examples/webgl_postprocessing_godrays.html @@ -19,7 +19,8 @@ @@ -28,11 +29,11 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OBJLoader } from './jsm/loaders/OBJLoader.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GodRaysFakeSunShader, GodRaysDepthMaskShader, GodRaysCombineShader, GodRaysGenerateShader } from './jsm/shaders/GodRaysShader.js'; + import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GodRaysFakeSunShader, GodRaysDepthMaskShader, GodRaysCombineShader, GodRaysGenerateShader } from 'three/addons/shaders/GodRaysShader.js'; let container, stats; let camera, scene, renderer, materialDepth; diff --git a/examples/webgl_postprocessing_masking.html b/examples/webgl_postprocessing_masking.html index dcdc2de0515c43..fa7195a12a4a5a 100644 --- a/examples/webgl_postprocessing_masking.html +++ b/examples/webgl_postprocessing_masking.html @@ -17,7 +17,8 @@ @@ -26,12 +27,12 @@ import * as THREE from 'three'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { ShaderPass } from './jsm/postprocessing/ShaderPass.js'; - import { TexturePass } from './jsm/postprocessing/TexturePass.js'; - import { ClearPass } from './jsm/postprocessing/ClearPass.js'; - import { MaskPass, ClearMaskPass } from './jsm/postprocessing/MaskPass.js'; - import { CopyShader } from './jsm/shaders/CopyShader.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { TexturePass } from 'three/addons/postprocessing/TexturePass.js'; + import { ClearPass } from 'three/addons/postprocessing/ClearPass.js'; + import { MaskPass, ClearMaskPass } from 'three/addons/postprocessing/MaskPass.js'; + import { CopyShader } from 'three/addons/shaders/CopyShader.js'; let camera, composer, renderer; let box, torus; diff --git a/examples/webgl_postprocessing_outline.html b/examples/webgl_postprocessing_outline.html index 4409c577ea385e..9756f09665db67 100644 --- a/examples/webgl_postprocessing_outline.html +++ b/examples/webgl_postprocessing_outline.html @@ -18,7 +18,8 @@ @@ -27,16 +28,16 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { OBJLoader } from './jsm/loaders/OBJLoader.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { ShaderPass } from './jsm/postprocessing/ShaderPass.js'; - import { OutlinePass } from './jsm/postprocessing/OutlinePass.js'; - import { FXAAShader } from './jsm/shaders/FXAAShader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { OutlinePass } from 'three/addons/postprocessing/OutlinePass.js'; + import { FXAAShader } from 'three/addons/shaders/FXAAShader.js'; let container, stats; let camera, scene, renderer, controls; diff --git a/examples/webgl_postprocessing_pixel.html b/examples/webgl_postprocessing_pixel.html index a0a03dea476684..b7550e9eaaf9ad 100644 --- a/examples/webgl_postprocessing_pixel.html +++ b/examples/webgl_postprocessing_pixel.html @@ -1,179 +1,226 @@ - - three.js webgl - postprocessing - pixel shader - - - - - - -
    - -
    - three.js - pixel shader by wongbryan -
    - - - - - - + + + } + - + - - diff --git a/examples/webgl_postprocessing_procedural.html b/examples/webgl_postprocessing_procedural.html index 964c6eb1475218..75dde7b4843b46 100644 --- a/examples/webgl_postprocessing_procedural.html +++ b/examples/webgl_postprocessing_procedural.html @@ -61,7 +61,8 @@ @@ -70,8 +71,8 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let postCamera, postScene, renderer; let postMaterial, noiseRandom1DMaterial, noiseRandom2DMaterial, noiseRandom3DMaterial, postQuad; diff --git a/examples/webgl_postprocessing_rgb_halftone.html b/examples/webgl_postprocessing_rgb_halftone.html index 353165710060ae..6e274914d5651f 100644 --- a/examples/webgl_postprocessing_rgb_halftone.html +++ b/examples/webgl_postprocessing_rgb_halftone.html @@ -19,7 +19,8 @@ @@ -28,13 +29,13 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { HalftonePass } from './jsm/postprocessing/HalftonePass.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { HalftonePass } from 'three/addons/postprocessing/HalftonePass.js'; let renderer, clock, camera, stats; diff --git a/examples/webgl_postprocessing_sao.html b/examples/webgl_postprocessing_sao.html index 08482cd9a47f81..39a601878a6dd9 100644 --- a/examples/webgl_postprocessing_sao.html +++ b/examples/webgl_postprocessing_sao.html @@ -19,7 +19,8 @@ @@ -28,12 +29,12 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { SAOPass } from './jsm/postprocessing/SAOPass.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { SAOPass } from 'three/addons/postprocessing/SAOPass.js'; let container, stats; let camera, scene, renderer; diff --git a/examples/webgl_postprocessing_smaa.html b/examples/webgl_postprocessing_smaa.html index 3d5cd2ef511642..f52b56eb6fb143 100644 --- a/examples/webgl_postprocessing_smaa.html +++ b/examples/webgl_postprocessing_smaa.html @@ -20,7 +20,8 @@ @@ -29,11 +30,11 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { SMAAPass } from './jsm/postprocessing/SMAAPass.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { SMAAPass } from 'three/addons/postprocessing/SMAAPass.js'; let camera, scene, renderer, composer, stats; diff --git a/examples/webgl_postprocessing_sobel.html b/examples/webgl_postprocessing_sobel.html index 99aca44660ba75..af22eaa5fd87c0 100644 --- a/examples/webgl_postprocessing_sobel.html +++ b/examples/webgl_postprocessing_sobel.html @@ -20,7 +20,8 @@ @@ -29,16 +30,16 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { ShaderPass } from './jsm/postprocessing/ShaderPass.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; - import { LuminosityShader } from './jsm/shaders/LuminosityShader.js'; - import { SobelOperatorShader } from './jsm/shaders/SobelOperatorShader.js'; + import { LuminosityShader } from 'three/addons/shaders/LuminosityShader.js'; + import { SobelOperatorShader } from 'three/addons/shaders/SobelOperatorShader.js'; let camera, scene, renderer, composer; diff --git a/examples/webgl_postprocessing_ssaa.html b/examples/webgl_postprocessing_ssaa.html index e502a510d85b8c..03005ed625f341 100644 --- a/examples/webgl_postprocessing_ssaa.html +++ b/examples/webgl_postprocessing_ssaa.html @@ -22,7 +22,8 @@ @@ -31,13 +32,13 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { ShaderPass } from './jsm/postprocessing/ShaderPass.js'; - import { SSAARenderPass } from './jsm/postprocessing/SSAARenderPass.js'; - import { CopyShader } from './jsm/shaders/CopyShader.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { SSAARenderPass } from 'three/addons/postprocessing/SSAARenderPass.js'; + import { CopyShader } from 'three/addons/shaders/CopyShader.js'; let scene, renderer, composer, copyPass; let cameraP, ssaaRenderPassP; diff --git a/examples/webgl_postprocessing_ssao.html b/examples/webgl_postprocessing_ssao.html index e6f71e653260ff..8746f09b8fcc9a 100644 --- a/examples/webgl_postprocessing_ssao.html +++ b/examples/webgl_postprocessing_ssao.html @@ -23,7 +23,8 @@ @@ -32,11 +33,11 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { SSAOPass } from './jsm/postprocessing/SSAOPass.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { SSAOPass } from 'three/addons/postprocessing/SSAOPass.js'; let container, stats; let camera, scene, renderer; diff --git a/examples/webgl_postprocessing_ssr.html b/examples/webgl_postprocessing_ssr.html index 880e062108ca72..da7753eb33c63f 100644 --- a/examples/webgl_postprocessing_ssr.html +++ b/examples/webgl_postprocessing_ssr.html @@ -24,7 +24,8 @@ @@ -32,18 +33,18 @@ @@ -32,14 +33,14 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { ShaderPass } from './jsm/postprocessing/ShaderPass.js'; - import { TAARenderPass } from './jsm/postprocessing/TAARenderPass.js'; - import { CopyShader } from './jsm/shaders/CopyShader.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { TAARenderPass } from 'three/addons/postprocessing/TAARenderPass.js'; + import { CopyShader } from 'three/addons/shaders/CopyShader.js'; let camera, scene, renderer, composer, copyPass, taaRenderPass, renderPass; let gui, stats; diff --git a/examples/webgl_postprocessing_unreal_bloom.html b/examples/webgl_postprocessing_unreal_bloom.html index f1af5e56f3439f..8566628a75e378 100644 --- a/examples/webgl_postprocessing_unreal_bloom.html +++ b/examples/webgl_postprocessing_unreal_bloom.html @@ -31,7 +31,8 @@ @@ -40,14 +41,14 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { UnrealBloomPass } from './jsm/postprocessing/UnrealBloomPass.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js'; let camera, stats; let composer, renderer, mixer, clock; diff --git a/examples/webgl_postprocessing_unreal_bloom_selective.html b/examples/webgl_postprocessing_unreal_bloom_selective.html index 8634af7bd62bc1..86271641422c6c 100644 --- a/examples/webgl_postprocessing_unreal_bloom_selective.html +++ b/examples/webgl_postprocessing_unreal_bloom_selective.html @@ -48,7 +48,8 @@ @@ -57,13 +58,13 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { ShaderPass } from './jsm/postprocessing/ShaderPass.js'; - import { UnrealBloomPass } from './jsm/postprocessing/UnrealBloomPass.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js'; const ENTIRE_SCENE = 0, BLOOM_SCENE = 1; diff --git a/examples/webgl_raycaster_bvh.html b/examples/webgl_raycaster_bvh.html index 0e940f5c6428e9..61792b3020abdf 100644 --- a/examples/webgl_raycaster_bvh.html +++ b/examples/webgl_raycaster_bvh.html @@ -32,6 +32,7 @@ { "imports": { "three": "../build/three.module.js", + "three/addons/": "./jsm/", "three-mesh-bvh": "https://unpkg.com/three-mesh-bvh@^0.5.10/build/index.module.js" } } @@ -41,10 +42,10 @@ import * as THREE from 'three'; import { computeBoundsTree, disposeBoundsTree, acceleratedRaycast, MeshBVHVisualizer } from 'three-mesh-bvh'; - import Stats from './jsm/libs/stats.module.js'; - import { FBXLoader } from './jsm/loaders/FBXLoader.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { FBXLoader } from 'three/addons/loaders/FBXLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; // Add the extension functions THREE.BufferGeometry.prototype.computeBoundsTree = computeBoundsTree; @@ -52,7 +53,7 @@ THREE.Mesh.prototype.raycast = acceleratedRaycast; let stats; - let camera, scene, renderer, controls; + let camera, scene, renderer; let mesh, helper, bvh; let sphereInstance, lineSegments; @@ -147,7 +148,9 @@ } ); - controls = new OrbitControls( camera, renderer.domElement ); + const controls = new OrbitControls( camera, renderer.domElement ); + controls.minDistance = 5; + controls.maxDistance = 75; // set up gui const gui = new GUI(); @@ -223,7 +226,7 @@ // raycast _raycaster.ray.origin.copy( _position ); - _raycaster.ray.direction.copy( _position ).multiplyScalar( - 1).normalize(); + _raycaster.ray.direction.copy( _position ).multiplyScalar( - 1 ).normalize(); // update hits points and lines const hits = _raycaster.intersectObject( mesh ); @@ -258,9 +261,6 @@ function onWindowResize() { - const hx = window.innerWidth / 2; - const hy = window.innerHeight / 2; - camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); @@ -291,6 +291,7 @@ mesh.updateMatrixWorld(); } + updateRays(); renderer.render( scene, camera ); diff --git a/examples/webgl_raycaster_sprite.html b/examples/webgl_raycaster_sprite.html index faab726c11880b..d37a9341fbac55 100644 --- a/examples/webgl_raycaster_sprite.html +++ b/examples/webgl_raycaster_sprite.html @@ -25,7 +25,8 @@ @@ -34,10 +35,10 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let renderer, scene, camera; - let controls, group; + let group; let selectedObject = null; const raycaster = new THREE.Raycaster(); @@ -66,8 +67,10 @@ camera.position.set( 15, 15, 15 ); camera.lookAt( scene.position ); - controls = new OrbitControls( camera, renderer.domElement ); - + const controls = new OrbitControls( camera, renderer.domElement ); + controls.minDistance = 15; + controls.maxDistance = 250; + // add sprites const sprite1 = new THREE.Sprite( new THREE.SpriteMaterial( { color: '#69f' } ) ); diff --git a/examples/webgl_raycaster_texture.html b/examples/webgl_raycaster_texture.html index c17006b457a1e0..08ce9f582d95cb 100644 --- a/examples/webgl_raycaster_texture.html +++ b/examples/webgl_raycaster_texture.html @@ -29,7 +29,8 @@ @@ -38,7 +39,7 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; const WRAPPING = { 'RepeatWrapping': THREE.RepeatWrapping, diff --git a/examples/webgl_raymarching_reflect.html b/examples/webgl_raymarching_reflect.html index a2eaee3772476a..096e61f07060dc 100644 --- a/examples/webgl_raymarching_reflect.html +++ b/examples/webgl_raymarching_reflect.html @@ -243,7 +243,8 @@ @@ -252,10 +253,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let dolly, camera, scene, renderer; let geometry, material, mesh; diff --git a/examples/webgl_read_float_buffer.html b/examples/webgl_read_float_buffer.html index 3c749f409cbfc2..bb8c305976211a 100644 --- a/examples/webgl_read_float_buffer.html +++ b/examples/webgl_read_float_buffer.html @@ -65,7 +65,8 @@ @@ -74,7 +75,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let container, stats; diff --git a/examples/webgl_refraction.html b/examples/webgl_refraction.html index ed317425f840ea..b168b2785adb46 100644 --- a/examples/webgl_refraction.html +++ b/examples/webgl_refraction.html @@ -28,7 +28,8 @@ @@ -37,9 +38,9 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { Refractor } from './jsm/objects/Refractor.js'; - import { WaterRefractionShader } from './jsm/shaders/WaterRefractionShader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { Refractor } from 'three/addons/objects/Refractor.js'; + import { WaterRefractionShader } from 'three/addons/shaders/WaterRefractionShader.js'; let camera, scene, renderer, clock; diff --git a/examples/webgl_renderer_pathtracer.html b/examples/webgl_renderer_pathtracer.html new file mode 100644 index 00000000000000..002d22e3cc1338 --- /dev/null +++ b/examples/webgl_renderer_pathtracer.html @@ -0,0 +1,488 @@ + + + + three.js webgl - three-gpu-pathtracer + + + + + + + +
    + three.js pathtracer - three-gpu-pathtracer
    + See main project repository for more information and examples on high fidelity path tracing. +
    + + + + + + + + + + + + + + diff --git a/examples/webgl_rtt.html b/examples/webgl_rtt.html index 72b38a0c45a46c..1e8979e949046e 100644 --- a/examples/webgl_rtt.html +++ b/examples/webgl_rtt.html @@ -62,7 +62,8 @@ @@ -71,7 +72,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let container, stats; diff --git a/examples/webgl_shader.html b/examples/webgl_shader.html index 45c1de70c80f20..4756b047a46c6b 100644 --- a/examples/webgl_shader.html +++ b/examples/webgl_shader.html @@ -70,7 +70,8 @@ diff --git a/examples/webgl_shader2.html b/examples/webgl_shader2.html index 8e9cb71c4c8da7..9a8b879cb772f8 100644 --- a/examples/webgl_shader2.html +++ b/examples/webgl_shader2.html @@ -138,7 +138,8 @@ @@ -147,7 +148,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let stats; @@ -172,15 +173,15 @@ const geometry = new THREE.BoxGeometry( 0.75, 0.75, 0.75 ); uniforms1 = { - "time": { value: 1.0 } + 'time': { value: 1.0 } }; uniforms2 = { - "time": { value: 1.0 }, - "colorTexture": { value: new THREE.TextureLoader().load( 'textures/disturb.jpg' ) } + 'time': { value: 1.0 }, + 'colorTexture': { value: new THREE.TextureLoader().load( 'textures/disturb.jpg' ) } }; - uniforms2[ "colorTexture" ].value.wrapS = uniforms2[ "colorTexture" ].value.wrapT = THREE.RepeatWrapping; + uniforms2[ 'colorTexture' ].value.wrapS = uniforms2[ 'colorTexture' ].value.wrapT = THREE.RepeatWrapping; const params = [ [ 'fragment_shader1', uniforms1 ], @@ -243,8 +244,8 @@ const delta = clock.getDelta(); - uniforms1[ "time" ].value += delta * 5; - uniforms2[ "time" ].value = clock.elapsedTime; + uniforms1[ 'time' ].value += delta * 5; + uniforms2[ 'time' ].value = clock.elapsedTime; for ( let i = 0; i < scene.children.length; i ++ ) { diff --git a/examples/webgl_shader_lava.html b/examples/webgl_shader_lava.html index 56632ef5b925bc..8c4c24a2760aa2 100644 --- a/examples/webgl_shader_lava.html +++ b/examples/webgl_shader_lava.html @@ -81,7 +81,8 @@ @@ -90,10 +91,10 @@ import * as THREE from 'three'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { FilmPass } from './jsm/postprocessing/FilmPass.js'; - import { BloomPass } from './jsm/postprocessing/BloomPass.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { FilmPass } from 'three/addons/postprocessing/FilmPass.js'; + import { BloomPass } from 'three/addons/postprocessing/BloomPass.js'; let camera, renderer, composer, clock; diff --git a/examples/webgl_shaders_ocean.html b/examples/webgl_shaders_ocean.html index 58ec8acf1f4100..a5f93a2a9a260e 100644 --- a/examples/webgl_shaders_ocean.html +++ b/examples/webgl_shaders_ocean.html @@ -20,7 +20,8 @@ @@ -29,12 +30,12 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { Water } from './jsm/objects/Water.js'; - import { Sky } from './jsm/objects/Sky.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { Water } from 'three/addons/objects/Water.js'; + import { Sky } from 'three/addons/objects/Sky.js'; let container, stats; let camera, scene, renderer; diff --git a/examples/webgl_shaders_sky.html b/examples/webgl_shaders_sky.html index cc6652460dd06f..a93b8b3c23fc22 100644 --- a/examples/webgl_shaders_sky.html +++ b/examples/webgl_shaders_sky.html @@ -18,7 +18,8 @@ @@ -27,9 +28,9 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { Sky } from './jsm/objects/Sky.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { Sky } from 'three/addons/objects/Sky.js'; let camera, scene, renderer; diff --git a/examples/webgl_shaders_tonemapping.html b/examples/webgl_shaders_tonemapping.html index b1ec84baec141b..4008d156249003 100644 --- a/examples/webgl_shaders_tonemapping.html +++ b/examples/webgl_shaders_tonemapping.html @@ -52,7 +52,8 @@ @@ -61,14 +62,14 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { ShaderPass } from './jsm/postprocessing/ShaderPass.js'; - import { AdaptiveToneMappingPass } from './jsm/postprocessing/AdaptiveToneMappingPass.js'; - import { BloomPass } from './jsm/postprocessing/BloomPass.js'; - import { GammaCorrectionShader } from './jsm/shaders/GammaCorrectionShader.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; + import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; + import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; + import { AdaptiveToneMappingPass } from 'three/addons/postprocessing/AdaptiveToneMappingPass.js'; + import { BloomPass } from 'three/addons/postprocessing/BloomPass.js'; + import { GammaCorrectionShader } from 'three/addons/shaders/GammaCorrectionShader.js'; let bloomPass, adaptToneMappingPass, ldrToneMappingPass, hdrToneMappingPass; let params; @@ -144,61 +145,61 @@ lights: true, uniforms: THREE.UniformsUtils.merge( [ - THREE.UniformsLib[ "common" ], - THREE.UniformsLib[ "lights" ] + THREE.UniformsLib[ 'common' ], + THREE.UniformsLib[ 'lights' ] ] ), vertexShader: [ - "varying vec3 vViewPosition;", - "varying vec3 vNormal;", - "void main() {", - THREE.ShaderChunk[ "beginnormal_vertex" ], - THREE.ShaderChunk[ "defaultnormal_vertex" ], + 'varying vec3 vViewPosition;', + 'varying vec3 vNormal;', + 'void main() {', + THREE.ShaderChunk[ 'beginnormal_vertex' ], + THREE.ShaderChunk[ 'defaultnormal_vertex' ], - " vNormal = normalize( transformedNormal );", - "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", - "vViewPosition = -mvPosition.xyz;", - "gl_Position = projectionMatrix * mvPosition;", - "}" + ' vNormal = normalize( transformedNormal );', + 'vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );', + 'vViewPosition = -mvPosition.xyz;', + 'gl_Position = projectionMatrix * mvPosition;', + '}' - ].join( "\n" ), + ].join( '\n' ), fragmentShader: [ - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "bsdfs" ], - THREE.ShaderChunk[ "lights_pars_begin" ], - THREE.ShaderChunk[ "normal_pars_fragment" ], - THREE.ShaderChunk[ "lights_phong_pars_fragment" ], + THREE.ShaderChunk[ 'common' ], + THREE.ShaderChunk[ 'bsdfs' ], + THREE.ShaderChunk[ 'lights_pars_begin' ], + THREE.ShaderChunk[ 'normal_pars_fragment' ], + THREE.ShaderChunk[ 'lights_phong_pars_fragment' ], - "void main() {", - "vec3 normal = normalize( -vNormal );", - "vec3 viewPosition = normalize( vViewPosition );", - "#if NUM_DIR_LIGHTS > 0", + 'void main() {', + 'vec3 normal = normalize( -vNormal );', + 'vec3 viewPosition = normalize( vViewPosition );', + '#if NUM_DIR_LIGHTS > 0', - "vec3 dirDiffuse = vec3( 0.0 );", + 'vec3 dirDiffuse = vec3( 0.0 );', - "for( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {", + 'for( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {', - "vec4 lDirection = viewMatrix * vec4( directionalLights[i].direction, 0.0 );", - "vec3 dirVector = normalize( lDirection.xyz );", - "float dotProduct = dot( viewPosition, dirVector );", - "dotProduct = 1.0 * max( dotProduct, 0.0 ) + (1.0 - max( -dot( normal, dirVector ), 0.0 ));", - "dotProduct *= dotProduct;", - "dirDiffuse += max( 0.5 * dotProduct, 0.0 ) * directionalLights[i].color;", - "}", - "#endif", + 'vec4 lDirection = viewMatrix * vec4( directionalLights[i].direction, 0.0 );', + 'vec3 dirVector = normalize( lDirection.xyz );', + 'float dotProduct = dot( viewPosition, dirVector );', + 'dotProduct = 1.0 * max( dotProduct, 0.0 ) + (1.0 - max( -dot( normal, dirVector ), 0.0 ));', + 'dotProduct *= dotProduct;', + 'dirDiffuse += max( 0.5 * dotProduct, 0.0 ) * directionalLights[i].color;', + '}', + '#endif', //Fade out atmosphere at edge - "float viewDot = abs(dot( normal, viewPosition ));", - "viewDot = clamp( pow( viewDot + 0.6, 10.0 ), 0.0, 1.0);", + 'float viewDot = abs(dot( normal, viewPosition ));', + 'viewDot = clamp( pow( viewDot + 0.6, 10.0 ), 0.0, 1.0);', - "vec3 color = vec3( 0.05, 0.09, 0.13 ) * dirDiffuse;", - "gl_FragColor = vec4( color, viewDot );", + 'vec3 color = vec3( 0.05, 0.09, 0.13 ) * dirDiffuse;', + 'gl_FragColor = vec4( color, viewDot );', - "}" + '}' - ].join( "\n" ) + ].join( '\n' ) }; const earthAtmoMat = new THREE.ShaderMaterial( atmoShader ); @@ -270,34 +271,34 @@ const vBGShader = [ // "attribute vec2 uv;", - "varying vec2 vUv;", - "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", - "}" + 'varying vec2 vUv;', + 'void main() {', + 'vUv = uv;', + 'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', + '}' - ].join( "\n" ); + ].join( '\n' ); const pBGShader = [ - "uniform sampler2D map;", - "varying vec2 vUv;", + 'uniform sampler2D map;', + 'varying vec2 vUv;', - "void main() {", + 'void main() {', - "vec2 sampleUV = vUv;", - "vec4 color = texture2D( map, sampleUV, 0.0 );", + 'vec2 sampleUV = vUv;', + 'vec4 color = texture2D( map, sampleUV, 0.0 );', - "gl_FragColor = vec4( color.xyz, 1.0 );", + 'gl_FragColor = vec4( color.xyz, 1.0 );', - "}" + '}' - ].join( "\n" ); + ].join( '\n' ); // Skybox adaptiveLuminanceMat = new THREE.ShaderMaterial( { uniforms: { - "map": { value: null } + 'map': { value: null } }, vertexShader: vBGShader, fragmentShader: pBGShader, @@ -308,7 +309,7 @@ currentLuminanceMat = new THREE.ShaderMaterial( { uniforms: { - "map": { value: null } + 'map': { value: null } }, vertexShader: vBGShader, fragmentShader: pBGShader, @@ -329,10 +330,10 @@ quadBG.scale.set( window.innerWidth, window.innerHeight, 1 ); debugScene.add( quadBG ); - const r = "textures/cube/MilkyWay/"; - const urls = [ r + "dark-s_px.jpg", r + "dark-s_nx.jpg", - r + "dark-s_py.jpg", r + "dark-s_ny.jpg", - r + "dark-s_pz.jpg", r + "dark-s_nz.jpg" ]; + const r = 'textures/cube/MilkyWay/'; + const urls = [ r + 'dark-s_px.jpg', r + 'dark-s_nx.jpg', + r + 'dark-s_py.jpg', r + 'dark-s_ny.jpg', + r + 'dark-s_pz.jpg', r + 'dark-s_nz.jpg' ]; const textureCube = new THREE.CubeTextureLoader().load( urls ); textureCube.encoding = THREE.sRGBEncoding; @@ -441,15 +442,15 @@ requestAnimationFrame( animate ); if ( bloomPass ) { - bloomPass.combineUniforms[ "strength" ].value = params.bloomAmount; + bloomPass.combineUniforms[ 'strength' ].value = params.bloomAmount; } if ( adaptToneMappingPass ) { adaptToneMappingPass.setAdaptionRate( params.adaptionRate ); - adaptiveLuminanceMat.uniforms[ "map" ].value = adaptToneMappingPass.luminanceRT; - currentLuminanceMat.uniforms[ "map" ].value = adaptToneMappingPass.currentLuminanceRT; + adaptiveLuminanceMat.uniforms[ 'map' ].value = adaptToneMappingPass.luminanceRT; + currentLuminanceMat.uniforms[ 'map' ].value = adaptToneMappingPass.currentLuminanceRT; adaptToneMappingPass.enabled = params.enabled; adaptToneMappingPass.setMaxLuminance( params.maxLuminance ); diff --git a/examples/webgl_shadow_contact.html b/examples/webgl_shadow_contact.html index a508b56b1021cd..db6e7e7ccb14ac 100644 --- a/examples/webgl_shadow_contact.html +++ b/examples/webgl_shadow_contact.html @@ -26,7 +26,8 @@ @@ -34,11 +35,11 @@ @@ -31,13 +32,13 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { FirstPersonControls } from './jsm/controls/FirstPersonControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import { FontLoader } from './jsm/loaders/FontLoader.js'; - import { TextGeometry } from './jsm/geometries/TextGeometry.js'; - import { ShadowMapViewer } from './jsm/utils/ShadowMapViewer.js'; + import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { FontLoader } from 'three/addons/loaders/FontLoader.js'; + import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; + import { ShadowMapViewer } from 'three/addons/utils/ShadowMapViewer.js'; const SHADOW_MAP_WIDTH = 2048, SHADOW_MAP_HEIGHT = 1024; diff --git a/examples/webgl_shadowmap_csm.html b/examples/webgl_shadowmap_csm.html index 919d2930c20df7..2a8f301b408e75 100644 --- a/examples/webgl_shadowmap_csm.html +++ b/examples/webgl_shadowmap_csm.html @@ -11,7 +11,7 @@
    three.js webgl - cascaded shadow maps
    - by vHawk (original repository) + by StrandedKitty (original repository)
    @@ -21,7 +21,8 @@ @@ -30,10 +31,10 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { CSM } from './jsm/csm/CSM.js'; - import { CSMHelper } from './jsm/csm/CSMHelper.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { CSM } from 'three/addons/csm/CSM.js'; + import { CSMHelper } from 'three/addons/csm/CSMHelper.js'; let renderer, scene, camera, orthoCamera, controls, csm, csmHelper; diff --git a/examples/webgl_shadowmap_pcss.html b/examples/webgl_shadowmap_pcss.html index f48c754d946b5f..8d6e0a8834fb60 100644 --- a/examples/webgl_shadowmap_pcss.html +++ b/examples/webgl_shadowmap_pcss.html @@ -125,7 +125,8 @@ @@ -134,9 +135,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let stats; let camera, scene, renderer; diff --git a/examples/webgl_shadowmap_performance.html b/examples/webgl_shadowmap_performance.html index cde3303c2f5711..f7105da6b43dbf 100644 --- a/examples/webgl_shadowmap_performance.html +++ b/examples/webgl_shadowmap_performance.html @@ -21,7 +21,8 @@ @@ -30,12 +31,12 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { FirstPersonControls } from './jsm/controls/FirstPersonControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import { FontLoader } from './jsm/loaders/FontLoader.js'; - import { TextGeometry } from './jsm/geometries/TextGeometry.js'; + import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { FontLoader } from 'three/addons/loaders/FontLoader.js'; + import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; const SHADOW_MAP_WIDTH = 2048, SHADOW_MAP_HEIGHT = 1024; diff --git a/examples/webgl_shadowmap_pointlight.html b/examples/webgl_shadowmap_pointlight.html index 1dcd749a5eee25..8e384393b22a3c 100644 --- a/examples/webgl_shadowmap_pointlight.html +++ b/examples/webgl_shadowmap_pointlight.html @@ -18,7 +18,8 @@ @@ -27,9 +28,9 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let camera, scene, renderer, stats; let pointLight, pointLight2; @@ -49,7 +50,7 @@ function createLight( color ) { - const intensity = 1.5; + const intensity = 2; const light = new THREE.PointLight( color, intensity, 20 ); light.castShadow = true; diff --git a/examples/webgl_shadowmap_progressive.html b/examples/webgl_shadowmap_progressive.html index 9f896830fd8e81..c223d3fdf5203a 100644 --- a/examples/webgl_shadowmap_progressive.html +++ b/examples/webgl_shadowmap_progressive.html @@ -20,18 +20,19 @@ @@ -27,10 +28,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { ShadowMapViewer } from './jsm/utils/ShadowMapViewer.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { ShadowMapViewer } from 'three/addons/utils/ShadowMapViewer.js'; let camera, scene, renderer, clock, stats; let dirLight, spotLight; diff --git a/examples/webgl_shadowmap_vsm.html b/examples/webgl_shadowmap_vsm.html index d9bd26f59d6b32..1a6c29dbcb4e82 100644 --- a/examples/webgl_shadowmap_vsm.html +++ b/examples/webgl_shadowmap_vsm.html @@ -18,7 +18,8 @@ @@ -27,10 +28,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; let camera, scene, renderer, clock, stats; let dirLight, spotLight; diff --git a/examples/webgl_shadowmesh.html b/examples/webgl_shadowmesh.html index 1be4c68892f305..25f6bb116d12ff 100644 --- a/examples/webgl_shadowmesh.html +++ b/examples/webgl_shadowmesh.html @@ -21,7 +21,8 @@ @@ -30,7 +31,7 @@ import * as THREE from 'three'; - import { ShadowMesh } from './jsm/objects/ShadowMesh.js'; + import { ShadowMesh } from 'three/addons/objects/ShadowMesh.js'; let SCREEN_WIDTH = window.innerWidth; let SCREEN_HEIGHT = window.innerHeight; @@ -72,7 +73,7 @@ renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT ); - document.getElementById( "container" ).appendChild( renderer.domElement ); + document.getElementById( 'container' ).appendChild( renderer.domElement ); window.addEventListener( 'resize', onWindowResize ); camera.position.set( 0, 2.5, 10 ); @@ -258,7 +259,7 @@ lightSphere.visible = false; lightHolder.visible = false; - document.getElementById( 'lightButton' ).value = "Switch to PointLight"; + document.getElementById( 'lightButton' ).value = 'Switch to PointLight'; } else { @@ -284,7 +285,7 @@ lightSphere.visible = true; lightHolder.visible = true; - document.getElementById( 'lightButton' ).value = "Switch to THREE.DirectionalLight"; + document.getElementById( 'lightButton' ).value = 'Switch to THREE.DirectionalLight'; } diff --git a/examples/webgl_simple_gi.html b/examples/webgl_simple_gi.html index 05a26c0dd471a3..045e03e9159ab6 100644 --- a/examples/webgl_simple_gi.html +++ b/examples/webgl_simple_gi.html @@ -19,7 +19,8 @@ @@ -28,7 +29,7 @@ import * as THREE from 'three'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; class GIMesh extends THREE.Mesh { diff --git a/examples/webgl_skinning_simple.html b/examples/webgl_skinning_simple.html index b790656de707a1..9f906f03a26513 100644 --- a/examples/webgl_skinning_simple.html +++ b/examples/webgl_skinning_simple.html @@ -19,7 +19,8 @@ @@ -28,10 +29,10 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; let stats, mixer, camera, scene, renderer, clock; diff --git a/examples/webgl_sprites.html b/examples/webgl_sprites.html index 0a50c00f477bb6..b9dcd68e0ddb51 100644 --- a/examples/webgl_sprites.html +++ b/examples/webgl_sprites.html @@ -19,7 +19,8 @@ diff --git a/examples/webgl_test_memory.html b/examples/webgl_test_memory.html index c32d3fd7265173..f9b007e7d7e700 100644 --- a/examples/webgl_test_memory.html +++ b/examples/webgl_test_memory.html @@ -28,7 +28,8 @@ diff --git a/examples/webgl_test_memory2.html b/examples/webgl_test_memory2.html index ee2e02b6fa2f27..d1aa95cb8a3be2 100644 --- a/examples/webgl_test_memory2.html +++ b/examples/webgl_test_memory2.html @@ -55,7 +55,8 @@ diff --git a/examples/webgl_tiled_forward.html b/examples/webgl_tiled_forward.html index a99a933e2ee1f3..15e2bd2004f734 100644 --- a/examples/webgl_tiled_forward.html +++ b/examples/webgl_tiled_forward.html @@ -19,7 +19,8 @@ @@ -28,12 +29,12 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { OBJLoader } from './jsm/loaders/OBJLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; - import { UnrealBloomPass } from './jsm/postprocessing/UnrealBloomPass.js'; + import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js'; // Simple form of tiled forward lighting // using texels as bitmasks of 32 lights diff --git a/examples/webgl_tonemapping.html b/examples/webgl_tonemapping.html index 33d56473a3fa8b..9952cb7883a41d 100644 --- a/examples/webgl_tonemapping.html +++ b/examples/webgl_tonemapping.html @@ -22,7 +22,8 @@ @@ -31,17 +32,18 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; - import { RGBELoader } from './jsm/loaders/RGBELoader.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; let mesh, renderer, scene, camera, controls; let gui, guiExposure = null; const params = { exposure: 1.0, - toneMapping: 'ACESFilmic' + toneMapping: 'ACESFilmic', + blurriness: 0.3 }; const toneMappingOptions = { @@ -85,6 +87,7 @@ ); scene = new THREE.Scene(); + scene.backgroundBlurriness = params.blurriness; camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 20 ); camera.position.set( - 1.8, 0.6, 2.7 ); @@ -135,6 +138,15 @@ } ); + gui.add( params, 'blurriness', 0, 1 ) + + .onChange( function ( value ) { + + scene.backgroundBlurriness = value; + render(); + + } ); + updateGUI(); gui.open(); diff --git a/examples/webgl_trails.html b/examples/webgl_trails.html index 2aa240191dad2d..7c09ff14787dbf 100644 --- a/examples/webgl_trails.html +++ b/examples/webgl_trails.html @@ -14,7 +14,8 @@ @@ -23,7 +24,7 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; let stats; diff --git a/examples/webgl_video_kinect.html b/examples/webgl_video_kinect.html index 1ee8319c1b5dc2..cdd929aabb9734 100644 --- a/examples/webgl_video_kinect.html +++ b/examples/webgl_video_kinect.html @@ -75,7 +75,8 @@ @@ -84,7 +85,7 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let scene, camera, renderer; let geometry, mesh, material; diff --git a/examples/webgl_video_panorama_equirectangular.html b/examples/webgl_video_panorama_equirectangular.html index f1b52b532d675f..fa18bad192977e 100644 --- a/examples/webgl_video_panorama_equirectangular.html +++ b/examples/webgl_video_panorama_equirectangular.html @@ -30,7 +30,8 @@ diff --git a/examples/webgl_water.html b/examples/webgl_water.html index 6337545f8004ab..b2098b7e57a539 100644 --- a/examples/webgl_water.html +++ b/examples/webgl_water.html @@ -20,7 +20,8 @@ @@ -29,9 +30,9 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { Water } from './jsm/objects/Water2.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { Water } from 'three/addons/objects/Water2.js'; let scene, camera, clock, renderer, water; diff --git a/examples/webgl_water_flowmap.html b/examples/webgl_water_flowmap.html index 189a5bea1915b7..d818dffa2890ad 100644 --- a/examples/webgl_water_flowmap.html +++ b/examples/webgl_water_flowmap.html @@ -20,7 +20,8 @@ @@ -29,9 +30,9 @@ import * as THREE from 'three'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { Water } from './jsm/objects/Water2.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { Water } from 'three/addons/objects/Water2.js'; let scene, camera, renderer, water; diff --git a/examples/webgl_worker_offscreencanvas.html b/examples/webgl_worker_offscreencanvas.html index 0a60bf60707e66..72acba3f37b742 100644 --- a/examples/webgl_worker_offscreencanvas.html +++ b/examples/webgl_worker_offscreencanvas.html @@ -68,10 +68,19 @@ + + + + + + + + diff --git a/examples/webgpu_compute.html b/examples/webgpu_compute.html index c7f98cd90759f6..b6379bdfeab699 100644 --- a/examples/webgpu_compute.html +++ b/examples/webgpu_compute.html @@ -17,7 +17,8 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } @@ -25,19 +26,19 @@ diff --git a/examples/webgpu_cubemap_adjustments.html b/examples/webgpu_cubemap_adjustments.html index e5a09f0324f1cc..ecaa16aa663f1f 100644 --- a/examples/webgpu_cubemap_adjustments.html +++ b/examples/webgpu_cubemap_adjustments.html @@ -22,7 +22,8 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } @@ -30,25 +31,25 @@ diff --git a/examples/webgpu_cubemap_mix.html b/examples/webgpu_cubemap_mix.html index c81e9d8f81801a..ff0de3c3cbdb07 100644 --- a/examples/webgpu_cubemap_mix.html +++ b/examples/webgpu_cubemap_mix.html @@ -22,7 +22,8 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } @@ -30,23 +31,23 @@ diff --git a/examples/webgpu_depth_texture.html b/examples/webgpu_depth_texture.html index 47c1523073ea32..0ba93bc2b572a5 100644 --- a/examples/webgpu_depth_texture.html +++ b/examples/webgpu_depth_texture.html @@ -17,7 +17,8 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } @@ -25,15 +26,15 @@ diff --git a/examples/webgpu_equirectangular.html b/examples/webgpu_equirectangular.html new file mode 100644 index 00000000000000..0e88a8c257dc08 --- /dev/null +++ b/examples/webgpu_equirectangular.html @@ -0,0 +1,102 @@ + + + + three.js webgpu - equirectangular + + + + + + +
    + three.js webgpu - equirectangular panorama demo. photo by Jón Ragnarsson. +
    + + + + + + + + + + + diff --git a/examples/webgpu_instance_mesh.html b/examples/webgpu_instance_mesh.html index e0c0034870d35c..031de74c593a72 100644 --- a/examples/webgpu_instance_mesh.html +++ b/examples/webgpu_instance_mesh.html @@ -18,7 +18,8 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } @@ -27,13 +28,13 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { mix, range, normalWorld, oscSine, timerLocal } from 'three-nodes/Nodes.js'; + import { mix, range, normalWorld, oscSine, timerLocal } from 'three/nodes'; - import WebGPU from './jsm/capabilities/WebGPU.js'; - import WebGPURenderer from './jsm/renderers/webgpu/WebGPURenderer.js'; + import WebGPU from 'three/addons/capabilities/WebGPU.js'; + import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js'; let camera, scene, renderer, stats; @@ -42,9 +43,9 @@ const count = Math.pow( amount, 3 ); const dummy = new THREE.Object3D(); - init().then( animate ).catch( error ); + init(); - async function init() { + function init() { if ( WebGPU.isAvailable() === false ) { @@ -88,6 +89,7 @@ renderer = new WebGPURenderer(); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); + renderer.setAnimationLoop( animate ); document.body.appendChild( renderer.domElement ); // @@ -99,8 +101,6 @@ window.addEventListener( 'resize', onWindowResize ); - return renderer.init(); - } function onWindowResize() { @@ -116,15 +116,13 @@ function animate() { - requestAnimationFrame( animate ); - render(); stats.update(); } - function render() { + async function render() { if ( mesh ) { @@ -158,13 +156,7 @@ } - renderer.render( scene, camera ); - - } - - function error( error ) { - - console.error( error ); + await renderer.render( scene, camera ); } diff --git a/examples/webgpu_instance_uniform.html b/examples/webgpu_instance_uniform.html index c6df9ba5312a80..4b08af3bea757e 100644 --- a/examples/webgpu_instance_uniform.html +++ b/examples/webgpu_instance_uniform.html @@ -18,7 +18,8 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } @@ -26,27 +27,26 @@ @@ -25,20 +26,20 @@ diff --git a/examples/webgpu_lights_selective.html b/examples/webgpu_lights_selective.html index 4ca936b08b417c..0e69301dcb1146 100644 --- a/examples/webgpu_lights_selective.html +++ b/examples/webgpu_lights_selective.html @@ -19,7 +19,8 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } @@ -27,27 +28,27 @@ @@ -31,21 +32,22 @@ diff --git a/examples/webgpu_materials.html b/examples/webgpu_materials.html index 02ca097be984be..71caa0b441ccf3 100644 --- a/examples/webgpu_materials.html +++ b/examples/webgpu_materials.html @@ -18,7 +18,8 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } @@ -26,16 +27,16 @@ @@ -52,29 +54,28 @@ @@ -25,23 +26,23 @@ diff --git a/examples/webgpu_rtt.html b/examples/webgpu_rtt.html index f4aa324afec67a..25887be4df104a 100644 --- a/examples/webgpu_rtt.html +++ b/examples/webgpu_rtt.html @@ -17,7 +17,8 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } @@ -25,11 +26,11 @@ diff --git a/examples/webgpu_sandbox.html b/examples/webgpu_sandbox.html index b877fac518306a..f21cab7e3f30c2 100644 --- a/examples/webgpu_sandbox.html +++ b/examples/webgpu_sandbox.html @@ -17,7 +17,8 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } @@ -25,20 +26,20 @@ diff --git a/examples/webgpu_skinning.html b/examples/webgpu_skinning.html index 534efca0ddf50d..02b625bd425afa 100644 --- a/examples/webgpu_skinning.html +++ b/examples/webgpu_skinning.html @@ -18,7 +18,8 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } @@ -26,20 +27,20 @@ diff --git a/examples/webgpu_skinning_instancing.html b/examples/webgpu_skinning_instancing.html index 79db1dc1df9534..1e8cf8ff1cacd1 100644 --- a/examples/webgpu_skinning_instancing.html +++ b/examples/webgpu_skinning_instancing.html @@ -18,7 +18,8 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } @@ -26,22 +27,22 @@ diff --git a/examples/webgpu_skinning_points.html b/examples/webgpu_skinning_points.html index 64801c3e352146..d12881ca8e0bc9 100644 --- a/examples/webgpu_skinning_points.html +++ b/examples/webgpu_skinning_points.html @@ -18,7 +18,8 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } @@ -26,20 +27,20 @@ diff --git a/examples/webgpu_sprites.html b/examples/webgpu_sprites.html index 2c731a5e2d36b5..1b7b43d6de2036 100644 --- a/examples/webgpu_sprites.html +++ b/examples/webgpu_sprites.html @@ -17,7 +17,8 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } @@ -25,12 +26,12 @@ diff --git a/examples/webxr_ar_cones.html b/examples/webxr_ar_cones.html index 1da7b83c16aa03..192581b23bc49a 100644 --- a/examples/webxr_ar_cones.html +++ b/examples/webxr_ar_cones.html @@ -19,7 +19,8 @@ @@ -27,7 +28,7 @@ @@ -27,20 +28,19 @@ @@ -27,7 +28,7 @@ @@ -28,9 +29,9 @@ @@ -27,8 +28,8 @@ + + + + + + diff --git a/examples/webxr_vr_ballshooter.html b/examples/webxr_vr_ballshooter.html index f6462a80191f3b..ea3c8f6874ed0d 100644 --- a/examples/webxr_vr_ballshooter.html +++ b/examples/webxr_vr_ballshooter.html @@ -19,7 +19,8 @@ @@ -28,9 +29,9 @@ import * as THREE from 'three'; - import { BoxLineGeometry } from './jsm/geometries/BoxLineGeometry.js'; - import { VRButton } from './jsm/webxr/VRButton.js'; - import { XRControllerModelFactory } from './jsm/webxr/XRControllerModelFactory.js'; + import { BoxLineGeometry } from 'three/addons/geometries/BoxLineGeometry.js'; + import { VRButton } from 'three/addons/webxr/VRButton.js'; + import { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFactory.js'; let camera, scene, renderer; let controller1, controller2; diff --git a/examples/webxr_vr_cubes.html b/examples/webxr_vr_cubes.html index 4d432dc85e1ddc..2e72db79c6ed84 100644 --- a/examples/webxr_vr_cubes.html +++ b/examples/webxr_vr_cubes.html @@ -19,7 +19,8 @@ @@ -28,9 +29,9 @@ import * as THREE from 'three'; - import { BoxLineGeometry } from './jsm/geometries/BoxLineGeometry.js'; - import { VRButton } from './jsm/webxr/VRButton.js'; - import { XRControllerModelFactory } from './jsm/webxr/XRControllerModelFactory.js'; + import { BoxLineGeometry } from 'three/addons/geometries/BoxLineGeometry.js'; + import { VRButton } from 'three/addons/webxr/VRButton.js'; + import { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFactory.js'; const clock = new THREE.Clock(); diff --git a/examples/webxr_vr_dragging.html b/examples/webxr_vr_dragging.html index f02c524f5f5bba..99b3a12d56d77a 100644 --- a/examples/webxr_vr_dragging.html +++ b/examples/webxr_vr_dragging.html @@ -19,7 +19,8 @@ @@ -27,9 +28,9 @@ @@ -28,10 +29,10 @@ @@ -28,10 +29,10 @@ @@ -30,13 +31,13 @@ @@ -30,13 +31,13 @@ @@ -30,12 +31,12 @@ @@ -28,10 +29,10 @@ @@ -27,9 +28,9 @@ @@ -35,12 +36,12 @@ @@ -27,9 +28,9 @@ @@ -22,7 +23,7 @@ @@ -29,7 +30,7 @@ @@ -29,8 +30,8 @@ RollerCoasterLiftersGeometry, TreesGeometry, SkyGeometry - } from './jsm/misc/RollerCoaster.js'; - import { VRButton } from './jsm/webxr/VRButton.js'; + } from 'three/addons/misc/RollerCoaster.js'; + import { VRButton } from 'three/addons/webxr/VRButton.js'; let mesh, material, geometry; diff --git a/examples/webxr_vr_sandbox.html b/examples/webxr_vr_sandbox.html index 02dd54d78678d1..da18b8c5621cd4 100644 --- a/examples/webxr_vr_sandbox.html +++ b/examples/webxr_vr_sandbox.html @@ -14,7 +14,8 @@ @@ -23,17 +24,17 @@ import * as THREE from 'three'; - import { RGBELoader } from './jsm/loaders/RGBELoader.js'; - import { Lensflare, LensflareElement } from './jsm/objects/Lensflare.js'; - import { Reflector } from './jsm/objects/Reflector.js'; - import { VRButton } from './jsm/webxr/VRButton.js'; + import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; + import { Lensflare, LensflareElement } from 'three/addons/objects/Lensflare.js'; + import { Reflector } from 'three/addons/objects/Reflector.js'; + import { VRButton } from 'three/addons/webxr/VRButton.js'; - import { HTMLMesh } from './jsm/interactive/HTMLMesh.js'; - import { InteractiveGroup } from './jsm/interactive/InteractiveGroup.js'; - import { XRControllerModelFactory } from './jsm/webxr/XRControllerModelFactory.js'; + import { HTMLMesh } from 'three/addons/interactive/HTMLMesh.js'; + import { InteractiveGroup } from 'three/addons/interactive/InteractiveGroup.js'; + import { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFactory.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import Stats from './jsm/libs/stats.module.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import Stats from 'three/addons/libs/stats.module.js'; let camera, scene, renderer; let reflector; diff --git a/examples/webxr_vr_sculpt.html b/examples/webxr_vr_sculpt.html index 68493b034dbf89..16857a047956f0 100644 --- a/examples/webxr_vr_sculpt.html +++ b/examples/webxr_vr_sculpt.html @@ -19,7 +19,8 @@ @@ -27,9 +28,9 @@ @@ -28,9 +29,9 @@ import * as THREE from 'three'; - import { BoxLineGeometry } from './jsm/geometries/BoxLineGeometry.js'; - import { VRButton } from './jsm/webxr/VRButton.js'; - import { XRControllerModelFactory } from './jsm/webxr/XRControllerModelFactory.js'; + import { BoxLineGeometry } from 'three/addons/geometries/BoxLineGeometry.js'; + import { VRButton } from 'three/addons/webxr/VRButton.js'; + import { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFactory.js'; let camera, scene, raycaster, renderer; let controller1, controller2; diff --git a/examples/webxr_vr_video.html b/examples/webxr_vr_video.html index 4e35680b488d7d..5c2140c3991e53 100644 --- a/examples/webxr_vr_video.html +++ b/examples/webxr_vr_video.html @@ -26,7 +26,8 @@ @@ -34,7 +35,7 @@ - - - - -
    -
    -

    Custom Geometry

    -
    -
    -
    -
    -NOTE! This article is deprecated. Three.js r125 -removed support for Geometry. Please refer to -the article on custom BufferGeometry. -
    - -

    A previous article gave a tour of -the various built in primitives included in THREE.js. In this -article we'll cover making our own geometry.

    -

    Just to be clear, if you are serious about making 3D content, -the most common way is to use a 3D modeling package like -Blender, -Maya, -3D Studio Max, -Cinema4D, etc... -You'd build a model and then export to gLTF -or .obj and load them up. -Whichever one you choose, expect to spend 2 or 3 weeks going through -their respective tutorials as all of them have a learning curve -to be useful.

    -

    Still, there are times when we might want to generate our own -3D geometry in code instead of using a modeling package.

    -

    First let's just make a cube. Even though three.js already -provides us with BoxGeometry and BoxGeometry a -cube is easy to understand so let's start there.

    -

    There are 2 ways to make custom geometry in THREE.js. One -is with the Geometry class, the other is BufferGeometry. -Each has their advantages. Geometry is arguably easier to -use but slower and uses more memory. For few 1000s triangles -it's a great choice but for 10s of thousands of triangles -it might be better to use BufferGeometry.

    -

    BufferGeometry is arguably harder to use but uses less -memory and is faster. If quick rule of thumb might be -if you're going to generate more than 10000 triangles -consider using BufferGeometry.

    -

    Note when I say Geometry is slower I mean it is slower to -start and slower to modify but it is not slower to draw so -if you're not planning on modifying your geometry then -as long as it's not too large there will only be slightly more -delay for your program to start using Geometry vs using -BufferGeometry. We'll go over both eventually. For now -though let's use geometry as it's easier to understand IMO.

    -

    First let's make a cube with Geometry. We'll start -with an example from the article on responsiveness.

    -

    Let's remove the part that uses BoxGeometry and replace it with -a Geometry.

    -
    -const boxWidth = 1;
    --const boxHeight = 1;
    --const boxDepth = 1;
    --const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);
    -+const geometry = new THREE.Geometry();
    -
    -

    Now let's add the 8 corners of a cube. Here are the 8 corners.

    -
    - -

    Centered around the origin we can add the vertex positions like this

    -
    const geometry = new THREE.Geometry();
    -+geometry.vertices.push(
    -+  new THREE.Vector3(-1, -1,  1),  // 0
    -+  new THREE.Vector3( 1, -1,  1),  // 1
    -+  new THREE.Vector3(-1,  1,  1),  // 2
    -+  new THREE.Vector3( 1,  1,  1),  // 3
    -+  new THREE.Vector3(-1, -1, -1),  // 4
    -+  new THREE.Vector3( 1, -1, -1),  // 5
    -+  new THREE.Vector3(-1,  1, -1),  // 6
    -+  new THREE.Vector3( 1,  1, -1),  // 7
    -+);
    -
    -

    We then need to make triangles, 2 for each face of the cube

    -
    - -

    We do that by creating Face3 objects and specifying the indices -of the 3 vertices that make up that face.

    -

    The order we specify the vertices is important. To be pointing toward the -outside of the cube they must be specified in a counter clockwise direction -when that triangle is facing the camera.

    -
    - -

    Following that pattern we can specify the 12 triangles that make -the cube like this

    -
    geometry.faces.push(
    -  // front
    -  new THREE.Face3(0, 3, 2),
    -  new THREE.Face3(0, 1, 3),
    -  // right
    -  new THREE.Face3(1, 7, 3),
    -  new THREE.Face3(1, 5, 7),
    -  // back
    -  new THREE.Face3(5, 6, 7),
    -  new THREE.Face3(5, 4, 6),
    -  // left
    -  new THREE.Face3(4, 2, 6),
    -  new THREE.Face3(4, 0, 2),
    -  // top
    -  new THREE.Face3(2, 7, 6),
    -  new THREE.Face3(2, 3, 7),
    -  // bottom
    -  new THREE.Face3(4, 1, 0),
    -  new THREE.Face3(4, 5, 1),
    -);
    -
    -

    A few other minor changes to the original code and it should -work.

    -

    These cubes are twice as large as the BoxGeometry we were -using before so let's move the camera back a little

    -
    const fov = 75;
    -const aspect = 2;  // the canvas default
    -const near = 0.1;
    --const far = 5;
    -+const far = 100;
    -const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
    --camera.position.z = 2;
    -+camera.position.z = 5;
    -
    -

    and let's separate them a little more and I changed their colors just because

    -
    const cubes = [
    --  makeInstance(geometry, 0x44aa88,  0),
    --  makeInstance(geometry, 0x8844aa, -2),
    --  makeInstance(geometry, 0xaa8844,  2),
    -+  makeInstance(geometry, 0x44FF44,  0),
    -+  makeInstance(geometry, 0x4444FF, -4),
    -+  makeInstance(geometry, 0xFF4444,  4),
    -];
    -
    -

    One last thing is we haven't added normals yet so we -can't do any lighting. Let's change the material -to something that doesn't need lights.

    -
    function makeInstance(geometry, color, x) {
    --  const material = new THREE.MeshPhongMaterial({color});
    -+  const material = new THREE.MeshBasicMaterial({color});
    -
    -  const cube = new THREE.Mesh(geometry, material);
    -  scene.add(cube);
    -
    -  ...
    -
    -

    and we get cubes we made ourselves.

    -

    - -

    -

    We can specify a color per face by setting the color property of -each face.

    -
    geometry.faces[ 0].color = geometry.faces[ 1].color = new THREE.Color('red');
    -geometry.faces[ 2].color = geometry.faces[ 3].color = new THREE.Color('yellow');
    -geometry.faces[ 4].color = geometry.faces[ 5].color = new THREE.Color('green');
    -geometry.faces[ 6].color = geometry.faces[ 7].color = new THREE.Color('cyan');
    -geometry.faces[ 8].color = geometry.faces[ 9].color = new THREE.Color('blue');
    -geometry.faces[10].color = geometry.faces[11].color = new THREE.Color('magenta');
    -
    -

    note we need to tell the material we want to use vertex colors

    -
    -const material = new THREE.MeshBasicMaterial({color});
    -+const material = new THREE.MeshBasicMaterial({vertexColors: true});
    -
    -

    - -

    -

    We can instead set the color of each individual vertex by setting the vertexColors -property of a Face to an array of the 3 colors for the 3 vertices.

    -
    geometry.faces.forEach((face, ndx) => {
    -  face.vertexColors = [
    -    (new THREE.Color()).setHSL(ndx / 12      , 1, 0.5),
    -    (new THREE.Color()).setHSL(ndx / 12 + 0.1, 1, 0.5),
    -    (new THREE.Color()).setHSL(ndx / 12 + 0.2, 1, 0.5),
    -  ];
    -});
    -
    -

    - -

    -

    To use lighting we need normals. Normals are vectors that specify direction. -Just like the colors we can specify a normal for the face by setting the normal -property on each face with

    -
    face.normal = new THREE.Vector3(...)
    -
    -

    or we can specify a normal for each vertex by setting the vertexNormals -property with something like

    -
    face.vertexNormals = [
    -  new THREE.Vector3(...),
    -  new THREE.Vector3(...),
    -  new THREE.Vector3(...),
    -]
    -
    -

    but often it's much easier to just ask THREE.js to compute normals -for us based on the positions we specified.

    -

    For face normals we'd call Geometry.computeFaceNormals as in

    -
    geometry.computeFaceNormals();
    -
    -

    Removing the vertex color stuff and changing the material back to MeshPhongMaterial

    -
    -const material = new THREE.MeshBasicMaterial({vertexColors: true});
    -+const material = new THREE.MeshPhongMaterial({color});
    -
    -

    and now our cubes can be lit.

    -

    - -

    -

    Using face normals will always give us a faceted look. We can use -vertex normals for a smoother look by calling Geometry.computeVertexNormals

    -
    -geometry.computeFaceNormals();
    -+geometry.computeVertexNormals();
    -
    -

    Unfortunately a cube is not a good candidate for vertex normals since it -means each vertex gets its normal from the -normals of all the faces it shares.

    -

    - -

    -

    Adding texture coordinates, sometimes called UVs, is done via an array of -layers of parallel arrays to the faces array which is set via Geometry.faceVertexUvs. -For our cube we could do something like

    -
    geometry.faceVertexUvs[0].push(
    -  // front
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
    -  // right
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
    -  // back
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
    -  // left
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
    -  // top
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
    -  // bottom
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
    -);
    -
    -

    It's important to notice faceVertexUvs is an array of layers. Each layer -is another set of UV coordinates. By default there is one layer of UV coordinates, -layer 0, so we just add our UVs to that layer.

    -

    Let's add a texture to our material and switch back to compute face normals

    -
    -geometry.computeVertexNormals();
    -+geometry.computeFaceNormals();
    -
    -+const loader = new THREE.TextureLoader();
    -+const texture = loader.load('resources/images/star.png');
    -
    -function makeInstance(geometry, color, x) {
    --  const material = new THREE.MeshPhongMaterial({color});
    -+  const material = new THREE.MeshPhongMaterial({color, map: texture});
    -
    -  const cube = new THREE.Mesh(geometry, material);
    -  scene.add(cube);
    -
    -  ...
    -
    -

    - -

    -

    Putting that all together, let's make a simple heightmap based -terrain mesh.

    -

    A heightmap based terrain is where you have a 2D array of heights -that you apply them to a grid. An easy way to get a 2D array of heights -is to draw them in an image editing program. Here's an image I drew. -It's 96x64 pixels

    -
    - -

    We'll load that and then generate a heightmap mesh from it. -We can use the ImageLoader to load the image.

    -
    const imgLoader = new THREE.ImageLoader();
    -imgLoader.load('resources/images/heightmap-96x64.png', createHeightmap);
    -
    -function createHeightmap(image) {
    -  // extract the data from the image by drawing it to a canvas
    -  // and calling getImageData
    -  const ctx = document.createElement('canvas').getContext('2d');
    -  const {width, height} = image;
    -  ctx.canvas.width = width;
    -  ctx.canvas.height = height;
    -  ctx.drawImage(image, 0, 0);
    -  const {data} = ctx.getImageData(0, 0, width, height);
    -
    -  const geometry = new THREE.Geometry();
    -
    -

    We extracted the data from the image, now we'll make a grid of cells. -The cells are the squares formed by the center points of each pixel -from the image

    -
    - -

    For each cell we'll generate 5 vertices. One for each corner of the cell -and one at the center point of the cell with the average height of the 4 -corner heights.

    -
    const cellsAcross = width - 1;
    -const cellsDeep = height - 1;
    -for (let z = 0; z < cellsDeep; ++z) {
    -  for (let x = 0; x < cellsAcross; ++x) {
    -    // compute row offsets into the height data
    -    // we multiply by 4 because the data is R,G,B,A but we
    -    // only care about R
    -    const base0 = (z * width + x) * 4;
    -    const base1 = base0 + (width * 4);
    -
    -    // look up the height for the for points
    -    // around this cell
    -    const h00 = data[base0] / 32;
    -    const h01 = data[base0 + 4] / 32;
    -    const h10 = data[base1] / 32;
    -    const h11 = data[base1 + 4] / 32;
    -    // compute the average height
    -    const hm = (h00 + h01 + h10 + h11) / 4;
    -
    -    // the corner positions
    -    const x0 = x;
    -    const x1 = x + 1;
    -    const z0 = z;
    -    const z1 = z + 1;
    -
    -    // remember the first index of these 5 vertices
    -    const ndx = geometry.vertices.length;
    -
    -    // add the 4 corners for this cell and the midpoint
    -    geometry.vertices.push(
    -      new THREE.Vector3(x0, h00, z0),
    -      new THREE.Vector3(x1, h01, z0),
    -      new THREE.Vector3(x0, h10, z1),
    -      new THREE.Vector3(x1, h11, z1),
    -      new THREE.Vector3((x0 + x1) / 2, hm, (z0 + z1) / 2),
    -    );
    -
    -

    We'll then make 4 triangles from those 5 vertices

    -
    - -
        // create 4 triangles
    -    geometry.faces.push(
    -      new THREE.Face3(ndx + 0, ndx + 4, ndx + 1),
    -      new THREE.Face3(ndx + 1, ndx + 4, ndx + 3),
    -      new THREE.Face3(ndx + 3, ndx + 4, ndx + 2),
    -      new THREE.Face3(ndx + 2, ndx + 4, ndx + 0),
    -    );
    -
    -    // add the texture coordinates for each vertex of each face
    -    const u0 = x / cellsAcross;
    -    const v0 = z / cellsDeep;
    -    const u1 = (x + 1) / cellsAcross;
    -    const v1 = (z + 1) / cellsDeep;
    -    const um = (u0 + u1) / 2;
    -    const vm = (v0 + v1) / 2;
    -    geometry.faceVertexUvs[0].push(
    -      [ new THREE.Vector2(u0, v0), new THREE.Vector2(um, vm), new THREE.Vector2(u1, v0) ],
    -      [ new THREE.Vector2(u1, v0), new THREE.Vector2(um, vm), new THREE.Vector2(u1, v1) ],
    -      [ new THREE.Vector2(u1, v1), new THREE.Vector2(um, vm), new THREE.Vector2(u0, v1) ],
    -      [ new THREE.Vector2(u0, v1), new THREE.Vector2(um, vm), new THREE.Vector2(u0, v0) ],
    -    );
    -  }
    -}
    -
    -

    and finish it up

    -
      geometry.computeFaceNormals();
    -
    -  // center the geometry
    -  geometry.translate(width / -2, 0, height / -2);
    -
    -  const loader = new THREE.TextureLoader();
    -  const texture = loader.load('resources/images/star.png');
    -
    -  const material = new THREE.MeshPhongMaterial({color: 'green', map: texture});
    -
    -  const cube = new THREE.Mesh(geometry, material);
    -  scene.add(cube);
    -}
    -
    -

    A few minor changes to make it easier to view.

    - -
    import * as THREE from '/build/three.module.js';
    -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
    -
    -
    const fov = 75;
    -const aspect = 2;  // the canvas default
    -const near = 0.1;
    --const far = 100;
    -+const far = 200;
    -const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
    --camera.position.z = 5;
    -+camera.position.set(20, 20, 20);
    -
    -+const controls = new OrbitControls(camera, canvas);
    -+controls.target.set(0, 0, 0);
    -+controls.update();
    -
    -

    add 2 lights

    -
    -{
    -+function addLight(...pos) {
    -  const color = 0xFFFFFF;
    -  const intensity = 1;
    -  const light = new THREE.DirectionalLight(color, intensity);
    --  light.position.set(-1, 2, 4\);
    -+  light.position.set(...pos);
    -  scene.add(light);
    -}
    -
    -+addLight(-1, 2, 4);
    -+addLight(1, 2, -2);
    -
    -

    and we deleted the code related to spinning the cubes.

    -

    - -

    -

    I hope that was a useful instruction to making your own -geometry using Geometry.

    -

    In another article we'll go over BufferGeometry.

    - -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/manual/en/fundamentals.html b/manual/en/fundamentals.html index 49b1b194564180..3dae91a84657e0 100644 --- a/manual/en/fundamentals.html +++ b/manual/en/fundamentals.html @@ -116,13 +116,12 @@

    Fundamentals

    First let's load three.js

    <script type="module">
    -import * as THREE from '../../build/three.module.js';
    +import * as THREE from 'three';
     </script>
     

    It's important you put type="module" in the script tag. This enables -us to use the import keyword to load three.js. There are other ways -to load three.js but as of r106 using modules is the recommended way. -Modules have the advantage that they can easily import other modules +us to use the import keyword to load three.js. As of r147, this is the +only way to load three.js properly. Modules have the advantage that they can easily import other modules they need. That saves us from having to manually load extra scripts they are dependent on.

    Next we need is a <canvas> tag so...

    @@ -132,7 +131,7 @@

    Fundamentals

    We will ask three.js to draw into that canvas so we need to look it up.

    <script type="module">
    -import * as THREE from '../../build/three.module.js';
    +import * as THREE from 'three';
     
     +function main() {
     +  const canvas = document.querySelector('#c');
    @@ -177,7 +176,7 @@ 

    Fundamentals

    The height of the near and far planes are determined by the field of view. The width of both planes is determined by the field of view and the aspect.

    -

    Anything inside the defined frustum will be be drawn. Anything outside +

    Anything inside the defined frustum will be drawn. Anything outside will not.

    The camera defaults to looking down the -Z axis with +Y up. We'll put our cube at the origin so we need to move the camera back a little from the origin @@ -210,7 +209,7 @@

    Fundamentals

    const material = new THREE.MeshBasicMaterial({color: 0x44aa88});
     

    We then create a Mesh. A Mesh in three represents the combination -of a three things

    +of three things

    1. A Geometry (the shape of the object)
    2. A Material (how to draw the object, shiny or flat, what color, what texture(s) to apply. Etc.)
    3. @@ -365,69 +364,86 @@

      Fundamentals

      making our code responsive so it is adaptable to multiple situations.

      es6 modules, three.js, and folder structure

      -

      As of version r106 the preferred way to use three.js is via es6 modules.

      +

      As of version r147 the preferred way to use three.js is via es6 modules and import maps.

      es6 modules can be loaded via the import keyword in a script -or inline via a <script type="module"> tag. Here's an example of -both +or inline via a <script type="module"> tag. Here's an example

      -
      <script type="module">
      -import * as THREE from '../../build/three.module.js';
      +
      <script type="module">
      +import * as THREE from 'three';
       
       ...
       
       </script>
       

      -Paths must be absolute or relative. Relative paths always start with ./ or ../ -which is different than other tags like <img> and <a>. +Notice 'three' specifier there. If you leave it as it is, it will likely produce an error. An import map should be used to tell the browser where to find three.js +

      +
      <script type="importmap">
      +{
      +  "imports": {
      +    "three": "./path/to/three.module.js"
      +  }
      +}
      +</script>
      +
      +

      +Note that path specifier can start only with ./ or ../.

      -References to the same script will only be loaded once as long as their absolute paths -are exactly the same. For three.js this means it's required that you put all the examples -libraries in the correct folder structure +Import maps are still unsupported in Firefox and Safari, so it is recommended to use an import maps polyfill like so

      -
      someFolder
      - |
      - ├-build
      - | |
      - | +-three.module.js
      - |
      - +-examples
      -   |
      -   +-jsm
      -     |
      -     +-controls
      -     | |
      -     | +-OrbitControls.js
      -     | +-TrackballControls.js
      -     | +-...
      -     |
      -     +-loaders
      -     | |
      -     | +-GLTFLoader.js
      -     | +-...
      -     |
      -     ...
      +
      <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
      +

      +To import addons like OrbitControls.js use the following +

      +
      import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
       

      -The reason this folder structure is required is because the scripts in the -examples like OrbitControls.js -have hard coded relative paths like +Don't forget to add addons to the import map like so

      -
      import * as THREE from '../../../build/three.module.js';
      +
      <script type="importmap">
      +{
      +  "imports": {
      +    "three": "./path/to/three.module.js",
      +    "three/addons/": "./different/path/to/examples/jsm/"
      +  }
      +}
      +</script>
       

      -Using the same structure assures then when you import both three and one of the example -libraries they'll both reference the same three.module.js file. +You can also use a CDN

      -
      import * as THREE from './someFolder/build/three.module.js';
      -import {OrbitControls} from './someFolder/examples/jsm/controls/OrbitControls.js';
      +
      <script type="importmap">
      +{
      +  "imports": {
      +    "three": "https://unpkg.com/three@0.147.0/build/three.module.js",
      +    "three/addons/": "https://unpkg.com/three@0.147.0/examples/jsm/"
      +  }
      +}
      +</script>
       
      -

      This includes when using a CDN. Be sure your path to three.module.js ends with -/build/three.modules.js. For example

      -
      import * as THREE from 'https://unpkg.com/three@0.108.0/build/three.module.js';
      -import {OrbitControls} from 'https://unpkg.com/three@0.108.0/examples/jsm/controls/OrbitControls.js';
      +

      +To conclude, the recommended way of using three.js is +

      +
      <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
      +
      +<script type="importmap">
      +{
      +  "imports": {
      +    "three": "./path/to/three.module.js",
      +    "three/addons/": "./different/path/to/examples/jsm/"
      +  }
      +}
      +</script>
      +
      +<script type="module">
      +import * as THREE from 'three';
      +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
      +
      +...
      +
      +</script>
       
      @@ -445,4 +461,4 @@

      es6 modules, three.js, and folder structure

      - \ No newline at end of file + diff --git a/manual/en/game.html b/manual/en/game.html index 2b3fd9f595ce55..c58a8f0458eba9 100644 --- a/manual/en/game.html +++ b/manual/en/game.html @@ -234,10 +234,10 @@

      Making a Game

      it for skinned animated characters. Fortunately there's a utility function, SkeletonUtils.clone we can use to do this. So, first we need to include the utils.

      -
      import * as THREE from '/build/three.module.js';
      -import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      -import {GLTFLoader} from '/examples/jsm/loaders/GLTFLoader.js';
      -+import * as SkeletonUtils from '/examples/jsm/utils/SkeletonUtils.js';
      +
      import * as THREE from 'three';
      +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
      +import {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';
      ++import * as SkeletonUtils from 'three/addons/utils/SkeletonUtils.js';
       

      Then we can clone the models we just loaded

      function init() {
      @@ -1513,11 +1513,11 @@ 

      Making a Game

      While we're at it lets make it so we can turn them on/off using lil-gui like we've used else where

      -
      import * as THREE from '/build/three.module.js';
      -import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      -import {GLTFLoader} from '/examples/jsm/loaders/GLTFLoader.js';
      -import * as SkeletonUtils from '/examples/jsm/utils/SkeletonUtils.js';
      -+import {GUI} from '/examples/jsm/libs/lil-gui.module.min.js';
      +
      import * as THREE from 'three';
      +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
      +import {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';
      +import * as SkeletonUtils from 'three/addons/utils/SkeletonUtils.js';
      ++import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
       
      +const gui = new GUI();
       +gui.add(globals, 'debug').onChange(showHideDebugInfo);
      diff --git a/manual/en/lights.html b/manual/en/lights.html
      index 393bd26003d0e0..70c8994c4973fa 100644
      --- a/manual/en/lights.html
      +++ b/manual/en/lights.html
      @@ -50,8 +50,8 @@ 

      Lights

      or orbit the camera around some point. The OrbitControls are an optional feature of three.js so first we need to include them in our page

      -
      import * as THREE from '/build/three.module.js';
      -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      +
      import * as THREE from 'three';
      ++import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
       

      Then we can use them. We pass the OrbitControls a camera to control and the DOM element to use to get input events

      @@ -422,9 +422,9 @@

      To use the RectAreaLight we need to include some extra three.js optional data and we'll include the RectAreaLightHelper to help us visualize the light

      -
      import * as THREE from '/build/three.module.js';
      -+import {RectAreaLightUniformsLib} from '/examples/jsm/lights/RectAreaLightUniformsLib.js';
      -+import {RectAreaLightHelper} from '/examples/jsm/helpers/RectAreaLightHelper.js';
      +
      import * as THREE from 'three';
      ++import {RectAreaLightUniformsLib} from 'three/addons/lights/RectAreaLightUniformsLib.js';
      ++import {RectAreaLightHelper} from 'three/addons/helpers/RectAreaLightHelper.js';
       

      and we need to call RectAreaLightUniformsLib.init

      function main() {
      diff --git a/manual/en/load-gltf.html b/manual/en/load-gltf.html
      index 93601619fa371f..7909f7d6432e01 100644
      --- a/manual/en/load-gltf.html
      +++ b/manual/en/load-gltf.html
      @@ -112,10 +112,10 @@ 

      Loading a .GLTF File

      I kept the auto framing code as before

      We also need to include the GLTFLoader and we can get rid of the OBJLoader.

      -
      -import {LoaderSupport} from '/examples/jsm/loaders/LoaderSupport.js';
      --import {OBJLoader} from '/examples/jsm/loaders/OBJLoader.js';
      --import {MTLLoader} from '/examples/jsm/loaders/MTLLoader.js';
      -+import {GLTFLoader} from '/examples/jsm/loaders/GLTFLoader.js';
      +
      -import {LoaderSupport} from 'three/addons/loaders/LoaderSupport.js';
      +-import {OBJLoader} from 'three/addons/loaders/OBJLoader.js';
      +-import {MTLLoader} from 'three/addons/loaders/MTLLoader.js';
      ++import {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';
       

      And running that we get

      @@ -271,7 +271,7 @@

      Loading a .GLTF File

      - cars = root.getObjectByName('Cars'); + const loadedCars = root.getObjectByName('Cars'); + const fixes = [ -+ { prefix: 'Car_08', rot: [Math.PI * .5, 0, Math.PI +* .5], }, ++ { prefix: 'Car_08', rot: [Math.PI * .5, 0, Math.PI * .5], }, + { prefix: 'CAR_03', rot: [0, Math.PI, 0], }, + { prefix: 'Car_04', rot: [0, Math.PI, 0], }, + ]; @@ -707,4 +707,4 @@

      Loading a .GLTF File

      - \ No newline at end of file + diff --git a/manual/en/load-obj.html b/manual/en/load-obj.html index f8601b93f73cfb..b3240cd6988485 100644 --- a/manual/en/load-obj.html +++ b/manual/en/load-obj.html @@ -66,7 +66,7 @@

      Loading a .OBJ File

      related to adjusting the lights. I also removed the cube and sphere that were being added to the scene.

      From that the first thing we need to do is include the OBJLoader loader in our script.

      -
      import {OBJLoader} from '/examples/jsm/loaders/OBJLoader.js';
      +
      import {OBJLoader} from 'three/addons/loaders/OBJLoader.js';
       

      Then to load the .OBJ file we create an instance of OBJLoader, pass it the URL of our .OBJ file, and pass in a callback that adds @@ -148,10 +148,10 @@

      Loading a .OBJ File

      Now that we have the textures available we can load the .MTL file.

      First we need to include the MTLLoader;

      -
      import * as THREE from '/build/three.module.js';
      -import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      -import {OBJLoader} from '/examples/jsm/loaders/OBJLoader.js';
      -+import {MTLLoader} from '/examples/jsm/loaders/MTLLoader.js';
      +
      import * as THREE from 'three';
      +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
      +import {OBJLoader} from 'three/addons/loaders/OBJLoader.js';
      ++import {MTLLoader} from 'three/addons/loaders/MTLLoader.js';
       

      Then we first load the .MTL file. When it's finished loading we add the just loaded materials on to the OBJLoader itself via the setMaterials diff --git a/manual/en/multiple-scenes.html b/manual/en/multiple-scenes.html index fa4ef72656d6d7..d477b870a95c1b 100644 --- a/manual/en/multiple-scenes.html +++ b/manual/en/multiple-scenes.html @@ -411,7 +411,7 @@

      Using HTML Dataset

      Adding Controls to each element

      Adding interactively, for example a TrackballControls is just as easy. First we add the script for the control.

      -
      import {TrackballControls} from '/examples/jsm/controls/TrackballControls.js';
      +
      import {TrackballControls} from 'three/addons/controls/TrackballControls.js';
       

      And then we can add a TrackballControls to each scene passing in the element associated with that scene.

      -function makeScene() {
      diff --git a/manual/en/offscreencanvas.html b/manual/en/offscreencanvas.html
      index 4a64755e755862..57f73fdc17ec1a 100644
      --- a/manual/en/offscreencanvas.html
      +++ b/manual/en/offscreencanvas.html
      @@ -258,7 +258,7 @@ 

      OffscreenCanvas

      copy all of offscreencanvas-cubes.js to shared-cube.js. Then we rename main to init since we already have a main in our HTML file and we need to export init and state

      -
      import * as THREE from '../../build/three.module.js';
      +
      import * as THREE from 'three';
       
       -const state = {
       +export const state = {
      @@ -609,7 +609,7 @@ 

      OffscreenCanvas

      as the original DOM events so the OrbitControls won't be able to tell the difference.

      Here's the code for the worker part.

      -
      import {EventDispatcher} from '../../build/three.module.js';
      +
      import {EventDispatcher} from 'three';
       
       class ElementProxyReceiver extends EventDispatcher {
         constructor() {
      @@ -683,8 +683,8 @@ 

      OffscreenCanvas

      };

      In our shared three.js code we need to import the OrbitControls and set them up.

      -
      import * as THREE from '../../build/three.module.js';
      -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      +
      import * as THREE from 'three';
      ++import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
       
       export function init(data) {
       -  const {canvas} = data;
      diff --git a/manual/en/optimize-lots-of-objects-animated.html b/manual/en/optimize-lots-of-objects-animated.html
      index 5471438931e35f..d118b5407ab467 100644
      --- a/manual/en/optimize-lots-of-objects-animated.html
      +++ b/manual/en/optimize-lots-of-objects-animated.html
      @@ -354,10 +354,10 @@ 

      Optimize Lots of Objects Animated

      because the original webgl globe uses an animation library let's use the same one here.

      We need to include the library

      -
      import * as THREE from '/build/three.module.js';
      -import * as BufferGeometryUtils from '/examples/jsm/utils/BufferGeometryUtils.js';
      -import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      -+import {TWEEN} from '/examples/jsm/libs/tween.min.js';
      +
      import * as THREE from 'three';
      +import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js';
      +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
      ++import {TWEEN} from 'three/addons/libs/tween.min.js';
       

      And then create a Tween to animate the influences.

      // show the selected data, hide the rest
      diff --git a/manual/en/optimize-lots-of-objects.html b/manual/en/optimize-lots-of-objects.html
      index 01efdd0324e521..a5d1e522149f27 100644
      --- a/manual/en/optimize-lots-of-objects.html
      +++ b/manual/en/optimize-lots-of-objects.html
      @@ -404,7 +404,7 @@ 

      Optimize Lots of Objects

      BufferGeometryUtils.mergeBufferGeometries which will combined all of them into a single mesh.

      We also need to include the BufferGeometryUtils

      -
      import * as BufferGeometryUtils from '/examples/jsm/utils/BufferGeometryUtils.js';
      +
      import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js';
       

      And now, at least on my machine, I get 60 frames per second

      diff --git a/manual/en/post-processing.html b/manual/en/post-processing.html index 6b60ba1168f13b..3c88a14d7363fc 100644 --- a/manual/en/post-processing.html +++ b/manual/en/post-processing.html @@ -103,10 +103,10 @@

      renderToScree true to tell it to render to the canvas. Without setting this it would instead render to the next render target.

      To use these classes we need to import a bunch of scripts.

      -
      import {EffectComposer} from '/examples/jsm/postprocessing/EffectComposer.js';
      -import {RenderPass} from '/examples/jsm/postprocessing/RenderPass.js';
      -import {BloomPass} from '/examples/jsm/postprocessing/BloomPass.js';
      -import {FilmPass} from '/examples/jsm/postprocessing/FilmPass.js';
      +
      import {EffectComposer} from 'three/addons/postprocessing/EffectComposer.js';
      +import {RenderPass} from 'three/addons/postprocessing/RenderPass.js';
      +import {BloomPass} from 'three/addons/postprocessing/BloomPass.js';
      +import {FilmPass} from 'three/addons/postprocessing/FilmPass.js';
       

      For pretty much any post processing EffectComposer.js, and RenderPass.js are required.

      @@ -173,7 +173,7 @@

      renderToScree

      So which makes it pretty clear how to set them.

      Let's make a quick GUI to set those values

      -
      import {GUI} from '/examples/jsm/libs/lil-gui.module.min.js';
      +
      import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
       

      and

      const gui = new GUI();
      diff --git a/manual/en/prerequisites.html b/manual/en/prerequisites.html
      index e5a88d96065c57..c6c11cb7d22976 100644
      --- a/manual/en/prerequisites.html
      +++ b/manual/en/prerequisites.html
      @@ -35,7 +35,7 @@ 

      Prerequisites

      you know what the DOM is, how to write HTML as well as create DOM elements in JavaScript. They assume you know how to use es6 modules -via import and via <script type="module"> tags. +via import and via <script type="module"> tags. They assume you know how to use import maps. They assume you know some CSS and that you know what CSS selectors are. They also assume you know ES5, ES6 and maybe some ES7. @@ -44,18 +44,27 @@

      Prerequisites

      Here's some brief refreshers and notes

      es6 modules

      es6 modules can be loaded via the import keyword in a script -or inline via a <script type="module"> tag. Here's an example of -both

      -
      <script type="module">
      -import * as THREE from '../../build/three.module.js';
      +or inline via a <script type="module"> tag. Here's an example

      +
      <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
      +
      +<script type="importmap">
      +{
      +  "imports": {
      +    "three": "./path/to/three.module.js",
      +    "three/addons/": "./different/path/to/examples/jsm/"
      +  }
      +}
      +</script>
      +
      +<script type="module">
      +import * as THREE from 'three';
      +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
       
       ...
       
       </script>
       
      -

      Paths must be absolute or relative. Relative paths always start with ./ or ../ -which is different than other tags like <img> and <a> and css references.

      -

      More details are mentioned at the bottom of this article.

      +

      See more details at the bottom of this article.

      document.querySelector and document.querySelectorAll

      You can use document.querySelector to select the first element that matches a CSS selector. document.querySelectorAll returns diff --git a/manual/en/rendering-on-demand.html b/manual/en/rendering-on-demand.html index 49e330df402dad..7deadfa9d30996 100644 --- a/manual/en/rendering-on-demand.html +++ b/manual/en/rendering-on-demand.html @@ -50,8 +50,8 @@

      Rendering on Demand

      and modify it to render on demand.

      First we'll add in the OrbitControls so there is something that could change that we can render in response to.

      -
      import * as THREE from '/build/three.module.js';
      -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      +
      import * as THREE from 'three';
      ++import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
       

      and set them up

      const fov = 75;
      @@ -174,9 +174,9 @@ 

      Rendering on Demand

      Let's also add a simple lil-gui GUI and make its changes render on demand.

      -
      import * as THREE from '/build/three.module.js';
      -import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      -+import {GUI} from '/examples/jsm/libs/lil-gui.module.min.js';
      +
      import * as THREE from 'three';
      +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
      ++import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
       

      Let's allow setting the color and x scale of each cube. To be able to set the color we'll use the ColorGUIHelper we created in the article on diff --git a/manual/en/textures.html b/manual/en/textures.html index edcf70b45d9512..be8341eeb71e6c 100644 --- a/manual/en/textures.html +++ b/manual/en/textures.html @@ -468,7 +468,7 @@

      lil-gui again to provide a simple interface.

      -
      import {GUI} from '/examples/jsm/libs/lil-gui.module.min.js';
      +
      import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
       

      As we did in previous lil-gui examples we'll use a simple class to give lil-gui an object that it can manipulate in degrees diff --git a/manual/en/transparency.html b/manual/en/transparency.html index 6c02b4081bfa91..a8d62c9fd72301 100644 --- a/manual/en/transparency.html +++ b/manual/en/transparency.html @@ -366,9 +366,9 @@

      Transparency

      .onChange(requestRenderIfNotRequested);

      and of course we need to include lil-gui

      -
      import * as THREE from '/build/three.module.js';
      -import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      -+import {GUI} from '/examples/jsm/libs/lil-gui.module.min.js';
      +
      import * as THREE from 'three';
      +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
      ++import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
       

      and here's the results

      diff --git a/manual/en/webxr.html b/manual/en/webxr-basics.html similarity index 99% rename from manual/en/webxr.html rename to manual/en/webxr-basics.html index 5e50991a451781..016b310e22664c 100644 --- a/manual/en/webxr.html +++ b/manual/en/webxr-basics.html @@ -68,8 +68,8 @@

      VR

      this site.

      The first thing we need to do is include the VR support after including three.js

      -
      import * as THREE from '/build/three.module.js';
      -+import {VRButton} from '/examples/jsm/webxr/VRButton.js';
      +
      import * as THREE from 'three';
      ++import {VRButton} from 'three/addons/webxr/VRButton.js';
       

      Then we need to enable three.js's WebXR support and add its VR button to our page

      @@ -380,4 +380,4 @@

      VR

      - \ No newline at end of file + diff --git a/manual/examples/align-html-elements-to-3d-globe-too-many-labels.html b/manual/examples/align-html-elements-to-3d-globe-too-many-labels.html index ed5b6ed2b52805..df85a8b6956ddc 100644 --- a/manual/examples/align-html-elements-to-3d-globe-too-many-labels.html +++ b/manual/examples/align-html-elements-to-3d-globe-too-many-labels.html @@ -65,14 +65,15 @@ @@ -31,13 +32,13 @@ import * as THREE from 'three'; import * as lutParser from './resources/lut-reader.js'; import * as dragAndDrop from './resources/drag-and-drop.js'; -import {OrbitControls} from '../../examples/jsm/controls/OrbitControls.js'; -import {GLTFLoader} from '../../examples/jsm/loaders/GLTFLoader.js'; -import {EffectComposer} from '../../examples/jsm/postprocessing/EffectComposer.js'; -import {RenderPass} from '../../examples/jsm/postprocessing/RenderPass.js'; -import {ShaderPass} from '../../examples/jsm/postprocessing/ShaderPass.js'; -import {GammaCorrectionShader} from '../../examples/jsm/shaders/GammaCorrectionShader.js'; -import {GUI} from '../../examples/jsm/libs/lil-gui.module.min.js'; +import {OrbitControls} from 'three/addons/controls/OrbitControls.js'; +import {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js'; +import {EffectComposer} from 'three/addons/postprocessing/EffectComposer.js'; +import {RenderPass} from 'three/addons/postprocessing/RenderPass.js'; +import {ShaderPass} from 'three/addons/postprocessing/ShaderPass.js'; +import {GammaCorrectionShader} from 'three/addons/shaders/GammaCorrectionShader.js'; +import {GUI} from 'three/addons/libs/lil-gui.module.min.js'; function main() { const canvas = document.querySelector('#c'); diff --git a/manual/examples/postprocessing-3dlut.html b/manual/examples/postprocessing-3dlut.html index f6c68a6cfd2054..e0c004631fd9b1 100644 --- a/manual/examples/postprocessing-3dlut.html +++ b/manual/examples/postprocessing-3dlut.html @@ -26,20 +26,21 @@ @@ -42,9 +43,9 @@

      Adobe LUT to PNG converter

      import * as THREE from 'three'; import * as lutParser from './resources/lut-reader.js'; import * as dragAndDrop from './resources/drag-and-drop.js'; -import {EffectComposer} from '../../examples/jsm/postprocessing/EffectComposer.js'; -import {RenderPass} from '../../examples/jsm/postprocessing/RenderPass.js'; -import {ShaderPass} from '../../examples/jsm/postprocessing/ShaderPass.js'; +import {EffectComposer} from 'three/addons/postprocessing/EffectComposer.js'; +import {RenderPass} from 'three/addons/postprocessing/RenderPass.js'; +import {ShaderPass} from 'three/addons/postprocessing/ShaderPass.js'; function main() { const canvas = document.querySelector('#c'); diff --git a/manual/examples/postprocessing-custom.html b/manual/examples/postprocessing-custom.html index d6454ed425f46e..66887a61376c07 100644 --- a/manual/examples/postprocessing-custom.html +++ b/manual/examples/postprocessing-custom.html @@ -27,17 +27,18 @@ - - - - -
      -
      -

      Custom Geometry

      -
      -
      -
      -

      Désolé, cet article n'a pas encore été traduit. Les traductions sont le bienvenue! 😄

      -

      Voici l'article anglais originel pour le moment.

      - -
      -
      -
      - - - - - - - - \ No newline at end of file diff --git a/manual/fr/fundamentals.html b/manual/fr/fundamentals.html index e6a22c9820faae..b33f97d3595324 100644 --- a/manual/fr/fundamentals.html +++ b/manual/fr/fundamentals.html @@ -116,7 +116,7 @@

      principes de base

      Tout d'abord, chargeons Three.js :

      <script type="module">
      -import * as THREE from './resources/threejs/r130/build/three.module.js';
      +import * as THREE from 'three';
       </script>
       

      Il est important d'écrire type="module" dans la balise script. @@ -133,7 +133,7 @@

      principes de base

      Nous allons demander à Three.js de dessiner dans ce canevas donc nous devons le rechercher dans le document html :

      <script type="module">
      -import * as THREE from '../../build/three.module.js';
      +import * as THREE from 'three';
       
       +function main() {
       +  const canvas = document.querySelector('#c');
      @@ -368,7 +368,7 @@ 

      es6 modules, Three.js et structure de dossiers

      par le biais d'une balise <script type="module">. Voici un exemple d'utilisation avec les deux :

      <script type="module">
      -import * as THREE from '../../build/three.module.js';
      +import * as THREE from 'three';
       
       ...
       
      @@ -421,12 +421,12 @@ 

      es6 modules, Three.js et structure de dossiers

      three.module.js.

      import * as THREE from './someFolder/build/three.module.js';
      -import {OrbitControls} from './someFolder/examples/jsm/controls/OrbitControls.js';
      +import {OrbitControls} from './someFolder/addons/controls/OrbitControls.js';
       

      Cela est valable aussi lors de l'utilisation d'un CDN. Assurez vous que vos chemins versThis includes when using a CDN. Be three.modules.js terminent par /build/three.modules.js. Par exemple :

      import * as THREE from 'https://unpkg.com/three@0.108.0/build/three.module.js';
      -import {OrbitControls} from 'https://unpkg.com/three@0.108.0/examples/jsm/controls/OrbitControls.js';
      +import {OrbitControls} from 'https://unpkg.com/three@0.108.0/addons/controls/OrbitControls.js';
       
      diff --git a/manual/fr/lights.html b/manual/fr/lights.html index cb98a01b03818a..766fded2f0fa9b 100644 --- a/manual/fr/lights.html +++ b/manual/fr/lights.html @@ -43,8 +43,8 @@

      Lumières en

      +camera.position.set(0, 10, 20);

      Ajoutons ensuite OrbitControls. OrbitControls permet à l'utilisateur de tourner ou de mettre la caméra en orbite autour d'un certain point. Il s'agit d'une fonctionnalité facultative de Three.js, nous devons donc d'abord l'importer

      -
      import * as THREE from '/build/three.module.js';
      -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      +
      import * as THREE from 'three';
      ++import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
       

      Ensuite, nous pouvons l'utiliser. Nous passons à OrbitControls une caméra à contrôler et l'élément DOM à utiliser.

      const controls = new OrbitControls(camera, canvas);
      @@ -345,9 +345,9 @@ 

      Pour utiliser RectAreaLight nous devons importer RectAreaLightHelper pour nous aider à voir la lumière.

      -
      import * as THREE from '/build/three.module.js';
      -+import {RectAreaLightUniformsLib} from '/examples/jsm/lights/RectAreaLightUniformsLib.js';
      -+import {RectAreaLightHelper} from '/examples/jsm/helpers/RectAreaLightHelper.js';
      +
      import * as THREE from 'three';
      ++import {RectAreaLightUniformsLib} from 'three/addons/lights/RectAreaLightUniformsLib.js';
      ++import {RectAreaLightHelper} from 'three/addons/helpers/RectAreaLightHelper.js';
       

      et nous devons appeler RectAreaLightUniformsLib.init

      function main() {
      diff --git a/manual/fr/prerequisites.html b/manual/fr/prerequisites.html
      index 07485f1ab3150d..7a867b9428753d 100644
      --- a/manual/fr/prerequisites.html
      +++ b/manual/fr/prerequisites.html
      @@ -50,7 +50,7 @@ 

      Modules es6

      Les modules es6 peuvent être chargé via le mot-clé import dans un script ou en ligne via une balise <script type="module">. Voici un exemple des deux

      <script type="module">
      -import * as THREE from '../../build/three.module.js';
      +import * as THREE from 'three';
       
       ...
       
      diff --git a/manual/fr/scenegraph.html b/manual/fr/scenegraph.html
      index 33f6155cff7b4b..9632483ef04a67 100644
      --- a/manual/fr/scenegraph.html
      +++ b/manual/fr/scenegraph.html
      @@ -1,10 +1,10 @@
       
           
      -    Graphique de scène de 
      +    Graphe de scène
           
           
           
      -    
      +    
           
           
           
      @@ -26,17 +26,17 @@
         
           
      -

      Graphique de scène de

      +

      Graphe de de scène

      Cet article fait partie d'une série consacrée à Three.js. Le premier article s'intitule Principes de base. Si vous ne l'avez pas encore lu, vous voudriez peut-être commencer par là.

      -

      Le coeurs de Three.js est sans aucun doute son graphique de scène. Un graphique de scène est une représentation arborescente des objets que l’on souhaite afficher, où chaque nœud représente un espace local.

      +

      Le cœur de Three.js est sans aucun doute son graphe de scène. Un graphe de scène est une représentation arborescente des objets que l’on souhaite afficher, où chaque nœud représente un espace local.

      C'est un peu abstrait, alors essayons de donner quelques exemples.

      -

      On pourrait prendre comme exemple le système solaire, le soleil, la terre, la lune.

      +

      On pourrait prendre comme exemple le système solaire, le Soleil, la Terre et la Lune.

      La Terre tourne autour du Soleil. La Lune tourne autour de la Terre. La Lune se déplace en cercle autour de la Terre. Du point de vue de la Lune, elle tourne dans "l'espace local" de la Terre. Même si son mouvement par rapport au Soleil est une courbe folle comme un spirographe du point de vue de la Lune, il n'a qu'à se préoccuper de tourner autour de l'espace local de la Terre.

      @@ -44,8 +44,8 @@

      Graphique de scène de

      -

      Pour le voir autrement, vous qui vivez sur Terre n'avez pas à penser à la rotation de la Terre sur son axe ni à sa rotation autour du Soleil. Vous marchez ou conduisez ou nagez ou courez comme si la Terre ne bougeait pas ou ne tournait pas du tout. Vous marchez, conduisez, nagez, courez et vivez dans "l'espace local" de la Terre même si par rapport au soleil, vous tournez autour de la terre à environ 1 600 km/h et autour du soleil à environ 107000km/h. Votre position dans le système solaire est similaire à celle de la lune au-dessus, mais vous n'avez pas à vous en préoccuper. Vous vous souciez simplement de votre position par rapport à la terre dans son "espace local".

      -

      Allons-y une étape à la fois. Imaginez que nous voulions faire un diagramme du soleil, de la terre et de la lune. Nous allons commencer par le soleil en créant simplement une sphère et en la mettant à l'origine. Remarque : Nous utilisons le soleil, la terre et la lune comme démonstration de l'utilisation d'une scène. Bien sûr, le vrai soleil, la terre et la lune utilisent la physique, mais pour nos besoins, nous allons faire semblant.

      +

      Pour le voir autrement, vous qui vivez sur Terre, n'avez pas à penser à la rotation de la Terre sur son axe ni à sa rotation autour du Soleil. Vous marchez ou conduisez ou nagez ou courez comme si la Terre ne bougeait pas ou ne tournait pas du tout. Vous marchez, conduisez, nagez, courez et vivez dans "l'espace local" de la Terre, même si par rapport au Soleil, vous tournez autour de la Terre à environ 1 600 km/h et autour du Soleil à environ 107000 km/h. Votre position dans le système solaire est similaire à celle de la Lune au-dessus, mais vous n'avez pas à vous en préoccuper. Vous vous souciez de votre position par rapport à la Terre dans son "espace local".

      +

      Mais allons-y une étape à la fois! Imaginez que nous voulions faire un diagramme du Soleil, de la Terre et de la Lune. Nous allons commencer par le Soleil en créant une simpme sphère et en la mettant à l'origine. Remarque : Nous utilisons le Soleil, la Terre et la Lune comme démonstration de l'utilisation d'une scène. Bien sûr, le vrai Soleil, la Terre et la Lune utilisent la physique, mais pour nos besoins, nous allons faire semblant.

      // un tableau d'objets dont la rotation à mettre à jour
       const objects = [];
       
      @@ -58,14 +58,14 @@ 

      Graphique de scène de

      const sunMaterial = new THREE.MeshPhongMaterial({emissive: 0xFFFF00}); const sunMesh = new THREE.Mesh(sphereGeometry, sunMaterial); -sunMesh.scale.set(5, 5, 5); // agrandir le soleil +sunMesh.scale.set(5, 5, 5); // agrandir le Soleil scene.add(sunMesh); objects.push(sunMesh);
      -

      Nous utilisons une sphère à très faible polygone. Seulement 6 segments autour de son équateur. C'est ainsi qu'il est facile de voir la rotation.

      -

      Nous allons réutiliser la même sphère pour tout, nous allons juste grossir la sunMesh 5 fois.

      -

      Nous avons également défini la propriété emissive du matériau phong sur jaune. La propriété émissive d'un matériau phong est essentiellement la couleur qui sera dessinée sans que la lumière ne frappe la surface. La lumière est ajoutée à cette couleur.

      -

      Mettons également une 'point light' au centre de la scène. Nous entrerons dans les détails plus tard, mais pour l'instant, la version simple est une lumière qui émane d'un seul point.

      +

      Nous utilisons une sphère ayant un faible nombre de polygones (avec seulement 6 segments autour de son équateur) afin de faciliter la visualisation de sa rotation.

      +

      Nous allons réutiliser la même sphère pour les autres astres : nous allons grossir la sunMesh 5 fois.

      +

      Nous avons également défini la propriété emissive du matériau Phong sur jaune. La propriété émissive d'un matériau Phong est essentiellement la couleur qui sera dessinée sans que la lumière ne frappe la surface. La lumière est ajoutée à cette couleur.

      +

      Mettons aussi une 'point light' au centre de la scène. Nous entrerons dans les détails plus tard, mais pour l'instant, la version simple est une lumière qui émane d'un seul point.

      {
         const color = 0xFFFFFF;
         const intensity = 3;
      @@ -73,7 +73,7 @@ 

      Graphique de scène de

      scene.add(light); }
      -

      Pour faciliter la visualisation, nous allons placer la caméra directement au-dessus de l'origine en regardant vers le bas. Le moyen le plus simple de le faire est d'utiliser la fonction lookAt. Cette fonction oriente la caméra pour "regarder" vers la position que nous passons à lookAt. Avant de faire cela, nous devons cependant indiquer à la caméra dans quelle direction le haut de la caméra est orienté ou plutôt dans quelle direction est "vers le haut" pour la caméra. Pour la plupart des situations, un Y positif est suffisant, mais puisque nous regardons vers le bas, nous devons dire à la caméra que Z positif est levé.

      +

      Pour faciliter la visualisation, nous allons placer la caméra directement au-dessus de l'origine en regardant vers le bas. Le moyen le plus simple de le faire est d'utiliser la fonction lookAt. Cette fonction oriente la caméra pour "regarder" vers la position que nous passons à lookAt. Avant de faire cela, nous devons cependant indiquer à la caméra dans quelle direction "vers son haut" est orienté. Pour la plupart des situations, un Y positif est suffisant, mais puisque nous regardons vers le bas, nous devons dire à la caméra que Z positif est levé.

      const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
       camera.position.set(0, 50, 0);
       camera.up.set(0, 0, 1);
      @@ -91,23 +91,23 @@ 

      Graphique de scène de

      -

      Ajoutons maintenant la terre.

      +

      Ajoutons maintenant la Terre.

      const earthMaterial = new THREE.MeshPhongMaterial({color: 0x2233FF, emissive: 0x112244});
       const earthMesh = new THREE.Mesh(sphereGeometry, earthMaterial);
       earthMesh.position.x = 10;
       scene.add(earthMesh);
       objects.push(earthMesh);
       
      -

      Nous fabriquons un matériau bleu mais nous lui donnons une petite quantité de bleu émissif pour qu'il apparaisse sur notre fond noir.

      -

      Nous utilisons la même sphereGeometry avec notre nouveau EarthMaterial bleu pour faire une earthMesh. -Nous positionnons ces 10 unités à gauche du soleil et l'ajoutons à la scène. L'ajouter à notre tableau objects, la met en mouvement également.

      +

      Nous fabriquons un matériau bleu, mais nous lui donnons une petite quantité de bleu émissif pour qu'il apparaisse sur notre fond noir.

      +

      Nous utilisons la même sphereGeometry avec notre nouveau EarthMaterial bleu pour faire une earthMesh. +Nous positionnons ces 10 unités à gauche du Soleil et l'ajoutons à la scène. L'ajouter à notre tableau objects, la met en mouvement également.

      -

      Vous pouvez voir que le soleil et la terre tournent mais que la terre ne tourne pas autour du soleil. Faisons de la terre un enfant du soleil

      +

      Vous pouvez voir que le Soleil et la Terre tournent, mais que la Terre ne tourne pas autour du Soleil. Faisons de la Terre un enfant du Soleil

      -scene.add(earthMesh);
       +sunMesh.add(earthMesh);
       
      @@ -118,13 +118,13 @@

      Graphique de scène de

      -

      Que s'est-il passé? Pourquoi la terre a-t-elle la même taille que le soleil et pourquoi est-elle si loin ? En fait, j'ai dû déplacer la caméra de 50 à 150 unités au-dessus pour voir la terre.

      -

      Nous avons fait de earthMesh un enfant du sunMesh. -La sunMesh a son échelle définie sur 5x grâce à sunMesh.scale.set(5, 5, 5). Cela signifie que l'espace local sunMeshs est 5 fois plus grand. -Tout ce qui est mis dans cet espace sera multiplié par 5. Cela signifie que la Terre est maintenant 5 fois plus grande et sa distance par rapport au soleil (earthMesh.position.x = 10) est également 5 fois plus grande.

      -

      Notre scène ressemble maintenant à celà

      +

      Que s'est-il passé ? Pourquoi la Terre a-t-elle la même taille que le Soleil et pourquoi est-elle si loin ? En fait, j'ai dû déplacer la caméra de 50 à 150 unités au-dessus pour voir la Terre.

      +

      Nous avons fait de earthMesh un enfant du sunMesh. +La sunMesh a son échelle définie sur 5x grâce à sunMesh.scale.set(5, 5, 5). Cela signifie que l'espace local sunMeshs est 5 fois plus grand. +Tout ce qui est mis dans cet espace sera multiplié par 5. Cela signifie que la Terre est maintenant 5 fois plus grande et sa distance par rapport au Soleil (earthMesh.position.x = 10) est également 5 fois plus grande.

      +

      Notre scène ressemble maintenant à cela

      -

      Pour résoudre ce problème, ajoutons un nœud vide. Nous lions le soleil et la terre à ce nœud.

      +

      Pour résoudre ce problème, ajoutons un nœud vide. Nous lions le Soleil et la Terre à ce nœud.

      +const solarSystem = new THREE.Object3D();
       +scene.add(solarSystem);
       +objects.push(solarSystem);
      @@ -146,7 +146,7 @@ 

      Graphique de scène de

      Ici, nous avons fait un Object3D. Comme une Mesh, c'est aussi un nœud, mais contrairement à une Mesh, il n'a ni matériau ni géométrie. Il ne représente qu'un espace local.

      Notre nouvelle scène ressemble à ceci :

      -

      La sunMesh et la earthMesh sont tous les deux des enfants de solarSystem. Les trois sont en train de tournés, et comme earthMesh n'est pas un enfant de sunMesh, elle n'est plus mise à l'échelle.

      +

      La sunMesh et la earthMesh sont tous les deux des enfants de solarSystem. Les trois sont en train de tourner, et comme earthMesh n'est pas un enfant de sunMesh, elle n'est plus mise à l'échelle.

      Cliquer ici pour ouvrir dans une fenêtre séparée @@ -177,7 +177,7 @@

      Graphique de scène de

      +moonOrbit.add(moonMesh); +objects.push(moonMesh);
      -

      Ajoutons à nouveau d'autres noeuds à notre scène. D'abord, un Object3D appelé earthOrbit +

      Ajoutons à nouveau d'autres nœuds à notre scène. D'abord, un Object3D appelé earthOrbit ensuite ajoutons-lui un earthMesh et un moonOrbit. Finalement, ajoutons un moonMesh au moonOrbit. Notre scène devrait ressembler à ceci :

      @@ -188,13 +188,13 @@

      Graphique de scène de

      -

      Vous pouvez voir que la lune suit le modèle de spirographe indiqué en haut de cet article, mais nous n'avons pas eu à le calculer manuellement. Nous venons de configurer notre graphe de scène pour le faire pour nous.

      +

      Vous pouvez voir que la Lune suit le modèle de spirographe indiqué en haut de cet article, mais nous n'avons pas eu à le calculer manuellement. Nous venons de configurer notre graphe de scène pour le faire pour nous.

      Il est souvent utile de dessiner quelque chose pour visualiser les nœuds dans le graphe de scène. Three.js dispose pour cela de Helpers.

      -

      L'un d'entre eux s'appelle AxesHelper. Il dessine trois lignes représentant les axes +

      L'un d'entre eux s'appelle AxesHelper. Il dessine trois lignes représentant les axes X, Y, et -Z. Ajoutons-en un à chacun de nos noeuds.

      +Z. Ajoutons-en un à chacun de nos nœuds.

      // add an AxesHelper to each node
       objects.forEach((node) => {
         const axes = new THREE.AxesHelper();
      @@ -214,7 +214,7 @@ 

      Graphique de scène de

      Vous pouvez voir les axes x (rouge) et z (bleu). Comme nous regardons vers le bas et que chacun de nos objets tourne autour de son axe y, nous ne voyons pas bien l'axe y (verte).

      -

      Il peut être difficile de voir certains d'entre eux car il y a 2 paires d'axes qui se chevauchent. Le sunMesh et le solarSystem sont tous les deux à la même position. De même, earthMesh et earthOrbit sont à la même position. Ajoutons quelques contrôles simples pour nous permettre de les activer/désactiver pour chaque nœud. Pendant que nous y sommes, ajoutons également un autre assistant appelé GridHelper. Il crée une grille 2D sur le plan X,Z. Par défaut, la grille est de 10x10 unités.

      +

      Il peut être difficile de voir certains d'entre eux, car il y a 2 paires d'axes qui se chevauchent. Le sunMesh et le solarSystem sont tous les deux à la même position. De même, earthMesh et earthOrbit sont à la même position. Ajoutons quelques contrôles simples pour nous permettre de les activer/désactiver pour chaque nœud. Pendant que nous y sommes, ajoutons également un autre assistant appelé GridHelper. Il crée une grille 2D sur le plan X,Z. Par défaut, la grille est de 10x10 unités.

      Nous allons également utiliser lil-gui, une librairie d'interface utilisateur très populaire pour les projets Three.js. lil-gui prend un objet et un nom de propriété sur cet objet et, en fonction du type de la propriété, crée automatiquement une interface utilisateur pour manipuler cette propriété.

      Nous voulons créer à la fois un GridHelper et un AxesHelper pour chaque nœud. Nous avons besoin d'un label pour chaque nœud, nous allons donc nous débarrasser de l'ancienne boucle et faire appel à une fonction pour ajouter les helpers pour chaque nœud.

      -// add an AxesHelper to each node
      @@ -237,11 +237,11 @@ 

      Graphique de scène de

      +makeAxisGrid(moonOrbit, 'moonOrbit'); +makeAxisGrid(moonMesh, 'moonMesh');
      -

      makeAxisGrid crée un AxisGridHelper qui est une classe que nous allons créer pour rendre lil-gui heureux. Comme il est dit ci-dessus, lil-gui créera automatiquement une interface utilisateur qui manipule la propriété nommée d'un objet. Cela créera une interface utilisateur différente selon le type de propriété. Nous voulons qu'il crée une case à cocher, nous devons donc spécifier une propriété bool. Mais, nous voulons que les axes et la grille apparaissent/disparaissent en fonction d'une seule propriété, nous allons donc créer une classe qui a un getter et un setter pour une propriété. De cette façon, nous pouvons laisser lil-gui penser qu'il manipule une seule propriété, mais en interne, nous pouvons définir la propriété visible de AxesHelper et GridHelper pour un nœud.

      -
      // Activer/désactiver les axes et la grille lil-gui 
      -// nécessite une propriété qui renvoie un bool 
      -// pour décider de faire une case à cocher 
      -// afin que nous créions un setter et un getter pour `visible` 
      +

      makeAxisGrid crée un AxisGridHelper qui est une classe que nous allons créer pour rendre lil-gui heureux. Comme il est dit ci-dessus, lil-gui créera automatiquement une interface utilisateur qui manipule la propriété nommée d'un objet. Cela créera une interface utilisateur différente selon le type de propriété. Nous voulons qu'il crée une case à cocher, nous devons donc spécifier une propriété bool. Mais, nous voulons que les axes et la grille apparaissent/disparaissent en fonction d'une seule propriété, nous allons en conséquence créer une classe qui a un getter et un setter pour une propriété. De cette façon, nous pouvons laisser lil-gui penser qu'il manipule une seule propriété, mais en interne, nous pouvons définir la propriété visible de AxesHelper et GridHelper pour un nœud.

      +
      // Activer/désactiver les axes et la grille lil-gui
      +// nécessite une propriété qui renvoie un bool
      +// pour décider de faire une case à cocher
      +// afin que nous créions un setter et un getter pour `visible`
       // que nous pouvons dire à lil-gui de regarder.
       class AxisGridHelper {
         constructor(node, units = 10) {
      @@ -276,22 +276,20 @@ 

      Graphique de scène de

      -

      Cliquez sur solarSystem et vous verrez que la terre est exactement à 10 unités du centre, comme nous l'avons défini ci-dessus. Vous pouvez voir que la terre est dans l'espace local du solarSystem. De même, si vous cliquez sur earthOrbit, vous verrez que la lune est exactement à 2 unités du centre de l'espace local de earthOrbit.

      -

      Un autre exemple de scène. Une automobile dans un jeu simple pourrait avoir un graphique de scène comme celui-ci

      +

      Cliquez sur solarSystem et vous verrez que la Terre est exactement à 10 unités du centre, comme nous l'avons défini ci-dessus. Vous pouvez voir que la Terre est dans l'espace local du solarSystem. De même, si vous cliquez sur earthOrbit, vous verrez que la Lune est exactement à 2 unités du centre de l'espace local de earthOrbit.

      +

      Un autre exemple de scène. Une automobile dans un jeu simple pourrait avoir un graphe de scène comme celui-ci

      Si vous déplacez la carrosserie de la voiture, toutes les roues bougeront avec elle. Si vous vouliez que le corps rebondisse séparément des roues, vous pouvez lier le corps et les roues à un nœud "cadre" qui représente le cadre de la voiture.

      Un autre exemple avec un humain dans un jeu vidéo.

      Vous pouvez voir que le graphique de la scène devient assez complexe pour un humain. En fait, le graphe ci-dessus est simplifié. Par exemple, vous pouvez l'étendre pour couvrir chaque doigt (au moins 28 autres nœuds) et chaque orteil (encore 28 nœuds) plus ceux pour le visage et la mâchoire, les yeux et peut-être plus.

      Faisons un graphe semi-complexe. On va faire un char. Il aura 6 roues et une tourelle. Il pourra suivre un chemin. Il y aura une sphère qui se déplacera et le char ciblera la sphère.

      -

      Let's make one semi-complex scene graph. We'll make a tank. The tank will have -6 wheels and a turret. The tank will follow a path. There will be a sphere that -moves around and the tank will target the sphere.

      +

      Créons une scène un peu plus complexe : nous allons créer un char d'assaut (tank) avec ses six roues et sa tourelle. Le tank suivra un chemin prédéfini. Il y aura aussi une sphère qui tourne autour du tank et ce dernier orientera sa tourelle vers cette cible.

      Voici le graphique de la scène. Les maillages sont colorés en vert, les Object3D en bleu, les lumières en or et les caméras en violet. Une caméra n'a pas été ajoutée au graphique de la scène.

      Regardez dans le code pour voir la configuration de tous ces nœuds.

      -

      Pour la cible, la chose que le char vise, il y a une targetOrbit (Object3D) qui tourne juste de la même manière que la earthOrbit ci-dessus. Une targetElevation (Object3D) qui est un enfant de targetOrbit fournit un décalage par rapport à targetOrbit et une élévation de base. Un autre Object3D appelé targetBob qui monte et descend par rapport à la targetElevation. Enfin, il y a le targetMesh qui est juste un cube que nous faisons pivoter et changeons ses couleurs.

      +

      Pour la cible, la sphère que le char vise, il y a une targetOrbit (Object3D) qui tourne de la même manière que la earthOrbit ci-dessus. Une targetElevation (Object3D) qui est un enfant de targetOrbit fournit un décalage par rapport à targetOrbit et une élévation de base. Un autre Object3D appelé targetBob qui monte et descend par rapport à la targetElevation. Enfin, il y a le targetMesh qui est seulement un cube que nous faisons pivoter et changeons ses couleurs.

      // mettre en mouvement la cible
       targetOrbit.rotation.y = time * .27;
       targetBob.position.y = Math.sin(time * 2) * 4;
      @@ -306,7 +304,7 @@ 

      Graphique de scène de

      ... -// mettre en mouvement le char +// Mettre en mouvement le char const tankTime = time * .05; curve.getPointAt(tankTime % 1, tankPosition); curve.getPointAt((tankTime + 0.01) % 1, tankTarget); @@ -318,7 +316,7 @@

      Graphique de scène de

      ... -// tourelle face à la cible +// Tourelle face à la cible targetMesh.getWorldPosition(targetPosition); turretPivot.lookAt(targetPosition);
      @@ -349,7 +347,7 @@

      Graphique de scène de

      const infoElem = document.querySelector('#info');
      -

      et nous parcourons chaque camera au moment du rendu

      +

      et nous parcourons chaque caméra au moment du rendu

      const camera = cameras[time * .25 % cameras.length | 0];
       infoElem.textContent = camera.desc;
       
      @@ -359,18 +357,13 @@

      Graphique de scène de

      -

      J'espère que cela donne une idée du fonctionnement des graphiques de scène et de la façon dont vous pouvez les utiliser. -Faire des nœuds « Object3D » et leur attacher des choses est une étape importante pour utiliser -un moteur 3D comme Three.js bien. Souvent, on pourrait penser que des mathématiques complexes soient nécessaires -pour faire bouger quelque chose et faire pivoter comme vous le souhaitez. Par exemple sans graphique de scène -calculer le mouvement de la lune, savoir où placer les roues de la voiture par rapport à son -corps serait très compliqué, mais en utilisant un graphique de scène, cela devient beaucoup plus facile.

      -

      Passons maintenant en revue les materials.

      +

      J'espère que cet article vous aura donné une bonne idée du fonctionnement des graphes de scène et de la façon dont vous devez les utiliser. Créer des nœuds « Object3D » et savoir leur attacher d'autres nœuds est une étape importante dans l'utilisant un moteur 3D tel que Three.js., car bien souvent, on pourrait penser que des mathématiques complexes sont nécessaires pour faire bouger quelque chose et faire pivoter comme vous le souhaitez (comme calculer le mouvement de la Lune, savoir où calculer la position des roues de la voiture par rapport à son corps). En utilisant un graphe de scène, et comme nous l'avons vu dans cet article, le travail en est grandement simplifié.

      +

      Article suivant :Passons maintenant en revue les materials.

      - + diff --git a/manual/fr/textures.html b/manual/fr/textures.html index 7cb2eefbc1638f..aba6e55c613b66 100644 --- a/manual/fr/textures.html +++ b/manual/fr/textures.html @@ -380,7 +380,7 @@

      lil-gui pour fournir une interface simple.

      -
      import {GUI} from '/examples/jsm/libs/lil-gui.module.min.js';
      +
      import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
       

      Comme nous l'avons fait dans les exemples précédents avec lil-gui, nous utiliserons une classe simple pour donner à lil-gui un objet qu'il peut manipuler en degrés mais qu'il définira en radians.

      class DegRadHelper {
      diff --git a/manual/fr/webxr.html b/manual/fr/webxr-basics.html
      similarity index 100%
      rename from manual/fr/webxr.html
      rename to manual/fr/webxr-basics.html
      diff --git a/manual/ja/align-html-elements-to-3d.html b/manual/ja/align-html-elements-to-3d.html
      index 2231e4b6f3059e..8e02efede091fa 100644
      --- a/manual/ja/align-html-elements-to-3d.html
      +++ b/manual/ja/align-html-elements-to-3d.html
      @@ -58,8 +58,8 @@ 

      でHTML要素を3Dに揃える

      いくつかのプリミティブで3Dシーンを作り、それぞれのプリミティブにラベルを付けます。 レスポンシブの記事の例を使います。

      ライティングの記事のように OrbitControls を追加します。

      -
      import * as THREE from '/build/three.module.js';
      -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      +
      import * as THREE from 'three';
      ++import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
       
      const controls = new OrbitControls(camera, canvas);
       controls.target.set(0, 0, 0);
      @@ -636,9 +636,9 @@ 

      でHTML要素を3Dに揃える

      私にはこの設定のための良い値が何か分からないです。 値を操作できるようにGUIを追加します。

      -
      import * as THREE from '/build/three.module.js';
      -import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      -+import {GUI} from '/examples/jsm/libs/lil-gui.module.min.js';
      +
      import * as THREE from 'three';
      +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
      ++import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
       
      +const settings = {
       +  minArea: 20,
      diff --git a/manual/ja/backgrounds.html b/manual/ja/backgrounds.html
      index 77cb390dcf7b5c..10c5dddf4f2963 100644
      --- a/manual/ja/backgrounds.html
      +++ b/manual/ja/backgrounds.html
      @@ -177,7 +177,7 @@ 

      の背景とスカイボックス

      }

      カメラを回転できるようにコントロールを追加してみましょう。

      -
      import {OrbitControls} from './resources/threejs/r119/examples/jsm/controls/OrbitControls.js';
      +
      import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
       
      const fov = 75;
       const aspect = 2;  // the canvas default
      @@ -247,4 +247,4 @@ 

      の背景とスカイボックス

      - \ No newline at end of file + diff --git a/manual/ja/canvas-textures.html b/manual/ja/canvas-textures.html index a12265f7ccdd45..317b4db8dfc22c 100644 --- a/manual/ja/canvas-textures.html +++ b/manual/ja/canvas-textures.html @@ -253,8 +253,8 @@

      のキャンバステクスチャ

      +makePerson(+3, 32, 'Red Menace', 'red');

      残作業はカメラを動かせるように OrbitControls を追加します。

      -
      import * as THREE from '/build/three.module.js';
      -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      +
      import * as THREE from 'three';
      ++import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
       
      const fov = 75;
       const aspect = 2;  // the canvas default
      diff --git a/manual/ja/custom-geometry.html b/manual/ja/custom-geometry.html
      deleted file mode 100644
      index a5e9db96ecce7a..00000000000000
      --- a/manual/ja/custom-geometry.html
      +++ /dev/null
      @@ -1,433 +0,0 @@
      -
      -    
      -    のカスタムジオメトリ
      -    
      -    
      -    
      -    
      -    
      -    
      -    
      -
      -    
      -    
      -
      -
      -
      -
      -
      -  
      -  
      -    
      -
      -

      のカスタムジオメトリ

      -
      -
      -
      -
      -NOTE! This article is deprecated. Three.js r125 -removed support for Geometry. Please refer to -the article on custom BufferGeometry. -
      - - -

      前回の記事ではTHREE.jsにある基本ジオメトリであるプリミティブジオメトリを紹介しました。この記事ではカスタムジオメトリを紹介します。

      -

      まず最初に断っておきますが、本格的な3Dコンテンツを作りたい場合は -3Dモデリングツールを使うべきです。3Dモデリングツールには -Blender, -Maya, -3D Studio Max, -Cinema4Dなどがあります。

      -

      これらのモデリングツールでモデルを作ってからgLTF.obj -にエクスポートしたものをTHREE.jsにインポートすることもできます。 -どのモデリングツールも習得にそれなりの時間がかかります。

      -

      ここまで簡単なカスタムジオメトリであれば大袈裟なモデリングツールを使わずにTHREE.jsのコードで作れます。

      -

      まずは立方体を作ってみましょう。THREE.jsのBoxGeometryBoxGeometryを使えば一発で -立方体を作れますが、簡単な例としてカスタムジオメトリで作ってみましょう。

      -

      THREE.jsにはカスタムジオメトリを作る方法が2つあります。1つ目はGeometryクラスで2つ目がBufferGeometryです。 -それぞれに利点があります。Geometryは簡単に使えますが遅く、メモリをより消費します。1000個以下の三角形を作る際は -よいですが、10,000個の三角形を作る時にはBufferGeometryが良いでしょう。

      -

      BufferGeometryは使うのが難しいですがメモリの消費が小さく速いです。1万個の三角形を作る時にはこれを使いましょう。

      -

      ただし変形などがない場合はそれほど変わりません。Geometryが遅いというのはジオメトリが編集された -場合に遅いと言う意味で、もし編集が必要なくそれほど大きくなければこの両者はあまり変わりません。 -この記事では両方紹介します。最初は簡単なGeometryを紹介します。

      -

      まずはGeometryで立方体を作ってみましょう。レスポンシブの記事の例を使います。

      -

      BoxGeometryを使っている部分を消してGeometryで置き換えてみます。

      -
      -const boxWidth = 1;
      --const boxHeight = 1;
      --const boxDepth = 1;
      --const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);
      -+const geometry = new THREE.Geometry();
      -
      -

      まずは8つの角を追加してみます。

      -
      - -

      中心の周囲にこのようにvertexを追加します。(訳註:vertexとはジオメトリを構成する頂点です。3つの頂点を結ぶことでface=面ができます)。

      -
      const geometry = new THREE.Geometry();
      -+geometry.vertices.push(
      -+  new THREE.Vector3(-1, -1,  1),  // 0
      -+  new THREE.Vector3( 1, -1,  1),  // 1
      -+  new THREE.Vector3(-1,  1,  1),  // 2
      -+  new THREE.Vector3( 1,  1,  1),  // 3
      -+  new THREE.Vector3(-1, -1, -1),  // 4
      -+  new THREE.Vector3( 1, -1, -1),  // 5
      -+  new THREE.Vector3(-1,  1, -1),  // 6
      -+  new THREE.Vector3( 1,  1, -1),  // 7
      -+);
      -
      -

      vertexを結んで三角形を作ります。1面につき2つの三角形を使います。 -(訳註:立方体は6つの正方形で構成されます。1つの正方形は2つの三角形で構成されます。)

      -
      - -

      vertexを結んで三角形を作るにはFace3を使います。Face3の3は3つのvertexでfaceを作ると言う意味です。

      -

      vertexを指定する順序は重要です。faceには表面と裏面があります。立方体を構成するfaceの -面が外に向くためには反時計回りの順序でvertexを指定します。

      -
      - -

      同じように12個の三角形を作って立方体を作ります。

      -
      geometry.faces.push(
      -  // front
      -  new THREE.Face3(0, 3, 2),
      -  new THREE.Face3(0, 1, 3),
      -  // right
      -  new THREE.Face3(1, 7, 3),
      -  new THREE.Face3(1, 5, 7),
      -  // back
      -  new THREE.Face3(5, 6, 7),
      -  new THREE.Face3(5, 4, 6),
      -  // left
      -  new THREE.Face3(4, 2, 6),
      -  new THREE.Face3(4, 0, 2),
      -  // top
      -  new THREE.Face3(2, 7, 6),
      -  new THREE.Face3(2, 3, 7),
      -  // bottom
      -  new THREE.Face3(4, 1, 0),
      -  new THREE.Face3(4, 5, 1),
      -);
      -
      -

      ちょっとコードを変えるだけで動きます。

      -

      これらの立方体は前に使ったBoxGeometryの立方体より2倍のサイズがあります。 -全体が映るようにカメラを引きます。

      -
      const fov = 75;
      -const aspect = 2;  // the canvas default
      -const near = 0.1;
      --const far = 5;
      -+const far = 100;
      -const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
      --camera.position.z = 2;
      -+camera.position.z = 5;
      -
      -

      わかりやすいようにそれぞれを離して色を変えます。

      -
      const cubes = [
      --  makeInstance(geometry, 0x44aa88,  0),
      --  makeInstance(geometry, 0x8844aa, -2),
      --  makeInstance(geometry, 0xaa8844,  2),
      -+  makeInstance(geometry, 0x44FF44,  0),
      -+  makeInstance(geometry, 0x4444FF, -4),
      -+  makeInstance(geometry, 0xFF4444,  4),
      -];
      -
      -

      この状態ではnormal(法線)がないのでライトが当たりません。 -そこでライトが必要ないマテリアルに変えます。

      -
      function makeInstance(geometry, color, x) {
      --  const material = new THREE.MeshPhongMaterial({color});
      -+  const material = new THREE.MeshBasicMaterial({color});
      -
      -  const cube = new THREE.Mesh(geometry, material);
      -  scene.add(cube);
      -
      -  ...
      -
      -

      これで自分で作った立方体ができました。

      -

      - -

      -

      それぞれのfaceに対してcolorを設定することで色を変えられます。

      -
      geometry.faces[ 0].color = geometry.faces[ 1].color = new THREE.Color('red');
      -geometry.faces[ 2].color = geometry.faces[ 3].color = new THREE.Color('yellow');
      -geometry.faces[ 4].color = geometry.faces[ 5].color = new THREE.Color('green');
      -geometry.faces[ 6].color = geometry.faces[ 7].color = new THREE.Color('cyan');
      -geometry.faces[ 8].color = geometry.faces[ 9].color = new THREE.Color('blue');
      -geometry.faces[10].color = geometry.faces[11].color = new THREE.Color('magenta');
      -
      -

      マテリアルにはvertexColorsを使うように設定します。

      -
      -const material = new THREE.MeshBasicMaterial({color});
      -+const material = new THREE.MeshBasicMaterial({vertexColors: true});
      -
      -

      - -

      -

      vertexcolorsを設定すればvertexそれぞれに色を設定できます。 -3つのvertexに対して3つの色を設定してみます。

      -
      geometry.faces.forEach((face, ndx) => {
      -  face.vertexColors = [
      -    (new THREE.Color()).setHSL(ndx / 12      , 1, 0.5),
      -    (new THREE.Color()).setHSL(ndx / 12 + 0.1, 1, 0.5),
      -    (new THREE.Color()).setHSL(ndx / 12 + 0.2, 1, 0.5),
      -  ];
      -});
      -
      -

      - -

      -

      ライトを適用する時はnormalが必要です。normalはfaceの向きを示すベクトルです。 -色を設定したのと同じようにそれぞれのfaceにのnormalを設定します。

      -
      face.normal = new THREE.Vector3(...)
      -
      -

      vertexNormalsでvertexに対してnormalを設定することもできます。

      -
      face.vertexNormals = [
      -  new THREE.Vector3(...),
      -  new THREE.Vector3(...),
      -  new THREE.Vector3(...),
      -]
      -
      -

      しかしTHREE.jsに自動的にnormalを設定してもらうこともできます。 -faceのnormalに対してはGeometry.computeFaceNormalsを使います。

      -
      geometry.computeFaceNormals();
      -
      -

      vertex colorを消してマテリアルをMeshPhongMaterialに戻します。

      -
      -const material = new THREE.MeshBasicMaterial({vertexColors: true});
      -+const material = new THREE.MeshPhongMaterial({color});
      -
      -

      ライトが適用できました。

      -

      - -

      -

      vertex normalsを使うことで滑らかな表面を表現できます。 -Geometry.computeVertexNormalsを設定してください。

      -
      -geometry.computeFaceNormals();
      -+geometry.computeVertexNormals();
      -
      -

      ここまで説明しておいてなんですが立方体はvertex normalの例としてはあまり適切ではありません。 -なぜなら1つのvertex normalがそのvertexが接する全ての面に依存しているからです。

      -

      - -

      -

      テクスチャの座標(UVと呼ばれる)を設定するにはfacesに対応した配列を用意します。 -Geometry.faceVertexUvsで設定します。 -これらのテクニックを使うと以下のような立方体ができます。

      -
      geometry.faceVertexUvs[0].push(
      -  // front
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
      -  // right
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
      -  // back
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
      -  // left
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
      -  // top
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
      -  // bottom
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
      -);
      -
      -

      faceVertexUvsは配列の配列によってUV座標がレイヤー状に格納されています。それぞれの配列にはUV座標が入っています。デフォルトではレイヤー数は1です。もう1つレイヤーを追加してみます。

      -

      マテリアルにテクスチャを追加 してください。

      -
      -geometry.computeVertexNormals();
      -+geometry.computeFaceNormals();
      -
      -+const loader = new THREE.TextureLoader();
      -+const texture = loader.load('resources/images/star.png');
      -
      -function makeInstance(geometry, color, x) {
      --  const material = new THREE.MeshPhongMaterial({color});
      -+  const material = new THREE.MeshPhongMaterial({color, map: texture});
      -
      -  const cube = new THREE.Mesh(geometry, material);
      -  scene.add(cube);
      -
      -  ...
      -
      -

      - -

      -

      OKです。単純なハイトマップをterrain meshから作りましょう。

      -

      terrain meshからつくるハイトマップとは詰まるところ二次元配列です。配列の数値は高さの表現に使います。二次元配列を取得するには画像編集ソフトで適当な画像を作ってしまうのが楽です。96x96の画像を作ってみました。

      -
      - -

      このPNG画像をロードして二次元配列にしてハイトマップとして使います。 -画像をロードするにはImageLoaderを使います。

      -
      const imgLoader = new THREE.ImageLoader();
      -imgLoader.load('resources/images/heightmap-96x64.png', createHeightmap);
      -
      -function createHeightmap(image) {
      -  // extract the data from the image by drawing it to a canvas
      -  // and calling getImageData
      -  const ctx = document.createElement('canvas').getContext('2d');
      -  const {width, height} = image;
      -  ctx.canvas.width = width;
      -  ctx.canvas.height = height;
      -  ctx.drawImage(image, 0, 0);
      -  const {data} = ctx.getImageData(0, 0, width, height);
      -
      -  const geometry = new THREE.Geometry();
      -
      -

      画像から二次元配列を取り出しました。次に粗い正方形で区切られたグリッドを作ります。このグリッドはそれぞれのピクセルの中心点を四隅とした正方形で構成されています。

      -
      - -

      それぞれの正方形に対して5つのvertexを作ります。4つは正方形の四隅のピクセル値で、のこり1つはその四隅の平均です。

      -
      const cellsAcross = width - 1;
      -const cellsDeep = height - 1;
      -for (let z = 0; z < cellsDeep; ++z) {
      -  for (let x = 0; x < cellsAcross; ++x) {
      -    // compute row offsets into the height data
      -    // we multiply by 4 because the data is R,G,B,A but we
      -    // only care about R
      -    const base0 = (z * width + x) * 4;
      -    const base1 = base0 + (width * 4);
      -
      -    // look up the height for the for points
      -    // around this cell
      -    const h00 = data[base0] / 32;
      -    const h01 = data[base0 + 4] / 32;
      -    const h10 = data[base1] / 32;
      -    const h11 = data[base1 + 4] / 32;
      -    // compute the average height
      -    const hm = (h00 + h01 + h10 + h11) / 4;
      -
      -    // the corner positions
      -    const x0 = x;
      -    const x1 = x + 1;
      -    const z0 = z;
      -    const z1 = z + 1;
      -
      -    // remember the first index of these 5 vertices
      -    const ndx = geometry.vertices.length;
      -
      -    // add the 4 corners for this cell and the midpoint
      -    geometry.vertices.push(
      -      new THREE.Vector3(x0, h00, z0),
      -      new THREE.Vector3(x1, h01, z0),
      -      new THREE.Vector3(x0, h10, z1),
      -      new THREE.Vector3(x1, h11, z1),
      -      new THREE.Vector3((x0 + x1) / 2, hm, (z0 + z1) / 2),
      -    );
      -
      -

      この5つのvertexを元に4つの三角形を作ります。

      -
      - -
          // create 4 triangles
      -    geometry.faces.push(
      -      new THREE.Face3(ndx + 0, ndx + 4, ndx + 1),
      -      new THREE.Face3(ndx + 1, ndx + 4, ndx + 3),
      -      new THREE.Face3(ndx + 3, ndx + 4, ndx + 2),
      -      new THREE.Face3(ndx + 2, ndx + 4, ndx + 0),
      -    );
      -
      -    // add the texture coordinates for each vertex of each face
      -    const u0 = x / cellsAcross;
      -    const v0 = z / cellsDeep;
      -    const u1 = (x + 1) / cellsAcross;
      -    const v1 = (z + 1) / cellsDeep;
      -    const um = (u0 + u1) / 2;
      -    const vm = (v0 + v1) / 2;
      -    geometry.faceVertexUvs[0].push(
      -      [ new THREE.Vector2(u0, v0), new THREE.Vector2(um, vm), new THREE.Vector2(u1, v0) ],
      -      [ new THREE.Vector2(u1, v0), new THREE.Vector2(um, vm), new THREE.Vector2(u1, v1) ],
      -      [ new THREE.Vector2(u1, v1), new THREE.Vector2(um, vm), new THREE.Vector2(u0, v1) ],
      -      [ new THREE.Vector2(u0, v1), new THREE.Vector2(um, vm), new THREE.Vector2(u0, v0) ],
      -    );
      -  }
      -}
      -
      -

      仕上げです。

      -
        geometry.computeFaceNormals();
      -
      -  // center the geometry
      -  geometry.translate(width / -2, 0, height / -2);
      -
      -  const loader = new THREE.TextureLoader();
      -  const texture = loader.load('resources/images/star.png');
      -
      -  const material = new THREE.MeshPhongMaterial({color: 'green', map: texture});
      -
      -  const cube = new THREE.Mesh(geometry, material);
      -  scene.add(cube);
      -}
      -
      -

      すこし視点を変えるとみやすくなります。

      - -
      import * as THREE from '/build/three.module.js';
      -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      -
      -
      const fov = 75;
      -const aspect = 2;  // the canvas default
      -const near = 0.1;
      --const far = 100;
      -+const far = 200;
      -const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
      --camera.position.z = 5;
      -+camera.position.set(20, 20, 20);
      -
      -+const controls = new OrbitControls(camera, canvas);
      -+controls.target.set(0, 0, 0);
      -+controls.update();
      -
      -

      ライトも2つ入れましょう。

      -
      -{
      -+function addLight(...pos) {
      -  const color = 0xFFFFFF;
      -  const intensity = 1;
      -  const light = new THREE.DirectionalLight(color, intensity);
      --  light.position.set(-1, 2, 4\);
      -+  light.position.set(...pos);
      -  scene.add(light);
      -}
      -
      -+addLight(-1, 2, 4);
      -+addLight(1, 2, -2);
      -
      -

      立方体を回転を止めました。

      -

      - -

      -

      Geometryの使用方法をおわかりいただけたでしょうか?

      -

      この記事ではBufferGeometryについて説明します。

      - -
      -
      -
      - - - - - - - - \ No newline at end of file diff --git a/manual/ja/fundamentals.html b/manual/ja/fundamentals.html index cb0939e2369e86..f37cd1bb6a45d1 100644 --- a/manual/ja/fundamentals.html +++ b/manual/ja/fundamentals.html @@ -52,7 +52,7 @@

      の基礎知識

      Three.jsはcanvasに描画するため、canvasをthree.jsに渡す必要があります。

      <script type="module">
      -import * as THREE from '../../build/three.module.js';
      +import * as THREE from 'three';
       
       function main() {
         const canvas = document.querySelector('#c');
      @@ -256,7 +256,7 @@ 

      es6モジュール、three.js、およびフォルダー構造

      両方とも以下に例を示します。

      <script type="module">
      -import * as THREE from '../../build/three.module.js';
      +import * as THREE from 'three';
       
       ...
       
      @@ -303,11 +303,11 @@ 

      es6モジュール、three.js、およびフォルダー構造

      同じフォルダ構造を使用すると、importしたthreeとexampleライブラリは両方とも同じthree.module.jsを参照します。

      import * as THREE from './someFolder/build/three.module.js';
      -import {OrbitControls} from './someFolder/examples/jsm/controls/OrbitControls.js';
      +import {OrbitControls} from './someFolder/addons/controls/OrbitControls.js';
       

      これにはCDNを使用する場合も含まれます。 three.modules.js のパスが /build/three.modules.js のようになってる事を確認して下さい。例えば

      import * as THREE from 'https://unpkg.com/three@0.108.0/build/three.module.js';
      -import {OrbitControls} from 'https://unpkg.com/three@0.108.0/examples/jsm/controls/OrbitControls.js';
      +import {OrbitControls} from 'https://unpkg.com/three@0.108.0/addons/controls/OrbitControls.js';
       
      diff --git a/manual/ja/lights.html b/manual/ja/lights.html index c3ea80f2656e53..0005a4ef353463 100644 --- a/manual/ja/lights.html +++ b/manual/ja/lights.html @@ -47,8 +47,8 @@

      のライト

      次に OrbitControls を追加します。 OrbitControls は、カメラをある点を中心に軌道を回転できます。 OrbitControls はthree.jsのオプション機能なので、importする必要があります。

      -
      import * as THREE from '/build/three.module.js';
      -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      +
      import * as THREE from 'three';
      ++import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
       

      これでOrbitControlsを利用できます。 OrbitControls にカメラと入力イベントを取得するDOM要素を渡します。

      @@ -379,9 +379,9 @@

      RectAreaLight

      RectAreaLight を使用するには、three.jsから追加のimportが必要です。 ライトを可視化するために RectAreaLightHelper をimportします。

      -
      import * as THREE from '/build/three.module.js';
      -+import {RectAreaLightUniformsLib} from '/examples/jsm/lights/RectAreaLightUniformsLib.js';
      -+import {RectAreaLightHelper} from '/examples/jsm/helpers/RectAreaLightHelper.js';
      +
      import * as THREE from 'three';
      ++import {RectAreaLightUniformsLib} from 'three/addons/lights/RectAreaLightUniformsLib.js';
      ++import {RectAreaLightHelper} from 'three/addons/helpers/RectAreaLightHelper.js';
       

      RectAreaLightUniformsLib.init を呼び出します。

      function main() {
      diff --git a/manual/ja/load-gltf.html b/manual/ja/load-gltf.html
      index 3dd226eea8aa8f..f6f0a660a7ad96 100644
      --- a/manual/ja/load-gltf.html
      +++ b/manual/ja/load-gltf.html
      @@ -106,10 +106,10 @@ 

      でGLFTファイルを読み込む

      自動フレーミングのコードは以前のままです。

      また OBJLoader を取り除き GLTFLoader を含める必要があります。

      -
      -import {LoaderSupport} from '/examples/jsm/loaders/LoaderSupport.js';
      --import {OBJLoader} from '/examples/jsm/loaders/OBJLoader.js';
      --import {MTLLoader} from '/examples/jsm/loaders/MTLLoader.js';
      -+import {GLTFLoader} from '/examples/jsm/loaders/GLTFLoader.js';
      +
      -import {LoaderSupport} from 'three/addons/loaders/LoaderSupport.js';
      +-import {OBJLoader} from 'three/addons/loaders/OBJLoader.js';
      +-import {MTLLoader} from 'three/addons/loaders/MTLLoader.js';
      ++import {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';
       

      実行すると以下になりました。

      @@ -249,7 +249,7 @@

      でGLFTファイルを読み込む

      - cars = root.getObjectByName('Cars'); + const loadedCars = root.getObjectByName('Cars'); + const fixes = [ -+ { prefix: 'Car_08', rot: [Math.PI * .5, 0, Math.PI +* .5], }, ++ { prefix: 'Car_08', rot: [Math.PI * .5, 0, Math.PI * .5], }, + { prefix: 'CAR_03', rot: [0, Math.PI, 0], }, + { prefix: 'Car_04', rot: [0, Math.PI, 0], }, + ]; @@ -643,4 +643,4 @@

      でGLFTファイルを読み込む

      - \ No newline at end of file + diff --git a/manual/ja/load-obj.html b/manual/ja/load-obj.html index 04709afc629fe5..9b4263fa1c0452 100644 --- a/manual/ja/load-obj.html +++ b/manual/ja/load-obj.html @@ -52,7 +52,7 @@

      でOBJファイルを読み込む

      ライティングの記事 にあるディレクショナルライティングの例から始めて、半球ライティングの例と組み合わせて HemisphereLightDirectionalLight を1つ作る事にしました。その結果として HemisphereLight は1つ、DirectionalLight は1つになりました。 また、ライトの調整に関連する全てのGUIを削除しました。シーンに追加していたキューブとスフィアも削除しました。

      まず最初に OBJLoader のローダーをコードに含める必要があります。

      -
      import {OBJLoader} from '/examples/jsm/loaders/OBJLoader.js';
      +
      import {OBJLoader} from 'three/addons/loaders/OBJLoader.js';
       

      次にOBJファイルをロードするために OBJLoader のインスタンスを作成し、OBJファイルのURLを渡し、ロードされたモデルをシーンに追加するコールバックを渡します。

      {
      @@ -124,10 +124,10 @@ 

      でOBJファイルを読み込む

      テクスチャを利用できるようになったのでMTLファイルをロードします。 MTLLoader をimportする必要があります。

      -
      import * as THREE from '/build/three.module.js';
      -import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      -import {OBJLoader} from '/examples/jsm/loaders/OBJLoader.js';
      -+import {MTLLoader} from '/examples/jsm/loaders/MTLLoader.js';
      +
      import * as THREE from 'three';
      +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
      +import {OBJLoader} from 'three/addons/loaders/OBJLoader.js';
      ++import {MTLLoader} from 'three/addons/loaders/MTLLoader.js';
       

      まず、MTLファイルをロードします。 読込後にロードしたマテリアルを OBJLoaderに設定して、OBJLoader でOBJファイルをロードします。

      diff --git a/manual/ja/multiple-scenes.html b/manual/ja/multiple-scenes.html index 810990656af875..82035a3f230553 100644 --- a/manual/ja/multiple-scenes.html +++ b/manual/ja/multiple-scenes.html @@ -416,7 +416,7 @@

      HTML Datasetを使う

      各要素にコントロールを追加する

      TrackballControls のようなインタラクティブな要素を追加するのは簡単です。 最初にコントロール用のスクリプトを追加します。

      -
      import {TrackballControls} from '/examples/jsm/controls/TrackballControls.js';
      +
      import {TrackballControls} from 'three/addons/controls/TrackballControls.js';
       

      そして TrackballControls を各シーンに追加し、シーンに関連付けられた要素を渡します。

      -function makeScene() {
      diff --git a/manual/ja/offscreencanvas.html b/manual/ja/offscreencanvas.html
      index 9028e218ea221d..3b972b9d103e24 100644
      --- a/manual/ja/offscreencanvas.html
      +++ b/manual/ja/offscreencanvas.html
      @@ -236,7 +236,7 @@ 

      のOffscreenCanvas

      shared-cubes.jsoffscreencanvas-worker-cubes.js は前の offscreencanvas-cubes.js ファイルを分割したものです。

      まず offscreencanvas-cubes.js を全て shared-cube.js にコピーします。 次にHTMLファイルには既に main があり、initstate をエクスポートする必要があるため main の名前を init に変更します。

      -
      import * as THREE from '../../build/three.module.js';
      +
      import * as THREE from 'three';
       
       -const state = {
       +export const state = {
      @@ -570,7 +570,7 @@ 

      のOffscreenCanvas

      ある時はメインページで実行され、全てのイベント、関連するプロパティ値をWorkerに渡します。 また、ある時はWorkerで実行され、全てのイベント、DOMイベントと同じ構造をもつイベントをメインページに渡すので、OrbitControlsは違いを見分けられません。

      ここにWorker部分のコードがあります。

      -
      import {EventDispatcher} from '../../build/three.module.js';
      +
      import {EventDispatcher} from 'three';
       
       class ElementProxyReceiver extends EventDispatcher {
         constructor() {
      @@ -640,8 +640,8 @@ 

      のOffscreenCanvas

      };

      共有のthree.jsコードでは OrbitControls をインポートして設定する必要があります。

      -
      import * as THREE from '../../build/three.module.js';
      -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      +
      import * as THREE from 'three';
      ++import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
       
       export function init(data) {
       -  const {canvas} = data;
      diff --git a/manual/ja/optimize-lots-of-objects-animated.html b/manual/ja/optimize-lots-of-objects-animated.html
      index 44ed5428668d96..21518620b4c3fd 100644
      --- a/manual/ja/optimize-lots-of-objects-animated.html
      +++ b/manual/ja/optimize-lots-of-objects-animated.html
      @@ -321,10 +321,10 @@ 

      でアニメーションする多くのオブジェクトを最適化

      または簡単にカスタムアニメーションのコードを書く事ができますが、 オリジナルのwebgl globeではアニメーションライブラリを使っているので合わせましょう。

      アニメーションライブラリをimportする必要があります。

      -
      import * as THREE from '/build/three.module.js';
      -import * as BufferGeometryUtils from '/examples/jsm/utils/BufferGeometryUtils.js';
      -import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      -+import {TWEEN} from '/examples/jsm/libs/tween.min.js';
      +
      import * as THREE from 'three';
      +import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js';
      +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
      ++import {TWEEN} from 'three/addons/libs/tween.min.js';
       

      そして、影響を与えるアニメーションの Tween を作成します。

      // show the selected data, hide the rest
      diff --git a/manual/ja/optimize-lots-of-objects.html b/manual/ja/optimize-lots-of-objects.html
      index 2907d4fb9c0932..09a99a6eaeed4c 100644
      --- a/manual/ja/optimize-lots-of-objects.html
      +++ b/manual/ja/optimize-lots-of-objects.html
      @@ -366,7 +366,7 @@ 

      で多くのオブジェクトを最適化

      今回は1つ1つのジオメトリを新しく作成し、各ボックスジオメトリの頂点を移動するために applyMatrix を使用するので、2回ではなく1回にした方が良いかもしれません。

      最後に全てのジオメトリの配列を BufferGeometryUtils.mergeBufferGeometries に渡します。 また BufferGeometryUtils も含める必要があります。

      -
      import * as BufferGeometryUtils from '/examples/jsm/utils/BufferGeometryUtils.js';
      +
      import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js';
       

      少なくとも私のマシンでは毎秒60フレームになりました。

      diff --git a/manual/ja/post-processing.html b/manual/ja/post-processing.html index 96cae9a50f0223..9f6ae79c450d25 100644 --- a/manual/ja/post-processing.html +++ b/manual/ja/post-processing.html @@ -95,10 +95,10 @@

      renderToScree

      filmPass は最後のPassなので、renderToScreen プロパティをtrueに設定し、キャンバスにレンダリングするようにします。 この設定がないと次のレンダーターゲットにレンダリングされます。

      これらのクラスを使用するには、以下をインポートする必要があります。

      -
      import {EffectComposer} from '/examples/jsm/postprocessing/EffectComposer.js';
      -import {RenderPass} from '/examples/jsm/postprocessing/RenderPass.js';
      -import {BloomPass} from '/examples/jsm/postprocessing/BloomPass.js';
      -import {FilmPass} from '/examples/jsm/postprocessing/FilmPass.js';
      +
      import {EffectComposer} from 'three/addons/postprocessing/EffectComposer.js';
      +import {RenderPass} from 'three/addons/postprocessing/RenderPass.js';
      +import {BloomPass} from 'three/addons/postprocessing/BloomPass.js';
      +import {FilmPass} from 'three/addons/postprocessing/FilmPass.js';
       

      ほとんどのポストプロセスには EffectComposer.jsRenderPass.js が必須です。

      最後に WebGLRenderer.render の代わりに EffectComposer.render を使用し、EffectComposer にキャンバスのサイズを合わせます。

      @@ -157,7 +157,7 @@

      renderToScree

      これでどのように設定するか、かなり明確になりました。

      これらの値を設定する簡単なGUIを作ってみましょう。

      -
      import {GUI} from '/examples/jsm/libs/lil-gui.module.min.js';
      +
      import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
       

      そして

      const gui = new GUI();
      diff --git a/manual/ja/prerequisites.html b/manual/ja/prerequisites.html
      index c6b53bc1eb4a94..776aa6403b37a4 100644
      --- a/manual/ja/prerequisites.html
      +++ b/manual/ja/prerequisites.html
      @@ -43,7 +43,7 @@ 

      es6モジュール

      es6モジュールはスクリプトの中で import キーワード、または <script type="module"> タグを使用してインラインでロードできます。 以下に両方の使用​​例があります。

      <script type="module">
      -import * as THREE from '../../build/three.module.js';
      +import * as THREE from 'three';
       
       ...
       
      diff --git a/manual/ja/rendering-on-demand.html b/manual/ja/rendering-on-demand.html
      index 71ad29db333843..6c889ab374cafb 100644
      --- a/manual/ja/rendering-on-demand.html
      +++ b/manual/ja/rendering-on-demand.html
      @@ -44,8 +44,8 @@ 

      で要求されたレンダリング

      変更にはテクスチャやモデルの読込完了、外部ソースからのデータ受取、ユーザーによる設定やカメラ調整などその他の関連する入力などが含まれます。

      レスポンシブデザインの記事を例に要求に応じてレンダリングするように修正してみましょう。

      最初に OrbitControls を追加します。これで何かの変更を反映してレンダリングする事ができます。

      -
      import * as THREE from '/build/three.module.js';
      -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      +
      import * as THREE from 'three';
      ++import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
       

      次に以下のように設定します。

      const fov = 75;
      @@ -162,9 +162,9 @@ 

      で要求されたレンダリング

      シンプルなlil-guiを追加し、GUIで値の変更時にレンダリングを要求してみましょう。

      -
      import * as THREE from '/build/three.module.js';
      -import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
      -+import {GUI} from '/examples/jsm/libs/lil-gui.module.min.js';
      +
      import * as THREE from 'three';
      +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
      ++import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
       

      各キューブの色と×スケールを設定できるようにしましょう。 色を設定するには照明の記事で作成した ColorGUIHelper を使います。

      diff --git a/manual/ja/textures.html b/manual/ja/textures.html index 31590ffb38ce3e..ebc1abf1e85b88 100644 --- a/manual/ja/textures.html +++ b/manual/ja/textures.html @@ -438,7 +438,7 @@

      テクスチャ });

      ここでも、簡単なインターフェースを提供するためにlil-guiを使います。

      -
      import {GUI} from '/examples/jsm/libs/lil-gui.module.min.js';
      +
      import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
       

      以前のlil-guiの例でしたように、lil-guiに度数で操作できるオブジェクトを与え、 ラジアン単位でプロパティを設定する簡単なクラスを使います。

      diff --git a/manual/ja/transparency.html b/manual/ja/transparency.html index 4af9ddb5000515..012164ce92f29d 100644 --- a/manual/ja/transparency.html +++ b/manual/ja/transparency.html @@ -342,9 +342,9 @@

      の透過

      .onChange(requestRenderIfNotRequested);

      もちろん、lil-guiを含める必要があります。

      -
      import * as THREE from './resources/three/r119/build/three.module.js';
      -import {OrbitControls} from './resources/threejs/r119/examples/jsm/controls/OrbitControls.js';
      -+import {GUI} from '/examples/jsm/libs/lil-gui.module.min.js';
      +
      import * as THREE from 'three';
      +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
      ++import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
       

      その結果がこちらです。

      @@ -378,4 +378,4 @@

      の透過

      - \ No newline at end of file + diff --git a/manual/ja/webxr.html b/manual/ja/webxr-basics.html similarity index 100% rename from manual/ja/webxr.html rename to manual/ja/webxr-basics.html diff --git a/manual/ko/align-html-elements-to-3d.html b/manual/ko/align-html-elements-to-3d.html index 8820039f33b3e2..924aacbcfb7322 100644 --- a/manual/ko/align-html-elements-to-3d.html +++ b/manual/ko/align-html-elements-to-3d.html @@ -47,8 +47,8 @@

      HTML 요소를 3D로 정렬하기

      이 글에서는 맨 마지막 방법에 대해 다룰 겁니다.

      간단한 것부터 시작해보죠. 원시 모델 위에 이름표를 붙인 3D 장면을 구현할 겁니다. 예제는 반응형 디자인에 관한 글의 예제를 수정해 쓰도록 하죠.

      여기에 OrbitControls를 넣습니다. 조명에 관한 글에서 다뤘었죠.

      -
      import * as THREE from '/build/three.module.js';
      -+import { OrbitControls } from '/examples/jsm/controls/OrbitControls.js';
      +
      import * as THREE from 'three';
      ++import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
       
      const controls = new OrbitControls(camera, canvas);
       controls.target.set(0, 0, 0);
      @@ -590,9 +590,9 @@ 

      HTML 요소를 3D로 정렬하기

      ...

      마지막으로 어떤 값이 적당한지 알기 어려우니 이 값을 조정할 수 있도록 GUI를 추가합니다.

      -
      import * as THREE from '/build/three.module.js';
      -import { OrbitControls } from '/examples/jsm/controls/OrbitControls.js';
      -+import { GUI } from '/examples/jsm/libs/lil-gui.module.min.js';
      +
      import * as THREE from 'three';
      +import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
      ++import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
       
      +const settings = {
       +  minArea: 20,
      diff --git a/manual/ko/backgrounds.html b/manual/ko/backgrounds.html
      index 6cac30ca4488bf..4ba90202901d40 100644
      --- a/manual/ko/backgrounds.html
      +++ b/manual/ko/backgrounds.html
      @@ -183,7 +183,7 @@ 

      배경과 하늘 상자

      }

      카메라도 조작이 가능하도록 만듭니다.

      -
      import { OrbitControls } from '/examples/jsm/controls/OrbitControls.js';
      +
      import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
       
      const fov = 75;
       const aspect = 2;  // canvas 기본값
      diff --git a/manual/ko/canvas-textures.html b/manual/ko/canvas-textures.html
      index 5eceff7f92f4b4..ddf4542606ceca 100644
      --- a/manual/ko/canvas-textures.html
      +++ b/manual/ko/canvas-textures.html
      @@ -237,8 +237,8 @@ 

      캔버스 텍스처

      +makePerson(+3, 32, 'Red Menace', 'red');

      마지막으로 OrbitControls를 넣어 카메라를 움직일 수 있도록 합니다.

      -
      import * as THREE from '/build/three.module.js';
      -+import { OrbitControls } from '/examples/jsm/controls/OrbitControls.js';
      +
      import * as THREE from 'three';
      ++import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
       
      const fov = 75;
       const aspect = 2;  // 캔버스 기본값
      diff --git a/manual/ko/custom-geometry.html b/manual/ko/custom-geometry.html
      deleted file mode 100644
      index 0e637d5d82a2f4..00000000000000
      --- a/manual/ko/custom-geometry.html
      +++ /dev/null
      @@ -1,451 +0,0 @@
      -
      -    
      -    사용자 지정 Geometry(Custom BufferGeometry)
      -    
      -    
      -    
      -    
      -    
      -    
      -    
      -
      -    
      -    
      -
      -
      -
      -
      -
      -    
      -  
      -  
      -    
      -
      -

      사용자 지정 Geometry(Custom BufferGeometry)

      -
      -
      -
      -
      -NOTE! This article is deprecated. Three.js r125 -removed support for Geometry. Please refer to -the article on custom BufferGeometry. -
      - - -

      이전 글에서는 Three.js의 내장 원시 모델에 -대해 살펴보았죠. 이 글에서는 이런 모델, geometry를 직접 만들어 볼 것입니다.

      -

      거듭 이야기하지만, 정말 진지하게 3D 컨텐츠를 만들 생각이라면 -블렌더(Blender), -마야(Maya), -3D Studio Max, -시네마4D(Cinema4D) 등의 3D 모델링 -프로그램을 사용하는 것이 좋습니다. 모델을 만들고 gLTF나 -.obj 포멧으로 저장하여 프로젝트에서 불러오는 -것이죠. 어떤 프로그램을 선택하든 튜토리얼에는 유용한 내용이 많으니, 2주에서 -3주 정도는 해당 프로그램의 튜토리얼을 익히는 데 투자하기 바랍니다.

      -

      하지만 때로는 모델링 프로그램을 쓰는 것보다 직접 3D geometry를 -만드는 게 유리할 수 있을 겁니다.

      -

      먼저 정육면체를 하나 만들어보겠습니다. 이미 원시 모델에 BoxGeometry와 -BoxGeometry가 있긴 하지만, 기본 개념을 이해하는 데는 간단한 게 -훨씬 효과적일 테니까요.

      -

      Three.js에서 사용자 지정 geometry는 Geometry 또는 BufferGeometry, -2가지 클래스를 이용해 만들 수 있습니다. Geometry는 분명 사용하기에는 -편하지만 느리고 메모리도 많이 차지합니다. 삼각형 천 개 정도까지야 그냥 -써도 나쁠 것이 없지만, 만 개가 넘어간다면 BufferGeometry를 고려하는 -것이 좋죠.

      -

      당연하게도 BufferGeometry는 훨씬 쓰기 어렵지만, 비교적 메모리도 덜 차지하고 -훨씬 빠릅니다. 대략 구상하기에 삼각형을 10000개 이상 쓰겠다 싶으면 BufferGeometry를 -고려하기 바랍니다.

      -

      아까 Geometry가 느리다고 했는데, 이는 처음 로드할 때와 수정할 때 느리다는 -것이지, 렌더링 속도가 느리다는 말이 아닙니다. geometry를 수정하지 않고 geometry가 -무지막지하게 크지 않은 한, GeometryBufferGeometry에 비해 프로그램 초기화 -단계에서만 약간 더 느릴 뿐입니다. 결국에는 둘 다 살펴보겠지만, 일단-제 생각에-훨씬 -간단하고 이해하기 쉬운 Geometry를 먼저 써봅시다.

      -

      먼저 정육면체를 만들겠습니다. 반응형 디자인에 관한 글에서 -썼던 예제를 일부 가져오도록 하죠.

      -

      먼저 BoxGeometryGeometry로 교체합니다.

      -
      -const boxWidth = 1;
      --const boxHeight = 1;
      --const boxDepth = 1;
      --const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);
      -+const geometry = new THREE.Geometry();
      -
      -

      이제 정육면체의 꼭지점를 추가합니다. 정육면체의 모서리는 총 8개이죠.

      -
      - -

      중점을 중심으로 각 꼭지점을 추가합니다.

      -
      const geometry = new THREE.Geometry();
      -+geometry.vertices.push(
      -+  new THREE.Vector3(-1, -1,  1),  // 0
      -+  new THREE.Vector3( 1, -1,  1),  // 1
      -+  new THREE.Vector3(-1,  1,  1),  // 2
      -+  new THREE.Vector3( 1,  1,  1),  // 3
      -+  new THREE.Vector3(-1, -1, -1),  // 4
      -+  new THREE.Vector3( 1, -1, -1),  // 5
      -+  new THREE.Vector3(-1,  1, -1),  // 6
      -+  new THREE.Vector3( 1,  1, -1),  // 7
      -+);
      -
      -

      다음으로 정육면체 한 면에 2개씩, 총 삼각형 12개를 추가해야 합니다.

      -
      - -

      Face3 인스턴스를 만들어 3 꼭지점의 인덱스(index)를 넘겨주면 삼각형 -면(face)을 만들 수 있습니다.

      -

      꼭지점의 인덱스를 넘겨줄 때는 순서에 유의해야 합니다. 삼각형이 카메라를 -바라볼 때, 면이 정육면체의 바깥쪽을 향하려면 시계 반대 방향 순으로 인덱스를 -넘겨줘야 합니다.

      -
      - -

      이 패턴대로 정육면체를 구성할 삼각형 12개를 만들어봅시다.

      -
      geometry.faces.push(
      -  // 앞쪽
      -  new THREE.Face3(0, 3, 2),
      -  new THREE.Face3(0, 1, 3),
      -  // 오른쪽
      -  new THREE.Face3(1, 7, 3),
      -  new THREE.Face3(1, 5, 7),
      -  // 뒷쪽
      -  new THREE.Face3(5, 6, 7),
      -  new THREE.Face3(5, 4, 6),
      -  // 왼쪽
      -  new THREE.Face3(4, 2, 6),
      -  new THREE.Face3(4, 0, 2),
      -  // 상단
      -  new THREE.Face3(2, 7, 6),
      -  new THREE.Face3(2, 3, 7),
      -  // 하단
      -  new THREE.Face3(4, 1, 0),
      -  new THREE.Face3(4, 5, 1),
      -);
      -
      -

      이제 몇 가지만 더 고치면 됩니다.

      -

      이 정육면체들은 BoxGeometry보다 두 배 더 크므로, 카메라를 약간 -더 뒤로 옮겨줍니다.

      -
      const fov = 75;
      -const aspect = 2;  // canvas 기본값
      -const near = 0.1;
      --const far = 5;
      -+const far = 100;
      -const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
      --camera.position.z = 2;
      -+camera.position.z = 5;
      -
      -

      커진 만큼 간격을 띄우고, 바꾸는 김에 색상도 바꿔주겠습니다.

      -
      const cubes = [
      --  makeInstance(geometry, 0x44aa88,  0),
      --  makeInstance(geometry, 0x8844aa, -2),
      --  makeInstance(geometry, 0xaa8844,  2),
      -+  makeInstance(geometry, 0x44FF44,  0),
      -+  makeInstance(geometry, 0x4444FF, -4),
      -+  makeInstance(geometry, 0xFF4444,  4),
      -];
      -
      -

      아직 법선(normal)을 넣지 않았는데, 법선이 없으면 빛은 소용이 없으니 마지막으로 -재질(material)을 MeshBasicMaterial로 바꿔줍니다.

      -
      function makeInstance(geometry, color, x) {
      --  const material = new THREE.MeshPhongMaterial({ color });
      -+  const material = new THREE.MeshBasicMaterial({ color });
      -
      -  const cube = new THREE.Mesh(geometry, material);
      -  scene.add(cube);
      -
      -  ...
      -
      -

      자, 이제 실행해보죠.

      -

      - -

      -

      각 삼각형 면의 color 속성을 바꿔 색을 따로 지정할 수 있습니다.

      -
      geometry.faces[ 0].color = geometry.faces[ 1].color = new THREE.Color('red');
      -geometry.faces[ 2].color = geometry.faces[ 3].color = new THREE.Color('yellow');
      -geometry.faces[ 4].color = geometry.faces[ 5].color = new THREE.Color('green');
      -geometry.faces[ 6].color = geometry.faces[ 7].color = new THREE.Color('cyan');
      -geometry.faces[ 8].color = geometry.faces[ 9].color = new THREE.Color('blue');
      -geometry.faces[10].color = geometry.faces[11].color = new THREE.Color('magenta');
      -
      -

      추가로 재질을 생성할 때 vertexColors를 사용한다고 명시해야 하죠.

      -
      -const material = new THREE.MeshBasicMaterial({ color });
      -+const material = new THREE.MeshBasicMaterial({ vertexColors: true });
      -
      -

      - -

      -

      또는 삼각형 면의 vertexColors 속성에 각 꼭지점의 색상을 지정할 수도 있습니다.

      -
      geometry.faces.forEach((face, ndx) => {
      -  face.vertexColors = [
      -    (new THREE.Color()).setHSL(ndx / 12      , 1, 0.5),
      -    (new THREE.Color()).setHSL(ndx / 12 + 0.1, 1, 0.5),
      -    (new THREE.Color()).setHSL(ndx / 12 + 0.2, 1, 0.5),
      -  ];
      -});
      -
      -

      - -

      -

      빛을 사용하려면 법선을 추가해야 합니다. 법선이란 특정 방향을 나타내는 벡터값으로, -색과 마찬가지로 법선도 각 삼각형 면의 normal 속성을 지정해 추가할 수 있습니다.

      -
      face.normal = new THREE.Vector3(...)
      -
      -

      또는 vertexNormals 속성에 각 꼭지점의 법선을 배열로 지정할 수도 있죠.

      -
      face.vertexNormals = [
      -  new THREE.Vector3(...),
      -  new THREE.Vector3(...),
      -  new THREE.Vector3(...),
      -]
      -
      -

      하지만 대게 우리가 지정한 좌표에 따라 알아서 법선을 계산해달라고 하는 게 -훨씬 편합니다.

      -

      삼각형 면 법선의 경우 Geometry.computeFaceNormals를 호출하면 되죠.

      -
      geometry.computeFaceNormals();
      -
      -

      꼭지점 색을 제거하고 다시 재질을 MeshPhongMaterial로 바꾸겠습니다.

      -
      -const material = new THREE.MeshBasicMaterial({ vertexColors: true });
      -+const material = new THREE.MeshPhongMaterial({ color });
      -
      -

      이제 정육면체들이 빛의 영향을 받습니다.

      -

      - -

      -

      삼각형 면 법선을 사용하면 물체가 각진 느낌을 줍니다. 꼭지점 법선을 사용하면 -훨씬 부드러워 보일 수 있죠. 꼭지점 법선은 Geometry.computeVertexNormals를 -호출해 사용합니다.

      -
      -geometry.computeFaceNormals();
      -+geometry.computeVertexNormals();
      -
      -

      아쉽게도 정육면체는 꼭지점 법선의 예제로 적당하지 않습니다. 각 꼭지점이 같은 -꼭지점을 쓰는 모든 삼각형 면에서 법선을 가져오기 때문이죠.

      -

      - -

      -

      UV라고도 불리는, 텍스처 좌표는 Geometry.faceVertexUvs 속성에 삼각형 면들의 -층(layer)을 배열로 지정해 추가할 수 있습니다. 정육면체의 경우 다음처럼 지정할 -수 있죠.

      -

      (※ 참고: UV 매핑. 역주)

      -
      geometry.faceVertexUvs[0].push(
      -  // 앞쪽
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
      -  // 오른쪽
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
      -  // 뒤쪽
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
      -  // 왼쪽
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
      -  // 상단
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
      -  // 하단
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
      -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
      -);
      -
      -

      중요한 건 faceVertexUvs는 층의 배열이라는 점입니다. 하나의 층은 별도의 UV 좌표이죠. -기본적으로 하나의 UV 층, 층 0이 있어, 예제에서는 그냥 그 층에 UV를 추가했습니다.

      -

      다시 삼각형 면 법선을 계산하도록 코드를 바꾸고, 이번에는 재질에 텍스처를 추가하겠습니다.

      -
      -geometry.computeVertexNormals();
      -+geometry.computeFaceNormals();
      -
      -+const loader = new THREE.TextureLoader();
      -+const texture = loader.load('resources/images/star.png');
      -
      -function makeInstance(geometry, color, x) {
      --  const material = new THREE.MeshPhongMaterial({color});
      -+  const material = new THREE.MeshPhongMaterial({color, map: texture});
      -
      -  const cube = new THREE.Mesh(geometry, material);
      -  scene.add(cube);
      -
      -  ...
      -
      -

      - -

      -

      다음으로는 이 글에서 배운 것을 총 동원해 지형 mesh를 기반으로 높이 맵(heightmap)을 -만들어보겠습니다.

      -

      높이 맵을 기반으로 한 지형이란, 이차원 높이 배열을 격자 형태로 만든 것을 -말합니다. 이차원 높이 배열을 만드는 가장 쉬운 방법은 이미지 편집 프로그램을 -사용하는 것이죠. 아래는 제가 만든 96x64 픽셀의 이미지입니다.

      -
      - -

      이 이미지의 데이터를 불러와 높이 맵 mesh를 만들겠습니다. 이미지 데이터를 -불러올 때는 ImageLoader를 활용합니다.

      -
      const imgLoader = new THREE.ImageLoader();
      -imgLoader.load('resources/images/heightmap-96x64.png', createHeightmap);
      -
      -function createHeightmap(image) {
      -  // canvas에 이미지를 렌더링한 후, getImageData 메서드를 호출해 픽셀 데이터를 추출합니다
      -  const ctx = document.createElement('canvas').getContext('2d');
      -  const { width, height } = image;
      -  ctx.canvas.width = width;
      -  ctx.canvas.height = height;
      -  ctx.drawImage(image, 0, 0);
      -  const { data } = ctx.getImageData(0, 0, width, height);
      -
      -  const geometry = new THREE.Geometry();
      -
      -

      이미지에서 데이터를 추출했으니, 이제 격자를 만들어야 합니다. 이미지의 픽셀 -하나당 정사각형 격자 한 칸을 만듭니다.

      -
      - -

      격자 한 칸당 꼭지점 5개를 만듭니다. 정사각형의 각 꼭지점 당 하나씩 총 4개를 두고, -네 꼭지점의 높이를 평균내 중앙에 하나를 둡니다.

      -
      const cellsAcross = width - 1;
      -const cellsDeep = height - 1;
      -for (let z = 0; z < cellsDeep; ++z) {
      -  for (let x = 0; x < cellsAcross; ++x) {
      -    /**
      -     * 열의 위치를 높이 데이터로 계산합니다
      -     * 데이터가 RGBA이므로 4를 곱하지만, R 값만 사용합니다
      -     **/
      -    const base0 = (z * width + x) * 4;
      -    const base1 = base0 + (width * 4);
      -
      -    // 격자 칸 각 꼭지점의 높이를 참조합니다
      -    const h00 = data[base0] / 32;
      -    const h01 = data[base0 + 4] / 32;
      -    const h10 = data[base1] / 32;
      -    const h11 = data[base1 + 4] / 32;
      -    // 높이의 평균값을 구합니다
      -    const hm = (h00 + h01 + h10 + h11) / 4;
      -
      -    // 꼭지점의 위치
      -    const x0 = x;
      -    const x1 = x + 1;
      -    const z0 = z;
      -    const z1 = z + 1;
      -
      -    // 각 꼭지점의 첫 번째 인덱스를 기록합니다
      -    const ndx = geometry.vertices.length;
      -
      -    // 격자에 모퉁이 꼭지점 4개와 중앙 꼭지점 하나를 배치합니다
      -    geometry.vertices.push(
      -      new THREE.Vector3(x0, h00, z0),
      -      new THREE.Vector3(x1, h01, z0),
      -      new THREE.Vector3(x0, h10, z1),
      -      new THREE.Vector3(x1, h11, z1),
      -      new THREE.Vector3((x0 + x1) / 2, hm, (z0 + z1) / 2),
      -    );
      -
      -

      다음으로 방금 만든 5개의 정점을 모아 4개의 삼각형을 만들어야 합니다.

      -
      - -
          // 삼각형 4개를 만듭니다
      -    geometry.faces.push(
      -      new THREE.Face3(ndx + 0, ndx + 4, ndx + 1),
      -      new THREE.Face3(ndx + 1, ndx + 4, ndx + 3),
      -      new THREE.Face3(ndx + 3, ndx + 4, ndx + 2),
      -      new THREE.Face3(ndx + 2, ndx + 4, ndx + 0),
      -    );
      -
      -    // 각 삼각형 면의 각 꼭지점에 텍스처 좌표를 추가합니다
      -    const u0 = x / cellsAcross;
      -    const v0 = z / cellsDeep;
      -    const u1 = (x + 1) / cellsAcross;
      -    const v1 = (z + 1) / cellsDeep;
      -    const um = (u0 + u1) / 2;
      -    const vm = (v0 + v1) / 2;
      -    geometry.faceVertexUvs[0].push(
      -      [ new THREE.Vector2(u0, v0), new THREE.Vector2(um, vm), new THREE.Vector2(u1, v0) ],
      -      [ new THREE.Vector2(u1, v0), new THREE.Vector2(um, vm), new THREE.Vector2(u1, v1) ],
      -      [ new THREE.Vector2(u1, v1), new THREE.Vector2(um, vm), new THREE.Vector2(u0, v1) ],
      -      [ new THREE.Vector2(u0, v1), new THREE.Vector2(um, vm), new THREE.Vector2(u0, v0) ],
      -    );
      -  }
      -}
      -
      -

      이제 마무리 지어보죠.

      -
        geometry.computeFaceNormals();
      -
      -  // geometry를 중점에 배치
      -  geometry.translate(width / -2, 0, height / -2);
      -
      -  const loader = new THREE.TextureLoader();
      -  const texture = loader.load('resources/images/star.png');
      -
      -  const material = new THREE.MeshPhongMaterial({ color: 'green', map: texture });
      -
      -  const cube = new THREE.Mesh(geometry, material);
      -  scene.add(cube);
      -}
      -
      -

      장면을 보기 쉽도록 몇 가지 요소를 추가하겠습니다.

      -

      OrbitControls를 추가하고,

      -
      import * as THREE from '/build/three.module.js';
      -+import { OrbitControls } from '/examples/jsm/controls/OrbitControls.js';
      -
      -
      const fov = 75;
      -const aspect = 2;  // canvas 기본 비율
      -const near = 0.1;
      --const far = 100;
      -+const far = 200;
      -const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
      --camera.position.z = 5;
      -+camera.position.set(20, 20, 20);
      -
      -+const controls = new OrbitControls(camera, canvas);
      -+controls.target.set(0, 0, 0);
      -+controls.update();
      -
      -

      조명도 두 개 추가합니다.

      -
      -{
      -+function addLight(...pos) {
      -  const color = 0xFFFFFF;
      -  const intensity = 1;
      -  const light = new THREE.DirectionalLight(color, intensity);
      --  light.position.set(-1, 2, 4\);
      -+  light.position.set(...pos);
      -  scene.add(light);
      -}
      -
      -+addLight(-1, 2, 4);
      -+addLight(1, 2, -2);
      -
      -

      정육면체를 회전시키는 코드는 필요없으니 삭제하도록 하죠.

      -

      - -

      -

      이 글이 Geometry를 활용하는 데 도움이 되었으면 합니다.

      -

      글이 길어졌으니 BufferGeometry다음 글에서 -살펴보도록 하겠습니다.

      - -
      -
      -
      - - - - - - - - \ No newline at end of file diff --git a/manual/ko/fundamentals.html b/manual/ko/fundamentals.html index 7df6ad7ba019c4..1bdf103f06317e 100644 --- a/manual/ko/fundamentals.html +++ b/manual/ko/fundamentals.html @@ -80,7 +80,7 @@

      Three.js란?

      Material, Geometry는 재사용이 가능하여 여러개의 Mesh가 하나의 Material 또는 Geometry를 동시에 참조할 수 있습니다. 파란색 정육면체 2개를 그린다고 해보죠. 일단 두 정육면체의 위치가 달라야 하니, 2개의 Mesh가 -필요합니다. 그리고 정점(vertext, 꼭지점) 데이터를 가진 한 개의 Geometry와 +필요합니다. 그리고 정점(vertex, 꼭지점) 데이터를 가진 한 개의 Geometry와 채색을 위한 하나의 Material이 필요하겠죠. 이때 각 Mesh는 객체를 복사할 필요 없이, 같은 Geometry 그리고 Material을 참조할 수 있습니다.

      @@ -106,7 +106,7 @@

      Three.js란?

      먼저, Three.js를 로드합니다.

      <script type="module">
      -import * as THREE from '../../build/three.module.js';
      +import * as THREE from 'three';
       </script>
       

      type="module" 속성을 지정하는 것을 잊지 마세요. 이러면 import 키워드를 @@ -121,7 +121,7 @@

      Three.js란?

      이제 Three.js에게 렌더링을 맡겨보죠.

      <script type="module">
      -import * as THREE from '../../build/three.module.js';
      +import * as THREE from 'three';
       
       +function main() {
       +  const canvas = document.querySelector('#c');
      @@ -260,7 +260,7 @@ 

      Three.js란?

      scene.add(light); }
      -

      DirectionnalLight에는 위치(position)목표(target) 속성이 있습니다. +

      DirectionalLight에는 위치(position)목표(target) 속성이 있습니다. 기본값은 0, 0, 0 이죠. 먼저 position-1, 2, 4로 설정해 카메라보다 약간 동서쪽, Z축으로는 약간 위로 보냅니다. target은 기본값 0, 0, 0 그대로 두어 공간의 중앙을 비추도록 합니다.

      @@ -345,7 +345,7 @@

      es6 모듈, Three.js, 프로젝트 구조

      import 키워드를 사용해 로드할 수 있습니다.

      <script type="module">
      -import * as THREE from '../../build/three.module.js';
      +import * as THREE from 'three';
       
       ...
       
      @@ -393,18 +393,18 @@ 

      es6 모듈, Three.js, 프로젝트 구조

      참조하도록 할 수 있죠.

      import * as THREE from './someFolder/build/three.module.js';
      -import {OrbitControls} from './someFolder/examples/jsm/controls/OrbitControls.js';
      +import {OrbitControls} from './someFolder/addons/controls/OrbitControls.js';
       

      아래는 CDN을 사용하는 예시입니다. three.modules.js의 경로가 /build/three.modules.js 로 끝나야 한다는 것을 명심하세요.

      import * as THREE from 'https://unpkg.com/three@0.108.0/build/three.module.js';
      -import {OrbitControls} from 'https://unpkg.com/three@0.108.0/examples/jsm/controls/OrbitControls.js';
      +import {OrbitControls} from 'https://unpkg.com/three@0.108.0/addons/controls/OrbitControls.js';
       

      - + diff --git a/manual/ko/game.html b/manual/ko/game.html index f805a23d16257d..009106a5ccbff5 100644 --- a/manual/ko/game.html +++ b/manual/ko/game.html @@ -173,10 +173,10 @@

      로 게임 만들기

      이제 애니메이션이 들어간 모델을 화면에 띄워봅시다.

      이전 glTF 파일 예제와 달리 이번에는 각 모델을 하나 이상 배치할 계획입니다. 그러니 파일을 불러온 뒤 바로 장면에 넣는 대신 각 glTF의 씬 그래프(scene), 이 경우에는 움직이는 캐릭터를 복사해야 합니다. 다행히 Three.js에는 SkeletonUtil.clone이라는 함수가 있어 이를 쉽게 구현할 수 있죠. 먼저 해당 모듈을 불러오겠습니다.

      -
      import * as THREE from '/build/three.module.js';
      -import { OrbitControls } from '/examples/jsm/controls/OrbitControls.js';
      -import { GLTFLoader } from '/examples/jsm/loaders/GLTFLoader.js';
      -+import { SkeletonUtils } from '/examples/jsm/utils/SkeletonUtils.js';
      +
      import * as THREE from 'three';
      +import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
      +import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
      ++import { SkeletonUtils } from 'three/addons/utils/SkeletonUtils.js';
       

      그리고 아까 불러왔던 모델을 복사합니다.

      function init() {
      @@ -1316,11 +1316,11 @@ 

      로 게임 만들기

      }

      추가로 lil-gui를 이용해 위 디버깅 요소들를 켜고 끌 수 있도록 합니다.

      -
      import * as THREE from '/build/three.module.js';
      -import { OrbitControls } from '/examples/jsm/controls/OrbitControls.js';
      -import { GLTFLoader } from '/examples/jsm/loaders/GLTFLoader.js';
      -import { SkeletonUtils } from '/examples/jsm/utils/SkeletonUtils.js';
      -+import { GUI } from '/examples/jsm/libs/lil-gui.module.min.js';
      +
      import * as THREE from 'three';
      +import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
      +import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
      +import { SkeletonUtils } from 'three/addons/utils/SkeletonUtils.js';
      ++import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
       
      +const gui = new GUI();
       +gui.add(globals, 'debug').onChange(showHideDebugInfo);
      diff --git a/manual/ko/lights.html b/manual/ko/lights.html
      index 185bf636c088a8..37098a3072e33f 100644
      --- a/manual/ko/lights.html
      +++ b/manual/ko/lights.html
      @@ -48,8 +48,8 @@ 

      조명(Lights)

      다음으로 OrbitControls를 추가합니다. OrbitControls는 특정 좌표를 중심으로 카메라를 자전 또는 공전(orbit)하도록 해줍니다. OrbitControls는 별도 모듈이므로, 먼저 페이지에 로드해야 합니다.

      -
      import * as THREE from '/build/three.module.js';
      -+import { OrbitControls } from '/examples/jsm/controls/OrbitControls.js';
      +
      import * as THREE from 'three';
      ++import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
       

      이제 OrbitControls에 카메라와, DOM 이벤트를 감지할 수 있도록 canvas 요소를 넘겨줍니다.

      @@ -396,9 +396,9 @@

      RectAreaLight를 사용하려면 별도의 데이터를 불러와야 합니다. 또한 RectAreaLightHelper도 같이 불러와 조명을 시각화하겠습니다.

      -
      import * as THREE from '/build/three.module.js';
      -+import { RectAreaLightUniformsLib } from '/examples/jsm/lights/RectAreaLightUniformsLib.js';
      -+import { RectAreaLightHelper } from '/examples/jsm/helpers/RectAreaLightHelper.js';
      +
      import * as THREE from 'three';
      ++import { RectAreaLightUniformsLib } from 'three/addons/lights/RectAreaLightUniformsLib.js';
      ++import { RectAreaLightHelper } from 'three/addons/helpers/RectAreaLightHelper.js';
       

      모듈을 불러온 후 RectAreaLightUniformsLib.init 메서드를 호출합니다.

      function main() {
      diff --git a/manual/ko/load-gltf.html b/manual/ko/load-gltf.html
      index 6ca7035c902527..df2b42570f51b5 100644
      --- a/manual/ko/load-gltf.html
      +++ b/manual/ko/load-gltf.html
      @@ -113,10 +113,10 @@ 

      에서 .GLTF 파일 불러오기

      자동으로 카메라의 시야를 조정하는 코드는 그대로 두었습니다.

      모듈이 바뀌었으니 import 문도 변경해야 합니다. OBJLoader를 제거하고 GLTFLoader를 추가합니다.

      -
      -import { LoaderSupport } from '/examples/jsm/loaders/LoaderSupport.js';
      --import { OBJLoader } from '/examples/jsm/loaders/OBJLoader.js';
      --import { MTLLoader } from '/examples/jsm/loaders/MTLLoader.js';
      -+import { GLTFLoader } from '/examples/jsm/loaders/GLTFLoader.js';
      +
      -import { LoaderSupport } from 'three/addons/loaders/LoaderSupport.js';
      +-import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';
      +-import { MTLLoader } from 'three/addons/loaders/MTLLoader.js';
      ++import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
       

      이제 실행해보죠.

      @@ -262,7 +262,7 @@

      에서 .GLTF 파일 불러오기

      - cars = root.getObjectByName('Cars'); + const loadedCars = root.getObjectByName('Cars'); + const fixes = [ -+ { prefix: 'Car_08', rot: [Math.PI * .5, 0, Math.PI +* .5], }, ++ { prefix: 'Car_08', rot: [Math.PI * .5, 0, Math.PI * .5], }, + { prefix: 'CAR_03', rot: [0, Math.PI, 0], }, + { prefix: 'Car_04', rot: [0, Math.PI, 0], }, + ]; @@ -674,4 +674,4 @@

      에서 .GLTF 파일 불러오기

      - \ No newline at end of file + diff --git a/manual/ko/load-obj.html b/manual/ko/load-obj.html index 7aa6a5705ea048..0787a5dea7d86b 100644 --- a/manual/ko/load-obj.html +++ b/manual/ko/load-obj.html @@ -62,7 +62,7 @@

      에서 .OBJ 파일 불러오기

      하나, DirectionalLight 하나가 있는 셈입니다. 또 GUI 관련 코드와 정육면체, 구체 관련 코드도 지웁니다.

      다음으로 먼저 OBJLoader 모듈을 스크립트에 로드합니다.

      -
      import { OBJLoader } from '/examples/jsm/loaders/OBJLoader.js';
      +
      import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';
       

      OBJLoader의 인스턴스를 생성한 뒤 .OBJ 파일의 경로와 콜백 함수를 넘겨 load 메서드를 실행합니다. 그리고 콜백 함수에서 불러온 모델을 장면에 @@ -139,10 +139,10 @@

      에서 .OBJ 파일 불러오기

      이제 .MTL 파일에서 사용할 텍스처를 생성했으니 .MTL 파일을 불러오도록 합시다.

      MTLLoader 모듈을 불러옵니다.

      -
      import * as THREE from '/build/three.module.js';
      -import { OrbitControls } from '/examples/jsm/controls/OrbitControls.js';
      -import { OBJLoader } from '/examples/jsm/loaders/OBJLoader.js';
      -+import { MTLLoader } from '/examples/jsm/loaders/MTLLoader.js';
      +
      import * as THREE from 'three';
      +import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
      +import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';
      ++import { MTLLoader } from 'three/addons/loaders/MTLLoader.js';
       

      우선 .MTL 파일을 불러와 MtlObjBridge로 재질을 만듭니다. 그리고 OBJLoader diff --git a/manual/ko/multiple-scenes.html b/manual/ko/multiple-scenes.html index 0a7b0050ffc00a..47024364d4d354 100644 --- a/manual/ko/multiple-scenes.html +++ b/manual/ko/multiple-scenes.html @@ -422,7 +422,7 @@

      HTML Dataset 사용하기

      각 요소에 액션 추가하기

      사용자 액션, 예를 들어 TrackballControls를 추가하는 건 아주 간단합니다. 먼저 스크립트를 불러옵니다.

      -
      import { TrackballControls } from '/examples/jsm/controls/TrackballControls.js';
      +
      import { TrackballControls } from 'three/addons/controls/TrackballControls.js';
       

      그리고 각 장면에 대응하는 요소에 TrackballControls를 추가합니다.

      -function makeScene() {
      diff --git a/manual/ko/offscreencanvas.html b/manual/ko/offscreencanvas.html
      index b271da9e9004bb..3503a5289a7380 100644
      --- a/manual/ko/offscreencanvas.html
      +++ b/manual/ko/offscreencanvas.html
      @@ -205,7 +205,7 @@ 

      OffscreenCanvas

    shared-cubes.jsoffscreencanvas-worker-cubes.js는 단순히 이전 offscreencanvas-cubes.js 파일을 쪼갠 것입니다. 먼저 offscreencanvas-cube.jsshared-cube.js로 옮긴 뒤, 메인 HTML 파일에 이미 main 함수가 있어 main 함수의 이름만 init으로 바꿔야 하죠. 여기에 추가로 initstate 함수를 export 시켜줘야 합니다.

    -
    import * as THREE from '../../build/three.module.js';
    +
    import * as THREE from 'three';
     
     -const state = {
     +export const state = {
    @@ -529,7 +529,7 @@ 

    OffscreenCanvas

    터치 이벤트의 경우는 touches 속성의 pageX, pageY 속성이 필요하네요.

    이를 처리할 경유(proxy) 객체를 한 쌍 만들어봅시다. 한쪽은 메인 페이지에서 위 이벤트를 받아 필요한 속성을 워커에 넘겨주는 역할을 할 겁니다. 그리고 다른 한쪽은 워커 안에서 이 이벤트를 받아 OrbitControls에 넘겨줄 겁니다. 이벤트 객체가 DOM 이벤트와 같은 구조이기에 OrbitControls는 이 이벤트가 DOM 이벤트가 아니란 걸 눈치채지 못하겠죠.

    아래는 워커 안의 코드입니다.

    -
    import { EventDispatcher } from '../../build/three.module.js';
    +
    import { EventDispatcher } from 'three';
     
     class ElementProxyReceiver extends EventDispatcher {
       constructor() {
    @@ -596,8 +596,8 @@ 

    OffscreenCanvas

    };

    Three.js의 공통 코드에 OrbitControls 모듈도 불러와 설정해야 합니다.

    -
    import * as THREE from '../../build/three.module.js';
    -+import { OrbitControls } from '/examples/jsm/controls/OrbitControls.js';
    +
    import * as THREE from 'three';
    ++import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
     
     export function init(data) {
     -  const { canvas } = data;
    diff --git a/manual/ko/optimize-lots-of-objects-animated.html b/manual/ko/optimize-lots-of-objects-animated.html
    index eabcf82bea07ac..acc6cabb213ebc 100644
    --- a/manual/ko/optimize-lots-of-objects-animated.html
    +++ b/manual/ko/optimize-lots-of-objects-animated.html
    @@ -294,10 +294,10 @@ 

    다중 애니메이션 요소 최적화하기

    이제 각 데이터 그룹에 전환 효과를 줘야 합니다. mesh를 사라지고 나타나게 하는 대신 mesh의 morphTargetInfluences 속성을 바꿔 애니메이션을 구현할 겁니다. 화면에 렌더링할 데이터 그룹의 influence(영향)은 1, 렌더링하지 않을 그룹의 influence는 0으로 설정하는 것이죠.

    단순히 숫자 0, 1을 바로 지정할 수도 있지만 그러면 애니메이션이 하나도 보이지 않을 겁니다. 아까 썼던 방법과 전혀 차이가 없는 결과가 나오겠죠. 물론 직접 애니메이션 코드를 작성할 수도 있지만 원본 WebGL 지구본이 애니메이션 라이브러리를 썼으므로 같은 라이브러리를 사용해보겠습니다.

    먼저 라이브러리를 불러옵니다.

    -
    import * as THREE from '/build/three.module.js';
    -import { BufferGeometryUtils } from '/examples/jsm/utils/BufferGeometryUtils.js';
    -import { OrbitControls } from '/examples/jsm/controls/OrbitControls.js';
    -+import { TWEEN } from '/examples/jsm/libs/tween.min.js';
    +
    import * as THREE from 'three';
    +import { BufferGeometryUtils } from 'three/addons/utils/BufferGeometryUtils.js';
    +import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
    ++import { TWEEN } from 'three/addons/libs/tween.min.js';
     

    그리고 Tween으로 influence 속성에 애니메이션을 줍니다.

    // 선택한 데이터를 보여주고 나머지는 숨깁니다.
    diff --git a/manual/ko/optimize-lots-of-objects.html b/manual/ko/optimize-lots-of-objects.html
    index b90d12718ca45e..a13fad766da3c0 100644
    --- a/manual/ko/optimize-lots-of-objects.html
    +++ b/manual/ko/optimize-lots-of-objects.html
    @@ -350,7 +350,7 @@ 

    다중 요소 렌더링 최적화하기

    위 코드에서는 육면체의 중심을 옮기는 대신 originHelper를 새로 만들어 중심축을 옮겼습니다. 이전에는 같은 geometry를 19000번 재활용했지만, 이번에는 데이터마다 geometry를 새로 생성했죠. 또한 applyMatrix를 이용해 육면체 자체의 정점을 이동시키므로 메서드를 두 번 쓰는 대신 한 번만 썼습니다.

    그리고 생성한 육면체를 전부 배열에 저장한 뒤 이 배열을 BufferGeometryUtils.mergeBufferGeometries에 넘겨 하나의 geometry로 합쳤습니다.

    물론 BufferGeometryUtils을 불러와야죠.

    -
    import { BufferGeometryUtils } from '/examples/jsm/utils/BufferGeometryUtils.js';
    +
    import { BufferGeometryUtils } from 'three/addons/utils/BufferGeometryUtils.js';
     

    이제 제 컴퓨터에서는 적어도 60 프레임 이상이 나오네요.

    diff --git a/manual/ko/post-processing.html b/manual/ko/post-processing.html index d283f9e5ea4c07..2a5b9e2f4c9ed7 100644 --- a/manual/ko/post-processing.html +++ b/manual/ko/post-processing.html @@ -78,10 +78,10 @@

    renderToScree

    filmPass가 마지막 pass이기에 캔버스에 결과를 바로 렌더링하도록 renderToScreen 옵션을 true로 설정했습니다. 이 옵션을 설정하지 않으면 캔버스가 아닌 다음 렌더 타겟에 장면을 렌더링할 거예요.

    또 이 클래스들을 사용하기 위해 여러 스크립트를 불러와야 합니다.

    -
    import { EffectComposer } from '/examples/jsm/postprocessing/EffectComposer.js';
    -import { RenderPass } from '/examples/jsm/postprocessing/RenderPass.js';
    -import { BloomPass } from '/examples/jsm/postprocessing/BloomPass.js';
    -import { FilmPass } from '/examples/jsm/postprocessing/FilmPass.js';
    +
    import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
    +import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
    +import { BloomPass } from 'three/addons/postprocessing/BloomPass.js';
    +import { FilmPass } from 'three/addons/postprocessing/FilmPass.js';
     

    대부분의 후처리에는 EffectComposer.jsRenderPass.js가 필수입니다.

    이제 WebGLRenderer.render 대신 EffectComposer.render를 사용하고 EffectComposer가 결과물을 캔버스의 크기에 맞추도록 해야 합니다.

    @@ -137,7 +137,7 @@

    renderToScree if ( scanlinesCount !== undefined ) this.uniforms.sCount.value = scanlinesCount;

    이제 어떻게 값을 지정해야 하는지 알았으니 이 값을 조작하는 GUI를 만들어봅시다.

    -
    import { GUI } from '/examples/jsm/libs/lil-gui.module.min.js';
    +
    import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
     

    일단 모듈을 로드합니다.

    const gui = new GUI();
    diff --git a/manual/ko/prerequisites.html b/manual/ko/prerequisites.html
    index 7e56993d44a6b9..a91045790bfa36 100644
    --- a/manual/ko/prerequisites.html
    +++ b/manual/ko/prerequisites.html
    @@ -44,7 +44,7 @@ 

    ES2015 모듈

    ES2015 모듈은 스크립트 안에서 import 키워드나, 인라인 <script type="module"> 태그로 불러올 수 있습니다. 두 가지 예시를 동시에 써보죠.

    <script type="module">
    -import * as THREE from '../../build/three.module.js';
    +import * as THREE from 'three';
     
     ...
     
    diff --git a/manual/ko/rendering-on-demand.html b/manual/ko/rendering-on-demand.html
    index 61f1f1582d8b51..6f03f3158ce66b 100644
    --- a/manual/ko/rendering-on-demand.html
    +++ b/manual/ko/rendering-on-demand.html
    @@ -51,8 +51,8 @@ 

    불필요한 렌더링 없애기

    반응형 디자인에 관한 글에서 썼던 예제를 수정해 필요에 따른 렌더링을 구현해봅시다.

    먼저 뭔가 변화를 일으킬 수 있는 요소가 필요하니 OrbitControls를 추가합니다.

    -
    import * as THREE from '/build/three.module.js';
    -+import { OrbitControls } from '/examples/jsm/controls/OrbitControls.js';
    +
    import * as THREE from 'three';
    ++import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
     
     ...
     
    @@ -174,9 +174,9 @@ 

    불필요한 렌더링 없애기

    간단한 lil-gui를 추가해 반복 렌더링 여부를 제어할 수 있도록 하겠습니다.

    -
    import * as THREE from '/build/three.module.js';
    -import { OrbitControls } from '/examples/jsm/controls/OrbitControls.js';
    -+import { GUI } from '/examples/jsm/libs/lil-gui.module.min.js';
    +
    import * as THREE from 'three';
    +import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
    ++import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
     

    먼저 각 정육면체의 색과 x축 스케일을 조정하는 GUI를 추가합니다. 조명에 관한 글에서 썼던 ColorGUIHelper를 가져와 쓰도록 하죠.

    diff --git a/manual/ko/textures.html b/manual/ko/textures.html index 1a27a3ae672867..107df3cea76be6 100644 --- a/manual/ko/textures.html +++ b/manual/ko/textures.html @@ -457,7 +457,7 @@

    간단한 인터페이스를 만들어보죠. 다시 한 번 lil-gui가 등장할 때입니다.

    -
    import { GUI } from '/examples/jsm/libs/lil-gui.module.min.js';
    +
    import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
     

    이전 예제처럼 간단한 헬퍼 클래스를 만들어 각도(degrees)로 값을 조절하면 알아서 호도(radians)로 변환해 지정하게끔 해줍니다.

    diff --git a/manual/ko/transparency.html b/manual/ko/transparency.html index b552212b3a5d60..bb76646af4fa29 100644 --- a/manual/ko/transparency.html +++ b/manual/ko/transparency.html @@ -355,9 +355,9 @@

    투명도

    .onChange(requestRenderIfNotRequested);

    물론 lil-gui 모듈도 불러와야죠.

    -
    import * as THREE from '/build/three.module.js';
    -import { OrbitControls } from '/examples/jsm/controls/OrbitControls.js';
    -+import { GUI } from '/examples/jsm/libs/lil-gui.module.min.js';
    +
    import * as THREE from 'three';
    +import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
    ++import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
     

    diff --git a/manual/ko/webxr.html b/manual/ko/webxr-basics.html similarity index 99% rename from manual/ko/webxr.html rename to manual/ko/webxr-basics.html index 22441ea1ed2f25..a8d5d2cd6cb02e 100644 --- a/manual/ko/webxr.html +++ b/manual/ko/webxr-basics.html @@ -56,8 +56,8 @@

    VR

    이를 통해 콘솔 경보, 오류, 실제로 코드 디버그(debug your code)가 가능합니다.

    아래 코드가 작동하는 것을 보고 싶다면 이 사이트에서 코드를 실행할 수 있습니다.

    가장 먼저 해야 할 일은 three.js를 포함시킨 후 VR 지원을 포함하는 것입니다.

    -
    import * as THREE from './resources/three/r132/build/three.module.js';
    -+import {VRButton} from './resources/threejs/r132/examples/jsm/webxr/VRButton.js';
    +
    import * as THREE from 'three';
    ++import {VRButton} from 'three/addons/webxr/VRButton.js';
     

    이후 three.js's WebXR 지원을 활성화하며, 이를 위한 VR button을 페이지에 추가하여 주어야합니다.

    function main() {
    @@ -347,4 +347,4 @@ 

    VR

    - \ No newline at end of file + diff --git a/manual/list.json b/manual/list.json index bbba61cf0c68d7..eeb6171a5570ad 100644 --- a/manual/list.json +++ b/manual/list.json @@ -52,7 +52,7 @@ "Start making a Game": "en/game" }, "WebXR": { - "VR - Basics": "en/webxr", + "VR - Basics": "en/webxr-basics", "VR - Look To Select": "en/webxr-look-to-select", "VR - Point To Select": "en/webxr-point-to-select" }, @@ -69,7 +69,7 @@ }, "Principes de base": { "Primitives": "fr/primitives", - "Graphique de scène": "fr/scenegraph", + "Graphe de scène": "fr/scenegraph", "Matériaux": "fr/materials", "Textures": "fr/textures", "Lumières": "fr/lights", @@ -113,7 +113,7 @@ "Start making a Game": "fr/game" }, "WebXR": { - "VR - Basics": "fr/webxr", + "VR - Basics": "fr/webxr-basics", "VR - Look To Select": "fr/webxr-look-to-select", "VR - Point To Select": "fr/webxr-point-to-select" }, @@ -174,7 +174,7 @@ "Start making a Game": "ja/game" }, "WebXR": { - "VR - Basics": "ja/webxr", + "VR - Basics": "ja/webxr-basics", "VR - Look To Select": "ja/webxr-look-to-select", "VR - Point To Select": "ja/webxr-point-to-select" }, @@ -235,7 +235,7 @@ "게임 만들기": "ko/game" }, "웹VR": { - "VR - 기본 사항": "ko/webxr", + "VR - 기본 사항": "ko/webxr-basics", "VR - Look To Select": "ko/webxr-look-to-select", "VR - Point To Select": "ko/webxr-point-to-select" }, @@ -296,7 +296,7 @@ "Start making a Game": "ru/game" }, "WebXR": { - "VR - Basics": "ru/webxr", + "VR - Basics": "ru/webxr-basics", "VR - Look To Select": "ru/webxr-look-to-select", "VR - Point To Select": "ru/webxr-point-to-select" }, @@ -305,6 +305,12 @@ } }, "zh": { + "基本": { + "基础": "zh/fundamentals", + "响应式设计": "zh/responsive", + "先决条件": "zh/prerequisites", + "设置": "zh/setup" + }, "基础": { "图元": "zh/primitives", "场景图": "zh/scenegraph", @@ -342,8 +348,8 @@ "后期处理": "zh/post-processing", "Applying a LUT File for effects": "zh/post-processing-3dlut", "Using Shadertoy shaders": "zh/shadertoy", - "对齐HTML元素和3D对象": "zh/align-html-elements-to-3d", - "Using Indexed Textures for Picking and Color": "zh/indexed-textures", + "对齐HTML元素到3D对象": "zh/align-html-elements-to-3d", + "使用纹理索引来拾取和着色": "zh/indexed-textures", "使用Canvas生成动态纹理": "zh/canvas-textures", "广告牌(Billboards)": "zh/billboards", "释放资源": "zh/cleanup", @@ -351,7 +357,7 @@ "Start making a Game": "zh/game" }, "WebXR": { - "VR - Basics": "zh/webxr", + "VR - Basics": "zh/webxr-basics", "VR - Look To Select": "zh/webxr-look-to-select", "VR - Point To Select": "zh/webxr-point-to-select" }, @@ -359,4 +365,4 @@ "材质特性表": "zh/material-table" } } -} +} \ No newline at end of file diff --git a/manual/ru/custom-geometry.html b/manual/ru/custom-geometry.html deleted file mode 100644 index a3fd28e0396151..00000000000000 --- a/manual/ru/custom-geometry.html +++ /dev/null @@ -1,415 +0,0 @@ - - - Пользовательская Geometry - - - - - - - - - - - - - - - - - -
    -
    -

    Пользовательская Geometry

    -
    -
    -
    -
    -NOTE! This article is deprecated. Three.js r125 -removed support for Geometry. Please refer to -the article on custom BufferGeometry. -
    - -

    В предыдущей статье рассказывалось о различных встроенных примитивах, включенных в THREE.js. В этой статье мы рассмотрим создание нашей собственной геометрии.

    -

    Просто для ясности, если вы серьезно относитесь к созданию 3D-контента, наиболее распространенный способ - использовать пакет 3D-моделирования, такой как Blender, -Maya, -3D Studio Max, -Cinema4D и т. д. -Вы создадите модель, а затем экспортируете в gLTF или .obj и загрузите их. -Какой бы вариант вы ни выбрали, рассчитывайте потратить 2 или 3 недели на изучение соответствующих учебных пособий, поскольку все они имеют полезную кривую обучения.

    -

    Тем не менее, бывают случаи, когда мы можем захотеть сгенерировать нашу собственную трехмерную геометрию в коде вместо использования пакета моделирования.

    -

    Сначала давайте просто сделаем куб. Хотя Three.js уже предоставляет нам BoxGeometry и BoxGeometry, куб легко понять, поэтому давайте начнем с него.

    -

    Есть два способа сделать пользовательскую геометрию в THREE.js. Один с классом Geometry, другой - BufferGeometry. У каждого есть свои преимущества. Geometry, возможно, проще в использовании, но медленнее и использует больше памяти. Для нескольких тысяч треугольников это отличный выбор, но для десятков тысяч треугольников может быть лучше использовать BufferGeometry.

    -

    BufferGeometry, возможно, сложнее в использовании, но использует меньше памяти и работает быстрее. Если вы хотите сгенерировать более 10000 треугольников, подумайте об использовании BufferGeometry.

    -

    Заметьте, когда я говорю, что Geometry медленнее, я имею в виду, что она медленнее запускается и медленнее изменяется, но отрисовывается она не медленнее, поэтому, если вы не планируете изменять свою геометрию, тогда, пока она не слишком велика, будет только немного больше. задержка для вашей программы, чтобы начать использовать Geometry против BufferGeometry. Мы изучим оба способа. Пока что давайте использовать геометрию, так как легче понять IMO.

    -

    Сначала давайте сделаем куб с Geometry. Начнем с примера из статьи об отзывчивости.

    -

    Давайте удалим код, который использует BoxGeometry, и заменим ее на Geometry.

    -
    -const boxWidth = 1;
    --const boxHeight = 1;
    --const boxDepth = 1;
    --const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);
    -+const geometry = new THREE.Geometry();
    -
    -

    Теперь давайте добавим 8 углов куба. Вот 8 углов.

    -
    - -

    Сосредоточив вокруг начала координат, мы можем добавить позиции вершин, как это

    -
    const geometry = new THREE.Geometry();
    -+geometry.vertices.push(
    -+  new THREE.Vector3(-1, -1,  1),  // 0
    -+  new THREE.Vector3( 1, -1,  1),  // 1
    -+  new THREE.Vector3(-1,  1,  1),  // 2
    -+  new THREE.Vector3( 1,  1,  1),  // 3
    -+  new THREE.Vector3(-1, -1, -1),  // 4
    -+  new THREE.Vector3( 1, -1, -1),  // 5
    -+  new THREE.Vector3(-1,  1, -1),  // 6
    -+  new THREE.Vector3( 1,  1, -1),  // 7
    -+);
    -
    -

    Затем нам нужно сделать треугольники, по 2 на каждую грань куба

    -
    - -

    Мы делаем это, создавая объекты Face3 и определяя индексы 3 вершин, которые составляют эту грань.

    -

    Порядок, в котором мы указываем вершины, важен. Чтобы указывать на внешнюю сторону куба, они должны быть указаны в направлении против часовой стрелки, когда этот треугольник направлен на камеру.

    -
    - -

    Следуя этой схеме, мы можем указать 12 треугольников, которые делают куб таким

    -
    geometry.faces.push(
    -  // front
    -  new THREE.Face3(0, 3, 2),
    -  new THREE.Face3(0, 1, 3),
    -  // right
    -  new THREE.Face3(1, 7, 3),
    -  new THREE.Face3(1, 5, 7),
    -  // back
    -  new THREE.Face3(5, 6, 7),
    -  new THREE.Face3(5, 4, 6),
    -  // left
    -  new THREE.Face3(4, 2, 6),
    -  new THREE.Face3(4, 0, 2),
    -  // top
    -  new THREE.Face3(2, 7, 6),
    -  new THREE.Face3(2, 3, 7),
    -  // bottom
    -  new THREE.Face3(4, 1, 0),
    -  new THREE.Face3(4, 5, 1),
    -);
    -
    -

    Несколько других мелких изменений в оригинальном коде, и он должен работать.

    -

    Эти кубики в два раза больше, чем BoxGeometry, которую мы использовали раньше, поэтому давайте немного переместим камеру назад

    -
    const fov = 75;
    -const aspect = 2;  // the canvas default
    -const near = 0.1;
    --const far = 5;
    -+const far = 100;
    -const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
    --camera.position.z = 2;
    -+camera.position.z = 5;
    -
    -

    и давайте отделим их немного больше, и я изменил их цвета только потому, что

    -
    const cubes = [
    --  makeInstance(geometry, 0x44aa88,  0),
    --  makeInstance(geometry, 0x8844aa, -2),
    --  makeInstance(geometry, 0xaa8844,  2),
    -+  makeInstance(geometry, 0x44FF44,  0),
    -+  makeInstance(geometry, 0x4444FF, -4),
    -+  makeInstance(geometry, 0xFF4444,  4),
    -];
    -
    -

    И последнее, что мы еще не добавили это нормалей, поэтому мы не можем включить освещение. Давайте изменим материал на то, что не нуждается в освещении.

    -
    function makeInstance(geometry, color, x) {
    --  const material = new THREE.MeshPhongMaterial({color});
    -+  const material = new THREE.MeshBasicMaterial({color});
    -
    -  const cube = new THREE.Mesh(geometry, material);
    -  scene.add(cube);
    -
    -  ...
    -
    -

    и мы получаем кубики, которые мы сделали сами. -

    - -

    -

    Мы можем указать цвет для каждой грани, установив свойство color каждой стороны.

    -
    geometry.faces[ 0].color = geometry.faces[ 1].color = new THREE.Color('red');
    -geometry.faces[ 2].color = geometry.faces[ 3].color = new THREE.Color('yellow');
    -geometry.faces[ 4].color = geometry.faces[ 5].color = new THREE.Color('green');
    -geometry.faces[ 6].color = geometry.faces[ 7].color = new THREE.Color('cyan');
    -geometry.faces[ 8].color = geometry.faces[ 9].color = new THREE.Color('blue');
    -geometry.faces[10].color = geometry.faces[11].color = new THREE.Color('magenta');
    -
    -

    обратите внимание, что мы должны указать материал, который мы хотим использовать vertexColors

    -
    -const material = new THREE.MeshBasicMaterial({color});
    -+const material = new THREE.MeshBasicMaterial({vertexColors: true});
    -
    -

    - -

    -

    Вместо этого мы можем установить цвет каждой отдельной вершины, установив для свойства vertexColors массив из 3 цветов для 3 вершин.

    -
    geometry.faces.forEach((face, ndx) => {
    -  face.vertexColors = [
    -    (new THREE.Color()).setHSL(ndx / 12      , 1, 0.5),
    -    (new THREE.Color()).setHSL(ndx / 12 + 0.1, 1, 0.5),
    -    (new THREE.Color()).setHSL(ndx / 12 + 0.2, 1, 0.5),
    -  ];
    -});
    -
    -

    - -

    -

    Чтобы использовать освещение, нам нужны нормали. Нормали - это векторы, которые определяют направление. Так же, как цвета, мы можем указать нормаль для грани, установив свойство normal для каждой стороны с помощью

    -
    face.normal = new THREE.Vector3(...)
    -
    -

    или мы можем указать нормаль для каждой вершины, установив для свойства vertexNormals что-то вроде

    -
    face.vertexNormals = [
    -  new THREE.Vector3(...),
    -  new THREE.Vector3(...),
    -  new THREE.Vector3(...),
    -]
    -
    -

    но часто гораздо проще просто попросить THREE.js вычислить для нас нормали на основе указанных позиций.

    -

    Для нормалей грани мы бы назвали Geometry.computeFaceNormals как в

    -
    geometry.computeFaceNormals();
    -
    -

    Удаление цвета вершин и изменение материала обратно на MeshPhongMaterial

    -
    -const material = new THREE.MeshBasicMaterial({vertexColors: true});
    -+const material = new THREE.MeshPhongMaterial({color});
    -
    -

    и теперь наши кубики будут освещены. -

    - -

    -

    Использование нормалей сторон всегда даст нам граненый взгляд. Мы можем использовать нормали вершин для более гладкого вида, вызывая Geometry.computeVertexNormals

    -
    -geometry.computeFaceNormals();
    -+geometry.computeVertexNormals();
    -
    -

    К сожалению, куб не является хорошим выбором для нормалей вершин, поскольку это означает, что каждая вершина получает свою нормаль от нормалей всех граней, которые она разделяет.

    -

    - -

    -

    Добавление текстурных координат, иногда называемых UV, выполняется через массив слоев параллельных массивов в массив faces , который устанавливается через Geometry.faceVertexUvs. Для нашего куба мы могли бы сделать что-то вроде

    -
    geometry.faceVertexUvs[0].push(
    -  // front
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
    -  // right
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
    -  // back
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
    -  // left
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
    -  // top
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
    -  // bottom
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
    -  [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
    -);
    -
    -

    Важно отметить, что faceVertexUvs - это массив слоев. Каждый слой представляет собой другой набор координат UV. По умолчанию есть один слой координат UV, слой 0, поэтому мы просто добавляем наши UV в этот слой.

    -

    Давайте добавим текстуру к нашему материалу и переключимся обратно, чтобы вычислить нормали стороны

    -
    -geometry.computeVertexNormals();
    -+geometry.computeFaceNormals();
    -
    -+const loader = new THREE.TextureLoader();
    -+const texture = loader.load('resources/images/star.png');
    -
    -function makeInstance(geometry, color, x) {
    --  const material = new THREE.MeshPhongMaterial({color});
    -+  const material = new THREE.MeshPhongMaterial({color, map: texture});
    -
    -  const cube = new THREE.Mesh(geometry, material);
    -  scene.add(cube);
    -
    -  ...
    -
    -

    - -

    -

    Собрав все это вместе, давайте создадим простую сетку ландшафта на основе карты высот.

    -

    Ландшафт на основе карты высот - это то место, где у вас есть двумерный массив высот, который вы применяете к сетке. Простой способ получить двумерный массив высот - нарисовать их в программе для редактирования изображений. Вот изображение, которое я нарисовал. Это 96x64 пикселей

    -
    - -

    Мы загрузим это и затем сгенерируем из него сетку карты высот. Мы можем использовать ImageLoader для загрузки изображения.

    -
    const imgLoader = new THREE.ImageLoader();
    -imgLoader.load('resources/images/heightmap-96x64.png', createHeightmap);
    -
    -function createHeightmap(image) {
    -  // extract the data from the image by drawing it to a canvas
    -  // and calling getImageData
    -  const ctx = document.createElement('canvas').getContext('2d');
    -  const {width, height} = image;
    -  ctx.canvas.width = width;
    -  ctx.canvas.height = height;
    -  ctx.drawImage(image, 0, 0);
    -  const {data} = ctx.getImageData(0, 0, width, height);
    -
    -  const geometry = new THREE.Geometry();
    -
    -

    Мы извлекли данные из изображения, теперь мы сделаем сетку ячеек. Ячейки - это квадраты, образованные центральными точками каждого пикселя изображения

    -
    - -

    Для каждой ячейки мы сгенерируем 5 вершин. Один для каждого угла ячейки и один в центральной точке ячейки со средней высотой 4 угловых высот.

    -
    const cellsAcross = width - 1;
    -const cellsDeep = height - 1;
    -for (let z = 0; z < cellsDeep; ++z) {
    -  for (let x = 0; x < cellsAcross; ++x) {
    -    // compute row offsets into the height data
    -    // we multiply by 4 because the data is R,G,B,A but we
    -    // only care about R
    -    const base0 = (z * width + x) * 4;
    -    const base1 = base0 + (width * 4);
    -
    -    // look up the height for the for points
    -    // around this cell
    -    const h00 = data[base0] / 32;
    -    const h01 = data[base0 + 4] / 32;
    -    const h10 = data[base1] / 32;
    -    const h11 = data[base1 + 4] / 32;
    -    // compute the average height
    -    const hm = (h00 + h01 + h10 + h11) / 4;
    -
    -    // the corner positions
    -    const x0 = x;
    -    const x1 = x + 1;
    -    const z0 = z;
    -    const z1 = z + 1;
    -
    -    // remember the first index of these 5 vertices
    -    const ndx = geometry.vertices.length;
    -
    -    // add the 4 corners for this cell and the midpoint
    -    geometry.vertices.push(
    -      new THREE.Vector3(x0, h00, z0),
    -      new THREE.Vector3(x1, h01, z0),
    -      new THREE.Vector3(x0, h10, z1),
    -      new THREE.Vector3(x1, h11, z1),
    -      new THREE.Vector3((x0 + x1) / 2, hm, (z0 + z1) / 2),
    -    );
    -
    -

    Затем мы сделаем 4 треугольника из этих 5 вершин

    -
    - -
        // create 4 triangles
    -    geometry.faces.push(
    -      new THREE.Face3(ndx + 0, ndx + 4, ndx + 1),
    -      new THREE.Face3(ndx + 1, ndx + 4, ndx + 3),
    -      new THREE.Face3(ndx + 3, ndx + 4, ndx + 2),
    -      new THREE.Face3(ndx + 2, ndx + 4, ndx + 0),
    -    );
    -
    -    // add the texture coordinates for each vertex of each face
    -    const u0 = x / cellsAcross;
    -    const v0 = z / cellsDeep;
    -    const u1 = (x + 1) / cellsAcross;
    -    const v1 = (z + 1) / cellsDeep;
    -    const um = (u0 + u1) / 2;
    -    const vm = (v0 + v1) / 2;
    -    geometry.faceVertexUvs[0].push(
    -      [ new THREE.Vector2(u0, v0), new THREE.Vector2(um, vm), new THREE.Vector2(u1, v0) ],
    -      [ new THREE.Vector2(u1, v0), new THREE.Vector2(um, vm), new THREE.Vector2(u1, v1) ],
    -      [ new THREE.Vector2(u1, v1), new THREE.Vector2(um, vm), new THREE.Vector2(u0, v1) ],
    -      [ new THREE.Vector2(u0, v1), new THREE.Vector2(um, vm), new THREE.Vector2(u0, v0) ],
    -    );
    -  }
    -}
    -
    -

    и закончим это

    -
      geometry.computeFaceNormals();
    -
    -  // center the geometry
    -  geometry.translate(width / -2, 0, height / -2);
    -
    -  const loader = new THREE.TextureLoader();
    -  const texture = loader.load('resources/images/star.png');
    -
    -  const material = new THREE.MeshPhongMaterial({color: 'green', map: texture});
    -
    -  const cube = new THREE.Mesh(geometry, material);
    -  scene.add(cube);
    -}
    -
    -

    Несколько небольших изменений, чтобы было удобнее просматривать. -включим OrbitControls

    - -
    import * as THREE from '/build/three.module.js';
    -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
    -
    -
    const fov = 75;
    -const aspect = 2;  // the canvas default
    -const near = 0.1;
    --const far = 100;
    -+const far = 200;
    -const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
    --camera.position.z = 5;
    -+camera.position.set(20, 20, 20);
    -
    -+const controls = new OrbitControls(camera, canvas);
    -+controls.target.set(0, 0, 0);
    -+controls.update();
    -
    -

    добавим 2 света

    -
    -{
    -+function addLight(...pos) {
    -  const color = 0xFFFFFF;
    -  const intensity = 1;
    -  const light = new THREE.DirectionalLight(color, intensity);
    --  light.position.set(-1, 2, 4\);
    -+  light.position.set(...pos);
    -  scene.add(light);
    -}
    -
    -+addLight(-1, 2, 4);
    -+addLight(1, 2, -2);
    -
    -

    и мы удалим код, связанный с вращением кубов. -

    - -

    -

    Я надеюсь, что это была полезная инструкция для создания вашей собственной геометрии с использованием Geometry. -В другой статье мы рассмотрим BufferGeometry.

    -

    В другой статье мы рассмотрим BufferGeometry.

    - -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/manual/ru/fundamentals.html b/manual/ru/fundamentals.html index 1487ebd9f720b4..a69b37c9717557 100644 --- a/manual/ru/fundamentals.html +++ b/manual/ru/fundamentals.html @@ -61,7 +61,7 @@

    Основы

    Three.js будет рисовать на этом холсте, так что нам нужно найти его и передать three.js.

    <script type="module">
    -import * as THREE from '../../build/three.module.js';
    +import * as THREE from 'three';
     
     function main() {
       const canvas = document.querySelector('#c');
    diff --git a/manual/ru/lights.html b/manual/ru/lights.html
    index cfddf72d151b1a..3c935008951e22 100644
    --- a/manual/ru/lights.html
    +++ b/manual/ru/lights.html
    @@ -50,8 +50,8 @@ 

    - Освещение

    или поворачивать камеру вокруг некоторой точки. OrbitControls - это дополнительные функции three.js, поэтому сначала нам нужно включить их в нашу страницу.

    -
    import * as THREE from '/build/three.module.js';
    -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
    +
    import * as THREE from 'three';
    ++import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
     

    Теперь мы можем использовать их. Мы передаем в OrbitControls камеру для управления и элемент DOM для получения входных событий

    @@ -414,9 +414,9 @@

    Для использования RectAreaLight нам нужно включить некоторые дополнительные возможности three.js

    -
    import * as THREE from '/build/three.module.js';
    -+import {RectAreaLightUniformsLib} from '/examples/jsm/lights/RectAreaLightUniformsLib.js';
    -+import {RectAreaLightHelper} from '/examples/jsm/helpers/RectAreaLightHelper.js';
    +
    import * as THREE from 'three';
    ++import {RectAreaLightUniformsLib} from 'three/addons/lights/RectAreaLightUniformsLib.js';
    ++import {RectAreaLightHelper} from 'three/addons/helpers/RectAreaLightHelper.js';
     
    function main() {
       const canvas = document.querySelector('#c');
    diff --git a/manual/ru/multiple-scenes.html b/manual/ru/multiple-scenes.html
    index 9789cdae9a8bcc..bc32a2e14d9790 100644
    --- a/manual/ru/multiple-scenes.html
    +++ b/manual/ru/multiple-scenes.html
    @@ -440,7 +440,7 @@ 

    Использование набора данных в HTML

    Добавление элементов управления к каждому элементу

    Например, добавление TrackballControls в интерактивном режиме так же просто. Сначала мы добавляем скрипт для контролов.

    -
    import {TrackballControls} from '/examples/jsm/controls/TrackballControls.js';
    +
    import {TrackballControls} from 'three/addons/controls/TrackballControls.js';
     

    И затем мы можем добавить TrackballControls к каждой сцене, передавая элемент, связанный с этой сценой.

    -function makeScene() {
    diff --git a/manual/ru/offscreencanvas.html b/manual/ru/offscreencanvas.html
    index 29ec8e9eb266c7..d7ccbd1fa1a494 100644
    --- a/manual/ru/offscreencanvas.html
    +++ b/manual/ru/offscreencanvas.html
    @@ -229,7 +229,7 @@ 

    OffscreenCanvas

    shared-cubes.js и offscreencanvas-worker-cubes.js по сути являются разделением нашего предыдущего файла offscreencanvas-cubes.js. Сначала мы копируем весь файл offscreencanvas-cubes.js в shared-cube.js. Затем мы переименовываем main в init, так как у нас уже есть main в нашем HTML-файле, и нам нужно экспортировать init и состояние

    -
    import * as THREE from '../../build/three.module.js';
    +
    import * as THREE from 'three';
     
     -const state = {
     +export const state = {
    @@ -561,7 +561,7 @@ 

    OffscreenCanvas

    А для событий касания нам понадобятся только pageX и pageY из свойства touches.

    Итак, создадим пару прокси-объектов. Одна часть будет работать на главной странице, получать все эти события и передавать соответствующие значения свойств воркеру. Другая часть будет запускаться в воркере, получать эти события и передавать их, используя события, которые имеют ту же структуру, что и исходные события DOM, поэтому OrbitControls не сможет определить разницу.

    Вот код рабочей части.

    -
    import {EventDispatcher} from '../../build/three.module.js';
    +
    import {EventDispatcher} from 'three';
     
     class ElementProxyReceiver extends EventDispatcher {
       constructor() {
    @@ -628,8 +628,8 @@ 

    OffscreenCanvas

    };

    Нам также нужно добавить OrbitControls в начало скрипта.

    -
    import * as THREE from '../../build/three.module.js';
    -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
    +
    import * as THREE from 'three';
    ++import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
     
     export function init(data) {
     -  const {canvas} = data;
    diff --git a/manual/ru/optimize-lots-of-objects-animated.html b/manual/ru/optimize-lots-of-objects-animated.html
    index 9e6ae45c63d779..4866ee05dfa956 100644
    --- a/manual/ru/optimize-lots-of-objects-animated.html
    +++ b/manual/ru/optimize-lots-of-objects-animated.html
    @@ -332,10 +332,10 @@ 

    Оптимизация большого количества анимиро но поскольку оригинальный глобус webgl использует библиотеку анимации давайте используем тот же самый здесь.

    Нам нужно включить библиотеку

    -
    import * as THREE from '/build/three.module.js';
    -import * as BufferGeometryUtils from '/examples/jsm/utils/BufferGeometryUtils.js';
    -import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
    -+import {TWEEN} from '/examples/jsm/libs/tween.min.js';
    +
    import * as THREE from 'three';
    +import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js';
    +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
    ++import {TWEEN} from 'three/addons/libs/tween.min.js';
     

    А затем создайте Tween чтобы оживить влияние.

    // show the selected data, hide the rest
    diff --git a/manual/ru/optimize-lots-of-objects.html b/manual/ru/optimize-lots-of-objects.html
    index 8436ec95620630..937d39bd41c78a 100644
    --- a/manual/ru/optimize-lots-of-objects.html
    +++ b/manual/ru/optimize-lots-of-objects.html
    @@ -380,7 +380,7 @@ 

    Оптимизация большого количества объекто для перемещения вершин каждой геометрии блока, мы могли бы сделать это один раз, а не два.

    В конце мы передаем массив всех геометрий в BufferGeometryUtils.mergeBufferGeometries, который объединит их все в одну сетку.

    Нам также нужно включить BufferGeometryUtils

    -
    import * as BufferGeometryUtils from '/examples/jsm/utils/BufferGeometryUtils.js';
    +
    import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js';
     

    И теперь, по крайней мере на моей машине, я получаю 60 кадров в секунду

    diff --git a/manual/ru/prerequisites.html b/manual/ru/prerequisites.html index eabf15122b48d9..e8101f242694c3 100644 --- a/manual/ru/prerequisites.html +++ b/manual/ru/prerequisites.html @@ -44,7 +44,7 @@

    Необходимые условия

    es6 modules

    Модули es6 можно загружать с помощью ключевого слова import в сценарии или встроенного тега <script type="module">. Вот пример обоих

    <script type="module">
    -import * as THREE from '../../build/three.module.js';
    +import * as THREE from 'three';
     
     ...
     
    diff --git a/manual/ru/rendering-on-demand.html b/manual/ru/rendering-on-demand.html
    index 0399fc7d7c62a2..9a6be7af52cfd1 100644
    --- a/manual/ru/rendering-on-demand.html
    +++ b/manual/ru/rendering-on-demand.html
    @@ -46,8 +46,8 @@ 

    Рендеринг по требованию

    Давайте возьмем пример из статьи об отзывчивости и изменим его для отображения по требованию.

    Сначала мы добавим в OrbitControls, чтобы можно было что-то изменить, что мы можем сделать в ответ.

    -
    import * as THREE from '/build/three.module.js';
    -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
    +
    import * as THREE from 'three';
    ++import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
     

    и настроить их

    const fov = 75;
    @@ -165,9 +165,9 @@ 

    Рендеринг по требованию

    Давайте также добавим простой графический интерфейс lil-gui и внесем его изменения по запросу.

    -
    import * as THREE from '/build/three.module.js';
    -import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
    -+import {GUI} from '/examples/jsm/libs/lil-gui.module.min.js';
    +
    import * as THREE from 'three';
    +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
    ++import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
     

    Давайте позволим установить цвет и шкалу х каждого куба. Чтобы установить цвет, мы будем использовать ColorGUIHelper, который мы создали в статье о светах.

    Сначала нам нужно создать графический интерфейс

    diff --git a/manual/ru/textures.html b/manual/ru/textures.html index 8af2d4c7f774ad..de780edad17269 100644 --- a/manual/ru/textures.html +++ b/manual/ru/textures.html @@ -461,7 +461,7 @@

    Повторе

    Затем мы снова будем использовать lil-gui для обеспечения простого интерфейса.

    -
    import {GUI} from '/examples/jsm/libs/lil-gui.module.min.js';
    +
    import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
     

    Как мы делали в предыдущих примерах lil-gui, мы будем использовать простой класс, чтобы дать lil-gui объект, которым он может манипулировать в градусах, diff --git a/manual/ru/webxr.html b/manual/ru/webxr-basics.html similarity index 100% rename from manual/ru/webxr.html rename to manual/ru/webxr-basics.html diff --git a/manual/zh/align-html-elements-to-3d.html b/manual/zh/align-html-elements-to-3d.html index 35c5c4733d4862..70eedaea161958 100644 --- a/manual/zh/align-html-elements-to-3d.html +++ b/manual/zh/align-html-elements-to-3d.html @@ -3,7 +3,7 @@ - 对齐HTML元素和3D对象 + 对齐HTML元素到3D对象 @@ -31,7 +31,7 @@

    -

    对齐HTML元素和3D对象

    +

    对齐HTML元素到3D对象

    @@ -60,8 +60,8 @@

    对齐HTML元素和3D对象

    我们会添加一个 OrbitControls 就像我们在 这篇光照的文章里做的一样。

    -import * as THREE from '/build/three.module.js';
    -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
    +import * as THREE from 'three'; ++import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
     const controls = new OrbitControls(camera, canvas);
     controls.target.set(0, 0, 0);
    @@ -613,9 +613,9 @@ 

    对齐HTML元素和3D对象

    ...

    最后,由于我不确定这些值设多少好,于是添加一个GUI,就可以调试了

    -
    import * as THREE from '/build/three.module.js';
    -import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
    -+import {GUI} from '/examples/jsm/libs/lil-gui.module.min.js';
    +
    import * as THREE from 'three';
    +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
    ++import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
    +const settings = {
     +  minArea: 20,
     +  maxVisibleDot: -0.2,
    diff --git a/manual/zh/backgrounds.html b/manual/zh/backgrounds.html
    index 7eec9865ed9350..783c003a8ea691 100644
    --- a/manual/zh/backgrounds.html
    +++ b/manual/zh/backgrounds.html
    @@ -188,7 +188,7 @@ 

    背景与天空盒

    }

    让我们添加一些控件,以便我们可以旋转相机。

    import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
    + translate="no">import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
    const fov = 75;
     const aspect = 2;  // Canvas默认值
     const near = 0.1;
    diff --git a/manual/zh/cameras.html b/manual/zh/cameras.html
    index 882faf23c85110..12f47364f98b56 100644
    --- a/manual/zh/cameras.html
    +++ b/manual/zh/cameras.html
    @@ -32,10 +32,10 @@ 

    摄像机

    本文是关于 three.js 系列文章的一部分。第一篇文章是 three.js 基础。如果你还没看过而且对three.js 还不熟悉,那应该从那里开始,并且了解如何设置开发环境。上一篇文章介绍了 three.js 中的 纹理

    -

    我们开始谈谈three.js中的摄像机. 我们已经在第一篇文章 中涉及到了摄像机的一些知识, 这里我们要更深入一些.

    -

    在three.js中最常用的摄像机并且之前我们一直用的摄像机是透视摄像机 PerspectiveCamera, 它可以提供一个近大远小的3D视觉效果.

    -

    PerspectiveCamera 定义了一个 视锥frustum. frustum 是一个切掉顶的三角锥或者说实心金字塔型. -说到实心体solid, 在这里通常是指一个立方体, 一个圆锥, 一个球, 一个圆柱或锥台.

    +

    我们开始谈谈three.js中的摄像机. 我们已经在第一篇文章 中涉及到了摄像机的一些知识,这里我们要更深入一些.

    +

    在three.js中最常用的摄像机并且之前我们一直用的摄像机是透视摄像机 PerspectiveCamera,它可以提供一个近大远小的3D视觉效果.

    +

    PerspectiveCamera 定义了一个 视锥(frustum)frustum 是一个切掉顶的三角锥或者说实心金字塔型。 +说到实心体solid,在这里通常是指一个立方体、一个圆锥、一个球、一个圆柱或锥台。

    立方体
    圆锥
    @@ -44,12 +44,11 @@

    摄像机

    锥台
    -

    重新讲一遍这些东西是因为我好久没有在意过了. 很多书或者文章提到锥台这个东西的时候我扫一眼就过去了. 再了解一下不同几何体会让下面的一些表述变得更为感性...吧😅

    -

    PerspectiveCamera通过四个属性来定义一个视锥. near定义了视锥的前端, far定义了后端, fov是视野, 通过计算正确的高度来从摄像机的位置获得指定的以near为单位的视野, 定义的是视锥的前端和后端的高度. aspect间接地定义了视锥前端和后端的宽度, 实际上视锥的宽度是通过高度乘以aspect来得到的.

    +

    重新讲一遍这些东西是因为我好久没有在意过了。很多书或者文章提到锥台这个东西的时候我扫一眼就过去了。再了解一下不同几何体会让下面的一些表述变得更为感性...吧😅

    +

    PerspectiveCamera通过四个属性来定义一个视锥。near定义了视锥的前端,far定义了后端,fov是视野,通过计算正确的高度来从摄像机的位置获得指定的以near为单位的视野,定义的是视锥的前端和后端的高度。aspect间接地定义了视锥前端和后端的宽度,实际上视锥的宽度是通过高度乘以 aspect 来得到的。

    -

    我们借用上一篇文章的场景. 其中包含一个地平面, 一个球和一个立方体, 我们可以在其中调整摄像机的设置. -· -我们通过MinMaxGUIHelper来调整near, far的设置. 显然near应该总是比far要小. lil-gui有minmax两个属性可调, 然后这两个属性将决定摄像机的设置.

    +

    我们借用上一篇文章的场景. 其中包含一个地平面,一个球和一个立方体,我们可以在其中调整摄像机的设置。 +我们通过MinMaxGUIHelper来调整nearfar的设置。显然near应该总是比far要小。lil-gui 有minmax两个属性可调,然后这两个属性将决定摄像机的设置。

    class MinMaxGUIHelper {
       constructor(obj, minProp, maxProp, minDif) {
         this.obj = obj;
    @@ -73,7 +72,7 @@ 

    摄像机

    } }
    -

    现在我们可以将GUI设置为

    +

    现在我们可以将GUI设置为:

    function updateCamera() {
       camera.updateProjectionMatrix();
     }
    @@ -84,17 +83,17 @@ 

    摄像机

    gui.add(minMaxGUIHelper, 'min', 0.1, 50, 0.1).name('near').onChange(updateCamera); gui.add(minMaxGUIHelper, 'max', 0.1, 50, 0.1).name('far').onChange(updateCamera);
    -

    任何时候摄像机的设置变动, 我们需要调用摄像机的updateProjectionMatrix来更新设置. 我们写一个函数updataCamera, 当lil-gui改变了属性的时候会调用它来更新参数.

    +

    任何时候摄像机的设置变动,我们需要调用摄像机的updateProjectionMatrix来更新设置。我们写一个函数updataCamera,当lil-gui改变了属性的时候会调用它来更新参数。

    -

    现在可以调整这些数值来观察这些参数是如何影响摄像机的. 注意我们并没有改变aspect, 因为这个参数来自于窗口的大小. 如果想调整aspect, 只需要开个新窗口然后调整窗口大小就可以了.

    -

    即便是这样, 观察参数对视野的影响还是挺麻烦的. 所以我们来设置两台摄像机吧! 一台是跟上面一样展现出摄像机中看到的实际场景, 另一个则是用来观察这个实际工作的摄像机, 然后画出摄像机的视锥.

    +

    现在可以调整这些数值来观察这些参数是如何影响摄像机的。注意我们并没有改变aspect,因为这个参数来自于窗口的大小. 如果想调整aspect,只需要开个新窗口然后调整窗口大小就可以了。

    +

    即便是这样,观察参数对视野的影响还是挺麻烦的. 所以我们来设置两台摄像机吧! 一台是跟上面一样展现出摄像机中看到的实际场景,另一个则是用来观察这个实际工作的摄像机,然后画出摄像机的视锥.

    我们需要用到three.js的剪函数(scissor function)来画两个场景和两个摄像机.

    -

    首先让我们用HTML和CSS来定义两个肩并肩的元素. 这也将帮助我们将两个摄像机赋予不同的OrbitControls.

    +

    首先让我们用HTML和CSS来定义两个肩并肩的元素. 这也将帮助我们将两个摄像机赋予不同的OrbitControls

    <body>
       <canvas id="c"></canvas>
     +  <div class="split">
    @@ -103,7 +102,7 @@ 

    摄像机

    + </div> </body>
    -

    CSS将控制两个视窗并排显示在canvas中

    +

    CSS将控制两个视窗并排显示在 canvas 中:

    .split {
       position: absolute;
       left: 0;
    @@ -117,22 +116,22 @@ 

    摄像机

    height: 100%; }
    -

    接下来将添加一个CameraHelper, 它可以把摄像机的视锥画出来

    +

    接下来将添加一个CameraHelper, 它可以把摄像机的视锥画出来:

    const cameraHelper = new THREE.CameraHelper(camera);
     
     ...
     
     scene.add(cameraHelper);
     
    -

    我们现在需要查找到刚刚定义的两个元素

    +

    我们现在需要查找到刚刚定义的两个元素:

    const view1Elem = document.querySelector('#view1');
     const view2Elem = document.querySelector('#view2');
     
    -

    现在只给第一个视窗中的摄像机分配OrbitControls

    +

    现在只给第一个视窗中的摄像机分配OrbitControls

    -const controls = new OrbitControls(camera, canvas);
     +const controls = new OrbitControls(camera, view1Elem);
     
    -

    我们定义第二个PerspectiveCameraOrbitControls.

    +

    我们定义第二个PerspectiveCameraOrbitControls

    const camera2 = new THREE.PerspectiveCamera(
       60,  // fov
       2,   // aspect
    @@ -146,9 +145,8 @@ 

    摄像机

    controls2.target.set(0, 5, 0); controls2.update();
    -

    最后我们需要

    最后,我们需要使用剪刀功能从每个摄影机的视角渲染场景,以仅渲染画布的一部分。 -这个函数接受一个元素, 计算这个元素在canvas上的重叠面积, 这将设置剪刀函数和视角长宽并返回aspect

    +这个函数接受一个元素,计算这个元素在canvas上的重叠面积,这将设置剪刀函数和视角长宽并返回 aspect :

    function setScissorForElement(elem) {
       const canvasRect = canvas.getBoundingClientRect();
       const elemRect = elem.getBoundingClientRect();
    @@ -227,8 +225,8 @@ 

    摄像机

    requestAnimationFrame(render); }
    -

    上面的代码还将主辅摄像机的背景色区分开以利观察.

    -

    我们可以移除updateCamera了, 因为所有的东西在render中更新过了.

    +

    上面的代码还将主辅摄像机的背景色区分开以利观察。

    +

    我们可以移除updateCamera了,因为所有的东西在render中更新过了。

    -function updateCamera() {
     -  camera.updateProjectionMatrix();
     -}
    @@ -242,17 +240,17 @@ 

    摄像机

    +gui.add(minMaxGUIHelper, 'min', 0.1, 50, 0.1).name('near'); +gui.add(minMaxGUIHelper, 'max', 0.1, 50, 0.1).name('far');
    -

    现在我们就可以在辅摄像机中观察到主摄像机的视锥轮廓了.

    +

    现在我们就可以在辅摄像机中观察到主摄像机的视锥轮廓了。

    -

    左侧可以看到主摄像机的视角, 右侧则是辅摄像机观察主摄像机和主摄像机的视锥轮廓. 可以调整near, far, fov和用鼠标移动摄像机来观察视锥轮廓和场景之间的关系.

    -

    near调整到大概20左右, 前景就会在视锥中消失. far低于35时, 远景也不复存在.

    -

    这带来一个问题, 为什么不把near设置到0.0000000001然后将far设置成100000000, 使得一切都可以尽收眼底? 原因是你的GPU 8太行, 没有足够的精度来决定什么在前什么在后. 更糟的是, 在默认情况下, 离摄像机近的将会更清晰, 远的模糊, 从nearfar逐渐过渡.

    -

    从上面的例子出发, 我们向场景中添加20个球

    +

    左侧可以看到主摄像机的视角,右侧则是辅摄像机观察主摄像机和主摄像机的视锥轮廓。可以调整nearfarfov和用鼠标移动摄像机来观察视锥轮廓和场景之间的关系.

    +

    near调整到大概20左右,前景就会在视锥中消失。far低于35时,远景也不复存在.

    +

    这带来一个问题,为什么不把near设置到0.0000000001然后将far设置成100000000,使得一切都可以尽收眼底? 原因是你的GPU没有足够的精度来决定某个东西是另一个东西的前面还是后面。更糟的是,在默认情况下,离摄像机近的将会更清晰,离摄像机远的模糊,从nearfar逐渐过渡。

    +

    从上面的例子出发,我们向场景中添加20个球:

    {
       const sphereRadius = 3;
       const sphereWidthDivisions = 32;
    @@ -280,18 +278,18 @@ 

    摄像机

    -gui.add(minMaxGUIHelper, 'min', 0.1, 50, 0.1).name('near').onChange(updateCamera);
     +gui.add(minMaxGUIHelper, 'min', 0.00001, 50, 0.00001).name('near').onChange(updateCamera);
     
    -

    你觉得会发生什么?

    +

    你觉得会发生什么?

    -

    这就是一个典型的z冲突的例子. GPU没有足够的精度来决定哪个像素在前哪个在后.

    -

    以防你的机器太好出现不了我说的情况, 我把我看到的截图放在这

    +

    这就是一个典型的z冲突的例子。GPU没有足够的精度来决定哪个像素在前哪个在后。

    +

    如果你的机器太好可能不会出现我说的情况,我把我看到的截图放在这:

    -

    解决的方法之一是告诉three.js使用不同的方法计算像素的前后关系. 我们可以在创建WebGLRenderer时开启logarithmicDepthBuffer

    +

    解决的方法之一是告诉three.js使用不同的方法计算像素的前后关系。我们可以在创建WebGLRenderer时开启logarithmicDepthBuffer

    -const renderer = new THREE.WebGLRenderer({canvas});
     +const renderer = new THREE.WebGLRenderer({
     +  canvas,
    @@ -305,12 +303,12 @@ 

    摄像机

    -

    如果这不行的话, 那你就遇到了为什么不能无脑使用这种解决方案的情况了. 到2018年9月, 绝大多数台式机可以但是几乎没有移动设备支持这个功能.

    -

    另一个最好别用这种解决方案的原因是这会大大降低运行速度.

    -

    即便是现在跑得好好地, 选择太小的near和太大的far最终也会遇到同样的问题.

    -

    所以说你需要选择好好抉择nearfar的设置, 来和你的场景配合. 既不丢失重要的近景, 也不让远处的东西消失不见. 如果你想渲染一个巨大的场景, 不但能看清面前的人的眼睫毛又想看到50公里以外的玩意, 你得自己想一个厉害的方案, 这里就不涉及了. 现在, 好好地选个需要的参数就行.

    -

    第二种常见的摄像机是正交摄像机 OrthographicCamera, 和指定一个视锥不同的是, 它需要设置left, right -top, bottom, near, 和far指定一个长方体, 使得视野是平行的而不是透视的.

    +

    如果上面的方案不行的话,那你就遇到了为什么不能无脑使用这种解决方案的情况了。截止2018年9月,绝大多数台式机可以,但几乎没有移动设备支持这个功能。

    +

    另外,最好别用这种解决方案,因为这会大大降低运行速度。

    +

    即便是现在跑得好好地,选择太小的near和太大的far最终也会遇到同样的问题。

    +

    所以说你需要选择好好抉择nearfar的设置,来和你的场景配合。既不丢失重要的近景,也不让远处的东西消失不见。如果你想渲染一个巨大的场景,不但能看清面前的人的眼睫毛又想看到50公里以外的玩意,你得自己想一个厉害的方案,这里就不涉及了。现在,好好地选个适合的参数就行。

    +

    第二种常见的摄像机是正交摄像机 OrthographicCamera,和指定一个视锥不同的是,它需要设置leftright +topbottomnear,和far指定一个长方体,使得视野是平行的而不是透视的。

    我们来把上面的例子改成OrthographicCamera, 首先来设置摄像机

    const left = -1;
     const right = 1;
    @@ -321,13 +319,13 @@ 

    摄像机

    const camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far); camera.zoom = 0.2;
    -

    我们将leftbottom设置成 -1 righttop设成 1, 这样就使盒子宽为两个单位, 高两个单位. 我们接下来通过调整lefttop来选择其aspect. 我们将用zoom属性来调整相机到底展现多少的单位大小.

    -

    给GUI添加zoom设置

    +

    我们将leftbottom设置成 -1 righttop设成 1,这样就使盒子宽为两个单位,高两个单位。我们接下来通过调整lefttop来选择其 aspect 。我们将用zoom属性来调整相机到底展现多少的单位大小。

    +

    给GUI添加zoom设置:

    const gui = new GUI();
     +gui.add(camera, 'zoom', 0.01, 1, 0.01).listen();
     
    -

    listen调用告诉lil-gui去监视属性的变化. 写在这里是因为OrbitControls同样可以控制缩放. 在这个例子中, 鼠标滚轮将会通过OrbitControls控件来控制缩放.

    -

    最后更改aspect然后更新摄像机

    +

    listen调用告诉lil-gui去监视属性的变化。写在这里是因为OrbitControls同样可以控制缩放。在这个例子中,鼠标滚轮将会通过OrbitControls控件来控制缩放。

    +

    最后更改aspect然后更新摄像机:

    {
       const aspect = setScissorForElement(view1Elem);
     
    @@ -345,15 +343,15 @@ 

    摄像机

    renderer.render(scene, camera); }
    -

    现在就可以看到OrthographicCamera工作了.

    +

    现在就可以看到OrthographicCamera工作了。

    -

    大多数情况下, 绘制2D图像的时候会用到OrthographicCamera. 你可以自己决定摄像机的视野大小. 比如说你想让canvas的一个像素匹配摄像机的一个单位, 你可以这么做

    -

    将原点置于中心, 令一个像素等于一个单位

    +

    大多数情况下,绘制2D图像的时候会用到OrthographicCamera。你可以自己决定摄像机的视野大小。比如说你想让 canvas 的一个像素匹配摄像机的一个单位,你可以这么做:

    +

    将原点置于中心,令一个像素等于一个单位

    camera.left = -canvas.width / 2;
     camera.right = canvas.width / 2;
     camera.top = canvas.height / 2;
    @@ -362,7 +360,7 @@ 

    摄像机

    camera.far = 1; camera.zoom = 1;
    -

    或者如果我们想让原点在左上, 就像是2D canvas

    +

    或者如果我们想让原点在左上,就像是2D canvas

    camera.left = 0;
     camera.right = canvas.width;
     camera.top = 0;
    @@ -372,7 +370,7 @@ 

    摄像机

    camera.zoom = 1;

    这样左上角就成了0,0

    -

    试试, 这样设置摄像机

    +

    试试,这样设置摄像机

    const left = 0;
     const right = 300;  // 默认的canvas大小
     const top = 0;
    @@ -382,7 +380,7 @@ 

    摄像机

    const camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far); camera.zoom = 1;
    -

    然后我们载入六个材质, 生成六个平面, 一一对应. 把每一个平面绑定到父对象THREE.Object3D上, 以便调整每个平面和左上角原点的相对关系

    +

    然后我们载入六个材质,生成六个平面,一一对应。把每一个平面绑定到父对象THREE.Object3D上,以便调整每个平面和左上角原点的相对关系

    const loader = new THREE.TextureLoader();
     const textures = [
       loader.load('resources/images/flower-1.jpg'),
    @@ -409,7 +407,7 @@ 

    摄像机

    return planePivot; });
    -

    然后当canvas更新后我们更新摄像机设置

    +

    然后当 canvas 更新后我们更新摄像机设置

    function render() {
     
       if (resizeRendererToDisplaySize(renderer)) {
    @@ -420,7 +418,7 @@ 

    摄像机

    ...
    -

    planesTHREE.Mesh的数组, 每一个对应一个平面. +

    planesTHREE.Mesh的数组,每一个对应一个平面。 现在让它随着时间移动

    function render(time) {
       time *= 0.001;  // 转换为秒;
    @@ -453,18 +451,18 @@ 

    摄像机

    renderer.render(scene, camera);
    -

    你可以看到图片在其中弹跳, 和边际完美契合, 就是2D canvas的效果一样

    +

    你可以看到图片在其中弹跳,和边际完美契合,就是2D canvas的效果一样

    -

    另一个常见的用途是用OrthographicCamera来展示模型的三视图.

    +

    另一个常见的用途是用OrthographicCamera来展示模型的三视图。

    -

    上面的截图展示了一个透视图和三个正交视角.

    -

    这就是摄像机的基础. 我们在其他的文章中会介绍另外的一些摄像机用法. 现在, 我们移步到阴影.

    +

    上面的截图展示了一个透视图和三个正交视角。

    +

    这就是摄像机的基础. 我们在其他的文章中会介绍另外的一些摄像机用法。现在,我们移步到阴影

    diff --git a/manual/zh/canvas-textures.html b/manual/zh/canvas-textures.html index 273b804d57f2c9..989f24ef1922b7 100644 --- a/manual/zh/canvas-textures.html +++ b/manual/zh/canvas-textures.html @@ -230,8 +230,8 @@

    Canvas 纹理

    +makePerson(-0, 32, 'Green Machine', 'green'); +makePerson(+3, 32, 'Red Menace', 'red');

    剩下的就是添加 OrbitControls 这样我们就可以移动相机了。

    -
    import * as THREE from '/build/three.module.js';
    -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
    +
    import * as THREE from 'three';
    ++import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
    const fov = 75;
     const aspect = 2;  // Canvas默认值
     const near = 0.1;
    diff --git a/manual/zh/custom-geometry.html b/manual/zh/custom-geometry.html
    deleted file mode 100644
    index d145c9ce5b668c..00000000000000
    --- a/manual/zh/custom-geometry.html
    +++ /dev/null
    @@ -1,47 +0,0 @@
    -
    -    
    -    Custom Geometry
    -    
    -    
    -    
    -    
    -    
    -    
    -    
    -
    -    
    -    
    -
    -
    -
    -
    -
    -    
    -  
    -  
    -    
    -
    -

    Custom Geometry

    -
    -
    -
    -

    抱歉,还没有中文翻译哦。 欢迎加入翻译! 😄

    -

    英文原文链接.

    - -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/manual/zh/fundamentals.html b/manual/zh/fundamentals.html index c545f8630185d3..b9534574d89d35 100644 --- a/manual/zh/fundamentals.html +++ b/manual/zh/fundamentals.html @@ -74,7 +74,7 @@

    基础

    首先是加载three.js

    <script type="module">
    -import * as THREE from '../../build/three.module.js';
    +import * as THREE from 'three';
     </script>
     

    type="module"放到script标签中很重要。这可以让我们使用import关键字加载three.js。还有其他的方法可以加载three.js,但是自r106开始,使用模块是最推荐的方式。模块的优点是可以很方便地导入需要的其他模块。这样我们就不用再手动引入它们所依赖的其他文件了。

    @@ -85,7 +85,7 @@

    基础

    Three.js需要使用这个canvas标签来绘制,所以我们要先获取它然后传给three.js。

    <script type="module">
    -import * as THREE from '../../build/three.module.js';
    +import * as THREE from 'three';
     
     +function main() {
     +  const canvas = document.querySelector('#c');
    @@ -258,7 +258,7 @@ 

    es6模块,three.js,和文件夹结构

    在一个脚本中,es6模块可以通过import关键字加载或者通过<script type="module">行内标签。这有一个两种方法都用的例子。

    <script type="module">
    -import * as THREE from '../../build/three.module.js';
    +import * as THREE from 'three';
     
     ...
     
    @@ -302,12 +302,12 @@ 

    es6模块,three.js,和文件夹结构

    使用相同的结构保证了当你导入three和任一示例库时,它们都会引用同一个three.module.js文件。

    import * as THREE from './someFolder/build/three.module.js';
    -import {OrbitControls} from './someFolder/examples/jsm/controls/OrbitControls.js';
    +import {OrbitControls} from './someFolder/addons/controls/OrbitControls.js';
     

    在使用CDN时,是同样的道理。确保three.modules.js的路径以 /build/three.modules.js结尾,比如

    import * as THREE from 'https://unpkg.com/three@0.108.0/build/three.module.js';
    -import {OrbitControls} from 'https://unpkg.com/three@0.108.0/examples/jsm/controls/OrbitControls.js';
    +import {OrbitControls} from 'https://unpkg.com/three@0.108.0/addons/controls/OrbitControls.js';
     

    diff --git a/manual/zh/indexed-textures.html b/manual/zh/indexed-textures.html index f2f9a9ebc56c4d..5e290b0fd68925 100644 --- a/manual/zh/indexed-textures.html +++ b/manual/zh/indexed-textures.html @@ -1,47 +1,607 @@ - - - Indexed Textures for Picking and Color - - - - - - - - - - - - - - - + + - - - -
    -
    -

    Indexed Textures for Picking and Color

    -
    -
    -
    -

    抱歉,还没有中文翻译哦。 欢迎加入翻译! 😄

    -

    英文原文链接.

    + + + + +
    +
    +

    使用纹理索引来拾取和着色

    +
    +
    +
    +

    这篇文章是 对齐HTML元素到3D对象 的延续。 + 如果你还没有读过上篇文章,你应该先从那里开始,然后再回来继续阅读。

    +

    有时候使用Three.js需要提出一些创造性的解决思路。我不确定这是一个很好的解决方案,但我想我会分享它,你可以看看是否可以为你的需求提供了一些解决思路或方案。

    +

    上一篇文章中,我们在3D地球周围显示了国家名称,那么我们如何做到,让用户选中一个国家并高亮他的选择?

    +

    第一个想法是为每个国家生成几何图形,我们可以 使用射线拾取 ,就像之前介绍的那样。 + 我们将为每个国家构建3D几何对象。如果用户点击代表那个国家的网格对象,我们就会知道对应的国家被点击了。

    +

    所以,为了验证这个解决方案,我尝试生成所有国家的3D网格对象,使用了在上一篇文章中和我生成轮廓一样的数据。 + 结果生成了15.5m的二进制GLTF(.glb)文件,让用户下载15.5m的数据对于我来说实在太多了。 +

    +

    有很多方法可以压缩数据。第一种可能是应用一些算法来降低轮廓的分辨率,但是我没有花时间来研究它。可能出现美国边界变大而加拿大边界变小的情况。

    +

    另一种解决方案是仅使用数据压缩,比如gzip将其降至11m,这减少了30%,但是还不够。

    +

    我们可以将所有数据存储为16位而不是32位浮点值。或者我们也可以使用像draco 压缩 + 这种东西也许就够了。不过我没有去试,我推荐你去试下回来告诉我是怎么回事,因为我很想知道😅

    +

    就我而言,我考虑使用 GPU拾取方案, + 这在上一篇 关于拾取的文章 的最后有提到。这种方案中,我们使用一种独特的颜色代表不同网格对象的ID,然后我们绘制了所有网格,看看哪个颜色被点击了。

    +

    基于这种灵感,我们可以预先生成一张国家的地图,每个国家的颜色是它在国家数组中的索引号。我们可以使用类似GPU拾取技术,我们使用索引纹理绘制一个离屏全局画布,查看颜色会告诉我们用户点击了那个国家ID。

    +

    因此,我 写了一些代码 + 生成这样的一个纹理,在这里:

    +
    + +

    注意:生成这份纹理的数据来源于 这个网站 + ,使用的协议是 CC-BY-SA

    +

    它只有217k,比国家网格对象的15m要好得多,事实上我们可以使用更低的分辨率,但现在217k似乎已经足够了。

    +

    所以让我们试着用它来选择国家。

    +

    GPU拾取案例中 获取代码,我们需要一个场景来做拾取。

    +
    const pickingScene = new THREE.Scene();
    +pickingScene.background = new THREE.Color(0);
    +
    +

    我们需要将带有索引纹理的地球添加到拾取场景中。

    +
    {
    +  const loader = new THREE.TextureLoader();
    +  const geometry = new THREE.SphereGeometry(1, 64, 32);
    +
    ++  const indexTexture = loader.load('resources/data/world/country-index-texture.png', render);
    ++  indexTexture.minFilter = THREE.NearestFilter;
    ++  indexTexture.magFilter = THREE.NearestFilter;
    ++
    ++  const pickingMaterial = new THREE.MeshBasicMaterial({map: indexTexture});
    ++  pickingScene.add(new THREE.Mesh(geometry, pickingMaterial));
    +
    +  const texture = loader.load('resources/data/world/country-outlines-4k.png', render);
    +  const material = new THREE.MeshBasicMaterial({map: texture});
    +  scene.add(new THREE.Mesh(geometry, material));
    +}
    +
    +

    然后我们把 GPUPickingHelper这个类拷贝下,在使用前我们需要做一些小改动

    +
    class GPUPickHelper {
    +  constructor() {
    +    // 创造一个 1x1 的渲染对象
    +    this.pickingTexture = new THREE.WebGLRenderTarget(1, 1);
    +    this.pixelBuffer = new Uint8Array(4);
    +-    this.pickedObject = null;
    +-    this.pickedObjectSavedColor = 0;
    +  }
    +  pick(cssPosition, scene, camera) {
    +    const {pickingTexture, pixelBuffer} = this;
    +
    +    // 将视图偏移设置为仅表示鼠标下单个元素
    +    const pixelRatio = renderer.getPixelRatio();
    +    camera.setViewOffset(
    +        renderer.getContext().drawingBufferWidth,   // full width
    +        renderer.getContext().drawingBufferHeight,  // full top
    +        cssPosition.x * pixelRatio | 0,             // rect x
    +        cssPosition.y * pixelRatio | 0,             // rect y
    +        1,                                          // rect width
    +        1,                                          // rect height
    +    );
    +    // 渲染场景
    +    renderer.setRenderTarget(pickingTexture);
    +    renderer.render(scene, camera);
    +    renderer.setRenderTarget(null);
    +    // 清除视图偏移,使渲染恢复正常
    +    camera.clearViewOffset();
    +    // 读取像素
    +    renderer.readRenderTargetPixels(
    +        pickingTexture,
    +        0,   // x
    +        0,   // y
    +        1,   // width
    +        1,   // height
    +        pixelBuffer);
    +
    ++    const id =
    ++        (pixelBuffer[0] << 16) |
    ++        (pixelBuffer[1] <<  8) |
    ++        (pixelBuffer[2] <<  0);
    ++
    ++    return id;
    +-    const id =
    +-        (pixelBuffer[0] << 16) |
    +-        (pixelBuffer[1] <<  8) |
    +-        (pixelBuffer[2]      );
    +-    const intersectedObject = idToObject[id];
    +-    if (intersectedObject) {
    +-      // 获取第一个对象,它是离我们最近的
    +-      this.pickedObject = intersectedObject;
    +-      // 保存它的颜色
    +-      this.pickedObjectSavedColor = this.pickedObject.material.emissive.getHex();
    +-      // 将其自发光颜色设置为闪烁的红色/黄色
    +-      this.pickedObject.material.emissive.setHex((time * 8) % 2 > 1 ? 0xFFFF00 : 0xFF0000);
    +-    }
    +  }
    +}
    +
    +

    现在我们可以用它来选择国家了。

    +
    const pickHelper = new GPUPickHelper();
    +
    +function getCanvasRelativePosition(event) {
    +  const rect = canvas.getBoundingClientRect();
    +  return {
    +    x: (event.clientX - rect.left) * canvas.width  / rect.width,
    +    y: (event.clientY - rect.top ) * canvas.height / rect.height,
    +  };
    +}
    +
    +function pickCountry(event) {
    +  // 如果我们还没有加载好数据,退出
    +  if (!countryInfos) {
    +    return;
    +  }
    +
    +  const position = getCanvasRelativePosition(event);
    +  const id = pickHelper.pick(position, pickingScene, camera);
    +  if (id > 0) {
    +    // 我们点击了一个国家,修改它的selected属性
    +    const countryInfo = countryInfos[id - 1];
    +    const selected = !countryInfo.selected;
    +    // 如果我们选中这个国家,并且没有按住控制键,取消所有选中的国家
    +    if (selected && !event.shiftKey && !event.ctrlKey && !event.metaKey) {
    +      unselectAllCountries();
    +    }
    +    numCountriesSelected += selected ? 1 : -1;
    +    countryInfo.selected = selected;
    +  } else if (numCountriesSelected) {
    +    // 海洋或者天空被选中了
    +    unselectAllCountries();
    +  }
    +  requestRenderIfNotRequested();
    +}
    +
    +function unselectAllCountries() {
    +  numCountriesSelected = 0;
    +  countryInfos.forEach((countryInfo) => {
    +    countryInfo.selected = false;
    +  });
    +}
    +
    +canvas.addEventListener('pointerup', pickCountry);
    +
    +

    上面的代码,设置/重置了国家数组元素的 selected 属性。如果 shiftctrlcmd + 被按下了,你就可以选择多个国家。

    +

    剩下的就是显示选择的国家,现在让我们更新标签

    +
    function updateLabels() {
    +  // 如果我们还没有加载好数据,退出
    +  if (!countryInfos) {
    +    return;
    +  }
    +
    +  const large = settings.minArea * settings.minArea;
    +  // 获取表示相机正对方向的矩阵
    +  normalMatrix.getNormalMatrix(camera.matrixWorldInverse);
    +  // 获取相机位置
    +  camera.getWorldPosition(cameraPosition);
    +  for (const countryInfo of countryInfos) {
    +-    const {position, elem, area} = countryInfo;
    +-    // 足够大了?
    +-    if (area < large) {
    ++    const {position, elem, area, selected} = countryInfo;
    ++    const largeEnough = area >= large;
    ++    const show = selected || (numCountriesSelected === 0 && largeEnough);
    ++    if (!show) {
    +      elem.style.display = 'none';
    +      continue;
    +    }
    +
    +    ...
    +
    +

    通过上面的代码,我们就有能力拾取对应的国家了。

    +

    + + +

    +

    代码仍然会根据地区显示对应的国家。不过如果你点击一个,只会显示对应的标签。

    +

    所以这似乎是选择国家的有效解决方案,但是如何突出显示选定的国家?

    +

    我们可以从 调色板图形算法 中获取灵感。

    +

    调色板算法 + 或者 索引颜色 + 是被旧的系统,比如Atari 800、Amiga、NES、Super Nintendolder及IBM + PCs所使用的。并非以RGBA的形式给每个颜色存储8位、每个像素至少32字节的位图,他们存储位图是8位或者更少。每个像素都是一个调色板的索引值, + 所以举例一个像素值为3,表示“显示3号颜色值”,而定义3号颜色值的地方就叫“调色板”。

    +

    在JavaScript中就像这样:

    +
    const face7x7PixelImageData = [
    +  0, 1, 1, 1, 1, 1, 0,
    +  1, 0, 0, 0, 0, 0, 1,
    +  1, 0, 2, 0, 2, 0, 1,
    +  1, 0, 0, 0, 0, 0, 1,
    +  1, 0, 3, 3, 3, 0, 1,
    +  1, 0, 0, 0, 0, 0, 1,
    +  0, 1, 1, 1, 1, 1, 1,
    +];
    +
    +const palette = [
    +  [255, 255, 255],  // 白
    +  [  0,   0,   0],  // 黑
    +  [  0, 255, 255],  // 青
    +  [255,   0,   0],  // 红
    +];
    +
    +

    图像数据中每个像素都是调色板的索引,如果你分析上面调色板的数据你会得到这个图像:

    +
    + +

    + 在我们的例子中,上面已经有一个用不同id代表不同国家的纹理了,所以我们可以通过调色板使用相同的纹理赋予每个国家各自的颜色。通过更改调色板颜色我们可以为单独的国家着色。比如通过设置整个调色板纹理为黑色,给某个国家使用不同的颜色,就可以凸显那个国家了。 +

    +

    要做调色板索引的话,需要一些自定义着色器代码,让我们修改Three.js中默认的着色器,这样我们也可以根据需要使用照明或其他特性。

    +

    就像我们在 大量移动物体的优化 这篇文章中提到的,通过 + onBeforeCompile 属性,我们可以通过向材质添加函数来修改默认的着色器。 +

    +

    默认的片元着色器在编译之前看起来就像这样:

    +
    #include <common>
    +#include <color_pars_fragment>
    +#include <uv_pars_fragment>
    +#include <uv2_pars_fragment>
    +#include <map_pars_fragment>
    +#include <alphamap_pars_fragment>
    +#include <aomap_pars_fragment>
    +#include <lightmap_pars_fragment>
    +#include <envmap_pars_fragment>
    +#include <fog_pars_fragment>
    +#include <specularmap_pars_fragment>
    +#include <logdepthbuf_pars_fragment>
    +#include <clipping_planes_pars_fragment>
    +void main() {
    +    #include <clipping_planes_fragment>
    +    vec4 diffuseColor = vec4( diffuse, opacity );
    +    #include <logdepthbuf_fragment>
    +    #include <map_fragment>
    +    #include <color_fragment>
    +    #include <alphamap_fragment>
    +    #include <alphatest_fragment>
    +    #include <specularmap_fragment>
    +    ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
    +    #ifdef USE_LIGHTMAP
    +        reflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;
    +    #else
    +        reflectedLight.indirectDiffuse += vec3( 1.0 );
    +    #endif
    +    #include <aomap_fragment>
    +    reflectedLight.indirectDiffuse *= diffuseColor.rgb;
    +    vec3 outgoingLight = reflectedLight.indirectDiffuse;
    +    #include <envmap_fragment>
    +    gl_FragColor = vec4( outgoingLight, diffuseColor.a );
    +    #include <premultiplied_alpha_fragment>
    +    #include <tonemapping_fragment>
    +    #include <encodings_fragment>
    +    #include <fog_fragment>
    +}
    +
    +

    查看所有的片段 + 我们发现THREE.js使用了一个名为 diffuseColor 的变量去管理基本材质颜色。它在这里设置: <color_fragment> 片段 + 所以我们应该能够在这部分之后进行修改。

    +

    diffuseColor + 在这个时刻应该已经是从我们轮廓纹理中获取的颜色了,所以我们应该可以从调色盘中获取颜色,然后把他们和最终颜色混合。

    +

    就像我们 之前做的那样 , + 在Material.onBeforeCompile我们使用一个用来搜索和替换着色器代码的数组。 +

    +
    {
    +  const loader = new THREE.TextureLoader();
    +  const geometry = new THREE.SphereGeometry(1, 64, 32);
    +
    +  const indexTexture = loader.load('resources/data/world/country-index-texture.png', render);
    +  indexTexture.minFilter = THREE.NearestFilter;
    +  indexTexture.magFilter = THREE.NearestFilter;
    +
    +  const pickingMaterial = new THREE.MeshBasicMaterial({map: indexTexture});
    +  pickingScene.add(new THREE.Mesh(geometry, pickingMaterial));
    +
    ++  const fragmentShaderReplacements = [
    ++    {
    ++      from: '#include <common>',
    ++      to: `
    ++        #include <common>
    ++        uniform sampler2D indexTexture;
    ++        uniform sampler2D paletteTexture;
    ++        uniform float paletteTextureWidth;
    ++      `,
    ++    },
    ++    {
    ++      from: '#include <color_fragment>',
    ++      to: `
    ++        #include <color_fragment>
    ++        {
    ++          vec4 indexColor = texture2D(indexTexture, vUv);
    ++          float index = indexColor.r * 255.0 + indexColor.g * 255.0 * 256.0;
    ++          vec2 paletteUV = vec2((index + 0.5) / paletteTextureWidth, 0.5);
    ++          vec4 paletteColor = texture2D(paletteTexture, paletteUV);
    ++          // diffuseColor.rgb += paletteColor.rgb;   // 白轮廓
    ++          diffuseColor.rgb = paletteColor.rgb - diffuseColor.rgb;  // 黑轮廓
    ++        }
    ++      `,
    ++    },
    ++  ];
     
    +  const texture = loader.load('resources/data/world/country-outlines-4k.png', render);
    +  const material = new THREE.MeshBasicMaterial({map: texture});
    ++  material.onBeforeCompile = function(shader) {
    ++    fragmentShaderReplacements.forEach((rep) => {
    ++      shader.fragmentShader = shader.fragmentShader.replace(rep.from, rep.to);
    ++    });
    ++  };
    +  scene.add(new THREE.Mesh(geometry, material));
    +}
    +
    +

    在上面可以看到我们添加了3个uniforms变量,indexTexture, paletteTexture, + and paletteTextureWidth。我们从 indexTexture + 获取颜色,并且把它转化成索引下标。 vUv + 是由Three.js提供的纹理坐标。然后我们使用索引下标从调色板中获取颜色。然后我们使用当前的 diffuseColor和最终的结果作混合。 + diffuseColor在此时是我们黑色纹理,而调色盘是白色纹理。所以如果我们相加两个颜色,得出的是白色轮廓。如果我们二者相减,得出的是黑色轮廓。 +

    +

    在我们渲染前,我们还需要设置调色板纹理,以及这3个uniforms变量。

    +

    对于调色板纹理,它只需要足够宽即可。每个国家保留一种颜色 + 一种海洋颜色。这里有240个国家或地区,我们可以等到国家列表加载完成后以获取确切的数字来查找。不过选择一些更大的数字没有危害,所以让我们选择512。

    +

    这里是创建调色板的代码

    +
    const maxNumCountries = 512;
    +const paletteTextureWidth = maxNumCountries;
    +const paletteTextureHeight = 1;
    +const palette = new Uint8Array(paletteTextureWidth * 4);
    +const paletteTexture = new THREE.DataTexture(
    +    palette, paletteTextureWidth, paletteTextureHeight);
    +paletteTexture.minFilter = THREE.NearestFilter;
    +paletteTexture.magFilter = THREE.NearestFilter;
    +
    +

    一个DataTexture 提供原始的纹理数据。在这种情况下,我们给他512个RGBA颜色,每个颜色4字节,每个包含0-255的红、绿、蓝分量。

    +

    让我们用随机颜色填充它,只是为了看看它是否有效

    +
    for (let i = 1; i < palette.length; ++i) {
    +  palette[i] = Math.random() * 256;
    +}
    +// 设置海洋颜色 (索引 #0)
    +palette.set([100, 200, 255, 255], 0);
    +paletteTexture.needsUpdate = true;
    +
    +

    任何时候我们想要Three.js通过 palette 数组的内容来更新调色板上的纹理,我们需要去设置paletteTexture.needsUpdate + 为 true

    +

    然后我们还需要设置材质上的uniforms变量

    +
    const geometry = new THREE.SphereGeometry(1, 64, 32);
    +const material = new THREE.MeshBasicMaterial({map: texture});
    +material.onBeforeCompile = function(shader) {
    +  fragmentShaderReplacements.forEach((rep) => {
    +    shader.fragmentShader = shader.fragmentShader.replace(rep.from, rep.to);
    +  });
    ++  shader.uniforms.paletteTexture = {value: paletteTexture};
    ++  shader.uniforms.indexTexture = {value: indexTexture};
    ++  shader.uniforms.paletteTextureWidth = {value: paletteTextureWidth};
    +};
    +scene.add(new THREE.Mesh(geometry, material));
    +
    +

    这样我们就得到了随机着色的国家

    +

    + + +

    +

    现在我们可以看到索引和调色板纹理生效了,让我们控制调色板进行高亮显示

    +

    首先让我们创建一个函数,我们传入一个THREE.js颜色,并格式化为可以放入调色板纹理的值。

    +
    const tempColor = new THREE.Color();
    +function get255BasedColor(color) {
    +  tempColor.set(color);
    +  const base = tempColor.toArray().map(v => v * 255);
    +  base.push(255); // alpha
    +  return base;
    +}
    +
    +

    像这样来调用 color = get255BasedColor('red') 会返回一个像 [255, 0, 0, 255]这样的数组。

    +

    接下来让我们用它来生成一些颜色并填充调色板。

    +
    const selectedColor = get255BasedColor('red');
    +const unselectedColor = get255BasedColor('#444');
    +const oceanColor = get255BasedColor('rgb(100,200,255)');
    +resetPalette();
    +
    +function setPaletteColor(index, color) {
    +  palette.set(color, index * 4);
    +}
    +
    +function resetPalette() {
    +  // 让所有的颜色都是未选择状态的颜色
    +  for (let i = 1; i < maxNumCountries; ++i) {
    +    setPaletteColor(i, unselectedColor);
    +  }
    +
    +  // 设置海洋颜色 (索引 #0)
    +  setPaletteColor(0, oceanColor);
    +  paletteTexture.needsUpdate = true;
    +}
    +
    +

    现在让我们使用这些函数来更新调色板,当一个国家被选中时:

    +
    function getCanvasRelativePosition(event) {
    +  const rect = canvas.getBoundingClientRect();
    +  return {
    +    x: (event.clientX - rect.left) * canvas.width  / rect.width,
    +    y: (event.clientY - rect.top ) * canvas.height / rect.height,
    +  };
    +}
    +
    +function pickCountry(event) {
    +  // 如果我们还没有加载好数据,退出
    +  if (!countryInfos) {
    +    return;
    +  }
    +
    +  const position = getCanvasRelativePosition(event);
    +  const id = pickHelper.pick(position, pickingScene, camera);
    +  if (id > 0) {
    +    const countryInfo = countryInfos[id - 1];
    +    const selected = !countryInfo.selected;
    +    if (selected && !event.shiftKey && !event.ctrlKey && !event.metaKey) {
    +      unselectAllCountries();
    +    }
    +    numCountriesSelected += selected ? 1 : -1;
    +    countryInfo.selected = selected;
    ++    setPaletteColor(id, selected ? selectedColor : unselectedColor);
    ++    paletteTexture.needsUpdate = true;
    +  } else if (numCountriesSelected) {
    +    unselectAllCountries();
    +  }
    +  requestRenderIfNotRequested();
    +}
    +
    +function unselectAllCountries() {
    +  numCountriesSelected = 0;
    +  countryInfos.forEach((countryInfo) => {
    +    countryInfo.selected = false;
    +  });
    ++  resetPalette();
    +}
    +
    +

    我们应该能够突出显示1个或多个国家。

    +

    + + +

    +

    这看起来有效!

    +

    一件小事是我们不能不改变选中状态就渲染地球。如果我们选择一个国家然后想要旋转地球,选中状态将改变。

    +

    让我们尝试解决这个问题。我认为,我们可以检查两件事情。点击和松开经过了多少时间;用户是否移动了鼠标。如果时间很短,或者他们没有移动鼠标,那么这个行为可能是点击。否则他们可能正在尝试拖动地球。

    +
    +const maxClickTimeMs = 200;
    ++const maxMoveDeltaSq = 5 * 5;
    ++const startPosition = {};
    ++let startTimeMs;
    ++
    ++function recordStartTimeAndPosition(event) {
    ++  startTimeMs = performance.now();
    ++  const pos = getCanvasRelativePosition(event);
    ++  startPosition.x = pos.x;
    ++  startPosition.y = pos.y;
    ++}
    +
    +function getCanvasRelativePosition(event) {
    +  const rect = canvas.getBoundingClientRect();
    +  return {
    +    x: (event.clientX - rect.left) * canvas.width  / rect.width,
    +    y: (event.clientY - rect.top ) * canvas.height / rect.height,
    +  };
    +}
    +
    +function pickCountry(event) {
    +  // exit if we have not loaded the data yet
    +  if (!countryInfos) {
    +    return;
    +  }
    +
    ++  // 如果用户触发后已经过了一段时间了
    ++  // 就认为这是一个拖动行为
    ++  const clickTimeMs = performance.now() - startTimeMs;
    ++  if (clickTimeMs > maxClickTimeMs) {
    ++    return;
    ++  }
    ++
    ++  // 如果鼠标移动了,就认为这是一个拖动行为
    ++  const position = getCanvasRelativePosition(event);
    ++  const moveDeltaSq = (startPosition.x - position.x) ** 2 +
    ++                      (startPosition.y - position.y) ** 2;
    ++  if (moveDeltaSq > maxMoveDeltaSq) {
    ++    return;
    ++  }
    +
    +-  const position = {x: event.clientX, y: event.clientY};
    +  const id = pickHelper.pick(position, pickingScene, camera);
    +  if (id > 0) {
    +    const countryInfo = countryInfos[id - 1];
    +    const selected = !countryInfo.selected;
    +    if (selected && !event.shiftKey && !event.ctrlKey && !event.metaKey) {
    +      unselectAllCountries();
    +    }
    +    numCountriesSelected += selected ? 1 : -1;
    +    countryInfo.selected = selected;
    +    setPaletteColor(id, selected ? selectedColor : unselectedColor);
    +    paletteTexture.needsUpdate = true;
    +  } else if (numCountriesSelected) {
    +    unselectAllCountries();
    +  }
    +  requestRenderIfNotRequested();
    +}
    +
    +function unselectAllCountries() {
    +  numCountriesSelected = 0;
    +  countryInfos.forEach((countryInfo) => {
    +    countryInfo.selected = false;
    +  });
    +  resetPalette();
    +}
    +
    ++canvas.addEventListener('pointerdown', recordStartTimeAndPosition);
    +canvas.addEventListener('pointerup', pickCountry);
    +
    +

    添加了这些操作,这看起来 对我有效。

    +

    + + +

    +

    我不是用户交互的专家,所以我很想知道是否有更好的解决方案。

    +

    我希望这能让你了解图形索引的用处,以及如何修改Three.js的着色器以添加简单的功能。对于如何使用GLSL,编写着色器语言对于本文来说太多了,这个链接有一些少量的信息,参考 + 关于后处理的这篇文章。 +

    +
    - +
    + - \ No newline at end of file + + + \ No newline at end of file diff --git a/manual/zh/lights.html b/manual/zh/lights.html index e56c5f21e85a28..72bcf01a976b13 100644 --- a/manual/zh/lights.html +++ b/manual/zh/lights.html @@ -42,8 +42,8 @@

    光照

    +camera.position.set(0, 10, 20);

    然后我们添加一个 OrbitControlsOrbitControls 让我们可以围绕某一个点旋转控制相机。OrbitControls 是 three.js 的可选模块,所以我们首先需要引入这个模块。

    -
    import * as THREE from '/build/three.module.js';
    -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
    +
    import * as THREE from 'three';
    ++import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
     

    然后我们就可以使用了。创建 OrbitControls 时传入两个参数,一个是要控制的相机对象,第二个是检测事件的 DOM 元素。

    const controls = new OrbitControls(camera, canvas);
    @@ -338,9 +338,9 @@ 

    矩形区域光(RectAreaLight,我们需要引入 three.js 的RectAreaLightUniformsLib 模块,同时使用 RectAreaLightHelper 来辅助查看灯光对象。

    -
    import * as THREE from '/build/three.module.js';
    -+import {RectAreaLightUniformsLib} from '/examples/jsm/lights/RectAreaLightUniformsLib.js';
    -+import {RectAreaLightHelper} from '/examples/jsm/helpers/RectAreaLightHelper.js';
    +
    import * as THREE from 'three';
    ++import {RectAreaLightUniformsLib} from 'three/addons/lights/RectAreaLightUniformsLib.js';
    ++import {RectAreaLightHelper} from 'three/addons/helpers/RectAreaLightHelper.js';
     

    我们需要先调用 RectAreaLightUniformsLib.init

    function main() {
    diff --git a/manual/zh/load-gltf.html b/manual/zh/load-gltf.html
    index c5c981bde235eb..08e47b1c7d2f58 100644
    --- a/manual/zh/load-gltf.html
    +++ b/manual/zh/load-gltf.html
    @@ -104,10 +104,10 @@ 

    加载 .gltf 文件

    我们需要包含 GLTFLoader 并删除 OBJLoader.

    -
    -import {LoaderSupport} from '/examples/jsm/loaders/LoaderSupport.js';
    --import {OBJLoader} from '/examples/jsm/loaders/OBJLoader.js';
    --import {MTLLoader} from '/examples/jsm/loaders/MTLLoader.js';
    -+import {GLTFLoader} from '/examples/jsm/loaders/GLTFLoader.js';
    +				
    -import {LoaderSupport} from 'three/addons/loaders/LoaderSupport.js';
    +-import {OBJLoader} from 'three/addons/loaders/OBJLoader.js';
    +-import {MTLLoader} from 'three/addons/loaders/MTLLoader.js';
    ++import {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';
     

    像这样运行

    @@ -262,7 +262,7 @@

    加载 .gltf 文件

    - cars = root.getObjectByName('Cars'); + const loadedCars = root.getObjectByName('Cars'); + const fixes = [ -+ { prefix: 'Car_08', rot: [Math.PI * .5, 0, Math.PI +* .5], }, ++ { prefix: 'Car_08', rot: [Math.PI * .5, 0, Math.PI * .5], }, + { prefix: 'CAR_03', rot: [0, Math.PI, 0], }, + { prefix: 'Car_04', rot: [0, Math.PI, 0], }, + ]; diff --git a/manual/zh/load-obj.html b/manual/zh/load-obj.html index ce65af20f3bee5..46fdbab7d59c9d 100644 --- a/manual/zh/load-obj.html +++ b/manual/zh/load-obj.html @@ -49,7 +49,7 @@

    加载 .OBJ 文件

    让我们一起来尝试将它展示出来。

    基于光线文章中的定向光线(DirectionalLight)示例,结合半球光线(HemisphereLight)示例。相对于示例,我删除了所有与调整灯光相关的GUI内容,还删除了添加到场景中的立方体和球体。

    第一件要做的事就是将OBJLoader添加到代码中。

    -
    import {OBJLoader} from '/examples/jsm/loaders/OBJLoader.js';
    +
    import {OBJLoader} from 'three/addons/loaders/OBJLoader.js';
     

    然后创建OBJLoader的实例并通过URL加载我们的.OBJ文件,并在回调函数中将已加载完的模型添加到场景(scene)里。

    {
    @@ -115,10 +115,10 @@ 

    加载 .OBJ 文件

    现在.MTL文件就能加载到这些纹理。

    首先要引用 MTLLoader;

    -
    import * as THREE from '/build/three.module.js';
    -import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
    -import {OBJLoader} from '/examples/jsm/loaders/OBJLoader.js';
    -+import {MTLLoader} from '/examples/jsm/loaders/MTLLoader.js';
    +
    import * as THREE from 'three';
    +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
    +import {OBJLoader} from 'three/addons/loaders/OBJLoader.js';
    ++import {MTLLoader} from 'three/addons/loaders/MTLLoader.js';
     

    然后我们先加载.MTL文件,在它加载完材质后利用MtlObjBridge将材质传给OBJLoader,再加载.OBJ文件。

    diff --git a/manual/zh/multiple-scenes.html b/manual/zh/multiple-scenes.html index 90b510ee010886..888fa0c1fd3bd7 100644 --- a/manual/zh/multiple-scenes.html +++ b/manual/zh/multiple-scenes.html @@ -397,7 +397,7 @@

    使用HTML Dataset

    给每个元素增加控制器

    当需要交互时,我们需要为每个场景分别添加交互控件,如TrackballControls。首先,需要引入该控件。

    -
    import {TrackballControls} from './resources/threejs/r132/examples/jsm/controls/TrackballControls.js';
    +
    import {TrackballControls} from 'three/addons/controls/TrackballControls.js';
     

    接着给每个元素增加控制器:

    -function makeScene() {
    @@ -614,4 +614,4 @@ 

    更新的方法

    - \ No newline at end of file + diff --git a/manual/zh/offscreencanvas.html b/manual/zh/offscreencanvas.html index 03e3feea642311..927a40ee2b7bbb 100644 --- a/manual/zh/offscreencanvas.html +++ b/manual/zh/offscreencanvas.html @@ -1,47 +1,924 @@ - - - OffscreenCanvas - - - - - - - - - - - - - - - + + - - - -
    -
    -

    OffscreenCanvas

    -
    -
    -
    -

    抱歉,还没有中文翻译哦。 欢迎加入翻译! 😄

    -

    英文原文链接.

    + + + + +
    +
    +

    离屏渲染

    +
    +
    +
    +

    OffscreenCanvas + 是一个相对较新的浏览器功能,目前仅在Chrome可用,但显然未来会适用到别的浏览器上。 OffscreenCanvas + 允许使用Web Worker去渲染画布,这是一种减轻繁重复杂工作的方法,比如把渲染一个复杂的3D场景交给一个Web + Worker,避免减慢浏览器的响应速度。它也意味着数据在Worker中加载和解析,因此可能会减少页面加载时的卡顿。

    +

    开始 使用它非常的简单。我们从移植 关于响应式的文章中 3个旋转的立方体开始。

    +

    Worker通常会把代码分割到另一个脚本文件中,本网页的大多数示例都有单独的脚本嵌入到他们所在的HTML文件中。

    +

    在我们的例子中,我们会创建一个叫 offscreencanvas-cubes.js 的文件, + 并且复制 响应式例子 中所有的JavaScript到里面。我们会进行一些必要的修改以使其在Worker中运行。

    +

    我们的HTML文件中仍然需要一些JavaScript,第一件事就是我们需要查找画布,然后转移对它的控制。通过调用 canvas.transferControlToOffscreen来使画布脱离屏幕。

    +
    function main() {
    +  const canvas = document.querySelector('#c');
    +  const offscreen = canvas.transferControlToOffscreen();
    +
    +  ...
    +

    然后我们可以用 new Worker(pathToScript, {type: 'module'})来启用我们的Worker。 + 并把 offscreen 对象传入给它。

    +
    function main() {
    +  const canvas = document.querySelector('#c');
    +  const offscreen = canvas.transferControlToOffscreen();
    +  const worker = new Worker('offscreencanvas-cubes.js', {type: 'module'});
    +  worker.postMessage({type: 'main', canvas: offscreen}, [offscreen]);
    +}
    +main();
    +

    特别需要关注一个重点,Worker不能访问 DOM。 + 它们不能查看HTML元素,也不能接受鼠标或者键盘事件。它们通常唯一能做的事情就是响应发送给他们的消息并将消息发送回主页面。

    + +

    想要发送消息给Worker,需要调用 worker.postMessage 并传入1个或2个参数。第一个参数是一个JavaScript对象,它会被 结构化拷贝 + 并发送给Worker。第二个参数是一个可选的对象数组,它是第一个对象的子集,属于我们想 传递 + 给Worker的一部分,这些对象是不会被克隆的。相反他们会被 转移 + 并且不再存在于主页面中。不复存在可能是一个不准确的描述,它们更像是不可访问。只有某些类型的对象可以转移而不是克隆,包括 OffscreenCanvas。 + 所以一旦转移了 offscreen 对象,在主页面它就没用了。

    + +

    Worker从它们的 onmessage 方法获取消息。我们调用 postMessage 传递的对象,在 onmessage 方法中,通过 + event.data 可以获取到。 + 上面的代码在传递给Worker的对象中声明了 type: 'main' + 。这个对象对浏览器完全没有意义,完全是我们自定义的用法。我们会写一个处理函数,基于 type + 参数来调用Worker中的不同方法。然后我们可以按需添加处理函数,并很容易的从主页面中调用它们。 +

    + +
    const handlers = {
    +  main,
    +};
    +
    +self.onmessage = function(e) {
    +  const fn = handlers[e.data.type];
    +  if (typeof fn !== 'function') {
    +    throw new Error('no handler for type: ' + e.data.type);
    +  }
    +  fn(e.data);
    +};
    +

    在上面你可以看到我们只是根据从主页面传入的 data 中的 type 查找处理函数。

    +

    所以现在我们只需要开始修改我们从 响应式文章中粘贴进 + offscreencanvas-cubes.jsmain 函数即可。 +

    +

    我们不会从 DOM 中获取画布,而是从事件数据中获取到它。

    +
    -function main() {
    +-  const canvas = document.querySelector('#c');
    ++function main(data) {
    ++  const {canvas} = data;
    +  const renderer = new THREE.WebGLRenderer({canvas});
    +
    +  ...
    +

    记住Worker根本看不见 DOM 结构。我们遇到的第一个问题是 resizeRendererToDisplaySize + 不能获取到 canvas.clientWidth + 和 canvas.clientHeight ,因为它们是DOM属性。这是原始代码

    + +
    function resizeRendererToDisplaySize(renderer) {
    +  const canvas = renderer.domElement;
    +  const width = canvas.clientWidth;
    +  const height = canvas.clientHeight;
    +  const needResize = canvas.width !== width || canvas.height !== height;
    +  if (needResize) {
    +    renderer.setSize(width, height, false);
    +  }
    +  return needResize;
    +}
    +

    相对的,我们需要把尺寸变化发送给Worker。所以,让我们添加一些保存宽度和高度的全局状态。

    +
    const state = {
    +  width: 300,  // canvas default
    +  height: 150,  // canvas default
    +};
    +

    然后我们添加一个 'size' 处理函数来更新这些值。

    +
    +function size(data) {
    ++  state.width = data.width;
    ++  state.height = data.height;
    ++}
    +
    +const handlers = {
    +  main,
    ++  size,
    +};
    +

    现在我们可以修改 resizeRendererToDisplaySize 函数以使用state.widthstate.height

    +
    function resizeRendererToDisplaySize(renderer) {
    +  const canvas = renderer.domElement;
    +-  const width = canvas.clientWidth;
    +-  const height = canvas.clientHeight;
    ++  const width = state.width;
    ++  const height = state.height;
    +  const needResize = canvas.width !== width || canvas.height !== height;
    +  if (needResize) {
    +    renderer.setSize(width, height, false);
    +  }
    +  return needResize;
    +}
    +

    其他我们需要用到长宽的地方也需要做类似的修改。

    +
    function render(time) {
    +  time *= 0.001;
    +
    +  if (resizeRendererToDisplaySize(renderer)) {
    +-    camera.aspect = canvas.clientWidth / canvas.clientHeight;
    ++    camera.aspect = state.width / state.height;
    +    camera.updateProjectionMatrix();
    +  }
    +
    +  ...
    +

    回到主页面,在任何页面尺寸发生变化的时候,我们都需要发送一个size 事件。

    +
    const worker = new Worker('offscreencanvas-picking.js', {type: 'module'});
    +worker.postMessage({type: 'main', canvas: offscreen}, [offscreen]);
    +
    ++function sendSize() {
    ++  worker.postMessage({
    ++    type: 'size',
    ++    width: canvas.clientWidth,
    ++    height: canvas.clientHeight,
    ++  });
    ++}
    ++
    ++window.addEventListener('resize', sendSize);
    ++sendSize();
    +

    我们也需要调用它一次来初始化大小。

    +

    通过这些细小改动,假设你的浏览器完全支持 OffscreenCanvas + ,它应该是有效的。在我们运行它之前,让我们检查一下浏览器是否真的支持 + OffscreenCanvas 并且不显示错误。首先添加一些HTML片段来展示错误。 +

    +
    <body>
    +  <canvas id="c"></canvas>
    ++  <div id="noOffscreenCanvas" style="display:none;">
    ++    <div>no OffscreenCanvas support</div>
    ++  </div>
    +</body>
    +

    和一些CSS代码

    +
    #noOffscreenCanvas {
    +    display: flex;
    +    width: 100%;
    +    height: 100%;
    +    align-items: center;
    +    justify-content: center;
    +    background: red;
    +    color: white;
    +}
    +

    然后我们可以通过检查transferControlToOffscreen是否存在 + 来判断浏览器对 OffscreenCanvas的兼容性。

    +
    function main() {
    +  const canvas = document.querySelector('#c');
    ++  if (!canvas.transferControlToOffscreen) {
    ++    canvas.style.display = 'none';
    ++    document.querySelector('#noOffscreenCanvas').style.display = '';
    ++    return;
    ++  }
    +  const offscreen = canvas.transferControlToOffscreen();
    +  const worker = new Worker('offscreencanvas-picking.js', {type: 'module});
    +  worker.postMessage({type: 'main', canvas: offscreen}, [offscreen]);
    +
    +  ...
    +

    如上,如果你的浏览器支持 OffscreenCanvas ,这个例子应该会生效。

    +

    + + +

    +

    这很棒,不过现在不是每个浏览器都支持 OffscreenCanvas。 + 让我们更改代码以同时适用 OffscreenCanvas 以及在主页面和通常用法一样的降级方案。

    + +
    +

    + 顺便说一句,如果你需要OffscreenCanvas来使页面具有尺寸自适应调整,降级的意义不大。也许基于你最终是在主页面还是Worker中运行,你可能会调整Worker的数量,以便让Worker运行时做的事情比在主页面可做的事情更多。这些都取决于你。 +

    +
    + +

    我们应该做的第一件事就是分离出THREE.js中特定于Worker相关的代码。这样我们就可以在主页面和Worker中使用相同的代码,换句话说,我们将会有3个文件

    + +
      +
    1. +

      我们的HTML文件

      +

      threejs-offscreencanvas-w-fallback.html

      +
    2. +
    3. +

      一个包含THREE.js的JavaScript代码文件

      +

      shared-cubes.js

      +
    4. +
    5. +

      我们支持Worker的代码文件

      +

      offscreencanvas-worker-cubes.js

      +
    6. +
    +

    shared-cubes.jsoffscreencanvas-worker-cubes.js 基本上都是从我们之前的 offscreencanvas-cubes.js 文件分割而来。 + 第一步我们拷贝所有的 offscreencanvas-cubes.js 代码到 shared-cube.js中。然后 + 我们重命名 maininit 因为我们已经有一个 main + 函数在我们的HTML文件中了,我们还需要导出 init 函数和 state对象。

    +
    import * as THREE from '../../build/three.module.js';
    +
    +-const state = {
    ++export const state = {
    +  width: 300,   // canvas default
    +  height: 150,  // canvas default
    +};
    +
    +-function main(data) {
    ++export function init(data) {
    +  const {canvas} = data;
    +  const renderer = new THREE.WebGLRenderer({canvas});
    +

    并去掉和THREE.js无关的部分

    +
    -function size(data) {
    +-  state.width = data.width;
    +-  state.height = data.height;
    +-}
    +-
    +-const handlers = {
    +-  main,
    +-  size,
    +-};
    +-
    +-self.onmessage = function(e) {
    +-  const fn = handlers[e.data.type];
    +-  if (typeof fn !== 'function') {
    +-    throw new Error('no handler for type: ' + e.data.type);
    +-  }
    +-  fn(e.data);
    +-};
    +

    然后我们需要把刚刚删除的部分拷贝到 offscreencanvas-worker-cubes.js + ,并导入 shared-cubes.js 以及调用 init 而不是 main方法。

    +
    import {init, state} from './shared-cubes.js';
    +
    +function size(data) {
    +  state.width = data.width;
    +  state.height = data.height;
    +}
     
    +const handlers = {
    +-  main,
    ++  init,
    +  size,
    +};
    +
    +self.onmessage = function(e) {
    +  const fn = handlers[e.data.type];
    +  if (typeof fn !== 'function') {
    +    throw new Error('no handler for type: ' + e.data.type);
    +  }
    +  fn(e.data);
    +};
    +

    类似的我们需要在主页面引入 shared-cubes.js 模块 +

    +
    <script type="module">
    ++import {init, state} from './shared-cubes.js';
    +

    我们也可以移除之前添加的HTML

    +
    <body>
    +  <canvas id="c"></canvas>
    +-  <div id="noOffscreenCanvas" style="display:none;">
    +-    <div>no OffscreenCanvas support</div>
    +-  </div>
    +</body>
    +

    以及CSS

    +
    -#noOffscreenCanvas {
    +-    display: flex;
    +-    width: 100%;
    +-    height: 100%;
    +-    align-items: center;
    +-    justify-content: center;
    +-    background: red;
    +-    color: white;
    +-}
    +

    然后我们把主页面的代码改成调用一次启动函数,启动函数取决于浏览器是否支持 OffscreenCanvas

    +
    function main() {
    +  const canvas = document.querySelector('#c');
    +-  if (!canvas.transferControlToOffscreen) {
    +-    canvas.style.display = 'none';
    +-    document.querySelector('#noOffscreenCanvas').style.display = '';
    +-    return;
    +-  }
    +-  const offscreen = canvas.transferControlToOffscreen();
    +-  const worker = new Worker('offscreencanvas-picking.js', {type: 'module'});
    +-  worker.postMessage({type: 'main', canvas: offscreen}, [offscreen]);
    ++  if (canvas.transferControlToOffscreen) {
    ++    startWorker(canvas);
    ++  } else {
    ++    startMainPage(canvas);
    ++  }
    +  ...
    +

    我们需要把启动Worker的代码移动到 startWorker函数中

    +
    function startWorker(canvas) {
    +  const offscreen = canvas.transferControlToOffscreen();
    +  const worker = new Worker('offscreencanvas-worker-cubes.js', {type: 'module'});
    +  worker.postMessage({type: 'main', canvas: offscreen}, [offscreen]);
    +
    +  function sendSize() {
    +    worker.postMessage({
    +      type: 'size',
    +      width: canvas.clientWidth,
    +      height: canvas.clientHeight,
    +    });
    +  }
    +
    +  window.addEventListener('resize', sendSize);
    +  sendSize();
    +
    +  console.log('using OffscreenCanvas');
    +}
    +

    然后发送消息类型为 init 而不是 main

    +
    -  worker.postMessage({type: 'main', canvas: offscreen}, [offscreen]);
    ++  worker.postMessage({type: 'init', canvas: offscreen}, [offscreen]);
    +

    若是从主页面启动,我们可以这样做

    +
    function startMainPage(canvas) {
    +  init({canvas});
    +
    +  function sendSize() {
    +    state.width = canvas.clientWidth;
    +    state.height = canvas.clientHeight;
    +  }
    +  window.addEventListener('resize', sendSize);
    +  sendSize();
    +
    +  console.log('using regular canvas');
    +}
    +

    这样,我们的示例在离屏画布或者主页面都可以运行了。

    +

    + +

    这应该是比较容易的。我们尝试下拾取,我们会从 关于拾取的文章 中的 射线 案例获取一些代码, + 让它在离屏时也可运行。

    +

    我们现在拷贝 shared-cube.jsshared-picking.js ,然后添加拾取部分。拷贝到 PickHelper 函数中

    +
    class PickHelper {
    +  constructor() {
    +    this.raycaster = new THREE.Raycaster();
    +    this.pickedObject = null;
    +    this.pickedObjectSavedColor = 0;
    +  }
    +  pick(normalizedPosition, scene, camera, time) {
    +    // restore the color if there is a picked object
    +    if (this.pickedObject) {
    +      this.pickedObject.material.emissive.setHex(this.pickedObjectSavedColor);
    +      this.pickedObject = undefined;
    +    }
    +
    +    // cast a ray through the frustum
    +    this.raycaster.setFromCamera(normalizedPosition, camera);
    +    // get the list of objects the ray intersected
    +    const intersectedObjects = this.raycaster.intersectObjects(scene.children);
    +    if (intersectedObjects.length) {
    +      // pick the first object. It's the closest one
    +      this.pickedObject = intersectedObjects[0].object;
    +      // save its color
    +      this.pickedObjectSavedColor = this.pickedObject.material.emissive.getHex();
    +      // set its emissive color to flashing red/yellow
    +      this.pickedObject.material.emissive.setHex((time * 8) % 2 > 1 ? 0xFFFF00 : 0xFF0000);
    +    }
    +  }
    +}
    +
    +const pickPosition = {x: 0, y: 0};
    +const pickHelper = new PickHelper();
    +

    我们从鼠标位置中更新 pickPosition,就像这样

    +
    function getCanvasRelativePosition(event) {
    +  const rect = canvas.getBoundingClientRect();
    +  return {
    +    x: (event.clientX - rect.left) * canvas.width  / rect.width,
    +    y: (event.clientY - rect.top ) * canvas.height / rect.height,
    +  };
    +}
    +
    +function setPickPosition(event) {
    +  const pos = getCanvasRelativePosition(event);
    +  pickPosition.x = (pos.x / canvas.width ) *  2 - 1;
    +  pickPosition.y = (pos.y / canvas.height) * -2 + 1;  // note we flip Y
    +}
    +window.addEventListener('mousemove', setPickPosition);
    +        
    +

    Worker不能直接读取鼠标位置,所以就像调整尺寸的代码那样,发送带有鼠标位置的消息。像刚才的代码一样我们发送鼠标位置消息并且更新 pickPosition

    + +
    function size(data) {
    +  state.width = data.width;
    +  state.height = data.height;
    +}
    +
    ++function mouse(data) {
    ++  pickPosition.x = data.x;
    ++  pickPosition.y = data.y;
    ++}
    +
    +const handlers = {
    +  init,
    ++  mouse,
    +  size,
    +};
    +
    +self.onmessage = function(e) {
    +  const fn = handlers[e.data.type];
    +  if (typeof fn !== 'function') {
    +    throw new Error('no handler for type: ' + e.data.type);
    +  }
    +  fn(e.data);
    +};
    +

    回到我们的主页面,我需要添加代码去把鼠标位置传给Worker或者主页面。

    +
    +let sendMouse;
    +
    +function startWorker(canvas) {
    +  const offscreen = canvas.transferControlToOffscreen();
    +  const worker = new Worker('offscreencanvas-worker-picking.js', {type: 'module'});
    +  worker.postMessage({type: 'init', canvas: offscreen}, [offscreen]);
    +
    ++  sendMouse = (x, y) => {
    ++    worker.postMessage({
    ++      type: 'mouse',
    ++      x,
    ++      y,
    ++    });
    ++  };
    +
    +  function sendSize() {
    +    worker.postMessage({
    +      type: 'size',
    +      width: canvas.clientWidth,
    +      height: canvas.clientHeight,
    +    });
    +  }
    +
    +  window.addEventListener('resize', sendSize);
    +  sendSize();
    +
    +  console.log('using OffscreenCanvas');  /* eslint-disable-line no-console */
    +}
    +
    +function startMainPage(canvas) {
    +  init({canvas});
    +
    ++  sendMouse = (x, y) => {
    ++    pickPosition.x = x;
    ++    pickPosition.y = y;
    ++  };
    +
    +  function sendSize() {
    +    state.width = canvas.clientWidth;
    +    state.height = canvas.clientHeight;
    +  }
    +  window.addEventListener('resize', sendSize);
    +  sendSize();
    +
    +  console.log('using regular canvas');  /* eslint-disable-line no-console */
    +}
    +

    然后我们可以将所有鼠标处理代码复制到主页面,只需稍作更改即可调用sendMouse

    +
    function setPickPosition(event) {
    +  const pos = getCanvasRelativePosition(event);
    +-  pickPosition.x = (pos.x / canvas.clientWidth ) *  2 - 1;
    +-  pickPosition.y = (pos.y / canvas.clientHeight) * -2 + 1;  // note we flip Y
    ++  sendMouse(
    ++      (pos.x / canvas.clientWidth ) *  2 - 1,
    ++      (pos.y / canvas.clientHeight) * -2 + 1);  // note we flip Y
    +}
    +
    +function clearPickPosition() {
    +  // unlike the mouse which always has a position
    +  // if the user stops touching the screen we want
    +  // to stop picking. For now we just pick a value
    +  // unlikely to pick something
    +-  pickPosition.x = -100000;
    +-  pickPosition.y = -100000;
    ++  sendMouse(-100000, -100000);
    +}
    +window.addEventListener('mousemove', setPickPosition);
    +window.addEventListener('mouseout', clearPickPosition);
    +window.addEventListener('mouseleave', clearPickPosition);
    +
    +window.addEventListener('touchstart', (event) => {
    +  // prevent the window from scrolling
    +  event.preventDefault();
    +  setPickPosition(event.touches[0]);
    +}, {passive: false});
    +
    +window.addEventListener('touchmove', (event) => {
    +  setPickPosition(event.touches[0]);
    +});
    +
    +window.addEventListener('touchend', clearPickPosition);
    +

    通过这种方式, OffscreenCanvas 的拾取应该也是有效的。 +

    +

    + + +

    +

    我们更进一步,添加进 OrbitControls。 + 这会有一些复杂。 OrbitControls利用了很多DOM特性,比如鼠标、触摸、键盘等等。

    +

    与我们现在的代码不同,我们不能真正使用全局 state 对象,不重写所有的OrbitControls代码是无法做到的。 + OrbitControls附加绑定了一个 HTMLElement + 的DOM事件。也许我们可以通过自行实现与DOM元素相同API签名的对象,我们只需要支持OrbitControls需要的功能即可。

    +

    挖掘了一下 OrbitControls + 源代码 + ,看起来我们需要处理以下事件:

    +
      +
    • contextmenu
    • +
    • pointerdown
    • +
    • pointermove
    • +
    • pointerup
    • +
    • touchstart
    • +
    • touchmove
    • +
    • touchend
    • +
    • wheel
    • +
    • keydown
    • +
    +

    对于点击事件,我们需要 ctrlKeymetaKeyshiftKey, + buttonpointerTypeclientXclientYpageX, + 和 pageY 这些属性。 +

    +

    对于键盘事件,我们需要 ctrlKeymetaKeyshiftKey, + 和 keyCode 这些属性。

    + +

    对于滚轮事件,我们只需要 deltaY 属性。

    +

    最后对于点击事件,我们只需要 pageXpageY ,来自 + touches 属性。 +

    +

    + 所以,让我们做一个代理的键值对,一部分会运行在主页面,获取所有这些事件,然后传递相关属性值给Worker。另一部分将在Worker中运行,接收事件并使用和原始DOM事件相同的事件参数。因此OrbitControls无法分辨其中的不同。 +

    +

    这里是Worker部分的代码。

    +
    import {EventDispatcher} from '../../build/three.module.js';
    +
    +class ElementProxyReceiver extends EventDispatcher {
    +  constructor() {
    +    super();
    +  }
    +  handleEvent(data) {
    +    this.dispatchEvent(data);
    +  }
    +}
    +

    它所做的就是接收到一条消息,就把它分发出去。它继承自EventDispatcher,这提供了一些方法,像addEventListenerremoveEventListener,就像一个DOM元素一样,我们把它传给OrbitControls的话,应该能行。 +

    ElementProxyReceiver + 接受一个元素,在我们的例子中,只需要一个。不过最好还是好好思考下,让Manager来管理多个。

    + +
    class ProxyManager {
    +  constructor() {
    +    this.targets = {};
    +    this.handleEvent = this.handleEvent.bind(this);
    +  }
    +  makeProxy(data) {
    +    const {id} = data;
    +    const proxy = new ElementProxyReceiver();
    +    this.targets[id] = proxy;
    +  }
    +  getProxy(id) {
    +    return this.targets[id];
    +  }
    +  handleEvent(data) {
    +    this.targets[data.id].handleEvent(data.data);
    +  }
    +}
    +

    我们可以创建一个 ProxyManager 实例,然后调用它的 makeProxy + 方法,通过一个id,可以生成一个响应对应id信息的 ElementProxyReceiver 对象。

    +

    让我们将它关联到Worker的消息处理函数上

    +
    const proxyManager = new ProxyManager();
    +
    +function start(data) {
    +  const proxy = proxyManager.getProxy(data.canvasId);
    +  init({
    +    canvas: data.canvas,
    +    inputElement: proxy,
    +  });
    +}
    +
    +function makeProxy(data) {
    +  proxyManager.makeProxy(data);
    +}
    +
    +...
    +
    +const handlers = {
    +-  init,
    +-  mouse,
    ++  start,
    ++  makeProxy,
    ++  event: proxyManager.handleEvent,
    +    size,
    +};
    +
    +self.onmessage = function(e) {
    +  const fn = handlers[e.data.type];
    +  if (typeof fn !== 'function') {
    +    throw new Error('no handler for type: ' + e.data.type);
    +  }
    +  fn(e.data);
    +};
    +

    在共享的THREE.js代码中,我们需要导入 OrbitControls 并且设置它。

    + +
    import * as THREE from '../../build/three.module.js';
    ++import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
    +
    +export function init(data) {
    +-  const {canvas} = data;
    ++  const {canvas, inputElement} = data;
    +  const renderer = new THREE.WebGLRenderer({canvas});
    +
    ++  const controls = new OrbitControls(camera, inputElement);
    ++  controls.target.set(0, 0, 0);
    ++  controls.update();
    +

    注意,我们通过传入代理的 inputElement 给了OrbitControls,而不是 + 像我们在其他非离屏渲染的例子中那样。

    +

    接下来我们可以从HTML文件中移动所有的拾取事件代码,把 canvas 修改为 inputElement。 +

    +
    function getCanvasRelativePosition(event) {
    +-  const rect = canvas.getBoundingClientRect();
    ++  const rect = inputElement.getBoundingClientRect();
    +  return {
    +    x: event.clientX - rect.left,
    +    y: event.clientY - rect.top,
    +  };
    +}
    +
    +function setPickPosition(event) {
    +  const pos = getCanvasRelativePosition(event);
    +-  sendMouse(
    +-      (pos.x / canvas.clientWidth ) *  2 - 1,
    +-      (pos.y / canvas.clientHeight) * -2 + 1);  // note we flip Y
    ++  pickPosition.x = (pos.x / inputElement.clientWidth ) *  2 - 1;
    ++  pickPosition.y = (pos.y / inputElement.clientHeight) * -2 + 1;  // note we flip Y
    +}
    +
    +function clearPickPosition() {
    +  // unlike the mouse which always has a position
    +  // if the user stops touching the screen we want
    +  // to stop picking. For now we just pick a value
    +  // unlikely to pick something
    +-  sendMouse(-100000, -100000);
    ++  pickPosition.x = -100000;
    ++  pickPosition.y = -100000;
    +}
    +
    +*inputElement.addEventListener('mousemove', setPickPosition);
    +*inputElement.addEventListener('mouseout', clearPickPosition);
    +*inputElement.addEventListener('mouseleave', clearPickPosition);
    +
    +*inputElement.addEventListener('touchstart', (event) => {
    +  // prevent the window from scrolling
    +  event.preventDefault();
    +  setPickPosition(event.touches[0]);
    +}, {passive: false});
    +
    +*inputElement.addEventListener('touchmove', (event) => {
    +  setPickPosition(event.touches[0]);
    +});
    +
    +*inputElement.addEventListener('touchend', clearPickPosition);
    +

    回到主页面,我们需要写一些代码来发送包含上面列举所有事件的消息。

    +
    let nextProxyId = 0;
    +class ElementProxy {
    +  constructor(element, worker, eventHandlers) {
    +    this.id = nextProxyId++;
    +    this.worker = worker;
    +    const sendEvent = (data) => {
    +      this.worker.postMessage({
    +        type: 'event',
    +        id: this.id,
    +        data,
    +      });
    +    };
    +
    +    // register an id
    +    worker.postMessage({
    +      type: 'makeProxy',
    +      id: this.id,
    +    });
    +    for (const [eventName, handler] of Object.entries(eventHandlers)) {
    +      element.addEventListener(eventName, function(event) {
    +        handler(event, sendEvent);
    +      });
    +    }
    +  }
    +}
    +

    ElementProxy 代理了事件需要被代理的元素, + 它向Worker注册了一个ID,通过选取和发送 + 我们早先注册的 makeProxy消息,Worker会生成一个 ElementProxyReceiver 并使用这个ID注册。

    + +

    然后我们又一个注册事件处理的对,这样我们可以对特定事件应用处理函数,并转发给Worker。

    +

    当我们启动Worker时,我们先创建一个代理,并传给我们的事件处理函数

    +
    function startWorker(canvas) {
    +  const offscreen = canvas.transferControlToOffscreen();
    +  const worker = new Worker('offscreencanvas-worker-orbitcontrols.js', {type: 'module'});
    +
    ++  const eventHandlers = {
    ++    contextmenu: preventDefaultHandler,
    ++    mousedown: mouseEventHandler,
    ++    mousemove: mouseEventHandler,
    ++    mouseup: mouseEventHandler,
    ++    pointerdown: mouseEventHandler,
    ++    pointermove: mouseEventHandler,
    ++    pointerup: mouseEventHandler,
    ++    touchstart: touchEventHandler,
    ++    touchmove: touchEventHandler,
    ++    touchend: touchEventHandler,
    ++    wheel: wheelEventHandler,
    ++    keydown: filteredKeydownEventHandler,
    ++  };
    ++  const proxy = new ElementProxy(canvas, worker, eventHandlers);
    +  worker.postMessage({
    +    type: 'start',
    +    canvas: offscreen,
    ++    canvasId: proxy.id,
    +  }, [offscreen]);
    +  console.log('using OffscreenCanvas');  /* eslint-disable-line no-console */
    +}
    +

    下面是事件处理函数。他们所做的只是从接收到的时间中复制属性列表。它们应用了一个 sendEvent函数 + ,这个函数会包含事件的数据,添加正确的ID,以及发送给Worker。

    + +
    class ElementProxy {
    +  constructor(element, worker, eventHandlers) {
    +    this.id = nextProxyId++;
    +    this.worker = worker;
    +    const sendEvent = (data) => {
    +      this.worker.postMessage({
    +        type: 'event',
    +        id: this.id,
    +        data,
    +      });
    +    };
    +
    +    // register an id
    +    worker.postMessage({
    +      type: 'makeProxy',
    +      id: this.id,
    +    });
    ++    sendSize();
    +    for (const [eventName, handler] of Object.entries(eventHandlers)) {
    +      element.addEventListener(eventName, function(event) {
    +        handler(event, sendEvent);
    +      });
    +    }
    +
    ++    function sendSize() {
    ++      const rect = element.getBoundingClientRect();
    ++      sendEvent({
    ++        type: 'size',
    ++        left: rect.left,
    ++        top: rect.top,
    ++        width: element.clientWidth,
    ++        height: element.clientHeight,
    ++      });
    ++    }
    ++
    ++    window.addEventListener('resize', sendSize);
    +  }
    +}
    +

    在我们共享的THREE.js代码中,我们不再需要 state

    +
    -export const state = {
    +-  width: 300,   // canvas default
    +-  height: 150,  // canvas default
    +-};
    +
    +...
    +
    +function resizeRendererToDisplaySize(renderer) {
    +  const canvas = renderer.domElement;
    +-  const width = state.width;
    +-  const height = state.height;
    ++  const width = inputElement.clientWidth;
    ++  const height = inputElement.clientHeight;
    +  const needResize = canvas.width !== width || canvas.height !== height;
    +  if (needResize) {
    +    renderer.setSize(width, height, false);
    +  }
    +  return needResize;
    +}
    +
    +function render(time) {
    +  time *= 0.001;
    +
    +  if (resizeRendererToDisplaySize(renderer)) {
    +-    camera.aspect = state.width / state.height;
    ++    camera.aspect = inputElement.clientWidth / inputElement.clientHeight;
    +    camera.updateProjectionMatrix();
    +  }
    +
    +  ...
    +

    还有一些黑科技。OrbitControls 监听了 pointermovepointerup 事件到元素的 + ownerDocument 属性上,这样可以处理鼠标捕获(当鼠标离开窗口时) +

    +

    此外,代码引用了全局document 不过在Worker中没有全局document对象。

    + +

    我们可以通过2个小hack来快速解决这些问题。在我们Worker的代码中,我们会使用Proxy来解决这两个问题。

    +
    function start(data) {
    +  const proxy = proxyManager.getProxy(data.canvasId);
    ++  proxy.ownerDocument = proxy; // HACK!
    ++  self.document = {} // HACK!
    +  init({
    +    canvas: data.canvas,
    +    inputElement: proxy,
    +  });
    +}
    +

    这会给 OrbitControls 检查到一些符合它期望的东西。

    + +

    我知道这会有点难以理解。简单来说就是: + ElementProxy 在主页面运行,并转发 DOM 事件给Worker中的 + ElementProxyReceiver, + 它会伪装成一个 HTMLElement ,这样我们可以同时使用 + OrbitControls 和我们自己的代码。 +

    +

    最后一件事是我们在不使用离屏渲染时的降级。我们所要做的就是将画布本身作为 inputElement 即可。

    + +
    function startMainPage(canvas) {
    +-  init({canvas});
    ++  init({canvas, inputElement: canvas});
    +  console.log('using regular canvas');
    +}
    +

    现在我们应该可以让OrbitControls在离屏渲染时正常工作了。

    +

    + + +

    +

    这可能是站点上目前为止最复杂的示例,可能会有点难以理解,因为每个案例都有3个文件:HTML文件、Worker文件、共享的THREE.js代码。

    +

    我希望它不会太难理解。希望它可以提供一些使用THREE.js、OffscreenCanvas和Web Worker有用的示例。

    - +
    + - \ No newline at end of file + + + \ No newline at end of file diff --git a/manual/zh/optimize-lots-of-objects-animated.html b/manual/zh/optimize-lots-of-objects-animated.html index 5e095537eccee1..750cde5f650005 100644 --- a/manual/zh/optimize-lots-of-objects-animated.html +++ b/manual/zh/optimize-lots-of-objects-animated.html @@ -294,10 +294,10 @@

    优化对象的同时保持动画效果

    以上我们为每一组数据集创建了几何体, 以第一个作为基准, 获取了position属性, 将其他的几何体作为其变形目标

    现在我们需要改变显示和隐藏各种数据集的方式. 我们需要改动变形目标的influence, 而不是简单地显示和隐藏mesh. 对于我们我们想看到的数据集, influence应该是1, 不想看到的是0. 但是我们又不能直接将他们设置成1和0, 这将会显示开与闭的两种情况, 和现在这种没有区别. 我们也可以写一段自定义的动画效果, 听起来不难. 但是我们模仿的WebGL globe用了一个动画库, 我们也用这一个.

    我们这里首先引入它

    -
    import * as THREE from '/build/three.module.js';
    -import {BufferGeometryUtils} from '/examples/jsm/utils/BufferGeometryUtils.js';
    -import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
    -+import {TWEEN} from '/examples/jsm/libs/tween.min.js';
    +
    import * as THREE from 'three';
    +import {BufferGeometryUtils} from 'three/addons/utils/BufferGeometryUtils.js';
    +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
    ++import {TWEEN} from 'three/addons/libs/tween.min.js';
     

    然后创建一个Tween来使influence变化

    // show the selected data, hide the rest
    diff --git a/manual/zh/optimize-lots-of-objects.html b/manual/zh/optimize-lots-of-objects.html
    index fbd3633f50e948..1f4a6650db68d7 100644
    --- a/manual/zh/optimize-lots-of-objects.html
    +++ b/manual/zh/optimize-lots-of-objects.html
    @@ -346,7 +346,7 @@ 

    大量对象的优化

    我们移除了之前用来改变盒子几何中心的代码, 取而代之的是originHelper. 这次我们要为每个长方体创建新的几何体, 因为我们要使用“applyMatrix”来移动每个长方体几何体的顶点, 所以我们最好只移动一次, 而不是两次.

    最后, 我们将所有几何体的数组传入BufferGeometryUtils.mergeBufferGeometries, 这个方法将会将其合并到一个mesh中

    别忘了引入BufferGeometryUtils

    -
    import * as BufferGeometryUtils from '/examples/jsm/utils/BufferGeometryUtils.js';
    +
    import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js';
     

    现在, 至少在我的机器上, 可以跑到60帧每秒了

    diff --git a/manual/zh/post-processing.html b/manual/zh/post-processing.html index 968338701cce64..6e3037e697559a 100644 --- a/manual/zh/post-processing.html +++ b/manual/zh/post-processing.html @@ -77,10 +77,10 @@

    renderToScreen

    由于filmPass是最后一次传递,我们将其renderToScreen属性设置为true来告诉它渲染到画布。如果不设置它,它将渲染到下一个渲染目标。

    为了使用这些类,我们需要导入一些js模块

    -
    import {EffectComposer} from '/examples/jsm/postprocessing/EffectComposer.js';
    -import {RenderPass} from '/examples/jsm/postprocessing/RenderPass.js';
    -import {BloomPass} from '/examples/jsm/postprocessing/BloomPass.js';
    -import {FilmPass} from '/examples/jsm/postprocessing/FilmPass.js';
    +
    import {EffectComposer} from 'three/addons/postprocessing/EffectComposer.js';
    +import {RenderPass} from 'three/addons/postprocessing/RenderPass.js';
    +import {BloomPass} from 'three/addons/postprocessing/BloomPass.js';
    +import {FilmPass} from 'three/addons/postprocessing/FilmPass.js';
     

    对于几乎所有的后期处理EffectComposer.js,RenderPass.js 都是必需的。

    们需要做的最后一件事是使用EffectComposer.render 替代 WebGLRenderer.render 并告诉EffectComposer来匹配画布的大小

    @@ -135,7 +135,7 @@

    renderToScreen

    这样就很清楚如何设置它们。

    让我们快速创建一个GUI来设置这些值

    -
    import {GUI} from '/examples/jsm/libs/lil-gui.module.min.js';
    +
    import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
     

    const gui = new GUI();
    diff --git a/manual/zh/rendering-on-demand.html b/manual/zh/rendering-on-demand.html
    index 7442d801337499..45853d7c15789d 100644
    --- a/manual/zh/rendering-on-demand.html
    +++ b/manual/zh/rendering-on-demand.html
    @@ -44,8 +44,8 @@ 

    按需渲染

    首先我们添加OrbitControls, 这样当摄像机改变之后场景就可以随之渲染

    First we'll add in the OrbitControls so there is something that could change that we can render in response to.

    -
    import * as THREE from '/build/three.module.js';
    -+import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
    +
    import * as THREE from 'three';
    ++import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
     

    然后

    const fov = 75;
    @@ -154,9 +154,9 @@ 

    按需渲染

    让我们加一个简单的GUI

    -
    import * as THREE from '/build/three.module.js';
    -import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
    -+import {GUI} from '/examples/jsm/libs/lil-gui.module.min.js';
    +
    import * as THREE from 'three';
    +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
    ++import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
     

    这个控制器可以改变每个立方体的颜色和在x方向缩放. 为了设置颜色我们用了ColorGUIHelper, 这个在光线一章提到过

    const gui = new GUI();
    diff --git a/manual/zh/responsive.html b/manual/zh/responsive.html
    index ce49754272e4c3..dfe39fcdb90b07 100644
    --- a/manual/zh/responsive.html
    +++ b/manual/zh/responsive.html
    @@ -1,49 +1,53 @@
    -
    -    
    -    响应式设计
    -    
    -    
    -    
    -    
    -    
    -    
    -    
    -
    -    
    -    
    -
    -
    -
    -
    -
    +
    +  
    -    
    -  
    -  
    -    
    -
    -

    响应式设计

    -
    -
    -
    -

    这是three.js系列文章的第二篇。 -第一篇是关于基础。 -如果你还没有阅读第一篇那你应该从第一篇开始。

    -

    本篇文章是关于如何让你的three.js应用自适应各种情况。 -网页的响应式是指让其在桌面、平板及手机等不同尺寸的屏幕上显示良好。

    -

    对three.js来说有更多的情况要考虑。例如,我们可能需要处理控件在左侧、右侧、顶部或底部的三维编辑器。本文的中间部分展示了另一个例子。

    -

    上一个例子中我们使用了一个没有设置样式和尺寸的。

    -
    <canvas id="c"></canvas>
    +  
    +
    +
    +
    +  
    +
    +

    响应式设计

    +
    +
    +
    +

    这是three.js系列文章的第二篇。 + 第一篇是关于基础。 + 如果你还没有阅读第一篇那你应该从第一篇开始。

    +

    本篇文章是关于如何让你的three.js应用自适应各种情况。 + 网页的响应式是指让其在桌面、平板及手机等不同尺寸的屏幕上显示良好。

    +

    对three.js来说有更多的情况要考虑。例如,我们可能需要处理控件在左侧、右侧、顶部或底部的三维编辑器。本文的中间部分展示了另一个例子。

    +

    上一个例子中我们使用了一个没有设置样式和尺寸的。

    +
    <canvas id="c"></canvas>
     
    -

    那个canvas默认300x150像素。

    -

    在web平台推荐使用CSS来设置物体的尺寸。

    -

    我们通过添加CSS来让canvas填充整个页面。

    -
    <style>
    +        

    那个canvas默认300x150像素。

    +

    在web平台推荐使用CSS来设置物体的尺寸。

    +

    我们通过添加CSS来让canvas填充整个页面。

    +
    <style>
     html, body {
        margin: 0;
        height: 100%;
    @@ -55,30 +59,36 @@ 

    响应式设计

    } </style>
    -

    HTML中的body默认有5个像素的margin值所以设置margin为0来移除margin值。 -设置html和body的高度为100%让他们充满整个窗口。不然的话他们的大小只会 -和填充他们的内容一样。

    -

    然后我们让id=c的元素的尺寸是容器的100%这里是body标签。

    -

    最后我们设置它的displayblock。canvas的display默认为 -inline。行内元素的末尾会有空格。 -通过设置canvas为块级元素就能消除这个空格。

    -

    这里是结果。

    -

    - -

    -

    你可以看到canvas充满了整个页面,但是有两个问题。 -第一是我们的立方体被拉伸了。他们不是立方体了更像是个盒子,太高或者太宽。 在新标签中打开它然后改变尺寸你就能看到立方体是怎么在宽高上被拉伸的。

    -

    -

    另一个问题是立方体看起来分辨率太低或者说块状化或者有点模糊。 -将窗口拉伸的非常大你就能看到问题。

    -

    -

    我们先解决拉伸的问题。为此我们要将相机的宽高比设置为canvas的宽高比。 -我们可以通过canvas的clientWidthclientHeight属性来实现。

    -

    我们需要将渲染循环变成这样。

    -
    function render(time) {
    +        

    HTML中的body默认有5个像素的margin值所以设置margin为0来移除margin值。 + 设置html和body的高度为100%让他们充满整个窗口。不然的话他们的大小只会 + 和填充他们的内容一样。

    +

    然后我们让id=c的元素的尺寸是容器的100%这里是body标签。

    +

    最后我们设置它的displayblock。canvas的display默认为 + inline。行内元素的末尾会有空格。 + 通过设置canvas为块级元素就能消除这个空格。 +

    +

    这里是结果。

    +

    + + +

    +

    你可以看到canvas充满了整个页面,但是有两个问题。 + 第一是我们的立方体被拉伸了。他们不是立方体了更像是个盒子,太高或者太宽。 在新标签中打开它然后改变尺寸你就能看到立方体是怎么在宽高上被拉伸的。

    +

    +

    另一个问题是立方体看起来分辨率太低或者说块状化或者有点模糊。 + 将窗口拉伸的非常大你就能看到问题。

    +

    +

    我们先解决拉伸的问题。为此我们要将相机的宽高比设置为canvas的宽高比。 + 我们可以通过canvas的clientWidthclientHeight属性来实现。

    +

    我们需要将渲染循环变成这样。

    +
    function render(time) {
       time *= 0.001;
     
     +  const canvas = renderer.domElement;
    @@ -87,30 +97,35 @@ 

    响应式设计

    ...
    -

    现在立方体应该不会变形了。

    -

    - -

    -

    在新标签页中打开例子你应该能看到立方体的宽高不会再被拉伸了。 -他们都会保持正确的比例不管窗口的尺寸如何。

    -

    -

    我们现在来解决块状化的问题。

    -

    canvas元素有两个尺寸。一个是canvas在页面上的显示尺寸, -是我们用CSS来设置的。另一个尺寸是canvas本身像素的数量。这和图片一样。 -比如我们有一个128x64像素的图片然后我们可以通过CSS让它显示为 -400x200像素。

    -
    <img src="some128x64image.jpg" style="width:400px; height:200px">
    +        

    现在立方体应该不会变形了。

    +

    + + +

    +

    在新标签页中打开例子你应该能看到立方体的宽高不会再被拉伸了。 + 他们都会保持正确的比例不管窗口的尺寸如何。

    +

    +

    我们现在来解决块状化的问题。

    +

    canvas元素有两个尺寸。一个是canvas在页面上的显示尺寸, + 是我们用CSS来设置的。另一个尺寸是canvas本身像素的数量。这和图片一样。 + 比如我们有一个128x64像素的图片然后我们可以通过CSS让它显示为 + 400x200像素。

    +
    <img src="some128x64image.jpg" style="width:400px; height:200px">
     
    -

    一个canvas的内部尺寸,它的分辨率,通常被叫做绘图缓冲区(drawingbuffer)尺寸。 -在three.js中我们可以通过调用renderer.setSize来设置canvas的绘图缓冲区。 -我们应该选择什么尺寸? 最显而易见的是"和canvas的显示尺寸一样"。 -即可以直接用canvas的clientWidthclientHeight属性。

    -

    我们写一个函数来检查渲染器的canvas尺寸是不是和canvas的显示尺寸不一样 -如果不一样就设置它。

    -
    function resizeRendererToDisplaySize(renderer) {
    +        

    一个canvas的内部尺寸,它的分辨率,通常被叫做绘图缓冲区(drawingbuffer)尺寸。 + 在three.js中我们可以通过调用renderer.setSize来设置canvas的绘图缓冲区。 + 我们应该选择什么尺寸? 最显而易见的是"和canvas的显示尺寸一样"。 + 即可以直接用canvas的clientWidthclientHeight属性。

    +

    我们写一个函数来检查渲染器的canvas尺寸是不是和canvas的显示尺寸不一样 + 如果不一样就设置它。

    +
    function resizeRendererToDisplaySize(renderer) {
       const canvas = renderer.domElement;
       const width = canvas.clientWidth;
       const height = canvas.clientHeight;
    @@ -121,17 +136,18 @@ 

    响应式设计

    return needResize; }
    -

    注意我们检查了canvas是否真的需要调整大小。 -调整画布大小是canvas规范的一个有趣部分,如果它已经是我们想要的大小,最好不要设置相同的大小.

    -

    一旦我们知道了是否需要调整大小我们就调用renderer.setSize然后 -传入新的宽高。在末尾传入false很重要。 -render.setSize默认会设置canvas的CSS尺寸但这并不是我们想要的。 -我们希望浏览器能继续工作就像其他使用CSS来定义尺寸的其他元素。我们不希望 -three.js使用canvas和其他元素不一样。

    -

    注意如果我们的canvas大小被调整了那函数会返回true。我们可以利用 -这个来检查是否有其他的东西应该更新。我们修改渲染循环 -来使用我们的新函数。

    -
    function render(time) {
    +        

    注意我们检查了canvas是否真的需要调整大小。 + 调整画布大小是canvas规范的一个有趣部分,如果它已经是我们想要的大小,最好不要设置相同的大小.

    +

    一旦我们知道了是否需要调整大小我们就调用renderer.setSize然后 + 传入新的宽高。在末尾传入false很重要。 + render.setSize默认会设置canvas的CSS尺寸但这并不是我们想要的。 + 我们希望浏览器能继续工作就像其他使用CSS来定义尺寸的其他元素。我们不希望 + three.js使用canvas和其他元素不一样。 +

    +

    注意如果我们的canvas大小被调整了那函数会返回true。我们可以利用 + 这个来检查是否有其他的东西应该更新。我们修改渲染循环 + 来使用我们的新函数。

    +
    function render(time) {
       time *= 0.001;
     
     +  if (resizeRendererToDisplaySize(renderer)) {
    @@ -142,53 +158,64 @@ 

    响应式设计

    ...
    -

    因为只有canvas的显示尺寸变化时宽高比才变化所以我们 -只在resizeRendererToDisplaySize函数返回true时才设置摄像机的宽高比。

    -

    - -

    -

    现在渲染的分辨率应该是和canvas的显示尺寸一样的。

    -

    为了说清楚让CSS处理调整尺寸我们将代码放进一个单独的js文件。 -这里还有一些例子我们让CSS决定尺寸的大小并且注意我们并没有改变任何 -代码来让他们工作。

    -

    我们将立方体放在文字段落的中间。

    -

    - -

    -

    这是我们在编辑器样式布局中使用的相同代码,右侧的控制区域可以调整大小。

    -

    - -

    -

    重点注意我们的代码并没有改变,只有我们的HTML和CSS变了。

    -

    应对HD-DPI显示器

    -

    HD-DPI代表每英寸高密度点显示器(视网膜显示器)。它指的是当今大多数的Mac和windows机器以及几乎所有的智能手机。

    -

    浏览器中的工作方式是不管屏幕的分辨率有多高使用CSS像素设置尺寸会被认为是一样的。 -同样的物理尺寸浏览器会渲染出字体的更多细节。

    -

    使用three.js有多种方法来应对HD-DPI。

    -

    第一种就是不做任何特别的事情。这可以说是最常见的。 -渲染三维图形需要大量的GPU处理能力。移动端的GPU能力比桌面端的要弱。至少截止到2018年, -手机都有非常高的分辨率显示器。 -目前最好的手机的HD-DPI比例为3x,意思是非高密度点显示器上的一个像素在高密度显示器上是9个像素。 -意味着需要9倍的渲染。

    -

    计算9倍的像素是个大工程所以如果保持代码不变我们将计算一个像素然后浏览器将以三倍大小绘制(3x3=9像素)。

    -

    对于大型的three.js应用来说上面就是你想要的否侧你的帧速率会很低。

    -

    尽管如此如果你确实想用设备的分辨率来渲染,three.js中有两种方法来实现。

    -

    一种是使用renderer.setPixelRatio来告诉three.js分辨率的倍数。 -访问浏览器从CSS像素到设备像素的倍数然后传给three.js。

    -
     renderer.setPixelRatio(window.devicePixelRatio);
    -

    之后任何对renderer.setSize的调用都会神奇地使用您请求的大小乘以您传入的像素比例. -强烈不建议这样。 看下面。

    -

    另一种方法是在调整canvas的大小时自己处理。

    -
        function resizeRendererToDisplaySize(renderer) {
    +        

    因为只有canvas的显示尺寸变化时宽高比才变化所以我们 + 只在resizeRendererToDisplaySize函数返回true时才设置摄像机的宽高比。

    +

    + + +

    +

    现在渲染的分辨率应该是和canvas的显示尺寸一样的。

    +

    为了说清楚让CSS处理调整尺寸我们将代码放进一个单独的js文件。 + 这里还有一些例子我们让CSS决定尺寸的大小并且注意我们并没有改变任何 + 代码来让他们工作。

    +

    我们将立方体放在文字段落的中间。

    +

    + + +

    +

    这是我们在编辑器样式布局中使用的相同代码,右侧的控制区域可以调整大小。

    +

    + + +

    +

    重点注意我们的代码并没有改变,只有我们的HTML和CSS变了。

    +

    应对HD-DPI显示器

    +

    HD-DPI代表每英寸高密度点显示器(视网膜显示器)。它指的是当今大多数的Mac和windows机器以及几乎所有的智能手机。

    +

    浏览器中的工作方式是不管屏幕的分辨率有多高使用CSS像素设置尺寸会被认为是一样的。 + 同样的物理尺寸浏览器会渲染出字体的更多细节。

    +

    使用three.js有多种方法来应对HD-DPI。

    +

    第一种就是不做任何特别的事情。这可以说是最常见的。 + 渲染三维图形需要大量的GPU处理能力。移动端的GPU能力比桌面端的要弱。至少截止到2018年, + 手机都有非常高的分辨率显示器。 + 目前最好的手机的HD-DPI比例为3x,意思是非高密度点显示器上的一个像素在高密度显示器上是9个像素。 + 意味着需要9倍的渲染。

    +

    计算9倍的像素是个大工程所以如果保持代码不变我们将计算一个像素然后浏览器将以三倍大小绘制(3x3=9像素)。

    +

    对于大型的three.js应用来说上面就是你想要的否侧你的帧速率会很低。

    +

    尽管如此如果你确实想用设备的分辨率来渲染,three.js中有两种方法来实现。

    +

    一种是使用renderer.setPixelRatio来告诉three.js分辨率的倍数。 + 访问浏览器从CSS像素到设备像素的倍数然后传给three.js。

    +
     renderer.setPixelRatio(window.devicePixelRatio);
    +
    +

    之后任何对renderer.setSize的调用都会神奇地使用您请求的大小乘以您传入的像素比例. + 强烈不建议这样。 看下面。 +

    +

    另一种方法是在调整canvas的大小时自己处理。

    +
        function resizeRendererToDisplaySize(renderer) {
           const canvas = renderer.domElement;
           const pixelRatio = window.devicePixelRatio;
           const width = canvas.clientWidth * pixelRatio | 0;
    @@ -200,32 +227,37 @@ 

    应对HD-DPI显示器

    return needResize; }
    -

    第二章方法从客观上来说更好。为什么?因为我拿到了我想要的。 -在使用three.js时有很多种情况下我们需要知道canvas的绘图缓冲区的确切尺寸。 -比如制作后期处理滤镜或者我们在操作着色器需要访问gl_FragCoord变量,如果我们截屏或者给GPU -读取像素,绘制到二维的canvas等等。 -通过我们自己处理我们会一直知道使用的尺寸是不是我们需要的。 -幕后并没有什么特殊的魔法发生。

    -

    这是一个使用上面代码的例子。

    -

    - -

    -

    可能很难看出区别但是如果你有一个HD-DPI显示器 -和上面的例子做对比你就能发现边角更清晰。

    -

    这篇文章涵盖了一个非常基础但是很有必要的主题。接下来我们快速 -过一遍three.js提供的基本的东西 .

    - +

    第二种方法从客观上来说更好。为什么?因为我拿到了我想要的。 + 在使用three.js时有很多种情况下我们需要知道canvas的绘图缓冲区的确切尺寸。 + 比如制作后期处理滤镜或者我们在操作着色器需要访问gl_FragCoord变量,如果我们截屏或者给GPU + 读取像素,绘制到二维的canvas等等。 + 通过我们自己处理我们会一直知道使用的尺寸是不是我们需要的。 + 幕后并没有什么特殊的魔法发生。

    +

    这是一个使用上面代码的例子。

    +

    + + +

    +

    可能很难看出区别但是如果你有一个HD-DPI显示器 + 和上面的例子做对比你就能发现边角更清晰。

    +

    这篇文章涵盖了一个非常基础但是很有必要的主题。接下来我们快速过一遍 + three.js提供的基本的东西 . +

    +
    - +
    + - \ No newline at end of file + + + \ No newline at end of file diff --git a/manual/zh/textures.html b/manual/zh/textures.html index 237f914dfbf607..2ce2607f97dc13 100644 --- a/manual/zh/textures.html +++ b/manual/zh/textures.html @@ -368,7 +368,7 @@

    重复,偏移 });

    然后,我们会再次使用 lil-gui 来提供一个简单的界面。

    -
    import {GUI} from '/examples/jsm/libs/lil-gui.module.min.js';
    +
    import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
     

    正如我们在之前的lil-gui例子中所做的那样,我们将使用一个简单的类来给lil-gui提供一个可以以度数为单位进行操作的对象,但它将以弧度为单位设置该属性。

    class DegRadHelper {
    diff --git a/manual/zh/transparency.html b/manual/zh/transparency.html
    index 38adf68bbfcf95..a06eae4d49c6b3 100644
    --- a/manual/zh/transparency.html
    +++ b/manual/zh/transparency.html
    @@ -329,9 +329,9 @@ 

    透明

    .onChange(requestRenderIfNotRequested);

    当然我们需要引用lil-gui。

    -
    import * as THREE from '/build/three.module.js';
    -import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
    -+import {GUI} from '/examples/jsm/libs/lil-gui.module.min.js';
    +			
    import * as THREE from 'three';
    +import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
    ++import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
     

    下面是结果。

    diff --git a/manual/zh/webxr.html b/manual/zh/webxr-basics.html similarity index 100% rename from manual/zh/webxr.html rename to manual/zh/webxr-basics.html diff --git a/package-lock.json b/package-lock.json index 3ab9ddb10a8d95..fd16dd8deca610 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,31 +1,31 @@ { "name": "three", - "version": "0.142.0", + "version": "0.145.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "three", - "version": "0.142.0", + "version": "0.145.0", "license": "MIT", "devDependencies": { - "@babel/core": "^7.18.6", - "@babel/eslint-parser": "^7.18.2", + "@babel/core": "^7.19.3", + "@babel/eslint-parser": "^7.19.1", "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/preset-env": "^7.18.6", + "@babel/preset-env": "^7.19.3", "@rollup/plugin-babel": "^5.3.1", - "@rollup/plugin-node-resolve": "^13.3.0", + "@rollup/plugin-node-resolve": "^14.1.0", "chalk": "^5.0.1", - "concurrently": "^7.2.2", - "eslint": "^8.18.0", + "concurrently": "^7.4.0", + "eslint": "^8.24.0", "eslint-config-mdcs": "^5.0.0", "eslint-plugin-compat": "^4.0.2", - "eslint-plugin-html": "^6.2.0", + "eslint-plugin-html": "^7.1.0", "eslint-plugin-import": "^2.26.0", - "rollup": "^2.75.7", + "rollup": "^2.79.1", "rollup-plugin-filesize": "^9.1.2", "rollup-plugin-terser": "^7.0.2", - "rollup-plugin-visualizer": "^5.6.0", + "rollup-plugin-visualizer": "^5.8.2", "servez": "^1.14.1" } }, @@ -55,30 +55,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.6.tgz", - "integrity": "sha512-tzulrgDT0QD6U7BJ4TKVk2SDDg7wlP39P9yAx1RfLy7vP/7rsDRlWVfbWxElslu56+r7QOhB2NSDsabYYruoZQ==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.4.tgz", + "integrity": "sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.6.tgz", - "integrity": "sha512-cQbWBpxcbbs/IUredIPkHiAGULLV8iwgNRMFzvbhEXISp4f3rUUXE5+TIw6KwUWUR3DwyI6gmBRnmAtYaWehwQ==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", + "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.6", - "@babel/helper-compilation-targets": "^7.18.6", - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helpers": "^7.18.6", - "@babel/parser": "^7.18.6", - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.6", - "@babel/types": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helpers": "^7.19.0", + "@babel/parser": "^7.19.3", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.3", + "@babel/types": "^7.19.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -94,12 +94,12 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.18.2.tgz", - "integrity": "sha512-oFQYkE8SuH14+uR51JVAmdqwKYXGRjEXx7s+WiagVjqQ+HPE+nnwyF2qlVG8evUsUHmPcA+6YXMEDbIhEyQc5A==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz", + "integrity": "sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==", "dev": true, "dependencies": { - "eslint-scope": "^5.1.1", + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", "eslint-visitor-keys": "^2.1.0", "semver": "^6.3.0" }, @@ -112,12 +112,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.18.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.7.tgz", - "integrity": "sha512-shck+7VLlY72a2w9c3zYWuE1pwOKEiQHV7GTUbSnhyl5eu3i04t30tBY82ZRWrDfo3gkakCFtevExnxbkf2a3A==", + "version": "7.19.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.5.tgz", + "integrity": "sha512-DxbNz9Lz4aMZ99qPpO1raTbcrI1ZeYh+9NR9qhfkQIbFtVEqotHojEBxHzmxhVONkGt6VyrqVQcgpefMy9pqcg==", "dev": true, "dependencies": { - "@babel/types": "^7.18.7", + "@babel/types": "^7.19.4", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -152,27 +152,27 @@ } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.6.tgz", - "integrity": "sha512-KT10c1oWEpmrIRYnthbzHgoOf6B+Xd6a5yhdbNtdhtG7aO1or5HViuf1TQR36xY/QprXA5nvxO6nAjhJ4y38jw==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", + "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", "dev": true, "dependencies": { "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/types": "^7.18.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.6.tgz", - "integrity": "sha512-vFjbfhNCzqdeAtZflUFrG5YIFqGTqsctrtkZ1D/NB0mDW9TwW3GmmUepYY4G9wCET5rY5ugz4OGTcLd614IzQg==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", + "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.18.6", + "@babel/compat-data": "^7.19.3", "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.20.2", + "browserslist": "^4.21.3", "semver": "^6.3.0" }, "engines": { @@ -183,17 +183,17 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.6.tgz", - "integrity": "sha512-YfDzdnoxHGV8CzqHGyCbFvXg5QESPFkXlHtvdCkesLjjVMT2Adxe4FGUR5ChIb3DxSaXO12iIOCWoXdsUVwnqw==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz", + "integrity": "sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.6", - "@babel/helper-function-name": "^7.18.6", - "@babel/helper-member-expression-to-functions": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-member-expression-to-functions": "^7.18.9", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.9", "@babel/helper-split-export-declaration": "^7.18.6" }, "engines": { @@ -204,9 +204,9 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.18.6.tgz", - "integrity": "sha512-7LcpH1wnQLGrI+4v+nPp+zUvIkF9x0ddv1Hkdue10tg3gmRnLy97DXh4STiOf1qeIInyD69Qv5kKSZzKD8B/7A==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", + "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", @@ -220,15 +220,13 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz", - "integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.13.0", - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/traverse": "^7.13.0", + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2", @@ -239,9 +237,9 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.6.tgz", - "integrity": "sha512-8n6gSfn2baOY+qlp+VSzsosjCVGFqWKmDF0cCWOybh52Dw3SEyoWR1KrhMJASjLwIEkkAufZ0xvr+SxLHSpy2Q==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", "dev": true, "engines": { "node": ">=6.9.0" @@ -260,13 +258,13 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.6.tgz", - "integrity": "sha512-0mWMxV1aC97dhjCah5U5Ua7668r5ZmSC2DLfH2EZnf9c3/dHZKiFa5pRLMH5tjSl471tY6496ZWk/kjNONBxhw==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "dev": true, "dependencies": { - "@babel/template": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -285,12 +283,12 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.6.tgz", - "integrity": "sha512-CeHxqwwipekotzPDUuJOfIMtcIHBuc7WAzLmTYWctVigqS5RktNMQ5bEwQSuGewzYnCtTWa3BARXeiLxDTv+Ng==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", + "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -309,19 +307,19 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.6.tgz", - "integrity": "sha512-L//phhB4al5uucwzlimruukHB3jRd5JGClwRMD/ROrVjXfLqovYnvQrK/JK36WYyVwGGO7OD3kMyVTjx+WVPhw==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", + "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", "@babel/helper-simple-access": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -340,24 +338,24 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.6.tgz", - "integrity": "sha512-gvZnm1YAAxh13eJdkb9EWHBnF3eAub3XTLCZEehHT2kWxiKVRL64+ae5Y6Ivne0mVHmMYKT+xWgZO+gQhuLUBg==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", + "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.6.tgz", - "integrity": "sha512-z5wbmV55TveUPZlCLZvxWHtrjuJd+8inFhk7DG0WW87/oJuGDcjDiu7HIvGcpf5464L6xKCg3vNkmlVVz9hwyQ==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", + "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.6", - "@babel/helper-wrap-function": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-wrap-function": "^7.18.9", + "@babel/types": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -367,40 +365,40 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.18.6.tgz", - "integrity": "sha512-fTf7zoXnUGl9gF25fXCWE26t7Tvtyn6H4hkLSYhATwJvw2uYxd3aoXplMSe0g9XbwK7bmxNes7+FGO0rB/xC0g==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", + "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.18.6", - "@babel/helper-member-expression-to-functions": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/traverse": "^7.19.1", + "@babel/types": "^7.19.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", - "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", + "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.19.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.6.tgz", - "integrity": "sha512-4KoLhwGS9vGethZpAhYnMejWkX64wsnHPDwvOsKWU6Fg4+AlK2Jz3TyjQLMEPvz+1zemi/WBdkYxCD0bAfIkiw==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz", + "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -418,10 +416,19 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true, "engines": { "node": ">=6.9.0" @@ -437,29 +444,29 @@ } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.18.6.tgz", - "integrity": "sha512-I5/LZfozwMNbwr/b1vhhuYD+J/mU+gfGAj5td7l5Rv9WYmH6i3Om69WGKNmlIpsVW/mF6O5bvTKbvDQZVgjqOw==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", + "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", "dev": true, "dependencies": { - "@babel/helper-function-name": "^7.18.6", - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/helper-function-name": "^7.19.0", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.6.tgz", - "integrity": "sha512-vzSiiqbQOghPngUYt/zWGvK3LAsPhz55vc9XNN0xAl2gV4ieShI2OQli5duxWHD+72PZPTKAcfcZDE1Cwc5zsQ==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.4.tgz", + "integrity": "sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==", "dev": true, "dependencies": { - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.4", + "@babel/types": "^7.19.4" }, "engines": { "node": ">=6.9.0" @@ -551,9 +558,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.6.tgz", - "integrity": "sha512-uQVSa9jJUe/G/304lXspfWVpKpK4euFLgGiMQFOCpM/bgcAdeoHwi/OQz23O9GK2osz26ZiXRRV9aV+Yl1O8tw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.4.tgz", + "integrity": "sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -578,14 +585,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.6.tgz", - "integrity": "sha512-Udgu8ZRgrBrttVz6A0EVL0SJ1z+RLbIeqsu632SA1hf0awEppD6TvdznoH+orIF8wtFFAV/Enmw9Y+9oV8TQcw==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", + "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.6" + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-proposal-optional-chaining": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -595,14 +602,14 @@ } }, "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.6.tgz", - "integrity": "sha512-WAz4R9bvozx4qwf74M+sfqPMKfSqwM0phxPTR6iJIi8robgzXwkEgmeJG1gEKhm6sDqT/U9aV3lfcqybIpev8w==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz", + "integrity": "sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-remap-async-to-generator": "^7.18.9", "@babel/plugin-syntax-async-generators": "^7.8.4" }, "engines": { @@ -662,12 +669,12 @@ } }, "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.6.tgz", - "integrity": "sha512-zr/QcUlUo7GPo6+X1wC98NJADqmy5QTFWWhqeQWiki4XHafJtLl/YMGkmRB2szDD2IYJCCdBTd4ElwhId9T7Xw==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", + "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.9", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { @@ -694,12 +701,12 @@ } }, "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.6.tgz", - "integrity": "sha512-zMo66azZth/0tVd7gmkxOkOjs2rpHyhpcFo565PUP37hSp6hSd9uUKIfTDFMz58BwqgQKhJ9YxtM5XddjXVn+Q==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", + "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.9", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { @@ -742,16 +749,16 @@ } }, "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.6.tgz", - "integrity": "sha512-9yuM6wr4rIsKa1wlUAbZEazkCrgw2sMPEXCr4Rnwetu7cEW1NydkCWytLuYletbf8vFxdJxFhwEZqMpOx2eZyw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.19.4.tgz", + "integrity": "sha512-wHmj6LDxVDnL+3WhXteUBaoM1aVILZODAUjg11kHqG4cOlfgMQGxw6aCgvrXrmaJR3Bn14oZhImyCPZzRpC93Q==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.18.6", - "@babel/helper-compilation-targets": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/compat-data": "^7.19.4", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-plugin-utils": "^7.19.0", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.18.6" + "@babel/plugin-transform-parameters": "^7.18.8" }, "engines": { "node": ">=6.9.0" @@ -777,13 +784,13 @@ } }, "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.6.tgz", - "integrity": "sha512-PatI6elL5eMzoypFAiYDpYQyMtXTn+iMhuxxQt5mAXD4fEmKorpSI3PHd+i3JXBJN3xyA6MvJv7at23HffFHwA==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", + "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { @@ -1083,12 +1090,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.6.tgz", - "integrity": "sha512-pRqwb91C42vs1ahSAWJkxOxU1RHWDn16XAa6ggQ72wjLlWyYeAcLvTtE0aM8ph3KNydy9CQF2nLYcjq1WysgxQ==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.19.4.tgz", + "integrity": "sha512-934S2VLLlt2hRJwPf4MczaOr4hYF0z+VKPwqTNxyKX7NthTiPfhuKFWQZHXRM0vh/wo/VyXB3s4bZUNA08l+tQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -1098,17 +1105,18 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.6.tgz", - "integrity": "sha512-XTg8XW/mKpzAF3actL554Jl/dOYoJtv3l8fxaEczpgz84IeeVf+T1u2CSvPHuZbt0w3JkIx4rdn/MRQI7mo0HQ==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz", + "integrity": "sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.6", - "@babel/helper-function-name": "^7.18.6", + "@babel/helper-compilation-targets": "^7.19.0", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-replace-supers": "^7.18.9", "@babel/helper-split-export-declaration": "^7.18.6", "globals": "^11.1.0" }, @@ -1120,12 +1128,12 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.6.tgz", - "integrity": "sha512-9repI4BhNrR0KenoR9vm3/cIc1tSBIo+u1WVjKCAynahj25O8zfbiE6JtAtHPGQSs4yZ+bA8mRasRP+qc+2R5A==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", + "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -1135,12 +1143,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.6.tgz", - "integrity": "sha512-tgy3u6lRp17ilY8r1kP4i2+HDUwxlVqq3RTc943eAWSzGgpU1qhiKpqZ5CMyHReIYPHdo3Kg8v8edKtDqSVEyQ==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.19.4.tgz", + "integrity": "sha512-t0j0Hgidqf0aM86dF8U+vXYReUgJnlv4bZLsyoPnwZNrGY+7/38o8YjaELrvHeVfTZao15kjR0PVv0nju2iduA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -1166,12 +1174,12 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.6.tgz", - "integrity": "sha512-NJU26U/208+sxYszf82nmGYqVF9QN8py2HFTblPT9hbawi8+1C5a9JubODLTGFuT0qlkqVinmkwOD13s0sZktg==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", + "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -1197,9 +1205,9 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.6.tgz", - "integrity": "sha512-WAjoMf4wIiSsy88KmG7tgj2nFdEK7E46tArVtcgED7Bkj6Fg/tG5SbvNIOKxbFS2VFgNh6+iaPswBeQZm4ox8w==", + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", + "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" @@ -1212,14 +1220,14 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.6.tgz", - "integrity": "sha512-kJha/Gbs5RjzIu0CxZwf5e3aTTSlhZnHMT8zPWnJMjNpLOUgqevg+PN5oMH68nMCXnfiMo4Bhgxqj59KHTlAnA==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", + "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.18.6", - "@babel/helper-function-name": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -1229,12 +1237,12 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.6.tgz", - "integrity": "sha512-x3HEw0cJZVDoENXOp20HlypIHfl0zMIhMVZEBVTfmqbObIpsMxMbmU5nOEO8R7LYT+z5RORKPlTI5Hj4OsO9/Q==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", + "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -1294,14 +1302,14 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.6.tgz", - "integrity": "sha512-UbPYpXxLjTw6w6yXX2BYNxF3p6QY225wcTkfQCy3OMnSlS/C3xGtwUjEzGkldb/sy6PWLiCQ3NbYfjWUTI3t4g==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz", + "integrity": "sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A==", "dev": true, "dependencies": { "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helper-plugin-utils": "^7.19.0", "@babel/helper-validator-identifier": "^7.18.6", "babel-plugin-dynamic-import-node": "^2.3.3" }, @@ -1329,13 +1337,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.18.6.tgz", - "integrity": "sha512-UmEOGF8XgaIqD74bC8g7iV3RYj8lMf0Bw7NJzvnS9qQhM4mg+1WHKotUIdjxgD2RGrgFLZZPCFPFj3P/kVDYhg==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", + "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.19.0", + "@babel/helper-plugin-utils": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -1376,9 +1384,9 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.6.tgz", - "integrity": "sha512-FjdqgMv37yVl/gwvzkcB+wfjRI8HQmc5EgOG9iGNvUY1ok+TjsoaMP7IqCDZBhkFcM5f3OPVMs6Dmp03C5k4/A==", + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz", + "integrity": "sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" @@ -1452,13 +1460,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.18.6.tgz", - "integrity": "sha512-ayT53rT/ENF8WWexIRg9AiV9h0aIteyWn5ptfZTZQrjk/+f3WdrJGCY4c9wcgl2+MKkKPhzbYp97FTsquZpDCw==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", + "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -1483,12 +1491,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.6.tgz", - "integrity": "sha512-UuqlRrQmT2SWRvahW46cGSany0uTlcj8NYOS5sRGYi8FxPYPoLd5DDmMd32ZXEj2Jq+06uGVQKHxa/hJx2EzKw==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", + "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -1498,12 +1506,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.6.tgz", - "integrity": "sha512-7m71iS/QhsPk85xSjFPovHPcH3H9qeyzsujhTc+vcdnsXavoWYJ74zx0lP5RhpC5+iDnVLO+PPMHzC11qels1g==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", + "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -1513,12 +1521,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.6.tgz", - "integrity": "sha512-XNRwQUXYMP7VLuy54cr/KS/WeL3AZeORhrmeZ7iewgu+X2eBqmpaLI/hzqr9ZxCeUoq0ASK4GUzSM0BDhZkLFw==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", + "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -1544,29 +1552,29 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.18.6.tgz", - "integrity": "sha512-WrthhuIIYKrEFAwttYzgRNQ5hULGmwTj+D6l7Zdfsv5M7IWV/OZbUfbeL++Qrzx1nVJwWROIFhCHRYQV4xbPNw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.4.tgz", + "integrity": "sha512-5QVOTXUdqTCjQuh2GGtdd7YEhoRXBMVGROAtsBeLGIbIz3obCBIfRMT1I3ZKkMgNzwkyCkftDXSSkHxnfVf4qg==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.18.6", - "@babel/helper-compilation-targets": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/compat-data": "^7.19.4", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-plugin-utils": "^7.19.0", "@babel/helper-validator-option": "^7.18.6", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.6", - "@babel/plugin-proposal-async-generator-functions": "^7.18.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-async-generator-functions": "^7.19.1", "@babel/plugin-proposal-class-properties": "^7.18.6", "@babel/plugin-proposal-class-static-block": "^7.18.6", "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-proposal-export-namespace-from": "^7.18.6", + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.6", + "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.18.6", + "@babel/plugin-proposal-object-rest-spread": "^7.19.4", "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.6", + "@babel/plugin-proposal-optional-chaining": "^7.18.9", "@babel/plugin-proposal-private-methods": "^7.18.6", "@babel/plugin-proposal-private-property-in-object": "^7.18.6", "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", @@ -1588,41 +1596,41 @@ "@babel/plugin-transform-arrow-functions": "^7.18.6", "@babel/plugin-transform-async-to-generator": "^7.18.6", "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.18.6", - "@babel/plugin-transform-classes": "^7.18.6", - "@babel/plugin-transform-computed-properties": "^7.18.6", - "@babel/plugin-transform-destructuring": "^7.18.6", + "@babel/plugin-transform-block-scoping": "^7.19.4", + "@babel/plugin-transform-classes": "^7.19.0", + "@babel/plugin-transform-computed-properties": "^7.18.9", + "@babel/plugin-transform-destructuring": "^7.19.4", "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-duplicate-keys": "^7.18.6", + "@babel/plugin-transform-duplicate-keys": "^7.18.9", "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.6", - "@babel/plugin-transform-function-name": "^7.18.6", - "@babel/plugin-transform-literals": "^7.18.6", + "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-function-name": "^7.18.9", + "@babel/plugin-transform-literals": "^7.18.9", "@babel/plugin-transform-member-expression-literals": "^7.18.6", "@babel/plugin-transform-modules-amd": "^7.18.6", "@babel/plugin-transform-modules-commonjs": "^7.18.6", - "@babel/plugin-transform-modules-systemjs": "^7.18.6", + "@babel/plugin-transform-modules-systemjs": "^7.19.0", "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.18.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", "@babel/plugin-transform-new-target": "^7.18.6", "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.18.6", + "@babel/plugin-transform-parameters": "^7.18.8", "@babel/plugin-transform-property-literals": "^7.18.6", "@babel/plugin-transform-regenerator": "^7.18.6", "@babel/plugin-transform-reserved-words": "^7.18.6", "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.18.6", + "@babel/plugin-transform-spread": "^7.19.0", "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-transform-template-literals": "^7.18.6", - "@babel/plugin-transform-typeof-symbol": "^7.18.6", - "@babel/plugin-transform-unicode-escapes": "^7.18.6", + "@babel/plugin-transform-template-literals": "^7.18.9", + "@babel/plugin-transform-typeof-symbol": "^7.18.9", + "@babel/plugin-transform-unicode-escapes": "^7.18.10", "@babel/plugin-transform-unicode-regex": "^7.18.6", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.18.6", - "babel-plugin-polyfill-corejs2": "^0.3.1", - "babel-plugin-polyfill-corejs3": "^0.5.2", - "babel-plugin-polyfill-regenerator": "^0.3.1", - "core-js-compat": "^3.22.1", + "@babel/types": "^7.19.4", + "babel-plugin-polyfill-corejs2": "^0.3.3", + "babel-plugin-polyfill-corejs3": "^0.6.0", + "babel-plugin-polyfill-regenerator": "^0.4.1", + "core-js-compat": "^3.25.1", "semver": "^6.3.0" }, "engines": { @@ -1649,9 +1657,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz", - "integrity": "sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.4.tgz", + "integrity": "sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==", "dev": true, "dependencies": { "regenerator-runtime": "^0.13.4" @@ -1661,33 +1669,33 @@ } }, "node_modules/@babel/template": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.6.tgz", - "integrity": "sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.6.tgz", - "integrity": "sha512-zS/OKyqmD7lslOtFqbscH6gMLFYOfG1YPqCKfAW5KrTeolKqvB8UelR49Fpr6y93kYkW2Ik00mT1LOGiAGvizw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.4.tgz", + "integrity": "sha512-w3K1i+V5u2aJUOXBFFC5pveFLmtq1s3qcdDNC2qRI6WPBQIDaKFqXxDEqDO/h1dQ3HjsZoZMyIy6jGLq0xtw+g==", "dev": true, "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.6", - "@babel/helper-function-name": "^7.18.6", + "@babel/generator": "^7.19.4", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.18.6", - "@babel/types": "^7.18.6", + "@babel/parser": "^7.19.4", + "@babel/types": "^7.19.4", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1696,12 +1704,13 @@ } }, "node_modules/@babel/types": { - "version": "7.18.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.7.tgz", - "integrity": "sha512-QG3yxTcTIBoAcQmkCs+wAPYZhu7Dk9rXKacINfNbdJDNERTbLQbHGyVG8q/YGMPeCJRIhSY0+fTc5+xuh6WPSQ==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1709,14 +1718,14 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.2", + "espree": "^9.4.0", "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -1726,12 +1735,15 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -1750,9 +1762,9 @@ "dev": true }, "node_modules/@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", + "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -1763,6 +1775,19 @@ "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -1783,18 +1808,18 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", - "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true, "engines": { "node": ">=6.0.0" @@ -1811,12 +1836,12 @@ } }, "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", - "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.0", + "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" }, @@ -1825,19 +1850,19 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", - "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "node_modules/@mdn/browser-compat-data": { @@ -1846,6 +1871,50 @@ "integrity": "sha512-EWUguj2kd7ldmrF9F+vI5hUOralPd+sdsUnYbRy33vZTuZkduC1shE9TtEMEjAQwyfyMb4ole5KtjF8MsnQOlA==", "dev": true }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "dev": true, + "dependencies": { + "eslint-scope": "5.1.1" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@npmcli/fs": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", @@ -1857,9 +1926,9 @@ } }, "node_modules/@npmcli/fs/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -1888,9 +1957,9 @@ } }, "node_modules/@npmcli/git/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -1982,9 +2051,9 @@ } }, "node_modules/@rollup/plugin-node-resolve": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.3.0.tgz", - "integrity": "sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-14.1.0.tgz", + "integrity": "sha512-5G2niJroNCz/1zqwXtk0t9+twOSDlG00k1Wfd7bkbbXmwg8H8dvgHdIWAun53Ps/rckfvOC7scDBjuGFg5OaWw==", "dev": true, "dependencies": { "@rollup/pluginutils": "^3.1.0", @@ -1998,7 +2067,7 @@ "node": ">= 10.0.0" }, "peerDependencies": { - "rollup": "^2.42.0" + "rollup": "^2.78.0" } }, "node_modules/@rollup/pluginutils": { @@ -2040,9 +2109,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.0.tgz", - "integrity": "sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==", + "version": "18.8.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.5.tgz", + "integrity": "sha512-Bq7G3AErwe5A/Zki5fdD3O6+0zDChhg671NfPjtIcbtzDNZTv4NPKMRFr7gtYPG7y+B8uTiNK4Ngd9T0FTar6Q==", "dev": true }, "node_modules/@types/resolve": { @@ -2074,9 +2143,9 @@ } }, "node_modules/acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2238,6 +2307,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/array.prototype.flat": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", @@ -2320,13 +2398,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz", - "integrity": "sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.3.1", + "@babel/compat-data": "^7.17.7", + "@babel/helper-define-polyfill-provider": "^0.3.3", "semver": "^6.1.1" }, "peerDependencies": { @@ -2334,25 +2412,25 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz", - "integrity": "sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", + "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.1", - "core-js-compat": "^3.21.0" + "@babel/helper-define-polyfill-provider": "^0.3.3", + "core-js-compat": "^3.25.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz", - "integrity": "sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.1" + "@babel/helper-define-polyfill-provider": "^0.3.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" @@ -2392,9 +2470,9 @@ } }, "node_modules/body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dev": true, "dependencies": { "bytes": "3.1.2", @@ -2405,7 +2483,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.10.3", + "qs": "6.11.0", "raw-body": "2.5.1", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -2452,9 +2530,9 @@ "dev": true }, "node_modules/body-parser/node_modules/qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, "dependencies": { "side-channel": "^1.0.4" @@ -2526,6 +2604,18 @@ "concat-map": "0.0.1" } }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/brotli-size": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/brotli-size/-/brotli-size-4.0.0.tgz", @@ -2539,9 +2629,9 @@ } }, "node_modules/browserslist": { - "version": "4.20.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.4.tgz", - "integrity": "sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==", + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "dev": true, "funding": [ { @@ -2554,11 +2644,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001349", - "electron-to-chromium": "^1.4.147", - "escalade": "^3.1.1", - "node-releases": "^2.0.5", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" }, "bin": { "browserslist": "cli.js" @@ -2664,9 +2753,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001357", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001357.tgz", - "integrity": "sha512-b+KbWHdHePp+ZpNj+RDHFChZmuN+J5EvuQUlee9jOQIUAdhv9uvAZeEtUeLAknXbkiu1uxjQ9NLp1ie894CuWg==", + "version": "1.0.30001419", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001419.tgz", + "integrity": "sha512-aFO1r+g6R7TW+PNQxKzjITwLOyDhVRLjW0LcwS/HCZGUUKTGNp9+IwLC4xyDSZBygVL/mxaFR3HIV6wEKQuSzw==", "dev": true, "funding": [ { @@ -2686,9 +2775,9 @@ "dev": true }, "node_modules/chalk": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", - "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.1.2.tgz", + "integrity": "sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==", "dev": true, "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" @@ -2728,14 +2817,17 @@ } }, "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/code-point-at": { @@ -2808,13 +2900,13 @@ "dev": true }, "node_modules/concurrently": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.2.2.tgz", - "integrity": "sha512-DcQkI0ruil5BA/g7Xy3EWySGrFJovF5RYAYxwGvv9Jf9q9B1v3jPFP2tl6axExNf1qgF30kjoNYrangZ0ey4Aw==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.4.0.tgz", + "integrity": "sha512-M6AfrueDt/GEna/Vg9BqQ+93yuvzkSKmoTixnwEJkH0LlcGrRC2eCmjeG1tLLHIYfpYJABokqSGyMcXjm96AFA==", "dev": true, "dependencies": { "chalk": "^4.1.0", - "date-fns": "^2.16.1", + "date-fns": "^2.29.1", "lodash": "^4.17.21", "rxjs": "^7.0.0", "shell-quote": "^1.7.3", @@ -2824,10 +2916,14 @@ "yargs": "^17.3.1" }, "bin": { + "conc": "dist/bin/concurrently.js", "concurrently": "dist/bin/concurrently.js" }, "engines": { "node": "^12.20.0 || ^14.13.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" } }, "node_modules/concurrently/node_modules/chalk": { @@ -2906,13 +3002,10 @@ } }, "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true }, "node_modules/cookie": { "version": "0.5.0", @@ -2930,9 +3023,9 @@ "dev": true }, "node_modules/core-js": { - "version": "3.23.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.23.2.tgz", - "integrity": "sha512-ELJOWxNrJfOH/WK4VJ3Qd+fOqZuOuDNDJz0xG6Bt4mGg2eO/UT9CljCrbqDGovjLKUrGajEEBcoTOc0w+yBYeQ==", + "version": "3.25.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.25.5.tgz", + "integrity": "sha512-nbm6eZSjm+ZuBQxCUPQKQCoUEfFOXjUZ8dTTyikyKaWrTYmAVbykQfwsKE5dBK88u3QCkCrzsx/PPlKfhsvgpw==", "dev": true, "hasInstallScript": true, "funding": { @@ -2941,28 +3034,18 @@ } }, "node_modules/core-js-compat": { - "version": "3.23.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.23.2.tgz", - "integrity": "sha512-lrgZvxFwbQp9v7E8mX0rJ+JX7Bvh4eGULZXA1IAyjlsnWvCdw6TF8Tg6xtaSUSJMrSrMaLdpmk+V54LM1dvfOA==", + "version": "3.25.5", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.5.tgz", + "integrity": "sha512-ovcyhs2DEBUIE0MGEKHP4olCUW/XYte3Vroyxuh38rD1wAO4dHohsovUC4eAOuzFxE6b+RXvBU3UZ9o0YhUTkA==", "dev": true, "dependencies": { - "browserslist": "^4.20.4", - "semver": "7.0.0" + "browserslist": "^4.21.4" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" } }, - "node_modules/core-js-compat/node_modules/semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -3009,9 +3092,9 @@ } }, "node_modules/date-fns": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", - "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==", + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==", "dev": true, "engines": { "node": ">=0.11" @@ -3112,6 +3195,18 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -3125,28 +3220,19 @@ } }, "node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" }, "funding": { "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", @@ -3160,12 +3246,12 @@ ] }, "node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, "dependencies": { - "domelementtype": "^2.2.0" + "domelementtype": "^2.3.0" }, "engines": { "node": ">= 4" @@ -3175,14 +3261,14 @@ } }, "node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", + "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", "dev": true, "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.1" }, "funding": { "url": "https://github.com/fb55/domutils?sponsor=1" @@ -3211,9 +3297,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.163", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.163.tgz", - "integrity": "sha512-c9q94pUVqIdc8hyr7jZDB4bNEoNF3QJ7y35lnddMD+mXtiv5GsL1bT/RmfW/KEOmvlNg5Oy1qioiy4tA7e864Q==", + "version": "1.4.282", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.282.tgz", + "integrity": "sha512-Dki0WhHNh/br/Xi1vAkueU5mtIc9XLHcMKB6tNfQKk+kPG0TEUjRh5QEMAUbRp30/rYNMFD1zKKvbVzwq/4wmg==", "dev": true }, "node_modules/emoji-regex": { @@ -3242,9 +3328,9 @@ } }, "node_modules/entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", "dev": true, "engines": { "node": ">=0.12" @@ -3269,31 +3355,32 @@ "dev": true }, "node_modules/es-abstract": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", - "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", + "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.1", + "get-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", "has": "^1.0.3", "has-property-descriptors": "^1.0.0", "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", + "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", + "object-inspect": "^1.12.2", "object-keys": "^1.1.1", - "object.assign": "^4.1.2", + "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", "string.prototype.trimend": "^1.0.5", "string.prototype.trimstart": "^1.0.5", "unbox-primitive": "^1.0.2" @@ -3359,13 +3446,14 @@ } }, "node_modules/eslint": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.18.0.tgz", - "integrity": "sha512-As1EfFMVk7Xc6/CvhssHUjsAQSkpfXvUGMFC3ce8JDe6WvqCgRrLOBQbVpsBFr1X1V+RACOadnzVvcUS5ni2bA==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.25.0.tgz", + "integrity": "sha512-DVlJOZ4Pn50zcKW5bYH7GQK/9MsoQG2d5eDH0ebEkE8PbgzTTmtt/VTH9GGJ4BfeZCpBLqFfvsjX35UacUL83A==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.9.2", + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.10.5", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -3375,18 +3463,21 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", + "find-up": "^5.0.0", "glob-parent": "^6.0.1", "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -3397,8 +3488,7 @@ "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -3436,16 +3526,20 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", "dev": true, "dependencies": { - "debug": "^3.2.7", - "find-up": "^2.1.0" + "debug": "^3.2.7" }, "engines": { "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, "node_modules/eslint-module-utils/node_modules/debug": { @@ -3457,64 +3551,6 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-module-utils/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/eslint-plugin-compat": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-4.0.2.tgz", @@ -3553,12 +3589,12 @@ } }, "node_modules/eslint-plugin-html": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-6.2.0.tgz", - "integrity": "sha512-vi3NW0E8AJombTvt8beMwkL1R/fdRWl4QSNRNMhVQKWm36/X0KF0unGNAY4mqUF06mnwVWZcIcerrCnfn9025g==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-7.1.0.tgz", + "integrity": "sha512-fNLRraV/e6j8e3XYOC9xgND4j+U7b1Rq+OygMlLcMg+wI/IpVbF+ubQa3R78EjKB9njT6TQOlcK5rFKBVVtdfg==", "dev": true, "dependencies": { - "htmlparser2": "^7.1.2" + "htmlparser2": "^8.0.1" } }, "node_modules/eslint-plugin-import": { @@ -3703,9 +3739,9 @@ } }, "node_modules/eslint/node_modules/globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -3730,17 +3766,20 @@ } }, "node_modules/espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "dependencies": { - "acorn": "^8.7.1", + "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/espree/node_modules/eslint-visitor-keys": { @@ -3828,14 +3867,14 @@ } }, "node_modules/express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dev": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.0", + "body-parser": "1.20.1", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.5.0", @@ -3854,7 +3893,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.10.3", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.18.0", @@ -3894,9 +3933,9 @@ "dev": true }, "node_modules/express/node_modules/qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, "dependencies": { "side-channel": "^1.0.4" @@ -3949,6 +3988,34 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -3961,6 +4028,15 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -3982,6 +4058,18 @@ "node": ">= 0.4.0" } }, + "node_modules/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, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/finalhandler": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", @@ -4045,9 +4133,9 @@ } }, "node_modules/flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, "node_modules/forever-agent": { @@ -4147,12 +4235,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, "node_modules/functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -4244,9 +4326,9 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "dev": true, "dependencies": { "function-bind": "^1.1.1", @@ -4323,12 +4405,38 @@ "node": ">=4" } }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "node_modules/gzip-size": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", @@ -4461,9 +4569,9 @@ } }, "node_modules/htmlparser2": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", - "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", + "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", "dev": true, "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", @@ -4473,10 +4581,10 @@ } ], "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.2", - "domutils": "^2.8.0", - "entities": "^3.0.1" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "entities": "^4.3.0" } }, "node_modules/http-cache-semantics": { @@ -4663,9 +4771,9 @@ } }, "node_modules/ip": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", "dev": true }, "node_modules/ipaddr.js": { @@ -4706,21 +4814,24 @@ } }, "node_modules/is-builtin-module": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz", - "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz", + "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==", "dev": true, "dependencies": { - "builtin-modules": "^3.0.0" + "builtin-modules": "^3.3.0" }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, "engines": { "node": ">= 0.4" @@ -4730,9 +4841,9 @@ } }, "node_modules/is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -4825,6 +4936,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/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, + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/is-number-object": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", @@ -4972,6 +5092,12 @@ "node": ">=8" } }, + "node_modules/js-sdsl": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", + "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", + "dev": true + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5186,6 +5312,15 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -5195,6 +5330,19 @@ "node": ">= 0.6" } }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -5241,15 +5389,18 @@ } }, "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/minipass": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.3.tgz", - "integrity": "sha512-N0BOsdFAlNRfmwMhjAsLVWOk7Ljmeb39iqFlsV1At+jqRhSUP9yeof8FyJu4imaJiSUp8vQebWD/guZwGQC8iA==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", + "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", "dev": true, "dependencies": { "yallist": "^4.0.0" @@ -5364,18 +5515,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -5425,9 +5564,9 @@ } }, "node_modules/node-gyp/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -5440,9 +5579,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz", - "integrity": "sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", "dev": true }, "node_modules/nopt": { @@ -5482,9 +5621,9 @@ } }, "node_modules/npm-install-checks/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -5517,9 +5656,9 @@ } }, "node_modules/npm-package-arg/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -5562,9 +5701,9 @@ } }, "node_modules/npm-pick-manifest/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -5651,14 +5790,14 @@ } }, "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, "engines": { @@ -5785,15 +5924,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/pacote": { "version": "11.3.5", "resolved": "https://registry.npmjs.org/pacote/-/pacote-11.3.5.tgz", @@ -5887,6 +6017,15 @@ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -5959,9 +6098,9 @@ } }, "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true }, "node_modules/punycode": { @@ -5982,6 +6121,26 @@ "node": ">=0.6" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -6062,9 +6221,9 @@ "dev": true }, "node_modules/regenerate-unicode-properties": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz", - "integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", + "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", "dev": true, "dependencies": { "regenerate": "^1.4.2" @@ -6074,9 +6233,9 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "version": "0.13.10", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", + "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==", "dev": true }, "node_modules/regenerator-transform": { @@ -6118,15 +6277,15 @@ } }, "node_modules/regexpu-core": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.1.0.tgz", - "integrity": "sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.1.tgz", + "integrity": "sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==", "dev": true, "dependencies": { "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.0.1", - "regjsgen": "^0.6.0", - "regjsparser": "^0.8.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsgen": "^0.7.1", + "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.0.0" }, @@ -6135,15 +6294,15 @@ } }, "node_modules/regjsgen": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz", - "integrity": "sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", + "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", "dev": true }, "node_modules/regjsparser": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz", - "integrity": "sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", "dev": true, "dependencies": { "jsesc": "~0.5.0" @@ -6237,6 +6396,16 @@ "node": ">= 4" } }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -6253,9 +6422,9 @@ } }, "node_modules/rollup": { - "version": "2.75.7", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.7.tgz", - "integrity": "sha512-VSE1iy0eaAYNCxEXaleThdFXqZJ42qDBatAwrfnPlENEZ8erQ+0LYX4JXOLPceWfZpV1VtZwZ3dFCuOZiSyFtQ==", + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -6302,30 +6471,57 @@ } }, "node_modules/rollup-plugin-visualizer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.6.0.tgz", - "integrity": "sha512-CKcc8GTUZjC+LsMytU8ocRr/cGZIfMR7+mdy4YnlyetlmIl/dM8BMnOEpD4JPIGt+ZVW7Db9ZtSsbgyeBH3uTA==", + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.8.2.tgz", + "integrity": "sha512-Fh7KoAa7FVVOojmyyX9ro7fBSR7mPG2cgfDbA877HM4IeJJtSZO+I/R3h/u6TB8wVP5J4pXPpTaRMSREyqCS3g==", "dev": true, "dependencies": { - "nanoid": "^3.1.32", "open": "^8.4.0", - "source-map": "^0.7.3", - "yargs": "^17.3.1" + "source-map": "^0.7.4", + "yargs": "^17.5.1" }, "bin": { "rollup-plugin-visualizer": "dist/bin/cli.js" }, "engines": { - "node": ">=12" + "node": ">=14" }, "peerDependencies": { "rollup": "^2.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" } }, "node_modules/rxjs": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", - "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz", + "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==", "dev": true, "dependencies": { "tslib": "^2.1.0" @@ -6337,6 +6533,20 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -6350,9 +6560,9 @@ "dev": true }, "node_modules/selfsigned": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.0.1.tgz", - "integrity": "sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz", + "integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==", "dev": true, "dependencies": { "node-forge": "^1" @@ -6639,10 +6849,13 @@ } }, "node_modules/shell-quote": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", - "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==", - "dev": true + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", + "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/side-channel": { "version": "1.0.4", @@ -6664,6 +6877,15 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -6675,12 +6897,12 @@ } }, "node_modules/socks": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", - "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", "dev": true, "dependencies": { - "ip": "^1.1.5", + "ip": "^2.0.0", "smart-buffer": "^4.2.0" }, "engines": { @@ -6911,9 +7133,9 @@ } }, "node_modules/terser": { - "version": "5.14.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", - "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", + "version": "5.15.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", + "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.2", @@ -6943,6 +7165,18 @@ "node": ">=4" } }, + "node_modules/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, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -7106,9 +7340,9 @@ } }, "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", - "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true, "engines": { "node": ">=4" @@ -7141,6 +7375,32 @@ "node": ">= 0.8" } }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -7175,12 +7435,6 @@ "uuid": "bin/uuid" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "node_modules/validate-npm-package-name": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", @@ -7319,12 +7573,12 @@ "dev": true }, "node_modules/yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz", + "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==", "dev": true, "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", @@ -7337,9 +7591,9 @@ } }, "node_modules/yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "engines": { "node": ">=12" @@ -7379,27 +7633,27 @@ } }, "@babel/compat-data": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.6.tgz", - "integrity": "sha512-tzulrgDT0QD6U7BJ4TKVk2SDDg7wlP39P9yAx1RfLy7vP/7rsDRlWVfbWxElslu56+r7QOhB2NSDsabYYruoZQ==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.4.tgz", + "integrity": "sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==", "dev": true }, "@babel/core": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.6.tgz", - "integrity": "sha512-cQbWBpxcbbs/IUredIPkHiAGULLV8iwgNRMFzvbhEXISp4f3rUUXE5+TIw6KwUWUR3DwyI6gmBRnmAtYaWehwQ==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", + "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", "dev": true, "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.6", - "@babel/helper-compilation-targets": "^7.18.6", - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helpers": "^7.18.6", - "@babel/parser": "^7.18.6", - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.6", - "@babel/types": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helpers": "^7.19.0", + "@babel/parser": "^7.19.3", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.3", + "@babel/types": "^7.19.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -7408,23 +7662,23 @@ } }, "@babel/eslint-parser": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.18.2.tgz", - "integrity": "sha512-oFQYkE8SuH14+uR51JVAmdqwKYXGRjEXx7s+WiagVjqQ+HPE+nnwyF2qlVG8evUsUHmPcA+6YXMEDbIhEyQc5A==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz", + "integrity": "sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==", "dev": true, "requires": { - "eslint-scope": "^5.1.1", + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", "eslint-visitor-keys": "^2.1.0", "semver": "^6.3.0" } }, "@babel/generator": { - "version": "7.18.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.7.tgz", - "integrity": "sha512-shck+7VLlY72a2w9c3zYWuE1pwOKEiQHV7GTUbSnhyl5eu3i04t30tBY82ZRWrDfo3gkakCFtevExnxbkf2a3A==", + "version": "7.19.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.5.tgz", + "integrity": "sha512-DxbNz9Lz4aMZ99qPpO1raTbcrI1ZeYh+9NR9qhfkQIbFtVEqotHojEBxHzmxhVONkGt6VyrqVQcgpefMy9pqcg==", "dev": true, "requires": { - "@babel/types": "^7.18.7", + "@babel/types": "^7.19.4", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -7452,46 +7706,46 @@ } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.6.tgz", - "integrity": "sha512-KT10c1oWEpmrIRYnthbzHgoOf6B+Xd6a5yhdbNtdhtG7aO1or5HViuf1TQR36xY/QprXA5nvxO6nAjhJ4y38jw==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", + "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", "dev": true, "requires": { "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/types": "^7.18.9" } }, "@babel/helper-compilation-targets": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.6.tgz", - "integrity": "sha512-vFjbfhNCzqdeAtZflUFrG5YIFqGTqsctrtkZ1D/NB0mDW9TwW3GmmUepYY4G9wCET5rY5ugz4OGTcLd614IzQg==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", + "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", "dev": true, "requires": { - "@babel/compat-data": "^7.18.6", + "@babel/compat-data": "^7.19.3", "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.20.2", + "browserslist": "^4.21.3", "semver": "^6.3.0" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.6.tgz", - "integrity": "sha512-YfDzdnoxHGV8CzqHGyCbFvXg5QESPFkXlHtvdCkesLjjVMT2Adxe4FGUR5ChIb3DxSaXO12iIOCWoXdsUVwnqw==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz", + "integrity": "sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.6", - "@babel/helper-function-name": "^7.18.6", - "@babel/helper-member-expression-to-functions": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-member-expression-to-functions": "^7.18.9", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.9", "@babel/helper-split-export-declaration": "^7.18.6" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.18.6.tgz", - "integrity": "sha512-7LcpH1wnQLGrI+4v+nPp+zUvIkF9x0ddv1Hkdue10tg3gmRnLy97DXh4STiOf1qeIInyD69Qv5kKSZzKD8B/7A==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", + "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", @@ -7499,15 +7753,13 @@ } }, "@babel/helper-define-polyfill-provider": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz", - "integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", "dev": true, "requires": { - "@babel/helper-compilation-targets": "^7.13.0", - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/traverse": "^7.13.0", + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2", @@ -7515,9 +7767,9 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.6.tgz", - "integrity": "sha512-8n6gSfn2baOY+qlp+VSzsosjCVGFqWKmDF0cCWOybh52Dw3SEyoWR1KrhMJASjLwIEkkAufZ0xvr+SxLHSpy2Q==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", "dev": true }, "@babel/helper-explode-assignable-expression": { @@ -7530,13 +7782,13 @@ } }, "@babel/helper-function-name": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.6.tgz", - "integrity": "sha512-0mWMxV1aC97dhjCah5U5Ua7668r5ZmSC2DLfH2EZnf9c3/dHZKiFa5pRLMH5tjSl471tY6496ZWk/kjNONBxhw==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "dev": true, "requires": { - "@babel/template": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" } }, "@babel/helper-hoist-variables": { @@ -7549,12 +7801,12 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.6.tgz", - "integrity": "sha512-CeHxqwwipekotzPDUuJOfIMtcIHBuc7WAzLmTYWctVigqS5RktNMQ5bEwQSuGewzYnCtTWa3BARXeiLxDTv+Ng==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", + "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.18.9" } }, "@babel/helper-module-imports": { @@ -7567,19 +7819,19 @@ } }, "@babel/helper-module-transforms": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.6.tgz", - "integrity": "sha512-L//phhB4al5uucwzlimruukHB3jRd5JGClwRMD/ROrVjXfLqovYnvQrK/JK36WYyVwGGO7OD3kMyVTjx+WVPhw==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", + "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", "@babel/helper-simple-access": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" } }, "@babel/helper-optimise-call-expression": { @@ -7592,52 +7844,52 @@ } }, "@babel/helper-plugin-utils": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.6.tgz", - "integrity": "sha512-gvZnm1YAAxh13eJdkb9EWHBnF3eAub3XTLCZEehHT2kWxiKVRL64+ae5Y6Ivne0mVHmMYKT+xWgZO+gQhuLUBg==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", + "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", "dev": true }, "@babel/helper-remap-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.6.tgz", - "integrity": "sha512-z5wbmV55TveUPZlCLZvxWHtrjuJd+8inFhk7DG0WW87/oJuGDcjDiu7HIvGcpf5464L6xKCg3vNkmlVVz9hwyQ==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", + "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.6", - "@babel/helper-wrap-function": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-wrap-function": "^7.18.9", + "@babel/types": "^7.18.9" } }, "@babel/helper-replace-supers": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.18.6.tgz", - "integrity": "sha512-fTf7zoXnUGl9gF25fXCWE26t7Tvtyn6H4hkLSYhATwJvw2uYxd3aoXplMSe0g9XbwK7bmxNes7+FGO0rB/xC0g==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", + "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.18.6", - "@babel/helper-member-expression-to-functions": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/traverse": "^7.19.1", + "@babel/types": "^7.19.0" } }, "@babel/helper-simple-access": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", - "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", + "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.19.4" } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.6.tgz", - "integrity": "sha512-4KoLhwGS9vGethZpAhYnMejWkX64wsnHPDwvOsKWU6Fg4+AlK2Jz3TyjQLMEPvz+1zemi/WBdkYxCD0bAfIkiw==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz", + "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==", "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.18.9" } }, "@babel/helper-split-export-declaration": { @@ -7649,10 +7901,16 @@ "@babel/types": "^7.18.6" } }, + "@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true + }, "@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true }, "@babel/helper-validator-option": { @@ -7662,26 +7920,26 @@ "dev": true }, "@babel/helper-wrap-function": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.18.6.tgz", - "integrity": "sha512-I5/LZfozwMNbwr/b1vhhuYD+J/mU+gfGAj5td7l5Rv9WYmH6i3Om69WGKNmlIpsVW/mF6O5bvTKbvDQZVgjqOw==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", + "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.18.6", - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/helper-function-name": "^7.19.0", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" } }, "@babel/helpers": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.6.tgz", - "integrity": "sha512-vzSiiqbQOghPngUYt/zWGvK3LAsPhz55vc9XNN0xAl2gV4ieShI2OQli5duxWHD+72PZPTKAcfcZDE1Cwc5zsQ==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.4.tgz", + "integrity": "sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==", "dev": true, "requires": { - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.4", + "@babel/types": "^7.19.4" } }, "@babel/highlight": { @@ -7754,9 +8012,9 @@ } }, "@babel/parser": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.6.tgz", - "integrity": "sha512-uQVSa9jJUe/G/304lXspfWVpKpK4euFLgGiMQFOCpM/bgcAdeoHwi/OQz23O9GK2osz26ZiXRRV9aV+Yl1O8tw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.4.tgz", + "integrity": "sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA==", "dev": true }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { @@ -7769,25 +8027,25 @@ } }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.6.tgz", - "integrity": "sha512-Udgu8ZRgrBrttVz6A0EVL0SJ1z+RLbIeqsu632SA1hf0awEppD6TvdznoH+orIF8wtFFAV/Enmw9Y+9oV8TQcw==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", + "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.6" + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-proposal-optional-chaining": "^7.18.9" } }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.6.tgz", - "integrity": "sha512-WAz4R9bvozx4qwf74M+sfqPMKfSqwM0phxPTR6iJIi8robgzXwkEgmeJG1gEKhm6sDqT/U9aV3lfcqybIpev8w==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz", + "integrity": "sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-remap-async-to-generator": "^7.18.9", "@babel/plugin-syntax-async-generators": "^7.8.4" } }, @@ -7823,12 +8081,12 @@ } }, "@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.6.tgz", - "integrity": "sha512-zr/QcUlUo7GPo6+X1wC98NJADqmy5QTFWWhqeQWiki4XHafJtLl/YMGkmRB2szDD2IYJCCdBTd4ElwhId9T7Xw==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", + "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.9", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, @@ -7843,12 +8101,12 @@ } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.6.tgz", - "integrity": "sha512-zMo66azZth/0tVd7gmkxOkOjs2rpHyhpcFo565PUP37hSp6hSd9uUKIfTDFMz58BwqgQKhJ9YxtM5XddjXVn+Q==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", + "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.9", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, @@ -7873,16 +8131,16 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.6.tgz", - "integrity": "sha512-9yuM6wr4rIsKa1wlUAbZEazkCrgw2sMPEXCr4Rnwetu7cEW1NydkCWytLuYletbf8vFxdJxFhwEZqMpOx2eZyw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.19.4.tgz", + "integrity": "sha512-wHmj6LDxVDnL+3WhXteUBaoM1aVILZODAUjg11kHqG4cOlfgMQGxw6aCgvrXrmaJR3Bn14oZhImyCPZzRpC93Q==", "dev": true, "requires": { - "@babel/compat-data": "^7.18.6", - "@babel/helper-compilation-targets": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/compat-data": "^7.19.4", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-plugin-utils": "^7.19.0", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.18.6" + "@babel/plugin-transform-parameters": "^7.18.8" } }, "@babel/plugin-proposal-optional-catch-binding": { @@ -7896,13 +8154,13 @@ } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.6.tgz", - "integrity": "sha512-PatI6elL5eMzoypFAiYDpYQyMtXTn+iMhuxxQt5mAXD4fEmKorpSI3PHd+i3JXBJN3xyA6MvJv7at23HffFHwA==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", + "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, @@ -8103,46 +8361,47 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.6.tgz", - "integrity": "sha512-pRqwb91C42vs1ahSAWJkxOxU1RHWDn16XAa6ggQ72wjLlWyYeAcLvTtE0aM8ph3KNydy9CQF2nLYcjq1WysgxQ==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.19.4.tgz", + "integrity": "sha512-934S2VLLlt2hRJwPf4MczaOr4hYF0z+VKPwqTNxyKX7NthTiPfhuKFWQZHXRM0vh/wo/VyXB3s4bZUNA08l+tQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" } }, "@babel/plugin-transform-classes": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.6.tgz", - "integrity": "sha512-XTg8XW/mKpzAF3actL554Jl/dOYoJtv3l8fxaEczpgz84IeeVf+T1u2CSvPHuZbt0w3JkIx4rdn/MRQI7mo0HQ==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz", + "integrity": "sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.6", - "@babel/helper-function-name": "^7.18.6", + "@babel/helper-compilation-targets": "^7.19.0", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-replace-supers": "^7.18.9", "@babel/helper-split-export-declaration": "^7.18.6", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.6.tgz", - "integrity": "sha512-9repI4BhNrR0KenoR9vm3/cIc1tSBIo+u1WVjKCAynahj25O8zfbiE6JtAtHPGQSs4yZ+bA8mRasRP+qc+2R5A==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", + "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.18.9" } }, "@babel/plugin-transform-destructuring": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.6.tgz", - "integrity": "sha512-tgy3u6lRp17ilY8r1kP4i2+HDUwxlVqq3RTc943eAWSzGgpU1qhiKpqZ5CMyHReIYPHdo3Kg8v8edKtDqSVEyQ==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.19.4.tgz", + "integrity": "sha512-t0j0Hgidqf0aM86dF8U+vXYReUgJnlv4bZLsyoPnwZNrGY+7/38o8YjaELrvHeVfTZao15kjR0PVv0nju2iduA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" } }, "@babel/plugin-transform-dotall-regex": { @@ -8156,12 +8415,12 @@ } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.6.tgz", - "integrity": "sha512-NJU26U/208+sxYszf82nmGYqVF9QN8py2HFTblPT9hbawi8+1C5a9JubODLTGFuT0qlkqVinmkwOD13s0sZktg==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", + "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.18.9" } }, "@babel/plugin-transform-exponentiation-operator": { @@ -8175,32 +8434,32 @@ } }, "@babel/plugin-transform-for-of": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.6.tgz", - "integrity": "sha512-WAjoMf4wIiSsy88KmG7tgj2nFdEK7E46tArVtcgED7Bkj6Fg/tG5SbvNIOKxbFS2VFgNh6+iaPswBeQZm4ox8w==", + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", + "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-transform-function-name": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.6.tgz", - "integrity": "sha512-kJha/Gbs5RjzIu0CxZwf5e3aTTSlhZnHMT8zPWnJMjNpLOUgqevg+PN5oMH68nMCXnfiMo4Bhgxqj59KHTlAnA==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", + "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", "dev": true, "requires": { - "@babel/helper-compilation-targets": "^7.18.6", - "@babel/helper-function-name": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9" } }, "@babel/plugin-transform-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.6.tgz", - "integrity": "sha512-x3HEw0cJZVDoENXOp20HlypIHfl0zMIhMVZEBVTfmqbObIpsMxMbmU5nOEO8R7LYT+z5RORKPlTI5Hj4OsO9/Q==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", + "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.18.9" } }, "@babel/plugin-transform-member-expression-literals": { @@ -8236,14 +8495,14 @@ } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.6.tgz", - "integrity": "sha512-UbPYpXxLjTw6w6yXX2BYNxF3p6QY225wcTkfQCy3OMnSlS/C3xGtwUjEzGkldb/sy6PWLiCQ3NbYfjWUTI3t4g==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz", + "integrity": "sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A==", "dev": true, "requires": { "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helper-plugin-utils": "^7.19.0", "@babel/helper-validator-identifier": "^7.18.6", "babel-plugin-dynamic-import-node": "^2.3.3" } @@ -8259,13 +8518,13 @@ } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.18.6.tgz", - "integrity": "sha512-UmEOGF8XgaIqD74bC8g7iV3RYj8lMf0Bw7NJzvnS9qQhM4mg+1WHKotUIdjxgD2RGrgFLZZPCFPFj3P/kVDYhg==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", + "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.19.0", + "@babel/helper-plugin-utils": "^7.19.0" } }, "@babel/plugin-transform-new-target": { @@ -8288,9 +8547,9 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.6.tgz", - "integrity": "sha512-FjdqgMv37yVl/gwvzkcB+wfjRI8HQmc5EgOG9iGNvUY1ok+TjsoaMP7IqCDZBhkFcM5f3OPVMs6Dmp03C5k4/A==", + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz", + "integrity": "sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6" @@ -8334,13 +8593,13 @@ } }, "@babel/plugin-transform-spread": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.18.6.tgz", - "integrity": "sha512-ayT53rT/ENF8WWexIRg9AiV9h0aIteyWn5ptfZTZQrjk/+f3WdrJGCY4c9wcgl2+MKkKPhzbYp97FTsquZpDCw==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", + "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" } }, "@babel/plugin-transform-sticky-regex": { @@ -8353,30 +8612,30 @@ } }, "@babel/plugin-transform-template-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.6.tgz", - "integrity": "sha512-UuqlRrQmT2SWRvahW46cGSany0uTlcj8NYOS5sRGYi8FxPYPoLd5DDmMd32ZXEj2Jq+06uGVQKHxa/hJx2EzKw==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", + "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.18.9" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.6.tgz", - "integrity": "sha512-7m71iS/QhsPk85xSjFPovHPcH3H9qeyzsujhTc+vcdnsXavoWYJ74zx0lP5RhpC5+iDnVLO+PPMHzC11qels1g==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", + "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.18.9" } }, "@babel/plugin-transform-unicode-escapes": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.6.tgz", - "integrity": "sha512-XNRwQUXYMP7VLuy54cr/KS/WeL3AZeORhrmeZ7iewgu+X2eBqmpaLI/hzqr9ZxCeUoq0ASK4GUzSM0BDhZkLFw==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", + "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.18.9" } }, "@babel/plugin-transform-unicode-regex": { @@ -8390,29 +8649,29 @@ } }, "@babel/preset-env": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.18.6.tgz", - "integrity": "sha512-WrthhuIIYKrEFAwttYzgRNQ5hULGmwTj+D6l7Zdfsv5M7IWV/OZbUfbeL++Qrzx1nVJwWROIFhCHRYQV4xbPNw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.4.tgz", + "integrity": "sha512-5QVOTXUdqTCjQuh2GGtdd7YEhoRXBMVGROAtsBeLGIbIz3obCBIfRMT1I3ZKkMgNzwkyCkftDXSSkHxnfVf4qg==", "dev": true, "requires": { - "@babel/compat-data": "^7.18.6", - "@babel/helper-compilation-targets": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/compat-data": "^7.19.4", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-plugin-utils": "^7.19.0", "@babel/helper-validator-option": "^7.18.6", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.6", - "@babel/plugin-proposal-async-generator-functions": "^7.18.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-async-generator-functions": "^7.19.1", "@babel/plugin-proposal-class-properties": "^7.18.6", "@babel/plugin-proposal-class-static-block": "^7.18.6", "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-proposal-export-namespace-from": "^7.18.6", + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.6", + "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.18.6", + "@babel/plugin-proposal-object-rest-spread": "^7.19.4", "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.6", + "@babel/plugin-proposal-optional-chaining": "^7.18.9", "@babel/plugin-proposal-private-methods": "^7.18.6", "@babel/plugin-proposal-private-property-in-object": "^7.18.6", "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", @@ -8434,41 +8693,41 @@ "@babel/plugin-transform-arrow-functions": "^7.18.6", "@babel/plugin-transform-async-to-generator": "^7.18.6", "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.18.6", - "@babel/plugin-transform-classes": "^7.18.6", - "@babel/plugin-transform-computed-properties": "^7.18.6", - "@babel/plugin-transform-destructuring": "^7.18.6", + "@babel/plugin-transform-block-scoping": "^7.19.4", + "@babel/plugin-transform-classes": "^7.19.0", + "@babel/plugin-transform-computed-properties": "^7.18.9", + "@babel/plugin-transform-destructuring": "^7.19.4", "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-duplicate-keys": "^7.18.6", + "@babel/plugin-transform-duplicate-keys": "^7.18.9", "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.6", - "@babel/plugin-transform-function-name": "^7.18.6", - "@babel/plugin-transform-literals": "^7.18.6", + "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-function-name": "^7.18.9", + "@babel/plugin-transform-literals": "^7.18.9", "@babel/plugin-transform-member-expression-literals": "^7.18.6", "@babel/plugin-transform-modules-amd": "^7.18.6", "@babel/plugin-transform-modules-commonjs": "^7.18.6", - "@babel/plugin-transform-modules-systemjs": "^7.18.6", + "@babel/plugin-transform-modules-systemjs": "^7.19.0", "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.18.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", "@babel/plugin-transform-new-target": "^7.18.6", "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.18.6", + "@babel/plugin-transform-parameters": "^7.18.8", "@babel/plugin-transform-property-literals": "^7.18.6", "@babel/plugin-transform-regenerator": "^7.18.6", "@babel/plugin-transform-reserved-words": "^7.18.6", "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.18.6", + "@babel/plugin-transform-spread": "^7.19.0", "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-transform-template-literals": "^7.18.6", - "@babel/plugin-transform-typeof-symbol": "^7.18.6", - "@babel/plugin-transform-unicode-escapes": "^7.18.6", + "@babel/plugin-transform-template-literals": "^7.18.9", + "@babel/plugin-transform-typeof-symbol": "^7.18.9", + "@babel/plugin-transform-unicode-escapes": "^7.18.10", "@babel/plugin-transform-unicode-regex": "^7.18.6", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.18.6", - "babel-plugin-polyfill-corejs2": "^0.3.1", - "babel-plugin-polyfill-corejs3": "^0.5.2", - "babel-plugin-polyfill-regenerator": "^0.3.1", - "core-js-compat": "^3.22.1", + "@babel/types": "^7.19.4", + "babel-plugin-polyfill-corejs2": "^0.3.3", + "babel-plugin-polyfill-corejs3": "^0.6.0", + "babel-plugin-polyfill-regenerator": "^0.4.1", + "core-js-compat": "^3.25.1", "semver": "^6.3.0" } }, @@ -8486,62 +8745,63 @@ } }, "@babel/runtime": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz", - "integrity": "sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.4.tgz", + "integrity": "sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" } }, "@babel/template": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.6.tgz", - "integrity": "sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dev": true, "requires": { "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" } }, "@babel/traverse": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.6.tgz", - "integrity": "sha512-zS/OKyqmD7lslOtFqbscH6gMLFYOfG1YPqCKfAW5KrTeolKqvB8UelR49Fpr6y93kYkW2Ik00mT1LOGiAGvizw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.4.tgz", + "integrity": "sha512-w3K1i+V5u2aJUOXBFFC5pveFLmtq1s3qcdDNC2qRI6WPBQIDaKFqXxDEqDO/h1dQ3HjsZoZMyIy6jGLq0xtw+g==", "dev": true, "requires": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.6", - "@babel/helper-function-name": "^7.18.6", + "@babel/generator": "^7.19.4", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.18.6", - "@babel/types": "^7.18.6", + "@babel/parser": "^7.19.4", + "@babel/types": "^7.19.4", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.18.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.7.tgz", - "integrity": "sha512-QG3yxTcTIBoAcQmkCs+wAPYZhu7Dk9rXKacINfNbdJDNERTbLQbHGyVG8q/YGMPeCJRIhSY0+fTc5+xuh6WPSQ==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" } }, "@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.2", + "espree": "^9.4.0", "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -8551,9 +8811,9 @@ }, "dependencies": { "globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -8568,9 +8828,9 @@ "dev": true }, "@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", + "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -8578,6 +8838,12 @@ "minimatch": "^3.0.4" } }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, "@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -8595,15 +8861,15 @@ } }, "@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true }, "@jridgewell/set-array": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", - "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true }, "@jridgewell/source-map": { @@ -8617,12 +8883,12 @@ }, "dependencies": { "@jridgewell/gen-mapping": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", - "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "dev": true, "requires": { - "@jridgewell/set-array": "^1.0.0", + "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" } @@ -8630,19 +8896,19 @@ } }, "@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", - "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "@mdn/browser-compat-data": { @@ -8651,6 +8917,41 @@ "integrity": "sha512-EWUguj2kd7ldmrF9F+vI5hUOralPd+sdsUnYbRy33vZTuZkduC1shE9TtEMEjAQwyfyMb4ole5KtjF8MsnQOlA==", "dev": true }, + "@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "dev": true, + "requires": { + "eslint-scope": "5.1.1" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, "@npmcli/fs": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", @@ -8662,9 +8963,9 @@ }, "dependencies": { "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -8689,9 +8990,9 @@ }, "dependencies": { "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -8757,9 +9058,9 @@ } }, "@rollup/plugin-node-resolve": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.3.0.tgz", - "integrity": "sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-14.1.0.tgz", + "integrity": "sha512-5G2niJroNCz/1zqwXtk0t9+twOSDlG00k1Wfd7bkbbXmwg8H8dvgHdIWAun53Ps/rckfvOC7scDBjuGFg5OaWw==", "dev": true, "requires": { "@rollup/pluginutils": "^3.1.0", @@ -8800,9 +9101,9 @@ "dev": true }, "@types/node": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.0.tgz", - "integrity": "sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==", + "version": "18.8.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.5.tgz", + "integrity": "sha512-Bq7G3AErwe5A/Zki5fdD3O6+0zDChhg671NfPjtIcbtzDNZTv4NPKMRFr7gtYPG7y+B8uTiNK4Ngd9T0FTar6Q==", "dev": true }, "@types/resolve": { @@ -8831,9 +9132,9 @@ } }, "acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "dev": true }, "acorn-jsx": { @@ -8956,6 +9257,12 @@ "is-string": "^1.0.7" } }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, "array.prototype.flat": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", @@ -9028,33 +9335,33 @@ } }, "babel-plugin-polyfill-corejs2": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz", - "integrity": "sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", "dev": true, "requires": { - "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.3.1", + "@babel/compat-data": "^7.17.7", + "@babel/helper-define-polyfill-provider": "^0.3.3", "semver": "^6.1.1" } }, "babel-plugin-polyfill-corejs3": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz", - "integrity": "sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", + "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", "dev": true, "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.1", - "core-js-compat": "^3.21.0" + "@babel/helper-define-polyfill-provider": "^0.3.3", + "core-js-compat": "^3.25.1" } }, "babel-plugin-polyfill-regenerator": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz", - "integrity": "sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", "dev": true, "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.1" + "@babel/helper-define-polyfill-provider": "^0.3.3" } }, "balanced-match": { @@ -9088,9 +9395,9 @@ } }, "body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dev": true, "requires": { "bytes": "3.1.2", @@ -9101,7 +9408,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.10.3", + "qs": "6.11.0", "raw-body": "2.5.1", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -9138,9 +9445,9 @@ "dev": true }, "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, "requires": { "side-channel": "^1.0.4" @@ -9195,6 +9502,15 @@ "concat-map": "0.0.1" } }, + "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": { + "fill-range": "^7.0.1" + } + }, "brotli-size": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/brotli-size/-/brotli-size-4.0.0.tgz", @@ -9205,16 +9521,15 @@ } }, "browserslist": { - "version": "4.20.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.4.tgz", - "integrity": "sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==", + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001349", - "electron-to-chromium": "^1.4.147", - "escalade": "^3.1.1", - "node-releases": "^2.0.5", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" } }, "buffer-from": { @@ -9290,9 +9605,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001357", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001357.tgz", - "integrity": "sha512-b+KbWHdHePp+ZpNj+RDHFChZmuN+J5EvuQUlee9jOQIUAdhv9uvAZeEtUeLAknXbkiu1uxjQ9NLp1ie894CuWg==", + "version": "1.0.30001419", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001419.tgz", + "integrity": "sha512-aFO1r+g6R7TW+PNQxKzjITwLOyDhVRLjW0LcwS/HCZGUUKTGNp9+IwLC4xyDSZBygVL/mxaFR3HIV6wEKQuSzw==", "dev": true }, "caseless": { @@ -9302,9 +9617,9 @@ "dev": true }, "chalk": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", - "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.1.2.tgz", + "integrity": "sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==", "dev": true }, "chownr": { @@ -9326,13 +9641,13 @@ "dev": true }, "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "requires": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, @@ -9391,13 +9706,13 @@ "dev": true }, "concurrently": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.2.2.tgz", - "integrity": "sha512-DcQkI0ruil5BA/g7Xy3EWySGrFJovF5RYAYxwGvv9Jf9q9B1v3jPFP2tl6axExNf1qgF30kjoNYrangZ0ey4Aw==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.4.0.tgz", + "integrity": "sha512-M6AfrueDt/GEna/Vg9BqQ+93yuvzkSKmoTixnwEJkH0LlcGrRC2eCmjeG1tLLHIYfpYJABokqSGyMcXjm96AFA==", "dev": true, "requires": { "chalk": "^4.1.0", - "date-fns": "^2.16.1", + "date-fns": "^2.29.1", "lodash": "^4.17.21", "rxjs": "^7.0.0", "shell-quote": "^1.7.3", @@ -9460,13 +9775,10 @@ "dev": true }, "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true }, "cookie": { "version": "0.5.0", @@ -9481,27 +9793,18 @@ "dev": true }, "core-js": { - "version": "3.23.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.23.2.tgz", - "integrity": "sha512-ELJOWxNrJfOH/WK4VJ3Qd+fOqZuOuDNDJz0xG6Bt4mGg2eO/UT9CljCrbqDGovjLKUrGajEEBcoTOc0w+yBYeQ==", + "version": "3.25.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.25.5.tgz", + "integrity": "sha512-nbm6eZSjm+ZuBQxCUPQKQCoUEfFOXjUZ8dTTyikyKaWrTYmAVbykQfwsKE5dBK88u3QCkCrzsx/PPlKfhsvgpw==", "dev": true }, "core-js-compat": { - "version": "3.23.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.23.2.tgz", - "integrity": "sha512-lrgZvxFwbQp9v7E8mX0rJ+JX7Bvh4eGULZXA1IAyjlsnWvCdw6TF8Tg6xtaSUSJMrSrMaLdpmk+V54LM1dvfOA==", + "version": "3.25.5", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.5.tgz", + "integrity": "sha512-ovcyhs2DEBUIE0MGEKHP4olCUW/XYte3Vroyxuh38rD1wAO4dHohsovUC4eAOuzFxE6b+RXvBU3UZ9o0YhUTkA==", "dev": true, "requires": { - "browserslist": "^4.20.4", - "semver": "7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true - } + "browserslist": "^4.21.4" } }, "core-util-is": { @@ -9541,9 +9844,9 @@ } }, "date-fns": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", - "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==", + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==", "dev": true }, "debug": { @@ -9607,6 +9910,15 @@ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -9617,22 +9929,14 @@ } }, "dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "dependencies": { - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true - } + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" } }, "domelementtype": { @@ -9642,23 +9946,23 @@ "dev": true }, "domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, "requires": { - "domelementtype": "^2.2.0" + "domelementtype": "^2.3.0" } }, "domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", + "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", "dev": true, "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.1" } }, "duplexer": { @@ -9684,9 +9988,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.4.163", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.163.tgz", - "integrity": "sha512-c9q94pUVqIdc8hyr7jZDB4bNEoNF3QJ7y35lnddMD+mXtiv5GsL1bT/RmfW/KEOmvlNg5Oy1qioiy4tA7e864Q==", + "version": "1.4.282", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.282.tgz", + "integrity": "sha512-Dki0WhHNh/br/Xi1vAkueU5mtIc9XLHcMKB6tNfQKk+kPG0TEUjRh5QEMAUbRp30/rYNMFD1zKKvbVzwq/4wmg==", "dev": true }, "emoji-regex": { @@ -9712,9 +10016,9 @@ } }, "entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", "dev": true }, "env-paths": { @@ -9730,31 +10034,32 @@ "dev": true }, "es-abstract": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", - "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", + "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", "dev": true, "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.1", + "get-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", "has": "^1.0.3", "has-property-descriptors": "^1.0.0", "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", + "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", + "object-inspect": "^1.12.2", "object-keys": "^1.1.1", - "object.assign": "^4.1.2", + "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", "string.prototype.trimend": "^1.0.5", "string.prototype.trimstart": "^1.0.5", "unbox-primitive": "^1.0.2" @@ -9799,13 +10104,14 @@ "dev": true }, "eslint": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.18.0.tgz", - "integrity": "sha512-As1EfFMVk7Xc6/CvhssHUjsAQSkpfXvUGMFC3ce8JDe6WvqCgRrLOBQbVpsBFr1X1V+RACOadnzVvcUS5ni2bA==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.25.0.tgz", + "integrity": "sha512-DVlJOZ4Pn50zcKW5bYH7GQK/9MsoQG2d5eDH0ebEkE8PbgzTTmtt/VTH9GGJ4BfeZCpBLqFfvsjX35UacUL83A==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.9.2", + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.10.5", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -9815,18 +10121,21 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", + "find-up": "^5.0.0", "glob-parent": "^6.0.1", "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -9837,8 +10146,7 @@ "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "dependencies": { "chalk": { @@ -9874,9 +10182,9 @@ "dev": true }, "globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -9921,13 +10229,12 @@ } }, "eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", "dev": true, "requires": { - "debug": "^3.2.7", - "find-up": "^2.1.0" + "debug": "^3.2.7" }, "dependencies": { "debug": { @@ -9938,49 +10245,6 @@ "requires": { "ms": "^2.1.1" } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true } } }, @@ -10012,12 +10276,12 @@ } }, "eslint-plugin-html": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-6.2.0.tgz", - "integrity": "sha512-vi3NW0E8AJombTvt8beMwkL1R/fdRWl4QSNRNMhVQKWm36/X0KF0unGNAY4mqUF06mnwVWZcIcerrCnfn9025g==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-7.1.0.tgz", + "integrity": "sha512-fNLRraV/e6j8e3XYOC9xgND4j+U7b1Rq+OygMlLcMg+wI/IpVbF+ubQa3R78EjKB9njT6TQOlcK5rFKBVVtdfg==", "dev": true, "requires": { - "htmlparser2": "^7.1.2" + "htmlparser2": "^8.0.1" } }, "eslint-plugin-import": { @@ -10093,12 +10357,12 @@ "dev": true }, "espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "requires": { - "acorn": "^8.7.1", + "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" }, @@ -10170,14 +10434,14 @@ "dev": true }, "express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dev": true, "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.0", + "body-parser": "1.20.1", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.5.0", @@ -10196,7 +10460,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.10.3", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.18.0", @@ -10230,9 +10494,9 @@ "dev": true }, "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, "requires": { "side-channel": "^1.0.4" @@ -10264,6 +10528,30 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -10276,6 +10564,15 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -10291,6 +10588,15 @@ "integrity": "sha512-mjFIpOHC4jbfcTfoh4rkWpI31mF7viw9ikj/JyLoKzqlwG/YsefKfvYlYhdYdg/9mtK2z1AzgN/0LvVQ3zdlSQ==", "dev": true }, + "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": { + "to-regex-range": "^5.0.1" + } + }, "finalhandler": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", @@ -10344,9 +10650,9 @@ } }, "flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, "forever-agent": { @@ -10418,12 +10724,6 @@ "functions-have-names": "^1.2.2" } }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, "functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -10496,9 +10796,9 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "dev": true, "requires": { "function-bind": "^1.1.1", @@ -10554,12 +10854,32 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "gzip-size": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", @@ -10654,15 +10974,15 @@ } }, "htmlparser2": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", - "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", + "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", "dev": true, "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.2", - "domutils": "^2.8.0", - "entities": "^3.0.1" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "entities": "^4.3.0" } }, "http-cache-semantics": { @@ -10814,9 +11134,9 @@ } }, "ip": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", "dev": true }, "ipaddr.js": { @@ -10845,24 +11165,24 @@ } }, "is-builtin-module": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz", - "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz", + "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==", "dev": true, "requires": { - "builtin-modules": "^3.0.0" + "builtin-modules": "^3.3.0" } }, "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true }, "is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", "dev": true, "requires": { "has": "^1.0.3" @@ -10922,6 +11242,12 @@ "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true }, + "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 + }, "is-number-object": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", @@ -11032,6 +11358,12 @@ } } }, + "js-sdsl": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", + "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -11207,12 +11539,28 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -11244,15 +11592,15 @@ } }, "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", "dev": true }, "minipass": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.3.tgz", - "integrity": "sha512-N0BOsdFAlNRfmwMhjAsLVWOk7Ljmeb39iqFlsV1At+jqRhSUP9yeof8FyJu4imaJiSUp8vQebWD/guZwGQC8iA==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", + "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", "dev": true, "requires": { "yallist": "^4.0.0" @@ -11338,12 +11686,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", - "dev": true - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -11381,9 +11723,9 @@ }, "dependencies": { "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -11392,9 +11734,9 @@ } }, "node-releases": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz", - "integrity": "sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", "dev": true }, "nopt": { @@ -11425,9 +11767,9 @@ }, "dependencies": { "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -11453,9 +11795,9 @@ }, "dependencies": { "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -11488,9 +11830,9 @@ }, "dependencies": { "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -11555,14 +11897,14 @@ "dev": true }, "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dev": true, "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", "object-keys": "^1.1.1" } }, @@ -11647,12 +11989,6 @@ "aggregate-error": "^3.0.0" } }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true - }, "pacote": { "version": "11.3.5", "resolved": "https://registry.npmjs.org/pacote/-/pacote-11.3.5.tgz", @@ -11725,6 +12061,12 @@ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -11782,9 +12124,9 @@ } }, "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true }, "punycode": { @@ -11799,6 +12141,12 @@ "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -11869,18 +12217,18 @@ "dev": true }, "regenerate-unicode-properties": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz", - "integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", + "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", "dev": true, "requires": { "regenerate": "^1.4.2" } }, "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "version": "0.13.10", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", + "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==", "dev": true }, "regenerator-transform": { @@ -11910,29 +12258,29 @@ "dev": true }, "regexpu-core": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.1.0.tgz", - "integrity": "sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.1.tgz", + "integrity": "sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==", "dev": true, "requires": { "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.0.1", - "regjsgen": "^0.6.0", - "regjsparser": "^0.8.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsgen": "^0.7.1", + "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.0.0" } }, "regjsgen": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz", - "integrity": "sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", + "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", "dev": true }, "regjsparser": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz", - "integrity": "sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -12003,6 +12351,12 @@ "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "dev": true }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -12013,9 +12367,9 @@ } }, "rollup": { - "version": "2.75.7", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.7.tgz", - "integrity": "sha512-VSE1iy0eaAYNCxEXaleThdFXqZJ42qDBatAwrfnPlENEZ8erQ+0LYX4JXOLPceWfZpV1VtZwZ3dFCuOZiSyFtQ==", + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "dev": true, "requires": { "fsevents": "~2.3.2" @@ -12050,21 +12404,29 @@ } }, "rollup-plugin-visualizer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.6.0.tgz", - "integrity": "sha512-CKcc8GTUZjC+LsMytU8ocRr/cGZIfMR7+mdy4YnlyetlmIl/dM8BMnOEpD4JPIGt+ZVW7Db9ZtSsbgyeBH3uTA==", + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.8.2.tgz", + "integrity": "sha512-Fh7KoAa7FVVOojmyyX9ro7fBSR7mPG2cgfDbA877HM4IeJJtSZO+I/R3h/u6TB8wVP5J4pXPpTaRMSREyqCS3g==", "dev": true, "requires": { - "nanoid": "^3.1.32", "open": "^8.4.0", - "source-map": "^0.7.3", - "yargs": "^17.3.1" + "source-map": "^0.7.4", + "yargs": "^17.5.1" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" } }, "rxjs": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", - "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz", + "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==", "dev": true, "requires": { "tslib": "^2.1.0" @@ -12076,6 +12438,17 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -12089,9 +12462,9 @@ "dev": true }, "selfsigned": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.0.1.tgz", - "integrity": "sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz", + "integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==", "dev": true, "requires": { "node-forge": "^1" @@ -12341,9 +12714,9 @@ "dev": true }, "shell-quote": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", - "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", + "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==", "dev": true }, "side-channel": { @@ -12363,6 +12736,12 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, "smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -12370,12 +12749,12 @@ "dev": true }, "socks": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", - "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", "dev": true, "requires": { - "ip": "^1.1.5", + "ip": "^2.0.0", "smart-buffer": "^4.2.0" } }, @@ -12545,9 +12924,9 @@ } }, "terser": { - "version": "5.14.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", - "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", + "version": "5.15.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", + "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", "dev": true, "requires": { "@jridgewell/source-map": "^0.3.2", @@ -12568,6 +12947,15 @@ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true }, + "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": { + "is-number": "^7.0.0" + } + }, "toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -12694,9 +13082,9 @@ "dev": true }, "unicode-property-aliases-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", - "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true }, "unique-filename": { @@ -12723,6 +13111,16 @@ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true }, + "update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -12750,12 +13148,6 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "validate-npm-package-name": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", @@ -12866,12 +13258,12 @@ "dev": true }, "yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz", + "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==", "dev": true, "requires": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", @@ -12881,9 +13273,9 @@ } }, "yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true }, "yocto-queue": { diff --git a/package.json b/package.json index 74e8b3c34a273c..c81587d316ad35 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "three", - "version": "0.143.0", + "version": "0.147.0", "description": "JavaScript 3D library", "type": "module", "main": "./build/three.js", @@ -12,7 +12,9 @@ }, "./examples/fonts/*": "./examples/fonts/*", "./examples/jsm/*": "./examples/jsm/*", - "./src/*": "./src/*" + "./addons/*": "./examples/jsm/*", + "./src/*": "./src/*", + "./nodes": "./examples/jsm/nodes/Nodes.js" }, "repository": { "type": "git", @@ -63,7 +65,6 @@ "WebGL2ComputeRenderingContext": "readonly", "potpack": "readonly", "fflate": "readonly", - "bodymovin": "readonly", "OIMO": "readonly", "Stats": "readonly", "XRWebGLBinding": "readonly", @@ -71,7 +72,10 @@ "GPUShaderStage": "readonly", "GPUBufferUsage": "readonly", "GPUTextureUsage": "readonly", - "QUnit": "readonly" + "QUnit": "readonly", + "Ammo":"readonly", + "XRRigidTransform":"readonly", + "XRMediaBinding":"readonly" }, "rules": { "no-throw-literal": [ @@ -101,11 +105,11 @@ "start": "npm run dev", "test": "npm run lint && npm run test-unit", "build": "rollup -c utils/build/rollup.config.js", - "build-module": "ONLY_MODULE=true rollup -c utils/build/rollup.config.js", + "build-module": "rollup -c utils/build/rollup.config.js --configOnlyModule", "build-examples": "rollup -c utils/build/rollup.examples.config.js && echo '\nFormatting...' && eslint examples/js --ext js --ignore-pattern libs --ignore-pattern ifc --fix", - "dev": "concurrently --names \"ROLLUP,HTTP\" -c \"bgBlue.bold,bgGreen.bold\" \"rollup -c utils/build/rollup.config.js -w -m inline\" \"servez -p 8080\"", + "dev": "concurrently --names \"ROLLUP,HTTP\" -c \"bgBlue.bold,bgGreen.bold\" \"rollup -c utils/build/rollup.config.js -w -m inline\" \"servez -p 8080 --ssl\"", "lint": "eslint src --ext js", - "lint-examples": "eslint examples/js examples/jsm --ext js --ignore-pattern libs --ignore-pattern ifc", + "lint-examples": "eslint examples/js examples/jsm examples/*.html --ext js,html --ignore-pattern libs --ignore-pattern ifc", "lint-docs": "eslint docs --ext html", "lint-fix": "npm run lint -- --fix && npm run lint-examples -- --fix && npm run lint-docs -- --fix", "test-unit": "npm run unit --prefix test", @@ -137,23 +141,23 @@ }, "homepage": "https://threejs.org/", "devDependencies": { - "@babel/core": "^7.18.6", - "@babel/eslint-parser": "^7.18.2", + "@babel/core": "^7.19.3", + "@babel/eslint-parser": "^7.19.1", "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/preset-env": "^7.18.6", + "@babel/preset-env": "^7.19.3", "@rollup/plugin-babel": "^5.3.1", - "@rollup/plugin-node-resolve": "^13.3.0", + "@rollup/plugin-node-resolve": "^14.1.0", "chalk": "^5.0.1", - "concurrently": "^7.2.2", - "eslint": "^8.18.0", + "concurrently": "^7.4.0", + "eslint": "^8.24.0", "eslint-config-mdcs": "^5.0.0", "eslint-plugin-compat": "^4.0.2", - "eslint-plugin-html": "^6.2.0", + "eslint-plugin-html": "^7.1.0", "eslint-plugin-import": "^2.26.0", - "rollup": "^2.75.7", + "rollup": "^2.79.1", "rollup-plugin-filesize": "^9.1.2", "rollup-plugin-terser": "^7.0.2", - "rollup-plugin-visualizer": "^5.6.0", + "rollup-plugin-visualizer": "^5.8.2", "servez": "^1.14.1" }, "jspm": { diff --git a/src/Three.Legacy.js b/src/Three.Legacy.js index 5ca704d00de0c6..336f55bd848ad9 100644 --- a/src/Three.Legacy.js +++ b/src/Three.Legacy.js @@ -1,94 +1,320 @@ -import { BufferGeometry } from './core/BufferGeometry.js'; import { WebGLRenderTarget } from './renderers/WebGLRenderTarget.js'; import { DataArrayTexture } from './textures/DataArrayTexture.js'; import { Data3DTexture } from './textures/Data3DTexture.js'; +import { BoxGeometry } from './geometries/BoxGeometry.js'; +import { CapsuleGeometry } from './geometries/CapsuleGeometry.js'; +import { CircleGeometry } from './geometries/CircleGeometry.js'; +import { ConeGeometry } from './geometries/ConeGeometry.js'; +import { CylinderGeometry } from './geometries/CylinderGeometry.js'; +import { DodecahedronGeometry } from './geometries/DodecahedronGeometry.js'; +import { ExtrudeGeometry } from './geometries/ExtrudeGeometry.js'; +import { IcosahedronGeometry } from './geometries/IcosahedronGeometry.js'; +import { LatheGeometry } from './geometries/LatheGeometry.js'; +import { OctahedronGeometry } from './geometries/OctahedronGeometry.js'; +import { PlaneGeometry } from './geometries/PlaneGeometry.js'; +import { PolyhedronGeometry } from './geometries/PolyhedronGeometry.js'; +import { RingGeometry } from './geometries/RingGeometry.js'; +import { ShapeGeometry } from './geometries/ShapeGeometry.js'; +import { SphereGeometry } from './geometries/SphereGeometry.js'; +import { TetrahedronGeometry } from './geometries/TetrahedronGeometry.js'; +import { TorusGeometry } from './geometries/TorusGeometry.js'; +import { TorusKnotGeometry } from './geometries/TorusKnotGeometry.js'; +import { TubeGeometry } from './geometries/TubeGeometry.js'; -// r133, c5bb5434555a3c3ddd784944a0a124f996fc721b +// r134, d65e0af06644fe5a84a6fc0e372f4318f95a04c0 + +export function ImmediateRenderObject() { -export class ParametricGeometry extends BufferGeometry { + console.error( 'THREE.ImmediateRenderObject has been removed.' ); - constructor() { +} - console.error( 'THREE.ParametricGeometry has been moved to /examples/jsm/geometries/ParametricGeometry.js' ); - super(); +// r138, 48b05d3500acc084df50be9b4c90781ad9b8cb17 + +export class WebGLMultisampleRenderTarget extends WebGLRenderTarget { + + constructor( width, height, options ) { + + console.error( 'THREE.WebGLMultisampleRenderTarget has been removed. Use a normal render target and set the "samples" property to greater 0 to enable multisampling.' ); + super( width, height, options ); + this.samples = 4; } } -// r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 +// r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce -export class TextGeometry extends BufferGeometry { +export class DataTexture2DArray extends DataArrayTexture { - constructor() { + constructor( data, width, height, depth ) { - console.error( 'THREE.TextGeometry has been moved to /examples/jsm/geometries/TextGeometry.js' ); - super(); + console.warn( 'THREE.DataTexture2DArray has been renamed to DataArrayTexture.' ); + super( data, width, height, depth ); } } -// r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 +// r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce + +export class DataTexture3D extends Data3DTexture { + + constructor( data, width, height, depth ) { -export function FontLoader() { + console.warn( 'THREE.DataTexture3D has been renamed to Data3DTexture.' ); + super( data, width, height, depth ); - console.error( 'THREE.FontLoader has been moved to /examples/jsm/loaders/FontLoader.js' ); + } } -// r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 +// r144 -export function Font() { +export class BoxBufferGeometry extends BoxGeometry { - console.error( 'THREE.Font has been moved to /examples/jsm/loaders/FontLoader.js' ); + constructor( width, height, depth, widthSegments, heightSegments, depthSegments ) { + + console.warn( 'THREE.BoxBufferGeometry has been renamed to THREE.BoxGeometry.' ); + super( width, height, depth, widthSegments, heightSegments, depthSegments ); + + + } } -// r134, d65e0af06644fe5a84a6fc0e372f4318f95a04c0 +// r144 -export function ImmediateRenderObject() { +export class CapsuleBufferGeometry extends CapsuleGeometry { - console.error( 'THREE.ImmediateRenderObject has been removed.' ); + constructor( radius, length, capSegments, radialSegments ) { + + console.warn( 'THREE.CapsuleBufferGeometry has been renamed to THREE.CapsuleGeometry.' ); + super( radius, length, capSegments, radialSegments ); + + } } -// r138, 48b05d3500acc084df50be9b4c90781ad9b8cb17 +// r144 -export class WebGLMultisampleRenderTarget extends WebGLRenderTarget { +export class CircleBufferGeometry extends CircleGeometry { - constructor( width, height, options ) { + constructor( radius, segments, thetaStart, thetaLength ) { - console.error( 'THREE.WebGLMultisampleRenderTarget has been removed. Use a normal render target and set the "samples" property to greater 0 to enable multisampling.' ); - super( width, height, options ); - this.samples = 4; + console.warn( 'THREE.CircleBufferGeometry has been renamed to THREE.CircleGeometry.' ); + super( radius, segments, thetaStart, thetaLength ); } } -// r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce +// r144 -export class DataTexture2DArray extends DataArrayTexture { +export class ConeBufferGeometry extends ConeGeometry { - constructor( data, width, height, depth ) { + constructor( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { - console.warn( 'THREE.DataTexture2DArray has been renamed to DataArrayTexture.' ); - super( data, width, height, depth ); + console.warn( 'THREE.ConeBufferGeometry has been renamed to THREE.ConeGeometry.' ); + super( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ); } } -// r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce +// r144 -export class DataTexture3D extends Data3DTexture { +export class CylinderBufferGeometry extends CylinderGeometry { - constructor( data, width, height, depth ) { + constructor( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { - console.warn( 'THREE.DataTexture3D has been renamed to Data3DTexture.' ); - super( data, width, height, depth ); + console.warn( 'THREE.CylinderBufferGeometry has been renamed to THREE.CylinderGeometry.' ); + super( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ); + + } + +} + +// r144 + +export class DodecahedronBufferGeometry extends DodecahedronGeometry { + + constructor( radius, detail ) { + + console.warn( 'THREE.DodecahedronBufferGeometry has been renamed to THREE.DodecahedronGeometry.' ); + super( radius, detail ); + + } + +} + +// r144 + +export class ExtrudeBufferGeometry extends ExtrudeGeometry { + + constructor( shapes, options ) { + + console.warn( 'THREE.ExtrudeBufferGeometry has been renamed to THREE.ExtrudeGeometry.' ); + super( shapes, options ); } } + +// r144 + +export class IcosahedronBufferGeometry extends IcosahedronGeometry { + + constructor( radius, detail ) { + + console.warn( 'THREE.IcosahedronBufferGeometry has been renamed to THREE.IcosahedronGeometry.' ); + super( radius, detail ); + + } + +} + +// r144 + +export class LatheBufferGeometry extends LatheGeometry { + + constructor( points, segments, phiStart, phiLength ) { + + console.warn( 'THREE.LatheBufferGeometry has been renamed to THREE.LatheGeometry.' ); + super( points, segments, phiStart, phiLength ); + + } + +} + +// r144 + +export class OctahedronBufferGeometry extends OctahedronGeometry { + + constructor( radius, detail ) { + + console.warn( 'THREE.OctahedronBufferGeometry has been renamed to THREE.OctahedronGeometry.' ); + super( radius, detail ); + + } + +} + +// r144 + +export class PlaneBufferGeometry extends PlaneGeometry { + + constructor( width, height, widthSegments, heightSegments ) { + + console.warn( 'THREE.PlaneBufferGeometry has been renamed to THREE.PlaneGeometry.' ); + super( width, height, widthSegments, heightSegments ); + + } + +} + +// r144 + +export class PolyhedronBufferGeometry extends PolyhedronGeometry { + + constructor( vertices, indices, radius, detail ) { + + console.warn( 'THREE.PolyhedronBufferGeometry has been renamed to THREE.PolyhedronGeometry.' ); + super( vertices, indices, radius, detail ); + + } + +} + +// r144 + +export class RingBufferGeometry extends RingGeometry { + + constructor( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) { + + console.warn( 'THREE.RingBufferGeometry has been renamed to THREE.RingGeometry.' ); + super( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ); + + } + +} + +// r144 + +export class ShapeBufferGeometry extends ShapeGeometry { + + constructor( shapes, curveSegments ) { + + console.warn( 'THREE.ShapeBufferGeometry has been renamed to THREE.ShapeGeometry.' ); + super( shapes, curveSegments ); + + } + +} + +// r144 + +export class SphereBufferGeometry extends SphereGeometry { + + constructor( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) { + + console.warn( 'THREE.SphereBufferGeometry has been renamed to THREE.SphereGeometry.' ); + super( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ); + + } + +} + +// r144 + +export class TetrahedronBufferGeometry extends TetrahedronGeometry { + + constructor( radius, detail ) { + + console.warn( 'THREE.TetrahedronBufferGeometry has been renamed to THREE.TetrahedronGeometry.' ); + super( radius, detail ); + + } + +} + +// r144 + +export class TorusBufferGeometry extends TorusGeometry { + + constructor( radius, tube, radialSegments, tubularSegments, arc ) { + + console.warn( 'THREE.TorusBufferGeometry has been renamed to THREE.TorusGeometry.' ); + super( radius, tube, radialSegments, tubularSegments, arc ); + + } + +} + +// r144 + +export class TorusKnotBufferGeometry extends TorusKnotGeometry { + + constructor( radius, tube, tubularSegments, radialSegments, p, q ) { + + console.warn( 'THREE.TorusKnotBufferGeometry has been renamed to THREE.TorusKnotGeometry.' ); + super( radius, tube, tubularSegments, radialSegments, p, q ); + + } + +} + +// r144 + +export class TubeBufferGeometry extends TubeGeometry { + + constructor( path, tubularSegments, radius, radialSegments, closed ) { + + console.warn( 'THREE.TubeBufferGeometry has been renamed to THREE.TubeGeometry.' ); + super( path, tubularSegments, radius, radialSegments, closed ); + + } + +} + + diff --git a/src/Three.js b/src/Three.js index 372352c7f91e24..8254f9a36f7038 100644 --- a/src/Three.js +++ b/src/Three.js @@ -33,6 +33,7 @@ export { DataTexture } from './textures/DataTexture.js'; export { DataArrayTexture } from './textures/DataArrayTexture.js'; export { Data3DTexture } from './textures/Data3DTexture.js'; export { CompressedTexture } from './textures/CompressedTexture.js'; +export { CompressedArrayTexture } from './textures/CompressedArrayTexture.js'; export { CubeTexture } from './textures/CubeTexture.js'; export { CanvasTexture } from './textures/CanvasTexture.js'; export { DepthTexture } from './textures/DepthTexture.js'; diff --git a/src/animation/AnimationAction.js b/src/animation/AnimationAction.js index b2b6b691195a1c..056297b26f9817 100644 --- a/src/animation/AnimationAction.js +++ b/src/animation/AnimationAction.js @@ -340,14 +340,15 @@ class AnimationAction { const timeRunning = ( time - startTime ) * timeDirection; if ( timeRunning < 0 || timeDirection === 0 ) { - return; // yet to come / don't decide when delta = 0 + deltaTime = 0; - } + } else { - // start - this._startTime = null; // unschedule - deltaTime = timeDirection * timeRunning; + this._startTime = null; // unschedule + deltaTime = timeDirection * timeRunning; + + } } diff --git a/src/animation/PropertyBinding.js b/src/animation/PropertyBinding.js index 862ba5cf9dadc7..9d23101c263181 100644 --- a/src/animation/PropertyBinding.js +++ b/src/animation/PropertyBinding.js @@ -32,7 +32,7 @@ const _trackRe = new RegExp( '' + '$' ); -const _supportedObjectNames = [ 'material', 'materials', 'bones' ]; +const _supportedObjectNames = [ 'material', 'materials', 'bones', 'map' ]; class Composite { @@ -496,6 +496,32 @@ class PropertyBinding { break; + case 'map': + + if ( 'map' in targetObject ) { + + targetObject = targetObject.map; + break; + + } + + if ( ! targetObject.material ) { + + console.error( 'THREE.PropertyBinding: Can not bind to material as node does not have a material.', this ); + return; + + } + + if ( ! targetObject.material.map ) { + + console.error( 'THREE.PropertyBinding: Can not bind to material.map as node.material does not have a map.', this ); + return; + + } + + targetObject = targetObject.material.map; + break; + default: if ( targetObject[ objectName ] === undefined ) { diff --git a/src/audio/AudioContext.js b/src/audio/AudioContext.js index ac0daf35ada934..a7cd911323aa7b 100644 --- a/src/audio/AudioContext.js +++ b/src/audio/AudioContext.js @@ -1,8 +1,8 @@ let _context; -const AudioContext = { +class AudioContext { - getContext: function () { + static getContext() { if ( _context === undefined ) { @@ -12,14 +12,14 @@ const AudioContext = { return _context; - }, + } - setContext: function ( value ) { + static setContext( value ) { _context = value; } -}; +} export { AudioContext }; diff --git a/src/cameras/CubeCamera.js b/src/cameras/CubeCamera.js index cf45d4a304a2d1..8560c7e9ffd91d 100644 --- a/src/cameras/CubeCamera.js +++ b/src/cameras/CubeCamera.js @@ -1,9 +1,9 @@ import { NoToneMapping } from '../constants.js'; import { Object3D } from '../core/Object3D.js'; -import { Vector3 } from '../math/Vector3.js'; import { PerspectiveCamera } from './PerspectiveCamera.js'; -const fov = 90, aspect = 1; +const fov = - 90; // negative fov is not an error +const aspect = 1; class CubeCamera extends Object3D { @@ -13,49 +13,42 @@ class CubeCamera extends Object3D { 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; const cameraPX = new PerspectiveCamera( fov, aspect, near, far ); cameraPX.layers = this.layers; - cameraPX.up.set( 0, - 1, 0 ); - cameraPX.lookAt( new Vector3( 1, 0, 0 ) ); + cameraPX.up.set( 0, 1, 0 ); + cameraPX.lookAt( 1, 0, 0 ); this.add( cameraPX ); const cameraNX = new PerspectiveCamera( fov, aspect, near, far ); cameraNX.layers = this.layers; - cameraNX.up.set( 0, - 1, 0 ); - cameraNX.lookAt( new Vector3( - 1, 0, 0 ) ); + cameraNX.up.set( 0, 1, 0 ); + cameraNX.lookAt( - 1, 0, 0 ); this.add( cameraNX ); const cameraPY = new PerspectiveCamera( fov, aspect, near, far ); cameraPY.layers = this.layers; - cameraPY.up.set( 0, 0, 1 ); - cameraPY.lookAt( new Vector3( 0, 1, 0 ) ); + cameraPY.up.set( 0, 0, - 1 ); + cameraPY.lookAt( 0, 1, 0 ); this.add( cameraPY ); const cameraNY = new PerspectiveCamera( fov, aspect, near, far ); cameraNY.layers = this.layers; - cameraNY.up.set( 0, 0, - 1 ); - cameraNY.lookAt( new Vector3( 0, - 1, 0 ) ); + cameraNY.up.set( 0, 0, 1 ); + cameraNY.lookAt( 0, - 1, 0 ); this.add( cameraNY ); const cameraPZ = new PerspectiveCamera( fov, aspect, near, far ); cameraPZ.layers = this.layers; - cameraPZ.up.set( 0, - 1, 0 ); - cameraPZ.lookAt( new Vector3( 0, 0, 1 ) ); + cameraPZ.up.set( 0, 1, 0 ); + cameraPZ.lookAt( 0, 0, 1 ); this.add( cameraPZ ); const cameraNZ = new PerspectiveCamera( fov, aspect, near, far ); cameraNZ.layers = this.layers; - cameraNZ.up.set( 0, - 1, 0 ); - cameraNZ.lookAt( new Vector3( 0, 0, - 1 ) ); + cameraNZ.up.set( 0, 1, 0 ); + cameraNZ.lookAt( 0, 0, - 1 ); this.add( cameraNZ ); } diff --git a/src/constants.js b/src/constants.js index 804359969c8ec4..5e5ac16a1b83a8 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,4 +1,4 @@ -export const REVISION = '143'; +export const REVISION = '147'; export const MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 }; export const TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 }; export const CullFaceNone = 0; @@ -12,8 +12,6 @@ export const VSMShadowMap = 3; export const FrontSide = 0; export const BackSide = 1; export const DoubleSide = 2; -export const FlatShading = 1; -export const SmoothShading = 2; export const NoBlending = 0; export const NormalBlending = 1; export const AdditiveBlending = 2; @@ -85,7 +83,7 @@ export const UnsignedShort4444Type = 1017; export const UnsignedShort5551Type = 1018; export const UnsignedInt248Type = 1020; export const AlphaFormat = 1021; -export const RGBFormat = 1022; +export const RGBFormat = 1022; // @deprecated since r137 export const RGBAFormat = 1023; export const LuminanceFormat = 1024; export const LuminanceAlphaFormat = 1025; diff --git a/src/core/BufferAttribute.js b/src/core/BufferAttribute.js index 3d47b0573281d6..688842c1186d09 100644 --- a/src/core/BufferAttribute.js +++ b/src/core/BufferAttribute.js @@ -1,7 +1,6 @@ -import { Vector4 } from '../math/Vector4.js'; import { Vector3 } from '../math/Vector3.js'; import { Vector2 } from '../math/Vector2.js'; -import { Color } from '../math/Color.js'; +import { denormalize, normalize } from '../math/MathUtils.js'; import { StaticDrawUsage } from '../constants.js'; const _vector = /*@__PURE__*/ new Vector3(); @@ -86,110 +85,6 @@ class BufferAttribute { } - copyColorsArray( colors ) { - - const array = this.array; - let offset = 0; - - for ( let i = 0, l = colors.length; i < l; i ++ ) { - - let color = colors[ i ]; - - if ( color === undefined ) { - - console.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i ); - color = new Color(); - - } - - array[ offset ++ ] = color.r; - array[ offset ++ ] = color.g; - array[ offset ++ ] = color.b; - - } - - return this; - - } - - copyVector2sArray( vectors ) { - - const array = this.array; - let offset = 0; - - for ( let i = 0, l = vectors.length; i < l; i ++ ) { - - let vector = vectors[ i ]; - - if ( vector === undefined ) { - - console.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i ); - vector = new Vector2(); - - } - - array[ offset ++ ] = vector.x; - array[ offset ++ ] = vector.y; - - } - - return this; - - } - - copyVector3sArray( vectors ) { - - const array = this.array; - let offset = 0; - - for ( let i = 0, l = vectors.length; i < l; i ++ ) { - - let vector = vectors[ i ]; - - 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; - - } - - return this; - - } - - copyVector4sArray( vectors ) { - - const array = this.array; - let offset = 0; - - for ( let i = 0, l = vectors.length; i < l; i ++ ) { - - let vector = vectors[ i ]; - - if ( vector === undefined ) { - - console.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i ); - vector = new Vector4(); - - } - - array[ offset ++ ] = vector.x; - array[ offset ++ ] = vector.y; - array[ offset ++ ] = vector.z; - array[ offset ++ ] = vector.w; - - } - - return this; - - } - applyMatrix3( m ) { if ( this.itemSize === 2 ) { @@ -270,6 +165,7 @@ class BufferAttribute { set( value, offset = 0 ) { + // Matching BufferAttribute constructor, do not normalize the array. this.array.set( value, offset ); return this; @@ -278,12 +174,18 @@ class BufferAttribute { getX( index ) { - return this.array[ index * this.itemSize ]; + let x = this.array[ index * this.itemSize ]; + + if ( this.normalized ) x = denormalize( x, this.array ); + + return x; } setX( index, x ) { + if ( this.normalized ) x = normalize( x, this.array ); + this.array[ index * this.itemSize ] = x; return this; @@ -292,12 +194,18 @@ class BufferAttribute { getY( index ) { - return this.array[ index * this.itemSize + 1 ]; + let y = this.array[ index * this.itemSize + 1 ]; + + if ( this.normalized ) y = denormalize( y, this.array ); + + return y; } setY( index, y ) { + if ( this.normalized ) y = normalize( y, this.array ); + this.array[ index * this.itemSize + 1 ] = y; return this; @@ -306,12 +214,18 @@ class BufferAttribute { getZ( index ) { - return this.array[ index * this.itemSize + 2 ]; + let z = this.array[ index * this.itemSize + 2 ]; + + if ( this.normalized ) z = denormalize( z, this.array ); + + return z; } setZ( index, z ) { + if ( this.normalized ) z = normalize( z, this.array ); + this.array[ index * this.itemSize + 2 ] = z; return this; @@ -320,12 +234,18 @@ class BufferAttribute { getW( index ) { - return this.array[ index * this.itemSize + 3 ]; + let w = this.array[ index * this.itemSize + 3 ]; + + if ( this.normalized ) w = denormalize( w, this.array ); + + return w; } setW( index, w ) { + if ( this.normalized ) w = normalize( w, this.array ); + this.array[ index * this.itemSize + 3 ] = w; return this; @@ -336,6 +256,13 @@ class BufferAttribute { index *= this.itemSize; + if ( this.normalized ) { + + x = normalize( x, this.array ); + y = normalize( y, this.array ); + + } + this.array[ index + 0 ] = x; this.array[ index + 1 ] = y; @@ -347,6 +274,14 @@ class BufferAttribute { index *= this.itemSize; + if ( this.normalized ) { + + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); + + } + this.array[ index + 0 ] = x; this.array[ index + 1 ] = y; this.array[ index + 2 ] = z; @@ -359,6 +294,15 @@ class BufferAttribute { index *= this.itemSize; + if ( this.normalized ) { + + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); + w = normalize( w, this.array ); + + } + this.array[ index + 0 ] = x; this.array[ index + 1 ] = y; this.array[ index + 2 ] = z; @@ -399,6 +343,32 @@ class BufferAttribute { } + // @deprecated + + copyColorsArray() { + + console.error( 'THREE.BufferAttribute: copyColorsArray() was removed in r144.' ); + + } + + copyVector2sArray() { + + console.error( 'THREE.BufferAttribute: copyVector2sArray() was removed in r144.' ); + + } + + copyVector3sArray() { + + console.error( 'THREE.BufferAttribute: copyVector3sArray() was removed in r144.' ); + + } + + copyVector4sArray() { + + console.error( 'THREE.BufferAttribute: copyVector4sArray() was removed in r144.' ); + + } + } // diff --git a/src/core/BufferGeometry.js b/src/core/BufferGeometry.js index 68bf0168ed879b..0465800aeac9b0 100644 --- a/src/core/BufferGeometry.js +++ b/src/core/BufferGeometry.js @@ -726,49 +726,11 @@ class BufferGeometry extends EventDispatcher { } - merge( geometry, offset ) { + // @deprecated since r144 - if ( ! ( geometry && geometry.isBufferGeometry ) ) { - - console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry ); - return; - - } - - if ( offset === undefined ) { - - offset = 0; - - console.warn( - 'THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. ' - + 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.' - ); - - } - - const attributes = this.attributes; - - for ( const key in attributes ) { - - if ( geometry.attributes[ key ] === undefined ) continue; - - const attribute1 = attributes[ key ]; - const attributeArray1 = attribute1.array; - - const attribute2 = geometry.attributes[ key ]; - const attributeArray2 = attribute2.array; - - const attributeOffset = attribute2.itemSize * offset; - const length = Math.min( attributeArray2.length, attributeArray1.length - attributeOffset ); - - for ( let i = 0, j = attributeOffset; i < length; i ++, j ++ ) { - - attributeArray1[ j ] = attributeArray2[ i ]; - - } - - } + merge() { + console.error( 'THREE.BufferGeometry.merge() has been removed. Use THREE.BufferGeometryUtils.mergeBufferGeometries() instead.' ); return this; } diff --git a/src/core/InstancedBufferAttribute.js b/src/core/InstancedBufferAttribute.js index 8123f4a23857dc..ed317ee32cd574 100644 --- a/src/core/InstancedBufferAttribute.js +++ b/src/core/InstancedBufferAttribute.js @@ -4,16 +4,6 @@ class InstancedBufferAttribute extends BufferAttribute { constructor( array, itemSize, normalized, meshPerAttribute = 1 ) { - if ( typeof normalized === 'number' ) { - - meshPerAttribute = normalized; - - normalized = false; - - console.error( 'THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument.' ); - - } - super( array, itemSize, normalized ); this.isInstancedBufferAttribute = true; diff --git a/src/core/InstancedBufferGeometry.js b/src/core/InstancedBufferGeometry.js index f061ccaadcba7a..0282b46f0fadbe 100644 --- a/src/core/InstancedBufferGeometry.js +++ b/src/core/InstancedBufferGeometry.js @@ -23,15 +23,9 @@ class InstancedBufferGeometry extends BufferGeometry { } - clone() { - - return new this.constructor().copy( this ); - - } - toJSON() { - const data = super.toJSON( this ); + const data = super.toJSON(); data.instanceCount = this.instanceCount; diff --git a/src/core/InterleavedBufferAttribute.js b/src/core/InterleavedBufferAttribute.js index 5010f3d4193500..993f57be4e9183 100644 --- a/src/core/InterleavedBufferAttribute.js +++ b/src/core/InterleavedBufferAttribute.js @@ -1,5 +1,6 @@ import { Vector3 } from '../math/Vector3.js'; import { BufferAttribute } from './BufferAttribute.js'; +import { denormalize, normalize } from '../math/MathUtils.js'; const _vector = /*@__PURE__*/ new Vector3(); @@ -87,6 +88,8 @@ class InterleavedBufferAttribute { setX( index, x ) { + if ( this.normalized ) x = normalize( x, this.array ); + this.data.array[ index * this.data.stride + this.offset ] = x; return this; @@ -95,6 +98,8 @@ class InterleavedBufferAttribute { setY( index, y ) { + if ( this.normalized ) y = normalize( y, this.array ); + this.data.array[ index * this.data.stride + this.offset + 1 ] = y; return this; @@ -103,6 +108,8 @@ class InterleavedBufferAttribute { setZ( index, z ) { + if ( this.normalized ) z = normalize( z, this.array ); + this.data.array[ index * this.data.stride + this.offset + 2 ] = z; return this; @@ -111,6 +118,8 @@ class InterleavedBufferAttribute { setW( index, w ) { + if ( this.normalized ) w = normalize( w, this.array ); + this.data.array[ index * this.data.stride + this.offset + 3 ] = w; return this; @@ -119,25 +128,41 @@ class InterleavedBufferAttribute { getX( index ) { - return this.data.array[ index * this.data.stride + this.offset ]; + let x = this.data.array[ index * this.data.stride + this.offset ]; + + if ( this.normalized ) x = denormalize( x, this.array ); + + return x; } getY( index ) { - return this.data.array[ index * this.data.stride + this.offset + 1 ]; + let y = this.data.array[ index * this.data.stride + this.offset + 1 ]; + + if ( this.normalized ) y = denormalize( y, this.array ); + + return y; } getZ( index ) { - return this.data.array[ index * this.data.stride + this.offset + 2 ]; + let z = this.data.array[ index * this.data.stride + this.offset + 2 ]; + + if ( this.normalized ) z = denormalize( z, this.array ); + + return z; } getW( index ) { - return this.data.array[ index * this.data.stride + this.offset + 3 ]; + let w = this.data.array[ index * this.data.stride + this.offset + 3 ]; + + if ( this.normalized ) w = denormalize( w, this.array ); + + return w; } @@ -145,6 +170,13 @@ class InterleavedBufferAttribute { index = index * this.data.stride + this.offset; + if ( this.normalized ) { + + x = normalize( x, this.array ); + y = normalize( y, this.array ); + + } + this.data.array[ index + 0 ] = x; this.data.array[ index + 1 ] = y; @@ -156,6 +188,14 @@ class InterleavedBufferAttribute { index = index * this.data.stride + this.offset; + if ( this.normalized ) { + + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); + + } + this.data.array[ index + 0 ] = x; this.data.array[ index + 1 ] = y; this.data.array[ index + 2 ] = z; @@ -168,6 +208,15 @@ class InterleavedBufferAttribute { index = index * this.data.stride + this.offset; + if ( this.normalized ) { + + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); + w = normalize( w, this.array ); + + } + this.data.array[ index + 0 ] = x; this.data.array[ index + 1 ] = y; this.data.array[ index + 2 ] = z; @@ -181,7 +230,7 @@ class InterleavedBufferAttribute { if ( data === undefined ) { - console.log( 'THREE.InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will deinterleave buffer data.' ); + console.log( 'THREE.InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will de-interleave buffer data.' ); const array = []; @@ -223,7 +272,7 @@ class InterleavedBufferAttribute { if ( data === undefined ) { - console.log( 'THREE.InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will deinterleave buffer data.' ); + console.log( 'THREE.InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will de-interleave buffer data.' ); const array = []; @@ -239,7 +288,7 @@ class InterleavedBufferAttribute { } - // deinterleave data and save it as an ordinary buffer attribute for now + // de-interleave data and save it as an ordinary buffer attribute for now return { itemSize: this.itemSize, @@ -250,7 +299,7 @@ class InterleavedBufferAttribute { } else { - // save as true interleaved attribtue + // save as true interleaved attribute if ( data.interleavedBuffers === undefined ) { diff --git a/src/core/Object3D.js b/src/core/Object3D.js index 71f63208e38e37..0bf6bb6a2fd868 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -100,6 +100,8 @@ class Object3D extends EventDispatcher { this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate; this.matrixWorldNeedsUpdate = false; + this.matrixWorldAutoUpdate = Object3D.DefaultMatrixWorldAutoUpdate; // checked by the renderer + this.layers = new Layers(); this.visible = true; @@ -584,7 +586,13 @@ class Object3D extends EventDispatcher { for ( let i = 0, l = children.length; i < l; i ++ ) { - children[ i ].updateMatrixWorld( force ); + const child = children[ i ]; + + if ( child.matrixWorldAutoUpdate === true || force === true ) { + + child.updateMatrixWorld( force ); + + } } @@ -594,7 +602,7 @@ class Object3D extends EventDispatcher { const parent = this.parent; - if ( updateParents === true && parent !== null ) { + if ( updateParents === true && parent !== null && parent.matrixWorldAutoUpdate === true ) { parent.updateWorldMatrix( true, false ); @@ -620,7 +628,13 @@ class Object3D extends EventDispatcher { for ( let i = 0, l = children.length; i < l; i ++ ) { - children[ i ].updateWorldMatrix( false, true ); + const child = children[ i ]; + + if ( child.matrixWorldAutoUpdate === true ) { + + child.updateWorldMatrix( false, true ); + + } } @@ -893,6 +907,8 @@ class Object3D extends EventDispatcher { this.matrixAutoUpdate = source.matrixAutoUpdate; this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; + this.matrixWorldAutoUpdate = source.matrixWorldAutoUpdate; + this.layers.mask = source.layers.mask; this.visible = source.visible; @@ -923,5 +939,6 @@ class Object3D extends EventDispatcher { Object3D.DefaultUp = /*@__PURE__*/ new Vector3( 0, 1, 0 ); Object3D.DefaultMatrixAutoUpdate = true; +Object3D.DefaultMatrixWorldAutoUpdate = true; export { Object3D }; diff --git a/src/core/Uniform.js b/src/core/Uniform.js index 73ba1916c096b0..a2d421c40c9618 100644 --- a/src/core/Uniform.js +++ b/src/core/Uniform.js @@ -2,13 +2,6 @@ class Uniform { constructor( value ) { - if ( typeof value === 'string' ) { - - console.warn( 'THREE.Uniform: Type parameter is no longer needed.' ); - value = arguments[ 1 ]; - - } - this.value = value; } diff --git a/src/extras/Earcut.js b/src/extras/Earcut.js index f42b21f7f357f1..0a824aca20631d 100644 --- a/src/extras/Earcut.js +++ b/src/extras/Earcut.js @@ -1,5 +1,5 @@ /** - * Port from https://github.com/mapbox/earcut (v2.2.2) + * Port from https://github.com/mapbox/earcut (v2.2.4) */ const Earcut = { @@ -36,11 +36,11 @@ const Earcut = { // minX, minY and invSize are later used to transform coords into integers for z-order calculation invSize = Math.max( maxX - minX, maxY - minY ); - invSize = invSize !== 0 ? 1 / invSize : 0; + invSize = invSize !== 0 ? 32767 / invSize : 0; } - earcutLinked( outerNode, triangles, dim, minX, minY, invSize ); + earcutLinked( outerNode, triangles, dim, minX, minY, invSize, 0 ); return triangles; @@ -125,9 +125,9 @@ function earcutLinked( ear, triangles, dim, minX, minY, invSize, pass ) { 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 ); + triangles.push( prev.i / dim | 0 ); + triangles.push( ear.i / dim | 0 ); + triangles.push( next.i / dim | 0 ); removeNode( ear ); @@ -182,11 +182,19 @@ function isEar( ear ) { 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 - let p = ear.next.next; + const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y; - while ( p !== ear.prev ) { + // triangle bbox; min & max are calculated like this for speed + const x0 = ax < bx ? ( ax < cx ? ax : cx ) : ( bx < cx ? bx : cx ), + y0 = ay < by ? ( ay < cy ? ay : cy ) : ( by < cy ? by : cy ), + x1 = ax > bx ? ( ax > cx ? ax : cx ) : ( bx > cx ? bx : cx ), + y1 = ay > by ? ( ay > cy ? ay : cy ) : ( by > cy ? by : cy ); + + let p = c.next; + while ( p !== a ) { - if ( pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && + if ( p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && + pointInTriangle( ax, ay, bx, by, cx, cy, p.x, p.y ) && area( p.prev, p, p.next ) >= 0 ) return false; p = p.next; @@ -204,15 +212,17 @@ function isEarHashed( ear, minX, minY, invSize ) { if ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear + const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y; + // triangle bbox; min & max are calculated like this for speed - const 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 ); + const x0 = ax < bx ? ( ax < cx ? ax : cx ) : ( bx < cx ? bx : cx ), + y0 = ay < by ? ( ay < cy ? ay : cy ) : ( by < cy ? by : cy ), + x1 = ax > bx ? ( ax > cx ? ax : cx ) : ( bx > cx ? bx : cx ), + y1 = ay > by ? ( ay > cy ? ay : cy ) : ( by > cy ? by : cy ); // z-order range for the current triangle bbox; - const minZ = zOrder( minTX, minTY, minX, minY, invSize ), - maxZ = zOrder( maxTX, maxTY, minX, minY, invSize ); + const minZ = zOrder( x0, y0, minX, minY, invSize ), + maxZ = zOrder( x1, y1, minX, minY, invSize ); let p = ear.prevZ, n = ear.nextZ; @@ -220,14 +230,12 @@ function isEarHashed( ear, minX, minY, invSize ) { // look for points inside the triangle in both directions 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; + if ( p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && + pointInTriangle( ax, ay, bx, by, cx, cy, 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; + if ( n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && + pointInTriangle( ax, ay, bx, by, cx, cy, n.x, n.y ) && area( n.prev, n, n.next ) >= 0 ) return false; n = n.nextZ; } @@ -235,9 +243,8 @@ function isEarHashed( ear, minX, minY, invSize ) { // 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; + if ( p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && + pointInTriangle( ax, ay, bx, by, cx, cy, p.x, p.y ) && area( p.prev, p, p.next ) >= 0 ) return false; p = p.prevZ; } @@ -245,9 +252,8 @@ function isEarHashed( ear, minX, minY, invSize ) { // look for remaining points in increasing z-order 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; + if ( n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && + pointInTriangle( ax, ay, bx, by, cx, cy, n.x, n.y ) && area( n.prev, n, n.next ) >= 0 ) return false; n = n.nextZ; } @@ -267,9 +273,9 @@ function cureLocalIntersections( start, triangles, dim ) { 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 ); + triangles.push( a.i / dim | 0 ); + triangles.push( p.i / dim | 0 ); + triangles.push( b.i / dim | 0 ); // remove two nodes involved removeNode( p ); @@ -307,8 +313,8 @@ function splitEarcut( start, triangles, dim, minX, minY, invSize ) { c = filterPoints( c, c.next ); // run earcut on each half - earcutLinked( a, triangles, dim, minX, minY, invSize ); - earcutLinked( c, triangles, dim, minX, minY, invSize ); + earcutLinked( a, triangles, dim, minX, minY, invSize, 0 ); + earcutLinked( c, triangles, dim, minX, minY, invSize, 0 ); return; } @@ -344,8 +350,7 @@ function eliminateHoles( data, holeIndices, outerNode, dim ) { // process holes from left to right for ( i = 0; i < queue.length; i ++ ) { - eliminateHole( queue[ i ], outerNode ); - outerNode = filterPoints( outerNode, outerNode.next ); + outerNode = eliminateHole( queue[ i ], outerNode ); } @@ -362,26 +367,29 @@ function compareX( a, b ) { // find a bridge between vertices that connects hole with an outer ring and link it function eliminateHole( hole, outerNode ) { - outerNode = findHoleBridge( hole, outerNode ); - if ( outerNode ) { - - const b = splitPolygon( outerNode, hole ); + const bridge = findHoleBridge( hole, outerNode ); + if ( ! bridge ) { - // filter collinear points around the cuts - filterPoints( outerNode, outerNode.next ); - filterPoints( b, b.next ); + return outerNode; } + const bridgeReverse = splitPolygon( bridge, hole ); + + // filter collinear points around the cuts + filterPoints( bridgeReverse, bridgeReverse.next ); + return filterPoints( bridge, bridge.next ); + } // David Eberly's algorithm for finding a bridge between hole and outer polygon function findHoleBridge( hole, outerNode ) { - let p = outerNode; - const hx = hole.x; - const hy = hole.y; - let qx = - Infinity, m; + let p = outerNode, + qx = - Infinity, + m; + + const hx = hole.x, hy = hole.y; // 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 @@ -393,14 +401,8 @@ function findHoleBridge( hole, outerNode ) { if ( x <= hx && x > qx ) { qx = x; - if ( x === hx ) { - - if ( hy === p.y ) return p; - if ( hy === p.next.y ) return p.next; - - } - m = p.x < p.next.x ? p : p.next; + if ( x === hx ) return m; // hole touches outer segment; pick leftmost endpoint } @@ -412,8 +414,6 @@ function findHoleBridge( hole, outerNode ) { 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 @@ -462,7 +462,7 @@ function indexCurve( start, minX, minY, invSize ) { let p = start; do { - if ( p.z === null ) p.z = zOrder( p.x, p.y, minX, minY, invSize ); + if ( p.z === 0 ) p.z = zOrder( p.x, p.y, minX, minY, invSize ); p.prevZ = p.prev; p.nextZ = p.next; p = p.next; @@ -546,8 +546,8 @@ function sortLinked( list ) { 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 - minX ) * invSize | 0; + y = ( y - minY ) * invSize | 0; x = ( x | ( x << 8 ) ) & 0x00FF00FF; x = ( x | ( x << 4 ) ) & 0x0F0F0F0F; @@ -582,19 +582,19 @@ function getLeftmost( start ) { // check if a point lies within a convex triangle 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; + return ( cx - px ) * ( ay - py ) >= ( ax - px ) * ( cy - py ) && + ( ax - px ) * ( by - py ) >= ( bx - px ) * ( ay - py ) && + ( bx - px ) * ( cy - py ) >= ( cx - px ) * ( by - py ); } // check if a diagonal between two polygon nodes is valid (lies in polygon interior) function isValidDiagonal( a, b ) { - return a.next.i !== b.i && a.prev.i !== b.i && ! intersectsPolygon( a, b ) && // doesn'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 + 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 } @@ -651,7 +651,7 @@ function intersectsPolygon( a, b ) { 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; + intersects( p, p.next, a, b ) ) return true; p = p.next; } while ( p !== a ); @@ -679,7 +679,7 @@ function middleInside( a, b ) { 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 ) ) + ( px < ( p.next.x - p.x ) * ( py - p.y ) / ( p.next.y - p.y ) + p.x ) ) inside = ! inside; p = p.next; @@ -761,7 +761,7 @@ function Node( i, x, y ) { this.next = null; // z-order curve value - this.z = null; + this.z = 0; // previous and next nodes in z-order this.prevZ = null; diff --git a/src/extras/core/ShapePath.js b/src/extras/core/ShapePath.js index b2b9a117db74af..036a6a566d9770 100644 --- a/src/extras/core/ShapePath.js +++ b/src/extras/core/ShapePath.js @@ -58,7 +58,7 @@ class ShapePath { } - toShapes( isCCW, noHoles ) { + toShapes( isCCW ) { function toShapesNoHoles( inSubpaths ) { @@ -144,9 +144,6 @@ class ShapePath { const subPaths = this.subPaths; if ( subPaths.length === 0 ) return []; - if ( noHoles === true ) return toShapesNoHoles( subPaths ); - - let solid, tmpPath, tmpShape; const shapes = []; diff --git a/src/geometries/BoxGeometry.js b/src/geometries/BoxGeometry.js index 00abffcc137f7d..5f3aa4c8590451 100644 --- a/src/geometries/BoxGeometry.js +++ b/src/geometries/BoxGeometry.js @@ -167,4 +167,4 @@ class BoxGeometry extends BufferGeometry { } -export { BoxGeometry, BoxGeometry as BoxBufferGeometry }; +export { BoxGeometry }; diff --git a/src/geometries/CapsuleGeometry.js b/src/geometries/CapsuleGeometry.js index aa5007e97db756..5841e221081459 100644 --- a/src/geometries/CapsuleGeometry.js +++ b/src/geometries/CapsuleGeometry.js @@ -30,4 +30,4 @@ class CapsuleGeometry extends LatheGeometry { } -export { CapsuleGeometry, CapsuleGeometry as CapsuleBufferGeometry }; +export { CapsuleGeometry }; diff --git a/src/geometries/CircleGeometry.js b/src/geometries/CircleGeometry.js index 799bf6628db94f..783d54a1bdb054 100644 --- a/src/geometries/CircleGeometry.js +++ b/src/geometries/CircleGeometry.js @@ -88,4 +88,4 @@ class CircleGeometry extends BufferGeometry { } -export { CircleGeometry, CircleGeometry as CircleBufferGeometry }; +export { CircleGeometry }; diff --git a/src/geometries/ConeGeometry.js b/src/geometries/ConeGeometry.js index 70ceb6a96b1228..c0e3c9f2274cbb 100644 --- a/src/geometries/ConeGeometry.js +++ b/src/geometries/ConeGeometry.js @@ -28,4 +28,4 @@ class ConeGeometry extends CylinderGeometry { } -export { ConeGeometry, ConeGeometry as ConeBufferGeometry }; +export { ConeGeometry }; diff --git a/src/geometries/CylinderGeometry.js b/src/geometries/CylinderGeometry.js index c865131bbb10a3..5ecd2da5bd3f98 100644 --- a/src/geometries/CylinderGeometry.js +++ b/src/geometries/CylinderGeometry.js @@ -273,4 +273,4 @@ class CylinderGeometry extends BufferGeometry { } -export { CylinderGeometry, CylinderGeometry as CylinderBufferGeometry }; +export { CylinderGeometry }; diff --git a/src/geometries/DodecahedronGeometry.js b/src/geometries/DodecahedronGeometry.js index 5627c29579305c..3434df937d9494 100644 --- a/src/geometries/DodecahedronGeometry.js +++ b/src/geometries/DodecahedronGeometry.js @@ -63,4 +63,4 @@ class DodecahedronGeometry extends PolyhedronGeometry { } -export { DodecahedronGeometry, DodecahedronGeometry as DodecahedronBufferGeometry }; +export { DodecahedronGeometry }; diff --git a/src/geometries/ExtrudeGeometry.js b/src/geometries/ExtrudeGeometry.js index 96f12368dc579b..a726b11360d4df 100644 --- a/src/geometries/ExtrudeGeometry.js +++ b/src/geometries/ExtrudeGeometry.js @@ -801,4 +801,4 @@ function toJSON( shapes, options, data ) { } -export { ExtrudeGeometry, ExtrudeGeometry as ExtrudeBufferGeometry }; +export { ExtrudeGeometry }; diff --git a/src/geometries/IcosahedronGeometry.js b/src/geometries/IcosahedronGeometry.js index b489eb0af2d24d..5ffd4a02ba16d4 100644 --- a/src/geometries/IcosahedronGeometry.js +++ b/src/geometries/IcosahedronGeometry.js @@ -39,4 +39,4 @@ class IcosahedronGeometry extends PolyhedronGeometry { } -export { IcosahedronGeometry, IcosahedronGeometry as IcosahedronBufferGeometry }; +export { IcosahedronGeometry }; diff --git a/src/geometries/LatheGeometry.js b/src/geometries/LatheGeometry.js index 8e28b8605c8b06..8e509912221990 100644 --- a/src/geometries/LatheGeometry.js +++ b/src/geometries/LatheGeometry.js @@ -176,4 +176,4 @@ class LatheGeometry extends BufferGeometry { } -export { LatheGeometry, LatheGeometry as LatheBufferGeometry }; +export { LatheGeometry }; diff --git a/src/geometries/OctahedronGeometry.js b/src/geometries/OctahedronGeometry.js index de9b75c31f2e05..d91bb1a18830d7 100644 --- a/src/geometries/OctahedronGeometry.js +++ b/src/geometries/OctahedronGeometry.js @@ -34,4 +34,4 @@ class OctahedronGeometry extends PolyhedronGeometry { } -export { OctahedronGeometry, OctahedronGeometry as OctahedronBufferGeometry }; +export { OctahedronGeometry }; diff --git a/src/geometries/PlaneGeometry.js b/src/geometries/PlaneGeometry.js index bad96d0a3cbe56..d093f041d71a0a 100644 --- a/src/geometries/PlaneGeometry.js +++ b/src/geometries/PlaneGeometry.js @@ -85,4 +85,4 @@ class PlaneGeometry extends BufferGeometry { } -export { PlaneGeometry, PlaneGeometry as PlaneBufferGeometry }; +export { PlaneGeometry }; diff --git a/src/geometries/PolyhedronGeometry.js b/src/geometries/PolyhedronGeometry.js index 36d650ea467bab..99478e618f8f5d 100644 --- a/src/geometries/PolyhedronGeometry.js +++ b/src/geometries/PolyhedronGeometry.js @@ -59,7 +59,7 @@ class PolyhedronGeometry extends BufferGeometry { const b = new Vector3(); const c = new Vector3(); - // iterate over all faces and apply a subdivison with the given detail value + // iterate over all faces and apply a subdivision with the given detail value for ( let i = 0; i < indices.length; i += 3 ) { @@ -306,4 +306,4 @@ class PolyhedronGeometry extends BufferGeometry { } -export { PolyhedronGeometry, PolyhedronGeometry as PolyhedronBufferGeometry }; +export { PolyhedronGeometry }; diff --git a/src/geometries/RingGeometry.js b/src/geometries/RingGeometry.js index d1199c19049197..f813da1955d082 100644 --- a/src/geometries/RingGeometry.js +++ b/src/geometries/RingGeometry.js @@ -115,4 +115,4 @@ class RingGeometry extends BufferGeometry { } -export { RingGeometry, RingGeometry as RingBufferGeometry }; +export { RingGeometry }; diff --git a/src/geometries/ShapeGeometry.js b/src/geometries/ShapeGeometry.js index d204b0c55f64c2..098c82e656fc9a 100644 --- a/src/geometries/ShapeGeometry.js +++ b/src/geometries/ShapeGeometry.js @@ -111,7 +111,7 @@ class ShapeGeometry extends BufferGeometry { } - // incides + // indices for ( let i = 0, l = faces.length; i < l; i ++ ) { @@ -182,4 +182,4 @@ function toJSON( shapes, data ) { } -export { ShapeGeometry, ShapeGeometry as ShapeBufferGeometry }; +export { ShapeGeometry }; diff --git a/src/geometries/SphereGeometry.js b/src/geometries/SphereGeometry.js index 0d5a33dff4df66..8551e9b228c865 100644 --- a/src/geometries/SphereGeometry.js +++ b/src/geometries/SphereGeometry.js @@ -124,4 +124,4 @@ class SphereGeometry extends BufferGeometry { } -export { SphereGeometry, SphereGeometry as SphereBufferGeometry }; +export { SphereGeometry }; diff --git a/src/geometries/TetrahedronGeometry.js b/src/geometries/TetrahedronGeometry.js index 537f664292df48..77c62107f2e8f4 100644 --- a/src/geometries/TetrahedronGeometry.js +++ b/src/geometries/TetrahedronGeometry.js @@ -31,4 +31,4 @@ class TetrahedronGeometry extends PolyhedronGeometry { } -export { TetrahedronGeometry, TetrahedronGeometry as TetrahedronBufferGeometry }; +export { TetrahedronGeometry }; diff --git a/src/geometries/TorusGeometry.js b/src/geometries/TorusGeometry.js index 63696384b368de..354ba92543c5f1 100644 --- a/src/geometries/TorusGeometry.js +++ b/src/geometries/TorusGeometry.js @@ -107,4 +107,4 @@ class TorusGeometry extends BufferGeometry { } -export { TorusGeometry, TorusGeometry as TorusBufferGeometry }; +export { TorusGeometry }; diff --git a/src/geometries/TorusKnotGeometry.js b/src/geometries/TorusKnotGeometry.js index 8a3324ee0c4ed5..66fcdf022b188a 100644 --- a/src/geometries/TorusKnotGeometry.js +++ b/src/geometries/TorusKnotGeometry.js @@ -154,4 +154,4 @@ class TorusKnotGeometry extends BufferGeometry { } -export { TorusKnotGeometry, TorusKnotGeometry as TorusKnotBufferGeometry }; +export { TorusKnotGeometry }; diff --git a/src/geometries/TubeGeometry.js b/src/geometries/TubeGeometry.js index 273a069fb0d914..e02eb923da75c2 100644 --- a/src/geometries/TubeGeometry.js +++ b/src/geometries/TubeGeometry.js @@ -190,4 +190,4 @@ class TubeGeometry extends BufferGeometry { } -export { TubeGeometry, TubeGeometry as TubeBufferGeometry }; +export { TubeGeometry }; diff --git a/src/helpers/ArrowHelper.js b/src/helpers/ArrowHelper.js index 691186b6bf697e..50d9a6dabe9365 100644 --- a/src/helpers/ArrowHelper.js +++ b/src/helpers/ArrowHelper.js @@ -99,6 +99,15 @@ class ArrowHelper extends Object3D { } + dispose() { + + this.line.geometry.dispose(); + this.line.material.dispose(); + this.cone.geometry.dispose(); + this.cone.material.dispose(); + + } + } diff --git a/src/helpers/Box3Helper.js b/src/helpers/Box3Helper.js index 1560162fb8c5de..93ef5930f50e9f 100644 --- a/src/helpers/Box3Helper.js +++ b/src/helpers/Box3Helper.js @@ -44,6 +44,13 @@ class Box3Helper extends LineSegments { } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + + } + } export { Box3Helper }; diff --git a/src/helpers/BoxHelper.js b/src/helpers/BoxHelper.js index 1ff9c121c08e2b..2629396bed6d50 100644 --- a/src/helpers/BoxHelper.js +++ b/src/helpers/BoxHelper.js @@ -79,7 +79,6 @@ class BoxHelper extends LineSegments { this.geometry.computeBoundingSphere(); - } setFromObject( object ) { @@ -101,6 +100,13 @@ class BoxHelper extends LineSegments { } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + + } + } diff --git a/src/helpers/DirectionalLightHelper.js b/src/helpers/DirectionalLightHelper.js index 9818f4aa51c511..f1b9c85c4a03cf 100644 --- a/src/helpers/DirectionalLightHelper.js +++ b/src/helpers/DirectionalLightHelper.js @@ -16,13 +16,14 @@ class DirectionalLightHelper extends Object3D { super(); this.light = light; - this.light.updateMatrixWorld(); this.matrix = light.matrixWorld; this.matrixAutoUpdate = false; this.color = color; + this.type = 'DirectionalLightHelper'; + if ( size === undefined ) size = 1; let geometry = new BufferGeometry(); @@ -60,6 +61,9 @@ class DirectionalLightHelper extends Object3D { update() { + this.light.updateWorldMatrix( true, false ); + this.light.target.updateWorldMatrix( true, false ); + _v1.setFromMatrixPosition( this.light.matrixWorld ); _v2.setFromMatrixPosition( this.light.target.matrixWorld ); _v3.subVectors( _v2, _v1 ); diff --git a/src/helpers/GridHelper.js b/src/helpers/GridHelper.js index 6ade28a79edef7..68f4dadd3e8b2c 100644 --- a/src/helpers/GridHelper.js +++ b/src/helpers/GridHelper.js @@ -43,6 +43,13 @@ class GridHelper extends LineSegments { } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + + } + } diff --git a/src/helpers/HemisphereLightHelper.js b/src/helpers/HemisphereLightHelper.js index 609c9e75c43731..b54f6938cd1763 100644 --- a/src/helpers/HemisphereLightHelper.js +++ b/src/helpers/HemisphereLightHelper.js @@ -17,13 +17,14 @@ class HemisphereLightHelper extends Object3D { super(); this.light = light; - this.light.updateMatrixWorld(); this.matrix = light.matrixWorld; this.matrixAutoUpdate = false; this.color = color; + this.type = 'HemisphereLightHelper'; + const geometry = new OctahedronGeometry( size ); geometry.rotateY( Math.PI * 0.5 ); @@ -75,6 +76,8 @@ class HemisphereLightHelper extends Object3D { } + this.light.updateWorldMatrix( true, false ); + mesh.lookAt( _vector.setFromMatrixPosition( this.light.matrixWorld ).negate() ); } diff --git a/src/helpers/PlaneHelper.js b/src/helpers/PlaneHelper.js index f6ca60f6502132..f3106afe648c6e 100644 --- a/src/helpers/PlaneHelper.js +++ b/src/helpers/PlaneHelper.js @@ -49,6 +49,15 @@ class PlaneHelper extends Line { } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + this.children[ 0 ].geometry.dispose(); + this.children[ 0 ].material.dispose(); + + } + } export { PlaneHelper }; diff --git a/src/helpers/PointLightHelper.js b/src/helpers/PointLightHelper.js index 83c983dc2da028..88990d49128751 100644 --- a/src/helpers/PointLightHelper.js +++ b/src/helpers/PointLightHelper.js @@ -12,7 +12,6 @@ class PointLightHelper extends Mesh { super( geometry, material ); this.light = light; - this.light.updateMatrixWorld(); this.color = color; @@ -58,6 +57,8 @@ class PointLightHelper extends Mesh { update() { + this.light.updateWorldMatrix( true, false ); + if ( this.color !== undefined ) { this.material.color.set( this.color ); diff --git a/src/helpers/PolarGridHelper.js b/src/helpers/PolarGridHelper.js index 46020bea01739f..83695f32c5a49c 100644 --- a/src/helpers/PolarGridHelper.js +++ b/src/helpers/PolarGridHelper.js @@ -6,7 +6,7 @@ import { Color } from '../math/Color.js'; class PolarGridHelper extends LineSegments { - constructor( radius = 10, radials = 16, circles = 8, divisions = 64, color1 = 0x444444, color2 = 0x888888 ) { + constructor( radius = 10, sectors = 16, rings = 8, divisions = 64, color1 = 0x444444, color2 = 0x888888 ) { color1 = new Color( color1 ); color2 = new Color( color2 ); @@ -14,32 +14,36 @@ class PolarGridHelper extends LineSegments { const vertices = []; const colors = []; - // create the radials + // create the sectors - for ( let i = 0; i <= radials; i ++ ) { + if ( sectors > 1 ) { - const v = ( i / radials ) * ( Math.PI * 2 ); + for ( let i = 0; i < sectors; i ++ ) { - const x = Math.sin( v ) * radius; - const z = Math.cos( v ) * radius; + const v = ( i / sectors ) * ( Math.PI * 2 ); - vertices.push( 0, 0, 0 ); - vertices.push( x, 0, z ); + const x = Math.sin( v ) * radius; + const z = Math.cos( v ) * radius; - const color = ( i & 1 ) ? color1 : color2; + vertices.push( 0, 0, 0 ); + vertices.push( x, 0, z ); + + const color = ( i & 1 ) ? color1 : color2; - colors.push( color.r, color.g, color.b ); - colors.push( color.r, color.g, color.b ); + colors.push( color.r, color.g, color.b ); + colors.push( color.r, color.g, color.b ); + + } } - // create the circles + // create the rings - for ( let i = 0; i <= circles; i ++ ) { + for ( let i = 0; i < rings; i ++ ) { const color = ( i & 1 ) ? color1 : color2; - const r = radius - ( radius / circles * i ); + const r = radius - ( radius / rings * i ); for ( let j = 0; j < divisions; j ++ ) { @@ -79,6 +83,13 @@ class PolarGridHelper extends LineSegments { } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + + } + } diff --git a/src/helpers/SkeletonHelper.js b/src/helpers/SkeletonHelper.js index 188395d7b7e1f9..cc684e388f9103 100644 --- a/src/helpers/SkeletonHelper.js +++ b/src/helpers/SkeletonHelper.js @@ -94,6 +94,13 @@ class SkeletonHelper extends LineSegments { } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + + } + } diff --git a/src/helpers/SpotLightHelper.js b/src/helpers/SpotLightHelper.js index a364801c4baf03..da9431c3dd2c5b 100644 --- a/src/helpers/SpotLightHelper.js +++ b/src/helpers/SpotLightHelper.js @@ -14,13 +14,14 @@ class SpotLightHelper extends Object3D { super(); this.light = light; - this.light.updateMatrixWorld(); this.matrix = light.matrixWorld; this.matrixAutoUpdate = false; this.color = color; + this.type = 'SpotLightHelper'; + const geometry = new BufferGeometry(); const positions = [ @@ -63,7 +64,8 @@ class SpotLightHelper extends Object3D { update() { - this.light.updateMatrixWorld(); + this.light.updateWorldMatrix( true, false ); + this.light.target.updateWorldMatrix( true, false ); const coneLength = this.light.distance ? this.light.distance : 1000; const coneWidth = coneLength * Math.tan( this.light.angle ); diff --git a/src/lights/LightShadow.js b/src/lights/LightShadow.js index e00f1ca55f95fb..f9a1dd19f13004 100644 --- a/src/lights/LightShadow.js +++ b/src/lights/LightShadow.js @@ -75,8 +75,7 @@ class LightShadow { 0.0, 0.0, 0.0, 1.0 ); - shadowMatrix.multiply( shadowCamera.projectionMatrix ); - shadowMatrix.multiply( shadowCamera.matrixWorldInverse ); + shadowMatrix.multiply( _projScreenMatrix ); } diff --git a/src/lights/PointLight.js b/src/lights/PointLight.js index b5acf8d00d96d1..7940a16e4511fd 100644 --- a/src/lights/PointLight.js +++ b/src/lights/PointLight.js @@ -3,7 +3,7 @@ import { PointLightShadow } from './PointLightShadow.js'; class PointLight extends Light { - constructor( color, intensity, distance = 0, decay = 1 ) { + constructor( color, intensity, distance = 0, decay = 2 ) { super( color, intensity ); @@ -12,7 +12,7 @@ class PointLight extends Light { this.type = 'PointLight'; this.distance = distance; - this.decay = decay; // for physically correct lights, should be 2. + this.decay = decay; this.shadow = new PointLightShadow(); diff --git a/src/lights/SpotLight.js b/src/lights/SpotLight.js index 93f3305a962aed..49ac6a081211a7 100644 --- a/src/lights/SpotLight.js +++ b/src/lights/SpotLight.js @@ -4,7 +4,7 @@ import { Object3D } from '../core/Object3D.js'; class SpotLight extends Light { - constructor( color, intensity, distance = 0, angle = Math.PI / 3, penumbra = 0, decay = 1 ) { + constructor( color, intensity, distance = 0, angle = Math.PI / 3, penumbra = 0, decay = 2 ) { super( color, intensity ); @@ -20,7 +20,9 @@ class SpotLight extends Light { this.distance = distance; this.angle = angle; this.penumbra = penumbra; - this.decay = decay; // for physically correct lights, should be 2. + this.decay = decay; + + this.map = null; this.shadow = new SpotLightShadow(); diff --git a/src/loaders/FileLoader.js b/src/loaders/FileLoader.js index bfcb6e1a63cf9b..1e528eb11fb19b 100644 --- a/src/loaders/FileLoader.js +++ b/src/loaders/FileLoader.js @@ -109,7 +109,10 @@ class FileLoader extends Loader { const callbacks = loading[ url ]; const reader = response.body.getReader(); - const contentLength = response.headers.get( 'Content-Length' ); + + // Nginx needs X-File-Size check + // https://serverfault.com/questions/482875/why-does-nginx-remove-content-length-header-for-chunked-content + const contentLength = response.headers.get( 'Content-Length' ) || response.headers.get( 'X-File-Size' ); const total = contentLength ? parseInt( contentLength ) : 0; const lengthComputable = total !== 0; let loaded = 0; diff --git a/src/loaders/MaterialLoader.js b/src/loaders/MaterialLoader.js index 056fd2ad71fa2b..ec47f5ffd1b567 100644 --- a/src/loaders/MaterialLoader.js +++ b/src/loaders/MaterialLoader.js @@ -225,6 +225,7 @@ class MaterialLoader extends Loader { 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.glslVersion !== undefined ) material.glslVersion = json.glslVersion; if ( json.extensions !== undefined ) { @@ -236,10 +237,6 @@ class MaterialLoader extends Loader { } - // Deprecated - - if ( json.shading !== undefined ) material.flatShading = json.shading === 1; // THREE.FlatShading - // for PointsMaterial if ( json.size !== undefined ) material.size = json.size; diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 9a1de2185efbea..b518159a576f34 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -101,6 +101,8 @@ class ObjectLoader extends Loader { if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) { + if ( onError !== undefined ) onError( new Error( 'THREE.ObjectLoader: Can\'t load ' + url ) ); + console.error( 'THREE.ObjectLoader: Can\'t load ' + url ); return; @@ -275,13 +277,6 @@ class ObjectLoader extends Loader { case 'InstancedBufferGeometry': geometry = bufferGeometryLoader.parse( data ); - - break; - - case 'Geometry': - - console.error( 'THREE.ObjectLoader: The legacy Geometry type is no longer supported.' ); - break; default: @@ -327,40 +322,14 @@ class ObjectLoader extends Loader { const data = json[ i ]; - if ( data.type === 'MultiMaterial' ) { - - // Deprecated - - const array = []; - - for ( let j = 0; j < data.materials.length; j ++ ) { - - const material = data.materials[ j ]; - - if ( cache[ material.uuid ] === undefined ) { - - cache[ material.uuid ] = loader.parse( material ); - - } - - array.push( cache[ material.uuid ] ); - - } - - materials[ data.uuid ] = array; - - } else { + if ( cache[ data.uuid ] === undefined ) { - if ( cache[ data.uuid ] === undefined ) { - - cache[ data.uuid ] = loader.parse( data ); - - } - - materials[ data.uuid ] = cache[ data.uuid ]; + cache[ data.uuid ] = loader.parse( data ); } + materials[ data.uuid ] = cache[ data.uuid ]; + } } @@ -813,6 +782,8 @@ class ObjectLoader extends Loader { } + if ( data.backgroundBlurriness !== undefined ) object.backgroundBlurriness = data.backgroundBlurriness; + break; case 'PerspectiveCamera': @@ -1047,7 +1018,7 @@ class ObjectLoader extends Loader { if ( child !== undefined ) { - object.addLevel( child, level.distance ); + object.addLevel( child, level.distance, level.hysteresis ); } diff --git a/src/materials/Material.js b/src/materials/Material.js index 1a2760c5403518..80b7b5e0721bb4 100644 --- a/src/materials/Material.js +++ b/src/materials/Material.js @@ -1,5 +1,5 @@ import { EventDispatcher } from '../core/EventDispatcher.js'; -import { FrontSide, FlatShading, NormalBlending, LessEqualDepth, AddEquation, OneMinusSrcAlphaFactor, SrcAlphaFactor, AlwaysStencilFunc, KeepStencilOp } from '../constants.js'; +import { FrontSide, NormalBlending, LessEqualDepth, AddEquation, OneMinusSrcAlphaFactor, SrcAlphaFactor, AlwaysStencilFunc, KeepStencilOp } from '../constants.js'; import * as MathUtils from '../math/MathUtils.js'; let materialId = 0; @@ -122,15 +122,6 @@ class Material extends EventDispatcher { } - // for backward compatibility if shading is set in the constructor - if ( key === 'shading' ) { - - console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); - this.flatShading = ( newValue === FlatShading ) ? true : false; - continue; - - } - const currentValue = this[ key ]; if ( currentValue === undefined ) { @@ -309,7 +300,7 @@ class Material extends EventDispatcher { if ( this.transmissionMap && this.transmissionMap.isTexture ) data.transmissionMap = this.transmissionMap.toJSON( meta ).uuid; if ( this.thickness !== undefined ) data.thickness = this.thickness; if ( this.thicknessMap && this.thicknessMap.isTexture ) data.thicknessMap = this.thicknessMap.toJSON( meta ).uuid; - if ( this.attenuationDistance !== undefined ) data.attenuationDistance = this.attenuationDistance; + if ( this.attenuationDistance !== undefined && this.attenuationDistance !== Infinity ) data.attenuationDistance = this.attenuationDistance; if ( this.attenuationColor !== undefined ) data.attenuationColor = this.attenuationColor.getHex(); if ( this.size !== undefined ) data.size = this.size; diff --git a/src/materials/MeshLambertMaterial.js b/src/materials/MeshLambertMaterial.js index cb17537a4564b0..a7c3b05053b85c 100644 --- a/src/materials/MeshLambertMaterial.js +++ b/src/materials/MeshLambertMaterial.js @@ -1,5 +1,6 @@ +import { MultiplyOperation, TangentSpaceNormalMap } from '../constants.js'; import { Material } from './Material.js'; -import { MultiplyOperation } from '../constants.js'; +import { Vector2 } from '../math/Vector2.js'; import { Color } from '../math/Color.js'; class MeshLambertMaterial extends Material { @@ -26,6 +27,17 @@ class MeshLambertMaterial extends Material { 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; @@ -40,6 +52,8 @@ class MeshLambertMaterial extends Material { this.wireframeLinecap = 'round'; this.wireframeLinejoin = 'round'; + this.flatShading = false; + this.fog = true; this.setValues( parameters ); @@ -64,6 +78,17 @@ class MeshLambertMaterial extends Material { 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; @@ -78,6 +103,8 @@ class MeshLambertMaterial extends Material { this.wireframeLinecap = source.wireframeLinecap; this.wireframeLinejoin = source.wireframeLinejoin; + this.flatShading = source.flatShading; + this.fog = source.fog; return this; diff --git a/src/materials/MeshPhysicalMaterial.js b/src/materials/MeshPhysicalMaterial.js index 45292a20fa0763..b3fb4c5d910e20 100644 --- a/src/materials/MeshPhysicalMaterial.js +++ b/src/materials/MeshPhysicalMaterial.js @@ -55,7 +55,7 @@ class MeshPhysicalMaterial extends MeshStandardMaterial { this.thickness = 0; this.thicknessMap = null; - this.attenuationDistance = 0.0; + this.attenuationDistance = Infinity; this.attenuationColor = new Color( 1, 1, 1 ); this.specularIntensity = 1.0; diff --git a/src/materials/ShaderMaterial.js b/src/materials/ShaderMaterial.js index faeba00fd76652..1a856e6a609a2d 100644 --- a/src/materials/ShaderMaterial.js +++ b/src/materials/ShaderMaterial.js @@ -52,12 +52,6 @@ class ShaderMaterial extends Material { if ( parameters !== undefined ) { - if ( parameters.attributes !== undefined ) { - - console.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' ); - - } - this.setValues( parameters ); } diff --git a/src/math/Color.js b/src/math/Color.js index e2c45f974fd386..80f8140ebd9763 100644 --- a/src/math/Color.js +++ b/src/math/Color.js @@ -1,6 +1,6 @@ import { clamp, euclideanModulo, lerp } from './MathUtils.js'; import { ColorManagement, SRGBToLinear, LinearToSRGB } from './ColorManagement.js'; -import { SRGBColorSpace, LinearSRGBColorSpace } from '../constants.js'; +import { SRGBColorSpace } from '../constants.js'; const _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF, 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2, @@ -117,7 +117,7 @@ class Color { } - setRGB( r, g, b, colorSpace = LinearSRGBColorSpace ) { + setRGB( r, g, b, colorSpace = ColorManagement.workingColorSpace ) { this.r = r; this.g = g; @@ -129,7 +129,7 @@ class Color { } - setHSL( h, s, l, colorSpace = LinearSRGBColorSpace ) { + setHSL( h, s, l, colorSpace = ColorManagement.workingColorSpace ) { // h,s,l ranges are in 0.0 - 1.0 h = euclideanModulo( h, 1 ); @@ -222,12 +222,12 @@ class Color { case 'hsl': case 'hsla': - if ( color = /^\s*(\d*\.?\d+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) { + if ( color = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) { // hsl(120,50%,50%) hsla(120,50%,50%,0.5) const h = parseFloat( color[ 1 ] ) / 360; - const s = parseInt( color[ 2 ], 10 ) / 100; - const l = parseInt( color[ 3 ], 10 ) / 100; + const s = parseFloat( color[ 2 ] ) / 100; + const l = parseFloat( color[ 3 ] ) / 100; handleAlpha( color[ 4 ] ); @@ -369,7 +369,7 @@ class Color { } - getHSL( target, colorSpace = LinearSRGBColorSpace ) { + getHSL( target, colorSpace = ColorManagement.workingColorSpace ) { // h,s,l ranges are in 0.0 - 1.0 @@ -414,7 +414,7 @@ class Color { } - getRGB( target, colorSpace = LinearSRGBColorSpace ) { + getRGB( target, colorSpace = ColorManagement.workingColorSpace ) { ColorManagement.fromWorkingColorSpace( toComponents( this, _rgb ), colorSpace ); @@ -580,16 +580,6 @@ class Color { this.g = attribute.getY( index ); this.b = attribute.getZ( index ); - if ( attribute.normalized === true ) { - - // assuming Uint8Array - - this.r /= 255; - this.g /= 255; - this.b /= 255; - - } - return this; } diff --git a/src/math/Matrix3.js b/src/math/Matrix3.js index fac26d2823d739..134b59efe9ac26 100644 --- a/src/math/Matrix3.js +++ b/src/math/Matrix3.js @@ -231,12 +231,11 @@ class Matrix3 { } - scale( sx, sy ) { + // - const te = this.elements; + scale( sx, sy ) { - te[ 0 ] *= sx; te[ 3 ] *= sx; te[ 6 ] *= sx; - te[ 1 ] *= sy; te[ 4 ] *= sy; te[ 7 ] *= sy; + this.premultiply( _m3.makeScale( sx, sy ) ); return this; @@ -244,37 +243,71 @@ class Matrix3 { rotate( theta ) { + this.premultiply( _m3.makeRotation( - theta ) ); + + return this; + + } + + translate( tx, ty ) { + + this.premultiply( _m3.makeTranslation( tx, ty ) ); + + return this; + + } + + // for 2D Transforms + + makeTranslation( x, y ) { + + this.set( + + 1, 0, x, + 0, 1, y, + 0, 0, 1 + + ); + + return this; + + } + + makeRotation( theta ) { + + // counterclockwise + const c = Math.cos( theta ); const s = Math.sin( theta ); - const te = this.elements; - - const a11 = te[ 0 ], a12 = te[ 3 ], a13 = te[ 6 ]; - const a21 = te[ 1 ], a22 = te[ 4 ], a23 = te[ 7 ]; + this.set( - te[ 0 ] = c * a11 + s * a21; - te[ 3 ] = c * a12 + s * a22; - te[ 6 ] = c * a13 + s * a23; + c, - s, 0, + s, c, 0, + 0, 0, 1 - te[ 1 ] = - s * a11 + c * a21; - te[ 4 ] = - s * a12 + c * a22; - te[ 7 ] = - s * a13 + c * a23; + ); return this; } - translate( tx, ty ) { + makeScale( x, y ) { - const te = this.elements; + this.set( - 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 ]; + x, 0, 0, + 0, y, 0, + 0, 0, 1 + + ); return this; } + // + equals( matrix ) { const te = this.elements; @@ -330,4 +363,6 @@ class Matrix3 { } +const _m3 = /*@__PURE__*/ new Matrix3(); + export { Matrix3 }; diff --git a/src/math/Quaternion.js b/src/math/Quaternion.js index 6a0127594f7f72..3d67435c32721b 100644 --- a/src/math/Quaternion.js +++ b/src/math/Quaternion.js @@ -200,12 +200,6 @@ class Quaternion { setFromEuler( euler, update ) { - if ( ! ( euler && euler.isEuler ) ) { - - throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' ); - - } - const x = euler._x, y = euler._y, z = euler._z, order = euler._order; // http://www.mathworks.com/matlabcentral/fileexchange/ diff --git a/src/math/Ray.js b/src/math/Ray.js index ad6c42a2b920b8..4544c904ca6862 100644 --- a/src/math/Ray.js +++ b/src/math/Ray.js @@ -356,12 +356,9 @@ class Ray { 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 || isNaN( tmin ) ) tmin = tymin; - if ( tymin > tmin || tmin !== tmin ) tmin = tymin; - - if ( tymax < tmax || tmax !== tmax ) tmax = tymax; + if ( tymax < tmax || isNaN( tmax ) ) tmax = tymax; if ( invdirz >= 0 ) { diff --git a/src/math/Sphere.js b/src/math/Sphere.js index b9f7ca12211a5d..64a60e30da1d05 100644 --- a/src/math/Sphere.js +++ b/src/math/Sphere.js @@ -3,8 +3,7 @@ import { Vector3 } from './Vector3.js'; const _box = /*@__PURE__*/ new Box3(); const _v1 = /*@__PURE__*/ new Vector3(); -const _toFarthestPoint = /*@__PURE__*/ new Vector3(); -const _toPoint = /*@__PURE__*/ new Vector3(); +const _v2 = /*@__PURE__*/ new Vector3(); class Sphere { @@ -161,23 +160,31 @@ class Sphere { expandByPoint( point ) { - // from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L649-L671 + if ( this.isEmpty() ) { + + this.center.copy( point ); + + this.radius = 0; - _toPoint.subVectors( point, this.center ); + return this; + + } - const lengthSq = _toPoint.lengthSq(); + _v1.subVectors( point, this.center ); + + const lengthSq = _v1.lengthSq(); if ( lengthSq > ( this.radius * this.radius ) ) { + // calculate the minimal sphere + const length = Math.sqrt( lengthSq ); - const missingRadiusHalf = ( length - this.radius ) * 0.5; - // Nudge this sphere towards the target point. Add half the missing distance to radius, - // and the other half to position. This gives a tighter enclosure, instead of if - // the whole missing distance were just added to radius. + const delta = ( length - this.radius ) * 0.5; - this.center.add( _toPoint.multiplyScalar( missingRadiusHalf / length ) ); - this.radius += missingRadiusHalf; + this.center.addScaledVector( _v1, delta / length ); + + this.radius += delta; } @@ -187,25 +194,33 @@ class Sphere { union( sphere ) { - // from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L759-L769 + if ( sphere.isEmpty() ) { + + return this; - // To enclose another sphere into this sphere, we only need to enclose two points: - // 1) Enclose the farthest point on the other sphere into this sphere. - // 2) Enclose the opposite point of the farthest point into this sphere. + } + + if ( this.isEmpty() ) { - if ( this.center.equals( sphere.center ) === true ) { + this.copy( sphere ); - _toFarthestPoint.set( 0, 0, 1 ).multiplyScalar( sphere.radius ); + return this; + + } + if ( this.center.equals( sphere.center ) === true ) { + + this.radius = Math.max( this.radius, sphere.radius ); } else { - _toFarthestPoint.subVectors( sphere.center, this.center ).normalize().multiplyScalar( sphere.radius ); + _v2.subVectors( sphere.center, this.center ).setLength( sphere.radius ); - } + this.expandByPoint( _v1.copy( sphere.center ).add( _v2 ) ); - this.expandByPoint( _v1.copy( sphere.center ).add( _toFarthestPoint ) ); - this.expandByPoint( _v1.copy( sphere.center ).sub( _toFarthestPoint ) ); + this.expandByPoint( _v1.copy( sphere.center ).sub( _v2 ) ); + + } return this; diff --git a/src/objects/InstancedMesh.js b/src/objects/InstancedMesh.js index 05565fa04e33be..e1c842bc633b0c 100644 --- a/src/objects/InstancedMesh.js +++ b/src/objects/InstancedMesh.js @@ -7,6 +7,7 @@ const _instanceWorldMatrix = /*@__PURE__*/ new Matrix4(); const _instanceIntersects = []; +const _identity = /*@__PURE__*/ new Matrix4(); const _mesh = /*@__PURE__*/ new Mesh(); class InstancedMesh extends Mesh { @@ -24,6 +25,12 @@ class InstancedMesh extends Mesh { this.frustumCulled = false; + for ( let i = 0; i < count; i ++ ) { + + this.setMatrixAt( i, _identity ); + + } + } copy( source, recursive ) { diff --git a/src/objects/LOD.js b/src/objects/LOD.js index 6c7a37619bccc9..08fbc102222284 100644 --- a/src/objects/LOD.js +++ b/src/objects/LOD.js @@ -38,7 +38,7 @@ class LOD extends Object3D { const level = levels[ i ]; - this.addLevel( level.object.clone(), level.distance ); + this.addLevel( level.object.clone(), level.distance, level.hysteresis ); } @@ -48,7 +48,7 @@ class LOD extends Object3D { } - addLevel( object, distance = 0 ) { + addLevel( object, distance = 0, hysteresis = 0 ) { distance = Math.abs( distance ); @@ -66,7 +66,7 @@ class LOD extends Object3D { } - levels.splice( l, 0, { distance: distance, object: object } ); + levels.splice( l, 0, { distance: distance, hysteresis: hysteresis, object: object } ); this.add( object ); @@ -80,6 +80,8 @@ class LOD extends Object3D { } + + getObjectForDistance( distance ) { const levels = this.levels; @@ -90,7 +92,15 @@ class LOD extends Object3D { for ( i = 1, l = levels.length; i < l; i ++ ) { - if ( distance < levels[ i ].distance ) { + let levelDistance = levels[ i ].distance; + + if ( levels[ i ].object.visible ) { + + levelDistance -= levelDistance * levels[ i ].hysteresis; + + } + + if ( distance < levelDistance ) { break; @@ -139,7 +149,15 @@ class LOD extends Object3D { for ( i = 1, l = levels.length; i < l; i ++ ) { - if ( distance >= levels[ i ].distance ) { + let levelDistance = levels[ i ].distance; + + if ( levels[ i ].object.visible ) { + + levelDistance -= levelDistance * levels[ i ].hysteresis; + + } + + if ( distance >= levelDistance ) { levels[ i - 1 ].object.visible = false; levels[ i ].object.visible = true; @@ -180,7 +198,8 @@ class LOD extends Object3D { data.object.levels.push( { object: level.object.uuid, - distance: level.distance + distance: level.distance, + hysteresis: level.hysteresis } ); } diff --git a/src/renderers/WebGL3DRenderTarget.js b/src/renderers/WebGL3DRenderTarget.js index 5b78f42bc2ce04..2d0727f272d909 100644 --- a/src/renderers/WebGL3DRenderTarget.js +++ b/src/renderers/WebGL3DRenderTarget.js @@ -3,7 +3,7 @@ import { Data3DTexture } from '../textures/Data3DTexture.js'; class WebGL3DRenderTarget extends WebGLRenderTarget { - constructor( width, height, depth ) { + constructor( width = 1, height = 1, depth = 1 ) { super( width, height ); diff --git a/src/renderers/WebGLArrayRenderTarget.js b/src/renderers/WebGLArrayRenderTarget.js index 4f63411383b364..a968ec2ed529a8 100644 --- a/src/renderers/WebGLArrayRenderTarget.js +++ b/src/renderers/WebGLArrayRenderTarget.js @@ -3,7 +3,7 @@ import { DataArrayTexture } from '../textures/DataArrayTexture.js'; class WebGLArrayRenderTarget extends WebGLRenderTarget { - constructor( width, height, depth ) { + constructor( width = 1, height = 1, depth = 1 ) { super( width, height ); diff --git a/src/renderers/WebGLCubeRenderTarget.js b/src/renderers/WebGLCubeRenderTarget.js index a5a7dddc22f051..3f22ea365f7cda 100644 --- a/src/renderers/WebGLCubeRenderTarget.js +++ b/src/renderers/WebGLCubeRenderTarget.js @@ -9,7 +9,7 @@ import { CubeTexture } from '../textures/CubeTexture.js'; class WebGLCubeRenderTarget extends WebGLRenderTarget { - constructor( size, options = {} ) { + constructor( size = 1, options = {} ) { super( size, size, options ); diff --git a/src/renderers/WebGLMultipleRenderTargets.js b/src/renderers/WebGLMultipleRenderTargets.js index 01613215e95d51..9d453a3337ab29 100644 --- a/src/renderers/WebGLMultipleRenderTargets.js +++ b/src/renderers/WebGLMultipleRenderTargets.js @@ -2,7 +2,7 @@ import { WebGLRenderTarget } from './WebGLRenderTarget.js'; class WebGLMultipleRenderTargets extends WebGLRenderTarget { - constructor( width, height, count, options = {} ) { + constructor( width = 1, height = 1, count = 1, options = {} ) { super( width, height, options ); diff --git a/src/renderers/WebGLRenderTarget.js b/src/renderers/WebGLRenderTarget.js index 346dc092aedf6b..a6df80e99620b1 100644 --- a/src/renderers/WebGLRenderTarget.js +++ b/src/renderers/WebGLRenderTarget.js @@ -11,7 +11,7 @@ import { Source } from '../textures/Source.js'; */ class WebGLRenderTarget extends EventDispatcher { - constructor( width, height, options = {} ) { + constructor( width = 1, height = 1, options = {} ) { super(); diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 2a967ff00fc0ea..cc400ea83b6e61 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -134,28 +134,6 @@ function WebGLRenderer( parameters = {} ) { this.toneMapping = NoToneMapping; this.toneMappingExposure = 1.0; - // - - Object.defineProperties( this, { - - // @deprecated since r136, 0e21088102b4de7e0a0a33140620b7a3424b9e6d - - gammaFactor: { - get: function () { - - console.warn( 'THREE.WebGLRenderer: .gammaFactor has been removed.' ); - return 2; - - }, - set: function () { - - console.warn( 'THREE.WebGLRenderer: .gammaFactor has been removed.' ); - - } - } - - } ); - // internal properties const _this = this; @@ -337,7 +315,7 @@ function WebGLRenderer( parameters = {} ) { materials = new WebGLMaterials( _this, properties ); renderLists = new WebGLRenderLists(); renderStates = new WebGLRenderStates( extensions, capabilities ); - background = new WebGLBackground( _this, cubemaps, state, objects, _alpha, _premultipliedAlpha ); + background = new WebGLBackground( _this, cubemaps, cubeuvmaps, state, objects, _alpha, _premultipliedAlpha ); shadowMap = new WebGLShadowMap( _this, objects, capabilities ); uniformsGroups = new WebGLUniformsGroups( _gl, info, capabilities, state ); @@ -722,31 +700,48 @@ function WebGLRenderer( parameters = {} ) { // let index = geometry.index; - const position = geometry.attributes.position; + let rangeFactor = 1; + + if ( material.wireframe === true ) { + + index = geometries.getWireframeAttribute( geometry ); + rangeFactor = 2; + + } // - if ( index === null ) { + const drawRange = geometry.drawRange; + const position = geometry.attributes.position; - if ( position === undefined || position.count === 0 ) return; + let drawStart = drawRange.start * rangeFactor; + let drawEnd = ( drawRange.start + drawRange.count ) * rangeFactor; - } else if ( index.count === 0 ) { + if ( group !== null ) { - return; + drawStart = Math.max( drawStart, group.start * rangeFactor ); + drawEnd = Math.min( drawEnd, ( group.start + group.count ) * rangeFactor ); } - // + if ( index !== null ) { - let rangeFactor = 1; + drawStart = Math.max( drawStart, 0 ); + drawEnd = Math.min( drawEnd, index.count ); - if ( material.wireframe === true ) { + } else if ( position !== undefined && position !== null ) { - index = geometries.getWireframeAttribute( geometry ); - rangeFactor = 2; + drawStart = Math.max( drawStart, 0 ); + drawEnd = Math.min( drawEnd, position.count ); } + const drawCount = drawEnd - drawStart; + + if ( drawCount < 0 || drawCount === Infinity ) return; + + // + bindingStates.setup( object, material, program, geometry, index ); let attribute; @@ -763,23 +758,6 @@ function WebGLRenderer( parameters = {} ) { // - const dataCount = ( index !== null ) ? index.count : position.count; - - const rangeStart = geometry.drawRange.start * rangeFactor; - const rangeCount = geometry.drawRange.count * rangeFactor; - - const groupStart = group !== null ? group.start * rangeFactor : 0; - const groupCount = group !== null ? group.count * rangeFactor : Infinity; - - const drawStart = Math.max( rangeStart, groupStart ); - const drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1; - - const drawCount = Math.max( 0, drawEnd - drawStart + 1 ); - - if ( drawCount === 0 ) return; - - // - if ( object.isMesh ) { if ( material.wireframe === true ) { @@ -831,7 +809,8 @@ function WebGLRenderer( parameters = {} ) { } else if ( geometry.isInstancedBufferGeometry ) { - const instanceCount = Math.min( geometry.instanceCount, geometry._maxInstanceCount ); + const maxInstanceCount = geometry._maxInstanceCount !== undefined ? geometry._maxInstanceCount : Infinity; + const instanceCount = Math.min( geometry.instanceCount, maxInstanceCount ); renderer.renderInstances( drawStart, drawCount, instanceCount ); @@ -847,6 +826,28 @@ function WebGLRenderer( parameters = {} ) { this.compile = function ( scene, camera ) { + function prepare( material, scene, object ) { + + if ( material.transparent === true && material.side === DoubleSide ) { + + material.side = BackSide; + material.needsUpdate = true; + getProgram( material, scene, object ); + + material.side = FrontSide; + material.needsUpdate = true; + getProgram( material, scene, object ); + + material.side = DoubleSide; + + } else { + + getProgram( material, scene, object ); + + } + + } + currentRenderState = renderStates.get( scene ); currentRenderState.init(); @@ -882,13 +883,13 @@ function WebGLRenderer( parameters = {} ) { const material2 = material[ i ]; - getProgram( material2, scene, object ); + prepare( material2, scene, object ); } } else { - getProgram( material, scene, object ); + prepare( material, scene, object ); } @@ -955,11 +956,11 @@ function WebGLRenderer( parameters = {} ) { // update scene graph - if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); + if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld(); // update camera matrices and frustum - if ( camera.parent === null ) camera.updateMatrixWorld(); + if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld(); if ( xr.enabled === true && xr.isPresenting === true ) { @@ -1428,7 +1429,8 @@ function WebGLRenderer( parameters = {} ) { 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.spotLightMatrix.value = lights.state.spotLightMatrix; + uniforms.spotLightMap.value = lights.state.spotLightMap; uniforms.pointShadowMap.value = lights.state.pointShadowMap; uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; // TODO (abelnation): add area lights shadow info to uniforms @@ -1726,7 +1728,6 @@ function WebGLRenderer( parameters = {} ) { } - if ( refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow ) { materialProperties.receiveShadow = object.receiveShadow; @@ -1734,6 +1735,16 @@ function WebGLRenderer( parameters = {} ) { } + // https://github.com/mrdoob/three.js/pull/24467#issuecomment-1209031512 + + if ( material.isMeshGouraudMaterial && material.envMap !== null ) { + + m_uniforms.envMap.value = envMap; + + m_uniforms.flipEnvMap.value = ( envMap.isCubeTexture && envMap.isRenderTargetTexture === false ) ? - 1 : 1; + + } + if ( refreshMaterial ) { p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure ); @@ -1903,6 +1914,9 @@ function WebGLRenderer( parameters = {} ) { _currentActiveMipmapLevel = activeMipmapLevel; let useDefaultFramebuffer = true; + let framebuffer = null; + let isCube = false; + let isRenderTarget3D = false; if ( renderTarget ) { @@ -1925,17 +1939,9 @@ function WebGLRenderer( parameters = {} ) { } - } - - let framebuffer = null; - let isCube = false; - let isRenderTarget3D = false; - - if ( renderTarget ) { - const texture = renderTarget.texture; - if ( texture.isData3DTexture || texture.isDataArrayTexture ) { + if ( texture.isData3DTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture ) { isRenderTarget3D = true; @@ -2176,7 +2182,7 @@ function WebGLRenderer( parameters = {} ) { } else { - if ( srcTexture.isCompressedTexture ) { + if ( srcTexture.isCompressedArrayTexture ) { console.warn( 'THREE.WebGLRenderer.copyTextureToTexture3D: untested support for compressed srcTexture.' ); _gl.compressedTexSubImage3D( glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, image.data ); @@ -2212,7 +2218,7 @@ function WebGLRenderer( parameters = {} ) { textures.setTexture3D( texture, 0 ); - } else if ( texture.isDataArrayTexture ) { + } else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) { textures.setTexture2DArray( texture, 0 ); diff --git a/src/renderers/shaders/ShaderChunk.js b/src/renderers/shaders/ShaderChunk.js index a6053380bca1b9..e8435e4359944a 100644 --- a/src/renderers/shaders/ShaderChunk.js +++ b/src/renderers/shaders/ShaderChunk.js @@ -38,7 +38,8 @@ import fog_pars_fragment from './ShaderChunk/fog_pars_fragment.glsl.js'; import gradientmap_pars_fragment from './ShaderChunk/gradientmap_pars_fragment.glsl.js'; import lightmap_fragment from './ShaderChunk/lightmap_fragment.glsl.js'; import lightmap_pars_fragment from './ShaderChunk/lightmap_pars_fragment.glsl.js'; -import lights_lambert_vertex from './ShaderChunk/lights_lambert_vertex.glsl.js'; +import lights_lambert_fragment from './ShaderChunk/lights_lambert_fragment.glsl.js'; +import lights_lambert_pars_fragment from './ShaderChunk/lights_lambert_pars_fragment.glsl.js'; import lights_pars_begin from './ShaderChunk/lights_pars_begin.glsl.js'; import envmap_physical_pars_fragment from './ShaderChunk/envmap_physical_pars_fragment.glsl.js'; import lights_toon_fragment from './ShaderChunk/lights_toon_fragment.glsl.js'; @@ -105,6 +106,7 @@ import uv2_vertex from './ShaderChunk/uv2_vertex.glsl.js'; import worldpos_vertex from './ShaderChunk/worldpos_vertex.glsl.js'; import * as background from './ShaderLib/background.glsl.js'; +import * as backgroundCube from './ShaderLib/backgroundCube.glsl.js'; import * as cube from './ShaderLib/cube.glsl.js'; import * as depth from './ShaderLib/depth.glsl.js'; import * as distanceRGBA from './ShaderLib/distanceRGBA.glsl.js'; @@ -163,7 +165,8 @@ export const ShaderChunk = { gradientmap_pars_fragment: gradientmap_pars_fragment, lightmap_fragment: lightmap_fragment, lightmap_pars_fragment: lightmap_pars_fragment, - lights_lambert_vertex: lights_lambert_vertex, + lights_lambert_fragment: lights_lambert_fragment, + lights_lambert_pars_fragment: lights_lambert_pars_fragment, lights_pars_begin: lights_pars_begin, lights_toon_fragment: lights_toon_fragment, lights_toon_pars_fragment: lights_toon_pars_fragment, @@ -230,6 +233,8 @@ export const ShaderChunk = { background_vert: background.vertex, background_frag: background.fragment, + backgroundCube_vert: backgroundCube.vertex, + backgroundCube_frag: backgroundCube.fragment, cube_vert: cube.vertex, cube_frag: cube.fragment, depth_vert: depth.vertex, diff --git a/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl.js index 1753cc8f736971..3826e9296642de 100644 --- a/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl.js @@ -118,41 +118,41 @@ export default /* glsl */` // These defines must match with PMREMGenerator - #define r0 1.0 - #define v0 0.339 - #define m0 - 2.0 - #define r1 0.8 - #define v1 0.276 - #define m1 - 1.0 - #define r4 0.4 - #define v4 0.046 - #define m4 2.0 - #define r5 0.305 - #define v5 0.016 - #define m5 3.0 - #define r6 0.21 - #define v6 0.0038 - #define m6 4.0 + #define cubeUV_r0 1.0 + #define cubeUV_v0 0.339 + #define cubeUV_m0 - 2.0 + #define cubeUV_r1 0.8 + #define cubeUV_v1 0.276 + #define cubeUV_m1 - 1.0 + #define cubeUV_r4 0.4 + #define cubeUV_v4 0.046 + #define cubeUV_m4 2.0 + #define cubeUV_r5 0.305 + #define cubeUV_v5 0.016 + #define cubeUV_m5 3.0 + #define cubeUV_r6 0.21 + #define cubeUV_v6 0.0038 + #define cubeUV_m6 4.0 float roughnessToMip( float roughness ) { float mip = 0.0; - if ( roughness >= r1 ) { + if ( roughness >= cubeUV_r1 ) { - mip = ( r0 - roughness ) * ( m1 - m0 ) / ( r0 - r1 ) + m0; + mip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0; - } else if ( roughness >= r4 ) { + } else if ( roughness >= cubeUV_r4 ) { - mip = ( r1 - roughness ) * ( m4 - m1 ) / ( r1 - r4 ) + m1; + mip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1; - } else if ( roughness >= r5 ) { + } else if ( roughness >= cubeUV_r5 ) { - mip = ( r4 - roughness ) * ( m5 - m4 ) / ( r4 - r5 ) + m4; + mip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4; - } else if ( roughness >= r6 ) { + } else if ( roughness >= cubeUV_r6 ) { - mip = ( r5 - roughness ) * ( m6 - m5 ) / ( r5 - r6 ) + m5; + mip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_m5; } else { @@ -165,7 +165,7 @@ export default /* glsl */` vec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) { - float mip = clamp( roughnessToMip( roughness ), m0, CUBEUV_MAX_MIP ); + float mip = clamp( roughnessToMip( roughness ), cubeUV_m0, CUBEUV_MAX_MIP ); float mipF = fract( mip ); diff --git a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js index 79454ff567aab8..ff441025c8270c 100644 --- a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js @@ -38,10 +38,6 @@ export default /* glsl */` vec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) ); - #elif defined( ENVMAP_TYPE_CUBE_UV ) - - vec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 ); - #else vec4 envColor = vec4( 0.0 ); diff --git a/src/renderers/shaders/ShaderChunk/envmap_pars_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/envmap_pars_fragment.glsl.js index a8e8e1c6b0dd92..17ffaaf295965a 100644 --- a/src/renderers/shaders/ShaderChunk/envmap_pars_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/envmap_pars_fragment.glsl.js @@ -3,7 +3,7 @@ export default /* glsl */` uniform float reflectivity; - #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) + #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT ) #define ENV_WORLDPOS diff --git a/src/renderers/shaders/ShaderChunk/envmap_pars_vertex.glsl.js b/src/renderers/shaders/ShaderChunk/envmap_pars_vertex.glsl.js index 6932df497ac759..6d13f230976e18 100644 --- a/src/renderers/shaders/ShaderChunk/envmap_pars_vertex.glsl.js +++ b/src/renderers/shaders/ShaderChunk/envmap_pars_vertex.glsl.js @@ -1,7 +1,7 @@ export default /* glsl */` #ifdef USE_ENVMAP - #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG ) + #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT ) #define ENV_WORLDPOS diff --git a/src/renderers/shaders/ShaderChunk/gradientmap_pars_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/gradientmap_pars_fragment.glsl.js index 8188d37fe1ef1b..a2ac095c419157 100644 --- a/src/renderers/shaders/ShaderChunk/gradientmap_pars_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/gradientmap_pars_fragment.glsl.js @@ -18,7 +18,8 @@ vec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) { #else - return ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 ); + vec2 fw = fwidth( coord ) * 0.5; + return mix( vec3( 0.7 ), vec3( 1.0 ), smoothstep( 0.7 - fw.x, 0.7 + fw.x, coord.x ) ); #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js b/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js index 0c7993835cbdfe..bf1742d172d6d4 100644 --- a/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +++ b/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js @@ -5,7 +5,6 @@ export default /* glsl */` * * Instructions for use: * - Ensure that both RE_Direct, RE_IndirectDiffuse and RE_IndirectSpecular are defined - * - If you have defined an RE_IndirectSpecular, you need to also provide a Material_LightProbeLOD. <---- ??? * - Create a material parameter that is to be passed as the third parameter to your lighting functions. * * TODO: @@ -82,6 +81,10 @@ IncidentLight directLight; #if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct ) SpotLight spotLight; + vec4 spotColor; + vec3 spotLightCoord; + bool inSpotLightMap; + #if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0 SpotLightShadow spotLightShadow; #endif @@ -93,9 +96,27 @@ IncidentLight directLight; getSpotLightInfo( spotLight, geometry, directLight ); + // spot lights are ordered [shadows with maps, shadows without maps, maps without shadows, none] + #if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS ) + #define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX + #elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS ) + #define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS + #else + #define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS ) + #endif + + #if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS ) + spotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w; + inSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) ); + spotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy ); + directLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color; + #endif + + #undef SPOT_LIGHT_MAP_INDEX + #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS ) spotLightShadow = spotLightShadows[ i ]; - directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0; + directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0; #endif RE_Direct( directLight, geometry, material, reflectedLight ); diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/lights_lambert_fragment.glsl.js new file mode 100644 index 00000000000000..52e3640dbc212b --- /dev/null +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_fragment.glsl.js @@ -0,0 +1,5 @@ +export default /* glsl */` +LambertMaterial material; +material.diffuseColor = diffuseColor.rgb; +material.specularStrength = specularStrength; +`; diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_pars_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/lights_lambert_pars_fragment.glsl.js new file mode 100644 index 00000000000000..2e1c4e7ac68e9b --- /dev/null +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_pars_fragment.glsl.js @@ -0,0 +1,28 @@ +export default /* glsl */` +varying vec3 vViewPosition; + +struct LambertMaterial { + + vec3 diffuseColor; + float specularStrength; + +}; + +void RE_Direct_Lambert( const in IncidentLight directLight, const in GeometricContext geometry, const in LambertMaterial material, inout ReflectedLight reflectedLight ) { + + float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); + vec3 irradiance = dotNL * directLight.color; + + reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); + +} + +void RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in GeometricContext geometry, const in LambertMaterial material, inout ReflectedLight reflectedLight ) { + + reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); + +} + +#define RE_Direct RE_Direct_Lambert +#define RE_IndirectDiffuse RE_IndirectDiffuse_Lambert +`; diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl.js b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl.js deleted file mode 100644 index d90246a7dd5b0a..00000000000000 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl.js +++ /dev/null @@ -1,122 +0,0 @@ -export default /* glsl */` -vec3 diffuse = vec3( 1.0 ); - -GeometricContext geometry; -geometry.position = mvPosition.xyz; -geometry.normal = normalize( transformedNormal ); -geometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz ); - -GeometricContext backGeometry; -backGeometry.position = geometry.position; -backGeometry.normal = -geometry.normal; -backGeometry.viewDir = geometry.viewDir; - -vLightFront = vec3( 0.0 ); -vIndirectFront = vec3( 0.0 ); -#ifdef DOUBLE_SIDED - vLightBack = vec3( 0.0 ); - vIndirectBack = vec3( 0.0 ); -#endif - -IncidentLight directLight; -float dotNL; -vec3 directLightColor_Diffuse; - -vIndirectFront += getAmbientLightIrradiance( ambientLightColor ); - -vIndirectFront += getLightProbeIrradiance( lightProbe, geometry.normal ); - -#ifdef DOUBLE_SIDED - - vIndirectBack += getAmbientLightIrradiance( ambientLightColor ); - - vIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry.normal ); - -#endif - -#if NUM_POINT_LIGHTS > 0 - - #pragma unroll_loop_start - for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) { - - getPointLightInfo( pointLights[ i ], geometry, directLight ); - - dotNL = dot( geometry.normal, directLight.direction ); - directLightColor_Diffuse = directLight.color; - - vLightFront += saturate( dotNL ) * directLightColor_Diffuse; - - #ifdef DOUBLE_SIDED - - vLightBack += saturate( - dotNL ) * directLightColor_Diffuse; - - #endif - - } - #pragma unroll_loop_end - -#endif - -#if NUM_SPOT_LIGHTS > 0 - - #pragma unroll_loop_start - for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) { - - getSpotLightInfo( spotLights[ i ], geometry, directLight ); - - dotNL = dot( geometry.normal, directLight.direction ); - directLightColor_Diffuse = directLight.color; - - vLightFront += saturate( dotNL ) * directLightColor_Diffuse; - - #ifdef DOUBLE_SIDED - - vLightBack += saturate( - dotNL ) * directLightColor_Diffuse; - - #endif - } - #pragma unroll_loop_end - -#endif - -#if NUM_DIR_LIGHTS > 0 - - #pragma unroll_loop_start - for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) { - - getDirectionalLightInfo( directionalLights[ i ], geometry, directLight ); - - dotNL = dot( geometry.normal, directLight.direction ); - directLightColor_Diffuse = directLight.color; - - vLightFront += saturate( dotNL ) * directLightColor_Diffuse; - - #ifdef DOUBLE_SIDED - - vLightBack += saturate( - dotNL ) * directLightColor_Diffuse; - - #endif - - } - #pragma unroll_loop_end - -#endif - -#if NUM_HEMI_LIGHTS > 0 - - #pragma unroll_loop_start - for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) { - - vIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal ); - - #ifdef DOUBLE_SIDED - - vIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry.normal ); - - #endif - - } - #pragma unroll_loop_end - -#endif -`; diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl.js index 32589cfd3b73d3..47669570e8a718 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl.js @@ -29,6 +29,4 @@ void RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in Geometric #define RE_Direct RE_Direct_BlinnPhong #define RE_IndirectDiffuse RE_IndirectDiffuse_BlinnPhong - -#define Material_LightProbeLOD( material ) (0) `; diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js index ed7b462e43f8ca..33ffd3724bc4ff 100644 --- a/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js @@ -11,6 +11,8 @@ material.roughness = min( material.roughness, 1.0 ); #ifdef IOR + material.ior = ior; + #ifdef SPECULAR float specularIntensityFactor = specularIntensity; @@ -38,7 +40,7 @@ material.roughness = min( material.roughness, 1.0 ); #endif - material.specularColor = mix( min( pow2( ( ior - 1.0 ) / ( ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor ); + material.specularColor = mix( min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor ); #else diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js index efb8f9a3fca233..0af32ea590ed4a 100644 --- a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js @@ -26,6 +26,18 @@ struct PhysicalMaterial { float sheenRoughness; #endif + #ifdef IOR + float ior; + #endif + + #ifdef USE_TRANSMISSION + float transmission; + float transmissionAlpha; + float thickness; + float attenuationDistance; + vec3 attenuationColor; + #endif + }; // temporary @@ -35,7 +47,7 @@ vec3 sheenSpecular = vec3( 0.0 ); // This is a curve-fit approxmation to the "Charlie sheen" BRDF integrated over the hemisphere from // Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF". The analysis can be found // in the Sheen section of https://drive.google.com/file/d/1T0D1VSyR4AllqIJTQAraEIzjlb5h4FKH/view?usp=sharing -float IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness) { +float IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) { float dotNV = saturate( dot( normal, viewDir ) ); diff --git a/src/renderers/shaders/ShaderChunk/lights_toon_pars_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/lights_toon_pars_fragment.glsl.js index da3df5f10eac07..f0e7583fd85f4f 100644 --- a/src/renderers/shaders/ShaderChunk/lights_toon_pars_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/lights_toon_pars_fragment.glsl.js @@ -23,6 +23,4 @@ void RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContex #define RE_Direct RE_Direct_Toon #define RE_IndirectDiffuse RE_IndirectDiffuse_Toon - -#define Material_LightProbeLOD( material ) (0) `; diff --git a/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js b/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js index 77e8fa4553dd6b..fc90fbb58d5fde 100644 --- a/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js +++ b/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js @@ -3,10 +3,8 @@ float faceDirection = gl_FrontFacing ? 1.0 : - 1.0; #ifdef FLAT_SHADED - // Workaround for Adreno GPUs not able to do dFdx( vViewPosition ) - - vec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) ); - vec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) ); + vec3 fdx = dFdx( vViewPosition ); + vec3 fdy = dFdy( vViewPosition ); vec3 normal = normalize( cross( fdx, fdy ) ); #else diff --git a/src/renderers/shaders/ShaderChunk/output_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/output_fragment.glsl.js index 68a0374da66a76..3377354bc8f15d 100644 --- a/src/renderers/shaders/ShaderChunk/output_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/output_fragment.glsl.js @@ -5,7 +5,7 @@ diffuseColor.a = 1.0; // https://github.com/mrdoob/three.js/pull/22425 #ifdef USE_TRANSMISSION -diffuseColor.a *= transmissionAlpha + 0.1; +diffuseColor.a *= material.transmissionAlpha + 0.1; #endif gl_FragColor = vec4( outgoingLight, diffuseColor.a ); diff --git a/src/renderers/shaders/ShaderChunk/packing.glsl.js b/src/renderers/shaders/ShaderChunk/packing.glsl.js index aaa73db069a91a..8bae84e1df6306 100644 --- a/src/renderers/shaders/ShaderChunk/packing.glsl.js +++ b/src/renderers/shaders/ShaderChunk/packing.glsl.js @@ -25,6 +25,14 @@ float unpackRGBAToDepth( const in vec4 v ) { return dot( v, UnpackFactors ); } +vec2 packDepthToRG( in highp float v ) { + return packDepthToRGBA( v ).yx; +} + +float unpackRGToDepth( const in highp vec2 v ) { + return unpackRGBAToDepth( vec4( v.xy, 0.0, 0.0 ) ); +} + vec4 pack2HalfToRGBA( vec2 v ) { vec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) ); return vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w ); diff --git a/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js index b3a14597eeb2e7..30879d3b788506 100644 --- a/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js @@ -1,4 +1,16 @@ export default /* glsl */` +#if NUM_SPOT_LIGHT_COORDS > 0 + + varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ]; + +#endif + +#if NUM_SPOT_LIGHT_MAPS > 0 + + uniform sampler2D spotLightMap[ NUM_SPOT_LIGHT_MAPS ]; + +#endif + #ifdef USE_SHADOWMAP #if NUM_DIR_LIGHT_SHADOWS > 0 @@ -20,7 +32,6 @@ export default /* glsl */` #if NUM_SPOT_LIGHT_SHADOWS > 0 uniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ]; - varying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ]; struct SpotLightShadow { float shadowBias; @@ -159,22 +170,22 @@ export default /* glsl */` texture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) + texture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) + texture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) + - mix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), + mix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ), f.x ) + - mix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), + mix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ), f.x ) + - mix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), + mix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ), f.y ) + - mix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), + mix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ), f.y ) + - mix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), + mix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ), f.x ), - mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), + mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ), f.x ), f.y ) diff --git a/src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl.js b/src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl.js index 96b9280c81e069..76f8995090e690 100644 --- a/src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl.js +++ b/src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl.js @@ -1,4 +1,12 @@ export default /* glsl */` + +#if NUM_SPOT_LIGHT_COORDS > 0 + + uniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ]; + varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ]; + +#endif + #ifdef USE_SHADOWMAP #if NUM_DIR_LIGHT_SHADOWS > 0 @@ -19,9 +27,6 @@ export default /* glsl */` #if NUM_SPOT_LIGHT_SHADOWS > 0 - uniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ]; - varying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ]; - struct SpotLightShadow { float shadowBias; float shadowNormalBias; diff --git a/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js b/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js index 3be5889b66e145..d3334ebd74e01e 100644 --- a/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +++ b/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js @@ -1,7 +1,7 @@ export default /* glsl */` -#ifdef USE_SHADOWMAP +#if defined( USE_SHADOWMAP ) || ( NUM_SPOT_LIGHT_COORDS > 0 ) - #if NUM_DIR_LIGHT_SHADOWS > 0 || NUM_SPOT_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 + #if NUM_DIR_LIGHT_SHADOWS > 0 || NUM_SPOT_LIGHT_COORDS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 // Offsetting the position used for querying occlusion along the world normal can be used to reduce shadow acne. vec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix ); @@ -22,13 +22,16 @@ export default /* glsl */` #endif - #if NUM_SPOT_LIGHT_SHADOWS > 0 + #if NUM_SPOT_LIGHT_COORDS > 0 #pragma unroll_loop_start - for ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) { + for ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) { - shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias, 0 ); - vSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * shadowWorldPosition; + shadowWorldPosition = worldPosition; + #if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS ) + shadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias; + #endif + vSpotLightCoord[ i ] = spotLightMatrix[ i ] * shadowWorldPosition; } #pragma unroll_loop_end diff --git a/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js index 38c8e909150d5d..9c117f126c80cf 100644 --- a/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js @@ -28,7 +28,7 @@ float getShadowMask() { for ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) { spotLight = spotLightShadows[ i ]; - shadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0; + shadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotLightCoord[ i ] ) : 1.0; } #pragma unroll_loop_end diff --git a/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js index 0f97725373ae0a..b5a601233a1da9 100644 --- a/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js @@ -1,19 +1,21 @@ export default /* glsl */` #ifdef USE_TRANSMISSION - float transmissionAlpha = 1.0; - float transmissionFactor = transmission; - float thicknessFactor = thickness; + material.transmission = transmission; + material.transmissionAlpha = 1.0; + material.thickness = thickness; + material.attenuationDistance = attenuationDistance; + material.attenuationColor = attenuationColor; #ifdef USE_TRANSMISSIONMAP - transmissionFactor *= texture2D( transmissionMap, vUv ).r; + material.transmission *= texture2D( transmissionMap, vUv ).r; #endif #ifdef USE_THICKNESSMAP - thicknessFactor *= texture2D( thicknessMap, vUv ).g; + material.thickness *= texture2D( thicknessMap, vUv ).g; #endif @@ -22,11 +24,13 @@ export default /* glsl */` vec3 n = inverseTransformDirection( normal, viewMatrix ); vec4 transmission = getIBLVolumeRefraction( - n, v, roughnessFactor, material.diffuseColor, material.specularColor, material.specularF90, - pos, modelMatrix, viewMatrix, projectionMatrix, ior, thicknessFactor, - attenuationColor, attenuationDistance ); + n, v, material.roughness, material.diffuseColor, material.specularColor, material.specularF90, + pos, modelMatrix, viewMatrix, projectionMatrix, material.ior, material.thickness, + material.attenuationColor, material.attenuationDistance ); + + material.transmissionAlpha = mix( material.transmissionAlpha, transmission.a, material.transmission ); + + totalDiffuse = mix( totalDiffuse, transmission.rgb, material.transmission ); - totalDiffuse = mix( totalDiffuse, transmission.rgb, transmissionFactor ); - transmissionAlpha = mix( transmissionAlpha, transmission.a, transmissionFactor ); #endif `; diff --git a/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js index 74161beae5f5b1..b96e6d3a3b36c1 100644 --- a/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js @@ -71,9 +71,9 @@ export default /* glsl */` vec3 applyVolumeAttenuation( const in vec3 radiance, const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) { - if ( attenuationDistance == 0.0 ) { + if ( isinf( attenuationDistance ) ) { - // Attenuation distance is +∞ (which we indicate by zero), i.e. the transmitted color is not attenuated at all. + // Attenuation distance is +∞, i.e. the transmitted color is not attenuated at all. return radiance; } else { diff --git a/src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl.js b/src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl.js index 3376d0c862a4b7..197295ffd0a8d5 100644 --- a/src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl.js +++ b/src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl.js @@ -1,5 +1,5 @@ export default /* glsl */` -#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) +#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) || NUM_SPOT_LIGHT_COORDS > 0 vec4 worldPosition = vec4( transformed, 1.0 ); diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 489d2269ec7612..3e628c0843d36a 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -33,6 +33,9 @@ const ShaderLib = { UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, UniformsLib.fog, UniformsLib.lights, { @@ -215,6 +218,7 @@ const ShaderLib = { uniforms: { uvTransform: { value: /*@__PURE__*/ new Matrix3() }, t2D: { value: null }, + backgroundIntensity: { value: 1 } }, vertexShader: ShaderChunk.background_vert, @@ -222,14 +226,27 @@ const ShaderLib = { }, + backgroundCube: { + + uniforms: { + envMap: { value: null }, + flipEnvMap: { value: - 1 }, + backgroundBlurriness: { value: 0 }, + backgroundIntensity: { value: 1 } + }, + + vertexShader: ShaderChunk.backgroundCube_vert, + fragmentShader: ShaderChunk.backgroundCube_frag + + }, + cube: { - uniforms: /*@__PURE__*/ mergeUniforms( [ - UniformsLib.envmap, - { - opacity: { value: 1.0 } - } - ] ), + uniforms: { + tCube: { value: null }, + tFlip: { value: - 1 }, + opacity: { value: 1.0 } + }, vertexShader: ShaderChunk.cube_vert, fragmentShader: ShaderChunk.cube_frag diff --git a/src/renderers/shaders/ShaderLib/background.glsl.js b/src/renderers/shaders/ShaderLib/background.glsl.js index 3d93165513f0a8..ec8e8ee34f10ef 100644 --- a/src/renderers/shaders/ShaderLib/background.glsl.js +++ b/src/renderers/shaders/ShaderLib/background.glsl.js @@ -13,21 +13,26 @@ void main() { export const fragment = /* glsl */` uniform sampler2D t2D; +uniform float backgroundIntensity; varying vec2 vUv; void main() { - gl_FragColor = texture2D( t2D, vUv ); + vec4 texColor = texture2D( t2D, vUv ); #ifdef DECODE_VIDEO_TEXTURE // inline sRGB decode (TODO: Remove this code when https://crbug.com/1256340 is solved) - gl_FragColor = vec4( mix( pow( gl_FragColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), gl_FragColor.rgb * 0.0773993808, vec3( lessThanEqual( gl_FragColor.rgb, vec3( 0.04045 ) ) ) ), gl_FragColor.w ); + texColor = vec4( mix( pow( texColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), texColor.rgb * 0.0773993808, vec3( lessThanEqual( texColor.rgb, vec3( 0.04045 ) ) ) ), texColor.w ); #endif + texColor.rgb *= backgroundIntensity; + + gl_FragColor = texColor; + #include #include diff --git a/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js b/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js new file mode 100644 index 00000000000000..5d57236208d111 --- /dev/null +++ b/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js @@ -0,0 +1,62 @@ +export const vertex = /* glsl */` +varying vec3 vWorldDirection; + +#include + +void main() { + + vWorldDirection = transformDirection( position, modelMatrix ); + + #include + #include + + gl_Position.z = gl_Position.w; // set z to camera.far + +} +`; + +export const fragment = /* glsl */` + +#ifdef ENVMAP_TYPE_CUBE + + uniform samplerCube envMap; + +#elif defined( ENVMAP_TYPE_CUBE_UV ) + + uniform sampler2D envMap; + +#endif + +uniform float flipEnvMap; +uniform float backgroundBlurriness; +uniform float backgroundIntensity; + +varying vec3 vWorldDirection; + +#include + +void main() { + + #ifdef ENVMAP_TYPE_CUBE + + vec4 texColor = textureCube( envMap, vec3( flipEnvMap * vWorldDirection.x, vWorldDirection.yz ) ); + + #elif defined( ENVMAP_TYPE_CUBE_UV ) + + vec4 texColor = textureCubeUV( envMap, vWorldDirection, backgroundBlurriness ); + + #else + + vec4 texColor = vec4( 0.0, 0.0, 0.0, 1.0 ); + + #endif + + texColor.rgb *= backgroundIntensity; + + gl_FragColor = texColor; + + #include + #include + +} +`; diff --git a/src/renderers/shaders/ShaderLib/cube.glsl.js b/src/renderers/shaders/ShaderLib/cube.glsl.js index 4613c10a2330de..5934f6c5ca2129 100644 --- a/src/renderers/shaders/ShaderLib/cube.glsl.js +++ b/src/renderers/shaders/ShaderLib/cube.glsl.js @@ -16,19 +16,17 @@ void main() { `; export const fragment = /* glsl */` -#include +uniform samplerCube tCube; +uniform float tFlip; uniform float opacity; varying vec3 vWorldDirection; -#include - void main() { - vec3 vReflect = vWorldDirection; - #include + vec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) ); - gl_FragColor = envColor; + gl_FragColor = texColor; gl_FragColor.a *= opacity; #include diff --git a/src/renderers/shaders/ShaderLib/meshbasic.glsl.js b/src/renderers/shaders/ShaderLib/meshbasic.glsl.js index e31f8f56aca4f9..d5b0199e674c93 100644 --- a/src/renderers/shaders/ShaderLib/meshbasic.glsl.js +++ b/src/renderers/shaders/ShaderLib/meshbasic.glsl.js @@ -63,7 +63,6 @@ uniform float opacity; #include #include #include -#include #include #include #include diff --git a/src/renderers/shaders/ShaderLib/meshlambert.glsl.js b/src/renderers/shaders/ShaderLib/meshlambert.glsl.js index e5d79df1a310f6..4592a156e1ae63 100644 --- a/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +++ b/src/renderers/shaders/ShaderLib/meshlambert.glsl.js @@ -1,22 +1,16 @@ export const vertex = /* glsl */` #define LAMBERT -varying vec3 vLightFront; -varying vec3 vIndirectFront; - -#ifdef DOUBLE_SIDED - varying vec3 vLightBack; - varying vec3 vIndirectBack; -#endif +varying vec3 vViewPosition; #include #include #include +#include #include -#include -#include #include #include +#include #include #include #include @@ -35,36 +29,33 @@ void main() { #include #include #include + #include #include #include #include + #include #include #include #include + vViewPosition = - mvPosition.xyz; + #include #include - #include #include #include + } `; export const fragment = /* glsl */` +#define LAMBERT + uniform vec3 diffuse; uniform vec3 emissive; uniform float opacity; -varying vec3 vLightFront; -varying vec3 vIndirectFront; - -#ifdef DOUBLE_SIDED - varying vec3 vLightBack; - varying vec3 vIndirectBack; -#endif - - #include #include #include @@ -79,12 +70,14 @@ varying vec3 vIndirectFront; #include #include #include -#include +#include #include #include -#include +#include +#include #include -#include +#include +#include #include #include #include @@ -103,49 +96,28 @@ void main() { #include #include #include + #include + #include #include // accumulation - - #ifdef DOUBLE_SIDED - - reflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack; - - #else - - reflectedLight.indirectDiffuse += vIndirectFront; - - #endif - - #include - - reflectedLight.indirectDiffuse *= BRDF_Lambert( diffuseColor.rgb ); - - #ifdef DOUBLE_SIDED - - reflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack; - - #else - - reflectedLight.directDiffuse = vLightFront; - - #endif - - reflectedLight.directDiffuse *= BRDF_Lambert( diffuseColor.rgb ) * getShadowMask(); + #include + #include + #include + #include // modulation - #include vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance; #include - #include #include #include #include #include #include + } `; diff --git a/src/renderers/shaders/ShaderLib/meshphong.glsl.js b/src/renderers/shaders/ShaderLib/meshphong.glsl.js index 24027b24342d84..54a7b5f80248c4 100644 --- a/src/renderers/shaders/ShaderLib/meshphong.glsl.js +++ b/src/renderers/shaders/ShaderLib/meshphong.glsl.js @@ -72,7 +72,6 @@ uniform float opacity; #include #include #include -#include #include #include #include diff --git a/src/renderers/shaders/ShaderLib/vsm.glsl.js b/src/renderers/shaders/ShaderLib/vsm.glsl.js index fb4109e6b60a75..49371dd3d400be 100644 --- a/src/renderers/shaders/ShaderLib/vsm.glsl.js +++ b/src/renderers/shaders/ShaderLib/vsm.glsl.js @@ -20,9 +20,6 @@ void main() { float mean = 0.0; float squared_mean = 0.0; - // This seems totally useless but it's a crazy work around for a Adreno compiler bug - // float depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy ) / resolution ) ); - float uvStride = samples <= 1.0 ? 0.0 : 2.0 / ( samples - 1.0 ); float uvStart = samples <= 1.0 ? 0.0 : - 1.0; for ( float i = 0.0; i < samples; i ++ ) { diff --git a/src/renderers/shaders/UniformsLib.js b/src/renderers/shaders/UniformsLib.js index b5f0d8a68251b0..6f6864709b8c9a 100644 --- a/src/renderers/shaders/UniformsLib.js +++ b/src/renderers/shaders/UniformsLib.js @@ -34,7 +34,7 @@ const UniformsLib = { flipEnvMap: { value: - 1 }, reflectivity: { value: 1.0 }, // basic, lambert, phong ior: { value: 1.5 }, // physical - refractionRatio: { value: 0.98 } // basic, lambert, phong + refractionRatio: { value: 0.98 }, // basic, lambert, phong }, @@ -145,8 +145,9 @@ const UniformsLib = { shadowMapSize: {} } }, + spotLightMap: { value: [] }, spotShadowMap: { value: [] }, - spotShadowMatrix: { value: [] }, + spotLightMatrix: { value: [] }, pointLights: { value: [], properties: { color: {}, diff --git a/src/renderers/shaders/UniformsUtils.js b/src/renderers/shaders/UniformsUtils.js index 855e534c02e3a6..b20b4abd60aa32 100644 --- a/src/renderers/shaders/UniformsUtils.js +++ b/src/renderers/shaders/UniformsUtils.js @@ -1,3 +1,5 @@ +import { sRGBEncoding, LinearSRGBColorSpace, SRGBColorSpace } from '../../constants.js'; + /** * Uniform Utilities */ @@ -73,6 +75,19 @@ export function cloneUniformsGroups( src ) { } +export function getUnlitUniformColorSpace( renderer ) { + + if ( renderer.getRenderTarget() === null ) { + + // https://github.com/mrdoob/three.js/pull/23937#issuecomment-1111067398 + return renderer.outputEncoding === sRGBEncoding ? SRGBColorSpace : LinearSRGBColorSpace; + + } + + return LinearSRGBColorSpace; + +} + // Legacy const UniformsUtils = { clone: cloneUniforms, merge: mergeUniforms }; diff --git a/src/renderers/webgl/WebGLAttributes.js b/src/renderers/webgl/WebGLAttributes.js index 177ed4bdcc8fd2..e810f967465665 100644 --- a/src/renderers/webgl/WebGLAttributes.js +++ b/src/renderers/webgl/WebGLAttributes.js @@ -112,6 +112,8 @@ function WebGLAttributes( gl, capabilities ) { } + attribute.onUploadCallback(); + } // diff --git a/src/renderers/webgl/WebGLBackground.js b/src/renderers/webgl/WebGLBackground.js index abca5e21add00d..7a9c48e7bdd226 100644 --- a/src/renderers/webgl/WebGLBackground.js +++ b/src/renderers/webgl/WebGLBackground.js @@ -5,9 +5,11 @@ import { ShaderMaterial } from '../../materials/ShaderMaterial.js'; import { Color } from '../../math/Color.js'; import { Mesh } from '../../objects/Mesh.js'; import { ShaderLib } from '../shaders/ShaderLib.js'; -import { cloneUniforms } from '../shaders/UniformsUtils.js'; +import { cloneUniforms, getUnlitUniformColorSpace } from '../shaders/UniformsUtils.js'; -function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipliedAlpha ) { +const _rgb = { r: 0, b: 0, g: 0 }; + +function WebGLBackground( renderer, cubemaps, cubeuvmaps, state, objects, alpha, premultipliedAlpha ) { const clearColor = new Color( 0x000000 ); let clearAlpha = alpha === true ? 0 : 1; @@ -26,7 +28,8 @@ function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipli if ( background && background.isTexture ) { - background = cubemaps.get( background ); + const usePMREM = scene.backgroundBlurriness > 0; // use PMREM if the user wants to blur the background + background = ( usePMREM ? cubeuvmaps : cubemaps ).get( background ); } @@ -67,9 +70,9 @@ function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipli new BoxGeometry( 1, 1, 1 ), new ShaderMaterial( { name: 'BackgroundCubeMaterial', - uniforms: cloneUniforms( ShaderLib.cube.uniforms ), - vertexShader: ShaderLib.cube.vertexShader, - fragmentShader: ShaderLib.cube.fragmentShader, + uniforms: cloneUniforms( ShaderLib.backgroundCube.uniforms ), + vertexShader: ShaderLib.backgroundCube.vertexShader, + fragmentShader: ShaderLib.backgroundCube.fragmentShader, side: BackSide, depthTest: false, depthWrite: false, @@ -86,7 +89,7 @@ function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipli }; - // enable code injection for non-built-in material + // add "envMap" material property so the renderer can evaluate it like for built-in materials Object.defineProperty( boxMesh.material, 'envMap', { get: function () { @@ -103,6 +106,8 @@ function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipli boxMesh.material.uniforms.envMap.value = background; boxMesh.material.uniforms.flipEnvMap.value = ( background.isCubeTexture && background.isRenderTargetTexture === false ) ? - 1 : 1; + boxMesh.material.uniforms.backgroundBlurriness.value = scene.backgroundBlurriness; + boxMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity; if ( currentBackground !== background || currentBackgroundVersion !== background.version || @@ -141,7 +146,7 @@ function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipli planeMesh.geometry.deleteAttribute( 'normal' ); - // enable code injection for non-built-in material + // add "map" material property so the renderer can evaluate it like for built-in materials Object.defineProperty( planeMesh.material, 'map', { get: function () { @@ -157,6 +162,7 @@ function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipli } planeMesh.material.uniforms.t2D.value = background; + planeMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity; if ( background.matrixAutoUpdate === true ) { @@ -189,7 +195,9 @@ function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipli function setClear( color, alpha ) { - state.buffers.color.setClear( color.r, color.g, color.b, alpha, premultipliedAlpha ); + color.getRGB( _rgb, getUnlitUniformColorSpace( renderer ) ); + + state.buffers.color.setClear( _rgb.r, _rgb.g, _rgb.b, alpha, premultipliedAlpha ); } diff --git a/src/renderers/webgl/WebGLLights.js b/src/renderers/webgl/WebGLLights.js index 7e7f0ce31801e4..2f0df97ae7381c 100644 --- a/src/renderers/webgl/WebGLLights.js +++ b/src/renderers/webgl/WebGLLights.js @@ -144,9 +144,9 @@ function ShadowUniformsCache() { let nextVersion = 0; -function shadowCastingLightsFirst( lightA, lightB ) { +function shadowCastingAndTexturingLightsFirst( lightA, lightB ) { - return ( lightB.castShadow ? 1 : 0 ) - ( lightA.castShadow ? 1 : 0 ); + return ( lightB.castShadow ? 2 : 0 ) - ( lightA.castShadow ? 2 : 0 ) + ( lightB.map ? 1 : 0 ) - ( lightA.map ? 1 : 0 ); } @@ -169,7 +169,8 @@ function WebGLLights( extensions, capabilities ) { numDirectionalShadows: - 1, numPointShadows: - 1, - numSpotShadows: - 1 + numSpotShadows: - 1, + numSpotMaps: - 1 }, ambient: [ 0, 0, 0 ], @@ -179,9 +180,10 @@ function WebGLLights( extensions, capabilities ) { directionalShadowMap: [], directionalShadowMatrix: [], spot: [], + spotLightMap: [], spotShadow: [], spotShadowMap: [], - spotShadowMatrix: [], + spotLightMatrix: [], rectArea: [], rectAreaLTC1: null, rectAreaLTC2: null, @@ -189,7 +191,8 @@ function WebGLLights( extensions, capabilities ) { pointShadow: [], pointShadowMap: [], pointShadowMatrix: [], - hemi: [] + hemi: [], + numSpotLightShadowsWithMaps: 0 }; @@ -214,8 +217,11 @@ function WebGLLights( extensions, capabilities ) { let numDirectionalShadows = 0; let numPointShadows = 0; let numSpotShadows = 0; + let numSpotMaps = 0; + let numSpotShadowsWithMaps = 0; - lights.sort( shadowCastingLightsFirst ); + // ordering : [shadow casting + map texturing, map texturing, shadow casting, none ] + lights.sort( shadowCastingAndTexturingLightsFirst ); // artist-friendly light intensity scaling factor const scaleFactor = ( physicallyCorrectLights !== true ) ? Math.PI : 1; @@ -286,9 +292,26 @@ function WebGLLights( extensions, capabilities ) { uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) ); uniforms.decay = light.decay; - if ( light.castShadow ) { + state.spot[ spotLength ] = uniforms; - const shadow = light.shadow; + const shadow = light.shadow; + + if ( light.map ) { + + state.spotLightMap[ numSpotMaps ] = light.map; + numSpotMaps ++; + + // make sure the lightMatrix is up to date + // TODO : do it if required only + shadow.updateMatrices( light ); + + if ( light.castShadow ) numSpotShadowsWithMaps ++; + + } + + state.spotLightMatrix[ spotLength ] = shadow.matrix; + + if ( light.castShadow ) { const shadowUniforms = shadowCache.get( light ); @@ -299,24 +322,17 @@ function WebGLLights( extensions, capabilities ) { state.spotShadow[ spotLength ] = shadowUniforms; state.spotShadowMap[ spotLength ] = shadowMap; - state.spotShadowMatrix[ spotLength ] = light.shadow.matrix; numSpotShadows ++; } - state.spot[ spotLength ] = uniforms; - spotLength ++; } else if ( light.isRectAreaLight ) { const uniforms = 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 uniforms.color.copy( color ).multiplyScalar( intensity ); uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 ); @@ -420,7 +436,8 @@ function WebGLLights( extensions, capabilities ) { hash.hemiLength !== hemiLength || hash.numDirectionalShadows !== numDirectionalShadows || hash.numPointShadows !== numPointShadows || - hash.numSpotShadows !== numSpotShadows ) { + hash.numSpotShadows !== numSpotShadows || + hash.numSpotMaps !== numSpotMaps ) { state.directional.length = directionalLength; state.spot.length = spotLength; @@ -436,7 +453,9 @@ function WebGLLights( extensions, capabilities ) { state.spotShadowMap.length = numSpotShadows; state.directionalShadowMatrix.length = numDirectionalShadows; state.pointShadowMatrix.length = numPointShadows; - state.spotShadowMatrix.length = numSpotShadows; + state.spotLightMatrix.length = numSpotShadows + numSpotMaps - numSpotShadowsWithMaps; + state.spotLightMap.length = numSpotMaps; + state.numSpotLightShadowsWithMaps = numSpotShadowsWithMaps; hash.directionalLength = directionalLength; hash.pointLength = pointLength; @@ -447,6 +466,7 @@ function WebGLLights( extensions, capabilities ) { hash.numDirectionalShadows = numDirectionalShadows; hash.numPointShadows = numPointShadows; hash.numSpotShadows = numSpotShadows; + hash.numSpotMaps = numSpotMaps; state.version = nextVersion ++; diff --git a/src/renderers/webgl/WebGLMaterials.js b/src/renderers/webgl/WebGLMaterials.js index 188aa8113e8cb1..2f249bb1d0afeb 100644 --- a/src/renderers/webgl/WebGLMaterials.js +++ b/src/renderers/webgl/WebGLMaterials.js @@ -1,10 +1,11 @@ import { BackSide } from '../../constants.js'; +import { getUnlitUniformColorSpace } from '../shaders/UniformsUtils.js'; function WebGLMaterials( renderer, properties ) { function refreshFogUniforms( uniforms, fog ) { - uniforms.fogColor.value.copy( fog.color ); + fog.color.getRGB( uniforms.fogColor.value, getUnlitUniformColorSpace( renderer ) ); if ( fog.isFog ) { diff --git a/src/renderers/webgl/WebGLMorphtargets.js b/src/renderers/webgl/WebGLMorphtargets.js index 480110103ba279..4fb585a138b98f 100644 --- a/src/renderers/webgl/WebGLMorphtargets.js +++ b/src/renderers/webgl/WebGLMorphtargets.js @@ -15,22 +15,6 @@ function absNumericalSort( a, b ) { } -function denormalize( morph, attribute ) { - - let denominator = 1; - const array = attribute.isInterleavedBufferAttribute ? attribute.data.array : attribute.array; - - if ( array instanceof Int8Array ) denominator = 127; - else if ( array instanceof Uint8Array ) denominator = 255; - else if ( array instanceof Uint16Array ) denominator = 65535; - else if ( array instanceof Int16Array ) denominator = 32767; - else if ( array instanceof Int32Array ) denominator = 2147483647; - else console.error( 'THREE.WebGLMorphtargets: Unsupported morph attribute data type: ', array ); - - morph.divideScalar( denominator ); - -} - function WebGLMorphtargets( gl, capabilities, textures ) { const influencesList = {}; @@ -114,8 +98,6 @@ function WebGLMorphtargets( gl, capabilities, textures ) { morph.fromBufferAttribute( morphTarget, j ); - if ( morphTarget.normalized === true ) denormalize( morph, morphTarget ); - buffer[ offset + stride + 0 ] = morph.x; buffer[ offset + stride + 1 ] = morph.y; buffer[ offset + stride + 2 ] = morph.z; @@ -127,8 +109,6 @@ function WebGLMorphtargets( gl, capabilities, textures ) { morph.fromBufferAttribute( morphNormal, j ); - if ( morphNormal.normalized === true ) denormalize( morph, morphNormal ); - buffer[ offset + stride + 4 ] = morph.x; buffer[ offset + stride + 5 ] = morph.y; buffer[ offset + stride + 6 ] = morph.z; @@ -140,8 +120,6 @@ function WebGLMorphtargets( gl, capabilities, textures ) { morph.fromBufferAttribute( morphColor, j ); - if ( morphColor.normalized === true ) denormalize( morph, morphColor ); - buffer[ offset + stride + 8 ] = morph.x; buffer[ offset + stride + 9 ] = morph.y; buffer[ offset + stride + 10 ] = morph.z; diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index 5e9ee696603db3..99fc10e4fdfd58 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -176,13 +176,18 @@ function filterEmptyLine( string ) { function replaceLightNums( string, parameters ) { + const numSpotLightCoords = parameters.numSpotLightShadows + parameters.numSpotLightMaps - parameters.numSpotLightShadowsWithMaps; + return string .replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights ) .replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights ) + .replace( /NUM_SPOT_LIGHT_MAPS/g, parameters.numSpotLightMaps ) + .replace( /NUM_SPOT_LIGHT_COORDS/g, numSpotLightCoords ) .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_WITH_MAPS/g, parameters.numSpotLightShadowsWithMaps ) .replace( /NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows ) .replace( /NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows ); @@ -222,21 +227,11 @@ function includeReplacer( match, include ) { // Unroll Loops -const deprecatedUnrollLoopPattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g; const 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; function unrollLoops( string ) { - return string - .replace( unrollLoopPattern, loopReplacer ) - .replace( deprecatedUnrollLoopPattern, deprecatedLoopReplacer ); - -} - -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 string.replace( unrollLoopPattern, loopReplacer ); } diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js index d70851732d83f9..3ab64b4e3706d9 100644 --- a/src/renderers/webgl/WebGLPrograms.js +++ b/src/renderers/webgl/WebGLPrograms.js @@ -199,12 +199,14 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities numDirLights: lights.directional.length, numPointLights: lights.point.length, numSpotLights: lights.spot.length, + numSpotLightMaps: lights.spotLightMap.length, numRectAreaLights: lights.rectArea.length, numHemiLights: lights.hemi.length, numDirLightShadows: lights.directionalShadowMap.length, numPointLightShadows: lights.pointShadowMap.length, numSpotLightShadows: lights.spotShadowMap.length, + numSpotLightShadowsWithMaps: lights.numSpotLightShadowsWithMaps, numClippingPlanes: clipping.numPlanes, numClipIntersection: clipping.numIntersection, @@ -299,11 +301,13 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities array.push( parameters.numDirLights ); array.push( parameters.numPointLights ); array.push( parameters.numSpotLights ); + array.push( parameters.numSpotLightMaps ); array.push( parameters.numHemiLights ); array.push( parameters.numRectAreaLights ); array.push( parameters.numDirLightShadows ); array.push( parameters.numPointLightShadows ); array.push( parameters.numSpotLightShadows ); + array.push( parameters.numSpotLightShadowsWithMaps ); array.push( parameters.shadowMapType ); array.push( parameters.toneMapping ); array.push( parameters.numClippingPlanes ); @@ -382,60 +386,60 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities _programLayers.enable( 31 ); if ( parameters.uvsVertexOnly ) _programLayers.enable( 32 ); - if ( parameters.fog ) - _programLayers.enable( 33 ); array.push( _programLayers.mask ); _programLayers.disableAll(); - if ( parameters.useFog ) + if ( parameters.fog ) _programLayers.enable( 0 ); - if ( parameters.flatShading ) + if ( parameters.useFog ) _programLayers.enable( 1 ); - if ( parameters.logarithmicDepthBuffer ) + if ( parameters.flatShading ) _programLayers.enable( 2 ); - if ( parameters.skinning ) + if ( parameters.logarithmicDepthBuffer ) _programLayers.enable( 3 ); - if ( parameters.morphTargets ) + if ( parameters.skinning ) _programLayers.enable( 4 ); - if ( parameters.morphNormals ) + if ( parameters.morphTargets ) _programLayers.enable( 5 ); - if ( parameters.morphColors ) + if ( parameters.morphNormals ) _programLayers.enable( 6 ); - if ( parameters.premultipliedAlpha ) + if ( parameters.morphColors ) _programLayers.enable( 7 ); - if ( parameters.shadowMapEnabled ) + if ( parameters.premultipliedAlpha ) _programLayers.enable( 8 ); - if ( parameters.physicallyCorrectLights ) + if ( parameters.shadowMapEnabled ) _programLayers.enable( 9 ); - if ( parameters.doubleSided ) + if ( parameters.physicallyCorrectLights ) _programLayers.enable( 10 ); - if ( parameters.flipSided ) + if ( parameters.doubleSided ) _programLayers.enable( 11 ); - if ( parameters.useDepthPacking ) + if ( parameters.flipSided ) _programLayers.enable( 12 ); - if ( parameters.dithering ) + if ( parameters.useDepthPacking ) _programLayers.enable( 13 ); - if ( parameters.specularIntensityMap ) + if ( parameters.dithering ) _programLayers.enable( 14 ); - if ( parameters.specularColorMap ) + if ( parameters.specularIntensityMap ) _programLayers.enable( 15 ); - if ( parameters.transmission ) + if ( parameters.specularColorMap ) _programLayers.enable( 16 ); - if ( parameters.transmissionMap ) + if ( parameters.transmission ) _programLayers.enable( 17 ); - if ( parameters.thicknessMap ) + if ( parameters.transmissionMap ) _programLayers.enable( 18 ); - if ( parameters.sheen ) + if ( parameters.thicknessMap ) _programLayers.enable( 19 ); - if ( parameters.sheenColorMap ) + if ( parameters.sheen ) _programLayers.enable( 20 ); - if ( parameters.sheenRoughnessMap ) + if ( parameters.sheenColorMap ) _programLayers.enable( 21 ); - if ( parameters.decodeVideoTexture ) + if ( parameters.sheenRoughnessMap ) _programLayers.enable( 22 ); - if ( parameters.opaque ) + if ( parameters.decodeVideoTexture ) _programLayers.enable( 23 ); + if ( parameters.opaque ) + _programLayers.enable( 24 ); array.push( _programLayers.mask ); diff --git a/src/renderers/webgl/WebGLRenderLists.js b/src/renderers/webgl/WebGLRenderLists.js index 16d4e48af60fcb..2839e8b94ac61e 100644 --- a/src/renderers/webgl/WebGLRenderLists.js +++ b/src/renderers/webgl/WebGLRenderLists.js @@ -194,23 +194,24 @@ function WebGLRenderLists() { function get( scene, renderCallDepth ) { + const listArray = lists.get( scene ); let list; - if ( lists.has( scene ) === false ) { + if ( listArray === undefined ) { list = new WebGLRenderList(); lists.set( scene, [ list ] ); } else { - if ( renderCallDepth >= lists.get( scene ).length ) { + if ( renderCallDepth >= listArray.length ) { list = new WebGLRenderList(); - lists.get( scene ).push( list ); + listArray.push( list ); } else { - list = lists.get( scene )[ renderCallDepth ]; + list = listArray[ renderCallDepth ]; } diff --git a/src/renderers/webgl/WebGLRenderStates.js b/src/renderers/webgl/WebGLRenderStates.js index fbe9af7b26d607..a04199744aabfc 100644 --- a/src/renderers/webgl/WebGLRenderStates.js +++ b/src/renderers/webgl/WebGLRenderStates.js @@ -63,23 +63,24 @@ function WebGLRenderStates( extensions, capabilities ) { function get( scene, renderCallDepth = 0 ) { + const renderStateArray = renderStates.get( scene ); let renderState; - if ( renderStates.has( scene ) === false ) { + if ( renderStateArray === undefined ) { renderState = new WebGLRenderState( extensions, capabilities ); renderStates.set( scene, [ renderState ] ); } else { - if ( renderCallDepth >= renderStates.get( scene ).length ) { + if ( renderCallDepth >= renderStateArray.length ) { renderState = new WebGLRenderState( extensions, capabilities ); - renderStates.get( scene ).push( renderState ); + renderStateArray.push( renderState ); } else { - renderState = renderStates.get( scene )[ renderCallDepth ]; + renderState = renderStateArray[ renderCallDepth ]; } diff --git a/src/renderers/webgl/WebGLShaderCache.js b/src/renderers/webgl/WebGLShaderCache.js index 8ac56c641d3a7c..4e0fffcbb035c5 100644 --- a/src/renderers/webgl/WebGLShaderCache.js +++ b/src/renderers/webgl/WebGLShaderCache.js @@ -77,29 +77,32 @@ class WebGLShaderCache { _getShaderCacheForMaterial( material ) { const cache = this.materialCache; + let set = cache.get( material ); - if ( cache.has( material ) === false ) { + if ( set === undefined ) { - cache.set( material, new Set() ); + set = new Set(); + cache.set( material, set ); } - return cache.get( material ); + return set; } _getShaderStage( code ) { const cache = this.shaderCache; + let stage = cache.get( code ); - if ( cache.has( code ) === false ) { + if ( stage === undefined ) { - const stage = new WebGLShaderStage( code ); + stage = new WebGLShaderStage( code ); cache.set( code, stage ); } - return cache.get( code ); + return stage; } diff --git a/src/renderers/webgl/WebGLShadowMap.js b/src/renderers/webgl/WebGLShadowMap.js index 1f0b4a9541a3ab..ce7de3e70e2076 100644 --- a/src/renderers/webgl/WebGLShadowMap.js +++ b/src/renderers/webgl/WebGLShadowMap.js @@ -244,7 +244,8 @@ function WebGLShadowMap( _renderer, _objects, _capabilities ) { if ( ( _renderer.localClippingEnabled && material.clipShadows === true && Array.isArray( material.clippingPlanes ) && material.clippingPlanes.length !== 0 ) || ( material.displacementMap && material.displacementScale !== 0 ) || - ( material.alphaMap && material.alphaTest > 0 ) ) { + ( material.alphaMap && material.alphaTest > 0 ) || + ( material.map && material.alphaTest > 0 ) ) { // in this case we need a unique material instance reflecting the // appropriate state @@ -288,6 +289,7 @@ function WebGLShadowMap( _renderer, _objects, _capabilities ) { result.alphaMap = material.alphaMap; result.alphaTest = material.alphaTest; + result.map = material.map; result.clipShadows = material.clipShadows; result.clippingPlanes = material.clippingPlanes; diff --git a/src/renderers/webgl/WebGLState.js b/src/renderers/webgl/WebGLState.js index d3c98b8d1ee07b..497ccaa3d6b445 100644 --- a/src/renderers/webgl/WebGLState.js +++ b/src/renderers/webgl/WebGLState.js @@ -103,59 +103,51 @@ function WebGLState( gl, extensions, capabilities ) { if ( currentDepthFunc !== depthFunc ) { - if ( depthFunc ) { + switch ( depthFunc ) { - switch ( depthFunc ) { + case NeverDepth: - case NeverDepth: - - gl.depthFunc( gl.NEVER ); - break; - - case AlwaysDepth: - - gl.depthFunc( gl.ALWAYS ); - break; - - case LessDepth: + gl.depthFunc( gl.NEVER ); + break; - gl.depthFunc( gl.LESS ); - break; + case AlwaysDepth: - case LessEqualDepth: + gl.depthFunc( gl.ALWAYS ); + break; - gl.depthFunc( gl.LEQUAL ); - break; + case LessDepth: - case EqualDepth: + gl.depthFunc( gl.LESS ); + break; - gl.depthFunc( gl.EQUAL ); - break; + case LessEqualDepth: - case GreaterEqualDepth: + gl.depthFunc( gl.LEQUAL ); + break; - gl.depthFunc( gl.GEQUAL ); - break; + case EqualDepth: - case GreaterDepth: + gl.depthFunc( gl.EQUAL ); + break; - gl.depthFunc( gl.GREATER ); - break; + case GreaterEqualDepth: - case NotEqualDepth: + gl.depthFunc( gl.GEQUAL ); + break; - gl.depthFunc( gl.NOTEQUAL ); - break; + case GreaterDepth: - default: + gl.depthFunc( gl.GREATER ); + break; - gl.depthFunc( gl.LEQUAL ); + case NotEqualDepth: - } + gl.depthFunc( gl.NOTEQUAL ); + break; - } else { + default: - gl.depthFunc( gl.LEQUAL ); + gl.depthFunc( gl.LEQUAL ); } @@ -726,7 +718,7 @@ function WebGLState( gl, extensions, capabilities ) { } currentBlending = blending; - currentPremultipledAlpha = null; + currentPremultipledAlpha = false; } @@ -888,25 +880,40 @@ function WebGLState( gl, extensions, capabilities ) { } - function bindTexture( webglType, webglTexture ) { + function bindTexture( webglType, webglTexture, webglSlot ) { + + if ( webglSlot === undefined ) { + + if ( currentTextureSlot === null ) { + + webglSlot = gl.TEXTURE0 + maxTextures - 1; + + } else { - if ( currentTextureSlot === null ) { + webglSlot = currentTextureSlot; - activeTexture(); + } } - let boundTexture = currentBoundTextures[ currentTextureSlot ]; + let boundTexture = currentBoundTextures[ webglSlot ]; if ( boundTexture === undefined ) { boundTexture = { type: undefined, texture: undefined }; - currentBoundTextures[ currentTextureSlot ] = boundTexture; + currentBoundTextures[ webglSlot ] = boundTexture; } if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) { + if ( currentTextureSlot !== webglSlot ) { + + gl.activeTexture( webglSlot ); + currentTextureSlot = webglSlot; + + } + gl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] ); boundTexture.type = webglType; @@ -945,6 +952,20 @@ function WebGLState( gl, extensions, capabilities ) { } + function compressedTexImage3D() { + + try { + + gl.compressedTexImage3D.apply( gl, arguments ); + + } catch ( error ) { + + console.error( 'THREE.WebGLState:', error ); + + } + + } + function texSubImage2D() { try { @@ -987,6 +1008,20 @@ function WebGLState( gl, extensions, capabilities ) { } + function compressedTexSubImage3D() { + + try { + + gl.compressedTexSubImage3D.apply( gl, arguments ); + + } catch ( error ) { + + console.error( 'THREE.WebGLState:', error ); + + } + + } + function texStorage2D() { try { @@ -1232,6 +1267,7 @@ function WebGLState( gl, extensions, capabilities ) { bindTexture: bindTexture, unbindTexture: unbindTexture, compressedTexImage2D: compressedTexImage2D, + compressedTexImage3D: compressedTexImage3D, texImage2D: texImage2D, texImage3D: texImage3D, @@ -1243,6 +1279,7 @@ function WebGLState( gl, extensions, capabilities ) { texSubImage2D: texSubImage2D, texSubImage3D: texSubImage3D, compressedTexSubImage2D: compressedTexSubImage2D, + compressedTexSubImage3D: compressedTexSubImage3D, scissor: scissor, viewport: viewport, diff --git a/src/renderers/webgl/WebGLTextures.js b/src/renderers/webgl/WebGLTextures.js index 2efd208bfc6912..325ce61d0f479d 100644 --- a/src/renderers/webgl/WebGLTextures.js +++ b/src/renderers/webgl/WebGLTextures.js @@ -11,7 +11,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, const maxTextureSize = capabilities.maxTextureSize; const maxSamples = capabilities.maxSamples; const multisampledRTTExt = extensions.has( 'WEBGL_multisampled_render_to_texture' ) ? extensions.get( 'WEBGL_multisampled_render_to_texture' ) : null; - const supportsInvalidateFramebuffer = /OculusBrowser/g.test( navigator.userAgent ); + const supportsInvalidateFramebuffer = typeof navigator === 'undefined' ? false : /OculusBrowser/g.test( navigator.userAgent ); const _videoTextures = new WeakMap(); let _canvas; @@ -135,7 +135,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - function getInternalFormat( internalFormatName, glFormat, glType, encoding, isVideoTexture = false ) { + function getInternalFormat( internalFormatName, glFormat, glType, encoding, forceLinearEncoding = false ) { if ( isWebGL2 === false ) return glFormat; @@ -169,7 +169,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, if ( glType === _gl.FLOAT ) internalFormat = _gl.RGBA32F; if ( glType === _gl.HALF_FLOAT ) internalFormat = _gl.RGBA16F; - if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = ( encoding === sRGBEncoding && isVideoTexture === false ) ? _gl.SRGB8_ALPHA8 : _gl.RGBA8; + if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = ( encoding === sRGBEncoding && forceLinearEncoding === false ) ? _gl.SRGB8_ALPHA8 : _gl.RGBA8; if ( glType === _gl.UNSIGNED_SHORT_4_4_4_4 ) internalFormat = _gl.RGBA4; if ( glType === _gl.UNSIGNED_SHORT_5_5_5_1 ) internalFormat = _gl.RGB5_A1; @@ -415,6 +415,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, array.push( texture.wrapS ); array.push( texture.wrapT ); + array.push( texture.wrapR || 0 ); array.push( texture.magFilter ); array.push( texture.minFilter ); array.push( texture.anisotropy ); @@ -460,8 +461,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - state.activeTexture( _gl.TEXTURE0 + slot ); - state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture ); + state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture, _gl.TEXTURE0 + slot ); } @@ -476,8 +476,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - state.activeTexture( _gl.TEXTURE0 + slot ); - state.bindTexture( _gl.TEXTURE_2D_ARRAY, textureProperties.__webglTexture ); + state.bindTexture( _gl.TEXTURE_2D_ARRAY, textureProperties.__webglTexture, _gl.TEXTURE0 + slot ); } @@ -492,8 +491,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - state.activeTexture( _gl.TEXTURE0 + slot ); - state.bindTexture( _gl.TEXTURE_3D, textureProperties.__webglTexture ); + state.bindTexture( _gl.TEXTURE_3D, textureProperties.__webglTexture, _gl.TEXTURE0 + slot ); } @@ -508,8 +506,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - state.activeTexture( _gl.TEXTURE0 + slot ); - state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture ); + state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture, _gl.TEXTURE0 + slot ); } @@ -675,16 +672,19 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, let textureType = _gl.TEXTURE_2D; - if ( texture.isDataArrayTexture ) textureType = _gl.TEXTURE_2D_ARRAY; + if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) textureType = _gl.TEXTURE_2D_ARRAY; if ( texture.isData3DTexture ) textureType = _gl.TEXTURE_3D; const forceUpload = initTexture( textureProperties, texture ); const source = texture.source; - state.activeTexture( _gl.TEXTURE0 + slot ); - state.bindTexture( textureType, textureProperties.__webglTexture ); + state.bindTexture( textureType, textureProperties.__webglTexture, _gl.TEXTURE0 + slot ); - if ( source.version !== source.__currentVersion || forceUpload === true ) { + const sourceProperties = properties.get( source ); + + if ( source.version !== sourceProperties.__version || forceUpload === true ) { + + state.activeTexture( _gl.TEXTURE0 + slot ); _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY ); _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha ); @@ -707,7 +707,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, const mipmaps = texture.mipmaps; const useTexStorage = ( isWebGL2 && texture.isVideoTexture !== true ); - const allocateMemory = ( source.__currentVersion === undefined ) || ( forceUpload === true ); + const allocateMemory = ( sourceProperties.__version === undefined ) || ( forceUpload === true ); const levels = getMipLevels( texture, image, supportsMips ); if ( texture.isDepthTexture ) { @@ -854,45 +854,97 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } else if ( texture.isCompressedTexture ) { - if ( useTexStorage && allocateMemory ) { + if ( texture.isCompressedArrayTexture ) { - state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height ); + if ( useTexStorage && allocateMemory ) { - } + state.texStorage3D( _gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height, image.depth ); - for ( let i = 0, il = mipmaps.length; i < il; i ++ ) { + } - mipmap = mipmaps[ i ]; + for ( let i = 0, il = mipmaps.length; i < il; i ++ ) { - if ( texture.format !== RGBAFormat ) { + mipmap = mipmaps[ i ]; - if ( glFormat !== null ) { + if ( texture.format !== RGBAFormat ) { - if ( useTexStorage ) { + if ( glFormat !== null ) { + + if ( useTexStorage ) { + + state.compressedTexSubImage3D( _gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, mipmap.data, 0, 0 ); + + } else { + + state.compressedTexImage3D( _gl.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, mipmap.data, 0, 0 ); - state.compressedTexSubImage2D( _gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data ); + } } else { - state.compressedTexImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); + console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' ); } } else { - console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' ); + if ( useTexStorage ) { + + state.texSubImage3D( _gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, glType, mipmap.data ); + + } else { + + state.texImage3D( _gl.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, glFormat, glType, mipmap.data ); + + } } - } else { + } - if ( useTexStorage ) { + } else { - state.texSubImage2D( _gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data ); + if ( useTexStorage && allocateMemory ) { + + state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height ); + + } + + for ( let i = 0, il = mipmaps.length; i < il; i ++ ) { + + mipmap = mipmaps[ i ]; + + if ( texture.format !== RGBAFormat ) { + + if ( glFormat !== null ) { + + if ( useTexStorage ) { + + state.compressedTexSubImage2D( _gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data ); + + } else { + + state.compressedTexImage2D( _gl.TEXTURE_2D, 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( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); + if ( useTexStorage ) { + + state.texSubImage2D( _gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data ); + + } else { + + state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); + + } } @@ -1023,7 +1075,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - source.__currentVersion = source.version; + sourceProperties.__version = source.version; if ( texture.onUpdate ) texture.onUpdate( texture ); @@ -1040,10 +1092,13 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, const forceUpload = initTexture( textureProperties, texture ); const source = texture.source; - state.activeTexture( _gl.TEXTURE0 + slot ); - state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture ); + state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture, _gl.TEXTURE0 + slot ); + + const sourceProperties = properties.get( source ); - if ( source.version !== source.__currentVersion || forceUpload === true ) { + if ( source.version !== sourceProperties.__version || forceUpload === true ) { + + state.activeTexture( _gl.TEXTURE0 + slot ); _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY ); _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha ); @@ -1078,7 +1133,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding ); const useTexStorage = ( isWebGL2 && texture.isVideoTexture !== true ); - const allocateMemory = ( source.__currentVersion === undefined ) || ( forceUpload === true ); + const allocateMemory = ( sourceProperties.__version === undefined ) || ( forceUpload === true ); let levels = getMipLevels( texture, image, supportsMips ); setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, supportsMips ); @@ -1227,7 +1282,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - source.__currentVersion = source.version; + sourceProperties.__version = source.version; if ( texture.onUpdate ) texture.onUpdate( texture ); @@ -1267,7 +1322,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( texture ).__webglTexture, 0, getRenderTargetSamples( renderTarget ) ); - } else { + } else if ( textureTarget === _gl.TEXTURE_2D || ( textureTarget >= _gl.TEXTURE_CUBE_MAP_POSITIVE_X && textureTarget <= _gl.TEXTURE_CUBE_MAP_NEGATIVE_Z ) ) { // see #24753 _gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( texture ).__webglTexture, 0 ); @@ -1591,7 +1646,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, const glFormat = utils.convert( texture.format, texture.encoding ); const glType = utils.convert( texture.type ); - const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding ); + const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding, renderTarget.isXRRenderTarget === true ); const samples = getRenderTargetSamples( renderTarget ); _gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height ); diff --git a/src/renderers/webgl/WebGLUniforms.js b/src/renderers/webgl/WebGLUniforms.js index 438a6610520ac5..b49f8c9d9bc2b6 100644 --- a/src/renderers/webgl/WebGLUniforms.js +++ b/src/renderers/webgl/WebGLUniforms.js @@ -362,17 +362,32 @@ function setValueV1i( gl, v ) { } -// Single integer / boolean vector (from flat array) +// Single integer / boolean vector (from flat array or THREE.VectorN) function setValueV2i( gl, v ) { const cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( v.x !== undefined ) { - gl.uniform2iv( this.addr, v ); + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y ) { + + gl.uniform2i( this.addr, v.x, v.y ); + + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; + + } - copyArray( cache, v ); + } else { + + if ( arraysEqual( cache, v ) ) return; + + gl.uniform2iv( this.addr, v ); + + copyArray( cache, v ); + + } } @@ -380,11 +395,27 @@ function setValueV3i( gl, v ) { const cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( v.x !== undefined ) { - gl.uniform3iv( this.addr, v ); + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z ) { + + gl.uniform3i( this.addr, v.x, v.y, v.z ); + + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; + cache[ 2 ] = v.z; + + } + + } else { + + if ( arraysEqual( cache, v ) ) return; + + gl.uniform3iv( this.addr, v ); + + copyArray( cache, v ); - copyArray( cache, v ); + } } @@ -392,11 +423,28 @@ function setValueV4i( gl, v ) { const cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( v.x !== undefined ) { - gl.uniform4iv( this.addr, v ); + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z || cache[ 3 ] !== v.w ) { + + gl.uniform4i( 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; - copyArray( cache, v ); + gl.uniform4iv( this.addr, v ); + + copyArray( cache, v ); + + } } @@ -414,17 +462,32 @@ function setValueV1ui( gl, v ) { } -// Single unsigned integer vector (from flat array) +// Single unsigned integer vector (from flat array or THREE.VectorN) function setValueV2ui( gl, v ) { const cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( v.x !== undefined ) { - gl.uniform2uiv( this.addr, v ); + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y ) { + + gl.uniform2ui( this.addr, v.x, v.y ); + + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; + + } + + } else { + + if ( arraysEqual( cache, v ) ) return; + + gl.uniform2uiv( this.addr, v ); - copyArray( cache, v ); + copyArray( cache, v ); + + } } @@ -432,11 +495,27 @@ function setValueV3ui( gl, v ) { const cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( v.x !== undefined ) { - gl.uniform3uiv( this.addr, v ); + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z ) { - copyArray( cache, v ); + gl.uniform3ui( this.addr, v.x, v.y, v.z ); + + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; + cache[ 2 ] = v.z; + + } + + } else { + + if ( arraysEqual( cache, v ) ) return; + + gl.uniform3uiv( this.addr, v ); + + copyArray( cache, v ); + + } } @@ -444,11 +523,28 @@ function setValueV4ui( gl, v ) { const cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( v.x !== undefined ) { - gl.uniform4uiv( this.addr, v ); + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z || cache[ 3 ] !== v.w ) { + + gl.uniform4ui( 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; - copyArray( cache, v ); + gl.uniform4uiv( this.addr, v ); + + copyArray( cache, v ); + + } } @@ -694,11 +790,19 @@ function setValueV4uiArray( gl, v ) { function setValueT1Array( gl, v, textures ) { + const cache = this.cache; + const n = v.length; const units = allocTexUnits( textures, n ); - gl.uniform1iv( this.addr, units ); + if ( ! arraysEqual( cache, units ) ) { + + gl.uniform1iv( this.addr, units ); + + copyArray( cache, units ); + + } for ( let i = 0; i !== n; ++ i ) { @@ -710,11 +814,19 @@ function setValueT1Array( gl, v, textures ) { function setValueT3DArray( gl, v, textures ) { + const cache = this.cache; + const n = v.length; const units = allocTexUnits( textures, n ); - gl.uniform1iv( this.addr, units ); + if ( ! arraysEqual( cache, units ) ) { + + gl.uniform1iv( this.addr, units ); + + copyArray( cache, units ); + + } for ( let i = 0; i !== n; ++ i ) { @@ -726,11 +838,19 @@ function setValueT3DArray( gl, v, textures ) { function setValueT6Array( gl, v, textures ) { + const cache = this.cache; + const n = v.length; const units = allocTexUnits( textures, n ); - gl.uniform1iv( this.addr, units ); + if ( ! arraysEqual( cache, units ) ) { + + gl.uniform1iv( this.addr, units ); + + copyArray( cache, units ); + + } for ( let i = 0; i !== n; ++ i ) { @@ -742,11 +862,19 @@ function setValueT6Array( gl, v, textures ) { function setValueT2DArrayArray( gl, v, textures ) { + const cache = this.cache; + const n = v.length; const units = allocTexUnits( textures, n ); - gl.uniform1iv( this.addr, units ); + if ( ! arraysEqual( cache, units ) ) { + + gl.uniform1iv( this.addr, units ); + + copyArray( cache, units ); + + } for ( let i = 0; i !== n; ++ i ) { diff --git a/src/renderers/webgl/WebGLUtils.js b/src/renderers/webgl/WebGLUtils.js index be468bdd53cde4..422d4d98084b58 100644 --- a/src/renderers/webgl/WebGLUtils.js +++ b/src/renderers/webgl/WebGLUtils.js @@ -43,7 +43,8 @@ function WebGLUtils( gl, extensions, capabilities ) { if ( p === LuminanceAlphaFormat ) return gl.LUMINANCE_ALPHA; if ( p === DepthFormat ) return gl.DEPTH_COMPONENT; if ( p === DepthStencilFormat ) return gl.DEPTH_STENCIL; - if ( p === RedFormat ) return gl.RED; + + // @deprecated since r137 if ( p === RGBFormat ) { @@ -72,6 +73,7 @@ function WebGLUtils( gl, extensions, capabilities ) { // WebGL2 formats. + if ( p === RedFormat ) return gl.RED; if ( p === RedIntegerFormat ) return gl.RED_INTEGER; if ( p === RGFormat ) return gl.RG; if ( p === RGIntegerFormat ) return gl.RG_INTEGER; diff --git a/src/renderers/webxr/WebXRController.js b/src/renderers/webxr/WebXRController.js index abb4b66cd880b2..2d8fe1b3da0f1c 100644 --- a/src/renderers/webxr/WebXRController.js +++ b/src/renderers/webxr/WebXRController.js @@ -90,6 +90,31 @@ class WebXRController { } + connect( inputSource ) { + + if ( inputSource && inputSource.hand ) { + + const hand = this._hand; + + if ( hand ) { + + for ( const inputjoint of inputSource.hand.values() ) { + + // Initialize hand with joints when connected + this._getHandJoint( hand, inputjoint ); + + } + + } + + } + + this.dispatchEvent( { type: 'connected', data: inputSource } ); + + return this; + + } + disconnect( inputSource ) { this.dispatchEvent( { type: 'disconnected', data: inputSource } ); @@ -137,19 +162,8 @@ class WebXRController { // Update the joints groups with the XRJoint poses const jointPose = frame.getJointPose( inputjoint, referenceSpace ); - if ( hand.joints[ inputjoint.jointName ] === undefined ) { - - // The transform of this joint will be updated with the joint pose on each frame - const joint = new Group(); - joint.matrixAutoUpdate = false; - joint.visible = false; - hand.joints[ inputjoint.jointName ] = joint; - // ?? - hand.add( joint ); - - } - - const joint = hand.joints[ inputjoint.jointName ]; + // The transform of this joint will be updated with the joint pose on each frame + const joint = this._getHandJoint( hand, inputjoint ); if ( jointPose !== null ) { @@ -301,6 +315,25 @@ class WebXRController { } + // private method + + _getHandJoint( hand, inputjoint ) { + + if ( hand.joints[ inputjoint.jointName ] === undefined ) { + + const joint = new Group(); + joint.matrixAutoUpdate = false; + joint.visible = false; + hand.joints[ inputjoint.jointName ] = joint; + + hand.add( joint ); + + } + + return hand.joints[ inputjoint.jointName ]; + + } + } diff --git a/src/renderers/webxr/WebXRManager.js b/src/renderers/webxr/WebXRManager.js index 0e55b4e95d053a..3f205b9e080059 100644 --- a/src/renderers/webxr/WebXRManager.js +++ b/src/renderers/webxr/WebXRManager.js @@ -43,6 +43,9 @@ class WebXRManager extends EventDispatcher { const controllers = []; const controllerInputSources = []; + const planes = new Set(); + const planesLastChangedTimes = new Map(); + // const cameraL = new PerspectiveCamera(); @@ -285,7 +288,8 @@ class WebXRManager extends EventDispatcher { { format: RGBAFormat, type: UnsignedByteType, - encoding: renderer.outputEncoding + encoding: renderer.outputEncoding, + stencilBuffer: attributes.stencil } ); @@ -363,7 +367,7 @@ class WebXRManager extends EventDispatcher { if ( index >= 0 ) { controllerInputSources[ index ] = null; - controllers[ index ].dispatchEvent( { type: 'disconnected', data: inputSource } ); + controllers[ index ].disconnect( inputSource ); } @@ -409,7 +413,7 @@ class WebXRManager extends EventDispatcher { if ( controller ) { - controller.dispatchEvent( { type: 'connected', data: inputSource } ); + controller.connect( inputSource ); } @@ -529,11 +533,8 @@ class WebXRManager extends EventDispatcher { // update user camera and its children - camera.position.copy( cameraVR.position ); - camera.quaternion.copy( cameraVR.quaternion ); - camera.scale.copy( cameraVR.scale ); camera.matrix.copy( cameraVR.matrix ); - camera.matrixWorld.copy( cameraVR.matrixWorld ); + camera.matrix.decompose( camera.position, camera.quaternion, camera.scale ); const children = camera.children; @@ -602,6 +603,12 @@ class WebXRManager extends EventDispatcher { }; + this.getPlanes = function () { + + return planes; + + }; + // Animation Loop let onAnimationFrameCallback = null; @@ -710,6 +717,65 @@ class WebXRManager extends EventDispatcher { if ( onAnimationFrameCallback ) onAnimationFrameCallback( time, frame ); + if ( frame.detectedPlanes ) { + + scope.dispatchEvent( { type: 'planesdetected', data: frame.detectedPlanes } ); + + let planesToRemove = null; + + for ( const plane of planes ) { + + if ( ! frame.detectedPlanes.has( plane ) ) { + + if ( planesToRemove === null ) { + + planesToRemove = []; + + } + + planesToRemove.push( plane ); + + } + + } + + if ( planesToRemove !== null ) { + + for ( const plane of planesToRemove ) { + + planes.delete( plane ); + planesLastChangedTimes.delete( plane ); + scope.dispatchEvent( { type: 'planeremoved', data: plane } ); + + } + + } + + for ( const plane of frame.detectedPlanes ) { + + if ( ! planes.has( plane ) ) { + + planes.add( plane ); + planesLastChangedTimes.set( plane, frame.lastChangedTime ); + scope.dispatchEvent( { type: 'planeadded', data: plane } ); + + } else { + + const lastKnownTime = planesLastChangedTimes.get( plane ); + + if ( plane.lastChangedTime > lastKnownTime ) { + + planesLastChangedTimes.set( plane, plane.lastChangedTime ); + scope.dispatchEvent( { type: 'planechanged', data: plane } ); + + } + + } + + } + + } + xrFrame = null; } diff --git a/src/scenes/Scene.js b/src/scenes/Scene.js index 2dc6785cb9d8b3..5e7feea23d597d 100644 --- a/src/scenes/Scene.js +++ b/src/scenes/Scene.js @@ -14,9 +14,10 @@ class Scene extends Object3D { this.environment = null; this.fog = null; - this.overrideMaterial = null; + this.backgroundBlurriness = 0; + this.backgroundIntensity = 1; - this.autoUpdate = true; // checked by the renderer + this.overrideMaterial = null; if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { @@ -34,9 +35,11 @@ class Scene extends Object3D { if ( source.environment !== null ) this.environment = source.environment.clone(); if ( source.fog !== null ) this.fog = source.fog.clone(); + this.backgroundBlurriness = source.backgroundBlurriness; + this.backgroundIntensity = source.backgroundIntensity; + if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone(); - this.autoUpdate = source.autoUpdate; this.matrixAutoUpdate = source.matrixAutoUpdate; return this; @@ -48,11 +51,29 @@ class Scene extends Object3D { const data = super.toJSON( meta ); if ( this.fog !== null ) data.object.fog = this.fog.toJSON(); + if ( this.backgroundBlurriness > 0 ) data.backgroundBlurriness = this.backgroundBlurriness; + if ( this.backgroundIntensity !== 1 ) data.backgroundIntensity = this.backgroundIntensity; return data; } + // @deprecated + + get autoUpdate() { + + console.warn( 'THREE.Scene: autoUpdate was renamed to matrixWorldAutoUpdate in r144.' ); + return this.matrixWorldAutoUpdate; + + } + + set autoUpdate( value ) { + + console.warn( 'THREE.Scene: autoUpdate was renamed to matrixWorldAutoUpdate in r144.' ); + this.matrixWorldAutoUpdate = value; + + } + } export { Scene }; diff --git a/src/textures/CompressedArrayTexture.js b/src/textures/CompressedArrayTexture.js new file mode 100644 index 00000000000000..cc062e695d41b3 --- /dev/null +++ b/src/textures/CompressedArrayTexture.js @@ -0,0 +1,18 @@ +import { ClampToEdgeWrapping } from '../constants.js'; +import { CompressedTexture } from './CompressedTexture.js'; + +class CompressedArrayTexture extends CompressedTexture { + + constructor( mipmaps, width, height, depth, format, type ) { + + super( mipmaps, width, height, format, type ); + + this.isCompressedArrayTexture = true; + this.image.depth = depth; + this.wrapR = ClampToEdgeWrapping; + + } + +} + +export { CompressedArrayTexture }; diff --git a/src/textures/Texture.js b/src/textures/Texture.js index b552e320625248..f9a5382e8f270f 100644 --- a/src/textures/Texture.js +++ b/src/textures/Texture.js @@ -19,7 +19,7 @@ let textureId = 0; class Texture extends EventDispatcher { - constructor( image = Texture.DEFAULT_IMAGE, mapping = Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format = RGBAFormat, type = UnsignedByteType, anisotropy = 1, encoding = LinearEncoding ) { + constructor( image = Texture.DEFAULT_IMAGE, mapping = Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format = RGBAFormat, type = UnsignedByteType, anisotropy = Texture.DEFAULT_ANISOTROPY, encoding = LinearEncoding ) { super(); @@ -304,5 +304,6 @@ class Texture extends EventDispatcher { Texture.DEFAULT_IMAGE = null; Texture.DEFAULT_MAPPING = UVMapping; +Texture.DEFAULT_ANISOTROPY = 1; export { Texture }; diff --git a/src/utils.js b/src/utils.js index 6ae2c2e404f6e3..9cee434e7219d6 100644 --- a/src/utils.js +++ b/src/utils.js @@ -36,7 +36,7 @@ function arrayNeedsUint32( array ) { for ( let i = array.length - 1; i >= 0; -- i ) { - if ( array[ i ] > 65535 ) return true; + if ( array[ i ] >= 65535 ) return true; // account for PRIMITIVE_RESTART_FIXED_INDEX, #24565 } diff --git a/test/e2e/puppeteer.js b/test/e2e/puppeteer.js index d02c46a080e56a..dc0485656f6b34 100644 --- a/test/e2e/puppeteer.js +++ b/test/e2e/puppeteer.js @@ -35,6 +35,7 @@ const exceptionList = [ 'webgl_nodes_materials_standard', // puppeteer does not support import maps yet 'webgl_postprocessing_crossfade', // fails for some misterious reason 'webgl_raymarching_reflect', // exception for Github Actions + 'webgl_renderer_pathtracer', // slow to render 'webgl_test_memory2', // gives fatal error in puppeteer 'webgl_tiled_forward', // exception for Github Actions 'webgl_video_kinect', // video tag not deterministic enough @@ -43,10 +44,12 @@ const exceptionList = [ // webxr 'webxr_ar_lighting', // webgpu + 'webgpu_audio_processing', 'webgpu_compute', 'webgpu_cubemap_adjustments', 'webgpu_cubemap_mix', 'webgpu_depth_texture', + 'webgpu_equirectangular', 'webgpu_instance_mesh', 'webgpu_instance_uniform', 'webgpu_lights_custom', diff --git a/test/package-lock.json b/test/package-lock.json index f643f67b65e0b1..3e7bebd8778c30 100644 --- a/test/package-lock.json +++ b/test/package-lock.json @@ -13,7 +13,7 @@ }, "devDependencies": { "failonlyreporter": "^1.0.0", - "jimp": "^0.16.1", + "jimp": "^0.16.0", "pixelmatch": "^5.3.0", "puppeteer": "^15.2.0", "qunit": "^2.19.1", @@ -22,26 +22,26 @@ }, "..": { "name": "three", - "version": "0.142.0", + "version": "0.144.0", "license": "MIT", "devDependencies": { - "@babel/core": "^7.18.2", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-proposal-class-properties": "^7.17.12", - "@babel/preset-env": "^7.18.2", + "@babel/core": "^7.18.9", + "@babel/eslint-parser": "^7.18.9", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/preset-env": "^7.18.9", "@rollup/plugin-babel": "^5.3.1", "@rollup/plugin-node-resolve": "^13.3.0", "chalk": "^5.0.1", - "concurrently": "^7.2.1", - "eslint": "^8.16.0", + "concurrently": "^7.3.0", + "eslint": "^8.20.0", "eslint-config-mdcs": "^5.0.0", "eslint-plugin-compat": "^4.0.2", - "eslint-plugin-html": "^6.2.0", + "eslint-plugin-html": "^7.1.0", "eslint-plugin-import": "^2.26.0", - "rollup": "^2.75.0", + "rollup": "^2.77.2", "rollup-plugin-filesize": "^9.1.2", "rollup-plugin-terser": "^7.0.2", - "rollup-plugin-visualizer": "^5.6.0", + "rollup-plugin-visualizer": "^5.7.1", "servez": "^1.14.1" } }, @@ -1014,9 +1014,9 @@ } }, "node_modules/jpeg-js": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.2.tgz", - "integrity": "sha512-+az2gi/hvex7eLTMTlbRLOhH6P6WFdk2ITI8HJsaH2VqYO0I594zXSYEP+tf4FW+8Cy68ScDXoAsQdyQanv3sw==", + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", "dev": true }, "node_modules/load-bmfont": { @@ -1795,7 +1795,7 @@ "requires": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.1", - "jpeg-js": "0.4.2" + "jpeg-js": "^0.4.4" } }, "@jimp/plugin-blit": { @@ -2482,9 +2482,9 @@ } }, "jpeg-js": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.2.tgz", - "integrity": "sha512-+az2gi/hvex7eLTMTlbRLOhH6P6WFdk2ITI8HJsaH2VqYO0I594zXSYEP+tf4FW+8Cy68ScDXoAsQdyQanv3sw==", + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", "dev": true }, "load-bmfont": { @@ -2905,23 +2905,23 @@ "three": { "version": "file:..", "requires": { - "@babel/core": "^7.18.2", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-proposal-class-properties": "^7.17.12", - "@babel/preset-env": "^7.18.2", + "@babel/core": "^7.18.9", + "@babel/eslint-parser": "^7.18.9", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/preset-env": "^7.18.9", "@rollup/plugin-babel": "^5.3.1", "@rollup/plugin-node-resolve": "^13.3.0", "chalk": "^5.0.1", - "concurrently": "^7.2.1", - "eslint": "^8.16.0", + "concurrently": "^7.3.0", + "eslint": "^8.20.0", "eslint-config-mdcs": "^5.0.0", "eslint-plugin-compat": "^4.0.2", - "eslint-plugin-html": "^6.2.0", + "eslint-plugin-html": "^7.1.0", "eslint-plugin-import": "^2.26.0", - "rollup": "^2.75.0", + "rollup": "^2.77.2", "rollup-plugin-filesize": "^9.1.2", "rollup-plugin-terser": "^7.0.2", - "rollup-plugin-visualizer": "^5.6.0", + "rollup-plugin-visualizer": "^5.7.1", "servez": "^1.14.1" } }, diff --git a/test/package.json b/test/package.json index c86ff7453569af..8782976b4e2963 100644 --- a/test/package.json +++ b/test/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "failonlyreporter": "^1.0.0", - "jimp": "^0.16.1", + "jimp": "^0.16.0", "pixelmatch": "^5.3.0", "puppeteer": "^15.2.0", "qunit": "^2.19.1", @@ -18,5 +18,8 @@ }, "dependencies": { "three": "file:.." + }, + "overrides": { + "jpeg-js": "^0.4.4" } } diff --git a/test/unit/src/animation/AnimationAction.tests.js b/test/unit/src/animation/AnimationAction.tests.js index 3923dd48a2d9c4..1798e57165b18e 100644 --- a/test/unit/src/animation/AnimationAction.tests.js +++ b/test/unit/src/animation/AnimationAction.tests.js @@ -444,6 +444,52 @@ export default QUnit.module( 'Animation', () => { } ); + QUnit.test( 'StartAt when already executed once', ( assert ) => { + var root = new Object3D(); + var mixer = new AnimationMixer( root ); + var track = new NumberKeyframeTrack( '.rotation[x]', [ 0, 750 ], [ 0, 270 ] ); + var clip = new AnimationClip( 'clip1', 750, [ track ] ); + + var animationAction = mixer.clipAction( clip ); + animationAction.setLoop( LoopOnce ); + animationAction.clampWhenFinished = true; + animationAction.play(); + mixer.addEventListener('finished', () => { + animationAction.timeScale*=-1; + animationAction.paused=false; + animationAction.startAt(mixer.time+2000).play(); + + }); + + mixer.update( 250 ); + assert.equal( root.rotation.x, 90, 'first' ); + mixer.update( 250 ); + assert.equal( root.rotation.x, 180, 'first' ); + mixer.update( 250 ); + assert.equal( root.rotation.x, 270, 'first' ); + //first loop done + mixer.update( 2000 ); + // startAt Done + assert.equal( root.rotation.x, 270, 'third' ); + mixer.update( 250 ); + assert.equal( root.rotation.x, 180, 'fourth' ); + mixer.update( 250 ); + assert.equal( root.rotation.x, 90, 'fourth' ); + mixer.update( 250 ); + assert.equal( root.rotation.x, 0, 'sixth' ); + mixer.update( 1 ); + assert.equal( root.rotation.x, 0, 'seventh' ); + mixer.update( 1000 ); + assert.equal( root.rotation.x, 0, 'seventh' ); + mixer.update( 1000 ); + assert.equal( root.rotation.x, 0, 'seventh' ); + mixer.update( 250 ); + assert.equal( root.rotation.x, 90, 'seventh' ); + mixer.update( 250 ); + assert.equal( root.rotation.x, 180, 'seventh' ); + //console.log(mixer.time); + }); + } ); } ); diff --git a/test/unit/src/constants.tests.js b/test/unit/src/constants.tests.js index 32b8338ebd80f5..e233ecf2c93534 100644 --- a/test/unit/src/constants.tests.js +++ b/test/unit/src/constants.tests.js @@ -18,8 +18,6 @@ export default QUnit.module( 'Constants', () => { assert.equal( Constants.FrontSide, 0, 'FrontSide is equal to 0' ); assert.equal( Constants.BackSide, 1, 'BackSide is equal to 1' ); assert.equal( Constants.DoubleSide, 2, 'DoubleSide is equal to 2' ); - assert.equal( Constants.FlatShading, 1, 'FlatShading is equal to 1' ); - assert.equal( Constants.SmoothShading, 2, 'SmoothShading is equal to 2' ); assert.equal( Constants.NoBlending, 0, 'NoBlending is equal to 0' ); assert.equal( Constants.NormalBlending, 1, 'NormalBlending is equal to 1' ); assert.equal( Constants.AdditiveBlending, 2, 'AdditiveBlending is equal to 2' ); diff --git a/test/unit/src/core/BufferAttribute.tests.js b/test/unit/src/core/BufferAttribute.tests.js index 3ac8ad0bcaf32c..3eba471d2188c2 100644 --- a/test/unit/src/core/BufferAttribute.tests.js +++ b/test/unit/src/core/BufferAttribute.tests.js @@ -1,10 +1,6 @@ /* global QUnit */ import { BufferAttribute } from '../../../../src/core/BufferAttribute.js'; -import { Color } from '../../../../src/math/Color.js'; -import { Vector2 } from '../../../../src/math/Vector2.js'; -import { Vector3 } from '../../../../src/math/Vector3.js'; -import { Vector4 } from '../../../../src/math/Vector4.js'; import { DynamicDrawUsage } from '../../../../src/constants.js'; export default QUnit.module( 'Core', () => { @@ -94,66 +90,6 @@ export default QUnit.module( 'Core', () => { } ); - QUnit.test( 'copyColorsArray', ( assert ) => { - - var attr = new BufferAttribute( new Float32Array( 6 ), 3 ); - - attr.copyColorsArray( [ - new Color( 0, 0.5, 1 ), - new Color( 0.25, 1, 0 ) - ] ); - - var i = attr.array; - assert.ok( i[ 0 ] === 0 && i[ 1 ] === 0.5 && i[ 2 ] === 1, 'first color was copied correctly' ); - assert.ok( i[ 3 ] === 0.25 && i[ 4 ] === 1 && i[ 5 ] === 0, 'second color was copied correctly' ); - - } ); - - QUnit.test( 'copyVector2sArray', ( assert ) => { - - var attr = new BufferAttribute( new Float32Array( 4 ), 2 ); - - attr.copyVector2sArray( [ - new Vector2( 1, 2 ), - new Vector2( 4, 5 ) - ] ); - - var i = attr.array; - assert.ok( i[ 0 ] === 1 && i[ 1 ] === 2, 'first vector was copied correctly' ); - assert.ok( i[ 2 ] === 4 && i[ 3 ] === 5, 'second vector was copied correctly' ); - - } ); - - QUnit.test( 'copyVector3sArray', ( assert ) => { - - var attr = new BufferAttribute( new Float32Array( 6 ), 2 ); - - attr.copyVector3sArray( [ - new Vector3( 1, 2, 3 ), - new Vector3( 10, 20, 30 ) - ] ); - - var i = attr.array; - assert.ok( i[ 0 ] === 1 && i[ 1 ] === 2 && i[ 2 ] === 3, 'first vector was copied correctly' ); - assert.ok( i[ 3 ] === 10 && i[ 4 ] === 20 && i[ 5 ] === 30, 'second vector was copied correctly' ); - - } ); - - QUnit.test( 'copyVector4sArray', ( assert ) => { - - var attr = new BufferAttribute( new Float32Array( 8 ), 2 ); - - attr.copyVector4sArray( [ - new Vector4( 1, 2, 3, 4 ), - new Vector4( 10, 20, 30, 40 ) - ] ); - - var i = attr.array; - assert.ok( i[ 0 ] === 1 && i[ 1 ] === 2 && i[ 2 ] === 3 && i[ 3 ] === 4, 'first vector was copied correctly' ); - assert.ok( i[ 4 ] === 10 && i[ 5 ] === 20 && i[ 6 ] === 30 && i[ 7 ] === 40, 'second vector was copied correctly' ); - - } ); - QUnit.test( 'set', ( assert ) => { var f32a = new Float32Array( [ 1, 2, 3, 4 ] ); diff --git a/test/unit/src/core/BufferGeometry.tests.js b/test/unit/src/core/BufferGeometry.tests.js index bf933e14dfe62d..5422ad7476ccca 100644 --- a/test/unit/src/core/BufferGeometry.tests.js +++ b/test/unit/src/core/BufferGeometry.tests.js @@ -11,7 +11,6 @@ import { Matrix4 } from '../../../../src/math/Matrix4.js'; import { Quaternion } from '../../../../src/math/Quaternion.js'; import { Sphere } from '../../../../src/math/Sphere.js'; import { x, y, z } from '../math/Constants.tests.js'; -import { CONSOLE_LEVEL } from '../../utils/console-wrapper.js'; var DegToRad = Math.PI / 180; @@ -449,33 +448,6 @@ export default QUnit.module( 'Core', () => { } ); - QUnit.test( 'merge', ( assert ) => { - - var geometry1 = new BufferGeometry(); - geometry1.setAttribute( 'attrName', new BufferAttribute( new Float32Array( [ 1, 2, 3, 0, 0, 0 ] ), 3 ) ); - - var geometry2 = new BufferGeometry(); - geometry2.setAttribute( 'attrName', new BufferAttribute( new Float32Array( [ 4, 5, 6 ] ), 3 ) ); - - var attr = geometry1.attributes.attrName.array; - - geometry1.merge( geometry2, 1 ); - - // merged array should be 1, 2, 3, 4, 5, 6 - for ( var i = 0; i < attr.length; i ++ ) { - - assert.ok( attr[ i ] === i + 1, '' ); - - } - - console.level = CONSOLE_LEVEL.ERROR; - geometry1.merge( geometry2 ); - console.level = CONSOLE_LEVEL.DEFAULT; - - assert.ok( attr[ 0 ] === 4 && attr[ 1 ] === 5 && attr[ 2 ] === 6, 'copied the 3 attributes without offset' ); - - } ); - QUnit.todo( 'normalizeNormals', ( assert ) => { assert.ok( false, 'everything\'s gonna be alright' ); diff --git a/test/unit/src/core/Object3D.tests.js b/test/unit/src/core/Object3D.tests.js index dc624d08bfa0d5..d998a7d10fe80c 100644 --- a/test/unit/src/core/Object3D.tests.js +++ b/test/unit/src/core/Object3D.tests.js @@ -12,6 +12,7 @@ import { w, eps } from '../math/Constants.tests.js'; +import { EventDispatcher } from '../../../../src/core/EventDispatcher.js'; const matrixEquals4 = ( a, b ) => { @@ -54,10 +55,12 @@ export default QUnit.module( 'Core', () => { }; // INHERITANCE - QUnit.todo( 'Extending', ( assert ) => { - - assert.ok( false, 'everything\'s gonna be alright' ); + QUnit.test( 'Extending', ( assert ) => { + var object = new Object3D(); + + assert.strictEqual( object instanceof EventDispatcher, true, 'Object3D extends from EventDispatcher' ); + } ); // INSTANCING @@ -786,8 +789,27 @@ export default QUnit.module( 'Core', () => { 0, 0, 0, 1 ], 'No effect to child world matrix if parent local and world matrices and child local matrix are not updated' ); + // -- matrixWorldAutoUpdate = false test + + parent.position.set( 3, 2, 1 ); + parent.updateMatrix(); + parent.matrixWorldNeedsUpdate = false; + + child.matrixWorldAutoUpdate = false; + parent.updateMatrixWorld(); + + assert.deepEqual( child.matrixWorld.elements, [ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + ], 'No effect to child world matrix when matrixWorldAutoUpdate is set to false' ); + // -- Propagation to children world matrices test + child.position.set( 0, 0, 0 ); + parent.position.set( 1, 2, 3 ); + child.matrixWorldAutoUpdate = true; parent.matrixAutoUpdate = true; parent.updateMatrixWorld(); @@ -1013,6 +1035,24 @@ export default QUnit.module( 'Core', () => { m.setPosition( parent.position ).elements, 'object\'s world matrix is updated even if matrixAutoUpdate is false' ); + // object.matrixWorldAutoUpdate = false test + + parent.matrixWorldAutoUpdate = false; + child.matrixWorldAutoUpdate = false; + + child.matrixWorld.identity(); + parent.matrixWorld.identity(); + + object.updateWorldMatrix( true, true ); + + assert.deepEqual( child.matrixWorld.elements, + m.identity().elements, + 'No effect to child\'s world matrix if matrixWorldAutoUpdate is false' ); + + assert.deepEqual( parent.matrixWorld.elements, + m.identity().elements, + 'No effect to parent\'s world matrix if matrixWorldAutoUpdate is false' ); + } ); QUnit.test( 'toJSON', ( assert ) => { diff --git a/test/unit/src/geometries/BoxGeometry.tests.js b/test/unit/src/geometries/BoxGeometry.tests.js index 1a4b5e348ed0cb..9e390dff4552f9 100644 --- a/test/unit/src/geometries/BoxGeometry.tests.js +++ b/test/unit/src/geometries/BoxGeometry.tests.js @@ -1,7 +1,7 @@ /* global QUnit */ import { runStdGeometryTests } from '../../utils/qunit-utils.js'; -import { BoxGeometry, BoxBufferGeometry } from '../../../../src/geometries/BoxGeometry.js'; +import { BoxGeometry } from '../../../../src/geometries/BoxGeometry.js'; export default QUnit.module( 'Geometries', () => { @@ -23,7 +23,6 @@ export default QUnit.module( 'Geometries', () => { new BoxGeometry(), new BoxGeometry( parameters.width, parameters.height, parameters.depth ), new BoxGeometry( parameters.width, parameters.height, parameters.depth, parameters.widthSegments, parameters.heightSegments, parameters.depthSegments ), - new BoxBufferGeometry() ]; } ); diff --git a/test/unit/src/geometries/CapsuleGeometry.tests.js b/test/unit/src/geometries/CapsuleGeometry.tests.js index 126aced28abfcf..57c285ab3374cd 100644 --- a/test/unit/src/geometries/CapsuleGeometry.tests.js +++ b/test/unit/src/geometries/CapsuleGeometry.tests.js @@ -1,7 +1,7 @@ /* global QUnit */ import { runStdGeometryTests } from '../../utils/qunit-utils.js'; -import { CapsuleGeometry, CapsuleBufferGeometry } from '../../../../src/geometries/CapsuleGeometry.js'; +import { CapsuleGeometry } from '../../../../src/geometries/CapsuleGeometry.js'; export default QUnit.module( 'Geometries', () => { @@ -14,7 +14,7 @@ export default QUnit.module( 'Geometries', () => { radius: 2, length: 2, capSegments: 20, - heightSegments: 20 + radialSegments: 20 }; geometries = [ @@ -22,8 +22,7 @@ export default QUnit.module( 'Geometries', () => { new CapsuleGeometry( parameters.radius ), new CapsuleGeometry( parameters.radius, parameters.length ), new CapsuleGeometry( parameters.radius, parameters.length, parameters.capSegments ), - new CapsuleGeometry( parameters.radius, parameters.length, parameters.capSegments, parameters.heightSegments ), - new CapsuleBufferGeometry(), + new CapsuleGeometry( parameters.radius, parameters.length, parameters.capSegments, parameters.radialSegments ), ]; } ); diff --git a/test/unit/src/geometries/CircleGeometry.tests.js b/test/unit/src/geometries/CircleGeometry.tests.js index 5c8e8a053349f6..f5572e4f75aa4f 100644 --- a/test/unit/src/geometries/CircleGeometry.tests.js +++ b/test/unit/src/geometries/CircleGeometry.tests.js @@ -1,7 +1,7 @@ /* global QUnit */ import { runStdGeometryTests } from '../../utils/qunit-utils.js'; -import { CircleGeometry, CircleBufferGeometry } from '../../../../src/geometries/CircleGeometry.js'; +import { CircleGeometry } from '../../../../src/geometries/CircleGeometry.js'; export default QUnit.module( 'Geometries', () => { @@ -23,7 +23,6 @@ export default QUnit.module( 'Geometries', () => { new CircleGeometry( parameters.radius, parameters.segments ), new CircleGeometry( parameters.radius, parameters.segments, parameters.thetaStart ), new CircleGeometry( parameters.radius, parameters.segments, parameters.thetaStart, parameters.thetaLength ), - new CircleBufferGeometry(), ]; } ); diff --git a/test/unit/src/geometries/ConeGeometry.tests.js b/test/unit/src/geometries/ConeGeometry.tests.js index 17b741c56c04bf..53baad71db5c59 100644 --- a/test/unit/src/geometries/ConeGeometry.tests.js +++ b/test/unit/src/geometries/ConeGeometry.tests.js @@ -1,7 +1,7 @@ /* global QUnit */ import { runStdGeometryTests } from '../../utils/qunit-utils.js'; -import { ConeGeometry, ConeBufferGeometry } from '../../../../src/geometries/ConeGeometry.js'; +import { ConeGeometry } from '../../../../src/geometries/ConeGeometry.js'; export default QUnit.module( 'Geometries', () => { @@ -12,7 +12,6 @@ export default QUnit.module( 'Geometries', () => { geometries = [ new ConeGeometry(), - new ConeBufferGeometry() ]; } ); diff --git a/test/unit/src/geometries/CylinderGeometry.tests.js b/test/unit/src/geometries/CylinderGeometry.tests.js index 8ff4405ed834ca..749aeaf837be07 100644 --- a/test/unit/src/geometries/CylinderGeometry.tests.js +++ b/test/unit/src/geometries/CylinderGeometry.tests.js @@ -1,7 +1,7 @@ /* global QUnit */ import { runStdGeometryTests } from '../../utils/qunit-utils.js'; -import { CylinderGeometry, CylinderBufferGeometry } from '../../../../src/geometries/CylinderGeometry.js'; +import { CylinderGeometry } from '../../../../src/geometries/CylinderGeometry.js'; export default QUnit.module( 'Geometries', () => { @@ -31,7 +31,6 @@ export default QUnit.module( 'Geometries', () => { new CylinderGeometry( parameters.radiusTop, parameters.radiusBottom, parameters.height, parameters.radialSegments, parameters.heightSegments, parameters.openEnded ), new CylinderGeometry( parameters.radiusTop, parameters.radiusBottom, parameters.height, parameters.radialSegments, parameters.heightSegments, parameters.openEnded, parameters.thetaStart ), new CylinderGeometry( parameters.radiusTop, parameters.radiusBottom, parameters.height, parameters.radialSegments, parameters.heightSegments, parameters.openEnded, parameters.thetaStart, parameters.thetaLength ), - new CylinderBufferGeometry() ]; } ); diff --git a/test/unit/src/geometries/DodecahedronGeometry.tests.js b/test/unit/src/geometries/DodecahedronGeometry.tests.js index dabda1cb340628..50e53e26759e62 100644 --- a/test/unit/src/geometries/DodecahedronGeometry.tests.js +++ b/test/unit/src/geometries/DodecahedronGeometry.tests.js @@ -1,11 +1,11 @@ /* global QUnit */ import { runStdGeometryTests } from '../../utils/qunit-utils.js'; -import { DodecahedronGeometry, DodecahedronBufferGeometry } from '../../../../src/geometries/DodecahedronGeometry.js'; +import { DodecahedronGeometry } from '../../../../src/geometries/DodecahedronGeometry.js'; export default QUnit.module( 'Geometries', () => { - QUnit.module( 'CircleBufferGeometry', ( hooks ) => { + QUnit.module( 'DodecahedronGeometry', ( hooks ) => { var geometries = undefined; hooks.beforeEach( function () { @@ -19,7 +19,6 @@ export default QUnit.module( 'Geometries', () => { new DodecahedronGeometry(), new DodecahedronGeometry( parameters.radius ), new DodecahedronGeometry( parameters.radius, parameters.detail ), - new DodecahedronBufferGeometry() ]; } ); diff --git a/test/unit/src/geometries/IcosahedronGeometry.tests.js b/test/unit/src/geometries/IcosahedronGeometry.tests.js index 74909b63b63846..d1e57f64c1ebd5 100644 --- a/test/unit/src/geometries/IcosahedronGeometry.tests.js +++ b/test/unit/src/geometries/IcosahedronGeometry.tests.js @@ -1,7 +1,7 @@ /* global QUnit */ import { runStdGeometryTests } from '../../utils/qunit-utils.js'; -import { IcosahedronGeometry, IcosahedronBufferGeometry } from '../../../../src/geometries/IcosahedronGeometry.js'; +import { IcosahedronGeometry } from '../../../../src/geometries/IcosahedronGeometry.js'; export default QUnit.module( 'Geometries', () => { @@ -19,7 +19,6 @@ export default QUnit.module( 'Geometries', () => { new IcosahedronGeometry(), new IcosahedronGeometry( parameters.radius ), new IcosahedronGeometry( parameters.radius, parameters.detail ), - new IcosahedronBufferGeometry() ]; } ); diff --git a/test/unit/src/geometries/LatheGeometry.tests.js b/test/unit/src/geometries/LatheGeometry.tests.js index 4a071bb03686f0..0f36fa1f73042d 100644 --- a/test/unit/src/geometries/LatheGeometry.tests.js +++ b/test/unit/src/geometries/LatheGeometry.tests.js @@ -1,7 +1,7 @@ /* global QUnit */ import { runStdGeometryTests } from '../../utils/qunit-utils.js'; -import { LatheGeometry, LatheBufferGeometry } from '../../../../src/geometries/LatheGeometry.js'; +import { LatheGeometry } from '../../../../src/geometries/LatheGeometry.js'; export default QUnit.module( 'Geometries', () => { @@ -19,7 +19,6 @@ export default QUnit.module( 'Geometries', () => { geometries = [ new LatheGeometry( parameters.points ), - new LatheBufferGeometry( parameters.points ), ]; } ); diff --git a/test/unit/src/geometries/OctahedronGeometry.tests.js b/test/unit/src/geometries/OctahedronGeometry.tests.js index 6d14331e2ddad1..9965b764963e99 100644 --- a/test/unit/src/geometries/OctahedronGeometry.tests.js +++ b/test/unit/src/geometries/OctahedronGeometry.tests.js @@ -1,7 +1,7 @@ /* global QUnit */ import { runStdGeometryTests } from '../../utils/qunit-utils.js'; -import { OctahedronGeometry, OctahedronBufferGeometry } from '../../../../src/geometries/OctahedronGeometry.js'; +import { OctahedronGeometry } from '../../../../src/geometries/OctahedronGeometry.js'; export default QUnit.module( 'Geometries', () => { @@ -19,7 +19,6 @@ export default QUnit.module( 'Geometries', () => { new OctahedronGeometry(), new OctahedronGeometry( parameters.radius ), new OctahedronGeometry( parameters.radius, parameters.detail ), - new OctahedronBufferGeometry() ]; } ); diff --git a/test/unit/src/geometries/PlaneGeometry.tests.js b/test/unit/src/geometries/PlaneGeometry.tests.js index 4ab40a2531f414..24c2c5611edfcc 100644 --- a/test/unit/src/geometries/PlaneGeometry.tests.js +++ b/test/unit/src/geometries/PlaneGeometry.tests.js @@ -1,7 +1,7 @@ /* global QUnit */ import { runStdGeometryTests } from '../../utils/qunit-utils.js'; -import { PlaneGeometry, PlaneBufferGeometry } from '../../../../src/geometries/PlaneGeometry.js'; +import { PlaneGeometry } from '../../../../src/geometries/PlaneGeometry.js'; export default QUnit.module( 'Geometries', () => { @@ -23,7 +23,6 @@ export default QUnit.module( 'Geometries', () => { new PlaneGeometry( parameters.width, parameters.height ), new PlaneGeometry( parameters.width, parameters.height, parameters.widthSegments ), new PlaneGeometry( parameters.width, parameters.height, parameters.widthSegments, parameters.heightSegments ), - new PlaneBufferGeometry() ]; } ); diff --git a/test/unit/src/geometries/PolyhedronGeometry.tests.js b/test/unit/src/geometries/PolyhedronGeometry.tests.js index 5609ff5d09d083..8cceb4e0b779c5 100644 --- a/test/unit/src/geometries/PolyhedronGeometry.tests.js +++ b/test/unit/src/geometries/PolyhedronGeometry.tests.js @@ -1,7 +1,7 @@ /* global QUnit */ import { runStdGeometryTests } from '../../utils/qunit-utils.js'; -import { PolyhedronGeometry, PolyhedronBufferGeometry } from '../../../../src/geometries/PolyhedronGeometry.js'; +import { PolyhedronGeometry } from '../../../../src/geometries/PolyhedronGeometry.js'; export default QUnit.module( 'Geometries', () => { @@ -20,7 +20,6 @@ export default QUnit.module( 'Geometries', () => { geometries = [ new PolyhedronGeometry( vertices, indices ), - new PolyhedronBufferGeometry( vertices, indices ) ]; } ); diff --git a/test/unit/src/geometries/RingGeometry.tests.js b/test/unit/src/geometries/RingGeometry.tests.js index c02cf86ce5eec9..962cdb83720940 100644 --- a/test/unit/src/geometries/RingGeometry.tests.js +++ b/test/unit/src/geometries/RingGeometry.tests.js @@ -1,7 +1,7 @@ /* global QUnit */ import { runStdGeometryTests } from '../../utils/qunit-utils.js'; -import { RingGeometry, RingBufferGeometry } from '../../../../src/geometries/RingGeometry.js'; +import { RingGeometry, } from '../../../../src/geometries/RingGeometry.js'; export default QUnit.module( 'Geometries', () => { @@ -27,7 +27,6 @@ export default QUnit.module( 'Geometries', () => { new RingGeometry( parameters.innerRadius, parameters.outerRadius, parameters.thetaSegments, parameters.phiSegments ), new RingGeometry( parameters.innerRadius, parameters.outerRadius, parameters.thetaSegments, parameters.phiSegments, parameters.thetaStart ), new RingGeometry( parameters.innerRadius, parameters.outerRadius, parameters.thetaSegments, parameters.phiSegments, parameters.thetaStart, parameters.thetaLength ), - new RingBufferGeometry() ]; } ); diff --git a/test/unit/src/geometries/ShapeGeometry.tests.js b/test/unit/src/geometries/ShapeGeometry.tests.js index f017a1c7e87982..147875f2ba76e3 100644 --- a/test/unit/src/geometries/ShapeGeometry.tests.js +++ b/test/unit/src/geometries/ShapeGeometry.tests.js @@ -1,6 +1,6 @@ /* global QUnit */ -import { ShapeGeometry, ShapeBufferGeometry } from '../../../../src/geometries/ShapeGeometry.js'; +import { ShapeGeometry } from '../../../../src/geometries/ShapeGeometry.js'; import { Shape } from '../../../../src/extras/core/Shape.js'; @@ -18,7 +18,6 @@ export default QUnit.module( 'Geometries', () => { geometries = [ new ShapeGeometry( triangleShape ), - new ShapeBufferGeometry( triangleShape ) ]; } ); diff --git a/test/unit/src/geometries/SphereGeometry.tests.js b/test/unit/src/geometries/SphereGeometry.tests.js index acd7baac48daf8..5df8c78b894959 100644 --- a/test/unit/src/geometries/SphereGeometry.tests.js +++ b/test/unit/src/geometries/SphereGeometry.tests.js @@ -1,7 +1,7 @@ /* global QUnit */ import { runStdGeometryTests } from '../../utils/qunit-utils.js'; -import { SphereGeometry, SphereBufferGeometry } from '../../../../src/geometries/SphereGeometry.js'; +import { SphereGeometry } from '../../../../src/geometries/SphereGeometry.js'; export default QUnit.module( 'Geometries', () => { @@ -29,7 +29,6 @@ export default QUnit.module( 'Geometries', () => { new SphereGeometry( parameters.radius, parameters.widthSegments, parameters.heightSegments, parameters.phiStart, parameters.phiLength ), new SphereGeometry( parameters.radius, parameters.widthSegments, parameters.heightSegments, parameters.phiStart, parameters.phiLength, parameters.thetaStart ), new SphereGeometry( parameters.radius, parameters.widthSegments, parameters.heightSegments, parameters.phiStart, parameters.phiLength, parameters.thetaStart, parameters.thetaLength ), - new SphereBufferGeometry() ]; } ); diff --git a/test/unit/src/geometries/TetrahedronGeometry.tests.js b/test/unit/src/geometries/TetrahedronGeometry.tests.js index 14b64d0fa45709..2c0440a7288b70 100644 --- a/test/unit/src/geometries/TetrahedronGeometry.tests.js +++ b/test/unit/src/geometries/TetrahedronGeometry.tests.js @@ -1,7 +1,7 @@ /* global QUnit */ import { runStdGeometryTests } from '../../utils/qunit-utils.js'; -import { TetrahedronGeometry, TetrahedronBufferGeometry } from '../../../../src/geometries/TetrahedronGeometry.js'; +import { TetrahedronGeometry } from '../../../../src/geometries/TetrahedronGeometry.js'; export default QUnit.module( 'Geometries', () => { @@ -19,7 +19,6 @@ export default QUnit.module( 'Geometries', () => { new TetrahedronGeometry(), new TetrahedronGeometry( parameters.radius ), new TetrahedronGeometry( parameters.radius, parameters.detail ), - new TetrahedronBufferGeometry() ]; } ); diff --git a/test/unit/src/geometries/TorusGeometry.tests.js b/test/unit/src/geometries/TorusGeometry.tests.js index bf40202edd1bca..cbe202f133426d 100644 --- a/test/unit/src/geometries/TorusGeometry.tests.js +++ b/test/unit/src/geometries/TorusGeometry.tests.js @@ -1,11 +1,11 @@ /* global QUnit */ import { runStdGeometryTests } from '../../utils/qunit-utils.js'; -import { TorusGeometry, TorusBufferGeometry } from '../../../../src/geometries/TorusGeometry.js'; +import { TorusGeometry } from '../../../../src/geometries/TorusGeometry.js'; export default QUnit.module( 'Geometries', () => { - QUnit.module( 'TorusBufferGeometry', ( hooks ) => { + QUnit.module( 'TorusGeometry', ( hooks ) => { var geometries = undefined; hooks.beforeEach( function () { @@ -25,7 +25,6 @@ export default QUnit.module( 'Geometries', () => { new TorusGeometry( parameters.radius, parameters.tube, parameters.radialSegments ), new TorusGeometry( parameters.radius, parameters.tube, parameters.radialSegments, parameters.tubularSegments ), new TorusGeometry( parameters.radius, parameters.tube, parameters.radialSegments, parameters.tubularSegments, parameters.arc ), - new TorusBufferGeometry() ]; } ); diff --git a/test/unit/src/geometries/TorusKnotGeometry.tests.js b/test/unit/src/geometries/TorusKnotGeometry.tests.js index 7107b176c32909..be0e5d681d4614 100644 --- a/test/unit/src/geometries/TorusKnotGeometry.tests.js +++ b/test/unit/src/geometries/TorusKnotGeometry.tests.js @@ -1,7 +1,7 @@ /* global QUnit */ import { runStdGeometryTests } from '../../utils/qunit-utils.js'; -import { TorusKnotGeometry, TorusKnotBufferGeometry } from '../../../../src/geometries/TorusKnotGeometry.js'; +import { TorusKnotGeometry } from '../../../../src/geometries/TorusKnotGeometry.js'; export default QUnit.module( 'Geometries', () => { @@ -26,7 +26,6 @@ export default QUnit.module( 'Geometries', () => { new TorusKnotGeometry( parameters.radius, parameters.tube, parameters.tubularSegments ), new TorusKnotGeometry( parameters.radius, parameters.tube, parameters.tubularSegments, parameters.radialSegments ), new TorusKnotGeometry( parameters.radius, parameters.tube, parameters.tubularSegments, parameters.radialSegments, parameters.p, parameters.q ), - new TorusKnotBufferGeometry() ]; } ); diff --git a/test/unit/src/geometries/TubeGeometry.tests.js b/test/unit/src/geometries/TubeGeometry.tests.js index 4cc7828388bda8..aa3e9b369bba6a 100644 --- a/test/unit/src/geometries/TubeGeometry.tests.js +++ b/test/unit/src/geometries/TubeGeometry.tests.js @@ -1,6 +1,6 @@ /* global QUnit */ -import { TubeGeometry, TubeBufferGeometry } from '../../../../src/geometries/TubeGeometry.js'; +import { TubeGeometry } from '../../../../src/geometries/TubeGeometry.js'; import { LineCurve3 } from '../../../../src/extras/curves/LineCurve3.js'; import { Vector3 } from '../../../../src/math/Vector3.js'; @@ -16,7 +16,6 @@ export default QUnit.module( 'Geometries', () => { geometries = [ new TubeGeometry( path ), - new TubeBufferGeometry( path ) ]; } ); diff --git a/test/unit/src/math/Box3.tests.js b/test/unit/src/math/Box3.tests.js index d758104785f6b9..f383d4d7e7965a 100644 --- a/test/unit/src/math/Box3.tests.js +++ b/test/unit/src/math/Box3.tests.js @@ -10,7 +10,7 @@ import { Mesh } from '../../../../src/objects/Mesh.js'; import { BufferAttribute } from '../../../../src/core/BufferAttribute.js'; import { BoxGeometry } from '../../../../src/geometries/BoxGeometry.js'; import { - SphereBufferGeometry, + SphereGeometry, } from '../../../../src/geometries/SphereGeometry.js'; import { negInf3, @@ -171,8 +171,8 @@ export default QUnit.module( 'Maths', () => { QUnit.test( 'setFromObject/Precise', ( assert ) => { var a = new Box3( zero3.clone(), one3.clone() ); - var object = new Mesh( new SphereBufferGeometry( 1, 32, 32 ) ); - var child = new Mesh( new SphereBufferGeometry( 2, 32, 32 ) ); + var object = new Mesh( new SphereGeometry( 1, 32, 32 ) ); + var child = new Mesh( new SphereGeometry( 2, 32, 32 ) ); object.add( child ); object.rotation.setFromVector3( new Vector3( 0, 0, Math.PI / 4.0 ) ); diff --git a/test/unit/src/math/Color.tests.js b/test/unit/src/math/Color.tests.js index fb139009cfce4a..786e041bc52371 100644 --- a/test/unit/src/math/Color.tests.js +++ b/test/unit/src/math/Color.tests.js @@ -611,6 +611,30 @@ export default QUnit.module( 'Maths', () => { } ); + QUnit.test( 'setStyleHSLRedWithDecimals', ( assert ) => { + + var c = new Color(); + c.setStyle( 'hsl(360,100.0%,50.0%)' ); + assert.ok( c.r == 1, 'Red: ' + c.r ); + assert.ok( c.g === 0, 'Green: ' + c.g ); + assert.ok( c.b === 0, 'Blue: ' + c.b ); + + } ); + + QUnit.test( 'setStyleHSLARedWithDecimals', ( assert ) => { + + var c = new Color(); + + console.level = CONSOLE_LEVEL.ERROR; + c.setStyle( 'hsla(360,100.0%,50.0%,0.5)' ); + console.level = CONSOLE_LEVEL.DEFAULT; + + assert.ok( c.r == 1, 'Red: ' + c.r ); + assert.ok( c.g === 0, 'Green: ' + c.g ); + assert.ok( c.b === 0, 'Blue: ' + c.b ); + + } ); + QUnit.test( 'setStyleHexSkyBlue', ( assert ) => { var c = new Color(); diff --git a/test/unit/src/objects/Bone.tests.js b/test/unit/src/objects/Bone.tests.js index 9ced1395af3990..b9fb5ffd193d6b 100644 --- a/test/unit/src/objects/Bone.tests.js +++ b/test/unit/src/objects/Bone.tests.js @@ -1,15 +1,18 @@ /* global QUnit */ -// import { Bone } from '../../../../src/objects/Bone.js'; +import { Object3D } from '../../../../src/core/Object3D.js'; +import { Bone } from '../../../../src/objects/Bone.js'; export default QUnit.module( 'Objects', () => { QUnit.module( 'Bone', () => { // INHERITANCE - QUnit.todo( 'Extending', ( assert ) => { + QUnit.test( 'Extending', ( assert ) => { - assert.ok( false, 'everything\'s gonna be alright' ); + var bone = new Bone(); + + assert.strictEqual( bone instanceof Object3D, true, 'Bone extends from Object3D' ); } ); diff --git a/test/unit/src/objects/Group.tests.js b/test/unit/src/objects/Group.tests.js index c7e07a344d737b..699c089d40fdf6 100644 --- a/test/unit/src/objects/Group.tests.js +++ b/test/unit/src/objects/Group.tests.js @@ -1,15 +1,18 @@ /* global QUnit */ -// import { Group } from '../../../../src/objects/Group.js'; +import { Object3D } from '../../../../src/core/Object3D.js'; +import { Group } from '../../../../src/objects/Group.js'; export default QUnit.module( 'Objects', () => { QUnit.module( 'Group', () => { // INHERITANCE - QUnit.todo( 'Extending', ( assert ) => { + QUnit.test( 'Extending', ( assert ) => { - assert.ok( false, 'everything\'s gonna be alright' ); + var group = new Group(); + + assert.strictEqual( group instanceof Object3D, true, 'Group extends from Object3D' ); } ); diff --git a/test/unit/src/objects/LOD.tests.js b/test/unit/src/objects/LOD.tests.js index 1ac7bbffc81ba2..d51c8dbfc6621c 100644 --- a/test/unit/src/objects/LOD.tests.js +++ b/test/unit/src/objects/LOD.tests.js @@ -73,14 +73,14 @@ export default QUnit.module( 'Objects', () => { var mid = new Object3D(); var low = new Object3D(); - lod.addLevel( high, 5 ); - lod.addLevel( mid, 25 ); - lod.addLevel( low, 50 ); + lod.addLevel( high, 5, 0.00 ); + lod.addLevel( mid, 25, 0.05 ); + lod.addLevel( low, 50, 0.10 ); assert.strictEqual( lod.levels.length, 3, 'LOD.levels has the correct length.' ); - assert.deepEqual( lod.levels[ 0 ], { distance: 5, object: high }, 'First entry correct.' ); - assert.deepEqual( lod.levels[ 1 ], { distance: 25, object: mid }, 'Second entry correct.' ); - assert.deepEqual( lod.levels[ 2 ], { distance: 50, object: low }, 'Third entry correct.' ); + assert.deepEqual( lod.levels[ 0 ], { distance: 5, object: high, hysteresis: 0.00 }, 'First entry correct.' ); + assert.deepEqual( lod.levels[ 1 ], { distance: 25, object: mid, hysteresis: 0.05 }, 'Second entry correct.' ); + assert.deepEqual( lod.levels[ 2 ], { distance: 50, object: low, hysteresis: 0.10 }, 'Third entry correct.' ); } ); QUnit.test( 'getObjectForDistance', ( assert ) => { diff --git a/test/unit/src/objects/Line.tests.js b/test/unit/src/objects/Line.tests.js index 0c6c972c43846e..b5dada855fc960 100644 --- a/test/unit/src/objects/Line.tests.js +++ b/test/unit/src/objects/Line.tests.js @@ -1,15 +1,18 @@ /* global QUnit */ -// import { Line } from '../../../../src/objects/Line.js'; +import { Object3D } from '../../../../src/core/Object3D.js'; +import { Line } from '../../../../src/objects/Line.js'; export default QUnit.module( 'Objects', () => { QUnit.module( 'Line', () => { // INHERITANCE - QUnit.todo( 'Extending', ( assert ) => { + QUnit.test( 'Extending', ( assert ) => { - assert.ok( false, 'everything\'s gonna be alright' ); + var line = new Line(); + + assert.strictEqual( line instanceof Object3D, true, 'Line extends from Object3D' ); } ); diff --git a/test/unit/src/objects/LineLoop.tests.js b/test/unit/src/objects/LineLoop.tests.js index 04f55f70eca5ed..d3f70471ff5dbe 100644 --- a/test/unit/src/objects/LineLoop.tests.js +++ b/test/unit/src/objects/LineLoop.tests.js @@ -1,16 +1,21 @@ /* global QUnit */ -// import { LineLoop } from '../../../../src/objects/LineLoop.js'; +import { Object3D } from '../../../../src/core/Object3D.js'; +import { Line } from '../../../../src/objects/Line.js'; +import { LineLoop } from '../../../../src/objects/LineLoop.js'; export default QUnit.module( 'Objects', () => { QUnit.module( 'LineLoop', () => { // INHERITANCE - QUnit.todo( 'Extending', ( assert ) => { - - assert.ok( false, 'everything\'s gonna be alright' ); + QUnit.test( 'Extending', ( assert ) => { + var lineLoop = new LineLoop(); + + assert.strictEqual( lineLoop instanceof Object3D, true, 'LineLoop extends from Object3D' ); + assert.strictEqual( lineLoop instanceof Line, true, 'LineLoop extends from Line' ); + } ); // INSTANCING diff --git a/test/unit/src/objects/LineSegments.tests.js b/test/unit/src/objects/LineSegments.tests.js index 7122a91290c052..4b227a1723a8b6 100644 --- a/test/unit/src/objects/LineSegments.tests.js +++ b/test/unit/src/objects/LineSegments.tests.js @@ -1,15 +1,20 @@ /* global QUnit */ -// import { LineSegments } from '../../../../src/objects/LineSegments.js'; +import { Object3D } from '../../../../src/core/Object3D.js'; +import { Line } from '../../../../src/objects/Line.js'; +import { LineSegments } from '../../../../src/objects/LineSegments.js'; export default QUnit.module( 'Objects', () => { QUnit.module( 'LineSegments', () => { // INHERITANCE - QUnit.todo( 'Extending', ( assert ) => { + QUnit.test( 'Extending', ( assert ) => { - assert.ok( false, 'everything\'s gonna be alright' ); + var lineSegments = new LineSegments(); + + assert.strictEqual( lineSegments instanceof Object3D, true, 'LineSegments extends from Object3D' ); + assert.strictEqual( lineSegments instanceof Line, true, 'LineSegments extends from Line' ); } ); diff --git a/test/unit/src/objects/Mesh.tests.js b/test/unit/src/objects/Mesh.tests.js index 0c55554bc8c91a..0cfb8b8a413741 100644 --- a/test/unit/src/objects/Mesh.tests.js +++ b/test/unit/src/objects/Mesh.tests.js @@ -1,5 +1,6 @@ /* global QUnit */ +import { Object3D } from '../../../../src/core/Object3D.js'; import { Mesh } from '../../../../src/objects/Mesh.js'; import { Raycaster } from '../../../../src/core/Raycaster.js'; import { PlaneGeometry } from '../../../../src/geometries/PlaneGeometry.js'; @@ -12,9 +13,11 @@ export default QUnit.module( 'Objects', () => { QUnit.module( 'Mesh', () => { // INHERITANCE - QUnit.todo( 'Extending', ( assert ) => { + QUnit.test( 'Extending', ( assert ) => { - assert.ok( false, 'everything\'s gonna be alright' ); + var mesh = new Mesh(); + + assert.strictEqual( mesh instanceof Object3D, true, 'Mesh extends from Object3D' ); } ); diff --git a/test/unit/src/objects/Points.tests.js b/test/unit/src/objects/Points.tests.js index 637de8530b67b7..4046b71f125524 100644 --- a/test/unit/src/objects/Points.tests.js +++ b/test/unit/src/objects/Points.tests.js @@ -1,15 +1,18 @@ /* global QUnit */ -// import { Points } from '../../../../src/objects/Points.js'; +import { Object3D } from '../../../../src/core/Object3D.js'; +import { Points } from '../../../../src/objects/Points.js'; export default QUnit.module( 'Objects', () => { QUnit.module( 'Points', () => { // INHERITANCE - QUnit.todo( 'isPoints', ( assert ) => { + QUnit.test( 'isPoints', ( assert ) => { - assert.ok( false, 'everything\'s gonna be alright' ); + var points = new Points(); + + assert.strictEqual( points instanceof Object3D, true, 'Points extends from Object3D' ); } ); diff --git a/test/unit/src/objects/SkinnedMesh.tests.js b/test/unit/src/objects/SkinnedMesh.tests.js index 025df0460274ea..afe6d0300a4e75 100644 --- a/test/unit/src/objects/SkinnedMesh.tests.js +++ b/test/unit/src/objects/SkinnedMesh.tests.js @@ -1,15 +1,20 @@ /* global QUnit */ -// import { SkinnedMesh } from '../../../../src/objects/SkinnedMesh.js'; +import { Object3D } from '../../../../src/core/Object3D.js'; +import { Mesh } from '../../../../src/objects/Mesh.js'; +import { SkinnedMesh } from '../../../../src/objects/SkinnedMesh.js'; export default QUnit.module( 'Objects', () => { QUnit.module( 'SkinnedMesh', () => { // INHERITANCE - QUnit.todo( 'Extending', ( assert ) => { + QUnit.test( 'Extending', ( assert ) => { - assert.ok( false, 'everything\'s gonna be alright' ); + var skinnedMesh = new SkinnedMesh(); + + assert.strictEqual( skinnedMesh instanceof Object3D, true, 'SkinnedMesh extends from Object3D' ); + assert.strictEqual( skinnedMesh instanceof Mesh, true, 'SkinnedMesh extends from Mesh' ); } ); diff --git a/test/unit/src/objects/Sprite.tests.js b/test/unit/src/objects/Sprite.tests.js index 9a1734943f3ccd..b43c5c9fb9f43a 100644 --- a/test/unit/src/objects/Sprite.tests.js +++ b/test/unit/src/objects/Sprite.tests.js @@ -1,15 +1,18 @@ /* global QUnit */ -// import { Sprite } from '../../../../src/objects/Sprite.js'; +import { Object3D } from '../../../../src/core/Object3D.js'; +import { Sprite } from '../../../../src/objects/Sprite.js'; export default QUnit.module( 'Objects', () => { QUnit.module( 'Sprite', () => { // INHERITANCE - QUnit.todo( 'Extending', ( assert ) => { + QUnit.test( 'Extending', ( assert ) => { - assert.ok( false, 'everything\'s gonna be alright' ); + var sprite = new Sprite(); + + assert.strictEqual( sprite instanceof Object3D, true, 'Sprite extends from Object3D' ); } ); diff --git a/utils/build/rollup.config.js b/utils/build/rollup.config.js index 849495c9cd6953..974f4e07881f7f 100644 --- a/utils/build/rollup.config.js +++ b/utils/build/rollup.config.js @@ -113,6 +113,7 @@ export function glconstants() { UNSIGNED_INT_24_8: 34042, TEXTURE_CUBE_MAP: 34067, TEXTURE_CUBE_MAP_POSITIVE_X: 34069, + TEXTURE_CUBE_MAP_NEGATIVE_Z: 34074, MAX_CUBE_MAP_TEXTURE_SIZE: 34076, COMPRESSED_TEXTURE_FORMATS: 34467, RGBA32F: 34836, @@ -285,7 +286,7 @@ ${ code }`; } -let builds = [ +const builds = [ { input: 'src/Three.js', plugins: [ @@ -355,11 +356,4 @@ let builds = [ } ]; - -if ( process.env.ONLY_MODULE === 'true' ) { - - builds = builds[ 0 ]; - -} - -export default builds; +export default ( args ) => args.configOnlyModule ? builds[ 0 ] : builds; \ No newline at end of file diff --git a/utils/build/rollup.examples.config.js b/utils/build/rollup.examples.config.js index 26951de9061804..ac9b2bbcf5e405 100644 --- a/utils/build/rollup.examples.config.js +++ b/utils/build/rollup.examples.config.js @@ -181,6 +181,7 @@ const files = glob.sync( '**/*.js', { cwd: jsmFolder, ignore: [ // no non-module library // https://unpkg.com/browse/web-ifc@0.0.17/ 'loaders/IFCLoader.js', + 'loaders/USDZLoader.js', 'node-editor/**/*', 'renderers/webgl/**/*', @@ -192,6 +193,8 @@ const files = glob.sync( '**/*.js', { cwd: jsmFolder, ignore: [ // dont convert new files 'exporters/KTX2Exporter.js', + 'loaders/KTX2Loader.js', + 'loaders/MaterialXLoader.js' ] } );